Merge NAN Component files from branch 'wlan-cmn.driver.lnx.2.0' into wlan-cld3.driver.lnx.2.0
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..e9d3e77
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,86 @@
+# Android makefile for the WLAN Module
+
+# Assume no targets will be supported
+WLAN_CHIPSET :=
+
+ifeq ($(BOARD_HAS_QCOM_WLAN), true)
+
+# Check if this driver needs be built for current target
+ifneq ($(findstring qca_cld3,$(WIFI_DRIVER_BUILT)),)
+	WLAN_CHIPSET := qca_cld3
+	WLAN_SELECT  := CONFIG_QCA_CLD_WLAN=m
+endif
+
+# Build/Package only in case of supported target
+ifneq ($(WLAN_CHIPSET),)
+
+LOCAL_PATH := $(call my-dir)
+
+# This makefile is only for DLKM
+ifneq ($(findstring vendor,$(LOCAL_PATH)),)
+
+ifneq ($(findstring opensource,$(LOCAL_PATH)),)
+	WLAN_BLD_DIR := vendor/qcom/opensource/wlan
+endif # opensource
+
+# DLKM_DIR was moved for JELLY_BEAN (PLATFORM_SDK 16)
+ifeq ($(call is-platform-sdk-version-at-least,16),true)
+	DLKM_DIR := $(TOP)/device/qcom/common/dlkm
+else
+	DLKM_DIR := build/dlkm
+endif # platform-sdk-version
+
+# Build wlan.ko as $(WLAN_CHIPSET)_wlan.ko
+###########################################################
+# This is set once per LOCAL_PATH, not per (kernel) module
+KBUILD_OPTIONS := WLAN_ROOT=$(WLAN_BLD_DIR)/qcacld-3.0
+KBUILD_OPTIONS += WLAN_COMMON_ROOT=../qca-wifi-host-cmn
+KBUILD_OPTIONS += WLAN_COMMON_INC=$(WLAN_BLD_DIR)/qca-wifi-host-cmn
+
+# We are actually building wlan.ko here, as per the
+# requirement we are specifying <chipset>_wlan.ko as LOCAL_MODULE.
+# This means we need to rename the module to <chipset>_wlan.ko
+# after wlan.ko is built.
+KBUILD_OPTIONS += MODNAME=wlan
+KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
+KBUILD_OPTIONS += $(WLAN_SELECT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE              := $(WLAN_CHIPSET)_wlan.ko
+LOCAL_MODULE_KBUILD_NAME  := wlan.ko
+LOCAL_MODULE_TAGS         := debug
+LOCAL_MODULE_DEBUG_ENABLE := true
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
+    ifeq ($(WIFI_DRIVER_INSTALL_TO_KERNEL_OUT),true)
+        LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
+    else
+        LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/modules/$(WLAN_CHIPSET)
+    endif
+else
+    LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/modules/$(WLAN_CHIPSET)
+endif
+
+include $(DLKM_DIR)/AndroidKernelModule.mk
+###########################################################
+
+# Create Symbolic link
+ifneq ($(findstring $(WLAN_CHIPSET),$(WIFI_DRIVER_DEFAULT)),)
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
+ifneq ($(WIFI_DRIVER_INSTALL_TO_KERNEL_OUT),)
+$(shell mkdir -p $(TARGET_OUT_VENDOR)/lib/modules; \
+	ln -sf /$(TARGET_COPY_OUT_VENDOR)/lib/modules/$(WLAN_CHIPSET)/$(LOCAL_MODULE) $(TARGET_OUT_VENDOR)/lib/modules/wlan.ko)
+endif
+else
+$(shell mkdir -p $(TARGET_OUT)/lib/modules; \
+	ln -sf /system/lib/modules/$(WLAN_CHIPSET)/$(LOCAL_MODULE) $(TARGET_OUT)/lib/modules/wlan.ko)
+endif
+endif
+
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
+$(shell ln -sf /mnt/vendor/persist/wlan_mac.bin $(TARGET_OUT_VENDOR)/firmware/wlan/qca_cld/wlan_mac.bin)
+else
+$(shell ln -sf /mnt/vendor/persist/wlan_mac.bin $(TARGET_OUT_ETC)/firmware/wlan/qca_cld/wlan_mac.bin)
+endif
+endif # DLKM check
+endif # supported target check
+endif # WLAN enabled check
diff --git a/Kbuild b/Kbuild
new file mode 100644
index 0000000..6f8a695
--- /dev/null
+++ b/Kbuild
@@ -0,0 +1,2570 @@
+# We can build either as part of a standalone Kernel build or as
+# an external module.  Determine which mechanism is being used
+ifeq ($(MODNAME),)
+	KERNEL_BUILD := y
+else
+	KERNEL_BUILD := n
+endif
+
+ifeq ($(KERNEL_BUILD), y)
+	# These are provided in external module based builds
+	# Need to explicitly define for Kernel-based builds
+	MODNAME := wlan
+	WLAN_ROOT := drivers/staging/qcacld-3.0
+	WLAN_COMMON_ROOT := ../qca-wifi-host-cmn
+	WLAN_COMMON_INC := $(WLAN_ROOT)/$(WLAN_COMMON_ROOT)
+endif
+
+WLAN_COMMON_ROOT ?= ../qca-wifi-host-cmn
+WLAN_COMMON_INC ?= $(WLAN_ROOT)/$(WLAN_COMMON_ROOT)
+
+CONFIG_QCA_CLD_WLAN_PROFILE ?= default
+ifeq ($(KERNEL_BUILD), n)
+ifneq ($(ANDROID_BUILD_TOP),)
+      override WLAN_ROOT := $(ANDROID_BUILD_TOP)/$(WLAN_ROOT)
+      override WLAN_COMMON_INC := $(ANDROID_BUILD_TOP)/$(WLAN_COMMON_INC)
+endif
+endif
+
+include $(WLAN_ROOT)/configs/$(CONFIG_QCA_CLD_WLAN_PROFILE)_defconfig
+
+############ UAPI ############
+UAPI_DIR :=	uapi
+UAPI_INC :=	-I$(WLAN_ROOT)/$(UAPI_DIR)/linux
+
+############ COMMON ############
+COMMON_DIR :=	core/common
+COMMON_INC :=	-I$(WLAN_ROOT)/$(COMMON_DIR)
+
+############ HDD ############
+HDD_DIR :=	core/hdd
+HDD_INC_DIR :=	$(HDD_DIR)/inc
+HDD_SRC_DIR :=	$(HDD_DIR)/src
+
+HDD_INC := 	-I$(WLAN_ROOT)/$(HDD_INC_DIR) \
+		-I$(WLAN_ROOT)/$(HDD_SRC_DIR)
+
+HDD_OBJS := 	$(HDD_SRC_DIR)/wlan_hdd_assoc.o \
+		$(HDD_SRC_DIR)/wlan_hdd_cfg.o \
+		$(HDD_SRC_DIR)/wlan_hdd_cfg80211.o \
+		$(HDD_SRC_DIR)/wlan_hdd_data_stall_detection.o \
+		$(HDD_SRC_DIR)/wlan_hdd_driver_ops.o \
+		$(HDD_SRC_DIR)/wlan_hdd_ext_scan.o \
+		$(HDD_SRC_DIR)/wlan_hdd_ftm.o \
+		$(HDD_SRC_DIR)/wlan_hdd_hostapd.o \
+		$(HDD_SRC_DIR)/wlan_hdd_ioctl.o \
+		$(HDD_SRC_DIR)/wlan_hdd_main.o \
+		$(HDD_SRC_DIR)/wlan_hdd_object_manager.o \
+		$(HDD_SRC_DIR)/wlan_hdd_oemdata.o \
+		$(HDD_SRC_DIR)/wlan_hdd_p2p.o \
+		$(HDD_SRC_DIR)/wlan_hdd_power.o \
+		$(HDD_SRC_DIR)/wlan_hdd_regulatory.o \
+		$(HDD_SRC_DIR)/wlan_hdd_scan.o \
+		$(HDD_SRC_DIR)/wlan_hdd_softap_tx_rx.o \
+		$(HDD_SRC_DIR)/wlan_hdd_stats.o \
+		$(HDD_SRC_DIR)/wlan_hdd_trace.o \
+		$(HDD_SRC_DIR)/wlan_hdd_tx_rx.o \
+		$(HDD_SRC_DIR)/wlan_hdd_wmm.o \
+		$(HDD_SRC_DIR)/wlan_hdd_wowl.o
+
+ifeq ($(CONFIG_WLAN_WEXT_SUPPORT_ENABLE), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_wext.o \
+	    $(HDD_SRC_DIR)/wlan_hdd_hostapd_wext.o
+endif
+
+ifeq ($(CONFIG_WLAN_DEBUGFS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs.o
+ifeq ($(CONFIG_WLAN_FEATURE_LINK_LAYER_STATS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_llstat.o
+endif
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_csr.o
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_connect.o
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_offload.o
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_roam.o
+endif
+
+ifeq ($(CONFIG_WLAN_CONV_SPECTRAL_ENABLE),y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_spectralscan.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+HDD_OBJS+=	$(HDD_SRC_DIR)/wlan_hdd_ocb.o
+endif
+
+ifeq ($(CONFIG_FEATURE_MEMDUMP_ENABLE), y)
+HDD_OBJS+=	$(HDD_SRC_DIR)/wlan_hdd_memdump.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_FIPS), y)
+HDD_OBJS+=	$(HDD_SRC_DIR)/wlan_hdd_fips.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_GREEN_AP), y)
+HDD_OBJS+=	$(HDD_SRC_DIR)/wlan_hdd_green_ap.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_APF), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_apf.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_LPSS), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_lpass.o
+endif
+
+ifeq ($(CONFIG_WLAN_LRO), y)
+HDD_OBJS +=     $(HDD_SRC_DIR)/wlan_hdd_lro.o
+endif
+
+ifeq ($(CONFIG_WLAN_NAPI), y)
+HDD_OBJS +=     $(HDD_SRC_DIR)/wlan_hdd_napi.o
+endif
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_ipa.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_NAN), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_nan.o
+endif
+
+ifeq ($(CONFIG_QCOM_TDLS), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_tdls.o
+endif
+
+ifeq ($(CONFIG_WLAN_SYNC_TSF_PLUS), y)
+CONFIG_WLAN_SYNC_TSF := y
+endif
+
+ifeq ($(CONFIG_WLAN_SYNC_TSF), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_tsf.o
+endif
+
+ifeq ($(CONFIG_MPC_UT_FRAMEWORK), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_conc_ut.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DISA), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_disa.o
+endif
+
+ifeq ($(CONFIG_LFR_SUBNET_DETECTION), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_subnet_detect.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_NAN_DATAPATH), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_nan_datapath.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_11AX), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_he.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_TWT), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_twt.o
+endif
+
+ifeq ($(CONFIG_LITHIUM), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_rx_monitor.o
+endif
+
+ifeq ($(CONFIG_LITHIUM), y)
+CONFIG_WLAN_FEATURE_DP_RX_THREADS := y
+endif
+
+ifeq ($(CONFIG_WLAN_NUD_TRACKING), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_nud_tracking.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_PACKET_FILTERING), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_packet_filter.o
+endif
+
+ifeq ($(CONFIG_FEATURE_RSSI_MONITOR), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_rssi_monitor.o
+endif
+
+ifeq ($(CONFIG_FEATURE_BSS_TRANSITION), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_bss_transition.o
+endif
+
+ifeq ($(CONFIG_FEATURE_STATION_INFO), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_station_info.o
+endif
+
+ifeq ($(CONFIG_FEATURE_TX_POWER), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tx_power.o
+endif
+
+ifeq ($(CONFIG_FEATURE_OTA_TEST), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_ota_test.o
+endif
+
+ifeq ($(CONFIG_FEATURE_ACTIVE_TOS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_active_tos.o
+endif
+
+ifeq ($(CONFIG_FEATURE_SAR_LIMITS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sar_limits.o
+endif
+
+ifeq ($(CONFIG_FEATURE_CONCURRENCY_MATRIX), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_concurrency_matrix.o
+endif
+
+ifeq ($(CONFIG_FEATURE_SAP_COND_CHAN_SWITCH), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sap_cond_chan_switch.o
+endif
+
+ifeq ($(CONFIG_FEATURE_P2P_LISTEN_OFFLOAD), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_p2p_listen_offload.o
+endif
+
+ifeq ($(CONFIG_WLAN_SYSFS), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs.o
+endif
+########### Driver Synchronization Core (DSC) ###########
+DSC_DIR := components/dsc
+DSC_INC_DIR := $(DSC_DIR)/inc
+DSC_SRC_DIR := $(DSC_DIR)/src
+DSC_TEST_DIR := $(DSC_DIR)/test
+
+DSC_INC := \
+	-I$(WLAN_ROOT)/$(DSC_INC_DIR) \
+	-I$(WLAN_ROOT)/$(DSC_SRC_DIR) \
+	-I$(WLAN_ROOT)/$(DSC_TEST_DIR)
+
+DSC_OBJS := \
+	$(DSC_SRC_DIR)/__wlan_dsc.o \
+	$(DSC_SRC_DIR)/wlan_dsc_driver.o \
+	$(DSC_SRC_DIR)/wlan_dsc_psoc.o \
+	$(DSC_SRC_DIR)/wlan_dsc_vdev.o
+
+ifeq ($(CONFIG_DSC_TEST), y)
+	DSC_OBJS += $(DSC_TEST_DIR)/wlan_dsc_test.o
+endif
+
+cppflags-$(CONFIG_DSC_DEBUG) += -DWLAN_DSC_DEBUG
+cppflags-$(CONFIG_DSC_TEST) += -DWLAN_DSC_TEST
+
+########### HOST DIAG LOG ###########
+HOST_DIAG_LOG_DIR :=	$(WLAN_COMMON_ROOT)/utils/host_diag_log
+
+HOST_DIAG_LOG_INC_DIR :=	$(HOST_DIAG_LOG_DIR)/inc
+HOST_DIAG_LOG_SRC_DIR :=	$(HOST_DIAG_LOG_DIR)/src
+
+HOST_DIAG_LOG_INC :=	-I$(WLAN_ROOT)/$(HOST_DIAG_LOG_INC_DIR) \
+			-I$(WLAN_ROOT)/$(HOST_DIAG_LOG_SRC_DIR)
+
+HOST_DIAG_LOG_OBJS +=	$(HOST_DIAG_LOG_SRC_DIR)/host_diag_log.o
+
+############ EPPING ############
+EPPING_DIR :=	$(WLAN_COMMON_ROOT)/utils/epping
+EPPING_INC_DIR :=	$(EPPING_DIR)/inc
+EPPING_SRC_DIR :=	$(EPPING_DIR)/src
+
+EPPING_INC := 	-I$(WLAN_ROOT)/$(EPPING_INC_DIR)
+
+EPPING_OBJS := $(EPPING_SRC_DIR)/epping_main.o \
+		$(EPPING_SRC_DIR)/epping_txrx.o \
+		$(EPPING_SRC_DIR)/epping_tx.o \
+		$(EPPING_SRC_DIR)/epping_rx.o \
+		$(EPPING_SRC_DIR)/epping_helper.o
+
+############ MAC ############
+MAC_DIR :=	core/mac
+MAC_INC_DIR :=	$(MAC_DIR)/inc
+MAC_SRC_DIR :=	$(MAC_DIR)/src
+
+MAC_INC := 	-I$(WLAN_ROOT)/$(MAC_INC_DIR) \
+		-I$(WLAN_ROOT)/$(MAC_SRC_DIR)/dph \
+		-I$(WLAN_ROOT)/$(MAC_SRC_DIR)/include \
+		-I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/include \
+		-I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/lim \
+		-I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/nan
+
+MAC_CFG_OBJS := $(MAC_SRC_DIR)/cfg/cfg_api.o \
+		$(MAC_SRC_DIR)/cfg/cfg_param_name.o \
+		$(MAC_SRC_DIR)/cfg/cfg_proc_msg.o \
+		$(MAC_SRC_DIR)/cfg/cfg_send_msg.o
+
+MAC_DPH_OBJS :=	$(MAC_SRC_DIR)/dph/dph_hash_table.o
+
+MAC_LIM_OBJS := $(MAC_SRC_DIR)/pe/lim/lim_aid_mgmt.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_admit_control.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_api.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_assoc_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_ft.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_ibss_peer_mgmt.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_link_monitoring_algo.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_action_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_assoc_req_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_assoc_rsp_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_auth_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_beacon_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_cfg_updates.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_deauth_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_disassoc_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_message_queue.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_mlm_req_messages.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_mlm_rsp_messages.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_probe_req_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_probe_rsp_frame.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_process_sme_req_messages.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_prop_exts_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_scan_result_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_security_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_send_management_frames.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_send_messages.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_send_sme_rsp_messages.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_ser_des_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_session.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_session_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_sme_req_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_sta_hash_api.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_timer_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_trace.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_utils.o
+
+ifeq ($(CONFIG_QCOM_TDLS), y)
+MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_process_tdls.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_FILS), y)
+MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_process_fils.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_NAN_DATAPATH), y)
+MAC_NDP_OBJS += $(MAC_SRC_DIR)/pe/nan/nan_datapath.o
+endif
+
+ifeq ($(CONFIG_QCACLD_WLAN_LFR2), y)
+	MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_process_mlm_host_roam.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_send_frames_host_roam.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_roam_timer_utils.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_ft_preauth.o \
+		$(MAC_SRC_DIR)/pe/lim/lim_reassoc_utils.o
+endif
+
+MAC_SCH_OBJS := $(MAC_SRC_DIR)/pe/sch/sch_api.o \
+		$(MAC_SRC_DIR)/pe/sch/sch_beacon_gen.o \
+		$(MAC_SRC_DIR)/pe/sch/sch_beacon_process.o \
+		$(MAC_SRC_DIR)/pe/sch/sch_message.o
+
+MAC_RRM_OBJS :=	$(MAC_SRC_DIR)/pe/rrm/rrm_api.o
+
+MAC_OBJS := 	$(MAC_CFG_OBJS) \
+		$(MAC_DPH_OBJS) \
+		$(MAC_LIM_OBJS) \
+		$(MAC_SCH_OBJS) \
+		$(MAC_RRM_OBJS) \
+		$(MAC_NDP_OBJS)
+
+############ SAP ############
+SAP_DIR :=	core/sap
+SAP_INC_DIR :=	$(SAP_DIR)/inc
+SAP_SRC_DIR :=	$(SAP_DIR)/src
+
+SAP_INC := 	-I$(WLAN_ROOT)/$(SAP_INC_DIR) \
+		-I$(WLAN_ROOT)/$(SAP_SRC_DIR)
+
+SAP_OBJS :=	$(SAP_SRC_DIR)/sap_api_link_cntl.o \
+		$(SAP_SRC_DIR)/sap_ch_select.o \
+		$(SAP_SRC_DIR)/sap_fsm.o \
+		$(SAP_SRC_DIR)/sap_module.o
+
+############ CFG ############
+CFG_REL_DIR := $(WLAN_COMMON_ROOT)/cfg
+CFG_DIR := $(WLAN_ROOT)/$(CFG_REL_DIR)
+CFG_INC := \
+	-I$(CFG_DIR)/inc \
+	-I$(CFG_DIR)/dispatcher/inc \
+	-I$(WLAN_ROOT)/components/cfg
+CFG_OBJS := \
+	$(CFG_REL_DIR)/src/cfg.o
+
+############ DFS ############
+DFS_DIR :=     $(WLAN_COMMON_ROOT)/umac/dfs
+DFS_CORE_INC_DIR := $(DFS_DIR)/core/inc
+DFS_CORE_SRC_DIR := $(DFS_DIR)/core/src
+
+DFS_DISP_INC_DIR := $(DFS_DIR)/dispatcher/inc
+DFS_DISP_SRC_DIR := $(DFS_DIR)/dispatcher/src
+DFS_TARGET_INC_DIR := $(WLAN_COMMON_ROOT)/target_if/dfs/inc
+DFS_CMN_SERVICES_INC_DIR := $(WLAN_COMMON_ROOT)/umac/cmn_services/dfs/inc
+
+DFS_INC :=	-I$(WLAN_ROOT)/$(DFS_DISP_INC_DIR) \
+		-I$(WLAN_ROOT)/$(DFS_TARGET_INC_DIR) \
+		-I$(WLAN_ROOT)/$(DFS_CMN_SERVICES_INC_DIR)
+
+DFS_OBJS :=	$(DFS_CORE_SRC_DIR)/misc/dfs.o \
+		$(DFS_CORE_SRC_DIR)/misc/dfs_cac.o \
+		$(DFS_CORE_SRC_DIR)/misc/dfs_nol.o \
+		$(DFS_CORE_SRC_DIR)/misc/dfs_random_chan_sel.o \
+		$(DFS_CORE_SRC_DIR)/misc/dfs_process_radar_found_ind.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_init_deinit_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_lmac_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_mlme_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_tgt_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_ucfg_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_tgt_api.o \
+		$(DFS_DISP_SRC_DIR)/wlan_dfs_utils_api.o \
+		$(WLAN_COMMON_ROOT)/target_if/dfs/src/target_if_dfs.o
+
+ifeq ($(CONFIG_WLAN_FEATURE_DFS_OFFLOAD), y)
+DFS_OBJS +=	$(WLAN_COMMON_ROOT)/target_if/dfs/src/target_if_dfs_full_offload.o \
+		$(DFS_CORE_SRC_DIR)/misc/dfs_full_offload.o
+else
+DFS_OBJS +=	$(WLAN_COMMON_ROOT)/target_if/dfs/src/target_if_dfs_partial_offload.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_fcc_bin5.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_bindetects.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_debug.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_init.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_misc.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_phyerr_tlv.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_process_phyerr.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_process_radarevent.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_staggered.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_radar.o \
+		$(DFS_CORE_SRC_DIR)/filtering/dfs_partial_offload_radar.o \
+		$(DFS_CORE_SRC_DIR)/misc/dfs_filter_init.o
+endif
+
+############ SME ############
+SME_DIR :=	core/sme
+SME_INC_DIR :=	$(SME_DIR)/inc
+SME_SRC_DIR :=	$(SME_DIR)/src
+
+SME_INC := 	-I$(WLAN_ROOT)/$(SME_INC_DIR) \
+		-I$(WLAN_ROOT)/$(SME_SRC_DIR)/csr
+
+SME_CSR_OBJS := $(SME_SRC_DIR)/csr/csr_api_roam.o \
+		$(SME_SRC_DIR)/csr/csr_api_scan.o \
+		$(SME_SRC_DIR)/csr/csr_cmd_process.o \
+		$(SME_SRC_DIR)/csr/csr_link_list.o \
+		$(SME_SRC_DIR)/csr/csr_neighbor_roam.o \
+		$(SME_SRC_DIR)/csr/csr_util.o \
+
+
+ifeq ($(CONFIG_QCACLD_WLAN_LFR2), y)
+SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csr_roam_preauth.o \
+		$(SME_SRC_DIR)/csr/csr_host_scan_roam.o
+endif
+
+SME_QOS_OBJS := $(SME_SRC_DIR)/qos/sme_qos.o
+
+SME_CMN_OBJS := $(SME_SRC_DIR)/common/sme_api.o \
+		$(SME_SRC_DIR)/common/sme_ft_api.o \
+		$(SME_SRC_DIR)/common/sme_power_save.o \
+		$(SME_SRC_DIR)/common/sme_trace.o
+
+SME_RRM_OBJS := $(SME_SRC_DIR)/rrm/sme_rrm.o
+
+ifeq ($(CONFIG_QCACLD_FEATURE_NAN), y)
+SME_NAN_OBJS = $(SME_SRC_DIR)/nan/nan_api.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_NAN_DATAPATH), y)
+SME_NDP_OBJS += $(SME_SRC_DIR)/nan/nan_datapath_api.o
+endif
+
+SME_OBJS :=	$(SME_CMN_OBJS) \
+		$(SME_CSR_OBJS) \
+		$(SME_QOS_OBJS) \
+		$(SME_RRM_OBJS) \
+		$(SME_NAN_OBJS) \
+		$(SME_NDP_OBJS)
+
+############ NLINK ############
+NLINK_DIR     :=	$(WLAN_COMMON_ROOT)/utils/nlink
+NLINK_INC_DIR :=	$(NLINK_DIR)/inc
+NLINK_SRC_DIR :=	$(NLINK_DIR)/src
+
+NLINK_INC     := 	-I$(WLAN_ROOT)/$(NLINK_INC_DIR)
+NLINK_OBJS    :=	$(NLINK_SRC_DIR)/wlan_nlink_srv.o
+
+############ PTT ############
+PTT_DIR     :=	$(WLAN_COMMON_ROOT)/utils/ptt
+PTT_INC_DIR :=	$(PTT_DIR)/inc
+PTT_SRC_DIR :=	$(PTT_DIR)/src
+
+PTT_INC     := 	-I$(WLAN_ROOT)/$(PTT_INC_DIR)
+PTT_OBJS    :=	$(PTT_SRC_DIR)/wlan_ptt_sock_svc.o
+
+############ WLAN_LOGGING ############
+WLAN_LOGGING_DIR     :=	$(WLAN_COMMON_ROOT)/utils/logging
+WLAN_LOGGING_INC_DIR :=	$(WLAN_LOGGING_DIR)/inc
+WLAN_LOGGING_SRC_DIR :=	$(WLAN_LOGGING_DIR)/src
+
+WLAN_LOGGING_INC     := -I$(WLAN_ROOT)/$(WLAN_LOGGING_INC_DIR)
+WLAN_LOGGING_OBJS    := $(WLAN_LOGGING_SRC_DIR)/wlan_logging_sock_svc.o \
+		$(WLAN_LOGGING_SRC_DIR)/wlan_roam_debug.o
+
+############ SYS ############
+SYS_DIR :=	core/mac/src/sys
+
+SYS_INC := 	-I$(WLAN_ROOT)/$(SYS_DIR)/common/inc \
+		-I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/platform/inc \
+		-I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/system/inc \
+		-I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/utils/inc
+
+SYS_COMMON_SRC_DIR := $(SYS_DIR)/common/src
+SYS_LEGACY_SRC_DIR := $(SYS_DIR)/legacy/src
+SYS_OBJS :=	$(SYS_COMMON_SRC_DIR)/wlan_qct_sys.o \
+		$(SYS_LEGACY_SRC_DIR)/platform/src/sys_wrapper.o \
+		$(SYS_LEGACY_SRC_DIR)/system/src/mac_init_api.o \
+		$(SYS_LEGACY_SRC_DIR)/system/src/sys_entry_func.o \
+		$(SYS_LEGACY_SRC_DIR)/utils/src/dot11f.o \
+		$(SYS_LEGACY_SRC_DIR)/utils/src/mac_trace.o \
+		$(SYS_LEGACY_SRC_DIR)/utils/src/parser_api.o \
+		$(SYS_LEGACY_SRC_DIR)/utils/src/utils_parser.o
+
+############ Qca-wifi-host-cmn ############
+QDF_OS_DIR :=	qdf
+QDF_OS_INC_DIR := $(QDF_OS_DIR)/inc
+QDF_OS_SRC_DIR := $(QDF_OS_DIR)/src
+QDF_OS_LINUX_SRC_DIR := $(QDF_OS_DIR)/linux/src
+QDF_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(QDF_OS_SRC_DIR)
+QDF_LINUX_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(QDF_OS_LINUX_SRC_DIR)
+
+QDF_INC :=	-I$(WLAN_COMMON_INC)/$(QDF_OS_INC_DIR) \
+		-I$(WLAN_COMMON_INC)/$(QDF_OS_LINUX_SRC_DIR)
+
+QDF_OBJS := 	$(QDF_LINUX_OBJ_DIR)/qdf_crypto.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_defer.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_dev.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_event.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_file.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_idr.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_list.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_lock.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_mc_timer.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_mem.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_nbuf.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_net_if.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_threads.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_trace.o \
+		$(QDF_LINUX_OBJ_DIR)/qdf_vfs.o \
+		$(QDF_OBJ_DIR)/qdf_flex_mem.o \
+		$(QDF_OBJ_DIR)/qdf_parse.o \
+		$(QDF_OBJ_DIR)/qdf_platform.o \
+		$(QDF_OBJ_DIR)/qdf_str.o \
+		$(QDF_OBJ_DIR)/qdf_types.o \
+
+ifeq ($(CONFIG_WLAN_DEBUGFS), y)
+QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_debugfs.o
+endif
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_ipa.o
+endif
+
+# enable CPU hotplug support if SMP is enabled
+ifeq ($(CONFIG_SMP), y)
+	QDF_OBJS += $(QDF_OBJ_DIR)/qdf_cpuhp.o
+	QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_cpuhp.o
+endif
+
+ifeq ($(CONFIG_LEAK_DETECTION), y)
+	QDF_OBJS += $(QDF_OBJ_DIR)/qdf_debug_domain.o
+endif
+
+############ WBUFF ############
+WBUFF_OS_DIR :=	wbuff
+WBUFF_OS_INC_DIR := $(WBUFF_OS_DIR)/inc
+WBUFF_OS_SRC_DIR := $(WBUFF_OS_DIR)/src
+WBUFF_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(WBUFF_OS_SRC_DIR)
+
+WBUFF_INC :=	-I$(WLAN_COMMON_INC)/$(WBUFF_OS_INC_DIR) \
+
+ifeq ($(CONFIG_WLAN_WBUFF), y)
+WBUFF_OBJS += 	$(WBUFF_OBJ_DIR)/wbuff.o
+endif
+
+##########QAL #######
+QAL_OS_DIR :=	qal
+QAL_OS_INC_DIR := $(QAL_OS_DIR)/inc
+QAL_OS_LINUX_SRC_DIR := $(QAL_OS_DIR)/linux/src
+QAL_LINUX_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(QAL_OS_LINUX_SRC_DIR)
+
+QAL_INC :=	-I$(WLAN_COMMON_INC)/$(QAL_OS_INC_DIR) \
+		-I$(WLAN_COMMON_INC)/$(QAL_OS_LINUX_SRC_DIR)
+
+QAL_OBJS := 	$(QAL_LINUX_OBJ_DIR)/qal_devcfg.o \
+		$(QAL_LINUX_OBJ_DIR)/qal_vbus_dev.o \
+
+##########OS_IF #######
+OS_IF_DIR := $(WLAN_COMMON_ROOT)/os_if
+
+OS_IF_INC := -I$(WLAN_COMMON_INC)/os_if/linux \
+            -I$(WLAN_COMMON_INC)/os_if/linux/scan/inc \
+            -I$(WLAN_COMMON_INC)/os_if/linux/p2p/inc \
+            -I$(WLAN_COMMON_INC)/os_if/linux/spectral/inc \
+            -I$(WLAN_COMMON_INC)/os_if/linux/tdls/inc \
+            -I$(WLAN_COMMON_INC)/os_if/linux/crypto/inc
+
+OS_IF_OBJ := $(OS_IF_DIR)/linux/p2p/src/wlan_cfg80211_p2p.o \
+	     $(OS_IF_DIR)/linux/wlan_osif_request_manager.o \
+	     $(OS_IF_DIR)/linux/crypto/src/wlan_nl_to_crypto_params.o
+
+############ UMAC_DISP ############
+UMAC_DISP_DIR := umac/global_umac_dispatcher/lmac_if
+UMAC_DISP_INC_DIR := $(UMAC_DISP_DIR)/inc
+UMAC_DISP_SRC_DIR := $(UMAC_DISP_DIR)/src
+UMAC_DISP_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_DISP_SRC_DIR)
+
+UMAC_DISP_INC := -I$(WLAN_COMMON_INC)/$(UMAC_DISP_INC_DIR)
+
+UMAC_DISP_OBJS := $(UMAC_DISP_OBJ_DIR)/wlan_lmac_if.o
+
+############# UMAC_SCAN ############
+UMAC_SCAN_DIR := umac/scan
+UMAC_SCAN_DISP_INC_DIR := $(UMAC_SCAN_DIR)/dispatcher/inc
+UMAC_SCAN_CORE_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_SCAN_DIR)/core/src
+UMAC_SCAN_DISP_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_SCAN_DIR)/dispatcher/src
+UMAC_TARGET_SCAN_INC := -I$(WLAN_COMMON_INC)/target_if/scan/inc
+
+UMAC_SCAN_INC := -I$(WLAN_COMMON_INC)/$(UMAC_SCAN_DISP_INC_DIR)
+UMAC_SCAN_OBJS := $(UMAC_SCAN_CORE_DIR)/wlan_scan_cache_db.o \
+		$(UMAC_SCAN_CORE_DIR)/wlan_scan_11d.o \
+		$(UMAC_SCAN_CORE_DIR)/wlan_scan_bss_score.o \
+		$(UMAC_SCAN_CORE_DIR)/wlan_scan_filter.o \
+		$(UMAC_SCAN_CORE_DIR)/wlan_scan_main.o \
+		$(UMAC_SCAN_CORE_DIR)/wlan_scan_manager.o \
+		$(UMAC_SCAN_DISP_DIR)/wlan_scan_tgt_api.o \
+		$(UMAC_SCAN_DISP_DIR)/wlan_scan_ucfg_api.o \
+		$(UMAC_SCAN_DISP_DIR)/wlan_scan_utils_api.o \
+		$(WLAN_COMMON_ROOT)/os_if/linux/scan/src/wlan_cfg80211_scan.o \
+		$(WLAN_COMMON_ROOT)/os_if/linux/wlan_cfg80211.o \
+		$(WLAN_COMMON_ROOT)/target_if/scan/src/target_if_scan.o
+
+ifeq ($(CONFIG_FEATURE_WLAN_EXTSCAN), y)
+UMAC_SCAN_OBJS += $(UMAC_SCAN_DISP_DIR)/wlan_extscan_api.o
+endif
+
+############# UMAC_SPECTRAL_SCAN ############
+UMAC_SPECTRAL_DIR := spectral
+UMAC_SPECTRAL_DISP_INC_DIR := $(UMAC_SPECTRAL_DIR)/dispatcher/inc
+UMAC_SPECTRAL_CORE_INC_DIR := $(UMAC_SPECTRAL_DIR)/core
+UMAC_SPECTRAL_CORE_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_SPECTRAL_DIR)/core
+UMAC_SPECTRAL_DISP_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_SPECTRAL_DIR)/dispatcher/src
+UMAC_TARGET_SPECTRAL_INC := -I$(WLAN_COMMON_INC)/target_if/spectral
+
+UMAC_SPECTRAL_INC := -I$(WLAN_COMMON_INC)/$(UMAC_SPECTRAL_DISP_INC_DIR) \
+			-I$(WLAN_COMMON_INC)/$(UMAC_SPECTRAL_CORE_INC_DIR) \
+			-I$(WLAN_COMMON_INC)/target_if/direct_buf_rx/inc
+ifeq ($(CONFIG_WLAN_CONV_SPECTRAL_ENABLE),y)
+UMAC_SPECTRAL_OBJS := $(UMAC_SPECTRAL_CORE_DIR)/spectral_offload.o \
+		$(UMAC_SPECTRAL_CORE_DIR)/spectral_common.o \
+		$(UMAC_SPECTRAL_DISP_DIR)/wlan_spectral_ucfg_api.o \
+		$(UMAC_SPECTRAL_DISP_DIR)/wlan_spectral_utils_api.o \
+		$(UMAC_SPECTRAL_DISP_DIR)/wlan_spectral_tgt_api.o \
+		$(WLAN_COMMON_ROOT)/os_if/linux/spectral/src/wlan_cfg80211_spectral.o \
+		$(WLAN_COMMON_ROOT)/os_if/linux/spectral/src/os_if_spectral_netlink.o \
+		$(WLAN_COMMON_ROOT)/target_if/spectral/target_if_spectral_netlink.o \
+		$(WLAN_COMMON_ROOT)/target_if/spectral/target_if_spectral_phyerr.o \
+		$(WLAN_COMMON_ROOT)/target_if/spectral/target_if_spectral.o \
+		$(WLAN_COMMON_ROOT)/target_if/spectral/target_if_spectral_sim.o
+endif
+############# UMAC_GREEN_AP ############
+UMAC_GREEN_AP_DIR := umac/green_ap
+UMAC_GREEN_AP_DISP_INC_DIR := $(UMAC_GREEN_AP_DIR)/dispatcher/inc
+UMAC_GREEN_AP_CORE_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_GREEN_AP_DIR)/core/src
+UMAC_GREEN_AP_DISP_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_GREEN_AP_DIR)/dispatcher/src
+UMAC_TARGET_GREEN_AP_INC := -I$(WLAN_COMMON_INC)/target_if/green_ap/inc
+
+UMAC_GREEN_AP_INC := -I$(WLAN_COMMON_INC)/$(UMAC_GREEN_AP_DISP_INC_DIR)
+UMAC_GREEN_AP_OBJS := $(UMAC_GREEN_AP_CORE_DIR)/wlan_green_ap_main.o \
+		$(UMAC_GREEN_AP_DISP_DIR)/wlan_green_ap_api.o \
+                $(UMAC_GREEN_AP_DISP_DIR)/wlan_green_ap_ucfg_api.o \
+                $(WLAN_COMMON_ROOT)/target_if/green_ap/src/target_if_green_ap.o
+
+############# WLAN_CONV_CRYPTO_SUPPORTED ############
+UMAC_CRYPTO_DIR := umac/cmn_services/crypto
+UMAC_CRYPTO_CORE_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_CRYPTO_DIR)/src
+UMAC_CRYPTO_INC := -I$(WLAN_COMMON_INC)/$(UMAC_CRYPTO_DIR)/inc \
+		-I$(WLAN_COMMON_INC)/$(UMAC_CRYPTO_DIR)/src
+UMAC_CRYPTO_OBJS := $(UMAC_CRYPTO_CORE_DIR)/wlan_crypto_global_api.o \
+		$(UMAC_CRYPTO_CORE_DIR)/wlan_crypto_main.o \
+		$(UMAC_CRYPTO_CORE_DIR)/wlan_crypto_obj_mgr.o \
+		$(UMAC_CRYPTO_CORE_DIR)/wlan_crypto_param_handling.o
+
+############# FTM CORE ############
+FTM_CORE_DIR := ftm
+TARGET_IF_FTM_DIR := target_if/ftm
+OS_IF_LINUX_FTM_DIR := os_if/linux/ftm
+
+FTM_CORE_SRC := $(WLAN_COMMON_ROOT)/$(FTM_CORE_DIR)/core/src
+FTM_DISP_SRC := $(WLAN_COMMON_ROOT)/$(FTM_CORE_DIR)/dispatcher/src
+TARGET_IF_FTM_SRC := $(WLAN_COMMON_ROOT)/$(TARGET_IF_FTM_DIR)/src
+OS_IF_FTM_SRC := $(WLAN_COMMON_ROOT)/$(OS_IF_LINUX_FTM_DIR)/src
+
+FTM_CORE_INC := $(WLAN_COMMON_INC)/$(FTM_CORE_DIR)/core/src
+FTM_DISP_INC := $(WLAN_COMMON_INC)/$(FTM_CORE_DIR)/dispatcher/inc
+TARGET_IF_FTM_INC := $(WLAN_COMMON_INC)/$(TARGET_IF_FTM_DIR)/inc
+OS_IF_FTM_INC := $(WLAN_COMMON_INC)/$(OS_IF_LINUX_FTM_DIR)/inc
+
+FTM_INC := -I$(FTM_DISP_INC)	\
+	   -I$(FTM_CORE_INC)	\
+	   -I$(OS_IF_FTM_INC)	\
+	   -I$(TARGET_IF_FTM_INC)
+
+ifeq ($(CONFIG_QCA_WIFI_FTM), y)
+FTM_OBJS := $(FTM_DISP_SRC)/wlan_ftm_init_deinit.o \
+	    $(FTM_DISP_SRC)/wlan_ftm_ucfg_api.o \
+	    $(FTM_CORE_SRC)/wlan_ftm_svc.o \
+	    $(TARGET_IF_FTM_SRC)/target_if_ftm.o
+
+ifeq ($(QCA_WIFI_FTM_NL80211), y)
+FTM_OBJS += $(OS_IF_FTM_SRC)/wlan_cfg80211_ftm.o
+endif
+
+ifeq ($(CONFIG_LINUX_QCMBR), y)
+FTM_OBJS += $(OS_IF_FTM_SRC)/wlan_ioctl_ftm.o
+endif
+
+endif
+
+############# UMAC_CMN_SERVICES ############
+UMAC_COMMON_INC := -I$(WLAN_COMMON_INC)/umac/cmn_services/cmn_defs/inc \
+		-I$(WLAN_COMMON_INC)/umac/cmn_services/utils/inc
+UMAC_COMMON_OBJS := $(WLAN_COMMON_ROOT)/umac/cmn_services/utils/src/wlan_utility.o
+
+ifeq ($(CONFIG_WLAN_LRO), y)
+QDF_OBJS +=     $(QDF_LINUX_OBJ_DIR)/qdf_lro.o
+endif
+
+############ CDS (Connectivity driver services) ############
+CDS_DIR :=	core/cds
+CDS_INC_DIR :=	$(CDS_DIR)/inc
+CDS_SRC_DIR :=	$(CDS_DIR)/src
+
+CDS_INC := 	-I$(WLAN_ROOT)/$(CDS_INC_DIR) \
+		-I$(WLAN_ROOT)/$(CDS_SRC_DIR)
+
+CDS_OBJS :=	$(CDS_SRC_DIR)/cds_api.o \
+		$(CDS_SRC_DIR)/cds_reg_service.o \
+		$(CDS_SRC_DIR)/cds_packet.o \
+		$(CDS_SRC_DIR)/cds_regdomain.o \
+		$(CDS_SRC_DIR)/cds_sched.o \
+		$(CDS_SRC_DIR)/cds_utils.o
+
+
+###### UMAC OBJMGR ########
+UMAC_OBJMGR_DIR := $(WLAN_COMMON_ROOT)/umac/cmn_services/obj_mgr
+
+UMAC_OBJMGR_INC := -I$(WLAN_COMMON_INC)/umac/cmn_services/obj_mgr/inc \
+		-I$(WLAN_COMMON_INC)/umac/cmn_services/obj_mgr/src \
+		-I$(WLAN_COMMON_INC)/umac/cmn_services/inc \
+		-I$(WLAN_COMMON_INC)/umac/global_umac_dispatcher/lmac_if/inc
+
+UMAC_OBJMGR_OBJS := $(UMAC_OBJMGR_DIR)/src/wlan_objmgr_global_obj.o \
+		$(UMAC_OBJMGR_DIR)/src/wlan_objmgr_pdev_obj.o \
+		$(UMAC_OBJMGR_DIR)/src/wlan_objmgr_peer_obj.o \
+		$(UMAC_OBJMGR_DIR)/src/wlan_objmgr_psoc_obj.o \
+		$(UMAC_OBJMGR_DIR)/src/wlan_objmgr_vdev_obj.o
+
+ifeq ($(CONFIG_WLAN_OBJMGR_DEBUG), y)
+UMAC_OBJMGR_OBJS += $(UMAC_OBJMGR_DIR)/src/wlan_objmgr_debug.o
+endif
+
+###########  UMAC MGMT TXRX ##########
+UMAC_MGMT_TXRX_DIR := $(WLAN_COMMON_ROOT)/umac/cmn_services/mgmt_txrx
+
+UMAC_MGMT_TXRX_INC := -I$(WLAN_COMMON_INC)/umac/cmn_services/mgmt_txrx/dispatcher/inc \
+
+UMAC_MGMT_TXRX_OBJS := $(UMAC_MGMT_TXRX_DIR)/core/src/wlan_mgmt_txrx_main.o \
+	$(UMAC_MGMT_TXRX_DIR)/dispatcher/src/wlan_mgmt_txrx_utils_api.o \
+	$(UMAC_MGMT_TXRX_DIR)/dispatcher/src/wlan_mgmt_txrx_tgt_api.o
+
+########## POWER MANAGEMENT OFFLOADS (PMO) ##########
+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 \
+
+ifeq ($(CONFIG_POWER_MANAGEMENT_OFFLOAD), y)
+PMO_OBJS :=     $(PMO_DIR)/core/src/wlan_pmo_main.o \
+		$(PMO_DIR)/core/src/wlan_pmo_apf.o \
+		$(PMO_DIR)/core/src/wlan_pmo_arp.o \
+		$(PMO_DIR)/core/src/wlan_pmo_gtk.o \
+		$(PMO_DIR)/core/src/wlan_pmo_mc_addr_filtering.o \
+		$(PMO_DIR)/core/src/wlan_pmo_static_config.o \
+		$(PMO_DIR)/core/src/wlan_pmo_wow.o \
+		$(PMO_DIR)/core/src/wlan_pmo_lphb.o \
+		$(PMO_DIR)/core/src/wlan_pmo_suspend_resume.o \
+		$(PMO_DIR)/core/src/wlan_pmo_hw_filter.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_obj_mgmt_api.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_ucfg_api.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_arp.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_gtk.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_wow.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_static_config.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_lphb.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_suspend_resume.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_hw_filter.o \
+
+ifeq ($(CONFIG_WLAN_FEATURE_PACKET_FILTERING), y)
+PMO_OBJS +=	$(PMO_DIR)/core/src/wlan_pmo_pkt_filter.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_pkt_filter.o
+endif
+endif
+
+ifeq ($(CONFIG_WLAN_NS_OFFLOAD), y)
+PMO_OBJS +=     $(PMO_DIR)/core/src/wlan_pmo_ns.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_ns.o
+endif
+
+########## DISA (ENCRYPTION TEST) ##########
+
+DISA_DIR :=	components/disa
+DISA_INC :=	-I$(WLAN_ROOT)/$(DISA_DIR)/core/inc \
+		-I$(WLAN_ROOT)/$(DISA_DIR)/dispatcher/inc
+
+ifeq ($(CONFIG_WLAN_FEATURE_DISA), y)
+DISA_OBJS :=	$(DISA_DIR)/core/src/wlan_disa_main.o \
+		$(DISA_DIR)/dispatcher/src/wlan_disa_obj_mgmt_api.o \
+		$(DISA_DIR)/dispatcher/src/wlan_disa_tgt_api.o \
+		$(DISA_DIR)/dispatcher/src/wlan_disa_ucfg_api.o
+endif
+
+######## OCB ##############
+OCB_DIR := components/ocb
+OCB_INC := -I$(WLAN_ROOT)/$(OCB_DIR)/core/inc \
+		-I$(WLAN_ROOT)/$(OCB_DIR)/dispatcher/inc
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+OCB_OBJS :=	$(OCB_DIR)/dispatcher/src/wlan_ocb_ucfg_api.o \
+		$(OCB_DIR)/dispatcher/src/wlan_ocb_tgt_api.o \
+		$(OCB_DIR)/core/src/wlan_ocb_main.o
+endif
+
+######## IPA ##############
+IPA_DIR := components/ipa
+IPA_INC := -I$(WLAN_ROOT)/$(IPA_DIR)/core/inc \
+		-I$(WLAN_ROOT)/$(IPA_DIR)/dispatcher/inc
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+IPA_OBJS :=	$(IPA_DIR)/dispatcher/src/wlan_ipa_ucfg_api.o \
+		$(IPA_DIR)/dispatcher/src/wlan_ipa_obj_mgmt_api.o \
+		$(IPA_DIR)/dispatcher/src/wlan_ipa_tgt_api.o \
+		$(IPA_DIR)/core/src/wlan_ipa_main.o \
+		$(IPA_DIR)/core/src/wlan_ipa_core.o \
+		$(IPA_DIR)/core/src/wlan_ipa_stats.o \
+		$(IPA_DIR)/core/src/wlan_ipa_rm.o
+endif
+
+######## FWOL ##########
+FWOL_DIR := components/fw_offload
+FWOL_INC := -I$(WLAN_ROOT)/$(FWOL_DIR)/core/inc \
+		-I$(WLAN_ROOT)/$(FWOL_DIR)/dispatcher/inc
+
+FWOL_OBJS :=	$(FWOL_DIR)/core/src/wlan_fw_offload_main.o \
+		$(FWOL_DIR)/dispatcher/src/wlan_fwol_ucfg_api.o
+
+######## SM FRAMEWORK  ##############
+UMAC_SM_DIR := umac/cmn_services/sm_engine
+UMAC_SM_INC := -I$(WLAN_COMMON_INC)/$(UMAC_SM_DIR)/inc
+
+UMAC_SM_OBJS := $(WLAN_COMMON_ROOT)/$(UMAC_SM_DIR)/src/wlan_sm_engine.o
+
+ifeq ($(CONFIG_SM_ENG_HIST), y)
+UMAC_SM_OBJS +=	$(WLAN_COMMON_ROOT)/$(UMAC_SM_DIR)/src/wlan_sm_engine_dbg.o
+endif
+
+######## COMMON MLME ##############
+UMAC_MLME_INC := -I$(WLAN_COMMON_INC)/umac/mlme \
+		-I$(WLAN_COMMON_INC)/umac/mlme/mlme_objmgr/dispatcher/inc \
+		-I$(WLAN_COMMON_INC)/umac/mlme/vdev_mgr/dispatcher/inc
+
+ifeq ($(CONFIG_CMN_VDEV_MLME_SM), y)
+UMAC_MLME_OBJS := $(WLAN_COMMON_ROOT)/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.o \
+		$(WLAN_COMMON_ROOT)/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mlme_api.o
+endif
+
+######## MLME ##############
+MLME_DIR := components/mlme
+MLME_INC := -I$(WLAN_ROOT)/$(MLME_DIR)/core/inc \
+		-I$(WLAN_ROOT)/$(MLME_DIR)/dispatcher/inc
+
+MLME_OBJS :=	$(MLME_DIR)/core/src/wlan_mlme_main.o \
+		$(MLME_DIR)/dispatcher/src/wlan_mlme_api.o \
+		$(MLME_DIR)/dispatcher/src/wlan_mlme_ucfg_api.o
+
+ifeq ($(CONFIG_VDEV_SM), y)
+MLME_OBJS += $(MLME_DIR)/core/src/wlan_mlme_vdev_mgr_interface.o
+endif
+
+########## ACTION OUI ##########
+
+ACTION_OUI_DIR := components/action_oui
+ACTION_OUI_INC := -I$(WLAN_ROOT)/$(ACTION_OUI_DIR)/core/inc \
+		  -I$(WLAN_ROOT)/$(ACTION_OUI_DIR)/dispatcher/inc
+
+ifeq ($(CONFIG_WLAN_FEATURE_ACTION_OUI), y)
+ACTION_OUI_OBJS := $(ACTION_OUI_DIR)/core/src/wlan_action_oui_main.o \
+		$(ACTION_OUI_DIR)/core/src/wlan_action_oui_parse.o \
+		$(ACTION_OUI_DIR)/dispatcher/src/wlan_action_oui_tgt_api.o \
+		$(ACTION_OUI_DIR)/dispatcher/src/wlan_action_oui_ucfg_api.o
+endif
+
+########## 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
+
+ifeq ($(CONFIG_POWER_MANAGEMENT_OFFLOAD), y)
+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_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
+ifeq ($(CONFIG_WLAN_NS_OFFLOAD), y)
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_ns.o
+endif
+ifeq ($(CONFIG_WLAN_FEATURE_PACKET_FILTERING), y)
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_pkt_filter.o
+endif
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+CLD_TARGET_IF_INC += -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/ocb/inc
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/ocb/src/target_if_ocb.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DISA), y)
+CLD_TARGET_IF_INC += -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/disa/inc
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/disa/src/target_if_disa.o
+endif
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+CLD_TARGET_IF_INC += -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/ipa/inc
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/ipa/src/target_if_ipa.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_ACTION_OUI), y)
+CLD_TARGET_IF_INC += -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/action_oui/inc
+CLD_TARGET_IF_OBJ += $(CLD_TARGET_IF_DIR)/action_oui/src/target_if_action_oui.o
+endif
+
+############## UMAC P2P ###########
+P2P_DIR := umac/p2p
+P2P_CORE_DIR := $(P2P_DIR)/core
+P2P_CORE_SRC_DIR := $(P2P_CORE_DIR)/src
+P2P_CORE_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(P2P_CORE_SRC_DIR)
+P2P_DISPATCHER_DIR := $(P2P_DIR)/dispatcher
+P2P_DISPATCHER_INC_DIR := $(P2P_DISPATCHER_DIR)/inc
+P2P_DISPATCHER_SRC_DIR := $(P2P_DISPATCHER_DIR)/src
+P2P_DISPATCHER_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(P2P_DISPATCHER_SRC_DIR)
+UMAC_P2P_INC := -I$(WLAN_COMMON_INC)/$(P2P_DISPATCHER_INC_DIR) \
+		-I$(WLAN_COMMON_INC)/umac/scan/dispatcher/inc
+UMAC_P2P_OBJS := $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_ucfg_api.o \
+                 $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_tgt_api.o \
+                 $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_cfg.o \
+                 $(P2P_CORE_OBJ_DIR)/wlan_p2p_main.o \
+                 $(P2P_CORE_OBJ_DIR)/wlan_p2p_roc.o \
+                 $(P2P_CORE_OBJ_DIR)/wlan_p2p_off_chan_tx.o
+
+###### UMAC POLICY MGR ########
+UMAC_POLICY_MGR_DIR := $(WLAN_COMMON_ROOT)/umac/cmn_services/policy_mgr
+
+UMAC_POLICY_MGR_INC := -I$(WLAN_COMMON_INC)/umac/cmn_services/policy_mgr/inc \
+		-I$(WLAN_COMMON_INC)/umac/cmn_services/policy_mgr/src
+
+UMAC_POLICY_MGR_OBJS := $(UMAC_POLICY_MGR_DIR)/src/wlan_policy_mgr_action.o \
+	$(UMAC_POLICY_MGR_DIR)/src/wlan_policy_mgr_core.o \
+	$(UMAC_POLICY_MGR_DIR)/src/wlan_policy_mgr_get_set_utils.o \
+	$(UMAC_POLICY_MGR_DIR)/src/wlan_policy_mgr_init_deinit.o \
+	$(UMAC_POLICY_MGR_DIR)/src/wlan_policy_mgr_ucfg.o \
+	$(UMAC_POLICY_MGR_DIR)/src/wlan_policy_mgr_pcl.o \
+
+###### UMAC TDLS ########
+UMAC_TDLS_DIR := $(WLAN_COMMON_ROOT)/umac/tdls
+
+UMAC_TDLS_INC := -I$(WLAN_COMMON_INC)/umac/tdls/dispatcher/inc
+
+UMAC_TDLS_OBJS := $(UMAC_TDLS_DIR)/core/src/wlan_tdls_main.o \
+       $(UMAC_TDLS_DIR)/core/src/wlan_tdls_cmds_process.o \
+       $(UMAC_TDLS_DIR)/core/src/wlan_tdls_peer.o \
+       $(UMAC_TDLS_DIR)/core/src/wlan_tdls_mgmt.o \
+       $(UMAC_TDLS_DIR)/core/src/wlan_tdls_ct.o \
+       $(UMAC_TDLS_DIR)/dispatcher/src/wlan_tdls_tgt_api.o \
+       $(UMAC_TDLS_DIR)/dispatcher/src/wlan_tdls_ucfg_api.o \
+       $(UMAC_TDLS_DIR)/dispatcher/src/wlan_tdls_utils_api.o \
+       $(UMAC_TDLS_DIR)/dispatcher/src/wlan_tdls_cfg.o \
+       $(WLAN_COMMON_ROOT)/os_if/linux/tdls/src/wlan_cfg80211_tdls.o
+
+########### BMI ###########
+BMI_DIR := core/bmi
+
+BMI_INC := -I$(WLAN_ROOT)/$(BMI_DIR)/inc
+
+ifeq ($(CONFIG_WLAN_FEATURE_BMI), y)
+BMI_OBJS := $(BMI_DIR)/src/bmi.o \
+            $(BMI_DIR)/src/bmi_1.o \
+            $(BMI_DIR)/src/ol_fw.o \
+            $(BMI_DIR)/src/ol_fw_common.o
+endif
+
+##########  TARGET_IF #######
+TARGET_IF_DIR := $(WLAN_COMMON_ROOT)/target_if
+
+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/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)/p2p/src/target_if_p2p.o \
+		$(TARGET_IF_DIR)/regulatory/src/target_if_reg.o \
+		$(TARGET_IF_DIR)/tdls/src/target_if_tdls.o \
+		$(TARGET_IF_DIR)/init_deinit/src/init_cmd_api.o \
+		$(TARGET_IF_DIR)/init_deinit/src/init_deinit_lmac.o \
+		$(TARGET_IF_DIR)/init_deinit/src/init_event_handler.o \
+		$(TARGET_IF_DIR)/init_deinit/src/service_ready_util.o \
+
+########### GLOBAL_LMAC_IF ##########
+GLOBAL_LMAC_IF_DIR := $(WLAN_COMMON_ROOT)/global_lmac_if
+
+GLOBAL_LMAC_IF_INC := -I$(WLAN_COMMON_INC)/global_lmac_if/inc \
+                      -I$(WLAN_COMMON_INC)/global_lmac_if/src
+
+GLOBAL_LMAC_IF_OBJ := $(GLOBAL_LMAC_IF_DIR)/src/wlan_global_lmac_if.o
+
+########### WMI ###########
+WMI_ROOT_DIR := wmi
+
+WMI_SRC_DIR := $(WMI_ROOT_DIR)/src
+WMI_INC_DIR := $(WMI_ROOT_DIR)/inc
+WMI_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(WMI_SRC_DIR)
+
+WMI_INC := -I$(WLAN_COMMON_INC)/$(WMI_INC_DIR)
+
+WMI_OBJS := $(WMI_OBJ_DIR)/wmi_unified.o \
+	    $(WMI_OBJ_DIR)/wmi_tlv_helper.o \
+	    $(WMI_OBJ_DIR)/wmi_unified_tlv.o \
+	    $(WMI_OBJ_DIR)/wmi_unified_api.o \
+	    $(WMI_OBJ_DIR)/wmi_unified_reg_api.o
+
+ifeq ($(CONFIG_POWER_MANAGEMENT_OFFLOAD), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_pmo_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_pmo_tlv.o
+endif
+
+ifeq ($(CONFIG_QCACLD_FEATURE_APF), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_apf_tlv.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_ACTION_OUI), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_action_oui_tlv.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+ifeq ($(CONFIG_OCB_UT_FRAMEWORK), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_ocb_ut.o
+endif
+endif
+
+ifeq ($(CONFIG_WLAN_DFS_MASTER_ENABLE), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_dfs_api.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_TWT), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_twt_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_twt_tlv.o
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_ocb_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_ocb_tlv.o
+endif
+
+ifeq ($(CONFIG_FEATURE_WLAN_EXTSCAN), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_extscan_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_extscan_tlv.o
+endif
+
+ifeq ($(CONFIG_NAN_CONVERGENCE), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_nan_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_nan_tlv.o
+endif
+
+ifeq ($(CONFIG_CONVERGED_P2P_ENABLE), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_p2p_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_p2p_tlv.o
+endif
+
+ifeq ($(CONFIG_WMI_ROAM_SUPPORT), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_roam_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_roam_tlv.o
+endif
+
+ifeq ($(CONFIG_WMI_CONCURRENCY_SUPPORT), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_concurrency_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_concurrency_tlv.o
+endif
+
+ifeq ($(CONFIG_WMI_STA_SUPPORT), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_sta_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_sta_tlv.o
+endif
+
+########### FWLOG ###########
+FWLOG_DIR := $(WLAN_COMMON_ROOT)/utils/fwlog
+
+FWLOG_INC := -I$(WLAN_ROOT)/$(FWLOG_DIR)
+
+FWLOG_OBJS := $(FWLOG_DIR)/dbglog_host.o
+
+############ TXRX ############
+TXRX_DIR :=     core/dp/txrx
+TXRX_INC :=     -I$(WLAN_ROOT)/$(TXRX_DIR)
+
+TXRX_OBJS := $(TXRX_DIR)/ol_txrx.o \
+                $(TXRX_DIR)/ol_cfg.o \
+                $(TXRX_DIR)/ol_rx.o \
+                $(TXRX_DIR)/ol_rx_fwd.o \
+                $(TXRX_DIR)/ol_txrx.o \
+                $(TXRX_DIR)/ol_rx_defrag.o \
+                $(TXRX_DIR)/ol_tx_desc.o \
+                $(TXRX_DIR)/ol_tx.o \
+                $(TXRX_DIR)/ol_rx_reorder_timeout.o \
+                $(TXRX_DIR)/ol_rx_reorder.o \
+                $(TXRX_DIR)/ol_rx_pn.o \
+                $(TXRX_DIR)/ol_txrx_peer_find.o \
+                $(TXRX_DIR)/ol_txrx_encap.o \
+                $(TXRX_DIR)/ol_tx_send.o
+
+ifeq ($(CONFIG_WDI_EVENT_ENABLE), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_txrx_event.o
+endif
+
+ifeq ($(CONFIG_LL_DP_SUPPORT), y)
+
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_ll.o
+
+ifeq ($(CONFIG_WLAN_FASTPATH), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_ll_fastpath.o
+else
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_ll_legacy.o
+endif
+
+ifeq ($(CONFIG_WLAN_TX_FLOW_CONTROL_V2), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_txrx_flow_control.o
+endif
+
+endif #CONFIG_LL_DP_SUPPORT
+
+ifeq ($(CONFIG_HL_DP_SUPPORT), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_hl.o
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_classify.o
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_sched.o
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_queue.o
+endif #CONFIG_HL_DP_SUPPORT
+
+ifeq ($(CONFIG_WLAN_TX_FLOW_CONTROL_LEGACY), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_txrx_legacy_flow_control.o
+endif
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_txrx_ipa.o
+endif
+
+ifeq ($(CONFIG_QCA_SUPPORT_TX_THROTTLE), y)
+TXRX_OBJS +=     $(TXRX_DIR)/ol_tx_throttle.o
+endif
+
+############ TXRX 3.0 ############
+TXRX3.0_DIR :=     core/dp/txrx3.0
+TXRX3.0_INC :=     -I$(WLAN_ROOT)/$(TXRX3.0_DIR)
+TXRX3.0_OBJS := $(TXRX3.0_DIR)/dp_txrx.o \
+		$(TXRX3.0_DIR)/dp_rx_thread.o
+ifeq ($(CONFIG_LITHIUM), y)
+############ DP 3.0 ############
+DP_INC := -I$(WLAN_COMMON_INC)/dp/inc \
+	-I$(WLAN_COMMON_INC)/dp/wifi3.0 \
+	-I$(WLAN_COMMON_INC)/target_if/dp/inc
+
+DP_SRC := $(WLAN_COMMON_ROOT)/dp/wifi3.0
+DP_OBJS := $(DP_SRC)/dp_main.o \
+		$(DP_SRC)/dp_tx.o \
+		$(DP_SRC)/dp_tx_desc.o \
+		$(DP_SRC)/dp_rx.o \
+		$(DP_SRC)/dp_rx_err.o \
+		$(DP_SRC)/dp_htt.o \
+		$(DP_SRC)/dp_peer.o \
+		$(DP_SRC)/dp_rx_desc.o \
+		$(DP_SRC)/dp_reo.o \
+		$(DP_SRC)/dp_rx_mon_dest.o \
+		$(DP_SRC)/dp_rx_mon_status.o \
+		$(DP_SRC)/dp_rx_defrag.o \
+		$(DP_SRC)/dp_stats.o \
+		$(WLAN_COMMON_ROOT)/target_if/dp/src/target_if_dp.o
+ifeq ($(CONFIG_WLAN_TX_FLOW_CONTROL_V2), y)
+DP_OBJS += $(DP_SRC)/dp_tx_flow_control.o
+endif
+endif
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+DP_OBJS +=     $(DP_SRC)/dp_ipa.o
+endif
+
+ifeq ($(CONFIG_WDI_EVENT_ENABLE), y)
+DP_OBJS +=     $(DP_SRC)/dp_wdi_event.o
+endif
+
+############ CFG ############
+WCFG_DIR := wlan_cfg
+WCFG_INC := -I$(WLAN_COMMON_INC)/$(WCFG_DIR)
+WCFG_SRC := $(WLAN_COMMON_ROOT)/$(WCFG_DIR)
+
+ifeq ($(CONFIG_LITHIUM), y)
+WCFG_OBJS := $(WCFG_SRC)/wlan_cfg.o
+endif
+
+############ OL ############
+OL_DIR :=     core/dp/ol
+OL_INC :=     -I$(WLAN_ROOT)/$(OL_DIR)/inc
+
+############ CDP ############
+CDP_ROOT_DIR := dp
+CDP_INC_DIR := $(CDP_ROOT_DIR)/inc
+CDP_INC := -I$(WLAN_COMMON_INC)/$(CDP_INC_DIR)
+
+############ PKTLOG ############
+PKTLOG_DIR :=      $(WLAN_COMMON_ROOT)/utils/pktlog
+PKTLOG_INC :=      -I$(WLAN_ROOT)/$(PKTLOG_DIR)/include
+
+PKTLOG_OBJS :=	$(PKTLOG_DIR)/pktlog_ac.o \
+		$(PKTLOG_DIR)/pktlog_internal.o \
+		$(PKTLOG_DIR)/linux_ac.o
+
+############ HTT ############
+HTT_DIR :=      core/dp/htt
+HTT_INC :=      -I$(WLAN_ROOT)/$(HTT_DIR)
+
+HTT_OBJS := $(HTT_DIR)/htt_tx.o \
+            $(HTT_DIR)/htt.o \
+            $(HTT_DIR)/htt_t2h.o \
+            $(HTT_DIR)/htt_h2t.o \
+            $(HTT_DIR)/htt_fw_stats.o \
+            $(HTT_DIR)/htt_rx.o
+
+ifeq ($(CONFIG_FEATURE_MONITOR_MODE_SUPPORT), y)
+HTT_OBJS += $(HTT_DIR)/htt_monitor_rx.o
+endif
+
+ifeq ($(CONFIG_LL_DP_SUPPORT), y)
+HTT_OBJS += $(HTT_DIR)/htt_rx_ll.o
+endif
+
+ifeq ($(CONFIG_HL_DP_SUPPORT), y)
+HTT_OBJS += $(HTT_DIR)/htt_rx_hl.o
+endif
+
+############## INIT-DEINIT ###########
+INIT_DEINIT_DIR := init_deinit/dispatcher
+INIT_DEINIT_INC_DIR := $(INIT_DEINIT_DIR)/inc
+INIT_DEINIT_SRC_DIR := $(INIT_DEINIT_DIR)/src
+INIT_DEINIT_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(INIT_DEINIT_SRC_DIR)
+INIT_DEINIT_INC := -I$(WLAN_COMMON_INC)/$(INIT_DEINIT_INC_DIR)
+INIT_DEINIT_OBJS := $(INIT_DEINIT_OBJ_DIR)/dispatcher_init_deinit.o
+
+############## REGULATORY ###########
+REGULATORY_DIR := umac/regulatory
+REGULATORY_CORE_INC_DIR := $(REGULATORY_DIR)/core/inc
+REGULATORY_CORE_SRC_DIR := $(REGULATORY_DIR)/core/src
+REG_DISPATCHER_INC_DIR := $(REGULATORY_DIR)/dispatcher/inc
+REG_DISPATCHER_SRC_DIR := $(REGULATORY_DIR)/dispatcher/src
+REG_CORE_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(REGULATORY_CORE_SRC_DIR)
+REG_DISPATCHER_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(REG_DISPATCHER_SRC_DIR)
+REGULATORY_INC := -I$(WLAN_COMMON_INC)/$(REGULATORY_CORE_INC_DIR)
+REGULATORY_INC += -I$(WLAN_COMMON_INC)/$(REG_DISPATCHER_INC_DIR)
+REGULATORY_OBJS := $(REG_CORE_OBJ_DIR)/reg_db.o \
+                   $(REG_CORE_OBJ_DIR)/reg_services.o \
+                   $(REG_CORE_OBJ_DIR)/reg_db_parser.o \
+                   $(REG_DISPATCHER_OBJ_DIR)/wlan_reg_services_api.o \
+                   $(REG_DISPATCHER_OBJ_DIR)/wlan_reg_tgt_api.o \
+                   $(REG_DISPATCHER_OBJ_DIR)/wlan_reg_ucfg_api.o
+ifeq ($(CONFIG_HOST_11D_SCAN), y)
+REGULATORY_OBJS += $(REG_CORE_OBJ_DIR)/reg_host_11d.o
+endif
+
+############## Control path common scheduler ##########
+SCHEDULER_DIR := scheduler
+SCHEDULER_INC_DIR := $(SCHEDULER_DIR)/inc
+SCHEDULER_SRC_DIR := $(SCHEDULER_DIR)/src
+SCHEDULER_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(SCHEDULER_SRC_DIR)
+SCHEDULER_INC := -I$(WLAN_COMMON_INC)/$(SCHEDULER_INC_DIR)
+SCHEDULER_OBJS := $(SCHEDULER_OBJ_DIR)/scheduler_api.o \
+                  $(SCHEDULER_OBJ_DIR)/scheduler_core.o
+
+###### UMAC SERIALIZATION ########
+UMAC_SER_DIR := umac/cmn_services/serialization
+UMAC_SER_INC_DIR := $(UMAC_SER_DIR)/inc
+UMAC_SER_SRC_DIR := $(UMAC_SER_DIR)/src
+UMAC_SER_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_SER_SRC_DIR)
+
+UMAC_SER_INC := -I$(WLAN_COMMON_INC)/$(UMAC_SER_INC_DIR)
+UMAC_SER_OBJS := $(UMAC_SER_OBJ_DIR)/wlan_serialization_main.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_api.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_utils.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_legacy_api.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_rules.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_internal.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_non_scan.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_queue.o \
+		 $(UMAC_SER_OBJ_DIR)/wlan_serialization_scan.o
+
+###### WIFI POS ########
+WIFI_POS_OS_IF_DIR := $(WLAN_COMMON_ROOT)/os_if/linux/wifi_pos/src
+WIFI_POS_OS_IF_INC := -I$(WLAN_COMMON_INC)/os_if/linux/wifi_pos/inc
+WIFI_POS_TGT_DIR := $(WLAN_COMMON_ROOT)/target_if/wifi_pos/src
+WIFI_POS_TGT_INC := -I$(WLAN_COMMON_INC)/target_if/wifi_pos/inc
+WIFI_POS_CORE_DIR := $(WLAN_COMMON_ROOT)/umac/wifi_pos/src
+WIFI_POS_API_INC := -I$(WLAN_COMMON_INC)/umac/wifi_pos/inc
+
+
+ifeq ($(CONFIG_WIFI_POS_CONVERGED), y)
+WIFI_POS_OBJS := $(WIFI_POS_CORE_DIR)/wifi_pos_api.o \
+		 $(WIFI_POS_CORE_DIR)/wifi_pos_main.o \
+		 $(WIFI_POS_CORE_DIR)/wifi_pos_ucfg.o \
+		 $(WIFI_POS_CORE_DIR)/wifi_pos_utils.o \
+		 $(WIFI_POS_OS_IF_DIR)/os_if_wifi_pos.o \
+		 $(WIFI_POS_TGT_DIR)/target_if_wifi_pos.o
+endif
+
+###### CP STATS ########
+CP_STATS_OS_IF_SRC      := $(WLAN_COMMON_ROOT)/os_if/linux/cp_stats/src
+CP_STATS_TGT_SRC        := $(WLAN_COMMON_ROOT)/target_if/cp_stats/src
+CP_STATS_CORE_SRC       := $(WLAN_COMMON_ROOT)/umac/cp_stats/core/src
+CP_STATS_DISPATCHER_SRC := $(WLAN_COMMON_ROOT)/umac/cp_stats/dispatcher/src
+
+CP_STATS_OS_IF_INC      := -I$(WLAN_COMMON_INC)/os_if/linux/cp_stats/inc
+CP_STATS_TGT_INC        := -I$(WLAN_COMMON_INC)/target_if/cp_stats/inc
+CP_STATS_DISPATCHER_INC := -I$(WLAN_COMMON_INC)/umac/cp_stats/dispatcher/inc
+
+ifeq ($(CONFIG_CP_STATS), y)
+CP_STATS_OBJS := $(CP_STATS_TGT_SRC)/target_if_mc_cp_stats.o                 \
+		 $(CP_STATS_CORE_SRC)/wlan_cp_stats_comp_handler.o           \
+		 $(CP_STATS_CORE_SRC)/wlan_cp_stats_obj_mgr_handler.o        \
+		 $(CP_STATS_CORE_SRC)/wlan_cp_stats_ol_api.o                 \
+		 $(CP_STATS_OS_IF_SRC)/wlan_cfg80211_mc_cp_stats.o           \
+		 $(CP_STATS_DISPATCHER_SRC)/wlan_cp_stats_utils_api.o        \
+		 $(CP_STATS_DISPATCHER_SRC)/wlan_cp_stats_mc_tgt_api.o       \
+		 $(CP_STATS_DISPATCHER_SRC)/wlan_cp_stats_mc_ucfg_api.o
+endif
+
+######################### NAN #########################
+NAN_CORE_DIR := $(WLAN_COMMON_ROOT)/umac/nan/core/src
+NAN_CORE_INC := -I$(WLAN_COMMON_INC)/umac/nan/core/inc
+NAN_UCFG_DIR := $(WLAN_COMMON_ROOT)/umac/nan/dispatcher/src
+NAN_UCFG_INC := -I$(WLAN_COMMON_INC)/umac/nan/dispatcher/inc
+NAN_TGT_DIR  := $(WLAN_COMMON_ROOT)/target_if/nan/src
+NAN_TGT_INC  := -I$(WLAN_COMMON_INC)/target_if/nan/inc
+NAN_OS_IF_DIR  := $(WLAN_COMMON_ROOT)/os_if/linux/nan/src
+NAN_OS_IF_INC  := -I$(WLAN_COMMON_INC)/os_if/linux/nan/inc
+
+ifeq ($(CONFIG_NAN_CONVERGENCE), y)
+WLAN_NAN_OBJS := $(NAN_CORE_DIR)/nan_main.o \
+		 $(NAN_CORE_DIR)/nan_api.o \
+		 $(NAN_CORE_DIR)/nan_utils.o \
+		 $(NAN_UCFG_DIR)/nan_ucfg_api.o \
+		 $(NAN_UCFG_DIR)/cfg_nan.o \
+		 $(NAN_TGT_DIR)/target_if_nan.o \
+		 $(NAN_OS_IF_DIR)/os_if_nan.o
+endif
+#######################################################
+
+############## HTC ##########
+HTC_DIR := htc
+HTC_INC := -I$(WLAN_COMMON_INC)/$(HTC_DIR)
+
+HTC_OBJS := $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc.o \
+            $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc_send.o \
+            $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc_recv.o \
+            $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc_services.o
+
+ifeq ($(CONFIG_FEATURE_HTC_CREDIT_HISTORY), y)
+HTC_OBJS += $(WLAN_COMMON_ROOT)/$(HTC_DIR)/htc_credit_history.o
+endif
+
+########### HIF ###########
+HIF_DIR := hif
+HIF_CE_DIR := $(HIF_DIR)/src/ce
+
+HIF_DISPATCHER_DIR := $(HIF_DIR)/src/dispatcher
+
+HIF_PCIE_DIR := $(HIF_DIR)/src/pcie
+HIF_SNOC_DIR := $(HIF_DIR)/src/snoc
+HIF_USB_DIR := $(HIF_DIR)/src/usb
+HIF_SDIO_DIR := $(HIF_DIR)/src/sdio
+
+HIF_SDIO_NATIVE_DIR := $(HIF_SDIO_DIR)/native_sdio
+HIF_SDIO_NATIVE_INC_DIR := $(HIF_SDIO_NATIVE_DIR)/include
+HIF_SDIO_NATIVE_SRC_DIR := $(HIF_SDIO_NATIVE_DIR)/src
+
+HIF_INC := -I$(WLAN_COMMON_INC)/$(HIF_DIR)/inc \
+	   -I$(WLAN_COMMON_INC)/$(HIF_DIR)/src
+
+ifeq ($(CONFIG_HIF_PCI), y)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_DISPATCHER_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_PCIE_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_CE_DIR)
+endif
+
+ifeq ($(CONFIG_HIF_SNOC), y)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_DISPATCHER_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_SNOC_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_CE_DIR)
+endif
+
+ifeq ($(CONFIG_HIF_USB), y)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_DISPATCHER_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_USB_DIR)
+endif
+
+ifeq ($(CONFIG_HIF_SDIO), y)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_DISPATCHER_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_SDIO_DIR)
+HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_SDIO_NATIVE_INC_DIR)
+endif
+
+HIF_COMMON_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/ath_procfs.o \
+		   $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_main.o
+
+ifneq ($(CONFIG_LITHIUM), y)
+HIF_COMMON_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_main_legacy.o
+endif
+
+ifeq ($(CONFIG_WLAN_NAPI), y)
+HIF_COMMON_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_exec.o
+HIF_COMMON_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_irq_affinity.o
+endif
+
+HIF_CE_OBJS :=  $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_diag.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_main.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_service.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_tasklet.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/mp_dev.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/regtable.o
+
+ifeq ($(CONFIG_WLAN_FEATURE_BMI), y)
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_bmi.o
+endif
+
+ifeq ($(CONFIG_LITHIUM), y)
+ifeq ($(CONFIG_CNSS_QCA6290), y)
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/qca6290def.o
+endif
+
+ifeq ($(CONFIG_CNSS_QCA6390), y)
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/qca6390def.o
+endif
+
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_service_srng.o
+else
+HIF_CE_OBJS +=  $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_service_legacy.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 \
+                $(WLAN_COMMON_ROOT)/$(HIF_USB_DIR)/regtable_usb.o
+
+HIF_SDIO_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/hif_diag_reg_access.o \
+                 $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/hif_sdio_dev.o \
+                 $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/hif_sdio.o \
+                 $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/regtable_sdio.o \
+                 $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/transfer/transfer.o
+
+ifeq ($(CONFIG_WLAN_FEATURE_BMI), y)
+HIF_SDIO_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/hif_bmi_reg_access.o
+endif
+
+ifeq ($(CONFIG_SDIO_TRANSFER), adma)
+HIF_SDIO_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/transfer/adma.o
+else
+HIF_SDIO_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/transfer/mailbox.o
+endif
+
+HIF_SDIO_NATIVE_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_SDIO_NATIVE_SRC_DIR)/hif.o \
+                        $(WLAN_COMMON_ROOT)/$(HIF_SDIO_NATIVE_SRC_DIR)/hif_scatter.o \
+                        $(WLAN_COMMON_ROOT)/$(HIF_SDIO_NATIVE_SRC_DIR)/dev_quirks.o
+
+ifeq ($(CONFIG_WLAN_NAPI), y)
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_napi.o
+endif
+
+ifeq ($(CONFIG_FEATURE_UNIT_TEST_SUSPEND), y)
+	HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_unit_test_suspend.o
+endif
+
+HIF_PCIE_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_PCIE_DIR)/if_pci.o
+HIF_SNOC_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_SNOC_DIR)/if_snoc.o
+HIF_SDIO_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/if_sdio.o
+
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus.o
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/dummy.o
+HIF_OBJS += $(HIF_COMMON_OBJS)
+
+ifeq ($(CONFIG_HIF_PCI), y)
+HIF_OBJS += $(HIF_PCIE_OBJS)
+HIF_OBJS += $(HIF_CE_OBJS)
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus_pci.o
+endif
+
+ifeq ($(CONFIG_HIF_SNOC), y)
+HIF_OBJS += $(HIF_SNOC_OBJS)
+HIF_OBJS += $(HIF_CE_OBJS)
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus_snoc.o
+endif
+
+ifeq ($(CONFIG_HIF_SDIO), y)
+HIF_OBJS += $(HIF_SDIO_OBJS)
+HIF_OBJS += $(HIF_SDIO_NATIVE_OBJS)
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus_sdio.o
+endif
+
+ifeq ($(CONFIG_HIF_USB), y)
+HIF_OBJS += $(HIF_USB_OBJS)
+HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus_usb.o
+endif
+
+ifeq ($(CONFIG_LITHIUM), y)
+############ HAL ############
+HAL_DIR :=	hal
+HAL_INC :=	-I$(WLAN_COMMON_INC)/$(HAL_DIR)/inc \
+		-I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0
+
+HAL_OBJS :=	$(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/hal_srng.o \
+		$(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/hal_reo.o
+
+ifeq ($(CONFIG_CNSS_QCA6290), y)
+HAL_INC += -I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/qca6290
+HAL_OBJS += $(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/qca6290/hal_6290.o
+else ifeq ($(CONFIG_CNSS_QCA6390), y)
+HAL_INC += -I$(WLAN_COMMON_INC)/$(HAL_DIR)/wifi3.0/qca6390
+HAL_OBJS += $(WLAN_COMMON_ROOT)/$(HAL_DIR)/wifi3.0/qca6390/hal_6390.o
+else
+#error "Not 11ax"
+endif
+
+endif #####CONFIG_LITHIUM####
+
+############ WMA ############
+WMA_DIR :=	core/wma
+
+WMA_INC_DIR :=  $(WMA_DIR)/inc
+WMA_SRC_DIR :=  $(WMA_DIR)/src
+
+WMA_INC :=	-I$(WLAN_ROOT)/$(WMA_INC_DIR) \
+		-I$(WLAN_ROOT)/$(WMA_SRC_DIR)
+
+ifeq ($(CONFIG_WLAN_FEATURE_NAN_DATAPATH), y)
+WMA_NDP_OBJS += $(WMA_SRC_DIR)/wma_nan_datapath.o
+endif
+
+WMA_OBJS :=	$(WMA_SRC_DIR)/wma_main.o \
+		$(WMA_SRC_DIR)/wma_scan_roam.o \
+		$(WMA_SRC_DIR)/wma_dev_if.o \
+		$(WMA_SRC_DIR)/wma_mgmt.o \
+		$(WMA_SRC_DIR)/wma_power.o \
+		$(WMA_SRC_DIR)/wma_data.o \
+		$(WMA_SRC_DIR)/wma_utils.o \
+		$(WMA_SRC_DIR)/wma_features.o \
+		$(WMA_SRC_DIR)/wlan_qct_wma_legacy.o\
+		$(WMA_NDP_OBJS)
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+WMA_OBJS+=	$(WMA_SRC_DIR)/wma_ocb.o
+endif
+ifeq ($(CONFIG_WLAN_FEATURE_FIPS), y)
+WMA_OBJS+=	$(WMA_SRC_DIR)/wma_fips_api.o
+endif
+ifeq ($(CONFIG_MPC_UT_FRAMEWORK), y)
+WMA_OBJS +=	$(WMA_SRC_DIR)/wma_utils_ut.o
+endif
+ifeq ($(CONFIG_WLAN_FEATURE_11AX), y)
+WMA_OBJS+=	$(WMA_SRC_DIR)/wma_he.o
+endif
+ifeq ($(CONFIG_WLAN_FEATURE_TWT), y)
+WMA_OBJS +=	$(WMA_SRC_DIR)/wma_twt.o
+endif
+############## PLD ##########
+PLD_DIR := core/pld
+PLD_INC_DIR := $(PLD_DIR)/inc
+PLD_SRC_DIR := $(PLD_DIR)/src
+
+PLD_INC :=	-I$(WLAN_ROOT)/$(PLD_INC_DIR) \
+		-I$(WLAN_ROOT)/$(PLD_SRC_DIR)
+
+PLD_OBJS :=	$(PLD_SRC_DIR)/pld_common.o
+
+ifeq ($(CONFIG_HIF_PCI), y)
+PLD_OBJS +=	$(PLD_SRC_DIR)/pld_pcie.o
+endif
+ifeq ($(CONFIG_ICNSS), y)
+PLD_OBJS +=	$(PLD_SRC_DIR)/pld_snoc.o
+endif
+ifeq ($(CONFIG_QCA_WIFI_SDIO), y)
+PLD_OBJS +=	$(PLD_SRC_DIR)/pld_sdio.o
+endif
+ifeq ($(CONFIG_HIF_USB), y)
+PLD_OBJS +=	$(PLD_SRC_DIR)/pld_usb.o
+endif
+
+TARGET_INC := 	-I$(WLAN_ROOT)/../fw-api/fw
+
+ifeq ($(CONFIG_CNSS_QCA6290), y)
+ifeq ($(CONFIG_QCA6290_11AX), y)
+TARGET_INC +=	-I$(WLAN_ROOT)/../fw-api/hw/qca6290/11ax/v2
+else
+TARGET_INC +=	-I$(WLAN_ROOT)/../fw-api/hw/qca6290/v2
+endif
+endif
+
+ifeq ($(CONFIG_CNSS_QCA6390), y)
+TARGET_INC +=	-I$(WLAN_ROOT)/../fw-api/hw/qca6390/v1
+endif
+
+LINUX_INC :=	-Iinclude
+
+INCS :=		$(HDD_INC) \
+		$(DSC_INC) \
+		$(EPPING_INC) \
+		$(LINUX_INC) \
+		$(MAC_INC) \
+		$(SAP_INC) \
+		$(SME_INC) \
+		$(SYS_INC) \
+		$(QAL_INC) \
+		$(QDF_INC) \
+		$(WBUFF_INC) \
+		$(CDS_INC) \
+		$(CFG_INC) \
+		$(DFS_INC) \
+		$(TARGET_IF_INC) \
+		$(CLD_TARGET_IF_INC) \
+		$(OS_IF_INC) \
+		$(GLOBAL_LMAC_IF_INC) \
+		$(FTM_INC)
+
+INCS +=		$(WMA_INC) \
+		$(UAPI_INC) \
+		$(COMMON_INC) \
+		$(WMI_INC) \
+		$(FWLOG_INC) \
+		$(TXRX_INC) \
+		$(OL_INC) \
+		$(CDP_INC) \
+		$(PKTLOG_INC) \
+		$(HTT_INC) \
+		$(INIT_DEINIT_INC) \
+		$(SCHEDULER_INC) \
+		$(REGULATORY_INC) \
+		$(HTC_INC) \
+		$(DFS_INC) \
+		$(WCFG_INC) \
+		$(TXRX3.0_INC)
+
+INCS +=		$(HIF_INC) \
+		$(BMI_INC)
+
+ifeq ($(CONFIG_LITHIUM), y)
+INCS += 	$(HAL_INC) \
+		$(DP_INC)
+endif
+
+################ WIFI POS ################
+INCS +=		$(WIFI_POS_API_INC)
+INCS +=		$(WIFI_POS_TGT_INC)
+INCS +=		$(WIFI_POS_OS_IF_INC)
+################ CP STATS ################
+INCS +=		$(CP_STATS_OS_IF_INC)
+INCS +=		$(CP_STATS_TGT_INC)
+INCS +=		$(CP_STATS_DISPATCHER_INC)
+################ NAN POS ################
+INCS +=		$(NAN_CORE_INC)
+INCS +=		$(NAN_UCFG_INC)
+INCS +=		$(NAN_TGT_INC)
+INCS +=		$(NAN_OS_IF_INC)
+##########################################
+INCS +=		$(UMAC_OBJMGR_INC)
+INCS +=		$(UMAC_MGMT_TXRX_INC)
+INCS +=		$(PMO_INC)
+INCS +=		$(UMAC_P2P_INC)
+INCS +=		$(UMAC_POLICY_MGR_INC)
+INCS +=		$(TARGET_INC)
+INCS +=		$(UMAC_TDLS_INC)
+INCS +=		$(UMAC_SER_INC)
+INCS +=		$(NLINK_INC) \
+		$(PTT_INC) \
+		$(WLAN_LOGGING_INC)
+
+INCS +=		$(PLD_INC)
+INCS +=		$(OCB_INC)
+
+INCS +=		$(IPA_INC)
+INCS +=		$(UMAC_SM_INC)
+INCS +=		$(UMAC_MLME_INC)
+INCS +=		$(MLME_INC)
+INCS +=		$(FWOL_INC)
+
+ifeq ($(CONFIG_REMOVE_PKT_LOG), n)
+INCS +=		$(PKTLOG_INC)
+endif
+
+INCS +=		$(HOST_DIAG_LOG_INC)
+
+INCS +=		$(DISA_INC)
+INCS +=		$(ACTION_OUI_INC)
+
+INCS +=		$(UMAC_DISP_INC)
+INCS +=		$(UMAC_SCAN_INC)
+INCS +=		$(UMAC_TARGET_SCAN_INC)
+INCS +=		$(UMAC_GREEN_AP_INC)
+INCS +=		$(UMAC_TARGET_GREEN_AP_INC)
+INCS +=		$(UMAC_COMMON_INC)
+INCS +=		$(UMAC_SPECTRAL_INC)
+INCS +=		$(UMAC_TARGET_SPECTRAL_INC)
+INCS +=		$(UMAC_CRYPTO_INC)
+
+OBJS :=		$(HDD_OBJS) \
+		$(DSC_OBJS) \
+		$(MAC_OBJS) \
+		$(SAP_OBJS) \
+		$(SME_OBJS) \
+		$(SYS_OBJS) \
+		$(QAL_OBJS) \
+		$(QDF_OBJS) \
+		$(WBUFF_OBJS) \
+		$(CDS_OBJS) \
+		$(CFG_OBJS) \
+		$(FTM_OBJS)
+
+OBJS +=		$(WMA_OBJS) \
+		$(TXRX_OBJS) \
+		$(WMI_OBJS) \
+		$(HTC_OBJS) \
+		$(INIT_DEINIT_OBJS) \
+		$(SCHEDULER_OBJS) \
+		$(REGULATORY_OBJS)
+
+OBJS +=		$(HIF_OBJS) \
+		$(BMI_OBJS) \
+		$(HTT_OBJS) \
+		$(OS_IF_OBJ) \
+		$(TARGET_IF_OBJ) \
+		$(CLD_TARGET_IF_OBJ) \
+		$(GLOBAL_LMAC_IF_OBJ)
+
+ifeq ($(CONFIG_LITHIUM), y)
+OBJS += 	$(HAL_OBJS)
+endif
+
+ifeq ($(CONFIG_FEATURE_FW_LOG_PARSING), y)
+OBJS +=        $(FWLOG_OBJS)
+endif
+
+ifeq ($(CONFIG_FEATURE_EPPING), y)
+OBJS += 	$(EPPING_OBJS)
+endif
+
+ifeq ($(CONFIG_WLAN_DFS_MASTER_ENABLE), y)
+OBJS +=		$(DFS_OBJS)
+endif
+
+OBJS +=		$(UMAC_OBJMGR_OBJS)
+OBJS +=		$(WIFI_POS_OBJS)
+OBJS +=		$(CP_STATS_OBJS)
+OBJS +=		$(WLAN_NAN_OBJS)
+OBJS +=		$(UMAC_MGMT_TXRX_OBJS)
+OBJS +=		$(UMAC_TDLS_OBJS)
+OBJS +=		$(PMO_OBJS)
+OBJS +=		$(UMAC_P2P_OBJS)
+OBJS +=		$(UMAC_POLICY_MGR_OBJS)
+OBJS +=		$(WLAN_LOGGING_OBJS)
+OBJS +=		$(NLINK_OBJS)
+OBJS +=		$(PTT_OBJS)
+OBJS +=		$(UMAC_SER_OBJS)
+OBJS +=		$(PLD_OBJS)
+OBJS +=		$(UMAC_SM_OBJS)
+OBJS +=		$(UMAC_MLME_OBJS)
+OBJS +=		$(MLME_OBJS)
+OBJS +=		$(FWOL_OBJS)
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+OBJS +=		$(OCB_OBJS)
+endif
+
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+OBJS +=		$(IPA_OBJS)
+endif
+
+ifeq ($(CONFIG_REMOVE_PKT_LOG), n)
+OBJS +=		$(PKTLOG_OBJS)
+endif
+
+ifeq ($(BUILD_DIAG_VERSION), y)
+OBJS +=		$(HOST_DIAG_LOG_OBJS)
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DISA), y)
+OBJS +=		$(DISA_OBJS)
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_ACTION_OUI), y)
+OBJS +=		$(ACTION_OUI_OBJS)
+endif
+
+OBJS +=		$(UMAC_DISP_OBJS)
+OBJS +=		$(UMAC_SCAN_OBJS)
+OBJS +=		$(UMAC_COMMON_OBJS)
+OBJS +=		$(WCFG_OBJS)
+
+OBJS +=		$(UMAC_SPECTRAL_OBJS)
+
+ifeq ($(CONFIG_QCACLD_FEATURE_GREEN_AP), y)
+OBJS +=		$(UMAC_GREEN_AP_OBJS)
+endif
+
+ifeq ($(CONFIG_CRYPTO_COMPONENT), y)
+OBJS +=		$(UMAC_CRYPTO_OBJS)
+endif
+
+ifeq ($(CONFIG_LITHIUM), y)
+OBJS +=		$(DP_OBJS)
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DP_RX_THREADS), y)
+OBJS += $(TXRX3.0_OBJS)
+endif
+
+ccflags-y += $(INCS)
+
+cppflags-y +=	-DANI_OS_TYPE_ANDROID=6 \
+		-Wall\
+		-Werror\
+		-D__linux__
+
+cppflags-$(CONFIG_PTT_SOCK_SVC_ENABLE) += -DPTT_SOCK_SVC_ENABLE
+cppflags-$(CONFIG_FEATURE_WLAN_WAPI) += -DFEATURE_WLAN_WAPI
+cppflags-$(CONFIG_FEATURE_WLAN_WAPI) += -DATH_SUPPORT_WAPI
+cppflags-$(CONFIG_AGEIE_ON_SCAN_RESULTS) += -DWLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
+cppflags-$(CONFIG_SOFTAP_CHANNEL_RANGE) += -DSOFTAP_CHANNEL_RANGE
+cppflags-$(CONFIG_FEATURE_WLAN_SCAN_PNO) += -DFEATURE_WLAN_SCAN_PNO
+cppflags-$(CONFIG_WLAN_FEATURE_PACKET_FILTERING) += -DWLAN_FEATURE_PACKET_FILTERING
+cppflags-$(CONFIG_WLAN_NS_OFFLOAD) += -DWLAN_NS_OFFLOAD
+cppflags-$(CONFIG_FEATURE_WLAN_RA_FILTERING) += -DFEATURE_WLAN_RA_FILTERING
+cppflags-$(CONFIG_FEATURE_WLAN_LPHB) += -DFEATURE_WLAN_LPHB
+cppflags-$(CONFIG_QCA_SUPPORT_TX_THROTTLE) += -DQCA_SUPPORT_TX_THROTTLE
+cppflags-$(CONFIG_WMI_INTERFACE_EVENT_LOGGING) += -DWMI_INTERFACE_EVENT_LOGGING
+cppflags-$(CONFIG_WLAN_FEATURE_LINK_LAYER_STATS) += -DWLAN_FEATURE_LINK_LAYER_STATS
+cppflags-$(CONFIG_FEATURE_WLAN_EXTSCAN) += -DFEATURE_WLAN_EXTSCAN
+cppflags-$(CONFIG_160MHZ_SUPPORT) += -DCONFIG_160MHZ_SUPPORT
+cppflags-$(CONFIG_MCL) += -DCONFIG_MCL
+cppflags-$(CONFIG_MCL_REGDB) += -DCONFIG_MCL_REGDB
+cppflags-$(CONFIG_LEGACY_CHAN_ENUM) += -DCONFIG_LEGACY_CHAN_ENUM
+cppflags-$(CONFIG_WLAN_PMO_ENABLE) += -DWLAN_PMO_ENABLE
+cppflags-$(CONFIG_CONVERGED_P2P_ENABLE) += -DCONVERGED_P2P_ENABLE
+cppflags-$(CONFIG_WLAN_POLICY_MGR_ENABLE) += -DWLAN_POLICY_MGR_ENABLE
+cppflags-$(CONFIG_SUPPORT_11AX) += -DSUPPORT_11AX
+cppflags-$(CONFIG_HDD_INIT_WITH_RTNL_LOCK) += -DCONFIG_HDD_INIT_WITH_RTNL_LOCK
+cppflags-$(CONFIG_CONVERGED_TDLS_ENABLE) += -DCONVERGED_TDLS_ENABLE
+cppflags-$(CONFIG_WLAN_CONV_SPECTRAL_ENABLE) += -DWLAN_CONV_SPECTRAL_ENABLE
+cppflags-$(CONFIG_WMI_CMD_STRINGS) += -DWMI_CMD_STRINGS
+cppflags-$(CONFIG_FEATURE_MONITOR_MODE_SUPPORT) += -DFEATURE_MONITOR_MODE_SUPPORT
+cppflags-$(CONFIG_WLAN_FEATURE_TWT) += -DWLAN_SUPPORT_TWT
+
+cppflags-$(CONFIG_WLAN_DISABLE_EXPORT_SYMBOL) += -DWLAN_DISABLE_EXPORT_SYMBOL
+cppflags-$(CONFIG_WIFI_POS_CONVERGED) += -DWIFI_POS_CONVERGED
+cppflags-$(CONFIG_WIFI_POS_LEGACY) += -DFEATURE_OEM_DATA_SUPPORT
+cppflags-$(CONFIG_FEATURE_HTC_CREDIT_HISTORY) += -DFEATURE_HTC_CREDIT_HISTORY
+cppflags-$(CONFIG_WLAN_FEATURE_P2P_DEBUG) += -DWLAN_FEATURE_P2P_DEBUG
+cppflags-$(CONFIG_WLAN_WEXT_SUPPORT_ENABLE) += -DWLAN_WEXT_SUPPORT_ENABLE
+cppflags-$(CONFIG_WLAN_LOGGING_SOCK_SVC) += -DWLAN_LOGGING_SOCK_SVC_ENABLE
+cppflags-$(CONFIG_WLAN_LOGGING_BUFFERS_DYNAMICALLY) += -DWLAN_LOGGING_BUFFERS_DYNAMICALLY
+cppflags-$(CONFIG_WLAN_FEATURE_FILS) += -DWLAN_FEATURE_FILS_SK
+cppflags-$(CONFIG_CP_STATS) += -DQCA_SUPPORT_CP_STATS
+cppflags-$(CONFIG_FEATURE_MEMDUMP_ENABLE) += -DWLAN_FEATURE_MEMDUMP_ENABLE
+cppflags-$(CONFIG_FEATURE_FW_LOG_PARSING) += -DFEATURE_FW_LOG_PARSING
+
+cppflags-$(CONFIG_PLD_SDIO_CNSS_FLAG) += -DCONFIG_PLD_SDIO_CNSS
+cppflags-$(CONFIG_PLD_PCIE_CNSS_FLAG) += -DCONFIG_PLD_PCIE_CNSS
+cppflags-$(CONFIG_PLD_PCIE_INIT_FLAG) += -DCONFIG_PLD_PCIE_INIT
+cppflags-$(CONFIG_WLAN_FEATURE_DP_RX_THREADS) += -DFEATURE_WLAN_DP_RX_THREADS
+
+#Enable NL80211 test mode
+cppflags-$(CONFIG_NL80211_TESTMODE) += -DWLAN_NL80211_TESTMODE
+
+# Flag to enable bus auto suspend
+ifeq ($(CONFIG_HIF_PCI), y)
+ifeq ($(CONFIG_BUS_AUTO_SUSPEND), y)
+cppflags-y += -DFEATURE_RUNTIME_PM
+endif
+endif
+
+cppflags-$(CONFIG_ICNSS) += -DCONFIG_PLD_SNOC_ICNSS
+
+cppflags-$(CONFIG_WIFI_3_0_ADRASTEA) += -DQCA_WIFI_3_0_ADRASTEA
+cppflags-$(CONFIG_WIFI_3_0_ADRASTEA) += -DQCA_WIFI_3_0
+cppflags-$(CONFIG_ADRASTEA_SHADOW_REGISTERS) += -DADRASTEA_SHADOW_REGISTERS
+cppflags-$(CONFIG_ADRASTEA_RRI_ON_DDR) += -DADRASTEA_RRI_ON_DDR
+
+ifeq ($(CONFIG_QMI_SUPPORT), n)
+cppflags-y += -DCONFIG_BYPASS_QMI
+endif
+
+cppflags-$(CONFIG_WLAN_FASTPATH) +=	-DWLAN_FEATURE_FASTPATH
+
+cppflags-$(CONFIG_FEATURE_PKTLOG) +=     -DFEATURE_PKTLOG
+
+ifeq ($(CONFIG_WLAN_NAPI), y)
+cppflags-y += -DFEATURE_NAPI
+cppflags-y += -DHIF_IRQ_AFFINITY
+ifeq ($(CONFIG_WLAN_NAPI_DEBUG), y)
+cppflags-y += -DFEATURE_NAPI_DEBUG
+endif
+endif
+
+ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM)))
+cppflags-y += -DMSM_PLATFORM
+endif
+
+cppflags-y +=	-DQCA_SUPPORT_TXRX_LOCAL_PEER_ID
+
+cppflags-$(CONFIG_WLAN_TX_FLOW_CONTROL_V2) += -DQCA_LL_TX_FLOW_CONTROL_V2
+cppflags-$(CONFIG_WLAN_TX_FLOW_CONTROL_V2) += -DQCA_LL_TX_FLOW_GLOBAL_MGMT_POOL
+cppflags-$(CONFIG_WLAN_TX_FLOW_CONTROL_LEGACY) += -DQCA_LL_LEGACY_TX_FLOW_CONTROL
+
+ifeq ($(BUILD_DEBUG_VERSION), y)
+cppflags-y +=	-DWLAN_DEBUG
+ifeq ($(CONFIG_TRACE_RECORD_FEATURE), y)
+cppflags-y +=	-DTRACE_RECORD \
+		-DLIM_TRACE_RECORD \
+		-DSME_TRACE_RECORD \
+		-DHDD_TRACE_RECORD
+endif
+endif
+cppflags-$(CONFIG_UNIT_TEST) += -DWLAN_UNIT_TEST
+cppflags-$(CONFIG_WLAN_DEBUG_CRASH_INJECT) += -DCONFIG_WLAN_DEBUG_CRASH_INJECT
+cppflags-$(CONFIG_FEATURE_UNIT_TEST_SUSPEND) += -DWLAN_SUSPEND_RESUME_TEST
+
+ifeq ($(CONFIG_LEAK_DETECTION), y)
+cppflags-y += \
+	-DCONFIG_HALT_KMEMLEAK \
+	-DCONFIG_LEAK_DETECTION \
+	-DMEMORY_DEBUG \
+	-DNBUF_MEMORY_DEBUG \
+	-DNBUF_MAP_UNMAP_DEBUG \
+	-DTIMER_MANAGER
+endif
+
+cppflags-y += -DWLAN_FEATURE_P2P
+cppflags-y += -DWLAN_FEATURE_WFD
+ifeq ($(CONFIG_QCOM_VOWIFI_11R), y)
+cppflags-y += -DKERNEL_SUPPORT_11R_CFG80211
+cppflags-y += -DUSE_80211_WMMTSPEC_FOR_RIC
+endif
+
+ifeq ($(CONFIG_QCOM_ESE), y)
+cppflags-y += -DFEATURE_WLAN_ESE
+endif
+
+#normally, TDLS negative behavior is not needed
+cppflags-$(CONFIG_QCOM_TDLS) += -DFEATURE_WLAN_TDLS
+
+cppflags-$(CONFIG_QCACLD_WLAN_LFR3) += -DWLAN_FEATURE_ROAM_OFFLOAD
+
+cppflags-$(CONFIG_CNSS_GENL) += -DCNSS_GENL
+
+cppflags-$(CONFIG_QCACLD_WLAN_LFR2) += -DWLAN_FEATURE_HOST_ROAM
+
+cppflags-$(CONFIG_FEATURE_ROAM_DEBUG) += -DFEATURE_ROAM_DEBUG
+
+cppflags-$(CONFIG_WLAN_POWER_DEBUGFS) += -DWLAN_POWER_DEBUGFS
+
+# Enable object manager reference count debug infrastructure
+cppflags-$(CONFIG_WLAN_OBJMGR_DEBUG) += -DWLAN_OBJMGR_DEBUG
+cppflags-$(CONFIG_WLAN_OBJMGR_DEBUG) += -DWLAN_OBJMGR_REF_ID_DEBUG
+
+cppflags-$(CONFIG_WLAN_FEATURE_SAE) += -DWLAN_FEATURE_SAE
+
+ifeq ($(BUILD_DIAG_VERSION), y)
+cppflags-y += -DFEATURE_WLAN_DIAG_SUPPORT
+cppflags-y += -DFEATURE_WLAN_DIAG_SUPPORT_CSR
+cppflags-y += -DFEATURE_WLAN_DIAG_SUPPORT_LIM
+ifeq ($(CONFIG_HIF_PCI), y)
+cppflags-y += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT
+endif
+endif
+
+ifeq ($(CONFIG_HIF_USB), y)
+cppflags-y += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT
+cppflags-y += -DQCA_SUPPORT_OL_RX_REORDER_TIMEOUT
+cppflags-y += -DCONFIG_ATH_PCIE_MAX_PERF=0 -DCONFIG_ATH_PCIE_AWAKE_WHILE_DRIVER_LOAD=0 -DCONFIG_DISABLE_CDC_MAX_PERF_WAR=0
+endif
+
+cppflags-$(CONFIG_WLAN_FEATURE_11W) += -DWLAN_FEATURE_11W
+
+cppflags-$(CONFIG_QCA_TXDESC_SANITY_CHECKS) += -DQCA_SUPPORT_TXDESC_SANITY_CHECKS
+
+cppflags-$(CONFIG_QCOM_LTE_COEX) += -DFEATURE_WLAN_CH_AVOID
+
+cppflags-$(CONFIG_WLAN_FEATURE_LPSS) += -DWLAN_FEATURE_LPSS
+
+cppflags-$(CONFIG_DESC_DUP_DETECT_DEBUG) += -DDESC_DUP_DETECT_DEBUG
+cppflags-$(CONFIG_DEBUG_RX_RING_BUFFER) += -DDEBUG_RX_RING_BUFFER
+
+cppflags-$(CONFIG_DESC_TIMESTAMP_DEBUG_INFO) += -DDESC_TIMESTAMP_DEBUG_INFO
+
+cppflags-$(PANIC_ON_BUG) += -DPANIC_ON_BUG
+
+cppflags-$(WLAN_WARN_ON_ASSERT) += -DWLAN_WARN_ON_ASSERT
+
+ccflags-$(CONFIG_POWER_MANAGEMENT_OFFLOAD) += -DWLAN_POWER_MANAGEMENT_OFFLOAD
+
+cppflags-$(CONFIG_WLAN_LOG_FATAL) += -DWLAN_LOG_FATAL
+cppflags-$(CONFIG_WLAN_LOG_ERROR) += -DWLAN_LOG_ERROR
+cppflags-$(CONFIG_WLAN_LOG_WARN) += -DWLAN_LOG_WARN
+cppflags-$(CONFIG_WLAN_LOG_INFO) += -DWLAN_LOG_INFO
+cppflags-$(CONFIG_WLAN_LOG_DEBUG) += -DWLAN_LOG_DEBUG
+cppflags-$(CONFIG_WLAN_LOG_ENTER) += -DWLAN_LOG_ENTER
+cppflags-$(CONFIG_WLAN_LOG_EXIT) += -DWLAN_LOG_EXIT
+cppflags-$(WLAN_OPEN_SOURCE) += -DWLAN_OPEN_SOURCE
+cppflags-$(CONFIG_FEATURE_STATS_EXT) += -DWLAN_FEATURE_STATS_EXT
+cppflags-$(CONFIG_QCACLD_FEATURE_NAN) += -DWLAN_FEATURE_NAN
+cppflags-$(CONFIG_QCA_IBSS_SUPPORT) += -DQCA_IBSS_SUPPORT
+cppflags-$(CONFIG_WLAN_SYSFS) += -DWLAN_SYSFS
+cppflags-$(CONFIG_FEATURE_WLAN_RMC) += -DFEATURE_WLAN_RMC
+
+#Enable OL debug and wmi unified functions
+cppflags-$(CONFIG_ATH_PERF_PWR_OFFLOAD) += -DATH_PERF_PWR_OFFLOAD
+
+#Disable packet log
+cppflags-$(CONFIG_REMOVE_PKT_LOG) += -DREMOVE_PKT_LOG
+
+#Enable 11AC TX
+cppflags-$(CONFIG_ATH_11AC_TXCOMPACT) += -DATH_11AC_TXCOMPACT
+
+#Enable PCI specific APIS (dma, etc)
+cppflags-$(CONFIG_HIF_PCI) += -DHIF_PCI
+
+cppflags-$(CONFIG_HIF_SNOC) += -DHIF_SNOC
+
+cppflags-$(CONFIG_HL_DP_SUPPORT) += -DCONFIG_HL_SUPPORT
+cppflags-$(CONFIG_HL_DP_SUPPORT) += -DWLAN_PARTIAL_REORDER_OFFLOAD
+cppflags-$(CONFIG_HL_DP_SUPPORT) += -DQCA_COMPUTE_TX_DELAY
+cppflags-$(CONFIG_HL_DP_SUPPORT) += -DQCA_COMPUTE_TX_DELAY_PER_TID
+cppflags-$(CONFIG_LL_DP_SUPPORT) += -DCONFIG_LL_DP_SUPPORT
+cppflags-$(CONFIG_LL_DP_SUPPORT) += -DWLAN_FULL_REORDER_OFFLOAD
+
+#Enable High Latency related Flags
+ifeq ($(CONFIG_QCA_WIFI_SDIO), y)
+cppflags-y += -DCONFIG_AR6320_SUPPORT \
+            -DSDIO_3_0 \
+            -DHIF_SDIO \
+            -DCONFIG_DISABLE_CDC_MAX_PERF_WAR=0 \
+            -DCONFIG_ATH_PROCFS_DIAG_SUPPORT \
+            -DHIF_MBOX_SLEEP_WAR \
+            -DDEBUG_HL_LOGGING \
+            -DQCA_BAD_PEER_TX_FLOW_CL \
+            -DCONFIG_SDIO \
+            -DFEATURE_WLAN_FORCE_SAP_SCC
+
+ifeq ($(CONFIG_SDIO_TRANSFER), adma)
+cppflags-y += -DCONFIG_SDIO_TRANSFER_ADMA
+else
+cppflags-y += -DCONFIG_SDIO_TRANSFER_MAILBOX
+endif
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
+cppflags-y += -DWLAN_FEATURE_DSRC
+
+ifeq ($(CONFIG_OCB_UT_FRAMEWORK), y)
+cppflags-y += -DWLAN_OCB_UT
+endif
+
+endif
+
+cppflags-$(CONFIG_FEATURE_SKB_PRE_ALLOC) += -DFEATURE_SKB_PRE_ALLOC
+
+#Enable USB specific APIS
+ifeq ($(CONFIG_HIF_USB), y)
+cppflags-y += -DHIF_USB \
+            -DDEBUG_HL_LOGGING
+endif
+
+#Enable Genoa specific features.
+cppflags-$(CONFIG_QCA_HL_NETDEV_FLOW_CONTROL) += -DQCA_HL_NETDEV_FLOW_CONTROL
+cppflags-$(CONFIG_FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL) += -DFEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+cppflags-$(CONFIG_FEATURE_HL_DBS_GROUP_CREDIT_SHARING) += -DFEATURE_HL_DBS_GROUP_CREDIT_SHARING
+cppflags-$(CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE) += -DCONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE
+
+cppflags-$(CONFIG_TX_DESC_HI_PRIO_RESERVE) += -DCONFIG_TX_DESC_HI_PRIO_RESERVE
+cppflags-$(CONFIG_PER_VDEV_TX_DESC_POOL) += -DCONFIG_PER_VDEV_TX_DESC_POOL
+
+#Enable FW logs through ini
+cppflags-y += -DCONFIG_FW_LOGS_BASED_ON_INI
+
+#Enable power management suspend/resume functionality
+cppflags-$(CONFIG_ATH_BUS_PM) += -DATH_BUS_PM
+
+#Enable FLOWMAC module support
+cppflags-$(CONFIG_ATH_SUPPORT_FLOWMAC_MODULE) += -DATH_SUPPORT_FLOWMAC_MODULE
+
+#Enable spectral support
+cppflags-$(CONFIG_ATH_SUPPORT_SPECTRAL) += -DATH_SUPPORT_SPECTRAL
+
+#Enable WDI Event support
+cppflags-$(CONFIG_WDI_EVENT_ENABLE) += -DWDI_EVENT_ENABLE
+
+#Endianness selection
+ifeq ($(CONFIG_LITTLE_ENDIAN), y)
+cppflags-y += -DANI_LITTLE_BYTE_ENDIAN
+cppflags-y += -DANI_LITTLE_BIT_ENDIAN
+cppflags-y += -DDOT11F_LITTLE_ENDIAN_HOST
+else
+cppflags-y += -DANI_BIG_BYTE_ENDIAN
+cppflags-y += -DBIG_ENDIAN_HOST
+endif
+
+#Enable MWS COEX support for 4G quick TDM and 5G NR pwr limit
+cppflags-y += -DMWS_COEX
+
+#Enable TX reclaim support
+cppflags-$(CONFIG_TX_CREDIT_RECLAIM_SUPPORT) += -DTX_CREDIT_RECLAIM_SUPPORT
+
+#Enable FTM support
+cppflags-$(CONFIG_QCA_WIFI_FTM) += -DQCA_WIFI_FTM
+cppflags-$(CONFIG_NL80211_TESTMODE) += -DQCA_WIFI_FTM_NL80211
+cppflags-$(CONFIG_LINUX_QCMBR) += -DLINUX_QCMBR -DQCA_WIFI_FTM_IOCTL
+
+#Enable Checksum Offload support
+cppflags-$(CONFIG_CHECKSUM_OFFLOAD) += -DCHECKSUM_OFFLOAD
+
+#Enable Checksum Offload support
+cppflags-$(CONFIG_IPA_OFFLOAD) += -DIPA_OFFLOAD
+
+ifeq ($(CONFIG_ARCH_SDX20), y)
+cppflags-y += -DSYNC_IPA_READY
+endif
+
+ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y)
+cppflags-y += -DFEATURE_SG
+endif
+
+#Enable wbuff
+cppflags-$(CONFIG_WLAN_WBUFF) += -DWLAN_FEATURE_WBUFF
+
+#Enable GTK Offload
+cppflags-$(CONFIG_GTK_OFFLOAD) += -DWLAN_FEATURE_GTK_OFFLOAD
+
+#Enable External WoW
+cppflags-$(CONFIG_EXT_WOW) += -DWLAN_FEATURE_EXTWOW_SUPPORT
+
+#Mark it as SMP Kernel
+cppflags-$(CONFIG_SMP) += -DQCA_CONFIG_SMP
+
+cppflags-$(CONFIG_CHNL_MATRIX_RESTRICTION) += -DWLAN_ENABLE_CHNL_MATRIX_RESTRICTION
+
+#Enable ICMP packet disable powersave feature
+cppflags-$(CONFIG_ICMP_DISABLE_PS) += -DWLAN_ICMP_DISABLE_PS
+
+#Enable OBSS feature
+cppflags-y += -DQCA_HT_2040_COEX
+
+#enable MCC TO SCC switch
+cppflags-$(CONFIG_FEATURE_WLAN_MCC_TO_SCC_SWITCH) += -DFEATURE_WLAN_MCC_TO_SCC_SWITCH
+
+#enable wlan auto shutdown feature
+cppflags-$(CONFIG_FEATURE_WLAN_AUTO_SHUTDOWN) += -DFEATURE_WLAN_AUTO_SHUTDOWN
+
+#enable AP-AP ACS Optimization
+cppflags-$(CONFIG_FEATURE_WLAN_AP_AP_ACS_OPTIMIZE) += -DFEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+
+#Enable 4address scheme
+cppflags-$(CONFIG_FEATURE_WLAN_STA_4ADDR_SCHEME) += -DFEATURE_WLAN_STA_4ADDR_SCHEME
+
+#enable MDM/SDX special config
+cppflags-$(CONFIG_MDM_PLATFORM) += -DMDM_PLATFORM
+
+#Disable STA-AP Mode DFS support
+cppflags-$(CONFIG_FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE) += -DFEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
+
+#Open P2P device interface only for non-Mobile router use cases
+cppflags-$(CONFIG_WLAN_OPEN_P2P_INTERFACE) += -DWLAN_OPEN_P2P_INTERFACE
+
+#Enable 2.4 GHz social channels in 5 GHz only mode for p2p usage
+cppflags-$(CONFIG_WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY) += -DWLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
+
+#Green AP feature
+cppflags-$(CONFIG_QCACLD_FEATURE_GREEN_AP) += -DWLAN_SUPPORT_GREEN_AP
+
+cppflags-$(CONFIG_QCACLD_FEATURE_APF) += -DFEATURE_WLAN_APF
+
+cppflags-$(CONFIG_WLAN_FEATURE_SARV1_TO_SARV2) += -DWLAN_FEATURE_SARV1_TO_SARV2
+#CRYPTO Coverged Component
+cppflags-$(CONFIG_CRYPTO_COMPONENT) += -DWLAN_CONV_CRYPTO_SUPPORTED \
+                                       -DWLAN_CRYPTO_WEP_OS_DERIVATIVE \
+                                       -DWLAN_CRYPTO_TKIP_OS_DERIVATIVE \
+                                       -DWLAN_CRYPTO_CCMP_OS_DERIVATIVE \
+                                       -DWLAN_CRYPTO_GCMP_OS_DERIVATIVE \
+                                       -DWLAN_CRYPTO_WAPI_OS_DERIVATIVE \
+                                       -DWLAN_CRYPTO_GCM_OS_DERIVATIVE \
+                                       -DWLAN_CRYPTO_FILS_OS_DERIVATIVE \
+                                       -DWLAN_CRYPTO_OMAC1_OS_DERIVATIVE
+
+#Enable host 11d scan
+cppflags-$(CONFIG_HOST_11D_SCAN) += -DHOST_11D_SCAN
+
+#Stats & Quota Metering feature
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+ifeq ($(CONFIG_QCACLD_FEATURE_METERING), y)
+cppflags-y += -DFEATURE_METERING
+endif
+endif
+
+cppflags-$(CONFIG_TUFELLO_DUAL_FW_SUPPORT) += -DCONFIG_TUFELLO_DUAL_FW_SUPPORT
+cppflags-$(CONFIG_CHANNEL_HOPPING_ALL_BANDS) += -DCHANNEL_HOPPING_ALL_BANDS
+
+#Enable Signed firmware support for split binary format
+cppflags-$(CONFIG_QCA_SIGNED_SPLIT_BINARY_SUPPORT) += -DQCA_SIGNED_SPLIT_BINARY_SUPPORT
+
+#Enable single firmware binary format
+cppflags-$(CONFIG_QCA_SINGLE_BINARY_SUPPORT) += -DQCA_SINGLE_BINARY_SUPPORT
+
+#Enable collecting target RAM dump after kernel panic
+cppflags-$(CONFIG_TARGET_RAMDUMP_AFTER_KERNEL_PANIC) += -DTARGET_RAMDUMP_AFTER_KERNEL_PANIC
+
+#Enable/disable secure firmware feature
+cppflags-$(CONFIG_FEATURE_SECURE_FIRMWARE) += -DFEATURE_SECURE_FIRMWARE
+
+cppflags-$(CONFIG_ATH_PCIE_ACCESS_DEBUG) += -DCONFIG_ATH_PCIE_ACCESS_DEBUG
+
+# Enable feature support for Linux version QCMBR
+cppflags-$(CONFIG_LINUX_QCMBR) += -DLINUX_QCMBR
+
+# Enable feature sync tsf between multi devices
+cppflags-$(CONFIG_WLAN_SYNC_TSF) += -DWLAN_FEATURE_TSF
+cppflags-$(CONFIG_WLAN_SYNC_TSF_PLUS) += -DWLAN_FEATURE_TSF_PLUS
+# Enable feature sync tsf for chips based on Adrastea arch
+cppflags-$(CONFIG_WLAN_SYNC_TSF_PLUS_NOIRQ) += -DWLAN_FEATURE_TSF_PLUS_NOIRQ
+
+cppflags-$(CONFIG_ATH_PROCFS_DIAG_SUPPORT) += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT
+
+cppflags-$(CONFIG_HELIUMPLUS) += -DHELIUMPLUS
+cppflags-$(CONFIG_RX_OL) += -DRECEIVE_OFFLOAD
+cppflags-$(CONFIG_TX_TID_OVERRIDE) += -DATH_TX_PRI_OVERRIDE
+cppflags-$(CONFIG_AR900B) += -DAR900B
+cppflags-$(CONFIG_HTT_PADDR64) += -DHTT_PADDR64
+cppflags-$(CONFIG_OL_RX_INDICATION_RECORD) += -DOL_RX_INDICATION_RECORD
+cppflags-$(CONFIG_TSOSEG_DEBUG) += -DTSOSEG_DEBUG
+
+cppflags-$(CONFIG_ENABLE_DEBUG_ADDRESS_MARKING) += -DENABLE_DEBUG_ADDRESS_MARKING
+cppflags-$(CONFIG_FEATURE_TSO) += -DFEATURE_TSO
+cppflags-$(CONFIG_FEATURE_TSO_DEBUG) += -DFEATURE_TSO_DEBUG
+
+cppflags-$(CONFIG_WLAN_LRO) += -DFEATURE_LRO
+
+cppflags-$(CONFIG_FEATURE_AP_MCC_CH_AVOIDANCE) += -DFEATURE_AP_MCC_CH_AVOIDANCE
+
+cppflags-$(CONFIG_MPC_UT_FRAMEWORK) += -DMPC_UT_FRAMEWORK
+
+cppflags-$(CONFIG_FEATURE_EPPING) += -DWLAN_FEATURE_EPPING
+
+cppflags-$(CONFIG_WLAN_OFFLOAD_PACKETS) += -DWLAN_FEATURE_OFFLOAD_PACKETS
+
+cppflags-$(CONFIG_WLAN_FEATURE_DISA) += -DWLAN_FEATURE_DISA
+
+cppflags-$(CONFIG_WLAN_FEATURE_ACTION_OUI) += -DWLAN_FEATURE_ACTION_OUI
+
+cppflags-$(CONFIG_WLAN_FEATURE_FIPS) += -DWLAN_FEATURE_FIPS
+
+cppflags-$(CONFIG_LFR_SUBNET_DETECTION) += -DFEATURE_LFR_SUBNET_DETECTION
+
+cppflags-$(CONFIG_MCC_TO_SCC_SWITCH) += -DFEATURE_WLAN_MCC_TO_SCC_SWITCH
+
+cppflags-$(CONFIG_WLAN_FEATURE_NAN_DATAPATH) += -DWLAN_FEATURE_NAN_DATAPATH
+
+cppflags-$(CONFIG_NAN_CONVERGENCE) += -DWLAN_FEATURE_NAN_CONVERGENCE
+
+cppflags-$(CONFIG_FEATURE_WLAN_D0WOW) += -DFEATURE_WLAN_D0WOW
+
+cppflags-$(CONFIG_QCA_WIFI_NAPIER_EMULATION) += -DQCA_WIFI_NAPIER_EMULATION
+cppflags-$(CONFIG_SHADOW_V2) += -DCONFIG_SHADOW_V2
+cppflags-$(CONFIG_QCA6290_HEADERS_DEF) += -DQCA6290_HEADERS_DEF
+cppflags-$(CONFIG_QCA_WIFI_QCA6290) += -DQCA_WIFI_QCA6290
+cppflags-$(CONFIG_QCA6390_HEADERS_DEF) += -DQCA6390_HEADERS_DEF
+cppflags-$(CONFIG_QCA_WIFI_QCA6390) += -DQCA_WIFI_QCA6390
+cppflags-$(CONFIG_QCA_WIFI_QCA8074) += -DQCA_WIFI_QCA8074
+cppflags-$(CONFIG_SCALE_INCLUDES) += -DSCALE_INCLUDES
+cppflags-$(CONFIG_QCA_WIFI_QCA8074_VP) += -DQCA_WIFI_QCA8074_VP
+cppflags-$(CONFIG_DP_INTR_POLL_BASED) += -DDP_INTR_POLL_BASED
+cppflags-$(CONFIG_TX_PER_PDEV_DESC_POOL) += -DTX_PER_PDEV_DESC_POOL
+cppflags-$(CONFIG_DP_TRACE) += -DCONFIG_DP_TRACE
+cppflags-$(CONFIG_FEATURE_TSO) += -DFEATURE_TSO
+cppflags-$(CONFIG_TSO_DEBUG_LOG_ENABLE) += -DTSO_DEBUG_LOG_ENABLE
+cppflags-$(CONFIG_DP_LFR) += -DDP_LFR
+cppflags-$(CONFIG_HTT_PADDR64) += -DHTT_PADDR64
+cppflags-$(CONFIG_WLAN_FEATURE_BMI) += -DWLAN_FEATURE_BMI
+cppflags-$(CONFIG_QCN7605_SUPPORT) += -DQCN7605_SUPPORT
+cppflags-$(CONFIG_HIF_REG_WINDOW_SUPPORT) += -DHIF_REG_WINDOW_SUPPORT
+cppflags-$(CONFIG_WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY) += -DWLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY
+
+ccflags-$(CONFIG_QCA_LL_TX_FLOW_CONTROL_RESIZE) += -DQCA_LL_TX_FLOW_CONTROL_RESIZE
+ccflags-$(CONFIG_HIF_PCI) += -DCE_SVC_CMN_INIT
+ccflags-$(CONFIG_HIF_SNOC) += -DCE_SVC_CMN_INIT
+
+ifeq ($(CONFIG_QCA6290_11AX), y)
+cppflags-y += -DQCA_WIFI_QCA6290_11AX
+cppflags-$(CONFIG_WLAN_TX_FLOW_CONTROL_V2) += -DQCA_AC_BASED_FLOW_CONTROL
+endif
+
+cppflags-$(CONFIG_WLAN_FEATURE_11AX) += -DWLAN_FEATURE_11AX
+cppflags-$(CONFIG_WLAN_FEATURE_11AX) += -DWLAN_FEATURE_11AX_BSS_COLOR
+cppflags-$(CONFIG_WLAN_FEATURE_11AX) += -DSUPPORT_11AX_D3
+
+cppflags-$(CONFIG_LITHIUM) += -DFEATURE_AST
+cppflags-$(CONFIG_LITHIUM) += -DPEER_PROTECTED_ACCESS
+
+#Enable STATE MACHINE HISTORY
+cppflags-$(CONFIG_SM_ENG_HIST) += -DSM_ENG_HIST_ENABLE
+#Enable VDEV STATE MACHINE
+cppflags-$(CONFIG_CMN_VDEV_MLME_SM) += -DCMN_VDEV_MLME_SM_ENABLE
+cppflags-$(CONFIG_VDEV_SM) += -DCONFIG_VDEV_SM
+
+# Vendor Commands
+cppflags-$(CONFIG_FEATURE_RSSI_MONITOR) += -DFEATURE_RSSI_MONITOR
+cppflags-$(CONFIG_FEATURE_BSS_TRANSITION) += -DFEATURE_BSS_TRANSITION
+cppflags-$(CONFIG_FEATURE_STATION_INFO) += -DFEATURE_STATION_INFO
+cppflags-$(CONFIG_FEATURE_TX_POWER) += -DFEATURE_TX_POWER
+cppflags-$(CONFIG_FEATURE_OTA_TEST) += -DFEATURE_OTA_TEST
+cppflags-$(CONFIG_FEATURE_ACTIVE_TOS) += -DFEATURE_ACTIVE_TOS
+cppflags-$(CONFIG_FEATURE_SAR_LIMITS) += -DFEATURE_SAR_LIMITS
+cppflags-$(CONFIG_FEATURE_CONCURRENCY_MATRIX) += -DFEATURE_CONCURRENCY_MATRIX
+cppflags-$(CONFIG_FEATURE_SAP_COND_CHAN_SWITCH) += -DFEATURE_SAP_COND_CHAN_SWITCH
+
+#if converged p2p is enabled
+ifeq ($(CONFIG_CONVERGED_P2P_ENABLE), y)
+cppflags-$(CONFIG_FEATURE_P2P_LISTEN_OFFLOAD) += -DFEATURE_P2P_LISTEN_OFFLOAD
+endif
+
+#Flags to enable/disable WMI APIs
+cppflags-$(CONFIG_WMI_ROAM_SUPPORT) += -DWMI_ROAM_SUPPORT
+cppflags-$(CONFIG_WMI_CONCURRENCY_SUPPORT) += -DWMI_CONCURRENCY_SUPPORT
+cppflags-$(CONFIG_WMI_STA_SUPPORT) += -DWMI_STA_SUPPORT
+
+# Dummy flag for WIN/MCL converged data path compilation
+cppflags-y += -DDP_PRINT_ENABLE=0
+cppflags-y += -DATH_SUPPORT_WRAP=0
+cppflags-y += -DQCA_HOST2FW_RXBUF_RING
+#endof dummy flags
+
+# Enable lock of serialization component to avoid race condition issues
+cppflags-y += -DWLAN_CMD_SERIALIZATION_LOCKING
+
+#CONFIG_SERIALIZATION_V1: Don't use enhancements to serialization component
+#No CONFIG_SERIALIZATION_V1: Use enhancements to serialization component
+
+ccflags-$(CONFIG_ENABLE_SIZE_OPTIMIZE) += -Os
+
+# DFS component
+cppflags-$(CONFIG_WLAN_DFS_STATIC_MEM_ALLOC) += -DWLAN_DFS_STATIC_MEM_ALLOC
+cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DQCA_MCL_DFS_SUPPORT
+ifeq ($(CONFIG_WLAN_FEATURE_DFS_OFFLOAD), y)
+cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DWLAN_DFS_FULL_OFFLOAD
+else
+cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DWLAN_DFS_PARTIAL_OFFLOAD
+endif
+cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DDFS_COMPONENT_ENABLE
+cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DQCA_DFS_USE_POLICY_MANAGER
+cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DQCA_DFS_NOL_PLATFORM_DRV_SUPPORT
+
+cppflags-$(CONFIG_WLAN_DEBUGFS) += -DWLAN_DEBUGFS
+
+cppflags-$(CONFIG_DYNAMIC_DEBUG) += -DFEATURE_MULTICAST_HOST_FW_MSGS
+
+cppflags-$(CONFIG_ENABLE_SMMU_S1_TRANSLATION) += -DENABLE_SMMU_S1_TRANSLATION
+
+#Flag to enable/disable MTRACE feature
+cppflags-$(CONFIG_ENABLE_MTRACE_LOG) += -DENABLE_MTRACE_LOG
+
+#Flag to enable NUD tracking
+cppflags-$(CONFIG_WLAN_NUD_TRACKING) += -DWLAN_NUD_TRACKING
+
+#Flag to enable set and get disable channel list feature
+cppflags-$(CONFIG_DISABLE_CHANNEL_LIST) += -DDISABLE_CHANNEL_LIST
+
+#Flag to enable Dynamic Voltage WDCVS (Config Voltage Mode)
+cppflags-$(CONFIG_WLAN_DYNAMIC_CVM) += -DFEATURE_WLAN_DYNAMIC_CVM
+
+ifdef CONFIG_MAX_LOGS_PER_SEC
+ccflags-y += -DWLAN_MAX_LOGS_PER_SEC=$(CONFIG_MAX_LOGS_PER_SEC)
+endif
+
+ifdef CONFIG_SCHED_HISTORY_SIZE
+ccflags-y += -DWLAN_SCHED_HISTORY_SIZE=$(CONFIG_SCHED_HISTORY_SIZE)
+endif
+
+# configure log buffer size
+ifdef CONFIG_CFG_NUM_DP_TRACE_RECORD
+ccflags-y += -DMAX_QDF_DP_TRACE_RECORDS=$(CONFIG_CFG_NUM_DP_TRACE_RECORD)
+endif
+
+ifdef CONFIG_CFG_NUM_HTC_CREDIT_HISTORY
+ccflags-y += -DHTC_CREDIT_HISTORY_MAX=$(CONFIG_CFG_NUM_HTC_CREDIT_HISTORY)
+endif
+
+ifdef CONFIG_CFG_NUM_WMI_EVENT_HISTORY
+ccflags-y += -DWMI_EVENT_DEBUG_MAX_ENTRY=$(CONFIG_CFG_NUM_WMI_EVENT_HISTORY)
+endif
+
+ifdef CONFIG_CFG_NUM_WMI_MGMT_EVENT_HISTORY
+ccflags-y += -DWMI_MGMT_EVENT_DEBUG_MAX_ENTRY=$(CONFIG_CFG_NUM_WMI_MGMT_EVENT_HISTORY)
+endif
+
+ifdef CONFIG_CFG_NUM_TX_RX_HISTOGRAM
+ccflags-y += -DNUM_TX_RX_HISTOGRAM=$(CONFIG_CFG_NUM_TX_RX_HISTOGRAM)
+endif
+
+ifdef CONFIG_CFG_NUM_RX_IND_RECORD
+ccflags-y += -DOL_RX_INDICATION_MAX_RECORDS=$(CONFIG_CFG_NUM_RX_IND_RECORD)
+endif
+
+ifdef CONFIG_CFG_NUM_ROAM_DEBUG_RECORD
+ccflags-y += -DWLAN_ROAM_DEBUG_MAX_REC=$(CONFIG_CFG_NUM_ROAM_DEBUG_RECORD)
+endif
+
+ifdef CONFIG_CFG_PMO_WOW_FILTERS_MAX
+ccflags-y += -DPMO_WOW_FILTERS_MAX=$(CONFIG_CFG_PMO_WOW_FILTERS_MAX)
+endif
+
+ifdef CONFIG_CFG_GTK_OFFLOAD_MAX_VDEV
+ccflags-y += -DCFG_TGT_DEFAULT_GTK_OFFLOAD_MAX_VDEV=$(CONFIG_CFG_GTK_OFFLOAD_MAX_VDEV)
+endif
+
+ifdef CONFIG_CFG_ROAM_OFFLOAD_MAX_VDEV
+ccflags-y += -DCFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_VDEV=$(CONFIG_CFG_ROAM_OFFLOAD_MAX_VDEV)
+endif
+
+ifdef CONFIG_CFG_MAX_PERIODIC_TX_PTRNS
+ccflags-y += -DWMA_MAXNUM_PERIODIC_TX_PTRNS=$(CONFIG_CFG_MAX_PERIODIC_TX_PTRNS)
+endif
+
+ifdef CONFIG_CFG_MAX_STA_VDEVS
+ccflags-y += -DCFG_TGT_DEFAULT_MAX_STA_VDEVS=$(CONFIG_CFG_MAX_STA_VDEVS)
+endif
+
+ifdef CONFIG_CFG_NUM_OF_ADDITIONAL_FW_PEERS
+ccflags-y += -DNUM_OF_ADDITIONAL_FW_PEERS=$(CONFIG_CFG_NUM_OF_ADDITIONAL_FW_PEERS)
+endif
+
+ifdef CONFIG_CFG_NUM_OF_TDLS_CONN_TABLE_ENTRIES
+ccflags-y += -DCFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES=$(CONFIG_CFG_NUM_OF_TDLS_CONN_TABLE_ENTRIES)
+endif
+
+ifdef CONFIG_SIR_MAX_SUPPORTED_BSS
+ccflags-y += -DSIR_MAX_SUPPORTED_BSS=$(CONFIG_SIR_MAX_SUPPORTED_BSS)
+endif
+
+ifdef CONFIG_SIR_SAP_MAX_NUM_PEERS
+ccflags-y += -DSIR_SAP_MAX_NUM_PEERS=$(CONFIG_SIR_SAP_MAX_NUM_PEERS)
+endif
+
+ifdef CONFIG_LOCK_STATS_ON
+ccflags-y += -DQDF_LOCK_STATS=1
+ccflags-y += -DQDF_LOCK_STATS_DESTROY_PRINT=0
+ccflags-y += -DQDF_LOCK_STATS_BUG_ON=1
+ccflags-y += -DQDF_LOCK_STATS_LIST=1
+ccflags-y += -DQDF_LOCK_STATS_LIST_SIZE=256
+endif
+
+KBUILD_CPPFLAGS += $(cppflags-y)
+
+# Currently, for versions of gcc which support it, the kernel Makefile
+# is disabling the maybe-uninitialized warning.  Re-enable it for the
+# WLAN driver.  Note that we must use ccflags-y here so that it
+# will override the kernel settings.
+ifeq ($(call cc-option-yn, -Wmaybe-uninitialized), y)
+ccflags-y += -Wmaybe-uninitialized
+ifneq (y,$(CONFIG_ARCH_MSM))
+ccflags-y += -Wframe-larger-than=4096
+endif
+endif
+ccflags-y += -Wmissing-prototypes
+
+ifeq ($(call cc-option-yn, -Wheader-guard), y)
+ccflags-y += -Wheader-guard
+endif
+# If the module name is not "wlan", then the define MULTI_IF_NAME to be the
+# same a the QCA CHIP name. The host driver will then append MULTI_IF_NAME to
+# any string that must be unique for all instances of the driver on the system.
+# This allows multiple instances of the driver with different module names.
+# If the module name is wlan, leave MULTI_IF_NAME undefined and the code will
+# treat the driver as the primary driver.
+ifneq ($(MODNAME), wlan)
+CHIP_NAME ?= $(MODNAME)
+ccflags-y += -DMULTI_IF_NAME=\"$(CHIP_NAME)\"
+endif
+
+# WLAN_HDD_ADAPTER_MAGIC must be unique for all instances of the driver on the
+# system. If it is not defined, then the host driver will use the first 4
+# characters (including NULL) of MULTI_IF_NAME to construct
+# WLAN_HDD_ADAPTER_MAGIC.
+ifdef WLAN_HDD_ADAPTER_MAGIC
+ccflags-y += -DWLAN_HDD_ADAPTER_MAGIC=$(WLAN_HDD_ADAPTER_MAGIC)
+endif
+
+# Determine if we are building against an arm architecture host
+ifeq ($(findstring arm, $(ARCH)),)
+	ccflags-y += -DWLAN_HOST_ARCH_ARM=0
+else
+	ccflags-y += -DWLAN_HOST_ARCH_ARM=1
+endif
+
+# inject some build related information
+ifeq ($(CONFIG_BUILD_TAG), y)
+CLD_CHECKOUT = $(shell cd "$(WLAN_ROOT)" && \
+	git reflog | grep -vm1 "}: cherry-pick: " | grep -oE ^[0-f]+)
+CLD_IDS = $(shell cd "$(WLAN_ROOT)" && \
+	git log -50 $(CLD_CHECKOUT)~..HEAD | \
+		sed -nE 's/^\s*Change-Id: (I[0-f]{10})[0-f]{30}\s*$$/\1/p' | \
+		paste -sd "," -)
+
+CMN_CHECKOUT = $(shell cd "$(WLAN_COMMON_INC)" && \
+	git reflog | grep -vm1 "}: cherry-pick: " | grep -oE ^[0-f]+)
+CMN_IDS = $(shell cd "$(WLAN_COMMON_INC)" && \
+	git log -50 $(CMN_CHECKOUT)~..HEAD | \
+		sed -nE 's/^\s*Change-Id: (I[0-f]{10})[0-f]{30}\s*$$/\1/p' | \
+		paste -sd "," -)
+
+TIMESTAMP = $(shell date -u +'%Y-%m-%dT%H:%M:%SZ')
+BUILD_TAG = "$(TIMESTAMP); cld:$(CLD_IDS); cmn:$(CMN_IDS);"
+# It's assumed that BUILD_TAG is used only in wlan_hdd_main.c
+CFLAGS_wlan_hdd_main.o += -DBUILD_TAG=\"$(BUILD_TAG)\"
+endif
+
+# Module information used by KBuild framework
+obj-$(CONFIG_QCA_CLD_WLAN) += $(MODNAME).o
+$(MODNAME)-y := $(OBJS)
+OBJS_DIRS := $(dir $(OBJS)) \
+	     $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ \
+	     $(QDF_OBJ_DIR)/ \
+	     $(WLAN_COMMON_ROOT)/$(HIF_PCIE_DIR)/ \
+	     $(WLAN_COMMON_ROOT)/$(HIF_SNOC_DIR)/ \
+	     $(WLAN_COMMON_ROOT)/$(HIF_SDIO_DIR)/
+CLEAN_DIRS := $(addsuffix *.o,$(sort $(OBJS_DIRS))) \
+	      $(addsuffix .*.o.cmd,$(sort $(OBJS_DIRS)))
+clean-files := $(CLEAN_DIRS)
diff --git a/Kconfig b/Kconfig
new file mode 100644
index 0000000..bb65a84
--- /dev/null
+++ b/Kconfig
@@ -0,0 +1,159 @@
+comment "Qualcomm Atheros CLD WLAN module"
+
+config QCA_CLD_WLAN
+
+	tristate "Qualcomm Atheros CLD WLAN module"
+	default n
+	help
+	Add support for the Qualcomm Atheros CLD WLAN module
+
+if QCA_CLD_WLAN != n
+
+config QCACLD_WLAN_LFR3
+	bool "Enable the WLAN Legacy Fast Roaming feature Version 3"
+	default n
+
+config PRIMA_WLAN_OKC
+	bool "Enable the Prima WLAN Opportunistic Key Caching feature"
+	default n
+
+config WLAN_FEATURE_11W
+	bool "Enable the WLAN 802.11w Protected Management Frames feature"
+	default n
+
+config WLAN_FEATURE_LPSS
+	bool "Enable the WLAN LPSS feature"
+	default n
+
+config QCOM_VOWIFI_11R
+	bool "Enable Fast Transition (11r) feature"
+	default n
+
+config QCACLD_FEATURE_NAN
+	bool "Enable NAN feature"
+	default n
+
+config WLAN_FEATURE_NAN_DATAPATH
+	bool "Enable NaN Data Path feature"
+	depends on QCACLD_FEATURE_NAN
+	default n
+
+config QCACLD_FEATURE_GREEN_AP
+	bool "Enable Green AP feature"
+	default n
+
+config HELIUMPLUS
+	bool "Enable Beeliner based descriptor structures for Helium"
+	default n
+
+config 64BIT_PADDR
+	bool "Enable 37-bit physical/bus addresses"
+	depends on HELIUMPLUS
+	default n
+
+config QCOM_TDLS
+	bool "Enable TDLS feature"
+	default n
+
+config QCOM_LTE_COEX
+	bool "Enable QCOM LTE Coex feature"
+	default n
+
+config MPC_UT_FRAMEWORK
+	bool "Enable Unit test framework for multiport concurrency"
+	default n
+
+config WLAN_OFFLOAD_PACKETS
+	bool "Enable offload packets feature"
+	default n
+
+config FEATURE_TSO
+	bool "Enable TCP Segmentation Offload"
+	depends on HELIUMPLUS
+	default n
+
+config FEATURE_TSO_DEBUG
+	bool "Enable TCP Segmentation Offload with debug"
+	depends on FEATURE_TSO
+	default n
+
+config WLAN_FASTPATH
+	bool "Enable fastpath for datapackets"
+	default n
+
+config WLAN_NAPI
+	bool "Enable NAPI - datapath rx"
+	default n
+
+config WLAN_NAPI_DEBUG
+       bool "Enable debug logging on NAPI"
+       depends on WLAN_NAPI
+       default n
+
+config WLAN_TX_FLOW_CONTROL_V2
+	bool "Enable tx flow control version:2"
+	default n
+
+config WLAN_LRO
+	bool "Enable Large Receive Offload"
+	depends on HELIUMPLUS
+	depends on INET_LRO
+	default n
+
+config WLAN_SYNC_TSF
+	bool "Enable QCOM sync multi devices tsf feature"
+	default n
+
+config LFR_SUBNET_DETECTION
+	bool "Enable LFR Subnet Change Detection"
+	default n
+
+config MCC_TO_SCC_SWITCH
+	bool "Enable MCC to SCC Switch Logic"
+	default n
+
+config QCACLD_WLAN_LFR2
+	bool "Enable the WLAN Legacy Fast Roaming feature Version 2"
+	default n
+
+config WLAN_FEATURE_DISA
+	bool "Enable DISA certification feature"
+	default n
+
+config WLAN_FEATURE_FIPS
+	bool "Enable FIPS certification feature"
+	default n
+
+config WLAN_FEATURE_11AX
+	bool "Enable 11AX(High Efficiency) feature"
+	default n
+
+config ICMP_DISABLE_PS
+	bool "Enable ICMP packet disable powersave feature"
+	default n
+
+config BUILD_TIMESTAMP
+	bool "Embed timestamp in wlan version"
+	default n
+
+config WLAN_FEATURE_FILS
+	bool "Enable FILS feature"
+	default n
+
+config NAN_CONVERGENCE
+	bool "Enable NAN_CONVERGENCE feature"
+	default n
+
+config WLAN_OBJMGR_DEBUG
+	bool "Enable WLAN Obj Mgr Debug services"
+	default n
+
+config WLAN_FEATURE_DFS_OFFLOAD
+	bool "Enable dfs offload feature"
+	default n
+
+config WLAN_FEATURE_SARV1_TO_SARV2
+	bool "Enable conversion of SAR v1 to v2 feature"
+	default n
+
+endif # QCA_CLD_WLAN
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..fb78b03
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,32 @@
+KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
+
+# The Make variable $(M) must point to the directory that contains the module
+# source code (which includes this Makefile). It can either be an absolute or a
+# relative path. If it is a relative path, then it must be relative to the
+# kernel source directory (KERNEL_SRC). An absolute path can be obtained very
+# easily through $(shell pwd). Generating a path relative to KERNEL_SRC is
+# difficult and we accept some outside help by letting the caller override the
+# variable $(M). Allowing a relative path for $(M) enables us to have the build
+# system put output/object files (.o, .ko.) into a directory different from the
+# module source directory.
+M ?= $(shell pwd)
+
+# WLAN_ROOT must contain an absolute path (i.e. not a relative path)
+KBUILD_OPTIONS := WLAN_ROOT=$(shell cd $(KERNEL_SRC); readlink -e $(M))
+KBUILD_OPTIONS += MODNAME?=wlan
+
+#By default build for CLD
+WLAN_SELECT := CONFIG_QCA_CLD_WLAN=m
+KBUILD_OPTIONS += CONFIG_QCA_WIFI_ISOC=0
+KBUILD_OPTIONS += CONFIG_QCA_WIFI_2_0=1
+KBUILD_OPTIONS += $(WLAN_SELECT)
+KBUILD_OPTIONS += $(KBUILD_EXTRA) # Extra config if any
+
+all:
+	$(MAKE) -C $(KERNEL_SRC) M=$(M) modules $(KBUILD_OPTIONS)
+
+modules_install:
+	$(MAKE) INSTALL_MOD_STRIP=1 M=$(M) -C $(KERNEL_SRC) modules_install
+
+clean:
+	$(MAKE) -C $(KERNEL_SRC) M=$(M) clean $(KBUILD_OPTIONS)
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..bdf3e7a
--- /dev/null
+++ b/README.txt
@@ -0,0 +1 @@
+This is CNSS WLAN Host Driver for products starting from iHelium
diff --git a/components/action_oui/core/inc/wlan_action_oui_main.h b/components/action_oui/core/inc/wlan_action_oui_main.h
new file mode 100644
index 0000000..7777476
--- /dev/null
+++ b/components/action_oui/core/inc/wlan_action_oui_main.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018 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 private API which shall be used internally only
+ * in action_oui component. This file shall include prototypes of
+ * various notification handlers and logging functions.
+ *
+ * Note: This API should be never accessed out of action_oui component.
+ */
+
+#ifndef _WLAN_ACTION_OUI_MAIN_H_
+#define _WLAN_ACTION_OUI_MAIN_H_
+
+#include <qdf_types.h>
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_priv.h"
+#include "wlan_action_oui_objmgr.h"
+
+#define action_oui_log(level, args...) \
+	QDF_TRACE(QDF_MODULE_ID_ACTION_OUI, level, ## args)
+
+#define action_oui_logfl(level, format, args...) \
+	action_oui_log(level, FL(format), ## args)
+
+#define action_oui_fatal(format, args...) \
+		action_oui_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args)
+#define action_oui_err(format, args...) \
+		action_oui_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args)
+#define action_oui_warn(format, args...) \
+		action_oui_logfl(QDF_TRACE_LEVEL_WARN, format, ## args)
+#define action_oui_info(format, args...) \
+		action_oui_logfl(QDF_TRACE_LEVEL_INFO, format, ## args)
+#define action_oui_debug(format, args...) \
+		action_oui_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
+
+#define ACTION_OUI_ENTER() action_oui_debug("enter")
+#define ACTION_OUI_EXIT() action_oui_debug("exit")
+
+/**
+ * action_oui_psoc_create_notification(): Handler for psoc create notify.
+ * @psoc: psoc which is going to be created by objmgr
+ * @arg: argument for notification handler.
+ *
+ * Allocate and attach psoc private object.
+ *
+ * Return: QDF_STATUS status in case of success else return error.
+ */
+QDF_STATUS
+action_oui_psoc_create_notification(struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * action_oui_psoc_destroy_notification(): Handler for psoc destroy notify.
+ * @psoc: psoc which is going to be destroyed by objmgr
+ * @arg: argument for notification handler.
+ *
+ * Deallocate and detach psoc private object.
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS
+action_oui_psoc_destroy_notification(struct wlan_objmgr_psoc *psoc, void *arg);
+
+#endif /* end  of _WLAN_ACTION_OUI_MAIN_H_ */
diff --git a/components/action_oui/core/inc/wlan_action_oui_objmgr.h b/components/action_oui/core/inc/wlan_action_oui_objmgr.h
new file mode 100644
index 0000000..17d0b09
--- /dev/null
+++ b/components/action_oui/core/inc/wlan_action_oui_objmgr.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018 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_ACTION_OUI_OBJMGR_H
+#define _WLAN_ACTION_OUI_OBJMGR_H
+
+#include "wlan_cmn.h"
+#include "wlan_objmgr_cmn.h"
+#include "wlan_objmgr_psoc_obj.h"
+
+/**
+ * action_oui_psoc_get_ref() - Wrapper to increment action_oui ref count
+ * @psoc: psoc object
+ *
+ * Wrapper for action_oui to increment ref count after checking valid
+ * object state.
+ *
+ * Return: SUCCESS/FAILURE
+ */
+static inline
+QDF_STATUS action_oui_psoc_get_ref(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_try_get_ref(psoc, WLAN_ACTION_OUI_ID);
+}
+
+/**
+ * action_oui_psoc_put_ref() - Wrapper to decrement action_oui ref count
+ * @psoc: psoc object
+ *
+ * Wrapper for action_oui to decrement ref count of psoc.
+ *
+ * Return: SUCCESS/FAILURE
+ */
+static inline
+void action_oui_psoc_put_ref(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_release_ref(psoc, WLAN_ACTION_OUI_ID);
+}
+
+/**
+ * action_oui_psoc_get_priv(): Wrapper to retrieve psoc priv obj
+ * @psoc: psoc pointer
+ *
+ * Wrapper for action_oui to get psoc private object pointer.
+ *
+ * Return: Private object of psoc
+ */
+static inline struct action_oui_psoc_priv *
+action_oui_psoc_get_priv(struct wlan_objmgr_psoc *psoc)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+
+	psoc_priv = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+					WLAN_UMAC_COMP_ACTION_OUI);
+	QDF_BUG(psoc_priv);
+
+	return psoc_priv;
+}
+
+#endif /* _WLAN_ACTION_OUI_OBJMGR_H */
diff --git a/components/action_oui/core/inc/wlan_action_oui_priv.h b/components/action_oui/core/inc/wlan_action_oui_priv.h
new file mode 100644
index 0000000..2b325b4
--- /dev/null
+++ b/components/action_oui/core/inc/wlan_action_oui_priv.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2012-2018 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 private API which shall be used internally only
+ * in action_oui component. This file shall include prototypes of
+ * action_oui parsing and send logic.
+ *
+ * Note: This API should be never accessed out of action_oui component.
+ */
+
+#ifndef _WLAN_ACTION_OUI_PRIV_STRUCT_H_
+#define _WLAN_ACTION_OUI_PRIV_STRUCT_H_
+
+#include <qdf_list.h>
+#include <qdf_types.h>
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_tgt_api.h"
+#include "wlan_action_oui_objmgr.h"
+
+/**
+ * enum action_oui_token_type - String token types expected.
+ * @ACTION_OUI_TOKEN: oui string
+ * @ACTION_OUI_DATA_LENGTH_TOKEN: data length string
+ * @ACTION_OUI_DATA_TOKEN: OUI data string
+ * @ACTION_OUI_DATA_MASK_TOKEN: data mask string
+ * @ACTION_OUI_INFO_MASK_TOKEN: info mask string
+ * @ACTION_OUI_MAC_ADDR_TOKEN: mac addr string
+ * @ACTION_OUI_MAC_MASK_TOKEN: mac mask string
+ * @ACTION_OUI_CAPABILITY_TOKEN: capability string
+ * @ACTION_OUI_END_TOKEN: end of one oui extension
+ */
+enum action_oui_token_type {
+	ACTION_OUI_TOKEN = 1 << 0,
+	ACTION_OUI_DATA_LENGTH_TOKEN = 1 << 1,
+	ACTION_OUI_DATA_TOKEN = 1 << 2,
+	ACTION_OUI_DATA_MASK_TOKEN = 1 << 3,
+	ACTION_OUI_INFO_MASK_TOKEN = 1 << 4,
+	ACTION_OUI_MAC_ADDR_TOKEN = 1 << 5,
+	ACTION_OUI_MAC_MASK_TOKEN = 1 << 6,
+	ACTION_OUI_CAPABILITY_TOKEN = 1 << 7,
+	ACTION_OUI_END_TOKEN = 1 << 8,
+};
+
+/**
+ * struct action_oui_extension_priv - Private contents of extension.
+ * @item: list element
+ * @extension: Extension contents
+ *
+ * This structure encapsulates action_oui_extension and list item.
+ */
+struct action_oui_extension_priv {
+	qdf_list_node_t item;
+	struct action_oui_extension extension;
+};
+
+/**
+ * struct action_oui_priv - Each action info.
+ * @id: type of action
+ * @extension_list: list of extensions
+ * @extension_lock: lock to control access to @extension_list
+ *
+ * All extensions of action specified by action_id are stored
+ * at @extension_list as linked list.
+ */
+struct action_oui_priv {
+	enum action_oui_id id;
+	qdf_list_t extension_list;
+	qdf_mutex_t extension_lock;
+};
+
+/**
+ * struct action_oui_psoc_priv - Private object to be stored in psoc
+ * @psoc: pointer to psoc object
+ * @total_extensions: total count of extensions from all actions
+ * @oui_priv: array of pointers used to refer each action info
+ * @tx_ops: call-back functions to send OUIs to firmware
+ */
+struct action_oui_psoc_priv {
+	struct wlan_objmgr_psoc *psoc;
+	uint32_t total_extensions;
+	struct action_oui_priv *oui_priv[ACTION_OUI_MAXIMUM_ID];
+	struct action_oui_tx_ops tx_ops;
+};
+
+/**
+ * action_oui_parse() - Parse action oui string
+ * @psoc_priv: pointer to action_oui psoc priv obj
+ * @oui_string: string to be parsed
+ * @ation_id: type of the action to be parsed
+ *
+ * This function parses the action oui string, extracts extensions and
+ * stores them @action_oui_priv using list data structure.
+ *
+ * Return: QDF_STATUS
+ *
+ */
+QDF_STATUS
+action_oui_parse(struct action_oui_psoc_priv *psoc_priv,
+		 uint8_t *oui_string, enum action_oui_id action_id);
+
+/**
+ * action_oui_send() - Send action oui extensions to target_if.
+ * @psoc_priv: pointer to action_oui psoc priv obj
+ * @ation_id: type of the action to be send
+ *
+ * This function sends action oui extensions to target_if.
+ *
+ * Return: QDF_STATUS
+ *
+ */
+QDF_STATUS
+action_oui_send(struct action_oui_psoc_priv *psoc_priv,
+		enum action_oui_id action_id);
+
+/**
+ * action_oui_search() - Check if Vendor OUIs are present in IE buffer
+ * @psoc_priv: pointer to action_oui psoc priv obj
+ * @attr: pointer to structure containing type of action, beacon IE data etc.,
+ * @action_id: type of action to be checked
+ *
+ * This function parses the IE buffer and finds if any of the vendor OUI
+ * and related attributes are present in it.
+ *
+ * Return: If vendor OUI is present return true else false
+ */
+bool
+action_oui_search(struct action_oui_psoc_priv *psoc_priv,
+		  struct action_oui_search_attr *attr,
+		  enum action_oui_id action_id);
+
+#endif /* End  of _WLAN_ACTION_OUI_PRIV_STRUCT_H_ */
diff --git a/components/action_oui/core/src/wlan_action_oui_main.c b/components/action_oui/core/src/wlan_action_oui_main.c
new file mode 100644
index 0000000..825b989
--- /dev/null
+++ b/components/action_oui/core/src/wlan_action_oui_main.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2012-2018 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 notification handlers which are accessed
+ * internally in action_oui component only.
+ */
+
+#include "wlan_action_oui_main.h"
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_tgt_api.h"
+#include "target_if_action_oui.h"
+
+/**
+ * action_oui_allocate() - Allocates memory for various actions.
+ * @psoc_priv: pointer to action_oui psoc priv obj
+ *
+ * This function allocates memory for all the action_oui types
+ * and initializes the respective lists to store extensions
+ * extracted from action_oui_extract().
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+action_oui_allocate(struct action_oui_psoc_priv *psoc_priv)
+{
+	struct action_oui_priv *oui_priv;
+	uint32_t i;
+	uint32_t j;
+
+	for (i = 0; i < ACTION_OUI_MAXIMUM_ID; i++) {
+		oui_priv = qdf_mem_malloc(sizeof(*oui_priv));
+		if (!oui_priv) {
+			action_oui_err("Mem alloc failed for oui_priv id: %u",
+					i);
+			goto free_mem;
+		}
+		oui_priv->id = i;
+		qdf_list_create(&oui_priv->extension_list,
+				ACTION_OUI_MAX_EXTENSIONS);
+		qdf_mutex_create(&oui_priv->extension_lock);
+		psoc_priv->oui_priv[i] = oui_priv;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+free_mem:
+	for (j = 0; j < i; j++) {
+		oui_priv = psoc_priv->oui_priv[j];
+		if (!oui_priv)
+			continue;
+
+		qdf_list_destroy(&oui_priv->extension_list);
+		qdf_mutex_destroy(&oui_priv->extension_lock);
+		psoc_priv->oui_priv[j] = NULL;
+	}
+
+	return QDF_STATUS_E_NOMEM;
+}
+
+/**
+ * action_oui_destroy() - Deallocates memory for various actions.
+ * @psoc_priv: pointer to action_oui psoc priv obj
+ *
+ * This function Deallocates memory for all the action_oui types.
+ * As a part of deallocate, all extensions are destroyed.
+ *
+ * Return: None
+ */
+static void
+action_oui_destroy(struct action_oui_psoc_priv *psoc_priv)
+{
+	struct action_oui_priv *oui_priv;
+	struct action_oui_extension_priv *ext_priv;
+	qdf_list_t *ext_list;
+	QDF_STATUS status;
+	qdf_list_node_t *node = NULL;
+	uint32_t i;
+
+	psoc_priv->total_extensions = 0;
+	for (i = 0; i < ACTION_OUI_MAXIMUM_ID; i++) {
+		oui_priv = psoc_priv->oui_priv[i];
+		psoc_priv->oui_priv[i] = NULL;
+		if (!oui_priv)
+			continue;
+
+		ext_list = &oui_priv->extension_list;
+		qdf_mutex_acquire(&oui_priv->extension_lock);
+		while (!qdf_list_empty(ext_list)) {
+			status = qdf_list_remove_front(ext_list, &node);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				action_oui_err("Invalid delete in action: %u",
+						oui_priv->id);
+				break;
+			}
+			ext_priv = qdf_container_of(node,
+					struct action_oui_extension_priv,
+					item);
+			qdf_mem_free(ext_priv);
+			ext_priv = NULL;
+		}
+
+		qdf_list_destroy(ext_list);
+		qdf_mutex_release(&oui_priv->extension_lock);
+		qdf_mutex_destroy(&oui_priv->extension_lock);
+		qdf_mem_free(oui_priv);
+		oui_priv = NULL;
+	}
+}
+
+QDF_STATUS
+action_oui_psoc_create_notification(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	QDF_STATUS status;
+
+	ACTION_OUI_ENTER();
+
+	psoc_priv = qdf_mem_malloc(sizeof(*psoc_priv));
+	if (!psoc_priv) {
+		action_oui_err("Failed to allocate psoc_priv");
+		status = QDF_STATUS_E_NOMEM;
+		goto exit;
+	}
+
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+				WLAN_UMAC_COMP_ACTION_OUI,
+				(void *)psoc_priv, QDF_STATUS_SUCCESS);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		action_oui_err("Failed to attach priv with psoc");
+		goto free_psoc_priv;
+	}
+
+	target_if_action_oui_register_tx_ops(&psoc_priv->tx_ops);
+	psoc_priv->psoc = psoc;
+
+	status = action_oui_allocate(psoc_priv);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		action_oui_err("Failed to alloc action_oui");
+		goto detach_psoc_priv;
+	}
+
+	action_oui_debug("psoc priv attached");
+	goto exit;
+
+detach_psoc_priv:
+	wlan_objmgr_psoc_component_obj_detach(psoc,
+					      WLAN_UMAC_COMP_ACTION_OUI,
+					      (void *)psoc_priv);
+free_psoc_priv:
+	qdf_mem_free(psoc_priv);
+	status = QDF_STATUS_E_INVAL;
+exit:
+	ACTION_OUI_EXIT();
+	return status;
+}
+
+QDF_STATUS
+action_oui_psoc_destroy_notification(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct action_oui_psoc_priv *psoc_priv = NULL;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	ACTION_OUI_ENTER();
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	status = wlan_objmgr_psoc_component_obj_detach(psoc,
+					WLAN_UMAC_COMP_ACTION_OUI,
+					(void *)psoc_priv);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		action_oui_err("Failed to detach priv with psoc");
+
+	action_oui_destroy(psoc_priv);
+	qdf_mem_free(psoc_priv);
+
+exit:
+	ACTION_OUI_EXIT();
+	return status;
+}
diff --git a/components/action_oui/core/src/wlan_action_oui_parse.c b/components/action_oui/core/src/wlan_action_oui_parse.c
new file mode 100644
index 0000000..a8f16c8
--- /dev/null
+++ b/components/action_oui/core/src/wlan_action_oui_parse.c
@@ -0,0 +1,961 @@
+/*
+ * Copyright (c) 2012-2018 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 parsing logic for action_oui strings, extract
+ * extensions and store them using linked list. Functions defined in
+ * this file can be accessed internally in action_oui component only.
+ */
+
+#include "wlan_action_oui_main.h"
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_tgt_api.h"
+#include "target_if_action_oui.h"
+#include <qdf_str.h>
+#include <wlan_utility.h>
+
+/**
+ * action_oui_string_to_hex() - convert string to uint8_t hex array
+ * @token - string to be converted
+ * @hex - output string to hold converted string
+ * @no_of_lengths - count of possible lengths for input string
+ * @possible_lengths - array holding possible lengths
+ *
+ * This function converts the continuous input string of even length and
+ * containing hexa decimal characters into hexa decimal array of uint8_t type.
+ * Input string needs to be NULL terminated and the length should match with
+ * one of entries in @possible_lengths
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool action_oui_string_to_hex(uint8_t *token, uint8_t *hex,
+			      uint32_t no_of_lengths,
+			      uint32_t *possible_lengths)
+{
+	uint32_t token_len = qdf_str_len(token);
+	uint32_t hex_str_len;
+	uint32_t i;
+	int ret;
+
+	if (!token_len || (token_len & 0x01)) {
+		action_oui_err("Token len is not multiple of 2");
+		return false;
+	}
+
+	for (i = 0; i < no_of_lengths; i++)
+		if (token_len == possible_lengths[i])
+			break;
+
+	if (i == no_of_lengths) {
+		action_oui_err("Token len doesn't match with expected len");
+		return false;
+	}
+
+	hex_str_len = token_len / 2;
+
+	ret = qdf_hex_str_to_binary(hex, token, hex_str_len);
+	if (ret) {
+		action_oui_err("Token doesn't contain hex digits");
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * action_oui_token_string() - converts enum value to string
+ * token_id: enum value to be converted to string
+ *
+ * This function converts the enum value of type action_oui_token_type
+ * to string
+ *
+ * Return: converted string
+ */
+static
+uint8_t *action_oui_token_string(enum action_oui_token_type token_id)
+{
+	switch (token_id) {
+		CASE_RETURN_STRING(ACTION_OUI_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_DATA_LENGTH_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_DATA_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_DATA_MASK_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_INFO_MASK_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_MAC_ADDR_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_MAC_MASK_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_CAPABILITY_TOKEN);
+		CASE_RETURN_STRING(ACTION_OUI_END_TOKEN);
+	}
+
+	return (uint8_t *) "UNKNOWN";
+}
+
+/**
+ * validate_and_convert_oui() - validate and convert OUI str to hex array
+ * @token: OUI string
+ * @ext: pointer to container which holds converted hex array
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the OUI string for action OUI inis, convert them to hex array and store it
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static
+bool validate_and_convert_oui(uint8_t *token,
+			struct action_oui_extension *ext,
+			enum action_oui_token_type *action_token)
+{
+	bool valid;
+	uint32_t expected_token_len[2] = {6, 10};
+
+	valid = action_oui_string_to_hex(token, ext->oui, 2,
+					 expected_token_len);
+	if (!valid)
+		return false;
+
+	ext->oui_length = qdf_str_len(token) / 2;
+
+	*action_token = ACTION_OUI_DATA_LENGTH_TOKEN;
+
+	return valid;
+}
+
+/**
+ * validate_and_convert_data_length() - validate data len str
+ * @token: data length string
+ * @ext: pointer to container which holds hex value formed from input str
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the data length string for action OUI inis, convert it to hex value and
+ * store it in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_data_length(uint8_t *token,
+				struct action_oui_extension *ext,
+				enum action_oui_token_type *action_token)
+{
+	uint32_t token_len = qdf_str_len(token);
+	int ret;
+	uint8_t len = 0;
+
+	if (token_len != 1 && token_len != 2) {
+		action_oui_err("Invalid str token len for action OUI data len");
+		return false;
+	}
+
+	ret = kstrtou8(token, 16, &len);
+	if (ret) {
+		action_oui_err("Invalid char in action OUI data len str token");
+		return false;
+	}
+
+	if ((uint32_t)len > ACTION_OUI_MAX_DATA_LENGTH) {
+		action_oui_err("action OUI data len is more than %u",
+			ACTION_OUI_MAX_DATA_LENGTH);
+		return false;
+	}
+
+	ext->data_length = len;
+
+	if (!ext->data_length)
+		*action_token = ACTION_OUI_INFO_MASK_TOKEN;
+	else
+		*action_token = ACTION_OUI_DATA_TOKEN;
+
+	return true;
+}
+
+/**
+ * validate_and_convert_data() - validate and convert data str to hex array
+ * @token: data string
+ * @ext: pointer to container which holds converted hex array
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the data string for action OUI inis, convert it to hex array and store in
+ * action_oui extension. After successful parsing update the @action_token
+ * to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_data(uint8_t *token,
+			      struct action_oui_extension *ext,
+			      enum action_oui_token_type *action_token)
+{
+	bool valid;
+	uint32_t expected_token_len[1] = {2 * ext->data_length};
+
+	valid = action_oui_string_to_hex(token, ext->data, 1,
+					 expected_token_len);
+	if (!valid)
+		return false;
+
+	*action_token = ACTION_OUI_DATA_MASK_TOKEN;
+
+	return true;
+}
+
+/**
+ * validate_and_convert_data_mask() - validate and convert data mask str
+ * @token: data mask string
+ * @ext: pointer to container which holds converted hex array
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the data mask string for action OUI inis, convert it to hex array and store
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_data_mask(uint8_t *token,
+				   struct action_oui_extension *ext,
+				   enum action_oui_token_type *action_token)
+{
+	bool valid;
+	uint32_t expected_token_len[1];
+	uint32_t data_mask_length;
+	uint32_t data_length = ext->data_length;
+
+	if (data_length % 8 == 0)
+		data_mask_length = data_length / 8;
+	else
+		data_mask_length = ((data_length / 8) + 1);
+
+	if (data_mask_length > ACTION_OUI_MAX_DATA_MASK_LENGTH)
+		return false;
+
+	expected_token_len[0] = 2 * data_mask_length;
+
+	valid = action_oui_string_to_hex(token, ext->data_mask, 1,
+				  expected_token_len);
+	if (!valid)
+		return false;
+
+	ext->data_mask_length = data_mask_length;
+
+	*action_token = ACTION_OUI_INFO_MASK_TOKEN;
+
+	return valid;
+}
+
+/**
+ * validate_and_convert_info_mask() - validate and convert info mask str
+ * @token: info mask string
+ * @ext: pointer to container which holds converted hex array
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the info mask string for action OUI inis, convert it to hex array and store
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_info_mask(uint8_t *token,
+				   struct action_oui_extension *ext,
+				   enum action_oui_token_type *action_token)
+{
+	uint32_t token_len = qdf_str_len(token);
+	uint8_t hex_value = 0;
+	uint32_t info_mask;
+	int ret;
+
+	if (token_len != 2) {
+		action_oui_err("action OUI info mask str token len is not of 2 chars");
+		return false;
+	}
+
+	ret = kstrtou8(token, 16, &hex_value);
+	if (ret) {
+		action_oui_err("Invalid char in action OUI info mask str token");
+		return false;
+	}
+
+	info_mask = hex_value;
+
+	ext->info_mask = info_mask;
+
+	if (!info_mask || !(info_mask & ~ACTION_OUI_INFO_OUI)) {
+		*action_token = ACTION_OUI_END_TOKEN;
+		return true;
+	}
+
+	if (info_mask & ~ACTION_OUI_INFO_MASK) {
+		action_oui_err("Invalid bits are set in action OUI info mask");
+		return false;
+	}
+
+	/*
+	 * If OUI bit is not set in the info presence, we need to ignore the
+	 * OUI and OUI Data. Set OUI and OUI data length to 0 here.
+	 */
+	if (!(info_mask & ACTION_OUI_INFO_OUI)) {
+		ext->oui_length = 0;
+		ext->data_length = 0;
+		ext->data_mask_length = 0;
+	}
+
+	if (info_mask & ACTION_OUI_INFO_MAC_ADDRESS) {
+		*action_token = ACTION_OUI_MAC_ADDR_TOKEN;
+		return true;
+	}
+
+	*action_token = ACTION_OUI_CAPABILITY_TOKEN;
+	return true;
+}
+
+/**
+ * validate_and_convert_mac_addr() - validate and convert mac addr str
+ * @token: mac address string
+ * @ext: pointer to container which holds converted hex array
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the mac address string for action OUI inis, convert it to hex array and store
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_mac_addr(uint8_t *token,
+				  struct action_oui_extension *ext,
+				  enum action_oui_token_type *action_token)
+{
+	uint32_t expected_token_len[1] = {2 * QDF_MAC_ADDR_SIZE};
+	bool valid;
+
+	valid = action_oui_string_to_hex(token, ext->mac_addr, 1,
+				  expected_token_len);
+	if (!valid)
+		return false;
+
+	ext->mac_addr_length = QDF_MAC_ADDR_SIZE;
+
+	*action_token = ACTION_OUI_MAC_MASK_TOKEN;
+
+	return true;
+}
+
+/**
+ * validate_and_convert_mac_mask() - validate and convert mac mask
+ * @token: mac mask string
+ * @ext: pointer to container which holds converted hex value
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the mac mask string for action OUI inis, convert it to hex value and store
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_mac_mask(uint8_t *token,
+				  struct action_oui_extension *ext,
+				  enum action_oui_token_type *action_token)
+{
+	uint32_t expected_token_len[1] = {2};
+	uint32_t info_mask = ext->info_mask;
+	bool valid;
+	uint32_t mac_mask_length;
+
+	valid = action_oui_string_to_hex(token, ext->mac_mask, 1,
+				  expected_token_len);
+	if (!valid)
+		return false;
+
+	mac_mask_length = qdf_str_len(token) / 2;
+	if (mac_mask_length > ACTION_OUI_MAC_MASK_LENGTH) {
+		action_oui_err("action OUI mac mask str token len is more than %u chars",
+			expected_token_len[0]);
+		return false;
+	}
+
+	ext->mac_mask_length = mac_mask_length;
+
+	if ((info_mask & ACTION_OUI_INFO_AP_CAPABILITY_NSS) ||
+	    (info_mask & ACTION_OUI_INFO_AP_CAPABILITY_HT) ||
+	    (info_mask & ACTION_OUI_INFO_AP_CAPABILITY_VHT) ||
+	    (info_mask & ACTION_OUI_INFO_AP_CAPABILITY_BAND)) {
+		*action_token = ACTION_OUI_CAPABILITY_TOKEN;
+		return true;
+	}
+
+	*action_token = ACTION_OUI_END_TOKEN;
+	return true;
+}
+
+/**
+ * validate_and_convert_capability() - validate and convert capability str
+ * @token: capability string
+ * @ext: pointer to container which holds converted hex value
+ * @action_token: next action to be parsed
+ *
+ * This is an internal function invoked from action_oui_parse to validate
+ * the capability string for action OUI inis, convert it to hex value and store
+ * in action_oui extension. After successful parsing update the
+ * @action_token to hold the next expected string.
+ *
+ * Return: If conversion is successful return true else false
+ */
+static bool
+validate_and_convert_capability(uint8_t *token,
+				struct action_oui_extension *ext,
+				enum action_oui_token_type *action_token)
+{
+	uint32_t expected_token_len[1] = {2};
+	uint32_t info_mask = ext->info_mask;
+	uint32_t capability_length;
+	uint8_t caps_0;
+	bool valid;
+
+	valid = action_oui_string_to_hex(token, ext->capability, 1,
+				  expected_token_len);
+	if (!valid)
+		return false;
+
+	capability_length = qdf_str_len(token) / 2;
+	if (capability_length > ACTION_OUI_MAX_CAPABILITY_LENGTH) {
+		action_oui_err("action OUI capability str token len is more than %u chars",
+			expected_token_len[0]);
+		return false;
+	}
+
+	caps_0 = ext->capability[0];
+
+	if ((info_mask & ACTION_OUI_INFO_AP_CAPABILITY_NSS) &&
+	    (!(caps_0 & ACTION_OUI_CAPABILITY_NSS_MASK))) {
+		action_oui_err("Info presence for NSS is set but respective bits in capability are not set");
+		return false;
+	}
+
+	if ((info_mask & ACTION_OUI_INFO_AP_CAPABILITY_BAND) &&
+	    (!(caps_0 & ACTION_OUI_CAPABILITY_BAND_MASK))) {
+		action_oui_err("Info presence for BAND is set but respective bits in capability are not set");
+		return false;
+	}
+
+	ext->capability_length = capability_length;
+
+	*action_token = ACTION_OUI_END_TOKEN;
+
+	return true;
+}
+
+/**
+ * action_oui_extension_store() - store action oui extension
+ * @priv_obj: pointer to action_oui priv obj
+ * @oui_priv: type of the action
+ * @ext: oui extension to store in sme
+ *
+ * This function stores the parsed oui extension
+ *
+ * Return: QDF_STATUS
+ *
+ */
+static QDF_STATUS
+action_oui_extension_store(struct action_oui_psoc_priv *psoc_priv,
+			   struct action_oui_priv *oui_priv,
+			   struct action_oui_extension ext)
+{
+	struct action_oui_extension_priv *ext_priv;
+
+	qdf_mutex_acquire(&oui_priv->extension_lock);
+	if (qdf_list_size(&oui_priv->extension_list) ==
+			  ACTION_OUI_MAX_EXTENSIONS) {
+		qdf_mutex_release(&oui_priv->extension_lock);
+		action_oui_err("Reached maximum OUI extensions");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ext_priv = qdf_mem_malloc(sizeof(*ext_priv));
+	if (!ext_priv) {
+		qdf_mutex_release(&oui_priv->extension_lock);
+		action_oui_err("Failed to allocate memory for action oui extension priv");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	ext_priv->extension = ext;
+	qdf_list_insert_back(&oui_priv->extension_list, &ext_priv->item);
+	psoc_priv->total_extensions++;
+	qdf_mutex_release(&oui_priv->extension_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+action_oui_parse(struct action_oui_psoc_priv *psoc_priv,
+		 uint8_t *oui_string, enum action_oui_id action_id)
+{
+	struct action_oui_extension ext = {0};
+	enum action_oui_token_type action_token = ACTION_OUI_TOKEN;
+	char *str1;
+	char *str2;
+	char *token;
+	bool valid = true;
+	bool oui_count_exceed = false;
+	uint32_t oui_index = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct action_oui_priv *oui_priv;
+
+	if (!oui_string) {
+		action_oui_err("Invalid string for action oui: %u", action_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	oui_priv = psoc_priv->oui_priv[action_id];
+	if (!oui_priv) {
+		action_oui_err("action oui priv not allocated");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	str1 = qdf_str_trim((char *)oui_string);
+
+	while (str1) {
+		str2 = skip_spaces(str1);
+		if (str2[0] == '\0') {
+			action_oui_err("Invalid spaces in action oui: %u at extension: %u for token: %s",
+				action_id,
+				oui_index + 1,
+				action_oui_token_string(action_token));
+			valid = false;
+			break;
+		}
+
+		token = strsep(&str2, " ");
+		if (!token) {
+			action_oui_err("Invalid string for token: %s at extension: %u in action oui: %u",
+				action_oui_token_string(action_token),
+				oui_index + 1, action_id);
+			valid = false;
+			break;
+		}
+
+		str1 = str2;
+
+		switch (action_token) {
+
+		case ACTION_OUI_TOKEN:
+			valid = validate_and_convert_oui(token, &ext,
+							 &action_token);
+			break;
+
+		case ACTION_OUI_DATA_LENGTH_TOKEN:
+			valid = validate_and_convert_data_length(token, &ext,
+								&action_token);
+			break;
+
+		case ACTION_OUI_DATA_TOKEN:
+			valid = validate_and_convert_data(token, &ext,
+							&action_token);
+			break;
+
+		case ACTION_OUI_DATA_MASK_TOKEN:
+			valid = validate_and_convert_data_mask(token, &ext,
+							&action_token);
+			break;
+
+		case ACTION_OUI_INFO_MASK_TOKEN:
+			valid = validate_and_convert_info_mask(token, &ext,
+							&action_token);
+			break;
+
+		case ACTION_OUI_MAC_ADDR_TOKEN:
+			valid = validate_and_convert_mac_addr(token, &ext,
+							&action_token);
+			break;
+
+		case ACTION_OUI_MAC_MASK_TOKEN:
+			valid = validate_and_convert_mac_mask(token, &ext,
+							&action_token);
+			break;
+
+		case ACTION_OUI_CAPABILITY_TOKEN:
+			valid = validate_and_convert_capability(token, &ext,
+							&action_token);
+			break;
+
+		default:
+			valid = false;
+			break;
+		}
+
+		if (!valid) {
+			action_oui_err("Invalid string for token: %s at extension: %u in action oui: %u",
+				action_oui_token_string(action_token),
+				oui_index + 1,
+				action_id);
+			break;
+		}
+
+		if (action_token != ACTION_OUI_END_TOKEN)
+			continue;
+
+		status = action_oui_extension_store(psoc_priv, oui_priv, ext);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			valid = false;
+			action_oui_err("sme set of extension: %u for action oui: %u failed",
+				oui_index + 1, action_id);
+			break;
+		}
+
+		oui_index++;
+		if (oui_index == ACTION_OUI_MAX_EXTENSIONS) {
+			if (str1)
+				oui_count_exceed = true;
+			break;
+		}
+
+		/* reset the params for next action OUI parse */
+		action_token = ACTION_OUI_TOKEN;
+		qdf_mem_zero(&ext, sizeof(ext));
+	}
+
+	if (oui_count_exceed) {
+		action_oui_err("Reached Maximum extensions: %u in action_oui: %u, ignoring the rest",
+			ACTION_OUI_MAX_EXTENSIONS, action_id);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (action_token != ACTION_OUI_TOKEN &&
+	    action_token != ACTION_OUI_END_TOKEN &&
+	    valid && !str1) {
+		action_oui_err("No string for token: %s at extension: %u in action oui: %u",
+			action_oui_token_string(action_token),
+			oui_index + 1,
+			action_id);
+		valid = false;
+	}
+
+	if (!oui_index) {
+		action_oui_err("Not able to parse any extension in action oui: %u",
+			action_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (valid)
+		action_oui_debug("All extensions: %u parsed successfully in action oui: %u",
+			  oui_index, action_id);
+	else
+		action_oui_err("First %u extensions parsed successfully in action oui: %u",
+			oui_index, action_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS action_oui_send(struct action_oui_psoc_priv *psoc_priv,
+			enum action_oui_id action_id)
+{
+	QDF_STATUS status;
+	struct action_oui_request *req;
+	struct action_oui_priv *oui_priv;
+	struct action_oui_extension *extension;
+	struct action_oui_extension_priv *ext_priv;
+	qdf_list_node_t *node = NULL;
+	qdf_list_node_t *next_node = NULL;
+	qdf_list_t *extension_list;
+	uint32_t len;
+	uint32_t no_oui_extensions;
+
+	oui_priv = psoc_priv->oui_priv[action_id];
+	if (!oui_priv)
+		return QDF_STATUS_SUCCESS;
+
+	extension_list = &oui_priv->extension_list;
+	qdf_mutex_acquire(&oui_priv->extension_lock);
+	if (qdf_list_empty(extension_list)) {
+		qdf_mutex_release(&oui_priv->extension_lock);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	no_oui_extensions = qdf_list_size(extension_list);
+	len = sizeof(*req) + no_oui_extensions * sizeof(*extension);
+	req = qdf_mem_malloc(len);
+	if (!req) {
+		action_oui_err("Failed to allocate memory for action_oui");
+		qdf_mutex_release(&oui_priv->extension_lock);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	req->action_id = oui_priv->id;
+	req->no_oui_extensions = no_oui_extensions;
+	req->total_no_oui_extensions = psoc_priv->total_extensions;
+
+	extension = req->extension;
+	qdf_list_peek_front(extension_list, &node);
+	while (node) {
+		ext_priv = qdf_container_of(node,
+					   struct action_oui_extension_priv,
+					   item);
+		*extension = ext_priv->extension;
+		status = qdf_list_peek_next(extension_list, node,
+						&next_node);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+		node = next_node;
+		next_node = NULL;
+		extension++;
+	}
+
+	qdf_mutex_release(&oui_priv->extension_lock);
+
+	status = tgt_action_oui_send(psoc_priv->psoc, req);
+	qdf_mem_free(req);
+
+	return status;
+}
+
+/**
+ * check_for_vendor_oui_data() - compares for vendor OUI data from IE
+ * and returns true if OUI data matches with the ini
+ * @extension: pointer to action oui extension data
+ * @oui_ptr: pointer to Vendor IE in the beacon
+ *
+ * Return: true or false
+ */
+static bool
+check_for_vendor_oui_data(struct action_oui_extension *extension,
+			  const uint8_t *oui_ptr)
+{
+	const uint8_t *data;
+	uint8_t i, j, elem_len, data_len;
+	uint8_t data_mask = 0x80;
+
+	elem_len = oui_ptr[1];
+	if (elem_len < extension->oui_length)
+		return false;
+
+	data_len = elem_len - extension->oui_length;
+	if (data_len < extension->data_length)
+		return false;
+
+	data = &oui_ptr[2 + extension->oui_length];
+	for (i = 0, j = 0;
+	     (i < data_len && j < extension->data_mask_length);
+	     i++) {
+		if ((extension->data_mask[j] & data_mask) &&
+		    !(extension->data[i] == data[i]))
+			return false;
+		data_mask = data_mask >> 1;
+		if (!data_mask) {
+			data_mask = 0x80;
+			j++;
+		}
+	}
+
+	return true;
+}
+
+/**
+ * check_for_vendor_ap_mac() - compares for vendor AP MAC in the ini with
+ * bssid from the session and returns true if matches
+ * @extension: pointer to action oui extension data
+ * @attr: pointer to structure containing mac_addr (bssid) of AP
+ *
+ * Return: true or false
+ */
+static bool
+check_for_vendor_ap_mac(struct action_oui_extension *extension,
+			struct action_oui_search_attr *attr)
+{
+	uint8_t i;
+	uint8_t mac_mask = 0x80;
+	uint8_t *mac_addr = attr->mac_addr;
+
+	for (i = 0; i < QDF_MAC_ADDR_SIZE; i++) {
+		if ((*extension->mac_mask & mac_mask) &&
+		    !(extension->mac_addr[i] == mac_addr[i]))
+			return false;
+		mac_mask = mac_mask >> 1;
+	}
+
+	return true;
+}
+
+/**
+ * check_for_vendor_ap_capabilities() - Compares various Vendor AP
+ * capabilities like NSS, HT, VHT, Band from the ini with the AP's capability
+ * from the beacon and returns true if all the capability matches
+ * @extension: pointer to oui extension data
+ * @attr: pointer to structure containing type of action, ap capabilities
+ *
+ * Return: true or false
+ */
+static bool
+check_for_vendor_ap_capabilities(struct action_oui_extension *extension,
+				 struct action_oui_search_attr *attr)
+{
+	uint8_t nss_mask;
+
+	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_NSS) {
+		nss_mask = 1 << (attr->nss - 1);
+		if (!((*extension->capability &
+		    ACTION_OUI_CAPABILITY_NSS_MASK) &
+		    nss_mask))
+		return false;
+	}
+
+	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_HT) {
+		if (*extension->capability &
+		    ACTION_OUI_CAPABILITY_HT_ENABLE_MASK) {
+			if (!attr->ht_cap)
+				return false;
+		} else {
+			if (attr->ht_cap)
+				return false;
+		}
+	}
+
+	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_VHT) {
+		if (*extension->capability &
+		    ACTION_OUI_CAPABILITY_VHT_ENABLE_MASK) {
+			if (!attr->vht_cap)
+				return false;
+		} else {
+			if (attr->vht_cap)
+				return false;
+		}
+	}
+
+	if (extension->info_mask & ACTION_OUI_INFO_AP_CAPABILITY_BAND) {
+		if ((*extension->capability &
+		    ACTION_OUI_CAPABILITY_2G_BAND_MASK) &&
+		    !attr->enable_2g)
+			return false;
+		if ((*extension->capability &
+		    ACTION_CAPABILITY_5G_BAND_MASK) &&
+		    !attr->enable_5g)
+			return false;
+	}
+
+	return true;
+}
+
+bool
+action_oui_search(struct action_oui_psoc_priv *psoc_priv,
+		  struct action_oui_search_attr *attr,
+		  enum action_oui_id action_id)
+{
+	struct action_oui_priv *oui_priv;
+	struct action_oui_extension_priv *priv_ext;
+	struct action_oui_extension *extension;
+	qdf_list_node_t *node = NULL;
+	qdf_list_node_t *next_node = NULL;
+	qdf_list_t *extension_list;
+	QDF_STATUS qdf_status;
+	const uint8_t *oui_ptr;
+	bool wildcard_oui = false;
+
+	oui_priv = psoc_priv->oui_priv[action_id];
+	if (!oui_priv) {
+		action_oui_debug("action oui for id %d is empty",
+				 action_id);
+		return false;
+	}
+
+	extension_list = &oui_priv->extension_list;
+	qdf_mutex_acquire(&oui_priv->extension_lock);
+	if (qdf_list_empty(extension_list)) {
+		qdf_mutex_release(&oui_priv->extension_lock);
+		action_oui_debug("OUI List Empty");
+		return false;
+	}
+
+	qdf_list_peek_front(extension_list, &node);
+	while (node) {
+		priv_ext = qdf_container_of(node,
+					   struct action_oui_extension_priv,
+					   item);
+		extension = &priv_ext->extension;
+
+		/*
+		 * If a wildcard OUI bit is not set in the info_mask, proceed
+		 * to other checks skipping the OUI and vendor data checks
+		 */
+
+		if (!(extension->info_mask & ACTION_OUI_INFO_OUI)) {
+			action_oui_debug("Wildcard OUI found");
+			wildcard_oui = true;
+		}
+
+		oui_ptr = wlan_get_vendor_ie_ptr_from_oui(extension->oui,
+							 extension->oui_length,
+							 attr->ie_data,
+							 attr->ie_length);
+		if (!oui_ptr  && !wildcard_oui) {
+			action_oui_debug("No matching IE found for OUI");
+			QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+					   QDF_TRACE_LEVEL_DEBUG,
+					   extension->oui,
+					   extension->oui_length);
+			goto next;
+		}
+
+		action_oui_debug("IE found for OUI");
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+				   QDF_TRACE_LEVEL_DEBUG,
+				   extension->oui,
+				   extension->oui_length);
+
+		if (extension->data_length && !wildcard_oui &&
+		    !check_for_vendor_oui_data(extension, oui_ptr)) {
+			action_oui_debug("Vendor IE Data mismatch");
+			goto next;
+		}
+
+		if ((extension->info_mask & ACTION_OUI_INFO_MAC_ADDRESS) &&
+		    !check_for_vendor_ap_mac(extension, attr)) {
+			action_oui_debug("Vendor IE MAC Mismatch");
+			goto next;
+		}
+
+		if (!check_for_vendor_ap_capabilities(extension, attr)) {
+			action_oui_debug("Vendor IE capabilties mismatch");
+			goto next;
+		}
+
+		action_oui_debug("Vendor AP found for OUI");
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				   extension->oui, extension->oui_length);
+		qdf_mutex_release(&oui_priv->extension_lock);
+		return true;
+next:
+		qdf_status = qdf_list_peek_next(extension_list,
+						node, &next_node);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			break;
+
+		node = next_node;
+		next_node = NULL;
+		wildcard_oui = false;
+	}
+
+	qdf_mutex_release(&oui_priv->extension_lock);
+	return false;
+}
diff --git a/components/action_oui/dispatcher/inc/wlan_action_oui_public_struct.h b/components/action_oui/dispatcher/inc/wlan_action_oui_public_struct.h
new file mode 100644
index 0000000..6056b76
--- /dev/null
+++ b/components/action_oui/dispatcher/inc/wlan_action_oui_public_struct.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2016-2018 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 structs and macros which can be accessed by various
+ * components and modules.
+ */
+
+#ifndef _WLAN_ACTION_OUI_PUBLIC_STRUCT_H_
+#define _WLAN_ACTION_OUI_PUBLIC_STRUCT_H_
+
+#include <wlan_cmn.h>
+#include <qdf_status.h>
+#include <qdf_types.h>
+
+/*
+ * Maximum ini string length of actions oui extensions,
+ * (n * 83) + (n - 1) spaces + 1 (terminating character),
+ * where n is the no of oui extensions
+ * currently, max no of oui extensions is 10
+ */
+#define ACTION_OUI_MAX_STR_LEN 840
+
+/*
+ * Maximum number of action oui extensions supported in
+ * each action oui category
+ */
+#define ACTION_OUI_MAX_EXTENSIONS 10
+
+#define ACTION_OUI_MAX_OUI_LENGTH 5
+#define ACTION_OUI_MAX_DATA_LENGTH 20
+#define ACTION_OUI_MAX_DATA_MASK_LENGTH 3
+#define ACTION_OUI_MAC_MASK_LENGTH 1
+#define ACTION_OUI_MAX_CAPABILITY_LENGTH 1
+
+/*
+ * NSS Mask and NSS Offset to extract NSS info from
+ * capability field of action oui extension
+ */
+#define ACTION_OUI_CAPABILITY_NSS_MASK 0x0f
+#define ACTION_OUI_CAPABILITY_NSS_OFFSET 0
+#define ACTION_OUI_CAPABILITY_NSS_MASK_1X1 1
+#define ACTION_OUI_CAPABILITY_NSS_MASK_2X2 2
+#define ACTION_OUI_CAPABILITY_NSS_MASK_3X3 4
+#define ACTION_OUI_CAPABILITY_NSS_MASK_4X4 8
+
+/*
+ * Mask and offset to extract HT and VHT info from
+ * capability field of action oui extension
+ */
+#define ACTION_OUI_CAPABILITY_HT_ENABLE_MASK 0x10
+#define ACTION_OUI_CAPABILITY_HT_ENABLE_OFFSET 4
+#define ACTION_OUI_CAPABILITY_VHT_ENABLE_MASK 0x20
+#define ACTION_OUI_CAPABILITY_VHT_ENABLE_OFFSET 5
+
+/*
+ * Mask and offset to extract Band (2G and 5G) info from
+ * capability field of action oui extension
+ */
+#define ACTION_OUI_CAPABILITY_BAND_MASK 0xC0
+#define ACTION_OUI_CAPABILITY_BAND_OFFSET 6
+#define ACTION_OUI_CAPABILITY_2G_BAND_MASK 0x40
+#define ACTION_OUI_CAPABILITY_2G_BAND_OFFSET 6
+#define ACTION_CAPABILITY_5G_BAND_MASK 0x80
+#define ACTION_CAPABILITY_5G_BAND_OFFSET 7
+
+/**
+ * enum action_oui_id - to identify type of action oui
+ * @ACTION_OUI_CONNECT_1X1: for 1x1 connection only
+ * @ACTION_OUI_ITO_EXTENSION: for extending inactivity time of station
+ * @ACTION_OUI_CCKM_1X1: for TX with CCKM 1x1 only
+ * @ACTION_OUI_MAXIMUM_ID: maximun number of action oui types
+ */
+enum action_oui_id {
+	ACTION_OUI_CONNECT_1X1 = 0,
+	ACTION_OUI_ITO_EXTENSION = 1,
+	ACTION_OUI_CCKM_1X1 = 2,
+	ACTION_OUI_ITO_ALTERNATE = 3,
+	ACTION_OUI_SWITCH_TO_11N_MODE = 4,
+	ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN = 5,
+	ACTION_OUI_MAXIMUM_ID
+};
+
+/**
+ * enum action_oui_info - to indicate presence of various action OUI
+ * fields in action oui extension, following identifiers are to be set in
+ * the info mask field of action oui extension
+ * @ACTION_OUI_INFO_OUI: to indicate presence of OUI string
+ * @ACTION_OUI_INFO_MAC_ADDRESS: to indicate presence of mac address
+ * @ACTION_OUI_INFO_AP_CAPABILITY_NSS: to indicate presence of nss info
+ * @ACTION_OUI_INFO_AP_CAPABILITY_HT: to indicate presence of HT cap
+ * @ACTION_OUI_INFO_AP_CAPABILITY_VHT: to indicate presence of VHT cap
+ * @ACTION_OUI_INFO_AP_CAPABILITY_BAND: to indicate presence of band info
+ */
+enum action_oui_info {
+	/*
+	 * OUI centric parsing, expect OUI in each action OUI extension,
+	 * hence, ACTION_OUI_INFO_OUI is dummy
+	 */
+	ACTION_OUI_INFO_OUI = 1 << 0,
+	ACTION_OUI_INFO_MAC_ADDRESS = 1 << 1,
+	ACTION_OUI_INFO_AP_CAPABILITY_NSS = 1 << 2,
+	ACTION_OUI_INFO_AP_CAPABILITY_HT = 1 << 3,
+	ACTION_OUI_INFO_AP_CAPABILITY_VHT = 1 << 4,
+	ACTION_OUI_INFO_AP_CAPABILITY_BAND = 1 << 5,
+};
+
+/* Total mask of all enum action_oui_info IDs */
+#define ACTION_OUI_INFO_MASK 0x3F
+
+/**
+ * struct action_oui_extension - action oui extension contents
+ * @info_mask: info mask
+ * @oui_length: length of the oui, either 3 or 5 bytes
+ * @data_length: length of the oui data
+ * @data_mask_length: length of the data mask
+ * @mac_addr_length: length of the mac addr
+ * @mac_mask_length: length of the mac mask
+ * @capability_length: length of the capability
+ * @oui: oui value
+ * @data: data buffer
+ * @data_mask: data mask buffer
+ * @mac_addr: mac addr
+ * @mac_mask: mac mask
+ * @capability: capability buffer
+ */
+struct action_oui_extension {
+	uint32_t info_mask;
+	uint32_t oui_length;
+	uint32_t data_length;
+	uint32_t data_mask_length;
+	uint32_t mac_addr_length;
+	uint32_t mac_mask_length;
+	uint32_t capability_length;
+	uint8_t oui[ACTION_OUI_MAX_OUI_LENGTH];
+	uint8_t data[ACTION_OUI_MAX_DATA_LENGTH];
+	uint8_t data_mask[ACTION_OUI_MAX_DATA_MASK_LENGTH];
+	uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
+	uint8_t mac_mask[ACTION_OUI_MAC_MASK_LENGTH];
+	uint8_t capability[ACTION_OUI_MAX_CAPABILITY_LENGTH];
+};
+
+/**
+ * struct action_oui_request - Contains specific action oui information
+ * @action_id: type of action from enum action_oui_info
+ * @no_oui_extensions: number of action oui extensions of type @action_id
+ * @total_no_oui_extensions: total no of oui extensions from all
+ * action oui types, this is just a total count needed by firmware
+ * @extension: pointer to zero length array, to indicate this structure is
+ * followed by a array of @no_oui_extensions structures of
+ * type struct action_oui_extension
+ */
+struct action_oui_request {
+	enum action_oui_id action_id;
+	uint32_t no_oui_extensions;
+	uint32_t total_no_oui_extensions;
+	struct action_oui_extension extension[0];
+};
+
+/**
+ * struct action_oui_search_attr - Used to check against action_oui ini input
+ *
+ * @ie_data: beacon ie data
+ * @ie_length: length of ie data
+ * @mac_addr: bssid of access point
+ * @nss: AP spatial stream info
+ * @ht_cap: Whether AP is HT capable
+ * @vht_cap: Whether AP is VHT capable
+ * @enable_2g: Whether 2.4GHz band is enabled in AP
+ * @enable_5g: Whether 5GHz band is enabled in AP
+ */
+struct action_oui_search_attr {
+	uint8_t *ie_data;
+	uint32_t ie_length;
+	uint8_t *mac_addr;
+	uint32_t nss;
+	bool ht_cap;
+	bool vht_cap;
+	bool enable_2g;
+	bool enable_5g;
+};
+
+#endif /* _WLAN_ACTION_OUI_PUBLIC_STRUCT_H_ */
diff --git a/components/action_oui/dispatcher/inc/wlan_action_oui_tgt_api.h b/components/action_oui/dispatcher/inc/wlan_action_oui_tgt_api.h
new file mode 100644
index 0000000..7a1d4f3
--- /dev/null
+++ b/components/action_oui/dispatcher/inc/wlan_action_oui_tgt_api.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018 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 action_oui to interact with target/WMI
+ */
+
+#ifndef _WLAN_ACTION_OUI_TGT_API_H_
+#define _WLAN_ACTION_OUI_TGT_API_H_
+
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_objmgr.h"
+
+#define GET_ACTION_OUI_TX_OPS_FROM_PSOC(psoc) \
+	(&action_oui_psoc_get_priv(psoc)->tx_ops)
+
+/**
+ * tgt_action_oui_send() - Send request to target if
+ * @psoc: objmgr psoc object
+ * @req: action_oui request to be send
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_action_oui_send(struct wlan_objmgr_psoc *psoc,
+				struct action_oui_request *req);
+
+/**
+ * struct action_oui_tx_ops - structure of tx operations
+ * @send_req: Pointer to hold target_if send function
+ */
+struct action_oui_tx_ops {
+	QDF_STATUS (*send_req)(struct wlan_objmgr_psoc *psoc,
+			       struct action_oui_request *req);
+};
+
+#endif /* _WLAN_ACTION_OUI_TGT_API_H_ */
diff --git a/components/action_oui/dispatcher/inc/wlan_action_oui_ucfg_api.h b/components/action_oui/dispatcher/inc/wlan_action_oui_ucfg_api.h
new file mode 100644
index 0000000..00daeb9
--- /dev/null
+++ b/components/action_oui/dispatcher/inc/wlan_action_oui_ucfg_api.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2012-2018 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 action_oui called by north bound
+ * HDD/OSIF/LIM
+ */
+
+#ifndef _WLAN_ACTION_OUI_UCFG_API_H_
+#define _WLAN_ACTION_OUI_UCFG_API_H_
+
+#include <qdf_status.h>
+#include <qdf_types.h>
+#include "wlan_action_oui_public_struct.h"
+#include "wlan_action_oui_objmgr.h"
+
+#ifdef WLAN_FEATURE_ACTION_OUI
+
+/**
+ * ucfg_action_oui_init() - Register notification handlers.
+ *
+ * This function registers action_oui notification handlers which are
+ * invoked from psoc create/destroy handlers.
+ *
+ * Return: For successful registration - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+QDF_STATUS ucfg_action_oui_init(void);
+
+/**
+ * ucfg_action_oui_deinit() - Unregister notification handlers.
+ *
+ * This function Unregisters action_oui notification handlers which are
+ * invoked from psoc create/destroy handlers.
+ *
+ * Return: None
+ */
+void ucfg_action_oui_deinit(void);
+
+/**
+ * ucfg_action_oui_parse() - Parse input string and extract extensions.
+ * @psoc: objmgr psoc object
+ * @in_str: input string to be parsed
+ * @action_id: action to which given string corresponds
+ *
+ * This is a wrapper function which invokes internal function
+ * action_oui_extract() to extract OUIs and related attributes.
+ *
+ * Return: For successful parse - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+QDF_STATUS
+ucfg_action_oui_parse(struct wlan_objmgr_psoc *psoc,
+		      const uint8_t *in_str,
+		      enum action_oui_id action_id);
+
+/**
+ * ucfg_action_oui_send() - Send action_oui and related attributes to Fw.
+ * @psoc: objmgr psoc object
+ *
+ * This is a wrapper function which invokes internal function
+ * action_oui_send() to send OUIs and related attributes to firmware.
+ *
+ * Return: For successful send - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+QDF_STATUS ucfg_action_oui_send(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_action_oui_enabled() - State of action_oui component
+ *
+ * Return: When action_oui component is present return true
+ *	   else return false.
+ */
+static inline bool ucfg_action_oui_enabled(void)
+{
+	return true;
+}
+
+/**
+ * ucfg_action_oui_search() - Check for OUIs and related info in IE data.
+ * @psoc: objmgr psoc object
+ * @attr: pointer to structure containing type of action, beacon IE data etc.,
+ * @action_id: type of action to be checked
+ *
+ * This is a wrapper function which invokes internal function to search
+ * for OUIs and related info (specified from ini file) in vendor specific
+ * data of beacon IE for given action.
+ *
+ * Return: If search is successful return true else false.
+ */
+bool ucfg_action_oui_search(struct wlan_objmgr_psoc *psoc,
+			    struct action_oui_search_attr *attr,
+			    enum action_oui_id action_id);
+
+#else
+
+/**
+ * ucfg_action_oui_init() - Register notification handlers.
+ *
+ * This function registers action_oui notification handlers which are
+ * invoked from psoc create/destroy handlers.
+ *
+ * Return: For successful registration - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+static inline
+QDF_STATUS ucfg_action_oui_init(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_action_oui_deinit() - Unregister notification handlers.
+ *
+ * This function Unregisters action_oui notification handlers which are
+ * invoked from psoc create/destroy handlers.
+ *
+ * Return: None
+ */
+static inline
+void ucfg_action_oui_deinit(void)
+{
+}
+
+/**
+ * ucfg_action_oui_parse() - Parse input string of action_id specified.
+ * @psoc: objmgr psoc object
+ * @in_str: input string to be parsed
+ * @action_id: action to which given string corresponds
+ *
+ * This is a wrapper function which invokes internal function
+ * action_oui_extract() to extract OUIs and related attributes.
+ *
+ * Return: For successful parse - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+static inline QDF_STATUS
+ucfg_action_oui_parse(struct wlan_objmgr_psoc *psoc,
+		      const uint8_t *in_str,
+		      enum action_oui_id action_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_action_oui_send() - Send action_oui and related attributes to Fw.
+ * @psoc: objmgr psoc object
+ *
+ * This is a wrapper function which invokes internal function
+ * action_oui_send() to send OUIs and related attributes to firmware.
+ *
+ * Return: For successful send - QDF_STATUS_SUCCESS,
+ *	   else QDF_STATUS error codes.
+ */
+static inline
+QDF_STATUS ucfg_action_oui_send(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_action_oui_enabled() - State of action_oui component
+ *
+ * Return: When action_oui component is present return true
+ *	   else return false.
+ */
+static inline bool ucfg_action_oui_enabled(void)
+{
+	return false;
+}
+
+/**
+ * ucfg_action_oui_search() - Check for OUIs and related info in IE data.
+ * @psoc: objmgr psoc object
+ * @attr: pointer to structure containing type of action, beacon IE data etc.,
+ * @action_id: type of action to be checked
+ *
+ * This is a wrapper function which invokes internal function to search
+ * for OUIs and related info (specified from ini file) in vendor specific
+ * data of beacon IE for given action.
+ *
+ * Return: If search is successful return true else false.
+ */
+static inline
+bool ucfg_action_oui_search(struct wlan_objmgr_psoc *psoc,
+			    struct action_oui_search_attr *attr,
+			    enum action_oui_id action_id)
+{
+	return false;
+}
+
+#endif /* WLAN_FEATURE_ACTION_OUI */
+
+#endif /* _WLAN_ACTION_OUI_UCFG_API_H_ */
diff --git a/components/action_oui/dispatcher/src/wlan_action_oui_tgt_api.c b/components/action_oui/dispatcher/src/wlan_action_oui_tgt_api.c
new file mode 100644
index 0000000..e3c2177
--- /dev/null
+++ b/components/action_oui/dispatcher/src/wlan_action_oui_tgt_api.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018 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 action_oui to interact with target/WMI
+ */
+
+#include "wlan_action_oui_tgt_api.h"
+#include "wlan_action_oui_main.h"
+#include "wlan_action_oui_public_struct.h"
+
+QDF_STATUS tgt_action_oui_send(struct wlan_objmgr_psoc *psoc,
+			       struct action_oui_request *req)
+{
+	struct action_oui_tx_ops *tx_ops;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	ACTION_OUI_ENTER();
+
+	tx_ops = GET_ACTION_OUI_TX_OPS_FROM_PSOC(psoc);
+	QDF_ASSERT(tx_ops->send_req);
+	if (tx_ops->send_req)
+		status = tx_ops->send_req(psoc, req);
+
+	ACTION_OUI_EXIT();
+
+	return status;
+}
diff --git a/components/action_oui/dispatcher/src/wlan_action_oui_ucfg_api.c b/components/action_oui/dispatcher/src/wlan_action_oui_ucfg_api.c
new file mode 100644
index 0000000..7a3e38b
--- /dev/null
+++ b/components/action_oui/dispatcher/src/wlan_action_oui_ucfg_api.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2012-2018 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 implementation of action_oui called by north bound HDD/OSIF.
+ */
+
+#include "wlan_action_oui_ucfg_api.h"
+#include "wlan_action_oui_main.h"
+#include "wlan_action_oui_main.h"
+#include "target_if_action_oui.h"
+#include "wlan_action_oui_tgt_api.h"
+#include <qdf_str.h>
+
+QDF_STATUS ucfg_action_oui_init(void)
+{
+	QDF_STATUS status;
+
+	ACTION_OUI_ENTER();
+
+	status = wlan_objmgr_register_psoc_create_handler(
+				WLAN_UMAC_COMP_ACTION_OUI,
+				action_oui_psoc_create_notification, NULL);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		action_oui_err("Failed to register psoc create handler");
+		goto exit;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+				WLAN_UMAC_COMP_ACTION_OUI,
+				action_oui_psoc_destroy_notification, NULL);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		action_oui_debug("psoc create/delete notifications registered");
+		goto exit;
+	}
+
+	action_oui_err("Failed to register psoc delete handler");
+	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_ACTION_OUI,
+			action_oui_psoc_create_notification, NULL);
+
+exit:
+	ACTION_OUI_EXIT();
+	return status;
+}
+
+void ucfg_action_oui_deinit(void)
+{
+	QDF_STATUS status;
+
+	ACTION_OUI_ENTER();
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+				WLAN_UMAC_COMP_ACTION_OUI,
+				action_oui_psoc_create_notification, NULL);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		action_oui_err("Failed to unregister psoc create handler");
+
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+				WLAN_UMAC_COMP_ACTION_OUI,
+				action_oui_psoc_destroy_notification,
+				NULL);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		action_oui_err("Failed to unregister psoc delete handler");
+
+	ACTION_OUI_EXIT();
+}
+
+QDF_STATUS
+ucfg_action_oui_parse(struct wlan_objmgr_psoc *psoc,
+		      const uint8_t *in_str,
+		      enum action_oui_id action_id)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint8_t *oui_str;
+	int len;
+
+	ACTION_OUI_ENTER();
+
+	if (!psoc) {
+		action_oui_err("psoc is NULL");
+		goto exit;
+	}
+
+	if (action_id >= ACTION_OUI_MAXIMUM_ID) {
+		action_oui_err("Invalid action_oui id: %u", action_id);
+		goto exit;
+	}
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	len = qdf_str_len(in_str);
+	if (len <= 0 || len > ACTION_OUI_MAX_STR_LEN - 1) {
+		action_oui_err("Invalid string length: %u", action_id);
+		goto exit;
+	}
+
+	oui_str = qdf_mem_malloc(len + 1);
+	if (!oui_str) {
+		action_oui_err("Mem alloc failed for string: %u", action_id);
+		status = QDF_STATUS_E_NOMEM;
+		goto exit;
+	}
+
+	qdf_mem_copy(oui_str, in_str, len);
+	oui_str[len] = '\0';
+
+	status = action_oui_parse(psoc_priv, oui_str, action_id);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		action_oui_err("Failed to parse: %u", action_id);
+
+	qdf_mem_free(oui_str);
+
+exit:
+	ACTION_OUI_EXIT();
+	return status;
+}
+
+QDF_STATUS ucfg_action_oui_send(struct wlan_objmgr_psoc *psoc)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint32_t id;
+
+	ACTION_OUI_ENTER();
+
+	if (!psoc) {
+		action_oui_err("psoc is NULL");
+		goto exit;
+	}
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
+		status = action_oui_send(psoc_priv, id);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			action_oui_err("Failed to send: %u", id);
+	}
+
+exit:
+	ACTION_OUI_EXIT();
+	return status;
+}
+
+bool ucfg_action_oui_search(struct wlan_objmgr_psoc *psoc,
+			    struct action_oui_search_attr *attr,
+			    enum action_oui_id action_id)
+{
+	struct action_oui_psoc_priv *psoc_priv;
+	bool found = false;
+
+	ACTION_OUI_ENTER();
+
+	if (!psoc || !attr) {
+		action_oui_err("Invalid psoc or search attrs");
+		goto exit;
+	}
+
+	if (action_id >= ACTION_OUI_MAXIMUM_ID ||
+	    !attr->ie_data || !attr->ie_length) {
+		action_oui_err("Invalid action_oui id: %u", action_id);
+		goto exit;
+	}
+
+	psoc_priv = action_oui_psoc_get_priv(psoc);
+	if (!psoc_priv) {
+		action_oui_err("psoc priv is NULL");
+		goto exit;
+	}
+
+	found = action_oui_search(psoc_priv, attr, action_id);
+	if (found)
+		action_oui_debug("Search Successful");
+
+exit:
+	ACTION_OUI_EXIT();
+	return found;
+}
diff --git a/components/cfg/cfg_all.h b/components/cfg/cfg_all.h
new file mode 100644
index 0000000..6b0ddfa
--- /dev/null
+++ b/components/cfg/cfg_all.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#include "wlan_policy_mgr_cfg.h"
+#include "cfg_define.h"
+#include "cfg_converged.h"
+#include "cfg_mlme.h"
+#include "cfg_fwol.h"
+#include "cfg_ipa.h"
+
+#ifdef CONVERGED_P2P_ENABLE
+#include "wlan_p2p_cfg.h"
+#else
+#define CFG_P2P_ALL
+#endif
+
+#ifdef CONVERGED_TDLS_ENABLE
+#include "wlan_tdls_cfg.h"
+#else
+#define CFG_TDLS_ALL
+#endif
+
+#ifdef WLAN_FEATURE_NAN_CONVERGENCE
+#include "cfg_nan.h"
+#else
+#define CFG_NAN_ALL
+#endif
+
+#include "wlan_pmo_cfg.h"
+#include "hdd_config.h"
+#include "hdd_dp_cfg.h"
+#include "cfg_legacy_dp.h"
+
+/* Maintain Alphabetic order here while adding components */
+#define CFG_ALL \
+	CFG_CONVERGED_ALL \
+	CFG_FWOL_ALL \
+	CFG_POLICY_MGR_ALL \
+	CFG_HDD_ALL \
+	CFG_HDD_DP_ALL \
+	CFG_IPA \
+	CFG_LEGACY_DP_ALL \
+	CFG_MLME_ALL \
+	CFG_NAN_ALL \
+	CFG_P2P_ALL \
+	CFG_PMO_ALL \
+	CFG_TDLS_ALL
diff --git a/components/disa/core/inc/wlan_disa_main.h b/components/disa/core/inc/wlan_disa_main.h
new file mode 100644
index 0000000..cefc300
--- /dev/null
+++ b/components/disa/core/inc/wlan_disa_main.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2018 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
+ * DISA user configuration and target interface
+ */
+
+#ifndef _WLAN_DISA_MAIN_H_
+#define _WLAN_DISA_MAIN_H_
+
+#include "wlan_disa_public_struct.h"
+#include "wlan_disa_obj_mgmt_public_struct.h"
+#include "wlan_disa_priv.h"
+#include "wlan_disa_objmgr.h"
+
+#define disa_fatal(params...) \
+	QDF_TRACE_FATAL(QDF_MODULE_ID_DISA, params)
+#define disa_err(params...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_DISA, params)
+#define disa_warn(params...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_DISA, params)
+#define disa_info(params...) \
+	QDF_TRACE_INFO(QDF_MODULE_ID_DISA, params)
+#define disa_debug(params...) \
+	QDF_TRACE_DEBUG(QDF_MODULE_ID_DISA, params)
+
+#define disa_nofl_fatal(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_DISA, params)
+#define disa_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_DISA, params)
+#define disa_nofl_warn(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_DISA, params)
+#define disa_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_DISA, params)
+#define disa_nofl_debug(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_DISA, params)
+
+#define DISA_ENTER() \
+	QDF_TRACE_ENTER(QDF_MODULE_ID_DISA, "enter")
+#define DISA_EXIT() \
+	QDF_TRACE_EXIT(QDF_MODULE_ID_DISA, "exit")
+
+/**
+ * disa_allocate_ctx() - Api to allocate disa ctx
+ *
+ * Helper function to allocate disa ctx
+ *
+ * Return: Success or failure.
+ */
+QDF_STATUS disa_allocate_ctx(void);
+
+/**
+ * disa_free_ctx() - to free disa context
+ *
+ * Helper function to free disa context
+ *
+ * Return: None.
+ */
+void disa_free_ctx(void);
+
+/**
+ * disa_get_context() - to get disa context
+ *
+ * Helper function to get disa context
+ *
+ * Return: disa context.
+ */
+struct wlan_disa_ctx *disa_get_context(void);
+
+/**
+ * disa_core_encrypt_decrypt_req() - Form encrypt/decrypt request
+ * @psoc: objmgr psoc object
+ * @req: DISA encrypt/decrypt request parameters
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS disa_core_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req,
+		encrypt_decrypt_resp_callback cb,
+		void *cookie);
+
+#endif /* end  of _WLAN_DISA_MAIN_H_ */
diff --git a/components/disa/core/inc/wlan_disa_objmgr.h b/components/disa/core/inc/wlan_disa_objmgr.h
new file mode 100644
index 0000000..6bb4977
--- /dev/null
+++ b/components/disa/core/inc/wlan_disa_objmgr.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2018 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_DISA_OBJMGR_H
+#define _WLAN_DISA_OBJMGR_H
+
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_disa_obj_mgmt_public_struct.h"
+
+/* Get/Put Ref */
+
+/**
+ * disa_psoc_get_ref() - DISA wrapper to increment ref count, if allowed
+ * @psoc: PSOC object
+ *
+ * DISA wrapper to increment ref count after checking valid object state
+ *
+ * Return: SUCCESS/FAILURE
+ */
+static inline QDF_STATUS disa_psoc_get_ref(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_try_get_ref(psoc, WLAN_DISA_ID);
+}
+
+/**
+ * disa_psoc_put_ref() - DISA wrapper to decrement ref count
+ * @psoc: PSOC object
+ *
+ * DISA wrapper to decrement ref count of psoc
+ *
+ * Return: SUCCESS/FAILURE
+ */
+static inline void disa_psoc_put_ref(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_release_ref(psoc, WLAN_DISA_ID);
+}
+
+/* Private Data */
+
+/**
+ * disa_psoc_get_priv_nolock(): DISA wrapper to retrieve component object
+ * @psoc: Psoc pointer
+ *
+ * DISA wrapper used to get the component private object pointer
+ *
+ * Return: Component private object
+ */
+static inline void *disa_psoc_get_priv_nolock(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_DISA);
+}
+
+/* Ids */
+static inline uint8_t
+disa_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 navigation 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 disa_[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 = disa_vdev_get_psoc(vdev);
+ *	if (!psoc)
+ *		// this is dead code
+ *
+ * Example #2:
+ *
+ *	psoc_priv = disa_psoc_get_priv(psoc);
+ *	if (!psoc_priv)
+ *		// this is dead code
+ *
+ * Example #3:
+ *
+ *	status = disa_psoc_get_ref(psoc);
+ *
+ *	...
+ *
+ *	psoc = disa_vdev_get_psoc(vdev);
+ *
+ *	// the next line is redundant, don't do it!
+ *	status = disa_psoc_get_ref(psoc);
+ */
+
+/* Tree Navigation: psoc */
+static inline struct disa_psoc_priv_obj *
+disa_psoc_get_priv(struct wlan_objmgr_psoc *psoc)
+{
+	struct disa_psoc_priv_obj *psoc_priv;
+
+	psoc_priv = disa_psoc_get_priv_nolock(psoc);
+	QDF_BUG(psoc_priv);
+
+	return psoc_priv;
+}
+
+static inline struct wlan_objmgr_vdev *
+disa_psoc_get_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS);
+	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS)
+		return NULL;
+
+	wlan_psoc_obj_lock(psoc);
+	vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
+	wlan_psoc_obj_unlock(psoc);
+
+	return vdev;
+}
+
+/* Tree Navigation: pdev */
+static inline struct wlan_objmgr_psoc *
+disa_pdev_get_psoc(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	QDF_BUG(psoc);
+
+	return psoc;
+}
+
+/* Tree Navigation: vdev */
+static inline struct wlan_objmgr_pdev *
+disa_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 *
+disa_vdev_get_psoc(struct wlan_objmgr_vdev *vdev)
+{
+	return disa_pdev_get_psoc(disa_vdev_get_pdev(vdev));
+}
+
+#endif /* _WLAN_DISA_OBJMGR_H */
diff --git a/components/disa/core/inc/wlan_disa_priv.h b/components/disa/core/inc/wlan_disa_priv.h
new file mode 100644
index 0000000..010d82f
--- /dev/null
+++ b/components/disa/core/inc/wlan_disa_priv.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018 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 privately in DISA
+  * component.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+#ifndef _WLAN_DISA_PRIV_STRUCT_H_
+#define _WLAN_DISA_PRIV_STRUCT_H_
+
+#include <qdf_lock.h>
+#include "wlan_disa_public_struct.h"
+
+/**
+ * struct disa_psoc_priv_obj -psoc specific user configuration required for disa
+ *
+ * @disa_rx_ops: rx operations for disa
+ * @disa_tx_ops: tx operations for disa
+ * @disa_psoc_lock: spin lock for disa psoc priv ctx
+ */
+struct disa_psoc_priv_obj {
+	struct wlan_disa_rx_ops disa_rx_ops;
+	struct wlan_disa_tx_ops disa_tx_ops;
+	qdf_spinlock_t lock;
+};
+
+/**
+ * struct wlan_disa_ctx - disa context for single command
+ *
+ * @callback: hdd callback for disa encrypt/decrypt resp
+ * @callback_context: context for the callback
+ * @lock: spin lock for disa context
+ */
+struct wlan_disa_ctx {
+	encrypt_decrypt_resp_callback callback;
+	void *callback_context;
+	bool request_active;
+	qdf_spinlock_t lock;
+};
+
+#endif /* end  of _WLAN_DISA_PRIV_STRUCT_H_ */
diff --git a/components/disa/core/src/wlan_disa_main.c b/components/disa/core/src/wlan_disa_main.c
new file mode 100644
index 0000000..7303394
--- /dev/null
+++ b/components/disa/core/src/wlan_disa_main.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2018 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 for
+ * DISA user and target interface.
+ */
+
+#include "wlan_disa_main.h"
+#include "wlan_disa_obj_mgmt_public_struct.h"
+#include "wlan_disa_tgt_api.h"
+
+static struct wlan_disa_ctx *gp_disa_ctx;
+
+QDF_STATUS disa_allocate_ctx(void)
+{
+	/* If it is already created, ignore */
+	if (gp_disa_ctx != NULL) {
+		disa_debug("already allocated disa_ctx");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* allocate DISA ctx */
+	gp_disa_ctx = qdf_mem_malloc(sizeof(*gp_disa_ctx));
+	if (!gp_disa_ctx) {
+		disa_err("unable to allocate disa_ctx");
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_NOMEM;
+	}
+	qdf_spinlock_create(&gp_disa_ctx->lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void disa_free_ctx(void)
+{
+	if (!gp_disa_ctx) {
+		disa_err("disa ctx is already freed");
+		QDF_ASSERT(0);
+		return;
+	}
+	qdf_spinlock_destroy(&gp_disa_ctx->lock);
+	qdf_mem_free(gp_disa_ctx);
+	gp_disa_ctx = NULL;
+}
+
+struct wlan_disa_ctx *disa_get_context(void)
+{
+	return gp_disa_ctx;
+}
+
+QDF_STATUS disa_core_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req,
+		encrypt_decrypt_resp_callback cb,
+		void *cookie)
+{
+	struct wlan_disa_ctx *disa_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	DISA_ENTER();
+	disa_ctx = disa_get_context();
+	if (!disa_ctx) {
+		disa_err("DISA context is NULL!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_spin_lock_bh(&disa_ctx->lock);
+	if (!disa_ctx->request_active) {
+		disa_ctx->callback = cb;
+		disa_ctx->callback_context = cookie;
+		disa_ctx->request_active = true;
+	} else {
+		status = QDF_STATUS_E_INVAL;
+	}
+	qdf_spin_unlock_bh(&disa_ctx->lock);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		disa_err("A request is already active!");
+		return status;
+	}
+
+	status = disa_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		disa_err("DISA cannot get the reference out of psoc");
+		return status;
+	}
+
+	status = tgt_disa_encrypt_decrypt_req(psoc, req);
+	disa_psoc_put_ref(psoc);
+
+	DISA_EXIT();
+	return status;
+}
diff --git a/components/disa/dispatcher/inc/wlan_disa_obj_mgmt_api.h b/components/disa/dispatcher/inc/wlan_disa_obj_mgmt_api.h
new file mode 100644
index 0000000..12a689a
--- /dev/null
+++ b/components/disa/dispatcher/inc/wlan_disa_obj_mgmt_api.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2018 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 disa component
+ * called by other components
+ */
+
+#ifndef _WLAN_DISA_OBJ_MGMT_API_H_
+#define _WLAN_DISA_OBJ_MGMT_API_H_
+
+#include <qdf_types.h>
+
+struct wlan_objmgr_psoc;
+
+/**
+ * disa_init() - register disa notification handlers.
+ *
+ * This function registers disa related notification handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+#ifdef WLAN_FEATURE_DISA
+QDF_STATUS disa_init(void);
+#else
+static inline QDF_STATUS disa_init(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * disa_deinit() - unregister disa notification handlers.
+ *
+ * This function unregisters disa related notification handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+#ifdef WLAN_FEATURE_DISA
+QDF_STATUS disa_deinit(void);
+#else
+static inline QDF_STATUS disa_deinit(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * disa_psoc_enable() - Trigger psoc enable for DISA
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+#ifdef WLAN_FEATURE_DISA
+QDF_STATUS disa_psoc_enable(struct wlan_objmgr_psoc *psoc);
+#else
+static inline QDF_STATUS disa_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * disa_psoc_disable() - Trigger psoc disable for DISA
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+#ifdef WLAN_FEATURE_DISA
+QDF_STATUS disa_psoc_disable(struct wlan_objmgr_psoc *psoc);
+#else
+static inline QDF_STATUS disa_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * disa_psoc_object_created_notification(): disa psoc create handler
+ * @psoc: psoc which is going to created by objmgr
+ * @arg: argument for psoc create handler
+ *
+ * Attach psoc private object, register rx/tx ops and event handlers
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS disa_psoc_object_created_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * disa_psoc_object_destroyed_notification(): disa psoc destroy handler
+ * @psoc: objmgr object corresponding to psoc which is going to be destroyed
+ * @arg: argument for psoc destroy handler
+ *
+ * Detach and free psoc private object, unregister event handlers
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS disa_psoc_object_destroyed_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg);
+
+#endif /* end  of _WLAN_DISA_OBJ_MGMT_API_H_ */
diff --git a/components/disa/dispatcher/inc/wlan_disa_obj_mgmt_public_struct.h b/components/disa/dispatcher/inc/wlan_disa_obj_mgmt_public_struct.h
new file mode 100644
index 0000000..76aae81
--- /dev/null
+++ b/components/disa/dispatcher/inc/wlan_disa_obj_mgmt_public_struct.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018 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 disa.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+#ifndef _WLAN_DISA_OBJ_MGMT_PUBLIC_STRUCT_H_
+#define _WLAN_DISA_OBJ_MGMT_PUBLIC_STRUCT_H_
+
+struct wlan_objmgr_psoc;
+struct disa_encrypt_decrypt_req_params;
+struct disa_encrypt_decrypt_resp_params;
+
+/**
+ * struct wlan_disa_tx_ops - structure of tx operation function
+ *	pointers for disa component
+ * @disa_encrypt_decrypt_req: send encrypt/decrypt request
+ * @disa_register_ev_handlers: register disa event handlers
+ * @disa_unregister_ev_handlers: unregister disa event handlers
+ */
+struct wlan_disa_tx_ops {
+	QDF_STATUS (*disa_encrypt_decrypt_req)(struct wlan_objmgr_psoc *psoc,
+			struct disa_encrypt_decrypt_req_params *req);
+	QDF_STATUS (*disa_register_ev_handlers)(struct wlan_objmgr_psoc *psoc);
+	QDF_STATUS (*disa_unregister_ev_handlers)
+			(struct wlan_objmgr_psoc *psoc);
+};
+
+/**
+ * struct wlan_disa_rx_ops - structure of rx operation function
+ *	pointers for disa component
+ * @encrypt_decrypt_msg_resp: send response of encrypt/decrypt request
+ */
+struct wlan_disa_rx_ops {
+	QDF_STATUS (*encrypt_decrypt_msg_resp)(struct wlan_objmgr_psoc *psoc,
+			struct disa_encrypt_decrypt_resp_params *resp);
+};
+#endif /* end  of _WLAN_DISA_OBJ_MGMT_PUBLIC_STRUCT_H_ */
diff --git a/components/disa/dispatcher/inc/wlan_disa_public_struct.h b/components/disa/dispatcher/inc/wlan_disa_public_struct.h
new file mode 100644
index 0000000..1c30f85
--- /dev/null
+++ b/components/disa/dispatcher/inc/wlan_disa_public_struct.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018 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 the DISA
+ * component.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+#ifndef _WLAN_DISA_PUBLIC_STRUCT_H_
+#define _WLAN_DISA_PUBLIC_STRUCT_H_
+
+#include <qdf_types.h>
+
+#define MAC_MAX_KEY_LENGTH 32
+#define MAC_PN_LENGTH 8
+#define MAX_MAC_HEADER_LEN 32
+#define MIN_MAC_HEADER_LEN 24
+
+/**
+ * struct disa_encrypt_decrypt_req_params - disa encrypt request
+ * @vdev_id: virtual device id
+ * @key_flag: This indicates firmware to encrypt/decrypt payload
+ *    see ENCRYPT_DECRYPT_FLAG
+ * @key_idx: Index used in storing key
+ * @key_cipher: cipher used for encryption/decryption
+ *    Eg: see WMI_CIPHER_AES_CCM for CCMP
+ * @key_len: length of key data
+ * @key_txmic_len: length of Tx MIC
+ * @key_rxmic_len: length of Rx MIC
+ * @key_data: Key
+ * @pn: packet number
+ * @mac_header: MAC header
+ * @data_len: length of data
+ * @data: pointer to payload
+ */
+struct disa_encrypt_decrypt_req_params {
+	uint32_t vdev_id;
+	uint8_t key_flag;
+	uint32_t key_idx;
+	uint32_t key_cipher;
+	uint32_t key_len;
+	uint32_t key_txmic_len;
+	uint32_t key_rxmic_len;
+	uint8_t key_data[MAC_MAX_KEY_LENGTH];
+	uint8_t pn[MAC_PN_LENGTH];
+	uint8_t mac_header[MAX_MAC_HEADER_LEN];
+	uint32_t data_len;
+	uint8_t *data;
+};
+
+/**
+ * struct disa_encrypt_decrypt_resp_params - disa encrypt response
+ * @vdev_id: vdev id
+ * @status: status
+ * @data_length: data length
+ * @data: data pointer
+ */
+struct disa_encrypt_decrypt_resp_params {
+	uint32_t vdev_id;
+	int32_t status;
+	uint32_t data_len;
+	uint8_t *data;
+};
+
+typedef void (*encrypt_decrypt_resp_callback)(void *cookie,
+	struct disa_encrypt_decrypt_resp_params *resp) ;
+#endif /* end  of _WLAN_DISA_PUBLIC_STRUCT_H_ */
+
diff --git a/components/disa/dispatcher/inc/wlan_disa_tgt_api.h b/components/disa/dispatcher/inc/wlan_disa_tgt_api.h
new file mode 100644
index 0000000..3988707
--- /dev/null
+++ b/components/disa/dispatcher/inc/wlan_disa_tgt_api.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018 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 disa to interact with target/WMI
+ */
+
+#ifndef _WLAN_DISA_TGT_API_H_
+#define _WLAN_DISA_TGT_API_H_
+
+#include <qdf_types.h>
+
+struct wlan_objmgr_psoc;
+struct disa_encrypt_decrypt_req_params;
+struct disa_encrypt_decrypt_resp_params;
+
+#define GET_DISA_TX_OPS_FROM_VDEV(vedv) \
+	(&disa_psoc_get_priv(psoc)->disa_tx_ops)
+
+/**
+ * tgt_disa_encrypt_decrypt_req() - send encrypt/decrypt request to target if
+ * @psoc: objmgr psoc object
+ * @req: encrypt/decrypt parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_disa_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req);
+
+/**
+ * tgt_disa_encrypt_decrypt_resp() - receive encrypt/decrypt response
+ *	from target if
+ * @psoc: objmgr psoc object
+ * @resp: encrypt/decrypt response containing results
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_disa_encrypt_decrypt_resp(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_resp_params *resp);
+
+/**
+ * tgt_disa_register_ev_handlers() - API to register disa event handlers
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS tgt_disa_register_ev_handlers(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * tgt_disa_unregister_ev_handlers() - API to unregister disa event handlers
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS tgt_disa_unregister_ev_handlers(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end  of _WLAN_DISA_TGT_API_H_ */
diff --git a/components/disa/dispatcher/inc/wlan_disa_ucfg_api.h b/components/disa/dispatcher/inc/wlan_disa_ucfg_api.h
new file mode 100644
index 0000000..b9c8206
--- /dev/null
+++ b/components/disa/dispatcher/inc/wlan_disa_ucfg_api.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018 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 disa called by north bound HDD/OSIF
+ */
+
+#ifndef _WLAN_DISA_UCFG_API_H_
+#define _WLAN_DISA_UCFG_API_H_
+
+#include "wlan_disa_public_struct.h"
+struct wlan_objmgr_psoc;
+struct disa_encrypt_decrypt_req_params;
+
+
+/**
+ * ucfg_disa_encrypt_decrypt_req() - Send encrypt/decrypt request to the DISA
+ * core
+ * @psoc: objmgr psoc object
+ * @req: DISA encrypt/decrypt request parameters
+ * @cb: Response callback for the encrypt/decrypt request
+ * @cookie: Cookie to pass to the response callback
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS ucfg_disa_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req,
+		encrypt_decrypt_resp_callback cb,
+		void *cookie);
+
+
+#endif /* end  of _WLAN_DISA_UCFG_API_H_ */
diff --git a/components/disa/dispatcher/src/wlan_disa_obj_mgmt_api.c b/components/disa/dispatcher/src/wlan_disa_obj_mgmt_api.c
new file mode 100644
index 0000000..7c6a1fe
--- /dev/null
+++ b/components/disa/dispatcher/src/wlan_disa_obj_mgmt_api.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2018 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 DISA component
+ * called by other components
+ */
+
+#include "wlan_disa_obj_mgmt_api.h"
+#include "wlan_disa_main.h"
+#include "target_if_disa.h"
+#include "wlan_disa_tgt_api.h"
+#include "wlan_objmgr_global_obj.h"
+
+/**
+ * disa_init() - register disa notification handlers.
+ *
+ * This function registers disa related notification handlers and
+ * allocates disa context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS disa_init(void)
+{
+	QDF_STATUS status;
+
+	DISA_ENTER();
+
+	if (disa_allocate_ctx() != QDF_STATUS_SUCCESS) {
+		disa_err("unable to allocate disa ctx");
+		status = QDF_STATUS_E_FAULT;
+		goto out;
+	}
+
+	status = wlan_objmgr_register_psoc_create_handler(
+			WLAN_UMAC_COMP_DISA,
+			disa_psoc_object_created_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		disa_err("unable to register psoc create handler");
+		goto err_free_ctx;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+			WLAN_UMAC_COMP_DISA,
+			disa_psoc_object_destroyed_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		disa_err("unable to register psoc destroy handler");
+		wlan_objmgr_unregister_psoc_create_handler(
+				WLAN_UMAC_COMP_DISA,
+				disa_psoc_object_created_notification,
+				NULL);
+	} else {
+		goto out;
+	}
+
+err_free_ctx:
+	disa_free_ctx();
+out:
+	DISA_EXIT();
+
+	return status;
+}
+
+/**
+ * disa_deinit() - unregister disa notification handlers.
+ *
+ * This function unregisters disa related notification handlers and
+ * frees disa context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS disa_deinit(void)
+{
+	QDF_STATUS status;
+
+	DISA_ENTER();
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+			WLAN_UMAC_COMP_DISA,
+			disa_psoc_object_destroyed_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		disa_err("unable to unregister psoc create handle");
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_DISA,
+			disa_psoc_object_created_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		disa_err("unable to unregister psoc create handle");
+
+	disa_free_ctx();
+	DISA_EXIT();
+
+	return status;
+}
+
+/**
+ * disa_psoc_object_created_notification(): disa psoc create handler
+ * @psoc: psoc which is going to created by objmgr
+ * @arg: argument for psoc create handler
+ *
+ * Attach psoc private object, register rx/tx ops and event handlers
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS disa_psoc_object_created_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct disa_psoc_priv_obj *disa_priv;
+	QDF_STATUS status;
+
+	DISA_ENTER();
+
+	disa_priv = qdf_mem_malloc(sizeof(*disa_priv));
+	if (disa_priv == NULL) {
+		disa_err("Failed to allocate disa_priv");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+			 WLAN_UMAC_COMP_DISA,
+			(void *)disa_priv, QDF_STATUS_SUCCESS);
+	if (status != QDF_STATUS_SUCCESS) {
+		disa_err("Failed to attach disa_priv with psoc");
+		qdf_mem_free(disa_priv);
+		goto out;
+	}
+
+	qdf_spinlock_create(&disa_priv->lock);
+	target_if_disa_register_tx_ops(&disa_priv->disa_tx_ops);
+
+out:
+	DISA_EXIT();
+
+	return status;
+}
+
+/**
+ * disa_psoc_object_destroyed_notification(): disa psoc destroy handler
+ * @psoc: objmgr object corresponding to psoc which is going to be destroyed
+ * @arg: argument for psoc destroy handler
+ *
+ * Detach and free psoc private object, unregister event handlers
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS disa_psoc_object_destroyed_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct disa_psoc_priv_obj *disa_priv = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	DISA_ENTER();
+
+	disa_priv = disa_psoc_get_priv(psoc);
+
+	status = wlan_objmgr_psoc_component_obj_detach(psoc,
+			 WLAN_UMAC_COMP_DISA,
+			(void *)disa_priv);
+
+	if (status != QDF_STATUS_SUCCESS)
+		disa_err("Failed to detach disa_priv with psoc");
+
+	qdf_spinlock_destroy(&disa_priv->lock);
+	qdf_mem_free(disa_priv);
+	DISA_EXIT();
+
+	return status;
+}
+
+/**
+ * disa_psoc_enable() - Trigger psoc enable for DISA
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS disa_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return tgt_disa_register_ev_handlers(psoc);
+}
+
+/**
+ * disa_psoc_disable() - Trigger psoc disable for DISA
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS disa_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return tgt_disa_unregister_ev_handlers(psoc);
+
+}
+
diff --git a/components/disa/dispatcher/src/wlan_disa_tgt_api.c b/components/disa/dispatcher/src/wlan_disa_tgt_api.c
new file mode 100644
index 0000000..5576ff1
--- /dev/null
+++ b/components/disa/dispatcher/src/wlan_disa_tgt_api.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2018 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 disa to interact with target/WMI
+ */
+
+#include "wlan_disa_tgt_api.h"
+#include "wlan_disa_main.h"
+#include "wlan_disa_public_struct.h"
+
+/**
+ * tgt_disa_encrypt_decrypt_req() - send encrypt/decrypt request to target if
+ * @psoc: objmgr psoc object
+ * @req: encrypt/decrypt parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_disa_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req)
+{
+	struct wlan_disa_tx_ops *disa_tx_ops;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	DISA_ENTER();
+
+	disa_tx_ops = GET_DISA_TX_OPS_FROM_VDEV(psoc);
+	QDF_ASSERT(disa_tx_ops->disa_encrypt_decrypt_req);
+
+	if (disa_tx_ops->disa_encrypt_decrypt_req)
+		status = disa_tx_ops->disa_encrypt_decrypt_req(psoc, req);
+
+	DISA_EXIT();
+	return status;
+}
+
+/**
+ * tgt_disa_encrypt_decrypt_resp() - receive encrypt/decrypt response
+ *	from target if
+ * @psoc: objmgr psoc object
+ * @resp: encrypt/decrypt response containing results
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_disa_encrypt_decrypt_resp(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_resp_params *resp)
+{
+	struct wlan_disa_ctx *disa_ctx;
+	encrypt_decrypt_resp_callback cb;
+	void *cookie;
+
+	DISA_ENTER();
+
+	if (!resp) {
+		disa_err("encrypt/decrypt resp is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	disa_ctx = disa_get_context();
+	if (!disa_ctx) {
+		disa_err("DISA context is NULL!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_spin_lock_bh(&disa_ctx->lock);
+	cb = disa_ctx->callback;
+	disa_ctx->callback = NULL;
+	cookie = disa_ctx->callback_context;
+	disa_ctx->callback_context = NULL;
+	disa_ctx->request_active = false;
+	qdf_spin_unlock_bh(&disa_ctx->lock);
+
+	if (cb)
+		cb(cookie, resp);
+
+	DISA_EXIT();
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * tgt_disa_register_ev_handlers() - API to register disa event handlers
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS tgt_disa_register_ev_handlers(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_disa_tx_ops *disa_tx_ops;
+
+	disa_tx_ops = GET_DISA_TX_OPS_FROM_VDEV(psoc);
+
+	QDF_ASSERT(disa_tx_ops->disa_register_ev_handlers);
+
+	if (disa_tx_ops->disa_register_ev_handlers)
+		return disa_tx_ops->disa_register_ev_handlers(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * tgt_disa_unregister_ev_handlers() - API to unregister disa event handlers
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS tgt_disa_unregister_ev_handlers(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_disa_tx_ops *disa_tx_ops;
+
+	disa_tx_ops = GET_DISA_TX_OPS_FROM_VDEV(psoc);
+
+	QDF_ASSERT(disa_tx_ops->disa_unregister_ev_handlers);
+
+	if (disa_tx_ops->disa_unregister_ev_handlers)
+		return disa_tx_ops->disa_unregister_ev_handlers(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
diff --git a/components/disa/dispatcher/src/wlan_disa_ucfg_api.c b/components/disa/dispatcher/src/wlan_disa_ucfg_api.c
new file mode 100644
index 0000000..e93c707
--- /dev/null
+++ b/components/disa/dispatcher/src/wlan_disa_ucfg_api.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 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 disa called by north bound HDD/OSIF
+ */
+
+#include "wlan_disa_ucfg_api.h"
+#include "wlan_disa_main.h"
+
+/**
+ * ucfg_disa_encrypt_decrypt_req() - Send encrypt/decrypt request to the DISA
+ * core
+ * @psoc: objmgr psoc object
+ * @req: DISA encrypt/decrypt request parameters
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS ucfg_disa_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req,
+		encrypt_decrypt_resp_callback cb,
+		void *cookie)
+{
+	return disa_core_encrypt_decrypt_req(psoc, req, cb, cookie);
+}
+
+
diff --git a/components/dsc/inc/wlan_dsc.h b/components/dsc/inc/wlan_dsc.h
new file mode 100644
index 0000000..49dd2dd
--- /dev/null
+++ b/components/dsc/inc/wlan_dsc.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018 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: Driver Synchronization Core (DSC) APIs for use by the driver
+ * orchestration layer.
+ *
+ * This infrastructure accomplishes two high level goals:
+ * 1) Replace ad-hoc locking/flags (hdd_init_deinit_lock,
+ *    iface_change_lock, con_mode_flag, etc., etc., etc.)
+ * 2) Make cds_ssr_protect() and driver state checking atomic
+ *
+ * These two goals are commplished in DSC via two corollary concepts:
+ * 1) Transitions (as in driver state machine transitions)
+ *    These are mutually exclusive, and replace ad-hoc locking
+ * 2) Operations (as in operations the driver is currently servicing)
+ *    These execute concurrently with other operations, and replace
+ *    cds_ssr_protect(). Any active transition causes new operations to be
+ *    rejected, in the same way as cds_ssr_protect/hdd_validate_context would.
+ *
+ * Transitions and operations are split into 3 distinct levels: driver, psoc,
+ * and vdev. These levels are arranged into a tree, with a single driver at
+ * the root, zero or more psocs per driver, and zero or more vdevs per psoc.
+ *
+ * High level transitions block transitions and operations at the same level
+ * down, and low level transitions block transitions at the same level up. So a
+ * driver transition effectively prevents any new activity in the system, while
+ * a vdev transition prevents transtitions on the same vdev, its parent psoc,
+ * and the driver. This also means that sibling nodes can transition at the same
+ * time, e.g. one vdev going up at the same time another is going down.
+ */
+
+#ifndef __WLAN_DSC_H
+#define __WLAN_DSC_H
+
+#include "wlan_dsc_driver.h"
+#include "wlan_dsc_psoc.h"
+#include "wlan_dsc_vdev.h"
+
+#endif /* __WLAN_DSC_H */
diff --git a/components/dsc/inc/wlan_dsc_driver.h b/components/dsc/inc/wlan_dsc_driver.h
new file mode 100644
index 0000000..88c73d4
--- /dev/null
+++ b/components/dsc/inc/wlan_dsc_driver.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2018 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: Driver Synchronization Core (DSC) driver-level APIs
+ */
+
+#ifndef __WLAN_DSC_DRIVER_H
+#define __WLAN_DSC_DRIVER_H
+
+#include "qdf_status.h"
+
+/**
+ * struct dsc_driver - opaque dsc driver context
+ */
+struct dsc_driver;
+
+/**
+ * dsc_driver_create() - create a dsc driver context
+ * @out_driver: opaque double pointer to assign the new context to
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS dsc_driver_create(struct dsc_driver **out_driver);
+
+/**
+ * dsc_driver_destroy() - destroy a dsc driver context
+ * @out_driver: opaque double pointer to context to destroy and NULL
+ *
+ * Note, this:
+ *	- aborts all queued transitions on @driver
+ *	- asserts @driver has no attached psoc's
+ *	- asserts @driver has no operations in flight
+ *
+ * Return: None
+ */
+void dsc_driver_destroy(struct dsc_driver **out_driver);
+
+/**
+ * dsc_driver_trans_start() - start a transition on @driver
+ * @driver: the driver to start a transition on
+ * @desc: a unique description of the transition to start
+ *
+ * This API immediately aborts if a transition on @driver is already in flight
+ *
+ * Call dsc_driver_trans_stop() to complete the transition.
+ *
+ * Return:
+ *	QDF_STATUS_SUCCESS - transition started succcessfully
+ *	QDF_STATUS_E_INVAL - invalid request (causes debug panic)
+ *	QDF_STATUS_E_AGAIN - transition cannot currently be started
+ *	QDF_STATUS_E_ALREADY - transition with @desc already in flight
+ */
+QDF_STATUS dsc_driver_trans_start(struct dsc_driver *driver, const char *desc);
+
+/**
+ * dsc_driver_trans_start_wait() - start a transition on @driver, blocking if a
+ *	transition is already in flight
+ * @driver: the driver to start a transition on
+ * @desc: a unique description of the transition to start
+ *
+ * Call dsc_driver_trans_stop() to complete the transition.
+ *
+ * Return:
+ *	QDF_STATUS_SUCCESS - transition started succcessfully
+ *	QDF_STATUS_E_INVAL - invalid request (causes debug panic)
+ *	QDF_STATUS_E_AGAIN - transition cannot currently be started
+ *	QDF_STATUS_E_ALREADY - transition with @desc already queued or in flight
+ */
+QDF_STATUS
+dsc_driver_trans_start_wait(struct dsc_driver *driver, const char *desc);
+
+/**
+ * dsc_driver_trans_stop() - complete current transition in flight on @driver
+ * @driver: the driver to complete the transition on
+ *
+ * Note: this asserts a transition is currently in flight on @driver
+ *
+ * Return: None
+ */
+void dsc_driver_trans_stop(struct dsc_driver *driver);
+
+/**
+ * dsc_driver_trans_assert() - assert transition in flight on @driver
+ * @driver: the driver to assert transition in flight on
+ *
+ * Return: None
+ */
+void dsc_driver_trans_assert(struct dsc_driver *driver);
+
+/**
+ * dsc_driver_op_start() - start an operation on @driver
+ * @driver: the driver to start an operation on
+ *
+ * Return:
+ *	QDF_STATUS_SUCCESS - operation started succcessfully
+ *	QDF_STATUS_E_INVAL - invalid request (causes debug panic)
+ *	QDF_STATUS_E_AGAIN - operation cannot currently be started
+ *	QDF_STATUS_E_NOMEM - out of memory
+ */
+#define dsc_driver_op_start(driver) _dsc_driver_op_start(driver, __func__)
+QDF_STATUS _dsc_driver_op_start(struct dsc_driver *driver, const char *func);
+
+/**
+ * dsc_driver_op_stop() - complete operation with matching @func on @driver
+ * @driver: the driver to stop an operation on
+ *
+ * Note: this asserts @func was previously started
+ *
+ * Return: None
+ */
+#define dsc_driver_op_stop(driver) _dsc_driver_op_stop(driver, __func__)
+void _dsc_driver_op_stop(struct dsc_driver *driver, const char *func);
+
+/**
+ * dsc_driver_wait_for_ops() - blocks until all operations on @driver have
+ *	stopped
+ * @driver: the driver to wait for operations on
+ *
+ * Note: this asserts that @driver cannot currently transition
+ *
+ * Return: None
+ */
+void dsc_driver_wait_for_ops(struct dsc_driver *driver);
+
+#endif /* __WLAN_DSC_DRIVER_H */
diff --git a/components/dsc/inc/wlan_dsc_psoc.h b/components/dsc/inc/wlan_dsc_psoc.h
new file mode 100644
index 0000000..050f5f6
--- /dev/null
+++ b/components/dsc/inc/wlan_dsc_psoc.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2018 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: Driver Synchronization Core (DSC) psoc-level APIs
+ */
+
+#ifndef __WLAN_DSC_PSOC_H
+#define __WLAN_DSC_PSOC_H
+
+#include "qdf_status.h"
+
+/**
+ * struct dsc_psoc - opaque dsc psoc context
+ */
+struct dsc_psoc;
+
+/**
+ * dsc_psoc_create() - create a dsc psoc context
+ * @driver: parent dsc driver context
+ * @out_psoc: opaque double pointer to assign the new context to
+ *
+ * Note: this attaches @out_psoc to @driver
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+dsc_psoc_create(struct dsc_driver *driver, struct dsc_psoc **out_psoc);
+
+/**
+ * dsc_psoc_destroy() - destroy a dsc psoc context
+ * @out_psoc: opaque double pointer to context to destroy and NULL
+ *
+ * Note, this:
+ *	- detaches @out_psoc from its parent driver context
+ *	- aborts all queued transitions on @psoc
+ *	- asserts @psoc has no attached vdev's
+ *	- asserts @psoc has no operations in flight
+ *
+ * Return: None
+ */
+void dsc_psoc_destroy(struct dsc_psoc **out_psoc);
+
+/**
+ * dsc_psoc_trans_start() - start a transition on @psoc
+ * @psoc: the psoc to start a transition on
+ * @desc: a unique description of the transition to start
+ *
+ * This API immediately aborts if a transition on @psoc is already in flight
+ *
+ * Call dsc_psoc_trans_stop() to complete the transition.
+ *
+ * Return:
+ *	QDF_STATUS_SUCCESS - transition started succcessfully
+ *	QDF_STATUS_E_INVAL - invalid request (causes debug panic)
+ *	QDF_STATUS_E_AGAIN - transition cannot currently be started
+ *	QDF_STATUS_E_ALREADY - transition with @desc already in flight
+ */
+QDF_STATUS dsc_psoc_trans_start(struct dsc_psoc *psoc, const char *desc);
+
+/**
+ * dsc_psoc_trans_start_wait() - start a transition on @psoc, blocking if a
+ *	transition is already in flight
+ * @psoc: the psoc to start a transition on
+ * @desc: a unique description of the transition to start
+ *
+ * Call dsc_psoc_trans_stop() to complete the transition.
+ *
+ * Return:
+ *	QDF_STATUS_SUCCESS - transition started succcessfully
+ *	QDF_STATUS_E_INVAL - invalid request (causes debug panic)
+ *	QDF_STATUS_E_AGAIN - transition cannot currently be started
+ *	QDF_STATUS_E_ALREADY - transition with @desc already queued or in flight
+ *	QDF_STATUS_E_ABORTED - transition was aborted
+ */
+QDF_STATUS dsc_psoc_trans_start_wait(struct dsc_psoc *psoc, const char *desc);
+
+/**
+ * dsc_psoc_trans_stop() - complete current transition in flight on @psoc
+ * @psoc: the psoc to complete the transition on
+ *
+ * Note: this asserts a transition is currently in flight on @psoc
+ *
+ * Return: None
+ */
+void dsc_psoc_trans_stop(struct dsc_psoc *psoc);
+
+/**
+ * dsc_psoc_trans_assert() - assert transition in flight on @psoc
+ * @psoc: the psoc to assert transition in flight on
+ *
+ * Return: None
+ */
+void dsc_psoc_trans_assert(struct dsc_psoc *psoc);
+
+/**
+ * dsc_psoc_op_start() - start an operation on @psoc
+ * @psoc: the psoc to start an operation on
+ *
+ * Return:
+ *	QDF_STATUS_SUCCESS - operation started succcessfully
+ *	QDF_STATUS_E_INVAL - invalid request (causes debug panic)
+ *	QDF_STATUS_E_AGAIN - operation cannot currently be started
+ *	QDF_STATUS_E_NOMEM - out of memory
+ */
+#define dsc_psoc_op_start(psoc) _dsc_psoc_op_start(psoc, __func__)
+QDF_STATUS _dsc_psoc_op_start(struct dsc_psoc *psoc, const char *func);
+
+/**
+ * dsc_psoc_op_stop() - complete operation with matching @func on @psoc
+ * @psoc: the psoc to stop an operation on
+ *
+ * Note: this asserts @func was previously started
+ *
+ * Return: None
+ */
+#define dsc_psoc_op_stop(psoc) _dsc_psoc_op_stop(psoc, __func__)
+void _dsc_psoc_op_stop(struct dsc_psoc *psoc, const char *func);
+
+/**
+ * dsc_psoc_wait_for_ops() - blocks until all operations on @psoc have stopped
+ * @psoc: the psoc to wait for operations on
+ *
+ * Note: this asserts that @psoc cannot currently transition
+ *
+ * Return: None
+ */
+void dsc_psoc_wait_for_ops(struct dsc_psoc *psoc);
+
+#endif /* __WLAN_DSC_PSOC_H */
diff --git a/components/dsc/inc/wlan_dsc_vdev.h b/components/dsc/inc/wlan_dsc_vdev.h
new file mode 100644
index 0000000..1271011
--- /dev/null
+++ b/components/dsc/inc/wlan_dsc_vdev.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2018 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: Driver Synchronization Core (DSC) vdev-level APIs
+ */
+
+#ifndef __WLAN_DSC_VDEV_H
+#define __WLAN_DSC_VDEV_H
+
+#include "qdf_status.h"
+
+/**
+ * struct dsc_vdev - opaque dsc vdev context
+ */
+struct dsc_vdev;
+
+/**
+ * dsc_vdev_create() - create a dsc vdev context
+ * @psoc: parent dsc psoc context
+ * @out_vdev: opaque double pointer to assign the new context to
+ *
+ * Note: this attaches @out_vdev to @psoc
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS dsc_vdev_create(struct dsc_psoc *psoc, struct dsc_vdev **out_vdev);
+
+/**
+ * dsc_vdev_destroy() - destroy a dsc vdev context
+ * @out_vdev: opaque double pointer to context to destroy and NULL
+ *
+ * Note, this:
+ *	- detaches @out_vdev from its parent psoc context
+ *	- aborts all queued transitions on @vdev
+ *	- asserts @vdev has no operations in flight
+ *
+ * Return: None
+ */
+void dsc_vdev_destroy(struct dsc_vdev **out_vdev);
+
+/**
+ * dsc_vdev_trans_start() - start a transition on @vdev
+ * @vdev: the vdev to start a transition on
+ * @desc: a unique description of the transition to start
+ *
+ * This API immediately aborts if a transition on @vdev is already in flight
+ *
+ * Call dsc_vdev_trans_stop() to complete the transition.
+ *
+ * Return:
+ *	QDF_STATUS_SUCCESS - transition started succcessfully
+ *	QDF_STATUS_E_INVAL - invalid request (causes debug panic)
+ *	QDF_STATUS_E_AGAIN - transition cannot currently be started
+ *	QDF_STATUS_E_ALREADY - transition with @desc already in flight
+ */
+QDF_STATUS dsc_vdev_trans_start(struct dsc_vdev *vdev, const char *desc);
+
+/**
+ * dsc_vdev_trans_start_wait() - start a transition on @vdev, blocking if a
+ *	transition is already in flight
+ * @vdev: the vdev to start a transition on
+ * @desc: a unique description of the transition to start
+ *
+ * Call dsc_vdev_trans_stop() to complete the transition.
+ *
+ * Return:
+ *	QDF_STATUS_SUCCESS - transition started succcessfully
+ *	QDF_STATUS_E_INVAL - invalid request (causes debug panic)
+ *	QDF_STATUS_E_AGAIN - transition cannot currently be started
+ *	QDF_STATUS_E_ALREADY - transition with @desc already queued or in flight
+ *	QDF_STATUS_E_ABORTED - transition was aborted
+ */
+QDF_STATUS dsc_vdev_trans_start_wait(struct dsc_vdev *vdev, const char *desc);
+
+/**
+ * dsc_vdev_trans_stop() - complete current transition in flight on @vdev
+ * @vdev: the vdev to complete the transition on
+ *
+ * Note: this asserts a transition is currently in flight on @vdev
+ *
+ * Return: None
+ */
+void dsc_vdev_trans_stop(struct dsc_vdev *vdev);
+
+/**
+ * dsc_vdev_trans_assert() - assert transition in flight on @vdev
+ * @vdev: the vdev to assert transition in flight on
+ *
+ * Return: None
+ */
+void dsc_vdev_trans_assert(struct dsc_vdev *vdev);
+
+/**
+ * dsc_vdev_op_start() - start an operation on @vdev
+ * @vdev: the vdev to start an operation on
+ *
+ * Return:
+ *	QDF_STATUS_SUCCESS - operation started succcessfully
+ *	QDF_STATUS_E_INVAL - invalid request (causes debug panic)
+ *	QDF_STATUS_E_AGAIN - operation cannot currently be started
+ *	QDF_STATUS_E_NOMEM - out of memory
+ */
+#define dsc_vdev_op_start(vdev) _dsc_vdev_op_start(vdev, __func__)
+QDF_STATUS _dsc_vdev_op_start(struct dsc_vdev *vdev, const char *func);
+
+/**
+ * dsc_vdev_op_stop() - complete operation with matching @func on @vdev
+ * @vdev: the vdev to stop an operation on
+ *
+ * Note: this asserts @func was previously started
+ *
+ * Return: None
+ */
+#define dsc_vdev_op_stop(vdev) _dsc_vdev_op_stop(vdev, __func__)
+void _dsc_vdev_op_stop(struct dsc_vdev *vdev, const char *func);
+
+/**
+ * dsc_vdev_wait_for_ops() - blocks until all operations on @vdev have stopped
+ * @vdev: the vdev to wait for operations on
+ *
+ * Note: this asserts that @vdev cannot currently transition
+ *
+ * Return: None
+ */
+void dsc_vdev_wait_for_ops(struct dsc_vdev *vdev);
+
+#endif /* __WLAN_DSC_VDEV_H */
diff --git a/components/dsc/src/__wlan_dsc.c b/components/dsc/src/__wlan_dsc.c
new file mode 100644
index 0000000..60032c2
--- /dev/null
+++ b/components/dsc/src/__wlan_dsc.c
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#include "qdf_list.h"
+#include "qdf_mem.h"
+#include "qdf_status.h"
+#include "qdf_str.h"
+#include "qdf_timer.h"
+#include "__wlan_dsc.h"
+
+#ifdef WLAN_DSC_DEBUG
+static void __dsc_dbg_op_timeout(void *opaque_op)
+{
+	struct dsc_op *op = opaque_op;
+
+	QDF_DEBUG_PANIC("Operation '%s' exceeded %ums",
+			op->func, DSC_OP_TIMEOUT_MS);
+}
+
+/**
+ * __dsc_dbg_ops_init() - initialize debug ops data structures
+ * @ops: the ops container to initialize
+ *
+ * Return: None
+ */
+static inline void __dsc_dbg_ops_init(struct dsc_ops *ops)
+{
+	qdf_list_create(&ops->list, 0);
+}
+
+/**
+ * __dsc_dbg_ops_deinit() - de-initialize debug ops data structures
+ * @ops: the ops container to de-initialize
+ *
+ * Return: None
+ */
+static inline void __dsc_dbg_ops_deinit(struct dsc_ops *ops)
+{
+	qdf_list_destroy(&ops->list);
+}
+
+/**
+ * __dsc_dbg_ops_insert() - insert @func into the debug information in @ops
+ * @ops: the ops container to insert into
+ * @func: the debug information to insert
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS __dsc_dbg_ops_insert(struct dsc_ops *ops, const char *func)
+{
+	QDF_STATUS status;
+	struct dsc_op *op;
+
+	op = qdf_mem_malloc(sizeof(*op));
+	if (!op)
+		return QDF_STATUS_E_NOMEM;
+
+	status = qdf_timer_init(NULL, &op->timeout_timer, __dsc_dbg_op_timeout,
+				op, QDF_TIMER_TYPE_SW);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto free_op;
+
+	op->func = func;
+
+	qdf_timer_start(&op->timeout_timer, DSC_OP_TIMEOUT_MS);
+	qdf_list_insert_back(&ops->list, &op->node);
+
+	return QDF_STATUS_SUCCESS;
+
+free_op:
+	qdf_mem_free(op);
+
+	return status;
+}
+
+/**
+ * __dsc_dbg_ops_remove() - remove @func from the debug information in @ops
+ * @ops: the ops container to remove from
+ * @func: the debug information to remove
+ *
+ * Return: None
+ */
+static void __dsc_dbg_ops_remove(struct dsc_ops *ops, const char *func)
+{
+	struct dsc_op *op;
+
+	/* Global pending op depth is usually <=3. Use linear search for now */
+	qdf_list_for_each(&ops->list, op, node) {
+		if (!qdf_str_eq(op->func, func))
+			continue;
+
+		/* this is safe because we cease iteration */
+		qdf_list_remove_node(&ops->list, &op->node);
+
+		qdf_timer_stop(&op->timeout_timer);
+		qdf_timer_free(&op->timeout_timer);
+		qdf_mem_free(op);
+
+		return;
+	}
+
+	QDF_DEBUG_PANIC("Driver op '%s' is not pending", func);
+}
+#else
+static inline void __dsc_dbg_ops_init(struct dsc_ops *ops) { }
+
+static inline void __dsc_dbg_ops_deinit(struct dsc_ops *ops) { }
+
+static inline QDF_STATUS
+__dsc_dbg_ops_insert(struct dsc_ops *ops, const char *func)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void
+__dsc_dbg_ops_remove(struct dsc_ops *ops, const char *func) { }
+#endif /* WLAN_DSC_DEBUG */
+
+void __dsc_ops_init(struct dsc_ops *ops)
+{
+	ops->count = 0;
+	qdf_event_create(&ops->event);
+	__dsc_dbg_ops_init(ops);
+}
+
+void __dsc_ops_deinit(struct dsc_ops *ops)
+{
+	/* assert no ops in flight */
+	dsc_assert(!ops->count);
+
+	__dsc_dbg_ops_deinit(ops);
+	qdf_event_destroy(&ops->event);
+}
+
+QDF_STATUS __dsc_ops_insert(struct dsc_ops *ops, const char *func)
+{
+	QDF_STATUS status;
+
+	status = __dsc_dbg_ops_insert(ops, func);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	ops->count++;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool __dsc_ops_remove(struct dsc_ops *ops, const char *func)
+{
+	dsc_assert(ops->count);
+	ops->count--;
+
+	__dsc_dbg_ops_remove(ops, func);
+
+	return ops->count == 0;
+}
+
+#ifdef WLAN_DSC_DEBUG
+static void __dsc_dbg_trans_timeout(void *opaque_trans)
+{
+	struct dsc_trans *trans = opaque_trans;
+
+	QDF_DEBUG_PANIC("Transition '%s' exceeded %ums",
+			trans->active_desc, DSC_TRANS_TIMEOUT_MS);
+}
+
+/**
+ * __dsc_dbg_trans_timeout_start() - start a timeout timer for @trans
+ * @trans: the active transition to start a timeout timer for
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS __dsc_dbg_trans_timeout_start(struct dsc_trans *trans)
+{
+	QDF_STATUS status;
+
+	status = qdf_timer_init(NULL, &trans->timeout_timer,
+				__dsc_dbg_trans_timeout, trans,
+				QDF_TIMER_TYPE_SW);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	qdf_timer_start(&trans->timeout_timer, DSC_TRANS_TIMEOUT_MS);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * __dsc_dbg_trans_timeout_stop() - stop the timeout timer for @trans
+ * @trans: the active transition to stop the timeout timer for
+ *
+ * Return: None
+ */
+static void __dsc_dbg_trans_timeout_stop(struct dsc_trans *trans)
+{
+	qdf_timer_stop(&trans->timeout_timer);
+	qdf_timer_free(&trans->timeout_timer);
+}
+
+static void __dsc_dbg_tran_wait_timeout(void *opaque_tran)
+{
+	struct dsc_tran *tran = opaque_tran;
+
+	QDF_DEBUG_PANIC("Transition '%s' waited more than %ums",
+			tran->desc, DSC_TRANS_WAIT_TIMEOUT_MS);
+}
+
+/**
+ * __dsc_dbg_tran_wait_timeout_start() - start a timeout timer for @tran
+ * @tran: the pending transition to start a timeout timer for
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS __dsc_dbg_tran_wait_timeout_start(struct dsc_tran *tran)
+{
+	QDF_STATUS status;
+
+	status = qdf_timer_init(NULL, &tran->timeout_timer,
+				__dsc_dbg_tran_wait_timeout, tran,
+				QDF_TIMER_TYPE_SW);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	qdf_timer_start(&tran->timeout_timer, DSC_TRANS_WAIT_TIMEOUT_MS);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * __dsc_dbg_tran_wait_timeout_stop() - stop the timeout timer for @tran
+ * @tran: the pending transition to stop the timeout timer for
+ *
+ * Return: None
+ */
+static void __dsc_dbg_tran_wait_timeout_stop(struct dsc_tran *tran)
+{
+	qdf_timer_stop(&tran->timeout_timer);
+	qdf_timer_free(&tran->timeout_timer);
+}
+#else
+static inline QDF_STATUS __dsc_dbg_trans_timeout_start(struct dsc_trans *trans)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void __dsc_dbg_trans_timeout_stop(struct dsc_trans *trans) { }
+
+static inline QDF_STATUS
+__dsc_dbg_tran_wait_timeout_start(struct dsc_tran *tran)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void __dsc_dbg_tran_wait_timeout_stop(struct dsc_tran *tran) { }
+#endif /* WLAN_DSC_DEBUG */
+
+void __dsc_trans_init(struct dsc_trans *trans)
+{
+	trans->active_desc = NULL;
+	qdf_list_create(&trans->queue, 0);
+}
+
+void __dsc_trans_deinit(struct dsc_trans *trans)
+{
+	qdf_list_destroy(&trans->queue);
+	trans->active_desc = NULL;
+}
+
+QDF_STATUS __dsc_trans_start(struct dsc_trans *trans, const char *desc)
+{
+	QDF_STATUS status;
+
+	status = __dsc_dbg_trans_timeout_start(trans);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	dsc_assert(!trans->active_desc);
+	trans->active_desc = desc;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void __dsc_trans_stop(struct dsc_trans *trans)
+{
+	dsc_assert(trans->active_desc);
+	trans->active_desc = NULL;
+	__dsc_dbg_trans_timeout_stop(trans);
+}
+
+QDF_STATUS __dsc_trans_queue(struct dsc_trans *trans, struct dsc_tran *tran,
+			     const char *desc)
+{
+	QDF_STATUS status;
+
+	tran->abort = false;
+	tran->desc = desc;
+	qdf_event_create(&tran->event);
+
+	status = __dsc_dbg_tran_wait_timeout_start(tran);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto event_destroy;
+
+	qdf_list_insert_back(&trans->queue, &tran->node);
+
+	return QDF_STATUS_SUCCESS;
+
+event_destroy:
+	qdf_event_destroy(&tran->event);
+
+	return status;
+}
+
+/**
+ * __dsc_trans_dequeue() - dequeue the next queued transition from @trans
+ * @trans: the transactions container to dequeue from
+ *
+ * Return: the dequeued transition, or NULL if @trans is empty
+ */
+static struct dsc_tran *__dsc_trans_dequeue(struct dsc_trans *trans)
+{
+	QDF_STATUS status;
+	qdf_list_node_t *node;
+	struct dsc_tran *tran;
+
+	status = qdf_list_remove_front(&trans->queue, &node);
+	if (QDF_IS_STATUS_ERROR(status))
+		return NULL;
+
+	tran = qdf_container_of(node, struct dsc_tran, node);
+	__dsc_dbg_tran_wait_timeout_stop(tran);
+
+	return tran;
+}
+
+bool __dsc_trans_abort(struct dsc_trans *trans)
+{
+	struct dsc_tran *tran;
+
+	tran = __dsc_trans_dequeue(trans);
+	if (!tran)
+		return false;
+
+	tran->abort = true;
+	qdf_event_set(&tran->event);
+
+	return true;
+}
+
+bool __dsc_trans_trigger(struct dsc_trans *trans)
+{
+	struct dsc_tran *tran;
+
+	tran = __dsc_trans_dequeue(trans);
+	if (!tran)
+		return false;
+
+	__dsc_trans_start(trans, tran->desc);
+	qdf_event_set(&tran->event);
+
+	return true;
+}
+
+bool __dsc_trans_active(struct dsc_trans *trans)
+{
+	return !!trans->active_desc;
+}
+
+bool __dsc_trans_queued(struct dsc_trans *trans)
+{
+	return !qdf_list_empty(&trans->queue);
+}
+
+bool __dsc_trans_active_or_queued(struct dsc_trans *trans)
+{
+	return __dsc_trans_active(trans) || __dsc_trans_queued(trans);
+}
+
+QDF_STATUS __dsc_tran_wait(struct dsc_tran *tran)
+{
+	QDF_STATUS status;
+
+	status = qdf_wait_single_event(&tran->event, 0);
+	qdf_event_destroy(&tran->event);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	if (tran->abort)
+		return QDF_STATUS_E_ABORTED;
+
+	return QDF_STATUS_SUCCESS;
+}
+
diff --git a/components/dsc/src/__wlan_dsc.h b/components/dsc/src/__wlan_dsc.h
new file mode 100644
index 0000000..721dbcd
--- /dev/null
+++ b/components/dsc/src/__wlan_dsc.h
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2018 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: Driver State Management (DSC) APIs for *internal* use
+ */
+
+#ifndef ____WLAN_DSC_H
+#define ____WLAN_DSC_H
+
+#include "qdf_event.h"
+#include "qdf_list.h"
+#include "qdf_trace.h"
+#include "qdf_timer.h"
+#include "qdf_types.h"
+#include "wlan_dsc.h"
+
+#define dsc_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, params)
+#define dsc_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_QDF, params)
+#define dsc_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_QDF, params)
+
+#define dsc_enter_exit dsc_debug
+#define dsc_enter() dsc_enter_exit("enter")
+#define dsc_enter_str(str) dsc_enter_exit("enter(\"%s\")", str)
+#define dsc_exit() dsc_enter_exit("exit")
+#define dsc_exit_status(status) dsc_enter_exit("exit(status:%u)", status)
+
+static inline bool __dsc_assert(const bool cond, const char *cond_str,
+				const char *func, const uint32_t line)
+{
+	if (cond)
+		return true;
+
+	QDF_DEBUG_PANIC_FL(func, line, "Failed assertion '%s'!", cond_str);
+
+	return false;
+}
+
+#define dsc_assert(cond) __dsc_assert(cond, #cond, __func__, __LINE__)
+#define dsc_assert_success(status) dsc_assert(QDF_IS_STATUS_SUCCESS(status))
+
+#ifdef WLAN_DSC_DEBUG
+#define DSC_OP_TIMEOUT_MS		(1 * 60 * 1000) /* 1 minute */
+#define DSC_TRANS_TIMEOUT_MS		(1 * 60 * 1000) /* 1 minute */
+#define DSC_TRANS_WAIT_TIMEOUT_MS	(2 * 60 * 1000) /* 2 minutes */
+
+/**
+ * struct dsc_op - list node for operation tracking information
+ * @node: list node
+ * @timeout_timer: a timer used to detect operation timeouts
+ * @func: name of the function the operation was started from
+ */
+struct dsc_op {
+	qdf_list_node_t node;
+	qdf_timer_t timeout_timer;
+	const char *func;
+};
+#endif /* WLAN_DSC_DEBUG */
+
+/**
+ * struct dsc_ops - operations in flight tracking container
+ * @list: list for tracking debug information
+ * @count: count of current operations in flight
+ * @event: event used to wait in *_wait_for_ops() APIs
+ */
+struct dsc_ops {
+#ifdef WLAN_DSC_DEBUG
+	qdf_list_t list;
+#endif
+	uint32_t count;
+	qdf_event_t event;
+};
+
+/**
+ * struct dsc_tran - representation of a pending transition
+ * @abort: used to indicate if the transition stopped waiting due to an abort
+ * @desc: unique description of the transition
+ * @node: list node
+ * @event: event used to wait in *_start_trans_wait() APIs
+ * @timeout_timer: a timer used to detect transition wait timeouts
+ */
+struct dsc_tran {
+	bool abort;
+	const char *desc;
+	qdf_list_node_t node;
+	qdf_event_t event;
+#ifdef WLAN_DSC_DEBUG
+	qdf_timer_t timeout_timer;
+#endif
+};
+
+/**
+ * struct dsc_trans - transition information container
+ * @active_desc: unique description of the current transition in progress
+ * @queue: queue of pending transitions
+ * @timeout_timer: a timer used to detect transition timeouts
+ */
+struct dsc_trans {
+	const char *active_desc;
+	qdf_list_t queue;
+#ifdef WLAN_DSC_DEBUG
+	qdf_timer_t timeout_timer;
+#endif
+};
+
+/**
+ * struct dsc_driver - concrete dsc driver context
+ * @lock: lock under which all dsc APIs execute
+ * @psocs: list of children psoc contexts
+ * @trans: transition tracking container for this node
+ * @ops: operations in flight tracking container for this node
+ */
+struct dsc_driver {
+	struct qdf_spinlock lock;
+	qdf_list_t psocs;
+	struct dsc_trans trans;
+	struct dsc_ops ops;
+};
+
+/**
+ * struct dsc_psoc - concrete dsc psoc context
+ * @node: list node for membership in @driver->psocs
+ * @driver: parent driver context
+ * @vdevs: list of children vdevs contexts
+ * @trans: transition tracking container for this node
+ * @ops: operations in flight tracking container for this node
+ */
+struct dsc_psoc {
+	qdf_list_node_t node;
+	struct dsc_driver *driver;
+	qdf_list_t vdevs;
+	struct dsc_trans trans;
+	struct dsc_ops ops;
+};
+
+/**
+ * struct dsc_vdev - concrete dsc vdev context
+ * @node: list node for membership in @psoc->vdevs
+ * @psoc: parent psoc context
+ * @trans: transition tracking container for this node
+ * @ops: operations in flight tracking container for this node
+ */
+struct dsc_vdev {
+	qdf_list_node_t node;
+	struct dsc_psoc *psoc;
+	struct dsc_trans trans;
+	struct dsc_ops ops;
+};
+
+#define dsc_for_each_driver_psoc(driver_ptr, psoc_cursor) \
+	qdf_list_for_each(&(driver_ptr)->psocs, psoc_cursor, node)
+
+#define dsc_for_each_psoc_vdev(psoc_ptr, vdev_cursor) \
+	qdf_list_for_each(&(psoc_ptr)->vdevs, vdev_cursor, node)
+
+/**
+ * __dsc_lock() - grab the dsc driver lock
+ * @driver: the driver to lock
+ *
+ * Return: None
+ */
+void __dsc_lock(struct dsc_driver *driver);
+
+/**
+ * __dsc_unlock() - release the dsc driver lock
+ * @driver: the driver to unlock
+ *
+ * Return: None
+ */
+void __dsc_unlock(struct dsc_driver *driver);
+
+/**
+ * __dsc_ops_init() - initialize @ops
+ * @ops: the ops container to initialize
+ *
+ * Return: None
+ */
+void __dsc_ops_init(struct dsc_ops *ops);
+
+/**
+ * __dsc_ops_deinit() - de-initialize @ops
+ * @ops: the ops container to de-initialize
+ *
+ * Return: None
+ */
+void __dsc_ops_deinit(struct dsc_ops *ops);
+
+/**
+ * __dsc_ops_insert() - insert @func into the trakcing information in @ops
+ * @ops: the ops container to insert into
+ * @func: the debug information to insert
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS __dsc_ops_insert(struct dsc_ops *ops, const char *func);
+
+/**
+ * __dsc_ops_remove() - remove @func from the tracking information in @ops
+ * @ops: the ops container to remove from
+ * @func: the debug information to remove
+ *
+ * Return: None
+ */
+bool __dsc_ops_remove(struct dsc_ops *ops, const char *func);
+
+/**
+ * __dsc_trans_init() - initialize @trans
+ * @trans: the trans container to initialize
+ *
+ * Return: None
+ */
+void __dsc_trans_init(struct dsc_trans *trans);
+
+/**
+ * __dsc_trans_deinit() - de-initialize @trans
+ * @trans: the trans container to de-initialize
+ *
+ * Return: None
+ */
+void __dsc_trans_deinit(struct dsc_trans *trans);
+
+/**
+ * __dsc_trans_start() - set the active transition on @trans
+ * @trans: the transition container used to track the new active transition
+ * @desc: unique description of the transition being started
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS __dsc_trans_start(struct dsc_trans *trans, const char *desc);
+
+/**
+ * __dsc_trans_stop() - unset the active transition on @trans
+ * @trans: the transition container currently tracking the active transition
+ *
+ * Return: None
+ */
+void __dsc_trans_stop(struct dsc_trans *trans);
+
+/**
+ * __dsc_trans_queue() - queue @tran at the back of @trans
+ * @trans: the transitions container to enqueue to
+ * @tran: the transition to enqueue
+ * @desc: unique description of the transition being queued
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS __dsc_trans_queue(struct dsc_trans *trans, struct dsc_tran *tran,
+			     const char *desc);
+
+/**
+ * __dsc_tran_wait() - block until @tran completes
+ * @tran: the transition to wait on
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS __dsc_tran_wait(struct dsc_tran *tran);
+
+/**
+ * __dsc_trans_abort() - abort the next queued transition from @trans
+ * @trans: the transitions container to abort from
+ *
+ * Return: true if a transition was aborted, false if @trans is empty
+ */
+bool __dsc_trans_abort(struct dsc_trans *trans);
+
+/**
+ * __dsc_trans_trigger() - trigger the next queued trans in @trans
+ * @trans: the transitions container to trigger from
+ *
+ * Return: true if a transition was triggered
+ */
+bool __dsc_trans_trigger(struct dsc_trans *trans);
+
+/**
+ * __dsc_trans_active() - check if a transition is active in @trans
+ * @trans: the transitions container to check
+ *
+ * Return: true if @trans has an active transition
+ */
+bool __dsc_trans_active(struct dsc_trans *trans);
+
+/**
+ * __dsc_trans_queued() - check if a transition is queued in @trans
+ * @trans: the transitions container to check
+ *
+ * Return: true if @trans has a queued transition
+ */
+bool __dsc_trans_queued(struct dsc_trans *trans);
+
+/**
+ * __dsc_trans_active_or_queued() - check if a transition is active or queued
+ *	in @trans
+ * @trans: the transitions container to check
+ *
+ * Return: true if @trans has an active or queued transition
+ */
+bool __dsc_trans_active_or_queued(struct dsc_trans *trans);
+
+/**
+ * __dsc_driver_trans_trigger_checked() - trigger any next pending driver
+ *	transition, only after passing the "can trans" check
+ *
+ * Return: true if the trigger was "handled." This indicates down-tree nodes
+ * should _not_ attempt to trigger a new transition.
+ */
+bool __dsc_driver_trans_trigger_checked(struct dsc_driver *driver);
+
+/**
+ * __dsc_psoc_trans_trigger_checked() - trigger any next pending psoc
+ *	transition, only after passing the "can trans" check
+ *
+ * Return: true if the trigger was "handled." This indicates down-tree nodes
+ * should _not_ attempt to trigger a new transition.
+ */
+bool __dsc_psoc_trans_trigger_checked(struct dsc_psoc *psoc);
+
+#endif /* ____WLAN_DSC_H */
diff --git a/components/dsc/src/wlan_dsc_driver.c b/components/dsc/src/wlan_dsc_driver.c
new file mode 100644
index 0000000..6f5d187
--- /dev/null
+++ b/components/dsc/src/wlan_dsc_driver.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#include "qdf_list.h"
+#include "qdf_status.h"
+#include "qdf_types.h"
+#include "__wlan_dsc.h"
+#include "wlan_dsc.h"
+
+void __dsc_lock(struct dsc_driver *driver)
+{
+	dsc_assert(driver);
+	qdf_spin_lock_bh(&driver->lock);
+}
+
+void __dsc_unlock(struct dsc_driver *driver)
+{
+	dsc_assert(driver);
+	qdf_spin_unlock_bh(&driver->lock);
+}
+
+static QDF_STATUS __dsc_driver_create(struct dsc_driver **out_driver)
+{
+	struct dsc_driver *driver;
+
+	if (!dsc_assert(out_driver))
+		return QDF_STATUS_E_INVAL;
+
+	*out_driver = NULL;
+
+	driver = qdf_mem_malloc(sizeof(*driver));
+	if (!driver)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_spinlock_create(&driver->lock);
+	qdf_list_create(&driver->psocs, 0);
+	__dsc_trans_init(&driver->trans);
+	__dsc_ops_init(&driver->ops);
+
+	*out_driver = driver;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS dsc_driver_create(struct dsc_driver **out_driver)
+{
+	QDF_STATUS status;
+
+	dsc_enter();
+	status = __dsc_driver_create(out_driver);
+	dsc_exit();
+
+	return status;
+}
+
+static void __dsc_driver_destroy(struct dsc_driver **out_driver)
+{
+	struct dsc_driver *driver;
+
+	if (!dsc_assert(out_driver))
+		return;
+
+	driver = *out_driver;
+	if (!dsc_assert(driver))
+		return;
+
+	*out_driver = NULL;
+
+	/* assert no children */
+	dsc_assert(qdf_list_empty(&driver->psocs));
+
+	/* flush pending transitions */
+	while (__dsc_trans_abort(&driver->trans))
+		;
+
+	/* de-init */
+	__dsc_ops_deinit(&driver->ops);
+	__dsc_trans_deinit(&driver->trans);
+	qdf_list_destroy(&driver->psocs);
+	qdf_spinlock_destroy(&driver->lock);
+
+	qdf_mem_free(driver);
+}
+
+void dsc_driver_destroy(struct dsc_driver **out_driver)
+{
+	dsc_enter();
+	__dsc_driver_destroy(out_driver);
+	dsc_exit();
+}
+
+static bool __dsc_driver_trans_active_down_tree(struct dsc_driver *driver)
+{
+	struct dsc_psoc *psoc;
+	struct dsc_vdev *vdev;
+
+	dsc_for_each_driver_psoc(driver, psoc) {
+		if (__dsc_trans_active(&psoc->trans))
+			return true;
+
+		dsc_for_each_psoc_vdev(psoc, vdev) {
+			if (__dsc_trans_active(&vdev->trans))
+				return true;
+		}
+	}
+
+	return false;
+}
+
+static bool __dsc_driver_can_op(struct dsc_driver *driver)
+{
+	return !__dsc_trans_active_or_queued(&driver->trans);
+}
+
+static bool __dsc_driver_can_trans(struct dsc_driver *driver)
+{
+	return !__dsc_trans_active_or_queued(&driver->trans) &&
+		!__dsc_driver_trans_active_down_tree(driver);
+}
+
+static bool __dsc_driver_can_trigger(struct dsc_driver *driver)
+{
+	return !__dsc_trans_active(&driver->trans) &&
+		!__dsc_driver_trans_active_down_tree(driver);
+}
+
+static QDF_STATUS
+__dsc_driver_trans_start_nolock(struct dsc_driver *driver, const char *desc)
+{
+	if (!__dsc_driver_can_trans(driver))
+		return QDF_STATUS_E_AGAIN;
+
+	return __dsc_trans_start(&driver->trans, desc);
+}
+
+static QDF_STATUS
+__dsc_driver_trans_start(struct dsc_driver *driver, const char *desc)
+{
+	QDF_STATUS status;
+
+	if (!dsc_assert(driver))
+		return QDF_STATUS_E_INVAL;
+
+	if (!dsc_assert(desc))
+		return QDF_STATUS_E_INVAL;
+
+	__dsc_lock(driver);
+	status = __dsc_driver_trans_start_nolock(driver, desc);
+	__dsc_unlock(driver);
+
+	return status;
+}
+
+QDF_STATUS dsc_driver_trans_start(struct dsc_driver *driver, const char *desc)
+{
+	QDF_STATUS status;
+
+	dsc_enter_str(desc);
+	status = __dsc_driver_trans_start(driver, desc);
+	dsc_exit_status(status);
+
+	return status;
+}
+
+static QDF_STATUS
+__dsc_driver_trans_start_wait(struct dsc_driver *driver, const char *desc)
+{
+	QDF_STATUS status;
+	struct dsc_tran tran = { 0 };
+
+	if (!dsc_assert(driver))
+		return QDF_STATUS_E_INVAL;
+
+	if (!dsc_assert(desc))
+		return QDF_STATUS_E_INVAL;
+
+	__dsc_lock(driver);
+
+	/* try to start without waiting */
+	status = __dsc_driver_trans_start_nolock(driver, desc);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		goto unlock;
+
+	status = __dsc_trans_queue(&driver->trans, &tran, desc);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto unlock;
+
+	__dsc_unlock(driver);
+
+	return __dsc_tran_wait(&tran);
+
+unlock:
+	__dsc_unlock(driver);
+
+	return status;
+}
+
+QDF_STATUS
+dsc_driver_trans_start_wait(struct dsc_driver *driver, const char *desc)
+{
+	QDF_STATUS status;
+
+	dsc_enter_str(desc);
+	status = __dsc_driver_trans_start_wait(driver, desc);
+	dsc_exit_status(status);
+
+	return status;
+}
+
+bool __dsc_driver_trans_trigger_checked(struct dsc_driver *driver)
+{
+	if (!__dsc_trans_queued(&driver->trans))
+		return false;
+
+	/* handled, but don't trigger; we need to wait for more children */
+	if (!__dsc_driver_can_trigger(driver))
+		return true;
+
+	return __dsc_trans_trigger(&driver->trans);
+}
+
+static void __dsc_driver_trigger_trans(struct dsc_driver *driver)
+{
+	struct dsc_psoc *psoc;
+	struct dsc_vdev *vdev;
+
+	if (__dsc_trans_trigger(&driver->trans))
+		return;
+
+	dsc_for_each_driver_psoc(driver, psoc) {
+		if (__dsc_trans_trigger(&psoc->trans))
+			continue;
+
+		dsc_for_each_psoc_vdev(psoc, vdev)
+			__dsc_trans_trigger(&vdev->trans);
+	}
+}
+
+static void __dsc_driver_trans_stop(struct dsc_driver *driver)
+{
+	if (!dsc_assert(driver))
+		return;
+
+	__dsc_lock(driver);
+
+	__dsc_trans_stop(&driver->trans);
+	__dsc_driver_trigger_trans(driver);
+
+	__dsc_unlock(driver);
+}
+
+void dsc_driver_trans_stop(struct dsc_driver *driver)
+{
+	dsc_enter();
+	__dsc_driver_trans_stop(driver);
+	dsc_exit();
+}
+
+static void __dsc_driver_trans_assert(struct dsc_driver *driver)
+{
+	if (!dsc_assert(driver))
+		return;
+
+	__dsc_lock(driver);
+	dsc_assert(__dsc_trans_active(&driver->trans));
+	__dsc_unlock(driver);
+}
+
+void dsc_driver_trans_assert(struct dsc_driver *driver)
+{
+	dsc_enter();
+	__dsc_driver_trans_assert(driver);
+	dsc_exit();
+}
+
+static QDF_STATUS
+__dsc_driver_op_start(struct dsc_driver *driver, const char *func)
+{
+	QDF_STATUS status;
+
+	if (!dsc_assert(driver))
+		return QDF_STATUS_E_INVAL;
+
+	if (!dsc_assert(func))
+		return QDF_STATUS_E_INVAL;
+
+	__dsc_lock(driver);
+
+	if (!__dsc_driver_can_op(driver)) {
+		status = QDF_STATUS_E_AGAIN;
+		goto unlock;
+	}
+
+	status = __dsc_ops_insert(&driver->ops, func);
+
+unlock:
+	__dsc_unlock(driver);
+
+	return status;
+}
+
+QDF_STATUS _dsc_driver_op_start(struct dsc_driver *driver, const char *func)
+{
+	QDF_STATUS status;
+
+	dsc_enter_str(func);
+	status = __dsc_driver_op_start(driver, func);
+	dsc_exit_status(status);
+
+	return status;
+}
+
+static void __dsc_driver_op_stop(struct dsc_driver *driver, const char *func)
+{
+	if (!dsc_assert(driver))
+		return;
+
+	if (!dsc_assert(func))
+		return;
+
+	__dsc_lock(driver);
+	if (__dsc_ops_remove(&driver->ops, func))
+		qdf_event_set(&driver->ops.event);
+	__dsc_unlock(driver);
+}
+
+void _dsc_driver_op_stop(struct dsc_driver *driver, const char *func)
+{
+	dsc_enter_str(func);
+	__dsc_driver_op_stop(driver, func);
+	dsc_exit();
+}
+
+static void __dsc_driver_wait_for_ops(struct dsc_driver *driver)
+{
+	struct dsc_psoc *psoc;
+	bool wait;
+
+	if (!dsc_assert(driver))
+		return;
+
+	__dsc_lock(driver);
+
+	/* flushing without preventing new ops is almost certainly a bug */
+	dsc_assert(!__dsc_driver_can_op(driver));
+
+	wait = driver->ops.count > 0;
+	if (wait)
+		qdf_event_reset(&driver->ops.event);
+
+	__dsc_unlock(driver);
+
+	if (wait)
+		qdf_wait_single_event(&driver->ops.event, 0);
+
+	/* wait for down-tree ops to complete as well */
+	dsc_for_each_driver_psoc(driver, psoc)
+		dsc_psoc_wait_for_ops(psoc);
+}
+
+void dsc_driver_wait_for_ops(struct dsc_driver *driver)
+{
+	dsc_enter();
+	__dsc_driver_wait_for_ops(driver);
+	dsc_exit();
+}
+
diff --git a/components/dsc/src/wlan_dsc_psoc.c b/components/dsc/src/wlan_dsc_psoc.c
new file mode 100644
index 0000000..cd21084
--- /dev/null
+++ b/components/dsc/src/wlan_dsc_psoc.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#include "qdf_list.h"
+#include "qdf_mem.h"
+#include "qdf_status.h"
+#include "qdf_types.h"
+#include "__wlan_dsc.h"
+#include "wlan_dsc.h"
+
+#define __dsc_driver_lock(psoc) __dsc_lock((psoc)->driver)
+#define __dsc_driver_unlock(psoc) __dsc_unlock((psoc)->driver)
+
+static QDF_STATUS
+__dsc_psoc_create(struct dsc_driver *driver, struct dsc_psoc **out_psoc)
+{
+	struct dsc_psoc *psoc;
+
+	if (!dsc_assert(driver))
+		return QDF_STATUS_E_INVAL;
+
+	if (!dsc_assert(out_psoc))
+		return QDF_STATUS_E_INVAL;
+
+	*out_psoc = NULL;
+
+	psoc = qdf_mem_malloc(sizeof(*psoc));
+	if (!psoc)
+		return QDF_STATUS_E_NOMEM;
+
+	/* init */
+	psoc->driver = driver;
+	qdf_list_create(&psoc->vdevs, 0);
+	__dsc_trans_init(&psoc->trans);
+	__dsc_ops_init(&psoc->ops);
+
+	/* attach */
+	__dsc_driver_lock(psoc);
+	qdf_list_insert_back(&driver->psocs, &psoc->node);
+	__dsc_driver_unlock(psoc);
+
+	*out_psoc = psoc;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+dsc_psoc_create(struct dsc_driver *driver, struct dsc_psoc **out_psoc)
+{
+	QDF_STATUS status;
+
+	dsc_enter();
+	status =  __dsc_psoc_create(driver, out_psoc);
+	dsc_exit();
+
+	return status;
+}
+
+static void __dsc_psoc_destroy(struct dsc_psoc **out_psoc)
+{
+	struct dsc_psoc *psoc;
+
+	if (!dsc_assert(out_psoc))
+		return;
+
+	psoc = *out_psoc;
+	if (!dsc_assert(psoc))
+		return;
+
+	*out_psoc = NULL;
+
+	/* assert no children */
+	dsc_assert(qdf_list_empty(&psoc->vdevs));
+
+	/* flush pending transitions */
+	while (__dsc_trans_abort(&psoc->trans))
+		;
+
+	/* detach */
+	__dsc_driver_lock(psoc);
+	qdf_list_remove_node(&psoc->driver->psocs, &psoc->node);
+	__dsc_driver_unlock(psoc);
+
+	/* de-init */
+	__dsc_ops_deinit(&psoc->ops);
+	__dsc_trans_deinit(&psoc->trans);
+	qdf_list_destroy(&psoc->vdevs);
+	psoc->driver = NULL;
+
+	qdf_mem_free(psoc);
+}
+
+void dsc_psoc_destroy(struct dsc_psoc **out_psoc)
+{
+	dsc_enter();
+	__dsc_psoc_destroy(out_psoc);
+	dsc_exit();
+}
+
+static bool __dsc_psoc_trans_active_down_tree(struct dsc_psoc *psoc)
+{
+	struct dsc_vdev *vdev;
+
+	dsc_for_each_psoc_vdev(psoc, vdev) {
+		if (__dsc_trans_active(&vdev->trans))
+			return true;
+	}
+
+	return false;
+}
+
+static bool __dsc_psoc_can_op(struct dsc_psoc *psoc)
+{
+	return !__dsc_trans_active_or_queued(&psoc->driver->trans) &&
+		!__dsc_trans_active_or_queued(&psoc->trans);
+}
+
+static bool __dsc_psoc_can_trans(struct dsc_psoc *psoc)
+{
+	return !__dsc_trans_active_or_queued(&psoc->driver->trans) &&
+		!__dsc_trans_active_or_queued(&psoc->trans) &&
+		!__dsc_psoc_trans_active_down_tree(psoc);
+}
+
+static bool __dsc_psoc_can_trigger(struct dsc_psoc *psoc)
+{
+	return !__dsc_trans_active_or_queued(&psoc->driver->trans) &&
+		!__dsc_trans_active(&psoc->trans) &&
+		!__dsc_psoc_trans_active_down_tree(psoc);
+}
+
+static QDF_STATUS
+__dsc_psoc_trans_start_nolock(struct dsc_psoc *psoc, const char *desc)
+{
+	if (!__dsc_psoc_can_trans(psoc))
+		return QDF_STATUS_E_AGAIN;
+
+	return __dsc_trans_start(&psoc->trans, desc);
+}
+
+static QDF_STATUS
+__dsc_psoc_trans_start(struct dsc_psoc *psoc, const char *desc)
+{
+	QDF_STATUS status;
+
+	if (!dsc_assert(psoc))
+		return QDF_STATUS_E_INVAL;
+
+	if (!dsc_assert(desc))
+		return QDF_STATUS_E_INVAL;
+
+	__dsc_driver_lock(psoc);
+	status = __dsc_psoc_trans_start_nolock(psoc, desc);
+	__dsc_driver_unlock(psoc);
+
+	return status;
+}
+
+QDF_STATUS dsc_psoc_trans_start(struct dsc_psoc *psoc, const char *desc)
+{
+	QDF_STATUS status;
+
+	dsc_enter_str(desc);
+	status = __dsc_psoc_trans_start(psoc, desc);
+	dsc_exit_status(status);
+
+	return status;
+}
+
+static QDF_STATUS
+__dsc_psoc_trans_start_wait(struct dsc_psoc *psoc, const char *desc)
+{
+	QDF_STATUS status;
+	struct dsc_tran tran = { 0 };
+
+	if (!dsc_assert(psoc))
+		return QDF_STATUS_E_INVAL;
+
+	if (!dsc_assert(desc))
+		return QDF_STATUS_E_INVAL;
+
+	__dsc_driver_lock(psoc);
+
+	/* try to start without waiting */
+	status = __dsc_psoc_trans_start_nolock(psoc, desc);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		goto unlock;
+
+	status = __dsc_trans_queue(&psoc->trans, &tran, desc);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto unlock;
+
+	__dsc_driver_unlock(psoc);
+
+	return __dsc_tran_wait(&tran);
+
+unlock:
+	__dsc_driver_unlock(psoc);
+
+	return status;
+}
+
+QDF_STATUS dsc_psoc_trans_start_wait(struct dsc_psoc *psoc, const char *desc)
+{
+	QDF_STATUS status;
+
+	dsc_enter_str(desc);
+	status = __dsc_psoc_trans_start_wait(psoc, desc);
+	dsc_exit_status(status);
+
+	return status;
+}
+
+static void __dsc_psoc_trigger_trans(struct dsc_psoc *psoc)
+{
+	struct dsc_vdev *vdev;
+
+	if (__dsc_driver_trans_trigger_checked(psoc->driver))
+		return;
+
+	if (__dsc_trans_trigger(&psoc->trans))
+		return;
+
+	dsc_for_each_psoc_vdev(psoc, vdev)
+		__dsc_trans_trigger(&vdev->trans);
+}
+
+static void __dsc_psoc_trans_stop(struct dsc_psoc *psoc)
+{
+	if (!dsc_assert(psoc))
+		return;
+
+	__dsc_driver_lock(psoc);
+
+	__dsc_trans_stop(&psoc->trans);
+	__dsc_psoc_trigger_trans(psoc);
+
+	__dsc_driver_unlock(psoc);
+}
+
+void dsc_psoc_trans_stop(struct dsc_psoc *psoc)
+{
+	dsc_enter();
+	__dsc_psoc_trans_stop(psoc);
+	dsc_exit();
+}
+
+static void __dsc_psoc_trans_assert(struct dsc_psoc *psoc)
+{
+	if (!dsc_assert(psoc))
+		return;
+
+	__dsc_driver_lock(psoc);
+	dsc_assert(__dsc_trans_active(&psoc->trans));
+	__dsc_driver_unlock(psoc);
+}
+
+void dsc_psoc_trans_assert(struct dsc_psoc *psoc)
+{
+	dsc_enter();
+	__dsc_psoc_trans_assert(psoc);
+	dsc_exit();
+}
+
+bool __dsc_psoc_trans_trigger_checked(struct dsc_psoc *psoc)
+{
+	if (qdf_list_empty(&psoc->trans.queue))
+		return false;
+
+	/* handled, but don't trigger; we need to wait for more children */
+	if (!__dsc_psoc_can_trigger(psoc))
+		return true;
+
+	return __dsc_trans_trigger(&psoc->trans);
+}
+
+static QDF_STATUS __dsc_psoc_op_start(struct dsc_psoc *psoc, const char *func)
+{
+	QDF_STATUS status;
+
+	if (!dsc_assert(psoc))
+		return QDF_STATUS_E_INVAL;
+
+	if (!dsc_assert(func))
+		return QDF_STATUS_E_INVAL;
+
+	__dsc_driver_lock(psoc);
+
+	if (!__dsc_psoc_can_op(psoc)) {
+		status = QDF_STATUS_E_AGAIN;
+		goto unlock;
+	}
+
+	status = __dsc_ops_insert(&psoc->ops, func);
+
+unlock:
+	__dsc_driver_unlock(psoc);
+
+	return status;
+}
+
+QDF_STATUS _dsc_psoc_op_start(struct dsc_psoc *psoc, const char *func)
+{
+	QDF_STATUS status;
+
+	dsc_enter_str(func);
+	status = __dsc_psoc_op_start(psoc, func);
+	dsc_exit_status(status);
+
+	return status;
+}
+
+static void __dsc_psoc_op_stop(struct dsc_psoc *psoc, const char *func)
+{
+	if (!dsc_assert(psoc))
+		return;
+
+	if (!dsc_assert(func))
+		return;
+
+	__dsc_driver_lock(psoc);
+	if (__dsc_ops_remove(&psoc->ops, func))
+		qdf_event_set(&psoc->ops.event);
+	__dsc_driver_unlock(psoc);
+}
+
+void _dsc_psoc_op_stop(struct dsc_psoc *psoc, const char *func)
+{
+	dsc_enter_str(func);
+	__dsc_psoc_op_stop(psoc, func);
+	dsc_exit();
+}
+
+static void __dsc_psoc_wait_for_ops(struct dsc_psoc *psoc)
+{
+	struct dsc_vdev *vdev;
+	bool wait;
+
+	if (!dsc_assert(psoc))
+		return;
+
+	__dsc_driver_lock(psoc);
+
+	/* flushing without preventing new ops is almost certainly a bug */
+	dsc_assert(!__dsc_psoc_can_op(psoc));
+
+	wait = psoc->ops.count > 0;
+	if (wait)
+		qdf_event_reset(&psoc->ops.event);
+
+	__dsc_driver_unlock(psoc);
+
+	if (wait)
+		qdf_wait_single_event(&psoc->ops.event, 0);
+
+	/* wait for down-tree ops to complete as well */
+	dsc_for_each_psoc_vdev(psoc, vdev)
+		dsc_vdev_wait_for_ops(vdev);
+}
+
+void dsc_psoc_wait_for_ops(struct dsc_psoc *psoc)
+{
+	dsc_enter();
+	__dsc_psoc_wait_for_ops(psoc);
+	dsc_exit();
+}
+
diff --git a/components/dsc/src/wlan_dsc_vdev.c b/components/dsc/src/wlan_dsc_vdev.c
new file mode 100644
index 0000000..9cff55f
--- /dev/null
+++ b/components/dsc/src/wlan_dsc_vdev.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#include "qdf_list.h"
+#include "qdf_mem.h"
+#include "qdf_status.h"
+#include "qdf_types.h"
+#include "__wlan_dsc.h"
+#include "wlan_dsc.h"
+
+#define __dsc_driver_lock(vdev) __dsc_lock((vdev)->psoc->driver)
+#define __dsc_driver_unlock(vdev) __dsc_unlock((vdev)->psoc->driver)
+
+static QDF_STATUS
+__dsc_vdev_create(struct dsc_psoc *psoc, struct dsc_vdev **out_vdev)
+{
+	struct dsc_vdev *vdev;
+
+	if (!dsc_assert(psoc))
+		return QDF_STATUS_E_INVAL;
+
+	if (!dsc_assert(out_vdev))
+		return QDF_STATUS_E_INVAL;
+
+	*out_vdev = NULL;
+
+	vdev = qdf_mem_malloc(sizeof(*vdev));
+	if (!vdev)
+		return QDF_STATUS_E_NOMEM;
+
+	/* init */
+	vdev->psoc = psoc;
+	__dsc_trans_init(&vdev->trans);
+	__dsc_ops_init(&vdev->ops);
+
+	/* attach */
+	__dsc_driver_lock(vdev);
+	qdf_list_insert_back(&psoc->vdevs, &vdev->node);
+	__dsc_driver_unlock(vdev);
+
+	*out_vdev = vdev;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS dsc_vdev_create(struct dsc_psoc *psoc, struct dsc_vdev **out_vdev)
+{
+	QDF_STATUS status;
+
+	dsc_enter();
+	status =  __dsc_vdev_create(psoc, out_vdev);
+	dsc_exit();
+
+	return status;
+}
+
+static void __dsc_vdev_destroy(struct dsc_vdev **out_vdev)
+{
+	struct dsc_vdev *vdev;
+
+	if (!dsc_assert(out_vdev))
+		return;
+
+	vdev = *out_vdev;
+	if (!dsc_assert(vdev))
+		return;
+
+	*out_vdev = NULL;
+
+	/* flush pending transitions */
+	while (__dsc_trans_abort(&vdev->trans))
+		;
+
+	/* detach */
+	__dsc_driver_lock(vdev);
+	qdf_list_remove_node(&vdev->psoc->vdevs, &vdev->node);
+	__dsc_driver_unlock(vdev);
+
+	/* de-init */
+	__dsc_ops_deinit(&vdev->ops);
+	__dsc_trans_deinit(&vdev->trans);
+	vdev->psoc = NULL;
+
+	qdf_mem_free(vdev);
+}
+
+void dsc_vdev_destroy(struct dsc_vdev **out_vdev)
+{
+	dsc_enter();
+	__dsc_vdev_destroy(out_vdev);
+	dsc_exit();
+}
+
+static bool __dsc_vdev_can_op(struct dsc_vdev *vdev)
+{
+	return !__dsc_trans_active_or_queued(&vdev->psoc->driver->trans) &&
+		!__dsc_trans_active_or_queued(&vdev->psoc->trans) &&
+		!__dsc_trans_active_or_queued(&vdev->trans);
+}
+
+static bool __dsc_vdev_can_trans(struct dsc_vdev *vdev)
+{
+	return __dsc_vdev_can_op(vdev);
+}
+
+static QDF_STATUS
+__dsc_vdev_trans_start_nolock(struct dsc_vdev *vdev, const char *desc)
+{
+	if (!__dsc_vdev_can_trans(vdev))
+		return QDF_STATUS_E_AGAIN;
+
+	return __dsc_trans_start(&vdev->trans, desc);
+}
+
+static QDF_STATUS
+__dsc_vdev_trans_start(struct dsc_vdev *vdev, const char *desc)
+{
+	QDF_STATUS status;
+
+	if (!dsc_assert(vdev))
+		return QDF_STATUS_E_INVAL;
+
+	if (!dsc_assert(desc))
+		return QDF_STATUS_E_INVAL;
+
+	__dsc_driver_lock(vdev);
+	status = __dsc_vdev_trans_start_nolock(vdev, desc);
+	__dsc_driver_unlock(vdev);
+
+	return status;
+}
+
+QDF_STATUS dsc_vdev_trans_start(struct dsc_vdev *vdev, const char *desc)
+{
+	QDF_STATUS status;
+
+	dsc_enter_str(desc);
+	status = __dsc_vdev_trans_start(vdev, desc);
+	dsc_exit_status(status);
+
+	return status;
+}
+
+static QDF_STATUS
+__dsc_vdev_trans_start_wait(struct dsc_vdev *vdev, const char *desc)
+{
+	QDF_STATUS status;
+	struct dsc_tran tran = { 0 };
+
+	if (!dsc_assert(vdev))
+		return QDF_STATUS_E_INVAL;
+
+	if (!dsc_assert(desc))
+		return QDF_STATUS_E_INVAL;
+
+	__dsc_driver_lock(vdev);
+
+	/* try to start without waiting */
+	status = __dsc_vdev_trans_start_nolock(vdev, desc);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		goto unlock;
+
+	status = __dsc_trans_queue(&vdev->trans, &tran, desc);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto unlock;
+
+	__dsc_driver_unlock(vdev);
+
+	return __dsc_tran_wait(&tran);
+
+unlock:
+	__dsc_driver_unlock(vdev);
+
+	return status;
+}
+
+QDF_STATUS dsc_vdev_trans_start_wait(struct dsc_vdev *vdev, const char *desc)
+{
+	QDF_STATUS status;
+
+	dsc_enter_str(desc);
+	status = __dsc_vdev_trans_start_wait(vdev, desc);
+	dsc_exit_status(status);
+
+	return status;
+}
+
+static void __dsc_vdev_trigger_trans(struct dsc_vdev *vdev)
+{
+	if (__dsc_driver_trans_trigger_checked(vdev->psoc->driver))
+		return;
+
+	if (__dsc_psoc_trans_trigger_checked(vdev->psoc))
+		return;
+
+	__dsc_trans_trigger(&vdev->trans);
+}
+
+static void __dsc_vdev_trans_stop(struct dsc_vdev *vdev)
+{
+	if (!dsc_assert(vdev))
+		return;
+
+	__dsc_driver_lock(vdev);
+
+	__dsc_trans_stop(&vdev->trans);
+	__dsc_vdev_trigger_trans(vdev);
+
+	__dsc_driver_unlock(vdev);
+}
+
+void dsc_vdev_trans_stop(struct dsc_vdev *vdev)
+{
+	dsc_enter();
+	__dsc_vdev_trans_stop(vdev);
+	dsc_exit();
+}
+
+static void __dsc_vdev_trans_assert(struct dsc_vdev *vdev)
+{
+	if (!dsc_assert(vdev))
+		return;
+
+	__dsc_driver_lock(vdev);
+	dsc_assert(__dsc_trans_active(&vdev->trans));
+	__dsc_driver_unlock(vdev);
+}
+
+void dsc_vdev_trans_assert(struct dsc_vdev *vdev)
+{
+	dsc_enter();
+	__dsc_vdev_trans_assert(vdev);
+	dsc_exit();
+}
+
+static QDF_STATUS __dsc_vdev_op_start(struct dsc_vdev *vdev, const char *func)
+{
+	QDF_STATUS status;
+
+	if (!dsc_assert(vdev))
+		return QDF_STATUS_E_INVAL;
+
+	if (!dsc_assert(func))
+		return QDF_STATUS_E_INVAL;
+
+	__dsc_driver_lock(vdev);
+
+	if (!__dsc_vdev_can_op(vdev)) {
+		status = QDF_STATUS_E_AGAIN;
+		goto unlock;
+	}
+
+	status = __dsc_ops_insert(&vdev->ops, func);
+
+unlock:
+	__dsc_driver_unlock(vdev);
+
+	return status;
+}
+
+QDF_STATUS _dsc_vdev_op_start(struct dsc_vdev *vdev, const char *func)
+{
+	QDF_STATUS status;
+
+	dsc_enter_str(func);
+	status = __dsc_vdev_op_start(vdev, func);
+	dsc_exit_status(status);
+
+	return status;
+}
+
+static void __dsc_vdev_op_stop(struct dsc_vdev *vdev, const char *func)
+{
+	if (!dsc_assert(vdev))
+		return;
+
+	if (!dsc_assert(func))
+		return;
+
+	__dsc_driver_lock(vdev);
+	if (__dsc_ops_remove(&vdev->ops, func))
+		qdf_event_set(&vdev->ops.event);
+	__dsc_driver_unlock(vdev);
+}
+
+void _dsc_vdev_op_stop(struct dsc_vdev *vdev, const char *func)
+{
+	dsc_enter_str(func);
+	__dsc_vdev_op_stop(vdev, func);
+	dsc_exit();
+}
+
+static void __dsc_vdev_wait_for_ops(struct dsc_vdev *vdev)
+{
+	bool wait;
+
+	if (!dsc_assert(vdev))
+		return;
+
+	__dsc_driver_lock(vdev);
+
+	/* flushing without preventing new ops is almost certainly a bug */
+	dsc_assert(!__dsc_vdev_can_op(vdev));
+
+	wait = vdev->ops.count > 0;
+	if (wait)
+		qdf_event_reset(&vdev->ops.event);
+
+	__dsc_driver_unlock(vdev);
+
+	if (wait)
+		qdf_wait_single_event(&vdev->ops.event, 0);
+}
+
+void dsc_vdev_wait_for_ops(struct dsc_vdev *vdev)
+{
+	dsc_enter();
+	__dsc_vdev_wait_for_ops(vdev);
+	dsc_exit();
+}
+
diff --git a/components/dsc/test/wlan_dsc_test.c b/components/dsc/test/wlan_dsc_test.c
new file mode 100644
index 0000000..55f34f5
--- /dev/null
+++ b/components/dsc/test/wlan_dsc_test.c
@@ -0,0 +1,572 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#include "__wlan_dsc.h"
+#include "qdf_event.h"
+#include "qdf_threads.h"
+#include "qdf_trace.h"
+#include "qdf_types.h"
+#include "wlan_dsc.h"
+#include "wlan_dsc_test.h"
+
+#define dsc_driver_trans_start(driver) dsc_driver_trans_start(driver, __func__)
+#define dsc_psoc_trans_start(psoc) dsc_psoc_trans_start(psoc, __func__)
+#define dsc_vdev_trans_start(vdev) dsc_vdev_trans_start(vdev, __func__)
+
+#define dsc_driver_trans_start_wait(driver) \
+	dsc_driver_trans_start_wait(driver, "")
+#define dsc_psoc_trans_start_wait(psoc) \
+	dsc_psoc_trans_start_wait(psoc, __func__)
+#define dsc_vdev_trans_start_wait(vdev) \
+	dsc_vdev_trans_start_wait(vdev, __func__)
+
+static struct dsc_psoc *nth_psoc(struct dsc_driver *driver, int n)
+{
+	struct dsc_psoc *psoc;
+
+	QDF_BUG(n > 0);
+	if (n <= 0)
+		return NULL;
+
+	dsc_for_each_driver_psoc(driver, psoc) {
+		n--;
+		if (n)
+			continue;
+
+		return psoc;
+	}
+
+	QDF_DEBUG_PANIC();
+
+	return NULL;
+}
+
+static struct dsc_vdev *nth_vdev(struct dsc_psoc *psoc, int n)
+{
+	struct dsc_vdev *vdev;
+
+	QDF_BUG(n > 0);
+	if (n <= 0)
+		return NULL;
+
+	dsc_for_each_psoc_vdev(psoc, vdev) {
+		n--;
+		if (n)
+			continue;
+
+		return vdev;
+	}
+
+	QDF_DEBUG_PANIC();
+
+	return NULL;
+}
+
+static void __dsc_tree_destroy(struct dsc_driver *driver)
+{
+	struct dsc_psoc *psoc;
+	struct dsc_psoc *next_psoc;
+
+	QDF_BUG(driver);
+
+	qdf_list_for_each_del(&driver->psocs, psoc, next_psoc, node) {
+		struct dsc_vdev *vdev;
+		struct dsc_vdev *next_vdev;
+
+		qdf_list_for_each_del(&psoc->vdevs, vdev, next_vdev, node)
+			dsc_vdev_destroy(&vdev);
+
+		dsc_psoc_destroy(&psoc);
+	}
+
+	dsc_driver_destroy(&driver);
+}
+
+static QDF_STATUS __dsc_tree_create(struct dsc_driver **out_driver,
+				    uint8_t psocs_per_driver,
+				    uint8_t vdevs_per_psoc)
+{
+	QDF_STATUS status;
+	struct dsc_driver *driver;
+	int i, j;
+
+	status = dsc_driver_create(&driver);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dsc_err("Failed to create driver; status:%u", status);
+		return status;
+	}
+
+	for (i = 0; i < psocs_per_driver; i++) {
+		struct dsc_psoc *psoc;
+
+		status = dsc_psoc_create(driver, &psoc);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			dsc_err("Failed to create psoc; status:%u", status);
+			goto free_tree;
+		}
+
+		for (j = 0; j < vdevs_per_psoc; j++) {
+			struct dsc_vdev *vdev;
+
+			status = dsc_vdev_create(psoc, &vdev);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				dsc_err("Failed to create vdev; status:%u",
+					status);
+				goto free_tree;
+			}
+		}
+	}
+
+	*out_driver = driver;
+
+	return QDF_STATUS_SUCCESS;
+
+free_tree:
+	__dsc_tree_destroy(driver);
+
+	return status;
+}
+
+static uint32_t dsc_test_create_destroy(void)
+{
+	uint32_t errors = 0;
+	QDF_STATUS status;
+	struct dsc_driver *driver;
+
+	dsc_enter();
+
+	status = __dsc_tree_create(&driver, 2, 2);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		errors++;
+		goto exit;
+	}
+
+	__dsc_tree_destroy(driver);
+
+exit:
+	dsc_exit();
+
+	return errors;
+}
+
+#define action_expect(obj, action, status, errors) \
+do { \
+	void *__obj = obj; \
+	QDF_STATUS __expected = status; \
+	QDF_STATUS __result; \
+\
+	__result = dsc_##obj##_##action##_start(__obj); \
+	if (__result != __expected) { \
+		dsc_err("FAIL: " #obj " " #action \
+			"; expected " #status " (%u), found %u", \
+			__expected, __result); \
+		(errors)++; \
+	} \
+	if (QDF_IS_STATUS_SUCCESS(__result) && QDF_IS_STATUS_ERROR(__expected))\
+		dsc_##obj##_##action##_stop(__obj); \
+} while (false)
+
+static uint32_t dsc_test_driver_trans_blocks(void)
+{
+	uint32_t errors = 0;
+	QDF_STATUS status;
+	struct dsc_driver *driver;
+	struct dsc_psoc *psoc;
+	struct dsc_vdev *vdev;
+
+	dsc_enter();
+
+	/* setup */
+
+	status = __dsc_tree_create(&driver, 2, 2);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		errors++;
+		goto exit;
+	}
+
+	action_expect(driver, trans, QDF_STATUS_SUCCESS, errors);
+
+	/* test */
+
+	action_expect(driver, trans, QDF_STATUS_E_AGAIN, errors);
+	action_expect(driver, op, QDF_STATUS_E_AGAIN, errors);
+
+	dsc_for_each_driver_psoc(driver, psoc) {
+		action_expect(psoc, trans, QDF_STATUS_E_AGAIN, errors);
+		action_expect(psoc, op, QDF_STATUS_E_AGAIN, errors);
+
+		dsc_for_each_psoc_vdev(psoc, vdev) {
+			action_expect(vdev, trans, QDF_STATUS_E_AGAIN, errors);
+			action_expect(vdev, op, QDF_STATUS_E_AGAIN, errors);
+		}
+	}
+
+	/* teardown */
+
+	dsc_driver_trans_stop(driver);
+
+	__dsc_tree_destroy(driver);
+
+exit:
+	dsc_exit();
+
+	return errors;
+}
+
+static uint32_t dsc_test_psoc_trans_blocks(void)
+{
+	uint32_t errors = 0;
+	QDF_STATUS status;
+	struct dsc_driver *driver;
+	struct dsc_psoc *psoc;
+	struct dsc_vdev *vdev;
+
+	dsc_enter();
+
+	/* setup */
+
+	status = __dsc_tree_create(&driver, 2, 2);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		errors++;
+		goto exit;
+	}
+
+	/* test */
+
+	psoc = nth_psoc(driver, 1);
+	action_expect(psoc, trans, QDF_STATUS_SUCCESS, errors);
+
+	action_expect(driver, trans, QDF_STATUS_E_AGAIN, errors);
+	action_expect(driver, op, QDF_STATUS_SUCCESS, errors);
+	dsc_driver_op_stop(driver);
+
+	action_expect(psoc, trans, QDF_STATUS_E_AGAIN, errors);
+	action_expect(psoc, op, QDF_STATUS_E_AGAIN, errors);
+
+	dsc_for_each_psoc_vdev(psoc, vdev) {
+		action_expect(vdev, trans, QDF_STATUS_E_AGAIN, errors);
+		action_expect(vdev, op, QDF_STATUS_E_AGAIN, errors);
+	}
+
+	psoc = nth_psoc(driver, 2);
+	action_expect(psoc, trans, QDF_STATUS_SUCCESS, errors);
+
+	action_expect(driver, trans, QDF_STATUS_E_AGAIN, errors);
+	action_expect(driver, op, QDF_STATUS_SUCCESS, errors);
+	dsc_driver_op_stop(driver);
+
+	action_expect(psoc, trans, QDF_STATUS_E_AGAIN, errors);
+	action_expect(psoc, op, QDF_STATUS_E_AGAIN, errors);
+
+	dsc_for_each_psoc_vdev(psoc, vdev) {
+		action_expect(vdev, trans, QDF_STATUS_E_AGAIN, errors);
+		action_expect(vdev, op, QDF_STATUS_E_AGAIN, errors);
+	}
+
+	/* teardown */
+
+	dsc_for_each_driver_psoc(driver, psoc)
+		dsc_psoc_trans_stop(psoc);
+
+	__dsc_tree_destroy(driver);
+
+exit:
+	dsc_exit();
+
+	return errors;
+}
+
+static uint32_t dsc_test_vdev_trans_blocks(void)
+{
+	uint32_t errors = 0;
+	QDF_STATUS status;
+	struct dsc_driver *driver;
+	struct dsc_psoc *psoc;
+	struct dsc_vdev *vdev;
+
+	dsc_enter();
+
+	/* setup */
+
+	status = __dsc_tree_create(&driver, 2, 2);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		errors++;
+		goto exit;
+	}
+
+	dsc_for_each_driver_psoc(driver, psoc) {
+		dsc_for_each_psoc_vdev(psoc, vdev)
+			action_expect(vdev, trans, QDF_STATUS_SUCCESS, errors);
+	}
+
+	/* test */
+
+	action_expect(driver, trans, QDF_STATUS_E_AGAIN, errors);
+	action_expect(driver, op, QDF_STATUS_SUCCESS, errors);
+	dsc_driver_op_stop(driver);
+
+	dsc_for_each_driver_psoc(driver, psoc) {
+		action_expect(psoc, trans, QDF_STATUS_E_AGAIN, errors);
+		action_expect(psoc, op, QDF_STATUS_SUCCESS, errors);
+		dsc_psoc_op_stop(psoc);
+
+		dsc_for_each_psoc_vdev(psoc, vdev) {
+			action_expect(vdev, trans, QDF_STATUS_E_AGAIN, errors);
+			action_expect(vdev, op, QDF_STATUS_E_AGAIN, errors);
+		}
+	}
+
+	/* teardown */
+
+	dsc_for_each_driver_psoc(driver, psoc) {
+		dsc_for_each_psoc_vdev(psoc, vdev)
+			dsc_vdev_trans_stop(vdev);
+	}
+
+	__dsc_tree_destroy(driver);
+
+exit:
+	dsc_exit();
+
+	return errors;
+}
+
+#define THREAD_TIMEOUT 1000 /* ms */
+#define dsc_event_wait(event) qdf_wait_single_event(event, THREAD_TIMEOUT)
+
+struct thread_ctx {
+	struct dsc_driver *driver;
+	qdf_event_t start_vdev_trans;
+	qdf_event_t start_vdev_wait;
+	qdf_event_t start_psoc_wait;
+	qdf_event_t start_driver_wait;
+	qdf_event_t stop_ops;
+	uint32_t step;
+};
+
+static QDF_STATUS dsc_thread_ops(void *context)
+{
+	struct thread_ctx *ctx = context;
+	struct dsc_driver *driver = ctx->driver;
+	struct dsc_psoc *psoc = nth_psoc(driver, 1);
+	struct dsc_vdev *vdev = nth_vdev(psoc, 1);
+
+	dsc_enter();
+
+	dsc_assert_success(dsc_driver_op_start(driver));
+	dsc_assert_success(dsc_psoc_op_start(psoc));
+	dsc_assert_success(dsc_vdev_op_start(vdev));
+
+	dsc_assert(++ctx->step == 1);
+	qdf_event_set(&ctx->start_vdev_trans);
+
+	dsc_assert_success(dsc_event_wait(&ctx->stop_ops));
+	dsc_assert(++ctx->step == 7);
+
+	dsc_driver_op_stop(driver);
+	schedule();
+	dsc_psoc_op_stop(psoc);
+	schedule();
+	dsc_vdev_op_stop(vdev);
+
+	dsc_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS dsc_thread_vdev_trans(void *context)
+{
+	struct thread_ctx *ctx = context;
+	struct dsc_driver *driver = ctx->driver;
+	struct dsc_psoc *psoc = nth_psoc(driver, 1);
+	struct dsc_vdev *vdev;
+
+	dsc_enter();
+
+	dsc_assert_success(dsc_event_wait(&ctx->start_vdev_trans));
+	dsc_assert(++ctx->step == 2);
+
+	dsc_for_each_psoc_vdev(psoc, vdev)
+		dsc_assert_success(dsc_vdev_trans_start(vdev));
+
+	dsc_assert(++ctx->step == 3);
+	qdf_event_set(&ctx->start_vdev_wait);
+
+	dsc_vdev_wait_for_ops(nth_vdev(psoc, 1));
+
+	dsc_assert(++ctx->step == 8);
+	dsc_vdev_trans_stop(nth_vdev(psoc, 1));
+	schedule();
+	dsc_assert(++ctx->step == 9);
+
+	dsc_vdev_trans_stop(nth_vdev(psoc, 2));
+
+	dsc_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS dsc_thread_vdev_wait(void *context)
+{
+	struct thread_ctx *ctx = context;
+	struct dsc_vdev *vdev = nth_vdev(nth_psoc(ctx->driver, 1), 1);
+
+	dsc_enter();
+
+	dsc_assert_success(dsc_event_wait(&ctx->start_vdev_wait));
+	dsc_assert(++ctx->step == 4);
+
+	qdf_event_set(&ctx->start_psoc_wait);
+	dsc_assert_success(dsc_vdev_trans_start_wait(vdev));
+	dsc_assert(++ctx->step == 14);
+
+	schedule();
+
+	dsc_assert(++ctx->step == 15);
+	dsc_vdev_trans_stop(vdev);
+
+	dsc_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS dsc_thread_psoc_wait(void *context)
+{
+	struct thread_ctx *ctx = context;
+	struct dsc_psoc *psoc = nth_psoc(ctx->driver, 1);
+
+	dsc_enter();
+
+	dsc_assert_success(dsc_event_wait(&ctx->start_psoc_wait));
+	dsc_assert(++ctx->step == 5);
+
+	qdf_event_set(&ctx->start_driver_wait);
+	dsc_assert_success(dsc_psoc_trans_start_wait(psoc));
+	dsc_assert(++ctx->step == 12);
+
+	schedule();
+
+	dsc_assert(++ctx->step == 13);
+	dsc_psoc_trans_stop(psoc);
+
+	dsc_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS dsc_thread_driver_wait(void *context)
+{
+	struct thread_ctx *ctx = context;
+	struct dsc_driver *driver = ctx->driver;
+
+	dsc_enter();
+
+	dsc_assert_success(dsc_event_wait(&ctx->start_driver_wait));
+	dsc_assert(++ctx->step == 6);
+
+	qdf_event_set(&ctx->stop_ops);
+	dsc_assert_success(dsc_driver_trans_start_wait(driver));
+	dsc_assert(++ctx->step == 10);
+
+	schedule();
+
+	dsc_assert(++ctx->step == 11);
+	dsc_driver_trans_stop(driver);
+
+	dsc_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static uint32_t dsc_test_trans_wait(void)
+{
+	uint32_t errors = 0;
+	QDF_STATUS status;
+	qdf_thread_t *ops_thread;
+	qdf_thread_t *vdev_trans_thread;
+	qdf_thread_t *vdev_wait_thread;
+	qdf_thread_t *psoc_wait_thread;
+	qdf_thread_t *driver_wait_thread;
+	struct thread_ctx ctx = { 0 };
+
+	dsc_enter();
+
+	status = __dsc_tree_create(&ctx.driver, 1, 2);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		errors++;
+		goto exit;
+	}
+
+	dsc_assert_success(qdf_event_create(&ctx.start_vdev_trans));
+	dsc_assert_success(qdf_event_create(&ctx.start_vdev_wait));
+	dsc_assert_success(qdf_event_create(&ctx.start_psoc_wait));
+	dsc_assert_success(qdf_event_create(&ctx.start_driver_wait));
+	dsc_assert_success(qdf_event_create(&ctx.stop_ops));
+
+	dsc_debug("starting threads");
+
+	ops_thread = qdf_thread_run(dsc_thread_ops, &ctx);
+	vdev_trans_thread = qdf_thread_run(dsc_thread_vdev_trans, &ctx);
+	vdev_wait_thread = qdf_thread_run(dsc_thread_vdev_wait, &ctx);
+	psoc_wait_thread = qdf_thread_run(dsc_thread_psoc_wait, &ctx);
+	driver_wait_thread = qdf_thread_run(dsc_thread_driver_wait, &ctx);
+
+	qdf_thread_join(ops_thread);
+	qdf_thread_join(vdev_trans_thread);
+	qdf_thread_join(vdev_wait_thread);
+	qdf_thread_join(psoc_wait_thread);
+	qdf_thread_join(driver_wait_thread);
+
+	dsc_debug("threads joined");
+
+	qdf_event_destroy(&ctx.stop_ops);
+	qdf_event_destroy(&ctx.start_driver_wait);
+	qdf_event_destroy(&ctx.start_psoc_wait);
+	qdf_event_destroy(&ctx.start_vdev_wait);
+	qdf_event_destroy(&ctx.start_vdev_trans);
+
+	__dsc_tree_destroy(ctx.driver);
+
+exit:
+	dsc_exit();
+
+	return errors;
+}
+
+uint32_t dsc_unit_test(void)
+{
+	uint32_t errors = 0;
+
+	dsc_debug("Starting dsc component tests");
+
+	errors += dsc_test_create_destroy();
+	errors += dsc_test_driver_trans_blocks();
+	errors += dsc_test_psoc_trans_blocks();
+	errors += dsc_test_vdev_trans_blocks();
+	errors += dsc_test_trans_wait();
+
+	if (errors) {
+		dsc_err("FAIL: %u dsc component tests failed!", errors);
+		return errors;
+	}
+
+	dsc_info("PASS: dsc component tests passed successfully");
+
+	return 0;
+}
+
diff --git a/components/dsc/test/wlan_dsc_test.h b/components/dsc/test/wlan_dsc_test.h
new file mode 100644
index 0000000..b2c23d2
--- /dev/null
+++ b/components/dsc/test/wlan_dsc_test.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef __WLAN_DSC_TEST
+#define __WLAN_DSC_TEST
+
+#ifdef WLAN_DSC_TEST
+/**
+ * dsc_unit_test() - run the dsc unit test suite
+ *
+ * Return: number of failed test cases
+ */
+uint32_t dsc_unit_test(void);
+#else
+static inline uint32_t dsc_unit_test(void)
+{
+	return 0;
+}
+#endif /* WLAN_DSC_TEST */
+
+#endif /* __WLAN_DSC_TEST */
+
diff --git a/components/fw_offload/core/inc/wlan_fw_offload_main.h b/components/fw_offload/core/inc/wlan_fw_offload_main.h
new file mode 100644
index 0000000..5182a12
--- /dev/null
+++ b/components/fw_offload/core/inc/wlan_fw_offload_main.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2012 - 2018 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 fw_offload component
+ * called by other components
+ */
+
+#ifndef _WLAN_FW_OFFLOAD_MAIN_H_
+#define _WLAN_FW_OFFLOAD_MAIN_H_
+
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_cmn.h>
+
+#include "cfg_ucfg_api.h"
+
+#define fwol_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_FWOL, params)
+#define fwol_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_FWOL, params)
+#define fwol_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_FWOL, params)
+#define fwol_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_FWOL, params)
+#define fwol_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_FWOL, params)
+
+/**
+ * struct wlan_fwol_three_antenna_btc - Three antenna BTC config items
+ * @btc_mode: Config BTC mode
+ * @antenna_isolation: Antenna isolation
+ * @max_tx_power_for_btc: Max wlan tx power in co-ex scenario
+ * @wlan_low_rssi_threshold: Wlan low rssi threshold for BTC mode switching
+ * @bt_low_rssi_threshold: BT low rssi threshold for BTC mode switching
+ * @bt_interference_low_ll: Lower limit of low level BT interference
+ * @bt_interference_low_ul: Upper limit of low level BT interference
+ * @bt_interference_medium_ll: Lower limit of medium level BT interference
+ * @bt_interference_medium_ul: Upper limit of medium level BT interference
+ * @bt_interference_high_ll: Lower limit of high level BT interference
+ * @bt_interference_high_ul: Upper limit of high level BT interference
+ */
+struct wlan_fwol_coex_config {
+	uint8_t btc_mode;
+	uint8_t antenna_isolation;
+	uint8_t max_tx_power_for_btc;
+	int16_t wlan_low_rssi_threshold;
+	int16_t bt_low_rssi_threshold;
+	int16_t bt_interference_low_ll;
+	int16_t bt_interference_low_ul;
+	int16_t bt_interference_medium_ll;
+	int16_t bt_interference_medium_ul;
+	int16_t bt_interference_high_ll;
+	int16_t bt_interference_high_ul;
+};
+
+/*
+ * struct wlan_fwol_thermal_temp - Thermal temperature config items
+ * @thermal_temp_min_level0: Thermal temperature minimum level 0
+ * @thermal_temp_max_level0: Thermal temperature maximum level 0
+ * @thermal_temp_min_level1: Thermal temperature minimum level 1
+ * @thermal_temp_max_level1: Thermal temperature maximum level 1
+ * @thermal_temp_min_level2: Thermal temperature minimum level 2
+ * @thermal_temp_max_level2: Thermal temperature maximum level 2
+ * @thermal_temp_min_level3: Thermal temperature minimum level 3
+ * @thermal_temp_max_level3: Thermal temperature maximum level 3
+ */
+struct wlan_fwol_thermal_temp {
+	uint16_t thermal_temp_min_level0;
+	uint16_t thermal_temp_max_level0;
+	uint16_t thermal_temp_min_level1;
+	uint16_t thermal_temp_max_level1;
+	uint16_t thermal_temp_min_level2;
+	uint16_t thermal_temp_max_level2;
+	uint16_t thermal_temp_min_level3;
+	uint16_t thermal_temp_max_level3;
+};
+
+/**
+ * struct wlan_fwol_ie_whitelist - Probe request IE whitelist config items
+ * @ie_whitelist: IE whitelist flag
+ * @ie_bitmap_0: IE bitmap 0
+ * @ie_bitmap_1: IE bitmap 1
+ * @ie_bitmap_2: IE bitmap 2
+ * @ie_bitmap_3: IE bitmap 3
+ * @ie_bitmap_4: IE bitmap 4
+ * @ie_bitmap_5: IE bitmap 5
+ * @ie_bitmap_6: IE bitmap 6
+ * @ie_bitmap_7: IE bitmap 7
+ * @no_of_probe_req_ouis: Total number of ouis present in probe req
+ * @probe_req_voui: Stores oui values after parsing probe req ouis
+ */
+struct wlan_fwol_ie_whitelist {
+	bool ie_whitelist;
+	uint32_t ie_bitmap_0;
+	uint32_t ie_bitmap_1;
+	uint32_t ie_bitmap_2;
+	uint32_t ie_bitmap_3;
+	uint32_t ie_bitmap_4;
+	uint32_t ie_bitmap_5;
+	uint32_t ie_bitmap_6;
+	uint32_t ie_bitmap_7;
+	uint32_t no_of_probe_req_ouis;
+	uint32_t probe_req_voui[MAX_PROBE_REQ_OUIS];
+};
+
+/**
+ * struct wlan_fwol_cfg - fwol config items
+ * coex_config: coex config items
+ * thermal_temp_cfg: Thermal temperature related config items
+ * ie_whitelist_cfg: IE Whitelist related config items
+ * @ani_enabled: ANI enable/disable
+ * @enable_rts_sifsbursting: Enable RTS SIFS Bursting
+ * @max_mpdus_inampdu: Max number of MPDUS
+ * @arp_ac_category: ARP AC category
+ * @enable_phy_reg_retention: Enable PHY reg retention
+ * @upper_brssi_thresh: Upper BRSSI threshold
+ * @lower_brssi_thresh: Lower BRSSI threshold
+ * @enable_dtim_1chrx: Enable/disable DTIM 1 CHRX
+ * @alternative_chainmask_enabled: Alternate chainmask
+ * @smart_chainmask_enabled: Enable/disable chainmask
+ * @get_rts_profile: Set the RTS profile
+ * @enable_fw_log_level: Set the FW log level
+ * @enable_fw_log_type: Set the FW log type
+ * @is_rate_limit_enabled: Enable/disable RA rate limited
+ * @tsf_gpio_pin: TSF GPIO Pin config
+ * @enable_dhcp_server_offload: DHCP Offload is enabled or not
+ * @dhcp_max_num_clients: Max number of DHCP client supported
+ */
+struct wlan_fwol_cfg {
+	/* Add CFG and INI items here */
+	struct wlan_fwol_coex_config coex_config;
+	struct wlan_fwol_thermal_temp thermal_temp_cfg;
+	struct wlan_fwol_ie_whitelist ie_whitelist_cfg;
+	bool ani_enabled;
+	bool enable_rts_sifsbursting;
+	uint8_t max_mpdus_inampdu;
+	uint32_t arp_ac_category;
+	uint8_t enable_phy_reg_retention;
+	uint16_t upper_brssi_thresh;
+	uint16_t lower_brssi_thresh;
+	bool enable_dtim_1chrx;
+	bool alternative_chainmask_enabled;
+	bool smart_chainmask_enabled;
+	uint16_t get_rts_profile;
+	uint16_t enable_fw_log_level;
+	uint16_t enable_fw_log_type;
+#ifdef FEATURE_WLAN_RA_FILTERING
+	bool is_rate_limit_enabled;
+#endif
+#ifdef WLAN_FEATURE_TSF
+	uint32_t tsf_gpio_pin;
+#endif
+#ifdef DHCP_SERVER_OFFLOAD
+	bool enable_dhcp_server_offload;
+	uint32_t dhcp_max_num_clients;
+#endif
+};
+
+/**
+ * struct wlan_fwol_psoc_obj - FW offload psoc priv object
+ * @cfg:     cfg items
+ */
+struct wlan_fwol_psoc_obj {
+	struct wlan_fwol_cfg cfg;
+};
+
+/**
+ * wlan_psoc_get_fwol_obj() - private API to get fwol object from psoc
+ * @psoc: psoc object
+ *
+ * Return: fwol object
+ */
+struct wlan_fwol_psoc_obj *fwol_get_psoc_obj(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * fwol_cfg_on_psoc_enable() - Populate FWOL structure from CFG and INI
+ * @psoc: pointer to the psoc object
+ *
+ * Populate the FWOL CFG structure from CFG and INI values using CFG APIs
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS fwol_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * fwol_cfg_on_psoc_disable() - Clear the CFG structure on psoc disable
+ * @psoc: pointer to the psoc object
+ *
+ * Clear the FWOL CFG structure on psoc disable
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS fwol_cfg_on_psoc_disable(struct wlan_objmgr_psoc *psoc);
+#endif
diff --git a/components/fw_offload/core/src/wlan_fw_offload_main.c b/components/fw_offload/core/src/wlan_fw_offload_main.c
new file mode 100644
index 0000000..f98463e
--- /dev/null
+++ b/components/fw_offload/core/src/wlan_fw_offload_main.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2018 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 internal APIs related to the fwol component
+ */
+
+#include "wlan_fw_offload_main.h"
+
+struct wlan_fwol_psoc_obj *fwol_get_psoc_obj(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_get_comp_private_obj(psoc,
+						     WLAN_UMAC_COMP_FWOL);
+}
+
+static void
+fwol_init_coex_config_in_cfg(struct wlan_objmgr_psoc *psoc,
+			     struct wlan_fwol_coex_config *coex_config)
+{
+	coex_config->btc_mode = cfg_get(psoc, CFG_BTC_MODE);
+	coex_config->antenna_isolation = cfg_get(psoc, CFG_ANTENNA_ISOLATION);
+	coex_config->max_tx_power_for_btc =
+				cfg_get(psoc, CFG_MAX_TX_POWER_FOR_BTC);
+	coex_config->wlan_low_rssi_threshold =
+				cfg_get(psoc, CFG_WLAN_LOW_RSSI_THRESHOLD);
+	coex_config->bt_low_rssi_threshold =
+				cfg_get(psoc, CFG_BT_LOW_RSSI_THRESHOLD);
+	coex_config->bt_interference_low_ll =
+				cfg_get(psoc, CFG_BT_INTERFERENCE_LOW_LL);
+	coex_config->bt_interference_low_ul =
+				cfg_get(psoc, CFG_BT_INTERFERENCE_LOW_UL);
+	coex_config->bt_interference_medium_ll =
+				cfg_get(psoc, CFG_BT_INTERFERENCE_MEDIUM_LL);
+	coex_config->bt_interference_medium_ul =
+				cfg_get(psoc, CFG_BT_INTERFERENCE_MEDIUM_UL);
+	coex_config->bt_interference_high_ll =
+				cfg_get(psoc, CFG_BT_INTERFERENCE_HIGH_LL);
+	coex_config->bt_interference_high_ul =
+				cfg_get(psoc, CFG_BT_INTERFERENCE_HIGH_UL);
+}
+
+static void
+fwol_init_thermal_temp_in_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_fwol_thermal_temp *thermal_temp)
+{
+	thermal_temp->thermal_temp_min_level0 =
+				cfg_get(psoc, CFG_THERMAL_TEMP_MIN_LEVEL0);
+	thermal_temp->thermal_temp_max_level0 =
+				cfg_get(psoc, CFG_THERMAL_TEMP_MAX_LEVEL0);
+	thermal_temp->thermal_temp_min_level1 =
+				cfg_get(psoc, CFG_THERMAL_TEMP_MIN_LEVEL1);
+	thermal_temp->thermal_temp_max_level1 =
+				cfg_get(psoc, CFG_THERMAL_TEMP_MAX_LEVEL1);
+	thermal_temp->thermal_temp_min_level2 =
+				cfg_get(psoc, CFG_THERMAL_TEMP_MIN_LEVEL2);
+	thermal_temp->thermal_temp_max_level2 =
+				cfg_get(psoc, CFG_THERMAL_TEMP_MAX_LEVEL2);
+	thermal_temp->thermal_temp_min_level3 =
+				cfg_get(psoc, CFG_THERMAL_TEMP_MIN_LEVEL3);
+	thermal_temp->thermal_temp_max_level3 =
+				cfg_get(psoc, CFG_THERMAL_TEMP_MAX_LEVEL3);
+}
+
+/**
+ * fwol_parse_probe_req_ouis - form ouis from ini gProbeReqOUIs
+ * @psoc: Pointer to struct wlan_objmgr_psoc context
+ * @whitelist: Pointer to struct wlan_fwol_ie_whitelist
+ *
+ * This function parses the ini string gProbeReqOUIs which needs be to in the
+ * following format:
+ * "<8 characters of [0-9] or [A-F]>space<8 characters from [0-9] etc.,"
+ * example: "AABBCCDD 1122EEFF"
+ * and the logic counts the number of OUIS and allocates the memory
+ * for every valid OUI and is stored in struct hdd_context
+ *
+ * Return: None
+ */
+static void fwol_parse_probe_req_ouis(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_fwol_ie_whitelist *whitelist)
+{
+	uint8_t probe_req_ouis[MAX_PRB_REQ_VENDOR_OUI_INI_LEN] = {0};
+	uint32_t *voui = whitelist->probe_req_voui;
+	char *str;
+	uint8_t *token;
+	uint32_t oui_indx = 0;
+	int ret;
+	uint32_t hex_value;
+
+	qdf_str_lcopy(probe_req_ouis, cfg_get(psoc, CFG_PROBE_REQ_OUI),
+		      MAX_PRB_REQ_VENDOR_OUI_INI_LEN);
+	str = probe_req_ouis;
+	whitelist->no_of_probe_req_ouis = 0;
+
+	if (!qdf_str_len(str)) {
+		fwol_info("NO OUIs to parse");
+		return;
+	}
+
+	token = strsep(&str, " ");
+	while (token) {
+		if (qdf_str_len(token) != 8)
+			goto next_token;
+
+		ret = qdf_kstrtouint(token, 16, &hex_value);
+		if (ret)
+			goto next_token;
+
+		voui[oui_indx++] = cpu_to_be32(hex_value);
+		if (oui_indx >= MAX_PROBE_REQ_OUIS)
+			break;
+next_token:
+		token = strsep(&str, " ");
+	}
+
+	if (!oui_indx) {
+		whitelist->ie_whitelist = false;
+		return;
+	}
+
+	whitelist->no_of_probe_req_ouis = oui_indx;
+}
+
+/**
+ * fwol_validate_ie_bitmaps() - Validate all IE whitelist bitmap param values
+ * @psoc: Pointer to struct wlan_objmgr_psoc
+ * @whitelist: Pointer to struct wlan_fwol_ie_whitelist
+ *
+ * Return: True if all bitmap values are valid, else false
+ */
+static bool fwol_validate_ie_bitmaps(struct wlan_objmgr_psoc *psoc,
+				     struct wlan_fwol_ie_whitelist *whitelist)
+{
+	if (!(whitelist->ie_bitmap_0 && whitelist->ie_bitmap_1 &&
+	      whitelist->ie_bitmap_2 && whitelist->ie_bitmap_3 &&
+	      whitelist->ie_bitmap_4 && whitelist->ie_bitmap_5 &&
+	      whitelist->ie_bitmap_6 && whitelist->ie_bitmap_7))
+		return false;
+
+	/*
+	 * check whether vendor oui IE is set and OUIs are present, each OUI
+	 * is entered in the form of string of 8 characters from ini, therefore,
+	 * for atleast one OUI, minimum length is 8 and hence this string length
+	 * is checked for minimum of 8
+	 */
+	if ((whitelist->ie_bitmap_6 & VENDOR_SPECIFIC_IE_BITMAP) &&
+	    (qdf_str_len(cfg_get(psoc, CFG_PROBE_REQ_OUI)) < 8))
+		return false;
+
+	/* check whether vendor oui IE is not set but OUIs are present */
+	if (!(whitelist->ie_bitmap_6 & VENDOR_SPECIFIC_IE_BITMAP) &&
+	    (qdf_str_len(cfg_get(psoc, CFG_PROBE_REQ_OUI)) > 0))
+		return false;
+
+	return true;
+}
+
+static void
+fwol_init_ie_whiltelist_in_cfg(struct wlan_objmgr_psoc *psoc,
+			       struct wlan_fwol_ie_whitelist *whitelist)
+{
+	whitelist->ie_whitelist = cfg_get(psoc, CFG_PROBE_REQ_IE_WHITELIST);
+	whitelist->ie_bitmap_0 = cfg_get(psoc, CFG_PROBE_REQ_IE_BIT_MAP0);
+	whitelist->ie_bitmap_1 = cfg_get(psoc, CFG_PROBE_REQ_IE_BIT_MAP1);
+	whitelist->ie_bitmap_2 = cfg_get(psoc, CFG_PROBE_REQ_IE_BIT_MAP2);
+	whitelist->ie_bitmap_3 = cfg_get(psoc, CFG_PROBE_REQ_IE_BIT_MAP3);
+	whitelist->ie_bitmap_4 = cfg_get(psoc, CFG_PROBE_REQ_IE_BIT_MAP4);
+	whitelist->ie_bitmap_5 = cfg_get(psoc, CFG_PROBE_REQ_IE_BIT_MAP5);
+	whitelist->ie_bitmap_6 = cfg_get(psoc, CFG_PROBE_REQ_IE_BIT_MAP6);
+	whitelist->ie_bitmap_7 = cfg_get(psoc, CFG_PROBE_REQ_IE_BIT_MAP7);
+	if (!fwol_validate_ie_bitmaps(psoc, whitelist))
+		whitelist->ie_whitelist = false;
+	fwol_parse_probe_req_ouis(psoc, whitelist);
+}
+
+/**
+ * ucfg_fwol_fetch_dhcp_server_settings: Populate the enable_dhcp_server_offload
+ * and dhcp_max_num_clients from cfg
+ * @psoc: The global psoc handler
+ * @fwol_cfg: The cfg structure
+ *
+ * Return: none
+ */
+#ifdef DHCP_SERVER_OFFLOAD
+static void ucfg_fwol_fetch_dhcp_server_settings(struct wlan_objmgr_psoc *psoc,
+						 struct wlan_fwol_cfg *fwol_cfg)
+{
+	fwol_cfg->enable_dhcp_server_offload =
+			cfg_get(psoc, CFG_DHCP_SERVER_OFFLOAD_SUPPORT);
+	fwol_cfg->dhcp_max_num_clients =
+			cfg_get(psoc, CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT);
+}
+#else
+static void ucfg_fwol_fetch_dhcp_server_settings(struct wlan_objmgr_psoc *psoc,
+						 struct wlan_fwol_cfg *fwol_cfg)
+{
+}
+#endif
+
+/**
+ * ucfg_fwol_fetch_tsf_gpio_pin: Populate the tsf_gpio_pin from cfg
+ * @psoc: The global psoc handler
+ * @fwol_cfg: The cfg structure
+ *
+ * Return: none
+ */
+#ifdef WLAN_FEATURE_TSF
+static void ucfg_fwol_fetch_tsf_gpio_pin(struct wlan_objmgr_psoc *psoc,
+					 struct wlan_fwol_cfg *fwol_cfg)
+{
+	fwol_cfg->tsf_gpio_pin = cfg_get(psoc, CFG_SET_TSF_GPIO_PIN);
+}
+#else
+static void ucfg_fwol_fetch_tsf_gpio_pin(struct wlan_objmgr_psoc *psoc,
+					 struct wlan_fwol_cfg *fwol_cfg)
+{
+}
+#endif
+
+/**
+ * ucfg_fwol_fetch_ra_filter: Populate the RA filter enabled or not from cfg
+ * @psoc: The global psoc handler
+ * @fwol_cfg: The cfg structure
+ *
+ * Return: none
+ */
+#ifdef FEATURE_WLAN_RA_FILTERING
+static void ucfg_fwol_fetch_ra_filter(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_fwol_cfg *fwol_cfg)
+{
+	fwol_cfg->is_rate_limit_enabled = cfg_get(psoc, CFG_RA_FILTER_ENABLE);
+}
+#else
+static void ucfg_fwol_fetch_ra_filter(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_fwol_cfg *fwol_cfg)
+{
+}
+#endif
+
+QDF_STATUS fwol_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_cfg *fwol_cfg;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	fwol_cfg = &fwol_obj->cfg;
+
+	fwol_init_coex_config_in_cfg(psoc, &fwol_cfg->coex_config);
+	fwol_init_thermal_temp_in_cfg(psoc, &fwol_cfg->thermal_temp_cfg);
+	fwol_init_ie_whiltelist_in_cfg(psoc, &fwol_cfg->ie_whitelist_cfg);
+	fwol_cfg->ani_enabled = cfg_get(psoc, CFG_ENABLE_ANI);
+	fwol_cfg->enable_rts_sifsbursting =
+				cfg_get(psoc, CFG_SET_RTS_FOR_SIFS_BURSTING);
+	fwol_cfg->max_mpdus_inampdu = cfg_get(psoc, CFG_MAX_MPDUS_IN_AMPDU);
+	fwol_cfg->arp_ac_category = cfg_get(psoc, CFG_ARP_AC_CATEGORY);
+	fwol_cfg->enable_phy_reg_retention = cfg_get(psoc, CFG_ENABLE_PHY_REG);
+	fwol_cfg->upper_brssi_thresh = cfg_get(psoc, CFG_UPPER_BRSSI_THRESH);
+	fwol_cfg->lower_brssi_thresh = cfg_get(psoc, CFG_LOWER_BRSSI_THRESH);
+	fwol_cfg->enable_dtim_1chrx = cfg_get(psoc, CFG_DTIM_1CHRX_ENABLE);
+	fwol_cfg->alternative_chainmask_enabled =
+				cfg_get(psoc, CFG_ENABLE_COEX_ALT_CHAINMASK);
+	fwol_cfg->smart_chainmask_enabled =
+				cfg_get(psoc, CFG_ENABLE_SMART_CHAINMASK);
+	fwol_cfg->get_rts_profile = cfg_get(psoc, CFG_ENABLE_FW_RTS_PROFILE);
+	fwol_cfg->enable_fw_log_level =
+				cfg_get(psoc, CFG_ENABLE_FW_DEBUG_LOG_LEVEL);
+	fwol_cfg->enable_fw_log_type = cfg_get(psoc, CFG_ENABLE_FW_LOG_TYPE);
+	ucfg_fwol_fetch_ra_filter(psoc, fwol_cfg);
+	ucfg_fwol_fetch_tsf_gpio_pin(psoc, fwol_cfg);
+	ucfg_fwol_fetch_dhcp_server_settings(psoc, fwol_cfg);
+
+	return status;
+}
+
+QDF_STATUS fwol_cfg_on_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	/* Clear the CFG structure */
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/components/fw_offload/dispatcher/inc/cfg_coex.h b/components/fw_offload/dispatcher/inc/cfg_coex.h
new file mode 100644
index 0000000..11f68c0
--- /dev/null
+++ b/components/fw_offload/dispatcher/inc/cfg_coex.h
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2012 - 2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_COEX_H
+#define __CFG_COEX_H
+
+/*
+ * <ini>
+ * gSetBTCMode - Config BTC mode
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * 0 - TDD
+ * 1 - FDD
+ * 2 - Hybrid
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BTC_MODE CFG_INI_UINT( \
+			"gSetBTCMode", \
+			0, \
+			2, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"BTC mode")
+
+/*
+ * <ini>
+ * gSetAntennaIsolation - Set Antenna Isolation
+ * @Min: 0
+ * @Max: 255
+ * @Default: 25
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ANTENNA_ISOLATION CFG_INI_UINT( \
+			"gSetAntennaIsolation", \
+			0, \
+			255, \
+			25, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Antenna Isolation")
+
+/*
+ * <ini>
+ * gSetMaxTxPowerForBTC - Set Max WLAN Tx power in COEX scenario
+ * @Min: 0
+ * @Max: 100
+ * @Default: 100
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_MAX_TX_POWER_FOR_BTC CFG_INI_UINT( \
+			"gSetMaxTxPowerForBTC", \
+			0, \
+			100, \
+			100, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Max Tx Power for BTC")
+
+/*
+ * <ini>
+ * gSetWlanLowRssiThreshold - Set WLAN low RSSI threshold for BTC mode switching
+ * @Min: -100
+ * @Max: 0
+ * @Default: -80
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_WLAN_LOW_RSSI_THRESHOLD CFG_INI_INT( \
+			"gSetWlanLowRssiThreshold", \
+			-100, \
+			0, \
+			-80, \
+			CFG_VALUE_OR_DEFAULT, \
+			"WLAN Low RSSI Threshold")
+
+/*
+ * <ini>
+ * gSetBtLowRssiThreshold - Set BT low RSSI threshold for BTC mode switching
+ * @Min: -100
+ * @Max: 0
+ * @Default: -80
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BT_LOW_RSSI_THRESHOLD CFG_INI_INT( \
+			"gSetBtLowRssiThreshold", \
+			-100, \
+			0, \
+			-80, \
+			CFG_VALUE_OR_DEFAULT, \
+			"BT Low RSSI Threshold")
+
+/*
+ * <ini>
+ * gSetBtInterferenceLowLL - Set lower limit of low level BT interference
+ * @Min: -100
+ * @Max: 100
+ * @Default: -25
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BT_INTERFERENCE_LOW_LL CFG_INI_INT( \
+			"gSetBtInterferenceLowLL", \
+			-100, \
+			100, \
+			-25, \
+			CFG_VALUE_OR_DEFAULT, \
+			"BT Interference Low LL")
+
+/*
+ * <ini>
+ * gSetBtInterferenceLowUL - Set upper limit of low level BT interference
+ * @Min: -100
+ * @Max: 100
+ * @Default: -21
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BT_INTERFERENCE_LOW_UL CFG_INI_INT( \
+			"gSetBtInterferenceLowUL", \
+			-100, \
+			100, \
+			-21, \
+			CFG_VALUE_OR_DEFAULT, \
+			"BT Interference Low UL")
+
+/*
+ * <ini>
+ * gSetBtInterferenceMediumLL - Set lower limit of medium level BT interference
+ * @Min: -100
+ * @Max: 100
+ * @Default: -20
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BT_INTERFERENCE_MEDIUM_LL CFG_INI_INT( \
+			"gSetBtInterferenceMediumLL", \
+			-100, \
+			100, \
+			-20, \
+			CFG_VALUE_OR_DEFAULT, \
+			"BT Interference Medium LL")
+
+/*
+ * <ini>
+ * gSetBtInterferenceMediumUL - Set upper limit of medium level BT interference
+ * @Min: -100
+ * @Max: 100
+ * @Default: -16
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BT_INTERFERENCE_MEDIUM_UL CFG_INI_INT( \
+			"gSetBtInterferenceMediumUL", \
+			-100, \
+			100, \
+			-16, \
+			CFG_VALUE_OR_DEFAULT, \
+			"BT Interference Medium UL")
+
+/*
+ * <ini>
+ * gSetBtInterferenceHighLL - Set lower limit of high level BT interference
+ * @Min: -100
+ * @Max: 100
+ * @Default: -15
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BT_INTERFERENCE_HIGH_LL CFG_INI_INT( \
+			"gSetBtInterferenceHighLL", \
+			-100, \
+			100, \
+			-15, \
+			CFG_VALUE_OR_DEFAULT, \
+			"BT Interference High LL")
+
+/*
+ * <ini>
+ * gSetBtInterferenceHighUL - Set upper limit of high level BT interference
+ * @Min: -100
+ * @Max: 100
+ * @Default: -11
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BT_INTERFERENCE_HIGH_UL CFG_INI_INT( \
+			"gSetBtInterferenceHighUL", \
+			-100, \
+			100, \
+			-11, \
+			CFG_VALUE_OR_DEFAULT, \
+			"BT Interference High UL")
+
+#define CFG_COEX_ALL \
+	CFG(CFG_BTC_MODE) \
+	CFG(CFG_ANTENNA_ISOLATION) \
+	CFG(CFG_MAX_TX_POWER_FOR_BTC) \
+	CFG(CFG_WLAN_LOW_RSSI_THRESHOLD) \
+	CFG(CFG_BT_LOW_RSSI_THRESHOLD) \
+	CFG(CFG_BT_INTERFERENCE_LOW_LL) \
+	CFG(CFG_BT_INTERFERENCE_LOW_UL) \
+	CFG(CFG_BT_INTERFERENCE_MEDIUM_LL) \
+	CFG(CFG_BT_INTERFERENCE_MEDIUM_UL) \
+	CFG(CFG_BT_INTERFERENCE_HIGH_LL) \
+	CFG(CFG_BT_INTERFERENCE_HIGH_UL)
+#endif
diff --git a/components/fw_offload/dispatcher/inc/cfg_fwol.h b/components/fw_offload/dispatcher/inc/cfg_fwol.h
new file mode 100644
index 0000000..91a2f75
--- /dev/null
+++ b/components/fw_offload/dispatcher/inc/cfg_fwol.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012 - 2018 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.
+ */
+
+#ifndef __CFG_FWOL_H
+#define __CFG_FWOL_H
+
+#include "cfg_define.h"
+#include "cfg_converged.h"
+#include "qdf_types.h"
+#include "cfg_coex.h"
+#include "cfg_thermal_temp.h"
+#include "cfg_ie_whitelist.h"
+#include "cfg_fwol_generic.h"
+
+#define CFG_FWOL_ALL \
+	CFG_COEX_ALL \
+	CFG_FWOL_GENERIC_ALL \
+	CFG_IE_WHITELIST \
+	CFG_THERMAL_TEMP_ALL
+
+#endif /* __CFG_FWOL_H */
+
diff --git a/components/fw_offload/dispatcher/inc/cfg_fwol_generic.h b/components/fw_offload/dispatcher/inc/cfg_fwol_generic.h
new file mode 100644
index 0000000..c04bb60
--- /dev/null
+++ b/components/fw_offload/dispatcher/inc/cfg_fwol_generic.h
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_FWOL_GENERIC_H
+#define __CFG_FWOL_GENERIC_H
+
+
+/*
+ *
+ * <ini>
+ * gEnableANI - Enable Adaptive Noise Immunity
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable or disable Adaptive Noise Immunity.
+ *
+ * Related: None
+ *
+ * Supported Feature: ANI
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_ANI CFG_INI_BOOL( \
+		"gEnableANI", \
+		1, \
+		"Enable/Disable Adaptive Noise Immunity")
+
+/**
+ * gSetRTSForSIFSBursting - set rts for sifs bursting
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini set rts for sifs bursting
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SET_RTS_FOR_SIFS_BURSTING CFG_INI_BOOL( \
+		"gSetRTSForSIFSBursting", \
+		0, \
+		"Set rts for sifs bursting")
+
+/**
+ * <ini>
+ * gMaxMPDUsInAMPDU - max mpdus in ampdu
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * This ini configure max mpdus in ampdu
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_MAX_MPDUS_IN_AMPDU CFG_INI_INT( \
+		"gMaxMPDUsInAMPDU", \
+		0, \
+		64, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"This ini configure max mpdus in ampdu")
+
+/**
+ * arp_ac_category - ARP access category
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * Firmware by default categorizes ARP packets with VOICE TID.
+ * This ini shall be used to override the default configuration.
+ * Access category enums are referenced in ieee80211_common.h
+ * WME_AC_BE = 0 (Best effort)
+ * WME_AC_BK = 1 (Background)
+ * WME_AC_VI = 2 (Video)
+ * WME_AC_VO = 3 (Voice)
+ *
+ * Related: none
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ARP_AC_CATEGORY CFG_INI_INT( \
+		"arp_ac_category", \
+		0, \
+		3, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Override the default ARP AC configuration")
+
+/*
+ * </ini>
+ * gEnableFastPwrTransition - Configuration for fast power transition
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * This ini supported values:
+ * 0x0: Phy register retention disabled (Higher timeline, Good for power)
+ * 0x1: Phy register retention statically enabled
+ * 0x2: Phy register retention enabled/disabled dynamically
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_PHY_REG CFG_INI_UINT( \
+		"gEnableFastPwrTransition", \
+		0x0, \
+		0x2, \
+		0x0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Configuration for fast power transition")
+
+/*
+ * <ini>
+ * gUpperBrssiThresh - Sets Upper threshold for beacon RSSI
+ * @Min: 36
+ * @Max: 66
+ * @Default: 46
+ *
+ * This ini sets Upper beacon threshold for beacon RSSI in FW
+ * Used to reduced RX chainmask in FW, once this threshold is
+ * reached FW will switch to 1X1 (Single chain).
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_UPPER_BRSSI_THRESH CFG_INI_UINT( \
+		"gUpperBrssiThresh", \
+		36, \
+		66, \
+		46, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Sets Upper threshold for beacon RSSI")
+
+/*
+ * <ini>
+ * gLowerrBrssiThresh - Sets Lower threshold for beacon RSSI
+ * @Min: 6
+ * @Max: 36
+ * @Default: 26
+ *
+ * This ini sets Lower beacon threshold for beacon RSSI in FW
+ * Used to increase RX chainmask in FW, once this threshold is
+ * reached FW will switch to 2X2 chain.
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LOWER_BRSSI_THRESH CFG_INI_UINT( \
+		"gLowerBrssiThresh", \
+		6, \
+		36, \
+		26, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Sets Lower threshold for beacon RSSI")
+
+/*
+ * <ini>
+ * gDtim1ChRxEnable - Enable/Disable DTIM 1Chrx feature
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini Enables or Disables DTIM 1CHRX feature in FW
+ * If this flag is set FW enables shutting off one chain
+ * while going to power save.
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_DTIM_1CHRX_ENABLE CFG_INI_BOOL( \
+		"gDtim1ChRxEnable", \
+		1, \
+		"Enable/Disable DTIM 1Chrx feature")
+
+/*
+ * <ini>
+ * gEnableAlternativeChainmask - Enable Co-Ex Alternative Chainmask
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable the Co-ex Alternative Chainmask
+ * feature via the WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME
+ * firmware parameter.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_COEX_ALT_CHAINMASK CFG_INI_BOOL( \
+		"gEnableAlternativeChainmask", \
+		0, \
+		"Enable Co-Ex Alternative Chainmask")
+
+/*
+ * <ini>
+ * gEnableSmartChainmask - Enable Smart Chainmask
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable the Smart Chainmask feature via
+ * the WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME firmware parameter.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_SMART_CHAINMASK CFG_INI_BOOL( \
+		"gEnableSmartChainmask", \
+		0, \
+		"Enable/disable the Smart Chainmask feature")
+
+/*
+ * <ini>
+ * gEnableRTSProfiles - It will use configuring different RTS profiles
+ * @Min: 0
+ * @Max: 66
+ * @Default: 33
+ *
+ * This ini used for configuring different RTS profiles
+ * to firmware.
+ * Following are the valid values for the rts profile:
+ * RTSCTS_DISABLED				0
+ * NOT_ALLOWED					1
+ * NOT_ALLOWED					2
+ * RTSCTS_DISABLED				16
+ * RTSCTS_ENABLED_4_SECOND_RATESERIES		17
+ * CTS2SELF_ENABLED_4_SECOND_RATESERIES		18
+ * RTSCTS_DISABLED				32
+ * RTSCTS_ENABLED_4_SWRETRIES			33
+ * CTS2SELF_ENABLED_4_SWRETRIES			34
+ * NOT_ALLOWED					48
+ * NOT_ALLOWED					49
+ * NOT_ALLOWED					50
+ * RTSCTS_DISABLED				64
+ * RTSCTS_ENABLED_4_ALL_RATESERIES		65
+ * CTS2SELF_ENABLED_4_ALL_RATESERIES		66
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_FW_RTS_PROFILE CFG_INI_INT( \
+		"gEnableRTSProfiles", \
+		0, \
+		66, \
+		33, \
+		CFG_VALUE_OR_DEFAULT, \
+		"It is used to configure different RTS profiles")
+
+/* <ini>
+ * gFwDebugLogLevel: Takes values from enum DBGLOG_LOG_LVL,
+ * make default value as DBGLOG_WARN to enable error and
+ * warning logs by default.
+ * @Min: 0
+ * @Max: 255
+ * @Default: 3
+ *
+ * Related: None
+ *
+ * Supported Features: Debugging
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_FW_DEBUG_LOG_LEVEL CFG_INI_INT( \
+		"gFwDebugLogLevel", \
+		0, \
+		255, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"enable error and warning logs by default")
+
+/* <ini>
+ * gFwDebugLogType: takes values from enum dbglog_process_t,
+ * make default value as DBGLOG_PROCESS_NET_RAW to give the
+ * logs to net link since cnss_diag service is started at boot
+ * time by default.
+ * @Min: 0
+ * @Max: 255
+ * @Default: 3
+ *
+ * Related: None
+ *
+ * Supported Features: Debugging
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_FW_LOG_TYPE CFG_INI_INT( \
+		"gFwDebugLogType", \
+		0, \
+		255, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Default value to be given to the net link cnss_diag service")
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+/* <ini>
+ * gRAFilterEnable
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * Related: None
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_RA_FILTER_ENABLE CFG_INI_BOOL( \
+		"gRAFilterEnable", \
+		1, \
+		"Enable RA Filter")
+#else
+#define CFG_RA_FILTER_ENABLE
+#endif
+
+/* <ini>
+ * gtsf_gpio_pin
+ * @Min: 0
+ * @Max: 254
+ * @Default: 255
+ *
+ * GPIO pin to toggle when capture tsf
+ *
+ * Related: None
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_SET_TSF_GPIO_PIN CFG_INI_INT( \
+		"gtsf_gpio_pin", \
+		0, \
+		254, \
+		255, \
+		CFG_VALUE_OR_DEFAULT, \
+		"GPIO pin to toggle when capture tsf")
+
+#ifdef DHCP_SERVER_OFFLOAD
+/* <ini>
+ * gEnableDeauthToDisassocMap
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * DHCP Server offload support
+ *
+ * Related: None
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DHCP_SERVER_OFFLOAD_SUPPORT CFG_INI_BOOL( \
+		"gEnableDeauthToDisassocMap", \
+		0, \
+		"DHCP Server offload support")
+
+/* <ini>
+ * gDHCPMaxNumClients
+ * @Min: 1
+ * @Max: 8
+ * @Default: 8
+ *
+ * Number of DHCP server offload clients
+ *
+ * Related: None
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT CFG_INI_INT( \
+		"gDHCPMaxNumClients", \
+		1, \
+		8, \
+		8, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Number of DHCP server offload clients")
+
+#define CFG_FWOL_DHCP \
+		CFG(CFG_DHCP_SERVER_OFFLOAD_SUPPORT) \
+		CFG(CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT)
+
+#else
+#define CFG_FWOL_DHCP
+#endif
+
+#define CFG_FWOL_GENERIC_ALL \
+	CFG_FWOL_DHCP \
+	CFG(CFG_ENABLE_ANI) \
+	CFG(CFG_SET_RTS_FOR_SIFS_BURSTING) \
+	CFG(CFG_MAX_MPDUS_IN_AMPDU) \
+	CFG(CFG_ARP_AC_CATEGORY) \
+	CFG(CFG_ENABLE_PHY_REG) \
+	CFG(CFG_UPPER_BRSSI_THRESH) \
+	CFG(CFG_LOWER_BRSSI_THRESH) \
+	CFG(CFG_DTIM_1CHRX_ENABLE) \
+	CFG(CFG_ENABLE_COEX_ALT_CHAINMASK) \
+	CFG(CFG_ENABLE_SMART_CHAINMASK) \
+	CFG(CFG_ENABLE_FW_RTS_PROFILE) \
+	CFG(CFG_ENABLE_FW_DEBUG_LOG_LEVEL) \
+	CFG(CFG_ENABLE_FW_LOG_TYPE) \
+	CFG(CFG_RA_FILTER_ENABLE) \
+	CFG(CFG_SET_TSF_GPIO_PIN)
+
+#endif
diff --git a/components/fw_offload/dispatcher/inc/cfg_ie_whitelist.h b/components/fw_offload/dispatcher/inc/cfg_ie_whitelist.h
new file mode 100644
index 0000000..a526d7b
--- /dev/null
+++ b/components/fw_offload/dispatcher/inc/cfg_ie_whitelist.h
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_IE_WHITELIST_H
+#define __CFG_IE_WHITELIST_H
+
+/*
+ * <ini>
+ * g_enable_probereq_whitelist_ies - Enable IE white listing
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable probe request IE white listing feature.
+ * Values 0 and 1 are used to disable and enable respectively, by default this
+ * feature is disabled.
+ *
+ * Related: None
+ *
+ * Supported Feature: Probe request IE whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PROBE_REQ_IE_WHITELIST CFG_INI_BOOL( \
+			"g_enable_probereq_whitelist_ies", \
+			0, \
+			"Enable IE whitelisting")
+
+/*
+ * For IE white listing in Probe Req, following ini parameters from
+ * g_probe_req_ie_bitmap_0 to g_probe_req_ie_bitmap_7 are used. User needs to
+ * input this values in hexa decimal format, when bit is set in bitmap,
+ * corresponding IE needs to be included in probe request.
+ *
+ * Example:
+ * ========
+ * If IE 221 needs to be in the probe request, set the corresponding bit
+ * as follows:
+ * a= IE/32 = 221/32 = 6 = g_probe_req_ie_bitmap_6
+ * b = IE modulo 32 = 29,
+ * means set the bth bit in g_probe_req_ie_bitmap_a,
+ * therefore set 29th bit in g_probe_req_ie_bitmap_6,
+ * as a result, g_probe_req_ie_bitmap_6=20000000
+ *
+ * Note: For IE 221, its mandatory to set the gProbeReqOUIs.
+ */
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_0 - Used to set the bitmap of IEs from 0 to 31
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 0 to 31 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PROBE_REQ_IE_BIT_MAP0 CFG_INI_UINT( \
+			"g_probe_req_ie_bitmap_0", \
+			0x00000000, \
+			0xFFFFFFFF, \
+			0x00000000, \
+			CFG_VALUE_OR_DEFAULT, \
+			"IE Bitmap 0")
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_1 - Used to set the bitmap of IEs from 32 to 63
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 32 to 63 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PROBE_REQ_IE_BIT_MAP1 CFG_INI_UINT( \
+			"g_probe_req_ie_bitmap_1", \
+			0x00000000, \
+			0xFFFFFFFF, \
+			0x00000000, \
+			CFG_VALUE_OR_DEFAULT, \
+			"IE Bitmap 1")
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_2 - Used to set the bitmap of IEs from 64 to 95
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 64 to 95 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PROBE_REQ_IE_BIT_MAP2 CFG_INI_UINT( \
+			"g_probe_req_ie_bitmap_2", \
+			0x00000000, \
+			0xFFFFFFFF, \
+			0x00000000, \
+			CFG_VALUE_OR_DEFAULT, \
+			"IE Bitmap 2")
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_3 - Used to set the bitmap of IEs from 96 to 127
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 96 to 127 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PROBE_REQ_IE_BIT_MAP3 CFG_INI_UINT( \
+			"g_probe_req_ie_bitmap_3", \
+			0x00000000, \
+			0xFFFFFFFF, \
+			0x00000000, \
+			CFG_VALUE_OR_DEFAULT, \
+			"IE Bitmap 3")
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_4 - Used to set the bitmap of IEs from 128 to 159
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 128 to 159 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PROBE_REQ_IE_BIT_MAP4 CFG_INI_UINT( \
+			"g_probe_req_ie_bitmap_4", \
+			0x00000000, \
+			0xFFFFFFFF, \
+			0x00000000, \
+			CFG_VALUE_OR_DEFAULT, \
+			"IE Bitmap 4")
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_5 - Used to set the bitmap of IEs from 160 to 191
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 160 to 191 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PROBE_REQ_IE_BIT_MAP5 CFG_INI_UINT( \
+			"g_probe_req_ie_bitmap_5", \
+			0x00000000, \
+			0xFFFFFFFF, \
+			0x00000000, \
+			CFG_VALUE_OR_DEFAULT, \
+			"IE Bitmap 5")
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_6 - Used to set the bitmap of IEs from 192 to 223
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 192 to 223 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PROBE_REQ_IE_BIT_MAP6 CFG_INI_UINT( \
+			"g_probe_req_ie_bitmap_6", \
+			0x00000000, \
+			0xFFFFFFFF, \
+			0x00000000, \
+			CFG_VALUE_OR_DEFAULT, \
+			"IE Bitmap 6")
+
+/*
+ * <ini>
+ * g_probe_req_ie_bitmap_7 - Used to set the bitmap of IEs from 224 to 255
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to include the IEs from 224 to 255 in probe request,
+ * when corresponding bit is set.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PROBE_REQ_IE_BIT_MAP7 CFG_INI_UINT( \
+			"g_probe_req_ie_bitmap_7", \
+			0x00000000, \
+			0xFFFFFFFF, \
+			0x00000000, \
+			CFG_VALUE_OR_DEFAULT, \
+			"IE Bitmap 7")
+
+#define MAX_PRB_REQ_VENDOR_OUI_INI_LEN 160
+#define VENDOR_SPECIFIC_IE_BITMAP 0x20000000
+/*
+ * For vendor specific IE, Probe Req OUI types and sub types which are
+ * to be white listed are specified in gProbeReqOUIs in the following
+ * example format - gProbeReqOUIs=AABBCCDD EEFF1122
+ */
+
+/*
+ * <ini>
+ * gProbeReqOUIs - Used to specify vendor specific OUIs
+ * @Default: Empty string
+ *
+ * This ini is used to include the specified OUIs in vendor specific IE
+ * of probe request.
+ *
+ * Related: Need to enable g_enable_probereq_whitelist_ies and
+ * vendor specific IE should be set in g_probe_req_ie_bitmap_6.
+ *
+ * Supported Feature: Probe request ie whitelisting
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PROBE_REQ_OUI CFG_INI_STRING( \
+			"gProbeReqOUIs", \
+			0, \
+			MAX_PRB_REQ_VENDOR_OUI_INI_LEN, \
+			"", \
+			"Probe Req OUIs")
+
+#define CFG_IE_WHITELIST \
+	CFG(CFG_PROBE_REQ_IE_WHITELIST) \
+	CFG(CFG_PROBE_REQ_IE_BIT_MAP0) \
+	CFG(CFG_PROBE_REQ_IE_BIT_MAP1) \
+	CFG(CFG_PROBE_REQ_IE_BIT_MAP2) \
+	CFG(CFG_PROBE_REQ_IE_BIT_MAP3) \
+	CFG(CFG_PROBE_REQ_IE_BIT_MAP4) \
+	CFG(CFG_PROBE_REQ_IE_BIT_MAP5) \
+	CFG(CFG_PROBE_REQ_IE_BIT_MAP6) \
+	CFG(CFG_PROBE_REQ_IE_BIT_MAP7) \
+	CFG(CFG_PROBE_REQ_OUI)
+
+#endif
diff --git a/components/fw_offload/dispatcher/inc/cfg_thermal_temp.h b/components/fw_offload/dispatcher/inc/cfg_thermal_temp.h
new file mode 100644
index 0000000..328546e
--- /dev/null
+++ b/components/fw_offload/dispatcher/inc/cfg_thermal_temp.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_THERMAL_TEMP_H
+#define __CFG_THERMAL_TEMP_H
+
+#define CFG_THERMAL_TEMP_MIN_LEVEL0 CFG_INI_UINT( \
+			"gThermalTempMinLevel0", \
+			0, \
+			1000, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Thermal Temp Min Level0")
+
+#define CFG_THERMAL_TEMP_MAX_LEVEL0 CFG_INI_UINT( \
+			"gThermalTempMaxLevel0", \
+			0, \
+			1000, \
+			90, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Thermal Temp Max Level0")
+
+#define CFG_THERMAL_TEMP_MIN_LEVEL1 CFG_INI_UINT( \
+			"gThermalTempMinLevel1", \
+			0, \
+			1000, \
+			70, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Thermal Temp Min Level1")
+
+#define CFG_THERMAL_TEMP_MAX_LEVEL1 CFG_INI_UINT( \
+			"gThermalTempMaxLevel1", \
+			0, \
+			1000, \
+			110, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Thermal Temp Max Level1")
+
+#define CFG_THERMAL_TEMP_MIN_LEVEL2 CFG_INI_UINT( \
+			"gThermalTempMinLevel2", \
+			0, \
+			1000, \
+			90, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Thermal Temp Min Level2")
+
+#define CFG_THERMAL_TEMP_MAX_LEVEL2 CFG_INI_UINT( \
+			"gThermalTempMaxLevel2", \
+			0, \
+			1000, \
+			125, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Thermal Temp Max Level2")
+
+#define CFG_THERMAL_TEMP_MIN_LEVEL3 CFG_INI_UINT( \
+			"gThermalTempMinLevel3", \
+			0, \
+			1000, \
+			110, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Thermal Temp Min Level3")
+
+#define CFG_THERMAL_TEMP_MAX_LEVEL3 CFG_INI_UINT( \
+			"gThermalTempMaxLevel3", \
+			0, \
+			1000, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Thermal Temp Max Level3")
+
+#define CFG_THERMAL_TEMP_ALL \
+	CFG(CFG_THERMAL_TEMP_MIN_LEVEL0) \
+	CFG(CFG_THERMAL_TEMP_MAX_LEVEL0) \
+	CFG(CFG_THERMAL_TEMP_MIN_LEVEL1) \
+	CFG(CFG_THERMAL_TEMP_MAX_LEVEL1) \
+	CFG(CFG_THERMAL_TEMP_MIN_LEVEL2) \
+	CFG(CFG_THERMAL_TEMP_MAX_LEVEL2) \
+	CFG(CFG_THERMAL_TEMP_MIN_LEVEL3) \
+	CFG(CFG_THERMAL_TEMP_MAX_LEVEL3) \
+
+#endif
+
diff --git a/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h b/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h
new file mode 100644
index 0000000..cd103a7
--- /dev/null
+++ b/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2018 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 internal API related to the fwol component
+ */
+
+#ifndef _WLAN_FWOL_UCFG_API_H_
+#define _WLAN_FWOL_UCFG_API_H_
+
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_cmn.h>
+#include "wlan_fw_offload_main.h"
+
+#include "wlan_fw_offload_main.h"
+
+/**
+ * ucfg_fwol_psoc_open() - FWOL component Open
+ * @psoc: pointer to psoc object
+ *
+ * Open the FWOL component and initialize the FWOL structure
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_fwol_psoc_close() - FWOL component close
+ * @psoc: pointer to psoc object
+ *
+ * Close the FWOL component and clear the FWOL structures
+ *
+ * Return: None
+ */
+void ucfg_fwol_psoc_close(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_fwol_init() - initialize fwol_ctx context.
+ *
+ * This function initializes the fwol context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS ucfg_fwol_init(void);
+
+/**
+ * ucfg_fwol_deinit() - De initialize fwol_ctx context.
+ *
+ * This function De initializes fwol contex.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+void ucfg_fwol_deinit(void);
+
+/**
+ * ucfg_fwol_get_coex_config_params() - Get coex config params
+ * @psoc: Pointer to psoc object
+ * @coex_config: Pointer to struct wlan_fwol_coex_config
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+ucfg_fwol_get_coex_config_params(struct wlan_objmgr_psoc *psoc,
+				 struct wlan_fwol_coex_config *coex_config);
+
+/**
+ * ucfg_fwol_get_thermal_temp() - Get thermal temperature config params
+ * @psoc: Pointer to psoc object
+ * @thermal_temp: Pointer to struct wlan_fwol_thermal_temp
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_fwol_get_thermal_temp(struct wlan_objmgr_psoc *psoc,
+			   struct wlan_fwol_thermal_temp *thermal_temp);
+
+/**
+ * ucfg_fwol_get_ie_whitelist() - Get IE whitelist param value
+ * @psoc: Pointer to psoc object
+ * @ie_whitelist: Pointer to return the IE whitelist param value
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_fwol_get_ie_whitelist(struct wlan_objmgr_psoc *psoc, bool *ie_whitelist);
+
+/**
+ * ucfg_fwol_set_ie_whitelist() - Set IE whitelist param value
+ * @psoc: Pointer to psoc object
+ * @ie_whitelist: Value to set IE whitelist param
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_fwol_set_ie_whitelist(struct wlan_objmgr_psoc *psoc, bool ie_whitelist);
+
+/**
+ * ucfg_fwol_get_all_whitelist_params() - Get all IE whitelist param values
+ * @psoc: Pointer to psoc object
+ * @whitelist: Pointer to struct wlan_fwol_ie_whitelist
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_fwol_get_all_whitelist_params(struct wlan_objmgr_psoc *psoc,
+				   struct wlan_fwol_ie_whitelist *whitelist);
+
+/** ucfg_fwol_get_ani_enabled() - Assigns the ani_enabled value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_fwol_get_ani_enabled(struct wlan_objmgr_psoc *psoc,
+				     bool *ani_enabled);
+
+/**
+ * ucfg_fwol_get_ani_enabled() - Assigns the enable_rts_sifsbursting value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_get_enable_rts_sifsbursting(struct wlan_objmgr_psoc *psoc,
+					    bool *enable_rts_sifsbursting);
+
+/**
+ * ucfg_get_max_mpdus_inampdu() - Assigns the max_mpdus_inampdu value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_get_max_mpdus_inampdu(struct wlan_objmgr_psoc *psoc,
+				      uint8_t *max_mpdus_inampdu);
+
+/**
+ * ucfg_get_arp_ac_category() - Assigns the arp_ac_category value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_get_arp_ac_category(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *arp_ac_category);
+
+/**
+ * ucfg_get_enable_phy_reg_retention() - Assigns enable_phy_reg_retention value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_get_enable_phy_reg_retention(struct wlan_objmgr_psoc *psoc,
+					     uint8_t *enable_phy_reg_retention);
+
+/**
+ * ucfg_get_upper_brssi_thresh() - Assigns upper_brssi_thresh value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_get_upper_brssi_thresh(struct wlan_objmgr_psoc *psoc,
+				       uint16_t *upper_brssi_thresh);
+
+/**
+ * ucfg_get_lower_brssi_thresh() - Assigns lower_brssi_thresh value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_get_lower_brssi_thresh(struct wlan_objmgr_psoc *psoc,
+				       uint16_t *lower_brssi_thresh);
+
+/**
+ * ucfg_get_enable_dtim_1chrx() - Assigns enable_dtim_1chrx value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_get_enable_dtim_1chrx(struct wlan_objmgr_psoc *psoc,
+				      bool *enable_dtim_1chrx);
+
+/**
+ * ucfg_get_alternate_chainmask_enabled() - Assigns alt chainmask_enabled value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_get_alternative_chainmask_enabled(struct wlan_objmgr_psoc *psoc,
+				       bool *alternative_chainmask_enabled);
+
+/**
+ * ucfg_get_smart_chainmask_enabled() - Assigns smart_chainmask_enabled value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_get_smart_chainmask_enabled(struct wlan_objmgr_psoc *psoc,
+					    bool *smart_chainmask_enabled);
+
+/**
+ * ucfg_fwol_get_rts_profile() - Assigns get_rts_profile value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_fwol_get_rts_profile(struct wlan_objmgr_psoc *psoc,
+				     uint16_t *get_rts_profile);
+
+/**
+ * ucfg_fwol_get_enable_fw_log_level() - Assigns enable_fw_log_level value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_fwol_get_enable_fw_log_level(struct wlan_objmgr_psoc *psoc,
+					     uint16_t *enable_fw_log_level);
+
+/**
+ * ucfg_fwol_get_enable_fw_log_type() - Assigns enable_fw_log_type value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_fwol_get_enable_fw_log_type(struct wlan_objmgr_psoc *psoc,
+					    uint16_t *enable_fw_log_type);
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+/**
+ * ucfg_fwol_set_is_rate_limit_enabled() - Sets the is_rate_limit_enabled value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_fwol_set_is_rate_limit_enabled(struct wlan_objmgr_psoc *psoc,
+					       bool is_rate_limit_enabled);
+
+/**
+ * ucfg_fwol_get_is_rate_limit_enabled() - Assigns is_rate_limit_enabled value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_fwol_get_is_rate_limit_enabled(struct wlan_objmgr_psoc *psoc,
+					       bool *is_rate_limit_enabled);
+
+#endif /* FEATURE_WLAN_RA_FILTERING */
+
+/**
+ * ucfg_fwol_get_tsf_gpio_pin() - Assigns tsf_gpio_pin value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+
+QDF_STATUS ucfg_fwol_get_tsf_gpio_pin(struct wlan_objmgr_psoc *psoc,
+				      uint32_t *tsf_gpio_pin);
+
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * ucfg_fwol_get_enable_dhcp_server_offload()-Assign enable_dhcp_server_offload
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_fwol_get_enable_dhcp_server_offload(struct wlan_objmgr_psoc *psoc,
+					 bool *enable_dhcp_server_offload);
+
+/**
+ * ucfg_fwol_get_dhcp_max_num_clients() - Assigns dhcp_max_num_clients value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_fwol_get_dhcp_max_num_clients(struct wlan_objmgr_psoc *psoc,
+					      uint32_t *dhcp_max_num_clients);
+
+#endif
+#endif /* _WLAN_FWOL_UCFG_API_H_ */
diff --git a/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c b/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c
new file mode 100644
index 0000000..4b5cc46
--- /dev/null
+++ b/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c
@@ -0,0 +1,518 @@
+/*
+ * Copyright (c) 2018 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 internal APIs related to the fwol component
+ */
+
+#include "wlan_fw_offload_main.h"
+#include "wlan_fwol_ucfg_api.h"
+
+QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+
+	status = fwol_cfg_on_psoc_enable(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		fwol_err("Failed to initialize FWOL CFG");
+
+	return status;
+}
+
+void ucfg_fwol_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	/* Clear the FWOL CFG Structure */
+}
+
+/**
+ * fwol_psoc_object_created_notification(): fwol psoc create handler
+ * @psoc: psoc which is going to created by objmgr
+ * @arg: argument for vdev create handler
+ *
+ * Register this api with objmgr to detect psoc is created
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+static QDF_STATUS
+fwol_psoc_object_created_notification(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	QDF_STATUS status;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = qdf_mem_malloc(sizeof(*fwol_obj));
+	if (!fwol_obj)
+		return QDF_STATUS_E_NOMEM;
+
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+						       WLAN_UMAC_COMP_FWOL,
+						       fwol_obj,
+						       QDF_STATUS_SUCCESS);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		fwol_err("Failed to attach psoc_ctx with psoc");
+		qdf_mem_free(fwol_obj);
+	}
+
+	return status;
+}
+
+/**
+ * fwol_psoc_object_destroyed_notification(): fwol psoc delete handler
+ * @psoc: psoc which is going to delete by objmgr
+ * @arg: argument for vdev delete handler
+ *
+ * Register this api with objmgr to detect psoc is deleted
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+static QDF_STATUS fwol_psoc_object_destroyed_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	QDF_STATUS status;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj)
+		return QDF_STATUS_E_NOMEM;
+
+	status = wlan_objmgr_psoc_component_obj_detach(psoc,
+						       WLAN_UMAC_COMP_FWOL,
+						       fwol_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		fwol_err("Failed to detach psoc_ctx from psoc");
+		return status;
+	}
+
+	qdf_mem_free(fwol_obj);
+
+	return status;
+}
+
+QDF_STATUS ucfg_fwol_init(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_register_psoc_create_handler(
+			WLAN_UMAC_COMP_FWOL,
+			fwol_psoc_object_created_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		fwol_err("unable to register psoc create handle");
+		return status;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+			WLAN_UMAC_COMP_FWOL,
+			fwol_psoc_object_destroyed_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		fwol_err("unable to register psoc create handle");
+		wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_FWOL,
+			fwol_psoc_object_created_notification,
+			NULL);
+	}
+
+	return status;
+}
+
+void ucfg_fwol_deinit(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+			WLAN_UMAC_COMP_FWOL,
+			fwol_psoc_object_destroyed_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status))
+		fwol_err("unable to unregister psoc destroy handle");
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_FWOL,
+			fwol_psoc_object_created_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status))
+		fwol_err("unable to unregister psoc create handle");
+}
+
+QDF_STATUS
+ucfg_fwol_get_coex_config_params(struct wlan_objmgr_psoc *psoc,
+				 struct wlan_fwol_coex_config *coex_config)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get fwol obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*coex_config = fwol_obj->cfg.coex_config;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_fwol_get_thermal_temp(struct wlan_objmgr_psoc *psoc,
+			   struct wlan_fwol_thermal_temp *thermal_info)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get fwol obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*thermal_info = fwol_obj->cfg.thermal_temp_cfg;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_fwol_get_ie_whitelist(struct wlan_objmgr_psoc *psoc, bool *ie_whitelist)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get fwol obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*ie_whitelist = fwol_obj->cfg.ie_whitelist_cfg.ie_whitelist;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_fwol_set_ie_whitelist(struct wlan_objmgr_psoc *psoc, bool ie_whitelist)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get fwol obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	fwol_obj->cfg.ie_whitelist_cfg.ie_whitelist = ie_whitelist;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_fwol_get_ani_enabled(struct wlan_objmgr_psoc *psoc,
+				     bool *ani_enabled)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*ani_enabled = fwol_obj->cfg.ani_enabled;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_get_enable_rts_sifsbursting(struct wlan_objmgr_psoc *psoc,
+					    bool *enable_rts_sifsbursting)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*enable_rts_sifsbursting = fwol_obj->cfg.enable_rts_sifsbursting;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_get_max_mpdus_inampdu(struct wlan_objmgr_psoc *psoc,
+				      uint8_t *max_mpdus_inampdu)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*max_mpdus_inampdu = fwol_obj->cfg.max_mpdus_inampdu;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_get_arp_ac_category(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *arp_ac_category)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*arp_ac_category = fwol_obj->cfg.arp_ac_category;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_get_enable_phy_reg_retention(struct wlan_objmgr_psoc *psoc,
+					     uint8_t *enable_phy_reg_retention)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*enable_phy_reg_retention = fwol_obj->cfg.enable_phy_reg_retention;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_fwol_get_all_whitelist_params(struct wlan_objmgr_psoc *psoc,
+				   struct wlan_fwol_ie_whitelist *whitelist)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get fwol obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*whitelist = fwol_obj->cfg.ie_whitelist_cfg;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_get_upper_brssi_thresh(struct wlan_objmgr_psoc *psoc,
+				       uint16_t *upper_brssi_thresh)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*upper_brssi_thresh = fwol_obj->cfg.upper_brssi_thresh;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_get_lower_brssi_thresh(struct wlan_objmgr_psoc *psoc,
+				       uint16_t *lower_brssi_thresh)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*lower_brssi_thresh = fwol_obj->cfg.lower_brssi_thresh;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_get_enable_dtim_1chrx(struct wlan_objmgr_psoc *psoc,
+				      bool *enable_dtim_1chrx)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*enable_dtim_1chrx = fwol_obj->cfg.enable_dtim_1chrx;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_get_alternative_chainmask_enabled(struct wlan_objmgr_psoc *psoc,
+				       bool *alternative_chainmask_enabled)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get fwol obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*alternative_chainmask_enabled =
+				fwol_obj->cfg.alternative_chainmask_enabled;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_get_smart_chainmask_enabled(struct wlan_objmgr_psoc *psoc,
+					    bool *smart_chainmask_enabled)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*smart_chainmask_enabled =
+				fwol_obj->cfg.smart_chainmask_enabled;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_fwol_get_rts_profile(struct wlan_objmgr_psoc *psoc,
+				     uint16_t *get_rts_profile)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*get_rts_profile = fwol_obj->cfg.get_rts_profile;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_fwol_get_enable_fw_log_level(struct wlan_objmgr_psoc *psoc,
+					     uint16_t *enable_fw_log_level)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*enable_fw_log_level = fwol_obj->cfg.enable_fw_log_level;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_fwol_get_enable_fw_log_type(struct wlan_objmgr_psoc *psoc,
+					    uint16_t *enable_fw_log_type)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*enable_fw_log_type = fwol_obj->cfg.enable_fw_log_type;
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+QDF_STATUS ucfg_fwol_set_is_rate_limit_enabled(struct wlan_objmgr_psoc *psoc,
+					       bool is_rate_limit_enabled)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	fwol_obj->cfg.is_rate_limit_enabled = is_rate_limit_enabled;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_fwol_get_is_rate_limit_enabled(struct wlan_objmgr_psoc *psoc,
+					       bool *is_rate_limit_enabled)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*is_rate_limit_enabled = fwol_obj->cfg.is_rate_limit_enabled;
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef WLAN_FEATURE_TSF
+QDF_STATUS ucfg_fwol_get_tsf_gpio_pin(struct wlan_objmgr_psoc *psoc,
+				      uint32_t *tsf_gpio_pin)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*tsf_gpio_pin = fwol_obj->cfg.tsf_gpio_pin;
+	return QDF_STATUS_SUCCESS;
+}
+#else
+QDF_STATUS ucfg_fwol_get_tsf_gpio_pin(struct wlan_objmgr_psoc *psoc,
+				      uint32_t *tsf_gpio_pin)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef DHCP_SERVER_OFFLOAD
+QDF_STATUS
+ucfg_fwol_get_enable_dhcp_server_offload(struct wlan_objmgr_psoc *psoc,
+					 bool *enable_dhcp_server_offload)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*enable_dhcp_server_offload = fwol_obj->cfg.enable_dhcp_server_offload;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_fwol_get_dhcp_max_num_clients(struct wlan_objmgr_psoc *psoc,
+					      uint32_t *dhcp_max_num_clients)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*dhcp_max_num_clients = fwol_obj->cfg.dhcp_max_num_clients;
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
diff --git a/components/ipa/core/inc/wlan_ipa_core.h b/components/ipa/core/inc/wlan_ipa_core.h
new file mode 100644
index 0000000..985cdc4
--- /dev/null
+++ b/components/ipa/core/inc/wlan_ipa_core.h
@@ -0,0 +1,678 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#ifndef _WLAN_IPA_CORE_H_
+#define _WLAN_IPA_CORE_H_
+
+#ifdef IPA_OFFLOAD
+
+#include "wlan_ipa_priv.h"
+#include "wlan_ipa_public_struct.h"
+
+/**
+ * wlan_ipa_is_enabled() - Is IPA enabled?
+ * @ipa_cfg: IPA config
+ *
+ * Return: true if IPA is enabled, false otherwise
+ */
+static inline bool wlan_ipa_is_enabled(struct wlan_ipa_config *ipa_cfg)
+{
+	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg, WLAN_IPA_ENABLE_MASK);
+}
+
+/**
+ * wlan_ipa_uc_is_enabled() - Is IPA UC enabled?
+ * @ipa_cfg: IPA config
+ *
+ * Return: true if IPA UC is enabled, false otherwise
+ */
+static inline bool wlan_ipa_uc_is_enabled(struct wlan_ipa_config *ipa_cfg)
+{
+	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg, WLAN_IPA_UC_ENABLE_MASK);
+}
+
+/**
+ * wlan_ipa_is_rt_debugging_enabled() - Is IPA RT debugging enabled?
+ * @ipa_cfg: IPA config
+ *
+ * Return: true if IPA RT debugging is enabled, false otherwise
+ */
+static inline
+bool wlan_ipa_is_rt_debugging_enabled(struct wlan_ipa_config *ipa_cfg)
+{
+	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg,
+					  WLAN_IPA_REAL_TIME_DEBUGGING);
+}
+
+/**
+ * wlan_ipa_setup - IPA initialize and setup
+ * @ipa_ctx: IPA priv obj
+ * @ipa_cfg: IPA config
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx,
+			  struct wlan_ipa_config *ipa_cfg);
+
+/**
+ * wlan_ipa_get_obj_context - Get IPA OBJ context
+ *
+ * Return: IPA context
+ */
+struct wlan_ipa_priv *wlan_ipa_get_obj_context(void);
+
+/**
+ * wlan_ipa_cleanup - IPA cleanup
+ * @ipa_ctx: IPA priv obj
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_uc_enable_pipes() - Enable IPA uC pipes
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_uc_enable_pipes(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_uc_disable_pipes() - Disable IPA uC pipes
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_uc_disable_pipes(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_set_perf_level() - Set IPA performance level
+ * @ipa_ctx: IPA context
+ * @tx_packets: Number of packets transmitted in the last sample period
+ * @rx_packets: Number of packets received in the last sample period
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS wlan_ipa_set_perf_level(struct wlan_ipa_priv *ipa_ctx,
+				   uint64_t tx_packets, uint64_t rx_packets);
+
+/**
+ * wlan_ipa_init_perf_level() - Initialize IPA performance level
+ * @ipa_ctx: IPA context
+ *
+ * If IPA clock scaling is disabled, initialize perf level to maximum.
+ * Else set the lowest level to start with.
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS wlan_ipa_init_perf_level(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_get_iface() - Get IPA interface
+ * @ipa_ctx: IPA context
+ * @mode: Interface device mode
+ *
+ * Return: IPA interface address
+ */
+struct wlan_ipa_iface_context
+*wlan_ipa_get_iface(struct wlan_ipa_priv *ipa_ctx, uint8_t mode);
+
+#ifndef CONFIG_IPA_WDI_UNIFIED_API
+
+/**
+ * wlan_ipa_is_rm_enabled() - Is IPA RM enabled?
+ * @ipa_cfg: IPA config
+ *
+ * Return: true if IPA RM is enabled, false otherwise
+ */
+static inline bool wlan_ipa_is_rm_enabled(struct wlan_ipa_config *ipa_cfg)
+{
+	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg, WLAN_IPA_RM_ENABLE_MASK);
+}
+
+/**
+ * wlan_ipa_is_clk_scaling_enabled() - Is IPA clock scaling enabled?
+ * @ipa_cfg: IPA config
+ *
+ * Return: true if IPA clock scaling is enabled, false otherwise
+ */
+static inline
+bool wlan_ipa_is_clk_scaling_enabled(struct wlan_ipa_config *ipa_cfg)
+{
+	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg,
+					  WLAN_IPA_CLK_SCALING_ENABLE_MASK |
+					  WLAN_IPA_RM_ENABLE_MASK);
+}
+
+/**
+ * wlan_ipa_wdi_rm_request_resource() - IPA WDI request resource
+ * @ipa_ctx: IPA context
+ * @res_name: IPA RM resource name
+ *
+ * Return: 0 on success, negative errno on error
+ */
+static inline
+int wlan_ipa_wdi_rm_request_resource(struct wlan_ipa_priv *ipa_ctx,
+				     qdf_ipa_rm_resource_name_t res_name)
+{
+	return qdf_ipa_rm_request_resource(res_name);
+}
+
+/**
+ * wlan_ipa_wdi_rm_release_resource() - IPA WDI release resource
+ * @ipa_ctx: IPA context
+ * @res_name: IPA RM resource name
+ *
+ * Return: 0 on success, negative errno on error
+ */
+static inline
+int wlan_ipa_wdi_rm_release_resource(struct wlan_ipa_priv *ipa_ctx,
+				     qdf_ipa_rm_resource_name_t res_name)
+{
+	return qdf_ipa_rm_release_resource(res_name);
+}
+
+/**
+ * wlan_ipa_wdi_rm_request() - Request resource from IPA
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_wdi_rm_request(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_wdi_rm_try_release() - Attempt to release IPA resource
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_wdi_rm_try_release(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_wdi_setup_rm() - Setup IPA resource management
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_wdi_setup_rm(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_wdi_destroy_rm() - Destroy IPA resources
+ * @ipa_ctx: IPA context
+ *
+ * Destroys all resources associated with the IPA resource manager
+ *
+ * Return: None
+ */
+void wlan_ipa_wdi_destroy_rm(struct wlan_ipa_priv *ipa_ctx);
+
+static inline
+int wlan_ipa_wdi_rm_notify_completion(qdf_ipa_rm_event_t event,
+				      qdf_ipa_rm_resource_name_t res_name)
+{
+	return qdf_ipa_rm_notify_completion(event, res_name);
+}
+
+static inline
+int wlan_ipa_wdi_rm_inactivity_timer_destroy(
+					qdf_ipa_rm_resource_name_t res_name)
+{
+	return qdf_ipa_rm_inactivity_timer_destroy(res_name);
+}
+
+bool wlan_ipa_is_rm_released(struct wlan_ipa_priv *ipa_ctx);
+
+#else /* CONFIG_IPA_WDI_UNIFIED_API */
+
+/**
+ * wlan_ipa_is_rm_enabled() - Is IPA RM enabled?
+ * @ipa_cfg: IPA config
+ *
+ * IPA RM is deprecated and IPA PM is involved. WLAN driver
+ * has no control over IPA PM and thus we could regard IPA
+ * RM as always enabled for power efficiency.
+ *
+ * Return: true
+ */
+static inline bool wlan_ipa_is_rm_enabled(struct wlan_ipa_config *ipa_cfg)
+{
+	return true;
+}
+
+/**
+ * wlan_ipa_is_clk_scaling_enabled() - Is IPA clock scaling enabled?
+ * @ipa_cfg: IPA config
+ *
+ * Return: true if IPA clock scaling is enabled, false otherwise
+ */
+static inline
+bool wlan_ipa_is_clk_scaling_enabled(struct wlan_ipa_config *ipa_cfg)
+{
+	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg,
+					  WLAN_IPA_CLK_SCALING_ENABLE_MASK);
+}
+
+static inline int wlan_ipa_wdi_rm_request_resource(
+			struct wlan_ipa_priv *ipa_ctx,
+			qdf_ipa_rm_resource_name_t res_name)
+{
+	return 0;
+}
+
+static inline int wlan_ipa_wdi_rm_release_resource(
+			struct wlan_ipa_priv *ipa_ctx,
+			qdf_ipa_rm_resource_name_t res_name)
+{
+	return 0;
+}
+
+static inline QDF_STATUS wlan_ipa_wdi_setup_rm(struct wlan_ipa_priv *ipa_ctx)
+{
+	return 0;
+}
+
+static inline int wlan_ipa_wdi_destroy_rm(struct wlan_ipa_priv *ipa_ctx)
+{
+	return 0;
+}
+
+static inline QDF_STATUS wlan_ipa_wdi_rm_request(struct wlan_ipa_priv *ipa_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS wlan_ipa_wdi_rm_try_release(struct wlan_ipa_priv
+						     *ipa_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+int wlan_ipa_wdi_rm_notify_completion(qdf_ipa_rm_event_t event,
+				      qdf_ipa_rm_resource_name_t res_name)
+{
+	return 0;
+}
+
+static inline
+int wlan_ipa_wdi_rm_inactivity_timer_destroy(
+					qdf_ipa_rm_resource_name_t res_name)
+{
+	return 0;
+}
+
+static inline
+bool wlan_ipa_is_rm_released(struct wlan_ipa_priv *ipa_ctx)
+{
+	return true;
+}
+
+#endif /* CONFIG_IPA_WDI_UNIFIED_API */
+
+#ifdef FEATURE_METERING
+
+/**
+ * wlan_ipa_uc_op_metering() - IPA uC operation for stats and quota limit
+ * @ipa_ctx: IPA context
+ * @op_msg: operation message received from firmware
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS wlan_ipa_uc_op_metering(struct wlan_ipa_priv *ipa_ctx,
+				  struct op_msg_type *op_msg);
+
+/**
+ * wlan_ipa_wdi_meter_notifier_cb() - SSR wrapper for
+ * __wlan_ipa_wdi_meter_notifier_cb
+ * @priv: pointer to private data registered with IPA (we register a
+ *        pointer to the global IPA context)
+ * @evt: the IPA event which triggered the callback
+ * @data: data associated with the event
+ *
+ * Return: None
+ */
+void wlan_ipa_wdi_meter_notifier_cb(qdf_ipa_wdi_meter_evt_type_t evt,
+				    void *data);
+
+/**
+ * wlan_ipa_init_metering() - IPA metering stats completion event reset
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF_STATUS enumeration
+ */
+void wlan_ipa_init_metering(struct wlan_ipa_priv *ipa_ctx);
+#else
+
+static inline
+QDF_STATUS wlan_ipa_uc_op_metering(struct wlan_ipa_priv *ipa_ctx,
+				   struct op_msg_type *op_msg)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void wlan_ipa_wdi_meter_notifier_cb(void)
+{
+}
+
+static inline void wlan_ipa_init_metering(struct wlan_ipa_priv *ipa_ctx)
+{
+}
+#endif /* FEATURE_METERING */
+
+/**
+ * wlan_ipa_uc_stat() - Print IPA uC stats
+ * @ipa_ctx: IPA context
+ *
+ * Return: None
+ */
+void wlan_ipa_uc_stat(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_uc_info() - Print IPA uC resource and session information
+ * @ipa_ctx: IPA context
+ *
+ * Return: None
+ */
+void wlan_ipa_uc_info(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_print_fw_wdi_stats() - Print FW IPA WDI stats
+ * @ipa_ctx: IPA context
+ *
+ * Return: None
+ */
+void wlan_ipa_print_fw_wdi_stats(struct wlan_ipa_priv *ipa_ctx,
+				 struct ipa_uc_fw_stats *uc_fw_stat);
+
+/**
+ * wlan_ipa_uc_stat_request() - Get IPA stats from IPA
+ * @ipa_ctx: IPA context
+ * @reason: STAT REQ Reason
+ *
+ * Return: None
+ */
+void wlan_ipa_uc_stat_request(struct wlan_ipa_priv *ipa_ctx, uint8_t reason);
+
+/**
+ * wlan_ipa_uc_stat_query() - Query the IPA stats
+ * @ipa_ctx: IPA context
+ * @ipa_tx_diff: tx packet count diff from previous tx packet count
+ * @ipa_rx_diff: rx packet count diff from previous rx packet count
+ *
+ * Return: None
+ */
+void wlan_ipa_uc_stat_query(struct wlan_ipa_priv *ipa_ctx,
+			    uint32_t *ipa_tx_diff, uint32_t *ipa_rx_diff);
+
+/**
+ * wlan_ipa_dump_info() - dump IPA IPA struct
+ * @ipa_ctx: IPA context
+ *
+ * Dump entire struct ipa_ctx
+ *
+ * Return: none
+ */
+void wlan_ipa_dump_info(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_uc_rt_debug_host_dump - dump rt debug buffer
+ * @ipa_ctx: IPA context
+ *
+ * If rt debug enabled, dump debug buffer contents based on requirement
+ *
+ * Return: none
+ */
+void wlan_ipa_uc_rt_debug_host_dump(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_uc_rt_debug_destructor() - called by data packet free
+ * @nbuff: packet pinter
+ *
+ * when free data packet, will be invoked by wlan client and will increase
+ * free counter
+ *
+ * Return: none
+ */
+void wlan_ipa_uc_rt_debug_destructor(qdf_nbuf_t nbuff);
+
+/**
+ * wlan_ipa_uc_rt_debug_deinit() - remove resources to handle rt debugging
+ * @ipa_ctx: IPA context
+ *
+ * free all rt debugging resources
+ *
+ * Return: none
+ */
+void wlan_ipa_uc_rt_debug_deinit(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_uc_rt_debug_init() - initialize resources to handle rt debugging
+ * @ipa_ctx: IPA context
+ *
+ * alloc and initialize all rt debugging resources
+ *
+ * Return: none
+ */
+void wlan_ipa_uc_rt_debug_init(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_reg_sap_xmit_cb() - Register upper layer SAP cb to transmit
+ * @ipa_ctx: IPA context
+ * @cb: callback
+ *
+ * Return: None
+ */
+static inline
+void wlan_ipa_reg_sap_xmit_cb(struct wlan_ipa_priv *ipa_ctx, void *cb)
+{
+	ipa_ctx->softap_xmit = cb;
+}
+
+/**
+ * wlan_ipa_reg_send_to_nw_cb() - Register cb to send IPA Rx packet to network
+ * @ipa_ctx: IPA context
+ * @cb: callback
+ *
+ * Return: None
+ */
+static inline
+void wlan_ipa_reg_send_to_nw_cb(struct wlan_ipa_priv *ipa_ctx, void *cb)
+{
+	ipa_ctx->send_to_nw = cb;
+}
+
+/**
+ * wlan_ipa_set_mcc_mode() - Set MCC mode
+ * @ipa_ctx: IPA context
+ * @mcc_mode: 1=MCC/0=SCC
+ *
+ * Return: void
+ */
+void wlan_ipa_set_mcc_mode(struct wlan_ipa_priv *ipa_ctx, bool mcc_mode);
+
+/**
+ * wlan_ipa_set_dfs_cac_tx() - Set DFS cac tx block
+ * @ipa_ctx: IPA context
+ * @tx_block: dfs cac tx block
+ *
+ * Return: void
+ */
+static inline
+void wlan_ipa_set_dfs_cac_tx(struct wlan_ipa_priv *ipa_ctx, bool tx_block)
+{
+	ipa_ctx->dfs_cac_block_tx = tx_block;
+}
+
+/**
+ * wlan_ipa_set_ap_ibss_fwd() - Set AP intra bss forward
+ * @ipa_ctx: IPA context
+ * @intra_bss: enable or disable ap intra bss forward
+ *
+ * Return: void
+ */
+static inline
+void wlan_ipa_set_ap_ibss_fwd(struct wlan_ipa_priv *ipa_ctx, bool intra_bss)
+{
+	ipa_ctx->ap_intrabss_fwd = intra_bss;
+}
+
+/**
+ * wlan_ipa_uc_ol_init() - Initialize IPA uC offload
+ * @ipa_ctx: IPA context
+ * @osdev: Parent device instance
+ *
+ * This function is called to update IPA pipe configuration with resources
+ * allocated by wlan driver (cds_pre_enable) before enabling it in FW
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx,
+			       qdf_device_t osdev);
+
+/**
+ * wlan_ipa_uc_ol_deinit() - Disconnect IPA TX and RX pipes
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_flush() - flush IPA exception path SKB's
+ * @ipa_ctx: IPA context
+ *
+ * Return: None
+ */
+void wlan_ipa_flush(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_suspend() - Suspend IPA
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS wlan_ipa_suspend(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_resume() - Resume IPA
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS wlan_ipa_resume(struct wlan_ipa_priv *ipa_ctx);
+
+#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+/**
+ * wlan_ipa_send_mcc_scc_msg() - Send IPA WLAN_SWITCH_TO_MCC/SCC message
+ * @ipa_ctx: IPA context
+ * @mcc_mode: 0=MCC/1=SCC
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx,
+				     bool mcc_mode);
+#else
+static inline
+QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx,
+				     bool mcc_mode)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void wlan_ipa_mcc_work_handler(void *data)
+{
+}
+#endif
+
+/**
+ * wlan_ipa_wlan_evt() - IPA event handler
+ * @net_dev: Interface net device
+ * @device_mode: Net interface device mode
+ * @sta_id: station id for the event
+ * @session_id: session id for the event
+ * @type: event enum of type ipa_wlan_event
+ * @mac_address: MAC address associated with the event
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
+			     uint8_t sta_id, uint8_t session_id,
+			     enum wlan_ipa_wlan_event ipa_event_type,
+			     uint8_t *mac_addr);
+
+/**
+ * wlan_ipa_uc_smmu_map() - Map / Unmap DMA buffer to IPA UC
+ * @map: Map / unmap operation
+ * @num_buf: Number of buffers in array
+ * @buf_arr: Buffer array of DMA mem mapping info
+ *
+ * This API maps/unmaps WLAN-IPA buffers if SMMU S1 translation
+ * is enabled.
+ *
+ * Return: Status of map operation
+ */
+int wlan_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr);
+
+/**
+ * wlan_ipa_is_fw_wdi_activated() - Is FW WDI actived?
+ * @ipa_ctx: IPA contex
+ *
+ * Return: true if FW WDI actived, false otherwise
+ */
+bool wlan_ipa_is_fw_wdi_activated(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_uc_disconnect_ap() - send ap disconnect event
+ * @ipa_ctx: IPA context
+ * @net_dev: Interface net device
+ *
+ * Send disconnect ap event to IPA driver
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_uc_disconnect_ap(struct wlan_ipa_priv *ipa_ctx,
+				     qdf_netdev_t net_dev);
+
+/**
+ * wlan_ipa_cleanup_dev_iface() - Clean up net dev IPA interface
+ * @ipa_ctx: IPA context
+ * @net_dev: Interface net device
+ *
+ * Return: None
+ */
+void wlan_ipa_cleanup_dev_iface(struct wlan_ipa_priv *ipa_ctx,
+				qdf_netdev_t net_dev);
+
+/**
+ * wlan_ipa_uc_ssr_cleanup() - handle IPA UC clean up during SSR
+ * @ipa_ctx: IPA context
+ *
+ * Return: None
+ */
+void wlan_ipa_uc_ssr_cleanup(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * wlan_ipa_fw_rejuvenate_send_msg() - send fw rejuvenate message to IPA driver
+ * @ipa_ctx: IPA context
+ *
+ * Return: void
+ */
+void wlan_ipa_fw_rejuvenate_send_msg(struct wlan_ipa_priv *ipa_ctx);
+
+#endif /* IPA_OFFLOAD */
+#endif /* _WLAN_IPA_CORE_H_ */
diff --git a/components/ipa/core/inc/wlan_ipa_main.h b/components/ipa/core/inc/wlan_ipa_main.h
new file mode 100644
index 0000000..19c2492
--- /dev/null
+++ b/components/ipa/core/inc/wlan_ipa_main.h
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2018 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
+ * IPA user configuration and target interface
+ */
+
+#ifndef _WLAN_IPA_MAIN_H_
+#define _WLAN_IPA_MAIN_H_
+
+#ifdef IPA_OFFLOAD
+
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_ipa_public_struct.h>
+#include <wlan_ipa_priv.h>
+
+#define ipa_fatal(params...) \
+	QDF_TRACE_FATAL(QDF_MODULE_ID_IPA, params)
+#define ipa_err(params...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_IPA, params)
+#define ipa_warn(params...) \
+	QDF_TRACE_WARN(QDF_MODULE_ID_IPA, params)
+#define ipa_info(params...) \
+	QDF_TRACE_INFO(QDF_MODULE_ID_IPA, params)
+#define ipa_debug(params...) \
+	QDF_TRACE_DEBUG(QDF_MODULE_ID_IPA, params)
+
+#define ipa_nofl_fatal(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_IPA, params)
+#define ipa_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_IPA, params)
+#define ipa_nofl_warn(params...) \
+	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_IPA, params)
+#define ipa_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_IPA, params)
+#define ipa_nofl_debug(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_IPA, params)
+
+#define ipa_fatal_rl(params...) QDF_TRACE_FATAL_RL(QDF_MODULE_ID_IPA, params)
+#define ipa_err_rl(params...) QDF_TRACE_ERROR_RL(QDF_MODULE_ID_IPA, params)
+#define ipa_warn_rl(params...) QDF_TRACE_WARN_RL(QDF_MODULE_ID_IPA, params)
+#define ipa_info_rl(params...) QDF_TRACE_INFO_RL(QDF_MODULE_ID_IPA, params)
+#define ipa_debug_rl(params...) QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_IPA, params)
+
+#define IPA_ENTER() \
+	QDF_TRACE_ENTER(QDF_MODULE_ID_IPA, "enter")
+#define IPA_EXIT() \
+	QDF_TRACE_EXIT(QDF_MODULE_ID_IPA, "exit")
+
+/**
+ * ipa_check_hw_present() - get IPA hw status
+ *
+ * ipa_uc_reg_rdyCB is not directly designed to check
+ * ipa hw status. This is an undocumented function which
+ * has confirmed with IPA team.
+ *
+ * Return: true - ipa hw present
+ *         false - ipa hw not present
+ */
+bool ipa_check_hw_present(void);
+
+/**
+ * wlan_get_pdev_ipa_obj() - private API to get ipa pdev object
+ * @pdev: pdev object
+ *
+ * Return: ipa object
+ */
+static inline struct wlan_ipa_priv *
+ipa_pdev_get_priv_obj(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *pdev_obj;
+
+	pdev_obj = (struct wlan_ipa_priv *)
+		wlan_objmgr_pdev_get_comp_private_obj(pdev,
+				WLAN_UMAC_COMP_IPA);
+
+	return pdev_obj;
+}
+
+/**
+ * ipa_is_hw_support() - Is IPA HW support?
+ *
+ * Return: true if IPA HW  is present or false otherwise
+ */
+bool ipa_is_hw_support(void);
+
+/**
+ * ipa_config_mem_alloc() - IPA config allocation
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ipa_config_mem_alloc(void);
+
+/**
+ * ipa_config_mem_free() - IPA config mem free
+ *
+ * Return: None
+ */
+void ipa_config_mem_free(void);
+
+/**
+ * ipa_config_is_enabled() - Is IPA config enabled?
+ *
+ * Return: true if IPA is enabled in IPA config
+ */
+bool ipa_config_is_enabled(void);
+
+/**
+ * ipa_config_is_uc_enabled() - Is IPA uC config enabled?
+ *
+ * Return: true if IPA uC is enabled in IPA config
+ */
+bool ipa_config_is_uc_enabled(void);
+
+/**
+ * ipa_obj_setup() - IPA obj initialization and setup
+ * @ipa_ctx: IPA obj context
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ipa_obj_setup(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * ipa_obj_cleanup() - IPA obj cleanup
+ * @ipa_ctx: IPA obj context
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ipa_obj_cleanup(struct wlan_ipa_priv *ipa_ctx);
+
+/**
+ * ipa_send_uc_offload_enable_disable() - wdi enable/disable notify to fw
+ * @pdev: objmgr pdev object
+ * @req: ipa offload control request
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS ipa_send_uc_offload_enable_disable(struct wlan_objmgr_pdev *pdev,
+				struct ipa_uc_offload_control_params *req);
+
+/**
+ * ipa_set_dp_handle() - set dp soc handle
+ * @psoc: psoc handle
+ * @dp_soc: dp soc handle
+ *
+ * Return: None
+ */
+void ipa_set_dp_handle(struct wlan_objmgr_psoc *psoc, void *dp_soc);
+
+/**
+ * ipa_set_txrx_handle() - set dp txrx handle
+ * @psoc: psoc handle
+ * @txrx_handle: dp txrx handle
+ *
+ * Return: None
+ */
+void ipa_set_txrx_handle(struct wlan_objmgr_psoc *psoc, void *txrx_handle);
+
+/**
+ * ipa_rm_set_perf_level() - set ipa rm perf level
+ * @pdev: pdev handle
+ * @tx_packets: packets transmitted in the last sample period
+ * @rx_packets: packets received in the last sample period
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ipa_rm_set_perf_level(struct wlan_objmgr_pdev *pdev,
+				 uint64_t tx_packets, uint64_t rx_packets);
+
+/**
+ * ipa_uc_info() - Print IPA uC resource and session information
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ipa_uc_info(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ipa_uc_stat() - Print IPA uC stats
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ipa_uc_stat(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ipa_uc_rt_debug_host_dump() - IPA rt debug host dump
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ipa_uc_rt_debug_host_dump(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ipa_dump_info() - Dump IPA context information
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ipa_dump_info(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ipa_uc_stat_request() - Get IPA stats from IPA.
+ * @pdev: pdev obj
+ * @reason: STAT REQ Reason
+ *
+ * Return: None
+ */
+void ipa_uc_stat_request(struct wlan_objmgr_pdev *pdev,
+			 uint8_t reason);
+
+/**
+ * ipa_uc_stat_query() - Query the IPA stats
+ * @pdev: pdev obj
+ * @ipa_tx_diff: tx packet count diff from previous tx packet count
+ * @ipa_rx_diff: rx packet count diff from previous rx packet count
+ *
+ * Return: None
+ */
+void ipa_uc_stat_query(struct wlan_objmgr_pdev *pdev,
+		       uint32_t *ipa_tx_diff, uint32_t *ipa_rx_diff);
+
+/**
+ * ipa_reg_sap_xmit_cb() - Register upper layer SAP cb to transmit
+ * @pdev: pdev obj
+ * @cb: callback
+ *
+ * Return: None
+ */
+void ipa_reg_sap_xmit_cb(struct wlan_objmgr_pdev *pdev, void *cb);
+
+/**
+ * ipa_reg_send_to_nw_cb() - Register cb to send IPA Rx packet to network
+ * @pdev: pdev obj
+ * @cb: callback
+ *
+ * Return: None
+ */
+void ipa_reg_send_to_nw_cb(struct wlan_objmgr_pdev *pdev, void *cb);
+
+/**
+ * ipa_set_mcc_mode() - Set MCC mode
+ * @pdev: pdev obj
+ * @mcc_mode: 0=MCC/1=SCC
+ *
+ * Return: void
+ */
+void ipa_set_mcc_mode(struct wlan_objmgr_pdev *pdev, bool mcc_mode);
+
+/**
+ * ipa_set_dfs_cac_tx() - Set DFS cac tx block
+ * @pdev: pdev obj
+ * @tx_block: dfs cac tx block
+ *
+ * Return: void
+ */
+void ipa_set_dfs_cac_tx(struct wlan_objmgr_pdev *pdev, bool tx_block);
+
+/**
+ * ipa_set_ap_ibss_fwd() - Set AP intra bss forward
+ * @pdev: pdev obj
+ * @intra_bss: enable or disable ap intra bss forward
+ *
+ * Return: void
+ */
+void ipa_set_ap_ibss_fwd(struct wlan_objmgr_pdev *pdev, bool intra_bss);
+
+/**
+ * ipa_uc_force_pipe_shutdown() - Force IPA pipe shutdown
+ * @pdev: pdev obj
+ *
+ * Return: void
+ */
+void ipa_uc_force_pipe_shutdown(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ipa_flush() - flush IPA exception path SKB's
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ipa_flush(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ipa_suspend() - Suspend IPA
+ * @pdev: pdev obj
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS ipa_suspend(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ipa_resume() - Resume IPA
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+QDF_STATUS ipa_resume(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_uc_ol_init() - Initialize IPA uC offload
+ * @pdev: pdev obj
+ * @osdev: OS dev
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS ipa_uc_ol_init(struct wlan_objmgr_pdev *pdev,
+			  qdf_device_t osdev);
+
+/**
+ * ucfg_ipa_uc_ol_deinit() - Deinitialize IPA uC offload
+ * @pdev: pdev obj
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ipa_send_mcc_scc_msg() - Send IPA WLAN_SWITCH_TO_MCC/SCC message
+ * @pdev: pdev obj
+ * @mcc_mode: 0=MCC/1=SCC
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev,
+				bool mcc_mode);
+
+/**
+ * ipa_wlan_evt() - IPA event handler
+ * @pdev: pdev obj
+ * @net_dev: Interface net device
+ * @device_mode: Net interface device mode
+ * @sta_id: station id for the event
+ * @session_id: session id for the event
+ * @type: event enum of type ipa_wlan_event
+ * @mac_address: MAC address associated with the event
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ipa_wlan_evt(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev,
+			uint8_t device_mode, uint8_t sta_id, uint8_t session_id,
+			enum wlan_ipa_wlan_event ipa_event_type,
+			uint8_t *mac_addr);
+
+/**
+ * ipa_uc_smmu_map() - Map / Unmap DMA buffer to IPA UC
+ * @map: Map / unmap operation
+ * @num_buf: Number of buffers in array
+ * @buf_arr: Buffer array of DMA mem mapping info
+ *
+ * Return: Status of map operation
+ */
+int ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr);
+
+/**
+ * ipa_is_fw_wdi_activated - Is FW WDI activated?
+ * @pdev: pdev obj
+ *
+ * Return: true if FW WDI activated, false otherwise
+ */
+bool ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ipa_uc_disconnect_ap() - send ap disconnect event
+ * @pdev: pdev obj
+ * @net_dev: Interface net device
+ *
+ * Send disconnect ap event to IPA driver
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
+				qdf_netdev_t net_dev);
+
+/**
+ * ipa_cleanup_dev_iface() - Clean up net dev IPA interface
+ * @pdev: pdev obj
+ * @net_dev: Interface net device
+ *
+ * Return: None
+ */
+void ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
+			   qdf_netdev_t net_dev);
+
+/**
+ * ipa_uc_ssr_cleanup() - handle IPA UC cleanup during SSR
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ipa_fw_rejuvenate_send_msg() - send fw rejuvenate message to IPA driver
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ipa_fw_rejuvenate_send_msg(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ipa_component_config_update() - update ipa config from psoc
+ * @psoc: psoc obj
+ *
+ * Return: None
+ */
+void ipa_component_config_update(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ipa_get_tx_buf_count() - get IPA config tx buffer count
+ *
+ * Return: IPA config tx buffer count
+ */
+
+uint32_t ipa_get_tx_buf_count(void);
+#endif /* IPA_OFFLOAD */
+#endif /* end  of _WLAN_IPA_MAIN_H_ */
diff --git a/components/ipa/core/inc/wlan_ipa_priv.h b/components/ipa/core/inc/wlan_ipa_priv.h
new file mode 100644
index 0000000..8497aad
--- /dev/null
+++ b/components/ipa/core/inc/wlan_ipa_priv.h
@@ -0,0 +1,726 @@
+/*
+ * Copyright (c) 2013-2018 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 privately in IPA
+ * component.
+ */
+
+#ifndef _WLAN_IPA_PRIV_STRUCT_H_
+#define _WLAN_IPA_PRIV_STRUCT_H_
+
+#ifdef IPA_OFFLOAD
+
+#ifdef CONFIG_IPA_WDI_UNIFIED_API
+#include <qdf_ipa_wdi3.h>
+#else
+#include <qdf_ipa.h>
+#endif
+
+#include <qdf_net_types.h>
+#include <qdf_mc_timer.h>
+#include <qdf_list.h>
+#include <qdf_defer.h>
+#include <qdf_event.h>
+#include "wlan_ipa_public_struct.h"
+
+#define WLAN_IPA_RX_INACTIVITY_MSEC_DELAY   1000
+#define WLAN_IPA_UC_WLAN_8023_HDR_SIZE      14
+
+#define WLAN_IPA_UC_NUM_WDI_PIPE            2
+#define WLAN_IPA_UC_MAX_PENDING_EVENT       33
+
+#define WLAN_IPA_UC_DEBUG_DUMMY_MEM_SIZE    32000
+#define WLAN_IPA_UC_RT_DEBUG_PERIOD         300
+#define WLAN_IPA_UC_RT_DEBUG_BUF_COUNT      30
+#define WLAN_IPA_UC_RT_DEBUG_FILL_INTERVAL  10000
+
+#define WLAN_IPA_WLAN_HDR_DES_MAC_OFFSET    0
+#define WLAN_IPA_MAX_IFACE                  3
+#define WLAN_IPA_MAX_SYSBAM_PIPE            4
+#define WLAN_IPA_MAX_SESSION                5
+#define WLAN_IPA_MAX_STA_COUNT              41
+
+#define WLAN_IPA_RX_PIPE                    WLAN_IPA_MAX_IFACE
+#define WLAN_IPA_ENABLE_MASK                BIT(0)
+#define WLAN_IPA_PRE_FILTER_ENABLE_MASK     BIT(1)
+#define WLAN_IPA_IPV6_ENABLE_MASK           BIT(2)
+#define WLAN_IPA_RM_ENABLE_MASK             BIT(3)
+#define WLAN_IPA_CLK_SCALING_ENABLE_MASK    BIT(4)
+#define WLAN_IPA_UC_ENABLE_MASK             BIT(5)
+#define WLAN_IPA_UC_STA_ENABLE_MASK         BIT(6)
+#define WLAN_IPA_REAL_TIME_DEBUGGING        BIT(8)
+
+#define WLAN_IPA_MAX_BANDWIDTH              800
+
+#define WLAN_IPA_MAX_PENDING_EVENT_COUNT    20
+
+#define IPA_WLAN_RX_SOFTIRQ_THRESH 32
+
+/**
+ * enum - IPA UC operation message
+ *
+ * @WLAN_IPA_UC_OPCODE_TX_SUSPEND: IPA WDI TX pipe suspend
+ * @WLAN_IPA_UC_OPCODE_TX_RESUME: IPA WDI TX pipe resume
+ * @WLAN_IPA_UC_OPCODE_RX_SUSPEND: IPA WDI RX pipe suspend
+ * @WLAN_IPA_UC_OPCODE_RX_RESUME: IPA WDI RX pipe resume
+ * @WLAN_IPA_UC_OPCODE_STATS: IPA UC stats
+ * @WLAN_IPA_UC_OPCODE_SHARING_STATS: IPA UC sharing stats
+ * @WLAN_IPA_UC_OPCODE_QUOTA_RSP: IPA UC quota response
+ * @WLAN_IPA_UC_OPCODE_QUOTA_IND: IPA UC quota indication
+ * @WLAN_IPA_UC_OPCODE_UC_READY: IPA UC ready indication
+ * @WLAN_IPA_UC_OPCODE_MAX: IPA UC max operation code
+ */
+enum wlan_ipa_uc_op_code {
+	WLAN_IPA_UC_OPCODE_TX_SUSPEND = 0,
+	WLAN_IPA_UC_OPCODE_TX_RESUME = 1,
+	WLAN_IPA_UC_OPCODE_RX_SUSPEND = 2,
+	WLAN_IPA_UC_OPCODE_RX_RESUME = 3,
+	WLAN_IPA_UC_OPCODE_STATS = 4,
+#ifdef FEATURE_METERING
+	WLAN_IPA_UC_OPCODE_SHARING_STATS = 5,
+	WLAN_IPA_UC_OPCODE_QUOTA_RSP = 6,
+	WLAN_IPA_UC_OPCODE_QUOTA_IND = 7,
+#endif
+	WLAN_IPA_UC_OPCODE_UC_READY = 8,
+	/* keep this last */
+	WLAN_IPA_UC_OPCODE_MAX
+};
+
+/**
+ * enum - Reason codes for stat query
+ *
+ * @WLAN_IPA_UC_STAT_REASON_NONE: Initial value
+ * @WLAN_IPA_UC_STAT_REASON_DEBUG: For debug/info
+ * @WLAN_IPA_UC_STAT_REASON_BW_CAL: For bandwidth calibration
+ * @WLAN_IPA_UC_STAT_REASON_DUMP_INFO: For debug info dump
+ */
+enum {
+	WLAN_IPA_UC_STAT_REASON_NONE,
+	WLAN_IPA_UC_STAT_REASON_DEBUG,
+	WLAN_IPA_UC_STAT_REASON_BW_CAL
+};
+
+/**
+ * enum wlan_ipa_rm_state - IPA resource manager state
+ * @WLAN_IPA_RM_RELEASED:      PROD pipe resource released
+ * @WLAN_IPA_RM_GRANT_PENDING: PROD pipe resource requested but not granted yet
+ * @WLAN_IPA_RM_GRANTED:       PROD pipe resource granted
+ */
+enum wlan_ipa_rm_state {
+	WLAN_IPA_RM_RELEASED,
+	WLAN_IPA_RM_GRANT_PENDING,
+	WLAN_IPA_RM_GRANTED,
+};
+
+/**
+ * enum wlan_ipa_forward_type: Type of forward packet received from IPA
+ * @WLAN_IPA_FORWARD_PKT_NONE: No forward packet
+ * @WLAN_IPA_FORWARD_PKT_LOCAL_STACK: Packet forwarded to kernel network stack
+ * @WLAN_IPA_FORWARD_PKT_DISCARD: Discarded packet before sending to kernel
+ */
+enum wlan_ipa_forward_type {
+	WLAN_IPA_FORWARD_PKT_NONE = 0,
+	WLAN_IPA_FORWARD_PKT_LOCAL_STACK = 1,
+	WLAN_IPA_FORWARD_PKT_DISCARD = 2
+};
+
+/**
+ * struct llc_snap_hdr - LLC snap header
+ * @dsap: Destination service access point
+ * @ssap: Source service access point
+ * @resv: Reserved for future use
+ * @eth_type: Ether type
+ */
+struct llc_snap_hdr {
+	uint8_t dsap;
+	uint8_t ssap;
+	uint8_t resv[4];
+	qdf_be16_t eth_type;
+} qdf_packed;
+
+/**
+ * struct wlan_ipa_tx_hdr - header type which IPA should handle to TX packet
+ * @eth:      ether II header
+ * @llc_snap: LLC snap header
+ */
+struct wlan_ipa_tx_hdr {
+	qdf_ether_header_t eth;
+	struct llc_snap_hdr llc_snap;
+} qdf_packed;
+
+/**
+ * struct frag_header - fragment header type registered to IPA hardware
+ * @length:    fragment length
+ * @reserved1: Reserved not used
+ * @reserved2: Reserved not used
+ */
+#if defined(QCA_WIFI_3_0) || \
+    defined(QCA_WIFI_QCA6290) || \
+    defined(QCA_WIFI_QCA6390)
+struct frag_header {
+	uint16_t length;
+	uint32_t reserved1;
+	uint32_t reserved2;
+} qdf_packed;
+#else
+struct frag_header {
+	uint32_t
+		length:16,
+		reserved16:16;
+	uint32_t reserved2;
+} qdf_packed;
+#endif
+
+/**
+ * struct ipa_header - ipa header type registered to IPA hardware
+ * @vdev_id:  vdev id
+ * @reserved: Reserved not used
+ */
+struct ipa_header {
+	uint32_t
+		vdev_id:8,	/* vdev_id field is LSB of IPA DESC */
+		reserved:24;
+} qdf_packed;
+
+/**
+ * struct wlan_ipa_uc_tx_hdr - full tx header registered to IPA hardware
+ * @frag_hd: fragment header
+ * @ipa_hd:  ipa header
+ * @eth:     ether II header
+ */
+struct wlan_ipa_uc_tx_hdr {
+	struct frag_header frag_hd;
+	struct ipa_header ipa_hd;
+	qdf_ether_header_t eth;
+} qdf_packed;
+
+/**
+ * struct wlan_ipa_cld_hdr - IPA CLD Header
+ * @reserved: reserved fields
+ * @iface_id: interface ID
+ * @sta_id: Station ID
+ *
+ * Packed 32-bit structure
+ * +----------+----------+--------------+--------+
+ * | Reserved | QCMAP ID | interface id | STA ID |
+ * +----------+----------+--------------+--------+
+ */
+struct wlan_ipa_cld_hdr {
+	uint8_t reserved[2];
+	uint8_t iface_id;
+	uint8_t sta_id;
+} qdf_packed;
+
+/**
+ * struct wlan_ipa_rx_hdr - IPA RX header
+ * @cld_hdr: IPA CLD header
+ * @eth:     ether II header
+ */
+struct wlan_ipa_rx_hdr {
+	struct wlan_ipa_cld_hdr cld_hdr;
+	qdf_ether_header_t eth;
+} qdf_packed;
+
+/**
+ * struct wlan_ipa_pm_tx_cb - PM resume TX callback
+ * @exception: Exception packet
+ * @iface_context: Interface context
+ * @ipa_tx_desc: IPA TX descriptor
+ */
+struct wlan_ipa_pm_tx_cb {
+	bool exception;
+	struct wlan_ipa_iface_context *iface_context;
+	qdf_ipa_rx_data_t *ipa_tx_desc;
+};
+
+/**
+ * struct wlan_ipa_sys_pipe - IPA system pipe
+ * @conn_hdl: IPA system pipe connection handle
+ * @conn_hdl_valid: IPA system pipe valid flag
+ * @ipa_sys_params: IPA system pipe params
+ */
+struct wlan_ipa_sys_pipe {
+	uint32_t conn_hdl;
+	uint8_t conn_hdl_valid;
+	qdf_ipa_sys_connect_params_t ipa_sys_params;
+};
+
+/**
+ * struct wlan_ipa_iface_stats - IPA system pipe
+ * @num_tx: Number of TX packets
+ * @num_tx_drop: Number of TX packet drops
+ * @num_tx_err: Number of TX packet errors
+ * @num_tx_cac_drop: Number of TX packet drop due to CAC
+ * @num_rx_ipa_excep: Number of RX IPA exception packets
+ */
+struct wlan_ipa_iface_stats {
+	uint64_t num_tx;
+	uint64_t num_tx_drop;
+	uint64_t num_tx_err;
+	uint64_t num_tx_cac_drop;
+	uint64_t num_rx_ipa_excep;
+};
+
+/* IPA private context structure */
+struct wlan_ipa_priv;
+
+/**
+ * struct wlan_ipa_iface_context - IPA interface context
+ * @ipa_ctx: IPA private context
+ * @tl_context: TL context
+ * @cons_client: IPA consumer pipe
+ * @prod_client: IPA producer pipe
+ * @prod_client: IPA producer pipe
+ * @iface_id: IPA interface ID
+ * @dev: Net device structure
+ * @device_mode: Interface device mode
+ * @sta_id: Interface station ID
+ * @session_id: Session ID
+ * @interface_lock: Interface lock
+ * @ifa_address: Interface address
+ * @stats: Interface stats
+ */
+struct wlan_ipa_iface_context {
+	struct wlan_ipa_priv *ipa_ctx;
+	void *tl_context;
+
+	qdf_ipa_client_type_t cons_client;
+	qdf_ipa_client_type_t prod_client;
+
+	uint8_t iface_id;       /* This iface ID */
+	qdf_netdev_t dev;
+	enum QDF_OPMODE device_mode;
+	uint8_t sta_id;         /* This iface station ID */
+	uint8_t session_id;
+	qdf_spinlock_t interface_lock;
+	uint32_t ifa_address;
+	struct wlan_ipa_iface_stats stats;
+};
+
+/**
+ * struct wlan_ipa_stats - IPA system stats
+ * @event: WLAN IPA event record
+ * @num_send_msg: Number of sent IPA messages
+ * @num_rm_grant: Number of times IPA RM resource granted
+ * @num_rm_release: Number of times IPA RM resource released
+ * @num_rm_grant_imm: Number of immediate IPA RM granted
+ e @num_cons_perf_req: Number of CONS pipe perf request
+ * @num_prod_perf_req: Number of PROD pipe perf request
+ * @num_rx_drop: Number of RX packet drops
+ * @num_tx_desc_q_cnt: Number of TX descriptor queue count
+ * @num_tx_desc_err: Number of TX descriptor error
+ * @num_tx_comp_cnt: Number of TX qdf_event_t count
+ * @num_tx_queued: Number of TX queued
+ * @num_tx_dequeued: Number of TX dequeued
+ * @num_max_pm_queue: Number of packets in PM queue
+ * @num_rx_excep: Number of RX IPA exception packets
+ * @num_tx_fwd_ok: Number of TX forward packet success
+ * @num_tx_fwd_err: Number of TX forward packet failures
+ */
+struct wlan_ipa_stats {
+	uint32_t event[QDF_IPA_WLAN_EVENT_MAX];
+	uint64_t num_send_msg;
+	uint64_t num_free_msg;
+	uint64_t num_rm_grant;
+	uint64_t num_rm_release;
+	uint64_t num_rm_grant_imm;
+	uint64_t num_cons_perf_req;
+	uint64_t num_prod_perf_req;
+	uint64_t num_rx_drop;
+	uint64_t num_tx_desc_q_cnt;
+	uint64_t num_tx_desc_error;
+	uint64_t num_tx_comp_cnt;
+	uint64_t num_tx_queued;
+	uint64_t num_tx_dequeued;
+	uint64_t num_max_pm_queue;
+	uint64_t num_rx_excep;
+	uint64_t num_tx_fwd_ok;
+	uint64_t num_tx_fwd_err;
+};
+
+/**
+ * struct ipa_uc_stas_map - IPA UC assoc station map
+ * @is_reserved: STA reserved flag
+ * @sta_id: Station ID
+ * @mac_addr: Station mac address
+ */
+struct ipa_uc_stas_map {
+	bool is_reserved;
+	uint8_t sta_id;
+	struct qdf_mac_addr mac_addr;
+};
+
+/**
+ * struct op_msg_type - IPA operation message type
+ * @msg_t: Message type
+ * @rsvd: Reserved
+ * @op_code: IPA Operation type
+ * @len: IPA message length
+ * @rsvd_snd: Reserved
+ */
+struct op_msg_type {
+	uint8_t msg_t;
+	uint8_t rsvd;
+	uint16_t op_code;
+	uint16_t len;
+	uint16_t rsvd_snd;
+};
+
+/**
+ * struct ipa_uc_fw_stats - IPA FW stats
+ * @tx_comp_ring_size: TX completion ring size
+ * @txcomp_ring_dbell_addr: TX comp ring door bell address
+ * @txcomp_ring_dbell_ind_val: TX cop ring door bell indication
+ * @txcomp_ring_dbell_cached_val: TX cop ring cached value
+ * @txpkts_enqueued: TX packets enqueued
+ * @txpkts_completed: TX packets completed
+ * @tx_is_suspend: TX suspend flag
+ * @tx_reserved: Reserved for TX stat
+ * @rx_ind_ring_base: RX indication ring base addess
+ * @rx_ind_ring_size: RX indication ring size
+ * @rx_ind_ring_dbell_addr: RX indication ring doorbell address
+ * @rx_ind_ring_dbell_ind_val: RX indication ring doorbell indication
+ * @rx_ind_ring_dbell_ind_cached_val: RX indication ring doorbell cached value
+ * @rx_ind_ring_rdidx_addr: RX indication ring read index address
+ * @rx_ind_ring_rd_idx_cached_val: RX indication ring read index cached value
+ * @rx_refill_idx: RX ring refill index
+ * @rx_num_pkts_indicated: Number of RX packets indicated
+ * @rx_buf_refilled: Number of RX buffer refilled
+ * @rx_num_ind_drop_no_space: Number of RX indication drops due to no space
+ * @rx_num_ind_drop_no_buf: Number of RX indication drops due to no buffer
+ * @rx_is_suspend: RX suspend flag
+ * @rx_reserved: Reserved for RX stat
+ */
+struct ipa_uc_fw_stats {
+	uint32_t tx_comp_ring_base;
+	uint32_t tx_comp_ring_size;
+	uint32_t tx_comp_ring_dbell_addr;
+	uint32_t tx_comp_ring_dbell_ind_val;
+	uint32_t tx_comp_ring_dbell_cached_val;
+	uint32_t tx_pkts_enqueued;
+	uint32_t tx_pkts_completed;
+	uint32_t tx_is_suspend;
+	uint32_t tx_reserved;
+	uint32_t rx_ind_ring_base;
+	uint32_t rx_ind_ring_size;
+	uint32_t rx_ind_ring_dbell_addr;
+	uint32_t rx_ind_ring_dbell_ind_val;
+	uint32_t rx_ind_ring_dbell_ind_cached_val;
+	uint32_t rx_ind_ring_rdidx_addr;
+	uint32_t rx_ind_ring_rd_idx_cached_val;
+	uint32_t rx_refill_idx;
+	uint32_t rx_num_pkts_indicated;
+	uint32_t rx_buf_refilled;
+	uint32_t rx_num_ind_drop_no_space;
+	uint32_t rx_num_ind_drop_no_buf;
+	uint32_t rx_is_suspend;
+	uint32_t rx_reserved;
+};
+
+/**
+ * struct wlan_ipa_uc_pending_event - WLAN IPA UC pending event
+ * @node: Pending event list node
+ * @type: WLAN IPA event type
+ * @device_mode: Device mode
+ * @sta_id: Station ID
+ * @session_id: Session ID
+ * @mac_addr: Mac address
+ * @is_loading: Driver loading flag
+ */
+struct wlan_ipa_uc_pending_event {
+	qdf_list_node_t node;
+	qdf_ipa_wlan_event type;
+	qdf_netdev_t net_dev;
+	uint8_t device_mode;
+	uint8_t sta_id;
+	uint8_t session_id;
+	uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
+	bool is_loading;
+};
+
+/**
+ * struct uc_rm_work_struct
+ * @work: uC RM work
+ * @event: IPA RM event
+ */
+struct uc_rm_work_struct {
+	qdf_work_t work;
+	qdf_ipa_rm_event_t event;
+};
+
+/**
+ * struct uc_op_work_struct
+ * @work: uC OP work
+ * @msg: OP message
+ */
+struct uc_op_work_struct {
+	qdf_work_t work;
+	struct op_msg_type *msg;
+};
+
+/**
+ * struct uc_rt_debug_info
+ * @time: system time
+ * @ipa_excep_count: IPA exception packet count
+ * @rx_drop_count: IPA Rx drop packet count
+ * @net_sent_count: IPA Rx packet sent to network stack count
+ * @rx_discard_count: IPA Rx discard packet count
+ * @tx_fwd_ok_count: IPA Tx forward success packet count
+ * @tx_fwd_count: IPA Tx forward packet count
+ * @rx_destructor_call: IPA Rx packet destructor count
+ */
+struct uc_rt_debug_info {
+	uint64_t time;
+	uint64_t ipa_excep_count;
+	uint64_t rx_drop_count;
+	uint64_t net_sent_count;
+	uint64_t rx_discard_count;
+	uint64_t tx_fwd_ok_count;
+	uint64_t tx_fwd_count;
+	uint64_t rx_destructor_call;
+};
+
+#ifdef FEATURE_METERING
+/**
+ * struct ipa_uc_sharing_stats - IPA UC sharing stats
+ * @ipv4_rx_packets: IPv4 RX packets
+ * @ipv4_rx_bytes: IPv4 RX bytes
+ * @ipv6_rx_packets: IPv6 RX packets
+ * @ipv6_rx_bytes: IPv6 RX bytes
+ * @ipv4_tx_packets: IPv4 TX packets
+ * @ipv4_tx_bytes: IPv4 TX bytes
+ * @ipv6_tx_packets: IPv4 TX packets
+ * @ipv6_tx_bytes: IPv6 TX bytes
+ */
+struct ipa_uc_sharing_stats {
+	uint64_t ipv4_rx_packets;
+	uint64_t ipv4_rx_bytes;
+	uint64_t ipv6_rx_packets;
+	uint64_t ipv6_rx_bytes;
+	uint64_t ipv4_tx_packets;
+	uint64_t ipv4_tx_bytes;
+	uint64_t ipv6_tx_packets;
+	uint64_t ipv6_tx_bytes;
+};
+
+/**
+ * struct ipa_uc_quota_rsp - IPA UC quota response
+ * @success: Success or fail flag
+ * @reserved[3]: Reserved
+ * @quota_lo: Quota limit low bytes
+ * @quota_hi: Quota limit high bytes
+ */
+struct ipa_uc_quota_rsp {
+	uint8_t success;
+	uint8_t reserved[3];
+	uint32_t quota_lo;
+	uint32_t quota_hi;
+};
+
+/**
+ * struct ipa_uc_quota_ind
+ * @quota_bytes: Quota bytes to set
+ */
+struct ipa_uc_quota_ind {
+	uint64_t quota_bytes;
+};
+#endif
+
+/**
+ * struct wlan_ipa_tx_desc
+ * @node: TX descriptor node
+ * @priv: pointer to priv list entry
+ * @id: Tx desc idex
+ * @ipa_tx_desc_ptr: pointer to IPA Tx descriptor
+ */
+struct wlan_ipa_tx_desc {
+	qdf_list_node_t node;
+	void *priv;
+	uint32_t id;
+	qdf_ipa_rx_data_t *ipa_tx_desc_ptr;
+};
+
+typedef int (*wlan_ipa_softap_xmit)(qdf_nbuf_t skb, qdf_netdev_t dev);
+typedef int (*wlan_ipa_send_to_nw)(qdf_nbuf_t skb, qdf_netdev_t dev);
+
+/* IPA private context structure definition */
+struct wlan_ipa_priv {
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_ipa_sys_pipe sys_pipe[WLAN_IPA_MAX_SYSBAM_PIPE];
+	struct wlan_ipa_iface_context iface_context[WLAN_IPA_MAX_IFACE];
+	uint8_t num_iface;
+	void *dp_soc;
+	void *dp_pdev;
+	struct wlan_ipa_config *config;
+	enum wlan_ipa_rm_state rm_state;
+	/*
+	 * IPA driver can send RM notifications with IRQ disabled so using qdf
+	 * APIs as it is taken care gracefully. Without this, kernel would throw
+	 * an warning if spin_lock_bh is used while IRQ is disabled
+	 */
+	qdf_spinlock_t rm_lock;
+	struct uc_rm_work_struct uc_rm_work;
+	struct uc_op_work_struct uc_op_work[WLAN_IPA_UC_OPCODE_MAX];
+	qdf_wake_lock_t wake_lock;
+	qdf_delayed_work_t wake_lock_work;
+	bool wake_lock_released;
+
+	qdf_atomic_t tx_ref_cnt;
+	qdf_nbuf_queue_t pm_queue_head;
+	qdf_work_t pm_work;
+	qdf_spinlock_t pm_lock;
+	bool suspended;
+
+	qdf_spinlock_t q_lock;
+
+	qdf_list_node_t pend_desc_head;
+	struct wlan_ipa_tx_desc *tx_desc_pool;
+	qdf_list_t tx_desc_free_list;
+
+	struct wlan_ipa_stats stats;
+
+	uint32_t curr_prod_bw;
+	uint32_t curr_cons_bw;
+
+	uint8_t activated_fw_pipe;
+	uint8_t sap_num_connected_sta;
+	uint8_t sta_connected;
+	uint32_t tx_pipe_handle;
+	uint32_t rx_pipe_handle;
+	bool resource_loading;
+	bool resource_unloading;
+	bool pending_cons_req;
+	struct ipa_uc_stas_map assoc_stas_map[WLAN_IPA_MAX_STA_COUNT];
+	qdf_list_t pending_event;
+	qdf_mutex_t event_lock;
+	bool ipa_pipes_down;
+	uint32_t ipa_tx_packets_diff;
+	uint32_t ipa_rx_packets_diff;
+	uint32_t ipa_p_tx_packets;
+	uint32_t ipa_p_rx_packets;
+	uint32_t stat_req_reason;
+	uint64_t ipa_tx_forward;
+	uint64_t ipa_rx_discard;
+	uint64_t ipa_rx_net_send_count;
+	uint64_t ipa_rx_internal_drop_count;
+	uint64_t ipa_rx_destructor_count;
+	qdf_mc_timer_t rt_debug_timer;
+	struct uc_rt_debug_info rt_bug_buffer[WLAN_IPA_UC_RT_DEBUG_BUF_COUNT];
+	unsigned int rt_buf_fill_index;
+	qdf_ipa_wdi_in_params_t cons_pipe_in;
+	qdf_ipa_wdi_in_params_t prod_pipe_in;
+	bool uc_loaded;
+	bool wdi_enabled;
+	qdf_mc_timer_t rt_debug_fill_timer;
+	qdf_mutex_t rt_debug_lock;
+	qdf_mutex_t ipa_lock;
+
+	uint8_t vdev_to_iface[WLAN_IPA_MAX_SESSION];
+	bool vdev_offload_enabled[WLAN_IPA_MAX_SESSION];
+	bool mcc_mode;
+	qdf_work_t mcc_work;
+	bool ap_intrabss_fwd;
+	bool dfs_cac_block_tx;
+#ifdef FEATURE_METERING
+	struct ipa_uc_sharing_stats ipa_sharing_stats;
+	struct ipa_uc_quota_rsp ipa_quota_rsp;
+	struct ipa_uc_quota_ind ipa_quota_ind;
+	qdf_event_t ipa_uc_sharing_stats_comp;
+	qdf_event_t ipa_uc_set_quota_comp;
+#endif
+
+	wlan_ipa_softap_xmit softap_xmit;
+	wlan_ipa_send_to_nw send_to_nw;
+	ipa_uc_offload_control_req ipa_tx_op;
+
+	qdf_event_t ipa_resource_comp;
+
+	uint32_t wdi_version;
+	bool is_smmu_enabled;	/* IPA caps returned from ipa_wdi_init */
+};
+
+#define WLAN_IPA_WLAN_FRAG_HEADER        sizeof(struct frag_header)
+#define WLAN_IPA_WLAN_IPA_HEADER         sizeof(struct ipa_header)
+#define WLAN_IPA_WLAN_CLD_HDR_LEN        sizeof(struct wlan_ipa_cld_hdr)
+#define WLAN_IPA_UC_WLAN_CLD_HDR_LEN     0
+#define WLAN_IPA_WLAN_TX_HDR_LEN         sizeof(struct wlan_ipa_tx_hdr)
+#define WLAN_IPA_UC_WLAN_TX_HDR_LEN      sizeof(struct wlan_ipa_uc_tx_hdr)
+#define WLAN_IPA_WLAN_RX_HDR_LEN         sizeof(struct wlan_ipa_rx_hdr)
+#define WLAN_IPA_UC_WLAN_HDR_DES_MAC_OFFSET \
+	(WLAN_IPA_WLAN_FRAG_HEADER + WLAN_IPA_WLAN_IPA_HEADER)
+
+#define WLAN_IPA_GET_IFACE_ID(_data) \
+	(((struct wlan_ipa_cld_hdr *) (_data))->iface_id)
+
+#define WLAN_IPA_LOG(LVL, fmt, args ...) \
+	QDF_TRACE(QDF_MODULE_ID_IPA, LVL, \
+		  "%s:%d: "fmt, __func__, __LINE__, ## args)
+
+#define WLAN_IPA_IS_CONFIG_ENABLED(_ipa_cfg, _mask) \
+	(((_ipa_cfg)->ipa_config & (_mask)) == (_mask))
+
+#define BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
+
+#define WLAN_IPA_DBG_DUMP_RX_LEN 84
+#define WLAN_IPA_DBG_DUMP_TX_LEN 48
+
+#define IPA_RESOURCE_COMP_WAIT_TIME	100
+
+#ifdef FEATURE_METERING
+#define IPA_UC_SHARING_STATES_WAIT_TIME	500
+#define IPA_UC_SET_QUOTA_WAIT_TIME	500
+#endif
+
+/**
+ * wlan_ipa_wlan_event_to_str() - convert IPA WLAN event to string
+ * @event: IPA WLAN event to be converted to a string
+ *
+ * Return: ASCII string representing the IPA WLAN event
+ */
+static inline char *wlan_ipa_wlan_event_to_str(qdf_ipa_wlan_event event)
+{
+	switch (event) {
+	CASE_RETURN_STRING(QDF_IPA_CLIENT_CONNECT);
+	CASE_RETURN_STRING(QDF_IPA_CLIENT_DISCONNECT);
+	CASE_RETURN_STRING(QDF_IPA_AP_CONNECT);
+	CASE_RETURN_STRING(QDF_IPA_AP_DISCONNECT);
+	CASE_RETURN_STRING(QDF_IPA_STA_CONNECT);
+	CASE_RETURN_STRING(QDF_IPA_STA_DISCONNECT);
+	CASE_RETURN_STRING(QDF_IPA_CLIENT_CONNECT_EX);
+	CASE_RETURN_STRING(QDF_SWITCH_TO_SCC);
+	CASE_RETURN_STRING(QDF_SWITCH_TO_MCC);
+	CASE_RETURN_STRING(QDF_WDI_ENABLE);
+	CASE_RETURN_STRING(QDF_WDI_DISABLE);
+	default:
+		return "UNKNOWN";
+	}
+}
+
+/**
+ * wlan_ipa_get_iface() - Get IPA interface
+ * @ipa_ctx: IPA context
+ * @mode: Interface device mode
+ *
+ * Return: IPA interface address
+ */
+struct wlan_ipa_iface_context
+*wlan_ipa_get_iface(struct wlan_ipa_priv *ipa_ctx, uint8_t mode);
+
+#endif /* IPA_OFFLOAD */
+#endif /* _WLAN_IPA_PRIV_STRUCT_H_ */
diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c
new file mode 100644
index 0000000..27f1152
--- /dev/null
+++ b/components/ipa/core/src/wlan_ipa_core.c
@@ -0,0 +1,3083 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/* Include Files */
+#include "wlan_ipa_core.h"
+#include "wlan_ipa_main.h"
+#include <ol_txrx.h>
+#include "cdp_txrx_ipa.h"
+#include "wal_rx_desc.h"
+#include "qdf_str.h"
+
+static struct wlan_ipa_priv *gp_ipa;
+
+static struct wlan_ipa_iface_2_client {
+	qdf_ipa_client_type_t cons_client;
+	qdf_ipa_client_type_t prod_client;
+} wlan_ipa_iface_2_client[WLAN_IPA_MAX_IFACE] = {
+	{
+		QDF_IPA_CLIENT_WLAN2_CONS, QDF_IPA_CLIENT_WLAN1_PROD
+	}, {
+		QDF_IPA_CLIENT_WLAN3_CONS, QDF_IPA_CLIENT_WLAN1_PROD
+	}, {
+		QDF_IPA_CLIENT_WLAN4_CONS, QDF_IPA_CLIENT_WLAN1_PROD
+	}
+};
+
+/* Local Function Prototypes */
+static void wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
+			    unsigned long data);
+static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
+			    unsigned long data);
+
+/**
+ * wlan_ipa_uc_sta_is_enabled() - Is STA mode IPA uC offload enabled?
+ * @ipa_cfg: IPA config
+ *
+ * Return: true if STA mode IPA uC offload is enabled, false otherwise
+ */
+static inline bool wlan_ipa_uc_sta_is_enabled(struct wlan_ipa_config *ipa_cfg)
+{
+	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg, WLAN_IPA_UC_STA_ENABLE_MASK);
+}
+
+/**
+ * wlan_ipa_is_pre_filter_enabled() - Is IPA pre-filter enabled?
+ * @ipa_cfg: IPA config
+ *
+ * Return: true if pre-filter is enabled, otherwise false
+ */
+static inline
+bool wlan_ipa_is_pre_filter_enabled(struct wlan_ipa_config *ipa_cfg)
+{
+	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg,
+					 WLAN_IPA_PRE_FILTER_ENABLE_MASK);
+}
+
+/**
+ * wlan_ipa_is_ipv6_enabled() - Is IPA IPv6 enabled?
+ * @ipa_cfg: IPA config
+ *
+ * Return: true if IPv6 is enabled, otherwise false
+ */
+static inline bool wlan_ipa_is_ipv6_enabled(struct wlan_ipa_config *ipa_cfg)
+{
+	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg, WLAN_IPA_IPV6_ENABLE_MASK);
+}
+
+/**
+ * wlan_ipa_msg_free_fn() - Free an IPA message
+ * @buff: pointer to the IPA message
+ * @len: length of the IPA message
+ * @type: type of IPA message
+ *
+ * Return: None
+ */
+static void wlan_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type)
+{
+	ipa_debug("msg type:%d, len:%d", type, len);
+	qdf_mem_free(buff);
+}
+
+/**
+ * wlan_ipa_uc_loaded_uc_cb() - IPA UC loaded event callback
+ * @priv_ctxt: IPA context
+ *
+ * Will be called by IPA context.
+ * It's atomic context, then should be scheduled to kworker thread
+ *
+ * Return: None
+ */
+static void wlan_ipa_uc_loaded_uc_cb(void *priv_ctxt)
+{
+	struct wlan_ipa_priv *ipa_ctx;
+	struct op_msg_type *msg;
+	struct uc_op_work_struct *uc_op_work;
+
+	if (!priv_ctxt) {
+		ipa_err("Invalid IPA context");
+		return;
+	}
+
+	ipa_ctx = priv_ctxt;
+	ipa_ctx->uc_loaded = true;
+
+	uc_op_work = &ipa_ctx->uc_op_work[WLAN_IPA_UC_OPCODE_UC_READY];
+	if (!list_empty(&uc_op_work->work.work.entry)) {
+		/* uc_op_work is not initialized yet */
+		return;
+	}
+
+	msg = qdf_mem_malloc(sizeof(*msg));
+	if (!msg) {
+		ipa_err("op_msg allocation fails");
+		return;
+	}
+
+	msg->op_code = WLAN_IPA_UC_OPCODE_UC_READY;
+
+	/* When the same uC OPCODE is already pended, just return */
+	if (uc_op_work->msg)
+		goto done;
+
+	uc_op_work->msg = msg;
+	qdf_sched_work(0, &uc_op_work->work);
+
+	/* work handler will free the msg buffer */
+	return;
+
+done:
+	qdf_mem_free(msg);
+}
+
+/**
+ * wlan_ipa_uc_send_wdi_control_msg() - Set WDI control message
+ * @ctrl: WDI control value
+ *
+ * Send WLAN_WDI_ENABLE for ctrl = true and WLAN_WDI_DISABLE otherwise.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS wlan_ipa_uc_send_wdi_control_msg(bool ctrl)
+{
+	struct wlan_ipa_priv *ipa_ctx = gp_ipa;
+	qdf_ipa_msg_meta_t meta;
+	qdf_ipa_wlan_msg_t *ipa_msg;
+	int ret = 0;
+
+	/* WDI enable message to IPA */
+	QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(*ipa_msg);
+	ipa_msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
+	if (!ipa_msg) {
+		ipa_err("msg allocation failed");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	if (ctrl) {
+		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_WDI_ENABLE);
+		ipa_ctx->stats.event[QDF_WDI_ENABLE]++;
+	} else {
+		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_WDI_DISABLE);
+		ipa_ctx->stats.event[QDF_WDI_DISABLE]++;
+	}
+
+	ipa_debug("ipa_send_msg(Evt:%d)", QDF_IPA_MSG_META_MSG_TYPE(&meta));
+	ret = qdf_ipa_send_msg(&meta, ipa_msg, wlan_ipa_msg_free_fn);
+	if (ret) {
+		ipa_err("ipa_send_msg(Evt:%d)-fail=%d",
+			QDF_IPA_MSG_META_MSG_TYPE(&meta), ret);
+		qdf_mem_free(ipa_msg);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+struct wlan_ipa_priv *wlan_ipa_get_obj_context(void)
+{
+	return gp_ipa;
+}
+
+/**
+ * wlan_ipa_send_pkt_to_tl() - Send an IPA packet to TL
+ * @iface_context: interface-specific IPA context
+ * @ipa_tx_desc: packet data descriptor
+ *
+ * Return: None
+ */
+static void wlan_ipa_send_pkt_to_tl(
+		struct wlan_ipa_iface_context *iface_context,
+		qdf_ipa_rx_data_t *ipa_tx_desc)
+{
+	struct wlan_ipa_priv *ipa_ctx = iface_context->ipa_ctx;
+	struct wlan_objmgr_pdev *pdev = ipa_ctx->pdev;
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+	qdf_device_t osdev = wlan_psoc_get_qdf_dev(psoc);
+	qdf_nbuf_t skb;
+	struct wlan_ipa_tx_desc *tx_desc;
+	qdf_dma_addr_t paddr;
+	QDF_STATUS status;
+
+	qdf_spin_lock_bh(&iface_context->interface_lock);
+	/*
+	 * During CAC period, data packets shouldn't be sent over the air so
+	 * drop all the packets here
+	 */
+	if (iface_context->device_mode == QDF_SAP_MODE ||
+	    iface_context->device_mode == QDF_P2P_GO_MODE) {
+		if (ipa_ctx->dfs_cac_block_tx) {
+			ipa_free_skb(ipa_tx_desc);
+			qdf_spin_unlock_bh(&iface_context->interface_lock);
+			iface_context->stats.num_tx_cac_drop++;
+			wlan_ipa_wdi_rm_try_release(ipa_ctx);
+			return;
+		}
+	}
+
+	if (!osdev) {
+		ipa_free_skb(ipa_tx_desc);
+		iface_context->stats.num_tx_drop++;
+		qdf_spin_unlock_bh(&iface_context->interface_lock);
+		wlan_ipa_wdi_rm_try_release(ipa_ctx);
+		return;
+	}
+	qdf_spin_unlock_bh(&iface_context->interface_lock);
+
+	skb = QDF_IPA_RX_DATA_SKB(ipa_tx_desc);
+
+	qdf_mem_set(skb->cb, sizeof(skb->cb), 0);
+
+	/* Store IPA Tx buffer ownership into SKB CB */
+	qdf_nbuf_ipa_owned_set(skb);
+
+	if (qdf_mem_smmu_s1_enabled(osdev)) {
+		status = qdf_nbuf_map(osdev, skb, QDF_DMA_TO_DEVICE);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			paddr = qdf_nbuf_get_frag_paddr(skb, 0);
+		} else {
+			ipa_free_skb(ipa_tx_desc);
+			qdf_spin_lock_bh(&iface_context->interface_lock);
+			iface_context->stats.num_tx_drop++;
+			qdf_spin_unlock_bh(&iface_context->interface_lock);
+			wlan_ipa_wdi_rm_try_release(ipa_ctx);
+			return;
+		}
+	} else {
+		paddr = QDF_IPA_RX_DATA_DMA_ADDR(ipa_tx_desc);
+	}
+
+	if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
+		qdf_nbuf_mapped_paddr_set(skb,
+					  paddr +
+					  WLAN_IPA_WLAN_FRAG_HEADER +
+					  WLAN_IPA_WLAN_IPA_HEADER);
+		QDF_IPA_RX_DATA_SKB_LEN(ipa_tx_desc) -=
+			WLAN_IPA_WLAN_FRAG_HEADER + WLAN_IPA_WLAN_IPA_HEADER;
+	} else {
+		qdf_nbuf_mapped_paddr_set(skb, paddr);
+	}
+
+	qdf_spin_lock_bh(&ipa_ctx->q_lock);
+	/* get free Tx desc and assign ipa_tx_desc pointer */
+	if (qdf_list_remove_front(&ipa_ctx->tx_desc_free_list,
+				  (qdf_list_node_t **)&tx_desc) ==
+	    QDF_STATUS_SUCCESS) {
+		tx_desc->ipa_tx_desc_ptr = ipa_tx_desc;
+		ipa_ctx->stats.num_tx_desc_q_cnt++;
+		qdf_spin_unlock_bh(&ipa_ctx->q_lock);
+		/* Store Tx Desc index into SKB CB */
+		QDF_NBUF_CB_TX_IPA_PRIV(skb) = tx_desc->id;
+	} else {
+		ipa_ctx->stats.num_tx_desc_error++;
+		qdf_spin_unlock_bh(&ipa_ctx->q_lock);
+		qdf_ipa_free_skb(ipa_tx_desc);
+		wlan_ipa_wdi_rm_try_release(ipa_ctx);
+		return;
+	}
+
+	skb = cdp_ipa_tx_send_data_frame(cds_get_context(QDF_MODULE_ID_SOC),
+			(struct cdp_vdev *)iface_context->tl_context,
+			QDF_IPA_RX_DATA_SKB(ipa_tx_desc));
+	if (skb) {
+		qdf_nbuf_free(skb);
+		iface_context->stats.num_tx_err++;
+		return;
+	}
+
+	atomic_inc(&ipa_ctx->tx_ref_cnt);
+
+	iface_context->stats.num_tx++;
+}
+
+#ifdef CONFIG_IPA_WDI_UNIFIED_API
+/*
+ * TODO: Get WDI version through FW capabilities
+ */
+#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390)
+static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx)
+{
+	ipa_ctx->wdi_version = IPA_WDI_3;
+}
+#elif defined(QCA_WIFI_3_0)
+static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx)
+{
+	ipa_ctx->wdi_version = IPA_WDI_2;
+}
+#else
+static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx)
+{
+	ipa_ctx->wdi_version = IPA_WDI_1;
+}
+#endif
+
+static inline bool wlan_ipa_wdi_is_smmu_enabled(struct wlan_ipa_priv *ipa_ctx,
+					       qdf_device_t osdev)
+{
+	return ipa_ctx->is_smmu_enabled && qdf_mem_smmu_s1_enabled(osdev);
+}
+
+static inline QDF_STATUS wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx,
+					    qdf_device_t osdev)
+{
+	qdf_ipa_sys_connect_params_t sys_in[WLAN_IPA_MAX_IFACE];
+	int i;
+
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++)
+		qdf_mem_copy(&sys_in[i],
+			     &ipa_ctx->sys_pipe[i].ipa_sys_params,
+			     sizeof(qdf_ipa_sys_connect_params_t));
+
+	return cdp_ipa_setup(ipa_ctx->dp_soc, ipa_ctx->dp_pdev,
+			     wlan_ipa_i2w_cb, wlan_ipa_w2i_cb,
+			     wlan_ipa_wdi_meter_notifier_cb,
+			     ipa_ctx->config->desc_size,
+			     ipa_ctx, wlan_ipa_is_rm_enabled(ipa_ctx->config),
+			     &ipa_ctx->tx_pipe_handle,
+			     &ipa_ctx->rx_pipe_handle,
+			     wlan_ipa_wdi_is_smmu_enabled(ipa_ctx, osdev),
+			     sys_in);
+}
+
+#ifdef FEATURE_METERING
+/**
+ * wlan_ipa_wdi_init_metering() - IPA WDI metering init
+ * @ipa_ctx: IPA context
+ * @in: IPA WDI in param
+ *
+ * Return: QDF_STATUS
+ */
+static inline void wlan_ipa_wdi_init_metering(struct wlan_ipa_priv *ipa_ctxt,
+					      qdf_ipa_wdi_init_in_params_t *in)
+{
+	QDF_IPA_WDI_INIT_IN_PARAMS_WDI_NOTIFY(in) =
+				wlan_ipa_wdi_meter_notifier_cb;
+}
+#else
+static inline void wlan_ipa_wdi_init_metering(struct wlan_ipa_priv *ipa_ctxt,
+					      qdf_ipa_wdi_init_in_params_t *in)
+{
+}
+#endif
+
+/**
+ * wlan_ipa_wdi_init() - IPA WDI init
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_ipa_wdi_init_in_params_t in;
+	qdf_ipa_wdi_init_out_params_t out;
+	int ret;
+
+	ipa_ctx->uc_loaded = false;
+
+	qdf_mem_zero(&in, sizeof(in));
+	qdf_mem_zero(&out, sizeof(out));
+
+	QDF_IPA_WDI_INIT_IN_PARAMS_WDI_VERSION(&in) = ipa_ctx->wdi_version;
+	QDF_IPA_WDI_INIT_IN_PARAMS_NOTIFY(&in) = wlan_ipa_uc_loaded_uc_cb;
+	QDF_IPA_WDI_INIT_IN_PARAMS_PRIV(&in) = ipa_ctx;
+	wlan_ipa_wdi_init_metering(ipa_ctx, &in);
+
+	ret = qdf_ipa_wdi_init(&in, &out);
+	if (ret) {
+		ipa_err("ipa_wdi_init failed with ret=%d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (QDF_IPA_WDI_INIT_OUT_PARAMS_IS_UC_READY(&out)) {
+		ipa_debug("IPA uC READY");
+		ipa_ctx->uc_loaded = true;
+		ipa_ctx->is_smmu_enabled =
+			QDF_IPA_WDI_INIT_OUT_PARAMS_IS_SMMU_ENABLED(&out);
+		ipa_debug("is_smmu_enabled=%d", ipa_ctx->is_smmu_enabled);
+	} else {
+		return QDF_STATUS_E_BUSY;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline int wlan_ipa_wdi_cleanup(void)
+{
+	int ret;
+
+	ret = qdf_ipa_wdi_cleanup();
+	if (ret)
+		ipa_info("ipa_wdi_cleanup failed ret=%d", ret);
+	return ret;
+}
+
+static inline int wlan_ipa_wdi_setup_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
+					     struct ipa_sys_connect_params *sys,
+					     uint32_t *handle)
+{
+	return 0;
+}
+
+static inline int wlan_ipa_wdi_teardown_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
+						uint32_t handle)
+{
+	return 0;
+}
+
+/**
+ * wlan_ipa_pm_flush() - flush queued packets
+ * @work: pointer to the scheduled work
+ *
+ * Called during PM resume to send packets to TL which were queued
+ * while host was in the process of suspending.
+ *
+ * Return: None
+ */
+static void wlan_ipa_pm_flush(void *data)
+{
+	struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data;
+	struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL;
+	qdf_nbuf_t skb;
+	uint32_t dequeued = 0;
+
+	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+	while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head)) !=
+	       NULL)) {
+		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+
+		pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
+		dequeued++;
+
+		if (pm_tx_cb->exception) {
+			if (ipa_ctx->softap_xmit &&
+			    pm_tx_cb->iface_context->dev) {
+				ipa_ctx->softap_xmit(skb,
+						pm_tx_cb->iface_context->dev);
+				ipa_ctx->stats.num_tx_fwd_ok++;
+			} else {
+				dev_kfree_skb_any(skb);
+			}
+		} else {
+			wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context,
+						pm_tx_cb->ipa_tx_desc);
+		}
+
+		qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+	}
+	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+
+	ipa_ctx->stats.num_tx_dequeued += dequeued;
+	if (dequeued > ipa_ctx->stats.num_max_pm_queue)
+		ipa_ctx->stats.num_max_pm_queue = dequeued;
+}
+
+int wlan_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
+{
+	if (!num_buf) {
+		ipa_info("No buffers to map/unmap");
+		return 0;
+	}
+
+	if (map)
+		return qdf_ipa_wdi_create_smmu_mapping(num_buf, buf_arr);
+	else
+		return qdf_ipa_wdi_release_smmu_mapping(num_buf, buf_arr);
+}
+
+#else /* CONFIG_IPA_WDI_UNIFIED_API */
+
+static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx)
+{
+}
+
+static inline int wlan_ipa_wdi_is_smmu_enabled(struct wlan_ipa_priv *ipa_ctx,
+					       qdf_device_t osdev)
+{
+	return qdf_mem_smmu_s1_enabled(osdev);
+}
+
+static inline QDF_STATUS wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx,
+					    qdf_device_t osdev)
+{
+	return cdp_ipa_setup(ipa_ctx->dp_soc, ipa_ctx->dp_pdev,
+			     wlan_ipa_i2w_cb, wlan_ipa_w2i_cb,
+			     wlan_ipa_wdi_meter_notifier_cb,
+			     ipa_ctx->config->desc_size,
+			     ipa_ctx, wlan_ipa_is_rm_enabled(ipa_ctx->config),
+			     &ipa_ctx->tx_pipe_handle,
+			     &ipa_ctx->rx_pipe_handle);
+}
+
+static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx)
+{
+	struct ipa_wdi_uc_ready_params uc_ready_param;
+
+	ipa_ctx->uc_loaded = false;
+	uc_ready_param.priv = (void *)ipa_ctx;
+	uc_ready_param.notify = wlan_ipa_uc_loaded_uc_cb;
+	if (qdf_ipa_uc_reg_rdyCB(&uc_ready_param)) {
+		ipa_info("UC Ready CB register fail");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (true == uc_ready_param.is_uC_ready) {
+		ipa_info("UC Ready");
+		ipa_ctx->uc_loaded = true;
+	} else {
+		return QDF_STATUS_E_BUSY;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline int wlan_ipa_wdi_cleanup(void)
+{
+	int ret;
+
+	ret = qdf_ipa_uc_dereg_rdyCB();
+	if (ret)
+		ipa_info("UC Ready CB deregister fail");
+	return ret;
+}
+
+static inline int wlan_ipa_wdi_setup_sys_pipe(
+		struct wlan_ipa_priv *ipa_ctx,
+		struct ipa_sys_connect_params *sys, uint32_t *handle)
+{
+	return qdf_ipa_setup_sys_pipe(sys, handle);
+}
+
+static inline int wlan_ipa_wdi_teardown_sys_pipe(
+		struct wlan_ipa_priv *ipa_ctx,
+		uint32_t handle)
+{
+	return qdf_ipa_teardown_sys_pipe(handle);
+}
+
+/**
+ * wlan_ipa_pm_flush() - flush queued packets
+ * @work: pointer to the scheduled work
+ *
+ * Called during PM resume to send packets to TL which were queued
+ * while host was in the process of suspending.
+ *
+ * Return: None
+ */
+static void wlan_ipa_pm_flush(void *data)
+{
+	struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data;
+	struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL;
+	qdf_nbuf_t skb;
+	uint32_t dequeued = 0;
+
+	qdf_wake_lock_acquire(&ipa_ctx->wake_lock,
+			      WIFI_POWER_EVENT_WAKELOCK_IPA);
+	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+	while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head)) !=
+	       NULL)) {
+		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+
+		pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
+		dequeued++;
+
+		if (pm_tx_cb->exception) {
+			if (ipa_ctx->softap_xmit &&
+			    pm_tx_cb->iface_context->dev) {
+				ipa_ctx->softap_xmit(skb,
+						pm_tx_cb->iface_context->dev);
+				ipa_ctx->stats.num_tx_fwd_ok++;
+			} else {
+				dev_kfree_skb_any(skb);
+			}
+		} else {
+			wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context,
+						pm_tx_cb->ipa_tx_desc);
+		}
+
+		qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+	}
+	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+	qdf_wake_lock_release(&ipa_ctx->wake_lock,
+			      WIFI_POWER_EVENT_WAKELOCK_IPA);
+
+	ipa_ctx->stats.num_tx_dequeued += dequeued;
+	if (dequeued > ipa_ctx->stats.num_max_pm_queue)
+		ipa_ctx->stats.num_max_pm_queue = dequeued;
+}
+
+int wlan_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
+{
+	if (!num_buf) {
+		ipa_info("No buffers to map/unmap");
+		return 0;
+	}
+
+	if (map)
+		return qdf_ipa_create_wdi_mapping(num_buf, buf_arr);
+	else
+		return qdf_ipa_release_wdi_mapping(num_buf, buf_arr);
+}
+
+#endif /* CONFIG_IPA_WDI_UNIFIED_API */
+
+/**
+ * wlan_ipa_send_skb_to_network() - Send skb to kernel
+ * @skb: network buffer
+ * @iface_ctx: IPA interface context
+ *
+ * Called when a network buffer is received which should not be routed
+ * to the IPA module.
+ *
+ * Return: None
+ */
+static void
+wlan_ipa_send_skb_to_network(qdf_nbuf_t skb,
+			     struct wlan_ipa_iface_context *iface_ctx)
+{
+	struct wlan_ipa_priv *ipa_ctx = gp_ipa;
+
+	if (!iface_ctx->dev) {
+		ipa_debug_rl("Invalid interface");
+		ipa_ctx->ipa_rx_internal_drop_count++;
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
+	skb->destructor = wlan_ipa_uc_rt_debug_destructor;
+
+	if (ipa_ctx->send_to_nw)
+		ipa_ctx->send_to_nw(skb, iface_ctx->dev);
+
+	ipa_ctx->ipa_rx_net_send_count++;
+}
+
+/**
+ * wlan_ipa_forward() - handle packet forwarding to wlan tx
+ * @ipa_ctx: pointer to ipa ipa context
+ * @iface_ctx: interface context
+ * @skb: data pointer
+ *
+ * if exception packet has set forward bit, copied new packet should be
+ * forwarded to wlan tx. if wlan subsystem is in suspend state, packet should
+ * put into pm queue and tx procedure will be differed
+ *
+ * Return: None
+ */
+static void wlan_ipa_forward(struct wlan_ipa_priv *ipa_ctx,
+			     struct wlan_ipa_iface_context *iface_ctx,
+			     qdf_nbuf_t skb)
+{
+	struct wlan_ipa_pm_tx_cb *pm_tx_cb;
+
+	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+
+	/* Set IPA ownership for intra-BSS Tx packets to avoid skb_orphan */
+	qdf_nbuf_ipa_owned_set(skb);
+
+	/* WLAN subsystem is in suspend, put in queue */
+	if (ipa_ctx->suspended) {
+		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+		ipa_info_rl("Tx in suspend, put in queue");
+		qdf_mem_set(skb->cb, sizeof(skb->cb), 0);
+		pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
+		pm_tx_cb->exception = true;
+		pm_tx_cb->iface_context = iface_ctx;
+		qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+		qdf_nbuf_queue_add(&ipa_ctx->pm_queue_head, skb);
+		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+		ipa_ctx->stats.num_tx_queued++;
+	} else {
+		/* Resume, put packet into WLAN TX */
+		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+
+		if (ipa_ctx->softap_xmit) {
+			if (ipa_ctx->softap_xmit(skb, iface_ctx->dev)) {
+				ipa_err_rl("packet Tx fail");
+				ipa_ctx->stats.num_tx_fwd_err++;
+			} else {
+				ipa_ctx->stats.num_tx_fwd_ok++;
+			}
+		} else {
+			dev_kfree_skb_any(skb);
+		}
+	}
+}
+
+/**
+ * wlan_ipa_intrabss_forward() - Forward intra bss packets.
+ * @ipa_ctx: pointer to IPA IPA struct
+ * @iface_ctx: ipa interface context
+ * @desc: Firmware descriptor
+ * @skb: Data buffer
+ *
+ * Return:
+ *      WLAN_IPA_FORWARD_PKT_NONE
+ *      WLAN_IPA_FORWARD_PKT_DISCARD
+ *      WLAN_IPA_FORWARD_PKT_LOCAL_STACK
+ *
+ */
+
+static enum wlan_ipa_forward_type wlan_ipa_intrabss_forward(
+		struct wlan_ipa_priv *ipa_ctx,
+		struct wlan_ipa_iface_context *iface_ctx,
+		uint8_t desc,
+		qdf_nbuf_t skb)
+{
+	int ret = WLAN_IPA_FORWARD_PKT_NONE;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if ((desc & FW_RX_DESC_FORWARD_M)) {
+		if (!ol_txrx_fwd_desc_thresh_check(
+			(struct ol_txrx_vdev_t *)cdp_get_vdev_from_vdev_id(soc,
+						(struct cdp_pdev *)pdev,
+						iface_ctx->session_id))) {
+			/* Drop the packet*/
+			ipa_ctx->stats.num_tx_fwd_err++;
+			dev_kfree_skb_any(skb);
+			ret = WLAN_IPA_FORWARD_PKT_DISCARD;
+			return ret;
+		}
+		ipa_debug_rl("Forward packet to Tx (fw_desc=%d)", desc);
+		ipa_ctx->ipa_tx_forward++;
+
+		if ((desc & FW_RX_DESC_DISCARD_M)) {
+			wlan_ipa_forward(ipa_ctx, iface_ctx, skb);
+			ipa_ctx->ipa_rx_internal_drop_count++;
+			ipa_ctx->ipa_rx_discard++;
+			ret = WLAN_IPA_FORWARD_PKT_DISCARD;
+		} else {
+			struct sk_buff *cloned_skb = skb_clone(skb, GFP_ATOMIC);
+
+			if (cloned_skb)
+				wlan_ipa_forward(ipa_ctx, iface_ctx,
+						 cloned_skb);
+			else
+				ipa_err_rl("tx skb alloc failed");
+			ret = WLAN_IPA_FORWARD_PKT_LOCAL_STACK;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * __wlan_ipa_w2i_cb() - WLAN to IPA callback handler
+ * @priv: pointer to private data registered with IPA (we register a
+ *	pointer to the global IPA context)
+ * @evt: the IPA event which triggered the callback
+ * @data: data associated with the event
+ *
+ * Return: None
+ */
+static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
+			      unsigned long data)
+{
+	struct wlan_ipa_priv *ipa_ctx = NULL;
+	qdf_nbuf_t skb;
+	uint8_t iface_id;
+	uint8_t session_id = 0xff;
+	struct wlan_ipa_iface_context *iface_context;
+	uint8_t fw_desc;
+
+	if (qdf_is_module_state_transitioning()) {
+		ipa_err("Module transition in progress");
+		return;
+	}
+
+	ipa_ctx = (struct wlan_ipa_priv *)priv;
+
+	if (!ipa_ctx)
+		return;
+
+	switch (evt) {
+	case IPA_RECEIVE:
+		skb = (qdf_nbuf_t) data;
+		if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
+			session_id = (uint8_t)skb->cb[0];
+			iface_id = ipa_ctx->vdev_to_iface[session_id];
+		} else {
+			iface_id = WLAN_IPA_GET_IFACE_ID(skb->data);
+		}
+		if (iface_id >= WLAN_IPA_MAX_IFACE) {
+			ipa_err_rl("Invalid iface_id: %u,session id: %x %x %x %x. Dropped!",
+				   iface_id, session_id, (uint8_t)skb->cb[1],
+				   (uint8_t)skb->cb[2], (uint8_t)skb->cb[3]);
+			ipa_ctx->ipa_rx_internal_drop_count++;
+			dev_kfree_skb_any(skb);
+			return;
+		}
+
+		iface_context = &ipa_ctx->iface_context[iface_id];
+		if (!iface_context->tl_context) {
+			ipa_err_rl("TL context of iface_id %u is NULL",
+				   iface_id);
+			ipa_ctx->ipa_rx_internal_drop_count++;
+			dev_kfree_skb_any(skb);
+			return;
+		}
+
+		if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
+			ipa_ctx->stats.num_rx_excep++;
+			qdf_nbuf_pull_head(skb, WLAN_IPA_UC_WLAN_CLD_HDR_LEN);
+		} else {
+			qdf_nbuf_pull_head(skb, WLAN_IPA_WLAN_CLD_HDR_LEN);
+		}
+		iface_context->stats.num_rx_ipa_excep++;
+
+		/* Disable to forward Intra-BSS Rx packets when
+		 * ap_isolate=1 in hostapd.conf
+		 */
+		if (!ipa_ctx->ap_intrabss_fwd) {
+			/*
+			 * When INTRA_BSS_FWD_OFFLOAD is enabled, FW will send
+			 * all Rx packets to IPA uC, which need to be forwarded
+			 * to other interface.
+			 * And, IPA driver will send back to WLAN host driver
+			 * through exception pipe with fw_desc field set by FW.
+			 * Here we are checking fw_desc field for FORWARD bit
+			 * set, and forward to Tx. Then copy to kernel stack
+			 * only when DISCARD bit is not set.
+			 */
+			fw_desc = (uint8_t)skb->cb[1];
+			if (WLAN_IPA_FORWARD_PKT_DISCARD ==
+			    wlan_ipa_intrabss_forward(ipa_ctx, iface_context,
+						     fw_desc, skb))
+				break;
+		} else {
+			ipa_debug_rl("Intra-BSS forwarding is disabled");
+		}
+
+		wlan_ipa_send_skb_to_network(skb, iface_context);
+		break;
+
+	default:
+		ipa_err_rl("w2i cb wrong event: 0x%x", evt);
+		return;
+	}
+}
+
+/**
+ * wlan_ipa_w2i_cb() - SSR wrapper for __wlan_ipa_w2i_cb
+ * @priv: pointer to private data registered with IPA (we register a
+ *	pointer to the global IPA context)
+ * @evt: the IPA event which triggered the callback
+ * @data: data associated with the event
+ *
+ * Return: None
+ */
+static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
+			    unsigned long data)
+{
+	qdf_ssr_protect(__func__);
+	__wlan_ipa_w2i_cb(priv, evt, data);
+	qdf_ssr_unprotect(__func__);
+}
+
+/**
+ * __wlan_ipa_i2w_cb() - IPA to WLAN callback
+ * @priv: pointer to private data registered with IPA (we register a
+ *	pointer to the interface-specific IPA context)
+ * @evt: the IPA event which triggered the callback
+ * @data: data associated with the event
+ *
+ * Return: None
+ */
+static void __wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
+			      unsigned long data)
+{
+	struct wlan_ipa_priv *ipa_ctx = NULL;
+	qdf_ipa_rx_data_t *ipa_tx_desc;
+	struct wlan_ipa_iface_context *iface_context;
+	qdf_nbuf_t skb;
+	struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL;
+
+	if (qdf_is_module_state_transitioning()) {
+		ipa_err("Module transition in progress");
+		return;
+	}
+
+	iface_context = (struct wlan_ipa_iface_context *)priv;
+	ipa_tx_desc = (qdf_ipa_rx_data_t *)data;
+	ipa_ctx = iface_context->ipa_ctx;
+
+	if (evt != IPA_RECEIVE) {
+		ipa_err_rl("Event is not IPA_RECEIVE");
+		ipa_free_skb(ipa_tx_desc);
+		iface_context->stats.num_tx_drop++;
+		return;
+	}
+
+	skb = QDF_IPA_RX_DATA_SKB(ipa_tx_desc);
+
+	/*
+	 * If PROD resource is not requested here then there may be cases where
+	 * IPA hardware may be clocked down because of not having proper
+	 * dependency graph between WLAN CONS and modem PROD pipes. Adding the
+	 * workaround to request PROD resource while data is going over CONS
+	 * pipe to prevent the IPA hardware clockdown.
+	 */
+	wlan_ipa_wdi_rm_request(ipa_ctx);
+
+	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+	/*
+	 * If host is still suspended then queue the packets and these will be
+	 * drained later when resume completes. When packet is arrived here and
+	 * host is suspended, this means that there is already resume is in
+	 * progress.
+	 */
+	if (ipa_ctx->suspended) {
+		qdf_mem_set(skb->cb, sizeof(skb->cb), 0);
+		pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
+		pm_tx_cb->iface_context = iface_context;
+		pm_tx_cb->ipa_tx_desc = ipa_tx_desc;
+		qdf_nbuf_queue_add(&ipa_ctx->pm_queue_head, skb);
+		ipa_ctx->stats.num_tx_queued++;
+
+		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+		return;
+	}
+
+	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+
+	/*
+	 * If we are here means, host is not suspended, wait for the work queue
+	 * to finish.
+	 */
+	qdf_flush_work(&ipa_ctx->pm_work);
+
+	return wlan_ipa_send_pkt_to_tl(iface_context, ipa_tx_desc);
+}
+
+/**
+ * wlan_ipa_i2w_cb() - IPA to WLAN callback
+ * @priv: pointer to private data registered with IPA (we register a
+ *	pointer to the interface-specific IPA context)
+ * @evt: the IPA event which triggered the callback
+ * @data: data associated with the event
+ *
+ * Return: None
+ */
+static void wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
+			    unsigned long data)
+{
+	qdf_ssr_protect(__func__);
+	__wlan_ipa_i2w_cb(priv, evt, data);
+	qdf_ssr_unprotect(__func__);
+}
+
+QDF_STATUS wlan_ipa_suspend(struct wlan_ipa_priv *ipa_ctx)
+{
+	/*
+	 * Check if IPA is ready for suspend, If we are here means, there is
+	 * high chance that suspend would go through but just to avoid any race
+	 * condition after suspend started, these checks are conducted before
+	 * allowing to suspend.
+	 */
+	if (atomic_read(&ipa_ctx->tx_ref_cnt))
+		return QDF_STATUS_E_AGAIN;
+
+	if (!wlan_ipa_is_rm_released(ipa_ctx))
+		return QDF_STATUS_E_AGAIN;
+
+	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+	ipa_ctx->suspended = true;
+	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_ipa_resume(struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_sched_work(0, &ipa_ctx->pm_work);
+
+	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+	ipa_ctx->suspended = false;
+	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_ipa_uc_enable_pipes(struct wlan_ipa_priv *ipa_ctx)
+{
+	int result;
+
+	ipa_debug("enter");
+
+	if (!ipa_ctx->ipa_pipes_down) {
+		/*
+		 * IPA WDI Pipes are already activated due to
+		 * rm deferred resources grant
+		 */
+		ipa_warn("IPA WDI Pipes are already activated");
+		goto end;
+	}
+
+	result = cdp_ipa_enable_pipes(ipa_ctx->dp_soc,
+				      ipa_ctx->dp_pdev);
+	if (result) {
+		ipa_err("Enable IPA WDI PIPE failed: ret=%d", result);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_event_reset(&ipa_ctx->ipa_resource_comp);
+	ipa_ctx->ipa_pipes_down = false;
+
+	cdp_ipa_enable_autonomy(ipa_ctx->dp_soc,
+				ipa_ctx->dp_pdev);
+
+end:
+	ipa_debug("exit: ipa_pipes_down=%d", ipa_ctx->ipa_pipes_down);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_ipa_uc_disable_pipes(struct wlan_ipa_priv *ipa_ctx)
+{
+	int result;
+
+	ipa_debug("enter");
+
+	if (ipa_ctx->ipa_pipes_down) {
+		ipa_warn("IPA WDI Pipes are already deactivated");
+		goto end;
+	}
+
+	cdp_ipa_disable_autonomy(ipa_ctx->dp_soc,
+				 ipa_ctx->dp_pdev);
+
+	result = cdp_ipa_disable_pipes(ipa_ctx->dp_soc,
+				       ipa_ctx->dp_pdev);
+	if (result) {
+		ipa_err("Disable IPA WDI PIPE failed: ret=%d", result);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ipa_ctx->ipa_pipes_down = true;
+
+end:
+	ipa_debug("exit: ipa_pipes_down=%d", ipa_ctx->ipa_pipes_down);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_ipa_uc_find_add_assoc_sta() - Find associated station
+ * @ipa_ctx: Global IPA IPA context
+ * @sta_add: Should station be added
+ * @sta_id: ID of the station being queried
+ *
+ * Return: true if the station was found
+ */
+static bool wlan_ipa_uc_find_add_assoc_sta(struct wlan_ipa_priv *ipa_ctx,
+					   bool sta_add, uint8_t sta_id,
+					   uint8_t *mac_addr)
+{
+	bool sta_found = false;
+	uint8_t idx;
+
+	for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) {
+		if ((ipa_ctx->assoc_stas_map[idx].is_reserved) &&
+		    (ipa_ctx->assoc_stas_map[idx].sta_id == sta_id)) {
+			sta_found = true;
+			break;
+		}
+	}
+	if (sta_add && sta_found) {
+		ipa_err("STA ID %d already exist, cannot add", sta_id);
+		return sta_found;
+	}
+	if (sta_add) {
+		for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) {
+			if (!ipa_ctx->assoc_stas_map[idx].is_reserved) {
+				ipa_ctx->assoc_stas_map[idx].is_reserved = true;
+				ipa_ctx->assoc_stas_map[idx].sta_id = sta_id;
+				qdf_mem_copy(&ipa_ctx->assoc_stas_map[idx].
+					     mac_addr, mac_addr,
+					     QDF_NET_ETH_LEN);
+				return sta_found;
+			}
+		}
+	}
+	if (!sta_add && !sta_found) {
+		ipa_err("STA ID %d does not exist, cannot delete", sta_id);
+		return sta_found;
+	}
+	if (!sta_add) {
+		for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) {
+			if ((ipa_ctx->assoc_stas_map[idx].is_reserved) &&
+			    (ipa_ctx->assoc_stas_map[idx].sta_id == sta_id)) {
+				ipa_ctx->assoc_stas_map[idx].is_reserved =
+					false;
+				ipa_ctx->assoc_stas_map[idx].sta_id = 0xFF;
+				qdf_mem_set(&ipa_ctx->assoc_stas_map[idx].
+					    mac_addr, 0, QDF_NET_ETH_LEN);
+				return sta_found;
+			}
+		}
+	}
+
+	return sta_found;
+}
+
+/**
+ * wlan_ipa_get_ifaceid() - Get IPA context interface ID
+ * @ipa_ctx: IPA context
+ * @session_id: Session ID
+ *
+ * Return: None
+ */
+static int wlan_ipa_get_ifaceid(struct wlan_ipa_priv *ipa_ctx,
+				uint8_t session_id)
+{
+	struct wlan_ipa_iface_context *iface_ctx;
+	int i;
+
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+		iface_ctx = &ipa_ctx->iface_context[i];
+		if (iface_ctx->session_id == session_id)
+			break;
+	}
+
+	return i;
+}
+
+/**
+ * wlan_ipa_cleanup_iface() - Cleanup IPA on a given interface
+ * @iface_context: interface-specific IPA context
+ *
+ * Return: None
+ */
+static void wlan_ipa_cleanup_iface(struct wlan_ipa_iface_context *iface_context)
+{
+	struct wlan_ipa_priv *ipa_ctx = iface_context->ipa_ctx;
+
+	ipa_debug("enter");
+
+	if (!iface_context->tl_context)
+		return;
+
+	cdp_ipa_cleanup_iface(ipa_ctx->dp_soc,
+			      iface_context->dev->name,
+			      wlan_ipa_is_ipv6_enabled(ipa_ctx->config));
+
+	qdf_spin_lock_bh(&iface_context->interface_lock);
+	iface_context->tl_context = NULL;
+	iface_context->dev = NULL;
+	iface_context->device_mode = QDF_MAX_NO_OF_MODE;
+	iface_context->session_id = WLAN_IPA_MAX_SESSION;
+	iface_context->sta_id = WLAN_IPA_MAX_STA_COUNT;
+	qdf_spin_unlock_bh(&iface_context->interface_lock);
+	iface_context->ifa_address = 0;
+	if (!iface_context->ipa_ctx->num_iface) {
+		ipa_err("NUM INTF 0, Invalid");
+		QDF_ASSERT(0);
+	}
+	iface_context->ipa_ctx->num_iface--;
+	ipa_debug("exit: num_iface=%d", iface_context->ipa_ctx->num_iface);
+}
+
+/**
+ * wlan_ipa_nbuf_cb() - IPA TX complete callback
+ * @skb: packet buffer which was transmitted
+ *
+ * Return: None
+ */
+static void wlan_ipa_nbuf_cb(qdf_nbuf_t skb)
+{
+	struct wlan_ipa_priv *ipa_ctx = gp_ipa;
+	qdf_ipa_rx_data_t *ipa_tx_desc;
+	struct wlan_ipa_tx_desc *tx_desc;
+	uint16_t id;
+
+	if (!qdf_nbuf_ipa_owned_get(skb)) {
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
+	/* Get Tx desc pointer from SKB CB */
+	id = QDF_NBUF_CB_TX_IPA_PRIV(skb);
+	tx_desc = &ipa_ctx->tx_desc_pool[id];
+	ipa_tx_desc = tx_desc->ipa_tx_desc_ptr;
+
+	/* Return Tx Desc to IPA */
+	qdf_ipa_free_skb(ipa_tx_desc);
+
+	/* Return to free tx desc list */
+	qdf_spin_lock_bh(&ipa_ctx->q_lock);
+	tx_desc->ipa_tx_desc_ptr = NULL;
+	qdf_list_insert_back(&ipa_ctx->tx_desc_free_list, &tx_desc->node);
+	ipa_ctx->stats.num_tx_desc_q_cnt--;
+	qdf_spin_unlock_bh(&ipa_ctx->q_lock);
+
+	ipa_ctx->stats.num_tx_comp_cnt++;
+
+	qdf_atomic_dec(&ipa_ctx->tx_ref_cnt);
+
+	wlan_ipa_wdi_rm_try_release(ipa_ctx);
+}
+
+/**
+ * wlan_ipa_setup_iface() - Setup IPA on a given interface
+ * @ipa_ctx: IPA IPA global context
+ * @net_dev: Interface net device
+ * @device_mode: Net interface device mode
+ * @adapter: Interface upon which IPA is being setup
+ * @sta_id: Station ID of the API instance
+ * @session_id: Station ID of the API instance
+ *
+ * Return: QDF STATUS
+ */
+static QDF_STATUS wlan_ipa_setup_iface(struct wlan_ipa_priv *ipa_ctx,
+				       qdf_netdev_t net_dev,
+				       uint8_t device_mode, uint8_t sta_id,
+				       uint8_t session_id)
+{
+	struct wlan_ipa_iface_context *iface_context = NULL;
+	void *tl_context = NULL;
+	int i;
+	QDF_STATUS status;
+
+	/* Lower layer may send multiple START_BSS_EVENT in DFS mode or during
+	 * channel change indication. Since these indications are sent by lower
+	 * layer as SAP updates and IPA doesn't have to do anything for these
+	 * updates so ignoring!
+	 */
+	if (device_mode == QDF_SAP_MODE) {
+		for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+			iface_context = &(ipa_ctx->iface_context[i]);
+			if (iface_context->dev == net_dev) {
+				ipa_debug("found iface %u device_mode %u",
+					 i, device_mode);
+				return QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+
+	if (WLAN_IPA_MAX_IFACE == ipa_ctx->num_iface) {
+		ipa_err("Max interface reached %d", WLAN_IPA_MAX_IFACE);
+		status = QDF_STATUS_E_NOMEM;
+		QDF_ASSERT(0);
+		goto end;
+	}
+
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+		if (ipa_ctx->iface_context[i].tl_context == NULL) {
+			iface_context = &(ipa_ctx->iface_context[i]);
+			break;
+		}
+	}
+
+	if (iface_context == NULL) {
+		ipa_err("All the IPA interfaces are in use");
+		status = QDF_STATUS_E_NOMEM;
+		QDF_ASSERT(0);
+		goto end;
+	}
+
+	iface_context->sta_id = sta_id;
+	tl_context = (void *)cdp_peer_get_vdev_by_sta_id(ipa_ctx->dp_soc,
+							 ipa_ctx->dp_pdev,
+							 sta_id);
+	if (tl_context == NULL) {
+		ipa_err("Not able to get TL context sta_id: %d", sta_id);
+		status = QDF_STATUS_E_INVAL;
+		goto end;
+	}
+
+	iface_context->tl_context = tl_context;
+	iface_context->dev = net_dev;
+	iface_context->device_mode = device_mode;
+	iface_context->session_id = session_id;
+
+	status = cdp_ipa_setup_iface(ipa_ctx->dp_soc, net_dev->name,
+				     net_dev->dev_addr,
+				     iface_context->prod_client,
+				     iface_context->cons_client,
+				     session_id,
+				     wlan_ipa_is_ipv6_enabled(ipa_ctx->config));
+	if (status != QDF_STATUS_SUCCESS)
+		goto end;
+
+	/* Register IPA Tx desc free callback */
+	qdf_nbuf_reg_free_cb(wlan_ipa_nbuf_cb);
+
+	ipa_ctx->num_iface++;
+
+	ipa_debug("exit: num_iface=%d", ipa_ctx->num_iface);
+
+	return status;
+
+end:
+	if (iface_context)
+		wlan_ipa_cleanup_iface(iface_context);
+
+	return status;
+}
+
+/**
+ * wlan_ipa_uc_handle_first_con() - Handle first uC IPA connection
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF STATUS
+ */
+static QDF_STATUS wlan_ipa_uc_handle_first_con(struct wlan_ipa_priv *ipa_ctx)
+{
+	ipa_debug("enter");
+
+	ipa_ctx->activated_fw_pipe = 0;
+	ipa_ctx->resource_loading = true;
+
+	/* If RM feature enabled
+	 * Request PROD Resource first
+	 * PROD resource may return sync or async manners
+	 */
+	if (wlan_ipa_is_rm_enabled(ipa_ctx->config)) {
+		if (!wlan_ipa_wdi_rm_request_resource(ipa_ctx,
+						IPA_RM_RESOURCE_WLAN_PROD)) {
+			/* RM PROD request sync return
+			 * enable pipe immediately
+			 */
+			if (wlan_ipa_uc_enable_pipes(ipa_ctx)) {
+				ipa_err("IPA WDI Pipe activation failed");
+				ipa_ctx->resource_loading = false;
+				return QDF_STATUS_E_BUSY;
+			}
+		} else {
+			ipa_err("IPA WDI Pipe activation deferred");
+		}
+	} else {
+		/* RM Disabled
+		 * Just enabled all the PIPEs
+		 */
+		if (wlan_ipa_uc_enable_pipes(ipa_ctx)) {
+			ipa_err("IPA WDI Pipe activation failed");
+			ipa_ctx->resource_loading = false;
+			return QDF_STATUS_E_BUSY;
+		}
+		ipa_ctx->resource_loading = false;
+	}
+
+	ipa_debug("exit");
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_ipa_uc_handle_last_discon() - Handle last uC IPA disconnection
+ * @ipa_ctx: IPA context
+ *
+ * Return: None
+ */
+static void wlan_ipa_uc_handle_last_discon(struct wlan_ipa_priv *ipa_ctx)
+{
+	ipa_debug("enter");
+
+	ipa_ctx->resource_unloading = true;
+	qdf_event_reset(&ipa_ctx->ipa_resource_comp);
+	ipa_info("Disable FW RX PIPE");
+	cdp_ipa_set_active(ipa_ctx->dp_soc, ipa_ctx->dp_pdev, false, false);
+
+	ipa_debug("exit: IPA WDI Pipes deactivated");
+}
+
+/**
+ * wlan_ipa_uc_offload_enable_disable() - wdi enable/disable notify to fw
+ * @ipa_ctx: global IPA context
+ * @offload_type: MCC or SCC
+ * @session_id: Session Id
+ * @enable: TX offload enable or disable
+ *
+ * Return: none
+ */
+static void wlan_ipa_uc_offload_enable_disable(struct wlan_ipa_priv *ipa_ctx,
+					       uint32_t offload_type,
+					       uint8_t session_id,
+					       bool enable)
+{
+
+	struct ipa_uc_offload_control_params req = {0};
+
+	if (session_id >= WLAN_IPA_MAX_SESSION) {
+		ipa_err("invalid session id: %d", session_id);
+		return;
+	}
+
+	if (enable == ipa_ctx->vdev_offload_enabled[session_id]) {
+		ipa_info("IPA offload status is already set");
+		ipa_info("offload_type=%d, vdev_id=%d, enable=%d",
+			 offload_type, session_id, enable);
+		return;
+	}
+
+	ipa_info("offload_type=%d, session_id=%d, enable=%d",
+		 offload_type, session_id, enable);
+
+	req.offload_type = offload_type;
+	req.vdev_id = session_id;
+	req.enable = enable;
+
+	if (QDF_STATUS_SUCCESS !=
+	    ipa_send_uc_offload_enable_disable(ipa_ctx->pdev, &req)) {
+		ipa_err("Fail to enable IPA offload");
+		ipa_err("offload type=%d, vdev_id=%d, enable=%d",
+			offload_type, session_id, enable);
+	} else {
+		ipa_ctx->vdev_offload_enabled[session_id] = enable;
+	}
+}
+
+/**
+ * __wlan_ipa_wlan_evt() - IPA event handler
+ * @net_dev: Interface net device
+ * @device_mode: Net interface device mode
+ * @sta_id: station id for the event
+ * @session_id: session id for the event
+ * @type: event enum of type ipa_wlan_event
+ * @mac_address: MAC address associated with the event
+ *
+ * This function is meant to be called from within wlan_ipa_ctx.c
+ *
+ * Return: QDF STATUS
+ */
+static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
+				      uint8_t sta_id, uint8_t session_id,
+				      qdf_ipa_wlan_event type,
+				      uint8_t *mac_addr)
+{
+	struct wlan_ipa_priv *ipa_ctx = gp_ipa;
+	struct wlan_ipa_iface_context *iface_ctx = NULL;
+	qdf_ipa_msg_meta_t meta;
+	qdf_ipa_wlan_msg_t *msg;
+	qdf_ipa_wlan_msg_ex_t *msg_ex = NULL;
+	int i;
+	QDF_STATUS status;
+	uint8_t sta_session_id = WLAN_IPA_MAX_SESSION;
+
+	ipa_debug("%s: EVT: %d, MAC: %pM, sta_id: %d session_id: %u",
+		 net_dev->name, type, mac_addr, sta_id, session_id);
+
+	if (type >= QDF_IPA_WLAN_EVENT_MAX)
+		return QDF_STATUS_E_INVAL;
+
+	if (wlan_ipa_uc_is_enabled(ipa_ctx->config) &&
+	    !wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
+	    (device_mode != QDF_SAP_MODE)) {
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (ipa_ctx->sta_connected) {
+		iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_STA_MODE);
+		if (iface_ctx)
+			sta_session_id = iface_ctx->session_id;
+		else
+			ipa_err("sta iface_ctx is NULL");
+	}
+
+	/*
+	 * During IPA UC resource loading/unloading new events can be issued.
+	 */
+	if (wlan_ipa_uc_is_enabled(ipa_ctx->config) &&
+	    (ipa_ctx->resource_loading || ipa_ctx->resource_unloading)) {
+		unsigned int pending_event_count;
+		struct wlan_ipa_uc_pending_event *pending_event = NULL;
+
+		ipa_info("Event:%d IPA resource %s inprogress", type,
+			 ipa_ctx->resource_loading ?
+			 "load" : "unload");
+
+		/* Wait until completion of the long/unloading */
+		status = qdf_wait_for_event_completion(
+				&ipa_ctx->ipa_resource_comp,
+				IPA_RESOURCE_COMP_WAIT_TIME);
+		if (status != QDF_STATUS_SUCCESS) {
+			/*
+			 * If timed out, store the events separately and
+			 * handle them later.
+			 */
+			ipa_info("IPA resource %s timed out",
+				  ipa_ctx->resource_loading ?
+				  "load" : "unload");
+
+			if (type == QDF_IPA_AP_DISCONNECT)
+				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
+						SIR_AP_RX_DATA_OFFLOAD,
+						session_id, false);
+
+			qdf_mutex_acquire(&ipa_ctx->ipa_lock);
+
+			pending_event_count =
+				qdf_list_size(&ipa_ctx->pending_event);
+			if (pending_event_count >=
+			    WLAN_IPA_MAX_PENDING_EVENT_COUNT) {
+				ipa_info("Reached max pending evt count");
+				qdf_list_remove_front(
+					&ipa_ctx->pending_event,
+					(qdf_list_node_t **)&pending_event);
+			} else {
+				pending_event =
+					(struct wlan_ipa_uc_pending_event *)
+					qdf_mem_malloc(sizeof(
+					struct wlan_ipa_uc_pending_event));
+			}
+
+			if (!pending_event) {
+				ipa_err("Pending event memory alloc fail");
+				qdf_mutex_release(&ipa_ctx->ipa_lock);
+				return QDF_STATUS_E_NOMEM;
+			}
+
+			pending_event->net_dev = net_dev;
+			pending_event->device_mode = device_mode;
+			pending_event->sta_id = sta_id;
+			pending_event->session_id = session_id;
+			pending_event->type = type;
+			pending_event->is_loading = ipa_ctx->resource_loading;
+			qdf_mem_copy(pending_event->mac_addr,
+				     mac_addr, QDF_MAC_ADDR_SIZE);
+			qdf_list_insert_back(&ipa_ctx->pending_event,
+					     &pending_event->node);
+
+			qdf_mutex_release(&ipa_ctx->ipa_lock);
+
+			/* Cleanup interface */
+			if (type == QDF_IPA_STA_DISCONNECT ||
+			    type == QDF_IPA_AP_DISCONNECT) {
+				for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+					iface_ctx = &ipa_ctx->iface_context[i];
+
+					if (iface_ctx->dev == net_dev)
+						break;
+				}
+				if (iface_ctx)
+					wlan_ipa_cleanup_iface(iface_ctx);
+			}
+
+			return QDF_STATUS_SUCCESS;
+		}
+		ipa_info("IPA resource %s completed",
+			 ipa_ctx->resource_loading ?
+			 "load" : "unload");
+	}
+
+	ipa_ctx->stats.event[type]++;
+
+	QDF_IPA_SET_META_MSG_TYPE(&meta, type);
+	switch (type) {
+	case QDF_IPA_STA_CONNECT:
+		qdf_mutex_acquire(&ipa_ctx->event_lock);
+
+		/* STA already connected and without disconnect, connect again
+		 * This is Roaming scenario
+		 */
+		if (ipa_ctx->sta_connected) {
+			iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_STA_MODE);
+			if (iface_ctx)
+				wlan_ipa_cleanup_iface(iface_ctx);
+		}
+
+		status = wlan_ipa_setup_iface(ipa_ctx, net_dev, device_mode,
+					   sta_id, session_id);
+		if (status != QDF_STATUS_SUCCESS) {
+			ipa_err("wlan_ipa_setup_iface failed %u", status);
+			qdf_mutex_release(&ipa_ctx->event_lock);
+			goto end;
+		}
+
+		if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
+		    (ipa_ctx->sap_num_connected_sta > 0) &&
+		    !ipa_ctx->sta_connected) {
+			qdf_mutex_release(&ipa_ctx->event_lock);
+			wlan_ipa_uc_offload_enable_disable(ipa_ctx,
+				SIR_STA_RX_DATA_OFFLOAD, session_id,
+				true);
+			qdf_mutex_acquire(&ipa_ctx->event_lock);
+		}
+
+		ipa_ctx->vdev_to_iface[session_id] =
+				wlan_ipa_get_ifaceid(ipa_ctx, session_id);
+
+		ipa_ctx->sta_connected = 1;
+
+		qdf_mutex_release(&ipa_ctx->event_lock);
+
+		ipa_debug("sta_connected=%d vdev_to_iface[%u] %u",
+			 ipa_ctx->sta_connected,
+			 session_id,
+			 ipa_ctx->vdev_to_iface[session_id]);
+		break;
+
+	case QDF_IPA_AP_CONNECT:
+		qdf_mutex_acquire(&ipa_ctx->event_lock);
+
+		/* For DFS channel we get two start_bss event (before and after
+		 * CAC). Also when ACS range includes both DFS and non DFS
+		 * channels, we could possibly change channel many times due to
+		 * RADAR detection and chosen channel may not be a DFS channels.
+		 * So dont return error here. Just discard the event.
+		 */
+		if (ipa_ctx->vdev_to_iface[session_id] !=
+				WLAN_IPA_MAX_SESSION) {
+			qdf_mutex_release(&ipa_ctx->event_lock);
+			return 0;
+		}
+
+		status = wlan_ipa_setup_iface(ipa_ctx, net_dev, device_mode,
+					   sta_id, session_id);
+		if (status != QDF_STATUS_SUCCESS) {
+			qdf_mutex_release(&ipa_ctx->event_lock);
+			ipa_err("%s: Evt: %d, Interface setup failed",
+				msg_ex->name, QDF_IPA_MSG_META_MSG_TYPE(&meta));
+			goto end;
+		}
+
+		if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
+			qdf_mutex_release(&ipa_ctx->event_lock);
+			wlan_ipa_uc_offload_enable_disable(ipa_ctx,
+				SIR_AP_RX_DATA_OFFLOAD, session_id, true);
+			qdf_mutex_acquire(&ipa_ctx->event_lock);
+		}
+
+		ipa_ctx->vdev_to_iface[session_id] =
+				wlan_ipa_get_ifaceid(ipa_ctx, session_id);
+		ipa_debug("vdev_to_iface[%u]=%u",
+			 session_id,
+			 ipa_ctx->vdev_to_iface[session_id]);
+		qdf_mutex_release(&ipa_ctx->event_lock);
+		break;
+
+	case QDF_IPA_STA_DISCONNECT:
+		qdf_mutex_acquire(&ipa_ctx->event_lock);
+
+		if (!ipa_ctx->sta_connected) {
+			qdf_mutex_release(&ipa_ctx->event_lock);
+			ipa_err("%s: Evt: %d, STA already disconnected",
+				msg_ex->name, QDF_IPA_MSG_META_MSG_TYPE(&meta));
+			return QDF_STATUS_E_INVAL;
+		}
+
+		ipa_ctx->sta_connected = 0;
+
+		if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
+			ipa_debug("%s: IPA UC OFFLOAD NOT ENABLED",
+				  msg_ex->name);
+		} else {
+			/* Disable IPA UC TX PIPE when STA disconnected */
+			if ((ipa_ctx->num_iface == 1) &&
+			    wlan_ipa_is_fw_wdi_activated(ipa_ctx) &&
+			    !ipa_ctx->ipa_pipes_down &&
+			    (ipa_ctx->resource_unloading == false)) {
+				if (cds_is_driver_unloading()) {
+					/*
+					 * We disable WDI pipes directly here
+					 * since IPA_OPCODE_TX/RX_SUSPEND
+					 * message will not be processed when
+					 * unloading WLAN driver is in progress
+					 */
+					wlan_ipa_uc_disable_pipes(ipa_ctx);
+				} else {
+					wlan_ipa_uc_handle_last_discon(ipa_ctx);
+				}
+			}
+		}
+
+		if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
+		    (ipa_ctx->sap_num_connected_sta > 0)) {
+			qdf_mutex_release(&ipa_ctx->event_lock);
+			wlan_ipa_uc_offload_enable_disable(ipa_ctx,
+				SIR_STA_RX_DATA_OFFLOAD, session_id, false);
+			qdf_mutex_acquire(&ipa_ctx->event_lock);
+			ipa_ctx->vdev_to_iface[session_id] =
+				WLAN_IPA_MAX_SESSION;
+			ipa_debug("vdev_to_iface[%u]=%u",
+				 session_id,
+				 ipa_ctx->vdev_to_iface[session_id]);
+		}
+
+		for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+			iface_ctx = &ipa_ctx->iface_context[i];
+
+			if (iface_ctx->dev == net_dev)
+				break;
+		}
+		if (i < WLAN_IPA_MAX_IFACE)
+			wlan_ipa_cleanup_iface(iface_ctx);
+
+		qdf_mutex_release(&ipa_ctx->event_lock);
+
+		ipa_debug("sta_connected=%d", ipa_ctx->sta_connected);
+		break;
+
+	case QDF_IPA_AP_DISCONNECT:
+		qdf_mutex_acquire(&ipa_ctx->event_lock);
+
+		if ((ipa_ctx->num_iface == 1) &&
+		    wlan_ipa_is_fw_wdi_activated(ipa_ctx) &&
+		    !ipa_ctx->ipa_pipes_down &&
+		    (ipa_ctx->resource_unloading == false)) {
+			if (cds_is_driver_unloading()) {
+				/*
+				 * We disable WDI pipes directly here since
+				 * IPA_OPCODE_TX/RX_SUSPEND message will not be
+				 * processed when unloading WLAN driver is in
+				 * progress
+				 */
+				wlan_ipa_uc_disable_pipes(ipa_ctx);
+			} else {
+				/*
+				 * This shouldn't happen :
+				 * No interface left but WDI pipes are still
+				 * active - force close WDI pipes
+				 */
+				ipa_err("No interface left but WDI pipes are still active");
+				wlan_ipa_uc_handle_last_discon(ipa_ctx);
+			}
+		}
+
+		if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
+			qdf_mutex_release(&ipa_ctx->event_lock);
+			wlan_ipa_uc_offload_enable_disable(ipa_ctx,
+				SIR_AP_RX_DATA_OFFLOAD, session_id, false);
+			qdf_mutex_acquire(&ipa_ctx->event_lock);
+			ipa_ctx->vdev_to_iface[session_id] =
+				WLAN_IPA_MAX_SESSION;
+			ipa_debug("vdev_to_iface[%u]=%u",
+				 session_id,
+				 ipa_ctx->vdev_to_iface[session_id]);
+		}
+
+		for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+			iface_ctx = &ipa_ctx->iface_context[i];
+
+			if (iface_ctx->dev == net_dev)
+				break;
+		}
+		if (i < WLAN_IPA_MAX_IFACE)
+			wlan_ipa_cleanup_iface(iface_ctx);
+
+		qdf_mutex_release(&ipa_ctx->event_lock);
+		break;
+
+	case QDF_IPA_CLIENT_CONNECT_EX:
+		if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
+			ipa_debug("%s: Evt: %d, IPA UC OFFLOAD NOT ENABLED",
+				  net_dev->name, type);
+			return QDF_STATUS_SUCCESS;
+		}
+
+		qdf_mutex_acquire(&ipa_ctx->event_lock);
+		if (wlan_ipa_uc_find_add_assoc_sta(ipa_ctx, true, sta_id,
+						   mac_addr)) {
+			qdf_mutex_release(&ipa_ctx->event_lock);
+			ipa_err("%s: STA ID %d found", net_dev->name, sta_id);
+			return QDF_STATUS_SUCCESS;
+		}
+
+		/* Enable IPA UC Data PIPEs when first STA connected */
+		if (ipa_ctx->sap_num_connected_sta == 0 &&
+				ipa_ctx->uc_loaded == true) {
+
+			if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
+			    ipa_ctx->sta_connected) {
+				qdf_mutex_release(&ipa_ctx->event_lock);
+				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
+							SIR_STA_RX_DATA_OFFLOAD,
+							sta_session_id, true);
+				qdf_mutex_acquire(&ipa_ctx->event_lock);
+			}
+
+			status = wlan_ipa_uc_handle_first_con(ipa_ctx);
+			if (status != QDF_STATUS_SUCCESS) {
+				ipa_info("%s: handle 1st con fail",
+					 net_dev->name);
+
+				if (wlan_ipa_uc_sta_is_enabled(
+					ipa_ctx->config) &&
+				    ipa_ctx->sta_connected) {
+					qdf_mutex_release(&ipa_ctx->event_lock);
+					wlan_ipa_uc_offload_enable_disable(
+							ipa_ctx,
+							SIR_STA_RX_DATA_OFFLOAD,
+							sta_session_id, false);
+				} else {
+					qdf_mutex_release(&ipa_ctx->event_lock);
+				}
+
+				return status;
+			} else
+				ipa_debug("%s: handle 1st con success",
+					  net_dev->name);
+		}
+
+		ipa_ctx->sap_num_connected_sta++;
+
+		qdf_mutex_release(&ipa_ctx->event_lock);
+
+		QDF_IPA_SET_META_MSG_TYPE(&meta, type);
+		QDF_IPA_MSG_META_MSG_LEN(&meta) =
+			(sizeof(qdf_ipa_wlan_msg_ex_t) +
+				sizeof(qdf_ipa_wlan_hdr_attrib_val_t));
+		msg_ex = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
+
+		if (msg_ex == NULL) {
+			ipa_err("msg_ex allocation failed");
+			return QDF_STATUS_E_NOMEM;
+		}
+		strlcpy(msg_ex->name, net_dev->name,
+			IPA_RESOURCE_NAME_MAX);
+		msg_ex->num_of_attribs = 1;
+		msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
+		if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
+			msg_ex->attribs[0].offset =
+				WLAN_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
+		} else {
+			msg_ex->attribs[0].offset =
+				WLAN_IPA_WLAN_HDR_DES_MAC_OFFSET;
+		}
+		memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr,
+		       IPA_MAC_ADDR_SIZE);
+
+		if (qdf_ipa_send_msg(&meta, msg_ex, wlan_ipa_msg_free_fn)) {
+			ipa_info("%s: Evt: %d send ipa msg fail",
+				 net_dev->name, type);
+			qdf_mem_free(msg_ex);
+			return QDF_STATUS_E_FAILURE;
+		}
+		ipa_ctx->stats.num_send_msg++;
+
+		ipa_info("sap_num_connected_sta=%d",
+			  ipa_ctx->sap_num_connected_sta);
+
+		return QDF_STATUS_SUCCESS;
+
+	case WLAN_CLIENT_DISCONNECT:
+		if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
+			ipa_debug("%s: IPA UC OFFLOAD NOT ENABLED",
+				  msg_ex->name);
+			return QDF_STATUS_SUCCESS;
+		}
+
+		qdf_mutex_acquire(&ipa_ctx->event_lock);
+		if (!ipa_ctx->sap_num_connected_sta) {
+			qdf_mutex_release(&ipa_ctx->event_lock);
+			ipa_err("%s: Evt: %d, Client already disconnected",
+				 msg_ex->name,
+				 QDF_IPA_MSG_META_MSG_TYPE(&meta));
+
+			return QDF_STATUS_SUCCESS;
+		}
+		if (!wlan_ipa_uc_find_add_assoc_sta(ipa_ctx, false,
+						    sta_id, mac_addr)) {
+			qdf_mutex_release(&ipa_ctx->event_lock);
+			ipa_err("%s: STA ID %d NOT found, not valid",
+				 msg_ex->name, sta_id);
+
+			return QDF_STATUS_SUCCESS;
+		}
+		ipa_ctx->sap_num_connected_sta--;
+
+		/* Disable IPA UC TX PIPE when last STA disconnected */
+		if (!ipa_ctx->sap_num_connected_sta &&
+				ipa_ctx->uc_loaded == true) {
+			if ((false == ipa_ctx->resource_unloading) &&
+			    wlan_ipa_is_fw_wdi_activated(ipa_ctx) &&
+			    !ipa_ctx->ipa_pipes_down) {
+				if (cds_is_driver_unloading()) {
+					/*
+					 * We disable WDI pipes directly here
+					 * since IPA_OPCODE_TX/RX_SUSPEND
+					 * message will not be processed when
+					 * unloading WLAN driver is in progress
+					 */
+					wlan_ipa_uc_disable_pipes(ipa_ctx);
+				} else {
+					wlan_ipa_uc_handle_last_discon(ipa_ctx);
+				}
+			}
+
+			if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
+			    ipa_ctx->sta_connected) {
+				qdf_mutex_release(&ipa_ctx->event_lock);
+				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
+							SIR_STA_RX_DATA_OFFLOAD,
+							sta_session_id, false);
+			} else {
+				qdf_mutex_release(&ipa_ctx->event_lock);
+			}
+		} else {
+			qdf_mutex_release(&ipa_ctx->event_lock);
+		}
+
+		ipa_info("sap_num_connected_sta=%d",
+			 ipa_ctx->sap_num_connected_sta);
+		break;
+
+	default:
+		return QDF_STATUS_SUCCESS;
+	}
+
+	QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t);
+	msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
+	if (!msg) {
+		ipa_err("msg allocation failed");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	QDF_IPA_SET_META_MSG_TYPE(&meta, type);
+	strlcpy(QDF_IPA_WLAN_MSG_NAME(msg), net_dev->name,
+		IPA_RESOURCE_NAME_MAX);
+	qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN);
+
+	ipa_debug("%s: Evt: %d", QDF_IPA_WLAN_MSG_NAME(msg),
+		  QDF_IPA_MSG_META_MSG_TYPE(&meta));
+
+	if (qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn)) {
+
+		ipa_err("%s: Evt: %d fail",
+			QDF_IPA_WLAN_MSG_NAME(msg),
+			QDF_IPA_MSG_META_MSG_TYPE(&meta));
+		qdf_mem_free(msg);
+
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ipa_ctx->stats.num_send_msg++;
+
+end:
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_host_to_ipa_wlan_event() - convert wlan_ipa_wlan_event to ipa_wlan_event
+ * @wlan_ipa_event_type: event to be converted to an ipa_wlan_event
+ *
+ * Return: qdf_ipa_wlan_event representing the wlan_ipa_wlan_event
+ */
+static qdf_ipa_wlan_event
+wlan_host_to_ipa_wlan_event(enum wlan_ipa_wlan_event wlan_ipa_event_type)
+{
+	qdf_ipa_wlan_event ipa_event;
+
+	switch (wlan_ipa_event_type) {
+	case WLAN_IPA_CLIENT_CONNECT:
+		ipa_event = QDF_IPA_CLIENT_CONNECT;
+		break;
+	case WLAN_IPA_CLIENT_DISCONNECT:
+		ipa_event = QDF_IPA_CLIENT_DISCONNECT;
+		break;
+	case WLAN_IPA_AP_CONNECT:
+		ipa_event = QDF_IPA_AP_CONNECT;
+		break;
+	case WLAN_IPA_AP_DISCONNECT:
+		ipa_event = QDF_IPA_AP_DISCONNECT;
+		break;
+	case WLAN_IPA_STA_CONNECT:
+		ipa_event = QDF_IPA_STA_CONNECT;
+		break;
+	case WLAN_IPA_STA_DISCONNECT:
+		ipa_event = QDF_IPA_STA_DISCONNECT;
+		break;
+	case WLAN_IPA_CLIENT_CONNECT_EX:
+		ipa_event = QDF_IPA_CLIENT_CONNECT_EX;
+		break;
+	case WLAN_IPA_WLAN_EVENT_MAX:
+	default:
+		ipa_event =  QDF_IPA_WLAN_EVENT_MAX;
+		break;
+	}
+
+	return ipa_event;
+}
+
+/**
+ * wlan_ipa_wlan_evt() - SSR wrapper for __wlan_ipa_wlan_evt
+ * @net_dev: Interface net device
+ * @device_mode: Net interface device mode
+ * @sta_id: station id for the event
+ * @session_id: session id for the event
+ * @ipa_event_type: event enum of type wlan_ipa_wlan_event
+ * @mac_address: MAC address associated with the event
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
+		      uint8_t sta_id, uint8_t session_id,
+		      enum wlan_ipa_wlan_event ipa_event_type,
+		      uint8_t *mac_addr)
+{
+	qdf_ipa_wlan_event type = wlan_host_to_ipa_wlan_event(ipa_event_type);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	/* Data path offload only support for STA and SAP mode */
+	if ((device_mode == QDF_STA_MODE) ||
+	    (device_mode == QDF_SAP_MODE))
+		status  = __wlan_ipa_wlan_evt(net_dev, device_mode, sta_id,
+					      session_id, type, mac_addr);
+
+	return status;
+}
+
+/**
+ * wlan_ipa_uc_proc_pending_event() - Process IPA uC pending events
+ * @ipa_ctx: Global IPA IPA context
+ * @is_loading: Indicate if invoked during loading
+ *
+ * Return: None
+ */
+static void
+wlan_ipa_uc_proc_pending_event(struct wlan_ipa_priv *ipa_ctx, bool is_loading)
+{
+	unsigned int pending_event_count;
+	struct wlan_ipa_uc_pending_event *pending_event = NULL;
+
+	pending_event_count = qdf_list_size(&ipa_ctx->pending_event);
+	ipa_debug("Pending Event Count %d",  pending_event_count);
+	if (!pending_event_count) {
+		ipa_debug("No Pending Event");
+		return;
+	}
+
+	qdf_list_remove_front(&ipa_ctx->pending_event,
+			(qdf_list_node_t **)&pending_event);
+	while (pending_event != NULL) {
+		struct wlan_objmgr_pdev *pdev = ipa_ctx->pdev;
+		struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+		struct wlan_objmgr_vdev *vdev =
+				wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+					pending_event->session_id,
+					WLAN_IPA_ID);
+		if (pending_event->is_loading == is_loading && vdev) {
+			__wlan_ipa_wlan_evt(pending_event->net_dev,
+					   pending_event->device_mode,
+					   pending_event->sta_id,
+					   pending_event->session_id,
+					   pending_event->type,
+					   pending_event->mac_addr);
+		}
+
+		if (vdev)
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_IPA_ID);
+		qdf_mem_free(pending_event);
+		pending_event = NULL;
+		qdf_list_remove_front(&ipa_ctx->pending_event,
+				      (qdf_list_node_t **)&pending_event);
+	}
+}
+
+/**
+ * wlan_ipa_free_tx_desc_list() - Free IPA Tx desc list
+ * @ipa_ctx: IPA context
+ *
+ * Return: None
+ */
+static inline void wlan_ipa_free_tx_desc_list(struct wlan_ipa_priv *ipa_ctx)
+{
+	int i;
+	qdf_ipa_rx_data_t *ipa_tx_desc;
+	uint32_t pool_size;
+
+	if (!ipa_ctx->tx_desc_pool)
+		return;
+
+	qdf_spin_lock_bh(&ipa_ctx->q_lock);
+	pool_size = ipa_ctx->tx_desc_free_list.max_size;
+	for (i = 0; i < pool_size; i++) {
+		ipa_tx_desc = ipa_ctx->tx_desc_pool[i].ipa_tx_desc_ptr;
+		if (ipa_tx_desc)
+			qdf_ipa_free_skb(ipa_tx_desc);
+
+		if (qdf_list_remove_node(&ipa_ctx->tx_desc_free_list,
+					 &ipa_ctx->tx_desc_pool[i].node) !=
+		    QDF_STATUS_SUCCESS)
+			ipa_err("Failed to remove node from tx desc freelist");
+	}
+	qdf_spin_unlock_bh(&ipa_ctx->q_lock);
+
+	qdf_list_destroy(&ipa_ctx->tx_desc_free_list);
+	qdf_mem_free(ipa_ctx->tx_desc_pool);
+	ipa_ctx->tx_desc_pool = NULL;
+
+	ipa_ctx->stats.num_tx_desc_q_cnt = 0;
+	ipa_ctx->stats.num_tx_desc_error = 0;
+}
+
+/**
+ * wlan_ipa_alloc_tx_desc_free_list() - Allocate IPA Tx desc list
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+wlan_ipa_alloc_tx_desc_free_list(struct wlan_ipa_priv *ipa_ctx)
+{
+	int i;
+	uint32_t max_desc_cnt;
+
+	max_desc_cnt = ipa_ctx->config->txbuf_count;
+
+	ipa_ctx->tx_desc_pool = qdf_mem_malloc(sizeof(struct wlan_ipa_tx_desc) *
+					       max_desc_cnt);
+
+	if (!ipa_ctx->tx_desc_pool) {
+		ipa_err("Free Tx descriptor allocation failed");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	qdf_list_create(&ipa_ctx->tx_desc_free_list, max_desc_cnt);
+
+	qdf_spin_lock_bh(&ipa_ctx->q_lock);
+	for (i = 0; i < max_desc_cnt; i++) {
+		ipa_ctx->tx_desc_pool[i].id = i;
+		ipa_ctx->tx_desc_pool[i].ipa_tx_desc_ptr = NULL;
+		qdf_list_insert_back(&ipa_ctx->tx_desc_free_list,
+				     &ipa_ctx->tx_desc_pool[i].node);
+	}
+
+	ipa_ctx->stats.num_tx_desc_q_cnt = 0;
+	ipa_ctx->stats.num_tx_desc_error = 0;
+
+	qdf_spin_unlock_bh(&ipa_ctx->q_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+/**
+ * wlan_ipa_setup_tx_sys_pipe() - Setup IPA Tx system pipes
+ * @ipa_ctx: Global IPA IPA context
+ * @desc_fifo_sz: Number of descriptors
+ *
+ * Return: 0 on success, negative errno on error
+ */
+static int wlan_ipa_setup_tx_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
+				     int32_t desc_fifo_sz)
+{
+	int i, ret = 0;
+	qdf_ipa_sys_connect_params_t *ipa;
+
+	/*setup TX pipes */
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+		ipa = &ipa_ctx->sys_pipe[i].ipa_sys_params;
+
+		ipa->client = wlan_ipa_iface_2_client[i].cons_client;
+		ipa->desc_fifo_sz = desc_fifo_sz;
+		ipa->priv = &ipa_ctx->iface_context[i];
+		ipa->notify = wlan_ipa_i2w_cb;
+
+		if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
+			ipa->ipa_ep_cfg.hdr.hdr_len =
+				WLAN_IPA_UC_WLAN_TX_HDR_LEN;
+			ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
+			ipa->ipa_ep_cfg.hdr.hdr_ofst_pkt_size_valid = 1;
+			ipa->ipa_ep_cfg.hdr.hdr_ofst_pkt_size = 0;
+			ipa->ipa_ep_cfg.hdr.hdr_additional_const_len =
+				WLAN_IPA_UC_WLAN_8023_HDR_SIZE;
+			ipa->ipa_ep_cfg.hdr_ext.hdr_little_endian = true;
+		} else {
+			ipa->ipa_ep_cfg.hdr.hdr_len = WLAN_IPA_WLAN_TX_HDR_LEN;
+		}
+		ipa->ipa_ep_cfg.mode.mode = IPA_BASIC;
+
+		ret = wlan_ipa_wdi_setup_sys_pipe(ipa_ctx, ipa,
+				&ipa_ctx->sys_pipe[i].conn_hdl);
+		if (ret) {
+			ipa_err("Failed for pipe %d ret: %d", i, ret);
+			return ret;
+		}
+		ipa_ctx->sys_pipe[i].conn_hdl_valid = 1;
+	}
+
+	return ret;
+}
+#else
+/**
+ * wlan_ipa_setup_tx_sys_pipe() - Setup IPA Tx system pipes
+ * @ipa_ctx: Global IPA IPA context
+ * @desc_fifo_sz: Number of descriptors
+ *
+ * Return: 0 on success, negative errno on error
+ */
+static int wlan_ipa_setup_tx_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
+				     int32_t desc_fifo_sz)
+{
+	/*
+	 * The Tx system pipes are not needed for MCC when TX_FLOW_CONTROL_V2
+	 * is enabled, where per vdev descriptors are supported in firmware.
+	 */
+	return 0;
+}
+#endif
+
+/**
+ * wlan_ipa_setup_rx_sys_pipe() - Setup IPA Rx system pipes
+ * @ipa_ctx: Global IPA IPA context
+ * @desc_fifo_sz: Number of descriptors
+ *
+ * Return: 0 on success, negative errno on error
+ */
+static int wlan_ipa_setup_rx_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
+				     int32_t desc_fifo_sz)
+{
+	int ret = 0;
+	qdf_ipa_sys_connect_params_t *ipa;
+
+	/*
+	 * Hard code it here, this can be extended if in case
+	 * PROD pipe is also per interface.
+	 * Right now there is no advantage of doing this.
+	 */
+	ipa = &ipa_ctx->sys_pipe[WLAN_IPA_RX_PIPE].ipa_sys_params;
+
+	ipa->client = IPA_CLIENT_WLAN1_PROD;
+
+	ipa->desc_fifo_sz = desc_fifo_sz;
+	ipa->priv = ipa_ctx;
+	ipa->notify = wlan_ipa_w2i_cb;
+
+	ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
+	ipa->ipa_ep_cfg.hdr.hdr_len = WLAN_IPA_WLAN_RX_HDR_LEN;
+	ipa->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 1;
+	ipa->ipa_ep_cfg.mode.mode = IPA_BASIC;
+
+	ret = qdf_ipa_setup_sys_pipe(ipa,
+			&ipa_ctx->sys_pipe[WLAN_IPA_RX_PIPE].conn_hdl);
+	if (ret) {
+		ipa_err("Failed for RX pipe: %d", ret);
+		return ret;
+	}
+	ipa_ctx->sys_pipe[WLAN_IPA_RX_PIPE].conn_hdl_valid = 1;
+
+	return ret;
+}
+
+/**
+ * wlan_ipa_teardown_sys_pipe() - Tear down all IPA Sys pipes
+ * @ipa_ctx: Global IPA IPA context
+ *
+ * Return: None
+ */
+static void wlan_ipa_teardown_sys_pipe(struct wlan_ipa_priv *ipa_ctx)
+{
+	int ret, i;
+
+	if (!ipa_ctx)
+		return;
+
+	for (i = 0; i < WLAN_IPA_MAX_SYSBAM_PIPE; i++) {
+		if (ipa_ctx->sys_pipe[i].conn_hdl_valid) {
+			ret = wlan_ipa_wdi_teardown_sys_pipe(ipa_ctx,
+							     ipa_ctx->sys_pipe[i].conn_hdl);
+			if (ret)
+				ipa_err("Failed:%d", ret);
+
+			ipa_ctx->sys_pipe[i].conn_hdl_valid = 0;
+		}
+	}
+
+	wlan_ipa_free_tx_desc_list(ipa_ctx);
+}
+
+/**
+ * wlan_ipa_setup_sys_pipe() - Setup all IPA system pipes
+ * @ipa_ctx: Global IPA IPA context
+ *
+ * Return: 0 on success, negative errno on error
+ */
+static int wlan_ipa_setup_sys_pipe(struct wlan_ipa_priv *ipa_ctx)
+{
+	int ret = 0;
+	uint32_t desc_fifo_sz;
+
+	/* The maximum number of descriptors that can be provided to a BAM at
+	 * once is one less than the total number of descriptors that the buffer
+	 * can contain.
+	 * If max_num_of_descriptors = (BAM_PIPE_DESCRIPTOR_FIFO_SIZE / sizeof
+	 * (SPS_DESCRIPTOR)), then (max_num_of_descriptors - 1) descriptors can
+	 * be provided at once.
+	 * Because of above requirement, one extra descriptor will be added to
+	 * make sure hardware always has one descriptor.
+	 */
+	desc_fifo_sz = ipa_ctx->config->desc_size
+		       + SPS_DESC_SIZE;
+
+	ret = wlan_ipa_setup_tx_sys_pipe(ipa_ctx, desc_fifo_sz);
+	if (ret) {
+		ipa_err("Failed for TX pipe: %d", ret);
+		goto setup_sys_pipe_fail;
+	}
+
+	if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
+		ret = wlan_ipa_setup_rx_sys_pipe(ipa_ctx, desc_fifo_sz);
+		if (ret) {
+			ipa_err("Failed for RX pipe: %d", ret);
+			goto setup_sys_pipe_fail;
+		}
+	}
+
+       /* Allocate free Tx desc list */
+	ret = wlan_ipa_alloc_tx_desc_free_list(ipa_ctx);
+	if (ret)
+		goto setup_sys_pipe_fail;
+
+	return ret;
+
+setup_sys_pipe_fail:
+	wlan_ipa_teardown_sys_pipe(ipa_ctx);
+
+	return ret;
+}
+
+#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx,
+				     bool mcc_mode)
+{
+	qdf_ipa_msg_meta_t meta;
+	qdf_ipa_wlan_msg_t *msg;
+	int ret;
+
+	if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config))
+		return QDF_STATUS_SUCCESS;
+
+	/* Send SCC/MCC Switching event to IPA */
+	QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(*msg);
+	msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
+	if (msg == NULL) {
+		ipa_err("msg allocation failed");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	if (mcc_mode) {
+		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_MCC);
+		ipa_ctx->stats.event[QDF_SWITCH_TO_MCC]++;
+	} else {
+		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_SCC);
+		ipa_ctx->stats.event[QDF_SWITCH_TO_SCC]++;
+	}
+
+	WLAN_IPA_LOG(QDF_TRACE_LEVEL_DEBUG,
+		    "ipa_send_msg(Evt:%d)",
+		    QDF_IPA_MSG_META_MSG_TYPE(&meta));
+
+	ret = qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn);
+
+	if (ret) {
+		ipa_err("ipa_send_msg(Evt:%d) - fail=%d",
+			QDF_IPA_MSG_META_MSG_TYPE(&meta), ret);
+		qdf_mem_free(msg);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void wlan_ipa_mcc_work_handler(void *data)
+{
+	struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data;
+
+	wlan_ipa_send_mcc_scc_msg(ipa_ctx, ipa_ctx->mcc_mode);
+}
+#endif
+
+/**
+ * wlan_ipa_setup() - IPA initialization function
+ * @ipa_ctx: IPA context
+ * @ipa_cfg: IPA config
+ *
+ * Allocate ipa_ctx resources, ipa pipe resource and register
+ * wlan interface with IPA module.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx,
+			  struct wlan_ipa_config *ipa_cfg)
+{
+	int ret, i;
+	struct wlan_ipa_iface_context *iface_context = NULL;
+	QDF_STATUS status;
+
+	ipa_debug("enter");
+
+	gp_ipa = ipa_ctx;
+	ipa_ctx->num_iface = 0;
+	ipa_ctx->config = ipa_cfg;
+
+	wlan_ipa_wdi_get_wdi_version(ipa_ctx);
+
+	/* Create the interface context */
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+		iface_context = &ipa_ctx->iface_context[i];
+		iface_context->ipa_ctx = ipa_ctx;
+		iface_context->cons_client =
+			wlan_ipa_iface_2_client[i].cons_client;
+		iface_context->prod_client =
+			wlan_ipa_iface_2_client[i].prod_client;
+		iface_context->iface_id = i;
+		iface_context->dev = NULL;
+		iface_context->device_mode = QDF_MAX_NO_OF_MODE;
+		iface_context->tl_context = NULL;
+		qdf_spinlock_create(&iface_context->interface_lock);
+	}
+
+	qdf_create_work(0, &ipa_ctx->pm_work, wlan_ipa_pm_flush, ipa_ctx);
+	qdf_spinlock_create(&ipa_ctx->pm_lock);
+	qdf_spinlock_create(&ipa_ctx->q_lock);
+	qdf_nbuf_queue_init(&ipa_ctx->pm_queue_head);
+	qdf_list_create(&ipa_ctx->pending_event, 1000);
+	qdf_mutex_create(&ipa_ctx->event_lock);
+	qdf_mutex_create(&ipa_ctx->ipa_lock);
+
+	status = wlan_ipa_wdi_setup_rm(ipa_ctx);
+	if (status != QDF_STATUS_SUCCESS)
+		goto fail_setup_rm;
+
+	for (i = 0; i < WLAN_IPA_MAX_SYSBAM_PIPE; i++)
+		qdf_mem_zero(&ipa_ctx->sys_pipe[i],
+			     sizeof(struct wlan_ipa_sys_pipe));
+
+	if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
+		qdf_mem_zero(&ipa_ctx->stats, sizeof(ipa_ctx->stats));
+		ipa_ctx->sap_num_connected_sta = 0;
+		ipa_ctx->ipa_tx_packets_diff = 0;
+		ipa_ctx->ipa_rx_packets_diff = 0;
+		ipa_ctx->ipa_p_tx_packets = 0;
+		ipa_ctx->ipa_p_rx_packets = 0;
+		ipa_ctx->resource_loading = false;
+		ipa_ctx->resource_unloading = false;
+		ipa_ctx->sta_connected = 0;
+		ipa_ctx->ipa_pipes_down = true;
+		ipa_ctx->wdi_enabled = false;
+		/* Setup IPA system pipes */
+		if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
+			ret = wlan_ipa_setup_sys_pipe(ipa_ctx);
+			if (ret)
+				goto fail_create_sys_pipe;
+
+			qdf_create_work(0, &ipa_ctx->mcc_work,
+					wlan_ipa_mcc_work_handler, ipa_ctx);
+		}
+
+		status = wlan_ipa_wdi_init(ipa_ctx);
+		if (status == QDF_STATUS_E_BUSY)
+			status = wlan_ipa_uc_send_wdi_control_msg(false);
+		if (status != QDF_STATUS_SUCCESS) {
+			ipa_err("IPA WDI init failed: ret=%d", status);
+			goto fail_create_sys_pipe;
+		}
+	} else {
+		ret = wlan_ipa_setup_sys_pipe(ipa_ctx);
+		if (ret)
+			goto fail_create_sys_pipe;
+	}
+
+	qdf_event_create(&ipa_ctx->ipa_resource_comp);
+
+	ipa_debug("exit: success");
+
+	return QDF_STATUS_SUCCESS;
+
+fail_create_sys_pipe:
+	wlan_ipa_wdi_destroy_rm(ipa_ctx);
+
+fail_setup_rm:
+	qdf_spinlock_destroy(&ipa_ctx->pm_lock);
+	qdf_spinlock_destroy(&ipa_ctx->q_lock);
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+		iface_context = &ipa_ctx->iface_context[i];
+		qdf_spinlock_destroy(&iface_context->interface_lock);
+	}
+	qdf_mutex_destroy(&ipa_ctx->event_lock);
+	qdf_mutex_destroy(&ipa_ctx->ipa_lock);
+	qdf_list_destroy(&ipa_ctx->pending_event);
+	gp_ipa = NULL;
+	ipa_debug("exit: fail");
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+void wlan_ipa_flush(struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_nbuf_t skb;
+	struct wlan_ipa_pm_tx_cb *pm_tx_cb;
+
+	if (!wlan_ipa_is_enabled(ipa_ctx->config))
+		return;
+
+	qdf_cancel_work(&ipa_ctx->pm_work);
+
+	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+
+	while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head))
+	       != NULL)) {
+		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+
+		pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
+
+		if (pm_tx_cb->exception) {
+			dev_kfree_skb_any(skb);
+		} else {
+			if (pm_tx_cb->ipa_tx_desc)
+				ipa_free_skb(pm_tx_cb->ipa_tx_desc);
+		}
+
+		qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+	}
+	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+}
+
+QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx)
+{
+	struct wlan_ipa_iface_context *iface_context;
+	int i;
+
+	if (!wlan_ipa_uc_is_enabled(ipa_ctx->config))
+		wlan_ipa_teardown_sys_pipe(ipa_ctx);
+
+	/* Teardown IPA sys_pipe for MCC */
+	if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
+		wlan_ipa_teardown_sys_pipe(ipa_ctx);
+		qdf_cancel_work(&ipa_ctx->mcc_work);
+	}
+
+	wlan_ipa_wdi_destroy_rm(ipa_ctx);
+
+	wlan_ipa_flush(ipa_ctx);
+
+	qdf_spinlock_destroy(&ipa_ctx->pm_lock);
+	qdf_spinlock_destroy(&ipa_ctx->q_lock);
+
+	/* destroy the interface lock */
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+		iface_context = &ipa_ctx->iface_context[i];
+		qdf_spinlock_destroy(&iface_context->interface_lock);
+	}
+
+	if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
+		wlan_ipa_wdi_cleanup();
+		qdf_mutex_destroy(&ipa_ctx->event_lock);
+		qdf_mutex_destroy(&ipa_ctx->ipa_lock);
+		qdf_list_destroy(&ipa_ctx->pending_event);
+
+	}
+
+	gp_ipa = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+struct wlan_ipa_iface_context
+*wlan_ipa_get_iface(struct wlan_ipa_priv *ipa_ctx, uint8_t mode)
+{
+	struct wlan_ipa_iface_context *iface_ctx = NULL;
+	int i;
+
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+		iface_ctx = &ipa_ctx->iface_context[i];
+
+		if (iface_ctx->device_mode == mode)
+			return iface_ctx;
+	}
+
+	return NULL;
+}
+
+void wlan_ipa_set_mcc_mode(struct wlan_ipa_priv *ipa_ctx, bool mcc_mode)
+{
+	if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config))
+		return;
+
+	if (ipa_ctx->mcc_mode == mcc_mode)
+		return;
+
+	ipa_ctx->mcc_mode = mcc_mode;
+	qdf_sched_work(0, &ipa_ctx->mcc_work);
+}
+
+/**
+ * wlan_ipa_uc_loaded_handler() - Process IPA uC loaded indication
+ * @ipa_ctx: ipa ipa local context
+ *
+ * Will handle IPA UC image loaded indication comes from IPA kernel
+ *
+ * Return: None
+ */
+static void wlan_ipa_uc_loaded_handler(struct wlan_ipa_priv *ipa_ctx)
+{
+	struct wlan_objmgr_pdev *pdev = ipa_ctx->pdev;
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+	qdf_device_t qdf_dev = wlan_psoc_get_qdf_dev(psoc);
+	QDF_STATUS status;
+
+	ipa_info("UC READY");
+
+	if (!qdf_dev) {
+		ipa_err("qdf device is NULL!");
+		return;
+	}
+
+	if (true == ipa_ctx->uc_loaded) {
+		ipa_info("UC already loaded");
+		return;
+	}
+
+	if (!qdf_dev) {
+		ipa_err("qdf_dev is null");
+		return;
+	}
+	/* Connect pipe */
+	status = wlan_ipa_wdi_setup(ipa_ctx, qdf_dev);
+	if (status) {
+		ipa_err("Failure to setup IPA pipes (status=%d)",
+			status);
+		return;
+	}
+
+	cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev);
+
+	/* If already any STA connected, enable IPA/FW PIPEs */
+	if (ipa_ctx->sap_num_connected_sta) {
+		ipa_debug("Client already connected, enable IPA/FW PIPEs");
+		wlan_ipa_uc_handle_first_con(ipa_ctx);
+	}
+}
+
+/**
+ * wlan_ipa_uc_op_cb() - IPA uC operation callback
+ * @op_msg: operation message received from firmware
+ * @usr_ctxt: user context registered with TL (we register the IPA Global
+ *	context)
+ *
+ * Return: None
+ */
+static void wlan_ipa_uc_op_cb(struct op_msg_type *op_msg,
+			      struct wlan_ipa_priv *ipa_ctx)
+{
+	struct op_msg_type *msg = op_msg;
+	struct ipa_uc_fw_stats *uc_fw_stat;
+
+	if (!op_msg) {
+		ipa_err("INVALID ARG");
+		return;
+	}
+
+	if (msg->op_code >= WLAN_IPA_UC_OPCODE_MAX) {
+		ipa_err("INVALID OPCODE %d",  msg->op_code);
+		qdf_mem_free(op_msg);
+		return;
+	}
+
+	ipa_debug("OPCODE=%d", msg->op_code);
+
+	if ((msg->op_code == WLAN_IPA_UC_OPCODE_TX_RESUME) ||
+	    (msg->op_code == WLAN_IPA_UC_OPCODE_RX_RESUME)) {
+		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
+		ipa_ctx->activated_fw_pipe++;
+		if (wlan_ipa_is_fw_wdi_activated(ipa_ctx)) {
+			ipa_ctx->resource_loading = false;
+			qdf_event_set(&ipa_ctx->ipa_resource_comp);
+			if (ipa_ctx->wdi_enabled == false) {
+				ipa_ctx->wdi_enabled = true;
+				if (wlan_ipa_uc_send_wdi_control_msg(true) == 0)
+					wlan_ipa_send_mcc_scc_msg(ipa_ctx,
+							ipa_ctx->mcc_mode);
+			}
+			wlan_ipa_uc_proc_pending_event(ipa_ctx, true);
+			if (ipa_ctx->pending_cons_req)
+				wlan_ipa_wdi_rm_notify_completion(
+						QDF_IPA_RM_RESOURCE_GRANTED,
+						QDF_IPA_RM_RESOURCE_WLAN_CONS);
+			ipa_ctx->pending_cons_req = false;
+		}
+		qdf_mutex_release(&ipa_ctx->ipa_lock);
+	} else if ((msg->op_code == WLAN_IPA_UC_OPCODE_TX_SUSPEND) ||
+	    (msg->op_code == WLAN_IPA_UC_OPCODE_RX_SUSPEND)) {
+		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
+
+		if (msg->op_code == WLAN_IPA_UC_OPCODE_RX_SUSPEND) {
+			wlan_ipa_uc_disable_pipes(ipa_ctx);
+			ipa_info("Disable FW TX PIPE");
+			cdp_ipa_set_active(ipa_ctx->dp_soc, ipa_ctx->dp_pdev,
+					   false, true);
+		}
+
+		ipa_ctx->activated_fw_pipe--;
+		if (!ipa_ctx->activated_fw_pipe) {
+			/*
+			 * Async return success from FW
+			 * Disable/suspend all the PIPEs
+			 */
+			ipa_ctx->resource_unloading = false;
+			qdf_event_set(&ipa_ctx->ipa_resource_comp);
+			if (wlan_ipa_is_rm_enabled(ipa_ctx->config))
+				wlan_ipa_wdi_rm_release_resource(ipa_ctx,
+						QDF_IPA_RM_RESOURCE_WLAN_PROD);
+			wlan_ipa_uc_proc_pending_event(ipa_ctx, false);
+			ipa_ctx->pending_cons_req = false;
+		}
+		qdf_mutex_release(&ipa_ctx->ipa_lock);
+	} else if ((msg->op_code == WLAN_IPA_UC_OPCODE_STATS) &&
+		(ipa_ctx->stat_req_reason == WLAN_IPA_UC_STAT_REASON_DEBUG)) {
+		uc_fw_stat = (struct ipa_uc_fw_stats *)
+			((uint8_t *)op_msg + sizeof(struct op_msg_type));
+
+		/* WLAN FW WDI stats */
+		wlan_ipa_print_fw_wdi_stats(ipa_ctx, uc_fw_stat);
+	} else if ((msg->op_code == WLAN_IPA_UC_OPCODE_STATS) &&
+		(ipa_ctx->stat_req_reason == WLAN_IPA_UC_STAT_REASON_BW_CAL)) {
+		/* STATs from FW */
+		uc_fw_stat = (struct ipa_uc_fw_stats *)
+			((uint8_t *)op_msg + sizeof(struct op_msg_type));
+		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
+		ipa_ctx->ipa_tx_packets_diff = BW_GET_DIFF(
+			uc_fw_stat->tx_pkts_completed,
+			ipa_ctx->ipa_p_tx_packets);
+		ipa_ctx->ipa_rx_packets_diff = BW_GET_DIFF(
+			(uc_fw_stat->rx_num_ind_drop_no_space +
+			uc_fw_stat->rx_num_ind_drop_no_buf +
+			uc_fw_stat->rx_num_pkts_indicated),
+			ipa_ctx->ipa_p_rx_packets);
+
+		ipa_ctx->ipa_p_tx_packets = uc_fw_stat->tx_pkts_completed;
+		ipa_ctx->ipa_p_rx_packets =
+			(uc_fw_stat->rx_num_ind_drop_no_space +
+			uc_fw_stat->rx_num_ind_drop_no_buf +
+			uc_fw_stat->rx_num_pkts_indicated);
+		qdf_mutex_release(&ipa_ctx->ipa_lock);
+	} else if (msg->op_code == WLAN_IPA_UC_OPCODE_UC_READY) {
+		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
+		wlan_ipa_uc_loaded_handler(ipa_ctx);
+		qdf_mutex_release(&ipa_ctx->ipa_lock);
+	} else if (wlan_ipa_uc_op_metering(ipa_ctx, op_msg)) {
+		ipa_err("Invalid message: op_code=%d, reason=%d",
+			msg->op_code, ipa_ctx->stat_req_reason);
+	}
+
+	qdf_mem_free(op_msg);
+}
+
+/**
+ * __wlan_ipa_uc_fw_op_event_handler - IPA uC FW OPvent handler
+ * @data: uC OP work
+ *
+ * Return: None
+ */
+static void __wlan_ipa_uc_fw_op_event_handler(void *data)
+{
+	struct op_msg_type *msg;
+	struct uc_op_work_struct *uc_op_work =
+				(struct uc_op_work_struct *)data;
+	struct wlan_ipa_priv *ipa_ctx = gp_ipa;
+
+	if (qdf_is_module_state_transitioning()) {
+		ipa_err("Module transition in progress");
+		return;
+	}
+
+	msg = uc_op_work->msg;
+	uc_op_work->msg = NULL;
+	ipa_debug("posted msg %d", msg->op_code);
+
+	wlan_ipa_uc_op_cb(msg, ipa_ctx);
+}
+
+/**
+ * wlan_ipa_uc_fw_op_event_handler - SSR wrapper for
+ * __wlan_ipa_uc_fw_op_event_handler
+ * @data: uC OP work
+ *
+ * Return: None
+ */
+static void wlan_ipa_uc_fw_op_event_handler(void *data)
+{
+	qdf_ssr_protect(__func__);
+	__wlan_ipa_uc_fw_op_event_handler(data);
+	qdf_ssr_unprotect(__func__);
+}
+
+/**
+ * wlan_ipa_uc_op_event_handler() - IPA UC OP event handler
+ * @op_msg: operation message received from firmware
+ * @ipa_ctx: Global IPA context
+ *
+ * Return: None
+ */
+static void wlan_ipa_uc_op_event_handler(uint8_t *op_msg, void *ctx)
+{
+	struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)ctx;
+	struct op_msg_type *msg;
+	struct uc_op_work_struct *uc_op_work;
+
+	if (!ipa_ctx)
+		goto end;
+
+	msg = (struct op_msg_type *)op_msg;
+
+	if (msg->op_code >= WLAN_IPA_UC_OPCODE_MAX) {
+		ipa_err("Invalid OP Code (%d)", msg->op_code);
+		goto end;
+	}
+
+	uc_op_work = &ipa_ctx->uc_op_work[msg->op_code];
+	if (uc_op_work->msg) {
+		/* When the same uC OPCODE is already pended, just return */
+		goto end;
+	}
+
+	uc_op_work->msg = msg;
+	qdf_sched_work(0, &uc_op_work->work);
+	return;
+
+end:
+	qdf_mem_free(op_msg);
+}
+
+QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx,
+			       qdf_device_t osdev)
+{
+	uint8_t i;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!wlan_ipa_uc_is_enabled(ipa_ctx->config))
+		return QDF_STATUS_SUCCESS;
+
+	ipa_debug("enter");
+
+	for (i = 0; i < WLAN_IPA_MAX_SESSION; i++) {
+		ipa_ctx->vdev_to_iface[i] = WLAN_IPA_MAX_SESSION;
+		ipa_ctx->vdev_offload_enabled[i] = false;
+	}
+
+	if (cdp_ipa_get_resource(ipa_ctx->dp_soc, ipa_ctx->dp_pdev)) {
+		ipa_err("IPA UC resource alloc fail");
+		status = QDF_STATUS_E_FAILURE;
+		goto fail_return;
+	}
+
+	if (true == ipa_ctx->uc_loaded) {
+		status = wlan_ipa_wdi_setup(ipa_ctx, osdev);
+		if (status) {
+			ipa_err("Failure to setup IPA pipes (status=%d)",
+				status);
+			status = QDF_STATUS_E_FAILURE;
+			goto fail_return;
+		}
+
+		cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev);
+		wlan_ipa_init_metering(ipa_ctx);
+
+		if (wlan_ipa_init_perf_level(ipa_ctx) != QDF_STATUS_SUCCESS)
+			ipa_err("Failed to init perf level");
+	}
+
+	cdp_ipa_register_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev,
+			       wlan_ipa_uc_op_event_handler, (void *)ipa_ctx);
+
+	for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) {
+		qdf_create_work(0, &ipa_ctx->uc_op_work[i].work,
+				wlan_ipa_uc_fw_op_event_handler,
+				&ipa_ctx->uc_op_work[i]);
+		ipa_ctx->uc_op_work[i].msg = NULL;
+	}
+
+fail_return:
+	ipa_debug("exit: status=%d", status);
+	return status;
+}
+
+/**
+ * wlan_ipa_cleanup_pending_event() - Cleanup IPA pending event list
+ * @ipa_ctx: pointer to IPA IPA struct
+ *
+ * Return: none
+ */
+static void wlan_ipa_cleanup_pending_event(struct wlan_ipa_priv *ipa_ctx)
+{
+	struct wlan_ipa_uc_pending_event *pending_event = NULL;
+
+	while (qdf_list_remove_front(&ipa_ctx->pending_event,
+		(qdf_list_node_t **)&pending_event) == QDF_STATUS_SUCCESS)
+		qdf_mem_free(pending_event);
+}
+
+QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	int i;
+
+	ipa_debug("enter");
+
+	if (!wlan_ipa_uc_is_enabled(ipa_ctx->config))
+		return status;
+
+	if (!ipa_ctx->ipa_pipes_down)
+		wlan_ipa_uc_disable_pipes(ipa_ctx);
+
+	if (true == ipa_ctx->uc_loaded) {
+		status = cdp_ipa_cleanup(ipa_ctx->dp_soc,
+					 ipa_ctx->tx_pipe_handle,
+					 ipa_ctx->rx_pipe_handle);
+		if (status)
+			ipa_err("Failure to cleanup IPA pipes (status=%d)",
+				status);
+	}
+
+	qdf_mutex_acquire(&ipa_ctx->ipa_lock);
+	wlan_ipa_cleanup_pending_event(ipa_ctx);
+	qdf_mutex_release(&ipa_ctx->ipa_lock);
+
+	for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) {
+		qdf_cancel_work(&ipa_ctx->uc_op_work[i].work);
+		qdf_mem_free(ipa_ctx->uc_op_work[i].msg);
+		ipa_ctx->uc_op_work[i].msg = NULL;
+	}
+
+	ipa_debug("exit: ret=%d", status);
+	return status;
+}
+
+bool wlan_ipa_is_fw_wdi_activated(struct wlan_ipa_priv *ipa_ctx)
+{
+	return (WLAN_IPA_UC_NUM_WDI_PIPE == ipa_ctx->activated_fw_pipe);
+}
+
+/**
+ * wlan_ipa_uc_send_evt() - send event to ipa
+ * @net_dev: Interface net device
+ * @type: event type
+ * @mac_addr: pointer to mac address
+ *
+ * Send event to IPA driver
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS wlan_ipa_uc_send_evt(qdf_netdev_t net_dev,
+				       qdf_ipa_wlan_event type,
+				       uint8_t *mac_addr)
+{
+	struct wlan_ipa_priv *ipa_ctx = gp_ipa;
+	qdf_ipa_msg_meta_t meta;
+	qdf_ipa_wlan_msg_t *msg;
+
+	QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t);
+	msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
+	if (!msg) {
+		ipa_err("msg allocation failed");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	QDF_IPA_SET_META_MSG_TYPE(&meta, type);
+	qdf_str_lcopy(QDF_IPA_WLAN_MSG_NAME(msg), net_dev->name,
+		      IPA_RESOURCE_NAME_MAX);
+	qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN);
+
+	if (qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn)) {
+		ipa_err("%s: Evt: %d fail",
+			QDF_IPA_WLAN_MSG_NAME(msg),
+			QDF_IPA_MSG_META_MSG_TYPE(&meta));
+		qdf_mem_free(msg);
+
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ipa_ctx->stats.num_send_msg++;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_ipa_uc_disconnect_ap(struct wlan_ipa_priv *ipa_ctx,
+				     qdf_netdev_t net_dev)
+{
+	struct wlan_ipa_iface_context *iface_ctx;
+	QDF_STATUS status;
+
+	ipa_debug("enter");
+
+	iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_SAP_MODE);
+	if (iface_ctx)
+		status = wlan_ipa_uc_send_evt(net_dev, QDF_IPA_AP_DISCONNECT,
+					      net_dev->dev_addr);
+	else
+		return QDF_STATUS_E_INVAL;
+
+	ipa_debug("exit :%d", status);
+
+	return status;
+}
+
+void wlan_ipa_cleanup_dev_iface(struct wlan_ipa_priv *ipa_ctx,
+				qdf_netdev_t net_dev)
+{
+	struct wlan_ipa_iface_context *iface_ctx;
+	int i;
+
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+		iface_ctx = &ipa_ctx->iface_context[i];
+		if (iface_ctx->dev == net_dev)
+			break;
+	}
+
+	if (iface_ctx)
+		wlan_ipa_cleanup_iface(iface_ctx);
+}
+
+void wlan_ipa_uc_ssr_cleanup(struct wlan_ipa_priv *ipa_ctx)
+{
+	struct wlan_ipa_iface_context *iface;
+	int i;
+
+	ipa_info("enter");
+
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+		iface = &ipa_ctx->iface_context[i];
+		if (iface->dev) {
+			if (iface->device_mode == QDF_SAP_MODE)
+				wlan_ipa_uc_send_evt(iface->dev,
+						     QDF_IPA_AP_DISCONNECT,
+						     iface->dev->dev_addr);
+			else if (iface->device_mode == QDF_STA_MODE)
+				wlan_ipa_uc_send_evt(iface->dev,
+						     QDF_IPA_STA_DISCONNECT,
+						     iface->dev->dev_addr);
+			wlan_ipa_cleanup_iface(iface);
+		}
+	}
+}
+
+void wlan_ipa_fw_rejuvenate_send_msg(struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_ipa_msg_meta_t meta;
+	qdf_ipa_wlan_msg_t *msg;
+	int ret;
+
+	meta.msg_len = sizeof(*msg);
+	msg = qdf_mem_malloc(meta.msg_len);
+	if (!msg) {
+		ipa_debug("msg allocation failed");
+		return;
+	}
+
+	QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_FWR_SSR_BEFORE_SHUTDOWN);
+	ipa_debug("ipa_send_msg(Evt:%d)",
+		  meta.msg_type);
+	ret = qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn);
+
+	if (ret) {
+		ipa_err("ipa_send_msg(Evt:%d)-fail=%d",
+			meta.msg_type, ret);
+		qdf_mem_free(msg);
+	}
+	ipa_ctx->stats.num_send_msg++;
+}
diff --git a/components/ipa/core/src/wlan_ipa_main.c b/components/ipa/core/src/wlan_ipa_main.c
new file mode 100644
index 0000000..fd11058
--- /dev/null
+++ b/components/ipa/core/src/wlan_ipa_main.c
@@ -0,0 +1,628 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: contains ipa component main function definitions
+ */
+
+#include "wlan_ipa_main.h"
+#include "wlan_ipa_core.h"
+#include "wlan_ipa_tgt_api.h"
+#include "cfg_ucfg_api.h"
+
+static struct wlan_ipa_config *g_ipa_config;
+static bool g_ipa_hw_support;
+
+bool ipa_check_hw_present(void)
+{
+	/* Check if ipa hw is enabled */
+	if (qdf_ipa_uc_reg_rdyCB(NULL) != -EPERM) {
+		g_ipa_hw_support = true;
+		return true;
+	} else {
+		return false;
+	}
+}
+
+QDF_STATUS ipa_config_mem_alloc(void)
+{
+	struct wlan_ipa_config *ipa_cfg;
+
+	ipa_cfg = qdf_mem_malloc(sizeof(*ipa_cfg));
+	if (!ipa_cfg) {
+		ipa_err("Failed to allocate memory for ipa config");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	g_ipa_config = ipa_cfg;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void ipa_config_mem_free(void)
+{
+	if (!g_ipa_config) {
+		ipa_err("IPA config already freed");
+		return;
+	}
+
+	qdf_mem_free(g_ipa_config);
+	g_ipa_config = NULL;
+}
+
+bool ipa_is_hw_support(void)
+{
+	return g_ipa_hw_support;
+}
+
+bool ipa_config_is_enabled(void)
+{
+	return g_ipa_config ? wlan_ipa_is_enabled(g_ipa_config) : 0;
+}
+
+bool ipa_config_is_uc_enabled(void)
+{
+	return g_ipa_config ? wlan_ipa_uc_is_enabled(g_ipa_config) : 0;
+}
+
+QDF_STATUS ipa_obj_setup(struct wlan_ipa_priv *ipa_ctx)
+{
+	return wlan_ipa_setup(ipa_ctx, g_ipa_config);
+}
+
+QDF_STATUS ipa_obj_cleanup(struct wlan_ipa_priv *ipa_ctx)
+{
+	return wlan_ipa_cleanup(ipa_ctx);
+}
+
+QDF_STATUS ipa_send_uc_offload_enable_disable(struct wlan_objmgr_pdev *pdev,
+				struct ipa_uc_offload_control_params *req)
+{
+	return tgt_ipa_uc_offload_enable_disable(pdev, req);
+}
+
+void ipa_set_dp_handle(struct wlan_objmgr_psoc *psoc, void *dp_soc)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
+					  WLAN_IPA_ID);
+
+	if (!pdev) {
+		ipa_err("Failed to get pdev handle");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
+		return;
+	}
+
+	ipa_obj->dp_soc = dp_soc;
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
+}
+
+void ipa_set_txrx_handle(struct wlan_objmgr_psoc *psoc, void *txrx_handle)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
+					  WLAN_IPA_ID);
+
+	if (!pdev) {
+		ipa_err("Failed to get pdev handle");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
+		return;
+	}
+
+	ipa_obj->dp_pdev = txrx_handle;
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID);
+}
+
+QDF_STATUS ipa_rm_set_perf_level(struct wlan_objmgr_pdev *pdev,
+				 uint64_t tx_packets, uint64_t rx_packets)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wlan_ipa_set_perf_level(ipa_obj, tx_packets, rx_packets);
+}
+
+void ipa_uc_info(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_uc_info(ipa_obj);
+}
+
+void ipa_uc_stat(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_uc_stat(ipa_obj);
+}
+
+void ipa_uc_rt_debug_host_dump(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_uc_rt_debug_host_dump(ipa_obj);
+}
+
+void ipa_dump_info(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_dump_info(ipa_obj);
+}
+
+void ipa_uc_stat_request(struct wlan_objmgr_pdev *pdev, uint8_t reason)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_uc_stat_request(ipa_obj, reason);
+}
+
+void ipa_uc_stat_query(struct wlan_objmgr_pdev *pdev,
+		       uint32_t *ipa_tx_diff, uint32_t *ipa_rx_diff)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_uc_stat_query(ipa_obj, ipa_tx_diff, ipa_rx_diff);
+}
+
+void ipa_reg_sap_xmit_cb(struct wlan_objmgr_pdev *pdev, void *cb)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_reg_sap_xmit_cb(ipa_obj, cb);
+}
+
+void ipa_reg_send_to_nw_cb(struct wlan_objmgr_pdev *pdev, void *cb)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_reg_send_to_nw_cb(ipa_obj, cb);
+}
+
+void ipa_set_mcc_mode(struct wlan_objmgr_pdev *pdev, bool mcc_mode)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_set_mcc_mode(ipa_obj, mcc_mode);
+}
+
+void ipa_set_dfs_cac_tx(struct wlan_objmgr_pdev *pdev, bool tx_block)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_set_dfs_cac_tx(ipa_obj, tx_block);
+}
+
+void ipa_set_ap_ibss_fwd(struct wlan_objmgr_pdev *pdev, bool intra_bss)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_set_ap_ibss_fwd(ipa_obj, intra_bss);
+}
+
+void ipa_uc_force_pipe_shutdown(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	wlan_ipa_uc_disable_pipes(ipa_obj);
+}
+
+void ipa_flush(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_flush(ipa_obj);
+}
+
+QDF_STATUS ipa_suspend(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wlan_ipa_suspend(ipa_obj);
+}
+
+QDF_STATUS ipa_resume(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wlan_ipa_resume(ipa_obj);
+}
+
+QDF_STATUS ipa_uc_ol_init(struct wlan_objmgr_pdev *pdev,
+			  qdf_device_t osdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wlan_ipa_uc_ol_init(ipa_obj, osdev);
+}
+
+QDF_STATUS ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wlan_ipa_uc_ol_deinit(ipa_obj);
+}
+
+QDF_STATUS ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev,
+				bool mcc_mode)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug("ipa is disabled");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wlan_ipa_send_mcc_scc_msg(ipa_obj, mcc_mode);
+}
+
+QDF_STATUS ipa_wlan_evt(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev,
+			uint8_t device_mode, uint8_t sta_id, uint8_t session_id,
+			enum wlan_ipa_wlan_event ipa_event_type,
+			uint8_t *mac_addr)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wlan_ipa_wlan_evt(net_dev, device_mode, sta_id, session_id,
+				 ipa_event_type, mac_addr);
+}
+
+int ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
+{
+	return wlan_ipa_uc_smmu_map(map, num_buf, buf_arr);
+}
+
+bool ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	if (!ipa_config_is_enabled()) {
+		ipa_debug_rl("ipa is disabled");
+		return false;
+	}
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err_rl("IPA object is NULL");
+		return false;
+	}
+
+	return wlan_ipa_is_fw_wdi_activated(ipa_obj);
+}
+
+QDF_STATUS ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
+				qdf_netdev_t net_dev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wlan_ipa_uc_disconnect_ap(ipa_obj, net_dev);
+}
+
+void ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
+			   qdf_netdev_t net_dev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_cleanup_dev_iface(ipa_obj, net_dev);
+}
+
+void ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_uc_ssr_cleanup(ipa_obj);
+}
+
+void ipa_fw_rejuvenate_send_msg(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_ipa_priv *ipa_obj;
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	if (!ipa_obj) {
+		ipa_err("IPA object is NULL");
+		return;
+	}
+
+	return wlan_ipa_fw_rejuvenate_send_msg(ipa_obj);
+}
+
+void ipa_component_config_update(struct wlan_objmgr_psoc *psoc)
+{
+	if (!g_ipa_config) {
+		ipa_err("g_ipa_config is NULL");
+		return;
+	}
+
+	g_ipa_config->ipa_config =
+		cfg_get(psoc, CFG_DP_IPA_OFFLOAD_CONFIG);
+	g_ipa_config->desc_size =
+		cfg_get(psoc, CFG_DP_IPA_DESC_SIZE);
+	g_ipa_config->txbuf_count =
+		qdf_rounddown_pow_of_two(cfg_get(psoc,
+						 CFG_DP_IPA_UC_TX_BUF_COUNT));
+	g_ipa_config->ipa_bw_high =
+		cfg_get(psoc, CFG_DP_IPA_HIGH_BANDWIDTH_MBPS);
+	g_ipa_config->ipa_bw_medium =
+		cfg_get(psoc, CFG_DP_IPA_MEDIUM_BANDWIDTH_MBPS);
+	g_ipa_config->ipa_bw_low =
+		cfg_get(psoc, CFG_DP_IPA_LOW_BANDWIDTH_MBPS);
+	g_ipa_config->bus_bw_high =
+		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_HIGH_THRESHOLD);
+	g_ipa_config->bus_bw_medium =
+		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_MEDIUM_THRESHOLD);
+	g_ipa_config->bus_bw_low =
+		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_LOW_THRESHOLD);
+}
+
+uint32_t ipa_get_tx_buf_count(void)
+{
+	return g_ipa_config ? g_ipa_config->txbuf_count : 0;
+}
diff --git a/components/ipa/core/src/wlan_ipa_rm.c b/components/ipa/core/src/wlan_ipa_rm.c
new file mode 100644
index 0000000..d1acc56
--- /dev/null
+++ b/components/ipa/core/src/wlan_ipa_rm.c
@@ -0,0 +1,512 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/* Include Files */
+#include "wlan_ipa_core.h"
+#include "wlan_ipa_main.h"
+#include "cdp_txrx_ipa.h"
+#include "host_diag_core_event.h"
+
+QDF_STATUS wlan_ipa_set_perf_level(struct wlan_ipa_priv *ipa_ctx,
+				    uint64_t tx_packets,
+				    uint64_t rx_packets)
+{
+	uint32_t next_cons_bw, next_prod_bw;
+	int ret;
+
+	if ((!wlan_ipa_is_enabled(ipa_ctx->config)) ||
+		(!wlan_ipa_is_clk_scaling_enabled(ipa_ctx->config)))
+		return 0;
+
+	if (tx_packets > (ipa_ctx->config->bus_bw_high / 2))
+		next_cons_bw = ipa_ctx->config->ipa_bw_high;
+	else if (tx_packets > (ipa_ctx->config->bus_bw_medium / 2))
+		next_cons_bw = ipa_ctx->config->ipa_bw_medium;
+	else
+		next_cons_bw = ipa_ctx->config->ipa_bw_low;
+
+	if (rx_packets > (ipa_ctx->config->bus_bw_high / 2))
+		next_prod_bw = ipa_ctx->config->ipa_bw_high;
+	else if (rx_packets > (ipa_ctx->config->bus_bw_medium / 2))
+		next_prod_bw = ipa_ctx->config->ipa_bw_medium;
+	else
+		next_prod_bw = ipa_ctx->config->ipa_bw_low;
+
+	if (ipa_ctx->curr_cons_bw != next_cons_bw) {
+		ipa_debug("Requesting CONS perf curr: %d, next: %d",
+			  ipa_ctx->curr_cons_bw, next_cons_bw);
+		ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
+					     QDF_IPA_CLIENT_WLAN1_CONS,
+					     next_cons_bw);
+		if (ret) {
+			ipa_err("RM CONS set perf profile failed: %d", ret);
+
+			return QDF_STATUS_E_FAILURE;
+		}
+		ipa_ctx->curr_cons_bw = next_cons_bw;
+		ipa_ctx->stats.num_cons_perf_req++;
+	}
+
+	if (ipa_ctx->curr_prod_bw != next_prod_bw) {
+		ipa_debug("Requesting PROD perf curr: %d, next: %d",
+			  ipa_ctx->curr_prod_bw, next_prod_bw);
+		ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
+					     QDF_IPA_CLIENT_WLAN1_PROD,
+					     next_prod_bw);
+		if (ret) {
+			ipa_err("RM PROD set perf profile failed: %d", ret);
+			return QDF_STATUS_E_FAILURE;
+		}
+		ipa_ctx->curr_prod_bw = next_prod_bw;
+		ipa_ctx->stats.num_prod_perf_req++;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_ipa_init_perf_level(struct wlan_ipa_priv *ipa_ctx)
+{
+	int ret;
+
+	/* Set lowest bandwidth to start with */
+	if (wlan_ipa_is_clk_scaling_enabled(ipa_ctx->config))
+		return wlan_ipa_set_perf_level(ipa_ctx, 0, 0);
+
+	ipa_debug("IPA clk scaling disabled. Set perf level to maximum %d",
+		  WLAN_IPA_MAX_BANDWIDTH);
+
+	ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
+				     QDF_IPA_CLIENT_WLAN1_CONS,
+				     WLAN_IPA_MAX_BANDWIDTH);
+	if (ret) {
+		ipa_err("CONS set perf profile failed: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
+				     QDF_IPA_CLIENT_WLAN1_PROD,
+				     WLAN_IPA_MAX_BANDWIDTH);
+	if (ret) {
+		ipa_err("PROD set perf profile failed: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_METERING
+void wlan_ipa_init_metering(struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_event_create(&ipa_ctx->ipa_uc_sharing_stats_comp);
+	qdf_event_create(&ipa_ctx->ipa_uc_set_quota_comp);
+}
+#endif
+
+#ifndef CONFIG_IPA_WDI_UNIFIED_API
+/**
+ * wlan_ipa_rm_cons_release() - WLAN consumer resource release handler
+ *
+ * Callback function registered with IPA that is called when IPA wants
+ * to release the WLAN consumer resource
+ *
+ * Return: 0 if the request is granted, negative errno otherwise
+ */
+static int wlan_ipa_rm_cons_release(void)
+{
+	return 0;
+}
+
+/**
+ * wlan_ipa_wdi_rm_request() - Request resource from IPA
+ * @ipa_ctx: IPA context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_ipa_wdi_rm_request(struct wlan_ipa_priv *ipa_ctx)
+{
+	int ret;
+
+	if (!wlan_ipa_is_rm_enabled(ipa_ctx->config))
+		return QDF_STATUS_SUCCESS;
+
+	qdf_spin_lock_bh(&ipa_ctx->rm_lock);
+
+	switch (ipa_ctx->rm_state) {
+	case WLAN_IPA_RM_GRANTED:
+		qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+		return QDF_STATUS_SUCCESS;
+	case WLAN_IPA_RM_GRANT_PENDING:
+		qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+		return QDF_STATUS_E_PENDING;
+	case WLAN_IPA_RM_RELEASED:
+		ipa_ctx->rm_state = WLAN_IPA_RM_GRANT_PENDING;
+		break;
+	}
+
+	qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+
+	ret = qdf_ipa_rm_inactivity_timer_request_resource(
+			QDF_IPA_RM_RESOURCE_WLAN_PROD);
+
+	qdf_spin_lock_bh(&ipa_ctx->rm_lock);
+	if (ret == 0) {
+		ipa_ctx->rm_state = WLAN_IPA_RM_GRANTED;
+		ipa_ctx->stats.num_rm_grant_imm++;
+	}
+
+	if (ipa_ctx->wake_lock_released) {
+		qdf_wake_lock_acquire(&ipa_ctx->wake_lock,
+				      WIFI_POWER_EVENT_WAKELOCK_IPA);
+		ipa_ctx->wake_lock_released = false;
+	}
+	qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+
+	qdf_cancel_delayed_work(&ipa_ctx->wake_lock_work);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_ipa_wdi_rm_try_release(struct wlan_ipa_priv *ipa_ctx)
+{
+	int ret;
+
+	if (!wlan_ipa_is_rm_enabled(ipa_ctx->config))
+		return QDF_STATUS_SUCCESS;
+
+	if (qdf_atomic_read(&ipa_ctx->tx_ref_cnt))
+		return QDF_STATUS_E_AGAIN;
+
+	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
+
+	if (!qdf_nbuf_is_queue_empty(&ipa_ctx->pm_queue_head)) {
+		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+		return QDF_STATUS_E_AGAIN;
+	}
+	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
+
+	qdf_spin_lock_bh(&ipa_ctx->rm_lock);
+	switch (ipa_ctx->rm_state) {
+	case WLAN_IPA_RM_GRANTED:
+		break;
+	case WLAN_IPA_RM_GRANT_PENDING:
+		qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+		return QDF_STATUS_E_PENDING;
+	case WLAN_IPA_RM_RELEASED:
+		qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* IPA driver returns immediately so set the state here to avoid any
+	 * race condition.
+	 */
+	ipa_ctx->rm_state = WLAN_IPA_RM_RELEASED;
+	ipa_ctx->stats.num_rm_release++;
+	qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+
+	ret = qdf_ipa_rm_inactivity_timer_release_resource(
+				QDF_IPA_RM_RESOURCE_WLAN_PROD);
+
+	if (qdf_unlikely(ret != 0)) {
+		qdf_spin_lock_bh(&ipa_ctx->rm_lock);
+		ipa_ctx->rm_state = WLAN_IPA_RM_GRANTED;
+		qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+		QDF_ASSERT(0);
+		ipa_warn("rm_inactivity_timer_release_resource ret fail");
+	}
+
+	/*
+	 * If wake_lock is released immediately, kernel would try to suspend
+	 * immediately as well, Just avoid ping-pong between suspend-resume
+	 * while there is healthy amount of data transfer going on by
+	 * releasing the wake_lock after some delay.
+	 */
+	qdf_sched_delayed_work(&ipa_ctx->wake_lock_work,
+			       msecs_to_jiffies
+			       (WLAN_IPA_RX_INACTIVITY_MSEC_DELAY));
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_ipa_uc_rm_notify_handler() - IPA uC resource notification handler
+ * @ipa_ctx: IPA context
+ * @event: IPA RM event
+ *
+ * Return: None
+ */
+static void
+wlan_ipa_uc_rm_notify_handler(struct wlan_ipa_priv *ipa_ctx,
+			      qdf_ipa_rm_event_t event)
+{
+	if (!wlan_ipa_is_rm_enabled(ipa_ctx->config))
+		return;
+
+	ipa_debug("event code %d", event);
+
+	switch (event) {
+	case QDF_IPA_RM_RESOURCE_GRANTED:
+		/* Differed RM Granted */
+		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
+		if ((!ipa_ctx->resource_unloading) &&
+		    (!ipa_ctx->activated_fw_pipe)) {
+			wlan_ipa_uc_enable_pipes(ipa_ctx);
+			ipa_ctx->resource_loading = false;
+		}
+		qdf_mutex_release(&ipa_ctx->ipa_lock);
+		break;
+
+	case QDF_IPA_RM_RESOURCE_RELEASED:
+		/* Differed RM Released */
+		ipa_ctx->resource_unloading = false;
+		break;
+
+	default:
+		ipa_err("invalid event code %d", event);
+		break;
+	}
+}
+
+/**
+ * wlan_ipa_uc_rm_notify_defer() - Defer IPA uC notification
+ * * @data: IPA context
+ *
+ * This function is called when a resource manager event is received
+ * from firmware in interrupt context.  This function will defer the
+ * handling to the OL RX thread
+ *
+ * Return: None
+ */
+static void wlan_ipa_uc_rm_notify_defer(void *data)
+{
+	struct wlan_ipa_priv *ipa_ctx = data;
+	qdf_ipa_rm_event_t event;
+	struct uc_rm_work_struct *uc_rm_work = &ipa_ctx->uc_rm_work;
+
+	event = uc_rm_work->event;
+
+	wlan_ipa_uc_rm_notify_handler(ipa_ctx, event);
+}
+
+/**
+ * wlan_ipa_wake_lock_timer_func() - Wake lock work handler
+ * @data: IPA context
+ *
+ * When IPA resources are released in wlan_ipa_wdi_rm_try_release() we do
+ * not want to immediately release the wake lock since the system
+ * would then potentially try to suspend when there is a healthy data
+ * rate.  Deferred work is scheduled and this function handles the
+ * work.  When this function is called, if the IPA resource is still
+ * released then we release the wake lock.
+ *
+ * Return: None
+ */
+static void wlan_ipa_wake_lock_timer_func(void *data)
+{
+	struct wlan_ipa_priv *ipa_ctx = data;
+
+	qdf_spin_lock_bh(&ipa_ctx->rm_lock);
+
+	if (ipa_ctx->rm_state != WLAN_IPA_RM_RELEASED)
+		goto end;
+
+	ipa_ctx->wake_lock_released = true;
+	qdf_wake_lock_release(&ipa_ctx->wake_lock,
+			      WIFI_POWER_EVENT_WAKELOCK_IPA);
+
+end:
+	qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+}
+
+/**
+ * wlan_ipa_rm_cons_request() - WLAN consumer resource request handler
+ *
+ * Callback function registered with IPA that is called when IPA wants
+ * to access the WLAN consumer resource
+ *
+ * Return: 0 if the request is granted, negative errno otherwise
+ */
+static int wlan_ipa_rm_cons_request(void)
+{
+	struct wlan_ipa_priv *ipa_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	ipa_ctx = wlan_ipa_get_obj_context();
+
+	if (ipa_ctx->resource_loading) {
+		ipa_err("IPA resource loading in progress");
+		ipa_ctx->pending_cons_req = true;
+		status = QDF_STATUS_E_PENDING;
+	} else if (ipa_ctx->resource_unloading) {
+		ipa_err("IPA resource unloading in progress");
+		ipa_ctx->pending_cons_req = true;
+		status = QDF_STATUS_E_PERM;
+	}
+
+	return qdf_status_to_os_return(status);
+}
+
+/**
+ * wlan_ipa_rm_notify() - IPA resource manager notifier callback
+ * @user_data: user data registered with IPA
+ * @event: the IPA resource manager event that occurred
+ * @data: the data associated with the event
+ *
+ * Return: None
+ */
+static void wlan_ipa_rm_notify(void *user_data, qdf_ipa_rm_event_t event,
+			       unsigned long data)
+{
+	struct wlan_ipa_priv *ipa_ctx = user_data;
+
+	if (qdf_unlikely(!ipa_ctx))
+		return;
+
+	if (!wlan_ipa_is_rm_enabled(ipa_ctx->config))
+		return;
+
+	ipa_debug("Evt: %d", event);
+
+	switch (event) {
+	case QDF_IPA_RM_RESOURCE_GRANTED:
+		if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
+			/* RM Notification comes with ISR context
+			 * it should be serialized into work queue to avoid
+			 * ISR sleep problem
+			 */
+			ipa_ctx->uc_rm_work.event = event;
+			qdf_sched_work(0, &ipa_ctx->uc_rm_work.work);
+			break;
+		}
+		qdf_spin_lock_bh(&ipa_ctx->rm_lock);
+		ipa_ctx->rm_state = WLAN_IPA_RM_GRANTED;
+		qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+		ipa_ctx->stats.num_rm_grant++;
+		break;
+
+	case QDF_IPA_RM_RESOURCE_RELEASED:
+		ipa_debug("RM Release");
+		ipa_ctx->resource_unloading = false;
+		break;
+
+	default:
+		ipa_err("Unknown RM Evt: %d", event);
+		break;
+	}
+}
+
+QDF_STATUS wlan_ipa_wdi_setup_rm(struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_ipa_rm_create_params_t create_params;
+	int ret;
+
+	if (!wlan_ipa_is_rm_enabled(ipa_ctx->config))
+		return 0;
+
+	qdf_create_work(0, &ipa_ctx->uc_rm_work.work,
+			wlan_ipa_uc_rm_notify_defer, ipa_ctx);
+	qdf_mem_set(&create_params, 0, sizeof(create_params));
+	create_params.name = QDF_IPA_RM_RESOURCE_WLAN_PROD;
+	create_params.reg_params.user_data = ipa_ctx;
+	create_params.reg_params.notify_cb = wlan_ipa_rm_notify;
+	create_params.floor_voltage = QDF_IPA_VOLTAGE_LEVEL;
+
+	ret = qdf_ipa_rm_create_resource(&create_params);
+	if (ret) {
+		ipa_err("Create RM resource failed: %d", ret);
+		goto setup_rm_fail;
+	}
+
+	qdf_mem_set(&create_params, 0, sizeof(create_params));
+	create_params.name = QDF_IPA_RM_RESOURCE_WLAN_CONS;
+	create_params.request_resource = wlan_ipa_rm_cons_request;
+	create_params.release_resource = wlan_ipa_rm_cons_release;
+	create_params.floor_voltage = QDF_IPA_VOLTAGE_LEVEL;
+
+	ret = qdf_ipa_rm_create_resource(&create_params);
+	if (ret) {
+		ipa_err("Create RM CONS resource failed: %d", ret);
+		goto delete_prod;
+	}
+
+	qdf_ipa_rm_add_dependency(QDF_IPA_RM_RESOURCE_WLAN_PROD,
+				  QDF_IPA_RM_RESOURCE_APPS_CONS);
+
+	ret = qdf_ipa_rm_inactivity_timer_init(QDF_IPA_RM_RESOURCE_WLAN_PROD,
+					WLAN_IPA_RX_INACTIVITY_MSEC_DELAY);
+	if (ret) {
+		ipa_err("Timer init failed: %d", ret);
+		goto timer_init_failed;
+	}
+
+	qdf_wake_lock_create(&ipa_ctx->wake_lock, "wlan_ipa");
+	qdf_create_delayed_work(&ipa_ctx->wake_lock_work,
+				wlan_ipa_wake_lock_timer_func, ipa_ctx);
+	qdf_spinlock_create(&ipa_ctx->rm_lock);
+	ipa_ctx->rm_state = WLAN_IPA_RM_RELEASED;
+	ipa_ctx->wake_lock_released = true;
+	qdf_atomic_set(&ipa_ctx->tx_ref_cnt, 0);
+
+	return QDF_STATUS_SUCCESS;
+
+timer_init_failed:
+	qdf_ipa_rm_delete_resource(QDF_IPA_RM_RESOURCE_APPS_CONS);
+
+delete_prod:
+	qdf_ipa_rm_delete_resource(QDF_IPA_RM_RESOURCE_WLAN_PROD);
+
+setup_rm_fail:
+	return QDF_STATUS_E_FAILURE;
+}
+
+void wlan_ipa_wdi_destroy_rm(struct wlan_ipa_priv *ipa_ctx)
+{
+	int ret;
+
+	if (!wlan_ipa_is_rm_enabled(ipa_ctx->config))
+		return;
+
+	qdf_cancel_delayed_work(&ipa_ctx->wake_lock_work);
+	qdf_wake_lock_destroy(&ipa_ctx->wake_lock);
+	qdf_cancel_work(&ipa_ctx->uc_rm_work.work);
+	qdf_spinlock_destroy(&ipa_ctx->rm_lock);
+
+	qdf_ipa_rm_inactivity_timer_destroy(QDF_IPA_RM_RESOURCE_WLAN_PROD);
+
+	ret = qdf_ipa_rm_delete_resource(QDF_IPA_RM_RESOURCE_WLAN_CONS);
+	if (ret)
+		ipa_err("RM CONS resource delete failed %d", ret);
+
+	ret = qdf_ipa_rm_delete_resource(QDF_IPA_RM_RESOURCE_WLAN_PROD);
+	if (ret)
+		ipa_err("RM PROD resource delete failed %d", ret);
+}
+
+bool wlan_ipa_is_rm_released(struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_spin_lock_bh(&ipa_ctx->rm_lock);
+
+	if (ipa_ctx->rm_state != WLAN_IPA_RM_RELEASED) {
+		qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+		return false;
+	}
+
+	qdf_spin_unlock_bh(&ipa_ctx->rm_lock);
+
+	return true;
+}
+#endif /* CONFIG_IPA_WDI_UNIFIED_API */
diff --git a/components/ipa/core/src/wlan_ipa_stats.c b/components/ipa/core/src/wlan_ipa_stats.c
new file mode 100644
index 0000000..48bb51a
--- /dev/null
+++ b/components/ipa/core/src/wlan_ipa_stats.c
@@ -0,0 +1,965 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/* Include Files */
+#include "wlan_ipa_main.h"
+#include "wlan_ipa_core.h"
+#include "cdp_txrx_ipa.h"
+#include "qdf_platform.h"
+
+/**
+ * wlan_ipa_uc_rt_debug_host_fill - fill rt debug buffer
+ * @ctext: pointer to ipa context.
+ *
+ * If rt debug enabled, periodically called, and fill debug buffer
+ *
+ * Return: none
+ */
+static void wlan_ipa_uc_rt_debug_host_fill(void *ctext)
+{
+	struct wlan_ipa_priv *ipa_ctx = ctext;
+	struct uc_rt_debug_info *dump_info = NULL;
+
+	if (!ipa_ctx)
+		return;
+
+	qdf_mutex_acquire(&ipa_ctx->rt_debug_lock);
+	dump_info = &ipa_ctx->rt_bug_buffer[
+		ipa_ctx->rt_buf_fill_index % WLAN_IPA_UC_RT_DEBUG_BUF_COUNT];
+
+	dump_info->time = (uint64_t)qdf_mc_timer_get_system_time();
+	dump_info->ipa_excep_count = ipa_ctx->stats.num_rx_excep;
+	dump_info->rx_drop_count = ipa_ctx->ipa_rx_internal_drop_count;
+	dump_info->net_sent_count = ipa_ctx->ipa_rx_net_send_count;
+	dump_info->tx_fwd_count = ipa_ctx->ipa_tx_forward;
+	dump_info->tx_fwd_ok_count = ipa_ctx->stats.num_tx_fwd_ok;
+	dump_info->rx_discard_count = ipa_ctx->ipa_rx_discard;
+	dump_info->rx_destructor_call = ipa_ctx->ipa_rx_destructor_count;
+	ipa_ctx->rt_buf_fill_index++;
+	qdf_mutex_release(&ipa_ctx->rt_debug_lock);
+
+	qdf_mc_timer_start(&ipa_ctx->rt_debug_fill_timer,
+		WLAN_IPA_UC_RT_DEBUG_FILL_INTERVAL);
+}
+
+void wlan_ipa_uc_rt_debug_host_dump(struct wlan_ipa_priv *ipa_ctx)
+{
+	unsigned int dump_count;
+	unsigned int dump_index;
+	struct uc_rt_debug_info *dump_info = NULL;
+
+	if (!wlan_ipa_is_rt_debugging_enabled(ipa_ctx->config)) {
+		ipa_debug("IPA RT debug is not enabled");
+		return;
+	}
+
+	ipa_info("========= WLAN-IPA DEBUG BUF DUMP ==========\n");
+	ipa_info("     TM     :   EXEP   :   DROP   :   NETS   :   FWOK"
+		 ":   TXFD   :   DSTR   :   DSCD\n");
+
+	qdf_mutex_acquire(&ipa_ctx->rt_debug_lock);
+	for (dump_count = 0;
+		dump_count < WLAN_IPA_UC_RT_DEBUG_BUF_COUNT;
+		dump_count++) {
+		dump_index = (ipa_ctx->rt_buf_fill_index + dump_count) %
+			WLAN_IPA_UC_RT_DEBUG_BUF_COUNT;
+		dump_info = &ipa_ctx->rt_bug_buffer[dump_index];
+		ipa_info("%12llu:%10llu:%10llu:%10llu:%10llu:%10llu:%10llu:%10llu\n",
+			dump_info->time, dump_info->ipa_excep_count,
+			dump_info->rx_drop_count, dump_info->net_sent_count,
+			dump_info->tx_fwd_ok_count, dump_info->tx_fwd_count,
+			dump_info->rx_destructor_call,
+			dump_info->rx_discard_count);
+	}
+	qdf_mutex_release(&ipa_ctx->rt_debug_lock);
+}
+
+/**
+ * wlan_ipa_uc_rt_debug_handler - periodic memory health monitor handler
+ * @ctext: pointer to ipa context.
+ *
+ * periodically called by timer expire
+ * will try to alloc dummy memory and detect out of memory condition
+ * if out of memory detected, dump wlan-ipa stats
+ *
+ * Return: none
+ */
+static void wlan_ipa_uc_rt_debug_handler(void *ctext)
+{
+	struct wlan_ipa_priv *ipa_ctx = ctext;
+	void *dummy_ptr = NULL;
+
+	if (!wlan_ipa_is_rt_debugging_enabled(ipa_ctx->config)) {
+		ipa_debug("IPA RT debug is not enabled");
+		return;
+	}
+
+	/* Allocate dummy buffer periodically and free immediately. this will
+	 * proactively detect OOM and if allocation fails dump ipa stats
+	 */
+	dummy_ptr = qdf_mem_malloc(WLAN_IPA_UC_DEBUG_DUMMY_MEM_SIZE);
+	if (!dummy_ptr) {
+		wlan_ipa_uc_rt_debug_host_dump(ipa_ctx);
+		wlan_ipa_uc_stat_request(ipa_ctx,
+					 WLAN_IPA_UC_STAT_REASON_DEBUG);
+	} else {
+		qdf_mem_free(dummy_ptr);
+	}
+
+	qdf_mc_timer_start(&ipa_ctx->rt_debug_timer,
+		WLAN_IPA_UC_RT_DEBUG_PERIOD);
+}
+
+void wlan_ipa_uc_rt_debug_destructor(qdf_nbuf_t nbuff)
+{
+	struct wlan_ipa_priv *ipa_ctx = wlan_ipa_get_obj_context();
+
+	if (!ipa_ctx) {
+		ipa_err("invalid ipa context");
+		return;
+	}
+
+	ipa_ctx->ipa_rx_destructor_count++;
+}
+
+void wlan_ipa_uc_rt_debug_deinit(struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_mutex_destroy(&ipa_ctx->rt_debug_lock);
+
+	if (!wlan_ipa_is_rt_debugging_enabled(ipa_ctx->config)) {
+		ipa_debug("IPA RT debug is not enabled");
+		return;
+	}
+
+	if (QDF_TIMER_STATE_STOPPED !=
+		qdf_mc_timer_get_current_state(&ipa_ctx->rt_debug_fill_timer)) {
+		qdf_mc_timer_stop(&ipa_ctx->rt_debug_fill_timer);
+	}
+	qdf_mc_timer_destroy(&ipa_ctx->rt_debug_fill_timer);
+
+	if (QDF_TIMER_STATE_STOPPED !=
+		qdf_mc_timer_get_current_state(&ipa_ctx->rt_debug_timer)) {
+		qdf_mc_timer_stop(&ipa_ctx->rt_debug_timer);
+	}
+	qdf_mc_timer_destroy(&ipa_ctx->rt_debug_timer);
+}
+
+void wlan_ipa_uc_rt_debug_init(struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_mutex_create(&ipa_ctx->rt_debug_lock);
+	ipa_ctx->rt_buf_fill_index = 0;
+	qdf_mem_zero(ipa_ctx->rt_bug_buffer,
+		sizeof(struct uc_rt_debug_info) *
+		WLAN_IPA_UC_RT_DEBUG_BUF_COUNT);
+	ipa_ctx->ipa_tx_forward = 0;
+	ipa_ctx->ipa_rx_discard = 0;
+	ipa_ctx->ipa_rx_net_send_count = 0;
+	ipa_ctx->ipa_rx_internal_drop_count = 0;
+	ipa_ctx->ipa_rx_destructor_count = 0;
+
+	/* Reatime debug enable on feature enable */
+	if (!wlan_ipa_is_rt_debugging_enabled(ipa_ctx->config)) {
+		ipa_debug("IPA RT debug is not enabled");
+		return;
+	}
+
+	qdf_mc_timer_init(&ipa_ctx->rt_debug_fill_timer, QDF_TIMER_TYPE_SW,
+		wlan_ipa_uc_rt_debug_host_fill, (void *)ipa_ctx);
+	qdf_mc_timer_start(&ipa_ctx->rt_debug_fill_timer,
+		WLAN_IPA_UC_RT_DEBUG_FILL_INTERVAL);
+
+	qdf_mc_timer_init(&ipa_ctx->rt_debug_timer, QDF_TIMER_TYPE_SW,
+		wlan_ipa_uc_rt_debug_handler, (void *)ipa_ctx);
+	qdf_mc_timer_start(&ipa_ctx->rt_debug_timer,
+		WLAN_IPA_UC_RT_DEBUG_PERIOD);
+
+}
+
+/**
+ * wlan_ipa_dump_ipa_ctx() - dump entries in IPA IPA struct
+ * @ipa_ctx: IPA context
+ *
+ * Dump entries in struct ipa_ctx
+ *
+ * Return: none
+ */
+static void wlan_ipa_dump_ipa_ctx(struct wlan_ipa_priv *ipa_ctx)
+{
+	int i;
+
+	/* IPA IPA */
+	ipa_info("\n==== IPA IPA ====\n"
+		"num_iface: %d\n"
+		"rm_state: %d\n"
+		"rm_lock: %pK\n"
+		"uc_rm_work: %pK\n"
+		"uc_op_work: %pK\n"
+		"wake_lock: %pK\n"
+		"wake_lock_work: %pK\n"
+		"wake_lock_released: %d\n"
+		"tx_ref_cnt: %d\n"
+		"pm_queue_head----\n"
+		"\thead: %pK\n"
+		"\ttail: %pK\n"
+		"\tqlen: %d\n"
+		"pm_work: %pK\n"
+		"pm_lock: %pK\n"
+		"suspended: %d\n",
+		ipa_ctx->num_iface,
+		ipa_ctx->rm_state,
+		&ipa_ctx->rm_lock,
+		&ipa_ctx->uc_rm_work,
+		&ipa_ctx->uc_op_work,
+		&ipa_ctx->wake_lock,
+		&ipa_ctx->wake_lock_work,
+		ipa_ctx->wake_lock_released,
+		ipa_ctx->tx_ref_cnt.counter,
+		ipa_ctx->pm_queue_head.head,
+		ipa_ctx->pm_queue_head.tail,
+		ipa_ctx->pm_queue_head.qlen,
+		&ipa_ctx->pm_work,
+		&ipa_ctx->pm_lock,
+		ipa_ctx->suspended);
+
+	ipa_info("\nq_lock: %pK\n"
+		"pend_desc_head----\n"
+		"\tnext: %pK\n"
+		"\tprev: %pK\n"
+		"stats: %pK\n"
+		"curr_prod_bw: %d\n"
+		"curr_cons_bw: %d\n"
+		"activated_fw_pipe: %d\n"
+		"sap_num_connected_sta: %d\n"
+		"sta_connected: %d\n",
+		&ipa_ctx->q_lock,
+		ipa_ctx->pend_desc_head.next,
+		ipa_ctx->pend_desc_head.prev,
+		&ipa_ctx->stats,
+		ipa_ctx->curr_prod_bw,
+		ipa_ctx->curr_cons_bw,
+		ipa_ctx->activated_fw_pipe,
+		ipa_ctx->sap_num_connected_sta,
+		(unsigned int)ipa_ctx->sta_connected);
+
+	ipa_info("\ntx_pipe_handle: 0x%x\n"
+		"rx_pipe_handle: 0x%x\n"
+		"resource_loading: %d\n"
+		"resource_unloading: %d\n"
+		"pending_cons_req: %d\n"
+		"pending_event----\n"
+		"\tanchor.next: %pK\n"
+		"\tanchor.prev: %pK\n"
+		"\tcount: %d\n"
+		"\tmax_size: %d\n"
+		"event_lock: %pK\n"
+		"ipa_tx_packets_diff: %d\n"
+		"ipa_rx_packets_diff: %d\n"
+		"ipa_p_tx_packets: %d\n"
+		"ipa_p_rx_packets: %d\n"
+		"stat_req_reason: %d\n",
+		ipa_ctx->tx_pipe_handle,
+		ipa_ctx->rx_pipe_handle,
+		ipa_ctx->resource_loading,
+		ipa_ctx->resource_unloading,
+		ipa_ctx->pending_cons_req,
+		ipa_ctx->pending_event.anchor.next,
+		ipa_ctx->pending_event.anchor.prev,
+		ipa_ctx->pending_event.count,
+		ipa_ctx->pending_event.max_size,
+		&ipa_ctx->event_lock,
+		ipa_ctx->ipa_tx_packets_diff,
+		ipa_ctx->ipa_rx_packets_diff,
+		ipa_ctx->ipa_p_tx_packets,
+		ipa_ctx->ipa_p_rx_packets,
+		ipa_ctx->stat_req_reason);
+
+	ipa_info("\ncons_pipe_in----\n"
+		"\tsys: %pK\n"
+		"\tdl.comp_ring_base_pa: 0x%x\n"
+		"\tdl.comp_ring_size: %d\n"
+		"\tdl.ce_ring_base_pa: 0x%x\n"
+		"\tdl.ce_door_bell_pa: 0x%x\n"
+		"\tdl.ce_ring_size: %d\n"
+		"\tdl.num_tx_buffers: %d\n"
+		"prod_pipe_in----\n"
+		"\tsys: %pK\n"
+		"\tul.rdy_ring_base_pa: 0x%x\n"
+		"\tul.rdy_ring_size: %d\n"
+		"\tul.rdy_ring_rp_pa: 0x%x\n"
+		"uc_loaded: %d\n"
+		"wdi_enabled: %d\n"
+		"rt_debug_fill_timer: %pK\n"
+		"rt_debug_lock: %pK\n"
+		"ipa_lock: %pK\n",
+		&ipa_ctx->cons_pipe_in.sys,
+		(unsigned int)ipa_ctx->cons_pipe_in.u.dl.comp_ring_base_pa,
+		ipa_ctx->cons_pipe_in.u.dl.comp_ring_size,
+		(unsigned int)ipa_ctx->cons_pipe_in.u.dl.ce_ring_base_pa,
+		(unsigned int)ipa_ctx->cons_pipe_in.u.dl.ce_door_bell_pa,
+		ipa_ctx->cons_pipe_in.u.dl.ce_ring_size,
+		ipa_ctx->cons_pipe_in.u.dl.num_tx_buffers,
+		&ipa_ctx->prod_pipe_in.sys,
+		(unsigned int)ipa_ctx->prod_pipe_in.u.ul.rdy_ring_base_pa,
+		ipa_ctx->prod_pipe_in.u.ul.rdy_ring_size,
+		(unsigned int)ipa_ctx->prod_pipe_in.u.ul.rdy_ring_rp_pa,
+		ipa_ctx->uc_loaded,
+		ipa_ctx->wdi_enabled,
+		&ipa_ctx->rt_debug_fill_timer,
+		&ipa_ctx->rt_debug_lock,
+		&ipa_ctx->ipa_lock);
+
+	ipa_info("\nvdev_to_iface----");
+	for (i = 0; i < WLAN_IPA_MAX_SESSION; i++)
+		ipa_info("\n\t[%d]=%d", i, ipa_ctx->vdev_to_iface[i]);
+
+	QDF_TRACE(QDF_MODULE_ID_IPA, QDF_TRACE_LEVEL_INFO,
+		"\nvdev_offload_enabled----");
+	for (i = 0; i < WLAN_IPA_MAX_SESSION; i++)
+		ipa_info("\n\t[%d]=%d", i, ipa_ctx->vdev_offload_enabled[i]);
+
+	QDF_TRACE(QDF_MODULE_ID_IPA, QDF_TRACE_LEVEL_INFO,
+		"\nassoc_stas_map ----");
+	for (i = 0; i < WLAN_IPA_MAX_STA_COUNT; i++) {
+		ipa_info("\n\t[%d]: is_reserved=%d, sta_id=%d", i,
+			ipa_ctx->assoc_stas_map[i].is_reserved,
+			ipa_ctx->assoc_stas_map[i].sta_id);
+	}
+}
+
+/**
+ * wlan_ipa_dump_sys_pipe() - dump IPA IPA SYS Pipe struct
+ * @ipa_ctx: IPA IPA struct
+ *
+ * Dump entire struct wlan_ipa_sys_pipe
+ *
+ * Return: none
+ */
+static void wlan_ipa_dump_sys_pipe(struct wlan_ipa_priv *ipa_ctx)
+{
+	int i;
+
+	/* IPA SYS Pipes */
+	ipa_info("==== IPA SYS Pipes ====");
+
+	for (i = 0; i < WLAN_IPA_MAX_SYSBAM_PIPE; i++) {
+		struct wlan_ipa_sys_pipe *sys_pipe;
+		qdf_ipa_sys_connect_params_t *ipa_sys_params;
+
+		sys_pipe = &ipa_ctx->sys_pipe[i];
+		ipa_sys_params = &sys_pipe->ipa_sys_params;
+
+		ipa_info("\nsys_pipe[%d]----\n"
+			"\tconn_hdl: 0x%x\n"
+			"\tconn_hdl_valid: %d\n"
+			"\tnat_en: %d\n"
+			"\thdr_len %d\n"
+			"\thdr_additional_const_len: %d\n"
+			"\thdr_ofst_pkt_size_valid: %d\n"
+			"\thdr_ofst_pkt_size: %d\n"
+			"\thdr_little_endian: %d\n"
+			"\tmode: %d\n"
+			"\tclient: %d\n"
+			"\tdesc_fifo_sz: %d\n"
+			"\tpriv: %pK\n"
+			"\tnotify: %pK\n"
+			"\tskip_ep_cfg: %d\n"
+			"\tkeep_ipa_awake: %d\n",
+			i,
+			sys_pipe->conn_hdl,
+			sys_pipe->conn_hdl_valid,
+			QDF_IPA_SYS_PARAMS_NAT_EN(ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_HDR_LEN(ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_HDR_ADDITIONAL_CONST_LEN(
+				ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_HDR_OFST_PKT_SIZE_VALID(
+				ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_HDR_OFST_PKT_SIZE(ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_HDR_LITTLE_ENDIAN(ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_MODE(ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_CLIENT(ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_DESC_FIFO_SZ(ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_PRIV(ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_NOTIFY(ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_SKIP_EP_CFG(ipa_sys_params),
+			QDF_IPA_SYS_PARAMS_KEEP_IPA_AWAKE(ipa_sys_params));
+	}
+}
+
+/**
+ * wlan_ipa_dump_iface_context() - dump IPA IPA Interface Context struct
+ * @ipa_ctx: IPA IPA struct
+ *
+ * Dump entire struct wlan_ipa_iface_context
+ *
+ * Return: none
+ */
+static void wlan_ipa_dump_iface_context(struct wlan_ipa_priv *ipa_ctx)
+{
+	int i;
+
+	/* IPA Interface Contexts */
+	ipa_info("\n==== IPA Interface Contexts ====\n");
+
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+		struct wlan_ipa_iface_context *iface_context;
+
+		iface_context = &ipa_ctx->iface_context[i];
+
+		ipa_info("\niface_context[%d]----\n"
+			"\tipa_ctx: %pK\n"
+			"\ttl_context: %pK\n"
+			"\tcons_client: %d\n"
+			"\tprod_client: %d\n"
+			"\tiface_id: %d\n"
+			"\tsta_id: %d\n"
+			"\tinterface_lock: %pK\n"
+			"\tifa_address: 0x%x\n",
+			i,
+			iface_context->ipa_ctx,
+			iface_context->tl_context,
+			iface_context->cons_client,
+			iface_context->prod_client,
+			iface_context->iface_id,
+			iface_context->sta_id,
+			&iface_context->interface_lock,
+			iface_context->ifa_address);
+	}
+}
+
+void wlan_ipa_dump_info(struct wlan_ipa_priv *ipa_ctx)
+{
+	wlan_ipa_dump_ipa_ctx(ipa_ctx);
+	wlan_ipa_dump_sys_pipe(ipa_ctx);
+	wlan_ipa_dump_iface_context(ipa_ctx);
+}
+
+void wlan_ipa_uc_stat_query(struct wlan_ipa_priv *ipa_ctx,
+			    uint32_t *ipa_tx_diff, uint32_t *ipa_rx_diff)
+{
+	*ipa_tx_diff = 0;
+	*ipa_rx_diff = 0;
+
+	qdf_mutex_acquire(&ipa_ctx->ipa_lock);
+	if ((ipa_ctx->activated_fw_pipe == WLAN_IPA_UC_NUM_WDI_PIPE) &&
+	    (false == ipa_ctx->resource_loading)) {
+		*ipa_tx_diff = ipa_ctx->ipa_tx_packets_diff;
+		*ipa_rx_diff = ipa_ctx->ipa_rx_packets_diff;
+	}
+	qdf_mutex_release(&ipa_ctx->ipa_lock);
+}
+
+void wlan_ipa_uc_stat_request(struct wlan_ipa_priv *ipa_ctx, uint8_t reason)
+{
+	qdf_mutex_acquire(&ipa_ctx->ipa_lock);
+	if ((ipa_ctx->activated_fw_pipe == WLAN_IPA_UC_NUM_WDI_PIPE) &&
+	    (false == ipa_ctx->resource_loading)) {
+		ipa_ctx->stat_req_reason = reason;
+		cdp_ipa_get_stat(ipa_ctx->dp_soc, ipa_ctx->dp_pdev);
+		qdf_mutex_release(&ipa_ctx->ipa_lock);
+	} else {
+		qdf_mutex_release(&ipa_ctx->ipa_lock);
+	}
+}
+
+/**
+ * wlan_ipa_print_session_info - Print IPA session info
+ * @ipa_ctx: IPA context
+ *
+ * Return: None
+ */
+static void wlan_ipa_print_session_info(struct wlan_ipa_priv *ipa_ctx)
+{
+	struct wlan_ipa_uc_pending_event *event = NULL, *next = NULL;
+	struct wlan_ipa_iface_context *iface_context = NULL;
+	int i;
+
+	ipa_info("\n==== IPA SESSION INFO ====\n"
+		"NUM IFACE: %d\n"
+		"RM STATE: %d\n"
+		"ACTIVATED FW PIPE: %d\n"
+		"SAP NUM STAs: %d\n"
+		"STA CONNECTED: %d\n"
+		"CONCURRENT MODE: %s\n"
+		"RSC LOADING: %d\n"
+		"RSC UNLOADING: %d\n"
+		"PENDING CONS REQ: %d\n"
+		"IPA PIPES DOWN: %d\n"
+		"IPA UC LOADED: %d\n"
+		"IPA WDI ENABLED: %d\n"
+		"NUM SEND MSG: %d\n"
+		"NUM FREE MSG: %d\n",
+		ipa_ctx->num_iface,
+		ipa_ctx->rm_state,
+		ipa_ctx->activated_fw_pipe,
+		ipa_ctx->sap_num_connected_sta,
+		ipa_ctx->sta_connected,
+		(ipa_ctx->mcc_mode ? "MCC" : "SCC"),
+		ipa_ctx->resource_loading,
+		ipa_ctx->resource_unloading,
+		ipa_ctx->pending_cons_req,
+		ipa_ctx->ipa_pipes_down,
+		ipa_ctx->uc_loaded,
+		ipa_ctx->wdi_enabled,
+		(unsigned int)ipa_ctx->stats.num_send_msg,
+		(unsigned int)ipa_ctx->stats.num_free_msg);
+
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+		iface_context = &ipa_ctx->iface_context[i];
+
+		if (!iface_context->tl_context)
+			continue;
+
+		ipa_info("\nIFACE[%d]: sta_id:%d, mode:%d, offload:%d",
+			 i, iface_context->sta_id,
+			 iface_context->device_mode,
+			 ipa_ctx->vdev_offload_enabled[iface_context->
+						       session_id]);
+	}
+
+	for (i = 0; i < QDF_IPA_WLAN_EVENT_MAX; i++)
+		ipa_info("\nEVENT[%d]=%d",
+			 i, ipa_ctx->stats.event[i]);
+
+	i = 0;
+	qdf_list_peek_front(&ipa_ctx->pending_event,
+			(qdf_list_node_t **)&event);
+	while (event != NULL) {
+		ipa_info("PENDING EVENT[%d]: EVT:%s, sta_id:%d, MAC:%pM",
+			 i, wlan_ipa_wlan_event_to_str(event->type),
+			 event->sta_id, event->mac_addr);
+
+		qdf_list_peek_next(&ipa_ctx->pending_event,
+				   (qdf_list_node_t *)event,
+				   (qdf_list_node_t **)&next);
+		event = next;
+		next = NULL;
+		i++;
+	}
+}
+
+/**
+ * wlan_ipa_print_txrx_stats - Print IPA IPA TX/RX stats
+ * @ipa_ctx: IPA context
+ *
+ * Return: None
+ */
+static void wlan_ipa_print_txrx_stats(struct wlan_ipa_priv *ipa_ctx)
+{
+	int i;
+	struct wlan_ipa_iface_context *iface_context = NULL;
+
+	ipa_info("\n==== IPA IPA TX/RX STATS ====\n"
+		"NUM RM GRANT: %llu\n"
+		"NUM RM RELEASE: %llu\n"
+		"NUM RM GRANT IMM: %llu\n"
+		"NUM CONS PERF REQ: %llu\n"
+		"NUM PROD PERF REQ: %llu\n"
+		"NUM RX DROP: %llu\n"
+		"NUM EXCP PKT: %llu\n"
+		"NUM TX FWD OK: %llu\n"
+		"NUM TX FWD ERR: %llu\n"
+		"NUM TX DESC Q CNT: %llu\n"
+		"NUM TX DESC ERROR: %llu\n"
+		"NUM TX COMP CNT: %llu\n"
+		"NUM TX QUEUED: %llu\n"
+		"NUM TX DEQUEUED: %llu\n"
+		"NUM MAX PM QUEUE: %llu\n"
+		"TX REF CNT: %d\n"
+		"SUSPENDED: %d\n"
+		"PEND DESC HEAD: %pK\n"
+		"TX DESC LIST: %pK\n",
+		ipa_ctx->stats.num_rm_grant,
+		ipa_ctx->stats.num_rm_release,
+		ipa_ctx->stats.num_rm_grant_imm,
+		ipa_ctx->stats.num_cons_perf_req,
+		ipa_ctx->stats.num_prod_perf_req,
+		ipa_ctx->stats.num_rx_drop,
+		ipa_ctx->stats.num_rx_excep,
+		ipa_ctx->stats.num_tx_fwd_ok,
+		ipa_ctx->stats.num_tx_fwd_err,
+		ipa_ctx->stats.num_tx_desc_q_cnt,
+		ipa_ctx->stats.num_tx_desc_error,
+		ipa_ctx->stats.num_tx_comp_cnt,
+		ipa_ctx->stats.num_tx_queued,
+		ipa_ctx->stats.num_tx_dequeued,
+		ipa_ctx->stats.num_max_pm_queue,
+		ipa_ctx->tx_ref_cnt.counter,
+		ipa_ctx->suspended,
+		&ipa_ctx->pend_desc_head,
+		&ipa_ctx->tx_desc_free_list);
+
+	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
+
+		iface_context = &ipa_ctx->iface_context[i];
+		if (!iface_context->tl_context)
+			continue;
+
+		ipa_info("IFACE[%d]: TX:%llu, TX DROP:%llu, TX ERR:%llu,"
+			 " TX CAC DROP:%llu, RX IPA EXCEP:%llu",
+			 i, iface_context->stats.num_tx,
+			 iface_context->stats.num_tx_drop,
+			 iface_context->stats.num_tx_err,
+			 iface_context->stats.num_tx_cac_drop,
+			 iface_context->stats.num_rx_ipa_excep);
+	}
+}
+
+void wlan_ipa_print_fw_wdi_stats(struct wlan_ipa_priv *ipa_ctx,
+				 struct ipa_uc_fw_stats *uc_fw_stat)
+{
+	ipa_info("\n==== WLAN FW WDI TX STATS ====\n"
+		"COMP RING SIZE: %d\n"
+		"COMP RING DBELL IND VAL : %d\n"
+		"COMP RING DBELL CACHED VAL : %d\n"
+		"PKTS ENQ : %d\n"
+		"PKTS COMP : %d\n"
+		"IS SUSPEND : %d\n",
+		uc_fw_stat->tx_comp_ring_size,
+		uc_fw_stat->tx_comp_ring_dbell_ind_val,
+		uc_fw_stat->tx_comp_ring_dbell_cached_val,
+		uc_fw_stat->tx_pkts_enqueued,
+		uc_fw_stat->tx_pkts_completed,
+		uc_fw_stat->tx_is_suspend);
+
+	ipa_info("\n==== WLAN FW WDI RX STATS ====\n"
+		"IND RING SIZE: %d\n"
+		"IND RING DBELL IND VAL : %d\n"
+		"IND RING DBELL CACHED VAL : %d\n"
+		"RDY IND CACHE VAL : %d\n"
+		"RFIL IND : %d\n"
+		"NUM PKT INDICAT : %d\n"
+		"BUF REFIL : %d\n"
+		"NUM DROP NO SPC : %d\n"
+		"NUM DROP NO BUF : %d\n"
+		"IS SUSPND : %d\n",
+		uc_fw_stat->rx_ind_ring_size,
+		uc_fw_stat->rx_ind_ring_dbell_ind_val,
+		uc_fw_stat->rx_ind_ring_dbell_ind_cached_val,
+		uc_fw_stat->rx_ind_ring_rd_idx_cached_val,
+		uc_fw_stat->rx_refill_idx,
+		uc_fw_stat->rx_num_pkts_indicated,
+		uc_fw_stat->rx_buf_refilled,
+		uc_fw_stat->rx_num_ind_drop_no_space,
+		uc_fw_stat->rx_num_ind_drop_no_buf,
+		uc_fw_stat->rx_is_suspend);
+}
+
+/**
+ * wlan_ipa_print_ipa_wdi_stats - Print IPA WDI stats
+ * @ipa_ctx: IPA context
+ *
+ * Return: None
+ */
+static void wlan_ipa_print_ipa_wdi_stats(struct wlan_ipa_priv *ipa_ctx)
+{
+	qdf_ipa_hw_stats_wdi_info_data_t ipa_stat;
+
+	qdf_ipa_get_wdi_stats(&ipa_stat);
+
+	ipa_info("\n==== IPA WDI TX STATS ====\n"
+		"NUM PROCD : %d\n"
+		"CE DBELL : 0x%x\n"
+		"NUM DBELL FIRED : %d\n"
+		"COMP RNG FULL : %d\n"
+		"COMP RNG EMPT : %d\n"
+		"COMP RNG USE HGH : %d\n"
+		"COMP RNG USE LOW : %d\n"
+		"BAM FIFO FULL : %d\n"
+		"BAM FIFO EMPT : %d\n"
+		"BAM FIFO USE HGH : %d\n"
+		"BAM FIFO USE LOW : %d\n"
+		"NUM DBELL : %d\n"
+		"NUM UNEXP DBELL : %d\n"
+		"NUM BAM INT HDL : 0x%x\n"
+		"NUM QMB INT HDL : 0x%x\n",
+		ipa_stat.tx_ch_stats.num_pkts_processed,
+		ipa_stat.tx_ch_stats.copy_engine_doorbell_value,
+		ipa_stat.tx_ch_stats.num_db_fired,
+		ipa_stat.tx_ch_stats.tx_comp_ring_stats.ringFull,
+		ipa_stat.tx_ch_stats.tx_comp_ring_stats.ringEmpty,
+		ipa_stat.tx_ch_stats.tx_comp_ring_stats.ringUsageHigh,
+		ipa_stat.tx_ch_stats.tx_comp_ring_stats.ringUsageLow,
+		ipa_stat.tx_ch_stats.bam_stats.bamFifoFull,
+		ipa_stat.tx_ch_stats.bam_stats.bamFifoEmpty,
+		ipa_stat.tx_ch_stats.bam_stats.bamFifoUsageHigh,
+		ipa_stat.tx_ch_stats.bam_stats.bamFifoUsageLow,
+		ipa_stat.tx_ch_stats.num_db,
+		ipa_stat.tx_ch_stats.num_unexpected_db,
+		ipa_stat.tx_ch_stats.num_bam_int_handled,
+		ipa_stat.tx_ch_stats.num_qmb_int_handled);
+
+	ipa_info("\n==== IPA WDI RX STATS ====\n"
+		"MAX OST PKT : %d\n"
+		"NUM PKT PRCSD : %d\n"
+		"RNG RP : 0x%x\n"
+		"IND RNG FULL : %d\n"
+		"IND RNG EMPT : %d\n"
+		"IND RNG USE HGH : %d\n"
+		"IND RNG USE LOW : %d\n"
+		"BAM FIFO FULL : %d\n"
+		"BAM FIFO EMPT : %d\n"
+		"BAM FIFO USE HGH : %d\n"
+		"BAM FIFO USE LOW : %d\n"
+		"NUM DB : %d\n"
+		"NUM UNEXP DB : %d\n"
+		"NUM BAM INT HNDL : 0x%x\n",
+		ipa_stat.rx_ch_stats.max_outstanding_pkts,
+		ipa_stat.rx_ch_stats.num_pkts_processed,
+		ipa_stat.rx_ch_stats.rx_ring_rp_value,
+		ipa_stat.rx_ch_stats.rx_ind_ring_stats.ringFull,
+		ipa_stat.rx_ch_stats.rx_ind_ring_stats.ringEmpty,
+		ipa_stat.rx_ch_stats.rx_ind_ring_stats.ringUsageHigh,
+		ipa_stat.rx_ch_stats.rx_ind_ring_stats.ringUsageLow,
+		ipa_stat.rx_ch_stats.bam_stats.bamFifoFull,
+		ipa_stat.rx_ch_stats.bam_stats.bamFifoEmpty,
+		ipa_stat.rx_ch_stats.bam_stats.bamFifoUsageHigh,
+		ipa_stat.rx_ch_stats.bam_stats.bamFifoUsageLow,
+		ipa_stat.rx_ch_stats.num_db,
+		ipa_stat.rx_ch_stats.num_unexpected_db,
+		ipa_stat.rx_ch_stats.num_bam_int_handled);
+}
+
+void wlan_ipa_uc_info(struct wlan_ipa_priv *ipa_ctx)
+{
+	wlan_ipa_print_session_info(ipa_ctx);
+}
+
+void wlan_ipa_uc_stat(struct wlan_ipa_priv *ipa_ctx)
+{
+	/* IPA IPA TX/RX stats */
+	wlan_ipa_print_txrx_stats(ipa_ctx);
+	/* IPA WDI stats */
+	wlan_ipa_print_ipa_wdi_stats(ipa_ctx);
+	/* WLAN FW WDI stats */
+	wlan_ipa_uc_stat_request(ipa_ctx, WLAN_IPA_UC_STAT_REASON_DEBUG);
+}
+
+#ifdef FEATURE_METERING
+/**
+ * wlan_ipa_uc_sharing_stats_request() - Get IPA stats from IPA.
+ * @ipa_ctx: IPA context
+ * @reset_stats: reset stat countis after response
+ *
+ * Return: None
+ */
+static void wlan_ipa_uc_sharing_stats_request(struct wlan_ipa_priv *ipa_ctx,
+					      uint8_t reset_stats)
+{
+	qdf_mutex_acquire(&ipa_ctx->ipa_lock);
+	if (false == ipa_ctx->resource_loading) {
+		qdf_mutex_release(&ipa_ctx->ipa_lock);
+		cdp_ipa_uc_get_share_stats(ipa_ctx->dp_soc, ipa_ctx->dp_pdev,
+					   reset_stats);
+	} else {
+		qdf_mutex_release(&ipa_ctx->ipa_lock);
+	}
+}
+
+/**
+ * wlan_ipa_uc_set_quota() - Set quota limit bytes from IPA.
+ * @ipa_ctx: IPA context
+ * @set_quota: when 1, FW starts quota monitoring
+ * @quota_bytes: quota limit in bytes
+ *
+ * Return: None
+ */
+static void wlan_ipa_uc_set_quota(struct wlan_ipa_priv *ipa_ctx,
+				  uint8_t set_quota,
+				  uint64_t quota_bytes)
+{
+	ipa_info("SET_QUOTA: set_quota=%d, quota_bytes=%llu",
+		 set_quota, quota_bytes);
+
+	qdf_mutex_acquire(&ipa_ctx->ipa_lock);
+	if (false == ipa_ctx->resource_loading) {
+		qdf_mutex_release(&ipa_ctx->ipa_lock);
+	} else {
+		cdp_ipa_uc_set_quota(ipa_ctx->dp_soc, ipa_ctx->dp_pdev,
+				     quota_bytes);
+		qdf_mutex_release(&ipa_ctx->ipa_lock);
+	}
+}
+
+QDF_STATUS wlan_ipa_uc_op_metering(struct wlan_ipa_priv *ipa_ctx,
+				   struct op_msg_type *op_msg)
+{
+	struct op_msg_type *msg = op_msg;
+	struct ipa_uc_sharing_stats *uc_sharing_stats;
+	struct ipa_uc_quota_rsp *uc_quota_rsp;
+	struct ipa_uc_quota_ind *uc_quota_ind;
+	struct wlan_ipa_iface_context *iface_ctx;
+
+	if (msg->op_code == WLAN_IPA_UC_OPCODE_SHARING_STATS) {
+		/* fill-up ipa_uc_sharing_stats structure from FW */
+		uc_sharing_stats = (struct ipa_uc_sharing_stats *)
+			     ((uint8_t *)op_msg + sizeof(struct op_msg_type));
+
+		memcpy(&(ipa_ctx->ipa_sharing_stats), uc_sharing_stats,
+		       sizeof(struct ipa_uc_sharing_stats));
+
+		qdf_event_set(&ipa_ctx->ipa_uc_sharing_stats_comp);
+	} else if (msg->op_code == WLAN_IPA_UC_OPCODE_QUOTA_RSP) {
+		/* received set quota response */
+		uc_quota_rsp = (struct ipa_uc_quota_rsp *)
+			     ((uint8_t *)op_msg + sizeof(struct op_msg_type));
+
+		memcpy(&(ipa_ctx->ipa_quota_rsp), uc_quota_rsp,
+			   sizeof(struct ipa_uc_quota_rsp));
+
+		qdf_event_set(&ipa_ctx->ipa_uc_set_quota_comp);
+	} else if (msg->op_code == WLAN_IPA_UC_OPCODE_QUOTA_IND) {
+		/* hit quota limit */
+		uc_quota_ind = (struct ipa_uc_quota_ind *)
+			     ((uint8_t *)op_msg + sizeof(struct op_msg_type));
+
+		ipa_ctx->ipa_quota_ind.quota_bytes =
+					uc_quota_ind->quota_bytes;
+
+		/* send quota exceeded indication to IPA */
+		iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_STA_MODE);
+		if (iface_ctx)
+			qdf_ipa_broadcast_wdi_quota_reach_ind(
+						iface_ctx->dev->ifindex,
+						uc_quota_ind->quota_bytes);
+		else
+			ipa_err("Failed quota_reach_ind: NULL interface");
+	} else {
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * __wlan_ipa_wdi_meter_notifier_cb() - WLAN to IPA callback handler.
+ * IPA calls to get WLAN stats or set quota limit.
+ * @priv: pointer to private data registered with IPA (we register a
+ *	  pointer to the IPA context)
+ * @evt: the IPA event which triggered the callback
+ * @data: data associated with the event
+ *
+ * Return: None
+ */
+static void __wlan_ipa_wdi_meter_notifier_cb(qdf_ipa_wdi_meter_evt_type_t evt,
+					     void *data)
+{
+	struct wlan_ipa_priv *ipa_ctx = wlan_ipa_get_obj_context();
+	struct wlan_ipa_iface_context *iface_ctx;
+	qdf_ipa_get_wdi_sap_stats_t *wdi_sap_stats;
+	qdf_ipa_set_wifi_quota_t *ipa_set_quota;
+	QDF_STATUS status;
+
+	ipa_debug("event=%d", evt);
+
+	if (qdf_is_module_state_transitioning()) {
+		ipa_err("Module transition in progress");
+		return;
+	}
+
+	iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_STA_MODE);
+	if (!iface_ctx) {
+		ipa_err("IPA uC share stats failed - no iface");
+		return;
+	}
+
+	switch (evt) {
+	case IPA_GET_WDI_SAP_STATS:
+		/* fill-up ipa_get_wdi_sap_stats structure after getting
+		 * ipa_uc_fw_stats from FW
+		 */
+		wdi_sap_stats = data;
+
+		qdf_event_reset(&ipa_ctx->ipa_uc_sharing_stats_comp);
+		wlan_ipa_uc_sharing_stats_request(ipa_ctx,
+			QDF_IPA_GET_WDI_SAP_STATS_RESET_STATS(wdi_sap_stats));
+		status = qdf_wait_for_event_completion(
+			&ipa_ctx->ipa_uc_sharing_stats_comp,
+			IPA_UC_SHARING_STATES_WAIT_TIME);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			ipa_err("IPA uC share stats request timed out");
+			QDF_IPA_GET_WDI_SAP_STATS_STATS_VALID(wdi_sap_stats)
+				= 0;
+		} else {
+			QDF_IPA_GET_WDI_SAP_STATS_STATS_VALID(wdi_sap_stats)
+				= 1;
+
+			QDF_IPA_GET_WDI_SAP_STATS_IPV4_RX_PACKETS(wdi_sap_stats)
+				= ipa_ctx->ipa_sharing_stats.ipv4_rx_packets;
+			QDF_IPA_GET_WDI_SAP_STATS_IPV4_RX_BYTES(wdi_sap_stats)
+				= ipa_ctx->ipa_sharing_stats.ipv4_rx_bytes;
+			QDF_IPA_GET_WDI_SAP_STATS_IPV6_RX_PACKETS(wdi_sap_stats)
+				= ipa_ctx->ipa_sharing_stats.ipv6_rx_packets;
+			QDF_IPA_GET_WDI_SAP_STATS_IPV6_RX_BYTES(wdi_sap_stats)
+				= ipa_ctx->ipa_sharing_stats.ipv6_rx_bytes;
+			QDF_IPA_GET_WDI_SAP_STATS_IPV4_TX_PACKETS(wdi_sap_stats)
+				= ipa_ctx->ipa_sharing_stats.ipv4_tx_packets;
+			QDF_IPA_GET_WDI_SAP_STATS_IPV4_TX_BYTES(wdi_sap_stats)
+				= ipa_ctx->ipa_sharing_stats.ipv4_tx_bytes;
+			QDF_IPA_GET_WDI_SAP_STATS_IPV6_TX_PACKETS(wdi_sap_stats)
+				= ipa_ctx->ipa_sharing_stats.ipv6_tx_packets;
+			QDF_IPA_GET_WDI_SAP_STATS_IPV6_TX_BYTES(wdi_sap_stats)
+				= ipa_ctx->ipa_sharing_stats.ipv6_tx_bytes;
+		}
+		break;
+
+	case IPA_SET_WIFI_QUOTA:
+		/* get ipa_set_wifi_quota structure from IPA and pass to FW
+		 * through quota_exceeded field in ipa_uc_fw_stats
+		 */
+		ipa_set_quota = data;
+
+		qdf_event_reset(&ipa_ctx->ipa_uc_set_quota_comp);
+		wlan_ipa_uc_set_quota(ipa_ctx, ipa_set_quota->set_quota,
+				      ipa_set_quota->quota_bytes);
+
+		status = qdf_wait_for_event_completion(
+				&ipa_ctx->ipa_uc_set_quota_comp,
+				IPA_UC_SET_QUOTA_WAIT_TIME);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			ipa_err("IPA uC set quota request timed out");
+			QDF_IPA_SET_WIFI_QUOTA_SET_VALID(ipa_set_quota)	= 0;
+		} else {
+			QDF_IPA_SET_WIFI_QUOTA_BYTES(ipa_set_quota) =
+				((uint64_t)(ipa_ctx->ipa_quota_rsp.quota_hi)
+				  <<32)|ipa_ctx->ipa_quota_rsp.quota_lo;
+			QDF_IPA_SET_WIFI_QUOTA_SET_VALID(ipa_set_quota)	=
+				ipa_ctx->ipa_quota_rsp.success;
+		}
+		break;
+	}
+}
+
+/**
+ * wlan_ipa_wdi_meter_notifier_cb() - SSR wrapper for
+ * __wlan_ipa_wdi_meter_notifier_cb
+ * @priv: pointer to private data registered with IPA (we register a
+ *	  pointer to the IPA context)
+ * @evt: the IPA event which triggered the callback
+ * @data: data associated with the event
+ *
+ * Return: None
+ */
+void wlan_ipa_wdi_meter_notifier_cb(qdf_ipa_wdi_meter_evt_type_t evt,
+				    void *data)
+{
+	qdf_ssr_protect(__func__);
+	__wlan_ipa_wdi_meter_notifier_cb(evt, data);
+	qdf_ssr_unprotect(__func__);
+}
+
+#endif /* FEATURE_METERING */
diff --git a/components/ipa/dispatcher/inc/cfg_ipa.h b/components/ipa/dispatcher/inc/cfg_ipa.h
new file mode 100644
index 0000000..117da5a
--- /dev/null
+++ b/components/ipa/dispatcher/inc/cfg_ipa.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2012-2018 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 definitions of Data Path configuration.
+ */
+
+#ifndef _CFG_IPA_H_
+#define _CFG_IPA_H_
+
+#include "cfg_define.h"
+
+/* DP INI Declerations */
+/*
+ * IPA Offload configuration - Each bit enables a feature
+ * bit0 - IPA Enable
+ * bit1 - IPA Pre filter enable
+ * bit2 - IPv6 enable
+ * bit3 - IPA Resource Manager (RM) enable
+ * bit4 - IPA Clock scaling enable
+ */
+
+/*
+ * <ini>
+ * gIPAConfig - IPA configuration
+ * @Min: 0
+ * @Max: 0xFFFFFFFF
+ * @Default: 0
+ *
+ * This ini specifies the IPA configuration
+ *
+ * Related: N/A
+ *
+ * Supported Feature: IPA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_IPA_OFFLOAD_CONFIG \
+		CFG_INI_UINT("gIPAConfig", \
+		0, \
+		0xFFFFFFFF, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, "IPA offload configuration")
+
+/*
+ * <ini>
+ * GIPADescSize - IPA descriptor size
+ * @Min: 800
+ * @Max: 8000
+ * @Default: 800
+ *
+ * This ini specifies the IPA descriptor size
+ *
+ * Related: N/A
+ *
+ * Supported Feature: IPA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+ #define CFG_DP_IPA_DESC_SIZE \
+		CFG_INI_UINT("GIPADescSize", \
+		800, \
+		8000, \
+		800, \
+		CFG_VALUE_OR_DEFAULT, "IPA DESC SIZE")
+
+/*
+ * <ini>
+ * gIPAHighBandwidthMbps - IPA high bw threshold
+ * @Min: 200
+ * @Max: 1000
+ * @Default: 400
+ *
+ * This ini specifies the IPA high bw threshold
+ *
+ * Related: N/A
+ *
+ * Supported Feature: IPA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+ #define CFG_DP_IPA_HIGH_BANDWIDTH_MBPS \
+		CFG_INI_UINT("gIPAHighBandwidthMbps", \
+		200, \
+		1000, \
+		400, \
+		CFG_VALUE_OR_DEFAULT, "IPA high bw threshold")
+
+/*
+ * <ini>
+ * gIPAHighBandwidthMbps - IPA medium bw threshold
+ * @Min: 100
+ * @Max: 400
+ * @Default: 200
+ *
+ * This ini specifies the IPA medium bw threshold
+ *
+ * Related: N/A
+ *
+ * Supported Feature: IPA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+ #define CFG_DP_IPA_MEDIUM_BANDWIDTH_MBPS \
+		CFG_INI_UINT("gIPAMediumBandwidthMbps", \
+		100, \
+		400, \
+		200, \
+		CFG_VALUE_OR_DEFAULT, "IPA medium bw threshold")
+
+/*
+ * <ini>
+ * gIPAHighBandwidthMbps - IPA low bw threshold
+ * @Min: 0
+ * @Max: 100
+ * @Default: 100
+ *
+ * This ini specifies the IPA low bw threshold
+ *
+ * Related: N/A
+ *
+ * Supported Feature: IPA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+ #define CFG_DP_IPA_LOW_BANDWIDTH_MBPS \
+		CFG_INI_UINT("gIPALowBandwidthMbps", \
+		0, \
+		100, \
+		100, \
+		CFG_VALUE_OR_DEFAULT, "IPA low bw threshold")
+
+/*
+ * <ini>
+ * IpaUcTxBufCount - IPA tx buffer count
+ * @Min: 0
+ * @Max: 2048
+ * @Default: 512
+ *
+ * This ini specifies the IPA tx buffer count
+ *
+ * Related: N/A
+ *
+ * Supported Feature: IPA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+ #define CFG_DP_IPA_UC_TX_BUF_COUNT \
+		CFG_INI_UINT("IpaUcTxBufCount", \
+		0, \
+		2048, \
+		512, \
+		CFG_VALUE_OR_DEFAULT, "IPA tx buffer count")
+
+#define CFG_IPA \
+	CFG(CFG_DP_IPA_OFFLOAD_CONFIG) \
+	CFG(CFG_DP_IPA_DESC_SIZE) \
+	CFG(CFG_DP_IPA_HIGH_BANDWIDTH_MBPS) \
+	CFG(CFG_DP_IPA_MEDIUM_BANDWIDTH_MBPS) \
+	CFG(CFG_DP_IPA_LOW_BANDWIDTH_MBPS) \
+	CFG(CFG_DP_IPA_UC_TX_BUF_COUNT)
+
+#endif /* _CFG_IPA_H_ */
diff --git a/components/ipa/dispatcher/inc/wlan_ipa_obj_mgmt_api.h b/components/ipa/dispatcher/inc/wlan_ipa_obj_mgmt_api.h
new file mode 100644
index 0000000..b4e7e81
--- /dev/null
+++ b/components/ipa/dispatcher/inc/wlan_ipa_obj_mgmt_api.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018 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 wlan ipa called by north bound
+ */
+
+#ifndef _WLAN_IPA_OBJ_MGMT_H_
+#define _WLAN_IPA_OBJ_MGMT_H_
+
+#include "wlan_ipa_public_struct.h"
+#include "wlan_objmgr_pdev_obj.h"
+
+#ifdef IPA_OFFLOAD
+
+/**
+ * ipa_init() - IPA module initialization
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ipa_init(void);
+
+/**
+ * ipa_deinit() - IPA module deinitialization
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ipa_deinit(void);
+#else
+
+static inline QDF_STATUS ipa_init(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS ipa_deinit(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* IPA_OFFLOAD */
+
+#endif /* _WLAN_IPA_OBJ_MGMT_H_ */
diff --git a/components/ipa/dispatcher/inc/wlan_ipa_public_struct.h b/components/ipa/dispatcher/inc/wlan_ipa_public_struct.h
new file mode 100644
index 0000000..ca3a01f
--- /dev/null
+++ b/components/ipa/dispatcher/inc/wlan_ipa_public_struct.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: contains ipa public structure definitions
+ */
+
+#ifndef _WLAN_IPA_PUBLIC_STRUCT_H_
+#define _WLAN_IPA_PUBLIC_STRUCT_H_
+
+#include <wlan_cmn.h>
+#include <qdf_status.h>
+#include <wlan_objmgr_psoc_obj.h>
+
+/**
+ * struct wlan_ipa_config
+ * @ipa_config: IPA config
+ * @desc_size: IPA descriptor size
+ * @txbuf_count: TX buffer count
+ * @bus_bw_high: Bus bandwidth high threshold
+ * @bus_bw_medium: Bus bandwidth medium threshold
+ * @bus_bw_low: Bus bandwidth low threshold
+ * @ipa_bw_high: IPA bandwidth high threshold
+ * @ipa_bw_medium: IPA bandwidth medium threshold
+ * @ipa_bw_low: IPA bandwidth low threshold
+ */
+struct wlan_ipa_config {
+	uint32_t ipa_config;
+	uint32_t desc_size;
+	uint32_t txbuf_count;
+	uint32_t bus_bw_high;
+	uint32_t bus_bw_medium;
+	uint32_t bus_bw_low;
+	uint32_t ipa_bw_high;
+	uint32_t ipa_bw_medium;
+	uint32_t ipa_bw_low;
+};
+
+/**
+ * enum wlan_ipa_wlan_event - WLAN IPA events
+ * @WLAN_IPA_CLIENT_CONNECT: Client Connects
+ * @WLAN_IPA_CLIENT_DISCONNECT: Client Disconnects
+ * @WLAN_IPA_AP_CONNECT: SoftAP is started
+ * @WLAN_IPA_AP_DISCONNECT: SoftAP is stopped
+ * @WLAN_IPA_STA_CONNECT: STA associates to AP
+ * @WLAN_IPA_STA_DISCONNECT: STA dissociates from AP
+ * @WLAN_IPA_CLIENT_CONNECT_EX: Peer associates/re-associates to softap
+ * @WLAN_IPA_WLAN_EVENT_MAX: Max value for the enum
+ */
+enum wlan_ipa_wlan_event {
+	WLAN_IPA_CLIENT_CONNECT,
+	WLAN_IPA_CLIENT_DISCONNECT,
+	WLAN_IPA_AP_CONNECT,
+	WLAN_IPA_AP_DISCONNECT,
+	WLAN_IPA_STA_CONNECT,
+	WLAN_IPA_STA_DISCONNECT,
+	WLAN_IPA_CLIENT_CONNECT_EX,
+	WLAN_IPA_WLAN_EVENT_MAX
+};
+
+/**
+ * struct ipa_uc_offload_control_params - ipa offload control params
+ * @offload_type: ipa offload type
+ * @vdev_id: vdev id
+ * @enable: ipa offload enable/disable
+ */
+struct ipa_uc_offload_control_params {
+	uint32_t offload_type;
+	uint32_t vdev_id;
+	uint32_t enable;
+};
+
+/* fp to send IPA UC offload cmd */
+typedef QDF_STATUS (*ipa_uc_offload_control_req)(struct wlan_objmgr_psoc *psoc,
+				struct ipa_uc_offload_control_params *req);
+#endif /* end  of _WLAN_IPA_PUBLIC_STRUCT_H_ */
diff --git a/components/ipa/dispatcher/inc/wlan_ipa_tgt_api.h b/components/ipa/dispatcher/inc/wlan_ipa_tgt_api.h
new file mode 100644
index 0000000..417b387
--- /dev/null
+++ b/components/ipa/dispatcher/inc/wlan_ipa_tgt_api.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018 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 wlan ipa to interact with target/WMI
+ */
+
+#ifndef _WLAN_IPA_TGT_API_H_
+#define _WLAN_IPA_TGT_API_H_
+
+#include "wlan_ipa_public_struct.h"
+
+/**
+ * tgt_ipa_uc_offload_enable_disable() - send ipa offload control to target if
+ * @pdev: objmgr pdev object
+ * @req: ipa offload control request
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_ipa_uc_offload_enable_disable(struct wlan_objmgr_pdev *pdev,
+				struct ipa_uc_offload_control_params *req);
+#endif /* _WLAN_IPA_TGT_API_H_ */
diff --git a/components/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h b/components/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h
new file mode 100644
index 0000000..6a2de01
--- /dev/null
+++ b/components/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h
@@ -0,0 +1,541 @@
+/*
+ * Copyright (c) 2018 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 wlan ipa called by north bound
+ */
+
+#ifndef _WLAN_IPA_UCFG_API_H_
+#define _WLAN_IPA_UCFG_API_H_
+
+#include "wlan_ipa_public_struct.h"
+#include "wlan_ipa_obj_mgmt_api.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "qdf_types.h"
+#include "wlan_ipa_main.h"
+
+#ifdef IPA_OFFLOAD
+
+/**
+ * ucfg_ipa_is_present() - get IPA hw status
+ *
+ * ipa_uc_reg_rdyCB is not directly designed to check
+ * ipa hw status. This is an undocumented function which
+ * has confirmed with IPA team.
+ *
+ * Return: true - ipa hw present
+ *         false - ipa hw not present
+ */
+bool ucfg_ipa_is_present(void);
+
+/**
+ * ucfg_ipa_is_enabled() - get IPA enable status
+ *
+ * Return: true - ipa is enabled
+ *         false - ipa is not enabled
+ */
+bool ucfg_ipa_is_enabled(void);
+
+/**
+ * ucfg_ipa_uc_is_enabled() - get IPA uC enable status
+ *
+ * Return: true - ipa uC is enabled
+ *         false - ipa uC is not enabled
+ */
+bool ucfg_ipa_uc_is_enabled(void);
+
+/**
+ * ucfg_ipa_set_dp_handle() - register DP handle
+ * @psoc: psoc handle
+ * @dp_soc: data path soc handle
+ *
+ * Return: None
+ */
+void ucfg_ipa_set_dp_handle(struct wlan_objmgr_psoc *psoc,
+			       void *dp_soc);
+
+/**
+ * ucfg_ipa_set_txrx_handle() - register pdev txrx handler
+ * @psoc: psoc handle
+ * @psoc: psoc obj
+ * @txrx_handle: data path pdev txrx handle
+ *
+ * Return: None
+ */
+void ucfg_ipa_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+			      void *txrx_handle);
+
+/**
+ * ucfg_ipa_set_perf_level() - Set IPA perf level
+ * @pdev: pdev obj
+ * @tx_packets: Number of packets transmitted in the last sample period
+ * @rx_packets: Number of packets received in the last sample period
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ipa_set_perf_level(struct wlan_objmgr_pdev *pdev,
+				   uint64_t tx_packets, uint64_t rx_packets);
+
+/**
+ * ucfg_ipa_uc_info() - Print IPA uC resource and session information
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ucfg_ipa_uc_info(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_uc_stat() - Print IPA uC stats
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ucfg_ipa_uc_stat(struct wlan_objmgr_pdev *pdev);
+
+
+/**
+ * ucfg_ipa_uc_rt_debug_host_dump() - IPA rt debug host dump
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ucfg_ipa_uc_rt_debug_host_dump(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_dump_info() - Dump IPA context information
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ucfg_ipa_dump_info(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_uc_stat_request() - Get IPA stats from IPA.
+ * @pdev: pdev obj
+ * @reason: STAT REQ Reason
+ *
+ * Return: None
+ */
+void ucfg_ipa_uc_stat_request(struct wlan_objmgr_pdev *pdev,
+			      uint8_t reason);
+
+/**
+ * ucfg_ipa_uc_stat_query() - Query the IPA stats
+ * @pdev: pdev obj
+ * @ipa_tx_diff: tx packet count diff from previous tx packet count
+ * @ipa_rx_diff: rx packet count diff from previous rx packet count
+ *
+ * Return: None
+ */
+void ucfg_ipa_uc_stat_query(struct wlan_objmgr_pdev *pdev,
+			    uint32_t *ipa_tx_diff, uint32_t *ipa_rx_diff);
+
+/**
+ * ucfg_ipa_reg_sap_xmit_cb() - Register upper layer SAP cb to transmit
+ * @pdev: pdev obj
+ * @cb: callback
+ *
+ * Return: None
+ */
+void ucfg_ipa_reg_sap_xmit_cb(struct wlan_objmgr_pdev *pdev, void *cb);
+
+/**
+ * ucfg_ipa_reg_send_to_nw_cb() - Register cb to send IPA Rx packet to network
+ * @pdev: pdev obj
+ * @cb: callback
+ *
+ * Return: None
+ */
+void ucfg_ipa_reg_send_to_nw_cb(struct wlan_objmgr_pdev *pdev, void *cb);
+
+/**
+ * ucfg_ipa_set_mcc_mode() - Set MCC mode
+ * @pdev: pdev obj
+ * @mcc_mode: 0=MCC/1=SCC
+ *
+ * Return: void
+ */
+void ucfg_ipa_set_mcc_mode(struct wlan_objmgr_pdev *pdev, bool mcc_mode);
+
+/**
+ * ucfg_ipa_set_dfs_cac_tx() - Set DFS cac tx block
+ * @pdev: pdev obj
+ * @tx_block: dfs cac tx block
+ *
+ * Return: void
+ */
+void ucfg_ipa_set_dfs_cac_tx(struct wlan_objmgr_pdev *pdev, bool tx_block);
+
+/**
+ * ucfg_ipa_set_ap_ibss_fwd() - Set AP intra bss forward
+ * @pdev: pdev obj
+ * @intra_bss: enable or disable ap intra bss forward
+ *
+ * Return: void
+ */
+void ucfg_ipa_set_ap_ibss_fwd(struct wlan_objmgr_pdev *pdev, bool intra_bss);
+
+/**
+ * ucfg_ipa_uc_force_pipe_shutdown() - Force shutdown IPA pipe
+ * @pdev: pdev obj
+ *
+ * Return: void
+ */
+void ucfg_ipa_uc_force_pipe_shutdown(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_flush() - flush IPA exception path SKB's
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ucfg_ipa_flush(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_suspend() - Suspend IPA
+ * @pdev: pdev obj
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS ucfg_ipa_suspend(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_resume() - Resume IPA
+ * @pdev: pdev obj
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS ucfg_ipa_resume(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_uc_ol_init() - Initialize IPA uC offload
+ * @pdev: pdev obj
+ * @osdev: OS dev
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS ucfg_ipa_uc_ol_init(struct wlan_objmgr_pdev *pdev,
+			       qdf_device_t osdev);
+
+/**
+ * ucfg_ipa_uc_ol_deinit() - Deinitialize IPA uC offload
+ * @pdev: pdev obj
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS ucfg_ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_send_mcc_scc_msg() - Send IPA WLAN_SWITCH_TO_MCC/SCC message
+ * @mcc_mode: 0=MCC/1=SCC
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS ucfg_ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev,
+				     bool mcc_mode);
+
+/**
+ * ucfg_ipa_wlan_evt() - IPA event handler
+ * @pdev: pdev obj
+ * @net_dev: Interface net device
+ * @device_mode: Net interface device mode
+ * @sta_id: station id for the event
+ * @session_id: session id for the event
+ * @type: event enum of type ipa_wlan_event
+ * @mac_address: MAC address associated with the event
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_ipa_wlan_evt(struct wlan_objmgr_pdev *pdev,
+			     qdf_netdev_t net_dev, uint8_t device_mode,
+			     uint8_t sta_id, uint8_t session_id,
+			     enum wlan_ipa_wlan_event ipa_event_type,
+			     uint8_t *mac_addr);
+
+/**
+ * ucfg_ipa_uc_smmu_map() - Map / Unmap DMA buffer to IPA UC
+ * @map: Map / unmap operation
+ * @num_buf: Number of buffers in array
+ * @buf_arr: Buffer array of DMA mem mapping info
+ *
+ * Return: Status of map operation
+ */
+int ucfg_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr);
+
+/**
+ * ucfg_ipa_is_fw_wdi_activated - Is FW WDI activated?
+ * @pdev: pdev obj
+ *
+ * Return: true if FW WDI activated, false otherwise
+ */
+bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_uc_disconnect_ap() - send ap disconnect event
+ * @pdev: pdev obj
+ * @net_dev: Interface net device
+ *
+ * Send disconnect ap event to IPA driver during SSR
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
+				     qdf_netdev_t net_dev);
+
+/**
+ * ucfg_ipa_cleanup_dev_iface() - Clean up net dev IPA interface
+ * @pdev: pdev obj
+ * @net_dev: Interface net device
+ *
+ *
+ * Return: None
+ */
+void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
+				qdf_netdev_t net_dev);
+
+/**
+ * ucfg_ipa_uc_ssr_cleanup() - Handle IPA cleanup for SSR
+ * @pdev: pdev obj
+ *
+ * From hostside do cleanup such as deregister IPA interafces
+ * and send disconnect events so that it will be sync after SSR
+ *
+ * Return: None
+ */
+void ucfg_ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_fw_rejuvenate_send_msg() - Send msg to IPA driver in FW rejuvenate
+ * @pdev: pdev obj
+ *
+ * Return: None
+ */
+void ucfg_ipa_fw_rejuvenate_send_msg(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ipa_component_config_update() - update IPA component config
+ * @psoc: pointer to psoc object
+ *
+ * Return: None
+ */
+void ucfg_ipa_component_config_update(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_get_ipa_tx_buf_count() - get IPA tx buffer count
+ *
+ * Return: IPA tx buffer count
+ */
+uint32_t ucfg_ipa_get_tx_buf_count(void);
+
+#else
+
+static inline bool ucfg_ipa_is_present(void)
+{
+	return false;
+}
+
+static inline void ucfg_ipa_update_config(struct wlan_ipa_config *config)
+{
+}
+
+static inline bool ucfg_ipa_is_enabled(void)
+{
+	return false;
+}
+
+static inline bool ucfg_ipa_uc_is_enabled(void)
+{
+	return false;
+}
+
+static inline
+QDF_STATUS ucfg_ipa_set_dp_handle(struct wlan_objmgr_psoc *psoc,
+				     void *dp_soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_ipa_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				    void *txrx_handle)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_ipa_set_perf_level(struct wlan_objmgr_pdev *pdev,
+				   uint64_t tx_packets, uint64_t rx_packets)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+void ucfg_ipa_uc_info(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+static inline
+void ucfg_ipa_uc_stat(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+static inline
+void ucfg_ipa_uc_rt_debug_host_dump(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+static inline
+void ucfg_ipa_dump_info(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+static inline
+void ucfg_ipa_uc_stat_request(struct wlan_objmgr_pdev *pdev,
+			      uint8_t reason)
+{
+}
+
+static inline
+void ucfg_ipa_uc_stat_query(struct wlan_objmgr_pdev *pdev,
+			    uint32_t *ipa_tx_diff, uint32_t *ipa_rx_diff)
+{
+}
+
+static inline
+void ucfg_ipa_reg_sap_xmit_cb(struct wlan_objmgr_pdev *pdev, void *cb)
+{
+}
+
+static inline
+void ucfg_ipa_reg_send_to_nw_cb(struct wlan_objmgr_pdev *pdev, void *cb)
+{
+}
+
+static inline
+void ucfg_ipa_set_mcc_mode(struct wlan_objmgr_pdev *pdev, bool mcc_mode)
+{
+}
+
+static inline
+void ucfg_ipa_set_dfs_cac_tx(struct wlan_objmgr_pdev *pdev, bool tx_block)
+{
+}
+
+static inline
+void ucfg_ipa_set_ap_ibss_fwd(struct wlan_objmgr_pdev *pdev, bool intra_bss)
+{
+}
+
+static inline
+void ucfg_ipa_uc_force_pipe_shutdown(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+static inline
+void ucfg_ipa_flush(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+static inline
+QDF_STATUS ucfg_ipa_suspend(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_ipa_resume(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_ipa_uc_ol_init(struct wlan_objmgr_pdev *pdev,
+			       qdf_device_t osdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev,
+				     bool mcc_mode)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_ipa_wlan_evt(struct wlan_objmgr_pdev *pdev,
+			     qdf_netdev_t net_dev, uint8_t device_mode,
+			     uint8_t sta_id, uint8_t session_id,
+			     enum wlan_ipa_wlan_event ipa_event_type,
+			     uint8_t *mac_addr)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+int ucfg_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
+{
+	return 0;
+}
+
+static inline
+bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev)
+{
+	return false;
+}
+
+static inline
+QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
+				     qdf_netdev_t net_dev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
+				qdf_netdev_t net_dev)
+{
+}
+
+static inline
+void ucfg_ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+static inline
+void ucfg_ipa_fw_rejuvenate_send_msg(struct wlan_objmgr_pdev *pdev)
+{
+}
+
+static inline
+void ucfg_ipa_component_config_update(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+uint32_t ucfg_ipa_get_tx_buf_count(void)
+{
+	return 0;
+}
+#endif /* IPA_OFFLOAD */
+#endif /* _WLAN_IPA_UCFG_API_H_ */
diff --git a/components/ipa/dispatcher/src/wlan_ipa_obj_mgmt_api.c b/components/ipa/dispatcher/src/wlan_ipa_obj_mgmt_api.c
new file mode 100644
index 0000000..aab026c
--- /dev/null
+++ b/components/ipa/dispatcher/src/wlan_ipa_obj_mgmt_api.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2018 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 wlan ipa called by north bound HDD/OSIF
+ */
+
+#include "wlan_ipa_obj_mgmt_api.h"
+#include "wlan_ipa_main.h"
+#include "wlan_objmgr_global_obj.h"
+#include "target_if_ipa.h"
+
+/**
+ * ipa_pdev_obj_destroy_notification() - IPA pdev object destroy notification
+ * @pdev: pdev handle
+ * @arg_list: arguments list
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+ipa_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
+				  void *arg_list)
+{
+	QDF_STATUS status;
+	struct wlan_ipa_priv *ipa_obj;
+
+	ipa_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
+							WLAN_UMAC_COMP_IPA);
+	if (!ipa_obj) {
+		ipa_err("Failed to get ipa pdev object");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = wlan_objmgr_pdev_component_obj_detach(pdev,
+						       WLAN_UMAC_COMP_IPA,
+						       ipa_obj);
+	if (QDF_IS_STATUS_ERROR(status))
+		ipa_err("Failed to detatch ipa pdev object");
+
+	ipa_obj_cleanup(ipa_obj);
+	qdf_mem_free(ipa_obj);
+
+	return status;
+}
+
+/**
+ * ipa_pdev_obj_create_notification() - IPA pdev object creation notification
+ * @pdev: pdev handle
+ * @arg_list: arguments list
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+ipa_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
+				 void *arg_list)
+{
+	QDF_STATUS status;
+	struct wlan_ipa_priv *ipa_obj;
+
+	ipa_debug("ipa pdev created");
+
+	if (!ipa_config_is_enabled()) {
+		ipa_info("IPA is disabled");
+		wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_IPA,
+				ipa_pdev_obj_destroy_notification, NULL);
+		return QDF_STATUS_COMP_DISABLED;
+	}
+
+	ipa_obj = qdf_mem_malloc(sizeof(*ipa_obj));
+	if (!ipa_obj) {
+		ipa_err("Failed to allocate memory for ipa pdev object");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	status = wlan_objmgr_pdev_component_obj_attach(pdev,
+						       WLAN_UMAC_COMP_IPA,
+						       (void *)ipa_obj,
+						       QDF_STATUS_SUCCESS);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ipa_err("Failed to attach pdev ipa component");
+		qdf_mem_free(ipa_obj);
+		return status;
+	}
+
+	ipa_obj->pdev = pdev;
+
+	status = ipa_obj_setup(ipa_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ipa_err("Failed to setup ipa component");
+		wlan_objmgr_pdev_component_obj_detach(pdev,
+						      WLAN_UMAC_COMP_IPA,
+						      ipa_obj);
+		qdf_mem_free(ipa_obj);
+		return status;
+	}
+
+	target_if_ipa_register_tx_ops(&ipa_obj->ipa_tx_op);
+
+	ipa_debug("ipa pdev attached");
+
+	return status;
+}
+
+QDF_STATUS ipa_init(void)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	ipa_info("ipa module dispatcher init");
+
+	if (!ipa_check_hw_present()) {
+		ipa_info("ipa hw not present");
+		return status;
+	}
+
+	status = ipa_config_mem_alloc();
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	status = wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_IPA,
+		ipa_pdev_obj_create_notification, NULL);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ipa_err("Failed to register pdev create handler for ipa");
+
+		return status;
+	}
+
+	status = wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_IPA,
+		ipa_pdev_obj_destroy_notification, NULL);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ipa_err("Failed to register pdev destroy handler for ipa");
+		goto fail_delete_pdev;
+	}
+
+	return status;
+
+fail_delete_pdev:
+	wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_IPA,
+		ipa_pdev_obj_create_notification, NULL);
+
+	return status;
+}
+
+QDF_STATUS ipa_deinit(void)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	ipa_info("ipa module dispatcher deinit");
+
+	if (!ipa_is_hw_support()) {
+		ipa_info("ipa hw is not present");
+		return status;
+	}
+
+	if (!ipa_config_is_enabled()) {
+		ipa_info("ipa is disabled");
+		ipa_config_mem_free();
+		return status;
+	}
+
+	status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_IPA,
+				ipa_pdev_obj_destroy_notification, NULL);
+	if (QDF_IS_STATUS_ERROR(status))
+		ipa_err("Failed to unregister pdev destroy handler");
+
+	status = wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_IPA,
+				ipa_pdev_obj_create_notification, NULL);
+	if (QDF_IS_STATUS_ERROR(status))
+		ipa_err("Failed to unregister pdev create handler");
+
+	ipa_config_mem_free();
+
+	return status;
+}
diff --git a/components/ipa/dispatcher/src/wlan_ipa_tgt_api.c b/components/ipa/dispatcher/src/wlan_ipa_tgt_api.c
new file mode 100644
index 0000000..c9c1e97
--- /dev/null
+++ b/components/ipa/dispatcher/src/wlan_ipa_tgt_api.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018 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 ipa to interact with target/WMI
+ */
+
+#include "wlan_ipa_tgt_api.h"
+#include "wlan_ipa_main.h"
+#include "wlan_ipa_public_struct.h"
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+
+QDF_STATUS tgt_ipa_uc_offload_enable_disable(struct wlan_objmgr_pdev *pdev,
+				struct ipa_uc_offload_control_params *req)
+{
+	struct wlan_ipa_priv *ipa_obj;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	IPA_ENTER();
+
+	ipa_obj = ipa_pdev_get_priv_obj(pdev);
+	psoc = wlan_pdev_get_psoc(pdev);
+
+	if (ipa_obj->ipa_tx_op)
+		status = ipa_obj->ipa_tx_op(psoc, req);
+
+	IPA_EXIT();
+	return status;
+}
diff --git a/components/ipa/dispatcher/src/wlan_ipa_ucfg_api.c b/components/ipa/dispatcher/src/wlan_ipa_ucfg_api.c
new file mode 100644
index 0000000..fd1802b
--- /dev/null
+++ b/components/ipa/dispatcher/src/wlan_ipa_ucfg_api.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2018 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 wlan ipa called by north bound HDD/OSIF
+ */
+
+#include "wlan_ipa_ucfg_api.h"
+#include "wlan_ipa_main.h"
+#include "cfg_ucfg_api.h"
+
+
+bool ucfg_ipa_is_present(void)
+{
+	return ipa_is_hw_support();
+}
+
+bool ucfg_ipa_is_enabled(void)
+{
+	return ipa_config_is_enabled();
+}
+
+bool ucfg_ipa_uc_is_enabled(void)
+{
+	return ipa_config_is_uc_enabled();
+}
+
+void ucfg_ipa_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				    void *txrx_handle)
+{
+	return ipa_set_txrx_handle(psoc, txrx_handle);
+}
+
+void ucfg_ipa_set_dp_handle(struct wlan_objmgr_psoc *psoc,
+				     void *dp_soc)
+{
+	return ipa_set_dp_handle(psoc, dp_soc);
+}
+
+QDF_STATUS ucfg_ipa_set_perf_level(struct wlan_objmgr_pdev *pdev,
+				   uint64_t tx_packets, uint64_t rx_packets)
+{
+	return ipa_rm_set_perf_level(pdev, tx_packets, rx_packets);
+}
+
+void ucfg_ipa_uc_info(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_uc_info(pdev);
+}
+
+void ucfg_ipa_uc_stat(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_uc_stat(pdev);
+}
+
+void ucfg_ipa_uc_rt_debug_host_dump(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_uc_rt_debug_host_dump(pdev);
+}
+
+void ucfg_ipa_dump_info(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_dump_info(pdev);
+}
+
+void ucfg_ipa_uc_stat_request(struct wlan_objmgr_pdev *pdev,
+			      uint8_t reason)
+{
+	return ipa_uc_stat_request(pdev, reason);
+}
+
+void ucfg_ipa_uc_stat_query(struct wlan_objmgr_pdev *pdev,
+			    uint32_t *ipa_tx_diff, uint32_t *ipa_rx_diff)
+{
+	return ipa_uc_stat_query(pdev, ipa_tx_diff, ipa_rx_diff);
+}
+
+void ucfg_ipa_reg_sap_xmit_cb(struct wlan_objmgr_pdev *pdev, void *cb)
+{
+	return ipa_reg_sap_xmit_cb(pdev, cb);
+}
+
+void ucfg_ipa_reg_send_to_nw_cb(struct wlan_objmgr_pdev *pdev, void *cb)
+{
+	return ipa_reg_send_to_nw_cb(pdev, cb);
+
+}
+
+void ucfg_ipa_set_mcc_mode(struct wlan_objmgr_pdev *pdev, bool mcc_mode)
+{
+	return ipa_set_mcc_mode(pdev, mcc_mode);
+}
+
+void ucfg_ipa_set_dfs_cac_tx(struct wlan_objmgr_pdev *pdev, bool tx_block)
+{
+	return ipa_set_dfs_cac_tx(pdev, tx_block);
+}
+
+void ucfg_ipa_set_ap_ibss_fwd(struct wlan_objmgr_pdev *pdev, bool intra_bss)
+{
+	return ipa_set_ap_ibss_fwd(pdev, intra_bss);
+}
+
+void ucfg_ipa_uc_force_pipe_shutdown(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_uc_force_pipe_shutdown(pdev);
+}
+
+void ucfg_ipa_flush(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_flush(pdev);
+}
+
+QDF_STATUS ucfg_ipa_suspend(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_suspend(pdev);
+}
+
+QDF_STATUS ucfg_ipa_resume(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_resume(pdev);
+}
+
+QDF_STATUS ucfg_ipa_uc_ol_init(struct wlan_objmgr_pdev *pdev,
+			       qdf_device_t osdev)
+{
+	return ipa_uc_ol_init(pdev, osdev);
+}
+
+QDF_STATUS ucfg_ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_uc_ol_deinit(pdev);
+}
+
+QDF_STATUS ucfg_ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev,
+				     bool mcc_mode)
+{
+	return ipa_send_mcc_scc_msg(pdev, mcc_mode);
+}
+
+QDF_STATUS ucfg_ipa_wlan_evt(struct wlan_objmgr_pdev *pdev,
+			     qdf_netdev_t net_dev, uint8_t device_mode,
+			     uint8_t sta_id, uint8_t session_id,
+			     enum wlan_ipa_wlan_event ipa_event_type,
+			     uint8_t *mac_addr)
+{
+	return ipa_wlan_evt(pdev, net_dev, device_mode, sta_id, session_id,
+			    ipa_event_type, mac_addr);
+}
+
+int ucfg_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
+{
+	return ipa_uc_smmu_map(map, num_buf, buf_arr);
+}
+
+bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_is_fw_wdi_activated(pdev);
+}
+
+QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
+				     qdf_netdev_t net_dev)
+{
+	return ipa_uc_disconnect_ap(pdev, net_dev);
+}
+
+void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
+				qdf_netdev_t net_dev)
+{
+	return ipa_cleanup_dev_iface(pdev, net_dev);
+}
+
+void ucfg_ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_uc_ssr_cleanup(pdev);
+}
+
+void ucfg_ipa_fw_rejuvenate_send_msg(struct wlan_objmgr_pdev *pdev)
+{
+	return ipa_fw_rejuvenate_send_msg(pdev);
+}
+
+void ucfg_ipa_component_config_update(struct wlan_objmgr_psoc *psoc)
+{
+	ipa_component_config_update(psoc);
+}
+
+uint32_t ucfg_ipa_get_tx_buf_count(void)
+{
+	return ipa_get_tx_buf_count();
+}
diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h
new file mode 100644
index 0000000..c402d94
--- /dev/null
+++ b/components/mlme/core/inc/wlan_mlme_main.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2018 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 internal API related to the mlme component
+ */
+
+#ifndef _WLAN_MLME_MAIN_H_
+#define _WLAN_MLME_MAIN_H_
+
+#include <wlan_mlme_public_struct.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_cmn.h>
+
+#define mlme_fatal(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_MLME, params)
+#define mlme_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_MLME, params)
+#define mlme_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_MLME, params)
+#define mlme_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_MLME, params)
+#define mlme_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_MLME, params)
+
+/**
+ * struct wlan_mlme_psoc_obj -MLME psoc priv object
+ * @cfg:     cfg items
+ */
+struct wlan_mlme_psoc_obj {
+	struct wlan_mlme_cfg cfg;
+};
+
+/**
+ * mlme_psoc_object_created_notification(): mlme psoc create handler
+ * @psoc: psoc which is going to created by objmgr
+ * @arg: argument for vdev create handler
+ *
+ * Register this api with objmgr to detect psoc is created
+ *
+ * Return: QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS
+mlme_psoc_object_created_notification(struct wlan_objmgr_psoc *psoc,
+				      void *arg);
+
+/**
+ * mlme_psoc_object_destroyed_notification(): mlme psoc delete handler
+ * @psoc: psoc which is going to delete by objmgr
+ * @arg: argument for vdev delete handler
+ *
+ * Register this api with objmgr to detect psoc is deleted
+ *
+ * Return: QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS
+mlme_psoc_object_destroyed_notification(struct wlan_objmgr_psoc *psoc,
+					void *arg);
+
+/**
+ * mlme_cfg_on_psoc_enable() - Populate MLME structure from CFG and INI
+ * @psoc: pointer to the psoc object
+ *
+ * Populate the MLME CFG structure from CFG and INI values using CFG APIs
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * mlme_get_psoc_obj() - Get MLME object from psoc
+ * @psoc: pointer to the psoc object
+ *
+ * Get the MLME object pointer from the psoc
+ *
+ * Return: pointer to MLME object
+ */
+struct wlan_mlme_psoc_obj *mlme_get_psoc_obj(struct wlan_objmgr_psoc *psoc);
+
+#endif
diff --git a/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h b/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h
new file mode 100644
index 0000000..9e87327
--- /dev/null
+++ b/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2018 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 VDEV Manager interface APIs exposed by the mlme component
+ */
+
+#ifndef _WLAN_MLME_VDEV_MGR_INT_API_H_
+#define _WLAN_MLME_VDEV_MGR_INT_API_H_
+
+#ifdef CONFIG_VDEV_SM
+#include <wlan_objmgr_vdev_obj.h>
+#include "include/wlan_vdev_mlme.h"
+
+/**
+ * enum vdev_assoc_type - VDEV associate/reassociate type
+ * @VDEV_ASSOC: associate
+ * @VDEV_REASSOC: reassociate
+ * @VDEV_FT_REASSOC: fast reassociate
+ */
+enum vdev_assoc_type {
+	VDEV_ASSOC,
+	VDEV_REASSOC,
+	VDEV_FT_REASSOC
+};
+
+/**
+ * struct mlme_legacy_priv - VDEV MLME legacy priv object
+ * @chan_switch_in_progress: flag to indicate that channel switch is in progress
+ * @hidden_ssid_restart_in_progress: flag to indicate hidden ssid restart is
+ *                                   in progress
+ * @vdev_start_failed: flag to indicate that vdev start failed.
+ * @connection_fail: flag to indicate connection failed
+ * @assoc_type: vdev associate/reassociate type
+ */
+struct mlme_legacy_priv {
+	bool chan_switch_in_progress;
+	bool hidden_ssid_restart_in_progress;
+	bool vdev_start_failed;
+	bool connection_fail;
+	enum vdev_assoc_type assoc_type;
+};
+
+/**
+ * mlme_register_vdev_mgr_ops() - Register vdev mgr ops
+ * @vdev_mlme: vdev mlme object
+ *
+ * This function is called to register vdev manager operations
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_register_vdev_mgr_ops(void *mlme);
+/**
+ * mlme_unregister_vdev_mgr_ops() - Unregister vdev mgr ops
+ * @vdev_mlme: vdev mlme object
+ *
+ * This function is called to unregister vdev manager operations
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_unregister_vdev_mgr_ops(struct vdev_mlme_obj *vdev_mlme);
+
+/**
+ * mlme_set_chan_switch_in_progress() - set mlme priv restart in progress
+ * @vdev: vdev pointer
+ * @val: value to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_set_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev,
+					       bool val);
+
+/**
+ * mlme_is_chan_switch_in_progress() - get mlme priv restart in progress
+ * @vdev: vdev pointer
+ *
+ * Return: value of mlme priv restart in progress
+ */
+bool mlme_is_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * ap_mlme_set_hidden_ssid_restart_in_progress() - set mlme priv hidden ssid
+ * restart in progress
+ * @vdev: vdev pointer
+ * @val: value to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+ap_mlme_set_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev,
+					    bool val);
+
+/**
+ * ap_mlme_is_hidden_ssid_restart_in_progress() - get mlme priv hidden ssid
+ * restart in progress
+ * @vdev: vdev pointer
+ *
+ * Return: value of mlme priv hidden ssid restart in progress
+ */
+bool ap_mlme_is_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * mlme_set_vdev_start_failed() - set mlme priv vdev restart fail flag
+ * @vdev: vdev pointer
+ * @val: value to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val);
+
+/**
+ * mlme_is_connection_fail() - get connection fail flag
+ * @vdev: vdev pointer
+ *
+ * Return: value of vdev connection failure flag
+ */
+bool mlme_is_connection_fail(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * mlme_set_connection_fail() - set connection failure flag
+ * @vdev: vdev pointer
+ * @val: value to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+mlme_set_connection_fail(struct wlan_objmgr_vdev *vdev, bool val);
+
+/**
+ * mlme_get_vdev_start_failed() - get mlme priv vdev restart fail flag
+ * @vdev: vdev pointer
+ *
+ * Return: value of mlme priv vdev restart fail flag
+ */
+bool mlme_get_vdev_start_failed(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * mlme_is_vdev_in_beaconning_mode() - check if vdev is beaconing mode
+ * @vdev_opmode: vdev opmode
+ *
+ * To check if vdev is operating in beaconing mode or not.
+ *
+ * Return: true or false
+ */
+bool mlme_is_vdev_in_beaconning_mode(enum QDF_OPMODE vdev_opmode);
+
+/**
+ * mlme_set_assoc_type() - set associate type
+ * @vdev: vdev pointer
+ * @assoc_type: type to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_set_assoc_type(struct wlan_objmgr_vdev *vdev,
+			       enum vdev_assoc_type assoc_type);
+
+/**
+ * mlme_get_assoc_type() - get associate type
+ * @vdev: vdev pointer
+ *
+ * Return: associate type
+ */
+enum vdev_assoc_type  mlme_get_assoc_type(struct wlan_objmgr_vdev *vdev);
+
+#endif
+#endif
diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c
new file mode 100644
index 0000000..ff45c8f
--- /dev/null
+++ b/components/mlme/core/src/wlan_mlme_main.c
@@ -0,0 +1,1427 @@
+/*
+ * Copyright (c) 2018 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 internal APIs related to the mlme component
+ */
+
+#include "wlan_mlme_main.h"
+#include "cfg_ucfg_api.h"
+#include "wmi_unified.h"
+#include "wlan_scan_public_structs.h"
+
+#define NUM_OF_SOUNDING_DIMENSIONS     1 /*Nss - 1, (Nss = 2 for 2x2)*/
+
+struct wlan_mlme_psoc_obj *mlme_get_psoc_obj(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = (struct wlan_mlme_psoc_obj *)
+		wlan_objmgr_psoc_get_comp_private_obj(psoc,
+						      WLAN_UMAC_COMP_MLME);
+
+	return mlme_obj;
+}
+
+QDF_STATUS
+mlme_psoc_object_created_notification(struct wlan_objmgr_psoc *psoc,
+				      void *arg)
+{
+	QDF_STATUS status;
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = qdf_mem_malloc(sizeof(struct wlan_mlme_psoc_obj));
+	if (!mlme_obj) {
+		mlme_err("Failed to allocate memory");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+						       WLAN_UMAC_COMP_MLME,
+						       mlme_obj,
+						       QDF_STATUS_SUCCESS);
+	if (status != QDF_STATUS_SUCCESS) {
+		mlme_err("Failed to attach psoc_ctx with psoc");
+		qdf_mem_free(mlme_obj);
+	}
+
+	return status;
+}
+
+QDF_STATUS
+mlme_psoc_object_destroyed_notification(struct wlan_objmgr_psoc *psoc,
+					void *arg)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = NULL;
+	QDF_STATUS status;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+
+	status = wlan_objmgr_psoc_component_obj_detach(psoc,
+						       WLAN_UMAC_COMP_MLME,
+						       mlme_obj);
+	if (status != QDF_STATUS_SUCCESS) {
+		mlme_err("Failed to detach psoc_ctx from psoc");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	qdf_mem_free(mlme_obj);
+
+out:
+	return status;
+}
+
+static void mlme_init_chainmask_cfg(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_mlme_chainmask *chainmask_info)
+{
+	chainmask_info->txchainmask1x1 =
+		cfg_get(psoc, CFG_VHT_ENABLE_1x1_TX_CHAINMASK);
+
+	chainmask_info->rxchainmask1x1 =
+		cfg_get(psoc, CFG_VHT_ENABLE_1x1_RX_CHAINMASK);
+
+	chainmask_info->tx_chain_mask_cck =
+		cfg_get(psoc, CFG_TX_CHAIN_MASK_CCK);
+
+	chainmask_info->tx_chain_mask_1ss =
+		cfg_get(psoc, CFG_TX_CHAIN_MASK_1SS);
+
+	chainmask_info->num_11b_tx_chains =
+		cfg_get(psoc, CFG_11B_NUM_TX_CHAIN);
+
+	chainmask_info->num_11ag_tx_chains =
+		cfg_get(psoc, CFG_11AG_NUM_TX_CHAIN);
+
+	chainmask_info->tx_chain_mask_2g =
+		cfg_get(psoc, CFG_TX_CHAIN_MASK_2G);
+
+	chainmask_info->rx_chain_mask_2g =
+		cfg_get(psoc, CFG_RX_CHAIN_MASK_2G);
+
+	chainmask_info->tx_chain_mask_5g =
+		cfg_get(psoc, CFG_TX_CHAIN_MASK_5G);
+
+	chainmask_info->rx_chain_mask_5g =
+		cfg_get(psoc, CFG_RX_CHAIN_MASK_5G);
+}
+
+#ifdef WLAN_FEATURE_11W
+static void mlme_init_pmf_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_mlme_generic *gen)
+{
+	gen->pmf_sa_query_max_retries =
+		cfg_get(psoc, CFG_PMF_SA_QUERY_MAX_RETRIES);
+	gen->pmf_sa_query_retry_interval =
+		cfg_get(psoc, CFG_PMF_SA_QUERY_RETRY_INTERVAL);
+}
+#else
+static void mlme_init_pmf_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_mlme_generic *gen)
+{
+	gen->pmf_sa_query_max_retries =
+		cfg_default(CFG_PMF_SA_QUERY_MAX_RETRIES);
+	gen->pmf_sa_query_retry_interval =
+		cfg_default(CFG_PMF_SA_QUERY_RETRY_INTERVAL);
+}
+#endif /*WLAN_FEATURE_11W*/
+
+#ifdef WLAN_FEATURE_LPSS
+static inline void
+mlme_init_lpass_support_cfg(struct wlan_objmgr_psoc *psoc,
+			    struct wlan_mlme_generic *gen)
+{
+	gen->lpass_support = cfg_get(psoc, CFG_ENABLE_LPASS_SUPPORT);
+}
+#else
+static inline void
+mlme_init_lpass_support_cfg(struct wlan_objmgr_psoc *psoc,
+			    struct wlan_mlme_generic *gen)
+{
+	gen->lpass_support = cfg_default(CFG_ENABLE_LPASS_SUPPORT);
+}
+#endif
+
+static void mlme_init_generic_cfg(struct wlan_objmgr_psoc *psoc,
+				  struct wlan_mlme_generic *gen)
+{
+	gen->rtt3_enabled = cfg_default(CFG_RTT3_ENABLE);
+	gen->band_capability =
+		cfg_get(psoc, CFG_BAND_CAPABILITY);
+	gen->band = gen->band_capability;
+	gen->select_5ghz_margin =
+		cfg_get(psoc, CFG_SELECT_5GHZ_MARGIN);
+	gen->sub_20_chan_width =
+		cfg_get(psoc, CFG_SUB_20_CHANNEL_WIDTH);
+	gen->ito_repeat_count =
+		cfg_get(psoc, CFG_ITO_REPEAT_COUNT);
+	gen->dropped_pkt_disconnect_thresh =
+		cfg_get(psoc, CFG_DROPPED_PKT_DISCONNECT_THRESHOLD);
+	gen->prevent_link_down =
+		cfg_get(psoc, CFG_PREVENT_LINK_DOWN);
+	gen->memory_deep_sleep =
+		cfg_get(psoc, CFG_ENABLE_MEM_DEEP_SLEEP);
+	gen->cck_tx_fir_override =
+		cfg_get(psoc, CFG_ENABLE_CCK_TX_FIR_OVERRIDE);
+	gen->crash_inject =
+		cfg_get(psoc, CFG_ENABLE_CRASH_INJECT);
+	gen->self_recovery =
+		cfg_get(psoc, CFG_ENABLE_SELF_RECOVERY);
+	gen->sap_dot11mc =
+		cfg_get(psoc, CFG_SAP_DOT11MC);
+	gen->fatal_event_trigger =
+		cfg_get(psoc, CFG_ENABLE_FATAL_EVENT_TRIGGER);
+	gen->optimize_ca_event =
+		cfg_get(psoc, CFG_OPTIMIZE_CA_EVENT);
+	gen->fw_timeout_crash =
+		cfg_get(psoc, CFG_CRASH_FW_TIMEOUT);
+	gen->debug_packet_log = cfg_get(psoc, CFG_ENABLE_DEBUG_PACKET_LOG);
+	mlme_init_pmf_cfg(psoc, gen);
+	mlme_init_lpass_support_cfg(psoc, gen);
+}
+
+static void mlme_init_edca_ani_cfg(struct wlan_mlme_edca_params *edca_params)
+{
+	/* initialize the max allowed array length for read/write */
+	edca_params->ani_acbe_l.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->ani_acbk_l.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->ani_acvi_l.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->ani_acvo_l.max_len = CFG_EDCA_DATA_LEN;
+
+	edca_params->ani_acbe_b.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->ani_acbk_b.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->ani_acvi_b.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->ani_acvo_b.max_len = CFG_EDCA_DATA_LEN;
+
+	/* parse the ETSI edca parameters from cfg string for BK,BE,VI,VO ac */
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ANI_ACBK_LOCAL),
+			      edca_params->ani_acbk_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->ani_acbk_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ANI_ACBE_LOCAL),
+			      edca_params->ani_acbe_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->ani_acbe_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ANI_ACVI_LOCAL),
+			      edca_params->ani_acvi_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->ani_acvi_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ANI_ACVO_LOCAL),
+			      edca_params->ani_acvo_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->ani_acvo_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ANI_ACBK),
+			      edca_params->ani_acbk_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->ani_acbk_b.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ANI_ACBE),
+			      edca_params->ani_acbe_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->ani_acbe_b.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ANI_ACVI),
+			      edca_params->ani_acvi_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->ani_acvi_b.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ANI_ACVO),
+			      edca_params->ani_acvo_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->ani_acvo_b.len);
+}
+
+static void mlme_init_edca_wme_cfg(struct wlan_mlme_edca_params *edca_params)
+{
+	/* initialize the max allowed array length for read/write */
+	edca_params->wme_acbk_l.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->wme_acbe_l.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->wme_acvi_l.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->wme_acvo_l.max_len = CFG_EDCA_DATA_LEN;
+
+	edca_params->wme_acbk_b.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->wme_acbe_b.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->wme_acvi_b.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->wme_acvo_b.max_len = CFG_EDCA_DATA_LEN;
+
+	/* parse the WME edca parameters from cfg string for BK,BE,VI,VO ac */
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_WME_ACBK_LOCAL),
+			      edca_params->wme_acbk_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->wme_acbk_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_WME_ACBE_LOCAL),
+			      edca_params->wme_acbe_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->wme_acbe_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_WME_ACVI_LOCAL),
+			      edca_params->wme_acvi_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->wme_acvi_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_WME_ACVO_LOCAL),
+			      edca_params->wme_acvo_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->wme_acvo_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_WME_ACBK),
+			      edca_params->wme_acbk_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->wme_acbk_b.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_WME_ACBE),
+			      edca_params->wme_acbe_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->wme_acbe_b.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_WME_ACVI),
+			      edca_params->wme_acvi_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->wme_acvi_b.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_WME_ACVO),
+			      edca_params->wme_acvo_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->wme_acvo_b.len);
+}
+
+static void mlme_init_edca_etsi_cfg(struct wlan_mlme_edca_params *edca_params)
+{
+	/* initialize the max allowed array length for read/write */
+	edca_params->etsi_acbe_l.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->etsi_acbk_l.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->etsi_acvi_l.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->etsi_acvo_l.max_len = CFG_EDCA_DATA_LEN;
+
+	edca_params->etsi_acbe_b.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->etsi_acbk_b.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->etsi_acvi_b.max_len = CFG_EDCA_DATA_LEN;
+	edca_params->etsi_acvo_b.max_len = CFG_EDCA_DATA_LEN;
+
+	/* parse the ETSI edca parameters from cfg string for BK,BE,VI,VO ac */
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ETSI_ACBK_LOCAL),
+			      edca_params->etsi_acbk_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->etsi_acbk_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ETSI_ACBE_LOCAL),
+			      edca_params->etsi_acbe_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->etsi_acbe_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ETSI_ACVI_LOCAL),
+			      edca_params->etsi_acvi_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->etsi_acvi_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ETSI_ACVO_LOCAL),
+			      edca_params->etsi_acvo_l.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->etsi_acvo_l.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ETSI_ACBK),
+			      edca_params->etsi_acbk_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->etsi_acbk_b.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ETSI_ACBE),
+			      edca_params->etsi_acbe_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->etsi_acbe_b.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ETSI_ACVI),
+			      edca_params->etsi_acvi_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->etsi_acvi_b.len);
+
+	qdf_uint8_array_parse(cfg_default(CFG_EDCA_ETSI_ACVO),
+			      edca_params->etsi_acvo_b.data,
+			      CFG_EDCA_DATA_LEN,
+			      &edca_params->etsi_acvo_b.len);
+}
+
+static void
+mlme_init_qos_edca_params(struct wlan_objmgr_psoc *psoc,
+			  struct wlan_mlme_edca_params *edca_params)
+{
+	edca_params->enable_edca_params =
+			cfg_get(psoc, CFG_EDCA_ENABLE_PARAM);
+
+	edca_params->edca_ac_vo.vo_cwmin =
+			cfg_get(psoc, CFG_EDCA_VO_CWMIN);
+	edca_params->edca_ac_vo.vo_cwmax =
+			cfg_get(psoc, CFG_EDCA_VO_CWMAX);
+	edca_params->edca_ac_vo.vo_aifs =
+			cfg_get(psoc, CFG_EDCA_VO_AIFS);
+
+	edca_params->edca_ac_vi.vi_cwmin =
+			cfg_get(psoc, CFG_EDCA_VI_CWMIN);
+	edca_params->edca_ac_vi.vi_cwmax =
+			cfg_get(psoc, CFG_EDCA_VI_CWMAX);
+	edca_params->edca_ac_vi.vi_aifs =
+			cfg_get(psoc, CFG_EDCA_VI_AIFS);
+
+	edca_params->edca_ac_bk.bk_cwmin =
+			cfg_get(psoc, CFG_EDCA_BK_CWMIN);
+	edca_params->edca_ac_bk.bk_cwmax =
+			cfg_get(psoc, CFG_EDCA_BK_CWMAX);
+	edca_params->edca_ac_bk.bk_aifs =
+			cfg_get(psoc, CFG_EDCA_BK_AIFS);
+
+	edca_params->edca_ac_be.be_cwmin =
+			cfg_get(psoc, CFG_EDCA_BE_CWMIN);
+	edca_params->edca_ac_be.be_cwmax =
+			cfg_get(psoc, CFG_EDCA_BE_CWMAX);
+	edca_params->edca_ac_be.be_aifs =
+			cfg_get(psoc, CFG_EDCA_BE_AIFS);
+}
+
+static void mlme_init_edca_params(struct wlan_objmgr_psoc *psoc,
+				  struct wlan_mlme_edca_params *edca_params)
+{
+	mlme_init_edca_ani_cfg(edca_params);
+	mlme_init_edca_wme_cfg(edca_params);
+	mlme_init_edca_etsi_cfg(edca_params);
+	mlme_init_qos_edca_params(psoc, edca_params);
+}
+
+static void mlme_init_timeout_cfg(struct wlan_objmgr_psoc *psoc,
+				  struct wlan_mlme_timeout *timeouts)
+{
+	timeouts->join_failure_timeout =
+			cfg_get(psoc, CFG_JOIN_FAILURE_TIMEOUT);
+	timeouts->auth_failure_timeout =
+			cfg_get(psoc, CFG_AUTH_FAILURE_TIMEOUT);
+	timeouts->auth_rsp_timeout =
+			cfg_get(psoc, CFG_AUTH_RSP_TIMEOUT);
+	timeouts->assoc_failure_timeout =
+			cfg_get(psoc, CFG_ASSOC_FAILURE_TIMEOUT);
+	timeouts->reassoc_failure_timeout =
+			cfg_get(psoc, CFG_REASSOC_FAILURE_TIMEOUT);
+	timeouts->probe_after_hb_fail_timeout =
+			cfg_get(psoc, CFG_PROBE_AFTER_HB_FAIL_TIMEOUT);
+	timeouts->olbc_detect_timeout =
+			cfg_get(psoc, CFG_OLBC_DETECT_TIMEOUT);
+	timeouts->addts_rsp_timeout =
+			cfg_get(psoc, CFG_ADDTS_RSP_TIMEOUT);
+	timeouts->heart_beat_threshold =
+			cfg_get(psoc, CFG_HEART_BEAT_THRESHOLD);
+	timeouts->ap_keep_alive_timeout =
+			cfg_get(psoc, CFG_AP_KEEP_ALIVE_TIMEOUT);
+	timeouts->ap_link_monitor_timeout =
+			cfg_get(psoc, CFG_AP_LINK_MONITOR_TIMEOUT);
+	timeouts->ps_data_inactivity_timeout =
+			cfg_get(psoc, CFG_PS_DATA_INACTIVITY_TIMEOUT);
+}
+
+static void mlme_init_ht_cap_in_cfg(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_mlme_ht_caps *ht_caps)
+{
+	union {
+		uint16_t val_16;
+		struct mlme_ht_capabilities_info ht_cap_info;
+	} u1;
+
+	union {
+		uint16_t val_16;
+		struct mlme_ht_ext_cap_info ext_cap_info;
+	} u2;
+
+	union {
+		uint8_t val_8;
+		struct mlme_ht_info_field_1 info_field_1;
+	} u3;
+
+	union {
+		uint16_t val_16;
+		struct mlme_ht_info_field_2 info_field_2;
+	} u4;
+
+	union {
+		uint16_t val_16;
+		struct mlme_ht_info_field_3 info_field_3;
+	} u5;
+
+	/* HT Capabilities - HT Caps Info Field */
+	u1.val_16 = (uint16_t)cfg_default(CFG_HT_CAP_INFO);
+	u1.ht_cap_info.adv_coding_cap =
+				cfg_get(psoc, CFG_RX_LDPC_ENABLE);
+	u1.ht_cap_info.rx_stbc = cfg_get(psoc, CFG_RX_STBC_ENABLE);
+	u1.ht_cap_info.tx_stbc = cfg_get(psoc, CFG_TX_STBC_ENABLE);
+	u1.ht_cap_info.short_gi_20_mhz =
+				cfg_get(psoc, CFG_SHORT_GI_20MHZ);
+	u1.ht_cap_info.short_gi_40_mhz =
+				cfg_get(psoc, CFG_SHORT_GI_40MHZ);
+	ht_caps->ht_cap_info = u1.ht_cap_info;
+
+	/* HT Capapabilties - AMPDU Params */
+	ht_caps->ampdu_params.max_rx_ampdu_factor =
+		cfg_get(psoc, CFG_MAX_RX_AMPDU_FACTOR);
+	ht_caps->ampdu_params.mpdu_density =
+		cfg_get(psoc, CFG_MPDU_DENSITY);
+	ht_caps->ampdu_params.reserved = 0;
+
+	/* HT Capabilities - Extended Capabilities field */
+	u2.val_16 = (uint16_t)cfg_default(CFG_EXT_HT_CAP_INFO);
+	ht_caps->ext_cap_info = u2.ext_cap_info;
+
+	/* HT Operation - Information subset 1 of 3 */
+	u3.val_8 = (uint8_t)cfg_default(CFG_HT_INFO_FIELD_1);
+	ht_caps->info_field_1 = u3.info_field_1;
+
+	/* HT Operation - Information subset 2 of 3 */
+	u4.val_16 = (uint16_t)cfg_default(CFG_HT_INFO_FIELD_2);
+	ht_caps->info_field_2 = u4.info_field_2;
+
+	/* HT Operation - Information subset 3 of 3 */
+	u5.val_16 = (uint16_t)cfg_default(CFG_HT_INFO_FIELD_3);
+	ht_caps->info_field_3 = u5.info_field_3;
+
+	ht_caps->short_preamble = cfg_get(psoc, CFG_SHORT_PREAMBLE);
+	ht_caps->enable_ampdu_ps = cfg_get(psoc, CFG_ENABLE_AMPDUPS);
+	ht_caps->enable_smps = cfg_get(psoc, CFG_ENABLE_HT_SMPS);
+	ht_caps->smps = cfg_get(psoc, CFG_HT_SMPS_MODE);
+	ht_caps->max_num_amsdu = cfg_get(psoc, CFG_MAX_AMSDU_NUM);
+}
+
+static void mlme_init_qos_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_mlme_qos *qos_aggr_params)
+{
+	qos_aggr_params->tx_aggregation_size =
+				cfg_get(psoc, CFG_TX_AGGREGATION_SIZE);
+	qos_aggr_params->tx_aggregation_size_be =
+				cfg_get(psoc, CFG_TX_AGGREGATION_SIZEBE);
+	qos_aggr_params->tx_aggregation_size_bk =
+				cfg_get(psoc, CFG_TX_AGGREGATION_SIZEBK);
+	qos_aggr_params->tx_aggregation_size_vi =
+				cfg_get(psoc, CFG_TX_AGGREGATION_SIZEVI);
+	qos_aggr_params->tx_aggregation_size_vo =
+				cfg_get(psoc, CFG_TX_AGGREGATION_SIZEVO);
+	qos_aggr_params->rx_aggregation_size =
+				cfg_get(psoc, CFG_RX_AGGREGATION_SIZE);
+	qos_aggr_params->tx_aggr_sw_retry_threshold_be =
+				cfg_get(psoc, CFG_TX_AGGR_SW_RETRY_BE);
+	qos_aggr_params->tx_aggr_sw_retry_threshold_bk =
+				cfg_get(psoc, CFG_TX_AGGR_SW_RETRY_BK);
+	qos_aggr_params->tx_aggr_sw_retry_threshold_vi =
+				cfg_get(psoc, CFG_TX_AGGR_SW_RETRY_VI);
+	qos_aggr_params->tx_aggr_sw_retry_threshold_vo =
+				cfg_get(psoc, CFG_TX_AGGR_SW_RETRY_VO);
+	qos_aggr_params->tx_non_aggr_sw_retry_threshold_be =
+				cfg_get(psoc, CFG_TX_NON_AGGR_SW_RETRY_BE);
+	qos_aggr_params->tx_non_aggr_sw_retry_threshold_bk =
+				cfg_get(psoc, CFG_TX_NON_AGGR_SW_RETRY_BK);
+	qos_aggr_params->tx_non_aggr_sw_retry_threshold_vi =
+				cfg_get(psoc, CFG_TX_NON_AGGR_SW_RETRY_VI);
+	qos_aggr_params->tx_non_aggr_sw_retry_threshold_vo =
+				cfg_get(psoc, CFG_TX_NON_AGGR_SW_RETRY_VO);
+	qos_aggr_params->sap_max_inactivity_override =
+				cfg_get(psoc, CFG_SAP_MAX_INACTIVITY_OVERRIDE);
+}
+
+static void mlme_init_mbo_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_mlme_mbo *mbo_params)
+{
+	mbo_params->mbo_candidate_rssi_thres =
+			cfg_get(psoc, CFG_MBO_CANDIDATE_RSSI_THRESHOLD);
+	mbo_params->mbo_current_rssi_thres =
+			cfg_get(psoc, CFG_MBO_CURRENT_RSSI_THRESHOLD);
+	mbo_params->mbo_current_rssi_mcc_thres =
+			cfg_get(psoc, CFG_MBO_CUR_RSSI_MCC_THRESHOLD);
+	mbo_params->mbo_candidate_rssi_btc_thres =
+			cfg_get(psoc, CFG_MBO_CAND_RSSI_BTC_THRESHOLD);
+}
+
+static void mlme_init_vht_cap_cfg(struct wlan_objmgr_psoc *psoc,
+				  struct mlme_vht_capabilities_info
+				  *vht_cap_info)
+{
+	vht_cap_info->supp_chan_width =
+			cfg_default(CFG_VHT_SUPP_CHAN_WIDTH);
+	vht_cap_info->num_soundingdim =
+			cfg_default(CFG_VHT_NUM_SOUNDING_DIMENSIONS);
+	vht_cap_info->htc_vhtc =
+			cfg_default(CFG_VHT_HTC_VHTC);
+	vht_cap_info->link_adap_cap =
+			cfg_default(CFG_VHT_LINK_ADAPTATION_CAP);
+	vht_cap_info->rx_antpattern =
+			cfg_default(CFG_VHT_RX_ANT_PATTERN);
+	vht_cap_info->tx_antpattern =
+			cfg_default(CFG_VHT_TX_ANT_PATTERN);
+	vht_cap_info->rx_supp_data_rate =
+			cfg_default(CFG_VHT_RX_SUPP_DATA_RATE);
+	vht_cap_info->tx_supp_data_rate =
+			cfg_default(CFG_VHT_TX_SUPP_DATA_RATE);
+	vht_cap_info->txop_ps =
+			cfg_default(CFG_VHT_TXOP_PS);
+	vht_cap_info->rx_mcs_map =
+			CFG_VHT_RX_MCS_MAP_STADEF;
+	vht_cap_info->tx_mcs_map =
+			CFG_VHT_TX_MCS_MAP_STADEF;
+	vht_cap_info->basic_mcs_set =
+			CFG_VHT_BASIC_MCS_SET_STADEF;
+
+	vht_cap_info->tx_bfee_ant_supp =
+			cfg_get(psoc, CFG_VHT_BEAMFORMEE_ANT_SUPP);
+
+	vht_cap_info->enable_txbf_20mhz =
+			cfg_get(psoc, CFG_VHT_ENABLE_TXBF_IN_20MHZ);
+	vht_cap_info->ampdu_len =
+			cfg_get(psoc, CFG_VHT_MPDU_LEN);
+
+	vht_cap_info->ldpc_coding_cap =
+			cfg_get(psoc, CFG_RX_LDPC_ENABLE);
+	vht_cap_info->short_gi_80mhz =
+			cfg_get(psoc, CFG_SHORT_GI_40MHZ);
+	vht_cap_info->short_gi_160mhz =
+			cfg_get(psoc, CFG_SHORT_GI_40MHZ);
+	vht_cap_info->tx_stbc =
+			cfg_get(psoc, CFG_TX_STBC_ENABLE);
+	vht_cap_info->rx_stbc =
+			cfg_get(psoc, CFG_RX_STBC_ENABLE);
+
+	vht_cap_info->su_bformee =
+		cfg_default(CFG_VHT_SU_BEAMFORMEE_CAP);
+
+	vht_cap_info->mu_bformer =
+			cfg_default(CFG_VHT_MU_BEAMFORMER_CAP);
+
+	vht_cap_info->enable_mu_bformee =
+			cfg_get(psoc, CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE);
+	vht_cap_info->ampdu_len_exponent =
+			cfg_get(psoc, CFG_VHT_AMPDU_LEN_EXPONENT);
+	vht_cap_info->channel_width =
+			cfg_get(psoc, CFG_VHT_CHANNEL_WIDTH);
+	vht_cap_info->rx_mcs =
+			cfg_get(psoc, CFG_VHT_ENABLE_RX_MCS_8_9);
+	vht_cap_info->tx_mcs =
+			cfg_get(psoc, CFG_VHT_ENABLE_TX_MCS_8_9);
+	vht_cap_info->rx_mcs2x2 =
+			cfg_get(psoc, CFG_VHT_ENABLE_RX_MCS2x2_8_9);
+	vht_cap_info->tx_mcs2x2 =
+			cfg_get(psoc, CFG_VHT_ENABLE_TX_MCS2x2_8_9);
+	vht_cap_info->enable_vht20_mcs9 =
+			cfg_get(psoc, CFG_ENABLE_VHT20_MCS9);
+	vht_cap_info->enable2x2 =
+			cfg_get(psoc, CFG_VHT_ENABLE_2x2_CAP_FEATURE);
+	vht_cap_info->enable_paid =
+			cfg_get(psoc, CFG_VHT_ENABLE_PAID_FEATURE);
+	vht_cap_info->enable_gid =
+			cfg_get(psoc, CFG_VHT_ENABLE_GID_FEATURE);
+	vht_cap_info->b24ghz_band =
+			cfg_get(psoc, CFG_ENABLE_VHT_FOR_24GHZ);
+	vht_cap_info->vendor_24ghz_band =
+			cfg_get(psoc, CFG_ENABLE_VENDOR_VHT_FOR_24GHZ);
+	vht_cap_info->tx_bfee_sap =
+			cfg_get(psoc, CFG_VHT_ENABLE_TXBF_SAP_MODE);
+	vht_cap_info->vendor_vhtie =
+			cfg_get(psoc, CFG_ENABLE_SUBFEE_IN_VENDOR_VHTIE);
+
+	if (vht_cap_info->enable2x2)
+		vht_cap_info->su_bformer =
+			cfg_get(psoc, CFG_VHT_ENABLE_TX_SU_BEAM_FORMER);
+
+	if (vht_cap_info->enable2x2 && vht_cap_info->su_bformer)
+		vht_cap_info->num_soundingdim = NUM_OF_SOUNDING_DIMENSIONS;
+}
+
+static void mlme_init_rates_in_cfg(struct wlan_objmgr_psoc *psoc,
+				   struct wlan_mlme_rates *rates)
+{
+	rates->cfp_period = cfg_default(CFG_CFP_PERIOD);
+	rates->cfp_max_duration = cfg_default(CFG_CFP_MAX_DURATION);
+	rates->max_htmcs_txdata = cfg_get(psoc, CFG_MAX_HT_MCS_FOR_TX_DATA);
+	rates->disable_abg_rate_txdata = cfg_get(psoc,
+					CFG_DISABLE_ABG_RATE_FOR_TX_DATA);
+	rates->sap_max_mcs_txdata = cfg_get(psoc,
+					CFG_SAP_MAX_MCS_FOR_TX_DATA);
+	rates->disable_high_ht_mcs_2x2 = cfg_get(psoc,
+					 CFG_DISABLE_HIGH_HT_RX_MCS_2x2);
+
+	rates->supported_11b.max_len = CFG_SUPPORTED_RATES_11B_LEN;
+	qdf_uint8_array_parse(cfg_default(CFG_SUPPORTED_RATES_11B),
+			      rates->supported_11b.data,
+			      sizeof(rates->supported_11b.data),
+			      &rates->supported_11b.len);
+	rates->supported_11a.max_len = CFG_SUPPORTED_RATES_11A_LEN;
+	qdf_uint8_array_parse(cfg_default(CFG_SUPPORTED_RATES_11A),
+			      rates->supported_11a.data,
+			      sizeof(rates->supported_11a.data),
+			      &rates->supported_11a.len);
+	rates->opr_rate_set.max_len = CFG_OPERATIONAL_RATE_SET_LEN;
+	rates->opr_rate_set.len = 0;
+	rates->ext_opr_rate_set.max_len = CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN;
+	rates->ext_opr_rate_set.len = 0;
+	rates->supported_mcs_set.max_len = CFG_SUPPORTED_MCS_SET_LEN;
+	qdf_uint8_array_parse(cfg_default(CFG_SUPPORTED_MCS_SET),
+			      rates->supported_mcs_set.data,
+			      sizeof(rates->supported_mcs_set.data),
+			      &rates->supported_mcs_set.len);
+	rates->basic_mcs_set.max_len = CFG_BASIC_MCS_SET_LEN;
+	qdf_uint8_array_parse(cfg_default(CFG_BASIC_MCS_SET),
+			      rates->basic_mcs_set.data,
+			      sizeof(rates->basic_mcs_set.data),
+			      &rates->basic_mcs_set.len);
+	rates->current_mcs_set.max_len = CFG_CURRENT_MCS_SET_LEN;
+	qdf_uint8_array_parse(cfg_default(CFG_CURRENT_MCS_SET),
+			      rates->current_mcs_set.data,
+			      sizeof(rates->current_mcs_set.data),
+			      &rates->current_mcs_set.len);
+}
+
+static void mlme_init_dfs_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_mlme_dfs_cfg *dfs_cfg)
+{
+	dfs_cfg->dfs_master_capable = cfg_get(psoc,
+					      CFG_ENABLE_DFS_MASTER_CAPABILITY);
+}
+
+static void mlme_init_feature_flag_in_cfg(
+				struct wlan_objmgr_psoc *psoc,
+				struct wlan_mlme_feature_flag *feature_flags)
+{
+	feature_flags->accept_short_slot_assoc =
+				cfg_default(CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY);
+	feature_flags->enable_hcf = cfg_default(CFG_HCF_ENABLED);
+	feature_flags->enable_rsn = cfg_default(CFG_RSN_ENABLED);
+	feature_flags->enable_short_preamble_11g =
+				cfg_default(CFG_11G_SHORT_PREAMBLE_ENABLED);
+	feature_flags->enable_short_slot_time_11g =
+				cfg_default(CFG_11G_SHORT_SLOT_TIME_ENABLED);
+	feature_flags->channel_bonding_mode =
+				cfg_default(CFG_CHANNEL_BONDING_MODE);
+	feature_flags->enable_block_ack = cfg_default(CFG_BLOCK_ACK_ENABLED);
+	feature_flags->enable_ampdu = cfg_get(psoc, CFG_ENABLE_AMPDUPS);
+}
+
+static void mlme_init_sap_protection_cfg(struct wlan_objmgr_psoc *psoc,
+					 struct wlan_mlme_sap_protection
+					 *sap_protection_params)
+{
+	sap_protection_params->protection_enabled =
+				cfg_default(CFG_PROTECTION_ENABLED);
+	sap_protection_params->protection_force_policy =
+				cfg_default(CFG_FORCE_POLICY_PROTECTION);
+	sap_protection_params->ignore_peer_ht_opmode =
+				cfg_get(psoc, CFG_IGNORE_PEER_HT_MODE);
+}
+
+static void mlme_init_he_cap_in_cfg(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_mlme_he_caps *he_caps)
+{
+	he_caps->he_control = cfg_default(CFG_HE_CONTROL);
+	he_caps->he_twt_requestor = cfg_default(CFG_HE_TWT_REQUESTOR);
+	he_caps->he_twt_responder = cfg_default(CFG_HE_TWT_RESPONDER);
+	he_caps->he_twt_fragmentation = cfg_default(CFG_HE_TWT_FRAGMENTATION);
+	he_caps->he_max_frag_msdu = cfg_default(CFG_HE_MAX_FRAG_MSDU);
+	he_caps->he_min_frag_size = cfg_default(CFG_HE_MIN_FRAG_SIZE);
+	he_caps->he_trig_pad = cfg_default(CFG_HE_TRIG_PAD);
+	he_caps->he_mtid_aggr_rx = cfg_default(CFG_HE_MTID_AGGR_RX);
+	he_caps->he_link_adaptation = cfg_default(CFG_HE_LINK_ADAPTATION);
+	he_caps->he_all_ack = cfg_default(CFG_HE_ALL_ACK);
+	he_caps->he_trigd_rsp_scheduling =
+			cfg_default(CFG_HE_TRIGD_RSP_SCHEDULING);
+	he_caps->he_buffer_status_rpt = cfg_default(CFG_HE_BUFFER_STATUS_RPT);
+	he_caps->he_bcast_twt = cfg_default(CFG_HE_BCAST_TWT);
+	he_caps->he_ba_32bit = cfg_default(CFG_HE_BA_32BIT);
+	he_caps->he_mu_cascading = cfg_default(CFG_HE_MU_CASCADING);
+	he_caps->he_multi_tid = cfg_default(CFG_HE_MULTI_TID);
+	he_caps->he_dl_mu_ba = cfg_default(CFG_HE_DL_MU_BA);
+	he_caps->he_omi = cfg_default(CFG_HE_OMI);
+	he_caps->he_ofdma_ra = cfg_default(CFG_HE_OFDMA_RA);
+	he_caps->he_max_ampdu_len = cfg_default(CFG_HE_MAX_AMPDU_LEN);
+	he_caps->he_amsdu_frag = cfg_default(CFG_HE_AMSDU_FRAG);
+	he_caps->he_flex_twt_sched = cfg_default(CFG_HE_FLEX_TWT_SCHED);
+	he_caps->he_rx_ctrl = cfg_default(CFG_HE_RX_CTRL);
+	he_caps->he_bsrp_ampdu_aggr = cfg_default(CFG_HE_BSRP_AMPDU_AGGR);
+	he_caps->he_qtp = cfg_default(CFG_HE_QTP);
+	he_caps->he_a_bqr = cfg_default(CFG_HE_A_BQR);
+	he_caps->he_sr_responder = cfg_default(CFG_HE_SR_RESPONDER);
+	he_caps->he_ndp_feedback_supp = cfg_default(CFG_HE_NDP_FEEDBACK_SUPP);
+	he_caps->he_ops_supp = cfg_default(CFG_HE_OPS_SUPP);
+	he_caps->he_amsdu_in_ampdu = cfg_default(CFG_HE_AMSDU_IN_AMPDU);
+	he_caps->he_chan_width = cfg_default(CFG_HE_CHAN_WIDTH);
+	he_caps->he_mtid_aggr_tx = cfg_default(CFG_HE_MTID_AGGR_TX);
+	he_caps->he_sub_ch_sel_tx = cfg_default(CFG_HE_SUB_CH_SEL_TX);
+	he_caps->he_ul_2x996_ru = cfg_default(CFG_HE_UL_2X996_RU);
+	he_caps->he_om_ctrl_ul_mu_dis_rx =
+				cfg_default(CFG_HE_OM_CTRL_UL_MU_DIS_RX);
+	he_caps->he_rx_pream_punc = cfg_default(CFG_HE_RX_PREAM_PUNC);
+	he_caps->he_class_of_device = cfg_default(CFG_HE_CLASS_OF_DEVICE);
+	he_caps->he_ldpc = cfg_default(CFG_HE_LDPC);
+	he_caps->he_ltf_ppdu = cfg_default(CFG_HE_LTF_PPDU);
+	he_caps->he_midamble_rx_nsts = cfg_default(CFG_HE_MIDAMBLE_RX_MAX_NSTS);
+	he_caps->he_ltf_ndp = cfg_default(CFG_HE_LTF_NDP);
+	he_caps->he_tx_stbc_lt80 = cfg_default(CFG_HE_TX_STBC_LT80);
+	he_caps->he_rx_stbc_lt80 = cfg_default(CFG_HE_RX_STBC_LT80);
+	he_caps->he_doppler = cfg_default(CFG_HE_DOPPLER);
+	he_caps->he_ul_mumimo = cfg_default(CFG_HE_UL_MUMIMO);
+	he_caps->he_dcm_tx = cfg_default(CFG_HE_DCM_TX);
+	he_caps->he_dcm_rx = cfg_default(CFG_HE_DCM_RX);
+	he_caps->he_mu_ppdu = cfg_default(CFG_HE_MU_PPDU);
+	he_caps->he_su_beamformer = cfg_default(CFG_HE_SU_BEAMFORMER);
+	he_caps->he_su_beamformee = cfg_default(CFG_HE_SU_BEAMFORMEE);
+	he_caps->he_mu_beamformer = cfg_default(CFG_HE_MU_BEAMFORMER);
+	he_caps->he_bfee_sts_lt80 = cfg_default(CFG_HE_BFEE_STS_LT80);
+	he_caps->he_bfee_sts_gt80 = cfg_default(CFG_HE_BFEE_STS_GT80);
+	he_caps->he_num_sound_lt80 = cfg_default(CFG_HE_NUM_SOUND_LT80);
+	he_caps->he_num_sound_gt80 = cfg_default(CFG_HE_NUM_SOUND_GT80);
+	he_caps->he_su_feed_tone16 = cfg_default(CFG_HE_SU_FEED_TONE16);
+	he_caps->he_mu_feed_tone16 = cfg_default(CFG_HE_MU_FEED_TONE16);
+	he_caps->he_codebook_su = cfg_default(CFG_HE_CODEBOOK_SU);
+	he_caps->he_codebook_mu = cfg_default(CFG_HE_CODEBOOK_MU);
+	he_caps->he_bfrm_feed = cfg_default(CFG_HE_BFRM_FEED);
+	he_caps->he_er_su_ppdu = cfg_default(CFG_HE_ER_SU_PPDU);
+	he_caps->he_dl_part_bw = cfg_default(CFG_HE_DL_PART_BW);
+	he_caps->he_ppet_present = cfg_default(CFG_HE_PPET_PRESENT);
+	he_caps->he_srp = cfg_default(CFG_HE_SRP);
+	he_caps->he_power_boost = cfg_default(CFG_HE_POWER_BOOST);
+	he_caps->he_4x_ltf_gi = cfg_default(CFG_HE_4x_LTF_GI);
+	he_caps->he_max_nc = cfg_default(CFG_HE_MAX_NC);
+	he_caps->he_tx_stbc_gt80 = cfg_default(CFG_HE_TX_STBC_GT80);
+	he_caps->he_rx_stbc_gt80 = cfg_default(CFG_HE_RX_STBC_GT80);
+	he_caps->he_er_4x_ltf_gi = cfg_default(CFG_HE_ER_4x_LTF_GI);
+	he_caps->he_ppdu_20_in_40mhz_2g =
+			cfg_default(CFG_HE_PPDU_20_IN_40MHZ_2G);
+	he_caps->he_ppdu_20_in_160_80p80mhz =
+			cfg_default(CFG_HE_PPDU_20_IN_160_80P80MHZ);
+	he_caps->he_ppdu_80_in_160_80p80mhz =
+			cfg_default(CFG_HE_PPDU_80_IN_160_80P80MHZ);
+		he_caps->he_er_1x_he_ltf_gi =
+			cfg_default(CFG_HE_ER_1X_HE_LTF_GI);
+	he_caps->he_midamble_rx_1x_he_ltf =
+			cfg_default(CFG_HE_MIDAMBLE_RX_1X_HE_LTF);
+	he_caps->he_dcm_max_bw = cfg_default(CFG_HE_DCM_MAX_BW);
+	he_caps->he_longer_16_sigb_ofdm_sym =
+			cfg_default(CFG_HE_LONGER_16_SIGB_OFDM_SYM);
+	he_caps->he_non_trig_cqi_feedback =
+			cfg_default(CFG_HE_NON_TRIG_CQI_FEEDBACK);
+	he_caps->he_tx_1024_qam_lt_242_ru =
+			cfg_default(CFG_HE_TX_1024_QAM_LT_242_RU);
+	he_caps->he_rx_1024_qam_lt_242_ru =
+			cfg_default(CFG_HE_RX_1024_QAM_LT_242_RU);
+	he_caps->he_rx_full_bw_mu_cmpr_sigb =
+			cfg_default(CFG_HE_RX_FULL_BW_MU_CMPR_SIGB);
+	he_caps->he_rx_full_bw_mu_non_cmpr_sigb =
+			cfg_default(CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB);
+	he_caps->he_rx_mcs_map_lt_80 = cfg_default(CFG_HE_RX_MCS_MAP_LT_80);
+	he_caps->he_tx_mcs_map_lt_80 = cfg_default(CFG_HE_TX_MCS_MAP_LT_80);
+	he_caps->he_rx_mcs_map_160 = cfg_default(CFG_HE_RX_MCS_MAP_160);
+	he_caps->he_tx_mcs_map_160 = cfg_default(CFG_HE_TX_MCS_MAP_160);
+	he_caps->he_rx_mcs_map_80_80 = cfg_default(CFG_HE_RX_MCS_MAP_80_80);
+	he_caps->he_tx_mcs_map_80_80 = cfg_default(CFG_HE_TX_MCS_MAP_80_80);
+	he_caps->he_ops_basic_mcs_nss = cfg_default(CFG_HE_OPS_BASIC_MCS_NSS);
+	he_caps->he_twt_dynamic_fragmentation =
+			cfg_get(psoc, CFG_HE_DYNAMIC_FRAGMENTATION);
+	he_caps->enable_ul_mimo =
+			cfg_get(psoc, CFG_ENABLE_UL_MIMO);
+	he_caps->enable_ul_ofdm =
+			cfg_get(psoc, CFG_ENABLE_UL_OFDMA);
+	he_caps->he_sta_obsspd =
+			cfg_get(psoc, CFG_HE_STA_OBSSPD);
+	qdf_mem_zero(he_caps->he_ppet_2g, MLME_HE_PPET_LEN);
+	qdf_mem_zero(he_caps->he_ppet_5g, MLME_HE_PPET_LEN);
+}
+
+static void mlme_init_sap_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_mlme_cfg_sap *sap_cfg)
+{
+	sap_cfg->beacon_interval = cfg_get(psoc, CFG_BEACON_INTERVAL);
+	sap_cfg->dtim_interval = cfg_default(CFG_DTIM_PERIOD);
+	sap_cfg->listen_interval = cfg_default(CFG_LISTEN_INTERVAL);
+	sap_cfg->sap_11g_policy = cfg_default(CFG_11G_ONLY_POLICY);
+	sap_cfg->assoc_sta_limit = cfg_default(CFG_ASSOC_STA_LIMIT);
+	sap_cfg->enable_lte_coex = cfg_get(psoc, CFG_ENABLE_LTE_COEX);
+	sap_cfg->rmc_action_period_freq =
+		cfg_default(CFG_RMC_ACTION_PERIOD_FREQUENCY);
+	sap_cfg->rate_tx_mgmt = cfg_get(psoc, CFG_RATE_FOR_TX_MGMT);
+	sap_cfg->rate_tx_mgmt_2g = cfg_get(psoc, CFG_RATE_FOR_TX_MGMT_2G);
+	sap_cfg->rate_tx_mgmt_5g = cfg_get(psoc, CFG_RATE_FOR_TX_MGMT_5G);
+	sap_cfg->tele_bcn_wakeup_en = cfg_get(psoc, CFG_TELE_BCN_WAKEUP_EN);
+	sap_cfg->tele_bcn_max_li = cfg_get(psoc, CFG_TELE_BCN_MAX_LI);
+	sap_cfg->sap_get_peer_info = cfg_get(psoc, CFG_SAP_GET_PEER_INFO);
+	sap_cfg->sap_allow_all_chan_param_name =
+			cfg_get(psoc, CFG_SAP_ALLOW_ALL_CHANNEL_PARAM);
+	sap_cfg->sap_max_no_peers = cfg_get(psoc, CFG_SAP_MAX_NO_PEERS);
+	sap_cfg->sap_max_offload_peers =
+			cfg_get(psoc, CFG_SAP_MAX_OFFLOAD_PEERS);
+	sap_cfg->sap_max_offload_reorder_buffs =
+			cfg_get(psoc, CFG_SAP_MAX_OFFLOAD_REORDER_BUFFS);
+	sap_cfg->sap_ch_switch_beacon_cnt =
+			cfg_get(psoc, CFG_SAP_CH_SWITCH_BEACON_CNT);
+	sap_cfg->sap_ch_switch_mode = cfg_get(psoc, CFG_SAP_CH_SWITCH_MODE);
+	sap_cfg->sap_internal_restart =
+			cfg_get(psoc, CFG_SAP_INTERNAL_RESTART);
+	sap_cfg->chan_switch_hostapd_rate_enabled_name =
+		cfg_get(psoc, CFG_CHAN_SWITCH_HOSTAPD_RATE_ENABLED_NAME);
+	sap_cfg->reduced_beacon_interval =
+		cfg_get(psoc, CFG_REDUCED_BEACON_INTERVAL);
+
+}
+
+static void mlme_init_obss_ht40_cfg(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_mlme_obss_ht40 *obss_ht40)
+{
+	obss_ht40->active_dwelltime =
+		cfg_get(psoc, CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME);
+	obss_ht40->passive_dwelltime =
+		cfg_get(psoc, CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME);
+	obss_ht40->width_trigger_interval =
+		cfg_get(psoc, CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL);
+	obss_ht40->passive_per_channel = (uint32_t)
+		cfg_default(CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL);
+	obss_ht40->active_per_channel = (uint32_t)
+		cfg_default(CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL);
+	obss_ht40->width_trans_delay = (uint32_t)
+		cfg_default(CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY);
+	obss_ht40->scan_activity_threshold = (uint32_t)
+		cfg_default(CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD);
+}
+static void mlme_init_threshold_cfg(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_mlme_threshold *threshold)
+{
+	threshold->rts_threshold = cfg_get(psoc, CFG_RTS_THRESHOLD);
+	threshold->frag_threshold = cfg_get(psoc, CFG_FRAG_THRESHOLD);
+}
+
+static void mlme_init_acs_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_mlme_acs *acs)
+{
+	acs->is_acs_with_more_param =
+		cfg_get(psoc, CFG_ACS_WITH_MORE_PARAM);
+	acs->auto_channel_select_weight =
+		cfg_get(psoc, CFG_AUTO_CHANNEL_SELECT_WEIGHT);
+	acs->is_vendor_acs_support =
+		cfg_get(psoc, CFG_USER_AUTO_CHANNEL_SELECTION);
+	acs->is_acs_support_for_dfs_ltecoex =
+		cfg_get(psoc, CFG_USER_ACS_DFS_LTE);
+	acs->is_external_acs_policy =
+		cfg_get(psoc, CFG_EXTERNAL_ACS_POLICY);
+}
+
+static void
+mlme_init_product_details_cfg(struct wlan_mlme_product_details_cfg
+			      *product_details)
+{
+	qdf_str_lcopy(product_details->manufacturer_name,
+		      cfg_default(CFG_MFR_NAME),
+		      sizeof(product_details->manufacturer_name));
+	qdf_str_lcopy(product_details->manufacture_product_name,
+		      cfg_default(CFG_MFR_PRODUCT_NAME),
+		      sizeof(product_details->manufacture_product_name));
+	qdf_str_lcopy(product_details->manufacture_product_version,
+		      cfg_default(CFG_MFR_PRODUCT_VERSION),
+		      sizeof(product_details->manufacture_product_version));
+	qdf_str_lcopy(product_details->model_name,
+		      cfg_default(CFG_MODEL_NAME),
+		      sizeof(product_details->model_name));
+	qdf_str_lcopy(product_details->model_number,
+		      cfg_default(CFG_MODEL_NUMBER),
+		      sizeof(product_details->model_number));
+}
+
+static void mlme_init_sta_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_mlme_sta_cfg *sta)
+{
+	sta->sta_keep_alive_period =
+		cfg_get(psoc, CFG_INFRA_STA_KEEP_ALIVE_PERIOD);
+	sta->tgt_gtx_usr_cfg =
+		cfg_get(psoc, CFG_TGT_GTX_USR_CFG);
+	sta->pmkid_modes =
+		cfg_get(psoc, CFG_PMKID_MODES);
+	sta->ignore_peer_erp_info =
+		cfg_get(psoc, CFG_IGNORE_PEER_ERP_INFO);
+	sta->sta_prefer_80mhz_over_160mhz =
+		cfg_get(psoc, CFG_STA_PREFER_80MHZ_OVER_160MHZ);
+	sta->enable_5g_ebt =
+		cfg_get(psoc, CFG_PPS_ENABLE_5G_EBT);
+	sta->deauth_before_connection =
+		cfg_get(psoc, CFG_ENABLE_DEAUTH_BEFORE_CONNECTION);
+	sta->dot11p_mode =
+		cfg_get(psoc, CFG_DOT11P_MODE);
+	sta->enable_go_cts2self_for_sta =
+		cfg_get(psoc, CFG_ENABLE_GO_CTS2SELF_FOR_STA);
+	sta->qcn_ie_support =
+		cfg_get(psoc, CFG_QCN_IE_SUPPORT);
+	sta->fils_max_chan_guard_time =
+		cfg_get(psoc, CFG_FILS_MAX_CHAN_GUARD_TIME);
+	sta->force_rsne_override =
+		cfg_get(psoc, CFG_FORCE_RSNE_OVERRIDE);
+	sta->single_tid =
+		cfg_get(psoc, CFG_SINGLE_TID_RC);
+	sta->wait_cnf_timeout =
+		(uint32_t)cfg_default(CFG_WT_CNF_TIMEOUT);
+	sta->current_rssi =
+		(uint32_t)cfg_default(CFG_CURRENT_RSSI);
+}
+
+static void mlme_init_lfr_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_mlme_lfr_cfg *lfr)
+{
+	lfr->mawc_roam_enabled =
+		cfg_get(psoc, CFG_LFR_MAWC_ROAM_ENABLED);
+	lfr->enable_fast_roam_in_concurrency =
+		cfg_get(psoc, CFG_LFR_ENABLE_FAST_ROAM_IN_CONCURRENCY);
+	lfr->lfr3_roaming_offload =
+		cfg_get(psoc, CFG_LFR3_ROAMING_OFFLOAD);
+	lfr->early_stop_scan_enable =
+		cfg_get(psoc, CFG_LFR_EARLY_STOP_SCAN_ENABLE);
+	lfr->lfr3_enable_subnet_detection =
+		cfg_get(psoc, CFG_LFR3_ENABLE_SUBNET_DETECTION);
+	lfr->enable_5g_band_pref =
+		cfg_get(psoc, CFG_LFR_ENABLE_5G_BAND_PREF);
+	lfr->mawc_roam_traffic_threshold =
+		cfg_get(psoc, CFG_LFR_MAWC_ROAM_TRAFFIC_THRESHOLD);
+	lfr->mawc_roam_ap_rssi_threshold =
+		cfg_get(psoc, CFG_LFR_MAWC_ROAM_AP_RSSI_THRESHOLD);
+	lfr->mawc_roam_rssi_high_adjust =
+		cfg_get(psoc, CFG_LFR_MAWC_ROAM_RSSI_HIGH_ADJUST);
+	lfr->mawc_roam_rssi_low_adjust =
+		cfg_get(psoc, CFG_LFR_MAWC_ROAM_RSSI_LOW_ADJUST);
+	lfr->roam_rssi_abs_threshold =
+		cfg_get(psoc, CFG_LFR_ROAM_RSSI_ABS_THRESHOLD);
+	lfr->rssi_threshold_offset_5g =
+		cfg_get(psoc, CFG_LFR_5G_RSSI_THRESHOLD_OFFSET);
+	lfr->early_stop_scan_min_threshold =
+		cfg_get(psoc, CFG_LFR_EARLY_STOP_SCAN_MIN_THRESHOLD);
+	lfr->early_stop_scan_max_threshold =
+		cfg_get(psoc, CFG_LFR_EARLY_STOP_SCAN_MAX_THRESHOLD);
+	lfr->first_scan_bucket_threshold =
+		cfg_get(psoc, CFG_LFR_FIRST_SCAN_BUCKET_THRESHOLD);
+	lfr->roam_dense_traffic_threshold =
+		cfg_get(psoc, CFG_LFR_ROAM_DENSE_TRAFFIC_THRESHOLD);
+	lfr->roam_dense_rssi_thre_offset =
+		cfg_get(psoc, CFG_LFR_ROAM_DENSE_RSSI_THRE_OFFSET);
+	lfr->roam_dense_min_aps =
+		cfg_get(psoc, CFG_LFR_ROAM_DENSE_MIN_APS);
+	lfr->roam_bg_scan_bad_rssi_threshold =
+		cfg_get(psoc, CFG_LFR_ROAM_BG_SCAN_BAD_RSSI_THRESHOLD);
+	lfr->roam_bg_scan_client_bitmap =
+		cfg_get(psoc, CFG_LFR_ROAM_BG_SCAN_CLIENT_BITMAP);
+	lfr->roam_bg_scan_bad_rssi_offset_2g =
+		cfg_get(psoc, CFG_LFR_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G);
+	lfr->adaptive_roamscan_dwell_mode =
+		cfg_get(psoc, CFG_LFR_ADAPTIVE_ROAMSCAN_DWELL_MODE);
+	lfr->per_roam_enable =
+		cfg_get(psoc, CFG_LFR_PER_ROAM_ENABLE);
+	lfr->per_roam_config_high_rate_th =
+		cfg_get(psoc, CFG_LFR_PER_ROAM_CONFIG_HIGH_RATE_TH);
+	lfr->per_roam_config_low_rate_th =
+		cfg_get(psoc, CFG_LFR_PER_ROAM_CONFIG_LOW_RATE_TH);
+	lfr->per_roam_config_rate_th_percent =
+		cfg_get(psoc, CFG_LFR_PER_ROAM_CONFIG_RATE_TH_PERCENT);
+	lfr->per_roam_rest_time =
+		cfg_get(psoc, CFG_LFR_PER_ROAM_REST_TIME);
+	lfr->per_roam_monitor_time =
+		cfg_get(psoc, CFG_LFR_PER_ROAM_MONITOR_TIME);
+	lfr->per_roam_min_candidate_rssi =
+		cfg_get(psoc, CFG_LFR_PER_ROAM_MIN_CANDIDATE_RSSI);
+	lfr->lfr3_disallow_duration =
+		cfg_get(psoc, CFG_LFR3_ROAM_DISALLOW_DURATION);
+	lfr->lfr3_rssi_channel_penalization =
+		cfg_get(psoc, CFG_LFR3_ROAM_RSSI_CHANNEL_PENALIZATION);
+	lfr->lfr3_num_disallowed_aps =
+		cfg_get(psoc, CFG_LFR3_ROAM_NUM_DISALLOWED_APS);
+	lfr->rssi_boost_threshold_5g =
+		cfg_get(psoc, CFG_LFR_5G_RSSI_BOOST_THRESHOLD);
+	lfr->rssi_boost_factor_5g =
+		cfg_get(psoc, CFG_LFR_5G_RSSI_BOOST_FACTOR);
+	lfr->max_rssi_boost_5g =
+		cfg_get(psoc, CFG_LFR_5G_MAX_RSSI_BOOST);
+	lfr->rssi_penalize_threshold_5g =
+		cfg_get(psoc, CFG_LFR_5G_RSSI_PENALIZE_THRESHOLD);
+	lfr->rssi_penalize_factor_5g =
+		cfg_get(psoc, CFG_LFR_5G_RSSI_PENALIZE_FACTOR);
+	lfr->max_rssi_penalize_5g =
+		cfg_get(psoc, CFG_LFR_5G_MAX_RSSI_PENALIZE);
+	lfr->max_num_pre_auth = (uint32_t)
+		cfg_default(CFG_LFR_MAX_NUM_PRE_AUTH);
+	lfr->roam_preauth_no_ack_timeout =
+		cfg_get(psoc, CFG_LFR3_ROAM_PREAUTH_NO_ACK_TIMEOUT);
+	lfr->roam_preauth_retry_count =
+		cfg_get(psoc, CFG_LFR3_ROAM_PREAUTH_RETRY_COUNT);
+}
+
+static uint32_t
+mlme_limit_max_per_index_score(uint32_t per_index_score)
+{
+	uint8_t i, score;
+
+	for (i = 0; i < MAX_INDEX_PER_INI; i++) {
+		score = WLAN_GET_SCORE_PERCENTAGE(per_index_score, i);
+		if (score > MAX_INDEX_SCORE)
+			WLAN_SET_SCORE_PERCENTAGE(per_index_score,
+				MAX_INDEX_SCORE, i);
+	}
+
+	return per_index_score;
+}
+
+static void mlme_init_scoring_cfg(struct wlan_objmgr_psoc *psoc,
+				  struct wlan_mlme_scoring_cfg *scoring_cfg)
+{
+	uint32_t total_weight;
+
+	scoring_cfg->enable_scoring_for_roam =
+		cfg_get(psoc, CFG_ENABLE_SCORING_FOR_ROAM);
+	scoring_cfg->weight_cfg.rssi_weightage =
+		cfg_get(psoc, CFG_SCORING_RSSI_WEIGHTAGE);
+	scoring_cfg->weight_cfg.ht_caps_weightage =
+		cfg_get(psoc, CFG_SCORING_HT_CAPS_WEIGHTAGE);
+	scoring_cfg->weight_cfg.vht_caps_weightage =
+		cfg_get(psoc, CFG_SCORING_VHT_CAPS_WEIGHTAGE);
+	scoring_cfg->weight_cfg.he_caps_weightage =
+		cfg_get(psoc, CFG_SCORING_HE_CAPS_WEIGHTAGE);
+	scoring_cfg->weight_cfg.chan_width_weightage =
+		cfg_get(psoc, CFG_SCORING_CHAN_WIDTH_WEIGHTAGE);
+	scoring_cfg->weight_cfg.chan_band_weightage =
+		cfg_get(psoc, CFG_SCORING_CHAN_BAND_WEIGHTAGE);
+	scoring_cfg->weight_cfg.nss_weightage =
+		cfg_get(psoc, CFG_SCORING_NSS_WEIGHTAGE);
+	scoring_cfg->weight_cfg.beamforming_cap_weightage =
+		cfg_get(psoc, CFG_SCORING_BEAMFORM_CAP_WEIGHTAGE);
+	scoring_cfg->weight_cfg.pcl_weightage =
+		cfg_get(psoc, CFG_SCORING_PCL_WEIGHTAGE);
+	scoring_cfg->weight_cfg.channel_congestion_weightage =
+		cfg_get(psoc, CFG_SCORING_CHAN_CONGESTION_WEIGHTAGE);
+	scoring_cfg->weight_cfg.oce_wan_weightage =
+		cfg_get(psoc, CFG_SCORING_OCE_WAN_WEIGHTAGE);
+
+	total_weight = scoring_cfg->enable_scoring_for_roam +
+			scoring_cfg->weight_cfg.rssi_weightage +
+			scoring_cfg->weight_cfg.ht_caps_weightage +
+			scoring_cfg->weight_cfg.vht_caps_weightage +
+			scoring_cfg->weight_cfg.he_caps_weightage +
+			scoring_cfg->weight_cfg.chan_width_weightage +
+			scoring_cfg->weight_cfg.chan_band_weightage +
+			scoring_cfg->weight_cfg.nss_weightage +
+			scoring_cfg->weight_cfg.beamforming_cap_weightage +
+			scoring_cfg->weight_cfg.pcl_weightage +
+			scoring_cfg->weight_cfg.channel_congestion_weightage +
+			scoring_cfg->weight_cfg.oce_wan_weightage;
+
+	/*
+	 * If configured weights are greater than max weight,
+	 * fallback to default weights
+	 */
+	if (total_weight > BEST_CANDIDATE_MAX_WEIGHT) {
+		mlme_err("Total weight greater than %d, using default weights",
+			 BEST_CANDIDATE_MAX_WEIGHT);
+		scoring_cfg->weight_cfg.rssi_weightage = RSSI_WEIGHTAGE;
+		scoring_cfg->weight_cfg.ht_caps_weightage =
+						HT_CAPABILITY_WEIGHTAGE;
+		scoring_cfg->weight_cfg.vht_caps_weightage =
+						VHT_CAP_WEIGHTAGE;
+		scoring_cfg->weight_cfg.he_caps_weightage = HE_CAP_WEIGHTAGE;
+		scoring_cfg->weight_cfg.chan_width_weightage =
+						CHAN_WIDTH_WEIGHTAGE;
+		scoring_cfg->weight_cfg.chan_band_weightage =
+						CHAN_BAND_WEIGHTAGE;
+		scoring_cfg->weight_cfg.nss_weightage = NSS_WEIGHTAGE;
+		scoring_cfg->weight_cfg.beamforming_cap_weightage =
+						BEAMFORMING_CAP_WEIGHTAGE;
+		scoring_cfg->weight_cfg.pcl_weightage = PCL_WEIGHT;
+		scoring_cfg->weight_cfg.channel_congestion_weightage =
+						CHANNEL_CONGESTION_WEIGHTAGE;
+		scoring_cfg->weight_cfg.oce_wan_weightage = OCE_WAN_WEIGHTAGE;
+	}
+
+	scoring_cfg->rssi_score.best_rssi_threshold =
+		cfg_get(psoc, CFG_SCORING_BEST_RSSI_THRESHOLD);
+	scoring_cfg->rssi_score.good_rssi_threshold =
+		cfg_get(psoc, CFG_SCORING_GOOD_RSSI_THRESHOLD);
+	scoring_cfg->rssi_score.bad_rssi_threshold =
+		cfg_get(psoc, CFG_SCORING_BAD_RSSI_THRESHOLD);
+
+	scoring_cfg->rssi_score.good_rssi_pcnt =
+		cfg_get(psoc, CFG_SCORING_GOOD_RSSI_PERCENT);
+	scoring_cfg->rssi_score.bad_rssi_pcnt =
+		cfg_get(psoc, CFG_SCORING_BAD_RSSI_PERCENT);
+
+	scoring_cfg->rssi_score.good_rssi_bucket_size =
+		cfg_get(psoc, CFG_SCORING_GOOD_RSSI_BUCKET_SIZE);
+	scoring_cfg->rssi_score.bad_rssi_bucket_size =
+		cfg_get(psoc, CFG_SCORING_BAD_RSSI_BUCKET_SIZE);
+
+	scoring_cfg->rssi_score.rssi_pref_5g_rssi_thresh =
+		cfg_get(psoc, CFG_SCORING_RSSI_PREF_5G_THRESHOLD);
+
+	scoring_cfg->bandwidth_weight_per_index =
+		mlme_limit_max_per_index_score(
+			cfg_get(psoc, CFG_SCORING_BW_WEIGHT_PER_IDX));
+	scoring_cfg->nss_weight_per_index =
+		mlme_limit_max_per_index_score(
+			cfg_get(psoc, CFG_SCORING_NSS_WEIGHT_PER_IDX));
+	scoring_cfg->band_weight_per_index =
+		mlme_limit_max_per_index_score(
+			cfg_get(psoc, CFG_SCORING_BAND_WEIGHT_PER_IDX));
+
+	scoring_cfg->esp_qbss_scoring.num_slot =
+		cfg_get(psoc, CFG_SCORING_NUM_ESP_QBSS_SLOTS);
+	scoring_cfg->esp_qbss_scoring.score_pcnt3_to_0 =
+		mlme_limit_max_per_index_score(
+			cfg_get(psoc, CFG_SCORING_ESP_QBSS_SCORE_IDX_3_TO_0));
+	scoring_cfg->esp_qbss_scoring.score_pcnt7_to_4 =
+		mlme_limit_max_per_index_score(
+			cfg_get(psoc, CFG_SCORING_ESP_QBSS_SCORE_IDX_7_TO_4));
+	scoring_cfg->esp_qbss_scoring.score_pcnt11_to_8 =
+		mlme_limit_max_per_index_score(
+			cfg_get(psoc, CFG_SCORING_ESP_QBSS_SCORE_IDX_11_TO_8));
+	scoring_cfg->esp_qbss_scoring.score_pcnt15_to_12 =
+		mlme_limit_max_per_index_score(
+			cfg_get(psoc, CFG_SCORING_ESP_QBSS_SCORE_IDX_15_TO_12));
+
+	scoring_cfg->oce_wan_scoring.num_slot =
+		cfg_get(psoc, CFG_SCORING_NUM_OCE_WAN_SLOTS);
+	scoring_cfg->oce_wan_scoring.score_pcnt3_to_0 =
+		mlme_limit_max_per_index_score(
+			cfg_get(psoc, CFG_SCORING_OCE_WAN_SCORE_IDX_3_TO_0));
+	scoring_cfg->oce_wan_scoring.score_pcnt7_to_4 =
+		mlme_limit_max_per_index_score(
+			cfg_get(psoc, CFG_SCORING_OCE_WAN_SCORE_IDX_7_TO_4));
+	scoring_cfg->oce_wan_scoring.score_pcnt11_to_8 =
+		mlme_limit_max_per_index_score(
+			cfg_get(psoc, CFG_SCORING_OCE_WAN_SCORE_IDX_11_TO_8));
+	scoring_cfg->oce_wan_scoring.score_pcnt15_to_12 =
+		mlme_limit_max_per_index_score(
+			cfg_get(psoc, CFG_SCORING_OCE_WAN_SCORE_IDX_15_TO_12));
+}
+
+static void mlme_init_oce_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_mlme_oce *oce)
+{
+	uint8_t val;
+	bool rssi_assoc_reject_enabled;
+	bool probe_req_rate_enabled;
+	bool probe_resp_rate_enabled;
+	bool beacon_rate_enabled;
+	bool probe_req_deferral_enabled;
+	bool fils_discovery_sap_enabled;
+	bool esp_for_roam_enabled;
+
+	oce->enable_bcast_probe_rsp =
+		cfg_get(psoc, CFG_ENABLE_BCAST_PROBE_RESP);
+	oce->oce_sta_enabled = cfg_get(psoc, CFG_OCE_ENABLE_STA);
+	oce->oce_sap_enabled = cfg_get(psoc, CFG_OCE_ENABLE_SAP);
+	oce->fils_enabled = cfg_get(psoc, CFG_IS_FILS_ENABLED);
+
+	rssi_assoc_reject_enabled =
+		cfg_get(psoc, CFG_OCE_ENABLE_RSSI_BASED_ASSOC_REJECT);
+	probe_req_rate_enabled = cfg_get(psoc, CFG_OCE_PROBE_REQ_RATE);
+	probe_resp_rate_enabled = cfg_get(psoc, CFG_OCE_PROBE_RSP_RATE);
+	beacon_rate_enabled = cfg_get(psoc, CFG_OCE_BEACON_RATE);
+	probe_req_deferral_enabled =
+		cfg_get(psoc, CFG_ENABLE_PROBE_REQ_DEFERRAL);
+	fils_discovery_sap_enabled =
+		cfg_get(psoc, CFG_ENABLE_FILS_DISCOVERY_SAP);
+	esp_for_roam_enabled = cfg_get(psoc, CFG_ENABLE_ESP_FEATURE);
+
+	if (!rssi_assoc_reject_enabled ||
+	    !oce->enable_bcast_probe_rsp) {
+		oce->oce_sta_enabled = 0;
+	}
+
+	val = (probe_req_rate_enabled *
+	WMI_VDEV_OCE_PROBE_REQUEST_RATE_FEATURE_BITMAP) +
+	(probe_resp_rate_enabled *
+	WMI_VDEV_OCE_PROBE_RESPONSE_RATE_FEATURE_BITMAP) +
+	(beacon_rate_enabled *
+	WMI_VDEV_OCE_BEACON_RATE_FEATURE_BITMAP) +
+	(probe_req_deferral_enabled *
+	 WMI_VDEV_OCE_PROBE_REQUEST_DEFERRAL_FEATURE_BITMAP) +
+	(fils_discovery_sap_enabled *
+	 WMI_VDEV_OCE_FILS_DISCOVERY_FRAME_FEATURE_BITMAP) +
+	(esp_for_roam_enabled *
+	 WMI_VDEV_OCE_ESP_FEATURE_BITMAP) +
+	(rssi_assoc_reject_enabled *
+	 WMI_VDEV_OCE_REASSOC_REJECT_FEATURE_BITMAP);
+	oce->feature_bitmap = val;
+}
+
+static void mlme_init_wep_keys(struct wlan_mlme_wep_cfg *wep_params)
+{
+	/* initialize the default key values to zero */
+	wep_params->wep_default_key_1.len = MLME_WEP_KEY_LEN_13;
+	wep_params->wep_default_key_1.max_len = MLME_WEP_KEY_LEN_13;
+	qdf_mem_zero(wep_params->wep_default_key_1.data, MLME_WEP_KEY_LEN_13);
+
+	wep_params->wep_default_key_2.len = MLME_WEP_KEY_LEN_13;
+	wep_params->wep_default_key_2.max_len = MLME_WEP_KEY_LEN_13;
+	qdf_mem_zero(wep_params->wep_default_key_2.data, MLME_WEP_KEY_LEN_13);
+
+	wep_params->wep_default_key_3.len = MLME_WEP_KEY_LEN_13;
+	wep_params->wep_default_key_3.max_len = MLME_WEP_KEY_LEN_13;
+	qdf_mem_zero(wep_params->wep_default_key_3.data, MLME_WEP_KEY_LEN_13);
+
+	wep_params->wep_default_key_4.len = MLME_WEP_KEY_LEN_13;
+	wep_params->wep_default_key_4.max_len = MLME_WEP_KEY_LEN_13;
+	qdf_mem_zero(wep_params->wep_default_key_4.data, MLME_WEP_KEY_LEN_13);
+}
+
+static void mlme_init_wep_cfg(struct wlan_mlme_wep_cfg *wep_params)
+{
+	wep_params->is_privacy_enabled = cfg_default(CFG_PRIVACY_ENABLED);
+	wep_params->auth_type = cfg_default(CFG_AUTHENTICATION_TYPE);
+	wep_params->is_shared_key_auth =
+			cfg_default(CFG_SHARED_KEY_AUTH_ENABLE);
+	wep_params->is_auth_open_system =
+			cfg_default(CFG_OPEN_SYSTEM_AUTH_ENABLE);
+
+	wep_params->wep_default_key_id = cfg_default(CFG_WEP_DEFAULT_KEYID);
+	mlme_init_wep_keys(wep_params);
+}
+
+static void mlme_init_wmm_in_cfg(struct wlan_objmgr_psoc *psoc,
+				 struct wlan_mlme_wmm_params *wmm_params)
+{
+	wmm_params->qos_enabled = cfg_default(CFG_QOS_ENABLED);
+	wmm_params->wme_enabled = cfg_default(CFG_WME_ENABLED);
+	wmm_params->max_sp_length = cfg_default(CFG_MAX_SP_LENGTH);
+	wmm_params->wsm_enabled = cfg_default(CFG_WSM_ENABLED);
+	wmm_params->edca_profile = cfg_default(CFG_EDCA_PROFILE);
+
+	wmm_params->ac_vo.dir_ac_vo = cfg_get(psoc, CFG_QOS_WMM_DIR_AC_VO);
+	wmm_params->ac_vo.nom_msdu_size_ac_vo =
+			cfg_get(psoc, CFG_QOS_WMM_NOM_MSDU_SIZE_AC_VO);
+	wmm_params->ac_vo.mean_data_rate_ac_vo =
+			cfg_get(psoc, CFG_QOS_WMM_MEAN_DATA_RATE_AC_VO);
+	wmm_params->ac_vo.min_phy_rate_ac_vo =
+			cfg_get(psoc, CFG_QOS_WMM_MIN_PHY_RATE_AC_VO);
+	wmm_params->ac_vo.sba_ac_vo = cfg_get(psoc, CFG_QOS_WMM_SBA_AC_VO);
+	wmm_params->ac_vo.uapsd_vo_srv_intv =
+			cfg_get(psoc, CFG_QOS_WMM_UAPSD_VO_SRV_INTV);
+	wmm_params->ac_vo.uapsd_vo_sus_intv =
+			cfg_get(psoc, CFG_QOS_WMM_UAPSD_VO_SUS_INTV);
+
+	wmm_params->ac_vi.dir_ac_vi =
+		cfg_get(psoc, CFG_QOS_WMM_DIR_AC_VI);
+	wmm_params->ac_vi.nom_msdu_size_ac_vi =
+		cfg_get(psoc, CFG_QOS_WMM_NOM_MSDU_SIZE_AC_VI);
+	wmm_params->ac_vi.mean_data_rate_ac_vi =
+		cfg_get(psoc, CFG_QOS_WMM_MEAN_DATA_RATE_AC_VI);
+	wmm_params->ac_vi.min_phy_rate_ac_vi =
+		cfg_get(psoc, CFG_QOS_WMM_MIN_PHY_RATE_AC_VI);
+	wmm_params->ac_vi.sba_ac_vi =
+		cfg_get(psoc, CFG_QOS_WMM_SBA_AC_VI);
+	wmm_params->ac_vi.uapsd_vi_srv_intv =
+		cfg_get(psoc, CFG_QOS_WMM_UAPSD_VI_SRV_INTV);
+	wmm_params->ac_vi.uapsd_vi_sus_intv =
+		cfg_get(psoc, CFG_QOS_WMM_UAPSD_VI_SUS_INTV);
+
+	wmm_params->ac_be.dir_ac_be =
+		cfg_get(psoc, CFG_QOS_WMM_DIR_AC_BE);
+	wmm_params->ac_be.nom_msdu_size_ac_be =
+		cfg_get(psoc, CFG_QOS_WMM_NOM_MSDU_SIZE_AC_BE);
+	wmm_params->ac_be.mean_data_rate_ac_be =
+		cfg_get(psoc, CFG_QOS_WMM_MEAN_DATA_RATE_AC_BE);
+	wmm_params->ac_be.min_phy_rate_ac_be =
+		cfg_get(psoc, CFG_QOS_WMM_MIN_PHY_RATE_AC_BE);
+	wmm_params->ac_be.sba_ac_be =
+		cfg_get(psoc, CFG_QOS_WMM_SBA_AC_BE);
+	wmm_params->ac_be.uapsd_be_srv_intv =
+		cfg_get(psoc, CFG_QOS_WMM_UAPSD_BE_SRV_INTV);
+	wmm_params->ac_be.uapsd_be_sus_intv =
+		cfg_get(psoc, CFG_QOS_WMM_UAPSD_BE_SUS_INTV);
+
+	wmm_params->ac_bk.dir_ac_bk =
+		cfg_get(psoc, CFG_QOS_WMM_DIR_AC_BK);
+	wmm_params->ac_bk.nom_msdu_size_ac_bk =
+		cfg_get(psoc, CFG_QOS_WMM_NOM_MSDU_SIZE_AC_BK);
+	wmm_params->ac_bk.mean_data_rate_ac_bk =
+		cfg_get(psoc, CFG_QOS_WMM_MEAN_DATA_RATE_AC_BK);
+	wmm_params->ac_bk.min_phy_rate_ac_bk =
+		cfg_get(psoc, CFG_QOS_WMM_MIN_PHY_RATE_AC_BK);
+	wmm_params->ac_bk.sba_ac_bk =
+		cfg_get(psoc, CFG_QOS_WMM_SBA_AC_BK);
+	wmm_params->ac_bk.uapsd_bk_srv_intv =
+		cfg_get(psoc, CFG_QOS_WMM_UAPSD_BK_SRV_INTV);
+	wmm_params->ac_bk.uapsd_bk_sus_intv =
+		cfg_get(psoc, CFG_QOS_WMM_UAPSD_BK_SUS_INTV);
+
+	wmm_params->wmm_config.wmm_mode =
+		cfg_get(psoc, CFG_QOS_WMM_MODE);
+	wmm_params->wmm_config.b80211e_is_enabled =
+		cfg_get(psoc, CFG_QOS_WMM_80211E_ENABLED);
+	wmm_params->wmm_config.uapsd_mask =
+		cfg_get(psoc, CFG_QOS_WMM_UAPSD_MASK);
+	wmm_params->wmm_config.bimplicit_qos_enabled =
+		cfg_get(psoc, CFG_QOS_WMM_IMPLICIT_SETUP_ENABLED);
+}
+
+static void mlme_init_wps_params_cfg(struct wlan_objmgr_psoc *psoc,
+				     struct wlan_mlme_wps_params *wps_params)
+{
+	wps_params->enable_wps = cfg_default(CFG_WPS_ENABLE);
+	wps_params->wps_cfg_method = cfg_default(CFG_WPS_CFG_METHOD);
+	wps_params->wps_device_password_id =
+				cfg_default(CFG_WPS_DEVICE_PASSWORD_ID);
+	wps_params->wps_device_sub_category =
+				cfg_default(CFG_WPS_DEVICE_SUB_CATEGORY);
+	wps_params->wps_primary_device_category =
+				cfg_default(CFG_WPS_PRIMARY_DEVICE_CATEGORY);
+	wps_params->wps_primary_device_oui =
+				cfg_default(CFG_WPS_PIMARY_DEVICE_OUI);
+	wps_params->wps_state = cfg_default(CFG_WPS_STATE);
+	wps_params->wps_version = cfg_default(CFG_WPS_VERSION);
+}
+
+QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+	struct wlan_mlme_cfg *mlme_cfg;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_cfg = &mlme_obj->cfg;
+	mlme_init_generic_cfg(psoc, &mlme_cfg->gen);
+	mlme_init_timeout_cfg(psoc, &mlme_cfg->timeouts);
+	mlme_init_edca_params(psoc, &mlme_cfg->edca_params);
+	mlme_init_ht_cap_in_cfg(psoc, &mlme_cfg->ht_caps);
+	mlme_init_wmm_in_cfg(psoc, &mlme_cfg->wmm_params);
+	mlme_init_mbo_cfg(psoc, &mlme_cfg->mbo_cfg);
+	mlme_init_qos_cfg(psoc, &mlme_cfg->qos_mlme_params);
+	mlme_init_rates_in_cfg(psoc, &mlme_cfg->rates);
+	mlme_init_dfs_cfg(psoc, &mlme_cfg->dfs_cfg);
+	mlme_init_sap_protection_cfg(psoc, &mlme_cfg->sap_protection_cfg);
+	mlme_init_vht_cap_cfg(psoc, &mlme_cfg->vht_caps.vht_cap_info);
+	mlme_init_chainmask_cfg(psoc, &mlme_cfg->chainmask_cfg);
+	mlme_init_sap_cfg(psoc, &mlme_cfg->sap_cfg);
+	mlme_init_he_cap_in_cfg(psoc, &mlme_cfg->he_caps);
+	mlme_init_obss_ht40_cfg(psoc, &mlme_cfg->obss_ht40);
+	mlme_init_product_details_cfg(&mlme_cfg->product_details);
+	mlme_init_sta_cfg(psoc, &mlme_cfg->sta);
+	mlme_init_lfr_cfg(psoc, &mlme_cfg->lfr);
+	mlme_init_feature_flag_in_cfg(psoc, &mlme_cfg->feature_flags);
+	mlme_init_scoring_cfg(psoc, &mlme_cfg->scoring);
+	mlme_init_threshold_cfg(psoc, &mlme_cfg->threshold);
+	mlme_init_acs_cfg(psoc, &mlme_cfg->acs);
+	mlme_init_oce_cfg(psoc, &mlme_cfg->oce);
+	mlme_init_wep_cfg(&mlme_cfg->wep_params);
+	mlme_init_wps_params_cfg(psoc, &mlme_cfg->wps_params);
+
+	return status;
+}
diff --git a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c
new file mode 100644
index 0000000..8a3f869
--- /dev/null
+++ b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c
@@ -0,0 +1,766 @@
+/*
+ * Copyright (c) 2018 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 internal APIs related to the mlme component
+ */
+#include "wlan_mlme_main.h"
+#include "wlan_mlme_vdev_mgr_interface.h"
+#include "lim_utils.h"
+#include "wma_api.h"
+#include "lim_types.h"
+
+static struct vdev_mlme_ops sta_mlme_ops;
+static struct vdev_mlme_ops ap_mlme_ops;
+
+bool mlme_is_vdev_in_beaconning_mode(enum QDF_OPMODE vdev_opmode)
+{
+	switch (vdev_opmode) {
+	case QDF_SAP_MODE:
+	case QDF_P2P_GO_MODE:
+	case QDF_IBSS_MODE:
+	case QDF_NDI_MODE:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/**
+ * mlme_register_vdev_mgr_ops() - Register vdev mgr ops
+ * @vdev_mlme: vdev mlme object
+ *
+ * This function is called to register vdev manager operations
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_register_vdev_mgr_ops(void *mlme)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)mlme;
+
+	vdev = vdev_mlme->vdev;
+
+	if (mlme_is_vdev_in_beaconning_mode(vdev->vdev_mlme.vdev_opmode))
+		vdev_mlme->ops = &ap_mlme_ops;
+	else
+		vdev_mlme->ops = &sta_mlme_ops;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * mlme_unregister_vdev_mgr_ops() - Unregister vdev mgr ops
+ * @vdev_mlme: vdev mlme object
+ *
+ * This function is called to unregister vdev manager operations
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_unregister_vdev_mgr_ops(struct vdev_mlme_obj *vdev_mlme)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sta_mlme_vdev_start_send() - MLME vdev start callback
+ * @vdev_mlme: vdev mlme object
+ * @event_data_len: event data length
+ * @event_data: event data
+ *
+ * This function is called to initiate actions of VDEV.start
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sta_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
+					   uint16_t event_data_len,
+					   void *event_data)
+{
+	return lim_sta_mlme_vdev_start_send(vdev_mlme, event_data_len,
+					    event_data);
+}
+
+/**
+ * sta_mlme_start_continue() - vdev start rsp calback
+ * @vdev_mlme: vdev mlme object
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to handle the VDEV START/RESTART calback
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sta_mlme_start_continue(struct vdev_mlme_obj *vdev_mlme,
+					  uint16_t data_len, void *data)
+{
+	return wma_sta_mlme_vdev_start_continue(vdev_mlme, data_len, data);
+}
+
+/**
+ * sta_mlme_vdev_restart_send() - MLME vdev restart send
+ * @vdev_mlme: vdev mlme object
+ * @event_data_len: event data length
+ * @event_data: event data
+ *
+ * This function is called to initiate actions of VDEV.start
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sta_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
+					     uint16_t event_data_len,
+					     void *event_data)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sta_mlme_vdev_start_connection() - MLME vdev start callback
+ * @vdev_mlme: vdev mlme object
+ * @event_data_len: event data length
+ * @event_data: event data
+ *
+ * This function is called to initiate actions of STA connection
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sta_mlme_vdev_start_connection(struct vdev_mlme_obj *vdev_mlme,
+						 uint16_t event_data_len,
+						 void *event_data)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sta_mlme_vdev_up_send() - MLME vdev UP callback
+ * @vdev_mlme: vdev mlme object
+ * @event_data_len: event data length
+ * @event_data: event data
+ *
+ * This function is called to send the vdev up command
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sta_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
+					uint16_t event_data_len,
+					void *event_data)
+{
+	return wma_sta_vdev_up_send(vdev_mlme, event_data_len, event_data);
+}
+
+/**
+ * sta_mlme_vdev_notify_up_complete() - MLME vdev UP complete callback
+ * @vdev_mlme: vdev mlme object
+ * @event_data_len: event data length
+ * @event_data: event data
+ *
+ * This function is called to VDEV MLME on moving
+ *  to UP state
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sta_mlme_vdev_notify_up_complete(struct vdev_mlme_obj *vdev_mlme,
+						   uint16_t event_data_len,
+						   void *event_data)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sta_mlme_vdev_disconnect_bss() - MLME vdev disconnect bss callback
+ * @vdev_mlme: vdev mlme object
+ * @event_data_len: event data length
+ * @event_data: event data
+ *
+ * This function is called to disconnect BSS/send deauth to AP
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sta_mlme_vdev_disconnect_bss(struct vdev_mlme_obj *vdev_mlme,
+					       uint16_t event_data_len,
+					       void *event_data)
+{
+	return lim_sta_mlme_vdev_disconnect_bss(vdev_mlme, event_data_len,
+						event_data);
+}
+
+/**
+ * sta_mlme_vdev_stop_send() - MLME vdev stop send callback
+ * @vdev_mlme: vdev mlme object
+ * @event_data_len: event data length
+ * @event_data: event data
+ *
+ * This function is called to send the vdev stop to firmware
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sta_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
+					  uint16_t data_len,
+					  void *data)
+{
+	return lim_sta_mlme_vdev_stop_send(vdev_mlme, data_len, data);
+}
+
+/**
+ * vdevmgr_mlme_stop_continue() - MLME vdev stop send callback
+ * @vdev_mlme: vdev mlme object
+ * @event_data_len: event data length
+ * @event_data: event data
+ *
+ * This function is called to initiate operations on
+ * LMAC/FW stop response such as remove peer.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS vdevmgr_mlme_stop_continue(struct vdev_mlme_obj *vdev_mlme,
+					     uint16_t data_len,
+					     void *data)
+{
+	return wma_mlme_vdev_stop_continue(vdev_mlme, data_len, data);
+}
+
+/**
+ * ap_mlme_vdev_start_send () - send vdev start req
+ * @vdev_mlme: vdev mlme object
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to initiate actions of VDEV start ie start bss
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ap_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
+					  uint16_t data_len, void *data)
+{
+	return lim_ap_mlme_vdev_start_send(vdev_mlme, data_len, data);
+}
+
+/**
+ * ap_start_continue () - vdev start rsp calback
+ * @vdev_mlme: vdev mlme object
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to handle the VDEV START/RESTART calback
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ap_mlme_start_continue(struct vdev_mlme_obj *vdev_mlme,
+					 uint16_t data_len, void *data)
+{
+	return wma_ap_mlme_vdev_start_continue(vdev_mlme, data_len, data);
+}
+
+/**
+ * ap_mlme_vdev_update_beacon() - callback to initiate beacon update
+ * @vdev_mlme: vdev mlme object
+ * @op: beacon operation
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to update beacon
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ap_mlme_vdev_update_beacon(struct vdev_mlme_obj *vdev_mlme,
+					     enum beacon_update_op op,
+					     uint16_t data_len, void *data)
+{
+	return lim_ap_mlme_vdev_update_beacon(vdev_mlme, op, data_len, data);
+}
+
+/**
+ * ap_mlme_vdev_up_send() - callback to send vdev up
+ * @vdev_mlme: vdev mlme object
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to send vdev up req
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ap_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
+				       uint16_t data_len, void *data)
+{
+	return lim_ap_mlme_vdev_up_send(vdev_mlme, data_len, data);
+}
+
+/**
+ * ap_mlme_vdev_notify_up_complete() - callback to notify up completion
+ * @vdev_mlme: vdev mlme object
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to indicate up is completed
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+ap_mlme_vdev_notify_up_complete(struct vdev_mlme_obj *vdev_mlme,
+				uint16_t data_len, void *data)
+{
+	if (!vdev_mlme) {
+		mlme_err("data is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	pe_debug("Vdev %d is up", wlan_vdev_get_id(vdev_mlme->vdev));
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ap_mlme_vdev_disconnect_peers() - callback to disconnect all connected peers
+ * @vdev_mlme: vdev mlme object
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to disconnect all connected peers
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ap_mlme_vdev_disconnect_peers(struct vdev_mlme_obj *vdev_mlme,
+						uint16_t data_len, void *data)
+{
+	return lim_ap_mlme_vdev_disconnect_peers(vdev_mlme, data_len, data);
+}
+
+/**
+ * ap_mlme_vdev_stop_send() - callback to send stop vdev request
+ * @vdev_mlme: vdev mlme object
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to send stop vdev request
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ap_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
+					 uint16_t data_len, void *data)
+{
+	return lim_ap_mlme_vdev_stop_send(vdev_mlme, data_len, data);
+}
+
+/**
+ * ap_mlme_vdev_down_send() - callback to send vdev down req
+ * @vdev_mlme: vdev mlme object
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to send vdev down req
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS vdevmgr_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
+					      uint16_t data_len, void *data)
+{
+	return wma_ap_mlme_vdev_down_send(vdev_mlme, data_len, data);
+}
+/**
+ * vdevmgr_notify_down_complete() - callback to indicate vdev down is completed
+ * @vdev_mlme: vdev mlme object
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to indicate vdev down is completed
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS vdevmgr_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
+					       uint16_t data_len, void *data)
+{
+	return wma_mlme_vdev_notify_down_complete(vdev_mlme, data_len, data);
+}
+
+/**
+ * ap_mlme_vdev_start_req_failed () - vdev start req fail callback
+ * @vdev_mlme: vdev mlme object
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to handle vdev start req/rsp failure
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme,
+						uint16_t data_len, void *data)
+{
+	return lim_ap_mlme_vdev_start_req_failed(vdev_mlme, data_len, data);
+}
+
+/**
+ * ap_mlme_vdev_restart_send() a callback to send vdev restart
+ * @vdev_mlme: vdev mlme object
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to initiate and send vdev restart req
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
+					    uint16_t data_len, void *data)
+{
+	return lim_ap_mlme_vdev_restart_send(vdev_mlme, data_len, data);
+}
+
+/**
+ * ap_mlme_vdev_stop_start_send() - handle vdev stop during start req
+ * @vdev_mlme: vdev mlme object
+ * @type: restart req or start req
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to handle vdev stop during start req
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme,
+					       enum vdev_cmd_type type,
+					       uint16_t data_len, void *data)
+{
+	return wma_ap_mlme_vdev_stop_start_send(vdev_mlme, type,
+						data_len, data);
+}
+
+QDF_STATUS mlme_set_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev,
+					       bool val)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	mlme_priv->chan_switch_in_progress = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool mlme_is_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return false;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	return mlme_priv->chan_switch_in_progress;
+}
+
+QDF_STATUS
+ap_mlme_set_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev,
+					    bool val)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	mlme_priv->hidden_ssid_restart_in_progress = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool ap_mlme_is_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return false;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	return mlme_priv->hidden_ssid_restart_in_progress;
+}
+
+QDF_STATUS mlme_set_connection_fail(struct wlan_objmgr_vdev *vdev, bool val)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	mlme_priv->connection_fail = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool mlme_is_connection_fail(struct wlan_objmgr_vdev *vdev)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return false;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	return mlme_priv->connection_fail;
+}
+
+QDF_STATUS mlme_set_assoc_type(struct wlan_objmgr_vdev *vdev,
+			       enum vdev_assoc_type assoc_type)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	mlme_priv->assoc_type = assoc_type;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+enum vdev_assoc_type  mlme_get_assoc_type(struct wlan_objmgr_vdev *vdev)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return false;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	return mlme_priv->assoc_type;
+}
+
+QDF_STATUS
+mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	mlme_priv->vdev_start_failed = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool mlme_get_vdev_start_failed(struct wlan_objmgr_vdev *vdev)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return false;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	return mlme_priv->vdev_start_failed;
+}
+
+
+/**
+ * mlme_legacy_hdl_create () - Create mlme legacy priv object
+ * @vdev_mlme: vdev mlme object
+ *
+ * Return: QDF_STATUS
+ */
+static
+QDF_STATUS mlme_legacy_hdl_create(struct vdev_mlme_obj *vdev_mlme)
+{
+	vdev_mlme->legacy_vdev_ptr =
+		qdf_mem_malloc(sizeof(struct mlme_legacy_priv));
+	if (!vdev_mlme->legacy_vdev_ptr) {
+		mlme_err("failed to allocate meory for legacy_vdev_ptr");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * mlme_legacy_hdl_destroy () - Destroy mlme legacy priv object
+ * @vdev_mlme: vdev mlme object
+ *
+ * Return: QDF_STATUS
+ */
+static
+QDF_STATUS mlme_legacy_hdl_destroy(struct vdev_mlme_obj *vdev_mlme)
+{
+	qdf_mem_free(vdev_mlme->legacy_vdev_ptr);
+	vdev_mlme->legacy_vdev_ptr = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ap_vdev_dfs_cac_timer_stop() – callback to stop cac timer
+ * @vdev_mlme: vdev mlme object
+ * @event_data_len: event data length
+ * @event_data: event data
+ *
+ * This function is called to stop cac timer
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ap_vdev_dfs_cac_timer_stop(struct vdev_mlme_obj *vdev_mlme,
+					     uint16_t event_data_len,
+					     void *event_data)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * struct sta_mlme_ops - VDEV MLME operation callbacks strucutre for sta
+ * @mlme_vdev_validate_basic_params:    callback to validate VDEV basic params
+ * @mlme_vdev_reset_proto_params:       callback to Reset protocol params
+ * @mlme_vdev_start_send:               callback to initiate actions of VDEV
+ *                                      MLME start operation
+ * @mlme_vdev_restart_send:             callback to initiate actions of VDEV
+ *                                      MLME restart operation
+ * @mlme_vdev_stop_start_send:          callback to block start/restart VDEV
+ *                                      request command
+ * @mlme_vdev_start_continue:           callback to initiate operations on
+ *                                      LMAC/FW start response
+ * @mlme_vdev_up_send:                  callback to initiate actions of VDEV
+ *                                      MLME up operation
+ * @mlme_vdev_notify_up_complete:       callback to notify VDEV MLME on moving
+ *                                      to UP state
+ * @mlme_vdev_update_beacon:            callback to initiate beacon update
+ * @mlme_vdev_disconnect_peers:         callback to initiate disconnection of
+ *                                      peers
+ * @mlme_vdev_dfs_cac_timer_stop:       callback to stop the DFS CAC timer
+ * @mlme_vdev_stop_send:                callback to initiate actions of VDEV
+ *                                      MLME stop operation
+ * @mlme_vdev_stop_continue:            callback to initiate operations on
+ *                                      LMAC/FW stop response
+ * @mlme_vdev_bss_peer_delete_continue: callback to initiate operations on BSS
+ *                                      peer delete completion
+ * @mlme_vdev_down_send:                callback to initiate actions of VDEV
+ *                                      MLME down operation
+ * @mlme_vdev_legacy_hdl_create:        callback to invoke creation of legacy
+ *                                      vdev object
+ * @mlme_vdev_legacy_hdl_post_create:   callback to invoke post creation actions
+ *                                      of legacy vdev object
+ * @mlme_vdev_legacy_hdl_destroy:       callback to invoke destroy of legacy
+ *                                      vdev object
+ */
+static struct vdev_mlme_ops sta_mlme_ops = {
+	.mlme_vdev_start_send = sta_mlme_vdev_start_send,
+	.mlme_vdev_restart_send = sta_mlme_vdev_restart_send,
+	.mlme_vdev_start_continue = sta_mlme_start_continue,
+	.mlme_vdev_sta_conn_start = sta_mlme_vdev_start_connection,
+	.mlme_vdev_up_send = sta_mlme_vdev_up_send,
+	.mlme_vdev_notify_up_complete = sta_mlme_vdev_notify_up_complete,
+	.mlme_vdev_disconnect_peers = sta_mlme_vdev_disconnect_bss,
+	.mlme_vdev_stop_send = sta_mlme_vdev_stop_send,
+	.mlme_vdev_stop_continue = vdevmgr_mlme_stop_continue,
+	.mlme_vdev_down_send = vdevmgr_mlme_vdev_down_send,
+	.mlme_vdev_notify_down_complete = vdevmgr_notify_down_complete,
+	.mlme_vdev_legacy_hdl_create = mlme_legacy_hdl_create,
+	.mlme_vdev_legacy_hdl_destroy = mlme_legacy_hdl_destroy,
+};
+
+/**
+ * struct ap_mlme_ops - VDEV MLME operation callbacks strucutre for beaconing
+ *                      interface
+ * @mlme_vdev_start_send:               callback to initiate actions of VDEV
+ *                                      MLME start operation
+ * @mlme_vdev_restart_send:             callback to initiate actions of VDEV
+ *                                      MLME restart operation
+ * @mlme_vdev_stop_start_send:          callback to block start/restart VDEV
+ *                                      request command
+ * @mlme_vdev_start_continue:           callback to initiate operations on
+ *                                      LMAC/FW start response
+ * @mlme_vdev_up_send:                  callback to initiate actions of VDEV
+ *                                      MLME up operation
+ * @mlme_vdev_notify_up_complete:       callback to notify VDEV MLME on moving
+ *                                      to UP state
+ * @mlme_vdev_update_beacon:            callback to initiate beacon update
+ * @mlme_vdev_disconnect_peers:         callback to initiate disconnection of
+ *                                      peers
+ * @mlme_vdev_dfs_cac_timer_stop:       callback to stop the DFS CAC timer
+ * @mlme_vdev_stop_send:                callback to initiate actions of VDEV
+ *                                      MLME stop operation
+ * @mlme_vdev_stop_continue:            callback to initiate operations on
+ *                                      LMAC/FW stop response
+ * @mlme_vdev_down_send:                callback to initiate actions of VDEV
+ *                                      MLME down operation
+ * @mlme_vdev_notify_down_complete:     callback to notify VDEV MLME on moving
+ *                                      to INIT state
+ * @mlme_vdev_legacy_hdl_create:        callback to invoke creation of legacy
+ *                                      vdev object
+ * @mlme_vdev_legacy_hdl_destroy:       callback to invoke destroy of legacy
+ *                                      vdev object
+ */
+static struct vdev_mlme_ops ap_mlme_ops = {
+	.mlme_vdev_start_send = ap_mlme_vdev_start_send,
+	.mlme_vdev_restart_send = ap_mlme_vdev_restart_send,
+	.mlme_vdev_stop_start_send = ap_mlme_vdev_stop_start_send,
+	.mlme_vdev_start_continue = ap_mlme_start_continue,
+	.mlme_vdev_start_req_failed = ap_mlme_vdev_start_req_failed,
+	.mlme_vdev_up_send = ap_mlme_vdev_up_send,
+	.mlme_vdev_notify_up_complete = ap_mlme_vdev_notify_up_complete,
+	.mlme_vdev_update_beacon = ap_mlme_vdev_update_beacon,
+	.mlme_vdev_disconnect_peers = ap_mlme_vdev_disconnect_peers,
+	.mlme_vdev_dfs_cac_timer_stop = ap_vdev_dfs_cac_timer_stop,
+	.mlme_vdev_stop_send = ap_mlme_vdev_stop_send,
+	.mlme_vdev_stop_continue = vdevmgr_mlme_stop_continue,
+	.mlme_vdev_down_send = vdevmgr_mlme_vdev_down_send,
+	.mlme_vdev_notify_down_complete = vdevmgr_notify_down_complete,
+	.mlme_vdev_legacy_hdl_create = mlme_legacy_hdl_create,
+	.mlme_vdev_legacy_hdl_destroy = mlme_legacy_hdl_destroy,
+};
diff --git a/components/mlme/dispatcher/inc/cfg_mlme.h b/components/mlme/dispatcher/inc/cfg_mlme.h
new file mode 100644
index 0000000..e8becb9
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef __CFG_MLME_H
+#define __CFG_MLME_H
+
+#include "cfg_define.h"
+#include "cfg_converged.h"
+#include "qdf_types.h"
+#include "cfg_mlme_wps_params.h"
+#include "cfg_mlme_chainmask.h"
+#include "cfg_mlme_edca_params.h"
+#include "cfg_mlme_generic.h"
+#include "cfg_mlme_acs.h"
+#include "cfg_mlme_ht_caps.h"
+#include "cfg_mlme_he_caps.h"
+#include "cfg_mlme_lfr.h"
+#include "cfg_mlme_obss_ht40.h"
+#include "cfg_mlme_dfs.h"
+#include "cfg_mlme_mbo.h"
+#include "cfg_mlme_vht_caps.h"
+#include "cfg_qos.h"
+#include "cfg_mlme_timeout.h"
+#include "cfg_mlme_rates.h"
+#include "wlan_mlme_product_details_cfg.h"
+#include "cfg_mlme_sta.h"
+#include "cfg_sap_protection.h"
+#include "cfg_mlme_fe_wmm.h"
+#include "cfg_mlme_sap.h"
+#include "cfg_mlme_scoring.h"
+#include "cfg_mlme_oce.h"
+#include "cfg_mlme_threshold.h"
+#include "cfg_mlme_feature_flag.h"
+#include "cfg_mlme_wep_params.h"
+
+/* Please Maintain Alphabetic Order here */
+#define CFG_MLME_ALL \
+	CFG_ACS_ALL \
+	CFG_CHAINMASK_ALL \
+	CFG_DFS_ALL \
+	CFG_EDCA_PARAMS_ALL \
+	CFG_FEATURE_FLAG_ALL \
+	CFG_GENERIC_ALL \
+	CFG_HT_CAPS_ALL \
+	CFG_HE_CAPS_ALL \
+	CFG_LFR_ALL \
+	CFG_MBO_ALL \
+	CFG_MLME_PRODUCT_DETAILS_ALL \
+	CFG_OBSS_HT40_ALL \
+	CFG_OCE_ALL \
+	CFG_QOS_ALL \
+	CFG_RATES_ALL \
+	CFG_WMM_PARAMS_ALL\
+	CFG_SAP_ALL \
+	CFG_SAP_PROTECTION_ALL \
+	CFG_SCORING_ALL \
+	CFG_STA_ALL \
+	CFG_THRESHOLD_ALL \
+	CFG_TIMEOUT_ALL \
+	CFG_VHT_CAPS_ALL \
+	CFG_WEP_PARAMS_ALL \
+	CFG_WPS_ALL
+
+#endif /* __CFG_MLME_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_acs.h b/components/mlme/dispatcher/inc/cfg_mlme_acs.h
new file mode 100644
index 0000000..6c5c67a
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_acs.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_ACS_H
+#define __CFG_MLME_ACS_H
+
+/*
+ * <ini>
+ * acs_with_more_param- Enable acs calculation with more param.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable acs calculation with more param.
+ *
+ * Related: NA
+ *
+ * Supported Feature: ACS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_ACS_WITH_MORE_PARAM CFG_INI_BOOL( \
+		"acs_with_more_param", \
+		0, \
+		"Enable ACS with more param")
+
+/*
+ * <ini>
+ * AutoChannelSelectWeight - ACS channel weight
+ * @Min: 0
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x000000FF
+ *
+ * This ini is used to adjust weight of factors in
+ * acs algorithm.
+ *
+ * Supported Feature: ACS
+ *
+ * Usage: Internal/External
+ *
+ * bits 0-3:   rssi weight
+ * bits 4-7:   bss count weight
+ * bits 8-11:  noise floor weight
+ * bits 12-15: channel free weight
+ * bits 16-19: tx power range weight
+ * bits 20-23: tx power throughput weight
+ * bits 24-31: reserved
+ *
+ * </ini>
+ */
+
+#define CFG_AUTO_CHANNEL_SELECT_WEIGHT CFG_INI_UINT( \
+		"AutoChannelSelectWeight", \
+		0, \
+		0xFFFFFFFF, \
+		0x000000FF, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Adjust weight factor in ACS")
+
+/*
+ * <ini>
+ * gvendor_acs_support - vendor based channel selection manager
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Enabling this parameter will force driver to use user application based
+ * channel selection algo instead of driver based auto channel selection
+ * logic.
+ *
+ * Supported Feature: ACS
+ *
+ * Usage: External/Internal
+ *
+ * </ini>
+ */
+
+#define CFG_USER_AUTO_CHANNEL_SELECTION CFG_INI_BOOL( \
+		"gvendor_acs_support", \
+		0, \
+		"Vendor channel selection manager")
+
+/*
+ * <ini>
+ * gacs_support_for_dfs_lte_coex - acs support for lte coex and dfs event
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Enabling this parameter will force driver to use user application based
+ * channel selection algo for channel selection in case of dfs and lte
+ * coex event.
+ *
+ * Supported Feature: ACS
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+
+#define CFG_USER_ACS_DFS_LTE CFG_INI_BOOL( \
+		"gacs_support_for_dfs_lte_coex", \
+		0, \
+		"Acs support for lte coex and dfs")
+
+/*
+ * <ini>
+ * external_acs_policy - External ACS policy control
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Values are per enum hdd_external_acs_policy.
+ *
+ * This ini is used to control the external ACS policy.
+ *
+ * 0 -Preferable for ACS to select a
+ *    channel with non-zero pcl weight.
+ * 1 -Mandatory for ACS to select a
+ *    channel with non-zero pcl weight.
+ *
+ * Related: None
+ *
+ * Supported Feature: ACS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_EXTERNAL_ACS_POLICY CFG_INI_BOOL( \
+		"acs_policy", \
+		0, \
+		"External ACS Policy Control")
+
+#define CFG_ACS_ALL \
+	CFG(CFG_ACS_WITH_MORE_PARAM) \
+	CFG(CFG_AUTO_CHANNEL_SELECT_WEIGHT) \
+	CFG(CFG_USER_AUTO_CHANNEL_SELECTION) \
+	CFG(CFG_USER_ACS_DFS_LTE) \
+	CFG(CFG_EXTERNAL_ACS_POLICY)
+
+#endif /* __CFG_MLME_ACS_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_chainmask.h b/components/mlme/dispatcher/inc/cfg_mlme_chainmask.h
new file mode 100644
index 0000000..21d8c96
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_chainmask.h
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_CHAINMASK_H
+#define __CFG_CHAINMASK_H
+
+/*
+ * <ini>
+ * gSetTxChainmask1x1 - Sets Transmit chain mask.
+ * @Min: 1
+ * @Max: 3
+ * @Default: 0
+ *
+ * This ini Sets Transmit chain mask.
+ *
+ * If gEnable2x2 is disabled, gSetTxChainmask1x1 and gSetRxChainmask1x1 values
+ * are taken into account. If chainmask value exceeds the maximum number of
+ * chains supported by target, the max number of chains is used. By default,
+ * chain0 is selected for both Tx and Rx.
+ * gSetTxChainmask1x1=1 or gSetRxChainmask1x1=1 to select chain0.
+ * gSetTxChainmask1x1=2 or gSetRxChainmask1x1=2 to select chain1.
+ * gSetTxChainmask1x1=3 or gSetRxChainmask1x1=3 to select both chains.
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_1x1_TX_CHAINMASK CFG_INI_UINT( \
+				"gSetTxChainmask1x1", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"1x1 VHT Tx Chainmask")
+
+/*
+ * <ini>
+ * gSetRxChainmask1x1 - Sets Receive chain mask.
+ * @Min: 1
+ * @Max: 3
+ * @Default: 0
+ *
+ * This ini is  used to set Receive chain mask.
+ *
+ * If gEnable2x2 is disabled, gSetTxChainmask1x1 and gSetRxChainmask1x1 values
+ * are taken into account. If chainmask value exceeds the maximum number of
+ * chains supported by target, the max number of chains is used. By default,
+ * chain0 is selected for both Tx and Rx.
+ * gSetTxChainmask1x1=1 or gSetRxChainmask1x1=1 to select chain0.
+ * gSetTxChainmask1x1=2 or gSetRxChainmask1x1=2 to select chain1.
+ * gSetTxChainmask1x1=3 or gSetRxChainmask1x1=3 to select both chains.
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_1x1_RX_CHAINMASK CFG_INI_UINT( \
+				"gSetRxChainmask1x1", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"1x1 VHT Rx Chainmask")
+
+/*
+ * <ini>
+ * gCckChainMaskEnable - Used to enable/disable Cck ChainMask
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set default Cck ChainMask
+ * 0: disable the cck tx chain mask (default)
+ * 1: enable the cck tx chain mask
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_TX_CHAIN_MASK_CCK CFG_INI_BOOL( \
+			"gCckChainMaskEnable", \
+			0, \
+			"Set default CCK Tx Chainmask")
+
+/*
+ * <ini>
+ * gTxChainMask1ss - Enables/disables tx chain Mask1ss
+ * @Min: 0
+ * @Max: 3
+ * @Default: 1
+ *
+ * This ini is used to set default tx chain Mask1ss
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_TX_CHAIN_MASK_1SS CFG_INI_UINT( \
+			"gTxChainMask1ss", \
+			0, \
+			3, \
+			1, \
+			CFG_VALUE_OR_DEFAULT, \
+			"1SS Tx Chainmask")
+
+/*
+ * <ini>
+ * g11bNumTxChains - Number of Tx Chanins in 11b mode
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * Number of Tx Chanins in 11b mode
+ *
+ *
+ * Related: None
+ *
+ * Supported Feature: connection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_11B_NUM_TX_CHAIN CFG_INI_UINT( \
+			"g11bNumTxChains", \
+			0, \
+			2, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"11b Num Tx chains")
+
+/*
+ * <ini>
+ * g11agNumTxChains - Number of Tx Chanins in 11ag mode
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * Number of Tx Chanins in 11ag mode
+ *
+ *
+ * Related: None
+ *
+ * Supported Feature: connection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_11AG_NUM_TX_CHAIN CFG_INI_UINT( \
+			"g11agNumTxChains", \
+			0, \
+			2, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"11ag Num Tx chains")
+
+/*
+ * <ini>
+ * tx_chain_mask_2g - tx chain mask for 2g
+ * @Min: 0
+ * @Max: 3
+ * @Default: 0
+ *
+ * This ini will set tx chain mask for 2g. To use the ini, make sure:
+ * gSetTxChainmask1x1/gSetRxChainmask1x1 = 0,
+ * gDualMacFeatureDisable = 1
+ * gEnable2x2 = 0
+ *
+ * tx_chain_mask_2g=0 : don't care
+ * tx_chain_mask_2g=1 : for 2g tx use chain 0
+ * tx_chain_mask_2g=2 : for 2g tx use chain 1
+ * tx_chain_mask_2g=3 : for 2g tx can use either chain
+ *
+ * Related: None
+ *
+ * Supported Feature: All profiles
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_TX_CHAIN_MASK_2G CFG_INI_UINT( \
+			"tx_chain_mask_2g", \
+			0, \
+			3, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"2.4G Tx Chainmask")
+
+/*
+ * <ini>
+ * rx_chain_mask_2g - rx chain mask for 2g
+ * @Min: 0
+ * @Max: 3
+ * @Default: 0
+ *
+ * This ini will set rx chain mask for 2g. To use the ini, make sure:
+ * gSetTxChainmask1x1/gSetRxChainmask1x1 = 0,
+ * gDualMacFeatureDisable = 1
+ * gEnable2x2 = 0
+ *
+ * rx_chain_mask_2g=0 : don't care
+ * rx_chain_mask_2g=1 : for 2g rx use chain 0
+ * rx_chain_mask_2g=2 : for 2g rx use chain 1
+ * rx_chain_mask_2g=3 : for 2g rx can use either chain
+ *
+ * Related: None
+ *
+ * Supported Feature: All profiles
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_RX_CHAIN_MASK_2G CFG_INI_UINT( \
+			"rx_chain_mask_2g", \
+			0, \
+			3, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"2.4G Rx Chainmask")
+
+/*
+ * <ini>
+ * tx_chain_mask_5g - tx chain mask for 5g
+ * @Min: 0
+ * @Max: 3
+ * @Default: 0
+ *
+ * This ini will set tx chain mask for 5g. To use the ini, make sure:
+ * gSetTxChainmask1x1/gSetRxChainmask1x1 = 0,
+ * gDualMacFeatureDisable = 1
+ * gEnable2x2 = 0
+ *
+ * tx_chain_mask_5g=0 : don't care
+ * tx_chain_mask_5g=1 : for 5g tx use chain 0
+ * tx_chain_mask_5g=2 : for 5g tx use chain 1
+ * tx_chain_mask_5g=3 : for 5g tx can use either chain
+ *
+ * Related: None
+ *
+ * Supported Feature: All profiles
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_TX_CHAIN_MASK_5G CFG_INI_UINT( \
+			"tx_chain_mask_5g", \
+			0, \
+			3, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"5Ghz Tx Chainmask")
+
+/*
+ * <ini>
+ * rx_chain_mask_5g - rx chain mask for 5g
+ * @Min: 0
+ * @Max: 3
+ * @Default: 0
+ *
+ * This ini will set rx chain mask for 5g. To use the ini, make sure:
+ * gSetTxChainmask1x1/gSetRxChainmask1x1 = 0,
+ * gDualMacFeatureDisable = 1
+ * gEnable2x2 = 0
+ *
+ * rx_chain_mask_5g=0 : don't care
+ * rx_chain_mask_5g=1 : for 5g rx use chain 0
+ * rx_chain_mask_5g=2 : for 5g rx use chain 1
+ * rx_chain_mask_5g=3 : for 5g rx can use either chain
+ *
+ * Related: None
+ *
+ * Supported Feature: All profiles
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_RX_CHAIN_MASK_5G CFG_INI_UINT( \
+			"rx_chain_mask_5g", \
+			0, \
+			3, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"5Ghz Tx Chainmask")
+
+#define CFG_CHAINMASK_ALL \
+	CFG(CFG_VHT_ENABLE_1x1_TX_CHAINMASK) \
+	CFG(CFG_VHT_ENABLE_1x1_RX_CHAINMASK) \
+	CFG(CFG_TX_CHAIN_MASK_CCK) \
+	CFG(CFG_TX_CHAIN_MASK_1SS) \
+	CFG(CFG_11B_NUM_TX_CHAIN) \
+	CFG(CFG_11AG_NUM_TX_CHAIN) \
+	CFG(CFG_TX_CHAIN_MASK_2G) \
+	CFG(CFG_RX_CHAIN_MASK_2G) \
+	CFG(CFG_TX_CHAIN_MASK_5G) \
+	CFG(CFG_RX_CHAIN_MASK_5G)
+
+#endif /* __CFG_CHAINMASK_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_dfs.h b/components/mlme/dispatcher/inc/cfg_mlme_dfs.h
new file mode 100644
index 0000000..e3dd2c5
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_dfs.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_DFS_H
+#define __CFG_MLME_DFS_H
+
+/*
+ * <ini>
+ * gEnableDFSMasterCap - Enable DFS master capability
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable the DFS master capability.
+ * Disabling it will cause driver to not advertise the spectrum
+ * management capability
+ * Related: NA.
+ *
+ * upported Feature: DFS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_DFS_MASTER_CAPABILITY CFG_INI_BOOL( \
+			"gEnableDFSMasterCap", \
+			0, \
+			"DFS master mode capability")
+
+#define CFG_DFS_ALL \
+	CFG(CFG_ENABLE_DFS_MASTER_CAPABILITY)
+
+#endif /* __CFG_MLME_DFS_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_edca_params.h b/components/mlme/dispatcher/inc/cfg_mlme_edca_params.h
new file mode 100644
index 0000000..7c34cfc
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_edca_params.h
@@ -0,0 +1,651 @@
+/*
+ * Copyright (c) 2011-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_EDCA__PARAM_H
+#define __CFG_MLME_EDCA__PARAM_H
+
+#define STR_EDCA_ANI_ACBK_LOCAL "0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0"
+#define STR_EDCA_ANI_ACBK_LOCAL_LEN (sizeof(STR_EDCA_ANI_ACBK_LOCAL) - 1)
+
+#define CFG_EDCA_ANI_ACBK_LOCAL CFG_STRING( \
+		"edca_ani_acbk_local", \
+		0, \
+		STR_EDCA_ANI_ACBK_LOCAL_LEN, \
+		STR_EDCA_ANI_ACBK_LOCAL, \
+		"EDCA ANI ACBK LOCAL")
+
+#define STR_EDCA_ANI_ACBE_LOCAL "0x0, 0x2, 0x0, 0xf, 0x3, 0xff, 0x64, 0x0, 0x1f, 0x3, 0xff, 0x64, 0x0, 0xf, 0x3, 0xff, 0x64"
+#define STR_EDCA_ANI_ACBE_LOCAL_LEN (sizeof(STR_EDCA_ANI_ACBK_LOCAL) - 1)
+
+#define CFG_EDCA_ANI_ACBE_LOCAL CFG_STRING( \
+		"edca_ani_acbe_local", \
+		0, \
+		STR_EDCA_ANI_ACBE_LOCAL_LEN, \
+		STR_EDCA_ANI_ACBE_LOCAL, \
+		"EDCA ANI ACBE LOCAL")
+
+#define STR_EDCA_ANI_ACVI_LOCAL "0x0, 0x2, 0x0, 0x7, 0x0, 0xf, 0xc8, 0x0, 0xf, 0x0, 0x1f, 0xbc, 0x0, 0x7, 0x0, 0xf, 0xc8"
+#define STR_EDCA_ANI_ACVI_LOCAL_LEN (sizeof(STR_EDCA_ANI_ACBK_LOCAL) - 1)
+
+#define CFG_EDCA_ANI_ACVI_LOCAL CFG_STRING( \
+		"edca_ani_acvi_local",\
+		0, \
+		STR_EDCA_ANI_ACVI_LOCAL_LEN, \
+		STR_EDCA_ANI_ACVI_LOCAL, \
+		"EDCA ANI ACVI LOCAL")
+
+#define STR_EDCA_ANI_ACVO_LOCAL "0x0, 0x2, 0x0, 0x3, 0x0, 0x7, 0x64, 0x0, 0x7, 0x0, 0xf, 0x66, 0x0, 0x3, 0x0, 0x7, 0x64"
+#define STR_EDCA_ANI_ACVO_LOCAL_LEN (sizeof(STR_EDCA_ANI_ACBK_LOCAL) - 1)
+
+#define CFG_EDCA_ANI_ACVO_LOCAL CFG_STRING( \
+		"edca_ani_acvo_local", \
+		0, \
+		STR_EDCA_ANI_ACVO_LOCAL_LEN, \
+		STR_EDCA_ANI_ACVO_LOCAL, \
+		"EDCA ANI ACVO LOCAL")
+
+#define STR_EDCA_ANI_ACBK "0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0"
+#define STR_EDCA_ANI_ACBK_LEN (sizeof(STR_EDCA_ANI_ACBK_LOCAL) - 1)
+
+#define CFG_EDCA_ANI_ACBK CFG_STRING( \
+		"edca_ani_acbk", \
+		0, \
+		STR_EDCA_ANI_ACBK_LEN, \
+		STR_EDCA_ANI_ACBK, \
+		"EDCA ANI ACBK BROADCAST")
+
+#define STR_EDCA_ANI_ACBE "0x0, 0x2, 0x0, 0xf, 0x3, 0xff, 0x64, 0x0, 0x1f, 0x3, 0xff, 0x64, 0x0, 0xf, 0x3, 0xff, 0x64"
+#define STR_EDCA_ANI_ACBE_LEN (sizeof(STR_EDCA_ANI_ACBK_LOCAL) - 1)
+
+#define CFG_EDCA_ANI_ACBE CFG_STRING( \
+		"edca_ani_acbe", \
+		0, \
+		STR_EDCA_ANI_ACBE_LEN, \
+		STR_EDCA_ANI_ACBE, \
+		"EDCA ANI ACBE BROADCAST")
+
+#define STR_EDCA_ANI_ACVI "0x0, 0x2, 0x0, 0x7, 0x0, 0xf, 0xc8, 0x0, 0xf, 0x0, 0x1f, 0xbc, 0x0, 0x7, 0x0, 0xf, 0xc8"
+#define STR_EDCA_ANI_ACVI_LEN (sizeof(STR_EDCA_ANI_ACBK_LOCAL) - 1)
+
+#define CFG_EDCA_ANI_ACVI CFG_STRING( \
+		"edca_ani_acvi", \
+		0, \
+		STR_EDCA_ANI_ACVI_LEN, \
+		STR_EDCA_ANI_ACVI, \
+		"EDCA ANI ACVI BROADCAST")
+
+#define STR_EDCA_ANI_ACVO "0x0, 0x2, 0x0, 0x3, 0x0, 0x7, 0x64, 0x0, 0x7, 0x0, 0xf, 0x66, 0x0, 0x3, 0x0, 0x7, 0x64"
+#define STR_EDCA_ANI_ACVO_LEN (sizeof(STR_EDCA_ANI_ACBK_LOCAL) - 1)
+
+#define CFG_EDCA_ANI_ACVO CFG_STRING( \
+		"edca_ani_acvo", \
+		0, \
+		STR_EDCA_ANI_ACVO_LEN, \
+		STR_EDCA_ANI_ACVO, \
+		"EDCA ANI ACVO BROADCAST")
+
+#define STR_EDCA_WME_ACBK_LOCAL "0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0"
+#define STR_EDCA_WME_ACBK_LOCAL_LEN (sizeof(STR_EDCA_WME_ACBK_LOCAL) - 1)
+
+#define CFG_EDCA_WME_ACBK_LOCAL CFG_STRING( \
+		"edca_wme_acbk_local", \
+		0, \
+		STR_EDCA_WME_ACBK_LOCAL_LEN, \
+		STR_EDCA_WME_ACBK_LOCAL, \
+		"EDCA WME ACBK LOCAL")
+
+#define STR_EDCA_WME_ACBE_LOCAL "0x0, 0x3, 0x0, 0xf, 0x0, 0x3f, 0x0, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0, 0xf, 0x0, 0x3f, 0x0"
+#define STR_EDCA_WME_ACBE_LOCAL_LEN (sizeof(STR_EDCA_WME_ACBE_LOCAL) - 1)
+
+#define CFG_EDCA_WME_ACBE_LOCAL CFG_STRING( \
+		"edca_wme_acbe_local", \
+		0, \
+		STR_EDCA_WME_ACBE_LOCAL_LEN, \
+		STR_EDCA_WME_ACBE_LOCAL, \
+		"EDCA WME ACBE LOCAL")
+
+#define STR_EDCA_WME_ACVI_LOCAL "0x0, 0x1, 0x0, 0x7, 0x0, 0xf, 0x5e, 0x0, 0x7, 0x0, 0xf, 0xbc, 0x0, 0x7, 0x0, 0xf, 0x5e"
+#define STR_EDCA_WME_ACVI_LOCAL_LEN (sizeof(STR_EDCA_WME_ACVI_LOCAL) - 1)
+
+#define CFG_EDCA_WME_ACVI_LOCAL CFG_STRING( \
+		"edca_wme_acvi_local", \
+		0, \
+		STR_EDCA_WME_ACVI_LOCAL_LEN, \
+		STR_EDCA_WME_ACVI_LOCAL, \
+		"EDCA WME ACVI LOCAL")
+
+#define STR_EDCA_WME_ACVO_LOCAL "0x0, 0x1, 0x0, 0x3, 0x0, 0x7, 0x2f, 0x0, 0x3, 0x0, 0x7, 0x66, 0x0, 0x3, 0x0, 0x7, 0x2f"
+#define STR_EDCA_WME_ACVO_LOCAL_LEN (sizeof(STR_EDCA_WME_ACVO_LOCAL) - 1)
+
+#define CFG_EDCA_WME_ACVO_LOCAL CFG_STRING( \
+		"edca_wme_acvo_local", \
+		0, \
+		STR_EDCA_WME_ACVO_LOCAL_LEN, \
+		STR_EDCA_WME_ACVO_LOCAL, \
+		"EDCA WME ACVO LOCAL")
+
+#define STR_EDCA_WME_ACBK "0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0"
+#define STR_EDCA_WME_ACBK_LEN (sizeof(STR_EDCA_WME_ACBK) - 1)
+
+#define CFG_EDCA_WME_ACBK CFG_STRING( \
+		"edca_wme_acbk", \
+		0, \
+		STR_EDCA_WME_ACBK_LEN, \
+		STR_EDCA_WME_ACBK, \
+		"EDCA WME ACBK BROADCAST")
+
+#define STR_EDCA_WME_ACBE "0x0, 0x3, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0"
+#define STR_EDCA_WME_ACBE_LEN (sizeof(STR_EDCA_WME_ACBE) - 1)
+
+#define CFG_EDCA_WME_ACBE CFG_STRING( \
+		"edca_wme_acbe", \
+		0, \
+		STR_EDCA_WME_ACBE_LEN, \
+		STR_EDCA_WME_ACBE, \
+		"EDCA WME ACBE BROADCAST")
+
+#define STR_EDCA_WME_ACVI "0x0, 0x2, 0x0, 0x7, 0x0, 0xf, 0x5e, 0x0, 0x7, 0x0, 0xf, 0xbc, 0x0, 0x7, 0x0, 0xf, 0x5e"
+#define STR_EDCA_WME_ACVI_LEN (sizeof(STR_EDCA_WME_ACVI) - 1)
+
+#define CFG_EDCA_WME_ACVI CFG_STRING( \
+		"edca_wme_acvi", \
+		0, \
+		STR_EDCA_WME_ACVI_LEN, \
+		STR_EDCA_WME_ACVI, \
+		"EDCA WME ACVI BROADCAST")
+
+#define STR_EDCA_WME_ACVO "0x0, 0x2, 0x0, 0x3, 0x0, 0x7, 0x2f, 0x0, 0x3, 0x0, 0x7, 0x66, 0x0, 0x3, 0x0, 0x7, 0x2f"
+#define STR_EDCA_WME_ACVO_LEN (sizeof(STR_EDCA_WME_ACVO) - 1)
+
+#define CFG_EDCA_WME_ACVO CFG_STRING( \
+		"edca_wme_acvo", \
+		0, \
+		STR_EDCA_WME_ACVO_LEN, \
+		STR_EDCA_WME_ACVO, \
+		"EDCA WME ACVO BROADCAST")
+
+#define STR_EDCA_ETSI_ACBK_LOCAL "0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0xbb, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0"
+#define STR_EDCA_ETSI_ACBK_LOCAL_LEN (sizeof(STR_EDCA_ETSI_ACBK_LOCAL) - 1)
+
+#define CFG_EDCA_ETSI_ACBK_LOCAL CFG_STRING( \
+		"edca_etsi_acbk_local", \
+		0, \
+		STR_EDCA_ETSI_ACBK_LOCAL_LEN, \
+		STR_EDCA_ETSI_ACBK_LOCAL, \
+		"EDCA ETSI ACBK LOCAL")
+
+#define STR_EDCA_ETSI_ACBE_LOCAL "0x0, 0x3, 0x0, 0xf, 0x0, 0x3f, 0xbb, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0, 0xf, 0x0, 0x3f, 0x0"
+#define STR_EDCA_ETSI_ACBE_LOCAL_LEN (sizeof(STR_EDCA_ETSI_ACBE_LOCAL) - 1)
+
+#define CFG_EDCA_ETSI_ACBE_LOCAL CFG_STRING( \
+		"edca_etsi_acbe_local", \
+		0, \
+		STR_EDCA_ETSI_ACBE_LOCAL_LEN, \
+		STR_EDCA_ETSI_ACBE_LOCAL, \
+		"EDCA ETSI ACBE LOCAL")
+
+#define STR_EDCA_ETSI_ACVI_LOCAL "0x0, 0x1, 0x0, 0x7, 0x0, 0xf, 0x7d, 0x0, 0x7, 0x0, 0xf, 0xbc, 0x0, 0x7, 0x0, 0xf, 0x5e"
+#define STR_EDCA_ETSI_ACVI_LOCAL_LEN (sizeof(STR_EDCA_ETSI_ACVI_LOCAL) - 1)
+
+#define CFG_EDCA_ETSI_ACVI_LOCAL CFG_STRING( \
+		"edca_etsi_acvi_local", \
+		0, \
+		STR_EDCA_ETSI_ACVI_LOCAL_LEN, \
+		STR_EDCA_ETSI_ACVI_LOCAL, \
+		"EDCA ETSI ACVI LOCAL")
+
+#define STR_EDCA_ETSI_ACVO_LOCAL "0x0, 0x1, 0x0, 0x3, 0x0, 0x7, 0x3e, 0x0, 0x3, 0x0, 0x7, 0x66, 0x0, 0x3, 0x0, 0x7, 0x2f"
+#define STR_EDCA_ETSI_ACVO_LOCAL_LEN (sizeof(STR_EDCA_ETSI_ACVO_LOCAL) - 1)
+
+#define CFG_EDCA_ETSI_ACVO_LOCAL CFG_STRING( \
+		"edca_etsi_acvo_local", \
+		0, \
+		STR_EDCA_ETSI_ACVO_LOCAL_LEN, \
+		STR_EDCA_ETSI_ACVO_LOCAL, \
+		"EDCA ETSI ACVO LOCAL")
+
+#define STR_EDCA_ETSI_ACBK "0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0xbb, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0"
+#define STR_EDCA_ETSI_ACBK_LEN (sizeof(STR_EDCA_ETSI_ACBK) - 1)
+
+#define CFG_EDCA_ETSI_ACBK CFG_STRING( \
+		"edca_etsi_acbk", \
+		0, \
+		STR_EDCA_ETSI_ACBK_LEN, \
+		STR_EDCA_ETSI_ACBK, \
+		"EDCA ETSI ACBK BROADCAST")
+
+#define STR_EDCA_ETSI_ACBE "0x0, 0x3, 0x0, 0xf, 0x3, 0xff, 0xbb, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0"
+#define STR_EDCA_ETSI_ACBE_LEN (sizeof(STR_EDCA_ETSI_ACBE) - 1)
+
+#define CFG_EDCA_ETSI_ACBE CFG_STRING( \
+		"edca_etsi_acbe", \
+		0, \
+		STR_EDCA_ETSI_ACBE_LEN, \
+		STR_EDCA_ETSI_ACBE, \
+		"EDCA ETSI ACBE BROADCAST")
+
+#define STR_EDCA_ETSI_ACVI "0x0, 0x2, 0x0, 0x7, 0x0, 0xf, 0x7d, 0x0, 0x7, 0x0, 0xf, 0xbc, 0x0, 0x7, 0x0, 0xf, 0x5e"
+#define STR_EDCA_ETSI_ACVI_LEN (sizeof(STR_EDCA_ETSI_ACVI) - 1)
+
+#define CFG_EDCA_ETSI_ACVI CFG_STRING( \
+		"edca_etsi_acvi", \
+		0, \
+		STR_EDCA_ETSI_ACVI_LEN, \
+		STR_EDCA_ETSI_ACVI, \
+		"EDCA ETSI ACVI BROADCAST")
+
+#define STR_EDCA_ETSI_ACVO "0x0, 0x2, 0x0, 0x3, 0x0, 0x7, 0x3e, 0x0, 0x3, 0x0, 0x7, 0x66, 0x0, 0x3, 0x0, 0x7, 0x2f"
+#define STR_EDCA_ETSI_ACVO_LEN (sizeof(STR_EDCA_ETSI_ACVO) - 1)
+
+#define CFG_EDCA_ETSI_ACVO CFG_STRING( \
+		"edca_etsi_acvo", \
+		0, \
+		STR_EDCA_ETSI_ACVO_LEN, \
+		STR_EDCA_ETSI_ACVO, \
+		"EDCA ETSI ACVO BROADCAST")
+
+/*
+ * <ini>
+ * gEnableEdcaParams - Enable edca parameter
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used if gEnableEdcaParams is set to 1, params gEdcaVoCwmin,
+ * gEdcaViCwmin, gEdcaBkCwmin, gEdcaBeCwmin, gEdcaVoCwmax,
+ * gEdcaViCwmax, gEdcaBkCwmax, gEdcaBeCwmax, gEdcaVoAifs,
+ * gEdcaViAifs, gEdcaBkAifs and gEdcaBeAifs values are used
+ * to overwrite the values received from AP
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_EDCA_ENABLE_PARAM CFG_INI_BOOL( \
+		"gEnableEdcaParams", \
+		0, \
+		"Enable edca parameter")
+
+/*
+ * <ini>
+ * gEdcaVoCwmin - Set Cwmin value for EDCA_AC_VO
+ * @Min: 0
+ * @Max: 0x15
+ * @Default: 2
+ *
+ * This ini is used to set default Cwmin value for EDCA_AC_VO
+ * Cwmin value for EDCA_AC_VO. CWVomin = 2^gEdcaVoCwmin -1
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin etc
+ * are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_EDCA_VO_CWMIN CFG_INI_UINT( \
+		"gEdcaVoCwmin", \
+		0x0, \
+		15, \
+		2, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Cwmin value for EDCA_AC_VO")
+
+/*
+ * <ini>
+ * gEdcaVoCwmax - Set Cwmax value for EDCA_AC_VO
+ * @Min: 0
+ * @Max: 15
+ * @Default: 3
+ *
+ * This ini is used to set default Cwmax value for EDCA_AC_VO
+ * Cwmax value for EDCA_AC_VO. CWVomax = 2^gEdcaVoCwmax -1
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin
+ * etc are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_EDCA_VO_CWMAX CFG_INI_UINT( \
+		"gEdcaVoCwmax", \
+		0x0, \
+		15, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Cwmax value for EDCA_AC_VO")
+
+/*
+ * <ini>
+ * gEdcaVoAifs - Set Aifs value for EDCA_AC_VO
+ * @Min: 0
+ * @Max: 15
+ * @Default: 2
+ *
+ * This ini is used to set default Aifs value for EDCA_AC_VO
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin
+ * etc are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_EDCA_VO_AIFS CFG_INI_UINT( \
+		"gEdcaVoAifs", \
+		0x0, \
+		15, \
+		2, \
+		CFG_VALUE_OR_DEFAULT, \
+		"default Aifs value for EDCA_AC_VO")
+
+/*
+ * <ini>
+ * gEdcaViCwmin - Set Cwmin value for EDCA_AC_VI
+ * @Min: 0x0
+ * @Max: 15
+ * @Default: 3
+ *
+ * This ini is used to set default value for EDCA_AC_VI
+ * Cwmin value for EDCA_AC_VI. CWVimin = 2^gEdcaViCwmin -1
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin
+ * etc are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_EDCA_VI_CWMIN CFG_INI_UINT( \
+		"gEdcaViCwmin", \
+		0x0, \
+		15, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Cwmin value for EDCA_AC_VI")
+
+/*
+ * <ini>
+ * gEdcaViCwmax - Set Cwmax value for EDCA_AC_VI
+ * @Min: 0
+ * @Max: 15
+ * @Default: 4
+ *
+ * This ini is used to set default Cwmax value for EDCA_AC_VI
+ * Cwmax value for EDCA_AC_VI. CWVimax = 2^gEdcaViCwmax -1
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin
+ * etc are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_EDCA_VI_CWMAX CFG_INI_UINT( \
+		"gEdcaViCwmax", \
+		0x0, \
+		15, \
+		4, \
+		CFG_VALUE_OR_DEFAULT, \
+		"cwmax value for EDCA_AC_VI")
+
+/*
+ * <ini>
+ * gEdcaViAifs - Set Aifs value for EDCA_AC_VI
+ * @Min: 0
+ * @Max: 15
+ * @Default: 2
+ *
+ * This ini is used to set default Aifs value for EDCA_AC_VI
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin
+ * etc are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_EDCA_VI_AIFS CFG_INI_UINT( \
+		"gEdcaViAifs", \
+		0x0, \
+		15, \
+		2, \
+		CFG_VALUE_OR_DEFAULT, \
+		"default Aifs value for EDCA_AC_VI")
+
+/*
+ * <ini>
+ * gEdcaBkCwmin - Set Cwmin value for EDCA_AC_BK
+ * @Min: 0x0
+ * @Max: 15
+ * @Default: 4
+ *
+ * This ini is used to set default Cwmin value for EDCA_AC_BK
+ * Cwmin value for EDCA_AC_BK. CWBkmin = 2^gEdcaBkCwmin -1
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin
+ * etc are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ * </ini>
+ */
+#define CFG_EDCA_BK_CWMIN CFG_INI_UINT( \
+		"gEdcaBkCwmin", \
+		0x0, \
+		15, \
+		4, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Cwmin value for EDCA_AC_BK")
+
+/*
+ * <ini>
+ * gEdcaBkCwmax - Set Cwmax value for EDCA_AC_BK
+ * @Min: 0
+ * @Max: 15
+ * @Default: 10
+ *
+ * This ini is used to set default Cwmax value for EDCA_AC_BK
+ * Cwmax value for EDCA_AC_BK. CWBkmax = 2^gEdcaBkCwmax -1
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin
+ * etc are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_EDCA_BK_CWMAX CFG_INI_UINT( \
+		"gEdcaBkCwmax", \
+		0, \
+		15, \
+		10, \
+		CFG_VALUE_OR_DEFAULT, \
+		"cwmax value for EDCA_AC_BK")
+
+/*
+ * <ini>
+ * gEdcaBkAifs - Set Aifs value for EDCA_AC_BK
+ * @Min: 0
+ * @Max: 15
+ * @Default: 7
+ *
+ * This ini is used to set default Aifs value for EDCA_AC_BK
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin
+ * etc are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_EDCA_BK_AIFS CFG_INI_UINT( \
+		"gEdcaBkAifs", \
+		0, \
+		15, \
+		7, \
+		CFG_VALUE_OR_DEFAULT, \
+		"default Aifs value for EDCA_AC_BK")
+
+/*
+ * <ini>
+ * gEdcaBeCwmin - Set Cwmin value for EDCA_AC_BE
+ * @Min: 0x0
+ * @Max: 15
+ * @Default: 4
+ *
+ * This ini is used to set default Cwmin value for EDCA_AC_BE
+ * Cwmin value for EDCA_AC_BE. CWBemin = 2^gEdcaBeCwmin
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin
+ * etc are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_EDCA_BE_CWMIN CFG_INI_UINT( \
+		"gEdcaBeCwmin", \
+		0x0, \
+		15, \
+		4, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Cwmin value for EDCA_AC_BE")
+
+/*
+ * <ini>
+ * gEdcaBeCwmax - Set Cwmax value for EDCA_AC_BE
+ * @Min: 0
+ * @Max: 15
+ * @Default: 10
+ *
+ * This ini is used to set default Cwmax value for EDCA_AC_BE
+ * Cwmax value for EDCA_AC_BE. CWBemax = 2^gEdcaBeCwmax -1
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin
+ * etc are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_EDCA_BE_CWMAX CFG_INI_UINT( \
+		"gEdcaBeCwmax", \
+		0, \
+		15, \
+		10, \
+		CFG_VALUE_OR_DEFAULT, \
+		"cwmax value for EDCA_AC_BE")
+
+/*
+ * <ini>
+ * gEdcaBeAifs - Set Aifs value for EDCA_AC_BE
+ * @Min: 0
+ * @Max: 15
+ * @Default: 3
+ *
+ * This ini is used to set default Aifs value for EDCA_AC_BE
+ *
+ * Related: If gEnableEdcaParams is set to 1, params gEdcaVoCwmin
+ * etc are aplicable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_EDCA_BE_AIFS CFG_INI_UINT( \
+		"gEdcaBeAifs", \
+		0, \
+		15, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"default Aifs value for EDCA_AC_BE")
+
+#define CFG_EDCA_PARAMS_ALL \
+	CFG(CFG_EDCA_ANI_ACBK_LOCAL) \
+	CFG(CFG_EDCA_ANI_ACBE_LOCAL) \
+	CFG(CFG_EDCA_ANI_ACVI_LOCAL) \
+	CFG(CFG_EDCA_ANI_ACVO_LOCAL) \
+	CFG(CFG_EDCA_ANI_ACBK) \
+	CFG(CFG_EDCA_ANI_ACBE) \
+	CFG(CFG_EDCA_ANI_ACVI) \
+	CFG(CFG_EDCA_ANI_ACVO) \
+	CFG(CFG_EDCA_WME_ACBK_LOCAL) \
+	CFG(CFG_EDCA_WME_ACBE_LOCAL) \
+	CFG(CFG_EDCA_WME_ACVI_LOCAL) \
+	CFG(CFG_EDCA_WME_ACVO_LOCAL) \
+	CFG(CFG_EDCA_WME_ACBK) \
+	CFG(CFG_EDCA_WME_ACBE) \
+	CFG(CFG_EDCA_WME_ACVI) \
+	CFG(CFG_EDCA_WME_ACVO) \
+	CFG(CFG_EDCA_ETSI_ACBK_LOCAL) \
+	CFG(CFG_EDCA_ETSI_ACBE_LOCAL) \
+	CFG(CFG_EDCA_ETSI_ACVI_LOCAL) \
+	CFG(CFG_EDCA_ETSI_ACVO_LOCAL) \
+	CFG(CFG_EDCA_ETSI_ACBK) \
+	CFG(CFG_EDCA_ETSI_ACBE) \
+	CFG(CFG_EDCA_ETSI_ACVI) \
+	CFG(CFG_EDCA_ETSI_ACVO) \
+	CFG(CFG_EDCA_ENABLE_PARAM) \
+	CFG(CFG_EDCA_VO_CWMIN) \
+	CFG(CFG_EDCA_VO_CWMAX) \
+	CFG(CFG_EDCA_VO_AIFS) \
+	CFG(CFG_EDCA_VI_CWMIN) \
+	CFG(CFG_EDCA_VI_CWMAX) \
+	CFG(CFG_EDCA_VI_AIFS) \
+	CFG(CFG_EDCA_BK_CWMIN) \
+	CFG(CFG_EDCA_BK_CWMAX) \
+	CFG(CFG_EDCA_BK_AIFS) \
+	CFG(CFG_EDCA_BE_CWMIN) \
+	CFG(CFG_EDCA_BE_CWMAX) \
+	CFG(CFG_EDCA_BE_AIFS)
+
+#endif  /* __CFG_MLME_EDCA__PARAM_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_fe_wmm.h b/components/mlme/dispatcher/inc/cfg_mlme_fe_wmm.h
new file mode 100644
index 0000000..3ac3283
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_fe_wmm.h
@@ -0,0 +1,893 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_FE_WMM_H
+#define __CFG_MLME_FE_WMM_H
+
+#define CFG_QOS_ENABLED CFG_BOOL( \
+		"qos_enabled", \
+		0, \
+		"QOS Enabled")
+
+#define CFG_WME_ENABLED CFG_BOOL( \
+		"wme_enabled", \
+		1, \
+		"WME Enabled")
+
+#define CFG_MAX_SP_LENGTH CFG_UINT( \
+		"max_sp_length", \
+		0, \
+		3, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"MAX sp length")
+
+#define CFG_WSM_ENABLED CFG_BOOL( \
+		"wsm_enabled", \
+		0, \
+		"WSM Enabled")
+
+#define CFG_EDCA_PROFILE CFG_UINT( \
+		"edca_profile", \
+		0, \
+		4, \
+		1, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Edca Profile")
+
+/* default TSPEC parameters for AC_VO */
+/*
+ * <ini>
+ * InfraDirAcVo - Set TSPEC direction for VO
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * This ini is used to set TSPEC direction for VO
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_DIR_AC_VO CFG_INI_UINT( \
+		"InfraDirAcVo", \
+		0, \
+		3, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"direction for vo")
+
+/*
+ * <ini>
+ * InfraNomMsduSizeAcVo - Set normal MSDU size for VO
+ * @Min: 0x0
+ * @Max: 0xFFFF
+ * @Default: 0x80D0
+ *
+ * This ini is used to set normal MSDU size for VO
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_NOM_MSDU_SIZE_AC_VO CFG_INI_UINT( \
+		"InfraNomMsduSizeAcVo", \
+		0x0, \
+		0xFFFF, \
+		0x80D0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"MSDU size for VO")
+
+/*
+ * <ini>
+ * InfraMeanDataRateAcVo - Set mean data rate for VO
+ * @Min: 0x0
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x14500
+ *
+ * This ini is used to set mean data rate for VO
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_MEAN_DATA_RATE_AC_VO CFG_INI_UINT( \
+		"InfraMeanDataRateAcVo", \
+		0x0, \
+		0xFFFFFFFF, \
+		0x14500, \
+		CFG_VALUE_OR_DEFAULT, \
+		"mean data rate for VO")
+
+/*
+ * <ini>
+ * InfraMinPhyRateAcVo - Set min PHY rate for VO
+ * @Min: 0x0
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x5B8D80
+ *
+ * This ini is used to set min PHY rate for VO
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_MIN_PHY_RATE_AC_VO CFG_INI_UINT( \
+		"InfraMinPhyRateAcVo", \
+		0x0, \
+		0xFFFFFFFF, \
+		0x5B8D80, \
+		CFG_VALUE_OR_DEFAULT, \
+		"min PHY rate for VO")
+
+/*
+ * <ini>
+ * InfraSbaAcVo - Set surplus bandwidth allowance for VO
+ * @Min: 0x2001
+ * @Max: 0xFFFF
+ * @Default: 0x2001
+ *
+ * This ini is used to set surplus bandwidth allowance for VO
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+*
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_SBA_AC_VO CFG_INI_UINT( \
+		"InfraSbaAcVo", \
+		0x2001, \
+		0xFFFF, \
+		0x2001, \
+		CFG_VALUE_OR_DEFAULT, \
+		"surplus bandwidth allowance for VO")
+/*
+ * <ini>
+ * InfraDirAcVi - Set TSPEC direction for VI
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * This ini is used to set TSPEC direction for VI
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_DIR_AC_VI CFG_INI_UINT( \
+		"InfraDirAcVi", \
+		0, \
+		3, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"TSPEC direction for VI")
+
+/*
+ * <ini>
+ * InfraNomMsduSizeAcVi - Set normal MSDU size for VI
+ * @Min: 0x0
+ * @Max: 0xFFFF
+ * @Default: 0x85DC
+ *
+ * This ini is used to set normal MSDU size for VI
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_NOM_MSDU_SIZE_AC_VI CFG_INI_UINT( \
+		"InfraNomMsduSizeAcVi", \
+		0x0, \
+		0xFFFF, \
+		0x85DC, \
+		CFG_VALUE_OR_DEFAULT, \
+		"MSDU size for VI")
+
+/*
+ * <ini>
+ * InfraMeanDataRateAcVi - Set mean data rate for VI
+ * @Min: 0x0
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x57E40
+ *
+ * This ini is used to set mean data rate for VI
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_MEAN_DATA_RATE_AC_VI CFG_INI_UINT( \
+		"InfraMeanDataRateAcVi", \
+		0x0, \
+		0xFFFFFFFF, \
+		0x57E40, \
+		CFG_VALUE_OR_DEFAULT, \
+		"data rate for VI")
+
+/*
+ * <ini>
+ * iInfraMinPhyRateAcVi - Set min PHY rate for VI
+ * @Min: 0x0
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x5B8D80
+ *
+ * This ini is used to set min PHY rate for VI
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_MIN_PHY_RATE_AC_VI CFG_INI_UINT( \
+		"InfraMinPhyRateAcVi", \
+		0x0, \
+		0xFFFFFFFF, \
+		0x5B8D80, \
+		CFG_VALUE_OR_DEFAULT, \
+		"min PHY rate for VI")
+
+/*
+ * <ini>
+ * InfraSbaAcVi - Set surplus bandwidth allowance for VI
+ * @Min: 0x2001
+ * @Max: 0xFFFF
+ * @Default: 0x2001
+ *
+ * This ini is used to set surplus bandwidth allowance for VI
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_QOS_WMM_SBA_AC_VI CFG_INI_UINT( \
+		"InfraSbaAcVi", \
+		0x2001, \
+		0xFFFF, \
+		0x2001, \
+		CFG_VALUE_OR_DEFAULT, \
+		"surplus bandwidth allowance for VI")
+
+/*
+ * <ini>
+ * InfraUapsdVoSrvIntv - Set Uapsd service interval for voice
+ * @Min: 0
+ * @Max: 4294967295UL
+ * @Default: 20
+ *
+ * This ini is used to set Uapsd service interval for voice.
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_UAPSD_VO_SRV_INTV CFG_INI_UINT( \
+		"InfraUapsdVoSrvIntv", \
+		0, \
+		4294967295UL, \
+		20, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Infra uapsd vo srv intv")
+
+/*
+ * <ini>
+ * InfraUapsdVoSuspIntv - Set Uapsd suspension interval for voice
+ * @Min: 0
+ * @Max: 4294967295UL
+ * @Default: 2000
+ *
+ * This ini is used to set Uapsd suspension interval for voice.
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_UAPSD_VO_SUS_INTV CFG_INI_UINT( \
+		"InfraUapsdVoSuspIntv", \
+		0, \
+		4294967295UL, \
+		2000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Infra uapsd vo sus intv")
+
+/*
+ * <ini>
+ * InfraUapsdViSrvIntv - Set Uapsd service interval for video
+ * @Min: 0
+ * @Max: 4294967295UL
+ * @Default: 300
+ *
+ * This ini is used to set Uapsd service interval for video.
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_QOS_WMM_UAPSD_VI_SRV_INTV CFG_INI_UINT( \
+		"InfraUapsdViSrvIntv", \
+		0, \
+		4294967295UL, \
+		300, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Infra uapsd vi srv intv")
+
+/*
+ * <ini>
+ * InfraUapsdViSuspIntv - Set Uapsd suspension interval for video
+ * @Min: 0
+ * @Max: 4294967295UL
+ * @Default: 2000
+ *
+ * This ini is used to set Uapsd suspension interval for video
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_UAPSD_VI_SUS_INTV CFG_INI_UINT( \
+		"InfraUapsdViSuspIntv", \
+		0, \
+		4294967295UL, \
+		2000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Infra uapsd vi sus intv")
+
+/*
+ * <ini>
+ * InfraDirAcBe - Set TSPEC direction for BE
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * This ini is used to set TSPEC direction for BE
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_DIR_AC_BE CFG_INI_UINT( \
+		"InfraDirAcBe", \
+		0, \
+		3, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"TSPEC direction for BE")
+
+/*
+ * <ini>
+ * InfraNomMsduSizeAcBe - Set normal MSDU size for BE
+ * @Min: 0x0
+ * @Max: 0xFFFF
+ * @Default: 0x85DC
+ *
+ * This ini is used to set normal MSDU size for BE
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_NOM_MSDU_SIZE_AC_BE CFG_INI_UINT( \
+		"InfraNomMsduSizeAcBe", \
+		0x0, \
+		0xFFFF, \
+		0x85DC, \
+		CFG_VALUE_OR_DEFAULT, \
+		"MSDU size for BE")
+
+/*
+ * <ini>
+ * InfraMeanDataRateAcBe - Set mean data rate for BE
+ * @Min: 0x0
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x493E0
+ *
+ * This ini is used to set mean data rate for BE
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_MEAN_DATA_RATE_AC_BE CFG_INI_UINT( \
+		"InfraMeanDataRateAcBe", \
+		0x0, \
+		0xFFFFFFFF, \
+		0x493E0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"data rate for BE")
+
+/*
+ * <ini>
+ * InfraMinPhyRateAcBe - Set min PHY rate for BE
+ * @Min: 0x0
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x5B8D80
+ *
+ * This ini is used to set min PHY rate for BE
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_MIN_PHY_RATE_AC_BE CFG_INI_UINT( \
+		"InfraMinPhyRateAcBe", \
+		0x0, \
+		0xFFFFFFFF, \
+		0x5B8D80, \
+		CFG_VALUE_OR_DEFAULT, \
+		"min PHY rate for BE")
+
+/*
+ * <ini>
+ * InfraSbaAcBe - Set surplus bandwidth allowance for BE
+ * @Min: 0x2001
+ * @Max: 0xFFFF
+ * @Default: 0x2001
+ *
+ * This ini is used to set surplus bandwidth allowance for BE
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_SBA_AC_BE CFG_INI_UINT( \
+		"InfraSbaAcBe", \
+		0x2001, \
+		0xFFFF, \
+		0x2001, \
+		CFG_VALUE_OR_DEFAULT, \
+		"surplus bandwidth allowance for BE")
+
+/*
+ * <ini>
+ * InfraUapsdBeSrvIntv - Set Uapsd service interval for BE
+ * @Min: 0
+ * @Max: 4294967295UL
+ * @Default: 300
+ *
+ * This ini is used to set Uapsd service interval for BE
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_UAPSD_BE_SRV_INTV CFG_INI_UINT( \
+		"InfraUapsdBeSrvIntv", \
+		0, \
+		4294967295UL, \
+		300, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Infra uapsd be srv intv")
+
+/*
+ * <ini>
+ * InfraUapsdBeSuspIntv - Set Uapsd suspension interval for BE
+ * @Min: 0
+ * @Max: 4294967295UL
+ * @Default: 2000
+ *
+ * This ini is used to set Uapsd suspension interval for BE
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_UAPSD_BE_SUS_INTV CFG_INI_UINT( \
+		"InfraUapsdBeSuspIntv", \
+		0, \
+		4294967295UL, \
+		2000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Infra uapsd vi sus intv")
+
+/*
+ * <ini>
+ * InfraDirAcBk - Set TSPEC direction for BK
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * This ini is used to set TSPEC direction for BK
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_DIR_AC_BK CFG_INI_UINT( \
+		"InfraDirAcBk", \
+		0, \
+		3, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"TSPEC direction for BK")
+
+/*
+ * <ini>
+ * InfraNomMsduSizeAcBk - Set normal MSDU size for BK
+ * @Min: 0x0
+ * @Max: 0xFFFF
+ * @Default: 0x85DC
+ *
+ * This ini is used to set normal MSDU size for BK
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_NOM_MSDU_SIZE_AC_BK CFG_INI_UINT( \
+		"InfraNomMsduSizeAcBk", \
+		0x0, \
+		0xFFFF, \
+		0x85DC, \
+		CFG_VALUE_OR_DEFAULT, \
+		"MSDU size for BK")
+
+/*
+ * <ini>
+ * InfraMeanDataRateAcBk - Set mean data rate for BK
+ * @Min: 0x0
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x493E0
+ *
+ * This ini is used to set mean data rate for BK
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_MEAN_DATA_RATE_AC_BK CFG_INI_UINT( \
+		"InfraMeanDataRateAcBk", \
+		0x0, \
+		0xFFFFFFFF, \
+		0x493E0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"data rate for BK")
+
+/*
+ * <ini>
+ * InfraMinPhyRateAcBke - Set min PHY rate for BK
+ * @Min: 0x0
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x5B8D80
+ *
+ * This ini is used to set min PHY rate for BK
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_MIN_PHY_RATE_AC_BK CFG_INI_UINT( \
+		"InfraMinPhyRateAcBk", \
+		0x0, \
+		0xFFFFFFFF, \
+		0x5B8D80, \
+		CFG_VALUE_OR_DEFAULT, \
+		"min PHY rate for BK")
+
+/*
+ * <ini>
+ * InfraSbaAcBk - Set surplus bandwidth allowance for BK
+ * @Min: 0x2001
+ * @Max: 0xFFFF
+ * @Default: 0x2001
+ *
+ * This ini is used to set surplus bandwidth allowance for BK
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_SBA_AC_BK CFG_INI_UINT( \
+		"InfraSbaAcBk", \
+		0x2001, \
+		0xFFFF, \
+		0x2001, \
+		CFG_VALUE_OR_DEFAULT, \
+		"surplus bandwidth allowance for BK")
+
+/*
+ * <ini>
+ * InfraUapsdBkSrvIntv - Set Uapsd service interval for BK
+ * @Min: 0
+ * @Max: 4294967295UL
+ * @Default: 300
+ *
+ * This ini is used to set Uapsd service interval for BK
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_UAPSD_BK_SRV_INTV CFG_INI_UINT( \
+		"InfraUapsdBkSrvIntv", \
+		0, \
+		4294967295UL, \
+		300, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Infra uapsd bk srv intv")
+
+/*
+ * <ini>
+ * InfraUapsdBkSuspIntv - Set Uapsd suspension interval for BK
+ * @Min: 0
+ * @Max: 4294967295UL
+ * @Default: 2000
+ *
+ * This ini is used to set Uapsd suspension interval for BK
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_UAPSD_BK_SUS_INTV CFG_INI_UINT( \
+		"InfraUapsdBkSuspIntv", \
+		0, \
+		4294967295UL, \
+		2000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Infra uapsd bk sus intv")
+
+/* WMM configuration */
+/*
+ * <ini>
+ * WmmIsEnabled - Enable WMM feature
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * This ini is used to enable/disable WMM.
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_MODE CFG_INI_UINT( \
+		"WmmIsEnabled", \
+		0, \
+		2, \
+		2, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Enable WMM feature")
+
+/*
+ * <ini>
+ * 80211eIsEnabled - Enable 802.11e feature
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable 802.11e.
+ *
+ * Related: None.
+ *
+ * Supported Feature: 802.11e
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_80211E_ENABLED CFG_INI_BOOL( \
+		"80211eIsEnabled", \
+		0, \
+		"Enable 802.11e feature")
+
+/*
+ * <ini>
+ * UapsdMask - To setup U-APSD mask for ACs
+ * @Min: 0x00
+ * @Max: 0xFF
+ * @Default: 0x00
+ *
+ * This ini is used to setup U-APSD mask for ACs.
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_UAPSD_MASK CFG_INI_UINT( \
+		"UapsdMask", \
+		0x00, \
+		0xFF, \
+		0x00, \
+		CFG_VALUE_OR_DEFAULT, \
+		"setup U-APSD mask for ACs")
+
+/*
+ * <ini>
+ * ImplicitQosIsEnabled - Enableimplicit QOS
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable implicit QOS.
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_IMPLICIT_SETUP_ENABLED CFG_INI_BOOL( \
+		"ImplicitQosIsEnabled", \
+		0, \
+		"Enable implicit QOS")
+
+#define CFG_WMM_PARAMS_ALL \
+	CFG(CFG_QOS_ENABLED) \
+	CFG(CFG_WME_ENABLED) \
+	CFG(CFG_MAX_SP_LENGTH) \
+	CFG(CFG_WSM_ENABLED) \
+	CFG(CFG_EDCA_PROFILE) \
+	CFG(CFG_QOS_WMM_DIR_AC_VO) \
+	CFG(CFG_QOS_WMM_NOM_MSDU_SIZE_AC_VO) \
+	CFG(CFG_QOS_WMM_MEAN_DATA_RATE_AC_VO) \
+	CFG(CFG_QOS_WMM_MIN_PHY_RATE_AC_VO) \
+	CFG(CFG_QOS_WMM_SBA_AC_VO) \
+	CFG(CFG_QOS_WMM_UAPSD_VO_SRV_INTV) \
+	CFG(CFG_QOS_WMM_UAPSD_VO_SUS_INTV) \
+	CFG(CFG_QOS_WMM_DIR_AC_VI) \
+	CFG(CFG_QOS_WMM_NOM_MSDU_SIZE_AC_VI) \
+	CFG(CFG_QOS_WMM_MEAN_DATA_RATE_AC_VI) \
+	CFG(CFG_QOS_WMM_MIN_PHY_RATE_AC_VI) \
+	CFG(CFG_QOS_WMM_SBA_AC_VI) \
+	CFG(CFG_QOS_WMM_UAPSD_VI_SRV_INTV) \
+	CFG(CFG_QOS_WMM_UAPSD_VI_SUS_INTV) \
+	CFG(CFG_QOS_WMM_DIR_AC_BE) \
+	CFG(CFG_QOS_WMM_NOM_MSDU_SIZE_AC_BE) \
+	CFG(CFG_QOS_WMM_MEAN_DATA_RATE_AC_BE) \
+	CFG(CFG_QOS_WMM_MIN_PHY_RATE_AC_BE) \
+	CFG(CFG_QOS_WMM_SBA_AC_BE) \
+	CFG(CFG_QOS_WMM_UAPSD_BE_SRV_INTV) \
+	CFG(CFG_QOS_WMM_UAPSD_BE_SUS_INTV) \
+	CFG(CFG_QOS_WMM_DIR_AC_BK) \
+	CFG(CFG_QOS_WMM_NOM_MSDU_SIZE_AC_BK) \
+	CFG(CFG_QOS_WMM_MEAN_DATA_RATE_AC_BK) \
+	CFG(CFG_QOS_WMM_MIN_PHY_RATE_AC_BK) \
+	CFG(CFG_QOS_WMM_SBA_AC_BK) \
+	CFG(CFG_QOS_WMM_UAPSD_BK_SRV_INTV) \
+	CFG(CFG_QOS_WMM_UAPSD_BK_SUS_INTV) \
+	CFG(CFG_QOS_WMM_MODE) \
+	CFG(CFG_QOS_WMM_80211E_ENABLED) \
+	CFG(CFG_QOS_WMM_UAPSD_MASK) \
+	CFG(CFG_QOS_WMM_IMPLICIT_SETUP_ENABLED)
+
+#endif /* __CFG_MLME_FE_WMM_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_feature_flag.h b/components/mlme/dispatcher/inc/cfg_mlme_feature_flag.h
new file mode 100644
index 0000000..a270063
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_feature_flag.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_FEATURE_FLAG_H
+#define __CFG_MLME_FEATURE_FLAG_H
+
+#define CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY CFG_BOOL( \
+		"accept_short_slot_assoc", \
+		0, \
+		"Accept short slot assoc only")
+
+#define CFG_HCF_ENABLED CFG_BOOL( \
+		"enable_hcf", \
+		0, \
+		"HCF enabled")
+
+#define CFG_RSN_ENABLED CFG_BOOL( \
+		"enable_rsn", \
+		0, \
+		"RSN enabled")
+
+#define CFG_11G_SHORT_PREAMBLE_ENABLED CFG_BOOL( \
+		"enable_short_preamble_11g", \
+		0, \
+		"Short Preamble Enable")
+
+#define CFG_11G_SHORT_SLOT_TIME_ENABLED CFG_BOOL( \
+		"enable_short_slot_time_11g", \
+		1, \
+		"Short Slot time enable")
+
+#define CFG_CHANNEL_BONDING_MODE CFG_UINT( \
+		"channel_bonding_mode", \
+		0, \
+		10, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"channel bonding mode")
+
+#define CFG_BLOCK_ACK_ENABLED CFG_UINT( \
+		"enable_block_ack", \
+		0, \
+		3, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"enable block Ack")
+/*
+ * <ini>
+ * gEnableAMPDUPS - Enable the AMPDUPS
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set default AMPDUPS
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_AMPDUPS CFG_INI_BOOL( \
+				"gEnableAMPDUPS", \
+				0, \
+				"Enable AMPDU")
+
+#define CFG_FEATURE_FLAG_ALL \
+	CFG(CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY) \
+	CFG(CFG_HCF_ENABLED) \
+	CFG(CFG_RSN_ENABLED) \
+	CFG(CFG_11G_SHORT_PREAMBLE_ENABLED) \
+	CFG(CFG_11G_SHORT_SLOT_TIME_ENABLED) \
+	CFG(CFG_CHANNEL_BONDING_MODE) \
+	CFG(CFG_BLOCK_ACK_ENABLED) \
+	CFG(CFG_ENABLE_AMPDUPS)
+
+#endif /* __CFG_MLME_FEATURE_FLAG_H */
+
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_generic.h b/components/mlme/dispatcher/inc/cfg_mlme_generic.h
new file mode 100644
index 0000000..eb5362b
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_generic.h
@@ -0,0 +1,496 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_GENERIC_H
+#define __CFG_MLME_GENERIC_H
+
+#ifdef WLAN_FEATURE_11W
+#define CFG_PMF_SA_QUERY_MAX_RETRIES_TYPE	CFG_INI_UINT
+#define CFG_PMF_SA_QUERY_RETRY_INTERVAL_TYPE	CFG_INI_UINT
+#else
+#define CFG_PMF_SA_QUERY_MAX_RETRIES_TYPE	CFG_UINT
+#define CFG_PMF_SA_QUERY_RETRY_INTERVAL_TYPE	CFG_UINT
+#endif /*WLAN_FEATURE_11W*/
+
+/*
+ * pmfSaQueryMaxRetries - Control PMF SA query retries for SAP
+ * @Min: 0
+ * @Max: 20
+ * @Default: 5
+ *
+ * This ini to set the number of PMF SA query retries for SAP
+ *
+ * Related: None.
+ *
+ * Supported Feature: PMF(11W)
+ *
+ */
+#define CFG_PMF_SA_QUERY_MAX_RETRIES CFG_PMF_SA_QUERY_MAX_RETRIES_TYPE( \
+		"pmfSaQueryMaxRetries", \
+		0, \
+		20, \
+		5, \
+		CFG_VALUE_OR_DEFAULT, \
+		"PMF SA query retries for SAP")
+/*
+ * pmfSaQueryRetryInterval - Control PMF SA query retry interval
+ * for SAP in ms
+ * @Min: 10
+ * @Max: 2000
+ * @Default: 200
+ *
+ * This ini to set the PMF SA query retry interval for SAP in ms
+ *
+ * Related: None.
+ *
+ * Supported Feature: PMF(11W)
+ *
+ */
+#define CFG_PMF_SA_QUERY_RETRY_INTERVAL CFG_PMF_SA_QUERY_RETRY_INTERVAL_TYPE( \
+		"pmfSaQueryRetryInterval", \
+		10, \
+		2000, \
+		200, \
+		CFG_VALUE_OR_DEFAULT, \
+		"PMF SA query retry interval for SAP")
+
+#define CFG_RTT3_ENABLE CFG_BOOL( \
+		"rtt3_enabled", \
+		1, \
+		"RTT3 enable/disable info")
+
+/*
+ * <ini>
+ * BandCapability - Preferred band (0: Both,  1: 2.4G only,  2: 5G only)
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * This ini is used to set default band capability
+ * (0: Both, 1: 2.4G only, 2: 5G only)
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_BAND_CAPABILITY CFG_INI_UINT( \
+	"BandCapability", \
+	0, \
+	2, \
+	0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Band Capability")
+
+/*
+ * <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>
+ */
+#if defined(QCA_WIFI_NAPIER_EMULATION) || defined(QCA_WIFI_QCA6290)
+#define CFG_PREVENT_LINK_DOWN CFG_INI_BOOL( \
+	"gPreventLinkDown", \
+	1, \
+	"Prevent Bus Link Down")
+#else
+#define CFG_PREVENT_LINK_DOWN CFG_INI_BOOL( \
+	"gPreventLinkDown", \
+	0, \
+	"Prevent Bus Link Down")
+#endif /* QCA_WIFI_NAPIER_EMULATION */
+
+/*
+ * <ini>
+ * gSelect5GHzMargin - Sets RSSI preference for 5GHz over 2.4GHz AP.
+ * @Min: 0
+ * @Max: 60
+ * @Default: 0
+ *
+ * Prefer connecting to 5G AP even if its RSSI is lower by gSelect5GHzMargin
+ * dBm than 2.4G AP. This feature requires the dependent cfg.ini
+ * "gRoamPrefer5GHz" set to 1
+ *
+ * Related: gRoamPrefer5GHz
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SELECT_5GHZ_MARGIN CFG_INI_UINT( \
+	"gSelect5GHzMargin", \
+	0, \
+	60, \
+	0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Select 5Ghz Margin")
+
+/*
+ * <ini>
+ * gEnableMemDeepSleep - Sets Memory Deep Sleep on/off.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ *
+ * Related: None
+ *
+ * Supported Feature: General
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_MEM_DEEP_SLEEP CFG_INI_BOOL( \
+	"gEnableMemDeepSleep", \
+	1, \
+	"Enable Memory Deep Sleep")
+
+/*
+ * <ini>
+ *
+ * gEnableCckTxFirOverride - Enable/disable CCK TxFIR Override
+ * @Min: 0 (disabled)
+ * @Max: 1 (enabled)
+ * @Default: 0 (disabled)
+ *
+ * When operating in an 802.11b mode, this configuration item forces a 2x2 radio
+ * configuration into 1x for Tx and 2x for Rx (ie 1x2) for regulatory compliance
+ * reasons.
+ *
+ * Related: enable2x2
+ *
+ * Supported Feature: 802.11b, 2x2
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_CCK_TX_FIR_OVERRIDE CFG_INI_BOOL( \
+	"gEnableCckTxFirOverride", \
+	0, \
+	"Enable CCK TX FIR Override")
+
+/*
+ * <ini>
+ *
+ * gEnableForceTargetAssert - Enable/disable SSR
+ * @Min: 0 (disabled)
+ * @Max: 1 (enabled)
+ * @Default: 0 (disabled)
+ *
+ * This INI item is used to control subsystem restart(SSR) test framework
+ * Set it's value to 1 to enable APPS trigerred SSR testing
+ *
+ * Related: None
+ *
+ * Supported Feature: General
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_CRASH_INJECT CFG_INI_BOOL( \
+	"gEnableForceTargetAssert", \
+	0, \
+	"Enable Crash Inject")
+
+/*
+ * <ini>
+ *
+ * gEnableLpassSupport - Enable/disable LPASS Support
+ * @Min: 0 (disabled)
+ * @Max: 1 (enabled)
+ * @Default: 0 (disabled)
+ *
+ * Related: None
+ *
+ * Supported Feature: General
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#ifdef WLAN_FEATURE_LPSS
+#define CFG_ENABLE_LPASS_SUPPORT CFG_INI_BOOL( \
+	"gEnableLpassSupport", \
+	0, \
+	"Enable LPASS Support")
+#else
+#define CFG_ENABLE_LPASS_SUPPORT CFG_BOOL( \
+	"gEnableLpassSupport", \
+	0, \
+	"Enable LPASS Support")
+#endif
+
+/*
+ * <ini>
+ *
+ * gEnableSelfRecovery - Enable/disable Self Recovery
+ * @Min: 0 (disabled)
+ * @Max: 1 (enabled)
+ * @Default: 0 (disabled)
+ *
+ * Related: None
+ *
+ * Supported Feature: General
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_SELF_RECOVERY CFG_INI_BOOL( \
+	"gEnableSelfRecovery", \
+	0, \
+	"Enable Self Recovery")
+
+/*
+ * <ini>
+ *
+ * gSapDot11mc - Enable/disable SAP 802.11mc support
+ * @Min: 0 (disabled)
+ * @Max: 1 (enabled)
+ * @Default: 0 (disabled)
+ *
+ * Related: None
+ *
+ * Supported Feature: General
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_SAP_DOT11MC CFG_INI_BOOL( \
+	"gSapDot11mc", \
+	0, \
+	"SAP 802.11mc support")
+
+/*
+ * <ini>
+ *
+ * gEnableFatalEvent - Enable/Disable BUG report in case of fatal event
+ * @Min: 0 (disabled)
+ * @Max: 1 (enabled)
+ * @Default: 1 (enabled)
+ *
+ * Related: None
+ *
+ * Supported Feature: General
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_FATAL_EVENT_TRIGGER CFG_INI_BOOL( \
+	"gEnableFatalEvent", \
+	1, \
+	"Enable Fatal Event Trigger")
+
+/*
+ * <ini>
+ * gSub20ChannelWidth - Control sub 20 channel width (5/10 Mhz)
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * This ini is used to set the sub 20 channel width.
+ * gSub20ChannelWidth=0: indicates do not use Sub 20 MHz bandwidth
+ * gSub20ChannelWidth=1: Bring up SAP/STA in 5 MHz bandwidth
+ * gSub20ChannelWidth=2: Bring up SAP/STA in 10 MHz bandwidth
+ *
+ * Related: None
+ *
+ * Supported Feature: 5/10 Mhz channel width support
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_SUB_20_CHANNEL_WIDTH CFG_INI_UINT( \
+	"gSub20ChannelWidth", \
+	0, \
+	2, \
+	0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Sub 20 Channel Width")
+
+/*
+ * <ini>
+ * goptimize_chan_avoid_event - Optimize channel avoidance indication
+ *				coming from firmware
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Related: None
+ *
+ * Supported Feature: General
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_OPTIMIZE_CA_EVENT CFG_INI_BOOL( \
+	"goptimize_chan_avoid_event", \
+	0, \
+	"Optimize FW CA Event")
+
+/*
+ * <ini>
+ * fw_timeout_crash - Enable/Disable BUG ON
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to Trigger host crash when firmware fails to send the
+ * response to host
+ * fw_timeout_crash = 0 Disabled
+ * fw_timeout_crash = 1 Trigger host crash
+ *
+ * Related: None
+ *
+ * Supported Feature: SSR
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_CRASH_FW_TIMEOUT CFG_INI_BOOL( \
+	"fw_timeout_crash", \
+	1, \
+	"Enable FW Timeout Crash")
+
+/*
+ * <ini>
+ * gDroppedPktDisconnectTh - Sets dropped packet threshold in firmware
+ * @Min: 0
+ * @Max: 65535
+ * @Default: 512
+ *
+ * This INI is the packet drop threshold will trigger disconnect from remote
+ * peer.
+ *
+ * Related: None
+ *
+ * Supported Feature: connection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_DROPPED_PKT_DISCONNECT_THRESHOLD CFG_INI_UINT( \
+	"gDroppedPktDisconnectTh", \
+	0, \
+	65535, \
+	512, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Dropped Pkt Disconnect threshold")
+
+/*
+ * <ini>
+ * gItoRepeatCount - sets ito repeated count
+ * @Min: 0
+ * @Max: 5
+ * @Default: 0
+ *
+ * This ini sets the ito count in FW
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ITO_REPEAT_COUNT CFG_INI_UINT( \
+	"gItoRepeatCount", \
+	0, \
+	5, \
+	0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"ITO Repeat Count")
+
+/*
+ * <ini>
+ * gEnableDebugLog - Enable/Disable the Connection related logs
+ * @Min: 0
+ * @Max: 0xFF
+ * @Default: 0x0F
+ *
+ * This ini is used to enable/disable the connection related logs
+ * 0x1 - Enable mgmt pkt logs (excpet probe req/rsp, beacons).
+ * 0x2 - Enable EAPOL pkt logs.
+ * 0x4 - Enable DHCP pkt logs.
+ * 0x8 - Enable mgmt action frames logs.
+ * 0x0 - Disable all the above connection related logs.
+ * The default value of 0x0F will enable all the above logs
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_DEBUG_PACKET_LOG CFG_INI_UINT( \
+				"gEnableDebugLog", \
+				0, 0xFF, 0x0F, \
+				CFG_VALUE_OR_DEFAULT, \
+				"Enable debug log")
+
+#define CFG_GENERIC_ALL \
+	CFG(CFG_ENABLE_DEBUG_PACKET_LOG) \
+	CFG(CFG_PMF_SA_QUERY_MAX_RETRIES) \
+	CFG(CFG_PMF_SA_QUERY_RETRY_INTERVAL) \
+	CFG(CFG_RTT3_ENABLE) \
+	CFG(CFG_BAND_CAPABILITY) \
+	CFG(CFG_PREVENT_LINK_DOWN) \
+	CFG(CFG_SELECT_5GHZ_MARGIN) \
+	CFG(CFG_ENABLE_MEM_DEEP_SLEEP) \
+	CFG(CFG_ENABLE_CCK_TX_FIR_OVERRIDE) \
+	CFG(CFG_ENABLE_CRASH_INJECT) \
+	CFG(CFG_ENABLE_LPASS_SUPPORT) \
+	CFG(CFG_ENABLE_SELF_RECOVERY) \
+	CFG(CFG_SAP_DOT11MC) \
+	CFG(CFG_ENABLE_FATAL_EVENT_TRIGGER) \
+	CFG(CFG_SUB_20_CHANNEL_WIDTH) \
+	CFG(CFG_OPTIMIZE_CA_EVENT) \
+	CFG(CFG_CRASH_FW_TIMEOUT) \
+	CFG(CFG_DROPPED_PKT_DISCONNECT_THRESHOLD) \
+	CFG(CFG_ITO_REPEAT_COUNT)
+
+#endif /* __CFG_MLME_GENERIC_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_he_caps.h b/components/mlme/dispatcher/inc/cfg_mlme_he_caps.h
new file mode 100644
index 0000000..5ff03754f
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_he_caps.h
@@ -0,0 +1,761 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_HE_CAPS_H
+#define __CFG_MLME_HE_CAPS_H
+
+#define CFG_HE_CONTROL CFG_BOOL( \
+				"he_control", \
+				0, \
+				"HE Control")
+
+#define CFG_HE_TWT_REQUESTOR CFG_BOOL( \
+				"he_twt_requestor", \
+				0, \
+				"HE Twt Requestor")
+
+#define CFG_HE_TWT_RESPONDER CFG_BOOL( \
+				"he_twt_responder", \
+				0, \
+				"HE Twt Responder")
+
+#define CFG_HE_TWT_FRAGMENTATION CFG_UINT( \
+				"he_twt_fragmentation", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"HE Twt Fragmentation")
+
+#define CFG_HE_MAX_FRAG_MSDU CFG_UINT( \
+				"he_max_frag_msdu", \
+				0, \
+				7, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"HE Max Frag Msdu")
+
+#define CFG_HE_MIN_FRAG_SIZE CFG_UINT( \
+				"he_min_frag_size", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"HE Min Frag Size")
+
+#define CFG_HE_TRIG_PAD CFG_UINT( \
+				"he_trig_pad", \
+				0, \
+				2, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"HE Trig Pad")
+
+#define CFG_HE_MTID_AGGR_RX CFG_UINT( \
+				"he_mtid_aggr_rx", \
+				0, \
+				7, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"HE Mtid Aggr")
+
+#define CFG_HE_LINK_ADAPTATION CFG_UINT( \
+				"he_link_adaptation", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"HE Link Adaptation")
+
+#define CFG_HE_ALL_ACK CFG_BOOL( \
+				"he_all_ack", \
+				0, \
+				"HE All Ack")
+
+#define CFG_HE_TRIGD_RSP_SCHEDULING CFG_BOOL( \
+				"he_trigd_rsp_scheduling", \
+				0, \
+				"HE Trigd Rsp Scheduling")
+
+#define CFG_HE_BUFFER_STATUS_RPT CFG_BOOL( \
+				"he_buffer_status_rpt", \
+				0, \
+				"HE Buffer Status Rpt")
+
+#define CFG_HE_BCAST_TWT CFG_BOOL( \
+				"he_bcast_twt", \
+				0, \
+				"HE Bcast twt")
+
+#define CFG_HE_BA_32BIT CFG_BOOL( \
+				"he_ba_32bit", \
+				0, \
+				"HE BA 32Bit")
+
+#define CFG_HE_MU_CASCADING CFG_BOOL( \
+				"he_mu_cascading", \
+				0, \
+				"HE Mu Cascading")
+
+#define CFG_HE_MULTI_TID CFG_BOOL( \
+				"he_multi_tid", \
+				0, \
+				"HE Multi Tid")
+
+#define CFG_HE_DL_MU_BA CFG_BOOL( \
+				"he_dl_mu_ba", \
+				0, \
+				"HE Dl_Mu_Ba")
+
+#define CFG_HE_OMI CFG_BOOL( \
+				"he_omi", \
+				0, \
+				"HE Omi")
+
+#define CFG_HE_OFDMA_RA CFG_BOOL( \
+				"he_ofdma_ra", \
+				0, \
+				"HE Ofdma Ra")
+
+#define CFG_HE_MAX_AMPDU_LEN CFG_UINT( \
+				"he_max_ampdu_len", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"HE Max Ampdu Len")
+
+#define CFG_HE_AMSDU_FRAG CFG_BOOL( \
+				"he_amspdu_frag", \
+				0, \
+				"HE Amsdu Frag")
+
+#define CFG_HE_FLEX_TWT_SCHED CFG_BOOL( \
+				"he_flex_twt_sched", \
+				0, \
+				"HE Flex Twt Sched")
+
+#define CFG_HE_RX_CTRL CFG_BOOL( \
+				"he_rx_ctrl", \
+				0, \
+				"HE Rx Ctrl")
+
+#define CFG_HE_BSRP_AMPDU_AGGR CFG_BOOL( \
+				"he_bsrp_ampdu_aggr", \
+				0, \
+				"He Bspr Ampdu Aggr")
+
+#define CFG_HE_QTP CFG_BOOL( \
+				"he_qtp", \
+				0, \
+				"He Qtp")
+
+#define CFG_HE_A_BQR CFG_BOOL( \
+				"he_a_bqr", \
+				0, \
+				"He A Bqr")
+
+#define CFG_HE_SR_RESPONDER CFG_BOOL( \
+				"he_sr_responder", \
+				0, \
+				"He Sr Responder")
+
+#define CFG_HE_NDP_FEEDBACK_SUPP CFG_BOOL( \
+				"he_ndp_feedback_supp", \
+				0, \
+				"He Ndp Feedback Supp")
+
+#define CFG_HE_OPS_SUPP CFG_BOOL( \
+				"he_ops_supp", \
+				0, \
+				"He Ops Supp")
+
+#define CFG_HE_AMSDU_IN_AMPDU CFG_BOOL( \
+				"he_amsdu_in_ampdu", \
+				0, \
+				"He Amsdu In Ampdu")
+
+#define CFG_HE_MTID_AGGR_TX CFG_UINT( \
+				"he_mtid_aggr_tx", \
+				0, \
+				0x7, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He MTid Aggr Tx")
+
+#define CFG_HE_SUB_CH_SEL_TX CFG_BOOL( \
+				"he_sub_ch_sel_tx", \
+				0, \
+				"He Sub cg sel tx")
+
+#define CFG_HE_UL_2X996_RU CFG_BOOL( \
+				"he_ul_2x996_ru", \
+				0, \
+				"He Ul 2x996 Ru")
+
+#define CFG_HE_OM_CTRL_UL_MU_DIS_RX CFG_BOOL( \
+				"he_om_ctrl_ul_mu_dis_rx", \
+				0, \
+				"He Om Ctrl Ul My Dis Rx")
+
+#define CFG_HE_CHAN_WIDTH CFG_UINT( \
+				"he_chan_width", \
+				0, \
+				0x3F, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Chan Width")
+
+#define CFG_HE_RX_PREAM_PUNC CFG_UINT( \
+				"he_rx_pream_punc", \
+				0, \
+				0xF, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Rx Pream Punc")
+
+#define CFG_HE_CLASS_OF_DEVICE CFG_BOOL( \
+				"he_class_of_device", \
+				0, \
+				"He Class Of Device")
+
+#define CFG_HE_LDPC CFG_BOOL( \
+				"he_ldpc", \
+				0, \
+				"He Ldpc")
+
+#define CFG_HE_LTF_PPDU CFG_UINT( \
+				"he_ltf_ppdu", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Ltf Ppdu")
+
+#define CFG_HE_MIDAMBLE_RX_MAX_NSTS CFG_UINT( \
+				"he_midamble_rx_max_nsts", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Midamble Rx Max Nsts")
+
+#define CFG_HE_LTF_NDP CFG_UINT( \
+				"he_ltf_ndp", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Ltf Ndp")
+
+#define CFG_HE_TX_STBC_LT80 CFG_BOOL( \
+				"he_tx_stbc_lt80_sta", \
+				0, \
+				"He Tx Stbc Lt80")
+
+#define CFG_HE_RX_STBC_LT80 CFG_BOOL( \
+				"he_rx_stbc_lt80", \
+				0, \
+				"He Rx Stbc Lt80")
+
+#define CFG_HE_DOPPLER CFG_UINT( \
+				"he_doppler", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Doppler")
+
+#define CFG_HE_UL_MUMIMO CFG_UINT( \
+				"he_ul_mumimo", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Ul Mumimo")
+
+#define CFG_HE_DCM_TX CFG_UINT( \
+				"he_dcm_tx", \
+				0, \
+				7, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Dcm Tx")
+
+#define CFG_HE_DCM_RX CFG_UINT( \
+				"he_dcm_rx", \
+				0, \
+				7, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Dcm Rx")
+
+#define CFG_HE_MU_PPDU CFG_BOOL( \
+				"he_mu_ppdu", \
+				0, \
+				"He Mu Ppdu")
+
+#define CFG_HE_SU_BEAMFORMER CFG_BOOL( \
+				"he_su_beamformer", \
+				0, \
+				"He Su Beamformer")
+
+#define CFG_HE_SU_BEAMFORMEE CFG_BOOL( \
+				"he_su_beamformee", \
+				0, \
+				"He Su Beamformee")
+
+#define CFG_HE_MU_BEAMFORMER CFG_BOOL( \
+				"he_mu_beamformer", \
+				0, \
+				"He Mu Beamformer")
+
+#define CFG_HE_BFEE_STS_LT80 CFG_UINT( \
+				"he_bfee_sts_lt80", \
+				0, \
+				7, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Mu Bfee Sts Lt80")
+
+#define CFG_HE_BFEE_STS_GT80 CFG_UINT( \
+				"he_bfee_sts_lt80", \
+				0, \
+				7, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Mu Bfee Sts Gt80")
+
+#define CFG_HE_NUM_SOUND_LT80 CFG_UINT( \
+				"he_num_sound_lt80", \
+				0, \
+				7, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Num Sound Lt80")
+
+#define CFG_HE_NUM_SOUND_GT80 CFG_UINT( \
+				"he_num_sound_gt80", \
+				0, \
+				7, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Num Sound Gt80")
+
+#define CFG_HE_SU_FEED_TONE16 CFG_BOOL( \
+				"he_su_feed_tone16", \
+				0, \
+				"He Su Feed Tone16")
+
+#define CFG_HE_MU_FEED_TONE16 CFG_BOOL( \
+				"he_mu_feed_tone16", \
+				0, \
+				"He Mu Feed Tone16")
+
+#define CFG_HE_CODEBOOK_SU CFG_BOOL( \
+				"he_codebook_su", \
+				0, \
+				"He Codebook Su")
+
+#define CFG_HE_CODEBOOK_MU CFG_BOOL( \
+				"he_codebook_mu", \
+				0, \
+				"He Codebook Mu")
+
+#define CFG_HE_BFRM_FEED CFG_UINT( \
+				"he_bfrm_feed", \
+				0, \
+				7, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Bfrm Feed")
+
+#define CFG_HE_ER_SU_PPDU CFG_BOOL( \
+				"he_bfrm_feed", \
+				0, \
+				"He Er Su Ppdu")
+
+#define CFG_HE_DL_PART_BW CFG_BOOL( \
+				"he_dl_part_bw", \
+				0, \
+				"He Dl Part Bw")
+
+#define CFG_HE_PPET_PRESENT CFG_BOOL( \
+				"he_ppet_present", \
+				0, \
+				"He Pper Present")
+
+#define CFG_HE_SRP CFG_BOOL( \
+				"he_srp", \
+				0, \
+				"He Srp")
+
+#define CFG_HE_POWER_BOOST CFG_BOOL( \
+				"he_power_boost", \
+				0, \
+				"He Power Boost")
+
+#define CFG_HE_4x_LTF_GI CFG_BOOL( \
+				"he_4x_ltf_gi", \
+				0, \
+				"He 4x Ltf Gi")
+
+#define CFG_HE_MAX_NC CFG_UINT( \
+				"he_max_nc", \
+				0, \
+				7, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Max Nc")
+
+#define CFG_HE_RX_STBC_GT80 CFG_BOOL( \
+				"he_rx_stbc_gt80", \
+				0, \
+				"He Rx Stbc Gt80")
+
+#define CFG_HE_TX_STBC_GT80 CFG_BOOL( \
+				"he_Tx_stbc_gt80", \
+				0, \
+				"He Tx Stbc Gt80")
+
+#define CFG_HE_ER_4x_LTF_GI CFG_BOOL( \
+				"he_er_4x_ltf_gi", \
+				0, \
+				"He Er 4x Ltf Gi")
+
+#define CFG_HE_PPDU_20_IN_40MHZ_2G CFG_BOOL( \
+				"he_ppdu_20_in_40mhz_2g", \
+				0, \
+				"He Ppdu 20 In 40Mhz 2g")
+
+#define CFG_HE_PPDU_20_IN_160_80P80MHZ CFG_BOOL( \
+				"he_ppdu_20_in_160_80p80mhz", \
+				0, \
+				"He Ppdu 20 In 160 80p80mhz")
+
+#define CFG_HE_PPDU_80_IN_160_80P80MHZ CFG_BOOL( \
+				"he_ppdu_80_in_160_80p80mhz", \
+				0, \
+				"He Ppdu 80 In 160 80p80mhz")
+
+#define CFG_HE_ER_1X_HE_LTF_GI CFG_BOOL( \
+				"he_er_1x_he_ltf_gi", \
+				0, \
+				"He Er 1x He Ltf Gi")
+
+#define CFG_HE_MIDAMBLE_RX_1X_HE_LTF CFG_BOOL( \
+				"he_midamble_rx_1x_he_ltf", \
+				0, \
+				"He Midamble Rx 1x He Ltf")
+
+#define CFG_HE_DCM_MAX_BW CFG_UINT( \
+				"he_dcm_max_bw", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Dcm Max Bw")
+
+#define CFG_HE_LONGER_16_SIGB_OFDM_SYM CFG_BOOL( \
+				"he_longer_16_sigb_ofdm_sys", \
+				0, \
+				"He Longer 16 Sigb Ofdm Sys")
+
+#define CFG_HE_NON_TRIG_CQI_FEEDBACK CFG_BOOL( \
+				"he_rx_mcs_map_lt_80", \
+				0, \
+				"He Non Trig Cqi Feedback")
+
+#define CFG_HE_TX_1024_QAM_LT_242_RU CFG_BOOL( \
+				"he_tx_1024_qam_lt_242_ru", \
+				0, \
+				"He Tx 1024 Qam Lt 242 Ru")
+
+#define CFG_HE_RX_1024_QAM_LT_242_RU CFG_BOOL( \
+				"he_rx_1024_qam_lt_242_ru", \
+				0, \
+				"He Rx 1024 Qam Lt 242 Ru")
+
+#define CFG_HE_RX_FULL_BW_MU_CMPR_SIGB CFG_BOOL( \
+				"he_rx_full_bw_cmpr_sigb", \
+				0, \
+				"He Rx Full Bw Mu Cmpr Sigb")
+
+#define CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB CFG_BOOL( \
+				"he_rx_full_bw_mu_non_cmpr_sigb", \
+				0, \
+				"He Rx Full Bw Mu Non Cmpr Sigb")
+
+#define CFG_HE_RX_MCS_MAP_LT_80 CFG_UINT( \
+				"he_rx_mcs_map_lt_80", \
+				0, \
+				0xFFFF, \
+				0xFFF0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Rx Mcs Map Lt 80")
+
+#define CFG_HE_TX_MCS_MAP_LT_80 CFG_UINT( \
+				"he_tx_mcs_map_lt_80", \
+				0, \
+				0xFFFF, \
+				0xFFF0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Tx Mcs Map Lt 80")
+
+#define CFG_HE_RX_MCS_MAP_160 CFG_UINT( \
+				"he_rx_mcs_map_160", \
+				0, \
+				0xFFFF, \
+				0xFFF0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Rx Mcs Map 160")
+
+#define CFG_HE_TX_MCS_MAP_160 CFG_UINT( \
+				"he_tx_mcs_map_160", \
+				0, \
+				0xFFFF, \
+				0xFFF0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Tx Mcs Map 160")
+
+#define CFG_HE_RX_MCS_MAP_80_80 CFG_UINT( \
+				"he_rx_mcs_map_80_80", \
+				0, \
+				0xFFFF, \
+				0xFFF0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Rx Mcs Map 80 80")
+
+#define CFG_HE_TX_MCS_MAP_80_80 CFG_UINT( \
+				"he_tx_mcs_map_80_80", \
+				0, \
+				0xFFFF, \
+				0xFFF0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He tx Mcs Map 80 80")
+
+#define CFG_HE_OPS_BASIC_MCS_NSS CFG_UINT( \
+				"cfg_he_ops_basic_mcs_nss", \
+				0x0000, \
+				0xFFFF, \
+				0xFFFC, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Ops Basic Mcs NSS")
+
+/*
+ * <ini>
+ * he_dynamic_frag_support - configure dynamic fragmentation
+ * @Min: 0
+ * @Max: 3
+ * @Default: 0
+ *
+ * This ini is used to configure dynamic fragmentation.
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AX
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_HE_DYNAMIC_FRAGMENTATION CFG_INI_UINT( \
+				"he_dynamic_frag_support", \
+				0, \
+				3, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"HE Dynamic Twt Fragmentation")
+
+/*
+ * <ini>
+ * enable_ul_mimo- Enable UL MIMO.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable or disable UL MIMO.
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AX
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_UL_MIMO CFG_INI_BOOL( \
+				"enable_ul_mimo", \
+				0, \
+				"He Enble Ul Mimo Name")
+
+/*
+ * <ini>
+ * enable_ul_ofdma- Enable UL OFDMA.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable or disable UL OFDMA.
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AX
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_UL_OFDMA CFG_INI_BOOL( \
+				"enable_ul_ofdma", \
+				0, \
+				"He Enable Ul Ofdma Name")
+
+/*
+ * <ini>
+ * he_sta_obsspd- 11AX HE OBSS PD bit field
+ * @Min: 0
+ * @Max: uin32_t max
+ * @Default: 0x15b8c2ae
+ *
+ * 4 Byte value with each byte representing a signed value for following params:
+ * Param                   Bit position    Default
+ * OBSS_PD min (primary)   7:0             -82 (0xae)
+ * OBSS_PD max (primary)   15:8            -62 (0xc2)
+ * Secondary channel Ed    23:16           -72 (0xb8)
+ * TX_PWR(ref)             31:24           21  (0x15)
+ * This bit field value is directly applied to FW
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AX
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_HE_STA_OBSSPD CFG_INI_UINT( \
+				"he_sta_obsspd", \
+				0, \
+				0xFFFFFFFF, \
+				0x15b8c2ae, \
+				CFG_VALUE_OR_DEFAULT, \
+				"He Mu Bfee Sts Gt80")
+
+ #define CFG_HE_CAPS_ALL \
+	CFG(CFG_HE_CONTROL) \
+	CFG(CFG_HE_TWT_REQUESTOR) \
+	CFG(CFG_HE_TWT_RESPONDER) \
+	CFG(CFG_HE_TWT_FRAGMENTATION) \
+	CFG(CFG_HE_MAX_FRAG_MSDU) \
+	CFG(CFG_HE_MIN_FRAG_SIZE) \
+	CFG(CFG_HE_TRIG_PAD) \
+	CFG(CFG_HE_MTID_AGGR_RX) \
+	CFG(CFG_HE_LINK_ADAPTATION) \
+	CFG(CFG_HE_ALL_ACK) \
+	CFG(CFG_HE_TRIGD_RSP_SCHEDULING) \
+	CFG(CFG_HE_BUFFER_STATUS_RPT) \
+	CFG(CFG_HE_BCAST_TWT) \
+	CFG(CFG_HE_BA_32BIT) \
+	CFG(CFG_HE_MU_CASCADING) \
+	CFG(CFG_HE_MULTI_TID) \
+	CFG(CFG_HE_DL_MU_BA) \
+	CFG(CFG_HE_OMI) \
+	CFG(CFG_HE_OFDMA_RA) \
+	CFG(CFG_HE_MAX_AMPDU_LEN) \
+	CFG(CFG_HE_AMSDU_FRAG) \
+	CFG(CFG_HE_FLEX_TWT_SCHED) \
+	CFG(CFG_HE_RX_CTRL) \
+	CFG(CFG_HE_BSRP_AMPDU_AGGR) \
+	CFG(CFG_HE_QTP) \
+	CFG(CFG_HE_A_BQR) \
+	CFG(CFG_HE_SR_RESPONDER) \
+	CFG(CFG_HE_NDP_FEEDBACK_SUPP) \
+	CFG(CFG_HE_OPS_SUPP) \
+	CFG(CFG_HE_AMSDU_IN_AMPDU) \
+	CFG(CFG_HE_CHAN_WIDTH) \
+	CFG(CFG_HE_MTID_AGGR_TX) \
+	CFG(CFG_HE_SUB_CH_SEL_TX) \
+	CFG(CFG_HE_UL_2X996_RU) \
+	CFG(CFG_HE_OM_CTRL_UL_MU_DIS_RX) \
+	CFG(CFG_HE_RX_PREAM_PUNC) \
+	CFG(CFG_HE_CLASS_OF_DEVICE) \
+	CFG(CFG_HE_LDPC) \
+	CFG(CFG_HE_LTF_PPDU) \
+	CFG(CFG_HE_MIDAMBLE_RX_MAX_NSTS) \
+	CFG(CFG_HE_LTF_NDP) \
+	CFG(CFG_HE_TX_STBC_LT80) \
+	CFG(CFG_HE_RX_STBC_LT80) \
+	CFG(CFG_HE_DOPPLER) \
+	CFG(CFG_HE_UL_MUMIMO) \
+	CFG(CFG_HE_DCM_TX) \
+	CFG(CFG_HE_DCM_RX) \
+	CFG(CFG_HE_MU_PPDU) \
+	CFG(CFG_HE_SU_BEAMFORMER) \
+	CFG(CFG_HE_SU_BEAMFORMEE) \
+	CFG(CFG_HE_MU_BEAMFORMER) \
+	CFG(CFG_HE_BFEE_STS_LT80) \
+	CFG(CFG_HE_BFEE_STS_GT80) \
+	CFG(CFG_HE_NUM_SOUND_LT80) \
+	CFG(CFG_HE_NUM_SOUND_GT80) \
+	CFG(CFG_HE_SU_FEED_TONE16) \
+	CFG(CFG_HE_MU_FEED_TONE16) \
+	CFG(CFG_HE_CODEBOOK_SU) \
+	CFG(CFG_HE_CODEBOOK_MU) \
+	CFG(CFG_HE_BFRM_FEED) \
+	CFG(CFG_HE_ER_SU_PPDU) \
+	CFG(CFG_HE_DL_PART_BW) \
+	CFG(CFG_HE_PPET_PRESENT) \
+	CFG(CFG_HE_SRP) \
+	CFG(CFG_HE_POWER_BOOST) \
+	CFG(CFG_HE_4x_LTF_GI) \
+	CFG(CFG_HE_MAX_NC) \
+	CFG(CFG_HE_RX_STBC_GT80) \
+	CFG(CFG_HE_TX_STBC_GT80) \
+	CFG(CFG_HE_ER_4x_LTF_GI) \
+	CFG(CFG_HE_PPDU_20_IN_40MHZ_2G) \
+	CFG(CFG_HE_PPDU_20_IN_160_80P80MHZ) \
+	CFG(CFG_HE_PPDU_80_IN_160_80P80MHZ) \
+	CFG(CFG_HE_ER_1X_HE_LTF_GI) \
+	CFG(CFG_HE_MIDAMBLE_RX_1X_HE_LTF) \
+	CFG(CFG_HE_DCM_MAX_BW) \
+	CFG(CFG_HE_LONGER_16_SIGB_OFDM_SYM) \
+	CFG(CFG_HE_NON_TRIG_CQI_FEEDBACK) \
+	CFG(CFG_HE_TX_1024_QAM_LT_242_RU) \
+	CFG(CFG_HE_RX_1024_QAM_LT_242_RU) \
+	CFG(CFG_HE_RX_FULL_BW_MU_CMPR_SIGB) \
+	CFG(CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB) \
+	CFG(CFG_HE_RX_MCS_MAP_LT_80) \
+	CFG(CFG_HE_TX_MCS_MAP_LT_80) \
+	CFG(CFG_HE_RX_MCS_MAP_160) \
+	CFG(CFG_HE_TX_MCS_MAP_160) \
+	CFG(CFG_HE_RX_MCS_MAP_80_80) \
+	CFG(CFG_HE_TX_MCS_MAP_80_80) \
+	CFG(CFG_HE_OPS_BASIC_MCS_NSS) \
+	CFG(CFG_HE_DYNAMIC_FRAGMENTATION) \
+	CFG(CFG_ENABLE_UL_MIMO) \
+	CFG(CFG_ENABLE_UL_OFDMA) \
+	CFG(CFG_HE_STA_OBSSPD)
+
+#endif /* __CFG_MLME_HE_CAPS_H */
+
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_ht_caps.h b/components/mlme/dispatcher/inc/cfg_mlme_ht_caps.h
new file mode 100644
index 0000000..f5680c3
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_ht_caps.h
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_HT_CAPS_H
+#define __CFG_MLME_HT_CAPS_H
+
+/*
+ * <ini>
+ * gTxLdpcEnable - Config Param to enable Tx LDPC capability
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * This ini is used to enable/disable Tx LDPC capability
+ * 0 - disable
+ * 1 - HT LDPC enable
+ * 2 - VHT LDPC enable
+ * 3 - HT & VHT LDPC enable
+ *
+ * Related: STA/SAP/P2P/IBSS/NAN.
+ *
+ * Supported Feature: Concurrency/Standalone
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_TX_LDPC_ENABLE CFG_INI_UINT( \
+		"gTxLdpcEnable", \
+		0, \
+		3, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Tx LDPC capability")
+
+/*
+ * <ini>
+ * gEnableRXLDPC - Config Param to enable Rx LDPC capability
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable Rx LDPC capability
+ * 0 - disable Rx LDPC
+ * 1 - enable Rx LDPC
+ *
+ * Related: STA/SAP/P2P/IBSS/NAN.
+ *
+ * Supported Feature: Concurrency/Standalone
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_RX_LDPC_ENABLE CFG_INI_BOOL( \
+		"gEnableRXLDPC", \
+		0, \
+		"Rx LDPC capability")
+
+/*
+ * <ini>
+ * gEnableTXSTBC - Enables/disables Tx STBC capability in STA mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set default Tx STBC capability
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_TX_STBC_ENABLE CFG_INI_BOOL( \
+		"gEnableTXSTBC", \
+		0, \
+		"Tx STBC capability")
+
+/*
+ * <ini>
+ * gEnableRXSTBC - Enables/disables Rx STBC capability in STA mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set default Rx STBC capability
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_RX_STBC_ENABLE CFG_INI_BOOL( \
+		"gEnableRXSTBC", \
+		1, \
+		"Rx STBC capability")
+
+/*
+ * <ini>
+ * gShortGI20Mhz - Short Guard Interval for HT20
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set default short interval for HT20
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_SHORT_GI_20MHZ CFG_INI_BOOL( \
+		"gShortGI20Mhz", \
+		1, \
+		"Short Guard Interval for HT20")
+
+/*
+ * <ini>
+ * gShortGI40Mhz - It will check gShortGI20Mhz and
+ * gShortGI40Mhz from session entry
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set default gShortGI40Mhz
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_SHORT_GI_40MHZ CFG_INI_BOOL( \
+		"gShortGI40Mhz", \
+		1, \
+		"Short Guard Interval for HT40")
+
+#define CFG_HT_CAP_INFO CFG_UINT( \
+		"ht_cap_info", \
+		0, \
+		65535, \
+		364, \
+		CFG_VALUE_OR_DEFAULT, \
+		"HT cap info")
+
+/*
+ * <ini>
+ * gShortPreamble - Set Short Preamble
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set default short Preamble
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_SHORT_PREAMBLE CFG_INI_BOOL( \
+		"gShortPreamble", \
+		1, \
+		"Short Preamble")
+
+#define CFG_HT_AMPDU_PARAMS CFG_UINT( \
+		"ht_ampdu_params", \
+		0, \
+		255, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"HT AMPDU Params")
+
+#define CFG_EXT_HT_CAP_INFO CFG_UINT( \
+		"ext_ht_cap_info", \
+		0, \
+		65535, \
+		1024, \
+		CFG_VALUE_OR_DEFAULT, \
+		"HT Ext Cap Info")
+
+#define CFG_HT_INFO_FIELD_1 CFG_UINT( \
+		"ht_info_field_1", \
+		0, \
+		255, \
+		15, \
+		CFG_VALUE_OR_DEFAULT, \
+		"HT Info Field 1")
+
+#define CFG_HT_INFO_FIELD_2 CFG_UINT( \
+		"ht_info_field_2", \
+		0, \
+		65535, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"HT Info Field 2")
+
+#define CFG_HT_INFO_FIELD_3 CFG_UINT( \
+		"ht_info_field_3", \
+		0, \
+		65535, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"HT Info Field 3")
+
+/*
+ * <ini>
+ * gEnableHtSMPS - Enable the SM Power Save
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable SM Power Save
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_HT_SMPS CFG_INI_BOOL( \
+	"gEnableHtSMPS", \
+	0, \
+	"Enable HT SM PowerSave")
+
+/*
+ * <ini>
+ * gHtSMPS - SMPS Mode
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * This ini is used to set default SM Power Save Antenna mode
+ * 0 - Static
+ * 1 - Dynamic
+ * 2 - Reserved/Invalid
+ * 3 - Disabled
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_HT_SMPS_MODE CFG_INI_UINT( \
+	"gHtSMPS", \
+	0, \
+	3, \
+	3, \
+	CFG_VALUE_OR_DEFAULT, \
+	"HT SM Power Save Config")
+
+/*
+ * <ini>
+ * gMaxAmsduNum - Max number of MSDU's in aggregate
+ * @Min: 0
+ * @Max: 3
+ * @Default: 1
+ * gMaxAmsduNum is the number of MSDU's transmitted in the 11n aggregate
+ * frame. Setting it to a value larger than 1 enables transmit aggregation.
+ * It is a PHY parameter that applies to all vdev's in firmware.
+ *
+ * Supported Feature: 11n aggregation
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_MAX_AMSDU_NUM CFG_INI_UINT( \
+	"gMaxAmsduNum", \
+	0, \
+	3, \
+	1, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Max AMSDU Number")
+
+/*
+ * <ini>
+ * gMaxRxAmpduFactor - Provide the maximum ampdu factor.
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * This ini is used to set default maxampdu factor
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_MAX_RX_AMPDU_FACTOR CFG_INI_UINT( \
+	"gMaxRxAmpduFactor", \
+	0, \
+	3, \
+	3, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Max Rx AMPDU Factor")
+
+/*
+ * <ini>
+ * ght_mpdu_density - Configuration option for HT MPDU density
+ * @Min: 0
+ * @Max: 7
+ * @Default: 7
+ *
+ * This ini is used to set default MDPU Density
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * As per (Table 8-125 802.11-2012)
+ * 0 for no restriction
+ * 1 for 1/4 micro sec
+ * 2 for 1/2 micro sec
+ * 3 for 1 micro sec
+ * 4 for 2 micro sec
+ * 5 for 4 micro sec
+ * 6 for 8 micro sec
+ * 7 for 16 micro sec
+ *
+ * </ini>
+ */
+#define CFG_MPDU_DENSITY CFG_INI_UINT( \
+	"ght_mpdu_density", \
+	0, \
+	7, \
+	7, \
+	CFG_VALUE_OR_DEFAULT, \
+	"MPDU Density")
+
+#define CFG_HT_CAPS_ALL \
+	CFG(CFG_HT_CAP_INFO) \
+	CFG(CFG_TX_LDPC_ENABLE) \
+	CFG(CFG_RX_LDPC_ENABLE) \
+	CFG(CFG_TX_STBC_ENABLE) \
+	CFG(CFG_RX_STBC_ENABLE) \
+	CFG(CFG_SHORT_GI_20MHZ) \
+	CFG(CFG_SHORT_GI_40MHZ) \
+	CFG(CFG_SHORT_PREAMBLE) \
+	CFG(CFG_HT_AMPDU_PARAMS) \
+	CFG(CFG_EXT_HT_CAP_INFO) \
+	CFG(CFG_HT_INFO_FIELD_1) \
+	CFG(CFG_HT_INFO_FIELD_2) \
+	CFG(CFG_HT_INFO_FIELD_3) \
+	CFG(CFG_ENABLE_HT_SMPS) \
+	CFG(CFG_HT_SMPS_MODE) \
+	CFG(CFG_MAX_AMSDU_NUM) \
+	CFG(CFG_MAX_RX_AMPDU_FACTOR) \
+	CFG(CFG_MPDU_DENSITY)
+
+#endif /* __CFG_MLME_HT_CAPS_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_lfr.h b/components/mlme/dispatcher/inc/cfg_mlme_lfr.h
new file mode 100644
index 0000000..d8581a5
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_lfr.h
@@ -0,0 +1,1187 @@
+/*
+ * Copyright (c) 2012-2018 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 configuration definitions for MLME LFR.
+ */
+
+#ifndef CFG_MLME_LFR_H__
+#define CFG_MLME_LFR_H__
+
+/*
+ * <ini>
+ * mawc_roam_enabled - Enable/Disable MAWC during roaming
+ * @Min: 0 - Disabled
+ * @Max: 1 - Enabled
+ * @Default: 0
+ *
+ * This ini is used to control MAWC during roaming.
+ *
+ * Related: MAWCEnabled.
+ *
+ * Supported Feature: MAWC Roaming
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_LFR_MAWC_ROAM_ENABLED CFG_INI_BOOL( \
+	"mawc_roam_enabled", \
+	0, \
+	"Enable/Disable MAWC during roaming")
+
+/*
+ * <ini>
+ * mawc_roam_traffic_threshold - Configure traffic threshold
+ * @Min: 0
+ * @Max: 0xFFFFFFFF
+ * @Default: 300
+ *
+ * This ini is used to configure the data traffic load in kbps to
+ * register CMC.
+ *
+ * Related: mawc_roam_enabled.
+ *
+ * Supported Feature: MAWC Roaming
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_LFR_MAWC_ROAM_TRAFFIC_THRESHOLD CFG_INI_UINT( \
+	"mawc_roam_traffic_threshold", \
+	0, \
+	0xFFFFFFFF, \
+	300, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Configure traffic threshold")
+
+/*
+ * <ini>
+ * mawc_roam_ap_rssi_threshold - Best AP RSSI threshold
+ * @Min: -120
+ * @Max: 0
+ * @Default: -66
+ *
+ * This ini is used to specify the RSSI threshold to scan for the AP.
+ *
+ * Related: mawc_roam_enabled.
+ *
+ * Supported Feature: MAWC Roaming
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_LFR_MAWC_ROAM_AP_RSSI_THRESHOLD CFG_INI_INT( \
+	"mawc_roam_ap_rssi_threshold", \
+	-120, \
+	0, \
+	-66, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Best AP RSSI threshold")
+
+/*
+ * <ini>
+ * mawc_roam_rssi_high_adjust - Adjust MAWC roam high RSSI
+ * @Min: 3
+ * @Max: 5
+ * @Default: 5
+ *
+ * This ini is used for high RSSI threshold adjustment in stationary state
+ * to suppress the scan.
+ *
+ * Related: mawc_roam_enabled.
+ *
+ * Supported Feature: MAWC Roaming
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_LFR_MAWC_ROAM_RSSI_HIGH_ADJUST CFG_INI_UINT( \
+	"mawc_roam_ap_rssi_threshold", \
+	3, \
+	5, \
+	5, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Adjust MAWC roam high RSSI")
+
+/*
+ * <ini>
+ * mawc_roam_rssi_low_adjust - Adjust MAWC roam low RSSI
+ * @Min: 3
+ * @Max: 5
+ * @Default: 5
+ *
+ * This ini is used for low RSSI threshold adjustment in stationary state
+ * to suppress the scan.
+ *
+ * Related: mawc_roam_enabled.
+ *
+ * Supported Feature: MAWC Roaming
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_LFR_MAWC_ROAM_RSSI_LOW_ADJUST CFG_INI_UINT( \
+	"mawc_roam_rssi_low_adjust", \
+	3, \
+	5, \
+	5, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Adjust MAWC roam low RSSI")
+
+/*
+ * <ini>
+ * rssi_abs_thresh - The min RSSI of the candidate AP to consider roam
+ * @Min: -96
+ * @Max: 0
+ * @Default: 0
+ *
+ * The RSSI value of the candidate AP should be higher than rssi_abs_thresh
+ * to roam to the AP. 0 means no absolute minimum RSSI is required.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_ROAM_RSSI_ABS_THRESHOLD CFG_INI_INT( \
+	"rssi_abs_thresh", \
+	-96, \
+	0, \
+	0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"The min RSSI of the candidate AP to consider roam")
+
+/*
+ * <ini>
+ * lookup_threshold_5g_offset - Lookup threshold offset for 5G band
+ * @Min: -120
+ * @Max: 120
+ * @Default: 0
+ *
+ * This ini is used to set the 5G band lookup threshold for roaming.
+ * It depends on another INI which is gNeighborLookupThreshold.
+ * gNeighborLookupThreshold is a legacy INI item which will be used to
+ * set the RSSI lookup threshold for both 2G and 5G bands. If the
+ * user wants to setup a different threshold for a 5G band, then user
+ * can use this offset value which will be summed up to the value of
+ * gNeighborLookupThreshold and used for 5G
+ * e.g: gNeighborLookupThreshold = -76dBm
+ *      lookup_threshold_5g_offset = 6dBm
+ *      Then the 5G band will be configured to -76+6 = -70dBm
+ * A default value of Zero to lookup_threshold_5g_offset will keep the
+ * thresholds same for both 2G and 5G bands
+ *
+ * Related: gNeighborLookupThreshold
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_LFR_5G_RSSI_THRESHOLD_OFFSET CFG_INI_INT( \
+	"lookup_threshold_5g_offset", \
+	-120, \
+	120, \
+	0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Lookup threshold offset for 5G band")
+
+/*
+ * <ini>
+ * gEnableFastRoamInConcurrency - Enable LFR roaming on STA during concurrency
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This INI is used to enable Legacy fast roaming(LFR) on STA link during
+ * concurrent sessions.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_ENABLE_FAST_ROAM_IN_CONCURRENCY CFG_INI_BOOL( \
+	"gEnableFastRoamInConcurrency", \
+	1, \
+	"Enable LFR roaming on STA during concurrency")
+
+/*
+ * <ini>
+ * gRoamOffloadEnabled - enable/disable roam offload feature
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This INI is used to enable/disable roam offload feature
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR3_ROAMING_OFFLOAD CFG_INI_BOOL( \
+	"gRoamOffloadEnabled", \
+	1, \
+	"enable roam offload")
+
+/*
+ * <ini>
+ * gEnableEarlyStopScan - Set early stop scan
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set early stop scan. Early stop
+ * scan is a feature for roaming to stop the scans at
+ * an early stage as soon as we find a better AP to roam.
+ * This would make the roaming happen quickly.
+ *
+ * Related: None
+ *
+ * Supported Feature: LFR Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_EARLY_STOP_SCAN_ENABLE CFG_INI_BOOL( \
+	"gEnableEarlyStopScan", \
+	0, \
+	"Set early stop scan")
+
+/*
+ * <ini>
+ * gEarlyStopScanMinThreshold - Set early stop scan min
+ * threshold
+ * @Min: -80
+ * @Max: -70
+ * @Default: -73
+ *
+ * This ini is used to set the early stop scan minimum
+ * threshold. Early stop scan minimum threshold is the
+ * minimum threshold to be considered for stopping the
+ * scan. The algorithm starts with a scan on the greedy
+ * channel list with the maximum threshold and steps down
+ * the threshold by 20% for each further channel. It can
+ * step down on each channel but cannot go lower than the
+ * minimum threshold.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_EARLY_STOP_SCAN_MIN_THRESHOLD CFG_INI_INT( \
+	"gEarlyStopScanMinThreshold", \
+	-80, \
+	-70, \
+	-73, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Set early stop scan min")
+
+/*
+ * <ini>
+ * gEarlyStopScanMaxThreshold - Set early stop scan max
+ * threshold
+ * @Min: -60
+ * @Max: -40
+ * @Default: -43
+ *
+ * This ini is used to set the the early stop scan maximum
+ * threshold at which the candidate AP should be to be
+ * qualified as a potential roam candidate and good enough
+ * to stop the roaming scan.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_EARLY_STOP_SCAN_MAX_THRESHOLD CFG_INI_INT( \
+	"gEarlyStopScanMaxThreshold", \
+	-60, \
+	-40, \
+	-43, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Set early stop scan max")
+
+/*
+ * <ini>
+ * gFirstScanBucketThreshold - Set first scan bucket
+ * threshold
+ * @Min: -50
+ * @Max: -30
+ * @Default: -30
+ *
+ * This ini will configure the first scan bucket
+ * threshold to the mentioned value and all the AP's which
+ * have RSSI under this threshold will fall under this
+ * bucket. This configuration item used to tweak and
+ * test the input for internal algorithm.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_LFR_FIRST_SCAN_BUCKET_THRESHOLD CFG_INI_INT( \
+	"gFirstScanBucketThreshold", \
+	-50, \
+	-30, \
+	-30, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Set first scan bucket")
+
+/*
+ * <ini>
+ * gLFRSubnetDetectionEnable - Enable LFR3 subnet detection
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * Enable IP subnet detection during legacy fast roming version 3. Legacy fast
+ * roaming could roam across IP subnets without host processors' knowledge.
+ * This feature enables firmware to wake up the host processor if it
+ * successfully determines change in the IP subnet. Change in IP subnet could
+ * potentially cause disruption in IP connnectivity if IP address is not
+ * refreshed.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR3_ENABLE_SUBNET_DETECTION CFG_INI_BOOL( \
+	"gLFRSubnetDetectionEnable", \
+	1, \
+	"Set early stop scan")
+
+/*
+ * <ini>
+ * gtraffic_threshold - Dense traffic threshold
+ * @Min: 0
+ * @Max: 0xffffffff
+ * @Default: 400
+ *
+ * Dense traffic threshold
+ * traffic threshold required for dense roam scan
+ * Measured in kbps
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_ROAM_DENSE_TRAFFIC_THRESHOLD CFG_INI_UINT( \
+	"gtraffic_threshold", \
+	0, \
+	0xffffffff, \
+	400, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Dense traffic threshold")
+
+/*
+ * <ini>
+ * groam_dense_rssi_thresh_offset - Sets dense roam RSSI threshold diff
+ * @Min: 0
+ * @Max: 20
+ * @Default: 10
+ *
+ * This INI is used to set offset value from normal RSSI threshold to dense
+ * RSSI threshold FW will optimize roaming based on new RSSI threshold once
+ * it detects dense environment.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_ROAM_DENSE_RSSI_THRE_OFFSET CFG_INI_UINT( \
+	"groam_dense_rssi_thresh_offset", \
+	0, \
+	20, \
+	10, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Dense traffic threshold")
+
+/*
+ * <ini>
+ * groam_dense_min_aps - Sets minimum number of AP for dense roam
+ * @Min: 1
+ * @Max: 5
+ * @Default: 3
+ *
+ * Minimum number of APs required for dense roam. FW will consider
+ * environment as dense once it detects #APs operating is more than
+ * groam_dense_min_aps.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_ROAM_DENSE_MIN_APS CFG_INI_UINT( \
+	"groam_dense_min_aps", \
+	1, \
+	5, \
+	3, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Sets minimum number of AP for dense roam")
+
+/*
+ * <ini>
+ * roam_bg_scan_bad_rssi_thresh - RSSI threshold for background roam
+ * @Min: -96
+ * @Max: 0
+ * @Default: -76
+ *
+ * If the DUT is connected to an AP with weak signal, then the bad RSSI
+ * threshold will be used as an opportunity to use the scan results
+ * from other scan clients and try to roam if there is a better AP
+ * available in the environment.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_ROAM_BG_SCAN_BAD_RSSI_THRESHOLD CFG_INI_INT( \
+	"roam_bg_scan_bad_rssi_thresh", \
+	-96, \
+	0, \
+	-76, \
+	CFG_VALUE_OR_DEFAULT, \
+	"RSSI threshold for background roam")
+
+/*
+ * <ini>
+ * roam_bg_scan_client_bitmap - Bitmap used to identify the scan clients
+ * @Min: 0
+ * @Max: 0x7FF
+ * @Default: 0x424
+ *
+ * This bitmap is used to define the client scans that need to be used
+ * by the roaming module to perform a background roaming.
+ * Currently supported bit positions are as follows:
+ * Bit 0 is reserved in the firmware.
+ * WMI_SCAN_CLIENT_NLO - 1
+ * WMI_SCAN_CLIENT_EXTSCAN - 2
+ * WMI_SCAN_CLIENT_ROAM - 3
+ * WMI_SCAN_CLIENT_P2P - 4
+ * WMI_SCAN_CLIENT_LPI - 5
+ * WMI_SCAN_CLIENT_NAN - 6
+ * WMI_SCAN_CLIENT_ANQP - 7
+ * WMI_SCAN_CLIENT_OBSS - 8
+ * WMI_SCAN_CLIENT_PLM - 9
+ * WMI_SCAN_CLIENT_HOST - 10
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_ROAM_BG_SCAN_CLIENT_BITMAP CFG_INI_UINT( \
+	"roam_bg_scan_client_bitmap", \
+	0, \
+	0x7FF, \
+	0x424, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Bitmap used to identify the scan clients")
+
+/*
+ * <ini>
+ * roam_bad_rssi_thresh_offset_2g - RSSI threshold offset for 2G to 5G roam
+ * @Min: 0
+ * @Max: 86
+ * @Default: 40
+ *
+ * If the DUT is connected to an AP with weak signal in 2G band, then the
+ * bad RSSI offset for 2g would be used as offset from the bad RSSI
+ * threshold configured and then use the resulting rssi for an opportunity
+ * to use the scan results from other scan clients and try to roam to
+ * 5G Band ONLY if there is a better AP available in the environment.
+ *
+ * For example if the roam_bg_scan_bad_rssi_thresh is -76 and
+ * roam_bad_rssi_thresh_offset_2g is 40 then the difference of -36 would be
+ * used as a trigger to roam to a 5G AP if DUT initially connected to a 2G AP
+ *
+ * Related: roam_bg_scan_bad_rssi_thresh
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G CFG_INI_UINT( \
+	"roam_bad_rssi_thresh_offset_2g", \
+	0, \
+	86, \
+	40, \
+	CFG_VALUE_OR_DEFAULT, \
+	"RSSI threshold offset for 2G to 5G roam")
+
+/*
+ * <ini>
+ * roamscan_adaptive_dwell_mode - Sets dwell time adaptive mode
+ * @Min: 0
+ * @Max: 4
+ * @Default: 1
+ *
+ * This parameter will set the algo used in dwell time optimization during
+ * roam scan. see enum scan_dwelltime_adaptive_mode.
+ * Acceptable values for this:
+ * 0: Default (Use firmware default mode)
+ * 1: Conservative optimization
+ * 2: Moderate optimization
+ * 3: Aggressive optimization
+ * 4: Static
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_ADAPTIVE_ROAMSCAN_DWELL_MODE CFG_INI_UINT( \
+	"roamscan_adaptive_dwell_mode", \
+	0, \
+	4, \
+	1, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Sets dwell time adaptive mode")
+
+/*
+ * <ini>
+ * gper_roam_enabled - To enabled/disable PER based roaming in FW
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * This ini is used to enable/disable Packet error based roaming, enabling this
+ * will cause DUT to monitor Tx and Rx traffic and roam to a better candidate
+ * if current is not good enough.
+ *
+ * Values supported:
+ * 0: disabled
+ * 1: enabled for Rx traffic
+ * 2: enabled for Tx traffic
+ * 3: enabled for Tx and Rx traffic
+ *
+ * Related: gper_roam_high_rate_th, gper_roam_low_rate_th,
+ *          gper_roam_th_percent, gper_roam_rest_time
+ *
+ * Supported Feature: LFR-3.0
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_LFR_PER_ROAM_ENABLE CFG_INI_UINT( \
+	"gper_roam_enabled", \
+	0, \
+	3, \
+	3, \
+	CFG_VALUE_OR_DEFAULT, \
+	"To enabled/disable PER based roaming in FW")
+
+/*
+ * <ini>
+ * gper_roam_high_rate_th - Rate at which PER based roam will stop
+ * @Min: 1 Mbps
+ * @Max: 0xffffffff
+ * @Default: 40 Mbps
+ *
+ * This ini is used to define the data rate in mbps*10 at which FW will stop
+ * monitoring the traffic for PER based roam.
+ *
+ * Related: gper_roam_enabled, gper_roam_low_rate_th,
+ *          gper_roam_th_percent, gper_roam_rest_time
+ *
+ * Supported Feature: LFR-3.0
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_LFR_PER_ROAM_CONFIG_HIGH_RATE_TH CFG_INI_UINT( \
+	"gper_roam_high_rate_th", \
+	10, \
+	0xffffffff, \
+	400, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Rate at which PER based roam will stop")
+
+/*
+ * <ini>
+ * gper_roam_low_rate_th - Rate at which FW starts considering traffic for PER
+ * based roam.
+ *
+ * @Min: 1 Mbps
+ * @Max: 0xffffffff
+ * @Default: 20 Mbps
+ *
+ * This ini is used to define the rate in mbps*10 at which FW starts considering
+ * traffic for PER based roam, if gper_roam_th_percent of data is below this
+ * rate, FW will issue a roam scan.
+ *
+ * Related: gper_roam_enabled, gper_roam_high_rate_th,
+ *          gper_roam_th_percent, gper_roam_rest_time
+ *
+ * Supported Feature: LFR-3.0
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_LFR_PER_ROAM_CONFIG_LOW_RATE_TH CFG_INI_UINT( \
+	"gper_roam_low_rate_th", \
+	10, \
+	0xffffffff, \
+	200, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Rate at which FW starts considering traffic for PER")
+
+/*
+ * <ini>
+ * gper_roam_th_percent - Percentage at which FW will issue a roam scan if
+ * traffic is below gper_roam_low_rate_th rate.
+ *
+ * @Min: 10%
+ * @Max: 100%
+ * @Default: 60%
+ *
+ * This ini is used to define the percentage at which FW will issue a roam scan
+ * if traffic is below gper_roam_low_rate_th rate.
+ *
+ * Related: gper_roam_enabled, gper_roam_high_rate_th,
+ *          gper_roam_high_rate_th, gper_roam_rest_time
+ *
+ * Supported Feature: LFR-3.0
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_LFR_PER_ROAM_CONFIG_RATE_TH_PERCENT CFG_INI_UINT( \
+	"gper_roam_th_percent", \
+	10, \
+	100, \
+	60, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Percentage at which FW will issue a roam scan")
+
+/*
+ * <ini>
+ * gper_roam_rest_time - Time for which FW will wait once it issues a
+ * roam scan.
+ *
+ * @Min: 10 seconds
+ * @Max: 3600 seconds
+ * @Default: 300 seconds
+ *
+ * This ini is used to define the time for which FW will wait once it issues a
+ * PER based roam scan.
+ *
+ * Related: gper_roam_enabled, gper_roam_high_rate_th,
+ *          gper_roam_high_rate_th, gper_roam_th_percent
+ *
+ * Supported Feature: LFR-3.0
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_LFR_PER_ROAM_REST_TIME CFG_INI_UINT( \
+	"gper_roam_rest_time", \
+	10, \
+	3600, \
+	300, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Time for which FW will wait once it issues a roam scan")
+
+/*
+ * <ini>
+ * gper_roam_mon_time - Minimum time required in seconds to
+ * be considered as valid scenario for PER based roam
+ * @Min: 5
+ * @Max: 25
+ * @Default: 25
+ *
+ * This ini is used to define minimum time in seconds for which DUT has
+ * collected the PER stats before it can consider the stats hysteresis to be
+ * valid for PER based scan.
+ * DUT collects following information during this period:
+ *     1. % of packets below gper_roam_low_rate_th
+ *     2. # packets above gper_roam_high_rate_th
+ * if DUT gets (1) greater than gper_roam_th_percent and (2) is zero during
+ * this period, it triggers PER based roam scan.
+ *
+ * Related: gper_roam_enabled, gper_roam_high_rate_th, gper_roam_low_rate_th,
+ *          gper_roam_th_percent, gper_roam_rest_time
+ *
+ * Supported Feature: LFR-3.0
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_LFR_PER_ROAM_MONITOR_TIME CFG_INI_UINT( \
+	"gper_roam_mon_time", \
+	5, \
+	25, \
+	25, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Minimum time to be considered as valid scenario for PER based roam")
+
+/*
+ * <ini>
+ * gper_min_rssi_threshold_for_roam -  Minimum roamable AP RSSI for
+ * candidate selection for PER based roam
+ * @Min: 0
+ * @Max: 96
+ * @Default: 83
+ *
+ * Minimum roamable AP RSSI for candidate selection for PER based roam
+ *
+ * Related: gper_roam_enabled, gper_roam_high_rate_th, gper_roam_low_rate_th,
+ *          gper_roam_th_percent, gper_roam_rest_time
+ *
+ * Supported Feature: LFR-3.0
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_LFR_PER_ROAM_MIN_CANDIDATE_RSSI CFG_INI_UINT( \
+	"gper_min_rssi_threshold_for_roam", \
+	10, \
+	96, \
+	83, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Minimum roamable AP RSSI for candidate selection for PER based roam")
+
+/*
+ * <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_LFR3_ROAM_DISALLOW_DURATION CFG_INI_UINT( \
+	"groam_disallow_duration", \
+	0, \
+	3600, \
+	30, \
+	CFG_VALUE_OR_DEFAULT, \
+	"disallow duration before roaming")
+
+/*
+ * <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_LFR3_ROAM_RSSI_CHANNEL_PENALIZATION CFG_INI_UINT( \
+	"grssi_channel_penalization", \
+	0, \
+	15, \
+	5, \
+	CFG_VALUE_OR_DEFAULT, \
+	"RSSI penalization")
+
+/*
+ * <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_LFR3_ROAM_NUM_DISALLOWED_APS CFG_INI_UINT( \
+	"groam_num_disallowed_aps", \
+	0, \
+	8, \
+	3, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Max number of AP's to maintain in LCA list")
+
+/*
+ * <ini>
+ * enable_5g_band_pref - Enable preference for 5G from INI.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ * This ini is used to enable 5G preference parameters.
+ *
+ * Related: 5g_rssi_boost_threshold, 5g_rssi_boost_factor, 5g_max_rssi_boost
+ * 5g_rssi_penalize_threshold, 5g_rssi_penalize_factor, 5g_max_rssi_penalize
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_ENABLE_5G_BAND_PREF CFG_INI_BOOL( \
+	"enable_5g_band_pref", \
+	0, \
+	"Enable preference for 5G from INI")
+
+/*
+ * <ini>
+ * 5g_rssi_boost_threshold - A_band_boost_threshold above which 5G is favored.
+ * @Min: -55
+ * @Max: -70
+ * @Default: -60
+ * This ini is used to set threshold for 5GHz band preference.
+ *
+ * Related: 5g_rssi_boost_factor, 5g_max_rssi_boost
+ * 5g_rssi_penalize_threshold, 5g_rssi_penalize_factor, 5g_max_rssi_penalize
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_5G_RSSI_BOOST_THRESHOLD CFG_INI_INT( \
+	"5g_rssi_boost_threshold", \
+	-55, \
+	-70, \
+	-60, \
+	CFG_VALUE_OR_DEFAULT, \
+	"A_band_boost_threshold above which 5 GHz is favored")
+
+/*
+ * <ini>
+ * 5g_rssi_boost_factor - Factor by which 5GHz RSSI is boosted.
+ * @Min: 0
+ * @Max: 2
+ * @Default: 1
+ * This ini is used to set the 5Ghz boost factor.
+ *
+ * Related: 5g_rssi_boost_threshold, 5g_max_rssi_boost
+ * 5g_rssi_penalize_threshold, 5g_rssi_penalize_factor, 5g_max_rssi_penalize
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_5G_RSSI_BOOST_FACTOR CFG_INI_UINT( \
+	"5g_rssi_boost_factor", \
+	0, \
+	2, \
+	1, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Factor by which 5GHz RSSI is boosted")
+
+/*
+ * <ini>
+ * 5g_max_rssi_boost - Maximum boost that can be applied to 5GHz RSSI.
+ * @Min: 0
+ * @Max: 20
+ * @Default: 10
+ * This ini is used to set maximum boost which can be given to a 5Ghz network.
+ *
+ * Related: 5g_rssi_boost_threshold, 5g_rssi_boost_factor
+ * 5g_rssi_penalize_threshold, 5g_rssi_penalize_factor, 5g_max_rssi_penalize
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_5G_MAX_RSSI_BOOST CFG_INI_UINT( \
+	"5g_max_rssi_boost", \
+	0, \
+	20, \
+	10, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Maximum boost that can be applied to 5GHz RSSI")
+
+/*
+ * <ini>
+ * 5g_rssi_penalize_threshold - A_band_penalize_threshold above which
+ * 5 GHz is not favored.
+ * @Min: -65
+ * @Max: -80
+ * @Default: -70
+ * This ini is used to set threshold for 5GHz band preference.
+ *
+ * Related: 5g_rssi_penalize_factor, 5g_max_rssi_penalize
+ * 5g_rssi_boost_threshold, 5g_rssi_boost_factor, 5g_max_rssi_boost
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_5G_RSSI_PENALIZE_THRESHOLD CFG_INI_INT( \
+	"5g_rssi_penalize_threshold", \
+	-65, \
+	-80, \
+	-70, \
+	CFG_VALUE_OR_DEFAULT, \
+	"A_band_penalize_threshold above which 5 GHz is not favored")
+
+/*
+ * <ini>
+ * 5g_rssi_penalize_factor - Factor by which 5GHz RSSI is penalizeed.
+ * @Min: 0
+ * @Max: 2
+ * @Default: 1
+ * This ini is used to set the 5Ghz penalize factor.
+ *
+ * Related: 5g_rssi_penalize_threshold, 5g_max_rssi_penalize
+ * 5g_rssi_boost_threshold, 5g_rssi_boost_factor, 5g_max_rssi_boost
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_5G_RSSI_PENALIZE_FACTOR CFG_INI_UINT( \
+	"5g_rssi_penalize_factor", \
+	0, \
+	2, \
+	1, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Factor by which 5GHz RSSI is penalizeed")
+
+/*
+ * <ini>
+ * 5g_max_rssi_penalize - Maximum penalty that can be applied to 5GHz RSSI.
+ * @Min: 0
+ * @Max: 20
+ * @Default: 10
+ * This ini is used to set maximum penalty which can be given to a 5Ghz network.
+ *
+ * Related: 5g_rssi_penalize_threshold, 5g_rssi_penalize_factor
+ * 5g_rssi_boost_threshold, 5g_rssi_boost_factor, 5g_max_rssi_boost
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_5G_MAX_RSSI_PENALIZE CFG_INI_UINT( \
+	"5g_max_rssi_penalize", \
+	0, \
+	20, \
+	10, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Maximum penalty that can be applied to 5GHz RSSI")
+
+/*
+ * max_num_pre_auth - Configure max number of pre-auth
+ * @Min: 0
+ * @Max: 256
+ * @Default: 64
+ *
+ * This ini is used to configure the data max number of pre-auth
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_LFR_MAX_NUM_PRE_AUTH CFG_UINT( \
+	"max_num_pre_auth", \
+	0, \
+	256, \
+	64, \
+	CFG_VALUE_OR_DEFAULT, \
+	"")
+
+/*
+ * roam_preauth_retry_count
+ *
+ * @Min: 1
+ * @Max: 10
+ * @Default: 5
+ *
+ * The maximum number of software retries for preauth or
+ * reassoc made before picking up the next candidate for
+ * connection during roaming.
+ *
+ * Related: N/A
+ *
+ * Supported Features: Roaming
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_LFR3_ROAM_PREAUTH_RETRY_COUNT CFG_INI_INT( \
+			"roam_preauth_retry_count", \
+			1, \
+			10, \
+			5, \
+			CFG_VALUE_OR_DEFAULT, \
+			"The maximum number of software retries for preauth")
+
+/*
+ * <ini>
+ * roam_preauth_no_ack_timeout
+ *
+ * @Min: 5
+ * @Max: 50
+ * @Default: 5
+ *
+ * Time to wait (in ms) after sending an preauth or reassoc
+ * request which didn’t have an ack, before considering
+ * it as a failure and making another software retry.
+ *
+ * Related: N/A
+ *
+ * Supported Features: Roaming
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_LFR3_ROAM_PREAUTH_NO_ACK_TIMEOUT CFG_INI_INT( \
+			"roam_preauth_no_ack_timeout", \
+			5, \
+			50, \
+			5, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Time to wait after sending an preauth or reassoc")
+
+#define CFG_LFR_ALL \
+	CFG(CFG_LFR_MAWC_ROAM_ENABLED) \
+	CFG(CFG_LFR_MAWC_ROAM_TRAFFIC_THRESHOLD) \
+	CFG(CFG_LFR_MAWC_ROAM_AP_RSSI_THRESHOLD) \
+	CFG(CFG_LFR_MAWC_ROAM_RSSI_HIGH_ADJUST) \
+	CFG(CFG_LFR_MAWC_ROAM_RSSI_LOW_ADJUST) \
+	CFG(CFG_LFR_ROAM_RSSI_ABS_THRESHOLD) \
+	CFG(CFG_LFR_5G_RSSI_THRESHOLD_OFFSET) \
+	CFG(CFG_LFR_ENABLE_FAST_ROAM_IN_CONCURRENCY) \
+	CFG(CFG_LFR3_ROAMING_OFFLOAD) \
+	CFG(CFG_LFR_EARLY_STOP_SCAN_ENABLE) \
+	CFG(CFG_LFR_EARLY_STOP_SCAN_MIN_THRESHOLD) \
+	CFG(CFG_LFR_EARLY_STOP_SCAN_MAX_THRESHOLD) \
+	CFG(CFG_LFR_FIRST_SCAN_BUCKET_THRESHOLD) \
+	CFG(CFG_LFR3_ENABLE_SUBNET_DETECTION) \
+	CFG(CFG_LFR_ROAM_DENSE_TRAFFIC_THRESHOLD) \
+	CFG(CFG_LFR_ROAM_DENSE_RSSI_THRE_OFFSET) \
+	CFG(CFG_LFR_ROAM_DENSE_MIN_APS) \
+	CFG(CFG_LFR_ROAM_BG_SCAN_BAD_RSSI_THRESHOLD) \
+	CFG(CFG_LFR_ROAM_BG_SCAN_CLIENT_BITMAP) \
+	CFG(CFG_LFR_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G) \
+	CFG(CFG_LFR_ADAPTIVE_ROAMSCAN_DWELL_MODE) \
+	CFG(CFG_LFR_PER_ROAM_ENABLE) \
+	CFG(CFG_LFR_PER_ROAM_CONFIG_HIGH_RATE_TH) \
+	CFG(CFG_LFR_PER_ROAM_CONFIG_LOW_RATE_TH) \
+	CFG(CFG_LFR_PER_ROAM_CONFIG_RATE_TH_PERCENT) \
+	CFG(CFG_LFR_PER_ROAM_REST_TIME) \
+	CFG(CFG_LFR_PER_ROAM_MONITOR_TIME) \
+	CFG(CFG_LFR_PER_ROAM_MIN_CANDIDATE_RSSI) \
+	CFG(CFG_LFR3_ROAM_DISALLOW_DURATION) \
+	CFG(CFG_LFR3_ROAM_RSSI_CHANNEL_PENALIZATION) \
+	CFG(CFG_LFR3_ROAM_NUM_DISALLOWED_APS) \
+	CFG(CFG_LFR_ENABLE_5G_BAND_PREF) \
+	CFG(CFG_LFR_5G_RSSI_BOOST_THRESHOLD) \
+	CFG(CFG_LFR_5G_RSSI_BOOST_FACTOR) \
+	CFG(CFG_LFR_5G_MAX_RSSI_BOOST) \
+	CFG(CFG_LFR_5G_RSSI_PENALIZE_THRESHOLD) \
+	CFG(CFG_LFR_5G_RSSI_PENALIZE_FACTOR) \
+	CFG(CFG_LFR_5G_MAX_RSSI_PENALIZE) \
+	CFG(CFG_LFR_MAX_NUM_PRE_AUTH) \
+	CFG(CFG_LFR3_ROAM_PREAUTH_RETRY_COUNT) \
+	CFG(CFG_LFR3_ROAM_PREAUTH_NO_ACK_TIMEOUT)
+
+#endif /* CFG_MLME_LFR_H__ */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_mbo.h b/components/mlme/dispatcher/inc/cfg_mlme_mbo.h
new file mode 100644
index 0000000..02dce22
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_mbo.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of QOS related
+ * converged configurations.
+ */
+
+#ifndef __CFG_MLME_MBO_H
+#define __CFG_MLME_MBO_H
+
+/*
+ * <ini>
+ * g_mbo_candidate_rssi_thres - Candidate AP's minimum RSSI to accept
+ * @Min: -120
+ * @Max: 0
+ * @Default: -72
+ *
+ * This ini specifies the minimum RSSI value a candidate should have to accept
+ * it as a target for transition.
+ *
+ * Related: N/A
+ *
+ * Supported Feature: MBO
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_MBO_CANDIDATE_RSSI_THRESHOLD CFG_INI_INT( \
+			"g_mbo_candidate_rssi_thres", \
+			-120, \
+			0, \
+			-72, \
+			CFG_VALUE_OR_DEFAULT, \
+			"candidate AP rssi threshold")
+/*
+ * <ini>
+ * g_mbo_current_rssi_thres - Connected AP's RSSI threshold to consider a
+ * transition
+ * @Min: -120
+ * @Max: 0
+ * @Default: -65
+ *
+ * This ini is used to configure connected AP's RSSI threshold value to consider
+ * a transition.
+ *
+ * Related: N/A
+ *
+ * Supported Feature: MBO
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_MBO_CURRENT_RSSI_THRESHOLD CFG_INI_INT( \
+			"g_mbo_current_rssi_thres", \
+			-120, \
+			0, \
+			-65, \
+			CFG_VALUE_OR_DEFAULT, \
+			"current AP rssi threshold")
+
+/*
+ * <ini>
+ * g_mbo_current_rssi_mcc_thres - connected AP's RSSI threshold value to prefer
+ * against a MCC
+ * @Min: -120
+ * @Max: 0
+ * @Default: -75
+ *
+ * This ini is used to configure connected AP's minimum RSSI threshold that is
+ * preferred against a MCC case, if the candidate can cause MCC.
+ *
+ * Related: N/A
+ *
+ * Supported Feature: MBO
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_MBO_CUR_RSSI_MCC_THRESHOLD CFG_INI_INT( \
+		"g_mbo_current_rssi_mcc_thres", \
+		-120, \
+		0, \
+		-75, \
+		CFG_VALUE_OR_DEFAULT, \
+		"current AP mcc rssi threshold")
+
+/*
+ * <ini>
+ * g_mbo_candidate_rssi_btc_thres -  Candidate AP's minimum RSSI threshold to
+ * prefer it even in case of BT coex
+ * @Min: -120
+ * @Max: 0
+ * @Default: -70
+ *
+ * This ini is used to configure candidate AP's minimum RSSI threshold to prefer
+ * it for transition even in case of BT coex.
+ *
+ * Related: N/A
+ *
+ * Supported Feature: MBO
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_MBO_CAND_RSSI_BTC_THRESHOLD CFG_INI_INT( \
+		"g_mbo_candidate_rssi_btc_thres", \
+		-120, \
+		0, \
+		-70, \
+		CFG_VALUE_OR_DEFAULT, \
+		"candidate AP rssi threshold")
+
+#define CFG_MBO_ALL \
+	CFG(CFG_MBO_CANDIDATE_RSSI_THRESHOLD) \
+	CFG(CFG_MBO_CURRENT_RSSI_THRESHOLD) \
+	CFG(CFG_MBO_CUR_RSSI_MCC_THRESHOLD) \
+	CFG(CFG_MBO_CAND_RSSI_BTC_THRESHOLD)
+
+#endif /* __CFG_MLME_MBO_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_obss_ht40.h b/components/mlme/dispatcher/inc/cfg_mlme_obss_ht40.h
new file mode 100644
index 0000000..866746d
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_obss_ht40.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2012-2018 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 configuration definitions for MLME OBSS HT40.
+ */
+#ifndef CFG_MLME_OBSS_HT40_H__
+#define CFG_MLME_OBSS_HT40_H__
+
+/*
+ * <ini>
+ * obss_active_dwelltime - Set obss active dwelltime
+ * @Min: 10
+ * @Max: 1000
+ * @Default: 10
+ *
+ * This ini is used to set dwell time in secs for active
+ * obss scan
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME CFG_INI_UINT( \
+	"obss_active_dwelltime", \
+	10, \
+	1000, \
+	10, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Set obss active dwelltime")
+
+/*
+ * <ini>
+ * obss_passive_dwelltime - Set obss passive dwelltime
+ * @Min: 5
+ * @Max: 1000
+ * @Default: 20
+ *
+ * This ini is used to set dwell time in secs for passive
+ * obss scan
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME CFG_INI_UINT( \
+	"obss_passive_dwelltime", \
+	5, \
+	1000, \
+	20, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Set obss passive dwelltime")
+
+/*
+ * <ini>
+ * obss_width_trigger_interval - Set obss trigger interval
+ * @Min: 10
+ * @Max: 900
+ * @Default: 200
+ *
+ * This ini is used during an OBSS scan operation,
+ * where each channel in the set is scanned at least
+ * once per configured trigger interval time. Unit is TUs.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL CFG_INI_UINT( \
+	"obss_width_trigger_interval", \
+	10, \
+	900, \
+	200, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Set obss trigger interval")
+
+/*
+ * obss_passive_total_per_channel - Set obss scan passive total per channel
+ * @Min: 200
+ * @Max: 10000
+ * @Default: 200
+ *
+ * FW can perform multiple scans with in a OBSS scan interval. This cfg is for
+ * the total per channel dwell time of passive scans. Unit is TUs.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL CFG_UINT( \
+	"obss_passive_total_per_channel", \
+	200, \
+	10000, \
+	200, \
+	CFG_VALUE_OR_DEFAULT, \
+	"obss passive total per channel")
+
+/*
+ * obss_active_total_per_channel - Set obss scan active total per channel
+ * @Min: 20
+ * @Max: 10000
+ * @Default: 20
+ *
+ * FW can perform multiple scans with in a OBSS scan interval. This cfg is for
+ * the total per channel dwell time of active scans. Unit is TUs.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL CFG_UINT( \
+	"obss_active_total_per_channel", \
+	20, \
+	10000, \
+	20, \
+	CFG_VALUE_OR_DEFAULT, \
+	"obss active total per channel")
+
+/*
+ * obss_scan_activity_thre - Set obss scan activity threshold
+ * @Min: 0
+ * @Max: 100
+ * @Default: 25
+ *
+ * This cfg sets obss scan activity threshold.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD CFG_UINT( \
+	"obss_scan_activity_thre", \
+	0, \
+	100, \
+	25, \
+	CFG_VALUE_OR_DEFAULT, \
+	"obss ht40 scan activity threshold")
+
+/*
+ * obss_width_transition_delay - Set obss width transition delay
+ * @Min: 5
+ * @Max: 100
+ * @Default: 5
+ *
+ * This cfg sets obss width transition delay, it is used to check exemption
+ * from scan. The unit is TUs.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY CFG_UINT( \
+	"obss_width_transition_delay", \
+	5, \
+	100, \
+	5, \
+	CFG_VALUE_OR_DEFAULT, \
+	"obss ht40 width transition delay")
+
+#define CFG_OBSS_HT40_ALL \
+	CFG(CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME) \
+	CFG(CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME) \
+	CFG(CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL) \
+	CFG(CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL) \
+	CFG(CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL) \
+	CFG(CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD) \
+	CFG(CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY)
+
+#endif /* CFG_MLME_OBSS_HT40_H__ */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_oce.h b/components/mlme/dispatcher/inc/cfg_mlme_oce.h
new file mode 100644
index 0000000..1b83900
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_oce.h
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_OCE_H
+#define __CFG_MLME_OCE_H
+
+/*
+ * <ini>
+ * g_enable_bcast_probe_rsp - Enable Broadcast probe response.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable broadcast probe response.
+ * If this is disabled then OCE ini oce_sta_enable will also be
+ * disabled and OCE IE will not be sent in frames.
+ *
+ * Related: None
+ *
+ * Supported Feature: FILS
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_BCAST_PROBE_RESP CFG_INI_BOOL( \
+		"g_enable_bcast_probe_rsp", \
+		1, \
+		"Enable Broadcast probe response")
+
+/*
+ * <ini>
+ * oce_sta_enable - Enable/disable oce feature for STA
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable oce feature for STA
+ *
+ * Related: None
+ *
+ * Supported Feature: OCE
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OCE_ENABLE_STA CFG_INI_BOOL( \
+		"oce_sta_enable", \
+		1, \
+		"Enable/disable oce feature for STA")
+
+/*
+ * <ini>
+ * oce_sap_enable - Enable/disable oce feature for SAP
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable oce feature for SAP
+ *
+ * Related: None
+ *
+ * Supported Feature: OCE
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OCE_ENABLE_SAP CFG_INI_BOOL( \
+		"oce_sap_enable", \
+		1, \
+		"Enable/disable oce feature for SAP")
+
+/*
+ * oce_enable_rssi_assoc_reject - Enable/disable rssi based assoc rejection
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable rssi based assoc rejection. If this is
+ * disabled then OCE ini oce_sta_enable will also be disabled and OCE IE will
+ * not be sent in frames.
+ *
+ * Related: None
+ *
+ * Supported Feature: OCE
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OCE_ENABLE_RSSI_BASED_ASSOC_REJECT CFG_INI_BOOL( \
+		"oce_enable_rssi_assoc_reject", \
+		1, \
+		"Enable/disable rssi based assoc rejection")
+
+/*
+ * <ini>
+ * oce_enable_probe_req_rate - Set probe request rate
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set probe request rate to 5.5Mbps as per OCE requirement
+ * in 2.4G band
+ *
+ * Related: None
+ *
+ * Supported Feature: OCE
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OCE_PROBE_REQ_RATE CFG_INI_BOOL( \
+		"oce_enable_probe_req_rate", \
+		0, \
+		"Set probe request rate for OCE")
+
+/*
+ * <ini>
+ * oce_enable_probe_resp_rate - Set probe response rate
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set probe response rate to 5.5Mbps as per OCE requirement
+ * in 2.4G band
+ *
+ * Related: None
+ *
+ * Supported Feature: OCE
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OCE_PROBE_RSP_RATE CFG_INI_BOOL( \
+		"oce_enable_probe_resp_rate", \
+		0, \
+		"Set probe response rate for OCE")
+
+/*
+ * <ini>
+ * oce_enable_beacon_rate - Set beacon rate
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set beacon rate to 5.5Mbps as per OCE requirement in
+ * 2.4G band
+ *
+ * Related: None
+ *
+ * Supported Feature: OCE
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OCE_BEACON_RATE CFG_INI_BOOL( \
+		"oce_enable_beacon_rate", \
+		0, \
+		"Set Beacon rate for OCE")
+/*
+ * <ini>
+ * oce_enable_probe_req_deferral - Enable/disable probe request deferral
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable probe request deferral as per OCE spec
+ *
+ * Related: None
+ *
+ * Supported Feature: OCE
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_PROBE_REQ_DEFERRAL CFG_INI_BOOL( \
+		"oce_enable_probe_req_deferral", \
+		0, \
+		"Enable/disable probe request deferral for OCE")
+
+/*
+ * <ini>
+ * oce_enable_fils_discovery_sap - Enable/disable fils discovery in sap mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable fils discovery in sap mode
+ *
+ * Related: None
+ *
+ * Supported Feature: FILS
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_FILS_DISCOVERY_SAP CFG_INI_BOOL( \
+		"oce_enable_fils_discovery_sap", \
+		1, \
+		"Enable/disable fils discovery in sap mode")
+
+/*
+ * <ini>
+ * enable_esp_for_roam - Enable/disable esp feature
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable ESP(Estimated service parameters) IE
+ * parsing and decides whether firmware will include this in its scoring algo.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_ESP_FEATURE CFG_INI_BOOL( \
+		"enable_esp_for_roam", \
+		0, \
+		"Enable/disable esp feature")
+
+/*
+ * <ini>
+ * g_is_fils_enabled - Enable/Disable FILS support in driver
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable FILS support in driver
+ * Driver will update config to supplicant based on this config.
+ *
+ * Related: None
+ *
+ * Supported Feature: FILS
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_IS_FILS_ENABLED CFG_INI_BOOL( \
+		"g_is_fils_enabled", \
+		1, \
+		"Enable/disable support")
+
+#define CFG_OCE_ALL \
+	CFG(CFG_ENABLE_BCAST_PROBE_RESP) \
+	CFG(CFG_OCE_ENABLE_STA) \
+	CFG(CFG_OCE_ENABLE_SAP) \
+	CFG(CFG_OCE_ENABLE_RSSI_BASED_ASSOC_REJECT) \
+	CFG(CFG_OCE_PROBE_REQ_RATE) \
+	CFG(CFG_OCE_PROBE_RSP_RATE) \
+	CFG(CFG_OCE_BEACON_RATE) \
+	CFG(CFG_ENABLE_PROBE_REQ_DEFERRAL) \
+	CFG(CFG_ENABLE_FILS_DISCOVERY_SAP) \
+	CFG(CFG_ENABLE_ESP_FEATURE) \
+	CFG(CFG_IS_FILS_ENABLED)
+#endif /* __CFG_MLME_OCE_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_rates.h b/components/mlme/dispatcher/inc/cfg_mlme_rates.h
new file mode 100644
index 0000000..73f7ee1
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_rates.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_RATES_H
+#define __CFG_MLME_RATES_H
+
+#define CFG_SUPPORTED_RATES_11B_LEN    4
+#define CFG_SUPPORTED_RATES_11A_LEN    8
+#define CFG_OPERATIONAL_RATE_SET_LEN    12
+#define CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN    8
+#define CFG_SUPPORTED_MCS_SET_LEN    16
+#define CFG_BASIC_MCS_SET_LEN    16
+#define CFG_CURRENT_MCS_SET_LEN    16
+
+/*
+ * <ini>
+ * gMaxHTMCSForTxData - max HT mcs for TX
+ * @Min: 0
+ * @Max: 383
+ * @Default: 0
+ *
+ * This ini is used to configure the max HT mcs
+ * for tx data.
+ *
+ * Usage: External
+ *
+ * bits 0-15:  max HT mcs
+ * bits 16-31: zero to disable, otherwise enable.
+ *
+ * </ini>
+ */
+#define CFG_MAX_HT_MCS_FOR_TX_DATA CFG_INI_UINT( \
+		"gMaxHTMCSForTxData", \
+		0, \
+		0x17f, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Max HT Mcs for Tx Data")
+
+/*
+ * <ini>
+ * gDisableABGRateForTxData - disable abg rate for tx data
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to disable abg rate for tx data.
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_DISABLE_ABG_RATE_FOR_TX_DATA CFG_INI_BOOL( \
+		"gDisableABGRateForTxData", \
+		0, \
+		"Disable ABG RATE for TX Data")
+
+/*
+ * gSapMaxMCSForTxData - sap 11n max mcs
+ * @Min: 0
+ * @Max: 383
+ * @Default: 0
+ *
+ * This ini configure SAP 11n max mcs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SAP_MAX_MCS_FOR_TX_DATA CFG_INI_UINT( \
+		"gSapMaxMCSForTxData", \
+		0, \
+		383, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"SAP Max MCS for TX Data")
+
+/*
+ * <ini>
+ * disable_high_ht_mcs_2x2 - disable high mcs index for 2nd stream in 2.4G
+ * @Min: 0
+ * @Max: 8
+ * @Default: 0
+ *
+ * This ini is used to disable high HT MCS index for 2.4G STA connection.
+ * It has been introduced to resolve IOT issue with one of the vendor.
+ *
+ * Note: This INI is not useful with 1x1 setting. If some platform supports
+ * only 1x1 then this INI is not useful.
+ *
+ * 0 - It won't disable any HT MCS index (just like normal HT MCS)
+ * 1 - It will disable 15th bit from HT RX MCS set (from 8-15 bits slot)
+ * 2 - It will disable 14th & 15th bits from HT RX MCS set
+ * 3 - It will disable 13th, 14th, & 15th bits from HT RX MCS set
+ * and so on.
+ *
+ * Related: STA
+ *
+ * Supported Feature: 11n
+ *
+ * Usage: External
+ */
+#define CFG_DISABLE_HIGH_HT_RX_MCS_2x2 CFG_INI_UINT( \
+		"disable_high_ht_mcs_2x2", \
+		0, \
+		8, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Disable high MCS index for 2x2")
+
+#define CFG_CFP_PERIOD CFG_UINT( \
+		"cfpPeriod", \
+		0, \
+		255, \
+		1, \
+		CFG_VALUE_OR_DEFAULT, \
+		"CFP Period")
+
+#define CFG_CFP_MAX_DURATION CFG_UINT( \
+		"cfpMaxDuration", \
+		0, \
+		65535, \
+		30000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"CFP Max Duration")
+/*
+ * <cfg>
+ * supported_rates_11b - supported rates for 11b
+ * @Min: 0 minimum length of supported rates
+ * @Max: default data length of supported rates in string format
+ * @Default: 2, 4, 11, 22
+ */
+#define CFG_SUPPORTED_RATES_11B_DATA "2, 4, 11, 22"
+#define CFG_SUPPORTED_RATES_11B CFG_STRING( \
+		"supported_rates_11b", \
+		0, \
+		sizeof(CFG_SUPPORTED_RATES_11B_DATA) - 1, \
+		CFG_SUPPORTED_RATES_11B_DATA, \
+		"Supported rates for 11B")
+
+/*
+ * <cfg>
+ * supported_rates_11a - supported rates for 11a
+ * @Min: 0 minimum length of supported rates
+ * @Max: default data length of supported rates in string format
+ * @Default: 12, 18, 24, 36, 48, 72, 96, 108
+ */
+#define CFG_SUPPORTED_RATES_11A_DATA "12, 18, 24, 36, 48, 72, 96, 108"
+#define CFG_SUPPORTED_RATES_11A CFG_STRING( \
+		"supported_rates_11a", \
+		0, \
+		sizeof(CFG_SUPPORTED_RATES_11A_DATA) - 1, \
+		CFG_SUPPORTED_RATES_11A_DATA, \
+		"Supported rates for 11A")
+
+/*
+ * <cfg>
+ * supported_mcs_set - supported MCS set data
+ * @Min: 0 minimum length of supported MCS set
+ * @Max: default data length of supported mcs set in string format
+ * @Default: 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ * 0x0, 0x0, 0x0
+ */
+#define CFG_SUPPORTED_MCS_SET_DATA "0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0"
+#define CFG_SUPPORTED_MCS_SET CFG_STRING( \
+		"supported_mcs_set", \
+		0, \
+		sizeof(CFG_SUPPORTED_MCS_SET_DATA) - 1, \
+		CFG_SUPPORTED_MCS_SET_DATA, \
+		"supported MCS set")
+
+/*
+ * <cfg>
+ * basic_mcs_set - basic MCS set data
+ * @Min: 0 minimum length of basic MCS set
+ * @Max: default data length of basic mcs set in string format
+ * @Default: 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ * 0x0, 0x0, 0x0
+ */
+#define CFG_BASIC_MCS_SET_DATA "0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0"
+#define CFG_BASIC_MCS_SET CFG_STRING( \
+		"basic_mcs_set", \
+		0, \
+		sizeof(CFG_BASIC_MCS_SET_DATA) - 1, \
+		CFG_BASIC_MCS_SET_DATA, \
+		"basic MCS set")
+
+/*
+ * <cfg>
+ * current_mcs_set - current MCS set data
+ * @Min: 0 minimum length of current MCS set
+ * @Max: default data length of current mcs set in string format
+ * @Default: 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ * 0x0, 0x0, 0x0
+ */
+#define CFG_CURRENT_MCS_SET_DATA "0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0"
+#define CFG_CURRENT_MCS_SET CFG_STRING( \
+		"current_mcs_set", \
+		0, \
+		sizeof(CFG_CURRENT_MCS_SET_DATA) - 1, \
+		CFG_CURRENT_MCS_SET_DATA, \
+		"current MCS set")
+
+#define CFG_RATES_ALL \
+	CFG(CFG_MAX_HT_MCS_FOR_TX_DATA) \
+	CFG(CFG_DISABLE_ABG_RATE_FOR_TX_DATA) \
+	CFG(CFG_SAP_MAX_MCS_FOR_TX_DATA) \
+	CFG(CFG_DISABLE_HIGH_HT_RX_MCS_2x2) \
+	CFG(CFG_CFP_PERIOD) \
+	CFG(CFG_CFP_MAX_DURATION) \
+	CFG(CFG_SUPPORTED_RATES_11B) \
+	CFG(CFG_SUPPORTED_RATES_11A) \
+	CFG(CFG_SUPPORTED_MCS_SET) \
+	CFG(CFG_BASIC_MCS_SET) \
+	CFG(CFG_CURRENT_MCS_SET)
+
+#endif /* __CFG_MLME_RATES_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_sap.h b/components/mlme/dispatcher/inc/cfg_mlme_sap.h
new file mode 100644
index 0000000..ca41356
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_sap.h
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_SAP_H
+#define __CFG_MLME_SAP_H
+
+#define CFG_SSID CFG_STRING( \
+			"cfg_ssid", \
+			0, \
+			32, \
+			"1,2,3,4,5,6,7,8,9,0", \
+			"CFG_SSID")
+
+#define CFG_BEACON_INTERVAL CFG_INI_UINT( \
+			"gBeaconInterval", \
+			0, \
+			65535, \
+			100, \
+			CFG_VALUE_OR_DEFAULT, \
+			"CFG_BEACON_INTERVAL")
+
+#define CFG_DTIM_PERIOD CFG_UINT( \
+			"cfg_dtim_period", \
+			0, \
+			65535, \
+			1, \
+			CFG_VALUE_OR_DEFAULT, \
+			"CFG_DTIM_PERIOD")
+
+#define CFG_LISTEN_INTERVAL CFG_UINT( \
+			"cfg_listen_interval", \
+			0, \
+			65535, \
+			1, \
+			CFG_VALUE_OR_DEFAULT, \
+			"CFG_LISTEN_INTERVAL")
+
+#define CFG_11G_ONLY_POLICY CFG_UINT( \
+			"cfg_11g_only_policy", \
+			0, \
+			1, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"CFG_11G_ONLY_POLICY")
+
+#define CFG_ASSOC_STA_LIMIT CFG_UINT( \
+			"cfg_beacon_interval", \
+			1, \
+			32, \
+			10, \
+			CFG_VALUE_OR_DEFAULT, \
+			"CFG_ASSOC_STA_LIMIT")
+
+/*
+ * <ini>
+ * cfg_enable_lte_coex - enable LTE COEX
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable LTE COEX
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_ENABLE_LTE_COEX CFG_INI_BOOL( \
+			"gEnableLTECoex", \
+			0, \
+			"enabled lte coex")
+
+#define CFG_RMC_ACTION_PERIOD_FREQUENCY CFG_UINT( \
+			"cfg_rcm_action_period_frequency", \
+			100, \
+			1000, \
+			300, \
+			CFG_VALUE_OR_DEFAULT, \
+			"CFG_RMC_ACTION_PERIOD_FREQUENCY")
+
+/*
+ * <ini>
+ * cfg_rate_for_tx_mgmt - Set rate for tx mgmt
+ * @Min: 0
+ * @Max: 0xFF
+ * @Default: 0xFF
+ *
+ * This ini is used to set rate for tx mgmt
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_RATE_FOR_TX_MGMT CFG_INI_UINT( \
+			"gRateForTxMgmt", \
+			0, \
+			0xFF, \
+			0xFF, \
+			CFG_VALUE_OR_DEFAULT, \
+			"set rate for mgmt tx")
+
+/*
+ * <ini>
+ * cfg_rate_for_tx_mgmt_2g - Set rate for tx mgmt 2g
+ * @Min: 0
+ * @Max: 255
+ * @Default: 255
+ *
+ * This ini is used to set rate for tx mgmt 2g
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_RATE_FOR_TX_MGMT_2G CFG_INI_UINT( \
+			"gRateForTxMgmt2G", \
+			0, \
+			255, \
+			255, \
+			CFG_VALUE_OR_DEFAULT, \
+			"set rate for mgmt tx 2g")
+
+/*
+ * <ini>
+ * cfg_rate_for_tx_mgmt_5g - Set rate for tx mgmt 5g
+ * @Min: 0
+ * @Max: 255
+ * @Default: 255
+ *
+ * This ini is used to set rate for tx mgmt 5g
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_RATE_FOR_TX_MGMT_5G CFG_INI_UINT( \
+			"gRateForTxMgmt5G", \
+			0, \
+			255, \
+			255, \
+			CFG_VALUE_OR_DEFAULT, \
+			"set rate for mgmt tx 5g")
+
+/*
+ * <ini>
+ * gTelescopicBeaconWakeupEn - Set teles copic beacon wakeup
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set default teles copic beacon wakeup
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_TELE_BCN_WAKEUP_EN CFG_INI_BOOL( \
+			"gTelescopicBeaconWakeupEn", \
+			0, \
+			"set tescopic beacon wakeup")
+
+/*
+ * <ini>
+ * telescopicBeaconMaxListenInterval - Set teles scopic beacon max listen value
+ * @Min: 0
+ * @Max: 7
+ * @Default: 5
+ *
+ * This ini is used to set teles scopic beacon max listen interval value
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_TELE_BCN_MAX_LI CFG_INI_UINT( \
+			"telescopicBeaconMaxListenInterval", \
+			0, \
+			7, \
+			5, \
+			CFG_VALUE_OR_DEFAULT, \
+			"set telescopic beacon max listen")
+
+/*
+ * <ini>
+ * gSapGetPeerInfo - Enable/Disable remote peer info query support
+ * @Min: 0 - Disable remote peer info query support
+ * @Max: 1 - Enable remote peer info query support
+ * @Default: 0
+ *
+ * This ini is used to enable/disable remote peer info query support
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+ #define CFG_SAP_GET_PEER_INFO CFG_INI_BOOL( \
+			"gSapGetPeerInfo", \
+			0, \
+			"sap get peer info")
+
+/*
+ * <ini>
+ * gSapAllowAllChannel - Sap allow all channels
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to allow all channels for SAP
+ *
+ * Related: None
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_SAP_ALLOW_ALL_CHANNEL_PARAM CFG_INI_BOOL( \
+			"gSapAllowAllChannel", \
+			0, \
+			"sap allow all channel params")
+
+/*
+ * <ini>
+ * gSoftApMaxPeers - Set Max peers connected for SAP
+ * @Min: 1
+ * @Max: 32
+ * @Default: 32
+ *
+ * This ini is used to set Max peers connected for SAP
+ *
+ * Related: None
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_SAP_MAX_NO_PEERS CFG_INI_UINT( \
+			"gSoftApMaxPeers", \
+			1, \
+			32, \
+			32, \
+			CFG_VALUE_OR_DEFAULT, \
+			"max no of peers")
+
+/*
+ * <ini>
+ * gMaxOffloadPeers - Set max offload peers
+ * @Min: 2
+ * @Max: 5
+ * @Default: 2
+ *
+ * This ini is used to set default teles copic beacon wakeup
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_SAP_MAX_OFFLOAD_PEERS CFG_INI_UINT( \
+			"gMaxOffloadPeers", \
+			2, \
+			5, \
+			2, \
+			CFG_VALUE_OR_DEFAULT, \
+			"max offload peers")
+
+/*
+ * <ini>
+ * gMaxOffloadReorderBuffs - Set max offload reorder buffs
+ * @Min: 0
+ * @Max: 3
+ * @Default: 2
+ *
+ * This ini is used to set max offload reorder buffs
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_SAP_MAX_OFFLOAD_REORDER_BUFFS CFG_INI_UINT( \
+			"gMaxOffloadReorderBuffs", \
+			0, \
+			3, \
+			2, \
+			CFG_VALUE_OR_DEFAULT, \
+			"sap max offload reorder buffs")
+
+/*
+ * <ini>
+ * g_sap_chanswitch_beacon_cnt - Set channel switch beacon count
+ * @Min: 1
+ * @Max: 10
+ * @Default: 10
+ *
+ * This ini is used to set channel switch beacon count
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_SAP_CH_SWITCH_BEACON_CNT CFG_INI_UINT( \
+			"g_sap_chanswitch_beacon_cnt", \
+			1, \
+			10, \
+			10, \
+			CFG_VALUE_OR_DEFAULT, \
+			"set channel switch beacon count")
+
+/*
+ * <ini>
+ * g_sap_chanswitch_mode - channel switch mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to configure channel switch mode
+ *
+ * Related: none
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SAP_CH_SWITCH_MODE CFG_INI_BOOL( \
+			"g_sap_chanswitch_mode", \
+			1, \
+			"sap channel switch mode")
+
+/*
+ * <ini>
+ * gEnableSapInternalRestart - Sap internal restart name
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used for sap internal restart name
+ *
+ * Related: None
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_SAP_INTERNAL_RESTART CFG_INI_BOOL( \
+			"gEnableSapInternalRestart", \
+			1, \
+			"sap internal restart")
+
+/*
+ * <ini>
+ * gChanSwitchHostapdRateEnabled - Enable channale switch hostapd rate
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable channale switch hostapd rate
+ *
+ * Related: None
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+ #define CFG_CHAN_SWITCH_HOSTAPD_RATE_ENABLED_NAME CFG_INI_BOOL( \
+			"gChanSwitchHostapdRateEnabled", \
+			0, \
+			"chan switch hostapd rate enabled")
+
+/*
+ * gReducedBeaconInterval - beacon interval reduced
+ * @Min: 0
+ * @Max: 100
+ * @Default: 0
+ *
+ * This ini is used to reduce beacon interval before channel
+ * switch (when val great than 0, or the feature is disabled).
+ * It would reduce the downtime on the STA side which is
+ * waiting for beacons from the AP to resume back transmission.
+ * Switch back the beacon_interval to its original value after
+ * channel switch based on the timeout.
+ *
+ * Related: none
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_REDUCED_BEACON_INTERVAL CFG_INI_UINT( \
+			"gReducedBeaconInterval", \
+			0, \
+			100, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"reduced beacon interval")
+
+ #define CFG_SAP_ALL \
+	CFG(CFG_SSID) \
+	CFG(CFG_BEACON_INTERVAL) \
+	CFG(CFG_DTIM_PERIOD) \
+	CFG(CFG_LISTEN_INTERVAL) \
+	CFG(CFG_11G_ONLY_POLICY) \
+	CFG(CFG_ASSOC_STA_LIMIT) \
+	CFG(CFG_ENABLE_LTE_COEX) \
+	CFG(CFG_RMC_ACTION_PERIOD_FREQUENCY) \
+	CFG(CFG_RATE_FOR_TX_MGMT) \
+	CFG(CFG_RATE_FOR_TX_MGMT_2G) \
+	CFG(CFG_RATE_FOR_TX_MGMT_5G) \
+	CFG(CFG_TELE_BCN_WAKEUP_EN) \
+	CFG(CFG_TELE_BCN_MAX_LI) \
+	CFG(CFG_SAP_GET_PEER_INFO) \
+	CFG(CFG_SAP_ALLOW_ALL_CHANNEL_PARAM) \
+	CFG(CFG_SAP_MAX_NO_PEERS) \
+	CFG(CFG_SAP_MAX_OFFLOAD_PEERS) \
+	CFG(CFG_SAP_MAX_OFFLOAD_REORDER_BUFFS) \
+	CFG(CFG_SAP_CH_SWITCH_BEACON_CNT) \
+	CFG(CFG_SAP_CH_SWITCH_MODE) \
+	CFG(CFG_SAP_INTERNAL_RESTART) \
+	CFG(CFG_CHAN_SWITCH_HOSTAPD_RATE_ENABLED_NAME) \
+	CFG(CFG_REDUCED_BEACON_INTERVAL)
+
+#endif /* __CFG_MLME_SAP_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_scoring.h b/components/mlme/dispatcher/inc/cfg_mlme_scoring.h
new file mode 100644
index 0000000..7af2d36
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_scoring.h
@@ -0,0 +1,1023 @@
+/*
+ * Copyright (c) 2012-2018 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 MLME SCORING related CFG/INI Items.
+ */
+
+#ifndef __CFG_MLME_SCORING_H
+#define __CFG_MLME_SCORING_H
+
+/*
+ * <ini>
+ * rssi_weightage - RSSI Weightage to calculate best candidate
+ * @Min: 0
+ * @Max: 100
+ * @Default: 20
+ *
+ * This ini is used to increase/decrease RSSI weightage in best candidate
+ * selection. AP with better RSSI will get more weightage.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_RSSI_WEIGHTAGE CFG_INI_UINT( \
+	"rssi_weightage", \
+	0, \
+	100, \
+	20, \
+	CFG_VALUE_OR_DEFAULT, \
+	"RSSI Weightage")
+
+/*
+ * <ini>
+ * ht_caps_weightage - HT caps weightage to calculate best candidate
+ * @Min: 0
+ * @Max: 100
+ * @Default: 2
+ *
+ * This ini is used to increase/decrease HT caps weightage in best candidate
+ * selection. If AP supports HT caps, AP will get additional Weightage with
+ * this param. Weightage will be given only if dot11mode is HT capable.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_HT_CAPS_WEIGHTAGE CFG_INI_UINT( \
+	"ht_caps_weightage", \
+	0, \
+	100, \
+	2, \
+	CFG_VALUE_OR_DEFAULT, \
+	"HT Caps Weightage")
+
+/*
+ * <ini>
+ * vht_caps_weightage - VHT caps Weightage to calculate best candidate
+ * @Min: 0
+ * @Max: 100
+ * @Default: 1
+ *
+ * This ini is used to increase/decrease VHT caps weightage in best candidate
+ * selection. If AP supports VHT caps, AP will get additional weightage with
+ * this param. Weightage will be given only if dot11mode is VHT capable.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_VHT_CAPS_WEIGHTAGE CFG_INI_UINT( \
+	"vht_caps_weightage", \
+	0, \
+	100, \
+	1, \
+	CFG_VALUE_OR_DEFAULT, \
+	"HT Caps Weightage")
+
+/*
+ * <ini>
+ * he_caps_weightage - HE caps Weightage to calculate best candidate
+ * @Min: 0
+ * @Max: 100
+ * @Default: 2
+ *
+ * This ini is used to increase/decrease HE caps weightage in best candidate
+ * selection. If AP supports HE caps, AP will get additional weightage with
+ * this param. Weightage will be given only if dot11mode is HE capable.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_HE_CAPS_WEIGHTAGE CFG_INI_UINT( \
+	"he_caps_weightage", \
+	0, \
+	100, \
+	2, \
+	CFG_VALUE_OR_DEFAULT, \
+	"HE Caps Weightage")
+
+/*
+ * <ini>
+ * chan_width_weightage - Channel Width Weightage to calculate best candidate
+ * @Min: 0
+ * @Max: 100
+ * @Default: 17
+ *
+ * This ini is used to increase/decrease Channel Width weightage in best
+ * candidate selection. AP with Higher channel width will get higher weightage
+ *
+ * Related: bandwidth_weight_per_index
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_CHAN_WIDTH_WEIGHTAGE CFG_INI_UINT( \
+	"chan_width_weightage", \
+	0, \
+	100, \
+	17, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Channel width weightage")
+
+/*
+ * <ini>
+ * chan_band_weightage - Channel Band perferance to 5GHZ to
+ * calculate best candidate
+ * @Min: 0
+ * @Max: 100
+ * @Default: 2
+ *
+ * This ini is used to increase/decrease Channel Band Preference weightage
+ * in best candidate selection. 5GHZ AP get this additional boost compare to
+ * 2GHZ AP before   rssi_pref_5g_rssi_thresh and 2.4Ghz get weightage after
+ * rssi_pref_5g_rssi_thresh.
+ *
+ * Related: rssi_pref_5g_rssi_thresh, band_weight_per_index
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_CHAN_BAND_WEIGHTAGE CFG_INI_UINT( \
+	"chan_band_weightage", \
+	0, \
+	100, \
+	2, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Channel Band Weightage")
+
+/*
+ * <ini>
+ * nss_weightage - NSS Weightage to calculate best candidate
+ * @Min: 0
+ * @Max: 100
+ * @Default: 16
+ *
+ * This ini is used to increase/decrease NSS weightage in best candidate
+ * selection. If there are two AP, one AP supports 2x2 and another one supports
+ * 1x1 and station supports 2X2, first A will get this additional weightage
+ * depending on self-capability.
+ *
+ * Related: nss_weight_per_index
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_NSS_WEIGHTAGE CFG_INI_UINT( \
+	"nss_weightage", \
+	0, \
+	100, \
+	16, \
+	CFG_VALUE_OR_DEFAULT, \
+	"NSS Weightage")
+/*
+ * <ini>
+ * beamforming_cap_weightage - Beam Forming Weightage to
+ *			       calculate best candidate
+ * @Min: 0
+ * @Max: 100
+ * @Default: 2
+ *
+ * This ini is used to increase/decrease Beam forming Weightage if some AP
+ * support Beam forming or not. If AP supports Beam forming, that AP will get
+ * additional boost of this weightage.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_BEAMFORM_CAP_WEIGHTAGE CFG_INI_UINT( \
+	"beamforming_cap_weightage", \
+	0, \
+	100, \
+	2, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Beamforming Cap Weightage")
+
+/*
+ * <ini>
+ * pcl_weightage - PCL Weightage to calculate best candidate
+ * @Min: 0
+ * @Max: 100
+ * @Default: 10
+ *
+ * This ini is used to increase/decrease PCL weightage in best candidate
+ * selection. If some APs are in PCL list, those AP will get addition
+ * weightage.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_PCL_WEIGHTAGE CFG_INI_UINT( \
+	"pcl_weightage", \
+	0, \
+	100, \
+	10, \
+	CFG_VALUE_OR_DEFAULT, \
+	"PCL Weightage")
+
+/*
+ * <ini>
+ * channel_congestion_weightage - channel Congestion Weightage to
+ * calculate best candidate
+ * @Min: 0
+ * @Max: 100
+ * @Default: 5
+ *
+ * This ini is used to increase/decrease channel congestion weightage in
+ * candidate selection. Congestion is measured with the help of ESP/QBSS load.
+ *
+ * Related: num_esp_qbss_slots
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_CHAN_CONGESTION_WEIGHTAGE CFG_INI_UINT( \
+	"channel_congestion_weightage", \
+	0, \
+	100, \
+	5, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Channel Congestion Weightage")
+
+/*
+ * <ini>
+ * oce_wan_weightage - OCE WAN DL capacity Weightage to calculate best candidate
+ * @Min: 0
+ * @Max: 100
+ * @Default: 2
+ *
+ * This ini is used to increase/decrease OCE WAN caps weightage in best
+ * candidate selection. If AP have OCE WAN information, give weightage depending
+ * on the downaload available capacity.
+ *
+ * Related: num_oce_wan_slots
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_OCE_WAN_WEIGHTAGE CFG_INI_UINT( \
+	"oce_wan_weightage", \
+	0, \
+	100, \
+	2, \
+	CFG_VALUE_OR_DEFAULT, \
+	"OCE WAN Weightage")
+
+/*
+ * <ini>
+ * best_rssi_threshold - Best Rssi for score calculation
+ * @Min: 0
+ * @Max: 96
+ * @Default: 55
+ *
+ * This ini tells limit for best RSSI. RSSI better than this limit are
+ * considered as best RSSI. The best RSSI is given full rssi_weightage.
+ *
+ * Related: rssi_weightage
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_BEST_RSSI_THRESHOLD CFG_INI_UINT( \
+	"best_rssi_threshold", \
+	0, \
+	96, \
+	55, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Best RSSI threshold")
+
+/*
+ * <ini>
+ * good_rssi_threshold - Good Rssi for score calculation
+ * @Min: 0
+ * @Max: 96
+ * @Default: 70
+ *
+ * This ini tells limit for good RSSI. RSSI better than this limit and less
+ * than best_rssi_threshold is considered as good RSSI.
+ *
+ * Related: rssi_weightage, best_rssi_threshold
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_GOOD_RSSI_THRESHOLD CFG_INI_UINT( \
+	"good_rssi_threshold", \
+	0, \
+	96, \
+	70, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Good RSSI threshold")
+
+/*
+ * <ini>
+ * bad_rssi_threshold - Bad Rssi for score calculation
+ * @Min: 0
+ * @Max: 96
+ * @Default: 80
+ *
+ * This ini tells limit for Bad RSSI. RSSI greater then bad_rssi_threshold
+ * is considered as bad RSSI.
+ *
+ * Related: rssi_weightage, good_rssi_threshold
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_BAD_RSSI_THRESHOLD CFG_INI_UINT( \
+	"bad_rssi_threshold", \
+	0, \
+	96, \
+	80, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Bad RSSI threshold")
+
+/*
+ * <ini>
+ * good_rssi_pcnt - Percent Score to Good RSSI out of total RSSI score.
+ * @Min: 0
+ * @Max: 100
+ * @Default: 80
+ *
+ * This ini tells about how much percent should be given to good RSSI(RSSI
+ * between best_rssi_threshold and good_rssi_threshold) out of RSSI weightage.
+ *
+ * Related: rssi_weightage, best_rssi_threshold, good_rssi_threshold
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_GOOD_RSSI_PERCENT CFG_INI_UINT( \
+	"good_rssi_pcnt", \
+	0, \
+	100, \
+	80, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Good RSSI Percent")
+
+/*
+ * <ini>
+ * bad_rssi_pcnt - Percent Score to BAD RSSI out of total RSSI score.
+ * @Min: 0
+ * @Max: 100
+ * @Default: 25
+ *
+ * This ini tells about how much percent should be given to bad RSSI (RSSI
+ * between good_rssi_threshold and bad_rssi_threshold) out of RSSI weightage.
+ *
+ * Related: rssi_weightage, good_rssi_threshold, bad_rssi_threshold
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_BAD_RSSI_PERCENT CFG_INI_UINT( \
+	"bad_rssi_pcnt", \
+	0, \
+	100, \
+	25, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Bad RSSI Percent")
+
+/*
+ * <ini>
+ * good_rssi_bucket_size - Bucket size between best and good RSSI to score.
+ * @Min: 1
+ * @Max: 10
+ * @Default: 5
+ *
+ * This ini tells about bucket size for scoring between best and good RSSI.
+ * Below Best RSSI, 100% score will be given. Between best and good RSSI, RSSI
+ * is divided in buckets and score will be assigned bucket wise starting from
+ * good_rssi_pcnt.
+ *
+ * Related: rssi_weightage, good_rssi_pcnt
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_GOOD_RSSI_BUCKET_SIZE CFG_INI_UINT( \
+	"good_rssi_bucket_size", \
+	1, \
+	10, \
+	5, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Good RSSI Bucket Size")
+
+/*
+ * <ini>
+ * bad_rssi_bucket_size - Bucket size between good and bad RSSI to score.
+ * @Min: 1
+ * @Max: 10
+ * @Default: 5
+ *
+ * This ini tells about bucket size for scoring between good and bad RSSI.
+ * Between good and bad RSSI, RSSI is divided in buckets and score will be
+ * assigned bucket wise starting from bad_rssi_pcnt.
+ *
+ * Related: rssi_weightage, bad_rssi_pcnt
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_BAD_RSSI_BUCKET_SIZE CFG_INI_UINT( \
+	"bad_rssi_bucket_size", \
+	1, \
+	10, \
+	5, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Bad RSSI Bucket Size")
+
+/*
+ * <ini>
+ * rssi_pref_5g_rssi_thresh - A RSSI threshold above which 5 GHz is not favored
+ * @Min: 0
+ * @Max: 96
+ * @Default: 76
+ *
+ * 5G AP are given chan_band_weightage. This ini tells about RSSI threshold
+ * above which 5GHZ is not favored.
+ *
+ * Related: chan_band_weightage
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_RSSI_PREF_5G_THRESHOLD CFG_INI_UINT( \
+	"rssi_pref_5g_rssi_thresh", \
+	0, \
+	96, \
+	76, \
+	CFG_VALUE_OR_DEFAULT, \
+	"RSSI Pref 5G Threshold")
+
+/*
+ * <ini>
+ * bandwidth_weight_per_index - percentage as per bandwidth
+ * @Min: 0x00000000
+ * @Max: 0x64646464
+ * @Default: 0x6432190C
+ *
+ * This INI give percentage value of chan_width_weightage to be used as per
+ * peer bandwidth. Self BW is also considered while calculating score. Eg if
+ * self BW is 20 MHZ 10% will be given for all AP irrespective of the AP
+ * capability.
+ *
+ * Indexes are defined in this way.
+ *     0 Index (BITS 0-7): 20 MHz - Def 12%
+ *     1 Index (BITS 8-15): 40 MHz - Def 25%
+ *     2 Index (BITS 16-23): 80 MHz - Def 50%
+ *     3 Index (BITS 24-31): 160 MHz - Def 100%
+ * These percentage values are stored in HEX. For any index max value, can be 64
+ *
+ * Related: chan_width_weightage
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_BW_WEIGHT_PER_IDX CFG_INI_UINT( \
+	"bandwidth_weight_per_index", \
+	0x00000000, \
+	0x64646464, \
+	0x6432190C, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Bandwidth weight per index")
+
+/*
+ * <ini>
+ * nss_weight_per_index - percentage as per NSS
+ * @Min: 0x00000000
+ * @Max: 0x64646464
+ * @Default: 0x6432190C
+ *
+ * This INI give percentage value of nss_weightage to be used as per peer NSS.
+ * Self NSS capability is also considered. Eg if self NSS is 1x1 10% will be
+ * given for all AP irrespective of the AP capability.
+ *
+ * Indexes are defined in this way.
+ *     0 Index (BITS 0-7): 1X1- Def 12%
+ *     1 Index (BITS 8-15): 2X2- Def 25%
+ *     2 Index (BITS 16-23): 3X3- Def 50%
+ *     3 Index (BITS 24-31): 4X4- Def 100%
+ * These percentage values are stored in HEX. For any index max value, can be 64
+ *
+ * Related: nss_weightage
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_NSS_WEIGHT_PER_IDX CFG_INI_UINT( \
+	"nss_weight_per_index", \
+	0x00000000, \
+	0x64646464, \
+	0x6432190C, \
+	CFG_VALUE_OR_DEFAULT, \
+	"NSS weight per index")
+
+/*
+ * <ini>
+ * band_weight_per_index - percentage as per band
+ * @Min: 0x00000000
+ * @Max: 0x64646464
+ * @Default: 0x0000644B
+ *
+ * This INI give percentage value of chan_band_weightage to be used as per band.
+ * If RSSI is greater than rssi_pref_5g_rssi_thresh preference is given for 5Ghz
+ * else, it's given for 2.4Ghz.
+ *
+ * Indexes are defined in this way.
+ *     0 Index (BITS 0-7): 2.4GHz - Def 10%
+ *     1 Index (BITS 8-15): 5GHz - Def 20%
+ *     2 Index (BITS 16-23): Reserved
+ *     3 Index (BITS 24-31): Reserved
+ * These percentage values are stored in HEX. For any index max value, can be 64
+ *
+ * Related: chan_band_weightage, rssi_pref_5g_rssi_thresh
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_BAND_WEIGHT_PER_IDX CFG_INI_UINT( \
+	"band_weight_per_index", \
+	0x00000000, \
+	0x64646464, \
+	0x0000644B, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Band weight per index")
+
+/*
+ * <ini>
+ * num_esp_qbss_slots - number of slots in which the esp/qbss load will
+ * be divided
+ *
+ * @Min: 1
+ * @Max: 15
+ * @Default: 4
+ *
+ * Number of slots in which the esp/qbss load will be divided. Max 15. index 0
+ * is used for 'not_present. Num_slot will equally divide 100. e.g, if
+ * num_slot = 4 slot 1 = 0-25% load, slot 2 = 26-50% load, slot 3 = 51-75% load,
+ * slot 4 = 76-100% load. Remaining unused index can be 0.
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_NUM_ESP_QBSS_SLOTS CFG_INI_UINT( \
+	"num_esp_qbss_slots", \
+	1, \
+	15, \
+	4, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Num ESP QPSS Slots")
+
+/*
+ * <ini>
+ * esp_qbss_score_idx3_to_0 - percentage for  esp/qbss load for slots 0-3
+ * @Min: 0x00000000
+ * @Max: 0x64646464
+ * @Default: 0x19326432
+ *
+ * This INI give percentage value of channel_congestion_weightage to be used as
+ * index in which the load value falls. Index 0 is for percentage when ESP/QBSS
+ * is not present.
+ *
+ * Indexes are defined in this way.
+ *     0 Index (BITS 0-7): when ESP/QBSS is not present
+ *     1 Index (BITS 8-15): SLOT_1
+ *     2 Index (BITS 16-23): SLOT_2
+ *     3 Index (BITS 24-31): SLOT_3
+ * These percentage values are stored in HEX. For any index max value, can be 64
+ *
+ * Related: channel_congestion_weightage, num_esp_qbss_slots
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_ESP_QBSS_SCORE_IDX_3_TO_0 CFG_INI_UINT( \
+	"esp_qbss_score_idx3_to_0", \
+	0x00000000, \
+	0x64646464, \
+	0x19326432, \
+	CFG_VALUE_OR_DEFAULT, \
+	"ESP QPSS Score Index 3 to 0")
+
+/*
+ * <ini>
+ * esp_qbss_score_idx7_to_4 - percentage for  esp/qbss load for slots 4-7
+ * @Min: 0x00000000
+ * @Max: 0x64646464
+ * @Default: 0x0000000A
+ *
+ * This INI give percentage value of channel_congestion_weightage to be used as
+ * index in which the load value falls. Used only if num_esp_qbss_slots is
+ * greater than 3.
+ *
+ * Indexes are defined in this way.
+ *     0 Index (BITS 0-7): SLOT_4
+ *     1 Index (BITS 8-15): SLOT_5
+ *     2 Index (BITS 16-23): SLOT_6
+ *     3 Index (BITS 24-31): SLOT_7
+ * These percentage values are stored in HEX. For any index max value, can be 64
+ *
+ * Related: channel_congestion_weightage, num_esp_qbss_slots
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_ESP_QBSS_SCORE_IDX_7_TO_4 CFG_INI_UINT( \
+	"esp_qbss_score_idx7_to_4", \
+	0x00000000, \
+	0x64646464, \
+	0x0000000A, \
+	CFG_VALUE_OR_DEFAULT, \
+	"ESP QPSS Score Index 7 to 4")
+
+/*
+ * <ini>
+ * esp_qbss_score_idx11_to_8 - percentage for  esp/qbss load for slots 8-11
+ * @Min: 0x00000000
+ * @Max: 0x64646464
+ * @Default: 0x00000000
+ *
+ * This INI give percentage value of channel_congestion_weightage to be used as
+ * index in which the load value falls. Used only if num_esp_qbss_slots is
+ * greater than 7.
+ *
+ * Indexes are defined in this way.
+ *     0 Index (BITS 0-7): SLOT_8
+ *     1 Index (BITS 8-15): SLOT_9
+ *     2 Index (BITS 16-23): SLOT_10
+ *     3 Index (BITS 24-31): SLOT_11
+ * These percentage values are stored in HEX. For any index max value, can be 64
+ *
+ * Related: channel_congestion_weightage, num_esp_qbss_slots
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_ESP_QBSS_SCORE_IDX_11_TO_8 CFG_INI_UINT( \
+	"esp_qbss_score_idx11_to_8", \
+	0x00000000, \
+	0x64646464, \
+	0x00000000, \
+	CFG_VALUE_OR_DEFAULT, \
+	"ESP QPSS Score Index 11 to 8")
+
+/*
+ * <ini>
+ * esp_qbss_score_idx15_to_12 - percentage for	esp/qbss load for slots 12-15
+ * @Min: 0x00000000
+ * @Max: 0x64646464
+ * @Default: 0x00000000
+ *
+ * This INI give percentage value of channel_congestion_weightage to be used as
+ * index in which the load value falls. Used only if num_esp_qbss_slots is
+ * greater than 11.
+ *
+ * Indexes are defined in this way.
+ *     0 Index (BITS 0-7): SLOT_12
+ *     1 Index (BITS 8-15): SLOT_13
+ *     2 Index (BITS 16-23): SLOT_14
+ *     3 Index (BITS 24-31): SLOT_15
+ * These percentage values are stored in HEX. For any index max value, can be 64
+ *
+ * Related: channel_congestion_weightage, num_esp_qbss_slots
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_ESP_QBSS_SCORE_IDX_15_TO_12 CFG_INI_UINT( \
+	"esp_qbss_score_idx15_to_12", \
+	0x00000000, \
+	0x64646464, \
+	0x00000000, \
+	CFG_VALUE_OR_DEFAULT, \
+	"ESP QPSS Score Index 15 to 12")
+
+/*
+ * <ini>
+ * num_oce_wan_slots - number of slots in which the oce wan metrics will
+ * be divided
+ *
+ * @Min: 1
+ * @Max: 15
+ * @Default: 8
+ *
+ * Number of slots in which the oce wan metrics will be divided. Max 15. index 0
+ * is used for not_present. Num_slot will equally divide 100. e.g, if
+ * num_slot = 4 slot 1 = 0-3 DL CAP, slot 2 = 4-7 DL CAP, slot 3 = 8-11 DL CAP,
+ * slot 4 = 12-15 DL CAP. Remaining unused index can be 0.
+ *
+ * Related: oce_wan_weightage
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_NUM_OCE_WAN_SLOTS CFG_INI_UINT( \
+	"num_oce_wan_slots", \
+	1, \
+	15, \
+	15, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Num OCE WAN Slots")
+
+/*
+ * <ini>
+ * oce_wan_score_idx3_to_0 - percentage for OCE WAN metrics score for slots 0-3
+ * @Min: 0x00000000
+ * @Max: 0x64646464
+ * @Default: 0x00000032
+ *
+ * This INI give percentage value of OCE WAN metrics DL CAP, to be used as
+ * index in which the DL CAP value falls. Index 0 is for percentage when
+ * OCE WAN metrics DL CAP is not present.
+ *
+ * Indexes are defined in this way.
+ *     0 Index (BITS 0-7): when OCE WAN metrics DL CAP is not present
+ *     1 Index (BITS 8-15): SLOT_1
+ *     2 Index (BITS 16-23): SLOT_2
+ *     3 Index (BITS 24-31): SLOT_3
+ * These percentage values are stored in HEX. For any index max value, can be 64
+ *
+ * Related: num_oce_wan_slots, oce_wan_weightage
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_OCE_WAN_SCORE_IDX_3_TO_0 CFG_INI_UINT( \
+	"oce_wan_score_idx3_to_0", \
+	0x00000000, \
+	0x64646464, \
+	0x00000032, \
+	CFG_VALUE_OR_DEFAULT, \
+	"OCE WAN Score Index 3 to 0")
+
+/*
+ * <ini>
+ * oce_wan_score_idx7_to_4 - percentage for OCE WAN metrics score for slots 4-7
+ * @Min: 0x00000000
+ * @Max: 0x64646464
+ * @Default: 0x00000000
+ *
+ * This INI give percentage value of OCE WAN metrics DL CAP, to be used as
+ * index in which the DL CAP value falls. Used only if num_oce_wan_slots is
+ * greater than 3.
+ *
+ * Indexes are defined in this way.
+ *     0 Index (BITS 0-7): SLOT_4
+ *     1 Index (BITS 8-15): SLOT_5
+ *     2 Index (BITS 16-23): SLOT_6
+ *     3 Index (BITS 24-31): SLOT_7
+ * These percentage values are stored in HEX. For any index max value, can be 64
+ *
+ * Related: num_oce_wan_slots, oce_wan_weightage
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_OCE_WAN_SCORE_IDX_7_TO_4 CFG_INI_UINT( \
+	"oce_wan_score_idx7_to_4", \
+	0x00000000, \
+	0x64646464, \
+	0x00000000, \
+	CFG_VALUE_OR_DEFAULT, \
+	"OCE WAN Score Index 7 to 4")
+
+/*
+ * <ini>
+ * oce_wan_score_idx11_to_8 - percentage for OCE WAN metrics score for slot 8-11
+ * @Min: 0x00000000
+ * @Max: 0x64646464
+ * @Default: 0x06030000
+ *
+ * This INI give percentage value of OCE WAN metrics DL CAP, to be used as
+ * index in which the DL CAP value falls. Used only if num_oce_wan_slots is
+ * greater than 7.
+ *
+ * Indexes are defined in this way.
+ *     0 Index (BITS 0-7): SLOT_8
+ *     1 Index (BITS 8-15): SLOT_9
+ *     2 Index (BITS 16-23): SLOT_10
+ *     3 Index (BITS 24-31): SLOT_11
+ * These percentage values are stored in HEX. For any index max value, can be 64
+ *
+ * Related: num_oce_wan_slots, oce_wan_weightage
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_OCE_WAN_SCORE_IDX_11_TO_8 CFG_INI_UINT( \
+	"oce_wan_score_idx11_to_8", \
+	0x00000000, \
+	0x64646464, \
+	0x06030000, \
+	CFG_VALUE_OR_DEFAULT, \
+	"OCE WAN Score Index 11 to 8")
+
+/*
+ * <ini>
+ * oce_wan_score_idx15_to_12 - % for OCE WAN metrics score for slot 12-15
+ * @Min: 0x00000000
+ * @Max: 0x64646464
+ * @Default: 0x6432190C
+ *
+ * This INI give percentage value of OCE WAN metrics DL CAP, to be used as
+ * index in which the DL CAP value falls. Used only if num_oce_wan_slots is
+ * greater than 11.
+ *
+ * Indexes are defined in this way.
+ *     0 Index (BITS 0-7): SLOT_12
+ *     1 Index (BITS 8-15): SLOT_13
+ *     2 Index (BITS 16-23): SLOT_14
+ *     3 Index (BITS 24-31): SLOT_15
+ * These percentage values are stored in HEX. For any index max value, can be 64
+ *
+ * Related: num_oce_wan_slots, oce_wan_weightage
+ *
+ * Supported Feature: STA Candidate selection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCORING_OCE_WAN_SCORE_IDX_15_TO_12 CFG_INI_UINT( \
+	"oce_wan_score_idx15_to_12", \
+	0x00000000, \
+	0x64646464, \
+	0x6432190C, \
+	CFG_VALUE_OR_DEFAULT, \
+	"OCE WAN Score Index 15 to 12")
+
+/*
+ * <ini>
+ * enable_scoring_for_roam - enable/disable scoring logic in FW for candidate
+ * selection during roaming
+ *
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable scoring logic in FW for candidate
+ * selection during roaming.
+ *
+ * Supported Feature: STA Candidate selection by FW during roaming based on
+ * scoring logic.
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_SCORING_FOR_ROAM CFG_INI_BOOL( \
+		"enable_scoring_for_roam", \
+		1, \
+		"Enable Scoring for Roam")
+
+#define CFG_SCORING_ALL \
+	CFG(CFG_SCORING_RSSI_WEIGHTAGE) \
+	CFG(CFG_SCORING_HT_CAPS_WEIGHTAGE) \
+	CFG(CFG_SCORING_VHT_CAPS_WEIGHTAGE) \
+	CFG(CFG_SCORING_HE_CAPS_WEIGHTAGE) \
+	CFG(CFG_SCORING_CHAN_WIDTH_WEIGHTAGE) \
+	CFG(CFG_SCORING_CHAN_BAND_WEIGHTAGE) \
+	CFG(CFG_SCORING_NSS_WEIGHTAGE) \
+	CFG(CFG_SCORING_BEAMFORM_CAP_WEIGHTAGE) \
+	CFG(CFG_SCORING_PCL_WEIGHTAGE) \
+	CFG(CFG_SCORING_CHAN_CONGESTION_WEIGHTAGE) \
+	CFG(CFG_SCORING_OCE_WAN_WEIGHTAGE) \
+	CFG(CFG_SCORING_BEST_RSSI_THRESHOLD) \
+	CFG(CFG_SCORING_GOOD_RSSI_THRESHOLD) \
+	CFG(CFG_SCORING_BAD_RSSI_THRESHOLD) \
+	CFG(CFG_SCORING_GOOD_RSSI_PERCENT) \
+	CFG(CFG_SCORING_BAD_RSSI_PERCENT) \
+	CFG(CFG_SCORING_GOOD_RSSI_BUCKET_SIZE) \
+	CFG(CFG_SCORING_BAD_RSSI_BUCKET_SIZE) \
+	CFG(CFG_SCORING_RSSI_PREF_5G_THRESHOLD) \
+	CFG(CFG_SCORING_BW_WEIGHT_PER_IDX) \
+	CFG(CFG_SCORING_NSS_WEIGHT_PER_IDX) \
+	CFG(CFG_SCORING_BAND_WEIGHT_PER_IDX) \
+	CFG(CFG_SCORING_NUM_ESP_QBSS_SLOTS) \
+	CFG(CFG_SCORING_ESP_QBSS_SCORE_IDX_3_TO_0) \
+	CFG(CFG_SCORING_ESP_QBSS_SCORE_IDX_7_TO_4) \
+	CFG(CFG_SCORING_ESP_QBSS_SCORE_IDX_11_TO_8) \
+	CFG(CFG_SCORING_ESP_QBSS_SCORE_IDX_15_TO_12) \
+	CFG(CFG_SCORING_NUM_OCE_WAN_SLOTS) \
+	CFG(CFG_SCORING_OCE_WAN_SCORE_IDX_3_TO_0) \
+	CFG(CFG_SCORING_OCE_WAN_SCORE_IDX_7_TO_4) \
+	CFG(CFG_SCORING_OCE_WAN_SCORE_IDX_11_TO_8) \
+	CFG(CFG_SCORING_OCE_WAN_SCORE_IDX_15_TO_12) \
+	CFG(CFG_ENABLE_SCORING_FOR_ROAM)
+
+#endif /* __CFG_MLME_SCORING_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_sta.h b/components/mlme/dispatcher/inc/cfg_mlme_sta.h
new file mode 100644
index 0000000..2fc1d1b
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_sta.h
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2012-2018, 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 configuration definitions for MLME STA.
+ */
+
+#ifndef CFG_MLME_STA_H__
+#define CFG_MLME_STA_H__
+
+#include "wlan_mlme_public_struct.h"
+
+/*
+ * <ini>
+ * gStaKeepAlivePeriod - Sends NULL frame to AP periodically in
+ * seconds to notify STA's existence
+ * @Min: 0
+ * @Max: 1000
+ * @Default: 60
+ *
+ * This ini is used to send default NULL frame to AP
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD CFG_INI_UINT( \
+	"gStaKeepAlivePeriod", \
+	0, \
+	1000, \
+	60, \
+	CFG_VALUE_OR_DEFAULT, \
+	"send default NULL frame to AP")
+
+/*
+ * <ini>
+ * tgt_gtx_usr_cfg - target gtx user config
+ * @Min: 0
+ * @Max: 32
+ * @Default: 32
+ *
+ * This ini is used to set target gtx user config.
+ *
+ * Related: None
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_TGT_GTX_USR_CFG CFG_INI_UINT( \
+	"tgt_gtx_usr_cfg", \
+	0, \
+	32, \
+	32, \
+	CFG_VALUE_OR_DEFAULT, \
+	"target gtx user config")
+
+/*
+ * <ini>
+ * pmkidModes - Enable PMKID modes
+ * This INI is used to enable PMKID feature options
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMKID_MODES CFG_INI_UINT( \
+	"pmkidModes", \
+	0, \
+	3, \
+	3, \
+	CFG_VALUE_OR_DEFAULT, \
+	"PMKID feature options")
+
+/*
+ * <ini>
+ * gIgnorePeerErpInfo - Ignore peer information
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to ignore default peer info
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IGNORE_PEER_ERP_INFO CFG_INI_BOOL( \
+	"gIgnorePeerErpInfo", \
+	0, \
+	"ignore default peer info")
+
+/*
+ * <ini>
+ * gStaPrefer80MHzOver160MHz - set sta preference to connect in 80HZ/160HZ
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set sta preference to connect in 80HZ/160HZ
+ *
+ * 0 - Connects in 160MHz 1x1 when AP is 160MHz 2x2
+ * 1 - Connects in 80MHz 2x2 when AP is 160MHz 2x2
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_STA_PREFER_80MHZ_OVER_160MHZ CFG_INI_BOOL( \
+	"gStaPrefer80MHzOver160MHz", \
+	1, \
+	"Sta preference to connect in 80HZ/160HZ")
+
+/*
+ * <ini>
+ * gEnable5gEBT - Enables/disables 5G early beacon termination. When enabled
+ *                 terminate the reception of beacon if the TIM element is
+ *                 clear for the power saving
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set default 5G early beacon termination
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PPS_ENABLE_5G_EBT CFG_INI_BOOL( \
+	"gEnable5gEBT", \
+	1, \
+	"5G early beacon termination")
+
+/*
+ * <ini>
+ * gSendDeauthBeforeCon - Send deauth before connection or not
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set whether send deauth before connection or
+ * not. If last disconnection was due to HB failure and we reconnect
+ * to same AP next time, send deauth before starting connection.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_DEAUTH_BEFORE_CONNECTION CFG_INI_BOOL( \
+	"gSendDeauthBeforeCon", \
+	0, \
+	"send deauth before connection")
+
+/*
+ * <ini>
+ * CFG_DOT11P_MODE - 802.11p mode
+ * @Min: CFG_11P_DISABLED
+ * @Max: CFG_11P_CONCURRENT
+ * @Default: CFG_11P_DISABLED
+ *
+ * This ini used to set 802.11p mode.
+ *
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_DOT11P_MODE CFG_INI_UINT( \
+	"gDot11PMode", \
+	CFG_11P_DISABLED, \
+	CFG_11P_CONCURRENT, \
+	CFG_11P_DISABLED, \
+	CFG_VALUE_OR_DEFAULT, \
+	"802.11p mode")
+
+/*
+ * <ini>
+ * gEnable_go_cts2self_for_sta - Indicate firmware to stop NOA and
+ * start using cts2self
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * When gEnable_go_cts2self_for_sta is enabled then if a legacy
+ * client connects to P2P GO, Host will send a WMI VDEV command
+ * to FW to stop using NOA for P2P GO
+ * and start using CTS2SELF.
+ *
+ *
+ * Supported Feature: P2P
+ *
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_GO_CTS2SELF_FOR_STA CFG_INI_BOOL( \
+	"gEnable_go_cts2self_for_sta", \
+	0, \
+	"firmware to stop NOA and start using cts2self")
+
+/*
+ * <ini>
+ * g_qcn_ie_support - QCN IE support
+ * @Min: 0 (disabled)
+ * @Max: 1 (enabled)
+ * @Default: 1 (enabled)
+ *
+ * This config item is used to support QCN IE in probe/assoc/reassoc request
+ * for STA mode. QCN IE support is not added for SAP mode.
+ *
+ * Related: N/A
+ *
+ * Supported Feature: N/A
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QCN_IE_SUPPORT CFG_INI_BOOL( \
+	"g_qcn_ie_support", \
+	1, \
+	"QCN IE support")
+
+/*
+ * <ini>
+ * g_fils_max_chan_guard_time - Set maximum channel guard time(ms)
+ * @Min: 0
+ * @Max: 10
+ * @Default: 0
+ *
+ * This ini is used to set maximum channel guard time in milliseconds.
+ *
+ * Related: None
+ *
+ * Supported Feature: FILS
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_FILS_MAX_CHAN_GUARD_TIME CFG_INI_UINT( \
+	"g_fils_max_chan_guard_time", \
+	0, \
+	10, \
+	0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Set maximum channel guard time")
+
+/*
+ * <ini>
+ * force_rsne_override - force rsnie override from user
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable test mode to force rsne override used in
+ * security enhancement test cases to pass the RSNIE sent by user in
+ * assoc request.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: internal
+ *
+ * </ini>
+ */
+#define CFG_FORCE_RSNE_OVERRIDE CFG_INI_BOOL( \
+	"force_rsne_override", \
+	0, \
+	"Set obss active dwelltime")
+
+/*
+ * <ini>
+ * SingleTIDRC - Set replay counter for all TID's
+ * @Min: 0       Separate replay counter for all TID
+ * @Max: 1       Single replay counter for all TID
+ * @Default: 1
+ *
+ * This ini is used to set replay counter for all TID's
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_SINGLE_TID_RC CFG_INI_BOOL( \
+	"SingleTIDRC", \
+	1, \
+	"replay counter for all TID")
+
+/*
+ * wait_cnf_timeout - Wait assoc cnf timeout
+ * @Min: 10
+ * @Max: 3000
+ * @Default: 1000
+ *
+ * This is internal configure for waiting assoc cnf timeout
+ *
+ * Related: None
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_WT_CNF_TIMEOUT CFG_UINT( \
+	"wait_cnf_timeout", \
+	10, \
+	3000, \
+	1000, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Wait confirm timeout")
+
+/*
+ * current_rssi - current rssi
+ * @Min: 0
+ * @Max: 127
+ * @Default: 0
+ *
+ * This is internal configure for current rssi
+ *
+ * Related: None
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_CURRENT_RSSI CFG_UINT( \
+	"current_rssi", \
+	0, \
+	127, \
+	0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Current RSSI")
+
+#define CFG_STA_ALL \
+	CFG(CFG_INFRA_STA_KEEP_ALIVE_PERIOD) \
+	CFG(CFG_TGT_GTX_USR_CFG) \
+	CFG(CFG_PMKID_MODES) \
+	CFG(CFG_IGNORE_PEER_ERP_INFO) \
+	CFG(CFG_STA_PREFER_80MHZ_OVER_160MHZ) \
+	CFG(CFG_PPS_ENABLE_5G_EBT) \
+	CFG(CFG_ENABLE_DEAUTH_BEFORE_CONNECTION) \
+	CFG(CFG_DOT11P_MODE) \
+	CFG(CFG_ENABLE_GO_CTS2SELF_FOR_STA) \
+	CFG(CFG_QCN_IE_SUPPORT) \
+	CFG(CFG_FILS_MAX_CHAN_GUARD_TIME) \
+	CFG(CFG_FORCE_RSNE_OVERRIDE) \
+	CFG(CFG_SINGLE_TID_RC) \
+	CFG(CFG_WT_CNF_TIMEOUT) \
+	CFG(CFG_CURRENT_RSSI)
+
+#endif /* CFG_MLME_STA_H__ */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_threshold.h b/components/mlme/dispatcher/inc/cfg_mlme_threshold.h
new file mode 100644
index 0000000..8134c3f
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_threshold.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_THRESHOLD_H
+#define __CFG_MLME_THRESHOLD_H
+
+#include "wni_cfg.h"
+
+/*
+ * <ini>
+ * RTSThreshold - Will provide RTSThreshold
+ * @Min: 0
+ * @Max: 1048576
+ * @Default: 2347
+ *
+ * This ini is used to set default RTSThreshold
+ * If minimum value 0 is selectd then it will use always RTS
+ * max is the max frame size
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_RTS_THRESHOLD CFG_INI_UINT( \
+		"RTSThreshold", \
+		0, \
+		1048576, \
+		2347, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Default RTS Threshold")
+
+/*
+ * <ini>
+ * gFragmentationThreshold - It will set fragmentation threshold
+ * @Min: 256
+ * @Max: 8000
+ * @Default: 8000
+ *
+ * This ini is used to indicate default fragmentation threshold
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_FRAG_THRESHOLD CFG_INI_UINT( \
+		"gFragmentationThreshold", \
+		256, \
+		8000, \
+		8000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Default Fragmentation Threshold")
+
+#define CFG_THRESHOLD_ALL \
+	CFG(CFG_RTS_THRESHOLD) \
+	CFG(CFG_FRAG_THRESHOLD)
+
+#endif /* __CFG_MLME_MAIN_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_timeout.h b/components/mlme/dispatcher/inc/cfg_mlme_timeout.h
new file mode 100644
index 0000000..7caed90
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_timeout.h
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2011-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_TIMEOUT_H
+#define __CFG_MLME_TIMEOUT_H
+
+/*
+ * <ini>
+ * join_failure_timeout - Join failure timeout value
+ * @Min: 0
+ * @Max: 65535
+ * @Default: 3000
+ *
+ * This cfg is used to configure the join failure timeout.
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_JOIN_FAILURE_TIMEOUT CFG_INI_UINT( \
+		"join_failure_timeout", \
+		0, \
+		65535, \
+		3000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Join failure timeout")
+
+/*
+ * <ini>
+ * auth_failure_timeout - Auth failure timeout value
+ * @Min: 0
+ * @Max: 65535
+ * @Default: 1000
+ *
+ * This cfg is used to configure the auth failure timeout.
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_AUTH_FAILURE_TIMEOUT CFG_INI_UINT( \
+		"auth_failure_timeout", \
+		500, \
+		5000, \
+		1000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"auth failure timeout")
+
+/*
+ * <ini>
+ * auth_rsp_timeout - Auth response timeout value
+ * @Min: 0
+ * @Max: 65535
+ * @Default: 1000
+ *
+ * This cfg is used to configure the auth response timeout.
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_AUTH_RSP_TIMEOUT CFG_INI_UINT( \
+		"auth_rsp_timeout", \
+		0, \
+		65535, \
+		1000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"auth rsp timeout")
+
+/*
+ * <ini>
+ * assoc_failure_timeout - Assoc failure timeout value
+ * @Min: 0
+ * @Max: 65535
+ * @Default: 2000
+ *
+ * This cfg is used to configure the assoc failure timeout.
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ASSOC_FAILURE_TIMEOUT CFG_INI_UINT( \
+		"assoc_failure_timeout", \
+		0, \
+		65535, \
+		2000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"assoc failure timeout")
+
+/*
+ * <ini>
+ * reassoc_failure_timeout - Re-Assoc failure timeout value
+ * @Min: 0
+ * @Max: 65535
+ * @Default: 1000
+ *
+ * This cfg is used to configure the re-assoc failure timeout.
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_REASSOC_FAILURE_TIMEOUT CFG_INI_UINT( \
+		"reassoc_failure_timeout", \
+		0, \
+		65535, \
+		1000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"reassoc failure timeout")
+
+/*
+ * <ini>
+ * probe_after_hb_fail_timeout - Probe after HB failure timeout value
+ * @Min: 10
+ * @Max: 10000
+ * @Default: 70
+ *
+ * This cfg is used to configure the Probe after HB failure timeout.
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_PROBE_AFTER_HB_FAIL_TIMEOUT CFG_INI_UINT( \
+		"probe_after_hb_fail_timeout", \
+		10, \
+		10000, \
+		70, \
+		CFG_VALUE_OR_DEFAULT, \
+		"probe after HB fail timeout")
+
+/*
+ * <ini>
+ * olbc_detect_timeout - olbc detect timeout value
+ * @Min: 1000
+ * @Max: 30000
+ * @Default: 10000
+ *
+ * This cfg is used to configure the olbc detect timeout.
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_OLBC_DETECT_TIMEOUT CFG_INI_UINT( \
+		"olbc_detect_timeout", \
+		1000, \
+		30000, \
+		10000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"OLBC detect timeout")
+
+/*
+ * <ini>
+ * addts_rsp_timeout - addts response timeout value
+ * @Min: 0
+ * @Max: 65535
+ * @Default: 1000
+ *
+ * This cfg is used to configure the addts response timeout.
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ADDTS_RSP_TIMEOUT CFG_INI_UINT( \
+		"addts_rsp_timeout", \
+		0, \
+		65535, \
+		1000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"ADDTS RSP timeout")
+
+/*
+ * <ini>
+ * gHeartbeat24 - Heart beat threashold value
+ * @Min: 0
+ * @Max: 65535
+ * @Default: 40
+ *
+ * This cfg is used to configure the Heart beat threashold.
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_HEART_BEAT_THRESHOLD CFG_INI_UINT( \
+		"gHeartbeat24", \
+		0, \
+		65535, \
+		40, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Heart beat threashold")
+
+/*
+ * <ini>
+ * gApKeepAlivePeriod - AP keep alive period
+ * @Min: 1
+ * @Max: 65535
+ * @Default: 20
+ *
+ * This ini is used to set keep alive period of AP
+ *
+ * Related: None.
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_AP_KEEP_ALIVE_TIMEOUT CFG_INI_UINT( \
+		"gApKeepAlivePeriod", \
+		1, \
+		65535, \
+		20, \
+		CFG_VALUE_OR_DEFAULT, \
+		"AP keep alive timeout")
+
+/*
+ * <ini>
+ * gApLinkMonitorPeriod - AP keep alive period
+ * @Min: 3
+ * @Max: 50
+ * @Default: 10
+ *
+ * This ini is used to configure AP link monitor timeout value
+ *
+ * Related: None.
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_AP_LINK_MONITOR_TIMEOUT CFG_INI_UINT( \
+		"gApLinkMonitorPeriod", \
+		3, \
+		50, \
+		10, \
+		CFG_VALUE_OR_DEFAULT, \
+		"AP link monitor timeout")
+
+/*
+ * <ini>
+ * gDataInactivityTimeout - Data activity timeout for non wow mode.
+ * @Min: 1
+ * @Max: 255
+ * @Default: 200
+ *
+ * This ini is used to set data inactivity timeout in non wow mode.
+ *
+ * Supported Feature: inactivity timeout in non wow mode
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PS_DATA_INACTIVITY_TIMEOUT CFG_INI_UINT( \
+		"gDataInactivityTimeout", \
+		1, \
+		255, \
+		200, \
+		CFG_VALUE_OR_DEFAULT, \
+		"PS data inactivity timeout")
+
+#define CFG_TIMEOUT_ALL \
+	CFG(CFG_JOIN_FAILURE_TIMEOUT) \
+	CFG(CFG_AUTH_FAILURE_TIMEOUT) \
+	CFG(CFG_AUTH_RSP_TIMEOUT) \
+	CFG(CFG_ASSOC_FAILURE_TIMEOUT) \
+	CFG(CFG_REASSOC_FAILURE_TIMEOUT) \
+	CFG(CFG_PROBE_AFTER_HB_FAIL_TIMEOUT) \
+	CFG(CFG_OLBC_DETECT_TIMEOUT) \
+	CFG(CFG_ADDTS_RSP_TIMEOUT) \
+	CFG(CFG_HEART_BEAT_THRESHOLD) \
+	CFG(CFG_AP_KEEP_ALIVE_TIMEOUT) \
+	CFG(CFG_AP_LINK_MONITOR_TIMEOUT) \
+	CFG(CFG_PS_DATA_INACTIVITY_TIMEOUT)
+
+#endif /* __CFG_MLME_TIMEOUT_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_vht_caps.h b/components/mlme/dispatcher/inc/cfg_mlme_vht_caps.h
new file mode 100644
index 0000000..dcc2540
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_vht_caps.h
@@ -0,0 +1,594 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_VHT_CAPS_H
+#define __CFG_MLME_VHT_CAPS_H
+
+#define CFG_VHT_SUPP_CHAN_WIDTH CFG_UINT( \
+		"supp_chan_width", \
+		0, \
+		2, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT SUPPORTED CHAN WIDTH SET")
+
+/*
+ * <ini>
+ * gTxBFCsnValue - ini to set VHT/HE STS Caps field
+ * @Min: 0
+ * @Max: 7
+ * @Default: 7
+ *
+ * This ini is used to configure the STS capability shown in AC/AX mode
+ * MGMT frame IE, the final STS field shown in VHT/HE IE will be calculated
+ * by MIN of (INI set, target report value). Only if gTxBFEnable is enabled
+ * and SU/MU BEAMFORMEE Caps is shown, then STS Caps make sense.
+ *
+ * Related: gTxBFEnable.
+ *
+ * Supported Feature: STA/SAP
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_VHT_BEAMFORMEE_ANT_SUPP CFG_INI_UINT( \
+		"txBFCsnValue", \
+		0, \
+		7, \
+		7, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT BEAMFORMEE ANTENNA SUPPORTED CAP")
+
+/*
+ * <ini>
+ * gEnableTxSUBeamformer - Enables TX Su beam former
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_TX_SU_BEAM_FORMER CFG_INI_BOOL( \
+		"gEnableTxSUBeamformer", \
+		0, \
+		"vht tx su beam former")
+
+#define CFG_VHT_NUM_SOUNDING_DIMENSIONS CFG_UINT( \
+		"num_soundingdim", \
+		0, \
+		3, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT NUMBER OF SOUNDING DIMENSIONS")
+
+#define CFG_VHT_HTC_VHTC CFG_BOOL( \
+		"htc_vhtc", \
+		0, \
+		"VHT HTC VHTC")
+
+#define CFG_VHT_LINK_ADAPTATION_CAP CFG_UINT( \
+		"link_adap_cap", \
+		0, \
+		3, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT LINK ADAPTATION CAP")
+
+#define CFG_VHT_RX_ANT_PATTERN CFG_BOOL( \
+		"rx_antpattern", \
+		1, \
+		"VHT RX ANTENNA PATTERN CAP")
+
+#define CFG_VHT_TX_ANT_PATTERN CFG_BOOL( \
+		"tx_antpattern", \
+		1, \
+		"VHT TX ANTENNA PATTERN CAP")
+
+#define CFG_VHT_RX_SUPP_DATA_RATE CFG_UINT( \
+		"rx_supp_data_rate", \
+		0, \
+		780, \
+		780, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT RX SUPP DATA RATE")
+
+#define CFG_VHT_TX_SUPP_DATA_RATE CFG_UINT( \
+		"tx_supp_data_rate", \
+		0, \
+		780, \
+		780, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT TX SUPP DATA RATE")
+
+/*
+ * <ini>
+ * gTxBFEnable - Enables SU beamformee caps
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_SU_BEAMFORMEE_CAP CFG_INI_BOOL( \
+		"gTxBFEnable", \
+		1, \
+		"VHT SU BEAMFORMEE CAPABILITY")
+
+/*
+ * <ini>
+ * gEnableTxBFin20MHz - Enables TXBF in 20mhz
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_TXBF_IN_20MHZ CFG_INI_BOOL( \
+		"gEnableTxBFin20MHz", \
+		0, \
+		"VHT ENABLE TXBF 20MHZ")
+
+#define CFG_VHT_MU_BEAMFORMER_CAP CFG_BOOL( \
+		"mu_bformer", \
+		0, \
+		"VHT MU BEAMFORMER CAP")
+
+#define CFG_VHT_TXOP_PS CFG_BOOL( \
+		"txop_ps", \
+		0, \
+		"VHT TXOP PS")
+
+/*
+ * <ini>
+ * gVhtChannelWidth - Channel width capability for 11ac
+ * @Min: 0
+ * @Max: 4
+ * @Default: 3
+ *
+ * This ini is  used to set channel width capability for 11AC.
+ * eHT_CHANNEL_WIDTH_20MHZ = 0,
+ * eHT_CHANNEL_WIDTH_40MHZ = 1,
+ * eHT_CHANNEL_WIDTH_80MHZ = 2,
+ * eHT_CHANNEL_WIDTH_160MHZ = 3,
+ * eHT_CHANNEL_WIDTH_80P80MHZ = 4,
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_CHANNEL_WIDTH CFG_INI_UINT( \
+		"gVhtChannelWidth", \
+		0, \
+		4, \
+		2, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Channel width capability for 11ac")
+
+/*
+ * <ini>
+ * gVhtRxMCS - VHT Rx MCS capability for 1x1 mode
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * This ini is  used to set VHT Rx MCS capability for 1x1 mode.
+ * 0, MCS0-7
+ * 1, MCS0-8
+ * 2, MCS0-9
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_RX_MCS_8_9 CFG_INI_UINT( \
+		"gVhtRxMCS", \
+		0, \
+		2, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT Rx MCS")
+
+/*
+ * <ini>
+ * gVhtTxMCS - VHT Tx MCS capability for 1x1 mode
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * This ini is  used to set VHT Tx MCS capability for 1x1 mode.
+ * 0, MCS0-7
+ * 1, MCS0-8
+ * 2, MCS0-9
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_TX_MCS_8_9 CFG_INI_UINT( \
+		"gVhtTxMCS", \
+		0, \
+		2, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT Tx MCS")
+
+/*
+ * <ini>
+ * gVhtRxMCS2x2 - VHT Rx MCS capability for 2x2 mode
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * This ini is  used to set VHT Rx MCS capability for 2x2 mode.
+ * 0, MCS0-7
+ * 1, MCS0-8
+ * 2, MCS0-9
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_RX_MCS2x2_8_9 CFG_INI_UINT( \
+		"gVhtRxMCS2x2", \
+		0, \
+		2, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT Rx MCS 2x2")
+
+/*
+ * <ini>
+ * gVhtTxMCS2x2 - VHT Tx MCS capability for 2x2 mode
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * This ini is  used to set VHT Tx MCS capability for 2x2 mode.
+ * 0, MCS0-7
+ * 1, MCS0-8
+ * 2, MCS0-9
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_TX_MCS2x2_8_9 CFG_INI_UINT( \
+		"gVhtTxMCS2x2", \
+		0, \
+		2, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT Tx MCS 2x2")
+
+/*
+ * <ini>
+ * enable_vht20_mcs9 - Enables VHT MCS9 in 20M BW operation
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_VHT20_MCS9 CFG_INI_BOOL( \
+		"enable_vht20_mcs9", \
+		1, \
+		"Enables VHT MCS9 in 20M BW")
+
+/*
+ * <ini>
+ * gEnable2x2 - Enables/disables VHT Tx/Rx MCS values for 2x2
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini disables/enables 2x2 mode. If this is zero then DUT operates as 1x1
+ *
+ * 0, Disable
+ * 1, Enable
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_2x2_CAP_FEATURE CFG_INI_BOOL( \
+		"gEnable2x2", \
+		0, \
+		"VHT Enable 2x2")
+
+/*
+ * <ini>
+ * gEnableMuBformee - Enables/disables multi-user (MU) beam formee capability
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini enables/disables multi-user (MU) beam formee
+ * capability
+ *
+ * Change MU Bformee only when  gTxBFEnable is enabled.
+ * When gTxBFEnable and gEnableMuBformee are set, MU beam formee capability is
+ * enabled.
+ * Related:  gTxBFEnable
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE CFG_INI_BOOL( \
+		"gEnableMuBformee", \
+		0, \
+		"VHT Enable MU Beamformee")
+
+/*
+ * <ini>
+ * gEnablePAID - Enables VHT paid feature
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_PAID_FEATURE CFG_INI_BOOL( \
+		"gEnablePAID", \
+		0, \
+		"VHT Enable PAID")
+
+/*
+ * <ini>
+ * gEnableGID - Enables VHT gid feature
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_GID_FEATURE CFG_INI_BOOL( \
+		"gEnableGID", \
+		0, \
+		"VHT Enable GID")
+
+/*
+ * <ini>
+ * gEnableVhtFor24GHzBand - Enable VHT for 2.4GHZ in SAP mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_VHT_FOR_24GHZ CFG_INI_BOOL( \
+		"gEnableVhtFor24GHzBand", \
+		0, \
+		"VHT Enable for 24GHz")
+
+/*
+ * gEnableVendorVhtFor24GHzBand:Parameter to control VHT support
+ * based on vendor ie in 2.4 GHz band
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This parameter will enable SAP to read VHT capability in vendor ie in Assoc
+ * Req and send VHT caps in Resp to establish connection in VHT Mode.
+ * Supported Feature: SAP
+ *
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_VENDOR_VHT_FOR_24GHZ CFG_INI_BOOL( \
+		"gEnableVendorVhtFor24GHzBand", \
+		1, \
+		"VHT Enable Vendor for 24GHz")
+
+/*
+ * <ini>
+ * gVhtAmpduLenExponent - maximum receive AMPDU size configuration
+ * @Min: 0
+ * @Max: 7
+ * @Default: 3
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_AMPDU_LEN_EXPONENT CFG_INI_UINT( \
+		"gVhtAmpduLenExponent", \
+		0, \
+		7, \
+		3, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT AMPDU Len in Exponent")
+
+/*
+ * <ini>
+ * gVhtMpduLen - VHT MPDU length
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_MPDU_LEN CFG_INI_UINT( \
+		"gVhtMpduLen", \
+		0, \
+		2, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"VHT MPDU Length")
+
+/*
+ * <ini>
+ * gEnableTxBFeeSAP - Enable / Disable Tx beamformee in SAP mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AC
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_VHT_ENABLE_TXBF_SAP_MODE CFG_INI_BOOL( \
+			"gEnableTxBFeeSAP", \
+			0, \
+			"Enable tx bf sap mode")
+
+/*
+ * <ini>
+ * enable_subfee_vendor_vhtie - ini to enable/disable SU Bformee in vendor VHTIE
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable SU Bformee in vendor vht ie if gTxBFEnable
+ * is enabled. if gTxBFEnable is 0 this will not have any effect.
+ *
+ * Related: gTxBFEnable.
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_SUBFEE_IN_VENDOR_VHTIE CFG_INI_BOOL( \
+			"enable_subfee_vendor_vhtie", \
+			0, \
+			"Enable subfee in vendor vht ie")
+
+#define CFG_VHT_CAPS_ALL \
+	CFG(CFG_VHT_SUPP_CHAN_WIDTH) \
+	CFG(CFG_VHT_SU_BEAMFORMEE_CAP) \
+	CFG(CFG_VHT_BEAMFORMEE_ANT_SUPP) \
+	CFG(CFG_VHT_ENABLE_TX_SU_BEAM_FORMER) \
+	CFG(CFG_VHT_NUM_SOUNDING_DIMENSIONS) \
+	CFG(CFG_VHT_MU_BEAMFORMER_CAP) \
+	CFG(CFG_VHT_TXOP_PS) \
+	CFG(CFG_VHT_HTC_VHTC) \
+	CFG(CFG_VHT_LINK_ADAPTATION_CAP) \
+	CFG(CFG_VHT_RX_ANT_PATTERN) \
+	CFG(CFG_VHT_TX_ANT_PATTERN) \
+	CFG(CFG_VHT_RX_SUPP_DATA_RATE) \
+	CFG(CFG_VHT_TX_SUPP_DATA_RATE) \
+	CFG(CFG_VHT_ENABLE_TXBF_IN_20MHZ) \
+	CFG(CFG_VHT_CHANNEL_WIDTH) \
+	CFG(CFG_VHT_ENABLE_RX_MCS_8_9) \
+	CFG(CFG_VHT_ENABLE_TX_MCS_8_9) \
+	CFG(CFG_VHT_ENABLE_RX_MCS2x2_8_9) \
+	CFG(CFG_VHT_ENABLE_TX_MCS2x2_8_9) \
+	CFG(CFG_ENABLE_VHT20_MCS9) \
+	CFG(CFG_VHT_ENABLE_2x2_CAP_FEATURE) \
+	CFG(CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE) \
+	CFG(CFG_VHT_ENABLE_PAID_FEATURE) \
+	CFG(CFG_VHT_ENABLE_GID_FEATURE) \
+	CFG(CFG_ENABLE_VHT_FOR_24GHZ) \
+	CFG(CFG_ENABLE_VENDOR_VHT_FOR_24GHZ) \
+	CFG(CFG_VHT_AMPDU_LEN_EXPONENT) \
+	CFG(CFG_VHT_MPDU_LEN) \
+	CFG(CFG_VHT_ENABLE_TXBF_SAP_MODE) \
+	CFG(CFG_ENABLE_SUBFEE_IN_VENDOR_VHTIE)
+
+#endif /* __CFG_MLME_VHT_CAPS_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_wep_params.h b/components/mlme/dispatcher/inc/cfg_mlme_wep_params.h
new file mode 100644
index 0000000..ddd5f93
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_wep_params.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011-2018 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 centralized definitions of WEP parameters related
+ * converged configuration.
+ */
+
+#ifndef __CFG_MLME_WEP_PARAMS_H
+#define __CFG_MLME_WEP_PARAMS_H
+
+#define CFG_WEP_DEFAULT_KEYID CFG_UINT( \
+			"wep_default_key_id", \
+			0, \
+			3, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"wep default key id")
+
+#define CFG_SHARED_KEY_AUTH_ENABLE CFG_BOOL( \
+			"shared_key_auth", \
+			1, \
+			"shared key authentication")
+
+#define CFG_OPEN_SYSTEM_AUTH_ENABLE CFG_BOOL( \
+			"open_system_auth", \
+			1, \
+			"Open system authentication")
+
+#define CFG_AUTHENTICATION_TYPE CFG_UINT( \
+			"auth_type", \
+			0, \
+			3, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"authentication type")
+
+#define CFG_PRIVACY_ENABLED CFG_BOOL( \
+			"privacy_enabled", \
+			0, \
+			"wep privacy")
+
+#define CFG_WEP_PARAMS_ALL \
+	CFG(CFG_WEP_DEFAULT_KEYID) \
+	CFG(CFG_SHARED_KEY_AUTH_ENABLE) \
+	CFG(CFG_OPEN_SYSTEM_AUTH_ENABLE) \
+	CFG(CFG_AUTHENTICATION_TYPE) \
+	CFG(CFG_PRIVACY_ENABLED)
+
+#endif /* __CFG_MLME_WEP_PARAMS_H */
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_wps_params.h b/components/mlme/dispatcher/inc/cfg_mlme_wps_params.h
new file mode 100644
index 0000000..66fa6ef
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_mlme_wps_params.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __CFG_MLME_WPS_PARAMS_H
+#define __CFG_MLME_WPS_PARAMS_H
+
+#define CFG_WPS_ENABLE CFG_UINT( \
+		"enable_wps", \
+		0, \
+		255, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"enable wps")
+
+#define CFG_WPS_STATE CFG_UINT( \
+		"wps_state", \
+		0, \
+		255, \
+		1, \
+		CFG_VALUE_OR_DEFAULT, \
+		"wps_state")
+
+#define CFG_WPS_VERSION CFG_UINT( \
+		"wps_version", \
+		0, \
+		255, \
+		16, \
+		CFG_VALUE_OR_DEFAULT, \
+		"wps version")
+
+#define CFG_WPS_CFG_METHOD CFG_UINT( \
+			"wps_cfg_method", \
+			0, \
+			4294967295, \
+			8, \
+			CFG_VALUE_OR_DEFAULT, \
+			"wps cfg method")
+
+#define CFG_WPS_PRIMARY_DEVICE_CATEGORY CFG_UINT( \
+			"wps_primary_device_category", \
+			0, \
+			65535, \
+			1, \
+			CFG_VALUE_OR_DEFAULT, \
+			"wps primary device category")
+
+#define CFG_WPS_PIMARY_DEVICE_OUI CFG_UINT( \
+			"wps_primary_device_oui", \
+			0, \
+			4294967295, \
+			5304836, \
+			CFG_VALUE_OR_DEFAULT, \
+			"wps primary device oui")
+
+#define CFG_WPS_DEVICE_SUB_CATEGORY CFG_UINT( \
+				"wps_device_sub_category", \
+				0, \
+				65535, \
+				1, \
+				CFG_VALUE_OR_DEFAULT, \
+				"wps device sub category")
+
+#define CFG_WPS_DEVICE_PASSWORD_ID CFG_UINT( \
+				"wps_device_password_id", \
+				0, \
+				4294967295, \
+				0, \
+				CFG_VALUE_OR_DEFAULT, \
+				"wps device password id")
+
+#define CFG_WPS_ALL \
+	CFG(CFG_WPS_ENABLE) \
+	CFG(CFG_WPS_STATE) \
+	CFG(CFG_WPS_VERSION) \
+	CFG(CFG_WPS_CFG_METHOD) \
+	CFG(CFG_WPS_PRIMARY_DEVICE_CATEGORY) \
+	CFG(CFG_WPS_PIMARY_DEVICE_OUI) \
+	CFG(CFG_WPS_DEVICE_SUB_CATEGORY) \
+	CFG(CFG_WPS_DEVICE_PASSWORD_ID)
+
+#endif /* __CFG_MLME_WPS_PARAMS_H */
+
diff --git a/components/mlme/dispatcher/inc/cfg_qos.h b/components/mlme/dispatcher/inc/cfg_qos.h
new file mode 100644
index 0000000..0213b96
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_qos.h
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of QOS related
+ * converged configurations.
+ */
+
+#ifndef __CFG_MLME_QOS_H
+#define __CFG_MLME_QOS_H
+
+/*
+ * <ini>
+ * gTxAggregationSize - Gives an option to configure Tx aggregation size
+ * in no of MPDUs
+ * @Min: 0
+ * @Max: 64
+ * @Default: 64
+ *
+ * gTxAggregationSize gives an option to configure Tx aggregation size
+ * in no of MPDUs.This can be useful in debugging throughput issues
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_TX_AGGREGATION_SIZE CFG_INI_UINT( \
+			"gTxAggregationSize", \
+			0, \
+			64, \
+			64, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx Aggregation size value")
+
+/*
+ * <ini>
+ * gTxAggregationSizeBE - To configure Tx aggregation size for BE queue
+ * in no of MPDUs
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxAggregationSizeBE gives an option to configure Tx aggregation size
+ * for BE queue in no of MPDUs.This can be useful in debugging
+ * throughput issues
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_AGGREGATION_SIZEBE CFG_INI_UINT( \
+			"gTxAggregationSizeBE", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx Aggregation size value BE")
+
+/*
+ * <ini>
+ * gTxAggregationSizeBK - To configure Tx aggregation size for BK queue
+ * in no of MPDUs
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxAggregationSizeBK gives an option to configure Tx aggregation size
+ * for BK queue in no of MPDUs.This can be useful in debugging
+ * throughput issues
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_AGGREGATION_SIZEBK CFG_INI_UINT( \
+			"gTxAggregationSizeBK", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx Aggregation size value BK")
+
+/*
+ * <ini>
+ * gTxAggregationSizeVI - To configure Tx aggregation size for VI queue
+ * in no of MPDUs
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxAggregationSizeVI gives an option to configure Tx aggregation size
+ * for VI queue in no of MPDUs.This can be useful in debugging
+ * throughput issues
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_AGGREGATION_SIZEVI CFG_INI_UINT( \
+			"gTxAggregationSizeVI", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx Aggregation size value for VI")
+
+/*
+ * <ini>
+ * gTxAggregationSizeVO - To configure Tx aggregation size for VO queue
+ * in no of MPDUs
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxAggregationSizeVO gives an option to configure Tx aggregation size
+ * for BE queue in no of MPDUs.This can be useful in debugging
+ * throughput issues
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_AGGREGATION_SIZEVO CFG_INI_UINT( \
+			"gTxAggregationSizeVO", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx Aggregation size value for VO")
+
+/*
+ * <ini>
+ * gRxAggregationSize - Gives an option to configure Rx aggregation size
+ * in no of MPDUs
+ * @Min: 1
+ * @Max: 64
+ * @Default: 64
+ *
+ * gRxAggregationSize gives an option to configure Rx aggregation size
+ * in no of MPDUs. This can be useful in debugging throughput issues
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_RX_AGGREGATION_SIZE CFG_INI_UINT( \
+			"gRxAggregationSize", \
+			1, \
+			64, \
+			64, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Rx Aggregation size value")
+
+/*
+ * <ini>
+ * gTxAggSwRetryBE - Configure Tx aggregation sw retry for BE
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxAggSwRetryBE gives an option to configure Tx aggregation sw
+ * retry for BE. This can be useful in debugging throughput issues.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_AGGR_SW_RETRY_BE CFG_INI_UINT( \
+			"gTxAggSwRetryBE", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx aggregation retry value for BE")
+
+/*
+ * <ini>
+ * gTxAggSwRetryBK - Configure Tx aggregation sw retry for BK
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxAggSwRetryBK gives an option to configure Tx aggregation sw
+ * retry for BK. This can be useful in debugging throughput issues.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_AGGR_SW_RETRY_BK CFG_INI_UINT( \
+			"gTxAggSwRetryBK", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx aggregation retry value for BK")
+
+/*
+ * <ini>
+ * gTxAggSwRetryVI - Configure Tx aggregation sw retry for VI
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxAggSwRetryVI gives an option to configure Tx aggregation sw
+ * retry for VI. This can be useful in debugging throughput issues.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_AGGR_SW_RETRY_VI CFG_INI_UINT( \
+			"gTxAggSwRetryVI", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx aggregation retry value for VI")
+
+/*
+ * <ini>
+ * gTxAggSwRetryVO - Configure Tx aggregation sw retry for VO
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxAggSwRetryVO gives an option to configure Tx aggregation sw
+ * retry for VO. This can be useful in debugging throughput issues.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_AGGR_SW_RETRY_VO CFG_INI_UINT( \
+			"gTxAggSwRetryVO", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx aggregation retry value for VO")
+
+/*
+ * <ini>
+ * gTxNonAggSwRetryBE - Configure Tx non aggregation sw retry for BE
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxNonAggSwRetryBE gives an option to configure Tx non aggregation sw
+ * retry for BE. This can be useful in debugging throughput issues.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_NON_AGGR_SW_RETRY_BE CFG_INI_UINT( \
+			"gTxNonAggSwRetryBE", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx non aggregation retry value for BE")
+
+/*
+ * <ini>
+ * gTxNonAggSwRetryBK - Configure Tx non aggregation sw retry for BK
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxNonAggSwRetryBK gives an option to configure Tx non aggregation sw
+ * retry for BK. This can be useful in debugging throughput issues.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_NON_AGGR_SW_RETRY_BK CFG_INI_UINT( \
+			"gTxNonAggSwRetryBK", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx non aggregation retry value for BK")
+
+/*
+ * <ini>
+ * gTxNonAggSwRetryVI - Configure Tx non aggregation sw retry for VI
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxNonAggSwRetryVI gives an option to configure Tx non aggregation sw
+ * retry for VI. This can be useful in debugging throughput issues.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_NON_AGGR_SW_RETRY_VI CFG_INI_UINT( \
+			"gTxNonAggSwRetryVI", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx non aggregation retry value for VI")
+
+/*
+ * <ini>
+ * gTxNonAggSwRetryVO - Configure Tx non aggregation sw retry for VO
+ * @Min: 0
+ * @Max: 64
+ * @Default: 0
+ *
+ * gTxNonAggSwRetryVO gives an option to configure Tx non aggregation sw
+ * retry for VO. This can be useful in debugging throughput issues.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TX_NON_AGGR_SW_RETRY_VO CFG_INI_UINT( \
+			"gTxNonAggSwRetryVO", \
+			0, \
+			64, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Tx non aggregation retry value for VO")
+
+/*
+ * <ini>
+ * gSapMaxInactivityOverride - Configure
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This parameter will avoid updating ap_sta_inactivity from hostapd.conf
+ * file. If a station does not send anything in ap_max_inactivity seconds, an
+ * empty data frame is sent to it in order to verify whether it is
+ * still in range. If this frame is not ACKed, the station will be
+ * disassociated and then deauthenticated. This feature is used to
+ * clear station table of old entries when the STAs move out of the
+ * range.
+ *
+ * Related: None
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ * </ini>
+ */
+#define CFG_SAP_MAX_INACTIVITY_OVERRIDE CFG_INI_BOOL( \
+			"gSapMaxInactivityOverride", \
+			0, \
+			"SAP maximum inactivity override flag")
+
+#define CFG_QOS_ALL \
+	CFG(CFG_SAP_MAX_INACTIVITY_OVERRIDE) \
+	CFG(CFG_TX_AGGREGATION_SIZE) \
+	CFG(CFG_TX_AGGREGATION_SIZEBE) \
+	CFG(CFG_TX_AGGREGATION_SIZEBK) \
+	CFG(CFG_TX_AGGREGATION_SIZEVI) \
+	CFG(CFG_TX_AGGREGATION_SIZEVO) \
+	CFG(CFG_RX_AGGREGATION_SIZE) \
+	CFG(CFG_TX_AGGR_SW_RETRY_BE) \
+	CFG(CFG_TX_AGGR_SW_RETRY_BK) \
+	CFG(CFG_TX_AGGR_SW_RETRY_VI) \
+	CFG(CFG_TX_AGGR_SW_RETRY_VO) \
+	CFG(CFG_TX_NON_AGGR_SW_RETRY_BE) \
+	CFG(CFG_TX_NON_AGGR_SW_RETRY_BK) \
+	CFG(CFG_TX_NON_AGGR_SW_RETRY_VI) \
+	CFG(CFG_TX_NON_AGGR_SW_RETRY_VO)
+
+#endif /* __CFG_MLME_QOS_H */
diff --git a/components/mlme/dispatcher/inc/cfg_sap_protection.h b/components/mlme/dispatcher/inc/cfg_sap_protection.h
new file mode 100644
index 0000000..e80034f
--- /dev/null
+++ b/components/mlme/dispatcher/inc/cfg_sap_protection.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of sap erp protection related
+ * converged configurations.
+ */
+
+#ifndef __CFG_MLME_SAP_PROTECTION_H
+#define __CFG_MLME_SAP_PROTECTION_H
+
+#define CFG_PROTECTION_ENABLED CFG_UINT( \
+		"protection_enabled", \
+		0, \
+		65535, \
+		65535, \
+		CFG_VALUE_OR_DEFAULT, \
+		"sap protection enabled")
+
+#define CFG_FORCE_POLICY_PROTECTION CFG_UINT( \
+		"protection_force_policy", \
+		0, \
+		5, \
+		5, \
+		CFG_VALUE_OR_DEFAULT, \
+		"force policy protection")
+
+/*
+ * <ini>
+ * gignore_peer_ht_opmode
+ *
+ * @min 0
+ * @max 1
+ * @default 1
+ *
+ * Enabling gignore_peer_ht_opmode will enable 11g
+ * protection only when there is a 11g AP in vicinity.
+ *
+ * Related: None
+ *
+ * Supported Feature: SAP Protection
+ * </ini>
+ */
+#define CFG_IGNORE_PEER_HT_MODE CFG_INI_BOOL( \
+		"gignore_peer_ht_opmode", \
+		0, \
+		"ignore the peer ht mode")
+
+#define CFG_SAP_PROTECTION_ALL \
+	CFG(CFG_PROTECTION_ENABLED) \
+	CFG(CFG_FORCE_POLICY_PROTECTION) \
+	CFG(CFG_IGNORE_PEER_HT_MODE)
+
+#endif /* __CFG_MLME_SAP_PROTECTION_H */
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h
new file mode 100644
index 0000000..9a6d4e0
--- /dev/null
+++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h
@@ -0,0 +1,1635 @@
+/*
+ * Copyright (c) 2018 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 APIs exposed by the mlme component
+ */
+
+#ifndef _WLAN_MLME_API_H_
+#define _WLAN_MLME_API_H_
+
+#include <wlan_mlme_public_struct.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_cmn.h>
+#include "sme_api.h"
+
+/**
+ * wlan_mlme_get_cfg_str() - Copy the uint8_t array for a particular CFG
+ * @dst:       pointer to the destination buffer.
+ * @cfg_str:   pointer to the cfg string structure
+ * @len:       length to be copied
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS wlan_mlme_get_cfg_str(uint8_t *dst, struct mlme_cfg_str *cfg_str,
+				 qdf_size_t *len);
+
+/**
+ * wlan_mlme_set_cfg_str() - Set values for a particular CFG
+ * @src:            pointer to the source buffer.
+ * @dst_cfg_str:    pointer to the cfg string structure to be modified
+ * @len:            length to be written
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS wlan_mlme_set_cfg_str(uint8_t *src, struct mlme_cfg_str *dst_cfg_str,
+				 qdf_size_t len);
+
+/**
+ * wlan_mlme_get_edca_params() - get the EDCA parameters corresponding to the
+ * edca profile access category
+ * @edca_params:   pointer to mlme edca parameters structure
+ * @data:          data to which the parameter is to be copied
+ * @edca_ac:       edca ac type enum passed to get the cfg value
+ *
+ * Return QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE
+ *
+ */
+QDF_STATUS wlan_mlme_get_edca_params(struct wlan_mlme_edca_params *edca_params,
+				     uint8_t *data, enum e_edca_type edca_ac);
+
+/*
+ * mlme_get_wep_key() - get the wep key to process during auth frame
+ * @wep_params: cfg wep parameters structure
+ * @wep_key_id: default key number
+ * @default_key: default key to be copied
+ * @key_len: length of the key to copy
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS mlme_get_wep_key(struct wlan_mlme_wep_cfg *wep_params,
+			    enum wep_key_id wep_keyid, uint8_t *default_key,
+			    qdf_size_t key_len);
+
+/**
+ * mlme_set_wep_key() - set the wep keys during auth
+ * @wep_params: cfg wep parametrs structure
+ * @wep_key_id: default key number that needs to be copied
+ * @key_to_set: destination buffer to be copied
+ * @len:        size to be copied
+ */
+QDF_STATUS mlme_set_wep_key(struct wlan_mlme_wep_cfg *wep_params,
+			    enum wep_key_id wep_keyid, uint8_t *key_to_set,
+			    qdf_size_t len);
+/**
+ * wlan_mlme_get_ht_cap_info() - Get the HT cap info config
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_ht_cap_info(struct wlan_objmgr_psoc *psoc,
+				     struct mlme_ht_capabilities_info
+				     *ht_cap_info);
+
+/**
+ * wlan_mlme_get_manufacturer_name() - get manufacturer name
+ * @psoc: pointer to psoc object
+ * @pbuf: pointer of the buff which will be filled for the caller
+ * @plen: pointer of max buffer length
+ *        actual length will be returned at this address
+ * This function gets manufacturer name
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+wlan_mlme_get_manufacturer_name(struct wlan_objmgr_psoc *psoc,
+				uint8_t *pbuf, uint32_t *plen);
+
+/**
+ * wlan_mlme_get_model_number() - get model number
+ * @psoc: pointer to psoc object
+ * @pbuf: pointer of the buff which will be filled for the caller
+ * @plen: pointer of max buffer length
+ *        actual length will be returned at this address
+ * This function gets model number
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+wlan_mlme_get_model_number(struct wlan_objmgr_psoc *psoc,
+			   uint8_t *pbuf, uint32_t *plen);
+
+/**
+ * wlan_mlme_get_model_name() - get model name
+ * @psoc: pointer to psoc object
+ * @pbuf: pointer of the buff which will be filled for the caller
+ * @plen: pointer of max buffer length
+ *        actual length will be returned at this address
+ * This function gets model name
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+wlan_mlme_get_model_name(struct wlan_objmgr_psoc *psoc,
+			 uint8_t *pbuf, uint32_t *plen);
+
+/**
+ * wlan_mlme_get_manufacture_product_name() - get manufacture product name
+ * @psoc: pointer to psoc object
+ * @pbuf: pointer of the buff which will be filled for the caller
+ * @plen: pointer of max buffer length
+ *        actual length will be returned at this address
+ * This function gets manufacture product name
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+wlan_mlme_get_manufacture_product_name(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *pbuf, uint32_t *plen);
+
+/**
+ * wlan_mlme_get_manufacture_product_version() - get manufacture product version
+ * @psoc: pointer to psoc object
+ * @pbuf: pointer of the buff which will be filled for the caller
+ * @plen: pointer of max buffer length
+ *        actual length will be returned at this address
+ * This function gets manufacture product version
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS
+wlan_mlme_get_manufacture_product_version(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *pbuf, uint32_t *plen);
+
+/**
+ * wlan_mlme_set_ht_cap_info() - Set the HT cap info config
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_ht_cap_info(struct wlan_objmgr_psoc *psoc,
+				     struct mlme_ht_capabilities_info
+				     ht_cap_info);
+
+/**
+ * wlan_mlme_get_max_amsdu_num() - get the max amsdu num
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value where the max_amsdu num is to be filled
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_max_amsdu_num(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *value);
+
+/**
+ * wlan_mlme_set_max_amsdu_num() - set the max amsdu num
+ * @psoc: pointer to psoc object
+ * @value: value to be set for max_amsdu_num
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_set_max_amsdu_num(struct wlan_objmgr_psoc *psoc,
+				       uint8_t value);
+
+/**
+ * wlan_mlme_get_ht_mpdu_density() - get the ht mpdu density
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value where the ht mpdu density is to be filled
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_ht_mpdu_density(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *value);
+
+/**
+ * wlan_mlme_set_ht_mpdu_density() - set the ht mpdu density
+ * @psoc: pointer to psoc object
+ * @value: value to be set for ht mpdu density
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_set_ht_mpdu_density(struct wlan_objmgr_psoc *psoc,
+					 uint8_t value);
+
+/**
+ * wlan_mlme_get_band_capability() - Get the Band capability config
+ * @psoc: pointer to psoc object
+ * @band_capability: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_band_capability(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *band_capability);
+
+/**
+ * wlan_mlme_set_band_capability() - Set the Band capability config
+ * @psoc: pointer to psoc object
+ * @band_capability: Value to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_band_capability(struct wlan_objmgr_psoc *psoc,
+					 uint8_t band_capability);
+
+/**
+ * wlan_mlme_get_prevent_link_down() - Get the prevent link down config
+ * @psoc: pointer to psoc object
+ * @prevent_link_down: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_prevent_link_down(struct wlan_objmgr_psoc *psoc,
+					   bool *prevent_link_down);
+
+/**
+ * wlan_mlme_get_select_5ghz_margin() - Get the select 5Ghz margin config
+ * @psoc: pointer to psoc object
+ * @select_5ghz_margin: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_select_5ghz_margin(struct wlan_objmgr_psoc *psoc,
+					    uint8_t *select_5ghz_margin);
+
+/**
+ * wlan_mlme_get_crash_inject() - Get the crash inject config
+ * @psoc: pointer to psoc object
+ * @crash_inject: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_crash_inject(struct wlan_objmgr_psoc *psoc,
+				      bool *crash_inject);
+
+/**
+ * wlan_mlme_get_lpass_support() - Get the LPASS Support config
+ * @psoc: pointer to psoc object
+ * @lpass_support: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_lpass_support(struct wlan_objmgr_psoc *psoc,
+				       bool *lpass_support);
+
+/**
+ * wlan_mlme_get_self_recovery() - Get the self recovery config
+ * @psoc: pointer to psoc object
+ * @self_recovery: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_self_recovery(struct wlan_objmgr_psoc *psoc,
+				       bool *self_recovery);
+
+/**
+ * wlan_mlme_get_sub_20_chan_width() - Get the sub 20 chan width config
+ * @psoc: pointer to psoc object
+ * @sub_20_chan_width: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_sub_20_chan_width(struct wlan_objmgr_psoc *psoc,
+					   uint8_t *sub_20_chan_width);
+
+/**
+ * wlan_mlme_get_fw_timeout_crash() - Get the fw timeout crash config
+ * @psoc: pointer to psoc object
+ * @fw_timeout_crash: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_fw_timeout_crash(struct wlan_objmgr_psoc *psoc,
+					  bool *fw_timeout_crash);
+
+/**
+ * wlan_mlme_get_ito_repeat_count() - Get the fw timeout crash config
+ * @psoc: pointer to psoc object
+ * @ito_repeat_count: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_ito_repeat_count(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *ito_repeat_count);
+
+/**
+ * wlan_mlme_get_acs_with_more_param() - Get the acs_with_more_param flag
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_acs_with_more_param(struct wlan_objmgr_psoc *psoc,
+					     bool *value);
+
+/**
+ * wlan_mlme_get_auto_channel_weight() - Get the auto channel weight
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_auto_channel_weight(struct wlan_objmgr_psoc *psoc,
+					     uint32_t *value);
+
+/**
+ * wlan_mlme_get_vendor_acs_support() - Get the vendor based channel selece
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+
+QDF_STATUS wlan_mlme_get_vendor_acs_support(struct wlan_objmgr_psoc *psoc,
+					    bool *value);
+
+/**
+ * wlan_mlme_get_acs_support_for_dfs_ltecoex() - Get the flag for
+ *						 acs support for dfs ltecoex
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_acs_support_for_dfs_ltecoex(struct wlan_objmgr_psoc *psoc,
+					  bool *value);
+
+/**
+ * wlan_mlme_get_external_acs_policy() - Get the flag for external acs policy
+ *
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_external_acs_policy(struct wlan_objmgr_psoc *psoc,
+				  bool *value);
+
+/**
+ *
+ * wlan_mlme_get_sap_inactivity_override() - Check if sap max inactivity
+ * override flag is set.
+ * @psoc: pointer to psoc object
+ * @sme_config - Sme config struct
+ *
+ * Return: QDF Status
+ */
+void wlan_mlme_get_sap_inactivity_override(struct wlan_objmgr_psoc *psoc,
+					   bool *value);
+
+/**
+ * wlan_mlme_get_ignore_peer_ht_mode() - Get the ignore peer ht opmode flag
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_ignore_peer_ht_mode(struct wlan_objmgr_psoc *psoc,
+					bool *value);
+/**
+ * wlan_mlme_get_tx_chainmask_cck() - Get the tx_chainmask_cfg value
+ *
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF_STATUS_FAILURE or QDF_STATUS_SUCCESS
+ */
+QDF_STATUS wlan_mlme_get_tx_chainmask_cck(struct wlan_objmgr_psoc *psoc,
+					  bool *value);
+
+/**
+ * wlan_mlme_get_tx_chainmask_1ss() - Get the tx_chainmask_1ss value
+ *
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF_STATUS_FAILURE or QDF_STATUS_SUCCESS
+ */
+QDF_STATUS wlan_mlme_get_tx_chainmask_1ss(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *value);
+
+/**
+ * wlan_mlme_get_num_11b_tx_chains() -  Get the number of 11b only tx chains
+ *
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF_STATUS_FAILURE or QDF_STATUS_SUCCESS
+ */
+QDF_STATUS wlan_mlme_get_num_11b_tx_chains(struct wlan_objmgr_psoc *psoc,
+					   uint16_t *value);
+
+/**
+ * wlan_mlme_get_num_11ag_tx_chains() - get the total number of 11a/g tx chains
+ *
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF_STATUS_FAILURE or QDF_STATUS_SUCCESS
+ */
+QDF_STATUS wlan_mlme_get_num_11ag_tx_chains(struct wlan_objmgr_psoc *psoc,
+					    uint16_t *value);
+
+/**
+ * wlan_mlme_configure_chain_mask() - configure chainmask parameters
+ *
+ * @psoc: pointer to psoc object
+ * @session_id: vdev_id
+ *
+ * Return: QDF_STATUS_FAILURE or QDF_STATUS_SUCCESS
+ */
+QDF_STATUS wlan_mlme_configure_chain_mask(struct wlan_objmgr_psoc *psoc,
+					  uint8_t session_id);
+
+/**
+ * wlan_mlme_set_sap_listen_interval() - Set the sap listen interval
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_sap_listen_interval(struct wlan_objmgr_psoc *psoc,
+					     int value);
+
+/**
+ * wlan_mlme_set_assoc_sta_limit() - Set the assoc sta limit
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_assoc_sta_limit(struct wlan_objmgr_psoc *psoc,
+					 int value);
+
+/**
+ * wlan_mlme_set_rmc_action_period_freq() - Set the rmc action period frequency
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_rmc_action_period_freq(struct wlan_objmgr_psoc *psoc,
+						int value);
+
+/**
+ * wlan_mlme_set_sap_get_peer_info() - get the sap get peer info
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_sap_get_peer_info(struct wlan_objmgr_psoc *psoc,
+					   bool *value);
+
+/**
+ * wlan_mlme_get_sap_allow_all_channels() - get the value of sap allow all
+ * channels
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_sap_allow_all_channels(struct wlan_objmgr_psoc *psoc,
+						bool *value);
+
+/**
+ * wlan_mlme_get_sap_allow_all_channels() - get the value sap max peers
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_sap_max_peers(struct wlan_objmgr_psoc *psoc,
+				       int *value);
+
+/**
+ * wlan_mlme_set_sap_max_peers() - set the value sap max peers
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_sap_max_peers(struct wlan_objmgr_psoc *psoc,
+				       int value);
+
+/**
+ * wlan_mlme_get_sap_max_offload_peers() - get the value sap max offload peers
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_sap_max_offload_peers(struct wlan_objmgr_psoc *psoc,
+					       int *value);
+
+/**
+ * wlan_mlme_get_sap_max_offload_reorder_buffs() - get the value sap max offload
+ * reorder buffs.
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_sap_max_offload_reorder_buffs(struct wlan_objmgr_psoc
+						       *psoc, int *value);
+
+/**
+ * wlan_mlme_get_sap_chn_switch_bcn_count() - get the value sap max channel
+ * switch beacon count
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_sap_chn_switch_bcn_count(struct wlan_objmgr_psoc *psoc,
+						  int *value);
+
+/**
+ * wlan_mlme_get_sap_chn_switch_mode() - get the sap channel
+ * switch mode
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_sap_chn_switch_mode(struct wlan_objmgr_psoc *psoc,
+					     bool *value);
+
+/**
+ * wlan_mlme_get_sap_internal_restart() - get the sap internal
+ * restart
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_sap_internal_restart(struct wlan_objmgr_psoc *psoc,
+					      bool *value);
+
+/**
+ * wlan_mlme_get_sap_reduced_beacon_interval() - get the sap reduced
+ * beacon interval
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_sap_reduced_beacon_interval(struct wlan_objmgr_psoc
+						     *psoc, int *value);
+
+/**
+ * wlan_mlme_get_sap_chan_switch_rate_enabled() - get the sap rate hostapd
+ * enabled beacon interval
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_sap_chan_switch_rate_enabled(struct wlan_objmgr_psoc
+						      *psoc, bool *value);
+
+/**
+ * wlan_mlme_get_oce_sta_enabled_info() - Get the OCE feature enable
+ * info for STA
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_oce_sta_enabled_info(struct wlan_objmgr_psoc *psoc,
+					      bool *value);
+
+/**
+ * wlan_mlme_get_oce_sap_enabled_info() - Get the OCE feature enable
+ * info for SAP
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_oce_sap_enabled_info(struct wlan_objmgr_psoc *psoc,
+					      bool *value);
+
+/**
+ * wlan_mlme_get_rts_threshold() - Get the RTS threshold config
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_rts_threshold(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value);
+
+/**
+ * wlan_mlme_set_rts_threshold() - Set the RTS threshold config
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_rts_threshold(struct wlan_objmgr_psoc *psoc,
+				       uint32_t value);
+
+/**
+ * wlan_mlme_get_frag_threshold() - Get the Fragmentation threshold
+ *                                  config
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_frag_threshold(struct wlan_objmgr_psoc *psoc,
+					uint32_t *value);
+
+/**
+ * wlan_mlme_set_frag_threshold() - Set the Fragmentation threshold
+ *                                  config
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_frag_threshold(struct wlan_objmgr_psoc *psoc,
+					uint32_t value);
+
+/**
+ * wlan_mlme_get_fils_enabled_info() - Get the fils enable info for driver
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_fils_enabled_info(struct wlan_objmgr_psoc *psoc,
+					   bool *value);
+/**
+ * wlan_mlme_set_fils_enabled_info() - Set the fils enable info for driver
+ * @psoc: pointer to psoc object
+ * @value: value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_fils_enabled_info(struct wlan_objmgr_psoc *psoc,
+					   bool value);
+
+/**
+ * wlan_mlme_get_wmm_dir_ac_vi() - Get TSPEC direction
+ * for VI
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_dir_ac_vi(struct wlan_objmgr_psoc *psoc,
+			    uint8_t *value);
+
+/**
+ * wlan_mlme_get_wmm_nom_msdu_size_ac_vi() - Get normal
+ * MSDU size for VI
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_nom_msdu_size_ac_vi(struct wlan_objmgr_psoc *psoc,
+				      uint16_t *value);
+
+/**
+ * wlan_mlme_get_wmm_mean_data_rate_ac_vi() - mean data
+ * rate for VI
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_mean_data_rate_ac_vi(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_min_phy_rate_ac_vi() - min PHY
+ * rate for VI
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_min_phy_rate_ac_vi(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_sba_ac_vi() - surplus bandwidth
+ * allowance for VI
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_sba_ac_vi(struct wlan_objmgr_psoc *psoc, uint16_t *value);
+
+/**
+ * wlan_mlme_get_wmm_uapsd_vi_srv_intv() - Get Uapsd service
+ * interval for video
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_uapsd_vi_srv_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_uapsd_vi_sus_intv() - Get Uapsd suspension
+ * interval for video
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_uapsd_vi_sus_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_dir_ac_be() - Get TSPEC direction
+ * for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_dir_ac_be(struct wlan_objmgr_psoc *psoc,
+			    uint8_t *value);
+
+/**
+ * wlan_mlme_get_wmm_nom_msdu_size_ac_be() - Get normal
+ * MSDU size for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_nom_msdu_size_ac_be(struct wlan_objmgr_psoc *psoc,
+				      uint16_t *value);
+
+/**
+ * wlan_mlme_get_wmm_mean_data_rate_ac_be() - mean data
+ * rate for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_mean_data_rate_ac_be(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_min_phy_rate_ac_be() - min PHY
+ * rate for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_wmm_min_phy_rate_ac_be(struct wlan_objmgr_psoc *psoc,
+						uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_sba_ac_be() - surplus bandwidth
+ * allowance for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_wmm_sba_ac_be(struct wlan_objmgr_psoc *psoc,
+				       uint16_t *value);
+
+/**
+ * wlan_mlme_get_wmm_uapsd_be_srv_intv() - Get Uapsd service
+ * interval for BE
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_wmm_uapsd_be_srv_intv(struct wlan_objmgr_psoc *psoc,
+					       uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_uapsd_be_sus_intv() - Get Uapsd suspension
+ * interval for BE
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_wmm_uapsd_be_sus_intv(struct wlan_objmgr_psoc *psoc,
+					       uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_dir_ac_bk() - Get TSPEC direction
+ * for BK
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_dir_ac_bk(struct wlan_objmgr_psoc *psoc, uint8_t *value);
+
+/**
+ * wlan_mlme_get_wmm_nom_msdu_size_ac_bk() - Get normal
+ * MSDU size for BK
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_nom_msdu_size_ac_bk(struct wlan_objmgr_psoc *psoc,
+				      uint16_t *value);
+
+/**
+ * wlan_mlme_get_wmm_mean_data_rate_ac_bk() - mean data
+ * rate for BK
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_mean_data_rate_ac_bk(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_min_phy_rate_ac_bk() - min PHY
+ * rate for BK
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_min_phy_rate_ac_bk(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_sba_ac_bk() - surplus bandwidth
+ * allowance for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_sba_ac_bk(struct wlan_objmgr_psoc *psoc, uint16_t *value);
+
+/**
+ * wlan_mlme_get_wmm_uapsd_bk_srv_intv() - Get Uapsd service
+ * interval for BK
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_uapsd_bk_srv_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_uapsd_bk_sus_intv() - Get Uapsd suspension
+ * interval for BK
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_uapsd_bk_sus_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_mode() - Enable WMM feature
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_mode(struct wlan_objmgr_psoc *psoc, uint8_t *value);
+
+/**
+ * wlan_mlme_get_80211e_is_enabled() - Enable 802.11e feature
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_80211e_is_enabled(struct wlan_objmgr_psoc *psoc, bool *value);
+
+/**
+ * wlan_mlme_get_wmm_uapsd_mask() - setup U-APSD mask for ACs
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_uapsd_mask(struct wlan_objmgr_psoc *psoc, uint8_t *value);
+
+/**
+ * wlan_mlme_get_implicit_qos_is_enabled() - Enable implicit QOS
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_implicit_qos_is_enabled(struct wlan_objmgr_psoc *psoc,
+				      bool *value);
+
+/**
+ * wlan_mlme_get_wmm_dir_ac_vo() - Get TSPEC direction
+ * for VO
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_get_wmm_dir_ac_vo(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *value);
+
+/**
+ * wlan_mlme_get_wmm_nom_msdu_size_ac_vo() - Get normal
+ * MSDU size for VO
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_nom_msdu_size_ac_vo(struct wlan_objmgr_psoc *psoc,
+				      uint16_t *value);
+
+/**
+ * wlan_mlme_get_wmm_mean_data_rate_ac_vo() - mean data rate for VO
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_mean_data_rate_ac_vo(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value);
+/**
+ * wlan_mlme_get_wmm_min_phy_rate_ac_vo() - min PHY
+ * rate for VO
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_min_phy_rate_ac_vo(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *value);
+/**
+ * wlan_mlme_get_wmm_sba_ac_vo() - surplus bandwidth allowance for VO
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ *  Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_sba_ac_vo(struct wlan_objmgr_psoc *psoc, uint16_t *value);
+
+/**
+ * wlan_mlme_set_enable_bcast_probe_rsp() - Set enable bcast probe resp info
+ * @psoc: pointer to psoc object
+ * @value: value that needs to be set from the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_enable_bcast_probe_rsp(struct wlan_objmgr_psoc *psoc,
+						bool value);
+
+/**
+ * wlan_mlme_get_wmm_uapsd_vo_srv_intv() - Get Uapsd service
+ * interval for voice
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_uapsd_vo_srv_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value);
+
+/**
+ * wlan_mlme_get_wmm_uapsd_vo_sus_intv() - Get Uapsd suspension
+ * interval for voice
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_wmm_uapsd_vo_sus_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value);
+
+/**
+ * wlan_mlme_cfg_get_vht_max_mpdu_len() - gets vht max mpdu length from cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_max_mpdu_len(struct wlan_objmgr_psoc *psoc,
+					      uint8_t *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_max_mpdu_len() - sets vht max mpdu length into cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_max_mpdu_len(struct wlan_objmgr_psoc *psoc,
+					      uint8_t value);
+
+/**
+ * wlan_mlme_cfg_get_vht_chan_width() - gets vht supported channel width from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_chan_width(struct wlan_objmgr_psoc *psoc,
+					    uint8_t *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_chan_width() - sets vht supported channel width into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_chan_width(struct wlan_objmgr_psoc *psoc,
+					    uint8_t value);
+
+/**
+ * wlan_mlme_cfg_get_vht_chan_width() - sets vht supported channel width into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_chan_width(struct wlan_objmgr_psoc *psoc,
+					    uint8_t *value);
+
+/**
+ * wlan_mlme_cfg_get_vht_ldpc_coding_cap() - gets vht ldpc coding cap from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_ldpc_coding_cap(struct wlan_objmgr_psoc *psoc,
+						 bool *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_ldpc_coding_cap() - sets vht ldpc coding cap into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_ldpc_coding_cap(struct wlan_objmgr_psoc *psoc,
+					         bool value);
+
+/**
+ * wlan_mlme_cfg_get_vht_short_gi_80mhz() - gets vht short gi 80MHz from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_short_gi_80mhz(struct wlan_objmgr_psoc *psoc,
+					        bool *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_short_gi_80mhz() - sets vht short gi 80MHz into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_short_gi_80mhz(struct wlan_objmgr_psoc *psoc,
+					        bool value);
+
+/**
+ * wlan_mlme_cfg_get_short_gi_160_mhz() - gets vht short gi 160MHz from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_short_gi_160_mhz(struct wlan_objmgr_psoc *psoc,
+					      bool *value);
+
+/**
+ * wlan_mlme_cfg_set_short_gi_160_mhz() - sets vht short gi 160MHz into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_short_gi_160_mhz(struct wlan_objmgr_psoc *psoc,
+					      bool value);
+
+/**
+ * wlan_mlme_cfg_get_vht_tx_stbc() - gets vht tx stbc from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_tx_stbc(struct wlan_objmgr_psoc *psoc,
+				         bool *value);
+
+/**
+ * wlan_mlme_cfg_get_vht_rx_stbc() - gets vht rx stbc from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_rx_stbc(struct wlan_objmgr_psoc *psoc,
+				         bool *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_tx_stbc() - sets vht tx stbc into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_tx_stbc(struct wlan_objmgr_psoc *psoc,
+				         bool value);
+
+/**
+ * wlan_mlme_cfg_get_vht_rx_stbc() - gets vht rx stbc from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_rx_stbc(struct wlan_objmgr_psoc *psoc,
+				         bool *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_rx_stbc() - sets vht rx stbc into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_rx_stbc(struct wlan_objmgr_psoc *psoc,
+				         bool value);
+
+/**
+ * wlan_mlme_cfg_get_vht_su_bformer() - gets vht su beam former cap from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_su_bformer(struct wlan_objmgr_psoc *psoc,
+				            bool *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_su_bformer() - sets vht su beam former cap into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_su_bformer(struct wlan_objmgr_psoc *psoc,
+				            bool value);
+
+/**
+ * wlan_mlme_cfg_set_vht_su_bformee() - sets vht su beam formee cap into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_su_bformee(struct wlan_objmgr_psoc *psoc,
+				            bool value);
+
+/**
+ * wlan_mlme_cfg_set_vht_tx_bfee_ant_supp() - sets vht Beamformee antenna
+ * support cap
+ * into cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_tx_bfee_ant_supp(struct wlan_objmgr_psoc *psoc,
+					           uint8_t value);
+
+/**
+ * wlan_mlme_cfg_get_vht_tx_bfee_ant_supp() - Gets vht Beamformee antenna
+ * support cap into cfg item
+ *
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_tx_bfee_ant_supp(struct wlan_objmgr_psoc *psoc,
+						  uint8_t *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_num_sounding_dim() - sets vht no of sounding dimensions
+ * into cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_num_sounding_dim(struct wlan_objmgr_psoc *psoc,
+					          uint8_t value);
+
+/**
+ * wlan_mlme_cfg_get_vht_mu_bformer() - gets vht mu beam former cap from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_mu_bformer(struct wlan_objmgr_psoc *psoc,
+				            bool *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_mu_bformer() - sets vht mu beam former cap into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_mu_bformer(struct wlan_objmgr_psoc *psoc,
+				            bool value);
+
+/**
+ * wlan_mlme_cfg_get_vht_mu_bformee() - gets vht mu beam formee cap from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_mu_bformee(struct wlan_objmgr_psoc *psoc,
+				            bool *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_mu_bformee() - sets vht mu beam formee cap into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_mu_bformee(struct wlan_objmgr_psoc *psoc,
+				            bool value);
+
+/**
+ * wlan_mlme_cfg_get_vht_txop_ps() - gets vht tx ops ps cap from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_txop_ps(struct wlan_objmgr_psoc *psoc,
+				         bool *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_txop_ps() - sets vht tx ops ps cap into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_txop_ps(struct wlan_objmgr_psoc *psoc,
+				         bool value);
+
+/**
+ * wlan_mlme_cfg_get_vht_ampdu_len_exp() - gets vht max AMPDU length exponent from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_ampdu_len_exp(struct wlan_objmgr_psoc *psoc,
+					       uint8_t *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_ampdu_len_exp() - sets vht max AMPDU length exponent into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_ampdu_len_exp(struct wlan_objmgr_psoc *psoc,
+					       uint8_t value);
+
+/**
+ * wlan_mlme_cfg_get_vht_rx_mcs_map() - gets vht rx mcs map from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_rx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				            uint32_t *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_rx_mcs_map() - sets rx mcs map into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_rx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				            uint32_t value);
+
+/**
+ * wlan_mlme_cfg_get_vht_tx_mcs_map() - gets vht tx mcs map from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_tx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				            uint32_t *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_tx_mcs_map() - sets tx mcs map into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_tx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				            uint32_t value);
+
+/**
+ * wlan_mlme_cfg_set_vht_rx_supp_data_rate() - sets rx supported data rate into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_mlme_cfg_set_vht_rx_supp_data_rate(struct wlan_objmgr_psoc *psoc,
+					uint32_t value);
+
+/**
+ * wlan_mlme_cfg_set_vht_tx_supp_data_rate() - sets tx supported data rate into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_mlme_cfg_set_vht_tx_supp_data_rate(struct wlan_objmgr_psoc *psoc,
+					uint32_t value);
+
+/**
+ * wlan_mlme_cfg_get_vht_basic_mcs_set() - gets basic mcs set from
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_get_vht_basic_mcs_set(struct wlan_objmgr_psoc *psoc,
+					       uint32_t *value);
+
+/**
+ * wlan_mlme_cfg_set_vht_basic_mcs_set() - sets basic mcs set into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_cfg_set_vht_basic_mcs_set(struct wlan_objmgr_psoc *psoc,
+					       uint32_t value);
+
+/**
+ * wlan_mlme_get_vht_enable_tx_bf() - Get vht enable tx bf
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht_enable_tx_bf(struct wlan_objmgr_psoc *psoc,
+					  bool *value);
+
+/**
+ * wlan_mlme_get_vht_tx_su_beamformer() - VHT enable tx su beamformer
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht_tx_su_beamformer(struct wlan_objmgr_psoc *psoc,
+					      bool *value);
+
+/**
+ * wlan_mlme_get_vht_channel_width() - gets Channel width capability
+ * for 11ac
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht_channel_width(struct wlan_objmgr_psoc *psoc,
+				           uint8_t *value);
+
+/**
+ * wlan_mlme_get_vht_rx_mcs_8_9() - VHT Rx MCS capability for 1x1 mode
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht_rx_mcs_8_9(struct wlan_objmgr_psoc *psoc,
+					uint8_t *value);
+
+/**
+ * wlan_mlme_get_vht_tx_mcs_8_9() - VHT Tx MCS capability for 1x1 mode
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht_tx_mcs_8_9(struct wlan_objmgr_psoc *psoc,
+				        uint8_t *value);
+
+/**
+ * wlan_mlme_get_vht_rx_mcs_2x2() - VHT Rx MCS capability for 2x2 mode
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht_rx_mcs_2x2(struct wlan_objmgr_psoc *psoc,
+					uint8_t *value);
+
+/**
+ * wlan_mlme_get_vht_tx_mcs_2x2() - VHT Tx MCS capability for 2x2 mode
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht_tx_mcs_2x2(struct wlan_objmgr_psoc *psoc,
+					uint8_t *value);
+
+/**
+ * wlan_mlme_get_vht20_mcs9() - Enables VHT MCS9 in 20M BW operation
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht20_mcs9(struct wlan_objmgr_psoc *psoc,
+				    bool *value);
+
+/**
+ * wlan_mlme_get_vht_enable2x2() - Enables/disables VHT Tx/Rx MCS values for 2x2
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht_enable2x2(struct wlan_objmgr_psoc *psoc,
+				       bool *value);
+
+/**
+ * wlan_mlme_set_vht_enable2x2() - Enables/disables VHT Tx/Rx MCS values for 2x2
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_set_vht_enable2x2(struct wlan_objmgr_psoc *psoc,
+				       bool value);
+
+/**
+ * wlan_mlme_get_vht_enable_paid() - Enables/disables paid feature
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht_enable_paid(struct wlan_objmgr_psoc *psoc,
+					 bool *value);
+
+/**
+ * wlan_mlme_get_vht_enable_gid() - Enables/disables VHT GID feature
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht_enable_gid(struct wlan_objmgr_psoc *psoc,
+					bool *value);
+
+/**
+ * wlan_mlme_get_vht_for_24ghz() - Enables/disables VHT for 24 ghz
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vht_for_24ghz(struct wlan_objmgr_psoc *psoc,
+				       bool *value);
+
+/**
+ * wlan_mlme_get_vendor_vht_for_24ghz() - nables/disables vendor VHT for 24 ghz
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_mlme_get_vendor_vht_for_24ghz(struct wlan_objmgr_psoc *psoc,
+					      bool *value);
+
+/**
+ * mlme_update_vht_cap() - update vht capabilities
+ * @psoc: psoc context
+ * @cfg: data to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_update_vht_cap(struct wlan_objmgr_psoc *psoc,
+			       struct wma_tgt_vht_cap *cfg);
+
+/**
+ * mlme_update_nss_vht_cap() - Update the number of spatial
+ * streams supported for vht
+ * @psoc: psoc context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_update_nss_vht_cap(struct wlan_objmgr_psoc *psoc);
+
+#endif /* _WLAN_MLME_API_H_ */
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_product_details_cfg.h b/components/mlme/dispatcher/inc/wlan_mlme_product_details_cfg.h
new file mode 100644
index 0000000..fb2b01e
--- /dev/null
+++ b/components/mlme/dispatcher/inc/wlan_mlme_product_details_cfg.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#ifndef WLAN_MLME_PRODUCT_DETAILS_H__
+#define WLAN_MLME_PRODUCT_DETAILS_H__
+
+/*
+ * manufacturer_name - Set manufacture Name
+ * @Min_len: 0
+ * @Max_len: 63
+ * @Default: Qualcomm Atheros
+ *
+ * This internal CFG is used to set manufacture name
+ *
+ * Related: None
+ *
+ * Supported Feature: product details
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_MFR_NAME CFG_STRING( \
+	"manufacturer_name", \
+	0, \
+	WLAN_CFG_MFR_NAME_LEN, \
+	"Qualcomm Atheros", \
+	"Manufacture name")
+
+/*
+ * model_number - Set model number
+ * @Min_len: 0
+ * @Max_len: 31
+ * @Default: MN1234
+ *
+ * This internal CFG is used to set model number
+ *
+ * Related: None
+ *
+ * Supported Feature: product details
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_MODEL_NUMBER CFG_STRING( \
+	"model_number", \
+	0, \
+	WLAN_CFG_MODEL_NUMBER_LEN, \
+	"MN1234", \
+	"model number")
+
+/*
+ * model_name - Set model name
+ * @Min_len: 0
+ * @Max_len: 31
+ * @Default: WFR4031
+ *
+ * This internal CFG is used to set model name
+ *
+ * Related: None
+ *
+ * Supported Feature: product details
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_MODEL_NAME CFG_STRING( \
+	"model_name", \
+	0, \
+	WLAN_CFG_MODEL_NAME_LEN, \
+	"WFR4031", \
+	"model name")
+
+/*
+ * manufacture_product_name - Set manufacture product name
+ * @Min_len: 0
+ * @Max_len: 31
+ * @Default: 11n-AP
+ *
+ * This internal CFG is used to set manufacture product name
+ *
+ * Related: None
+ *
+ * Supported Feature: product details
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_MFR_PRODUCT_NAME CFG_STRING( \
+	"manufacture_product_name", \
+	0, \
+	WLAN_CFG_MFR_PRODUCT_NAME_LEN, \
+	"11n-AP", \
+	"manufacture product name")
+
+/*
+ * model_number - Set manufacture product version
+ * @Min_len: 0
+ * @Max_len: 31
+ * @Default: SN1234
+ *
+ * This internal CFG is used to set manufacture product version
+ *
+ * Related: None
+ *
+ * Supported Feature: product details
+ *
+ * Usage: Internal
+ *
+ */
+#define CFG_MFR_PRODUCT_VERSION CFG_STRING( \
+	"manufacture_product_version", \
+	0, \
+	WLAN_CFG_MFR_PRODUCT_VERSION_LEN, \
+	"SN1234", \
+	"manufacture product version")
+
+#define CFG_MLME_PRODUCT_DETAILS_ALL \
+		CFG(CFG_MFR_NAME) \
+		CFG(CFG_MODEL_NUMBER) \
+		CFG(CFG_MODEL_NAME) \
+		CFG(CFG_MFR_PRODUCT_NAME) \
+		CFG(CFG_MFR_PRODUCT_VERSION)
+
+#endif
+
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
new file mode 100644
index 0000000..40d800c
--- /dev/null
+++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
@@ -0,0 +1,1538 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: contains mlme structure definations
+ */
+
+#ifndef _WLAN_MLME_STRUCT_H_
+#define _WLAN_MLME_STRUCT_H_
+
+#include <wlan_cmn.h>
+#include <reg_services_public_struct.h>
+
+#define CFG_PMKID_MODES_OKC                        (0x1)
+#define CFG_PMKID_MODES_PMKSA_CACHING              (0x2)
+
+#define CFG_VHT_BASIC_MCS_SET_STADEF    0xFFFE
+
+#define CFG_VHT_RX_MCS_MAP_STAMIN    0
+#define CFG_VHT_RX_MCS_MAP_STAMAX    0xFFFF
+#define CFG_VHT_RX_MCS_MAP_STADEF    0xFFFE
+
+#define CFG_VHT_TX_MCS_MAP_STAMIN    0
+#define CFG_VHT_TX_MCS_MAP_STAMAX    0xFFFF
+#define CFG_VHT_TX_MCS_MAP_STADEF    0xFFFE
+
+#define CFG_STR_DATA_LEN     17
+#define CFG_EDCA_DATA_LEN    17
+
+/**
+ * struct mlme_cfg_str - generic structure for all mlme CFG string items
+ *
+ * @max_len: maximum data length allowed
+ * @len: valid no. of elements of the data
+ * @data: uint8_t array to store values
+ */
+struct mlme_cfg_str {
+	qdf_size_t max_len;
+	qdf_size_t len;
+	uint8_t data[CFG_STR_DATA_LEN];
+};
+
+/**
+ * enum e_edca_type - to index edca params for edca profile
+ *			 EDCA profile   AC   unicast/bcast
+ * @edca_ani_acbe_local:    ani          BE      unicast
+ * @edca_ani_acbk_local:    ani          BK      unicast
+ * @edca_ani_acvi_local:    ani          VI      unicast
+ * @edca_ani_acvo_local:    ani          VO      unicast
+ * @edca_ani_acbe_bcast:    ani          BE      bcast
+ * @edca_ani_acbk_bcast:    ani          BK      bcast
+ * @edca_ani_acvi_bcast:    ani          VI      bcast
+ * @edca_ani_acvo_bcast:    ani          VO      bcast
+ * @edca_wme_acbe_local:    wme          BE      unicast
+ * @edca_wme_acbk_local:    wme          BK      unicast
+ * @edca_wme_acvi_local:    wme          VI      unicast
+ * @edca_wme_acvo_local:    wme          VO      unicast
+ * @edca_wme_acbe_bcast:    wme          BE      bcast
+ * @edca_wme_acbk_bcast:    wme          BK      bcast
+ * @edca_wme_acvi_bcast:    wme          VI      bcast
+ * @edca_wme_acvo_bcast:    wme          VO      bcast
+ * @edca_etsi_acbe_local:   etsi         BE      unicast
+ * @edca_etsi_acbk_local:   etsi         BK      unicast
+ * @edca_etsi_acvi_local:   etsi         VI      unicast
+ * @edca_etsi_acvo_local:   etsi         VO      unicast
+ * @edca_etsi_acbe_bcast:   etsi         BE      bcast
+ * @edca_etsi_acbk_bcast:   etsi         BK      bcast
+ * @edca_etsi_acvi_bcast:   etsi         VI      bcast
+ * @edca_etsi_acvo_bcast:   etsi         VO      bcast
+ */
+enum e_edca_type {
+	edca_ani_acbe_local,
+	edca_ani_acbk_local,
+	edca_ani_acvi_local,
+	edca_ani_acvo_local,
+	edca_ani_acbe_bcast,
+	edca_ani_acbk_bcast,
+	edca_ani_acvi_bcast,
+	edca_ani_acvo_bcast,
+	edca_wme_acbe_local,
+	edca_wme_acbk_local,
+	edca_wme_acvi_local,
+	edca_wme_acvo_local,
+	edca_wme_acbe_bcast,
+	edca_wme_acbk_bcast,
+	edca_wme_acvi_bcast,
+	edca_wme_acvo_bcast,
+	edca_etsi_acbe_local,
+	edca_etsi_acbk_local,
+	edca_etsi_acvi_local,
+	edca_etsi_acvo_local,
+	edca_etsi_acbe_bcast,
+	edca_etsi_acbk_bcast,
+	edca_etsi_acvi_bcast,
+	edca_etsi_acvo_bcast
+};
+
+#define CFG_EDCA_PROFILE_ACM_IDX      0
+#define CFG_EDCA_PROFILE_AIFSN_IDX    1
+#define CFG_EDCA_PROFILE_CWMINA_IDX   2
+#define CFG_EDCA_PROFILE_CWMAXA_IDX   4
+#define CFG_EDCA_PROFILE_TXOPA_IDX    6
+#define CFG_EDCA_PROFILE_CWMINB_IDX   7
+#define CFG_EDCA_PROFILE_CWMAXB_IDX   9
+#define CFG_EDCA_PROFILE_TXOPB_IDX    11
+#define CFG_EDCA_PROFILE_CWMING_IDX   12
+#define CFG_EDCA_PROFILE_CWMAXG_IDX   14
+#define CFG_EDCA_PROFILE_TXOPG_IDX    16
+
+/**
+ * struct mlme_edca_ac_vo - cwmin, cwmax and  aifs value for edca_ac_vo
+ *
+ * @vo_cwmin: cwmin value for voice
+ * @vo_cwmax: cwmax value for voice
+ * @vo_aifs: aifs value for voice
+ */
+struct mlme_edca_ac_vo {
+	uint32_t vo_cwmin;
+	uint32_t vo_cwmax;
+	uint32_t vo_aifs;
+};
+
+/**
+ * struct mlme_edca_ac_vi - cwmin, cwmax and  aifs value for edca_ac_vi
+ *
+ * @vi_cwmin: cwmin value for video
+ * @vi_cwmax: cwmax value for video
+ * @vi_aifs: aifs value for video
+ */
+struct mlme_edca_ac_vi {
+	uint32_t vi_cwmin;
+	uint32_t vi_cwmax;
+	uint32_t vi_aifs;
+};
+
+/**
+ * struct mlme_edca_ac_bk - cwmin, cwmax and  aifs value for edca_ac_bk
+ *
+ * @bk_cwmin: cwmin value for background
+ * @bk_cwmax: cwmax value for background
+ * @bk_aifs: aifs value for background
+ */
+struct mlme_edca_ac_bk {
+	uint32_t bk_cwmin;
+	uint32_t bk_cwmax;
+	uint32_t bk_aifs;
+};
+
+/**
+ * struct mlme_edca_ac_be - cwmin, cwmax and  aifs value for edca_ac_be
+ *
+ * @be_cwmin: cwmin value for best effort
+ * @be_cwmax: cwmax value for best effort
+ * @be_aifs: aifs value for best effort
+ */
+struct mlme_edca_ac_be {
+	uint32_t be_cwmin;
+	uint32_t be_cwmax;
+	uint32_t be_aifs;
+};
+
+/**
+ * struct mlme_edca_params - EDCA pramaters related config items
+ *
+ * @ani_acbk_l:  EDCA parameters for ANI local access category background
+ * @ani_acbe_l:  EDCA parameters for ANI local access category best effort
+ * @ani_acvi_l:  EDCA parameters for ANI local access category video
+ * @ani_acvo_l:  EDCA parameters for ANI local access category voice
+ * @ani_acbk_b:  EDCA parameters for ANI bcast access category background
+ * @ani_acbe_b:  EDCA parameters for ANI bcast access category best effort
+ * @ani_acvi_b:  EDCA parameters for ANI bcast access category video
+ * @ani_acvo_b:  EDCA parameters for ANI bcast access category voice
+ * @wme_acbk_l:  EDCA parameters for WME local access category background
+ * @wme_acbe_l:  EDCA parameters for WME local access category best effort
+ * @wme_acvi_l:  EDCA parameters for WME local access category video
+ * @wme_acvo_l:  EDCA parameters for WME local access category voice
+ * @wme_acbk_b:  EDCA parameters for WME bcast access category background
+ * @wme_acbe_b:  EDCA parameters for WME bcast access category best effort
+ * @wme_acvi_b:  EDCA parameters for WME bcast access category video
+ * @wme_acvo_b:  EDCA parameters for WME bcast access category voice
+ * @etsi_acbk_l: EDCA parameters for ETSI local access category background
+ * @etsi_acbe_l: EDCA parameters for ETSI local access category best effort
+ * @etsi_acvi_l: EDCA parameters for ETSI local access category video
+ * @etsi_acvo_l: EDCA parameters for ETSI local access category voice
+ * @etsi_acbk_b: EDCA parameters for ETSI bcast access category background
+ * @etsi_acbe_b: EDCA parameters for ETSI bcast access category best effort
+ * @etsi_acvi_b: EDCA parameters for ETSI bcast access category video
+ * @etsi_acvo_b: EDCA parameters for ETSI bcast access category voice
+ * @enable_edca_params: Enable edca parameter
+ * @mlme_edca_ac_vo: value for edca_ac_vo
+ * @mlme_edca_ac_vi: value for edca_ac_vi
+ * @mlme_edca_ac_bk: value for edca_ac_bk
+ * @mlme_edca_ac_be: value for edca_ac_be
+ */
+struct wlan_mlme_edca_params {
+	struct mlme_cfg_str ani_acbk_l;
+	struct mlme_cfg_str ani_acbe_l;
+	struct mlme_cfg_str ani_acvi_l;
+	struct mlme_cfg_str ani_acvo_l;
+	struct mlme_cfg_str ani_acbk_b;
+	struct mlme_cfg_str ani_acbe_b;
+	struct mlme_cfg_str ani_acvi_b;
+	struct mlme_cfg_str ani_acvo_b;
+
+	struct mlme_cfg_str wme_acbk_l;
+	struct mlme_cfg_str wme_acbe_l;
+	struct mlme_cfg_str wme_acvi_l;
+	struct mlme_cfg_str wme_acvo_l;
+	struct mlme_cfg_str wme_acbk_b;
+	struct mlme_cfg_str wme_acbe_b;
+	struct mlme_cfg_str wme_acvi_b;
+	struct mlme_cfg_str wme_acvo_b;
+
+	struct mlme_cfg_str etsi_acbk_l;
+	struct mlme_cfg_str etsi_acbe_l;
+	struct mlme_cfg_str etsi_acvi_l;
+	struct mlme_cfg_str etsi_acvo_l;
+	struct mlme_cfg_str etsi_acbk_b;
+	struct mlme_cfg_str etsi_acbe_b;
+	struct mlme_cfg_str etsi_acvi_b;
+	struct mlme_cfg_str etsi_acvo_b;
+
+	bool enable_edca_params;
+	struct mlme_edca_ac_vo edca_ac_vo;
+	struct mlme_edca_ac_vi edca_ac_vi;
+	struct mlme_edca_ac_bk edca_ac_bk;
+	struct mlme_edca_ac_be edca_ac_be;
+};
+
+#define WLAN_CFG_MFR_NAME_LEN (63)
+#define WLAN_CFG_MODEL_NUMBER_LEN (31)
+#define WLAN_CFG_MODEL_NAME_LEN (31)
+#define WLAN_CFG_MFR_PRODUCT_NAME_LEN (31)
+#define WLAN_CFG_MFR_PRODUCT_VERSION_LEN (31)
+
+/**
+ * struct mlme_ht_capabilities_info - HT Capabilities Info
+ * @l_sig_tx_op_protection: L-SIG TXOP Protection Mechanism support
+ * @stbc_control_frame: STBC Control frame support
+ * @psmp: PSMP Support
+ * @dsss_cck_mode_40_mhz: To indicate use of DSSS/CCK in 40Mhz
+ * @maximal_amsdu_size: Maximum AMSDU Size - 0:3839 octes, 1:7935 octets
+ * @delayed_ba: Support of Delayed Block Ack
+ * @rx_stbc: Rx STBC Support - 0:Not Supported, 1: 1SS, 2: 1,2SS, 3: 1,2,3SS
+ * @tx_stbc: Tx STBC Support
+ * @short_gi_40_mhz: Short GI Support for HT40
+ * @short_gi_20_mhz: Short GI support for HT20
+ * @green_field: Support for HT Greenfield PPDUs
+ * @mimo_power_save: SM Power Save Mode - 0:Static, 1:Dynamic, 3:Disabled, 2:Res
+ * @supported_channel_width_set: Supported Chan Width - 0:20Mhz, 1:20Mhz & 40Mhz
+ * @adv_coding_cap: Rx LDPC support
+ */
+#ifndef ANI_LITTLE_BIT_ENDIAN
+struct mlme_ht_capabilities_info {
+	uint16_t l_sig_tx_op_protection:1;
+	uint16_t stbc_control_frame:1;
+	uint16_t psmp:1;
+	uint16_t dsss_cck_mode_40_mhz:1;
+	uint16_t maximal_amsdu_size:1;
+	uint16_t delayed_ba:1;
+	uint16_t rx_stbc:2;
+	uint16_t tx_stbc:1;
+	uint16_t short_gi_40_mhz:1;
+	uint16_t short_gi_20_mhz:1;
+	uint16_t green_field:1;
+	uint16_t mimo_power_save:2;
+	uint16_t supported_channel_width_set:1;
+	uint16_t adv_coding_cap:1;
+} qdf_packed;
+#else
+struct mlme_ht_capabilities_info {
+	uint16_t adv_coding_cap:1;
+	uint16_t supported_channel_width_set:1;
+	uint16_t mimo_power_save:2;
+	uint16_t green_field:1;
+	uint16_t short_gi_20_mhz:1;
+	uint16_t short_gi_40_mhz:1;
+	uint16_t tx_stbc:1;
+	uint16_t rx_stbc:2;
+	uint16_t delayed_ba:1;
+	uint16_t maximal_amsdu_size:1;
+	uint16_t dsss_cck_mode_40_mhz:1;
+	uint16_t psmp:1;
+	uint16_t stbc_control_frame:1;
+	uint16_t l_sig_tx_op_protection:1;
+} qdf_packed;
+#endif
+
+/**
+ * struct mlme_ht_param_info - HT AMPDU Parameters Info
+ * @reserved: reserved bits
+ * @mpdu_density: MPDU Density
+ * @max_rx_ampdu_factor: Max Rx AMPDU Factor
+ */
+#ifndef ANI_LITTLE_BIT_ENDIAN
+struct mlme_ht_param_info {
+	uint8_t reserved:3;
+	uint8_t mpdu_density:3;
+	uint8_t max_rx_ampdu_factor:2;
+} qdf_packed;
+#else
+struct mlme_ht_param_info {
+	uint8_t max_rx_ampdu_factor:2;
+	uint8_t mpdu_density:3;
+	uint8_t reserved:3;
+#endif
+} qdf_packed;
+
+/**
+ * struct mlme_ht_ext_cap_info - Extended HT Capabilities Info
+ * reserved_2: Reserved Bits
+ * mcs_feedback: MCS Feedback Capability
+ * reserved_1: Reserved Bits
+ * transition_time: Time needed for transition between 20Mhz and 40 Mhz
+ * pco: PCO (Phased Coexistence Operation) Support
+ */
+#ifndef ANI_LITTLE_BIT_ENDIAN
+struct mlme_ht_ext_cap_info {
+	uint16_t reserved_2:6;
+	uint16_t mcs_feedback:2;
+	uint16_t reserved_1:5;
+	uint16_t transition_time:2;
+	uint16_t pco:1;
+} qdf_packed;
+#else
+struct mlme_ht_ext_cap_info {
+	uint16_t pco:1;
+	uint16_t transition_time:2;
+	uint16_t reserved1:5;
+	uint16_t mcs_feedback:2;
+	uint16_t reserved2:6;
+} qdf_packed;
+#endif
+
+/**
+ * struct mlme_ht_info_field_1 - Additional HT IE Field1
+ * @service_interval_granularity: Shortest Service Interval
+ * @controlled_access_only: Access Control for assoc requests
+ * @rifs_mode: Reduced Interframe Spacing mode
+ * @recommended_tx_width_set: Recommended Tx Channel Width
+ * @secondary_channel_offset: Secondary Channel Offset
+ */
+#ifndef ANI_LITTLE_BIT_ENDIAN
+struct mlme_ht_info_field_1 {
+	uint8_t service_interval_granularity:3;
+	uint8_t controlled_access_only:1;
+	uint8_t rifs_mode:1;
+	uint8_t recommended_tx_width_set:1;
+	uint8_t secondary_channel_offset:2;
+} qdf_packed;
+#else
+struct mlme_ht_info_field_1 {
+	uint8_t secondary_channel_offset:2;
+	uint8_t recommended_tx_width_set:1;
+	uint8_t rifs_mode:1;
+	uint8_t controlled_access_only:1;
+	uint8_t service_interval_granularity:3;
+} qdf_packed;
+#endif
+
+/* struct mlme_ht_info_field_2 - Additional HT IE Field2
+ * @reserved: reserved bits
+ * @obss_non_ht_sta_present: Protection for non-HT STAs by Overlapping BSS
+ * @transmit_burst_limit: Transmit Burst Limit
+ * @non_gf_devices_present: Non Greenfield devices present
+ * @op_mode: Operation Mode
+ */
+#ifndef ANI_LITTLE_BIT_ENDIAN
+struct mlme_ht_info_field_2 {
+	uint16_t reserved:11;
+	uint16_t obss_non_ht_sta_present:1;
+	uint16_t transmit_burst_limit:1;
+	uint16_t non_gf_devices_present:1;
+	uint16_t op_mode:2;
+} qdf_packed;
+#else
+struct mlme_ht_info_field_2 {
+	uint16_t op_mode:2;
+	uint16_t nonGFDevicesPresent:1;
+	uint16_t transmit_burst_limit:1;
+	uint16_t obss_non_ht_sta_present:1;
+	uint16_t reserved:11;
+} qdf_packed;
+#endif
+
+/**
+ * struct mlme_ht_info_field_3 - Additional HT IE Field3
+ * @reserved: reserved bits
+ * @pco_phase: PCO Phase
+ * @pco_active: PCO state
+ * @lsig_txop_protection_full_support: L-Sig TXOP Protection Full Support
+ * @secondary_beacon: Beacon ID
+ * @dual_cts_protection: Dual CTS protection Required
+ * @basic_stbc_mcs: Basic STBC MCS
+ */
+#ifndef ANI_LITTLE_BIT_ENDIAN
+struct mlme_ht_info_field_3 {
+	uint16_t reserved:4;
+	uint16_t pco_phase:1;
+	uint16_t pco_active:1;
+	uint16_t lsig_txop_protection_full_support:1;
+	uint16_t secondary_beacon:1;
+	uint16_t dual_cts_protection:1;
+	uint16_t basic_stbc_mcs:7;
+} qdf_packed;
+#else
+struct mlme_ht_info_field_3 {
+	uint16_t basic_stbc_mcs:7;
+	uint16_t dual_cts_protection:1;
+	uint16_t secondary_beacon:1;
+	uint16_t lsig_txop_protection_full_support:1;
+	uint16_t pco_active:1;
+	uint16_t pco_phase:1;
+	uint16_t reserved:4;
+} qdf_packed;
+#endif
+
+/**
+ * struct wlan_mlme_ht_caps - HT Capabilities related config items
+ * @ht_cap_info: HT capabilities Info Structure
+ * @ampdu_params: AMPDU parameters
+ * @ext_cap_info: HT EXT capabilities info
+ * @info_field_1: HT Information Subset 1
+ * @info_field_2: HT Information Subset 2
+ * @info_field_3: HT Information Subset 3
+ * @short_preamble: Short Preamble support
+ * @enable_ampdu_ps: Enable AMPDU Power Save
+ * @enable_smps: Enabled SM Power Save
+ * @smps : SM Power Save mode
+ * @max_num_amsdu: Max number of AMSDU
+ */
+struct wlan_mlme_ht_caps {
+	struct mlme_ht_capabilities_info ht_cap_info;
+	struct mlme_ht_param_info ampdu_params;
+	struct mlme_ht_ext_cap_info ext_cap_info;
+	struct mlme_ht_info_field_1 info_field_1;
+	struct mlme_ht_info_field_2 info_field_2;
+	struct mlme_ht_info_field_3 info_field_3;
+	bool short_preamble;
+	bool enable_ampdu_ps;
+	bool enable_smps;
+	uint8_t smps;
+	uint8_t max_num_amsdu;
+};
+
+/*
+ * struct wlan_mlme_wps_params - All wps based related cfg items
+ *
+ * @enable_wps - to enable wps
+ * @wps_state - current wps state
+ * @wps_version - wps version
+ * @wps_cfg_method - wps config method
+ * @wps_primary_device_category - wps primary device category
+ * @wps_primary_device_oui - primary device OUI
+ * @wps_device_sub_category - device sub category
+ * @wps_device_password_id - password id of device
+ */
+struct wlan_mlme_wps_params {
+	uint8_t enable_wps;
+	uint8_t wps_state;
+	uint8_t wps_version;
+	uint32_t wps_cfg_method;
+	uint32_t wps_primary_device_category;
+	uint32_t wps_primary_device_oui;
+	uint16_t wps_device_sub_category;
+	uint32_t wps_device_password_id;
+};
+
+#define MLME_CFG_LISTEN_INTERVAL        1
+#define MLME_CFG_BEACON_INTERVAL_DEF    100
+#define MLME_CFG_TX_MGMT_RATE_DEF       0xFF
+#define MLME_CFG_TX_MGMT_2G_RATE_DEF    0xFF
+#define MLME_CFG_TX_MGMT_5G_RATE_DEF    0xFF
+/**
+ * struct wlan_mlme_cfg_sap - SAP related config items
+ * @cfg_ssid: SSID to be configured
+ * @beacon_interval: beacon interval
+ * @dtim_interval:   dtim interval
+ * @listen_interval: listen interval
+ * @sap_11g_policy:  Check if 11g support is enabled
+ * @assoc_sta_limit: Limit on number of STA associated to SAP
+ * @enable_lte_coex: Flag for LTE coexistence
+ * @rmc_action_period_freq: rmc action period frequency
+ * @rate_tx_mgmt: mgmt frame tx rate
+ * @rate_tx_mgmt_2g: mgmt frame tx rate for 2G band
+ * @rate_tx_mgmt_5g: mgmt frame tx rate for 5G band
+ * @tele_bcn_wakeup_en: beacon wakeup enable/disable
+ * @tele_bcn_max_li: max listen interval
+ * @sap_get_peer_info: get peer info
+ * @sap_allow_all_chan_param_name: allow all channels
+ * @sap_max_no_peers: Maximum number of peers
+ * @sap_max_offload_peers: Maximum number of peer offloads
+ * @sap_max_offload_reorder_buffs: Maximum offload reorder buffs
+ * @sap_ch_switch_beacon_cnt: Number of beacons to be sent out during CSA
+ * @sap_internal_restart: flag to check if sap restart is in progress
+ * @sap_ch_switch_mode: Channel switch test mode enable/disable
+ * @chan_switch_hostapd_rate_enabled_name: enable/disable skip hostapd rate
+ * @reduced_beacon_interval: reduced beacon interval value
+ */
+struct wlan_mlme_cfg_sap {
+	uint8_t cfg_ssid[32];
+	uint16_t beacon_interval;
+	uint16_t dtim_interval;
+	uint16_t listen_interval;
+	bool sap_11g_policy;
+	uint8_t assoc_sta_limit;
+	bool enable_lte_coex;
+	uint16_t rmc_action_period_freq;
+	uint8_t rate_tx_mgmt;
+	uint8_t rate_tx_mgmt_2g;
+	uint8_t rate_tx_mgmt_5g;
+	bool tele_bcn_wakeup_en;
+	uint8_t tele_bcn_max_li;
+	bool sap_get_peer_info;
+	bool sap_allow_all_chan_param_name;
+	uint8_t sap_max_no_peers;
+	uint8_t sap_max_offload_peers;
+	uint8_t sap_max_offload_reorder_buffs;
+	uint8_t sap_ch_switch_beacon_cnt;
+	bool sap_internal_restart;
+	bool sap_ch_switch_mode;
+	bool chan_switch_hostapd_rate_enabled_name;
+	uint8_t reduced_beacon_interval;
+};
+
+/**
+ * struct wlan_mlme_dfs_cfg - DFS Capabilities related config items
+ * @dfs_master_capable: Is DFS master mode support enabled
+ */
+struct wlan_mlme_dfs_cfg {
+	bool dfs_master_capable;
+};
+
+/**
+ * struct wlan_mlme_mbo - Multiband Operation related ini configs
+ * @mbo_candidate_rssi_thres:
+ * @mbo_current_rssi_thres:
+ * @mbo_current_rssi_mcc_thres:
+ * @mbo_candidate_rssi_btc_thres:
+ */
+struct wlan_mlme_mbo {
+	int8_t mbo_candidate_rssi_thres;
+	int8_t mbo_current_rssi_thres;
+	int8_t mbo_current_rssi_mcc_thres;
+	int8_t mbo_candidate_rssi_btc_thres;
+};
+
+/**
+ * struct wlan_mlme_vht_caps - MLME VHT config items
+ * @supp_chan_width: Supported Channel Width
+ * @ldpc_coding_cap: LDPC Coding Capability
+ * @short_gi_80mhz: 80MHz Short Guard Interval
+ * @short_gi_160mhz: 160MHz Short Guard Interval
+ * @tx_stbc: Tx STBC cap
+ * @rx_stbc: Rx STBC cap
+ * @su_bformer: SU Beamformer cap
+ * @su_bformee: SU Beamformee cap
+ * @tx_bfee_ant_supp: Tx beamformee anti supp
+ * @num_soundingdim: Number of sounding dimensions
+ * @mu_bformer: MU Beamformer cap
+ * @txop_ps: Tx OPs in power save
+ * @htc_vhtc: htc_vht capability
+ * @link_adap_cap: Link adaptation capability
+ * @rx_antpattern: Rx Antenna Pattern cap
+ * @tx_antpattern: Tx Antenna Pattern cap
+ * @rx_mcs_map: Rx MCS Map
+ * @tx_mcs_map: Tx MCS Map
+ * @rx_supp_data_rate: Rx highest supported data rate
+ * @tx_supp_data_rate: Tx highest supported data rate
+ * @basic_mcs_set: Basic MCS set
+ * @enable_txbf_20mhz: enable tx bf for 20mhz
+ * @channel_width: Channel width capability for 11ac
+ * @rx_mcs: VHT Rx MCS capability for 1x1 mode
+ * @tx_mcs: VHT Tx MCS capability for 1x1 mode
+ * @rx_mcs2x2: VHT Rx MCS capability for 2x2 mode
+ * @tx_mcs2x2: VHT Tx MCS capability for 2x2 mode
+ * @enable_vht20_mcs9: Enables VHT MCS9 in 20M BW operation
+ * @enable2x2: Enables/disables VHT Tx/Rx MCS values for 2x2
+ * @enable_mu_bformee: Enables/disables multi-user (MU)
+ * beam formee capability
+ * @enable_paid: Enables/disables paid
+ * @enable_gid: Enables/disables gid
+ * @b24ghz_band: To control VHT support in 2.4 GHz band
+ * @vendor_24ghz_band: to control VHT support based on vendor
+ * ie in 2.4 GHz band
+ * @ampdu_len_exponent: To handle maximum receive AMPDU ampdu len exponent
+ * @ampdu_len: To handle maximum receive AMPDU ampdu len
+ * @tx_bfee_sap: enable tx bfee SAp
+ * @subfee_vendor_vhtie: enable subfee vendor vht ie
+ */
+struct mlme_vht_capabilities_info {
+	uint8_t supp_chan_width;
+	bool ldpc_coding_cap;
+	bool short_gi_80mhz;
+	bool short_gi_160mhz;
+	bool tx_stbc;
+	bool rx_stbc;
+	bool su_bformer;
+	bool su_bformee;
+	uint8_t tx_bfee_ant_supp;
+	uint8_t num_soundingdim;
+	bool mu_bformer;
+	bool txop_ps;
+	bool htc_vhtc;
+	uint8_t link_adap_cap;
+	bool rx_antpattern;
+	bool tx_antpattern;
+	uint32_t rx_mcs_map;
+	uint32_t tx_mcs_map;
+	uint32_t rx_supp_data_rate;
+	uint32_t tx_supp_data_rate;
+	uint32_t basic_mcs_set;
+	bool enable_txbf_20mhz;
+	uint8_t channel_width;
+	uint32_t rx_mcs;
+	uint32_t tx_mcs;
+	uint8_t rx_mcs2x2;
+	uint8_t tx_mcs2x2;
+	bool enable_vht20_mcs9;
+	bool enable2x2;
+	bool enable_mu_bformee;
+	bool enable_paid;
+	bool enable_gid;
+	bool b24ghz_band;
+	bool vendor_24ghz_band;
+	uint8_t ampdu_len_exponent;
+	uint8_t ampdu_len;
+	bool tx_bfee_sap;
+	bool vendor_vhtie;
+};
+
+/**
+ * struct wlan_mlme_vht_caps - VHT Capabilities related config items
+ * @vht_cap_info: VHT capabilities Info Structure
+ */
+struct wlan_mlme_vht_caps {
+	struct mlme_vht_capabilities_info vht_cap_info;
+};
+
+/**
+ * struct wlan_mlme_qos - QOS TX/RX aggregation related CFG items
+ * @tx_aggregation_size: TX aggr size in number of MPDUs
+ * @tx_aggregation_size_be: No. of MPDUs for BE queue for TX aggr
+ * @tx_aggregation_size_bk: No. of MPDUs for BK queue for TX aggr
+ * @tx_aggregation_size_vi: No. of MPDUs for VI queue for TX aggr
+ * @tx_aggregation_size_vo: No. of MPDUs for VO queue for TX aggr
+ * @rx_aggregation_size: No. of MPDUs for RX aggr
+ * @tx_aggr_sw_retry_threshold_be: aggr sw retry threshold for BE
+ * @tx_aggr_sw_retry_threshold_bk: aggr sw retry threshold for BK
+ * @tx_aggr_sw_retry_threshold_vi: aggr sw retry threshold for VI
+ * @tx_aggr_sw_retry_threshold_vo: aggr sw retry threshold for VO
+ * @tx_non_aggr_sw_retry_threshold_be: non aggr sw retry threshold for BE
+ * @tx_non_aggr_sw_retry_threshold_bk: non aggr sw retry threshold for BK
+ * @tx_non_aggr_sw_retry_threshold_vi: non aggr sw retry threshold for VI
+ * @tx_non_aggr_sw_retry_threshold_vo: non aggr sw retry threshold for VO
+ * @sap_max_inactivity_override: Override updating ap_sta_inactivity from
+ * hostapd.conf
+ */
+struct wlan_mlme_qos {
+	uint32_t tx_aggregation_size;
+	uint32_t tx_aggregation_size_be;
+	uint32_t tx_aggregation_size_bk;
+	uint32_t tx_aggregation_size_vi;
+	uint32_t tx_aggregation_size_vo;
+	uint32_t rx_aggregation_size;
+	uint32_t tx_aggr_sw_retry_threshold_be;
+	uint32_t tx_aggr_sw_retry_threshold_bk;
+	uint32_t tx_aggr_sw_retry_threshold_vi;
+	uint32_t tx_aggr_sw_retry_threshold_vo;
+	uint32_t tx_non_aggr_sw_retry_threshold_be;
+	uint32_t tx_non_aggr_sw_retry_threshold_bk;
+	uint32_t tx_non_aggr_sw_retry_threshold_vi;
+	uint32_t tx_non_aggr_sw_retry_threshold_vo;
+	bool sap_max_inactivity_override;
+};
+
+#define MLME_HE_PPET_LEN 25
+/**
+ * struct wlan_mlme_he_caps - HE Capabilities related config items
+ */
+struct wlan_mlme_he_caps {
+	uint8_t he_control;
+	uint8_t he_twt_requestor;
+	uint8_t he_twt_responder;
+	uint8_t he_twt_fragmentation;
+	uint8_t he_max_frag_msdu;
+	uint8_t he_min_frag_size;
+	uint8_t he_trig_pad;
+	uint8_t he_mtid_aggr_rx;
+	uint8_t he_link_adaptation;
+	uint8_t he_all_ack;
+	uint8_t he_trigd_rsp_scheduling;
+	uint8_t he_buffer_status_rpt;
+	uint8_t he_bcast_twt;
+	uint8_t he_ba_32bit;
+	uint8_t he_mu_cascading;
+	uint8_t he_multi_tid;
+	uint8_t he_dl_mu_ba;
+	uint8_t he_omi;
+	uint8_t he_ofdma_ra;
+	uint8_t he_max_ampdu_len;
+	uint8_t he_amsdu_frag;
+	uint8_t he_flex_twt_sched;
+	uint8_t he_rx_ctrl;
+	uint8_t he_bsrp_ampdu_aggr;
+	uint8_t he_qtp;
+	uint8_t he_a_bqr;
+	uint8_t he_sr_responder;
+	uint8_t he_ndp_feedback_supp;
+	uint8_t he_ops_supp;
+	uint8_t he_amsdu_in_ampdu;
+	uint8_t he_chan_width;
+	uint8_t he_mtid_aggr_tx;
+	uint8_t he_sub_ch_sel_tx;
+	uint8_t he_ul_2x996_ru;
+	uint8_t he_om_ctrl_ul_mu_dis_rx;
+	uint8_t he_rx_pream_punc;
+	uint8_t he_class_of_device;
+	uint8_t he_ldpc;
+	uint8_t he_ltf_ppdu;
+	uint8_t he_midamble_rx_nsts;
+	uint8_t he_ltf_ndp;
+	uint8_t he_tx_stbc_lt80;
+	uint8_t he_rx_stbc_lt80;
+	uint8_t he_doppler;
+	uint8_t he_ul_mumimo;
+	uint8_t he_dcm_tx;
+	uint8_t he_dcm_rx;
+	uint8_t he_mu_ppdu;
+	uint8_t he_su_beamformer;
+	uint8_t he_su_beamformee;
+	uint8_t he_mu_beamformer;
+	uint8_t he_bfee_sts_lt80;
+	uint8_t he_bfee_sts_gt80;
+	uint8_t he_num_sound_lt80;
+	uint8_t he_num_sound_gt80;
+	uint8_t he_su_feed_tone16;
+	uint8_t he_mu_feed_tone16;
+	uint8_t he_codebook_su;
+	uint8_t he_codebook_mu;
+	uint8_t he_bfrm_feed;
+	uint8_t he_er_su_ppdu;
+	uint8_t he_dl_part_bw;
+	uint8_t he_ppet_present;
+	uint8_t he_srp;
+	uint8_t he_power_boost;
+	uint8_t he_4x_ltf_gi;
+	uint8_t he_max_nc;
+	uint8_t he_rx_stbc_gt80;
+	uint8_t he_tx_stbc_gt80;
+	uint8_t he_er_4x_ltf_gi;
+	uint8_t he_ppdu_20_in_40mhz_2g;
+	uint8_t he_ppdu_20_in_160_80p80mhz;
+	uint8_t he_ppdu_80_in_160_80p80mhz;
+	uint8_t he_er_1x_he_ltf_gi;
+	uint8_t he_midamble_rx_1x_he_ltf;
+	uint8_t he_dcm_max_bw;
+	uint8_t he_longer_16_sigb_ofdm_sym;
+	uint8_t he_non_trig_cqi_feedback;
+	uint8_t he_tx_1024_qam_lt_242_ru;
+	uint8_t he_rx_1024_qam_lt_242_ru;
+	uint8_t he_rx_full_bw_mu_cmpr_sigb;
+	uint8_t he_rx_full_bw_mu_non_cmpr_sigb;
+	uint32_t he_rx_mcs_map_lt_80;
+	uint32_t he_tx_mcs_map_lt_80;
+	uint32_t he_rx_mcs_map_160;
+	uint32_t he_tx_mcs_map_160;
+	uint32_t he_rx_mcs_map_80_80;
+	uint32_t he_tx_mcs_map_80_80;
+	uint8_t he_ppet_2g[MLME_HE_PPET_LEN];
+	uint8_t he_ppet_5g[MLME_HE_PPET_LEN];
+	uint32_t he_ops_basic_mcs_nss;
+	uint8_t he_twt_dynamic_fragmentation;
+	uint8_t enable_ul_mimo;
+	uint8_t enable_ul_ofdm;
+	uint32_t he_sta_obsspd;
+};
+
+/**
+ * struct wlan_mlme_rates - RATES related config items
+ * @cfpPeriod: cfp period info
+ * @cfpMaxDuration: cfp Max duration info
+ * @max_htmcs_txdata: max HT mcs info for Tx
+ * @disable_abg_rate_txdata: disable abg rate info for tx data
+ * @sap_max_mcs_txdata: sap max mcs info
+ * @disable_high_ht_mcs_2x2: disable high mcs for 2x2 info
+ * @supported_11b: supported 11B rates
+ * @supported_11a: supported 11A rates
+ * @opr_rate_set: operational rates set
+ * @ext_opr_rate_set: extended operational rates set
+ * @supported_mcs_set: supported MCS set
+ * @basic_mcs_set: basic MCS set
+ * @current_mcs_set: current MCS set
+ */
+struct wlan_mlme_rates {
+	uint8_t cfp_period;
+	uint16_t cfp_max_duration;
+	uint16_t max_htmcs_txdata;
+	bool disable_abg_rate_txdata;
+	uint16_t sap_max_mcs_txdata;
+	uint8_t disable_high_ht_mcs_2x2;
+	struct mlme_cfg_str supported_11b;
+	struct mlme_cfg_str supported_11a;
+	struct mlme_cfg_str opr_rate_set;
+	struct mlme_cfg_str ext_opr_rate_set;
+	struct mlme_cfg_str supported_mcs_set;
+	struct mlme_cfg_str basic_mcs_set;
+	struct mlme_cfg_str current_mcs_set;
+};
+
+
+/* Flags for gLimProtectionControl that is updated in pe session*/
+#define MLME_FORCE_POLICY_PROTECTION_DISABLE        0
+#define MLME_FORCE_POLICY_PROTECTION_CTS            1
+#define MLME_FORCE_POLICY_PROTECTION_RTS            2
+#define MLME_FORCE_POLICY_PROTECTION_DUAL_CTS       3
+#define MLME_FORCE_POLICY_PROTECTION_RTS_ALWAYS     4
+#define MLME_FORCE_POLICY_PROTECTION_AUTO           5
+
+/* protection_enabled bits*/
+#define MLME_PROTECTION_ENABLED_FROM_llA            0
+#define MLME_PROTECTION_ENABLED_FROM_llB            1
+#define MLME_PROTECTION_ENABLED_FROM_llG            2
+#define MLME_PROTECTION_ENABLED_HT_20               3
+#define MLME_PROTECTION_ENABLED_NON_GF              4
+#define MLME_PROTECTION_ENABLED_LSIG_TXOP           5
+#define MLME_PROTECTION_ENABLED_RIFS                6
+#define MLME_PROTECTION_ENABLED_OBSS                7
+#define MLME_PROTECTION_ENABLED_OLBC_FROM_llA       8
+#define MLME_PROTECTION_ENABLED_OLBC_FROM_llB       9
+#define MLME_PROTECTION_ENABLED_OLBC_FROM_llG       10
+#define MLME_PROTECTION_ENABLED_OLBC_HT20           11
+#define MLME_PROTECTION_ENABLED_OLBC_NON_GF         12
+#define MLME_PROTECTION_ENABLED_OLBC_LSIG_TXOP      13
+#define MLME_PROTECTION_ENABLED_OLBC_RIFS           14
+#define MLME_PROTECTION_ENABLED_OLBC_OBSS           15
+
+/**
+ * struct wlan_mlme_feature_flag - feature related information
+ * @accept_short_slot_assoc: enable short sloc feature
+ * @enable_hcf: enable HCF feature
+ * @enable_rsn: enable RSN for connection
+ * @enable_short_preamble_11g: enable short preamble for 11g
+ * @channel_bonding_mode: channel bonding mode
+ * @enable_block_ack: enable block ack feature
+ * @enable_ampdu: Enable AMPDU feature
+ */
+
+struct wlan_mlme_feature_flag {
+	bool accept_short_slot_assoc;
+	bool enable_hcf;
+	bool enable_rsn;
+	bool enable_short_preamble_11g;
+	bool enable_short_slot_time_11g;
+	uint32_t channel_bonding_mode;
+	uint32_t enable_block_ack;
+	bool enable_ampdu;
+};
+
+/*
+ * struct wlan_mlme_sap_protection_cfg - SAP erp protection config items
+ *
+ * @protection_enabled:        Force enable protection. static via cfg
+ * @protection_force_policy:   Protection force policy. Static via cfg
+ * @ignore_peer_ht_opmode:     Ignore the ht opmode of the peer. Dynamic via INI
+ *
+ */
+struct wlan_mlme_sap_protection {
+	uint32_t protection_enabled;
+	uint8_t protection_force_policy;
+	bool ignore_peer_ht_opmode;
+};
+
+/*
+ * struct wlan_mlme_chainmask - All chainmask related cfg items
+ *
+ * @txchainmask1x1:     To set transmit chainmask
+ * @rxchainmask1x1:     To set rx chainmask
+ * @tx_chain_mask_cck:  Used to enable/disable Cck ChainMask
+ * @tx_chain_mask_1ss:  Enables/disables tx chain Mask1ss
+ * @num_11b_tx_chains:  Number of Tx Chains in 11b mode
+ * @num_11ag_tx_chains: Number of Tx Chains in 11ag mode
+ * @tx_chain_mask_2g:   Tx chain mask for 2g
+ * @rx_chain_mask_2g:   Tx chain mask for 2g
+ * @tx_chain_mask_5g:   Tx chain mask for 5g
+ * @rx_chain_mask_5g:   Rx chain mask for 5g
+ */
+struct wlan_mlme_chainmask {
+	uint8_t txchainmask1x1;
+	uint8_t rxchainmask1x1;
+	bool tx_chain_mask_cck;
+	uint8_t tx_chain_mask_1ss;
+	uint16_t num_11b_tx_chains;
+	uint16_t num_11ag_tx_chains;
+	uint8_t tx_chain_mask_2g;
+	uint8_t rx_chain_mask_2g;
+	uint8_t tx_chain_mask_5g;
+	uint8_t rx_chain_mask_5g;
+};
+
+/* struct wlan_mlme_generic - Generic CFG config items
+ *
+ * @band_capability: HW Band Capability - Both or 2.4G only or 5G only
+ * @band: Current Band - Internal variable, initialized to INI and updated later
+ * @select_5ghz_margin: RSSI margin to select 5Ghz over 2.4 Ghz
+ * @sub_20_chan_width: Sub 20Mhz Channel Width
+ * @ito_repeat_count: ITO Repeat Count
+ * @pmf_sa_query_max_retries: PMF query max retries for SAP
+ * @pmf_sa_query_retry_interval: PMF query retry interval for SAP
+ * @dropped_pkt_disconnect_thresh: Threshold for dropped pkts before disconnect
+ * @rtt3_enabled: RTT3 enable or disable info
+ * @prevent_link_down: Enable/Disable prevention of link down
+ * @memory_deep_sleep: Enable/Disable memory deep sleep
+ * @cck_tx_fir_override: Enable/Disable CCK Tx FIR Override
+ * @crash_inject: Enable/Disable Crash Inject
+ * @lpass_support: Enable/Disable LPASS Support
+ * @self_recovery: Enable/Disable Self Recovery
+ * @sap_dot11mc: Enable/Disable SAP 802.11mc support
+ * @fatal_event_trigger: Enable/Disable Fatal Events Trigger
+ * @optimize_ca_event: Enable/Disable Optimization of CA events
+ * @fw_timeout_crash: Enable/Disable FW Timeout Crash *
+ * @debug_packet_log: Debug packet log flags
+ */
+struct wlan_mlme_generic {
+	enum band_info band_capability;
+	enum band_info band;
+	uint8_t select_5ghz_margin;
+	uint8_t sub_20_chan_width;
+	uint8_t ito_repeat_count;
+	uint8_t pmf_sa_query_max_retries;
+	uint16_t pmf_sa_query_retry_interval;
+	uint16_t dropped_pkt_disconnect_thresh;
+	bool rtt3_enabled;
+	bool prevent_link_down;
+	bool memory_deep_sleep;
+	bool cck_tx_fir_override;
+	bool crash_inject;
+	bool lpass_support;
+	bool self_recovery;
+	bool sap_dot11mc;
+	bool fatal_event_trigger;
+	bool optimize_ca_event;
+	bool fw_timeout_crash;
+	uint8_t debug_packet_log;
+};
+
+/*
+ * struct wlan_mlme_product_details_cfg - product details config items
+ * @manufacturer_name: manufacture name
+ * @model_number: model number
+ * @model_name: model name
+ * @manufacture_product_name: manufacture product name
+ * @manufacture_product_version: manufacture product version
+ */
+struct wlan_mlme_product_details_cfg {
+	char manufacturer_name[WLAN_CFG_MFR_NAME_LEN + 1];
+	char model_number[WLAN_CFG_MODEL_NUMBER_LEN + 1];
+	char model_name[WLAN_CFG_MODEL_NAME_LEN + 1];
+	char manufacture_product_name[WLAN_CFG_MFR_PRODUCT_NAME_LEN + 1];
+	char manufacture_product_version[WLAN_CFG_MFR_PRODUCT_VERSION_LEN + 1];
+};
+
+/*
+ * struct wlan_mlme_acs - All acs related cfg items
+ * @is_acs_with_more_param - to enable acs with more param
+ * @auto_channel_select_weight - to set acs channel weight
+ * @is_vendor_acs_support - enable application based channel selection
+ * @is_acs_support_for_dfs_ltecoex - enable channel for dfs and lte coex
+ * @is_external_acs_policy - control external policy
+ */
+struct wlan_mlme_acs {
+	bool is_acs_with_more_param;
+	uint32_t auto_channel_select_weight;
+	bool is_vendor_acs_support;
+	bool is_acs_support_for_dfs_ltecoex;
+	bool is_external_acs_policy;
+};
+
+/**
+ * struct wlan_mlme_obss_ht40 - OBSS HT40 config items
+ * @active_dwelltime:        obss active dwelltime
+ * @passive_dwelltime:       obss passive dwelltime
+ * @width_trigger_interval:  obss trigger interval
+ * @passive_per_channel:     obss scan passive total duration per channel
+ * @active_per_channel:      obss scan active total duration per channel
+ * @width_trans_delay:       obss width transition delay
+ * @scan_activity_threshold: obss scan activity threshold
+ */
+struct wlan_mlme_obss_ht40 {
+	uint32_t active_dwelltime;
+	uint32_t passive_dwelltime;
+	uint32_t width_trigger_interval;
+	uint32_t passive_per_channel;
+	uint32_t active_per_channel;
+	uint32_t width_trans_delay;
+	uint32_t scan_activity_threshold;
+};
+
+/**
+ * enum dot11p_mode - The 802.11p mode of operation
+ * @WLAN_HDD_11P_DISABLED:   802.11p mode is disabled
+ * @WLAN_HDD_11P_STANDALONE: 802.11p-only operation
+ * @WLAN_HDD_11P_CONCURRENT: 802.11p and WLAN operate concurrently
+ */
+enum dot11p_mode {
+	CFG_11P_DISABLED = 0,
+	CFG_11P_STANDALONE,
+	CFG_11P_CONCURRENT,
+};
+
+/**
+ * struct wlan_mlme_sta_cfg - MLME STA configuration items
+ * @sta_keep_alive_period:          Sends NULL frame to AP period
+ * @tgt_gtx_usr_cfg:                Target gtx user config
+ * @pmkid_modes:                    Enable PMKID modes
+ * @wait_cnf_timeout:               Wait assoc cnf timeout
+ * @dot11p_mode:                    Set 802.11p mode
+ * @fils_max_chan_guard_time:       Set maximum channel guard time
+ * @current_rssi:                   Current rssi
+ * @ignore_peer_erp_info:           Ignore peer infrormation
+ * @sta_prefer_80mhz_over_160mhz:   Set Sta preference to connect in 80HZ/160HZ
+ * @enable_5g_ebt:                  Set default 5G early beacon termination
+ * @deauth_before_connection:       Send deauth before connection or not
+ * @enable_go_cts2self_for_sta:     Stop NOA and start using cts2self
+ * @qcn_ie_support:                 QCN IE support
+ * @force_rsne_override:            Force rsnie override from user
+ * @single_tid:                     Set replay counter for all TID
+ */
+struct wlan_mlme_sta_cfg {
+	uint32_t sta_keep_alive_period;
+	uint32_t tgt_gtx_usr_cfg;
+	uint32_t pmkid_modes;
+	uint32_t wait_cnf_timeout;
+	enum dot11p_mode dot11p_mode;
+	uint8_t fils_max_chan_guard_time;
+	uint8_t current_rssi;
+	bool ignore_peer_erp_info;
+	bool sta_prefer_80mhz_over_160mhz;
+	bool enable_5g_ebt;
+	bool deauth_before_connection;
+	bool enable_go_cts2self_for_sta;
+	bool qcn_ie_support;
+	bool force_rsne_override;
+	bool single_tid;
+};
+
+/*
+ * @mawc_roam_enabled:              Enable/Disable MAWC during roaming
+ * @enable_fast_roam_in_concurrency:Enable LFR roaming on STA during concurrency
+ * @lfr3_roaming_offload:           Enable/disable roam offload feature
+ * @early_stop_scan_enable:         Set early stop scan
+ * @lfr3_enable_subnet_detection:   Enable LFR3 subnet detection
+ * @enable_5g_band_pref:            Enable preference for 5G from INI
+ * @mawc_roam_traffic_threshold:    Configure traffic threshold
+ * @mawc_roam_ap_rssi_threshold:    Best AP RSSI threshold
+ * @mawc_roam_rssi_high_adjust:     Adjust MAWC roam high RSSI
+ * @mawc_roam_rssi_low_adjust:      Adjust MAWC roam low RSSI
+ * @roam_rssi_abs_threshold:        The min RSSI of the candidate AP
+ * @rssi_threshold_offset_5g:       Lookup threshold offset for 5G band
+ * @early_stop_scan_min_threshold:  Set early stop scan min
+ * @early_stop_scan_max_threshold:  Set early stop scan max
+ * @first_scan_bucket_threshold:    Set first scan bucket
+ * @roam_dense_traffic_threshold:   Dense traffic threshold
+ * @roam_dense_rssi_thre_offset:    Sets dense roam RSSI threshold diff
+ * @roam_dense_min_aps:             Sets minimum number of AP for dense roam
+ * @roam_bg_scan_bad_rssi_threshold:RSSI threshold for background roam
+ * @roam_bg_scan_client_bitmap:     Bitmap used to identify the scan clients
+ * @roam_bg_scan_bad_rssi_offset_2g:RSSI threshold offset for 2G to 5G roam
+ * @adaptive_roamscan_dwell_mode:   Sets dwell time adaptive mode
+ * @per_roam_enable:                To enabled/disable PER based roaming in FW
+ * @per_roam_config_high_rate_th:   Rate at which PER based roam will stop
+ * @per_roam_config_low_rate_th:    Rate at which PER based roam will start
+ * @per_roam_config_rate_th_percent:Percentage at which FW will issue roam scan
+ * @per_roam_rest_time:             FW will wait once it issues a roam scan.
+ * @per_roam_monitor_time:          Min time to be considered as valid scenario
+ * @per_roam_min_candidate_rssi:    Min roamable AP RSSI for candidate selection
+ * @lfr3_disallow_duration:         Disallow duration before roaming
+ * @lfr3_rssi_channel_penalization: RSSI penalization
+ * @lfr3_num_disallowed_aps:        Max number of AP's to maintain in LCA list
+ * @rssi_boost_threshold_5g:        Boost threshold above which 5 GHz is favored
+ * @rssi_boost_factor_5g:           Factor by which 5GHz RSSI is boosted
+ * @max_rssi_boost_5g:              Maximum boost that can be applied to 5G RSSI
+ * @rssi_penalize_threshold_5g:     Penalize thres above which 5G isn't favored
+ * @rssi_penalize_factor_5g:        Factor by which 5GHz RSSI is penalizeed
+ * @max_rssi_penalize_5g:           Max penalty that can be applied to 5G RSSI
+ * @max_num_pre_auth:               Configure max number of pre-auth
+ * @roam_preauth_retry_count:       Configure the max number of preauth retry
+ * @roam_preauth_no_ack_timeout:    Configure the no ack timeout period
+ */
+struct wlan_mlme_lfr_cfg {
+	bool mawc_roam_enabled;
+	bool enable_fast_roam_in_concurrency;
+	bool lfr3_roaming_offload;
+	bool early_stop_scan_enable;
+	bool lfr3_enable_subnet_detection;
+	bool enable_5g_band_pref;
+	uint32_t mawc_roam_traffic_threshold;
+	uint32_t mawc_roam_ap_rssi_threshold;
+	uint32_t mawc_roam_rssi_high_adjust;
+	uint32_t mawc_roam_rssi_low_adjust;
+	uint32_t roam_rssi_abs_threshold;
+	uint8_t rssi_threshold_offset_5g;
+	uint8_t early_stop_scan_min_threshold;
+	uint8_t early_stop_scan_max_threshold;
+	uint8_t first_scan_bucket_threshold;
+	uint32_t roam_dense_traffic_threshold;
+	uint32_t roam_dense_rssi_thre_offset;
+	uint32_t roam_dense_min_aps;
+	uint32_t roam_bg_scan_bad_rssi_threshold;
+	uint32_t roam_bg_scan_client_bitmap;
+	uint32_t roam_bg_scan_bad_rssi_offset_2g;
+	uint32_t adaptive_roamscan_dwell_mode;
+	uint32_t per_roam_enable;
+	uint32_t per_roam_config_high_rate_th;
+	uint32_t per_roam_config_low_rate_th;
+	uint32_t per_roam_config_rate_th_percent;
+	uint32_t per_roam_rest_time;
+	uint32_t per_roam_monitor_time;
+	uint32_t per_roam_min_candidate_rssi;
+	uint32_t lfr3_disallow_duration;
+	uint32_t lfr3_rssi_channel_penalization;
+	uint32_t lfr3_num_disallowed_aps;
+	uint32_t rssi_boost_threshold_5g;
+	uint32_t rssi_boost_factor_5g;
+	uint32_t max_rssi_boost_5g;
+	uint32_t rssi_penalize_threshold_5g;
+	uint32_t rssi_penalize_factor_5g;
+	uint32_t max_rssi_penalize_5g;
+	uint32_t max_num_pre_auth;
+	uint32_t roam_preauth_retry_count;
+	uint32_t roam_preauth_no_ack_timeout;
+};
+
+/**
+ * struct wlan_mlme_wmm_config - WMM configuration
+ * @wmm_mode: Enable WMM feature
+ * @b80211e_is_enabled: Enable 802.11e feature
+ * @uapsd_mask: what ACs to setup U-APSD for at assoc
+ * @bimplicit_qos_enabled: Enable implicit QOS
+ */
+struct wlan_mlme_wmm_config {
+	uint8_t wmm_mode;
+	bool b80211e_is_enabled;
+	uint8_t uapsd_mask;
+	bool bimplicit_qos_enabled;
+};
+
+/**
+ * struct wlan_mlme_wmm_ac_vo - Default TSPEC parameters
+ * for AC_VO
+ * @dir_ac_vo: TSPEC direction for VO
+ * @nom_msdu_size_ac_vo: normal MSDU size for VO
+ * @mean_data_rate_ac_vo: mean data rate for VO
+ * @min_phy_rate_ac_vo: min PHY rate for VO
+ * @sba_ac_vo: surplus bandwidth allowance for VO
+ * @uapsd_vo_srv_intv: Uapsd service interval for voice
+ * @uapsd_vo_sus_intv: Uapsd suspension interval for voice
+ */
+struct wlan_mlme_wmm_ac_vo {
+	uint8_t dir_ac_vo;
+	uint16_t nom_msdu_size_ac_vo;
+	uint32_t mean_data_rate_ac_vo;
+	uint32_t min_phy_rate_ac_vo;
+	uint16_t sba_ac_vo;
+	uint32_t uapsd_vo_srv_intv;
+	uint32_t uapsd_vo_sus_intv;
+};
+
+/**
+ * struct wlan_mlme_wmm_ac_vi - Default TSPEC parameters
+ * for AC_VI
+ * @dir_ac_vi: TSPEC direction for VI
+ * @nom_msdu_size_ac_vi: normal MSDU size for VI
+ * @mean_data_rate_ac_vi: mean data rate for VI
+ * @min_phy_rate_ac_vi: min PHY rate for VI
+ * @sba_ac_vi: surplus bandwidth allowance for VI
+ * @uapsd_vo_srv_intv: Uapsd service interval for VI
+ * @uapsd_vo_sus_intv: Uapsd suspension interval for VI
+ */
+struct wlan_mlme_wmm_ac_vi {
+	uint8_t dir_ac_vi;
+	uint16_t nom_msdu_size_ac_vi;
+	uint32_t mean_data_rate_ac_vi;
+	uint32_t min_phy_rate_ac_vi;
+	uint16_t sba_ac_vi;
+	uint32_t uapsd_vi_srv_intv;
+	uint32_t uapsd_vi_sus_intv;
+};
+
+/**
+ * struct wlan_mlme_wmm_ac_be - Default TSPEC parameters
+ * for AC_BE
+ * @dir_ac_be: TSPEC direction for BE
+ * @nom_msdu_size_ac_be: normal MSDU size for BE
+ * @mean_data_rate_ac_be: mean data rate for BE
+ * @min_phy_rate_ac_be: min PHY rate for BE
+ * @sba_ac_be: surplus bandwidth allowance for BE
+ * @uapsd_be_srv_intv: Uapsd service interval for BE
+ * @uapsd_be_sus_intv: Uapsd suspension interval for BE
+
+ */
+struct wlan_mlme_wmm_ac_be {
+	uint8_t dir_ac_be;
+	uint16_t nom_msdu_size_ac_be;
+	uint32_t mean_data_rate_ac_be;
+	uint32_t min_phy_rate_ac_be;
+	uint16_t sba_ac_be;
+	uint32_t uapsd_be_srv_intv;
+	uint32_t uapsd_be_sus_intv;
+
+};
+
+/**
+ * struct wlan_mlme_wmm_ac_bk - Default TSPEC parameters
+ * for AC_BK
+ * @dir_ac_bk: TSPEC direction for BK
+ * @nom_msdu_size_ac_bk: normal MSDU size for BK
+ * @mean_data_rate_ac_bk: mean data rate for BK
+ * @min_phy_rate_ac_bk: min PHY rate for BK
+ * @sba_ac_bk: surplus bandwidth allowance for BK
+ * @uapsd_bk_srv_intv: Uapsd service interval for BK
+ * @uapsd_bk_sus_intv: Uapsd suspension interval for BK
+ */
+struct wlan_mlme_wmm_ac_bk {
+	uint8_t dir_ac_bk;
+	uint16_t nom_msdu_size_ac_bk;
+	uint32_t mean_data_rate_ac_bk;
+	uint32_t min_phy_rate_ac_bk;
+	uint16_t sba_ac_bk;
+	uint32_t uapsd_bk_srv_intv;
+	uint32_t uapsd_bk_sus_intv;
+};
+
+/**
+ * struct wlan_mlme_wmm_params - WMM CFG Items
+ * @qos_enabled: AP is enabled with 11E
+ * @wme_enabled: AP is enabled with WMM
+ * @max_sp_length: Maximum SP Length
+ * @wsm_enabled: AP is enabled with WSM
+ * @ac_vo: Default TSPEC parameters for AC_VO
+ * @ac_vi: Default TSPEC parameters for AC_VI
+ * @ac_be: Default TSPEC parameters for AC_BE
+ * @ac_bk: Default TSPEC parameters for AC_BK
+ */
+struct wlan_mlme_wmm_params {
+	bool qos_enabled;
+	bool wme_enabled;
+	uint8_t max_sp_length;
+	bool wsm_enabled;
+	uint32_t edca_profile;
+	struct wlan_mlme_wmm_config wmm_config;
+	struct wlan_mlme_wmm_ac_vo ac_vo;
+	struct wlan_mlme_wmm_ac_vi ac_vi;
+	struct wlan_mlme_wmm_ac_be ac_be;
+	struct wlan_mlme_wmm_ac_bk ac_bk;
+};
+
+/**
+ * struct wlan_mlme_weight_config - weight params to
+ * calculate best candidate
+ *
+ * @rssi_weightage: RSSI weightage
+ * @ht_caps_weightage: HT caps weightage
+ * @vht_caps_weightage: VHT caps weightage
+ * @he_caps_weightage: HE caps weightage
+ * @chan_width_weightage: Channel width weightage
+ * @chan_band_weightage: Channel band weightage
+ * @nss_weightage: NSS weightage
+ * @beamforming_cap_weightage: Beamforming caps weightage
+ * @pcl_weightage: PCL weightage
+ * @channel_congestion_weightage: channel congestion weightage
+ * @oce_wan_weightage: OCE WAN metrics weightage
+ */
+struct  wlan_mlme_weight_config {
+	uint8_t rssi_weightage;
+	uint8_t ht_caps_weightage;
+	uint8_t vht_caps_weightage;
+	uint8_t he_caps_weightage;
+	uint8_t chan_width_weightage;
+	uint8_t chan_band_weightage;
+	uint8_t nss_weightage;
+	uint8_t beamforming_cap_weightage;
+	uint8_t pcl_weightage;
+	uint8_t channel_congestion_weightage;
+	uint8_t oce_wan_weightage;
+};
+
+/**
+ * struct wlan_mlme_rssi_cfg_score - RSSI params to
+ * calculate best candidate
+ *
+ * @best_rssi_threshold: Best RSSI threshold
+ * @good_rssi_threshold: Good RSSI threshold
+ * @bad_rssi_threshold: Bad RSSI threshold
+ * @good_rssi_pcnt: Good RSSI Percentage
+ * @bad_rssi_pcnt: Bad RSSI Percentage
+ * @good_rssi_bucket_size: Good RSSI Bucket Size
+ * @bad_rssi_bucket_size: Bad RSSI Bucket Size
+ * @rssi_pref_5g_rssi_thresh: Preffered 5G RSSI threshold
+ */
+struct wlan_mlme_rssi_cfg_score  {
+	uint32_t best_rssi_threshold;
+	uint32_t good_rssi_threshold;
+	uint32_t bad_rssi_threshold;
+	uint32_t good_rssi_pcnt;
+	uint32_t bad_rssi_pcnt;
+	uint32_t good_rssi_bucket_size;
+	uint32_t bad_rssi_bucket_size;
+	uint32_t rssi_pref_5g_rssi_thresh;
+};
+
+/**
+ * struct wlan_mlme_per_slot_scoring - define % score for differents slots
+ *				for a scoring param.
+ * num_slot: number of slots in which the param will be divided.
+ *           Max 15. index 0 is used for 'not_present. Num_slot will
+ *           equally divide 100. e.g, if num_slot = 4 slot 0 = 0-25%, slot
+ *           1 = 26-50% slot 2 = 51-75%, slot 3 = 76-100%
+ * score_pcnt3_to_0: Conatins score percentage for slot 0-3
+ *             BITS 0-7   :- the scoring pcnt when not present
+ *             BITS 8-15  :- SLOT_1
+ *             BITS 16-23 :- SLOT_2
+ *             BITS 24-31 :- SLOT_3
+ * score_pcnt7_to_4: Conatins score percentage for slot 4-7
+ *             BITS 0-7   :- SLOT_4
+ *             BITS 8-15  :- SLOT_5
+ *             BITS 16-23 :- SLOT_6
+ *             BITS 24-31 :- SLOT_7
+ * score_pcnt11_to_8: Conatins score percentage for slot 8-11
+ *             BITS 0-7   :- SLOT_8
+ *             BITS 8-15  :- SLOT_9
+ *             BITS 16-23 :- SLOT_10
+ *             BITS 24-31 :- SLOT_11
+ * score_pcnt15_to_12: Conatins score percentage for slot 12-15
+ *             BITS 0-7   :- SLOT_12
+ *             BITS 8-15  :- SLOT_13
+ *             BITS 16-23 :- SLOT_14
+ *             BITS 24-31 :- SLOT_15
+ */
+struct wlan_mlme_per_slot_scoring {
+	uint32_t num_slot;
+	uint32_t score_pcnt3_to_0;
+	uint32_t score_pcnt7_to_4;
+	uint32_t score_pcnt11_to_8;
+	uint32_t score_pcnt15_to_12;
+};
+
+/*
+ * struct wlan_mlme_score_config - MLME BSS Scoring related config
+ * @enable_scoring_for_roam: Enable/disable BSS Scoring for Roaming
+ * @weight_cfg: Various Weight related Scoring Configs
+ * @rssi_score: RSSI Scoring related thresholds/percentages config
+ * @esp_qbss_scoring: ESP QBSS Scoring configs
+ * @oce_wan_scoring: OCE WAN Scoring Configs
+ * @bandwidth_weight_per_index: Bandwidth weight per index for scoring logic
+ * @nss_weight_per_index: NSS weight per index for scoring logic
+ * @band_weight_per_index: Band weight per index for scoring logic
+ */
+struct wlan_mlme_scoring_cfg {
+	bool enable_scoring_for_roam;
+	struct wlan_mlme_weight_config weight_cfg;
+	struct wlan_mlme_rssi_cfg_score rssi_score;
+	struct wlan_mlme_per_slot_scoring esp_qbss_scoring;
+	struct wlan_mlme_per_slot_scoring oce_wan_scoring;
+	uint32_t bandwidth_weight_per_index;
+	uint32_t nss_weight_per_index;
+	uint32_t band_weight_per_index;
+};
+
+/* struct wlan_mlme_threshold - Threshold related config items
+ * @rts_threshold: set rts threshold
+ * @frag_threshold: set fragmentation threshold
+ */
+struct wlan_mlme_threshold {
+	uint32_t rts_threshold;
+	uint32_t frag_threshold;
+};
+
+/*
+ * struct wlan_mlme_timeout - mlme timeout related config items
+ * @join_failure_timeout: join failure timeout
+ * @auth_failure_timeout: authenticate failure timeout
+ * @auth_rsp_timeout: authenticate response timeout
+ * @assoc_failure_timeout: assoc failure timeout
+ * @reassoc_failure_timeout: re-assoc failure timeout
+ * @probe_after_hb_fail_timeout: Probe after HB fail timeout
+ * @olbc_detect_timeout: OLBC detect timeout
+ * @addts_rsp_timeout: ADDTS rsp timeout value
+ * @heart_beat_threshold: Heart beat threshold
+ * @ap_keep_alive_timeout: AP keep alive timeout value
+ * @ap_link_monitor_timeout: AP link monitor timeout value
+ * @ps_data_inactivity_timeout: PS data inactivity timeout
+ */
+struct wlan_mlme_timeout {
+	uint32_t join_failure_timeout;
+	uint32_t auth_failure_timeout;
+	uint32_t auth_rsp_timeout;
+	uint32_t assoc_failure_timeout;
+	uint32_t reassoc_failure_timeout;
+	uint32_t probe_after_hb_fail_timeout;
+	uint32_t olbc_detect_timeout;
+	uint32_t addts_rsp_timeout;
+	uint32_t heart_beat_threshold;
+	uint32_t ap_keep_alive_timeout;
+	uint32_t ap_link_monitor_timeout;
+	uint32_t ps_data_inactivity_timeout;
+};
+
+/**
+ * struct wlan_mlme_oce - OCE related config items
+ * @enable_bcast_probe_rsp: enable broadcast probe response
+ * @oce_sta_enabled: enable/disable oce feature for sta
+ * @oce_sap_enabled: enable/disable oce feature for sap
+ * @fils_enabled: enable/disable fils support
+ * @feature_bitmap: oce feature bitmap
+ *
+ */
+struct wlan_mlme_oce {
+	bool enable_bcast_probe_rsp;
+	bool oce_sta_enabled;
+	bool oce_sap_enabled;
+	bool fils_enabled;
+	uint8_t feature_bitmap;
+};
+
+#define MLME_WEP_KEY_LEN_13 (13)
+#define MLME_WEP_KEY_LENGTH_5 (5)
+
+/**
+ * enum wep_key_id  - values passed to get/set wep default keys
+ * @MLME_WEP_DEFAULT_KEY_1: wep default key 1
+ * @MLME_WEP_DEFAULT_KEY_2: wep default key 2
+ * @MLME_WEP_DEFAULT_KEY_3: wep default key 3
+ * @MLME_WEP_DEFAULT_KEY_4: wep default key 4
+ */
+enum wep_key_id {
+	MLME_WEP_DEFAULT_KEY_1 = 0,
+	MLME_WEP_DEFAULT_KEY_2,
+	MLME_WEP_DEFAULT_KEY_3,
+	MLME_WEP_DEFAULT_KEY_4
+};
+
+/**
+ * struct wlan_mlme_wep_cfg - WEP related configs
+ * @is_privacy_enabled:     Flag to check if encryption is enabled
+ * @is_shared_key_auth:     Flag to check if the auth type is shared key
+ * @is_auth_open_system:    Flag to check if the auth type is open
+ * @auth_type:              Authentication type value
+ * @wep_default_key_id:     Default WEP key id
+ * @wep_default_key_1:      WEP encryption key 1
+ * @wep_default_key_2:      WEP encryption key 2
+ * @wep_default_key_3:      WEP encryption key 3
+ * @wep_default_key_4:      WEP encryption key 4
+ */
+struct wlan_mlme_wep_cfg {
+	bool is_privacy_enabled;
+	bool is_shared_key_auth;
+	bool is_auth_open_system;
+	uint8_t auth_type;
+	uint8_t wep_default_key_id;
+	struct mlme_cfg_str wep_default_key_1;
+	struct mlme_cfg_str wep_default_key_2;
+	struct mlme_cfg_str wep_default_key_3;
+	struct mlme_cfg_str wep_default_key_4;
+};
+
+/**
+ * struct wlan_mlme_cfg - MLME config items
+ * @chainmask_cfg: VHT chainmask related cfg items
+ * @edca_params: edca related CFG items
+ * @gen: Generic CFG items
+ * @ht_caps: HT related CFG Items
+ * @he_caps: HE related cfg items
+ * @lfr: LFR related CFG Items
+ * @obss_ht40:obss ht40 CFG Items
+ * @mbo_cfg: Multiband Operation related CFG items
+ * @vht_caps: VHT related CFG Items
+ * @qos_mlme_params: QOS CFG Items
+ * @rates: Rates related cfg items
+ * @product_details: product details related CFG Items
+ * @dfs_cfg: DFS related CFG Items
+ * @sap_protection_cfg: SAP erp protection related CFG items
+ * @sap_cfg: sap CFG items
+ * @sta: sta CFG Items
+ * @scoring: BSS Scoring related CFG Items
+ * @oce: OCE related CFG items
+ * @threshold: threshold related cfg items
+ * @timeouts: mlme timeout related CFG items
+ * @acs: ACS related CFG items
+ * @feature_flags: Feature flag config items
+ * @wep_params:  WEP related config items
+ * @wmm_params: WMM related CFG & INI Items
+ * @wps_params: WPS related CFG itmes
+ */
+struct wlan_mlme_cfg {
+	struct wlan_mlme_chainmask chainmask_cfg;
+	struct wlan_mlme_edca_params edca_params;
+	struct wlan_mlme_generic gen;
+	struct wlan_mlme_ht_caps ht_caps;
+	struct wlan_mlme_he_caps he_caps;
+	struct wlan_mlme_lfr_cfg lfr;
+	struct wlan_mlme_obss_ht40 obss_ht40;
+	struct wlan_mlme_mbo mbo_cfg;
+	struct wlan_mlme_vht_caps vht_caps;
+	struct wlan_mlme_qos qos_mlme_params;
+	struct wlan_mlme_rates rates;
+	struct wlan_mlme_product_details_cfg product_details;
+	struct wlan_mlme_dfs_cfg dfs_cfg;
+	struct wlan_mlme_sap_protection sap_protection_cfg;
+	struct wlan_mlme_cfg_sap sap_cfg;
+	struct wlan_mlme_sta_cfg sta;
+	struct wlan_mlme_scoring_cfg scoring;
+	struct wlan_mlme_oce oce;
+	struct wlan_mlme_threshold threshold;
+	struct wlan_mlme_timeout timeouts;
+	struct wlan_mlme_acs acs;
+	struct wlan_mlme_feature_flag feature_flags;
+	struct wlan_mlme_wep_cfg wep_params;
+	struct wlan_mlme_wmm_params wmm_params;
+	struct wlan_mlme_wps_params wps_params;
+};
+
+#endif
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
new file mode 100644
index 0000000..fa2e8e5
--- /dev/null
+++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
@@ -0,0 +1,2169 @@
+/*
+ * Copyright (c) 2018 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 UCFG APIs exposed by the mlme component
+ */
+
+#ifndef _WLAN_MLME_UCFG_API_H_
+#define _WLAN_MLME_UCFG_API_H_
+
+#include <wlan_mlme_public_struct.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_cmn.h>
+#include <wlan_mlme_api.h>
+
+/**
+ * ucfg_mlme_init() - initialize mlme_ctx context.
+ *
+ * This function initializes the mlme context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS ucfg_mlme_init(void);
+
+/**
+ * ucfg_mlme_deinit() - De initialize mlme_ctx context.
+ *
+ * This function De initializes mlme contex.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS ucfg_mlme_deinit(void);
+
+/**
+ * ucfg_mlme_psoc_open() - MLME component Open
+ * @psoc: pointer to psoc object
+ *
+ * Open the MLME component and initialize the MLME strucutre
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_mlme_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_mlme_psoc_close() - MLME component close
+ * @psoc: pointer to psoc object
+ *
+ * Close the MLME component and clear the MLME structures
+ *
+ * Return: None
+ */
+void ucfg_mlme_psoc_close(struct wlan_objmgr_psoc *psoc);
+
+#ifdef CONFIG_VDEV_SM
+/**
+ * ucfg_mlme_pdev_open() - MLME component pdev Open
+ * @pdev: pointer to pdev object
+ *
+ * Open the MLME component and initialize the MLME pdev strucutre
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_mlme_pdev_open(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_mlme_pdev_close() - MLME component pdev close
+ * @pdev: pointer to pdev object
+ *
+ * close the MLME pdev information
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_mlme_pdev_close(struct wlan_objmgr_pdev *pdev);
+
+#else
+/**
+ * ucfg_mlme_pdev_open() - MLME component pdev Open
+ * @pdev: pointer to pdev object
+ *
+ * Open the MLME component and initialize the MLME pdev strucutre
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS ucfg_mlme_pdev_open(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_mlme_pdev_close() - MLME component pdev close
+ * @pdev: pointer to pdev object
+ *
+ * close the MLME pdev information
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS ucfg_mlme_pdev_close(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * ucfg_mlme_get_ht_cap_info() - Get the HT cap info config
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_ht_cap_info(struct wlan_objmgr_psoc *psoc,
+				     struct mlme_ht_capabilities_info
+				     *ht_cap_info)
+{
+	return wlan_mlme_get_ht_cap_info(psoc, ht_cap_info);
+}
+
+/**
+ * ucfg_mlme_set_ht_cap_info() - Set the HT cap info config
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_ht_cap_info(struct wlan_objmgr_psoc *psoc,
+				     struct mlme_ht_capabilities_info
+				     ht_cap_info)
+{
+	return wlan_mlme_set_ht_cap_info(psoc, ht_cap_info);
+}
+
+/**
+ * ucfg_mlme_get_max_amsdu_num() - get the max amsdu num
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value where the max_amsdu num is to be filled
+ *
+ * Return: QDF_STATUS
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_max_amsdu_num(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *value)
+{
+	return wlan_mlme_get_max_amsdu_num(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_max_amsdu_num() - set the max amsdu num
+ * @psoc: pointer to psoc object
+ * @value: value to be set for max_amsdu_num
+ *
+ * Return: QDF_STATUS
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_max_amsdu_num(struct wlan_objmgr_psoc *psoc,
+				       uint8_t value)
+{
+	return wlan_mlme_set_max_amsdu_num(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_ht_mpdu_density() - get the ht mpdu density
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value where the ht mpdu density is to be filled
+ *
+ * Return: QDF_STATUS
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_ht_mpdu_density(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *value)
+{
+	return wlan_mlme_get_ht_mpdu_density(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_ht_mpdu_density() - set the ht mpdu density
+ * @psoc: pointer to psoc object
+ * @value: value to be set for ht mpdu density
+ *
+ * Return: QDF_STATUS
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_ht_mpdu_density(struct wlan_objmgr_psoc *psoc,
+					 uint8_t value)
+{
+	return wlan_mlme_set_ht_mpdu_density(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_band_capability() - Get the Band capability config
+ * @psoc: pointer to psoc object
+ * @band_capability: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_band_capability(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *band_capability)
+{
+	return wlan_mlme_get_band_capability(psoc, band_capability);
+}
+
+/**
+ * ucfg_mlme_set_band_capability() - Set the Band capability config
+ * @psoc: pointer to psoc object
+ * @band_capability: Value to be set from the caller
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_band_capability(struct wlan_objmgr_psoc *psoc,
+					 uint8_t band_capability)
+{
+	return wlan_mlme_set_band_capability(psoc, band_capability);
+}
+
+/**
+ * ucfg_mlme_get_prevent_link_down() - Get the prevent link down config
+ * @psoc: pointer to psoc object
+ * @prevent_link_down: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_prevent_link_down(struct wlan_objmgr_psoc *psoc,
+					   bool *prevent_link_down)
+{
+	return wlan_mlme_get_prevent_link_down(psoc, prevent_link_down);
+}
+
+/**
+ * ucfg_mlme_get_select_5ghz_margin() - Get the select 5Ghz margin config
+ * @psoc: pointer to psoc object
+ * @select_5ghz_margin: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_select_5ghz_margin(struct wlan_objmgr_psoc *psoc,
+					    uint8_t *select_5ghz_margin)
+{
+	return wlan_mlme_get_select_5ghz_margin(psoc, select_5ghz_margin);
+}
+
+/**
+ * ucfg_mlme_get_crash_inject() - Get the crash inject config
+ * @psoc: pointer to psoc object
+ * @crash_inject: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_crash_inject(struct wlan_objmgr_psoc *psoc,
+				      bool *crash_inject)
+{
+	return wlan_mlme_get_crash_inject(psoc, crash_inject);
+}
+
+/**
+ * ucfg_mlme_get_lpass_support() - Get the LPASS Support config
+ * @psoc: pointer to psoc object
+ * @lpass_support: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_lpass_support(struct wlan_objmgr_psoc *psoc,
+				       bool *lpass_support)
+{
+	return wlan_mlme_get_lpass_support(psoc, lpass_support);
+}
+
+/**
+ * ucfg_mlme_get_self_recovery() - Get the self recovery config
+ * @psoc: pointer to psoc object
+ * @self_recovery: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_self_recovery(struct wlan_objmgr_psoc *psoc,
+				       bool *self_recovery)
+{
+	return wlan_mlme_get_self_recovery(psoc, self_recovery);
+}
+
+/**
+ * ucfg_mlme_get_sub_20_chan_width() - Get the sub 20 chan width config
+ * @psoc: pointer to psoc object
+ * @sub_20_chan_width: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_sub_20_chan_width(struct wlan_objmgr_psoc *psoc,
+					   uint8_t *sub_20_chan_width)
+{
+	return wlan_mlme_get_sub_20_chan_width(psoc, sub_20_chan_width);
+}
+
+/**
+ * ucfg_mlme_get_fw_timeout_crash() - Get the fw timeout crash config
+ * @psoc: pointer to psoc object
+ * @fw_timeout_crash: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_fw_timeout_crash(struct wlan_objmgr_psoc *psoc,
+					  bool *fw_timeout_crash)
+{
+	return wlan_mlme_get_fw_timeout_crash(psoc, fw_timeout_crash);
+}
+
+/**
+ * ucfg_mlme_get_ito_repeat_count() - Get the fw timeout crash config
+ * @psoc: pointer to psoc object
+ * @ito_repeat_count: Pointer to the variable from caller
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_ito_repeat_count(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *ito_repeat_count)
+{
+	return wlan_mlme_get_ito_repeat_count(psoc, ito_repeat_count);
+}
+
+/**
+ * ucfg_mlme_get_acs_with_more_param() - Get the flag for acs with
+ *					 more param
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_acs_with_more_param(struct wlan_objmgr_psoc *psoc,
+					     bool *value)
+{
+	return wlan_mlme_get_acs_with_more_param(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_auto_channel_weight() - Get the auto channel select weight
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_auto_channel_weight(struct wlan_objmgr_psoc *psoc,
+					     uint32_t *value)
+{
+	return wlan_mlme_get_auto_channel_weight(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vendor_acs_support() - Get the flag for
+ *					vendor acs support
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_vendor_acs_support(struct wlan_objmgr_psoc *psoc,
+					    bool *value)
+{
+	return wlan_mlme_get_vendor_acs_support(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_external_acs_policy() - Get flag for external control
+ *					 acs policy
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_external_acs_policy(struct wlan_objmgr_psoc *psoc,
+				  bool *value)
+{
+	return wlan_mlme_get_external_acs_policy(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_ht_cap_info() - Set the HT cap info config
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS
+ucfg_mlme_get_acs_support_for_dfs_ltecoex(struct wlan_objmgr_psoc *psoc,
+					  bool *value)
+{
+	return wlan_mlme_get_acs_support_for_dfs_ltecoex(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_dir_ac_vo() - Get TSPEC direction for VO
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_dir_ac_vo(struct wlan_objmgr_psoc *psoc,
+			    uint8_t *value)
+{
+	return wlan_mlme_get_wmm_dir_ac_vo(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_nom_msdu_size_ac_vo() - Get normal
+ * MSDU size for VO
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_nom_msdu_size_ac_vo(struct wlan_objmgr_psoc *psoc,
+				      uint16_t *value)
+{
+	return wlan_mlme_get_wmm_nom_msdu_size_ac_vo(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_mean_data_rate_ac_vo() - mean data rate for VO
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_mean_data_rate_ac_vo(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value)
+{
+	return wlan_mlme_get_wmm_mean_data_rate_ac_vo(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_min_phy_rate_ac_vo() - min PHY
+ * rate for VO
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_min_phy_rate_ac_vo(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *value)
+{
+	return wlan_mlme_get_wmm_min_phy_rate_ac_vo(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_sba_ac_vo() - surplus bandwidth
+ * allowance for VO
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_sba_ac_vo(struct wlan_objmgr_psoc *psoc,
+			    uint16_t *value)
+{
+	return wlan_mlme_get_wmm_sba_ac_vo(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_uapsd_vo_srv_intv() - Get Uapsd service
+ * interval for voice
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_uapsd_vo_srv_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	return wlan_mlme_get_wmm_uapsd_vo_srv_intv(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_uapsd_vo_sus_intv() - Get Uapsd suspension
+ * interval for voice
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_uapsd_vo_sus_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	return wlan_mlme_get_wmm_uapsd_vo_sus_intv(psoc, value);
+}
+
+/**
+ *
+ * ucfg_mlme_get_sap_inactivity_override() - Check if sap max inactivity
+ * override flag is set.
+ * @psoc: pointer to psoc object
+ * @sme_config - Sme config struct
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to call
+ * the mlme function wlan_mlme_get_sap_inactivity_override
+ *
+ * Return: QDF Status
+ */
+static inline
+void ucfg_mlme_get_sap_inactivity_override(struct wlan_objmgr_psoc *psoc,
+					   bool *value)
+{
+	wlan_mlme_get_sap_inactivity_override(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_tx_chainmask_1ss() - Get the tx_chainmask_1ss value
+ *
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF_STATUS_FAILURE or QDF_STATUS_SUCCESS
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_tx_chainmask_1ss(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *value)
+{
+	return wlan_mlme_get_tx_chainmask_1ss(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_num_11b_tx_chains() -  Get the number of 11b only tx chains
+ *
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF_STATUS_FAILURE or QDF_STATUS_SUCCESS
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_num_11b_tx_chains(struct wlan_objmgr_psoc *psoc,
+					   uint16_t *value)
+{
+	return wlan_mlme_get_num_11b_tx_chains(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_num_11ag_tx_chains() - get the total number of 11a/g tx chains
+ *
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Return: QDF_STATUS_FAILURE or QDF_STATUS_SUCCESS
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_num_11ag_tx_chains(struct wlan_objmgr_psoc *psoc,
+					    uint16_t *value)
+{
+	return wlan_mlme_get_num_11ag_tx_chains(psoc, value);
+}
+
+/**
+ * ucfg_mlme_configure_chain_mask() - configure chainmask parameters
+ *
+ * @psoc: pointer to psoc object
+ * @session_id: vdev_id
+ *
+ * Return: QDF_STATUS_FAILURE or QDF_STATUS_SUCCESS
+ */
+static inline
+QDF_STATUS ucfg_mlme_configure_chain_mask(struct wlan_objmgr_psoc *psoc,
+					  uint8_t session_id)
+{
+	return wlan_mlme_configure_chain_mask(psoc, session_id);
+}
+
+/*
+ * ucfg_mlme_get_sta_keep_alive_period() - Get the sta keep alive period
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_sta_keep_alive_period(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *val);
+
+/*
+ * ucfg_mlme_get_dfs_master_capability() - Get the dfs master capability
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_dfs_master_capability(struct wlan_objmgr_psoc *psoc,
+				    bool *val);
+
+/**
+ * ucfg_mlme_get_pmkid_modes() - Get PMKID modes
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_pmkid_modes(struct wlan_objmgr_psoc *psoc,
+			  uint32_t *val);
+
+/**
+ * ucfg_mlme_set_pmkid_modes() - Set PMKID modes
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_pmkid_modes(struct wlan_objmgr_psoc *psoc,
+			  uint32_t val);
+
+/**
+ * ucfg_mlme_get_dot11p_mode() - Get the setting about 802.11p mode
+ * @psoc: pointer to psoc object
+ * @out_mode:  Pointer to the mode which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_dot11p_mode(struct wlan_objmgr_psoc *psoc,
+			  enum dot11p_mode *out_mode);
+
+/**
+ * ucfg_mlme_get_go_cts2self_for_sta() - Stop NOA and start using cts2self
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_go_cts2self_for_sta(struct wlan_objmgr_psoc *psoc,
+				  bool *val);
+
+/**
+ * ucfg_mlme_get_force_rsne_override() - Force rsnie override from user
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_force_rsne_override(struct wlan_objmgr_psoc *psoc,
+				  bool *val);
+
+/**
+ * ucfg_mlme_get_qcn_ie_support() - QCN IE support or not
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_qcn_ie_support(struct wlan_objmgr_psoc *psoc,
+			     bool *val);
+
+/**
+ * ucfg_mlme_get_tgt_gtx_usr_cfg() - Get the target gtx user config
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_tgt_gtx_usr_cfg(struct wlan_objmgr_psoc *psoc,
+			      uint32_t *val);
+
+/**
+ * ucfg_mlme_get_roaming_offload() - Get roaming offload setting
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to enable/disable roaming offload
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_roaming_offload(struct wlan_objmgr_psoc *psoc,
+			      bool *val);
+
+/**
+ * ucfg_mlme_set_roaming_offload() - Enable/disable roaming offload
+ * @psoc: pointer to psoc object
+ * @val:  enable/disable roaming offload
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_roaming_offload(struct wlan_objmgr_psoc *psoc,
+			      bool val);
+
+/**
+ * ucfg_mlme_get_first_scan_bucket_threshold() - Get first scan bucket thre
+ * @psoc: pointer to psoc object
+ * @val:  first scan bucket threshold
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_first_scan_bucket_threshold(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *val);
+/**
+ * ucfg_mlme_set_sap_listen_interval() - Set the Sap listen interval
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_sap_listen_interval(struct wlan_objmgr_psoc *psoc,
+					     int value)
+{
+	return wlan_mlme_set_sap_listen_interval(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_assoc_sta_limit() - Set the assoc sta limit
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_assoc_sta_limit(struct wlan_objmgr_psoc *psoc,
+					 int value)
+{
+	return wlan_mlme_set_assoc_sta_limit(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_rmc_action_period_freq() - Set the rmc action period frequency
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_rmc_action_period_freq(struct wlan_objmgr_psoc *psoc,
+						int value)
+{
+	return wlan_mlme_set_rmc_action_period_freq(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_sap_get_peer_info() - get the sap get peer info
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_sap_get_peer_info(struct wlan_objmgr_psoc *psoc,
+					   bool *value)
+{
+	return wlan_mlme_get_sap_get_peer_info(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_sap_allow_all_channels() - get the sap allow all channels
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_sap_allow_all_channels(struct wlan_objmgr_psoc *psoc,
+						bool *value)
+{
+	return wlan_mlme_get_sap_allow_all_channels(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_sap_max_peers() - get the sap max peers
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_sap_max_peers(struct wlan_objmgr_psoc *psoc,
+				       int *value)
+{
+	return wlan_mlme_get_sap_max_peers(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_sap_max_peers() - Set the sap max peers
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_sap_max_peers(struct wlan_objmgr_psoc *psoc, int value)
+{
+	return wlan_mlme_set_sap_max_peers(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_sap_max_offload_peers() - get the sap max offload peers
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_sap_max_offload_peers(struct wlan_objmgr_psoc *psoc,
+					       int *value)
+{
+	return wlan_mlme_get_sap_max_offload_peers(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_sap_max_offload_reorder_buffs() - get the sap max offload
+ * reorder buffs
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_sap_max_offload_reorder_buffs(struct wlan_objmgr_psoc
+						       *psoc, int *value)
+{
+	return wlan_mlme_get_sap_max_offload_reorder_buffs(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_sap_chn_switch_bcn_count() - get the sap channel
+ * switch beacon count
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_sap_chn_switch_bcn_count(struct wlan_objmgr_psoc *psoc,
+						  int *value)
+{
+	return wlan_mlme_get_sap_chn_switch_bcn_count(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_sap_channel_switch_mode() - get the sap channel switch mode
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_sap_channel_switch_mode(struct wlan_objmgr_psoc *psoc,
+						 bool *value)
+{
+	return wlan_mlme_get_sap_chn_switch_mode(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_sap_internal_restart() - get sap internal restart value
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_sap_internal_restart(struct wlan_objmgr_psoc *psoc,
+					      bool *value)
+{
+	return wlan_mlme_get_sap_internal_restart(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_sap_reduces_beacon_interval() - get the sap reduces beacon
+ * interval
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_sap_reduces_beacon_interval(struct wlan_objmgr_psoc
+						     *psoc, int *value)
+{
+	return wlan_mlme_get_sap_reduced_beacon_interval(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_sap_chan_switch_rate_enabled() - get the sap channel
+ * switch rate enabled.
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_sap_chan_switch_rate_enabled(struct wlan_objmgr_psoc
+						      *psoc, bool *value)
+{
+	return wlan_mlme_get_sap_chan_switch_rate_enabled(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_oce_sta_enabled_info() - Get OCE feature enable/disable
+ * info for STA
+ *
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * OCE STA feature enable value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_oce_sta_enabled_info(struct wlan_objmgr_psoc *psoc,
+					      bool *value)
+{
+	return wlan_mlme_get_oce_sta_enabled_info(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_oce_sap_enabled_info() - Get OCE feature enable/disable
+ * info for SAP
+ *
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * OCE SAP feature enable value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_oce_sap_enabled_info(struct wlan_objmgr_psoc *psoc,
+					      bool *value)
+{
+	return wlan_mlme_get_oce_sap_enabled_info(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_rts_threshold() - Get the rts threshold config
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_rts_threshold(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value)
+{
+	return wlan_mlme_get_rts_threshold(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_rts_threshold() - Set the rts threshold config
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_rts_threshold(struct wlan_objmgr_psoc *psoc,
+				       uint32_t value)
+{
+	return wlan_mlme_set_rts_threshold(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_frag_threshold() - Get the fragmentation threshold
+ *                                  config
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_frag_threshold(struct wlan_objmgr_psoc *psoc,
+					uint32_t *value)
+{
+	return wlan_mlme_get_frag_threshold(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_frag_threshold() - set the frag threshold config
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_frag_threshold(struct wlan_objmgr_psoc *psoc,
+					uint32_t value)
+{
+	return wlan_mlme_set_frag_threshold(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_fils_enabled_info() - Get fils enable/disable info
+ *
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * fils enable value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline
+QDF_STATUS ucfg_mlme_get_fils_enabled_info(struct wlan_objmgr_psoc *psoc,
+					   bool *value)
+{
+	return wlan_mlme_get_fils_enabled_info(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_fils_enabled_info() - Set fils enable info
+ *
+ * @psoc: pointer to psoc object
+ * @value: value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to set the
+ * fils enable value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_fils_enabled_info(struct wlan_objmgr_psoc *psoc,
+					   bool value)
+{
+	return wlan_mlme_set_fils_enabled_info(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_enable_bcast_probe_rsp() - Set enable bcast probe resp info
+ * @psoc: pointer to psoc object
+ * @value: value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to set the
+ * enable bcast probe resp info
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_enable_bcast_probe_rsp(struct wlan_objmgr_psoc *psoc,
+						bool value)
+{
+	return wlan_mlme_set_enable_bcast_probe_rsp(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_vht_ch_width() - set the vht supported channel width cfg
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_vht_ch_width(struct wlan_objmgr_psoc *psoc,
+				      uint8_t value)
+{
+	return wlan_mlme_cfg_set_vht_chan_width(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_get_vht_chan_width() - gets vht supported channel width into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline
+QDF_STATUS ucfg_mlme_cfg_get_vht_chan_width(struct wlan_objmgr_psoc *psoc,
+					    uint8_t *value)
+{
+	return wlan_mlme_cfg_get_vht_chan_width(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_set_vht_ldpc_coding_cap() - sets vht ldpc coding cap into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_set_vht_ldpc_coding_cap(struct wlan_objmgr_psoc *psoc,
+				      bool value)
+{
+	return wlan_mlme_cfg_set_vht_ldpc_coding_cap(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_get_short_gi_160_mhz() - Get SHORT GI 160MHZ from cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_get_short_gi_160_mhz(struct wlan_objmgr_psoc *psoc,
+				   bool *value)
+{
+	return wlan_mlme_cfg_get_short_gi_160_mhz(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_set_short_gi_160_mhz() - sets basic set SHORT GI 160MHZ into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_set_short_gi_160_mhz(struct wlan_objmgr_psoc *psoc,
+				   bool value)
+{
+	return wlan_mlme_cfg_set_short_gi_160_mhz(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_get_vht_tx_stbc() - gets vht tx stbc from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_get_vht_tx_stbc(struct wlan_objmgr_psoc *psoc,
+			      bool *value)
+{
+	return wlan_mlme_cfg_get_vht_tx_stbc(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_get_vht_rx_stbc() - gets vht rx stbc from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_get_vht_rx_stbc(struct wlan_objmgr_psoc *psoc,
+			      bool *value)
+{
+	return wlan_mlme_cfg_get_vht_rx_stbc(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp() - sets vht Beamformee antenna
+ * support cap into cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(struct wlan_objmgr_psoc *psoc,
+				       uint8_t value)
+{
+	return wlan_mlme_cfg_set_vht_tx_bfee_ant_supp(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp() - gets vht Beamformee antenna
+ * support cap into cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *value)
+{
+	return wlan_mlme_cfg_get_vht_tx_bfee_ant_supp(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_get_vht_rx_mcs_map() - gets vht rx mcs map from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_get_vht_rx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				 uint32_t *value)
+{
+	return wlan_mlme_cfg_get_vht_rx_mcs_map(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_set_vht_rx_mcs_map() - sets rx mcs map into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_set_vht_rx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				 uint32_t value)
+{
+	return wlan_mlme_cfg_set_vht_rx_mcs_map(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_get_vht_tx_mcs_map() - gets vht tx mcs map from
+ * cfg item
+ * @psoc: psoc context
+ * @value: pointer to get required data
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_get_vht_tx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				 uint32_t *value)
+{
+	return wlan_mlme_cfg_get_vht_tx_mcs_map(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_set_vht_tx_mcs_map() - sets tx mcs map into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_set_vht_tx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				 uint32_t value)
+{
+	return wlan_mlme_cfg_set_vht_tx_mcs_map(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_set_vht_rx_supp_data_rate() - sets rx supported data
+ * rate into cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_set_vht_rx_supp_data_rate(struct wlan_objmgr_psoc *psoc,
+					uint32_t value)
+{
+	return wlan_mlme_cfg_set_vht_rx_supp_data_rate(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_set_vht_tx_supp_data_rate() - sets tx supported data rate into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_set_vht_tx_supp_data_rate(struct wlan_objmgr_psoc *psoc,
+					uint32_t value)
+{
+	return wlan_mlme_cfg_set_vht_tx_supp_data_rate(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_get_vht_basic_mcs_set() - gets basic mcs set from
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_get_vht_basic_mcs_set(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	return wlan_mlme_cfg_get_vht_basic_mcs_set(psoc, value);
+}
+
+/**
+ * ucfg_mlme_cfg_set_vht_basic_mcs_set() - sets basic mcs set into
+ * cfg item
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_cfg_set_vht_basic_mcs_set(struct wlan_objmgr_psoc *psoc,
+				    uint32_t value)
+{
+	return wlan_mlme_cfg_set_vht_basic_mcs_set(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht_enable_tx_bf() - gets enable TXBF for 20MHZ
+ * for 11ac
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht_enable_tx_bf(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	return wlan_mlme_get_vht_enable_tx_bf(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht_tx_su_beamformer() - gets enable tx_su_beamformer
+ * for 11ac
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht_tx_su_beamformer(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	return wlan_mlme_get_vht_tx_su_beamformer(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht_channel_width() - gets Channel width capability
+ * for 11ac
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht_channel_width(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	return wlan_mlme_get_vht_channel_width(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht_rx_mcs_8_9() - VHT Rx MCS capability for 1x1 mode
+ * for 11ac
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht_rx_mcs_8_9(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	return wlan_mlme_get_vht_rx_mcs_8_9(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht_tx_mcs_8_9() - VHT Tx MCS capability for 1x1 mode
+ * for 11ac
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht_tx_mcs_8_9(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	return wlan_mlme_get_vht_tx_mcs_8_9(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht_rx_mcs_2x2() - VHT Rx MCS capability for 2x2 mode
+ * for 11ac
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht_rx_mcs_2x2(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	return wlan_mlme_get_vht_rx_mcs_2x2(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht_tx_mcs_2x2() - VHT Tx MCS capability for 2x2 mode
+ * for 11ac
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht_tx_mcs_2x2(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	return wlan_mlme_get_vht_tx_mcs_2x2(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht20_mcs9() - Enables VHT MCS9 in 20M BW operation
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht20_mcs9(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	return wlan_mlme_get_vht20_mcs9(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht_enable2x2() - Enables/disables VHT Tx/Rx MCS values for 2x2
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht_enable2x2(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	return wlan_mlme_get_vht_enable2x2(psoc, value);
+}
+
+/**
+ * ucfg_mlme_set_vht_enable2x2() - Enables/disables VHT Tx/Rx MCS values for 2x2
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_set_vht_enable2x2(struct wlan_objmgr_psoc *psoc, bool value)
+{
+	return wlan_mlme_set_vht_enable2x2(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht_enable_paid() - Enables/disables paid feature
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht_enable_paid(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	return wlan_mlme_get_vht_enable_paid(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht_enable_gid() - Enables/disables gid feature
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht_enable_gid(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	return wlan_mlme_get_vht_enable_gid(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vht_for_24ghz() - Enables/disables vht for 24ghz
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vht_for_24ghz(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	return wlan_mlme_get_vht_for_24ghz(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_vendor_vht_for_24ghz() - Enables/disables vendor vht for 24ghz
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_vendor_vht_for_24ghz(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	return wlan_mlme_get_vendor_vht_for_24ghz(psoc, value);
+}
+
+/**
+ * ucfg_mlme_update_vht_cap() - Update vht capabilities
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_update_vht_cap(struct wlan_objmgr_psoc *psoc,
+			 struct wma_tgt_vht_cap *cfg)
+{
+	return mlme_update_vht_cap(psoc, cfg);
+}
+
+/**
+ * ucfg_mlme_update_nss_vht_cap() -Update the number of spatial
+ * streams supported for vht
+ * @psoc: psoc context
+ * @value: data to be set
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers to get the
+ * ignore_peer_ht_opmode flag value
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline QDF_STATUS
+ucfg_mlme_update_nss_vht_cap(struct wlan_objmgr_psoc *psoc)
+{
+	return mlme_update_nss_vht_cap(psoc);
+}
+
+/**
+ * ucfg_mlme_get_opr_rate_set() - Get operational rate set
+ * @psoc: pointer to psoc object
+ * @buf: buffer to get rates set
+ * @len: length of the buffer
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_opr_rate_set(struct wlan_objmgr_psoc *psoc, uint8_t *buf,
+			   qdf_size_t *len);
+
+/**
+ * ucfg_mlme_get_ext_opr_rate_set() - Get operational rate set
+ * @psoc: pointer to psoc object
+ * @buf: buffer to get rates set
+ * @len: length of the buffer
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_ext_opr_rate_set(struct wlan_objmgr_psoc *psoc, uint8_t *buf,
+			       qdf_size_t *len);
+
+/**
+ * ucfg_mlme_get_supported_mcs_set() - Get Supported MCS set
+ * @psoc: pointer to psoc object
+ * @buf:  caller buffer to copy mcs set info
+ * @len: length of the buffer
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_supported_mcs_set(struct wlan_objmgr_psoc *psoc, uint8_t *buf,
+				qdf_size_t *len);
+
+/**
+ * ucfg_mlme_set_supported_mcs_set() - Get Supported MCS set
+ * @psoc: pointer to psoc object
+ * @buf: caller buffer having mcs set info
+ * @len: length of the buffer
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_supported_mcs_set(struct wlan_objmgr_psoc *psoc, uint8_t *buf,
+				qdf_size_t len);
+
+/**
+ * ucfg_mlme_get_current_mcs_set() - Get current MCS set
+ * @psoc: pointer to psoc object
+ * @buf:  caller buffer to copy mcs set info
+ * @len: length of the buffer
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_current_mcs_set(struct wlan_objmgr_psoc *psoc, uint8_t *buf,
+			      qdf_size_t *len);
+/**
+ * ucfg_mlme_get_wmm_dir_ac_vi() - Get TSPEC direction
+ * for VI
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_dir_ac_vi(struct wlan_objmgr_psoc *psoc,
+			    uint8_t *value)
+{
+	return wlan_mlme_get_wmm_dir_ac_vi(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_nom_msdu_size_ac_vi() - Get normal
+ * MSDU size for VI
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_nom_msdu_size_ac_vi(struct wlan_objmgr_psoc *psoc,
+				      uint16_t *value)
+{
+	return wlan_mlme_get_wmm_nom_msdu_size_ac_vi(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_mean_data_rate_ac_vi() - mean data
+ * rate for VI
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_mean_data_rate_ac_vi(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value)
+{
+	return wlan_mlme_get_wmm_mean_data_rate_ac_vi(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_min_phy_rate_ac_vi() - min PHY
+ * rate for VI
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_min_phy_rate_ac_vi(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *value)
+{
+	return wlan_mlme_get_wmm_min_phy_rate_ac_vi(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_sba_ac_vi() - surplus bandwidth
+ * allowance for VI
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_sba_ac_vi(struct wlan_objmgr_psoc *psoc, uint16_t *value)
+{
+	return wlan_mlme_get_wmm_sba_ac_vi(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_uapsd_vi_srv_intv() - Get Uapsd service
+ * interval for video
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_uapsd_vi_srv_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	return wlan_mlme_get_wmm_uapsd_vi_srv_intv(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_uapsd_vi_sus_intv() - Get Uapsd suspension
+ * interval for video
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_uapsd_vi_sus_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	return wlan_mlme_get_wmm_uapsd_vi_sus_intv(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_dir_ac_be() - Get TSPEC direction
+ * for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_dir_ac_be(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	return wlan_mlme_get_wmm_dir_ac_be(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_nom_msdu_size_ac_be() - Get normal
+ * MSDU size for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_nom_msdu_size_ac_be(struct wlan_objmgr_psoc *psoc,
+				      uint16_t *value)
+{
+	return wlan_mlme_get_wmm_nom_msdu_size_ac_be(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_mean_data_rate_ac_be() - mean data
+ * rate for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_mean_data_rate_ac_be(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value)
+{
+	return wlan_mlme_get_wmm_mean_data_rate_ac_be(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_min_phy_rate_ac_be() - min PHY
+ * rate for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_min_phy_rate_ac_be(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *value)
+{
+	return wlan_mlme_get_wmm_min_phy_rate_ac_be(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_sba_ac_be() - surplus bandwidth
+ * allowance for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_sba_ac_be(struct wlan_objmgr_psoc *psoc, uint16_t *value)
+{
+	return wlan_mlme_get_wmm_sba_ac_be(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_uapsd_be_srv_intv() - Get Uapsd service
+ * interval for BE
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_uapsd_be_srv_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	return wlan_mlme_get_wmm_uapsd_be_srv_intv(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_uapsd_be_sus_intv() - Get Uapsd suspension
+ * interval for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_uapsd_be_sus_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	return wlan_mlme_get_wmm_uapsd_be_sus_intv(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_dir_ac_bk() - Get TSPEC direction
+ * for BK
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_dir_ac_bk(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	return wlan_mlme_get_wmm_dir_ac_bk(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_nom_msdu_size_ac_be() - Get normal
+ * MSDU size for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_nom_msdu_size_ac_bk(struct wlan_objmgr_psoc *psoc,
+				      uint16_t *value)
+{
+	return wlan_mlme_get_wmm_nom_msdu_size_ac_bk(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_mean_data_rate_ac_bk() - mean data
+ * rate for BK
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_mean_data_rate_ac_bk(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value)
+{
+	return wlan_mlme_get_wmm_mean_data_rate_ac_bk(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_min_phy_rate_ac_bk() - min PHY
+ * rate for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_min_phy_rate_ac_bk(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *value)
+{
+	return wlan_mlme_get_wmm_min_phy_rate_ac_bk(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_sba_ac_bk() - surplus bandwidth
+ * allowance for BE
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_sba_ac_bk(struct wlan_objmgr_psoc *psoc, uint16_t *value)
+{
+	return wlan_mlme_get_wmm_sba_ac_bk(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_uapsd_bk_srv_intv() - Get Uapsd service
+ * interval for BK
+ * @psoc: pointer to psoc object
+ * @value: pointer to the value which will be filled for the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_uapsd_bk_srv_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	return wlan_mlme_get_wmm_uapsd_bk_srv_intv(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_uapsd_bk_sus_intv() - Get Uapsd suspension
+ * interval for BK
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_uapsd_bk_sus_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	return wlan_mlme_get_wmm_uapsd_bk_sus_intv(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_mode() - Enable WMM feature
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_mode(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	return wlan_mlme_get_wmm_mode(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_80211e_is_enabled() - Enable 802.11e feature
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_80211e_is_enabled(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	return wlan_mlme_get_80211e_is_enabled(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_wmm_uapsd_mask() - setup U-APSD mask for ACs
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_wmm_uapsd_mask(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	return wlan_mlme_get_wmm_uapsd_mask(psoc, value);
+}
+
+/**
+ * ucfg_mlme_get_implicit_qos_is_enabled() - Enable implicit QOS
+ * @psoc: pointer to psoc object
+ * @value: Value that needs to be set from the caller
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_get_implicit_qos_is_enabled(struct wlan_objmgr_psoc *psoc,
+				      bool *value)
+{
+	return wlan_mlme_get_implicit_qos_is_enabled(psoc, value);
+}
+
+#endif /* _WLAN_MLME_UCFG_API_H_ */
diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c
new file mode 100644
index 0000000..cd7fcdd
--- /dev/null
+++ b/components/mlme/dispatcher/src/wlan_mlme_api.c
@@ -0,0 +1,2414 @@
+/*
+ * Copyright (c) 2018 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 public APIs exposed by the mlme component
+ */
+
+#include "cfg_ucfg_api.h"
+#include "wlan_mlme_main.h"
+#include "wlan_mlme_ucfg_api.h"
+#include "wma_types.h"
+#include "wmi_unified.h"
+#include "wma.h"
+#include "wma_internal.h"
+
+QDF_STATUS wlan_mlme_get_cfg_str(uint8_t *dst, struct mlme_cfg_str *cfg_str,
+				 qdf_size_t *len)
+{
+	if (*len < cfg_str->len) {
+		mlme_err("Invalid len %zd", *len);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*len = cfg_str->len;
+	qdf_mem_copy(dst, cfg_str->data, *len);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_cfg_str(uint8_t *src, struct mlme_cfg_str *dst_cfg_str,
+				 qdf_size_t len)
+{
+	if (len > dst_cfg_str->max_len) {
+		mlme_err("Invalid len %zd (>%zd)", len,
+			 dst_cfg_str->max_len);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	dst_cfg_str->len = len;
+	qdf_mem_copy(dst_cfg_str->data, src, len);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_ht_cap_info(struct wlan_objmgr_psoc *psoc,
+				     struct mlme_ht_capabilities_info
+				     *ht_cap_info)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*ht_cap_info = mlme_obj->cfg.ht_caps.ht_cap_info;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_ht_cap_info(struct wlan_objmgr_psoc *psoc,
+				     struct mlme_ht_capabilities_info
+				     ht_cap_info)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.ht_caps.ht_cap_info = ht_cap_info;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_max_amsdu_num(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.ht_caps.max_num_amsdu;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_max_amsdu_num(struct wlan_objmgr_psoc *psoc,
+				       uint8_t value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!cfg_in_range(CFG_MAX_AMSDU_NUM, value)) {
+		mlme_err("Error in setting Max AMSDU Num");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mlme_obj->cfg.ht_caps.max_num_amsdu = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_ht_mpdu_density(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = (uint8_t)mlme_obj->cfg.ht_caps.ampdu_params.mpdu_density;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_ht_mpdu_density(struct wlan_objmgr_psoc *psoc,
+					 uint8_t value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!cfg_in_range(CFG_MPDU_DENSITY, value)) {
+		mlme_err("Invalid value %d", value);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mlme_obj->cfg.ht_caps.ampdu_params.mpdu_density = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_band_capability(struct wlan_objmgr_psoc *psoc,
+					 uint8_t *band_capability)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*band_capability = mlme_obj->cfg.gen.band_capability;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_band_capability(struct wlan_objmgr_psoc *psoc,
+					 uint8_t band_capability)
+
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.gen.band_capability = band_capability;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_prevent_link_down(struct wlan_objmgr_psoc *psoc,
+					   bool *prevent_link_down)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*prevent_link_down = mlme_obj->cfg.gen.prevent_link_down;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_select_5ghz_margin(struct wlan_objmgr_psoc *psoc,
+					    uint8_t *select_5ghz_margin)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*select_5ghz_margin = mlme_obj->cfg.gen.select_5ghz_margin;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_crash_inject(struct wlan_objmgr_psoc *psoc,
+				      bool *crash_inject)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*crash_inject = mlme_obj->cfg.gen.crash_inject;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_lpass_support(struct wlan_objmgr_psoc *psoc,
+				       bool *lpass_support)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*lpass_support = mlme_obj->cfg.gen.lpass_support;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_self_recovery(struct wlan_objmgr_psoc *psoc,
+				       bool *self_recovery)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*self_recovery = mlme_obj->cfg.gen.self_recovery;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_sub_20_chan_width(struct wlan_objmgr_psoc *psoc,
+					   uint8_t *sub_20_chan_width)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*sub_20_chan_width = mlme_obj->cfg.gen.sub_20_chan_width;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_fw_timeout_crash(struct wlan_objmgr_psoc *psoc,
+					  bool *fw_timeout_crash)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*fw_timeout_crash = mlme_obj->cfg.gen.fw_timeout_crash;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_ito_repeat_count(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *ito_repeat_count)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*ito_repeat_count = mlme_obj->cfg.gen.ito_repeat_count;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wlan_mlme_get_sap_inactivity_override(struct wlan_objmgr_psoc *psoc,
+					   bool *val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return;
+	}
+	*val = mlme_obj->cfg.qos_mlme_params.sap_max_inactivity_override;
+}
+
+QDF_STATUS wlan_mlme_get_acs_with_more_param(struct wlan_objmgr_psoc *psoc,
+					     bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.acs.is_acs_with_more_param;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_auto_channel_weight(struct wlan_objmgr_psoc *psoc,
+					     uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.acs.auto_channel_select_weight;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_vendor_acs_support(struct wlan_objmgr_psoc *psoc,
+					    bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.acs.is_vendor_acs_support;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_acs_support_for_dfs_ltecoex(struct wlan_objmgr_psoc *psoc,
+					  bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.acs.is_acs_support_for_dfs_ltecoex;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_external_acs_policy(struct wlan_objmgr_psoc *psoc,
+				  bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.acs.is_external_acs_policy;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_tx_chainmask_cck(struct wlan_objmgr_psoc *psoc,
+					  bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.chainmask_cfg.tx_chain_mask_cck;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_tx_chainmask_1ss(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.chainmask_cfg.tx_chain_mask_1ss;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_num_11b_tx_chains(struct wlan_objmgr_psoc *psoc,
+					   uint16_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.chainmask_cfg.num_11b_tx_chains;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_num_11ag_tx_chains(struct wlan_objmgr_psoc *psoc,
+					    uint16_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.chainmask_cfg.num_11ag_tx_chains;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_configure_chain_mask(struct wlan_objmgr_psoc *psoc,
+					  uint8_t session_id)
+{
+	int ret_val;
+	uint8_t ch_msk_val;
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_debug("txchainmask1x1: %d rxchainmask1x1: %d",
+		   mlme_obj->cfg.chainmask_cfg.txchainmask1x1,
+		   mlme_obj->cfg.chainmask_cfg.rxchainmask1x1);
+	mlme_debug("tx_chain_mask_2g: %d, rx_chain_mask_2g: %d",
+		   mlme_obj->cfg.chainmask_cfg.tx_chain_mask_2g,
+		   mlme_obj->cfg.chainmask_cfg.rx_chain_mask_2g);
+	mlme_debug("tx_chain_mask_5g: %d, rx_chain_mask_5g: %d",
+		   mlme_obj->cfg.chainmask_cfg.tx_chain_mask_5g,
+		   mlme_obj->cfg.chainmask_cfg.rx_chain_mask_5g);
+
+	if (mlme_obj->cfg.chainmask_cfg.txchainmask1x1) {
+		ch_msk_val = mlme_obj->cfg.chainmask_cfg.txchainmask1x1;
+		ret_val = wma_cli_set_command(session_id,
+					      WMI_PDEV_PARAM_TX_CHAIN_MASK,
+					      ch_msk_val, PDEV_CMD);
+		if (ret_val)
+			return QDF_STATUS_E_FAILURE;
+	}
+
+	if (mlme_obj->cfg.chainmask_cfg.rxchainmask1x1) {
+		ch_msk_val = mlme_obj->cfg.chainmask_cfg.rxchainmask1x1;
+		ret_val = wma_cli_set_command(session_id,
+					      WMI_PDEV_PARAM_RX_CHAIN_MASK,
+					      ch_msk_val, PDEV_CMD);
+		if (ret_val)
+			return QDF_STATUS_E_FAILURE;
+	}
+
+	if (mlme_obj->cfg.chainmask_cfg.txchainmask1x1 ||
+	    mlme_obj->cfg.chainmask_cfg.rxchainmask1x1) {
+		mlme_debug("band agnostic tx/rx chain mask set. skip per band chain mask");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (mlme_obj->cfg.chainmask_cfg.tx_chain_mask_2g) {
+		ch_msk_val = mlme_obj->cfg.chainmask_cfg.tx_chain_mask_2g;
+		ret_val = wma_cli_set_command(session_id,
+					      WMI_PDEV_PARAM_TX_CHAIN_MASK_2G,
+					      ch_msk_val, PDEV_CMD);
+		if (0 != ret_val)
+			return QDF_STATUS_E_FAILURE;
+	}
+
+	if (mlme_obj->cfg.chainmask_cfg.rx_chain_mask_2g) {
+		ch_msk_val = mlme_obj->cfg.chainmask_cfg.rx_chain_mask_2g;
+		ret_val = wma_cli_set_command(session_id,
+					      WMI_PDEV_PARAM_RX_CHAIN_MASK_2G,
+					      ch_msk_val, PDEV_CMD);
+		if (0 != ret_val)
+			return QDF_STATUS_E_FAILURE;
+	}
+
+	if (mlme_obj->cfg.chainmask_cfg.tx_chain_mask_5g) {
+		ch_msk_val = mlme_obj->cfg.chainmask_cfg.tx_chain_mask_5g;
+		ret_val = wma_cli_set_command(session_id,
+					      WMI_PDEV_PARAM_TX_CHAIN_MASK_5G,
+					      ch_msk_val, PDEV_CMD);
+		if (0 != ret_val)
+			return QDF_STATUS_E_FAILURE;
+	}
+
+	if (mlme_obj->cfg.chainmask_cfg.rx_chain_mask_5g) {
+		ch_msk_val = mlme_obj->cfg.chainmask_cfg.rx_chain_mask_5g;
+		ret_val = wma_cli_set_command(session_id,
+					      WMI_PDEV_PARAM_RX_CHAIN_MASK_5G,
+					      ch_msk_val, PDEV_CMD);
+		if (0 != ret_val)
+			return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_manufacturer_name(struct wlan_objmgr_psoc *psoc,
+				uint8_t *pbuf, uint32_t *plen)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*plen = qdf_str_lcopy(pbuf,
+			      mlme_obj->cfg.product_details.manufacturer_name,
+			      *plen);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_model_number(struct wlan_objmgr_psoc *psoc,
+			   uint8_t *pbuf, uint32_t *plen)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*plen = qdf_str_lcopy(pbuf,
+			      mlme_obj->cfg.product_details.model_number,
+			      *plen);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_model_name(struct wlan_objmgr_psoc *psoc,
+			 uint8_t *pbuf, uint32_t *plen)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*plen = qdf_str_lcopy(pbuf,
+			      mlme_obj->cfg.product_details.model_name,
+			      *plen);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_manufacture_product_version(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *pbuf, uint32_t *plen)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*plen = qdf_str_lcopy(pbuf,
+		     mlme_obj->cfg.product_details.manufacture_product_version,
+		     *plen);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_manufacture_product_name(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *pbuf, uint32_t *plen)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*plen = qdf_str_lcopy(pbuf,
+			mlme_obj->cfg.product_details.manufacture_product_name,
+			*plen);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_dir_ac_vo(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*value = mlme_obj->cfg.wmm_params.ac_vo.dir_ac_vo;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS wlan_mlme_get_wmm_nom_msdu_size_ac_vo(struct wlan_objmgr_psoc *psoc,
+						 uint16_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vo.nom_msdu_size_ac_vo;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_mean_data_rate_ac_vo(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("failed to get mlme obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vo.mean_data_rate_ac_vo;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_min_phy_rate_ac_vo(struct wlan_objmgr_psoc *psoc,
+						uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("failed to get mlme obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vo.min_phy_rate_ac_vo;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_sba_ac_vo(struct wlan_objmgr_psoc *psoc,
+				       uint16_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vo.sba_ac_vo;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_uapsd_vo_srv_intv(struct wlan_objmgr_psoc *psoc,
+					       uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vo.uapsd_vo_srv_intv;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_uapsd_vo_sus_intv(struct wlan_objmgr_psoc *psoc,
+					       uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vo.uapsd_vo_sus_intv;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_dir_ac_vi(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vi.dir_ac_vi;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_nom_msdu_size_ac_vi(struct wlan_objmgr_psoc *psoc,
+						 uint16_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value =
+		mlme_obj->cfg.wmm_params.ac_vi.nom_msdu_size_ac_vi;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_mean_data_rate_ac_vi(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vi.mean_data_rate_ac_vi;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_min_phy_rate_ac_vi(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vi.min_phy_rate_ac_vi;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_sba_ac_vi(struct wlan_objmgr_psoc *psoc,
+				       uint16_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vi.sba_ac_vi;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_uapsd_vi_srv_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vi.uapsd_vi_srv_intv;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_uapsd_vi_sus_intv(struct wlan_objmgr_psoc *psoc,
+						uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_vi.uapsd_vi_sus_intv;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_dir_ac_be(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_be.dir_ac_be;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_nom_msdu_size_ac_be(struct wlan_objmgr_psoc *psoc,
+						 uint16_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_be.nom_msdu_size_ac_be;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_mean_data_rate_ac_be(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_be.mean_data_rate_ac_be;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_min_phy_rate_ac_be(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_be.min_phy_rate_ac_be;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_sba_ac_be(struct wlan_objmgr_psoc *psoc, uint16_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_be.sba_ac_be;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_uapsd_be_srv_intv(struct wlan_objmgr_psoc *psoc,
+					       uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_be.uapsd_be_srv_intv;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_uapsd_be_sus_intv(struct wlan_objmgr_psoc *psoc,
+					       uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_be.uapsd_be_sus_intv;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_dir_ac_bk(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_bk.dir_ac_bk;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_wmm_nom_msdu_size_ac_bk(struct wlan_objmgr_psoc *psoc,
+						 uint16_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_bk.nom_msdu_size_ac_bk;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_mean_data_rate_ac_bk(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_bk.mean_data_rate_ac_bk;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_min_phy_rate_ac_bk(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_bk.min_phy_rate_ac_bk;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_sba_ac_bk(struct wlan_objmgr_psoc *psoc, uint16_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_bk.sba_ac_bk;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_uapsd_bk_srv_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_bk.uapsd_bk_srv_intv;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_uapsd_bk_sus_intv(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.ac_bk.uapsd_bk_sus_intv;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_mode(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.wmm_config.wmm_mode;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_80211e_is_enabled(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.wmm_config.b80211e_is_enabled;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_wmm_uapsd_mask(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.wmm_config.uapsd_mask;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_implicit_qos_is_enabled(struct wlan_objmgr_psoc *psoc,
+				      bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.wmm_params.wmm_config.bimplicit_qos_enabled;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_sap_listen_interval(struct wlan_objmgr_psoc *psoc,
+					     int value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (cfg_in_range(CFG_LISTEN_INTERVAL, value))
+		mlme_obj->cfg.sap_cfg.listen_interval = value;
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_assoc_sta_limit(struct wlan_objmgr_psoc *psoc,
+					 int value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (cfg_in_range(CFG_ASSOC_STA_LIMIT, value))
+		mlme_obj->cfg.sap_cfg.assoc_sta_limit = value;
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_rmc_action_period_freq(struct wlan_objmgr_psoc *psoc,
+						int value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (cfg_in_range(CFG_RMC_ACTION_PERIOD_FREQUENCY, value))
+		mlme_obj->cfg.sap_cfg.rmc_action_period_freq = value;
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_sap_get_peer_info(struct wlan_objmgr_psoc *psoc,
+					   bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.sap_cfg.sap_get_peer_info;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_sap_allow_all_channels(struct wlan_objmgr_psoc *psoc,
+						bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.sap_cfg.sap_allow_all_chan_param_name;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_sap_max_peers(struct wlan_objmgr_psoc *psoc,
+				       int *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.sap_cfg.sap_max_no_peers;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_sap_max_peers(struct wlan_objmgr_psoc *psoc,
+				       int value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (cfg_in_range(CFG_RMC_ACTION_PERIOD_FREQUENCY, value))
+		mlme_obj->cfg.sap_cfg.sap_max_no_peers = value;
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_sap_max_offload_peers(struct wlan_objmgr_psoc *psoc,
+					       int *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.sap_cfg.sap_max_offload_peers;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_sap_max_offload_reorder_buffs(struct wlan_objmgr_psoc
+						       *psoc, int *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.sap_cfg.sap_max_offload_reorder_buffs;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_sap_chn_switch_bcn_count(struct wlan_objmgr_psoc *psoc,
+						  int *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.sap_cfg.sap_ch_switch_beacon_cnt;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_sap_chn_switch_mode(struct wlan_objmgr_psoc *psoc,
+					     bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.sap_cfg.sap_ch_switch_mode;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_sap_internal_restart(struct wlan_objmgr_psoc *psoc,
+					      bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.sap_cfg.sap_internal_restart;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_sap_reduced_beacon_interval(struct wlan_objmgr_psoc
+						     *psoc, int *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.sap_cfg.reduced_beacon_interval;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_sap_chan_switch_rate_enabled(struct wlan_objmgr_psoc
+						      *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.sap_cfg.chan_switch_hostapd_rate_enabled_name;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_oce_sta_enabled_info(struct wlan_objmgr_psoc *psoc,
+					      bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.oce.oce_sta_enabled;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_oce_sap_enabled_info(struct wlan_objmgr_psoc *psoc,
+					      bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.oce.oce_sap_enabled;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_rts_threshold(struct wlan_objmgr_psoc *psoc,
+				       uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*value = mlme_obj->cfg.threshold.rts_threshold;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_rts_threshold(struct wlan_objmgr_psoc *psoc,
+				       uint32_t value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+	tp_wma_handle wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: wma_handle is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.threshold.rts_threshold = value;
+	wma_update_rts_params(wma_handle, value);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_frag_threshold(struct wlan_objmgr_psoc *psoc,
+					uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.threshold.frag_threshold;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_frag_threshold(struct wlan_objmgr_psoc *psoc,
+					uint32_t value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+	tp_wma_handle wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: wma_handle is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.threshold.frag_threshold = value;
+	wma_update_frag_params(wma_handle,
+			       value);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_fils_enabled_info(struct wlan_objmgr_psoc *psoc,
+					   bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.oce.fils_enabled;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_fils_enabled_info(struct wlan_objmgr_psoc *psoc,
+					   bool value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.oce.fils_enabled = value;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_set_enable_bcast_probe_rsp(struct wlan_objmgr_psoc *psoc,
+						bool value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc);
+
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.oce.enable_bcast_probe_rsp = value;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mlme_get_edca_params(struct wlan_mlme_edca_params *edca_params,
+				     uint8_t *data, enum e_edca_type edca_ac)
+{
+	qdf_size_t len;
+
+	switch (edca_ac) {
+	case edca_ani_acbe_local:
+		len = edca_params->ani_acbe_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->ani_acbe_l, &len);
+		break;
+
+	case edca_ani_acbk_local:
+		len = edca_params->ani_acbk_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->ani_acbk_l, &len);
+		break;
+
+	case edca_ani_acvi_local:
+		len = edca_params->ani_acvi_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->ani_acvi_l, &len);
+		break;
+
+	case edca_ani_acvo_local:
+		len = edca_params->ani_acvo_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->ani_acvo_l, &len);
+		break;
+
+	case edca_ani_acbk_bcast:
+		len = edca_params->ani_acbk_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->ani_acbk_b, &len);
+		break;
+
+	case edca_ani_acbe_bcast:
+		len = edca_params->ani_acbe_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->ani_acbe_b, &len);
+		break;
+
+	case edca_ani_acvi_bcast:
+		len = edca_params->ani_acvi_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->ani_acvi_b, &len);
+		break;
+
+	case edca_ani_acvo_bcast:
+		len = edca_params->ani_acvo_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->ani_acvo_b, &len);
+		break;
+
+	case edca_wme_acbe_local:
+		len = edca_params->wme_acbe_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->wme_acbe_l, &len);
+		break;
+
+	case edca_wme_acbk_local:
+		len = edca_params->wme_acbk_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->wme_acbk_l, &len);
+		break;
+
+	case edca_wme_acvi_local:
+		len = edca_params->wme_acvi_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->wme_acvi_l, &len);
+		break;
+
+	case edca_wme_acvo_local:
+		len = edca_params->wme_acvo_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->wme_acvo_l, &len);
+		break;
+
+	case edca_wme_acbe_bcast:
+		len = edca_params->wme_acbe_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->wme_acbe_b, &len);
+		break;
+
+	case edca_wme_acbk_bcast:
+		len = edca_params->wme_acbk_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->wme_acbk_b, &len);
+		break;
+
+	case edca_wme_acvi_bcast:
+		len = edca_params->wme_acvi_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->wme_acvi_b, &len);
+		break;
+
+	case edca_wme_acvo_bcast:
+		len = edca_params->wme_acvo_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->wme_acvo_b, &len);
+		break;
+
+	case edca_etsi_acbe_local:
+		len = edca_params->etsi_acbe_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->etsi_acbe_l, &len);
+		break;
+
+	case edca_etsi_acbk_local:
+		len = edca_params->etsi_acbk_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->etsi_acbk_l, &len);
+		break;
+
+	case edca_etsi_acvi_local:
+		len = edca_params->etsi_acvi_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->etsi_acvi_l, &len);
+		break;
+
+	case edca_etsi_acvo_local:
+		len = edca_params->etsi_acvo_l.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->etsi_acvo_l, &len);
+		break;
+
+	case edca_etsi_acbe_bcast:
+		len = edca_params->etsi_acbe_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->etsi_acbe_b, &len);
+		break;
+
+	case edca_etsi_acbk_bcast:
+		len = edca_params->etsi_acbk_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->etsi_acbk_b, &len);
+		break;
+
+	case edca_etsi_acvi_bcast:
+		len = edca_params->etsi_acvi_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->etsi_acvi_b, &len);
+		break;
+
+	case edca_etsi_acvo_bcast:
+		len = edca_params->etsi_acvo_b.len;
+		wlan_mlme_get_cfg_str(data, &edca_params->etsi_acvo_b, &len);
+		break;
+	default:
+		mlme_err("Invalid edca access category");
+		return QDF_STATUS_E_INVAL;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS mlme_get_wep_key(struct wlan_mlme_wep_cfg *wep_params,
+			    enum wep_key_id wep_keyid, uint8_t *default_key,
+			    qdf_size_t key_len)
+{
+	switch (wep_keyid) {
+	case MLME_WEP_DEFAULT_KEY_1:
+		wlan_mlme_get_cfg_str(default_key,
+				      &wep_params->wep_default_key_1,
+				      &key_len);
+		break;
+
+	case MLME_WEP_DEFAULT_KEY_2:
+		wlan_mlme_get_cfg_str(default_key,
+				      &wep_params->wep_default_key_2,
+				      &key_len);
+		break;
+
+	case MLME_WEP_DEFAULT_KEY_3:
+		wlan_mlme_get_cfg_str(default_key,
+				      &wep_params->wep_default_key_3,
+				      &key_len);
+		break;
+
+	case MLME_WEP_DEFAULT_KEY_4:
+		wlan_mlme_get_cfg_str(default_key,
+				      &wep_params->wep_default_key_4,
+				      &key_len);
+		break;
+
+	default:
+		mlme_err("Invalid key id:%d", wep_keyid);
+		return QDF_STATUS_E_INVAL;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS mlme_set_wep_key(struct wlan_mlme_wep_cfg *wep_params,
+			    enum wep_key_id wep_keyid, uint8_t *key_to_set,
+			    qdf_size_t len)
+{
+	if (len == 0) {
+		mlme_debug("WEP set key length is zero");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	switch (wep_keyid) {
+	case MLME_WEP_DEFAULT_KEY_1:
+		wlan_mlme_set_cfg_str(key_to_set,
+				      &wep_params->wep_default_key_1,
+				      len);
+		break;
+
+	case MLME_WEP_DEFAULT_KEY_2:
+		wlan_mlme_set_cfg_str(key_to_set,
+				      &wep_params->wep_default_key_2,
+				      len);
+		break;
+
+	case MLME_WEP_DEFAULT_KEY_3:
+		wlan_mlme_set_cfg_str(key_to_set,
+				      &wep_params->wep_default_key_3,
+				      len);
+		break;
+
+	case MLME_WEP_DEFAULT_KEY_4:
+		wlan_mlme_set_cfg_str(key_to_set,
+				      &wep_params->wep_default_key_4,
+				      len);
+		break;
+
+	default:
+		mlme_err("Invalid key id:%d", wep_keyid);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_set_vht_chan_width(struct wlan_objmgr_psoc *psoc, uint8_t value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.vht_caps.vht_cap_info.supp_chan_width = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_get_vht_chan_width(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.supp_chan_width;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_set_vht_ldpc_coding_cap(struct wlan_objmgr_psoc *psoc,
+				      bool value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.vht_caps.vht_cap_info.ldpc_coding_cap = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_set_short_gi_160_mhz(struct wlan_objmgr_psoc *psoc,
+				   bool value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.vht_caps.vht_cap_info.short_gi_160mhz = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_get_short_gi_160_mhz(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.short_gi_160mhz;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_get_vht_tx_stbc(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.tx_stbc;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_get_vht_rx_stbc(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.rx_stbc;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_set_vht_tx_bfee_ant_supp(struct wlan_objmgr_psoc *psoc,
+				       uint8_t value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.vht_caps.vht_cap_info.tx_bfee_ant_supp = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_get_vht_tx_bfee_ant_supp(struct wlan_objmgr_psoc *psoc,
+				       uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.tx_bfee_ant_supp;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_get_vht_rx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				 uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.rx_mcs_map;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_set_vht_rx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				 uint32_t value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.vht_caps.vht_cap_info.rx_mcs_map = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_get_vht_tx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				 uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.tx_mcs_map;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_set_vht_tx_mcs_map(struct wlan_objmgr_psoc *psoc,
+				 uint32_t value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.vht_caps.vht_cap_info.tx_mcs_map = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_set_vht_rx_supp_data_rate(struct wlan_objmgr_psoc *psoc,
+				        uint32_t value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.vht_caps.vht_cap_info.rx_supp_data_rate = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_set_vht_tx_supp_data_rate(struct wlan_objmgr_psoc *psoc,
+				        uint32_t value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.vht_caps.vht_cap_info.tx_supp_data_rate = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_get_vht_basic_mcs_set(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.basic_mcs_set;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_cfg_set_vht_basic_mcs_set(struct wlan_objmgr_psoc *psoc,
+				    uint32_t value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.vht_caps.vht_cap_info.basic_mcs_set = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vht_enable_tx_bf(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.su_bformee;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vht_tx_su_beamformer(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.su_bformer;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vht_channel_width(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.channel_width;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS
+wlan_mlme_get_vht_rx_mcs_8_9(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.rx_mcs;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vht_tx_mcs_8_9(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.tx_mcs;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vht_rx_mcs_2x2(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.rx_mcs2x2;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vht_tx_mcs_2x2(struct wlan_objmgr_psoc *psoc, uint8_t *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.tx_mcs2x2;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vht20_mcs9(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.enable_vht20_mcs9;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vht_enable2x2(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.enable2x2;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_set_vht_enable2x2(struct wlan_objmgr_psoc *psoc, bool value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_obj->cfg.vht_caps.vht_cap_info.enable2x2 = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vht_enable_paid(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.enable_paid;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vht_enable_gid(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.enable_gid;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vht_for_24ghz(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.b24ghz_band;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_mlme_get_vendor_vht_for_24ghz(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*value = mlme_obj->cfg.vht_caps.vht_cap_info.vendor_24ghz_band;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS mlme_update_vht_cap(struct wlan_objmgr_psoc *psoc,
+			       struct wma_tgt_vht_cap *cfg)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+	struct mlme_vht_capabilities_info *vht_cap_info;
+	uint32_t value = 0;
+	bool hw_rx_ldpc_enabled;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vht_cap_info = &mlme_obj->cfg.vht_caps.vht_cap_info;
+
+	/*
+	 * VHT max MPDU length:
+	 * override if user configured value is too high
+	 * that the target cannot support
+	 */
+	if (vht_cap_info->ampdu_len > cfg->vht_max_mpdu)
+		vht_cap_info->ampdu_len = cfg->vht_max_mpdu;
+
+	value = (CFG_VHT_BASIC_MCS_SET_STADEF & VHT_MCS_1x1) |
+		vht_cap_info->basic_mcs_set;
+	if (vht_cap_info->enable2x2)
+		value = (value & VHT_MCS_2x2) | (vht_cap_info->rx_mcs2x2 << 2);
+	vht_cap_info->basic_mcs_set = value;
+
+	value = (CFG_VHT_RX_MCS_MAP_STADEF & VHT_MCS_1x1) |
+		 vht_cap_info->rx_mcs;
+
+	if (vht_cap_info->enable2x2)
+		value = (value & VHT_MCS_2x2) | (vht_cap_info->rx_mcs2x2 << 2);
+	vht_cap_info->rx_mcs_map = value;
+
+	value = (CFG_VHT_TX_MCS_MAP_STADEF & VHT_MCS_1x1) |
+		 vht_cap_info->tx_mcs;
+	if (vht_cap_info->enable2x2)
+		value = (value & VHT_MCS_2x2) | (vht_cap_info->tx_mcs2x2 << 2);
+	vht_cap_info->tx_mcs_map = value;
+
+	 /* Set HW RX LDPC capability */
+	hw_rx_ldpc_enabled = !!cfg->vht_rx_ldpc;
+	if (hw_rx_ldpc_enabled != vht_cap_info->ldpc_coding_cap)
+		vht_cap_info->ldpc_coding_cap = hw_rx_ldpc_enabled;
+
+	/* set the Guard interval 80MHz */
+	if (vht_cap_info->short_gi_80mhz && !cfg->vht_short_gi_80)
+		vht_cap_info->short_gi_80mhz = cfg->vht_short_gi_80;
+
+	/* Set VHT TX STBC cap */
+	if (vht_cap_info->tx_stbc && !cfg->vht_tx_stbc)
+		vht_cap_info->tx_stbc = cfg->vht_tx_stbc;
+
+	/* Set VHT RX STBC cap */
+	if (vht_cap_info->rx_stbc && !cfg->vht_rx_stbc)
+		vht_cap_info->rx_stbc = cfg->vht_rx_stbc;
+
+	/* Set VHT SU Beamformer cap */
+	if (vht_cap_info->su_bformer && !cfg->vht_su_bformer)
+		vht_cap_info->su_bformer = cfg->vht_su_bformer;
+
+	/* check and update SU BEAMFORMEE capabality */
+	if (vht_cap_info->su_bformee && !cfg->vht_su_bformee)
+		vht_cap_info->su_bformee = cfg->vht_su_bformee;
+
+	/* Set VHT MU Beamformer cap */
+	if (vht_cap_info->mu_bformer && !cfg->vht_mu_bformer)
+		vht_cap_info->mu_bformer = cfg->vht_mu_bformer;
+
+	/* Set VHT MU Beamformee cap */
+	if (vht_cap_info->enable_mu_bformee && !cfg->vht_mu_bformee)
+		vht_cap_info->enable_mu_bformee = cfg->vht_mu_bformee;
+
+	/*
+	 * VHT max AMPDU len exp:
+	 * override if user configured value is too high
+	 * that the target cannot support.
+	 * Even though Rome publish ampdu_len=7, it can
+	 * only support 4 because of some h/w bug.
+	 */
+	if (vht_cap_info->ampdu_len_exponent > cfg->vht_max_ampdu_len_exp)
+		vht_cap_info->ampdu_len_exponent = cfg->vht_max_ampdu_len_exp;
+
+	/* Set VHT TXOP PS CAP */
+	if (vht_cap_info->txop_ps && !cfg->vht_txop_ps)
+		vht_cap_info->txop_ps = cfg->vht_txop_ps;
+
+	/* set the Guard interval 160MHz */
+	if (vht_cap_info->short_gi_160mhz && !cfg->vht_short_gi_160)
+		vht_cap_info->short_gi_160mhz = cfg->vht_short_gi_160;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS mlme_update_nss_vht_cap(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+	struct mlme_vht_capabilities_info *vht_cap_info;
+	uint32_t temp = 0;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("Failed to get MLME Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vht_cap_info = &mlme_obj->cfg.vht_caps.vht_cap_info;
+
+	temp = vht_cap_info->basic_mcs_set;
+	temp = (temp & 0xFFFC) | vht_cap_info->rx_mcs;
+	if (vht_cap_info->enable2x2)
+		temp = (temp & 0xFFF3) | (vht_cap_info->rx_mcs2x2 << 2);
+	else
+		temp |= 0x000C;
+
+	vht_cap_info->basic_mcs_set = temp;
+
+	temp = vht_cap_info->rx_mcs_map;
+	temp = (temp & 0xFFFC) | vht_cap_info->rx_mcs;
+	if (vht_cap_info->enable2x2)
+		temp = (temp & 0xFFF3) | (vht_cap_info->rx_mcs2x2 << 2);
+	else
+		temp |= 0x000C;
+
+	vht_cap_info->rx_mcs_map = temp;
+
+	temp = vht_cap_info->tx_mcs_map;
+	temp = (temp & 0xFFFC) | vht_cap_info->tx_mcs;
+	if (vht_cap_info->enable2x2)
+		temp = (temp & 0xFFF3) | (vht_cap_info->tx_mcs2x2 << 2);
+	else
+		temp |= 0x000C;
+
+	vht_cap_info->tx_mcs_map = temp;
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c
new file mode 100644
index 0000000..6d4115e
--- /dev/null
+++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 2018 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 UCFG APIs exposed by the mlme component
+ */
+
+#include "cfg_ucfg_api.h"
+#include "cfg_mlme_sta.h"
+#include "wlan_mlme_main.h"
+#include "wlan_mlme_api.h"
+#include "wlan_mlme_ucfg_api.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_mlme_vdev_mgr_interface.h"
+
+QDF_STATUS ucfg_mlme_init(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_register_psoc_create_handler(
+			WLAN_UMAC_COMP_MLME,
+			mlme_psoc_object_created_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		mlme_err("unable to register psoc create handle");
+		return status;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+			WLAN_UMAC_COMP_MLME,
+			mlme_psoc_object_destroyed_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		mlme_err("unable to register psoc create handle");
+
+	return status;
+}
+
+QDF_STATUS ucfg_mlme_deinit(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_MLME,
+			mlme_psoc_object_created_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		mlme_err("unable to unregister psoc create handle");
+		return status;
+	}
+
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+			WLAN_UMAC_COMP_MLME,
+			mlme_psoc_object_destroyed_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		mlme_err("unable to unregister psoc destroy handle");
+
+	return status;
+}
+
+QDF_STATUS ucfg_mlme_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+
+	status = mlme_cfg_on_psoc_enable(psoc);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		mlme_err("Failed to initialize MLME CFG");
+
+	return status;
+}
+
+void ucfg_mlme_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	/* Clear the MLME CFG Structure */
+}
+
+#ifdef CONFIG_VDEV_SM
+QDF_STATUS ucfg_mlme_pdev_open(struct wlan_objmgr_pdev *pdev)
+{
+	pdev->pdev_mlme.mlme_register_ops = mlme_register_vdev_mgr_ops;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_mlme_pdev_close(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+QDF_STATUS
+ucfg_mlme_get_sta_keep_alive_period(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_INFRA_STA_KEEP_ALIVE_PERIOD);
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.sta.sta_keep_alive_period;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_dfs_master_capability(struct wlan_objmgr_psoc *psoc,
+				    bool *val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_ENABLE_DFS_MASTER_CAPABILITY);
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.dfs_cfg.dfs_master_capable;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_pmkid_modes(struct wlan_objmgr_psoc *psoc,
+			  uint32_t *val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_PMKID_MODES);
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.sta.pmkid_modes;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_set_pmkid_modes(struct wlan_objmgr_psoc *psoc,
+			  uint32_t val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mlme_obj->cfg.sta.pmkid_modes = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_dot11p_mode(struct wlan_objmgr_psoc *psoc,
+			  enum dot11p_mode *out_mode)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		*out_mode = cfg_default(CFG_DOT11P_MODE);
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*out_mode = mlme_obj->cfg.sta.dot11p_mode;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_go_cts2self_for_sta(struct wlan_objmgr_psoc *psoc,
+				  bool *val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_ENABLE_GO_CTS2SELF_FOR_STA);
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.sta.enable_go_cts2self_for_sta;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_force_rsne_override(struct wlan_objmgr_psoc *psoc,
+				  bool *val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_FORCE_RSNE_OVERRIDE);
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.sta.force_rsne_override;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_qcn_ie_support(struct wlan_objmgr_psoc *psoc,
+			     bool *val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_QCN_IE_SUPPORT);
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.sta.qcn_ie_support;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_tgt_gtx_usr_cfg(struct wlan_objmgr_psoc *psoc,
+			      uint32_t *val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_TGT_GTX_USR_CFG);
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.sta.tgt_gtx_usr_cfg;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_roaming_offload(struct wlan_objmgr_psoc *psoc,
+			      bool *val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_LFR3_ROAMING_OFFLOAD);
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.lfr.lfr3_roaming_offload;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_set_roaming_offload(struct wlan_objmgr_psoc *psoc,
+			      bool val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mlme_obj->cfg.lfr.lfr3_roaming_offload = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_first_scan_bucket_threshold(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *val)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_LFR_FIRST_SCAN_BUCKET_THRESHOLD);
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.lfr.first_scan_bucket_threshold;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_opr_rate_set(struct wlan_objmgr_psoc *psoc,
+			   uint8_t *buf, qdf_size_t *len)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wlan_mlme_get_cfg_str(buf, &mlme_obj->cfg.rates.opr_rate_set,
+				     len);
+}
+
+QDF_STATUS
+ucfg_mlme_get_ext_opr_rate_set(struct wlan_objmgr_psoc *psoc,
+			       uint8_t *buf, qdf_size_t *len)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wlan_mlme_get_cfg_str(buf, &mlme_obj->cfg.rates.ext_opr_rate_set,
+				     len);
+}
+
+QDF_STATUS
+ucfg_mlme_get_supported_mcs_set(struct wlan_objmgr_psoc *psoc,
+				uint8_t *buf, qdf_size_t *len)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wlan_mlme_get_cfg_str(buf,
+				     &mlme_obj->cfg.rates.supported_mcs_set,
+				     len);
+}
+
+QDF_STATUS
+ucfg_mlme_set_supported_mcs_set(struct wlan_objmgr_psoc *psoc,
+				uint8_t *buf, qdf_size_t len)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wlan_mlme_set_cfg_str(buf,
+				     &mlme_obj->cfg.rates.supported_mcs_set,
+				     len);
+}
+
+QDF_STATUS
+ucfg_mlme_get_current_mcs_set(struct wlan_objmgr_psoc *psoc,
+			      uint8_t *buf, qdf_size_t *len)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		mlme_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wlan_mlme_get_cfg_str(buf,
+				     &mlme_obj->cfg.rates.current_mcs_set,
+				     len);
+}
diff --git a/components/ocb/core/inc/wlan_ocb_main.h b/components/ocb/core/inc/wlan_ocb_main.h
new file mode 100644
index 0000000..ad06180
--- /dev/null
+++ b/components/ocb/core/inc/wlan_ocb_main.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: contains ocb init/deinit public api
+ */
+
+#ifndef _WLAN_OCB_MAIN_API_H_
+#define _WLAN_OCB_MAIN_API_H_
+
+#include <qdf_atomic.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_ocb_public_structs.h>
+
+#define ocb_alert_rl(params...) QDF_TRACE_FATAL_RL(QDF_MODULE_ID_OCB, params)
+#define ocb_err_rl(params...) QDF_TRACE_ERROR_RL(QDF_MODULE_ID_OCB, params)
+#define ocb_warn_rl(params...) QDF_TRACE_WARN_RL(QDF_MODULE_ID_OCB, params)
+#define ocb_info_rl(params...) QDF_TRACE_INFO_RL(QDF_MODULE_ID_OCB, params)
+#define ocb_debug_rl(params...) QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_OCB, params)
+
+#define ocb_alert(params...) \
+	QDF_TRACE_FATAL(QDF_MODULE_ID_OCB, params)
+#define ocb_err(params...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_OCB, params)
+#define ocb_warn(params...) \
+	QDF_TRACE_WARN(QDF_MODULE_ID_OCB, params)
+#define ocb_notice(params...) \
+	QDF_TRACE_INFO(QDF_MODULE_ID_OCB, params)
+#define ocb_info(params...) \
+	QDF_TRACE_INFO(QDF_MODULE_ID_OCB, params)
+#define ocb_debug(params...) \
+	QDF_TRACE_DEBUG(QDF_MODULE_ID_OCB, params)
+
+#define ocb_nofl_alert(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_OCB, params)
+#define ocb_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_OCB, params)
+#define ocb_nofl_warn(params...) \
+	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_OCB, params)
+#define ocb_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_OCB, params)
+#define ocb_nofl_debug(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_OCB, params)
+
+/**
+ * enum ocb_southbound_event - OCB south bound event type
+ * @OCB_CHANNEL_CONFIG_STATUS: set channel config response
+ * @OCB_TSF_TIMER: get TSF timer response
+ * @OCB_DCC_STATS_RESPONSE: get DCC stats response
+ * @OCB_NDL_RESPONSE: NDL update response
+ * @OCB_DCC_INDICATION: DCC stats indication
+ */
+enum ocb_southbound_event {
+	OCB_CHANNEL_CONFIG_STATUS,
+	OCB_TSF_TIMER,
+	OCB_DCC_STATS_RESPONSE,
+	OCB_NDL_RESPONSE,
+	OCB_DCC_INDICATION,
+};
+
+/**
+ * struct ocb_pdev_obj - ocb pdev object
+ * @pdev: pdev handle
+ * @ocb_mac: MAC address for different channels
+ * @ocb_channel_count: channel count
+ * @channel_config: current channel configurations
+ * @dp_soc: psoc data path handle
+ * @dp_pdev: pdev data path handle
+ * @ocb_cbs: legacy callback functions
+ * @ocb_txops: tx opertions for target interface
+ * @ocb_rxops: rx opertions for target interface
+ */
+struct ocb_pdev_obj {
+	struct wlan_objmgr_pdev *pdev;
+	struct qdf_mac_addr ocb_mac[QDF_MAX_CONCURRENCY_PERSONA];
+	uint32_t ocb_channel_count;
+	struct ocb_config *channel_config;
+	void *dp_soc;
+	void *dp_pdev;
+	struct ocb_callbacks ocb_cbs;
+	struct wlan_ocb_tx_ops ocb_txops;
+	struct wlan_ocb_rx_ops ocb_rxops;
+};
+
+/**
+ * struct ocb_rx_event - event from south bound
+ * @psoc: psoc handle
+ * @vdev: vdev handle
+ * @evt_id: event ID
+ * @channel_cfg_rsp: set channel config status
+ * @tsf_timer: get TSF timer response
+ * @ndl: NDL DCC response
+ * @dcc_stats: DCC stats
+ */
+struct ocb_rx_event {
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_vdev *vdev;
+	uint32_t evt_id;
+	union event {
+		struct ocb_set_config_response channel_cfg_rsp;
+		struct ocb_get_tsf_timer_response tsf_timer;
+		struct ocb_dcc_update_ndl_response ndl;
+		struct ocb_dcc_get_stats_response dcc_stats;
+	} rsp;
+};
+
+/**
+ * wlan_get_pdev_ocb_obj() - private API to get ocb pdev object
+ * @pdev: pdev object
+ *
+ * Return: ocb object
+ */
+static inline struct ocb_pdev_obj *
+wlan_get_pdev_ocb_obj(struct wlan_objmgr_pdev *pdev)
+{
+	struct ocb_pdev_obj *pdev_obj;
+
+	pdev_obj = (struct ocb_pdev_obj *)
+		wlan_objmgr_pdev_get_comp_private_obj(pdev,
+				WLAN_UMAC_COMP_OCB);
+
+	return pdev_obj;
+}
+
+/**
+ * wlan_ocb_get_callbacks() - get legacy layer callbacks
+ * @pdev: pdev handle
+ *
+ * Return: legacy layer callbacks
+ */
+static inline struct ocb_callbacks *
+wlan_ocb_get_callbacks(struct wlan_objmgr_pdev *pdev)
+{
+	struct ocb_pdev_obj *pdev_obj;
+
+	pdev_obj = wlan_get_pdev_ocb_obj(pdev);
+
+	if (pdev_obj)
+		return &pdev_obj->ocb_cbs;
+	else
+		return NULL;
+}
+
+/**
+ * wlan_pdev_get_ocb_tx_ops() - get OCB tx operations
+ * @pdev: pdev handle
+ *
+ * Return: fps to OCB tx operations
+ */
+static inline struct wlan_ocb_tx_ops *
+wlan_pdev_get_ocb_tx_ops(struct wlan_objmgr_pdev *pdev)
+{
+	struct ocb_pdev_obj *ocb_obj;
+
+	ocb_obj = wlan_get_pdev_ocb_obj(pdev);
+
+	return &ocb_obj->ocb_txops;
+}
+
+/**
+ * wlan_ocb_release_rx_event() - Release OCB RX event
+ * @event: OCB RX event
+ *
+ * Return: none
+ */
+static inline void wlan_ocb_release_rx_event(struct ocb_rx_event *event)
+{
+
+	if (!event) {
+		ocb_err("event is NULL");
+		return;
+	}
+
+	if (event->vdev)
+		wlan_objmgr_vdev_release_ref(event->vdev, WLAN_OCB_SB_ID);
+	if (event->psoc)
+		wlan_objmgr_psoc_release_ref(event->psoc, WLAN_OCB_SB_ID);
+	qdf_mem_free(event);
+}
+
+/**
+ * ocb_pdev_obj_create_notification() - OCB pdev object creation notification
+ * @pdev: pdev handle
+ * @arg_list: arguments list
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ocb_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
+					    void *arg_list);
+
+/**
+ * ocb_pdev_obj_destroy_notification() - OCB pdev object destroy notification
+ * @pdev: pdev handle
+ * @arg_list: arguments list
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ocb_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
+					     void *arg_list);
+
+/**
+ * ocb_config_new() - Creates a new OCB configuration
+ * @num_channels: the number of channels
+ * @num_schedule: the schedule size
+ * @ndl_chan_list_len: length in bytes of the NDL chan blob
+ * @ndl_active_state_list_len: length in bytes of the active state blob
+ *
+ * Return: A pointer to the OCB configuration struct, NULL on failure.
+ */
+struct ocb_config *ocb_config_new(uint32_t num_channels,
+				  uint32_t num_schedule,
+				  uint32_t ndl_chan_list_len,
+				  uint32_t ndl_active_state_list_len);
+
+/**
+ * ocb_copy_config() - Backup current config parameters
+ * @src: current config parameters
+ *
+ * Return: A pointer to the OCB configuration struct, NULL on failure.
+ */
+struct ocb_config *ocb_copy_config(struct ocb_config *src);
+
+/**
+ * ocb_process_evt() - API to process event from south bound
+ * @msg: south bound message
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ocb_process_evt(struct scheduler_msg *msg);
+
+/**
+ * ocb_vdev_start() - start OCB vdev
+ * @ocb_obj: OCB object
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ocb_vdev_start(struct ocb_pdev_obj *ocb_obj);
+#endif
diff --git a/components/ocb/core/src/wlan_ocb_main.c b/components/ocb/core/src/wlan_ocb_main.c
new file mode 100644
index 0000000..928641b
--- /dev/null
+++ b/components/ocb/core/src/wlan_ocb_main.c
@@ -0,0 +1,574 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: contains core ocb function definitions
+ */
+
+#include <qdf_status.h>
+#include "scheduler_api.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 <cdp_txrx_handle.h>
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_ocb.h>
+#include "wlan_ocb_main.h"
+#include "wlan_ocb_tgt_api.h"
+#include "target_if_ocb.h"
+
+/**
+ * ocb_get_cmd_type_str() - parse cmd to string
+ * @cmd_type: ocb cmd type
+ *
+ * This function parse ocb cmd to string.
+ *
+ * Return: command string
+ */
+static const char *ocb_get_evt_type_str(enum ocb_southbound_event evt_type)
+{
+	switch (evt_type) {
+	case OCB_CHANNEL_CONFIG_STATUS:
+		return "OCB channel config status";
+	case OCB_TSF_TIMER:
+		return "OCB TSF timer";
+	case OCB_DCC_STATS_RESPONSE:
+		return "OCB DCC get stats response";
+	case OCB_NDL_RESPONSE:
+		return "OCB NDL indication";
+	case OCB_DCC_INDICATION:
+		return "OCB DCC stats indication";
+	default:
+		return "Invalid OCB command";
+	}
+}
+
+/**
+ * ocb_set_chan_info() - Set channel info to dp
+ * @dp_soc: data path soc handle
+ * @dp_pdev: data path pdev handle
+ * @vdev_id: OCB vdev_id
+ * @config: channel config parameters
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS ocb_set_chan_info(void *dp_soc,
+				    void *dp_pdev,
+				    uint32_t vdev_id,
+				    struct ocb_config *config)
+{
+	struct cdp_vdev *dp_vdev;
+	struct ol_txrx_ocb_set_chan ocb_set_chan;
+	struct ol_txrx_ocb_chan_info *ocb_channel_info;
+
+	if (!dp_soc || !dp_pdev) {
+		ocb_err("DP global handle is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	dp_vdev = cdp_get_vdev_from_vdev_id(dp_soc, dp_pdev, vdev_id);
+	if (!dp_vdev) {
+		ocb_err("DP vdev handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ocb_set_chan.ocb_channel_count = config->channel_count;
+
+	/* release old settings */
+	ocb_channel_info = cdp_get_ocb_chan_info(dp_soc, dp_vdev);
+	if (ocb_channel_info)
+		qdf_mem_free(ocb_channel_info);
+
+	if (config->channel_count) {
+		int i, buf_size;
+
+		buf_size = sizeof(*ocb_channel_info) * config->channel_count;
+		ocb_set_chan.ocb_channel_info = qdf_mem_malloc(buf_size);
+		if (!ocb_set_chan.ocb_channel_info) {
+			ocb_err("Failed to allocate buffer for chan info");
+			return QDF_STATUS_E_NOMEM;
+		}
+		ocb_channel_info = ocb_set_chan.ocb_channel_info;
+		for (i = 0; i < config->channel_count; i++) {
+			ocb_channel_info[i].chan_freq =
+				config->channels[i].chan_freq;
+			if (config->channels[i].flags &
+				OCB_CHANNEL_FLAG_DISABLE_RX_STATS_HDR)
+				ocb_channel_info[i].disable_rx_stats_hdr = 1;
+		}
+	} else {
+		ocb_debug("No channel config to dp");
+		ocb_set_chan.ocb_channel_info = NULL;
+	}
+	ocb_debug("Sync channel config to dp");
+	cdp_set_ocb_chan_info(dp_soc, dp_vdev, ocb_set_chan);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ocb_channel_config_status() - Process set channel config response
+ * @evt: response event
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS ocb_channel_config_status(struct ocb_rx_event *evt)
+{
+	QDF_STATUS status;
+	uint32_t vdev_id;
+	struct ocb_rx_event *event;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	struct ocb_pdev_obj *ocb_obj;
+	struct ocb_callbacks *cbs;
+	struct ocb_set_config_response config_rsp;
+
+	if (!evt) {
+		ocb_err("Event buffer is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	event = evt;
+	psoc = event->psoc;
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_OCB_SB_ID);
+	if (!pdev) {
+		ocb_alert("Pdev is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ocb_obj = wlan_get_pdev_ocb_obj(pdev);
+	if (!ocb_obj) {
+		ocb_err("Pdev object is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto exit;
+	}
+
+	cbs = &ocb_obj->ocb_cbs;
+	if (ocb_obj->channel_config) {
+		vdev_id = ocb_obj->channel_config->vdev_id;
+		config_rsp = event->rsp.channel_cfg_rsp;
+
+		/* Sync channel status to data path */
+		if (config_rsp.status == OCB_CHANNEL_CONFIG_SUCCESS)
+			ocb_set_chan_info(ocb_obj->dp_soc,
+					  ocb_obj->dp_pdev,
+					  vdev_id,
+					  ocb_obj->channel_config);
+		qdf_mem_free(ocb_obj->channel_config);
+		ocb_obj->channel_config = NULL;
+	} else {
+		ocb_err("Failed to sync channel info to DP");
+		config_rsp.status = OCB_CHANNEL_CONFIG_FAIL;
+	}
+
+	if (cbs->ocb_set_config_callback) {
+		cbs->ocb_set_config_callback(cbs->ocb_set_config_context,
+					     &config_rsp);
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		ocb_err("ocb_set_config_resp_cb is NULL");
+		status = QDF_STATUS_E_INVAL;
+	}
+exit:
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_SB_ID);
+
+	return status;
+}
+
+/**
+ * ocb_tsf_timer() - Process get TSF timer response
+ * @evt: repsonse event
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS ocb_tsf_timer(struct ocb_rx_event *evt)
+{
+	QDF_STATUS status;
+	struct ocb_rx_event *event;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_pdev *pdev;
+	struct ocb_callbacks *cbs;
+	struct ocb_get_tsf_timer_response *tsf_timer;
+
+	if (!evt) {
+		ocb_err("Event buffer is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	event = evt;
+	vdev = event->vdev;
+	pdev = wlan_vdev_get_pdev(vdev);
+	cbs = wlan_ocb_get_callbacks(pdev);
+	tsf_timer = &event->rsp.tsf_timer;
+	ocb_debug("TSF timer low=%d, high=%d",
+		  tsf_timer->timer_low, tsf_timer->timer_high);
+	if (cbs && cbs->ocb_get_tsf_timer_callback) {
+		ocb_debug("%s: send TSF timer.", __func__);
+		cbs->ocb_get_tsf_timer_callback(cbs->ocb_get_tsf_timer_context,
+						tsf_timer);
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		ocb_err("ocb_get_tsf_timer_cb is NULL");
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+/**
+ * ocb_dcc_stats_response() - Process get DCC stats response
+ * @evt: repsonse event
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS ocb_dcc_stats_response(struct ocb_rx_event *evt)
+{
+	QDF_STATUS status;
+	struct ocb_rx_event *event;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_pdev *pdev;
+	struct ocb_callbacks *cbs;
+	struct ocb_dcc_get_stats_response *dcc_stats;
+
+	if (!evt) {
+		ocb_err("Event buffer is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	event = evt;
+	vdev = event->vdev;
+	pdev = wlan_vdev_get_pdev(vdev);
+	cbs = wlan_ocb_get_callbacks(pdev);
+	dcc_stats = &event->rsp.dcc_stats;
+	if (cbs && cbs->ocb_dcc_get_stats_callback) {
+		ocb_debug("%s: send DCC stats", __func__);
+		cbs->ocb_dcc_get_stats_callback(cbs->ocb_dcc_get_stats_context,
+						dcc_stats);
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		ocb_err("dcc_get_stats_cb is NULL");
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+/**
+ * ocb_ndl_response() - Process NDL update response
+ * @evt: repsonse event
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS ocb_ndl_response(struct ocb_rx_event *evt)
+{
+	QDF_STATUS status;
+	struct ocb_rx_event *event;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_pdev *pdev;
+	struct ocb_callbacks *cbs;
+	struct ocb_dcc_update_ndl_response *ndl;
+
+	if (!evt) {
+		ocb_err("Event buffer is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	event = evt;
+	vdev = event->vdev;
+	pdev = wlan_vdev_get_pdev(vdev);
+	cbs = wlan_ocb_get_callbacks(pdev);
+	ndl = &event->rsp.ndl;
+	if (cbs && cbs->ocb_dcc_update_ndl_callback) {
+		ocb_debug("%s: NDL update response", __func__);
+		cbs->ocb_dcc_update_ndl_callback(
+				cbs->ocb_dcc_update_ndl_context, ndl);
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		ocb_err("dcc_update_ndl is NULL");
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+/**
+ * ocb_dcc_indication() - Process DCC stats indication
+ * @evt: repsonse event
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS ocb_dcc_indication(struct ocb_rx_event *evt)
+{
+	QDF_STATUS status;
+	struct ocb_rx_event *event;
+	struct wlan_objmgr_vdev *vdev;
+	struct ocb_callbacks *cbs;
+	struct wlan_objmgr_pdev *pdev;
+	struct ocb_dcc_get_stats_response *dcc_stats;
+
+	if (!evt) {
+		ocb_err("Event buffer is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	event = evt;
+	vdev = event->vdev;
+	pdev = wlan_vdev_get_pdev(vdev);
+	cbs = wlan_ocb_get_callbacks(pdev);
+	dcc_stats = &event->rsp.dcc_stats;
+	if (cbs && cbs->ocb_dcc_stats_event_callback) {
+		ocb_debug("%s: DCC stats indication", __func__);
+		cbs->ocb_dcc_stats_event_callback(
+				cbs->ocb_dcc_stats_event_context, dcc_stats);
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		ocb_err("dcc_get_stats_cb is NULL");
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+/**
+ * ocb_flush_start_msg() - Flush ocb start message
+ * @msg: OCB start vdev message
+ *
+ * Return: QDF_STATUS_SUCCESS on success.
+ */
+static QDF_STATUS ocb_flush_start_msg(struct scheduler_msg *msg)
+{
+	struct ocb_pdev_obj *ocb_obj;
+
+	if (!msg) {
+		ocb_err("Null point for OCB message");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	ocb_obj = msg->bodyptr;
+	if (ocb_obj && ocb_obj->channel_config) {
+		ocb_info("release the backed config parameters");
+		qdf_mem_free(ocb_obj->channel_config);
+		ocb_obj->channel_config = NULL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ocb_process_start_vdev_msg() - Handler for OCB vdev start message
+ * @msg: OCB start vdev message
+ *
+ * Return: QDF_STATUS_SUCCESS on success.
+ */
+static QDF_STATUS ocb_process_start_vdev_msg(struct scheduler_msg *msg)
+{
+	QDF_STATUS status;
+	struct ocb_config *config;
+	struct ocb_pdev_obj *ocb_obj;
+	struct ocb_callbacks *ocb_cbs;
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!msg || !msg->bodyptr) {
+		ocb_err("invalid message");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	ocb_obj = msg->bodyptr;
+	ocb_cbs = &ocb_obj->ocb_cbs;
+	if (!ocb_cbs->start_ocb_vdev) {
+		ocb_err("No callback to start ocb vdev");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	config = ocb_obj->channel_config;
+	if (!config) {
+		ocb_err("NULL config parameters");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(ocb_obj->pdev,
+						    config->vdev_id,
+						    WLAN_OCB_SB_ID);
+	if (!vdev) {
+		ocb_err("Cannot get vdev");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ocb_debug("Start to send OCB vdev start cmd");
+	status = ocb_cbs->start_ocb_vdev(config);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_OCB_SB_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ocb_err("Failed to start OCB vdev");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ocb_vdev_start(struct ocb_pdev_obj *ocb_obj)
+{
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+
+	msg.bodyptr = ocb_obj;
+	msg.callback = ocb_process_start_vdev_msg;
+	msg.flush_callback = ocb_flush_start_msg;
+	status = scheduler_post_message(QDF_MODULE_ID_OCB,
+					QDF_MODULE_ID_OCB,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status))
+		ocb_err("Failed to post vdev start message");
+
+	return status;
+}
+
+QDF_STATUS ocb_process_evt(struct scheduler_msg *msg)
+{
+	QDF_STATUS status;
+	struct ocb_rx_event *event;
+
+	ocb_debug("msg type %d, %s", msg->type,
+		  ocb_get_evt_type_str(msg->type));
+
+	if (!(msg->bodyptr)) {
+		ocb_err("Invalid message body");
+		return QDF_STATUS_E_INVAL;
+	}
+	event = msg->bodyptr;
+	switch (msg->type) {
+	case OCB_CHANNEL_CONFIG_STATUS:
+		status = ocb_channel_config_status(event);
+		break;
+	case OCB_TSF_TIMER:
+		status = ocb_tsf_timer(event);
+		break;
+	case OCB_DCC_STATS_RESPONSE:
+		status = ocb_dcc_stats_response(event);
+		break;
+	case OCB_NDL_RESPONSE:
+		status = ocb_ndl_response(event);
+		break;
+	case OCB_DCC_INDICATION:
+		status = ocb_dcc_indication(event);
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+		break;
+	}
+
+	wlan_ocb_release_rx_event(event);
+	msg->bodyptr = NULL;
+
+	return status;
+}
+
+struct ocb_config *ocb_copy_config(struct ocb_config *src)
+{
+	struct ocb_config *dst;
+	uint32_t length;
+	uint8_t *cursor;
+
+	length = sizeof(*src) +
+		src->channel_count * sizeof(*src->channels) +
+		src->schedule_size * sizeof(*src->schedule) +
+		src->dcc_ndl_chan_list_len +
+		src->dcc_ndl_active_state_list_len;
+
+	dst = qdf_mem_malloc(length);
+	if (!dst)
+		return NULL;
+
+	*dst = *src;
+
+	cursor = (uint8_t *)dst;
+	cursor += sizeof(*dst);
+	dst->channels = (struct ocb_config_chan *)cursor;
+	cursor += src->channel_count * sizeof(*dst->channels);
+	qdf_mem_copy(dst->channels, src->channels,
+		     src->channel_count * sizeof(*dst->channels));
+	dst->schedule = (struct ocb_config_schdl *)cursor;
+	cursor += src->schedule_size * sizeof(*dst->schedule);
+	qdf_mem_copy(dst->schedule, src->schedule,
+		     src->schedule_size * sizeof(*dst->schedule));
+	dst->dcc_ndl_chan_list = cursor;
+	cursor += src->dcc_ndl_chan_list_len;
+	qdf_mem_copy(dst->dcc_ndl_chan_list, src->dcc_ndl_chan_list,
+		     src->dcc_ndl_chan_list_len);
+	dst->dcc_ndl_active_state_list = cursor;
+	cursor += src->dcc_ndl_active_state_list_len;
+	qdf_mem_copy(dst->dcc_ndl_active_state_list,
+		     src->dcc_ndl_active_state_list,
+		     src->dcc_ndl_active_state_list_len);
+
+	return dst;
+}
+
+QDF_STATUS ocb_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
+					    void *arg_list)
+{
+	QDF_STATUS status;
+	struct ocb_pdev_obj *ocb_obj;
+
+	ocb_notice("ocb pdev created");
+	ocb_obj = qdf_mem_malloc(sizeof(*ocb_obj));
+	if (!ocb_obj) {
+		ocb_err("Failed to allocate memory for ocb pdev object");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = wlan_objmgr_pdev_component_obj_attach(pdev,
+						       WLAN_UMAC_COMP_OCB,
+						       (void *)ocb_obj,
+						       QDF_STATUS_SUCCESS);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ocb_err("Failed to attach pdev ocb component");
+		qdf_mem_free(ocb_obj);
+		return status;
+	}
+	ocb_obj->pdev = pdev;
+
+	/* register OCB tx/rx ops */
+	tgt_ocb_register_rx_ops(&ocb_obj->ocb_rxops);
+	target_if_ocb_register_tx_ops(&ocb_obj->ocb_txops);
+	ocb_notice("ocb pdev attached");
+
+	return status;
+}
+
+QDF_STATUS ocb_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
+					     void *arg_list)
+{
+	QDF_STATUS status;
+	struct ocb_pdev_obj *ocb_obj;
+
+	ocb_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
+							WLAN_UMAC_COMP_OCB);
+	if (!ocb_obj) {
+		ocb_err("Failed to get ocb pdev object");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = wlan_objmgr_pdev_component_obj_detach(pdev,
+						       WLAN_UMAC_COMP_OCB,
+						       ocb_obj);
+	if (QDF_IS_STATUS_ERROR(status))
+		ocb_err("Failed to detatch ocb pdev object");
+
+	qdf_mem_free(ocb_obj);
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/components/ocb/dispatcher/inc/wlan_ocb_public_structs.h b/components/ocb/dispatcher/inc/wlan_ocb_public_structs.h
new file mode 100644
index 0000000..b23fe51
--- /dev/null
+++ b/components/ocb/dispatcher/inc/wlan_ocb_public_structs.h
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: contains ocb structure definitions
+ */
+
+#ifndef _WLAN_OCB_STRUCTS_H_
+#define _WLAN_OCB_STRUCTS_H_
+#include <qdf_status.h>
+
+/* number of vdevs that can support OCB */
+#define OCB_VDEVS_NUM			1
+
+/* maximum number of channels that can do OCB */
+#define OCB_CHANNELS_NUM		2
+
+/* maximum number of channels in an OCB schedule */
+#define OCB_SCHEDULES_NUM		2
+
+/* Don't add the RX stats header to packets received on this channel */
+#define OCB_CHANNEL_FLAG_DISABLE_RX_STATS_HDR	(1 << 0)
+
+/* The size of the utc time in bytes. */
+#define OCB_SIZE_UTC_TIME                       (10)
+
+/* The size of the utc time error in bytes. */
+#define OCB_SIZE_UTC_TIME_ERROR                 (5)
+
+#define OCB_CHANNEL_MAX                         (5)
+#define OCB_MAX_NUM_AC                          (4)
+
+/**
+ * struct ocb_utc_param - parameters to set UTC time
+ * @vdev_id: vdev id
+ * @utc_time: number of nanoseconds from Jan 1st 1958
+ * @time_error: the error in the UTC time. All 1's for unknown
+ */
+struct ocb_utc_param {
+	uint32_t vdev_id;
+	uint8_t utc_time[OCB_SIZE_UTC_TIME];
+	uint8_t time_error[OCB_SIZE_UTC_TIME_ERROR];
+};
+
+/**
+ * struct ocb_timing_advert_param - parameters to start/stop
+ *  timing advertisement
+ * @vdev_id: vdev id
+ * @chan_freq: frequency on which to advertise (unit in Mhz)
+ * @repeat_rate: the number of times it will send TA in 5 seconds
+ * @timestamp_offset: offset of the timestamp field in the TA frame
+ * @time_value_offset: offset of the time_value field in the TA frame
+ * @template_length: size in bytes of the TA frame
+ * @template_value: the TA frame
+ */
+struct ocb_timing_advert_param {
+	uint32_t vdev_id;
+	uint32_t chan_freq;
+	uint32_t repeat_rate;
+	uint32_t timestamp_offset;
+	uint32_t time_value_offset;
+	uint32_t template_length;
+	uint8_t *template_value;
+};
+
+/**
+ * struct ocb_dcc_get_stats_param - parameters to get DCC stats
+ * @vdev_id: vdev id
+ * @channel_count: number of dcc channels
+ * @request_array_len: size in bytes of the request array
+ * @request_array: the request array
+ */
+struct ocb_dcc_get_stats_param {
+	uint32_t vdev_id;
+	uint32_t channel_count;
+	uint32_t request_array_len;
+	void *request_array;
+};
+
+/**
+ * struct ocb_dcc_update_ndl_param - parameters to update NDL
+ * @vdev_id: vdev id
+ * @channel_count: number of channels to be updated
+ * @dcc_ndl_chan_list_len: size in bytes of the ndl_chan array
+ * @dcc_ndl_chan_list: the ndl_chan array
+ * @dcc_ndl_active_state_list_len: size in bytes of the active_state array
+ * @dcc_ndl_active_state_list: the active state array
+ */
+struct ocb_dcc_update_ndl_param {
+	uint32_t vdev_id;
+	uint32_t channel_count;
+	uint32_t dcc_ndl_chan_list_len;
+	void *dcc_ndl_chan_list;
+	uint32_t dcc_ndl_active_state_list_len;
+	void *dcc_ndl_active_state_list;
+};
+
+/**
+ * struct ocb_config_schdl - parameters for channel scheduling
+ * @chan_freq: frequency of the channel (unit in Mhz)
+ * @total_duration: duration of the schedule (unit in ms)
+ * @guard_interval: guard interval on the start of the schedule (unit in ms)
+ */
+struct ocb_config_schdl {
+	uint32_t chan_freq;
+	uint32_t total_duration;
+	uint32_t guard_interval;
+};
+
+/**
+ * struct ocb_wmm_param - WMM parameters
+ * @aifsn: AIFS number
+ * @cwmin: value of CWmin
+ * @cwmax: value of CWmax
+ */
+struct ocb_wmm_param {
+	uint8_t aifsn;
+	uint8_t cwmin;
+	uint8_t cwmax;
+};
+
+/**
+ * struct ocb_config_chan - parameters to configure a channel
+ * @chan_freq: frequency of the channel (unit in MHz)
+ * @bandwidth: bandwidth of the channel, either 10 or 20 MHz
+ * @mac_address: MAC address assigned to this channel
+ * @qos_params: QoS parameters
+ * @max_pwr: maximum transmit power of the channel (dBm)
+ * @min_pwr: minimum transmit power of the channel (dBm)
+ * @reg_pwr: maximum transmit power specified by the regulatory domain (dBm)
+ * @antenna_max: maximum antenna gain specified by the regulatory domain (dB)
+ * @flags: bit0: 0 enable RX stats on this channel; 1 disable RX stats
+ *         bit1: flag to indicate TSF expiry time in TX control.
+ *               0 relative time is used. 1 absolute time is used.
+ *         bit2: Frame mode from user layer.
+ *               0 for 802.3 frame, 1 for 802.11 frame.
+ * @ch_mode: channel mode
+ */
+struct ocb_config_chan {
+	uint32_t chan_freq;
+	uint32_t bandwidth;
+	struct qdf_mac_addr mac_address;
+	struct ocb_wmm_param qos_params[OCB_MAX_NUM_AC];
+	uint32_t max_pwr;
+	uint32_t min_pwr;
+	uint8_t reg_pwr;
+	uint8_t antenna_max;
+	uint16_t flags;
+	uint32_t ch_mode;
+};
+
+/**
+ * struct ocb_config - parameters for OCB vdev config
+ * @vdev_id: vdev id
+ * @channel_count: number of channels
+ * @schedule_size: size of the channel schedule
+ * @flags: reserved
+ * @channels: array of OCB channels
+ * @schedule: array of OCB schedule elements
+ * @dcc_ndl_chan_list_len: size in bytes of the ndl_chan array
+ * @dcc_ndl_chan_list: array of dcc channel info
+ * @dcc_ndl_active_state_list_len: size in bytes of the active state array
+ * @dcc_ndl_active_state_list: array of active states
+ */
+struct ocb_config {
+	uint32_t vdev_id;
+	uint32_t channel_count;
+	uint32_t schedule_size;
+	uint32_t flags;
+	struct ocb_config_chan *channels;
+	struct ocb_config_schdl *schedule;
+	uint32_t dcc_ndl_chan_list_len;
+	void *dcc_ndl_chan_list;
+	uint32_t dcc_ndl_active_state_list_len;
+	void *dcc_ndl_active_state_list;
+};
+
+/**
+ * enum ocb_channel_config_status - ocb config status
+ * @OCB_CHANNEL_CONFIG_SUCCESS: success
+ * @OCB_CHANNEL_CONFIG_FAIL: failure
+ * @OCB_CHANNEL_CONFIG_STATUS_MAX: place holder, not a real status
+ */
+enum ocb_channel_config_status {
+	OCB_CHANNEL_CONFIG_SUCCESS = 0,
+	OCB_CHANNEL_CONFIG_FAIL,
+	OCB_CHANNEL_CONFIG_STATUS_MAX
+};
+
+/**
+ * struct ocb_set_config_response - ocb config status
+ * @status: response status. OCB_CHANNEL_CONFIG_SUCCESS for success.
+ */
+struct ocb_set_config_response {
+	enum ocb_channel_config_status status;
+};
+
+/**
+ * struct ocb_get_tsf_timer_response - TSF timer response
+ * @vdev_id: vdev id
+ * @timer_high: higher 32-bits of the timer
+ * @timer_low: lower 32-bits of the timer
+ */
+struct ocb_get_tsf_timer_response {
+	uint32_t vdev_id;
+	uint32_t timer_high;
+	uint32_t timer_low;
+};
+
+/**
+ * struct ocb_get_tsf_timer_param - parameters to get tsf timer
+ * @vdev_id: vdev id
+ */
+struct ocb_get_tsf_timer_param {
+	uint32_t vdev_id;
+};
+
+/**
+ * struct ocb_dcc_get_stats_response - DCC stats response
+ * @vdev_id: vdev id
+ * @num_channels: number of dcc channels
+ * @channel_stats_array_len: size in bytes of the stats array
+ * @channel_stats_array: the stats array
+ */
+struct ocb_dcc_get_stats_response {
+	uint32_t vdev_id;
+	uint32_t num_channels;
+	uint32_t channel_stats_array_len;
+	void *channel_stats_array;
+};
+
+/**
+ * struct ocb_dcc_clear_stats_param - parameters to clear DCC stats
+ * @vdev_id: vdev id
+ * @dcc_stats_bitmap: bitmap of clear option
+ */
+struct ocb_dcc_clear_stats_param {
+	uint32_t vdev_id;
+	uint32_t dcc_stats_bitmap;
+};
+
+/**
+ * struct ocb_dcc_update_ndl_response - NDP update response
+ * @vdev_id: vdev id
+ * @status: response status
+ */
+struct ocb_dcc_update_ndl_response {
+	uint32_t vdev_id;
+	uint32_t status;
+};
+
+/**
+ * struct wlan_ocb_rx_ops - structure containing rx ops for OCB
+ * @ocb_set_config_status: fp to get channel config status
+ * @ocb_tsf_timer: fp to get TSF timer
+ * @ocb_dcc_ndl_update: fp to get NDL update status
+ * @ocb_dcc_stats_indicate: fp to get DCC stats
+ */
+struct wlan_ocb_rx_ops {
+	QDF_STATUS (*ocb_set_config_status)(struct wlan_objmgr_psoc *psoc,
+					    uint32_t status);
+	QDF_STATUS (*ocb_tsf_timer)(struct wlan_objmgr_psoc *psoc,
+				struct ocb_get_tsf_timer_response *response);
+	QDF_STATUS (*ocb_dcc_ndl_update)(struct wlan_objmgr_psoc *psoc,
+				struct ocb_dcc_update_ndl_response *resp);
+	QDF_STATUS (*ocb_dcc_stats_indicate)(struct wlan_objmgr_psoc *psoc,
+		struct ocb_dcc_get_stats_response *response, bool indicate);
+};
+
+/**
+ * struct wlan_ocb_tx_ops - structures containing tx ops for OCB
+ * @ocb_set_config: fp to set channel config
+ * @ocb_set_utc_time: fp to set utc time
+ * @ocb_start_timing_advert: fp to start timing advertisement
+ * @ocb_stop_timing_advert: fp to stop timing advertisement
+ * @ocb_get_tsf_timer: fp to get tsf timer
+ * @ocb_dcc_get_stats: fp to get DCC stats
+ * @ocb_dcc_clear_stats: fp to clear DCC stats
+ * @ocb_dcc_update_ndl: fp to update ndl
+ * @ocb_reg_ev_handler: fp to register event handler
+ * @ocb_unreg_ev_handler: fp to unregister event handler
+ */
+struct wlan_ocb_tx_ops {
+	QDF_STATUS (*ocb_set_config)(struct wlan_objmgr_psoc *psoc,
+			struct ocb_config *config);
+	QDF_STATUS (*ocb_set_utc_time)(struct wlan_objmgr_psoc *psoc,
+			struct ocb_utc_param *utc);
+	QDF_STATUS (*ocb_start_timing_advert)(struct wlan_objmgr_psoc *psoc,
+			struct ocb_timing_advert_param *timing_advert);
+	QDF_STATUS (*ocb_stop_timing_advert)(struct wlan_objmgr_psoc *psoc,
+			struct ocb_timing_advert_param *timing_advert);
+	QDF_STATUS (*ocb_get_tsf_timer)(struct wlan_objmgr_psoc *psoc,
+			struct ocb_get_tsf_timer_param *request);
+	QDF_STATUS (*ocb_dcc_get_stats)(struct wlan_objmgr_psoc *psoc,
+			struct ocb_dcc_get_stats_param *get_stats_param);
+	QDF_STATUS (*ocb_dcc_clear_stats)(struct wlan_objmgr_psoc *psoc,
+			struct ocb_dcc_clear_stats_param *clear_stats);
+	QDF_STATUS (*ocb_dcc_update_ndl)(struct wlan_objmgr_psoc *psoc,
+			struct ocb_dcc_update_ndl_param *update_ndl_param);
+	QDF_STATUS (*ocb_reg_ev_handler)(struct wlan_objmgr_psoc *psoc,
+					 void *arg);
+	QDF_STATUS (*ocb_unreg_ev_handler)(struct wlan_objmgr_psoc *psoc,
+					   void *arg);
+};
+
+typedef void (*ocb_sync_callback)(void *context, void *response);
+
+/**
+ * struct ocb_callback - structure containing callback to legacy driver
+ * @ocb_set_config_context: context for set channel config callback
+ * @ocb_set_config_callback: set channel config callback
+ * @ocb_get_tsf_timer_context: context for get tsf timer callback
+ * @ocb_get_tsf_timer_callback: get tsf timer callback
+ * @ocb_dcc_get_stats_context: context for get DCC stats callback
+ * @ocb_dcc_get_stats_callback: get DCC stats callback
+ * @ocb_dcc_update_ndl_context: context for NDL update callback
+ * @ocb_dcc_update_ndl_callback: NDL update callback
+ * @ocb_dcc_stats_event_context: context for DCC stats event callback
+ * @ocb_dcc_stats_event_callback: DCC stats event callback
+ * @start_ocb_vdev: start ocb callback
+ */
+struct ocb_callbacks {
+	void *ocb_set_config_context;
+	ocb_sync_callback ocb_set_config_callback;
+	void *ocb_get_tsf_timer_context;
+	ocb_sync_callback ocb_get_tsf_timer_callback;
+	void *ocb_dcc_get_stats_context;
+	ocb_sync_callback ocb_dcc_get_stats_callback;
+	void *ocb_dcc_update_ndl_context;
+	ocb_sync_callback ocb_dcc_update_ndl_callback;
+	void *ocb_dcc_stats_event_context;
+	ocb_sync_callback ocb_dcc_stats_event_callback;
+	QDF_STATUS (*start_ocb_vdev)(struct ocb_config *config);
+};
+#endif
diff --git a/components/ocb/dispatcher/inc/wlan_ocb_tgt_api.h b/components/ocb/dispatcher/inc/wlan_ocb_tgt_api.h
new file mode 100644
index 0000000..4456f60
--- /dev/null
+++ b/components/ocb/dispatcher/inc/wlan_ocb_tgt_api.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018 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: OCB south bound interface declaration
+ */
+#ifndef _WLAN_OCB_TGT_API_H
+#define _WLAN_OCB_TGT_API_H
+#include <wlan_ocb_public_structs.h>
+
+/**
+ * tgt_ocb_register_ev_handler() - register south bound event handler
+ * @pdev: pdev handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS tgt_ocb_register_ev_handler(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * tgt_ocb_unregister_ev_handler() - unregister south bound event handler
+ * @pdev: pdev handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS tgt_ocb_unregister_ev_handler(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * tgt_ocb_register_rx_ops() - register OCB rx operations
+ * @ocb_rxops: fps to rx operations
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS tgt_ocb_register_rx_ops(struct wlan_ocb_rx_ops *ocb_rxops);
+#endif
diff --git a/components/ocb/dispatcher/inc/wlan_ocb_ucfg_api.h b/components/ocb/dispatcher/inc/wlan_ocb_ucfg_api.h
new file mode 100644
index 0000000..de90f5b
--- /dev/null
+++ b/components/ocb/dispatcher/inc/wlan_ocb_ucfg_api.h
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: Contains OCB north bound interface definitions
+ */
+
+#ifndef _WLAN_OCB_UCFG_API_H_
+#define _WLAN_OCB_UCFG_API_H_
+#include <qdf_types.h>
+#include "wlan_ocb_public_structs.h"
+
+#ifdef WLAN_FEATURE_DSRC
+/**
+ * ucfg_ocb_set_channel_config() - send OCB config request
+ * @vdev: vdev handle
+ * @config: config parameters
+ * @set_config_cb: callback for set channel config
+ * @arg: arguments for the callback
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_set_channel_config(struct wlan_objmgr_vdev *vdev,
+				       struct ocb_config *config,
+				       ocb_sync_callback set_config_cb,
+				       void *arg);
+
+/**
+ * ucfg_ocb_set_utc_time() - UCFG API to set UTC time
+ * @vdev: vdev handle
+ * @utc: UTC time
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_set_utc_time(struct wlan_objmgr_vdev *vdev,
+				 struct ocb_utc_param *utc);
+
+/**
+ * ucfg_ocb_start_timing_advert() - ucfg API to start TA
+ * @vdev: vdev handle
+ * @ta: timing advertisement parameters
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_start_timing_advert(struct wlan_objmgr_vdev *vdev,
+					struct ocb_timing_advert_param *ta);
+
+/**
+ * ucfg_ocb_stop_timing_advert() - ucfg API to stop TA
+ * @vdev: vdev handle
+ * @ta: timing advertisement parameters
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_stop_timing_advert(struct wlan_objmgr_vdev *vdev,
+				       struct ocb_timing_advert_param *ta);
+
+/**
+ * ucfg_ocb_get_tsf_timer() - ucfg API to get tsf timer
+ * @vdev: vdev handle
+ * @request: request for TSF timer
+ * @get_tsf_cb: callback for TSF timer response
+ * @arg: argument for the ccallback
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_get_tsf_timer(struct wlan_objmgr_vdev *vdev,
+				  struct ocb_get_tsf_timer_param *request,
+				  ocb_sync_callback get_tsf_cb,
+				  void *arg);
+
+/**
+ * ucfg_ocb_dcc_get_stats() - get DCC stats
+ * @vdev: vdev handle
+ * @request: request for dcc stats
+ * @dcc_get_stats_cb: callback for get dcc stats response
+ * @arg: argument for the ccallback
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_dcc_get_stats(struct wlan_objmgr_vdev *vdev,
+				  struct ocb_dcc_get_stats_param *request,
+				  ocb_sync_callback dcc_get_stats_cb,
+				  void *arg);
+
+/**
+ * ucfg_ocb_dcc_clear_stats() - Clear DCC stats
+ * @vdev: vdev handle
+ * @vdev_id: vdev ID
+ * @bitmap: bitmap for stats to be cleared
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_dcc_clear_stats(struct wlan_objmgr_vdev *vdev,
+				    uint16_t vdev_id,
+				    uint32_t bitmap);
+
+/**
+ * ucfg_ocb_dcc_update_ndl() - ucfg API to update NDL
+ * @vdev: vdev handle
+ * @request: request parameters
+ * @dcc_update_ndl_cb: callback for update resposne
+ * @arg: argument for the callback
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_dcc_update_ndl(struct wlan_objmgr_vdev *vdev,
+				   struct ocb_dcc_update_ndl_param *request,
+				   ocb_sync_callback dcc_update_ndl_cb,
+				   void *arg);
+
+/**
+ * ucfg_ocb_register_for_dcc_stats_event() - register dcc stats
+ * events callback
+ * @pdev: pdev handle
+ * @context: argument for the callback
+ * @dcc_stats_cb: callback for dcc stats event
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_register_for_dcc_stats_event(struct wlan_objmgr_pdev *pdev,
+				void *ctx, ocb_sync_callback dcc_stats_cb);
+/**
+ * ucfg_ocb_init() - OCB module initialization
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_init(void);
+
+/**
+ * ucfg_ocb_deinit() - OCB module deinitialization
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_deinit(void);
+
+/**
+ * ucfg_ocb_config_channel() - Set channel config using after OCB started
+ * @pdev: pdev handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_config_channel(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_ocb_register_vdev_start() - register callback to start ocb vdev
+ * @pdev: pdev handle
+ * @ocb_start: legacy callback to start ocb vdev
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_register_vdev_start(struct wlan_objmgr_pdev *pdev,
+				QDF_STATUS (*ocb_start)(struct ocb_config *));
+
+/**
+ * ocb_psoc_enable() - Trigger psoc enable for ocb
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS ocb_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ocb_psoc_disable() - Trigger psoc disable for ocb
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+QDF_STATUS ocb_psoc_disable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_ocb_update_dp_handle() - register DP handle
+ * @soc: soc handle
+ * @dp_soc: data path soc handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_update_dp_handle(struct wlan_objmgr_psoc *soc,
+				     void *dp_soc);
+
+/**
+ * ucfg_ocb_set_txrx_handle() - register pdev txrx handler
+ * @soc: soc handle
+ * @txrx_handle: data path pdev txrx handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_ocb_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				    void *txrx_handle);
+#else
+/**
+ * ucfg_ocb_init() - OCB module initialization
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static inline QDF_STATUS ucfg_ocb_init(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_ocb_deinit() - OCB module deinitialization
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static inline QDF_STATUS ucfg_ocb_deinit(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_ocb_config_channel() - Set channel config using after OCB started
+ * @pdev: pdev handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static inline QDF_STATUS
+ucfg_ocb_config_channel(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ocb_psoc_enable() - Trigger psoc enable for ocb
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+static inline
+QDF_STATUS ocb_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ocb_psoc_disable() - Trigger psoc disable for ocb
+ * @psoc: objmgr psoc object
+ *
+ * Return: QDF status success or failure
+ */
+static inline
+QDF_STATUS ocb_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_ocb_update_dp_handle() - register DP handle
+ * @soc: soc handle
+ * @dp_soc: data path soc handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static inline
+QDF_STATUS ucfg_ocb_update_dp_handle(struct wlan_objmgr_psoc *soc,
+				     void *dp_soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ucfg_ocb_set_txrx_handle() - register pdev txrx handler
+ * @soc: soc handle
+ * @txrx_handle: data path pdev txrx handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static inline
+QDF_STATUS ucfg_ocb_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				    void *txrx_handle)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#endif
diff --git a/components/ocb/dispatcher/src/wlan_ocb_tgt_api.c b/components/ocb/dispatcher/src/wlan_ocb_tgt_api.c
new file mode 100644
index 0000000..e55027e
--- /dev/null
+++ b/components/ocb/dispatcher/src/wlan_ocb_tgt_api.c
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2018 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 ocb south bound interface definitions
+ */
+
+#include <scheduler_api.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include "wlan_ocb_public_structs.h"
+#include "wlan_ocb_ucfg_api.h"
+#include "wlan_ocb_tgt_api.h"
+#include "wlan_ocb_main.h"
+
+/**
+ * wlan_ocb_flush_callback() - OCB message flash callback
+ * @msg: OCB message
+ *
+ * Return: QDF_STATUS_SUCCESS on success.
+ */
+static QDF_STATUS wlan_ocb_flush_callback(struct scheduler_msg *msg)
+{
+	struct ocb_rx_event *event;
+
+	if (!msg) {
+		ocb_err("Null point for OCB message");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	event = msg->bodyptr;
+	wlan_ocb_release_rx_event(event);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * tgt_ocb_channel_config_status() - handler for channel config response
+ * @psoc: psoc handle
+ * @status: status for last channel config
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+tgt_ocb_channel_config_status(struct wlan_objmgr_psoc *psoc,
+			      uint32_t status)
+{
+	QDF_STATUS qdf_status;
+	struct scheduler_msg msg = {0};
+	struct ocb_rx_event *event;
+
+	event = qdf_mem_malloc(sizeof(*event));
+	if (!event) {
+		ocb_err("Memory malloc failed for channel config status");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	qdf_status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_OCB_SB_ID);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		ocb_err("Failed to get psoc ref");
+		wlan_ocb_release_rx_event(event);
+		return qdf_status;
+	}
+	event->psoc = psoc;
+	event->rsp.channel_cfg_rsp.status = status;
+	event->evt_id = OCB_CHANNEL_CONFIG_STATUS;
+	msg.type = OCB_CHANNEL_CONFIG_STATUS;
+	msg.bodyptr = event;
+	msg.callback = ocb_process_evt;
+	msg.flush_callback = wlan_ocb_flush_callback;
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_OCB,
+					    QDF_MODULE_ID_OCB,
+					    QDF_MODULE_ID_TARGET_IF, &msg);
+
+	if (QDF_IS_STATUS_SUCCESS(qdf_status))
+		return QDF_STATUS_SUCCESS;
+
+	ocb_err("failed to send OCB_CHANNEL_CONFIG_STATUS msg");
+	wlan_ocb_release_rx_event(event);
+
+	return qdf_status;
+}
+
+/**
+ * tgt_ocb_get_tsf_timer() - handle for TSF timer response
+ * @psoc: psoc handle
+ * @response: TSF timer response
+ *
+ * Return: QDF_STATUS_SUCCESS on succcess
+ */
+static QDF_STATUS
+tgt_ocb_get_tsf_timer(struct wlan_objmgr_psoc *psoc,
+		      struct ocb_get_tsf_timer_response *response)
+{
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+	struct ocb_rx_event *event;
+
+	event = qdf_mem_malloc(sizeof(*event));
+	if (!event) {
+		ocb_err("Memory malloc failed for tsf timer");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_OCB_SB_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ocb_err("Failed to get psoc ref");
+		goto flush_ref;
+	}
+	event->psoc = psoc;
+	event->vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+							   response->vdev_id,
+							   WLAN_OCB_SB_ID);
+	if (!event->vdev) {
+		ocb_err("Cannot get vdev handle");
+		status = QDF_STATUS_E_FAILURE;
+		goto flush_ref;
+	}
+
+	event->evt_id = OCB_TSF_TIMER;
+	event->rsp.tsf_timer.vdev_id = response->vdev_id;
+	event->rsp.tsf_timer.timer_high = response->timer_high;
+	event->rsp.tsf_timer.timer_low = response->timer_low;
+	msg.type = OCB_TSF_TIMER;
+	msg.bodyptr = event;
+	msg.callback = ocb_process_evt;
+	msg.flush_callback = wlan_ocb_flush_callback;
+
+	status = scheduler_post_message(QDF_MODULE_ID_OCB,
+					QDF_MODULE_ID_OCB,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	ocb_err("failed to send OCB_TSF_TIMER msg");
+flush_ref:
+	wlan_ocb_release_rx_event(event);
+
+	return status;
+}
+
+/**
+ * tgt_ocb_dcc_ndl_update() - handler for NDL update response
+ * @psoc: psoc handle
+ * @resp: NDL update response
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+tgt_ocb_dcc_ndl_update(struct wlan_objmgr_psoc *psoc,
+		       struct ocb_dcc_update_ndl_response *resp)
+{
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+	struct ocb_rx_event *event;
+
+	event = qdf_mem_malloc(sizeof(*event));
+	if (!event) {
+		ocb_err("Memory malloc failed for ndl update response");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_OCB_SB_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ocb_err("Failed to get psoc ref");
+		goto flush_ref;
+	}
+	event->psoc = psoc;
+	event->vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+							   resp->vdev_id,
+							   WLAN_OCB_SB_ID);
+	if (!event->vdev) {
+		ocb_err("Cannot get vdev handle");
+		status = QDF_STATUS_E_FAILURE;
+		goto flush_ref;
+	}
+
+	event->evt_id = OCB_NDL_RESPONSE;
+	qdf_mem_copy(&event->rsp.ndl, resp, sizeof(*resp));
+	msg.type = OCB_NDL_RESPONSE;
+	msg.bodyptr = event;
+	msg.callback = ocb_process_evt;
+	msg.flush_callback = wlan_ocb_flush_callback;
+
+	status = scheduler_post_message(QDF_MODULE_ID_OCB,
+					QDF_MODULE_ID_OCB,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	ocb_err("failed to send OCB_NDL_RESPONSE msg");
+flush_ref:
+	wlan_ocb_release_rx_event(event);
+
+	return status;
+}
+
+/**
+ * tgt_ocb_dcc_stats_indicate() - handler for DCC stats indication
+ * @psoc: psoc handle
+ * @response: DCC stats
+ * @bool: true for active query, false for passive indicate
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+tgt_ocb_dcc_stats_indicate(struct wlan_objmgr_psoc *psoc,
+			   struct ocb_dcc_get_stats_response *response,
+			   bool active)
+{
+	QDF_STATUS status;
+	uint8_t *buf;
+	uint32_t size;
+	struct scheduler_msg msg = {0};
+	struct ocb_rx_event *event;
+
+	size = sizeof(*event) +
+		response->channel_stats_array_len;
+	buf = qdf_mem_malloc(size);
+	if (!buf) {
+		ocb_err("Memory malloc failed for dcc indication");
+		return QDF_STATUS_E_NOMEM;
+	}
+	event = (struct ocb_rx_event *)buf;
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_OCB_SB_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ocb_err("Failed to get psoc ref");
+		goto flush_ref;
+	}
+	event->psoc = psoc;
+	event->vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+							   response->vdev_id,
+							   WLAN_OCB_SB_ID);
+	if (!event->vdev) {
+		ocb_err("Cannot get vdev handle");
+		status = QDF_STATUS_E_FAILURE;
+		goto flush_ref;
+	}
+
+	event->rsp.dcc_stats.channel_stats_array =
+		(uint8_t *)&event->rsp.dcc_stats +
+		sizeof(struct ocb_dcc_get_stats_response);
+	event->rsp.dcc_stats.vdev_id = response->vdev_id;
+	event->rsp.dcc_stats.num_channels = response->num_channels;
+	event->rsp.dcc_stats.channel_stats_array_len =
+		response->channel_stats_array_len;
+	qdf_mem_copy(event->rsp.dcc_stats.channel_stats_array,
+		     response->channel_stats_array,
+		     response->channel_stats_array_len);
+	ocb_debug("Message type is %s",
+		  active ? "Get stats response" : "DCC stats indication");
+	if (active)
+		msg.type = OCB_DCC_STATS_RESPONSE;
+	else
+		msg.type = OCB_DCC_INDICATION;
+	event->evt_id = msg.type;
+	msg.bodyptr = event;
+	msg.callback = ocb_process_evt;
+	msg.flush_callback = wlan_ocb_flush_callback;
+
+	status = scheduler_post_message(QDF_MODULE_ID_OCB,
+					QDF_MODULE_ID_OCB,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	ocb_err("failed to send DCC stats msg(%d)", msg.type);
+flush_ref:
+	wlan_ocb_release_rx_event(event);
+
+	return status;
+}
+
+QDF_STATUS tgt_ocb_register_ev_handler(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_ocb_tx_ops *ocb_ops;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc) {
+		ocb_err("Null soc handle");
+		return QDF_STATUS_E_INVAL;
+	}
+	ocb_ops = wlan_pdev_get_ocb_tx_ops(pdev);
+	if (ocb_ops && ocb_ops->ocb_reg_ev_handler) {
+		status = ocb_ops->ocb_reg_ev_handler(psoc, NULL);
+		ocb_debug("register ocb event, status:%d", status);
+	} else {
+		ocb_alert("No ocb objects or ocb_reg_ev_handler");
+	}
+
+	return status;
+}
+
+QDF_STATUS tgt_ocb_unregister_ev_handler(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_ocb_tx_ops *ocb_ops;
+	QDF_STATUS status;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc) {
+		ocb_err("Null soc handle");
+		return QDF_STATUS_E_INVAL;
+	}
+	ocb_ops = wlan_pdev_get_ocb_tx_ops(pdev);
+	if (ocb_ops && ocb_ops->ocb_unreg_ev_handler) {
+		status = ocb_ops->ocb_unreg_ev_handler(psoc, NULL);
+		ocb_debug("unregister ocb event, status:%d", status);
+	} else {
+		ocb_alert("No ocb objects or ocb_unreg_ev_handler");
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+QDF_STATUS tgt_ocb_register_rx_ops(struct wlan_ocb_rx_ops *ocb_rxops)
+{
+	ocb_rxops->ocb_set_config_status = tgt_ocb_channel_config_status;
+	ocb_rxops->ocb_tsf_timer = tgt_ocb_get_tsf_timer;
+	ocb_rxops->ocb_dcc_ndl_update = tgt_ocb_dcc_ndl_update;
+	ocb_rxops->ocb_dcc_stats_indicate = tgt_ocb_dcc_stats_indicate;
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/components/ocb/dispatcher/src/wlan_ocb_ucfg_api.c b/components/ocb/dispatcher/src/wlan_ocb_ucfg_api.c
new file mode 100644
index 0000000..de87d31
--- /dev/null
+++ b/components/ocb/dispatcher/src/wlan_ocb_ucfg_api.c
@@ -0,0 +1,629 @@
+/*
+ * Copyright (c) 2018 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 ocb north bound interface definitions
+ */
+
+#include <scheduler_api.h>
+#include <wlan_defs.h>
+#include <wlan_reg_services_api.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_ocb_public_structs.h>
+#include <wlan_ocb_ucfg_api.h>
+#include <wlan_ocb_tgt_api.h>
+#include <wlan_lmac_if_def.h>
+#include "wlan_ocb_main.h"
+
+/**
+ * wlan_ocb_get_tx_ops() - get target interface tx operations
+ * @pdev: pdev handle
+ *
+ * Return: fp to target interface operations
+ */
+static struct wlan_ocb_tx_ops *
+wlan_ocb_get_tx_ops(struct wlan_objmgr_pdev *pdev)
+{
+	struct ocb_pdev_obj *ocb_obj;
+
+	ocb_obj = wlan_get_pdev_ocb_obj(pdev);
+	if (!ocb_obj) {
+		ocb_err("failed to get OCB pdev object");
+		return NULL;
+	}
+
+	return &ocb_obj->ocb_txops;
+}
+
+QDF_STATUS ucfg_ocb_init(void)
+{
+	QDF_STATUS status;
+
+	ocb_notice("ocb module dispatcher init");
+	status = wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_OCB,
+		ocb_pdev_obj_create_notification, NULL);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ocb_err("Failed to register pdev create handler for ocb");
+
+		return status;
+	}
+
+	status = wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_OCB,
+		ocb_pdev_obj_destroy_notification, NULL);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ocb_err("Failed to register pdev destroy handler for ocb");
+		goto fail_delete_pdev;
+	}
+
+	return status;
+
+fail_delete_pdev:
+	wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_OCB,
+		ocb_pdev_obj_create_notification, NULL);
+
+	return status;
+}
+
+QDF_STATUS ucfg_ocb_deinit(void)
+{
+	QDF_STATUS status;
+
+	ocb_notice("ocb module dispatcher deinit");
+	status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_OCB,
+				ocb_pdev_obj_destroy_notification, NULL);
+	if (QDF_IS_STATUS_ERROR(status))
+		ocb_err("Failed to unregister pdev destroy handler");
+
+	status = wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_OCB,
+				ocb_pdev_obj_create_notification, NULL);
+	if (QDF_IS_STATUS_ERROR(status))
+		ocb_err("Failed to unregister pdev create handler");
+
+	return status;
+}
+
+QDF_STATUS ocb_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_objmgr_pdev *pdev;
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
+					  WLAN_OCB_NB_ID);
+	if (!pdev) {
+		ocb_err("Failed to get pdev handle");
+
+		return QDF_STATUS_E_FAILURE;
+	}
+	tgt_ocb_register_ev_handler(pdev);
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_NB_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ocb_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_objmgr_pdev *pdev;
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
+					  WLAN_OCB_NB_ID);
+	if (!pdev) {
+		ocb_err("Failed to get pdev handle");
+		return QDF_STATUS_E_FAILURE;
+	}
+	tgt_ocb_unregister_ev_handler(pdev);
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_NB_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_ocb_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				    void *txrx_handle)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct ocb_pdev_obj *ocb_obj;
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
+					  WLAN_OCB_NB_ID);
+	if (!pdev) {
+		ocb_err("Failed to get pdev handle");
+		return QDF_STATUS_E_FAILURE;
+	}
+	ocb_obj = wlan_get_pdev_ocb_obj(pdev);
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_NB_ID);
+	if (!ocb_obj) {
+		ocb_err("OCB object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	ocb_obj->dp_pdev = txrx_handle;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_ocb_update_dp_handle(struct wlan_objmgr_psoc *psoc,
+				     void *dp_soc)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct ocb_pdev_obj *ocb_obj;
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
+					  WLAN_OCB_NB_ID);
+	if (!pdev) {
+		ocb_err("Failed to get pdev handle");
+		return QDF_STATUS_E_FAILURE;
+	}
+	ocb_obj = wlan_get_pdev_ocb_obj(pdev);
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_NB_ID);
+	if (!ocb_obj) {
+		ocb_err("OCB object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	ocb_obj->dp_soc = dp_soc;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_ocb_config_channel(struct wlan_objmgr_pdev *pdev)
+{
+	QDF_STATUS status;
+	struct ocb_config *config;
+	struct ocb_pdev_obj *ocb_obj;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_ocb_tx_ops *tx_ops;
+
+	ocb_obj = wlan_get_pdev_ocb_obj(pdev);
+	if (!ocb_obj || !ocb_obj->channel_config) {
+		ocb_alert("The request could not be found");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	config = ocb_obj->channel_config;
+	ocb_debug("Set config to vdev%d", config->vdev_id);
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc) {
+		ocb_err("Null pointer for psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+	tx_ops = wlan_ocb_get_tx_ops(pdev);
+	if (tx_ops && tx_ops->ocb_set_config)
+		status = tx_ops->ocb_set_config(psoc, ocb_obj->channel_config);
+	else
+		status = QDF_STATUS_E_IO;
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		ocb_debug("Set channel cmd is sent to southbound");
+	} else {
+		ocb_err("Failed to set channel config to southbound");
+
+		if (ocb_obj->channel_config) {
+			/*
+			 * On success case, backup parameters will be released
+			 * after channel info is synced to DP
+			 */
+			ocb_info("release the backed config parameters");
+			qdf_mem_free(ocb_obj->channel_config);
+			ocb_obj->channel_config = NULL;
+		}
+	}
+
+	return status;
+}
+
+QDF_STATUS ucfg_ocb_set_channel_config(struct wlan_objmgr_vdev *vdev,
+				       struct ocb_config *config,
+				       ocb_sync_callback set_config_cb,
+				       void *arg)
+{
+	QDF_STATUS status;
+	enum wlan_vdev_state state;
+	uint32_t i;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_ocb_tx_ops *tx_ops;
+	struct ocb_pdev_obj *ocb_obj;
+	struct ocb_callbacks *ocb_cbs;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		ocb_err("Null pointer for pdev");
+		return QDF_STATUS_E_INVAL;
+	}
+	ocb_obj = wlan_get_pdev_ocb_obj(pdev);
+	if (!ocb_obj) {
+		ocb_alert("Failed to get OCB vdev object");
+		return QDF_STATUS_E_IO;
+	}
+
+	if (!config) {
+		ocb_err("Invalid config input");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (i = 0; i < config->channel_count; i++) {
+		if (WLAN_REG_CHAN_TO_BAND(wlan_reg_freq_to_chan(pdev,
+					  config->channels[i].chan_freq))
+				== BAND_2G)
+			config->channels[i].ch_mode = MODE_11G;
+		else
+			config->channels[i].ch_mode = MODE_11A;
+	}
+
+	/*
+	 * backup the new configuration,
+	 * it will be released after target's response
+	 */
+	ocb_obj->channel_config = ocb_copy_config(config);
+	if (!ocb_obj->channel_config) {
+		ocb_err("Failed to backup config");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	ocb_cbs = &ocb_obj->ocb_cbs;
+	ocb_cbs->ocb_set_config_callback = set_config_cb;
+	ocb_cbs->ocb_set_config_context = arg;
+
+	state = wlan_vdev_mlme_get_state(vdev);
+	if (state != WLAN_VDEV_S_RUN) {
+		/* Vdev is not started, start it */
+		ocb_debug("OCB vdev%d is not up", config->vdev_id);
+		status = ocb_vdev_start(ocb_obj);
+	} else {
+		psoc = wlan_vdev_get_psoc(vdev);
+		tx_ops = wlan_ocb_get_tx_ops(pdev);
+		if (tx_ops && tx_ops->ocb_set_config)
+			status = tx_ops->ocb_set_config(psoc, config);
+		else
+			status = QDF_STATUS_E_IO;
+
+		ocb_debug("Set config to vdev%d", config->vdev_id);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			ocb_debug("Set channel cmd is sent to southbound");
+		else
+			ocb_err("Failed to set channel config to southbound");
+	}
+
+	if (QDF_IS_STATUS_ERROR(status) && ocb_obj->channel_config) {
+		/*
+		 * On success case, backup parameters will be released
+		 * after channel info is synced to DP
+		 */
+		ocb_info("release the backed config parameters");
+		qdf_mem_free(ocb_obj->channel_config);
+		ocb_obj->channel_config = NULL;
+	}
+
+	return status;
+}
+
+QDF_STATUS ucfg_ocb_set_utc_time(struct wlan_objmgr_vdev *vdev,
+				 struct ocb_utc_param *utc)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_ocb_tx_ops *tx_ops;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!psoc || !pdev) {
+		ocb_err("Null pointer for psoc/pdev");
+		return QDF_STATUS_E_INVAL;
+	}
+	tx_ops = wlan_ocb_get_tx_ops(pdev);
+
+	if (!tx_ops) {
+		ocb_alert("tx_ops is null");
+		return QDF_STATUS_E_IO;
+	}
+	if (!tx_ops->ocb_set_utc_time) {
+		ocb_alert("ocb_set_utc_time is null");
+		return QDF_STATUS_E_IO;
+	}
+
+	status = tx_ops->ocb_set_utc_time(psoc, utc);
+	if (QDF_IS_STATUS_ERROR(status))
+		ocb_err("Failed to set UTC time to southbound");
+	else
+		ocb_debug("UTC time is sent to southbound");
+
+	return status;
+}
+
+QDF_STATUS ucfg_ocb_start_timing_advert(struct wlan_objmgr_vdev *vdev,
+					struct ocb_timing_advert_param *ta)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_ocb_tx_ops *tx_ops;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!psoc || !pdev) {
+		ocb_err("Null pointer for psoc/pdev");
+		return QDF_STATUS_E_INVAL;
+	}
+	tx_ops = wlan_ocb_get_tx_ops(pdev);
+	if (!tx_ops) {
+		ocb_alert("tx_ops is null");
+		return QDF_STATUS_E_IO;
+	}
+	if (!tx_ops->ocb_start_timing_advert) {
+		ocb_alert("ocb_start_timing_advert is null");
+		return QDF_STATUS_E_IO;
+	}
+	status = tx_ops->ocb_start_timing_advert(psoc, ta);
+	if (QDF_IS_STATUS_ERROR(status))
+		ocb_err("Failed to sent start timing advert to southbound");
+	else
+		ocb_debug("Start timing advert is sent to southbound");
+
+	return status;
+}
+
+QDF_STATUS ucfg_ocb_stop_timing_advert(struct wlan_objmgr_vdev *vdev,
+				       struct ocb_timing_advert_param *ta)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_ocb_tx_ops *tx_ops;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!psoc || !pdev) {
+		ocb_err("Null pointer for psoc/pdev");
+		return QDF_STATUS_E_INVAL;
+	}
+	tx_ops = wlan_ocb_get_tx_ops(pdev);
+	if (!tx_ops) {
+		ocb_alert("tx_ops is null");
+		return QDF_STATUS_E_IO;
+	}
+	if (!tx_ops->ocb_stop_timing_advert) {
+		ocb_alert("ocb_stop_timing_advert is null");
+		return QDF_STATUS_E_IO;
+	}
+	status = tx_ops->ocb_stop_timing_advert(psoc, ta);
+	if (QDF_IS_STATUS_ERROR(status))
+		ocb_err("Failed to sent start timing advert to southbound");
+	else
+		ocb_debug("Start timing advert is sent to southbound");
+
+	return status;
+}
+
+QDF_STATUS ucfg_ocb_get_tsf_timer(struct wlan_objmgr_vdev *vdev,
+				  struct ocb_get_tsf_timer_param *req,
+				  ocb_sync_callback get_tsf_cb,
+				  void *arg)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct ocb_get_tsf_timer_param request;
+	struct wlan_ocb_tx_ops *tx_ops;
+	struct ocb_callbacks *ocb_cbs;
+	struct wlan_objmgr_pdev *pdev;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		ocb_err("Null pointer for pdev");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_ops = wlan_ocb_get_tx_ops(pdev);
+	if (!tx_ops) {
+		ocb_alert("tx_ops is null");
+		return QDF_STATUS_E_IO;
+	}
+	if (!tx_ops->ocb_get_tsf_timer) {
+		ocb_alert("ocb_get_tsf_timer is null");
+		return QDF_STATUS_E_IO;
+	}
+
+	ocb_cbs = wlan_ocb_get_callbacks(pdev);
+	ocb_cbs->ocb_get_tsf_timer_context = arg;
+	ocb_cbs->ocb_get_tsf_timer_callback = get_tsf_cb;
+	request.vdev_id =  req->vdev_id;
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		ocb_err("Null pointer for psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+	status = tx_ops->ocb_get_tsf_timer(psoc, &request);
+	if (QDF_IS_STATUS_ERROR(status))
+		ocb_err("Failed to sent get tsf timer to southbound");
+	else
+		ocb_debug("Get tsf timer is sent to southbound");
+
+	return status;
+}
+
+QDF_STATUS ucfg_ocb_dcc_get_stats(struct wlan_objmgr_vdev *vdev,
+				  struct ocb_dcc_get_stats_param *request,
+				  ocb_sync_callback dcc_get_stats_cb,
+				  void *arg)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	struct ocb_callbacks *ocb_cbs;
+	struct wlan_ocb_tx_ops *tx_ops;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		ocb_err("Null pointer for pdev");
+		return QDF_STATUS_E_INVAL;
+	}
+	ocb_cbs = wlan_ocb_get_callbacks(pdev);
+	ocb_cbs->ocb_dcc_get_stats_context = arg;
+	ocb_cbs->ocb_dcc_get_stats_callback = dcc_get_stats_cb;
+
+	tx_ops = wlan_ocb_get_tx_ops(pdev);
+	if (!tx_ops) {
+		ocb_alert("tx_ops is null");
+		return QDF_STATUS_E_IO;
+	}
+
+	if (!tx_ops->ocb_dcc_get_stats) {
+		ocb_alert("ocb_dcc_get_stats is null");
+		return QDF_STATUS_E_IO;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		ocb_err("Null pointer for psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+	status = tx_ops->ocb_dcc_get_stats(psoc, request);
+	if (QDF_IS_STATUS_ERROR(status))
+		ocb_err("Failed to sent get dcc stats to southbound");
+	else
+		ocb_debug("Get dcc stats is sent to southbound");
+
+	return status;
+}
+
+QDF_STATUS ucfg_ocb_dcc_clear_stats(struct wlan_objmgr_vdev *vdev,
+				    uint16_t vdev_id,
+				    uint32_t bitmap)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_ocb_tx_ops *tx_ops;
+	struct ocb_dcc_clear_stats_param clear_stats_param;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		ocb_err("Null pointer for pdev");
+		return QDF_STATUS_E_INVAL;
+	}
+	tx_ops = wlan_ocb_get_tx_ops(pdev);
+	if (!tx_ops) {
+		ocb_alert("tx_ops is null");
+		return QDF_STATUS_E_IO;
+	}
+
+	if (!tx_ops->ocb_dcc_clear_stats) {
+		ocb_alert("ocb_dcc_clear_stats is null");
+		return QDF_STATUS_E_IO;
+	}
+
+	clear_stats_param.vdev_id = vdev_id;
+	clear_stats_param.dcc_stats_bitmap = bitmap;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		ocb_err("Null pointer for psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+	status = tx_ops->ocb_dcc_clear_stats(psoc, &clear_stats_param);
+	if (QDF_IS_STATUS_ERROR(status))
+		ocb_err("Failed to sent clear dcc stats to southbound");
+	else
+		ocb_debug("clear dcc stats is sent to southbound");
+
+	return status;
+}
+
+QDF_STATUS ucfg_ocb_dcc_update_ndl(struct wlan_objmgr_vdev *vdev,
+				   struct ocb_dcc_update_ndl_param *request,
+				   ocb_sync_callback dcc_update_ndl_cb,
+				   void *arg)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct ocb_callbacks *ocb_cbs;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_ocb_tx_ops *tx_ops;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		ocb_err("Null pointer for pdev");
+		return QDF_STATUS_E_INVAL;
+	}
+	ocb_cbs = wlan_ocb_get_callbacks(pdev);
+	ocb_cbs->ocb_dcc_update_ndl_context = arg;
+	ocb_cbs->ocb_dcc_update_ndl_callback = dcc_update_ndl_cb;
+
+	tx_ops = wlan_ocb_get_tx_ops(pdev);
+	if (!tx_ops) {
+		ocb_alert("tx_ops is null");
+		return QDF_STATUS_E_IO;
+	}
+	if (!tx_ops->ocb_dcc_update_ndl) {
+		ocb_alert("dcc_update_ndl is null");
+		return QDF_STATUS_E_IO;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		ocb_err("Null pointer for psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+	status = tx_ops->ocb_dcc_update_ndl(psoc, request);
+	if (QDF_IS_STATUS_ERROR(status))
+		ocb_err("Failed to sent update ndl to southbound");
+	else
+		ocb_debug("Update ndl is sent to southbound");
+
+	return status;
+}
+
+QDF_STATUS ucfg_ocb_register_for_dcc_stats_event(struct wlan_objmgr_pdev *pdev,
+				void *ctx, ocb_sync_callback dcc_stats_cb)
+{
+	struct ocb_callbacks *ocb_cbs;
+
+	if (!pdev) {
+		ocb_err("Null pointer for pdev");
+		return QDF_STATUS_E_INVAL;
+	}
+	ocb_cbs = wlan_ocb_get_callbacks(pdev);
+
+	if (!ocb_cbs) {
+		ocb_err("Failed to register dcc stats callback");
+		return QDF_STATUS_E_FAILURE;
+	}
+	ocb_cbs->ocb_dcc_stats_event_context = ctx;
+	ocb_cbs->ocb_dcc_stats_event_callback = dcc_stats_cb;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_ocb_register_vdev_start(struct wlan_objmgr_pdev *pdev,
+				QDF_STATUS (*ocb_start)(struct ocb_config *))
+{
+	struct ocb_callbacks *ocb_cbs;
+
+	if (!pdev) {
+		ocb_err("Null pointer for pdev");
+		return QDF_STATUS_E_INVAL;
+	}
+	ocb_cbs = wlan_ocb_get_callbacks(pdev);
+
+	if (!ocb_cbs) {
+		ocb_err("Failed to register dcc stats callback");
+		return QDF_STATUS_E_FAILURE;
+	}
+	ocb_cbs->start_ocb_vdev = ocb_start;
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/components/pmo/core/inc/wlan_pmo_apf.h b/components/pmo/core/inc/wlan_pmo_apf.h
new file mode 100644
index 0000000..64dfa34
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_apf.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 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: Android Packet Filter (APF) headers for PMO
+ */
+
+#ifndef __WLAN_PMO_APF_H
+#define __WLAN_PMO_APF_H
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#include "qdf_types.h"
+#include "wlan_objmgr_psoc_obj.h"
+
+/**
+ * pmo_get_apf_instruction_size() - get the current APF instruction size
+ * @psoc: the psoc to query
+ *
+ * Return: APF instruction size
+ */
+uint32_t pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc);
+
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#endif /* __WLAN_PMO_APF_H */
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..d577cd2
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_arp.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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);
+
+/**
+ * pmo_core_get_arp_offload_params() - API to get arp offload params
+ * @vdev: objmgr vdev
+ * @params: output pointer to hold offload params
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS
+pmo_core_get_arp_offload_params(struct wlan_objmgr_vdev *vdev,
+				struct pmo_arp_offload_params *params);
+
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#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..4477487
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_gtk.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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 /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#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..6739cd0
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_hw_filter.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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_POWER_MANAGEMENT_OFFLOAD */
+
+#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..00caccc
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_lphb.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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 /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#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..9232b44
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_main.h
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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_fatal(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_PMO, params)
+#define pmo_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_PMO, params)
+#define pmo_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_PMO, params)
+#define pmo_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_PMO, params)
+#define pmo_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_PMO, params)
+
+#define pmo_nofl_fatal(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_PMO, params)
+#define pmo_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_PMO, params)
+#define pmo_nofl_warn(params...) \
+	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_PMO, params)
+#define pmo_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_PMO, params)
+#define pmo_nofl_debug(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_PMO, params)
+
+#define pmo_enter() QDF_TRACE_ENTER(QDF_MODULE_ID_PMO, "enter")
+#define pmo_exit() QDF_TRACE_EXIT(QDF_MODULE_ID_PMO, "exit")
+
+#define PMO_VDEV_IN_STA_MODE(mode) \
+	((mode) == QDF_STA_MODE || (mode) == QDF_P2P_CLIENT_MODE ? 1 : 0)
+
+static inline enum QDF_OPMODE pmo_get_vdev_opmode(struct wlan_objmgr_vdev *vdev)
+{
+	return wlan_vdev_mlme_get_opmode(vdev);
+}
+
+/**
+ * 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_psoc_open() - pmo psoc object open
+ * @psoc: objmgr vdev
+ *.
+ * This function used to open pmo psoc object
+ *
+ * Return: Success or failure
+ */
+QDF_STATUS pmo_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_psoc_close() - pmo psoc object close
+ * @psoc: objmgr vdev
+ *.
+ * This function used to close pmo psoc object
+ *
+ * Return: Success or failure
+ */
+QDF_STATUS pmo_psoc_close(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * 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 QDF_OPMODE 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 QDF_OPMODE 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_psoc_set_caps() - overwrite configured device capability flags
+ * @psoc: the psoc for which the capabilities apply
+ * @caps: the cabability information to configure
+ *
+ * Return: None
+ */
+void pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc,
+		       struct pmo_device_caps *caps);
+
+/**
+ * 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 QDF_OPMODE pmo_core_get_vdev_op_mode(
+					struct wlan_objmgr_vdev *vdev)
+{
+	enum QDF_OPMODE 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;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->dp_hdl = dp_hdl;
+	}
+}
+
+/**
+ * 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 = NULL;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		dp_hdl = psoc_ctx->dp_hdl;
+	}
+
+	return dp_hdl;
+}
+
+/**
+ * pmo_core_vdev_get_dp_handle() - Get vdev data path handle
+ * @psoc_ctx: pmo psoc private context
+ * @vdev_id: vdev id config to get data path handle
+ *
+ * Return: Vdev data path handle
+ */
+static inline
+struct cdp_vdev *pmo_core_vdev_get_dp_handle(struct pmo_psoc_priv_obj *psoc_ctx,
+					     uint8_t vdev_id)
+{
+	struct cdp_vdev *dp_hdl = NULL;
+	pmo_get_vdev_dp_handle handler;
+
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	handler = psoc_ctx->get_vdev_dp_handle;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	if (handler)
+		dp_hdl = handler(vdev_id);
+
+	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;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->htc_hdl = htc_hdl;
+	}
+}
+
+/**
+ * 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 = NULL;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		htc_hdl = psoc_ctx->htc_hdl;
+	}
+
+	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_intersect_arp_ns_offload() - intersect config and firmware capability for
+ *	the ARP/NS Offload feature
+ * @psoc_ctx: A PMO psoc context
+ *
+ * Note: The caller is expected to grab the PMO context lock.
+ *
+ * Return: True if firmware supports and configuration has enabled the feature
+ */
+static inline bool
+pmo_intersect_arp_ns_offload(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	struct pmo_psoc_cfg *cfg = &psoc_ctx->psoc_cfg;
+	bool arp_ns_enabled =
+		cfg->ns_offload_enable_static ||
+		cfg->ns_offload_enable_dynamic ||
+		cfg->arp_offload_enable;
+
+	return arp_ns_enabled && psoc_ctx->caps.arp_ns_offload;
+}
+
+/**
+ * pmo_intersect_apf() - intersect config and firmware capability for
+ *	the APF feature
+ * @psoc_ctx: A PMO psoc context
+ *
+ * Note: The caller is expected to grab the PMO context lock.
+ *
+ * Return: True if firmware supports and configuration has enabled the feature
+ */
+static inline bool pmo_intersect_apf(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	return psoc_ctx->psoc_cfg.apf_enable && psoc_ctx->caps.apf;
+}
+
+/**
+ * pmo_intersect_packet_filter() - intersect config and firmware capability for
+ *	the APF feature
+ * @psoc_ctx: A PMO psoc context
+ *
+ * Note: The caller is expected to grab the PMO context lock.
+ *
+ * Return: True if firmware supports and configuration has enabled the feature
+ */
+static inline bool
+pmo_intersect_packet_filter(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	return psoc_ctx->psoc_cfg.packet_filter_enabled &&
+		psoc_ctx->caps.packet_filter;
+}
+
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#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..fd0cca9
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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_enhance_mc_filter_enable() - enable enhanced multicast filtering
+ * @vdev: the vdev to enable enhanced multicast filtering for
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_core_enhanced_mc_filter_enable(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_enhance_mc_filter_disable() - disable enhanced multicast filtering
+ * @vdev: the vdev to disable enhanced multicast filtering for
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_core_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * 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);
+
+/**
+ * pmo_core_get_mc_addr_list() - Get mc addr list configured
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev identifier
+ * @mc_list_req: output pointer to hold mc addr list params
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS
+pmo_core_get_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+			  uint8_t vdev_id,
+			  struct pmo_mc_addr_list *mc_list_req);
+
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#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..26662dd
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_ns.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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);
+
+/**
+ * pmo_core_get_ns_offload_params() - API to get ns offload params
+ * @vdev: objmgr vdev
+ * @params: output pointer to hold offload params
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS
+pmo_core_get_ns_offload_params(struct wlan_objmgr_vdev *vdev,
+			       struct pmo_ns_offload_params *params);
+
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#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..41db7e3
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_objmgr.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2017-2018 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
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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;
+
+	QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS);
+	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS)
+		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;
+}
+
+static inline bool __pmo_spinlock_bh_safe(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	if (!psoc_ctx)
+		return false;
+
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+
+	return true;
+}
+
+#define pmo_psoc_with_ctx(psoc, cursor) \
+	for (cursor = pmo_psoc_get_priv(psoc); \
+	     __pmo_spinlock_bh_safe(cursor); \
+	     qdf_spin_unlock_bh(&cursor->lock), cursor = NULL)
+
+/* 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_POWER_MANAGEMENT_OFFLOAD */
+
+#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..7a3db9b
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_pkt_filter.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017-2018 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_H_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#include "wlan_pmo_pkt_filter_public_struct.h"
+
+struct wlan_objmgr_psoc;
+
+/**
+ * pmo_get_num_packet_filters() - get the number of packet filters
+ * @psoc: the psoc to query
+ *
+ * Return: number of packet filters
+ */
+uint32_t pmo_get_num_packet_filters(struct wlan_objmgr_psoc *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 /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#endif /* _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..4a9a266
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_priv.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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
+ * @caps: PMO specific device capability bits
+ * @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
+ * @get_cfg_int: register callback to get integer from cfg
+ * @get_dtim_period: register callback to get dtim period from mlme
+ * @get_beacon_interval: register callback to get beacon interval from mlme
+ * @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;
+	struct pmo_device_caps caps;
+	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_get_vdev_dp_handle get_vdev_dp_handle;
+	pmo_is_device_in_low_pwr_mode is_device_in_low_pwr_mode;
+	pmo_get_cfg_int get_cfg_int;
+	pmo_get_dtim_period get_dtim_period;
+	pmo_get_beacon_interval get_beacon_interval;
+	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
+ * @dyn_modulated_dtim: dynamically configured modulated dtim value
+ * @dyn_modulated_dtim_enabled: if dynamically modulated dtim is set or not
+ * @dyn_listen_interval: dynamically user configured listen interval
+ * @restore_dtim_setting: DTIM settings restore flag
+ * @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;
+	uint32_t dyn_modulated_dtim;
+	bool dyn_modulated_dtim_enabled;
+	uint32_t dyn_listen_interval;
+	bool restore_dtim_setting;
+	qdf_spinlock_t pmo_vdev_lock;
+};
+
+/**
+ * enum pmo_cfg_int_type: Mapping for Mac config param ID's
+ * @PMO_CFG_DTIM_PERIOD: CFG ID for Dtim Period value
+ * @PMO_CFG_LISTEN_INTERVAL: CFG ID for Listen Interval value
+ */
+enum pmo_cfg_int_type {
+	PMO_CFG_DTIM_PERIOD = 0x5,
+	PMO_CFG_LISTEN_INTERVAL = 0x26,
+};
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#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..9265ea6
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_static_config.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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 apf filter
+ *  enabled or not
+ * @psoc: objmgr psoc
+ * @apf_enabled: true when apf service is enabled else false
+ *
+ * Return: none
+ */
+void pmo_update_ra_limit(struct wlan_objmgr_psoc *psoc, bool apf_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 /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#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..18289df
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_suspend_resume.h
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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 = false;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		value = psoc_ctx->wow.is_wow_bus_suspended;
+	}
+
+	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_vdev_set_restore_dtim() - vdev dtim restore setting value
+ * @vdev: objmgr vdev handle
+ * @value: dtim restore policy value
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_vdev_set_restore_dtim(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->restore_dtim_setting = value;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_core_vdev_get_restore_dtim() - Get vdev restore dtim setting
+ * @vdev: objmgr vdev handle
+ *
+ * Return: dtim restore policy
+ */
+static inline
+bool pmo_core_vdev_get_restore_dtim(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);
+	value = vdev_ctx->restore_dtim_setting;
+	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;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->psoc_cfg.power_save_mode = value;
+	}
+}
+
+/**
+ * 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 = 0;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		value = psoc_ctx->psoc_cfg.power_save_mode;
+	}
+
+	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_debug("QPOWER is enabled in power save mode %d", ps_mode);
+		return pmo_qpower_enabled;
+	case pmo_ps_duty_cycling_qpower:
+		pmo_debug("DUTY cycling QPOWER is enabled in power save mode %d",
+			ps_mode);
+		return pmo_qpower_duty_cycling;
+	default:
+		pmo_debug("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 QDF_OPMODE 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 QDF_OPMODE 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);
+
+/**
+ * pmo_core_config_listen_interval() - function to dynamically configure
+ * listen interval
+ * @vdev: objmgr vdev
+ * @listen_interval: new listen interval passed by user
+ *
+ * This function allows user to configure listen interval dynamically
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_core_config_listen_interval(struct wlan_objmgr_vdev *vdev,
+					   uint32_t listen_interval);
+
+/**
+ * pmo_core_config_modulated_dtim() - function to configure modulated dtim
+ * @vdev: objmgr vdev handle
+ * @mod_dtim: New modulated dtim value passed by user
+ *
+ * This function configures the modulated dtim in firmware
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_core_config_modulated_dtim(struct wlan_objmgr_vdev *vdev,
+					  uint32_t mod_dtim);
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#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..b3a0189
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_wow.h
@@ -0,0 +1,675 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+#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
+
+#define PMO_WOW_FILTERS_ARP_NS		2
+#define PMO_WOW_FILTERS_PKT_OR_APF	5
+/* Default Listen Interval */
+#define PMO_DEFAULT_LISTEN_INTERVAL 1
+
+/**
+ * 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;
+
+	if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
+		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);
+	} else {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+		count = vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def++;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->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)
+{
+	if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+		vdev_ctx->num_wow_default_patterns++;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+	} else {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+		vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def++;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->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)
+{
+	if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+		vdev_ctx->num_wow_default_patterns--;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+	} else {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+		vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def--;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+	}
+}
+
+/**
+ * pmo_get_wow_default_ptrn() -Get wow default ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to get wow default ptrn
+ *
+ * Return: current wow default ptrn count
+ */
+static inline uint8_t pmo_get_wow_default_ptrn(
+		struct pmo_vdev_priv_obj *vdev_ctx)
+{
+	uint8_t count;
+
+	if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
+		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);
+	} else {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+		count = vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+	}
+
+	return count;
+}
+
+/**
+ * pmo_get_wow_default_ptrn() -Set wow default ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to set wow default ptrn
+ *
+ * Return: Set wow default ptrn count
+ */
+static inline void pmo_set_wow_default_ptrn(
+		struct pmo_vdev_priv_obj *vdev_ctx, uint8_t value)
+{
+	if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+		vdev_ctx->num_wow_default_patterns = value;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+	} else {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+		vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def = value;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->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)
+{
+	if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+		vdev_ctx->num_wow_user_patterns++;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+	} else {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+		vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_usr++;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->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)
+{
+	if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+		vdev_ctx->num_wow_user_patterns--;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+	} else {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+		vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_usr--;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+	}
+}
+
+/**
+ * pmo_get_wow_user_ptrn() -Get wow user ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to Get wow user ptrn
+ *
+ * Return: None
+ */
+static inline uint8_t pmo_get_wow_user_ptrn(
+		struct pmo_vdev_priv_obj *vdev_ctx)
+{
+	uint8_t count;
+
+	if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+		count = vdev_ctx->num_wow_user_patterns;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+	} else {
+		qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+		count = vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_usr;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
+	}
+
+	return count;
+}
+
+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_user_pattern(struct wlan_objmgr_vdev *vdev,
+			struct pmo_wow_add_pattern *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 delete
+ *
+ * Return: error if any errors encountered, QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS pmo_core_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
+			uint8_t pattern_id);
+
+/**
+ * pmo_core_enable_wakeup_event() -  enable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @wow_event: wow event to enable
+ *
+ * Return: none
+ */
+void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+				  uint32_t vdev_id,
+				  WOW_WAKE_EVENT_TYPE wow_event);
+
+/**
+ * pmo_core_disable_wakeup_event() -  disable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @wow_event: wow event to disable
+ *
+ * Return: none
+ */
+void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+				   uint32_t vdev_id,
+				   WOW_WAKE_EVENT_TYPE wow_event);
+
+/**
+ * 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
+
+/**
+ * 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:%pK idx:%pK 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);
+	}
+}
+
+/**
+ * pmo_get_num_wow_filters() - get the supported number of WoW filters
+ * @psoc: the psoc to query
+ *
+ * Return: number of WoW filters supported
+ */
+uint8_t pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc);
+
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#endif /* end  of _WLAN_PMO_WOW_H_ */
diff --git a/components/pmo/core/src/wlan_pmo_apf.c b/components/pmo/core/src/wlan_pmo_apf.c
new file mode 100644
index 0000000..8acc3c1
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_apf.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018 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: PMO implementations for Android Packet Filter (APF) functions
+ */
+
+#include "qdf_types.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_pmo_apf.h"
+#include "wlan_pmo_main.h"
+
+#define PMO_APF_SIZE_AUTO	0
+#define PMO_APF_SIZE_DISABLE	0xffffffff
+
+uint32_t pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	bool apf = false;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		apf = pmo_intersect_apf(psoc_ctx);
+	}
+
+	return apf ? PMO_APF_SIZE_AUTO : PMO_APF_SIZE_DISABLE;
+}
+
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..cbc54c9
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_arp.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2017-2018 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_vdev_priv_obj *vdev_ctx;
+	int index;
+	struct qdf_mac_addr peer_bssid;
+
+	pmo_enter();
+
+	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 exit_with_status;
+	}
+
+	status = pmo_get_vdev_bss_peer_mac_addr(vdev, &peer_bssid);
+	if (status != QDF_STATUS_SUCCESS)
+		goto free_req;
+
+	qdf_mem_copy(&request->bssid.bytes, &peer_bssid.bytes,
+			QDF_MAC_ADDR_SIZE);
+	pmo_debug("vdev self mac addr: %pM bss peer mac addr: %pM",
+		wlan_vdev_mlme_get_macaddr(vdev),
+		peer_bssid.bytes);
+
+	request->enable = PMO_OFFLOAD_ENABLE;
+	request->is_offload_applied = false;
+	/* 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_debug("cached arp offload; addr:" QDF_IPV4_ADDR_STR ", enable:%d",
+		  QDF_IPV4_ADDR_ARRAY(request->host_ipv4_addr),
+		  request->enable);
+
+free_req:
+	qdf_mem_free(request);
+
+exit_with_status:
+	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;
+	vdev_ctx->vdev_arp_req.is_offload_applied = false;
+	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;
+	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_debug("active offload is disabled, skip in mode %d",
+				  trigger);
+			status = QDF_STATUS_SUCCESS;
+			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_debug("active offload is enabled, skip in mode %d",
+				  trigger);
+			status = QDF_STATUS_SUCCESS;
+			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_debug("active offload is enabled, skip in mode: %d",
+				trigger);
+			status = QDF_STATUS_SUCCESS;
+			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_debug("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_debug("Cache arp for vdev id: %d psoc: %pK vdev: %pK",
+			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_debug("Flush arp for vdev id: %d vdev: %pK", 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 put_ref;
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_debug("Enable arp offload in fwr vdev id: %d vdev: %pK",
+		vdev_id, vdev);
+
+	status = pmo_core_do_enable_arp_offload(vdev, vdev_id, trigger);
+
+put_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_debug("Disable arp offload in fwr vdev id: %d vdev: %pK",
+		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;
+}
+
+QDF_STATUS
+pmo_core_get_arp_offload_params(struct wlan_objmgr_vdev *vdev,
+				struct pmo_arp_offload_params *params)
+{
+	QDF_STATUS status;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	uint8_t vdev_id;
+
+	pmo_enter();
+
+	if (!params)
+		return QDF_STATUS_E_INVAL;
+
+	qdf_mem_zero(params, sizeof(*params));
+
+	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 put_ref;
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	*params = vdev_ctx->vdev_arp_req;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+put_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..30a8ffd
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_gtk.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2017-2018 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_debug("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_debug("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_debug("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 QDF_OPMODE 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_debug("vdev opmode: %d vdev_id: %d", opmode, vdev_id);
+	if (!pmo_core_is_vdev_supports_offload(vdev)) {
+		pmo_debug("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 QDF_OPMODE 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_debug("vdev opmode: %d vdev_id: %d", opmode, vdev_id);
+	if (!pmo_core_is_vdev_supports_offload(vdev)) {
+		pmo_debug("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..6dec685
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_hw_filter.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017-2018 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"
+
+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_bitmap;
+	struct pmo_hw_filter_params req = {0};
+
+	pmo_enter();
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto exit_with_status;
+
+	if (!pmo_core_is_vdev_connected(vdev)) {
+		status = QDF_STATUS_E_NOSUPPORT;
+		goto exit_with_status;
+	}
+
+	psoc_priv = pmo_vdev_get_psoc_priv(vdev);
+	qdf_spin_lock_bh(&psoc_priv->lock);
+	mode_bitmap = psoc_priv->psoc_cfg.hw_filter_mode_bitmap;
+	qdf_spin_unlock_bh(&psoc_priv->lock);
+
+	req.vdev_id = pmo_vdev_get_id(vdev);
+	req.mode_bitmap = psoc_priv->psoc_cfg.hw_filter_mode_bitmap;
+	req.enable = true;
+	status = pmo_tgt_conf_hw_filter(pmo_vdev_get_psoc(vdev), &req);
+
+	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;
+	struct pmo_psoc_priv_obj *psoc_priv;
+	enum pmo_hw_filter_mode mode_bitmap;
+	struct pmo_hw_filter_params req = {0};
+
+	pmo_enter();
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto exit_with_status;
+
+	if (!pmo_core_is_vdev_connected(vdev)) {
+		status = QDF_STATUS_E_NOSUPPORT;
+		goto exit_with_status;
+	}
+
+	psoc_priv = pmo_vdev_get_psoc_priv(vdev);
+	qdf_spin_lock_bh(&psoc_priv->lock);
+	mode_bitmap = psoc_priv->psoc_cfg.hw_filter_mode_bitmap;
+	qdf_spin_unlock_bh(&psoc_priv->lock);
+
+	req.vdev_id = pmo_vdev_get_id(vdev);
+	req.mode_bitmap = mode_bitmap;
+	req.enable = false;
+	status = pmo_tgt_conf_hw_filter(pmo_vdev_get_psoc(vdev), &req);
+
+	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..2ee672a
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_lphb.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2017-2018 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 && ts_lphb_enable->item > 0) {
+		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_debug("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_debug("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_debug("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..b75bdb4
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_main.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 2017-2018 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"
+#include "wlan_pmo_cfg.h"
+#include "cfg_ucfg_api.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;
+}
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+static void wlan_extwow_init_cfg(struct wlan_objmgr_psoc *psoc,
+				 struct pmo_psoc_cfg *psoc_cfg)
+{
+	psoc_cfg->extwow_goto_suspend =
+			cfg_get(psoc, CFG_EXTWOW_GOTO_SUSPEND);
+	psoc_cfg->extwow_app1_wakeup_pin_num =
+			cfg_get(psoc, CFG_EXTWOW_APP1_WAKE_PIN_NUMBER);
+	psoc_cfg->extwow_app2_wakeup_pin_num =
+			cfg_get(psoc, CFG_EXTWOW_APP2_WAKE_PIN_NUMBER);
+	psoc_cfg->extwow_app2_init_ping_interval =
+			cfg_get(psoc, CFG_EXTWOW_KA_INIT_PING_INTERVAL);
+	psoc_cfg->extwow_app2_min_ping_interval =
+			cfg_get(psoc, CFG_EXTWOW_KA_MIN_PING_INTERVAL);
+	psoc_cfg->extwow_app2_max_ping_interval =
+			cfg_get(psoc, CFG_EXTWOW_KA_MAX_PING_INTERVAL);
+	psoc_cfg->extwow_app2_inc_ping_interval =
+			cfg_get(psoc, CFG_EXTWOW_KA_INC_PING_INTERVAL);
+	psoc_cfg->extwow_app2_tcp_src_port =
+			cfg_get(psoc, CFG_EXTWOW_TCP_SRC_PORT);
+	psoc_cfg->extwow_app2_tcp_dst_port =
+			cfg_get(psoc, CFG_EXTWOW_TCP_DST_PORT);
+	psoc_cfg->extwow_app2_tcp_tx_timeout =
+			cfg_get(psoc, CFG_EXTWOW_TCP_TX_TIMEOUT);
+	psoc_cfg->extwow_app2_tcp_rx_timeout =
+			cfg_get(psoc, CFG_EXTWOW_TCP_RX_TIMEOUT);
+}
+#else
+static void wlan_extwow_init_cfg(struct wlan_objmgr_psoc *psoc,
+				 struct pmo_psoc_cfg *psoc_cfg)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_WOW_PULSE
+static void wlan_pmo_wow_pulse_init_cfg(struct wlan_objmgr_psoc *psoc,
+					struct pmo_psoc_cfg *psoc_cfg)
+{
+	psoc_cfg->is_wow_pulse_supported =
+			cfg_get(psoc, CFG_PMO_WOW_PULSE_ENABLE);
+	psoc_cfg->wow_pulse_pin = cfg_get(psoc, CFG_PMO_WOW_PULSE_PIN);
+	psoc_cfg->wow_pulse_interval_high =
+			cfg_get(psoc, CFG_PMO_WOW_PULSE_HIGH);
+	psoc_cfg->wow_pulse_interval_low =
+			cfg_get(psoc, CFG_PMO_WOW_PULSE_LOW);
+}
+#else
+static void wlan_pmo_wow_pulse_init_cfg(struct wlan_objmgr_psoc *psoc,
+					struct pmo_psoc_cfg *psoc_cfg)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+static void wlan_pmo_pkt_filter_init_cfg(struct wlan_objmgr_psoc *psoc,
+					 struct pmo_psoc_cfg *psoc_cfg)
+{
+	psoc_cfg->packet_filters_bitmap = cfg_get(psoc, CFG_PMO_PKT_FILTER);
+}
+#else
+static void wlan_pmo_pkt_filter_init_cfg(struct wlan_objmgr_psoc *psoc,
+					 struct pmo_psoc_cfg *psoc_cfg)
+{
+}
+#endif
+
+#ifdef FEATURE_RUNTIME_PM
+static void wlan_pmo_runtime_pm_init_cfg(struct wlan_objmgr_psoc *psoc,
+					 struct pmo_psoc_cfg *psoc_cfg)
+{
+	psoc_cfg->runtime_pm_delay = cfg_get(psoc, CFG_PMO_RUNTIME_PM_DELAY);
+}
+#else
+static void wlan_pmo_runtime_pm_init_cfg(struct wlan_objmgr_psoc *psoc,
+					 struct pmo_psoc_cfg *psoc_cfg)
+{
+}
+#endif
+
+static void wlan_pmo_init_cfg(struct wlan_objmgr_psoc *psoc,
+			      struct pmo_psoc_cfg *psoc_cfg)
+{
+	psoc_cfg->arp_offload_enable =
+			cfg_get(psoc, CFG_PMO_ENABLE_HOST_ARPOFFLOAD);
+	psoc_cfg->hw_filter_mode_bitmap = cfg_get(psoc, CFG_PMO_HW_FILTER_MODE);
+	psoc_cfg->ssdp = cfg_get(psoc, CFG_PMO_ENABLE_HOST_SSDP);
+	psoc_cfg->ns_offload_enable_static =
+			cfg_get(psoc, CFG_PMO_ENABLE_HOST_NSOFFLOAD);
+	psoc_cfg->ns_offload_enable_dynamic =
+			cfg_get(psoc, CFG_PMO_ENABLE_HOST_NSOFFLOAD);
+	psoc_cfg->sta_dynamic_dtim = cfg_get(psoc, CFG_PMO_ENABLE_DYNAMIC_DTIM);
+	psoc_cfg->sta_mod_dtim = cfg_get(psoc, CFG_PMO_ENABLE_MODULATED_DTIM);
+	psoc_cfg->enable_mc_list = cfg_get(psoc, CFG_PMO_MC_ADDR_LIST_ENABLE);
+	psoc_cfg->power_save_mode = cfg_get(psoc, CFG_PMO_POWERSAVE_OFFLOAD);
+	psoc_cfg->max_ps_poll = cfg_get(psoc, CFG_PMO_MAX_PS_POLL);
+
+	psoc_cfg->wow_enable = cfg_get(psoc, CFG_PMO_WOW_ENABLE);
+	psoc_cfg->wowlan_deauth_enable =
+			cfg_get(psoc, CFG_PMO_WOWLAN_DEAUTH_ENABLE);
+	psoc_cfg->wowlan_disassoc_enable =
+			cfg_get(psoc, CFG_PMO_WOWLAN_DISASSOC_ENABLE);
+
+	wlan_extwow_init_cfg(psoc, psoc_cfg);
+	psoc_cfg->apf_enable = cfg_get(psoc, CFG_PMO_APF_ENABLE);
+	psoc_cfg->active_mode_offload = cfg_get(psoc, CFG_PMO_ACTIVE_MODE);
+	wlan_pmo_wow_pulse_init_cfg(psoc, psoc_cfg);
+	wlan_pmo_pkt_filter_init_cfg(psoc, psoc_cfg);
+	wlan_pmo_runtime_pm_init_cfg(psoc, psoc_cfg);
+	psoc_cfg->auto_power_save_fail_mode =
+			cfg_get(psoc, CFG_PMO_PWR_FAILURE);
+}
+
+QDF_STATUS pmo_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx;
+
+	if (!psoc) {
+		pmo_err("null psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+	wlan_pmo_init_cfg(psoc, &pmo_psoc_ctx->psoc_cfg);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+bool pmo_is_vdev_in_beaconning_mode(enum QDF_OPMODE 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 QDF_OPMODE 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_debug("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_debug("bss peer is null");
+		return false;
+	}
+
+	peer_state = wlan_peer_mlme_get_state(peer);
+	if (peer_state != WLAN_ASSOC_STATE) {
+		pmo_debug("peer is not associated; state:%d", peer_state);
+		return false;
+	}
+
+	return true;
+}
+
+bool pmo_core_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev)
+{
+	enum QDF_OPMODE opmode;
+	bool val;
+
+	opmode = pmo_get_vdev_opmode(vdev);
+	pmo_debug("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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		qdf_mem_copy(psoc_cfg, &psoc_ctx->psoc_cfg, sizeof(*psoc_cfg));
+	}
+
+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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		qdf_mem_copy(&psoc_ctx->psoc_cfg, psoc_cfg, sizeof(*psoc_cfg));
+	}
+
+out:
+	pmo_exit();
+
+	return status;
+}
+
+void pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc,
+		       struct pmo_device_caps *caps)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		qdf_mem_copy(&psoc_ctx->caps, caps, sizeof(psoc_ctx->caps));
+	}
+}
+
+void pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+				  void *hif_hdl)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->hif_hdl = hif_hdl;
+	}
+}
+
+void *pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc *psoc)
+{
+	void *hif_hdl = NULL;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		hif_hdl = psoc_ctx->hif_hdl;
+	}
+
+	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;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->txrx_hdl = txrx_hdl;
+	}
+}
+
+void *pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc)
+{
+	void *txrx_hdl = NULL;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		txrx_hdl = psoc_ctx->txrx_hdl;
+	}
+
+	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..5620ef4
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c
@@ -0,0 +1,684 @@
+/*
+ * Copyright (c) 2017-2018 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_enhanced_mc_filter_enable(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;
+
+	pmo_tgt_send_enhance_multicast_offload_req(vdev, true);
+
+	pmo_vdev_put_ref(vdev);
+
+exit_with_status:
+	pmo_exit();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_enhanced_mc_filter_disable(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;
+
+	pmo_tgt_send_enhance_multicast_offload_req(vdev, false);
+
+	pmo_vdev_put_ref(vdev);
+
+exit_with_status:
+	pmo_exit();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+	struct pmo_mc_addr_list *mc_list)
+{
+	int i;
+
+	pmo_enter();
+
+	if (pmo_tgt_get_multiple_mc_filter_support(vdev)) {
+		pmo_debug("FW supports multiple mcast filter");
+		pmo_tgt_set_multiple_mc_filter_req(vdev, mc_list);
+	} else {
+		pmo_debug("FW does not support multiple mcast filter");
+		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)
+{
+	int i;
+
+	pmo_enter();
+	if (pmo_tgt_get_multiple_mc_filter_support(vdev)) {
+		pmo_debug("FW supports multiple mcast filter");
+		pmo_tgt_clear_multiple_mc_filter_req(vdev, mc_list);
+	} else {
+		pmo_debug("FW does not support multiple mcast filter");
+		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_debug("user disabled mc_addr_list using INI");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!pmo_core_is_vdev_supports_offload(vdev)) {
+		pmo_debug("vdev in invalid opmode for mc addr filtering %d",
+			  pmo_get_vdev_opmode(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_debug("Cache mc addr list for vdev id: %d psoc: %pK",
+		  mc_list_config->vdev_id, mc_list_config->psoc);
+
+	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_debug("Flush mc addr list for vdev id: %d psoc: %pK",
+		  vdev_id, psoc);
+
+	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 = QDF_STATUS_SUCCESS;
+	struct pmo_mc_addr_list *op_mc_list_req;
+
+	pmo_enter();
+
+	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_NOMEM;
+		goto exit_with_status;
+	}
+
+	switch (trigger) {
+	case pmo_mc_list_change_notify:
+		if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_debug("active offload is disabled, skip in mode %d",
+				  trigger);
+			goto free_req;
+		}
+		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_debug("active offload is enabled, skip in mode %d",
+				  trigger);
+			goto free_req;
+		}
+		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;
+	}
+
+free_req:
+	qdf_mem_free(op_mc_list_req);
+
+exit_with_status:
+	pmo_exit();
+
+	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();
+
+	status = pmo_psoc_get_ref(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto exit_with_status;
+
+	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto put_psoc;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto put_psoc;
+
+	status = pmo_core_mc_addr_flitering_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto put_vdev;
+
+	if (!pmo_core_is_vdev_connected(vdev)) {
+		status = QDF_STATUS_E_INVAL;
+		goto put_vdev;
+	}
+
+	pmo_debug("enable mclist trigger: %d", trigger);
+	status = pmo_core_handle_enable_mc_list_trigger(vdev, trigger);
+
+put_vdev:
+	pmo_vdev_put_ref(vdev);
+
+put_psoc:
+	pmo_psoc_put_ref(psoc);
+
+exit_with_status:
+	pmo_exit();
+
+	return status;
+}
+
+static QDF_STATUS pmo_core_handle_disable_mc_list_trigger(
+			struct wlan_objmgr_vdev *vdev,
+			enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct pmo_mc_addr_list *op_mc_list_req;
+
+	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("out of memory");
+		status = QDF_STATUS_E_NOMEM;
+		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_debug("active offload is disabled, skip in mode %d",
+				  trigger);
+			goto free_req;
+		}
+		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_debug("active offload is enabled, skip in mode %d",
+				  trigger);
+			goto free_req;
+		}
+		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;
+	}
+
+free_req:
+	qdf_mem_free(op_mc_list_req);
+
+out:
+	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_INVAL;
+		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 put_ref;
+
+	if (!pmo_core_is_vdev_connected(vdev)) {
+		status = QDF_STATUS_E_INVAL;
+		goto put_ref;
+	}
+
+	pmo_debug("disable mclist trigger: %d", trigger);
+
+	status = pmo_core_handle_disable_mc_list_trigger(vdev, trigger);
+
+put_ref:
+	pmo_vdev_put_ref(vdev);
+
+out:
+	pmo_exit();
+
+	return status;
+}
+
+QDF_STATUS
+pmo_core_get_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+			  uint8_t vdev_id,
+			  struct pmo_mc_addr_list *mc_list_req)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	pmo_enter();
+
+	if (!mc_list_req)
+		return QDF_STATUS_E_INVAL;
+
+	qdf_mem_zero(mc_list_req, sizeof(*mc_list_req));
+
+	status = pmo_psoc_get_ref(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto exit_with_status;
+
+	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto put_psoc;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto put_psoc;
+
+	status = pmo_core_mc_addr_flitering_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto put_vdev;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	*mc_list_req = vdev_ctx->vdev_mc_list_req;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+put_vdev:
+	pmo_vdev_put_ref(vdev);
+
+put_psoc:
+	pmo_psoc_put_ref(psoc);
+
+exit_with_status:
+	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..291cbe0
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_ns.c
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2017-2018 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];
+
+		request->scope[i] = ns_req->scope[i];
+
+		pmo_debug("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;
+	request.is_offload_applied = false;
+	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_debug("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;
+	vdev_ctx->vdev_ns_req.is_offload_applied = false;
+	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_debug("active offload is disabled, skip in mode:%d",
+				  trigger);
+			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_debug("active offload is enabled, skip in mode: %d",
+				  trigger);
+			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_debug("active offload is disabled, skip in mode:%d",
+				  trigger);
+			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_debug("active offload is enabled, skip in mode: %d",
+				  trigger);
+			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_debug("ns offload statically disable");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_dynamic) {
+		pmo_debug("ns offload dynamically disable");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!pmo_core_is_vdev_supports_offload(vdev)) {
+		pmo_debug("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_debug("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_debug("Flush ns offload on vdev id: %d vdev: %pK", 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_debug("ns offload dynamically disable");
+		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_debug("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_debug("Enable ns offload in fwr vdev id: %d vdev: %pK 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_debug("ns offload dynamically disable");
+		goto dec_ref;
+	}
+
+skip_ns_dynamic_check:
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_debug("disable ns offload in fwr vdev id: %d vdev: %pK 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;
+}
+
+QDF_STATUS
+pmo_core_get_ns_offload_params(struct wlan_objmgr_vdev *vdev,
+			       struct pmo_ns_offload_params *params)
+{
+	QDF_STATUS status;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	pmo_enter();
+
+	if (!params)
+		return QDF_STATUS_E_INVAL;
+
+	qdf_mem_zero(params, sizeof(*params));
+
+	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;
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	*params = vdev_ctx->vdev_ns_req;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+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..2624c5c
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_pkt_filter.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2017-2018 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"
+
+#define PMO_PKT_FILTERS_DEFAULT 12
+#define PMO_PKT_FILTERS_DISABLED 0xffffffff
+
+uint32_t pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	bool pkt_filter = false;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		pkt_filter = pmo_intersect_packet_filter(psoc_ctx);
+	}
+
+	return pkt_filter ? PMO_PKT_FILTERS_DEFAULT : PMO_PKT_FILTERS_DISABLED;
+}
+
+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..fb52d45
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_static_config.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2017-2018 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 QDF_OPMODE  vdev_opmode;
+	const char *iface_type;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	pmo_is_device_in_low_pwr_mode is_low_pwr_mode;
+
+	vdev_opmode = pmo_get_vdev_opmode(vdev);
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_debug("vdev_opmode %d vdev_id %d", vdev_opmode, vdev_id);
+
+	switch (vdev_opmode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+		/* set power on failure event only for STA and P2P_CLI mode*/
+		psoc_ctx =  pmo_vdev_get_psoc_priv(vdev);
+		if (psoc_ctx->psoc_cfg.auto_power_save_fail_mode ==
+		    PMO_FW_TO_SEND_WOW_IND_ON_PWR_FAILURE){
+			qdf_spin_lock(&psoc_ctx->lock);
+			is_low_pwr_mode = psoc_ctx->is_device_in_low_pwr_mode;
+			qdf_spin_unlock(&psoc_ctx->lock);
+			if (is_low_pwr_mode && is_low_pwr_mode(vdev_id))
+				pmo_set_wow_event_bitmap(
+					WOW_CHIP_POWER_FAILURE_DETECT_EVENT,
+					PMO_WOW_MAX_EVENT_BM_LEN,
+					event_bitmap);
+		}
+	/* fallthrough */
+	case QDF_P2P_DEVICE_MODE:
+	case QDF_OCB_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";
+		/* wake up host when Nan Management Frame is received */
+		pmo_set_wow_event_bitmap(WOW_NAN_DATA_EVENT,
+					 PMO_WOW_MAX_EVENT_BM_LEN,
+					 event_bitmap);
+		/* wake up host when NDP data packet is received */
+		pmo_set_wow_event_bitmap(WOW_PATTERN_MATCH_EVENT,
+					 WMI_WOW_MAX_EVENT_BM_LEN,
+					 event_bitmap);
+#endif
+		break;
+
+	default:
+		pmo_err("Skipping wake event configuration for vdev_opmode %d",
+			vdev_opmode);
+		return;
+	}
+
+	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_debug("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_debug("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_debug("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 QDF_OPMODE  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_debug("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_debug("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_debug("Config STA RA wow pattern vdev_id %d",
+				  vdev_id);
+			pmo_tgt_send_ra_filter_req(vdev);
+		}
+	}
+
+}
+
+/**
+ * set_action_id_drop_pattern_for_spec_mgmt() - Set action id of action
+ * frames for spectrum mgmt frames to be droppped in fw.
+ *
+ * @action_id_per_category: Pointer to action id bitmaps.
+ */
+static void set_action_id_drop_pattern_for_spec_mgmt(
+					uint32_t *action_id_per_category)
+{
+	action_id_per_category[PMO_MAC_ACTION_SPECTRUM_MGMT]
+				= DROP_SPEC_MGMT_ACTION_FRAME_BITMAP;
+}
+
+/**
+ * set_action_id_drop_pattern_for_public_action() - Set action id of action
+ * frames for public action frames to be droppped in fw.
+ *
+ * @action_id_per_category: Pointer to action id bitmaps.
+ */
+static void set_action_id_drop_pattern_for_public_action(
+					uint32_t *action_id_per_category)
+{
+	action_id_per_category[PMO_MAC_ACTION_PUBLIC_USAGE]
+				= DROP_PUBLIC_ACTION_FRAME_BITMAP;
+}
+
+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;
+
+	set_action_id_drop_pattern_for_spec_mgmt(cmd.action_per_category);
+	set_action_id_drop_pattern_for_public_action(cmd.action_per_category);
+
+	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;
+	}
+
+	pmo_debug("Spectrum mgmt action id drop bitmap: 0x%x",
+			cmd.action_per_category[PMO_MAC_ACTION_SPECTRUM_MGMT]);
+	pmo_debug("Public action id drop bitmap: 0x%x",
+			cmd.action_per_category[PMO_MAC_ACTION_PUBLIC_USAGE]);
+
+	/*  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..3493312
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_suspend_resume.c
@@ -0,0 +1,1417 @@
+/*
+ * Copyright (c) 2017-2018 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_get_vdev_dtim_period() - Get vdev dtim period
+ * @vdev: objmgr vdev handle
+ *
+ * Return: Vdev dtim period
+ */
+static uint8_t pmo_core_get_vdev_dtim_period(struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t dtim_period = 0;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		if (psoc_ctx->get_dtim_period)
+			ret = psoc_ctx->get_dtim_period(pmo_vdev_get_id(vdev),
+							&dtim_period);
+	}
+
+	if (QDF_IS_STATUS_ERROR(ret))
+		pmo_err("Failed to get to dtim period for vdevId %d",
+				pmo_vdev_get_id(vdev));
+
+	return dtim_period;
+}
+
+/**
+ * pmo_core_get_vdev_beacon_interval() - Get vdev beacon interval
+ * @vdev: objmgr vdev handle
+ *
+ * Return: Vdev beacon interval
+ */
+static uint16_t pmo_core_get_vdev_beacon_interval(struct wlan_objmgr_vdev *vdev)
+{
+	uint16_t beacon_interval = 0;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		if (psoc_ctx->get_beacon_interval)
+			ret = psoc_ctx->get_beacon_interval(
+							pmo_vdev_get_id(vdev),
+							&beacon_interval);
+	}
+
+	if (QDF_IS_STATUS_ERROR(ret))
+		pmo_err("Failed to get beacon interval for vdev id %d",
+			pmo_vdev_get_id(vdev));
+
+	return beacon_interval;
+}
+
+/**
+ * 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;
+	struct pmo_psoc_priv_obj *psoc_priv = pmo_vdev_get_psoc_priv(vdev);
+
+	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 {
+		int cfg_value = 0;
+		/* Get Listen Interval */
+		if ((psoc_priv->get_cfg_int) &&
+			(psoc_priv->get_cfg_int(PMO_CFG_LISTEN_INTERVAL,
+				&cfg_value) != QDF_STATUS_SUCCESS)) {
+			pmo_err("Failed to get value for listen interval");
+			cfg_value = PMO_DEFAULT_LISTEN_INTERVAL;
+		}
+		*listen_interval = cfg_value;
+	}
+	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 = PMO_DEFAULT_LISTEN_INTERVAL;
+	QDF_STATUS ret;
+	uint8_t vdev_id;
+	enum QDF_OPMODE opmode = pmo_core_get_vdev_op_mode(vdev);
+
+	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_debug("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_debug("Failed to Set Listen Interval vdevId %d",
+				 vdev_id);
+		}
+		pmo_debug("Set Listen Interval vdevId %d Listen Intv %d",
+			  vdev_id, listen_interval);
+
+		pmo_core_vdev_set_restore_dtim(vdev, true);
+	}
+}
+
+/*
+ * pmo_is_listen_interval_user_set() - Check if listen interval is configured
+ * by user or not
+ * @vdev_ctx: PMO vdev private object
+ *
+ * Return: true if listen interval is user configured else false
+ */
+static inline
+bool pmo_is_listen_interval_user_set(struct pmo_vdev_priv_obj *vdev_ctx)
+{
+	bool retval;
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	retval = vdev_ctx->dyn_modulated_dtim_enabled
+		 || vdev_ctx->dyn_listen_interval;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return retval;
+}
+
+/**
+ * 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;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	bool li_offload_support = false;
+	QDF_STATUS status;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		li_offload_support = psoc_ctx->caps.li_offload;
+	}
+
+	if (li_offload_support)
+		pmo_debug("listen interval offload support is enabled");
+
+	/* 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);
+		if (!pmo_is_listen_interval_user_set(vdev_ctx)
+		    && !li_offload_support)
+			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 ==
+		    PMO_FW_TO_SEND_WOW_IND_ON_PWR_FAILURE &&
+		    (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);
+				enable_configured = true;
+			}
+		}
+
+		if (enable_configured)
+			pmo_tgt_enable_wow_wakeup_event(vdev, enable_mask);
+		if (disable_configured)
+			pmo_tgt_disable_wow_wakeup_event(vdev, 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_debug("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)
+{
+	QDF_STATUS ret;
+	uint8_t vdev_id;
+	enum QDF_OPMODE opmode = pmo_core_get_vdev_op_mode(vdev);
+	int32_t cfg_data_val = 0;
+	struct pmo_psoc_priv_obj *psoc_priv = pmo_vdev_get_psoc_priv(vdev);
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	if ((PMO_VDEV_IN_STA_MODE(opmode)) &&
+	    (pmo_core_vdev_get_restore_dtim(vdev))) {
+		/* Get Listen Interval */
+		if ((psoc_priv->get_cfg_int) &&
+			(psoc_priv->get_cfg_int(PMO_CFG_LISTEN_INTERVAL,
+				&cfg_data_val) != QDF_STATUS_SUCCESS)) {
+			pmo_err("Failed to get value for listen interval");
+			cfg_data_val = PMO_DEFAULT_LISTEN_INTERVAL;
+		}
+
+		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);
+		pmo_core_vdev_set_restore_dtim(vdev, false);
+	}
+}
+
+/**
+ * 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;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	bool li_offload_support = false;
+	QDF_STATUS status;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		li_offload_support = psoc_ctx->caps.li_offload;
+	}
+
+	if (li_offload_support)
+		pmo_debug("listen interval offload support is enabled");
+
+	/* 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);
+		if (!pmo_is_listen_interval_user_set(vdev_ctx)
+		    && !li_offload_support)
+			pmo_core_set_vdev_resume_dtim(psoc, vdev, vdev_ctx);
+		pmo_vdev_put_ref(vdev);
+	}
+}
+
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
+/**
+ * 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 cdp_vdev *vdev_dp;
+
+	/* Iterate through VDEV list */
+	for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+		vdev_dp = pmo_core_vdev_get_dp_handle(psoc_ctx, vdev_id);
+		if (!vdev_dp)
+			continue;
+
+		/* When host resumes, 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),
+					    vdev_dp,
+					    0xffffffff);
+			if (psoc_ctx->pause_bitmap_notifier)
+				psoc_ctx->pause_bitmap_notifier(vdev_id, 0);
+		}
+	}
+}
+#else
+static inline void pmo_unpause_all_vdev(struct wlan_objmgr_psoc *psoc,
+					struct pmo_psoc_priv_obj *psoc_ctx)
+{
+}
+#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;
+	}
+
+	if (psoc_ctx->psoc_cfg.d0_wow_supported &&
+	    !psoc_ctx->caps.unified_wow &&
+	    !param.can_suspend_link) {
+		psoc_ctx->wow.wow_state = pmo_wow_state_legacy_d0;
+	} else if (param.can_suspend_link) {
+		psoc_ctx->wow.wow_state = pmo_wow_state_unified_d3;
+	} else {
+		psoc_ctx->wow.wow_state = pmo_wow_state_unified_d0;
+	}
+
+	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;
+	}
+
+	if (psoc_ctx->wow.wow_state != pmo_wow_state_legacy_d0)
+		pmo_tgt_update_target_suspend_flag(psoc, true);
+
+	status = qdf_wait_for_event_completion(&psoc_ctx->wow.target_suspend,
+					       PMO_TARGET_SUSPEND_TIMEOUT);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		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);
+		qdf_trigger_self_recovery();
+		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));
+		qdf_trigger_self_recovery();
+	}
+	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);
+
+	status = qdf_wait_for_event_completion(&psoc_ctx->wow.target_suspend,
+					       PMO_TARGET_SUSPEND_TIMEOUT);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pmo_err("Failed to get ACK from firmware for pdev suspend");
+		pmo_tgt_update_target_suspend_flag(psoc, false);
+		qdf_trigger_self_recovery();
+	}
+
+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);
+
+	wow_mode_selected = pmo_core_is_wow_enabled(psoc_ctx);
+	pmo_debug("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: %pK, dp: %pK, txrx: %pK, htc: %pK",
+			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: %pK, dp: %pK, txrx: %pK, htc: %pK",
+			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_for_event_completion(&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_trigger_self_recovery();
+	} 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_trigger_self_recovery();
+	} 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_debug("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);
+	psoc_ctx->wow.wow_state = pmo_wow_state_none;
+	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();
+}
+
+QDF_STATUS pmo_core_config_listen_interval(struct wlan_objmgr_vdev *vdev,
+					   uint32_t new_li)
+{
+	uint32_t listen_interval;
+	QDF_STATUS status;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	uint8_t vdev_id;
+
+	pmo_enter();
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	vdev_id =  pmo_vdev_get_id(vdev);
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	if (vdev_ctx->dyn_listen_interval == new_li) {
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+		status = QDF_STATUS_SUCCESS;
+		pmo_debug("Listen Interval(%d) already set for vdev id %d",
+			new_li, vdev_id);
+		goto dec_ref;
+	}
+
+	vdev_ctx->dyn_listen_interval = new_li;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	listen_interval = new_li ? new_li : PMO_DEFAULT_LISTEN_INTERVAL;
+
+	if (!new_li) {
+		/* Configure default LI as we do on resume */
+		pmo_psoc_with_ctx(pmo_vdev_get_psoc(vdev), psoc_ctx) {
+			if (psoc_ctx->get_cfg_int &&
+			   (QDF_STATUS_SUCCESS != psoc_ctx->get_cfg_int(
+							PMO_CFG_LISTEN_INTERVAL,
+							&listen_interval))) {
+				pmo_err("Failed to get listen interval");
+			}
+		}
+	}
+
+	pmo_debug("Set Listen Interval %d for vdevId %d", listen_interval,
+			vdev_id);
+	status = pmo_tgt_vdev_update_param_req(vdev,
+					       pmo_vdev_param_listen_interval,
+					       listen_interval);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		/* even it fails continue fwr will take default LI */
+		pmo_err("Failed to Set Listen Interval");
+	}
+
+	/* Set it to Normal DTIM */
+	status = pmo_tgt_vdev_update_param_req(vdev,
+					       pmo_vdev_param_dtim_policy,
+					       pmo_normal_dtim);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pmo_err("Failed to set Normal DTIM for vdev id %d", vdev_id);
+	} else {
+		pmo_debug("Set DTIM Policy to Normal for vdev id %d", vdev_id);
+		pmo_core_vdev_set_restore_dtim(vdev, true);
+	}
+
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	pmo_exit();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_config_modulated_dtim(struct wlan_objmgr_vdev *vdev,
+					  uint32_t mod_dtim)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct pmo_psoc_cfg *psoc_cfg;
+	bool prev_dtim_enabled;
+	uint32_t listen_interval;
+	uint32_t beacon_interval_mod;
+	uint32_t max_mod_dtim;
+	QDF_STATUS status;
+	uint8_t vdev_id;
+
+	pmo_enter();
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	psoc_cfg = &vdev_ctx->pmo_psoc_ctx->psoc_cfg;
+
+	/* Calculate Maximum allowed modulated DTIM */
+	beacon_interval_mod =
+		pmo_core_get_vdev_beacon_interval(vdev) / 100;
+	if (!beacon_interval_mod)
+		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)
+		max_mod_dtim = 1;
+
+	/* Calculate Listen Interval from provided mod DTIM */
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->dyn_modulated_dtim = mod_dtim;
+	prev_dtim_enabled = vdev_ctx->dyn_modulated_dtim_enabled;
+	vdev_ctx->dyn_modulated_dtim_enabled = mod_dtim != 1;
+	if (vdev_ctx->dyn_modulated_dtim > max_mod_dtim) {
+		listen_interval = max_mod_dtim *
+			pmo_core_get_vdev_dtim_period(vdev);
+	} else {
+		listen_interval = vdev_ctx->dyn_modulated_dtim  *
+			pmo_core_get_vdev_dtim_period(vdev);
+	}
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	if (prev_dtim_enabled || mod_dtim != 1) {
+		status = pmo_tgt_vdev_update_param_req(vdev,
+					pmo_vdev_param_listen_interval,
+					listen_interval);
+		if (QDF_IS_STATUS_ERROR(status))
+			/* even it fails continue fwr will take default LI */
+			pmo_err("Failed to set Listen Interval for vdev id %d",
+				vdev_id);
+		else
+			pmo_debug("Set Listen Interval %d for  vdev id %d",
+				  listen_interval, vdev_id);
+
+		status = pmo_tgt_vdev_update_param_req(vdev,
+				pmo_vdev_param_dtim_policy,
+				pmo_normal_dtim);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pmo_err("Failed to set Normal DTIM for vdev id %d",
+				vdev_id);
+		} else {
+			pmo_debug("Set DTIM Policy to Normal for vdev id %d",
+				  vdev_id);
+			pmo_core_vdev_set_restore_dtim(vdev, true);
+		}
+	}
+
+	pmo_vdev_put_ref(vdev);
+out:
+	pmo_exit();
+	return status;
+}
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..a36d44f
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_wow.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2017-2018 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"
+#include "cfg_nan_api.h"
+#include "wlan_utility.h"
+
+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;
+}
+
+QDF_STATUS pmo_core_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
+		struct pmo_wow_add_pattern *ptrn)
+{
+	QDF_STATUS status;
+	uint8_t id;
+	uint8_t bit_to_check, pos;
+	uint8_t new_mask[PMO_WOWL_BCAST_PATTERN_MAX_SIZE];
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	/* clear all default patterns cofigured by pmo */
+	for (id = 0; id < pmo_get_wow_default_ptrn(vdev_ctx); id++)
+		pmo_tgt_del_wow_pattern(vdev, id, false);
+
+	pmo_set_wow_default_ptrn(vdev_ctx, 0);
+
+	pmo_debug("Add user passed wow pattern id %d vdev id %d",
+		  ptrn->pattern_id, ptrn->session_id);
+	/*
+	 * Convert received pattern mask value from bit representation
+	 * to byte representation.
+	 *
+	 * For example, received value from umac,
+	 *
+	 *      Mask value    : A1 (equivalent binary is "1010 0001")
+	 *      Pattern value : 12:00:13:00:00:00:00:44
+	 *
+	 * The value which goes to FW after the conversion from this
+	 * function (1 in mask value will become FF and 0 will
+	 * become 00),
+	 *
+	 *      Mask value    : FF:00:FF:00:00:00:00:FF
+	 *      Pattern value : 12:00:13:00:00:00:00:44
+	 */
+	qdf_mem_zero(new_mask, sizeof(new_mask));
+	for (pos = 0; pos < ptrn->pattern_size; pos++) {
+		bit_to_check = (PMO_NUM_BITS_IN_BYTE - 1) -
+			       (pos % PMO_NUM_BITS_IN_BYTE);
+		bit_to_check = 0x1 << bit_to_check;
+		if (ptrn->pattern_mask[pos / PMO_NUM_BITS_IN_BYTE] &
+		    bit_to_check)
+			new_mask[pos] = PMO_WOW_PTRN_MASK_VALID;
+	}
+
+	status = pmo_tgt_send_wow_patterns_to_fw(vdev,
+						 ptrn->pattern_id,
+						 ptrn->pattern,
+						 ptrn->pattern_size,
+						 ptrn->pattern_byte_offset,
+						 new_mask,
+						 ptrn->pattern_size, true);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to add wow pattern %d", ptrn->pattern_id);
+
+	pmo_vdev_put_ref(vdev);
+out:
+	pmo_exit();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
+		uint8_t pattern_id)
+{
+	QDF_STATUS status;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	if (pmo_get_wow_user_ptrn(vdev_ctx) <= 0) {
+		pmo_err("No valid user pattern. Num user pattern %u",
+			pmo_get_wow_user_ptrn(vdev_ctx));
+		status = QDF_STATUS_E_INVAL;
+		goto rel_ref;
+	}
+
+	pmo_debug("Delete user passed wow pattern id %d total user pattern %d",
+		  pattern_id, pmo_get_wow_user_ptrn(vdev_ctx));
+
+	pmo_tgt_del_wow_pattern(vdev, pattern_id, true);
+
+	/* configure default patterns once all user patterns are deleted */
+	if (!pmo_get_wow_user_ptrn(vdev_ctx))
+		pmo_register_wow_default_patterns(vdev);
+rel_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	pmo_exit();
+
+	return status;
+}
+
+void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+				  uint32_t vdev_id,
+				  WOW_WAKE_EVENT_TYPE wow_event)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+	uint32_t bitmap[PMO_WOW_MAX_EVENT_BM_LEN] = {0};
+
+	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_set_wow_event_bitmap(wow_event, PMO_WOW_MAX_EVENT_BM_LEN, bitmap);
+
+	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,
+				   WOW_WAKE_EVENT_TYPE wow_event)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+	uint32_t bitmap[PMO_WOW_MAX_EVENT_BM_LEN] = {0};
+
+	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_set_wow_event_bitmap(wow_event, PMO_WOW_MAX_EVENT_BM_LEN, bitmap);
+
+	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 QDF_OPMODE 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) &&
+			       wlan_vdev_is_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_enabled(wma->wmi_handle,
+	 *			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 = false;
+	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 (cfg_nan_get_enable(psoc)) {
+			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_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);
+	pmo_set_wow_event_bitmap(WOW_SAP_OBSS_DETECTION_EVENT,
+				 wow_bitmap_size,
+				 bitmask);
+	pmo_set_wow_event_bitmap(WOW_BSS_COLOR_COLLISION_DETECT_EVENT,
+				 wow_bitmap_size,
+				 bitmask);
+}
+
+uint8_t pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	bool apf = false;
+	bool arp_ns = false;
+	bool pkt_filter = false;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		apf = pmo_intersect_apf(psoc_ctx);
+		arp_ns = pmo_intersect_arp_ns_offload(psoc_ctx);
+		pkt_filter = pmo_intersect_packet_filter(psoc_ctx);
+	}
+
+	if (!apf && !pkt_filter)
+		return PMO_WOW_FILTERS_MAX;
+
+	if (arp_ns)
+		return PMO_WOW_FILTERS_ARP_NS;
+
+	return PMO_WOW_FILTERS_PKT_OR_APF;
+}
+
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_apf_cfg.h b/components/pmo/dispatcher/inc/wlan_pmo_apf_cfg.h
new file mode 100644
index 0000000..4419d26
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_apf_cfg.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef WLAN_PMO_APF_CFG_H__
+#define WLAN_PMO_APF_CFG_H__
+
+/*
+ * <ini>
+ * gBpfFilterEnable - APF feature support configuration
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * When set to 1 APF feature will be enabled.
+ *
+ * Supported Feature: Android packet filter
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_APF_ENABLE CFG_INI_BOOL("gBpfFilterEnable", \
+					1, \
+					"Enable APF Support")
+
+#define CFG_PMO_APF_ALL \
+	CFG(CFG_PMO_APF_ENABLE)
+
+#endif /* WLAN_PMO_APF_CFG_H__ */
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..4a78921
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_arp_public_struct.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017-2018 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;
+	bool is_offload_applied;
+};
+
+#endif /* end  of _WLAN_PMO_ARP_PUBLIC_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_cfg.h b/components/pmo/dispatcher/inc/wlan_pmo_cfg.h
new file mode 100644
index 0000000..f51a027
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_cfg.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef WLAN_PMO_CFG_H__
+#define WLAN_PMO_CFG_H__
+
+#include "wlan_pmo_apf_cfg.h"
+#include "wlan_pmo_common_cfg.h"
+#include "wlan_pmo_extwow_cfg.h"
+#include "wlan_pmo_pkt_filter_cfg.h"
+#include "wlan_pmo_runtime_pm_cfg.h"
+#include "wlan_pmo_wow_pulse_cfg.h"
+
+#define CFG_PMO_ALL \
+	CFG_EXTWOW_ALL \
+	CFG_PACKET_FILTER_ALL \
+	CFG_PMO_APF_ALL \
+	CFG_PMO_COMMON_ALL \
+	CFG_RUNTIME_PM_ALL \
+	CFG_WOW_PULSE_ALL
+
+#endif /* WLAN_PMO_CFG_H__ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h b/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h
new file mode 100644
index 0000000..34a28e8
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef WLAN_PMO_COMMON_CFG_H__
+#define WLAN_PMO_COMMON_CFG_H__
+
+#include "wlan_pmo_common_public_struct.h"
+
+/*
+ * <ini>
+ * hostArpOffload - Enable/disable host ARP offload
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable host ARP offload.
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_ENABLE_HOST_ARPOFFLOAD CFG_INI_BOOL( \
+	"hostArpOffload", \
+	1, \
+	"enable/disable host arp offload")
+
+/*
+ * <ini>
+ * gHwFilterMode - configure hardware filter for DTIM mode
+ * @Min: 0
+ * @Max: 3
+ * @Default: 1
+ *
+ * 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
+ *
+ * Takes a bitmap of frame types to drop
+ * @E.g.
+ *	# disable feature
+ *	gHwFilterMode=0
+ *	# drop all broadcast frames, except ARP (default)
+ *	gHwFilterMode=1
+ *	# drop all multicast frames, except ICMPv6
+ *	gHwFilterMode=2
+ *	# drop all broadcast and multicast frames, except ARP and ICMPv6
+ *	gHwFilterMode=3
+ *
+ * Related: N/A
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PMO_HW_FILTER_MODE CFG_INI_UINT( \
+	"gHwFilterMode", \
+	0, \
+	3, \
+	1, \
+	CFG_VALUE_OR_DEFAULT, \
+	"hardware filter for DTIM mode")
+
+/*
+ * <ini>
+ * ssdp - Enable/disable ssdp
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable ssdp.
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_ENABLE_HOST_SSDP CFG_INI_BOOL( \
+	"ssdp", \
+	1, \
+	"Enable/disable ssdp")
+
+/*
+ * <ini>
+ * hostNSOffload - Enable/disable NS offload
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable NS offload.
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_ENABLE_HOST_NSOFFLOAD CFG_INI_BOOL( \
+	"hostNSOffload", \
+	1, \
+	"Enable/disable NS offload")
+
+/*
+ * <ini>
+ * gEnableDynamicDTIM - Enable Dynamic DTIM
+ * @Min: 0
+ * @Max: 9
+ * @Default: 0
+ *
+ * This ini is used to enable/disable ssdp.
+ *
+ * 0 -Disable DynamicDTIM
+ * 1 to 5 - SLM will switch to DTIM specified here when host suspends and
+ *          switch DTIM1 when host resumes
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_ENABLE_DYNAMIC_DTIM CFG_INI_UINT( \
+	"gEnableDynamicDTIM", \
+	0, \
+	9, \
+	0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Enable Dynamic DTIM")
+
+/*
+ * <ini>
+ * gEnableDynamicDTIM - Enable/Disable modulated DTIM feature
+ * @Min: 0
+ * @Max: 5
+ * @Default: 0
+ *
+ * This ini is used to enable/disable modulated DTIM feature.
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_ENABLE_MODULATED_DTIM CFG_INI_UINT( \
+	"gEnableModulatedDTIM", \
+	0, \
+	5, \
+	0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Enable/disable modulated DTIM feature")
+
+/*
+ * <ini>
+ * gMCAddrListEnable - Enable/disable multicast MAC address list feature
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable multicast MAC address list feature.
+ * Default: Enable
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PMO_MC_ADDR_LIST_ENABLE CFG_INI_BOOL( \
+	"gMCAddrListEnable", \
+	1, \
+	"Enable/disable multicast MAC address list feature")
+
+/*
+ * <ini>
+ * gEnablePowerSaveOffload - Enable Power Save Offload
+ * @Min: 0
+ * @Max: 5
+ * @Default: 0
+ *
+ * This ini is used to set Power Save Offload configuration:
+ * Current values of gEnablePowerSaveOffload:
+ * 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
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_POWERSAVE_OFFLOAD CFG_INI_UINT( \
+	"gEnablePowerSaveOffload", \
+	0, \
+	5, \
+	0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Enable Power Save Offload")
+
+/*
+ * <ini>
+ * gMaxPsPoll - Max powersave poll
+ * @Min: 0
+ * @Max: 255
+ * @Default: 0
+ *
+ * This ini is used to set max powersave poll.
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_MAX_PS_POLL CFG_INI_UINT( \
+		"gMaxPsPoll", \
+		0, \
+		255, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Max powersave poll")
+
+/*
+ * <ini>
+ * gEnableWoW - Enable/Disable WoW
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * This ini is used to enable/disable WoW. Configurations are as follows:
+ * 0 - Disable both magic pattern match and pattern byte match.
+ * 1 - Enable magic pattern match on all interfaces.
+ * 2 - Enable pattern byte match on all interfaces.
+ * 3 - Enable both magic patter and pattern byte match on all interfaces.
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_WOW_ENABLE CFG_INI_UINT("gEnableWoW", \
+					0, 3, 3, \
+					CFG_VALUE_OR_DEFAULT, \
+					"Enable WoW Support")
+/*
+ * <ini>
+ * wowlan_deauth_enable - Enable/Disable wowlan deauth enable
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable wowlan deauth enable.
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_WOWLAN_DEAUTH_ENABLE CFG_INI_BOOL("wowlan_deauth_enable", \
+						  1, \
+						  "Enable WoWLan deauth")
+/*
+ * <ini>
+ * wowlan_disassoc_enable - Enable/Disable wowlan disassoc enable
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable wowlan disassoc enable.
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_WOWLAN_DISASSOC_ENABLE CFG_INI_BOOL("wowlan_disassoc_enable", \
+						    1, \
+						    "Enable WoW Support")
+
+/*
+ * <ini>
+ * gActiveModeOffload - Active offload mode configuration
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * When set to 1 active mode offload will be enabled.
+ *
+ * If active mode offload is enabled then all applicable data offload/filtering
+ * is enabled immediately in FW once config is available in WLAN driver and FW
+ * caches this configuration across suspend/resume;
+ * If active mode offload is disabled then all applicable data offload/filtering
+ * is enabled during cfg80211 suspend and disabled during cfg80211 resume.
+ *
+ * Supported Feature: Active mode offload
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_ACTIVE_MODE CFG_INI_BOOL("gActiveModeOffload", \
+					 1, \
+					 "Enable active mode offload")
+
+/*
+ * <ini>
+ * g_auto_detect_power_failure_mode - Auto detect power save failure mode
+ * @Min: PMO_FW_TO_CRASH_ON_PWR_FAILURE
+ * @Max: PMO_AUTO_PWR_FAILURE_DETECT_DISABLE
+ * @Default: PMO_FW_TO_CRASH_ON_PWR_FAILURE
+ *
+ * Specifies the behavior of FW in case of CHIP_POWER_SAVE_FAIL_DETECTED event
+ *
+ * Supported Feature: Auto detect power save failure
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_PWR_FAILURE CFG_INI_UINT("g_auto_detect_power_failure_mode", \
+					 PMO_FW_TO_CRASH_ON_PWR_FAILURE, \
+					 PMO_AUTO_PWR_FAILURE_DETECT_DISABLE, \
+					 PMO_FW_TO_CRASH_ON_PWR_FAILURE, \
+					 CFG_VALUE_OR_DEFAULT, \
+					 "Auto detect power save failure mode")
+
+#define CFG_PMO_COMMON_ALL \
+	CFG(CFG_PMO_ENABLE_HOST_ARPOFFLOAD) \
+	CFG(CFG_PMO_HW_FILTER_MODE) \
+	CFG(CFG_PMO_ENABLE_HOST_SSDP) \
+	CFG(CFG_PMO_ENABLE_HOST_NSOFFLOAD) \
+	CFG(CFG_PMO_ENABLE_DYNAMIC_DTIM) \
+	CFG(CFG_PMO_ENABLE_MODULATED_DTIM) \
+	CFG(CFG_PMO_MC_ADDR_LIST_ENABLE) \
+	CFG(CFG_PMO_POWERSAVE_OFFLOAD) \
+	CFG(CFG_PMO_MAX_PS_POLL) \
+	CFG(CFG_PMO_WOWLAN_DEAUTH_ENABLE) \
+	CFG(CFG_PMO_WOWLAN_DISASSOC_ENABLE) \
+	CFG(CFG_PMO_WOW_ENABLE) \
+	CFG(CFG_PMO_ACTIVE_MODE) \
+	CFG(CFG_PMO_PWR_FAILURE)
+
+#endif /* WLAN_PMO_COMMON_CFG_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..7b1b6fa
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2017-2018 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
+};
+
+/**
+ * enum wow_enable_type - used to enable/disable WoW.
+ * @PMO_WOW_DISABLE_BOTH: Disable both magic pattern match and pattern
+ *  byte match.
+ * @PMO_WOW_ENABLE_MAGIC_PATTERN: Enable magic pattern match on all interfaces.
+ * @PMO_WOW_ENABLE_PATTERN_BYTE: Enable pattern byte match on all interfaces.
+ * @PMO_WOW_ENABLE_BOTH: Enable both magic patter and pattern byte match on
+ *  all interfaces.
+ */
+enum pmo_wow_enable_type {
+	PMO_WOW_DISABLE_BOTH = 0,
+	PMO_WOW_ENABLE_MAGIC_PATTERN,
+	PMO_WOW_ENABLE_PATTERN_BYTE,
+	PMO_WOW_ENABLE_BOTH
+};
+
+/**
+ * enum powersave_qpower_mode: powersave_mode
+ * @PS_NOT_SUPPORTED: Power save is not supported
+ * @PS_LEGACY_NODEEPSLEEP: Legacy power save enabled and deep sleep disabled
+ * @PS_QPOWER_NODEEPSLEEP: QPOWER enabled and deep sleep disabled
+ * @PS_LEGACY_DEEPSLEEP: Legacy power save enabled and deep sleep enabled
+ * @PS_QPOWER_DEEPSLEEP: QPOWER enabled and deep sleep enabled
+ * @PS_DUTY_CYCLING_QPOWER: QPOWER enabled in duty cycling mode
+ */
+enum powersave_mode {
+	PS_NOT_SUPPORTED = 0,
+	PS_LEGACY_NODEEPSLEEP = 1,
+	PS_QPOWER_NODEEPSLEEP = 2,
+	PS_LEGACY_DEEPSLEEP = 3,
+	PS_QPOWER_DEEPSLEEP = 4,
+	PS_DUTY_CYCLING_QPOWER = 5
+};
+
+#define PMO_TARGET_SUSPEND_TIMEOUT   6000
+#define PMO_WAKE_LOCK_TIMEOUT        1000
+#define PMO_RESUME_TIMEOUT           6000
+
+/**
+ * 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,
+};
+
+/**
+ * enum pmo_auto_pwr_detect_failure_mode_t - auto detect failure modes
+ * @PMO_FW_TO_CRASH_ON_PWR_FAILURE: Don't register wow wakeup event and FW
+ * crashes on power failure
+ * @PMO_FW_TO_SEND_WOW_IND_ON_PWR_FAILURE: Register wow wakeup event and FW
+ * sends failure event to host on power failure
+ * @PMO_FW_TO_REJUVENATE_ON_PWR_FAILURE: Don't register wow wakeup event and
+ * FW silently rejuvenate on power failure
+ * @PMO_AUTO_PWR_FAILURE_DETECT_DISABLE: Don't register wow wakeup event and the
+ * auto power failure detect feature is disabled in FW.
+ */
+enum pmo_auto_pwr_detect_failure_mode {
+	PMO_FW_TO_CRASH_ON_PWR_FAILURE,
+	PMO_FW_TO_SEND_WOW_IND_ON_PWR_FAILURE,
+	PMO_FW_TO_REJUVENATE_ON_PWR_FAILURE,
+	PMO_AUTO_PWR_FAILURE_DETECT_DISABLE
+};
+
+/**
+ * struct pmo_psoc_cfg - user configuration required for pmo
+ * @ptrn_match_enable_all_vdev: true when pattern match is enable for all vdev
+ * @apf_enable: true if psoc supports apf else false
+ * @arp_offload_enable: true if arp offload is supported for psoc else false
+ * @hw_filter_mode_bitmap: 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.
+ * @packet_filter_enabled: true if feature is enabled by configuration
+ * @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
+ * @d0_wow_supported: true if psoc supports D0 wow command
+ * @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
+ * @lpass_enable: true when lpass is enabled else false
+ * @max_ps:poll: max power save poll
+ * @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
+ * @wow_enable: enable wow with majic pattern match or pattern byte match
+ * @power_save_mode: power save mode for psoc
+ * @runtime_pm_delay: set runtime pm's inactivity timer
+ * @extwow_goto_suspend: true when extended WoW enabled else false
+ * @extwow_app1_wakeup_pin_num: set wakeup1 PIN number
+ * @extwow_app2_wakeup_pin_num: set wakeup2 PIN number
+ * @extwow_app2_init_ping_interval: set keep alive init ping interval
+ * @extwow_app2_min_ping_interval: set keep alive minimum ping interval
+ * @extwow_app2_max_ping_interval: set keep alive maximum ping interval
+ * @extwow_app2_inc_ping_interval: set keep alive increment ping interval
+ * @extwow_app2_tcp_src_port: set TCP source port
+ * @extwow_app2_tcp_dst_port: set TCP dest port
+ * @extwow_app2_tcp_tx_timeout: set TCP TX timeout
+ * @extwow_app2_tcp_rx_timeout: set TCP RX timeout
+ * @auto_power_save_fail_mode: auto detect power save failure
+ * @is_wow_pulse_supported: true when wow pulse feature is enabled else false
+ * @wow_pulse_pin: GPIO pin of wow pulse feature
+ * @wow_pulse_interval_high: The interval of high level in the pulse
+ * @wow_pulse_interval_low: The interval of low level in the pulse
+ * @packet_filters_bitmap: Packet filter bitmap configuration
+ */
+struct pmo_psoc_cfg {
+	bool ptrn_match_enable_all_vdev;
+	bool apf_enable;
+	bool arp_offload_enable;
+	enum pmo_hw_filter_mode hw_filter_mode_bitmap;
+	bool ns_offload_enable_static;
+	bool ns_offload_enable_dynamic;
+	bool packet_filter_enabled;
+	bool ssdp;
+	bool enable_mc_list;
+	bool active_mode_offload;
+	bool ap_arpns_support;
+	bool d0_wow_supported;
+	bool ra_ratelimit_enable;
+	uint16_t ra_ratelimit_interval;
+	bool magic_ptrn_enable;
+	bool deauth_enable;
+	bool disassoc_enable;
+	bool bmiss_enable;
+	bool lpass_enable;
+	bool wowlan_deauth_enable;
+	bool wowlan_disassoc_enable;
+	uint8_t max_ps_poll;
+	uint8_t sta_dynamic_dtim;
+	uint8_t sta_mod_dtim;
+	uint8_t sta_max_li_mod_dtim;
+	enum pmo_wow_enable_type wow_enable;
+	enum powersave_mode power_save_mode;
+#ifdef FEATURE_RUNTIME_PM
+	uint32_t runtime_pm_delay;
+#endif
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+	bool extwow_goto_suspend;
+	uint8_t extwow_app1_wakeup_pin_num;
+	uint8_t extwow_app2_wakeup_pin_num;
+	uint32_t extwow_app2_init_ping_interval;
+	uint32_t extwow_app2_min_ping_interval;
+	uint32_t extwow_app2_max_ping_interval;
+	uint32_t extwow_app2_inc_ping_interval;
+	uint16_t extwow_app2_tcp_src_port;
+	uint16_t extwow_app2_tcp_dst_port;
+	uint32_t extwow_app2_tcp_tx_timeout;
+	uint32_t extwow_app2_tcp_rx_timeout;
+#endif
+	enum pmo_auto_pwr_detect_failure_mode auto_power_save_fail_mode;
+#ifdef WLAN_FEATURE_WOW_PULSE
+	bool is_wow_pulse_supported;
+	uint8_t wow_pulse_pin;
+	uint16_t wow_pulse_interval_high;
+	uint16_t wow_pulse_interval_low;
+#endif
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+	uint8_t packet_filters_bitmap;
+#endif
+};
+
+/**
+ * pmo_device_caps - device capability flags (true if feature is supported)
+ * @apf: Android Packet Filter (aka BPF)
+ * @arp_ns_offload: APR/NS offload
+ * @packet_filter: Legacy "Packet Filter"
+ * @unified_wow: Firmware supports "interface pause" flag in WoW command.
+ *	This allows both D0-WoW (bus up) and Non-D0-WoW (bus down) to use one
+ *	unified command
+ * @li_offload: Firmware has listen interval offload support
+ */
+struct pmo_device_caps {
+	bool apf;
+	bool arp_ns_offload;
+	bool packet_filter;
+	bool unified_wow;
+	bool li_offload;
+};
+
+#endif /* end  of _WLAN_PMO_COMMONP_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_extwow_cfg.h b/components/pmo/dispatcher/inc/wlan_pmo_extwow_cfg.h
new file mode 100644
index 0000000..71b4dfe
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_extwow_cfg.h
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef WLAN_PMO_EXTWOW_CFG_H__
+#define WLAN_PMO_EXTWOW_CFG_H__
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+/*
+ * <ini>
+ * gExtWoWgotoSuspend - Enable/Disable Extended WoW
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable Extended WoW.
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EXTWOW_GOTO_SUSPEND CFG_INI_BOOL("gExtWoWgotoSuspend", \
+					     1, \
+					     "Enable Ext WoW goto support")
+/*
+ * <ini>
+ * gExtWowApp1WakeupPinNumber - Set wakeup1 PIN number
+ * @Min: 0
+ * @Max: 255
+ * @Default: 12
+ *
+ * This ini is used to set EXT WOW APP1 wakeup PIN number
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EXTWOW_APP1_WAKE_PIN_NUMBER \
+		CFG_INI_UINT("gExtWowApp1WakeupPinNumber", \
+			     0, 255, 12, \
+			     CFG_VALUE_OR_DEFAULT, \
+			     "Set wakeup1 PIN number")
+/*
+ * <ini>
+ * gExtWowApp2WakeupPinNumber - Set wakeup2 PIN number
+ * @Min: 0
+ * @Max: 255
+ * @Default: 16
+ *
+ * This ini is used to set EXT WOW APP2 wakeup PIN number
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EXTWOW_APP2_WAKE_PIN_NUMBER \
+		CFG_INI_UINT("gExtWowApp2WakeupPinNumber", \
+			     0, 255, 16, \
+			     CFG_VALUE_OR_DEFAULT, \
+			     "Set wakeup2 PIN number")
+/*
+ * <ini>
+ * gExtWoWApp2KAInitPingInterval - Set Keep Alive Init Ping Interval
+ * @Min: 0
+ * @Max: 0xffffffff
+ * @Default: 240
+ *
+ * This ini is used to set Keep Alive Init Ping Interval for EXT WOW
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EXTWOW_KA_INIT_PING_INTERVAL \
+		CFG_INI_UINT("gExtWoWApp2KAInitPingInterval", \
+			     0, 0xffffffff, 240, \
+			     CFG_VALUE_OR_DEFAULT, \
+			     "Set Keep Alive Init Ping Interval")
+/*
+ * <ini>
+ * gExtWoWApp2KAMinPingInterval - Set Keep Alive Minimum Ping Interval
+ * @Min: 0
+ * @Max: 0xffffffff
+ * @Default: 240
+ *
+ * This ini is used to set Keep Alive Minimum Ping Interval for EXT WOW
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EXTWOW_KA_MIN_PING_INTERVAL \
+		CFG_INI_UINT("gExtWoWApp2KAMinPingInterval", \
+			     0, 0xffffffff, 240, \
+			     CFG_VALUE_OR_DEFAULT, \
+			     "Set Keep Alive Minimum Ping Interval")
+/*
+ * <ini>
+ * gExtWoWApp2KAMaxPingInterval - Set Keep Alive Maximum Ping Interval
+ * @Min: 0
+ * @Max: 0xffffffff
+ * @Default: 1280
+ *
+ * This ini is used to set Keep Alive Maximum Ping Interval for EXT WOW
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EXTWOW_KA_MAX_PING_INTERVAL \
+		CFG_INI_UINT("gExtWoWApp2KAMaxPingInterval", \
+			     0, 0xffffffff, 1280, \
+			     CFG_VALUE_OR_DEFAULT, \
+			     "Set Keep Alive Maximum Ping Interval")
+/*
+ * <ini>
+ * gExtWoWApp2KAIncPingInterval - Set Keep Alive increment of Ping Interval
+ * @Min: 0
+ * @Max: 0xffffffff
+ * @Default: 4
+ *
+ * This ini is used to set Keep Alive increment of Ping Interval for EXT WOW
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EXTWOW_KA_INC_PING_INTERVAL \
+		CFG_INI_UINT("gExtWoWApp2KAIncPingInterval", \
+			     0, 0xffffffff, 4, \
+			     CFG_VALUE_OR_DEFAULT, \
+			     "Set Keep Alive increment of Ping Interval")
+/*
+ * <ini>
+ * gExtWoWApp2KAIncPingInterval - Set TCP source port
+ * @Min: 0
+ * @Max: 65535
+ * @Default: 5000
+ *
+ * This ini is used to set TCP source port when EXT WOW is enabled
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EXTWOW_TCP_SRC_PORT \
+		CFG_INI_UINT("gExtWoWApp2KAIncPingInterval", \
+			     0, 65535, 5000, \
+			     CFG_VALUE_OR_DEFAULT, \
+			     "Set TCP source port")
+/*
+ * <ini>
+ * gExtWoWApp2TcpDstPort - Set TCP Destination port
+ * @Min: 0
+ * @Max: 65535
+ * @Default: 5001
+ *
+ * This ini is used to set TCP Destination port when EXT WOW is enabled
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EXTWOW_TCP_DST_PORT \
+		CFG_INI_UINT("gExtWoWApp2TcpDstPort", \
+			     0, 65535, 5001, \
+			     CFG_VALUE_OR_DEFAULT, \
+			     "Set TCP Destination port")
+/*
+ * <ini>
+ * gExtWoWApp2TcpTxTimeout - Set TCP tx timeout
+ * @Min: 0
+ * @Max: 0xffffffff
+ * @Default: 200
+ *
+ * This ini is used to set TCP Tx timeout when EXT WOW is enabled
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EXTWOW_TCP_TX_TIMEOUT \
+		CFG_INI_UINT("gExtWoWApp2TcpTxTimeout", \
+			     0, 0xffffffff, 200, \
+			     CFG_VALUE_OR_DEFAULT, \
+			     "Set TCP tx timeout")
+
+/*
+ * <ini>
+ * gExtWoWApp2TcpRxTimeout - Set TCP rx timeout
+ * @Min: 0
+ * @Max: 0xffffffff
+ * @Default: 200
+ *
+ * This ini is used to set TCP Rx timeout when EXT WOW is enabled
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EXTWOW_TCP_RX_TIMEOUT \
+		CFG_INI_UINT("gExtWoWApp2TcpRxTimeout", \
+			     0, 0xffffffff, 200, \
+			     CFG_VALUE_OR_DEFAULT, \
+			     "ExtWow App2 tcp rx timeout")
+
+#define CFG_EXTWOW_ALL \
+	CFG(CFG_EXTWOW_GOTO_SUSPEND) \
+	CFG(CFG_EXTWOW_APP1_WAKE_PIN_NUMBER) \
+	CFG(CFG_EXTWOW_APP2_WAKE_PIN_NUMBER) \
+	CFG(CFG_EXTWOW_KA_INIT_PING_INTERVAL) \
+	CFG(CFG_EXTWOW_KA_MIN_PING_INTERVAL) \
+	CFG(CFG_EXTWOW_KA_MAX_PING_INTERVAL) \
+	CFG(CFG_EXTWOW_KA_INC_PING_INTERVAL) \
+	CFG(CFG_EXTWOW_TCP_SRC_PORT) \
+	CFG(CFG_EXTWOW_TCP_DST_PORT) \
+	CFG(CFG_EXTWOW_TCP_TX_TIMEOUT) \
+	CFG(CFG_EXTWOW_TCP_RX_TIMEOUT)
+#else
+#define CFG_EXTWOW_ALL
+#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
+#endif /* WLAN_PMO_EXTWOW_CFG_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..9112d46
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_gtk_public_struct.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017-2018 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_LEGACY 16
+#define PMO_KEK_LEN 64
+#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
+ * @kek_len: KEK Length
+ * @replay_counter: replay_counter
+ * @bssid: bssid
+ * @is_fils_connection: is current connection with peer FILS or not.
+ */
+struct pmo_gtk_req {
+	uint32_t flags;
+	uint8_t kck[PMO_KCK_LEN];
+	uint8_t kek[PMO_KEK_LEN];
+	uint32_t kek_len;
+	uint64_t replay_counter;
+	struct qdf_mac_addr bssid;
+	bool is_fils_connection;
+};
+
+/**
+ * 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..8315bb0
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_hw_filter_public_struct.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017-2018 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 << 0),
+	PMO_HW_FILTER_NON_ICMPV6_MC	= (1 << 1),
+};
+
+/**
+ * struct pmo_hw_filter_params - hardware filter configuration parameters
+ * @vdev_id: Id of the virtual device to configure
+ * @enable: Enable/Disable the given hw filter modes
+ * @mode_bitmap: the hardware filter mode bitmap to configure
+ */
+struct pmo_hw_filter_params {
+	uint8_t vdev_id;
+	bool enable;
+	enum pmo_hw_filter_mode mode_bitmap;
+};
+
+#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..4cd0df3
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_lphb_public_struct.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2017-2018 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"
+
+#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;
+};
+
+/*
+ * 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..6f92299
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_mc_addr_filtering_public_struct.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 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
+#define PMO_MAX_NUM_MULTICAST_ADDRESS 240
+
+/**
+ * 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];
+};
+
+/**
+ * struct mcast_filter_params - mcast filter parameters
+ * @multicast_addr_cnt: num of addresses
+ * @multicast_addr: address array
+ * @action: operation to perform
+ */
+struct pmo_mcast_filter_params {
+	uint32_t multicast_addr_cnt;
+	struct qdf_mac_addr multicast_addr[PMO_MAX_NUM_MULTICAST_ADDRESS];
+	uint8_t action;
+};
+#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..7aa44d4
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_ns_public_struct.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017-2018 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"
+
+/**
+ * enum pmo_ns_addr_scope - Internal identification of IPv6 addr scope
+ * @PMO_NS_ADDR_SCOPE_INVALID: invalid scope
+ * @PMO_NS_ADDR_SCOPE_NODELOCAL: node local scope
+ * @PMO_NS_ADDR_SCOPE_LINKLOCAL: link local scope
+ * @PMO_NS_ADDR_SCOPE_SITELOCAL: site local scope
+ * @PMO_NS_ADDR_SCOPE_ORGLOCAL: org local scope
+ * @PMO_NS_ADDR_SCOPE_GLOBAL: global scope
+ */
+enum pmo_ns_addr_scope {
+	PMO_NS_ADDR_SCOPE_INVALID = 0,
+	PMO_NS_ADDR_SCOPE_NODELOCAL = 1,
+	PMO_NS_ADDR_SCOPE_LINKLOCAL = 2,
+	PMO_NS_ADDR_SCOPE_SITELOCAL = 3,
+	PMO_NS_ADDR_SCOPE_ORGLOCAL = 4,
+	PMO_NS_ADDR_SCOPE_GLOBAL = 5
+};
+
+/**
+ * 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;
+	enum pmo_ns_addr_scope scope[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA];
+	bool is_offload_applied;
+};
+
+/**
+ * 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];
+	enum pmo_ns_addr_scope scope[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..3d69e1c
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2017-2018 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"
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+/**
+ * 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
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * 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
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_register_get_dtim_period_callback(): API to register callback that gets
+ * dtim period from mlme
+ * @psoc: objmgr psoc handle
+ * @handler: pointer to the callback function
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else error
+ */
+QDF_STATUS pmo_register_get_dtim_period_callback(struct wlan_objmgr_psoc *psoc,
+						 pmo_get_dtim_period handler);
+
+/**
+ * pmo_unregister_get_dtim_period_callback(): API to unregister callback that
+ * gets dtim period from mlme
+ * @psoc: objmgr psoc handle
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else error
+ */
+QDF_STATUS
+pmo_unregister_get_dtim_period_callback(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_register_get_beacon_interval_callback(): API to register callback that
+ * gets beacon interval from mlme
+ * @psoc: objmgr psoc handle
+ * @handler: pointer to the callback function
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else error
+ */
+QDF_STATUS
+pmo_register_get_beacon_interval_callback(struct wlan_objmgr_psoc *psoc,
+					  pmo_get_beacon_interval handler);
+
+/**
+ * pmo_unregister_get_beacon_interval_callback(): API to unregister callback
+ * that gets beacon interval from mlme
+ * @psoc: objmgr psoc handle
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else error
+ */
+QDF_STATUS
+pmo_unregister_get_beacon_interval_callback(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_register_get_vdev_dp_handle(): API to register get vdev datapath handle
+ * @psoc: objmgr psoc handle
+ * @handler: get vdev datapath handle callback
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_register_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc,
+					   pmo_get_vdev_dp_handle handler);
+
+/**
+ * pmo_unregister_get_vdev_dp_handle(): API to unregister get vdev dp handle
+ * @psoc: objmgr psoc handle
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * 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
+ *
+ * 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_register_get_cfg_int_callback(): API to register callback for getting
+ * cfg integer from mlme
+ * @psoc: objmgr psoc handle
+ * @handler: get cfg integer callback notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_register_get_cfg_int_callback(struct wlan_objmgr_psoc *psoc,
+					     pmo_get_cfg_int handler);
+
+/**
+ * pmo_unregister_get_cfg_int_callback(): API to unregister callback that gets
+ * cfg integer from mlme
+ * @psoc: objmgr psoc handle
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_get_cfg_int_callback(struct wlan_objmgr_psoc *psoc);
+
+#else /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+static inline QDF_STATUS pmo_init(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS pmo_deinit(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_psoc_object_created_notification(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_psoc_object_destroyed_notification(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_vdev_object_created_notification(struct wlan_objmgr_vdev *vdev, void *arg)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_vdev_ready(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_vdev_object_destroyed_notification(struct wlan_objmgr_vdev *vdev, void *arg)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_register_suspend_handler(enum wlan_umac_comp_id id,
+			     pmo_psoc_suspend_handler handler,
+			     void *arg)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_unregister_suspend_handler(enum wlan_umac_comp_id id,
+			       pmo_psoc_suspend_handler handler)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_register_resume_handler(enum wlan_umac_comp_id id,
+			    pmo_psoc_resume_handler handler,
+			    void *arg)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_unregister_resume_handler(enum wlan_umac_comp_id id,
+			      pmo_psoc_resume_handler handler)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc,
+			   enum qdf_suspend_type suspend_type)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_resume_all_components(struct wlan_objmgr_psoc *psoc,
+			  enum qdf_suspend_type suspend_type)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_register_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc,
+				   pmo_notify_pause_bitmap handler)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_unregister_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_register_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
+			      pmo_get_pause_bitmap handler)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_register_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc,
+				pmo_get_vdev_dp_handle handler)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+QDF_STATUS pmo_unregister_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_register_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc *psoc,
+				       pmo_is_device_in_low_pwr_mode handler)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_unregister_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_register_get_cfg_int_callback(struct wlan_objmgr_psoc *psoc,
+				  pmo_get_cfg_int handler)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_unregister_get_cfg_int_callback(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_register_get_dtim_period_callback(struct wlan_objmgr_psoc *psoc,
+				      pmo_get_dtim_period handler)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_unregister_get_dtim_period_callback(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_register_get_beacon_interval_callback(struct wlan_objmgr_psoc *psoc,
+					  pmo_get_beacon_interval handler)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+pmo_unregister_get_beacon_interval_callback(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#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..38e6346
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2017-2018 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 function that gets cfg integer from mlme
+ */
+typedef QDF_STATUS (*pmo_get_cfg_int)(int cfg_id, int *value);
+
+/**
+ * typedef for function that gets dtim period from mlme
+ */
+typedef QDF_STATUS (*pmo_get_dtim_period)(uint8_t vdev_id, uint8_t *value);
+
+/**
+ * typedef for function that gets  beacon interval from mlme
+ */
+typedef QDF_STATUS (*pmo_get_beacon_interval)(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 for getting vdev datapath handle
+ */
+typedef struct cdp_vdev * (*pmo_get_vdev_dp_handle)(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
+ * @del_wow_pattern: fp to delete wow pattern from firmware
+ * @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
+ * @get_multiple_mc_filter_support: fp to get mc filter support
+ * @send_set_multiple_mc_filter_req: fp to send set multiple mc filter request
+ * @send_clear_multiple_mc_filter_req: fp to send clear multiple mc filter req
+ * @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
+ * @psoc_send_d0wow_enable_req: fp to send D0 WOW enable request
+ * @psoc_send_d0wow_disable_req: fp to send D0 WOW disable 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);
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+	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);
+#endif
+	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 (*del_wow_pattern)(
+			struct wlan_objmgr_vdev *vdev, uint8_t ptrn_id);
+	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);
+	bool (*get_multiple_mc_filter_support)(
+			struct wlan_objmgr_psoc *psoc);
+	QDF_STATUS(*send_set_multiple_mc_filter_req)(
+			struct wlan_objmgr_vdev *vdev,
+			struct pmo_mc_addr_list *mc_list);
+	QDF_STATUS(*send_clear_multiple_mc_filter_req)(
+			struct wlan_objmgr_vdev *vdev,
+			struct pmo_mc_addr_list *mc_list);
+	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);
+	QDF_STATUS (*psoc_send_d0wow_enable_req)(
+			struct wlan_objmgr_psoc *psoc);
+	QDF_STATUS (*psoc_send_d0wow_disable_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_cfg.h b/components/pmo/dispatcher/inc/wlan_pmo_pkt_filter_cfg.h
new file mode 100644
index 0000000..a4b8a6e
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_pkt_filter_cfg.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef WLAN_PMO_PACKET_FILTER_CFG_H__
+#define WLAN_PMO_PACKET_FILTER_CFG_H__
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+/*
+ * <ini>
+ * g_enable_packet_filter_bitmap - Packet filters configuration
+ * @Min: 0
+ * @Max: 63
+ * @Default: 0
+ *
+ * To enable packet filters when target goes to suspend, clear when resume:
+ * bit-0 : IPv6 multicast
+ * bit-1 : IPv4 multicast
+ * bit-2 : IPv4 broadcast
+ * bit-3 : XID - Exchange station Identification packet, solicits the
+ *         identification of the receiving station
+ * bit-4 : STP - Spanning Tree Protocol, builds logical loop free topology
+ * bit-5 : DTP/LLC/CDP
+ *         DTP - Dynamic Trunking Protocol is used by Cisco switches to
+ *               negotiate whether an interconnection between two switches
+ *               should be put into access or trunk mode
+ *         LLC - Logical link control, used for multiplexing, flow & error
+ *               control
+ *         CDP - Cisco Discovery Protocol packet contains information
+ *               about the cisco devices in the network
+ *
+ * Supported Feature: Packet filtering
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PMO_PKT_FILTER CFG_INI_UINT( \
+	"g_enable_packet_filter_bitmap", \
+	0, 63, 0, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Packet filter bitmap configure")
+
+#define CFG_PACKET_FILTER_ALL \
+	CFG(CFG_PMO_PKT_FILTER)
+#else
+#define CFG_PACKET_FILTER_ALL
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+#endif /* WLAN_PMO_PACKET_FILTER_CFG_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..6ed76bd
--- /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_runtime_pm_cfg.h b/components/pmo/dispatcher/inc/wlan_pmo_runtime_pm_cfg.h
new file mode 100644
index 0000000..4b03cdf
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_runtime_pm_cfg.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef WLAN_PMO_RUNTIME_PM_CFG_H__
+#define WLAN_PMO_RUNTIME_PM_CFG_H__
+
+#ifdef FEATURE_RUNTIME_PM
+/*
+ * <ini>
+ * gRuntimePMDelay - Set runtime pm's inactivity timer
+ * @Min: 100
+ * @Max: 10000
+ * @Default: 500
+ *
+ * This ini is used to set runtime pm's inactivity timer value.
+ * the wlan driver will wait for this number of milliseconds of
+ * inactivity before performing a runtime suspend.
+ *
+ * Related: gRuntimePM
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_RUNTIME_PM_DELAY CFG_INI_UINT( \
+	"gRuntimePMDelay", \
+	100, \
+	10000, \
+	500, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Set runtime pm's inactivity timer")
+
+#define CFG_RUNTIME_PM_ALL \
+	CFG(CFG_PMO_RUNTIME_PM_DELAY)
+#else
+#define CFG_RUNTIME_PM_ALL
+#endif /* FEATURE_RUNTIME_PM */
+#endif /* WLAN_PMO_RUNTIME_PM_CFG_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..b322576
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h
@@ -0,0 +1,439 @@
+/*
+ * Copyright (c) 2017-2018 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);
+
+#ifdef WLAN_NS_OFFLOAD
+/**
+ * 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);
+#endif /* WLAN_NS_OFFLOAD */
+
+/**
+ * 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);
+
+QDF_STATUS pmo_tgt_del_wow_pattern(
+		struct wlan_objmgr_vdev *vdev, uint8_t ptrn_id,
+		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_get_multiple_mc_filter_support() - get multiple mcast filter support
+ * @vdev: objmgr vdev
+ *
+ * Return: true if FW supports else false
+ */
+bool pmo_tgt_get_multiple_mc_filter_support(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_tgt_set_multiple_mc_filter_req() - Set multiple mcast filter cmd to fw
+ * @vdev: objmgr vdev
+ * @mc_list: mcast address list
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_tgt_set_multiple_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_mc_addr_list *mc_list);
+
+/**
+ * pmo_tgt_clear_multiple_mc_filter_req() - clear multiple mcast filter
+ *					    to fw
+ * @vdev: objmgr vdev
+ * @mc_list: mcast address list
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_tgt_clear_multiple_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_mc_addr_list *mc_list);
+
+/**
+ * pmo_tgt_send_enhance_multicast_offload_req() - send enhance mc offload req
+ * @vdev: the vdev to configure
+ * @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 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..e8f6e8b
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h
@@ -0,0 +1,1768 @@
+/*
+ * Copyright (c) 2017-2018 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.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"
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+
+/**
+ * ucfg_pmo_psoc_open() - pmo psoc object open
+ * @psoc: objmgr vdev
+ *.
+ * This function used to open pmo psoc object by user space
+ *
+ * Return: true in case success else false
+ */
+QDF_STATUS ucfg_pmo_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_psoc_open() - pmo psoc object close
+ * @psoc: objmgr vdev
+ *.
+ * This function used to close pmo psoc object by user space
+ *
+ * Return: true in case success else false
+ */
+QDF_STATUS ucfg_pmo_psoc_close(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_apf_instruction_size() - get the current APF instruction size
+ * @psoc: the psoc to query
+ *
+ * Return: APF instruction size
+ */
+uint32_t ucfg_pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_num_wow_filters() - get the supported number of WoW filters
+ * @psoc: the psoc to query
+ *
+ * Return: number of WoW filters supported
+ */
+uint8_t ucfg_pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
+	enum QDF_OPMODE vdev_opmode);
+
+/**
+ * ucfg_pmo_is_vdev_connected() -  to check whether peer is associated or not
+ * @vdev: objmgr vdev
+ *
+ * Return: true in case success else false
+ */
+bool ucfg_pmo_is_vdev_connected(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * ucfg_pmo_is_vdev_supports_offload() - check offload is supported on vdev
+ * @vdev: objmgr vdev
+ *
+ * Return: true in case success else false
+ */
+bool ucfg_pmo_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_get_psoc_config(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_update_psoc_config(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg);
+
+/**
+ * ucfg_pmo_psoc_set_caps() - overwrite configured device capability flags
+ * @psoc: the psoc for which the capabilities apply
+ * @caps: the cabability information to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc,
+				  struct pmo_device_caps *caps);
+
+/**
+ * ucfg_pmo_is_arp_offload_enabled() - Get arp offload enable or not
+ * @psoc: pointer to psoc object
+ *
+ * Return: arp offload enable or not
+ */
+bool
+ucfg_pmo_is_arp_offload_enabled(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_set_arp_offload_enabled() - Set arp offload enable or not
+ * @psoc: pointer to psoc object
+ * @val:  enable/disable arp offload
+ *
+ * Return: None
+ */
+void
+ucfg_pmo_set_arp_offload_enabled(struct wlan_objmgr_psoc *psoc,
+				 bool val);
+
+/**
+ * ucfg_pmo_is_ssdp_enabled() - Get ssdp enable or not
+ * @psoc: pointer to psoc object
+ *
+ * Return: enable/disable ssdp
+ */
+bool
+ucfg_pmo_is_ssdp_enabled(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_is_ns_offloaded() - Get ns offload support or not
+ * @psoc: pointer to psoc object
+ *
+ * Return: ns offload or not
+ */
+bool
+ucfg_pmo_is_ns_offloaded(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_sta_dynamic_dtim() - Get dynamic dtim
+ * @psoc: pointer to psoc object
+ *
+ * Return: dynamic dtim
+ */
+uint8_t
+ucfg_pmo_get_sta_dynamic_dtim(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_sta_mod_dtim() - Get modulated dtim
+ * @psoc: pointer to psoc object
+ *
+ * Return: modulated dtim
+ */
+uint8_t
+ucfg_pmo_get_sta_mod_dtim(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_set_sta_mod_dtim() - Set modulated dtim
+ * @psoc: pointer to psoc object
+ * @val:  modulated dtim
+ *
+ * Return: None
+ */
+void
+ucfg_pmo_set_sta_mod_dtim(struct wlan_objmgr_psoc *psoc,
+			  uint8_t val);
+
+/**
+ * ucfg_pmo_is_mc_addr_list_enabled() - Get multicast address list enable or not
+ * @psoc: pointer to psoc object
+ *
+ * Return: multicast address list enable or not
+ */
+bool
+ucfg_pmo_is_mc_addr_list_enabled(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_power_save_mode() - Get power save mode
+ * @psoc: pointer to psoc object
+ *
+ * Return: power save mode
+ */
+enum powersave_mode
+ucfg_pmo_get_power_save_mode(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_set_power_save_mode() - Set power save mode
+ * @psoc: pointer to psoc object
+ * @val:  power save mode
+ *
+ * Return: None
+ */
+void
+ucfg_pmo_set_power_save_mode(struct wlan_objmgr_psoc *psoc,
+			     enum powersave_mode val);
+
+/**
+ * ucfg_pmo_get_max_ps_poll() - Get max power save poll
+ * @psoc: pointer to psoc object
+ *
+ * Return: power save poll
+ */
+uint8_t
+ucfg_pmo_get_max_ps_poll(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_power_save_offload_enabled() - Get power save offload enabled type
+ * @psoc: pointer to psoc object
+ *
+ * Return: power save offload enabled type
+ */
+uint8_t
+ucfg_pmo_power_save_offload_enabled(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_enable_wakeup_event() -  enable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @wow_event: wow event to enable
+ *
+ * Return: none
+ */
+void ucfg_pmo_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+				  uint32_t vdev_id,
+				  WOW_WAKE_EVENT_TYPE wow_event);
+
+/**
+ * ucfg_pmo_disable_wakeup_event() -  disable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @wow_event: wow event to disable
+ *
+ * Return: none
+ */
+void ucfg_pmo_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+				   uint32_t vdev_id,
+				   WOW_WAKE_EVENT_TYPE wow_event);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_cache_arp_offload_req(struct pmo_arp_req *arp_req);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * ucfg_pmo_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
+ucfg_pmo_enable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+				   enum pmo_offload_trigger trigger);
+
+/**
+ * ucfg_pmo_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
+ucfg_pmo_disable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+				    enum pmo_offload_trigger trigger);
+
+/**
+ * ucfg_pmo_get_arp_offload_params() - API to get arp offload params
+ * @vdev: objmgr vdev
+ * @params: output pointer to hold offload params
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS
+ucfg_pmo_get_arp_offload_params(struct wlan_objmgr_vdev *vdev,
+				struct pmo_arp_offload_params *params);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_cache_ns_offload_req(struct pmo_ns_req *ns_req);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * ucfg_pmo_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
+ucfg_pmo_enable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+				  enum pmo_offload_trigger trigger);
+
+/**
+ * ucfg_pmo_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
+ucfg_pmo_disable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+				   enum pmo_offload_trigger trigger);
+
+/**
+ * ucfg_pmo_get_ns_offload_params() - API to get ns offload params
+ * @vdev: objmgr vdev
+ * @params: output pointer to hold offload params
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS
+ucfg_pmo_get_ns_offload_params(struct wlan_objmgr_vdev *vdev,
+			       struct pmo_ns_offload_params *params);
+
+/**
+ * ucfg_pmo_ns_addr_scope() - Convert linux specific IPv6 addr scope to
+ *			      WLAN driver specific value
+ * @scope: linux specific IPv6 addr scope
+ *
+ * Return: PMO identifier of linux IPv6 addr scope
+ */
+enum pmo_ns_addr_scope
+ucfg_pmo_ns_addr_scope(uint32_t ipv6_scope);
+
+/**
+ * ucfg_pmo_enable_hw_filter_in_fwr() - enable previously configured hw filter
+ * @vdev: objmgr vdev to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_pmo_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * ucfg_pmo_disable_hw_filter_in_fwr() - disable previously configured hw filter
+ * @vdev: objmgr vdev to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_pmo_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_max_mc_addr_supported(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_cache_mc_addr_list(
+		struct pmo_mc_addr_list_params *mc_list_config);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+				       uint8_t vdev_id);
+
+/**
+ * ucfg_pmo_enhance_mc_filter_enable() - enable enhanced multicast filtering
+ * @vdev: the vdev to enable enhanced multicast filtering for
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS
+ucfg_pmo_enhanced_mc_filter_enable(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_enhanced_mc_filter_enable(vdev);
+}
+
+/**
+ * ucfg_pmo_enhance_mc_filter_disable() - disable enhanced multicast filtering
+ * @vdev: the vdev to disable enhanced multicast filtering for
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS
+ucfg_pmo_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_enhanced_mc_filter_disable(vdev);
+}
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_enable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_disable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * ucfg_pmo_get_mc_addr_list() - API to get mc addr list configured
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev identifier
+ * @mc_list_req: output pointer to hold mc addr list params
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS
+ucfg_pmo_get_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+			  uint8_t vdev_id,
+			  struct pmo_mc_addr_list *mc_list_req);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_cache_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+					  struct pmo_gtk_req *gtk_req);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_flush_gtk_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+/**
+ * ucfg_pmo_get_pkt_filter_bitmap() - get default packet filters bitmap
+ * @psoc: the psoc to query
+ *
+ * Return: retrieve packet filter bitmap configuration
+ */
+uint8_t ucfg_pmo_get_pkt_filter_bitmap(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_num_packet_filters() - get the number of packet filters
+ * @psoc: the psoc to query
+ *
+ * Return: number of packet filters
+ */
+uint32_t ucfg_pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_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
+ucfg_pmo_set_pkt_filter(struct wlan_objmgr_psoc *psoc,
+			struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+			uint8_t vdev_id);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_clear_pkt_filter(
+	struct wlan_objmgr_psoc *psoc,
+	struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param,
+	uint8_t vdev_id);
+#else
+static inline uint8_t
+ucfg_pmo_get_pkt_filter_bitmap(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint32_t
+ucfg_pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_set_pkt_filter(
+		struct wlan_objmgr_psoc *psoc,
+		struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+		uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_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 QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * ucfg_pmo_get_wow_enable() - Get wow enable type
+ * @psoc: pointer to psoc object
+ *
+ * Return: wow enable type
+ */
+enum pmo_wow_enable_type
+ucfg_pmo_get_wow_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_set_wow_enable() - Set wow enable type
+ * @psoc: pointer to psoc object
+ * @val: wow enalbe value
+ *
+ * Return: None
+ */
+void
+ucfg_pmo_set_wow_enable(struct wlan_objmgr_psoc *psoc,
+			enum pmo_wow_enable_type val);
+
+/**
+ * ucfg_pmo_is_wowlan_deauth_enabled() - Get wowlan deauth enable
+ * @psoc: pointer to psoc object
+ *
+ * Return: wowlan deauth enable or not
+ */
+bool
+ucfg_pmo_is_wowlan_deauth_enabled(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_is_wowlan_disassoc_enabled() - Get wowlan disassoc enable
+ * @psoc: pointer to psoc object
+ *
+ * Return: wowlan disassoc enable
+ */
+bool
+ucfg_pmo_is_wowlan_disassoc_enabled(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_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
+ucfg_pmo_get_gtk_rsp(struct wlan_objmgr_vdev *vdev,
+		     struct pmo_gtk_rsp_req *gtk_rsp_req);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
+					 bool value);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_update_p2plo_in_progress(struct wlan_objmgr_vdev *vdev,
+				       bool value);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_lphb_config_req(struct wlan_objmgr_psoc *psoc,
+				    struct pmo_lphb_req *lphb_req,
+				    void *lphb_cb_ctx,
+				    pmo_lphb_callback callback);
+
+/**
+ * ucfg_pmo_psoc_update_power_save_mode() - update power save mode
+ * @vdev: objmgr vdev handle
+ * @value:vdev power save mode
+ *
+ * Return: None
+ */
+void ucfg_pmo_psoc_update_power_save_mode(struct wlan_objmgr_psoc *psoc,
+					  uint8_t value);
+
+/**
+ * ucfg_pmo_psoc_update_dp_handle() - update psoc data path handle
+ * @psoc: objmgr psoc handle
+ * @dp_hdl: psoc data path handle
+ *
+ * Return: None
+ */
+void ucfg_pmo_psoc_update_dp_handle(struct wlan_objmgr_psoc *psoc,
+				    void *dp_hdl);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_psoc_update_htc_handle(struct wlan_objmgr_psoc *psoc,
+				     void *htc_handle);
+
+/**
+ * ucfg_pmo_psoc_set_hif_handle() - Set psoc hif layer handle
+ * @psoc: objmgr psoc handle
+ * @hif_handle: hif context handle
+ *
+ * Return: None
+ */
+void ucfg_pmo_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+				  void *hif_handle);
+
+/**
+ * ucfg_pmo_psoc_set_txrx_handle() - Set psoc pdev txrx layer handle
+ * @psoc: objmgr psoc handle
+ * @txrx_handle: pdev txrx context handle
+ *
+ * Return: None
+ */
+void ucfg_pmo_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				   void *txrx_handle);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc,
+						enum qdf_suspend_type type);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
+					       enum qdf_suspend_type type);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_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
+/**
+ * ucfg_pmo_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 ucfg_pmo_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+					     pmo_pld_auto_suspend_cb pld_cb);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+					    pmo_pld_auto_resume_cb pld_cb);
+#endif
+
+/**
+ * ucfg_pmo_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
+ucfg_pmo_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
+			     int disable_target_intr);
+
+QDF_STATUS
+ucfg_pmo_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
+			      struct pmo_wow_add_pattern *ptrn);
+
+QDF_STATUS
+ucfg_pmo_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
+			      uint8_t pattern_id);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
+					enum qdf_suspend_type type);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_get_wow_bus_suspend(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_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 ucfg_pmo_psoc_handle_initial_wake_up(void *cb_ctx);
+
+/**
+ * ucfg_pmo_psoc_is_target_wake_up_received() - Get initial wake up status
+ * @psoc: objmgr psoc handle
+ *
+ * Return: 0 on success else error code
+ */
+int ucfg_pmo_psoc_is_target_wake_up_received(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_psoc_is_target_wake_up_received() - Clear initial wake up status
+ * @psoc: objmgr psoc handle
+ *
+ * Return: 0 on success else error code
+ */
+int ucfg_pmo_psoc_clear_target_wake_up(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_psoc_target_suspend_acknowledge() - Clear initial wake up status
+ * @psoc: objmgr psoc handle
+ *
+ * Return: None
+ */
+void ucfg_pmo_psoc_target_suspend_acknowledge(void *context, bool wow_nack);
+
+/**
+ * ucfg_pmo_psoc_wakeup_host_event_received() - got host wake up evennt from fwr
+ * @psoc: objmgr psoc handle
+ *
+ * Return: None
+ */
+void ucfg_pmo_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_config_listen_interval() - function to configure listen interval
+ * @vdev: objmgr vdev
+ * @listen_interval: new listen interval passed by user
+ *
+ * This function allows user to configure listen interval dynamically
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_pmo_config_listen_interval(struct wlan_objmgr_vdev *vdev,
+					   uint32_t listen_interval);
+
+/**
+ * ucfg_pmo_config_modulated_dtim() - function to configure modulated dtim
+ * @vdev: objmgr vdev handle
+ * @param_value: New modulated dtim value passed by user
+ *
+ * This function configures the modulated dtim in firmware
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_pmo_config_modulated_dtim(struct wlan_objmgr_vdev *vdev,
+					  uint32_t mod_dtim);
+
+#ifdef WLAN_FEATURE_WOW_PULSE
+/**
+ * ucfg_pmo_is_wow_pulse_enabled() - to get wow pulse enable configuration
+ * @psoc: objmgr psoc handle
+ *
+ * Return: wow pulse enable configuration
+ */
+bool ucfg_pmo_is_wow_pulse_enabled(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_wow_pulse_pin() - to get wow pulse pin configuration
+ * @psoc: objmgr psoc handle
+ *
+ * Return: wow pulse pin configuration
+ */
+uint8_t ucfg_pmo_get_wow_pulse_pin(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_wow_pulse_interval_high() - to get wow pulse interval high
+ * @psoc: objmgr psoc handle
+ *
+ * Return: wow pulse interval high configuration
+ */
+uint16_t ucfg_pmo_get_wow_pulse_interval_high(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_wow_pulse_interval_low() - to get wow pulse interval low
+ * @psoc: objmgr psoc handle
+ *
+ * Return: wow pulse interval high configuration
+ */
+uint16_t ucfg_pmo_get_wow_pulse_interval_low(struct wlan_objmgr_psoc *psoc);
+#else
+static inline bool
+ucfg_pmo_is_wow_pulse_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline uint8_t
+ucfg_pmo_get_wow_pulse_pin(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint16_t
+ucfg_pmo_get_wow_pulse_interval_high(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+#endif
+
+/**
+ * ucfg_pmo_is_active_mode_offloaded() - get active mode offload configuration
+ * @psoc: objmgr psoc handle
+ *
+ * Return: retrieve active mode offload configuration
+ */
+bool ucfg_pmo_is_active_mode_offloaded(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_auto_power_fail_mode() - to get auto power save failure mode
+ * @psoc: objmgr psoc handle
+ *
+ * Return: auto power save failure mode configuration
+ */
+enum pmo_auto_pwr_detect_failure_mode
+ucfg_pmo_get_auto_power_fail_mode(struct wlan_objmgr_psoc *psoc);
+
+#ifdef FEATURE_WLAN_APF
+/**
+ * ucfg_pmo_is_apf_enabled() - to get apf configuration
+ * @psoc: objmgr psoc handle
+ *
+ * Return: true if enabled, it is intersection of ini and target cap
+ */
+bool ucfg_pmo_is_apf_enabled(struct wlan_objmgr_psoc *psoc);
+#else
+static inline bool ucfg_pmo_is_apf_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+#endif
+
+#else /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+static inline QDF_STATUS
+ucfg_pmo_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline uint32_t
+ucfg_pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint8_t
+ucfg_pmo_get_pkt_filter_bitmap(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint32_t
+ucfg_pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint8_t
+ucfg_pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_get_psoc_config(
+		struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_update_psoc_config(
+		struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_psoc_set_caps(
+		struct wlan_objmgr_psoc *psoc,
+		struct pmo_device_caps *caps)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline bool
+ucfg_pmo_is_ap_mode_supports_arp_ns(
+		struct wlan_objmgr_psoc *psoc,
+		enum QDF_OPMODE vdev_opmode)
+{
+	return true;
+}
+
+static inline bool
+ucfg_pmo_is_vdev_connected(struct wlan_objmgr_vdev *vdev)
+{
+	return true;
+}
+
+static inline bool
+ucfg_pmo_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev)
+{
+	return true;
+}
+
+static inline void
+ucfg_pmo_enable_wakeup_event(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t vdev_id, uint32_t *bitmap)
+{
+}
+
+static inline void
+ucfg_pmo_disable_wakeup_event(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t vdev_id, uint32_t bitmap)
+{
+}
+
+static inline QDF_STATUS
+ucfg_pmo_cache_arp_offload_req(struct pmo_arp_req *arp_req)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_enable_arp_offload_in_fwr(
+		struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_disable_arp_offload_in_fwr(
+		struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_get_arp_offload_params(struct wlan_objmgr_vdev *vdev,
+				struct pmo_arp_offload_params *params)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_cache_ns_offload_req(struct pmo_ns_req *ns_req)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_enable_ns_offload_in_fwr(
+		struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_disable_ns_offload_in_fwr(
+		struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_get_ns_offload_params(struct wlan_objmgr_vdev *vdev,
+			       struct pmo_ns_offload_params *params)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline enum pmo_ns_addr_scope
+ucfg_pmo_ns_addr_scope(uint32_t ipv6_scope)
+{
+	return PMO_NS_ADDR_SCOPE_INVALID;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_cache_mc_addr_list(
+		struct pmo_mc_addr_list_params *mc_list_config)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_flush_mc_addr_list(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_enable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_disable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline uint8_t
+ucfg_pmo_max_mc_addr_supported(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_get_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+			  uint8_t vdev_id,
+			  struct pmo_mc_addr_list *mc_list_req)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_cache_gtk_offload_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_req *gtk_req)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_flush_gtk_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_set_pkt_filter(
+		struct wlan_objmgr_psoc *psoc,
+		struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+		uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_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 QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_get_gtk_rsp(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_rsp_req *gtk_rsp_req)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void
+ucfg_pmo_update_extscan_in_progress(
+		struct wlan_objmgr_vdev *vdev,
+		bool value)
+{
+}
+
+static inline void
+ucfg_pmo_update_p2plo_in_progress(
+		struct wlan_objmgr_vdev *vdev,
+		bool value)
+{
+}
+
+static inline QDF_STATUS
+ucfg_pmo_lphb_config_req(
+		struct wlan_objmgr_psoc *psoc,
+		struct pmo_lphb_req *lphb_req, void *lphb_cb_ctx,
+		pmo_lphb_callback callback)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void
+ucfg_pmo_psoc_update_power_save_mode(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t value)
+{
+}
+
+static inline void
+ucfg_pmo_psoc_update_dp_handle(
+		struct wlan_objmgr_psoc *psoc,
+		void *dp_handle)
+{
+}
+
+static inline void
+ucfg_pmo_vdev_update_dp_handle(
+		struct wlan_objmgr_vdev *vdev,
+		void *dp_handle)
+{
+}
+
+static inline void
+ucfg_pmo_psoc_update_htc_handle(
+		struct wlan_objmgr_psoc *psoc,
+		void *htc_handle)
+{
+}
+
+static inline void
+ucfg_pmo_psoc_set_hif_handle(
+		struct wlan_objmgr_psoc *psoc,
+		void *hif_handle)
+{
+}
+
+static inline void
+ucfg_pmo_psoc_set_txrx_handle(
+		struct wlan_objmgr_psoc *psoc,
+		void *txrx_handle)
+{
+}
+
+static inline void
+ucfg_pmo_psoc_handle_initial_wake_up(void *cb_ctx)
+{
+}
+
+static inline QDF_STATUS
+ucfg_pmo_psoc_user_space_suspend_req(
+		struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_psoc_user_space_resume_req(
+		struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_psoc_bus_suspend_req(
+		struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type,
+		struct pmo_wow_enable_params *wow_params)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_RUNTIME_PM
+static inline QDF_STATUS
+ucfg_pmo_psoc_bus_runtime_suspend(
+		struct wlan_objmgr_psoc *psoc,
+		pmo_pld_auto_suspend_cb pld_cb)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_psoc_bus_runtime_resume(
+		struct wlan_objmgr_psoc *psoc,
+		pmo_pld_auto_suspend_cb pld_cb)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+static inline QDF_STATUS
+ucfg_pmo_psoc_suspend_target(
+		struct wlan_objmgr_psoc *psoc,
+		int disable_target_intr)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_add_wow_user_pattern(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_wow_add_pattern *ptrn)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_del_wow_user_pattern(
+		struct wlan_objmgr_vdev *vdev,
+		uint8_t pattern_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_psoc_bus_resume_req(
+		struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline bool
+ucfg_pmo_get_wow_bus_suspend(struct wlan_objmgr_psoc *psoc)
+{
+	return true;
+}
+
+static inline int
+ucfg_pmo_psoc_is_target_wake_up_received(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline int
+ucfg_pmo_psoc_clear_target_wake_up(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline void
+ucfg_pmo_psoc_target_suspend_acknowledge(void *context, bool wow_nack)
+{
+}
+
+static inline void
+ucfg_pmo_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline QDF_STATUS
+ucfg_pmo_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_enhanced_mc_filter_enable(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_config_listen_interval(struct wlan_objmgr_vdev *vdev,
+				uint32_t listen_interval)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+ucfg_pmo_config_modulated_dtim(struct wlan_objmgr_vdev *vdev,
+			       uint32_t mod_dtim)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline bool
+ucfg_pmo_is_arp_offload_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline void
+ucfg_pmo_set_arp_offload_enabled(struct wlan_objmgr_psoc *psoc,
+				 bool val)
+{
+}
+
+static inline bool
+ucfg_pmo_is_wow_pulse_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline uint8_t
+ucfg_pmo_get_wow_pulse_pin(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint16_t
+ucfg_pmo_get_wow_pulse_interval_high(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint16_t
+ucfg_pmo_get_wow_pulse_interval_low(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline bool
+ucfg_pmo_is_active_mode_offloaded(struct wlan_objmgr_psoc *psoc)
+{
+	return true;
+}
+
+static inline enum pmo_auto_pwr_detect_failure_mode
+ucfg_pmo_get_auto_power_fail_mode(struct wlan_objmgr_psoc *psoc)
+{
+	return PMO_FW_TO_CRASH_ON_PWR_FAILURE;
+}
+
+static inline bool ucfg_pmo_is_apf_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline bool ucfg_pmo_is_ssdp_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline bool ucfg_pmo_is_ns_offloaded(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline uint8_t
+ucfg_pmo_get_sta_dynamic_dtim(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint8_t
+ucfg_pmo_get_sta_mod_dtim(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline void
+ucfg_pmo_set_sta_mod_dtim(struct wlan_objmgr_psoc *psoc,
+			  uint8_t val)
+{
+}
+
+static inline bool
+ucfg_pmo_is_mc_addr_list_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline enum powersave_mode
+ucfg_pmo_get_power_save_mode(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline void
+ucfg_pmo_set_power_save_mode(struct wlan_objmgr_psoc *psoc,
+			     enum powersave_mode val)
+{
+}
+
+static inline uint8_t
+ucfg_pmo_get_max_ps_poll(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint8_t
+ucfg_pmo_power_save_offload_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+/**
+ * ucfg_pmo_extwow_is_goto_suspend_enabled() - Get extwow goto suspend enable
+ * @psoc: pointer to psoc object
+ *
+ * Return: extend wow goto suspend enable or not
+ */
+bool
+ucfg_pmo_extwow_is_goto_suspend_enabled(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_extwow_app1_wakeup_pin_num() - Get wakeup1 PIN number
+ * @psoc: pointer to psoc object
+ *
+ * Return: wakeup1 PIN number
+ */
+uint8_t
+ucfg_pmo_extwow_app1_wakeup_pin_num(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_extwow_app2_wakeup_pin_num() - Get wakeup2 PIN number
+ * @psoc: pointer to psoc object
+ *
+ * Return: wakeup2 PIN number
+ */
+uint8_t
+ucfg_pmo_extwow_app2_wakeup_pin_num(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_extwow_app2_init_ping_interval() - Get keep alive init ping interval
+ * @psoc: pointer to psoc object
+ *
+ * Return: keep alive init ping interval
+ */
+uint32_t
+ucfg_pmo_extwow_app2_init_ping_interval(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_extwow_app2_min_ping_interval() - Get keep alive min ping interval
+ * @psoc: pointer to psoc object
+ *
+ * Return: keep alive min ping interval
+ */
+uint32_t
+ucfg_pmo_extwow_app2_min_ping_interval(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_extwow_app2_max_ping_interval() - Get keep alive max ping interval
+ * @psoc: pointer to psoc object
+ *
+ * Return: keep alive max ping interval
+ */
+uint32_t
+ucfg_pmo_extwow_app2_max_ping_interval(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_extwow_app2_inc_ping_interval() - Get keep alive inc ping interval
+ * @psoc: pointer to psoc object
+ *
+ * Return: keep alive inc ping interval
+ */
+uint32_t
+ucfg_pmo_extwow_app2_inc_ping_interval(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_extwow_app2_tcp_src_port() - Get TCP source port
+ * @psoc: pointer to psoc object
+ *
+ * Return: TCP source port
+ */
+uint16_t
+ucfg_pmo_extwow_app2_tcp_src_port(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_extwow_app2_tcp_dst_port() - Get TCP Destination port
+ * @psoc: pointer to psoc object
+ *
+ * Return: TCP Destination port
+ */
+uint16_t
+ucfg_pmo_extwow_app2_tcp_dst_port(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_extwow_app2_tcp_tx_timeout() - Get TCP Tx timeout
+ * @psoc: pointer to psoc object
+ *
+ * Return: TCP Tx timeout
+ */
+uint32_t
+ucfg_pmo_extwow_app2_tcp_tx_timeout(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_extwow_app2_tcp_rx_timeout() - to get extwow tcp rx timeout
+ * @psoc: objmgr psoc handle
+ *
+ * Return: retrieve extwow app2 tcp rx timeout configuration
+ */
+uint32_t
+ucfg_pmo_extwow_app2_tcp_rx_timeout(struct wlan_objmgr_psoc *psoc);
+
+#else
+static inline bool
+ucfg_pmo_extwow_is_goto_suspend_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline uint32_t
+ucfg_pmo_extwow_app1_wakeup_pin_num(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint32_t
+ucfg_pmo_extwow_app2_wakeup_pin_num(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint32_t
+ucfg_pmo_extwow_app2_init_ping_interval(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint32_t
+ucfg_pmo_extwow_app2_min_ping_interval(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint32_t
+ucfg_pmo_extwow_app2_max_ping_interval(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint32_t
+ucfg_pmo_extwow_app2_inc_ping_interval(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint16_t
+ucfg_pmo_extwow_app2_tcp_src_port(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint16_t
+ucfg_pmo_extwow_app2_tcp_dst_port(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint32_t
+ucfg_pmo_extwow_app2_tcp_tx_timeout(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+
+static inline uint32_t
+ucfg_pmo_extwow_app2_tcp_rx_timeout(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+#endif
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * ucfg_pmo_get_runtime_pm_delay() - Get runtime pm's inactivity timer
+ * @psoc: pointer to psoc object
+ *
+ * Return: runtime pm's inactivity timer
+ */
+uint32_t
+ucfg_pmo_get_runtime_pm_delay(struct wlan_objmgr_psoc *psoc);
+#else
+static inline uint32_t
+ucfg_pmo_get_runtime_pm_delay(struct wlan_objmgr_psoc *psoc)
+{
+	return 0;
+}
+#endif /* FEATURE_RUNTIME_PM */
+#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..78badb9
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2017-2018 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_
+
+#ifndef PMO_WOW_FILTERS_MAX
+#define PMO_WOW_FILTERS_MAX             22
+#endif
+
+#define PMO_WOWL_PTRN_MAX_SIZE          146
+#define PMO_WOWL_PTRN_MASK_MAX_SIZE      19
+#define PMO_WOWL_BCAST_PATTERN_MAX_SIZE 146
+
+#define PMO_WOW_INTER_PTRN_TOKENIZER   ';'
+#define PMO_WOW_INTRA_PTRN_TOKENIZER   ':'
+
+#define PMO_WOW_PTRN_MASK_VALID     0xFF
+#define PMO_NUM_BITS_IN_BYTE           8
+
+
+/* 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
+
+#define PMO_MAC_ACTION_MEASURE_REQUEST_ID      0
+#define PMO_MAC_ACTION_TPC_REQUEST_ID          2
+/*
+ * 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      0
+ * 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_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)
+
+/* Public Action for 20/40 BSS Coexistence */
+#define PMO_MAC_ACTION_MEASUREMENT_PILOT    7
+
+#define DROP_PUBLIC_ACTION_FRAME_BITMAP \
+		(1 << PMO_MAC_ACTION_MEASUREMENT_PILOT)
+
+#ifndef ANI_SUPPORT_11H
+/*
+ * DROP_SPEC_MGMT_ACTION_FRAME_BITMAP
+ *
+ * Bitmask is based on the below. The frames with 1's
+ * set to their corresponding bit can be dropped in FW.
+ *
+ * ----------------------------------+-----+------+
+ *         Type                      | Bit | Drop |
+ * ----------------------------------+-----+------+
+ * SIR_MAC_ACTION_MEASURE_REQUEST_ID    0     1
+ * SIR_MAC_ACTION_TPC_REQUEST_ID        2     1
+ * ----------------------------------+-----+------+
+ */
+#define DROP_SPEC_MGMT_ACTION_FRAME_BITMAP \
+		((1 << PMO_MAC_ACTION_MEASURE_REQUEST_ID) |\
+		 (1 << PMO_MAC_ACTION_TPC_REQUEST_ID))
+#else
+/*
+ * If 11H support is defined, dont drop the above action category of
+ * spectrum mgmt action frames as host driver is processing them.
+ */
+#define DROP_SPEC_MGMT_ACTION_FRAME_BITMAP 0
+#endif /* ANI_SUPPORT_11H */
+
+#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.
+ * @action_per_category: bitmap per action category
+ */
+struct pmo_action_wakeup_set_params {
+	uint32_t vdev_id;
+	uint32_t operation;
+	uint32_t action_category_map[PMO_SUPPORTED_ACTION_CATE_ELE_LIST];
+	uint32_t action_per_category[PMO_SUPPORTED_ACTION_CATE];
+};
+
+/**
+ * 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,
+};
+
+/**
+ * enum pmo_wow_state: enumeration of wow state
+ * @pmo_wow_state_none: not in wow state
+ * @pmo_wow_state_legacy_d0: in d0 wow state trigger by legacy d0 wow command
+ * @pmo_wow_state_unified_d0: in d0 wow state trigger by unified wow command
+ * @pmo_wow_state_unified_d3: in d3 wow state trigger by unified wow command
+ */
+enum pmo_wow_state {
+	pmo_wow_state_none = 0,
+	pmo_wow_state_legacy_d0,
+	pmo_wow_state_unified_d0,
+	pmo_wow_state_unified_d3,
+};
+
+/**
+ * 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
+ * @wow_state: state of wow
+ * @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
+ * @ptrn_id_def: default pattern id counter for legacy firmware
+ * @ptrn_id_usr: user pattern id counter for legacy firmware
+ *
+ * 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;
+	enum pmo_wow_state wow_state;
+	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;
+
+	uint8_t ptrn_id_def;
+	uint8_t ptrn_id_usr;
+};
+
+/* 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_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/inc/wlan_pmo_wow_pulse_cfg.h b/components/pmo/dispatcher/inc/wlan_pmo_wow_pulse_cfg.h
new file mode 100644
index 0000000..6dfaf67
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_wow_pulse_cfg.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef WLAN_PMO_WOW_PULSE_CFG_H__
+#define WLAN_PMO_WOW_PULSE_CFG_H__
+
+#ifdef WLAN_FEATURE_WOW_PULSE
+/*
+ * <ini>
+ * gwow_pulse_support - WOW pulse feature configuration
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * When set to 1 WOW pulse feature will be enabled.
+ *
+ * Related: gwow_pulse_pin, gwow_pulse_interval_low, gwow_pulse_interval_high
+ *
+ * Supported Feature: WOW pulse
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_WOW_PULSE_ENABLE CFG_INI_BOOL("gwow_pulse_support", \
+					      0, \
+					      "Enable wow pulse")
+
+/*
+ * <ini>
+ * gwow_pulse_pin - GPIO pin for WOW pulse
+ * @Min: 0
+ * @Max: 254
+ * @Default: 35
+ *
+ * Which PIN to send the Pulse
+ *
+ * Supported Feature: WOW pulse
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_WOW_PULSE_PIN CFG_INI_UINT("gwow_pulse_pin", \
+					   0, 254, 35, \
+					   CFG_VALUE_OR_DEFAULT, \
+					   "Pin for wow pulse")
+
+/*
+ * <ini>
+ * gwow_pulse_interval_low - Pulse interval low
+ * @Min: 160
+ * @Max: 480
+ * @Default: 180
+ *
+ * The interval of low level in the pulse
+ *
+ * Supported Feature: WOW pulse
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_WOW_PULSE_LOW CFG_INI_UINT("gwow_pulse_interval_low", \
+					   160, 480, 180, \
+					   CFG_VALUE_OR_DEFAULT, \
+					   "Interval of low pulse")
+
+/*
+ * <ini>
+ * gwow_pulse_interval_high - Pulse interval high
+ * @Min: 20
+ * @Max: 40
+ * @Default: 20
+ *
+ * The interval of high level in the pulse
+ *
+ * Supported Feature: WOW pulse
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PMO_WOW_PULSE_HIGH CFG_INI_UINT("gwow_pulse_interval_high", \
+					    20, 40, 20, \
+					    CFG_VALUE_OR_DEFAULT, \
+					    "Interval of high pulse")
+
+#define CFG_WOW_PULSE_ALL \
+	CFG(CFG_PMO_WOW_PULSE_ENABLE) \
+	CFG(CFG_PMO_WOW_PULSE_PIN) \
+	CFG(CFG_PMO_WOW_PULSE_LOW) \
+	CFG(CFG_PMO_WOW_PULSE_HIGH)
+#else
+#define CFG_WOW_PULSE_ALL
+#endif /* WLAN_FEATURE_WOW_PULSE */
+#endif /* WLAN_PMO_WOW_PULSE_CFG_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..f32742b
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c
@@ -0,0 +1,948 @@
+/*
+ * Copyright (c) 2018 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 < 0 || id >= WLAN_UMAC_MAX_COMPONENTS) {
+		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 < 0 || id >= WLAN_UMAC_MAX_COMPONENTS) {
+		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 < 0 || id >= WLAN_UMAC_MAX_COMPONENTS) {
+		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 < 0 || id >= WLAN_UMAC_MAX_COMPONENTS) {
+		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;
+	int 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))
+			QDF_DEBUG_PANIC("component %d failed resume; status:%d",
+					i, resume_status);
+	}
+
+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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->pause_bitmap_notifier = handler;
+	}
+
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_unregister_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc 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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->pause_bitmap_notifier = NULL;
+	}
+
+	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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->get_pause_bitmap = handler;
+	}
+
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc 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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->get_pause_bitmap = NULL;
+	}
+
+	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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->is_device_in_low_pwr_mode = handler;
+	}
+
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+pmo_unregister_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc 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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->is_device_in_low_pwr_mode = NULL;
+	}
+
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_register_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc,
+					   pmo_get_vdev_dp_handle handler)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	if (!psoc) {
+		QDF_BUG(psoc);
+		pmo_err("psoc is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!handler) {
+		QDF_BUG(handler);
+		pmo_err("pmo_get_vdev_dp_handle is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->get_vdev_dp_handle = handler;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_unregister_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	if (!psoc) {
+		QDF_BUG(psoc);
+		pmo_err("psoc is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->get_vdev_dp_handle = NULL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_register_get_cfg_int_callback(struct wlan_objmgr_psoc *psoc,
+					     pmo_get_cfg_int 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_cfg_int 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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->get_cfg_int = handler;
+	}
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_unregister_get_cfg_int_callback(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc 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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->get_cfg_int = NULL;
+	}
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_register_get_dtim_period_callback(struct wlan_objmgr_psoc *psoc,
+						 pmo_get_dtim_period 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_dtim_period 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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->get_dtim_period = handler;
+	}
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+pmo_unregister_get_dtim_period_callback(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc 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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->get_dtim_period = NULL;
+	}
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+pmo_register_get_beacon_interval_callback(struct wlan_objmgr_psoc *psoc,
+					  pmo_get_beacon_interval 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_beacon_interval 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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->get_beacon_interval = handler;
+	}
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+pmo_unregister_get_beacon_interval_callback(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc 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;
+	}
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		psoc_ctx->get_beacon_interval = NULL;
+	}
+	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..50734d9
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_arp.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2017-2018 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");
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	if (vdev_ctx->vdev_arp_req.enable)
+		vdev_ctx->vdev_arp_req.is_offload_applied = true;
+	if (vdev_ctx->vdev_ns_req.enable)
+		vdev_ctx->vdev_ns_req.is_offload_applied = true;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+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");
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->vdev_arp_req.is_offload_applied = false;
+	vdev_ctx->vdev_ns_req.is_offload_applied = false;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+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..18132ea
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_gtk.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2017-2018 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:%pK",
+			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_debug("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:%pK",
+			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:%pK",
+			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_debug("callback:%pK context:%pK psoc:%pK 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 %pK",
+			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..396d307
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_hw_filter.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017-2018 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("Send %s hw filter mode 0x%X for vdev_id %u",
+		  req->enable ? "Enable" : "Disable", req->mode_bitmap,
+		  req->vdev_id);
+
+	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..f363e56
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_lphb.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2017-2018 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) {
+		psoc_ctx->wow.lphb_cb(psoc_ctx->wow.lphb_cb_ctx, rsp_param);
+	} else {
+		pmo_err("lphb rsp callback/context is null for psoc %pK",
+			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..8fd9809
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2017-2018 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;
+}
+
+bool pmo_tgt_get_multiple_mc_filter_support(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+	struct wlan_objmgr_psoc *psoc;
+
+	pmo_enter();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.get_multiple_mc_filter_support) {
+		pmo_err("get_multiple_mc_filter_support is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return pmo_tx_ops.get_multiple_mc_filter_support(psoc);
+}
+
+QDF_STATUS pmo_tgt_set_multiple_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_mc_addr_list *mc_list)
+{
+	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_multiple_mc_filter_req) {
+		pmo_err("send_set_multiple_mc_filter_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tx_ops.send_set_multiple_mc_filter_req(
+			vdev, mc_list);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to add/clear multiple mc filter");
+out:
+	pmo_exit();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_clear_multiple_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_mc_addr_list *mc_list)
+{
+	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_multiple_mc_filter_req) {
+		pmo_err("send_clear_multiple_mc_filter_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tx_ops.send_clear_multiple_mc_filter_req(
+			vdev, mc_list);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to add/clear multiple 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..6d7b9ca
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_ns.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2017-2018 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");
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	if (vdev_ctx->vdev_arp_req.enable)
+		vdev_ctx->vdev_arp_req.is_offload_applied = true;
+	if (vdev_ctx->vdev_ns_req.enable)
+		vdev_ctx->vdev_ns_req.is_offload_applied = true;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+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");
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->vdev_arp_req.is_offload_applied = false;
+	vdev_ctx->vdev_ns_req.is_offload_applied = false;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+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..0ae1146
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2017-2018 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 %pK", vdev);
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	pmo_debug("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 %pK", vdev);
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	pmo_debug("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..99d1b97
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2017-2018 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 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..c54a778
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2017-2018 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 pmo_psoc_priv_obj *psoc_ctx;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+
+	if (psoc_ctx->wow.wow_state == pmo_wow_state_legacy_d0) {
+		if (!pmo_tx_ops.psoc_send_d0wow_enable_req) {
+			pmo_err("psoc_send_d0wow_enable_req is null");
+			return QDF_STATUS_E_NULL_VALUE;
+		}
+		pmo_debug("Sending D0WOW enable command...");
+		return pmo_tx_ops.psoc_send_d0wow_enable_req(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 pmo_psoc_priv_obj *psoc_ctx;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+
+	if (psoc_ctx->psoc_cfg.d0_wow_supported &&
+	    psoc_ctx->wow.wow_state == pmo_wow_state_legacy_d0) {
+		if (!pmo_tx_ops.psoc_send_d0wow_disable_req) {
+			pmo_err("psoc_send_d0wow_disable_req is null");
+			return QDF_STATUS_E_NULL_VALUE;
+		}
+		pmo_debug("Sending D0WOW disable command...");
+		return pmo_tx_ops.psoc_send_d0wow_disable_req(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..d527be0
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2017-2018 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;
+	int vdev_id;
+
+	pmo_enter();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+	vdev_id = pmo_vdev_get_id(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;
+	}
+
+	pmo_debug("Enable wakeup events 0x%x%x%x%x for vdev_id %d",
+		  bitmap[3], bitmap[2], bitmap[1], bitmap[0], vdev_id);
+
+	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;
+	int vdev_id;
+
+	pmo_enter();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+	vdev_id = pmo_vdev_get_id(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;
+	}
+
+	pmo_debug("Disable wakeup events 0x%x%x%x%x for vdev_id %d",
+		  bitmap[3], bitmap[2], bitmap[1], bitmap[0], vdev_id);
+
+	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 send wow pattern event");
+		goto out;
+	}
+
+	if (user)
+		pmo_increment_wow_user_ptrn(vdev_ctx);
+out:
+	pmo_exit();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_del_wow_pattern(
+		struct wlan_objmgr_vdev *vdev, uint8_t ptrn_id,
+		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.del_wow_pattern) {
+		pmo_err("del_wow_pattern is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.del_wow_pattern(vdev, ptrn_id);
+	if (status) {
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	if (user)
+		pmo_decrement_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..daf1d2c
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c
@@ -0,0 +1,778 @@
+/*
+ * Copyright (c) 2017-2018 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_apf.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"
+#include "wlan_pmo_cfg.h"
+#include "cfg_ucfg_api.h"
+
+QDF_STATUS ucfg_pmo_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	return pmo_psoc_open(psoc);
+}
+
+QDF_STATUS ucfg_pmo_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	return pmo_psoc_close(psoc);
+}
+
+uint32_t ucfg_pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_BUG(psoc);
+	if (!psoc)
+		return 0;
+
+	return pmo_get_apf_instruction_size(psoc);
+}
+
+uint8_t ucfg_pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_BUG(psoc);
+	if (!psoc)
+		return 0;
+
+	return pmo_get_num_wow_filters(psoc);
+}
+
+QDF_STATUS ucfg_pmo_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 ucfg_pmo_update_psoc_config(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg)
+{
+	return pmo_core_update_psoc_config(psoc, psoc_cfg);
+}
+
+QDF_STATUS ucfg_pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc,
+				  struct pmo_device_caps *caps)
+{
+	QDF_BUG(psoc);
+	if (!psoc)
+		return QDF_STATUS_E_INVAL;
+
+	QDF_BUG(caps);
+	if (!caps)
+		return QDF_STATUS_E_INVAL;
+
+	pmo_psoc_set_caps(psoc, caps);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool ucfg_pmo_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
+	enum QDF_OPMODE vdev_opmode)
+{
+	return pmo_core_is_ap_mode_supports_arp_ns(psoc, vdev_opmode);
+}
+
+bool ucfg_pmo_is_vdev_connected(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_is_vdev_connected(vdev);
+}
+
+bool ucfg_pmo_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_is_vdev_supports_offload(vdev);
+}
+
+void ucfg_pmo_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+				  uint32_t vdev_id,
+				  WOW_WAKE_EVENT_TYPE wow_event)
+{
+	pmo_core_enable_wakeup_event(psoc, vdev_id, wow_event);
+}
+
+void ucfg_pmo_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+				   uint32_t vdev_id,
+				   WOW_WAKE_EVENT_TYPE wow_event)
+{
+	pmo_core_disable_wakeup_event(psoc, vdev_id, wow_event);
+}
+
+QDF_STATUS ucfg_pmo_cache_arp_offload_req(struct pmo_arp_req *arp_req)
+{
+	return pmo_core_cache_arp_offload_req(arp_req);
+}
+
+QDF_STATUS ucfg_pmo_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_flush_arp_offload_req(vdev);
+}
+
+QDF_STATUS ucfg_pmo_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
+ucfg_pmo_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
+ucfg_pmo_get_arp_offload_params(struct wlan_objmgr_vdev *vdev,
+				struct pmo_arp_offload_params *params)
+{
+	return pmo_core_get_arp_offload_params(vdev, params);
+}
+
+#ifdef WLAN_NS_OFFLOAD
+QDF_STATUS ucfg_pmo_cache_ns_offload_req(struct pmo_ns_req *ns_req)
+{
+	return pmo_core_cache_ns_offload_req(ns_req);
+}
+
+QDF_STATUS ucfg_pmo_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_flush_ns_offload_req(vdev);
+}
+
+QDF_STATUS
+ucfg_pmo_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
+ucfg_pmo_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);
+}
+#endif /* WLAN_NS_OFFLOAD */
+
+QDF_STATUS
+ucfg_pmo_get_ns_offload_params(struct wlan_objmgr_vdev *vdev,
+			       struct pmo_ns_offload_params *params)
+{
+	return pmo_core_get_ns_offload_params(vdev, params);
+}
+
+enum pmo_ns_addr_scope
+ucfg_pmo_ns_addr_scope(uint32_t ipv6_scope)
+{
+	switch (ipv6_scope) {
+	case IPV6_ADDR_SCOPE_NODELOCAL:
+		return PMO_NS_ADDR_SCOPE_NODELOCAL;
+	case IPV6_ADDR_SCOPE_LINKLOCAL:
+		return PMO_NS_ADDR_SCOPE_LINKLOCAL;
+	case IPV6_ADDR_SCOPE_SITELOCAL:
+		return PMO_NS_ADDR_SCOPE_SITELOCAL;
+	case IPV6_ADDR_SCOPE_ORGLOCAL:
+		return PMO_NS_ADDR_SCOPE_ORGLOCAL;
+	case IPV6_ADDR_SCOPE_GLOBAL:
+		return PMO_NS_ADDR_SCOPE_GLOBAL;
+	}
+
+	return PMO_NS_ADDR_SCOPE_INVALID;
+}
+
+QDF_STATUS ucfg_pmo_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 ucfg_pmo_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 ucfg_pmo_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 ucfg_pmo_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 ucfg_pmo_max_mc_addr_supported(struct wlan_objmgr_psoc *psoc)
+{
+	return pmo_core_max_mc_addr_supported(psoc);
+}
+
+QDF_STATUS
+ucfg_pmo_get_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+			  uint8_t vdev_id,
+			  struct pmo_mc_addr_list *mc_list_req)
+{
+	return pmo_core_get_mc_addr_list(psoc, vdev_id, mc_list_req);
+}
+
+QDF_STATUS
+ucfg_pmo_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 ucfg_pmo_flush_gtk_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_flush_gtk_offload_req(vdev);
+}
+
+QDF_STATUS ucfg_pmo_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_enable_gtk_offload_in_fwr(vdev);
+}
+
+QDF_STATUS ucfg_pmo_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_disable_gtk_offload_in_fwr(vdev);
+}
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+uint8_t ucfg_pmo_get_pkt_filter_bitmap(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.packet_filters_bitmap;
+}
+
+uint32_t ucfg_pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_BUG(psoc);
+	if (!psoc)
+		return 0;
+
+	return pmo_get_num_packet_filters(psoc);
+}
+
+QDF_STATUS
+ucfg_pmo_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 ucfg_pmo_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);
+}
+#endif
+
+QDF_STATUS ucfg_pmo_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 ucfg_pmo_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
+					 bool value)
+{
+	pmo_core_update_extscan_in_progress(vdev, value);
+}
+
+void ucfg_pmo_update_p2plo_in_progress(struct wlan_objmgr_vdev *vdev,
+				       bool value)
+{
+	pmo_core_update_p2plo_in_progress(vdev, value);
+}
+
+QDF_STATUS ucfg_pmo_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 ucfg_pmo_psoc_update_power_save_mode(struct wlan_objmgr_psoc *psoc,
+					  uint8_t value)
+{
+	pmo_core_psoc_update_power_save_mode(psoc, value);
+}
+
+void ucfg_pmo_psoc_update_dp_handle(struct wlan_objmgr_psoc *psoc,
+				    void *dp_handle)
+{
+	pmo_core_psoc_update_dp_handle(psoc, dp_handle);
+}
+
+void ucfg_pmo_psoc_update_htc_handle(struct wlan_objmgr_psoc *psoc,
+				     void *htc_handle)
+{
+	pmo_core_psoc_update_htc_handle(psoc, htc_handle);
+}
+
+void ucfg_pmo_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+				  void *hif_handle)
+{
+	pmo_core_psoc_set_hif_handle(psoc, hif_handle);
+}
+
+void ucfg_pmo_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				   void *txrx_handle)
+{
+	pmo_core_psoc_set_txrx_handle(psoc, txrx_handle);
+}
+
+void ucfg_pmo_psoc_handle_initial_wake_up(void *cb_ctx)
+{
+	return pmo_core_psoc_handle_initial_wake_up(cb_ctx);
+}
+
+QDF_STATUS
+ucfg_pmo_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
+ucfg_pmo_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
+ucfg_pmo_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 ucfg_pmo_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 ucfg_pmo_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
+ucfg_pmo_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
+			     int disable_target_intr)
+{
+	return pmo_core_psoc_suspend_target(psoc, disable_target_intr);
+}
+
+QDF_STATUS
+ucfg_pmo_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
+			      struct pmo_wow_add_pattern *ptrn)
+{
+	return pmo_core_add_wow_user_pattern(vdev, ptrn);
+}
+
+QDF_STATUS
+ucfg_pmo_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
+			      uint8_t pattern_id)
+{
+	return pmo_core_del_wow_user_pattern(vdev, pattern_id);
+}
+
+QDF_STATUS
+ucfg_pmo_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
+			     enum qdf_suspend_type type)
+{
+	return pmo_core_psoc_bus_resume_req(psoc, type);
+}
+
+bool ucfg_pmo_get_wow_bus_suspend(struct wlan_objmgr_psoc *psoc)
+{
+	return pmo_core_get_wow_bus_suspend(psoc);
+}
+
+int ucfg_pmo_psoc_is_target_wake_up_received(struct wlan_objmgr_psoc *psoc)
+{
+	return pmo_core_psoc_is_target_wake_up_received(psoc);
+}
+
+int ucfg_pmo_psoc_clear_target_wake_up(struct wlan_objmgr_psoc *psoc)
+{
+	return pmo_core_psoc_clear_target_wake_up(psoc);
+}
+
+void ucfg_pmo_psoc_target_suspend_acknowledge(void *context, bool wow_nack)
+{
+	pmo_core_psoc_target_suspend_acknowledge(context, wow_nack);
+}
+
+void ucfg_pmo_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc)
+{
+	pmo_core_psoc_wakeup_host_event_received(psoc);
+}
+
+QDF_STATUS ucfg_pmo_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_enable_hw_filter_in_fwr(vdev);
+}
+
+QDF_STATUS ucfg_pmo_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_disable_hw_filter_in_fwr(vdev);
+}
+
+QDF_STATUS ucfg_pmo_config_listen_interval(struct wlan_objmgr_vdev *vdev,
+					   uint32_t listen_interval)
+{
+	return pmo_core_config_listen_interval(vdev, listen_interval);
+}
+
+QDF_STATUS ucfg_pmo_config_modulated_dtim(struct wlan_objmgr_vdev *vdev,
+					  uint32_t mod_dtim)
+{
+	return pmo_core_config_modulated_dtim(vdev, mod_dtim);
+}
+
+enum pmo_wow_enable_type
+ucfg_pmo_get_wow_enable(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.wow_enable;
+}
+
+void
+ucfg_pmo_set_wow_enable(struct wlan_objmgr_psoc *psoc,
+			enum pmo_wow_enable_type val)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	pmo_psoc_ctx->psoc_cfg.wow_enable = val;
+}
+
+bool
+ucfg_pmo_is_wowlan_deauth_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.wowlan_deauth_enable;
+}
+
+bool
+ucfg_pmo_is_wowlan_disassoc_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.wowlan_disassoc_enable;
+}
+
+bool
+ucfg_pmo_is_arp_offload_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.arp_offload_enable;
+}
+
+void
+ucfg_pmo_set_arp_offload_enabled(struct wlan_objmgr_psoc *psoc,
+				 bool val)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	pmo_psoc_ctx->psoc_cfg.arp_offload_enable = val;
+}
+
+enum pmo_auto_pwr_detect_failure_mode
+ucfg_pmo_get_auto_power_fail_mode(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.auto_power_save_fail_mode;
+}
+
+#ifdef WLAN_FEATURE_WOW_PULSE
+bool ucfg_pmo_is_wow_pulse_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.is_wow_pulse_supported;
+}
+
+uint8_t ucfg_pmo_get_wow_pulse_pin(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.wow_pulse_pin;
+}
+
+uint16_t ucfg_pmo_get_wow_pulse_interval_high(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.wow_pulse_interval_high;
+}
+
+uint16_t ucfg_pmo_get_wow_pulse_interval_low(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.wow_pulse_interval_low;
+}
+#endif
+
+bool ucfg_pmo_is_active_mode_offloaded(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.active_mode_offload;
+}
+
+#ifdef FEATURE_WLAN_APF
+bool ucfg_pmo_is_apf_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_intersect_apf(pmo_psoc_ctx);
+}
+#endif
+
+bool
+ucfg_pmo_is_ssdp_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.ssdp;
+}
+
+#ifdef FEATURE_RUNTIME_PM
+uint32_t
+ucfg_pmo_get_runtime_pm_delay(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.runtime_pm_delay;
+}
+#endif /* FEATURE_RUNTIME_PM */
+
+bool
+ucfg_pmo_is_ns_offloaded(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.ns_offload_enable_static;
+}
+
+uint8_t
+ucfg_pmo_get_sta_dynamic_dtim(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.sta_dynamic_dtim;
+}
+
+uint8_t
+ucfg_pmo_get_sta_mod_dtim(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.sta_dynamic_dtim;
+}
+
+void
+ucfg_pmo_set_sta_mod_dtim(struct wlan_objmgr_psoc *psoc,
+			  uint8_t val)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	pmo_psoc_ctx->psoc_cfg.sta_dynamic_dtim = val;
+}
+
+bool
+ucfg_pmo_is_mc_addr_list_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.enable_mc_list;
+}
+
+enum powersave_mode
+ucfg_pmo_get_power_save_mode(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.power_save_mode;
+}
+
+void
+ucfg_pmo_set_power_save_mode(struct wlan_objmgr_psoc *psoc,
+			     enum powersave_mode val)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	pmo_psoc_ctx->psoc_cfg.power_save_mode = val;
+}
+
+uint8_t
+ucfg_pmo_get_max_ps_poll(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.max_ps_poll;
+}
+
+uint8_t
+ucfg_pmo_power_save_offload_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t powersave_offload_enabled;
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	if (!pmo_psoc_ctx->psoc_cfg.max_ps_poll ||
+	    !pmo_psoc_ctx->psoc_cfg.power_save_mode)
+		powersave_offload_enabled =
+			pmo_psoc_ctx->psoc_cfg.power_save_mode;
+	else if ((pmo_psoc_ctx->psoc_cfg.power_save_mode ==
+		  PS_QPOWER_NODEEPSLEEP) ||
+		 (pmo_psoc_ctx->psoc_cfg.power_save_mode ==
+		  PS_LEGACY_NODEEPSLEEP))
+		powersave_offload_enabled = PS_LEGACY_NODEEPSLEEP;
+	else
+		powersave_offload_enabled = PS_LEGACY_DEEPSLEEP;
+
+	pmo_debug("powersave offload enabled type:%d",
+		  powersave_offload_enabled);
+
+	return powersave_offload_enabled;
+}
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+bool
+ucfg_pmo_extwow_is_goto_suspend_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.extwow_goto_suspend;
+}
+
+uint8_t
+ucfg_pmo_extwow_app1_wakeup_pin_num(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.extwow_app1_wakeup_pin_num;
+}
+
+uint8_t
+ucfg_pmo_extwow_app2_wakeup_pin_num(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.extwow_app2_wakeup_pin_num;
+}
+
+uint32_t
+ucfg_pmo_extwow_app2_init_ping_interval(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.extwow_app2_init_ping_interval;
+}
+
+uint32_t
+ucfg_pmo_extwow_app2_min_ping_interval(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.extwow_app2_min_ping_interval;
+}
+
+uint32_t
+ucfg_pmo_extwow_app2_max_ping_interval(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.extwow_app2_max_ping_interval;
+}
+
+uint32_t
+ucfg_pmo_extwow_app2_inc_ping_interval(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.extwow_app2_inc_ping_interval;
+}
+
+uint16_t
+ucfg_pmo_extwow_app2_tcp_src_port(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.extwow_app2_tcp_src_port;
+}
+
+uint16_t
+ucfg_pmo_extwow_app2_tcp_dst_port(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.extwow_app2_tcp_dst_port;
+}
+
+uint32_t
+ucfg_pmo_extwow_app2_tcp_tx_timeout(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.extwow_app2_tcp_tx_timeout;
+}
+
+uint32_t
+ucfg_pmo_extwow_app2_tcp_rx_timeout(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	return pmo_psoc_ctx->psoc_cfg.extwow_app2_tcp_rx_timeout;
+}
+#endif
diff --git a/components/target_if/action_oui/inc/target_if_action_oui.h b/components/target_if/action_oui/inc/target_if_action_oui.h
new file mode 100644
index 0000000..4bd65b7
--- /dev/null
+++ b/components/target_if/action_oui/inc/target_if_action_oui.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018 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 action_oui component for wmi command path.
+ */
+
+#ifndef _TARGET_IF_ACTION_OUI_H_
+#define _TARGET_IF_ACTION_OUI_H_
+
+#include "target_if.h"
+#include <wmi_unified_api.h>
+#include <wmi_unified_priv.h>
+#include <wmi_unified_param.h>
+#include "wlan_action_oui_tgt_api.h"
+#include "wlan_action_oui_public_struct.h"
+
+/**
+ * target_if_action_oui_register_tx_ops() - Register action_oui component TX OPS
+ * @tx_ops: action_oui transmit ops
+ *
+ * Return: None
+ */
+void
+target_if_action_oui_register_tx_ops(struct action_oui_tx_ops *tx_ops);
+
+#endif /* _TARGET_IF_ACTION_OUI_H_ */
diff --git a/components/target_if/action_oui/src/target_if_action_oui.c b/components/target_if/action_oui/src/target_if_action_oui.c
new file mode 100644
index 0000000..4893b63
--- /dev/null
+++ b/components/target_if/action_oui/src/target_if_action_oui.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013-2018 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 action_oui component to
+ * Implement api's which shall be used by action_oui component
+ * in target_if internally.
+ */
+
+#include "target_if_action_oui.h"
+#include "wlan_action_oui_tgt_api.h"
+#include "wlan_action_oui_public_struct.h"
+
+static QDF_STATUS
+target_if_action_oui_send_req(struct wlan_objmgr_psoc *psoc,
+			      struct action_oui_request *req)
+{
+	void *wmi_hdl;
+
+	wmi_hdl = GET_WMI_HDL_FROM_PSOC(psoc);
+	if (!wmi_hdl)
+		return QDF_STATUS_E_FAILURE;
+
+	return wmi_unified_send_action_oui_cmd(wmi_hdl, req);
+}
+
+void
+target_if_action_oui_register_tx_ops(struct action_oui_tx_ops *tx_ops)
+{
+	if (!tx_ops) {
+		target_if_err("action_oui tx_ops is null");
+		return;
+	}
+
+	tx_ops->send_req = target_if_action_oui_send_req;
+}
diff --git a/components/target_if/disa/inc/target_if_disa.h b/components/target_if/disa/inc/target_if_disa.h
new file mode 100644
index 0000000..c501b6c
--- /dev/null
+++ b/components/target_if/disa/inc/target_if_disa.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 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 disa component for wmi cmd (tx path) and
+ * event (rx) handling.
+ */
+
+#ifndef _TARGET_IF_DISA_H_
+#define _TARGET_IF_DISA_H_
+
+#include <wlan_objmgr_psoc_obj.h>
+#include <wmi_unified_param.h>
+#include "wlan_disa_obj_mgmt_public_struct.h"
+
+/**
+ * target_if_disa_encrypt_decrypt_req() - Send encrypt/decrypt request to
+ * target.
+ * @psoc: objmgr psoc handle
+ * @req: Encrypt/decrypt request params
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_disa_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+				struct disa_encrypt_decrypt_req_params *req);
+
+/**
+ * target_if_encrypt_decrypt_event_handler() - Collect encrypt/decrypt request
+ * event from the target and pass on the data to tgt api of DISA.
+ * @scn_handle: target handle
+ * @data: event data
+ * @data_len: data length
+ *
+ * Return: QDF status
+ */
+int target_if_encrypt_decrypt_event_handler(ol_scn_t scn_handle, uint8_t *data,
+			uint32_t data_len);
+
+/**
+ * target_if_disa_register_tx_ops() - Register DISA component TX OPS
+ * @tx_ops: DISA if transmit ops
+ *
+ * Return: None
+ */
+void target_if_disa_register_tx_ops(struct wlan_disa_tx_ops *tx_ops);
+
+/**
+ * target_if_disa_register_ev_handler() -  Register disa event handlers.
+ * @psoc:objmgr psoc handle
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+target_if_disa_register_ev_handlers(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_disa_register_ev_handler() -  Unregister disa event handlers.
+ * @psoc:objmgr psoc handle
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+target_if_disa_unregister_ev_handlers(struct wlan_objmgr_psoc *psoc);
+#endif
+
diff --git a/components/target_if/disa/src/target_if_disa.c b/components/target_if/disa/src/target_if_disa.c
new file mode 100644
index 0000000..055497d
--- /dev/null
+++ b/components/target_if/disa/src/target_if_disa.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2018 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 disa component to
+ * Implement api's which shall be used by disa component
+ * in target if internally.
+ */
+
+#include "target_if.h"
+#include "target_if_disa.h"
+#include "wlan_disa_tgt_api.h"
+#include "wlan_disa_public_struct.h"
+#include <wmi_unified_api.h>
+
+int
+target_if_encrypt_decrypt_event_handler(ol_scn_t scn_handle, uint8_t *data,
+					uint32_t data_len)
+{
+	struct disa_encrypt_decrypt_resp_params resp;
+	struct wlan_objmgr_psoc *psoc;
+	wmi_unified_t wmi_handle;
+
+	if (data == NULL) {
+		target_if_err("%s: invalid pointer", __func__);
+		return -EINVAL;
+	}
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
+	if (!psoc) {
+		target_if_err("psoc ptr is NULL");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return -EINVAL;
+	}
+
+	if (wmi_extract_encrypt_decrypt_resp_params(wmi_handle, data, &resp) !=
+						    QDF_STATUS_SUCCESS) {
+		target_if_err("Extraction of encrypt decrypt resp params failed");
+		return -EINVAL;
+	}
+
+	tgt_disa_encrypt_decrypt_resp(psoc, &resp);
+
+	return 0;
+}
+
+QDF_STATUS
+target_if_disa_register_ev_handlers(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_register_event(wmi_handle,
+				wmi_vdev_encrypt_decrypt_data_rsp_event_id,
+				target_if_encrypt_decrypt_event_handler);
+	if (status) {
+		target_if_err("Failed to register Scan match event cb");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+QDF_STATUS
+target_if_disa_unregister_ev_handlers(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_unregister_event(wmi_handle,
+				wmi_vdev_encrypt_decrypt_data_rsp_event_id);
+	if (status) {
+		target_if_err("Failed to unregister Scan match event cb");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+QDF_STATUS
+target_if_disa_encrypt_decrypt_req(struct wlan_objmgr_psoc *psoc,
+		struct disa_encrypt_decrypt_req_params *req)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wmi_unified_encrypt_decrypt_send_cmd(wmi_handle, req);
+}
+
+
+void target_if_disa_register_tx_ops(struct wlan_disa_tx_ops *disa_tx_ops)
+{
+	if (!disa_tx_ops) {
+		target_if_err("disa_tx_ops is null");
+		return;
+	}
+
+	disa_tx_ops->disa_encrypt_decrypt_req =
+		target_if_disa_encrypt_decrypt_req;
+	disa_tx_ops->disa_register_ev_handlers =
+		target_if_disa_register_ev_handlers;
+	disa_tx_ops->disa_unregister_ev_handlers =
+		target_if_disa_unregister_ev_handlers;
+}
diff --git a/components/target_if/ipa/inc/target_if_ipa.h b/components/target_if/ipa/inc/target_if_ipa.h
new file mode 100644
index 0000000..3055bf0
--- /dev/null
+++ b/components/target_if/ipa/inc/target_if_ipa.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 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 ipa component for wmi cmd (tx path)
+ */
+
+#ifndef _TARGET_IF_IPA_H_
+#define _TARGET_IF_IPA_H_
+
+#ifdef IPA_OFFLOAD
+
+#include "wlan_ipa_public_struct.h"
+
+/**
+ * target_if_ipa_register_tx_ops() - Register IPA component TX OPS
+ * @ipa_tx_op: IPA if transmit op
+ *
+ * Return: None
+ */
+void target_if_ipa_register_tx_ops(ipa_uc_offload_control_req *ipa_tx_op);
+
+#endif /* IPA_OFFLOAD */
+#endif /* _TARGET_IF_IPA_H_ */
+
diff --git a/components/target_if/ipa/src/target_if_ipa.c b/components/target_if/ipa/src/target_if_ipa.c
new file mode 100644
index 0000000..bde9808
--- /dev/null
+++ b/components/target_if/ipa/src/target_if_ipa.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 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 disa component to
+ * Implement api's which shall be used by ipa component
+ * in target if internally.
+ */
+
+#include <target_if.h>
+#include <qdf_status.h>
+#include <wmi_unified_api.h>
+#include <wmi_unified_priv.h>
+#include <wmi_unified_param.h>
+#include <target_if_ipa.h>
+#include <wlan_objmgr_psoc_obj.h>
+
+/**
+ * target_if_ipa_uc_offload_control_req() - send IPA offload control to FW
+ * @psoc: pointer to PSOC object
+ * @req: IPA UC offload enable/disable control param
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_ipa_uc_offload_control_req(struct wlan_objmgr_psoc *psoc,
+			struct ipa_uc_offload_control_params *req)
+{
+	return wmi_unified_ipa_offload_control_cmd(
+			get_wmi_unified_hdl_from_psoc(psoc), req);
+}
+
+void target_if_ipa_register_tx_ops(ipa_uc_offload_control_req *ipa_tx_op)
+{
+	*ipa_tx_op = target_if_ipa_uc_offload_control_req;
+}
diff --git a/components/target_if/nan/inc/target_if_nan.h b/components/target_if/nan/inc/target_if_nan.h
new file mode 100644
index 0000000..45109e3
--- /dev/null
+++ b/components/target_if/nan/inc/target_if_nan.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: contains nan target if declarations
+ */
+
+#ifndef _WLAN_NAN_TGT_IF_H_
+#define _WLAN_NAN_TGT_IF_H_
+
+#include "qdf_types.h"
+
+#include <qdf_mem.h>
+#include <qdf_status.h>
+#include <wmi_unified_api.h>
+#include <wmi_unified_priv.h>
+#include <wmi_unified_param.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_scan_tgt_api.h>
+#include <target_if.h>
+#include <target_if_scan.h>
+
+struct wlan_objmgr_psoc;
+struct wlan_lmac_if_rx_ops;
+struct wlan_lmac_if_tx_ops;
+struct wlan_lmac_if_nan_rx_ops;
+
+/**
+ * target_if_nan_get_tx_ops() - retrieve the nan tx_ops
+ * @psoc: psoc context
+ *
+ * API to retrieve the nan tx_ops from the psoc context
+ *
+ * Return: nan tx_ops pointer
+ */
+struct wlan_lmac_if_nan_tx_ops *target_if_nan_get_tx_ops(
+						struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_nan_get_rx_ops() - retrieve the nan rx_ops
+ * @psoc: psoc context
+ *
+ * API to retrieve the nan rx_ops from the psoc context
+ *
+ * Return: nan rx_ops pointer
+ */
+struct wlan_lmac_if_nan_rx_ops *target_if_nan_get_rx_ops(
+						struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_nan_register_tx_ops() - registers nan tx ops
+ * @tx_ops: tx ops
+ *
+ * Return: none
+ */
+void target_if_nan_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops);
+
+/**
+ * target_if_nan_register_rx_ops() - registers nan rx ops
+ * @tx_ops: rx ops
+ *
+ * Return: none
+ */
+void target_if_nan_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops);
+
+/**
+ * target_if_nan_register_events() - registers with NDP events
+ * @psoc: pointer to psoc object
+ *
+ * Return: status of operation
+ */
+QDF_STATUS target_if_nan_register_events(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_nan_deregister_events() - registers nan rx ops
+ * @psoc: pointer to psoc object
+ *
+ * Return: status of operation
+ */
+QDF_STATUS target_if_nan_deregister_events(struct wlan_objmgr_psoc *psoc);
+
+#endif /* _WIFI_POS_TGT_IF_H_ */
diff --git a/components/target_if/nan/src/target_if_nan.c b/components/target_if/nan/src/target_if_nan.c
new file mode 100644
index 0000000..abb5eec
--- /dev/null
+++ b/components/target_if/nan/src/target_if_nan.c
@@ -0,0 +1,834 @@
+/*
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: contains nan target if functions
+ */
+
+#include "../../../umac/nan/core/src/nan_main_i.h"
+#include "nan_public_structs.h"
+#include "nan_ucfg_api.h"
+#include "target_if_nan.h"
+#include "wmi_unified_api.h"
+#include "scheduler_api.h"
+
+static QDF_STATUS target_if_nan_event_flush_cb(struct scheduler_msg *msg)
+{
+	void *ptr = msg->bodyptr;
+	struct wlan_objmgr_vdev *vdev = NULL;
+
+	switch (msg->type) {
+	case NDP_INITIATOR_RSP:
+		vdev = ((struct nan_datapath_initiator_rsp *)ptr)->vdev;
+		break;
+	case NDP_INDICATION:
+		vdev = ((struct nan_datapath_indication_event *)ptr)->vdev;
+		break;
+	case NDP_CONFIRM:
+		vdev = ((struct nan_datapath_confirm_event *)ptr)->vdev;
+		break;
+	case NDP_RESPONDER_RSP:
+		vdev = ((struct nan_datapath_responder_rsp *)ptr)->vdev;
+		break;
+	case NDP_END_RSP:
+		vdev = ((struct nan_datapath_end_rsp_event *)ptr)->vdev;
+		break;
+	case NDP_END_IND:
+		vdev = ((struct nan_datapath_end_indication_event *)ptr)->vdev;
+		break;
+	case NDP_SCHEDULE_UPDATE:
+		vdev = ((struct nan_datapath_sch_update_event *)ptr)->vdev;
+		break;
+	default:
+		break;
+	}
+
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
+	qdf_mem_free(msg->bodyptr);
+	msg->bodyptr = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS target_if_nan_event_dispatcher(struct scheduler_msg *msg)
+{
+	QDF_STATUS status;
+	void *ptr = msg->bodyptr;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_vdev *vdev = NULL;
+	struct wlan_lmac_if_nan_rx_ops *nan_rx_ops;
+
+	switch (msg->type) {
+	case NDP_INITIATOR_RSP:
+		vdev = ((struct nan_datapath_initiator_rsp *)ptr)->vdev;
+		break;
+	case NDP_INDICATION:
+		vdev = ((struct nan_datapath_indication_event *)ptr)->vdev;
+		break;
+	case NDP_CONFIRM:
+		vdev = ((struct nan_datapath_confirm_event *)ptr)->vdev;
+		break;
+	case NDP_RESPONDER_RSP:
+		vdev = ((struct nan_datapath_responder_rsp *)ptr)->vdev;
+		break;
+	case NDP_END_RSP:
+		vdev = ((struct nan_datapath_end_rsp_event *)ptr)->vdev;
+		break;
+	case NDP_END_IND:
+		vdev = ((struct nan_datapath_end_indication_event *)ptr)->vdev;
+		break;
+	case NDP_SCHEDULE_UPDATE:
+		vdev = ((struct nan_datapath_sch_update_event *)ptr)->vdev;
+		break;
+	default:
+		target_if_err("invalid msg type %d", msg->type);
+		status = QDF_STATUS_E_INVAL;
+		goto free_res;
+	}
+
+	if (!vdev) {
+		target_if_err("vdev is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto free_res;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto free_res;
+	}
+
+	nan_rx_ops = target_if_nan_get_rx_ops(psoc);
+	if (!nan_rx_ops) {
+		target_if_err("nan_rx_ops is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto free_res;
+	}
+
+	status = nan_rx_ops->nan_event_rx(msg);
+free_res:
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
+	qdf_mem_free(msg->bodyptr);
+	msg->bodyptr = NULL;
+	return status;
+}
+
+static QDF_STATUS target_if_nan_ndp_initiator_req(
+			struct nan_datapath_initiator_req *ndp_req)
+{
+	QDF_STATUS status;
+	struct wmi_unified *wmi_handle;
+	struct wlan_objmgr_psoc *psoc;
+	struct scheduler_msg pe_msg = {0};
+	struct wlan_lmac_if_nan_rx_ops *nan_rx_ops;
+	struct nan_datapath_initiator_rsp ndp_rsp = {0};
+
+	if (!ndp_req) {
+		target_if_err("ndp_req is null.");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(ndp_req->vdev);
+	if (!psoc) {
+		target_if_err("psoc is null.");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null.");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	nan_rx_ops = target_if_nan_get_rx_ops(psoc);
+	if (!nan_rx_ops) {
+		target_if_err("nan_rx_ops is null.");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_ndp_initiator_req_cmd_send(wmi_handle, ndp_req);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	ndp_rsp.vdev = ndp_req->vdev;
+	ndp_rsp.transaction_id = ndp_req->transaction_id;
+	ndp_rsp.ndp_instance_id = ndp_req->service_instance_id;
+	ndp_rsp.status = NAN_DATAPATH_DATA_INITIATOR_REQ_FAILED;
+	pe_msg.type = NDP_INITIATOR_RSP;
+	pe_msg.bodyptr = &ndp_rsp;
+	if (nan_rx_ops->nan_event_rx)
+		nan_rx_ops->nan_event_rx(&pe_msg);
+
+	return status;
+}
+
+static int target_if_ndp_initiator_rsp_handler(ol_scn_t scn, uint8_t *data,
+						uint32_t len)
+{
+	QDF_STATUS status;
+	struct wmi_unified *wmi_handle;
+	struct wlan_objmgr_psoc *psoc;
+	struct scheduler_msg msg = {0};
+	struct nan_datapath_initiator_rsp *rsp;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null");
+		return -EINVAL;
+	}
+
+	rsp = qdf_mem_malloc(sizeof(*rsp));
+	if (!rsp) {
+		target_if_err("malloc failed");
+		return -ENOMEM;
+	}
+
+	status = wmi_extract_ndp_initiator_rsp(wmi_handle, data, rsp);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("parsing of event failed, %d", status);
+		qdf_mem_free(rsp);
+		return -EINVAL;
+	}
+
+	msg.bodyptr = rsp;
+	msg.type = NDP_INITIATOR_RSP;
+	msg.callback = target_if_nan_event_dispatcher;
+	msg.flush_callback = target_if_nan_event_flush_cb;
+	target_if_debug("NDP_INITIATOR_RSP sent: %d", msg.type);
+	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("failed to post msg, status: %d", status);
+		target_if_nan_event_flush_cb(&msg);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int target_if_ndp_ind_handler(ol_scn_t scn, uint8_t *data,
+				     uint32_t data_len)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wmi_unified *wmi_handle;
+	struct scheduler_msg msg = {0};
+	struct nan_datapath_indication_event *rsp;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null");
+		return -EINVAL;
+	}
+
+	rsp = qdf_mem_malloc(sizeof(*rsp));
+	if (!rsp) {
+		target_if_err("malloc failed");
+		return -ENOMEM;
+	}
+
+	status = wmi_extract_ndp_ind(wmi_handle, data, rsp);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("parsing of event failed, %d", status);
+		qdf_mem_free(rsp);
+		return -EINVAL;
+	}
+
+	msg.bodyptr = rsp;
+	msg.type = NDP_INDICATION;
+	msg.callback = target_if_nan_event_dispatcher;
+	msg.flush_callback = target_if_nan_event_flush_cb;
+	target_if_debug("NDP_INDICATION sent: %d", msg.type);
+	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("failed to post msg, status: %d", status);
+		target_if_nan_event_flush_cb(&msg);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int target_if_ndp_confirm_handler(ol_scn_t scn, uint8_t *data,
+					uint32_t data_len)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wmi_unified *wmi_handle;
+	struct scheduler_msg msg = {0};
+	struct nan_datapath_confirm_event *rsp;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null");
+		return -EINVAL;
+	}
+
+	rsp = qdf_mem_malloc(sizeof(*rsp));
+	if (!rsp) {
+		target_if_err("malloc failed");
+		return -ENOMEM;
+	}
+
+	status = wmi_extract_ndp_confirm(wmi_handle, data, rsp);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("parsing of event failed, %d", status);
+		qdf_mem_free(rsp);
+		return -EINVAL;
+	}
+
+	msg.bodyptr = rsp;
+	msg.type = NDP_CONFIRM;
+	msg.callback = target_if_nan_event_dispatcher;
+	msg.flush_callback = target_if_nan_event_flush_cb;
+	target_if_debug("NDP_CONFIRM sent: %d", msg.type);
+	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("failed to post msg, status: %d", status);
+		target_if_nan_event_flush_cb(&msg);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static QDF_STATUS target_if_nan_ndp_responder_req(
+				struct nan_datapath_responder_req *req)
+{
+	QDF_STATUS status;
+	struct wmi_unified *wmi_handle;
+	struct wlan_objmgr_psoc *psoc;
+	struct scheduler_msg pe_msg = {0};
+	struct wlan_lmac_if_nan_rx_ops *nan_rx_ops;
+	struct nan_datapath_responder_rsp rsp = {0};
+
+	if (!req) {
+		target_if_err("Invalid req.");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(req->vdev);
+	if (!psoc) {
+		target_if_err("psoc is null.");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null.");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	nan_rx_ops = target_if_nan_get_rx_ops(psoc);
+	if (!nan_rx_ops) {
+		target_if_err("nan_rx_ops is null.");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	status = wmi_unified_ndp_responder_req_cmd_send(wmi_handle, req);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	rsp.vdev = req->vdev;
+	rsp.transaction_id = req->transaction_id;
+	rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
+	rsp.reason = NAN_DATAPATH_DATA_RESPONDER_REQ_FAILED;
+	pe_msg.bodyptr = &rsp;
+	pe_msg.type = NDP_RESPONDER_RSP;
+	if (nan_rx_ops->nan_event_rx)
+		nan_rx_ops->nan_event_rx(&pe_msg);
+
+	return status;
+}
+
+static int target_if_ndp_responder_rsp_handler(ol_scn_t scn, uint8_t *data,
+						uint32_t len)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wmi_unified *wmi_handle;
+	struct scheduler_msg msg = {0};
+	struct nan_datapath_responder_rsp *rsp;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null.");
+		return -EINVAL;
+	}
+
+	rsp = qdf_mem_malloc(sizeof(*rsp));
+	if (!rsp) {
+		target_if_err("malloc failed");
+		return -ENOMEM;
+	}
+
+	status = wmi_extract_ndp_responder_rsp(wmi_handle, data, rsp);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("parsing of event failed, %d", status);
+		qdf_mem_free(rsp);
+		return -EINVAL;
+	}
+
+	msg.bodyptr = rsp;
+	msg.type = NDP_RESPONDER_RSP;
+	msg.callback = target_if_nan_event_dispatcher;
+	msg.flush_callback = target_if_nan_event_flush_cb;
+	target_if_debug("NDP_INITIATOR_RSP sent: %d", msg.type);
+	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("failed to post msg, status: %d", status);
+		target_if_nan_event_flush_cb(&msg);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static QDF_STATUS target_if_nan_ndp_end_req(struct nan_datapath_end_req *req)
+{
+	QDF_STATUS status;
+	struct wmi_unified *wmi_handle;
+	struct wlan_objmgr_psoc *psoc;
+	struct scheduler_msg msg = {0};
+	struct wlan_lmac_if_nan_rx_ops *nan_rx_ops;
+	struct nan_datapath_end_rsp_event end_rsp = {0};
+
+	if (!req) {
+		target_if_err("req is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(req->vdev);
+	if (!psoc) {
+		target_if_err("psoc is null.");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null.");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	nan_rx_ops = target_if_nan_get_rx_ops(psoc);
+	if (!nan_rx_ops) {
+		target_if_err("nan_rx_ops is null.");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	status = wmi_unified_ndp_end_req_cmd_send(wmi_handle, req);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	end_rsp.vdev = req->vdev;
+	msg.type = NDP_END_RSP;
+	end_rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
+	end_rsp.reason = NAN_DATAPATH_END_FAILED;
+	end_rsp.transaction_id = req->transaction_id;
+	msg.bodyptr = &end_rsp;
+
+	if (nan_rx_ops->nan_event_rx)
+		nan_rx_ops->nan_event_rx(&msg);
+
+	return status;
+}
+
+static int target_if_ndp_end_rsp_handler(ol_scn_t scn, uint8_t *data,
+					 uint32_t data_len)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wmi_unified *wmi_handle;
+	struct scheduler_msg msg = {0};
+	struct nan_datapath_end_rsp_event *end_rsp;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null.");
+		return -EINVAL;
+	}
+
+	end_rsp = qdf_mem_malloc(sizeof(*end_rsp));
+	if (!end_rsp) {
+		target_if_err("malloc failed");
+		return -ENOMEM;
+	}
+
+	status = wmi_extract_ndp_end_rsp(wmi_handle, data, end_rsp);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("parsing of event failed, %d", status);
+		qdf_mem_free(end_rsp);
+		return -EINVAL;
+	}
+
+	msg.bodyptr = end_rsp;
+	msg.type = NDP_END_RSP;
+	msg.callback = target_if_nan_event_dispatcher;
+	msg.flush_callback = target_if_nan_event_flush_cb;
+	target_if_debug("NDP_END_RSP sent: %d", msg.type);
+	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("failed to post msg, status: %d", status);
+		target_if_nan_event_flush_cb(&msg);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int target_if_ndp_end_ind_handler(ol_scn_t scn, uint8_t *data,
+					 uint32_t data_len)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wmi_unified *wmi_handle;
+	struct scheduler_msg msg = {0};
+	struct nan_datapath_end_indication_event *rsp = NULL;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null.");
+		return -EINVAL;
+	}
+
+	status = wmi_extract_ndp_end_ind(wmi_handle, data, &rsp);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("parsing of event failed, %d", status);
+		return -EINVAL;
+	}
+
+	rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
+			  wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID);
+	if (!rsp->vdev) {
+		target_if_err("vdev is null");
+		qdf_mem_free(rsp);
+		return -EINVAL;
+	}
+
+	msg.bodyptr = rsp;
+	msg.type = NDP_END_IND;
+	msg.callback = target_if_nan_event_dispatcher;
+	msg.flush_callback = target_if_nan_event_flush_cb;
+	target_if_debug("NDP_END_IND sent: %d", msg.type);
+	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("failed to post msg, status: %d", status);
+		target_if_nan_event_flush_cb(&msg);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int target_if_ndp_sch_update_handler(ol_scn_t scn, uint8_t *data,
+					    uint32_t data_len)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wmi_unified *wmi_handle;
+	struct scheduler_msg msg = {0};
+	struct nan_datapath_sch_update_event *rsp;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null.");
+		return -EINVAL;
+	}
+
+	rsp = qdf_mem_malloc(sizeof(*rsp));
+	if (!rsp) {
+		target_if_err("malloc failed");
+		return -ENOMEM;
+	}
+
+	status = wmi_extract_ndp_sch_update(wmi_handle, data, rsp);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("parsing of event failed, %d", status);
+		qdf_mem_free(rsp);
+		return -EINVAL;
+	}
+
+	msg.bodyptr = rsp;
+	msg.type = NDP_SCHEDULE_UPDATE;
+	msg.callback = target_if_nan_event_dispatcher;
+	msg.flush_callback = target_if_nan_event_flush_cb;
+	target_if_debug("NDP_SCHEDULE_UPDATE sent: %d", msg.type);
+	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("failed to post msg, status: %d", status);
+		target_if_nan_event_flush_cb(&msg);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static QDF_STATUS target_if_nan_req(void *req, uint32_t req_type)
+{
+	/* send cmd to fw */
+	switch (req_type) {
+	case NDP_INITIATOR_REQ:
+		target_if_nan_ndp_initiator_req(req);
+		break;
+	case NDP_RESPONDER_REQ:
+		target_if_nan_ndp_responder_req(req);
+		break;
+	case NDP_END_REQ:
+		target_if_nan_ndp_end_req(req);
+		break;
+	default:
+		target_if_err("invalid req type");
+		break;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+void target_if_nan_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
+{
+	tx_ops->nan_tx_ops.nan_req_tx = target_if_nan_req;
+}
+
+void target_if_nan_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
+{
+	rx_ops->nan_rx_ops.nan_event_rx = nan_event_handler;
+}
+
+inline struct wlan_lmac_if_nan_tx_ops *target_if_nan_get_tx_ops(
+				struct wlan_objmgr_psoc *psoc)
+{
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return NULL;
+	}
+
+	return &psoc->soc_cb.tx_ops.nan_tx_ops;
+}
+
+inline struct wlan_lmac_if_nan_rx_ops *target_if_nan_get_rx_ops(
+				struct wlan_objmgr_psoc *psoc)
+{
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return NULL;
+	}
+
+	return &psoc->soc_cb.rx_ops.nan_rx_ops;
+}
+
+QDF_STATUS target_if_nan_register_events(struct wlan_objmgr_psoc *psoc)
+{
+	int ret;
+	wmi_unified_t handle = get_wmi_unified_hdl_from_psoc(psoc);
+
+	if (!handle) {
+		target_if_err("handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	ret = wmi_unified_register_event_handler(handle,
+		wmi_ndp_initiator_rsp_event_id,
+		target_if_ndp_initiator_rsp_handler,
+		WMI_RX_UMAC_CTX);
+	if (ret) {
+		target_if_err("wmi event registration failed, ret: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wmi_unified_register_event_handler(handle,
+		wmi_ndp_indication_event_id,
+		target_if_ndp_ind_handler,
+		WMI_RX_UMAC_CTX);
+	if (ret) {
+		target_if_err("wmi event registration failed, ret: %d", ret);
+		target_if_nan_deregister_events(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wmi_unified_register_event_handler(handle,
+		wmi_ndp_confirm_event_id,
+		target_if_ndp_confirm_handler,
+		WMI_RX_UMAC_CTX);
+	if (ret) {
+		target_if_err("wmi event registration failed, ret: %d", ret);
+		target_if_nan_deregister_events(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wmi_unified_register_event_handler(handle,
+		wmi_ndp_responder_rsp_event_id,
+		target_if_ndp_responder_rsp_handler,
+		WMI_RX_UMAC_CTX);
+	if (ret) {
+		target_if_err("wmi event registration failed, ret: %d", ret);
+		target_if_nan_deregister_events(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wmi_unified_register_event_handler(handle,
+		wmi_ndp_end_indication_event_id,
+		target_if_ndp_end_ind_handler,
+		WMI_RX_UMAC_CTX);
+	if (ret) {
+		target_if_err("wmi event registration failed, ret: %d", ret);
+		target_if_nan_deregister_events(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wmi_unified_register_event_handler(handle,
+		wmi_ndp_end_rsp_event_id,
+		target_if_ndp_end_rsp_handler,
+		WMI_RX_UMAC_CTX);
+	if (ret) {
+		target_if_err("wmi event registration failed, ret: %d", ret);
+		target_if_nan_deregister_events(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wmi_unified_register_event_handler(handle,
+		wmi_ndl_schedule_update_event_id,
+		target_if_ndp_sch_update_handler,
+		WMI_RX_UMAC_CTX);
+	if (ret) {
+		target_if_err("wmi event registration failed, ret: %d", ret);
+		target_if_nan_deregister_events(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS target_if_nan_deregister_events(struct wlan_objmgr_psoc *psoc)
+{
+	int ret, status = 0;
+	wmi_unified_t handle = get_wmi_unified_hdl_from_psoc(psoc);
+
+	if (!handle) {
+		target_if_err("handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	ret = wmi_unified_unregister_event_handler(handle,
+				wmi_ndl_schedule_update_event_id);
+	if (ret) {
+		target_if_err("wmi event deregistration failed, ret: %d", ret);
+		status = ret;
+	}
+
+	ret = wmi_unified_unregister_event_handler(handle,
+				wmi_ndp_end_rsp_event_id);
+	if (ret) {
+		target_if_err("wmi event deregistration failed, ret: %d", ret);
+		status = ret;
+	}
+
+	ret = wmi_unified_unregister_event_handler(handle,
+				wmi_ndp_end_indication_event_id);
+	if (ret) {
+		target_if_err("wmi event deregistration failed, ret: %d", ret);
+		status = ret;
+	}
+
+	ret = wmi_unified_unregister_event_handler(handle,
+				wmi_ndp_responder_rsp_event_id);
+	if (ret) {
+		target_if_err("wmi event deregistration failed, ret: %d", ret);
+		status = ret;
+	}
+
+	ret = wmi_unified_unregister_event_handler(handle,
+				wmi_ndp_confirm_event_id);
+	if (ret) {
+		target_if_err("wmi event deregistration failed, ret: %d", ret);
+		status = ret;
+	}
+
+	ret = wmi_unified_unregister_event_handler(handle,
+				wmi_ndp_indication_event_id);
+	if (ret) {
+		target_if_err("wmi event deregistration failed, ret: %d", ret);
+		status = ret;
+	}
+
+	ret = wmi_unified_unregister_event_handler(handle,
+				wmi_ndp_initiator_rsp_event_id);
+	if (ret) {
+		target_if_err("wmi event deregistration failed, ret: %d", ret);
+		status = ret;
+	}
+
+	if (status)
+		return QDF_STATUS_E_FAILURE;
+	else
+		return QDF_STATUS_SUCCESS;
+}
diff --git a/components/target_if/ocb/inc/target_if_ocb.h b/components/target_if/ocb/inc/target_if_ocb.h
new file mode 100644
index 0000000..13f9afb
--- /dev/null
+++ b/components/target_if/ocb/inc/target_if_ocb.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018 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: offload lmac interface APIs for ocb
+ *
+ */
+
+#ifndef __TARGET_IF_OCB_H__
+#define __TARGET_IF_OCB_H__
+
+/**
+ * target_if_ocb_register_event_handler() - lmac handler to register ocb event
+ * handler
+ * @psoc : psoc object
+ * @arg: argument passed to lmac
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_if_ocb_register_event_handler(struct wlan_objmgr_psoc *psoc,
+						void *arg);
+
+/**
+ * target_if_ocb_unregister_event_handler() - lmac handler to unregister ocb
+ * event handler
+ * @psoc : psoc object
+ * @arg: argument passed to lmac
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_if_ocb_unregister_event_handler(struct wlan_objmgr_psoc *psoc,
+						  void *arg);
+/**
+ * target_if_ocb_register_tx_ops() - lmac handler to register ocb tx ops
+ * callback functions
+ * @tx_ops: ocb tx operations
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_if_ocb_register_tx_ops(
+		struct wlan_ocb_tx_ops *tx_ops);
+
+#endif
diff --git a/components/target_if/ocb/src/target_if_ocb.c b/components/target_if/ocb/src/target_if_ocb.c
new file mode 100644
index 0000000..e727a9b
--- /dev/null
+++ b/components/target_if/ocb/src/target_if_ocb.c
@@ -0,0 +1,699 @@
+/*
+ * Copyright (c) 2018 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: offload lmac interface APIs for ocb
+ *
+ */
+
+#include <qdf_mem.h>
+#include <target_if.h>
+#include <qdf_status.h>
+#include <wmi_unified_api.h>
+#include <wmi_unified_priv.h>
+#include <wmi_unified_param.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_utility.h>
+#include <wlan_defs.h>
+#include <wlan_ocb_public_structs.h>
+#include <wlan_ocb_main.h>
+#include <target_if_ocb.h>
+
+/**
+ * target_if_ocb_get_rx_ops() - get target interface RX operations
+ * @pdev: pdev handle
+ *
+ * Return: fp to target interface RX operations
+ */
+static inline struct wlan_ocb_rx_ops *
+target_if_ocb_get_rx_ops(struct wlan_objmgr_pdev *pdev)
+{
+	struct ocb_pdev_obj *ocb_obj;
+
+	ocb_obj = wlan_get_pdev_ocb_obj(pdev);
+
+	return &ocb_obj->ocb_rxops;
+}
+
+/**
+ * target_if_ocb_set_config() - send the OCB config to the FW
+ * @psoc: pointer to PSOC object
+ * @config: OCB channel configuration
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS target_if_ocb_set_config(struct wlan_objmgr_psoc *psoc,
+					   struct ocb_config *config)
+{
+	QDF_STATUS status;
+
+	status = wmi_unified_ocb_set_config(get_wmi_unified_hdl_from_psoc(psoc),
+					    config);
+	if (status)
+		target_if_err("Failed to set OCB config %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_ocb_set_utc_time() - send the UTC time to the firmware
+ * @psoc: pointer to PSOC object
+ * @utc: pointer to the UTC time structure
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS target_if_ocb_set_utc_time(struct wlan_objmgr_psoc *psoc,
+					     struct ocb_utc_param *utc)
+{
+	QDF_STATUS status;
+
+	status = wmi_unified_ocb_set_utc_time_cmd(
+			get_wmi_unified_hdl_from_psoc(psoc), utc);
+	if (status)
+		target_if_err("Failed to set OCB UTC time %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_ocb_start_timing_advert() - start sending the timing
+ *  advertisement frame on a channel
+ * @psoc: pointer to PSOC object
+ * @ta: pointer to the timing advertisement
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_ocb_start_timing_advert(struct wlan_objmgr_psoc *psoc,
+				  struct ocb_timing_advert_param *ta)
+{
+	QDF_STATUS status;
+
+	status = wmi_unified_ocb_start_timing_advert(
+			get_wmi_unified_hdl_from_psoc(psoc), ta);
+	if (status)
+		target_if_err("Failed to start OCB timing advert %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_ocb_stop_timing_advert() - stop sending the timing
+ *   advertisement frame on a channel
+ * @psoc: pointer to PSOC object
+ * @ta: pointer to the timing advertisement
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_ocb_stop_timing_advert(struct wlan_objmgr_psoc *psoc,
+				 struct ocb_timing_advert_param *ta)
+{
+	QDF_STATUS status;
+
+	status =
+		wmi_unified_ocb_stop_timing_advert(
+				get_wmi_unified_hdl_from_psoc(psoc), ta);
+	if (status)
+		target_if_err("Failed to stop OCB timing advert %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_ocb_get_tsf_timer() - get tsf timer
+ * @psoc: pointer to PSOC object
+ * @request: pointer to the request
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_ocb_get_tsf_timer(struct wlan_objmgr_psoc *psoc,
+			    struct ocb_get_tsf_timer_param *request)
+{
+	QDF_STATUS status;
+
+	status = wmi_unified_ocb_get_tsf_timer(
+			get_wmi_unified_hdl_from_psoc(psoc), request);
+	if (status)
+		target_if_err("Failed to send get tsf timer cmd: %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_dcc_get_stats() - get the DCC channel stats
+ * @psoc: pointer to PSOC object
+ * @get_stats_param: pointer to the dcc stats request
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_dcc_get_stats(struct wlan_objmgr_psoc *psoc,
+			struct ocb_dcc_get_stats_param *get_stats_param)
+{
+	QDF_STATUS status;
+
+	status = wmi_unified_dcc_get_stats_cmd(
+			get_wmi_unified_hdl_from_psoc(psoc), get_stats_param);
+	if (status)
+		target_if_err("Failed to send get DCC stats cmd: %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_dcc_clear_stats() - send command to clear the DCC stats
+ * @psoc: pointer to PSOC object
+ * @clear_stats_param: parameters to the command
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_dcc_clear_stats(struct wlan_objmgr_psoc *psoc,
+			  struct ocb_dcc_clear_stats_param *clear_stats_param)
+{
+	QDF_STATUS status;
+
+	status = wmi_unified_dcc_clear_stats(
+			get_wmi_unified_hdl_from_psoc(psoc), clear_stats_param);
+	if (status)
+		target_if_err("Failed to send clear DCC stats cmd: %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_dcc_update_ndl() - command to update the NDL data
+ * @psoc: pointer to PSOC object
+ * @update_ndl_param: pointer to the request parameters
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_dcc_update_ndl(struct wlan_objmgr_psoc *psoc,
+			 struct ocb_dcc_update_ndl_param *update_ndl_param)
+{
+	QDF_STATUS status;
+
+	/* Send the WMI command */
+	status = wmi_unified_dcc_update_ndl(get_wmi_unified_hdl_from_psoc(psoc),
+					    update_ndl_param);
+	if (status)
+		target_if_err("Failed to send NDL update cmd: %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_ocb_set_config_resp() - handler for channel config response
+ * @scn: scn handle
+ * @event_buf: pointer to the event buffer
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+static int
+target_if_ocb_set_config_resp(ol_scn_t scn, uint8_t *event_buf,
+			      uint32_t len)
+{
+	int rc;
+	QDF_STATUS status;
+	uint32_t resp;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_ocb_rx_ops *ocb_rx_ops;
+
+	target_if_debug("scn:%pK, data:%pK, datalen:%d",
+			scn, event_buf, len);
+	if (!scn || !event_buf) {
+		target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf);
+		return -EINVAL;
+	}
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("null psoc");
+		return -EINVAL;
+	}
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
+					  WLAN_OCB_SB_ID);
+	if (!pdev) {
+		target_if_err("pdev is NULL");
+		return -EINVAL;
+	}
+
+	ocb_rx_ops = target_if_ocb_get_rx_ops(pdev);
+	if (ocb_rx_ops->ocb_set_config_status) {
+		status = wmi_extract_ocb_set_channel_config_resp(
+					get_wmi_unified_hdl_from_psoc(psoc),
+					event_buf, &resp);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("Failed to extract config status");
+			rc = -EINVAL;
+			goto exit;
+		}
+		status = ocb_rx_ops->ocb_set_config_status(psoc, resp);
+		if (status != QDF_STATUS_SUCCESS) {
+			target_if_err("ocb_set_config_status failed.");
+			rc = -EINVAL;
+			goto exit;
+		}
+		rc = 0;
+	} else {
+		target_if_fatal("No ocb_set_config_status callback");
+		rc = -EINVAL;
+	}
+exit:
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_SB_ID);
+
+	return rc;
+};
+
+/**
+ * target_if_ocb_get_tsf_timer_resp() - handler for TSF timer response
+ * @scn: scn handle
+ * @event_buf: pointer to the event buffer
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+static int target_if_ocb_get_tsf_timer_resp(ol_scn_t scn,
+					    uint8_t *event_buf,
+					    uint32_t len)
+{
+	int rc;
+	QDF_STATUS status;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_psoc *psoc;
+	struct ocb_get_tsf_timer_response response;
+	struct wlan_ocb_rx_ops *ocb_rx_ops;
+
+	target_if_debug("scn:%pK, data:%pK, datalen:%d",
+			scn, event_buf, len);
+
+	if (!scn || !event_buf) {
+		target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf);
+		return -EINVAL;
+	}
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("null psoc");
+		return -EINVAL;
+	}
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
+					  WLAN_OCB_SB_ID);
+	if (!pdev) {
+		target_if_err("pdev is NULL");
+		return -EINVAL;
+	}
+
+	ocb_rx_ops = target_if_ocb_get_rx_ops(pdev);
+	if (ocb_rx_ops->ocb_tsf_timer) {
+		status = wmi_extract_ocb_tsf_timer(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			event_buf, &response);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("Failed to extract tsf timer");
+			rc = -EINVAL;
+			goto exit;
+		}
+		status = ocb_rx_ops->ocb_tsf_timer(psoc, &response);
+		if (status != QDF_STATUS_SUCCESS) {
+			target_if_err("ocb_tsf_timer failed.");
+			rc = -EINVAL;
+			goto exit;
+		}
+		rc = 0;
+	} else {
+		target_if_fatal("No ocb_tsf_timer callback");
+		rc = -EINVAL;
+	}
+exit:
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_SB_ID);
+
+	return rc;
+}
+
+/**
+ * target_if_dcc_update_ndl_resp() - handler for update NDL response
+ * @scn: scn handle
+ * @event_buf: pointer to the event buffer
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+static int target_if_dcc_update_ndl_resp(ol_scn_t scn,
+					 uint8_t *event_buf,
+					 uint32_t len)
+{
+	int rc;
+	QDF_STATUS status;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_psoc *psoc;
+	struct ocb_dcc_update_ndl_response *resp;
+	struct wlan_ocb_rx_ops *ocb_rx_ops;
+
+	target_if_debug("scn:%pK, data:%pK, datalen:%d",
+			scn, event_buf, len);
+
+	if (!scn || !event_buf) {
+		target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf);
+		return -EINVAL;
+	}
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("null psoc");
+		return -EINVAL;
+	}
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
+					  WLAN_OCB_SB_ID);
+	if (!pdev) {
+		target_if_err("pdev is NULL");
+		return -EINVAL;
+	}
+
+	/* Allocate and populate the response */
+	resp = qdf_mem_malloc(sizeof(*resp));
+	if (!resp) {
+		target_if_err("Error allocating memory for the response.");
+		rc = -ENOMEM;
+		goto exit;
+	}
+
+	ocb_rx_ops = target_if_ocb_get_rx_ops(pdev);
+	if (ocb_rx_ops->ocb_dcc_ndl_update) {
+		status = wmi_extract_dcc_update_ndl_resp(
+					get_wmi_unified_hdl_from_psoc(psoc),
+					event_buf, resp);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("Failed to extract ndl status");
+			rc = -EINVAL;
+			goto exit;
+		}
+		status = ocb_rx_ops->ocb_dcc_ndl_update(psoc, resp);
+		if (status != QDF_STATUS_SUCCESS) {
+			target_if_err("dcc_ndl_update failed.");
+			rc = -EINVAL;
+			goto exit;
+		}
+		rc = 0;
+	} else {
+		target_if_fatal("No dcc_ndl_update callback");
+		rc = -EINVAL;
+	}
+exit:
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_SB_ID);
+	if (resp)
+		qdf_mem_free(resp);
+
+	return rc;
+}
+
+/**
+ * target_if_dcc_get_stats_resp() - handler for get stats response
+ * @scn: scn handle
+ * @event_buf: pointer to the event buffer
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+static int target_if_dcc_get_stats_resp(ol_scn_t scn,
+					uint8_t *event_buf,
+					uint32_t len)
+{
+	int rc;
+	QDF_STATUS status;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_psoc *psoc;
+	struct ocb_dcc_get_stats_response *response;
+	struct wlan_ocb_rx_ops *ocb_rx_ops;
+
+	target_if_debug("scn:%pK, data:%pK, datalen:%d",
+			scn, event_buf, len);
+
+	if (!scn || !event_buf) {
+		target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf);
+		return -EINVAL;
+	}
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("null psoc");
+		return -EINVAL;
+	}
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
+					  WLAN_OCB_SB_ID);
+	if (!pdev) {
+		target_if_err("pdev is NULL");
+		return -EINVAL;
+	}
+
+	ocb_rx_ops = target_if_ocb_get_rx_ops(pdev);
+	if (ocb_rx_ops->ocb_dcc_stats_indicate) {
+		status = wmi_extract_dcc_stats(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			event_buf, &response);
+		if (!response || QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("Cannot get DCC stats");
+			rc = -ENOMEM;
+			goto exit;
+		}
+
+		status = ocb_rx_ops->ocb_dcc_stats_indicate(psoc,
+							    response,
+							    true);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("dcc_stats_indicate failed.");
+			rc = -EINVAL;
+			goto exit;
+		}
+		rc = 0;
+	} else {
+		target_if_fatal("No dcc_stats_indicate callback");
+		rc = -EINVAL;
+	}
+exit:
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_SB_ID);
+	if (response)
+		qdf_mem_free(response);
+
+	return rc;
+}
+
+/**
+ * target_if_dcc_stats_resp() - handler for DCC stats indication event
+ * @scn: scn handle
+ * @event_buf: pointer to the event buffer
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+static int target_if_dcc_stats_resp(ol_scn_t scn, uint8_t *event_buf,
+				    uint32_t len)
+{
+	int rc;
+	QDF_STATUS status;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_psoc *psoc;
+	struct ocb_dcc_get_stats_response *response;
+	struct wlan_ocb_rx_ops *ocb_rx_ops;
+
+	target_if_debug("scn:%pK, data:%pK, datalen:%d",
+			scn, event_buf, len);
+
+	if (!scn || !event_buf) {
+		target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf);
+		return -EINVAL;
+	}
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("null psoc");
+		return -EINVAL;
+	}
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
+					  WLAN_OCB_SB_ID);
+	if (!pdev) {
+		target_if_err("pdev is NULL");
+		return -EINVAL;
+	}
+
+	ocb_rx_ops = target_if_ocb_get_rx_ops(pdev);
+	if (ocb_rx_ops->ocb_dcc_stats_indicate) {
+		status = wmi_extract_dcc_stats(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			event_buf, &response);
+		if (!response || QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("Cannot get DCC stats");
+			rc = -ENOMEM;
+			goto exit;
+		}
+		status = ocb_rx_ops->ocb_dcc_stats_indicate(psoc,
+							    response,
+							    false);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("dcc_stats_indicate failed.");
+			rc = -EINVAL;
+			goto exit;
+		}
+		rc = 0;
+	} else {
+		target_if_fatal("dcc_stats_indicate failed.");
+		response = NULL;
+		rc = -EINVAL;
+	}
+exit:
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_SB_ID);
+	if (response)
+		qdf_mem_free(response);
+
+	return rc;
+}
+
+QDF_STATUS target_if_ocb_register_event_handler(struct wlan_objmgr_psoc *psoc,
+						void *arg)
+{
+	int rc;
+
+	/* Initialize the members in WMA used by wma_ocb */
+	rc = wmi_unified_register_event(get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_ocb_set_config_resp_event_id,
+			target_if_ocb_set_config_resp);
+	if (rc) {
+		target_if_err("Failed to register OCB config resp event cb");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	rc = wmi_unified_register_event(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_ocb_get_tsf_timer_resp_event_id,
+			target_if_ocb_get_tsf_timer_resp);
+	if (rc) {
+		target_if_err("Failed to register OCB TSF resp event cb");
+		goto unreg_set_config;
+	}
+
+	rc = wmi_unified_register_event(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_dcc_get_stats_resp_event_id,
+			target_if_dcc_get_stats_resp);
+	if (rc) {
+		target_if_err("Failed to register DCC get stats resp event cb");
+		goto unreg_tsf_timer;
+	}
+
+	rc = wmi_unified_register_event(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_dcc_update_ndl_resp_event_id,
+			target_if_dcc_update_ndl_resp);
+	if (rc) {
+		target_if_err("Failed to register NDL update event cb");
+		goto unreg_get_stats;
+	}
+
+	rc = wmi_unified_register_event(get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_dcc_stats_event_id,
+			target_if_dcc_stats_resp);
+	if (rc) {
+		target_if_err("Failed to register DCC stats event cb");
+		goto unreg_ndl;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+unreg_ndl:
+	wmi_unified_unregister_event_handler(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_dcc_update_ndl_resp_event_id);
+unreg_get_stats:
+	wmi_unified_unregister_event_handler(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_dcc_get_stats_resp_event_id);
+unreg_tsf_timer:
+	wmi_unified_unregister_event_handler(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_ocb_get_tsf_timer_resp_event_id);
+unreg_set_config:
+	wmi_unified_unregister_event(get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_ocb_set_config_resp_event_id);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS
+target_if_ocb_unregister_event_handler(struct wlan_objmgr_psoc *psoc,
+				       void *arg)
+{
+	int rc;
+
+	rc = wmi_unified_unregister_event_handler(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_dcc_stats_event_id);
+	if (rc)
+		target_if_err("Failed to unregister DCC stats event cb");
+
+	rc = wmi_unified_unregister_event_handler(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_dcc_update_ndl_resp_event_id);
+	if (rc)
+		target_if_err("Failed to unregister NDL update event cb");
+
+	rc = wmi_unified_unregister_event_handler(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_dcc_get_stats_resp_event_id);
+	if (rc)
+		target_if_err("Failed to unregister DCC get stats resp cb");
+
+	rc = wmi_unified_unregister_event_handler(
+			get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_ocb_get_tsf_timer_resp_event_id);
+	if (rc)
+		target_if_err("Failed to unregister OCB TSF resp event cb");
+
+	rc = wmi_unified_unregister_event(get_wmi_unified_hdl_from_psoc(psoc),
+			wmi_ocb_set_config_resp_event_id);
+	if (rc)
+		target_if_err("Failed to unregister OCB config resp event cb");
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+target_if_ocb_register_tx_ops(struct wlan_ocb_tx_ops *ocb_txops)
+{
+	ocb_txops->ocb_set_config = target_if_ocb_set_config;
+	ocb_txops->ocb_set_utc_time = target_if_ocb_set_utc_time;
+	ocb_txops->ocb_start_timing_advert = target_if_ocb_start_timing_advert;
+	ocb_txops->ocb_stop_timing_advert = target_if_ocb_stop_timing_advert;
+	ocb_txops->ocb_get_tsf_timer = target_if_ocb_get_tsf_timer;
+	ocb_txops->ocb_dcc_get_stats = target_if_dcc_get_stats;
+	ocb_txops->ocb_dcc_clear_stats = target_if_dcc_clear_stats;
+	ocb_txops->ocb_dcc_update_ndl = target_if_dcc_update_ndl;
+	ocb_txops->ocb_reg_ev_handler = target_if_ocb_register_event_handler;
+	ocb_txops->ocb_unreg_ev_handler =
+			target_if_ocb_unregister_event_handler;
+
+	return QDF_STATUS_SUCCESS;
+}
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..dbb4236
--- /dev/null
+++ b/components/target_if/pmo/inc/target_if_pmo.h
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2017-2018 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);
+
+QDF_STATUS target_if_pmo_del_wow_patterns_to_fw(struct wlan_objmgr_vdev *vdev,
+		uint8_t ptrn_id);
+
+/**
+ * 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_get_multiple_mc_filter_support() - get multiple mc filter
+ *						    request fw support
+ * @psoc: the psoc containing the vdev to configure
+ *
+ * Return: true if fw supports else false
+ */
+bool target_if_pmo_get_multiple_mc_filter_support(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_set_multiple_mc_filter_req() - set multiple 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_multiple_mc_filter_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_mc_addr_list *mc_list);
+
+/**
+ * target_if_pmo_clear_multiple_mc_filter_req() - clear multiple 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_multiple_mc_filter_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_mc_addr_list *mc_list);
+
+/**
+ * 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);
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+/**
+ * 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);
+#endif
+
+/**
+ * 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);
+
+#ifdef WLAN_NS_OFFLOAD
+/**
+ * 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);
+#else /* WLAN_NS_OFFLOAD */
+static inline 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)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_NS_OFFLOAD */
+/**
+ * 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_psoc_send_d0wow_enable_req() - send d0 wow enable request
+ * @psoc: objmgr psoc
+ *
+ * Return: return QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_psoc_send_d0wow_enable_req(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_psoc_send_d0wow_disable_req() - send d0 wow disable request
+ * @psoc: objmgr psoc
+ *
+ * Return: return QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_psoc_send_d0wow_disable_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..c8e4aef
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_arp.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017-2018 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_enable_arp_ns_offload_cmd(wmi_handle,
+						       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..d279984
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_gtk.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2017-2018 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_send_gtk_offload_cmd(wmi_handle,
+						  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;
+	wmi_unified_t wmi_handle;
+
+	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;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* send the wmi command */
+	status = wmi_unified_process_gtk_offload_getinfo_cmd(wmi_handle,
+			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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		qdf_mem_free(gtk_rsp_param);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (wmi_extract_gtk_rsp_event(wmi_handle, 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..d378f1c
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_hw_filter.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017-2018 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;
+	wmi_unified_t wmi_handle;
+
+	if (!psoc) {
+		target_if_err("psoc is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_conf_hw_filter_cmd(wmi_handle, 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..c02d264
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_lphb.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2017-2018 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_lphb_config_hbenable_cmd(wmi_handle,
+						      &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};
+	wmi_unified_t wmi_handle;
+
+	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);
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_lphb_config_tcp_params_cmd(wmi_handle,
+							&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};
+	wmi_unified_t wmi_handle;
+
+	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);
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_lphb_config_tcp_pkt_filter_cmd(wmi_handle,
+							    &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};
+	wmi_unified_t wmi_handle;
+
+	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);
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_lphb_config_udp_params_cmd(wmi_handle,
+							&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};
+	wmi_unified_t wmi_handle;
+
+	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);
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_lphb_config_udp_pkt_filter_cmd(wmi_handle,
+							    &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..d7a274c
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_main.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2017-2018 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"
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+static inline
+void tgt_if_pmo_reg_pkt_filter_ops(struct wlan_pmo_tx_ops *pmo_tx_ops)
+{
+	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;
+}
+#else
+static inline
+void tgt_if_pmo_reg_pkt_filter_ops(struct wlan_pmo_tx_ops *pmo_tx_ops)
+{
+}
+#endif
+
+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->del_wow_pattern =
+		target_if_pmo_del_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->get_multiple_mc_filter_support =
+		target_if_pmo_get_multiple_mc_filter_support;
+	pmo_tx_ops->send_set_multiple_mc_filter_req =
+		target_if_pmo_set_multiple_mc_filter_req;
+	pmo_tx_ops->send_clear_multiple_mc_filter_req =
+		target_if_pmo_clear_multiple_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->psoc_send_d0wow_enable_req =
+		target_if_pmo_psoc_send_d0wow_enable_req;
+	pmo_tx_ops->psoc_send_d0wow_disable_req =
+		target_if_pmo_psoc_send_d0wow_disable_req;
+	tgt_if_pmo_reg_pkt_filter_ops(pmo_tx_ops);
+}
+
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..8d0f768
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_mc_addr_filtering.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017-2018 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_add_clear_mcbc_filter_cmd(wmi_handle, 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_add_clear_mcbc_filter_cmd(wmi_handle, vdev_id,
+						       multicast_addr, true);
+	if (status)
+		target_if_err("Failed to send add/clear mcbc filter cmd");
+
+	return status;
+
+}
+
+bool target_if_pmo_get_multiple_mc_filter_support(
+		struct wlan_objmgr_psoc *psoc)
+{
+	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return false;
+	}
+
+	return wmi_service_enabled(wmi_handle,
+				   wmi_service_multiple_mcast_filter_set);
+}
+
+QDF_STATUS target_if_pmo_set_multiple_mc_filter_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_mc_addr_list *mc_list)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	struct pmo_mcast_filter_params filter_params;
+	QDF_STATUS status;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	filter_params.multicast_addr_cnt = mc_list->mc_cnt;
+	qdf_mem_copy(filter_params.multicast_addr,
+		     mc_list->mc_addr,
+		     mc_list->mc_cnt * ATH_MAC_LEN);
+	/* add one/multiple mc list */
+	filter_params.action = 1;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_multiple_add_clear_mcbc_filter_cmd(wmi_handle,
+								vdev_id,
+								&filter_params);
+	if (status)
+		target_if_err("Failed to send add/clear mcbc filter cmd");
+
+	return status;
+}
+
+QDF_STATUS target_if_pmo_clear_multiple_mc_filter_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_mc_addr_list *mc_list)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	struct pmo_mcast_filter_params filter_params;
+	QDF_STATUS status;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	filter_params.multicast_addr_cnt = mc_list->mc_cnt;
+	qdf_mem_copy(filter_params.multicast_addr,
+		     mc_list->mc_addr,
+		     mc_list->mc_cnt * ATH_MAC_LEN);
+	/* delete one/multiple mc list */
+	filter_params.action = 0;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_multiple_add_clear_mcbc_filter_cmd(wmi_handle,
+								vdev_id,
+								&filter_params);
+	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..0f23bb1
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_ns.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017-2018 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_enable_arp_ns_offload_cmd(wmi_handle,
+						       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..85725b9
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_pkt_filter.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2017-2018 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* send the command along with data */
+	status = wmi_unified_config_packet_filter_cmd(wmi_handle, 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(wmi_handle,
+							      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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* send the command along with data */
+	status = wmi_unified_config_packet_filter_cmd(wmi_handle, 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..79d1138
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_static_config.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2017-2018 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_wow_sta_ra_filter_cmd(wmi_handle,
+						   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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_action_frame_patterns_cmd(wmi_handle, 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_enable_enhance_multicast_offload_cmd(wmi_handle,
+								  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..aa379ab
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_suspend_resume.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2017-2018 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 "wma.h"
+#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};
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	param.if_id = vdev_id;
+	param.param_id = param_id;
+	param.param_value = param_value;
+	target_if_debug("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(wmi_handle, &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};
+	wmi_unified_t wmi_handle;
+
+	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_debug("set vdev param vdev_id: %d value: %d for param_id: %d",
+			vdev_id, param_value, param_id);
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_sta_ps_cmd_send(wmi_handle, &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_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return;
+	}
+
+	wmi_set_is_wow_bus_suspended(wmi_handle, value);
+}
+
+int target_if_pmo_psoc_get_host_credits(struct wlan_objmgr_psoc *psoc)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return 0;
+	}
+
+	return wmi_get_host_credits(wmi_handle);
+}
+
+int target_if_pmo_psoc_get_pending_cmnds(struct wlan_objmgr_psoc *psoc)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return 0;
+	}
+
+	return wmi_get_pending_cmds(wmi_handle);
+}
+
+void target_if_pmo_update_target_suspend_flag(struct wlan_objmgr_psoc *psoc,
+		uint8_t value)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return;
+	}
+
+	wmi_set_target_suspend(wmi_handle, value);
+}
+
+QDF_STATUS target_if_pmo_psoc_send_wow_enable_req(
+		struct wlan_objmgr_psoc *psoc,
+		struct pmo_wow_cmd_params *param)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wma_check_and_set_wake_timer(SIR_INSTALL_KEY_TIMEOUT_MS);
+	return wmi_unified_wow_enable_send(wmi_handle,
+					   (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)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wmi_unified_suspend_send(wmi_handle,
+					(struct suspend_params *) param,
+					TGT_WILDCARD_PDEV_ID);
+}
+
+void target_if_pmo_set_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc,
+					      bool value)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return;
+	}
+
+	return wmi_set_runtime_pm_inprogress(wmi_handle, value);
+}
+
+bool target_if_pmo_get_runtime_pm_in_progress(
+		struct wlan_objmgr_psoc *psoc)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return false;
+	}
+
+	return wmi_get_runtime_pm_inprogress(wmi_handle);
+}
+
+QDF_STATUS target_if_pmo_psoc_send_host_wakeup_ind(
+		struct wlan_objmgr_psoc *psoc)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wmi_unified_host_wakeup_ind_to_fw_cmd(wmi_handle);
+}
+
+QDF_STATUS target_if_pmo_psoc_send_target_resume_req(
+		struct wlan_objmgr_psoc *psoc)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wmi_unified_resume_send(wmi_handle, TGT_WILDCARD_PDEV_ID);
+}
+
+#ifdef FEATURE_WLAN_D0WOW
+QDF_STATUS target_if_pmo_psoc_send_d0wow_enable_req(
+		struct wlan_objmgr_psoc *psoc)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wmi_unified_d0wow_enable_send(wmi_handle, TGT_WILDCARD_PDEV_ID);
+}
+
+QDF_STATUS target_if_pmo_psoc_send_d0wow_disable_req(
+		struct wlan_objmgr_psoc *psoc)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wmi_unified_d0wow_disable_send(wmi_handle, TGT_WILDCARD_PDEV_ID);
+}
+#else
+QDF_STATUS target_if_pmo_psoc_send_d0wow_enable_req(
+		struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_E_INVAL;
+}
+
+QDF_STATUS target_if_pmo_psoc_send_d0wow_disable_req(
+		struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_E_INVAL;
+}
+#endif
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..6c2481e
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_wow.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2017-2018 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_add_wow_wakeup_event_cmd(wmi_handle, 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_add_wow_wakeup_event_cmd(wmi_handle, 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;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_wow_patterns_to_fw_cmd(wmi_handle,
+						    vdev_id, ptrn_id, ptrn,
+						    ptrn_len, ptrn_offset,
+						    mask, mask_len, user, 0);
+
+	return status;
+}
+
+QDF_STATUS target_if_pmo_del_wow_patterns_to_fw(struct wlan_objmgr_vdev *vdev,
+		uint8_t ptrn_id)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+	wmi_unified_t wmi_handle;
+
+	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;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("Invalid wmi handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_wow_delete_pattern_cmd(wmi_handle, ptrn_id,
+						    vdev_id);
+
+	return status;
+}
+
diff --git a/configs/default_defconfig b/configs/default_defconfig
new file mode 100644
index 0000000..eb182c6
--- /dev/null
+++ b/configs/default_defconfig
@@ -0,0 +1,718 @@
+ifeq ($(CONFIG_CNSS_QCA6290), y)
+	ifeq ($(CONFIG_CNSS_EMULATION), y)
+		CONFIG_QCA_WIFI_NAPIER_EMULATION := y
+	endif
+	CONFIG_LITHIUM := y
+	CONFIG_QCA6290_11AX := y
+	CONFIG_WLAN_FEATURE_11AX := y
+	CONFIG_WLAN_FEATURE_DFS_OFFLOAD := y
+	CONFIG_IPA3 := n
+endif
+
+ifeq ($(CONFIG_CNSS_QCA6390), y)
+	ifeq ($(CONFIG_CNSS_EMULATION), y)
+		CONFIG_QCA_WIFI_NAPIER_EMULATION := y
+	endif
+	CONFIG_LITHIUM := y
+	CONFIG_WLAN_FEATURE_11AX := y
+	CONFIG_WLAN_FEATURE_DFS_OFFLOAD := y
+	CONFIG_IPA3 := n
+	CONFIG_SCALE_INCLUDES := y
+endif
+
+ifeq ($(CONFIG_CLD_HL_SDIO_CORE), y)
+	CONFIG_QCA_WIFI_SDIO := y
+ifndef CONFIG_SDIO_TRANSFER
+	CONFIG_SDIO_TRANSFER = mailbox
+endif
+endif
+
+ifeq ($(CONFIG_QCA_WIFI_SDIO), y)
+	CONFIG_ROME_IF = sdio
+endif
+
+ifdef CONFIG_ICNSS
+	CONFIG_ROME_IF = snoc
+endif
+
+ifeq (y,$(findstring y,$(CONFIG_CNSS) $(CONFIG_CNSS2)))
+ifndef CONFIG_ROME_IF
+	#use pci as default interface
+	CONFIG_ROME_IF = pci
+endif
+endif
+
+# Make WLAN as open-source driver by default
+WLAN_OPEN_SOURCE := y
+
+ifeq ($(CONFIG_ICNSS), y)
+	CONFIG_HELIUMPLUS := y
+	CONFIG_64BIT_PADDR := y
+	CONFIG_FEATURE_TSO := y
+	CONFIG_FEATURE_TSO_DEBUG := y
+	ifeq ($(CONFIG_INET_LRO), y)
+		CONFIG_WLAN_LRO := y
+	else
+		CONFIG_WLAN_LRO := n
+	endif
+endif
+
+ifneq ($(DEVELOPER_DISABLE_BUILD_TIMESTAMP), y)
+ifneq ($(WLAN_DISABLE_BUILD_TAG), y)
+CONFIG_BUILD_TAG := y
+endif
+endif
+
+ifeq ($(CONFIG_ARCH_MDM9630), y)
+CONFIG_MOBILE_ROUTER := y
+endif
+
+ifeq ($(CONFIG_ARCH_MDM9640), y)
+CONFIG_MOBILE_ROUTER := y
+endif
+
+ifeq ($(CONFIG_ARCH_SDX20), y)
+CONFIG_MOBILE_ROUTER := y
+endif
+
+ifeq ($(CONFIG_ARCH_MSM8917), y)
+	ifeq ($(CONFIG_ROME_IF), sdio)
+		CONFIG_WLAN_SYNC_TSF_PLUS := y
+	endif
+endif
+
+ifeq ($(CONFIG_ARCH_QCS405), y)
+	CONFIG_WLAN_SYNC_TSF_PLUS := y
+	CONFIG_WLAN_SYNC_TSF_PLUS_NOIRQ := y
+endif
+
+#Flag to enable Legacy Fast Roaming2(LFR2)
+CONFIG_QCACLD_WLAN_LFR2 := y
+#Flag to enable Legacy Fast Roaming3(LFR3)
+ifneq ($(CONFIG_ARCH_SDX20), y)
+CONFIG_QCACLD_WLAN_LFR3 := y
+endif
+
+ifneq ($(CONFIG_MOBILE_ROUTER), y)
+#Flag to enable TDLS feature
+CONFIG_QCOM_TDLS := y
+
+CONFIG_WLAN_SYSFS := y
+endif
+
+CONFIG_QCACLD_FEATURE_GREEN_AP := y
+CONFIG_CRYPTO_COMPONENT := y
+#Flag to enable Android Packet Filtering
+CONFIG_QCACLD_FEATURE_APF := y
+
+#Flag to enable SARv1 -> SARv2 conversion
+CONFIG_WLAN_FEATURE_SARV1_TO_SARV2 := n
+
+ifeq ($(CONFIG_ARCH_MSM8998), y)
+CONFIG_QCACLD_FEATURE_METERING := y
+endif
+
+ifeq ($(CONFIG_ARCH_SDM660), y)
+CONFIG_QCACLD_FEATURE_METERING := y
+endif
+
+ifeq ($(CONFIG_ARCH_SDM630), y)
+CONFIG_QCACLD_FEATURE_METERING := y
+endif
+
+ifeq ($(CONFIG_ARCH_SDM845), y)
+CONFIG_QCACLD_FEATURE_METERING := y
+endif
+
+ifeq ($(CONFIG_ARCH_SM8150), y)
+CONFIG_QCACLD_FEATURE_METERING := y
+endif
+
+ifeq ($(CONFIG_ARCH_SDM670), y)
+CONFIG_QCACLD_FEATURE_METERING := y
+endif
+
+ifeq ($(CONFIG_ARCH_SM6150), y)
+CONFIG_QCACLD_FEATURE_METERING := y
+endif
+
+#Flag to enable Fast Transition (11r) feature
+CONFIG_QCOM_VOWIFI_11R := y
+
+#Flag to enable disable ACTION OUI feature
+CONFIG_WLAN_FEATURE_ACTION_OUI := y
+
+#Flag to enable FILS Feature (11ai)
+CONFIG_WLAN_FEATURE_FILS := y
+ifneq ($(CONFIG_QCA_CLD_WLAN),)
+	ifeq (y,$(findstring y,$(CONFIG_CNSS) $(CONFIG_CNSS2) $(CONFIG_ICNSS)))
+	#Flag to enable Protected Management Frames (11w) feature
+	CONFIG_WLAN_FEATURE_11W := y
+	#Flag to enable LTE CoEx feature
+	CONFIG_QCOM_LTE_COEX := y
+		ifneq ($(CONFIG_MOBILE_ROUTER), y)
+		#Flag to enable LPSS feature
+		CONFIG_WLAN_FEATURE_LPSS := y
+		endif
+	endif
+endif
+
+#Flag to enable Protected Management Frames (11w) feature
+ifeq ($(CONFIG_ROME_IF),usb)
+	CONFIG_WLAN_FEATURE_11W := y
+endif
+ifeq ($(CONFIG_ROME_IF),sdio)
+	CONFIG_WLAN_FEATURE_11W := y
+endif
+
+#Flag to enable the tx desc sanity check
+ifeq ($(CONFIG_ROME_IF),usb)
+	CONFIG_QCA_TXDESC_SANITY_CHECKS := y
+endif
+
+ifneq ($(CONFIG_MOBILE_ROUTER), y)
+	#Flag to enable NAN
+	CONFIG_QCACLD_FEATURE_NAN := y
+endif
+
+ifneq ($(CONFIG_MOBILE_ROUTER), y)
+	#Flag to enable NAN Data path
+	CONFIG_WLAN_FEATURE_NAN_DATAPATH := y
+	CONFIG_NAN_CONVERGENCE := y
+endif
+
+#Flag to enable Linux QCMBR feature as default feature
+ifeq ($(CONFIG_ROME_IF),usb)
+	CONFIG_LINUX_QCMBR :=y
+endif
+
+
+CONFIG_FEATURE_EPPING := y
+
+#Flag to enable offload packets feature
+CONFIG_WLAN_OFFLOAD_PACKETS := y
+
+#enable TSF get feature
+CONFIG_WLAN_SYNC_TSF := y
+#Enable DSRC feature
+ifeq ($(CONFIG_QCA_WIFI_SDIO), y)
+CONFIG_WLAN_FEATURE_DSRC := y
+endif
+
+ifneq ($(CONFIG_ROME_IF),usb)
+ifneq ($(CONFIG_ROME_IF),sdio)
+	#Flag to enable DISA
+	CONFIG_WLAN_FEATURE_DISA := y
+
+	#Flag to enable FIPS
+	CONFIG_WLAN_FEATURE_FIPS := y
+
+	#Flag to enable SAE
+	CONFIG_WLAN_FEATURE_SAE := y
+
+	#Flag to enable Fast Path feature
+	ifneq ($(CONFIG_LITHIUM), y)
+		CONFIG_WLAN_FASTPATH := y
+	endif
+
+	# Flag to enable NAPI
+	CONFIG_WLAN_NAPI := y
+	CONFIG_WLAN_NAPI_DEBUG := n
+
+	# Flag to enable FW based TX Flow control
+	ifeq ($(CONFIG_LITHIUM), y)
+		CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y
+	else
+		CONFIG_WLAN_TX_FLOW_CONTROL_V2 := n
+	endif
+
+endif
+endif
+
+CONFIG_POWER_MANAGEMENT_OFFLOAD := y
+
+ifeq ($(CONFIG_ROME_IF), snoc)
+	CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y
+endif
+
+# Flag to enable LFR Subnet Detection
+CONFIG_LFR_SUBNET_DETECTION := y
+
+# Flag to enable MCC to SCC switch feature
+CONFIG_MCC_TO_SCC_SWITCH := y
+
+ifeq ($(CONFIG_SLUB_DEBUG), y)
+	# Enable Obj Mgr Degug services if slub build
+	CONFIG_WLAN_OBJMGR_DEBUG:= y
+	CONFIG_MPC_UT_FRAMEWORK := y
+	CONFIG_LOCK_STATS_ON:= y
+endif
+
+ifeq (y,$(findstring y,$(CONFIG_QCA_WIFI_SDIO) $(CONFIG_HIF_USB)))
+CONFIG_HL_DP_SUPPORT := y
+else
+CONFIG_LL_DP_SUPPORT := y
+endif
+
+ifeq ($(CONFIG_HIF_PCI), y)
+ifneq ($(CONFIG_WLAN_TX_FLOW_CONTROL_V2), y)
+ifneq ($(CONFIG_LITHIUM), y)
+CONFIG_WLAN_TX_FLOW_CONTROL_LEGACY := y
+endif
+endif
+endif
+
+#Whether have QMI support
+CONFIG_QMI_SUPPORT := y
+
+ifeq ($(CONFIG_ICNSS), y)
+CONFIG_WIFI_3_0_ADRASTEA := y
+CONFIG_ADRASTEA_RRI_ON_DDR := y
+# Enable athdiag procfs debug support for adrastea
+CONFIG_ATH_PROCFS_DIAG_SUPPORT := y
+# Enable 11AC TX compact feature for adrastea
+CONFIG_ATH_11AC_TXCOMPACT := y
+ifeq ($(CONFIG_QMI_SUPPORT), y)
+CONFIG_ADRASTEA_SHADOW_REGISTERS := y
+endif
+endif
+
+# NOTE: CONFIG_64BIT_PADDR requires CONFIG_HELIUMPLUS
+ifeq ($(CONFIG_HELIUMPLUS), y)
+CONFIG_AR900B := y
+
+ifeq ($(CONFIG_64BIT_PADDR), y)
+CONFIG_HTT_PADDR64 := y
+endif
+
+ifeq ($(CONFIG_SLUB_DEBUG_ON), y)
+CONFIG_OL_RX_INDICATION_RECORD := y
+CONFIG_TSOSEG_DEBUG := y
+endif
+
+endif #CONFIG_HELIUMPLUS
+
+ifeq ($(CONFIG_LITHIUM), y)
+#
+# Enable Shadow V2 for all lithium platform
+#
+CONFIG_SHADOW_V2 := y
+
+ifeq ($(CONFIG_CNSS_QCA6290), y)
+	CONFIG_QCA6290_HEADERS_DEF := y
+	CONFIG_QCA_WIFI_QCA6290 := y
+endif
+ifeq ($(CONFIG_CNSS_QCA6390), y)
+	CONFIG_QCA6390_HEADERS_DEF := y
+	CONFIG_QCA_WIFI_QCA6390 := y
+endif
+
+CONFIG_QCA_WIFI_QCA8074 := y
+CONFIG_QCA_WIFI_QCA8074_VP := y
+CONFIG_DP_INTR_POLL_BASED := y
+CONFIG_TX_PER_PDEV_DESC_POOL := y
+CONFIG_DP_TRACE := y
+CONFIG_FEATURE_TSO := y
+CONFIG_TSO_DEBUG_LOG_ENABLE := y
+CONFIG_DP_LFR := y
+CONFIG_HTT_PADDR64 := y
+CONFIG_RX_OL := y
+CONFIG_TX_TID_OVERRIDE := y
+endif
+
+# As per target team, build is done as follows:
+# Defconfig : build with default flags
+# Slub      : defconfig  + CONFIG_SLUB_DEBUG=y +
+#	      CONFIG_SLUB_DEBUG_ON=y + CONFIG_PAGE_POISONING=y
+# Perf      : Using appropriate msmXXXX-perf_defconfig
+#
+# Shipment builds (user variants) should not have any debug feature
+# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds
+# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since
+# there is no other way to identify defconfig builds, QCOMs internal
+# representation of perf builds (identified using the string 'perf'),
+# is used to identify if the build is a slub or defconfig one. This
+# way no critical debug feature will be enabled for perf and shipment
+# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT
+# config.
+ifneq ($(TARGET_BUILD_VARIANT),user)
+	ifeq ($(CONFIG_LITHIUM), y)
+		CONFIG_FEATURE_PKTLOG := n
+	else
+		CONFIG_FEATURE_PKTLOG := y
+	endif
+	CONFIG_WLAN_DEBUG_CRASH_INJECT := y
+endif
+
+#Enable WLAN/Power debugfs feature only if debug_fs is enabled
+ifeq ($(CONFIG_DEBUG_FS), y)
+       # Flag to enable debugfs. Depends on CONFIG_DEBUG_FS in kernel
+       # configuration.
+       CONFIG_WLAN_DEBUGFS := y
+
+       CONFIG_WLAN_POWER_DEBUGFS := y
+endif
+
+# Feature flags which are not (currently) configurable via Kconfig
+
+#Whether to build debug version
+BUILD_DEBUG_VERSION := y
+
+#Enable this flag to build driver in diag version
+BUILD_DIAG_VERSION := y
+
+ifeq ($(CONFIG_SLUB_DEBUG), y)
+	PANIC_ON_BUG := y
+	WLAN_WARN_ON_ASSERT := y
+else ifeq ($(CONFIG_PERF_DEBUG), y)
+	PANIC_ON_BUG := y
+	WLAN_WARN_ON_ASSERT := y
+else
+	PANIC_ON_BUG := n
+	WLAN_WARN_ON_ASSERT := n
+endif
+
+# Compile all log levels by default
+CONFIG_WLAN_LOG_FATAL := y
+CONFIG_WLAN_LOG_ERROR := y
+CONFIG_WLAN_LOG_WARN := y
+CONFIG_WLAN_LOG_INFO := y
+CONFIG_WLAN_LOG_DEBUG := y
+CONFIG_WLAN_LOG_ENTER := y
+CONFIG_WLAN_LOG_EXIT := y
+
+#Enable OL debug and wmi unified functions
+CONFIG_ATH_PERF_PWR_OFFLOAD := y
+
+#Disable packet log
+CONFIG_REMOVE_PKT_LOG := n
+
+#Enable 11AC TX
+ifeq ($(CONFIG_ROME_IF),pci)
+	CONFIG_ATH_11AC_TXCOMPACT := y
+endif
+
+ifeq ($(CONFIG_ROME_IF),usb)
+	CONFIG_ATH_11AC_TXCOMPACT := n
+endif
+
+#Enable PCI specific APIS (dma, etc)
+ifeq ($(CONFIG_ROME_IF),pci)
+	CONFIG_HIF_PCI := y
+endif
+
+#Enable USB specific APIS
+ifeq ($(CONFIG_ROME_IF),usb)
+	CONFIG_HIF_USB := y
+endif
+
+#Enable SDIO specific APIS
+ifeq ($(CONFIG_ROME_IF),sdio)
+	CONFIG_HIF_SDIO := y
+	CONFIG_TX_DESC_HI_PRIO_RESERVE := y
+	CONFIG_PER_VDEV_TX_DESC_POOL := y
+	CONFIG_FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL := y
+endif
+
+ifeq ($(CONFIG_ROME_IF),snoc)
+	CONFIG_HIF_SNOC:= y
+endif
+
+# enable/disable feature flags based upon mobile router profile
+ifeq ($(CONFIG_MOBILE_ROUTER), y)
+CONFIG_FEATURE_WLAN_MCC_TO_SCC_SWITCH := y
+CONFIG_FEATURE_WLAN_AUTO_SHUTDOWN := y
+CONFIG_FEATURE_WLAN_AP_AP_ACS_OPTIMIZE := y
+CONFIG_FEATURE_WLAN_STA_4ADDR_SCHEME := y
+CONFIG_MDM_PLATFORM := y
+CONFIG_FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE := y
+CONFIG_FEATURE_AP_MCC_CH_AVOIDANCE := y
+else
+CONFIG_QCOM_ESE := y
+CONFIG_QCA_IBSS_SUPPORT := y
+CONFIG_FEATURE_WLAN_RMC := y
+CONFIG_WLAN_OPEN_P2P_INTERFACE := y
+CONFIG_WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY := y
+endif
+
+#enable 4addr support for QCS405
+ifeq ($(CONFIG_ARCH_QCS405), y)
+CONFIG_FEATURE_WLAN_STA_4ADDR_SCHEME := y
+endif
+
+#Enable power management suspend/resume functionality to PCI
+CONFIG_ATH_BUS_PM := y
+
+#Enable FLOWMAC module support
+CONFIG_ATH_SUPPORT_FLOWMAC_MODULE := n
+
+#Enable spectral support
+CONFIG_ATH_SUPPORT_SPECTRAL := n
+
+#Enable WDI Event support
+ifeq ($(CONFIG_REMOVE_PKT_LOG), y)
+CONFIG_WDI_EVENT_ENABLE := n
+else
+CONFIG_WDI_EVENT_ENABLE := y
+endif
+
+#Endianness selection
+CONFIG_LITTLE_ENDIAN := y
+
+#Enable TX reclaim support
+CONFIG_TX_CREDIT_RECLAIM_SUPPORT := n
+
+#Enable FTM support
+CONFIG_QCA_WIFI_FTM := y
+
+ifeq ($(CONFIG_QCA_WIFI_FTM), y)
+
+ifeq ($(CONFIG_NL80211_TESTMODE), y)
+	QCA_WIFI_FTM_NL80211 :=y
+else
+	QCA_WIFI_FTM_NL80211 :=n
+endif
+	CONFIG_LINUX_QCMBR :=y
+
+else
+	QCA_WIFI_FTM_NL80211 :=n
+	CONFIG_LINUX_QCMBR :=n
+endif
+
+
+#Enable Checksum Offload
+CONFIG_CHECKSUM_OFFLOAD := y
+
+#Enable GTK offload
+CONFIG_GTK_OFFLOAD := y
+
+#Enable EXT WOW
+ifeq ($(CONFIG_HIF_PCI), y)
+	CONFIG_EXT_WOW := y
+endif
+
+#Set this to 1 to catch erroneous Target accesses during debug.
+CONFIG_ATH_PCIE_ACCESS_DEBUG := n
+
+#Enable IPA offload
+ifeq ($(CONFIG_IPA), y)
+CONFIG_IPA_OFFLOAD := y
+endif
+ifeq ($(CONFIG_IPA3), y)
+CONFIG_IPA_OFFLOAD := y
+endif
+
+#Flag to enable SMMU S1 support
+ifeq ($(CONFIG_ARCH_SDM845), y)
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+CONFIG_ENABLE_SMMU_S1_TRANSLATION := y
+endif
+endif
+
+ifeq ($(CONFIG_ARCH_SM8150), y)
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+CONFIG_ENABLE_SMMU_S1_TRANSLATION := y
+endif
+endif
+
+ifeq ($(CONFIG_ARCH_SDX20), y)
+ifeq ($(CONFIG_QCA_WIFI_SDIO), y)
+ifeq ($(CONFIG_WCNSS_SKB_PRE_ALLOC), y)
+CONFIG_FEATURE_SKB_PRE_ALLOC := y
+endif
+endif
+endif
+
+#Enable Signed firmware support for split binary format
+CONFIG_QCA_SIGNED_SPLIT_BINARY_SUPPORT := n
+
+#Enable single firmware binary format
+CONFIG_QCA_SINGLE_BINARY_SUPPORT := n
+
+#Enable collecting target RAM dump after kernel panic
+CONFIG_TARGET_RAMDUMP_AFTER_KERNEL_PANIC := y
+
+#Flag to enable/disable secure firmware feature
+CONFIG_FEATURE_SECURE_FIRMWARE := n
+
+#Flag to enable Stats Ext implementation
+CONFIG_FEATURE_STATS_EXT := y
+
+#Flag to allocate memory dynamically for different buffers
+CONFIG_WLAN_LOGGING_BUFFERS_DYNAMICALLY := n
+CONFIG_WLAN_DFS_STATIC_MEM_ALLOC := y
+
+#Flag to enable HTC credit history feature
+CONFIG_FEATURE_HTC_CREDIT_HISTORY := y
+
+#Flag to enable MTRACE feature
+CONFIG_TRACE_RECORD_FEATURE := y
+
+#Flag to enable p2p debug feature
+CONFIG_WLAN_FEATURE_P2P_DEBUG := y
+
+#Flag to enable roam debug log
+CONFIG_FEATURE_ROAM_DEBUG := y
+
+#Flag to enable DFS Master feature
+CONFIG_WLAN_DFS_MASTER_ENABLE := y
+
+#Flag to enable WEXT support for STA/AP/P2P interfaces
+CONFIG_WLAN_WEXT_SUPPORT_ENABLE := y
+
+#Flag to enable/disable MTRACE feature
+CONFIG_ENABLE_MTRACE_LOG := y
+
+#Flag to enable nud tracking feature
+CONFIG_WLAN_NUD_TRACKING := y
+
+#Flag to enable wbuff feature
+CONFIG_WLAN_WBUFF := y
+
+#Flag to enable set and get disable channel list feature
+CONFIG_DISABLE_CHANNEL_LIST :=y
+
+#Flag to enable Dynamic Voltage WDCVS (Config Voltage Mode)
+CONFIG_WLAN_DYNAMIC_CVM := y
+
+CONFIG_WIFI_POS_CONVERGED := y
+ifneq ($(CONFIG_WIFI_POS_CONVERGED), y)
+CONFIG_WIFI_POS_LEGACY := y
+endif
+
+CONFIG_CP_STATS := y
+
+CONFIG_FEATURE_WLAN_WAPI := y
+
+CONFIG_AGEIE_ON_SCAN_RESULTS := y
+
+#Flag to enable FW log parsing support feature
+CONFIG_FEATURE_FW_LOG_PARSING := y
+
+CONFIG_PTT_SOCK_SVC_ENABLE := y
+CONFIG_SOFTAP_CHANNEL_RANGE := y
+CONFIG_FEATURE_WLAN_SCAN_PNO := y
+CONFIG_WLAN_FEATURE_PACKET_FILTERING := y
+CONFIG_WLAN_NS_OFFLOAD := y
+CONFIG_FEATURE_WLAN_RA_FILTERING:= y
+CONFIG_FEATURE_WLAN_LPHB := y
+CONFIG_QCA_SUPPORT_TX_THROTTLE := y
+CONFIG_WMI_INTERFACE_EVENT_LOGGING := y
+CONFIG_WLAN_FEATURE_LINK_LAYER_STATS := y
+CONFIG_FEATURE_WLAN_EXTSCAN := y
+CONFIG_160MHZ_SUPPORT := y
+CONFIG_MCL := y
+CONFIG_MCL_REGDB := y
+CONFIG_LEGACY_CHAN_ENUM := y
+CONFIG_WLAN_PMO_ENABLE := y
+CONFIG_CONVERGED_P2P_ENABLE := y
+CONFIG_WLAN_POLICY_MGR_ENABLE := y
+CONFIG_SUPPORT_11AX := y
+CONFIG_HDD_INIT_WITH_RTNL_LOCK := y
+CONFIG_CONVERGED_TDLS_ENABLE := y
+CONFIG_WLAN_CONV_SPECTRAL_ENABLE := y
+CONFIG_WLAN_SPECTRAL_ENABLE := y
+CONFIG_WMI_CMD_STRINGS := y
+CONFIG_FEATURE_MONITOR_MODE_SUPPORT := y
+CONFIG_WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY := n
+CONFIG_WLAN_FEATURE_TWT := y
+CONFIG_WLAN_FEATURE_BMI := y
+
+#Flags to enable/disable vendor commands
+CONFIG_FEATURE_RSSI_MONITOR := y
+CONFIG_FEATURE_BSS_TRANSITION := y
+CONFIG_FEATURE_STATION_INFO := y
+CONFIG_FEATURE_TX_POWER := y
+CONFIG_FEATURE_OTA_TEST := y
+CONFIG_FEATURE_ACTIVE_TOS := y
+CONFIG_FEATURE_SAR_LIMITS := y
+CONFIG_FEATURE_CONCURRENCY_MATRIX := y
+CONFIG_FEATURE_SAP_COND_CHAN_SWITCH := y
+CONFIG_FEATURE_P2P_LISTEN_OFFLOAD := y
+
+#Flags to enable/disable WMI APIs
+CONFIG_WMI_ROAM_SUPPORT := y
+CONFIG_WMI_CONCURRENCY_SUPPORT := y
+CONFIG_WMI_STA_SUPPORT := y
+
+ifeq ($(CONFIG_HELIUMPLUS), y)
+ifneq ($(CONFIG_FORCE_ALLOC_FROM_DMA_ZONE), y)
+CONFIG_ENABLE_DEBUG_ADDRESS_MARKING := y
+endif
+CONFIG_RX_OL := y
+endif
+
+ifeq ($(CONFIG_SLUB_DEBUG_ON), y)
+	CONFIG_DSC_DEBUG := y
+	CONFIG_FEATURE_UNIT_TEST_SUSPEND := y
+	CONFIG_LEAK_DETECTION := y
+	CONFIG_MAX_LOGS_PER_SEC := 500
+	CONFIG_SCHED_HISTORY_SIZE := 256
+	CONFIG_UNIT_TEST := y
+	CONFIG_DESC_TIMESTAMP_DEBUG_INFO := y
+endif
+
+ifeq ($(CONFIG_UNIT_TEST), y)
+	CONFIG_DSC_TEST := y
+endif
+
+# enable unit-test suspend for napier builds
+ifeq ($(CONFIG_LITHIUM), y)
+	CONFIG_FEATURE_UNIT_TEST_SUSPEND := y
+endif
+
+#Flag to enable hdd memory dump feature
+CONFIG_FEATURE_MEMDUMP_ENABLE := y
+
+#Flag to enable/disable WLAN D0-WOW
+ifeq ($(CONFIG_PCI_MSM), y)
+ifeq ($(CONFIG_HIF_PCI), y)
+CONFIG_FEATURE_WLAN_D0WOW := y
+endif
+endif
+
+#Enable Channel Matrix restriction for all Rome only targets
+ifneq ($(CONFIG_ICNSS), y)
+CONFIG_CHNL_MATRIX_RESTRICTION := y
+endif
+
+ifeq ($(CONFIG_ARCH_MDM9607), y)
+CONFIG_TUFELLO_DUAL_FW_SUPPORT := y
+endif
+
+ifeq ($(CONFIG_ARCH_MSM8996), y)
+CONFIG_CHANNEL_HOPPING_ALL_BANDS := y
+endif
+
+ifneq ($(CONFIG_HIF_USB), y)
+CONFIG_WLAN_LOGGING_SOCK_SVC := y
+endif
+
+ifneq ($(TARGET_BUILD_VARIANT),user)
+CONFIG_DESC_DUP_DETECT_DEBUG := y
+CONFIG_DEBUG_RX_RING_BUFFER := y
+endif
+
+CONFIG_DP_TRACE := y
+
+ifeq ($(CONFIG_CNSS), y)
+ifeq ($(CONFIG_CNSS_SDIO), y)
+CONFIG_PLD_SDIO_CNSS_FLAG := y
+endif
+ifeq ($(CONFIG_HIF_PCI), y)
+CONFIG_PLD_PCIE_CNSS_FLAG := y
+endif
+endif
+
+ifeq ($(CONFIG_CNSS2), y)
+ifeq ($(CONFIG_HIF_PCI), y)
+CONFIG_PLD_PCIE_CNSS_FLAG := y
+CONFIG_PLD_PCIE_INIT_FLAG := y
+endif
+endif
+
+#Enable STATE MACHINE HISTORY
+CONFIG_SM_ENG_HIST := n
+#Enable VDEV STATE MACHINE
+CONFIG_CMN_VDEV_MLME_SM := n
+CONFIG_VDEV_SM := n
diff --git a/configs/genoa.common b/configs/genoa.common
new file mode 100644
index 0000000..5cc1494
--- /dev/null
+++ b/configs/genoa.common
@@ -0,0 +1,199 @@
+# Protocol specific features
+
+#features not required for GENOA IOT, compilation errors are there.
+CONFIG_SUPPORT_11AX := y
+CONFIG_160MHZ_SUPPORT := y
+CONFIG_FEATURE_STATS_EXT := n
+CONFIG_QCA_IBSS_SUPPORT := y
+
+#required features
+CONFIG_FEATURE_WLAN_RMC := n
+CONFIG_QCACLD_WLAN_LFR2 := y
+CONFIG_QCACLD_WLAN_LFR3 := n
+CONFIG_QCOM_TDLS := y
+CONFIG_QCACLD_FEATURE_GREEN_AP := n
+CONFIG_QCOM_VOWIFI_11R := y
+CONFIG_WLAN_FEATURE_FILS := y
+CONFIG_WLAN_FEATURE_11W := y
+CONFIG_QCOM_LTE_COEX := n
+CONFIG_WLAN_FEATURE_LPSS := n
+CONFIG_QCACLD_FEATURE_NAN := y
+CONFIG_WLAN_FEATURE_NAN_DATAPATH := y
+CONFIG_NAN_CONVERGENCE := y
+CONFIG_POWER_MANAGEMENT_OFFLOAD := y
+CONFIG_LFR_SUBNET_DETECTION := y
+CONFIG_MCC_TO_SCC_SWITCH := y
+CONFIG_QCOM_ESE := n
+CONFIG_WLAN_OPEN_P2P_INTERFACE := y
+CONFIG_WLAN_CONV_SPECTRAL_ENABLE := n
+CONFIG_WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY := y
+CONFIG_WLAN_DFS_MASTER_ENABLE := y
+CONFIG_WIFI_POS_CONVERGED := y
+CONFIG_WIFI_POS_LEGACY := n
+CONFIG_FEATURE_WLAN_WAPI := y
+CONFIG_AGEIE_ON_SCAN_RESULTS := y
+CONFIG_LEGACY_CHAN_ENUM := y
+CONFIG_WLAN_PMO_ENABLE := y
+CONFIG_CONVERGED_P2P_ENABLE := y
+CONFIG_WLAN_POLICY_MGR_ENABLE := y
+CONFIG_HDD_INIT_WITH_RTNL_LOCK := y
+CONFIG_CONVERGED_TDLS_ENABLE := y
+CONFIG_WLAN_FEATURE_TWT := n
+CONFIG_WMI_CMD_STRINGS := y
+CONFIG_SOFTAP_CHANNEL_RANGE := y
+CONFIG_FEATURE_WLAN_SCAN_PNO := y
+CONFIG_WLAN_FEATURE_DSRC := n
+CONFIG_FEATURE_MONITOR_MODE_SUPPORT := n
+CONFIG_DP_TRACE := y
+CONFIG_QCACLD_FEATURE_METERING := n
+
+#Flag to enable Dynamic Voltage WDCVS (Config Voltage Mode)
+CONFIG_WLAN_DYNAMIC_CVM := n
+
+#We might need to disable WEXT support in perf builds in future
+CONFIG_WLAN_WEXT_SUPPORT_ENABLE := y
+CONFIG_HOST_11D_SCAN := y
+
+ifeq ($(CONFIG_ARCH_MSM8996), y)
+CONFIG_CHANNEL_HOPPING_ALL_BANDS := y
+endif
+
+# Debug specific features
+CONFIG_WLAN_LOGGING_BUFFERS_DYNAMICALLY := y
+BUILD_DEBUG_VERSION := y
+BUILD_DIAG_VERSION := n
+
+CONFIG_REMOVE_PKT_LOG := n
+CONFIG_FEATURE_HTC_CREDIT_HISTORY := y
+CONFIG_TRACE_RECORD_FEATURE := y
+CONFIG_WLAN_NUD_TRACKING := n
+CONFIG_CP_STATS := n
+CONFIG_FEATURE_FW_LOG_PARSING := n
+CONFIG_PTT_SOCK_SVC_ENABLE := y
+CONFIG_WMI_INTERFACE_EVENT_LOGGING := y
+CONFIG_WLAN_FEATURE_LINK_LAYER_STATS := n
+CONFIG_FEATURE_ROAM_DEBUG := y
+
+CONFIG_WLAN_LOG_FATAL := y
+CONFIG_WLAN_LOG_ERROR := y
+CONFIG_WLAN_LOG_WARN := y
+CONFIG_WLAN_LOG_INFO := y
+CONFIG_WLAN_LOG_DEBUG := y
+
+ifeq ($(CONFIG_REMOVE_PKT_LOG), y)
+CONFIG_WDI_EVENT_ENABLE := n
+else
+CONFIG_WDI_EVENT_ENABLE := y
+endif
+
+PANIC_ON_BUG := y
+WLAN_WARN_ON_ASSERT := y
+CONFIG_WLAN_LOGGING_SOCK_SVC := y
+
+#Flag to enable wbuff feature
+CONFIG_WLAN_WBUFF := n
+
+# other features
+WLAN_OPEN_SOURCE := y
+CONFIG_ATH_PERF_PWR_OFFLOAD := y
+CONFIG_ATH_BUS_PM := n
+CONFIG_ATH_SUPPORT_FLOWMAC_MODULE := n
+CONFIG_ATH_SUPPORT_SPECTRAL := n
+CONFIG_LITTLE_ENDIAN := y
+CONFIG_ATH_PCIE_ACCESS_DEBUG := n
+CONFIG_QCA_SIGNED_SPLIT_BINARY_SUPPORT := n
+CONFIG_QCA_SINGLE_BINARY_SUPPORT := n
+CONFIG_TARGET_RAMDUMP_AFTER_KERNEL_PANIC := y
+CONFIG_FEATURE_SECURE_FIRMWARE := n
+CONFIG_WLAN_FEATURE_PACKET_FILTERING := n
+CONFIG_WLAN_NS_OFFLOAD := y
+CONFIG_FEATURE_WLAN_RA_FILTERING:= y
+ifeq ($(CONFIG_POWER_MANAGEMENT_OFFLOAD), y)
+CONFIG_FEATURE_WLAN_LPHB := y
+endif
+CONFIG_FEATURE_WLAN_EXTSCAN := n
+CONFIG_MCL := y
+CONFIG_MCL_REGDB := y
+CONFIG_WLAN_OFFLOAD_PACKETS := y
+CONFIG_WLAN_SYNC_TSF := y
+CONFIG_WLAN_FEATURE_DISA := n
+CONFIG_WLAN_FEATURE_FIPS := y
+CONFIG_WLAN_FEATURE_SAE := y
+CONFIG_CHNL_MATRIX_RESTRICTION := n
+CONFIG_WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY := y
+CONFIG_WLAN_FEATURE_BMI := n
+
+#Flags to enable/disable vendor commands
+CONFIG_FEATURE_RSSI_MONITOR := n
+CONFIG_FEATURE_BSS_TRANSITION := n
+CONFIG_FEATURE_STATION_INFO := n
+CONFIG_FEATURE_TX_POWER := n
+CONFIG_FEATURE_OTA_TEST := n
+CONFIG_FEATURE_ACTIVE_TOS := n
+CONFIG_FEATURE_SAR_LIMITS := y
+CONFIG_FEATURE_CONCURRENCY_MATRIX := n
+CONFIG_FEATURE_SAP_COND_CHAN_SWITCH := n
+CONFIG_FEATURE_P2P_LISTEN_OFFLOAD := n
+
+#Flags to enable/disable WMI APIs
+CONFIG_WMI_ROAM_SUPPORT := y
+CONFIG_WMI_CONCURRENCY_SUPPORT := y
+CONFIG_WMI_STA_SUPPORT := y
+
+ifeq ($(CONFIG_ARCH_SDM845), y)
+ifeq ($(CONFIG_IPA_OFFLOAD), y)
+CONFIG_ENABLE_SMMU_S1_TRANSLATION := y
+endif
+endif
+
+#Data Path specific features
+CONFIG_TX_CREDIT_RECLAIM_SUPPORT := n
+CONFIG_CHECKSUM_OFFLOAD := y
+CONFIG_QCA_SUPPORT_TX_THROTTLE := y
+
+ifeq ($(CONFIG_POWER_MANAGEMENT_OFFLOAD), y)
+CONFIG_GTK_OFFLOAD := y
+endif
+CONFIG_QCACLD_FEATURE_APF := y
+
+#Flag to enable SARv1 -> SARv2 conversion
+CONFIG_WLAN_FEATURE_SARV1_TO_SARV2 := n
+
+ifneq ($(DEVELOPER_DISABLE_BUILD_TIMESTAMP), y)
+ifneq ($(WLAN_DISABLE_BUILD_TAG), y)
+CONFIG_BUILD_TAG := y
+endif
+endif
+
+#Buffer allocations dynamically
+ifeq ($(CONFIG_WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY), y)
+CONFIG_WLAN_DFS_STATIC_MEM_ALLOC := n
+endif
+
+# WoW filer configs
+CONFIG_CFG_PMO_WOW_FILTERS_MAX := 16
+
+# Offload configs
+CONFIG_CFG_GTK_OFFLOAD_MAX_VDEV := 2
+CONFIG_CFG_ROAM_OFFLOAD_MAX_VDEV := 1
+
+# Max Periodic Tx Pattern Config
+CONFIG_CFG_MAX_PERIODIC_TX_PTRNS := 2
+
+# Max Sta Vdev Config
+CONFIG_CFG_MAX_STA_VDEVS := 2
+
+# Additional peers sent to firmware
+CONFIG_CFG_NUM_OF_ADDITIONAL_FW_PEERS := 0
+
+# Number of TDLS peers that each Tdls vdev can track
+CONFIG_CFG_NUM_OF_TDLS_CONN_TABLE_ENTRIES := 4
+
+#Number of BSS sessions at a time, used for allocating memory should never be
+#less then number of vdevs - INI
+CONFIG_SIR_MAX_SUPPORTED_BSS := 3
+
+#Number of STA sessions max connected to our SAP, used for allocating memory
+#should never be less then number of max peers - INI
+CONFIG_SIR_SAP_MAX_NUM_PEERS := 10
+###################################
diff --git a/configs/genoa.pci.debug_defconfig b/configs/genoa.pci.debug_defconfig
new file mode 100644
index 0000000..ef83969
--- /dev/null
+++ b/configs/genoa.pci.debug_defconfig
@@ -0,0 +1,114 @@
+
+include $(WLAN_ROOT)/configs/genoa.common
+
+CONFIG_ROME_PCIE := n
+
+# Interface specific features
+CONFIG_ROME_IF = pci
+CONFIG_QMI_SUPPORT := y
+CONFIG_HIF_PCI := y
+CONFIG_EXT_WOW := y
+
+ifeq ($(CONFIG_PCI_MSM), y)
+CONFIG_FEATURE_WLAN_D0WOW := y
+endif
+
+# Data Path specific features
+CONFIG_WLAN_FASTPATH := y
+CONFIG_WLAN_NAPI := y
+CONFIG_ATH_11AC_TXCOMPACT := y
+CONFIG_FEATURE_MONITOR_MODE_SUPPORT := y
+CONFIG_QCA_LL_TX_FLOW_CONTROL_RESIZE := y
+CONFIG_LL_DP_SUPPORT := y
+
+ifeq ($(CONFIG_IPA), y)
+CONFIG_IPA_OFFLOAD := y
+endif
+ifeq ($(CONFIG_IPA3), y)
+CONFIG_IPA_OFFLOAD := y
+endif
+
+# Debug specific features
+CONFIG_MPC_UT_FRAMEWORK := y
+CONFIG_FEATURE_EPPING := y
+CONFIG_WLAN_NAPI_DEBUG := n
+CONFIG_WLAN_FEATURE_P2P_DEBUG := y
+CONFIG_WLAN_LOG_ENTER := y
+CONFIG_WLAN_LOG_EXIT := y
+
+# Features gets enabled on slub debug
+CONFIG_FEATURE_PKTLOG := y
+CONFIG_WLAN_DEBUG_CRASH_INJECT := y
+CONFIG_FEATURE_MEMDUMP_ENABLE := y
+
+ifeq ($(CONFIG_DEBUG_FS), y)
+       CONFIG_WLAN_DEBUGFS := y
+       CONFIG_WLAN_POWER_DEBUGFS := y
+endif
+
+ifeq ($(CONFIG_SLUB_DEBUG_ON), y)
+CONFIG_DESC_DUP_DETECT_DEBUG := y
+CONFIG_DEBUG_RX_RING_BUFFER := y
+CONFIG_WLAN_OBJMGR_DEBUG:= y
+CONFIG_FEATURE_UNIT_TEST_SUSPEND := y
+CONFIG_LEAK_DETECTION := y
+endif
+
+# Genoa features vs Rome PCIe
+ifeq ($(CONFIG_ROME_PCIE), y)
+CONFIG_CHNL_MATRIX_RESTRICTION := y
+CONFIG_WLAN_TX_FLOW_CONTROL_LEGACY := y
+else
+CONFIG_OL_RX_INDICATION_RECORD := y
+CONFIG_TSOSEG_DEBUG := y
+CONFIG_FEATURE_TSO_DEBUG := y
+CONFIG_FEATURE_TSO := y
+CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y
+CONFIG_HELIUMPLUS := y
+CONFIG_64BIT_PADDR := y
+CONFIG_WIFI_3_0_ADRASTEA := y
+CONFIG_ADRASTEA_RRI_ON_DDR := y
+CONFIG_ATH_PROCFS_DIAG_SUPPORT := y
+CONFIG_ADRASTEA_SHADOW_REGISTERS := y
+CONFIG_HTT_PADDR64 := y
+CONFIG_AR900B := y
+CONFIG_RX_OL := y
+
+CONFIG_QCN7605_SUPPORT := y
+CONFIG_HIF_REG_WINDOW_SUPPORT := y
+
+ifneq ($(CONFIG_X86), y)
+ifeq ($(CONFIG_INET_LRO), y)
+CONFIG_WLAN_LRO := y
+else
+CONFIG_WLAN_LRO := n
+endif
+endif
+
+ifneq ($(CONFIG_FORCE_ALLOC_FROM_DMA_ZONE), y)
+CONFIG_ENABLE_DEBUG_ADDRESS_MARKING := y
+endif
+
+endif # CONFIG_ROME_PCIE
+
+ifeq ($(CONFIG_CNSS), y)
+ifeq ($(CONFIG_HIF_PCI), y)
+CONFIG_PLD_PCIE_CNSS_FLAG := y
+endif
+endif
+
+ifeq ($(CONFIG_CNSS2), y)
+ifeq ($(CONFIG_HIF_PCI), y)
+CONFIG_PLD_PCIE_CNSS_FLAG := y
+CONFIG_PLD_PCIE_INIT_FLAG := y
+endif
+endif
+
+CONFIG_QCA_WIFI_FTM := y
+ifeq ($(CONFIG_NL80211_TESTMODE), y)
+	QCA_WIFI_FTM_NL80211 :=y
+else
+	QCA_WIFI_FTM_NL80211 :=n
+endif
+CONFIG_LINUX_QCMBR :=y
+###################################
diff --git a/configs/genoa.pci.perf_defconfig b/configs/genoa.pci.perf_defconfig
new file mode 100644
index 0000000..57d6c49
--- /dev/null
+++ b/configs/genoa.pci.perf_defconfig
@@ -0,0 +1,124 @@
+
+include $(WLAN_ROOT)/configs/genoa.common
+
+CONFIG_ROME_PCIE := n
+
+# Interface specific features
+CONFIG_ROME_IF = pci
+CONFIG_QMI_SUPPORT := y
+CONFIG_HIF_PCI := y
+CONFIG_EXT_WOW := y
+
+ifeq ($(CONFIG_PCI_MSM), y)
+CONFIG_FEATURE_WLAN_D0WOW := y
+endif
+
+# Data Path specific features
+CONFIG_WLAN_FASTPATH := y
+CONFIG_WLAN_NAPI := y
+CONFIG_ATH_11AC_TXCOMPACT := y
+CONFIG_QCA_LL_TX_FLOW_CONTROL_RESIZE := y
+CONFIG_LL_DP_SUPPORT := y
+
+ifeq ($(CONFIG_IPA), y)
+CONFIG_IPA_OFFLOAD := y
+endif
+ifeq ($(CONFIG_IPA3), y)
+CONFIG_IPA_OFFLOAD := y
+endif
+
+# Debug specific features
+CONFIG_MPC_UT_FRAMEWORK := n
+CONFIG_FEATURE_EPPING := n
+CONFIG_WLAN_NAPI_DEBUG := n
+CONFIG_WLAN_FEATURE_P2P_DEBUG := n
+CONFIG_WLAN_LOG_ENTER := n
+CONFIG_WLAN_LOG_EXIT := n
+
+# Features gets enabled on slub debug
+CONFIG_FEATURE_PKTLOG := y
+CONFIG_WLAN_DEBUG_CRASH_INJECT := n
+CONFIG_FEATURE_MEMDUMP_ENABLE := n
+
+ifeq ($(CONFIG_DEBUG_FS), y)
+       CONFIG_WLAN_DEBUGFS := n
+       CONFIG_WLAN_POWER_DEBUGFS := n
+endif
+
+ifeq ($(CONFIG_SLUB_DEBUG_ON), y)
+CONFIG_DESC_DUP_DETECT_DEBUG := n
+CONFIG_DEBUG_RX_RING_BUFFER := n
+CONFIG_WLAN_OBJMGR_DEBUG:= n
+CONFIG_FEATURE_UNIT_TEST_SUSPEND := n
+CONFIG_LEAK_DETECTION := n
+endif
+
+# Genoa features vs Rome PCIe
+ifeq ($(CONFIG_ROME_PCIE), y)
+CONFIG_CHNL_MATRIX_RESTRICTION := y
+CONFIG_WLAN_TX_FLOW_CONTROL_LEGACY := y
+else
+CONFIG_OL_RX_INDICATION_RECORD := y
+CONFIG_TSOSEG_DEBUG := n
+CONFIG_FEATURE_TSO_DEBUG := n
+CONFIG_FEATURE_TSO := y
+CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y
+CONFIG_HELIUMPLUS := y
+CONFIG_64BIT_PADDR := y
+CONFIG_WIFI_3_0_ADRASTEA := y
+CONFIG_ADRASTEA_RRI_ON_DDR := y
+CONFIG_ATH_PROCFS_DIAG_SUPPORT := y
+CONFIG_ADRASTEA_SHADOW_REGISTERS := y
+CONFIG_HTT_PADDR64 := y
+CONFIG_AR900B := y
+CONFIG_RX_OL := y
+
+CONFIG_QCN7605_SUPPORT := y
+CONFIG_HIF_REG_WINDOW_SUPPORT := y
+
+ifneq ($(CONFIG_X86), y)
+ifeq ($(CONFIG_INET_LRO), y)
+CONFIG_WLAN_LRO := y
+else
+CONFIG_WLAN_LRO := n
+endif
+endif
+
+ifneq ($(CONFIG_FORCE_ALLOC_FROM_DMA_ZONE), y)
+CONFIG_ENABLE_DEBUG_ADDRESS_MARKING := y
+endif
+
+endif # CONFIG_ROME_PCIE
+
+ifeq ($(CONFIG_CNSS), y)
+ifeq ($(CONFIG_HIF_PCI), y)
+CONFIG_PLD_PCIE_CNSS_FLAG := y
+endif
+endif
+
+ifeq ($(CONFIG_CNSS2), y)
+ifeq ($(CONFIG_HIF_PCI), y)
+CONFIG_PLD_PCIE_CNSS_FLAG := y
+CONFIG_PLD_PCIE_INIT_FLAG := y
+endif
+endif
+
+CONFIG_QCA_WIFI_FTM := n
+QCA_WIFI_FTM_NL80211 := n
+CONFIG_LINUX_QCMBR := n
+
+###################################
+CONFIG_ENABLE_SIZE_OPTIMIZE := y
+
+# configure log buffer size
+CONFIG_CFG_NUM_DP_TRACE_RECORD := 1000
+CONFIG_CFG_NUM_HTC_CREDIT_HISTORY := 16
+CONFIG_CFG_NUM_WMI_EVENT_HISTORY := 16
+CONFIG_CFG_NUM_WMI_MGMT_EVENT_HISTORY := 16
+CONFIG_CFG_NUM_TX_RX_HISTOGRAM := 16
+CONFIG_CFG_NUM_RX_IND_RECORD := 1024
+
+ifeq ($(CONFIG_FEATURE_ROAM_DEBUG), y)
+CONFIG_CFG_NUM_ROAM_DEBUG_RECORD := 64
+endif
+###################################
diff --git a/configs/genoa.sdio.debug_defconfig b/configs/genoa.sdio.debug_defconfig
new file mode 100644
index 0000000..8534cdb
--- /dev/null
+++ b/configs/genoa.sdio.debug_defconfig
@@ -0,0 +1,50 @@
+
+include $(WLAN_ROOT)/configs/genoa.common
+
+# Interface specific features
+CONFIG_CLD_HL_SDIO_CORE := y
+CONFIG_QCA_WIFI_SDIO := y
+CONFIG_ROME_IF = sdio
+CONFIG_HIF_SDIO := y
+CONFIG_LINUX_QCMBR := y
+CONFIG_SDIO_TRANSFER = mailbox
+
+# Data Path specific features
+CONFIG_ATH_11AC_TXCOMPACT := n
+CONFIG_QCA_HL_NETDEV_FLOW_CONTROL := y
+CONFIG_FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL := y
+CONFIG_FEATURE_HL_DBS_GROUP_CREDIT_SHARING := y
+CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE := y
+CONFIG_HL_DP_SUPPORT := y
+
+# Debug specific features
+CONFIG_MPC_UT_FRAMEWORK := y
+CONFIG_FEATURE_EPPING := y
+CONFIG_WLAN_FEATURE_P2P_DEBUG := y
+CONFIG_WLAN_LOG_ENTER := y
+CONFIG_WLAN_LOG_EXIT := y
+
+ifeq ($(CONFIG_DEBUG_FS), y)
+       CONFIG_WLAN_DEBUGFS := y
+       CONFIG_WLAN_POWER_DEBUGFS := y
+endif
+
+# Features gets enabled on slub debug
+CONFIG_FEATURE_PKTLOG := y
+CONFIG_WLAN_DEBUG_CRASH_INJECT := y
+CONFIG_FEATURE_MEMDUMP_ENABLE := y
+
+ifeq ($(CONFIG_SLUB_DEBUG_ON), y)
+CONFIG_WLAN_OBJMGR_DEBUG:= y
+CONFIG_FEATURE_UNIT_TEST_SUSPEND := y
+CONFIG_LEAK_DETECTION := y
+endif
+
+CONFIG_QCA_WIFI_FTM := y
+ifeq ($(CONFIG_NL80211_TESTMODE), y)
+	QCA_WIFI_FTM_NL80211 :=y
+else
+	QCA_WIFI_FTM_NL80211 :=n
+endif
+CONFIG_LINUX_QCMBR :=y
+###################################
diff --git a/configs/genoa.sdio.perf_defconfig b/configs/genoa.sdio.perf_defconfig
new file mode 100644
index 0000000..f6c4357
--- /dev/null
+++ b/configs/genoa.sdio.perf_defconfig
@@ -0,0 +1,56 @@
+
+include $(WLAN_ROOT)/configs/genoa.common
+
+# Interface specific features
+CONFIG_CLD_HL_SDIO_CORE := y
+CONFIG_QCA_WIFI_SDIO := y
+CONFIG_ROME_IF = sdio
+CONFIG_HIF_SDIO := y
+CONFIG_LINUX_QCMBR := y
+CONFIG_SDIO_TRANSFER = mailbox
+
+# Data Path specific features
+CONFIG_ATH_11AC_TXCOMPACT := n
+CONFIG_QCA_HL_NETDEV_FLOW_CONTROL := y
+CONFIG_FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL := y
+CONFIG_FEATURE_HL_DBS_GROUP_CREDIT_SHARING := y
+CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE := y
+CONFIG_HL_DP_SUPPORT := y
+
+# Debug specific features
+CONFIG_MPC_UT_FRAMEWORK := n
+CONFIG_FEATURE_EPPING := n
+CONFIG_WLAN_FEATURE_P2P_DEBUG := n
+CONFIG_WLAN_LOG_ENTER := n
+CONFIG_WLAN_LOG_EXIT := n
+
+# Features gets enabled on slub debug
+CONFIG_FEATURE_PKTLOG := y
+CONFIG_WLAN_DEBUG_CRASH_INJECT := n
+CONFIG_FEATURE_MEMDUMP_ENABLE := n
+
+ifeq ($(CONFIG_SLUB_DEBUG_ON), y)
+CONFIG_WLAN_OBJMGR_DEBUG:= n
+CONFIG_FEATURE_UNIT_TEST_SUSPEND := n
+CONFIG_LEAK_DETECTION := n
+endif
+
+
+CONFIG_ENABLE_SIZE_OPTIMIZE := y
+
+# configure log buffer size
+CONFIG_CFG_NUM_DP_TRACE_RECORD := 1000
+CONFIG_CFG_NUM_HTC_CREDIT_HISTORY := 16
+CONFIG_CFG_NUM_WMI_EVENT_HISTORY := 16
+CONFIG_CFG_NUM_WMI_MGMT_EVENT_HISTORY := 16
+CONFIG_CFG_NUM_TX_RX_HISTOGRAM := 16
+CONFIG_CFG_NUM_RX_IND_RECORD := 1024
+
+ifeq ($(CONFIG_FEATURE_ROAM_DEBUG), y)
+CONFIG_CFG_NUM_ROAM_DEBUG_RECORD := 64
+endif
+
+CONFIG_QCA_WIFI_FTM := n
+QCA_WIFI_FTM_NL80211 := n
+CONFIG_LINUX_QCMBR := n
+###################################
diff --git a/configs/genoa.snoc.debug_defconfig b/configs/genoa.snoc.debug_defconfig
new file mode 100644
index 0000000..5e0f7da
--- /dev/null
+++ b/configs/genoa.snoc.debug_defconfig
@@ -0,0 +1,89 @@
+
+include $(WLAN_ROOT)/configs/genoa.common
+
+# Interface specific features
+CONFIG_ROME_IF = snoc
+CONFIG_HELIUMPLUS := y
+CONFIG_64BIT_PADDR := y
+CONFIG_QMI_SUPPORT := y
+CONFIG_WIFI_3_0_ADRASTEA := y
+CONFIG_ADRASTEA_RRI_ON_DDR := y
+CONFIG_ATH_PROCFS_DIAG_SUPPORT := y
+CONFIG_ADRASTEA_SHADOW_REGISTERS := y
+CONFIG_HTT_PADDR64 := y
+CONFIG_AR900B := y
+CONFIG_HIF_SNOC:= y
+
+# Genoa specific features
+CONFIG_QCA_LL_TX_FLOW_CONTROL_RESIZE := y
+
+# Data Path specific features
+CONFIG_WLAN_FASTPATH := y
+CONFIG_FEATURE_TSO := y
+CONFIG_WLAN_NAPI := y
+CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y
+CONFIG_ATH_11AC_TXCOMPACT := y
+CONFIG_RX_OL := y
+CONFIG_DESC_DUP_DETECT_DEBUG := y
+CONFIG_DEBUG_RX_RING_BUFFER := y
+CONFIG_LL_DP_SUPPORT := y
+
+ifeq ($(CONFIG_INET_LRO), y)
+CONFIG_WLAN_LRO := y
+else
+CONFIG_WLAN_LRO := n
+endif
+
+ifeq ($(CONFIG_IPA), y)
+CONFIG_IPA_OFFLOAD := y
+endif
+ifeq ($(CONFIG_IPA3), y)
+CONFIG_IPA_OFFLOAD := y
+endif
+
+ifneq ($(CONFIG_FORCE_ALLOC_FROM_DMA_ZONE), y)
+CONFIG_ENABLE_DEBUG_ADDRESS_MARKING := y
+endif
+
+# Debug specific features
+CONFIG_FEATURE_TSO_DEBUG := y
+CONFIG_WLAN_NAPI_DEBUG := n
+CONFIG_WLAN_FEATURE_P2P_DEBUG := y
+CONFIG_MPC_UT_FRAMEWORK := y
+CONFIG_FEATURE_EPPING := y
+CONFIG_WLAN_LOG_ENTER := y
+CONFIG_WLAN_LOG_EXIT := y
+
+# Features gets enabled on slub debug
+CONFIG_WLAN_OBJMGR_DEBUG:= y
+CONFIG_OL_RX_INDICATION_RECORD := y
+CONFIG_TSOSEG_DEBUG := y
+CONFIG_FEATURE_PKTLOG := y
+CONFIG_WLAN_DEBUG_CRASH_INJECT := y
+CONFIG_FEATURE_MEMDUMP_ENABLE := y
+CONFIG_FEATURE_UNIT_TEST_SUSPEND := y
+CONFIG_LEAK_DETECTION := y
+
+ifeq ($(CONFIG_DEBUG_FS), y)
+       CONFIG_WLAN_DEBUGFS := y
+       CONFIG_WLAN_POWER_DEBUGFS := y
+endif
+
+# other features
+CONFIG_QCA_WIFI_FTM := y
+ifeq ($(CONFIG_NL80211_TESTMODE), y)
+	QCA_WIFI_FTM_NL80211 :=y
+else
+	QCA_WIFI_FTM_NL80211 :=n
+endif
+CONFIG_LINUX_QCMBR :=y
+
+#Flag to enable Dynamic Voltage WDCVS (Config Voltage Mode)
+CONFIG_WLAN_DYNAMIC_CVM := y
+ifeq ($(CONFIG_CNSS2), y)
+ifeq ($(CONFIG_HIF_PCI), y)
+CONFIG_PLD_PCIE_CNSS_FLAG := y
+CONFIG_PLD_PCIE_INIT_FLAG := y
+endif
+endif
+###################################
diff --git a/configs/genoa.snoc.perf_defconfig b/configs/genoa.snoc.perf_defconfig
new file mode 100644
index 0000000..bc6eda6
--- /dev/null
+++ b/configs/genoa.snoc.perf_defconfig
@@ -0,0 +1,98 @@
+
+include $(WLAN_ROOT)/configs/genoa.common
+
+# Interface specific features
+CONFIG_ROME_IF = snoc
+CONFIG_HELIUMPLUS := y
+CONFIG_64BIT_PADDR := y
+CONFIG_QMI_SUPPORT := y
+CONFIG_WIFI_3_0_ADRASTEA := y
+CONFIG_ADRASTEA_RRI_ON_DDR := y
+CONFIG_ATH_PROCFS_DIAG_SUPPORT := y
+CONFIG_ADRASTEA_SHADOW_REGISTERS := y
+CONFIG_HTT_PADDR64 := y
+CONFIG_AR900B := y
+CONFIG_HIF_SNOC:= y
+
+# Genoa specific features
+CONFIG_QCA_LL_TX_FLOW_CONTROL_RESIZE := y
+
+# Data Path specific features
+CONFIG_WLAN_FASTPATH := y
+CONFIG_FEATURE_TSO := y
+CONFIG_WLAN_NAPI := y
+CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y
+CONFIG_ATH_11AC_TXCOMPACT := y
+CONFIG_RX_OL := y
+CONFIG_DESC_DUP_DETECT_DEBUG := n
+CONFIG_DEBUG_RX_RING_BUFFER := n
+CONFIG_LL_DP_SUPPORT := y
+
+ifeq ($(CONFIG_INET_LRO), y)
+CONFIG_WLAN_LRO := y
+else
+CONFIG_WLAN_LRO := n
+endif
+
+ifeq ($(CONFIG_IPA), y)
+CONFIG_IPA_OFFLOAD := y
+endif
+ifeq ($(CONFIG_IPA3), y)
+CONFIG_IPA_OFFLOAD := y
+endif
+
+ifneq ($(CONFIG_FORCE_ALLOC_FROM_DMA_ZONE), y)
+CONFIG_ENABLE_DEBUG_ADDRESS_MARKING := y
+endif
+
+CONFIG_FEATURE_TSO_DEBUG := n
+CONFIG_WLAN_NAPI_DEBUG := n
+CONFIG_WLAN_FEATURE_P2P_DEBUG := n
+CONFIG_MPC_UT_FRAMEWORK := n
+CONFIG_FEATURE_EPPING := n
+CONFIG_WLAN_LOG_ENTER := n
+CONFIG_WLAN_LOG_EXIT := n
+
+CONFIG_QCA_WIFI_FTM := n
+QCA_WIFI_FTM_NL80211 := n
+CONFIG_LINUX_QCMBR := n
+
+#Flag to enable Dynamic Voltage WDCVS (Config Voltage Mode)
+CONFIG_WLAN_DYNAMIC_CVM := y
+
+# Features gets enabled on slub debug
+CONFIG_WLAN_OBJMGR_DEBUG:= n
+CONFIG_FEATURE_MEMDUMP_ENABLE := n
+CONFIG_FEATURE_UNIT_TEST_SUSPEND := n
+CONFIG_OL_RX_INDICATION_RECORD := n
+CONFIG_TSOSEG_DEBUG := n
+CONFIG_FEATURE_PKTLOG := n
+CONFIG_WLAN_DEBUG_CRASH_INJECT := n
+CONFIG_LEAK_DETECTION := n
+
+ifeq ($(CONFIG_DEBUG_FS), y)
+       CONFIG_WLAN_DEBUGFS := n
+       CONFIG_WLAN_POWER_DEBUGFS := n
+endif
+
+ifeq ($(CONFIG_CNSS2), y)
+ifeq ($(CONFIG_HIF_PCI), y)
+CONFIG_PLD_PCIE_CNSS_FLAG := y
+CONFIG_PLD_PCIE_INIT_FLAG := y
+endif
+endif
+
+CONFIG_ENABLE_SIZE_OPTIMIZE := y
+
+# configure log buffer size
+CONFIG_CFG_NUM_DP_TRACE_RECORD := 1000
+CONFIG_CFG_NUM_HTC_CREDIT_HISTORY := 16
+CONFIG_CFG_NUM_WMI_EVENT_HISTORY := 16
+CONFIG_CFG_NUM_WMI_MGMT_EVENT_HISTORY := 16
+CONFIG_CFG_NUM_TX_RX_HISTOGRAM := 16
+CONFIG_CFG_NUM_RX_IND_RECORD := 1024
+
+ifeq ($(CONFIG_FEATURE_ROAM_DEBUG), y)
+CONFIG_CFG_NUM_ROAM_DEBUG_RECORD := 64
+endif
+###################################
diff --git a/configs/genoa.usb.debug_defconfig b/configs/genoa.usb.debug_defconfig
new file mode 100644
index 0000000..defdbe6
--- /dev/null
+++ b/configs/genoa.usb.debug_defconfig
@@ -0,0 +1,51 @@
+
+include $(WLAN_ROOT)/configs/genoa.common
+
+# Interface specific features
+CONFIG_ROME_IF := usb
+CONFIG_HIF_USB := y
+CONFIG_LINUX_QCMBR := y
+CONFIG_PLD_USB_CNSS := y
+
+# Data Path specific features
+CONFIG_ATH_11AC_TXCOMPACT := n
+CONFIG_QCA_HL_NETDEV_FLOW_CONTROL := y
+CONFIG_FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL := y
+CONFIG_FEATURE_HL_DBS_GROUP_CREDIT_SHARING := y
+CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE := y
+CONFIG_HL_DP_SUPPORT := y
+
+# Debug specific features
+CONFIG_MPC_UT_FRAMEWORK := y
+CONFIG_FEATURE_EPPING := y
+CONFIG_WLAN_FEATURE_P2P_DEBUG := y
+CONFIG_WLAN_LOG_ENTER := y
+CONFIG_WLAN_LOG_EXIT := y
+
+ifeq ($(CONFIG_DEBUG_FS), y)
+       CONFIG_WLAN_DEBUGFS := y
+       CONFIG_WLAN_POWER_DEBUGFS := y
+endif
+
+# Features gets enabled on slub debug
+CONFIG_FEATURE_PKTLOG := y
+CONFIG_WLAN_DEBUG_CRASH_INJECT := y
+CONFIG_FEATURE_MEMDUMP_ENABLE := y
+
+ifeq ($(CONFIG_SLUB_DEBUG_ON), y)
+CONFIG_WLAN_OBJMGR_DEBUG:= y
+CONFIG_FEATURE_UNIT_TEST_SUSPEND := y
+CONFIG_LEAK_DETECTION := y
+endif
+
+# Genoa features vs Rome
+CONFIG_HTT_PADDR64 := y
+
+CONFIG_QCA_WIFI_FTM := y
+ifeq ($(CONFIG_NL80211_TESTMODE), y)
+	QCA_WIFI_FTM_NL80211 :=y
+else
+	QCA_WIFI_FTM_NL80211 :=n
+endif
+CONFIG_LINUX_QCMBR :=y
+###################################
diff --git a/configs/genoa.usb.perf_defconfig b/configs/genoa.usb.perf_defconfig
new file mode 100644
index 0000000..88f74e4
--- /dev/null
+++ b/configs/genoa.usb.perf_defconfig
@@ -0,0 +1,57 @@
+
+include $(WLAN_ROOT)/configs/genoa.common
+
+# Interface specific features
+CONFIG_ROME_IF := usb
+CONFIG_HIF_USB := y
+CONFIG_LINUX_QCMBR := y
+CONFIG_PLD_USB_CNSS := y
+
+# Data Path specific features
+CONFIG_ATH_11AC_TXCOMPACT := n
+CONFIG_QCA_HL_NETDEV_FLOW_CONTROL := y
+CONFIG_FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL := y
+CONFIG_FEATURE_HL_DBS_GROUP_CREDIT_SHARING := y
+CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE := y
+CONFIG_HL_DP_SUPPORT := y
+
+# Debug specific features
+CONFIG_MPC_UT_FRAMEWORK := n
+CONFIG_FEATURE_EPPING := n
+CONFIG_WLAN_FEATURE_P2P_DEBUG := n
+CONFIG_WLAN_LOG_ENTER := n
+CONFIG_WLAN_LOG_EXIT := n
+
+# Features gets enabled on slub debug
+CONFIG_FEATURE_PKTLOG := y
+CONFIG_WLAN_DEBUG_CRASH_INJECT := n
+CONFIG_FEATURE_MEMDUMP_ENABLE := n
+
+ifeq ($(CONFIG_SLUB_DEBUG_ON), y)
+CONFIG_WLAN_OBJMGR_DEBUG:= n
+CONFIG_FEATURE_UNIT_TEST_SUSPEND := n
+CONFIG_LEAK_DETECTION := n
+endif
+
+
+CONFIG_ENABLE_SIZE_OPTIMIZE := y
+
+# configure log buffer size
+CONFIG_CFG_NUM_DP_TRACE_RECORD := 1000
+CONFIG_CFG_NUM_HTC_CREDIT_HISTORY := 16
+CONFIG_CFG_NUM_WMI_EVENT_HISTORY := 16
+CONFIG_CFG_NUM_WMI_MGMT_EVENT_HISTORY := 16
+CONFIG_CFG_NUM_TX_RX_HISTOGRAM := 16
+CONFIG_CFG_NUM_RX_IND_RECORD := 1024
+
+ifeq ($(CONFIG_FEATURE_ROAM_DEBUG), y)
+CONFIG_CFG_NUM_ROAM_DEBUG_RECORD := 64
+endif
+
+# Genoa features vs Rome
+CONFIG_HTT_PADDR64 := y
+
+CONFIG_QCA_WIFI_FTM := n
+QCA_WIFI_FTM_NL80211 := n
+CONFIG_LINUX_QCMBR := n
+###################################
diff --git a/core/bmi/inc/bmi.h b/core/bmi/inc/bmi.h
new file mode 100644
index 0000000..583a1b1
--- /dev/null
+++ b/core/bmi/inc/bmi.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/* ================================================================ */
+/* BMI declarations and prototypes */
+/* */
+/* ================================================================= */
+
+#ifndef _BMI_H_
+#define _BMI_H_
+#include "bmi_msg.h"
+#include "qdf_trace.h"
+#include "ol_if_athvar.h"
+#include "hif.h"
+
+struct ol_context;
+
+/**
+ * struct hif_config_info - Place Holder for hif confiruation
+ * @enable_uart_print: UART Print
+ * @enable_self_recovery: Self Recovery
+ * @enable_fw_log:      To Enable FW LOG
+ * @enable_lpass_support: LPASS support
+ * @enable_ramdump_collection: Ramdump Collection
+ *
+ * Structure for holding ini parameters.
+ */
+
+struct ol_config_info {
+	bool enable_uart_print;
+	bool enable_self_recovery;
+	uint8_t enable_fw_log;
+	bool enable_lpass_support;
+	bool enable_ramdump_collection;
+};
+
+#ifdef WLAN_FEATURE_BMI
+QDF_STATUS ol_cds_init(qdf_device_t qdf_dev, void *hif_ctx);
+void ol_cds_free(void);
+void ol_init_ini_config(struct ol_context *ol_ctx,
+			struct ol_config_info *cfg);
+void bmi_cleanup(struct ol_context *scn);
+QDF_STATUS bmi_done(struct ol_context *ol_ctx);
+void bmi_target_ready(struct hif_opaque_softc *scn, void *cfg_ctx);
+QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx);
+
+#else /* WLAN_FEATURE_BMI */
+
+static inline QDF_STATUS
+ol_cds_init(qdf_device_t qdf_dev, void *hif_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void ol_cds_free(void)
+{
+}
+
+static inline void
+ol_init_ini_config(struct ol_context *ol_ctx, struct ol_config_info *cfg)
+{
+}
+
+static inline void bmi_cleanup(struct ol_context *scn)
+{
+}
+
+static inline QDF_STATUS bmi_done(struct ol_context *ol_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void
+bmi_target_ready(struct hif_opaque_softc *scn, void *cfg_ctx)
+{
+}
+
+static inline QDF_STATUS
+bmi_download_firmware(struct ol_context *ol_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_BMI */
+
+#endif /* _BMI_H_ */
diff --git a/core/bmi/inc/ol_fw.h b/core/bmi/inc/ol_fw.h
new file mode 100644
index 0000000..d4af7dc
--- /dev/null
+++ b/core/bmi/inc/ol_fw.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014-2016, 2018 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.
+ */
+
+#ifndef _OL_FW_H_
+#define _OL_FW_H_
+
+#include "qdf_types.h"
+#include "hif.h"
+#include "hif_hw_version.h"
+#include "bmi.h"
+
+#define AR6320_REV2_VERSION          AR6320_REV1_1_VERSION
+#define AR6320_REV4_VERSION          AR6320_REV2_1_VERSION
+#define SIGN_HEADER_MAGIC            0x454D4F52
+#define HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET          (1 << 0)
+#define HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET       (1 << 1)
+#define HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE           (1 << 2)
+
+#define HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_FW_ACK       (1 << 16)
+#define HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_FW_ACK    (1 << 17)
+
+#ifdef WLAN_FEATURE_BMI
+void ol_target_failure(void *instance, QDF_STATUS status);
+
+void ol_target_ready(struct hif_opaque_softc *scn, void *cfg_ctx);
+QDF_STATUS ol_get_fw_files(struct ol_context *ol_ctx);
+QDF_STATUS ol_extra_initialization(struct ol_context *ol_ctx);
+#else /* WLAN_FEATURE_BMI */
+static inline void ol_target_failure(void *instance, QDF_STATUS status) {}
+#endif /* WLAN_FEATURE_BMI */
+#endif /* _OL_FW_H_ */
diff --git a/core/bmi/inc/ol_if_athvar.h b/core/bmi/inc/ol_if_athvar.h
new file mode 100644
index 0000000..0f8f03b
--- /dev/null
+++ b/core/bmi/inc/ol_if_athvar.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014-2016, 2018 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.
+ */
+
+/*
+ * Definitions for the Atheros Wireless LAN controller driver.
+ */
+#ifndef _DEV_OL_ATH_ATHVAR_H
+#define _DEV_OL_ATH_ATHVAR_H
+
+#include <osapi_linux.h>
+#include "qdf_types.h"
+#include "qdf_lock.h"
+#include "wmi_unified_api.h"
+#include "htc_api.h"
+#include "bmi_msg.h"
+#include "ol_params.h"
+#include <wdi_event_api.h>
+
+#include "ol_ctrl_addba_api.h"
+
+struct ol_version {
+	uint32_t host_ver;
+	uint32_t target_ver;
+	uint32_t wlan_ver;
+	uint32_t wlan_ver_1;
+	uint32_t abi_ver;
+};
+
+enum ol_ath_tx_ecodes {
+	TX_IN_PKT_INCR = 0,
+	TX_OUT_HDR_COMPL,
+	TX_OUT_PKT_COMPL,
+	PKT_ENCAP_FAIL,
+	TX_PKT_BAD,
+	RX_RCV_MSG_RX_IND,
+	RX_RCV_MSG_PEER_MAP,
+	RX_RCV_MSG_TYPE_TEST
+};
+
+/*
+ * structure to hold the packet error count for CE and hif layer
+ */
+struct ol_ath_stats {
+	int hif_pipe_no_resrc_count;
+	int ce_ring_delta_fail_count;
+};
+
+#endif /* _DEV_OL_ATH_ATHVAR_H  */
diff --git a/core/bmi/src/bmi.c b/core/bmi/src/bmi.c
new file mode 100644
index 0000000..ab6d5dc
--- /dev/null
+++ b/core/bmi/src/bmi.c
@@ -0,0 +1,577 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#include "i_bmi.h"
+#include "cds_api.h"
+
+/* APIs visible to the driver */
+
+QDF_STATUS bmi_init(struct ol_context *ol_ctx)
+{
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
+
+	if (!scn) {
+		BMI_ERR("Invalid scn Context");
+		bmi_assert(0);
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	if (!qdf_dev->dev) {
+		BMI_ERR("%s: Invalid Device Pointer", __func__);
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	info->bmi_done = false;
+
+	if (!info->bmi_cmd_buff) {
+		info->bmi_cmd_buff =
+			qdf_mem_alloc_consistent(qdf_dev, qdf_dev->dev,
+						 MAX_BMI_CMDBUF_SZ,
+						 &info->bmi_cmd_da);
+		if (!info->bmi_cmd_buff) {
+			BMI_ERR("No Memory for BMI Command");
+			return QDF_STATUS_E_NOMEM;
+		}
+	}
+
+	if (!info->bmi_rsp_buff) {
+		info->bmi_rsp_buff =
+			qdf_mem_alloc_consistent(qdf_dev, qdf_dev->dev,
+						 MAX_BMI_CMDBUF_SZ,
+						 &info->bmi_rsp_da);
+		if (!info->bmi_rsp_buff) {
+			BMI_ERR("No Memory for BMI Response");
+			goto end;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+end:
+	qdf_mem_free_consistent(qdf_dev, qdf_dev->dev, MAX_BMI_CMDBUF_SZ,
+				 info->bmi_cmd_buff, info->bmi_cmd_da, 0);
+	info->bmi_cmd_buff = NULL;
+	return QDF_STATUS_E_NOMEM;
+}
+
+void bmi_cleanup(struct ol_context *ol_ctx)
+{
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	qdf_device_t qdf_dev;
+
+	if (!info || !ol_ctx) {
+		BMI_WARN("%s: no bmi to cleanup", __func__);
+		return;
+	}
+
+	qdf_dev = ol_ctx->qdf_dev;
+	if (!qdf_dev || !qdf_dev->dev) {
+		BMI_ERR("%s: Invalid Device Pointer", __func__);
+		return;
+	}
+
+	if (info->bmi_cmd_buff) {
+		qdf_mem_free_consistent(qdf_dev, qdf_dev->dev,
+					MAX_BMI_CMDBUF_SZ,
+				    info->bmi_cmd_buff, info->bmi_cmd_da, 0);
+		info->bmi_cmd_buff = NULL;
+		info->bmi_cmd_da = 0;
+	}
+
+	if (info->bmi_rsp_buff) {
+		qdf_mem_free_consistent(qdf_dev, qdf_dev->dev,
+					MAX_BMI_CMDBUF_SZ,
+				    info->bmi_rsp_buff, info->bmi_rsp_da, 0);
+		info->bmi_rsp_buff = NULL;
+		info->bmi_rsp_da = 0;
+	}
+}
+
+/**
+ * bmi_done() - finish the bmi opperation
+ * @ol_ctx: the bmi context
+ *
+ * does some sanity checking.
+ * exchanges one last message with firmware.
+ * frees some buffers.
+ *
+ * Return: QDF_STATUS_SUCCESS if bmi isn't needed.
+ *	QDF_STATUS_SUCCESS if bmi finishes.
+ *	otherwise returns failure.
+ */
+QDF_STATUS bmi_done(struct ol_context *ol_ctx)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (NO_BMI)
+		return QDF_STATUS_SUCCESS;
+
+	if (!ol_ctx) {
+		BMI_ERR("%s: null context", __func__);
+		return QDF_STATUS_E_NOMEM;
+	}
+	hif_claim_device(ol_ctx->scn);
+
+	if (!hif_needs_bmi(ol_ctx->scn))
+		return QDF_STATUS_SUCCESS;
+
+	status = bmi_done_local(ol_ctx);
+	if (status != QDF_STATUS_SUCCESS)
+		BMI_ERR("BMI_DONE Failed status:%d", status);
+
+	return status;
+}
+
+void bmi_target_ready(struct hif_opaque_softc *scn, void *cfg_ctx)
+{
+	ol_target_ready(scn, cfg_ctx);
+}
+
+static QDF_STATUS
+bmi_get_target_info_message_based(struct bmi_target_info *targ_info,
+						struct ol_context *ol_ctx)
+{
+	int status = 0;
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
+	uint8_t *bmi_rsp_buff = info->bmi_rsp_buff;
+	uint32_t cid, length;
+	qdf_dma_addr_t cmd = info->bmi_cmd_da;
+	qdf_dma_addr_t rsp = info->bmi_rsp_da;
+
+	if (!bmi_cmd_buff || !bmi_rsp_buff) {
+		BMI_ERR("%s:BMI CMD/RSP Buffer is NULL", __func__);
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	cid = BMI_GET_TARGET_INFO;
+
+	qdf_mem_copy(bmi_cmd_buff, &cid, sizeof(cid));
+	length = sizeof(struct bmi_target_info);
+
+	status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, sizeof(cid),
+					(uint8_t *)bmi_rsp_buff, &length,
+					BMI_EXCHANGE_TIMEOUT_MS);
+	if (status) {
+		BMI_ERR("Failed to target info: status:%d", status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_copy(targ_info, bmi_rsp_buff, length);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+bmi_get_target_info(struct bmi_target_info *targ_info,
+						struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	QDF_STATUS status;
+
+	if (info->bmi_done) {
+		BMI_ERR("BMI Phase is Already Done");
+		return QDF_STATUS_E_PERM;
+	}
+
+	switch (hif_get_bus_type(scn)) {
+	case QDF_BUS_TYPE_PCI:
+	case QDF_BUS_TYPE_SNOC:
+	case QDF_BUS_TYPE_USB:
+		status = bmi_get_target_info_message_based(targ_info, ol_ctx);
+		break;
+#ifdef HIF_SDIO
+	case QDF_BUS_TYPE_SDIO:
+		status = hif_reg_based_get_target_info(scn, targ_info);
+		break;
+#endif
+	default:
+		status = QDF_STATUS_E_FAILURE;
+		break;
+	}
+	return status;
+}
+
+QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn;
+
+	if (!ol_ctx) {
+		if (NO_BMI) {
+			/* ol_ctx is not allocated in NO_BMI case */
+			return QDF_STATUS_SUCCESS;
+		}
+
+		BMI_ERR("ol_ctx is NULL");
+		bmi_assert(0);
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	scn = ol_ctx->scn;
+
+	if (!scn) {
+		BMI_ERR("Invalid scn context");
+		bmi_assert(0);
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	if (!hif_needs_bmi(scn))
+		return QDF_STATUS_SUCCESS;
+	else
+		hif_register_bmi_callbacks(scn);
+
+	return bmi_firmware_download(ol_ctx);
+}
+
+QDF_STATUS bmi_read_soc_register(uint32_t address, uint32_t *param,
+						struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	uint32_t cid;
+	int status;
+	uint32_t offset, param_len;
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
+	uint8_t *bmi_rsp_buff = info->bmi_rsp_buff;
+	qdf_dma_addr_t cmd = info->bmi_cmd_da;
+	qdf_dma_addr_t rsp = info->bmi_rsp_da;
+
+	bmi_assert(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
+	qdf_mem_set(bmi_cmd_buff, 0, sizeof(cid) + sizeof(address));
+	qdf_mem_set(bmi_rsp_buff, 0, sizeof(cid) + sizeof(address));
+
+	if (info->bmi_done) {
+		BMI_DBG("Command disallowed");
+		return QDF_STATUS_E_PERM;
+	}
+
+	BMI_DBG("BMI Read SOC Register:device: 0x%pK, address: 0x%x",
+			 scn, address);
+
+	cid = BMI_READ_SOC_REGISTER;
+
+	offset = 0;
+	qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid));
+	offset += sizeof(cid);
+	qdf_mem_copy(&(bmi_cmd_buff[offset]), &address, sizeof(address));
+	offset += sizeof(address);
+	param_len = sizeof(*param);
+	status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, offset,
+			bmi_rsp_buff, &param_len, BMI_EXCHANGE_TIMEOUT_MS);
+	if (status) {
+		BMI_DBG("Unable to read from the device; status:%d", status);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_copy(param, bmi_rsp_buff, sizeof(*param));
+
+	BMI_DBG("BMI Read SOC Register: Exit value: %d", *param);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS bmi_write_soc_register(uint32_t address, uint32_t param,
+					struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	uint32_t cid;
+	int status;
+	uint32_t offset;
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
+	uint32_t size = sizeof(cid) + sizeof(address) + sizeof(param);
+	qdf_dma_addr_t cmd = info->bmi_cmd_da;
+	qdf_dma_addr_t rsp = info->bmi_rsp_da;
+
+	bmi_assert(BMI_COMMAND_FITS(size));
+	qdf_mem_set(bmi_cmd_buff, 0, size);
+
+	if (info->bmi_done) {
+		BMI_DBG("Command disallowed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	BMI_DBG("SOC Register Write:device:0x%pK, addr:0x%x, param:%d",
+						scn, address, param);
+
+	cid = BMI_WRITE_SOC_REGISTER;
+
+	offset = 0;
+	qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid));
+	offset += sizeof(cid);
+	qdf_mem_copy(&(bmi_cmd_buff[offset]), &address, sizeof(address));
+	offset += sizeof(address);
+	qdf_mem_copy(&(bmi_cmd_buff[offset]), &param, sizeof(param));
+	offset += sizeof(param);
+	status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, offset,
+						NULL, NULL, 0);
+	if (status) {
+		BMI_ERR("Unable to write to the device: status:%d", status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	BMI_DBG("BMI Read SOC Register: Exit");
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+bmilz_data(uint8_t *buffer, uint32_t length, struct ol_context *ol_ctx)
+{
+	uint32_t cid;
+	int status;
+	uint32_t offset;
+	uint32_t remaining, txlen;
+	const uint32_t header = sizeof(cid) + sizeof(length);
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
+	qdf_dma_addr_t cmd = info->bmi_cmd_da;
+	qdf_dma_addr_t rsp = info->bmi_rsp_da;
+
+	bmi_assert(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
+	qdf_mem_set(bmi_cmd_buff, 0, BMI_DATASZ_MAX + header);
+
+	if (info->bmi_done) {
+		BMI_ERR("Command disallowed");
+		return QDF_STATUS_E_PERM;
+	}
+
+	BMI_DBG("BMI Send LZ Data: device: 0x%pK, length: %d",
+						scn, length);
+
+	cid = BMI_LZ_DATA;
+
+	remaining = length;
+	while (remaining) {
+		txlen = (remaining < (BMI_DATASZ_MAX - header)) ?
+			remaining : (BMI_DATASZ_MAX - header);
+		offset = 0;
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid));
+		offset += sizeof(cid);
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), &txlen, sizeof(txlen));
+		offset += sizeof(txlen);
+		qdf_mem_copy(&(bmi_cmd_buff[offset]),
+			&buffer[length - remaining], txlen);
+		offset += txlen;
+		status = hif_exchange_bmi_msg(scn, cmd, rsp,
+						bmi_cmd_buff, offset,
+						NULL, NULL, 0);
+		if (status) {
+			BMI_ERR("Failed to write to the device: status:%d",
+								status);
+			return QDF_STATUS_E_FAILURE;
+		}
+		remaining -= txlen;
+	}
+
+	BMI_DBG("BMI LZ Data: Exit");
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS bmi_sign_stream_start(uint32_t address, uint8_t *buffer,
+				 uint32_t length, struct ol_context *ol_ctx)
+{
+	uint32_t cid;
+	int status;
+	uint32_t offset;
+	const uint32_t header = sizeof(cid) + sizeof(address) + sizeof(length);
+	uint8_t aligned_buf[BMI_DATASZ_MAX + 4];
+	uint8_t *src;
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
+	uint32_t remaining, txlen;
+	qdf_dma_addr_t cmd = info->bmi_cmd_da;
+	qdf_dma_addr_t rsp = info->bmi_rsp_da;
+
+	bmi_assert(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
+	qdf_mem_set(bmi_cmd_buff, 0, BMI_DATASZ_MAX + header);
+
+	if (info->bmi_done) {
+		BMI_ERR("Command disallowed");
+		return QDF_STATUS_E_PERM;
+	}
+
+	BMI_ERR("Sign Stream start:device:0x%pK, addr:0x%x, length:%d",
+						scn, address, length);
+
+	cid = BMI_SIGN_STREAM_START;
+	remaining = length;
+	while (remaining) {
+		src = &buffer[length - remaining];
+		if (remaining < (BMI_DATASZ_MAX - header)) {
+			if (remaining & 0x3) {
+				memcpy(aligned_buf, src, remaining);
+				remaining = remaining + (4 - (remaining & 0x3));
+				src = aligned_buf;
+			}
+			txlen = remaining;
+		} else {
+			txlen = (BMI_DATASZ_MAX - header);
+		}
+
+		offset = 0;
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid));
+		offset += sizeof(cid);
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), &address,
+						sizeof(address));
+		offset += sizeof(offset);
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), &txlen, sizeof(txlen));
+		offset += sizeof(txlen);
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), src, txlen);
+		offset += txlen;
+		status = hif_exchange_bmi_msg(scn, cmd, rsp,
+						bmi_cmd_buff, offset, NULL,
+						NULL, BMI_EXCHANGE_TIMEOUT_MS);
+		if (status) {
+			BMI_ERR("Unable to write to the device: status:%d",
+								status);
+			return QDF_STATUS_E_FAILURE;
+		}
+		remaining -= txlen;
+	}
+	BMI_DBG("BMI SIGN Stream Start: Exit");
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+bmilz_stream_start(uint32_t address, struct ol_context *ol_ctx)
+{
+	uint32_t cid;
+	int status;
+	uint32_t offset;
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
+	qdf_dma_addr_t cmd = info->bmi_cmd_da;
+	qdf_dma_addr_t rsp = info->bmi_rsp_da;
+
+	bmi_assert(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
+	qdf_mem_set(bmi_cmd_buff, 0, sizeof(cid) + sizeof(address));
+
+	if (info->bmi_done) {
+		BMI_DBG("Command disallowed");
+		return QDF_STATUS_E_PERM;
+	}
+	BMI_DBG("BMI LZ Stream Start: (device: 0x%pK, address: 0x%x)",
+						scn, address);
+
+	cid = BMI_LZ_STREAM_START;
+	offset = 0;
+	qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid));
+	offset += sizeof(cid);
+	qdf_mem_copy(&(bmi_cmd_buff[offset]), &address, sizeof(address));
+	offset += sizeof(address);
+	status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, offset,
+						NULL, NULL, 0);
+	if (status) {
+		BMI_ERR("Unable to Start LZ Stream to the device status:%d",
+								status);
+		return QDF_STATUS_E_FAILURE;
+	}
+	BMI_DBG("BMI LZ Stream: Exit");
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+bmi_fast_download(uint32_t address, uint8_t *buffer,
+		  uint32_t length, struct ol_context *ol_ctx)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t last_word = 0;
+	uint32_t last_word_offset = length & ~0x3;
+	uint32_t unaligned_bytes = length & 0x3;
+
+	status = bmilz_stream_start(address, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS)
+		goto end;
+
+	/* copy the last word into a zero padded buffer */
+	if (unaligned_bytes)
+		qdf_mem_copy(&last_word, &buffer[last_word_offset],
+						unaligned_bytes);
+
+	status = bmilz_data(buffer, last_word_offset, ol_ctx);
+
+	if (status != QDF_STATUS_SUCCESS)
+		goto end;
+
+	if (unaligned_bytes)
+		status = bmilz_data((uint8_t *) &last_word, 4, ol_ctx);
+
+	if (status != QDF_STATUS_SUCCESS)
+		/*
+		 * Close compressed stream and open a new (fake) one.
+		 * This serves mainly to flush Target caches.
+		 */
+		status = bmilz_stream_start(0x00, ol_ctx);
+end:
+	return status;
+}
+
+/**
+ * ol_cds_init() - API to initialize global CDS OL Context
+ * @qdf_dev: QDF Device
+ * @hif_ctx: HIF Context
+ *
+ * Return: Success/Failure
+ */
+QDF_STATUS ol_cds_init(qdf_device_t qdf_dev, void *hif_ctx)
+{
+	struct ol_context *ol_info;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (NO_BMI)
+		return QDF_STATUS_SUCCESS; /* no BMI for Q6 bring up */
+
+	status = cds_alloc_context(QDF_MODULE_ID_BMI,
+				   (void **)&ol_info, sizeof(*ol_info));
+
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("%s: CDS Allocation failed for ol_bmi context",
+								__func__);
+		return status;
+	}
+
+	ol_info->qdf_dev = qdf_dev;
+	ol_info->scn = hif_ctx;
+	ol_info->tgt_def.targetdef = hif_get_targetdef(hif_ctx);
+
+	qdf_create_work(qdf_dev, &ol_info->ramdump_work,
+			ramdump_work_handler, ol_info);
+	qdf_create_work(qdf_dev, &ol_info->fw_indication_work,
+			fw_indication_work_handler, ol_info);
+
+	return status;
+}
+
+/**
+ * ol_cds_free() - API to free the global CDS OL Context
+ *
+ * Return: void
+ */
+void ol_cds_free(void)
+{
+	struct ol_context *ol_info = cds_get_context(QDF_MODULE_ID_BMI);
+
+	if (NO_BMI)
+		return;
+
+	cds_free_context(QDF_MODULE_ID_BMI, ol_info);
+}
diff --git a/core/bmi/src/bmi_1.c b/core/bmi/src/bmi_1.c
new file mode 100644
index 0000000..a4b653d
--- /dev/null
+++ b/core/bmi/src/bmi_1.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#include "i_bmi.h"
+#include "cds_api.h"
+
+/* APIs visible to the driver */
+
+QDF_STATUS
+bmi_read_memory(uint32_t address,
+		uint8_t *buffer, uint32_t length, struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	uint32_t cid;
+	int status;
+	uint32_t offset;
+	uint32_t remaining, rxlen;
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
+	uint8_t *bmi_rsp_buff = info->bmi_rsp_buff;
+	uint32_t align;
+	qdf_dma_addr_t cmd = info->bmi_cmd_da;
+	qdf_dma_addr_t rsp = info->bmi_rsp_da;
+
+	if (info->bmi_done) {
+		BMI_DBG("command disallowed");
+		return QDF_STATUS_E_PERM;
+	}
+
+	if (!info->bmi_cmd_buff || !info->bmi_rsp_buff) {
+		BMI_ERR("BMI Initialization hasn't done");
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	bmi_assert(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) +
+			sizeof(address) + sizeof(length)));
+	qdf_mem_set(bmi_cmd_buff, 0, BMI_DATASZ_MAX + sizeof(cid) +
+			sizeof(address) + sizeof(length));
+	qdf_mem_set(bmi_rsp_buff, 0, BMI_DATASZ_MAX + sizeof(cid) +
+			sizeof(address) + sizeof(length));
+
+	cid = BMI_READ_MEMORY;
+	align = 0;
+	remaining = length;
+
+	while (remaining) {
+		rxlen = (remaining < BMI_DATASZ_MAX) ?
+				remaining : BMI_DATASZ_MAX;
+		offset = 0;
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid));
+		offset += sizeof(cid);
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), &address,
+						sizeof(address));
+		offset += sizeof(address);
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), &rxlen, sizeof(rxlen));
+		offset += sizeof(length);
+
+		/* note we reuse the same buffer to receive on */
+		status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff,
+						offset, bmi_rsp_buff, &rxlen,
+						BMI_EXCHANGE_TIMEOUT_MS);
+		if (status) {
+			BMI_ERR("Unable to read from the device");
+			return QDF_STATUS_E_FAILURE;
+		}
+		if (remaining == rxlen) {
+			qdf_mem_copy(&buffer[length - remaining + align],
+					bmi_rsp_buff, rxlen - align);
+			/* last align bytes are invalid */
+		} else {
+			qdf_mem_copy(&buffer[length - remaining + align],
+				 bmi_rsp_buff, rxlen);
+		}
+		remaining -= rxlen;
+		address += rxlen;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS bmi_write_memory(uint32_t address, uint8_t *buffer, uint32_t length,
+						struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	uint32_t cid;
+	int status;
+	uint32_t offset;
+	uint32_t remaining, txlen;
+	const uint32_t header = sizeof(cid) + sizeof(address) + sizeof(length);
+	uint8_t aligned_buffer[BMI_DATASZ_MAX];
+	uint8_t *src;
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
+	qdf_dma_addr_t cmd = info->bmi_cmd_da;
+	qdf_dma_addr_t rsp = info->bmi_rsp_da;
+
+	if (info->bmi_done) {
+		BMI_ERR("Command disallowed");
+		return QDF_STATUS_E_PERM;
+	}
+
+	if (!bmi_cmd_buff) {
+		BMI_ERR("BMI initialization hasn't done");
+		return QDF_STATUS_E_PERM;
+	}
+
+	bmi_assert(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
+	qdf_mem_set(bmi_cmd_buff, 0, BMI_DATASZ_MAX + header);
+
+	cid = BMI_WRITE_MEMORY;
+
+	remaining = length;
+	while (remaining) {
+		src = &buffer[length - remaining];
+		if (remaining < (BMI_DATASZ_MAX - header)) {
+			if (remaining & 3) {
+				/* align it with 4 bytes */
+				remaining = remaining + (4 - (remaining & 3));
+				memcpy(aligned_buffer, src, remaining);
+				src = aligned_buffer;
+			}
+			txlen = remaining;
+		} else {
+			txlen = (BMI_DATASZ_MAX - header);
+		}
+		offset = 0;
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid));
+		offset += sizeof(cid);
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), &address,
+						sizeof(address));
+		offset += sizeof(address);
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), &txlen, sizeof(txlen));
+		offset += sizeof(txlen);
+		qdf_mem_copy(&(bmi_cmd_buff[offset]), src, txlen);
+		offset += txlen;
+		status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff,
+						offset, NULL, NULL,
+						BMI_EXCHANGE_TIMEOUT_MS);
+		if (status) {
+			BMI_ERR("Unable to write to the device; status:%d",
+								status);
+			return QDF_STATUS_E_FAILURE;
+		}
+		remaining -= txlen;
+		address += txlen;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+bmi_execute(uint32_t address, A_UINT32 *param, struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	uint32_t cid;
+	int status;
+	uint32_t offset;
+	uint32_t param_len;
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	uint8_t *bmi_cmd_buff = info->bmi_cmd_buff;
+	uint8_t *bmi_rsp_buff = info->bmi_rsp_buff;
+	uint32_t size = sizeof(cid) + sizeof(address) + sizeof(param);
+	qdf_dma_addr_t cmd = info->bmi_cmd_da;
+	qdf_dma_addr_t rsp = info->bmi_rsp_da;
+
+	if (info->bmi_done) {
+		BMI_ERR("Command disallowed");
+		return QDF_STATUS_E_PERM;
+	}
+
+	if (!bmi_cmd_buff || !bmi_rsp_buff) {
+		BMI_ERR("%s:BMI CMD/RSP Buffer is NULL", __func__);
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	bmi_assert(BMI_COMMAND_FITS(size));
+	qdf_mem_set(bmi_cmd_buff, 0, size);
+	qdf_mem_set(bmi_rsp_buff, 0, size);
+
+
+	BMI_DBG("BMI Execute: device: 0x%pK, address: 0x%x, param: %d",
+						scn, address, *param);
+
+	cid = BMI_EXECUTE;
+
+	offset = 0;
+	qdf_mem_copy(&(bmi_cmd_buff[offset]), &cid, sizeof(cid));
+	offset += sizeof(cid);
+	qdf_mem_copy(&(bmi_cmd_buff[offset]), &address, sizeof(address));
+	offset += sizeof(address);
+	qdf_mem_copy(&(bmi_cmd_buff[offset]), param, sizeof(*param));
+	offset += sizeof(*param);
+	param_len = sizeof(*param);
+	status = hif_exchange_bmi_msg(scn, cmd, rsp, bmi_cmd_buff, offset,
+					bmi_rsp_buff, &param_len, 0);
+	if (status) {
+		BMI_ERR("Unable to read from the device status:%d", status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_copy(param, bmi_rsp_buff, sizeof(*param));
+
+	BMI_DBG("BMI Execute: Exit (param: %d)", *param);
+	return QDF_STATUS_SUCCESS;
+}
+
+inline QDF_STATUS
+bmi_no_command(struct ol_context *ol_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+bmi_firmware_download(struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	QDF_STATUS status;
+	struct bmi_target_info targ_info;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+
+	qdf_mem_zero(&targ_info, sizeof(targ_info));
+	/* Initialize BMI */
+	status = bmi_init(ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("BMI Initialization Failed err:%d", status);
+		return status;
+	}
+
+	/* Get target information */
+	status = bmi_get_target_info(&targ_info, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("BMI Target Info get failed: status:%d", status);
+		return status;
+	}
+
+	tgt_info->target_type = targ_info.target_type;
+	tgt_info->target_version = targ_info.target_ver;
+	/* Configure target */
+	status = ol_configure_target(ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("BMI Configure Target Failed status:%d", status);
+		return status;
+	}
+	status = ol_download_firmware(ol_ctx);
+	if (status != QDF_STATUS_SUCCESS)
+		BMI_ERR("BMI Download Firmware Failed Status:%d", status);
+
+	return status;
+}
+
+QDF_STATUS bmi_done_local(struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	int status;
+	uint32_t cid;
+	struct bmi_info *info;
+	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
+	qdf_dma_addr_t cmd, rsp;
+
+	if (!scn) {
+		BMI_ERR("Invalid scn context");
+		bmi_assert(0);
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	if (!qdf_dev->dev) {
+		BMI_ERR("%s: Invalid device pointer", __func__);
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	info = GET_BMI_CONTEXT(ol_ctx);
+	if (info->bmi_done) {
+		BMI_DBG(FL("skipped"));
+		return QDF_STATUS_E_PERM;
+	}
+
+	cmd = info->bmi_cmd_da;
+	rsp = info->bmi_rsp_da;
+
+	BMI_DBG("BMI Done: Enter (device: 0x%pK)", scn);
+
+	info->bmi_done = true;
+	cid = BMI_DONE;
+
+	if (!info->bmi_cmd_buff) {
+		BMI_ERR("Invalid scn BMICmdBuff");
+		bmi_assert(0);
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	qdf_mem_copy(info->bmi_cmd_buff, &cid, sizeof(cid));
+
+	status = hif_exchange_bmi_msg(scn, cmd, rsp, info->bmi_cmd_buff,
+				sizeof(cid), NULL, NULL, 0);
+	if (status) {
+		BMI_ERR("Failed to write to the device; status:%d", status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (info->bmi_cmd_buff) {
+		qdf_mem_free_consistent(qdf_dev, qdf_dev->dev,
+					MAX_BMI_CMDBUF_SZ,
+				    info->bmi_cmd_buff, info->bmi_cmd_da, 0);
+		info->bmi_cmd_buff = NULL;
+		info->bmi_cmd_da = 0;
+	}
+
+	if (info->bmi_rsp_buff) {
+		qdf_mem_free_consistent(qdf_dev, qdf_dev->dev,
+					MAX_BMI_CMDBUF_SZ,
+				    info->bmi_rsp_buff, info->bmi_rsp_da, 0);
+		info->bmi_rsp_buff = NULL;
+		info->bmi_rsp_da = 0;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/core/bmi/src/i_ar6320v2_regtable.h b/core/bmi/src/i_ar6320v2_regtable.h
new file mode 100644
index 0000000..4bdf553
--- /dev/null
+++ b/core/bmi/src/i_ar6320v2_regtable.h
@@ -0,0 +1,872 @@
+/*
+ * Copyright (c) 2014, 2016-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.
+ */
+
+#ifndef _AR6320V2_DBG_REGTABLE_H_
+#define _AR6320V2_DBG_REGTABLE_H_
+
+#include "regtable.h"
+
+#define AR6320_REV2_1_REG_SIZE 0x0007F820
+#define AR6320_REV3_REG_SIZE   0x0007F820
+
+/*
+ * Redefine the register list. To minimize the size of the array, the list must
+ * obey the below format. {start0, end0}, {start1, end1}, {start2, end2}.......
+ * The value below must obey to "start0 < end0 < start1 < end1 < start2 < ...",
+ * otherwise we may encouter error in the dump processing.
+ */
+
+static const struct tgt_reg_section ar6320v2_reg_table[] = {
+	{0x800, 0x810},
+	{0x820, 0x82C},
+	{0x830, 0x8F4},
+	{0x90C, 0x91C},
+	{0xA14, 0xA18},
+	{0xA84, 0xA94},
+	{0xAA8, 0xAD4},
+	{0xADC, 0xB40},
+	{0x1000, 0x10A4},
+	{0x10BC, 0x111C},
+	{0x1134, 0x1138},
+	{0x1144, 0x114C},
+	{0x1150, 0x115C},
+	{0x1160, 0x1178},
+	{0x1240, 0x1260},
+	{0x2000, 0x207C},
+	{0x3000, 0x3014},
+	{0x4000, 0x4014},
+	{0x5000, 0x5124},
+	{0x6000, 0x6040},
+	{0x6080, 0x60CC},
+	{0x6100, 0x611C},
+	{0x6140, 0x61D8},
+	{0x6200, 0x6238},
+	{0x6240, 0x628C},
+	{0x62C0, 0x62EC},
+	{0x6380, 0x63E8},
+	{0x6400, 0x6440},
+	{0x6480, 0x64CC},
+	{0x6500, 0x651C},
+	{0x6540, 0x6580},
+	{0x6600, 0x6638},
+	{0x6640, 0x668C},
+	{0x66C0, 0x66EC},
+	{0x6780, 0x67E8},
+	{0x7080, 0x708C},
+	{0x70C0, 0x70C8},
+	{0x7400, 0x741C},
+	{0x7440, 0x7454},
+	{0x7800, 0x7818},
+	{0x8000, 0x8004},
+	{0x8010, 0x8064},
+	{0x8080, 0x8084},
+	{0x80A0, 0x80A4},
+	{0x80C0, 0x80C4},
+	{0x80E0, 0x80F4},
+	{0x8100, 0x8104},
+	{0x8110, 0x812C},
+	{0x9000, 0x9004},
+	{0x9800, 0x982C},
+	{0x9830, 0x9838},
+	{0x9840, 0x986C},
+	{0x9870, 0x9898},
+	{0x9A00, 0x9C00},
+	{0xD580, 0xD59C},
+	{0xF000, 0xF0E0},
+	{0xF140, 0xF190},
+	{0xF250, 0xF25C},
+	{0xF260, 0xF268},
+	{0xF26C, 0xF2A8},
+	{0x10008, 0x1000C},
+	{0x10014, 0x10018},
+	{0x1001C, 0x10020},
+	{0x10024, 0x10028},
+	{0x10030, 0x10034},
+	{0x10040, 0x10054},
+	{0x10058, 0x1007C},
+	{0x10080, 0x100C4},
+	{0x100C8, 0x10114},
+	{0x1012C, 0x10130},
+	{0x10138, 0x10144},
+	{0x10200, 0x10220},
+	{0x10230, 0x10250},
+	{0x10260, 0x10280},
+	{0x10290, 0x102B0},
+	{0x102C0, 0x102DC},
+	{0x102E0, 0x102F4},
+	{0x102FC, 0x1037C},
+	{0x10380, 0x10390},
+	{0x10800, 0x10828},
+	{0x10840, 0x10844},
+	{0x10880, 0x10884},
+	{0x108C0, 0x108E8},
+	{0x10900, 0x10928},
+	{0x10940, 0x10944},
+	{0x10980, 0x10984},
+	{0x109C0, 0x109E8},
+	{0x10A00, 0x10A28},
+	{0x10A40, 0x10A50},
+	{0x11000, 0x11028},
+	{0x11030, 0x11034},
+	{0x11038, 0x11068},
+	{0x11070, 0x11074},
+	{0x11078, 0x110A8},
+	{0x110B0, 0x110B4},
+	{0x110B8, 0x110E8},
+	{0x110F0, 0x110F4},
+	{0x110F8, 0x11128},
+	{0x11138, 0x11144},
+	{0x11178, 0x11180},
+	{0x111B8, 0x111C0},
+	{0x111F8, 0x11200},
+	{0x11238, 0x1123C},
+	{0x11270, 0x11274},
+	{0x11278, 0x1127C},
+	{0x112B0, 0x112B4},
+	{0x112B8, 0x112BC},
+	{0x112F0, 0x112F4},
+	{0x112F8, 0x112FC},
+	{0x11338, 0x1133C},
+	{0x11378, 0x1137C},
+	{0x113B8, 0x113BC},
+	{0x113F8, 0x113FC},
+	{0x11438, 0x11440},
+	{0x11478, 0x11480},
+	{0x114B8, 0x114BC},
+	{0x114F8, 0x114FC},
+	{0x11538, 0x1153C},
+	{0x11578, 0x1157C},
+	{0x115B8, 0x115BC},
+	{0x115F8, 0x115FC},
+	{0x11638, 0x1163C},
+	{0x11678, 0x1167C},
+	{0x116B8, 0x116BC},
+	{0x116F8, 0x116FC},
+	{0x11738, 0x1173C},
+	{0x11778, 0x1177C},
+	{0x117B8, 0x117BC},
+	{0x117F8, 0x117FC},
+	{0x17000, 0x1701C},
+	{0x17020, 0x170AC},
+	{0x18000, 0x18050},
+	{0x18054, 0x18074},
+	{0x18080, 0x180D4},
+	{0x180DC, 0x18104},
+	{0x18108, 0x1813C},
+	{0x18144, 0x18148},
+	{0x18168, 0x18174},
+	{0x18178, 0x18180},
+	{0x181C8, 0x181E0},
+	{0x181E4, 0x181E8},
+	{0x181EC, 0x1820C},
+	{0x1825C, 0x18280},
+	{0x18284, 0x18290},
+	{0x18294, 0x182A0},
+	{0x18300, 0x18304},
+	{0x18314, 0x18320},
+	{0x18328, 0x18350},
+	{0x1835C, 0x1836C},
+	{0x18370, 0x18390},
+	{0x18398, 0x183AC},
+	{0x183BC, 0x183D8},
+	{0x183DC, 0x183F4},
+	{0x18400, 0x186F4},
+	{0x186F8, 0x1871C},
+	{0x18720, 0x18790},
+	{0x19800, 0x19830},
+	{0x19834, 0x19840},
+	{0x19880, 0x1989C},
+	{0x198A4, 0x198B0},
+	{0x198BC, 0x19900},
+	{0x19C00, 0x19C88},
+	{0x19D00, 0x19D20},
+	{0x19E00, 0x19E7C},
+	{0x19E80, 0x19E94},
+	{0x19E98, 0x19EAC},
+	{0x19EB0, 0x19EBC},
+	{0x19F70, 0x19F74},
+	{0x19F80, 0x19F8C},
+	{0x19FA0, 0x19FB4},
+	{0x19FC0, 0x19FD8},
+	{0x1A000, 0x1A200},
+	{0x1A204, 0x1A210},
+	{0x1A228, 0x1A22C},
+	{0x1A230, 0x1A248},
+	{0x1A250, 0x1A270},
+	{0x1A280, 0x1A290},
+	{0x1A2A0, 0x1A2A4},
+	{0x1A2C0, 0x1A2EC},
+	{0x1A300, 0x1A3BC},
+	{0x1A3F0, 0x1A3F4},
+	{0x1A3F8, 0x1A434},
+	{0x1A438, 0x1A444},
+	{0x1A448, 0x1A468},
+	{0x1A580, 0x1A58C},
+	{0x1A644, 0x1A654},
+	{0x1A670, 0x1A698},
+	{0x1A6AC, 0x1A6B0},
+	{0x1A6D0, 0x1A6D4},
+	{0x1A6EC, 0x1A70C},
+	{0x1A710, 0x1A738},
+	{0x1A7C0, 0x1A7D0},
+	{0x1A7D4, 0x1A7D8},
+	{0x1A7DC, 0x1A7E4},
+	{0x1A7F0, 0x1A7F8},
+	{0x1A888, 0x1A89C},
+	{0x1A8A8, 0x1A8AC},
+	{0x1A8C0, 0x1A8DC},
+	{0x1A8F0, 0x1A8FC},
+	{0x1AE04, 0x1AE08},
+	{0x1AE18, 0x1AE24},
+	{0x1AF80, 0x1AF8C},
+	{0x1AFA0, 0x1AFB4},
+	{0x1B000, 0x1B200},
+	{0x1B284, 0x1B288},
+	{0x1B2D0, 0x1B2D8},
+	{0x1B2DC, 0x1B2EC},
+	{0x1B300, 0x1B340},
+	{0x1B374, 0x1B378},
+	{0x1B380, 0x1B384},
+	{0x1B388, 0x1B38C},
+	{0x1B404, 0x1B408},
+	{0x1B420, 0x1B428},
+	{0x1B440, 0x1B444},
+	{0x1B448, 0x1B44C},
+	{0x1B450, 0x1B458},
+	{0x1B45C, 0x1B468},
+	{0x1B584, 0x1B58C},
+	{0x1B68C, 0x1B690},
+	{0x1B6AC, 0x1B6B0},
+	{0x1B7F0, 0x1B7F8},
+	{0x1C800, 0x1CC00},
+	{0x1CE00, 0x1CE04},
+	{0x1CF80, 0x1CF84},
+	{0x1D200, 0x1D800},
+	{0x1E000, 0x20014},
+	{0x20100, 0x20124},
+	{0x21400, 0x217A8},
+	{0x21800, 0x21BA8},
+	{0x21C00, 0x21FA8},
+	{0x22000, 0x223A8},
+	{0x22400, 0x227A8},
+	{0x22800, 0x22BA8},
+	{0x22C00, 0x22FA8},
+	{0x23000, 0x233A8},
+	{0x24000, 0x24034},
+
+	/*
+	 * EFUSE0,1,2 is disabled here
+	 * because it's state may be reset
+	 *
+	 * {0x24800, 0x24804},
+	 * {0x25000, 0x25004},
+	 * {0x25800, 0x25804},
+	 */
+
+	{0x26000, 0x26064},
+	{0x27000, 0x27024},
+	{0x34000, 0x3400C},
+	{0x34400, 0x3445C},
+	{0x34800, 0x3485C},
+	{0x34C00, 0x34C5C},
+	{0x35000, 0x3505C},
+	{0x35400, 0x3545C},
+	{0x35800, 0x3585C},
+	{0x35C00, 0x35C5C},
+	{0x36000, 0x3605C},
+	{0x38000, 0x38064},
+	{0x38070, 0x380E0},
+	{0x3A000, 0x3A064},
+
+	/* DBI windows is skipped here, it can be only accessed when pcie
+	 * is active (not in reset) and CORE_CTRL_PCIE_LTSSM_EN = 0 &&
+	 * PCIE_CTRL_APP_LTSSM_ENALBE=0.
+	 * {0x3C000 , 0x3C004},
+	 */
+
+	{0x40000, 0x400A4},
+
+	/*
+	 * SI register is skiped here.
+	 * Because it will cause bus hang
+	 *
+	 * {0x50000, 0x50018},
+	 */
+
+	{0x80000, 0x8000C},
+	{0x80010, 0x80020},
+};
+
+#ifdef HIF_SDIO
+static const struct tgt_reg_section ar6320v3_reg_table[] = {
+	{0x800, 0x810},
+	{0x820, 0x82C},
+	{0x830, 0x8F4},
+	{0x90C, 0x91C},
+	{0xA14, 0xA18},
+	{0xA84, 0xA94},
+	{0xAA8, 0xAD4},
+	{0xADC, 0xB40},
+	{0x1000, 0x10A4},
+	{0x10BC, 0x111C},
+	{0x1134, 0x1138},
+	{0x1144, 0x114C},
+	{0x1150, 0x115C},
+	{0x1160, 0x1178},
+	{0x1240, 0x1260},
+	{0x2000, 0x207C},
+	{0x3000, 0x3014},
+	{0x4000, 0x4014},
+	{0x5000, 0x5124},
+	{0x6000, 0x6040},
+	{0x6080, 0x60CC},
+	{0x6100, 0x611C},
+	{0x6140, 0x61D8},
+	{0x6200, 0x6238},
+	{0x6240, 0x628C},
+	{0x62C0, 0x62EC},
+	{0x6380, 0x63E8},
+	{0x6400, 0x6440},
+	{0x6480, 0x64CC},
+	{0x6500, 0x651C},
+	{0x6540, 0x6580},
+	{0x6600, 0x6638},
+	{0x6640, 0x668C},
+	{0x66C0, 0x66EC},
+	{0x6780, 0x67E8},
+	{0x7080, 0x708C},
+	{0x70C0, 0x70C8},
+	{0x7400, 0x741C},
+	{0x7440, 0x7454},
+	{0x7800, 0x7818},
+	{0x8010, 0x8060},
+	{0x8080, 0x8084},
+	{0x80A0, 0x80A4},
+	{0x80C0, 0x80C4},
+	{0x80E0, 0x80ec},
+	{0x8110, 0x8128},
+	{0x9000, 0x9004},
+	{0xF000, 0xF0E0},
+	{0xF140, 0xF190},
+	{0xF250, 0xF25C},
+	{0xF260, 0xF268},
+	{0xF26C, 0xF2A8},
+	{0x10008, 0x1000C},
+	{0x10014, 0x10018},
+	{0x1001C, 0x10020},
+	{0x10024, 0x10028},
+	{0x10030, 0x10034},
+	{0x10040, 0x10054},
+	{0x10058, 0x1007C},
+	{0x10080, 0x100C4},
+	{0x100C8, 0x10114},
+	{0x1012C, 0x10130},
+	{0x10138, 0x10144},
+	{0x10200, 0x10220},
+	{0x10230, 0x10250},
+	{0x10260, 0x10280},
+	{0x10290, 0x102B0},
+	{0x102C0, 0x102DC},
+	{0x102E0, 0x102F4},
+	{0x102FC, 0x1037C},
+	{0x10380, 0x10390},
+	{0x10800, 0x10828},
+	{0x10840, 0x10844},
+	{0x10880, 0x10884},
+	{0x108C0, 0x108E8},
+	{0x10900, 0x10928},
+	{0x10940, 0x10944},
+	{0x10980, 0x10984},
+	{0x109C0, 0x109E8},
+	{0x10A00, 0x10A28},
+	{0x10A40, 0x10A50},
+	{0x11000, 0x11028},
+	{0x11030, 0x11034},
+	{0x11038, 0x11068},
+	{0x11070, 0x11074},
+	{0x11078, 0x110A8},
+	{0x110B0, 0x110B4},
+	{0x110B8, 0x110E8},
+	{0x110F0, 0x110F4},
+	{0x110F8, 0x11128},
+	{0x11138, 0x11144},
+	{0x11178, 0x11180},
+	{0x111B8, 0x111C0},
+	{0x111F8, 0x11200},
+	{0x11238, 0x1123C},
+	{0x11270, 0x11274},
+	{0x11278, 0x1127C},
+	{0x112B0, 0x112B4},
+	{0x112B8, 0x112BC},
+	{0x112F0, 0x112F4},
+	{0x112F8, 0x112FC},
+	{0x11338, 0x1133C},
+	{0x11378, 0x1137C},
+	{0x113B8, 0x113BC},
+	{0x113F8, 0x113FC},
+	{0x11438, 0x11440},
+	{0x11478, 0x11480},
+	{0x114B8, 0x114BC},
+	{0x114F8, 0x114FC},
+	{0x11538, 0x1153C},
+	{0x11578, 0x1157C},
+	{0x115B8, 0x115BC},
+	{0x115F8, 0x115FC},
+	{0x11638, 0x1163C},
+	{0x11678, 0x1167C},
+	{0x116B8, 0x116BC},
+	{0x116F8, 0x116FC},
+	{0x11738, 0x1173C},
+	{0x11778, 0x1177C},
+	{0x117B8, 0x117BC},
+	{0x117F8, 0x117FC},
+	{0x17000, 0x1701C},
+	{0x17020, 0x170AC},
+	{0x18000, 0x18050},
+	{0x18054, 0x18074},
+	{0x18080, 0x180D4},
+	{0x180DC, 0x18104},
+	{0x18108, 0x1813C},
+	{0x18144, 0x18148},
+	{0x18168, 0x18174},
+	{0x18178, 0x18180},
+	{0x181C8, 0x181E0},
+	{0x181E4, 0x181E8},
+	{0x181EC, 0x1820C},
+	{0x1825C, 0x18280},
+	{0x18284, 0x18290},
+	{0x18294, 0x182A0},
+	{0x18300, 0x18304},
+	{0x18314, 0x18320},
+	{0x18328, 0x18350},
+	{0x1835C, 0x1836C},
+	{0x18370, 0x18390},
+	{0x18398, 0x183AC},
+	{0x183BC, 0x183D8},
+	{0x183DC, 0x183F4},
+	{0x18400, 0x186F4},
+	{0x186F8, 0x1871C},
+	{0x18720, 0x18790},
+	{0x19800, 0x19830},
+	{0x19834, 0x19840},
+	{0x19880, 0x1989C},
+	{0x198A4, 0x198B0},
+	{0x198BC, 0x19900},
+	{0x19C00, 0x19C88},
+	{0x19D00, 0x19D20},
+	{0x19E00, 0x19E7C},
+	{0x19E80, 0x19E94},
+	{0x19E98, 0x19EAC},
+	{0x19EB0, 0x19EBC},
+	{0x19F70, 0x19F74},
+	{0x19F80, 0x19F8C},
+	{0x19FA0, 0x19FB4},
+	{0x19FC0, 0x19FD8},
+	{0x1A000, 0x1A200},
+	{0x1A204, 0x1A210},
+	{0x1A228, 0x1A22C},
+	{0x1A230, 0x1A248},
+	{0x1A250, 0x1A270},
+	{0x1A280, 0x1A290},
+	{0x1A2A0, 0x1A2A4},
+	{0x1A2C0, 0x1A2EC},
+	{0x1A300, 0x1A3BC},
+	{0x1A3F0, 0x1A3F4},
+	{0x1A3F8, 0x1A434},
+	{0x1A438, 0x1A444},
+	{0x1A448, 0x1A468},
+	{0x1A580, 0x1A58C},
+	{0x1A644, 0x1A654},
+	{0x1A670, 0x1A698},
+	{0x1A6AC, 0x1A6B0},
+	{0x1A6D0, 0x1A6D4},
+	{0x1A6EC, 0x1A70C},
+	{0x1A710, 0x1A738},
+	{0x1A7C0, 0x1A7D0},
+	{0x1A7D4, 0x1A7D8},
+	{0x1A7DC, 0x1A7E4},
+	{0x1A7F0, 0x1A7F8},
+	{0x1A888, 0x1A89C},
+	{0x1A8A8, 0x1A8AC},
+	{0x1A8C0, 0x1A8DC},
+	{0x1A8F0, 0x1A8FC},
+	{0x1AE04, 0x1AE08},
+	{0x1AE18, 0x1AE24},
+	{0x1AF80, 0x1AF8C},
+	{0x1AFA0, 0x1AFB4},
+	{0x1B000, 0x1B200},
+	{0x1B284, 0x1B288},
+	{0x1B2D0, 0x1B2D8},
+	{0x1B2DC, 0x1B2EC},
+	{0x1B300, 0x1B340},
+	{0x1B374, 0x1B378},
+	{0x1B380, 0x1B384},
+	{0x1B388, 0x1B38C},
+	{0x1B404, 0x1B408},
+	{0x1B420, 0x1B428},
+	{0x1B440, 0x1B444},
+	{0x1B448, 0x1B44C},
+	{0x1B450, 0x1B458},
+	{0x1B45C, 0x1B468},
+	{0x1B584, 0x1B58C},
+	{0x1B68C, 0x1B690},
+	{0x1B6AC, 0x1B6B0},
+	{0x1B7F0, 0x1B7F8},
+	{0x1C800, 0x1CC00},
+	{0x1CE00, 0x1CE04},
+	{0x1CF80, 0x1CF84},
+	{0x1D200, 0x1D800},
+	{0x1E000, 0x20014},
+	{0x20100, 0x20124},
+	{0x21400, 0x217A8},
+	{0x21800, 0x21BA8},
+	{0x21C00, 0x21FA8},
+	{0x22000, 0x223A8},
+	{0x22400, 0x227A8},
+	{0x22800, 0x22BA8},
+	{0x22C00, 0x22FA8},
+	{0x23000, 0x233A8},
+	{0x24000, 0x24034},
+
+	/*
+	 * EFUSE0,1,2 is disabled here
+	 * because it's state may be reset
+	 *
+	 * {0x24800, 0x24804},
+	 * {0x25000, 0x25004},
+	 * {0x25800, 0x25804},
+	 */
+
+	{0x26000, 0x26064},
+	{0x27000, 0x27024},
+	{0x34000, 0x3400C},
+	{0x34400, 0x3445C},
+	{0x34800, 0x3485C},
+	{0x34C00, 0x34C5C},
+	{0x35000, 0x3505C},
+	{0x35400, 0x3545C},
+	{0x35800, 0x3585C},
+	{0x35C00, 0x35C5C},
+	{0x36000, 0x3605C},
+	{0x38000, 0x38064},
+	{0x38070, 0x380E0},
+	{0x3A000, 0x3A074},
+
+	/*
+	 * DBI windows is skipped here, it can be only accessed when pcie
+	 * is active (not in reset) and CORE_CTRL_PCIE_LTSSM_EN = 0 &&
+	 * PCIE_CTRL_APP_LTSSM_ENALBE=0.
+	 * {0x3C000 , 0x3C004},
+	 */
+
+	{0x40000, 0x400A4},
+
+	/*
+	 * SI register is skiped here.
+	 * Because it will cause bus hang
+	 *
+	 * {0x50000, 0x50018},
+	 */
+
+	{0x80000, 0x8000C},
+	{0x80010, 0x80020},
+};
+#else
+static const struct tgt_reg_section ar6320v3_reg_table[] = {
+	{0x800, 0x810},
+	{0x820, 0x82C},
+	{0x830, 0x8F4},
+	{0x90C, 0x91C},
+	{0xA14, 0xA18},
+	{0xA84, 0xA94},
+	{0xAA8, 0xAD4},
+	{0xADC, 0xB40},
+	{0x1000, 0x10A4},
+	{0x10BC, 0x111C},
+	{0x1134, 0x1138},
+	{0x1144, 0x114C},
+	{0x1150, 0x115C},
+	{0x1160, 0x1178},
+	{0x1240, 0x1260},
+	{0x2000, 0x207C},
+	{0x3000, 0x3014},
+	{0x4000, 0x4014},
+	{0x5000, 0x5124},
+	{0x6000, 0x6040},
+	{0x6080, 0x60CC},
+	{0x6100, 0x611C},
+	{0x6140, 0x61D8},
+	{0x6200, 0x6238},
+	{0x6240, 0x628C},
+	{0x62C0, 0x62EC},
+	{0x6380, 0x63E8},
+	{0x6400, 0x6440},
+	{0x6480, 0x64CC},
+	{0x6500, 0x651C},
+	{0x6540, 0x6580},
+	{0x6600, 0x6638},
+	{0x6640, 0x668C},
+	{0x66C0, 0x66EC},
+	{0x6780, 0x67E8},
+	{0x7080, 0x708C},
+	{0x70C0, 0x70C8},
+	{0x7400, 0x741C},
+	{0x7440, 0x7454},
+	{0x7800, 0x7818},
+	{0x8000, 0x8004},
+	{0x8010, 0x8064},
+	{0x8080, 0x8084},
+	{0x80A0, 0x80A4},
+	{0x80C0, 0x80C4},
+	{0x80E0, 0x80F4},
+	{0x8100, 0x8104},
+	{0x8110, 0x812C},
+	{0x9000, 0x9004},
+	{0x9800, 0x982C},
+	{0x9830, 0x9838},
+	{0x9840, 0x986C},
+	{0x9870, 0x9898},
+	{0x9A00, 0x9C00},
+	{0xD580, 0xD59C},
+	{0xF000, 0xF0E0},
+	{0xF140, 0xF190},
+	{0xF250, 0xF25C},
+	{0xF260, 0xF268},
+	{0xF26C, 0xF2A8},
+	{0x10008, 0x1000C},
+	{0x10014, 0x10018},
+	{0x1001C, 0x10020},
+	{0x10024, 0x10028},
+	{0x10030, 0x10034},
+	{0x10040, 0x10054},
+	{0x10058, 0x1007C},
+	{0x10080, 0x100C4},
+	{0x100C8, 0x10114},
+	{0x1012C, 0x10130},
+	{0x10138, 0x10144},
+	{0x10200, 0x10220},
+	{0x10230, 0x10250},
+	{0x10260, 0x10280},
+	{0x10290, 0x102B0},
+	{0x102C0, 0x102DC},
+	{0x102E0, 0x102F4},
+	{0x102FC, 0x1037C},
+	{0x10380, 0x10390},
+	{0x10800, 0x10828},
+	{0x10840, 0x10844},
+	{0x10880, 0x10884},
+	{0x108C0, 0x108E8},
+	{0x10900, 0x10928},
+	{0x10940, 0x10944},
+	{0x10980, 0x10984},
+	{0x109C0, 0x109E8},
+	{0x10A00, 0x10A28},
+	{0x10A40, 0x10A50},
+	{0x11000, 0x11028},
+	{0x11030, 0x11034},
+	{0x11038, 0x11068},
+	{0x11070, 0x11074},
+	{0x11078, 0x110A8},
+	{0x110B0, 0x110B4},
+	{0x110B8, 0x110E8},
+	{0x110F0, 0x110F4},
+	{0x110F8, 0x11128},
+	{0x11138, 0x11144},
+	{0x11178, 0x11180},
+	{0x111B8, 0x111C0},
+	{0x111F8, 0x11200},
+	{0x11238, 0x1123C},
+	{0x11270, 0x11274},
+	{0x11278, 0x1127C},
+	{0x112B0, 0x112B4},
+	{0x112B8, 0x112BC},
+	{0x112F0, 0x112F4},
+	{0x112F8, 0x112FC},
+	{0x11338, 0x1133C},
+	{0x11378, 0x1137C},
+	{0x113B8, 0x113BC},
+	{0x113F8, 0x113FC},
+	{0x11438, 0x11440},
+	{0x11478, 0x11480},
+	{0x114B8, 0x114BC},
+	{0x114F8, 0x114FC},
+	{0x11538, 0x1153C},
+	{0x11578, 0x1157C},
+	{0x115B8, 0x115BC},
+	{0x115F8, 0x115FC},
+	{0x11638, 0x1163C},
+	{0x11678, 0x1167C},
+	{0x116B8, 0x116BC},
+	{0x116F8, 0x116FC},
+	{0x11738, 0x1173C},
+	{0x11778, 0x1177C},
+	{0x117B8, 0x117BC},
+	{0x117F8, 0x117FC},
+	{0x17000, 0x1701C},
+	{0x17020, 0x170AC},
+	{0x18000, 0x18050},
+	{0x18054, 0x18074},
+	{0x18080, 0x180D4},
+	{0x180DC, 0x18104},
+	{0x18108, 0x1813C},
+	{0x18144, 0x18148},
+	{0x18168, 0x18174},
+	{0x18178, 0x18180},
+	{0x181C8, 0x181E0},
+	{0x181E4, 0x181E8},
+	{0x181EC, 0x1820C},
+	{0x1825C, 0x18280},
+	{0x18284, 0x18290},
+	{0x18294, 0x182A0},
+	{0x18300, 0x18304},
+	{0x18314, 0x18320},
+	{0x18328, 0x18350},
+	{0x1835C, 0x1836C},
+	{0x18370, 0x18390},
+	{0x18398, 0x183AC},
+	{0x183BC, 0x183D8},
+	{0x183DC, 0x183F4},
+	{0x18400, 0x186F4},
+	{0x186F8, 0x1871C},
+	{0x18720, 0x18790},
+	{0x19800, 0x19830},
+	{0x19834, 0x19840},
+	{0x19880, 0x1989C},
+	{0x198A4, 0x198B0},
+	{0x198BC, 0x19900},
+	{0x19C00, 0x19C88},
+	{0x19D00, 0x19D20},
+	{0x19E00, 0x19E7C},
+	{0x19E80, 0x19E94},
+	{0x19E98, 0x19EAC},
+	{0x19EB0, 0x19EBC},
+	{0x19F70, 0x19F74},
+	{0x19F80, 0x19F8C},
+	{0x19FA0, 0x19FB4},
+	{0x19FC0, 0x19FD8},
+	{0x1A000, 0x1A200},
+	{0x1A204, 0x1A210},
+	{0x1A228, 0x1A22C},
+	{0x1A230, 0x1A248},
+	{0x1A250, 0x1A270},
+	{0x1A280, 0x1A290},
+	{0x1A2A0, 0x1A2A4},
+	{0x1A2C0, 0x1A2EC},
+	{0x1A300, 0x1A3BC},
+	{0x1A3F0, 0x1A3F4},
+	{0x1A3F8, 0x1A434},
+	{0x1A438, 0x1A444},
+	{0x1A448, 0x1A468},
+	{0x1A580, 0x1A58C},
+	{0x1A644, 0x1A654},
+	{0x1A670, 0x1A698},
+	{0x1A6AC, 0x1A6B0},
+	{0x1A6D0, 0x1A6D4},
+	{0x1A6EC, 0x1A70C},
+	{0x1A710, 0x1A738},
+	{0x1A7C0, 0x1A7D0},
+	{0x1A7D4, 0x1A7D8},
+	{0x1A7DC, 0x1A7E4},
+	{0x1A7F0, 0x1A7F8},
+	{0x1A888, 0x1A89C},
+	{0x1A8A8, 0x1A8AC},
+	{0x1A8C0, 0x1A8DC},
+	{0x1A8F0, 0x1A8FC},
+	{0x1AE04, 0x1AE08},
+	{0x1AE18, 0x1AE24},
+	{0x1AF80, 0x1AF8C},
+	{0x1AFA0, 0x1AFB4},
+	{0x1B000, 0x1B200},
+	{0x1B284, 0x1B288},
+	{0x1B2D0, 0x1B2D8},
+	{0x1B2DC, 0x1B2EC},
+	{0x1B300, 0x1B340},
+	{0x1B374, 0x1B378},
+	{0x1B380, 0x1B384},
+	{0x1B388, 0x1B38C},
+	{0x1B404, 0x1B408},
+	{0x1B420, 0x1B428},
+	{0x1B440, 0x1B444},
+	{0x1B448, 0x1B44C},
+	{0x1B450, 0x1B458},
+	{0x1B45C, 0x1B468},
+	{0x1B584, 0x1B58C},
+	{0x1B68C, 0x1B690},
+	{0x1B6AC, 0x1B6B0},
+	{0x1B7F0, 0x1B7F8},
+	{0x1C800, 0x1CC00},
+	{0x1CE00, 0x1CE04},
+	{0x1CF80, 0x1CF84},
+	{0x1D200, 0x1D800},
+	{0x1E000, 0x20014},
+	{0x20100, 0x20124},
+	{0x21400, 0x217A8},
+	{0x21800, 0x21BA8},
+	{0x21C00, 0x21FA8},
+	{0x22000, 0x223A8},
+	{0x22400, 0x227A8},
+	{0x22800, 0x22BA8},
+	{0x22C00, 0x22FA8},
+	{0x23000, 0x233A8},
+	{0x24000, 0x24034},
+
+	/*
+	 * EFUSE0,1,2 is disabled here
+	 * because it's state may be reset
+	 *
+	 * {0x24800, 0x24804},
+	 * {0x25000, 0x25004},
+	 * {0x25800, 0x25804},
+	 */
+
+	{0x26000, 0x26064},
+	{0x27000, 0x27024},
+	{0x34000, 0x3400C},
+	{0x34400, 0x3445C},
+	{0x34800, 0x3485C},
+	{0x34C00, 0x34C5C},
+	{0x35000, 0x3505C},
+	{0x35400, 0x3545C},
+	{0x35800, 0x3585C},
+	{0x35C00, 0x35C5C},
+	{0x36000, 0x3605C},
+	{0x38000, 0x38064},
+	{0x38070, 0x380E0},
+	{0x3A000, 0x3A074},
+
+	/*
+	 * DBI windows is skipped here, it can be only accessed when pcie
+	 * is active (not in reset) and CORE_CTRL_PCIE_LTSSM_EN = 0 &&
+	 * PCIE_CTRL_APP_LTSSM_ENALBE=0.
+	 * {0x3C000 , 0x3C004},
+	 */
+
+	{0x40000, 0x400A4},
+
+	/*
+	 * SI register is skiped here.
+	 * Because it will cause bus hang
+	 *
+	 * {0x50000, 0x50018},
+	 */
+
+	{0x80000, 0x8000C},
+	{0x80010, 0x80020},
+};
+#endif
+#endif /* #ifndef _AR6320V2_DBG_REGTABLE_H_ */
diff --git a/core/bmi/src/i_bmi.h b/core/bmi/src/i_bmi.h
new file mode 100644
index 0000000..0c1d93d
--- /dev/null
+++ b/core/bmi/src/i_bmi.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+/* ===================================================================
+ * Internal BMI Header File
+ */
+
+#ifndef _I_BMI_H_
+#define _I_BMI_H_
+
+#include "hif.h"
+#include "bmi_msg.h"
+#include "bmi.h"
+#include "ol_fw.h"
+#include "pld_common.h"
+
+/*
+ * Note that not all the register locations are accessible.
+ * A list of accessible target registers are specified with
+ * their start and end addresses in a table for given target
+ * version. We should NOT access other locations as either
+ * they are invalid locations or host does not have read
+ * access to it or the value of the particular register
+ * read might change
+ */
+#define REGISTER_LOCATION       0x00000800
+
+#define DRAM_LOCATION           0x00400000
+#ifdef HIF_PCI
+#define DRAM_SIZE               0x000a8000
+#else
+#define DRAM_SIZE               0x00098000
+#endif
+/* The local base addr is used to read the target dump using pcie I/O reads */
+#define DRAM_LOCAL_BASE_ADDR    (0x100000)
+
+/* Target IRAM config */
+#define FW_RAM_CONFIG_ADDRESS   0x0018
+#define IRAM1_LOCATION          0x00980000
+#define IRAM1_SIZE              0x00080000
+#define IRAM2_LOCATION          0x00a00000
+#define IRAM2_SIZE              0x00040000
+#ifdef HIF_SDIO
+#define IRAM_LOCATION           0x00980000
+#define IRAM_SIZE               0x000C0000
+#else
+#define IRAM_LOCATION           0x00980000
+#define IRAM_SIZE               0x00038000
+#endif
+
+#define AXI_LOCATION            0x000a0000
+#ifdef HIF_PCI
+#define AXI_SIZE                0x00018000
+#else
+#define AXI_SIZE                0x00020000
+#endif
+
+#define PCIE_READ_LIMIT         0x00005000
+
+#define SHA256_DIGEST_SIZE      32
+
+/* BMI LOGGING WRAPPERS */
+
+#define BMI_LOG(level, args...) QDF_TRACE(QDF_MODULE_ID_BMI, \
+					level, ##args)
+#define BMI_ERR(args ...)	BMI_LOG(QDF_TRACE_LEVEL_ERROR, args)
+#define BMI_DBG(args ...)	BMI_LOG(QDF_TRACE_LEVEL_DEBUG, args)
+#define BMI_WARN(args ...)	BMI_LOG(QDF_TRACE_LEVEL_WARN, args)
+#define BMI_INFO(args ...)	BMI_LOG(QDF_TRACE_LEVEL_INFO, args)
+/* End of BMI Logging Wrappers */
+
+/* BMI Assert Wrappers */
+#define bmi_assert QDF_BUG
+/*
+ * Although we had envisioned BMI to run on top of HTC, this is not how the
+ * final implementation ended up. On the Target side, BMI is a part of the BSP
+ * and does not use the HTC protocol nor even DMA -- it is intentionally kept
+ * very simple.
+ */
+
+#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
+			sizeof(uint32_t) /* cmd */ + \
+			sizeof(uint32_t) /* addr */ + \
+			sizeof(uint32_t))    /* length */
+#define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ)
+#define BMI_EXCHANGE_TIMEOUT_MS  1000
+
+struct hash_fw {
+	u8 qwlan[SHA256_DIGEST_SIZE];
+	u8 otp[SHA256_DIGEST_SIZE];
+	u8 bdwlan[SHA256_DIGEST_SIZE];
+	u8 utf[SHA256_DIGEST_SIZE];
+};
+
+enum ATH_BIN_FILE {
+	ATH_OTP_FILE,
+	ATH_FIRMWARE_FILE,
+	ATH_PATCH_FILE,
+	ATH_BOARD_DATA_FILE,
+	ATH_FLASH_FILE,
+	ATH_SETUP_FILE,
+};
+
+#if defined(QCA_WIFI_3_0_ADRASTEA)
+#define NO_BMI 1
+#else
+#define NO_BMI 0
+#endif
+
+/**
+ * struct bmi_info - Structure to hold BMI Specific information
+ * @bmi_cmd_buff - BMI Command Buffer
+ * @bmi_rsp_buff - BMI Response Buffer
+ * @bmi_cmd_da - BMI Command Physical address
+ * @bmi_rsp_da - BMI Response Physical address
+ * @bmi_done - Flag to check if BMI Phase is complete
+ * @board_id - board ID
+ * @fw_files - FW files
+ *
+ */
+struct bmi_info {
+	uint8_t *bmi_cmd_buff;
+	uint8_t *bmi_rsp_buff;
+	dma_addr_t bmi_cmd_da;
+	dma_addr_t bmi_rsp_da;
+	bool bmi_done;
+	uint16_t board_id;
+	struct pld_fw_files fw_files;
+};
+
+/**
+ * struct ol_context - Structure to hold OL context
+ * @bmi: BMI info
+ * @cal_in_flash: For Firmware Flash Download
+ * @qdf_dev: QDF Device
+ * @scn: HIF Context
+ * @ramdump_work: Work for Ramdump collection
+ * @fw_indication_work: Work for Fw inciation
+ * @tgt_def: Target Defnition pointer
+ *
+ * Structure to hold all ol BMI/Ramdump info
+ */
+struct ol_context {
+	struct bmi_info bmi;
+	struct ol_config_info cfg_info;
+	uint8_t *cal_in_flash;
+	qdf_device_t qdf_dev;
+	qdf_work_t ramdump_work;
+	qdf_work_t fw_indication_work;
+	struct hif_opaque_softc *scn;
+	struct targetdef_t {
+		struct targetdef_s *targetdef;
+	} tgt_def;
+};
+
+#define GET_BMI_CONTEXT(ol_ctx) ((struct bmi_info *)ol_ctx)
+
+QDF_STATUS bmi_execute(uint32_t address, uint32_t *param,
+				struct ol_context *ol_ctx);
+QDF_STATUS bmi_init(struct ol_context *ol_ctx);
+QDF_STATUS bmi_no_command(struct ol_context *ol_ctx);
+QDF_STATUS bmi_read_memory(uint32_t address, uint8_t *buffer, uint32_t length,
+					struct ol_context *ol_ctx);
+QDF_STATUS bmi_write_memory(uint32_t address, uint8_t *buffer, uint32_t length,
+					struct ol_context *ol_ctx);
+QDF_STATUS bmi_fast_download(uint32_t address, uint8_t *buffer, uint32_t length,
+					struct ol_context *ol_ctx);
+QDF_STATUS bmi_read_soc_register(uint32_t address,
+				uint32_t *param, struct ol_context *ol_ctx);
+QDF_STATUS bmi_write_soc_register(uint32_t address, uint32_t param,
+					struct ol_context *ol_ctx);
+QDF_STATUS bmi_get_target_info(struct bmi_target_info *targ_info,
+			       struct ol_context *ol_ctx);
+QDF_STATUS bmi_firmware_download(struct ol_context *ol_ctx);
+QDF_STATUS bmi_done_local(struct ol_context *ol_ctx);
+QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx);
+QDF_STATUS ol_configure_target(struct ol_context *ol_ctx);
+QDF_STATUS bmi_sign_stream_start(uint32_t address, uint8_t *buffer,
+				 uint32_t length, struct ol_context *ol_ctx);
+void ramdump_work_handler(void *arg);
+void fw_indication_work_handler(void *arg);
+struct ol_config_info *ol_get_ini_handle(struct ol_context *ol_ctx);
+
+#ifdef HIF_SDIO
+QDF_STATUS hif_reg_based_get_target_info(struct hif_opaque_softc *hif_ctx,
+		  struct bmi_target_info *targ_info);
+#endif
+#if defined(HIF_PCI) || defined(SNOC) || defined(HIF_AHB) || defined(HIF_USB)
+static inline QDF_STATUS
+hif_reg_based_get_target_info(struct hif_opaque_softc *hif_ctx,
+		  struct bmi_target_info *targ_info)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#endif
diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c
new file mode 100644
index 0000000..c49dc32
--- /dev/null
+++ b/core/bmi/src/ol_fw.c
@@ -0,0 +1,1895 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#include <linux/firmware.h>
+#include "ol_if_athvar.h"
+#include "targaddrs.h"
+#include "ol_cfg.h"
+#include "cds_api.h"
+#include "wma_api.h"
+#include "wma.h"
+#include "bin_sig.h"
+#include "i_ar6320v2_regtable.h"
+#include "epping_main.h"
+#ifdef HIF_PCI
+#include "ce_reg.h"
+#endif
+#if defined(HIF_SDIO)
+#include "if_sdio.h"
+#include "regtable_sdio.h"
+#endif
+#if defined(HIF_USB)
+#include "if_usb.h"
+#include "regtable_usb.h"
+#endif
+#include "pld_common.h"
+#include "hif_main.h"
+
+#include "i_bmi.h"
+#include "qwlan_version.h"
+#include "wlan_policy_mgr_api.h"
+#include "dbglog_host.h"
+
+#ifdef FEATURE_SECURE_FIRMWARE
+static struct hash_fw fw_hash;
+#endif
+
+static uint32_t refclk_speed_to_hz[] = {
+	48000000,               /* SOC_REFCLK_48_MHZ */
+	19200000,               /* SOC_REFCLK_19_2_MHZ */
+	24000000,               /* SOC_REFCLK_24_MHZ */
+	26000000,               /* SOC_REFCLK_26_MHZ */
+	37400000,               /* SOC_REFCLK_37_4_MHZ */
+	38400000,               /* SOC_REFCLK_38_4_MHZ */
+	40000000,               /* SOC_REFCLK_40_MHZ */
+	52000000,               /* SOC_REFCLK_52_MHZ */
+};
+
+static int ol_target_coredump(void *inst, void *memory_block,
+					uint32_t block_len);
+
+#ifdef FEATURE_SECURE_FIRMWARE
+static int ol_check_fw_hash(struct device *dev, const u8 *data,
+			    u32 fw_size, enum ATH_BIN_FILE file)
+{
+	u8 *hash = NULL;
+	u8 *fw_mem = NULL;
+	u8 digest[SHA256_DIGEST_SIZE];
+	u8 temp[SHA256_DIGEST_SIZE] = { };
+	int ret = 0;
+
+	switch (file) {
+	case ATH_BOARD_DATA_FILE:
+		hash = fw_hash.bdwlan;
+		break;
+	case ATH_OTP_FILE:
+		hash = fw_hash.otp;
+		break;
+	case ATH_FIRMWARE_FILE:
+#ifdef QCA_WIFI_FTM
+		if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+			hash = fw_hash.utf;
+			break;
+		}
+#endif
+		hash = fw_hash.qwlan;
+	default:
+		break;
+	}
+
+	if (!hash) {
+		BMI_INFO("No entry for file:%d Download FW in non-secure mode",
+									file);
+		goto end;
+	}
+
+	if (qdf_mem_cmp(hash, temp, SHA256_DIGEST_SIZE)) {
+		BMI_INFO("Download FW in non-secure mode:%d", file);
+		goto end;
+	}
+
+	fw_mem = pld_get_fw_ptr(dev);
+	if (!fw_mem || (fw_size > MAX_FIRMWARE_SIZE)) {
+		BMI_ERR("No Memory to copy FW data");
+		ret = -1;
+		goto end;
+	}
+	qdf_mem_copy(fw_mem, data, fw_size);
+
+	ret = pld_get_sha_hash(dev, fw_mem, fw_size, "sha256", digest);
+
+	if (ret) {
+		BMI_ERR("Sha256 Hash computation failed err:%d", ret);
+		goto end;
+	}
+
+	if (qdf_mem_cmp(hash, digest, SHA256_DIGEST_SIZE)) {
+		BMI_ERR("Hash Mismatch");
+		qdf_trace_hex_dump(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
+				   digest, SHA256_DIGEST_SIZE);
+		qdf_trace_hex_dump(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
+				   hash, SHA256_DIGEST_SIZE);
+		ret = QDF_STATUS_E_FAILURE;
+	}
+end:
+	return ret;
+}
+#endif
+
+/**
+ * ol_board_id_to_filename() - Auto BDF board_id to filename conversion
+ * @old_name: name of the default board data file
+ * @board_id: board ID
+ *
+ * The API return board filename based on the board_id and chip_id.
+ * eg: input = "bdwlan30.bin", board_id = 0x01, board_file = "bdwlan30.b01"
+ * Return: The buffer with the formated board filename.
+ */
+static char *ol_board_id_to_filename(const char *old_name,
+				     uint16_t board_id)
+{
+	int name_len;
+	char *new_name;
+
+	name_len = strlen(old_name);
+	new_name = qdf_mem_malloc(name_len + 1);
+
+	if (!new_name)
+		goto out;
+
+	if (board_id > 0xFF)
+		board_id = 0x0;
+
+	qdf_mem_copy(new_name, old_name, name_len);
+	snprintf(&new_name[name_len - 2], 3, "%.2x", board_id);
+out:
+	return new_name;
+}
+
+#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT
+#define SIGNED_SPLIT_BINARY_VALUE true
+#else
+#define SIGNED_SPLIT_BINARY_VALUE false
+#endif
+
+static int
+__ol_transfer_bin_file(struct ol_context *ol_ctx, enum ATH_BIN_FILE file,
+		       uint32_t address, bool compressed)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	int status = EOK;
+	const char *filename;
+	const struct firmware *fw_entry;
+	uint32_t fw_entry_size;
+	uint8_t *temp_eeprom;
+	uint32_t board_data_size;
+	bool bin_sign = false;
+	int bin_off, bin_len;
+	SIGN_HEADER_T *sign_header;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	uint32_t target_type = tgt_info->target_type;
+	struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx);
+	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
+	int i;
+
+	/*
+	 * If there is no board data file bases on board id, the default
+	 * board data file should be used.
+	 * For factory mode, the sequence for file selection should be
+	 * utfbd.board_id -> utfbd.bin -> bd.board_id -> bd.bin. So we
+	 * need to cache 4 file names.
+	 */
+	uint32_t bd_files = 1;
+	char *bd_id_filename[2] = {NULL, NULL};
+	const char *bd_filename[2] = {NULL, NULL};
+
+	switch (file) {
+	default:
+		BMI_ERR("%s: Unknown file type", __func__);
+		return -EINVAL;
+	case ATH_OTP_FILE:
+		filename = bmi_ctx->fw_files.otp_data;
+		if (SIGNED_SPLIT_BINARY_VALUE)
+			bin_sign = true;
+
+		break;
+	case ATH_FIRMWARE_FILE:
+		if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
+			filename = bmi_ctx->fw_files.epping_file;
+			BMI_INFO("%s: Loading epping firmware file %s",
+						__func__, filename);
+			break;
+		}
+#ifdef QCA_WIFI_FTM
+		if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+			filename = bmi_ctx->fw_files.utf_file;
+			if (SIGNED_SPLIT_BINARY_VALUE)
+				bin_sign = true;
+			BMI_INFO("%s: Loading firmware file %s",
+						__func__, filename);
+			break;
+		}
+#endif
+		if (cds_get_conparam() == QDF_GLOBAL_IBSS_MODE &&
+		    (bmi_ctx->fw_files.ibss_image_file[0] != '\0')) {
+			filename = bmi_ctx->fw_files.ibss_image_file;
+		} else {
+			filename = bmi_ctx->fw_files.image_file;
+		}
+
+		if (SIGNED_SPLIT_BINARY_VALUE)
+			bin_sign = true;
+		break;
+	case ATH_PATCH_FILE:
+		BMI_INFO("%s: no Patch file defined", __func__);
+		return 0;
+	case ATH_BOARD_DATA_FILE:
+		filename = bmi_ctx->fw_files.board_data;
+#ifdef QCA_WIFI_FTM
+		if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+			filename = bmi_ctx->fw_files.utf_board_data;
+			if (SIGNED_SPLIT_BINARY_VALUE)
+				bin_sign = true;
+
+			BMI_INFO("%s: Loading board data file %s",
+						__func__, filename);
+
+			/*
+			 * In FTM mode, if utf files do not exit.
+			 * bdwlan should be used.
+			 */
+			bd_files = 2;
+		}
+#endif /* QCA_WIFI_FTM */
+		if (SIGNED_SPLIT_BINARY_VALUE)
+			bin_sign = false;
+
+		bd_filename[0] = filename;
+
+		/*
+		 * For factory mode, we should cache 2 group of file names.
+		 * For mission mode, bd_files==1, only one group of file names.
+		 */
+		bd_filename[bd_files - 1] =
+					bmi_ctx->fw_files.board_data;
+		for (i = 0; i < bd_files; i++) {
+			bd_id_filename[i] =
+				ol_board_id_to_filename(bd_filename[i],
+							bmi_ctx->board_id);
+			if (bd_id_filename[i]) {
+				BMI_INFO("%s: board data file is %s",
+					 __func__, bd_id_filename[i]);
+			} else {
+				BMI_ERR("%s: Fail to allocate board filename",
+					__func__);
+			}
+		}
+		break;
+	case ATH_SETUP_FILE:
+		if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE &&
+		    !QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
+			filename = bmi_ctx->fw_files.setup_file;
+			if (filename[0] == 0) {
+				BMI_INFO("%s: no Setup file defined", __func__);
+				return -EPERM;
+			}
+
+			if (SIGNED_SPLIT_BINARY_VALUE)
+				bin_sign = true;
+
+			BMI_INFO("%s: Loading setup file %s",
+			       __func__, filename);
+		} else {
+			BMI_INFO("%s: no Setup file needed", __func__);
+			return -EPERM;
+		}
+		break;
+	}
+
+	/* For FTM mode. bd.bin is used if there is no utf.bin */
+	if (file == ATH_BOARD_DATA_FILE) {
+		for (i = 0; i < bd_files; i++) {
+			if (bd_id_filename[i]) {
+				BMI_DBG("%s: Trying to load %s",
+					 __func__, bd_id_filename[i]);
+				status = request_firmware(&fw_entry,
+							  bd_id_filename[i],
+							  qdf_dev->dev);
+				if (!status)
+					break;
+				BMI_ERR("%s: Failed to get %s:%d",
+					__func__, bd_id_filename[i],
+					status);
+			}
+
+			/* bd.board_id not exits, using bd.bin */
+			BMI_DBG("%s: Trying to load default %s",
+				 __func__, bd_filename[i]);
+			status = request_firmware(&fw_entry, bd_filename[i],
+						  qdf_dev->dev);
+			if (!status)
+				break;
+			BMI_ERR("%s: Failed to get default %s:%d",
+				__func__, bd_filename[i], status);
+		}
+	} else {
+		status = request_firmware(&fw_entry, filename, qdf_dev->dev);
+	}
+
+	if (status) {
+		BMI_ERR("%s: Failed to get %s", __func__, filename);
+		status = -ENOENT;
+		goto release_fw;
+	}
+
+	if (!fw_entry || !fw_entry->data) {
+		BMI_ERR("Invalid fw_entries");
+		status = -ENOENT;
+		goto release_fw;
+	}
+
+	fw_entry_size = fw_entry->size;
+	temp_eeprom = NULL;
+
+#ifdef FEATURE_SECURE_FIRMWARE
+	if (ol_check_fw_hash(qdf_dev->dev, fw_entry->data,
+			     fw_entry_size, file)) {
+		BMI_ERR("Hash Check failed for file:%s", filename);
+		status = -EINVAL;
+		goto end;
+	}
+#endif
+
+	if (file == ATH_BOARD_DATA_FILE) {
+		uint32_t board_ext_address = 0;
+		int32_t board_ext_data_size;
+
+		temp_eeprom = qdf_mem_malloc(fw_entry_size);
+		if (!temp_eeprom) {
+			BMI_ERR("%s: Memory allocation failed", __func__);
+			status = -ENOMEM;
+			goto release_fw;
+		}
+
+		qdf_mem_copy(temp_eeprom, (uint8_t *) fw_entry->data,
+			  fw_entry_size);
+
+		switch (target_type) {
+		case TARGET_TYPE_AR6004:
+			board_data_size = AR6004_BOARD_DATA_SZ;
+			board_ext_data_size = AR6004_BOARD_EXT_DATA_SZ;
+			break;
+		case TARGET_TYPE_AR9888:
+			board_data_size = AR9888_BOARD_DATA_SZ;
+			board_ext_data_size = AR9888_BOARD_EXT_DATA_SZ;
+			break;
+		default:
+			board_data_size = 0;
+			board_ext_data_size = 0;
+			break;
+		}
+
+		/* Determine where in Target RAM to write Board Data */
+		bmi_read_memory(HOST_INTEREST_ITEM_ADDRESS(target_type,
+							   hi_board_ext_data),
+				(uint8_t *) &board_ext_address, 4, ol_ctx);
+		BMI_INFO("Board extended Data download address: 0x%x",
+		       board_ext_address);
+
+		/* Check whether the target has allocated memory for extended
+		 * board data and file contains extended board data
+		 */
+
+		if ((board_ext_address)
+		    && (fw_entry_size ==
+			(board_data_size + board_ext_data_size))) {
+			uint32_t param;
+
+			status = bmi_write_memory(board_ext_address,
+					(uint8_t *)(temp_eeprom +
+					board_data_size),
+					board_ext_data_size, ol_ctx);
+
+			if (status != EOK)
+				goto end;
+
+			/* Record extended board Data initialized */
+			param = (board_ext_data_size << 16) | 1;
+			bmi_write_memory(
+				HOST_INTEREST_ITEM_ADDRESS(target_type,
+					hi_board_ext_data_config),
+					(uint8_t *)&param, 4, ol_ctx);
+
+			fw_entry_size = board_data_size;
+		}
+	}
+
+	if (bin_sign && SIGNED_SPLIT_BINARY_VALUE) {
+		uint32_t chip_id;
+
+		if (fw_entry_size < sizeof(SIGN_HEADER_T)) {
+			BMI_ERR("Invalid binary size %d", fw_entry_size);
+			status = -EINVAL;
+			goto end;
+		}
+
+		sign_header = (SIGN_HEADER_T *) fw_entry->data;
+		chip_id = cpu_to_le32(sign_header->product_id);
+		if (sign_header->magic_num == SIGN_HEADER_MAGIC
+		    && (chip_id == AR6320_REV1_1_VERSION
+			|| chip_id == AR6320_REV1_3_VERSION
+			|| chip_id == AR6320_REV2_1_VERSION)) {
+
+			bin_off = sizeof(SIGN_HEADER_T);
+			status = bmi_sign_stream_start(address,
+						(uint8_t *)fw_entry->data,
+						bin_off, ol_ctx);
+			if (status != EOK) {
+				BMI_ERR("unable to start sign stream");
+				status = -EINVAL;
+				goto end;
+			}
+
+			bin_len = sign_header->rampatch_len - bin_off;
+			if (bin_len <= 0 || bin_len > fw_entry_size - bin_off) {
+				BMI_ERR("Invalid sign header");
+				status = -EINVAL;
+				goto end;
+			}
+		} else {
+			bin_sign = false;
+			bin_off = 0;
+			bin_len = fw_entry_size;
+		}
+	} else {
+		bin_len = fw_entry_size;
+		bin_off = 0;
+	}
+
+	if (compressed) {
+		status = bmi_fast_download(address,
+					   (uint8_t *) fw_entry->data + bin_off,
+					   bin_len, ol_ctx);
+	} else {
+		if (file == ATH_BOARD_DATA_FILE && fw_entry->data) {
+			status = bmi_write_memory(address,
+						  (uint8_t *) temp_eeprom,
+						  fw_entry_size, ol_ctx);
+		} else {
+			status = bmi_write_memory(address,
+						  (uint8_t *) fw_entry->data
+						  + bin_off, bin_len, ol_ctx);
+		}
+	}
+
+	if (bin_sign && SIGNED_SPLIT_BINARY_VALUE) {
+		bin_off += bin_len;
+		bin_len = sign_header->total_len - sign_header->rampatch_len;
+
+		if (bin_len > 0 && bin_len <= fw_entry_size - bin_off) {
+			status = bmi_sign_stream_start(0,
+					(uint8_t *)fw_entry->data +
+					bin_off, bin_len, ol_ctx);
+			if (status != EOK)
+				BMI_ERR("sign stream error");
+		}
+	}
+
+end:
+	if (temp_eeprom)
+		qdf_mem_free(temp_eeprom);
+
+release_fw:
+	if (fw_entry)
+		release_firmware(fw_entry);
+
+	for (i = 0; i < bd_files; i++) {
+		if (bd_id_filename[i]) {
+			qdf_mem_free(bd_id_filename[i]);
+			bd_id_filename[i] = NULL;
+		}
+	}
+
+	if (status != EOK)
+		BMI_ERR("%s, BMI operation failed: %d", __func__, __LINE__);
+	else
+		BMI_INFO("transferring file: %s size %d bytes done!",
+			 (filename != NULL) ? filename : " ", fw_entry_size);
+	return status;
+}
+
+static int
+ol_transfer_bin_file(struct ol_context *ol_ctx, enum ATH_BIN_FILE file,
+		     uint32_t address, bool compressed)
+{
+	int ret;
+	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
+
+	/* Wait until suspend and resume are completed before loading FW */
+	pld_lock_pm_sem(qdf_dev->dev);
+
+	ret = __ol_transfer_bin_file(ol_ctx, file, address, compressed);
+
+	pld_release_pm_sem(qdf_dev->dev);
+
+	return ret;
+}
+
+/**
+ * struct ramdump_info: Structure to hold ramdump information
+ * @base: Base address for Ramdump collection
+ * @size: Size of the dump
+ *
+ * Ramdump information.
+ */
+struct ramdump_info {
+	void *base;
+	unsigned long size;
+};
+
+#if !defined(QCA_WIFI_3_0)
+static inline void ol_get_ramdump_mem(struct device *dev,
+				      struct ramdump_info *info)
+{
+	info->base = pld_get_virt_ramdump_mem(dev, &info->size);
+}
+#else
+static inline void ol_get_ramdump_mem(struct device *dev,
+				      struct ramdump_info *info) { }
+#endif
+
+int ol_copy_ramdump(struct hif_opaque_softc *scn)
+{
+	int ret = -1;
+	struct ramdump_info *info;
+	qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	if (!qdf_dev) {
+		BMI_ERR("%s qdf_dev is NULL", __func__);
+		return -EINVAL;
+	}
+	if (pld_is_fw_dump_skipped(qdf_dev->dev)) {
+		BMI_INFO("%s ssr enabled, skip ramdump", __func__);
+		return 0;
+	}
+	info = qdf_mem_malloc(sizeof(struct ramdump_info));
+	if (!info) {
+		BMI_ERR("%s Memory for Ramdump Allocation failed", __func__);
+		return -ENOMEM;
+	}
+
+	ol_get_ramdump_mem(qdf_dev->dev, info);
+
+	if (!info->base || !info->size) {
+		BMI_ERR("%s:ramdump collection fail", __func__);
+		qdf_mem_free(info);
+		return -EACCES;
+	}
+
+	ret = ol_target_coredump(scn, info->base, info->size);
+
+	qdf_mem_free(info);
+	return ret;
+}
+
+void ramdump_work_handler(void *data)
+{
+	int ret;
+	uint32_t host_interest_address;
+	uint32_t dram_dump_values[4];
+	uint32_t target_type;
+	struct hif_target_info *tgt_info;
+	struct ol_context *ol_ctx = data;
+	struct hif_opaque_softc *ramdump_scn = ol_ctx->scn;
+	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
+	struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
+
+	if (!ramdump_scn) {
+		BMI_ERR("%s:Ramdump_scn is null:", __func__);
+		goto out_fail;
+	}
+	tgt_info = hif_get_target_info_handle(ramdump_scn);
+	target_type = tgt_info->target_type;
+#ifdef WLAN_DEBUG
+	ret = hif_check_soc_status(ramdump_scn);
+	if (ret)
+		goto out_fail;
+
+	ret = hif_dump_registers(ramdump_scn);
+	if (ret)
+		goto out_fail;
+
+#endif
+
+	if (hif_diag_read_mem(ramdump_scn,
+			hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_failure_state)),
+			(uint8_t *)&host_interest_address,
+			sizeof(uint32_t)) != QDF_STATUS_SUCCESS) {
+		BMI_ERR("HifDiagReadiMem FW Dump Area Pointer failed!");
+		ol_copy_ramdump(ramdump_scn);
+		pld_device_crashed(qdf_dev->dev);
+
+		return;
+	}
+
+	BMI_ERR("Host interest item address: 0x%08x", host_interest_address);
+
+	if (hif_diag_read_mem(ramdump_scn, host_interest_address,
+			      (uint8_t *) &dram_dump_values[0],
+			      4 * sizeof(uint32_t)) != QDF_STATUS_SUCCESS) {
+		BMI_ERR("HifDiagReadiMem FW Dump Area failed!");
+		goto out_fail;
+	}
+	BMI_ERR("FW Assertion at PC: 0x%08x BadVA: 0x%08x TargetID: 0x%08x",
+	       dram_dump_values[2], dram_dump_values[3], dram_dump_values[0]);
+
+	if (ol_copy_ramdump(ramdump_scn))
+		goto out_fail;
+
+	BMI_ERR("%s: RAM dump collecting completed!", __func__);
+
+	/*
+	 * if unloading is in progress, then skip SSR,
+	 * otherwise notify SSR framework the target has crashed.
+	 */
+	if (cds_is_load_or_unload_in_progress())
+		cds_set_recovery_in_progress(false);
+	else
+		pld_device_crashed(qdf_dev->dev);
+	return;
+
+out_fail:
+	/* Silent SSR on dump failure */
+	if (ini_cfg->enable_self_recovery)
+		pld_device_self_recovery(qdf_dev->dev,
+					 PLD_REASON_DEFAULT);
+	else
+		pld_device_crashed(qdf_dev->dev);
+}
+
+void fw_indication_work_handler(void *data)
+{
+	struct ol_context *ol_ctx = data;
+	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
+
+	pld_device_self_recovery(qdf_dev->dev,
+				 PLD_REASON_DEFAULT);
+}
+
+void ol_target_failure(void *instance, QDF_STATUS status)
+{
+	struct ol_context *ol_ctx = instance;
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
+	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
+	int ret;
+	enum hif_target_status target_status = hif_get_target_status(scn);
+
+	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SNOC) {
+		BMI_ERR("SNOC doesn't suppor this code path!");
+		return;
+	}
+
+	qdf_event_set(&wma->recovery_event);
+
+	if (TARGET_STATUS_RESET == target_status) {
+		BMI_ERR("Target is already asserted, ignore!");
+		return;
+	}
+
+	hif_set_target_status(scn, TARGET_STATUS_RESET);
+
+	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_USB) {
+		if (status == QDF_STATUS_E_USB_ERROR)
+			hif_ramdump_handler(scn);
+		return;
+	}
+
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		BMI_ERR("%s: Recovery in progress, ignore!\n", __func__);
+		return;
+	}
+
+	if (cds_is_load_or_unload_in_progress()) {
+		BMI_ERR("%s: Loading/Unloading is in progress, ignore!",
+		       __func__);
+		return;
+	}
+	cds_set_recovery_in_progress(true);
+
+	ret = hif_check_fw_reg(scn);
+	if (0 == ret) {
+		if (ini_cfg->enable_self_recovery) {
+			qdf_sched_work(0, &ol_ctx->fw_indication_work);
+			return;
+		}
+	} else if (-1 == ret) {
+		return;
+	}
+
+	BMI_ERR("XXX TARGET ASSERTED XXX");
+
+	cds_svc_fw_shutdown_ind(qdf_dev->dev);
+	/* Collect the RAM dump through a workqueue */
+	if (ini_cfg->enable_ramdump_collection)
+		qdf_sched_work(0, &ol_ctx->ramdump_work);
+	else
+		pr_debug("%s: athdiag read for target reg\n", __func__);
+}
+
+#ifdef CONFIG_DISABLE_CDC_MAX_PERF_WAR
+static QDF_STATUS ol_disable_cdc_max_perf(struct ol_context *ol_ctx)
+{
+	uint32_t param;
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	uint32_t target_type = tgt_info->target_type;
+
+	/* set the firmware to disable CDC max perf WAR */
+		if (bmi_read_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag2)),
+			(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+			BMI_ERR("BMI READ for setting cdc max perf failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		param |= HI_OPTION_DISABLE_CDC_MAX_PERF_WAR;
+		if (bmi_write_memory(
+			hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag2)),
+			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+			BMI_ERR("setting cdc max perf failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#else
+static QDF_STATUS ol_disable_cdc_max_perf(struct ol_context *ol_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif
+
+#ifdef WLAN_FEATURE_LPSS
+static QDF_STATUS ol_set_lpass_support(struct ol_context *ol_ctx)
+{
+	uint32_t param;
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
+	uint32_t target_type = tgt_info->target_type;
+
+	if (ini_cfg->enable_lpass_support) {
+		if (bmi_read_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag2)),
+			(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+			BMI_ERR("BMI READ:Setting LPASS Support failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		param |= HI_OPTION_DBUART_SUPPORT;
+		if (bmi_write_memory(
+			hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag2)),
+			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+			BMI_ERR("BMI_READ for setting LPASS Support fail");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#else
+static QDF_STATUS ol_set_lpass_support(struct ol_context *ol_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif
+
+
+QDF_STATUS ol_configure_target(struct ol_context *ol_ctx)
+{
+	uint32_t param;
+	struct pld_platform_cap cap = {0};
+	int ret;
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	uint32_t target_type = tgt_info->target_type;
+	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
+
+	/* Tell target which HTC version it is used */
+	param = HTC_PROTOCOL_VERSION;
+	if (bmi_write_memory(
+		hif_hia_item_address(target_type,
+		offsetof(struct host_interest_s, hi_app_host_interest)),
+		(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+		BMI_ERR("bmi_write_memory for htc version failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* set the firmware mode to STA/IBSS/AP */
+	{
+		if (bmi_read_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag)),
+			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+			BMI_ERR("bmi_read_memory for setting fwmode failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		/* TODO following parameters need to be re-visited. */
+		param |= (1 << HI_OPTION_NUM_DEV_SHIFT); /* num_device */
+		/* Firmware mode ?? */
+		param |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT);
+		/* mac_addr_method */
+		param |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
+		/* firmware_bridge */
+		param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
+		/* fwsubmode */
+		param |= (0 << HI_OPTION_FW_SUBMODE_SHIFT);
+
+		BMI_INFO("NUM_DEV=%d FWMODE=0x%x FWSUBMODE=0x%x FWBR_BUF %d",
+		       1, HI_OPTION_FW_MODE_AP, 0, 0);
+
+		if (bmi_write_memory(
+			hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag)),
+			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+			BMI_ERR("BMI WRITE for setting fwmode failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI) {
+		if (ol_disable_cdc_max_perf(ol_ctx))
+			return QDF_STATUS_E_FAILURE;
+
+		qdf_mem_zero(&cap, sizeof(cap));
+
+		ret = pld_get_platform_cap(qdf_dev->dev, &cap);
+		if (ret)
+			BMI_ERR("platform capability info not available");
+
+		if (!ret && cap.cap_flag & PLD_HAS_EXTERNAL_SWREG) {
+			if (bmi_read_memory(hif_hia_item_address(target_type,
+				offsetof(struct host_interest_s,
+					 hi_option_flag2)),
+				(uint8_t *)&param, 4, ol_ctx) !=
+							QDF_STATUS_SUCCESS) {
+				BMI_ERR("BMI READ failed for external SWREG");
+				return QDF_STATUS_E_FAILURE;
+			}
+
+			param |= HI_OPTION_USE_EXT_LDO;
+			if (bmi_write_memory(
+				hif_hia_item_address(target_type,
+					offsetof(struct host_interest_s,
+						 hi_option_flag2)),
+					(uint8_t *)&param, 4, ol_ctx) !=
+							QDF_STATUS_SUCCESS) {
+				BMI_ERR("BMI WRITE failed for external SWREG");
+				return QDF_STATUS_E_FAILURE;
+			}
+		}
+
+		if (ol_set_lpass_support(ol_ctx))
+			return QDF_STATUS_E_FAILURE;
+	}
+
+	/* If host is running on a BE CPU, set the host interest area */
+	{
+#ifdef BIG_ENDIAN_HOST
+		param = 1;
+#else
+		param = 0;
+#endif
+		if (bmi_write_memory(
+			hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_be)),
+			(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+			BMI_ERR("setting host CPU BE mode failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	/* FW descriptor/Data swap flags */
+	param = 0;
+	if (bmi_write_memory(
+		hif_hia_item_address(target_type,
+		offsetof(struct host_interest_s, hi_fw_swap)),
+		(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+		BMI_ERR("BMI WRITE failed setting FW data/desc swap flags");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static int
+ol_check_dataset_patch(struct hif_opaque_softc *scn, uint32_t *address)
+{
+	/* Check if patch file needed for this target type/version. */
+	return 0;
+}
+
+static QDF_STATUS ol_fw_populate_clk_settings(enum a_refclk_speed_t refclk,
+					      struct cmnos_clock_s *clock_s)
+{
+	if (!clock_s)
+		return QDF_STATUS_E_FAILURE;
+
+	switch (refclk) {
+	case SOC_REFCLK_48_MHZ:
+		clock_s->wlan_pll.div = 0xE;
+		clock_s->wlan_pll.rnfrac = 0x2AAA8;
+		clock_s->pll_settling_time = 2400;
+		break;
+	case SOC_REFCLK_19_2_MHZ:
+		clock_s->wlan_pll.div = 0x24;
+		clock_s->wlan_pll.rnfrac = 0x2AAA8;
+		clock_s->pll_settling_time = 960;
+		break;
+	case SOC_REFCLK_24_MHZ:
+		clock_s->wlan_pll.div = 0x1D;
+		clock_s->wlan_pll.rnfrac = 0x15551;
+		clock_s->pll_settling_time = 1200;
+		break;
+	case SOC_REFCLK_26_MHZ:
+		clock_s->wlan_pll.div = 0x1B;
+		clock_s->wlan_pll.rnfrac = 0x4EC4;
+		clock_s->pll_settling_time = 1300;
+		break;
+	case SOC_REFCLK_37_4_MHZ:
+		clock_s->wlan_pll.div = 0x12;
+		clock_s->wlan_pll.rnfrac = 0x34B49;
+		clock_s->pll_settling_time = 1870;
+		break;
+	case SOC_REFCLK_38_4_MHZ:
+		clock_s->wlan_pll.div = 0x12;
+		clock_s->wlan_pll.rnfrac = 0x15551;
+		clock_s->pll_settling_time = 1920;
+		break;
+	case SOC_REFCLK_40_MHZ:
+		clock_s->wlan_pll.div = 0x11;
+		clock_s->wlan_pll.rnfrac = 0x26665;
+		clock_s->pll_settling_time = 2000;
+		break;
+	case SOC_REFCLK_52_MHZ:
+		clock_s->wlan_pll.div = 0x1B;
+		clock_s->wlan_pll.rnfrac = 0x4EC4;
+		clock_s->pll_settling_time = 2600;
+		break;
+	case SOC_REFCLK_UNKNOWN:
+		clock_s->wlan_pll.refdiv = 0;
+		clock_s->wlan_pll.div = 0;
+		clock_s->wlan_pll.rnfrac = 0;
+		clock_s->wlan_pll.outdiv = 0;
+		clock_s->pll_settling_time = 1024;
+		clock_s->refclk_hz = 0;
+	default:
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	clock_s->refclk_hz = refclk_speed_to_hz[refclk];
+	clock_s->wlan_pll.refdiv = 0;
+	clock_s->wlan_pll.outdiv = 1;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS ol_patch_pll_switch(struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *hif = ol_ctx->scn;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t addr = 0;
+	uint32_t reg_val = 0;
+	uint32_t mem_val = 0;
+	struct cmnos_clock_s clock_s;
+	uint32_t cmnos_core_clk_div_addr = 0;
+	uint32_t cmnos_cpu_pll_init_done_addr = 0;
+	uint32_t cmnos_cpu_speed_addr = 0;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(hif);
+	uint32_t target_version = tgt_info->target_version;
+	struct targetdef_t *scn = &ol_ctx->tgt_def;
+
+	switch (target_version) {
+	case AR6320_REV1_1_VERSION:
+		cmnos_core_clk_div_addr = AR6320_CORE_CLK_DIV_ADDR;
+		cmnos_cpu_pll_init_done_addr = AR6320_CPU_PLL_INIT_DONE_ADDR;
+		cmnos_cpu_speed_addr = AR6320_CPU_SPEED_ADDR;
+		break;
+	case AR6320_REV1_3_VERSION:
+	case AR6320_REV2_1_VERSION:
+		cmnos_core_clk_div_addr = AR6320V2_CORE_CLK_DIV_ADDR;
+		cmnos_cpu_pll_init_done_addr = AR6320V2_CPU_PLL_INIT_DONE_ADDR;
+		cmnos_cpu_speed_addr = AR6320V2_CPU_SPEED_ADDR;
+		break;
+	case AR6320_REV3_VERSION:
+	case AR6320_REV3_2_VERSION:
+	case QCA9379_REV1_VERSION:
+	case QCA9377_REV1_1_VERSION:
+		cmnos_core_clk_div_addr = AR6320V3_CORE_CLK_DIV_ADDR;
+		cmnos_cpu_pll_init_done_addr = AR6320V3_CPU_PLL_INIT_DONE_ADDR;
+		cmnos_cpu_speed_addr = AR6320V3_CPU_SPEED_ADDR;
+		break;
+	default:
+		BMI_ERR("%s: Unsupported target version %x", __func__,
+							target_version);
+		goto end;
+	}
+
+	addr = (RTC_SOC_BASE_ADDRESS | EFUSE_OFFSET);
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read EFUSE Addr");
+		goto end;
+	}
+
+	status = ol_fw_populate_clk_settings(EFUSE_XTAL_SEL_GET(reg_val),
+					     &clock_s);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to set clock settings");
+		goto end;
+	}
+	BMI_DBG("crystal_freq: %dHz", clock_s.refclk_hz);
+
+	/* ------Step 1---- */
+	reg_val = 0;
+	addr = (RTC_SOC_BASE_ADDRESS | BB_PLL_CONFIG_OFFSET);
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read PLL_CONFIG Addr");
+		goto end;
+	}
+	BMI_DBG("Step 1a: %8X", reg_val);
+
+	reg_val &= ~(BB_PLL_CONFIG_FRAC_MASK | BB_PLL_CONFIG_OUTDIV_MASK);
+	reg_val |= (BB_PLL_CONFIG_FRAC_SET(clock_s.wlan_pll.rnfrac) |
+		    BB_PLL_CONFIG_OUTDIV_SET(clock_s.wlan_pll.outdiv));
+	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to write PLL_CONFIG Addr");
+		goto end;
+	}
+
+	reg_val = 0;
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read back PLL_CONFIG Addr");
+		goto end;
+	}
+	BMI_DBG("Step 1b: %8X", reg_val);
+
+	/* ------Step 2---- */
+	reg_val = 0;
+	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_SETTLE_OFFSET);
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read PLL_SETTLE Addr");
+		goto end;
+	}
+	BMI_DBG("Step 2a: %8X", reg_val);
+
+	reg_val &= ~WLAN_PLL_SETTLE_TIME_MASK;
+	reg_val |= WLAN_PLL_SETTLE_TIME_SET(clock_s.pll_settling_time);
+	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to write PLL_SETTLE Addr");
+		goto end;
+	}
+
+	reg_val = 0;
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read back PLL_SETTLE Addr");
+		goto end;
+	}
+	BMI_DBG("Step 2b: %8X", reg_val);
+
+	/* ------Step 3---- */
+	reg_val = 0;
+	addr = (RTC_SOC_BASE_ADDRESS | SOC_CORE_CLK_CTRL_OFFSET);
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read CLK_CTRL Addr");
+		goto end;
+	}
+	BMI_DBG("Step 3a: %8X", reg_val);
+
+	reg_val &= ~SOC_CORE_CLK_CTRL_DIV_MASK;
+	reg_val |= SOC_CORE_CLK_CTRL_DIV_SET(1);
+	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to write CLK_CTRL Addr");
+		goto end;
+	}
+
+	reg_val = 0;
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read back CLK_CTRL Addr");
+		goto end;
+	}
+	BMI_DBG("Step 3b: %8X", reg_val);
+
+	/* ------Step 4----- */
+	mem_val = 1;
+	status = bmi_write_memory(cmnos_core_clk_div_addr,
+				  (uint8_t *) &mem_val, 4, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to write CLK_DIV Addr");
+		goto end;
+	}
+
+	/* ------Step 5----- */
+	reg_val = 0;
+	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read PLL_CTRL Addr");
+		goto end;
+	}
+	BMI_DBG("Step 5a: %8X", reg_val);
+
+	reg_val &= ~(WLAN_PLL_CONTROL_REFDIV_MASK | WLAN_PLL_CONTROL_DIV_MASK |
+		     WLAN_PLL_CONTROL_NOPWD_MASK);
+	reg_val |= (WLAN_PLL_CONTROL_REFDIV_SET(clock_s.wlan_pll.refdiv) |
+		    WLAN_PLL_CONTROL_DIV_SET(clock_s.wlan_pll.div) |
+		    WLAN_PLL_CONTROL_NOPWD_SET(1));
+	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to write PLL_CTRL Addr");
+		goto end;
+	}
+
+	reg_val = 0;
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read back PLL_CTRL Addr");
+		goto end;
+	}
+	OS_DELAY(100);
+	BMI_DBG("Step 5b: %8X", reg_val);
+
+	/* ------Step 6------- */
+	do {
+		reg_val = 0;
+		status = bmi_read_soc_register((RTC_WMAC_BASE_ADDRESS |
+				RTC_SYNC_STATUS_OFFSET), &reg_val, ol_ctx);
+		if (status != QDF_STATUS_SUCCESS) {
+			BMI_ERR("Failed to read RTC_SYNC_STATUS Addr");
+			goto end;
+		}
+	} while (RTC_SYNC_STATUS_PLL_CHANGING_GET(reg_val));
+
+	/* ------Step 7------- */
+	reg_val = 0;
+	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read PLL_CTRL Addr for CTRL_BYPASS");
+		goto end;
+	}
+	BMI_DBG("Step 7a: %8X", reg_val);
+
+	reg_val &= ~WLAN_PLL_CONTROL_BYPASS_MASK;
+	reg_val |= WLAN_PLL_CONTROL_BYPASS_SET(0);
+	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to write PLL_CTRL Addr for CTRL_BYPASS");
+		goto end;
+	}
+
+	reg_val = 0;
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read back PLL_CTRL Addr for CTRL_BYPASS");
+		goto end;
+	}
+	BMI_DBG("Step 7b: %8X", reg_val);
+
+	/* ------Step 8-------- */
+	do {
+		reg_val = 0;
+		status = bmi_read_soc_register((RTC_WMAC_BASE_ADDRESS |
+				RTC_SYNC_STATUS_OFFSET), &reg_val, ol_ctx);
+		if (status != QDF_STATUS_SUCCESS) {
+			BMI_ERR("Failed to read SYNC_STATUS Addr");
+			goto end;
+		}
+	} while (RTC_SYNC_STATUS_PLL_CHANGING_GET(reg_val));
+
+	/* ------Step 9-------- */
+	reg_val = 0;
+	addr = (RTC_SOC_BASE_ADDRESS | SOC_CPU_CLOCK_OFFSET);
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read CPU_CLK Addr");
+		goto end;
+	}
+	BMI_DBG("Step 9a: %8X", reg_val);
+
+	reg_val &= ~SOC_CPU_CLOCK_STANDARD_MASK;
+	reg_val |= SOC_CPU_CLOCK_STANDARD_SET(1);
+	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to write CPU_CLK Addr");
+		goto end;
+	}
+
+	reg_val = 0;
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read back CPU_CLK Addr");
+		goto end;
+	}
+	BMI_DBG("Step 9b: %8X", reg_val);
+
+	/* ------Step 10------- */
+	reg_val = 0;
+	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read PLL_CTRL Addr for NOPWD");
+		goto end;
+	}
+	BMI_DBG("Step 10a: %8X", reg_val);
+
+	reg_val &= ~WLAN_PLL_CONTROL_NOPWD_MASK;
+	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to write PLL_CTRL Addr for NOPWD");
+		goto end;
+	}
+	reg_val = 0;
+	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to read back PLL_CTRL Addr for NOPWD");
+		goto end;
+	}
+	BMI_DBG("Step 10b: %8X", reg_val);
+
+	/* ------Step 11------- */
+	mem_val = 1;
+	status = bmi_write_memory(cmnos_cpu_pll_init_done_addr,
+				  (uint8_t *) &mem_val, 4, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to write PLL_INIT Addr");
+		goto end;
+	}
+
+	mem_val = TARGET_CPU_FREQ;
+	status = bmi_write_memory(cmnos_cpu_speed_addr,
+				  (uint8_t *) &mem_val, 4, ol_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("Failed to write CPU_SPEED Addr");
+		goto end;
+	}
+
+end:
+	return status;
+}
+
+QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	uint32_t param, address = 0;
+	QDF_STATUS status = !QDF_STATUS_SUCCESS;
+	QDF_STATUS ret;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
+	uint32_t target_type = tgt_info->target_type;
+	uint32_t target_version = tgt_info->target_version;
+	struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx);
+	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
+
+	if (0 != pld_get_fw_files_for_target(qdf_dev->dev,
+					     &bmi_ctx->fw_files,
+					      target_type,
+					      target_version)) {
+		BMI_ERR("%s: No FW files from platform driver", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Transfer Board Data from Target EEPROM to Target RAM */
+	/* Determine where in Target RAM to write Board Data */
+	bmi_read_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_board_data)),
+			(uint8_t *)&address, 4, ol_ctx);
+
+	if (!address) {
+		address = AR6004_REV5_BOARD_DATA_ADDRESS;
+		BMI_DBG("%s: Target address not known! Using 0x%x",
+						__func__, address);
+	}
+
+	if (hif_get_bus_type(scn) != QDF_BUS_TYPE_USB) {
+		ret = ol_patch_pll_switch(ol_ctx);
+		if (ret != QDF_STATUS_SUCCESS) {
+			BMI_ERR("pll switch failed. status %d", ret);
+			return ret;
+		}
+	}
+
+	if (ol_ctx->cal_in_flash) {
+		/* Write EEPROM or Flash data to Target RAM */
+		status = ol_transfer_bin_file(ol_ctx, ATH_FLASH_FILE,
+						address, false);
+	}
+
+	if (status == EOK) {
+		/* Record the fact that Board Data is initialized */
+		param = 1;
+		bmi_write_memory(
+			hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s,
+				hi_board_data_initialized)),
+				(uint8_t *) &param, 4, ol_ctx);
+	} else {
+		/* Transfer One Time Programmable data */
+		address = BMI_SEGMENTED_WRITE_ADDR;
+		BMI_INFO("%s: Using 0x%x for the remainder of init",
+				__func__, address);
+
+		status = ol_transfer_bin_file(ol_ctx, ATH_OTP_FILE,
+					      address, true);
+		/* Execute the OTP code only if entry found and downloaded */
+		if (status == EOK) {
+			uint16_t board_id = 0xffff;
+			/* get board id */
+			param = 0x10;
+			bmi_execute(address, &param, ol_ctx);
+			if (!(param & 0xff))
+				board_id = (param >> 8) & 0xffff;
+			BMI_INFO("%s: board ID is 0x%0x", __func__, board_id);
+			bmi_ctx->board_id = board_id;
+		} else if (status < 0) {
+			return status;
+		}
+
+		bmi_read_memory(hif_hia_item_address(target_type,
+				offsetof(struct host_interest_s,
+					hi_board_data)),
+				(uint8_t *)&address, 4, ol_ctx);
+
+		if (!address) {
+			address = AR6004_REV5_BOARD_DATA_ADDRESS;
+			pr_err("%s: Target address not known! Using 0x%x\n",
+			       __func__, address);
+		}
+
+		/* Flash is either not available or invalid */
+		if (ol_transfer_bin_file(ol_ctx, ATH_BOARD_DATA_FILE,
+					 address, false) != EOK) {
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		/* Record the fact that Board Data is initialized */
+		param = 1;
+		bmi_write_memory(hif_hia_item_address(target_type,
+				 offsetof(struct host_interest_s,
+					  hi_board_data_initialized)),
+				 (uint8_t *) &param, 4, ol_ctx);
+		address = BMI_SEGMENTED_WRITE_ADDR;
+		param = 0;
+		bmi_execute(address, &param, ol_ctx);
+	}
+
+	if (ol_transfer_bin_file(ol_ctx, ATH_SETUP_FILE,
+		BMI_SEGMENTED_WRITE_ADDR, true) == EOK) {
+		param = 0;
+		bmi_execute(address, &param, ol_ctx);
+	}
+
+	/* Download Target firmware
+	 * TODO point to target specific files in runtime
+	 */
+	address = BMI_SEGMENTED_WRITE_ADDR;
+	if (ol_transfer_bin_file(ol_ctx, ATH_FIRMWARE_FILE,
+				address, true) != EOK) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Apply the patches */
+	if (ol_check_dataset_patch(scn, &address)) {
+		if ((ol_transfer_bin_file(ol_ctx, ATH_PATCH_FILE, address,
+					  false)) != EOK) {
+			return QDF_STATUS_E_FAILURE;
+		}
+		bmi_write_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_dset_list_head)),
+			(uint8_t *) &address, 4, ol_ctx);
+	}
+
+	switch (target_version) {
+	case AR6004_VERSION_REV1_3:
+		param = 11;
+		break;
+	case AR6320_REV1_VERSION:
+	case AR6320_REV2_VERSION:
+	case AR6320_REV3_VERSION:
+	case AR6320_REV3_2_VERSION:
+	case QCA9377_REV1_1_VERSION:
+	case QCA9379_REV1_VERSION:
+	case AR6320_REV4_VERSION:
+	case AR6320_DEV_VERSION:
+		/*
+		 * In sdio interface chip, both sdio_data2 and uart_tx pin
+		 * will use GPIO6. It is set by fw rom code, which will cause
+		 * sdio CRC error when there is sdio transaction.
+		 * Override uart tx pin to avoid side effect to sdio pin.
+		 */
+		if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)
+			param = 19;
+		else
+			param = 6;
+		break;
+	default:
+	/* Configure GPIO AR9888 UART */
+		param = 7;
+	}
+
+	bmi_write_memory(hif_hia_item_address(target_type,
+		offsetof(struct host_interest_s, hi_dbg_uart_txpin)),
+		(uint8_t *)&param, 4, ol_ctx);
+
+	if (ini_cfg->enable_uart_print) {
+		param = 1;
+		bmi_write_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_serial_enable)),
+			(uint8_t *)&param, 4, ol_ctx);
+	} else {
+		/*
+		 * Explicitly setting UART prints to zero as target turns it on
+		 * based on scratch registers.
+		 */
+		param = 0;
+		bmi_write_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_serial_enable)),
+			(uint8_t *)&param, 4, ol_ctx);
+	}
+
+	if (ini_cfg->enable_fw_log) {
+		bmi_read_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag)),
+			(uint8_t *)&param, 4, ol_ctx);
+
+		param &= ~(HI_OPTION_DISABLE_DBGLOG);
+		bmi_write_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag)),
+			(uint8_t *)&param, 4, ol_ctx);
+	} else {
+		/*
+		 * Explicitly setting fwlog prints to zero as target turns it on
+		 * based on scratch registers.
+		 */
+		bmi_read_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag)),
+			(uint8_t *)&param, 4, ol_ctx);
+
+		param |= HI_OPTION_DISABLE_DBGLOG;
+		bmi_write_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag)),
+			(uint8_t *) &param, 4, ol_ctx);
+	}
+	status = ol_extra_initialization(ol_ctx);
+
+	return status;
+}
+
+static int ol_diag_read(struct hif_opaque_softc *scn, uint8_t *buffer,
+			uint32_t pos, size_t count)
+{
+	int result = 0;
+
+	if ((4 == count) && ((pos & 3) == 0)) {
+		result = hif_diag_read_access(scn, pos,
+					      (uint32_t *) buffer);
+	} else {
+		size_t amount_read = 0;
+		size_t readSize = PCIE_READ_LIMIT;
+		size_t remainder = 0;
+
+		if (count > PCIE_READ_LIMIT) {
+			while ((amount_read < count) && (0 == result)) {
+				result = hif_diag_read_mem(scn, pos,
+							   buffer, readSize);
+				if (0 == result) {
+					buffer += readSize;
+					pos += readSize;
+					amount_read += readSize;
+					remainder = count - amount_read;
+					if (remainder < PCIE_READ_LIMIT)
+						readSize = remainder;
+				}
+			}
+		} else {
+		result = hif_diag_read_mem(scn, pos,
+					   buffer, count);
+		}
+	}
+
+	if (!result)
+		return count;
+	else
+		return -EIO;
+}
+
+static int ol_ath_get_reg_table(struct hif_opaque_softc *scn,
+				uint32_t target_version,
+				struct tgt_reg_table *reg_table)
+{
+	int section_len = 0;
+
+	if (!reg_table) {
+		qdf_assert(0);
+		return section_len;
+	}
+
+	if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI &&
+	    hif_get_bus_type(scn) != QDF_BUS_TYPE_SDIO)
+		return section_len;
+
+	switch (target_version) {
+	case AR6320_REV2_1_VERSION:
+		reg_table->section = ar6320v2_reg_table;
+		reg_table->section_size = ARRAY_SIZE(ar6320v2_reg_table);
+		section_len = AR6320_REV2_1_REG_SIZE;
+		break;
+	case AR6320_REV3_VERSION:
+	case AR6320_REV3_2_VERSION:
+	case QCA9379_REV1_VERSION:
+	case QCA9377_REV1_1_VERSION:
+		reg_table->section = ar6320v3_reg_table;
+		reg_table->section_size = ARRAY_SIZE(ar6320v3_reg_table);
+		section_len = AR6320_REV3_REG_SIZE;
+		break;
+	default:
+		reg_table->section = NULL;
+		reg_table->section_size = 0;
+		section_len = 0;
+	}
+
+	return section_len;
+}
+
+static int ol_diag_read_reg_loc(struct hif_opaque_softc *scn, uint8_t *buffer,
+				uint32_t buffer_len)
+{
+	int i, len, section_len, fill_len;
+	int dump_len, result = 0;
+	struct tgt_reg_table reg_table;
+	const struct tgt_reg_section *curr_sec, *next_sec;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	uint32_t target_version =  tgt_info->target_version;
+
+	reg_table.section = NULL;
+	reg_table.section_size = 0;
+
+	section_len = ol_ath_get_reg_table(scn, target_version, &reg_table);
+
+	if (!reg_table.section || !reg_table.section_size || !section_len) {
+		BMI_ERR("%s: failed to get reg table", __func__);
+		result = -EIO;
+		goto out;
+	}
+
+	curr_sec = reg_table.section;
+	for (i = 0; i < reg_table.section_size; i++) {
+
+		dump_len = curr_sec->end_addr - curr_sec->start_addr;
+
+		if ((buffer_len - result) < dump_len) {
+			BMI_ERR("No buffer to dump regs:%d: 0x%08x-0x%08x",
+				i, curr_sec->start_addr, curr_sec->end_addr);
+			goto out;
+		}
+
+		len = ol_diag_read(scn, buffer, curr_sec->start_addr, dump_len);
+
+		if (len != -EIO) {
+			buffer += len;
+			result += len;
+		} else {
+			BMI_ERR("%s: can't read reg 0x%08x len = %d",
+				__func__, curr_sec->start_addr, dump_len);
+			result = -EIO;
+			goto out;
+		}
+
+		if (result < section_len) {
+			next_sec = (struct tgt_reg_section *) ((uint8_t *)
+						 curr_sec + sizeof(*curr_sec));
+			fill_len = next_sec->start_addr - curr_sec->end_addr;
+			if ((buffer_len - result) < fill_len) {
+				BMI_ERR("No buf to fill regs:%d: 0x%08x-0x%08x",
+					i, curr_sec->end_addr,
+					next_sec->start_addr);
+				goto out;
+			}
+
+			if (fill_len) {
+				buffer += fill_len;
+				result += fill_len;
+			}
+		}
+		curr_sec++;
+	}
+
+out:
+	return result;
+}
+
+static
+void ol_dump_target_memory(struct hif_opaque_softc *scn, void *memory_block)
+{
+	char *buffer_loc = memory_block;
+	u_int32_t section_count = 0;
+	u_int32_t address = 0;
+	u_int32_t size = 0;
+
+	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO ||
+	    hif_get_bus_type(scn) == QDF_BUS_TYPE_USB)
+		return;
+
+	for (; section_count < 2; section_count++) {
+		switch (section_count) {
+		case 0:
+			address = DRAM_LOCAL_BASE_ADDR;
+			size = DRAM_SIZE;
+			break;
+		case 1:
+			address = AXI_LOCATION;
+			size = AXI_SIZE;
+		default:
+			break;
+		}
+		hif_dump_target_memory(scn, buffer_loc, address, size);
+		buffer_loc += size;
+	}
+}
+
+static int
+ol_dump_ce_register(struct hif_opaque_softc *scn, void *memory_block)
+{
+	int ret;
+
+	BMI_ERR("Could not read dump section!");
+
+	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO ||
+	    hif_get_bus_type(scn) == QDF_BUS_TYPE_USB)
+		return 0;
+
+	if (hif_dump_registers(scn))
+		BMI_ERR("Failed to dump bus registers");
+
+	ol_dump_target_memory(scn, memory_block);
+	ret = -EACCES;
+
+	return ret;
+}
+
+static inline uint32_t
+ol_get_max_section_count(struct hif_opaque_softc *scn)
+{
+	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI)
+		return 5;
+	else
+		return 4;
+}
+
+/**
+ * ol_set_ram_config_reg() - set target RAM configuration register
+ * @sc: pointer of hif_softc context
+ * @config: value to be written to the register
+ *
+ * This function will write the given value to target RAM configuration
+ * register which is bit[23-20] of target CPU inbound address in order to
+ * provide correct address mapping.
+ *
+ * Return: 0 for success or reasons for failure
+ */
+static int ol_set_ram_config_reg(struct hif_opaque_softc *scn, uint32_t config)
+{
+	QDF_STATUS status;
+	uint32_t val;
+	struct targetdef_s *targetdef =
+		(struct targetdef_s *)hif_get_targetdef(scn);
+	uint32_t ram_config_addr =
+		targetdef->d_SOC_CORE_BASE_ADDRESS + FW_RAM_CONFIG_ADDRESS;
+
+	if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI)
+		return -EACCES;
+
+	status = hif_diag_write_access(scn, ram_config_addr, config);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		return -EACCES;
+	}
+	status = hif_diag_read_access(scn, ram_config_addr, &val);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		return -EACCES;
+	}
+	if (val != config) {
+		BMI_ERR("%s: Failed to set RAM config reg from 0x%x to 0x%x",
+			__func__, val, config);
+		return -EACCES;
+	}
+	return 0;
+}
+
+static int
+ol_get_iram_len_and_pos(struct hif_opaque_softc *scn, uint32_t *pos,
+			uint32_t *len, uint32_t section)
+{
+	enum hif_target_status status;
+	uint32_t iram_addr, iram_size;
+	int ret;
+
+	if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI) {
+		*pos = IRAM_LOCATION;
+		*len = IRAM_SIZE;
+		BMI_ERR("%s: Dumping IRAM Section", __func__);
+		return 0;
+	}
+
+	status = hif_get_target_status(scn);
+	if (status != TARGET_STATUS_RESET) {
+		BMI_ERR("%s: Target status invalid: %d", __func__, status);
+		return -EBUSY;
+	}
+
+	switch (section) {
+	case 3:
+		BMI_ERR("%s: Dumping IRAM1 section", __func__);
+		iram_addr = IRAM1_LOCATION;
+		iram_size = IRAM1_SIZE;
+		break;
+	case 4:
+		BMI_ERR("%s: Dumping IRAM2 section", __func__);
+		iram_addr = IRAM2_LOCATION;
+		iram_size = IRAM2_SIZE;
+		break;
+	default:
+		BMI_ERR("%s: Invalid input iram section %d",
+			__func__, section);
+		return A_EINVAL;
+	}
+
+	ret = ol_set_ram_config_reg(scn, iram_addr >> 20);
+	if (ret) {
+		BMI_ERR("%s: Skip IRAM1 ret:%d", __func__, ret);
+		return -EBUSY;
+	}
+
+	*pos = iram_addr;
+	*len = iram_size;
+	return 0;
+}
+
+/**
+ * ol_target_coredump() - API to collect target ramdump
+ * @inst - private context
+ * @memory_block - non-NULL reserved memory location
+ * @block_len - size of the dump to collect
+ *
+ * Function to perform core dump for the target.
+ *
+ * Return: int
+ */
+static int ol_target_coredump(void *inst, void *memory_block,
+					uint32_t block_len)
+{
+	struct hif_opaque_softc *scn = (struct hif_opaque_softc *)inst;
+	int8_t *buffer_loc = memory_block;
+	int result = 0;
+	int ret = 0;
+	uint32_t amount_read = 0;
+	uint32_t section_count = 0;
+	uint32_t pos = 0;
+	uint32_t read_len = 0;
+	uint32_t max_count = ol_get_max_section_count(scn);
+
+	while ((section_count < max_count) && (amount_read < block_len)) {
+		switch (section_count) {
+		case 0:
+			pos = DRAM_LOCATION;
+			read_len = DRAM_SIZE;
+			BMI_ERR("%s: Dumping DRAM section...", __func__);
+			break;
+		case 1:
+			pos = AXI_LOCATION;
+			read_len = AXI_SIZE;
+			BMI_ERR("%s: Dumping AXI section...", __func__);
+			break;
+		case 2:
+			pos = REGISTER_LOCATION;
+			/* ol_diag_read_reg_loc checks for buffer overrun */
+			read_len = 0;
+			BMI_ERR("%s: Dumping Register section...", __func__);
+			break;
+		case 3:
+		case 4:
+			ret = ol_get_iram_len_and_pos(scn, &pos, &read_len,
+						      section_count);
+			if (ret) {
+				BMI_ERR("%s: Fail to Dump IRAM Section "
+					"ret:%d", __func__, ret);
+				return ret;
+			}
+			break;
+		default:
+			BMI_ERR("%s: INVALID SECTION_:%d", __func__,
+				section_count);
+			return 0;
+		}
+
+		if (block_len - amount_read < read_len) {
+			BMI_ERR("%s: No memory to dump section:%d buffer!",
+				__func__, section_count);
+			return -ENOMEM;
+		}
+
+		if (((hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI) ||
+		     (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)) &&
+		    pos == REGISTER_LOCATION)
+			result = ol_diag_read_reg_loc(scn, buffer_loc,
+						      block_len - amount_read);
+		else
+			result = ol_diag_read(scn, buffer_loc, pos, read_len);
+
+		if (result == -EIO)
+			return ol_dump_ce_register(scn, memory_block);
+
+		BMI_INFO("%s: Section:%d Bytes Read:%0x", __func__,
+			 section_count, result);
+
+		amount_read += result;
+		buffer_loc += result;
+		section_count++;
+	}
+	return ret;
+}
+
+/**
+ * ol_get_ini_handle() - API to get Ol INI configuration
+ * @ol_ctx: OL Context
+ *
+ * Return: pointer to OL configuration
+ */
+struct ol_config_info *ol_get_ini_handle(struct ol_context *ol_ctx)
+{
+	return &ol_ctx->cfg_info;
+}
+
+/**
+ * ol_init_ini_config() - API to initialize INI configuration
+ * @ol_ctx: OL Context
+ * @cfg: OL ini configuration
+ *
+ * Return: void
+ */
+void ol_init_ini_config(struct ol_context *ol_ctx,
+			struct ol_config_info *cfg)
+{
+	qdf_mem_copy(&ol_ctx->cfg_info, cfg, sizeof(struct ol_config_info));
+}
diff --git a/core/bmi/src/ol_fw_common.c b/core/bmi/src/ol_fw_common.c
new file mode 100644
index 0000000..493c820
--- /dev/null
+++ b/core/bmi/src/ol_fw_common.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#include "ol_if_athvar.h"
+#include "targaddrs.h"
+#include "ol_cfg.h"
+#include "i_ar6320v2_regtable.h"
+#include "ol_fw.h"
+#ifdef HIF_PCI
+#include "ce_reg.h"
+#endif
+#if defined(HIF_SDIO)
+#include "regtable_sdio.h"
+#endif
+#if defined(HIF_USB)
+#include "regtable_usb.h"
+#endif
+#if  defined(CONFIG_CNSS)
+#include <net/cnss.h>
+#endif
+#include "i_bmi.h"
+#include "cds_api.h"
+
+#ifdef CONFIG_DISABLE_SLEEP_BMI_OPTION
+static inline void ol_sdio_disable_sleep(struct ol_context *ol_ctx)
+{
+	uint32_t value;
+
+	BMI_ERR("prevent ROME from sleeping");
+	bmi_read_soc_register(MBOX_BASE_ADDRESS + LOCAL_SCRATCH_OFFSET,
+		/* this address should be 0x80C0 for ROME*/
+		&value,
+		ol_ctx);
+
+	value |= SOC_OPTION_SLEEP_DISABLE;
+
+	bmi_write_soc_register(MBOX_BASE_ADDRESS + LOCAL_SCRATCH_OFFSET,
+				 value,
+				 ol_ctx);
+}
+
+#else
+static inline void ol_sdio_disable_sleep(struct ol_context *ol_ctx)
+{
+}
+
+#endif
+
+/**
+ * ol_usb_extra_initialization() - USB extra initialization
+ * @ol_ctx: pointer to ol_context
+ *
+ * USB specific initialization after firmware download
+ *
+ * Return: QDF_STATUS_SUCCESS on success and error QDF status on failure
+ */
+static QDF_STATUS
+ol_usb_extra_initialization(struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct hif_target_info *tgt_info =
+				hif_get_target_info_handle(scn);
+	QDF_STATUS status = !QDF_STATUS_SUCCESS;
+	u_int32_t param = 0;
+
+	param |= HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE;
+	status = bmi_write_memory(
+				hif_hia_item_address(tgt_info->target_type,
+					offsetof(struct host_interest_s,
+					hi_acs_flags)),
+				(u_int8_t *)&param, 4, ol_ctx);
+
+	return status;
+}
+
+/*Setting SDIO block size, mbox ISR yield limit for SDIO based HIF*/
+static
+QDF_STATUS ol_sdio_extra_initialization(struct ol_context *ol_ctx)
+{
+
+	QDF_STATUS status;
+	uint32_t param;
+	uint32_t blocksizes[HTC_MAILBOX_NUM_MAX];
+	uint32_t MboxIsrYieldValue = 99;
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	uint32_t target_type = tgt_info->target_type;
+
+	/* get the block sizes */
+	status = hif_get_config_item(scn,
+				HIF_DEVICE_GET_BLOCK_SIZE,
+				blocksizes, sizeof(blocksizes));
+	if (status != EOK) {
+		BMI_ERR("Failed to get block size info from HIF layer");
+		goto exit;
+	}
+	/* note: we actually get the block size for mailbox 1,
+	 * for SDIO the block size on mailbox 0 is artificially
+	 * set to 1 must be a power of 2
+	 */
+	qdf_assert((blocksizes[1] & (blocksizes[1] - 1)) == 0);
+
+	/* set the host interest area for the block size */
+	status = bmi_write_memory(hif_hia_item_address(target_type,
+				 offsetof(struct host_interest_s,
+				 hi_mbox_io_block_sz)),
+				(uint8_t *)&blocksizes[1],
+				4,
+				ol_ctx);
+
+	if (status != EOK) {
+		BMI_ERR("BMIWriteMemory for IO block size failed");
+		goto exit;
+	}
+
+	if (MboxIsrYieldValue != 0) {
+		/* set the host for the mbox ISR yield limit */
+		status =
+		bmi_write_memory(hif_hia_item_address(target_type,
+				offsetof(struct host_interest_s,
+				hi_mbox_isr_yield_limit)),
+				(uint8_t *)&MboxIsrYieldValue,
+				4,
+				ol_ctx);
+
+		if (status != EOK) {
+			BMI_ERR("BMI write for yield limit failed\n");
+			goto exit;
+		}
+	}
+	ol_sdio_disable_sleep(ol_ctx);
+	status = bmi_read_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s,
+			hi_acs_flags)),
+			(uint8_t *)&param,
+			4,
+			ol_ctx);
+	if (status != EOK) {
+		BMI_ERR("BMIReadMemory for hi_acs_flags failed");
+		goto exit;
+	}
+
+	param |= HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE;
+
+	/* disable swap mailbox for FTM */
+	if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE)
+		param |= HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET;
+
+	if (!cds_is_ptp_tx_opt_enabled())
+		param |= HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET;
+
+	/* enable TX completion to collect tx_desc for pktlog */
+	if (cds_is_packet_log_enabled())
+		param &= ~HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET;
+
+	bmi_write_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s,
+			hi_acs_flags)),
+			(uint8_t *)&param, 4, ol_ctx);
+exit:
+	return status;
+}
+
+/**
+ * ol_extra_initialization() - OL extra initialization
+ * @ol_ctx: pointer to ol_context
+ *
+ * Bus specific initialization after firmware download
+ *
+ * Return: QDF_STATUS_SUCCESS on success and error QDF status on failure
+ */
+QDF_STATUS ol_extra_initialization(struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+
+	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)
+		return ol_sdio_extra_initialization(ol_ctx);
+	else if (hif_get_bus_type(scn) == QDF_BUS_TYPE_USB)
+		return ol_usb_extra_initialization(ol_ctx);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void ol_target_ready(struct hif_opaque_softc *scn, void *cfg_ctx)
+{
+	uint32_t value = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	uint32_t target_type = tgt_info->target_type;
+
+	if (hif_get_bus_type(scn) != QDF_BUS_TYPE_SDIO)
+		return;
+	status = hif_diag_read_mem(scn,
+		hif_hia_item_address(target_type,
+		offsetof(struct host_interest_s, hi_acs_flags)),
+		(uint8_t *)&value, sizeof(u_int32_t));
+
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("HIFDiagReadMem failed");
+		return;
+	}
+
+	if (value & HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_FW_ACK) {
+		BMI_ERR("MAILBOX SWAP Service is enabled!");
+		hif_set_mailbox_swap(scn);
+	}
+
+	if (value & HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_FW_ACK) {
+		BMI_ERR("Reduced Tx Complete service is enabled!");
+		ol_cfg_set_tx_free_at_download(cfg_ctx);
+	}
+}
diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h
new file mode 100644
index 0000000..08ed546
--- /dev/null
+++ b/core/cds/inc/cds_api.h
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#if !defined(__CDS_API_H)
+#define __CDS_API_H
+
+/**
+ * DOC:  cds_api.h
+ *
+ * Connectivity driver services public API
+ *
+ */
+
+#include <qdf_types.h>
+#include <qdf_status.h>
+#include <qdf_mem.h>
+#include <qdf_debugfs.h>
+#include <qdf_list.h>
+#include <qdf_trace.h>
+#include <qdf_event.h>
+#include <qdf_lock.h>
+#include "qdf_platform.h"
+#include "qdf_cpuhp.h"
+#include "reg_services_public_struct.h"
+#include <cds_reg_service.h>
+#include <cds_packet.h>
+#include <cds_sched.h>
+#include <qdf_threads.h>
+#include <qdf_mc_timer.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <cdp_txrx_handle.h>
+
+/* Amount of time to wait for WMA to perform an asynchronous activity.
+ * This value should be larger than the timeout used by WMI to wait for
+ * a response from target
+ */
+#define CDS_WMA_TIMEOUT  (15000)
+
+/**
+ * enum cds_driver_state - Driver state
+ * @CDS_DRIVER_STATE_UNINITIALIZED: Driver is in uninitialized state.
+ * CDS_DRIVER_STATE_LOADED: Driver is loaded and functional.
+ * CDS_DRIVER_STATE_LOADING: Driver probe is in progress.
+ * CDS_DRIVER_STATE_UNLOADING: Driver remove is in progress.
+ * CDS_DRIVER_STATE_RECOVERING: Recovery in progress.
+ * CDS_DRIVER_STATE_BAD: Driver in bad state.
+ * CDS_DRIVER_STATE_MODULE_STOPPING: Module stop in progress.
+ */
+enum cds_driver_state {
+	CDS_DRIVER_STATE_UNINITIALIZED          = 0,
+	CDS_DRIVER_STATE_LOADED                 = BIT(0),
+	CDS_DRIVER_STATE_LOADING                = BIT(1),
+	CDS_DRIVER_STATE_UNLOADING              = BIT(2),
+	CDS_DRIVER_STATE_RECOVERING             = BIT(3),
+	CDS_DRIVER_STATE_BAD                    = BIT(4),
+	CDS_DRIVER_STATE_FW_READY               = BIT(5),
+	CDS_DRIVER_STATE_MODULE_STOPPING        = BIT(6),
+};
+
+#define __CDS_IS_DRIVER_STATE(_state, _mask) (((_state) & (_mask)) == (_mask))
+
+/**
+ * enum cds_fw_state - Firmware state
+ * @CDS_FW_STATE_UNINITIALIZED: Firmware is in uninitialized state.
+ */
+enum cds_fw_state {
+	CDS_FW_STATE_UNINITIALIZED = 0,
+};
+
+#define __CDS_IS_FW_STATE(_state, _mask) (((_state) & (_mask)) == (_mask))
+
+/**
+ * struct cds_sme_cbacks - list of sme functions registered with
+ * CDS
+ * @sme_get_valid_channels: gets the valid channel list for current reg domain
+ * @sme_get_nss_for_vdev: gets the nss allowed for the vdev type
+ */
+struct cds_sme_cbacks {
+	QDF_STATUS (*sme_get_valid_channels)(void*, uint8_t *, uint32_t *);
+	void (*sme_get_nss_for_vdev)(void*, enum QDF_OPMODE,
+				     uint8_t *, uint8_t *);
+};
+
+void cds_set_driver_state(enum cds_driver_state);
+void cds_clear_driver_state(enum cds_driver_state);
+enum cds_driver_state cds_get_driver_state(void);
+
+/**
+ * cds_set_fw_state() - Set current firmware state
+ * @state:	Firmware state to be set to.
+ *
+ * This API sets firmware state to state. This API only sets the state and
+ * doesn't clear states, please make sure to use cds_clear_firmware_state
+ * to clear any state if required.
+ *
+ * Return: None
+ */
+void cds_set_fw_state(enum cds_fw_state);
+
+/**
+ * cds_clear_fw_state() - Clear current fw state
+ * @state:	Driver state to be cleared.
+ *
+ * This API clears fw state. This API only clears the state, please make
+ * sure to use cds_set_fw_state to set any new states.
+ *
+ * Return: None
+ */
+void cds_clear_fw_state(enum cds_fw_state);
+
+/**
+ * cds_get_fw_state() - Get current firmware state
+ *
+ * This API returns current firmware state stored in global context.
+ *
+ * Return: Firmware state enum
+ */
+enum cds_fw_state cds_get_fw_state(void);
+
+/**
+ * cds_is_driver_loading() - Is driver load in progress
+ *
+ * Return: true if driver is loading and false otherwise.
+ */
+static inline bool cds_is_driver_loading(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_LOADING);
+}
+
+/**
+ * cds_is_driver_unloading() - Is driver unload in progress
+ *
+ * Return: true if driver is unloading and false otherwise.
+ */
+static inline bool cds_is_driver_unloading(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_UNLOADING);
+}
+
+/**
+ * cds_is_driver_recovering() - Is recovery in progress
+ *
+ * Return: true if recovery in progress  and false otherwise.
+ */
+static inline bool cds_is_driver_recovering(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_RECOVERING);
+}
+
+/**
+ * cds_is_driver_in_bad_state() - is driver in bad state
+ *
+ * Return: true if driver is in bad state and false otherwise.
+ */
+static inline bool cds_is_driver_in_bad_state(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_BAD);
+}
+
+/**
+ * cds_is_load_or_unload_in_progress() - Is driver load OR unload in progress
+ *
+ * Return: true if driver is loading OR unloading and false otherwise.
+ */
+static inline bool cds_is_load_or_unload_in_progress(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_LOADING) ||
+		__CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_UNLOADING);
+}
+
+/**
+ * cds_is_module_stop_in_progress() - Is module stopping
+ *
+ * Return: true if module stop is in progress.
+ */
+static inline bool cds_is_module_stop_in_progress(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_MODULE_STOPPING);
+}
+
+/**
+ * cds_is_target_ready() - Is target is in ready state
+ *
+ * Return: true if target is in ready state and false otherwise.
+ */
+static inline bool cds_is_target_ready(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_FW_READY);
+}
+
+/**
+ * cds_set_recovery_in_progress() - Set recovery in progress
+ * @value: value to set
+ *
+ * Return: none
+ */
+static inline void cds_set_recovery_in_progress(uint8_t value)
+{
+	if (value)
+		cds_set_driver_state(CDS_DRIVER_STATE_RECOVERING);
+	else
+		cds_clear_driver_state(CDS_DRIVER_STATE_RECOVERING);
+}
+
+/**
+ * cds_set_driver_in_bad_state() - Set driver state
+ * @value: value to set
+ *
+ * Return: none
+ */
+static inline void cds_set_driver_in_bad_state(uint8_t value)
+{
+	if (value)
+		cds_set_driver_state(CDS_DRIVER_STATE_BAD);
+	else
+		cds_clear_driver_state(CDS_DRIVER_STATE_BAD);
+}
+
+/**
+ * cds_set_target_ready() - Set target ready state
+ * @value: value to set
+ *
+ * Return: none
+ */
+static inline void cds_set_target_ready(uint8_t value)
+{
+	if (value)
+		cds_set_driver_state(CDS_DRIVER_STATE_FW_READY);
+	else
+		cds_clear_driver_state(CDS_DRIVER_STATE_FW_READY);
+}
+
+/**
+ * cds_set_load_in_progress() - Set load in progress
+ * @value: value to set
+ *
+ * Return: none
+ */
+static inline void cds_set_load_in_progress(uint8_t value)
+{
+	if (value)
+		cds_set_driver_state(CDS_DRIVER_STATE_LOADING);
+	else
+		cds_clear_driver_state(CDS_DRIVER_STATE_LOADING);
+}
+
+/**
+ * cds_set_driver_loaded() - Set load completed
+ * @value: value to set
+ *
+ * Return: none
+ */
+static inline void cds_set_driver_loaded(uint8_t value)
+{
+	if (value)
+		cds_set_driver_state(CDS_DRIVER_STATE_LOADED);
+	else
+		cds_clear_driver_state(CDS_DRIVER_STATE_LOADED);
+}
+
+/**
+ * cds_set_unload_in_progress() - Set unload in progress
+ * @value: value to set
+ *
+ * Return: none
+ */
+static inline void cds_set_unload_in_progress(uint8_t value)
+{
+	if (value)
+		cds_set_driver_state(CDS_DRIVER_STATE_UNLOADING);
+	else
+		cds_clear_driver_state(CDS_DRIVER_STATE_UNLOADING);
+}
+
+/**
+ * cds_set_module_stop_in_progress() - Setting module stop in progress
+ *
+ * @value: value to set
+ *
+ * Return: none
+ */
+static inline void cds_set_module_stop_in_progress(bool value)
+{
+	if (value)
+		cds_set_driver_state(CDS_DRIVER_STATE_MODULE_STOPPING);
+	else
+		cds_clear_driver_state(CDS_DRIVER_STATE_MODULE_STOPPING);
+}
+
+/**
+ * cds_is_driver_loaded() - Is driver loaded
+ *
+ * Return: true if driver is loaded or false otherwise.
+ */
+static inline bool cds_is_driver_loaded(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_LOADED);
+}
+
+/**
+ * cds_init() - Initialize CDS
+ *
+ * This function allocates the resource required for CDS, but does not
+ * initialize all the members. This overall initialization will happen at
+ * cds_open().
+ *
+ * Return: QDF_STATUS_SUCCESS if CDS was initialized and an error on failure
+ */
+QDF_STATUS cds_init(void);
+
+void cds_deinit(void);
+
+QDF_STATUS cds_pre_enable(void);
+
+QDF_STATUS cds_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * cds_dp_open() - Open datapath module
+ * @psoc - object manager soc handle
+ *
+ * API to map the datapath rings to interrupts
+ * and also open the datapath pdev module.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_dp_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * cds_enable() - start/enable cds module
+ * @psoc: Psoc pointer
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_enable(struct wlan_objmgr_psoc *psoc);
+
+QDF_STATUS cds_disable(struct wlan_objmgr_psoc *psoc);
+
+QDF_STATUS cds_post_disable(void);
+
+QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * cds_dp_close() - Close datapath module
+ * @psoc: Object manager soc handle
+ *
+ * API used to detach interrupts assigned to service
+ * datapath rings and close pdev module
+ *
+ * Return: Status
+ */
+QDF_STATUS cds_dp_close(struct wlan_objmgr_psoc *psoc);
+
+void *cds_get_context(QDF_MODULE_ID module_id);
+
+uint8_t cds_get_datapath_handles(void **soc, struct cdp_pdev **pdev,
+			 struct cdp_vdev **vdev, uint8_t sessionId);
+void *cds_get_global_context(void);
+
+QDF_STATUS cds_alloc_context(QDF_MODULE_ID module_id, void **module_context,
+			     uint32_t size);
+
+QDF_STATUS cds_free_context(QDF_MODULE_ID module_id, void *module_context);
+
+QDF_STATUS cds_set_context(QDF_MODULE_ID module_id, void *context);
+
+QDF_STATUS cds_get_vdev_types(enum QDF_OPMODE mode, uint32_t *type,
+			      uint32_t *subType);
+
+void cds_flush_work(void *work);
+void cds_flush_delayed_work(void *dwork);
+
+#ifdef REMOVE_PKT_LOG
+static inline
+bool cds_is_packet_log_enabled(void)
+{
+	return false;
+}
+#else
+bool cds_is_packet_log_enabled(void);
+#endif
+
+uint64_t cds_get_monotonic_boottime(void);
+
+/**
+ * cds_get_recovery_reason() - get self recovery reason
+ * @reason: cds hang reason
+ *
+ * Return: None
+ */
+void cds_get_recovery_reason(enum qdf_hang_reason *reason);
+
+/**
+ * cds_reset_recovery_reason() - reset the reason to unspecified
+ *
+ * Return: None
+ */
+void cds_reset_recovery_reason(void);
+
+/**
+ * cds_trigger_recovery() - trigger self recovery
+ * @reason: recovery reason
+ *
+ * Return: none
+ */
+#define cds_trigger_recovery(reason) \
+	__cds_trigger_recovery(reason, __func__, __LINE__)
+void __cds_trigger_recovery(enum qdf_hang_reason reason, const char *func,
+			    const uint32_t line);
+
+void cds_set_wakelock_logging(bool value);
+bool cds_is_wakelock_enabled(void);
+void cds_set_ring_log_level(uint32_t ring_id, uint32_t log_level);
+enum wifi_driver_log_level cds_get_ring_log_level(uint32_t ring_id);
+void cds_set_multicast_logging(uint8_t value);
+uint8_t cds_is_multicast_logging(void);
+QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
+		uint32_t type,
+		uint32_t sub_type,
+		bool recovery_needed);
+void cds_get_and_reset_log_completion(uint32_t *is_fatal,
+		uint32_t *type,
+		uint32_t *sub_type,
+		bool *recovery_needed);
+bool cds_is_log_report_in_progress(void);
+bool cds_is_fatal_event_enabled(void);
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+bool cds_is_ptp_rx_opt_enabled(void);
+bool cds_is_ptp_tx_opt_enabled(void);
+#else
+static inline bool cds_is_ptp_rx_opt_enabled(void)
+{
+	return false;
+}
+
+static inline bool cds_is_ptp_tx_opt_enabled(void)
+{
+	return false;
+}
+#endif
+
+uint32_t cds_get_log_indicator(void);
+void cds_set_fatal_event(bool value);
+void cds_wlan_flush_host_logs_for_fatal(void);
+
+void cds_init_log_completion(void);
+QDF_STATUS cds_flush_logs(uint32_t is_fatal,
+		uint32_t indicator,
+		uint32_t reason_code,
+		bool dump_mac_trace,
+		bool recovery_needed);
+void cds_logging_set_fw_flush_complete(void);
+void cds_svc_fw_shutdown_ind(struct device *dev);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
+			uint8_t type, uint8_t sub_type, uint8_t *peer_mac);
+#else
+static inline
+void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
+			uint8_t type, uint8_t sub_type, uint8_t *peer_mac)
+
+{
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+int cds_get_radio_index(void);
+QDF_STATUS cds_set_radio_index(int radio_index);
+void cds_init_ini_config(struct cds_config_info *cds_cfg);
+void cds_deinit_ini_config(void);
+struct cds_config_info *cds_get_ini_config(void);
+
+bool cds_is_5_mhz_enabled(void);
+bool cds_is_10_mhz_enabled(void);
+bool cds_is_sub_20_mhz_enabled(void);
+bool cds_is_self_recovery_enabled(void);
+bool cds_is_fw_down(void);
+enum QDF_GLOBAL_MODE cds_get_conparam(void);
+
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+void cds_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data);
+#else
+static inline
+void cds_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data)
+{
+}
+#endif
+
+#ifdef FEATURE_HTC_CREDIT_HISTORY
+/**
+ * cds_print_htc_credit_history() - Helper function to copy HTC credit
+ *				    history via htc_print_credit_history()
+ *
+ * @count:	Number of lines to be copied
+ * @print:	Print callback to print in the buffer
+ *
+ * Return:	none
+ */
+void cds_print_htc_credit_history(uint32_t count,
+				qdf_abstract_print * print,
+				void *print_priv);
+#else
+
+static inline
+void cds_print_htc_credit_history(uint32_t count,
+				qdf_abstract_print *print,
+				void *print_priv)
+{
+}
+#endif
+/**
+ * cds_is_group_addr() - checks whether addr is multi cast
+ * @mac_addr: address to be checked for multicast
+ *
+ * Check if the input mac addr is multicast addr
+ *
+ * Return: true if multicast addr else false
+ */
+static inline
+bool cds_is_group_addr(uint8_t *mac_addr)
+{
+	if (mac_addr[0] & 0x01)
+		return true;
+	else
+		return false;
+}
+
+/**
+ * cds_get_arp_stats_gw_ip() - get arp stats track IP
+ * @context: osif dev
+ *
+ * Return: ARP stats IP to track.
+ */
+uint32_t cds_get_arp_stats_gw_ip(void *context);
+/**
+ * cds_get_connectivity_stats_pkt_bitmap() - get pkt-type bitmap
+ * @context: osif dev context
+ *
+ * Return: pkt bitmap to track
+ */
+uint32_t cds_get_connectivity_stats_pkt_bitmap(void *context);
+void cds_incr_arp_stats_tx_tgt_delivered(void);
+void cds_incr_arp_stats_tx_tgt_acked(void);
+
+/**
+ * cds_smmu_mem_map_setup() - Check SMMU S1 stage enable
+ *                            status and setup wlan driver
+ * @osdev: Parent device instance
+ * @ipa_present: IPA HW support flag
+ *
+ * This API checks if SMMU S1 translation is enabled in
+ * platform driver or not and sets it accordingly in driver.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS cds_smmu_mem_map_setup(qdf_device_t osdev, bool ipa_present);
+
+/**
+ * cds_smmu_map_unmap() - Map / Unmap DMA buffer to IPA UC
+ * @map: Map / unmap operation
+ * @num_buf: Number of buffers in array
+ * @buf_arr: Buffer array of DMA mem mapping info
+ *
+ * This API maps/unmaps WLAN-IPA buffers if SMMU S1 translation
+ * is enabled.
+ *
+ * Return: Status of map operation
+ */
+int cds_smmu_map_unmap(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr);
+#endif /* if !defined __CDS_API_H */
diff --git a/core/cds/inc/cds_config.h b/core/cds/inc/cds_config.h
new file mode 100644
index 0000000..ff80a54
--- /dev/null
+++ b/core/cds/inc/cds_config.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2016-2018 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: cds_config.h
+ *
+ * Defines the configuration Information for various modules. Default values
+ * are read from the INI file and saved into cds_config_info which are passed
+ * to various modules for the initialization.
+ */
+
+#if !defined(__CDS_CONFIG_H)
+#define __CDS_CONFIG_H
+
+#include "osdep.h"
+#include "cdp_txrx_mob_def.h"
+#include "wlan_pmo_common_public_struct.h"
+
+/**
+ * enum cfg_sub_20_channel_width: ini values for su 20 mhz channel width
+ * @WLAN_SUB_20_CH_WIDTH_5: Use 5 mhz channel width
+ * @WLAN_SUB_20_CH_WIDTH_10: Use 10 mhz channel width
+ */
+enum cfg_sub_20_channel_width {
+	WLAN_SUB_20_CH_WIDTH_NONE = 0,
+	WLAN_SUB_20_CH_WIDTH_5 = 1,
+	WLAN_SUB_20_CH_WIDTH_10 = 2,
+};
+
+/**
+ * enum active_apf_mode - the modes active APF can operate in
+ * @ACTIVE_APF_DISABLED: APF is disabled in active mode
+ * @ACTIVE_APF_ENABLED: APF is enabled for all packets
+ * @ACTIVE_APF_ADAPTIVE: APF is enabled for packets up to some threshold
+ * @ACTIVE_APF_MODE_COUNT: The number of active APF modes
+ */
+enum active_apf_mode {
+	ACTIVE_APF_DISABLED = 0,
+	ACTIVE_APF_ENABLED,
+	ACTIVE_APF_ADAPTIVE,
+	ACTIVE_APF_MODE_COUNT
+};
+
+/**
+ * struct cds_config_info - Place Holder for cds configuration
+ * @max_station: Max station supported
+ * @max_bssid: Max Bssid Supported
+ * @sta_maxlimod_dtim: station max listen interval
+ * @driver_type: Enumeration of Driver Type whether FTM or Mission mode
+ * currently rest of bits are not used
+ * @dfs_phyerr_filter_offload: DFS Phyerror Filtering offload status from ini
+ * Indicates whether support is enabled or not
+ * @ap_disable_intrabss_fwd: pass intra-bss-fwd info to txrx module
+ * @ap_maxoffload_peers: max offload peer
+ * @ap_maxoffload_reorderbuffs: max offload reorder buffs
+ * @ra_ratelimit_interval: RA rate limit value
+ * @is_ra_ratelimit_enabled: Indicate RA rate limit enabled or not
+ * @reorder_offload: is RX re-ordering offloaded to the fw
+ * @dfs_pri_multiplier: dfs radar pri multiplier
+ * @uc_offload_enabled: IPA Micro controller data path offload enable flag
+ * @uc_txbuf_count: IPA Micro controller data path offload TX buffer count
+ * @uc_txbuf_size: IPA Micro controller data path offload TX buffer size
+ * @uc_rxind_ringcount: IPA Micro controller data path offload RX indication
+ * ring count
+ * @uc_tx_partition_base: IPA Micro controller datapath offload TX partition
+ * base
+ * @enable_rxthread: Rx processing in thread from TXRX
+ * @ip_tcp_udp_checksum_offload: checksum offload enabled or not
+ * @ce_classify_enabled: CE based classification enabled
+ * @max_scan: Maximum number of parallel scans
+ * @tx_flow_stop_queue_th: Threshold to stop queue in percentage
+ * @tx_flow_start_queue_offset: Start queue offset in percentage
+ * @num_dp_rx_threads: number of dp rx threads to be configured
+ * @enable_dp_rx_threads: enable dp rx threads
+ * @is_lpass_enabled: Indicate whether LPASS is enabled or not
+ * @tx_chain_mask_cck: Tx chain mask enabled or not
+ * @self_gen_frm_pwr: Self gen from power
+ * @sub_20_channel_width: Sub 20 MHz ch width, ini intersected with fw cap
+ * @flow_steering_enabled: Receive flow steering.
+ * @is_fw_timeout: Indicate whether crash host when fw timesout or not
+ * @active_uc_apf_mode: Setting that determines how APF is applied in active
+ *	mode for uc packets
+ * @active_mc_bc_apf_mode: Setting that determines how APF is applied in
+ *	active mode for MC/BC packets
+ * @ito_repeat_count: Indicates ito repeated count
+ * @force_target_assert_enabled: Indicate whether target assert enabled or not
+ * @bandcapability: Configured band by user
+ * @rps_enabled: RPS enabled in SAP mode
+ * @delay_before_vdev_stop: wait time for tx complete before vdev stop
+ * Structure for holding cds ini parameters.
+ * @num_vdevs: Configured max number of VDEVs can be supported in the stack.
+ */
+
+struct cds_config_info {
+	uint16_t max_station;
+	uint16_t max_bssid;
+	uint8_t sta_maxlimod_dtim;
+	enum qdf_driver_type driver_type;
+	uint8_t dfs_phyerr_filter_offload;
+	uint8_t ap_disable_intrabss_fwd;
+	uint8_t ap_maxoffload_peers;
+	uint8_t ap_maxoffload_reorderbuffs;
+#ifdef FEATURE_WLAN_RA_FILTERING
+	uint16_t ra_ratelimit_interval;
+	bool is_ra_ratelimit_enabled;
+#endif
+	uint8_t reorder_offload;
+	int32_t dfs_pri_multiplier;
+	uint8_t uc_offload_enabled;
+	uint32_t uc_txbuf_count;
+	uint32_t uc_txbuf_size;
+	uint32_t uc_rxind_ringcount;
+	uint32_t uc_tx_partition_base;
+	bool enable_rxthread;
+	bool ip_tcp_udp_checksum_offload;
+	bool ce_classify_enabled;
+	uint8_t max_scan;
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+	uint32_t tx_flow_stop_queue_th;
+	uint32_t tx_flow_start_queue_offset;
+#endif
+	uint8_t num_dp_rx_threads;
+	uint8_t enable_dp_rx_threads;
+#ifdef WLAN_FEATURE_LPSS
+	bool is_lpass_enabled;
+#endif
+	uint16_t self_gen_frm_pwr;
+	enum cfg_sub_20_channel_width sub_20_channel_width;
+	bool flow_steering_enabled;
+	uint8_t max_msdus_per_rxinorderind;
+	bool self_recovery_enabled;
+	bool fw_timeout_crash;
+	struct ol_tx_sched_wrr_ac_specs_t ac_specs[TX_WMM_AC_NUM];
+	enum active_apf_mode active_uc_apf_mode;
+	enum active_apf_mode active_mc_bc_apf_mode;
+	uint8_t ito_repeat_count;
+	bool force_target_assert_enabled;
+	uint8_t bandcapability;
+	bool rps_enabled;
+	uint8_t delay_before_vdev_stop;
+	uint32_t num_vdevs;
+};
+
+#ifdef WLAN_FEATURE_FILS_SK
+#define MAX_PMK_LEN 48
+#define MAX_PMKID_LEN 16
+#define FILS_MAX_KEYNAME_NAI_LENGTH 253
+#define FILS_MAX_REALM_LEN 255
+#define FILS_MAX_RRK_LENGTH 64
+#define FILS_MAX_RIK_LENGTH FILS_MAX_RRK_LENGTH
+
+struct cds_fils_connection_info {
+	bool is_fils_connection;
+	uint8_t keyname_nai[FILS_MAX_KEYNAME_NAI_LENGTH];
+	uint32_t key_nai_length;
+	uint16_t sequence_number;
+	uint8_t r_rk[FILS_MAX_RRK_LENGTH];
+	uint32_t r_rk_length;
+	uint8_t realm[FILS_MAX_REALM_LEN];
+	uint32_t realm_len;
+	uint8_t akm_type;
+	uint8_t auth_type;
+	uint8_t pmk[MAX_PMK_LEN];
+	uint8_t pmk_len;
+	uint8_t pmkid[16];
+};
+#endif
+#endif /* !defined( __CDS_CONFIG_H ) */
diff --git a/core/cds/inc/cds_crypto.h b/core/cds/inc/cds_crypto.h
new file mode 100644
index 0000000..0d507be
--- /dev/null
+++ b/core/cds/inc/cds_crypto.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014-2016 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.
+ */
+
+#if !defined(__CDS_CRYPTO_H)
+#define __CDS_CRYPTO_H
+
+/**
+ * DOC:  cds_crypto.h
+ *
+ * Crypto APIs
+ *
+ */
+
+#include <linux/crypto.h>
+
+static inline struct crypto_cipher *
+cds_crypto_alloc_cipher(const char *alg_name, u32 type, u32 mask)
+{
+	return crypto_alloc_cipher(alg_name, type, mask);
+}
+
+static inline void cds_crypto_free_cipher(struct crypto_cipher *tfm)
+{
+	crypto_free_cipher(tfm);
+}
+
+#endif /* if !defined __CDS_CRYPTO_H */
diff --git a/core/cds/inc/cds_ieee80211_common.h b/core/cds/inc/cds_ieee80211_common.h
new file mode 100644
index 0000000..aa23126
--- /dev/null
+++ b/core/cds/inc/cds_ieee80211_common.h
@@ -0,0 +1,2051 @@
+/*
+ * Copyright (c) 2011,2014-2018 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.
+ */
+
+#ifndef EXTERNAL_USE_ONLY
+#include "osdep.h"
+#endif /* EXTERNAL_USE_ONLY */
+#include "cds_ieee80211_common_i.h"
+#include "cdp_txrx_mob_def.h"
+
+#ifndef CDS_COMMON_IEEE80211_H_
+#define CDS_COMMON_IEEE80211_H_
+
+/*
+ * 802.11 protocol definitions.
+ */
+
+#define IEEE80211_IS_IPV4_MULTICAST(_a)  (*(_a) == 0x01)
+
+#define IEEE80211_IS_IPV6_MULTICAST(_a)		\
+	((_a)[0] == 0x33 &&			    \
+	 (_a)[1] == 0x33)
+
+#define IEEE80211_IS_BROADCAST(_a)		\
+	((_a)[0] == 0xff &&			    \
+	 (_a)[1] == 0xff &&			    \
+	 (_a)[2] == 0xff &&			    \
+	 (_a)[3] == 0xff &&			    \
+	 (_a)[4] == 0xff &&			    \
+	 (_a)[5] == 0xff)
+
+/* IEEE 802.11 PLCP header */
+struct ieee80211_plcp_hdr {
+	uint16_t i_sfd;
+	uint8_t i_signal;
+	uint8_t i_service;
+	uint16_t i_length;
+	uint16_t i_crc;
+} __packed;
+
+#define IEEE80211_PLCP_SFD      0xF3A0
+#define IEEE80211_PLCP_SERVICE  0x00
+
+/*
+ * generic definitions for IEEE 802.11 frames
+ */
+struct ieee80211_frame {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	union {
+		struct {
+			uint8_t i_addr1[IEEE80211_ADDR_LEN];
+			uint8_t i_addr2[IEEE80211_ADDR_LEN];
+			uint8_t i_addr3[IEEE80211_ADDR_LEN];
+		};
+		uint8_t i_addr_all[3 * IEEE80211_ADDR_LEN];
+	};
+	uint8_t i_seq[2];
+	/* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
+	/* see below */
+} __packed;
+
+struct ieee80211_qosframe {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	uint8_t i_addr1[IEEE80211_ADDR_LEN];
+	uint8_t i_addr2[IEEE80211_ADDR_LEN];
+	uint8_t i_addr3[IEEE80211_ADDR_LEN];
+	uint8_t i_seq[2];
+	uint8_t i_qos[2];
+	/* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
+	/* see below */
+} __packed;
+
+struct ieee80211_qoscntl {
+	uint8_t i_qos[2];
+};
+
+struct ieee80211_frame_addr4 {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	uint8_t i_addr1[IEEE80211_ADDR_LEN];
+	uint8_t i_addr2[IEEE80211_ADDR_LEN];
+	uint8_t i_addr3[IEEE80211_ADDR_LEN];
+	uint8_t i_seq[2];
+	uint8_t i_addr4[IEEE80211_ADDR_LEN];
+} __packed;
+
+struct ieee80211_qosframe_addr4 {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	uint8_t i_addr1[IEEE80211_ADDR_LEN];
+	uint8_t i_addr2[IEEE80211_ADDR_LEN];
+	uint8_t i_addr3[IEEE80211_ADDR_LEN];
+	uint8_t i_seq[2];
+	uint8_t i_addr4[IEEE80211_ADDR_LEN];
+	uint8_t i_qos[2];
+} __packed;
+
+/* HTC frame for TxBF*/
+/* for TxBF RC */
+struct ieee80211_frame_min_one {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	uint8_t i_addr1[IEEE80211_ADDR_LEN];
+
+} __packed;                     /* For TxBF RC */
+
+struct ieee80211_qosframe_htc {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	uint8_t i_addr1[IEEE80211_ADDR_LEN];
+	uint8_t i_addr2[IEEE80211_ADDR_LEN];
+	uint8_t i_addr3[IEEE80211_ADDR_LEN];
+	uint8_t i_seq[2];
+	uint8_t i_qos[2];
+	uint8_t i_htc[4];
+	/* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
+	/* see below */
+} __packed;
+struct ieee80211_qosframe_htc_addr4 {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	uint8_t i_addr1[IEEE80211_ADDR_LEN];
+	uint8_t i_addr2[IEEE80211_ADDR_LEN];
+	uint8_t i_addr3[IEEE80211_ADDR_LEN];
+	uint8_t i_seq[2];
+	uint8_t i_addr4[IEEE80211_ADDR_LEN];
+	uint8_t i_qos[2];
+	uint8_t i_htc[4];
+} __packed;
+struct ieee80211_htc {
+	uint8_t i_htc[4];
+};
+/*HTC frame for TxBF*/
+
+struct ieee80211_ctlframe_addr2 {
+	uint8_t i_fc[2];
+	uint8_t i_aidordur[2];  /* AID or duration */
+	uint8_t i_addr1[IEEE80211_ADDR_LEN];
+	uint8_t i_addr2[IEEE80211_ADDR_LEN];
+} __packed;
+
+#define IEEE80211_WHQ(wh)               ((struct ieee80211_qosframe *)(wh))
+#define IEEE80211_WH4(wh)               ((struct ieee80211_frame_addr4 *)(wh))
+#define IEEE80211_WHQ4(wh)              ((struct ieee80211_qosframe_addr4 *)(wh))
+
+#define IEEE80211_FC0_VERSION_MASK          0x03
+#define IEEE80211_FC0_VERSION_SHIFT         0
+#define IEEE80211_FC0_VERSION_0             0x00
+#define IEEE80211_FC0_TYPE_MASK             0x0c
+#define IEEE80211_FC0_TYPE_SHIFT            2
+#define IEEE80211_FC0_TYPE_MGT              0x00
+#define IEEE80211_FC0_TYPE_CTL              0x04
+#define IEEE80211_FC0_TYPE_DATA             0x08
+
+#define IEEE80211_FC0_SUBTYPE_MASK          0xf0
+#define IEEE80211_FC0_SUBTYPE_SHIFT         4
+/* for TYPE_MGT */
+#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ     0x00
+#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP    0x10
+#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ   0x20
+#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP  0x30
+#define IEEE80211_FC0_SUBTYPE_PROBE_REQ     0x40
+#define IEEE80211_FC0_SUBTYPE_PROBE_RESP    0x50
+#define IEEE80211_FC0_SUBTYPE_BEACON        0x80
+#define IEEE80211_FC0_SUBTYPE_ATIM          0x90
+#define IEEE80211_FC0_SUBTYPE_DISASSOC      0xa0
+#define IEEE80211_FC0_SUBTYPE_AUTH          0xb0
+#define IEEE80211_FC0_SUBTYPE_DEAUTH        0xc0
+#define IEEE80211_FC0_SUBTYPE_ACTION        0xd0
+#define IEEE80211_FCO_SUBTYPE_ACTION_NO_ACK 0xe0
+/* for TYPE_CTL */
+#define IEEE80211_FCO_SUBTYPE_Control_Wrapper   0x70    /* For TxBF RC */
+#define IEEE80211_FC0_SUBTYPE_BAR           0x80
+#define IEEE80211_FC0_SUBTYPE_PS_POLL       0xa0
+#define IEEE80211_FC0_SUBTYPE_RTS           0xb0
+#define IEEE80211_FC0_SUBTYPE_CTS           0xc0
+#define IEEE80211_FC0_SUBTYPE_ACK           0xd0
+#define IEEE80211_FC0_SUBTYPE_CF_END        0xe0
+#define IEEE80211_FC0_SUBTYPE_CF_END_ACK    0xf0
+/* for TYPE_DATA (bit combination) */
+#define IEEE80211_FC0_SUBTYPE_DATA          0x00
+#define IEEE80211_FC0_SUBTYPE_CF_ACK        0x10
+#define IEEE80211_FC0_SUBTYPE_CF_POLL       0x20
+#define IEEE80211_FC0_SUBTYPE_CF_ACPL       0x30
+#define IEEE80211_FC0_SUBTYPE_NODATA        0x40
+#define IEEE80211_FC0_SUBTYPE_CFACK         0x50
+#define IEEE80211_FC0_SUBTYPE_CFPOLL        0x60
+#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70
+#define IEEE80211_FC0_SUBTYPE_QOS           0x80
+#define IEEE80211_FC0_SUBTYPE_QOS_NULL      0xc0
+
+#define IEEE80211_FC1_DIR_MASK              0x03
+#define IEEE80211_FC1_DIR_NODS              0x00        /* STA->STA */
+#define IEEE80211_FC1_DIR_TODS              0x01        /* STA->AP  */
+#define IEEE80211_FC1_DIR_FROMDS            0x02        /* AP ->STA */
+#define IEEE80211_FC1_DIR_DSTODS            0x03        /* AP ->AP  */
+
+#define IEEE80211_FC1_MORE_FRAG             0x04
+#define IEEE80211_FC1_RETRY                 0x08
+#define IEEE80211_FC1_PWR_MGT               0x10
+#define IEEE80211_FC1_MORE_DATA             0x20
+#define IEEE80211_FC1_WEP                   0x40
+#define IEEE80211_FC1_ORDER                 0x80
+
+#define IEEE80211_SEQ_FRAG_MASK             0x000f
+#define IEEE80211_SEQ_FRAG_SHIFT            0
+#define IEEE80211_SEQ_SEQ_MASK              0xfff0
+#define IEEE80211_SEQ_SEQ_SHIFT             4
+#define IEEE80211_SEQ_MAX                   4096
+
+#define IEEE80211_SEQ_LEQ(a, b)  ((int)((a) - (b)) <= 0)
+
+#define IEEE80211_QOS_TXOP                  0x00ff
+
+#define IEEE80211_QOS_AMSDU                 0x80
+#define IEEE80211_QOS_AMSDU_S               7
+#define IEEE80211_QOS_ACKPOLICY             0x60
+#define IEEE80211_QOS_ACKPOLICY_S           5
+#define IEEE80211_QOS_EOSP                  0x10
+#define IEEE80211_QOS_EOSP_S                4
+#define IEEE80211_QOS_TID                   0x0f
+#define IEEE80211_MFP_TID                   0xff
+
+#define IEEE80211_HTC0_TRQ                  0x02
+#define IEEE80211_HTC2_CalPos               0x03
+#define IEEE80211_HTC2_CalSeq               0x0C
+#define IEEE80211_HTC2_CSI_NONCOMP_BF       0x80
+#define IEEE80211_HTC2_CSI_COMP_BF          0xc0
+
+/* Set bits 14 and 15 to 1 when duration field carries Association ID */
+#define IEEE80211_FIELD_TYPE_AID            0xC000
+
+#define IEEE80211_IS_BEACON(_frame)    ((((_frame)->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) && \
+					(((_frame)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_BEACON))
+#define IEEE80211_IS_DATA(_frame)      (((_frame)->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
+
+#define IEEE80211_IS_MFP_FRAME(_frame) ((((_frame)->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) && \
+					((_frame)->i_fc[1] & IEEE80211_FC1_WEP) && \
+					((((_frame)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_DEAUTH) || \
+					 (((_frame)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_DISASSOC) || \
+					 (((_frame)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_ACTION)))
+#define IEEE80211_IS_AUTH(_frame)      ((((_frame)->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) && \
+					(((_frame)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_AUTH))
+
+/* MCS Set */
+#define IEEE80211_RX_MCS_1_STREAM_BYTE_OFFSET 0
+#define IEEE80211_RX_MCS_2_STREAM_BYTE_OFFSET 1
+#define IEEE80211_RX_MCS_3_STREAM_BYTE_OFFSET 2
+#define IEEE80211_RX_MCS_ALL_NSTREAM_RATES 0xff
+#define IEEE80211_TX_MCS_OFFSET 12
+
+#define IEEE80211_TX_MCS_SET_DEFINED 0x80
+#define IEEE80211_TX_RX_MCS_SET_NOT_EQUAL 0x40
+#define IEEE80211_TX_1_SPATIAL_STREAMS 0x0
+#define IEEE80211_TX_2_SPATIAL_STREAMS 0x10
+#define IEEE80211_TX_3_SPATIAL_STREAMS 0x20
+#define IEEE80211_TX_4_SPATIAL_STREAMS 0x30
+
+#define IEEE80211_TX_MCS_SET 0xf8
+
+/*
+ * Subtype data: If bit 6 is set then the data frame contains no actual data.
+ */
+#define IEEE80211_FC0_SUBTYPE_NO_DATA_MASK  0x40
+#define IEEE80211_CONTAIN_DATA(_subtype) \
+	(!((_subtype) & IEEE80211_FC0_SUBTYPE_NO_DATA_MASK))
+
+#define IEEE8023_MAX_LEN 0x600  /* 1536 - larger is Ethernet II */
+#define RFC1042_SNAP_ORGCODE_0 0x00
+#define RFC1042_SNAP_ORGCODE_1 0x00
+#define RFC1042_SNAP_ORGCODE_2 0x00
+
+#define BTEP_SNAP_ORGCODE_0 0x00
+#define BTEP_SNAP_ORGCODE_1 0x00
+#define BTEP_SNAP_ORGCODE_2 0xf8
+
+/* BT 3.0 */
+#define BTAMP_SNAP_ORGCODE_0 0x00
+#define BTAMP_SNAP_ORGCODE_1 0x19
+#define BTAMP_SNAP_ORGCODE_2 0x58
+
+/* Aironet OUI Codes */
+#define AIRONET_SNAP_CODE_0  0x00
+#define AIRONET_SNAP_CODE_1  0x40
+#define AIRONET_SNAP_CODE_2  0x96
+
+#define IEEE80211_LSIG_LEN  3
+#define IEEE80211_HTSIG_LEN 6
+#define IEEE80211_SB_LEN    2
+
+/*
+ * Information element header format
+ */
+struct ieee80211_ie_header {
+	uint8_t element_id;     /* Element Id */
+	uint8_t length;         /* IE Length */
+} __packed;
+
+/*
+ * Country information element.
+ */
+#define IEEE80211_COUNTRY_MAX_TRIPLETS (83)
+struct ieee80211_ie_country {
+	uint8_t country_id;
+	uint8_t country_len;
+	uint8_t country_str[3];
+	uint8_t country_triplet[IEEE80211_COUNTRY_MAX_TRIPLETS * 3];
+} __packed;
+
+/* does frame have QoS sequence control data */
+#define IEEE80211_QOS_HAS_SEQ(wh) \
+	(((wh)->i_fc[0] & \
+	  (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == \
+	 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
+
+#define WME_QOSINFO_UAPSD   0x80        /* Mask for U-APSD field */
+#define WME_QOSINFO_COUNT   0x0f        /* Mask for Param Set Count field */
+/*
+ * WME/802.11e information element.
+ */
+struct ieee80211_ie_wme {
+	uint8_t wme_id;         /* IEEE80211_ELEMID_VENDOR */
+	uint8_t wme_len;        /* length in bytes */
+	uint8_t wme_oui[3];     /* 0x00, 0x50, 0xf2 */
+	uint8_t wme_type;       /* OUI type */
+	uint8_t wme_subtype;    /* OUI subtype */
+	uint8_t wme_version;    /* spec revision */
+	uint8_t wme_info;       /* QoS info */
+} __packed;
+
+/*
+ * TS INFO part of the tspec element is a collection of bit flags
+ */
+#if _BYTE_ORDER == _BIG_ENDIAN
+struct ieee80211_tsinfo_bitmap {
+	uint8_t one : 1, direction : 2, tid : 4, reserved1 : 1;
+	uint8_t reserved2 : 2, dot1Dtag : 3, psb : 1, reserved3 : 1, zero : 1;
+	uint8_t reserved5 : 7, reserved4 : 1;
+} __packed;
+#else
+struct ieee80211_tsinfo_bitmap {
+	uint8_t reserved1 : 1, tid : 4, direction : 2, one : 1;
+	uint8_t zero : 1, reserved3 : 1, psb : 1, dot1Dtag : 3, reserved2 : 2;
+	uint8_t reserved4 : 1, reserved5 : 7;
+} __packed;
+#endif
+
+/*
+ * WME/802.11e Tspec Element
+ */
+struct ieee80211_wme_tspec {
+	uint8_t ts_id;
+	uint8_t ts_len;
+	uint8_t ts_oui[3];
+	uint8_t ts_oui_type;
+	uint8_t ts_oui_subtype;
+	uint8_t ts_version;
+	uint8_t ts_tsinfo[3];
+	uint8_t ts_nom_msdu[2];
+	uint8_t ts_max_msdu[2];
+	uint8_t ts_min_svc[4];
+	uint8_t ts_max_svc[4];
+	uint8_t ts_inactv_intv[4];
+	uint8_t ts_susp_intv[4];
+	uint8_t ts_start_svc[4];
+	uint8_t ts_min_rate[4];
+	uint8_t ts_mean_rate[4];
+	uint8_t ts_peak_rate[4];
+	uint8_t ts_max_burst[4];
+	uint8_t ts_delay[4];
+	uint8_t ts_min_phy[4];
+	uint8_t ts_surplus[2];
+	uint8_t ts_medium_time[2];
+} __packed;
+
+/*
+ * WME AC parameter field
+ */
+struct ieee80211_wme_acparams {
+	uint8_t acp_aci_aifsn;
+	uint8_t acp_logcwminmax;
+	uint16_t acp_txop;
+} __packed;
+
+#define IEEE80211_WME_PARAM_LEN 24
+#define WME_NUM_AC              4       /* 4 AC categories */
+
+#define WME_PARAM_ACI           0x60    /* Mask for ACI field */
+#define WME_PARAM_ACI_S         5       /* Shift for ACI field */
+#define WME_PARAM_ACM           0x10    /* Mask for ACM bit */
+#define WME_PARAM_ACM_S         4       /* Shift for ACM bit */
+#define WME_PARAM_AIFSN         0x0f    /* Mask for aifsn field */
+#define WME_PARAM_AIFSN_S       0       /* Shift for aifsn field */
+#define WME_PARAM_LOGCWMIN      0x0f    /* Mask for CwMin field (in log) */
+#define WME_PARAM_LOGCWMIN_S    0       /* Shift for CwMin field */
+#define WME_PARAM_LOGCWMAX      0xf0    /* Mask for CwMax field (in log) */
+#define WME_PARAM_LOGCWMAX_S    4       /* Shift for CwMax field */
+
+#define WME_AC_TO_TID(_ac) (	   \
+		((_ac) == WME_AC_VO) ? 6 : \
+		((_ac) == WME_AC_VI) ? 5 : \
+		((_ac) == WME_AC_BK) ? 1 : \
+		0)
+
+#define TID_TO_WME_AC(_tid) (	   \
+		(((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
+		(((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
+		(((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
+		WME_AC_VO)
+
+/*
+ * WME Parameter Element
+ */
+struct ieee80211_wme_param {
+	uint8_t param_id;
+	uint8_t param_len;
+	uint8_t param_oui[3];
+	uint8_t param_oui_type;
+	uint8_t param_oui_sybtype;
+	uint8_t param_version;
+	uint8_t param_qosInfo;
+	uint8_t param_reserved;
+	struct ieee80211_wme_acparams params_acParams[WME_NUM_AC];
+} __packed;
+
+/*
+ * WME U-APSD qos info field defines
+ */
+#define WME_CAPINFO_UAPSD_EN                    0x00000080
+#define WME_CAPINFO_UAPSD_VO                    0x00000001
+#define WME_CAPINFO_UAPSD_VI                    0x00000002
+#define WME_CAPINFO_UAPSD_BK                    0x00000004
+#define WME_CAPINFO_UAPSD_BE                    0x00000008
+#define WME_CAPINFO_UAPSD_ACFLAGS_SHIFT         0
+#define WME_CAPINFO_UAPSD_ACFLAGS_MASK          0xF
+#define WME_CAPINFO_UAPSD_MAXSP_SHIFT           5
+#define WME_CAPINFO_UAPSD_MAXSP_MASK            0x3
+#define WME_CAPINFO_IE_OFFSET                   8
+#define WME_UAPSD_MAXSP(_qosinfo) (((_qosinfo) >> WME_CAPINFO_UAPSD_MAXSP_SHIFT) & WME_CAPINFO_UAPSD_MAXSP_MASK)
+#define WME_UAPSD_AC_ENABLED(_ac, _qosinfo) ((1 << (3 - (_ac))) &   \
+					      (((_qosinfo) >> WME_CAPINFO_UAPSD_ACFLAGS_SHIFT) & WME_CAPINFO_UAPSD_ACFLAGS_MASK))
+
+/* Mask used to determined whether all queues are UAPSD-enabled */
+#define WME_CAPINFO_UAPSD_ALL                   (WME_CAPINFO_UAPSD_VO |	\
+						 WME_CAPINFO_UAPSD_VI |	\
+						 WME_CAPINFO_UAPSD_BK |	\
+						 WME_CAPINFO_UAPSD_BE)
+#define WME_CAPINFO_UAPSD_NONE          0
+
+#define WME_UAPSD_AC_MAX_VAL            1
+#define WME_UAPSD_AC_INVAL              (WME_UAPSD_AC_MAX_VAL + 1)
+
+/*
+ * Atheros Advanced Capability information element.
+ */
+struct ieee80211_ie_athAdvCap {
+	uint8_t athAdvCap_id;   /* IEEE80211_ELEMID_VENDOR */
+	uint8_t athAdvCap_len;  /* length in bytes */
+	uint8_t athAdvCap_oui[3];       /* 0x00, 0x03, 0x7f */
+	uint8_t athAdvCap_type; /* OUI type */
+	uint16_t athAdvCap_version;     /* spec revision */
+	uint8_t athAdvCap_capability;   /* Capability info */
+	uint16_t athAdvCap_defKeyIndex;
+} __packed;
+
+/*
+ * Atheros Extended Capability information element.
+ */
+struct ieee80211_ie_ath_extcap {
+	uint8_t ath_extcap_id;  /* IEEE80211_ELEMID_VENDOR */
+	uint8_t ath_extcap_len; /* length in bytes */
+	uint8_t ath_extcap_oui[3];      /* 0x00, 0x03, 0x7f */
+	uint8_t ath_extcap_type;        /* OUI type */
+	uint8_t ath_extcap_subtype;     /* OUI subtype */
+	uint8_t ath_extcap_version;     /* spec revision */
+	uint32_t ath_extcap_extcap : 16,  /* B0-15  extended capabilities */
+		 ath_extcap_weptkipaggr_rxdelim : 8, /* B16-23 num delimiters for receiving WEP/TKIP aggregates */
+		 ath_extcap_reserved : 8; /* B24-31 reserved */
+} __packed;
+
+/*
+ * Atheros XR information element.
+ */
+struct ieee80211_xr_param {
+	uint8_t param_id;
+	uint8_t param_len;
+	uint8_t param_oui[3];
+	uint8_t param_oui_type;
+	uint8_t param_oui_sybtype;
+	uint8_t param_version;
+	uint8_t param_Info;
+	uint8_t param_base_bssid[IEEE80211_ADDR_LEN];
+	uint8_t param_xr_bssid[IEEE80211_ADDR_LEN];
+	uint16_t param_xr_beacon_interval;
+	uint8_t param_base_ath_capability;
+	uint8_t param_xr_ath_capability;
+} __packed;
+
+/*
+ * SFA information element.
+ */
+struct ieee80211_ie_sfa {
+	uint8_t sfa_id;         /* IEEE80211_ELEMID_VENDOR */
+	uint8_t sfa_len;        /* length in bytes */
+	uint8_t sfa_oui[3];     /* 0x00, 0x40, 0x96 */
+	uint8_t sfa_type;       /* OUI type */
+	uint8_t sfa_caps;       /* Capabilities */
+} __packed;
+
+/* Atheros capabilities */
+#define IEEE80211_ATHC_TURBOP   0x0001  /* Turbo Prime */
+#define IEEE80211_ATHC_COMP     0x0002  /* Compression */
+#define IEEE80211_ATHC_FF       0x0004  /* Fast Frames */
+#define IEEE80211_ATHC_XR       0x0008  /* Xtended Range support */
+#define IEEE80211_ATHC_AR       0x0010  /* Advanced Radar support */
+#define IEEE80211_ATHC_BURST    0x0020  /* Bursting - not negotiated */
+#define IEEE80211_ATHC_WME      0x0040  /* CWMin tuning */
+#define IEEE80211_ATHC_BOOST    0x0080  /* Boost */
+#define IEEE80211_ATHC_TDLS     0x0100  /* TDLS */
+
+/* Atheros extended capabilities */
+/* OWL device capable of WDS workaround */
+#define IEEE80211_ATHEC_OWLWDSWAR        0x0001
+#define IEEE80211_ATHEC_WEPTKIPAGGR          0x0002
+#define IEEE80211_ATHEC_EXTRADELIMWAR    0x0004
+/*
+ * Management Frames
+ */
+
+/*
+ * *** Platform-specific code?? ***
+ * In Vista one must use bit fields of type (unsigned short = uint16_t) to
+ * ensure data structure is of the correct size. ANSI C used to specify only
+ * "int" bit fields, which led to a larger structure size in Windows (32 bits).
+ *
+ * We must make sure the following construction is valid in all OS's.
+ */
+union ieee80211_capability {
+	struct {
+		uint16_t ess : 1;
+		uint16_t ibss : 1;
+		uint16_t cf_pollable : 1;
+		uint16_t cf_poll_request : 1;
+		uint16_t privacy : 1;
+		uint16_t short_preamble : 1;
+		uint16_t pbcc : 1;
+		uint16_t channel_agility : 1;
+		uint16_t spectrum_management : 1;
+		uint16_t qos : 1;
+		uint16_t short_slot_time : 1;
+		uint16_t apsd : 1;
+		uint16_t reserved2 : 1;
+		uint16_t dsss_ofdm : 1;
+		uint16_t del_block_ack : 1;
+		uint16_t immed_block_ack : 1;
+	};
+
+	uint16_t value;
+} __packed;
+
+struct ieee80211_beacon_frame {
+	uint8_t timestamp[8];   /* the value of sender's TSFTIMER */
+	uint16_t beacon_interval;       /* the number of time units between target beacon transmission times */
+	union ieee80211_capability capability;
+/* Value of capability for every bit
+   #define IEEE80211_CAPINFO_ESS               0x0001
+   #define IEEE80211_CAPINFO_IBSS              0x0002
+   #define IEEE80211_CAPINFO_CF_POLLABLE       0x0004
+   #define IEEE80211_CAPINFO_CF_POLLREQ        0x0008
+   #define IEEE80211_CAPINFO_PRIVACY           0x0010
+   #define IEEE80211_CAPINFO_SHORT_PREAMBLE    0x0020
+   #define IEEE80211_CAPINFO_PBCC              0x0040
+   #define IEEE80211_CAPINFO_CHNL_AGILITY      0x0080
+   #define IEEE80211_CAPINFO_SPECTRUM_MGMT     0x0100
+   #define IEEE80211_CAPINFO_QOS               0x0200
+   #define IEEE80211_CAPINFO_SHORT_SLOTTIME    0x0400
+   #define IEEE80211_CAPINFO_APSD              0x0800
+   #define IEEE80211_CAPINFO_RADIOMEAS         0x1000
+   #define IEEE80211_CAPINFO_DSSSOFDM          0x2000
+   bits 14-15 are reserved
+ */
+	struct ieee80211_ie_header info_elements;
+} __packed;
+
+/*
+ * Management Action Frames
+ */
+
+/* generic frame format */
+struct ieee80211_action {
+	uint8_t ia_category;
+	uint8_t ia_action;
+} __packed;
+
+/* spectrum action frame header */
+struct ieee80211_action_measrep_header {
+	struct ieee80211_action action_header;
+	uint8_t dialog_token;
+} __packed;
+
+/* categories */
+#define IEEE80211_ACTION_CAT_SPECTRUM       0   /* Spectrum management */
+#define IEEE80211_ACTION_CAT_QOS            1   /* IEEE QoS  */
+#define IEEE80211_ACTION_CAT_DLS            2   /* DLS */
+#define IEEE80211_ACTION_CAT_BA             3   /* BA */
+#define IEEE80211_ACTION_CAT_PUBLIC         4   /* Public Action Frame */
+#define IEEE80211_ACTION_CAT_HT             7   /* HT per IEEE802.11n-D1.06 */
+#define IEEE80211_ACTION_CAT_SA_QUERY       8   /* SA Query per IEEE802.11w, PMF */
+#define IEEE80211_ACTION_CAT_WMM_QOS       17   /* QoS from WMM specification */
+#define IEEE80211_ACTION_CAT_VHT           21   /* VHT Action */
+
+/* Spectrum Management actions */
+#define IEEE80211_ACTION_MEAS_REQUEST       0   /* Measure channels */
+#define IEEE80211_ACTION_MEAS_REPORT        1
+#define IEEE80211_ACTION_TPC_REQUEST        2   /* Transmit Power control */
+#define IEEE80211_ACTION_TPC_REPORT         3
+#define IEEE80211_ACTION_CHAN_SWITCH        4   /* 802.11h Channel Switch Announcement */
+
+/* HT actions */
+#define IEEE80211_ACTION_HT_TXCHWIDTH       0   /* recommended transmission channel width */
+#define IEEE80211_ACTION_HT_SMPOWERSAVE     1   /* Spatial Multiplexing (SM) Power Save */
+#define IEEE80211_ACTION_HT_CSI             4   /* CSI Frame */
+#define IEEE80211_ACTION_HT_NONCOMP_BF      5   /* Non-compressed Beamforming */
+#define IEEE80211_ACTION_HT_COMP_BF         6   /* Compressed Beamforming */
+
+/* VHT actions */
+#define IEEE80211_ACTION_VHT_OPMODE         2   /* Operating  mode notification */
+
+/* Spectrum channel switch action frame after IE*/
+/* Public Actions*/
+#define IEEE80211_ACTION_TDLS_DISCRESP  14      /* TDLS Discovery Response frame */
+
+/* HT - recommended transmission channel width */
+struct ieee80211_action_ht_txchwidth {
+	struct ieee80211_action at_header;
+	uint8_t at_chwidth;
+} __packed;
+
+#define IEEE80211_A_HT_TXCHWIDTH_20         0
+#define IEEE80211_A_HT_TXCHWIDTH_2040       1
+
+/* HT - Spatial Multiplexing (SM) Power Save */
+struct ieee80211_action_ht_smpowersave {
+	struct ieee80211_action as_header;
+	uint8_t as_control;
+} __packed;
+
+/*HT - CSI Frame */                        /* for TxBF RC */
+#define MIMO_CONTROL_LEN 6
+struct ieee80211_action_ht_CSI {
+	struct ieee80211_action as_header;
+	uint8_t mimo_control[MIMO_CONTROL_LEN];
+} __packed;
+
+/*HT - V/CV report frame*/
+struct ieee80211_action_ht_txbf_rpt {
+	struct ieee80211_action as_header;
+	uint8_t mimo_control[MIMO_CONTROL_LEN];
+} __packed;
+
+/*
+ * 802.11ac Operating Mode  Notification
+ */
+struct ieee80211_ie_op_mode {
+#if _BYTE_ORDER == _BIG_ENDIAN
+	uint8_t rx_nss_type : 1, rx_nss : 3, reserved : 2, ch_width : 2;
+#else
+	uint8_t ch_width : 2, reserved : 2, rx_nss : 3, rx_nss_type : 1;
+#endif
+} __packed;
+
+struct ieee80211_ie_op_mode_ntfy {
+	uint8_t elem_id;
+	uint8_t elem_len;
+	struct ieee80211_ie_op_mode opmode;
+} __packed;
+
+/* VHT - recommended Channel width and Nss */
+struct ieee80211_action_vht_opmode {
+	struct ieee80211_action at_header;
+	struct ieee80211_ie_op_mode at_op_mode;
+} __packed;
+
+/* values defined for 'as_control' field per 802.11n-D1.06 */
+#define IEEE80211_A_HT_SMPOWERSAVE_DISABLED     0x00    /* SM Power Save Disabled, SM packets ok  */
+#define IEEE80211_A_HT_SMPOWERSAVE_ENABLED      0x01    /* SM Power Save Enabled bit  */
+#define IEEE80211_A_HT_SMPOWERSAVE_MODE         0x02    /* SM Power Save Mode bit */
+#define IEEE80211_A_HT_SMPOWERSAVE_RESERVED     0xFC    /* SM Power Save Reserved bits */
+
+/* values defined for SM Power Save Mode bit */
+#define IEEE80211_A_HT_SMPOWERSAVE_STATIC       0x00    /* Static, SM packets not ok */
+#define IEEE80211_A_HT_SMPOWERSAVE_DYNAMIC      0x02    /* Dynamic, SM packets ok if preceded by RTS */
+
+/* DLS actions */
+#define IEEE80211_ACTION_DLS_REQUEST            0
+#define IEEE80211_ACTION_DLS_RESPONSE           1
+#define IEEE80211_ACTION_DLS_TEARDOWN           2
+
+struct ieee80211_dls_request {
+	struct ieee80211_action hdr;
+	uint8_t dst_addr[IEEE80211_ADDR_LEN];
+	uint8_t src_addr[IEEE80211_ADDR_LEN];
+	uint16_t capa_info;
+	uint16_t timeout;
+} __packed;
+
+struct ieee80211_dls_response {
+	struct ieee80211_action hdr;
+	uint16_t statuscode;
+	uint8_t dst_addr[IEEE80211_ADDR_LEN];
+	uint8_t src_addr[IEEE80211_ADDR_LEN];
+} __packed;
+
+/* BA - ADDBA request */
+struct ieee80211_action_ba_addbarequest {
+	struct ieee80211_action rq_header;
+	uint8_t rq_dialogtoken;
+	struct ieee80211_ba_parameterset rq_baparamset;
+	uint16_t rq_batimeout;  /* in TUs */
+	struct ieee80211_ba_seqctrl rq_basequencectrl;
+} __packed;
+
+/* BA - ADDBA response */
+struct ieee80211_action_ba_addbaresponse {
+	struct ieee80211_action rs_header;
+	uint8_t rs_dialogtoken;
+	uint16_t rs_statuscode;
+	struct ieee80211_ba_parameterset rs_baparamset;
+	uint16_t rs_batimeout;  /* in TUs */
+} __packed;
+
+/* BA - DELBA */
+struct ieee80211_action_ba_delba {
+	struct ieee80211_action dl_header;
+	struct ieee80211_delba_parameterset dl_delbaparamset;
+	uint16_t dl_reasoncode;
+} __packed;
+
+/* MGT Notif actions */
+#define IEEE80211_WMM_QOS_ACTION_SETUP_REQ    0
+#define IEEE80211_WMM_QOS_ACTION_SETUP_RESP   1
+#define IEEE80211_WMM_QOS_ACTION_TEARDOWN     2
+
+#define IEEE80211_WMM_QOS_DIALOG_TEARDOWN     0
+#define IEEE80211_WMM_QOS_DIALOG_SETUP        1
+
+#define IEEE80211_WMM_QOS_TSID_DATA_TSPEC     6
+#define IEEE80211_WMM_QOS_TSID_SIG_TSPEC      7
+
+struct ieee80211_action_wmm_qos {
+	struct ieee80211_action ts_header;
+	uint8_t ts_dialogtoken;
+	uint8_t ts_statuscode;
+	struct ieee80211_wme_tspec ts_tspecie;
+} __packed;
+
+/*
+ * Control frames.
+ */
+struct ieee80211_frame_min {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	uint8_t i_addr1[IEEE80211_ADDR_LEN];
+	uint8_t i_addr2[IEEE80211_ADDR_LEN];
+	/* FCS */
+} __packed;
+
+/*
+ * BAR frame format
+ */
+#define IEEE80211_BAR_CTL_TID_M     0xF000      /* tid mask             */
+#define IEEE80211_BAR_CTL_TID_S         12      /* tid shift            */
+#define IEEE80211_BAR_CTL_NOACK     0x0001      /* no-ack policy        */
+#define IEEE80211_BAR_CTL_COMBA     0x0004      /* compressed block-ack */
+
+/*
+ * SA Query Action mgmt Frame
+ */
+struct ieee80211_action_sa_query {
+	struct ieee80211_action sa_header;
+	uint16_t sa_transId;
+};
+
+typedef enum ieee80211_action_sa_query_type {
+	IEEE80211_ACTION_SA_QUERY_REQUEST,
+	IEEE80211_ACTION_SA_QUERY_RESPONSE
+} ieee80211_action_sa_query_type_t;
+
+struct ieee80211_frame_bar {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	uint8_t i_ra[IEEE80211_ADDR_LEN];
+	uint8_t i_ta[IEEE80211_ADDR_LEN];
+	uint16_t i_ctl;
+	uint16_t i_seq;
+	/* FCS */
+} __packed;
+
+struct ieee80211_frame_rts {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	uint8_t i_ra[IEEE80211_ADDR_LEN];
+	uint8_t i_ta[IEEE80211_ADDR_LEN];
+	/* FCS */
+} __packed;
+
+struct ieee80211_frame_cts {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	uint8_t i_ra[IEEE80211_ADDR_LEN];
+	/* FCS */
+} __packed;
+
+struct ieee80211_frame_ack {
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];
+	uint8_t i_ra[IEEE80211_ADDR_LEN];
+	/* FCS */
+} __packed;
+
+struct ieee80211_frame_pspoll {
+	uint8_t i_fc[2];
+	uint8_t i_aid[2];
+	uint8_t i_bssid[IEEE80211_ADDR_LEN];
+	uint8_t i_ta[IEEE80211_ADDR_LEN];
+	/* FCS */
+} __packed;
+
+struct ieee80211_frame_cfend {  /* NB: also CF-End+CF-Ack */
+	uint8_t i_fc[2];
+	uint8_t i_dur[2];       /* should be zero */
+	uint8_t i_ra[IEEE80211_ADDR_LEN];
+	uint8_t i_bssid[IEEE80211_ADDR_LEN];
+	/* FCS */
+} __packed;
+
+/*
+ * BEACON management packets
+ *
+ *  octet timestamp[8]
+ *  octet beacon interval[2]
+ *  octet capability information[2]
+ *  information element
+ *      octet elemid
+ *      octet length
+ *      octet information[length]
+ */
+
+typedef uint8_t *ieee80211_mgt_beacon_t;
+
+#define IEEE80211_BEACON_INTERVAL(beacon) \
+	((beacon)[8] | ((beacon)[9] << 8))
+#define IEEE80211_BEACON_CAPABILITY(beacon) \
+	((beacon)[10] | ((beacon)[11] << 8))
+
+#define IEEE80211_CAPINFO_ESS               0x0001
+#define IEEE80211_CAPINFO_IBSS              0x0002
+#define IEEE80211_CAPINFO_CF_POLLABLE       0x0004
+#define IEEE80211_CAPINFO_CF_POLLREQ        0x0008
+#define IEEE80211_CAPINFO_PRIVACY           0x0010
+#define IEEE80211_CAPINFO_SHORT_PREAMBLE    0x0020
+#define IEEE80211_CAPINFO_PBCC              0x0040
+#define IEEE80211_CAPINFO_CHNL_AGILITY      0x0080
+#define IEEE80211_CAPINFO_SPECTRUM_MGMT     0x0100
+#define IEEE80211_CAPINFO_QOS               0x0200
+#define IEEE80211_CAPINFO_SHORT_SLOTTIME    0x0400
+#define IEEE80211_CAPINFO_APSD              0x0800
+#define IEEE80211_CAPINFO_RADIOMEAS         0x1000
+#define IEEE80211_CAPINFO_DSSSOFDM          0x2000
+/* bits 14-15 are reserved */
+
+/*
+ * 802.11i/WPA information element (maximally sized).
+ */
+struct ieee80211_ie_wpa {
+	uint8_t wpa_id;         /* IEEE80211_ELEMID_VENDOR */
+	uint8_t wpa_len;        /* length in bytes */
+	uint8_t wpa_oui[3];     /* 0x00, 0x50, 0xf2 */
+	uint8_t wpa_type;       /* OUI type */
+	uint16_t wpa_version;   /* spec revision */
+	uint32_t wpa_mcipher[1];        /* multicast/group key cipher */
+	uint16_t wpa_uciphercnt;        /* # pairwise key ciphers */
+	uint32_t wpa_uciphers[8];       /* ciphers */
+	uint16_t wpa_authselcnt;        /* authentication selector cnt */
+	uint32_t wpa_authsels[8];       /* selectors */
+	uint16_t wpa_caps;      /* 802.11i capabilities */
+	uint16_t wpa_pmkidcnt;  /* 802.11i pmkid count */
+	uint16_t wpa_pmkids[8]; /* 802.11i pmkids */
+} __packed;
+
+#ifndef _BYTE_ORDER
+#error "Don't know native byte order"
+#endif
+
+#ifndef IEEE80211N_IE
+/* Temporary vendor specific IE for 11n pre-standard interoperability */
+#define VENDOR_HT_OUI       0x00904c
+#define VENDOR_HT_CAP_ID    51
+#define VENDOR_HT_INFO_ID   52
+#endif
+
+#ifdef ATH_SUPPORT_TxBF
+union ieee80211_hc_txbf {
+	struct {
+#if _BYTE_ORDER == _BIG_ENDIAN
+		uint32_t reserved : 3,
+			 channel_estimation_cap : 2,
+			 csi_max_rows_bfer : 2,
+			 comp_bfer_antennas : 2,
+			 noncomp_bfer_antennas : 2,
+			 csi_bfer_antennas : 2,
+			 minimal_grouping : 2,
+			 explicit_comp_bf : 2,
+			 explicit_noncomp_bf : 2,
+			 explicit_csi_feedback : 2,
+			 explicit_comp_steering : 1,
+			 explicit_noncomp_steering : 1,
+			 explicit_csi_txbf_capable : 1,
+			 calibration : 2,
+			 implicit_txbf_capable : 1,
+			 tx_ndp_capable : 1,
+			 rx_ndp_capable : 1,
+			 tx_staggered_sounding : 1,
+			 rx_staggered_sounding : 1, implicit_rx_capable : 1;
+#else
+		uint32_t implicit_rx_capable : 1,
+			 rx_staggered_sounding : 1,
+			 tx_staggered_sounding : 1,
+			 rx_ndp_capable : 1,
+			 tx_ndp_capable : 1,
+			 implicit_txbf_capable : 1,
+			 calibration : 2,
+			 explicit_csi_txbf_capable : 1,
+			 explicit_noncomp_steering : 1,
+			 explicit_comp_steering : 1,
+			 explicit_csi_feedback : 2,
+			 explicit_noncomp_bf : 2,
+			 explicit_comp_bf : 2,
+			 minimal_grouping : 2,
+			 csi_bfer_antennas : 2,
+			 noncomp_bfer_antennas : 2,
+			 comp_bfer_antennas : 2,
+			 csi_max_rows_bfer : 2, channel_estimation_cap : 2, reserved : 3;
+#endif
+	};
+
+	uint32_t value;
+} __packed;
+#endif
+
+struct ieee80211_ie_htcap_cmn {
+	uint16_t hc_cap;        /* HT capabilities */
+#if _BYTE_ORDER == _BIG_ENDIAN
+	uint8_t hc_reserved : 3,  /* B5-7 reserved */
+		hc_mpdudensity : 3, /* B2-4 MPDU density (aka Minimum MPDU Start Spacing) */
+		hc_maxampdu : 2; /* B0-1 maximum rx A-MPDU factor */
+#else
+	uint8_t hc_maxampdu : 2,  /* B0-1 maximum rx A-MPDU factor */
+		hc_mpdudensity : 3, /* B2-4 MPDU density (aka Minimum MPDU Start Spacing) */
+		hc_reserved : 3; /* B5-7 reserved */
+#endif
+	uint8_t hc_mcsset[16];  /* supported MCS set */
+	uint16_t hc_extcap;     /* extended HT capabilities */
+#ifdef ATH_SUPPORT_TxBF
+	union ieee80211_hc_txbf hc_txbf;        /* txbf capabilities */
+#else
+	uint32_t hc_txbf;       /* txbf capabilities */
+#endif
+	uint8_t hc_antenna;     /* antenna capabilities */
+} __packed;
+
+/*
+ * 802.11n HT Capability IE
+ */
+struct ieee80211_ie_htcap {
+	uint8_t hc_id;          /* element ID */
+	uint8_t hc_len;         /* length in bytes */
+	struct ieee80211_ie_htcap_cmn hc_ie;
+} __packed;
+
+/*
+ * Temporary vendor private HT Capability IE
+ */
+struct vendor_ie_htcap {
+	uint8_t hc_id;          /* element ID */
+	uint8_t hc_len;         /* length in bytes */
+	uint8_t hc_oui[3];
+	uint8_t hc_ouitype;
+	struct ieee80211_ie_htcap_cmn hc_ie;
+} __packed;
+
+/* HT capability flags */
+#define IEEE80211_HTCAP_C_ADVCODING             0x0001
+#define IEEE80211_HTCAP_C_CHWIDTH40             0x0002
+#define IEEE80211_HTCAP_C_SMPOWERSAVE_STATIC    0x0000  /* Capable of SM Power Save (Static) */
+#define IEEE80211_HTCAP_C_SMPOWERSAVE_DYNAMIC   0x0004  /* Capable of SM Power Save (Dynamic) */
+#define IEEE80211_HTCAP_C_SM_RESERVED           0x0008  /* Reserved */
+#define IEEE80211_HTCAP_C_SM_ENABLED            0x000c  /* SM enabled, no SM Power Save */
+#define IEEE80211_HTCAP_C_GREENFIELD            0x0010
+#define IEEE80211_HTCAP_C_SHORTGI20             0x0020
+#define IEEE80211_HTCAP_C_SHORTGI40             0x0040
+#define IEEE80211_HTCAP_C_TXSTBC                0x0080
+#define IEEE80211_HTCAP_C_TXSTBC_S                   7
+#define IEEE80211_HTCAP_C_RXSTBC                0x0300  /* 2 bits */
+#define IEEE80211_HTCAP_C_RXSTBC_S                   8
+#define IEEE80211_HTCAP_C_DELAYEDBLKACK         0x0400
+#define IEEE80211_HTCAP_C_MAXAMSDUSIZE          0x0800  /* 1 = 8K, 0 = 3839B */
+#define IEEE80211_HTCAP_C_DSSSCCK40             0x1000
+#define IEEE80211_HTCAP_C_PSMP                  0x2000
+#define IEEE80211_HTCAP_C_INTOLERANT40          0x4000
+#define IEEE80211_HTCAP_C_LSIGTXOPPROT          0x8000
+
+#define IEEE80211_HTCAP_C_SM_MASK               0x000c  /* Spatial Multiplexing (SM) capabitlity bitmask */
+
+/* B0-1 maximum rx A-MPDU factor 2^(13+Max Rx A-MPDU Factor) */
+enum {
+	IEEE80211_HTCAP_MAXRXAMPDU_8192,        /* 2 ^ 13 */
+	IEEE80211_HTCAP_MAXRXAMPDU_16384,       /* 2 ^ 14 */
+	IEEE80211_HTCAP_MAXRXAMPDU_32768,       /* 2 ^ 15 */
+	IEEE80211_HTCAP_MAXRXAMPDU_65536,       /* 2 ^ 16 */
+};
+#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR   13
+
+/* B2-4 MPDU density (usec) */
+enum {
+	IEEE80211_HTCAP_MPDUDENSITY_NA, /* No time restriction */
+	IEEE80211_HTCAP_MPDUDENSITY_0_25,       /* 1/4 usec */
+	IEEE80211_HTCAP_MPDUDENSITY_0_5,        /* 1/2 usec */
+	IEEE80211_HTCAP_MPDUDENSITY_1,  /* 1 usec */
+	IEEE80211_HTCAP_MPDUDENSITY_2,  /* 2 usec */
+	IEEE80211_HTCAP_MPDUDENSITY_4,  /* 4 usec */
+	IEEE80211_HTCAP_MPDUDENSITY_8,  /* 8 usec */
+	IEEE80211_HTCAP_MPDUDENSITY_16, /* 16 usec */
+};
+
+/* HT extended capability flags */
+#define IEEE80211_HTCAP_EXTC_PCO                0x0001
+#define IEEE80211_HTCAP_EXTC_TRANS_TIME_RSVD    0x0000
+#define IEEE80211_HTCAP_EXTC_TRANS_TIME_400     0x0002  /* 20-40 switch time */
+#define IEEE80211_HTCAP_EXTC_TRANS_TIME_1500    0x0004  /* in us             */
+#define IEEE80211_HTCAP_EXTC_TRANS_TIME_5000    0x0006
+#define IEEE80211_HTCAP_EXTC_RSVD_1             0x00f8
+#define IEEE80211_HTCAP_EXTC_MCS_FEEDBACK_NONE  0x0000
+#define IEEE80211_HTCAP_EXTC_MCS_FEEDBACK_RSVD  0x0100
+#define IEEE80211_HTCAP_EXTC_MCS_FEEDBACK_UNSOL 0x0200
+#define IEEE80211_HTCAP_EXTC_MCS_FEEDBACK_FULL  0x0300
+#define IEEE80211_HTCAP_EXTC_RSVD_2             0xfc00
+#ifdef ATH_SUPPORT_TxBF
+#define IEEE80211_HTCAP_EXTC_HTC_SUPPORT        0x0400
+#endif
+
+struct ieee80211_ie_htinfo_cmn {
+	uint8_t hi_ctrlchannel; /* control channel */
+#if _BYTE_ORDER == _BIG_ENDIAN
+	uint8_t hi_serviceinterval : 3,   /* B5-7 svc interval granularity */
+		hi_ctrlaccess : 1, /* B4   controlled access only */
+		hi_rifsmode : 1, /* B3   rifs mode */
+		hi_txchwidth : 1, /* B2   recommended xmiss width set */
+		hi_extchoff : 2; /* B0-1 extension channel offset */
+
+/*
+
+ * The following 2 consecutive bytes are defined in word in 80211n spec.
+
+ * Some processors store MSB byte into lower memory address which causes wrong
+
+ * wrong byte sequence in beacon. Thus we break into byte definition which should
+
+ * avoid the problem for all processors
+
+ */
+
+	uint8_t hi_reserved3 : 3, /* B5-7 reserved */
+		hi_obssnonhtpresent : 1, /* B4   OBSS non-HT STA present */
+		hi_txburstlimit : 1, /* B3   transmit burst limit */
+		hi_nongfpresent : 1, /* B2   non greenfield devices present */
+		hi_opmode : 2;  /* B0-1 operating mode */
+
+	uint8_t hi_reserved0;   /* B0-7 (B8-15 in 11n) reserved */
+
+/* The following 2 consecutive bytes are defined in word in 80211n spec. */
+
+	uint8_t hi_dualctsprot : 1,       /* B7   dual CTS protection */
+		hi_dualbeacon : 1, /* B6   dual beacon */
+		hi_reserved2 : 6; /* B0-5 reserved */
+	uint8_t hi_reserved1 : 4, /* B4-7 (B12-15 in 11n) reserved */
+		hi_pcophase : 1, /* B3   (B11 in 11n)  pco phase */
+		hi_pcoactive : 1, /* B2   (B10 in 11n)  pco active */
+		hi_lsigtxopprot : 1, /* B1   (B9 in 11n)   l-sig txop protection full support */
+		hi_stbcbeacon : 1; /* B0   (B8 in 11n)   STBC beacon */
+#else
+	uint8_t hi_extchoff : 2,  /* B0-1 extension channel offset */
+		hi_txchwidth : 1, /* B2   recommended xmiss width set */
+		hi_rifsmode : 1, /* B3   rifs mode */
+		hi_ctrlaccess : 1, /* B4   controlled access only */
+		hi_serviceinterval : 3; /* B5-7 svc interval granularity */
+	uint16_t hi_opmode : 2,   /* B0-1 operating mode */
+		 hi_nongfpresent : 1, /* B2   non greenfield devices present */
+		 hi_txburstlimit : 1, /* B3   transmit burst limit */
+		 hi_obssnonhtpresent : 1, /* B4   OBSS non-HT STA present */
+		 hi_reserved0 : 11; /* B5-15 reserved */
+	uint16_t hi_reserved2 : 6,        /* B0-5 reserved */
+		 hi_dualbeacon : 1, /* B6   dual beacon */
+		 hi_dualctsprot : 1, /* B7   dual CTS protection */
+		 hi_stbcbeacon : 1, /* B8   STBC beacon */
+		 hi_lsigtxopprot : 1, /* B9   l-sig txop protection full support */
+		 hi_pcoactive : 1, /* B10  pco active */
+		 hi_pcophase : 1, /* B11  pco phase */
+		 hi_reserved1 : 4; /* B12-15 reserved */
+#endif
+	uint8_t hi_basicmcsset[16];     /* basic MCS set */
+} __packed;
+
+/*
+ * 802.11n HT Information IE
+ */
+struct ieee80211_ie_htinfo {
+	uint8_t hi_id;          /* element ID */
+	uint8_t hi_len;         /* length in bytes */
+	struct ieee80211_ie_htinfo_cmn hi_ie;
+} __packed;
+
+/*
+ * Temporary vendor private HT Information IE
+ */
+struct vendor_ie_htinfo {
+	uint8_t hi_id;          /* element ID */
+	uint8_t hi_len;         /* length in bytes */
+	uint8_t hi_oui[3];
+	uint8_t hi_ouitype;
+	struct ieee80211_ie_htinfo_cmn hi_ie;
+} __packed;
+
+/* extension channel offset (2 bit signed number) */
+enum {
+	IEEE80211_HTINFO_EXTOFFSET_NA = 0,      /* 0  no extension channel is present */
+	IEEE80211_HTINFO_EXTOFFSET_ABOVE = 1,   /* +1 extension channel above control channel */
+	IEEE80211_HTINFO_EXTOFFSET_UNDEF = 2,   /* -2 undefined */
+	IEEE80211_HTINFO_EXTOFFSET_BELOW = 3    /* -1 extension channel below control channel */
+};
+
+/* recommended transmission width set */
+enum {
+	IEEE80211_HTINFO_TXWIDTH_20,
+	IEEE80211_HTINFO_TXWIDTH_2040
+};
+
+/* operating flags */
+#define IEEE80211_HTINFO_OPMODE_PURE                0x00        /* no protection */
+#define IEEE80211_HTINFO_OPMODE_MIXED_PROT_OPT      0x01        /* prot optional (legacy device maybe present) */
+#define IEEE80211_HTINFO_OPMODE_MIXED_PROT_40       0x02        /* prot required (20 MHz) */
+#define IEEE80211_HTINFO_OPMODE_MIXED_PROT_ALL      0x03        /* prot required (legacy devices present) */
+#define IEEE80211_HTINFO_OPMODE_NON_GF_PRESENT      0x04        /* non-greenfield devices present */
+
+#define IEEE80211_HTINFO_OPMODE_MASK                0x03        /* For protection 0x00-0x03 */
+
+/* Non-greenfield STAs present */
+enum {
+	IEEE80211_HTINFO_NON_GF_NOT_PRESENT,    /* Non-greenfield STAs not present */
+	IEEE80211_HTINFO_NON_GF_PRESENT,        /* Non-greenfield STAs present */
+};
+
+/* Transmit Burst Limit */
+enum {
+	IEEE80211_HTINFO_TXBURST_UNLIMITED,     /* Transmit Burst is unlimited */
+	IEEE80211_HTINFO_TXBURST_LIMITED,       /* Transmit Burst is limited */
+};
+
+/* OBSS Non-HT STAs present */
+enum {
+	IEEE80211_HTINFO_OBSS_NONHT_NOT_PRESENT,        /* OBSS Non-HT STAs not present */
+	IEEE80211_HTINFO_OBSS_NONHT_PRESENT,    /* OBSS Non-HT STAs present */
+};
+
+/* misc flags */
+#define IEEE80211_HTINFO_DUALBEACON               0x0040        /* B6   dual beacon */
+#define IEEE80211_HTINFO_DUALCTSPROT              0x0080        /* B7   dual stbc protection */
+#define IEEE80211_HTINFO_STBCBEACON               0x0100        /* B8   secondary beacon */
+#define IEEE80211_HTINFO_LSIGTXOPPROT             0x0200        /* B9   lsig txop prot full support */
+#define IEEE80211_HTINFO_PCOACTIVE                0x0400        /* B10  pco active */
+#define IEEE80211_HTINFO_PCOPHASE                 0x0800        /* B11  pco phase */
+
+/* Secondary Channel offset for for 40MHz direct link */
+#define IEEE80211_SECONDARY_CHANNEL_ABOVE         1
+#define IEEE80211_SECONDARY_CHANNEL_BELOW         3
+
+#define IEEE80211_TDLS_CHAN_SX_PROHIBIT         0x00000002      /* bit-2 TDLS Channel Switch Prohibit */
+
+/* RIFS mode */
+enum {
+	IEEE80211_HTINFO_RIFSMODE_PROHIBITED,   /* use of rifs prohibited */
+	IEEE80211_HTINFO_RIFSMODE_ALLOWED,      /* use of rifs permitted */
+};
+
+/*
+ * Management information element payloads.
+ */
+enum {
+	IEEE80211_ELEMID_SSID = 0,
+	IEEE80211_ELEMID_RATES = 1,
+	IEEE80211_ELEMID_FHPARMS = 2,
+	IEEE80211_ELEMID_DSPARMS = 3,
+	IEEE80211_ELEMID_CFPARMS = 4,
+	IEEE80211_ELEMID_TIM = 5,
+	IEEE80211_ELEMID_IBSSPARMS = 6,
+	IEEE80211_ELEMID_COUNTRY = 7,
+	IEEE80211_ELEMID_REQINFO = 10,
+	IEEE80211_ELEMID_QBSS_LOAD = 11,
+	IEEE80211_ELEMID_TCLAS = 14,
+	IEEE80211_ELEMID_CHALLENGE = 16,
+	/* 17-31 reserved for challenge text extension */
+	IEEE80211_ELEMID_PWRCNSTR = 32,
+	IEEE80211_ELEMID_PWRCAP = 33,
+	IEEE80211_ELEMID_TPCREQ = 34,
+	IEEE80211_ELEMID_TPCREP = 35,
+	IEEE80211_ELEMID_SUPPCHAN = 36,
+	IEEE80211_ELEMID_CHANSWITCHANN = 37,
+	IEEE80211_ELEMID_MEASREQ = 38,
+	IEEE80211_ELEMID_MEASREP = 39,
+	IEEE80211_ELEMID_QUIET = 40,
+	IEEE80211_ELEMID_IBSSDFS = 41,
+	IEEE80211_ELEMID_ERP = 42,
+	IEEE80211_ELEMID_TCLAS_PROCESS = 44,
+	IEEE80211_ELEMID_HTCAP_ANA = 45,
+	IEEE80211_ELEMID_RESERVED_47 = 47,
+	IEEE80211_ELEMID_RSN = 48,
+	IEEE80211_ELEMID_XRATES = 50,
+	IEEE80211_ELEMID_HTCAP = 51,
+	IEEE80211_ELEMID_HTINFO = 52,
+	IEEE80211_ELEMID_MOBILITY_DOMAIN = 54,
+	IEEE80211_ELEMID_FT = 55,
+	IEEE80211_ELEMID_TIMEOUT_INTERVAL = 56,
+	IEEE80211_ELEMID_EXTCHANSWITCHANN = 60,
+	IEEE80211_ELEMID_HTINFO_ANA = 61,
+	IEEE80211_ELEMID_SECCHANOFFSET = 62,
+	IEEE80211_ELEMID_WAPI = 68,     /*IE for WAPI */
+	IEEE80211_ELEMID_TIME_ADVERTISEMENT = 69,
+	IEEE80211_ELEMID_RRM = 70,      /* Radio resource measurement */
+	IEEE80211_ELEMID_2040_COEXT = 72,
+	IEEE80211_ELEMID_2040_INTOL = 73,
+	IEEE80211_ELEMID_OBSS_SCAN = 74,
+	IEEE80211_ELEMID_MMIE = 76,     /* 802.11w Management MIC IE */
+	IEEE80211_ELEMID_FMS_DESCRIPTOR = 86,   /* 802.11v FMS descriptor IE */
+	IEEE80211_ELEMID_FMS_REQUEST = 87,      /* 802.11v FMS request IE */
+	IEEE80211_ELEMID_FMS_RESPONSE = 88,     /* 802.11v FMS response IE */
+	IEEE80211_ELEMID_BSSMAX_IDLE_PERIOD = 90,       /* BSS MAX IDLE PERIOD */
+	IEEE80211_ELEMID_TFS_REQUEST = 91,
+	IEEE80211_ELEMID_TFS_RESPONSE = 92,
+	IEEE80211_ELEMID_TIM_BCAST_REQUEST = 94,
+	IEEE80211_ELEMID_TIM_BCAST_RESPONSE = 95,
+	IEEE80211_ELEMID_INTERWORKING = 107,
+	IEEE80211_ELEMID_XCAPS = 127,
+	IEEE80211_ELEMID_RESERVED_133 = 133,
+	IEEE80211_ELEMID_TPC = 150,
+	IEEE80211_ELEMID_CCKM = 156,
+	IEEE80211_ELEMID_VHTCAP = 191,  /* VHT Capabilities */
+	IEEE80211_ELEMID_VHTOP = 192,   /* VHT Operation */
+	IEEE80211_ELEMID_EXT_BSS_LOAD = 193,    /* Extended BSS Load */
+	IEEE80211_ELEMID_WIDE_BAND_CHAN_SWITCH = 194,   /* Wide Band Channel Switch */
+	IEEE80211_ELEMID_VHT_TX_PWR_ENVLP = 195,        /* VHT Transmit Power Envelope */
+	IEEE80211_ELEMID_CHAN_SWITCH_WRAP = 196,        /* Channel Switch Wrapper */
+	IEEE80211_ELEMID_AID = 197,     /* AID */
+	IEEE80211_ELEMID_QUIET_CHANNEL = 198,   /* Quiet Channel */
+	IEEE80211_ELEMID_OP_MODE_NOTIFY = 199,  /* Operating Mode Notification */
+	IEEE80211_ELEMID_VENDOR = 221,  /* vendor private */
+};
+
+#define IEEE80211_MAX_IE_LEN                255
+#define IEEE80211_RSN_IE_LEN                22
+
+#define IEEE80211_CHANSWITCHANN_BYTES        5
+#define IEEE80211_EXTCHANSWITCHANN_BYTES     6
+
+/* TODO -> Need to Check Redefinition Error used in only UMAC */
+#if 0
+struct ieee80211_tim_ie {
+	uint8_t tim_ie;         /* IEEE80211_ELEMID_TIM */
+	uint8_t tim_len;
+	uint8_t tim_count;      /* DTIM count */
+	uint8_t tim_period;     /* DTIM period */
+	uint8_t tim_bitctl;     /* bitmap control */
+	uint8_t tim_bitmap[1];  /* variable-length bitmap */
+} __packed;
+#endif
+
+/* Country IE channel triplet */
+struct country_ie_triplet {
+	union {
+		uint8_t schan;  /* starting channel */
+		uint8_t regextid;       /* Regulatory Extension Identifier */
+	};
+	union {
+		uint8_t nchan;  /* number of channels */
+		uint8_t regclass;       /* Regulatory Class */
+	};
+	union {
+		uint8_t maxtxpwr;       /* tx power  */
+		uint8_t coverageclass;  /* Coverage Class */
+	};
+} __packed;
+
+struct ieee80211_country_ie {
+	uint8_t ie;             /* IEEE80211_ELEMID_COUNTRY */
+	uint8_t len;
+	uint8_t cc[3];          /* ISO CC+(I)ndoor/(O)utdoor */
+	struct country_ie_triplet triplet[1];
+} __packed;
+
+struct ieee80211_fh_ie {
+	uint8_t ie;             /* IEEE80211_ELEMID_FHPARMS */
+	uint8_t len;
+	uint16_t dwell_time;    /* endianness?? */
+	uint8_t hop_set;
+	uint8_t hop_pattern;
+	uint8_t hop_index;
+} __packed;
+
+struct ieee80211_ds_ie {
+	uint8_t ie;             /* IEEE80211_ELEMID_DSPARMS */
+	uint8_t len;
+	uint8_t current_channel;
+} __packed;
+
+struct ieee80211_erp_ie {
+	uint8_t ie;             /* IEEE80211_ELEMID_ERP */
+	uint8_t len;
+	uint8_t value;
+} __packed;
+
+/* TODO -> Need to Check Redefinition Error used in only UMAC */
+#if 0
+struct ieee80211_quiet_ie {
+	uint8_t ie;             /* IEEE80211_ELEMID_QUIET */
+	uint8_t len;
+	uint8_t tbttcount;      /* quiet start */
+	uint8_t period;         /* beacon intervals between quiets */
+	uint16_t duration;      /* TUs of each quiet */
+	uint16_t offset;        /* TUs of from TBTT of quiet start */
+} __packed;
+#endif
+
+struct ieee80211_channelswitch_ie {
+	uint8_t ie;             /* IEEE80211_ELEMID_CHANSWITCHANN */
+	uint8_t len;
+	uint8_t switchmode;
+	uint8_t newchannel;
+	uint8_t tbttcount;
+} __packed;
+
+/* channel switch action frame format definition */
+struct ieee80211_action_spectrum_channel_switch {
+	struct ieee80211_action csa_header;
+	struct ieee80211_channelswitch_ie csa_element;
+} __packed;
+
+struct ieee80211_extendedchannelswitch_ie {
+	uint8_t ie;             /* IEEE80211_ELEMID_EXTCHANSWITCHANN */
+	uint8_t len;
+	uint8_t switchmode;
+	uint8_t newClass;
+	uint8_t newchannel;
+	uint8_t tbttcount;
+} __packed;
+
+struct ieee80211_tpc_ie {
+	uint8_t ie;
+	uint8_t len;
+	uint8_t pwrlimit;
+} __packed;
+
+/*
+ * MHDRIE included in TKIP MFP protected management frames
+ */
+struct ieee80211_ese_mhdr_ie {
+	uint8_t mhdr_id;
+	uint8_t mhdr_len;
+	uint8_t mhdr_oui[3];
+	uint8_t mhdr_oui_type;
+	uint8_t mhdr_fc[2];
+	uint8_t mhdr_bssid[IEEE80211_ADDR_LEN];
+} __packed;
+
+/*
+ * SSID IE
+ */
+struct ieee80211_ie_ssid {
+	uint8_t ssid_id;
+	uint8_t ssid_len;
+	uint8_t ssid[32];
+} __packed;
+
+/*
+ * Supported rates
+ */
+#define IEEE80211_MAX_SUPPORTED_RATES      8
+
+struct ieee80211_ie_rates {
+	uint8_t rate_id;        /* Element Id */
+	uint8_t rate_len;       /* IE Length */
+	uint8_t rate[IEEE80211_MAX_SUPPORTED_RATES];    /* IE Length */
+} __packed;
+
+/*
+ * Extended rates
+ */
+#define IEEE80211_MAX_EXTENDED_RATES     256
+
+struct ieee80211_ie_xrates {
+	uint8_t xrate_id;       /* Element Id */
+	uint8_t xrate_len;      /* IE Length */
+	uint8_t xrate[IEEE80211_MAX_EXTENDED_RATES];    /* IE Length */
+} __packed;
+
+/*
+ * WPS SSID list information element (maximally sized).
+ */
+struct ieee80211_ie_ssidl {
+	uint8_t ssidl_id;       /* IEEE80211_ELEMID_VENDOR */
+	uint8_t ssidl_len;      /* length in bytes */
+	uint8_t ssidl_oui[3];   /* 0x00, 0x50, 0xf2 */
+	uint8_t ssidl_type;     /* OUI type */
+	uint8_t ssidl_prim_cap; /* Primary capabilities */
+	uint8_t ssidl_count;    /* # of secondary SSIDs */
+	uint16_t ssidl_value[248];
+} __packed;
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+struct ieee80211_sec_ssid_cap {
+	uint32_t reserved0 : 1,
+		 akmlist : 6, reserved1 : 4, reeserved2 : 2, ucipher : 15, mcipher : 4;
+};
+#else
+struct ieee80211_sec_ssid_cap {
+	uint32_t mcipher : 4,
+		 ucipher : 15, reserved2 : 2, reserved1 : 4, akmlist : 6, reserved0 : 1;
+};
+#endif
+
+struct ieee80211_ie_qbssload {
+	uint8_t elem_id;        /* IEEE80211_ELEMID_QBSS_LOAD */
+	uint8_t length;         /* length in bytes */
+	uint16_t station_count; /* number of station associated */
+	uint8_t channel_utilization;    /* channel busy time in 0-255 scale */
+	uint16_t aac;           /* available admission capacity */
+} __packed;
+
+#define SEC_SSID_HEADER_LEN  6
+#define SSIDL_IE_HEADER_LEN  6
+
+struct ieee80211_sec_ssid {
+	uint8_t sec_ext_cap;
+	struct ieee80211_sec_ssid_cap sec_cap;
+	uint8_t sec_ssid_len;
+	uint8_t sec_ssid[32];
+} __packed;
+
+/* Definitions of SSIDL IE */
+enum {
+	CAP_MCIPHER_ENUM_NONE = 0,
+	CAP_MCIPHER_ENUM_WEP40,
+	CAP_MCIPHER_ENUM_WEP104,
+	CAP_MCIPHER_ENUM_TKIP,
+	CAP_MCIPHER_ENUM_CCMP,
+	CAP_MCIPHER_ENUM_CKIP_CMIC,
+	CAP_MCIPHER_ENUM_CKIP,
+	CAP_MCIPHER_ENUM_CMIC
+};
+
+#define CAP_UCIPHER_BIT_NONE           0x0001
+#define CAP_UCIPHER_BIT_WEP40          0x0002
+#define CAP_UCIPHER_BIT_WEP104         0x0004
+#define CAP_UCIPHER_BIT_TKIP           0x0008
+#define CAP_UCIPHER_BIT_CCMP           0x0010
+#define CAP_UCIPHER_BIT_CKIP_CMIC      0x0020
+#define CAP_UCIPHER_BIT_CKIP           0x0040
+#define CAP_UCIPHER_BIT_CMIC           0x0080
+#define CAP_UCIPHER_BIT_WPA2_WEP40     0x0100
+#define CAP_UCIPHER_BIT_WPA2_WEP104    0x0200
+#define CAP_UCIPHER_BIT_WPA2_TKIP      0x0400
+#define CAP_UCIPHER_BIT_WPA2_CCMP      0x0800
+#define CAP_UCIPHER_BIT_WPA2_CKIP_CMIC 0x1000
+#define CAP_UCIPHER_BIT_WPA2_CKIP      0x2000
+#define CAP_UCIPHER_BIT_WPA2_CMIC      0x4000
+
+#define CAP_AKM_BIT_WPA1_1X            0x01
+#define CAP_AKM_BIT_WPA1_PSK           0x02
+#define CAP_AKM_BIT_WPA2_1X            0x04
+#define CAP_AKM_BIT_WPA2_PSK           0x08
+#define CAP_AKM_BIT_WPA1_CCKM          0x10
+#define CAP_AKM_BIT_WPA2_CCKM          0x20
+
+#define IEEE80211_CHALLENGE_LEN         128
+
+#define IEEE80211_SUPPCHAN_LEN          26
+
+#define IEEE80211_RATE_BASIC            0x80
+#define IEEE80211_RATE_VAL              0x7f
+
+/* EPR information element flags */
+#define IEEE80211_ERP_NON_ERP_PRESENT   0x01
+#define IEEE80211_ERP_USE_PROTECTION    0x02
+#define IEEE80211_ERP_LONG_PREAMBLE     0x04
+
+/* Atheros private advanced capabilities info */
+#define ATHEROS_CAP_TURBO_PRIME         0x01
+#define ATHEROS_CAP_COMPRESSION         0x02
+#define ATHEROS_CAP_FAST_FRAME          0x04
+/* bits 3-6 reserved */
+#define ATHEROS_CAP_BOOST               0x80
+
+#define ATH_OUI                     0x7f0300    /* Atheros OUI */
+#define ATH_OUI_TYPE                    0x01
+#define ATH_OUI_SUBTYPE                 0x01
+#define ATH_OUI_VERSION                 0x00
+#define ATH_OUI_TYPE_XR                 0x03
+#define ATH_OUI_VER_XR                  0x01
+#define ATH_OUI_EXTCAP_TYPE             0x04    /* Atheros Extended Cap Type */
+#define ATH_OUI_EXTCAP_SUBTYPE          0x01    /* Atheros Extended Cap Sub-type */
+#define ATH_OUI_EXTCAP_VERSION          0x00    /* Atheros Extended Cap Version */
+
+#define WPA_OUI                     0xf25000
+#define WPA_VERSION                        1    /* current supported version */
+#define CSCO_OUI                    0x964000    /* Cisco OUI */
+#define AOW_OUI                     0x4a0100    /* AoW OUI, workaround */
+#define AOW_OUI_TYPE                    0x01
+#define AOW_OUI_VERSION                 0x01
+
+#define WSC_OUI                   0x0050f204
+
+#define WPA_CSE_NULL                    0x00
+#define WPA_CSE_WEP40                   0x01
+#define WPA_CSE_TKIP                    0x02
+#define WPA_CSE_CCMP                    0x04
+#define WPA_CSE_WEP104                  0x05
+
+#define WPA_ASE_NONE                    0x00
+#define WPA_ASE_8021X_UNSPEC            0x01
+#define WPA_ASE_8021X_PSK               0x02
+#define WPA_ASE_FT_IEEE8021X            0x20
+#define WPA_ASE_FT_PSK                  0x40
+#define WPA_ASE_SHA256_IEEE8021X        0x80
+#define WPA_ASE_SHA256_PSK              0x100
+#define WPA_ASE_WPS                     0x200
+
+#define RSN_OUI                     0xac0f00
+#define RSN_VERSION                        1    /* current supported version */
+
+#define RSN_CSE_NULL                    0x00
+#define RSN_CSE_WEP40                   0x01
+#define RSN_CSE_TKIP                    0x02
+#define RSN_CSE_WRAP                    0x03
+#define RSN_CSE_CCMP                    0x04
+#define RSN_CSE_WEP104                  0x05
+#define RSN_CSE_AES_CMAC                0x06
+
+#define RSN_ASE_NONE                    0x00
+#define RSN_ASE_8021X_UNSPEC            0x01
+#define RSN_ASE_8021X_PSK               0x02
+#define RSN_ASE_FT_IEEE8021X            0x20
+#define RSN_ASE_FT_PSK                  0x40
+#define RSN_ASE_SHA256_IEEE8021X        0x80
+#define RSN_ASE_SHA256_PSK              0x100
+#define RSN_ASE_WPS                     0x200
+
+#define AKM_SUITE_TYPE_IEEE8021X        0x01
+#define AKM_SUITE_TYPE_PSK              0x02
+#define AKM_SUITE_TYPE_FT_IEEE8021X     0x03
+#define AKM_SUITE_TYPE_FT_PSK           0x04
+#define AKM_SUITE_TYPE_SHA256_IEEE8021X 0x05
+#define AKM_SUITE_TYPE_SHA256_PSK       0x06
+
+#define RSN_CAP_PREAUTH                 0x01
+#define RSN_CAP_PTKSA_REPLAYCOUNTER    0x0c
+#define RSN_CAP_GTKSA_REPLAYCOUNTER    0x30
+#define RSN_CAP_MFP_REQUIRED            0x40
+#define RSN_CAP_MFP_ENABLED             0x80
+
+#define CCKM_OUI                    0x964000
+#define CCKM_ASE_UNSPEC                    0
+#define WPA_CCKM_AKM              0x00964000
+#define RSN_CCKM_AKM              0x00964000
+
+#define WME_OUI                     0xf25000
+#define WME_OUI_TYPE                    0x02
+#define WME_INFO_OUI_SUBTYPE            0x00
+#define WME_PARAM_OUI_SUBTYPE           0x01
+#define WME_TSPEC_OUI_SUBTYPE           0x02
+
+#define WME_PARAM_OUI_VERSION              1
+#define WME_TSPEC_OUI_VERSION              1
+#define WME_VERSION                        1
+
+/* WME stream classes */
+#define WME_AC_BE                          0    /* best effort */
+#define WME_AC_BK                          1    /* background */
+#define WME_AC_VI                          2    /* video */
+#define WME_AC_VO                          3    /* voice */
+
+/* WCN IE */
+#define WCN_OUI                     0xf25000    /* Microsoft OUI */
+#define WCN_OUI_TYPE                    0x04    /* WCN */
+
+/* Atheros htoui  for ht vender ie; use Epigram OUI for compatibility with pre11n devices */
+#define ATH_HTOUI                   0x00904c
+
+#define SFA_OUI                     0x964000
+#define SFA_OUI_TYPE                    0x14
+#define SFA_IE_CAP_MFP                  0x01
+#define SFA_IE_CAP_DIAG_CHANNEL         0x02
+#define SFA_IE_CAP_LOCATION_SVCS        0x04
+#define SFA_IE_CAP_EXP_BANDWIDTH        0x08
+
+#define WPA_OUI_BYTES       0x00, 0x50, 0xf2
+#define RSN_OUI_BYTES       0x00, 0x0f, 0xac
+#define WME_OUI_BYTES       0x00, 0x50, 0xf2
+#define ATH_OUI_BYTES       0x00, 0x03, 0x7f
+#define SFA_OUI_BYTES       0x00, 0x40, 0x96
+#define CCKM_OUI_BYTES      0x00, 0x40, 0x96
+#define WPA_SEL(x)          (((x)<<24)|WPA_OUI)
+#define RSN_SEL(x)          (((x)<<24)|RSN_OUI)
+#define SFA_SEL(x)          (((x)<<24)|SFA_OUI)
+#define CCKM_SEL(x)         (((x)<<24)|CCKM_OUI)
+
+#define IEEE80211_RV(v)     ((v) & IEEE80211_RATE_VAL)
+
+/*
+ * AUTH management packets
+ *
+ *  octet algo[2]
+ *  octet seq[2]
+ *  octet status[2]
+ *  octet chal.id
+ *  octet chal.length
+ *  octet chal.text[253]
+ */
+
+typedef uint8_t *ieee80211_mgt_auth_t;
+
+#define IEEE80211_AUTH_ALGORITHM(auth) \
+	((auth)[0] | ((auth)[1] << 8))
+#define IEEE80211_AUTH_TRANSACTION(auth) \
+	((auth)[2] | ((auth)[3] << 8))
+#define IEEE80211_AUTH_STATUS(auth) \
+	((auth)[4] | ((auth)[5] << 8))
+
+#define IEEE80211_AUTH_ALG_OPEN     0x0000
+#define IEEE80211_AUTH_ALG_SHARED   0x0001
+#define IEEE80211_AUTH_ALG_FT       0x0002
+#define IEEE80211_AUTH_ALG_LEAP     0x0080
+
+enum {
+	IEEE80211_AUTH_OPEN_REQUEST = 1,
+	IEEE80211_AUTH_OPEN_RESPONSE = 2,
+};
+
+enum {
+	IEEE80211_AUTH_SHARED_REQUEST = 1,
+	IEEE80211_AUTH_SHARED_CHALLENGE = 2,
+	IEEE80211_AUTH_SHARED_RESPONSE = 3,
+	IEEE80211_AUTH_SHARED_PASS = 4,
+};
+
+/*
+ * Reason codes
+ *
+ * Unlisted codes are reserved
+ */
+
+enum {
+	IEEE80211_REASON_UNSPECIFIED = 1,
+	IEEE80211_REASON_AUTH_EXPIRE = 2,
+	IEEE80211_REASON_AUTH_LEAVE = 3,
+	IEEE80211_REASON_ASSOC_EXPIRE = 4,
+	IEEE80211_REASON_ASSOC_TOOMANY = 5,
+	IEEE80211_REASON_NOT_AUTHED = 6,
+	IEEE80211_REASON_NOT_ASSOCED = 7,
+	IEEE80211_REASON_ASSOC_LEAVE = 8,
+	IEEE80211_REASON_ASSOC_NOT_AUTHED = 9,
+
+	IEEE80211_REASON_RSN_REQUIRED = 11,
+	IEEE80211_REASON_RSN_INCONSISTENT = 12,
+	IEEE80211_REASON_IE_INVALID = 13,
+	IEEE80211_REASON_MIC_FAILURE = 14,
+
+	IEEE80211_REASON_QOS = 32,
+	IEEE80211_REASON_QOS_BANDWITDH = 33,
+	IEEE80211_REASON_QOS_CH_CONDITIONS = 34,
+	IEEE80211_REASON_QOS_TXOP = 35,
+	IEEE80211_REASON_QOS_LEAVE = 36,
+	IEEE80211_REASON_QOS_DECLINED = 37,
+	IEEE80211_REASON_QOS_SETUP_REQUIRED = 38,
+	IEEE80211_REASON_QOS_TIMEOUT = 39,
+	IEEE80211_REASON_QOS_CIPHER = 45,
+
+	IEEE80211_STATUS_SUCCESS = 0,
+	IEEE80211_STATUS_UNSPECIFIED = 1,
+	IEEE80211_STATUS_CAPINFO = 10,
+	IEEE80211_STATUS_NOT_ASSOCED = 11,
+	IEEE80211_STATUS_OTHER = 12,
+	IEEE80211_STATUS_ALG = 13,
+	IEEE80211_STATUS_SEQUENCE = 14,
+	IEEE80211_STATUS_CHALLENGE = 15,
+	IEEE80211_STATUS_TIMEOUT = 16,
+	IEEE80211_STATUS_TOOMANY = 17,
+	IEEE80211_STATUS_BASIC_RATE = 18,
+	IEEE80211_STATUS_SP_REQUIRED = 19,
+	IEEE80211_STATUS_PBCC_REQUIRED = 20,
+	IEEE80211_STATUS_CA_REQUIRED = 21,
+	IEEE80211_STATUS_TOO_MANY_STATIONS = 22,
+	IEEE80211_STATUS_RATES = 23,
+	IEEE80211_STATUS_SHORTSLOT_REQUIRED = 25,
+	IEEE80211_STATUS_DSSSOFDM_REQUIRED = 26,
+	IEEE80211_STATUS_NO_HT = 27,
+	IEEE80211_STATUS_REJECT_TEMP = 30,
+	IEEE80211_STATUS_MFP_VIOLATION = 31,
+	IEEE80211_STATUS_REFUSED = 37,
+	IEEE80211_STATUS_INVALID_PARAM = 38,
+
+	IEEE80211_STATUS_DLS_NOT_ALLOWED = 48,
+};
+
+/* private IEEE80211_STATUS */
+#define    IEEE80211_STATUS_CANCEL             -1
+#define    IEEE80211_STATUS_INVALID_IE         -2
+#define    IEEE80211_STATUS_INVALID_CHANNEL    -3
+
+#define IEEE80211_WEP_KEYLEN        5   /* 40bit */
+#define IEEE80211_WEP_IVLEN         3   /* 24bit */
+#define IEEE80211_WEP_KIDLEN        1   /* 1 octet */
+#define IEEE80211_WEP_CRCLEN        4   /* CRC-32 */
+#define IEEE80211_WEP_NKID          4   /* number of key ids */
+
+/*
+ * 802.11i defines an extended IV for use with non-WEP ciphers.
+ * When the EXTIV bit is set in the key id byte an additional
+ * 4 bytes immediately follow the IV for TKIP.  For CCMP the
+ * EXTIV bit is likewise set but the 8 bytes represent the
+ * CCMP header rather than IV+extended-IV.
+ */
+#define IEEE80211_WEP_EXTIV      0x20
+#define IEEE80211_WEP_EXTIVLEN      4   /* extended IV length */
+#define IEEE80211_WEP_MICLEN        8   /* trailing MIC */
+
+#define IEEE80211_CCMP_HEADERLEN    8
+#define IEEE80211_CCMP_MICLEN       8
+#define WLAN_IEEE80211_GCMP_HEADERLEN    8
+#define WLAN_IEEE80211_GCMP_MICLEN      16
+
+/*
+ * 802.11w defines a MMIE chunk to be attached at the end of
+ * any outgoing broadcast or multicast robust management frame.
+ * MMIE field is total 18 bytes in size. Following the diagram of MMIE
+ *
+ *        <------------ 18 Bytes MMIE ----------------------->
+ *        +--------+---------+---------+-----------+---------+
+ *        |Element | Length  | Key id  |   IPN     |  MIC    |
+ *        |  id    |         |         |           |         |
+ *        +--------+---------+---------+-----------+---------+
+ * bytes      1         1         2         6            8
+ *
+ */
+#define IEEE80211_MMIE_LEN          18
+#define IEEE80211_MMIE_ELEMENTIDLEN 1
+#define IEEE80211_MMIE_LENGTHLEN    1
+#define IEEE80211_MMIE_KEYIDLEN     2
+#define IEEE80211_MMIE_IPNLEN       6
+#define IEEE80211_MMIE_MICLEN       8
+
+#define IEEE80211_CRC_LEN           4
+
+#define IEEE80211_8021Q_HEADER_LEN  4
+/*
+ * Maximum acceptable MTU is:
+ *  IEEE80211_MAX_LEN - WEP overhead - CRC -
+ *      QoS overhead - RSN/WPA overhead
+ * Min is arbitrarily chosen > IEEE80211_MIN_LEN.  The default
+ * mtu is Ethernet-compatible; it's set by ether_ifattach.
+ */
+#define IEEE80211_MTU_MAX       2290
+#define IEEE80211_MTU_MIN       32
+
+/* Rather than using this default value, customer platforms can provide a custom value for this constant.
+   Coustomer platform will use the different define value by themself */
+#ifndef IEEE80211_MAX_MPDU_LEN
+#define IEEE80211_MAX_MPDU_LEN      (3840 + IEEE80211_CRC_LEN +	\
+				     (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN))
+#endif
+#define IEEE80211_ACK_LEN \
+	(sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN)
+#define IEEE80211_MIN_LEN \
+	(sizeof(struct ieee80211_frame_min) + IEEE80211_CRC_LEN)
+
+/* An 802.11 data frame can be one of three types:
+   1. An unaggregated frame: The maximum length of an unaggregated data frame is 2324 bytes + headers.
+   2. A data frame that is part of an AMPDU: The maximum length of an AMPDU may be upto 65535 bytes, but data frame is limited to 2324 bytes + header.
+   3. An AMSDU: The maximum length of an AMSDU is eihther 3839 or 7095 bytes.
+   The maximum frame length supported by hardware is 4095 bytes.
+   A length of 3839 bytes is chosen here to support unaggregated data frames, any size AMPDUs and 3839 byte AMSDUs.
+ */
+#define IEEE80211N_MAX_FRAMELEN  3839
+#define IEEE80211N_MAX_LEN (IEEE80211N_MAX_FRAMELEN + IEEE80211_CRC_LEN + \
+			    (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN))
+
+#define IEEE80211_TX_CHAINMASK_MIN  1
+#define IEEE80211_TX_CHAINMASK_MAX  7
+
+#define IEEE80211_RX_CHAINMASK_MIN  1
+#define IEEE80211_RX_CHAINMASK_MAX  7
+
+/*
+ * The 802.11 spec says at most 2007 stations may be
+ * associated at once.  For most AP's this is way more
+ * than is feasible so we use a default of 128.  This
+ * number may be overridden by the driver and/or by
+ * user configuration.
+ */
+#define IEEE80211_AID_MAX       2007
+#define IEEE80211_AID_DEF       128
+
+#define IEEE80211_AID(b)    ((b) & ~0xc000)
+
+/*
+ * RTS frame length parameters.  The default is specified in
+ * the 802.11 spec.  The max may be wrong for jumbo frames.
+ */
+#define IEEE80211_RTS_DEFAULT       512
+#define IEEE80211_RTS_MIN           0
+#define IEEE80211_RTS_MAX           2347
+
+/*
+ * Fragmentation limits
+ */
+#define IEEE80211_FRAGMT_THRESHOLD_MIN        540       /* min frag threshold */
+#define IEEE80211_FRAGMT_THRESHOLD_MAX       2346       /* max frag threshold */
+
+/*
+ * Regulatory extension identifier for country IE.
+ */
+#define IEEE80211_REG_EXT_ID        201
+
+/*
+ * overlapping BSS
+ */
+#define IEEE80211_OBSS_SCAN_PASSIVE_DWELL_DEF  20
+#define IEEE80211_OBSS_SCAN_ACTIVE_DWELL_DEF   10
+#define IEEE80211_OBSS_SCAN_INTERVAL_DEF       300
+#define IEEE80211_OBSS_SCAN_PASSIVE_TOTAL_DEF  200
+#define IEEE80211_OBSS_SCAN_ACTIVE_TOTAL_DEF   20
+#define IEEE80211_OBSS_SCAN_THRESH_DEF   25
+#define IEEE80211_OBSS_SCAN_DELAY_DEF   5
+
+/*
+ * overlapping BSS scan ie
+ */
+struct ieee80211_ie_obss_scan {
+	uint8_t elem_id;
+	uint8_t elem_len;
+	uint16_t scan_passive_dwell;
+	uint16_t scan_active_dwell;
+	uint16_t scan_interval;
+	uint16_t scan_passive_total;
+	uint16_t scan_active_total;
+	uint16_t scan_delay;
+	uint16_t scan_thresh;
+} __packed;
+
+/*
+ * Extended capability ie
+ */
+struct ieee80211_ie_ext_cap {
+	uint8_t elem_id;
+	uint8_t elem_len;
+	uint32_t ext_capflags;
+	uint32_t ext_capflags2;
+} __packed;
+
+/* Extended capability IE flags */
+#define IEEE80211_EXTCAPIE_2040COEXTMGMT        0x00000001
+#define IEEE80211_EXTCAPIE_TFS                  0x00010000
+#define IEEE80211_EXTCAPIE_FMS                  0x00000800
+#define IEEE80211_EXTCAPIE_WNMSLEEPMODE         0x00020000
+#define IEEE80211_EXTCAPIE_TIMBROADCAST         0x00040000
+#define IEEE80211_EXTCAPIE_PROXYARP             0x00001000
+#define IEEE80211_EXTCAPIE_BSSTRANSITION        0x00080000
+/* Tunneled Direct Link Setup (TDLS) extended capability bits */
+#define IEEE80211_EXTCAPIE_PEER_UAPSD_BUF_STA   0x10000000
+#define IEEE80211_EXTCAPIE_TDLS_PEER_PSM        0x20000000
+#define IEEE80211_EXTCAPIE_TDLS_CHAN_SX         0x40000000
+/* 2nd Extended capability IE flags bit32-bit63*/
+#define IEEE80211_EXTCAPIE_TDLSSUPPORT      0x00000020  /* bit-37 TDLS Support */
+#define IEEE80211_EXTCAPIE_TDLSPROHIBIT     0x00000040  /* bit-38 TDLS Prohibit Support */
+#define IEEE80211_EXTCAPIE_TDLSCHANSXPROHIBIT   0x00000080      /* bit-39 TDLS Channel Switch Prohibit */
+#define IEEE80211_EXTCAPIE_TDLS_WIDE_BAND   0x20000080  /* bit-61 TDLS Wide Bandwidth support */
+#define IEEE80211_EXTCAPIE_OP_MODE_NOTIFY   0x40000000  /* bit-62 Operating Mode notification */
+
+/*
+ * These caps are populated when we receive beacon/probe response
+ * This is used to maintain local TDLS cap bit masks
+ */
+
+#define IEEE80211_TDLS_PROHIBIT     0x00000001  /* bit-1 TDLS Prohibit Support */
+
+/*
+ * 20/40 BSS coexistence ie
+ */
+struct ieee80211_ie_bss_coex {
+	uint8_t elem_id;
+	uint8_t elem_len;
+#if _BYTE_ORDER == _BIG_ENDIAN
+	uint8_t reserved1 : 1,
+		reserved2 : 1,
+		reserved3 : 1,
+		obss_exempt_grant : 1,
+		obss_exempt_req : 1,
+		ht20_width_req : 1, ht40_intolerant : 1, inf_request : 1;
+#else
+	uint8_t inf_request : 1,
+		ht40_intolerant : 1,
+		ht20_width_req : 1,
+		obss_exempt_req : 1,
+		obss_exempt_grant : 1, reserved3 : 1, reserved2 : 1, reserved1 : 1;
+#endif
+} __packed;
+
+/*
+ * 20/40 BSS intolerant channel report ie
+ */
+struct ieee80211_ie_intolerant_report {
+	uint8_t elem_id;
+	uint8_t elem_len;
+	uint8_t reg_class;
+	uint8_t chan_list[1];   /* variable-length channel list */
+} __packed;
+
+/*
+ * 20/40 coext management action frame
+ */
+struct ieee80211_action_bss_coex_frame {
+	struct ieee80211_action ac_header;
+	struct ieee80211_ie_bss_coex coex;
+	struct ieee80211_ie_intolerant_report chan_report;
+} __packed;
+
+typedef enum ieee80211_tie_interval_type {
+	IEEE80211_TIE_INTERVAL_TYPE_RESERVED = 0,
+	IEEE80211_TIE_INTERVAL_TYPE_REASSOC_DEADLINE_INTERVAL = 1,
+	IEEE80211_TIE_INTERVAL_TYPE_KEY_LIFETIME_INTERVAL = 2,
+	IEEE80211_TIE_INTERVAL_TYPE_ASSOC_COMEBACK_TIME = 3,
+} ieee80211_tie_interval_type_t;
+
+struct ieee80211_ie_timeout_interval {
+	uint8_t elem_id;
+	uint8_t elem_len;
+	uint8_t interval_type;
+	uint32_t value;
+} __packed;
+
+/* TODO -> Need to Check Redefinition Error used in only UMAC */
+#if 0
+/* Management MIC information element (IEEE 802.11w) */
+struct ieee80211_mmie {
+	uint8_t element_id;
+	uint8_t length;
+	uint16_t key_id;
+	uint8_t sequence_number[6];
+	uint8_t mic[8];
+} __packed;
+#endif
+
+/*
+ * 802.11n Secondary Channel Offset element
+ */
+#define IEEE80211_SEC_CHAN_OFFSET_SCN               0   /* no secondary channel */
+#define IEEE80211_SEC_CHAN_OFFSET_SCA               1   /* secondary channel above */
+#define IEEE80211_SEC_CHAN_OFFSET_SCB               3   /* secondary channel below */
+
+struct ieee80211_ie_sec_chan_offset {
+	uint8_t elem_id;
+	uint8_t len;
+	uint8_t sec_chan_offset;
+} __packed;
+
+/*
+ * 802.11ac Transmit Power Envelope element
+ */
+#define IEEE80211_VHT_TXPWR_IS_SUB_ELEMENT          1   /* It checks whether its  sub element */
+#define IEEE80211_VHT_TXPWR_MAX_POWER_COUNT         4   /* Max TX power elements valid */
+#define IEEE80211_VHT_TXPWR_NUM_POWER_SUPPORTED     3   /* Max TX power elements supported */
+#define IEEE80211_VHT_TXPWR_LCL_MAX_PWR_UNITS_SHFT  3   /* B3-B5 Local Max transmit power units */
+
+struct ieee80211_ie_vht_txpwr_env {
+	uint8_t elem_id;
+	uint8_t elem_len;
+	uint8_t txpwr_info;     /* Transmit Power Information */
+	uint8_t local_max_txpwr[4];     /* Local Max TxPower for 20,40,80,160MHz */
+} __packed;
+
+/*
+ * 802.11ac Wide Bandwidth Channel Switch Element
+ */
+
+#define IEEE80211_VHT_EXTCH_SWITCH             1        /* For extension channel switch */
+#define CHWIDTH_VHT20                          20       /* Channel width 20 */
+#define CHWIDTH_VHT40                          40       /* Channel width 40 */
+#define CHWIDTH_VHT80                          80       /* Channel width 80 */
+#define CHWIDTH_VHT160                         160      /* Channel width 160 */
+
+struct ieee80211_ie_wide_bw_switch {
+	uint8_t elem_id;
+	uint8_t elem_len;
+	uint8_t new_ch_width;   /* New channel width */
+	uint8_t new_ch_freq_seg1;       /* Channel Center frequency 1 */
+	uint8_t new_ch_freq_seg2;       /* Channel Center frequency 2 */
+} __packed;
+
+#define IEEE80211_RSSI_RX       0x00000001
+#define IEEE80211_RSSI_TX       0x00000002
+#define IEEE80211_RSSI_EXTCHAN  0x00000004
+#define IEEE80211_RSSI_BEACON   0x00000008
+#define IEEE80211_RSSI_RXDATA   0x00000010
+
+#define IEEE80211_RATE_TX 0
+#define IEEE80211_RATE_RX 1
+#define IEEE80211_LASTRATE_TX 2
+#define IEEE80211_LASTRATE_RX 3
+#define IEEE80211_RATECODE_TX 4
+#define IEEE80211_RATECODE_RX 5
+
+#define IEEE80211_MAX_RATE_PER_CLIENT 8
+/* Define for the P2P Wildcard SSID */
+#define IEEE80211_P2P_WILDCARD_SSID         "DIRECT-"
+
+#define IEEE80211_P2P_WILDCARD_SSID_LEN     (sizeof(IEEE80211_P2P_WILDCARD_SSID) - 1)
+
+#endif /* CDS_COMMON_IEEE80211_H_ */
diff --git a/core/cds/inc/cds_ieee80211_defines.h b/core/cds/inc/cds_ieee80211_defines.h
new file mode 100644
index 0000000..82b14b8
--- /dev/null
+++ b/core/cds/inc/cds_ieee80211_defines.h
@@ -0,0 +1,1365 @@
+/*
+ * Copyright (c) 2011, 2014-2015, 2018 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.
+ */
+
+#ifndef CDS_IEEE80211_DEFINES_H_
+#define CDS_IEEE80211_DEFINES_H_
+
+#include "cds_ieee80211_common.h"
+
+/*
+ * Public defines for Atheros Upper MAC Layer
+ */
+
+/**
+ * @brief Opaque handle of 802.11 protocal layer.
+ */
+struct ieee80211com;
+typedef struct ieee80211com *wlan_dev_t;
+
+/**
+ * @brief Opaque handle to App IE module.
+ */
+struct wlan_mlme_app_ie;
+typedef struct wlan_mlme_app_ie *wlan_mlme_app_ie_t;
+
+/**
+ * @brief Opaque handle of network instance (vap) in 802.11 protocal layer.
+ */
+struct ieee80211vap;
+typedef struct ieee80211vap *wlan_if_t;
+
+struct ieee80211vapprofile;
+typedef struct ieee80211vapprofile *wlan_if_info_t;
+
+/**
+ * @brief Opaque handle of a node in the wifi network.
+ */
+struct ieee80211_node;
+typedef struct ieee80211_node *wlan_node_t;
+
+/**
+ * @brief Opaque handle of OS interface (ifp in the case of unix ).
+ */
+struct _os_if_t;
+typedef struct _os_if_t *os_if_t;
+
+/**
+ *
+ * @brief Opaque handle.
+ */
+typedef void *os_handle_t;
+
+/**
+ * @brief Opaque handle of a channel.
+ */
+struct ieee80211_channel;
+typedef struct ieee80211_channel *wlan_chan_t;
+
+/**
+ * @brief Opaque handle scan_entry.
+ */
+struct ieee80211_scan_entry;
+typedef struct ieee80211_scan_entry *wlan_scan_entry_t;
+
+/* AoW related defines */
+#define AOW_MAX_RECEIVER_COUNT  10
+
+#define IEEE80211_NWID_LEN                  32
+#define IEEE80211_ISO_COUNTRY_LENGTH        3   /* length of 11d ISO country string */
+
+typedef struct _ieee80211_ssid {
+	int len;
+	uint8_t ssid[IEEE80211_NWID_LEN];
+} ieee80211_ssid;
+
+typedef struct ieee80211_tx_status {
+	int ts_flags;
+#define IEEE80211_TX_ERROR          0x01
+#define IEEE80211_TX_XRETRY         0x02
+
+	int ts_retries;         /* number of retries to successfully transmit this frame */
+#ifdef ATH_SUPPORT_TxBF
+	uint8_t ts_txbfstatus;
+#define AR_BW_Mismatch      0x1
+#define AR_Stream_Miss      0x2
+#define AR_CV_Missed        0x4
+#define AR_Dest_Miss        0x8
+#define AR_Expired          0x10
+#define AR_TxBF_Valid_HW_Status    (AR_BW_Mismatch|AR_Stream_Miss|AR_CV_Missed|AR_Dest_Miss|AR_Expired)
+#define TxBF_STATUS_Sounding_Complete   0x20
+#define TxBF_STATUS_Sounding_Request    0x40
+#define TxBF_Valid_SW_Status  (TxBF_STATUS_Sounding_Complete | TxBF_STATUS_Sounding_Request)
+#define TxBF_Valid_Status  (AR_TxBF_Valid_HW_Status | TxBF_Valid_SW_Status)
+	uint32_t ts_tstamp;     /* tx time stamp */
+#endif
+#ifdef ATH_SUPPORT_FLOWMAC_MODULE
+	uint8_t ts_flowmac_flags;
+#define IEEE80211_TX_FLOWMAC_DONE           0x01
+#endif
+	uint32_t ts_rateKbps;
+} ieee80211_xmit_status;
+
+#ifndef EXTERNAL_USE_ONLY
+typedef struct ieee80211_rx_status {
+	int rs_numchains;
+	int rs_flags;
+#define IEEE80211_RX_FCS_ERROR      0x01
+#define IEEE80211_RX_MIC_ERROR      0x02
+#define IEEE80211_RX_DECRYPT_ERROR  0x04
+/* holes in flags here between, ATH_RX_XXXX to IEEE80211_RX_XXX */
+#define IEEE80211_RX_KEYMISS        0x200
+	int rs_rssi;            /* RSSI (noise floor ajusted) */
+	int rs_abs_rssi;        /* absolute RSSI */
+	int rs_datarate;        /* data rate received */
+	int rs_rateieee;
+	int rs_ratephy;
+
+#define IEEE80211_MAX_ANTENNA       3   /* Keep the same as ATH_MAX_ANTENNA */
+	uint8_t rs_rssictl[IEEE80211_MAX_ANTENNA];      /* RSSI (noise floor ajusted) */
+	uint8_t rs_rssiextn[IEEE80211_MAX_ANTENNA];     /* RSSI (noise floor ajusted) */
+	uint8_t rs_isvalidrssi; /* rs_rssi is valid or not */
+
+	enum ieee80211_phymode rs_phymode;
+	int rs_freq;
+
+	union {
+		uint8_t data[8];
+		uint64_t tsf;
+	} rs_tstamp;
+
+	/*
+	 * Detail channel structure of recv frame.
+	 * It could be NULL if not available
+	 */
+	struct ieee80211_channel *rs_full_chan;
+
+	uint8_t rs_isaggr;
+	uint8_t rs_isapsd;
+	int16_t rs_noisefloor;
+	uint16_t rs_channel;
+#ifdef ATH_SUPPORT_TxBF
+	uint32_t rs_rpttstamp;  /* txbf report time stamp */
+#endif
+
+	/* The following counts are meant to assist in stats calculation.
+	   These variables are incremented only in specific situations, and
+	   should not be relied upon for any purpose other than the original
+	   stats related purpose they have been introduced for. */
+
+	uint16_t rs_cryptodecapcount;   /* Crypto bytes decapped/demic'ed. */
+	uint8_t rs_padspace;    /* No. of padding bytes present after header
+	                           in wbuf. */
+	uint8_t rs_qosdecapcount;       /* QoS/HTC bytes decapped. */
+
+	/* End of stats calculation related counts. */
+
+	uint8_t rs_lsig[IEEE80211_LSIG_LEN];
+	uint8_t rs_htsig[IEEE80211_HTSIG_LEN];
+	uint8_t rs_servicebytes[IEEE80211_SB_LEN];
+
+} ieee80211_recv_status;
+#endif /* EXTERNAL_USE_ONLY */
+
+/*
+ * flags to be passed to ieee80211_vap_create function .
+ */
+#define IEEE80211_CLONE_BSSID           0x0001  /* allocate unique mac/bssid */
+#define IEEE80211_CLONE_NOBEACONS       0x0002  /* don't setup beacon timers */
+#define IEEE80211_CLONE_WDS             0x0004  /* enable WDS processing */
+#define IEEE80211_CLONE_WDSLEGACY       0x0008  /* legacy WDS operation */
+#define IEEE80211_PRIMARY_VAP           0x0010  /* primary vap */
+#define IEEE80211_P2PDEV_VAP            0x0020  /* p2pdev vap */
+#define IEEE80211_P2PGO_VAP             0x0040  /* p2p-go vap */
+#define IEEE80211_P2PCLI_VAP            0x0080  /* p2p-client vap */
+#define IEEE80211_CLONE_MACADDR         0x0100  /* create vap w/ specified mac/bssid */
+#define IEEE80211_CLONE_MATADDR         0x0200  /* create vap w/ specified MAT addr */
+#define IEEE80211_WRAP_VAP              0x0400  /* wireless repeater ap vap */
+
+/*
+ * For the new multi-vap scan feature, there is a set of default priority tables
+ * for each OpMode.
+ * The following are the default list of the VAP Scan Priority Mapping based on OpModes.
+ * NOTE: the following are only used when "#if ATH_SUPPORT_MULTIPLE_SCANS" is true.
+ */
+/* For IBSS opmode */
+#define DEF_VAP_SCAN_PRI_MAP_OPMODE_IBSS_BASE               0
+/* For STA opmode */
+#define DEF_VAP_SCAN_PRI_MAP_OPMODE_STA_BASE                0
+#define DEF_VAP_SCAN_PRI_MAP_OPMODE_STA_P2P_CLIENT          1
+/* For HostAp opmode */
+#define DEF_VAP_SCAN_PRI_MAP_OPMODE_AP_BASE                 0
+#define DEF_VAP_SCAN_PRI_MAP_OPMODE_AP_P2P_GO               1
+#define DEF_VAP_SCAN_PRI_MAP_OPMODE_AP_P2P_DEVICE           2
+/* For BTAmp opmode */
+#define DEF_VAP_SCAN_PRI_MAP_OPMODE_BTAMP_BASE              0
+
+typedef enum _ieee80211_dev_vap_event {
+	IEEE80211_VAP_CREATED = 1,
+	IEEE80211_VAP_STOPPED,
+	IEEE80211_VAP_DELETED
+} ieee80211_dev_vap_event;
+
+typedef struct _wlan_dev_event_handler_table {
+	void (*wlan_dev_vap_event)(void *event_arg, wlan_dev_t, os_if_t, ieee80211_dev_vap_event);      /* callback to receive vap events */
+#ifdef ATH_SUPPORT_SPECTRAL
+	void (*wlan_dev_spectral_indicate)(void *, void *, uint32_t);
+#endif
+} wlan_dev_event_handler_table;
+
+typedef enum _ieee80211_ap_stopped_reason {
+	IEEE80211_AP_STOPPED_REASON_DUMMY = 0,  /* Dummy placeholder. Should not use */
+	IEEE80211_AP_STOPPED_REASON_CHANNEL_DFS = 1,
+} ieee80211_ap_stopped_reason;
+
+typedef int IEEE80211_REASON_CODE;
+typedef int IEEE80211_STATUS;
+
+/*
+ * scan API related structs.
+ */
+typedef enum _ieee80211_scan_type {
+	IEEE80211_SCAN_BACKGROUND,
+	IEEE80211_SCAN_FOREGROUND,
+	IEEE80211_SCAN_SPECTRAL,
+	IEEE80211_SCAN_REPEATER_BACKGROUND,
+	IEEE80211_SCAN_REPEATER_EXT_BACKGROUND,
+	IEEE80211_SCAN_RADIO_MEASUREMENTS,
+} ieee80211_scan_type;
+
+/*
+ * Priority numbers must be sequential, starting with 0.
+ */
+typedef enum ieee80211_scan_priority_t {
+	IEEE80211_SCAN_PRIORITY_VERY_LOW = 0,
+	IEEE80211_SCAN_PRIORITY_LOW,
+	IEEE80211_SCAN_PRIORITY_MEDIUM,
+	IEEE80211_SCAN_PRIORITY_HIGH,
+	IEEE80211_SCAN_PRIORITY_VERY_HIGH,
+
+	IEEE80211_SCAN_PRIORITY_COUNT   /* number of priorities supported */
+} IEEE80211_SCAN_PRIORITY;
+
+typedef uint16_t IEEE80211_SCAN_REQUESTOR;
+typedef uint32_t IEEE80211_SCAN_ID;
+
+#define IEEE80211_SCAN_ID_NONE                    0
+
+/* All P2P scans currently use medium priority */
+#define IEEE80211_P2P_DEFAULT_SCAN_PRIORITY       IEEE80211_SCAN_PRIORITY_MEDIUM
+#define IEEE80211_P2P_SCAN_PRIORITY_HIGH          IEEE80211_SCAN_PRIORITY_HIGH
+
+/* Masks identifying types/ID of scans */
+#define IEEE80211_SPECIFIC_SCAN       0x00000000
+#define IEEE80211_VAP_SCAN            0x01000000
+#define IEEE80211_ALL_SCANS           0x04000000
+
+/**
+ * host scan bit. only relevant for host/target architecture.
+ * do not reuse this bit definition. target uses this .
+ *
+ */
+#define IEEE80211_HOST_SCAN           0x80000000
+#define IEEE80211_SCAN_CLASS_MASK     0xFF000000
+
+#define IEEE80211_SCAN_PASSIVE            0x0001        /* passively scan all the channels */
+#define IEEE80211_SCAN_ACTIVE             0x0002        /* actively  scan all the channels (regdomain rules still apply) */
+#define IEEE80211_SCAN_2GHZ               0x0004        /* scan 2GHz band */
+#define IEEE80211_SCAN_5GHZ               0x0008        /* scan 5GHz band */
+#define IEEE80211_SCAN_ALLBANDS           (IEEE80211_SCAN_5GHZ | IEEE80211_SCAN_2GHZ)
+#define IEEE80211_SCAN_CONTINUOUS         0x0010        /* keep scanning until maxscantime expires */
+#define IEEE80211_SCAN_FORCED             0x0020        /* forced scan (OS request) - should proceed even in the presence of data traffic */
+#define IEEE80211_SCAN_NOW                0x0040        /* scan now (User request)  - should proceed even in the presence of data traffic */
+#define IEEE80211_SCAN_ADD_BCAST_PROBE    0x0080        /* add wildcard ssid and broadcast probe request if there is none */
+#define IEEE80211_SCAN_EXTERNAL           0x0100        /* scan requested by OS */
+#define IEEE80211_SCAN_BURST              0x0200        /* scan multiple channels before returning to BSS channel */
+#define IEEE80211_SCAN_CHAN_EVENT         0x0400        /* scan chan event for  offload architectures */
+#define IEEE80211_SCAN_FILTER_PROBE_REQ   0x0800        /* Filter probe requests- applicable only for offload architectures */
+
+#define IEEE80211_SCAN_PARAMS_MAX_SSID     10
+#define IEEE80211_SCAN_PARAMS_MAX_BSSID    10
+
+/* flag definitions passed to scan_cancel API */
+
+#define IEEE80211_SCAN_CANCEL_ASYNC 0x0 /* asynchronouly wait for scan SM to complete cancel */
+#define IEEE80211_SCAN_CANCEL_WAIT  0x1 /* wait for scan SM to complete cancel */
+#define IEEE80211_SCAN_CANCEL_SYNC  0x2 /* synchronously execute cancel scan */
+
+#ifndef EXTERNAL_USE_ONLY
+typedef bool (*ieee80211_scan_termination_check)(void *arg);
+
+typedef struct _ieee80211_scan_params {
+	ieee80211_scan_type type;
+	int min_dwell_time_active;      /* min time in msec on active channels */
+	int max_dwell_time_active;      /* max time in msec on active channels (if no response) */
+	int min_dwell_time_passive;     /* min time in msec on passive channels */
+	int max_dwell_time_passive;     /* max time in msec on passive channels (if no response) */
+	int min_rest_time;      /* min time in msec on the BSS channel, only valid for BG scan */
+	int max_rest_time;      /* max time in msec on the BSS channel, only valid for BG scan */
+	int max_offchannel_time;        /* max time away from BSS channel, in ms */
+	int repeat_probe_time;  /* time before sending second probe request */
+	int idle_time;          /* time in msec on bss channel before switching channel */
+	int max_scan_time;      /* maximum time in msec allowed for scan  */
+	int probe_delay;        /* delay in msec before sending probe request */
+	int offchan_retry_delay;        /* delay in msec before retrying off-channel switch */
+	int min_beacon_count;   /* number of home AP beacons to receive before leaving the home channel */
+	int max_offchan_retries;        /* maximum number of times to retry off-channel switch */
+	int beacon_timeout;     /* maximum time to wait for beacons */
+	int flags;              /* scan flags */
+	int num_channels;       /* number of channels to scan */
+	bool multiple_ports_active;     /* driver has multiple ports active in the home channel */
+	bool restricted_scan;   /* Perform restricted scan */
+	bool chan_list_allocated;
+	IEEE80211_SCAN_PRIORITY p2p_scan_priority;      /* indicates the scan priority if this is a P2P-related scan */
+	uint32_t *chan_list;    /* array of ieee channels (or) frequencies to scan */
+	int num_ssid;           /* number of desired ssids */
+	ieee80211_ssid ssid_list[IEEE80211_SCAN_PARAMS_MAX_SSID];
+	int num_bssid;          /* number of desired bssids */
+	uint8_t bssid_list[IEEE80211_SCAN_PARAMS_MAX_BSSID][IEEE80211_ADDR_LEN];
+	struct ieee80211_node *bss_node;        /* BSS node */
+	int ie_len;             /* length of the ie data to be added to probe req */
+	uint8_t *ie_data;       /* pointer to ie data */
+	ieee80211_scan_termination_check check_termination_function;    /* function checking for termination condition */
+	void *check_termination_context;        /* context passed to function above */
+} ieee80211_scan_params;
+
+/* Data types used to specify scan priorities */
+typedef uint32_t IEEE80211_PRIORITY_MAPPING[IEEE80211_SCAN_PRIORITY_COUNT];
+
+/**************************************
+ * Called before attempting to roam.  Modifies the rssiAdder of a BSS
+ * based on the preferred status of a BSS.
+ *
+ * According to CCX spec, AP in the neighbor list is not meant for giving extra
+ * weightage in roaming. By doing so, roaming becomes sticky. See bug 21220.
+ * Change the weightage to 0. Cisco may ask in future for a user control of
+ * this weightage.
+ */
+#define PREFERRED_BSS_RANK                20
+#define NEIGHBOR_BSS_RANK                  0    /* must be less than preferred BSS rank */
+
+/*
+ * The utility of the BSS is the metric used in the selection
+ * of a BSS. The Utility of the BSS is reduced if we just left the BSS.
+ * The Utility of the BSS is not reduced if we have left the
+ * BSS for 8 seconds (8000ms) or more.
+ * 2^13 milliseconds is a close approximation to avoid expensive division
+ */
+#define LAST_ASSOC_TIME_DELTA_REQUIREMENT (1 << 13)     /* 8192 */
+
+#define QBSS_SCALE_MAX                   255    /* Qbss channel load Max value */
+#define QBSS_SCALE_DOWN_FACTOR             2    /* scale factor to reduce Qbss channel load */
+#define QBSS_HYST_ADJ                     60    /* Qbss Weightage factor for the current AP */
+
+/*
+ * Flags used to set field APState
+ */
+#define AP_STATE_GOOD    0x00
+#define AP_STATE_BAD     0x01
+#define AP_STATE_RETRY   0x10
+#define BAD_AP_TIMEOUT   6000   /* In milli seconds */
+/*
+ * To disable BAD_AP status check on any scan entry
+ */
+#define BAD_AP_TIMEOUT_DISABLED             0
+
+/*
+ * BAD_AP timeout specified in seconds
+ */
+#define BAD_AP_TIMEOUT_IN_SECONDS           10
+
+/*
+ * State values used to represent our assoc_state with ap (discrete, not bitmasks)
+ */
+#define AP_ASSOC_STATE_NONE     0
+#define AP_ASSOC_STATE_AUTH     1
+#define AP_ASSOC_STATE_ASSOC    2
+
+/*
+ * Entries in the scan list are considered obsolete after 75 seconds.
+ */
+#define IEEE80211_SCAN_ENTRY_EXPIRE_TIME           75000
+
+/*
+ * idle time is only valid for scan type IEEE80211_SCAN_BACKGROUND.
+ * if idle time is set then the scanner would change channel from BSS
+ * channel to foreign channel only if both resttime is expired and
+ * the theres was not traffic for idletime msec on the bss channel.
+ * value of 0 for idletime would cause the channel to switch from BSS
+ * channel to foreign channel as soon  as the resttime is expired.
+ *
+ * if maxscantime is nonzero and if the scanner can not complete the
+ * scan in maxscantime msec then the scanner will cancel the scan and
+ * post IEEE80211_SCAN_COMPLETED event with reason SCAN_TIMEDOUT.
+ *
+ */
+
+/*
+ * chanlist can be either ieee channels (or) frequencies.
+ * if a value is less than 1000 implementation assumes it
+ * as ieee channel # otherwise implementation assumes it
+ * as frequency in Mhz.
+ */
+
+typedef enum _ieee80211_scan_event_type {
+	IEEE80211_SCAN_STARTED,
+	IEEE80211_SCAN_COMPLETED,
+	IEEE80211_SCAN_RADIO_MEASUREMENT_START,
+	IEEE80211_SCAN_RADIO_MEASUREMENT_END,
+	IEEE80211_SCAN_RESTARTED,
+	IEEE80211_SCAN_HOME_CHANNEL,
+	IEEE80211_SCAN_FOREIGN_CHANNEL,
+	IEEE80211_SCAN_BSSID_MATCH,
+	IEEE80211_SCAN_FOREIGN_CHANNEL_GET_NF,
+	IEEE80211_SCAN_DEQUEUED,
+	IEEE80211_SCAN_PREEMPTED,
+
+	IEEE80211_SCAN_EVENT_COUNT
+} ieee80211_scan_event_type;
+
+typedef enum ieee80211_scan_completion_reason {
+	IEEE80211_REASON_NONE,
+	IEEE80211_REASON_COMPLETED,
+	IEEE80211_REASON_CANCELLED,
+	IEEE80211_REASON_TIMEDOUT,
+	IEEE80211_REASON_TERMINATION_FUNCTION,
+	IEEE80211_REASON_MAX_OFFCHAN_RETRIES,
+	IEEE80211_REASON_PREEMPTED,
+	IEEE80211_REASON_RUN_FAILED,
+	IEEE80211_REASON_INTERNAL_STOP,
+
+	IEEE80211_REASON_COUNT
+} ieee80211_scan_completion_reason;
+
+typedef struct _ieee80211_scan_event {
+	ieee80211_scan_event_type type;
+	ieee80211_scan_completion_reason reason;
+	wlan_chan_t chan;
+	IEEE80211_SCAN_REQUESTOR requestor;     /* Requestor ID passed to the scan_start function */
+	IEEE80211_SCAN_ID scan_id;      /* Specific ID of the scan reporting the event */
+} ieee80211_scan_event;
+
+typedef enum _ieee80211_scan_request_status {
+	IEEE80211_SCAN_STATUS_QUEUED,
+	IEEE80211_SCAN_STATUS_RUNNING,
+	IEEE80211_SCAN_STATUS_PREEMPTED,
+	IEEE80211_SCAN_STATUS_COMPLETED
+} ieee80211_scan_request_status;
+
+/*
+ * the sentry field of tht ieee80211_scan_event is only valid if the
+ * event type is IEEE80211_SCAN_BSSID_MATCH.
+ */
+
+typedef void (*ieee80211_scan_event_handler)(wlan_if_t vaphandle,
+					     ieee80211_scan_event *event,
+					     void *arg);
+
+typedef struct _ieee80211_scan_info {
+	ieee80211_scan_type type;
+	IEEE80211_SCAN_REQUESTOR requestor;     /* Originator ID passed to the scan_start function */
+	IEEE80211_SCAN_ID scan_id;      /* Specific ID of the scan reporting the event */
+	IEEE80211_SCAN_PRIORITY priority;       /* Requested priority level (low/medium/high) */
+	ieee80211_scan_request_status scheduling_status;        /* Queued/running/preempted/completed */
+	int min_dwell_time_active;      /* min time in msec on active channels */
+	int max_dwell_time_active;      /* max time in msec on active channel (if no response) */
+	int min_dwell_time_passive;     /* min time in msec on passive channels */
+	int max_dwell_time_passive;     /* max time in msec on passive channel */
+	int min_rest_time;      /* min time in msec on the BSS channel, only valid for BG scan */
+	int max_rest_time;      /* max time in msec on the BSS channel, only valid for BG scan */
+	int max_offchannel_time;        /* max time away from BSS channel, in ms */
+	int repeat_probe_time;  /* time before sending second probe request */
+	int min_beacon_count;   /* number of home AP beacons to receive before leaving the home channel */
+	int flags;              /* scan flags */
+	systime_t scan_start_time;      /* system time when last scani started */
+	int scanned_channels;   /* number of scanned channels */
+	int default_channel_list_length;        /* number of channels in the default channel list */
+	int channel_list_length;        /* number of channels in the channel list used for the current scan */
+	uint8_t in_progress : 1,  /* if the scan is in progress */
+		cancelled : 1,  /* if the scan is cancelled */
+		preempted : 1,  /* if the scan is preempted */
+		restricted : 1; /* if the scan is restricted */
+} ieee80211_scan_info;
+
+typedef struct _ieee80211_scan_request_info {
+	wlan_if_t vaphandle;
+	IEEE80211_SCAN_REQUESTOR requestor;
+	IEEE80211_SCAN_PRIORITY requested_priority;
+	IEEE80211_SCAN_PRIORITY absolute_priority;
+	IEEE80211_SCAN_ID scan_id;
+	ieee80211_scan_request_status scheduling_status;
+	ieee80211_scan_params params;
+	systime_t request_timestamp;
+	uint32_t maximum_duration;
+} ieee80211_scan_request_info;
+
+#endif /* EXTERNAL_USE_ONLY */
+
+#ifndef EXTERNAL_USE_ONLY
+typedef void (*ieee80211_acs_event_handler)(void *arg, wlan_chan_t channel);
+#endif /* EXTERNAL_USE_ONLY */
+
+#define MAX_CHAINS 3
+
+typedef struct _wlan_rssi_info {
+	int8_t avg_rssi;        /* average rssi */
+	uint8_t valid_mask;     /* bitmap of valid elements in rssi_ctrl/ext array */
+	int8_t rssi_ctrl[MAX_CHAINS];
+	int8_t rssi_ext[MAX_CHAINS];
+} wlan_rssi_info;
+
+typedef enum _wlan_rssi_type {
+	WLAN_RSSI_TX,
+	WLAN_RSSI_RX,
+	WLAN_RSSI_BEACON,       /* rssi of the beacon, only valid for STA/IBSS vap */
+	WLAN_RSSI_RX_DATA
+} wlan_rssi_type;
+
+typedef enum _ieee80211_rate_type {
+	IEEE80211_RATE_TYPE_LEGACY,
+	IEEE80211_RATE_TYPE_MCS,
+} ieee80211_rate_type;
+
+typedef struct _ieee80211_rate_info {
+	ieee80211_rate_type type;
+	uint32_t rate;          /* average rate in kbps */
+	uint32_t lastrate;      /* last packet rate in kbps */
+	uint8_t mcs;            /* mcs index . is valid if rate type is MCS20 or MCS40 */
+	uint8_t maxrate_per_client;
+} ieee80211_rate_info;
+
+typedef enum _ieee80211_node_param_type {
+	IEEE80211_NODE_PARAM_TX_POWER,
+	IEEE80211_NODE_PARAM_ASSOCID,
+	IEEE80211_NODE_PARAM_INACT,     /* inactivity timer value */
+	IEEE80211_NODE_PARAM_AUTH_MODE, /* auth mode */
+	IEEE80211_NODE_PARAM_CAP_INFO,  /* auth mode */
+} ieee80211_node_param_type;
+
+/*
+ * Per/node (station) statistics available when operating as an AP.
+ */
+struct ieee80211_nodestats {
+	uint32_t ns_rx_data;    /* rx data frames */
+	uint32_t ns_rx_mgmt;    /* rx management frames */
+	uint32_t ns_rx_ctrl;    /* rx control frames */
+	uint32_t ns_rx_ucast;   /* rx unicast frames */
+	uint32_t ns_rx_mcast;   /* rx multi/broadcast frames */
+	uint64_t ns_rx_bytes;   /* rx data count (bytes) */
+	uint64_t ns_rx_beacons; /* rx beacon frames */
+	uint32_t ns_rx_proberesp;       /* rx probe response frames */
+
+	uint32_t ns_rx_dup;     /* rx discard 'cuz dup */
+	uint32_t ns_rx_noprivacy;       /* rx w/ wep but privacy off */
+	uint32_t ns_rx_wepfail; /* rx wep processing failed */
+	uint32_t ns_rx_demicfail;       /* rx demic failed */
+
+	/* We log MIC and decryption failures against Transmitter STA stats.
+	   Though the frames may not actually be sent by STAs corresponding
+	   to TA, the stats are still valuable for some customers as a sort
+	   of rough indication.
+	   Also note that the mapping from TA to STA may fail sometimes. */
+	uint32_t ns_rx_tkipmic; /* rx TKIP MIC failure */
+	uint32_t ns_rx_ccmpmic; /* rx CCMP MIC failure */
+	uint32_t ns_rx_wpimic;  /* rx WAPI MIC failure */
+	uint32_t ns_rx_tkipicv; /* rx ICV check failed (TKIP) */
+	uint32_t ns_rx_decap;   /* rx decapsulation failed */
+	uint32_t ns_rx_defrag;  /* rx defragmentation failed */
+	uint32_t ns_rx_disassoc;        /* rx disassociation */
+	uint32_t ns_rx_deauth;  /* rx deauthentication */
+	uint32_t ns_rx_action;  /* rx action */
+	uint32_t ns_rx_decryptcrc;      /* rx decrypt failed on crc */
+	uint32_t ns_rx_unauth;  /* rx on unauthorized port */
+	uint32_t ns_rx_unencrypted;     /* rx unecrypted w/ privacy */
+
+	uint32_t ns_tx_data;    /* tx data frames */
+	uint32_t ns_tx_data_success;    /* tx data frames successfully
+	                                   transmitted (unicast only) */
+	uint32_t ns_tx_mgmt;    /* tx management frames */
+	uint32_t ns_tx_ucast;   /* tx unicast frames */
+	uint32_t ns_tx_mcast;   /* tx multi/broadcast frames */
+	uint64_t ns_tx_bytes;   /* tx data count (bytes) */
+	uint64_t ns_tx_bytes_success;   /* tx success data count - unicast only
+	                                   (bytes) */
+	uint32_t ns_tx_probereq;        /* tx probe request frames */
+	uint32_t ns_tx_uapsd;   /* tx on uapsd queue */
+	uint32_t ns_tx_discard; /* tx dropped by NIC */
+
+	uint32_t ns_tx_novlantag;       /* tx discard 'cuz no tag */
+	uint32_t ns_tx_vlanmismatch;    /* tx discard 'cuz bad tag */
+
+	uint32_t ns_tx_eosplost;        /* uapsd EOSP retried out */
+
+	uint32_t ns_ps_discard; /* ps discard 'cuz of age */
+
+	uint32_t ns_uapsd_triggers;     /* uapsd triggers */
+	uint32_t ns_uapsd_duptriggers;  /* uapsd duplicate triggers */
+	uint32_t ns_uapsd_ignoretriggers;       /* uapsd duplicate triggers */
+	uint32_t ns_uapsd_active;       /* uapsd duplicate triggers */
+	uint32_t ns_uapsd_triggerenabled;       /* uapsd duplicate triggers */
+
+	/* MIB-related state */
+	uint32_t ns_tx_assoc;   /* [re]associations */
+	uint32_t ns_tx_assoc_fail;      /* [re]association failures */
+	uint32_t ns_tx_auth;    /* [re]authentications */
+	uint32_t ns_tx_auth_fail;       /* [re]authentication failures */
+	uint32_t ns_tx_deauth;  /* deauthentications */
+	uint32_t ns_tx_deauth_code;     /* last deauth reason */
+	uint32_t ns_tx_disassoc;        /* disassociations */
+	uint32_t ns_tx_disassoc_code;   /* last disassociation reason */
+	uint32_t ns_psq_drops;  /* power save queue drops */
+};
+
+/*
+ * station power save mode.
+ */
+typedef enum ieee80211_psmode {
+	IEEE80211_PWRSAVE_NONE = 0,     /* no power save */
+	IEEE80211_PWRSAVE_LOW,
+	IEEE80211_PWRSAVE_NORMAL,
+	IEEE80211_PWRSAVE_MAXIMUM,
+	IEEE80211_PWRSAVE_WNM   /* WNM-Sleep Mode */
+} ieee80211_pwrsave_mode;
+
+/* station power save pspoll handling */
+typedef enum {
+	IEEE80211_CONTINUE_PSPOLL_FOR_MORE_DATA,
+	IEEE80211_WAKEUP_FOR_MORE_DATA,
+} ieee80211_pspoll_moredata_handling;
+
+/*
+ * apps power save state.
+ */
+typedef enum {
+	APPS_AWAKE = 0,
+	APPS_PENDING_SLEEP,
+	APPS_SLEEP,
+	APPS_FAKE_SLEEP,        /* Pending blocking sleep */
+	APPS_FAKING_SLEEP,      /* Blocking sleep */
+	APPS_UNKNOWN_PWRSAVE,
+} ieee80211_apps_pwrsave_state;
+
+typedef enum _iee80211_mimo_powersave_mode {
+	IEEE80211_MIMO_POWERSAVE_NONE,  /* no mimo power save */
+	IEEE80211_MIMO_POWERSAVE_STATIC,        /* static mimo power save */
+	IEEE80211_MIMO_POWERSAVE_DYNAMIC        /* dynamic mimo powersave */
+} ieee80211_mimo_powersave_mode;
+
+#ifdef ATH_COALESCING
+typedef enum _ieee80211_coalescing_state {
+	IEEE80211_COALESCING_DISABLED = 0,      /* Coalescing is disabled */
+	IEEE80211_COALESCING_DYNAMIC = 1,       /* Dynamically move to Enabled state based on Uruns */
+	IEEE80211_COALESCING_ENABLED = 2,       /* Coalescing is enabled */
+} ieee80211_coalescing_state;
+
+#define IEEE80211_TX_COALESCING_THRESHOLD     5 /* Number of underrun errors to trigger coalescing */
+#endif
+
+typedef enum _ieee80211_cap {
+	IEEE80211_CAP_SHSLOT,   /* CAPABILITY: short slot */
+	IEEE80211_CAP_SHPREAMBLE,       /* CAPABILITY: short premable */
+	IEEE80211_CAP_MULTI_DOMAIN,     /* CAPABILITY: multiple domain */
+	IEEE80211_CAP_WMM,      /* CAPABILITY: WMM */
+	IEEE80211_CAP_HT,       /* CAPABILITY: HT */
+	IEEE80211_CAP_PERF_PWR_OFLD,    /* CAPABILITY: power performance offload support */
+	IEEE80211_CAP_11AC,     /* CAPABILITY: 11ac support */
+} ieee80211_cap;
+
+typedef enum _ieee80211_device_param {
+	IEEE80211_DEVICE_RSSI_CTL,
+	IEEE80211_DEVICE_NUM_TX_CHAIN,
+	IEEE80211_DEVICE_NUM_RX_CHAIN,
+	IEEE80211_DEVICE_TX_CHAIN_MASK,
+	IEEE80211_DEVICE_RX_CHAIN_MASK,
+	IEEE80211_DEVICE_TX_CHAIN_MASK_LEGACY,
+	IEEE80211_DEVICE_RX_CHAIN_MASK_LEGACY,
+	IEEE80211_DEVICE_BMISS_LIMIT,   /* # of beacon misses for HW to generate BMISS intr */
+	IEEE80211_DEVICE_PROTECTION_MODE,       /* protection mode */
+	IEEE80211_DEVICE_BLKDFSCHAN,    /* block the use of DFS channels */
+	IEEE80211_DEVICE_GREEN_AP_PS_ENABLE,
+	IEEE80211_DEVICE_GREEN_AP_PS_TIMEOUT,
+	IEEE80211_DEVICE_GREEN_AP_PS_ON_TIME,
+	IEEE80211_DEVICE_CWM_EXTPROTMODE,
+	IEEE80211_DEVICE_CWM_EXTPROTSPACING,
+	IEEE80211_DEVICE_CWM_ENABLE,
+	IEEE80211_DEVICE_CWM_EXTBUSYTHRESHOLD,
+	IEEE80211_DEVICE_DOTH,
+	IEEE80211_DEVICE_ADDBA_MODE,
+	IEEE80211_DEVICE_COUNTRYCODE,
+	IEEE80211_DEVICE_MULTI_CHANNEL, /* turn on/off off channel support */
+	IEEE80211_DEVICE_MAX_AMSDU_SIZE,        /* Size of AMSDU to be sent on the air */
+	IEEE80211_DEVICE_P2P,   /* Enable or Disable P2P */
+	IEEE80211_DEVICE_OVERRIDE_SCAN_PROBERESPONSE_IE,        /* Override scan Probe response IE, 0: Don't over-ride */
+	IEEE80211_DEVICE_2G_CSA,
+	IEEE80211_DEVICE_PWRTARGET,
+	IEEE80211_DEVICE_OFF_CHANNEL_SUPPORT,
+} ieee80211_device_param;
+
+typedef enum _ieee80211_param {
+	IEEE80211_BEACON_INTVAL,        /* in TUs */
+	IEEE80211_LISTEN_INTVAL,        /* number of beacons */
+	IEEE80211_DTIM_INTVAL,  /* number of beacons */
+	IEEE80211_BMISS_COUNT_RESET,    /* number of beacon miss intrs before reset */
+	IEEE80211_BMISS_COUNT_MAX,      /* number of beacon miss intrs for bmiss notificationst */
+	IEEE80211_ATIM_WINDOW,  /* ATIM window */
+	IEEE80211_SHORT_SLOT,   /* short slot on/off */
+	IEEE80211_SHORT_PREAMBLE,       /* short preamble on/off */
+	IEEE80211_RTS_THRESHOLD,        /* rts threshold, 0 means no rts threshold  */
+	IEEE80211_FRAG_THRESHOLD,       /* fragmentation threshold, 0 means no rts threshold  */
+	IEEE80211_FIXED_RATE,   /*
+	                         * rate code series(0: auto rate, 32 bit value:  rate
+	                         * codes for 4 rate series. each byte for one rate series)
+	                         */
+	IEEE80211_MCAST_RATE,   /* rate in Kbps */
+	IEEE80211_TXPOWER,      /* in 0.5db units */
+	IEEE80211_AMPDU_DENCITY,        /* AMPDU dencity */
+	IEEE80211_AMPDU_LIMIT,  /* AMPDU limit */
+	IEEE80211_MAX_AMPDU,    /* Max AMPDU Exp */
+	IEEE80211_VHT_MAX_AMPDU,        /* VHT Max AMPDU Exp */
+	IEEE80211_WPS_MODE,     /* WPS mode */
+	IEEE80211_TSN_MODE,     /* TSN mode */
+	IEEE80211_MULTI_DOMAIN, /* Multiple domain */
+	IEEE80211_SAFE_MODE,    /* Safe mode */
+	IEEE80211_NOBRIDGE_MODE,        /* No bridging done, all frames sent up the stack */
+	IEEE80211_PERSTA_KEYTABLE_SIZE, /* IBSS-only, read-only: persta key table size */
+	IEEE80211_RECEIVE_80211,        /* deliver std 802.11 frames 802.11 instead of ethernet frames on the rx */
+	IEEE80211_SEND_80211,   /* OS sends std 802.11 frames 802.11 instead of ethernet frames on tx side */
+	IEEE80211_MIN_BEACON_COUNT,     /* minimum number beacons to tx/rx before vap can pause */
+	IEEE80211_IDLE_TIME,    /* minimun no activity time before vap can pause */
+	IEEE80211_MIN_FRAMESIZE,        /* smallest frame size we are allowed to receive */
+	/* features. 0:feature is off. 1:feature is on. */
+	IEEE80211_FEATURE_WMM,  /* WMM */
+	IEEE80211_FEATURE_WMM_PWRSAVE,  /* WMM Power Save */
+	IEEE80211_FEATURE_UAPSD,        /* UAPSD setting (BE/BK/VI/VO) */
+	IEEE80211_FEATURE_WDS,  /* dynamic WDS feature */
+	IEEE80211_FEATURE_PRIVACY,      /* encryption */
+	IEEE80211_FEATURE_DROP_UNENC,   /* drop un encrypted frames */
+	IEEE80211_FEATURE_COUNTER_MEASURES,     /* turn on counter measures */
+	IEEE80211_FEATURE_HIDE_SSID,    /* turn on hide ssid feature */
+	IEEE80211_FEATURE_APBRIDGE,     /* turn on internal mcast traffic bridging for AP */
+	IEEE80211_FEATURE_PUREB,        /* turn on pure B mode for AP */
+	IEEE80211_FEATURE_PUREG,        /* turn on pure G mode for AP */
+	IEEE80211_FEATURE_REGCLASS,     /* add regulatory class IE in AP */
+	IEEE80211_FEATURE_COUNTRY_IE,   /* add country IE for vap in AP */
+	IEEE80211_FEATURE_IC_COUNTRY_IE,        /* add country IE for ic in AP */
+	IEEE80211_FEATURE_DOTH, /* enable 802.11h */
+	IEEE80211_FEATURE_PURE11N,      /* enable pure 11n  mode */
+	IEEE80211_FEATURE_PRIVATE_RSNIE,        /* enable OS shim to setup RSN IE */
+	IEEE80211_FEATURE_COPY_BEACON,  /* keep a copy of beacon */
+	IEEE80211_FEATURE_PSPOLL,       /* enable/disable pspoll mode in power save SM */
+	IEEE80211_FEATURE_CONTINUE_PSPOLL_FOR_MOREDATA, /* enable/disable option to contunue sending ps polls when there is more data */
+	IEEE80211_FEATURE_AMPDU,        /* Enable or Disable Aggregation */
+#ifdef ATH_COALESCING
+	IEEE80211_FEATURE_TX_COALESCING,        /* enable tx coalescing */
+#endif
+	IEEE80211_FEATURE_VAP_IND,      /* Repeater independent VAP */
+	IEEE80211_FIXED_RETRIES,        /* fixed retries  0-4 */
+	IEEE80211_SHORT_GI,     /* short gi on/off */
+	IEEE80211_HT40_INTOLERANT,
+	IEEE80211_CHWIDTH,
+	IEEE80211_CHEXTOFFSET,
+	IEEE80211_DISABLE_2040COEXIST,
+	IEEE80211_DISABLE_HTPROTECTION,
+	IEEE80211_STA_QUICKKICKOUT,
+	IEEE80211_CHSCANINIT,
+	IEEE80211_FEATURE_STAFWD,       /* dynamic AP Client  feature */
+	IEEE80211_DRIVER_CAPS,
+	IEEE80211_UAPSD_MAXSP,  /* UAPSD service period setting (0:unlimited, 2,4,6) */
+	IEEE80211_WEP_MBSSID,
+	IEEE80211_MGMT_RATE,    /* ieee rate to be used for management */
+	IEEE80211_RESMGR_VAP_AIR_TIME_LIMIT,    /* When multi-channel enabled, restrict air-time allocated to a VAP */
+	IEEE80211_TDLS_MACADDR1,        /* Upper 4 bytes of device's MAC address */
+	IEEE80211_TDLS_MACADDR2,        /* Lower 2 bytes of device's MAC address */
+	IEEE80211_TDLS_ACTION,  /* TDLS action requested                 */
+	IEEE80211_AUTO_ASSOC,
+	IEEE80211_PROTECTION_MODE,      /* per VAP protection mode */
+	IEEE80211_AUTH_INACT_TIMEOUT,   /* inactivity time while waiting for 802.11x auth to complete */
+	IEEE80211_INIT_INACT_TIMEOUT,   /* inactivity time while waiting for 802.11 auth/assoc to complete */
+	IEEE80211_RUN_INACT_TIMEOUT,    /* inactivity time when fully authed */
+	IEEE80211_PROBE_INACT_TIMEOUT,  /* inactivity counter value below which starts probing */
+	IEEE80211_QBSS_LOAD,
+	IEEE80211_WNM_CAP,
+	IEEE80211_WNM_BSS_CAP,
+	IEEE80211_WNM_TFS_CAP,
+	IEEE80211_WNM_TIM_CAP,
+	IEEE80211_WNM_SLEEP_CAP,
+	IEEE80211_WNM_FMS_CAP,
+	IEEE80211_AP_REJECT_DFS_CHAN,   /* AP to reject resuming on DFS Channel */
+	IEEE80211_ABOLT,
+	IEEE80211_COMP,
+	IEEE80211_FF,
+	IEEE80211_TURBO,
+	IEEE80211_BURST,
+	IEEE80211_AR,
+	IEEE80211_SLEEP,
+	IEEE80211_EOSPDROP,
+	IEEE80211_MARKDFS,
+	IEEE80211_WDS_AUTODETECT,
+	IEEE80211_WEP_TKIP_HT,
+	IEEE80211_ATH_RADIO,
+	IEEE80211_IGNORE_11DBEACON,
+	/* Video debug feature */
+	IEEE80211_VI_DBG_CFG,   /* Video debug configuration - Bit0- enable dbg, Bit1 - enable stats log */
+	IEEE80211_VI_DBG_NUM_STREAMS,   /* Total number of receive streams */
+	IEEE80211_VI_STREAM_NUM,        /* the stream number whose marker parameters are being set */
+	IEEE80211_VI_DBG_NUM_MARKERS,   /* total number of markers used to filter pkts */
+	IEEE80211_VI_MARKER_NUM,        /* the marker number whose parameters (offset, size & match) are being set */
+	IEEE80211_VI_MARKER_OFFSET_SIZE,        /* byte offset from skb start (upper 16 bits) & size in bytes(lower 16 bits) */
+	IEEE80211_VI_MARKER_MATCH,      /* marker pattern match used in filtering */
+	IEEE80211_VI_RXSEQ_OFFSET_SIZE, /* Rx Seq num offset skb start (upper 16 bits) & size in bytes(lower 16 bits) */
+	IEEE80211_VI_RX_SEQ_RSHIFT,     /* right-shift value in case field is not word aligned */
+	IEEE80211_VI_RX_SEQ_MAX,        /* maximum Rx Seq number (to check wrap around) */
+	IEEE80211_VI_RX_SEQ_DROP,       /* Indicator to the debug app that a particular seq num has been dropped */
+	IEEE80211_VI_TIME_OFFSET_SIZE,  /* Timestamp offset skb start (upper 16 bits) & size in bytes(lower 16 bits) */
+	IEEE80211_VI_RESTART,   /* If set to 1 resets all internal variables/counters & restarts debug tool */
+	IEEE80211_VI_RXDROP_STATUS,     /* Total RX drops in wireless */
+	IEEE80211_TRIGGER_MLME_RESP,    /* Option for App to trigger mlme response */
+#ifdef ATH_SUPPORT_TxBF
+	IEEE80211_TXBF_AUTO_CVUPDATE,   /* auto CV update enable */
+	IEEE80211_TXBF_CVUPDATE_PER,    /* per threshold to initial CV update */
+#endif
+	IEEE80211_MAX_CLIENT_NUMBERS,
+	IEEE80211_SMARTNET,
+	IEEE80211_FEATURE_MFP_TEST,     /* MFP test */
+	IEEE80211_WEATHER_RADAR,        /* weather radar channel skip */
+	IEEE80211_WEP_KEYCACHE, /* WEP KEYCACHE is enable */
+	IEEE80211_SEND_DEAUTH,  /* send deauth instead of disassoc while doing interface down  */
+	IEEE80211_SET_TXPWRADJUST,
+	IEEE80211_RRM_CAP,
+	IEEE80211_RRM_DEBUG,
+	IEEE80211_RRM_STATS,
+	IEEE80211_RRM_SLWINDOW,
+	IEEE80211_FEATURE_OFF_CHANNEL_SUPPORT,
+	IEEE80211_FIXED_VHT_MCS,        /* VHT mcs index */
+	IEEE80211_FIXED_NSS,    /* Spatial Streams count */
+	IEEE80211_SUPPORT_LDPC, /* LDPC Support */
+	IEEE80211_SUPPORT_TX_STBC,      /* TX STBC enable/disable */
+	IEEE80211_SUPPORT_RX_STBC,      /* RX STBC enable/disable */
+	IEEE80211_DEFAULT_KEYID,        /* XMIT default key */
+	IEEE80211_OPMODE_NOTIFY_ENABLE, /* Op mode notification enable/disable */
+	IEEE80211_ENABLE_RTSCTS,        /* Enable/Disable RTS-CTS */
+	IEEE80211_VHT_MCSMAP,   /* VHT MCS Map */
+	IEEE80211_GET_ACS_STATE,        /* get acs state */
+	IEEE80211_GET_CAC_STATE,        /* get cac state */
+} ieee80211_param;
+
+#define  IEEE80211_PROTECTION_NONE         0
+#define  IEEE80211_PROTECTION_CTSTOSELF    1
+#define  IEEE80211_PROTECTION_RTS_CTS      2
+
+typedef enum _ieee80211_privacy_filter {
+	IEEE80211_PRIVACY_FILTER_ALLWAYS,
+	IEEE80211_PRIVACY_FILTER_KEY_UNAVAILABLE,
+} ieee80211_privacy_filter;
+
+typedef enum _ieee80211_privacy_filter_packet_type {
+	IEEE80211_PRIVACY_FILTER_PACKET_UNICAST,
+	IEEE80211_PRIVACY_FILTER_PACKET_MULTICAST,
+	IEEE80211_PRIVACY_FILTER_PACKET_BOTH
+} ieee80211_privacy_filter_packet_type;
+
+typedef struct _ieee80211_privacy_excemption_filter {
+	uint16_t ether_type;    /* type of ethernet to apply this filter, in host byte order */
+	ieee80211_privacy_filter filter_type;
+	ieee80211_privacy_filter_packet_type packet_type;
+} ieee80211_privacy_exemption;
+
+/*
+ * Authentication mode.
+ * NB: the usage of auth modes NONE, AUTO are deprecated,
+ * they are implemented through combinations of other auth modes
+ * and cipher types. The deprecated values are preserved here to
+ * maintain binary compatibility with applications like
+ * wpa_supplicant and hostapd.
+ */
+typedef enum _ieee80211_auth_mode {
+	IEEE80211_AUTH_NONE = 0,        /* deprecated */
+	IEEE80211_AUTH_OPEN = 1,        /* open */
+	IEEE80211_AUTH_SHARED = 2,      /* shared-key */
+	IEEE80211_AUTH_8021X = 3,       /* 802.1x */
+	IEEE80211_AUTH_AUTO = 4,        /* deprecated */
+	IEEE80211_AUTH_WPA = 5, /* WPA */
+	IEEE80211_AUTH_RSNA = 6,        /* WPA2/RSNA */
+	IEEE80211_AUTH_CCKM = 7,        /* CCK */
+	IEEE80211_AUTH_WAPI = 8,        /* WAPI */
+} ieee80211_auth_mode;
+
+#define IEEE80211_AUTH_MAX      (IEEE80211_AUTH_WAPI+1)
+
+/*
+ * Cipher types.
+ * NB: The values are preserved here to maintain binary compatibility
+ * with applications like wpa_supplicant and hostapd.
+ */
+typedef enum _ieee80211_cipher_type {
+	IEEE80211_CIPHER_WEP = 0,
+	IEEE80211_CIPHER_TKIP = 1,
+	IEEE80211_CIPHER_AES_OCB = 2,
+	IEEE80211_CIPHER_AES_CCM = 3,
+	IEEE80211_CIPHER_WAPI = 4,
+	IEEE80211_CIPHER_CKIP = 5,
+	IEEE80211_CIPHER_AES_CMAC = 6,
+	IEEE80211_CIPHER_NONE = 7,
+} ieee80211_cipher_type;
+
+#define IEEE80211_CIPHER_MAX    (IEEE80211_CIPHER_NONE+1)
+
+/* key direction */
+typedef enum _ieee80211_key_direction {
+	IEEE80211_KEY_DIR_TX,
+	IEEE80211_KEY_DIR_RX,
+	IEEE80211_KEY_DIR_BOTH
+} ieee80211_key_direction;
+
+#define IEEE80211_KEYIX_NONE    ((uint16_t) -1)
+
+typedef struct _ieee80211_keyval {
+	ieee80211_cipher_type keytype;
+	ieee80211_key_direction keydir;
+	u_int persistent : 1,     /* persistent key */
+	      mfp : 1;          /* management frame protection */
+	uint16_t keylen;        /* length of the key data fields */
+	uint8_t *macaddr;       /* mac address of length IEEE80211_ADDR_LEN . all bytes are 0xff for multicast key */
+	uint64_t keyrsc;
+	uint64_t keytsc;
+	uint16_t txmic_offset;  /* TKIP/SMS4 only: offset to tx mic key */
+	uint16_t rxmic_offset;  /* TKIP/SMS4 only: offset to rx mic key */
+	uint8_t *keydata;
+#ifdef ATH_SUPPORT_WAPI
+	uint8_t key_used;       /*index for WAPI rekey labeling */
+#endif
+} ieee80211_keyval;
+
+#define IEEE80211_AES_CMAC_LEN     128
+typedef enum _ieee80211_rsn_param {
+	IEEE80211_UCAST_CIPHER_LEN,
+	IEEE80211_MCAST_CIPHER_LEN,
+	IEEE80211_MCASTMGMT_CIPHER_LEN,
+	IEEE80211_KEYMGT_ALGS,
+	IEEE80211_RSN_CAPS
+} ieee80211_rsn_param;
+
+#define IEEE80211_PMKID_LEN     16
+
+typedef struct _ieee80211_pmkid_entry {
+	uint8_t bssid[IEEE80211_ADDR_LEN];
+	uint8_t pmkid[IEEE80211_PMKID_LEN];
+} ieee80211_pmkid_entry;
+
+typedef enum _wlan_wme_param {
+	WLAN_WME_CWMIN,
+	WLAN_WME_CWMAX,
+	WLAN_WME_AIFS,
+	WLAN_WME_TXOPLIMIT,
+	WLAN_WME_ACM,           /*bss only */
+	WLAN_WME_ACKPOLICY      /*bss only */
+} wlan_wme_param;
+
+typedef enum _ieee80211_frame_type {
+	IEEE80211_FRAME_TYPE_PROBEREQ,
+	IEEE80211_FRAME_TYPE_BEACON,
+	IEEE80211_FRAME_TYPE_PROBERESP,
+	IEEE80211_FRAME_TYPE_ASSOCREQ,
+	IEEE80211_FRAME_TYPE_ASSOCRESP,
+	IEEE80211_FRAME_TYPE_AUTH
+} ieee80211_frame_type;
+
+#define IEEE80211_FRAME_TYPE_MAX    (IEEE80211_FRAME_TYPE_AUTH+1)
+
+typedef enum _ieee80211_ampdu_mode {
+	IEEE80211_AMPDU_MODE_OFF,       /* disable AMPDU */
+	IEEE80211_AMPDU_MODE_ON,        /* enable AMPDU */
+	IEEE80211_AMPDU_MODE_WDSVAR     /* enable AMPDU with 4addr WAR */
+} ieee80211_ampdu_mode;
+
+typedef enum _ieee80211_reset_type {
+	IEEE80211_RESET_TYPE_DEVICE = 0,        /* device reset on error: tx timeout and etc. */
+	IEEE80211_RESET_TYPE_DOT11_INTF,        /* dot11 reset: only reset one network interface (vap) */
+	IEEE80211_RESET_TYPE_INTERNAL,  /* internal reset */
+} ieee80211_reset_type;
+
+typedef struct _ieee80211_reset_request {
+	ieee80211_reset_type type;
+
+	u_int reset_hw : 1,       /* reset the actual H/W */
+	/*
+	 * The following fields are only valid for DOT11 reset, i.e.,
+	 * IEEE80211_RESET_TYPE_DOT11_INTF
+	 */
+	      reset_phy : 1,    /* reset PHY */
+	      reset_mac : 1,    /* reset MAC */
+	      set_default_mib : 1, /* set default MIB variables */
+	      no_flush : 1;
+	uint8_t macaddr[IEEE80211_ADDR_LEN];
+	enum ieee80211_phymode phy_mode;
+} ieee80211_reset_request;
+
+#define IEEE80211_MSG_MAX 63
+#define IEEE80211_MSG_SMARTANT 7        /* Bit 7 (0x80)for Smart Antenna debug */
+enum {
+	/* IEEE80211_PARAM_DBG_LVL */
+	IEEE80211_MSG_TDLS = 0, /* TDLS */
+	IEEE80211_MSG_ACS,      /* auto channel selection */
+	IEEE80211_MSG_SCAN_SM,  /* scan state machine */
+	IEEE80211_MSG_SCANENTRY,        /* scan entry */
+	IEEE80211_MSG_WDS,      /* WDS handling */
+	IEEE80211_MSG_ACTION,   /* action management frames */
+	IEEE80211_MSG_ROAM,     /* sta-mode roaming */
+	IEEE80211_MSG_INACT,    /* inactivity handling */
+	IEEE80211_MSG_DOTH = 8, /* 11.h */
+	IEEE80211_MSG_IQUE,     /* IQUE features */
+	IEEE80211_MSG_WME,      /* WME protocol */
+	IEEE80211_MSG_ACL,      /* ACL handling */
+	IEEE80211_MSG_WPA,      /* WPA/RSN protocol */
+	IEEE80211_MSG_RADKEYS,  /* dump 802.1x keys */
+	IEEE80211_MSG_RADDUMP,  /* dump 802.1x radius packets */
+	IEEE80211_MSG_RADIUS,   /* 802.1x radius client */
+	IEEE80211_MSG_DOT1XSM = 16,     /* 802.1x state machine */
+	IEEE80211_MSG_DOT1X,    /* 802.1x authenticator */
+	IEEE80211_MSG_POWER,    /* power save handling */
+	IEEE80211_MSG_STATE,    /* state machine */
+	IEEE80211_MSG_OUTPUT,   /* output handling */
+	IEEE80211_MSG_SCAN,     /* scanning */
+	IEEE80211_MSG_AUTH,     /* authentication handling */
+	IEEE80211_MSG_ASSOC,    /* association handling */
+	IEEE80211_MSG_NODE = 24,        /* node handling */
+	IEEE80211_MSG_ELEMID,   /* element id parsing */
+	IEEE80211_MSG_XRATE,    /* rate set handling */
+	IEEE80211_MSG_INPUT,    /* input handling */
+	IEEE80211_MSG_CRYPTO,   /* crypto work */
+	IEEE80211_MSG_DUMPPKTS, /* IFF_LINK2 equivalant */
+	IEEE80211_MSG_DEBUG,    /* IFF_DEBUG equivalent */
+	IEEE80211_MSG_MLME,     /* MLME */
+	/* IEEE80211_PARAM_DBG_LVL_HIGH */
+	IEEE80211_MSG_RRM = 32, /* Radio resource measurement */
+	IEEE80211_MSG_WNM,      /* Wireless Network Management */
+	IEEE80211_MSG_P2P_PROT, /* P2P Protocol driver */
+	IEEE80211_MSG_PROXYARP, /* 11v Proxy ARP */
+	IEEE80211_MSG_L2TIF,    /* Hotspot 2.0 L2 TIF */
+	IEEE80211_MSG_WIFIPOS,  /* WifiPositioning Feature */
+	IEEE80211_MSG_WRAP,     /* WRAP or Wireless ProxySTA */
+	IEEE80211_MSG_DFS,      /* DFS debug mesg */
+
+	IEEE80211_MSG_NUM_CATEGORIES,   /* total ieee80211 messages */
+	IEEE80211_MSG_UNMASKABLE = IEEE80211_MSG_MAX,   /* anything */
+	IEEE80211_MSG_ANY = IEEE80211_MSG_MAX,  /* anything */
+};
+
+/* verbosity levels */
+#define     IEEE80211_VERBOSE_OFF                  100
+#define     IEEE80211_VERBOSE_FORCE               1
+#define     IEEE80211_VERBOSE_SERIOUS             2
+#define     IEEE80211_VERBOSE_NORMAL              3
+#define     IEEE80211_VERBOSE_LOUD                4
+#define     IEEE80211_VERBOSE_DETAILED            5
+#define     IEEE80211_VERBOSE_COMPLEX             6
+#define     IEEE80211_VERBOSE_FUNCTION            7
+#define     IEEE80211_VERBOSE_TRACE               8
+
+#define IEEE80211_DEBUG_DEFAULT IEEE80211_MSG_DEBUG
+
+/*
+ * the lower 4 bits of the msg flags are used for extending the
+ * debug flags.
+ */
+
+/*
+ * flag definitions for wlan_mlme_stop_bss(vap) API.
+ */
+#define WLAN_MLME_STOP_BSS_F_SEND_DEAUTH                0x01
+#define WLAN_MLME_STOP_BSS_F_CLEAR_ASSOC_STATE          0x02
+#define WLAN_MLME_STOP_BSS_F_FORCE_STOP_RESET           0x04
+#define WLAN_MLME_STOP_BSS_F_WAIT_RX_DONE               0x08
+#define WLAN_MLME_STOP_BSS_F_NO_RESET                   0x10
+#define WLAN_MLME_STOP_BSS_F_STANDBY                    0x20
+
+/*
+ * WAPI commands to authenticator
+ */
+#define WAPI_WAI_REQUEST            (uint16_t)0x00F1
+#define WAPI_UNICAST_REKEY          (uint16_t)0x00F2
+#define WAPI_STA_AGING              (uint16_t)0x00F3
+#define WAPI_MULTI_REKEY            (uint16_t)0x00F4
+#define WAPI_STA_STATS              (uint16_t)0x00F5
+
+/*
+ * IEEE80211 PHY Statistics.
+ */
+struct ieee80211_phy_stats {
+	uint64_t ips_tx_packets;        /* frames successfully transmitted */
+	uint64_t ips_tx_multicast;      /* multicast/broadcast frames successfully transmitted */
+	uint64_t ips_tx_fragments;      /* fragments successfully transmitted */
+	uint64_t ips_tx_xretries;       /* frames that are xretried. NB: not number of retries */
+	uint64_t ips_tx_retries;        /* frames transmitted after retries. NB: not number of retries */
+	uint64_t ips_tx_multiretries;   /* frames transmitted after more than one retry. */
+	uint64_t ips_tx_timeout;        /* frames that expire the dot11MaxTransmitMSDULifetime */
+	uint64_t ips_rx_packets;        /* frames successfully received */
+	uint64_t ips_rx_multicast;      /* multicast/broadcast frames successfully received */
+	uint64_t ips_rx_fragments;      /* fragments successfully received */
+	uint64_t ips_rx_timeout;        /* frmaes that expired the dot11MaxReceiveLifetime */
+	uint64_t ips_rx_dup;    /* duplicated fragments */
+	uint64_t ips_rx_mdup;   /* multiple duplicated fragments */
+	uint64_t ips_rx_promiscuous;    /* frames that are received only because promiscuous filter is on */
+	uint64_t ips_rx_promiscuous_fragments;  /* fragments that are received only because promiscuous filter is on */
+	uint64_t ips_tx_rts;    /* RTS success count */
+	uint64_t ips_tx_shortretry;     /* tx on-chip retries (short). RTSFailCnt */
+	uint64_t ips_tx_longretry;      /* tx on-chip retries (long). DataFailCnt */
+	uint64_t ips_rx_crcerr; /* rx failed 'cuz of bad CRC */
+	uint64_t ips_rx_fifoerr;        /* rx failed 'cuz of FIFO overrun */
+	uint64_t ips_rx_decrypterr;     /* rx decryption error */
+};
+
+struct ieee80211_chan_stats {
+	uint32_t chan_clr_cnt;
+	uint32_t cycle_cnt;
+	uint32_t phy_err_cnt;
+};
+
+struct ieee80211_mac_stats {
+	uint64_t ims_tx_packets;        /* frames successfully transmitted */
+	uint64_t ims_rx_packets;        /* frames successfully received */
+	uint64_t ims_tx_bytes;  /* bytes successfully transmitted */
+	uint64_t ims_rx_bytes;  /* bytes successfully received */
+
+	/* TODO: For the byte counts below, we need to handle some scenarios
+	   such as encryption related decaps, etc */
+	uint64_t ims_tx_data_packets;   /* data frames successfully transmitted */
+	uint64_t ims_rx_data_packets;   /* data frames successfully received */
+	uint64_t ims_tx_data_bytes;     /* data bytes successfully transmitted,
+	                                   inclusive of FCS. */
+	uint64_t ims_rx_data_bytes;     /* data bytes successfully received,
+	                                   inclusive of FCS. */
+
+	uint64_t ims_tx_datapyld_bytes; /* data payload bytes successfully
+	                                   transmitted */
+	uint64_t ims_rx_datapyld_bytes; /* data payload successfully
+	                                   received */
+
+	/* Decryption errors */
+	uint64_t ims_rx_unencrypted;    /* rx w/o wep and privacy on */
+	uint64_t ims_rx_badkeyid;       /* rx w/ incorrect keyid */
+	uint64_t ims_rx_decryptok;      /* rx decrypt okay */
+	uint64_t ims_rx_decryptcrc;     /* rx decrypt failed on crc */
+	uint64_t ims_rx_wepfail;        /* rx wep processing failed */
+	uint64_t ims_rx_tkipreplay;     /* rx seq# violation (TKIP) */
+	uint64_t ims_rx_tkipformat;     /* rx format bad (TKIP) */
+	uint64_t ims_rx_tkipmic;        /* rx MIC check failed (TKIP) */
+	uint64_t ims_rx_tkipicv;        /* rx ICV check failed (TKIP) */
+	uint64_t ims_rx_ccmpreplay;     /* rx seq# violation (CCMP) */
+	uint64_t ims_rx_ccmpformat;     /* rx format bad (CCMP) */
+	uint64_t ims_rx_ccmpmic;        /* rx MIC check failed (CCMP) */
+/*this file can be included by applications as 80211stats that has no such MACRO definition*/
+/* #if ATH_SUPPORT_WAPI */
+	uint64_t ims_rx_wpireplay;      /* rx seq# violation (WPI) */
+	uint64_t ims_rx_wpimic; /* rx MIC check failed (WPI) */
+/* #endif */
+	/* Other Tx/Rx errors */
+	uint64_t ims_tx_discard;        /* tx dropped by NIC */
+	uint64_t ims_rx_discard;        /* rx dropped by NIC */
+
+	uint64_t ims_rx_countermeasure; /* rx TKIP countermeasure activation count */
+};
+
+/*
+ * Summary statistics.
+ */
+struct ieee80211_stats {
+	uint32_t is_rx_badversion;      /* rx frame with bad version */
+	uint32_t is_rx_tooshort;        /* rx frame too short */
+	uint32_t is_rx_wrongbss;        /* rx from wrong bssid */
+	uint32_t is_rx_wrongdir;        /* rx w/ wrong direction */
+	uint32_t is_rx_mcastecho;       /* rx discard 'cuz mcast echo */
+	uint32_t is_rx_notassoc;        /* rx discard 'cuz sta !assoc */
+	uint32_t is_rx_noprivacy;       /* rx w/ wep but privacy off */
+	uint32_t is_rx_decap;   /* rx decapsulation failed */
+	uint32_t is_rx_mgtdiscard;      /* rx discard mgt frames */
+	uint32_t is_rx_ctl;     /* rx discard ctrl frames */
+	uint32_t is_rx_beacon;  /* rx beacon frames */
+	uint32_t is_rx_rstoobig;        /* rx rate set truncated */
+	uint32_t is_rx_elem_missing;    /* rx required element missing */
+	uint32_t is_rx_elem_toobig;     /* rx element too big */
+	uint32_t is_rx_elem_toosmall;   /* rx element too small */
+	uint32_t is_rx_elem_unknown;    /* rx element unknown */
+	uint32_t is_rx_badchan; /* rx frame w/ invalid chan */
+	uint32_t is_rx_chanmismatch;    /* rx frame chan mismatch */
+	uint32_t is_rx_nodealloc;       /* rx frame dropped */
+	uint32_t is_rx_ssidmismatch;    /* rx frame ssid mismatch  */
+	uint32_t is_rx_auth_unsupported;        /* rx w/ unsupported auth alg */
+	uint32_t is_rx_auth_fail;       /* rx sta auth failure */
+	uint32_t is_rx_auth_countermeasures;    /* rx auth discard 'cuz CM */
+	uint32_t is_rx_assoc_bss;       /* rx assoc from wrong bssid */
+	uint32_t is_rx_assoc_notauth;   /* rx assoc w/o auth */
+	uint32_t is_rx_assoc_capmismatch;       /* rx assoc w/ cap mismatch */
+	uint32_t is_rx_assoc_norate;    /* rx assoc w/ no rate match */
+	uint32_t is_rx_assoc_badwpaie;  /* rx assoc w/ bad WPA IE */
+	uint32_t is_rx_deauth;  /* rx deauthentication */
+	uint32_t is_rx_disassoc;        /* rx disassociation */
+	uint32_t is_rx_action;  /* rx action mgt */
+	uint32_t is_rx_badsubtype;      /* rx frame w/ unknown subtype */
+	uint32_t is_rx_nobuf;   /* rx failed for lack of buf */
+	uint32_t is_rx_ahdemo_mgt;      /* rx discard ahdemo mgt frame */
+	uint32_t is_rx_bad_auth;        /* rx bad auth request */
+	uint32_t is_rx_unauth;  /* rx on unauthorized port */
+	uint32_t is_rx_badcipher;       /* rx failed 'cuz key type */
+	uint32_t is_tx_nodefkey;        /* tx failed 'cuz no defkey */
+	uint32_t is_tx_noheadroom;      /* tx failed 'cuz no space */
+	uint32_t is_rx_nocipherctx;     /* rx failed 'cuz key !setup */
+	uint32_t is_rx_acl;     /* rx discard 'cuz acl policy */
+	uint32_t is_rx_ffcnt;   /* rx fast frames */
+	uint32_t is_rx_badathtnl;       /* driver key alloc failed */
+	uint32_t is_rx_nowds;   /* 4-addr packets received with no wds enabled */
+	uint32_t is_tx_nobuf;   /* tx failed for lack of buf */
+	uint32_t is_tx_nonode;  /* tx failed for no node */
+	uint32_t is_tx_unknownmgt;      /* tx of unknown mgt frame */
+	uint32_t is_tx_badcipher;       /* tx failed 'cuz key type */
+	uint32_t is_tx_ffokcnt; /* tx fast frames sent success */
+	uint32_t is_tx_fferrcnt;        /* tx fast frames sent success */
+	uint32_t is_scan_active;        /* active scans started */
+	uint32_t is_scan_passive;       /* passive scans started */
+	uint32_t is_node_timeout;       /* nodes timed out inactivity */
+	uint32_t is_crypto_nomem;       /* no memory for crypto ctx */
+	uint32_t is_crypto_tkip;        /* tkip crypto done in s/w */
+	uint32_t is_crypto_tkipenmic;   /* tkip en-MIC done in s/w */
+	uint32_t is_crypto_tkipdemic;   /* tkip de-MIC done in s/w */
+	uint32_t is_crypto_tkipcm;      /* tkip counter measures */
+	uint32_t is_crypto_ccmp;        /* ccmp crypto done in s/w */
+	uint32_t is_crypto_wep; /* wep crypto done in s/w */
+	uint32_t is_crypto_setkey_cipher;       /* cipher rejected key */
+	uint32_t is_crypto_setkey_nokey;        /* no key index for setkey */
+	uint32_t is_crypto_delkey;      /* driver key delete failed */
+	uint32_t is_crypto_badcipher;   /* unknown cipher */
+	uint32_t is_crypto_nocipher;    /* cipher not available */
+	uint32_t is_crypto_attachfail;  /* cipher attach failed */
+	uint32_t is_crypto_swfallback;  /* cipher fallback to s/w */
+	uint32_t is_crypto_keyfail;     /* driver key alloc failed */
+	uint32_t is_crypto_enmicfail;   /* en-MIC failed */
+	uint32_t is_ibss_capmismatch;   /* merge failed-cap mismatch */
+	uint32_t is_ibss_norate;        /* merge failed-rate mismatch */
+	uint32_t is_ps_unassoc; /* ps-poll for unassoc. sta */
+	uint32_t is_ps_badaid;  /* ps-poll w/ incorrect aid */
+	uint32_t is_ps_qempty;  /* ps-poll w/ nothing to send */
+};
+
+typedef enum _ieee80211_send_frame_type {
+	IEEE80211_SEND_NULL,
+	IEEE80211_SEND_QOSNULL,
+} ieee80211_send_frame_type;
+
+typedef struct _ieee80211_tspec_info {
+	uint8_t traffic_type;
+	uint8_t direction;
+	uint8_t dot1Dtag;
+	uint8_t tid;
+	uint8_t acc_policy_edca;
+	uint8_t acc_policy_hcca;
+	uint8_t aggregation;
+	uint8_t psb;
+	uint8_t ack_policy;
+	uint16_t norminal_msdu_size;
+	uint16_t max_msdu_size;
+	uint32_t min_srv_interval;
+	uint32_t max_srv_interval;
+	uint32_t inactivity_interval;
+	uint32_t suspension_interval;
+	uint32_t srv_start_time;
+	uint32_t min_data_rate;
+	uint32_t mean_data_rate;
+	uint32_t peak_data_rate;
+	uint32_t max_burst_size;
+	uint32_t delay_bound;
+	uint32_t min_phy_rate;
+	uint16_t surplus_bw;
+	uint16_t medium_time;
+} ieee80211_tspec_info;
+
+#ifndef EXTERNAL_USE_ONLY
+/*
+ * Manual ADDBA support
+ */
+enum {
+	ADDBA_SEND = 0,
+	ADDBA_STATUS = 1,
+	DELBA_SEND = 2,
+	ADDBA_RESP = 3,
+	ADDBA_CLR_RESP = 4,
+	SINGLE_AMSDU = 5,
+};
+
+enum {
+	ADDBA_MODE_AUTO = 0,
+	ADDBA_MODE_MANUAL = 1,
+};
+
+struct ieee80211_addba_delba_request {
+	wlan_dev_t ic;
+	uint8_t action;
+	uint8_t tid;
+	uint16_t status;
+	uint16_t aid;
+	uint32_t arg1;
+	uint32_t arg2;
+};
+#endif /* EXTERNAL_USE_ONLY */
+
+#ifdef ATH_BT_COEX
+typedef enum _ieee80211_bt_coex_info_type {
+	IEEE80211_BT_COEX_INFO_SCHEME = 0,
+	IEEE80211_BT_COEX_INFO_BTBUSY = 1,
+} ieee80211_bt_coex_info_type;
+#endif
+
+struct tkip_countermeasure {
+	uint16_t mic_count_in_60s;
+	uint32_t timestamp;
+};
+
+enum _ieee80211_qos_frame_direction {
+	IEEE80211_RX_QOS_FRAME = 0,
+	IEEE80211_TX_QOS_FRAME = 1,
+	IEEE80211_TX_COMPLETE_QOS_FRAME = 2
+};
+
+typedef struct ieee80211_vap_opmode_count {
+	int total_vaps;
+	int ibss_count;
+	int sta_count;
+	int wds_count;
+	int ahdemo_count;
+	int ap_count;
+	int monitor_count;
+	int btamp_count;
+	int unknown_count;
+} ieee80211_vap_opmode_count;
+
+struct ieee80211_app_ie_t {
+	uint32_t length;
+	uint8_t *ie;
+};
+
+/*
+ * MAC ACL operations.
+ */
+enum {
+	IEEE80211_MACCMD_POLICY_OPEN = 0,       /* set policy: no ACL's */
+	IEEE80211_MACCMD_POLICY_ALLOW = 1,      /* set policy: allow traffic */
+	IEEE80211_MACCMD_POLICY_DENY = 2,       /* set policy: deny traffic */
+	IEEE80211_MACCMD_FLUSH = 3,     /* flush ACL database */
+	IEEE80211_MACCMD_DETACH = 4,    /* detach ACL policy */
+	IEEE80211_MACCMD_POLICY_RADIUS = 5,     /* set policy: RADIUS managed ACLs */
+};
+
+#endif
diff --git a/core/cds/inc/cds_if_upperproto.h b/core/cds/inc/cds_if_upperproto.h
new file mode 100644
index 0000000..26c723b
--- /dev/null
+++ b/core/cds/inc/cds_if_upperproto.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2011, 2014, 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.
+ */
+
+/* #ifndef _NET_IF_ETHERSUBR_H_ */
+/* #define _NET_IF_ETHERSUBR_H_ */
+#ifndef _NET_IF_UPPERPROTO_H_
+#define _NET_IF_UPPERPROTO_H_
+
+#define ETHER_ADDR_LEN    6     /* length of an Ethernet address */
+#define ETHER_TYPE_LEN    2     /* length of the Ethernet type field */
+#define ETHER_CRC_LEN     4     /* length of the Ethernet CRC */
+#define ETHER_HDR_LEN     (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN)
+#define ETHER_MAX_LEN     1518
+
+#define ETHERMTU          (ETHER_MAX_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
+
+/*
+ * Structure of a 10Mb/s Ethernet header.
+ */
+#ifndef _NET_ETHERNET_H_
+struct ether_header {
+	uint8_t ether_dhost[ETHER_ADDR_LEN];
+	uint8_t ether_shost[ETHER_ADDR_LEN];
+	uint16_t ether_type;
+} __packed;
+#endif
+
+#ifndef ETHERTYPE_PAE
+#define ETHERTYPE_PAE    0x888e /* EAPOL PAE/802.1x */
+#endif
+#ifndef ETHERTYPE_IP
+#define ETHERTYPE_IP     0x0800 /* IP protocol */
+#endif
+#ifndef ETHERTYPE_AARP
+#define ETHERTYPE_AARP  0x80f3  /* Appletalk AARP protocol */
+#endif
+#ifndef ETHERTYPE_IPX
+#define ETHERTYPE_IPX    0x8137 /* IPX over DIX protocol */
+#endif
+#ifndef ETHERTYPE_ARP
+#define ETHERTYPE_ARP    0x0806 /* ARP protocol */
+#endif
+#ifndef ETHERTYPE_IPV6
+#define ETHERTYPE_IPV6   0x86dd /* IPv6 */
+#endif
+#ifndef ETHERTYPE_8021Q
+#define ETHERTYPE_8021Q 0x8100  /* 802.1Q vlan protocol */
+#endif
+#ifndef ETHERTYPE_VLAN
+#define ETHERTYPE_VLAN  0x8100  /* VLAN TAG protocol */
+#endif
+#ifndef TX_QUEUE_FOR_EAPOL_FRAME
+#define TX_QUEUE_FOR_EAPOL_FRAME  0x7   /* queue eapol frame to queue 7 to avoid aggregation disorder */
+#endif
+
+/*
+ * define WAI ethertype
+ */
+#ifndef ETHERTYPE_WAI
+#define ETHERTYPE_WAI    0x88b4 /* WAI/WAPI */
+#endif
+
+#define ETHERTYPE_OCB_TX   0x8151
+#define ETHERTYPE_OCB_RX   0x8152
+
+/*
+ * Structure of a 48-bit Ethernet address.
+ */
+#if 0
+#ifndef _NET_ETHERNET_H_
+struct ether_addr {
+	uint8_t octet[ETHER_ADDR_LEN];
+} __packed;
+#endif
+#endif
+
+#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01)       /* is address mcast/bcast? */
+
+#define VLAN_PRI_SHIFT  13      /* Shift to find VLAN user priority */
+#define VLAN_PRI_MASK    7      /* Mask for user priority bits in VLAN */
+
+/*
+ * Structure of the IP frame
+ */
+struct ip_header {
+	uint8_t version_ihl;
+	uint8_t tos;
+	uint16_t tot_len;
+	uint16_t id;
+	uint16_t frag_off;
+	uint8_t ttl;
+	uint8_t protocol;
+	uint16_t check;
+	uint32_t saddr;
+	uint32_t daddr;
+	/*The options start here. */
+};
+#ifndef IP_PROTO_TCP
+#define IP_PROTO_TCP    0x6     /* TCP protocol */
+#endif
+#ifndef IP_PROTO_UDP
+#define IP_PROTO_UDP 17
+#endif
+
+/*
+ *   IGMP protocol structures
+ */
+
+/* IGMP record type */
+#define IGMP_QUERY_TYPE       0x11
+#define IGMPV1_REPORT_TYPE    0x12
+#define IGMPV2_REPORT_TYPE    0x16
+#define IGMPV2_LEAVE_TYPE     0x17
+#define IGMPV3_REPORT_TYPE    0x22
+
+/* Is packet type is either leave or report */
+#define IS_IGMP_REPORT_LEAVE_PACKET(type) ( \
+		(IGMPV1_REPORT_TYPE == type) \
+		|| (IGMPV2_REPORT_TYPE == type)	\
+		|| (IGMPV2_LEAVE_TYPE  == type)	\
+		|| (IGMPV3_REPORT_TYPE == type)	\
+		)
+/*
+ *    Header in on cable format
+ */
+
+struct igmp_header {
+	uint8_t type;
+	uint8_t code;           /* For newer IGMP */
+	uint16_t csum;
+	uint32_t group;
+};
+
+/* V3 group record types [grec_type] */
+#define IGMPV3_MODE_IS_INCLUDE        1
+#define IGMPV3_MODE_IS_EXCLUDE        2
+#define IGMPV3_CHANGE_TO_INCLUDE      3
+#define IGMPV3_CHANGE_TO_EXCLUDE      4
+#define IGMPV3_ALLOW_NEW_SOURCES      5
+#define IGMPV3_BLOCK_OLD_SOURCES      6
+
+/*  Group record format
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |  Record Type  |  Aux Data Len |     Number of Sources (N)     |
+ ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |                       Multicast Address                       |
+ ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |                       Source Address [1]                      |
+ ||+-                                                             -+
+ |                       Source Address [2]                      |
+ ||+-                                                             -+
+      .                               .                               .
+      .                               .                               .
+      .                               .                               .
+ ||+-                                                             -+
+ |                       Source Address [N]                      |
+ ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |                                                               |
+      .                                                               .
+      .                         Auxiliary Data                        .
+      .                                                               .
+ |                                                               |
+ ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct igmp_v3_grec {
+	uint8_t grec_type;
+	uint8_t grec_auxwords;
+	uint16_t grec_nsrcs;
+	uint32_t grec_mca;
+};
+
+/* IGMPv3 report format
+       0                   1                   2                   3
+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |  Type = 0x22  |    Reserved   |           Checksum            |
+ ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |           Reserved            |  Number of Group Records (M)  |
+ ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |                                                               |
+      .                                                               .
+      .                        Group Record [1]                       .
+      .                                                               .
+ |                                                               |
+ ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |                                                               |
+      .                                                               .
+      .                        Group Record [2]                       .
+      .                                                               .
+ |                                                               |
+ ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |                               .                               |
+      .                               .                               .
+ |                               .                               |
+ ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |                                                               |
+      .                                                               .
+      .                        Group Record [M]                       .
+      .                                                               .
+ |                                                               |
+ ||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct igmp_v3_report {
+	uint8_t type;
+	uint8_t resv1;
+	uint16_t csum;
+	uint16_t resv2;
+	uint16_t ngrec;
+};
+
+/* Calculate the group record length*/
+#define IGMPV3_GRP_REC_LEN(x) (8 + (4 * x->grec_nsrcs) + (4 * x->grec_auxwords))
+
+#endif /* _NET_IF_ETHERSUBR_H_ */
diff --git a/core/cds/inc/cds_packet.h b/core/cds/inc/cds_packet.h
new file mode 100644
index 0000000..07ac3a7
--- /dev/null
+++ b/core/cds/inc/cds_packet.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2014-2016 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.
+ */
+
+#if !defined(__CDS_PKT_H)
+#define __CDS_PKT_H
+
+/**=========================================================================
+
+   \file        cds_packet.h
+
+   \brief       Connectivity driver services (CDS) network Packet APIs
+
+   Network Protocol packet/buffer support interfaces
+
+   ========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include <qdf_types.h>
+#include <qdf_status.h>
+
+/*--------------------------------------------------------------------------
+   Preprocessor definitions and constants
+   ------------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------------
+   Type declarations
+   ------------------------------------------------------------------------*/
+struct cds_pkt_t;
+typedef struct cds_pkt_t cds_pkt_t;
+
+#include "qdf_nbuf.h"
+
+/**
+ * cds_pkt_return_packet  Free the cds Packet
+ * @ cds Packet
+ */
+QDF_STATUS cds_pkt_return_packet(cds_pkt_t *packet);
+
+/**
+ * cds_pkt_get_packet_length  Returns the packet length
+ * @ cds Packet
+ */
+QDF_STATUS cds_pkt_get_packet_length(cds_pkt_t *pPacket,
+				     uint16_t *pPacketSize);
+
+/*
+ * TODO: Remove later
+ * All the below difinitions are not
+ * required for Host Driver 2.0
+ * once corresponding references are removed
+ * from HDD and other layers
+ * below code will be removed
+ */
+/* The size of AMSDU frame per spec can be a max of 3839 bytes
+   in BD/PDUs that means 30 (one BD = 128 bytes)
+   we must add the size of the 802.11 header to that */
+#define CDS_PKT_SIZE_BUFFER  ((30 * 128) + 32)
+
+/* cds Packet Types */
+typedef enum {
+	/* cds Packet is used to transmit 802.11 Management frames. */
+	CDS_PKT_TYPE_TX_802_11_MGMT,
+
+	/* cds Packet is used to transmit 802.11 Data frames. */
+	CDS_PKT_TYPE_TX_802_11_DATA,
+
+	/* cds Packet is used to transmit 802.3 Data frames. */
+	CDS_PKT_TYPE_TX_802_3_DATA,
+
+	/* cds Packet contains Received data of an unknown frame type */
+	CDS_PKT_TYPE_RX_RAW,
+
+	/* Invalid sentinel value */
+	CDS_PKT_TYPE_MAXIMUM
+} CDS_PKT_TYPE;
+
+/* user IDs.   These IDs are needed on the cds_pkt_get/set_user_data_ptr()
+   to identify the user area in the cds Packet. */
+typedef enum {
+	CDS_PKT_USER_DATA_ID_TL = 0,
+	CDS_PKT_USER_DATA_ID_BAL,
+	CDS_PKT_USER_DATA_ID_WMA,
+	CDS_PKT_USER_DATA_ID_HDD,
+	CDS_PKT_USER_DATA_ID_BSL,
+
+	CDS_PKT_USER_DATA_ID_MAX
+} CDS_PKT_USER_DATA_ID;
+
+#ifdef MEMORY_DEBUG
+#define cds_packet_alloc(s, d, p)	\
+	cds_packet_alloc_debug(s, d, p, __FILE__, __LINE__)
+
+QDF_STATUS cds_packet_alloc_debug(uint16_t size, void **data, void **ppPacket,
+				  uint8_t *file_name, uint32_t line_num);
+#else
+QDF_STATUS cds_packet_alloc(uint16_t size, void **data, void **ppPacket);
+#endif
+
+void cds_packet_free(void *pPacket);
+
+typedef QDF_STATUS (*cds_pkt_get_packet_callback)(cds_pkt_t *pPacket,
+						  void *userData);
+
+#endif /* !defined( __CDS_PKT_H ) */
diff --git a/core/cds/inc/cds_queue.h b/core/cds/inc/cds_queue.h
new file mode 100644
index 0000000..0487edb
--- /dev/null
+++ b/core/cds/inc/cds_queue.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013-2015 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.
+ */
+
+#ifndef _CDS_QUEUE_H
+#define _CDS_QUEUE_H
+
+#include <queue.h> /* include BSD queue */
+
+#endif /* end of _CDS_QUEUE_H */
diff --git a/core/cds/inc/cds_reg_service.h b/core/cds/inc/cds_reg_service.h
new file mode 100644
index 0000000..0888d58
--- /dev/null
+++ b/core/cds/inc/cds_reg_service.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014-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.
+ */
+
+#if !defined __CDS_REG_SERVICE_H
+#define __CDS_REG_SERVICE_H
+
+/**=========================================================================
+
+   \file  cds_reg_service.h
+
+   \brief Connectivity driver services (CDS): Non-Volatile storage API
+
+   ========================================================================*/
+
+#include "qdf_status.h"
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+
+#define CDS_COUNTRY_CODE_LEN  2
+#define CDS_MAC_ADDRESS_LEN 6
+#define CDS_SBS_SEPARATION_THRESHOLD 100
+#define HT40PLUS_2G_FCC_CH_END       7
+#define HT40PLUS_2G_EURJAP_CH_END    9
+#define HT40MINUS_2G_CH_START        5
+#define HT40MINUS_2G_CH_END          13
+
+/**
+ * cds_get_vendor_reg_flags() - This API returns vendor specific regulatory
+ * channel flags
+ * @pdev: pdev pointer
+ * @chan: channel number
+ * @bandwidth: channel BW
+ * @is_ht_enabled: HT enabled/disabled flag
+ * @is_vht_enabled: VHT enabled/disabled flag
+ * @sub_20_channel_width: Sub 20 channel bandwidth
+ * Return: channel flags
+ */
+uint32_t cds_get_vendor_reg_flags(struct wlan_objmgr_pdev *pdev, uint32_t chan,
+				  uint16_t bandwidth,
+				  bool is_ht_enabled, bool is_vht_enabled,
+				  uint8_t sub_20_channel_width);
+#endif /* __CDS_REG_SERVICE_H */
diff --git a/core/cds/inc/cds_regdomain.h b/core/cds/inc/cds_regdomain.h
new file mode 100644
index 0000000..5c54829
--- /dev/null
+++ b/core/cds/inc/cds_regdomain.h
@@ -0,0 +1,522 @@
+/*
+ * Copyright (c) 2011, 2014-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.
+ */
+
+/*
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
+ * Copyright (c) 2005-2006 Atheros Communications, Inc.
+ * Copyright (c) 2010, Atheros Communications Inc.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the following conditions are met:
+ * 1. The materials contained herein are unmodified and are used
+ *    unmodified.
+ * 2. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following NO
+ *    ''WARRANTY'' disclaimer below (''Disclaimer''), without
+ *    modification.
+ * 3. Redistributions in binary form must reproduce at minimum a
+ *    disclaimer similar to the Disclaimer below and any redistribution
+ *    must be conditioned upon including a substantially similar
+ *    Disclaimer requirement for further binary redistribution.
+ * 4. Neither the names of the above-listed copyright holders nor the
+ *    names of any contributors may be used to endorse or promote
+ *    product derived from this software without specific prior written
+ *    permission.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
+ * FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ *
+ * This module contains the regulatory domain private structure definitions .
+ *
+ */
+
+#ifndef __CDS_REGDOMAIN_H
+#define __CDS_REGDOMAIN_H
+
+#include <reg_services_public_struct.h>
+
+#define MIN_TX_PWR_CAP    8
+#define MAX_TX_PWR_CAP    22
+
+#define CTRY_DEFAULT          0
+#define CTRY_FLAG             0x8000
+#define WORLD_ROAMING_FLAG    0x4000
+#define WORLD_ROAMING_MASK    0x00F0
+#define WORLD_ROAMING_PREFIX  0x0060
+
+enum country_code {
+	CTRY_AFGHANISTAN = 4,
+	CTRY_ALBANIA = 8,
+	CTRY_ALGERIA = 12,
+	CTRY_AMERICAN_SAMOA = 16,
+	CTRY_ANGUILLA = 660,
+	CTRY_ARGENTINA = 32,
+	CTRY_ARGENTINA_AP = 5003,
+	CTRY_ARMENIA = 51,
+	CTRY_ARUBA = 533,
+	CTRY_AUSTRALIA = 36,
+	CTRY_AUSTRALIA_AP = 5000,
+	CTRY_AUSTRIA = 40,
+	CTRY_AZERBAIJAN = 31,
+	CTRY_BAHAMAS = 44,
+	CTRY_BAHRAIN = 48,
+	CTRY_BANGLADESH = 50,
+	CTRY_BARBADOS = 52,
+	CTRY_BELARUS = 112,
+	CTRY_BELGIUM = 56,
+	CTRY_BELIZE = 84,
+	CTRY_BERMUDA = 60,
+	CTRY_BHUTAN = 64,
+	CTRY_BOLIVIA = 68,
+	CTRY_BOSNIA_HERZ = 70,
+	CTRY_BRAZIL = 76,
+	CTRY_BRUNEI_DARUSSALAM = 96,
+	CTRY_BULGARIA = 100,
+	CTRY_BURKINA_FASO = 854,
+	CTRY_CAMBODIA = 116,
+	CTRY_CANADA = 124,
+	CTRY_CANADA_AP = 5001,
+	CTRY_CAYMAN_ISLANDS = 136,
+	CTRY_CENTRAL_AFRICA_REPUBLIC = 140,
+	CTRY_CHAD = 148,
+	CTRY_CHILE = 152,
+	CTRY_CHINA = 156,
+	CTRY_CHRISTMAS_ISLAND = 162,
+	CTRY_COLOMBIA = 170,
+	CTRY_COSTA_RICA = 188,
+	CTRY_COTE_DIVOIRE = 384,
+	CTRY_CROATIA = 191,
+	CTRY_CYPRUS = 196,
+	CTRY_CZECH = 203,
+	CTRY_DENMARK = 208,
+	CTRY_DOMINICA = 212,
+	CTRY_DOMINICAN_REPUBLIC = 214,
+	CTRY_ECUADOR = 218,
+	CTRY_EGYPT = 818,
+	CTRY_EL_SALVADOR = 222,
+	CTRY_ESTONIA = 233,
+	CTRY_ETHIOPIA = 231,
+	CTRY_FINLAND = 246,
+	CTRY_FRANCE = 250,
+	CTRY_FRENCH_GUIANA = 254,
+	CTRY_FRENCH_POLYNESIA = 258,
+	CTRY_GEORGIA = 268,
+	CTRY_GERMANY = 276,
+	CTRY_GHANA = 288,
+	CTRY_GIBRALTAR = 292,
+	CTRY_GREECE = 300,
+	CTRY_GREENLAND = 304,
+	CTRY_GRENADA = 308,
+	CTRY_GUADELOUPE = 312,
+	CTRY_GUAM = 316,
+	CTRY_GUATEMALA = 320,
+	CTRY_GUYANA = 328,
+	CTRY_HAITI = 332,
+	CTRY_HONDURAS = 340,
+	CTRY_HONG_KONG = 344,
+	CTRY_HUNGARY = 348,
+	CTRY_ICELAND = 352,
+	CTRY_INDIA = 356,
+	CTRY_INDONESIA = 360,
+	CTRY_IRAQ = 368,
+	CTRY_IRELAND = 372,
+	CTRY_ISRAEL = 376,
+	CTRY_ITALY = 380,
+	CTRY_JAMAICA = 388,
+	CTRY_JORDAN = 400,
+	CTRY_KAZAKHSTAN = 398,
+	CTRY_KENYA = 404,
+	CTRY_KOREA_ROC = 410,
+	CTRY_KOREA_ROC_AP = 412,
+	CTRY_KUWAIT = 414,
+	CTRY_LATVIA = 428,
+	CTRY_LEBANON = 422,
+	CTRY_LESOTHO = 426,
+	CTRY_LIBYA = 434,
+	CTRY_LIECHTENSTEIN = 438,
+	CTRY_LITHUANIA = 440,
+	CTRY_LUXEMBOURG = 442,
+	CTRY_MACAU = 446,
+	CTRY_MACEDONIA = 807,
+	CTRY_MALAWI = 454,
+	CTRY_MALAYSIA = 458,
+	CTRY_MALDIVES = 462,
+	CTRY_MALTA = 470,
+	CTRY_MARSHALL_ISLANDS = 584,
+	CTRY_MARTINIQUE = 474,
+	CTRY_MAURITANIA = 478,
+	CTRY_MAURITIUS = 480,
+	CTRY_MAYOTTE = 175,
+	CTRY_MEXICO = 484,
+	CTRY_MICRONESIA = 583,
+	CTRY_MOLDOVA = 498,
+	CTRY_MONACO = 492,
+	CTRY_MONGOLIA = 496,
+	CTRY_MONTENEGRO = 499,
+	CTRY_MOROCCO = 504,
+	CTRY_NAMIBIA = 516,
+	CTRY_NEPAL = 524,
+	CTRY_NETHERLANDS = 528,
+	CTRY_NETHERLANDS_ANTILLES = 530,
+	CTRY_NEW_ZEALAND = 554,
+	CTRY_NIGERIA = 566,
+	CTRY_NORTHERN_MARIANA_ISLANDS = 580,
+	CTRY_NICARAGUA = 558,
+	CTRY_NORWAY = 578,
+	CTRY_OMAN = 512,
+	CTRY_PAKISTAN = 586,
+	CTRY_PALAU = 585,
+	CTRY_PANAMA = 591,
+	CTRY_PAPUA_NEW_GUINEA = 598,
+	CTRY_PARAGUAY = 600,
+	CTRY_PERU = 604,
+	CTRY_PHILIPPINES = 608,
+	CTRY_POLAND = 616,
+	CTRY_PORTUGAL = 620,
+	CTRY_PUERTO_RICO = 630,
+	CTRY_QATAR = 634,
+	CTRY_REUNION = 638,
+	CTRY_ROMANIA = 642,
+	CTRY_RUSSIA = 643,
+	CTRY_RWANDA = 646,
+	CTRY_SAINT_BARTHELEMY = 652,
+	CTRY_SAINT_KITTS_AND_NEVIS = 659,
+	CTRY_SAINT_LUCIA = 662,
+	CTRY_SAINT_MARTIN = 663,
+	CTRY_SAINT_PIERRE_AND_MIQUELON = 666,
+	CTRY_SAINT_VINCENT_AND_THE_GRENADIENS = 670,
+	CTRY_SAMOA = 882,
+	CTRY_SAUDI_ARABIA = 682,
+	CTRY_SENEGAL = 686,
+	CTRY_SERBIA = 688,
+	CTRY_SINGAPORE = 702,
+	CTRY_SLOVAKIA = 703,
+	CTRY_SLOVENIA = 705,
+	CTRY_SOUTH_AFRICA = 710,
+	CTRY_SPAIN = 724,
+	CTRY_SURINAME = 740,
+	CTRY_SRI_LANKA = 144,
+	CTRY_SWEDEN = 752,
+	CTRY_SWITZERLAND = 756,
+	CTRY_TAIWAN = 158,
+	CTRY_TANZANIA = 834,
+	CTRY_THAILAND = 764,
+	CTRY_TOGO = 768,
+	CTRY_TRINIDAD_Y_TOBAGO = 780,
+	CTRY_TUNISIA = 788,
+	CTRY_TURKEY = 792,
+	CTRY_TURKS_AND_CAICOS = 796,
+	CTRY_UGANDA = 800,
+	CTRY_UKRAINE = 804,
+	CTRY_UAE = 784,
+	CTRY_UNITED_KINGDOM = 826,
+	CTRY_UNITED_STATES = 840,
+	CTRY_UNITED_STATES_AP = 841,
+	CTRY_UNITED_STATES_AP2 = 843,
+	CTRY_UNITED_STATES_PS = 842,
+	CTRY_URUGUAY = 858,
+	CTRY_UZBEKISTAN = 860,
+	CTRY_VANUATU = 548,
+	CTRY_VENEZUELA = 862,
+	CTRY_VIET_NAM = 704,
+	CTRY_VIRGIN_ISLANDS = 850,
+	CTRY_WALLIS_AND_FUTUNA = 876,
+	CTRY_YEMEN = 887,
+	CTRY_ZIMBABWE = 716,
+	CTRY_JAPAN9 = 4009,
+	CTRY_JAPAN15 = 4015,
+	CTRY_JAPAN48 = 4048,
+	CTRY_JAPAN55 = 4055,
+	CTRY_JAPAN60 = 4060,
+	CTRY_XA = 4100,
+};
+
+enum reg_domain {
+	NO_ENUMRD = 0x00,
+	NULL1_WORLD = 0x03,
+	NULL1_ETSIB = 0x07,
+	NULL1_ETSIC = 0x08,
+
+	FCC1_FCCA = 0x10,
+	FCC1_WORLD = 0x11,
+	FCC2_FCCA = 0x20,
+	FCC2_WORLD = 0x21,
+	FCC2_ETSIC = 0x22,
+	FCC3_FCCA = 0x3A,
+	FCC3_WORLD = 0x3B,
+	FCC3_ETSIC = 0x3F,
+	FCC4_FCCA = 0x12,
+	FCC5_FCCA = 0x13,
+	FCC6_FCCA = 0x14,
+	FCC7_FCCA = 0x15,
+	FCC8_FCCA = 0x16,
+	FCC6_WORLD = 0x23,
+	FCC9_FCCA = 0x17,
+	FCC10_FCCA = 0x18,
+	FCC11_WORLD = 0x19,
+	FCC13_WORLD = 0xE4,
+	FCC14_FCCB = 0xE6,
+
+	ETSI1_WORLD = 0x37,
+	ETSI3_ETSIA = 0x32,
+	ETSI2_WORLD = 0x35,
+	ETSI3_WORLD = 0x36,
+	ETSI4_WORLD = 0x30,
+	ETSI4_ETSIC = 0x38,
+	ETSI5_WORLD = 0x39,
+	ETSI6_WORLD = 0x34,
+	ETSI_RESERVED = 0x33,
+	FRANCE_RES = 0x31,
+	ETSI7_WORLD = 0x3C,
+	ETSI8_WORLD = 0x3D,
+	ETSI9_WORLD = 0x3E,
+	ETSI10_WORLD = 0x24,
+	ETSI11_WORLD = 0x26,
+
+	APL4_WORLD = 0x42,
+	APL3_FCCA = 0x50,
+	APL_RESERVED = 0x44,
+	APL2_WORLD = 0x45,
+	APL2_FCCA = 0x4D,
+	APL2_APLC = 0x46,
+	APL3_WORLD = 0x47,
+	APL2_APLD = 0x49,
+	APL1_WORLD = 0x52,
+	APL1_FCCA = 0x53,
+	APL1_APLA = 0x54,
+	APL1_ETSIC = 0x55,
+	APL2_ETSIC = 0x56,
+	APL5_WORLD = 0x58,
+	APL6_WORLD = 0x5B,
+	APL7_FCCA = 0x5C,
+	APL8_WORLD = 0x5D,
+	APL9_WORLD = 0x5E,
+	APL10_WORLD = 0x5F,
+	APL11_FCCA = 0x4F,
+	APL12_WORLD = 0x51,
+	APL13_WORLD = 0x5A,
+	APL14_WORLD = 0x57,
+	APL15_WORLD = 0x59,
+	APL16_WORLD = 0x70,
+	APL17_ETSID = 0xE0,
+	APL20_WORLD = 0xE5,
+	APL23_WORLD = 0xE3,
+
+	WOR0_WORLD = 0x60,
+	WOR1_WORLD = 0x61,
+	WOR2_WORLD = 0x62,
+	WOR3_WORLD = 0x63,
+	WOR4_FCCA = 0x64,
+	WOR5_ETSIC = 0x65,
+	WOR01_WORLD = 0x66,
+	WOR02_WORLD = 0x67,
+	EU1_WORLD = 0x68,
+	WOR9_WORLD = 0x69,
+	WORA_WORLD = 0x6A,
+	WORB_WORLD = 0x6B,
+	WORC_WORLD = 0x6C,
+
+	MKK3_MKKB = 0x80,
+	MKK3_MKKA2 = 0x81,
+	MKK3_MKKC = 0x82,
+	MKK4_MKKB = 0x83,
+	MKK4_MKKA2 = 0x84,
+	MKK4_MKKC = 0x85,
+	MKK5_MKKA = 0x99,
+	MKK5_FCCA = 0x9A,
+	MKK5_MKKB = 0x86,
+	MKK5_MKKA2 = 0x87,
+	MKK5_MKKC = 0x88,
+	MKK3_MKKA = 0xF0,
+	MKK3_MKKA1 = 0xF1,
+	MKK3_FCCA = 0xF2,
+	MKK4_MKKA = 0xF3,
+	MKK4_MKKA1 = 0xF4,
+	MKK4_FCCA = 0xF5,
+	MKK9_MKKA = 0xF6,
+	MKK9_FCCA = 0xFC,
+	MKK9_MKKA1 = 0xFD,
+	MKK9_MKKC = 0xFE,
+	MKK9_MKKA2 = 0xFF,
+	MKK10_MKKA = 0xF7,
+	MKK10_FCCA = 0xD0,
+	MKK10_MKKA1 = 0xD1,
+	MKK10_MKKC = 0xD2,
+	MKK10_MKKA2 = 0xD3,
+	MKK11_MKKA = 0xD4,
+	MKK11_FCCA = 0xD5,
+	MKK11_MKKA1 = 0xD6,
+	MKK11_MKKC = 0xD7,
+	MKK11_MKKA2 = 0xD8,
+	MKK16_MKKC = 0xDF,
+
+	FCC1 = 0x0110,
+	FCC2 = 0x0120,
+	FCC3 = 0x0160,
+	FCC4 = 0x0165,
+	FCC5 = 0x0510,
+	FCC6 = 0x0610,
+	FCC7 = 0x0710,
+	FCC8 = 0x0810,
+	FCC9 = 0x0910,
+	FCC10 = 0x0B10,
+	FCC11 = 0x0B20,
+	FCC13 = 0x0B60,
+	FCC14 = 0x0B70,
+
+	ETSI1 = 0x0130,
+	ETSI2 = 0x0230,
+	ETSI3 = 0x0330,
+	ETSI4 = 0x0430,
+	ETSI5 = 0x0530,
+	ETSI6 = 0x0630,
+	ETSI8 = 0x0830,
+	ETSI9 = 0x0930,
+	ETSI10 = 0x0D30,
+	ETSI11 = 0x0E30,
+
+	APL1 = 0x0150,
+	APL2 = 0x0250,
+	APL3 = 0x0350,
+	APL4 = 0x0450,
+	APL5 = 0x0550,
+	APL6 = 0x0650,
+	APL7 = 0x0750,
+	APL8 = 0x0850,
+	APL9 = 0x0950,
+	APL10 = 0x1050,
+	APL11 = 0x1150,
+	APL12 = 0x1160,
+	APL13 = 0x1170,
+	APL14 = 0x1180,
+	APL15 = 0x1190,
+	APL16 = 0x1200,
+	APL17 = 0x1210,
+	APL23 = 0x1280,
+	APL20 = 0x1250,
+
+	NULL1 = 0x0198,
+	MKK3 = 0x0340,
+	MKK5 = 0x0540,
+	MKK11 = 0x1140,
+	MKK16 =  0x1640,
+
+	WORLD = 0x0199,
+	FCCA = 0x0A10,
+	FCCB = 0x0B90,
+	MKKA = 0x0A40,
+	MKKC = 0x0A50,
+	ETSIC = 0x0C30,
+
+};
+
+/**
+ * enum ctl_val: CTL value
+ * @FCC: FCC
+ * @MKK: MKK
+ * @ETSI: ETSI
+ * @NO_CTL: no CTL
+ */
+enum ctl_val {
+	FCC = 0x10,
+	MKK = 0x40,
+	ETSI = 0x30,
+	NO_CTL = 0xff
+};
+
+/**
+ * struct reg_dmn_pair: regulatory domain pair
+ * @reg_dmn_pair: reg domain pair
+ * @reg_dmn_5ghz: 5G reg domain
+ * @reg_dmn_2ghz: 2G reg domain
+ * @single_cc: country with this reg domain
+ */
+struct reg_dmn_pair {
+	uint16_t reg_dmn_pair;
+	uint16_t reg_dmn_5ghz;
+	uint16_t reg_dmn_2ghz;
+	uint16_t single_cc;
+};
+
+/**
+ * struct country_code_to_reg_dmn: country code to reg domain mapping
+ * @country_code: country code
+ * @reg_dmn_pair: regulatory domain pair
+ * @alpha2: country alpha2
+ * @name: country name
+ */
+struct country_code_to_reg_dmn {
+	uint16_t country_code;
+	uint16_t reg_dmn_pair;
+	const char *alpha2;
+	const char *name;
+};
+
+/**
+ * struct reg_dmn: regulatory domain structure
+ * @reg_dmn: regulatory domain
+ * @conformance_test_limit:  CTL limit
+ */
+struct reg_dmn {
+	uint16_t reg_dmn;
+	uint8_t conformance_test_limit;
+};
+
+/**
+ * struct reg_dmn_tables: reg domain table
+ * @reg_dmn_pairs: list of reg domain pairs
+ * @all_countries: list of countries
+ * @reg_dmns: list of reg domains
+ * @reg_dmn_pairs_cnt: count of reg domain pairs
+ * @all_countries_cnt: count of countries
+ * @reg_dmns_cnt: count of reg domains
+ */
+struct reg_dmn_tables {
+	const struct reg_dmn_pair *reg_dmn_pairs;
+	const struct country_code_to_reg_dmn *all_countries;
+	const struct reg_dmn *reg_dmns;
+	uint16_t reg_dmn_pairs_cnt;
+	uint16_t all_countries_cnt;
+	uint16_t reg_dmns_cnt;
+};
+
+int32_t cds_fill_some_regulatory_info(struct regulatory *reg);
+int32_t cds_get_country_from_alpha2(uint8_t *alpha2);
+void cds_fill_and_send_ctl_to_fw(struct regulatory *reg);
+/**
+ * cds_is_etsi_europe_country - check ETSI Europe country or not
+ * @country: country string with two Characters
+ *
+ * Return: true if country in ETSI Europe country list
+ */
+bool cds_is_etsi_europe_country(uint8_t *country);
+#endif /* __CDS_REGDOMAIN_H */
diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h
new file mode 100644
index 0000000..33487d5
--- /dev/null
+++ b/core/cds/inc/cds_sched.h
@@ -0,0 +1,514 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#if !defined(__CDS_SCHED_H)
+#define __CDS_SCHED_H
+
+/**=========================================================================
+
+   \file  cds_sched.h
+
+   \brief Connectivity driver services scheduler
+
+   ========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include <qdf_event.h>
+#include <i_qdf_types.h>
+#include <linux/wait.h>
+#if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK)
+#include <linux/wakelock.h>
+#endif
+#include <qdf_types.h>
+#include "qdf_lock.h"
+#include "qdf_mc_timer.h"
+#include "cds_config.h"
+#include "qdf_cpuhp.h"
+
+#define TX_POST_EVENT               0x001
+#define TX_SUSPEND_EVENT            0x002
+#define MC_POST_EVENT               0x001
+#define MC_SUSPEND_EVENT            0x002
+#define RX_POST_EVENT               0x001
+#define RX_SUSPEND_EVENT            0x002
+#define TX_SHUTDOWN_EVENT           0x010
+#define MC_SHUTDOWN_EVENT           0x010
+#define RX_SHUTDOWN_EVENT           0x010
+#define WD_POST_EVENT               0x001
+#define WD_SHUTDOWN_EVENT           0x002
+#define WD_CHIP_RESET_EVENT         0x004
+#define WD_WLAN_SHUTDOWN_EVENT      0x008
+#define WD_WLAN_REINIT_EVENT        0x010
+
+#ifdef QCA_CONFIG_SMP
+/*
+** Maximum number of cds messages to be allocated for
+** OL Rx thread.
+*/
+#define CDS_MAX_OL_RX_PKT 4000
+#endif
+
+typedef void (*cds_ol_rx_thread_cb)(void *context, void *rxpkt, uint16_t staid);
+
+/*
+** CDS message wrapper for data rx from TXRX
+*/
+struct cds_ol_rx_pkt {
+	struct list_head list;
+	void *context;
+
+	/* Rx skb */
+	void *Rxpkt;
+
+	/* Station id to which this packet is destined */
+	uint16_t staId;
+
+	/* Call back to further send this packet to txrx layer */
+	cds_ol_rx_thread_cb callback;
+
+};
+
+/*
+** CDS Scheduler context
+** The scheduler context contains the following:
+**   ** the messages queues
+**   ** the handle to the tread
+**   ** pointer to the events that gracefully shutdown the MC and Tx threads
+**
+*/
+typedef struct _cds_sched_context {
+#ifdef QCA_CONFIG_SMP
+	spinlock_t ol_rx_thread_lock;
+
+	/* OL Rx thread handle */
+	struct task_struct *ol_rx_thread;
+
+	/* Handle of Event for Rx thread to signal startup */
+	struct completion ol_rx_start_event;
+
+	/* Completion object to suspend OL rx thread */
+	struct completion ol_suspend_rx_event;
+
+	/* Completion object to resume OL rx thread */
+	struct completion ol_resume_rx_event;
+
+	/* Completion object for OL Rxthread shutdown */
+	struct completion ol_rx_shutdown;
+
+	/* Waitq for OL Rx thread */
+	wait_queue_head_t ol_rx_wait_queue;
+
+	unsigned long ol_rx_event_flag;
+
+	/* Rx buffer queue */
+	struct list_head ol_rx_thread_queue;
+
+	/* Spinlock to synchronize between tasklet and thread */
+	spinlock_t ol_rx_queue_lock;
+
+	/* Rx queue length */
+	unsigned int ol_rx_queue_len;
+
+	/* Lock to synchronize free buffer queue access */
+	spinlock_t cds_ol_rx_pkt_freeq_lock;
+
+	/* Free message queue for OL Rx processing */
+	struct list_head cds_ol_rx_pkt_freeq;
+
+	/* The CPU hotplug event registration handle, used to unregister */
+	struct qdf_cpuhp_handler *cpuhp_event_handle;
+
+	/* affinity lock */
+	struct mutex affinity_lock;
+
+	/* Saved rx thread CPU affinity */
+	struct cpumask rx_thread_cpu_mask;
+
+	/* CPU affinity bitmask */
+	uint8_t conf_rx_thread_cpu_mask;
+
+	/* high throughput required */
+	bool high_throughput_required;
+#endif
+} cds_sched_context, *p_cds_sched_context;
+
+/**
+ * struct cds_log_complete - Log completion internal structure
+ * @is_fatal: Type is fatal or not
+ * @indicator: Source of bug report
+ * @reason_code: Reason code for bug report
+ * @is_report_in_progress: If bug report is in progress
+ * @recovery_needed: if recovery is needed after report completion
+ *
+ * This structure internally stores the log related params
+ */
+struct cds_log_complete {
+	uint32_t is_fatal;
+	uint32_t indicator;
+	uint32_t reason_code;
+	bool is_report_in_progress;
+	bool recovery_needed;
+};
+
+/* forward-declare hdd_context_s as it is used ina function type */
+struct hdd_context_s;
+struct cds_context {
+	/* Scheduler Context */
+	cds_sched_context qdf_sched;
+
+	/* HDD Module Context  */
+	void *hdd_context;
+
+	/* MAC Module Context  */
+	void *mac_context;
+
+	uint32_t driver_state;
+	unsigned long fw_state;
+
+	qdf_event_t wma_complete_event;
+
+	/* WMA Context */
+	void *wma_context;
+
+	void *hif_context;
+
+	void *htc_ctx;
+
+	void *g_ol_context;
+	/*
+	 * qdf_ctx will be used by qdf
+	 * while allocating dma memory
+	 * to access dev information.
+	 */
+	qdf_device_t qdf_ctx;
+
+	struct cdp_pdev *pdev_txrx_ctx;
+	void *dp_soc;
+
+	/* Configuration handle used to get system configuration */
+	struct cdp_cfg *cfg_ctx;
+
+	/* radio index per driver */
+	int radio_index;
+
+	bool is_wakelock_log_enabled;
+	uint32_t wakelock_log_level;
+	uint32_t connectivity_log_level;
+	uint32_t packet_stats_log_level;
+	uint32_t driver_debug_log_level;
+	uint32_t fw_debug_log_level;
+	struct cds_log_complete log_complete;
+	qdf_spinlock_t bug_report_lock;
+
+	bool enable_fatal_event;
+	struct cds_config_info *cds_cfg;
+
+	struct ol_tx_sched_wrr_ac_specs_t ac_specs[TX_WMM_AC_NUM];
+	qdf_work_t cds_recovery_work;
+	qdf_workqueue_t *cds_recovery_wq;
+	enum qdf_hang_reason recovery_reason;
+};
+
+/*---------------------------------------------------------------------------
+   Function declarations and documenation
+   ---------------------------------------------------------------------------*/
+#ifdef QCA_CONFIG_SMP
+int cds_sched_handle_cpu_hot_plug(void);
+int cds_sched_handle_throughput_req(bool high_tput_required);
+
+/**
+ * cds_set_rx_thread_cpu_mask() - Rx_thread affinity from INI
+ * @cpu_affinity_mask: CPU affinity bitmap
+ *
+ * Return:None
+ */
+void cds_set_rx_thread_cpu_mask(uint8_t cpu_affinity_mask);
+
+/*---------------------------------------------------------------------------
+   \brief cds_drop_rxpkt_by_staid() - API to drop pending Rx packets for a sta
+   The \a cds_drop_rxpkt_by_staid() drops queued packets for a station, to drop
+   all the pending packets the caller has to send WLAN_MAX_STA_COUNT as staId.
+   \param  pSchedContext - pointer to the global CDS Sched Context
+   \param staId - Station Id
+
+   \return Nothing
+   \sa cds_drop_rxpkt_by_staid()
+   -------------------------------------------------------------------------*/
+void cds_drop_rxpkt_by_staid(p_cds_sched_context pSchedContext, uint16_t staId);
+
+/*---------------------------------------------------------------------------
+   \brief cds_indicate_rxpkt() - API to Indicate rx data packet
+   The \a cds_indicate_rxpkt() enqueues the rx packet onto ol_rx_thread_queue
+   and notifies cds_ol_rx_thread().
+   \param  Arg - pointer to the global CDS Sched Context
+   \param pkt - Vos data message buffer
+
+   \return Nothing
+   \sa cds_indicate_rxpkt()
+   -------------------------------------------------------------------------*/
+void cds_indicate_rxpkt(p_cds_sched_context pSchedContext,
+			struct cds_ol_rx_pkt *pkt);
+
+/*---------------------------------------------------------------------------
+   \brief cds_alloc_ol_rx_pkt() - API to return next available cds message
+   The \a cds_alloc_ol_rx_pkt() returns next available cds message buffer
+   used for Rx Data processing.
+   \param pSchedContext - pointer to the global CDS Sched Context
+
+   \return pointer to cds message buffer
+   \sa cds_alloc_ol_rx_pkt()
+   -------------------------------------------------------------------------*/
+struct cds_ol_rx_pkt *cds_alloc_ol_rx_pkt(p_cds_sched_context pSchedContext);
+
+/*---------------------------------------------------------------------------
+   \brief cds_free_ol_rx_pkt() - API to release cds message to the freeq
+   The \a cds_free_ol_rx_pkt() returns the cds message used for Rx data
+   to the free queue.
+   \param  pSchedContext - pointer to the global CDS Sched Context
+   \param  pkt - Vos message buffer to be returned to free queue.
+
+   \return Nothing
+   \sa cds_free_ol_rx_pkt()
+   -------------------------------------------------------------------------*/
+void cds_free_ol_rx_pkt(p_cds_sched_context pSchedContext,
+			 struct cds_ol_rx_pkt *pkt);
+/*---------------------------------------------------------------------------
+   \brief cds_free_ol_rx_pkt_freeq() - Free cdss buffer free queue
+   The \a cds_free_ol_rx_pkt_freeq() does mem free of the buffers
+   available in free cds buffer queue which is used for Data rx processing
+   from Tlshim.
+   \param pSchedContext - pointer to the global CDS Sched Context
+
+   \return Nothing
+   \sa cds_free_ol_rx_pkt_freeq()
+   -------------------------------------------------------------------------*/
+void cds_free_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext);
+#else
+/**
+ * cds_set_rx_thread_cpu_mask() - Rx_thread affinity from INI
+ * @cpu_affinity_mask: CPU affinity bitmap
+ *
+ * Return:None
+ */
+static inline void cds_set_rx_thread_cpu_mask(uint8_t cpu_affinity_mask) {}
+
+/**
+ * cds_drop_rxpkt_by_staid() - api to drop pending rx packets for a sta
+ * @pSchedContext: Pointer to the global CDS Sched Context
+ * @staId: Station Id
+ *
+ * This api drops queued packets for a station, to drop all the pending
+ * packets the caller has to send WLAN_MAX_STA_COUNT as staId.
+ *
+ * Return: none
+ */
+static inline
+void cds_drop_rxpkt_by_staid(p_cds_sched_context pSchedContext, uint16_t staId)
+{
+}
+
+/**
+ * cds_indicate_rxpkt() - API to Indicate rx data packet
+ * @pSchedContext: pointer to  CDS Sched Context
+ * @pkt: CDS OL RX pkt pointer containing to RX data message buffer
+ *
+ * Return: none
+ */
+static inline
+void cds_indicate_rxpkt(p_cds_sched_context pSchedContext,
+			struct cds_ol_rx_pkt *pkt)
+{
+}
+
+/**
+ * cds_alloc_ol_rx_pkt() - API to return next available cds message
+ * @pSchedContext: pointer to  CDS Sched Context
+ *
+ * Return: none
+ */
+static inline
+struct cds_ol_rx_pkt *cds_alloc_ol_rx_pkt(p_cds_sched_context pSchedContext)
+{
+	return NULL;
+}
+
+/**
+ * cds_free_ol_rx_pkt() - API to release cds message to the freeq
+ * @pSchedContext: pointer to  CDS Sched Context
+ * @pkt: CDS message buffer to be returned to free queue
+ *
+ * Return: none
+ */
+static inline
+void cds_free_ol_rx_pkt(p_cds_sched_context pSchedContext,
+			 struct cds_ol_rx_pkt *pkt)
+{
+}
+
+/**
+ * cds_free_ol_rx_pkt_freeq() - Free cds buffer free queue
+ * @pSchedContext: pointer to  CDS Sched Context
+ * @pkt: CDS message buffer to be returned to free queue
+ *
+ * Return: none
+ */
+static inline
+void cds_free_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext)
+{
+}
+
+static inline int cds_sched_handle_throughput_req(
+	bool high_tput_required)
+{
+	return 0;
+}
+
+#endif
+
+/*---------------------------------------------------------------------------
+
+   \brief cds_sched_open() - initialize the CDS Scheduler
+
+   The \a cds_sched_open() function initializes the CDS Scheduler
+   Upon successful initialization:
+
+     - All the message queues are initialized
+
+     - The Main Controller thread is created and ready to receive and
+       dispatch messages.
+
+     - The Tx thread is created and ready to receive and dispatch messages
+
+   \param  p_cds_context - pointer to the global QDF Context
+
+   \param  p_cds_sched_context - pointer to a previously allocated buffer big
+   enough to hold a scheduler context.
+
+   \return QDF_STATUS_SUCCESS - Scheduler was successfully initialized and
+   is ready to be used.
+
+   QDF_STATUS_E_RESOURCES - System resources (other than memory)
+   are unavailable to initialize the scheduler
+
+   QDF_STATUS_E_NOMEM - insufficient memory exists to initialize
+   the scheduler
+
+   QDF_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open
+   function
+
+   QDF_STATUS_E_FAILURE - Failure to initialize the scheduler/
+
+   \sa cds_sched_open()
+
+   -------------------------------------------------------------------------*/
+QDF_STATUS cds_sched_open(void *p_cds_context,
+			  p_cds_sched_context pSchedCxt, uint32_t SchedCtxSize);
+
+/*---------------------------------------------------------------------------
+
+   \brief cds_sched_close() - Close the CDS Scheduler
+
+   The \a cds_sched_closes() function closes the CDS Scheduler
+   Upon successful closing:
+
+     - All the message queues are flushed
+
+     - The Main Controller thread is closed
+
+     - The Tx thread is closed
+
+   \return QDF_STATUS_SUCCESS - Scheduler was successfully initialized and
+   is ready to be used.
+
+   QDF_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open
+   function
+
+   QDF_STATUS_E_FAILURE - Failure to initialize the scheduler/
+
+   \sa cds_sched_close()
+
+   ---------------------------------------------------------------------------*/
+QDF_STATUS cds_sched_close(void);
+
+p_cds_sched_context get_cds_sched_ctxt(void);
+
+void qdf_timer_module_init(void);
+void qdf_timer_module_deinit(void);
+void cds_ssr_protect_init(void);
+void cds_ssr_protect(const char *caller_func);
+void cds_ssr_unprotect(const char *caller_func);
+bool cds_wait_for_external_threads_completion(const char *caller_func);
+void cds_print_external_threads(void);
+int cds_get_gfp_flags(void);
+
+/**
+ * cds_return_external_threads_count() - return active external thread calls
+ *
+ * Return: total number of active extrenal threads in driver
+ */
+int cds_return_external_threads_count(void);
+
+/**
+ * cds_shutdown_notifier_register() - Register for shutdown notification
+ * @cb          : Call back to be called
+ * @priv        : Private pointer to be passed back to call back
+ *
+ * During driver remove or shutdown (recovery), external threads might be stuck
+ * waiting on some event from firmware at lower layers. Remove or shutdown can't
+ * proceed till the thread completes to avoid any race condition. Call backs can
+ * be registered here to get early notification of remove or shutdown so that
+ * waiting thread can be unblocked and hence remove or shutdown can proceed
+ * further as waiting there may not make sense when FW may already have been
+ * down.
+ *
+ * Return: CDS status
+ */
+QDF_STATUS cds_shutdown_notifier_register(void (*cb)(void *priv), void *priv);
+
+/**
+ * cds_shutdown_notifier_purge() - Purge all the notifiers
+ *
+ * Shutdown notifiers are added to provide the early notification of remove or
+ * shutdown being initiated. Adding this API to purge all the registered call
+ * backs as they are not useful any more while all the lower layers are being
+ * shutdown.
+ *
+ * Return: None
+ */
+void cds_shutdown_notifier_purge(void);
+
+/**
+ * cds_shutdown_notifier_call() - Call shutdown notifier call back
+ *
+ * Call registered shutdown notifier call back to indicate about remove or
+ * shutdown.
+ */
+void cds_shutdown_notifier_call(void);
+
+/**
+ * cds_resume_rx_thread() - resume rx thread by completing its resume event
+ *
+ * Resume RX thread by completing RX thread resume event
+ *
+ * Return: None
+ */
+void cds_resume_rx_thread(void);
+
+#endif /* #if !defined __CDS_SCHED_H */
diff --git a/core/cds/inc/cds_utils.h b/core/cds/inc/cds_utils.h
new file mode 100644
index 0000000..eedcb4c
--- /dev/null
+++ b/core/cds/inc/cds_utils.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#if !defined(__CDS_UTILS_H)
+#define __CDS_UTILS_H
+
+/**=========================================================================
+
+   \file  cds_utils.h
+
+   \brief Connectivity driver services (CDS) utility APIs
+
+   Various utility functions
+
+   ========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include <qdf_types.h>
+#include <qdf_status.h>
+#include <qdf_event.h>
+#include <qdf_lock.h>
+#include "ani_global.h"
+
+/*--------------------------------------------------------------------------
+   Preprocessor definitions and constants
+   ------------------------------------------------------------------------*/
+#define CDS_DIGEST_SHA1_SIZE    (20)
+#define CDS_DIGEST_MD5_SIZE     (16)
+
+#define CDS_24_GHZ_BASE_FREQ   (2407)
+#define CDS_5_GHZ_BASE_FREQ    (5000)
+#define CDS_24_GHZ_CHANNEL_6   (6)
+#define CDS_24_GHZ_CHANNEL_1   (1)
+#define CDS_5_GHZ_CHANNEL_36   (36)
+#define CDS_24_GHZ_CHANNEL_14  (14)
+#define CDS_24_GHZ_CHANNEL_15  (15)
+#define CDS_24_GHZ_CHANNEL_27  (27)
+#define CDS_5_GHZ_CHANNEL_165  (165)
+#define CDS_5_GHZ_CHANNEL_170  (170)
+#define CDS_CHAN_SPACING_5MHZ  (5)
+#define CDS_CHAN_SPACING_20MHZ (20)
+#define CDS_CHAN_14_FREQ       (2484)
+#define CDS_CHAN_15_FREQ       (2512)
+#define CDS_CHAN_170_FREQ      (5852)
+
+#define INVALID_SCAN_ID        0xFFFFFFFF
+
+#define CDS_DBS_SCAN_CLIENTS_MAX           (7)
+#define CDS_DBS_SCAN_PARAM_PER_CLIENT      (3)
+
+#define cds_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_QDF, params)
+#define cds_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, params)
+#define cds_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_QDF, params)
+#define cds_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_QDF, params)
+#define cds_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_QDF, params)
+
+#define cds_nofl_alert(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_QDF, params)
+#define cds_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_QDF, params)
+#define cds_nofl_warn(params...) \
+	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_QDF, params)
+#define cds_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_QDF, params)
+#define cds_nofl_debug(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_QDF, params)
+
+#define cds_enter() QDF_TRACE_ENTER(QDF_MODULE_ID_QDF, "enter")
+#define cds_exit() QDF_TRACE_EXIT(QDF_MODULE_ID_QDF, "exit")
+
+/**
+ * enum cds_band_type - Band type - 2g, 5g or all
+ * CDS_BAND_ALL: Both 2G and 5G are valid.
+ * CDS_BAND_2GHZ: only 2G is valid.
+ * CDS_BAND_5GHZ: only 5G is valid.
+ */
+enum cds_band_type {
+	CDS_BAND_ALL = 0,
+	CDS_BAND_2GHZ = 1,
+	CDS_BAND_5GHZ = 2
+};
+
+/*-------------------------------------------------------------------------
+   Function declarations and documenation
+   ------------------------------------------------------------------------*/
+
+QDF_STATUS cds_crypto_init(uint32_t *phCryptProv);
+
+QDF_STATUS cds_crypto_deinit(uint32_t hCryptProv);
+
+/**
+ * cds_rand_get_bytes
+
+ * FUNCTION:
+ * Returns cryptographically secure pseudo-random bytes.
+ *
+ *
+ * @param pbBuf - the caller allocated location where the bytes should be copied
+ * @param numBytes the number of bytes that should be generated and
+ * copied
+ *
+ * @return QDF_STATUS_SUCCSS if the operation succeeds
+ */
+QDF_STATUS cds_rand_get_bytes(uint32_t handle, uint8_t *pbBuf,
+			      uint32_t numBytes);
+
+uint32_t cds_chan_to_freq(uint8_t chan);
+uint8_t cds_freq_to_chan(uint32_t freq);
+enum cds_band_type cds_chan_to_band(uint32_t chan);
+
+/**
+ * cds_upper_to_lower: API to convert upper case string into lower case
+ * @txt: input text
+ * @length: length of input string
+ *
+ * Return: None
+ */
+void cds_upper_to_lower(uint8_t *txt, uint32_t length);
+#ifdef WLAN_FEATURE_11W
+bool cds_is_mmie_valid(uint8_t *key, uint8_t *ipn,
+		       uint8_t *frm, uint8_t *efrm);
+bool cds_attach_mmie(uint8_t *igtk, uint8_t *ipn, uint16_t key_id,
+		     uint8_t *frm, uint8_t *efrm, uint16_t frmLen);
+uint8_t cds_get_mmie_size(void);
+/**
+ * cds_is_gmac_mmie_valid: Validates GMAC MIC
+ * @igtk: integrity group temporal key
+ * @ipn: IGTK packet number
+ * @frm: IEEE 802.11 frame
+ * @efrm: End of frame
+ * @key_length: Length of IGTK
+ *
+ * Return: True if MIC validation is successful, false otherwise
+ */
+bool cds_is_gmac_mmie_valid(uint8_t *igtk, uint8_t *ipn, uint8_t *frm,
+			    uint8_t *efrm, uint16_t key_length);
+
+/**
+ * cds_get_gmac_mmie_size: Gives length of GMAC MMIE size
+ *
+ * Return: Size of MMIE for GMAC
+ */
+uint8_t cds_get_gmac_mmie_size(void);
+
+#endif /* WLAN_FEATURE_11W */
+QDF_STATUS sme_send_flush_logs_cmd_to_fw(tpAniSirGlobal pMac);
+static inline void cds_host_diag_log_work(qdf_wake_lock_t *lock, uint32_t msec,
+			    uint32_t reason) {
+	if (((cds_get_ring_log_level(RING_ID_WAKELOCK) >= WLAN_LOG_LEVEL_ACTIVE)
+	     && (WIFI_POWER_EVENT_WAKELOCK_HOLD_RX == reason)) ||
+	    (WIFI_POWER_EVENT_WAKELOCK_HOLD_RX != reason)) {
+		host_diag_log_wlock(reason, qdf_wake_lock_name(lock),
+				    msec, WIFI_POWER_EVENT_WAKELOCK_TAKEN);
+	}
+}
+
+/**
+ * cds_copy_hlp_info() - Copy HLP info
+ * @input_dst_mac: input HLP destination MAC address
+ * @input_src_mac: input HLP source MAC address
+ * @input_hlp_data_len: input HLP data length
+ * @input_hlp_data: Pointer to input HLP data
+ * @output_dst_mac: output HLP destination MAC address
+ * @output_src_mac: output HLP source MAC address
+ * @output_hlp_data_len: Pointer to output HLP data length
+ * @output_hlp_data: output Pointer to HLP data
+ *
+ * Util API to copy HLP info from input to output
+ *
+ * Return: None
+ */
+void cds_copy_hlp_info(struct qdf_mac_addr *input_dst_mac,
+		       struct qdf_mac_addr *input_src_mac,
+		       uint16_t input_hlp_data_len,
+		       uint8_t *input_hlp_data,
+		       struct qdf_mac_addr *output_dst_mac,
+		       struct qdf_mac_addr *output_src_mac,
+		       uint16_t *output_hlp_data_len,
+		       uint8_t *output_hlp_data);
+#endif /* #if !defined __CDS_UTILS_H */
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
new file mode 100644
index 0000000..ee8b2c8
--- /dev/null
+++ b/core/cds/src/cds_api.c
@@ -0,0 +1,2861 @@
+/*
+ * Copyright (c) 2012-2018 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: cds_api.c
+ *
+ * Connectivity driver services APIs
+ */
+
+#include <cds_api.h>
+#include "sir_types.h"
+#include "sir_api.h"
+#include "sir_mac_prot_def.h"
+#include "sme_api.h"
+#include "mac_init_api.h"
+#include "wlan_qct_sys.h"
+#include "i_cds_packet.h"
+#include "cds_reg_service.h"
+#include "wma_types.h"
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_power.h"
+#include "wlan_hdd_tsf.h"
+#include <linux/vmalloc.h>
+
+#include "pld_common.h"
+#include "sap_api.h"
+#include "bmi.h"
+#include "ol_fw.h"
+#include "ol_if_athvar.h"
+#include "hif.h"
+#include "wlan_policy_mgr_api.h"
+#include "cds_utils.h"
+#include "wlan_logging_sock_svc.h"
+#include "wma.h"
+#include "pktlog_ac.h"
+#include "wlan_policy_mgr_api.h"
+
+#include <cdp_txrx_cmn_reg.h>
+#include <cdp_txrx_cfg.h>
+#include <cdp_txrx_misc.h>
+#include <dispatcher_init_deinit.h>
+#include <cdp_txrx_handle.h>
+#include "target_type.h"
+#include "wlan_ocb_ucfg_api.h"
+#include "wlan_ipa_ucfg_api.h"
+#include "dp_txrx.h"
+#ifdef ENABLE_SMMU_S1_TRANSLATION
+#include "pld_common.h"
+#include <asm/dma-iommu.h>
+#include <linux/iommu.h>
+#endif
+
+#ifdef QCA_WIFI_QCA8074
+#include <target_if_dp.h>
+#endif
+#include "wlan_mlme_ucfg_api.h"
+#include "cfg_ucfg_api.h"
+
+/* Preprocessor Definitions and Constants */
+
+/* Preprocessor Definitions and Constants */
+
+/* Data definitions */
+static struct cds_context g_cds_context;
+static struct cds_context *gp_cds_context;
+static struct __qdf_device g_qdf_ctx;
+
+static uint8_t cds_multicast_logging;
+
+#ifdef QCA_WIFI_QCA8074
+static struct ol_if_ops  dp_ol_if_ops = {
+	.peer_set_default_routing = target_if_peer_set_default_routing,
+	.peer_rx_reorder_queue_setup = target_if_peer_rx_reorder_queue_setup,
+	.peer_rx_reorder_queue_remove = target_if_peer_rx_reorder_queue_remove,
+	.is_hw_dbs_2x2_capable = policy_mgr_is_hw_dbs_2x2_capable,
+	.lro_hash_config = target_if_lro_hash_config,
+	.rx_mic_error = wma_rx_mic_error_ind,
+	.rx_invalid_peer = wma_rx_invalid_peer_ind
+    /* TODO: Add any other control path calls required to OL_IF/WMA layer */
+};
+#else
+static struct ol_if_ops  dp_ol_if_ops;
+#endif
+
+static void cds_trigger_recovery_work(void *param);
+
+/**
+ * struct cds_recovery_call_info - caller information for cds_trigger_recovery
+ * @func: caller's function name
+ * @line: caller's line number
+ */
+struct cds_recovery_call_info {
+	const char *func;
+	uint32_t line;
+} __cds_recovery_caller;
+
+/**
+ * cds_recovery_work_init() - Initialize recovery work queue
+ *
+ * Return: none
+ */
+static QDF_STATUS cds_recovery_work_init(void)
+{
+	qdf_create_work(0, &gp_cds_context->cds_recovery_work,
+			cds_trigger_recovery_work, &__cds_recovery_caller);
+	gp_cds_context->cds_recovery_wq =
+		qdf_create_workqueue("cds_recovery_workqueue");
+	if (NULL == gp_cds_context->cds_recovery_wq) {
+		cds_err("Failed to create cds_recovery_workqueue");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cds_recovery_work_deinit() - Initialize recovery work queue
+ *
+ * Return: none
+ */
+static void cds_recovery_work_deinit(void)
+{
+	if (gp_cds_context->cds_recovery_wq) {
+		qdf_flush_workqueue(0, gp_cds_context->cds_recovery_wq);
+		qdf_destroy_workqueue(0, gp_cds_context->cds_recovery_wq);
+	}
+}
+
+/** cds_get_datapath_handles - Initialize pdev, vdev and soc
+ * @soc - soc handle
+ * @vdev - virtual handle
+ * @pdev - physical handle
+ */
+uint8_t cds_get_datapath_handles(void **soc, struct cdp_pdev **pdev,
+		struct cdp_vdev **vdev, uint8_t sessionId)
+{
+
+	(*soc) = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!(*soc)) {
+		cds_err("soc handle is invalid");
+		return -EINVAL;
+	}
+
+	(*pdev) = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!(*pdev)) {
+		cds_err("pdev handle is invalid");
+		return -EINVAL;
+	}
+
+	(*vdev) = cdp_get_vdev_from_vdev_id((*soc), (*pdev),
+					sessionId);
+
+	if (!(*vdev)) {
+		cds_err("vdev handle is invalid");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+QDF_STATUS cds_init(void)
+{
+	QDF_STATUS status;
+
+	gp_cds_context = &g_cds_context;
+
+	status = cds_recovery_work_init();
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_err("Failed to init recovery work; status:%u", status);
+		goto deinit;
+	}
+
+	cds_ssr_protect_init();
+
+	gp_cds_context->qdf_ctx = &g_qdf_ctx;
+
+	qdf_register_self_recovery_callback(__cds_trigger_recovery);
+	qdf_register_fw_down_callback(cds_is_fw_down);
+	qdf_register_ssr_protect_callbacks(cds_ssr_protect, cds_ssr_unprotect);
+	qdf_register_recovering_state_query_callback(cds_is_driver_recovering);
+
+	return QDF_STATUS_SUCCESS;
+
+deinit:
+	gp_cds_context = NULL;
+	qdf_mem_zero(&g_cds_context, sizeof(g_cds_context));
+
+	return status;
+}
+
+/**
+ * cds_deinit() - Deinitialize CDS
+ *
+ * This function frees the CDS resources
+ */
+void cds_deinit(void)
+{
+	QDF_BUG(gp_cds_context);
+	if (!gp_cds_context)
+		return;
+	qdf_register_recovering_state_query_callback(NULL);
+	qdf_register_ssr_protect_callbacks(NULL, NULL);
+	qdf_register_fw_down_callback(NULL);
+	qdf_register_self_recovery_callback(NULL);
+
+	gp_cds_context->qdf_ctx = NULL;
+	qdf_mem_zero(&g_qdf_ctx, sizeof(g_qdf_ctx));
+
+	/* currently, no ssr_protect_deinit */
+
+	cds_recovery_work_deinit();
+
+	gp_cds_context = NULL;
+	qdf_mem_zero(&g_cds_context, sizeof(g_cds_context));
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * cds_tdls_tx_rx_mgmt_event()- send tdls mgmt rx tx event
+ * @event_id: event id
+ * @tx_rx: tx or rx
+ * @type: type of frame
+ * @action_sub_type: action frame type
+ * @peer_mac: peer mac
+ *
+ * This Function sends tdls mgmt rx tx diag event
+ *
+ * Return: void.
+ */
+void cds_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
+		uint8_t type, uint8_t action_sub_type, uint8_t *peer_mac)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(tdls_tx_rx_mgmt,
+		struct host_event_tdls_tx_rx_mgmt);
+
+	tdls_tx_rx_mgmt.event_id = event_id;
+	tdls_tx_rx_mgmt.tx_rx = tx_rx;
+	tdls_tx_rx_mgmt.type = type;
+	tdls_tx_rx_mgmt.action_sub_type = action_sub_type;
+	qdf_mem_copy(tdls_tx_rx_mgmt.peer_mac,
+			peer_mac, CDS_MAC_ADDRESS_LEN);
+	WLAN_HOST_DIAG_EVENT_REPORT(&tdls_tx_rx_mgmt,
+				EVENT_WLAN_TDLS_TX_RX_MGMT);
+}
+#endif
+
+/**
+ * cds_cfg_update_ac_specs_params() - update ac_specs params
+ * @olcfg: cfg handle
+ * @mac_params: mac params
+ *
+ * Return: none
+ */
+static void
+cds_cfg_update_ac_specs_params(struct txrx_pdev_cfg_param_t *olcfg,
+		struct cds_config_info *cds_cfg)
+{
+	int i;
+
+	if (NULL == olcfg)
+		return;
+
+	if (NULL == cds_cfg)
+		return;
+
+	for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
+		olcfg->ac_specs[i].wrr_skip_weight =
+			cds_cfg->ac_specs[i].wrr_skip_weight;
+		olcfg->ac_specs[i].credit_threshold =
+			cds_cfg->ac_specs[i].credit_threshold;
+		olcfg->ac_specs[i].send_limit =
+			cds_cfg->ac_specs[i].send_limit;
+		olcfg->ac_specs[i].credit_reserve =
+			cds_cfg->ac_specs[i].credit_reserve;
+		olcfg->ac_specs[i].discard_weight =
+			cds_cfg->ac_specs[i].discard_weight;
+	}
+}
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+static inline void
+cds_cdp_set_flow_control_params(struct wlan_objmgr_psoc *psoc,
+				struct txrx_pdev_cfg_param_t *cdp_cfg)
+{
+	cdp_cfg->tx_flow_stop_queue_th =
+		cfg_get(psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
+	cdp_cfg->tx_flow_start_queue_offset =
+		cfg_get(psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
+}
+#else
+static inline void
+cds_cdp_set_flow_control_params(struct wlan_objmgr_psoc *psoc,
+				struct txrx_pdev_cfg_param_t *cdp_cfg)
+{}
+#endif
+
+/**
+ * cds_cdp_cfg_attach() - attach data path config module
+ * @cds_cfg: generic platform level config instance
+ *
+ * Return: none
+ */
+static void cds_cdp_cfg_attach(struct wlan_objmgr_psoc *psoc)
+{
+	struct txrx_pdev_cfg_param_t cdp_cfg = {0};
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct hdd_context *hdd_ctx = gp_cds_context->hdd_context;
+
+	cdp_cfg.is_full_reorder_offload =
+		cfg_get(psoc, CFG_DP_REORDER_OFFLOAD_SUPPORT);
+	cdp_cfg.is_uc_offload_enabled = ucfg_ipa_uc_is_enabled();
+	cdp_cfg.uc_tx_buffer_count = cfg_get(psoc, CFG_DP_IPA_UC_TX_BUF_COUNT);
+	cdp_cfg.uc_tx_buffer_size =
+			cfg_get(psoc, CFG_DP_IPA_UC_TX_BUF_SIZE);
+	cdp_cfg.uc_rx_indication_ring_count =
+		cfg_get(psoc, CFG_DP_IPA_UC_RX_IND_RING_COUNT);
+	cdp_cfg.uc_tx_partition_base =
+		cfg_get(psoc, CFG_DP_IPA_UC_TX_PARTITION_BASE);
+	cdp_cfg.enable_rxthread = hdd_ctx->enable_rxthread;
+	cdp_cfg.ip_tcp_udp_checksum_offload =
+		cfg_get(psoc, CFG_DP_TCP_UDP_CKSUM_OFFLOAD);
+	cdp_cfg.ce_classify_enabled =
+		cfg_get(psoc, CFG_DP_CE_CLASSIFY_ENABLE);
+	cdp_cfg.tso_enable = cfg_get(psoc, CFG_DP_TSO);
+	cdp_cfg.lro_enable = cfg_get(psoc, CFG_DP_LRO);
+	cdp_cfg.enable_data_stall_detection =
+		cfg_get(psoc, CFG_DP_ENABLE_DATA_STALL_DETECTION);
+	cdp_cfg.tso_enable = cfg_get(psoc, CFG_DP_TSO);
+	cdp_cfg.lro_enable = cfg_get(psoc, CFG_DP_LRO);
+	cdp_cfg.gro_enable = cfg_get(psoc, CFG_DP_GRO);
+	cdp_cfg.enable_flow_steering =
+		cfg_get(psoc, CFG_DP_FLOW_STEERING_ENABLED);
+	cdp_cfg.disable_intra_bss_fwd =
+		cfg_get(psoc, CFG_DP_AP_STA_SECURITY_SEPERATION);
+	cdp_cfg.ce_classify_enabled =
+		cfg_get(psoc, CFG_DP_CE_CLASSIFY_ENABLE);
+
+	gp_cds_context->cfg_ctx = cdp_cfg_attach(soc, gp_cds_context->qdf_ctx,
+					(void *)(&cdp_cfg));
+	if (!gp_cds_context->cfg_ctx) {
+		WMA_LOGP("%s: failed to init cfg handle", __func__);
+		return;
+	}
+
+	/* Configure Receive flow steering */
+	cdp_cfg_set_flow_steering(soc, gp_cds_context->cfg_ctx,
+				  cfg_get(psoc, CFG_DP_FLOW_STEERING_ENABLED));
+
+	cds_cdp_set_flow_control_params(psoc, &cdp_cfg);
+	cdp_cfg_set_flow_control_parameters(soc, gp_cds_context->cfg_ctx,
+					    (void *)&cdp_cfg);
+
+	/* adjust the cfg_ctx default value based on setting */
+	cdp_cfg_set_rx_fwd_disabled(soc, gp_cds_context->cfg_ctx,
+				    cfg_get(psoc,
+					    CFG_DP_AP_STA_SECURITY_SEPERATION));
+
+	/*
+	 * adjust the packet log enable default value
+	 * based on CFG INI setting
+	 */
+	cdp_cfg_set_packet_log_enabled(soc, gp_cds_context->cfg_ctx,
+		(uint8_t)cds_is_packet_log_enabled());
+
+	/* adjust the ptp rx option default value based on CFG INI setting */
+	cdp_cfg_set_ptp_rx_opt_enabled(soc, gp_cds_context->cfg_ctx,
+				       (uint8_t)cds_is_ptp_rx_opt_enabled());
+}
+static QDF_STATUS cds_register_all_modules(void)
+{
+	QDF_STATUS status;
+
+	scheduler_register_wma_legacy_handler(&wma_mc_process_handler);
+	scheduler_register_sys_legacy_handler(&sys_mc_process_handler);
+
+	/* Register message queues in given order such that queue priority is
+	 * intact:
+	 * 1) QDF_MODULE_ID_SYS: Timer queue(legacy SYS queue)
+	 * 2) QDF_MODULE_ID_TARGET_IF: Target interface queue
+	 * 3) QDF_MODULE_ID_PE: Legacy PE message queue
+	 * 4) QDF_MODULE_ID_SME: Legacy SME message queue
+	 * 5) QDF_MODULE_ID_OS_IF: OS IF message queue for new components
+	 */
+	status = scheduler_register_module(QDF_MODULE_ID_SYS,
+					&scheduler_timer_q_mq_handler);
+	status = scheduler_register_module(QDF_MODULE_ID_TARGET_IF,
+					&scheduler_target_if_mq_handler);
+	status = scheduler_register_module(QDF_MODULE_ID_PE,
+					&pe_mc_process_handler);
+	status = scheduler_register_module(QDF_MODULE_ID_SME,
+					&sme_mc_process_handler);
+	status = scheduler_register_module(QDF_MODULE_ID_OS_IF,
+					&scheduler_os_if_mq_handler);
+	status = scheduler_register_module(QDF_MODULE_ID_SCAN,
+					&scheduler_scan_mq_handler);
+	return status;
+}
+
+static QDF_STATUS cds_deregister_all_modules(void)
+{
+	QDF_STATUS status;
+
+	scheduler_deregister_wma_legacy_handler();
+	scheduler_deregister_sys_legacy_handler();
+	status = scheduler_deregister_module(QDF_MODULE_ID_SYS);
+	status = scheduler_deregister_module(QDF_MODULE_ID_TARGET_IF);
+	status = scheduler_deregister_module(QDF_MODULE_ID_PE);
+	status = scheduler_deregister_module(QDF_MODULE_ID_SME);
+	status = scheduler_deregister_module(QDF_MODULE_ID_OS_IF);
+
+	return status;
+}
+
+/**
+ * cds_set_ac_specs_params() - set ac_specs params in cds_config_info
+ * @cds_cfg: Pointer to cds_config_info
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Return: none
+ */
+static void
+cds_set_ac_specs_params(struct cds_config_info *cds_cfg)
+{
+	int i;
+	struct cds_context *cds_ctx;
+
+	if (NULL == cds_cfg)
+		return;
+
+	cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+
+	if (!cds_ctx) {
+		cds_err("Invalid CDS Context");
+		return;
+	}
+
+	for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
+		cds_cfg->ac_specs[i] = cds_ctx->ac_specs[i];
+	}
+}
+
+/**
+ * cds_open() - open the CDS Module
+ *
+ * cds_open() function opens the CDS Scheduler
+ * Upon successful initialization:
+ * - All CDS submodules should have been initialized
+ *
+ * - The CDS scheduler should have opened
+ *
+ * - All the WLAN SW components should have been opened. This includes
+ * SYS, MAC, SME, WMA and TL.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_open(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	struct cds_config_info *cds_cfg;
+	qdf_device_t qdf_ctx;
+	struct htc_init_info htcInfo;
+	struct ol_context *ol_ctx;
+	struct hif_opaque_softc *scn;
+	void *HTCHandle;
+	struct hdd_context *hdd_ctx;
+	struct cds_context *cds_ctx;
+	mac_handle_t mac_handle;
+
+	cds_debug("Opening CDS");
+
+	cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+	if (!cds_ctx) {
+		cds_alert("Trying to open CDS without a PreOpen");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Initialize the timer module */
+	qdf_timer_module_init();
+
+	/* Initialize bug reporting structure */
+	cds_init_log_completion();
+
+	status = qdf_event_create(&gp_cds_context->wma_complete_event);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_alert("Unable to init wma_complete_event");
+		return status;
+	}
+
+	hdd_ctx = gp_cds_context->hdd_context;
+	if (!hdd_ctx || !hdd_ctx->config) {
+		cds_err("Hdd Context is Null");
+
+		status = QDF_STATUS_E_FAILURE;
+		goto err_wma_complete_event;
+	}
+
+	status = dispatcher_enable();
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_err("Failed to enable dispatcher; status:%d", status);
+		goto err_wma_complete_event;
+	}
+
+	/* Now Open the CDS Scheduler */
+	status = cds_sched_open(gp_cds_context,
+				&gp_cds_context->qdf_sched,
+				sizeof(cds_sched_context));
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_alert("Failed to open CDS Scheduler");
+		goto err_dispatcher_disable;
+	}
+
+	scn = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!scn) {
+		cds_alert("scn is null!");
+
+		status = QDF_STATUS_E_FAILURE;
+		goto err_sched_close;
+	}
+
+	cds_cfg = cds_get_ini_config();
+	if (!cds_cfg) {
+		cds_err("Cds config is NULL");
+
+		status = QDF_STATUS_E_FAILURE;
+		goto err_sched_close;
+	}
+
+	hdd_enable_fastpath(hdd_ctx, scn);
+
+	/* Initialize BMI and Download firmware */
+	ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
+	status = bmi_download_firmware(ol_ctx);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_alert("BMI FIALED status:%d", status);
+		goto err_bmi_close;
+	}
+
+	hdd_wlan_update_target_info(hdd_ctx, scn);
+
+	htcInfo.pContext = ol_ctx;
+	htcInfo.TargetFailure = ol_target_failure;
+	htcInfo.TargetSendSuspendComplete =
+		ucfg_pmo_psoc_target_suspend_acknowledge;
+	htcInfo.target_initial_wakeup_cb = ucfg_pmo_psoc_handle_initial_wake_up;
+	htcInfo.target_psoc = (void *)psoc;
+	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	/* Create HTC */
+	gp_cds_context->htc_ctx =
+		htc_create(scn, &htcInfo, qdf_ctx, cds_get_conparam());
+	if (!gp_cds_context->htc_ctx) {
+		cds_alert("Failed to Create HTC");
+
+		status = QDF_STATUS_E_FAILURE;
+		goto err_bmi_close;
+	}
+	ucfg_pmo_psoc_update_htc_handle(psoc, (void *)gp_cds_context->htc_ctx);
+
+	status = bmi_done(ol_ctx);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_alert("Failed to complete BMI phase");
+		goto err_htc_close;
+	}
+
+	/*Open the WMA module */
+	status = wma_open(psoc, hdd_update_tgt_cfg, cds_cfg,
+			  hdd_ctx->target_type);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_alert("Failed to open WMA module");
+		goto err_htc_close;
+	}
+
+	/* Number of peers limit differs in each chip version. If peer max
+	 * limit configured in ini exceeds more than supported, WMA adjusts
+	 * and keeps correct limit in cds_cfg.max_station. So, make sure
+	 * config entry hdd_ctx->config->maxNumberOfPeers has adjusted value
+	 */
+	/* In FTM mode cds_cfg->max_stations will be zero. On updating same
+	 * into hdd context config entry, leads to pe_open() to fail, if
+	 * con_mode change happens from FTM mode to any other mode.
+	 */
+	if (QDF_DRIVER_TYPE_PRODUCTION == cds_cfg->driver_type)
+		ucfg_mlme_set_sap_max_peers(psoc, cds_cfg->max_station);
+
+	HTCHandle = cds_get_context(QDF_MODULE_ID_HTC);
+	if (!HTCHandle) {
+		cds_alert("HTCHandle is null!");
+
+		status = QDF_STATUS_E_FAILURE;
+		goto err_wma_close;
+	}
+
+	status = htc_wait_target(HTCHandle);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_alert("Failed to complete BMI phase. status: %d", status);
+		QDF_BUG(status == QDF_STATUS_E_NOMEM || cds_is_fw_down());
+
+		goto err_wma_close;
+	}
+
+	cds_debug("target_type %d 8074:%d 6290:%d 6390: %d",
+		  hdd_ctx->target_type,
+		  TARGET_TYPE_QCA8074,
+		  TARGET_TYPE_QCA6290,
+		  TARGET_TYPE_QCA6390);
+
+	if (TARGET_TYPE_QCA6290 == hdd_ctx->target_type ||
+	    TARGET_TYPE_QCA6390 == hdd_ctx->target_type)
+		gp_cds_context->dp_soc = cdp_soc_attach(LITHIUM_DP,
+			gp_cds_context->hif_context, psoc,
+			gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx,
+			&dp_ol_if_ops);
+	else
+		gp_cds_context->dp_soc = cdp_soc_attach(MOB_DRV_LEGACY_DP,
+			gp_cds_context->hif_context, psoc,
+			gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx,
+			&dp_ol_if_ops);
+
+	if (!gp_cds_context->dp_soc) {
+		status = QDF_STATUS_E_FAILURE;
+		goto err_wma_close;
+	}
+
+	wlan_psoc_set_dp_handle(psoc, gp_cds_context->dp_soc);
+	ucfg_pmo_psoc_update_dp_handle(psoc, gp_cds_context->dp_soc);
+	ucfg_ocb_update_dp_handle(psoc, gp_cds_context->dp_soc);
+
+	cds_set_ac_specs_params(cds_cfg);
+	cds_cfg_update_ac_specs_params((struct txrx_pdev_cfg_param_t *)
+				       gp_cds_context->cfg_ctx, cds_cfg);
+	cds_cdp_cfg_attach(psoc);
+
+	bmi_target_ready(scn, gp_cds_context->cfg_ctx);
+
+	/* Now proceed to open the MAC */
+	status = mac_open(psoc, &mac_handle,
+			  gp_cds_context->hdd_context, cds_cfg);
+
+	if (QDF_STATUS_SUCCESS != status) {
+		cds_alert("Failed to open MAC");
+		goto err_soc_detach;
+	}
+	gp_cds_context->mac_context = mac_handle;
+
+	/* Now proceed to open the SME */
+	status = sme_open(mac_handle);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_alert("Failed to open SME");
+		goto err_mac_close;
+	}
+
+	cds_register_all_modules();
+
+	status = dispatcher_psoc_open(psoc);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_alert("Failed to open PSOC Components");
+		goto deregister_modules;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+deregister_modules:
+	cds_deregister_all_modules();
+	sme_close(mac_handle);
+
+err_mac_close:
+	mac_close(mac_handle);
+	gp_cds_context->mac_context = NULL;
+
+err_soc_detach:
+	cdp_soc_detach(gp_cds_context->dp_soc);
+	gp_cds_context->dp_soc = NULL;
+
+	ucfg_ocb_update_dp_handle(psoc, NULL);
+	ucfg_pmo_psoc_update_dp_handle(psoc, NULL);
+	wlan_psoc_set_dp_handle(psoc, NULL);
+
+err_wma_close:
+	cds_shutdown_notifier_purge();
+	wma_close();
+	wma_wmi_service_close();
+
+err_htc_close:
+	if (gp_cds_context->htc_ctx) {
+		htc_destroy(gp_cds_context->htc_ctx);
+		gp_cds_context->htc_ctx = NULL;
+		ucfg_pmo_psoc_update_htc_handle(psoc, NULL);
+	}
+
+err_bmi_close:
+	bmi_cleanup(ol_ctx);
+
+err_sched_close:
+	if (QDF_IS_STATUS_ERROR(cds_sched_close()))
+		QDF_DEBUG_PANIC("Failed to close CDS Scheduler");
+
+err_dispatcher_disable:
+	if (QDF_IS_STATUS_ERROR(dispatcher_disable()))
+		QDF_DEBUG_PANIC("Failed to disable dispatcher");
+
+err_wma_complete_event:
+	qdf_event_destroy(&gp_cds_context->wma_complete_event);
+
+	return status;
+} /* cds_open() */
+
+QDF_STATUS cds_dp_open(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS qdf_status;
+	struct dp_txrx_config dp_config;
+
+	if (cdp_txrx_intr_attach(gp_cds_context->dp_soc)
+				!= QDF_STATUS_SUCCESS) {
+		cds_alert("Failed to attach interrupts");
+		goto close;
+	}
+
+	cds_set_context(QDF_MODULE_ID_TXRX,
+		cdp_pdev_attach(cds_get_context(QDF_MODULE_ID_SOC),
+			(struct cdp_ctrl_objmgr_pdev *)gp_cds_context->cfg_ctx,
+			gp_cds_context->htc_ctx,
+			gp_cds_context->qdf_ctx, 0));
+	if (!gp_cds_context->pdev_txrx_ctx) {
+		/* Critical Error ...  Cannot proceed further */
+		cds_alert("Failed to open TXRX");
+		QDF_ASSERT(0);
+		goto intr_close;
+	}
+
+	dp_config.num_rx_threads = gp_cds_context->cds_cfg->num_dp_rx_threads;
+	dp_config.enable_rx_threads =
+		gp_cds_context->cds_cfg->enable_dp_rx_threads;
+	qdf_status = dp_txrx_init(cds_get_context(QDF_MODULE_ID_SOC),
+				  cds_get_context(QDF_MODULE_ID_TXRX),
+				  &dp_config);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		goto pdev_detach;
+
+	ucfg_pmo_psoc_set_txrx_handle(psoc, gp_cds_context->pdev_txrx_ctx);
+	ucfg_ocb_set_txrx_handle(psoc, gp_cds_context->pdev_txrx_ctx);
+
+	cds_debug("CDS successfully Opened");
+
+	return 0;
+
+pdev_detach:
+	cdp_pdev_detach(gp_cds_context->dp_soc,
+			cds_get_context(QDF_MODULE_ID_TXRX), false);
+intr_close:
+	cdp_txrx_intr_detach(gp_cds_context->dp_soc);
+close:
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * cds_pre_enable() - pre enable cds
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_pre_enable(void)
+{
+	QDF_STATUS status;
+	int errno;
+	void *scn;
+	void *soc;
+	void *hif_ctx;
+
+	cds_enter();
+
+	if (!gp_cds_context) {
+		cds_err("cds context is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!gp_cds_context->wma_context) {
+		cds_err("wma context is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	scn = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!scn) {
+		cds_err("hif context is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	soc = cds_get_context(QDF_MODULE_ID_SOC);
+	if (!soc) {
+		cds_err("soc context is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* call Packetlog connect service */
+	if (QDF_GLOBAL_FTM_MODE != cds_get_conparam() &&
+	    QDF_GLOBAL_EPPING_MODE != cds_get_conparam())
+		cdp_pkt_log_con_service(soc, gp_cds_context->pdev_txrx_ctx,
+					scn);
+
+	/* Reset wma wait event */
+	qdf_event_reset(&gp_cds_context->wma_complete_event);
+
+	/*call WMA pre start */
+	status = wma_pre_start();
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_err("Failed to WMA prestart");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Need to update time out of complete */
+	status = qdf_wait_for_event_completion(
+					&gp_cds_context->wma_complete_event,
+					CDS_WMA_TIMEOUT);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_err("Failed to wait for WMA complete; status:%u", status);
+		cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
+		goto exit_with_status;
+	}
+
+	status = htc_start(gp_cds_context->htc_ctx);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_err("Failed to Start HTC");
+		goto exit_with_status;
+	}
+
+	status = wma_wait_for_ready_event(gp_cds_context->wma_context);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_err("Failed to wait for ready event; status: %u", status);
+		cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
+		goto stop_wmi;
+	}
+
+	errno = cdp_pdev_post_attach(soc, gp_cds_context->pdev_txrx_ctx);
+	if (errno) {
+		cds_err("Failed to attach pdev");
+		status = qdf_status_from_os_return(errno);
+		goto stop_wmi;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+stop_wmi:
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!hif_ctx)
+		cds_err("%s: Failed to get hif_handle!", __func__);
+
+	wma_wmi_stop();
+
+	if (hif_ctx) {
+		cds_err("%s: Disable the isr & reset the soc!", __func__);
+		hif_disable_isr(hif_ctx);
+		hif_reset_soc(hif_ctx);
+	}
+	htc_stop(gp_cds_context->htc_ctx);
+
+exit_with_status:
+	return status;
+}
+
+QDF_STATUS cds_enable(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS qdf_status;
+	struct mac_start_params mac_params;
+	int errno;
+
+	/* We support only one instance for now ... */
+	if (!gp_cds_context) {
+		cds_err("Invalid CDS context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!gp_cds_context->wma_context) {
+		cds_err("WMA NULL context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!gp_cds_context->mac_context) {
+		cds_err("MAC NULL context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Start the wma */
+	qdf_status = wma_start();
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		cds_err("Failed to start wma; status:%d", qdf_status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Start the MAC */
+	qdf_mem_zero(&mac_params, sizeof(mac_params));
+	mac_params.driver_type = QDF_DRIVER_TYPE_PRODUCTION;
+	qdf_status = mac_start(gp_cds_context->mac_context, &mac_params);
+
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		cds_err("Failed to start MAC; status:%d", qdf_status);
+		goto err_wma_stop;
+	}
+
+	/* START SME */
+	qdf_status = sme_start(gp_cds_context->mac_context);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_err("Failed to start SME; status:%d", qdf_status);
+		goto err_mac_stop;
+	}
+
+	qdf_status = cdp_soc_attach_target(cds_get_context(QDF_MODULE_ID_SOC));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_err("Failed to attach soc target; status:%d", qdf_status);
+		goto err_sme_stop;
+	}
+
+	errno = cdp_pdev_attach_target(cds_get_context(QDF_MODULE_ID_SOC),
+				       cds_get_context(QDF_MODULE_ID_TXRX));
+	if (errno) {
+		cds_err("Failed to attach pdev target; errno:%d", errno);
+		goto err_soc_target_detach;
+	}
+
+	qdf_status = dispatcher_psoc_enable(psoc);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_err("dispatcher_psoc_enable failed; status:%d", qdf_status);
+		goto err_soc_target_detach;
+	}
+
+	/* Trigger psoc enable for CLD components */
+	hdd_component_psoc_enable(psoc);
+
+	return QDF_STATUS_SUCCESS;
+
+err_soc_target_detach:
+	/* NOOP */
+
+err_sme_stop:
+	sme_stop(gp_cds_context->mac_context);
+
+err_mac_stop:
+	mac_stop(gp_cds_context->mac_context);
+
+err_wma_stop:
+	qdf_event_reset(&gp_cds_context->wma_complete_event);
+	qdf_status = wma_stop();
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_err("Failed to stop wma");
+		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+		wma_setneedshutdown();
+	} else {
+		qdf_status =
+			qdf_wait_for_event_completion(
+					&gp_cds_context->wma_complete_event,
+					CDS_WMA_TIMEOUT);
+		if (qdf_status != QDF_STATUS_SUCCESS) {
+			if (qdf_status == QDF_STATUS_E_TIMEOUT) {
+				cds_alert("Timeout occurred before WMA_stop complete");
+			} else {
+				cds_alert("WMA_stop reporting other error");
+			}
+			QDF_ASSERT(0);
+			wma_setneedshutdown();
+		}
+	}
+
+	return QDF_STATUS_E_FAILURE;
+} /* cds_enable() */
+
+/**
+ * cds_disable() - stop/disable cds module
+ * @psoc: Psoc pointer
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_disable(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS qdf_status;
+	void *handle;
+
+	/* PSOC disable for all new components. It needs to happen before
+	 * target is PDEV suspended such that a component can abort all its
+	 * ongoing transaction with FW. Always keep it before wma_stop() as
+	 * wma_stop() does target PDEV suspend.
+	 */
+
+	/* Trigger psoc disable for CLD components */
+	if (psoc) {
+		hdd_component_psoc_disable(psoc);
+		dispatcher_psoc_disable(psoc);
+	}
+
+	qdf_status = wma_stop();
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_err("Failed to stop wma");
+		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+		wma_setneedshutdown();
+	}
+
+	handle = cds_get_context(QDF_MODULE_ID_PE);
+	if (!handle) {
+		cds_err("Invalid PE context return!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	umac_stop();
+
+	return qdf_status;
+}
+
+#ifdef HIF_USB
+static inline void cds_suspend_target(tp_wma_handle wma_handle)
+{
+	QDF_STATUS status;
+	/* Suspend the target and disable interrupt */
+	status = ucfg_pmo_psoc_suspend_target(wma_handle->psoc, 0);
+	if (status)
+		cds_err("Failed to suspend target, status = %d", status);
+}
+#else
+static inline void cds_suspend_target(tp_wma_handle wma_handle)
+{
+	QDF_STATUS status;
+	/* Suspend the target and disable interrupt */
+	status = ucfg_pmo_psoc_suspend_target(wma_handle->psoc, 1);
+	if (status)
+		cds_err("Failed to suspend target, status = %d", status);
+}
+#endif /* HIF_USB */
+
+/**
+ * cds_post_disable() - post disable cds module
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_post_disable(void)
+{
+	tp_wma_handle wma_handle;
+	struct hif_opaque_softc *hif_ctx;
+	struct cdp_pdev *txrx_pdev;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		cds_err("Failed to get wma_handle!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!hif_ctx) {
+		cds_err("Failed to get hif_handle!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!txrx_pdev) {
+		cds_err("Failed to get txrx pdev!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/*
+	 * With new state machine changes cds_close can be invoked without
+	 * cds_disable. So, send the following clean up prerequisites to fw,
+	 * So Fw and host are in sync for cleanup indication:
+	 * - Send PDEV_SUSPEND indication to firmware
+	 * - Disable HIF Interrupts.
+	 * - Clean up CE tasklets.
+	 */
+
+	cds_info("send deinit sequence to firmware");
+	if (!(cds_is_driver_recovering() || cds_is_driver_in_bad_state()))
+		cds_suspend_target(wma_handle);
+	hif_disable_isr(hif_ctx);
+	hif_reset_soc(hif_ctx);
+
+	if (gp_cds_context->htc_ctx) {
+		wma_wmi_stop();
+		htc_stop(gp_cds_context->htc_ctx);
+	}
+
+	cdp_pdev_pre_detach(cds_get_context(QDF_MODULE_ID_SOC),
+		       (struct cdp_pdev *)txrx_pdev, 1);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cds_close() - close cds module
+ * @psoc: Psoc pointer
+ *
+ * This API allows user to close modules registered
+ * with connectivity device services.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS qdf_status;
+
+	qdf_status = cds_sched_close();
+	QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		cds_err("Failed to close CDS Scheduler");
+
+	qdf_status = dispatcher_disable();
+	QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		cds_err("Failed to disable dispatcher; status:%d", qdf_status);
+
+	dispatcher_psoc_close(psoc);
+
+	qdf_status = wma_wmi_work_close();
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_err("Failed to close wma_wmi_work");
+		QDF_ASSERT(0);
+	}
+
+	if (gp_cds_context->htc_ctx) {
+		htc_destroy(gp_cds_context->htc_ctx);
+		ucfg_pmo_psoc_update_htc_handle(psoc, NULL);
+		gp_cds_context->htc_ctx = NULL;
+	}
+
+	qdf_status = sme_close(gp_cds_context->mac_context);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_err("Failed to close SME");
+		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+	}
+
+	qdf_status = mac_close(gp_cds_context->mac_context);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_err("Failed to close MAC");
+		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+	}
+
+	gp_cds_context->mac_context = NULL;
+
+	cdp_soc_detach(gp_cds_context->dp_soc);
+	ucfg_pmo_psoc_update_dp_handle(psoc, NULL);
+	wlan_psoc_set_dp_handle(psoc, NULL);
+
+	cds_shutdown_notifier_purge();
+
+	if (true == wma_needshutdown()) {
+		cds_err("Failed to shutdown wma");
+	} else {
+		qdf_status = wma_close();
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			cds_err("Failed to close wma");
+			QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+		}
+	}
+
+	qdf_status = wma_wmi_service_close();
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_err("Failed to close wma_wmi_service");
+		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+	}
+
+	qdf_status = qdf_event_destroy(&gp_cds_context->wma_complete_event);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_err("failed to destroy wma_complete_event");
+		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+	}
+
+	cds_deinit_ini_config();
+	qdf_timer_module_deinit();
+
+	cds_deregister_all_modules();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS cds_dp_close(struct wlan_objmgr_psoc *psoc)
+{
+	void *ctx;
+
+	cdp_txrx_intr_detach(gp_cds_context->dp_soc);
+	ctx = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	dp_txrx_deinit(cds_get_context(QDF_MODULE_ID_SOC));
+
+	cdp_pdev_detach(cds_get_context(QDF_MODULE_ID_SOC),
+		       (struct cdp_pdev *)ctx, 1);
+
+	cds_set_context(QDF_MODULE_ID_TXRX, NULL);
+	ucfg_pmo_psoc_set_txrx_handle(psoc, NULL);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cds_get_context() - get context data area
+ *
+ * @module_id: ID of the module who's context data is being retrieved.
+ *
+ * Each module in the system has a context / data area that is allocated
+ * and managed by CDS.  This API allows any user to get a pointer to its
+ * allocated context data area from the CDS global context.
+ *
+ * Return: pointer to the context data area of the module ID
+ *	   specified, or NULL if the context data is not allocated for
+ *	   the module ID specified
+ */
+void *cds_get_context(QDF_MODULE_ID module_id)
+{
+	void *context = NULL;
+
+	if (gp_cds_context == NULL) {
+		cds_err("cds context pointer is null");
+		return NULL;
+	}
+
+	switch (module_id) {
+	case QDF_MODULE_ID_HDD:
+	{
+		context = gp_cds_context->hdd_context;
+		break;
+	}
+
+	case QDF_MODULE_ID_SME:
+	case QDF_MODULE_ID_PE:
+	{
+		/* In all these cases, we just return the MAC Context */
+		context = gp_cds_context->mac_context;
+		break;
+	}
+
+	case QDF_MODULE_ID_WMA:
+	{
+		/* For wma module */
+		context = gp_cds_context->wma_context;
+		break;
+	}
+
+	case QDF_MODULE_ID_QDF:
+	{
+		/* For SYS this is CDS itself */
+		context = gp_cds_context;
+		break;
+	}
+
+	case QDF_MODULE_ID_HIF:
+	{
+		context = gp_cds_context->hif_context;
+		break;
+	}
+
+	case QDF_MODULE_ID_HTC:
+	{
+		context = gp_cds_context->htc_ctx;
+		break;
+	}
+
+	case QDF_MODULE_ID_QDF_DEVICE:
+	{
+		context = gp_cds_context->qdf_ctx;
+		break;
+	}
+
+	case QDF_MODULE_ID_BMI:
+	{
+		context = gp_cds_context->g_ol_context;
+		break;
+	}
+
+	case QDF_MODULE_ID_TXRX:
+	{
+		context = (void *)gp_cds_context->pdev_txrx_ctx;
+		break;
+	}
+
+	case QDF_MODULE_ID_CFG:
+	{
+		context = gp_cds_context->cfg_ctx;
+		break;
+	}
+
+	case QDF_MODULE_ID_SOC:
+	{
+		context = gp_cds_context->dp_soc;
+		break;
+	}
+
+	default:
+	{
+		cds_err("Module ID %i does not have its context maintained by CDS",
+			module_id);
+		QDF_ASSERT(0);
+		return NULL;
+	}
+	}
+
+	if (!context)
+		cds_err("Module ID %i context is Null", module_id);
+
+	return context;
+} /* cds_get_context() */
+
+/**
+ * cds_get_global_context() - get CDS global Context
+ *
+ * This API allows any user to get the CDS Global Context pointer from a
+ * module context data area.
+ *
+ * Return: pointer to the CDS global context, NULL if the function is
+ *	   unable to retrieve the CDS context.
+ */
+void *cds_get_global_context(void)
+{
+	if (gp_cds_context == NULL) {
+		/*
+		 * To avoid recursive call, this should not change to
+		 * QDF_TRACE().
+		 */
+		pr_err("%s: global cds context is NULL", __func__);
+	}
+
+	return gp_cds_context;
+} /* cds_get_global_context() */
+
+/**
+ * cds_get_driver_state() - Get current driver state
+ *
+ * This API returns current driver state stored in global context.
+ *
+ * Return: Driver state enum
+ */
+enum cds_driver_state cds_get_driver_state(void)
+{
+	if (gp_cds_context == NULL) {
+		cds_err("global cds context is NULL");
+
+		return CDS_DRIVER_STATE_UNINITIALIZED;
+	}
+
+	return gp_cds_context->driver_state;
+}
+
+/**
+ * cds_set_driver_state() - Set current driver state
+ * @state:	Driver state to be set to.
+ *
+ * This API sets driver state to state. This API only sets the state and doesn't
+ * clear states, please make sure to use cds_clear_driver_state to clear any
+ * state if required.
+ *
+ * Return: None
+ */
+void cds_set_driver_state(enum cds_driver_state state)
+{
+	if (gp_cds_context == NULL) {
+		cds_err("global cds context is NULL: %x", state);
+
+		return;
+	}
+
+	gp_cds_context->driver_state |= state;
+}
+
+/**
+ * cds_clear_driver_state() - Clear current driver state
+ * @state:	Driver state to be cleared.
+ *
+ * This API clears driver state. This API only clears the state, please make
+ * sure to use cds_set_driver_state to set any new states.
+ *
+ * Return: None
+ */
+void cds_clear_driver_state(enum cds_driver_state state)
+{
+	if (gp_cds_context == NULL) {
+		cds_err("global cds context is NULL: %x", state);
+
+		return;
+	}
+
+	gp_cds_context->driver_state &= ~state;
+}
+
+enum cds_fw_state cds_get_fw_state(void)
+{
+	if (gp_cds_context == NULL) {
+		cds_err("global cds context is NULL");
+
+		return CDS_FW_STATE_UNINITIALIZED;
+	}
+
+	return gp_cds_context->fw_state;
+}
+
+void cds_set_fw_state(enum cds_fw_state state)
+{
+	if (gp_cds_context == NULL) {
+		cds_err("global cds context is NULL: %d", state);
+
+		return;
+	}
+
+	qdf_atomic_set_bit(state, &gp_cds_context->fw_state);
+}
+
+void cds_clear_fw_state(enum cds_fw_state state)
+{
+	if (gp_cds_context == NULL) {
+		cds_err("global cds context is NULL: %d", state);
+
+		return;
+	}
+
+	qdf_atomic_clear_bit(state, &gp_cds_context->fw_state);
+}
+
+/**
+ * cds_alloc_context() - allocate a context within the CDS global Context
+ * @module_id: module ID who's context area is being allocated.
+ * @module_context: pointer to location where the pointer to the
+ *	allocated context is returned. Note this output pointer
+ *	is valid only if the API returns QDF_STATUS_SUCCESS
+ * @param size: size of the context area to be allocated.
+ *
+ * This API allows any user to allocate a user context area within the
+ * CDS Global Context.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_alloc_context(QDF_MODULE_ID module_id,
+			     void **module_context, uint32_t size)
+{
+	void **cds_mod_context = NULL;
+
+	if (!gp_cds_context) {
+		cds_err("cds context is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!module_context) {
+		cds_err("null param passed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	switch (module_id) {
+	case QDF_MODULE_ID_WMA:
+		cds_mod_context = &gp_cds_context->wma_context;
+		break;
+
+	case QDF_MODULE_ID_HIF:
+		cds_mod_context = &gp_cds_context->hif_context;
+		break;
+
+	case QDF_MODULE_ID_BMI:
+		cds_mod_context = &gp_cds_context->g_ol_context;
+		break;
+
+	default:
+		cds_err("Module ID %i does not have its context allocated by CDS",
+			module_id);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (*cds_mod_context) {
+		/* Context has already been allocated!
+		 * Prevent double allocation
+		 */
+		cds_err("Module ID %i context has already been allocated",
+			module_id);
+		return QDF_STATUS_E_EXISTS;
+	}
+
+	/* Dynamically allocate the context for module */
+
+	*module_context = qdf_mem_malloc(size);
+
+	if (!*module_context) {
+		cds_err("Failed to allocate Context for module ID %i",
+			module_id);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	*cds_mod_context = *module_context;
+
+	return QDF_STATUS_SUCCESS;
+} /* cds_alloc_context() */
+
+/**
+ * cds_set_context() - API to set context in global CDS Context
+ * @module_id: Module ID
+ * @context: Pointer to the Module Context
+ *
+ * API to set a MODULE Context in global CDS Context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS cds_set_context(QDF_MODULE_ID module_id, void *context)
+{
+	struct cds_context *p_cds_context = cds_get_global_context();
+
+	if (!p_cds_context) {
+		cds_err("cds context is Invalid");
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	switch (module_id) {
+	case QDF_MODULE_ID_HDD:
+		p_cds_context->hdd_context = context;
+		break;
+	case QDF_MODULE_ID_TXRX:
+		p_cds_context->pdev_txrx_ctx = context;
+		break;
+	case QDF_MODULE_ID_HIF:
+		p_cds_context->hif_context = context;
+		break;
+	default:
+		cds_err("Module ID %i does not have its context managed by CDS",
+			module_id);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cds_free_context() - free an allocated context within the
+ *			CDS global Context
+ * @module_id: module ID who's context area is being free
+ * @module_context: pointer to module context area to be free'd.
+ *
+ *  This API allows a user to free the user context area within the
+ *  CDS Global Context.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_free_context(QDF_MODULE_ID module_id, void *module_context)
+{
+	void **cds_mod_context = NULL;
+
+	if (!gp_cds_context) {
+		cds_err("cds context is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!module_context) {
+		cds_err("Null param");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	switch (module_id) {
+	case QDF_MODULE_ID_WMA:
+		cds_mod_context = &gp_cds_context->wma_context;
+		break;
+
+	case QDF_MODULE_ID_HIF:
+		cds_mod_context = &gp_cds_context->hif_context;
+		break;
+
+	case QDF_MODULE_ID_TXRX:
+		cds_mod_context = (void **)&gp_cds_context->pdev_txrx_ctx;
+		break;
+
+	case QDF_MODULE_ID_BMI:
+		cds_mod_context = &gp_cds_context->g_ol_context;
+		break;
+
+	default:
+		cds_err("Module ID %i does not have its context allocated by CDS",
+			module_id);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!*cds_mod_context) {
+		/* Context has not been allocated or freed already! */
+		cds_err("Module ID %i context has not been allocated or freed already",
+			module_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (*cds_mod_context != module_context) {
+		cds_err("cds_mod_context != module_context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_free(module_context);
+
+	*cds_mod_context = NULL;
+
+	return QDF_STATUS_SUCCESS;
+} /* cds_free_context() */
+
+/**
+ * cds_wma_complete_cback() - wma complete callback
+ *
+ * Return: none
+ */
+void cds_wma_complete_cback(void)
+{
+	if (!gp_cds_context) {
+		cds_err("invalid gp_cds_context");
+		return;
+	}
+
+	if (qdf_event_set(&gp_cds_context->wma_complete_event) !=
+	    QDF_STATUS_SUCCESS) {
+		cds_err("qdf_event_set failed");
+		return;
+	}
+} /* cds_wma_complete_cback() */
+
+/**
+ * cds_get_vdev_types() - get vdev type
+ * @mode: mode
+ * @type: type
+ * @sub_type: sub_type
+ *
+ * Return: WMI vdev type
+ */
+QDF_STATUS cds_get_vdev_types(enum QDF_OPMODE mode, uint32_t *type,
+			      uint32_t *sub_type)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	*type = 0;
+	*sub_type = 0;
+
+	switch (mode) {
+	case QDF_STA_MODE:
+		*type = WMI_VDEV_TYPE_STA;
+		break;
+	case QDF_SAP_MODE:
+		*type = WMI_VDEV_TYPE_AP;
+		break;
+	case QDF_P2P_DEVICE_MODE:
+		*type = WMI_VDEV_TYPE_AP;
+		*sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE;
+		break;
+	case QDF_P2P_CLIENT_MODE:
+		*type = WMI_VDEV_TYPE_STA;
+		*sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT;
+		break;
+	case QDF_P2P_GO_MODE:
+		*type = WMI_VDEV_TYPE_AP;
+		*sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO;
+		break;
+	case QDF_OCB_MODE:
+		*type = WMI_VDEV_TYPE_OCB;
+		break;
+	case QDF_IBSS_MODE:
+		*type = WMI_VDEV_TYPE_IBSS;
+		break;
+	case QDF_MONITOR_MODE:
+		*type = WMI_VDEV_TYPE_MONITOR;
+		break;
+	case QDF_NDI_MODE:
+		*type = WMI_VDEV_TYPE_NDI;
+		break;
+	default:
+		cds_err("Invalid device mode %d", mode);
+		status = QDF_STATUS_E_INVAL;
+		break;
+	}
+	return status;
+}
+
+/**
+ * cds_flush_work() - flush pending works
+ * @work: pointer to work
+ *
+ * Return: none
+ */
+void cds_flush_work(void *work)
+{
+	cancel_work_sync(work);
+}
+
+/**
+ * cds_flush_delayed_work() - flush delayed works
+ * @dwork: pointer to delayed work
+ *
+ * Return: none
+ */
+void cds_flush_delayed_work(void *dwork)
+{
+	cancel_delayed_work_sync(dwork);
+}
+
+#ifndef REMOVE_PKT_LOG
+/**
+ * cds_is_packet_log_enabled() - check if packet log is enabled
+ *
+ * Return: true if packet log is enabled else false
+ */
+bool cds_is_packet_log_enabled(void)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = gp_cds_context->hdd_context;
+	if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
+		cds_alert("Hdd Context is Null");
+		return false;
+	}
+	return hdd_ctx->config->enable_packet_log;
+}
+#endif
+
+static int cds_force_assert_target_via_pld(qdf_device_t qdf)
+{
+	int errno;
+
+	errno = pld_force_assert_target(qdf->dev);
+	if (errno == -EOPNOTSUPP)
+		cds_info("PLD does not support target force assert");
+	else if (errno)
+		cds_err("Failed PLD target force assert; errno %d", errno);
+	else
+		cds_info("Target force assert triggered via PLD");
+
+	return errno;
+}
+
+static QDF_STATUS cds_force_assert_target_via_wmi(qdf_device_t qdf)
+{
+	QDF_STATUS status;
+	t_wma_handle *wma;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		cds_err("wma is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wma_crash_inject(wma, RECOVERY_SIM_SELF_RECOVERY, 0);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_err("Failed target force assert; status %d", status);
+		return status;
+	}
+
+	status = qdf_wait_for_event_completion(&wma->recovery_event,
+				       WMA_CRASH_INJECT_TIMEOUT);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_err("Failed target force assert wait; status %d", status);
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cds_force_assert_target() - Send assert command to firmware
+ * @qdf: QDF device instance to assert
+ *
+ * An out-of-band recovery mechanism will cleanup and restart the entire wlan
+ * subsystem in the event of a firmware crash. This API injects a firmware
+ * crash to start this process when the wlan driver is known to be in a bad
+ * state. If a firmware assert inject fails, the wlan driver will schedule
+ * the driver recovery anyway, as a best effort attempt to return to a working
+ * state.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS cds_force_assert_target(qdf_device_t qdf)
+{
+	int errno;
+	QDF_STATUS status;
+
+	/* first, try target assert inject via pld */
+	errno = cds_force_assert_target_via_pld(qdf);
+	if (!errno)
+		return QDF_STATUS_SUCCESS;
+	if (errno != -EOPNOTSUPP)
+		return QDF_STATUS_E_FAILURE;
+
+	/* pld assert is not supported, try target assert inject via wmi */
+	status = cds_force_assert_target_via_wmi(qdf);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	/* wmi assert failed, start recovery without the firmware assert */
+	cds_err("Scheduling recovery work without firmware assert");
+	cds_set_recovery_in_progress(true);
+	pld_schedule_recovery_work(qdf->dev, PLD_REASON_DEFAULT);
+
+	return status;
+}
+
+/**
+ * cds_trigger_recovery_handler() - handle a self recovery request
+ * @func: the name of the function that called cds_trigger_recovery
+ * @line: the line number of the call site which called cds_trigger_recovery
+ *
+ * Return: none
+ */
+static void cds_trigger_recovery_handler(const char *func, const uint32_t line)
+{
+	QDF_STATUS status;
+	qdf_runtime_lock_t rtl;
+	qdf_device_t qdf;
+
+	/* NOTE! This code path is delicate! Think very carefully before
+	 * modifying the content or order of the following. Please review any
+	 * potential changes with someone closely familiar with this feature.
+	 */
+
+	if (cds_is_driver_recovering()) {
+		cds_info("WLAN recovery already in progress");
+		return;
+	}
+
+	if (cds_is_driver_in_bad_state()) {
+		cds_info("WLAN has already failed recovery");
+		return;
+	}
+
+	if (cds_is_fw_down()) {
+		cds_info("Firmware has already initiated recovery");
+		return;
+	}
+
+	/* if *wlan* recovery is disabled, crash here for debugging */
+	if (!cds_is_self_recovery_enabled()) {
+		QDF_DEBUG_PANIC("WLAN recovery is not enabled (via %s:%d)",
+				func, line);
+		return;
+	}
+
+	/* ignore recovery if we are unloading; it would be a waste anyway */
+	if (cds_is_driver_unloading()) {
+		cds_info("WLAN is unloading; ignore recovery");
+		return;
+	}
+
+	qdf = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	if (!qdf) {
+		cds_err("Qdf context is null");
+		return;
+	}
+
+	status = qdf_runtime_lock_init(&rtl);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_err("qdf_runtime_lock_init failed, status: %d", status);
+		return;
+	}
+
+	status = qdf_runtime_pm_prevent_suspend(&rtl);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cds_err("Failed to acquire runtime pm lock");
+		goto deinit_rtl;
+	}
+
+	cds_force_assert_target(qdf);
+
+	status = qdf_runtime_pm_allow_suspend(&rtl);
+	if (QDF_IS_STATUS_ERROR(status))
+		cds_err("Failed to release runtime pm lock");
+
+deinit_rtl:
+	qdf_runtime_lock_deinit(&rtl);
+}
+
+static void cds_trigger_recovery_work(void *context)
+{
+	struct cds_recovery_call_info *call_info = context;
+
+	cds_trigger_recovery_handler(call_info->func, call_info->line);
+}
+
+void __cds_trigger_recovery(enum qdf_hang_reason reason, const char *func,
+			    const uint32_t line)
+{
+	if (!gp_cds_context) {
+		cds_err("gp_cds_context is null");
+		return;
+	}
+
+	gp_cds_context->recovery_reason = reason;
+
+	if (in_atomic()) {
+		__cds_recovery_caller.func = func;
+		__cds_recovery_caller.line = line;
+		qdf_queue_work(0, gp_cds_context->cds_recovery_wq,
+			       &gp_cds_context->cds_recovery_work);
+		return;
+	}
+
+	cds_trigger_recovery_handler(func, line);
+}
+
+/**
+ * cds_get_recovery_reason() - get self recovery reason
+ * @reason: recovery reason
+ *
+ * Return: None
+ */
+void cds_get_recovery_reason(enum qdf_hang_reason *reason)
+{
+	if (!gp_cds_context) {
+		cds_err("gp_cds_context is null");
+		return;
+	}
+
+	*reason = gp_cds_context->recovery_reason;
+}
+
+/**
+ * cds_reset_recovery_reason() - reset the reason to unspecified
+ *
+ * Return: None
+ */
+void cds_reset_recovery_reason(void)
+{
+	if (!gp_cds_context) {
+		cds_err("gp_cds_context is null");
+		return;
+	}
+
+	gp_cds_context->recovery_reason = QDF_REASON_UNSPECIFIED;
+}
+
+/**
+ * cds_get_monotonic_boottime() - Get kernel boot time.
+ *
+ * Return: Time in microseconds
+ */
+
+uint64_t cds_get_monotonic_boottime(void)
+{
+	struct timespec ts;
+
+	get_monotonic_boottime(&ts);
+	return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
+}
+
+/**
+ * cds_set_wakelock_logging() - Logging of wakelock enabled/disabled
+ * @value: Boolean value
+ *
+ * This function is used to set the flag which will indicate whether
+ * logging of wakelock is enabled or not
+ *
+ * Return: None
+ */
+void cds_set_wakelock_logging(bool value)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invald");
+		return;
+	}
+	p_cds_context->is_wakelock_log_enabled = value;
+}
+
+/**
+ * cds_is_wakelock_enabled() - Check if logging of wakelock is enabled/disabled
+ * @value: Boolean value
+ *
+ * This function is used to check whether logging of wakelock is enabled or not
+ *
+ * Return: true if logging of wakelock is enabled
+ */
+bool cds_is_wakelock_enabled(void)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invald");
+		return false;
+	}
+	return p_cds_context->is_wakelock_log_enabled;
+}
+
+/**
+ * cds_set_ring_log_level() - Sets the log level of a particular ring
+ * @ring_id: ring_id
+ * @log_levelvalue: Log level specificed
+ *
+ * This function converts HLOS values to driver log levels and sets the log
+ * level of a particular ring accordingly.
+ *
+ * Return: None
+ */
+void cds_set_ring_log_level(uint32_t ring_id, uint32_t log_level)
+{
+	struct cds_context *p_cds_context;
+	uint32_t log_val;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invald");
+		return;
+	}
+
+	switch (log_level) {
+	case LOG_LEVEL_NO_COLLECTION:
+		log_val = WLAN_LOG_LEVEL_OFF;
+		break;
+	case LOG_LEVEL_NORMAL_COLLECT:
+		log_val = WLAN_LOG_LEVEL_NORMAL;
+		break;
+	case LOG_LEVEL_ISSUE_REPRO:
+		log_val = WLAN_LOG_LEVEL_REPRO;
+		break;
+	case LOG_LEVEL_ACTIVE:
+	default:
+		log_val = WLAN_LOG_LEVEL_ACTIVE;
+		break;
+	}
+
+	if (ring_id == RING_ID_WAKELOCK) {
+		p_cds_context->wakelock_log_level = log_val;
+		return;
+	} else if (ring_id == RING_ID_CONNECTIVITY) {
+		p_cds_context->connectivity_log_level = log_val;
+		return;
+	} else if (ring_id == RING_ID_PER_PACKET_STATS) {
+		p_cds_context->packet_stats_log_level = log_val;
+		return;
+	} else if (ring_id == RING_ID_DRIVER_DEBUG) {
+		p_cds_context->driver_debug_log_level = log_val;
+		return;
+	} else if (ring_id == RING_ID_FIRMWARE_DEBUG) {
+		p_cds_context->fw_debug_log_level = log_val;
+		return;
+	}
+}
+
+/**
+ * cds_get_ring_log_level() - Get the a ring id's log level
+ * @ring_id: Ring id
+ *
+ * Fetch and return the log level corresponding to a ring id
+ *
+ * Return: Log level corresponding to the ring ID
+ */
+enum wifi_driver_log_level cds_get_ring_log_level(uint32_t ring_id)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invald");
+		return WLAN_LOG_LEVEL_OFF;
+	}
+
+	if (ring_id == RING_ID_WAKELOCK)
+		return p_cds_context->wakelock_log_level;
+	else if (ring_id == RING_ID_CONNECTIVITY)
+		return p_cds_context->connectivity_log_level;
+	else if (ring_id == RING_ID_PER_PACKET_STATS)
+		return p_cds_context->packet_stats_log_level;
+	else if (ring_id == RING_ID_DRIVER_DEBUG)
+		return p_cds_context->driver_debug_log_level;
+	else if (ring_id == RING_ID_FIRMWARE_DEBUG)
+		return p_cds_context->fw_debug_log_level;
+
+	return WLAN_LOG_LEVEL_OFF;
+}
+
+/**
+ * cds_set_multicast_logging() - Set mutlicast logging value
+ * @value: Value of multicast logging
+ *
+ * Set the multicast logging value which will indicate
+ * whether to multicast host and fw messages even
+ * without any registration by userspace entity
+ *
+ * Return: None
+ */
+void cds_set_multicast_logging(uint8_t value)
+{
+	cds_multicast_logging = value;
+}
+
+/**
+ * cds_is_multicast_logging() - Get multicast logging value
+ *
+ * Get the multicast logging value which will indicate
+ * whether to multicast host and fw messages even
+ * without any registration by userspace entity
+ *
+ * Return: 0 - Multicast logging disabled, 1 - Multicast logging enabled
+ */
+uint8_t cds_is_multicast_logging(void)
+{
+	return cds_multicast_logging;
+}
+
+/*
+ * cds_init_log_completion() - Initialize log param structure
+ *
+ * This function is used to initialize the logging related
+ * parameters
+ *
+ * Return: None
+ */
+void cds_init_log_completion(void)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invalid");
+		return;
+	}
+
+	p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
+	p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
+	p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
+	p_cds_context->log_complete.is_report_in_progress = false;
+}
+
+/**
+ * cds_set_log_completion() - Store the logging params
+ * @is_fatal: Indicates if the event triggering bug report is fatal or not
+ * @indicator: Source which trigerred the bug report
+ * @reason_code: Reason for triggering bug report
+ * @recovery_needed: If recovery is needed after bug report
+ *
+ * This function is used to set the logging parameters based on the
+ * caller
+ *
+ * Return: 0 if setting of params is successful
+ */
+QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
+		uint32_t indicator,
+		uint32_t reason_code,
+		bool recovery_needed)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invalid");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
+	p_cds_context->log_complete.is_fatal = is_fatal;
+	p_cds_context->log_complete.indicator = indicator;
+	p_cds_context->log_complete.reason_code = reason_code;
+	p_cds_context->log_complete.recovery_needed = recovery_needed;
+	p_cds_context->log_complete.is_report_in_progress = true;
+	qdf_spinlock_release(&p_cds_context->bug_report_lock);
+	cds_debug("is_fatal %d indicator %d reason_code %d recovery needed %d",
+		  is_fatal, indicator, reason_code, recovery_needed);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cds_get_and_reset_log_completion() - Get and reset logging related params
+ * @is_fatal: Indicates if the event triggering bug report is fatal or not
+ * @indicator: Source which trigerred the bug report
+ * @reason_code: Reason for triggering bug report
+ * @recovery_needed: If recovery is needed after bug report
+ *
+ * This function is used to get the logging related parameters
+ *
+ * Return: None
+ */
+void cds_get_and_reset_log_completion(uint32_t *is_fatal,
+		uint32_t *indicator,
+		uint32_t *reason_code,
+		bool *recovery_needed)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invalid");
+		return;
+	}
+
+	qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
+	*is_fatal =  p_cds_context->log_complete.is_fatal;
+	*indicator = p_cds_context->log_complete.indicator;
+	*reason_code = p_cds_context->log_complete.reason_code;
+	*recovery_needed = p_cds_context->log_complete.recovery_needed;
+
+	/* reset */
+	p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
+	p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
+	p_cds_context->log_complete.is_report_in_progress = false;
+	p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
+	p_cds_context->log_complete.recovery_needed = false;
+	qdf_spinlock_release(&p_cds_context->bug_report_lock);
+}
+
+/**
+ * cds_is_log_report_in_progress() - Check if bug reporting is in progress
+ *
+ * This function is used to check if the bug reporting is already in progress
+ *
+ * Return: true if the bug reporting is in progress
+ */
+bool cds_is_log_report_in_progress(void)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invalid");
+		return true;
+	}
+	return p_cds_context->log_complete.is_report_in_progress;
+}
+
+/**
+ * cds_is_fatal_event_enabled() - Return if fatal event is enabled
+ *
+ * Return true if fatal event is enabled.
+ */
+bool cds_is_fatal_event_enabled(void)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invalid");
+		return false;
+	}
+
+
+	return p_cds_context->enable_fatal_event;
+}
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+bool cds_is_ptp_rx_opt_enabled(void)
+{
+	struct hdd_context *hdd_ctx;
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invalid");
+		return false;
+	}
+
+	hdd_ctx = (struct hdd_context *)(p_cds_context->hdd_context);
+	if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
+		cds_err("Hdd Context is Null");
+		return false;
+	}
+
+	return hdd_tsf_is_rx_set(hdd_ctx);
+}
+
+bool cds_is_ptp_tx_opt_enabled(void)
+{
+	struct hdd_context *hdd_ctx;
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invalid");
+		return false;
+	}
+
+	hdd_ctx = (struct hdd_context *)(p_cds_context->hdd_context);
+	if ((NULL == hdd_ctx) || (NULL == hdd_ctx->config)) {
+		cds_err("Hdd Context is Null");
+		return false;
+	}
+
+	return hdd_tsf_is_tx_set(hdd_ctx);
+}
+#endif
+
+/**
+ * cds_get_log_indicator() - Get the log flush indicator
+ *
+ * This function is used to get the log flush indicator
+ *
+ * Return: log indicator
+ */
+uint32_t cds_get_log_indicator(void)
+{
+	struct cds_context *p_cds_context;
+	uint32_t indicator;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invalid");
+		return WLAN_LOG_INDICATOR_UNUSED;
+	}
+
+	if (cds_is_load_or_unload_in_progress() ||
+	    cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		return WLAN_LOG_INDICATOR_UNUSED;
+	}
+
+	qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
+	indicator = p_cds_context->log_complete.indicator;
+	qdf_spinlock_release(&p_cds_context->bug_report_lock);
+	return indicator;
+}
+
+/**
+ * cds_wlan_flush_host_logs_for_fatal() - Wrapper to flush host logs
+ *
+ * This function is used to send signal to the logger thread to
+ * flush the host logs.
+ *
+ * Return: None
+ *
+ */
+void cds_wlan_flush_host_logs_for_fatal(void)
+{
+	wlan_flush_host_logs_for_fatal();
+}
+
+/**
+ * cds_flush_logs() - Report fatal event to userspace
+ * @is_fatal: Indicates if the event triggering bug report is fatal or not
+ * @indicator: Source which trigerred the bug report
+ * @reason_code: Reason for triggering bug report
+ * @dump_mac_trace: If mac trace are needed in logs.
+ * @recovery_needed: If recovery is needed after bug report
+ *
+ * This function sets the log related params and send the WMI command to the
+ * FW to flush its logs. On receiving the flush completion event from the FW
+ * the same will be conveyed to userspace
+ *
+ * Return: 0 on success
+ */
+QDF_STATUS cds_flush_logs(uint32_t is_fatal,
+		uint32_t indicator,
+		uint32_t reason_code,
+		bool dump_mac_trace,
+		bool recovery_needed)
+{
+	uint32_t ret;
+	QDF_STATUS status;
+
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invalid");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (!p_cds_context->enable_fatal_event) {
+		cds_err("Fatal event not enabled");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (cds_is_load_or_unload_in_progress() ||
+	    cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		cds_err("un/Load/SSR in progress");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (cds_is_log_report_in_progress()) {
+		cds_err("Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
+			is_fatal, indicator, reason_code);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = cds_set_log_completion(is_fatal, indicator,
+		reason_code, recovery_needed);
+	if (QDF_STATUS_SUCCESS != status) {
+		cds_err("Failed to set log trigger params");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cds_debug("Triggering bug report: type:%d, indicator=%d reason_code=%d",
+		  is_fatal, indicator, reason_code);
+
+	if (dump_mac_trace)
+		qdf_trace_dump_all(p_cds_context->mac_context, 0, 0, 500, 0);
+
+	if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator) {
+		cds_wlan_flush_host_logs_for_fatal();
+		return QDF_STATUS_SUCCESS;
+	}
+
+	ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->mac_context);
+	if (0 != ret) {
+		cds_err("Failed to send flush FW log");
+		cds_init_log_completion();
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cds_logging_set_fw_flush_complete() - Wrapper for FW log flush completion
+ *
+ * This function is used to send signal to the logger thread to indicate
+ * that the flushing of FW logs is complete by the FW
+ *
+ * Return: None
+ *
+ */
+void cds_logging_set_fw_flush_complete(void)
+{
+	wlan_logging_set_fw_flush_complete();
+}
+
+/**
+ * cds_set_fatal_event() - set fatal event status
+ * @value: pending statue to set
+ *
+ * Return: None
+ */
+void cds_set_fatal_event(bool value)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		cds_err("cds context is Invalid");
+		return;
+	}
+	p_cds_context->enable_fatal_event = value;
+}
+
+/**
+ * cds_get_radio_index() - get radio index
+ *
+ * Return: radio index otherwise, -EINVAL
+ */
+int cds_get_radio_index(void)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		/*
+		 * To avoid recursive call, this should not change to
+		 * QDF_TRACE().
+		 */
+		pr_err("%s: cds context is invalid\n", __func__);
+		return -EINVAL;
+	}
+
+	return p_cds_context->radio_index;
+}
+
+/**
+ * cds_set_radio_index() - set radio index
+ * @radio_index:	the radio index to set
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_set_radio_index(int radio_index)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		pr_err("%s: cds context is invalid\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	p_cds_context->radio_index = radio_index;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cds_init_ini_config() - API to initialize CDS configuration parameters
+ * @cfg: CDS Configuration
+ *
+ * Return: void
+ */
+
+void cds_init_ini_config(struct cds_config_info *cfg)
+{
+	struct cds_context *cds_ctx;
+
+	cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+	if (!cds_ctx) {
+		cds_err("Invalid CDS Context");
+		return;
+	}
+
+	cds_ctx->cds_cfg = cfg;
+}
+
+/**
+ * cds_deinit_ini_config() - API to free CDS configuration parameters
+ *
+ * Return: void
+ */
+void cds_deinit_ini_config(void)
+{
+	struct cds_context *cds_ctx;
+	struct cds_config_info *cds_cfg;
+
+	cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+	if (!cds_ctx) {
+		cds_err("Invalid CDS Context");
+		return;
+	}
+
+	cds_cfg = cds_ctx->cds_cfg;
+	cds_ctx->cds_cfg = NULL;
+
+	if (cds_cfg)
+		qdf_mem_free(cds_cfg);
+}
+
+/**
+ * cds_get_ini_config() - API to get CDS configuration parameters
+ *
+ * Return: cds config structure
+ */
+struct cds_config_info *cds_get_ini_config(void)
+{
+	struct cds_context *cds_ctx;
+
+	cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+	if (!cds_ctx) {
+		cds_err("Invalid CDS Context");
+		return NULL;
+	}
+
+	return cds_ctx->cds_cfg;
+}
+
+/**
+ * cds_is_5_mhz_enabled() - API to get 5MHZ enabled
+ *
+ * Return: true if 5 mhz is enabled, false otherwise
+ */
+bool cds_is_5_mhz_enabled(void)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
+	if (!p_cds_context) {
+		cds_err("%s: cds context is invalid", __func__);
+		return false;
+	}
+
+	if (p_cds_context->cds_cfg)
+		return (p_cds_context->cds_cfg->sub_20_channel_width ==
+						WLAN_SUB_20_CH_WIDTH_5);
+
+	return false;
+}
+
+/**
+ * cds_is_10_mhz_enabled() - API to get 10-MHZ enabled
+ *
+ * Return: true if 10 mhz is enabled, false otherwise
+ */
+bool cds_is_10_mhz_enabled(void)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
+	if (!p_cds_context) {
+		cds_err("%s: cds context is invalid", __func__);
+		return false;
+	}
+
+	if (p_cds_context->cds_cfg)
+		return (p_cds_context->cds_cfg->sub_20_channel_width ==
+						WLAN_SUB_20_CH_WIDTH_10);
+
+	return false;
+}
+
+/**
+ * cds_is_sub_20_mhz_enabled() - API to get sub 20-MHZ enabled
+ *
+ * Return: true if 5 or 10 mhz is enabled, false otherwise
+ */
+bool cds_is_sub_20_mhz_enabled(void)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
+	if (!p_cds_context) {
+		cds_err("%s: cds context is invalid", __func__);
+		return false;
+	}
+
+	if (p_cds_context->cds_cfg)
+		return p_cds_context->cds_cfg->sub_20_channel_width;
+
+	return false;
+}
+
+/**
+ * cds_is_self_recovery_enabled() - API to get self recovery enabled
+ *
+ * Return: true if self recovery enabled, false otherwise
+ */
+bool cds_is_self_recovery_enabled(void)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
+	if (!p_cds_context) {
+		cds_err("%s: cds context is invalid", __func__);
+		return false;
+	}
+
+	if (p_cds_context->cds_cfg)
+		return p_cds_context->cds_cfg->self_recovery_enabled;
+
+	return false;
+}
+
+/**
+ * cds_is_fw_down() - Is FW down or not
+ *
+ * Return: true if FW is down and false otherwise.
+ */
+bool cds_is_fw_down(void)
+{
+	qdf_device_t qdf_ctx;
+
+	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	if (!qdf_ctx) {
+		cds_err("cds context is invalid");
+		return false;
+	}
+
+	return pld_is_fw_down(qdf_ctx->dev);
+}
+
+/**
+ * cds_svc_fw_shutdown_ind() - API to send userspace about FW crash
+ *
+ * @dev: Device Pointer
+ *
+ * Return: None
+ */
+void cds_svc_fw_shutdown_ind(struct device *dev)
+{
+	hdd_svc_fw_shutdown_ind(dev);
+}
+
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+/*
+ * cds_pkt_stats_to_logger_thread() - send pktstats to user
+ * @pl_hdr: Pointer to pl_hdr
+ * @pkt_dump: Pointer to pkt_dump data structure.
+ * @data: Pointer to data
+ *
+ * This function is used to send the pkt stats to SVC module.
+ *
+ * Return: None
+ */
+inline void cds_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump,
+						void *data)
+{
+	if (cds_get_ring_log_level(RING_ID_PER_PACKET_STATS) !=
+						WLAN_LOG_LEVEL_ACTIVE)
+		return;
+
+	wlan_pkt_stats_to_logger_thread(pl_hdr, pkt_dump, data);
+}
+#endif
+
+/**
+ * cds_get_conparam() - Get the connection mode parameters
+ *
+ * Return the connection mode parameter set by insmod or set during statically
+ * linked driver
+ *
+ * Return: enum QDF_GLOBAL_MODE
+ */
+enum QDF_GLOBAL_MODE cds_get_conparam(void)
+{
+	enum QDF_GLOBAL_MODE con_mode;
+
+	con_mode = hdd_get_conparam();
+
+	return con_mode;
+}
+
+#ifdef FEATURE_HTC_CREDIT_HISTORY
+inline void
+cds_print_htc_credit_history(uint32_t count, qdf_abstract_print *print,
+			     void *print_priv)
+{
+	htc_print_credit_history(gp_cds_context->htc_ctx, count,
+				 print, print_priv);
+}
+#endif
+
+uint32_t cds_get_connectivity_stats_pkt_bitmap(void *context)
+{
+	struct hdd_adapter *adapter = NULL;
+
+	if (!context)
+		return 0;
+
+	adapter = (struct hdd_adapter *)context;
+	if (unlikely(adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
+		cds_err("Magic cookie(%x) for adapter sanity verification is invalid",
+			adapter->magic);
+		return 0;
+	}
+	return adapter->pkt_type_bitmap;
+}
+
+/**
+ * cds_get_arp_stats_gw_ip() - get arp stats track IP
+ *
+ * Return: ARP stats IP to track
+ */
+uint32_t cds_get_arp_stats_gw_ip(void *context)
+{
+	struct hdd_adapter *adapter = NULL;
+
+	if (!context)
+		return 0;
+
+	adapter = (struct hdd_adapter *)context;
+
+	if (unlikely(adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
+		cds_err("Magic cookie(%x) for adapter sanity verification is invalid",
+			adapter->magic);
+		return 0;
+	}
+
+	return adapter->track_arp_ip;
+}
+
+/**
+ * cds_incr_arp_stats_tx_tgt_delivered() - increment ARP stats
+ *
+ * Return: none
+ */
+void cds_incr_arp_stats_tx_tgt_delivered(void)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter = NULL;
+
+	hdd_ctx = gp_cds_context->hdd_context;
+	if (!hdd_ctx) {
+		cds_err("Hdd Context is Null");
+		return;
+	}
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (QDF_STA_MODE == adapter->device_mode)
+			break;
+	}
+
+	if (adapter)
+		adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent++;
+}
+
+/**
+ * cds_incr_arp_stats_tx_tgt_acked() - increment ARP stats
+ *
+ * Return: none
+ */
+void cds_incr_arp_stats_tx_tgt_acked(void)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter = NULL;
+
+	hdd_ctx = gp_cds_context->hdd_context;
+	if (!hdd_ctx) {
+		cds_err("Hdd Context is Null");
+		return;
+	}
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (QDF_STA_MODE == adapter->device_mode)
+			break;
+	}
+
+	if (adapter)
+		adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt++;
+}
+
+#ifdef ENABLE_SMMU_S1_TRANSLATION
+QDF_STATUS cds_smmu_mem_map_setup(qdf_device_t osdev, bool ipa_present)
+{
+	struct dma_iommu_mapping *mapping;
+	bool ipa_smmu_enabled;
+	bool wlan_smmu_enabled;
+
+	mapping = pld_smmu_get_mapping(osdev->dev);
+	if (mapping) {
+		int attr = 0;
+		int errno = iommu_domain_get_attr(mapping->domain,
+						  DOMAIN_ATTR_S1_BYPASS, &attr);
+
+		wlan_smmu_enabled = !errno && !attr;
+	} else {
+		cds_info("No SMMU mapping present");
+		wlan_smmu_enabled = false;
+	}
+
+	if (!wlan_smmu_enabled) {
+		osdev->smmu_s1_enabled = false;
+		goto exit_with_success;
+	}
+
+	if (!ipa_present) {
+		osdev->smmu_s1_enabled = true;
+		goto exit_with_success;
+	}
+
+	ipa_smmu_enabled = qdf_get_ipa_smmu_enabled();
+
+	osdev->smmu_s1_enabled = ipa_smmu_enabled && wlan_smmu_enabled;
+	if (ipa_smmu_enabled != wlan_smmu_enabled) {
+		cds_err("SMMU mismatch; IPA:%s, WLAN:%s",
+			ipa_smmu_enabled ? "enabled" : "disabled",
+			wlan_smmu_enabled ? "enabled" : "disabled");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+exit_with_success:
+	osdev->iommu_mapping = mapping;
+
+	cds_info("SMMU S1 %s", osdev->smmu_s1_enabled ? "enabled" : "disabled");
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef IPA_OFFLOAD
+int cds_smmu_map_unmap(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
+{
+	return ucfg_ipa_uc_smmu_map(map, num_buf, buf_arr);
+}
+#else
+int cds_smmu_map_unmap(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
+{
+	return 0;
+}
+#endif
+
+#else
+QDF_STATUS cds_smmu_mem_map_setup(qdf_device_t osdev, bool ipa_present)
+{
+	osdev->smmu_s1_enabled = false;
+	osdev->iommu_mapping = NULL;
+	return QDF_STATUS_SUCCESS;
+}
+
+int cds_smmu_map_unmap(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
+{
+	return 0;
+}
+#endif
diff --git a/core/cds/src/cds_ieee80211_common_i.h b/core/cds/src/cds_ieee80211_common_i.h
new file mode 100644
index 0000000..72566a7
--- /dev/null
+++ b/core/cds/src/cds_ieee80211_common_i.h
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 2013-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.
+ */
+
+#ifndef CDS_COMMON__IEEE80211_I_H_
+#define CDS_COMMON__IEEE80211_I_H_
+
+/**
+ * enum ieee80211_phymode - not really a mode; there are really multiple PHY's
+ * @IEEE80211_MODE_AUTO - autoselect
+ * @IEEE80211_MODE_11A - 5GHz, OFDM
+ * @IEEE80211_MODE_11B - 2GHz, CCK
+ * @IEEE80211_MODE_11G - 2GHz, OFDM
+ * @IEEE80211_MODE_FH - 2GHz, GFSK
+ * @IEEE80211_MODE_TURBO_A - 5GHz, OFDM, 2x clock dynamic turbo
+ * @IEEE80211_MODE_TURBO_G - 2GHz, OFDM, 2x clock dynamic turbo
+ * @IEEE80211_MODE_11NA_HT20 - 5Ghz, HT20
+ * @IEEE80211_MODE_11NG_HT20 - 2Ghz, HT20
+ * @IEEE80211_MODE_11NA_HT40PLUS - 5Ghz, HT40 (ext ch +1)
+ * @IEEE80211_MODE_11NA_HT40MINUS - 5Ghz, HT40 (ext ch -1)
+ * @IEEE80211_MODE_11NG_HT40PLUS - 2Ghz, HT40 (ext ch +1)
+ * @IEEE80211_MODE_11NG_HT40MINUS - 2Ghz, HT40 (ext ch -1)
+ * @IEEE80211_MODE_11NG_HT40 - 2Ghz, Auto HT40
+ * @IEEE80211_MODE_11NA_HT40 - 2Ghz, Auto HT40
+ * @IEEE80211_MODE_11AC_VHT20 - 5Ghz, VHT20
+ * @IEEE80211_MODE_11AC_VHT40PLUS - 5Ghz, VHT40 (Ext ch +1)
+ * @IEEE80211_MODE_11AC_VHT40MINUS - 5Ghz VHT40 (Ext ch -1)
+ * @IEEE80211_MODE_11AC_VHT40 - 5Ghz, VHT40
+ * @IEEE80211_MODE_11AC_VHT80 - 5Ghz, VHT80
+ * @IEEE80211_MODE_2G_AUTO - 2G 11 b/g/n autoselect
+ * @IEEE80211_MODE_5G_AUTO - 5G 11 a/n/ac autoselect
+ * @IEEE80211_MODE_11AGN - Support 11N in both 2G and 5G
+ * @IEEE80211_MODE_11AX_HE20 - HE20
+ * @IEEE80211_MODE_11AX_HE40 - HE40
+ * @IEEE80211_MODE_11AX_HE40PLUS - HE40 (ext ch +1)
+ * @IEEE80211_MODE_11AX_HE40MINUS - HE40 (ext ch -1)
+ * @IEEE80211_MODE_11AX_HE80 - HE80
+ * @IEEE80211_MODE_11AX_HE80P80 - HE 80P80
+ * @IEEE80211_MODE_11AX_HE160 - HE160
+ * @IEEE80211_MODE_MAX - Maximum possible value
+ */
+enum ieee80211_phymode {
+	IEEE80211_MODE_AUTO = 0,
+	IEEE80211_MODE_11A = 1,
+	IEEE80211_MODE_11B = 2,
+	IEEE80211_MODE_11G = 3,
+	IEEE80211_MODE_FH = 4,
+	IEEE80211_MODE_TURBO_A = 5,
+	IEEE80211_MODE_TURBO_G = 6,
+	IEEE80211_MODE_11NA_HT20 = 7,
+	IEEE80211_MODE_11NG_HT20 = 8,
+	IEEE80211_MODE_11NA_HT40PLUS = 9,
+	IEEE80211_MODE_11NA_HT40MINUS = 10,
+	IEEE80211_MODE_11NG_HT40PLUS = 11,
+	IEEE80211_MODE_11NG_HT40MINUS = 12,
+	IEEE80211_MODE_11NG_HT40 = 13,
+	IEEE80211_MODE_11NA_HT40 = 14,
+	IEEE80211_MODE_11AC_VHT20 = 15,
+	IEEE80211_MODE_11AC_VHT40PLUS = 16,
+	IEEE80211_MODE_11AC_VHT40MINUS = 17,
+	IEEE80211_MODE_11AC_VHT40 = 18,
+	IEEE80211_MODE_11AC_VHT80 = 19,
+	IEEE80211_MODE_2G_AUTO = 20,
+	IEEE80211_MODE_5G_AUTO = 21,
+	IEEE80211_MODE_11AGN = 22,
+	IEEE80211_MODE_11AX_HE20 = 23,
+	IEEE80211_MODE_11AX_HE40 = 24,
+	IEEE80211_MODE_11AX_HE40PLUS = 25,
+	IEEE80211_MODE_11AX_HE40MINUS = 26,
+	IEEE80211_MODE_11AX_HE80 = 27,
+	IEEE80211_MODE_11AX_HE80P80 = 28,
+	IEEE80211_MODE_11AX_HE160 = 29,
+
+	/* Do not add after this line */
+	IEEE80211_MODE_MAX = IEEE80211_MODE_11AX_HE160,
+};
+
+/**
+ * enum ieee80211_opmode - operating mode
+ * @IEEE80211_M_IBSS - IBSS (adhoc) station
+ * @IEEE80211_M_HOSTAP - Software Access Point
+ * @IEEE80211_OPMODE_MAX = Highest numbered opmode in the list
+ * @IEEE80211_M_ANY - Any of the above; used by NDIS 6.x
+ *
+*/
+enum ieee80211_opmode {
+	IEEE80211_M_IBSS = 0,
+	IEEE80211_M_HOSTAP = 6,
+
+	/* Do not add after this line */
+	IEEE80211_OPMODE_MAX = IEEE80211_M_HOSTAP,
+
+	IEEE80211_M_ANY = 0xFF,
+};
+
+/*
+ * 802.11n
+ */
+#define IEEE80211_CWM_EXTCH_BUSY_THRESHOLD 30
+
+enum ieee80211_cwm_mode {
+	IEEE80211_CWM_MODE20,
+	IEEE80211_CWM_MODE2040,
+	IEEE80211_CWM_MODE40,
+	IEEE80211_CWM_MODEMAX
+};
+
+enum ieee80211_cwm_extprotspacing {
+	IEEE80211_CWM_EXTPROTSPACING20,
+	IEEE80211_CWM_EXTPROTSPACING25,
+	IEEE80211_CWM_EXTPROTSPACINGMAX
+};
+
+enum ieee80211_cwm_width {
+	IEEE80211_CWM_WIDTH20,
+	IEEE80211_CWM_WIDTH40,
+	IEEE80211_CWM_WIDTH80,
+	IEEE80211_CWM_WIDTHINVALID = 0xff       /* user invalid value */
+};
+
+enum ieee80211_cwm_extprotmode {
+	IEEE80211_CWM_EXTPROTNONE,      /* no protection */
+	IEEE80211_CWM_EXTPROTCTSONLY,   /* CTS to self */
+	IEEE80211_CWM_EXTPROTRTSCTS,    /* RTS-CTS */
+	IEEE80211_CWM_EXTPROTMAX
+};
+
+enum ieee80211_fixed_rate_mode {
+	IEEE80211_FIXED_RATE_NONE = 0,
+	IEEE80211_FIXED_RATE_MCS = 1,   /* HT rates */
+	IEEE80211_FIXED_RATE_LEGACY = 2,        /* legacy rates */
+	IEEE80211_FIXED_RATE_VHT = 3    /* VHT rates */
+};
+
+/* Holds the fixed rate information for each VAP */
+struct ieee80211_fixed_rate {
+	enum ieee80211_fixed_rate_mode mode;
+	uint32_t series;
+	uint32_t retries;
+};
+
+/*
+ * 802.11g protection mode.
+ */
+enum ieee80211_protmode {
+	IEEE80211_PROT_NONE = 0,        /* no protection */
+	IEEE80211_PROT_CTSONLY = 1,     /* CTS to self */
+	IEEE80211_PROT_RTSCTS = 2,      /* RTS-CTS */
+};
+
+/*
+ * Roaming mode is effectively who controls the operation
+ * of the 802.11 state machine when operating as a station.
+ * State transitions are controlled either by the driver
+ * (typically when management frames are processed by the
+ * hardware/firmware), the host (auto/normal operation of
+ * the 802.11 layer), or explicitly through ioctl requests
+ * when applications like wpa_supplicant want control.
+ */
+enum ieee80211_roamingmode {
+	IEEE80211_ROAMING_DEVICE = 0,   /* driver/hardware control */
+	IEEE80211_ROAMING_AUTO = 1,     /* 802.11 layer control */
+	IEEE80211_ROAMING_MANUAL = 2,   /* application control */
+};
+
+/*
+ * Scanning mode controls station scanning work; this is
+ * used only when roaming mode permits the host to select
+ * the bss to join/channel to use.
+ */
+enum ieee80211_scanmode {
+	IEEE80211_SCAN_DEVICE = 0,      /* driver/hardware control */
+	IEEE80211_SCAN_BEST = 1,        /* 802.11 layer selects best */
+	IEEE80211_SCAN_FIRST = 2,       /* take first suitable candidate */
+};
+
+#define IEEE80211_NWID_LEN      32
+#define IEEE80211_CHAN_MAX      255
+#define IEEE80211_CHAN_BYTES    32      /* howmany(IEEE80211_CHAN_MAX, NBBY) */
+#define IEEE80211_CHAN_ANY      (-1)    /* token for ``any channel'' */
+#define IEEE80211_CHAN_ANYC \
+	((struct ieee80211_channel *) IEEE80211_CHAN_ANY)
+
+#define IEEE80211_CHAN_DEFAULT          11
+#define IEEE80211_CHAN_DEFAULT_11A      52
+#define IEEE80211_CHAN_ADHOC_DEFAULT1   10
+#define IEEE80211_CHAN_ADHOC_DEFAULT2   11
+
+#define IEEE80211_RADAR_11HCOUNT        5
+#define IEEE80211_RADAR_TEST_MUTE_CHAN_11A      36      /* Move to channel 36 for mute test */
+#define IEEE80211_RADAR_TEST_MUTE_CHAN_11NHT20  36
+#define IEEE80211_RADAR_TEST_MUTE_CHAN_11NHT40U 36
+#define IEEE80211_RADAR_TEST_MUTE_CHAN_11NHT40D 40      /* Move to channel 40 for HT40D mute test */
+#define IEEE80211_RADAR_DETECT_DEFAULT_DELAY    60000   /* STA ignore AP beacons during this period in millisecond */
+
+#define IEEE80211_2GCSA_TBTTCOUNT        3
+
+/* bits 0-3 are for private use by drivers */
+/* channel attributes */
+#define IEEE80211_CHAN_TURBO            0x00000010      /* Turbo channel */
+#define IEEE80211_CHAN_CCK              0x00000020      /* CCK channel */
+#define IEEE80211_CHAN_OFDM             0x00000040      /* OFDM channel */
+#define IEEE80211_CHAN_2GHZ             0x00000080      /* 2 GHz spectrum channel. */
+#define IEEE80211_CHAN_5GHZ             0x00000100      /* 5 GHz spectrum channel */
+#define IEEE80211_CHAN_PASSIVE          0x00000200      /* Only passive scan allowed */
+#define IEEE80211_CHAN_DYN              0x00000400      /* Dynamic CCK-OFDM channel */
+#define IEEE80211_CHAN_GFSK             0x00000800      /* GFSK channel (FHSS PHY) */
+#define IEEE80211_CHAN_RADAR_DFS        0x00001000      /* Radar found on channel */
+#define IEEE80211_CHAN_STURBO           0x00002000      /* 11a static turbo channel only */
+#define IEEE80211_CHAN_HALF             0x00004000      /* Half rate channel */
+#define IEEE80211_CHAN_QUARTER          0x00008000      /* Quarter rate channel */
+#define IEEE80211_CHAN_HT20             0x00010000      /* HT 20 channel */
+#define IEEE80211_CHAN_HT40PLUS         0x00020000      /* HT 40 with extension channel above */
+#define IEEE80211_CHAN_HT40MINUS        0x00040000      /* HT 40 with extension channel below */
+#define IEEE80211_CHAN_HT40INTOL        0x00080000      /* HT 40 Intolerant */
+#define IEEE80211_CHAN_VHT20            0x00100000      /* VHT 20 channel */
+#define IEEE80211_CHAN_VHT40PLUS        0x00200000      /* VHT 40 with extension channel above */
+#define IEEE80211_CHAN_VHT40MINUS       0x00400000      /* VHT 40 with extension channel below */
+#define IEEE80211_CHAN_VHT80            0x00800000      /* VHT 80 channel */
+/* HT 40 Intolerant mark bit for ACS use */
+#define IEEE80211_CHAN_HT40INTOLMARK    0x01000000
+/* channel temporarily blocked due to noise */
+#define IEEE80211_CHAN_BLOCKED          0x02000000
+/* VHT 160 channel */
+#define IEEE80211_CHAN_VHT160           0x04000000
+/* VHT 80_80 channel */
+#define IEEE80211_CHAN_VHT80_80         0x08000000
+
+/* flagext */
+#define IEEE80211_CHAN_RADAR_FOUND    0x01
+#define IEEE80211_CHAN_DFS              0x0002  /* DFS required on channel */
+#define IEEE80211_CHAN_DFS_CLEAR        0x0008  /* if channel has been checked for DFS */
+#define IEEE80211_CHAN_11D_EXCLUDED     0x0010  /* excluded in 11D */
+#define IEEE80211_CHAN_CSA_RECEIVED     0x0020  /* Channel Switch Announcement received on this channel */
+#define IEEE80211_CHAN_DISALLOW_ADHOC   0x0040  /* ad-hoc is not allowed */
+#define IEEE80211_CHAN_DISALLOW_HOSTAP  0x0080  /* Station only channel */
+
+/*
+ * Useful combinations of channel characteristics.
+ */
+#define IEEE80211_CHAN_FHSS \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
+#define IEEE80211_CHAN_A \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
+#define IEEE80211_CHAN_B \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
+#define IEEE80211_CHAN_PUREG \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
+#define IEEE80211_CHAN_G \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
+#define IEEE80211_CHAN_108A \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
+#define IEEE80211_CHAN_108G \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
+#define IEEE80211_CHAN_ST \
+	(IEEE80211_CHAN_108A | IEEE80211_CHAN_STURBO)
+
+#define IEEE80211_IS_CHAN_11AC_2G(_c) \
+	(IEEE80211_IS_CHAN_2GHZ((_c)) && IEEE80211_IS_CHAN_VHT((_c)))
+#define IEEE80211_CHAN_11AC_VHT20_2G \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_VHT20)
+#define IEEE80211_CHAN_11AC_VHT40_2G \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_VHT40PLUS | IEEE80211_CHAN_VHT40MINUS)
+#define IEEE80211_CHAN_11AC_VHT80_2G \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_VHT80)
+
+#define IEEE80211_IS_CHAN_11AC_VHT20_2G(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT20_2G) == IEEE80211_CHAN_11AC_VHT20_2G)
+#define IEEE80211_IS_CHAN_11AC_VHT40_2G(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT40_2G) != 0)
+#define IEEE80211_IS_CHAN_11AC_VHT80_2G(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT80_2G) == IEEE80211_CHAN_11AC_VHT80_2G)
+
+#define IEEE80211_CHAN_11NG_HT20 \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_HT20)
+#define IEEE80211_CHAN_11NA_HT20 \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_HT20)
+#define IEEE80211_CHAN_11NG_HT40PLUS \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_HT40PLUS)
+#define IEEE80211_CHAN_11NG_HT40MINUS \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_HT40MINUS)
+#define IEEE80211_CHAN_11NA_HT40PLUS \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_HT40PLUS)
+#define IEEE80211_CHAN_11NA_HT40MINUS \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_HT40MINUS)
+
+#define IEEE80211_CHAN_ALL \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_GFSK | \
+	 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN | \
+	 IEEE80211_CHAN_HT20 | IEEE80211_CHAN_HT40PLUS | IEEE80211_CHAN_HT40MINUS | \
+	 IEEE80211_CHAN_VHT20 | IEEE80211_CHAN_VHT40PLUS | IEEE80211_CHAN_VHT40MINUS | IEEE80211_CHAN_VHT80 | \
+	 IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER)
+#define IEEE80211_CHAN_ALLTURBO	\
+	(IEEE80211_CHAN_ALL | IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO)
+
+#define IEEE80211_IS_CHAN_FHSS(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
+#define IEEE80211_IS_CHAN_A(_c)	\
+	(((_c)->ic_flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
+#define IEEE80211_IS_CHAN_B(_c)	\
+	(((_c)->ic_flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
+#define IEEE80211_IS_CHAN_PUREG(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
+#define IEEE80211_IS_CHAN_G(_c)	\
+	(((_c)->ic_flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
+#define IEEE80211_IS_CHAN_ANYG(_c) \
+	(IEEE80211_IS_CHAN_PUREG(_c) || IEEE80211_IS_CHAN_G(_c))
+#define IEEE80211_IS_CHAN_ST(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_ST) == IEEE80211_CHAN_ST)
+#define IEEE80211_IS_CHAN_108A(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_108A) == IEEE80211_CHAN_108A)
+#define IEEE80211_IS_CHAN_108G(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_108G) == IEEE80211_CHAN_108G)
+
+#define IEEE80211_IS_CHAN_2GHZ(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_2GHZ) != 0)
+#define IEEE80211_IS_CHAN_5GHZ(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_5GHZ) != 0)
+#define IEEE80211_IS_CHAN_OFDM(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_OFDM) != 0)
+#define IEEE80211_IS_CHAN_CCK(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_CCK) != 0)
+#define IEEE80211_IS_CHAN_GFSK(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_GFSK) != 0)
+#define IEEE80211_IS_CHAN_TURBO(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_TURBO) != 0)
+#define IEEE80211_IS_CHAN_WEATHER_RADAR(_c) \
+	((((_c)->ic_freq >= 5600) && ((_c)->ic_freq <= 5650)) \
+	 || (((_c)->ic_flags & IEEE80211_CHAN_HT40PLUS) && (5580 == (_c)->ic_freq)))
+#define IEEE80211_IS_CHAN_STURBO(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_STURBO) != 0)
+#define IEEE80211_IS_CHAN_DTURBO(_c) \
+	(((_c)->ic_flags & \
+	  (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO)) == IEEE80211_CHAN_TURBO)
+#define IEEE80211_IS_CHAN_HALF(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_HALF) != 0)
+#define IEEE80211_IS_CHAN_QUARTER(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_QUARTER) != 0)
+#define IEEE80211_IS_CHAN_PASSIVE(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_PASSIVE) != 0)
+
+#define IEEE80211_IS_CHAN_DFS(_c) \
+	(((_c)->ic_flagext & (IEEE80211_CHAN_DFS|IEEE80211_CHAN_DFS_CLEAR)) == IEEE80211_CHAN_DFS)
+#define IEEE80211_IS_CHAN_DFSFLAG(_c) \
+	(((_c)->ic_flagext & IEEE80211_CHAN_DFS) == IEEE80211_CHAN_DFS)
+#define IEEE80211_IS_CHAN_DISALLOW_ADHOC(_c) \
+	(((_c)->ic_flagext & IEEE80211_CHAN_DISALLOW_ADHOC) != 0)
+#define IEEE80211_IS_CHAN_11D_EXCLUDED(_c) \
+	(((_c)->ic_flagext & IEEE80211_CHAN_11D_EXCLUDED) != 0)
+#define IEEE80211_IS_CHAN_CSA(_c) \
+	(((_c)->ic_flagext & IEEE80211_CHAN_CSA_RECEIVED) != 0)
+#define IEEE80211_IS_CHAN_ODD(_c) \
+	(((_c)->ic_freq == 5170) || ((_c)->ic_freq == 5190) || \
+	 ((_c)->ic_freq == 5210) || ((_c)->ic_freq == 5230))
+#define IEEE80211_IS_CHAN_DISALLOW_HOSTAP(_c) \
+	(((_c)->ic_flagext & IEEE80211_CHAN_DISALLOW_HOSTAP) != 0)
+
+#define IEEE80211_IS_CHAN_11NG_HT20(_c)	\
+	(((_c)->ic_flags & IEEE80211_CHAN_11NG_HT20) == IEEE80211_CHAN_11NG_HT20)
+#define IEEE80211_IS_CHAN_11NA_HT20(_c)	\
+	(((_c)->ic_flags & IEEE80211_CHAN_11NA_HT20) == IEEE80211_CHAN_11NA_HT20)
+#define IEEE80211_IS_CHAN_11NG_HT40PLUS(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_11NG_HT40PLUS) == IEEE80211_CHAN_11NG_HT40PLUS)
+#define IEEE80211_IS_CHAN_11NG_HT40MINUS(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_11NG_HT40MINUS) == IEEE80211_CHAN_11NG_HT40MINUS)
+#define IEEE80211_IS_CHAN_11NA_HT40PLUS(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_11NA_HT40PLUS) == IEEE80211_CHAN_11NA_HT40PLUS)
+#define IEEE80211_IS_CHAN_11NA_HT40MINUS(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_11NA_HT40MINUS) == IEEE80211_CHAN_11NA_HT40MINUS)
+
+#define IEEE80211_IS_CHAN_11N(_c) \
+	(((_c)->ic_flags & (IEEE80211_CHAN_HT20 | IEEE80211_CHAN_HT40PLUS | IEEE80211_CHAN_HT40MINUS)) != 0)
+#define IEEE80211_IS_CHAN_11N_HT20(_c) \
+	(((_c)->ic_flags & (IEEE80211_CHAN_HT20)) != 0)
+#define IEEE80211_IS_CHAN_11N_HT40(_c) \
+	(((_c)->ic_flags & (IEEE80211_CHAN_HT40PLUS | IEEE80211_CHAN_HT40MINUS)) != 0)
+#define IEEE80211_IS_CHAN_11NG(_c) \
+	(IEEE80211_IS_CHAN_2GHZ((_c)) && IEEE80211_IS_CHAN_11N((_c)))
+#define IEEE80211_IS_CHAN_11NA(_c) \
+	(IEEE80211_IS_CHAN_5GHZ((_c)) && IEEE80211_IS_CHAN_11N((_c)))
+#define IEEE80211_IS_CHAN_11N_HT40PLUS(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_HT40PLUS) != 0)
+#define IEEE80211_IS_CHAN_11N_HT40MINUS(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_HT40MINUS) != 0)
+
+#define IEEE80211_IS_CHAN_HT20_CAPABLE(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_HT20) == IEEE80211_CHAN_HT20)
+#define IEEE80211_IS_CHAN_HT40PLUS_CAPABLE(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_HT40PLUS) == IEEE80211_CHAN_HT40PLUS)
+#define IEEE80211_IS_CHAN_HT40MINUS_CAPABLE(_c)	\
+	(((_c)->ic_flags & IEEE80211_CHAN_HT40MINUS) == IEEE80211_CHAN_HT40MINUS)
+#define IEEE80211_IS_CHAN_HT40_CAPABLE(_c) \
+	(IEEE80211_IS_CHAN_HT40PLUS_CAPABLE(_c) || IEEE80211_IS_CHAN_HT40MINUS_CAPABLE(_c))
+#define IEEE80211_IS_CHAN_HT_CAPABLE(_c) \
+	(IEEE80211_IS_CHAN_HT20_CAPABLE(_c) || IEEE80211_IS_CHAN_HT40_CAPABLE(_c))
+#define IEEE80211_IS_CHAN_11N_CTL_CAPABLE(_c)  IEEE80211_IS_CHAN_HT20_CAPABLE(_c)
+#define IEEE80211_IS_CHAN_11N_CTL_U_CAPABLE(_c)	\
+	(((_c)->ic_flags & IEEE80211_CHAN_HT40PLUS) == IEEE80211_CHAN_HT40PLUS)
+#define IEEE80211_IS_CHAN_11N_CTL_L_CAPABLE(_c)	\
+	(((_c)->ic_flags & IEEE80211_CHAN_HT40MINUS) == IEEE80211_CHAN_HT40MINUS)
+#define IEEE80211_IS_CHAN_11N_CTL_40_CAPABLE(_c) \
+	(IEEE80211_IS_CHAN_11N_CTL_U_CAPABLE((_c)) || IEEE80211_IS_CHAN_11N_CTL_L_CAPABLE((_c)))
+
+#define IEEE80211_IS_CHAN_VHT(_c) \
+	(((_c)->ic_flags & (IEEE80211_CHAN_VHT20 | \
+			    IEEE80211_CHAN_VHT40PLUS | IEEE80211_CHAN_VHT40MINUS | IEEE80211_CHAN_VHT80)) != 0)
+#define IEEE80211_IS_CHAN_11AC(_c) \
+	(IEEE80211_IS_CHAN_5GHZ((_c)) && IEEE80211_IS_CHAN_VHT((_c)))
+#define IEEE80211_CHAN_11AC_VHT20 \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT20)
+#define IEEE80211_CHAN_11AC_VHT40 \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT40PLUS | IEEE80211_CHAN_VHT40MINUS)
+#define IEEE80211_CHAN_11AC_VHT40PLUS \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT40PLUS)
+#define IEEE80211_CHAN_11AC_VHT40MINUS \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT40MINUS)
+#define IEEE80211_CHAN_11AC_VHT80 \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT80)
+#define IEEE80211_IS_CHAN_11AC_VHT20(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT20) == IEEE80211_CHAN_11AC_VHT20)
+
+#define IEEE80211_IS_CHAN_11AC_VHT40(_c) \
+	(((_c)->ic_flags & (IEEE80211_CHAN_VHT40PLUS | IEEE80211_CHAN_VHT40MINUS)) != 0)
+#define IEEE80211_IS_CHAN_11AC_VHT40PLUS(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT40PLUS) == IEEE80211_CHAN_11AC_VHT40PLUS)
+#define IEEE80211_IS_CHAN_11AC_VHT40MINUS(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT40MINUS) == IEEE80211_CHAN_11AC_VHT40MINUS)
+#define IEEE80211_IS_CHAN_11AC_VHT80(_c) \
+	(((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT80) == IEEE80211_CHAN_11AC_VHT80)
+
+#define IEEE80211_IS_CHAN_RADAR(_c)    \
+	(((_c)->ic_flags & IEEE80211_CHAN_RADAR_DFS) == IEEE80211_CHAN_RADAR_DFS)
+#define IEEE80211_CHAN_SET_RADAR(_c)	\
+	((_c)->ic_flags |= IEEE80211_CHAN_RADAR_DFS)
+#define IEEE80211_CHAN_CLR_RADAR(_c)	\
+	((_c)->ic_flags &= ~IEEE80211_CHAN_RADAR_DFS)
+#define IEEE80211_CHAN_SET_DISALLOW_ADHOC(_c)	\
+	((_c)->ic_flagext |= IEEE80211_CHAN_DISALLOW_ADHOC)
+#define IEEE80211_CHAN_SET_DISALLOW_HOSTAP(_c)	 \
+	((_c)->ic_flagext |= IEEE80211_CHAN_DISALLOW_HOSTAP)
+#define IEEE80211_CHAN_SET_DFS(_c)  \
+	((_c)->ic_flagext |= IEEE80211_CHAN_DFS)
+#define IEEE80211_CHAN_SET_DFS_CLEAR(_c)  \
+	((_c)->ic_flagext |= IEEE80211_CHAN_DFS_CLEAR)
+#define IEEE80211_CHAN_EXCLUDE_11D(_c)	\
+	((_c)->ic_flagext |= IEEE80211_CHAN_11D_EXCLUDED)
+
+/* channel encoding for FH phy */
+#define IEEE80211_FH_CHANMOD        80
+#define IEEE80211_FH_CHAN(set, pat) (((set) - 1) * IEEE80211_FH_CHANMOD + (pat))
+#define IEEE80211_FH_CHANSET(chan)  ((chan) / IEEE80211_FH_CHANMOD + 1)
+#define IEEE80211_FH_CHANPAT(chan)  ((chan) % IEEE80211_FH_CHANMOD)
+
+/*
+ * 802.11 rate set.
+ */
+#define IEEE80211_RATE_SIZE     8       /* 802.11 standard */
+#define IEEE80211_RATE_MAXSIZE  36      /* max rates we'll handle */
+#define IEEE80211_HT_RATE_SIZE  128
+#define IEEE80211_RATE_SINGLE_STREAM_MCS_MAX     7      /* MCS7 */
+
+#define IEEE80211_RATE_MCS      0x8000
+#define IEEE80211_RATE_MCS_VAL  0x7FFF
+
+#define IEEE80211_RATE_IDX_ENTRY(val, idx) (((val & (0xff << (idx * 8))) >> (idx * 8)))
+
+/*
+ * RSSI range
+ */
+#define IEEE80211_RSSI_MAX           -10        /* in db */
+#define IEEE80211_RSSI_MIN           -200
+
+/*
+ * 11n A-MPDU & A-MSDU limits
+ */
+#define IEEE80211_AMPDU_LIMIT_MIN           (1 * 1024)
+#define IEEE80211_AMPDU_LIMIT_MAX           (64 * 1024 - 1)
+#define IEEE80211_AMPDU_LIMIT_DEFAULT       IEEE80211_AMPDU_LIMIT_MAX
+#define IEEE80211_AMPDU_SUBFRAME_MIN        2
+#define IEEE80211_AMPDU_SUBFRAME_MAX        64
+#define IEEE80211_AMPDU_SUBFRAME_DEFAULT    32
+#define IEEE80211_AMSDU_LIMIT_MAX           4096
+#define IEEE80211_RIFS_AGGR_DIV             10
+#define IEEE80211_MAX_AMPDU_MIN             0
+#define IEEE80211_MAX_AMPDU_MAX             3
+
+/*
+ * 11ac A-MPDU limits
+ */
+#define IEEE80211_VHT_MAX_AMPDU_MIN         0
+#define IEEE80211_VHT_MAX_AMPDU_MAX         7
+
+struct ieee80211_rateset {
+	uint8_t rs_nrates;
+	uint8_t rs_rates[IEEE80211_RATE_MAXSIZE];
+};
+
+struct ieee80211_beacon_info {
+	uint8_t essid[IEEE80211_NWID_LEN + 1];
+	uint8_t esslen;
+	uint8_t rssi_ctl_0;
+	uint8_t rssi_ctl_1;
+	uint8_t rssi_ctl_2;
+	int numchains;
+};
+
+#define IEEE80211_ADDR_LEN  6   /* size of 802.11 address */
+
+struct ieee80211_ibss_peer_list {
+	uint8_t bssid[IEEE80211_ADDR_LEN];
+};
+
+struct ieee80211_roam {
+	int8_t rssi11a;         /* rssi thresh for 11a bss */
+	int8_t rssi11b;         /* for 11g sta in 11b bss */
+	int8_t rssi11bOnly;     /* for 11b sta */
+	uint8_t pad1;
+	uint8_t rate11a;        /* rate thresh for 11a bss */
+	uint8_t rate11b;        /* for 11g sta in 11b bss */
+	uint8_t rate11bOnly;    /* for 11b sta */
+	uint8_t pad2;
+};
+
+#define IEEE80211_TID_SIZE      17      /* total number of TIDs */
+#define IEEE80211_NON_QOS_SEQ   16      /* index for non-QoS (including management) sequence number space */
+#define IEEE80211_SEQ_MASK      0xfff   /* sequence generator mask */
+#define MIN_SW_SEQ              0x100   /* minimum sequence for SW generate packect */
+
+/* crypto related defines*/
+#define IEEE80211_KEYBUF_SIZE   16
+#define IEEE80211_MICBUF_SIZE   (8+8)   /* space for both tx+rx keys */
+
+enum ieee80211_clist_cmd {
+	CLIST_UPDATE,
+	CLIST_DFS_UPDATE,
+	CLIST_NEW_COUNTRY,
+	CLIST_NOL_UPDATE
+};
+
+enum ieee80211_nawds_param {
+	IEEE80211_NAWDS_PARAM_NUM = 0,
+	IEEE80211_NAWDS_PARAM_MODE,
+	IEEE80211_NAWDS_PARAM_DEFCAPS,
+	IEEE80211_NAWDS_PARAM_OVERRIDE,
+};
+
+struct ieee80211_mib_cycle_cnts {
+	uint32_t tx_frame_count;
+	uint32_t rx_frame_count;
+	uint32_t rx_clear_count;
+	uint32_t cycle_count;
+	uint8_t is_rx_active;
+	uint8_t is_tx_active;
+};
+
+struct ieee80211_chanutil_info {
+	uint32_t rx_clear_count;
+	uint32_t cycle_count;
+	uint8_t value;
+	uint32_t beacon_count;
+	uint8_t beacon_intervals;
+};
+
+#endif /* CDS_COMMON__IEEE80211_I_H_ */
diff --git a/core/cds/src/cds_packet.c b/core/cds/src/cds_packet.c
new file mode 100644
index 0000000..ad5f291
--- /dev/null
+++ b/core/cds/src/cds_packet.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2014-2016, 2018 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.
+ */
+
+/**=========================================================================
+
+   \file        cds_packet.c
+
+   \brief       Connectivity driver services (CDS) network Packet APIs
+
+   Network Protocol packet/buffer support interfaces
+
+   ========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include <cds_packet.h>
+#include <i_cds_packet.h>
+#include <qdf_mc_timer.h>
+#include <qdf_trace.h>
+#include <wlan_hdd_main.h>
+#include "qdf_nbuf.h"
+#include "qdf_mem.h"
+#include "cds_utils.h"
+
+#define TX_PKT_MIN_HEADROOM          (64)
+
+/* Protocol specific packet tracking feature */
+#define CDS_PKT_TRAC_ETH_TYPE_OFFSET (12)
+#define CDS_PKT_TRAC_IP_OFFSET       (14)
+#define CDS_PKT_TRAC_IP_HEADER_SIZE  (20)
+#define CDS_PKT_TRAC_DHCP_SRV_PORT   (67)
+#define CDS_PKT_TRAC_DHCP_CLI_PORT   (68)
+#define CDS_PKT_TRAC_EAPOL_ETH_TYPE  (0x888E)
+
+/**
+ * cds_pkt_return_packet  Free the cds Packet
+ * @ cds Packet
+ */
+QDF_STATUS cds_pkt_return_packet(cds_pkt_t *packet)
+{
+	/* Validate the input parameter pointer */
+	if (unlikely(packet == NULL)) {
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* Free up the qdf nbuf */
+	qdf_nbuf_free(packet->pkt_buf);
+
+	packet->pkt_buf = NULL;
+
+	/* Free up the Rx packet */
+	qdf_mem_free(packet);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**--------------------------------------------------------------------------
+
+   \brief cds_pkt_get_packet_length() - Get packet length for a cds Packet
+
+   This API returns the total length of the data in a cds Packet.
+
+   \param pPacket - the cds Packet to get the packet length from.
+
+   \param pPacketSize - location to return the total size of the data contained
+   in the cds Packet.
+   \return
+
+   \sa
+
+   ---------------------------------------------------------------------------*/
+QDF_STATUS
+cds_pkt_get_packet_length(cds_pkt_t *pPacket, uint16_t *pPacketSize)
+{
+	/* Validate the parameter pointers */
+	if (unlikely((pPacket == NULL) || (pPacketSize == NULL)) ||
+	    (pPacket->pkt_buf == NULL)) {
+		cds_alert("NULL pointer");
+		return QDF_STATUS_E_INVAL;
+	}
+	/* return the requested information */
+	*pPacketSize = qdf_nbuf_len(pPacket->pkt_buf);
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef MEMORY_DEBUG
+/*---------------------------------------------------------------------------
+* @brief cds_packet_alloc_debug() -
+      Allocate a network buffer for TX
+   ---------------------------------------------------------------------------*/
+QDF_STATUS cds_packet_alloc_debug(uint16_t size, void **data, void **ppPacket,
+				  uint8_t *file_name, uint32_t line_num)
+{
+	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
+	qdf_nbuf_t nbuf;
+
+	nbuf = qdf_nbuf_alloc_debug(NULL,
+		roundup(size + TX_PKT_MIN_HEADROOM, 4),
+		TX_PKT_MIN_HEADROOM, sizeof(uint32_t), false,
+				     file_name, line_num);
+
+	if (nbuf != NULL) {
+		qdf_nbuf_put_tail(nbuf, size);
+		qdf_nbuf_set_protocol(nbuf, ETH_P_CONTROL);
+		*ppPacket = nbuf;
+		*data = qdf_nbuf_data(nbuf);
+		qdf_ret_status = QDF_STATUS_SUCCESS;
+	}
+
+	return qdf_ret_status;
+}
+#else
+/*---------------------------------------------------------------------------
+* @brief cds_packet_alloc() -
+      Allocate a network buffer for TX
+   ---------------------------------------------------------------------------*/
+QDF_STATUS cds_packet_alloc(uint16_t size, void **data, void **ppPacket)
+{
+	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
+	qdf_nbuf_t nbuf;
+
+	nbuf = qdf_nbuf_alloc(NULL, roundup(size + TX_PKT_MIN_HEADROOM, 4),
+			      TX_PKT_MIN_HEADROOM, sizeof(uint32_t), false);
+
+	if (nbuf != NULL) {
+		qdf_nbuf_put_tail(nbuf, size);
+		qdf_nbuf_set_protocol(nbuf, ETH_P_CONTROL);
+		*ppPacket = nbuf;
+		*data = qdf_nbuf_data(nbuf);
+		qdf_ret_status = QDF_STATUS_SUCCESS;
+	}
+
+	return qdf_ret_status;
+}
+
+#endif
+/*---------------------------------------------------------------------------
+* @brief cds_packet_free() -
+      Free input network buffer
+   ---------------------------------------------------------------------------*/
+void cds_packet_free(void *pPacket)
+{
+	qdf_nbuf_free((qdf_nbuf_t) pPacket);
+}
diff --git a/core/cds/src/cds_reg_service.c b/core/cds/src/cds_reg_service.c
new file mode 100644
index 0000000..c658fdc
--- /dev/null
+++ b/core/cds/src/cds_reg_service.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+/*============================================================================
+   FILE:         cds_reg_service.c
+   OVERVIEW:     This source file contains definitions for CDS regulatory APIs
+   DEPENDENCIES: None
+   ============================================================================*/
+
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "wlan_reg_services_api.h"
+#include "cds_reg_service.h"
+#include "cds_ieee80211_common_i.h"
+#include "cds_config.h"
+#include "cds_utils.h"
+
+uint32_t cds_get_vendor_reg_flags(struct wlan_objmgr_pdev *pdev,
+		uint32_t chan, uint16_t bandwidth,
+		bool is_ht_enabled, bool is_vht_enabled,
+		uint8_t sub_20_channel_width)
+{
+	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;
+	}
+	if (state == CHANNEL_STATE_DISABLE)
+		flags |= IEEE80211_CHAN_BLOCKED;
+
+	if (WLAN_REG_IS_24GHZ_CH(chan)) {
+		if ((bandwidth == CH_WIDTH_80P80MHZ) ||
+		    (bandwidth == CH_WIDTH_160MHZ) ||
+		    (bandwidth == CH_WIDTH_80MHZ)) {
+			bandwidth = CH_WIDTH_40MHZ;
+		}
+		flags |= IEEE80211_CHAN_2GHZ;
+	} else
+		flags |= IEEE80211_CHAN_5GHZ;
+
+	switch (bandwidth) {
+	case CH_WIDTH_80P80MHZ:
+		if (wlan_reg_get_5g_bonded_channel_state(pdev, chan,
+					bandwidth) != CHANNEL_STATE_INVALID) {
+			if (is_vht_enabled)
+				flags |= IEEE80211_CHAN_VHT80_80;
+		}
+		bandwidth = CH_WIDTH_160MHZ;
+	/* FALLTHROUGH */
+	case CH_WIDTH_160MHZ:
+		if (wlan_reg_get_5g_bonded_channel_state(pdev, chan,
+					bandwidth) != CHANNEL_STATE_INVALID) {
+			if (is_vht_enabled)
+				flags |= IEEE80211_CHAN_VHT160;
+		}
+		bandwidth = CH_WIDTH_80MHZ;
+	/* FALLTHROUGH */
+	case CH_WIDTH_80MHZ:
+		if (wlan_reg_get_5g_bonded_channel_state(pdev, chan,
+					bandwidth) != CHANNEL_STATE_INVALID) {
+			if (is_vht_enabled)
+				flags |= IEEE80211_CHAN_VHT80;
+		}
+		bandwidth = CH_WIDTH_40MHZ;
+	/* FALLTHROUGH */
+	case CH_WIDTH_40MHZ:
+		qdf_mem_zero(&ch_params, sizeof(ch_params));
+		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,
+					sec_channel) !=
+				CHANNEL_STATE_INVALID) {
+			if (ch_params.sec_ch_offset == LOW_PRIMARY_CH) {
+				flags |= IEEE80211_CHAN_HT40PLUS;
+				if (is_vht_enabled)
+					flags |= IEEE80211_CHAN_VHT40PLUS;
+			} else if (ch_params.sec_ch_offset ==
+					HIGH_PRIMARY_CH) {
+				flags |= IEEE80211_CHAN_HT40MINUS;
+				if (is_vht_enabled)
+					flags |= IEEE80211_CHAN_VHT40MINUS;
+			}
+		}
+		bandwidth = CH_WIDTH_20MHZ;
+	/* FALLTHROUGH */
+	case CH_WIDTH_20MHZ:
+		if (is_vht_enabled)
+			flags |= IEEE80211_CHAN_VHT20;
+		if (is_ht_enabled)
+			flags |= IEEE80211_CHAN_HT20;
+		bandwidth = CH_WIDTH_10MHZ;
+	/* FALLTHROUGH */
+	case CH_WIDTH_10MHZ:
+		if ((wlan_reg_get_bonded_channel_state(pdev, chan, bandwidth,
+						0) != CHANNEL_STATE_INVALID) &&
+				(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,
+						0) != CHANNEL_STATE_INVALID) &&
+				(sub_20_channel_width ==
+				 WLAN_SUB_20_CH_WIDTH_5))
+			flags |= IEEE80211_CHAN_QUARTER;
+		break;
+	default:
+		cds_info("invalid channel width value %d", bandwidth);
+	}
+
+	return flags;
+}
+
diff --git a/core/cds/src/cds_regdomain.c b/core/cds/src/cds_regdomain.c
new file mode 100644
index 0000000..f8f55d2
--- /dev/null
+++ b/core/cds/src/cds_regdomain.c
@@ -0,0 +1,713 @@
+/*
+ * Copyright (c) 2011,2013-2018 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.
+ */
+
+/*
+ * Notifications and licenses are retained for attribution purposes only.
+ */
+/*
+ * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
+ * Copyright (c) 2005-2006 Atheros Communications, Inc.
+ * Copyright (c) 2010, Atheros Communications Inc.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the following conditions are met:
+ * 1. The materials contained herein are unmodified and are used
+ *    unmodified.
+ * 2. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following NO
+ *    ''WARRANTY'' disclaimer below (''Disclaimer''), without
+ *    modification.
+ * 3. Redistributions in binary form must reproduce at minimum a
+ *    disclaimer similar to the Disclaimer below and any redistribution
+ *    must be conditioned upon including a substantially similar
+ *    Disclaimer requirement for further binary redistribution.
+ * 4. Neither the names of the above-listed copyright holders nor the
+ *    names of any contributors may be used to endorse or promote
+ *    product derived from this software without specific prior written
+ *    permission.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
+ * FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#include "qdf_types.h"
+#include "wma.h"
+#include "cds_regdomain.h"
+
+
+static const struct reg_dmn_pair g_reg_dmn_pairs[] = {
+	{NO_ENUMRD, FCC8, FCCA, CTRY_DEFAULT},
+	{NULL1_WORLD, NULL1, WORLD, CTRY_DEFAULT},
+	{FCC1_FCCA, FCC1, FCCA, CTRY_DEFAULT},
+	{FCC1_WORLD, FCC1, WORLD, CTRY_DEFAULT},
+	{FCC2_WORLD, FCC2, WORLD, CTRY_DEFAULT},
+	{FCC2_ETSIC, FCC2, ETSIC, CTRY_DEFAULT},
+	{FCC2_FCCA, FCC2, FCCA, CTRY_DEFAULT},
+	{FCC3_FCCA, FCC3, FCCA, CTRY_DEFAULT},
+	{FCC3_WORLD, FCC3, WORLD, CTRY_DEFAULT},
+	{FCC3_ETSIC, FCC3, ETSIC, CTRY_DEFAULT},
+	{FCC4_FCCA, FCC4, FCCA, CTRY_DEFAULT},
+	{FCC5_FCCA, FCC5, FCCA, CTRY_DEFAULT},
+	{FCC6_FCCA, FCC6, FCCA, CTRY_DEFAULT},
+	{FCC7_FCCA, FCC7, FCCA, CTRY_DEFAULT},
+	{FCC8_FCCA, FCC8, FCCA, CTRY_DEFAULT},
+	{FCC6_WORLD, FCC6, WORLD, CTRY_DEFAULT},
+	{FCC9_FCCA, FCC9, FCCA, CTRY_DEFAULT},
+	{FCC10_FCCA, FCC10, FCCA, CTRY_DEFAULT},
+	{FCC11_WORLD, FCC11, WORLD, CTRY_DEFAULT},
+	{FCC13_WORLD, FCC13, WORLD, CTRY_DEFAULT},
+	{FCC14_FCCB, FCC14, FCCB, CTRY_DEFAULT},
+	{ETSI1_WORLD, ETSI1, WORLD, CTRY_DEFAULT},
+	{ETSI3_WORLD, ETSI3, WORLD, CTRY_DEFAULT},
+	{ETSI4_WORLD, ETSI4, WORLD, CTRY_DEFAULT},
+	{ETSI7_WORLD, ETSI4, WORLD, CTRY_DEFAULT},
+	{ETSI8_WORLD, ETSI8, WORLD, CTRY_DEFAULT},
+	{ETSI9_WORLD, ETSI9, WORLD, CTRY_DEFAULT},
+	{APL4_WORLD, APL4, WORLD, CTRY_DEFAULT},
+	{APL2_WORLD, APL2, WORLD, CTRY_DEFAULT},
+	{APL2_FCCA, APL2, FCCA, CTRY_DEFAULT},
+	{APL2_ETSIC, APL2, ETSIC, CTRY_DEFAULT},
+	{APL1_WORLD, APL1, WORLD, CTRY_DEFAULT},
+	{APL1_ETSIC, APL1, ETSIC, CTRY_DEFAULT},
+	{APL6_WORLD, APL6, WORLD, CTRY_DEFAULT},
+	{APL7_FCCA, APL7, FCCA, CTRY_DEFAULT},
+	{APL8_WORLD, APL8, WORLD, CTRY_DEFAULT},
+	{APL9_WORLD, APL9, WORLD, CTRY_DEFAULT},
+	{APL10_WORLD, APL10, WORLD, CTRY_DEFAULT},
+	{APL12_WORLD, APL12, WORLD, CTRY_DEFAULT},
+	{APL13_WORLD, APL13, WORLD, CTRY_DEFAULT},
+	{APL14_WORLD, APL14, WORLD, CTRY_DEFAULT},
+	{APL15_WORLD, APL15, WORLD, CTRY_DEFAULT},
+	{APL16_WORLD, APL16, WORLD, CTRY_DEFAULT},
+	{APL17_ETSID, APL17, WORLD, CTRY_DEFAULT},
+	{APL20_WORLD, APL20, WORLD, CTRY_DEFAULT},
+	{APL23_WORLD, APL23, WORLD, CTRY_DEFAULT},
+	{WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, CTRY_DEFAULT},
+	{WOR1_WORLD, WOR1_WORLD, WOR1_WORLD, CTRY_DEFAULT},
+	{WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, CTRY_DEFAULT},
+	{WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, CTRY_DEFAULT},
+	{WOR4_FCCA, WOR4_FCCA, WOR4_FCCA, CTRY_DEFAULT},
+	{WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC, CTRY_DEFAULT},
+	{WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, CTRY_DEFAULT},
+	{WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, CTRY_DEFAULT},
+	{EU1_WORLD, EU1_WORLD, EU1_WORLD, CTRY_DEFAULT},
+	{WOR9_WORLD, WOR9_WORLD, WOR9_WORLD, CTRY_DEFAULT},
+	{WORA_WORLD, WORA_WORLD, WORA_WORLD, CTRY_DEFAULT},
+	{WORB_WORLD, WORB_WORLD, WORB_WORLD, CTRY_DEFAULT},
+	{WORC_WORLD, WORC_WORLD, WORC_WORLD, CTRY_DEFAULT},
+	{MKK5_MKKC, MKK5, MKKC, CTRY_JAPAN15},
+	{MKK5_MKKA2, MKK5, MKKA, CTRY_DEFAULT},
+};
+
+static const struct country_code_to_reg_dmn g_all_countries[] = {
+	{CTRY_AFGHANISTAN, ETSI1_WORLD, "AF", "AFGHANISTAN"},
+	{CTRY_ALBANIA, ETSI1_WORLD, "AL", "ALBANIA"},
+	{CTRY_ALGERIA, APL13_WORLD, "DZ", "ALGERIA"},
+	{CTRY_AMERICAN_SAMOA, FCC3_FCCA, "AS", "AMERICAN SAMOA"},
+	{CTRY_ANGUILLA, ETSI1_WORLD, "AI", "ANGUILLA"},
+	{CTRY_ARGENTINA, APL17_ETSID, "AR", "ARGENTINA"},
+	{CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA"},
+	{CTRY_ARUBA, ETSI1_WORLD, "AW", "ARUBA"},
+	{CTRY_AUSTRALIA, FCC6_WORLD, "AU", "AUSTRALIA"},
+	{CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA"},
+	{CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN"},
+	{CTRY_BAHAMAS, FCC3_WORLD, "BS", "BAHAMAS"},
+	{CTRY_BAHRAIN, APL15_WORLD, "BH", "BAHRAIN"},
+	{CTRY_BANGLADESH, APL1_WORLD, "BD", "BANGLADESH"},
+	{CTRY_BARBADOS, FCC2_WORLD, "BB", "BARBADOS"},
+	{CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS"},
+	{CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM"},
+	{CTRY_BELIZE, ETSI8_WORLD, "BZ", "BELIZE"},
+	{CTRY_BERMUDA, FCC3_FCCA, "BM", "BERMUDA"},
+	{CTRY_BHUTAN, ETSI1_WORLD, "BT", "BHUTAN"},
+	{CTRY_BOLIVIA, APL8_WORLD, "BO", "BOLIVIA"},
+	{CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA", "BOSNIA AND HERZEGOVINA"},
+	{CTRY_BRAZIL, FCC3_ETSIC, "BR", "BRAZIL"},
+	{CTRY_BRUNEI_DARUSSALAM, APL6_WORLD, "BN", "BRUNEI DARUSSALAM"},
+	{CTRY_BULGARIA, ETSI1_WORLD, "BG", "BULGARIA"},
+	{CTRY_BURKINA_FASO, FCC3_WORLD, "BF", "BURKINA-FASO"},
+	{CTRY_CAMBODIA, ETSI1_WORLD, "KH", "CAMBODIA"},
+	{CTRY_CANADA, FCC3_FCCA, "CA", "CANADA"},
+	{CTRY_CAYMAN_ISLANDS, FCC3_WORLD, "KY", "CAYMAN ISLANDS"},
+	{CTRY_CENTRAL_AFRICA_REPUBLIC, FCC3_WORLD, "CF", "AFRICA REPUBLIC"},
+	{CTRY_CHAD, ETSI1_WORLD, "TD", "CHAD"},
+	{CTRY_CHILE, APL23_WORLD, "CL", "CHILE"},
+	{CTRY_CHINA, APL14_WORLD, "CN", "CHINA"},
+	{CTRY_CHRISTMAS_ISLAND, FCC3_WORLD, "CX", "CHRISTMAS ISLAND"},
+	{CTRY_COLOMBIA, FCC3_WORLD, "CO", "COLOMBIA"},
+	{CTRY_COSTA_RICA, FCC3_WORLD, "CR", "COSTA RICA"},
+	{CTRY_COTE_DIVOIRE, FCC3_WORLD, "CI", "COTE DIVOIRE"},
+	{CTRY_CROATIA, ETSI1_WORLD, "HR", "CROATIA"},
+	{CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS"},
+	{CTRY_CZECH, ETSI1_WORLD, "CZ", "CZECH REPUBLIC"},
+	{CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK"},
+	{CTRY_DOMINICA, FCC2_FCCA, "DM", "DOMINICA"},
+	{CTRY_DOMINICAN_REPUBLIC, FCC2_FCCA, "DO", "DOMINICAN REPUBLIC"},
+	{CTRY_ECUADOR, FCC3_WORLD, "EC", "ECUADOR"},
+	{CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT"},
+	{CTRY_EL_SALVADOR, FCC2_WORLD, "SV", "EL SALVADOR"},
+	{CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA"},
+	{CTRY_ETHIOPIA, ETSI1_WORLD, "ET", "ETHIOPIA"},
+	{CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND"},
+	{CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE"},
+	{CTRY_FRENCH_GUIANA, ETSI1_WORLD, "GF", "FRENCH GUIANA"},
+	{CTRY_FRENCH_POLYNESIA, ETSI1_WORLD, "PF", "FRENCH POLYNESIA"},
+	{CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA"},
+	{CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY"},
+	{CTRY_GHANA, FCC3_WORLD, "GH", "GHANA"},
+	{CTRY_GIBRALTAR, ETSI1_WORLD, "GI", "GIBRALTAR"},
+	{CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE"},
+	{CTRY_GREENLAND, ETSI1_WORLD, "GL", "GREENLAND"},
+	{CTRY_GRENADA, FCC3_FCCA, "GD", "GRENADA"},
+	{CTRY_GUADELOUPE, ETSI1_WORLD, "GP", "GUADELOUPE"},
+	{CTRY_GUAM, FCC3_FCCA, "GU", "GUAM"},
+	{CTRY_GUATEMALA, ETSI1_WORLD, "GT", "GUATEMALA"},
+	{CTRY_GUYANA, APL1_ETSIC, "GY", "GUYANA"},
+	{CTRY_HAITI, FCC3_FCCA, "HT", "HAITI"},
+	{CTRY_HONDURAS, FCC13_WORLD, "HN", "HONDURAS"},
+	{CTRY_HONG_KONG, FCC3_WORLD, "HK", "HONG KONG"},
+	{CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY"},
+	{CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND"},
+	{CTRY_INDIA, APL15_WORLD, "IN", "INDIA"},
+	{CTRY_INDONESIA, APL2_ETSIC, "ID", "INDONESIA"},
+	{CTRY_IRAQ, ETSI1_WORLD, "IQ", "IRAQ"},
+	{CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND"},
+	{CTRY_ISRAEL, ETSI3_WORLD, "IL", "ISRAEL"},
+	{CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY"},
+	{CTRY_JAMAICA, FCC13_WORLD, "JM", "JAMAICA"},
+	{CTRY_JORDAN, APL4_WORLD, "JO", "JORDAN"},
+	{CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN"},
+	{CTRY_KENYA, APL12_WORLD, "KE", "KENYA"},
+	{CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC"},
+	{CTRY_KUWAIT, ETSI3_WORLD, "KW", "KUWAIT"},
+	{CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA"},
+	{CTRY_LEBANON, FCC3_WORLD, "LB", "LEBANON"},
+	{CTRY_LESOTHO, ETSI1_WORLD, "LS", "LESOTHO"},
+	{CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI", "LIECHTENSTEIN"},
+	{CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA"},
+	{CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG"},
+	{CTRY_MACAU, FCC3_WORLD, "MO", "MACAU SAR"},
+	{CTRY_MACEDONIA, ETSI1_WORLD, "MK", "MACEDONIA, FYRO"},
+	{CTRY_MALAWI, ETSI1_WORLD, "MW", "MALAWI"},
+	{CTRY_MALAYSIA, FCC11_WORLD, "MY", "MALAYSIA"},
+	{CTRY_MALDIVES, APL6_WORLD, "MV", "MALDIVES"},
+	{CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA"},
+	{CTRY_MARSHALL_ISLANDS, FCC3_FCCA, "MH", "MARSHALL ISLANDS"},
+	{CTRY_MARTINIQUE, ETSI1_WORLD, "MQ", "MARTINIQUE"},
+	{CTRY_MAURITANIA, ETSI1_WORLD, "MR", "MAURITANA"},
+	{CTRY_MAURITIUS, FCC3_WORLD, "MU", "MAURITIUS"},
+	{CTRY_MAYOTTE, ETSI1_WORLD, "YT", "MAYOTTE"},
+	{CTRY_MEXICO, FCC3_ETSIC, "MX", "MEXICO"},
+	{CTRY_MICRONESIA, FCC3_FCCA, "FM", "MICRONESIA"},
+	{CTRY_MOLDOVA, ETSI1_WORLD, "MD", "MOLDOVA"},
+	{CTRY_MONACO, ETSI1_WORLD, "MC", "MONACO"},
+	{CTRY_MONGOLIA, FCC3_WORLD, "MN", "MONGOLIA"},
+	{CTRY_MONTENEGRO, ETSI1_WORLD, "ME", "MONTENEGRO"},
+	{CTRY_MOROCCO, ETSI3_WORLD, "MA", "MOROCCO"},
+	{CTRY_NAMIBIA, APL20_WORLD, "NA", "NAMIBIA"},
+	{CTRY_NEPAL, APL23_WORLD, "NP", "NEPAL"},
+	{CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS"},
+	{CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN", "NETHERLANDS ANTILLES"},
+	{CTRY_NEW_ZEALAND, FCC3_ETSIC, "NZ", "NEW ZEALAND"},
+	{CTRY_NIGERIA, APL8_WORLD, "NG", "NIGERIA"},
+	{CTRY_NORTHERN_MARIANA_ISLANDS, FCC3_FCCA, "MP", "MARIANA ISLANDS"},
+	{CTRY_NICARAGUA, FCC3_FCCA, "NI", "NICARAGUA"},
+	{CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY"},
+	{CTRY_OMAN, ETSI1_WORLD, "OM", "OMAN"},
+	{CTRY_PAKISTAN, APL1_ETSIC, "PK", "PAKISTAN"},
+	{CTRY_PALAU, FCC3_FCCA, "PW", "PALAU"},
+	{CTRY_PANAMA, FCC14_FCCB, "PA", "PANAMA"},
+	{CTRY_PAPUA_NEW_GUINEA, FCC3_WORLD, "PG", "PAPUA NEW GUINEA"},
+	{CTRY_PARAGUAY, FCC3_WORLD, "PY", "PARAGUAY"},
+	{CTRY_PERU, FCC3_WORLD, "PE", "PERU"},
+	{CTRY_PHILIPPINES, FCC3_WORLD, "PH", "PHILIPPINES"},
+	{CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND"},
+	{CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL"},
+	{CTRY_PUERTO_RICO, FCC3_FCCA, "PR", "PUERTO RICO"},
+	{CTRY_QATAR, APL1_WORLD, "QA", "QATAR"},
+	{CTRY_REUNION, ETSI1_WORLD, "RE", "REUNION"},
+	{CTRY_ROMANIA, ETSI1_WORLD, "RO", "ROMANIA"},
+	{CTRY_RUSSIA, ETSI8_WORLD, "RU", "RUSSIA"},
+	{CTRY_RWANDA, FCC3_WORLD, "RW", "RWANDA"},
+	{CTRY_SAINT_BARTHELEMY, ETSI1_WORLD, "BL", "SAINT BARTHELEMY"},
+	{CTRY_SAINT_KITTS_AND_NEVIS, APL10_WORLD, "KN", "SAINT KITTS"},
+	{CTRY_SAINT_LUCIA, APL10_WORLD, "LC", "SAINT LUCIA"},
+	{CTRY_SAINT_MARTIN, ETSI1_WORLD, "MF", "SAINT MARTIN"},
+	{CTRY_SAINT_PIERRE_AND_MIQUELON, ETSI1_WORLD, "PM", "SAINT PIERRE"},
+	{CTRY_SAINT_VINCENT_AND_THE_GRENADIENS, ETSI1_WORLD, "VC", "VINCENT"},
+	{CTRY_SAMOA, ETSI1_WORLD, "WS", "SAMOA"},
+	{CTRY_SAUDI_ARABIA, ETSI1_WORLD, "SA", "SAUDI ARABIA"},
+	{CTRY_SENEGAL, FCC13_WORLD, "SN", "SENEGAL"},
+	{CTRY_SERBIA, ETSI1_WORLD, "RS", "REPUBLIC OF SERBIA"},
+	{CTRY_SINGAPORE, FCC3_WORLD, "SG", "SINGAPORE"},
+	{CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAKIA"},
+	{CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA"},
+	{CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", "SOUTH AFRICA"},
+	{CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN"},
+	{CTRY_SURINAME, ETSI1_WORLD, "SR", "SURINAME"},
+	{CTRY_SRI_LANKA, FCC3_WORLD, "LK", "SRI LANKA"},
+	{CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN"},
+	{CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND"},
+	{CTRY_TAIWAN, FCC3_FCCA, "TW", "TAIWAN"},
+	{CTRY_TANZANIA, APL1_WORLD, "TZ", "TANZANIA"},
+	{CTRY_THAILAND, FCC3_WORLD, "TH", "THAILAND"},
+	{CTRY_TOGO, ETSI1_WORLD, "TG", "TOGO"},
+	{CTRY_TRINIDAD_Y_TOBAGO, FCC3_WORLD, "TT", "TRINIDAD AND TOBAGO"},
+	{CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA"},
+	{CTRY_TURKEY, ETSI1_WORLD, "TR", "TURKEY"},
+	{CTRY_TURKS_AND_CAICOS, FCC3_WORLD, "TC" "TURKS AND CAICOS"},
+	{CTRY_UGANDA, FCC3_WORLD, "UG", "UGANDA"},
+	{CTRY_UKRAINE, ETSI9_WORLD, "UA", "UKRAINE"},
+	{CTRY_UAE, FCC3_WORLD, "AE", "UNITED ARAB EMIRATES"},
+	{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB", "UNITED KINGDOM"},
+	{CTRY_UNITED_STATES, FCC8_FCCA, "US", "UNITED STATES"},
+	{CTRY_URUGUAY, FCC2_WORLD, "UY", "URUGUAY"},
+	{CTRY_UZBEKISTAN, ETSI3_WORLD, "UZ", "UZBEKISTAN"},
+	{CTRY_VANUATU, FCC3_WORLD, "VU", "VANUATU"},
+	{CTRY_VENEZUELA, FCC2_ETSIC, "VE", "VENEZUELA"},
+	{CTRY_VIET_NAM, FCC3_WORLD, "VN", "VIETNAM"},
+	{CTRY_VIRGIN_ISLANDS, FCC3_FCCA, "VI", "VIRGIN ISLANDS"},
+	{CTRY_WALLIS_AND_FUTUNA, ETSI1_WORLD, "WF" "WALLIS"},
+	{CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN"},
+	{CTRY_ZIMBABWE, ETSI1_WORLD, "ZW", "ZIMBABWE"},
+	{CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN"},
+	{CTRY_XA, MKK5_MKKA2, "XA", "JAPAN PASSIVE"}
+};
+
+static const struct reg_dmn g_reg_dmns[] = {
+	{FCC1, FCC},
+	{FCC2, FCC},
+	{FCC3, FCC},
+	{FCC4, FCC},
+	{FCC5, FCC},
+	{FCC6, FCC},
+	{FCC7, FCC},
+	{FCC8, FCC},
+	{FCC9, FCC},
+	{FCC10, FCC},
+	{FCC11, FCC},
+	{FCC13, FCC},
+	{FCC14, FCC},
+	{ETSI1, ETSI},
+	{ETSI2, ETSI},
+	{ETSI3, ETSI},
+	{ETSI4, ETSI},
+	{ETSI5, ETSI},
+	{ETSI6, ETSI},
+	{ETSI8, ETSI},
+	{ETSI9, ETSI},
+	{ETSI10, ETSI},
+	{ETSI11, ETSI},
+	{APL1, ETSI},
+	{APL2, ETSI},
+	{APL3, ETSI},
+	{APL4, ETSI},
+	{APL5, ETSI},
+	{APL6, ETSI},
+	{APL7, ETSI},
+	{APL8, ETSI},
+	{APL9, ETSI},
+	{APL10, ETSI},
+	{APL11, ETSI},
+	{APL12, ETSI},
+	{APL13, ETSI},
+	{APL14, FCC},
+	{APL15, FCC},
+	{APL16, FCC},
+	{APL17, FCC},
+	{APL20, ETSI},
+	{APL23, ETSI},
+	{NULL1, NO_CTL},
+	{MKK3, MKK},
+	{MKK5, MKK},
+	{MKK11, MKK},
+	{WORLD, ETSI},
+	{FCCA, FCC},
+	{MKKA, MKK},
+	{MKKC, MKK},
+	{ETSIC, ETSI},
+	{WOR0_WORLD, NO_CTL},
+	{WOR1_WORLD, NO_CTL},
+	{WOR2_WORLD, NO_CTL},
+	{WOR3_WORLD, NO_CTL},
+	{WOR4_FCCA, NO_CTL},
+	{WOR5_ETSIC, NO_CTL},
+	{WOR01_WORLD, NO_CTL},
+	{WOR02_WORLD, NO_CTL},
+	{EU1_WORLD, NO_CTL},
+	{WOR9_WORLD, NO_CTL},
+	{WORA_WORLD, NO_CTL},
+	{WORB_WORLD, NO_CTL},
+	{WORC_WORLD, NO_CTL},
+};
+
+
+struct reg_dmn_tables g_reg_dmn_tbl = {
+	g_reg_dmn_pairs,
+	g_all_countries,
+	g_reg_dmns,
+	QDF_ARRAY_SIZE(g_reg_dmn_pairs),
+	QDF_ARRAY_SIZE(g_all_countries),
+	QDF_ARRAY_SIZE(g_reg_dmns),
+};
+
+/*
+ *  ETSI is updating EN 301 893, which specifies 5 GHz channel access
+ *  in Europe
+ */
+static const char etsi_europe_country[][2] = {
+	{'A', 'T'},
+	{'B', 'E'},
+	{'B', 'G'},
+	{'C', 'Z'},
+	{'D', 'K'},
+	{'E', 'E'},
+	{'F', 'R'},
+
+	{'D', 'E'},
+	{'I', 'S'},
+	{'I', 'E'},
+	{'I', 'T'},
+	{'E', 'L'},
+	{'E', 'S'},
+	{'C', 'Y'},
+
+	{'L', 'V'},
+	{'L', 'I'},
+	{'L', 'T'},
+	{'L', 'U'},
+	{'H', 'U'},
+	{'M', 'T'},
+	{'N', 'L'},
+
+	{'N', 'O'},
+	{'P', 'L'},
+	{'P', 'T'},
+	{'R', 'O'},
+	{'S', 'I'},
+	{'S', 'K'},
+	{'T', 'R'},
+
+	{'F', 'I'},
+	{'S', 'E'},
+	{'C', 'H'},
+	{'U', 'K'},
+	{'H', 'R'},
+};
+
+bool cds_is_etsi_europe_country(uint8_t *country)
+{
+	int32_t i;
+
+	for (i = 0; i < QDF_ARRAY_SIZE(etsi_europe_country); i++) {
+		if (country[0] == etsi_europe_country[i][0] &&
+		    country[1] == etsi_europe_country[i][1])
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * get_bdf_reg_dmn() - get regulatory domain from BDF
+ * @reg_dmn: BDF regulatory domain
+ *
+ * Return: regulatory domain
+ */
+static uint16_t get_bdf_reg_dmn(uint16_t reg_dmn)
+{
+	return reg_dmn & ~WORLD_ROAMING_FLAG;
+}
+
+/**
+ * is_reg_dmn_valid() - is regulatory domain valid
+ * @reg_dmn: regulatory domain
+ *
+ * Return: true or false
+ */
+static bool is_reg_dmn_valid(uint16_t reg_dmn)
+{
+	int32_t i;
+
+	if (reg_dmn & CTRY_FLAG) {
+		uint16_t cc = reg_dmn & ~CTRY_FLAG;
+
+		for (i = 0; i < g_reg_dmn_tbl.all_countries_cnt; i++)
+			if (g_reg_dmn_tbl.all_countries[i].country_code == cc)
+				return true;
+	} else {
+		for (i = 0; i < g_reg_dmn_tbl.reg_dmn_pairs_cnt; i++)
+			if (g_reg_dmn_tbl.reg_dmn_pairs[i].reg_dmn_pair
+			    == reg_dmn)
+				return true;
+	}
+
+	cds_err("invalid regulatory domain/country code 0x%x", reg_dmn);
+
+	return false;
+}
+
+/**
+ * find_country() - find country data
+ * @country_code: country code
+ *
+ * Return: country code data pointer
+ */
+static const struct country_code_to_reg_dmn *find_country(uint16_t country_code)
+{
+	int32_t i;
+
+	for (i = 0; i < g_reg_dmn_tbl.all_countries_cnt; i++) {
+		if (g_reg_dmn_tbl.all_countries[i].country_code == country_code)
+			return &g_reg_dmn_tbl.all_countries[i];
+	}
+
+	return NULL;
+}
+
+/**
+ * cds_get_country_from_alpha2() - get country from alpha2
+ * @alpha2: country code alpha2
+ *
+ * Return: country code
+ */
+int32_t cds_get_country_from_alpha2(uint8_t *alpha2)
+{
+	int32_t i;
+
+	for (i = 0; i < g_reg_dmn_tbl.all_countries_cnt; i++) {
+		if (g_reg_dmn_tbl.all_countries[i].alpha2[0] == alpha2[0] &&
+		    g_reg_dmn_tbl.all_countries[i].alpha2[1] == alpha2[1])
+			return g_reg_dmn_tbl.all_countries[i].country_code;
+	}
+
+	return CTRY_DEFAULT;
+}
+
+/**
+ * reg_dmn_get_default_country() - get default country for regulatory domain
+ * @reg_dmn: regulatory domain
+ *
+ * Return: default country
+ */
+static uint16_t reg_dmn_get_default_country(uint16_t reg_dmn)
+{
+	int32_t i;
+	const struct country_code_to_reg_dmn *country = NULL;
+	uint16_t cc = reg_dmn & ~CTRY_FLAG;
+
+	if (reg_dmn & CTRY_FLAG) {
+		country = find_country(cc);
+		if (country)
+			return cc;
+	}
+
+	for (i = 0; i < g_reg_dmn_tbl.reg_dmn_pairs_cnt; i++) {
+		if (g_reg_dmn_tbl.reg_dmn_pairs[i].reg_dmn_pair == reg_dmn) {
+			if (g_reg_dmn_tbl.reg_dmn_pairs[i].single_cc != 0)
+				return g_reg_dmn_tbl.reg_dmn_pairs[i].single_cc;
+			else
+				i = g_reg_dmn_tbl.reg_dmn_pairs_cnt;
+		}
+	}
+
+	return CTRY_DEFAULT;
+}
+
+/**
+ * get_reg_dmn_pair() - get regulatory domain pair pointer
+ * @reg_dmn: regulatory domain
+ *
+ * Return: pointer to regulatory domain pair data
+ */
+static const struct reg_dmn_pair *get_reg_dmn_pair(uint16_t reg_dmn)
+{
+	int32_t i;
+
+	for (i = 0; i < g_reg_dmn_tbl.reg_dmn_pairs_cnt; i++) {
+		if (g_reg_dmn_tbl.reg_dmn_pairs[i].reg_dmn_pair == reg_dmn)
+			return &g_reg_dmn_tbl.reg_dmn_pairs[i];
+	}
+
+	return NULL;
+}
+
+/**
+ * get_reg_dmn() - get regulatory domain pointer
+ * @reg_dmn: regulatory domain
+ *
+ * Return: pointer to regulatory domain data
+ */
+static const struct reg_dmn *get_reg_dmn(uint16_t reg_dmn)
+{
+	int32_t i;
+
+	for (i = 0; i < g_reg_dmn_tbl.reg_dmns_cnt; i++) {
+		if (g_reg_dmn_tbl.reg_dmns[i].reg_dmn == reg_dmn)
+			return &g_reg_dmn_tbl.reg_dmns[i];
+	}
+
+	return NULL;
+}
+
+/**
+ * get_country_from_rd() - get country from regulatory domain
+ * @reg_dmn: regulatory domain
+ *
+ * Return: country code enum
+ */
+static const struct country_code_to_reg_dmn *get_country_from_rd(
+	uint16_t reg_dmn)
+{
+	int32_t i;
+
+	for (i = 0; i < g_reg_dmn_tbl.all_countries_cnt; i++) {
+		if (g_reg_dmn_tbl.all_countries[i].reg_dmn_pair == reg_dmn)
+			return &g_reg_dmn_tbl.all_countries[i];
+	}
+
+	return NULL;
+}
+
+/**
+ * reg_dmn_sanitize() - sanitize regulatory domain
+ * @reg: regulatory data structure
+ *
+ * Return: none
+ */
+static void reg_dmn_sanitize(struct regulatory *reg)
+{
+	if (reg->reg_domain != CTRY_FLAG)
+		return;
+
+	reg->reg_domain = WOR0_WORLD;
+}
+
+/**
+ * cds_fill_some_regulatory_info() - fill regulatory information
+ * @reg: regulatory data structure
+ *
+ * Return: error code
+ */
+int32_t cds_fill_some_regulatory_info(struct regulatory *reg)
+{
+	uint16_t country_code;
+	uint16_t reg_dmn, rd;
+	const struct country_code_to_reg_dmn *country = NULL;
+
+	reg_dmn_sanitize(reg);
+	rd = reg->reg_domain;
+
+	if (!is_reg_dmn_valid(rd))
+		return -EINVAL;
+
+	reg_dmn = get_bdf_reg_dmn(rd);
+
+	country_code = reg_dmn_get_default_country(reg_dmn);
+	if (country_code == CTRY_DEFAULT && reg_dmn == CTRY_DEFAULT)
+		country_code = CTRY_UNITED_STATES;
+
+	if (country_code != CTRY_DEFAULT) {
+		country = find_country(country_code);
+		if (!country) {
+			cds_err("not a valid country code");
+			return -EINVAL;
+		}
+
+		reg_dmn = country->reg_dmn_pair;
+	}
+
+	reg->regpair = get_reg_dmn_pair(reg_dmn);
+	if (!reg->regpair) {
+		cds_err("no regpair is found, can not proceeed");
+		return -EINVAL;
+	}
+
+	reg->country_code = country_code;
+
+	if (!country)
+		country = get_country_from_rd(reg_dmn);
+
+	if (country) {
+		reg->alpha2[0] = country->alpha2[0];
+		reg->alpha2[1] = country->alpha2[1];
+	} else {
+		reg->alpha2[0] = '0';
+		reg->alpha2[1] = '0';
+	}
+
+	return 0;
+}
+
+/**
+ * cds_fill_and_send_ctl_to_fw() - fill and send ctl to firmware
+ * @reg: the regulatory handle
+ *
+ * Return: none
+ */
+void cds_fill_and_send_ctl_to_fw(struct regulatory *reg)
+{
+	const struct reg_dmn *reg_dmn_2g = NULL;
+	const struct reg_dmn *reg_dmn_5g = NULL;
+	uint8_t ctl_2g, ctl_5g;
+	const struct reg_dmn_pair *regpair;
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma) {
+		cds_err("unable to get WMA handle");
+		return;
+	}
+
+	if (!reg->regpair) {
+		cds_err(FL("no regpair is found, can not proceed"));
+		return;
+	}
+	regpair = reg->regpair;
+	reg_dmn_2g = get_reg_dmn(regpair->reg_dmn_2ghz);
+	if (!reg_dmn_2g) {
+		cds_err("failed to get regdmn 2G");
+		return;
+	}
+
+	reg_dmn_5g = get_reg_dmn(regpair->reg_dmn_5ghz);
+	if (!reg_dmn_5g) {
+		cds_err("failed to get regdmn 5G");
+		return;
+	}
+
+	ctl_2g = reg_dmn_2g->conformance_test_limit;
+	ctl_5g = reg_dmn_5g->conformance_test_limit;
+
+
+	reg->ctl_5g = ctl_5g;
+	reg->ctl_2g = ctl_2g;
+
+	wma_send_regdomain_info_to_fw(reg->reg_domain, regpair->reg_dmn_2ghz,
+				      regpair->reg_dmn_5ghz, ctl_2g, ctl_5g);
+}
diff --git a/core/cds/src/cds_sched.c b/core/cds/src/cds_sched.c
new file mode 100644
index 0000000..cfcb2c8
--- /dev/null
+++ b/core/cds/src/cds_sched.c
@@ -0,0 +1,1121 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+/**
+ *  File: cds_sched.c
+ *
+ *  DOC: CDS Scheduler Implementation
+ */
+
+ /* Include Files */
+#include <cds_api.h>
+#include <ani_global.h>
+#include <sir_types.h>
+#include <qdf_types.h>
+#include <lim_api.h>
+#include <sme_api.h>
+#include <wlan_qct_sys.h>
+#include "cds_sched.h"
+#include <wlan_hdd_power.h>
+#include "wma_types.h"
+#include <linux/spinlock.h>
+#include <linux/kthread.h>
+#include <linux/cpu.h>
+/* Preprocessor Definitions and Constants */
+#define CDS_SCHED_THREAD_HEART_BEAT    INFINITE
+/* Milli seconds to delay SSR thread when an Entry point is Active */
+#define SSR_WAIT_SLEEP_TIME 200
+/* MAX iteration count to wait for Entry point to exit before
+ * we proceed with SSR in WD Thread
+ */
+#define MAX_SSR_WAIT_ITERATIONS 100
+#define MAX_SSR_PROTECT_LOG (16)
+
+static atomic_t ssr_protect_entry_count;
+
+/**
+ * struct ssr_protect - sub system restart(ssr) protection tracking table
+ * @func: Function which needs ssr protection
+ * @free: Flag to tell whether entry is free in table or not
+ * @pid: Process id which needs ssr protection
+ */
+struct ssr_protect {
+	const char *func;
+	bool  free;
+	uint32_t pid;
+};
+
+static spinlock_t ssr_protect_lock;
+static struct ssr_protect ssr_protect_log[MAX_SSR_PROTECT_LOG];
+
+struct shutdown_notifier {
+	struct list_head list;
+	void (*cb)(void *priv);
+	void *priv;
+};
+
+struct list_head shutdown_notifier_head;
+
+enum notifier_state {
+	NOTIFIER_STATE_NONE,
+	NOTIFIER_STATE_NOTIFYING,
+} notifier_state;
+
+
+static p_cds_sched_context gp_cds_sched_context;
+#ifdef QCA_CONFIG_SMP
+static int cds_ol_rx_thread(void *arg);
+static uint32_t affine_cpu;
+static QDF_STATUS cds_alloc_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext);
+
+#define CDS_CORE_PER_CLUSTER (4)
+/*Maximum 2 clusters supported*/
+#define CDS_MAX_CPU_CLUSTERS 2
+
+#define CDS_CPU_CLUSTER_TYPE_LITTLE 0
+#define CDS_CPU_CLUSTER_TYPE_PERF 1
+
+static inline
+int cds_set_cpus_allowed_ptr(struct task_struct *task, unsigned long cpu)
+{
+	return set_cpus_allowed_ptr(task, cpumask_of(cpu));
+}
+
+
+void cds_set_rx_thread_cpu_mask(uint8_t cpu_affinity_mask)
+{
+	p_cds_sched_context sched_context = get_cds_sched_ctxt();
+
+	if (!sched_context) {
+		qdf_err("invalid context");
+		return;
+	}
+	sched_context->conf_rx_thread_cpu_mask = cpu_affinity_mask;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+/**
+ * cds_rx_thread_log_cpu_affinity_change - Log Rx thread affinity change
+ * @core_affine_cnt: Available cores
+ * @tput_req: Throughput request
+ * @old_mask: Old affinity mask
+ * @new_mask: New affinity mask
+ *
+ * Return: NONE
+ */
+static void cds_rx_thread_log_cpu_affinity_change(unsigned char core_affine_cnt,
+						  int tput_req,
+						  struct cpumask *old_mask,
+						  struct cpumask *new_mask)
+{
+	char new_mask_str[10];
+	char old_mask_str[10];
+
+	qdf_mem_set(new_mask_str, sizeof(new_mask_str), 0);
+	qdf_mem_set(new_mask_str, sizeof(old_mask_str), 0);
+
+	cpumap_print_to_pagebuf(false, old_mask_str, old_mask);
+	cpumap_print_to_pagebuf(false, new_mask_str, new_mask);
+
+	cds_debug("num online perf cores %d, high tput req %d, Rx_thread old mask %s new mask %s",
+		  core_affine_cnt, tput_req, old_mask_str, new_mask_str);
+}
+#else
+static void cds_rx_thread_log_cpu_affinity_change(unsigned char core_affine_cnt,
+						  int tput_req,
+						  struct cpumask *old_mask,
+						  struct cpumask *new_mask)
+{
+}
+#endif
+
+/**
+ * cds_sched_find_attach_cpu - find available cores and attach to required core
+ * @pSchedContext:	wlan scheduler context
+ * @high_throughput:	high throughput is required or not
+ *
+ * Find current online cores.
+ * During high TPUT,
+ * 1) If user INI configured cores, affine to those cores
+ * 2) Otherwise perf cores.
+ * 3) Otherwise to all cores.
+ *
+ * During low TPUT, set affinity to any core, let system decide.
+ *
+ * Return: 0 success
+ *         1 fail
+ */
+static int cds_sched_find_attach_cpu(p_cds_sched_context pSchedContext,
+	bool high_throughput)
+{
+	unsigned char core_affine_count = 0;
+	struct cpumask new_mask;
+	unsigned long cpus;
+
+	cds_debug("num possible cpu %d", num_possible_cpus());
+
+	cpumask_clear(&new_mask);
+
+	if (high_throughput) {
+		/* Get Online perf/pwr CPU count */
+		for_each_online_cpu(cpus) {
+			if (topology_physical_package_id(cpus) >
+							CDS_MAX_CPU_CLUSTERS) {
+				cds_err("can handle max %d clusters, returning...",
+					CDS_MAX_CPU_CLUSTERS);
+				goto err;
+			}
+
+			if (pSchedContext->conf_rx_thread_cpu_mask) {
+				if (pSchedContext->conf_rx_thread_cpu_mask &
+								(1 << cpus))
+					cpumask_set_cpu(cpus, &new_mask);
+			} else if (topology_physical_package_id(cpus) ==
+						 CDS_CPU_CLUSTER_TYPE_PERF) {
+				cpumask_set_cpu(cpus, &new_mask);
+			}
+
+			core_affine_count++;
+		}
+	} else {
+		/* Attach to all cores, let scheduler decide */
+		cpumask_setall(&new_mask);
+	}
+
+	cds_rx_thread_log_cpu_affinity_change(core_affine_count,
+				(int)pSchedContext->high_throughput_required,
+				&pSchedContext->rx_thread_cpu_mask,
+				&new_mask);
+
+	if (!cpumask_equal(&pSchedContext->rx_thread_cpu_mask, &new_mask)) {
+		cpumask_copy(&pSchedContext->rx_thread_cpu_mask, &new_mask);
+		set_cpus_allowed_ptr(pSchedContext->ol_rx_thread, &new_mask);
+	}
+
+	return 0;
+err:
+	return 1;
+}
+
+/**
+ * cds_sched_handle_cpu_hot_plug - cpu hotplug event handler
+ *
+ * cpu hotplug indication handler
+ * will find online cores and will assign proper core based on perf requirement
+ *
+ * Return: 0 success
+ *         1 fail
+ */
+int cds_sched_handle_cpu_hot_plug(void)
+{
+	p_cds_sched_context pSchedContext = get_cds_sched_ctxt();
+
+	if (!pSchedContext) {
+		cds_err("invalid context");
+		return 1;
+	}
+
+	if (cds_is_load_or_unload_in_progress())
+		return 0;
+
+	mutex_lock(&pSchedContext->affinity_lock);
+	if (cds_sched_find_attach_cpu(pSchedContext,
+		pSchedContext->high_throughput_required)) {
+		cds_err("handle hot plug fail");
+		mutex_unlock(&pSchedContext->affinity_lock);
+		return 1;
+	}
+	mutex_unlock(&pSchedContext->affinity_lock);
+	return 0;
+}
+
+/**
+ * cds_sched_handle_throughput_req - cpu throughput requirement handler
+ * @high_tput_required:	high throughput is required or not
+ *
+ * high or low throughput indication ahndler
+ * will find online cores and will assign proper core based on perf requirement
+ *
+ * Return: 0 success
+ *         1 fail
+ */
+int cds_sched_handle_throughput_req(bool high_tput_required)
+{
+	p_cds_sched_context pSchedContext = get_cds_sched_ctxt();
+
+	if (!pSchedContext) {
+		cds_err("invalid context");
+		return 1;
+	}
+
+	if (cds_is_load_or_unload_in_progress()) {
+		cds_err("load or unload in progress");
+		return 0;
+	}
+
+	mutex_lock(&pSchedContext->affinity_lock);
+	if (pSchedContext->high_throughput_required != high_tput_required) {
+		pSchedContext->high_throughput_required = high_tput_required;
+		if (cds_sched_find_attach_cpu(pSchedContext,
+					      high_tput_required)) {
+			mutex_unlock(&pSchedContext->affinity_lock);
+			return 1;
+		}
+	}
+	mutex_unlock(&pSchedContext->affinity_lock);
+	return 0;
+}
+
+/**
+ * cds_cpu_hotplug_multi_cluster() - calls the multi-cluster hotplug handler,
+ *	when on a multi-cluster platform
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS cds_cpu_hotplug_multi_cluster(void)
+{
+	int cpus;
+	unsigned int multi_cluster = 0;
+
+	for_each_online_cpu(cpus) {
+		multi_cluster = topology_physical_package_id(cpus);
+	}
+
+	if (!multi_cluster)
+		return QDF_STATUS_E_NOSUPPORT;
+
+	if (cds_sched_handle_cpu_hot_plug())
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * __cds_cpu_hotplug_notify() - CPU hotplug event handler
+ * @cpu: CPU Id of the CPU generating the event
+ * @cpu_up: true if the CPU is online
+ *
+ * Return: None
+ */
+static void __cds_cpu_hotplug_notify(uint32_t cpu, bool cpu_up)
+{
+	unsigned long pref_cpu = 0;
+	p_cds_sched_context pSchedContext = get_cds_sched_ctxt();
+	int i;
+
+	if (!pSchedContext || !pSchedContext->ol_rx_thread)
+		return;
+
+	if (cds_is_load_or_unload_in_progress() ||
+	    cds_is_module_stop_in_progress() || cds_is_driver_recovering())
+		return;
+
+	cds_debug("'%s' event on CPU %u (of %d); Currently affine to CPU %u",
+		  cpu_up ? "Up" : "Down", cpu, num_possible_cpus(), affine_cpu);
+
+	/* try multi-cluster scheduling first */
+	if (QDF_IS_STATUS_SUCCESS(cds_cpu_hotplug_multi_cluster()))
+		return;
+
+	if (cpu_up) {
+		if (affine_cpu != 0)
+			return;
+
+		for_each_online_cpu(i) {
+			if (i == 0)
+				continue;
+			pref_cpu = i;
+			break;
+		}
+	} else {
+		if (cpu != affine_cpu)
+			return;
+
+		affine_cpu = 0;
+		for_each_online_cpu(i) {
+			if (i == 0)
+				continue;
+			pref_cpu = i;
+			break;
+		}
+	}
+
+	if (pref_cpu == 0)
+		return;
+
+	if (pSchedContext->ol_rx_thread &&
+	    !cds_set_cpus_allowed_ptr(pSchedContext->ol_rx_thread, pref_cpu))
+		affine_cpu = pref_cpu;
+}
+
+/**
+ * cds_cpu_hotplug_notify - cpu core up/down notification handler wrapper
+ * @cpu: CPU Id of the CPU generating the event
+ * @cpu_up: true if the CPU is online
+ *
+ * Return: None
+ */
+static void cds_cpu_hotplug_notify(uint32_t cpu, bool cpu_up)
+{
+	cds_ssr_protect(__func__);
+	__cds_cpu_hotplug_notify(cpu, cpu_up);
+	cds_ssr_unprotect(__func__);
+}
+
+static void cds_cpu_online_cb(void *context, uint32_t cpu)
+{
+	cds_cpu_hotplug_notify(cpu, true);
+}
+
+static void cds_cpu_before_offline_cb(void *context, uint32_t cpu)
+{
+	cds_cpu_hotplug_notify(cpu, false);
+}
+#endif /* QCA_CONFIG_SMP */
+
+/**
+ * cds_sched_open() - initialize the CDS Scheduler
+ * @p_cds_context: Pointer to the global CDS Context
+ * @pSchedContext: Pointer to a previously allocated buffer big
+ *	enough to hold a scheduler context.
+ * @SchedCtxSize: CDS scheduler context size
+ *
+ * This function initializes the CDS Scheduler
+ * Upon successful initialization:
+ *	- All the message queues are initialized
+ *	- The Main Controller thread is created and ready to receive and
+ *	dispatch messages.
+ *
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_sched_open(void *p_cds_context,
+		p_cds_sched_context pSchedContext,
+		uint32_t SchedCtxSize)
+{
+	cds_debug("Opening the CDS Scheduler");
+	/* Sanity checks */
+	if ((p_cds_context == NULL) || (pSchedContext == NULL)) {
+		cds_err("Null params being passed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (sizeof(cds_sched_context) != SchedCtxSize) {
+		cds_debug("Incorrect CDS Sched Context size passed");
+		return QDF_STATUS_E_INVAL;
+	}
+	qdf_mem_zero(pSchedContext, sizeof(cds_sched_context));
+#ifdef QCA_CONFIG_SMP
+	spin_lock_init(&pSchedContext->ol_rx_thread_lock);
+	init_waitqueue_head(&pSchedContext->ol_rx_wait_queue);
+	init_completion(&pSchedContext->ol_rx_start_event);
+	init_completion(&pSchedContext->ol_suspend_rx_event);
+	init_completion(&pSchedContext->ol_resume_rx_event);
+	init_completion(&pSchedContext->ol_rx_shutdown);
+	pSchedContext->ol_rx_event_flag = 0;
+	spin_lock_init(&pSchedContext->ol_rx_queue_lock);
+	spin_lock_init(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	INIT_LIST_HEAD(&pSchedContext->ol_rx_thread_queue);
+	spin_lock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	INIT_LIST_HEAD(&pSchedContext->cds_ol_rx_pkt_freeq);
+	spin_unlock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	if (cds_alloc_ol_rx_pkt_freeq(pSchedContext) != QDF_STATUS_SUCCESS)
+		goto pkt_freeqalloc_failure;
+	qdf_cpuhp_register(&pSchedContext->cpuhp_event_handle,
+			   NULL,
+			   cds_cpu_online_cb,
+			   cds_cpu_before_offline_cb);
+	mutex_init(&pSchedContext->affinity_lock);
+	pSchedContext->high_throughput_required = false;
+#endif
+	gp_cds_sched_context = pSchedContext;
+
+#ifdef QCA_CONFIG_SMP
+	pSchedContext->ol_rx_thread = kthread_create(cds_ol_rx_thread,
+						       pSchedContext,
+						       "cds_ol_rx_thread");
+	if (IS_ERR(pSchedContext->ol_rx_thread)) {
+
+		cds_alert("Could not Create CDS OL RX Thread");
+		goto OL_RX_THREAD_START_FAILURE;
+
+	}
+	wake_up_process(pSchedContext->ol_rx_thread);
+	cds_debug("CDS OL RX thread Created");
+	wait_for_completion_interruptible(&pSchedContext->ol_rx_start_event);
+	cds_debug("CDS OL Rx Thread has started");
+#endif
+	/* We're good now: Let's get the ball rolling!!! */
+	cds_debug("CDS Scheduler successfully Opened");
+	return QDF_STATUS_SUCCESS;
+
+#ifdef QCA_CONFIG_SMP
+OL_RX_THREAD_START_FAILURE:
+#endif
+
+#ifdef QCA_CONFIG_SMP
+	qdf_cpuhp_unregister(&pSchedContext->cpuhp_event_handle);
+	cds_free_ol_rx_pkt_freeq(gp_cds_sched_context);
+pkt_freeqalloc_failure:
+#endif
+	gp_cds_sched_context = NULL;
+
+	return QDF_STATUS_E_RESOURCES;
+
+} /* cds_sched_open() */
+
+#ifdef QCA_CONFIG_SMP
+/**
+ * cds_free_ol_rx_pkt_freeq() - free cds buffer free queue
+ * @pSchedContext - pointer to the global CDS Sched Context
+ *
+ * This API does mem free of the buffers available in free cds buffer
+ * queue which is used for Data rx processing.
+ *
+ * Return: none
+ */
+void cds_free_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext)
+{
+	struct cds_ol_rx_pkt *pkt;
+
+	spin_lock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	while (!list_empty(&pSchedContext->cds_ol_rx_pkt_freeq)) {
+		pkt = list_entry((&pSchedContext->cds_ol_rx_pkt_freeq)->next,
+			typeof(*pkt), list);
+		list_del(&pkt->list);
+		spin_unlock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+		qdf_mem_free(pkt);
+		spin_lock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	}
+	spin_unlock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+}
+
+/**
+ * cds_alloc_ol_rx_pkt_freeq() - Function to allocate free buffer queue
+ * @pSchedContext - pointer to the global CDS Sched Context
+ *
+ * This API allocates CDS_MAX_OL_RX_PKT number of cds message buffers
+ * which are used for Rx data processing.
+ *
+ * Return: status of memory allocation
+ */
+static QDF_STATUS cds_alloc_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext)
+{
+	struct cds_ol_rx_pkt *pkt, *tmp;
+	int i;
+
+	for (i = 0; i < CDS_MAX_OL_RX_PKT; i++) {
+		pkt = qdf_mem_malloc(sizeof(*pkt));
+		if (!pkt) {
+			cds_err("Vos packet allocation for ol rx thread failed");
+			goto free;
+		}
+		spin_lock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+		list_add_tail(&pkt->list, &pSchedContext->cds_ol_rx_pkt_freeq);
+		spin_unlock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+free:
+	spin_lock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	list_for_each_entry_safe(pkt, tmp, &pSchedContext->cds_ol_rx_pkt_freeq,
+				 list) {
+		list_del(&pkt->list);
+		spin_unlock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+		qdf_mem_free(pkt);
+		spin_lock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	}
+	spin_unlock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	return QDF_STATUS_E_NOMEM;
+}
+
+/**
+ * cds_free_ol_rx_pkt() - api to release cds message to the freeq
+ * This api returns the cds message used for Rx data to the free queue
+ * @pSchedContext: Pointer to the global CDS Sched Context
+ * @pkt: CDS message buffer to be returned to free queue.
+ *
+ * Return: none
+ */
+void
+cds_free_ol_rx_pkt(p_cds_sched_context pSchedContext,
+		    struct cds_ol_rx_pkt *pkt)
+{
+	memset(pkt, 0, sizeof(*pkt));
+	spin_lock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	list_add_tail(&pkt->list, &pSchedContext->cds_ol_rx_pkt_freeq);
+	spin_unlock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+}
+
+/**
+ * cds_alloc_ol_rx_pkt() - API to return next available cds message
+ * @pSchedContext: Pointer to the global CDS Sched Context
+ *
+ * This api returns next available cds message buffer used for rx data
+ * processing
+ *
+ * Return: Pointer to cds message buffer
+ */
+struct cds_ol_rx_pkt *cds_alloc_ol_rx_pkt(p_cds_sched_context pSchedContext)
+{
+	struct cds_ol_rx_pkt *pkt;
+
+	spin_lock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	if (list_empty(&pSchedContext->cds_ol_rx_pkt_freeq)) {
+		spin_unlock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+		return NULL;
+	}
+	pkt = list_first_entry(&pSchedContext->cds_ol_rx_pkt_freeq,
+			       struct cds_ol_rx_pkt, list);
+	list_del(&pkt->list);
+	spin_unlock_bh(&pSchedContext->cds_ol_rx_pkt_freeq_lock);
+	return pkt;
+}
+
+/**
+ * cds_indicate_rxpkt() - indicate rx data packet
+ * @Arg: Pointer to the global CDS Sched Context
+ * @pkt: CDS data message buffer
+ *
+ * This api enqueues the rx packet into ol_rx_thread_queue and notifies
+ * cds_ol_rx_thread()
+ *
+ * Return: none
+ */
+void
+cds_indicate_rxpkt(p_cds_sched_context pSchedContext,
+		   struct cds_ol_rx_pkt *pkt)
+{
+	spin_lock_bh(&pSchedContext->ol_rx_queue_lock);
+	list_add_tail(&pkt->list, &pSchedContext->ol_rx_thread_queue);
+	spin_unlock_bh(&pSchedContext->ol_rx_queue_lock);
+	set_bit(RX_POST_EVENT, &pSchedContext->ol_rx_event_flag);
+	wake_up_interruptible(&pSchedContext->ol_rx_wait_queue);
+}
+
+/**
+ * cds_drop_rxpkt_by_staid() - api to drop pending rx packets for a sta
+ * @pSchedContext: Pointer to the global CDS Sched Context
+ * @staId: Station Id
+ *
+ * This api drops queued packets for a station, to drop all the pending
+ * packets the caller has to send WLAN_MAX_STA_COUNT as staId.
+ *
+ * Return: none
+ */
+void cds_drop_rxpkt_by_staid(p_cds_sched_context pSchedContext, uint16_t staId)
+{
+	struct list_head local_list;
+	struct cds_ol_rx_pkt *pkt, *tmp;
+	qdf_nbuf_t buf, next_buf;
+
+	INIT_LIST_HEAD(&local_list);
+	spin_lock_bh(&pSchedContext->ol_rx_queue_lock);
+	if (list_empty(&pSchedContext->ol_rx_thread_queue)) {
+		spin_unlock_bh(&pSchedContext->ol_rx_queue_lock);
+		return;
+	}
+	list_for_each_entry_safe(pkt, tmp, &pSchedContext->ol_rx_thread_queue,
+								list) {
+		if (pkt->staId == staId || staId == WLAN_MAX_STA_COUNT)
+			list_move_tail(&pkt->list, &local_list);
+	}
+	spin_unlock_bh(&pSchedContext->ol_rx_queue_lock);
+
+	list_for_each_entry_safe(pkt, tmp, &local_list, list) {
+		list_del(&pkt->list);
+		buf = pkt->Rxpkt;
+		while (buf) {
+			next_buf = qdf_nbuf_queue_next(buf);
+			qdf_nbuf_free(buf);
+			buf = next_buf;
+		}
+		cds_free_ol_rx_pkt(pSchedContext, pkt);
+	}
+}
+
+/**
+ * cds_rx_from_queue() - function to process pending Rx packets
+ * @pSchedContext: Pointer to the global CDS Sched Context
+ *
+ * This api traverses the pending buffer list and calling the callback.
+ * This callback would essentially send the packet to HDD.
+ *
+ * Return: none
+ */
+static void cds_rx_from_queue(p_cds_sched_context pSchedContext)
+{
+	struct cds_ol_rx_pkt *pkt;
+	uint16_t sta_id;
+
+	spin_lock_bh(&pSchedContext->ol_rx_queue_lock);
+	while (!list_empty(&pSchedContext->ol_rx_thread_queue)) {
+		pkt = list_first_entry(&pSchedContext->ol_rx_thread_queue,
+				       struct cds_ol_rx_pkt, list);
+		list_del(&pkt->list);
+		spin_unlock_bh(&pSchedContext->ol_rx_queue_lock);
+		sta_id = pkt->staId;
+		pkt->callback(pkt->context, pkt->Rxpkt, sta_id);
+		cds_free_ol_rx_pkt(pSchedContext, pkt);
+		spin_lock_bh(&pSchedContext->ol_rx_queue_lock);
+	}
+	spin_unlock_bh(&pSchedContext->ol_rx_queue_lock);
+}
+
+/**
+ * cds_ol_rx_thread() - cds main tlshim rx thread
+ * @Arg: pointer to the global CDS Sched Context
+ *
+ * This api is the thread handler for Tlshim Data packet processing.
+ *
+ * Return: thread exit code
+ */
+static int cds_ol_rx_thread(void *arg)
+{
+	p_cds_sched_context pSchedContext = (p_cds_sched_context) arg;
+	bool shutdown = false;
+	int status;
+
+	set_user_nice(current, -1);
+#ifdef MSM_PLATFORM
+	set_wake_up_idle(true);
+#endif
+
+	complete(&pSchedContext->ol_rx_start_event);
+
+	while (!shutdown) {
+		status =
+			wait_event_interruptible(pSchedContext->ol_rx_wait_queue,
+						 test_bit(RX_POST_EVENT,
+							  &pSchedContext->ol_rx_event_flag)
+						 || test_bit(RX_SUSPEND_EVENT,
+							     &pSchedContext->ol_rx_event_flag));
+		if (status == -ERESTARTSYS)
+			break;
+
+		clear_bit(RX_POST_EVENT, &pSchedContext->ol_rx_event_flag);
+		while (true) {
+			if (test_bit(RX_SHUTDOWN_EVENT,
+				     &pSchedContext->ol_rx_event_flag)) {
+				clear_bit(RX_SHUTDOWN_EVENT,
+					  &pSchedContext->ol_rx_event_flag);
+				if (test_bit(RX_SUSPEND_EVENT,
+					     &pSchedContext->ol_rx_event_flag)) {
+					clear_bit(RX_SUSPEND_EVENT,
+						  &pSchedContext->ol_rx_event_flag);
+					complete
+						(&pSchedContext->ol_suspend_rx_event);
+				}
+				cds_info("Shutting down OL RX Thread");
+				shutdown = true;
+				break;
+			}
+			cds_rx_from_queue(pSchedContext);
+
+			if (test_bit(RX_SUSPEND_EVENT,
+				     &pSchedContext->ol_rx_event_flag)) {
+				clear_bit(RX_SUSPEND_EVENT,
+					  &pSchedContext->ol_rx_event_flag);
+				spin_lock(&pSchedContext->ol_rx_thread_lock);
+				INIT_COMPLETION
+					(pSchedContext->ol_resume_rx_event);
+				complete(&pSchedContext->ol_suspend_rx_event);
+				spin_unlock(&pSchedContext->ol_rx_thread_lock);
+				wait_for_completion_interruptible
+					(&pSchedContext->ol_resume_rx_event);
+			}
+			break;
+		}
+	}
+
+	cds_debug("Exiting CDS OL rx thread");
+	complete_and_exit(&pSchedContext->ol_rx_shutdown, 0);
+
+	return 0;
+}
+
+void cds_resume_rx_thread(void)
+{
+	p_cds_sched_context cds_sched_context;
+
+	cds_sched_context = get_cds_sched_ctxt();
+	if (NULL == cds_sched_context) {
+		cds_err("cds_sched_context is NULL");
+		return;
+	}
+
+	complete(&cds_sched_context->ol_resume_rx_event);
+}
+#endif
+
+/**
+ * cds_sched_close() - close the cds scheduler
+ *
+ * This api closes the CDS Scheduler upon successful closing:
+ *	- All the message queues are flushed
+ *	- The Main Controller thread is closed
+ *	- The Tx thread is closed
+ *
+ *
+ * Return: qdf status
+ */
+QDF_STATUS cds_sched_close(void)
+{
+	cds_debug("invoked");
+
+	if (gp_cds_sched_context == NULL) {
+		cds_err("gp_cds_sched_context == NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+#ifdef QCA_CONFIG_SMP
+	if (!gp_cds_sched_context->ol_rx_thread)
+		return QDF_STATUS_SUCCESS;
+
+	/* Shut down Tlshim Rx thread */
+	set_bit(RX_SHUTDOWN_EVENT, &gp_cds_sched_context->ol_rx_event_flag);
+	set_bit(RX_POST_EVENT, &gp_cds_sched_context->ol_rx_event_flag);
+	wake_up_interruptible(&gp_cds_sched_context->ol_rx_wait_queue);
+	wait_for_completion(&gp_cds_sched_context->ol_rx_shutdown);
+	gp_cds_sched_context->ol_rx_thread = NULL;
+	cds_drop_rxpkt_by_staid(gp_cds_sched_context, WLAN_MAX_STA_COUNT);
+	cds_free_ol_rx_pkt_freeq(gp_cds_sched_context);
+	qdf_cpuhp_unregister(&gp_cds_sched_context->cpuhp_event_handle);
+#endif
+	gp_cds_sched_context = NULL;
+	return QDF_STATUS_SUCCESS;
+} /* cds_sched_close() */
+
+/**
+ * get_cds_sched_ctxt() - get cds scheduler context
+ *
+ * Return: none
+ */
+p_cds_sched_context get_cds_sched_ctxt(void)
+{
+	/* Make sure that Vos Scheduler context has been initialized */
+	if (gp_cds_sched_context == NULL)
+		cds_err("gp_cds_sched_context == NULL");
+
+	return gp_cds_sched_context;
+}
+
+/**
+ * cds_ssr_protect_init() - initialize ssr protection debug functionality
+ *
+ * Return:
+ *        void
+ */
+void cds_ssr_protect_init(void)
+{
+	int i = 0;
+
+	spin_lock_init(&ssr_protect_lock);
+
+	while (i < MAX_SSR_PROTECT_LOG) {
+		ssr_protect_log[i].func = NULL;
+		ssr_protect_log[i].free = true;
+		ssr_protect_log[i].pid =  0;
+		i++;
+	}
+
+	INIT_LIST_HEAD(&shutdown_notifier_head);
+}
+
+/**
+ * cds_print_external_threads() - print external threads stuck in driver
+ *
+ * Return:
+ *        void
+ */
+void cds_print_external_threads(void)
+{
+	int i = 0;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&ssr_protect_lock, irq_flags);
+
+	while (i < MAX_SSR_PROTECT_LOG) {
+		if (!ssr_protect_log[i].free) {
+			cds_err("PID %d is executing %s",
+				ssr_protect_log[i].pid,
+				ssr_protect_log[i].func);
+		}
+		i++;
+	}
+
+	spin_unlock_irqrestore(&ssr_protect_lock, irq_flags);
+}
+
+/**
+ * cds_ssr_protect() - start ssr protection
+ * @caller_func: name of calling function.
+ *
+ * This function is called to keep track of active driver entry points
+ *
+ * Return: none
+ */
+void cds_ssr_protect(const char *caller_func)
+{
+	int count;
+	int i = 0;
+	bool status = false;
+	unsigned long irq_flags;
+
+	count = atomic_inc_return(&ssr_protect_entry_count);
+
+	spin_lock_irqsave(&ssr_protect_lock, irq_flags);
+
+	while (i < MAX_SSR_PROTECT_LOG) {
+		if (ssr_protect_log[i].free) {
+			ssr_protect_log[i].func = caller_func;
+			ssr_protect_log[i].free = false;
+			ssr_protect_log[i].pid = current->pid;
+			status = true;
+			break;
+		}
+		i++;
+	}
+
+	spin_unlock_irqrestore(&ssr_protect_lock, irq_flags);
+
+	/*
+	 * Dump the protect log at intervals if count is consistently growing.
+	 * Long running functions should tend to dominate the protect log, so
+	 * hopefully, dumping at multiples of log size will prevent spamming the
+	 * logs while telling us which calls are taking a long time to finish.
+	 */
+	if (count >= MAX_SSR_PROTECT_LOG && count % MAX_SSR_PROTECT_LOG == 0) {
+		cds_err("Protect Log overflow; Dumping contents:");
+		cds_print_external_threads();
+	}
+
+	if (!status)
+		cds_err("%s can not be protected; PID:%d, entry_count:%d",
+			caller_func, current->pid, count);
+}
+
+/**
+ * cds_ssr_unprotect() - stop ssr protection
+ * @caller_func: name of calling function.
+ *
+ * Return: none
+ */
+void cds_ssr_unprotect(const char *caller_func)
+{
+	int count;
+	int i = 0;
+	bool status = false;
+	unsigned long irq_flags;
+
+	count = atomic_dec_return(&ssr_protect_entry_count);
+
+	spin_lock_irqsave(&ssr_protect_lock, irq_flags);
+
+	while (i < MAX_SSR_PROTECT_LOG) {
+		if (!ssr_protect_log[i].free) {
+			if ((ssr_protect_log[i].pid == current->pid) &&
+			     !strcmp(ssr_protect_log[i].func, caller_func)) {
+				ssr_protect_log[i].func = NULL;
+				ssr_protect_log[i].free = true;
+				ssr_protect_log[i].pid =  0;
+				status = true;
+				break;
+			}
+		}
+		i++;
+	}
+
+	spin_unlock_irqrestore(&ssr_protect_lock, irq_flags);
+
+	if (!status)
+		cds_err("%s was not protected; PID:%d, entry_count:%d",
+			caller_func, current->pid, count);
+}
+
+/**
+ * cds_shutdown_notifier_register() - Register for shutdown notification
+ * @cb          : Call back to be called
+ * @priv        : Private pointer to be passed back to call back
+ *
+ * During driver remove or shutdown (recovery), external threads might be stuck
+ * waiting on some event from firmware at lower layers. Remove or shutdown can't
+ * proceed till the thread completes to avoid any race condition. Call backs can
+ * be registered here to get early notification of remove or shutdown so that
+ * waiting thread can be unblocked and hence remove or shutdown can proceed
+ * further as waiting there may not make sense when FW may already have been
+ * down.
+ *
+ * This is intended for early notification of remove() or shutdown() only so
+ * that lower layers can take care of stuffs like external waiting thread.
+ *
+ * Return: CDS status
+ */
+QDF_STATUS cds_shutdown_notifier_register(void (*cb)(void *priv), void *priv)
+{
+	struct shutdown_notifier *notifier;
+	unsigned long irq_flags;
+
+	notifier = qdf_mem_malloc(sizeof(*notifier));
+
+	if (notifier == NULL)
+		return QDF_STATUS_E_NOMEM;
+
+	/*
+	 * This logic can be simpilfied if there is separate state maintained
+	 * for shutdown and reinit. Right now there is only recovery in progress
+	 * state and it doesn't help to check against it as during reinit some
+	 * of the modules may need to register the call backs.
+	 * For now this logic added to avoid notifier registration happen while
+	 * this function is trying to call the call back with the notification.
+	 */
+	spin_lock_irqsave(&ssr_protect_lock, irq_flags);
+	if (notifier_state == NOTIFIER_STATE_NOTIFYING) {
+		spin_unlock_irqrestore(&ssr_protect_lock, irq_flags);
+		qdf_mem_free(notifier);
+		return -EINVAL;
+	}
+
+	notifier->cb = cb;
+	notifier->priv = priv;
+
+	list_add_tail(&notifier->list, &shutdown_notifier_head);
+	spin_unlock_irqrestore(&ssr_protect_lock, irq_flags);
+
+	return 0;
+}
+
+/**
+ * cds_shutdown_notifier_purge() - Purge all the notifiers
+ *
+ * Shutdown notifiers are added to provide the early notification of remove or
+ * shutdown being initiated. Adding this API to purge all the registered call
+ * backs as they are not useful any more while all the lower layers are being
+ * shutdown.
+ *
+ * Return: None
+ */
+void cds_shutdown_notifier_purge(void)
+{
+	struct shutdown_notifier *notifier, *temp;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&ssr_protect_lock, irq_flags);
+	list_for_each_entry_safe(notifier, temp,
+				 &shutdown_notifier_head, list) {
+		list_del(&notifier->list);
+		spin_unlock_irqrestore(&ssr_protect_lock, irq_flags);
+
+		qdf_mem_free(notifier);
+
+		spin_lock_irqsave(&ssr_protect_lock, irq_flags);
+	}
+
+	spin_unlock_irqrestore(&ssr_protect_lock, irq_flags);
+}
+
+/**
+ * cds_shutdown_notifier_call() - Call shutdown notifier call back
+ *
+ * Call registered shutdown notifier call back to indicate about remove or
+ * shutdown.
+ */
+void cds_shutdown_notifier_call(void)
+{
+	struct shutdown_notifier *notifier;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&ssr_protect_lock, irq_flags);
+	notifier_state = NOTIFIER_STATE_NOTIFYING;
+
+	list_for_each_entry(notifier, &shutdown_notifier_head, list) {
+		spin_unlock_irqrestore(&ssr_protect_lock, irq_flags);
+
+		notifier->cb(notifier->priv);
+
+		spin_lock_irqsave(&ssr_protect_lock, irq_flags);
+	}
+
+	notifier_state = NOTIFIER_STATE_NONE;
+	spin_unlock_irqrestore(&ssr_protect_lock, irq_flags);
+}
+
+/**
+ * cds_wait_for_external_threads_completion() - wait for external threads
+ *					completion before proceeding further
+ * @caller_func: name of calling function.
+ *
+ * Return: true if there is no active entry points in driver
+ *	   false if there is at least one active entry in driver
+ */
+bool cds_wait_for_external_threads_completion(const char *caller_func)
+{
+	int count = MAX_SSR_WAIT_ITERATIONS;
+	int r;
+
+	while (count) {
+
+		r = atomic_read(&ssr_protect_entry_count);
+
+		if (!r)
+			break;
+
+		if (--count) {
+			cds_err("Waiting for %d active entry points to exit",
+				r);
+			msleep(SSR_WAIT_SLEEP_TIME);
+			if (count & 0x1) {
+				cds_err("in middle of waiting for active entry points:");
+				cds_print_external_threads();
+			}
+		}
+	}
+
+	/* at least one external thread is executing */
+	if (!count) {
+		cds_err("Timed-out waiting for active entry points:");
+		cds_print_external_threads();
+		return false;
+	}
+
+	cds_info("Allowing SSR/Driver unload for %s", caller_func);
+
+	return true;
+}
+
+int cds_return_external_threads_count(void)
+{
+	return  atomic_read(&ssr_protect_entry_count);
+}
+
+/**
+ * cds_get_gfp_flags(): get GFP flags
+ *
+ * Based on the scheduled context, return GFP flags
+ * Return: gfp flags
+ */
+int cds_get_gfp_flags(void)
+{
+	int flags = GFP_KERNEL;
+
+	if (in_interrupt() || in_atomic() || irqs_disabled())
+		flags = GFP_ATOMIC;
+
+	return flags;
+}
+
diff --git a/core/cds/src/cds_utils.c b/core/cds/src/cds_utils.c
new file mode 100644
index 0000000..2de74af
--- /dev/null
+++ b/core/cds/src/cds_utils.c
@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+/*============================================================================
+   FILE:         cds_utils.c
+
+   OVERVIEW:     This source file contains definitions for CDS crypto APIs
+   The four APIs mentioned in this file are used for
+   initializing, and de-initializing a crypto context, and
+   obtaining truly random data (for keys), as well as
+   SHA1 HMAC, and AES encrypt and decrypt routines.
+
+   The routines include:
+   cds_crypto_init() - Initializes Crypto module
+   cds_crypto_deinit() - De-initializes Crypto module
+   cds_rand_get_bytes() - Generates random byte
+
+   DEPENDENCIES:
+   ============================================================================*/
+
+/*----------------------------------------------------------------------------
+ * Include Files
+ * -------------------------------------------------------------------------*/
+
+#include "qdf_trace.h"
+#include "cds_utils.h"
+#include "qdf_mem.h"
+#include "cds_crypto.h"
+
+#include <linux/err.h>
+#include <linux/random.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+#include <linux/completion.h>
+#include <linux/ieee80211.h>
+#include <crypto/hash.h>
+#include <crypto/aes.h>
+
+#include "cds_ieee80211_common.h"
+#include <qdf_crypto.h>
+
+/*----------------------------------------------------------------------------
+ * Preprocessor Definitions and Constants
+ * -------------------------------------------------------------------------*/
+#define AAD_LEN 20
+#define IV_SIZE_AES_128 16
+#define CMAC_IPN_LEN 6
+#define CMAC_TLEN 8             /* CMAC TLen = 64 bits (8 octets) */
+#define GMAC_NONCE_LEN 12
+
+/*----------------------------------------------------------------------------
+ * Type Declarations
+ * -------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------
+ * Global Data Definitions
+ * -------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------
+ * Static Variable Definitions
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+   Function Definitions and Documentation
+ * -------------------------------------------------------------------------*/
+#ifdef WLAN_FEATURE_11W
+static inline void xor_128(const u8 *a, const u8 *b, u8 *out)
+{
+	u8 i;
+
+	for (i = 0; i < AES_BLOCK_SIZE; i++)
+		out[i] = a[i] ^ b[i];
+}
+
+static inline void leftshift_onebit(const u8 *input, u8 *output)
+{
+	int i, overflow = 0;
+
+	for (i = (AES_BLOCK_SIZE - 1); i >= 0; i--) {
+		output[i] = input[i] << 1;
+		output[i] |= overflow;
+		overflow = (input[i] & 0x80) ? 1 : 0;
+	}
+	return;
+}
+
+static void generate_subkey(struct crypto_cipher *tfm, u8 *k1, u8 *k2)
+{
+	u8 l[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
+	u8 const_rb[AES_BLOCK_SIZE] = {
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
+	};
+	u8 const_zero[AES_BLOCK_SIZE] = {
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	};
+
+	crypto_cipher_encrypt_one(tfm, l, const_zero);
+
+	if ((l[0] & 0x80) == 0) {       /* If MSB(l) = 0, then k1 = l << 1 */
+		leftshift_onebit(l, k1);
+	} else {                /* Else k1 = ( l << 1 ) (+) Rb */
+		leftshift_onebit(l, tmp);
+		xor_128(tmp, const_rb, k1);
+	}
+
+	if ((k1[0] & 0x80) == 0) {
+		leftshift_onebit(k1, k2);
+	} else {
+		leftshift_onebit(k1, tmp);
+		xor_128(tmp, const_rb, k2);
+	}
+}
+
+static inline void padding(u8 *lastb, u8 *pad, u16 length)
+{
+	u8 j;
+
+	/* original last block */
+	for (j = 0; j < AES_BLOCK_SIZE; j++) {
+		if (j < length)
+			pad[j] = lastb[j];
+		else if (j == length)
+			pad[j] = 0x80;
+		else
+			pad[j] = 0x00;
+	}
+}
+
+static void cds_cmac_calc_mic(struct crypto_cipher *tfm,
+		u8 *m, u16 length, u8 *mac)
+{
+	u8 x[AES_BLOCK_SIZE], y[AES_BLOCK_SIZE];
+	u8 m_last[AES_BLOCK_SIZE], padded[AES_BLOCK_SIZE];
+	u8 k1[AES_KEYSIZE_128], k2[AES_KEYSIZE_128];
+	int cmpBlk;
+	int i, nBlocks = (length + 15) / AES_BLOCK_SIZE;
+
+	generate_subkey(tfm, k1, k2);
+
+	if (nBlocks == 0) {
+		nBlocks = 1;
+		cmpBlk = 0;
+	} else {
+		cmpBlk = ((length % AES_BLOCK_SIZE) == 0) ? 1 : 0;
+	}
+
+	if (cmpBlk) {           /* Last block is complete block */
+		xor_128(&m[AES_BLOCK_SIZE * (nBlocks - 1)], k1, m_last);
+	} else {                /* Last block is not complete block */
+		padding(&m[AES_BLOCK_SIZE * (nBlocks - 1)], padded,
+			length % AES_BLOCK_SIZE);
+		xor_128(padded, k2, m_last);
+	}
+
+	for (i = 0; i < AES_BLOCK_SIZE; i++)
+		x[i] = 0;
+
+	for (i = 0; i < (nBlocks - 1); i++) {
+		xor_128(x, &m[AES_BLOCK_SIZE * i], y);  /* y = Mi (+) x */
+		crypto_cipher_encrypt_one(tfm, x, y);   /* x = AES-128(KEY, y) */
+	}
+
+	xor_128(x, m_last, y);
+	crypto_cipher_encrypt_one(tfm, x, y);
+
+	memcpy(mac, x, CMAC_TLEN);
+}
+#endif
+
+/*--------------------------------------------------------------------------
+
+   \brief cds_crypto_init() - Initializes Crypto module
+
+   The cds_crypto_init() function initializes Crypto module.
+
+   \param phCryptProv - pointer to the Crypt handle
+
+   \return QDF_STATUS_SUCCESS - Successfully generated random memory.
+
+   QDF_STATUS_E_FAULT  - pbBuf is an invalid pointer.
+
+   QDF_STATUS_E_FAILURE - default return value if it fails due to
+   unknown reasons
+
+   ***QDF_STATUS_E_RESOURCES - System resources (other than memory)
+   are unavailable
+   \sa
+
+    ( *** return value not considered yet )
+   --------------------------------------------------------------------------*/
+QDF_STATUS cds_crypto_init(uint32_t *phCryptProv)
+{
+	QDF_STATUS uResult = QDF_STATUS_E_FAILURE;
+
+	/* This implementation doesn't require a crypto context */
+	*phCryptProv = 0;
+	uResult = QDF_STATUS_SUCCESS;
+	return uResult;
+}
+
+QDF_STATUS cds_crypto_deinit(uint32_t hCryptProv)
+{
+	QDF_STATUS uResult = QDF_STATUS_E_FAILURE;
+
+	/* CryptReleaseContext succeeded */
+	uResult = QDF_STATUS_SUCCESS;
+
+	return uResult;
+}
+
+/*--------------------------------------------------------------------------
+
+   \brief cds_rand_get_bytes() - Generates random byte
+
+   The cds_rand_get_bytes() function generate random bytes.
+
+   Buffer should be allocated before calling cds_rand_get_bytes().
+
+   Attempting to initialize an already initialized lock results in
+   a failure.
+
+   \param lock - pointer to the opaque lock object to initialize
+
+   \return QDF_STATUS_SUCCESS - Successfully generated random memory.
+
+   QDF_STATUS_E_FAULT  - pbBuf is an invalid pointer.
+
+   QDF_STATUS_E_FAILURE - default return value if it fails due to
+   unknown reasons
+
+  ***QDF_STATUS_E_RESOURCES - System resources (other than memory)
+  are unavailable
+   \sa
+
+    ( *** return value not considered yet )
+   --------------------------------------------------------------------------*/
+QDF_STATUS
+cds_rand_get_bytes(uint32_t cryptHandle, uint8_t *pbBuf, uint32_t numBytes)
+{
+	QDF_STATUS uResult = QDF_STATUS_E_FAILURE;
+
+	/* check for invalid pointer */
+	if (NULL == pbBuf) {
+		uResult = QDF_STATUS_E_FAULT;
+		return uResult;
+	}
+
+	get_random_bytes(pbBuf, numBytes);
+	/* "Random sequence generated." */
+	uResult = QDF_STATUS_SUCCESS;
+	return uResult;
+}
+
+#ifdef WLAN_FEATURE_11W
+uint8_t cds_get_mmie_size(void)
+{
+	return sizeof(struct ieee80211_mmie);
+}
+
+/*--------------------------------------------------------------------------
+
+   \brief cds_increase_seq() - Increase the IPN aka Sequence number by one unit
+
+   The cds_increase_seq() function increases the IPN by one unit.
+
+   \param ipn - pointer to the IPN aka Sequence number [6 bytes]
+
+   --------------------------------------------------------------------------*/
+static void cds_increase_seq(uint8_t *ipn)
+{
+	uint64_t value = 0;
+
+	if (ipn) {
+		value = (0xffffffffffff) & (*((uint64_t *) ipn));
+		value = value + 1;
+		qdf_mem_copy(ipn, &value, IEEE80211_MMIE_IPNLEN);
+	}
+}
+
+/*--------------------------------------------------------------------------
+
+   \brief cds_attach_mmie() - attches the complete MMIE at the end of frame
+
+   The cds_attach_mmie() calculates the entire MMIE and attaches at the end
+   of Broadcast/Multicast robust management frames.
+
+   \param igtk - pointer  group key which will be used to calculate
+   the 8 byte MIC.
+   \param ipn - pointer ipn, it is also known as sequence number
+   \param key_id - key identication number
+   \param frm - pointer to the start of the frame.
+   \param efrm - pointer to the end of the frame.
+   \param frmLen - size of the entire frame.
+
+   \return - this function will return true on success and false on
+   failure.
+
+   --------------------------------------------------------------------------*/
+
+bool
+cds_attach_mmie(uint8_t *igtk, uint8_t *ipn, uint16_t key_id,
+		uint8_t *frm, uint8_t *efrm, uint16_t frmLen)
+{
+	struct ieee80211_mmie *mmie;
+	struct ieee80211_frame *wh;
+	uint8_t aad[AAD_LEN], mic[CMAC_TLEN], *input = NULL;
+	uint8_t previous_ipn[IEEE80211_MMIE_IPNLEN] = { 0 };
+	uint16_t nBytes = 0;
+	int ret = 0;
+	struct crypto_cipher *tfm;
+
+	/*  This is how received frame look like
+	 *
+	 *        <------------frmLen---------------------------->
+	 *
+	 *        +---------------+----------------------+-------+
+	 *        | 802.11 HEADER | Management framebody | MMIE  |
+	 *        +---------------+----------------------+-------+
+	 *                                                       ^
+	 *                                                       |
+	 *                                                      efrm
+	 *   This is how MMIE from above frame look like
+	 *
+	 *
+	 *        <------------ 18 Bytes----------------------------->
+	 *        +--------+---------+---------+-----------+---------+
+	 *        |Element | Length  | Key id  |   IPN     |  MIC    |
+	 *        |  id    |         |         |           |         |
+	 *        +--------+---------+---------+-----------+---------+
+	 * Octet     1         1         2         6            8
+	 *
+	 */
+
+	/* Check if frame is invalid length */
+	if (((efrm - frm) != frmLen) || (frmLen < sizeof(*wh))) {
+		cds_err("Invalid frame length");
+		return false;
+	}
+	mmie = (struct ieee80211_mmie *)(efrm - sizeof(*mmie));
+
+	/* Copy Element id */
+	mmie->element_id = IEEE80211_ELEMID_MMIE;
+
+	/* Copy Length */
+	mmie->length = sizeof(*mmie) - 2;
+
+	/* Copy Key id */
+	mmie->key_id = key_id;
+
+	/*
+	 * In case of error, revert back to original IPN
+	 * to do that copy the original IPN into previous_ipn
+	 */
+	qdf_mem_copy(&previous_ipn[0], ipn, IEEE80211_MMIE_IPNLEN);
+	cds_increase_seq(ipn);
+	qdf_mem_copy(mmie->sequence_number, ipn, IEEE80211_MMIE_IPNLEN);
+
+	/*
+	 * Calculate MIC and then copy
+	 */
+	tfm = cds_crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(tfm)) {
+		ret = PTR_ERR(tfm);
+		tfm = NULL;
+		cds_err("crypto_alloc_cipher failed (%d)", ret);
+		goto err_tfm;
+	}
+
+	ret = crypto_cipher_setkey(tfm, igtk, AES_KEYSIZE_128);
+	if (ret) {
+		cds_err("crypto_cipher_setkey failed (%d)", ret);
+		goto err_tfm;
+	}
+
+	/* Construct AAD */
+	wh = (struct ieee80211_frame *)frm;
+
+	/* Generate BIP AAD: FC(masked) || A1 || A2 || A3 */
+
+	/* FC type/subtype */
+	aad[0] = wh->i_fc[0];
+	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
+	aad[1] = wh->i_fc[1] & ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT |
+				 IEEE80211_FC1_MORE_DATA);
+	/* A1 || A2 || A3 */
+	qdf_mem_copy(aad + 2, wh->i_addr_all, 3 * IEEE80211_ADDR_LEN);
+
+	/* MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) */
+	nBytes = AAD_LEN + (frmLen - sizeof(struct ieee80211_frame));
+	input = (uint8_t *) qdf_mem_malloc(nBytes);
+	if (NULL == input) {
+		cds_err("Memory allocation failed");
+		ret = QDF_STATUS_E_NOMEM;
+		goto err_tfm;
+	}
+
+	/*
+	 * Copy the AAD, Management frame body, and
+	 * MMIE with 8 bit MIC zeroed out
+	 */
+	qdf_mem_copy(input, aad, AAD_LEN);
+	/* Copy Management Frame Body and MMIE without MIC */
+	qdf_mem_copy(input + AAD_LEN,
+		     (uint8_t *) (efrm -
+				  (frmLen - sizeof(struct ieee80211_frame))),
+		     nBytes - AAD_LEN - CMAC_TLEN);
+
+	cds_cmac_calc_mic(tfm, input, nBytes, mic);
+	qdf_mem_free(input);
+
+	cds_debug("CMAC(T)= %02X %02X %02X %02X %02X %02X %02X %02X",
+		  mic[0], mic[1], mic[2], mic[3],
+		  mic[4], mic[5], mic[6], mic[7]);
+	qdf_mem_copy(mmie->mic, mic, IEEE80211_MMIE_MICLEN);
+
+err_tfm:
+	if (ret) {
+		qdf_mem_copy(ipn, previous_ipn, IEEE80211_MMIE_IPNLEN);
+	}
+
+	if (tfm)
+		cds_crypto_free_cipher(tfm);
+	return !ret ? true : false;
+}
+
+bool
+cds_is_mmie_valid(uint8_t *igtk, uint8_t *ipn, uint8_t *frm, uint8_t *efrm)
+{
+	struct ieee80211_mmie *mmie;
+	struct ieee80211_frame *wh;
+	uint8_t *rx_ipn, aad[AAD_LEN], mic[CMAC_TLEN], *input;
+	uint16_t nBytes = 0;
+	int ret = 0;
+	struct crypto_cipher *tfm;
+
+	/* Check if frame is invalid length */
+	if ((efrm < frm) || ((efrm - frm) < sizeof(*wh))) {
+		cds_err("Invalid frame length");
+		return false;
+	}
+
+	mmie = (struct ieee80211_mmie *)(efrm - sizeof(*mmie));
+
+	/* Check Element ID */
+	if ((mmie->element_id != IEEE80211_ELEMID_MMIE) ||
+	    (mmie->length != (sizeof(*mmie) - 2))) {
+		cds_err("IE is not Mgmt MIC IE or Invalid length");
+		/* IE is not Mgmt MIC IE or invalid length */
+		return false;
+	}
+
+	/* Validate IPN */
+	rx_ipn = mmie->sequence_number;
+	if (OS_MEMCMP(rx_ipn, ipn, CMAC_IPN_LEN) <= 0) {
+		/* Replay error */
+		cds_err("Replay error mmie ipn %02X %02X %02X %02X %02X %02X"
+			  " drvr ipn %02X %02X %02X %02X %02X %02X",
+			  rx_ipn[0], rx_ipn[1], rx_ipn[2], rx_ipn[3], rx_ipn[4],
+			  rx_ipn[5], ipn[0], ipn[1], ipn[2], ipn[3], ipn[4],
+			  ipn[5]);
+		return false;
+	}
+	tfm = cds_crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(tfm)) {
+		ret = PTR_ERR(tfm);
+		tfm = NULL;
+		cds_err("crypto_alloc_cipher failed (%d)", ret);
+		goto err_tfm;
+	}
+
+	ret = crypto_cipher_setkey(tfm, igtk, AES_KEYSIZE_128);
+	if (ret) {
+		cds_err("crypto_cipher_setkey failed (%d)", ret);
+		goto err_tfm;
+	}
+
+	/* Construct AAD */
+	wh = (struct ieee80211_frame *)frm;
+
+	/* Generate BIP AAD: FC(masked) || A1 || A2 || A3 */
+
+	/* FC type/subtype */
+	aad[0] = wh->i_fc[0];
+	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
+	aad[1] = wh->i_fc[1] & ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT |
+				 IEEE80211_FC1_MORE_DATA);
+	/* A1 || A2 || A3 */
+	qdf_mem_copy(aad + 2, wh->i_addr_all, 3 * IEEE80211_ADDR_LEN);
+
+	/* MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) */
+	nBytes = AAD_LEN + (efrm - (uint8_t *) (wh + 1));
+	input = (uint8_t *) qdf_mem_malloc(nBytes);
+	if (NULL == input) {
+		cds_err("Memory allocation failed");
+		ret = QDF_STATUS_E_NOMEM;
+		goto err_tfm;
+	}
+
+	/* Copy the AAD, MMIE with 8 bit MIC zeroed out */
+	qdf_mem_copy(input, aad, AAD_LEN);
+	qdf_mem_copy(input + AAD_LEN, (uint8_t *) (wh + 1),
+		     nBytes - AAD_LEN - CMAC_TLEN);
+
+	cds_cmac_calc_mic(tfm, input, nBytes, mic);
+	qdf_mem_free(input);
+
+	cds_err("CMAC(T)= %02X %02X %02X %02X %02X %02X %02X %02X",
+		mic[0], mic[1], mic[2], mic[3],
+		mic[4], mic[5], mic[6], mic[7]);
+
+	if (OS_MEMCMP(mic, mmie->mic, CMAC_TLEN) != 0) {
+		/* MMIE MIC mismatch */
+		cds_err("BC/MC MGMT frame MMIE MIC check Failed"
+			  " rmic %02X %02X %02X %02X %02X %02X %02X %02X"
+			  " cmic %02X %02X %02X %02X %02X %02X %02X %02X",
+			  mmie->mic[0], mmie->mic[1], mmie->mic[2],
+			  mmie->mic[3], mmie->mic[4], mmie->mic[5],
+			  mmie->mic[6], mmie->mic[7], mic[0], mic[1], mic[2],
+			  mic[3], mic[4], mic[5], mic[6], mic[7]);
+		return false;
+	}
+
+	/* Update IPN */
+	qdf_mem_copy(ipn, rx_ipn, CMAC_IPN_LEN);
+
+err_tfm:
+	if (tfm)
+		cds_crypto_free_cipher(tfm);
+
+	return !ret ? true : false;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+uint8_t cds_get_gmac_mmie_size(void)
+{
+	return sizeof(struct ieee80211_mmie_16);
+}
+#else
+uint8_t cds_get_gmac_mmie_size(void)
+{
+	return 0;
+}
+#endif
+
+/**
+ * ipn_swap: Swaps ipn
+ * @d: destination pointer
+ * @s: source pointer
+ *
+ * Return: None
+ */
+static inline void ipn_swap(u8 *d, const u8 *s)
+{
+	*d++ = s[5];
+	*d++ = s[4];
+	*d++ = s[3];
+	*d++ = s[2];
+	*d++ = s[1];
+	*d = s[0];
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+bool cds_is_gmac_mmie_valid(uint8_t *igtk, uint8_t *ipn, uint8_t *frm,
+			    uint8_t *efrm, uint16_t key_length)
+{
+	struct ieee80211_mmie_16 *mmie;
+	struct ieee80211_frame *wh;
+	uint8_t rx_ipn[6], aad[AAD_LEN];
+	uint8_t mic[IEEE80211_MMIE_GMAC_MICLEN] = {0};
+	uint16_t data_len;
+	uint8_t gmac_nonce[GMAC_NONCE_LEN];
+	uint8_t iv[AES_BLOCK_SIZE] = {0};
+	int ret;
+
+	/* Check if frame is invalid length */
+	if ((efrm < frm) || ((efrm - frm) < sizeof(*wh))) {
+		cds_err("Invalid frame length");
+		return false;
+	}
+
+	mmie = (struct ieee80211_mmie_16 *)(efrm - sizeof(*mmie));
+
+	/* Check Element ID */
+	if ((mmie->element_id != IEEE80211_ELEMID_MMIE) ||
+	    (mmie->length != (sizeof(*mmie) - 2))) {
+		cds_err("IE is not Mgmt MIC IE or Invalid length");
+		/* IE is not Mgmt MIC IE or invalid length */
+		return false;
+	}
+
+	/* Validate IPN */
+	ipn_swap(rx_ipn, mmie->sequence_number);
+	if (qdf_mem_cmp(rx_ipn, ipn, IEEE80211_MMIE_IPNLEN) <= 0) {
+		/* Replay error */
+		cds_debug("Replay error mmie ipn %02X %02X %02X %02X %02X %02X"
+			  " drvr ipn %02X %02X %02X %02X %02X %02X",
+			  rx_ipn[0], rx_ipn[1], rx_ipn[2], rx_ipn[3], rx_ipn[4],
+			  rx_ipn[5], ipn[0], ipn[1], ipn[2], ipn[3], ipn[4],
+			  ipn[5]);
+		return false;
+	}
+
+	/* Construct AAD */
+	wh = (struct ieee80211_frame *)frm;
+
+	/* Generate AAD: FC(masked) || A1 || A2 || A3 */
+	/* FC type/subtype */
+	aad[0] = wh->i_fc[0];
+	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
+	aad[1] = wh->i_fc[1] & ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT |
+				 IEEE80211_FC1_MORE_DATA);
+	/* A1 || A2 || A3 */
+	qdf_mem_copy(aad + 2, wh->i_addr_all, 3 * IEEE80211_ADDR_LEN);
+
+	data_len = efrm - (uint8_t *) (wh + 1) - IEEE80211_MMIE_GMAC_MICLEN;
+
+	/* IV */
+	qdf_mem_copy(gmac_nonce, wh->i_addr2, IEEE80211_ADDR_LEN);
+	qdf_mem_copy(gmac_nonce + IEEE80211_ADDR_LEN, rx_ipn,
+		     IEEE80211_MMIE_IPNLEN);
+	qdf_mem_copy(iv, gmac_nonce, GMAC_NONCE_LEN);
+	iv[AES_BLOCK_SIZE - 1] = 0x01;
+
+	ret = qdf_crypto_aes_gmac(igtk, key_length, iv, aad,
+				     (uint8_t *) (wh + 1), data_len, mic);
+	if (ret) {
+		cds_err("qdf_crypto_aes_gmac failed %d", ret);
+		return false;
+	}
+
+	if (qdf_mem_cmp(mic, mmie->mic, IEEE80211_MMIE_GMAC_MICLEN) != 0) {
+		/* MMIE MIC mismatch */
+		cds_debug("BC/MC MGMT frame MMIE MIC check Failed"
+			  " rmic %02X %02X %02X %02X %02X %02X %02X %02X"
+			  " %02X %02X %02X %02X %02X %02X %02X %02X",
+			  mmie->mic[0], mmie->mic[1], mmie->mic[2],
+			  mmie->mic[3], mmie->mic[4], mmie->mic[5],
+			  mmie->mic[6], mmie->mic[7], mmie->mic[8],
+			  mmie->mic[9], mmie->mic[10], mmie->mic[11],
+			  mmie->mic[12], mmie->mic[13], mmie->mic[14],
+			  mmie->mic[15]);
+		return false;
+	}
+
+	/* Update IPN */
+	qdf_mem_copy(ipn, rx_ipn, IEEE80211_MMIE_IPNLEN);
+
+	return true;
+}
+#else
+bool cds_is_gmac_mmie_valid(uint8_t *igtk, uint8_t *ipn, uint8_t *frm,
+			    uint8_t *efrm, uint16_t key_length)
+{
+	return false;
+}
+#endif
+
+#endif /* WLAN_FEATURE_11W */
+
+uint32_t cds_chan_to_freq(uint8_t chan)
+{
+	if (chan < CDS_24_GHZ_CHANNEL_14)       /* ch 0 - ch 13 */
+		return CDS_24_GHZ_BASE_FREQ + chan * CDS_CHAN_SPACING_5MHZ;
+	else if (chan == CDS_24_GHZ_CHANNEL_14) /* ch 14 */
+		return CDS_CHAN_14_FREQ;
+	else if (chan < CDS_24_GHZ_CHANNEL_27)  /* ch 15 - ch 26 */
+		return CDS_CHAN_15_FREQ +
+		       (chan - CDS_24_GHZ_CHANNEL_15) * CDS_CHAN_SPACING_20MHZ;
+	else if (chan == CDS_5_GHZ_CHANNEL_170)
+		return CDS_CHAN_170_FREQ;
+	else
+		return CDS_5_GHZ_BASE_FREQ + chan * CDS_CHAN_SPACING_5MHZ;
+}
+
+uint8_t cds_freq_to_chan(uint32_t freq)
+{
+	uint8_t chan;
+
+	if (freq > CDS_24_GHZ_BASE_FREQ && freq < CDS_CHAN_14_FREQ)
+		chan = ((freq - CDS_24_GHZ_BASE_FREQ) / CDS_CHAN_SPACING_5MHZ);
+	else if (freq == CDS_CHAN_14_FREQ)
+		chan = CDS_24_GHZ_CHANNEL_14;
+	else if ((freq > CDS_24_GHZ_BASE_FREQ) && (freq < CDS_5_GHZ_BASE_FREQ))
+		chan = (((freq - CDS_CHAN_15_FREQ) / CDS_CHAN_SPACING_20MHZ) +
+			CDS_24_GHZ_CHANNEL_15);
+	else
+		chan = (freq - CDS_5_GHZ_BASE_FREQ) / CDS_CHAN_SPACING_5MHZ;
+	return chan;
+}
+
+void cds_upper_to_lower(uint8_t *txt, uint32_t length)
+{
+	int i;
+
+	for (i = 0; i < length; i++) {
+		if (txt[i] >= 'A' && txt[i] <= 'Z')
+			txt[i] = txt[i] + 32;
+	}
+}
+
+enum cds_band_type cds_chan_to_band(uint32_t chan)
+{
+	if (chan <= CDS_24_GHZ_CHANNEL_14)
+		return CDS_BAND_2GHZ;
+
+	return CDS_BAND_5GHZ;
+}
+
+void cds_copy_hlp_info(struct qdf_mac_addr *input_dst_mac,
+		       struct qdf_mac_addr *input_src_mac,
+		       uint16_t input_hlp_data_len,
+		       uint8_t *input_hlp_data,
+		       struct qdf_mac_addr *output_dst_mac,
+		       struct qdf_mac_addr *output_src_mac,
+		       uint16_t *output_hlp_data_len,
+		       uint8_t *output_hlp_data)
+{
+	if (!input_hlp_data_len) {
+		cds_debug("Input HLP data len zero\n");
+		return;
+	}
+
+	qdf_copy_macaddr(output_dst_mac, input_dst_mac);
+	qdf_copy_macaddr(output_src_mac, input_src_mac);
+	*output_hlp_data_len = input_hlp_data_len;
+	qdf_mem_copy(output_hlp_data, input_hlp_data, input_hlp_data_len);
+}
diff --git a/core/cds/src/i_cds_packet.h b/core/cds/src/i_cds_packet.h
new file mode 100644
index 0000000..24f900f
--- /dev/null
+++ b/core/cds/src/i_cds_packet.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014-2016 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.
+ */
+
+#if !defined(__I_CDS_PACKET_H)
+#define __I_CDS_PACKET_H
+
+/**=========================================================================
+
+   \file        i_cds_packet.h
+
+   \brief       Connectivity driver services network packet APIs
+
+   Network Protocol packet/buffer internal include file
+
+   ========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include "qdf_types.h"
+/**
+ * Rx Packet Struct
+ * Buffer for the packet received from WMA has pointers to 802.11
+ * frame fields and additional information based on the type of frame.
+ * @channel: Channel number
+ * @snr: Signal to noise ratio
+ * @rssi: Received signal strength indicator, normalized to -96 dBm as
+ *        normal noise floor by adding -96 to snr. All the configured
+ *        thresholds in the driver assume that noise floor is -96 dBm.
+ * @timestamp: System timestamp when frame was received. Set to jiffies.
+ * @mpdu_hdr_ptr: Pointer to beginning of 802.11 MPDU
+ * @mpdu_data_ptr: Pointer to beginning of payload
+ * @mpdu_len: Length of 802.11 MPDU
+ * @mpdu_hdr_len: Length of 802.11 MPDU header
+ * @mpdu_data_len: Length of 802.11 MPDU payload
+ * @offloadScanLearn: Bit set to 1 for beacons received during roaming scan
+ * @roamCandidateInd: Bit set to 1 when roaming candidate is found by fw
+ * @scan: Bit set to 1 if packet received during scanning
+ * @scan_src: Source of scan
+ * @dpuFeedback: DPU feedback for frame
+ * @sessionId: PE session
+ * @tsf_delta: Delta between tsf in frame and local value of tsf
+ * @rssi_raw: rssi based on actual noise floor in hardware.
+ */
+typedef struct {
+	uint8_t channel;
+	uint8_t snr;
+	uint32_t rssi;
+	uint32_t timestamp;
+	uint8_t *mpdu_hdr_ptr;
+	uint8_t *mpdu_data_ptr;
+	uint32_t mpdu_len;
+	uint32_t mpdu_hdr_len;
+	uint32_t mpdu_data_len;
+	uint8_t offloadScanLearn:1;
+	uint8_t roamCandidateInd:1;
+	uint8_t scan:1;
+	uint8_t scan_src;
+	uint8_t dpuFeedback;
+	uint8_t sessionId;
+	uint32_t tsf_delta;
+	uint32_t rssi_raw;
+} t_packetmeta, *tp_packetmeta;
+
+/* implementation specific cds packet type */
+struct cds_pkt_t {
+	/* Packet Meta Information */
+	t_packetmeta pkt_meta;
+
+	/* Pointer to Packet */
+	void *pkt_buf;
+};
+
+#endif /* !defined( __I_CDS_PACKET_H ) */
diff --git a/core/cds/src/queue.h b/core/cds/src/queue.h
new file mode 100644
index 0000000..7320042
--- /dev/null
+++ b/core/cds/src/queue.h
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 1991, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *    @(#)queue.h    8.5 (Berkeley) 8/20/94
+ * $FreeBSD: src/sys/sys/queue.h,v 1.58 2004/04/07 04:19:49 imp Exp $
+ */
+
+#if !defined(__NetBSD__)
+#ifndef _SYS_QUEUE_H_
+#define    _SYS_QUEUE_H_
+
+/*
+ * This file defines four types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction.  Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ *                SLIST    LIST    STAILQ    TAILQ
+ * _HEAD            +    +    +    +
+ * _HEAD_INITIALIZER        +    +    +    +
+ * _ENTRY            +    +    +    +
+ * _INIT            +    +    +    +
+ * _EMPTY            +    +    +    +
+ * _FIRST            +    +    +    +
+ * _NEXT            +    +    +    +
+ * _PREV            -    -    -    +
+ * _LAST            -    -    +    +
+ * _FOREACH            +    +    +    +
+ * _FOREACH_SAFE        +    +    +    +
+ * _FOREACH_REVERSE        -    -    -    +
+ * _FOREACH_REVERSE_SAFE    -    -    -    +
+ * _INSERT_HEAD            +    +    +    +
+ * _INSERT_BEFORE        -    +    -    +
+ * _INSERT_AFTER        +    +    +    +
+ * _INSERT_TAIL            -    -    +    +
+ * _CONCAT            -    -    +    +
+ * _REMOVE_HEAD            +    -    +    -
+ * _REMOVE            +    +    +    +
+ *
+ */
+#define    QUEUE_MACRO_DEBUG 0
+#if QUEUE_MACRO_DEBUG
+/* Store the last 2 places the queue element or head was altered */
+struct qm_trace {
+	char *lastfile;
+	int lastline;
+	char *prevfile;
+	int prevline;
+};
+
+#define    TRACEBUF    struct qm_trace trace;
+#define    TRASHIT(x)    do {(x) = (void *)NULL; } while (0)
+
+#define    QMD_TRACE_HEAD(head) do {			\
+		(head)->trace.prevline = (head)->trace.lastline;	\
+		(head)->trace.prevfile = (head)->trace.lastfile;	\
+		(head)->trace.lastline = __LINE__;		  \
+		(head)->trace.lastfile = __FILE__;		  \
+} while (0)
+
+#define    QMD_TRACE_ELEM(elem) do {			\
+		(elem)->trace.prevline = (elem)->trace.lastline;	\
+		(elem)->trace.prevfile = (elem)->trace.lastfile;	\
+		(elem)->trace.lastline = __LINE__;		  \
+		(elem)->trace.lastfile = __FILE__;		  \
+} while (0)
+
+#else
+#define    QMD_TRACE_ELEM(elem)
+#define    QMD_TRACE_HEAD(head)
+#define    TRACEBUF
+#define TRASHIT(x) do {(x) = (void *)0; } while (0)
+#endif /* QUEUE_MACRO_DEBUG */
+
+#ifdef ATHR_RNWF
+/* NDIS contains a defn for SLIST_ENTRY and SINGLE_LIST_ENTRY */
+#endif
+
+/*
+ * Singly-linked List declarations.
+ */
+#define    SLIST_HEAD(name, type)			 \
+	struct name {				     \
+		struct type *slh_first; /* first element */	       \
+	}
+
+#define    SLIST_HEAD_INITIALIZER(head)			   \
+	{ NULL }
+
+#define    SING_LIST_ENTRY(type)			\
+	struct {				\
+		struct type *sle_next; /* next element */	     \
+	}
+
+/*
+ * Singly-linked List functions.
+ */
+#define    SLIST_EMPTY(head)    ((head)->slh_first == NULL)
+
+#define    SLIST_FIRST(head)    ((head)->slh_first)
+
+#define    SLIST_FOREACH(var, head, field)		      \
+	for ((var) = SLIST_FIRST((head));		 \
+	     (var);			       \
+	     (var) = SLIST_NEXT((var), field))
+
+#define    SLIST_FOREACH_SAFE(var, head, field, tvar)		 \
+	for ((var) = SLIST_FIRST((head));		 \
+	     (var) && ((tvar) = SLIST_NEXT((var), field), 1);	     \
+	     (var) = (tvar))
+
+#define    SLIST_FOREACH_PREVPTR(var, varp, head, field)	    \
+	for ((varp) = &SLIST_FIRST((head));		   \
+	     ((var) = *(varp)) != NULL;			   \
+	     (varp) = &SLIST_NEXT((var), field))
+
+#define    SLIST_INIT(head) do {			\
+		SLIST_FIRST((head)) = NULL;		       \
+} while (0)
+
+#define    SLIST_INSERT_AFTER(slistelm, elm, field) do {	    \
+		SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);    \
+		SLIST_NEXT((slistelm), field) = (elm);		      \
+} while (0)
+
+#define    SLIST_INSERT_HEAD(head, elm, field) do {	       \
+		SLIST_NEXT((elm), field) = SLIST_FIRST((head));		   \
+		SLIST_FIRST((head)) = (elm);			\
+} while (0)
+
+#define    SLIST_NEXT(elm, field)    ((elm)->field.sle_next)
+
+#define    SLIST_REMOVE(head, elm, type, field) do {		\
+		if (SLIST_FIRST((head)) == (elm)) {		   \
+			SLIST_REMOVE_HEAD((head), field);	     \
+		}				 \
+		else {				      \
+			struct type *curelm = SLIST_FIRST((head));	  \
+			while (SLIST_NEXT(curelm, field) != (elm))	  \
+				curelm = SLIST_NEXT(curelm, field);	   \
+			SLIST_NEXT(curelm, field) =		   \
+				SLIST_NEXT(SLIST_NEXT(curelm, field), field);	 \
+		}				 \
+} while (0)
+
+#define    SLIST_REMOVE_HEAD(head, field) do {		      \
+		SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	 \
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define    STAILQ_HEAD(name, type)			  \
+	struct name {				     \
+		struct type *stqh_first; /* first element */		\
+		struct type **stqh_last; /* addr of last next element */	 \
+	}
+
+#define    STAILQ_HEAD_INITIALIZER(head)		    \
+	{ NULL, &(head).stqh_first }
+
+#define    STAILQ_ENTRY(type)			     \
+	struct {				\
+		struct type *stqe_next; /* next element */	      \
+	}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define    STAILQ_CONCAT(head1, head2) do {		   \
+		if (!STAILQ_EMPTY((head2))) {			 \
+			*(head1)->stqh_last = (head2)->stqh_first;	  \
+			(head1)->stqh_last = (head2)->stqh_last;	\
+			STAILQ_INIT((head2));			 \
+		}				 \
+} while (0)
+
+#define    STAILQ_EMPTY(head)    ((head)->stqh_first == NULL)
+
+#define    STAILQ_FIRST(head)    ((head)->stqh_first)
+
+#define    STAILQ_FOREACH(var, head, field)		   \
+	for((var) = STAILQ_FIRST((head));		 \
+	    (var);			      \
+	    (var) = STAILQ_NEXT((var), field))
+
+#define    STAILQ_FOREACH_SAFE(var, head, field, tvar)		  \
+	for ((var) = STAILQ_FIRST((head));		  \
+	     (var) && ((tvar) = STAILQ_NEXT((var), field), 1);	      \
+	     (var) = (tvar))
+
+#define    STAILQ_INIT(head) do {			 \
+		STAILQ_FIRST((head)) = NULL;			\
+		(head)->stqh_last = &STAILQ_FIRST((head));	      \
+} while (0)
+
+#define    STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {	    \
+		if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL) \
+			(head)->stqh_last = &STAILQ_NEXT((elm), field);	       \
+		STAILQ_NEXT((tqelm), field) = (elm);		    \
+} while (0)
+
+#define    STAILQ_INSERT_HEAD(head, elm, field) do {		\
+		if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	   \
+			(head)->stqh_last = &STAILQ_NEXT((elm), field);	       \
+		STAILQ_FIRST((head)) = (elm);			 \
+} while (0)
+
+#define    STAILQ_INSERT_TAIL(head, elm, field) do {		\
+		STAILQ_NEXT((elm), field) = NULL;		 \
+		*(head)->stqh_last = (elm);		       \
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		   \
+} while (0)
+
+#define    STAILQ_LAST(head, type, field)		     \
+	(STAILQ_EMPTY((head)) ?			       \
+	 NULL :				   \
+	 ((struct type *)		     \
+	  ((char *)((head)->stqh_last) - __offsetof(struct type, field))))
+
+#define    STAILQ_NEXT(elm, field)    ((elm)->field.stqe_next)
+
+#define    STAILQ_REMOVE(head, elm, type, field) do {		 \
+		if (STAILQ_FIRST((head)) == (elm)) {		    \
+			STAILQ_REMOVE_HEAD((head), field);	      \
+		}				 \
+		else {				      \
+			struct type *curelm = STAILQ_FIRST((head));	   \
+			while (STAILQ_NEXT(curelm, field) != (elm))	   \
+				curelm = STAILQ_NEXT(curelm, field);	    \
+			if ((STAILQ_NEXT(curelm, field) =	     \
+				     STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL) \
+				(head)->stqh_last = &STAILQ_NEXT((curelm), field); \
+		}				 \
+} while (0)
+
+#define    STAILQ_REMOVE_AFTER(head, elm, field) do {		 \
+		if (STAILQ_NEXT(elm, field)) {	      \
+			if ((STAILQ_NEXT(elm, field) =		  \
+				     STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
+				(head)->stqh_last = &STAILQ_NEXT((elm), field);	\
+		}				 \
+} while (0)
+
+#define    STAILQ_REMOVE_HEAD(head, field) do {		       \
+		if ((STAILQ_FIRST((head)) =		       \
+			     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)	       \
+			(head)->stqh_last = &STAILQ_FIRST((head));	  \
+} while (0)
+
+#define    STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {	      \
+		if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL)	   \
+			(head)->stqh_last = &STAILQ_FIRST((head));	  \
+} while (0)
+
+/*
+ * List declarations.
+ */
+#define    ATH_LIST_HEAD(name, type)			\
+	struct name {				     \
+		struct type *lh_first; /* first element */	      \
+	}
+
+#ifndef LIST_HEAD
+#define LIST_HEAD ATH_LIST_HEAD
+#endif
+
+#define    LIST_HEAD_INITIALIZER(head)			  \
+	{ NULL }
+
+#define    LIST_ENTRY(type)			   \
+	struct {				\
+		struct type *le_next; /* next element */	    \
+		struct type **le_prev; /* address of previous next element */	  \
+	}
+
+/*
+ * List functions.
+ */
+
+#define    LIST_EMPTY(head)    ((head)->lh_first == NULL)
+
+#define    LIST_FIRST(head)    ((head)->lh_first)
+
+#define    LIST_FOREACH(var, head, field)		     \
+	for ((var) = LIST_FIRST((head));		\
+	     (var);			       \
+	     (var) = LIST_NEXT((var), field))
+
+#define    LIST_FOREACH_SAFE(var, head, field, tvar)		\
+	for ((var) = LIST_FIRST((head));		\
+	     (var) && ((tvar) = LIST_NEXT((var), field), 1);	    \
+	     (var) = (tvar))
+
+#define    LIST_INIT(head) do {			       \
+		LIST_FIRST((head)) = NULL;		      \
+} while (0)
+
+#define    LIST_INSERT_AFTER(listelm, elm, field) do {		  \
+		if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) \
+			LIST_NEXT((listelm), field)->field.le_prev =	    \
+				&LIST_NEXT((elm), field);		 \
+		LIST_NEXT((listelm), field) = (elm);		    \
+		(elm)->field.le_prev = &LIST_NEXT((listelm), field);	    \
+} while (0)
+
+#define    LIST_INSERT_BEFORE(listelm, elm, field) do {		   \
+		(elm)->field.le_prev = (listelm)->field.le_prev;	\
+		LIST_NEXT((elm), field) = (listelm);		    \
+		*(listelm)->field.le_prev = (elm);		  \
+		(listelm)->field.le_prev = &LIST_NEXT((elm), field);	    \
+} while (0)
+
+#define    LIST_INSERT_HEAD(head, elm, field) do {		  \
+		if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)    \
+			LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); \
+		LIST_FIRST((head)) = (elm);		       \
+		(elm)->field.le_prev = &LIST_FIRST((head));	       \
+} while (0)
+
+#define    LIST_NEXT(elm, field)    ((elm)->field.le_next)
+
+#define    LIST_REMOVE(elm, field) do {			   \
+		if (LIST_NEXT((elm), field) != NULL)		    \
+			LIST_NEXT((elm), field)->field.le_prev =	 \
+				(elm)->field.le_prev;		     \
+		*(elm)->field.le_prev = LIST_NEXT((elm), field);	\
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#define  HEADNAME
+#define  COPY_HEADNAME(head)
+
+#define    TAILQ_HEAD(name, type)			 \
+	struct name {				     \
+		struct type *tqh_first; /* first element */	       \
+		struct type **tqh_last; /* addr of last next element */	\
+		HEADNAME			    \
+			TRACEBUF			    \
+	}
+
+#define    TAILQ_HEAD_INITIALIZER(head)			   \
+	{ NULL, &(head).tqh_first }
+
+#define    TAILQ_ENTRY(type)			    \
+	struct {				\
+		struct type *tqe_next; /* next element */	     \
+		struct type **tqe_prev; /* address of previous next element */	   \
+		TRACEBUF			    \
+	}
+
+/*
+ * Tail queue functions.
+ */
+
+#define    TAILQ_EMPTY(head)    ((head)->tqh_first == NULL)
+
+#define    TAILQ_FIRST(head)    ((head)->tqh_first)
+
+#define    TAILQ_FOREACH(var, head, field)		      \
+	for ((var) = TAILQ_FIRST((head));		 \
+	     (var);			       \
+	     (var) = TAILQ_NEXT((var), field))
+
+#define    TAILQ_FOREACH_SAFE(var, head, field, tvar)		 \
+	for ((var) = TAILQ_FIRST((head));		 \
+	     (var) && ((tvar) = TAILQ_NEXT((var), field), 1);	     \
+	     (var) = (tvar))
+
+#define    TAILQ_FOREACH_REVERSE(var, head, headname, field)	    \
+	for ((var) = TAILQ_LAST((head), headname);	      \
+	     (var);			       \
+	     (var) = TAILQ_PREV((var), headname, field))
+
+#define    TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	   \
+	for ((var) = TAILQ_LAST((head), headname);	      \
+	     (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	   \
+	     (var) = (tvar))
+
+#define    TAILQ_INIT(head) do {			\
+		TAILQ_FIRST((head)) = NULL;		       \
+		(head)->tqh_last = &TAILQ_FIRST((head));	    \
+		COPY_HEADNAME(head);			     \
+		QMD_TRACE_HEAD(head);			     \
+} while (0)
+
+#define    TAILQ_INSERT_AFTER(head, listelm, elm, field) do {	     \
+		if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL) \
+			TAILQ_NEXT((elm), field)->field.tqe_prev =	   \
+				&TAILQ_NEXT((elm), field);		  \
+		else {				      \
+			(head)->tqh_last = &TAILQ_NEXT((elm), field);	     \
+			QMD_TRACE_HEAD(head);			 \
+		}				 \
+		TAILQ_NEXT((listelm), field) = (elm);		     \
+		(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);	      \
+		QMD_TRACE_ELEM(&(elm)->field);			  \
+		QMD_TRACE_ELEM(&listelm->field);		\
+} while (0)
+
+#define    TAILQ_INSERT_BEFORE(listelm, elm, field) do {	    \
+		(elm)->field.tqe_prev = (listelm)->field.tqe_prev;	  \
+		TAILQ_NEXT((elm), field) = (listelm);		     \
+		*(listelm)->field.tqe_prev = (elm);		   \
+		(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);	      \
+		QMD_TRACE_ELEM(&(elm)->field);			  \
+		QMD_TRACE_ELEM(&listelm->field);		\
+} while (0)
+
+#define    TAILQ_INSERT_HEAD(head, elm, field) do {	       \
+		if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	 \
+			TAILQ_FIRST((head))->field.tqe_prev =		 \
+				&TAILQ_NEXT((elm), field);		  \
+		else				    \
+			(head)->tqh_last = &TAILQ_NEXT((elm), field);	     \
+		TAILQ_FIRST((head)) = (elm);			\
+		(elm)->field.tqe_prev = &TAILQ_FIRST((head));		 \
+		QMD_TRACE_HEAD(head);			     \
+		QMD_TRACE_ELEM(&(elm)->field);			  \
+} while (0)
+
+#define    TAILQ_INSERT_TAIL(head, elm, field) do {	       \
+		TAILQ_NEXT((elm), field) = NULL;		\
+		(elm)->field.tqe_prev = (head)->tqh_last;	     \
+		*(head)->tqh_last = (elm);		      \
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		 \
+		QMD_TRACE_HEAD(head);			     \
+		QMD_TRACE_ELEM(&(elm)->field);			  \
+} while (0)
+
+#define    TAILQ_LAST(head, headname)			 \
+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define    TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define    TAILQ_PREV(elm, headname, field)		   \
+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define    TAILQ_REMOVE(head, elm, field) do {		      \
+		if ((TAILQ_NEXT((elm), field)) != NULL)		       \
+			TAILQ_NEXT((elm), field)->field.tqe_prev =	   \
+				(elm)->field.tqe_prev;		      \
+		else {				      \
+			(head)->tqh_last = (elm)->field.tqe_prev;	 \
+			QMD_TRACE_HEAD(head);			 \
+		}				 \
+		*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);	  \
+		TRASHIT((elm)->field.tqe_next);			   \
+		TRASHIT((elm)->field.tqe_prev);			   \
+		QMD_TRACE_ELEM(&(elm)->field);			  \
+} while (0)
+
+#define TAILQ_CONCAT(head1, head2, field)  do {			 \
+		if (!TAILQ_EMPTY(head2)) {				     \
+			*(head1)->tqh_last = (head2)->tqh_first;		 \
+			(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	 \
+			(head1)->tqh_last  = (head2)->tqh_last;			 \
+			TAILQ_INIT((head2));					 \
+		}							     \
+} while (0)
+
+#ifdef _KERNEL
+
+/*
+ * XXX insque() and remque() are an old way of handling certain queues.
+ * They bogusly assumes that all queue heads look alike.
+ */
+
+struct quehead {
+	struct quehead *qh_link;
+	struct quehead *qh_rlink;
+};
+
+#if defined(__GNUC__) || defined(__INTEL_COMPILER)
+
+static __inline void insque(void *a, void *b)
+{
+	struct quehead *element = (struct quehead *)a,
+	*head = (struct quehead *)b;
+
+	element->qh_link = head->qh_link;
+	element->qh_rlink = head;
+	head->qh_link = element;
+	element->qh_link->qh_rlink = element;
+}
+
+static __inline void remque(void *a)
+{
+	struct quehead *element = (struct quehead *)a;
+
+	element->qh_link->qh_rlink = element->qh_rlink;
+	element->qh_rlink->qh_link = element->qh_link;
+	element->qh_rlink = 0;
+}
+
+#else                           /* !(__GNUC__ || __INTEL_COMPILER) */
+
+void insque(void *a, void *b);
+void remque(void *a);
+
+#endif /* __GNUC__ || __INTEL_COMPILER */
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_QUEUE_H_ */
+#else                           /* !__NetBSD__ */
+#include_next <sys/queue.h>
+#endif /* __NetBSD__ */
diff --git a/core/dp/htt/htt.c b/core/dp/htt/htt.c
new file mode 100644
index 0000000..ae15b37
--- /dev/null
+++ b/core/dp/htt/htt.c
@@ -0,0 +1,1003 @@
+/*
+ * Copyright (c) 2011, 2014-2018 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.
+ */
+
+/**
+ * @file htt.c
+ * @brief Provide functions to create+init and destroy a HTT instance.
+ * @details
+ *  This file contains functions for creating a HTT instance; initializing
+ *  the HTT instance, e.g. by allocating a pool of HTT tx descriptors and
+ *  connecting the HTT service with HTC; and deleting a HTT instance.
+ */
+
+#include <qdf_mem.h>         /* qdf_mem_malloc */
+#include <qdf_types.h>          /* qdf_device_t, qdf_print */
+
+#include <htt.h>                /* htt_tx_msdu_desc_t */
+#include <ol_cfg.h>
+#include <ol_txrx_htt_api.h>    /* ol_tx_dowload_done_ll, etc. */
+#include <ol_htt_api.h>
+
+#include <htt_internal.h>
+#include <ol_htt_tx_api.h>
+#include <cds_api.h>
+#include "hif.h"
+#include <cdp_txrx_handle.h>
+
+#define HTT_HTC_PKT_POOL_INIT_SIZE 100  /* enough for a large A-MPDU */
+
+QDF_STATUS(*htt_h2t_rx_ring_cfg_msg)(struct htt_pdev_t *pdev);
+QDF_STATUS(*htt_h2t_rx_ring_rfs_cfg_msg)(struct htt_pdev_t *pdev);
+
+#ifdef IPA_OFFLOAD
+static QDF_STATUS htt_ipa_config(htt_pdev_handle pdev, QDF_STATUS status)
+{
+	if ((QDF_STATUS_SUCCESS == status) &&
+	    ol_cfg_ipa_uc_offload_enabled(pdev->ctrl_pdev))
+		status = htt_h2t_ipa_uc_rsc_cfg_msg(pdev);
+	return status;
+}
+
+#define HTT_IPA_CONFIG htt_ipa_config
+#else
+#define HTT_IPA_CONFIG(pdev, status) status     /* no-op */
+#endif /* IPA_OFFLOAD */
+
+struct htt_htc_pkt *htt_htc_pkt_alloc(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt_union *pkt = NULL;
+
+	HTT_TX_MUTEX_ACQUIRE(&pdev->htt_tx_mutex);
+	if (pdev->htt_htc_pkt_freelist) {
+		pkt = pdev->htt_htc_pkt_freelist;
+		pdev->htt_htc_pkt_freelist = pdev->htt_htc_pkt_freelist->u.next;
+	}
+	HTT_TX_MUTEX_RELEASE(&pdev->htt_tx_mutex);
+
+	if (pkt == NULL)
+		pkt = qdf_mem_malloc(sizeof(*pkt));
+
+	if (!pkt) {
+		qdf_print("%s: HTC packet allocation failed\n", __func__);
+		return NULL;
+	}
+	htc_packet_set_magic_cookie(&(pkt->u.pkt.htc_pkt), 0);
+	return &pkt->u.pkt;     /* not actually a dereference */
+}
+
+void htt_htc_pkt_free(struct htt_pdev_t *pdev, struct htt_htc_pkt *pkt)
+{
+	struct htt_htc_pkt_union *u_pkt = (struct htt_htc_pkt_union *)pkt;
+
+	if (!u_pkt) {
+		qdf_print("%s: HTC packet is NULL\n", __func__);
+		return;
+	}
+
+	HTT_TX_MUTEX_ACQUIRE(&pdev->htt_tx_mutex);
+	htc_packet_set_magic_cookie(&(u_pkt->u.pkt.htc_pkt), 0);
+	u_pkt->u.next = pdev->htt_htc_pkt_freelist;
+	pdev->htt_htc_pkt_freelist = u_pkt;
+	HTT_TX_MUTEX_RELEASE(&pdev->htt_tx_mutex);
+}
+
+void htt_htc_pkt_pool_free(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt_union *pkt, *next;
+
+	HTT_TX_MUTEX_ACQUIRE(&pdev->htt_tx_mutex);
+	pkt = pdev->htt_htc_pkt_freelist;
+	pdev->htt_htc_pkt_freelist = NULL;
+	HTT_TX_MUTEX_RELEASE(&pdev->htt_tx_mutex);
+
+	while (pkt) {
+		next = pkt->u.next;
+		qdf_mem_free(pkt);
+		pkt = next;
+	}
+}
+
+#ifdef ATH_11AC_TXCOMPACT
+
+void
+htt_htc_misc_pkt_list_trim(struct htt_pdev_t *pdev, int level)
+{
+	struct htt_htc_pkt_union *pkt, *next, *prev = NULL;
+	int i = 0;
+	qdf_nbuf_t netbuf;
+
+	HTT_TX_MUTEX_ACQUIRE(&pdev->htt_tx_mutex);
+	pkt = pdev->htt_htc_pkt_misclist;
+	while (pkt) {
+		next = pkt->u.next;
+		/* trim the out grown list*/
+		if (++i > level) {
+			netbuf =
+				(qdf_nbuf_t)(pkt->u.pkt.htc_pkt.pNetBufContext);
+			qdf_nbuf_unmap(pdev->osdev, netbuf, QDF_DMA_TO_DEVICE);
+			qdf_nbuf_free(netbuf);
+			qdf_mem_free(pkt);
+			pkt = NULL;
+			if (prev)
+				prev->u.next = NULL;
+		}
+		prev = pkt;
+		pkt = next;
+	}
+	HTT_TX_MUTEX_RELEASE(&pdev->htt_tx_mutex);
+}
+
+void htt_htc_misc_pkt_list_add(struct htt_pdev_t *pdev, struct htt_htc_pkt *pkt)
+{
+	struct htt_htc_pkt_union *u_pkt = (struct htt_htc_pkt_union *)pkt;
+	int misclist_trim_level = htc_get_tx_queue_depth(pdev->htc_pdev,
+							pkt->htc_pkt.Endpoint)
+				+ HTT_HTC_PKT_MISCLIST_SIZE;
+
+	HTT_TX_MUTEX_ACQUIRE(&pdev->htt_tx_mutex);
+	if (pdev->htt_htc_pkt_misclist) {
+		u_pkt->u.next = pdev->htt_htc_pkt_misclist;
+		pdev->htt_htc_pkt_misclist = u_pkt;
+	} else {
+		pdev->htt_htc_pkt_misclist = u_pkt;
+	}
+	HTT_TX_MUTEX_RELEASE(&pdev->htt_tx_mutex);
+
+	/* only ce pipe size + tx_queue_depth could possibly be in use
+	 * free older packets in the msiclist
+	 */
+	htt_htc_misc_pkt_list_trim(pdev, misclist_trim_level);
+}
+
+void htt_htc_misc_pkt_pool_free(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt_union *pkt, *next;
+	qdf_nbuf_t netbuf;
+
+	HTT_TX_MUTEX_ACQUIRE(&pdev->htt_tx_mutex);
+	pkt = pdev->htt_htc_pkt_misclist;
+	pdev->htt_htc_pkt_misclist = NULL;
+	HTT_TX_MUTEX_RELEASE(&pdev->htt_tx_mutex);
+
+	while (pkt) {
+		next = pkt->u.next;
+		if (htc_packet_get_magic_cookie(&(pkt->u.pkt.htc_pkt)) !=
+				HTC_PACKET_MAGIC_COOKIE) {
+			QDF_ASSERT(0);
+			pkt = next;
+			continue;
+		}
+
+		netbuf = (qdf_nbuf_t) (pkt->u.pkt.htc_pkt.pNetBufContext);
+		qdf_nbuf_unmap(pdev->osdev, netbuf, QDF_DMA_TO_DEVICE);
+		qdf_nbuf_free(netbuf);
+		qdf_mem_free(pkt);
+		pkt = next;
+	}
+}
+#endif
+
+
+/* AR6004 don't need HTT layer. */
+#ifdef AR6004_HW
+#define NO_HTT_NEEDED true
+#else
+#define NO_HTT_NEEDED false
+#endif
+
+#if defined(QCA_TX_HTT2_SUPPORT) && defined(CONFIG_HL_SUPPORT)
+
+/**
+ * htt_htc_tx_htt2_service_start() - Start TX HTT2 service
+ *
+ * @pdev: pointer to htt device.
+ * @connect_req: pointer to service connection request information
+ * @connect_resp: pointer to service connection response information
+ *
+ *
+ * Return: None
+ */
+static void
+htt_htc_tx_htt2_service_start(struct htt_pdev_t *pdev,
+			      struct htc_service_connect_req *connect_req,
+			      struct htc_service_connect_resp *connect_resp)
+{
+	QDF_STATUS status;
+
+	qdf_mem_set(connect_req, 0, sizeof(struct htc_service_connect_req));
+	qdf_mem_set(connect_resp, 0, sizeof(struct htc_service_connect_resp));
+
+	/* The same as HTT service but no RX. */
+	connect_req->EpCallbacks.pContext = pdev;
+	connect_req->EpCallbacks.EpTxComplete = htt_h2t_send_complete;
+	connect_req->EpCallbacks.EpSendFull = htt_h2t_full;
+	connect_req->MaxSendQueueDepth = HTT_MAX_SEND_QUEUE_DEPTH;
+	/* Should NOT support credit flow control. */
+	connect_req->ConnectionFlags |=
+				HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
+	/* Enable HTC schedule mechanism for TX HTT2 service. */
+	connect_req->ConnectionFlags |= HTC_CONNECT_FLAGS_ENABLE_HTC_SCHEDULE;
+
+	connect_req->service_id = HTT_DATA2_MSG_SVC;
+
+	status = htc_connect_service(pdev->htc_pdev, connect_req, connect_resp);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		pdev->htc_tx_htt2_endpoint = ENDPOINT_UNUSED;
+		pdev->htc_tx_htt2_max_size = 0;
+	} else {
+		pdev->htc_tx_htt2_endpoint = connect_resp->Endpoint;
+		pdev->htc_tx_htt2_max_size = HTC_TX_HTT2_MAX_SIZE;
+	}
+
+	qdf_print("TX HTT %s, ep %d size %d\n",
+		  (status == QDF_STATUS_SUCCESS ? "ON" : "OFF"),
+		  pdev->htc_tx_htt2_endpoint,
+		  pdev->htc_tx_htt2_max_size);
+}
+#else
+
+static inline void
+htt_htc_tx_htt2_service_start(struct htt_pdev_t *pdev,
+			      struct htc_service_connect_req *connect_req,
+			      struct htc_service_connect_resp *connect_resp)
+{
+}
+#endif
+
+/**
+ * htt_htc_credit_flow_disable() - disable flow control for
+ *				   HTT data message service
+ *
+ * @pdev: pointer to htt device.
+ * @connect_req: pointer to service connection request information
+ *
+ * HTC Credit mechanism is disabled based on
+ * default_tx_comp_req as throughput will be lower
+ * if we disable htc credit mechanism with default_tx_comp_req
+ * set since txrx download packet will be limited by ota
+ * completion.
+ *
+ * Return: None
+ */
+static
+void htt_htc_credit_flow_disable(struct htt_pdev_t *pdev,
+				 struct htc_service_connect_req *connect_req)
+{
+	if (pdev->osdev->bus_type == QDF_BUS_TYPE_SDIO) {
+		/*
+		 * TODO:Conditional disabling will be removed once firmware
+		 * with reduced tx completion is pushed into release builds.
+		 */
+		if (!pdev->cfg.default_tx_comp_req)
+			connect_req->ConnectionFlags |=
+			HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
+	} else {
+		connect_req->ConnectionFlags |=
+			HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
+	}
+}
+
+#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
+
+/**
+ * htt_dump_bundle_stats() - dump wlan stats
+ * @pdev: handle to the HTT instance
+ *
+ * Return: None
+ */
+void htt_dump_bundle_stats(htt_pdev_handle pdev)
+{
+	htc_dump_bundle_stats(pdev->htc_pdev);
+}
+
+/**
+ * htt_clear_bundle_stats() - clear wlan stats
+ * @pdev: handle to the HTT instance
+ *
+ * Return: None
+ */
+void htt_clear_bundle_stats(htt_pdev_handle pdev)
+{
+	htc_clear_bundle_stats(pdev->htc_pdev);
+}
+#endif
+
+#if defined(QCA_WIFI_3_0_ADRASTEA)
+/**
+ * htt_htc_attach_all() - Connect to HTC service for HTT
+ * @pdev: pdev ptr
+ *
+ * Return: 0 for success or error code.
+ */
+
+#if defined(QCN7605_SUPPORT) && defined(IPA_OFFLOAD)
+
+/* In case of QCN7605 with IPA offload only 2 CE
+ * are used for RFS
+ */
+static int
+htt_htc_attach_all(struct htt_pdev_t *pdev)
+{
+	if (htt_htc_attach(pdev, HTT_DATA_MSG_SVC))
+		goto flush_endpoint;
+
+	if (htt_htc_attach(pdev, HTT_DATA2_MSG_SVC))
+		goto flush_endpoint;
+
+	return 0;
+
+flush_endpoint:
+	htc_flush_endpoint(pdev->htc_pdev, ENDPOINT_0, HTC_TX_PACKET_TAG_ALL);
+
+	return -EIO;
+}
+
+#else
+
+static int
+htt_htc_attach_all(struct htt_pdev_t *pdev)
+{
+	if (htt_htc_attach(pdev, HTT_DATA_MSG_SVC))
+		goto flush_endpoint;
+
+	if (htt_htc_attach(pdev, HTT_DATA2_MSG_SVC))
+		goto flush_endpoint;
+
+	if (htt_htc_attach(pdev, HTT_DATA3_MSG_SVC))
+		goto flush_endpoint;
+
+	return 0;
+
+flush_endpoint:
+	htc_flush_endpoint(pdev->htc_pdev, ENDPOINT_0, HTC_TX_PACKET_TAG_ALL);
+
+	return -EIO;
+}
+
+#endif
+
+#else
+/**
+ * htt_htc_attach_all() - Connect to HTC service for HTT
+ * @pdev: pdev ptr
+ *
+ * Return: 0 for success or error code.
+ */
+static int
+htt_htc_attach_all(struct htt_pdev_t *pdev)
+{
+	return htt_htc_attach(pdev, HTT_DATA_MSG_SVC);
+}
+#endif
+
+/**
+ * htt_pdev_alloc() - allocate HTT pdev
+ * @txrx_pdev: txrx pdev
+ * @ctrl_pdev: cfg pdev
+ * @htc_pdev: HTC pdev
+ * @osdev: os device
+ *
+ * Return: HTT pdev handle
+ */
+htt_pdev_handle
+htt_pdev_alloc(ol_txrx_pdev_handle txrx_pdev,
+	   struct cdp_cfg *ctrl_pdev,
+	   HTC_HANDLE htc_pdev, qdf_device_t osdev)
+{
+	struct htt_pdev_t *pdev;
+	struct hif_opaque_softc *osc =  cds_get_context(QDF_MODULE_ID_HIF);
+
+	if (!osc)
+		goto fail1;
+
+	pdev = qdf_mem_malloc(sizeof(*pdev));
+	if (!pdev)
+		goto fail1;
+
+	pdev->osdev = osdev;
+	pdev->ctrl_pdev = ctrl_pdev;
+	pdev->txrx_pdev = txrx_pdev;
+	pdev->htc_pdev = htc_pdev;
+
+	pdev->htt_htc_pkt_freelist = NULL;
+#ifdef ATH_11AC_TXCOMPACT
+	pdev->htt_htc_pkt_misclist = NULL;
+#endif
+
+	/* for efficiency, store a local copy of the is_high_latency flag */
+	pdev->cfg.is_high_latency = ol_cfg_is_high_latency(pdev->ctrl_pdev);
+	/*
+	 * Credit reporting through HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND
+	 * enabled or not.
+	 */
+	pdev->cfg.credit_update_enabled =
+		ol_cfg_is_credit_update_enabled(pdev->ctrl_pdev);
+
+	pdev->cfg.request_tx_comp = cds_is_ptp_rx_opt_enabled() ||
+		cds_is_packet_log_enabled();
+
+	pdev->cfg.default_tx_comp_req =
+			!ol_cfg_tx_free_at_download(pdev->ctrl_pdev);
+
+	pdev->cfg.is_full_reorder_offload =
+			ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev);
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+		  "full_reorder_offloaded %d",
+		  (int)pdev->cfg.is_full_reorder_offload);
+
+	pdev->cfg.ce_classify_enabled =
+		ol_cfg_is_ce_classify_enabled(ctrl_pdev);
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+		  "ce_classify %d",
+		  pdev->cfg.ce_classify_enabled);
+
+	if (pdev->cfg.is_high_latency) {
+		qdf_atomic_init(&pdev->htt_tx_credit.target_delta);
+		qdf_atomic_init(&pdev->htt_tx_credit.bus_delta);
+		qdf_atomic_add(HTT_MAX_BUS_CREDIT,
+			       &pdev->htt_tx_credit.bus_delta);
+	}
+
+	pdev->targetdef = htc_get_targetdef(htc_pdev);
+#if defined(HELIUMPLUS)
+	HTT_SET_WIFI_IP(pdev, 2, 0);
+#endif /* defined(HELIUMPLUS) */
+
+	if (NO_HTT_NEEDED)
+		goto success;
+	/*
+	 * Connect to HTC service.
+	 * This has to be done before calling htt_rx_attach,
+	 * since htt_rx_attach involves sending a rx ring configure
+	 * message to the target.
+	 */
+	HTT_TX_MUTEX_INIT(&pdev->htt_tx_mutex);
+	HTT_TX_NBUF_QUEUE_MUTEX_INIT(pdev);
+	HTT_TX_MUTEX_INIT(&pdev->credit_mutex);
+	if (htt_htc_attach_all(pdev))
+		goto htt_htc_attach_fail;
+	if (hif_ce_fastpath_cb_register(osc, htt_t2h_msg_handler_fast, pdev))
+		qdf_print("failed to register fastpath callback\n");
+
+success:
+	return pdev;
+
+htt_htc_attach_fail:
+	HTT_TX_MUTEX_DESTROY(&pdev->credit_mutex);
+	HTT_TX_MUTEX_DESTROY(&pdev->htt_tx_mutex);
+	HTT_TX_NBUF_QUEUE_MUTEX_DESTROY(pdev);
+	qdf_mem_free(pdev);
+
+fail1:
+	return NULL;
+
+}
+
+/**
+ * htt_attach() - Allocate and setup HTT TX/RX descriptors
+ * @pdev: pdev ptr
+ * @desc_pool_size: size of tx descriptors
+ *
+ * Return: 0 for success or error code.
+ */
+int
+htt_attach(struct htt_pdev_t *pdev, int desc_pool_size)
+{
+	int i;
+	int ret = 0;
+
+	pdev->is_ipa_uc_enabled = false;
+	if (ol_cfg_ipa_uc_offload_enabled(pdev->ctrl_pdev))
+		pdev->is_ipa_uc_enabled = true;
+
+	ret = htt_tx_attach(pdev, desc_pool_size);
+	if (ret)
+		goto fail1;
+
+	ret = htt_rx_attach(pdev);
+	if (ret)
+		goto fail2;
+
+	/* pre-allocate some HTC_PACKET objects */
+	for (i = 0; i < HTT_HTC_PKT_POOL_INIT_SIZE; i++) {
+		struct htt_htc_pkt_union *pkt;
+
+		pkt = qdf_mem_malloc(sizeof(*pkt));
+		if (!pkt)
+			break;
+		htt_htc_pkt_free(pdev, &pkt->u.pkt);
+	}
+
+	if (pdev->cfg.is_high_latency) {
+		/*
+		 * HL - download the whole frame.
+		 * Specify a download length greater than the max MSDU size,
+		 * so the downloads will be limited by the actual frame sizes.
+		 */
+		pdev->download_len = 5000;
+
+		if (ol_cfg_tx_free_at_download(pdev->ctrl_pdev) &&
+		    !pdev->cfg.request_tx_comp)
+			pdev->tx_send_complete_part2 =
+						ol_tx_download_done_hl_free;
+		else
+			pdev->tx_send_complete_part2 =
+						ol_tx_download_done_hl_retain;
+
+		/*
+		 * CHECK THIS LATER: does the HL HTT version of
+		 * htt_rx_mpdu_desc_list_next
+		 * (which is not currently implemented) present the
+		 * adf_nbuf_data(rx_ind_msg)
+		 * as the abstract rx descriptor?
+		 * If not, the rx_fw_desc_offset initialization
+		 * here will have to be adjusted accordingly.
+		 * NOTE: for HL, because fw rx desc is in ind msg,
+		 * not in rx desc, so the
+		 * offset should be negtive value
+		 */
+		pdev->rx_fw_desc_offset =
+			HTT_ENDIAN_BYTE_IDX_SWAP(
+					HTT_RX_IND_FW_RX_DESC_BYTE_OFFSET
+					- HTT_RX_IND_HL_BYTES);
+
+		htt_h2t_rx_ring_cfg_msg = htt_h2t_rx_ring_cfg_msg_hl;
+		htt_h2t_rx_ring_rfs_cfg_msg = htt_h2t_rx_ring_rfs_cfg_msg_hl;
+
+		/* initialize the txrx credit count */
+		ol_tx_target_credit_update(
+				pdev->txrx_pdev, ol_cfg_target_tx_credit(
+					pdev->ctrl_pdev));
+	} else {
+		enum wlan_frm_fmt frm_type;
+
+		/*
+		 * LL - download just the initial portion of the frame.
+		 * Download enough to cover the encapsulation headers checked
+		 * by the target's tx classification descriptor engine.
+		 *
+		 * For LL, the FW rx desc directly referenced at its location
+		 * inside the rx indication message.
+		 */
+
+		/* account for the 802.3 or 802.11 header */
+		frm_type = ol_cfg_frame_type(pdev->ctrl_pdev);
+
+		if (frm_type == wlan_frm_fmt_native_wifi) {
+			pdev->download_len = HTT_TX_HDR_SIZE_NATIVE_WIFI;
+		} else if (frm_type == wlan_frm_fmt_802_3) {
+			pdev->download_len = HTT_TX_HDR_SIZE_ETHERNET;
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+				  "Unexpected frame type spec: %d", frm_type);
+			HTT_ASSERT0(0);
+		}
+
+		/*
+		 * Account for the optional L2 / ethernet header fields:
+		 * 802.1Q, LLC/SNAP
+		 */
+		pdev->download_len +=
+			HTT_TX_HDR_SIZE_802_1Q + HTT_TX_HDR_SIZE_LLC_SNAP;
+
+		/*
+		 * Account for the portion of the L3 (IP) payload that the
+		 * target needs for its tx classification.
+		 */
+		pdev->download_len += ol_cfg_tx_download_size(pdev->ctrl_pdev);
+
+		/*
+		 * Account for the HTT tx descriptor, including the
+		 * HTC header + alignment padding.
+		 */
+		pdev->download_len += sizeof(struct htt_host_tx_desc_t);
+
+		/*
+		 * The TXCOMPACT htt_tx_sched function uses pdev->download_len
+		 * to apply for all requeued tx frames.  Thus,
+		 * pdev->download_len has to be the largest download length of
+		 * any tx frame that will be downloaded.
+		 * This maximum download length is for management tx frames,
+		 * which have an 802.11 header.
+		 */
+#ifdef ATH_11AC_TXCOMPACT
+		pdev->download_len = sizeof(struct htt_host_tx_desc_t)
+			+ HTT_TX_HDR_SIZE_OUTER_HDR_MAX /* worst case */
+			+ HTT_TX_HDR_SIZE_802_1Q
+			+ HTT_TX_HDR_SIZE_LLC_SNAP
+			+ ol_cfg_tx_download_size(pdev->ctrl_pdev);
+#endif
+		pdev->tx_send_complete_part2 = ol_tx_download_done_ll;
+
+		/*
+		 * For LL, the FW rx desc is alongside the HW rx desc fields in
+		 * the htt_host_rx_desc_base struct/.
+		 */
+		pdev->rx_fw_desc_offset = RX_STD_DESC_FW_MSDU_OFFSET;
+
+		htt_h2t_rx_ring_cfg_msg = htt_h2t_rx_ring_cfg_msg_ll;
+		htt_h2t_rx_ring_rfs_cfg_msg = htt_h2t_rx_ring_rfs_cfg_msg_ll;
+	}
+
+	return 0;
+
+fail2:
+	htt_tx_detach(pdev);
+
+fail1:
+	return ret;
+}
+
+QDF_STATUS htt_attach_target(htt_pdev_handle pdev)
+{
+	QDF_STATUS status;
+
+	status = htt_h2t_ver_req_msg(pdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s:%d: could not send h2t_ver_req msg",
+			  __func__, __LINE__);
+		return status;
+	}
+#if defined(HELIUMPLUS)
+	/*
+	 * Send the frag_desc info to target.
+	 */
+	status = htt_h2t_frag_desc_bank_cfg_msg(pdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s:%d: could not send h2t_frag_desc_bank_cfg msg",
+			  __func__, __LINE__);
+		return status;
+	}
+#endif /* defined(HELIUMPLUS) */
+
+
+	/*
+	 * If applicable, send the rx ring config message to the target.
+	 * The host could wait for the HTT version number confirmation message
+	 * from the target before sending any further HTT messages, but it's
+	 * reasonable to assume that the host and target HTT version numbers
+	 * match, and proceed immediately with the remaining configuration
+	 * handshaking.
+	 */
+
+	status = htt_h2t_rx_ring_rfs_cfg_msg(pdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s:%d: could not send h2t_rx_ring_rfs_cfg msg",
+			  __func__, __LINE__);
+		return status;
+	}
+
+	status = htt_h2t_rx_ring_cfg_msg(pdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s:%d: could not send h2t_rx_ring_cfg msg",
+			  __func__, __LINE__);
+		return status;
+	}
+
+	status = HTT_IPA_CONFIG(pdev, status);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s:%d: could not send h2t_ipa_uc_rsc_cfg msg",
+			  __func__, __LINE__);
+		return status;
+	}
+
+	return status;
+}
+
+void htt_detach(htt_pdev_handle pdev)
+{
+	htt_rx_detach(pdev);
+	htt_tx_detach(pdev);
+	htt_htc_pkt_pool_free(pdev);
+#ifdef ATH_11AC_TXCOMPACT
+	htt_htc_misc_pkt_pool_free(pdev);
+#endif
+	HTT_TX_MUTEX_DESTROY(&pdev->credit_mutex);
+	HTT_TX_MUTEX_DESTROY(&pdev->htt_tx_mutex);
+	HTT_TX_NBUF_QUEUE_MUTEX_DESTROY(pdev);
+}
+
+/**
+ * htt_pdev_free() - Free HTT pdev
+ * @pdev: htt pdev
+ *
+ * Return: none
+ */
+void htt_pdev_free(htt_pdev_handle pdev)
+{
+	qdf_mem_free(pdev);
+}
+
+void htt_detach_target(htt_pdev_handle pdev)
+{
+}
+
+static inline
+int htt_update_endpoint(struct htt_pdev_t *pdev,
+			uint16_t service_id, HTC_ENDPOINT_ID ep)
+{
+	struct hif_opaque_softc *hif_ctx;
+	uint8_t ul = 0xff, dl = 0xff;
+	int     ul_polled, dl_polled;
+	int     tx_service = 0;
+	int     rc = 0;
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (qdf_unlikely(NULL == hif_ctx)) {
+		QDF_ASSERT(NULL != hif_ctx);
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s:%d: assuming non-tx service.",
+			  __func__, __LINE__);
+	} else {
+		ul = dl = 0xff;
+		if (QDF_STATUS_SUCCESS !=
+		    hif_map_service_to_pipe(hif_ctx, service_id,
+					    &ul, &dl,
+					    &ul_polled, &dl_polled))
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+				  "%s:%d: assuming non-tx srv.",
+				  __func__, __LINE__);
+		else
+			tx_service = (ul != 0xff);
+	}
+	if (tx_service) {
+		/* currently we have only one OUT htt tx service */
+		QDF_BUG(service_id == HTT_DATA_MSG_SVC);
+
+		pdev->htc_tx_endpoint = ep;
+		hif_save_htc_htt_config_endpoint(hif_ctx, ep);
+		rc = 1;
+	}
+	return rc;
+}
+
+int htt_htc_attach(struct htt_pdev_t *pdev, uint16_t service_id)
+{
+	struct htc_service_connect_req connect;
+	struct htc_service_connect_resp response;
+	QDF_STATUS status;
+
+	qdf_mem_set(&connect, sizeof(connect), 0);
+	qdf_mem_set(&response, sizeof(response), 0);
+
+	connect.pMetaData = NULL;
+	connect.MetaDataLength = 0;
+	connect.EpCallbacks.pContext = pdev;
+	connect.EpCallbacks.EpTxComplete = htt_h2t_send_complete;
+	connect.EpCallbacks.EpTxCompleteMultiple = NULL;
+	connect.EpCallbacks.EpRecv = htt_t2h_msg_handler;
+	connect.EpCallbacks.ep_resume_tx_queue = htt_tx_resume_handler;
+
+	/* rx buffers currently are provided by HIF, not by EpRecvRefill */
+	connect.EpCallbacks.EpRecvRefill = NULL;
+	connect.EpCallbacks.RecvRefillWaterMark = 1;
+	/* N/A, fill is done by HIF */
+
+	connect.EpCallbacks.EpSendFull = htt_h2t_full;
+	/*
+	 * Specify how deep to let a queue get before htc_send_pkt will
+	 * call the EpSendFull function due to excessive send queue depth.
+	 */
+	connect.MaxSendQueueDepth = HTT_MAX_SEND_QUEUE_DEPTH;
+
+	/* disable flow control for HTT data message service */
+	htt_htc_credit_flow_disable(pdev, &connect);
+
+	/* connect to control service */
+	connect.service_id = service_id;
+
+	status = htc_connect_service(pdev->htc_pdev, &connect, &response);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		if (cds_is_fw_down())
+			return -EIO;
+
+		if (status == QDF_STATUS_E_NOMEM ||
+		    cds_is_self_recovery_enabled())
+			return qdf_status_to_os_return(status);
+
+		QDF_BUG(0);
+	}
+
+	htt_update_endpoint(pdev, service_id, response.Endpoint);
+
+	/* Start TX HTT2 service if the target support it. */
+	htt_htc_tx_htt2_service_start(pdev, &connect, &response);
+
+	return 0;               /* success */
+}
+
+void htt_log_rx_ring_info(htt_pdev_handle pdev)
+{
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s: htt pdev is NULL", __func__);
+		return;
+	}
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Data Stall Detected with reason 4 (=FW_RX_REFILL_FAILED)."
+		  "src htt rx ring:  space for %d elements, filled with %d buffers, buffers in the ring %d, refill debt %d",
+		  __func__, pdev->rx_ring.size, pdev->rx_ring.fill_level,
+		  pdev->rx_ring.fill_cnt,
+		  qdf_atomic_read(&pdev->rx_ring.refill_debt));
+}
+
+#if HTT_DEBUG_LEVEL > 5
+void htt_display(htt_pdev_handle pdev, int indent)
+{
+	qdf_print("%*s%s:\n", indent, " ", "HTT");
+	qdf_print("%*stx desc pool: %d elems of %d bytes, %d allocated\n",
+		  indent + 4, " ",
+		  pdev->tx_descs.pool_elems,
+		  pdev->tx_descs.size, pdev->tx_descs.alloc_cnt);
+	qdf_print("%*srx ring: space for %d elems, filled with %d buffers\n",
+		  indent + 4, " ",
+		  pdev->rx_ring.size, pdev->rx_ring.fill_level);
+	qdf_print("%*sat %pK (%llx paddr)\n", indent + 8, " ",
+		  pdev->rx_ring.buf.paddrs_ring,
+		  (unsigned long long)pdev->rx_ring.base_paddr);
+	qdf_print("%*snetbuf ring @ %pK\n", indent + 8, " ",
+		  pdev->rx_ring.buf.netbufs_ring);
+	qdf_print("%*sFW_IDX shadow register: vaddr = %pK, paddr = %llx\n",
+		  indent + 8, " ",
+		  pdev->rx_ring.alloc_idx.vaddr,
+		  (unsigned long long)pdev->rx_ring.alloc_idx.paddr);
+	qdf_print("%*sSW enqueue idx= %d, SW dequeue idx: desc= %d, buf= %d\n",
+		  indent + 8, " ", *pdev->rx_ring.alloc_idx.vaddr,
+		  pdev->rx_ring.sw_rd_idx.msdu_desc,
+		  pdev->rx_ring.sw_rd_idx.msdu_payld);
+}
+#endif
+
+#ifdef IPA_OFFLOAD
+/**
+ * htt_ipa_uc_attach() - Allocate UC data path resources
+ * @pdev: handle to the HTT instance
+ *
+ * Return: 0 success
+ *         none 0 fail
+ */
+int htt_ipa_uc_attach(struct htt_pdev_t *pdev)
+{
+	int error;
+
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_DEBUG, "%s: enter",
+		  __func__);
+
+	/* TX resource attach */
+	error = htt_tx_ipa_uc_attach(
+		pdev,
+		ol_cfg_ipa_uc_tx_buf_size(pdev->ctrl_pdev),
+		ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev),
+		ol_cfg_ipa_uc_tx_partition_base(pdev->ctrl_pdev));
+	if (error) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "HTT IPA UC TX attach fail code %d", error);
+		HTT_ASSERT0(0);
+		return error;
+	}
+
+	/* RX resource attach */
+	error = htt_rx_ipa_uc_attach(
+		pdev, qdf_get_pwr2(pdev->rx_ring.fill_level));
+	if (error) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "HTT IPA UC RX attach fail code %d", error);
+		htt_tx_ipa_uc_detach(pdev);
+		HTT_ASSERT0(0);
+		return error;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_DEBUG, "%s: exit",
+		__func__);
+	return 0;               /* success */
+}
+
+/**
+ * htt_ipa_uc_attach() - Remove UC data path resources
+ * @pdev: handle to the HTT instance
+ *
+ * Return: None
+ */
+void htt_ipa_uc_detach(struct htt_pdev_t *pdev)
+{
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_DEBUG, "%s: enter",
+		__func__);
+
+	/* TX IPA micro controller detach */
+	htt_tx_ipa_uc_detach(pdev);
+
+	/* RX IPA micro controller detach */
+	htt_rx_ipa_uc_detach(pdev);
+
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_DEBUG, "%s: exit",
+		__func__);
+}
+
+int
+htt_ipa_uc_get_resource(htt_pdev_handle pdev,
+			qdf_shared_mem_t **ce_sr,
+			qdf_shared_mem_t **tx_comp_ring,
+			qdf_shared_mem_t **rx_rdy_ring,
+			qdf_shared_mem_t **rx2_rdy_ring,
+			qdf_shared_mem_t **rx_proc_done_idx,
+			qdf_shared_mem_t **rx2_proc_done_idx,
+			uint32_t *ce_sr_ring_size,
+			qdf_dma_addr_t *ce_reg_paddr,
+			uint32_t *tx_num_alloc_buffer)
+{
+	/* Release allocated resource to client */
+	*tx_comp_ring = pdev->ipa_uc_tx_rsc.tx_comp_ring;
+	*rx_rdy_ring = pdev->ipa_uc_rx_rsc.rx_ind_ring;
+	*rx2_rdy_ring = pdev->ipa_uc_rx_rsc.rx2_ind_ring;
+	*rx_proc_done_idx = pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx;
+	*rx2_proc_done_idx = pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx;
+	*tx_num_alloc_buffer = (uint32_t)pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt;
+
+	/* Get copy engine, bus resource */
+	htc_ipa_get_ce_resource(pdev->htc_pdev, ce_sr,
+				ce_sr_ring_size, ce_reg_paddr);
+
+	return 0;
+}
+
+/**
+ * htt_ipa_uc_set_doorbell_paddr() - Propagate IPA doorbell address
+ * @pdev: handle to the HTT instance
+ * @ipa_uc_tx_doorbell_paddr: TX doorbell base physical address
+ * @ipa_uc_rx_doorbell_paddr: RX doorbell base physical address
+ *
+ * Return: 0 success
+ */
+int
+htt_ipa_uc_set_doorbell_paddr(htt_pdev_handle pdev,
+			      qdf_dma_addr_t ipa_uc_tx_doorbell_paddr,
+			      qdf_dma_addr_t ipa_uc_rx_doorbell_paddr)
+{
+	pdev->ipa_uc_tx_rsc.tx_comp_idx_paddr = ipa_uc_tx_doorbell_paddr;
+	pdev->ipa_uc_rx_rsc.rx_rdy_idx_paddr = ipa_uc_rx_doorbell_paddr;
+	return 0;
+}
+#endif /* IPA_OFFLOAD */
+
+/**
+ * htt_mark_first_wakeup_packet() - set flag to indicate that
+ *    fw is compatible for marking first packet after wow wakeup
+ * @pdev: pointer to htt pdev
+ * @value: 1 for enabled/ 0 for disabled
+ *
+ * Return: None
+ */
+void htt_mark_first_wakeup_packet(htt_pdev_handle pdev,
+			uint8_t value)
+{
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s: htt pdev is NULL", __func__);
+		return;
+	}
+
+	pdev->cfg.is_first_wakeup_packet = value;
+}
+
diff --git a/core/dp/htt/htt_fw_stats.c b/core/dp/htt/htt_fw_stats.c
new file mode 100644
index 0000000..c21dede
--- /dev/null
+++ b/core/dp/htt/htt_fw_stats.c
@@ -0,0 +1,1330 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/**
+ * @file htt_fw_stats.c
+ * @brief Provide functions to process FW status retrieved from FW.
+ */
+
+#include <htc_api.h>            /* HTC_PACKET */
+#include <htt.h>                /* HTT_T2H_MSG_TYPE, etc. */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <qdf_mem.h>         /* qdf_mem_set */
+#include <ol_fw_tx_dbg.h>       /* ol_fw_tx_dbg_ppdu_base */
+
+#include <ol_htt_rx_api.h>
+#include <ol_txrx_htt_api.h>    /* htt_tx_status */
+
+#include <htt_internal.h>
+
+#include <wlan_defs.h>
+
+#define ROUND_UP_TO_4(val) (((val) + 3) & ~0x3)
+
+
+static char *bw_str_arr[] = {"20MHz", "40MHz", "80MHz", "160MHz"};
+
+/*
+ * Defined the macro tx_rate_stats_print_cmn()
+ * so that this could be used in both
+ * htt_t2h_stats_tx_rate_stats_print() &
+ * htt_t2h_stats_tx_rate_stats_print_v2().
+ * Each of these functions take a different structure as argument,
+ * but with common fields in the structures--so using a macro
+ * to bypass the strong type-checking of a function seems a simple
+ * trick to use to avoid the code duplication.
+ */
+#define tx_rate_stats_print_cmn(_tx_rate_info, _concise) \
+	do {							 \
+		qdf_nofl_info("TX Rate Info:");			 \
+		\
+		/* MCS */					 \
+		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
+				"MCS counts (0..9)",		 \
+				_tx_rate_info->mcs[0],		 \
+				_tx_rate_info->mcs[1],		 \
+				_tx_rate_info->mcs[2],		 \
+				_tx_rate_info->mcs[3],		 \
+				_tx_rate_info->mcs[4],		 \
+				_tx_rate_info->mcs[5],		 \
+				_tx_rate_info->mcs[6],		 \
+				_tx_rate_info->mcs[7],		 \
+				_tx_rate_info->mcs[8],		 \
+				_tx_rate_info->mcs[9]);		 \
+		\
+		/* SGI */					 \
+		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
+				"SGI counts (0..9)",		 \
+				_tx_rate_info->sgi[0],		 \
+				_tx_rate_info->sgi[1],		 \
+				_tx_rate_info->sgi[2],		 \
+				_tx_rate_info->sgi[3],		 \
+				_tx_rate_info->sgi[4],		 \
+				_tx_rate_info->sgi[5],		 \
+				_tx_rate_info->sgi[6],		 \
+				_tx_rate_info->sgi[7],		 \
+				_tx_rate_info->sgi[8],		 \
+				_tx_rate_info->sgi[9]);		 \
+		\
+		/* NSS */					 \
+		qdf_nofl_info("NSS  counts: 1x1 %d, 2x2 %d, 3x3 %d", \
+				_tx_rate_info->nss[0],		 \
+				_tx_rate_info->nss[1], _tx_rate_info->nss[2]);\
+		\
+		/* BW */					 \
+		if (ARRAY_SIZE(_tx_rate_info->bw) == 3) \
+			qdf_nofl_info("BW counts: %s %d, %s %d, %s %d", \
+				bw_str_arr[0], _tx_rate_info->bw[0],	 \
+				bw_str_arr[1], _tx_rate_info->bw[1],	 \
+				bw_str_arr[2], _tx_rate_info->bw[2]);	 \
+		else if (ARRAY_SIZE(_tx_rate_info->bw) == 4) \
+			qdf_nofl_info("BW counts: %s %d, %s %d, %s %d, %s %d", \
+				bw_str_arr[0], _tx_rate_info->bw[0],	 \
+				bw_str_arr[1], _tx_rate_info->bw[1],	 \
+				bw_str_arr[2], _tx_rate_info->bw[2],     \
+				bw_str_arr[3], _tx_rate_info->bw[3]);	 \
+		\
+		\
+		/* Preamble */					 \
+		qdf_nofl_info("Preamble (O C H V) counts: %d, %d, %d, %d",\
+				_tx_rate_info->pream[0],		 \
+				_tx_rate_info->pream[1],		 \
+				_tx_rate_info->pream[2],		 \
+				_tx_rate_info->pream[3]);		 \
+		\
+		/* STBC rate counts */				 \
+		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
+				"STBC rate counts (0..9)",	 \
+				_tx_rate_info->stbc[0],		 \
+				_tx_rate_info->stbc[1],		 \
+				_tx_rate_info->stbc[2],		 \
+				_tx_rate_info->stbc[3],		 \
+				_tx_rate_info->stbc[4],		 \
+				_tx_rate_info->stbc[5],		 \
+				_tx_rate_info->stbc[6],		 \
+				_tx_rate_info->stbc[7],		 \
+				_tx_rate_info->stbc[8],		 \
+				_tx_rate_info->stbc[9]);	 \
+			\
+		/* LDPC and TxBF counts */			 \
+		qdf_nofl_info("LDPC Counts: %d", _tx_rate_info->ldpc);\
+		qdf_nofl_info("RTS Counts: %d", _tx_rate_info->rts_cnt);\
+		/* RSSI Values for last ack frames */		\
+		qdf_nofl_info("Ack RSSI: %d", _tx_rate_info->ack_rssi);\
+	} while (0)
+
+static void htt_t2h_stats_tx_rate_stats_print(wlan_dbg_tx_rate_info_t *
+					      tx_rate_info, int concise)
+{
+	tx_rate_stats_print_cmn(tx_rate_info, concise);
+}
+
+static void htt_t2h_stats_tx_rate_stats_print_v2(wlan_dbg_tx_rate_info_v2_t *
+					      tx_rate_info, int concise)
+{
+	tx_rate_stats_print_cmn(tx_rate_info, concise);
+}
+
+/*
+ * Defined the macro rx_rate_stats_print_cmn()
+ * so that this could be used in both
+ * htt_t2h_stats_rx_rate_stats_print() &
+ * htt_t2h_stats_rx_rate_stats_print_v2().
+ * Each of these functions take a different structure as argument,
+ * but with common fields in the structures -- so using a macro
+ * to bypass the strong type-checking of a function seems a simple
+ * trick to use to avoid the code duplication.
+ */
+#define rx_rate_stats_print_cmn(_rx_phy_info, _concise) \
+	do {							\
+		qdf_nofl_info("RX Rate Info:");			\
+		\
+		/* MCS */					\
+		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
+				"MCS counts (0..9)",		 \
+				_rx_phy_info->mcs[0],			\
+				_rx_phy_info->mcs[1],			\
+				_rx_phy_info->mcs[2],			\
+				_rx_phy_info->mcs[3],			\
+				_rx_phy_info->mcs[4],			\
+				_rx_phy_info->mcs[5],			\
+				_rx_phy_info->mcs[6],			\
+				_rx_phy_info->mcs[7],			\
+				_rx_phy_info->mcs[8],			\
+				_rx_phy_info->mcs[9]);			\
+		\
+		/* SGI */						\
+		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
+				"SGI counts (0..9)",		 \
+				_rx_phy_info->sgi[0],			\
+				_rx_phy_info->sgi[1],			\
+				_rx_phy_info->sgi[2],			\
+				_rx_phy_info->sgi[3],			\
+				_rx_phy_info->sgi[4],			\
+				_rx_phy_info->sgi[5],			\
+				_rx_phy_info->sgi[6],			\
+				_rx_phy_info->sgi[7],			\
+				_rx_phy_info->sgi[8],			\
+				_rx_phy_info->sgi[9]);			\
+		\
+		/*
+		 * NSS							       \
+		 * nss[0] just holds the count of non-stbc frames that were    \
+		 * sent at 1x1 rates and nsts holds the count of frames sent   \
+		 * with stbc.						       \
+		 * It was decided to not include PPDUs sent w/ STBC in nss[0]  \
+		 * since it would be easier to change the value that needs to  \
+		 * be printed (from stbc+non-stbc count to only non-stbc count)\
+		 * if needed in the future. Hence the addition in the host code\
+		 * at this line.
+		 */							       \
+		qdf_nofl_info("NSS  counts: 1x1 %d, 2x2 %d, 3x3 %d, 4x4 %d",\
+				_rx_phy_info->nss[0] + _rx_phy_info->nsts,\
+				_rx_phy_info->nss[1],			\
+				_rx_phy_info->nss[2],			\
+				_rx_phy_info->nss[3]);		\
+		\
+		/* NSTS */					\
+		qdf_nofl_info("NSTS count: %d", _rx_phy_info->nsts);	\
+		\
+		/* BW */					\
+		if (ARRAY_SIZE(_rx_phy_info->bw) == 3) \
+			qdf_nofl_info("BW counts: %s %d, %s %d, %s %d",	\
+				bw_str_arr[0], _rx_phy_info->bw[0],	\
+				bw_str_arr[1], _rx_phy_info->bw[1],	\
+				bw_str_arr[2], _rx_phy_info->bw[2]);	\
+		else if (ARRAY_SIZE(_rx_phy_info->bw) == 4) \
+			qdf_nofl_info("BW counts: %s %d, %s %d, %s %d, %s %d", \
+				bw_str_arr[0], _rx_phy_info->bw[0],	\
+				bw_str_arr[1], _rx_phy_info->bw[1],	\
+				bw_str_arr[2], _rx_phy_info->bw[2],    \
+				bw_str_arr[3], _rx_phy_info->bw[3]);	\
+		\
+		/* Preamble */					\
+		qdf_nofl_info("Preamble counts: %d, %d, %d, %d, %d, %d",\
+				_rx_phy_info->pream[0],		\
+				_rx_phy_info->pream[1],		\
+				_rx_phy_info->pream[2],		\
+				_rx_phy_info->pream[3],		\
+				_rx_phy_info->pream[4],		\
+				_rx_phy_info->pream[5]);		\
+		\
+		/* STBC rate counts */				\
+		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
+				"STBC rate counts (0..9)",	\
+				_rx_phy_info->stbc[0],		\
+				_rx_phy_info->stbc[1],		\
+				_rx_phy_info->stbc[2],		\
+				_rx_phy_info->stbc[3],		\
+				_rx_phy_info->stbc[4],		\
+				_rx_phy_info->stbc[5],		\
+				_rx_phy_info->stbc[6],		\
+				_rx_phy_info->stbc[7],		\
+				_rx_phy_info->stbc[8],		\
+				_rx_phy_info->stbc[9]);		\
+		\
+		/* LDPC and TxBF counts */			\
+		qdf_nofl_info("LDPC TXBF Counts: %d, %d",		\
+				_rx_phy_info->ldpc, _rx_phy_info->txbf);\
+		/* RSSI Values for last received frames */	\
+		qdf_nofl_info("RSSI (data, mgmt): %d, %d", _rx_phy_info->data_rssi,\
+				_rx_phy_info->mgmt_rssi);		\
+		\
+		qdf_nofl_info("RSSI Chain 0 (0x%02x 0x%02x 0x%02x 0x%02x)",\
+				((_rx_phy_info->rssi_chain0 >> 24) & 0xff),\
+				((_rx_phy_info->rssi_chain0 >> 16) & 0xff),\
+				((_rx_phy_info->rssi_chain0 >> 8) & 0xff),\
+				((_rx_phy_info->rssi_chain0 >> 0) & 0xff));\
+		\
+		qdf_nofl_info("RSSI Chain 1 (0x%02x 0x%02x 0x%02x 0x%02x)",\
+				((_rx_phy_info->rssi_chain1 >> 24) & 0xff),\
+				((_rx_phy_info->rssi_chain1 >> 16) & 0xff),\
+				((_rx_phy_info->rssi_chain1 >> 8) & 0xff),\
+				((_rx_phy_info->rssi_chain1 >> 0) & 0xff));\
+		\
+		qdf_nofl_info("RSSI Chain 2 (0x%02x 0x%02x 0x%02x 0x%02x)",\
+				((_rx_phy_info->rssi_chain2 >> 24) & 0xff),\
+				((_rx_phy_info->rssi_chain2 >> 16) & 0xff),\
+				((_rx_phy_info->rssi_chain2 >> 8) & 0xff),\
+				((_rx_phy_info->rssi_chain2 >> 0) & 0xff));\
+	} while (0)
+
+static void htt_t2h_stats_rx_rate_stats_print(wlan_dbg_rx_rate_info_t *
+					      rx_phy_info, int concise)
+{
+	rx_rate_stats_print_cmn(rx_phy_info, concise);
+}
+
+static void htt_t2h_stats_rx_rate_stats_print_v2(wlan_dbg_rx_rate_info_v2_t *
+					      rx_phy_info, int concise)
+{
+	rx_rate_stats_print_cmn(rx_phy_info, concise);
+}
+
+static void
+htt_t2h_stats_pdev_stats_print(struct wlan_dbg_stats *wlan_pdev_stats,
+			       int concise)
+{
+	struct wlan_dbg_tx_stats *tx = &wlan_pdev_stats->tx;
+	struct wlan_dbg_rx_stats *rx = &wlan_pdev_stats->rx;
+
+	qdf_nofl_info("WAL Pdev stats:");
+	qdf_nofl_info("\n### Tx ###");
+
+	/* Num HTT cookies queued to dispatch list */
+	qdf_nofl_info("comp_queued       :\t%d", tx->comp_queued);
+	/* Num HTT cookies dispatched */
+	qdf_nofl_info("comp_delivered    :\t%d", tx->comp_delivered);
+	/* Num MSDU queued to WAL */
+	qdf_nofl_info("msdu_enqued       :\t%d", tx->msdu_enqued);
+	/* Num MPDU queued to WAL */
+	qdf_nofl_info("mpdu_enqued       :\t%d", tx->mpdu_enqued);
+	/* Num MSDUs dropped by WMM limit */
+	qdf_nofl_info("wmm_drop          :\t%d", tx->wmm_drop);
+	/* Num Local frames queued */
+	qdf_nofl_info("local_enqued      :\t%d", tx->local_enqued);
+	/* Num Local frames done */
+	qdf_nofl_info("local_freed       :\t%d", tx->local_freed);
+	/* Num queued to HW */
+	qdf_nofl_info("hw_queued         :\t%d", tx->hw_queued);
+	/* Num PPDU reaped from HW */
+	qdf_nofl_info("hw_reaped         :\t%d", tx->hw_reaped);
+	/* Num underruns */
+	qdf_nofl_info("mac underrun      :\t%d", tx->underrun);
+	/* Num underruns */
+	qdf_nofl_info("phy underrun      :\t%d", tx->phy_underrun);
+	/* Num PPDUs cleaned up in TX abort */
+	qdf_nofl_info("tx_abort          :\t%d", tx->tx_abort);
+	/* Num MPDUs requed by SW */
+	qdf_nofl_info("mpdus_requed      :\t%d", tx->mpdus_requed);
+	/* Excessive retries */
+	qdf_nofl_info("excess retries    :\t%d", tx->tx_ko);
+	/* last data rate */
+	qdf_nofl_info("last rc           :\t%d", tx->data_rc);
+	/* scheduler self triggers */
+	qdf_nofl_info("sched self trig   :\t%d", tx->self_triggers);
+	/* SW retry failures */
+	qdf_nofl_info("ampdu retry failed:\t%d", tx->sw_retry_failure);
+	/* ilegal phy rate errirs */
+	qdf_nofl_info("illegal rate errs :\t%d", tx->illgl_rate_phy_err);
+	/* pdev continuous excessive retries  */
+	qdf_nofl_info("pdev cont xretry  :\t%d", tx->pdev_cont_xretry);
+	/* pdev continuous excessive retries  */
+	qdf_nofl_info("pdev tx timeout   :\t%d", tx->pdev_tx_timeout);
+	/* pdev resets  */
+	qdf_nofl_info("pdev resets       :\t%d", tx->pdev_resets);
+	/* PPDU > txop duration  */
+	qdf_nofl_info("ppdu txop ovf     :\t%d", tx->txop_ovf);
+
+	qdf_nofl_info("\n### Rx ###\n");
+	/* Cnts any change in ring routing mid-ppdu */
+	qdf_nofl_info("ppdu_route_change :\t%d", rx->mid_ppdu_route_change);
+	/* Total number of statuses processed */
+	qdf_nofl_info("status_rcvd       :\t%d", rx->status_rcvd);
+	/* Extra frags on rings 0-3 */
+	qdf_nofl_info("r0_frags          :\t%d", rx->r0_frags);
+	qdf_nofl_info("r1_frags          :\t%d", rx->r1_frags);
+	qdf_nofl_info("r2_frags          :\t%d", rx->r2_frags);
+	qdf_nofl_info("r3_frags          :\t%d", rx->r3_frags);
+	/* MSDUs / MPDUs delivered to HTT */
+	qdf_nofl_info("htt_msdus         :\t%d", rx->htt_msdus);
+	qdf_nofl_info("htt_mpdus         :\t%d", rx->htt_mpdus);
+	/* MSDUs / MPDUs delivered to local stack */
+	qdf_nofl_info("loc_msdus         :\t%d", rx->loc_msdus);
+	qdf_nofl_info("loc_mpdus         :\t%d", rx->loc_mpdus);
+	/* AMSDUs that have more MSDUs than the status ring size */
+	qdf_nofl_info("oversize_amsdu    :\t%d", rx->oversize_amsdu);
+	/* Number of PHY errors */
+	qdf_nofl_info("phy_errs          :\t%d", rx->phy_errs);
+	/* Number of PHY errors dropped */
+	qdf_nofl_info("phy_errs dropped  :\t%d", rx->phy_err_drop);
+	/* Number of mpdu errors - FCS, MIC, ENC etc. */
+	qdf_nofl_info("mpdu_errs         :\t%d", rx->mpdu_errs);
+
+}
+
+static void
+htt_t2h_stats_rx_reorder_stats_print(struct rx_reorder_stats *stats_ptr,
+				     int concise)
+{
+	qdf_nofl_info("Rx reorder statistics:");
+	qdf_nofl_info("  %u non-QoS frames received",
+		      stats_ptr->deliver_non_qos);
+	qdf_nofl_info("  %u frames received in-order",
+		      stats_ptr->deliver_in_order);
+	qdf_nofl_info("  %u frames flushed due to timeout",
+		      stats_ptr->deliver_flush_timeout);
+	qdf_nofl_info("  %u frames flushed due to moving out of window",
+		      stats_ptr->deliver_flush_oow);
+	qdf_nofl_info("  %u frames flushed due to receiving DELBA",
+		      stats_ptr->deliver_flush_delba);
+	qdf_nofl_info("  %u frames discarded due to FCS error",
+		      stats_ptr->fcs_error);
+	qdf_nofl_info("  %u frames discarded due to invalid peer",
+		      stats_ptr->invalid_peer);
+	qdf_nofl_info
+		("  %u frames discarded due to duplication (non aggregation)",
+		 stats_ptr->dup_non_aggr);
+	qdf_nofl_info("  %u frames discarded due to duplication in reorder queue",
+		      stats_ptr->dup_in_reorder);
+	qdf_nofl_info("  %u frames discarded due to processed before",
+		      stats_ptr->dup_past);
+	qdf_nofl_info("  %u times reorder timeout happened",
+		      stats_ptr->reorder_timeout);
+	qdf_nofl_info("  %u times incorrect bar received",
+		      stats_ptr->invalid_bar_ssn);
+	qdf_nofl_info("  %u times bar ssn reset happened",
+		      stats_ptr->ssn_reset);
+	qdf_nofl_info("  %u times flushed due to peer delete",
+		      stats_ptr->deliver_flush_delpeer);
+	qdf_nofl_info("  %u times flushed due to offload",
+		      stats_ptr->deliver_flush_offload);
+	qdf_nofl_info("  %u times flushed due to ouf of buffer",
+		      stats_ptr->deliver_flush_oob);
+	qdf_nofl_info("  %u MPDU's dropped due to PN check fail",
+		      stats_ptr->pn_fail);
+	qdf_nofl_info("  %u MPDU's dropped due to lack of memory",
+		      stats_ptr->store_fail);
+	qdf_nofl_info("  %u times tid pool alloc succeeded",
+		      stats_ptr->tid_pool_alloc_succ);
+	qdf_nofl_info("  %u times MPDU pool alloc succeeded",
+		      stats_ptr->mpdu_pool_alloc_succ);
+	qdf_nofl_info("  %u times MSDU pool alloc succeeded",
+		      stats_ptr->msdu_pool_alloc_succ);
+	qdf_nofl_info("  %u times tid pool alloc failed",
+		      stats_ptr->tid_pool_alloc_fail);
+	qdf_nofl_info("  %u times MPDU pool alloc failed",
+		      stats_ptr->mpdu_pool_alloc_fail);
+	qdf_nofl_info("  %u times MSDU pool alloc failed",
+		      stats_ptr->msdu_pool_alloc_fail);
+	qdf_nofl_info("  %u times tid pool freed",
+		      stats_ptr->tid_pool_free);
+	qdf_nofl_info("  %u times MPDU pool freed",
+		      stats_ptr->mpdu_pool_free);
+	qdf_nofl_info("  %u times MSDU pool freed",
+		      stats_ptr->msdu_pool_free);
+	qdf_nofl_info("  %u MSDUs undelivered to HTT, queued to Rx MSDU free list",
+		      stats_ptr->msdu_queued);
+	qdf_nofl_info("  %u MSDUs released from Rx MSDU list to MAC ring",
+		      stats_ptr->msdu_recycled);
+	qdf_nofl_info("  %u MPDUs with invalid peer but A2 found in AST",
+		      stats_ptr->invalid_peer_a2_in_ast);
+	qdf_nofl_info("  %u MPDUs with invalid peer but A3 found in AST",
+		      stats_ptr->invalid_peer_a3_in_ast);
+	qdf_nofl_info("  %u MPDUs with invalid peer, Broadcast or Mulitcast frame",
+		      stats_ptr->invalid_peer_bmc_mpdus);
+	qdf_nofl_info("  %u MSDUs with err attention word",
+		      stats_ptr->rxdesc_err_att);
+	qdf_nofl_info("  %u MSDUs with flag of peer_idx_invalid",
+		      stats_ptr->rxdesc_err_peer_idx_inv);
+	qdf_nofl_info("  %u MSDUs with  flag of peer_idx_timeout",
+		      stats_ptr->rxdesc_err_peer_idx_to);
+	qdf_nofl_info("  %u MSDUs with  flag of overflow",
+		      stats_ptr->rxdesc_err_ov);
+	qdf_nofl_info("  %u MSDUs with  flag of msdu_length_err",
+		      stats_ptr->rxdesc_err_msdu_len);
+	qdf_nofl_info("  %u MSDUs with  flag of mpdu_length_err",
+		      stats_ptr->rxdesc_err_mpdu_len);
+	qdf_nofl_info("  %u MSDUs with  flag of tkip_mic_err",
+		      stats_ptr->rxdesc_err_tkip_mic);
+	qdf_nofl_info("  %u MSDUs with  flag of decrypt_err",
+		      stats_ptr->rxdesc_err_decrypt);
+	qdf_nofl_info("  %u MSDUs with  flag of fcs_err",
+		      stats_ptr->rxdesc_err_fcs);
+	qdf_nofl_info("  %u Unicast frames with invalid peer handler",
+		      stats_ptr->rxdesc_uc_msdus_inv_peer);
+	qdf_nofl_info("  %u unicast frame to DUT with invalid peer handler",
+		      stats_ptr->rxdesc_direct_msdus_inv_peer);
+	qdf_nofl_info("  %u Broadcast/Multicast frames with invalid peer handler",
+		      stats_ptr->rxdesc_bmc_msdus_inv_peer);
+	qdf_nofl_info("  %u MSDUs dropped due to no first MSDU flag",
+		      stats_ptr->rxdesc_no_1st_msdu);
+	qdf_nofl_info("  %u MSDUs dropped due to ring overflow",
+		      stats_ptr->msdu_drop_ring_ov);
+	qdf_nofl_info("  %u MSDUs dropped due to FC mismatch",
+		      stats_ptr->msdu_drop_fc_mismatch);
+	qdf_nofl_info("  %u MSDUs dropped due to mgt frame in Remote ring",
+		      stats_ptr->msdu_drop_mgmt_remote_ring);
+	qdf_nofl_info("  %u MSDUs dropped due to misc non error",
+		      stats_ptr->msdu_drop_misc);
+	qdf_nofl_info("  %u MSDUs go to offload before reorder",
+		      stats_ptr->offload_msdu_wal);
+	qdf_nofl_info("  %u data frame dropped by offload after reorder",
+		      stats_ptr->offload_msdu_reorder);
+	qdf_nofl_info("  %u  MPDUs with SN in the past & within BA window",
+		      stats_ptr->dup_past_within_window);
+	qdf_nofl_info("  %u  MPDUs with SN in the past & outside BA window",
+		      stats_ptr->dup_past_outside_window);
+}
+
+static void
+htt_t2h_stats_rx_rem_buf_stats_print(
+	struct rx_remote_buffer_mgmt_stats *stats_ptr, int concise)
+{
+	qdf_nofl_info("Rx Remote Buffer Statistics:");
+	qdf_nofl_info("  %u MSDU's reaped for Rx processing",
+		      stats_ptr->remote_reaped);
+	qdf_nofl_info("  %u MSDU's recycled within firmware",
+		      stats_ptr->remote_recycled);
+	qdf_nofl_info("  %u MSDU's stored by Data Rx",
+		      stats_ptr->data_rx_msdus_stored);
+	qdf_nofl_info("  %u HTT indications from WAL Rx MSDU",
+		      stats_ptr->wal_rx_ind);
+	qdf_nofl_info("  %u HTT indications unconsumed from WAL Rx MSDU",
+		      stats_ptr->wal_rx_ind_unconsumed);
+	qdf_nofl_info("  %u HTT indications from Data Rx MSDU",
+		      stats_ptr->data_rx_ind);
+	qdf_nofl_info("  %u HTT indications unconsumed from Data Rx MSDU",
+		      stats_ptr->data_rx_ind_unconsumed);
+	qdf_nofl_info("  %u HTT indications from ATHBUF",
+		      stats_ptr->athbuf_rx_ind);
+	qdf_nofl_info("  %u Remote buffers requested for refill",
+		      stats_ptr->refill_buf_req);
+	qdf_nofl_info("  %u Remote buffers filled by host",
+		      stats_ptr->refill_buf_rsp);
+	qdf_nofl_info("  %u times MAC has no buffers",
+		      stats_ptr->mac_no_bufs);
+	qdf_nofl_info("  %u times f/w write & read indices on MAC ring are equal",
+		      stats_ptr->fw_indices_equal);
+	qdf_nofl_info("  %u times f/w has no remote buffers to post to MAC",
+		      stats_ptr->host_no_bufs);
+}
+
+static void
+htt_t2h_stats_txbf_info_buf_stats_print(
+	struct wlan_dbg_txbf_data_stats *stats_ptr)
+{
+	qdf_nofl_info("TXBF data Statistics:");
+	qdf_nofl_info("tx_txbf_vht (0..9): %u, %u, %u, %u, %u, %u, %u, %u, %u, %d",
+		      stats_ptr->tx_txbf_vht[0],
+		      stats_ptr->tx_txbf_vht[1],
+		      stats_ptr->tx_txbf_vht[2],
+		      stats_ptr->tx_txbf_vht[3],
+		      stats_ptr->tx_txbf_vht[4],
+		      stats_ptr->tx_txbf_vht[5],
+		      stats_ptr->tx_txbf_vht[6],
+		      stats_ptr->tx_txbf_vht[7],
+		      stats_ptr->tx_txbf_vht[8],
+		      stats_ptr->tx_txbf_vht[9]);
+	qdf_nofl_info("rx_txbf_vht (0..9): %u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
+		      stats_ptr->rx_txbf_vht[0],
+		      stats_ptr->rx_txbf_vht[1],
+		      stats_ptr->rx_txbf_vht[2],
+		      stats_ptr->rx_txbf_vht[3],
+		      stats_ptr->rx_txbf_vht[4],
+		      stats_ptr->rx_txbf_vht[5],
+		      stats_ptr->rx_txbf_vht[6],
+		      stats_ptr->rx_txbf_vht[7],
+		      stats_ptr->rx_txbf_vht[8],
+		      stats_ptr->rx_txbf_vht[9]);
+	qdf_nofl_info("tx_txbf_ht (0..7): %u, %u, %u, %u, %u, %u, %u, %u",
+		      stats_ptr->tx_txbf_ht[0],
+		      stats_ptr->tx_txbf_ht[1],
+		      stats_ptr->tx_txbf_ht[2],
+		      stats_ptr->tx_txbf_ht[3],
+		      stats_ptr->tx_txbf_ht[4],
+		      stats_ptr->tx_txbf_ht[5],
+		      stats_ptr->tx_txbf_ht[6],
+		      stats_ptr->tx_txbf_ht[7]);
+	qdf_nofl_info("tx_txbf_ofdm (0..7): %u, %u, %u, %u, %u, %u, %u, %u",
+		      stats_ptr->tx_txbf_ofdm[0],
+		      stats_ptr->tx_txbf_ofdm[1],
+		      stats_ptr->tx_txbf_ofdm[2],
+		      stats_ptr->tx_txbf_ofdm[3],
+		      stats_ptr->tx_txbf_ofdm[4],
+		      stats_ptr->tx_txbf_ofdm[5],
+		      stats_ptr->tx_txbf_ofdm[6],
+		      stats_ptr->tx_txbf_ofdm[7]);
+	qdf_nofl_info("tx_txbf_cck (0..6): %u, %u, %u, %u, %u, %u, %u",
+		      stats_ptr->tx_txbf_cck[0],
+		      stats_ptr->tx_txbf_cck[1],
+		      stats_ptr->tx_txbf_cck[2],
+		      stats_ptr->tx_txbf_cck[3],
+		      stats_ptr->tx_txbf_cck[4],
+		      stats_ptr->tx_txbf_cck[5],
+		      stats_ptr->tx_txbf_cck[6]);
+}
+
+static void
+htt_t2h_stats_txbf_snd_buf_stats_print(
+	struct wlan_dbg_txbf_snd_stats *stats_ptr)
+{
+	qdf_nofl_info("TXBF snd Buffer Statistics:");
+	qdf_nofl_info("cbf_20: %u, %u, %u, %u",
+		      stats_ptr->cbf_20[0],
+		      stats_ptr->cbf_20[1],
+		      stats_ptr->cbf_20[2],
+		      stats_ptr->cbf_20[3]);
+	qdf_nofl_info("cbf_40: %u, %u, %u, %u",
+		      stats_ptr->cbf_40[0],
+		      stats_ptr->cbf_40[1],
+		      stats_ptr->cbf_40[2],
+		      stats_ptr->cbf_40[3]);
+	qdf_nofl_info("cbf_80: %u, %u, %u, %u",
+		      stats_ptr->cbf_80[0],
+		      stats_ptr->cbf_80[1],
+		      stats_ptr->cbf_80[2],
+		      stats_ptr->cbf_80[3]);
+	qdf_nofl_info("sounding: %u, %u, %u, %u, %u, %u, %u, %u, %u",
+		      stats_ptr->sounding[0],
+		      stats_ptr->sounding[1],
+		      stats_ptr->sounding[2],
+		      stats_ptr->sounding[3],
+		      stats_ptr->sounding[4],
+		      stats_ptr->sounding[5],
+		      stats_ptr->sounding[6],
+		      stats_ptr->sounding[7],
+		      stats_ptr->sounding[8]);
+}
+
+static void
+htt_t2h_stats_tx_selfgen_buf_stats_print(
+	struct wlan_dbg_tx_selfgen_stats *stats_ptr)
+{
+	qdf_nofl_info("Tx selfgen Buffer Statistics:");
+	qdf_nofl_info("  %u su_ndpa",
+		      stats_ptr->su_ndpa);
+	qdf_nofl_info("  %u mu_ndp",
+		      stats_ptr->mu_ndp);
+	qdf_nofl_info("  %u mu_ndpa",
+		      stats_ptr->mu_ndpa);
+	qdf_nofl_info("  %u mu_ndp",
+		      stats_ptr->mu_ndp);
+	qdf_nofl_info("  %u mu_brpoll_1",
+		      stats_ptr->mu_brpoll_1);
+	qdf_nofl_info("  %u mu_brpoll_2",
+		      stats_ptr->mu_brpoll_2);
+	qdf_nofl_info("  %u mu_bar_1",
+		      stats_ptr->mu_bar_1);
+	qdf_nofl_info("  %u mu_bar_2",
+		      stats_ptr->mu_bar_2);
+	qdf_nofl_info("  %u cts_burst",
+		      stats_ptr->cts_burst);
+	qdf_nofl_info("  %u su_ndp_err",
+		      stats_ptr->su_ndp_err);
+	qdf_nofl_info("  %u su_ndpa_err",
+		      stats_ptr->su_ndpa_err);
+	qdf_nofl_info("  %u mu_ndp_err",
+		      stats_ptr->mu_ndp_err);
+	qdf_nofl_info("  %u mu_brp1_err",
+		      stats_ptr->mu_brp1_err);
+	qdf_nofl_info("  %u mu_brp2_err",
+		      stats_ptr->mu_brp2_err);
+}
+
+static void
+htt_t2h_stats_wifi2_error_stats_print(
+	struct wlan_dbg_wifi2_error_stats *stats_ptr)
+{
+	int i;
+
+	qdf_nofl_info("Scheduler error Statistics:");
+	qdf_nofl_info("urrn_stats: ");
+	qdf_nofl_info("urrn_stats: %d, %d, %d",
+		      stats_ptr->urrn_stats[0],
+		      stats_ptr->urrn_stats[1],
+		      stats_ptr->urrn_stats[2]);
+	qdf_nofl_info("flush_errs (0..%d): ",
+		      WHAL_DBG_FLUSH_REASON_MAXCNT);
+	for (i = 0; i < WHAL_DBG_FLUSH_REASON_MAXCNT; i++)
+		qdf_nofl_info("  %u", stats_ptr->flush_errs[i]);
+	qdf_nofl_info("\n");
+	qdf_nofl_info("schd_stall_errs (0..3): ");
+	qdf_nofl_info("%d, %d, %d, %d",
+		      stats_ptr->schd_stall_errs[0],
+		      stats_ptr->schd_stall_errs[1],
+		      stats_ptr->schd_stall_errs[2],
+		      stats_ptr->schd_stall_errs[3]);
+	qdf_nofl_info("schd_cmd_result (0..%d): ",
+		      WHAL_DBG_CMD_RESULT_MAXCNT);
+	for (i = 0; i < WHAL_DBG_CMD_RESULT_MAXCNT; i++)
+		qdf_nofl_info("  %u", stats_ptr->schd_cmd_result[i]);
+	qdf_nofl_info("\n");
+	qdf_nofl_info("sifs_status (0..%d): ",
+		      WHAL_DBG_SIFS_STATUS_MAXCNT);
+	for (i = 0; i < WHAL_DBG_SIFS_STATUS_MAXCNT; i++)
+		qdf_nofl_info("  %u", stats_ptr->sifs_status[i]);
+	qdf_nofl_info("\n");
+	qdf_nofl_info("phy_errs (0..%d): ",
+		      WHAL_DBG_PHY_ERR_MAXCNT);
+	for (i = 0; i < WHAL_DBG_PHY_ERR_MAXCNT; i++)
+		qdf_nofl_info("  %u", stats_ptr->phy_errs[i]);
+	qdf_nofl_info("\n");
+	qdf_nofl_info("  %u rx_rate_inval",
+		      stats_ptr->rx_rate_inval);
+}
+
+static void
+htt_t2h_rx_musu_ndpa_pkts_stats_print(
+	struct rx_txbf_musu_ndpa_pkts_stats *stats_ptr)
+{
+	qdf_nofl_info("Rx TXBF MU/SU Packets and NDPA Statistics:");
+	qdf_nofl_info("  %u Number of TXBF MU packets received",
+		      stats_ptr->number_mu_pkts);
+	qdf_nofl_info("  %u Number of TXBF SU packets received",
+		      stats_ptr->number_su_pkts);
+	qdf_nofl_info("  %u Number of TXBF directed NDPA",
+		      stats_ptr->txbf_directed_ndpa_count);
+	qdf_nofl_info("  %u Number of TXBF retried NDPA",
+		      stats_ptr->txbf_ndpa_retry_count);
+	qdf_nofl_info("  %u Total number of TXBF NDPA",
+		      stats_ptr->txbf_total_ndpa_count);
+}
+
+#define HTT_TICK_TO_USEC(ticks, microsec_per_tick) (ticks * microsec_per_tick)
+static inline int htt_rate_flags_to_mhz(uint8_t rate_flags)
+{
+	if (rate_flags & 0x20)
+		return 40;      /* WHAL_RC_FLAG_40MHZ */
+	if (rate_flags & 0x40)
+		return 80;      /* WHAL_RC_FLAG_80MHZ */
+	if (rate_flags & 0x80)
+		return 160;     /* WHAL_RC_FLAG_160MHZ */
+	return 20;
+}
+
+#define HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW 64
+
+static void
+htt_t2h_tx_ppdu_bitmaps_pr(uint32_t *queued_ptr, uint32_t *acked_ptr)
+{
+	char queued_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW + 1];
+	char acked_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW + 1];
+	int i, j, word;
+
+	qdf_mem_set(queued_str, HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW, '0');
+	qdf_mem_set(acked_str, HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW, '-');
+	i = 0;
+	for (word = 0; word < 2; word++) {
+		uint32_t queued = *(queued_ptr + word);
+		uint32_t acked = *(acked_ptr + word);
+
+		for (j = 0; j < 32; j++, i++) {
+			if (queued & (1 << j)) {
+				queued_str[i] = '1';
+				acked_str[i] = (acked & (1 << j)) ? 'y' : 'N';
+			}
+		}
+	}
+	queued_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW] = '\0';
+	acked_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW] = '\0';
+	qdf_nofl_info("%s\n", queued_str);
+	qdf_nofl_info("%s\n", acked_str);
+}
+
+static inline uint16_t htt_msg_read16(uint16_t *p16)
+{
+#ifdef BIG_ENDIAN_HOST
+	/*
+	 * During upload, the bytes within each uint32_t word were
+	 * swapped by the HIF HW.  This results in the lower and upper bytes
+	 * of each uint16_t to be in the correct big-endian order with
+	 * respect to each other, but for each even-index uint16_t to
+	 * have its position switched with its successor neighbor uint16_t.
+	 * Undo this uint16_t position swapping.
+	 */
+	return (((size_t) p16) & 0x2) ? *(p16 - 1) : *(p16 + 1);
+#else
+	return *p16;
+#endif
+}
+
+static inline uint8_t htt_msg_read8(uint8_t *p8)
+{
+#ifdef BIG_ENDIAN_HOST
+	/*
+	 * During upload, the bytes within each uint32_t word were
+	 * swapped by the HIF HW.
+	 * Undo this byte swapping.
+	 */
+	switch (((size_t) p8) & 0x3) {
+	case 0:
+		return *(p8 + 3);
+	case 1:
+		return *(p8 + 1);
+	case 2:
+		return *(p8 - 1);
+	default /* 3 */:
+		return *(p8 - 3);
+	}
+#else
+	return *p8;
+#endif
+}
+
+static void htt_make_u8_list_str(uint32_t *aligned_data,
+				 char *buffer, int space, int max_elems)
+{
+	uint8_t *p8 = (uint8_t *) aligned_data;
+	char *buf_p = buffer;
+
+	while (max_elems-- > 0) {
+		int bytes;
+		uint8_t val;
+
+		val = htt_msg_read8(p8);
+		if (val == 0)
+			/* not enough data to fill the reserved msg buffer*/
+			break;
+
+		bytes = qdf_snprint(buf_p, space, "%d,", val);
+		space -= bytes;
+		if (space > 0)
+			buf_p += bytes;
+		else /* not enough print buffer space for all the data */
+			break;
+		p8++;
+	}
+	if (buf_p == buffer)
+		*buf_p = '\0';        /* nothing was written */
+	else
+		*(buf_p - 1) = '\0';  /* erase the final comma */
+
+}
+
+static void htt_make_u16_list_str(uint32_t *aligned_data,
+				  char *buffer, int space, int max_elems)
+{
+	uint16_t *p16 = (uint16_t *) aligned_data;
+	char *buf_p = buffer;
+
+	while (max_elems-- > 0) {
+		int bytes;
+		uint16_t val;
+
+		val = htt_msg_read16(p16);
+		if (val == 0)
+			/* not enough data to fill the reserved msg buffer */
+			break;
+		bytes = qdf_snprint(buf_p, space, "%d,", val);
+		space -= bytes;
+		if (space > 0)
+			buf_p += bytes;
+		else /* not enough print buffer space for all the data */
+			break;
+
+		p16++;
+	}
+	if (buf_p == buffer)
+		*buf_p = '\0';  /* nothing was written */
+	else
+		*(buf_p - 1) = '\0';    /* erase the final comma */
+}
+
+static void
+htt_t2h_tx_ppdu_log_print(struct ol_fw_tx_dbg_ppdu_msg_hdr *hdr,
+			  struct ol_fw_tx_dbg_ppdu_base *record,
+			  int length, int concise)
+{
+	int i;
+	int record_size;
+	int calculated_record_size;
+	int num_records;
+
+	record_size = sizeof(*record);
+	calculated_record_size = record_size +
+				hdr->mpdu_bytes_array_len * sizeof(uint16_t);
+	if (calculated_record_size < record_size) {
+		qdf_err("Overflow due to record and hdr->mpdu_bytes_array_len %u",
+			hdr->mpdu_bytes_array_len);
+		return;
+	}
+	record_size = calculated_record_size;
+	calculated_record_size += hdr->mpdu_msdus_array_len * sizeof(uint8_t);
+	if (calculated_record_size < record_size) {
+		qdf_err("Overflow due to hdr->mpdu_msdus_array_len %u",
+			hdr->mpdu_msdus_array_len);
+		return;
+	}
+	record_size = calculated_record_size;
+	calculated_record_size += hdr->msdu_bytes_array_len * sizeof(uint16_t);
+	if (calculated_record_size < record_size) {
+		qdf_err("Overflow due to hdr->msdu_bytes_array_len %u",
+			hdr->msdu_bytes_array_len);
+		return;
+	}
+	record_size = calculated_record_size;
+	num_records = (length - sizeof(*hdr)) / record_size;
+	if (num_records < 0) {
+		qdf_err("Underflow due to length %d", length);
+		return;
+	}
+	qdf_nofl_info("Tx PPDU log elements: num_records %d", num_records);
+
+	for (i = 0; i < num_records; i++) {
+		uint16_t start_seq_num;
+		uint16_t start_pn_lsbs;
+		uint8_t num_mpdus;
+		uint16_t peer_id;
+		uint8_t ext_tid;
+		uint8_t rate_code;
+		uint8_t rate_flags;
+		uint8_t tries;
+		uint8_t complete;
+		uint32_t time_enqueue_us;
+		uint32_t time_completion_us;
+		uint32_t *msg_word = (uint32_t *) record;
+
+		/* fields used for both concise and complete printouts */
+		start_seq_num =
+			((*(msg_word + OL_FW_TX_DBG_PPDU_START_SEQ_NUM_WORD)) &
+			 OL_FW_TX_DBG_PPDU_START_SEQ_NUM_M) >>
+			OL_FW_TX_DBG_PPDU_START_SEQ_NUM_S;
+		complete =
+			((*(msg_word + OL_FW_TX_DBG_PPDU_COMPLETE_WORD)) &
+			 OL_FW_TX_DBG_PPDU_COMPLETE_M) >>
+			OL_FW_TX_DBG_PPDU_COMPLETE_S;
+
+		/* fields used only for complete printouts */
+		if (!concise) {
+#define BUF_SIZE 80
+			char buf[BUF_SIZE];
+			uint8_t *p8;
+			uint8_t *calculated_p8;
+
+			time_enqueue_us =
+				HTT_TICK_TO_USEC(record->timestamp_enqueue,
+						 hdr->microsec_per_tick);
+			time_completion_us =
+				HTT_TICK_TO_USEC(record->timestamp_completion,
+						 hdr->microsec_per_tick);
+
+			start_pn_lsbs =
+				((*(msg_word +
+				OL_FW_TX_DBG_PPDU_START_PN_LSBS_WORD)) &
+				OL_FW_TX_DBG_PPDU_START_PN_LSBS_M) >>
+				OL_FW_TX_DBG_PPDU_START_PN_LSBS_S;
+			num_mpdus =
+				((*(msg_word +
+				OL_FW_TX_DBG_PPDU_NUM_MPDUS_WORD))&
+				OL_FW_TX_DBG_PPDU_NUM_MPDUS_M) >>
+				OL_FW_TX_DBG_PPDU_NUM_MPDUS_S;
+			peer_id =
+				((*(msg_word +
+				OL_FW_TX_DBG_PPDU_PEER_ID_WORD)) &
+				OL_FW_TX_DBG_PPDU_PEER_ID_M) >>
+				OL_FW_TX_DBG_PPDU_PEER_ID_S;
+			ext_tid =
+				((*(msg_word +
+				OL_FW_TX_DBG_PPDU_EXT_TID_WORD)) &
+				OL_FW_TX_DBG_PPDU_EXT_TID_M) >>
+				OL_FW_TX_DBG_PPDU_EXT_TID_S;
+			rate_code =
+				((*(msg_word +
+				OL_FW_TX_DBG_PPDU_RATE_CODE_WORD))&
+				OL_FW_TX_DBG_PPDU_RATE_CODE_M) >>
+				OL_FW_TX_DBG_PPDU_RATE_CODE_S;
+			rate_flags =
+				((*(msg_word +
+				OL_FW_TX_DBG_PPDU_RATE_FLAGS_WORD))&
+				OL_FW_TX_DBG_PPDU_RATE_FLAGS_M) >>
+				OL_FW_TX_DBG_PPDU_RATE_FLAGS_S;
+			tries =
+				((*(msg_word +
+				OL_FW_TX_DBG_PPDU_TRIES_WORD)) &
+				OL_FW_TX_DBG_PPDU_TRIES_M) >>
+				OL_FW_TX_DBG_PPDU_TRIES_S;
+
+			qdf_nofl_info(" - PPDU tx to peer %d, TID %d", peer_id,
+				      ext_tid);
+			qdf_nofl_info("   start seq num= %u, start PN LSBs= %#04x",
+				      start_seq_num, start_pn_lsbs);
+			qdf_nofl_info("   PPDU: %d MPDUs, (?) MSDUs, %d bytes",
+				      num_mpdus,
+				      /* num_msdus-not yet computed in target */
+				      record->num_bytes);
+			if (complete) {
+				qdf_nofl_info("   enqueued: %u, completed: %u usec)",
+					      time_enqueue_us,
+					      time_completion_us);
+				qdf_nofl_info("   %d tries, last tx used rate %d ",
+					      tries, rate_code);
+				qdf_nofl_info("on %d MHz chan (flags = %#x)",
+					      htt_rate_flags_to_mhz
+					      (rate_flags), rate_flags);
+				qdf_nofl_info("  enqueued and acked MPDU bitmaps:");
+				htt_t2h_tx_ppdu_bitmaps_pr(msg_word +
+					OL_FW_TX_DBG_PPDU_ENQUEUED_LSBS_WORD,
+					msg_word +
+					OL_FW_TX_DBG_PPDU_BLOCK_ACK_LSBS_WORD);
+			} else {
+				qdf_nofl_info("  enqueued: %d us, not yet completed",
+					      time_enqueue_us);
+			}
+			/* skip the regular msg fields to reach the tail area */
+			p8 = (uint8_t *) record;
+			calculated_p8 = p8 + sizeof(struct ol_fw_tx_dbg_ppdu_base);
+			if (calculated_p8 < p8) {
+				qdf_err("Overflow due to record %pK", p8);
+				continue;
+			}
+			p8 = calculated_p8;
+			if (hdr->mpdu_bytes_array_len) {
+				htt_make_u16_list_str((uint32_t *) p8, buf,
+						      BUF_SIZE,
+						      hdr->
+						      mpdu_bytes_array_len);
+				qdf_nofl_info("   MPDU bytes: %s", buf);
+			}
+			calculated_p8 += hdr->mpdu_bytes_array_len * sizeof(uint16_t);
+			if (calculated_p8 < p8) {
+				qdf_err("Overflow due to hdr->mpdu_bytes_array_len %u",
+					hdr->mpdu_bytes_array_len);
+				continue;
+			}
+			p8 = calculated_p8;
+			if (hdr->mpdu_msdus_array_len) {
+				htt_make_u8_list_str((uint32_t *) p8, buf,
+						     BUF_SIZE,
+						     hdr->mpdu_msdus_array_len);
+				qdf_nofl_info("   MPDU MSDUs: %s", buf);
+			}
+			calculated_p8 += hdr->mpdu_msdus_array_len * sizeof(uint8_t);
+			if (calculated_p8 < p8) {
+				qdf_err("Overflow due to hdr->mpdu_msdus_array_len %u",
+					hdr->mpdu_msdus_array_len);
+				continue;
+			}
+			p8 = calculated_p8;
+			if (hdr->msdu_bytes_array_len) {
+				htt_make_u16_list_str((uint32_t *) p8, buf,
+						      BUF_SIZE,
+						      hdr->
+						      msdu_bytes_array_len);
+				qdf_nofl_info("   MSDU bytes: %s", buf);
+			}
+		} else {
+			/* concise */
+			qdf_nofl_info("start seq num = %u ", start_seq_num);
+			qdf_nofl_info("enqueued and acked MPDU bitmaps:");
+			if (complete) {
+				htt_t2h_tx_ppdu_bitmaps_pr(msg_word +
+					OL_FW_TX_DBG_PPDU_ENQUEUED_LSBS_WORD,
+							   msg_word +
+					OL_FW_TX_DBG_PPDU_BLOCK_ACK_LSBS_WORD);
+			} else {
+				qdf_nofl_info("(not completed)");
+			}
+		}
+		record = (struct ol_fw_tx_dbg_ppdu_base *)
+			 (((uint8_t *) record) + record_size);
+	}
+}
+
+static void htt_t2h_stats_tidq_stats_print(
+	struct wlan_dbg_tidq_stats *tidq_stats, int concise)
+{
+	qdf_nofl_info("TID QUEUE STATS:");
+	qdf_nofl_info("tid_txq_stats: %u", tidq_stats->wlan_dbg_tid_txq_status);
+	qdf_nofl_info("num_pkts_queued(0..9):");
+	qdf_nofl_info("%u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
+		      tidq_stats->txq_st.num_pkts_queued[0],
+		      tidq_stats->txq_st.num_pkts_queued[1],
+		      tidq_stats->txq_st.num_pkts_queued[2],
+		      tidq_stats->txq_st.num_pkts_queued[3],
+		      tidq_stats->txq_st.num_pkts_queued[4],
+		      tidq_stats->txq_st.num_pkts_queued[5],
+		      tidq_stats->txq_st.num_pkts_queued[6],
+		      tidq_stats->txq_st.num_pkts_queued[7],
+		      tidq_stats->txq_st.num_pkts_queued[8],
+		      tidq_stats->txq_st.num_pkts_queued[9]);
+	qdf_nofl_info("tid_hw_qdepth(0..19):");
+	qdf_nofl_info("%u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
+		      tidq_stats->txq_st.tid_hw_qdepth[0],
+		      tidq_stats->txq_st.tid_hw_qdepth[1],
+		      tidq_stats->txq_st.tid_hw_qdepth[2],
+		      tidq_stats->txq_st.tid_hw_qdepth[3],
+		      tidq_stats->txq_st.tid_hw_qdepth[4],
+		      tidq_stats->txq_st.tid_hw_qdepth[5],
+		      tidq_stats->txq_st.tid_hw_qdepth[6],
+		      tidq_stats->txq_st.tid_hw_qdepth[7],
+		      tidq_stats->txq_st.tid_hw_qdepth[8],
+		      tidq_stats->txq_st.tid_hw_qdepth[9]);
+	qdf_nofl_info("%u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
+		      tidq_stats->txq_st.tid_hw_qdepth[10],
+		      tidq_stats->txq_st.tid_hw_qdepth[11],
+		      tidq_stats->txq_st.tid_hw_qdepth[12],
+		      tidq_stats->txq_st.tid_hw_qdepth[13],
+		      tidq_stats->txq_st.tid_hw_qdepth[14],
+		      tidq_stats->txq_st.tid_hw_qdepth[15],
+		      tidq_stats->txq_st.tid_hw_qdepth[16],
+		      tidq_stats->txq_st.tid_hw_qdepth[17],
+		      tidq_stats->txq_st.tid_hw_qdepth[18],
+		      tidq_stats->txq_st.tid_hw_qdepth[19]);
+	qdf_nofl_info("tid_sw_qdepth(0..19):");
+	qdf_nofl_info("%u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
+		      tidq_stats->txq_st.tid_sw_qdepth[0],
+		      tidq_stats->txq_st.tid_sw_qdepth[1],
+		      tidq_stats->txq_st.tid_sw_qdepth[2],
+		      tidq_stats->txq_st.tid_sw_qdepth[3],
+		      tidq_stats->txq_st.tid_sw_qdepth[4],
+		      tidq_stats->txq_st.tid_sw_qdepth[5],
+		      tidq_stats->txq_st.tid_sw_qdepth[6],
+		      tidq_stats->txq_st.tid_sw_qdepth[7],
+		      tidq_stats->txq_st.tid_sw_qdepth[8],
+		      tidq_stats->txq_st.tid_sw_qdepth[9]);
+	qdf_nofl_info("%u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
+		      tidq_stats->txq_st.tid_sw_qdepth[10],
+		      tidq_stats->txq_st.tid_sw_qdepth[11],
+		      tidq_stats->txq_st.tid_sw_qdepth[12],
+		      tidq_stats->txq_st.tid_sw_qdepth[13],
+		      tidq_stats->txq_st.tid_sw_qdepth[14],
+		      tidq_stats->txq_st.tid_sw_qdepth[15],
+		      tidq_stats->txq_st.tid_sw_qdepth[16],
+		      tidq_stats->txq_st.tid_sw_qdepth[17],
+		      tidq_stats->txq_st.tid_sw_qdepth[18],
+		      tidq_stats->txq_st.tid_sw_qdepth[19]);
+}
+
+static void htt_t2h_stats_tx_mu_stats_print(
+	struct wlan_dbg_tx_mu_stats *tx_mu_stats, int concise)
+{
+	qdf_nofl_info("TX MU STATS:");
+	qdf_nofl_info("mu_sch_nusers_2: %u", tx_mu_stats->mu_sch_nusers_2);
+	qdf_nofl_info("mu_sch_nusers_3: %u", tx_mu_stats->mu_sch_nusers_3);
+	qdf_nofl_info("mu_mpdus_queued_usr: %u, %u, %u, %u",
+		      tx_mu_stats->mu_mpdus_queued_usr[0],
+		      tx_mu_stats->mu_mpdus_queued_usr[1],
+		      tx_mu_stats->mu_mpdus_queued_usr[2],
+		      tx_mu_stats->mu_mpdus_queued_usr[3]);
+	qdf_nofl_info("mu_mpdus_tried_usr: %u, %u, %u, %u",
+		      tx_mu_stats->mu_mpdus_tried_usr[0],
+		      tx_mu_stats->mu_mpdus_tried_usr[1],
+		      tx_mu_stats->mu_mpdus_tried_usr[2],
+		      tx_mu_stats->mu_mpdus_tried_usr[3]);
+	qdf_nofl_info("mu_mpdus_failed_usr: %u, %u, %u, %u",
+		      tx_mu_stats->mu_mpdus_failed_usr[0],
+		      tx_mu_stats->mu_mpdus_failed_usr[1],
+		      tx_mu_stats->mu_mpdus_failed_usr[2],
+		      tx_mu_stats->mu_mpdus_failed_usr[3]);
+	qdf_nofl_info("mu_mpdus_requeued_usr: %u, %u, %u, %u",
+		      tx_mu_stats->mu_mpdus_requeued_usr[0],
+		      tx_mu_stats->mu_mpdus_requeued_usr[1],
+		      tx_mu_stats->mu_mpdus_requeued_usr[2],
+		      tx_mu_stats->mu_mpdus_requeued_usr[3]);
+	qdf_nofl_info("mu_err_no_ba_usr: %u, %u, %u, %u",
+		      tx_mu_stats->mu_err_no_ba_usr[0],
+		      tx_mu_stats->mu_err_no_ba_usr[1],
+		      tx_mu_stats->mu_err_no_ba_usr[2],
+		      tx_mu_stats->mu_err_no_ba_usr[3]);
+	qdf_nofl_info("mu_mpdu_underrun_usr: %u, %u, %u, %u",
+		      tx_mu_stats->mu_mpdu_underrun_usr[0],
+		      tx_mu_stats->mu_mpdu_underrun_usr[1],
+		      tx_mu_stats->mu_mpdu_underrun_usr[2],
+		      tx_mu_stats->mu_mpdu_underrun_usr[3]);
+	qdf_nofl_info("mu_ampdu_underrun_usr: %u, %u, %u, %u",
+		      tx_mu_stats->mu_ampdu_underrun_usr[0],
+		      tx_mu_stats->mu_ampdu_underrun_usr[1],
+		      tx_mu_stats->mu_ampdu_underrun_usr[2],
+		      tx_mu_stats->mu_ampdu_underrun_usr[3]);
+
+}
+
+static void htt_t2h_stats_sifs_resp_stats_print(
+	struct wlan_dbg_sifs_resp_stats *sifs_stats, int concise)
+{
+	qdf_nofl_info("SIFS RESP STATS:");
+	qdf_nofl_info("num of ps-poll trigger frames: %u",
+		      sifs_stats->ps_poll_trigger);
+	qdf_nofl_info("num of uapsd trigger frames: %u",
+		      sifs_stats->uapsd_trigger);
+	qdf_nofl_info("num of data trigger frames: %u, %u",
+		      sifs_stats->qb_data_trigger[0],
+		      sifs_stats->qb_data_trigger[1]);
+	qdf_nofl_info("num of bar trigger frames: %u, %u",
+		      sifs_stats->qb_bar_trigger[0],
+		      sifs_stats->qb_bar_trigger[1]);
+	qdf_nofl_info("num of ppdu transmitted at SIFS interval: %u",
+		      sifs_stats->sifs_resp_data);
+	qdf_nofl_info("num of ppdu failed to meet SIFS resp timing: %u",
+		      sifs_stats->sifs_resp_err);
+}
+
+void htt_t2h_stats_print(uint8_t *stats_data, int concise)
+{
+	uint32_t *msg_word = (uint32_t *) stats_data;
+	enum htt_dbg_stats_type type;
+	enum htt_dbg_stats_status status;
+	int length;
+
+	type = HTT_T2H_STATS_CONF_TLV_TYPE_GET(*msg_word);
+	status = HTT_T2H_STATS_CONF_TLV_STATUS_GET(*msg_word);
+	length = HTT_T2H_STATS_CONF_TLV_LENGTH_GET(*msg_word);
+
+	/* check that we've been given a valid stats type */
+	if (status == HTT_DBG_STATS_STATUS_SERIES_DONE) {
+		return;
+	} else if (status == HTT_DBG_STATS_STATUS_INVALID) {
+		qdf_debug("Target doesn't support stats type %d", type);
+		return;
+	} else if (status == HTT_DBG_STATS_STATUS_ERROR) {
+		qdf_debug("Target couldn't upload stats type %d (no mem?)",
+			  type);
+		return;
+	}
+	/* got valid (though perhaps partial) stats - process them */
+	switch (type) {
+	case HTT_DBG_STATS_WAL_PDEV_TXRX:
+	{
+		struct wlan_dbg_stats *wlan_dbg_stats_ptr;
+
+		wlan_dbg_stats_ptr =
+			(struct wlan_dbg_stats *)(msg_word + 1);
+		htt_t2h_stats_pdev_stats_print(wlan_dbg_stats_ptr,
+					       concise);
+		break;
+	}
+	case HTT_DBG_STATS_RX_REORDER:
+	{
+		struct rx_reorder_stats *rx_reorder_stats_ptr;
+
+		rx_reorder_stats_ptr =
+			(struct rx_reorder_stats *)(msg_word + 1);
+		htt_t2h_stats_rx_reorder_stats_print
+			(rx_reorder_stats_ptr, concise);
+		break;
+	}
+
+	case HTT_DBG_STATS_RX_RATE_INFO:
+	{
+		wlan_dbg_rx_rate_info_t *rx_phy_info;
+
+		rx_phy_info = (wlan_dbg_rx_rate_info_t *) (msg_word + 1);
+		htt_t2h_stats_rx_rate_stats_print(rx_phy_info, concise);
+		break;
+	}
+	case HTT_DBG_STATS_RX_RATE_INFO_V2:
+	{
+		wlan_dbg_rx_rate_info_v2_t *rx_phy_info;
+
+		rx_phy_info = (wlan_dbg_rx_rate_info_v2_t *) (msg_word + 1);
+		htt_t2h_stats_rx_rate_stats_print_v2(rx_phy_info, concise);
+		break;
+	}
+	case HTT_DBG_STATS_TX_PPDU_LOG:
+	{
+		struct ol_fw_tx_dbg_ppdu_msg_hdr *hdr;
+		struct ol_fw_tx_dbg_ppdu_base *record;
+
+		if (status == HTT_DBG_STATS_STATUS_PARTIAL
+		    && length == 0) {
+			qdf_debug("HTT_DBG_STATS_TX_PPDU_LOG -- length = 0!");
+			break;
+		}
+		hdr = (struct ol_fw_tx_dbg_ppdu_msg_hdr *)(msg_word + 1);
+		record = (struct ol_fw_tx_dbg_ppdu_base *)(hdr + 1);
+		htt_t2h_tx_ppdu_log_print(hdr, record, length, concise);
+	}
+	break;
+	case HTT_DBG_STATS_TX_RATE_INFO:
+	{
+		wlan_dbg_tx_rate_info_t *tx_rate_info;
+
+		tx_rate_info = (wlan_dbg_tx_rate_info_t *) (msg_word + 1);
+		htt_t2h_stats_tx_rate_stats_print(tx_rate_info, concise);
+		break;
+	}
+	case HTT_DBG_STATS_TX_RATE_INFO_V2:
+	{
+		wlan_dbg_tx_rate_info_v2_t *tx_rate_info;
+
+		tx_rate_info = (wlan_dbg_tx_rate_info_v2_t *) (msg_word + 1);
+		htt_t2h_stats_tx_rate_stats_print_v2(tx_rate_info, concise);
+		break;
+	}
+	case HTT_DBG_STATS_RX_REMOTE_RING_BUFFER_INFO:
+	{
+		struct rx_remote_buffer_mgmt_stats *rx_rem_buf;
+
+		rx_rem_buf =
+			(struct rx_remote_buffer_mgmt_stats *)(msg_word + 1);
+		htt_t2h_stats_rx_rem_buf_stats_print(rx_rem_buf, concise);
+		break;
+	}
+	case HTT_DBG_STATS_TXBF_INFO:
+	{
+		struct wlan_dbg_txbf_data_stats *txbf_info_buf;
+
+		txbf_info_buf =
+			(struct wlan_dbg_txbf_data_stats *)(msg_word + 1);
+		htt_t2h_stats_txbf_info_buf_stats_print(txbf_info_buf);
+		break;
+	}
+	case HTT_DBG_STATS_SND_INFO:
+	{
+		struct wlan_dbg_txbf_snd_stats *txbf_snd_buf;
+
+		txbf_snd_buf = (struct wlan_dbg_txbf_snd_stats *)(msg_word + 1);
+		htt_t2h_stats_txbf_snd_buf_stats_print(txbf_snd_buf);
+		break;
+	}
+	case HTT_DBG_STATS_TX_SELFGEN_INFO:
+	{
+		struct wlan_dbg_tx_selfgen_stats  *tx_selfgen_buf;
+
+		tx_selfgen_buf =
+			(struct wlan_dbg_tx_selfgen_stats  *)(msg_word + 1);
+		htt_t2h_stats_tx_selfgen_buf_stats_print(tx_selfgen_buf);
+		break;
+	}
+	case HTT_DBG_STATS_ERROR_INFO:
+	{
+		struct wlan_dbg_wifi2_error_stats  *wifi2_error_buf;
+
+		wifi2_error_buf =
+			(struct wlan_dbg_wifi2_error_stats  *)(msg_word + 1);
+		htt_t2h_stats_wifi2_error_stats_print(wifi2_error_buf);
+		break;
+	}
+	case HTT_DBG_STATS_TXBF_MUSU_NDPA_PKT:
+	{
+		struct rx_txbf_musu_ndpa_pkts_stats *rx_musu_ndpa_stats;
+
+		rx_musu_ndpa_stats = (struct rx_txbf_musu_ndpa_pkts_stats *)
+								(msg_word + 1);
+		htt_t2h_rx_musu_ndpa_pkts_stats_print(rx_musu_ndpa_stats);
+		break;
+	}
+	case HTT_DBG_STATS_TIDQ:
+	{
+		struct wlan_dbg_tidq_stats *tidq_stats;
+
+		tidq_stats = (struct wlan_dbg_tidq_stats *)(msg_word + 1);
+		htt_t2h_stats_tidq_stats_print(tidq_stats, concise);
+		break;
+	}
+	case HTT_DBG_STATS_TX_MU_INFO:
+	{
+		struct wlan_dbg_tx_mu_stats *tx_mu_stats;
+
+		tx_mu_stats = (struct wlan_dbg_tx_mu_stats *)(msg_word + 1);
+		htt_t2h_stats_tx_mu_stats_print(tx_mu_stats, concise);
+		break;
+	}
+	case HTT_DBG_STATS_SIFS_RESP_INFO:
+	{
+		struct wlan_dbg_sifs_resp_stats *sifs_stats;
+
+		sifs_stats = (struct wlan_dbg_sifs_resp_stats *)(msg_word + 1);
+		htt_t2h_stats_sifs_resp_stats_print(sifs_stats, concise);
+		break;
+	}
+	default:
+		break;
+	}
+}
diff --git a/core/dp/htt/htt_h2t.c b/core/dp/htt/htt_h2t.c
new file mode 100644
index 0000000..94f6f4d
--- /dev/null
+++ b/core/dp/htt/htt_h2t.c
@@ -0,0 +1,1504 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ * @file htt_h2t.c
+ * @brief Provide functions to send host->target HTT messages.
+ * @details
+ *  This file contains functions related to host->target HTT messages.
+ *  There are a couple aspects of this host->target messaging:
+ *  1.  This file contains the function that is called by HTC when
+ *      a host->target send completes.
+ *      This send-completion callback is primarily relevant to HL,
+ *      to invoke the download scheduler to set up a new download,
+ *      and optionally free the tx frame whose download is completed.
+ *      For both HL and LL, this completion callback frees up the
+ *      HTC_PACKET object used to specify the download.
+ *  2.  This file contains functions for creating messages to send
+ *      from the host to the target.
+ */
+
+#include <qdf_mem.h>         /* qdf_mem_copy */
+#include <qdf_nbuf.h>           /* qdf_nbuf_map_single */
+#include <htc_api.h>            /* HTC_PACKET */
+#include <htc.h>                /* HTC_HDR_ALIGNMENT_PADDING */
+#include <htt.h>                /* HTT host->target msg defs */
+#include <wdi_ipa.h>            /* HTT host->target WDI IPA msg defs */
+#include <ol_txrx_htt_api.h>    /* ol_tx_completion_handler, htt_tx_status */
+#include <ol_htt_tx_api.h>
+
+#include <htt_internal.h>
+#include <wlan_policy_mgr_api.h>
+
+#define HTT_MSG_BUF_SIZE(msg_bytes) \
+	((msg_bytes) + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING)
+
+#ifndef container_of
+#define container_of(ptr, type, member) \
+	((type *)((char *)(ptr) - (char *)(&((type *)0)->member)))
+#endif
+
+#ifdef ATH_11AC_TXCOMPACT
+#define HTT_SEND_HTC_PKT(pdev, pkt)                              \
+do {                                                             \
+	if (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == QDF_STATUS_SUCCESS) \
+		htt_htc_misc_pkt_list_add(pdev, pkt);            \
+} while (0)
+#else
+#define HTT_SEND_HTC_PKT(pdev, ppkt) \
+	htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
+#endif
+
+
+static void
+htt_h2t_send_complete_free_netbuf(void *pdev, QDF_STATUS status,
+				  qdf_nbuf_t netbuf, uint16_t msdu_id)
+{
+	qdf_nbuf_free(netbuf);
+}
+
+void htt_h2t_send_complete(void *context, HTC_PACKET *htc_pkt)
+{
+	void (*send_complete_part2)(void *pdev, QDF_STATUS status,
+				    qdf_nbuf_t msdu, uint16_t msdu_id);
+	struct htt_pdev_t *pdev = (struct htt_pdev_t *)context;
+	struct htt_htc_pkt *htt_pkt;
+	qdf_nbuf_t netbuf;
+
+	send_complete_part2 = htc_pkt->pPktContext;
+
+	htt_pkt = container_of(htc_pkt, struct htt_htc_pkt, htc_pkt);
+
+	/* process (free or keep) the netbuf that held the message */
+	netbuf = (qdf_nbuf_t) htc_pkt->pNetBufContext;
+	if (send_complete_part2 != NULL) {
+		send_complete_part2(htt_pkt->pdev_ctxt, htc_pkt->Status, netbuf,
+				    htt_pkt->msdu_id);
+	}
+
+	if (pdev->cfg.is_high_latency && !pdev->cfg.default_tx_comp_req) {
+		int32_t credit_delta;
+
+		HTT_TX_MUTEX_ACQUIRE(&pdev->credit_mutex);
+		qdf_atomic_add(1, &pdev->htt_tx_credit.bus_delta);
+		credit_delta = htt_tx_credit_update(pdev);
+		HTT_TX_MUTEX_RELEASE(&pdev->credit_mutex);
+
+		if (credit_delta)
+			ol_tx_credit_completion_handler(pdev->txrx_pdev,
+							credit_delta);
+	}
+
+	/* free the htt_htc_pkt / HTC_PACKET object */
+	htt_htc_pkt_free(pdev, htt_pkt);
+}
+
+enum htc_send_full_action htt_h2t_full(void *context, HTC_PACKET *pkt)
+{
+/* FIX THIS */
+	return HTC_SEND_FULL_KEEP;
+}
+
+#if defined(HELIUMPLUS)
+QDF_STATUS htt_h2t_frag_desc_bank_cfg_msg(struct htt_pdev_t *pdev)
+{
+	QDF_STATUS rc = QDF_STATUS_SUCCESS;
+
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	u_int32_t *msg_word;
+	struct htt_tx_frag_desc_bank_cfg_t *bank_cfg;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return QDF_STATUS_E_FAILURE; /* failure */
+
+	/* show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL; /* not used during send-done callback */
+
+	msg = qdf_nbuf_alloc(
+		pdev->osdev,
+		HTT_MSG_BUF_SIZE(sizeof(struct htt_tx_frag_desc_bank_cfg_t)),
+		/* reserve room for the HTC header */
+		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, true);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return QDF_STATUS_E_FAILURE; /* failure */
+	}
+
+	/*
+	 * Set the length of the message.
+	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
+	 * separately during the below call to adf_nbuf_push_head.
+	 * The contribution from the HTC header is added separately inside HTC.
+	 */
+	qdf_nbuf_put_tail(msg, sizeof(struct htt_tx_frag_desc_bank_cfg_t));
+
+	/* fill in the message contents */
+	msg_word = (u_int32_t *) qdf_nbuf_data(msg);
+
+	memset(msg_word, 0, sizeof(struct htt_tx_frag_desc_bank_cfg_t));
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG);
+
+	bank_cfg = (struct htt_tx_frag_desc_bank_cfg_t *)msg_word;
+
+	/** @note @todo Hard coded to 0 Assuming just one pdev for now.*/
+	HTT_H2T_FRAG_DESC_BANK_PDEVID_SET(*msg_word, 0);
+	/** @note Hard coded to 1.*/
+	HTT_H2T_FRAG_DESC_BANK_NUM_BANKS_SET(*msg_word, 1);
+	HTT_H2T_FRAG_DESC_BANK_DESC_SIZE_SET(*msg_word, pdev->frag_descs.size);
+	HTT_H2T_FRAG_DESC_BANK_SWAP_SET(*msg_word, 0);
+
+	/** Bank specific data structure.*/
+#if HTT_PADDR64
+	bank_cfg->bank_base_address[0].lo = qdf_get_lower_32_bits(
+			pdev->frag_descs.desc_pages.dma_pages->page_p_addr);
+	bank_cfg->bank_base_address[0].hi = qdf_get_upper_32_bits(
+			pdev->frag_descs.desc_pages.dma_pages->page_p_addr);
+#else /* ! HTT_PADDR64 */
+	bank_cfg->bank_base_address[0] =
+		pdev->frag_descs.desc_pages.dma_pages->page_p_addr;
+#endif /* HTT_PADDR64 */
+	/* Logical Min index */
+	HTT_H2T_FRAG_DESC_BANK_MIN_IDX_SET(bank_cfg->bank_info[0], 0);
+	/* Logical Max index */
+	HTT_H2T_FRAG_DESC_BANK_MAX_IDX_SET(bank_cfg->bank_info[0],
+					   pdev->frag_descs.pool_elems-1);
+
+	SET_HTC_PACKET_INFO_TX(
+		&pkt->htc_pkt,
+		htt_h2t_send_complete_free_netbuf,
+		qdf_nbuf_data(msg),
+		qdf_nbuf_len(msg),
+		pdev->htc_tx_endpoint,
+		1); /* tag - not relevant here */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+
+	rc = htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
+#ifdef ATH_11AC_TXCOMPACT
+	if (rc == QDF_STATUS_SUCCESS)
+		htt_htc_misc_pkt_list_add(pdev, pkt);
+#endif
+
+	return rc;
+}
+
+#endif /* defined(HELIUMPLUS) */
+
+QDF_STATUS htt_h2t_ver_req_msg(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+	uint32_t msg_size;
+	uint32_t max_tx_group;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return QDF_STATUS_E_FAILURE; /* failure */
+
+	max_tx_group = ol_tx_get_max_tx_groups_supported(pdev->txrx_pdev);
+
+	if (max_tx_group)
+		msg_size = HTT_VER_REQ_BYTES +
+			sizeof(struct htt_option_tlv_mac_tx_queue_groups_t);
+	else
+		msg_size = HTT_VER_REQ_BYTES;
+
+	/* show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for the HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(msg_size),
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     true);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return QDF_STATUS_E_FAILURE; /* failure */
+	}
+
+	/*
+	 * Set the length of the message.
+	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
+	 * separately during the below call to qdf_nbuf_push_head.
+	 * The contribution from the HTC header is added separately inside HTC.
+	 */
+	qdf_nbuf_put_tail(msg, msg_size);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_VERSION_REQ);
+
+	if (max_tx_group) {
+		*(msg_word + 1) = 0;
+
+		/* Fill Group Info */
+		HTT_OPTION_TLV_TAG_SET(*(msg_word+1),
+				       HTT_OPTION_TLV_TAG_MAX_TX_QUEUE_GROUPS);
+		HTT_OPTION_TLV_LENGTH_SET(*(msg_word+1),
+			(sizeof(struct htt_option_tlv_mac_tx_queue_groups_t)/
+			 sizeof(uint32_t)));
+		HTT_OPTION_TLV_VALUE0_SET(*(msg_word+1), max_tx_group);
+	}
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg), qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       1); /* tag - not relevant here */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+	HTT_SEND_HTC_PKT(pdev, pkt);
+
+	if ((pdev->cfg.is_high_latency) &&
+	    (!pdev->cfg.default_tx_comp_req))
+		ol_tx_target_credit_update(pdev->txrx_pdev, -1);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#if defined(HELIUMPLUS)
+/**
+ * htt_h2t_rx_ring_rfs_cfg_msg_ll() - Configure receive flow steering
+ * @pdev: handle to the HTT instance
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ *         A_NO_MEMORY No memory fail
+ */
+QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_ll(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+	uint32_t  msg_local;
+	struct cds_config_info *cds_cfg;
+
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+		  "Receive flow steering configuration, disable gEnableFlowSteering(=0) in ini if FW doesnot support it\n");
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return QDF_STATUS_E_NOMEM; /* failure */
+
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for the HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev,
+			     HTT_MSG_BUF_SIZE(HTT_RFS_CFG_REQ_BYTES),
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     true);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return QDF_STATUS_E_NOMEM; /* failure */
+	}
+	/*
+	 * Set the length of the message.
+	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
+	 * separately during the below call to qdf_nbuf_push_head.
+	 * The contribution from the HTC header is added separately inside HTC.
+	 */
+	qdf_nbuf_put_tail(msg, HTT_RFS_CFG_REQ_BYTES);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	msg_local = 0;
+	HTT_H2T_MSG_TYPE_SET(msg_local, HTT_H2T_MSG_TYPE_RFS_CONFIG);
+	if (ol_cfg_is_flow_steering_enabled(pdev->ctrl_pdev)) {
+		HTT_RX_RFS_CONFIG_SET(msg_local, 1);
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+			  "Enable Rx flow steering");
+	} else {
+	    QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+		      "Disable Rx flow steering");
+	}
+	cds_cfg = cds_get_ini_config();
+	if (cds_cfg != NULL) {
+		msg_local |= ((cds_cfg->max_msdus_per_rxinorderind & 0xff)
+			      << 16);
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+			  "Updated maxMSDUsPerRxInd");
+	}
+
+	*msg_word = msg_local;
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%s: Sending msg_word: 0x%08x",
+		  __func__, *msg_word);
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg), qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       1); /* tag - not relevant here */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+	HTT_SEND_HTC_PKT(pdev, pkt);
+	return QDF_STATUS_SUCCESS;
+}
+#else
+/**
+ * htt_h2t_rx_ring_rfs_cfg_msg_ll() - Configure receive flow steering
+ * @pdev: handle to the HTT instance
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ *         A_NO_MEMORY No memory fail
+ */
+QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_ll(struct htt_pdev_t *pdev)
+{
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+		  "Doesnot support receive flow steering configuration\n");
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* HELIUMPLUS */
+
+QDF_STATUS htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+	int enable_ctrl_data, enable_mgmt_data,
+	    enable_null_data, enable_phy_data, enable_hdr,
+	    enable_ppdu_start, enable_ppdu_end;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return QDF_STATUS_E_FAILURE; /* failure */
+
+	/*
+	 * show that this is not a tx frame download
+	 *  (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for the HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev,
+			     HTT_MSG_BUF_SIZE(HTT_RX_RING_CFG_BYTES(1)),
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     true);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return QDF_STATUS_E_FAILURE; /* failure */
+	}
+	/*
+	 * Set the length of the message.
+	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
+	 * separately during the below call to qdf_nbuf_push_head.
+	 * The contribution from the HTC header is added separately inside HTC.
+	 */
+	qdf_nbuf_put_tail(msg, HTT_RX_RING_CFG_BYTES(1));
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_RING_CFG);
+	HTT_RX_RING_CFG_NUM_RINGS_SET(*msg_word, 1);
+
+	msg_word++;
+	*msg_word = 0;
+#if HTT_PADDR64
+	HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_LO_SET(
+			*msg_word,
+			qdf_get_lower_32_bits(pdev->rx_ring.alloc_idx.paddr));
+	msg_word++;
+	HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_HI_SET(
+			*msg_word,
+			qdf_get_upper_32_bits(pdev->rx_ring.alloc_idx.paddr));
+#else /* ! HTT_PADDR64 */
+	HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_SET(*msg_word,
+						 pdev->rx_ring.alloc_idx.paddr);
+#endif /* HTT_PADDR64 */
+
+	msg_word++;
+	*msg_word = 0;
+#if HTT_PADDR64
+	HTT_RX_RING_CFG_BASE_PADDR_LO_SET(*msg_word,
+					  pdev->rx_ring.base_paddr);
+	{
+		uint32_t tmp;
+
+		tmp = qdf_get_upper_32_bits(pdev->rx_ring.base_paddr);
+		if (tmp & 0xfffffe0) {
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+				  "%s:%d paddr > 37 bits!. Trimmed.",
+				  __func__, __LINE__);
+			tmp &= 0x01f;
+		}
+
+
+		msg_word++;
+		HTT_RX_RING_CFG_BASE_PADDR_HI_SET(*msg_word, tmp);
+	}
+#else /* ! HTT_PADDR64 */
+	HTT_RX_RING_CFG_BASE_PADDR_SET(*msg_word, pdev->rx_ring.base_paddr);
+#endif /* HTT_PADDR64 */
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_LEN_SET(*msg_word, pdev->rx_ring.size);
+	HTT_RX_RING_CFG_BUF_SZ_SET(*msg_word, HTT_RX_BUF_SIZE);
+
+/* FIX THIS: if the FW creates a complete translated rx descriptor,
+ * then the MAC DMA of the HW rx descriptor should be disabled.
+ */
+	msg_word++;
+	*msg_word = 0;
+#ifndef REMOVE_PKT_LOG
+	if (ol_cfg_is_packet_log_enabled(pdev->ctrl_pdev)) {
+		enable_ctrl_data = 1;
+		enable_mgmt_data = 1;
+		enable_null_data = 1;
+		enable_phy_data = 1;
+		enable_hdr = 1;
+		enable_ppdu_start = 1;
+		enable_ppdu_end = 1;
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+			  "%s : %d Pkt log is enabled\n",  __func__, __LINE__);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+			  "%s : %d Pkt log is disabled\n",  __func__, __LINE__);
+		enable_ctrl_data = 0;
+		enable_mgmt_data = 0;
+		enable_null_data = 0;
+		enable_phy_data = 0;
+		enable_hdr = 0;
+		enable_ppdu_start = 0;
+		enable_ppdu_end = 0;
+	}
+#else
+	enable_ctrl_data = 0;
+	enable_mgmt_data = 0;
+	enable_null_data = 0;
+	enable_phy_data = 0;
+	enable_hdr = 0;
+	enable_ppdu_start = 0;
+	enable_ppdu_end = 0;
+#endif
+	if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) {
+		enable_ctrl_data  = 1;
+		enable_mgmt_data  = 1;
+		enable_null_data  = 1;
+		enable_phy_data   = 1;
+		enable_hdr        = 1;
+		enable_ppdu_start = 1;
+		enable_ppdu_end   = 1;
+		/* Disable ASPM for monitor mode */
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+			  "%s : %d Monitor mode is enabled\n",
+			  __func__, __LINE__);
+	}
+
+	HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(*msg_word, enable_hdr);
+	HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(*msg_word, 1);
+	HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(*msg_word, enable_ppdu_start);
+	HTT_RX_RING_CFG_ENABLED_PPDU_END_SET(*msg_word, enable_ppdu_end);
+	HTT_RX_RING_CFG_ENABLED_MPDU_START_SET(*msg_word, 1);
+	HTT_RX_RING_CFG_ENABLED_MPDU_END_SET(*msg_word, 1);
+	HTT_RX_RING_CFG_ENABLED_MSDU_START_SET(*msg_word, 1);
+	HTT_RX_RING_CFG_ENABLED_MSDU_END_SET(*msg_word, 1);
+	HTT_RX_RING_CFG_ENABLED_RX_ATTN_SET(*msg_word, 1);
+	/* always present? */
+	HTT_RX_RING_CFG_ENABLED_FRAG_INFO_SET(*msg_word, 1);
+	HTT_RX_RING_CFG_ENABLED_UCAST_SET(*msg_word, 1);
+	HTT_RX_RING_CFG_ENABLED_MCAST_SET(*msg_word, 1);
+	/* Must change to dynamic enable at run time
+	 * rather than at compile time
+	 */
+	HTT_RX_RING_CFG_ENABLED_CTRL_SET(*msg_word, enable_ctrl_data);
+	HTT_RX_RING_CFG_ENABLED_MGMT_SET(*msg_word, enable_mgmt_data);
+	HTT_RX_RING_CFG_ENABLED_NULL_SET(*msg_word, enable_null_data);
+	HTT_RX_RING_CFG_ENABLED_PHY_SET(*msg_word, enable_phy_data);
+	HTT_RX_RING_CFG_IDX_INIT_VAL_SET(*msg_word,
+					 *pdev->rx_ring.alloc_idx.vaddr);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_OFFSET_802_11_HDR_SET(*msg_word,
+					      RX_DESC_HDR_STATUS_OFFSET32);
+	HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_SET(*msg_word,
+					      HTT_RX_DESC_RESERVATION32);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_OFFSET_PPDU_START_SET(*msg_word,
+					      RX_DESC_PPDU_START_OFFSET32);
+	HTT_RX_RING_CFG_OFFSET_PPDU_END_SET(*msg_word,
+					    RX_DESC_PPDU_END_OFFSET32);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_OFFSET_MPDU_START_SET(*msg_word,
+					      RX_DESC_MPDU_START_OFFSET32);
+	HTT_RX_RING_CFG_OFFSET_MPDU_END_SET(*msg_word,
+					    RX_DESC_MPDU_END_OFFSET32);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_OFFSET_MSDU_START_SET(*msg_word,
+					      RX_DESC_MSDU_START_OFFSET32);
+	HTT_RX_RING_CFG_OFFSET_MSDU_END_SET(*msg_word,
+					    RX_DESC_MSDU_END_OFFSET32);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_OFFSET_RX_ATTN_SET(*msg_word,
+					   RX_DESC_ATTN_OFFSET32);
+	HTT_RX_RING_CFG_OFFSET_FRAG_INFO_SET(*msg_word,
+					     RX_DESC_FRAG_INFO_OFFSET32);
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg),
+			       qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+	HTT_SEND_HTC_PKT(pdev, pkt);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	u_int32_t *msg_word;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return A_ERROR; /* failure */
+
+	/*
+	 * show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL; /* not used during send-done callback */
+
+	msg = qdf_nbuf_alloc(
+		pdev->osdev,
+		HTT_MSG_BUF_SIZE(HTT_RX_RING_CFG_BYTES(1)),
+		/* reserve room for the HTC header */
+		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, true);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return A_ERROR; /* failure */
+	}
+	/*
+	 * Set the length of the message.
+	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
+	 * separately during the below call to adf_nbuf_push_head.
+	 * The contribution from the HTC header is added separately inside HTC.
+	 */
+	qdf_nbuf_put_tail(msg, HTT_RX_RING_CFG_BYTES(1));
+
+	/* fill in the message contents */
+	msg_word = (u_int32_t *)qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_RING_CFG);
+	HTT_RX_RING_CFG_NUM_RINGS_SET(*msg_word, 1);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_SET(
+			*msg_word, pdev->rx_ring.alloc_idx.paddr);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_BASE_PADDR_SET(*msg_word, pdev->rx_ring.base_paddr);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_LEN_SET(*msg_word, pdev->rx_ring.size);
+	HTT_RX_RING_CFG_BUF_SZ_SET(*msg_word, HTT_RX_BUF_SIZE);
+
+	/* FIX THIS: if the FW creates a complete translated rx descriptor,
+	 * then the MAC DMA of the HW rx descriptor should be disabled. */
+	msg_word++;
+	*msg_word = 0;
+
+	HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(*msg_word, 0);
+	HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(*msg_word, 1);
+	HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(*msg_word, 0);
+	HTT_RX_RING_CFG_ENABLED_PPDU_END_SET(*msg_word, 0);
+	HTT_RX_RING_CFG_ENABLED_MPDU_START_SET(*msg_word, 0);
+	HTT_RX_RING_CFG_ENABLED_MPDU_END_SET(*msg_word,   0);
+	HTT_RX_RING_CFG_ENABLED_MSDU_START_SET(*msg_word, 0);
+	HTT_RX_RING_CFG_ENABLED_MSDU_END_SET(*msg_word,   0);
+	HTT_RX_RING_CFG_ENABLED_RX_ATTN_SET(*msg_word,    0);
+	/* always present? */
+	HTT_RX_RING_CFG_ENABLED_FRAG_INFO_SET(*msg_word,  0);
+	HTT_RX_RING_CFG_ENABLED_UCAST_SET(*msg_word, 1);
+	HTT_RX_RING_CFG_ENABLED_MCAST_SET(*msg_word, 1);
+	/* Must change to dynamic enable at run time
+	 * rather than at compile time
+	 */
+	HTT_RX_RING_CFG_ENABLED_CTRL_SET(*msg_word, 0);
+	HTT_RX_RING_CFG_ENABLED_MGMT_SET(*msg_word, 0);
+	HTT_RX_RING_CFG_ENABLED_NULL_SET(*msg_word, 0);
+	HTT_RX_RING_CFG_ENABLED_PHY_SET(*msg_word, 0);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_OFFSET_802_11_HDR_SET(*msg_word,
+					      0);
+	HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_SET(*msg_word,
+					      0);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_OFFSET_PPDU_START_SET(*msg_word,
+					      0);
+	HTT_RX_RING_CFG_OFFSET_PPDU_END_SET(*msg_word,
+					    0);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_OFFSET_MPDU_START_SET(*msg_word,
+					      0);
+	HTT_RX_RING_CFG_OFFSET_MPDU_END_SET(*msg_word,
+					    0);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_OFFSET_MSDU_START_SET(*msg_word,
+					      0);
+	HTT_RX_RING_CFG_OFFSET_MSDU_END_SET(*msg_word,
+					    0);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_RX_RING_CFG_OFFSET_RX_ATTN_SET(*msg_word,
+					   0);
+	HTT_RX_RING_CFG_OFFSET_FRAG_INFO_SET(*msg_word,
+					     0);
+
+	SET_HTC_PACKET_INFO_TX(
+		&pkt->htc_pkt,
+		htt_h2t_send_complete_free_netbuf,
+		qdf_nbuf_data(msg),
+		qdf_nbuf_len(msg),
+		pdev->htc_tx_endpoint,
+		1); /* tag - not relevant here */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+
+#ifdef ATH_11AC_TXCOMPACT
+	if (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == QDF_STATUS_SUCCESS)
+		htt_htc_misc_pkt_list_add(pdev, pkt);
+#else
+	htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
+#endif
+
+	if ((pdev->cfg.is_high_latency) &&
+	    (!pdev->cfg.default_tx_comp_req))
+		ol_tx_target_credit_update(pdev->txrx_pdev, -1);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * htt_h2t_rx_ring_rfs_cfg_msg_hl() - Configure receive flow steering
+ * @pdev: handle to the HTT instance
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ *         A_NO_MEMORY No memory fail
+ */
+QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_hl(struct htt_pdev_t *pdev)
+{
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+		  "Doesnot support Receive flow steering configuration\n");
+	return QDF_STATUS_SUCCESS;
+}
+
+int
+htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev,
+		      uint32_t stats_type_upload_mask,
+		      uint32_t stats_type_reset_mask,
+		      uint8_t cfg_stat_type, uint32_t cfg_val, uint8_t cookie)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+	uint16_t htc_tag = 1;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return -EINVAL;      /* failure */
+
+	if (stats_type_upload_mask >= 1 << HTT_DBG_NUM_STATS ||
+	    stats_type_reset_mask >= 1 << HTT_DBG_NUM_STATS) {
+		/* FIX THIS - add more details? */
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%#x %#x stats not supported\n",
+			  stats_type_upload_mask, stats_type_reset_mask);
+		htt_htc_pkt_free(pdev, pkt);
+		return -EINVAL;      /* failure */
+	}
+
+	if (stats_type_reset_mask)
+		htc_tag = HTC_TX_PACKET_TAG_RUNTIME_PUT;
+
+	/* show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+
+	msg = qdf_nbuf_alloc(pdev->osdev,
+			     HTT_MSG_BUF_SIZE(HTT_H2T_STATS_REQ_MSG_SZ),
+			     /* reserve room for HTC header */
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     false);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return -EINVAL;      /* failure */
+	}
+	/* set the length of the message */
+	qdf_nbuf_put_tail(msg, HTT_H2T_STATS_REQ_MSG_SZ);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_STATS_REQ);
+	HTT_H2T_STATS_REQ_UPLOAD_TYPES_SET(*msg_word, stats_type_upload_mask);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_H2T_STATS_REQ_RESET_TYPES_SET(*msg_word, stats_type_reset_mask);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_H2T_STATS_REQ_CFG_VAL_SET(*msg_word, cfg_val);
+	HTT_H2T_STATS_REQ_CFG_STAT_TYPE_SET(*msg_word, cfg_stat_type);
+
+	/* cookie LSBs */
+	msg_word++;
+	*msg_word = cookie;
+
+	/* cookie MSBs */
+	msg_word++;
+	*msg_word = 0;
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg),
+			       qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       htc_tag); /* tag - not relevant here */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+
+#ifdef ATH_11AC_TXCOMPACT
+	if (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == QDF_STATUS_SUCCESS)
+		htt_htc_misc_pkt_list_add(pdev, pkt);
+#else
+	htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
+#endif
+
+	if ((pdev->cfg.is_high_latency) &&
+	    (!pdev->cfg.default_tx_comp_req))
+		ol_tx_target_credit_update(pdev->txrx_pdev, -1);
+
+	return 0;
+}
+
+A_STATUS htt_h2t_sync_msg(struct htt_pdev_t *pdev, uint8_t sync_cnt)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return A_NO_MEMORY;
+
+	/* show that this is not a tx frame download
+	   (not required, but helpful)
+	*/
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_H2T_SYNC_MSG_SZ),
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     false);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return A_NO_MEMORY;
+	}
+	/* set the length of the message */
+	qdf_nbuf_put_tail(msg, HTT_H2T_SYNC_MSG_SZ);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_SYNC);
+	HTT_H2T_SYNC_COUNT_SET(*msg_word, sync_cnt);
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg),
+			       qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+	HTT_SEND_HTC_PKT(pdev, pkt);
+
+	if ((pdev->cfg.is_high_latency) &&
+	    (!pdev->cfg.default_tx_comp_req))
+		ol_tx_target_credit_update(pdev->txrx_pdev, -1);
+
+	return A_OK;
+}
+
+int
+htt_h2t_aggr_cfg_msg(struct htt_pdev_t *pdev,
+		     int max_subfrms_ampdu, int max_subfrms_amsdu)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return -EINVAL;      /* failure */
+
+	/* show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_AGGR_CFG_MSG_SZ),
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     false);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return -EINVAL;      /* failure */
+	}
+	/* set the length of the message */
+	qdf_nbuf_put_tail(msg, HTT_AGGR_CFG_MSG_SZ);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_AGGR_CFG);
+
+	if (max_subfrms_ampdu && (max_subfrms_ampdu <= 64)) {
+		HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM_SET(*msg_word,
+						      max_subfrms_ampdu);
+	}
+
+	if (max_subfrms_amsdu && (max_subfrms_amsdu < 32)) {
+		HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM_SET(*msg_word,
+						      max_subfrms_amsdu);
+	}
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg),
+			       qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+
+#ifdef ATH_11AC_TXCOMPACT
+	if (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == QDF_STATUS_SUCCESS)
+		htt_htc_misc_pkt_list_add(pdev, pkt);
+#else
+	htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
+#endif
+
+	if ((pdev->cfg.is_high_latency) &&
+	    (!pdev->cfg.default_tx_comp_req))
+		ol_tx_target_credit_update(pdev->txrx_pdev, -1);
+
+	return 0;
+}
+
+#ifdef IPA_OFFLOAD
+/**
+ * htt_h2t_ipa_uc_rsc_cfg_msg() - Send WDI IPA config message to firmware
+ * @pdev: handle to the HTT instance
+ *
+ * Return: 0 success
+ *         A_NO_MEMORY No memory fail
+ */
+#ifdef QCA_WIFI_3_0
+int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return -A_NO_MEMORY;
+
+	/* show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_WDI_IPA_CFG_SZ),
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     false);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return -A_NO_MEMORY;
+	}
+	/* set the length of the message */
+	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_CFG_SZ);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_SET(*msg_word,
+		pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt);
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_CFG);
+
+	msg_word++;
+	*msg_word = 0;
+	/* TX COMP RING BASE LO */
+	HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_LO_SET(*msg_word,
+		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
+			&pdev->ipa_uc_tx_rsc.tx_comp_ring->mem_info));
+	msg_word++;
+	*msg_word = 0;
+	/* TX COMP RING BASE HI, NONE */
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_SET(*msg_word,
+		(unsigned int)ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev));
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_LO_SET(*msg_word,
+		(unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_idx_paddr);
+	msg_word++;
+	*msg_word = 0;
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_LO_SET(*msg_word,
+		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
+			&pdev->ipa_uc_tx_rsc.tx_ce_idx->mem_info));
+	msg_word++;
+	*msg_word = 0;
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_LO_SET(*msg_word,
+		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
+			&pdev->ipa_uc_rx_rsc.rx_ind_ring->mem_info));
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_HI_SET(*msg_word,
+		0);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_SET(*msg_word,
+		(unsigned int)qdf_get_pwr2(pdev->rx_ring.fill_level));
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_LO_SET(*msg_word,
+		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
+			&pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx->mem_info));
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_HI_SET(*msg_word,
+		0);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_LO_SET(*msg_word,
+		(unsigned int)pdev->ipa_uc_rx_rsc.rx_rdy_idx_paddr);
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_HI_SET(*msg_word,
+		0);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_LO_SET(*msg_word,
+		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
+			&pdev->ipa_uc_rx_rsc.rx2_ind_ring->mem_info));
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_HI_SET(*msg_word,
+		0);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_RING2_SIZE_SET(*msg_word,
+		(unsigned int)qdf_get_pwr2(pdev->rx_ring.fill_level));
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_LO_SET(*msg_word,
+		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
+			&pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx->mem_info));
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_HI_SET(*msg_word,
+		0);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_LO_SET(*msg_word,
+		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
+			&pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx->mem_info));
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_HI_SET(*msg_word,
+		0);
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg),
+			       qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+	HTT_SEND_HTC_PKT(pdev, pkt);
+	return A_OK;
+}
+#else
+/* Rome Support only WDI 1.0 */
+int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return A_NO_MEMORY;
+
+	/* show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_WDI_IPA_CFG_SZ),
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     false);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return A_NO_MEMORY;
+	}
+	/* set the length of the message */
+	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_CFG_SZ);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_SET(*msg_word,
+				pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt);
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_CFG);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_SET(*msg_word,
+		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
+			&pdev->ipa_uc_tx_rsc.tx_comp_ring->mem_info));
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_SET(
+		*msg_word,
+		(unsigned int)ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev));
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_SET(*msg_word,
+		(unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_idx_paddr);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_SET(*msg_word,
+		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
+			&pdev->ipa_uc_tx_rsc.tx_ce_idx->mem_info));
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_SET(*msg_word,
+		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
+			&pdev->ipa_uc_rx_rsc.rx_ind_ring->mem_info));
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_SET(*msg_word,
+		(unsigned int)qdf_get_pwr2(pdev->rx_ring.fill_level));
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_SET(*msg_word,
+		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
+			&pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx->mem_info));
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_SET(*msg_word,
+	       (unsigned int)pdev->ipa_uc_rx_rsc.rx_rdy_idx_paddr);
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg),
+			       qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+	HTT_SEND_HTC_PKT(pdev, pkt);
+	return A_OK;
+}
+#endif
+
+/**
+ * htt_h2t_ipa_uc_set_active() - Propagate WDI path enable/disable to firmware
+ * @pdev: handle to the HTT instance
+ * @uc_active: WDI UC path enable or not
+ * @is_tx: TX path or RX path
+ *
+ * Return: 0 success
+ *         A_NO_MEMORY No memory fail
+ */
+int htt_h2t_ipa_uc_set_active(struct htt_pdev_t *pdev,
+			      bool uc_active, bool is_tx)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+	uint8_t active_target = 0;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return -A_NO_MEMORY;
+
+	/* show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev,
+			     HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ),
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     false);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return -A_NO_MEMORY;
+	}
+	/* set the length of the message */
+	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	if (uc_active && is_tx)
+		active_target = HTT_WDI_IPA_OPCODE_TX_RESUME;
+	else if (!uc_active && is_tx)
+		active_target = HTT_WDI_IPA_OPCODE_TX_SUSPEND;
+	else if (uc_active && !is_tx)
+		active_target = HTT_WDI_IPA_OPCODE_RX_RESUME;
+	else if (!uc_active && !is_tx)
+		active_target = HTT_WDI_IPA_OPCODE_RX_SUSPEND;
+
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+			"%s: HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ (%d)\n",
+			__func__, active_target);
+
+	HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word, active_target);
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ);
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg),
+			       qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       1); /* tag - not relevant here */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+	HTT_SEND_HTC_PKT(pdev, pkt);
+	return A_OK;
+}
+
+/**
+ * htt_h2t_ipa_uc_get_stats() - WDI UC state query request to firmware
+ * @pdev: handle to the HTT instance
+ *
+ * Return: 0 success
+ *         A_NO_MEMORY No memory fail
+ */
+int htt_h2t_ipa_uc_get_stats(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return -A_NO_MEMORY;
+
+	/* show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev,
+			     HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ),
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     false);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return -A_NO_MEMORY;
+	}
+	/* set the length of the message */
+	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word,
+					   HTT_WDI_IPA_OPCODE_DBG_STATS);
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ);
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg),
+			       qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       1); /* tag - not relevant here */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+	HTT_SEND_HTC_PKT(pdev, pkt);
+	return A_OK;
+}
+
+/**
+ * htt_h2t_ipa_uc_get_share_stats() - WDI UC wifi sharing state request to FW
+ * @pdev: handle to the HTT instance
+ *
+ * Return: A_OK success
+ *         A_NO_MEMORY No memory fail
+ */
+int htt_h2t_ipa_uc_get_share_stats(struct htt_pdev_t *pdev, uint8_t reset_stats)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return -A_NO_MEMORY;
+
+	/* show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev,
+		HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ)+
+		HTT_MSG_BUF_SIZE(WLAN_WDI_IPA_GET_SHARING_STATS_REQ_SZ),
+		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, false);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return -A_NO_MEMORY;
+	}
+	/* set the length of the message */
+	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ+
+			  WLAN_WDI_IPA_GET_SHARING_STATS_REQ_SZ);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word,
+				   HTT_WDI_IPA_OPCODE_GET_SHARING_STATS);
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ);
+
+	msg_word++;
+	*msg_word = 0;
+	WLAN_WDI_IPA_GET_SHARING_STATS_REQ_RESET_STATS_SET(*msg_word,
+							     reset_stats);
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg),
+			       qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       1); /* tag - not relevant here */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+	HTT_SEND_HTC_PKT(pdev, pkt);
+	return A_OK;
+}
+
+/**
+ * htt_h2t_ipa_uc_set_quota() - WDI UC state query request to firmware
+ * @pdev: handle to the HTT instance
+ *
+ * Return: A_OK success
+ *         A_NO_MEMORY No memory fail
+ */
+int htt_h2t_ipa_uc_set_quota(struct htt_pdev_t *pdev, uint64_t quota_bytes)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return -A_NO_MEMORY;
+
+	/* show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev,
+		HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ)+
+		HTT_MSG_BUF_SIZE(WLAN_WDI_IPA_SET_QUOTA_REQ_SZ),
+		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, false);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return -A_NO_MEMORY;
+	}
+	/* set the length of the message */
+	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ+
+			  WLAN_WDI_IPA_SET_QUOTA_REQ_SZ);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word,
+					   HTT_WDI_IPA_OPCODE_SET_QUOTA);
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ);
+
+	msg_word++;
+	*msg_word = 0;
+	WLAN_WDI_IPA_SET_QUOTA_REQ_SET_QUOTA_SET(*msg_word, quota_bytes > 0);
+
+	msg_word++;
+	*msg_word = 0;
+	WLAN_WDI_IPA_SET_QUOTA_REQ_QUOTA_LO_SET(*msg_word,
+			(uint32_t)(quota_bytes &
+				   WLAN_WDI_IPA_SET_QUOTA_REQ_QUOTA_LO_M));
+
+	msg_word++;
+	*msg_word = 0;
+	WLAN_WDI_IPA_SET_QUOTA_REQ_QUOTA_HI_SET(*msg_word,
+			(uint32_t)(quota_bytes>>32 &
+				   WLAN_WDI_IPA_SET_QUOTA_REQ_QUOTA_HI_M));
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg),
+			       qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       1); /* tag - not relevant here */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+	HTT_SEND_HTC_PKT(pdev, pkt);
+	return A_OK;
+}
+#endif /* IPA_OFFLOAD */
diff --git a/core/dp/htt/htt_internal.h b/core/dp/htt/htt_internal.h
new file mode 100644
index 0000000..08842bf
--- /dev/null
+++ b/core/dp/htt/htt_internal.h
@@ -0,0 +1,1074 @@
+/*
+ * Copyright (c) 2011, 2014-2018 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.
+ */
+
+#ifndef _HTT_INTERNAL__H_
+#define _HTT_INTERNAL__H_
+
+#include <athdefs.h>            /* A_STATUS */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <qdf_util.h>           /* qdf_assert */
+#include <htc_api.h>            /* HTC_PACKET */
+
+#include <htt_types.h>
+
+#ifndef offsetof
+#define offsetof(type, field)   ((size_t)(&((type *)0)->field))
+#endif
+
+#undef MS
+#define MS(_v, _f) (((_v) & _f ## _MASK) >> _f ## _LSB)
+#undef SM
+#define SM(_v, _f) (((_v) << _f ## _LSB) & _f ## _MASK)
+#undef WO
+#define WO(_f)      ((_f ## _OFFSET) >> 2)
+
+#define GET_FIELD(_addr, _f) MS(*((A_UINT32 *)(_addr) + WO(_f)), _f)
+
+#include <rx_desc.h>
+#include <wal_rx_desc.h>        /* struct rx_attention, etc */
+
+struct htt_host_fw_desc_base {
+	union {
+		struct fw_rx_desc_base val;
+		A_UINT32 dummy_pad;     /* make sure it is DOWRD aligned */
+	} u;
+};
+
+
+/*
+ * This struct defines the basic descriptor information used by host,
+ * which is written either by the 11ac HW MAC into the host Rx data
+ * buffer ring directly or generated by FW and copied from Rx indication
+ */
+struct htt_host_rx_desc_base {
+	struct htt_host_fw_desc_base fw_desc;
+	struct rx_attention attention;
+	struct rx_frag_info frag_info;
+	struct rx_mpdu_start mpdu_start;
+	struct rx_msdu_start msdu_start;
+	struct rx_msdu_end msdu_end;
+	struct rx_mpdu_end mpdu_end;
+	struct rx_ppdu_start ppdu_start;
+	struct rx_ppdu_end ppdu_end;
+#ifdef QCA_WIFI_3_0_ADRASTEA
+/* Increased to support some of offload features */
+#define RX_HTT_HDR_STATUS_LEN 256
+#else
+#define RX_HTT_HDR_STATUS_LEN 64
+#endif
+	char rx_hdr_status[RX_HTT_HDR_STATUS_LEN];
+};
+
+#define RX_DESC_ATTN_MPDU_LEN_ERR_BIT   0x08000000
+
+#define RX_STD_DESC_ATTN_OFFSET	\
+	(offsetof(struct htt_host_rx_desc_base, attention))
+#define RX_STD_DESC_FRAG_INFO_OFFSET \
+	(offsetof(struct htt_host_rx_desc_base, frag_info))
+#define RX_STD_DESC_MPDU_START_OFFSET \
+	(offsetof(struct htt_host_rx_desc_base, mpdu_start))
+#define RX_STD_DESC_MSDU_START_OFFSET \
+	(offsetof(struct htt_host_rx_desc_base, msdu_start))
+#define RX_STD_DESC_MSDU_END_OFFSET \
+	(offsetof(struct htt_host_rx_desc_base, msdu_end))
+#define RX_STD_DESC_MPDU_END_OFFSET \
+	(offsetof(struct htt_host_rx_desc_base, mpdu_end))
+#define RX_STD_DESC_PPDU_START_OFFSET \
+	(offsetof(struct htt_host_rx_desc_base, ppdu_start))
+#define RX_STD_DESC_PPDU_END_OFFSET \
+	(offsetof(struct htt_host_rx_desc_base, ppdu_end))
+#define RX_STD_DESC_HDR_STATUS_OFFSET \
+	(offsetof(struct htt_host_rx_desc_base, rx_hdr_status))
+
+#define RX_STD_DESC_FW_MSDU_OFFSET \
+	(offsetof(struct htt_host_rx_desc_base, fw_desc))
+
+#define RX_STD_DESC_SIZE (sizeof(struct htt_host_rx_desc_base))
+
+#define RX_DESC_ATTN_OFFSET32       (RX_STD_DESC_ATTN_OFFSET >> 2)
+#define RX_DESC_FRAG_INFO_OFFSET32  (RX_STD_DESC_FRAG_INFO_OFFSET >> 2)
+#define RX_DESC_MPDU_START_OFFSET32 (RX_STD_DESC_MPDU_START_OFFSET >> 2)
+#define RX_DESC_MSDU_START_OFFSET32 (RX_STD_DESC_MSDU_START_OFFSET >> 2)
+#define RX_DESC_MSDU_END_OFFSET32   (RX_STD_DESC_MSDU_END_OFFSET >> 2)
+#define RX_DESC_MPDU_END_OFFSET32   (RX_STD_DESC_MPDU_END_OFFSET >> 2)
+#define RX_DESC_PPDU_START_OFFSET32 (RX_STD_DESC_PPDU_START_OFFSET >> 2)
+#define RX_DESC_PPDU_END_OFFSET32   (RX_STD_DESC_PPDU_END_OFFSET >> 2)
+#define RX_DESC_HDR_STATUS_OFFSET32 (RX_STD_DESC_HDR_STATUS_OFFSET >> 2)
+
+#define RX_STD_DESC_SIZE_DWORD      (RX_STD_DESC_SIZE >> 2)
+
+/*
+ * Make sure there is a minimum headroom provided in the rx netbufs
+ * for use by the OS shim and OS and rx data consumers.
+ */
+#define HTT_RX_BUF_OS_MIN_HEADROOM 32
+#define HTT_RX_STD_DESC_RESERVATION  \
+	((HTT_RX_BUF_OS_MIN_HEADROOM > RX_STD_DESC_SIZE) ? \
+	 HTT_RX_BUF_OS_MIN_HEADROOM : RX_STD_DESC_SIZE)
+#define HTT_RX_DESC_RESERVATION32 \
+	(HTT_RX_STD_DESC_RESERVATION >> 2)
+
+#define HTT_RX_DESC_ALIGN_MASK 7        /* 8-byte alignment */
+
+#ifdef DEBUG_RX_RING_BUFFER
+#define NBUF_MAP_ID(skb) \
+	(((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.dev.priv_cb_m.map_index)
+
+#ifdef MSM_PLATFORM
+#define HTT_ADDRESS_MASK   0xfffffffffffffffe
+#else
+#define HTT_ADDRESS_MASK   0xfffffffe
+#endif /* MSM_PLATFORM */
+
+/**
+ * rx_buf_debug: rx_ring history
+ *
+ * There are three types of entries in history:
+ * 1) rx-descriptors posted (and received)
+ *    Both of these events are stored on the same entry
+ *    @paddr : physical address posted on the ring
+ *    @nbuf  : virtual address of nbuf containing data
+ *    @ndata : virual address of data (corresponds to physical address)
+ *    @posted: time-stamp when the buffer is posted to the ring
+ *    @recved: time-stamp when the buffer is received (rx_in_order_ind)
+ *           : or 0, if the buffer has not been received yet
+ * 2) ring alloc-index (fill-index) updates
+ *    @paddr : = 0
+ *    @nbuf  : = 0
+ *    @ndata : = 0
+ *    posted : time-stamp when alloc index was updated
+ *    recved : value of alloc index
+ * 3) htt_rx_in_order_indication reception
+ *    @paddr : = 0
+ *    @nbuf  : = 0
+ *    @ndata : msdu_cnt
+ *    @posted: time-stamp when HTT message is recived
+ *    @recvd : 0x48545452584D5367 ('HTTRXMSG')
+ */
+#define HTT_RX_RING_BUFF_DBG_LIST          (2 * 1024)
+struct rx_buf_debug {
+	qdf_dma_addr_t paddr;
+	qdf_nbuf_t     nbuf;
+	void          *nbuf_data;
+	uint64_t       posted; /* timetamp */
+	uint64_t       recved; /* timestamp */
+	int            cpu;
+
+};
+#endif
+
+static inline struct htt_host_rx_desc_base *htt_rx_desc(qdf_nbuf_t msdu)
+{
+	return (struct htt_host_rx_desc_base *)
+	       (((size_t) (qdf_nbuf_head(msdu) + HTT_RX_DESC_ALIGN_MASK)) &
+		~HTT_RX_DESC_ALIGN_MASK);
+}
+
+#if defined(HELIUMPLUS)
+/**
+ * htt_print_rx_desc_lro() - print LRO information in the rx
+ * descriptor
+ * @rx_desc: HTT rx descriptor
+ *
+ * Prints the LRO related fields in the HTT rx descriptor
+ *
+ * Return: none
+ */
+static inline void htt_print_rx_desc_lro(struct htt_host_rx_desc_base *rx_desc)
+{
+	qdf_nofl_info
+		("----------------------RX DESC LRO----------------------\n");
+	qdf_nofl_info("msdu_end.lro_eligible:0x%x\n",
+		      rx_desc->msdu_end.lro_eligible);
+	qdf_nofl_info("msdu_start.tcp_only_ack:0x%x\n",
+		      rx_desc->msdu_start.tcp_only_ack);
+	qdf_nofl_info("msdu_end.tcp_udp_chksum:0x%x\n",
+		      rx_desc->msdu_end.tcp_udp_chksum);
+	qdf_nofl_info("msdu_end.tcp_seq_number:0x%x\n",
+		      rx_desc->msdu_end.tcp_seq_number);
+	qdf_nofl_info("msdu_end.tcp_ack_number:0x%x\n",
+		      rx_desc->msdu_end.tcp_ack_number);
+	qdf_nofl_info("msdu_start.tcp_proto:0x%x\n",
+		      rx_desc->msdu_start.tcp_proto);
+	qdf_nofl_info("msdu_start.ipv6_proto:0x%x\n",
+		      rx_desc->msdu_start.ipv6_proto);
+	qdf_nofl_info("msdu_start.ipv4_proto:0x%x\n",
+		      rx_desc->msdu_start.ipv4_proto);
+	qdf_nofl_info("msdu_start.l3_offset:0x%x\n",
+		      rx_desc->msdu_start.l3_offset);
+	qdf_nofl_info("msdu_start.l4_offset:0x%x\n",
+		      rx_desc->msdu_start.l4_offset);
+	qdf_nofl_info("msdu_start.flow_id_toeplitz:0x%x\n",
+		      rx_desc->msdu_start.flow_id_toeplitz);
+	qdf_nofl_info
+		("---------------------------------------------------------\n");
+}
+
+/**
+ * htt_print_rx_desc_lro() - extract LRO information from the rx
+ * descriptor
+ * @msdu: network buffer
+ * @rx_desc: HTT rx descriptor
+ *
+ * Extracts the LRO related fields from the HTT rx descriptor
+ * and stores them in the network buffer's control block
+ *
+ * Return: none
+ */
+static inline void htt_rx_extract_lro_info(qdf_nbuf_t msdu,
+	 struct htt_host_rx_desc_base *rx_desc)
+{
+	if (rx_desc->attention.tcp_udp_chksum_fail)
+		QDF_NBUF_CB_RX_LRO_ELIGIBLE(msdu) = 0;
+	else
+		QDF_NBUF_CB_RX_LRO_ELIGIBLE(msdu) =
+			rx_desc->msdu_end.lro_eligible;
+
+	if (QDF_NBUF_CB_RX_LRO_ELIGIBLE(msdu)) {
+		QDF_NBUF_CB_RX_TCP_PURE_ACK(msdu) =
+			rx_desc->msdu_start.tcp_only_ack;
+		QDF_NBUF_CB_RX_TCP_CHKSUM(msdu) =
+			rx_desc->msdu_end.tcp_udp_chksum;
+		QDF_NBUF_CB_RX_TCP_SEQ_NUM(msdu) =
+			rx_desc->msdu_end.tcp_seq_number;
+		QDF_NBUF_CB_RX_TCP_ACK_NUM(msdu) =
+			rx_desc->msdu_end.tcp_ack_number;
+		QDF_NBUF_CB_RX_TCP_WIN(msdu) =
+			rx_desc->msdu_end.window_size;
+		QDF_NBUF_CB_RX_TCP_PROTO(msdu) =
+			rx_desc->msdu_start.tcp_proto;
+		QDF_NBUF_CB_RX_IPV6_PROTO(msdu) =
+			rx_desc->msdu_start.ipv6_proto;
+		QDF_NBUF_CB_RX_TCP_OFFSET(msdu) =
+			rx_desc->msdu_start.l4_offset;
+		QDF_NBUF_CB_RX_FLOW_ID(msdu) =
+			rx_desc->msdu_start.flow_id_toeplitz;
+	}
+}
+#else
+static inline void htt_print_rx_desc_lro(struct htt_host_rx_desc_base *rx_desc)
+{}
+static inline void htt_rx_extract_lro_info(qdf_nbuf_t msdu,
+	 struct htt_host_rx_desc_base *rx_desc) {}
+#endif /* HELIUMPLUS */
+
+static inline void htt_print_rx_desc(struct htt_host_rx_desc_base *rx_desc)
+{
+	qdf_nofl_info
+		("----------------------RX DESC----------------------------\n");
+	qdf_nofl_info("attention: %#010x\n",
+		      (unsigned int)(*(uint32_t *)&rx_desc->attention));
+	qdf_nofl_info("frag_info: %#010x\n",
+		      (unsigned int)(*(uint32_t *)&rx_desc->frag_info));
+	qdf_nofl_info("mpdu_start: %#010x %#010x %#010x\n",
+		      (unsigned int)(((uint32_t *)&rx_desc->mpdu_start)[0]),
+		      (unsigned int)(((uint32_t *)&rx_desc->mpdu_start)[1]),
+		      (unsigned int)(((uint32_t *)&rx_desc->mpdu_start)[2]));
+	qdf_nofl_info("msdu_start: %#010x %#010x %#010x\n",
+		      (unsigned int)(((uint32_t *)&rx_desc->msdu_start)[0]),
+		      (unsigned int)(((uint32_t *)&rx_desc->msdu_start)[1]),
+		      (unsigned int)(((uint32_t *)&rx_desc->msdu_start)[2]));
+	qdf_nofl_info("msdu_end: %#010x %#010x %#010x %#010x %#010x\n",
+		      (unsigned int)(((uint32_t *)&rx_desc->msdu_end)[0]),
+		      (unsigned int)(((uint32_t *)&rx_desc->msdu_end)[1]),
+		      (unsigned int)(((uint32_t *)&rx_desc->msdu_end)[2]),
+		      (unsigned int)(((uint32_t *)&rx_desc->msdu_end)[3]),
+		      (unsigned int)(((uint32_t *)&rx_desc->msdu_end)[4]));
+	qdf_nofl_info("mpdu_end: %#010x\n",
+		      (unsigned int)(*(uint32_t *)&rx_desc->mpdu_end));
+	qdf_nofl_info("ppdu_start: %#010x %#010x %#010x %#010x %#010x\n"
+		      "%#010x %#010x %#010x %#010x %#010x\n",
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_start)[0]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_start)[1]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_start)[2]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_start)[3]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_start)[4]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_start)[5]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_start)[6]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_start)[7]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_start)[8]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_start)[9]));
+	qdf_nofl_info("ppdu_end: %#010x %#010x %#010x %#010x %#010x\n"
+		      "%#010x %#010x %#010x %#010x %#010x\n"
+		      "%#010x,%#010x %#010x %#010x %#010x\n"
+		      "%#010x %#010x %#010x %#010x %#010x\n" "%#010x %#010x\n",
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[0]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[1]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[2]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[3]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[4]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[5]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[6]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[7]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[8]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[9]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[10]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[11]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[12]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[13]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[14]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[15]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[16]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[17]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[18]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[19]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[20]),
+		      (unsigned int)(((uint32_t *)&rx_desc->ppdu_end)[21]));
+	qdf_nofl_info
+		("---------------------------------------------------------\n");
+}
+
+#ifndef HTT_ASSERT_LEVEL
+#define HTT_ASSERT_LEVEL 3
+#endif
+
+#define HTT_ASSERT_ALWAYS(condition) qdf_assert_always((condition))
+
+#define HTT_ASSERT0(condition) qdf_assert((condition))
+#if HTT_ASSERT_LEVEL > 0
+#define HTT_ASSERT1(condition) qdf_assert((condition))
+#else
+#define HTT_ASSERT1(condition)
+#endif
+
+#if HTT_ASSERT_LEVEL > 1
+#define HTT_ASSERT2(condition) qdf_assert((condition))
+#else
+#define HTT_ASSERT2(condition)
+#endif
+
+#if HTT_ASSERT_LEVEL > 2
+#define HTT_ASSERT3(condition) qdf_assert((condition))
+#else
+#define HTT_ASSERT3(condition)
+#endif
+
+#define HTT_MAC_ADDR_LEN 6
+
+/*
+ * HTT_MAX_SEND_QUEUE_DEPTH -
+ * How many packets HTC should allow to accumulate in a send queue
+ * before calling the EpSendFull callback to see whether to retain
+ * or drop packets.
+ * This is not relevant for LL, where tx descriptors should be immediately
+ * downloaded to the target.
+ * This is not very relevant for HL either, since it is anticipated that
+ * the HL tx download scheduler will not work this far in advance - rather,
+ * it will make its decisions just-in-time, so it can be responsive to
+ * changing conditions.
+ * Hence, this queue depth threshold spec is mostly just a formality.
+ */
+#define HTT_MAX_SEND_QUEUE_DEPTH 64
+
+#define IS_PWR2(value) (((value) ^ ((value)-1)) == ((value) << 1) - 1)
+
+/*
+ * HTT_RX_PRE_ALLOC_POOL_SIZE -
+ * How many Rx Buffer should be there in pre-allocated pool of buffers.
+ * This is mainly for low memory condition where kernel fails to alloc
+ * SKB buffer to the Rx ring.
+ */
+#define HTT_RX_PRE_ALLOC_POOL_SIZE 64
+/* Max rx MSDU size including L2 headers */
+#define MSDU_SIZE 1560
+/* Rounding up to a cache line size. */
+#define HTT_RX_BUF_SIZE  roundup(MSDU_SIZE +				\
+				 sizeof(struct htt_host_rx_desc_base),	\
+				 QDF_CACHE_LINE_SZ)
+#define MAX_RX_PAYLOAD_SZ (HTT_RX_BUF_SIZE - RX_STD_DESC_SIZE)
+/*
+ * DMA_MAP expects the buffer to be an integral number of cache lines.
+ * Rather than checking the actual cache line size, this code makes a
+ * conservative estimate of what the cache line size could be.
+ */
+#define HTT_LOG2_MAX_CACHE_LINE_SIZE 7  /* 2^7 = 128 */
+#define HTT_MAX_CACHE_LINE_SIZE_MASK ((1 << HTT_LOG2_MAX_CACHE_LINE_SIZE) - 1)
+
+#ifdef BIG_ENDIAN_HOST
+/*
+ * big-endian: bytes within a 4-byte "word" are swapped:
+ * pre-swap  post-swap
+ *  index     index
+ *    0         3
+ *    1         2
+ *    2         1
+ *    3         0
+ *    4         7
+ *    5         6
+ * etc.
+ * To compute the post-swap index from the pre-swap index, compute
+ * the byte offset for the start of the word (index & ~0x3) and add
+ * the swapped byte offset within the word (3 - (index & 0x3)).
+ */
+#define HTT_ENDIAN_BYTE_IDX_SWAP(idx) (((idx) & ~0x3) + (3 - ((idx) & 0x3)))
+#else
+/* little-endian: no adjustment needed */
+#define HTT_ENDIAN_BYTE_IDX_SWAP(idx) idx
+#endif
+
+#define HTT_TX_MUTEX_INIT(_mutex)			\
+	qdf_spinlock_create(_mutex)
+
+#define HTT_TX_MUTEX_ACQUIRE(_mutex)			\
+	qdf_spin_lock_bh(_mutex)
+
+#define HTT_TX_MUTEX_RELEASE(_mutex)			\
+	qdf_spin_unlock_bh(_mutex)
+
+#define HTT_TX_MUTEX_DESTROY(_mutex)			\
+	qdf_spinlock_destroy(_mutex)
+
+#define HTT_TX_DESC_PADDR(_pdev, _tx_desc_vaddr)       \
+	((_pdev)->tx_descs.pool_paddr +  (uint32_t)	  \
+	 ((char *)(_tx_desc_vaddr) -			   \
+	  (char *)((_pdev)->tx_descs.pool_vaddr)))
+
+#ifdef ATH_11AC_TXCOMPACT
+
+#define HTT_TX_NBUF_QUEUE_MUTEX_INIT(_pdev)		\
+	qdf_spinlock_create(&_pdev->txnbufq_mutex)
+
+#define HTT_TX_NBUF_QUEUE_MUTEX_DESTROY(_pdev)	       \
+	HTT_TX_MUTEX_DESTROY(&_pdev->txnbufq_mutex)
+
+#define HTT_TX_NBUF_QUEUE_REMOVE(_pdev, _msdu)	do {	\
+	HTT_TX_MUTEX_ACQUIRE(&_pdev->txnbufq_mutex);	\
+	_msdu =  qdf_nbuf_queue_remove(&_pdev->txnbufq);\
+	HTT_TX_MUTEX_RELEASE(&_pdev->txnbufq_mutex);    \
+	} while (0)
+
+#define HTT_TX_NBUF_QUEUE_ADD(_pdev, _msdu) do {	\
+	HTT_TX_MUTEX_ACQUIRE(&_pdev->txnbufq_mutex);	\
+	qdf_nbuf_queue_add(&_pdev->txnbufq, _msdu);     \
+	HTT_TX_MUTEX_RELEASE(&_pdev->txnbufq_mutex);    \
+	} while (0)
+
+#define HTT_TX_NBUF_QUEUE_INSERT_HEAD(_pdev, _msdu) do {   \
+	HTT_TX_MUTEX_ACQUIRE(&_pdev->txnbufq_mutex);	   \
+	qdf_nbuf_queue_insert_head(&_pdev->txnbufq, _msdu);\
+	HTT_TX_MUTEX_RELEASE(&_pdev->txnbufq_mutex);       \
+	} while (0)
+#else
+
+#define HTT_TX_NBUF_QUEUE_MUTEX_INIT(_pdev)
+#define HTT_TX_NBUF_QUEUE_REMOVE(_pdev, _msdu)
+#define HTT_TX_NBUF_QUEUE_ADD(_pdev, _msdu)
+#define HTT_TX_NBUF_QUEUE_INSERT_HEAD(_pdev, _msdu)
+#define HTT_TX_NBUF_QUEUE_MUTEX_DESTROY(_pdev)
+
+#endif
+
+#ifdef CONFIG_HL_SUPPORT
+
+static inline void htt_tx_resume_handler(void *context)
+{
+}
+#else
+
+void htt_tx_resume_handler(void *context);
+#endif
+
+#ifdef ATH_11AC_TXCOMPACT
+#define HTT_TX_SCHED htt_tx_sched
+#else
+#define HTT_TX_SCHED(pdev)      /* no-op */
+#endif
+
+int htt_tx_attach(struct htt_pdev_t *pdev, int desc_pool_elems);
+
+void htt_tx_detach(struct htt_pdev_t *pdev);
+
+int htt_rx_attach(struct htt_pdev_t *pdev);
+
+#if defined(CONFIG_HL_SUPPORT)
+
+static inline void htt_rx_detach(struct htt_pdev_t *pdev)
+{
+}
+#else
+
+void htt_rx_detach(struct htt_pdev_t *pdev);
+#endif
+
+int htt_htc_attach(struct htt_pdev_t *pdev, uint16_t service_id);
+
+void htt_t2h_msg_handler(void *context, HTC_PACKET *pkt);
+#ifdef WLAN_FEATURE_FASTPATH
+void htt_t2h_msg_handler_fast(void *htt_pdev, qdf_nbuf_t *cmpl_msdus,
+			      uint32_t num_cmpls);
+#else
+static inline void htt_t2h_msg_handler_fast(void *htt_pdev,
+					   qdf_nbuf_t *cmpl_msdus,
+					   uint32_t num_cmpls)
+{
+}
+#endif
+
+void htt_h2t_send_complete(void *context, HTC_PACKET *pkt);
+
+QDF_STATUS htt_h2t_ver_req_msg(struct htt_pdev_t *pdev);
+
+#if defined(HELIUMPLUS)
+QDF_STATUS
+htt_h2t_frag_desc_bank_cfg_msg(struct htt_pdev_t *pdev);
+#endif /* defined(HELIUMPLUS) */
+
+extern QDF_STATUS htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev);
+
+extern QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_ll(struct htt_pdev_t *pdev);
+
+extern QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_hl(struct htt_pdev_t *pdev);
+
+extern QDF_STATUS htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t *pdev);
+
+extern QDF_STATUS (*htt_h2t_rx_ring_cfg_msg)(struct htt_pdev_t *pdev);
+
+enum htc_send_full_action htt_h2t_full(void *context, HTC_PACKET *pkt);
+
+struct htt_htc_pkt *htt_htc_pkt_alloc(struct htt_pdev_t *pdev);
+
+void htt_htc_pkt_free(struct htt_pdev_t *pdev, struct htt_htc_pkt *pkt);
+
+void htt_htc_pkt_pool_free(struct htt_pdev_t *pdev);
+
+#ifdef ATH_11AC_TXCOMPACT
+void htt_htc_misc_pkt_list_trim(struct htt_pdev_t *pdev, int level);
+
+void
+htt_htc_misc_pkt_list_add(struct htt_pdev_t *pdev, struct htt_htc_pkt *pkt);
+
+void htt_htc_misc_pkt_pool_free(struct htt_pdev_t *pdev);
+#endif
+
+#ifdef WLAN_FULL_REORDER_OFFLOAD
+int
+htt_rx_hash_list_insert(struct htt_pdev_t *pdev,
+			qdf_dma_addr_t paddr,
+			qdf_nbuf_t netbuf);
+#else
+static inline int
+htt_rx_hash_list_insert(struct htt_pdev_t *pdev,
+			qdf_dma_addr_t paddr,
+			qdf_nbuf_t netbuf)
+{
+	return 0;
+}
+#endif
+
+qdf_nbuf_t
+htt_rx_hash_list_lookup(struct htt_pdev_t *pdev, qdf_dma_addr_t paddr);
+
+#ifdef IPA_OFFLOAD
+int
+htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev,
+		     unsigned int uc_tx_buf_sz,
+		     unsigned int uc_tx_buf_cnt,
+		     unsigned int uc_tx_partition_base);
+
+int
+htt_rx_ipa_uc_attach(struct htt_pdev_t *pdev, unsigned int rx_ind_ring_size);
+
+int htt_tx_ipa_uc_detach(struct htt_pdev_t *pdev);
+
+int htt_rx_ipa_uc_detach(struct htt_pdev_t *pdev);
+
+#else
+/**
+ * htt_tx_ipa_uc_attach() - attach htt ipa uc tx resource
+ * @pdev: htt context
+ * @uc_tx_buf_sz: single tx buffer size
+ * @uc_tx_buf_cnt: total tx buffer count
+ * @uc_tx_partition_base: tx buffer partition start
+ *
+ * Return: 0 success
+ */
+static inline int
+htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev,
+		     unsigned int uc_tx_buf_sz,
+		     unsigned int uc_tx_buf_cnt,
+		     unsigned int uc_tx_partition_base)
+{
+	return 0;
+}
+
+/**
+ * htt_rx_ipa_uc_attach() - attach htt ipa uc rx resource
+ * @pdev: htt context
+ * @rx_ind_ring_size: rx ring size
+ *
+ * Return: 0 success
+ */
+static inline int
+htt_rx_ipa_uc_attach(struct htt_pdev_t *pdev, unsigned int rx_ind_ring_size)
+{
+	return 0;
+}
+
+static inline int htt_tx_ipa_uc_detach(struct htt_pdev_t *pdev)
+{
+	return 0;
+}
+
+static inline int htt_rx_ipa_uc_detach(struct htt_pdev_t *pdev)
+{
+	return 0;
+}
+
+#endif /* IPA_OFFLOAD */
+
+/* Maximum Outstanding Bus Download */
+#define HTT_MAX_BUS_CREDIT 33
+
+#ifdef CONFIG_HL_SUPPORT
+
+/**
+ * htt_tx_credit_update() - check for diff in bus delta and target delta
+ * @pdev: pointer to htt device.
+ *
+ * Return: min of bus delta and target delta
+ */
+int
+htt_tx_credit_update(struct htt_pdev_t *pdev);
+#else
+
+static inline int
+htt_tx_credit_update(struct htt_pdev_t *pdev)
+{
+	return 0;
+}
+#endif
+
+
+#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+
+#define HTT_TX_GROUP_INDEX_OFFSET \
+(sizeof(struct htt_txq_group) / sizeof(u_int32_t))
+
+void htt_tx_group_credit_process(struct htt_pdev_t *pdev, u_int32_t *msg_word);
+#else
+
+static inline
+void htt_tx_group_credit_process(struct htt_pdev_t *pdev, u_int32_t *msg_word)
+{
+}
+#endif
+
+#ifdef DEBUG_RX_RING_BUFFER
+/**
+ * htt_rx_dbg_rxbuf_init() - init debug rx buff list
+ * @pdev: pdev handle
+ *
+ * Allocation is done from bss segment. This uses vmalloc and has a bit
+ * of an overhead compared to kmalloc (which qdf_mem_alloc wraps). The impact
+ * of the overhead to performance will need to be quantified.
+ *
+ * Return: none
+ */
+static struct rx_buf_debug rx_buff_list_bss[HTT_RX_RING_BUFF_DBG_LIST];
+static inline
+void htt_rx_dbg_rxbuf_init(struct htt_pdev_t *pdev)
+{
+	pdev->rx_buff_list = rx_buff_list_bss;
+	qdf_spinlock_create(&(pdev->rx_buff_list_lock));
+	pdev->rx_buff_index = 0;
+	pdev->rx_buff_posted_cum = 0;
+	pdev->rx_buff_recvd_cum  = 0;
+	pdev->rx_buff_recvd_err  = 0;
+	pdev->refill_retry_timer_starts = 0;
+	pdev->refill_retry_timer_calls = 0;
+	pdev->refill_retry_timer_doubles = 0;
+}
+
+/**
+ * htt_display_rx_buf_debug() - display debug rx buff list and some counters
+ * @pdev: pdev handle
+ *
+ * Return: Success
+ */
+static inline int htt_display_rx_buf_debug(struct htt_pdev_t *pdev)
+{
+	int i;
+	struct rx_buf_debug *buf;
+
+	if ((pdev != NULL) &&
+	    (pdev->rx_buff_list != NULL)) {
+		buf = pdev->rx_buff_list;
+		for (i = 0; i < HTT_RX_RING_BUFF_DBG_LIST; i++) {
+			if (buf[i].posted != 0)
+				qdf_nofl_info("[%d][0x%x] %pK %lu %pK %llu %llu",
+					      i, buf[i].cpu,
+					      buf[i].nbuf_data,
+					      (unsigned long)buf[i].paddr,
+					      buf[i].nbuf,
+					      buf[i].posted,
+					      buf[i].recved);
+		}
+
+		qdf_nofl_info("rxbuf_idx %d all_posted: %d all_recvd: %d recv_err: %d",
+			      pdev->rx_buff_index,
+			      pdev->rx_buff_posted_cum,
+			      pdev->rx_buff_recvd_cum,
+			      pdev->rx_buff_recvd_err);
+
+		qdf_nofl_info("timer kicks :%d actual  :%d restarts:%d debtors: %d fill_n: %d",
+			      pdev->refill_retry_timer_starts,
+			      pdev->refill_retry_timer_calls,
+			      pdev->refill_retry_timer_doubles,
+			      pdev->rx_buff_debt_invoked,
+			      pdev->rx_buff_fill_n_invoked);
+	} else
+		return -EINVAL;
+	return 0;
+}
+
+/**
+ * htt_rx_dbg_rxbuf_set() - set element of rx buff list
+ * @pdev: pdev handle
+ * @paddr: physical address of netbuf
+ * @rx_netbuf: received netbuf
+ *
+ * Return: none
+ */
+static inline
+void htt_rx_dbg_rxbuf_set(struct htt_pdev_t *pdev, qdf_dma_addr_t paddr,
+			  qdf_nbuf_t rx_netbuf)
+{
+	if (pdev->rx_buff_list) {
+		qdf_spin_lock_bh(&(pdev->rx_buff_list_lock));
+		pdev->rx_buff_list[pdev->rx_buff_index].paddr = paddr;
+		pdev->rx_buff_list[pdev->rx_buff_index].nbuf  = rx_netbuf;
+		pdev->rx_buff_list[pdev->rx_buff_index].nbuf_data =
+							rx_netbuf->data;
+		pdev->rx_buff_list[pdev->rx_buff_index].posted =
+						qdf_get_log_timestamp();
+		pdev->rx_buff_posted_cum++;
+		pdev->rx_buff_list[pdev->rx_buff_index].recved = 0;
+		pdev->rx_buff_list[pdev->rx_buff_index].cpu =
+				(1 << qdf_get_cpu());
+		NBUF_MAP_ID(rx_netbuf) = pdev->rx_buff_index;
+		if (++pdev->rx_buff_index >=
+				HTT_RX_RING_BUFF_DBG_LIST)
+			pdev->rx_buff_index = 0;
+		qdf_spin_unlock_bh(&(pdev->rx_buff_list_lock));
+	}
+}
+
+/**
+ * htt_rx_dbg_rxbuf_set() - reset element of rx buff list
+ * @pdev: pdev handle
+ * @netbuf: rx sk_buff
+ * Return: none
+ */
+static inline
+void htt_rx_dbg_rxbuf_reset(struct htt_pdev_t *pdev,
+				qdf_nbuf_t netbuf)
+{
+	uint32_t index;
+
+	if (pdev->rx_buff_list) {
+		qdf_spin_lock_bh(&(pdev->rx_buff_list_lock));
+		index = NBUF_MAP_ID(netbuf);
+		if (index < HTT_RX_RING_BUFF_DBG_LIST) {
+			pdev->rx_buff_list[index].recved =
+				qdf_get_log_timestamp();
+			pdev->rx_buff_recvd_cum++;
+		} else {
+			pdev->rx_buff_recvd_err++;
+		}
+		pdev->rx_buff_list[pdev->rx_buff_index].cpu |=
+				(1 << qdf_get_cpu());
+		qdf_spin_unlock_bh(&(pdev->rx_buff_list_lock));
+	}
+}
+/**
+ * htt_rx_dbg_rxbuf_indupd() - add a record for alloc index update
+ * @pdev: pdev handle
+ * @idx : value of the index
+ *
+ * Return: none
+ */
+static inline
+void htt_rx_dbg_rxbuf_indupd(struct htt_pdev_t *pdev, int alloc_index)
+{
+	if (pdev->rx_buff_list) {
+		qdf_spin_lock_bh(&(pdev->rx_buff_list_lock));
+		pdev->rx_buff_list[pdev->rx_buff_index].paddr = 0;
+		pdev->rx_buff_list[pdev->rx_buff_index].nbuf  = 0;
+		pdev->rx_buff_list[pdev->rx_buff_index].nbuf_data = 0;
+		pdev->rx_buff_list[pdev->rx_buff_index].posted =
+						qdf_get_log_timestamp();
+		pdev->rx_buff_list[pdev->rx_buff_index].recved =
+			(uint64_t)alloc_index;
+		pdev->rx_buff_list[pdev->rx_buff_index].cpu =
+				(1 << qdf_get_cpu());
+		if (++pdev->rx_buff_index >=
+				HTT_RX_RING_BUFF_DBG_LIST)
+			pdev->rx_buff_index = 0;
+		qdf_spin_unlock_bh(&(pdev->rx_buff_list_lock));
+	}
+}
+/**
+ * htt_rx_dbg_rxbuf_httrxind() - add a record for recipt of htt rx_ind msg
+ * @pdev: pdev handle
+ *
+ * Return: none
+ */
+static inline
+void htt_rx_dbg_rxbuf_httrxind(struct htt_pdev_t *pdev, unsigned int msdu_cnt)
+{
+	if (pdev->rx_buff_list) {
+		qdf_spin_lock_bh(&(pdev->rx_buff_list_lock));
+		pdev->rx_buff_list[pdev->rx_buff_index].paddr = msdu_cnt;
+		pdev->rx_buff_list[pdev->rx_buff_index].nbuf  = 0;
+		pdev->rx_buff_list[pdev->rx_buff_index].nbuf_data = 0;
+		pdev->rx_buff_list[pdev->rx_buff_index].posted =
+						qdf_get_log_timestamp();
+		pdev->rx_buff_list[pdev->rx_buff_index].recved =
+			(uint64_t)0x48545452584D5347; /* 'HTTRXMSG' */
+		pdev->rx_buff_list[pdev->rx_buff_index].cpu =
+				(1 << qdf_get_cpu());
+		if (++pdev->rx_buff_index >=
+				HTT_RX_RING_BUFF_DBG_LIST)
+			pdev->rx_buff_index = 0;
+		qdf_spin_unlock_bh(&(pdev->rx_buff_list_lock));
+	}
+}
+
+/**
+ * htt_rx_dbg_rxbuf_deinit() - deinit debug rx buff list
+ * @pdev: pdev handle
+ *
+ * Return: none
+ */
+static inline
+void htt_rx_dbg_rxbuf_deinit(struct htt_pdev_t *pdev)
+{
+	if (pdev->rx_buff_list)
+		pdev->rx_buff_list = NULL;
+	qdf_spinlock_destroy(&(pdev->rx_buff_list_lock));
+}
+#else
+static inline
+void htt_rx_dbg_rxbuf_init(struct htt_pdev_t *pdev)
+{
+}
+static inline int htt_display_rx_buf_debug(struct htt_pdev_t *pdev)
+{
+	return 0;
+}
+
+static inline
+void htt_rx_dbg_rxbuf_set(struct htt_pdev_t *pdev,
+				uint32_t paddr,
+				qdf_nbuf_t rx_netbuf)
+{
+}
+static inline
+void htt_rx_dbg_rxbuf_reset(struct htt_pdev_t *pdev,
+				qdf_nbuf_t netbuf)
+{
+}
+static inline
+void htt_rx_dbg_rxbuf_indupd(struct htt_pdev_t *pdev,
+			     int    alloc_index)
+{
+}
+static inline
+void htt_rx_dbg_rxbuf_httrxind(struct htt_pdev_t *pdev,
+			       unsigned int msdu_cnt)
+{
+}
+static inline
+void htt_rx_dbg_rxbuf_deinit(struct htt_pdev_t *pdev)
+{
+	return;
+}
+#endif
+
+#ifndef HTT_RX_RING_SIZE_MIN
+#define HTT_RX_RING_SIZE_MIN 128        /* slightly > than one large A-MPDU */
+#endif
+
+#ifndef HTT_RX_RING_SIZE_MAX
+#define HTT_RX_RING_SIZE_MAX 2048       /* ~20 ms @ 1 Gbps of 1500B MSDUs */
+#endif
+
+#ifndef HTT_RX_AVG_FRM_BYTES
+#define HTT_RX_AVG_FRM_BYTES 1000
+#endif
+
+#define HTT_FCS_LEN (4)
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+#ifdef HTT_DEBUG_DATA
+#define HTT_PKT_DUMP(x) x
+#else
+#define HTT_PKT_DUMP(x) /* no-op */
+#endif
+
+#ifdef RX_HASH_DEBUG
+#define HTT_RX_CHECK_MSDU_COUNT(msdu_count) HTT_ASSERT_ALWAYS(msdu_count)
+#else
+#define HTT_RX_CHECK_MSDU_COUNT(msdu_count)     /* no-op */
+#endif
+
+#if HTT_PADDR64
+#define NEXT_FIELD_OFFSET_IN32 2
+#else /* ! HTT_PADDR64 */
+#define NEXT_FIELD_OFFSET_IN32 1
+#endif /* HTT_PADDR64 */
+
+#define RX_PADDR_MAGIC_PATTERN 0xDEAD0000
+
+#if HTT_PADDR64
+static inline qdf_dma_addr_t htt_paddr_trim_to_37(qdf_dma_addr_t paddr)
+{
+	qdf_dma_addr_t ret = paddr;
+
+	if (sizeof(paddr) > 4)
+		ret &= 0x1fffffffff;
+	return ret;
+}
+#else /* not 64 bits */
+static inline qdf_dma_addr_t htt_paddr_trim_to_37(qdf_dma_addr_t paddr)
+{
+	return paddr;
+}
+#endif /* HTT_PADDR64 */
+
+#ifdef WLAN_FULL_REORDER_OFFLOAD
+#ifdef ENABLE_DEBUG_ADDRESS_MARKING
+static inline qdf_dma_addr_t
+htt_rx_paddr_unmark_high_bits(qdf_dma_addr_t paddr)
+{
+	uint32_t markings;
+
+	if (sizeof(qdf_dma_addr_t) > 4) {
+		markings = (uint32_t)((paddr >> 16) >> 16);
+		/*
+		 * check if it is marked correctly:
+		 * See the mark_high_bits function above for the expected
+		 * pattern.
+		 * the LS 5 bits are the high bits of physical address
+		 * padded (with 0b0) to 8 bits
+		 */
+		if ((markings & 0xFFFF0000) != RX_PADDR_MAGIC_PATTERN) {
+			qdf_print("%s: paddr not marked correctly: 0x%pK!\n",
+				  __func__, (void *)paddr);
+			HTT_ASSERT_ALWAYS(0);
+		}
+
+		/* clear markings  for further use */
+		paddr = htt_paddr_trim_to_37(paddr);
+	}
+	return paddr;
+}
+
+static inline
+qdf_dma_addr_t htt_rx_in_ord_paddr_get(uint32_t *u32p)
+{
+	qdf_dma_addr_t paddr = 0;
+
+	paddr = (qdf_dma_addr_t)HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p);
+	if (sizeof(qdf_dma_addr_t) > 4) {
+		u32p++;
+		/* 32 bit architectures dont like <<32 */
+		paddr |= (((qdf_dma_addr_t)
+			  HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p))
+			  << 16 << 16);
+	}
+	paddr = htt_rx_paddr_unmark_high_bits(paddr);
+
+	return paddr;
+}
+#else
+#if HTT_PADDR64
+static inline
+qdf_dma_addr_t htt_rx_in_ord_paddr_get(uint32_t *u32p)
+{
+	qdf_dma_addr_t paddr = 0;
+
+	paddr = (qdf_dma_addr_t)HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p);
+	if (sizeof(qdf_dma_addr_t) > 4) {
+		u32p++;
+		/* 32 bit architectures dont like <<32 */
+		paddr |= (((qdf_dma_addr_t)
+			  HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p))
+			  << 16 << 16);
+	}
+	return paddr;
+}
+#else
+static inline
+qdf_dma_addr_t htt_rx_in_ord_paddr_get(uint32_t *u32p)
+{
+	return HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p);
+}
+#endif
+#endif /* ENABLE_DEBUG_ADDRESS_MARKING */
+
+static inline
+unsigned int htt_rx_in_order_ring_elems(struct htt_pdev_t *pdev)
+{
+	return (*pdev->rx_ring.alloc_idx.vaddr -
+		*pdev->rx_ring.target_idx.vaddr) &
+		pdev->rx_ring.size_mask;
+}
+
+static inline qdf_nbuf_t
+htt_rx_in_order_netbuf_pop(htt_pdev_handle pdev, qdf_dma_addr_t paddr)
+{
+	HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0);
+	pdev->rx_ring.fill_cnt--;
+	paddr = htt_paddr_trim_to_37(paddr);
+	return htt_rx_hash_list_lookup(pdev, paddr);
+}
+
+#else
+static inline
+qdf_dma_addr_t htt_rx_in_ord_paddr_get(uint32_t *u32p)
+{
+	return 0;
+}
+
+static inline qdf_nbuf_t
+htt_rx_in_order_netbuf_pop(htt_pdev_handle pdev, qdf_dma_addr_t paddr)
+{
+	return NULL;
+}
+#endif
+
+#if defined(FEATURE_MONITOR_MODE_SUPPORT) && defined(WLAN_FULL_REORDER_OFFLOAD)
+int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
+					qdf_nbuf_t rx_ind_msg,
+					qdf_nbuf_t *head_msdu,
+					qdf_nbuf_t *tail_msdu,
+					uint32_t *replenish_cnt);
+#else
+static inline
+int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
+					qdf_nbuf_t rx_ind_msg,
+					qdf_nbuf_t *head_msdu,
+					qdf_nbuf_t *tail_msdu,
+					uint32_t *replenish_cnt)
+{
+	return 0;
+}
+#endif
+
+#endif /* _HTT_INTERNAL__H_ */
diff --git a/core/dp/htt/htt_monitor_rx.c b/core/dp/htt/htt_monitor_rx.c
new file mode 100644
index 0000000..d49c888
--- /dev/null
+++ b/core/dp/htt/htt_monitor_rx.c
@@ -0,0 +1,1087 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#include <qdf_mem.h>         /* qdf_mem_malloc,free, etc. */
+#include <qdf_types.h>          /* qdf_print, bool */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_timer.h>		/* qdf_timer_free */
+
+#include <htt.h>                /* HTT_HL_RX_DESC_SIZE */
+#include <ol_cfg.h>
+#include <ol_rx.h>
+#include <ol_htt_rx_api.h>
+#include <htt_internal.h>       /* HTT_ASSERT, htt_pdev_t, HTT_RX_BUF_SIZE */
+#include "regtable.h"
+
+#include <cds_ieee80211_common.h>   /* ieee80211_frame, ieee80211_qoscntl */
+#include <cds_ieee80211_defines.h>  /* ieee80211_rx_status */
+#include <cds_utils.h>
+#include <wlan_policy_mgr_api.h>
+#include "ol_txrx_types.h"
+#ifdef DEBUG_DMA_DONE
+#include <asm/barrier.h>
+#include <wma_api.h>
+#endif
+#include <pktlog_ac_fmt.h>
+
+#define HTT_FCS_LEN (4)
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+enum {
+	HW_RX_DECAP_FORMAT_RAW = 0,
+	HW_RX_DECAP_FORMAT_NWIFI,
+	HW_RX_DECAP_FORMAT_8023,
+	HW_RX_DECAP_FORMAT_ETH2,
+};
+
+/**
+ * htt_rx_mon_note_capture_channel() - Make note of channel to update in
+ * radiotap
+ * @pdev: handle to htt_pdev
+ * @mon_ch: capture channel number.
+ *
+ * Return: None
+ */
+void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch)
+{
+	struct mon_channel *ch_info = &pdev->mon_ch_info;
+
+	ch_info->ch_num = mon_ch;
+	ch_info->ch_freq = cds_chan_to_freq(mon_ch);
+}
+
+#ifndef CONFIG_HL_SUPPORT
+/**
+ * htt_mon_rx_handle_amsdu_packet() - Handle consecutive fragments of amsdu
+ * @msdu: pointer to first msdu of amsdu
+ * @pdev: Handle to htt_pdev_handle
+ * @msg_word: Input and output variable, so pointer to HTT msg pointer
+ * @amsdu_len: remaining length of all N-1 msdu msdu's
+ * @frag_cnt: number of frags handled
+ *
+ * This function handles the (N-1) msdu's of amsdu, N'th msdu is already
+ * handled by calling function. N-1 msdu's are tied using frags_list.
+ * msdu_info field updated by FW indicates if this is last msdu. All the
+ * msdu's before last msdu will be of MAX payload.
+ *
+ * Return: 1 on success and 0 on failure.
+ */
+static
+int htt_mon_rx_handle_amsdu_packet(qdf_nbuf_t msdu, htt_pdev_handle pdev,
+				   uint32_t **msg_word, uint32_t amsdu_len,
+				   uint32_t *frag_cnt)
+{
+	qdf_nbuf_t frag_nbuf;
+	qdf_nbuf_t prev_frag_nbuf;
+	uint32_t len;
+	uint32_t last_frag;
+	qdf_dma_addr_t paddr;
+
+	*msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+	paddr = htt_rx_in_ord_paddr_get(*msg_word);
+	frag_nbuf = htt_rx_in_order_netbuf_pop(pdev, paddr);
+	if (qdf_unlikely(!frag_nbuf)) {
+		qdf_print("%s: netbuf pop failed!\n", __func__);
+		return 0;
+	}
+	*frag_cnt = *frag_cnt + 1;
+	last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)*msg_word)->
+		msdu_info;
+	qdf_nbuf_append_ext_list(msdu, frag_nbuf, amsdu_len);
+	qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE);
+	qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE);
+	/* For msdu's other than parent will not have htt_host_rx_desc_base */
+	len = MIN(amsdu_len, HTT_RX_BUF_SIZE);
+	amsdu_len -= len;
+	qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len);
+
+	HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+					QDF_TRACE_LEVEL_INFO_HIGH,
+					qdf_nbuf_data(frag_nbuf),
+					qdf_nbuf_len(frag_nbuf)));
+	prev_frag_nbuf = frag_nbuf;
+	while (!last_frag) {
+		*msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+		paddr = htt_rx_in_ord_paddr_get(*msg_word);
+		frag_nbuf = htt_rx_in_order_netbuf_pop(pdev, paddr);
+		last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
+			     *msg_word)->msdu_info;
+
+		if (qdf_unlikely(!frag_nbuf)) {
+			qdf_print("%s: netbuf pop failed!\n", __func__);
+			prev_frag_nbuf->next = NULL;
+			return 0;
+		}
+		*frag_cnt = *frag_cnt + 1;
+		qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE);
+		qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE);
+
+		len = MIN(amsdu_len, HTT_RX_BUF_SIZE);
+		amsdu_len -= len;
+		qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len);
+		HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+						QDF_TRACE_LEVEL_INFO_HIGH,
+						qdf_nbuf_data(frag_nbuf),
+						qdf_nbuf_len(frag_nbuf)));
+
+		qdf_nbuf_set_next(prev_frag_nbuf, frag_nbuf);
+		prev_frag_nbuf = frag_nbuf;
+	}
+	qdf_nbuf_set_next(prev_frag_nbuf, NULL);
+	return 1;
+}
+
+#define SHORT_PREAMBLE 1
+#define LONG_PREAMBLE  0
+#ifdef HELIUMPLUS
+/**
+ * htt_rx_get_rate() - get rate info in terms of 500Kbps from htt_rx_desc
+ * @l_sig_rate_select: OFDM or CCK rate
+ * @l_sig_rate:
+ *
+ * If l_sig_rate_select is 0:
+ * 0x8: OFDM 48 Mbps
+ * 0x9: OFDM 24 Mbps
+ * 0xA: OFDM 12 Mbps
+ * 0xB: OFDM 6 Mbps
+ * 0xC: OFDM 54 Mbps
+ * 0xD: OFDM 36 Mbps
+ * 0xE: OFDM 18 Mbps
+ * 0xF: OFDM 9 Mbps
+ * If l_sig_rate_select is 1:
+ * 0x1:  DSSS 1 Mbps long preamble
+ * 0x2:  DSSS 2 Mbps long preamble
+ * 0x3:  CCK 5.5 Mbps long preamble
+ * 0x4:  CCK 11 Mbps long preamble
+ * 0x5:  DSSS 2 Mbps short preamble
+ * 0x6:  CCK 5.5 Mbps
+ * 0x7:  CCK 11 Mbps short  preamble
+ *
+ * Return: rate interms of 500Kbps.
+ */
+static unsigned char htt_rx_get_rate(uint32_t l_sig_rate_select,
+				     uint32_t l_sig_rate, uint8_t *preamble)
+{
+	char ret = 0x0;
+	*preamble = SHORT_PREAMBLE;
+	if (l_sig_rate_select == 0) {
+		switch (l_sig_rate) {
+		case 0x8:
+			ret = 0x60;
+			break;
+		case 0x9:
+			ret = 0x30;
+			break;
+		case 0xA:
+			ret = 0x18;
+			break;
+		case 0xB:
+			ret = 0x0c;
+			break;
+		case 0xC:
+			ret = 0x6c;
+			break;
+		case 0xD:
+			ret = 0x48;
+			break;
+		case 0xE:
+			ret = 0x24;
+			break;
+		case 0xF:
+			ret = 0x12;
+			break;
+		default:
+			break;
+		}
+	} else if (l_sig_rate_select == 1) {
+		switch (l_sig_rate) {
+		case 0x1:
+			ret = 0x2;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0x2:
+			ret = 0x4;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0x3:
+			ret = 0xB;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0x4:
+			ret = 0x16;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0x5:
+			ret = 0x4;
+			break;
+		case 0x6:
+			ret = 0xB;
+			break;
+		case 0x7:
+			ret = 0x16;
+			break;
+		default:
+			break;
+		}
+	} else {
+		qdf_print("Invalid rate info\n");
+	}
+	return ret;
+}
+#else
+/**
+ * htt_rx_get_rate() - get rate info in terms of 500Kbps from htt_rx_desc
+ * @l_sig_rate_select: OFDM or CCK rate
+ * @l_sig_rate:
+ *
+ * If l_sig_rate_select is 0:
+ * 0x8: OFDM 48 Mbps
+ * 0x9: OFDM 24 Mbps
+ * 0xA: OFDM 12 Mbps
+ * 0xB: OFDM 6 Mbps
+ * 0xC: OFDM 54 Mbps
+ * 0xD: OFDM 36 Mbps
+ * 0xE: OFDM 18 Mbps
+ * 0xF: OFDM 9 Mbps
+ * If l_sig_rate_select is 1:
+ * 0x8: CCK 11 Mbps long preamble
+ *  0x9: CCK 5.5 Mbps long preamble
+ * 0xA: CCK 2 Mbps long preamble
+ * 0xB: CCK 1 Mbps long preamble
+ * 0xC: CCK 11 Mbps short preamble
+ * 0xD: CCK 5.5 Mbps short preamble
+ * 0xE: CCK 2 Mbps short preamble
+ *
+ * Return: rate interms of 500Kbps.
+ */
+static unsigned char htt_rx_get_rate(uint32_t l_sig_rate_select,
+				     uint32_t l_sig_rate, uint8_t *preamble)
+{
+	char ret = 0x0;
+	*preamble = SHORT_PREAMBLE;
+	if (l_sig_rate_select == 0) {
+		switch (l_sig_rate) {
+		case 0x8:
+			ret = 0x60;
+			break;
+		case 0x9:
+			ret = 0x30;
+			break;
+		case 0xA:
+			ret = 0x18;
+			break;
+		case 0xB:
+			ret = 0x0c;
+			break;
+		case 0xC:
+			ret = 0x6c;
+			break;
+		case 0xD:
+			ret = 0x48;
+			break;
+		case 0xE:
+			ret = 0x24;
+			break;
+		case 0xF:
+			ret = 0x12;
+			break;
+		default:
+			break;
+		}
+	} else if (l_sig_rate_select == 1) {
+		switch (l_sig_rate) {
+		case 0x8:
+			ret = 0x16;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0x9:
+			ret = 0x0B;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0xA:
+			ret = 0x4;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0xB:
+			ret = 0x02;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0xC:
+			ret = 0x16;
+			break;
+		case 0xD:
+			ret = 0x0B;
+			break;
+		case 0xE:
+			ret = 0x04;
+			break;
+		default:
+			break;
+		}
+	} else {
+		qdf_print("Invalid rate info\n");
+	}
+	return ret;
+}
+#endif /* HELIUMPLUS */
+
+/**
+ * htt_mon_rx_get_phy_info() - Get phy info
+ * @rx_desc: Pointer to struct htt_host_rx_desc_base
+ * @rx_status: Return variable updated with phy_info in rx_status
+ *
+ * Return: None
+ */
+static void htt_mon_rx_get_phy_info(struct htt_host_rx_desc_base *rx_desc,
+				    struct mon_rx_status *rx_status)
+{
+	uint8_t preamble = 0;
+	uint8_t preamble_type = rx_desc->ppdu_start.preamble_type;
+	uint8_t mcs = 0, nss = 0, sgi = 0, bw = 0, beamformed = 0;
+	uint16_t vht_flags = 0, ht_flags = 0;
+	uint32_t l_sig_rate_select = rx_desc->ppdu_start.l_sig_rate_select;
+	uint32_t l_sig_rate = rx_desc->ppdu_start.l_sig_rate;
+	bool is_stbc = 0, ldpc = 0;
+
+	switch (preamble_type) {
+	case 4:
+	/* legacy */
+		rx_status->rate = htt_rx_get_rate(l_sig_rate_select, l_sig_rate,
+						&preamble);
+		break;
+	case 8:
+		is_stbc = ((VHT_SIG_A_2(rx_desc) >> 4) & 3);
+		/* fallthrough */
+	case 9:
+		ht_flags = 1;
+		sgi = (VHT_SIG_A_2(rx_desc) >> 7) & 0x01;
+		bw = (VHT_SIG_A_1(rx_desc) >> 7) & 0x01;
+		mcs = (VHT_SIG_A_1(rx_desc) & 0x7f);
+		nss = mcs >> 3;
+		beamformed =
+			(VHT_SIG_A_2(rx_desc) >> 8) & 0x1;
+		break;
+	case 0x0c:
+		is_stbc = (VHT_SIG_A_2(rx_desc) >> 3) & 1;
+		ldpc = (VHT_SIG_A_2(rx_desc) >> 2) & 1;
+		/* fallthrough */
+	case 0x0d:
+	{
+		uint8_t gid_in_sig = ((VHT_SIG_A_1(rx_desc) >> 4) & 0x3f);
+
+		vht_flags = 1;
+		sgi = VHT_SIG_A_2(rx_desc) & 0x01;
+		bw = (VHT_SIG_A_1(rx_desc) & 0x03);
+		if (gid_in_sig == 0 || gid_in_sig == 63) {
+			/* SU case */
+			mcs = (VHT_SIG_A_2(rx_desc) >> 4) &
+				0xf;
+			nss = (VHT_SIG_A_1(rx_desc) >> 10) &
+				0x7;
+		} else {
+			/* MU case */
+			uint8_t sta_user_pos =
+				(uint8_t)((rx_desc->ppdu_start.reserved_4a >> 8)
+					  & 0x3);
+			mcs = (rx_desc->ppdu_start.vht_sig_b >> 16);
+			if (bw >= 2)
+				mcs >>= 3;
+			else if (bw > 0)
+				mcs >>= 1;
+			mcs &= 0xf;
+			nss = (((VHT_SIG_A_1(rx_desc) >> 10) +
+				sta_user_pos * 3) & 0x7);
+		}
+		beamformed = (VHT_SIG_A_2(rx_desc) >> 8) & 0x1;
+	}
+		/* fallthrough */
+	default:
+		break;
+	}
+
+	rx_status->mcs = mcs;
+	rx_status->bw = bw;
+	rx_status->nr_ant = nss;
+	rx_status->is_stbc = is_stbc;
+	rx_status->sgi = sgi;
+	rx_status->ldpc = ldpc;
+	rx_status->beamformed = beamformed;
+	rx_status->vht_flag_values3[0] = mcs << 0x4 | (nss + 1);
+	rx_status->ht_flags = ht_flags;
+	rx_status->vht_flags = vht_flags;
+	rx_status->rtap_flags |= ((preamble == SHORT_PREAMBLE) ? BIT(1) : 0);
+	if (bw == 0)
+		rx_status->vht_flag_values2 = 0;
+	else if (bw == 1)
+		rx_status->vht_flag_values2 = 1;
+	else if (bw == 2)
+		rx_status->vht_flag_values2 = 4;
+}
+
+/**
+ * htt_mon_rx_get_rtap_flags() - Get radiotap flags
+ * @rx_desc: Pointer to struct htt_host_rx_desc_base
+ *
+ * Return: Bitmapped radiotap flags.
+ */
+static uint8_t htt_mon_rx_get_rtap_flags(struct htt_host_rx_desc_base *rx_desc)
+{
+	uint8_t rtap_flags = 0;
+
+	/* WEP40 || WEP104 || WEP128 */
+	if (rx_desc->mpdu_start.encrypt_type == 0 ||
+	    rx_desc->mpdu_start.encrypt_type == 1 ||
+	    rx_desc->mpdu_start.encrypt_type == 3)
+		rtap_flags |= BIT(2);
+
+	/* IEEE80211_RADIOTAP_F_FRAG */
+	if (rx_desc->attention.fragment)
+		rtap_flags |= BIT(3);
+
+	/* IEEE80211_RADIOTAP_F_FCS */
+	rtap_flags |= BIT(4);
+
+	/* IEEE80211_RADIOTAP_F_BADFCS */
+	if (rx_desc->mpdu_end.fcs_err)
+		rtap_flags |= BIT(6);
+
+	return rtap_flags;
+}
+
+/**
+ * htt_rx_mon_get_rx_status() - Update information about the rx status,
+ * which is used later for radiotap updation.
+ * @rx_desc: Pointer to struct htt_host_rx_desc_base
+ * @rx_status: Return variable updated with rx_status
+ *
+ * Return: None
+ */
+static void htt_rx_mon_get_rx_status(htt_pdev_handle pdev,
+				     struct htt_host_rx_desc_base *rx_desc,
+				     struct mon_rx_status *rx_status)
+{
+	uint16_t channel_flags = 0;
+	struct mon_channel *ch_info = &pdev->mon_ch_info;
+
+	rx_status->tsft = (u_int64_t)TSF_TIMESTAMP(rx_desc);
+	rx_status->chan_freq = ch_info->ch_freq;
+	rx_status->chan_num = ch_info->ch_num;
+	htt_mon_rx_get_phy_info(rx_desc, rx_status);
+	rx_status->rtap_flags |= htt_mon_rx_get_rtap_flags(rx_desc);
+	channel_flags |= rx_desc->ppdu_start.l_sig_rate_select ?
+		IEEE80211_CHAN_CCK : IEEE80211_CHAN_OFDM;
+	channel_flags |=
+		(cds_chan_to_band(ch_info->ch_num) == CDS_BAND_2GHZ ?
+		IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ);
+
+	rx_status->chan_flags = channel_flags;
+	rx_status->ant_signal_db = rx_desc->ppdu_start.rssi_comb;
+}
+
+/**
+ * htt_rx_mon_amsdu_rx_in_order_pop_ll() - Monitor mode HTT Rx in order pop
+ * function
+ * @pdev: Handle to htt_pdev_handle
+ * @rx_ind_msg: In order indication message.
+ * @head_msdu: Return variable pointing to head msdu.
+ * @tail_msdu: Return variable pointing to tail msdu.
+ *
+ * This function pops the msdu based on paddr:length of inorder indication
+ * message.
+ *
+ * Return: 1 for success, 0 on failure.
+ */
+int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
+					qdf_nbuf_t rx_ind_msg,
+					qdf_nbuf_t *head_msdu,
+					qdf_nbuf_t *tail_msdu,
+					uint32_t *replenish_cnt)
+{
+	qdf_nbuf_t msdu, next, prev = NULL;
+	uint8_t *rx_ind_data;
+	uint32_t *msg_word;
+	uint32_t msdu_count;
+	struct htt_host_rx_desc_base *rx_desc;
+	struct mon_rx_status rx_status = {0};
+	uint32_t amsdu_len;
+	uint32_t len;
+	uint32_t last_frag;
+	qdf_dma_addr_t paddr;
+	static uint8_t preamble_type;
+	static uint32_t vht_sig_a_1;
+	static uint32_t vht_sig_a_2;
+
+	HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0);
+
+	rx_ind_data = qdf_nbuf_data(rx_ind_msg);
+	msg_word = (uint32_t *)rx_ind_data;
+
+	*replenish_cnt = 0;
+	HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+					QDF_TRACE_LEVEL_INFO_HIGH,
+					(void *)rx_ind_data,
+					(int)qdf_nbuf_len(rx_ind_msg)));
+
+	/* Get the total number of MSDUs */
+	msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1));
+	HTT_RX_CHECK_MSDU_COUNT(msdu_count);
+
+	msg_word = (uint32_t *)(rx_ind_data +
+				 HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES);
+	paddr = htt_rx_in_ord_paddr_get(msg_word);
+	msdu = htt_rx_in_order_netbuf_pop(pdev, paddr);
+
+	if (qdf_unlikely(!msdu)) {
+		qdf_print("%s: netbuf pop failed!\n", __func__);
+		*tail_msdu = NULL;
+		return 0;
+	}
+	*replenish_cnt = *replenish_cnt + 1;
+
+	while (msdu_count > 0) {
+		msdu_count--;
+		/*
+		 * Set the netbuf length to be the entire buffer length
+		 * initially, so the unmap will unmap the entire buffer.
+		 */
+		qdf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE);
+		qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE);
+
+		/*
+		 * cache consistency has been taken care of by the
+		 * qdf_nbuf_unmap
+		 */
+		rx_desc = htt_rx_desc(msdu);
+		if ((unsigned int)(*(uint32_t *)&rx_desc->attention) &
+				RX_DESC_ATTN_MPDU_LEN_ERR_BIT) {
+			qdf_nbuf_free(msdu);
+			last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
+			     msg_word)->msdu_info;
+			while (!last_frag) {
+				msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+				paddr = htt_rx_in_ord_paddr_get(msg_word);
+				msdu = htt_rx_in_order_netbuf_pop(pdev, paddr);
+				last_frag = ((struct
+					htt_rx_in_ord_paddr_ind_msdu_t *)
+					msg_word)->msdu_info;
+				if (qdf_unlikely(!msdu)) {
+					qdf_print("%s: netbuf pop failed!\n",
+						  __func__);
+					return 0;
+				}
+				*replenish_cnt = *replenish_cnt + 1;
+				qdf_nbuf_unmap(pdev->osdev, msdu,
+					       QDF_DMA_FROM_DEVICE);
+				qdf_nbuf_free(msdu);
+			}
+			msdu = prev;
+			goto next_pop;
+		}
+
+		if (!prev)
+			(*head_msdu) = msdu;
+		prev = msdu;
+
+		HTT_PKT_DUMP(htt_print_rx_desc(rx_desc));
+
+		/*
+		 * Only the first mpdu has valid preamble type, so use it
+		 * till the last mpdu is reached
+		 */
+		if (rx_desc->attention.first_mpdu) {
+			preamble_type = rx_desc->ppdu_start.preamble_type;
+			if (preamble_type == 8 || preamble_type == 9 ||
+			    preamble_type == 0x0c || preamble_type == 0x0d) {
+				vht_sig_a_1 = VHT_SIG_A_1(rx_desc);
+				vht_sig_a_2 = VHT_SIG_A_2(rx_desc);
+			}
+		} else {
+			rx_desc->ppdu_start.preamble_type = preamble_type;
+			if (preamble_type == 8 || preamble_type == 9 ||
+			    preamble_type == 0x0c || preamble_type == 0x0d) {
+				VHT_SIG_A_1(rx_desc) = vht_sig_a_1;
+				VHT_SIG_A_2(rx_desc) = vht_sig_a_2;
+			}
+		}
+
+		if (rx_desc->attention.last_mpdu) {
+			preamble_type = 0;
+			vht_sig_a_1 = 0;
+			vht_sig_a_2 = 0;
+		}
+
+		/*
+		 * Make the netbuf's data pointer point to the payload rather
+		 * than the descriptor.
+		 */
+		htt_rx_mon_get_rx_status(pdev, rx_desc, &rx_status);
+		/*
+		 * For certain platform, 350 bytes of headroom is already
+		 * appended to accommodate radiotap header but
+		 * qdf_nbuf_update_radiotap() API again will try to create
+		 * a room for radiotap header. To make our design simple
+		 * let qdf_nbuf_update_radiotap() API create a room for radiotap
+		 * header and update it, do qdf_nbuf_pull_head() operation and
+		 * pull 350 bytes of headroom.
+		 *
+		 *
+		 *
+		 *               (SKB buffer)
+		 * skb->head --> +-----------+ <-- skb->data
+		 *               |           |     (Before pulling headroom)
+		 *               |           |
+		 *               |   HEAD    |  350 bytes of headroom
+		 *               |           |
+		 *               |           |
+		 *               +-----------+ <-- skb->data
+		 *               |           |     (After pulling headroom)
+		 *               |           |
+		 *               |   DATA    |
+		 *               |           |
+		 *               |           |
+		 *               +-----------+
+		 *               |           |
+		 *               |           |
+		 *               |   TAIL    |
+		 *               |           |
+		 *               |           |
+		 *               +-----------+
+		 *
+		 */
+		if (qdf_nbuf_head(msdu) == qdf_nbuf_data(msdu))
+			qdf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION);
+		qdf_nbuf_update_radiotap(&rx_status, msdu,
+					 HTT_RX_STD_DESC_RESERVATION);
+		amsdu_len = HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_GET(*(msg_word +
+						NEXT_FIELD_OFFSET_IN32));
+
+		/*
+		 * MAX_RX_PAYLOAD_SZ when we have AMSDU packet. amsdu_len in
+		 * which case is the total length of sum of all AMSDU's
+		 */
+		len = MIN(amsdu_len, MAX_RX_PAYLOAD_SZ);
+		amsdu_len -= len;
+		qdf_nbuf_trim_tail(msdu, HTT_RX_BUF_SIZE -
+				   (RX_STD_DESC_SIZE + len));
+
+		HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+						QDF_TRACE_LEVEL_INFO_HIGH,
+						qdf_nbuf_data(msdu),
+						qdf_nbuf_len(msdu)));
+		last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
+			     msg_word)->msdu_info;
+
+		/* Handle amsdu packet */
+		if (!last_frag) {
+			/*
+			 * For AMSDU packet msdu->len is sum of all the msdu's
+			 * length, msdu->data_len is sum of length's of
+			 * remaining msdu's other than parent.
+			 */
+			if (!htt_mon_rx_handle_amsdu_packet(msdu, pdev,
+							    &msg_word,
+							    amsdu_len,
+							    replenish_cnt)) {
+				qdf_print("%s: failed to handle amsdu packet\n",
+					  __func__);
+				return 0;
+			}
+		}
+
+next_pop:
+		/* check if this is the last msdu */
+		if (msdu_count) {
+			msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+			paddr = htt_rx_in_ord_paddr_get(msg_word);
+			next = htt_rx_in_order_netbuf_pop(pdev, paddr);
+			if (qdf_unlikely(!next)) {
+				qdf_print("%s: netbuf pop failed!\n",
+					  __func__);
+				*tail_msdu = NULL;
+				return 0;
+			}
+			*replenish_cnt = *replenish_cnt + 1;
+			if (msdu)
+				qdf_nbuf_set_next(msdu, next);
+			msdu = next;
+		} else {
+			*tail_msdu = msdu;
+			if (msdu)
+				qdf_nbuf_set_next(msdu, NULL);
+		}
+	}
+
+	return 1;
+}
+#endif /* CONFIG_HL_SUPPORT */
+
+#if defined(FEATURE_MONITOR_MODE_SUPPORT)
+#if !defined(QCA6290_HEADERS_DEF) && !defined(QCA6390_HEADERS_DEF)
+static void
+htt_rx_parse_ppdu_start_status(struct htt_host_rx_desc_base *rx_desc,
+			       struct ieee80211_rx_status *rs)
+{
+	struct rx_ppdu_start *ppdu_start = &rx_desc->ppdu_start;
+
+	/* RSSI */
+	rs->rs_rssi = ppdu_start->rssi_comb;
+
+	/* PHY rate */
+	/*
+	 * rs_ratephy coding
+	 * [b3 - b0]
+	 * 0 -> OFDM
+	 * 1 -> CCK
+	 * 2 -> HT
+	 * 3 -> VHT
+	 * OFDM / CCK
+	 * [b7  - b4 ] => LSIG rate
+	 * [b23 - b8 ] => service field
+	 * (b'12 static/dynamic,
+	 * b'14..b'13 BW for VHT)
+	 * [b31 - b24 ] => Reserved
+	 * HT / VHT
+	 * [b15 - b4 ] => SIG A_2 12 LSBs
+	 * [b31 - b16] => SIG A_1 16 LSBs
+	 */
+	if (ppdu_start->preamble_type == 0x4) {
+		rs->rs_ratephy = ppdu_start->l_sig_rate_select;
+		rs->rs_ratephy |= ppdu_start->l_sig_rate << 4;
+		rs->rs_ratephy |= ppdu_start->service << 8;
+	} else {
+		rs->rs_ratephy = (ppdu_start->preamble_type & 0x4) ? 3 : 2;
+#ifdef HELIUMPLUS
+		rs->rs_ratephy |=
+			(ppdu_start->ht_sig_vht_sig_ah_sig_a_2 & 0xFFF) << 4;
+		rs->rs_ratephy |=
+			(ppdu_start->ht_sig_vht_sig_ah_sig_a_1 & 0xFFFF) << 16;
+#else
+		rs->rs_ratephy |= (ppdu_start->ht_sig_vht_sig_a_2 & 0xFFF) << 4;
+		rs->rs_ratephy |=
+			(ppdu_start->ht_sig_vht_sig_a_1 & 0xFFFF) << 16;
+#endif
+	}
+}
+
+/* Util fake function that has same prototype as qdf_nbuf_clone that just
+ * returns the same nbuf
+ */
+static qdf_nbuf_t htt_rx_qdf_noclone_buf(qdf_nbuf_t buf)
+{
+	return buf;
+}
+
+/* This function is used by montior mode code to restitch an MSDU list
+ * corresponding to an MPDU back into an MPDU by linking up the skbs.
+ */
+qdf_nbuf_t
+htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev,
+				qdf_nbuf_t head_msdu,
+				struct ieee80211_rx_status *rx_status,
+				unsigned int clone_not_reqd)
+{
+	qdf_nbuf_t msdu, mpdu_buf, prev_buf, msdu_orig, head_frag_list_cloned;
+	unsigned int decap_format, wifi_hdr_len, sec_hdr_len, msdu_llc_len,
+		 mpdu_buf_len, decap_hdr_pull_bytes, frag_list_sum_len, dir,
+		 is_amsdu, is_first_frag, amsdu_pad, msdu_len;
+	struct htt_host_rx_desc_base *rx_desc;
+	char *hdr_desc;
+	unsigned char *dest;
+	struct ieee80211_frame *wh;
+	struct ieee80211_qoscntl *qos;
+
+	/* The nbuf has been pulled just beyond the status and points to the
+	 * payload
+	 */
+	msdu_orig = head_msdu;
+	rx_desc = htt_rx_desc(msdu_orig);
+
+	/* Fill out the rx_status from the PPDU start and end fields */
+	if (rx_desc->attention.first_mpdu) {
+		htt_rx_parse_ppdu_start_status(rx_desc, rx_status);
+
+		/* The timestamp is no longer valid - It will be valid only for
+		 * the last MPDU
+		 */
+		rx_status->rs_tstamp.tsf = ~0;
+	}
+
+	decap_format =
+		GET_FIELD(&rx_desc->msdu_start, RX_MSDU_START_2_DECAP_FORMAT);
+
+	head_frag_list_cloned = NULL;
+
+	/* Easy case - The MSDU status indicates that this is a non-decapped
+	 * packet in RAW mode.
+	 * return
+	 */
+	if (decap_format == HW_RX_DECAP_FORMAT_RAW) {
+		/* Note that this path might suffer from headroom unavailabilty,
+		 * but the RX status is usually enough
+		 */
+		if (clone_not_reqd)
+			mpdu_buf = htt_rx_qdf_noclone_buf(head_msdu);
+		else
+			mpdu_buf = qdf_nbuf_clone(head_msdu);
+
+		if (!mpdu_buf)
+			goto mpdu_stitch_fail;
+
+		prev_buf = mpdu_buf;
+
+		frag_list_sum_len = 0;
+		is_first_frag = 1;
+		msdu_len = qdf_nbuf_len(mpdu_buf);
+
+		/* Drop the zero-length msdu */
+		if (!msdu_len)
+			goto mpdu_stitch_fail;
+
+		msdu_orig = qdf_nbuf_next(head_msdu);
+
+		while (msdu_orig) {
+			/* TODO: intra AMSDU padding - do we need it ??? */
+			if (clone_not_reqd)
+				msdu = htt_rx_qdf_noclone_buf(msdu_orig);
+			else
+				msdu = qdf_nbuf_clone(msdu_orig);
+
+			if (!msdu)
+				goto mpdu_stitch_fail;
+
+			if (is_first_frag) {
+				is_first_frag = 0;
+				head_frag_list_cloned = msdu;
+			}
+
+			msdu_len = qdf_nbuf_len(msdu);
+			/* Drop the zero-length msdu */
+			if (!msdu_len)
+				goto mpdu_stitch_fail;
+
+			frag_list_sum_len += msdu_len;
+
+			/* Maintain the linking of the cloned MSDUS */
+			qdf_nbuf_set_next_ext(prev_buf, msdu);
+
+			/* Move to the next */
+			prev_buf = msdu;
+			msdu_orig = qdf_nbuf_next(msdu_orig);
+		}
+
+		/* The last msdu length need be larger than HTT_FCS_LEN */
+		if (msdu_len < HTT_FCS_LEN)
+			goto mpdu_stitch_fail;
+
+		qdf_nbuf_trim_tail(prev_buf, HTT_FCS_LEN);
+
+		/* If there were more fragments to this RAW frame */
+		if (head_frag_list_cloned) {
+			qdf_nbuf_append_ext_list(mpdu_buf,
+						 head_frag_list_cloned,
+						 frag_list_sum_len);
+		}
+
+		goto mpdu_stitch_done;
+	}
+
+	/* Decap mode:
+	 * Calculate the amount of header in decapped packet to knock off based
+	 * on the decap type and the corresponding number of raw bytes to copy
+	 * status header
+	 */
+
+	hdr_desc = &rx_desc->rx_hdr_status[0];
+
+	/* Base size */
+	wifi_hdr_len = sizeof(struct ieee80211_frame);
+	wh = (struct ieee80211_frame *)hdr_desc;
+
+	dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
+	if (dir == IEEE80211_FC1_DIR_DSTODS)
+		wifi_hdr_len += 6;
+
+	is_amsdu = 0;
+	if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
+		qos = (struct ieee80211_qoscntl *)
+		      (hdr_desc + wifi_hdr_len);
+		wifi_hdr_len += 2;
+
+		is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU);
+	}
+
+	/* TODO: Any security headers associated with MPDU */
+	sec_hdr_len = 0;
+
+	/* MSDU related stuff LLC - AMSDU subframe header etc */
+	msdu_llc_len = is_amsdu ? (14 + 8) : 8;
+
+	mpdu_buf_len = wifi_hdr_len + sec_hdr_len + msdu_llc_len;
+
+	/* "Decap" header to remove from MSDU buffer */
+	decap_hdr_pull_bytes = 14;
+
+	/* Allocate a new nbuf for holding the 802.11 header retrieved from the
+	 * status of the now decapped first msdu. Leave enough headroom for
+	 * accomodating any radio-tap /prism like PHY header
+	 */
+#define HTT_MAX_MONITOR_HEADER (512)
+	mpdu_buf = qdf_nbuf_alloc(pdev->osdev,
+				  HTT_MAX_MONITOR_HEADER + mpdu_buf_len,
+				  HTT_MAX_MONITOR_HEADER, 4, false);
+
+	if (!mpdu_buf)
+		goto mpdu_stitch_fail;
+
+	/* Copy the MPDU related header and enc headers into the first buffer
+	 * - Note that there can be a 2 byte pad between heaader and enc header
+	 */
+
+	prev_buf = mpdu_buf;
+	dest = qdf_nbuf_put_tail(prev_buf, wifi_hdr_len);
+	if (!dest)
+		goto mpdu_stitch_fail;
+	qdf_mem_copy(dest, hdr_desc, wifi_hdr_len);
+	hdr_desc += wifi_hdr_len;
+
+	/* NOTE - This padding is present only in the RAW header status - not
+	 * when the MSDU data payload is in RAW format.
+	 */
+	/* Skip the "IV pad" */
+	if (wifi_hdr_len & 0x3)
+		hdr_desc += 2;
+
+	/* The first LLC len is copied into the MPDU buffer */
+	frag_list_sum_len = 0;
+	frag_list_sum_len -= msdu_llc_len;
+
+	msdu_orig = head_msdu;
+	is_first_frag = 1;
+	amsdu_pad = 0;
+
+	while (msdu_orig) {
+		/* TODO: intra AMSDU padding - do we need it ??? */
+		if (clone_not_reqd)
+			msdu = htt_rx_qdf_noclone_buf(msdu_orig);
+		else
+			msdu = qdf_nbuf_clone(msdu_orig);
+
+		if (!msdu)
+			goto mpdu_stitch_fail;
+
+		if (is_first_frag) {
+			is_first_frag = 0;
+			head_frag_list_cloned = msdu;
+		} else {
+			/* Maintain the linking of the cloned MSDUS */
+			qdf_nbuf_set_next_ext(prev_buf, msdu);
+
+			/* Reload the hdr ptr only on non-first MSDUs */
+			rx_desc = htt_rx_desc(msdu_orig);
+			hdr_desc = &rx_desc->rx_hdr_status[0];
+		}
+
+		/* Copy this buffers MSDU related status into the prev buffer */
+		dest = qdf_nbuf_put_tail(prev_buf, msdu_llc_len + amsdu_pad);
+		dest += amsdu_pad;
+		qdf_mem_copy(dest, hdr_desc, msdu_llc_len);
+
+		/* Push the MSDU buffer beyond the decap header */
+		qdf_nbuf_pull_head(msdu, decap_hdr_pull_bytes);
+		frag_list_sum_len +=
+			msdu_llc_len + qdf_nbuf_len(msdu) + amsdu_pad;
+
+		/*
+		 * Set up intra-AMSDU pad to be added to start of next buffer -
+		 * AMSDU pad is 4 byte pad on AMSDU subframe
+		 */
+		amsdu_pad = (msdu_llc_len + qdf_nbuf_len(msdu)) & 0x3;
+		amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0;
+
+		/*
+		 * TODO FIXME How do we handle MSDUs that have fraglist - Should
+		 * probably iterate all the frags cloning them along the way and
+		 * and also updating the prev_buf pointer
+		 */
+
+		/* Move to the next */
+		prev_buf = msdu;
+		msdu_orig = qdf_nbuf_next(msdu_orig);
+	}
+
+	/* TODO: Convert this to suitable qdf routines */
+	qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list_cloned,
+				 frag_list_sum_len);
+
+mpdu_stitch_done:
+	/* Check if this buffer contains the PPDU end status for TSF */
+	if (rx_desc->attention.last_mpdu)
+#ifdef HELIUMPLUS
+		rx_status->rs_tstamp.tsf =
+			rx_desc->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32;
+#else
+		rx_status->rs_tstamp.tsf = rx_desc->ppdu_end.tsf_timestamp;
+#endif
+	/* All the nbufs have been linked into the ext list
+	 * and then unlink the nbuf list
+	 */
+	if (clone_not_reqd) {
+		msdu = head_msdu;
+		while (msdu) {
+			msdu_orig = msdu;
+			msdu = qdf_nbuf_next(msdu);
+			qdf_nbuf_set_next(msdu_orig, NULL);
+		}
+	}
+
+	return mpdu_buf;
+
+mpdu_stitch_fail:
+	/* Free these alloced buffers and the orig buffers in non-clone case */
+	if (!clone_not_reqd) {
+		/* Free the head buffer */
+		if (mpdu_buf)
+			qdf_nbuf_free(mpdu_buf);
+
+		/* Free the partial list */
+		while (head_frag_list_cloned) {
+			msdu = head_frag_list_cloned;
+			head_frag_list_cloned =
+				qdf_nbuf_next_ext(head_frag_list_cloned);
+			qdf_nbuf_free(msdu);
+		}
+	} else {
+		/* Free the alloced head buffer */
+		if (decap_format != HW_RX_DECAP_FORMAT_RAW)
+			if (mpdu_buf)
+				qdf_nbuf_free(mpdu_buf);
+
+		/* Free the orig buffers */
+		msdu = head_msdu;
+		while (msdu) {
+			msdu_orig = msdu;
+			msdu = qdf_nbuf_next(msdu);
+			qdf_nbuf_free(msdu_orig);
+		}
+	}
+
+	return NULL;
+}
+#endif
+#endif
diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c
new file mode 100644
index 0000000..63e19b6
--- /dev/null
+++ b/core/dp/htt/htt_rx.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ * @file htt_rx.c
+ * @brief Implement receive aspects of HTT.
+ * @details
+ *  This file contains three categories of HTT rx code:
+ *  1.  An abstraction of the rx descriptor, to hide the
+ *      differences between the HL vs. LL rx descriptor.
+ *  2.  Functions for providing access to the (series of)
+ *      rx descriptor(s) and rx frame(s) associated with
+ *      an rx indication message.
+ *  3.  Functions for setting up and using the MAC DMA
+ *      rx ring (applies to LL only).
+ */
+
+#include <qdf_mem.h>         /* qdf_mem_malloc,free, etc. */
+#include <qdf_types.h>          /* qdf_print, bool */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_timer.h>		/* qdf_timer_free */
+
+#include <htt.h>                /* HTT_HL_RX_DESC_SIZE */
+#include <ol_cfg.h>
+#include <ol_rx.h>
+#include <ol_htt_rx_api.h>
+#include <htt_internal.h>       /* HTT_ASSERT, htt_pdev_t, HTT_RX_BUF_SIZE */
+#include "regtable.h"
+
+#include <cds_ieee80211_common.h>   /* ieee80211_frame, ieee80211_qoscntl */
+#include <cds_ieee80211_defines.h>  /* ieee80211_rx_status */
+#include <cds_utils.h>
+#include <wlan_policy_mgr_api.h>
+#include "ol_txrx_types.h"
+#ifdef DEBUG_DMA_DONE
+#include <asm/barrier.h>
+#include <wma_api.h>
+#endif
+#include <pktlog_ac_fmt.h>
+
+/**
+ * htt_rx_mpdu_wifi_hdr_retrieve() - retrieve 802.11 header
+ * @pdev - pdev handle
+ * @mpdu_desc - mpdu descriptor
+ *
+ * Return : pointer to 802.11 header
+ */
+char *htt_rx_mpdu_wifi_hdr_retrieve(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	struct htt_host_rx_desc_base *rx_desc =
+		(struct htt_host_rx_desc_base *)mpdu_desc;
+
+	if (!rx_desc)
+		return NULL;
+	else
+		return rx_desc->rx_hdr_status;
+}
+
+/**
+ * htt_rx_mpdu_desc_tsf32() - Return the TSF timestamp indicating when
+ *                            a MPDU was received.
+ * @pdev - the HTT instance the rx data was received on
+ * @mpdu_desc - the abstract descriptor for the MPDU in question
+ *
+ * return : 32 LSBs of TSF time at which the MPDU's PPDU was received
+ */
+uint32_t htt_rx_mpdu_desc_tsf32(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	return 0;
+}
+
+static inline
+uint8_t htt_rx_msdu_fw_desc_get(htt_pdev_handle pdev, void *msdu_desc)
+{
+	/*
+	 * HL and LL use the same format for FW rx desc, but have the FW rx desc
+	 * in different locations.
+	 * In LL, the FW rx descriptor has been copied into the same
+	 * htt_host_rx_desc_base struct that holds the HW rx desc.
+	 * In HL, the FW rx descriptor, along with the MSDU payload,
+	 * is in the same buffer as the rx indication message.
+	 *
+	 * Use the FW rx desc offset configured during startup to account for
+	 * this difference between HL vs. LL.
+	 *
+	 * An optimization would be to define the LL and HL msdu_desc pointer
+	 * in such a way that they both use the same offset to the FW rx desc.
+	 * Then the following functions could be converted to macros, without
+	 * needing to expose the htt_pdev_t definition outside HTT.
+	 */
+	return *(((uint8_t *)msdu_desc) + pdev->rx_fw_desc_offset);
+}
+
+int htt_rx_msdu_discard(htt_pdev_handle pdev, void *msdu_desc)
+{
+	return htt_rx_msdu_fw_desc_get(pdev, msdu_desc) & FW_RX_DESC_DISCARD_M;
+}
+
+int htt_rx_msdu_forward(htt_pdev_handle pdev, void *msdu_desc)
+{
+	return htt_rx_msdu_fw_desc_get(pdev, msdu_desc) & FW_RX_DESC_FORWARD_M;
+}
+
+int htt_rx_msdu_inspect(htt_pdev_handle pdev, void *msdu_desc)
+{
+	return htt_rx_msdu_fw_desc_get(pdev, msdu_desc) & FW_RX_DESC_INSPECT_M;
+}
+
+void
+htt_rx_msdu_actions(htt_pdev_handle pdev,
+		    void *msdu_desc, int *discard, int *forward, int *inspect)
+{
+	uint8_t rx_msdu_fw_desc = htt_rx_msdu_fw_desc_get(pdev, msdu_desc);
+#ifdef HTT_DEBUG_DATA
+	HTT_PRINT("act:0x%x ", rx_msdu_fw_desc);
+#endif
+	*discard = rx_msdu_fw_desc & FW_RX_DESC_DISCARD_M;
+	*forward = rx_msdu_fw_desc & FW_RX_DESC_FORWARD_M;
+	*inspect = rx_msdu_fw_desc & FW_RX_DESC_INSPECT_M;
+}
+
+uint32_t htt_rx_amsdu_rx_in_order_get_pktlog(qdf_nbuf_t rx_ind_msg)
+{
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *)qdf_nbuf_data(rx_ind_msg);
+	return HTT_RX_IN_ORD_PADDR_IND_PKTLOG_GET(*msg_word);
+}
+
+int16_t htt_rx_mpdu_desc_rssi_dbm(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	/*
+	 * Currently the RSSI is provided only as a field in the
+	 * HTT_T2H_RX_IND message, rather than in each rx descriptor.
+	 */
+	return HTT_RSSI_INVALID;
+}
+
+/*
+ * htt_rx_amsdu_pop -
+ * global function pointer that is programmed during attach to point
+ * to either htt_rx_amsdu_pop_ll or htt_rx_amsdu_rx_in_order_pop_ll.
+ */
+int (*htt_rx_amsdu_pop)(htt_pdev_handle pdev,
+			qdf_nbuf_t rx_ind_msg,
+			qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu,
+			uint32_t *msdu_count);
+
+/*
+ * htt_rx_frag_pop -
+ * global function pointer that is programmed during attach to point
+ * to either htt_rx_amsdu_pop_ll
+ */
+int (*htt_rx_frag_pop)(htt_pdev_handle pdev,
+		       qdf_nbuf_t rx_ind_msg,
+		       qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu,
+		       uint32_t *msdu_count);
+
+int (*htt_rx_offload_msdu_cnt)(htt_pdev_handle pdev);
+
+int
+(*htt_rx_offload_msdu_pop)(htt_pdev_handle pdev,
+			   qdf_nbuf_t offload_deliver_msg,
+			   int *vdev_id,
+			   int *peer_id,
+			   int *tid,
+			   uint8_t *fw_desc,
+			   qdf_nbuf_t *head_buf, qdf_nbuf_t *tail_buf);
+
+void * (*htt_rx_mpdu_desc_list_next)(htt_pdev_handle pdev,
+				     qdf_nbuf_t rx_ind_msg);
+
+bool (*htt_rx_mpdu_desc_retry)(htt_pdev_handle pdev, void *mpdu_desc);
+
+uint16_t (*htt_rx_mpdu_desc_seq_num)(htt_pdev_handle pdev, void *mpdu_desc);
+
+void (*htt_rx_mpdu_desc_pn)(htt_pdev_handle pdev,
+			    void *mpdu_desc,
+			    union htt_rx_pn_t *pn, int pn_len_bits);
+
+uint8_t (*htt_rx_mpdu_desc_tid)(htt_pdev_handle pdev, void *mpdu_desc);
+
+bool (*htt_rx_msdu_desc_completes_mpdu)(htt_pdev_handle pdev, void *msdu_desc);
+
+bool (*htt_rx_msdu_first_msdu_flag)(htt_pdev_handle pdev, void *msdu_desc);
+
+int (*htt_rx_msdu_has_wlan_mcast_flag)(htt_pdev_handle pdev, void *msdu_desc);
+
+bool (*htt_rx_msdu_is_wlan_mcast)(htt_pdev_handle pdev, void *msdu_desc);
+
+int (*htt_rx_msdu_is_frag)(htt_pdev_handle pdev, void *msdu_desc);
+
+void * (*htt_rx_msdu_desc_retrieve)(htt_pdev_handle pdev, qdf_nbuf_t msdu);
+
+bool (*htt_rx_mpdu_is_encrypted)(htt_pdev_handle pdev, void *mpdu_desc);
+
+bool (*htt_rx_msdu_desc_key_id)(htt_pdev_handle pdev,
+				void *mpdu_desc, uint8_t *key_id);
+
+bool (*htt_rx_msdu_chan_info_present)(
+	htt_pdev_handle pdev,
+	void *mpdu_desc);
+
+bool (*htt_rx_msdu_center_freq)(
+	htt_pdev_handle pdev,
+	struct ol_txrx_peer_t *peer,
+	void *mpdu_desc,
+	uint16_t *primary_chan_center_freq_mhz,
+	uint16_t *contig_chan1_center_freq_mhz,
+	uint16_t *contig_chan2_center_freq_mhz,
+	uint8_t *phy_mode);
+
+void htt_rx_desc_frame_free(htt_pdev_handle htt_pdev, qdf_nbuf_t msdu)
+{
+	qdf_nbuf_free(msdu);
+}
+
+void htt_rx_msdu_desc_free(htt_pdev_handle htt_pdev, qdf_nbuf_t msdu)
+{
+	/*
+	 * The rx descriptor is in the same buffer as the rx MSDU payload,
+	 * and does not need to be freed separately.
+	 */
+}
+
+void htt_rx_msdu_buff_replenish(htt_pdev_handle pdev)
+{
+	if (qdf_atomic_dec_and_test(&pdev->rx_ring.refill_ref_cnt))
+		htt_rx_fill_ring_count(pdev);
+
+	qdf_atomic_inc(&pdev->rx_ring.refill_ref_cnt);
+}
+
+#ifdef IPA_OFFLOAD
+#ifdef QCA_WIFI_3_0
+/**
+ * htt_rx_ipa_uc_alloc_wdi2_rsc() - Allocate WDI2.0 resources
+ * @pdev: htt context
+ * @rx_ind_ring_elements: rx ring elements
+ *
+ * Return: 0 success
+ */
+static int htt_rx_ipa_uc_alloc_wdi2_rsc(struct htt_pdev_t *pdev,
+			 unsigned int rx_ind_ring_elements)
+{
+	/*
+	 * Allocate RX2 indication ring
+	 * RX2 IND ring element
+	 *   4bytes: pointer
+	 *   2bytes: VDEV ID
+	 *   2bytes: length
+	 *
+	 * RX indication ring size, by bytes
+	 */
+	pdev->ipa_uc_rx_rsc.rx2_ind_ring =
+		qdf_mem_shared_mem_alloc(pdev->osdev,
+					 rx_ind_ring_elements *
+					 sizeof(qdf_dma_addr_t));
+	if (!pdev->ipa_uc_rx_rsc.rx2_ind_ring) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Unable to allocate memory for IPA rx2 ind ring",
+			  __func__);
+		return 1;
+	}
+
+	pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx =
+		qdf_mem_shared_mem_alloc(pdev->osdev, 4);
+	if (!pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Unable to allocate memory for IPA rx proc done index",
+			  __func__);
+		qdf_mem_shared_mem_free(pdev->osdev,
+					pdev->ipa_uc_rx_rsc.rx2_ind_ring);
+		return 1;
+	}
+
+	return 0;
+}
+
+/**
+ * htt_rx_ipa_uc_free_wdi2_rsc() - Free WDI2.0 resources
+ * @pdev: htt context
+ *
+ * Return: None
+ */
+static void htt_rx_ipa_uc_free_wdi2_rsc(struct htt_pdev_t *pdev)
+{
+	qdf_mem_shared_mem_free(pdev->osdev, pdev->ipa_uc_rx_rsc.rx2_ind_ring);
+	qdf_mem_shared_mem_free(pdev->osdev,
+				pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx);
+}
+#else
+static int htt_rx_ipa_uc_alloc_wdi2_rsc(struct htt_pdev_t *pdev,
+			 unsigned int rx_ind_ring_elements)
+{
+	return 0;
+}
+
+static void htt_rx_ipa_uc_free_wdi2_rsc(struct htt_pdev_t *pdev)
+{
+}
+#endif
+
+/**
+ * htt_rx_ipa_uc_attach() - attach htt ipa uc rx resource
+ * @pdev: htt context
+ * @rx_ind_ring_size: rx ring size
+ *
+ * Return: 0 success
+ */
+int htt_rx_ipa_uc_attach(struct htt_pdev_t *pdev,
+			 unsigned int rx_ind_ring_elements)
+{
+	int ret = 0;
+
+	/*
+	 * Allocate RX indication ring
+	 * RX IND ring element
+	 *   4bytes: pointer
+	 *   2bytes: VDEV ID
+	 *   2bytes: length
+	 */
+	pdev->ipa_uc_rx_rsc.rx_ind_ring =
+		qdf_mem_shared_mem_alloc(pdev->osdev,
+					 rx_ind_ring_elements *
+					 sizeof(struct ipa_uc_rx_ring_elem_t));
+	if (!pdev->ipa_uc_rx_rsc.rx_ind_ring) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Unable to allocate memory for IPA rx ind ring",
+			  __func__);
+		return 1;
+	}
+
+	pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx =
+		qdf_mem_shared_mem_alloc(pdev->osdev, 4);
+	if (!pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Unable to allocate memory for IPA rx proc done index",
+			  __func__);
+		qdf_mem_shared_mem_free(pdev->osdev,
+					pdev->ipa_uc_rx_rsc.rx_ind_ring);
+		return 1;
+	}
+
+	ret = htt_rx_ipa_uc_alloc_wdi2_rsc(pdev, rx_ind_ring_elements);
+	if (ret) {
+		qdf_mem_shared_mem_free(pdev->osdev, pdev->ipa_uc_rx_rsc.rx_ind_ring);
+		qdf_mem_shared_mem_free(pdev->osdev,
+					pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx);
+	}
+	return ret;
+}
+
+int htt_rx_ipa_uc_detach(struct htt_pdev_t *pdev)
+{
+	qdf_mem_shared_mem_free(pdev->osdev, pdev->ipa_uc_rx_rsc.rx_ind_ring);
+	qdf_mem_shared_mem_free(pdev->osdev,
+				pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx);
+
+	htt_rx_ipa_uc_free_wdi2_rsc(pdev);
+	return 0;
+}
+#endif /* IPA_OFFLOAD */
+
+#ifndef REMOVE_PKT_LOG
+/**
+ * htt_register_rx_pkt_dump_callback() - registers callback to
+ *   get rx pkt status and call callback to do rx packet dump
+ *
+ * @pdev: htt pdev handle
+ * @callback: callback to get rx pkt status and
+ *     call callback to do rx packet dump
+ *
+ * This function is used to register the callback to get
+ * rx pkt status and call callback to do rx packet dump
+ *
+ * Return: None
+ *
+ */
+void htt_register_rx_pkt_dump_callback(struct htt_pdev_t *pdev,
+				tp_rx_pkt_dump_cb callback)
+{
+	if (!pdev) {
+		qdf_print("%s: %s, %s",
+			__func__,
+			"htt pdev is NULL",
+			"rx packet status callback register unsuccessful\n");
+		return;
+	}
+	pdev->rx_pkt_dump_cb = callback;
+}
+
+/**
+ * htt_deregister_rx_pkt_dump_callback() - deregisters callback to
+ *   get rx pkt status and call callback to do rx packet dump
+ *
+ * @pdev: htt pdev handle
+ *
+ * This function is used to deregister the callback to get
+ * rx pkt status and call callback to do rx packet dump
+ *
+ * Return: None
+ *
+ */
+void htt_deregister_rx_pkt_dump_callback(struct htt_pdev_t *pdev)
+{
+	if (!pdev) {
+		qdf_print("%s: %s, %s",
+			__func__,
+			"htt pdev is NULL",
+			"rx packet status callback deregister unsuccessful\n");
+		return;
+	}
+	pdev->rx_pkt_dump_cb = NULL;
+}
+#endif
diff --git a/core/dp/htt/htt_rx_hl.c b/core/dp/htt/htt_rx_hl.c
new file mode 100644
index 0000000..5f9d1fc
--- /dev/null
+++ b/core/dp/htt/htt_rx_hl.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#include <qdf_mem.h>         /* qdf_mem_malloc,free, etc. */
+#include <qdf_types.h>          /* qdf_print, bool */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_timer.h>		/* qdf_timer_free */
+
+#include <htt.h>                /* HTT_HL_RX_DESC_SIZE */
+#include <ol_cfg.h>
+#include <ol_rx.h>
+#include <ol_htt_rx_api.h>
+#include <htt_internal.h>       /* HTT_ASSERT, htt_pdev_t, HTT_RX_BUF_SIZE */
+#include "regtable.h"
+
+#include <cds_ieee80211_common.h>   /* ieee80211_frame, ieee80211_qoscntl */
+#include <cds_ieee80211_defines.h>  /* ieee80211_rx_status */
+#include <cds_utils.h>
+#include <wlan_policy_mgr_api.h>
+#include "ol_txrx_types.h"
+
+/*
+ * This function is used both below within this file (which the compiler
+ * will hopefully inline), and out-line from other files via the
+ * htt_rx_msdu_first_msdu_flag function pointer.
+ */
+static inline bool
+htt_rx_msdu_first_msdu_flag_hl(htt_pdev_handle pdev, void *msdu_desc)
+{
+	return ((u_int8_t *)msdu_desc - sizeof(struct hl_htt_rx_ind_base))
+		[HTT_ENDIAN_BYTE_IDX_SWAP(HTT_RX_IND_HL_FLAG_OFFSET)] &
+		HTT_RX_IND_HL_FLAG_FIRST_MSDU ? true : false;
+}
+
+u_int16_t
+htt_rx_msdu_rx_desc_size_hl(
+	htt_pdev_handle pdev,
+	void *msdu_desc
+		)
+{
+	return ((u_int8_t *)(msdu_desc) - HTT_RX_IND_HL_BYTES)
+		[HTT_ENDIAN_BYTE_IDX_SWAP(HTT_RX_IND_HL_RX_DESC_LEN_OFFSET)];
+}
+
+#ifdef CHECKSUM_OFFLOAD
+static void
+htt_set_checksum_result_hl(qdf_nbuf_t msdu,
+			   struct htt_host_rx_desc_base *rx_desc)
+{
+	u_int8_t flag = ((u_int8_t *)rx_desc -
+				sizeof(struct hl_htt_rx_ind_base))[
+					HTT_ENDIAN_BYTE_IDX_SWAP(
+						HTT_RX_IND_HL_FLAG_OFFSET)];
+
+	int is_ipv6 = flag & HTT_RX_IND_HL_FLAG_IPV6 ? 1 : 0;
+	int is_tcp = flag & HTT_RX_IND_HL_FLAG_TCP ? 1 : 0;
+	int is_udp = flag & HTT_RX_IND_HL_FLAG_UDP ? 1 : 0;
+
+	qdf_nbuf_rx_cksum_t cksum = {
+		QDF_NBUF_RX_CKSUM_NONE,
+		QDF_NBUF_RX_CKSUM_NONE,
+		0
+	};
+
+	switch ((is_udp << 2) | (is_tcp << 1) | (is_ipv6 << 0)) {
+	case 0x4:
+		cksum.l4_type = QDF_NBUF_RX_CKSUM_UDP;
+		break;
+	case 0x2:
+		cksum.l4_type = QDF_NBUF_RX_CKSUM_TCP;
+		break;
+	case 0x5:
+		cksum.l4_type = QDF_NBUF_RX_CKSUM_UDPIPV6;
+		break;
+	case 0x3:
+		cksum.l4_type = QDF_NBUF_RX_CKSUM_TCPIPV6;
+		break;
+	default:
+		cksum.l4_type = QDF_NBUF_RX_CKSUM_NONE;
+		break;
+	}
+	if (cksum.l4_type != (qdf_nbuf_l4_rx_cksum_type_t)
+				QDF_NBUF_RX_CKSUM_NONE) {
+		cksum.l4_result = flag & HTT_RX_IND_HL_FLAG_C4_FAILED ?
+			QDF_NBUF_RX_CKSUM_NONE :
+				QDF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY;
+	}
+	qdf_nbuf_set_rx_cksum(msdu, &cksum);
+}
+#else
+static inline
+void htt_set_checksum_result_hl(qdf_nbuf_t msdu,
+				struct htt_host_rx_desc_base *rx_desc)
+{
+}
+#endif
+
+/**
+ * htt_rx_fill_ring_count() - replenish rx msdu buffer
+ * @pdev: Handle (pointer) to HTT pdev.
+ *
+ * This funciton will replenish the rx buffer to the max number
+ * that can be kept in the ring
+ *
+ * Return: None
+ */
+void htt_rx_fill_ring_count(htt_pdev_handle pdev)
+{
+}
+
+/**
+ * htt_rx_mpdu_desc_list_next_hl() - provides an abstract way to obtain
+ *				     the next MPDU descriptor
+ * @pdev: the HTT instance the rx data was received on
+ * @rx_ind_msg: the netbuf containing the rx indication message
+ *
+ * for HL, the returned value is not mpdu_desc,
+ * it's translated hl_rx_desc just after the hl_ind_msg
+ * for HL AMSDU, we can't point to payload now, because
+ * hl rx desc is not fixed, we can't retrieve the desc
+ * by minus rx_desc_size when release. keep point to hl rx desc
+ * now
+ *
+ * Return: next abstract rx descriptor from the series of MPDUs
+ *		   referenced by an rx ind msg
+ */
+static inline void *
+htt_rx_mpdu_desc_list_next_hl(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
+{
+	void *mpdu_desc = (void *)qdf_nbuf_data(rx_ind_msg);
+	return mpdu_desc;
+}
+
+/**
+ * htt_rx_msdu_desc_retrieve_hl() - Retrieve a previously-stored rx descriptor
+ *				    from a MSDU buffer
+ * @pdev: the HTT instance the rx data was received on
+ * @msdu - the buffer containing the MSDU payload
+ *
+ * currently for HL AMSDU, we don't point to payload.
+ * we shift to payload in ol_rx_deliver later
+ *
+ * Return: the corresponding abstract rx MSDU descriptor
+ */
+static inline void *
+htt_rx_msdu_desc_retrieve_hl(htt_pdev_handle pdev, qdf_nbuf_t msdu)
+{
+	return qdf_nbuf_data(msdu);
+}
+
+static
+bool htt_rx_mpdu_is_encrypted_hl(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	if (htt_rx_msdu_first_msdu_flag_hl(pdev, mpdu_desc) == true) {
+		/* Fix Me: only for little endian */
+		struct hl_htt_rx_desc_base *rx_desc =
+			(struct hl_htt_rx_desc_base *)mpdu_desc;
+
+		return HTT_WORD_GET(*(u_int32_t *)rx_desc,
+					HTT_HL_RX_DESC_MPDU_ENC);
+	} else {
+		/* not first msdu, no encrypt info for hl */
+		qdf_print(
+			"Error: get encrypted from a not-first msdu.\n");
+		qdf_assert(0);
+		return false;
+	}
+}
+
+static inline bool
+htt_rx_msdu_chan_info_present_hl(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	if (htt_rx_msdu_first_msdu_flag_hl(pdev, mpdu_desc) == true &&
+	    HTT_WORD_GET(*(u_int32_t *)mpdu_desc,
+			 HTT_HL_RX_DESC_CHAN_INFO_PRESENT))
+		return true;
+
+	return false;
+}
+
+static bool
+htt_rx_msdu_center_freq_hl(htt_pdev_handle pdev,
+			   struct ol_txrx_peer_t *peer,
+			   void *mpdu_desc,
+			   uint16_t *primary_chan_center_freq_mhz,
+			   uint16_t *contig_chan1_center_freq_mhz,
+			   uint16_t *contig_chan2_center_freq_mhz,
+			   uint8_t *phy_mode)
+{
+	int pn_len, index;
+	uint32_t *chan_info;
+
+	index = htt_rx_msdu_is_wlan_mcast(pdev, mpdu_desc) ?
+		txrx_sec_mcast : txrx_sec_ucast;
+
+	pn_len = (peer ?
+			pdev->txrx_pdev->rx_pn[peer->security[index].sec_type].
+								len : 0);
+	chan_info = (uint32_t *)((uint8_t *)mpdu_desc +
+			HTT_HL_RX_DESC_PN_OFFSET + pn_len);
+
+	if (htt_rx_msdu_chan_info_present_hl(pdev, mpdu_desc)) {
+		if (primary_chan_center_freq_mhz)
+			*primary_chan_center_freq_mhz =
+				HTT_WORD_GET(
+					*chan_info,
+					HTT_CHAN_INFO_PRIMARY_CHAN_CENTER_FREQ);
+		if (contig_chan1_center_freq_mhz)
+			*contig_chan1_center_freq_mhz =
+				HTT_WORD_GET(
+					*chan_info,
+					HTT_CHAN_INFO_CONTIG_CHAN1_CENTER_FREQ);
+		chan_info++;
+		if (contig_chan2_center_freq_mhz)
+			*contig_chan2_center_freq_mhz =
+				HTT_WORD_GET(
+					*chan_info,
+					HTT_CHAN_INFO_CONTIG_CHAN2_CENTER_FREQ);
+		if (phy_mode)
+			*phy_mode =
+				HTT_WORD_GET(*chan_info,
+					     HTT_CHAN_INFO_PHY_MODE);
+		return true;
+	}
+
+	if (primary_chan_center_freq_mhz)
+		*primary_chan_center_freq_mhz = 0;
+	if (contig_chan1_center_freq_mhz)
+		*contig_chan1_center_freq_mhz = 0;
+	if (contig_chan2_center_freq_mhz)
+		*contig_chan2_center_freq_mhz = 0;
+	if (phy_mode)
+		*phy_mode = 0;
+	return false;
+}
+
+static bool
+htt_rx_msdu_desc_key_id_hl(htt_pdev_handle htt_pdev,
+			   void *mpdu_desc, u_int8_t *key_id)
+{
+	if (htt_rx_msdu_first_msdu_flag_hl(htt_pdev, mpdu_desc) == true) {
+		/* Fix Me: only for little endian */
+		struct hl_htt_rx_desc_base *rx_desc =
+			(struct hl_htt_rx_desc_base *)mpdu_desc;
+
+		*key_id = rx_desc->key_id_oct;
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * htt_rx_mpdu_desc_retry_hl() - Returns the retry bit from the Rx descriptor
+ *                               for the High Latency driver
+ * @pdev: Handle (pointer) to HTT pdev.
+ * @mpdu_desc: Void pointer to the Rx descriptor for MPDU
+ *             before the beginning of the payload.
+ *
+ *  This function returns the retry bit of the 802.11 header for the
+ *  provided rx MPDU descriptor. For the high latency driver, this function
+ *  pretends as if the retry bit is never set so that the mcast duplicate
+ *  detection never fails.
+ *
+ * Return:        boolean -- false always for HL
+ */
+static inline bool
+htt_rx_mpdu_desc_retry_hl(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	return false;
+}
+
+static int
+htt_rx_amsdu_pop_hl(
+	htt_pdev_handle pdev,
+	qdf_nbuf_t rx_ind_msg,
+	qdf_nbuf_t *head_msdu,
+	qdf_nbuf_t *tail_msdu,
+	uint32_t *msdu_count)
+{
+	pdev->rx_desc_size_hl =
+		(qdf_nbuf_data(rx_ind_msg))
+		[HTT_ENDIAN_BYTE_IDX_SWAP(
+				HTT_RX_IND_HL_RX_DESC_LEN_OFFSET)];
+
+	/* point to the rx desc */
+	qdf_nbuf_pull_head(rx_ind_msg,
+			   sizeof(struct hl_htt_rx_ind_base));
+	*head_msdu = *tail_msdu = rx_ind_msg;
+
+	htt_set_checksum_result_hl(rx_ind_msg,
+				   (struct htt_host_rx_desc_base *)
+				   (qdf_nbuf_data(rx_ind_msg)));
+
+	qdf_nbuf_set_next(*tail_msdu, NULL);
+	return 0;
+}
+
+static int
+htt_rx_frag_pop_hl(
+	htt_pdev_handle pdev,
+	qdf_nbuf_t frag_msg,
+	qdf_nbuf_t *head_msdu,
+	qdf_nbuf_t *tail_msdu,
+	uint32_t *msdu_count)
+{
+	qdf_nbuf_pull_head(frag_msg, HTT_RX_FRAG_IND_BYTES);
+	pdev->rx_desc_size_hl =
+		(qdf_nbuf_data(frag_msg))
+		[HTT_ENDIAN_BYTE_IDX_SWAP(
+				HTT_RX_IND_HL_RX_DESC_LEN_OFFSET)];
+
+	/* point to the rx desc */
+	qdf_nbuf_pull_head(frag_msg,
+			   sizeof(struct hl_htt_rx_ind_base));
+	*head_msdu = *tail_msdu = frag_msg;
+
+	qdf_nbuf_set_next(*tail_msdu, NULL);
+	return 0;
+}
+
+static inline int
+htt_rx_offload_msdu_cnt_hl(htt_pdev_handle pdev)
+{
+	return 1;
+}
+
+static inline int
+htt_rx_offload_msdu_pop_hl(htt_pdev_handle pdev,
+			   qdf_nbuf_t offload_deliver_msg,
+			   int *vdev_id,
+			   int *peer_id,
+			   int *tid,
+			   u_int8_t *fw_desc,
+			   qdf_nbuf_t *head_buf,
+			   qdf_nbuf_t *tail_buf)
+{
+	qdf_nbuf_t buf;
+	u_int32_t *msdu_hdr, msdu_len;
+	int ret = 0;
+
+	*head_buf = *tail_buf = buf = offload_deliver_msg;
+	msdu_hdr = (u_int32_t *)qdf_nbuf_data(buf);
+	/* First dword */
+
+	/* Second dword */
+	msdu_hdr++;
+	msdu_len = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_GET(*msdu_hdr);
+	*peer_id = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_GET(*msdu_hdr);
+
+	/* Third dword */
+	msdu_hdr++;
+	*vdev_id = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_GET(*msdu_hdr);
+	*tid = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_GET(*msdu_hdr);
+	*fw_desc = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_GET(*msdu_hdr);
+
+	qdf_nbuf_pull_head(buf, HTT_RX_OFFLOAD_DELIVER_IND_MSDU_HDR_BYTES
+			+ HTT_RX_OFFLOAD_DELIVER_IND_HDR_BYTES);
+
+	if (msdu_len <= qdf_nbuf_len(buf)) {
+		qdf_nbuf_set_pktlen(buf, msdu_len);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "%s: drop frame with invalid msdu len %d %d",
+			  __func__, msdu_len, (int)qdf_nbuf_len(buf));
+		qdf_nbuf_free(offload_deliver_msg);
+		ret = -1;
+	}
+
+	return ret;
+}
+
+static uint16_t
+htt_rx_mpdu_desc_seq_num_hl(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	if (pdev->rx_desc_size_hl) {
+		return pdev->cur_seq_num_hl =
+			(u_int16_t)(HTT_WORD_GET(*(u_int32_t *)mpdu_desc,
+						HTT_HL_RX_DESC_MPDU_SEQ_NUM));
+	} else {
+		return (u_int16_t)(pdev->cur_seq_num_hl);
+	}
+}
+
+static void
+htt_rx_mpdu_desc_pn_hl(
+	htt_pdev_handle pdev,
+	void *mpdu_desc,
+	union htt_rx_pn_t *pn,
+	int pn_len_bits)
+{
+	if (htt_rx_msdu_first_msdu_flag_hl(pdev, mpdu_desc) == true) {
+		/* Fix Me: only for little endian */
+		struct hl_htt_rx_desc_base *rx_desc =
+			(struct hl_htt_rx_desc_base *)mpdu_desc;
+		u_int32_t *word_ptr = (u_int32_t *)pn->pn128;
+
+		/* TODO: for Host of big endian */
+		switch (pn_len_bits) {
+		case 128:
+			/* bits 128:64 */
+			*(word_ptr + 3) = rx_desc->pn_127_96;
+			/* bits 63:0 */
+			*(word_ptr + 2) = rx_desc->pn_95_64;
+		case 48:
+			/* bits 48:0
+			 * copy 64 bits
+			 */
+			*(word_ptr + 1) = rx_desc->u0.pn_63_32;
+		case 24:
+			/* bits 23:0
+			 * copy 32 bits
+			 */
+			*(word_ptr + 0) = rx_desc->pn_31_0;
+			break;
+		default:
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+				  "Error: invalid length spec (%d bits) for PN",
+				  pn_len_bits);
+			qdf_assert(0);
+			break;
+		};
+	} else {
+		/* not first msdu, no pn info */
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "Error: get pn from a not-first msdu.");
+		qdf_assert(0);
+	}
+}
+
+/**
+ * htt_rx_mpdu_desc_tid_hl() - Returns the TID value from the Rx descriptor
+ *                             for High Latency driver
+ * @pdev:                        Handle (pointer) to HTT pdev.
+ * @mpdu_desc:                   Void pointer to the Rx descriptor for the MPDU
+ *                               before the beginning of the payload.
+ *
+ * This function returns the TID set in the 802.11 QoS Control for the MPDU
+ * in the packet header, by looking at the mpdu_start of the Rx descriptor.
+ * Rx descriptor gets a copy of the TID from the MAC.
+ * For the HL driver, this is currently uimplemented and always returns
+ * an invalid tid. It is the responsibility of the caller to make
+ * sure that return value is checked for valid range.
+ *
+ * Return:        Invalid TID value (0xff) for HL driver.
+ */
+static inline uint8_t
+htt_rx_mpdu_desc_tid_hl(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	return 0xff;  /* Invalid TID */
+}
+
+static inline bool
+htt_rx_msdu_desc_completes_mpdu_hl(htt_pdev_handle pdev, void *msdu_desc)
+{
+	return (
+		((u_int8_t *)(msdu_desc) - sizeof(struct hl_htt_rx_ind_base))
+		[HTT_ENDIAN_BYTE_IDX_SWAP(HTT_RX_IND_HL_FLAG_OFFSET)]
+		& HTT_RX_IND_HL_FLAG_LAST_MSDU)
+		? true : false;
+}
+
+static inline int
+htt_rx_msdu_has_wlan_mcast_flag_hl(htt_pdev_handle pdev, void *msdu_desc)
+{
+	/* currently, only first msdu has hl rx_desc */
+	return htt_rx_msdu_first_msdu_flag_hl(pdev, msdu_desc) == true;
+}
+
+static inline bool
+htt_rx_msdu_is_wlan_mcast_hl(htt_pdev_handle pdev, void *msdu_desc)
+{
+	struct hl_htt_rx_desc_base *rx_desc =
+		(struct hl_htt_rx_desc_base *)msdu_desc;
+
+	return
+		HTT_WORD_GET(*(u_int32_t *)rx_desc, HTT_HL_RX_DESC_MCAST_BCAST);
+}
+
+static inline int
+htt_rx_msdu_is_frag_hl(htt_pdev_handle pdev, void *msdu_desc)
+{
+	struct hl_htt_rx_desc_base *rx_desc =
+		(struct hl_htt_rx_desc_base *)msdu_desc;
+
+	return
+		HTT_WORD_GET(*(u_int32_t *)rx_desc, HTT_HL_RX_DESC_MCAST_BCAST);
+}
+
+int htt_rx_attach(struct htt_pdev_t *pdev)
+{
+	pdev->rx_ring.size = HTT_RX_RING_SIZE_MIN;
+	HTT_ASSERT2(IS_PWR2(pdev->rx_ring.size));
+	pdev->rx_ring.size_mask = pdev->rx_ring.size - 1;
+	/* host can force ring base address if it wish to do so */
+	pdev->rx_ring.base_paddr = 0;
+	htt_rx_amsdu_pop = htt_rx_amsdu_pop_hl;
+	htt_rx_frag_pop = htt_rx_frag_pop_hl;
+	htt_rx_offload_msdu_cnt = htt_rx_offload_msdu_cnt_hl;
+	htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_hl;
+	htt_rx_mpdu_desc_list_next = htt_rx_mpdu_desc_list_next_hl;
+	htt_rx_mpdu_desc_retry = htt_rx_mpdu_desc_retry_hl;
+	htt_rx_mpdu_desc_seq_num = htt_rx_mpdu_desc_seq_num_hl;
+	htt_rx_mpdu_desc_pn = htt_rx_mpdu_desc_pn_hl;
+	htt_rx_mpdu_desc_tid = htt_rx_mpdu_desc_tid_hl;
+	htt_rx_msdu_desc_completes_mpdu = htt_rx_msdu_desc_completes_mpdu_hl;
+	htt_rx_msdu_first_msdu_flag = htt_rx_msdu_first_msdu_flag_hl;
+	htt_rx_msdu_has_wlan_mcast_flag = htt_rx_msdu_has_wlan_mcast_flag_hl;
+	htt_rx_msdu_is_wlan_mcast = htt_rx_msdu_is_wlan_mcast_hl;
+	htt_rx_msdu_is_frag = htt_rx_msdu_is_frag_hl;
+	htt_rx_msdu_desc_retrieve = htt_rx_msdu_desc_retrieve_hl;
+	htt_rx_mpdu_is_encrypted = htt_rx_mpdu_is_encrypted_hl;
+	htt_rx_msdu_desc_key_id = htt_rx_msdu_desc_key_id_hl;
+	htt_rx_msdu_chan_info_present = htt_rx_msdu_chan_info_present_hl;
+	htt_rx_msdu_center_freq = htt_rx_msdu_center_freq_hl;
+
+	/*
+	 * HL case, the rx descriptor can be different sizes for
+	 * different sub-types of RX_IND messages, e.g. for the
+	 * initial vs. interior vs. final MSDUs within a PPDU.
+	 * The size of each RX_IND message's rx desc is read from
+	 * a field within the RX_IND message itself.
+	 * In the meantime, until the rx_desc_size_hl variable is
+	 * set to its real value based on the RX_IND message,
+	 * initialize it to a reasonable value (zero).
+	 */
+	pdev->rx_desc_size_hl = 0;
+	return 0;	/* success */
+}
diff --git a/core/dp/htt/htt_rx_ll.c b/core/dp/htt/htt_rx_ll.c
new file mode 100644
index 0000000..80d6b32
--- /dev/null
+++ b/core/dp/htt/htt_rx_ll.c
@@ -0,0 +1,2323 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#include <qdf_mem.h>         /* qdf_mem_malloc,free, etc. */
+#include <qdf_types.h>          /* qdf_print, bool */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_timer.h>		/* qdf_timer_free */
+
+#include <htt.h>                /* HTT_HL_RX_DESC_SIZE */
+#include <ol_cfg.h>
+#include <ol_rx.h>
+#include <ol_htt_rx_api.h>
+#include <htt_internal.h>       /* HTT_ASSERT, htt_pdev_t, HTT_RX_BUF_SIZE */
+#include "regtable.h"
+
+#include <cds_ieee80211_common.h>   /* ieee80211_frame, ieee80211_qoscntl */
+#include <cds_ieee80211_defines.h>  /* ieee80211_rx_status */
+#include <cds_utils.h>
+#include <wlan_policy_mgr_api.h>
+#include "ol_txrx_types.h"
+#ifdef DEBUG_DMA_DONE
+#include <asm/barrier.h>
+#include <wma_api.h>
+#endif
+#include <pktlog_ac_fmt.h>
+
+#ifdef DEBUG_DMA_DONE
+#define MAX_DONE_BIT_CHECK_ITER 5
+#endif
+
+#define AR600P_ASSEMBLE_HW_RATECODE(_rate, _nss, _pream)     \
+	(((_pream) << 6) | ((_nss) << 4) | (_rate))
+
+enum AR600P_HW_RATECODE_PREAM_TYPE {
+	AR600P_HW_RATECODE_PREAM_OFDM,
+	AR600P_HW_RATECODE_PREAM_CCK,
+	AR600P_HW_RATECODE_PREAM_HT,
+	AR600P_HW_RATECODE_PREAM_VHT,
+};
+
+#ifdef HTT_DEBUG_DATA
+#define HTT_PKT_DUMP(x) x
+#else
+#define HTT_PKT_DUMP(x) /* no-op */
+#endif
+
+/*--- setup / tear-down functions -------------------------------------------*/
+
+#ifndef HTT_RX_HOST_LATENCY_MAX_MS
+#define HTT_RX_HOST_LATENCY_MAX_MS 20 /* ms */	/* very conservative */
+#endif
+
+ /* very conservative to ensure enough buffers are allocated */
+#ifndef HTT_RX_HOST_LATENCY_WORST_LIKELY_MS
+#ifdef QCA_WIFI_3_0
+#define HTT_RX_HOST_LATENCY_WORST_LIKELY_MS 20
+#else
+#define HTT_RX_HOST_LATENCY_WORST_LIKELY_MS 10
+#endif
+#endif
+
+#ifndef HTT_RX_RING_REFILL_RETRY_TIME_MS
+#define HTT_RX_RING_REFILL_RETRY_TIME_MS    50
+#endif
+
+#define RX_PADDR_MAGIC_PATTERN 0xDEAD0000
+
+#ifdef ENABLE_DEBUG_ADDRESS_MARKING
+static qdf_dma_addr_t
+htt_rx_paddr_mark_high_bits(qdf_dma_addr_t paddr)
+{
+	if (sizeof(qdf_dma_addr_t) > 4) {
+		/* clear high bits, leave lower 37 bits (paddr) */
+		paddr &= 0x01FFFFFFFFF;
+		/* mark upper 16 bits of paddr */
+		paddr |= (((uint64_t)RX_PADDR_MAGIC_PATTERN) << 32);
+	}
+	return paddr;
+}
+#else
+static qdf_dma_addr_t
+htt_rx_paddr_mark_high_bits(qdf_dma_addr_t paddr)
+{
+	return paddr;
+}
+#endif
+
+/**
+ * htt_get_first_packet_after_wow_wakeup() - get first packet after wow wakeup
+ * @msg_word: pointer to rx indication message word
+ * @buf: pointer to buffer
+ *
+ * Return: None
+ */
+static void
+htt_get_first_packet_after_wow_wakeup(uint32_t *msg_word, qdf_nbuf_t buf)
+{
+	if (HTT_RX_IN_ORD_PADDR_IND_MSDU_INFO_GET(*msg_word) &
+			FW_MSDU_INFO_FIRST_WAKEUP_M) {
+		qdf_nbuf_mark_wakeup_frame(buf);
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+			  "%s: First packet after WOW Wakeup rcvd", __func__);
+	}
+}
+
+static inline qdf_nbuf_t htt_rx_netbuf_pop(htt_pdev_handle pdev)
+{
+	int idx;
+	qdf_nbuf_t msdu;
+
+	HTT_ASSERT1(htt_rx_ring_elems(pdev) != 0);
+
+#ifdef DEBUG_DMA_DONE
+	pdev->rx_ring.dbg_ring_idx++;
+	pdev->rx_ring.dbg_ring_idx &= pdev->rx_ring.size_mask;
+#endif
+
+	idx = pdev->rx_ring.sw_rd_idx.msdu_payld;
+	msdu = pdev->rx_ring.buf.netbufs_ring[idx];
+	idx++;
+	idx &= pdev->rx_ring.size_mask;
+	pdev->rx_ring.sw_rd_idx.msdu_payld = idx;
+	pdev->rx_ring.fill_cnt--;
+	return msdu;
+}
+
+static inline unsigned int htt_rx_ring_elems(struct htt_pdev_t *pdev)
+{
+	return
+		(*pdev->rx_ring.alloc_idx.vaddr -
+		 pdev->rx_ring.sw_rd_idx.msdu_payld) & pdev->rx_ring.size_mask;
+}
+
+/**
+ * htt_rx_buff_pool_init() - initialize the pool of buffers
+ * @pdev: pointer to device
+ *
+ * Return: 0 - success, 1 - failure
+ */
+static int htt_rx_buff_pool_init(struct htt_pdev_t *pdev)
+{
+	qdf_nbuf_t net_buf;
+	int i;
+
+	pdev->rx_buff_pool.netbufs_ring =
+		qdf_mem_malloc(HTT_RX_PRE_ALLOC_POOL_SIZE * sizeof(qdf_nbuf_t));
+
+	if (!pdev->rx_buff_pool.netbufs_ring)
+		return 1; /* failure */
+
+	qdf_atomic_init(&pdev->rx_buff_pool.fill_cnt);
+	qdf_atomic_init(&pdev->rx_buff_pool.refill_low_mem);
+
+	for (i = 0; i < HTT_RX_PRE_ALLOC_POOL_SIZE; i++) {
+		net_buf = qdf_nbuf_alloc(pdev->osdev,
+					 HTT_RX_BUF_SIZE,
+					 0, 4, false);
+		if (net_buf) {
+			qdf_atomic_inc(&pdev->rx_buff_pool.fill_cnt);
+			/*
+			 * Mark this netbuf to differentiate it
+			 * from other buf. If set 1, this buf
+			 * is from pre allocated pool.
+			 */
+			QDF_NBUF_CB_RX_PACKET_BUFF_POOL(net_buf) = 1;
+		}
+		/* Allow NULL to be inserted.
+		 * Taken care during alloc from this pool.
+		 */
+		pdev->rx_buff_pool.netbufs_ring[i] = net_buf;
+	}
+	QDF_TRACE(QDF_MODULE_ID_HTT,
+		  QDF_TRACE_LEVEL_INFO,
+		  "max pool size %d pool filled %d",
+		  HTT_RX_PRE_ALLOC_POOL_SIZE,
+		  qdf_atomic_read(&pdev->rx_buff_pool.fill_cnt));
+
+	qdf_spinlock_create(&pdev->rx_buff_pool.rx_buff_pool_lock);
+	return 0;
+}
+
+/**
+ * htt_rx_buff_pool_deinit() - deinitialize the pool of buffers
+ * @pdev: pointer to device
+ *
+ * Return: none
+ */
+static void htt_rx_buff_pool_deinit(struct htt_pdev_t *pdev)
+{
+	qdf_nbuf_t net_buf;
+	int i;
+
+	if (!pdev->rx_buff_pool.netbufs_ring)
+		return;
+
+	qdf_spin_lock_bh(&pdev->rx_buff_pool.rx_buff_pool_lock);
+	for (i = 0; i < HTT_RX_PRE_ALLOC_POOL_SIZE; i++) {
+		net_buf = pdev->rx_buff_pool.netbufs_ring[i];
+		if (!net_buf)
+			continue;
+		qdf_nbuf_free(net_buf);
+		qdf_atomic_dec(&pdev->rx_buff_pool.fill_cnt);
+	}
+	qdf_spin_unlock_bh(&pdev->rx_buff_pool.rx_buff_pool_lock);
+	QDF_TRACE(QDF_MODULE_ID_HTT,
+		  QDF_TRACE_LEVEL_INFO,
+		  "max pool size %d pool filled %d",
+		  HTT_RX_PRE_ALLOC_POOL_SIZE,
+		  qdf_atomic_read(&pdev->rx_buff_pool.fill_cnt));
+
+	qdf_mem_free(pdev->rx_buff_pool.netbufs_ring);
+	qdf_spinlock_destroy(&pdev->rx_buff_pool.rx_buff_pool_lock);
+}
+
+/**
+ * htt_rx_buff_pool_refill() - refill the pool with new buf or reuse same buf
+ * @pdev: pointer to device
+ * @netbuf: netbuf to reuse
+ *
+ * Return: true - if able to alloc new buf and insert into pool,
+ * false - if need to reuse the netbuf or not able to insert into pool
+ */
+static bool htt_rx_buff_pool_refill(struct htt_pdev_t *pdev, qdf_nbuf_t netbuf)
+{
+	bool ret = false;
+	qdf_nbuf_t net_buf;
+	int i;
+
+	net_buf = qdf_nbuf_alloc(pdev->osdev,
+				 HTT_RX_BUF_SIZE,
+				 0, 4, false);
+	if (net_buf) {
+		/* able to alloc new net_buf.
+		 * mark this netbuf as pool buf.
+		 */
+		QDF_NBUF_CB_RX_PACKET_BUFF_POOL(net_buf) = 1;
+		ret = true;
+	} else {
+		/* reuse the netbuf and
+		 * reset all fields of this netbuf.
+		 */
+		net_buf = netbuf;
+		qdf_nbuf_reset(net_buf, 0, 4);
+
+		/* mark this netbuf as pool buf */
+		QDF_NBUF_CB_RX_PACKET_BUFF_POOL(net_buf) = 1;
+	}
+
+	qdf_spin_lock_bh(&pdev->rx_buff_pool.rx_buff_pool_lock);
+	for (i = 0; i < HTT_RX_PRE_ALLOC_POOL_SIZE; i++) {
+		/* insert the netbuf in empty slot of pool */
+		if (pdev->rx_buff_pool.netbufs_ring[i])
+			continue;
+
+		pdev->rx_buff_pool.netbufs_ring[i] = net_buf;
+		qdf_atomic_inc(&pdev->rx_buff_pool.fill_cnt);
+		break;
+	}
+	qdf_spin_unlock_bh(&pdev->rx_buff_pool.rx_buff_pool_lock);
+
+	if (i == HTT_RX_PRE_ALLOC_POOL_SIZE) {
+		/* fail to insert into pool, free net_buf */
+		qdf_nbuf_free(net_buf);
+		ret = false;
+	}
+
+	return ret;
+}
+
+/**
+ * htt_rx_buff_alloc() - alloc the net buf from the pool
+ * @pdev: pointer to device
+ *
+ * Return: nbuf or NULL
+ */
+static qdf_nbuf_t htt_rx_buff_alloc(struct htt_pdev_t *pdev)
+{
+	qdf_nbuf_t net_buf = NULL;
+	int i;
+
+	if (!pdev->rx_buff_pool.netbufs_ring)
+		return net_buf;
+
+	qdf_spin_lock_bh(&pdev->rx_buff_pool.rx_buff_pool_lock);
+	for (i = 0; i < HTT_RX_PRE_ALLOC_POOL_SIZE; i++) {
+		/* allocate the valid netbuf */
+		if (!pdev->rx_buff_pool.netbufs_ring[i])
+			continue;
+
+		net_buf = pdev->rx_buff_pool.netbufs_ring[i];
+		qdf_atomic_dec(&pdev->rx_buff_pool.fill_cnt);
+		pdev->rx_buff_pool.netbufs_ring[i] = NULL;
+		break;
+	}
+	qdf_spin_unlock_bh(&pdev->rx_buff_pool.rx_buff_pool_lock);
+	return net_buf;
+}
+
+/**
+ * htt_rx_ring_buf_attach() - retrun net buf to attach in ring
+ * @pdev: pointer to device
+ *
+ * Return: nbuf or NULL
+ */
+static qdf_nbuf_t htt_rx_ring_buf_attach(struct htt_pdev_t *pdev)
+{
+	qdf_nbuf_t net_buf = NULL;
+	bool allocated = true;
+
+	net_buf =
+		qdf_nbuf_alloc(pdev->osdev, HTT_RX_BUF_SIZE,
+			       0, 4, false);
+	if (!net_buf) {
+		if (pdev->rx_buff_pool.netbufs_ring &&
+		    qdf_atomic_read(&pdev->rx_buff_pool.refill_low_mem) &&
+		    qdf_atomic_read(&pdev->rx_buff_pool.fill_cnt))
+			net_buf = htt_rx_buff_alloc(pdev);
+
+		allocated = false; /* allocated from pool */
+	}
+
+	if (allocated || !qdf_atomic_read(&pdev->rx_buff_pool.fill_cnt))
+		qdf_atomic_set(&pdev->rx_buff_pool.refill_low_mem, 0);
+
+	return net_buf;
+}
+
+/**
+ * htt_rx_ring_buff_free() - free the net buff or reuse it
+ * @pdev: pointer to device
+ * @netbuf: netbuf
+ *
+ * Return: none
+ */
+static void htt_rx_ring_buff_free(struct htt_pdev_t *pdev, qdf_nbuf_t netbuf)
+{
+	bool status = false;
+
+	if (pdev->rx_buff_pool.netbufs_ring &&
+	    QDF_NBUF_CB_RX_PACKET_BUFF_POOL(netbuf)) {
+		int i;
+
+		/* rest this netbuf before putting back into pool */
+		qdf_nbuf_reset(netbuf, 0, 4);
+
+		/* mark this netbuf as pool buf */
+		QDF_NBUF_CB_RX_PACKET_BUFF_POOL(netbuf) = 1;
+
+		qdf_spin_lock_bh(&pdev->rx_buff_pool.rx_buff_pool_lock);
+		for (i = 0; i < HTT_RX_PRE_ALLOC_POOL_SIZE; i++) {
+			/* insert the netbuf in empty slot of pool */
+			if (!pdev->rx_buff_pool.netbufs_ring[i]) {
+				pdev->rx_buff_pool.netbufs_ring[i] = netbuf;
+				qdf_atomic_inc(&pdev->rx_buff_pool.fill_cnt);
+				status = true;    /* valid insertion */
+				break;
+			}
+		}
+		qdf_spin_unlock_bh(&pdev->rx_buff_pool.rx_buff_pool_lock);
+	}
+	if (!status)
+		qdf_nbuf_free(netbuf);
+}
+
+/* full_reorder_offload case: this function is called with lock held */
+static int htt_rx_ring_fill_n(struct htt_pdev_t *pdev, int num)
+{
+	int idx;
+	QDF_STATUS status;
+	struct htt_host_rx_desc_base *rx_desc;
+	int filled = 0;
+	int debt_served = 0;
+	qdf_mem_info_t mem_map_table = {0};
+	bool ipa_smmu = false;
+
+	idx = *pdev->rx_ring.alloc_idx.vaddr;
+
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev) && pdev->is_ipa_uc_enabled &&
+	    pdev->rx_ring.smmu_map)
+		ipa_smmu = true;
+
+	if ((idx < 0) || (idx > pdev->rx_ring.size_mask) ||
+	    (num > pdev->rx_ring.size))  {
+		QDF_TRACE(QDF_MODULE_ID_HTT,
+			  QDF_TRACE_LEVEL_ERROR,
+			  "%s:rx refill failed!", __func__);
+		return filled;
+	}
+
+moretofill:
+	while (num > 0) {
+		qdf_dma_addr_t paddr, paddr_marked;
+		qdf_nbuf_t rx_netbuf;
+		int headroom;
+
+		rx_netbuf = htt_rx_ring_buf_attach(pdev);
+		if (!rx_netbuf) {
+			qdf_timer_stop(&pdev->rx_ring.
+						 refill_retry_timer);
+			/*
+			 * Failed to fill it to the desired level -
+			 * we'll start a timer and try again next time.
+			 * As long as enough buffers are left in the ring for
+			 * another A-MPDU rx, no special recovery is needed.
+			 */
+#ifdef DEBUG_DMA_DONE
+			pdev->rx_ring.dbg_refill_cnt++;
+#endif
+			pdev->refill_retry_timer_starts++;
+			qdf_timer_start(
+				&pdev->rx_ring.refill_retry_timer,
+				HTT_RX_RING_REFILL_RETRY_TIME_MS);
+			goto update_alloc_idx;
+		}
+
+		/* Clear rx_desc attention word before posting to Rx ring */
+		rx_desc = htt_rx_desc(rx_netbuf);
+		*(uint32_t *)&rx_desc->attention = 0;
+
+#ifdef DEBUG_DMA_DONE
+		*(uint32_t *)&rx_desc->msdu_end = 1;
+
+#define MAGIC_PATTERN 0xDEADBEEF
+		*(uint32_t *)&rx_desc->msdu_start = MAGIC_PATTERN;
+
+		/*
+		 * To ensure that attention bit is reset and msdu_end is set
+		 * before calling dma_map
+		 */
+		smp_mb();
+#endif
+		/*
+		 * Adjust qdf_nbuf_data to point to the location in the buffer
+		 * where the rx descriptor will be filled in.
+		 */
+		headroom = qdf_nbuf_data(rx_netbuf) - (uint8_t *)rx_desc;
+		qdf_nbuf_push_head(rx_netbuf, headroom);
+
+#ifdef DEBUG_DMA_DONE
+		status = qdf_nbuf_map(pdev->osdev, rx_netbuf,
+				      QDF_DMA_BIDIRECTIONAL);
+#else
+		status = qdf_nbuf_map(pdev->osdev, rx_netbuf,
+				      QDF_DMA_FROM_DEVICE);
+#endif
+		if (status != QDF_STATUS_SUCCESS) {
+			htt_rx_ring_buff_free(pdev, rx_netbuf);
+			goto update_alloc_idx;
+		}
+
+		paddr = qdf_nbuf_get_frag_paddr(rx_netbuf, 0);
+		paddr_marked = htt_rx_paddr_mark_high_bits(paddr);
+		if (pdev->cfg.is_full_reorder_offload) {
+			if (qdf_unlikely(htt_rx_hash_list_insert(
+					pdev, paddr_marked, rx_netbuf))) {
+				QDF_TRACE(QDF_MODULE_ID_HTT,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "%s: hash insert failed!", __func__);
+#ifdef DEBUG_DMA_DONE
+				qdf_nbuf_unmap(pdev->osdev, rx_netbuf,
+					       QDF_DMA_BIDIRECTIONAL);
+#else
+				qdf_nbuf_unmap(pdev->osdev, rx_netbuf,
+					       QDF_DMA_FROM_DEVICE);
+#endif
+				htt_rx_ring_buff_free(pdev, rx_netbuf);
+
+				goto update_alloc_idx;
+			}
+			htt_rx_dbg_rxbuf_set(pdev, paddr_marked, rx_netbuf);
+		} else {
+			pdev->rx_ring.buf.netbufs_ring[idx] = rx_netbuf;
+		}
+
+		if (ipa_smmu) {
+			qdf_update_mem_map_table(pdev->osdev, &mem_map_table,
+						 paddr, HTT_RX_BUF_SIZE);
+			cds_smmu_map_unmap(true, 1, &mem_map_table);
+		}
+
+		pdev->rx_ring.buf.paddrs_ring[idx] = paddr_marked;
+		pdev->rx_ring.fill_cnt++;
+
+		num--;
+		idx++;
+		filled++;
+		idx &= pdev->rx_ring.size_mask;
+	}
+
+	if (debt_served <  qdf_atomic_read(&pdev->rx_ring.refill_debt)) {
+		num = qdf_atomic_read(&pdev->rx_ring.refill_debt);
+		debt_served += num;
+		goto moretofill;
+	}
+
+update_alloc_idx:
+	/*
+	 * Make sure alloc index write is reflected correctly before FW polls
+	 * remote ring write index as compiler can reorder the instructions
+	 * based on optimizations.
+	 */
+	qdf_mb();
+	*pdev->rx_ring.alloc_idx.vaddr = idx;
+	htt_rx_dbg_rxbuf_indupd(pdev, idx);
+
+	return filled;
+}
+
+static int htt_rx_ring_size(struct htt_pdev_t *pdev)
+{
+	int size;
+
+	/*
+	 * It is expected that the host CPU will typically be able to service
+	 * the rx indication from one A-MPDU before the rx indication from
+	 * the subsequent A-MPDU happens, roughly 1-2 ms later.
+	 * However, the rx ring should be sized very conservatively, to
+	 * accommodate the worst reasonable delay before the host CPU services
+	 * a rx indication interrupt.
+	 * The rx ring need not be kept full of empty buffers.  In theory,
+	 * the htt host SW can dynamically track the low-water mark in the
+	 * rx ring, and dynamically adjust the level to which the rx ring
+	 * is filled with empty buffers, to dynamically meet the desired
+	 * low-water mark.
+	 * In contrast, it's difficult to resize the rx ring itself, once
+	 * it's in use.
+	 * Thus, the ring itself should be sized very conservatively, while
+	 * the degree to which the ring is filled with empty buffers should
+	 * be sized moderately conservatively.
+	 */
+	size =
+		ol_cfg_max_thruput_mbps(pdev->ctrl_pdev) *
+		1000 /* 1e6 bps/mbps / 1e3 ms per sec = 1000 */  /
+		(8 * HTT_RX_AVG_FRM_BYTES) * HTT_RX_HOST_LATENCY_MAX_MS;
+
+	if (size < HTT_RX_RING_SIZE_MIN)
+		size = HTT_RX_RING_SIZE_MIN;
+	else if (size > HTT_RX_RING_SIZE_MAX)
+		size = HTT_RX_RING_SIZE_MAX;
+
+	size = qdf_get_pwr2(size);
+	return size;
+}
+
+static int htt_rx_ring_fill_level(struct htt_pdev_t *pdev)
+{
+	int size;
+
+	size = ol_cfg_max_thruput_mbps(pdev->ctrl_pdev) *
+		1000 /* 1e6 bps/mbps / 1e3 ms per sec = 1000 */  /
+		(8 * HTT_RX_AVG_FRM_BYTES) *
+		HTT_RX_HOST_LATENCY_WORST_LIKELY_MS;
+
+	size = qdf_get_pwr2(size);
+	/*
+	 * Make sure the fill level is at least 1 less than the ring size.
+	 * Leaving 1 element empty allows the SW to easily distinguish
+	 * between a full ring vs. an empty ring.
+	 */
+	if (size >= pdev->rx_ring.size)
+		size = pdev->rx_ring.size - 1;
+
+	return size;
+}
+
+static void htt_rx_ring_refill_retry(void *arg)
+{
+	htt_pdev_handle pdev = (htt_pdev_handle)arg;
+	int filled = 0;
+	int num;
+
+	pdev->refill_retry_timer_calls++;
+	qdf_spin_lock_bh(&pdev->rx_ring.refill_lock);
+
+	num = qdf_atomic_read(&pdev->rx_ring.refill_debt);
+	qdf_atomic_sub(num, &pdev->rx_ring.refill_debt);
+
+	qdf_atomic_set(&pdev->rx_buff_pool.refill_low_mem, 1);
+
+	filled = htt_rx_ring_fill_n(pdev, num);
+
+	if (filled > num) {
+		/* we served ourselves and some other debt */
+		/* sub is safer than  = 0 */
+		qdf_atomic_sub(filled - num, &pdev->rx_ring.refill_debt);
+	} else if (num == filled) { /* nothing to be done */
+	} else {
+		qdf_atomic_add(num - filled, &pdev->rx_ring.refill_debt);
+		/* we could not fill all, timer must have been started */
+		pdev->refill_retry_timer_doubles++;
+	}
+	qdf_spin_unlock_bh(&pdev->rx_ring.refill_lock);
+}
+
+/*--- rx descriptor field access functions ----------------------------------*/
+/*
+ * These functions need to use bit masks and shifts to extract fields
+ * from the rx descriptors, rather than directly using the bitfields.
+ * For example, use
+ *     (desc & FIELD_MASK) >> FIELD_LSB
+ * rather than
+ *     desc.field
+ * This allows the functions to work correctly on either little-endian
+ * machines (no endianness conversion needed) or big-endian machines
+ * (endianness conversion provided automatically by the HW DMA's
+ * byte-swizzling).
+ */
+
+#ifdef CHECKSUM_OFFLOAD
+static inline void
+htt_set_checksum_result_ll(htt_pdev_handle pdev, qdf_nbuf_t msdu,
+			   struct htt_host_rx_desc_base *rx_desc)
+{
+#define MAX_IP_VER          2
+#define MAX_PROTO_VAL       4
+	struct rx_msdu_start *rx_msdu = &rx_desc->msdu_start;
+	unsigned int proto = (rx_msdu->tcp_proto) | (rx_msdu->udp_proto << 1);
+
+	/*
+	 * HW supports TCP & UDP checksum offload for ipv4 and ipv6
+	 */
+	static const qdf_nbuf_l4_rx_cksum_type_t
+		cksum_table[][MAX_PROTO_VAL][MAX_IP_VER] = {
+		{
+			/* non-fragmented IP packet */
+			/* non TCP/UDP packet */
+			{QDF_NBUF_RX_CKSUM_ZERO, QDF_NBUF_RX_CKSUM_ZERO},
+			/* TCP packet */
+			{QDF_NBUF_RX_CKSUM_TCP, QDF_NBUF_RX_CKSUM_TCPIPV6},
+			/* UDP packet */
+			{QDF_NBUF_RX_CKSUM_UDP, QDF_NBUF_RX_CKSUM_UDPIPV6},
+			/* invalid packet type */
+			{QDF_NBUF_RX_CKSUM_ZERO, QDF_NBUF_RX_CKSUM_ZERO},
+		},
+		{
+			/* fragmented IP packet */
+			{QDF_NBUF_RX_CKSUM_ZERO, QDF_NBUF_RX_CKSUM_ZERO},
+			{QDF_NBUF_RX_CKSUM_ZERO, QDF_NBUF_RX_CKSUM_ZERO},
+			{QDF_NBUF_RX_CKSUM_ZERO, QDF_NBUF_RX_CKSUM_ZERO},
+			{QDF_NBUF_RX_CKSUM_ZERO, QDF_NBUF_RX_CKSUM_ZERO},
+		}
+	};
+
+	qdf_nbuf_rx_cksum_t cksum = {
+		cksum_table[rx_msdu->ip_frag][proto][rx_msdu->ipv6_proto],
+		QDF_NBUF_RX_CKSUM_NONE,
+		0
+	};
+
+	if (cksum.l4_type !=
+	    (qdf_nbuf_l4_rx_cksum_type_t)QDF_NBUF_RX_CKSUM_NONE) {
+		cksum.l4_result =
+			((*(uint32_t *)&rx_desc->attention) &
+			 RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK) ?
+			QDF_NBUF_RX_CKSUM_NONE :
+			QDF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY;
+	}
+	qdf_nbuf_set_rx_cksum(msdu, &cksum);
+#undef MAX_IP_VER
+#undef MAX_PROTO_VAL
+}
+
+#else
+
+static inline
+void htt_set_checksum_result_ll(htt_pdev_handle pdev, qdf_nbuf_t msdu,
+				struct htt_host_rx_desc_base *rx_desc)
+{
+}
+
+#endif
+
+static void *htt_rx_msdu_desc_retrieve_ll(htt_pdev_handle pdev, qdf_nbuf_t msdu)
+{
+	return htt_rx_desc(msdu);
+}
+
+static bool htt_rx_mpdu_is_encrypted_ll(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	struct htt_host_rx_desc_base *rx_desc =
+		(struct htt_host_rx_desc_base *)mpdu_desc;
+
+	return (((*((uint32_t *)&rx_desc->mpdu_start)) &
+		 RX_MPDU_START_0_ENCRYPTED_MASK) >>
+		RX_MPDU_START_0_ENCRYPTED_LSB) ? true : false;
+}
+
+static
+bool htt_rx_msdu_chan_info_present_ll(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	return false;
+}
+
+static bool htt_rx_msdu_center_freq_ll(htt_pdev_handle pdev,
+				       struct ol_txrx_peer_t *peer,
+				       void *mpdu_desc,
+				       uint16_t *primary_chan_center_freq_mhz,
+				       uint16_t *contig_chan1_center_freq_mhz,
+				       uint16_t *contig_chan2_center_freq_mhz,
+				       uint8_t *phy_mode)
+{
+	if (primary_chan_center_freq_mhz)
+		*primary_chan_center_freq_mhz = 0;
+	if (contig_chan1_center_freq_mhz)
+		*contig_chan1_center_freq_mhz = 0;
+	if (contig_chan2_center_freq_mhz)
+		*contig_chan2_center_freq_mhz = 0;
+	if (phy_mode)
+		*phy_mode = 0;
+	return false;
+}
+
+static bool
+htt_rx_msdu_first_msdu_flag_ll(htt_pdev_handle pdev, void *msdu_desc)
+{
+	struct htt_host_rx_desc_base *rx_desc =
+		(struct htt_host_rx_desc_base *)msdu_desc;
+	return (bool)
+		(((*(((uint32_t *)&rx_desc->msdu_end) + 4)) &
+		  RX_MSDU_END_4_FIRST_MSDU_MASK) >>
+		 RX_MSDU_END_4_FIRST_MSDU_LSB);
+}
+
+static bool
+htt_rx_msdu_desc_key_id_ll(htt_pdev_handle pdev, void *mpdu_desc,
+			   uint8_t *key_id)
+{
+	struct htt_host_rx_desc_base *rx_desc = (struct htt_host_rx_desc_base *)
+						mpdu_desc;
+
+	if (!htt_rx_msdu_first_msdu_flag_ll(pdev, mpdu_desc))
+		return false;
+
+	*key_id = ((*(((uint32_t *)&rx_desc->msdu_end) + 1)) &
+		   (RX_MSDU_END_1_KEY_ID_OCT_MASK >>
+		    RX_MSDU_END_1_KEY_ID_OCT_LSB));
+
+	return true;
+}
+
+/**
+ * htt_rx_mpdu_desc_retry_ll() - Returns the retry bit from the Rx descriptor
+ *                               for the Low Latency driver
+ * @pdev:                          Handle (pointer) to HTT pdev.
+ * @mpdu_desc:                     Void pointer to the Rx descriptor for MPDU
+ *                                 before the beginning of the payload.
+ *
+ *  This function returns the retry bit of the 802.11 header for the
+ *  provided rx MPDU descriptor.
+ *
+ * Return:        boolean -- true if retry is set, false otherwise
+ */
+static bool
+htt_rx_mpdu_desc_retry_ll(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	struct htt_host_rx_desc_base *rx_desc =
+		(struct htt_host_rx_desc_base *)mpdu_desc;
+
+	return
+		(bool)(((*((uint32_t *)&rx_desc->mpdu_start)) &
+		RX_MPDU_START_0_RETRY_MASK) >>
+		RX_MPDU_START_0_RETRY_LSB);
+}
+
+static uint16_t htt_rx_mpdu_desc_seq_num_ll(htt_pdev_handle pdev,
+					    void *mpdu_desc)
+{
+	struct htt_host_rx_desc_base *rx_desc =
+		(struct htt_host_rx_desc_base *)mpdu_desc;
+
+	return
+		(uint16_t)(((*((uint32_t *)&rx_desc->mpdu_start)) &
+			     RX_MPDU_START_0_SEQ_NUM_MASK) >>
+			    RX_MPDU_START_0_SEQ_NUM_LSB);
+}
+
+static void
+htt_rx_mpdu_desc_pn_ll(htt_pdev_handle pdev,
+		       void *mpdu_desc, union htt_rx_pn_t *pn, int pn_len_bits)
+{
+	struct htt_host_rx_desc_base *rx_desc =
+		(struct htt_host_rx_desc_base *)mpdu_desc;
+
+	switch (pn_len_bits) {
+	case 24:
+		/* bits 23:0 */
+		pn->pn24 = rx_desc->mpdu_start.pn_31_0 & 0xffffff;
+		break;
+	case 48:
+		/* bits 31:0 */
+		pn->pn48 = rx_desc->mpdu_start.pn_31_0;
+		/* bits 47:32 */
+		pn->pn48 |= ((uint64_t)
+			     ((*(((uint32_t *)&rx_desc->mpdu_start) + 2))
+			      & RX_MPDU_START_2_PN_47_32_MASK))
+			<< (32 - RX_MPDU_START_2_PN_47_32_LSB);
+		break;
+	case 128:
+		/* bits 31:0 */
+		pn->pn128[0] = rx_desc->mpdu_start.pn_31_0;
+		/* bits 47:32 */
+		pn->pn128[0] |=
+			((uint64_t)((*(((uint32_t *)&rx_desc->mpdu_start) + 2))
+				     & RX_MPDU_START_2_PN_47_32_MASK))
+			<< (32 - RX_MPDU_START_2_PN_47_32_LSB);
+		/* bits 63:48 */
+		pn->pn128[0] |=
+			((uint64_t)((*(((uint32_t *)&rx_desc->msdu_end) + 2))
+				     & RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK))
+			<< (48 - RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB);
+		/* bits 95:64 */
+		pn->pn128[1] = rx_desc->msdu_end.ext_wapi_pn_95_64;
+		/* bits 127:96 */
+		pn->pn128[1] |=
+			((uint64_t)rx_desc->msdu_end.ext_wapi_pn_127_96) << 32;
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+			  "Error: invalid length spec (%d bits) for PN",
+			  pn_len_bits);
+	};
+}
+
+/**
+ * htt_rx_mpdu_desc_tid_ll() - Returns the TID value from the Rx descriptor
+ *                             for Low Latency driver
+ * @pdev:                        Handle (pointer) to HTT pdev.
+ * @mpdu_desc:                   Void pointer to the Rx descriptor for the MPDU
+ *                               before the beginning of the payload.
+ *
+ * This function returns the TID set in the 802.11 QoS Control for the MPDU
+ * in the packet header, by looking at the mpdu_start of the Rx descriptor.
+ * Rx descriptor gets a copy of the TID from the MAC.
+ *
+ * Return:        Actual TID set in the packet header.
+ */
+static uint8_t
+htt_rx_mpdu_desc_tid_ll(htt_pdev_handle pdev, void *mpdu_desc)
+{
+	struct htt_host_rx_desc_base *rx_desc =
+		(struct htt_host_rx_desc_base *)mpdu_desc;
+
+	return
+		(uint8_t)(((*(((uint32_t *)&rx_desc->mpdu_start) + 2)) &
+		RX_MPDU_START_2_TID_MASK) >>
+		RX_MPDU_START_2_TID_LSB);
+}
+
+static bool htt_rx_msdu_desc_completes_mpdu_ll(htt_pdev_handle pdev,
+					       void *msdu_desc)
+{
+	struct htt_host_rx_desc_base *rx_desc =
+		(struct htt_host_rx_desc_base *)msdu_desc;
+	return (bool)
+		(((*(((uint32_t *)&rx_desc->msdu_end) + 4)) &
+		  RX_MSDU_END_4_LAST_MSDU_MASK) >> RX_MSDU_END_4_LAST_MSDU_LSB);
+}
+
+static int htt_rx_msdu_has_wlan_mcast_flag_ll(htt_pdev_handle pdev,
+					      void *msdu_desc)
+{
+	struct htt_host_rx_desc_base *rx_desc =
+		(struct htt_host_rx_desc_base *)msdu_desc;
+	/*
+	 * HW rx desc: the mcast_bcast flag is only valid
+	 * if first_msdu is set
+	 */
+	return ((*(((uint32_t *)&rx_desc->msdu_end) + 4)) &
+		RX_MSDU_END_4_FIRST_MSDU_MASK) >> RX_MSDU_END_4_FIRST_MSDU_LSB;
+}
+
+static bool htt_rx_msdu_is_wlan_mcast_ll(htt_pdev_handle pdev, void *msdu_desc)
+{
+	struct htt_host_rx_desc_base *rx_desc =
+		(struct htt_host_rx_desc_base *)msdu_desc;
+	return ((*((uint32_t *)&rx_desc->attention)) &
+		RX_ATTENTION_0_MCAST_BCAST_MASK)
+		>> RX_ATTENTION_0_MCAST_BCAST_LSB;
+}
+
+static int htt_rx_msdu_is_frag_ll(htt_pdev_handle pdev, void *msdu_desc)
+{
+	struct htt_host_rx_desc_base *rx_desc =
+		(struct htt_host_rx_desc_base *)msdu_desc;
+	return ((*((uint32_t *)&rx_desc->attention)) &
+		 RX_ATTENTION_0_FRAGMENT_MASK) >> RX_ATTENTION_0_FRAGMENT_LSB;
+}
+
+static inline int
+htt_rx_offload_msdu_cnt_ll(htt_pdev_handle pdev)
+{
+	return htt_rx_ring_elems(pdev);
+}
+
+static int
+htt_rx_offload_msdu_pop_ll(htt_pdev_handle pdev,
+			   qdf_nbuf_t offload_deliver_msg,
+			   int *vdev_id,
+			   int *peer_id,
+			   int *tid,
+			   uint8_t *fw_desc,
+			   qdf_nbuf_t *head_buf, qdf_nbuf_t *tail_buf)
+{
+	qdf_nbuf_t buf;
+	uint32_t *msdu_hdr, msdu_len;
+
+	*head_buf = *tail_buf = buf = htt_rx_netbuf_pop(pdev);
+
+	if (qdf_unlikely(!buf)) {
+		qdf_print("%s: netbuf pop failed!\n", __func__);
+		return 1;
+	}
+
+	/* Fake read mpdu_desc to keep desc ptr in sync */
+	htt_rx_mpdu_desc_list_next(pdev, NULL);
+	qdf_nbuf_set_pktlen(buf, HTT_RX_BUF_SIZE);
+#ifdef DEBUG_DMA_DONE
+	qdf_nbuf_unmap(pdev->osdev, buf, QDF_DMA_BIDIRECTIONAL);
+#else
+	qdf_nbuf_unmap(pdev->osdev, buf, QDF_DMA_FROM_DEVICE);
+#endif
+	msdu_hdr = (uint32_t *)qdf_nbuf_data(buf);
+
+	/* First dword */
+	msdu_len = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_GET(*msdu_hdr);
+	*peer_id = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_GET(*msdu_hdr);
+
+	/* Second dword */
+	msdu_hdr++;
+	*vdev_id = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_GET(*msdu_hdr);
+	*tid = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_GET(*msdu_hdr);
+	*fw_desc = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_GET(*msdu_hdr);
+
+	qdf_nbuf_pull_head(buf, HTT_RX_OFFLOAD_DELIVER_IND_MSDU_HDR_BYTES);
+	qdf_nbuf_set_pktlen(buf, msdu_len);
+	return 0;
+}
+
+int
+htt_rx_offload_paddr_msdu_pop_ll(htt_pdev_handle pdev,
+				 uint32_t *msg_word,
+				 int msdu_iter,
+				 int *vdev_id,
+				 int *peer_id,
+				 int *tid,
+				 uint8_t *fw_desc,
+				 qdf_nbuf_t *head_buf, qdf_nbuf_t *tail_buf)
+{
+	qdf_nbuf_t buf;
+	uint32_t *msdu_hdr, msdu_len;
+	uint32_t *curr_msdu;
+	qdf_dma_addr_t paddr;
+
+	curr_msdu =
+		msg_word + (msdu_iter * HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS);
+	paddr = htt_rx_in_ord_paddr_get(curr_msdu);
+	*head_buf = *tail_buf = buf = htt_rx_in_order_netbuf_pop(pdev, paddr);
+
+	if (qdf_unlikely(!buf)) {
+		qdf_print("%s: netbuf pop failed!\n", __func__);
+		return 1;
+	}
+	qdf_nbuf_set_pktlen(buf, HTT_RX_BUF_SIZE);
+#ifdef DEBUG_DMA_DONE
+	qdf_nbuf_unmap(pdev->osdev, buf, QDF_DMA_BIDIRECTIONAL);
+#else
+	qdf_nbuf_unmap(pdev->osdev, buf, QDF_DMA_FROM_DEVICE);
+#endif
+
+	if (pdev->cfg.is_first_wakeup_packet)
+		htt_get_first_packet_after_wow_wakeup(
+			msg_word + NEXT_FIELD_OFFSET_IN32, buf);
+
+	msdu_hdr = (uint32_t *)qdf_nbuf_data(buf);
+
+	/* First dword */
+	msdu_len = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_GET(*msdu_hdr);
+	*peer_id = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_GET(*msdu_hdr);
+
+	/* Second dword */
+	msdu_hdr++;
+	*vdev_id = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_GET(*msdu_hdr);
+	*tid = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_GET(*msdu_hdr);
+	*fw_desc = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_GET(*msdu_hdr);
+
+	qdf_nbuf_pull_head(buf, HTT_RX_OFFLOAD_DELIVER_IND_MSDU_HDR_BYTES);
+	qdf_nbuf_set_pktlen(buf, msdu_len);
+	return 0;
+}
+
+#ifdef WLAN_FULL_REORDER_OFFLOAD
+
+/* Number of buckets in the hash table */
+#define RX_NUM_HASH_BUCKETS 1024        /* This should always be a power of 2 */
+#define RX_NUM_HASH_BUCKETS_MASK (RX_NUM_HASH_BUCKETS - 1)
+
+/* Number of hash entries allocated per bucket */
+#define RX_ENTRIES_SIZE 10
+
+#define RX_HASH_FUNCTION(a) \
+	((((a) >> 14) ^ ((a) >> 4)) & RX_NUM_HASH_BUCKETS_MASK)
+
+#ifdef RX_HASH_DEBUG_LOG
+#define RX_HASH_LOG(x) x
+#else
+#define RX_HASH_LOG(x)          /* no-op */
+#endif
+
+/* Return values: 1 - success, 0 - failure */
+#define RX_DESC_DISCARD_IS_SET ((*((u_int8_t *)&rx_desc->fw_desc.u.val)) & \
+							FW_RX_DESC_DISCARD_M)
+#define RX_DESC_MIC_ERR_IS_SET ((*((u_int8_t *)&rx_desc->fw_desc.u.val)) & \
+							FW_RX_DESC_ANY_ERR_M)
+
+#define RX_RING_REFILL_DEBT_MAX 128
+
+/* Initializes the circular linked list */
+static inline void htt_list_init(struct htt_list_node *head)
+{
+	head->prev = head;
+	head->next = head;
+}
+
+/* Adds entry to the end of the linked list */
+static inline void htt_list_add_tail(struct htt_list_node *head,
+				     struct htt_list_node *node)
+{
+	head->prev->next = node;
+	node->prev = head->prev;
+	node->next = head;
+	head->prev = node;
+}
+
+/* Removes the entry corresponding to the input node from the linked list */
+static inline void htt_list_remove(struct htt_list_node *node)
+{
+	node->prev->next = node->next;
+	node->next->prev = node->prev;
+}
+
+/* Helper macro to iterate through the linked list */
+#define HTT_LIST_ITER_FWD(iter, head) for (iter = (head)->next;		\
+					   (iter) != (head);		\
+					   (iter) = (iter)->next)	\
+
+#ifdef RX_HASH_DEBUG
+/* Hash cookie related macros */
+#define HTT_RX_HASH_COOKIE 0xDEED
+
+#define HTT_RX_HASH_COOKIE_SET(hash_element) \
+	((hash_element)->cookie = HTT_RX_HASH_COOKIE)
+
+#define HTT_RX_HASH_COOKIE_CHECK(hash_element) \
+	HTT_ASSERT_ALWAYS((hash_element)->cookie == HTT_RX_HASH_COOKIE)
+
+/* Hash count related macros */
+#define HTT_RX_HASH_COUNT_INCR(hash_bucket) \
+	((hash_bucket)->count++)
+
+#define HTT_RX_HASH_COUNT_DECR(hash_bucket) \
+	((hash_bucket)->count--)
+
+#define HTT_RX_HASH_COUNT_RESET(hash_bucket) ((hash_bucket)->count = 0)
+
+#define HTT_RX_HASH_COUNT_PRINT(hash_bucket) \
+	RX_HASH_LOG(qdf_print(" count %d\n", (hash_bucket)->count))
+#else                           /* RX_HASH_DEBUG */
+/* Hash cookie related macros */
+#define HTT_RX_HASH_COOKIE_SET(hash_element)    /* no-op */
+#define HTT_RX_HASH_COOKIE_CHECK(hash_element)  /* no-op */
+/* Hash count related macros */
+#define HTT_RX_HASH_COUNT_INCR(hash_bucket)     /* no-op */
+#define HTT_RX_HASH_COUNT_DECR(hash_bucket)     /* no-op */
+#define HTT_RX_HASH_COUNT_PRINT(hash_bucket)    /* no-op */
+#define HTT_RX_HASH_COUNT_RESET(hash_bucket)    /* no-op */
+#endif /* RX_HASH_DEBUG */
+
+/*
+ * Inserts the given "physical address - network buffer" pair into the
+ * hash table for the given pdev. This function will do the following:
+ * 1. Determine which bucket to insert the pair into
+ * 2. First try to allocate the hash entry for this pair from the pre-allocated
+ *    entries list
+ * 3. If there are no more entries in the pre-allocated entries list, allocate
+ *    the hash entry from the hash memory pool
+ * Note: this function is not thread-safe
+ * Returns 0 - success, 1 - failure
+ */
+int
+htt_rx_hash_list_insert(struct htt_pdev_t *pdev,
+			qdf_dma_addr_t paddr,
+			qdf_nbuf_t netbuf)
+{
+	int i;
+	int rc = 0;
+	struct htt_rx_hash_entry *hash_element = NULL;
+
+	qdf_spin_lock_bh(&pdev->rx_ring.rx_hash_lock);
+
+	/* get rid of the marking bits if they are available */
+	paddr = htt_paddr_trim_to_37(paddr);
+
+	i = RX_HASH_FUNCTION(paddr);
+
+	/* Check if there are any entries in the pre-allocated free list */
+	if (pdev->rx_ring.hash_table[i]->freepool.next !=
+	    &pdev->rx_ring.hash_table[i]->freepool) {
+		hash_element =
+			(struct htt_rx_hash_entry *)(
+				(char *)
+				pdev->rx_ring.hash_table[i]->freepool.next -
+				pdev->rx_ring.listnode_offset);
+		if (qdf_unlikely(!hash_element)) {
+			HTT_ASSERT_ALWAYS(0);
+			rc = 1;
+			goto hli_end;
+		}
+
+		htt_list_remove(pdev->rx_ring.hash_table[i]->freepool.next);
+	} else {
+		hash_element = qdf_mem_malloc(sizeof(struct htt_rx_hash_entry));
+		if (qdf_unlikely(!hash_element)) {
+			HTT_ASSERT_ALWAYS(0);
+			rc = 1;
+			goto hli_end;
+		}
+		hash_element->fromlist = 0;
+	}
+
+	hash_element->netbuf = netbuf;
+	hash_element->paddr = paddr;
+	HTT_RX_HASH_COOKIE_SET(hash_element);
+
+	htt_list_add_tail(&pdev->rx_ring.hash_table[i]->listhead,
+			  &hash_element->listnode);
+
+	RX_HASH_LOG(qdf_print("rx hash: %s: paddr 0x%x netbuf %pK bucket %d\n",
+			      __func__, paddr, netbuf, (int)i));
+
+	HTT_RX_HASH_COUNT_INCR(pdev->rx_ring.hash_table[i]);
+	HTT_RX_HASH_COUNT_PRINT(pdev->rx_ring.hash_table[i]);
+
+hli_end:
+	qdf_spin_unlock_bh(&pdev->rx_ring.rx_hash_lock);
+	return rc;
+}
+
+/*
+ * Given a physical address this function will find the corresponding network
+ *  buffer from the hash table.
+ *  paddr is already stripped off of higher marking bits.
+ */
+qdf_nbuf_t htt_rx_hash_list_lookup(struct htt_pdev_t *pdev,
+				   qdf_dma_addr_t     paddr)
+{
+	uint32_t i;
+	struct htt_list_node *list_iter = NULL;
+	qdf_nbuf_t netbuf = NULL;
+	struct htt_rx_hash_entry *hash_entry;
+
+	qdf_spin_lock_bh(&pdev->rx_ring.rx_hash_lock);
+
+	if (!pdev->rx_ring.hash_table) {
+		qdf_spin_unlock_bh(&pdev->rx_ring.rx_hash_lock);
+		return NULL;
+	}
+
+	i = RX_HASH_FUNCTION(paddr);
+
+	HTT_LIST_ITER_FWD(list_iter, &pdev->rx_ring.hash_table[i]->listhead) {
+		hash_entry = (struct htt_rx_hash_entry *)
+			     ((char *)list_iter -
+			      pdev->rx_ring.listnode_offset);
+
+		HTT_RX_HASH_COOKIE_CHECK(hash_entry);
+
+		if (hash_entry->paddr == paddr) {
+			/* Found the entry corresponding to paddr */
+			netbuf = hash_entry->netbuf;
+			/* set netbuf to NULL to trace if freed entry
+			 * is getting unmapped in hash deinit.
+			 */
+			hash_entry->netbuf = NULL;
+			htt_list_remove(&hash_entry->listnode);
+			HTT_RX_HASH_COUNT_DECR(pdev->rx_ring.hash_table[i]);
+			/*
+			 * if the rx entry is from the pre-allocated list,
+			 * return it
+			 */
+			if (hash_entry->fromlist)
+				htt_list_add_tail(
+					&pdev->rx_ring.hash_table[i]->freepool,
+					&hash_entry->listnode);
+			else
+				qdf_mem_free(hash_entry);
+
+			htt_rx_dbg_rxbuf_reset(pdev, netbuf);
+			break;
+		}
+	}
+
+	RX_HASH_LOG(qdf_print("rx hash: %s: paddr 0x%x, netbuf %pK, bucket %d\n",
+			      __func__, paddr, netbuf, (int)i));
+	HTT_RX_HASH_COUNT_PRINT(pdev->rx_ring.hash_table[i]);
+
+	qdf_spin_unlock_bh(&pdev->rx_ring.rx_hash_lock);
+
+	if (!netbuf) {
+		qdf_print("rx hash: %s: no entry found for %pK!\n",
+			  __func__, (void *)paddr);
+		cds_trigger_recovery(QDF_RX_HASH_NO_ENTRY_FOUND);
+	}
+
+	return netbuf;
+}
+
+/*
+ * Initialization function of the rx buffer hash table. This function will
+ * allocate a hash table of a certain pre-determined size and initialize all
+ * the elements
+ */
+static int htt_rx_hash_init(struct htt_pdev_t *pdev)
+{
+	int i, j;
+	int rc = 0;
+	void *allocation;
+
+	HTT_ASSERT2(QDF_IS_PWR2(RX_NUM_HASH_BUCKETS));
+
+	/* hash table is array of bucket pointers */
+	pdev->rx_ring.hash_table =
+		qdf_mem_malloc(RX_NUM_HASH_BUCKETS *
+			       sizeof(struct htt_rx_hash_bucket *));
+
+	if (!pdev->rx_ring.hash_table) {
+		qdf_print("rx hash table allocation failed!\n");
+		return 1;
+	}
+
+	qdf_spinlock_create(&pdev->rx_ring.rx_hash_lock);
+	qdf_spin_lock_bh(&pdev->rx_ring.rx_hash_lock);
+
+	for (i = 0; i < RX_NUM_HASH_BUCKETS; i++) {
+		qdf_spin_unlock_bh(&pdev->rx_ring.rx_hash_lock);
+		/* pre-allocate bucket and pool of entries for this bucket */
+		allocation = qdf_mem_malloc((sizeof(struct htt_rx_hash_bucket) +
+			(RX_ENTRIES_SIZE * sizeof(struct htt_rx_hash_entry))));
+		qdf_spin_lock_bh(&pdev->rx_ring.rx_hash_lock);
+		pdev->rx_ring.hash_table[i] = allocation;
+
+		HTT_RX_HASH_COUNT_RESET(pdev->rx_ring.hash_table[i]);
+
+		/* initialize the hash table buckets */
+		htt_list_init(&pdev->rx_ring.hash_table[i]->listhead);
+
+		/* initialize the hash table free pool per bucket */
+		htt_list_init(&pdev->rx_ring.hash_table[i]->freepool);
+
+		/* pre-allocate a pool of entries for this bucket */
+		pdev->rx_ring.hash_table[i]->entries =
+			(struct htt_rx_hash_entry *)
+			((uint8_t *)pdev->rx_ring.hash_table[i] +
+			sizeof(struct htt_rx_hash_bucket));
+
+		if (!pdev->rx_ring.hash_table[i]->entries) {
+			qdf_print("rx hash bucket %d entries alloc failed\n",
+				  (int)i);
+			while (i) {
+				i--;
+				qdf_mem_free(pdev->rx_ring.hash_table[i]);
+			}
+			qdf_mem_free(pdev->rx_ring.hash_table);
+			pdev->rx_ring.hash_table = NULL;
+			rc = 1;
+			goto hi_end;
+		}
+
+		/* initialize the free list with pre-allocated entries */
+		for (j = 0; j < RX_ENTRIES_SIZE; j++) {
+			pdev->rx_ring.hash_table[i]->entries[j].fromlist = 1;
+			htt_list_add_tail(
+				&pdev->rx_ring.hash_table[i]->freepool,
+				&pdev->rx_ring.hash_table[i]->entries[j].
+				listnode);
+		}
+	}
+
+	pdev->rx_ring.listnode_offset =
+		qdf_offsetof(struct htt_rx_hash_entry, listnode);
+hi_end:
+	qdf_spin_unlock_bh(&pdev->rx_ring.rx_hash_lock);
+
+	return rc;
+}
+
+/* De -initialization function of the rx buffer hash table. This function will
+ *   free up the hash table which includes freeing all the pending rx buffers
+ */
+static void htt_rx_hash_deinit(struct htt_pdev_t *pdev)
+{
+	uint32_t i;
+	struct htt_rx_hash_entry *hash_entry;
+	struct htt_rx_hash_bucket **hash_table;
+	struct htt_list_node *list_iter = NULL;
+	qdf_mem_info_t mem_map_table = {0};
+	bool ipa_smmu = false;
+
+	if (!pdev->rx_ring.hash_table)
+		return;
+
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev) && pdev->is_ipa_uc_enabled &&
+	    pdev->rx_ring.smmu_map)
+		ipa_smmu = true;
+
+	qdf_spin_lock_bh(&pdev->rx_ring.rx_hash_lock);
+	hash_table = pdev->rx_ring.hash_table;
+	pdev->rx_ring.hash_table = NULL;
+	qdf_spin_unlock_bh(&pdev->rx_ring.rx_hash_lock);
+
+	for (i = 0; i < RX_NUM_HASH_BUCKETS; i++) {
+		/* Free the hash entries in hash bucket i */
+		list_iter = hash_table[i]->listhead.next;
+		while (list_iter != &hash_table[i]->listhead) {
+			hash_entry =
+				(struct htt_rx_hash_entry *)((char *)list_iter -
+							     pdev->rx_ring.
+							     listnode_offset);
+			if (hash_entry->netbuf) {
+				if (ipa_smmu) {
+					qdf_update_mem_map_table(pdev->osdev,
+						&mem_map_table,
+						QDF_NBUF_CB_PADDR(
+							hash_entry->netbuf),
+						HTT_RX_BUF_SIZE);
+
+					cds_smmu_map_unmap(false, 1,
+							   &mem_map_table);
+				}
+#ifdef DEBUG_DMA_DONE
+				qdf_nbuf_unmap(pdev->osdev, hash_entry->netbuf,
+					       QDF_DMA_BIDIRECTIONAL);
+#else
+				qdf_nbuf_unmap(pdev->osdev, hash_entry->netbuf,
+					       QDF_DMA_FROM_DEVICE);
+#endif
+				qdf_nbuf_free(hash_entry->netbuf);
+				hash_entry->paddr = 0;
+			}
+			list_iter = list_iter->next;
+
+			if (!hash_entry->fromlist)
+				qdf_mem_free(hash_entry);
+		}
+
+		qdf_mem_free(hash_table[i]);
+	}
+	qdf_mem_free(hash_table);
+
+	qdf_spinlock_destroy(&pdev->rx_ring.rx_hash_lock);
+}
+
+int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num)
+{
+	int filled = 0;
+
+	if (!qdf_spin_trylock_bh(&pdev->rx_ring.refill_lock)) {
+		if (qdf_atomic_read(&pdev->rx_ring.refill_debt)
+			 < RX_RING_REFILL_DEBT_MAX) {
+			qdf_atomic_add(num, &pdev->rx_ring.refill_debt);
+			pdev->rx_buff_debt_invoked++;
+			return filled; /* 0 */
+		}
+		/*
+		 * else:
+		 * If we have quite a debt, then it is better for the lock
+		 * holder to finish its work and then acquire the lock and
+		 * fill our own part.
+		 */
+		qdf_spin_lock_bh(&pdev->rx_ring.refill_lock);
+	}
+	pdev->rx_buff_fill_n_invoked++;
+
+	filled = htt_rx_ring_fill_n(pdev, num);
+
+	if (filled > num) {
+		/* we served ourselves and some other debt */
+		/* sub is safer than  = 0 */
+		qdf_atomic_sub(filled - num, &pdev->rx_ring.refill_debt);
+	} else {
+		qdf_atomic_add(num - filled, &pdev->rx_ring.refill_debt);
+	}
+	qdf_spin_unlock_bh(&pdev->rx_ring.refill_lock);
+
+	return filled;
+}
+
+static int
+htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
+				qdf_nbuf_t rx_ind_msg,
+				qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu,
+				uint32_t *replenish_cnt)
+{
+	qdf_nbuf_t msdu, next, prev = NULL;
+	uint8_t *rx_ind_data;
+	uint32_t *msg_word;
+	uint32_t rx_ctx_id;
+	unsigned int msdu_count = 0;
+	uint8_t offload_ind, frag_ind;
+	uint8_t peer_id;
+	struct htt_host_rx_desc_base *rx_desc;
+	enum rx_pkt_fate status = RX_PKT_FATE_SUCCESS;
+	qdf_dma_addr_t paddr;
+	qdf_mem_info_t mem_map_table = {0};
+	int ret = 1;
+	bool ipa_smmu = false;
+
+	HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0);
+
+	rx_ind_data = qdf_nbuf_data(rx_ind_msg);
+	rx_ctx_id = QDF_NBUF_CB_RX_CTX_ID(rx_ind_msg);
+	msg_word = (uint32_t *)rx_ind_data;
+	peer_id = HTT_RX_IN_ORD_PADDR_IND_PEER_ID_GET(
+					*(u_int32_t *)rx_ind_data);
+
+	offload_ind = HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_GET(*msg_word);
+	frag_ind = HTT_RX_IN_ORD_PADDR_IND_FRAG_GET(*msg_word);
+
+	/* Get the total number of MSDUs */
+	msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1));
+	HTT_RX_CHECK_MSDU_COUNT(msdu_count);
+
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev) && pdev->is_ipa_uc_enabled &&
+	    pdev->rx_ring.smmu_map)
+		ipa_smmu = true;
+
+	ol_rx_update_histogram_stats(msdu_count, frag_ind, offload_ind);
+	htt_rx_dbg_rxbuf_httrxind(pdev, msdu_count);
+
+	msg_word =
+		(uint32_t *)(rx_ind_data + HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES);
+	if (offload_ind) {
+		ol_rx_offload_paddr_deliver_ind_handler(pdev, msdu_count,
+							msg_word);
+		*head_msdu = *tail_msdu = NULL;
+		ret = 0;
+		goto end;
+	}
+
+	paddr = htt_rx_in_ord_paddr_get(msg_word);
+	(*head_msdu) = msdu = htt_rx_in_order_netbuf_pop(pdev, paddr);
+
+	if (qdf_unlikely(!msdu)) {
+		qdf_print("%s: netbuf pop failed!\n", __func__);
+		*tail_msdu = NULL;
+		pdev->rx_ring.pop_fail_cnt++;
+		ret = 0;
+		goto end;
+	}
+
+	while (msdu_count > 0) {
+		if (ipa_smmu) {
+			qdf_update_mem_map_table(pdev->osdev, &mem_map_table,
+						 QDF_NBUF_CB_PADDR(msdu),
+						 HTT_RX_BUF_SIZE);
+			cds_smmu_map_unmap(false, 1, &mem_map_table);
+		}
+
+		/*
+		 * Set the netbuf length to be the entire buffer length
+		 * initially, so the unmap will unmap the entire buffer.
+		 */
+		qdf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE);
+#ifdef DEBUG_DMA_DONE
+		qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_BIDIRECTIONAL);
+#else
+		qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE);
+#endif
+		msdu_count--;
+
+		if (pdev->rx_buff_pool.netbufs_ring &&
+		    QDF_NBUF_CB_RX_PACKET_BUFF_POOL(msdu) &&
+		    !htt_rx_buff_pool_refill(pdev, msdu)) {
+			if (!msdu_count) {
+				if (!prev) {
+					*head_msdu = *tail_msdu = NULL;
+					ret = 1;
+					goto end;
+				}
+				*tail_msdu = prev;
+				qdf_nbuf_set_next(prev, NULL);
+				goto end;
+			} else {
+				/* get the next msdu */
+				msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+				paddr = htt_rx_in_ord_paddr_get(msg_word);
+				next = htt_rx_in_order_netbuf_pop(pdev, paddr);
+				if (qdf_unlikely(!next)) {
+					qdf_print("%s: netbuf pop failed!\n",
+						  __func__);
+					*tail_msdu = NULL;
+					pdev->rx_ring.pop_fail_cnt++;
+					ret = 0;
+					goto end;
+				}
+				/* if this is not the first msdu, update the
+				 * next pointer of the preceding msdu
+				 */
+				if (prev) {
+					qdf_nbuf_set_next(prev, next);
+				} else {
+					/* if this is the first msdu, update
+					 * head pointer
+					 */
+					*head_msdu = next;
+				}
+				msdu = next;
+				continue;
+			}
+		}
+
+		/* cache consistency has been taken care of by qdf_nbuf_unmap */
+		rx_desc = htt_rx_desc(msdu);
+		htt_rx_extract_lro_info(msdu, rx_desc);
+
+		/*
+		 * Make the netbuf's data pointer point to the payload rather
+		 * than the descriptor.
+		 */
+		qdf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION);
+
+		QDF_NBUF_CB_DP_TRACE_PRINT(msdu) = false;
+		qdf_dp_trace_set_track(msdu, QDF_RX);
+		QDF_NBUF_CB_TX_PACKET_TRACK(msdu) = QDF_NBUF_TX_PKT_DATA_TRACK;
+		QDF_NBUF_CB_RX_CTX_ID(msdu) = rx_ctx_id;
+		DPTRACE(qdf_dp_trace(msdu,
+				     QDF_DP_TRACE_RX_HTT_PACKET_PTR_RECORD,
+				     QDF_TRACE_DEFAULT_PDEV_ID,
+				     qdf_nbuf_data_addr(msdu),
+				     sizeof(qdf_nbuf_data(msdu)), QDF_RX));
+
+		qdf_nbuf_trim_tail(msdu,
+				   HTT_RX_BUF_SIZE -
+				   (RX_STD_DESC_SIZE +
+				    HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_GET(
+				    *(msg_word + NEXT_FIELD_OFFSET_IN32))));
+#if defined(HELIUMPLUS_DEBUG)
+		ol_txrx_dump_pkt(msdu, 0, 64);
+#endif
+		*((uint8_t *)&rx_desc->fw_desc.u.val) =
+			HTT_RX_IN_ORD_PADDR_IND_FW_DESC_GET(*(msg_word +
+						NEXT_FIELD_OFFSET_IN32));
+
+		/* calling callback function for packet logging */
+		if (pdev->rx_pkt_dump_cb) {
+			if (qdf_unlikely(RX_DESC_MIC_ERR_IS_SET &&
+					 !RX_DESC_DISCARD_IS_SET))
+				status = RX_PKT_FATE_FW_DROP_INVALID;
+			pdev->rx_pkt_dump_cb(msdu, peer_id, status);
+		}
+
+		if (pdev->cfg.is_first_wakeup_packet)
+			htt_get_first_packet_after_wow_wakeup(
+				msg_word + NEXT_FIELD_OFFSET_IN32, msdu);
+
+		/* if discard flag is set (SA is self MAC), then
+		 * don't check mic failure.
+		 */
+		if (qdf_unlikely(RX_DESC_MIC_ERR_IS_SET &&
+				 !RX_DESC_DISCARD_IS_SET)) {
+			uint8_t tid =
+				HTT_RX_IN_ORD_PADDR_IND_EXT_TID_GET(
+					*(u_int32_t *)rx_ind_data);
+			ol_rx_mic_error_handler(pdev->txrx_pdev, tid, peer_id,
+						rx_desc, msdu);
+
+			htt_rx_desc_frame_free(pdev, msdu);
+			/* if this is the last msdu */
+			if (!msdu_count) {
+				/* if this is the only msdu */
+				if (!prev) {
+					*head_msdu = *tail_msdu = NULL;
+					ret = 0;
+					goto end;
+				}
+				*tail_msdu = prev;
+				qdf_nbuf_set_next(prev, NULL);
+				goto end;
+			} else { /* if this is not the last msdu */
+				/* get the next msdu */
+				msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+				paddr = htt_rx_in_ord_paddr_get(msg_word);
+				next = htt_rx_in_order_netbuf_pop(pdev, paddr);
+				if (qdf_unlikely(!next)) {
+					qdf_print("%s: netbuf pop failed!\n",
+						  __func__);
+					*tail_msdu = NULL;
+					pdev->rx_ring.pop_fail_cnt++;
+					ret = 0;
+					goto end;
+				}
+
+				/* if this is not the first msdu, update the
+				 * next pointer of the preceding msdu
+				 */
+				if (prev) {
+					qdf_nbuf_set_next(prev, next);
+				} else {
+					/* if this is the first msdu, update the
+					 * head pointer
+					 */
+					*head_msdu = next;
+				}
+				msdu = next;
+				continue;
+			}
+		}
+		/* check if this is the last msdu */
+		if (msdu_count) {
+			msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+			paddr = htt_rx_in_ord_paddr_get(msg_word);
+			next = htt_rx_in_order_netbuf_pop(pdev, paddr);
+			if (qdf_unlikely(!next)) {
+				qdf_print("%s: netbuf pop failed!\n",
+					  __func__);
+				*tail_msdu = NULL;
+				pdev->rx_ring.pop_fail_cnt++;
+				ret = 0;
+				goto end;
+			}
+			qdf_nbuf_set_next(msdu, next);
+			prev = msdu;
+			msdu = next;
+		} else {
+			*tail_msdu = msdu;
+			qdf_nbuf_set_next(msdu, NULL);
+		}
+	}
+
+end:
+	return ret;
+}
+
+static void *htt_rx_in_ord_mpdu_desc_list_next_ll(htt_pdev_handle pdev,
+						  qdf_nbuf_t netbuf)
+{
+	return (void *)htt_rx_desc(netbuf);
+}
+#else
+
+static inline
+int htt_rx_hash_init(struct htt_pdev_t *pdev)
+{
+	return 0;
+}
+
+static inline
+void htt_rx_hash_deinit(struct htt_pdev_t *pdev)
+{
+}
+
+static inline int
+htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
+				qdf_nbuf_t rx_ind_msg,
+				qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu,
+				uint32_t *replenish_cnt)
+{
+	return 0;
+}
+
+static inline
+void *htt_rx_in_ord_mpdu_desc_list_next_ll(htt_pdev_handle pdev,
+					   qdf_nbuf_t netbuf)
+{
+	return NULL;
+}
+#endif
+
+#ifdef WLAN_PARTIAL_REORDER_OFFLOAD
+
+/* AR9888v1 WORKAROUND for EV#112367 */
+/* FIX THIS - remove this WAR when the bug is fixed */
+#define PEREGRINE_1_0_ZERO_LEN_PHY_ERR_WAR
+
+static int
+htt_rx_amsdu_pop_ll(htt_pdev_handle pdev,
+		    qdf_nbuf_t rx_ind_msg,
+		    qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu,
+		    uint32_t *msdu_count)
+{
+	int msdu_len, msdu_chaining = 0;
+	qdf_nbuf_t msdu;
+	struct htt_host_rx_desc_base *rx_desc;
+	uint8_t *rx_ind_data;
+	uint32_t *msg_word, num_msdu_bytes;
+	qdf_dma_addr_t rx_desc_paddr;
+	enum htt_t2h_msg_type msg_type;
+	uint8_t pad_bytes = 0;
+
+	HTT_ASSERT1(htt_rx_ring_elems(pdev) != 0);
+	rx_ind_data = qdf_nbuf_data(rx_ind_msg);
+	msg_word = (uint32_t *)rx_ind_data;
+
+	msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word);
+
+	if (qdf_unlikely(msg_type == HTT_T2H_MSG_TYPE_RX_FRAG_IND)) {
+		num_msdu_bytes = HTT_RX_FRAG_IND_FW_RX_DESC_BYTES_GET(
+			*(msg_word + HTT_RX_FRAG_IND_HDR_PREFIX_SIZE32));
+	} else {
+		num_msdu_bytes = HTT_RX_IND_FW_RX_DESC_BYTES_GET(
+			*(msg_word
+			  + HTT_RX_IND_HDR_PREFIX_SIZE32
+			  + HTT_RX_PPDU_DESC_SIZE32));
+	}
+	msdu = *head_msdu = htt_rx_netbuf_pop(pdev);
+	while (1) {
+		int last_msdu, msdu_len_invalid, msdu_chained;
+		int byte_offset;
+		qdf_nbuf_t next;
+
+		/*
+		 * Set the netbuf length to be the entire buffer length
+		 * initially, so the unmap will unmap the entire buffer.
+		 */
+		qdf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE);
+#ifdef DEBUG_DMA_DONE
+		qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_BIDIRECTIONAL);
+#else
+		qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE);
+#endif
+
+		/* cache consistency has been taken care of by qdf_nbuf_unmap */
+
+		/*
+		 * Now read the rx descriptor.
+		 * Set the length to the appropriate value.
+		 * Check if this MSDU completes a MPDU.
+		 */
+		rx_desc = htt_rx_desc(msdu);
+#if defined(HELIUMPLUS)
+		if (HTT_WIFI_IP(pdev, 2, 0))
+			pad_bytes = rx_desc->msdu_end.l3_header_padding;
+#endif /* defined(HELIUMPLUS) */
+
+		/*
+		 * Save PADDR of descriptor and make the netbuf's data pointer
+		 * point to the payload rather than the descriptor.
+		 */
+		rx_desc_paddr = QDF_NBUF_CB_PADDR(msdu);
+		qdf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION +
+					 pad_bytes);
+
+		/*
+		 * Sanity check - confirm the HW is finished filling in
+		 * the rx data.
+		 * If the HW and SW are working correctly, then it's guaranteed
+		 * that the HW's MAC DMA is done before this point in the SW.
+		 * To prevent the case that we handle a stale Rx descriptor,
+		 * just assert for now until we have a way to recover.
+		 */
+
+#ifdef DEBUG_DMA_DONE
+		if (qdf_unlikely(!((*(uint32_t *)&rx_desc->attention)
+				   & RX_ATTENTION_0_MSDU_DONE_MASK))) {
+			int dbg_iter = MAX_DONE_BIT_CHECK_ITER;
+
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+				  "malformed frame");
+
+			while (dbg_iter &&
+			       (!((*(uint32_t *)&rx_desc->attention) &
+				  RX_ATTENTION_0_MSDU_DONE_MASK))) {
+				qdf_mdelay(1);
+				qdf_mem_dma_sync_single_for_cpu(
+					pdev->osdev,
+					rx_desc_paddr,
+					HTT_RX_STD_DESC_RESERVATION,
+					DMA_FROM_DEVICE);
+
+				QDF_TRACE(QDF_MODULE_ID_HTT,
+					  QDF_TRACE_LEVEL_INFO,
+					  "debug iter %d success %d", dbg_iter,
+					  pdev->rx_ring.dbg_sync_success);
+
+				dbg_iter--;
+			}
+
+			if (qdf_unlikely(!((*(uint32_t *)&rx_desc->attention)
+					   & RX_ATTENTION_0_MSDU_DONE_MASK))) {
+#ifdef HTT_RX_RESTORE
+				QDF_TRACE(QDF_MODULE_ID_HTT,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "RX done bit error detected!");
+
+				qdf_nbuf_set_next(msdu, NULL);
+				*tail_msdu = msdu;
+				pdev->rx_ring.rx_reset = 1;
+				return msdu_chaining;
+#else
+				wma_cli_set_command(0, GEN_PARAM_CRASH_INJECT,
+						    0, GEN_CMD);
+				HTT_ASSERT_ALWAYS(0);
+#endif
+			}
+			pdev->rx_ring.dbg_sync_success++;
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+				  "debug iter %d success %d", dbg_iter,
+				  pdev->rx_ring.dbg_sync_success);
+		}
+#else
+		HTT_ASSERT_ALWAYS((*(uint32_t *)&rx_desc->attention) &
+				  RX_ATTENTION_0_MSDU_DONE_MASK);
+#endif
+		/*
+		 * Copy the FW rx descriptor for this MSDU from the rx
+		 * indication message into the MSDU's netbuf.
+		 * HL uses the same rx indication message definition as LL, and
+		 * simply appends new info (fields from the HW rx desc, and the
+		 * MSDU payload itself).
+		 * So, the offset into the rx indication message only has to
+		 * account for the standard offset of the per-MSDU FW rx
+		 * desc info within the message, and how many bytes of the
+		 * per-MSDU FW rx desc info have already been consumed.
+		 * (And the endianness of the host,
+		 * since for a big-endian host, the rx ind message contents,
+		 * including the per-MSDU rx desc bytes, were byteswapped during
+		 * upload.)
+		 */
+		if (pdev->rx_ind_msdu_byte_idx < num_msdu_bytes) {
+			if (qdf_unlikely
+				    (msg_type == HTT_T2H_MSG_TYPE_RX_FRAG_IND))
+				byte_offset =
+					HTT_ENDIAN_BYTE_IDX_SWAP
+					(HTT_RX_FRAG_IND_FW_DESC_BYTE_OFFSET);
+			else
+				byte_offset =
+					HTT_ENDIAN_BYTE_IDX_SWAP
+					(HTT_RX_IND_FW_RX_DESC_BYTE_OFFSET +
+						pdev->rx_ind_msdu_byte_idx);
+
+			*((uint8_t *)&rx_desc->fw_desc.u.val) =
+				rx_ind_data[byte_offset];
+			/*
+			 * The target is expected to only provide the basic
+			 * per-MSDU rx descriptors.  Just to be sure,
+			 * verify that the target has not attached
+			 * extension data (e.g. LRO flow ID).
+			 */
+			/*
+			 * The assertion below currently doesn't work for
+			 * RX_FRAG_IND messages, since their format differs
+			 * from the RX_IND format (no FW rx PPDU desc in
+			 * the current RX_FRAG_IND message).
+			 * If the RX_FRAG_IND message format is updated to match
+			 * the RX_IND message format, then the following
+			 * assertion can be restored.
+			 */
+			/*
+			 * qdf_assert((rx_ind_data[byte_offset] &
+			 * FW_RX_DESC_EXT_M) == 0);
+			 */
+			pdev->rx_ind_msdu_byte_idx += 1;
+			/* or more, if there's ext data */
+		} else {
+			/*
+			 * When an oversized AMSDU happened, FW will lost some
+			 * of MSDU status - in this case, the FW descriptors
+			 * provided will be less than the actual MSDUs
+			 * inside this MPDU.
+			 * Mark the FW descriptors so that it will still
+			 * deliver to upper stack, if no CRC error for the MPDU.
+			 *
+			 * FIX THIS - the FW descriptors are actually for MSDUs
+			 * in the end of this A-MSDU instead of the beginning.
+			 */
+			*((uint8_t *)&rx_desc->fw_desc.u.val) = 0;
+		}
+
+		/*
+		 *  TCP/UDP checksum offload support
+		 */
+		htt_set_checksum_result_ll(pdev, msdu, rx_desc);
+
+		msdu_len_invalid = (*(uint32_t *)&rx_desc->attention) &
+				   RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK;
+		msdu_chained = (((*(uint32_t *)&rx_desc->frag_info) &
+				 RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK) >>
+				RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB);
+		msdu_len =
+			((*((uint32_t *)&rx_desc->msdu_start)) &
+			 RX_MSDU_START_0_MSDU_LENGTH_MASK) >>
+			RX_MSDU_START_0_MSDU_LENGTH_LSB;
+
+		do {
+			if (!msdu_len_invalid && !msdu_chained) {
+#if defined(PEREGRINE_1_0_ZERO_LEN_PHY_ERR_WAR)
+				if (msdu_len > 0x3000)
+					break;
+#endif
+				qdf_nbuf_trim_tail(msdu,
+						   HTT_RX_BUF_SIZE -
+						   (RX_STD_DESC_SIZE +
+						    msdu_len));
+			}
+		} while (0);
+
+		while (msdu_chained--) {
+			next = htt_rx_netbuf_pop(pdev);
+			qdf_nbuf_set_pktlen(next, HTT_RX_BUF_SIZE);
+			msdu_len -= HTT_RX_BUF_SIZE;
+			qdf_nbuf_set_next(msdu, next);
+			msdu = next;
+			msdu_chaining = 1;
+
+			if (msdu_chained == 0) {
+				/* Trim the last one to the correct size -
+				 * accounting for inconsistent HW lengths
+				 * causing length overflows and underflows
+				 */
+				if (((unsigned int)msdu_len) >
+				    ((unsigned int)
+				     (HTT_RX_BUF_SIZE - RX_STD_DESC_SIZE))) {
+					msdu_len =
+						(HTT_RX_BUF_SIZE -
+						 RX_STD_DESC_SIZE);
+				}
+
+				qdf_nbuf_trim_tail(next,
+						   HTT_RX_BUF_SIZE -
+						   (RX_STD_DESC_SIZE +
+						    msdu_len));
+			}
+		}
+
+		last_msdu =
+			((*(((uint32_t *)&rx_desc->msdu_end) + 4)) &
+			 RX_MSDU_END_4_LAST_MSDU_MASK) >>
+			RX_MSDU_END_4_LAST_MSDU_LSB;
+
+		if (last_msdu) {
+			qdf_nbuf_set_next(msdu, NULL);
+			break;
+		}
+
+		next = htt_rx_netbuf_pop(pdev);
+		qdf_nbuf_set_next(msdu, next);
+		msdu = next;
+	}
+	*tail_msdu = msdu;
+
+	/*
+	 * Don't refill the ring yet.
+	 * First, the elements popped here are still in use - it is
+	 * not safe to overwrite them until the matching call to
+	 * mpdu_desc_list_next.
+	 * Second, for efficiency it is preferable to refill the rx ring
+	 * with 1 PPDU's worth of rx buffers (something like 32 x 3 buffers),
+	 * rather than one MPDU's worth of rx buffers (sth like 3 buffers).
+	 * Consequently, we'll rely on the txrx SW to tell us when it is done
+	 * pulling all the PPDU's rx buffers out of the rx ring, and then
+	 * refill it just once.
+	 */
+	return msdu_chaining;
+}
+
+static
+void *htt_rx_mpdu_desc_list_next_ll(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
+{
+	int idx = pdev->rx_ring.sw_rd_idx.msdu_desc;
+	qdf_nbuf_t netbuf = pdev->rx_ring.buf.netbufs_ring[idx];
+
+	pdev->rx_ring.sw_rd_idx.msdu_desc = pdev->rx_ring.sw_rd_idx.msdu_payld;
+	return (void *)htt_rx_desc(netbuf);
+}
+
+#else
+
+static inline int
+htt_rx_amsdu_pop_ll(htt_pdev_handle pdev,
+		    qdf_nbuf_t rx_ind_msg,
+		    qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu,
+		    uint32_t *msdu_count)
+{
+	return 0;
+}
+
+static inline
+void *htt_rx_mpdu_desc_list_next_ll(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
+{
+	return NULL;
+}
+#endif
+
+/**
+ * htt_rx_fill_ring_count() - replenish rx msdu buffer
+ * @pdev: Handle (pointer) to HTT pdev.
+ *
+ * This funciton will replenish the rx buffer to the max number
+ * that can be kept in the ring
+ *
+ * Return: None
+ */
+void htt_rx_fill_ring_count(htt_pdev_handle pdev)
+{
+	int num_to_fill;
+
+	num_to_fill = pdev->rx_ring.fill_level - pdev->rx_ring.fill_cnt;
+	htt_rx_ring_fill_n(pdev, num_to_fill /* okay if <= 0 */);
+}
+
+int htt_rx_attach(struct htt_pdev_t *pdev)
+{
+	qdf_dma_addr_t paddr;
+	uint32_t ring_elem_size = sizeof(target_paddr_t);
+
+	pdev->rx_ring.size = htt_rx_ring_size(pdev);
+	HTT_ASSERT2(QDF_IS_PWR2(pdev->rx_ring.size));
+	pdev->rx_ring.size_mask = pdev->rx_ring.size - 1;
+
+	/*
+	 * Set the initial value for the level to which the rx ring
+	 * should be filled, based on the max throughput and the worst
+	 * likely latency for the host to fill the rx ring.
+	 * In theory, this fill level can be dynamically adjusted from
+	 * the initial value set here to reflect the actual host latency
+	 * rather than a conservative assumption.
+	 */
+	pdev->rx_ring.fill_level = htt_rx_ring_fill_level(pdev);
+
+	if (pdev->cfg.is_full_reorder_offload) {
+		if (htt_rx_hash_init(pdev))
+			goto fail1;
+
+		/* allocate the target index */
+		pdev->rx_ring.target_idx.vaddr =
+			 qdf_mem_alloc_consistent(pdev->osdev, pdev->osdev->dev,
+						  sizeof(uint32_t), &paddr);
+
+		if (!pdev->rx_ring.target_idx.vaddr)
+			goto fail2;
+
+		pdev->rx_ring.target_idx.paddr = paddr;
+		*pdev->rx_ring.target_idx.vaddr = 0;
+	} else {
+		pdev->rx_ring.buf.netbufs_ring =
+			qdf_mem_malloc(pdev->rx_ring.size * sizeof(qdf_nbuf_t));
+		if (!pdev->rx_ring.buf.netbufs_ring)
+			goto fail1;
+
+		pdev->rx_ring.sw_rd_idx.msdu_payld = 0;
+		pdev->rx_ring.sw_rd_idx.msdu_desc = 0;
+	}
+
+	pdev->rx_ring.buf.paddrs_ring =
+		qdf_mem_alloc_consistent(
+			pdev->osdev, pdev->osdev->dev,
+			 pdev->rx_ring.size * ring_elem_size,
+			 &paddr);
+	if (!pdev->rx_ring.buf.paddrs_ring)
+		goto fail3;
+
+	pdev->rx_ring.base_paddr = paddr;
+	pdev->rx_ring.alloc_idx.vaddr =
+		 qdf_mem_alloc_consistent(
+			pdev->osdev, pdev->osdev->dev,
+			 sizeof(uint32_t), &paddr);
+
+	if (!pdev->rx_ring.alloc_idx.vaddr)
+		goto fail4;
+
+	pdev->rx_ring.alloc_idx.paddr = paddr;
+	*pdev->rx_ring.alloc_idx.vaddr = 0;
+
+	if (htt_rx_buff_pool_init(pdev))
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+			  "HTT: pre allocated packet pool alloc failed");
+
+	/*
+	 * Initialize the Rx refill reference counter to be one so that
+	 * only one thread is allowed to refill the Rx ring.
+	 */
+	qdf_atomic_init(&pdev->rx_ring.refill_ref_cnt);
+	qdf_atomic_inc(&pdev->rx_ring.refill_ref_cnt);
+
+	/* Initialize the refill_lock and debt (for rx-parallelization) */
+	qdf_spinlock_create(&pdev->rx_ring.refill_lock);
+	qdf_atomic_init(&pdev->rx_ring.refill_debt);
+
+	/* Initialize the Rx refill retry timer */
+	qdf_timer_init(pdev->osdev,
+		       &pdev->rx_ring.refill_retry_timer,
+		       htt_rx_ring_refill_retry, (void *)pdev,
+		       QDF_TIMER_TYPE_SW);
+
+	pdev->rx_ring.fill_cnt = 0;
+	pdev->rx_ring.pop_fail_cnt = 0;
+#ifdef DEBUG_DMA_DONE
+	pdev->rx_ring.dbg_ring_idx = 0;
+	pdev->rx_ring.dbg_refill_cnt = 0;
+	pdev->rx_ring.dbg_sync_success = 0;
+#endif
+#ifdef HTT_RX_RESTORE
+	pdev->rx_ring.rx_reset = 0;
+	pdev->rx_ring.htt_rx_restore = 0;
+#endif
+	htt_rx_dbg_rxbuf_init(pdev);
+	htt_rx_ring_fill_n(pdev, pdev->rx_ring.fill_level);
+
+	if (pdev->cfg.is_full_reorder_offload) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+			  "HTT: full reorder offload enabled");
+		htt_rx_amsdu_pop = htt_rx_amsdu_rx_in_order_pop_ll;
+		htt_rx_frag_pop = htt_rx_amsdu_rx_in_order_pop_ll;
+		htt_rx_mpdu_desc_list_next =
+			 htt_rx_in_ord_mpdu_desc_list_next_ll;
+	} else {
+		htt_rx_amsdu_pop = htt_rx_amsdu_pop_ll;
+		htt_rx_frag_pop = htt_rx_amsdu_pop_ll;
+		htt_rx_mpdu_desc_list_next = htt_rx_mpdu_desc_list_next_ll;
+	}
+
+	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
+		htt_rx_amsdu_pop = htt_rx_mon_amsdu_rx_in_order_pop_ll;
+
+	htt_rx_offload_msdu_cnt = htt_rx_offload_msdu_cnt_ll;
+	htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_ll;
+	htt_rx_mpdu_desc_retry = htt_rx_mpdu_desc_retry_ll;
+	htt_rx_mpdu_desc_seq_num = htt_rx_mpdu_desc_seq_num_ll;
+	htt_rx_mpdu_desc_pn = htt_rx_mpdu_desc_pn_ll;
+	htt_rx_mpdu_desc_tid = htt_rx_mpdu_desc_tid_ll;
+	htt_rx_msdu_desc_completes_mpdu = htt_rx_msdu_desc_completes_mpdu_ll;
+	htt_rx_msdu_first_msdu_flag = htt_rx_msdu_first_msdu_flag_ll;
+	htt_rx_msdu_has_wlan_mcast_flag = htt_rx_msdu_has_wlan_mcast_flag_ll;
+	htt_rx_msdu_is_wlan_mcast = htt_rx_msdu_is_wlan_mcast_ll;
+	htt_rx_msdu_is_frag = htt_rx_msdu_is_frag_ll;
+	htt_rx_msdu_desc_retrieve = htt_rx_msdu_desc_retrieve_ll;
+	htt_rx_mpdu_is_encrypted = htt_rx_mpdu_is_encrypted_ll;
+	htt_rx_msdu_desc_key_id = htt_rx_msdu_desc_key_id_ll;
+	htt_rx_msdu_chan_info_present = htt_rx_msdu_chan_info_present_ll;
+	htt_rx_msdu_center_freq = htt_rx_msdu_center_freq_ll;
+
+	return 0;               /* success */
+
+fail4:
+	qdf_mem_free_consistent(pdev->osdev, pdev->osdev->dev,
+				pdev->rx_ring.size * sizeof(target_paddr_t),
+				pdev->rx_ring.buf.paddrs_ring,
+				pdev->rx_ring.base_paddr,
+				qdf_get_dma_mem_context((&pdev->rx_ring.buf),
+							memctx));
+
+fail3:
+	if (pdev->cfg.is_full_reorder_offload)
+		qdf_mem_free_consistent(pdev->osdev, pdev->osdev->dev,
+					sizeof(uint32_t),
+					pdev->rx_ring.target_idx.vaddr,
+					pdev->rx_ring.target_idx.paddr,
+					qdf_get_dma_mem_context((&pdev->
+								 rx_ring.
+								 target_idx),
+								 memctx));
+	else
+		qdf_mem_free(pdev->rx_ring.buf.netbufs_ring);
+
+fail2:
+	if (pdev->cfg.is_full_reorder_offload)
+		htt_rx_hash_deinit(pdev);
+
+fail1:
+	return 1;               /* failure */
+}
+
+void htt_rx_detach(struct htt_pdev_t *pdev)
+{
+	bool ipa_smmu = false;
+
+	qdf_timer_stop(&pdev->rx_ring.refill_retry_timer);
+	qdf_timer_free(&pdev->rx_ring.refill_retry_timer);
+	htt_rx_dbg_rxbuf_deinit(pdev);
+
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev) && pdev->is_ipa_uc_enabled &&
+	    pdev->rx_ring.smmu_map)
+		ipa_smmu = true;
+
+	if (pdev->cfg.is_full_reorder_offload) {
+		qdf_mem_free_consistent(pdev->osdev, pdev->osdev->dev,
+					sizeof(uint32_t),
+					pdev->rx_ring.target_idx.vaddr,
+					pdev->rx_ring.target_idx.paddr,
+					qdf_get_dma_mem_context((&pdev->
+								 rx_ring.
+								 target_idx),
+								 memctx));
+		htt_rx_hash_deinit(pdev);
+	} else {
+		int sw_rd_idx = pdev->rx_ring.sw_rd_idx.msdu_payld;
+		qdf_mem_info_t mem_map_table = {0};
+
+		while (sw_rd_idx != *pdev->rx_ring.alloc_idx.vaddr) {
+			if (ipa_smmu) {
+				qdf_update_mem_map_table(pdev->osdev,
+					&mem_map_table,
+					QDF_NBUF_CB_PADDR(
+						pdev->rx_ring.buf.
+						netbufs_ring[sw_rd_idx]),
+					HTT_RX_BUF_SIZE);
+				cds_smmu_map_unmap(false, 1,
+						   &mem_map_table);
+			}
+#ifdef DEBUG_DMA_DONE
+			qdf_nbuf_unmap(pdev->osdev,
+				       pdev->rx_ring.buf.
+				       netbufs_ring[sw_rd_idx],
+				       QDF_DMA_BIDIRECTIONAL);
+#else
+			qdf_nbuf_unmap(pdev->osdev,
+				       pdev->rx_ring.buf.
+				       netbufs_ring[sw_rd_idx],
+				       QDF_DMA_FROM_DEVICE);
+#endif
+			qdf_nbuf_free(pdev->rx_ring.buf.
+				      netbufs_ring[sw_rd_idx]);
+			sw_rd_idx++;
+			sw_rd_idx &= pdev->rx_ring.size_mask;
+		}
+		qdf_mem_free(pdev->rx_ring.buf.netbufs_ring);
+	}
+
+	htt_rx_buff_pool_deinit(pdev);
+
+	qdf_mem_free_consistent(pdev->osdev, pdev->osdev->dev,
+				sizeof(uint32_t),
+				pdev->rx_ring.alloc_idx.vaddr,
+				pdev->rx_ring.alloc_idx.paddr,
+				qdf_get_dma_mem_context((&pdev->rx_ring.
+							 alloc_idx),
+							 memctx));
+
+	qdf_mem_free_consistent(pdev->osdev, pdev->osdev->dev,
+				pdev->rx_ring.size * sizeof(target_paddr_t),
+				pdev->rx_ring.buf.paddrs_ring,
+				pdev->rx_ring.base_paddr,
+				qdf_get_dma_mem_context((&pdev->rx_ring.buf),
+							memctx));
+
+	/* destroy the rx-parallelization refill spinlock */
+	qdf_spinlock_destroy(&pdev->rx_ring.refill_lock);
+}
+
+static QDF_STATUS htt_rx_hash_smmu_map(bool map, struct htt_pdev_t *pdev)
+{
+	uint32_t i;
+	struct htt_rx_hash_entry *hash_entry;
+	struct htt_rx_hash_bucket **hash_table;
+	struct htt_list_node *list_iter = NULL;
+	qdf_mem_info_t mem_map_table = {0};
+	int ret;
+
+	qdf_spin_lock_bh(&pdev->rx_ring.rx_hash_lock);
+	hash_table = pdev->rx_ring.hash_table;
+
+	for (i = 0; i < RX_NUM_HASH_BUCKETS; i++) {
+		/* Free the hash entries in hash bucket i */
+		list_iter = hash_table[i]->listhead.next;
+		while (list_iter != &hash_table[i]->listhead) {
+			hash_entry =
+				(struct htt_rx_hash_entry *)((char *)list_iter -
+							     pdev->rx_ring.
+							     listnode_offset);
+			if (hash_entry->netbuf) {
+				qdf_update_mem_map_table(pdev->osdev,
+						&mem_map_table,
+						QDF_NBUF_CB_PADDR(
+							hash_entry->netbuf),
+						HTT_RX_BUF_SIZE);
+				ret = cds_smmu_map_unmap(map, 1,
+							 &mem_map_table);
+				if (ret) {
+					qdf_spin_unlock_bh(
+						&pdev->rx_ring.rx_hash_lock);
+					return QDF_STATUS_E_FAILURE;
+				}
+			}
+			list_iter = list_iter->next;
+		}
+	}
+
+	qdf_spin_unlock_bh(&pdev->rx_ring.rx_hash_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS htt_rx_update_smmu_map(struct htt_pdev_t *pdev, bool map)
+{
+	QDF_STATUS status;
+
+	if (!pdev->rx_ring.hash_table)
+		return QDF_STATUS_SUCCESS;
+
+	if (!qdf_mem_smmu_s1_enabled(pdev->osdev) || !pdev->is_ipa_uc_enabled)
+		return QDF_STATUS_SUCCESS;
+
+	qdf_spin_lock_bh(&pdev->rx_ring.refill_lock);
+	pdev->rx_ring.smmu_map = map;
+	status = htt_rx_hash_smmu_map(map, pdev);
+	qdf_spin_unlock_bh(&pdev->rx_ring.refill_lock);
+
+	return status;
+}
diff --git a/core/dp/htt/htt_t2h.c b/core/dp/htt/htt_t2h.c
new file mode 100644
index 0000000..8a0566f
--- /dev/null
+++ b/core/dp/htt/htt_t2h.c
@@ -0,0 +1,1592 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ * @file htt_t2h.c
+ * @brief Provide functions to process target->host HTT messages.
+ * @details
+ *  This file contains functions related to target->host HTT messages.
+ *  There are two categories of functions:
+ *  1.  A function that receives a HTT message from HTC, and dispatches it
+ *      based on the HTT message type.
+ *  2.  functions that provide the info elements from specific HTT messages.
+ */
+#include <wma.h>
+#include <htc_api.h>            /* HTC_PACKET */
+#include <htt.h>                /* HTT_T2H_MSG_TYPE, etc. */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+
+#include <ol_htt_rx_api.h>
+#include <ol_htt_tx_api.h>
+#include <ol_txrx_htt_api.h>    /* htt_tx_status */
+
+#include <htt_internal.h>       /* HTT_TX_SCHED, etc. */
+#include <pktlog_ac_fmt.h>
+#include <wdi_event.h>
+#include <ol_htt_tx_api.h>
+#include <ol_txrx_peer_find.h>
+#include <cdp_txrx_ipa.h>
+#include "pktlog_ac.h"
+#include <cdp_txrx_handle.h>
+/*--- target->host HTT message dispatch function ----------------------------*/
+
+#ifndef DEBUG_CREDIT
+#define DEBUG_CREDIT 0
+#endif
+
+#if defined(CONFIG_HL_SUPPORT)
+
+
+
+/**
+ * htt_rx_frag_set_last_msdu() - set last msdu bit in rx descriptor
+ *				 for received frames
+ * @pdev: Handle (pointer) to HTT pdev.
+ * @msg: htt received msg
+ *
+ * Return: None
+ */
+static inline
+void htt_rx_frag_set_last_msdu(struct htt_pdev_t *pdev, qdf_nbuf_t msg)
+{
+}
+#else
+
+static void htt_rx_frag_set_last_msdu(struct htt_pdev_t *pdev, qdf_nbuf_t msg)
+{
+	uint32_t *msg_word;
+	unsigned int num_msdu_bytes;
+	qdf_nbuf_t msdu;
+	struct htt_host_rx_desc_base *rx_desc;
+	int start_idx;
+	uint8_t *p_fw_msdu_rx_desc = 0;
+
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+	num_msdu_bytes = HTT_RX_FRAG_IND_FW_RX_DESC_BYTES_GET(
+		*(msg_word + HTT_RX_FRAG_IND_HDR_PREFIX_SIZE32));
+	/*
+	 * 1 word for the message header,
+	 * 1 word to specify the number of MSDU bytes,
+	 * 1 word for every 4 MSDU bytes (round up),
+	 * 1 word for the MPDU range header
+	 */
+	pdev->rx_mpdu_range_offset_words = 3 + ((num_msdu_bytes + 3) >> 2);
+	pdev->rx_ind_msdu_byte_idx = 0;
+
+	p_fw_msdu_rx_desc = ((uint8_t *) (msg_word) +
+			     HTT_ENDIAN_BYTE_IDX_SWAP
+				     (HTT_RX_FRAG_IND_FW_DESC_BYTE_OFFSET));
+
+	/*
+	 * Fix for EV126710, in which BSOD occurs due to last_msdu bit
+	 * not set while the next pointer is deliberately set to NULL
+	 * before calling ol_rx_pn_check_base()
+	 *
+	 * For fragment frames, the HW may not have set the last_msdu bit
+	 * in the rx descriptor, but the SW expects this flag to be set,
+	 * since each fragment is in a separate MPDU. Thus, set the flag here,
+	 * just in case the HW didn't.
+	 */
+	start_idx = pdev->rx_ring.sw_rd_idx.msdu_payld;
+	msdu = pdev->rx_ring.buf.netbufs_ring[start_idx];
+	qdf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE);
+	qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE);
+	rx_desc = htt_rx_desc(msdu);
+	*((uint8_t *) &rx_desc->fw_desc.u.val) = *p_fw_msdu_rx_desc;
+	rx_desc->msdu_end.last_msdu = 1;
+	qdf_nbuf_map(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE);
+}
+#endif
+
+static uint8_t *htt_t2h_mac_addr_deswizzle(uint8_t *tgt_mac_addr,
+					   uint8_t *buffer)
+{
+#ifdef BIG_ENDIAN_HOST
+	/*
+	 * The host endianness is opposite of the target endianness.
+	 * To make uint32_t elements come out correctly, the target->host
+	 * upload has swizzled the bytes in each uint32_t element of the
+	 * message.
+	 * For byte-array message fields like the MAC address, this
+	 * upload swizzling puts the bytes in the wrong order, and needs
+	 * to be undone.
+	 */
+	buffer[0] = tgt_mac_addr[3];
+	buffer[1] = tgt_mac_addr[2];
+	buffer[2] = tgt_mac_addr[1];
+	buffer[3] = tgt_mac_addr[0];
+	buffer[4] = tgt_mac_addr[7];
+	buffer[5] = tgt_mac_addr[6];
+	return buffer;
+#else
+	/*
+	 * The host endianness matches the target endianness -
+	 * we can use the mac addr directly from the message buffer.
+	 */
+	return tgt_mac_addr;
+#endif
+}
+
+/**
+ * htt_ipa_op_response() - invoke an event handler from FW
+ * @pdev: Handle (pointer) to HTT pdev.
+ * @msg_word: htt msg
+ *
+ * Return: None
+ */
+#ifdef IPA_OFFLOAD
+static void htt_ipa_op_response(struct htt_pdev_t *pdev, uint32_t *msg_word)
+{
+	uint8_t op_code;
+	uint16_t len;
+	uint8_t *op_msg_buffer;
+	uint8_t *msg_start_ptr;
+
+	htc_pm_runtime_put(pdev->htc_pdev);
+	msg_start_ptr = (uint8_t *) msg_word;
+	op_code =
+		HTT_WDI_IPA_OP_RESPONSE_OP_CODE_GET(*msg_word);
+	msg_word++;
+	len = HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_GET(*msg_word);
+
+	op_msg_buffer =
+		qdf_mem_malloc(sizeof
+				(struct htt_wdi_ipa_op_response_t) +
+				len);
+	if (!op_msg_buffer) {
+		qdf_print("OPCODE message buffer alloc fail");
+		return;
+	}
+	qdf_mem_copy(op_msg_buffer,
+			msg_start_ptr,
+			sizeof(struct htt_wdi_ipa_op_response_t) +
+			len);
+	cdp_ipa_op_response(cds_get_context(QDF_MODULE_ID_SOC),
+			(struct cdp_pdev *)pdev->txrx_pdev,
+			op_msg_buffer);
+}
+#else
+static void htt_ipa_op_response(struct htt_pdev_t *pdev, uint32_t *msg_word)
+{
+}
+#endif
+
+#define MAX_TARGET_TX_CREDIT    204800
+
+/* Target to host Msg/event  handler  for low priority messages*/
+static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg,
+				   bool free_msg_buf)
+{
+	struct htt_pdev_t *pdev = (struct htt_pdev_t *)context;
+	uint32_t *msg_word;
+	enum htt_t2h_msg_type msg_type;
+
+	msg_word = (uint32_t *) qdf_nbuf_data(htt_t2h_msg);
+	msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word);
+	switch (msg_type) {
+	case HTT_T2H_MSG_TYPE_VERSION_CONF:
+	{
+		htc_pm_runtime_put(pdev->htc_pdev);
+		pdev->tgt_ver.major = HTT_VER_CONF_MAJOR_GET(*msg_word);
+		pdev->tgt_ver.minor = HTT_VER_CONF_MINOR_GET(*msg_word);
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+			  "target uses HTT version %d.%d; host uses %d.%d",
+			  pdev->tgt_ver.major, pdev->tgt_ver.minor,
+			  HTT_CURRENT_VERSION_MAJOR,
+			  HTT_CURRENT_VERSION_MINOR);
+		if (pdev->tgt_ver.major != HTT_CURRENT_VERSION_MAJOR)
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_WARN,
+				  "*** Incompatible host/target HTT versions!");
+		/* abort if the target is incompatible with the host */
+		qdf_assert(pdev->tgt_ver.major ==
+			   HTT_CURRENT_VERSION_MAJOR);
+		if (pdev->tgt_ver.minor != HTT_CURRENT_VERSION_MINOR) {
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+				  "*** Warning: host/target HTT versions are ");
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
+				  "different, though compatible!");
+		}
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_RX_FLUSH:
+	{
+		uint16_t peer_id;
+		uint8_t tid;
+		uint16_t seq_num_start, seq_num_end;
+		enum htt_rx_flush_action action;
+
+		peer_id = HTT_RX_FLUSH_PEER_ID_GET(*msg_word);
+		tid = HTT_RX_FLUSH_TID_GET(*msg_word);
+		seq_num_start =
+			HTT_RX_FLUSH_SEQ_NUM_START_GET(*(msg_word + 1));
+		seq_num_end =
+			HTT_RX_FLUSH_SEQ_NUM_END_GET(*(msg_word + 1));
+		action =
+			HTT_RX_FLUSH_MPDU_STATUS_GET(*(msg_word + 1)) ==
+			1 ? htt_rx_flush_release : htt_rx_flush_discard;
+		ol_rx_flush_handler(pdev->txrx_pdev, peer_id, tid,
+				    seq_num_start, seq_num_end, action);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND:
+	{
+		uint16_t msdu_cnt;
+
+		if (!pdev->cfg.is_high_latency &&
+		    pdev->cfg.is_full_reorder_offload) {
+			qdf_print("HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND not ");
+			qdf_print("supported when full reorder offload is ");
+			qdf_print("enabled in the configuration.\n");
+			break;
+		}
+		msdu_cnt =
+			HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_GET(*msg_word);
+		ol_rx_offload_deliver_ind_handler(pdev->txrx_pdev,
+						  htt_t2h_msg,
+						  msdu_cnt);
+		if (pdev->cfg.is_high_latency) {
+			/*
+			 * return here for HL to avoid double free on
+			 * htt_t2h_msg
+			 */
+			return;
+		}
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_RX_FRAG_IND:
+	{
+		uint16_t peer_id;
+		uint8_t tid;
+
+		peer_id = HTT_RX_FRAG_IND_PEER_ID_GET(*msg_word);
+		tid = HTT_RX_FRAG_IND_EXT_TID_GET(*msg_word);
+		htt_rx_frag_set_last_msdu(pdev, htt_t2h_msg);
+
+		/* If packet len is invalid, will discard this frame. */
+		if (pdev->cfg.is_high_latency) {
+			u_int32_t rx_pkt_len = 0;
+
+			rx_pkt_len = qdf_nbuf_len(htt_t2h_msg);
+
+			if (rx_pkt_len < (HTT_RX_FRAG_IND_BYTES +
+				sizeof(struct hl_htt_rx_ind_base)+
+				sizeof(struct ieee80211_frame))) {
+
+				qdf_print("%s: invalid packet len, %u\n",
+						__func__,
+						rx_pkt_len);
+				/*
+				 * This buf will be freed before
+				 * exiting this function.
+				 */
+				break;
+			}
+		}
+
+		ol_rx_frag_indication_handler(pdev->txrx_pdev,
+					      htt_t2h_msg,
+					      peer_id, tid);
+
+		if (pdev->cfg.is_high_latency) {
+			/*
+			* For high latency solution,
+			* HTT_T2H_MSG_TYPE_RX_FRAG_IND message and RX packet
+			* share the same buffer. All buffer will be freed by
+			* ol_rx_frag_indication_handler or upper layer to
+			* avoid double free issue.
+			*
+			*/
+			return;
+		}
+
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_RX_ADDBA:
+	{
+		qdf_print("HTT_T2H_MSG_TYPE_RX_ADDBA not supported ");
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_RX_DELBA:
+	{
+		qdf_print("HTT_T2H_MSG_TYPE_RX_DELBA not supported ");
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_PEER_MAP:
+	{
+		uint8_t mac_addr_deswizzle_buf[HTT_MAC_ADDR_LEN];
+		uint8_t *peer_mac_addr;
+		uint16_t peer_id;
+		uint8_t vdev_id;
+
+		peer_id = HTT_RX_PEER_MAP_PEER_ID_GET(*msg_word);
+		vdev_id = HTT_RX_PEER_MAP_VDEV_ID_GET(*msg_word);
+		peer_mac_addr = htt_t2h_mac_addr_deswizzle(
+			(uint8_t *) (msg_word + 1),
+			&mac_addr_deswizzle_buf[0]);
+
+		if (peer_id > ol_cfg_max_peer_id(pdev->ctrl_pdev)) {
+			qdf_print("%s: HTT_T2H_MSG_TYPE_PEER_MAP,"
+				"invalid peer_id, %u\n",
+				__FUNCTION__,
+				peer_id);
+			break;
+		}
+
+		ol_rx_peer_map_handler(pdev->txrx_pdev, peer_id,
+				       vdev_id, peer_mac_addr,
+				       1 /*can tx */);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_PEER_UNMAP:
+	{
+		uint16_t peer_id;
+
+		peer_id = HTT_RX_PEER_UNMAP_PEER_ID_GET(*msg_word);
+		if (peer_id > ol_cfg_max_peer_id(pdev->ctrl_pdev)) {
+			qdf_print("%s: HTT_T2H_MSG_TYPE_PEER_UNMAP,"
+				"invalid peer_id, %u\n",
+				__FUNCTION__,
+				peer_id);
+			break;
+		}
+
+		ol_rx_peer_unmap_handler(pdev->txrx_pdev, peer_id);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_SEC_IND:
+	{
+		uint16_t peer_id;
+		enum htt_sec_type sec_type;
+		int is_unicast;
+
+		peer_id = HTT_SEC_IND_PEER_ID_GET(*msg_word);
+		sec_type = HTT_SEC_IND_SEC_TYPE_GET(*msg_word);
+		is_unicast = HTT_SEC_IND_UNICAST_GET(*msg_word);
+		msg_word++;   /* point to the first part of the Michael key */
+		ol_rx_sec_ind_handler(pdev->txrx_pdev, peer_id,
+				      sec_type, is_unicast, msg_word,
+				      msg_word + 2);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_MGMT_TX_COMPL_IND:
+	{
+		struct htt_mgmt_tx_compl_ind *compl_msg;
+		int32_t credit_delta = 1;
+		int msg_len = qdf_nbuf_len(htt_t2h_msg);
+		if (msg_len < (sizeof(struct htt_mgmt_tx_compl_ind) + sizeof(*msg_word))) {
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+				  "Invalid msg_word length in HTT_T2H_MSG_TYPE_MGMT_TX_COMPL_IND");
+			WARN_ON(1);
+			break;
+		}
+
+		compl_msg =
+			(struct htt_mgmt_tx_compl_ind *)(msg_word + 1);
+
+		if (pdev->cfg.is_high_latency) {
+			if (!pdev->cfg.default_tx_comp_req) {
+				HTT_TX_MUTEX_ACQUIRE(&pdev->credit_mutex);
+				qdf_atomic_add(credit_delta,
+					       &pdev->htt_tx_credit.
+								target_delta);
+				credit_delta = htt_tx_credit_update(pdev);
+				HTT_TX_MUTEX_RELEASE(&pdev->credit_mutex);
+			}
+			if (credit_delta)
+				ol_tx_target_credit_update(
+						pdev->txrx_pdev, credit_delta);
+		}
+		ol_tx_desc_update_group_credit(
+			pdev->txrx_pdev, compl_msg->desc_id, 1,
+			0, compl_msg->status);
+
+		if (!ol_tx_get_is_mgmt_over_wmi_enabled()) {
+			ol_tx_single_completion_handler(pdev->txrx_pdev,
+							compl_msg->status,
+							compl_msg->desc_id);
+			htc_pm_runtime_put(pdev->htc_pdev);
+			HTT_TX_SCHED(pdev);
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+				  "Ignoring HTT_T2H_MSG_TYPE_MGMT_TX_COMPL_IND indication");
+		}
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_STATS_CONF:
+	{
+		uint8_t cookie;
+		uint8_t *stats_info_list;
+
+		cookie = *(msg_word + 1);
+
+		stats_info_list = (uint8_t *) (msg_word + 3);
+		htc_pm_runtime_put(pdev->htc_pdev);
+		ol_txrx_fw_stats_handler(pdev->txrx_pdev, cookie,
+					 stats_info_list);
+		break;
+	}
+#ifndef REMOVE_PKT_LOG
+	case HTT_T2H_MSG_TYPE_PKTLOG:
+	{
+		uint32_t len = qdf_nbuf_len(htt_t2h_msg);
+
+		if (len < sizeof(*msg_word) + sizeof(uint32_t)) {
+			qdf_print("%s: invalid nbuff len \n", __func__);
+			WARN_ON(1);
+			break;
+		}
+
+		/*len is reduced by sizeof(*msg_word)*/
+		pktlog_process_fw_msg(msg_word + 1, len - sizeof(*msg_word));
+		break;
+	}
+#endif
+	case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND:
+	{
+		uint32_t htt_credit_delta_abs;
+		int32_t htt_credit_delta;
+		int sign, old_credit;
+
+		htt_credit_delta_abs =
+			HTT_TX_CREDIT_DELTA_ABS_GET(*msg_word);
+		sign = HTT_TX_CREDIT_SIGN_BIT_GET(*msg_word) ? -1 : 1;
+		htt_credit_delta = sign * htt_credit_delta_abs;
+
+		old_credit = qdf_atomic_read(&pdev->htt_tx_credit.target_delta);
+		if (((old_credit + htt_credit_delta) > MAX_TARGET_TX_CREDIT) ||
+			((old_credit + htt_credit_delta) < -MAX_TARGET_TX_CREDIT)) {
+			qdf_print("%s: invalid credit update,old_credit=%d,"
+				"htt_credit_delta=%d\n",
+				__func__,
+				old_credit,
+				htt_credit_delta);
+			break;
+		}
+
+		if (pdev->cfg.is_high_latency &&
+		    !pdev->cfg.default_tx_comp_req) {
+			HTT_TX_MUTEX_ACQUIRE(&pdev->credit_mutex);
+			qdf_atomic_add(htt_credit_delta,
+				       &pdev->htt_tx_credit.target_delta);
+			htt_credit_delta = htt_tx_credit_update(pdev);
+			HTT_TX_MUTEX_RELEASE(&pdev->credit_mutex);
+		}
+
+		htt_tx_group_credit_process(pdev, msg_word);
+		ol_tx_credit_completion_handler(pdev->txrx_pdev,
+						htt_credit_delta);
+		break;
+	}
+
+	case HTT_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE:
+	{
+		uint16_t len;
+		int msg_len = qdf_nbuf_len(htt_t2h_msg);
+		len = HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_GET(*(msg_word + 1));
+
+		if (sizeof(struct htt_wdi_ipa_op_response_t) + len > msg_len) {
+			qdf_print("Invalid buf len size %zu len %d, msg_len %d",
+				  sizeof(struct htt_wdi_ipa_op_response_t),
+				  len, msg_len);
+			WARN_ON(1);
+			break;
+		}
+		htt_ipa_op_response(pdev, msg_word);
+		break;
+	}
+
+	case HTT_T2H_MSG_TYPE_FLOW_POOL_MAP:
+	{
+		uint8_t num_flows;
+		struct htt_flow_pool_map_payload_t *pool_map_payoad;
+		int msg_len = qdf_nbuf_len(htt_t2h_msg);
+
+		num_flows = HTT_FLOW_POOL_MAP_NUM_FLOWS_GET(*msg_word);
+
+		if (((HTT_FLOW_POOL_MAP_PAYLOAD_SZ /
+			HTT_FLOW_POOL_MAP_HEADER_SZ) * num_flows + 1) * sizeof(*msg_word) > msg_len) {
+			qdf_print("Invalid num_flows");
+			WARN_ON(1);
+			break;
+		}
+
+		msg_word++;
+		while (num_flows) {
+			pool_map_payoad = (struct htt_flow_pool_map_payload_t *)
+								msg_word;
+			ol_tx_flow_pool_map_handler(pool_map_payoad->flow_id,
+					pool_map_payoad->flow_type,
+					pool_map_payoad->flow_pool_id,
+					pool_map_payoad->flow_pool_size);
+
+			msg_word += (HTT_FLOW_POOL_MAP_PAYLOAD_SZ /
+						 HTT_FLOW_POOL_MAP_HEADER_SZ);
+			num_flows--;
+		}
+		break;
+	}
+
+	case HTT_T2H_MSG_TYPE_FLOW_POOL_UNMAP:
+	{
+		struct htt_flow_pool_unmap_t *pool_numap_payload;
+		int msg_len = qdf_nbuf_len(htt_t2h_msg);
+
+		if (msg_len < sizeof(struct htt_flow_pool_unmap_t)) {
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+				  "Invalid msg_word length in HTT_T2H_MSG_TYPE_FLOW_POOL_UNMAP");
+			WARN_ON(1);
+			break;
+		}
+
+		pool_numap_payload = (struct htt_flow_pool_unmap_t *)msg_word;
+		ol_tx_flow_pool_unmap_handler(pool_numap_payload->flow_id,
+					pool_numap_payload->flow_type,
+					pool_numap_payload->flow_pool_id);
+		break;
+	}
+
+	case HTT_T2H_MSG_TYPE_FLOW_POOL_RESIZE:
+	{
+		struct htt_flow_pool_resize_t *msg;
+		int msg_len = qdf_nbuf_len(htt_t2h_msg);
+
+		if (msg_len < sizeof(struct htt_flow_pool_resize_t)) {
+			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
+				  "Invalid msg_word length in HTT_T2H_MSG_TYPE_FLOW_POOL_RESIZE");
+			WARN_ON(1);
+			break;
+		}
+
+		msg = (struct htt_flow_pool_resize_t *)msg_word;
+		ol_tx_flow_pool_resize_handler(msg->flow_pool_id,
+					       msg->flow_pool_new_size);
+
+		break;
+	}
+
+	case HTT_T2H_MSG_TYPE_RX_OFLD_PKT_ERR:
+	{
+		switch (HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_GET(*msg_word)) {
+		case HTT_RX_OFLD_PKT_ERR_TYPE_MIC_ERR:
+		{
+			struct ol_error_info err_info;
+			struct ol_txrx_vdev_t *vdev;
+			struct ol_txrx_peer_t *peer;
+			uint16_t peer_id =
+				 HTT_RX_OFLD_PKT_ERR_MIC_ERR_PEER_ID_GET
+				(*(msg_word + 1));
+
+			peer = ol_txrx_peer_find_by_id(pdev->txrx_pdev,
+				 peer_id);
+			if (!peer) {
+				qdf_print("%s: invalid peer id %d\n",
+					 __func__, peer_id);
+				qdf_assert(0);
+				break;
+			}
+			vdev = peer->vdev;
+			err_info.u.mic_err.vdev_id = vdev->vdev_id;
+			err_info.u.mic_err.key_id =
+				HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_GET
+				(*(msg_word + 1));
+			qdf_mem_copy(err_info.u.mic_err.da,
+				 (uint8_t *)(msg_word + 2),
+				 OL_TXRX_MAC_ADDR_LEN);
+			qdf_mem_copy(err_info.u.mic_err.sa,
+				 (uint8_t *)(msg_word + 4),
+				 OL_TXRX_MAC_ADDR_LEN);
+			qdf_mem_copy(&err_info.u.mic_err.pn,
+				 (uint8_t *)(msg_word + 6), 6);
+			qdf_mem_copy(err_info.u.mic_err.ta,
+				 peer->mac_addr.raw, OL_TXRX_MAC_ADDR_LEN);
+
+			wma_indicate_err(OL_RX_ERR_TKIP_MIC, &err_info);
+			break;
+		}
+		default:
+		{
+			qdf_print("%s: unhandled error type %d\n",
+			 __func__,
+			 HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_GET(*msg_word));
+		break;
+		}
+		}
+	}
+
+	default:
+		break;
+	};
+	/* Free the indication buffer */
+	if (free_msg_buf)
+		qdf_nbuf_free(htt_t2h_msg);
+}
+
+#define HTT_TX_COMPL_HEAD_SZ			4
+#define HTT_TX_COMPL_BYTES_PER_MSDU_ID		2
+
+/**
+ * Generic Target to host Msg/event  handler  for low priority messages
+ * Low priority message are handler in a different handler called from
+ * this function . So that the most likely succes path like Rx and
+ * Tx comp   has little code   foot print
+ */
+void htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
+{
+	struct htt_pdev_t *pdev = (struct htt_pdev_t *)context;
+	qdf_nbuf_t htt_t2h_msg = (qdf_nbuf_t) pkt->pPktContext;
+	uint32_t *msg_word;
+	enum htt_t2h_msg_type msg_type;
+
+	/* check for successful message reception */
+	if (pkt->Status != QDF_STATUS_SUCCESS) {
+		if (pkt->Status != QDF_STATUS_E_CANCELED)
+			pdev->stats.htc_err_cnt++;
+		qdf_nbuf_free(htt_t2h_msg);
+		return;
+	}
+#ifdef HTT_RX_RESTORE
+	if (qdf_unlikely(pdev->rx_ring.rx_reset)) {
+		qdf_print("rx restore ..\n");
+		qdf_nbuf_free(htt_t2h_msg);
+		return;
+	}
+#endif
+
+	/* confirm alignment */
+	HTT_ASSERT3((((unsigned long)qdf_nbuf_data(htt_t2h_msg)) & 0x3) == 0);
+
+	msg_word = (uint32_t *) qdf_nbuf_data(htt_t2h_msg);
+	msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word);
+
+#if defined(HELIUMPLUS_DEBUG)
+	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+		  "%s %d: msg_word 0x%x msg_type %d", __func__, __LINE__,
+		  *msg_word, msg_type);
+#endif
+
+	switch (msg_type) {
+	case HTT_T2H_MSG_TYPE_RX_IND:
+	{
+		unsigned int num_mpdu_ranges;
+		unsigned int num_msdu_bytes;
+		unsigned int calculated_msg_len;
+		unsigned int rx_mpdu_range_offset_bytes;
+		uint16_t peer_id;
+		uint8_t tid;
+		int msg_len = qdf_nbuf_len(htt_t2h_msg);
+
+		if (qdf_unlikely(pdev->cfg.is_full_reorder_offload)) {
+			qdf_print("HTT_T2H_MSG_TYPE_RX_IND not supported ");
+			qdf_print("with full reorder offload\n");
+			break;
+		}
+		peer_id = HTT_RX_IND_PEER_ID_GET(*msg_word);
+		tid = HTT_RX_IND_EXT_TID_GET(*msg_word);
+
+		if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid tid %d\n",
+				tid);
+			break;
+		}
+		if (msg_len < (2 + HTT_RX_PPDU_DESC_SIZE32 + 1) * sizeof(uint32_t)) {
+			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid msg_len\n");
+			break;
+		}
+		num_msdu_bytes =
+			HTT_RX_IND_FW_RX_DESC_BYTES_GET(
+				*(msg_word + 2 + HTT_RX_PPDU_DESC_SIZE32));
+		/*
+		 * 1 word for the message header,
+		 * HTT_RX_PPDU_DESC_SIZE32 words for the FW rx PPDU desc
+		 * 1 word to specify the number of MSDU bytes,
+		 * 1 word for every 4 MSDU bytes (round up),
+		 * 1 word for the MPDU range header
+		 */
+		rx_mpdu_range_offset_bytes =
+			(HTT_RX_IND_HDR_BYTES + num_msdu_bytes + 3);
+		if (qdf_unlikely(num_msdu_bytes >
+				 rx_mpdu_range_offset_bytes)) {
+			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid %s %u\n",
+				  "num_msdu_bytes",
+				  num_msdu_bytes);
+			WARN_ON(1);
+			break;
+		}
+		pdev->rx_mpdu_range_offset_words =
+			rx_mpdu_range_offset_bytes >> 2;
+		num_mpdu_ranges =
+			HTT_RX_IND_NUM_MPDU_RANGES_GET(*(msg_word + 1));
+		pdev->rx_ind_msdu_byte_idx = 0;
+		if (qdf_unlikely(rx_mpdu_range_offset_bytes >
+		    msg_len)) {
+			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid %s %d\n",
+				  "rx_mpdu_range_offset_words",
+				  pdev->rx_mpdu_range_offset_words);
+			WARN_ON(1);
+			break;
+		}
+		calculated_msg_len = rx_mpdu_range_offset_bytes +
+			(num_mpdu_ranges * (int)sizeof(uint32_t));
+		/*
+		 * Check that the addition and multiplication
+		 * do not cause integer overflow
+		 */
+		if (qdf_unlikely(calculated_msg_len <
+		    rx_mpdu_range_offset_bytes)) {
+			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid %s %u\n",
+				  "num_mpdu_ranges",
+				  (num_mpdu_ranges * (int)sizeof(uint32_t)));
+			WARN_ON(1);
+			break;
+		}
+		if (qdf_unlikely(calculated_msg_len > msg_len)) {
+			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid %s %u\n",
+				  "offset_words + mpdu_ranges",
+				  calculated_msg_len);
+			WARN_ON(1);
+			break;
+		}
+		ol_rx_indication_handler(pdev->txrx_pdev,
+					 htt_t2h_msg, peer_id,
+					 tid, num_mpdu_ranges);
+
+		if (pdev->cfg.is_high_latency)
+			return;
+
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
+	{
+		int old_credit;
+		int num_msdus;
+		enum htt_tx_status status;
+		int msg_len = qdf_nbuf_len(htt_t2h_msg);
+
+		/* status - no enum translation needed */
+		status = HTT_TX_COMPL_IND_STATUS_GET(*msg_word);
+		num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word);
+
+		/*
+		 * each desc id will occupy 2 bytes.
+		 * the 4 is for htt msg header
+		 */
+		if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID +
+			HTT_TX_COMPL_HEAD_SZ) > msg_len) {
+			qdf_print("%s: num_msdus(%d) is invalid,"
+				"adf_nbuf_len = %d\n",
+				__FUNCTION__,
+				num_msdus,
+				msg_len);
+			break;
+		}
+
+		if (num_msdus & 0x1) {
+			struct htt_tx_compl_ind_base *compl =
+				(void *)msg_word;
+
+			/*
+			 * Host CPU endianness can be different from FW CPU.
+			 * This can result in even and odd MSDU IDs being
+			 * switched. If this happens, copy the switched final
+			 * odd MSDU ID from location payload[size], to
+			 * location payload[size-1], where the message
+			 * handler function expects to find it
+			 */
+			if (compl->payload[num_msdus] !=
+			    HTT_TX_COMPL_INV_MSDU_ID) {
+				compl->payload[num_msdus - 1] =
+					compl->payload[num_msdus];
+			}
+		}
+
+		if (pdev->cfg.is_high_latency &&
+		    !pdev->cfg.credit_update_enabled) {
+			old_credit = qdf_atomic_read(
+						&pdev->htt_tx_credit.target_delta);
+			if (((old_credit + num_msdus) > MAX_TARGET_TX_CREDIT) ||
+				((old_credit + num_msdus) < -MAX_TARGET_TX_CREDIT)) {
+				qdf_print("%s: invalid credit update,old_credit=%d,"
+					"num_msdus=%d\n",
+					__func__,
+					old_credit,
+					num_msdus);
+			} else {
+				if (!pdev->cfg.default_tx_comp_req) {
+					int credit_delta;
+
+					HTT_TX_MUTEX_ACQUIRE(&pdev->credit_mutex);
+					qdf_atomic_add(num_msdus,
+						       &pdev->htt_tx_credit.
+							target_delta);
+					credit_delta = htt_tx_credit_update(pdev);
+					HTT_TX_MUTEX_RELEASE(&pdev->credit_mutex);
+
+					if (credit_delta) {
+						ol_tx_target_credit_update(
+								pdev->txrx_pdev,
+								credit_delta);
+					}
+				} else {
+					ol_tx_target_credit_update(pdev->txrx_pdev,
+								   num_msdus);
+				}
+			}
+		}
+
+		ol_tx_completion_handler(pdev->txrx_pdev, num_msdus,
+					 status, msg_word);
+		HTT_TX_SCHED(pdev);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_RX_PN_IND:
+	{
+		uint16_t peer_id;
+		uint8_t tid, pn_ie_cnt, *pn_ie = NULL;
+		uint16_t seq_num_start, seq_num_end;
+
+		/*First dword */
+		peer_id = HTT_RX_PN_IND_PEER_ID_GET(*msg_word);
+		tid = HTT_RX_PN_IND_EXT_TID_GET(*msg_word);
+
+		msg_word++;
+		/*Second dword */
+		seq_num_start =
+			HTT_RX_PN_IND_SEQ_NUM_START_GET(*msg_word);
+		seq_num_end = HTT_RX_PN_IND_SEQ_NUM_END_GET(*msg_word);
+		pn_ie_cnt = HTT_RX_PN_IND_PN_IE_CNT_GET(*msg_word);
+
+		msg_word++;
+		/*Third dword */
+		if (pn_ie_cnt)
+			pn_ie = (uint8_t *) msg_word;
+
+		ol_rx_pn_ind_handler(pdev->txrx_pdev, peer_id, tid,
+				     seq_num_start, seq_num_end,
+				     pn_ie_cnt, pn_ie);
+
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_TX_INSPECT_IND:
+	{
+		int num_msdus;
+		int msg_len = qdf_nbuf_len(htt_t2h_msg);
+
+		num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word);
+		/*
+		 * each desc id will occupy 2 bytes.
+		 * the 4 is for htt msg header
+		 */
+		if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID +
+			HTT_TX_COMPL_HEAD_SZ) > msg_len) {
+			qdf_print("%s: num_msdus(%d) is invalid,"
+				"adf_nbuf_len = %d\n",
+				__FUNCTION__,
+				num_msdus,
+				msg_len);
+			break;
+		}
+
+		if (num_msdus & 0x1) {
+			struct htt_tx_compl_ind_base *compl =
+				(void *)msg_word;
+
+			/*
+			 * Host CPU endianness can be different from FW CPU.
+			 * This can result in even and odd MSDU IDs being
+			 * switched. If this happens, copy the switched final
+			 * odd MSDU ID from location payload[size], to
+			 * location payload[size-1], where the message handler
+			 * function expects to find it
+			 */
+			if (compl->payload[num_msdus] !=
+			    HTT_TX_COMPL_INV_MSDU_ID) {
+				compl->payload[num_msdus - 1] =
+					compl->payload[num_msdus];
+			}
+		}
+		ol_tx_inspect_handler(pdev->txrx_pdev, num_msdus,
+				      msg_word + 1);
+		HTT_TX_SCHED(pdev);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND:
+	{
+		uint16_t peer_id;
+		uint8_t tid;
+		uint8_t offload_ind, frag_ind;
+
+		if (qdf_unlikely(!pdev->cfg.is_full_reorder_offload)) {
+			qdf_print("HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND not ");
+			qdf_print("supported when full reorder offload is ");
+			qdf_print("disabled in the configuration.\n");
+			break;
+		}
+
+		if (qdf_unlikely(pdev->cfg.is_high_latency)) {
+			qdf_print("HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND ");
+			qdf_print("not supported on high latency.\n");
+			break;
+		}
+
+		peer_id = HTT_RX_IN_ORD_PADDR_IND_PEER_ID_GET(*msg_word);
+		tid = HTT_RX_IN_ORD_PADDR_IND_EXT_TID_GET(*msg_word);
+		offload_ind = HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_GET(*msg_word);
+		frag_ind = HTT_RX_IN_ORD_PADDR_IND_FRAG_GET(*msg_word);
+
+#if defined(HELIUMPLUS_DEBUG)
+		qdf_print("%s %d: peerid %d tid %d offloadind %d fragind %d\n",
+			  __func__, __LINE__, peer_id, tid, offload_ind,
+			  frag_ind);
+#endif
+		if (qdf_unlikely(frag_ind)) {
+			ol_rx_frag_indication_handler(pdev->txrx_pdev,
+						      htt_t2h_msg,
+						      peer_id, tid);
+			break;
+		}
+
+		ol_rx_in_order_indication_handler(pdev->txrx_pdev,
+						  htt_t2h_msg, peer_id,
+						  tid, offload_ind);
+		break;
+	}
+
+	default:
+		htt_t2h_lp_msg_handler(context, htt_t2h_msg, true);
+		return;
+
+	};
+
+	/* Free the indication buffer */
+	qdf_nbuf_free(htt_t2h_msg);
+}
+
+#ifdef WLAN_FEATURE_FASTPATH
+#define HTT_T2H_MSG_BUF_REINIT(_buf, dev)				\
+	do {								\
+		QDF_NBUF_CB_PADDR(_buf) -= (HTC_HEADER_LEN +		\
+					HTC_HDR_ALIGNMENT_PADDING);	\
+		qdf_nbuf_init_fast((_buf));				\
+		qdf_mem_dma_sync_single_for_device(dev,			\
+					(QDF_NBUF_CB_PADDR(_buf)),	\
+					(skb_end_pointer(_buf) -	\
+					(_buf)->data),			\
+					PCI_DMA_FROMDEVICE);		\
+	} while (0)
+
+/**
+ * htt_t2h_msg_handler_fast() -  Fastpath specific message handler
+ * @context: HTT context
+ * @cmpl_msdus: netbuf completions
+ * @num_cmpls: number of completions to be handled
+ *
+ * Return: None
+ */
+void htt_t2h_msg_handler_fast(void *context, qdf_nbuf_t *cmpl_msdus,
+			      uint32_t num_cmpls)
+{
+	struct htt_pdev_t *pdev = (struct htt_pdev_t *)context;
+	qdf_nbuf_t htt_t2h_msg;
+	uint32_t *msg_word;
+	uint32_t i;
+	enum htt_t2h_msg_type msg_type;
+	uint32_t msg_len;
+
+	for (i = 0; i < num_cmpls; i++) {
+		htt_t2h_msg = cmpl_msdus[i];
+		msg_len = qdf_nbuf_len(htt_t2h_msg);
+
+		/*
+		 * Move the data pointer to point to HTT header
+		 * past the HTC header + HTC header alignment padding
+		 */
+		qdf_nbuf_pull_head(htt_t2h_msg, HTC_HEADER_LEN +
+				   HTC_HDR_ALIGNMENT_PADDING);
+
+		/* confirm alignment */
+		HTT_ASSERT3((((unsigned long) qdf_nbuf_data(htt_t2h_msg)) & 0x3)
+			    == 0);
+
+		msg_word = (u_int32_t *) qdf_nbuf_data(htt_t2h_msg);
+		msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word);
+
+		switch (msg_type) {
+		case HTT_T2H_MSG_TYPE_RX_IND:
+		{
+			unsigned int num_mpdu_ranges;
+			unsigned int num_msdu_bytes;
+			unsigned int calculated_msg_len;
+			unsigned int rx_mpdu_range_offset_bytes;
+			u_int16_t peer_id;
+			u_int8_t tid;
+			msg_len = qdf_nbuf_len(htt_t2h_msg);
+
+			peer_id = HTT_RX_IND_PEER_ID_GET(*msg_word);
+			tid = HTT_RX_IND_EXT_TID_GET(*msg_word);
+			if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+				qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid tid %d\n",
+					tid);
+				WARN_ON(1);
+				break;
+			}
+			num_msdu_bytes =
+				HTT_RX_IND_FW_RX_DESC_BYTES_GET(
+				*(msg_word + 2 +
+				  HTT_RX_PPDU_DESC_SIZE32));
+			/*
+			 * 1 word for the message header,
+			 * HTT_RX_PPDU_DESC_SIZE32 words for the FW
+			 * rx PPDU desc.
+			 * 1 word to specify the number of MSDU bytes,
+			 * 1 word for every 4 MSDU bytes (round up),
+			 * 1 word for the MPDU range header
+			 */
+			rx_mpdu_range_offset_bytes =
+				(HTT_RX_IND_HDR_BYTES + num_msdu_bytes + 3);
+			if (qdf_unlikely(num_msdu_bytes >
+					 rx_mpdu_range_offset_bytes)) {
+				qdf_print("HTT_T2H_MSG_TYPE_RX_IND, %s %u\n",
+					  "invalid num_msdu_bytes",
+					  num_msdu_bytes);
+				WARN_ON(1);
+				break;
+			}
+			pdev->rx_mpdu_range_offset_words =
+				rx_mpdu_range_offset_bytes >> 2;
+			num_mpdu_ranges =
+				HTT_RX_IND_NUM_MPDU_RANGES_GET(*(msg_word
+								 + 1));
+			pdev->rx_ind_msdu_byte_idx = 0;
+			if (qdf_unlikely(rx_mpdu_range_offset_bytes >
+					 msg_len)) {
+				qdf_print("HTT_T2H_MSG_TYPE_RX_IND, %s %d\n",
+					  "invalid rx_mpdu_range_offset_words",
+					  pdev->rx_mpdu_range_offset_words);
+				WARN_ON(1);
+				break;
+			}
+			calculated_msg_len = rx_mpdu_range_offset_bytes +
+					     (num_mpdu_ranges *
+					     (int)sizeof(uint32_t));
+			/*
+			 * Check that the addition and multiplication
+			 * do not cause integer overflow
+			 */
+			if (qdf_unlikely(calculated_msg_len <
+					 rx_mpdu_range_offset_bytes)) {
+				qdf_print("HTT_T2H_MSG_TYPE_RX_IND, %s %u\n",
+					  "invalid num_mpdu_ranges",
+					  (num_mpdu_ranges *
+					   (int)sizeof(uint32_t)));
+				WARN_ON(1);
+				break;
+			}
+			if (qdf_unlikely(calculated_msg_len > msg_len)) {
+				qdf_print("HTT_T2H_MSG_TYPE_RX_IND, %s %u\n",
+					  "invalid offset_words + mpdu_ranges",
+					  calculated_msg_len);
+				WARN_ON(1);
+				break;
+			}
+			ol_rx_indication_handler(pdev->txrx_pdev, htt_t2h_msg,
+						 peer_id, tid, num_mpdu_ranges);
+			break;
+		}
+		case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
+		{
+			int num_msdus;
+			enum htt_tx_status status;
+
+			/* status - no enum translation needed */
+			status = HTT_TX_COMPL_IND_STATUS_GET(*msg_word);
+			num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word);
+
+			/*
+			 * each desc id will occupy 2 bytes.
+			 * the 4 is for htt msg header
+			 */
+			if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID +
+				HTT_TX_COMPL_HEAD_SZ) > msg_len) {
+				qdf_print("%s: num_msdus(%d) is invalid,"
+					"adf_nbuf_len = %d\n",
+					__FUNCTION__,
+					num_msdus,
+					msg_len);
+				break;
+			}
+
+			if (num_msdus & 0x1) {
+				struct htt_tx_compl_ind_base *compl =
+					(void *)msg_word;
+
+				/*
+				 * Host CPU endianness can be different
+				 * from FW CPU. This can result in even
+				 * and odd MSDU IDs being switched. If
+				 * this happens, copy the switched final
+				 * odd MSDU ID from location
+				 * payload[size], to location
+				 * payload[size-1],where the message
+				 * handler function expects to find it
+				 */
+				if (compl->payload[num_msdus] !=
+				    HTT_TX_COMPL_INV_MSDU_ID) {
+					compl->payload[num_msdus - 1] =
+						compl->payload[num_msdus];
+				}
+			}
+			ol_tx_completion_handler(pdev->txrx_pdev, num_msdus,
+						 status, msg_word);
+
+			break;
+		}
+		case HTT_T2H_MSG_TYPE_RX_PN_IND:
+		{
+			u_int16_t peer_id;
+			u_int8_t tid, pn_ie_cnt, *pn_ie = NULL;
+			int seq_num_start, seq_num_end;
+
+			/*First dword */
+			peer_id = HTT_RX_PN_IND_PEER_ID_GET(*msg_word);
+			tid = HTT_RX_PN_IND_EXT_TID_GET(*msg_word);
+
+			msg_word++;
+			/*Second dword */
+			seq_num_start =
+				HTT_RX_PN_IND_SEQ_NUM_START_GET(*msg_word);
+			seq_num_end =
+				HTT_RX_PN_IND_SEQ_NUM_END_GET(*msg_word);
+			pn_ie_cnt =
+				HTT_RX_PN_IND_PN_IE_CNT_GET(*msg_word);
+
+			msg_word++;
+			/*Third dword*/
+			if (pn_ie_cnt)
+				pn_ie = (u_int8_t *)msg_word;
+
+			ol_rx_pn_ind_handler(pdev->txrx_pdev, peer_id, tid,
+				seq_num_start, seq_num_end, pn_ie_cnt, pn_ie);
+
+			break;
+		}
+		case HTT_T2H_MSG_TYPE_TX_INSPECT_IND:
+		{
+			int num_msdus;
+
+			num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word);
+			/*
+			 * each desc id will occupy 2 bytes.
+			 * the 4 is for htt msg header
+			 */
+			if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID +
+				HTT_TX_COMPL_HEAD_SZ) > msg_len) {
+				qdf_print("%s: num_msdus(%d) is invalid,"
+					"adf_nbuf_len = %d\n",
+					__FUNCTION__,
+					num_msdus,
+					msg_len);
+				break;
+			}
+
+			if (num_msdus & 0x1) {
+				struct htt_tx_compl_ind_base *compl =
+					(void *)msg_word;
+
+				/*
+				 * Host CPU endianness can be different
+				 * from FW CPU. This * can result in
+				 * even and odd MSDU IDs being switched.
+				 * If this happens, copy the switched
+				 * final odd MSDU ID from location
+				 * payload[size], to location
+				 * payload[size-1], where the message
+				 * handler function expects to find it
+				 */
+				if (compl->payload[num_msdus] !=
+				    HTT_TX_COMPL_INV_MSDU_ID) {
+					compl->payload[num_msdus - 1] =
+					compl->payload[num_msdus];
+				}
+			}
+			ol_tx_inspect_handler(pdev->txrx_pdev,
+					      num_msdus, msg_word + 1);
+			break;
+		}
+		case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND:
+		{
+			u_int16_t peer_id;
+			u_int8_t tid;
+			u_int8_t offload_ind, frag_ind;
+
+			if (qdf_unlikely(
+				  !pdev->cfg.is_full_reorder_offload)) {
+				qdf_print("HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND not supported when full reorder offload is disabled\n");
+				break;
+			}
+
+			if (qdf_unlikely(
+				pdev->txrx_pdev->cfg.is_high_latency)) {
+				qdf_print("HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND not supported on high latency\n");
+				break;
+			}
+
+			peer_id = HTT_RX_IN_ORD_PADDR_IND_PEER_ID_GET(
+							*msg_word);
+			tid = HTT_RX_IN_ORD_PADDR_IND_EXT_TID_GET(
+							*msg_word);
+			offload_ind =
+				HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_GET(
+							*msg_word);
+			frag_ind = HTT_RX_IN_ORD_PADDR_IND_FRAG_GET(
+							*msg_word);
+
+			if (qdf_unlikely(frag_ind)) {
+				ol_rx_frag_indication_handler(
+				pdev->txrx_pdev, htt_t2h_msg, peer_id,
+				tid);
+				break;
+			}
+
+			ol_rx_in_order_indication_handler(
+					pdev->txrx_pdev, htt_t2h_msg,
+					peer_id, tid, offload_ind);
+			break;
+		}
+		default:
+			htt_t2h_lp_msg_handler(context, htt_t2h_msg, false);
+			break;
+		};
+
+		/* Re-initialize the indication buffer */
+		HTT_T2H_MSG_BUF_REINIT(htt_t2h_msg, pdev->osdev);
+		qdf_nbuf_set_pktlen(htt_t2h_msg, 0);
+	}
+}
+#endif /* WLAN_FEATURE_FASTPATH */
+
+/*--- target->host HTT message Info Element access methods ------------------*/
+
+/*--- tx completion message ---*/
+
+uint16_t htt_tx_compl_desc_id(void *iterator, int num)
+{
+	/*
+	 * The MSDU IDs are packed , 2 per 32-bit word.
+	 * Iterate on them as an array of 16-bit elements.
+	 * This will work fine if the host endianness matches
+	 * the target endianness.
+	 * If the host endianness is opposite of the target's,
+	 * this iterator will produce descriptor IDs in a different
+	 * order than the target inserted them into the message -
+	 * if the target puts in [0, 1, 2, 3, ...] the host will
+	 * put out [1, 0, 3, 2, ...].
+	 * This is fine, except for the last ID if there are an
+	 * odd number of IDs.  But the TX_COMPL_IND handling code
+	 * in the htt_t2h_msg_handler already added a duplicate
+	 * of the final ID, if there were an odd number of IDs,
+	 * so this function can safely treat the IDs as an array
+	 * of 16-bit elements.
+	 */
+	return *(((uint16_t *) iterator) + num);
+}
+
+/*--- rx indication message ---*/
+
+int htt_rx_ind_flush(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
+{
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *) qdf_nbuf_data(rx_ind_msg);
+	return HTT_RX_IND_FLUSH_VALID_GET(*msg_word);
+}
+
+void
+htt_rx_ind_flush_seq_num_range(htt_pdev_handle pdev,
+			       qdf_nbuf_t rx_ind_msg,
+			       unsigned int *seq_num_start,
+			       unsigned int *seq_num_end)
+{
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *) qdf_nbuf_data(rx_ind_msg);
+	msg_word++;
+	*seq_num_start = HTT_RX_IND_FLUSH_SEQ_NUM_START_GET(*msg_word);
+	*seq_num_end = HTT_RX_IND_FLUSH_SEQ_NUM_END_GET(*msg_word);
+}
+
+int htt_rx_ind_release(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
+{
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *) qdf_nbuf_data(rx_ind_msg);
+	return HTT_RX_IND_REL_VALID_GET(*msg_word);
+}
+
+void
+htt_rx_ind_release_seq_num_range(htt_pdev_handle pdev,
+				 qdf_nbuf_t rx_ind_msg,
+				 unsigned int *seq_num_start,
+				 unsigned int *seq_num_end)
+{
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *) qdf_nbuf_data(rx_ind_msg);
+	msg_word++;
+	*seq_num_start = HTT_RX_IND_REL_SEQ_NUM_START_GET(*msg_word);
+	*seq_num_end = HTT_RX_IND_REL_SEQ_NUM_END_GET(*msg_word);
+}
+
+void
+htt_rx_ind_mpdu_range_info(struct htt_pdev_t *pdev,
+			   qdf_nbuf_t rx_ind_msg,
+			   int mpdu_range_num,
+			   enum htt_rx_status *status, int *mpdu_count)
+{
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *) qdf_nbuf_data(rx_ind_msg);
+	msg_word += pdev->rx_mpdu_range_offset_words + mpdu_range_num;
+	*status = HTT_RX_IND_MPDU_STATUS_GET(*msg_word);
+	*mpdu_count = HTT_RX_IND_MPDU_COUNT_GET(*msg_word);
+}
+
+/**
+ * htt_rx_ind_rssi_dbm() - Return the RSSI provided in a rx indication message.
+ *
+ * @pdev:       the HTT instance the rx data was received on
+ * @rx_ind_msg: the netbuf containing the rx indication message
+ *
+ * Return the RSSI from an rx indication message, in dBm units.
+ *
+ * Return: RSSI in dBm, or HTT_INVALID_RSSI
+ */
+int16_t htt_rx_ind_rssi_dbm(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
+{
+	int8_t rssi;
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *)
+		   (qdf_nbuf_data(rx_ind_msg) +
+		    HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET);
+
+	/* check if the RX_IND message contains valid rx PPDU start info */
+	if (!HTT_RX_IND_START_VALID_GET(*msg_word))
+		return HTT_RSSI_INVALID;
+
+	rssi = HTT_RX_IND_RSSI_CMB_GET(*msg_word);
+	return (HTT_TGT_RSSI_INVALID == rssi) ?
+	       HTT_RSSI_INVALID : rssi;
+}
+
+/**
+ * htt_rx_ind_rssi_dbm_chain() - Return the RSSI for a chain provided in a rx
+ *              indication message.
+ * @pdev:       the HTT instance the rx data was received on
+ * @rx_ind_msg: the netbuf containing the rx indication message
+ * @chain:      the index of the chain (0-4)
+ *
+ * Return the RSSI for a chain from an rx indication message, in dBm units.
+ *
+ * Return: RSSI, or HTT_INVALID_RSSI
+ */
+int16_t
+htt_rx_ind_rssi_dbm_chain(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg,
+		      int8_t chain)
+{
+	int8_t rssi;
+	uint32_t *msg_word;
+
+	if (chain < 0 || chain > 3)
+		return HTT_RSSI_INVALID;
+
+	msg_word = (uint32_t *)
+		(qdf_nbuf_data(rx_ind_msg) +
+		 HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET);
+
+	/* check if the RX_IND message contains valid rx PPDU start info */
+	if (!HTT_RX_IND_START_VALID_GET(*msg_word))
+		return HTT_RSSI_INVALID;
+
+	msg_word += 1 + chain;
+
+	rssi = HTT_RX_IND_RSSI_PRI20_GET(*msg_word);
+	return (HTT_TGT_RSSI_INVALID == rssi) ?
+		HTT_RSSI_INVALID :
+		rssi;
+}
+
+/**
+ * htt_rx_ind_legacy_rate() - Return the data rate
+ * @pdev:        the HTT instance the rx data was received on
+ * @rx_ind_msg:  the netbuf containing the rx indication message
+ * @legacy_rate: (output) the data rate
+ *      The legacy_rate parameter's value depends on the
+ *      legacy_rate_sel value.
+ *      If legacy_rate_sel is 0:
+ *              0x8: OFDM 48 Mbps
+ *              0x9: OFDM 24 Mbps
+ *              0xA: OFDM 12 Mbps
+ *              0xB: OFDM 6 Mbps
+ *              0xC: OFDM 54 Mbps
+ *              0xD: OFDM 36 Mbps
+ *              0xE: OFDM 18 Mbps
+ *              0xF: OFDM 9 Mbps
+ *      If legacy_rate_sel is 1:
+ *              0x8: CCK 11 Mbps long preamble
+ *              0x9: CCK 5.5 Mbps long preamble
+ *              0xA: CCK 2 Mbps long preamble
+ *              0xB: CCK 1 Mbps long preamble
+ *              0xC: CCK 11 Mbps short preamble
+ *              0xD: CCK 5.5 Mbps short preamble
+ *              0xE: CCK 2 Mbps short preamble
+ *      -1 on error.
+ * @legacy_rate_sel: (output) 0 to indicate OFDM, 1 to indicate CCK.
+ *      -1 on error.
+ *
+ * Return the data rate provided in a rx indication message.
+ */
+void
+htt_rx_ind_legacy_rate(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg,
+		       uint8_t *legacy_rate, uint8_t *legacy_rate_sel)
+{
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *)
+		(qdf_nbuf_data(rx_ind_msg) +
+		 HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET);
+
+	/* check if the RX_IND message contains valid rx PPDU start info */
+	if (!HTT_RX_IND_START_VALID_GET(*msg_word)) {
+		*legacy_rate = -1;
+		*legacy_rate_sel = -1;
+		return;
+	}
+
+	*legacy_rate = HTT_RX_IND_LEGACY_RATE_GET(*msg_word);
+	*legacy_rate_sel = HTT_RX_IND_LEGACY_RATE_SEL_GET(*msg_word);
+}
+
+/**
+ * htt_rx_ind_timestamp() - Return the timestamp
+ * @pdev:                  the HTT instance the rx data was received on
+ * @rx_ind_msg:            the netbuf containing the rx indication message
+ * @timestamp_microsec:    (output) the timestamp to microsecond resolution.
+ *                         -1 on error.
+ * @timestamp_submicrosec: the submicrosecond portion of the
+ *                         timestamp. -1 on error.
+ *
+ * Return the timestamp provided in a rx indication message.
+ */
+void
+htt_rx_ind_timestamp(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg,
+		     uint32_t *timestamp_microsec,
+		     uint8_t *timestamp_submicrosec)
+{
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *)
+		(qdf_nbuf_data(rx_ind_msg) +
+		 HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET);
+
+	/* check if the RX_IND message contains valid rx PPDU start info */
+	if (!HTT_RX_IND_END_VALID_GET(*msg_word)) {
+		*timestamp_microsec = -1;
+		*timestamp_submicrosec = -1;
+		return;
+	}
+
+	*timestamp_microsec = *(msg_word + 6);
+	*timestamp_submicrosec =
+		HTT_RX_IND_TIMESTAMP_SUBMICROSEC_GET(*msg_word);
+}
+
+#define INVALID_TSF -1
+/**
+ * htt_rx_ind_tsf32() - Return the TSF timestamp
+ * @pdev:       the HTT instance the rx data was received on
+ * @rx_ind_msg: the netbuf containing the rx indication message
+ *
+ * Return the TSF timestamp provided in a rx indication message.
+ *
+ * Return: TSF timestamp
+ */
+uint32_t
+htt_rx_ind_tsf32(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
+{
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *)
+		(qdf_nbuf_data(rx_ind_msg) +
+		 HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET);
+
+	/* check if the RX_IND message contains valid rx PPDU start info */
+	if (!HTT_RX_IND_END_VALID_GET(*msg_word))
+		return INVALID_TSF;
+
+	return *(msg_word + 5);
+}
+
+/**
+ * htt_rx_ind_ext_tid() - Return the extended traffic ID provided in a rx
+ *			  indication message.
+ * @pdev:       the HTT instance the rx data was received on
+ * @rx_ind_msg: the netbuf containing the rx indication message
+ *
+ * Return the extended traffic ID in a rx indication message.
+ *
+ * Return: Extended TID
+ */
+uint8_t
+htt_rx_ind_ext_tid(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
+{
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *)
+		(qdf_nbuf_data(rx_ind_msg));
+
+	return HTT_RX_IND_EXT_TID_GET(*msg_word);
+}
+
+/*--- stats confirmation message ---*/
+
+void
+htt_t2h_dbg_stats_hdr_parse(uint8_t *stats_info_list,
+			    enum htt_dbg_stats_type *type,
+			    enum htt_dbg_stats_status *status,
+			    int *length, uint8_t **stats_data)
+{
+	uint32_t *msg_word = (uint32_t *) stats_info_list;
+	*type = HTT_T2H_STATS_CONF_TLV_TYPE_GET(*msg_word);
+	*status = HTT_T2H_STATS_CONF_TLV_STATUS_GET(*msg_word);
+	*length = HTT_T2H_STATS_CONF_TLV_HDR_SIZE +     /* header length */
+		HTT_T2H_STATS_CONF_TLV_LENGTH_GET(*msg_word); /* data len */
+	*stats_data = stats_info_list + HTT_T2H_STATS_CONF_TLV_HDR_SIZE;
+}
+
+void
+htt_rx_frag_ind_flush_seq_num_range(htt_pdev_handle pdev,
+				    qdf_nbuf_t rx_frag_ind_msg,
+				    uint16_t *seq_num_start, uint16_t *seq_num_end)
+{
+	uint32_t *msg_word;
+
+	msg_word = (uint32_t *) qdf_nbuf_data(rx_frag_ind_msg);
+	msg_word++;
+	*seq_num_start = HTT_RX_FRAG_IND_FLUSH_SEQ_NUM_START_GET(*msg_word);
+	*seq_num_end = HTT_RX_FRAG_IND_FLUSH_SEQ_NUM_END_GET(*msg_word);
+}
diff --git a/core/dp/htt/htt_tx.c b/core/dp/htt/htt_tx.c
new file mode 100644
index 0000000..6500877
--- /dev/null
+++ b/core/dp/htt/htt_tx.c
@@ -0,0 +1,1953 @@
+/*
+ * Copyright (c) 2011, 2014-2018 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.
+ */
+
+/**
+ * @file htt_tx.c
+ * @brief Implement transmit aspects of HTT.
+ * @details
+ *  This file contains three categories of HTT tx code:
+ *  1.  An abstraction of the tx descriptor, to hide the
+ *      differences between the HL vs. LL tx descriptor.
+ *  2.  Functions for allocating and freeing HTT tx descriptors.
+ *  3.  The function that accepts a tx frame from txrx and sends the
+ *      tx frame to HTC.
+ */
+#include <osdep.h>              /* uint32_t, offsetof, etc. */
+#include <qdf_types.h>          /* qdf_dma_addr_t */
+#include <qdf_mem.h>         /* qdf_mem_alloc_consistent et al */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_time.h>           /* qdf_mdelay */
+
+#include <htt.h>                /* htt_tx_msdu_desc_t */
+#include <htc.h>                /* HTC_HDR_LENGTH */
+#include <htc_api.h>            /* htc_flush_surprise_remove */
+#include <ol_cfg.h>             /* ol_cfg_netbuf_frags_max, etc. */
+#include <ol_htt_tx_api.h>      /* HTT_TX_DESC_VADDR_OFFSET */
+#include <ol_txrx_htt_api.h>    /* ol_tx_msdu_id_storage */
+#include <ol_txrx_internal.h>
+#include <htt_internal.h>
+
+#include <cds_utils.h>
+
+/* IPA Micro controller TX data packet HTT Header Preset
+ * 31 | 30  29 | 28 | 27 | 26  22  | 21   16 | 15  13   | 12  8      | 7 0
+ ***----------------------------------------------------------------------------
+ * R  | CS  OL | R  | PP | ext TID | vdev ID | pkt type | pkt subtyp | msg type
+ * 0  | 0      | 0  |    | 0x1F    | 0       | 2        | 0          | 0x01
+ ***----------------------------------------------------------------------------
+ * pkt ID                                    | pkt length
+ ***----------------------------------------------------------------------------
+ *                                frag_desc_ptr
+ ***----------------------------------------------------------------------------
+ *                                   peer_id
+ ***----------------------------------------------------------------------------
+ */
+#define HTT_IPA_UC_OFFLOAD_TX_HEADER_DEFAULT 0x07C04001
+
+#ifdef QCA_WIFI_3_0
+#define IPA_UC_TX_BUF_FRAG_DESC_OFFSET 20
+#define IPA_UC_TX_BUF_FRAG_HDR_OFFSET  64
+#define IPA_UC_TX_BUF_TSO_HDR_SIZE     6
+#define IPA_UC_TX_BUF_PADDR_HI_MASK    0x0000001F
+#define IPA_UC_TX_BUF_PADDR_HI_OFFSET  32
+#else
+#define IPA_UC_TX_BUF_FRAG_DESC_OFFSET 16
+#define IPA_UC_TX_BUF_FRAG_HDR_OFFSET  32
+#endif /* QCA_WIFI_3_0 */
+
+#if HTT_PADDR64
+#define HTT_TX_DESC_FRAG_FIELD_HI_UPDATE(frag_filed_ptr)                       \
+do {                                                                           \
+	frag_filed_ptr++;                                                      \
+	/* frags_desc_ptr.hi */                                                \
+	*frag_filed_ptr = 0;                                                   \
+} while (0)
+#else
+#define HTT_TX_DESC_FRAG_FIELD_HI_UPDATE(frag_filed_ptr) {}
+#endif
+
+/*--- setup / tear-down functions -------------------------------------------*/
+
+static qdf_dma_addr_t htt_tx_get_paddr(htt_pdev_handle pdev,
+				char *target_vaddr);
+
+#ifdef HELIUMPLUS
+/**
+ * htt_tx_desc_get_size() - get tx descripotrs size
+ * @pdev:	htt device instance pointer
+ *
+ * This function will get HTT TX descriptor size and fragment descriptor size
+ *
+ * Return: None
+ */
+static void htt_tx_desc_get_size(struct htt_pdev_t *pdev)
+{
+	pdev->tx_descs.size = sizeof(struct htt_host_tx_desc_t);
+	if (HTT_WIFI_IP_VERSION(pdev->wifi_ip_ver.major, 0x2)) {
+		/*
+		 * sizeof MSDU_EXT/Fragmentation descriptor.
+		 */
+		pdev->frag_descs.size = sizeof(struct msdu_ext_desc_t);
+	} else {
+		/*
+		 * Add the fragmentation descriptor elements.
+		 * Add the most that the OS may deliver, plus one more
+		 * in case the txrx code adds a prefix fragment (for
+		 * TSO or audio interworking SNAP header)
+		 */
+		pdev->frag_descs.size =
+			(ol_cfg_netbuf_frags_max(pdev->ctrl_pdev)+1) * 8
+			+ 4;
+	}
+}
+
+/**
+ * htt_tx_frag_desc_field_update() - Update fragment descriptor field
+ * @pdev:	htt device instance pointer
+ * @fptr:	Fragment descriptor field pointer
+ * @index:	Descriptor index to find page and offset
+ * @desc_v_ptr:	descriptor virtual pointot to find offset
+ *
+ * This function will update fragment descriptor field with actual fragment
+ * descriptor stating physical pointer
+ *
+ * Return: None
+ */
+static void htt_tx_frag_desc_field_update(struct htt_pdev_t *pdev,
+		uint32_t *fptr, unsigned int index,
+		struct htt_tx_msdu_desc_t *desc_v_ptr)
+{
+	unsigned int target_page;
+	unsigned int offset;
+	struct qdf_mem_dma_page_t *dma_page;
+
+	target_page = index / pdev->frag_descs.desc_pages.num_element_per_page;
+	offset = index % pdev->frag_descs.desc_pages.num_element_per_page;
+	dma_page = &pdev->frag_descs.desc_pages.dma_pages[target_page];
+	*fptr = (uint32_t)(dma_page->page_p_addr +
+		offset * pdev->frag_descs.size);
+	HTT_TX_DESC_FRAG_FIELD_HI_UPDATE(fptr);
+}
+
+/**
+ * htt_tx_frag_desc_attach() - Attach fragment descriptor
+ * @pdev:		htt device instance pointer
+ * @desc_pool_elems:	Number of fragment descriptor
+ *
+ * This function will allocate fragment descriptor
+ *
+ * Return: 0 success
+ */
+static int htt_tx_frag_desc_attach(struct htt_pdev_t *pdev,
+	uint16_t desc_pool_elems)
+{
+	pdev->frag_descs.pool_elems = desc_pool_elems;
+	qdf_mem_multi_pages_alloc(pdev->osdev, &pdev->frag_descs.desc_pages,
+		pdev->frag_descs.size, desc_pool_elems,
+		qdf_get_dma_mem_context((&pdev->frag_descs), memctx), false);
+	if ((0 == pdev->frag_descs.desc_pages.num_pages) ||
+		(NULL == pdev->frag_descs.desc_pages.dma_pages)) {
+		ol_txrx_err("FRAG descriptor alloc fail");
+		return -ENOBUFS;
+	}
+	return 0;
+}
+
+/**
+ * htt_tx_frag_desc_detach() - Detach fragment descriptor
+ * @pdev:		htt device instance pointer
+ *
+ * This function will free fragment descriptor
+ *
+ * Return: None
+ */
+static void htt_tx_frag_desc_detach(struct htt_pdev_t *pdev)
+{
+	qdf_mem_multi_pages_free(pdev->osdev, &pdev->frag_descs.desc_pages,
+		qdf_get_dma_mem_context((&pdev->frag_descs), memctx), false);
+}
+
+/**
+ * htt_tx_frag_alloc() - Allocate single fragment descriptor from the pool
+ * @pdev:		htt device instance pointer
+ * @index:		Descriptor index
+ * @frag_paddr:	        Fragment descriptor physical address
+ * @frag_ptr:		Fragment descriptor virtual address
+ *
+ * This function will free fragment descriptor
+ *
+ * Return: None
+ */
+int htt_tx_frag_alloc(htt_pdev_handle pdev,
+	u_int16_t index, qdf_dma_addr_t *frag_paddr, void **frag_ptr)
+{
+	uint16_t frag_page_index;
+	uint16_t frag_elem_index;
+	struct qdf_mem_dma_page_t *dma_page;
+
+	/*
+	 * Index should never be 0, since its used by the hardware
+	 * to terminate the link.
+	 */
+	if (index >= pdev->tx_descs.pool_elems) {
+		*frag_ptr = NULL;
+		return 1;
+	}
+
+	frag_page_index = index /
+		pdev->frag_descs.desc_pages.num_element_per_page;
+	frag_elem_index = index %
+		pdev->frag_descs.desc_pages.num_element_per_page;
+	dma_page = &pdev->frag_descs.desc_pages.dma_pages[frag_page_index];
+
+	*frag_ptr = dma_page->page_v_addr_start +
+		frag_elem_index * pdev->frag_descs.size;
+	if (((char *)(*frag_ptr) < dma_page->page_v_addr_start) ||
+		((char *)(*frag_ptr) > dma_page->page_v_addr_end)) {
+		*frag_ptr = NULL;
+		return 1;
+	}
+
+	*frag_paddr = dma_page->page_p_addr +
+		frag_elem_index * pdev->frag_descs.size;
+	return 0;
+}
+#else
+
+/**
+ * htt_tx_desc_get_size() - get tx descripotrs size
+ * @pdev:	htt device instance pointer
+ *
+ * This function will get HTT TX descriptor size and fragment descriptor size
+ *
+ * Return: None
+ */
+static inline void htt_tx_desc_get_size(struct htt_pdev_t *pdev)
+{
+	if (pdev->cfg.is_high_latency) {
+		pdev->tx_descs.size = sizeof(struct htt_host_tx_desc_t);
+	} else {
+		/*
+		 * Start with the size of the base struct
+		 * that actually gets downloaded.
+		 *
+		 * Add the fragmentation descriptor elements.
+		 * Add the most that the OS may deliver, plus one more
+		 * in case the txrx code adds a prefix fragment (for
+		 * TSO or audio interworking SNAP header)
+		 */
+		pdev->tx_descs.size =
+		sizeof(struct htt_host_tx_desc_t)
+		+ (ol_cfg_netbuf_frags_max(pdev->ctrl_pdev) + 1) * 8
+		/* 2x uint32_t */
+		+ 4; /* uint32_t fragmentation list terminator */
+	}
+}
+
+#ifndef CONFIG_HL_SUPPORT
+
+/**
+ * htt_tx_frag_desc_field_update() - Update fragment descriptor field
+ * @pdev:	htt device instance pointer
+ * @fptr:	Fragment descriptor field pointer
+ * @index:	Descriptor index to find page and offset
+ * @desc_v_ptr:	descriptor virtual pointot to find offset
+ *
+ * This function will update fragment descriptor field with actual fragment
+ * descriptor stating physical pointer
+ *
+ * Return: None
+ */
+static void htt_tx_frag_desc_field_update(struct htt_pdev_t *pdev,
+		uint32_t *fptr, unsigned int index,
+		struct htt_tx_msdu_desc_t *desc_v_ptr)
+{
+	*fptr = (uint32_t)htt_tx_get_paddr(pdev, (char *)desc_v_ptr) +
+		HTT_TX_DESC_LEN;
+}
+#endif
+
+/**
+ * htt_tx_frag_desc_attach() - Attach fragment descriptor
+ * @pdev:	htt device instance pointer
+ * @desc_pool_elems:	Number of fragment descriptor
+ *
+ * This function will allocate fragment descriptor
+ *
+ * Return: 0 success
+ */
+static inline int htt_tx_frag_desc_attach(struct htt_pdev_t *pdev,
+	int desc_pool_elems)
+{
+	return 0;
+}
+
+/**
+ * htt_tx_frag_desc_detach() - Detach fragment descriptor
+ * @pdev:		htt device instance pointer
+ *
+ * This function will free fragment descriptor
+ *
+ * Return: None
+ */
+static void htt_tx_frag_desc_detach(struct htt_pdev_t *pdev) {}
+#endif /* HELIUMPLUS */
+
+#ifdef CONFIG_HL_SUPPORT
+
+/**
+ * htt_tx_attach() - Attach HTT device instance
+ * @pdev:		htt device instance pointer
+ * @desc_pool_elems:	Number of TX descriptors
+ *
+ * This function will allocate HTT TX resources
+ *
+ * Return: 0 Success
+ */
+int htt_tx_attach(struct htt_pdev_t *pdev, int desc_pool_elems)
+{
+	int i, i_int, pool_size;
+	uint32_t **p;
+	uint32_t num_link = 0;
+	uint16_t num_page, num_desc_per_page;
+	void **cacheable_pages = NULL;
+
+	htt_tx_desc_get_size(pdev);
+
+	/*
+	 * Make sure tx_descs.size is a multiple of 4-bytes.
+	 * It should be, but round up just to be sure.
+	 */
+	pdev->tx_descs.size = (pdev->tx_descs.size + 3) & (~0x3);
+
+	pdev->tx_descs.pool_elems = desc_pool_elems;
+	pdev->tx_descs.alloc_cnt = 0;
+	pool_size = pdev->tx_descs.pool_elems * pdev->tx_descs.size;
+	qdf_mem_multi_pages_alloc(pdev->osdev, &pdev->tx_descs.desc_pages,
+				  pdev->tx_descs.size,
+				  pdev->tx_descs.pool_elems,
+				  qdf_get_dma_mem_context((&pdev->tx_descs),
+							  memctx), true);
+	if ((0 == pdev->tx_descs.desc_pages.num_pages) ||
+	    (NULL == pdev->tx_descs.desc_pages.cacheable_pages)) {
+		ol_txrx_err("HTT desc alloc fail");
+		goto out_fail;
+	}
+	num_page = pdev->tx_descs.desc_pages.num_pages;
+	num_desc_per_page = pdev->tx_descs.desc_pages.num_element_per_page;
+
+	/* link tx descriptors into a freelist */
+	cacheable_pages = pdev->tx_descs.desc_pages.cacheable_pages;
+
+	pdev->tx_descs.freelist = (uint32_t *)cacheable_pages[0];
+	p = (uint32_t **)pdev->tx_descs.freelist;
+	for (i = 0; i < num_page; i++) {
+		for (i_int = 0; i_int < num_desc_per_page; i_int++) {
+			if (i_int == (num_desc_per_page - 1)) {
+				/*
+				 * Last element on this page,
+				 * should point next page
+				 */
+				if (!cacheable_pages[i + 1]) {
+					ol_txrx_err("over flow num link %d\n",
+						   num_link);
+					goto free_htt_desc;
+				}
+				*p = (uint32_t *)cacheable_pages[i + 1];
+			} else {
+				*p = (uint32_t *)
+					(((char *)p) + pdev->tx_descs.size);
+			}
+			num_link++;
+			p = (uint32_t **) *p;
+			/* Last link established exit */
+			if (num_link == (pdev->tx_descs.pool_elems - 1))
+				break;
+		}
+	}
+	*p = NULL;
+
+	if (htt_tx_frag_desc_attach(pdev, desc_pool_elems)) {
+		ol_txrx_err("HTT Frag descriptor alloc fail");
+		goto free_htt_desc;
+	}
+
+	/* success */
+	return 0;
+
+free_htt_desc:
+	qdf_mem_multi_pages_free(pdev->osdev, &pdev->tx_descs.desc_pages,
+				 qdf_get_dma_mem_context((&pdev->tx_descs),
+							 memctx), true);
+out_fail:
+	return -ENOBUFS;
+}
+
+void htt_tx_detach(struct htt_pdev_t *pdev)
+{
+	if (!pdev) {
+		qdf_print("htt tx detach invalid instance");
+		return;
+	}
+
+	htt_tx_frag_desc_detach(pdev);
+	qdf_mem_multi_pages_free(pdev->osdev, &pdev->tx_descs.desc_pages,
+				 qdf_get_dma_mem_context((&pdev->tx_descs),
+							 memctx), true);
+}
+
+/**
+ * htt_tx_set_frag_desc_addr() - set up the fragmentation descriptor address
+ * @pdev: pointer to the HTT instance making the allocation
+ * @htt_tx_desc: Host tx decriptor that does not include HTC hdr
+ * @index: index to alloc htt tx desc
+ *
+ *
+ * Return: None
+ */
+static inline void
+htt_tx_set_frag_desc_addr(struct htt_pdev_t *pdev,
+			  struct htt_tx_msdu_desc_t *htt_tx_desc,
+			  uint16_t index)
+{
+}
+
+/**
+ * htt_tx_desc_frags_table_set() - set up the descriptor and payload
+ *				   to correspondinf fragments
+ * @pdev: pointer to the HTT instance making the allocation
+ * @htt_tx_desc: Host tx decriptor that does not include HTC hdr
+ * @paddr: fragment physical address
+ * @frag_desc_paddr_lo: frag descriptor address
+ * @reset: reset
+ *
+ * Return: None
+ */
+void htt_tx_desc_frags_table_set(htt_pdev_handle pdev,
+				 void *desc,
+				 qdf_dma_addr_t paddr,
+				 qdf_dma_addr_t frag_desc_paddr,
+				 int reset)
+{
+	/* fragments table only applies to LL systems */
+}
+
+/**
+ * htt_tx_credit_update() - get the number of credits by which the amount of
+ *			    target credits needs to be updated
+ * @pdev: htt context
+ *
+ * Return: number of credits
+ */
+int htt_tx_credit_update(struct htt_pdev_t *pdev)
+{
+	int credit_delta;
+
+	credit_delta = QDF_MIN(qdf_atomic_read(
+			&pdev->htt_tx_credit.target_delta),
+			qdf_atomic_read(&pdev->htt_tx_credit.bus_delta));
+	if (credit_delta) {
+		qdf_atomic_add(-credit_delta,
+			       &pdev->htt_tx_credit.target_delta);
+		qdf_atomic_add(-credit_delta,
+			       &pdev->htt_tx_credit.bus_delta);
+	}
+	return credit_delta;
+}
+
+/**
+ * htt_tx_get_paddr() - get physical address for htt desc
+ *
+ * Get HTT descriptor physical address from virtual address
+ * Find page first and find offset
+ * Not required for HL systems
+ *
+ * Return: Physical address of descriptor
+ */
+static inline
+qdf_dma_addr_t htt_tx_get_paddr(htt_pdev_handle pdev,
+				char *target_vaddr)
+{
+	return 0;
+}
+
+
+#else
+
+int htt_tx_attach(struct htt_pdev_t *pdev, int desc_pool_elems)
+{
+	int i, i_int, pool_size;
+	uint32_t **p;
+	struct qdf_mem_dma_page_t *page_info;
+	uint32_t num_link = 0;
+	uint16_t num_page, num_desc_per_page;
+
+	htt_tx_desc_get_size(pdev);
+
+	/*
+	 * Make sure tx_descs.size is a multiple of 4-bytes.
+	 * It should be, but round up just to be sure.
+	 */
+	pdev->tx_descs.size = (pdev->tx_descs.size + 3) & (~0x3);
+
+	pdev->tx_descs.pool_elems = desc_pool_elems;
+	pdev->tx_descs.alloc_cnt = 0;
+	pool_size = pdev->tx_descs.pool_elems * pdev->tx_descs.size;
+	qdf_mem_multi_pages_alloc(pdev->osdev, &pdev->tx_descs.desc_pages,
+		pdev->tx_descs.size, pdev->tx_descs.pool_elems,
+		qdf_get_dma_mem_context((&pdev->tx_descs), memctx), false);
+	if ((0 == pdev->tx_descs.desc_pages.num_pages) ||
+		(NULL == pdev->tx_descs.desc_pages.dma_pages)) {
+		ol_txrx_err("HTT desc alloc fail");
+		goto out_fail;
+	}
+	num_page = pdev->tx_descs.desc_pages.num_pages;
+	num_desc_per_page = pdev->tx_descs.desc_pages.num_element_per_page;
+
+	/* link tx descriptors into a freelist */
+	page_info = pdev->tx_descs.desc_pages.dma_pages;
+	pdev->tx_descs.freelist = (uint32_t *)page_info->page_v_addr_start;
+	p = (uint32_t **) pdev->tx_descs.freelist;
+	for (i = 0; i < num_page; i++) {
+		for (i_int = 0; i_int < num_desc_per_page; i_int++) {
+			if (i_int == (num_desc_per_page - 1)) {
+				/*
+				 * Last element on this page,
+				 * should pint next page
+				 */
+				if (!page_info->page_v_addr_start) {
+					ol_txrx_err("over flow num link %d\n",
+						num_link);
+					goto free_htt_desc;
+				}
+				page_info++;
+				*p = (uint32_t *)page_info->page_v_addr_start;
+			} else {
+				*p = (uint32_t *)
+					(((char *) p) + pdev->tx_descs.size);
+			}
+			num_link++;
+			p = (uint32_t **) *p;
+			/* Last link established exit */
+			if (num_link == (pdev->tx_descs.pool_elems - 1))
+				break;
+		}
+	}
+	*p = NULL;
+
+	if (htt_tx_frag_desc_attach(pdev, desc_pool_elems)) {
+		ol_txrx_err("HTT Frag descriptor alloc fail");
+		goto free_htt_desc;
+	}
+
+	/* success */
+	return 0;
+
+free_htt_desc:
+	qdf_mem_multi_pages_free(pdev->osdev, &pdev->tx_descs.desc_pages,
+		qdf_get_dma_mem_context((&pdev->tx_descs), memctx), false);
+out_fail:
+	return -ENOBUFS;
+}
+
+void htt_tx_detach(struct htt_pdev_t *pdev)
+{
+	if (!pdev) {
+		qdf_print("htt tx detach invalid instance");
+		return;
+	}
+
+	htt_tx_frag_desc_detach(pdev);
+	qdf_mem_multi_pages_free(pdev->osdev, &pdev->tx_descs.desc_pages,
+		qdf_get_dma_mem_context((&pdev->tx_descs), memctx), false);
+}
+
+static void
+htt_tx_set_frag_desc_addr(struct htt_pdev_t *pdev,
+			  struct htt_tx_msdu_desc_t *htt_tx_desc,
+			  uint16_t index)
+{
+	uint32_t *fragmentation_descr_field_ptr;
+
+	fragmentation_descr_field_ptr = (uint32_t *)
+		((uint32_t *)htt_tx_desc) +
+		HTT_TX_DESC_FRAGS_DESC_PADDR_OFFSET_DWORD;
+	/*
+	 * The fragmentation descriptor is allocated from consistent
+	 * memory. Therefore, we can use the address directly rather
+	 * than having to map it from a virtual/CPU address to a
+	 * physical/bus address.
+	 */
+	htt_tx_frag_desc_field_update(pdev, fragmentation_descr_field_ptr,
+				      index, htt_tx_desc);
+
+		return;
+}
+
+void htt_tx_desc_frags_table_set(htt_pdev_handle pdev,
+				 void *htt_tx_desc,
+				 qdf_dma_addr_t paddr,
+				 qdf_dma_addr_t frag_desc_paddr,
+				 int reset)
+{
+	uint32_t *fragmentation_descr_field_ptr;
+
+	fragmentation_descr_field_ptr = (uint32_t *)
+		((uint32_t *) htt_tx_desc) +
+		HTT_TX_DESC_FRAGS_DESC_PADDR_OFFSET_DWORD;
+	if (reset) {
+#if defined(HELIUMPLUS)
+		*fragmentation_descr_field_ptr = frag_desc_paddr;
+#else
+		*fragmentation_descr_field_ptr =
+			htt_tx_get_paddr(pdev, htt_tx_desc) + HTT_TX_DESC_LEN;
+#endif
+	} else {
+		*fragmentation_descr_field_ptr = paddr;
+	}
+}
+
+void htt_tx_pending_discard(htt_pdev_handle pdev)
+{
+	htc_flush_surprise_remove(pdev->htc_pdev);
+}
+
+static qdf_dma_addr_t htt_tx_get_paddr(htt_pdev_handle pdev,
+				char *target_vaddr)
+{
+	uint16_t i;
+	struct qdf_mem_dma_page_t *page_info = NULL;
+	uint64_t offset;
+
+	for (i = 0; i < pdev->tx_descs.desc_pages.num_pages; i++) {
+		page_info = pdev->tx_descs.desc_pages.dma_pages + i;
+		if (!page_info->page_v_addr_start) {
+			qdf_assert(0);
+			return 0;
+		}
+		if ((target_vaddr >= page_info->page_v_addr_start) &&
+			(target_vaddr <= page_info->page_v_addr_end))
+			break;
+	}
+
+	if (!page_info) {
+		ol_txrx_err("invalid page_info");
+		return 0;
+	}
+
+	offset = (uint64_t)(target_vaddr - page_info->page_v_addr_start);
+	return page_info->page_p_addr + offset;
+}
+
+#endif
+
+/*--- descriptor allocation functions ---------------------------------------*/
+
+void *htt_tx_desc_alloc(htt_pdev_handle pdev, qdf_dma_addr_t *paddr,
+			uint16_t index)
+{
+	struct htt_host_tx_desc_t *htt_host_tx_desc;    /* includes HTC hdr */
+	struct htt_tx_msdu_desc_t *htt_tx_desc; /* doesn't include  HTC hdr */
+
+	htt_host_tx_desc = (struct htt_host_tx_desc_t *)pdev->tx_descs.freelist;
+	if (!htt_host_tx_desc)
+		return NULL;    /* pool is exhausted */
+
+	htt_tx_desc = &htt_host_tx_desc->align32.tx_desc;
+
+	if (pdev->tx_descs.freelist) {
+		pdev->tx_descs.freelist =
+			*((uint32_t **) pdev->tx_descs.freelist);
+		pdev->tx_descs.alloc_cnt++;
+	}
+	/*
+	 * For LL, set up the fragmentation descriptor address.
+	 * Currently, this HTT tx desc allocation is performed once up front.
+	 * If this is changed to have the allocation done during tx, then it
+	 * would be helpful to have separate htt_tx_desc_alloc functions for
+	 * HL vs. LL, to remove the below conditional branch.
+	 */
+	htt_tx_set_frag_desc_addr(pdev, htt_tx_desc, index);
+
+	/*
+	 * Include the headroom for the HTC frame header when specifying the
+	 * physical address for the HTT tx descriptor.
+	 */
+	*paddr = (qdf_dma_addr_t)htt_tx_get_paddr(pdev,
+						  (char *)htt_host_tx_desc);
+	/*
+	 * The allocated tx descriptor space includes headroom for a
+	 * HTC frame header.  Hide this headroom, so that we don't have
+	 * to jump past the headroom each time we program a field within
+	 * the tx desc, but only once when we download the tx desc (and
+	 * the headroom) to the target via HTC.
+	 * Skip past the headroom and return the address of the HTT tx desc.
+	 */
+	return (void *)htt_tx_desc;
+}
+
+void htt_tx_desc_free(htt_pdev_handle pdev, void *tx_desc)
+{
+	char *htt_host_tx_desc = tx_desc;
+	/* rewind over the HTC frame header space */
+	htt_host_tx_desc -=
+		offsetof(struct htt_host_tx_desc_t, align32.tx_desc);
+	*((uint32_t **) htt_host_tx_desc) = pdev->tx_descs.freelist;
+	pdev->tx_descs.freelist = (uint32_t *) htt_host_tx_desc;
+	pdev->tx_descs.alloc_cnt--;
+}
+
+/*--- descriptor field access methods ---------------------------------------*/
+
+/* PUT THESE AS inline IN ol_htt_tx_api.h */
+
+void htt_tx_desc_flag_postponed(htt_pdev_handle pdev, void *desc)
+{
+}
+
+void htt_tx_desc_flag_batch_more(htt_pdev_handle pdev, void *desc)
+{
+}
+
+/*--- tx send function ------------------------------------------------------*/
+
+#ifdef ATH_11AC_TXCOMPACT
+
+/*
+ * Scheduling the Queued packets in HTT which could not be sent out
+ * because of No CE desc
+ */
+void htt_tx_sched(htt_pdev_handle pdev)
+{
+	qdf_nbuf_t msdu;
+	int download_len = pdev->download_len;
+	int packet_len;
+
+	HTT_TX_NBUF_QUEUE_REMOVE(pdev, msdu);
+	while (msdu != NULL) {
+		int not_accepted;
+		/* packet length includes HTT tx desc frag added above */
+		packet_len = qdf_nbuf_len(msdu);
+		if (packet_len < download_len) {
+			/*
+			 * This case of packet length being less than the
+			 * nominal download length can happen for a couple
+			 * of reasons:
+			 * In HL, the nominal download length is a large
+			 * artificial value.
+			 * In LL, the frame may not have the optional header
+			 * fields accounted for in the nominal download size
+			 * (LLC/SNAP header, IPv4 or IPv6 header).
+			 */
+			download_len = packet_len;
+		}
+
+		not_accepted =
+			htc_send_data_pkt(pdev->htc_pdev, msdu,
+					  pdev->htc_tx_endpoint,
+					  download_len);
+		if (not_accepted) {
+			HTT_TX_NBUF_QUEUE_INSERT_HEAD(pdev, msdu);
+			return;
+		}
+		HTT_TX_NBUF_QUEUE_REMOVE(pdev, msdu);
+	}
+}
+
+int htt_tx_send_std(htt_pdev_handle pdev, qdf_nbuf_t msdu, uint16_t msdu_id)
+{
+
+	int download_len = pdev->download_len;
+
+	int packet_len;
+
+	/* packet length includes HTT tx desc frag added above */
+	packet_len = qdf_nbuf_len(msdu);
+	if (packet_len < download_len) {
+		/*
+		 * This case of packet length being less than the nominal
+		 * download length can happen for a couple of reasons:
+		 * In HL, the nominal download length is a large artificial
+		 * value.
+		 * In LL, the frame may not have the optional header fields
+		 * accounted for in the nominal download size (LLC/SNAP header,
+		 * IPv4 or IPv6 header).
+		 */
+		download_len = packet_len;
+	}
+
+	if (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_EXT_HEADER(msdu))
+		download_len += sizeof(struct htt_tx_msdu_desc_ext_t);
+
+
+	QDF_NBUF_UPDATE_TX_PKT_COUNT(msdu, QDF_NBUF_TX_PKT_HTT);
+	DPTRACE(qdf_dp_trace(msdu, QDF_DP_TRACE_HTT_PACKET_PTR_RECORD,
+				QDF_TRACE_DEFAULT_PDEV_ID,
+				qdf_nbuf_data_addr(msdu),
+				sizeof(qdf_nbuf_data(msdu)), QDF_TX));
+	if (qdf_nbuf_queue_len(&pdev->txnbufq) > 0) {
+		HTT_TX_NBUF_QUEUE_ADD(pdev, msdu);
+		htt_tx_sched(pdev);
+		return 0;
+	}
+
+	if (htc_send_data_pkt(pdev->htc_pdev, msdu,
+			      pdev->htc_tx_endpoint, download_len)) {
+		HTT_TX_NBUF_QUEUE_ADD(pdev, msdu);
+	}
+
+	return 0;               /* success */
+
+}
+
+#ifndef CONFIG_HL_SUPPORT
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * htt_tx_resume_handler() - resume callback for the htt endpoint
+ * @context: a pointer to the htt context
+ *
+ * runs htt_tx_sched.
+ */
+void htt_tx_resume_handler(void *context)
+{
+	struct htt_pdev_t *pdev =  (struct htt_pdev_t *) context;
+
+	htt_tx_sched(pdev);
+}
+#else
+void
+htt_tx_resume_handler(void *context) { }
+#endif
+#endif
+
+qdf_nbuf_t
+htt_tx_send_batch(htt_pdev_handle pdev, qdf_nbuf_t head_msdu, int num_msdus)
+{
+	qdf_print("*** %s currently only applies for HL systems\n", __func__);
+	qdf_assert(0);
+	return head_msdu;
+
+}
+
+int
+htt_tx_send_nonstd(htt_pdev_handle pdev,
+		   qdf_nbuf_t msdu,
+		   uint16_t msdu_id, enum htt_pkt_type pkt_type)
+{
+	int download_len;
+
+	/*
+	 * The pkt_type could be checked to see what L2 header type is present,
+	 * and then the L2 header could be examined to determine its length.
+	 * But for simplicity, just use the maximum possible header size,
+	 * rather than computing the actual header size.
+	 */
+	download_len = sizeof(struct htt_host_tx_desc_t)
+		+ HTT_TX_HDR_SIZE_OUTER_HDR_MAX /* worst case */
+		+ HTT_TX_HDR_SIZE_802_1Q
+		+ HTT_TX_HDR_SIZE_LLC_SNAP
+		+ ol_cfg_tx_download_size(pdev->ctrl_pdev);
+	qdf_assert(download_len <= pdev->download_len);
+	return htt_tx_send_std(pdev, msdu, msdu_id);
+}
+
+#else                           /*ATH_11AC_TXCOMPACT */
+
+#ifdef QCA_TX_HTT2_SUPPORT
+static inline HTC_ENDPOINT_ID
+htt_tx_htt2_get_ep_id(htt_pdev_handle pdev, qdf_nbuf_t msdu)
+{
+	/*
+	 * TX HTT2 service mainly for small sized frame and check if
+	 * this candidate frame allow or not.
+	 */
+	if ((pdev->htc_tx_htt2_endpoint != ENDPOINT_UNUSED) &&
+	    qdf_nbuf_get_tx_parallel_dnload_frm(msdu) &&
+	    (qdf_nbuf_len(msdu) < pdev->htc_tx_htt2_max_size))
+		return pdev->htc_tx_htt2_endpoint;
+	else
+		return pdev->htc_tx_endpoint;
+}
+#else
+#define htt_tx_htt2_get_ep_id(pdev, msdu)     (pdev->htc_tx_endpoint)
+#endif /* QCA_TX_HTT2_SUPPORT */
+
+static inline int
+htt_tx_send_base(htt_pdev_handle pdev,
+		 qdf_nbuf_t msdu,
+		 uint16_t msdu_id, int download_len, uint8_t more_data)
+{
+	struct htt_host_tx_desc_t *htt_host_tx_desc;
+	struct htt_htc_pkt *pkt;
+	int packet_len;
+	HTC_ENDPOINT_ID ep_id;
+
+	/*
+	 * The HTT tx descriptor was attached as the prefix fragment to the
+	 * msdu netbuf during the call to htt_tx_desc_init.
+	 * Retrieve it so we can provide its HTC header space to HTC.
+	 */
+	htt_host_tx_desc = (struct htt_host_tx_desc_t *)
+			   qdf_nbuf_get_frag_vaddr(msdu, 0);
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return -ENOBUFS;       /* failure */
+
+	pkt->msdu_id = msdu_id;
+	pkt->pdev_ctxt = pdev->txrx_pdev;
+
+	/* packet length includes HTT tx desc frag added above */
+	packet_len = qdf_nbuf_len(msdu);
+	if (packet_len < download_len) {
+		/*
+		 * This case of packet length being less than the nominal
+		 * download length can happen for a couple reasons:
+		 * In HL, the nominal download length is a large artificial
+		 * value.
+		 * In LL, the frame may not have the optional header fields
+		 * accounted for in the nominal download size (LLC/SNAP header,
+		 * IPv4 or IPv6 header).
+		 */
+		download_len = packet_len;
+	}
+
+	ep_id = htt_tx_htt2_get_ep_id(pdev, msdu);
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       pdev->tx_send_complete_part2,
+			       (unsigned char *)htt_host_tx_desc,
+			       download_len - HTC_HDR_LENGTH,
+			       ep_id,
+			       1); /* tag - not relevant here */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msdu);
+
+	QDF_NBUF_UPDATE_TX_PKT_COUNT(msdu, QDF_NBUF_TX_PKT_HTT);
+	DPTRACE(qdf_dp_trace(msdu, QDF_DP_TRACE_HTT_PACKET_PTR_RECORD,
+				QDF_TRACE_DEFAULT_PDEV_ID,
+				qdf_nbuf_data_addr(msdu),
+				sizeof(qdf_nbuf_data(msdu)), QDF_TX));
+	htc_send_data_pkt(pdev->htc_pdev, &pkt->htc_pkt, more_data);
+
+	return 0;               /* success */
+}
+
+qdf_nbuf_t
+htt_tx_send_batch(htt_pdev_handle pdev, qdf_nbuf_t head_msdu, int num_msdus)
+{
+	qdf_nbuf_t rejected = NULL;
+	uint16_t *msdu_id_storage;
+	uint16_t msdu_id;
+	qdf_nbuf_t msdu;
+
+	/*
+	 * FOR NOW, iterate through the batch, sending the frames singly.
+	 * Eventually HTC and HIF should be able to accept a batch of
+	 * data frames rather than singles.
+	 */
+	msdu = head_msdu;
+	while (num_msdus--) {
+		qdf_nbuf_t next_msdu = qdf_nbuf_next(msdu);
+
+		msdu_id_storage = ol_tx_msdu_id_storage(msdu);
+		msdu_id = *msdu_id_storage;
+
+		/* htt_tx_send_base returns 0 as success and 1 as failure */
+		if (htt_tx_send_base(pdev, msdu, msdu_id, pdev->download_len,
+				     num_msdus)) {
+			qdf_nbuf_set_next(msdu, rejected);
+			rejected = msdu;
+		}
+		msdu = next_msdu;
+	}
+	return rejected;
+}
+
+int
+htt_tx_send_nonstd(htt_pdev_handle pdev,
+		   qdf_nbuf_t msdu,
+		   uint16_t msdu_id, enum htt_pkt_type pkt_type)
+{
+	int download_len;
+
+	/*
+	 * The pkt_type could be checked to see what L2 header type is present,
+	 * and then the L2 header could be examined to determine its length.
+	 * But for simplicity, just use the maximum possible header size,
+	 * rather than computing the actual header size.
+	 */
+	download_len = sizeof(struct htt_host_tx_desc_t)
+		+ HTT_TX_HDR_SIZE_OUTER_HDR_MAX      /* worst case */
+		+ HTT_TX_HDR_SIZE_802_1Q
+		+ HTT_TX_HDR_SIZE_LLC_SNAP
+		+ ol_cfg_tx_download_size(pdev->ctrl_pdev);
+	return htt_tx_send_base(pdev, msdu, msdu_id, download_len, 0);
+}
+
+int htt_tx_send_std(htt_pdev_handle pdev, qdf_nbuf_t msdu, uint16_t msdu_id)
+{
+	return htt_tx_send_base(pdev, msdu, msdu_id, pdev->download_len, 0);
+}
+
+#endif /*ATH_11AC_TXCOMPACT */
+
+#if defined(HTT_DBG)
+void htt_tx_desc_display(void *tx_desc)
+{
+	struct htt_tx_msdu_desc_t *htt_tx_desc;
+
+	htt_tx_desc = (struct htt_tx_msdu_desc_t *)tx_desc;
+
+	/* only works for little-endian */
+	qdf_debug("HTT tx desc (@ %pK):", htt_tx_desc);
+	qdf_debug("  msg type = %d", htt_tx_desc->msg_type);
+	qdf_debug("  pkt subtype = %d", htt_tx_desc->pkt_subtype);
+	qdf_debug("  pkt type = %d", htt_tx_desc->pkt_type);
+	qdf_debug("  vdev ID = %d", htt_tx_desc->vdev_id);
+	qdf_debug("  ext TID = %d", htt_tx_desc->ext_tid);
+	qdf_debug("  postponed = %d", htt_tx_desc->postponed);
+	qdf_debug("  extension = %d", htt_tx_desc->extension);
+	qdf_debug("  cksum_offload = %d", htt_tx_desc->cksum_offload);
+	qdf_debug("  tx_compl_req= %d", htt_tx_desc->tx_compl_req);
+	qdf_debug("  length = %d", htt_tx_desc->len);
+	qdf_debug("  id = %d", htt_tx_desc->id);
+#if HTT_PADDR64
+	qdf_debug("  frag desc addr.lo = %#x",
+		  htt_tx_desc->frags_desc_ptr.lo);
+	qdf_debug("  frag desc addr.hi = %#x",
+		  htt_tx_desc->frags_desc_ptr.hi);
+#else /* ! HTT_PADDR64 */
+	qdf_debug("  frag desc addr = %#x", htt_tx_desc->frags_desc_ptr);
+#endif /* HTT_PADDR64 */
+	qdf_debug("  peerid = %d", htt_tx_desc->peerid);
+	qdf_debug("  chanfreq = %d", htt_tx_desc->chanfreq);
+}
+#endif
+
+#ifdef IPA_OFFLOAD
+#ifdef QCA_WIFI_3_0
+/**
+ * htt_tx_ipa_uc_wdi_tx_buf_alloc() - Alloc WDI TX buffers
+ * @pdev: htt context
+ * @uc_tx_buf_sz: TX buffer size
+ * @uc_tx_buf_cnt: TX Buffer count
+ * @uc_tx_partition_base: IPA UC TX partition base value
+ *
+ * Allocate WDI TX buffers. Also note Rome supports only WDI 1.0.
+ *
+ * Return: 0 success
+ */
+
+static int htt_tx_ipa_uc_wdi_tx_buf_alloc(struct htt_pdev_t *pdev,
+					  unsigned int uc_tx_buf_sz,
+					  unsigned int uc_tx_buf_cnt,
+					  unsigned int uc_tx_partition_base)
+{
+	unsigned int tx_buffer_count;
+	unsigned int  tx_buffer_count_pwr2;
+	qdf_dma_addr_t buffer_paddr;
+	uint32_t *header_ptr;
+	qdf_dma_addr_t *ring_vaddr;
+	uint16_t idx;
+	qdf_mem_info_t *mem_map_table = NULL, *mem_info = NULL;
+	qdf_shared_mem_t *shared_tx_buffer;
+
+	ring_vaddr = (qdf_dma_addr_t *)pdev->ipa_uc_tx_rsc.tx_comp_ring->vaddr;
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+		mem_map_table = qdf_mem_map_table_alloc(uc_tx_buf_cnt);
+		if (!mem_map_table) {
+			qdf_print("%s: Failed to allocate memory for mem map table\n",
+				  __func__);
+			return 0;
+		}
+		mem_info = mem_map_table;
+	}
+
+	/* Allocate TX buffers as many as possible */
+	for (tx_buffer_count = 0;
+	     tx_buffer_count < (uc_tx_buf_cnt - 1); tx_buffer_count++) {
+
+		shared_tx_buffer = qdf_mem_shared_mem_alloc(pdev->osdev,
+							    uc_tx_buf_sz);
+		if (!shared_tx_buffer || !shared_tx_buffer->vaddr) {
+			qdf_print("IPA WDI TX buffer alloc fail %d allocated\n",
+				tx_buffer_count);
+			goto pwr2;
+		}
+
+		header_ptr = shared_tx_buffer->vaddr;
+		buffer_paddr = qdf_mem_get_dma_addr(pdev->osdev,
+						&shared_tx_buffer->mem_info);
+
+		/* HTT control header */
+		*header_ptr = HTT_IPA_UC_OFFLOAD_TX_HEADER_DEFAULT;
+		header_ptr++;
+
+		/* PKT ID */
+		*header_ptr |= ((uint16_t) uc_tx_partition_base +
+				tx_buffer_count) << 16;
+
+		header_ptr++;
+
+		/* Frag Desc Pointer */
+		/* 64bits descriptor, Low 32bits */
+		*header_ptr = qdf_get_lower_32_bits(buffer_paddr +
+					IPA_UC_TX_BUF_FRAG_DESC_OFFSET);
+		header_ptr++;
+
+		/* 64bits descriptor, high 32bits */
+		*header_ptr = qdf_get_upper_32_bits(buffer_paddr) &
+			IPA_UC_TX_BUF_PADDR_HI_MASK;
+		header_ptr++;
+
+		/* chanreq, peerid */
+		*header_ptr = 0xFFFFFFFF;
+		header_ptr++;
+
+		/* FRAG Header */
+		/* 6 words TSO header */
+		header_ptr += IPA_UC_TX_BUF_TSO_HDR_SIZE;
+		*header_ptr = buffer_paddr + IPA_UC_TX_BUF_FRAG_HDR_OFFSET;
+
+		*ring_vaddr = buffer_paddr;
+		pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[tx_buffer_count] =
+			shared_tx_buffer;
+
+		/* Memory barrier to ensure actual value updated */
+
+		ring_vaddr++;
+		if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+			*mem_info = pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[
+						tx_buffer_count]->mem_info;
+			 mem_info++;
+		}
+	}
+
+pwr2:
+	/*
+	 * Tx complete ring buffer count should be power of 2.
+	 * So, allocated Tx buffer count should be one less than ring buffer
+	 * size.
+	 */
+	tx_buffer_count_pwr2 = qdf_rounddown_pow_of_two(tx_buffer_count + 1)
+			       - 1;
+	if (tx_buffer_count > tx_buffer_count_pwr2) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+			  "%s: Allocated Tx buffer count %d is rounded down to %d",
+			  __func__, tx_buffer_count, tx_buffer_count_pwr2);
+
+		/* Free over allocated buffers below power of 2 */
+		for (idx = tx_buffer_count_pwr2; idx < tx_buffer_count; idx++) {
+			if (pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[idx]) {
+				qdf_mem_shared_mem_free(pdev->osdev,
+					pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[
+								idx]);
+				 pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[idx] =
+									NULL;
+			}
+		}
+	}
+
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+		cds_smmu_map_unmap(true, tx_buffer_count_pwr2,
+				   mem_map_table);
+		qdf_mem_free(mem_map_table);
+	}
+
+	return tx_buffer_count_pwr2;
+}
+
+/**
+ * htt_tx_buf_pool_free() - Free tx buffer pool
+ * @pdev: htt context
+ *
+ * Free memory in tx buffer pool
+ *
+ * Return: 0 success
+ */
+static void htt_tx_buf_pool_free(struct htt_pdev_t *pdev)
+{
+	uint16_t idx;
+	qdf_mem_info_t *mem_map_table = NULL, *mem_info = NULL;
+	uint32_t num_unmapped = 0;
+
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+		mem_map_table = qdf_mem_map_table_alloc(
+					pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt);
+		if (!mem_map_table) {
+			qdf_print("%s: Failed to allocate memory for mem map table\n",
+				  __func__);
+			return;
+		}
+		mem_info = mem_map_table;
+	}
+
+	for (idx = 0; idx < pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt; idx++) {
+		if (pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[idx]) {
+			if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+				*mem_info = pdev->ipa_uc_tx_rsc.
+					      tx_buf_pool_strg[idx]->mem_info;
+				mem_info++;
+				num_unmapped++;
+			}
+			qdf_mem_shared_mem_free(pdev->osdev,
+						pdev->ipa_uc_tx_rsc.
+							tx_buf_pool_strg[idx]);
+			pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[idx] = NULL;
+		}
+	}
+
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+		if (num_unmapped)
+			cds_smmu_map_unmap(false, num_unmapped, mem_map_table);
+		qdf_mem_free(mem_map_table);
+	}
+}
+#else
+static int htt_tx_ipa_uc_wdi_tx_buf_alloc(struct htt_pdev_t *pdev,
+					  unsigned int uc_tx_buf_sz,
+					  unsigned int uc_tx_buf_cnt,
+					  unsigned int uc_tx_partition_base)
+{
+	unsigned int tx_buffer_count;
+	unsigned int  tx_buffer_count_pwr2;
+	qdf_dma_addr_t buffer_paddr;
+	uint32_t *header_ptr;
+	uint32_t *ring_vaddr;
+	uint16_t idx;
+	qdf_mem_info_t *mem_map_table = NULL, *mem_info = NULL;
+	qdf_shared_mem_t *shared_tx_buffer;
+
+	ring_vaddr = pdev->ipa_uc_tx_rsc.tx_comp_ring->vaddr;
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+		mem_map_table = qdf_mem_map_table_alloc(uc_tx_buf_cnt);
+		if (!mem_map_table) {
+			qdf_print("%s: Failed to allocate memory for mem map table\n",
+				  __func__);
+			return 0;
+		}
+		mem_info = mem_map_table;
+	}
+
+	/* Allocate TX buffers as many as possible */
+	for (tx_buffer_count = 0;
+	     tx_buffer_count < (uc_tx_buf_cnt - 1); tx_buffer_count++) {
+		shared_tx_buffer = qdf_mem_shared_mem_alloc(pdev->osdev,
+							    uc_tx_buf_sz);
+		if (!shared_tx_buffer || !shared_tx_buffer->vaddr) {
+			qdf_print("%s: TX BUF alloc fail, loop index: %d",
+				  __func__, tx_buffer_count);
+			goto pwr2;
+		}
+
+		/* Init buffer */
+		qdf_mem_zero(shared_tx_buffer->vaddr, uc_tx_buf_sz);
+		header_ptr = (uint32_t *)shared_tx_buffer->vaddr;
+		buffer_paddr = qdf_mem_get_dma_addr(pdev->osdev,
+						&shared_tx_buffer->mem_info);
+
+		/* HTT control header */
+		*header_ptr = HTT_IPA_UC_OFFLOAD_TX_HEADER_DEFAULT;
+		header_ptr++;
+
+		/* PKT ID */
+		*header_ptr |= ((uint16_t) uc_tx_partition_base +
+				tx_buffer_count) << 16;
+		header_ptr++;
+
+		/*FRAG Desc Pointer */
+		*header_ptr = (uint32_t) (buffer_paddr +
+						IPA_UC_TX_BUF_FRAG_DESC_OFFSET);
+		header_ptr++;
+		*header_ptr = 0xFFFFFFFF;
+
+		/* FRAG Header */
+		header_ptr++;
+		*header_ptr = buffer_paddr + IPA_UC_TX_BUF_FRAG_HDR_OFFSET;
+
+		*ring_vaddr = buffer_paddr;
+		pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[tx_buffer_count] =
+			shared_tx_buffer;
+		/* Memory barrier to ensure actual value updated */
+
+		ring_vaddr++;
+		if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+			*mem_info = pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[
+						tx_buffer_count]->mem_info;
+			 mem_info++;
+		}
+	}
+
+pwr2:
+	/*
+	 * Tx complete ring buffer count should be power of 2.
+	 * So, allocated Tx buffer count should be one less than ring buffer
+	 * size.
+	 */
+	tx_buffer_count_pwr2 = qdf_rounddown_pow_of_two(tx_buffer_count + 1)
+			       - 1;
+	if (tx_buffer_count > tx_buffer_count_pwr2) {
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+			  "%s: Allocated Tx buffer count %d is rounded down to %d",
+			  __func__, tx_buffer_count, tx_buffer_count_pwr2);
+
+		/* Free over allocated buffers below power of 2 */
+		for (idx = tx_buffer_count_pwr2; idx < tx_buffer_count; idx++) {
+			if (pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[idx]) {
+				qdf_mem_shared_mem_free(pdev->osdev,
+							pdev->ipa_uc_tx_rsc.
+							tx_buf_pool_strg[idx]);
+				pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[idx] =
+									NULL;
+			}
+		}
+	}
+
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+		cds_smmu_map_unmap(true, tx_buffer_count_pwr2,
+				   mem_map_table);
+		qdf_mem_free(mem_map_table);
+	}
+
+	return tx_buffer_count_pwr2;
+}
+
+static void htt_tx_buf_pool_free(struct htt_pdev_t *pdev)
+{
+	uint16_t idx;
+	qdf_mem_info_t *mem_map_table = NULL, *mem_info = NULL;
+	uint32_t num_unmapped = 0;
+
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+		mem_map_table = qdf_mem_map_table_alloc(
+					pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt);
+		if (!mem_map_table) {
+			qdf_print("%s: Failed to allocate memory for mem map table\n",
+				  __func__);
+			return;
+		}
+		mem_info = mem_map_table;
+	}
+
+	for (idx = 0; idx < pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt; idx++) {
+		if (pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[idx]) {
+			if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+				*mem_info = pdev->ipa_uc_tx_rsc.
+					      tx_buf_pool_strg[idx]->mem_info;
+				mem_info++;
+				num_unmapped++;
+			}
+			qdf_mem_shared_mem_free(pdev->osdev,
+						pdev->ipa_uc_tx_rsc.
+							tx_buf_pool_strg[idx]);
+			pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[idx] = NULL;
+		}
+	}
+
+	if (qdf_mem_smmu_s1_enabled(pdev->osdev)) {
+		if (num_unmapped)
+			cds_smmu_map_unmap(false, num_unmapped, mem_map_table);
+		qdf_mem_free(mem_map_table);
+	}
+}
+#endif
+
+/**
+ * htt_tx_ipa_uc_attach() - attach htt ipa uc tx resource
+ * @pdev: htt context
+ * @uc_tx_buf_sz: single tx buffer size
+ * @uc_tx_buf_cnt: total tx buffer count
+ * @uc_tx_partition_base: tx buffer partition start
+ *
+ * Return: 0 success
+ *         ENOBUFS No memory fail
+ */
+int htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev,
+			 unsigned int uc_tx_buf_sz,
+			 unsigned int uc_tx_buf_cnt,
+			 unsigned int uc_tx_partition_base)
+{
+	int return_code = 0;
+	unsigned int tx_comp_ring_size;
+
+	/* Allocate CE Write Index WORD */
+	pdev->ipa_uc_tx_rsc.tx_ce_idx =
+		qdf_mem_shared_mem_alloc(pdev->osdev, 4);
+	if (!pdev->ipa_uc_tx_rsc.tx_ce_idx) {
+		qdf_print("%s: Unable to allocate memory for IPA tx ce idx\n",
+			  __func__);
+		return -ENOBUFS;
+	}
+
+	/* Allocate TX COMP Ring */
+	tx_comp_ring_size = uc_tx_buf_cnt * sizeof(target_paddr_t);
+	pdev->ipa_uc_tx_rsc.tx_comp_ring =
+		qdf_mem_shared_mem_alloc(pdev->osdev,
+					 tx_comp_ring_size);
+	if (!pdev->ipa_uc_tx_rsc.tx_comp_ring ||
+	    !pdev->ipa_uc_tx_rsc.tx_comp_ring->vaddr) {
+		qdf_print("%s: TX COMP ring alloc fail", __func__);
+		return_code = -ENOBUFS;
+		goto free_tx_ce_idx;
+	}
+
+	/* Allocate TX BUF vAddress Storage */
+	pdev->ipa_uc_tx_rsc.tx_buf_pool_strg =
+		qdf_mem_malloc(uc_tx_buf_cnt *
+			sizeof(*pdev->ipa_uc_tx_rsc.tx_buf_pool_strg));
+	if (!pdev->ipa_uc_tx_rsc.tx_buf_pool_strg) {
+		qdf_print("%s: TX BUF POOL vaddr storage alloc fail", __func__);
+		return_code = -ENOBUFS;
+		goto free_tx_comp_base;
+	}
+
+	qdf_mem_zero(pdev->ipa_uc_tx_rsc.tx_buf_pool_strg,
+		     uc_tx_buf_cnt *
+		     sizeof(*pdev->ipa_uc_tx_rsc.tx_buf_pool_strg));
+
+	pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt = htt_tx_ipa_uc_wdi_tx_buf_alloc(
+		pdev, uc_tx_buf_sz, uc_tx_buf_cnt, uc_tx_partition_base);
+
+
+	return 0;
+
+free_tx_comp_base:
+	qdf_mem_shared_mem_free(pdev->osdev,
+				pdev->ipa_uc_tx_rsc.tx_comp_ring);
+free_tx_ce_idx:
+	qdf_mem_shared_mem_free(pdev->osdev,
+				pdev->ipa_uc_tx_rsc.tx_ce_idx);
+
+	return return_code;
+}
+
+/**
+ * htt_tx_ipa_uc_detach() - Free WDI TX resources
+ * @pdev: htt context
+ *
+ * Remove IPA WDI TX resources during device detach
+ * Free all of allocated resources
+ *
+ * Return: 0 success
+ */
+int htt_tx_ipa_uc_detach(struct htt_pdev_t *pdev)
+{
+	qdf_mem_shared_mem_free(pdev->osdev,
+				pdev->ipa_uc_tx_rsc.tx_ce_idx);
+	qdf_mem_shared_mem_free(pdev->osdev,
+				pdev->ipa_uc_tx_rsc.tx_comp_ring);
+
+	/* Free each single buffer */
+	htt_tx_buf_pool_free(pdev);
+
+	/* Free storage */
+	qdf_mem_free(pdev->ipa_uc_tx_rsc.tx_buf_pool_strg);
+
+	return 0;
+}
+#endif /* IPA_OFFLOAD */
+
+#if defined(FEATURE_TSO) && defined(HELIUMPLUS)
+void
+htt_tx_desc_fill_tso_info(htt_pdev_handle pdev, void *desc,
+	 struct qdf_tso_info_t *tso_info)
+{
+	u_int32_t *word;
+	int i;
+	struct qdf_tso_seg_elem_t *tso_seg = tso_info->curr_seg;
+	struct msdu_ext_desc_t *msdu_ext_desc = (struct msdu_ext_desc_t *)desc;
+
+	word = (u_int32_t *)(desc);
+
+	/* Initialize the TSO flags per MSDU */
+	msdu_ext_desc->tso_flags =
+		 tso_seg->seg.tso_flags;
+
+	/* First 24 bytes (6*4) contain the TSO flags */
+	TSO_DEBUG("%s seq# %u l2 len %d, ip len %d\n",
+		  __func__,
+		  tso_seg->seg.tso_flags.tcp_seq_num,
+		  tso_seg->seg.tso_flags.l2_len,
+		  tso_seg->seg.tso_flags.ip_len);
+	TSO_DEBUG("%s flags 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+		  __func__,
+		  *word,
+		  *(word + 1),
+		  *(word + 2),
+		  *(word + 3),
+		  *(word + 4),
+		  *(word + 5));
+
+	word += 6;
+
+	for (i = 0; i < tso_seg->seg.num_frags; i++) {
+		uint32_t lo = 0;
+		uint32_t hi = 0;
+
+		qdf_dmaaddr_to_32s(tso_seg->seg.tso_frags[i].paddr,
+						&lo, &hi);
+		/* [31:0] first 32 bits of the buffer pointer  */
+		*word = lo;
+		word++;
+		/* [15:0] the upper 16 bits of the first buffer pointer */
+		/* [31:16] length of the first buffer */
+		*word = (tso_seg->seg.tso_frags[i].length << 16) | hi;
+		word++;
+		TSO_DEBUG("%s frag[%d] ptr_low 0x%x ptr_hi 0x%x len %u\n",
+			__func__, i,
+			msdu_ext_desc->frags[i].u.frag32.ptr_low,
+			msdu_ext_desc->frags[i].u.frag32.ptr_hi,
+			msdu_ext_desc->frags[i].u.frag32.len);
+	}
+
+	if (tso_seg->seg.num_frags < FRAG_NUM_MAX)
+		*word = 0;
+	qdf_tso_seg_dbg_record(tso_seg, TSOSEG_LOC_FILLHTTSEG);
+}
+#endif /* FEATURE_TSO */
+
+/**
+ * htt_get_ext_tid() - get ext_tid value
+ * @type: extension header type
+ * @ext_header_data: header data
+ * @msdu_info: msdu info
+ *
+ * Return: ext_tid value
+ */
+static inline
+int htt_get_ext_tid(enum extension_header_type type,
+	void *ext_header_data, struct htt_msdu_info_t *msdu_info)
+{
+	if (type == OCB_MODE_EXT_HEADER && ext_header_data)
+		return ((struct ocb_tx_ctrl_hdr_t *)ext_header_data)->ext_tid;
+	else
+		return msdu_info->info.ext_tid;
+}
+
+/**
+ * htt_get_channel_freq() - get channel frequency
+ * @type: extension header type
+ * @ext_header_data: header data
+ *
+ * Return: channel frequency number
+ */
+static inline
+int htt_get_channel_freq(enum extension_header_type type,
+	void *ext_header_data)
+{
+	if (type == OCB_MODE_EXT_HEADER && ext_header_data)
+		return ((struct ocb_tx_ctrl_hdr_t *)ext_header_data)
+							->channel_freq;
+	else
+		return HTT_INVALID_CHANNEL;
+}
+
+/**
+ * htt_fill_ocb_ext_header() - fill OCB extension header
+ * @msdu: network buffer
+ * @local_desc_ext: extension descriptor
+ * @type: extension header type
+ * @ext_header_data: header data
+ * @is_dsrc: is dsrc is eenabled or not
+ *
+ * Return: none
+ */
+#ifdef WLAN_FEATURE_DSRC
+static
+void htt_fill_ocb_ext_header(qdf_nbuf_t msdu,
+			     struct htt_tx_msdu_desc_ext_t *local_desc_ext,
+			     enum extension_header_type type,
+			     void *ext_header_data)
+{
+	struct ocb_tx_ctrl_hdr_t *tx_ctrl =
+		(struct ocb_tx_ctrl_hdr_t *)ext_header_data;
+
+	if (tx_ctrl->all_flags == 0)
+		return;
+	/*
+	 * Copy the info that was read from TX control header from the
+	 * user application to the extended HTT header.
+	 * First copy everything
+	 * to a local temp structure, and then copy everything to the
+	 * actual uncached structure in one go to save memory writes.
+	 */
+	local_desc_ext->valid_pwr = tx_ctrl->valid_pwr;
+	local_desc_ext->valid_mcs_mask = tx_ctrl->valid_datarate;
+	local_desc_ext->valid_retries = tx_ctrl->valid_retries;
+	local_desc_ext->valid_expire_tsf = tx_ctrl->valid_expire_tsf;
+	local_desc_ext->valid_chainmask = tx_ctrl->valid_chain_mask;
+
+	local_desc_ext->pwr = tx_ctrl->pwr;
+	if (tx_ctrl->valid_datarate &&
+			tx_ctrl->datarate <= htt_ofdm_datarate_max)
+		local_desc_ext->mcs_mask =
+			(1 << (tx_ctrl->datarate + 4));
+	local_desc_ext->retry_limit = tx_ctrl->retry_limit;
+	local_desc_ext->expire_tsf_lo = tx_ctrl->expire_tsf_lo;
+	local_desc_ext->expire_tsf_hi = tx_ctrl->expire_tsf_hi;
+	local_desc_ext->chain_mask = tx_ctrl->chain_mask;
+	local_desc_ext->is_dsrc = 1;
+	qdf_nbuf_push_head(msdu, sizeof(struct htt_tx_msdu_desc_ext_t));
+	qdf_mem_copy(qdf_nbuf_data(msdu), local_desc_ext,
+			sizeof(struct htt_tx_msdu_desc_ext_t));
+	QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_EXT_HEADER(msdu) = 1;
+}
+#else
+static
+void htt_fill_ocb_ext_header(qdf_nbuf_t msdu,
+			     struct htt_tx_msdu_desc_ext_t *local_desc_ext,
+			     enum extension_header_type type,
+			     void *ext_header_data)
+{
+}
+#endif
+
+/**
+ * htt_fill_wisa_ext_header() - fill WiSA extension header
+ * @msdu: network buffer
+ * @local_desc_ext: extension descriptor
+ * @type: extension header type
+ * @ext_header_data: header data
+ *
+ * Return: none
+ */
+static
+void htt_fill_wisa_ext_header(qdf_nbuf_t msdu,
+	struct htt_tx_msdu_desc_ext_t *local_desc_ext,
+	enum extension_header_type type, void *ext_header_data)
+{
+	void *qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	QDF_STATUS status;
+
+	if (!qdf_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			"%s: qdf_ctx is NULL", __func__);
+		return;
+	}
+
+	local_desc_ext->valid_mcs_mask = 1;
+	if (WISA_MODE_EXT_HEADER_6MBPS == type)
+		local_desc_ext->mcs_mask = htt_ofdm_datarate_6_mbps;
+	else
+		local_desc_ext->mcs_mask = htt_ofdm_datarate_24_mbps;
+	local_desc_ext->valid_nss_mask = 1;
+	local_desc_ext->nss_mask = 1;
+	local_desc_ext->valid_bandwidth = 1;
+	local_desc_ext->bandwidth_mask = htt_tx_bandwidth_20MHz;
+	local_desc_ext->valid_guard_interval = 1;
+	local_desc_ext->guard_interval = htt_tx_guard_interval_regular;
+
+	/*
+	 * Do dma_unmap and dma_map again if already mapped
+	 * as adding extra bytes in skb
+	 */
+	if (QDF_NBUF_CB_PADDR(msdu) != 0)
+		qdf_nbuf_unmap_single(qdf_ctx, msdu, QDF_DMA_TO_DEVICE);
+
+	qdf_nbuf_push_head(msdu, sizeof(struct htt_tx_msdu_desc_ext_t));
+	qdf_mem_copy(qdf_nbuf_data(msdu), local_desc_ext,
+			sizeof(struct htt_tx_msdu_desc_ext_t));
+
+	if (QDF_NBUF_CB_PADDR(msdu) != 0) {
+		status = qdf_nbuf_map_single(qdf_ctx, msdu, QDF_DMA_TO_DEVICE);
+		if (qdf_unlikely(status != QDF_STATUS_SUCCESS)) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN,
+				"%s: nbuf map failed", __func__);
+			return;
+		}
+	}
+	QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_EXT_HEADER(msdu) = 1;
+}
+
+/**
+ * htt_push_ext_header() - fill extension header
+ * @msdu: network buffer
+ * @local_desc_ext: extension descriptor
+ * @type: extension header type
+ * @ext_header_data: header data
+ * @is_dsrc: is dsrc is eenabled or not
+ *
+ * Return: none
+ */
+static
+void htt_push_ext_header(qdf_nbuf_t msdu,
+	struct htt_tx_msdu_desc_ext_t *local_desc_ext,
+	enum extension_header_type type, void *ext_header_data)
+{
+	switch (type) {
+	case OCB_MODE_EXT_HEADER:
+		htt_fill_ocb_ext_header(msdu, local_desc_ext,
+					type, ext_header_data);
+		break;
+	case WISA_MODE_EXT_HEADER_6MBPS:
+	case WISA_MODE_EXT_HEADER_24MBPS:
+		htt_fill_wisa_ext_header(msdu, local_desc_ext,
+					type, ext_header_data);
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
+			"Invalid EXT header type %d\n", type);
+		break;
+	}
+}
+
+QDF_STATUS
+htt_tx_desc_init(htt_pdev_handle pdev,
+		 void *htt_tx_desc,
+		 qdf_dma_addr_t htt_tx_desc_paddr,
+		 uint16_t msdu_id,
+		 qdf_nbuf_t msdu, struct htt_msdu_info_t *msdu_info,
+		 struct qdf_tso_info_t *tso_info,
+		 void *ext_header_data,
+		 enum extension_header_type type)
+{
+	uint8_t  pkt_type, pkt_subtype = 0, ce_pkt_type = 0;
+	uint32_t hw_classify = 0, data_attr = 0;
+	uint32_t *word0, *word1, local_word3;
+#if HTT_PADDR64
+	uint32_t *word4;
+#else /* ! HTT_PADDR64 */
+	uint32_t *word3;
+#endif /* HTT_PADDR64 */
+	uint32_t local_word0, local_word1;
+	struct htt_host_tx_desc_t *htt_host_tx_desc =
+		(struct htt_host_tx_desc_t *)
+		(((char *)htt_tx_desc) - HTT_TX_DESC_VADDR_OFFSET);
+	bool desc_ext_required = (type != EXT_HEADER_NOT_PRESENT);
+	int channel_freq;
+	void *qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	qdf_dma_dir_t dir;
+	QDF_STATUS status;
+
+	if (qdf_unlikely(!qdf_ctx)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			"%s: qdf_ctx is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (qdf_unlikely(!msdu_info)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			"%s: bad arg: msdu_info is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (qdf_unlikely(!tso_info)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			"%s: bad arg: tso_info is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	word0 = (uint32_t *) htt_tx_desc;
+	word1 = word0 + 1;
+	/*
+	 * word2 is frag desc pointer
+	 * word3 or 4 is peer_id
+	 */
+#if HTT_PADDR64
+	word4 = word0 + 4;      /* Dword 3 */
+#else /* ! HTT_PADDR64  */
+	word3 = word0 + 3;      /* Dword 3 */
+#endif /* HTT_PADDR64 */
+
+	pkt_type = msdu_info->info.l2_hdr_type;
+
+	if (qdf_likely(pdev->cfg.ce_classify_enabled)) {
+		if (qdf_likely(pkt_type == htt_pkt_type_eth2 ||
+			pkt_type == htt_pkt_type_ethernet))
+			qdf_nbuf_tx_info_get(msdu, pkt_type, pkt_subtype,
+				     hw_classify);
+
+		ce_pkt_type = htt_to_ce_pkt_type[pkt_type];
+		if (0xffffffff == ce_pkt_type) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+			"Invalid HTT pkt type %d\n", pkt_type);
+			return QDF_STATUS_E_INVAL;
+		}
+	}
+
+	/*
+	 * HTT Tx Desc is in uncached memory. Used cached writes per word, to
+	 * reduce unnecessary memory access.
+	 */
+
+	local_word0 = 0;
+
+	HTT_H2T_MSG_TYPE_SET(local_word0, HTT_H2T_MSG_TYPE_TX_FRM);
+	HTT_TX_DESC_PKT_TYPE_SET(local_word0, pkt_type);
+	HTT_TX_DESC_PKT_SUBTYPE_SET(local_word0, pkt_subtype);
+	HTT_TX_DESC_VDEV_ID_SET(local_word0, msdu_info->info.vdev_id);
+	HTT_TX_DESC_EXT_TID_SET(local_word0, htt_get_ext_tid(type,
+					ext_header_data, msdu_info));
+	HTT_TX_DESC_EXTENSION_SET(local_word0, desc_ext_required);
+	HTT_TX_DESC_EXT_TID_SET(local_word0, msdu_info->info.ext_tid);
+	HTT_TX_DESC_CKSUM_OFFLOAD_SET(local_word0,
+				      msdu_info->action.cksum_offload);
+	if (pdev->cfg.is_high_latency)
+		HTT_TX_DESC_TX_COMP_SET(local_word0, msdu_info->action.
+							tx_comp_req);
+	HTT_TX_DESC_NO_ENCRYPT_SET(local_word0,
+				   msdu_info->action.do_encrypt ?
+				   0 : 1);
+
+	*word0 = local_word0;
+
+	local_word1 = 0;
+
+	if (tso_info->is_tso) {
+		uint32_t total_len = tso_info->curr_seg->seg.total_len;
+
+		HTT_TX_DESC_FRM_LEN_SET(local_word1, total_len);
+		TSO_DEBUG("%s setting HTT TX DESC Len = %d\n",
+			  __func__, total_len);
+	} else {
+		HTT_TX_DESC_FRM_LEN_SET(local_word1, qdf_nbuf_len(msdu));
+	}
+
+	QDF_BUG(HTT_TX_DESC_FRM_LEN_GET(local_word1) != 0);
+
+	HTT_TX_DESC_FRM_ID_SET(local_word1, msdu_id);
+	*word1 = local_word1;
+
+	/*
+	 * Initialize peer_id to INVALID_PEER because
+	 * this is NOT Reinjection path
+	 */
+	local_word3 = HTT_INVALID_PEER;
+	channel_freq = htt_get_channel_freq(type, ext_header_data);
+	if (channel_freq != HTT_INVALID_CHANNEL && channel_freq > 0)
+		HTT_TX_DESC_CHAN_FREQ_SET(local_word3, channel_freq);
+#if HTT_PADDR64
+	*word4 = local_word3;
+#else /* ! HTT_PADDR64 */
+	*word3 = local_word3;
+#endif /* HTT_PADDR64 */
+
+	/*
+	 *  If any of the tx control flags are set, then we need the extended
+	 *  HTT header.
+	 */
+	if (desc_ext_required) {
+		struct htt_tx_msdu_desc_ext_t local_desc_ext = {0};
+
+		htt_push_ext_header(msdu, &local_desc_ext,
+			type, ext_header_data);
+	}
+
+	/*
+	 * Specify that the data provided by the OS is a bytestream,
+	 * and thus should not be byte-swapped during the HIF download
+	 * even if the host is big-endian.
+	 * There could be extra fragments added before the OS's fragments,
+	 * e.g. for TSO, so it's incorrect to clear the frag 0 wordstream flag.
+	 * Instead, clear the wordstream flag for the final fragment, which
+	 * is certain to be (one of the) fragment(s) provided by the OS.
+	 * Setting the flag for this final fragment suffices for specifying
+	 * all fragments provided by the OS rather than added by the driver.
+	 */
+	qdf_nbuf_set_frag_is_wordstream(msdu, qdf_nbuf_get_num_frags(msdu) - 1,
+					0);
+
+	if (QDF_NBUF_CB_PADDR(msdu) == 0) {
+		dir = QDF_NBUF_CB_TX_DMA_BI_MAP(msdu) ?
+			QDF_DMA_BIDIRECTIONAL : QDF_DMA_TO_DEVICE;
+		status = qdf_nbuf_map_single(qdf_ctx, msdu, dir);
+		if (qdf_unlikely(status != QDF_STATUS_SUCCESS)) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: nbuf map failed", __func__);
+			return QDF_STATUS_E_NOMEM;
+		}
+	}
+
+	/* store a link to the HTT tx descriptor within the netbuf */
+	qdf_nbuf_frag_push_head(msdu, sizeof(struct htt_host_tx_desc_t),
+				(char *)htt_host_tx_desc, /* virtual addr */
+				htt_tx_desc_paddr);
+
+	/*
+	 * Indicate that the HTT header (and HTC header) is a meta-data
+	 * "wordstream", i.e. series of uint32_t, rather than a data
+	 * bytestream.
+	 * This allows the HIF download to byteswap the HTT + HTC headers if
+	 * the host is big-endian, to convert to the target's little-endian
+	 * format.
+	 */
+	qdf_nbuf_set_frag_is_wordstream(msdu, 0, 1);
+
+	if (qdf_likely(pdev->cfg.ce_classify_enabled &&
+		(msdu_info->info.l2_hdr_type != htt_pkt_type_mgmt))) {
+		uint32_t pkt_offset = qdf_nbuf_get_frag_len(msdu, 0);
+
+		data_attr = hw_classify << QDF_CE_TX_CLASSIFY_BIT_S;
+		data_attr |= ce_pkt_type << QDF_CE_TX_PKT_TYPE_BIT_S;
+		data_attr |= pkt_offset  << QDF_CE_TX_PKT_OFFSET_BIT_S;
+	}
+
+	qdf_nbuf_data_attr_set(msdu, data_attr);
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+
+/**
+ * htt_tx_group_credit_process() - process group data for
+ *				   credit update indication
+ * @pdev: pointer to htt device.
+ * @msg_word: htt msg
+ *
+ * Return: None
+ */
+void htt_tx_group_credit_process(struct htt_pdev_t *pdev, u_int32_t *msg_word)
+{
+	int group_credit_sign;
+	int32_t group_credit;
+	u_int32_t group_credit_abs, vdev_id_mask, ac_mask;
+	u_int8_t group_abs, group_id;
+	u_int8_t group_offset = 0, more_group_present = 0;
+
+	more_group_present = HTT_TX_CREDIT_TXQ_GRP_GET(*msg_word);
+
+	while (more_group_present) {
+		/* Parse the Group Data */
+		group_id = HTT_TXQ_GROUP_ID_GET(*(msg_word+1
+						+group_offset));
+		group_credit_abs =
+			HTT_TXQ_GROUP_CREDIT_COUNT_GET(*(msg_word+1
+						+group_offset));
+		group_credit_sign =
+			HTT_TXQ_GROUP_SIGN_GET(*(msg_word+1
+						+group_offset)) ? -1 : 1;
+		group_credit = group_credit_sign * group_credit_abs;
+		group_abs = HTT_TXQ_GROUP_ABS_GET(*(msg_word+1
+						+group_offset));
+
+		vdev_id_mask =
+			HTT_TXQ_GROUP_VDEV_ID_MASK_GET(*(msg_word+2
+						+group_offset));
+		ac_mask = HTT_TXQ_GROUP_AC_MASK_GET(*(msg_word+2
+						+group_offset));
+
+		ol_txrx_update_tx_queue_groups(pdev->txrx_pdev, group_id,
+					       group_credit, group_abs,
+					       vdev_id_mask, ac_mask);
+		more_group_present = HTT_TXQ_GROUP_EXT_GET(*(msg_word+1
+						+group_offset));
+		group_offset += HTT_TX_GROUP_INDEX_OFFSET;
+	}
+	ol_tx_update_group_credit_stats(pdev->txrx_pdev);
+}
+#endif
+
diff --git a/core/dp/htt/htt_types.h b/core/dp/htt/htt_types.h
new file mode 100644
index 0000000..08dd8fb
--- /dev/null
+++ b/core/dp/htt/htt_types.h
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 2011, 2014-2018 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.
+ */
+
+#ifndef _HTT_TYPES__H_
+#define _HTT_TYPES__H_
+
+#include <osdep.h>              /* uint16_t, dma_addr_t */
+#include <qdf_types.h>          /* qdf_device_t */
+#include <qdf_lock.h>           /* qdf_spinlock_t */
+#include <qdf_timer.h>		/* qdf_timer_t */
+#include <qdf_atomic.h>         /* qdf_atomic_inc */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <htc_api.h>            /* HTC_PACKET */
+#include <ol_htt_api.h>
+#include <cdp_txrx_handle.h>
+#define DEBUG_DMA_DONE
+
+#define HTT_TX_MUTEX_TYPE qdf_spinlock_t
+
+#ifdef QCA_TX_HTT2_SUPPORT
+#ifndef HTC_TX_HTT2_MAX_SIZE
+/* Should sync to the target's implementation. */
+#define HTC_TX_HTT2_MAX_SIZE    (120)
+#endif
+#endif /* QCA_TX_HTT2_SUPPORT */
+
+/*
+ * Set the base misclist size to the size of the htt tx copy engine
+ * to guarantee that a packet on the misclist wont be freed while it
+ * is sitting in the copy engine.
+ */
+#define HTT_HTC_PKT_MISCLIST_SIZE          2048
+
+struct htt_htc_pkt {
+	void *pdev_ctxt;
+	target_paddr_t nbuf_paddr;
+	HTC_PACKET htc_pkt;
+	uint16_t msdu_id;
+};
+
+struct htt_htc_pkt_union {
+	union {
+		struct htt_htc_pkt pkt;
+		struct htt_htc_pkt_union *next;
+	} u;
+};
+
+/*
+ * HTT host descriptor:
+ * Include the htt_tx_msdu_desc that gets downloaded to the target,
+ * but also include the HTC_FRAME_HDR and alignment padding that
+ * precede the htt_tx_msdu_desc.
+ * htc_send_data_pkt expects this header space at the front of the
+ * initial fragment (i.e. tx descriptor) that is downloaded.
+ */
+struct htt_host_tx_desc_t {
+	uint8_t htc_header[HTC_HEADER_LEN];
+	/* force the tx_desc field to begin on a 4-byte boundary */
+	union {
+		uint32_t dummy_force_align;
+		struct htt_tx_msdu_desc_t tx_desc;
+	} align32;
+};
+
+struct htt_tx_mgmt_desc_buf {
+	qdf_nbuf_t msg_buf;
+	A_BOOL is_inuse;
+	qdf_nbuf_t mgmt_frm;
+};
+
+struct htt_tx_mgmt_desc_ctxt {
+	struct htt_tx_mgmt_desc_buf *pool;
+	A_UINT32 pending_cnt;
+};
+
+struct htt_list_node {
+	struct htt_list_node *prev;
+	struct htt_list_node *next;
+};
+
+struct htt_rx_hash_entry {
+	qdf_dma_addr_t paddr;
+	qdf_nbuf_t netbuf;
+	A_UINT8 fromlist;
+	struct htt_list_node listnode;
+#ifdef RX_HASH_DEBUG
+	A_UINT32 cookie;
+#endif
+};
+
+struct htt_rx_hash_bucket {
+	struct htt_list_node listhead;
+	struct htt_rx_hash_entry *entries;
+	struct htt_list_node freepool;
+#ifdef RX_HASH_DEBUG
+	A_UINT32 count;
+#endif
+};
+
+/*
+ * Micro controller datapath offload
+ * WLAN TX resources
+ */
+struct htt_ipa_uc_tx_resource_t {
+	qdf_shared_mem_t *tx_ce_idx;
+	qdf_shared_mem_t *tx_comp_ring;
+
+	uint32_t tx_comp_idx_paddr;
+	qdf_shared_mem_t **tx_buf_pool_strg;
+	uint32_t alloc_tx_buf_cnt;
+};
+
+/**
+ * struct htt_ipa_uc_rx_resource_t
+ * @rx_rdy_idx_paddr: rx ready index physical address
+ * @rx_ind_ring: rx indication ring memory info
+ * @rx_ipa_prc_done_idx: rx process done index memory info
+ * @rx2_ind_ring: rx2 indication ring memory info
+ * @rx2_ipa_prc_done_idx: rx2 process done index memory info
+ */
+struct htt_ipa_uc_rx_resource_t {
+	qdf_dma_addr_t rx_rdy_idx_paddr;
+	qdf_shared_mem_t *rx_ind_ring;
+	qdf_shared_mem_t *rx_ipa_prc_done_idx;
+
+	/* 2nd RX ring */
+	qdf_shared_mem_t *rx2_ind_ring;
+	qdf_shared_mem_t *rx2_ipa_prc_done_idx;
+};
+
+/**
+ * struct ipa_uc_rx_ring_elem_t
+ * @rx_packet_paddr: rx packet physical address
+ * @vdev_id: virtual interface id
+ * @rx_packet_leng: packet length
+ */
+#if HTT_PADDR64
+struct ipa_uc_rx_ring_elem_t {
+	target_paddr_t rx_packet_paddr;
+	uint32_t vdev_id;
+	uint32_t rx_packet_leng;
+};
+#else
+struct ipa_uc_rx_ring_elem_t {
+	target_paddr_t rx_packet_paddr;
+	uint16_t vdev_id;
+	uint16_t rx_packet_leng;
+};
+#endif
+
+struct htt_tx_credit_t {
+	qdf_atomic_t bus_delta;
+	qdf_atomic_t target_delta;
+};
+
+#if defined(HELIUMPLUS)
+/**
+ * msdu_ext_frag_desc:
+ * semantically, this is an array of 6 of 2-tuples of
+ * a 48-bit physical address and a 16 bit len field
+ * with the following layout:
+ * 31               16       8       0
+ * |        p t r - l o w 3 2         |
+ * | len             | ptr-7/16       |
+ */
+struct msdu_ext_frag_desc {
+	union {
+		uint64_t desc64;
+		struct {
+			uint32_t ptr_low;
+			uint32_t ptr_hi:16,
+				len:16;
+		} frag32;
+	} u;
+};
+
+struct msdu_ext_desc_t {
+	struct qdf_tso_flags_t tso_flags;
+	struct msdu_ext_frag_desc frags[6];
+/*
+ *	u_int32_t frag_ptr0;
+ *	u_int32_t frag_len0;
+ *	u_int32_t frag_ptr1;
+ *	u_int32_t frag_len1;
+ *	u_int32_t frag_ptr2;
+ *	u_int32_t frag_len2;
+ *	u_int32_t frag_ptr3;
+ *	u_int32_t frag_len3;
+ *	u_int32_t frag_ptr4;
+ *	u_int32_t frag_len4;
+ *	u_int32_t frag_ptr5;
+ *	u_int32_t frag_len5;
+ */
+};
+#endif  /* defined(HELIUMPLUS) */
+
+/**
+ * struct mon_channel
+ * @ch_num: Monitor mode capture channel number
+ * @ch_freq: channel frequency.
+ */
+struct mon_channel {
+	uint32_t ch_num;
+	uint32_t ch_freq;
+};
+
+struct htt_pdev_t {
+	struct cdp_cfg *ctrl_pdev;
+	ol_txrx_pdev_handle txrx_pdev;
+	HTC_HANDLE htc_pdev;
+	qdf_device_t osdev;
+
+	HTC_ENDPOINT_ID htc_tx_endpoint;
+
+#ifdef QCA_TX_HTT2_SUPPORT
+	HTC_ENDPOINT_ID htc_tx_htt2_endpoint;
+	uint16_t htc_tx_htt2_max_size;
+#endif /* QCA_TX_HTT2_SUPPORT */
+
+#ifdef ATH_11AC_TXCOMPACT
+	HTT_TX_MUTEX_TYPE txnbufq_mutex;
+	qdf_nbuf_queue_t txnbufq;
+	struct htt_htc_pkt_union *htt_htc_pkt_misclist;
+#endif
+
+	struct htt_htc_pkt_union *htt_htc_pkt_freelist;
+	struct {
+		int is_high_latency;
+		int is_full_reorder_offload;
+		int default_tx_comp_req;
+		int ce_classify_enabled;
+		uint8_t is_first_wakeup_packet;
+		/*
+		 * To track if credit reporting through
+		 * HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND is enabled/disabled.
+		 * In Genoa(QCN7605) credits are reported through
+		 * HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND only.
+		 */
+		u8 credit_update_enabled;
+		/* Explicitly request TX completions. */
+		u8 request_tx_comp;
+	} cfg;
+	struct {
+		uint8_t major;
+		uint8_t minor;
+	} tgt_ver;
+#if defined(HELIUMPLUS)
+	struct {
+		u_int8_t major;
+		u_int8_t minor;
+	} wifi_ip_ver;
+#endif /* defined(HELIUMPLUS) */
+	struct {
+		struct {
+			/*
+			 * Ring of network buffer objects -
+			 * This ring is used exclusively by the host SW.
+			 * This ring mirrors the dev_addrs_ring that is shared
+			 * between the host SW and the MAC HW.
+			 * The host SW uses this netbufs ring to locate the nw
+			 * buffer objects whose data buffers the HW has filled.
+			 */
+			qdf_nbuf_t *netbufs_ring;
+			/*
+			 * Ring of buffer addresses -
+			 * This ring holds the "physical" device address of the
+			 * rx buffers the host SW provides for MAC HW to fill.
+			 */
+#if HTT_PADDR64
+			uint64_t *paddrs_ring;
+#else   /* ! HTT_PADDR64 */
+			uint32_t *paddrs_ring;
+#endif
+			qdf_dma_mem_context(memctx);
+		} buf;
+		/*
+		 * Base address of ring, as a "physical" device address rather
+		 * than a CPU address.
+		 */
+		qdf_dma_addr_t base_paddr;
+		int32_t  size;	/* how many elems in the ring (power of 2) */
+		uint32_t size_mask;	/* size - 1, at least 16 bits long */
+
+		int fill_level; /* how many rx buffers to keep in the ring */
+		int fill_cnt;   /* # of rx buffers (full+empty) in the ring */
+		int pop_fail_cnt;   /* # of nebuf pop failures */
+
+		/*
+		 * target_idx -
+		 * Without reorder offload:
+		 * not used
+		 * With reorder offload:
+		 * points to the location in the rx ring from which rx buffers
+		 * are available to copy into the MAC DMA ring
+		 */
+		struct {
+			uint32_t *vaddr;
+			qdf_dma_addr_t paddr;
+			qdf_dma_mem_context(memctx);
+		} target_idx;
+
+		/*
+		 * alloc_idx/host_idx -
+		 * Without reorder offload:
+		 * where HTT SW has deposited empty buffers
+		 * This is allocated in consistent mem, so that the FW can read
+		 * this variable, and program the HW's FW_IDX reg with the value
+		 * of this shadow register
+		 * With reorder offload:
+		 * points to the end of the available free rx buffers
+		 */
+		struct {
+			uint32_t *vaddr;
+			qdf_dma_addr_t paddr;
+			qdf_dma_mem_context(memctx);
+		} alloc_idx;
+
+		/*
+		 * sw_rd_idx -
+		 * where HTT SW has processed bufs filled by rx MAC DMA
+		 */
+		struct {
+			unsigned int msdu_desc;
+			unsigned int msdu_payld;
+		} sw_rd_idx;
+
+		/*
+		 * refill_retry_timer - timer triggered when the ring is not
+		 * refilled to the level expected
+		 */
+		qdf_timer_t refill_retry_timer;
+
+		/*
+		 * refill_ref_cnt - ref cnt for Rx buffer replenishment - this
+		 * variable is used to guarantee that only one thread tries
+		 * to replenish Rx ring.
+		 */
+		qdf_atomic_t   refill_ref_cnt;
+		qdf_spinlock_t refill_lock;
+		qdf_atomic_t   refill_debt;
+#ifdef DEBUG_DMA_DONE
+		uint32_t dbg_initial_msdu_payld;
+		uint32_t dbg_mpdu_range;
+		uint32_t dbg_mpdu_count;
+		uint32_t dbg_ring_idx;
+		uint32_t dbg_refill_cnt;
+		uint32_t dbg_sync_success;
+#endif
+#ifdef HTT_RX_RESTORE
+		int rx_reset;
+		uint8_t htt_rx_restore;
+#endif
+		qdf_spinlock_t rx_hash_lock;
+		struct htt_rx_hash_bucket **hash_table;
+		uint32_t listnode_offset;
+		bool smmu_map;
+	} rx_ring;
+
+#ifndef CONFIG_HL_SUPPORT
+	struct {
+		qdf_atomic_t fill_cnt;          /* # of buffers in pool */
+		qdf_atomic_t refill_low_mem;    /* if set refill the ring */
+		qdf_nbuf_t *netbufs_ring;
+		qdf_spinlock_t rx_buff_pool_lock;
+	} rx_buff_pool;
+#endif
+
+#ifdef CONFIG_HL_SUPPORT
+	int rx_desc_size_hl;
+#endif
+	long rx_fw_desc_offset;
+	int rx_mpdu_range_offset_words;
+	int rx_ind_msdu_byte_idx;
+
+	struct {
+		int size;       /* of each HTT tx desc */
+		uint16_t pool_elems;
+		uint16_t alloc_cnt;
+		struct qdf_mem_multi_page_t desc_pages;
+		uint32_t *freelist;
+		qdf_dma_mem_context(memctx);
+	} tx_descs;
+#if defined(HELIUMPLUS)
+	struct {
+		int size; /* of each Fragment/MSDU-Ext descriptor */
+		int pool_elems;
+		struct qdf_mem_multi_page_t desc_pages;
+		qdf_dma_mem_context(memctx);
+	} frag_descs;
+#endif /* defined(HELIUMPLUS) */
+
+	int download_len;
+	void (*tx_send_complete_part2)(void *pdev, A_STATUS status,
+				       qdf_nbuf_t msdu, uint16_t msdu_id);
+
+	HTT_TX_MUTEX_TYPE htt_tx_mutex;
+	HTT_TX_MUTEX_TYPE credit_mutex;
+
+	struct {
+		int htc_err_cnt;
+	} stats;
+#ifdef CONFIG_HL_SUPPORT
+	int cur_seq_num_hl;
+#endif
+	struct htt_tx_mgmt_desc_ctxt tx_mgmt_desc_ctxt;
+	struct targetdef_s *targetdef;
+	struct ce_reg_def *target_ce_def;
+
+	struct htt_ipa_uc_tx_resource_t ipa_uc_tx_rsc;
+	struct htt_ipa_uc_rx_resource_t ipa_uc_rx_rsc;
+	int is_ipa_uc_enabled;
+
+	struct htt_tx_credit_t htt_tx_credit;
+
+#ifdef DEBUG_RX_RING_BUFFER
+	struct rx_buf_debug *rx_buff_list;
+	qdf_spinlock_t       rx_buff_list_lock;
+	int rx_buff_index;
+	int rx_buff_posted_cum;
+	int rx_buff_recvd_cum;
+	int rx_buff_recvd_err;
+#endif
+	/*
+	 * Counters below are being invoked from functions defined outside of
+	 * DEBUG_RX_RING_BUFFER
+	 */
+	int rx_buff_debt_invoked;
+	int rx_buff_fill_n_invoked;
+	int refill_retry_timer_starts;
+	int refill_retry_timer_calls;
+	int refill_retry_timer_doubles;
+
+	/* callback function for packetdump */
+	tp_rx_pkt_dump_cb rx_pkt_dump_cb;
+
+	struct mon_channel mon_ch_info;
+};
+
+#define HTT_EPID_GET(_htt_pdev_hdl)  \
+	(((struct htt_pdev_t *)(_htt_pdev_hdl))->htc_tx_endpoint)
+
+#if defined(HELIUMPLUS)
+#define HTT_WIFI_IP(pdev, x, y) (((pdev)->wifi_ip_ver.major == (x)) &&	\
+				 ((pdev)->wifi_ip_ver.minor == (y)))
+
+#define HTT_SET_WIFI_IP(pdev, x, y) (((pdev)->wifi_ip_ver.major = (x)) && \
+				     ((pdev)->wifi_ip_ver.minor = (y)))
+#endif /* defined(HELIUMPLUS) */
+
+#endif /* _HTT_TYPES__H_ */
diff --git a/core/dp/htt/rx_desc.h b/core/dp/htt/rx_desc.h
new file mode 100644
index 0000000..cd31a86
--- /dev/null
+++ b/core/dp/htt/rx_desc.h
@@ -0,0 +1,534 @@
+/*
+ * Copyright (c) 2011-2015, 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.
+ */
+
+#ifndef _RX_DESC_H_
+#define _RX_DESC_H_
+
+/*
+ * REMIND: Copy one of rx_desc related structures here for export,
+ *         hopes they are always the same between Peregrine and Rome in future
+ */
+struct rx_attention {
+	volatile
+	uint32_t first_mpdu:1, /* [0] */
+		last_mpdu:1, /* [1] */
+		mcast_bcast:1, /* [2] */
+		peer_idx_invalid:1, /* [3] */
+		peer_idx_timeout:1, /* [4] */
+		power_mgmt:1, /* [5] */
+		non_qos:1, /* [6] */
+		null_data:1, /* [7] */
+		mgmt_type:1, /* [8] */
+		ctrl_type:1, /* [9] */
+		more_data:1, /* [10] */
+		eosp:1, /* [11] */
+		u_apsd_trigger:1, /* [12] */
+		fragment:1, /* [13] */
+		order:1, /* [14] */
+		classification:1, /* [15] */
+		overflow_err:1, /* [16] */
+		msdu_length_err:1, /* [17] */
+		tcp_udp_chksum_fail:1, /* [18] */
+		ip_chksum_fail:1, /* [19] */
+		sa_idx_invalid:1, /* [20] */
+		da_idx_invalid:1, /* [21] */
+		sa_idx_timeout:1, /* [22] */
+		da_idx_timeout:1, /* [23] */
+		encrypt_required:1, /* [24] */
+		directed:1, /* [25] */
+		buffer_fragment:1, /* [26] */
+		mpdu_length_err:1, /* [27] */
+		tkip_mic_err:1, /* [28] */
+		decrypt_err:1, /* [29] */
+		fcs_err:1, /* [30] */
+		msdu_done:1; /* [31] */
+};
+
+struct rx_frag_info {
+	volatile
+	uint32_t ring0_more_count:8,   /* [7:0] */
+		ring1_more_count:8, /* [15:8] */
+		ring2_more_count:8, /* [23:16] */
+		ring3_more_count:8; /* [31:24] */
+	volatile
+	uint32_t ring4_more_count:8, /* [7:0] */
+		ring5_more_count:8, /* [15:8] */
+		ring6_more_count:8, /* [23:16] */
+		ring7_more_count:8; /* [31:24] */
+};
+
+struct rx_msdu_start {
+	volatile
+	uint32_t msdu_length:14, /* [13:0] */
+#if defined(HELIUMPLUS)
+		l3_offset:7, /* [20:14] */
+		ipsec_ah:1, /* [21] */
+		reserved_0a:2, /* [23:22] */
+		l4_offset:7, /* [30:24] */
+		ipsec_esp:1; /* [31] */
+#else
+		ip_offset:6, /* [19:14] */
+		ring_mask:4, /* [23:20] */
+		tcp_udp_offset:7, /* [30:24] */
+		reserved_0c:1; /* [31] */
+#endif /* defined(HELIUMPLUS) */
+#if defined(HELIUMPLUS)
+	volatile uint32_t flow_id_toeplitz:32; /* [31:0] */
+#else
+	volatile uint32_t flow_id_crc:32; /* [31:0] */
+#endif /* defined(HELIUMPLUS) */
+	volatile
+	uint32_t msdu_number:8, /* [7:0] */
+		decap_format:2, /* [9:8] */
+		ipv4_proto:1, /* [10] */
+		ipv6_proto:1, /* [11] */
+		tcp_proto:1, /* [12] */
+		udp_proto:1, /* [13] */
+		ip_frag:1, /* [14] */
+		tcp_only_ack:1, /* [15] */
+		sa_idx:11, /* [26:16] */
+		reserved_2b:5; /* [31:27] */
+#if defined(HELIUMPLUS)
+	volatile
+	uint32_t da_idx:11, /* [10:0] */
+		da_is_bcast_mcast:1, /* [11] */
+		reserved_3a:4, /* [15:12] */
+		ip4_protocol_ip6_next_header:8, /* [23:16] */
+		ring_mask:8; /* [31:24] */
+	volatile uint32_t toeplitz_hash_2_or_4:32; /* [31:0] */
+#endif /* defined(HELIUMPLUS) */
+};
+
+struct rx_msdu_end {
+	volatile
+	uint32_t ip_hdr_chksum:16, /* [15:0] */
+		tcp_udp_chksum:16; /* [31:16] */
+	volatile
+	uint32_t key_id_octet:8, /* [7:0] */
+#if defined(HELIUMPLUS)
+		classification_rule:6, /* [13:8] */
+		classify_not_done_truncate:1, /* [14] */
+		classify_not_done_cce_dis:1, /* [15] */
+#else
+		classification_filter:8, /* [15:8] */
+#endif /* defined(HELIUMPLUS) */
+	ext_wapi_pn_63_48:16; /* [31:16] */
+	volatile uint32_t ext_wapi_pn_95_64:32; /* [31:0] */
+	volatile uint32_t ext_wapi_pn_127_96:32; /* [31:0] */
+	volatile
+	uint32_t reported_mpdu_length:14, /* [13:0] */
+		first_msdu:1, /* [14] */
+		last_msdu:1, /* [15] */
+#if defined(HELIUMPLUS)
+		sa_idx_timeout:1, /* [16] */
+		da_idx_timeout:1, /* [17] */
+		msdu_limit_error:1, /* [18] */
+		classify_ring_mask:8, /* [26:19] */
+#endif /* defined(HELIUMPLUS) */
+		reserved_3a:3, /* [29:27] */
+		pre_delim_err:1, /* [30] */
+		reserved_3b:1; /* [31] */
+#if defined(HELIUMPLUS)
+	volatile uint32_t ipv6_options_crc:32;
+	volatile uint32_t tcp_seq_number:32;
+	volatile uint32_t tcp_ack_number:32;
+	volatile
+	uint32_t tcp_flag:9, /* [8:0] */
+		lro_eligible:1, /* [9] */
+		l3_header_padding:3, /* [12:10] */
+		reserved_8a:3, /* [15:13] */
+		window_size:16; /* [31:16] */
+	volatile
+	uint32_t da_offset:6, /* [5:0] */
+		sa_offset:6, /* [11:6] */
+		da_offset_valid:1, /* [12] */
+		sa_offset_valid:1, /* [13] */
+		type_offset:7, /* [20:14] */
+		reserved_9a:11; /* [31:21] */
+	volatile uint32_t rule_indication_31_0:32;
+	volatile uint32_t rule_indication_63_32:32;
+	volatile uint32_t rule_indication_95_64:32;
+	volatile uint32_t rule_indication_127_96:32;
+#endif /* defined(HELIUMPLUS) */
+};
+
+struct rx_mpdu_end {
+	volatile
+	uint32_t reserved_0:13, /* [12:0] */
+		overflow_err:1, /* [13] */
+		last_mpdu:1, /* [14] */
+		post_delim_err:1, /* [15] */
+		post_delim_cnt:12, /* [27:16] */
+		mpdu_length_err:1, /* [28] */
+		tkip_mic_err:1, /* [29] */
+		decrypt_err:1, /* [30] */
+		fcs_err:1; /* [31] */
+};
+
+
+#if defined(HELIUMPLUS)
+
+struct rx_mpdu_start {
+	volatile
+	uint32_t peer_idx:11, /* [10:0] */
+		fr_ds:1, /* [11] */
+		to_ds:1, /* [12] */
+		encrypted:1, /* [13] */
+		retry:1, /* [14] */
+		reserved:1, /* [15] */
+		seq_num:12, /* [27:16] */
+		encrypt_type:4; /* [31:28] */
+	volatile uint32_t pn_31_0:32; /* [31:0] */
+	volatile
+	uint32_t pn_47_32:16, /* [15:0] */
+		toeplitz_hash:2, /* [17:16] */
+		reserved_2:10, /* [27:18] */
+		tid:4; /* [31:28] */
+};
+
+
+struct rx_ppdu_start {
+	volatile
+	uint32_t rssi_pri_chain0:8, /* [7:0] */
+		rssi_sec20_chain0:8, /* [15:8] */
+		rssi_sec40_chain0:8, /* [23:16] */
+		rssi_sec80_chain0:8; /* [31:24] */
+	volatile
+	uint32_t rssi_pri_chain1:8, /* [7:0] */
+		rssi_sec20_chain1:8, /* [15:8] */
+		rssi_sec40_chain1:8, /* [23:16] */
+		rssi_sec80_chain1:8; /* [31:24] */
+	volatile
+	uint32_t rssi_pri_chain2:8, /* [7:0] */
+		rssi_sec20_chain2:8, /* [15:8] */
+		rssi_sec40_chain2:8, /* [23:16] */
+		rssi_sec80_chain2:8; /* [31:24] */
+	volatile
+	uint32_t rssi_pri_chain3:8, /* [7:0] */
+		rssi_sec20_chain3:8, /* [15:8] */
+		rssi_sec40_chain3:8, /* [23:16] */
+		rssi_sec80_chain3:8; /* [31:24] */
+	volatile
+	uint32_t rssi_comb:8, /* [7:0] */
+		bandwidth:3, /* [10:8] */
+		reserved_4a:5, /* [15:11] */
+		rssi_comb_ht:8, /* [23:16] */
+		reserved_4b:8; /* [31:24] */
+	volatile
+	uint32_t l_sig_rate:4, /*[3:0] */
+		l_sig_rate_select:1, /* [4] */
+		l_sig_length:12, /* [16:5] */
+		l_sig_parity:1, /* [17] */
+		l_sig_tail:6, /* [23:18] */
+		preamble_type:8; /* [31:24] */
+	volatile
+	uint32_t ht_sig_vht_sig_ah_sig_a_1:24, /* [23:0] */
+		captured_implicit_sounding:1, /* [24] */
+		reserved_6:7; /* [31:25] */
+	volatile
+	uint32_t ht_sig_vht_sig_ah_sig_a_2:24, /* [23:0] */
+		reserved_7:8; /* [31:24] */
+	volatile uint32_t vht_sig_b:32; /* [31:0] */
+	volatile
+	uint32_t service:16, /* [15:0] */
+		reserved_9:16; /* [31:16] */
+};
+
+#define VHT_SIG_A_1(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_ah_sig_a_1)
+#define VHT_SIG_A_2(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_ah_sig_a_2)
+#define TSF_TIMESTAMP(rx_desc) \
+((rx_desc)->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32)
+
+struct rx_location_info {
+	volatile
+	uint32_t rtt_fac_legacy:14, /* [13:0] */
+		rtt_fac_legacy_status:1, /* [14] */
+		rtt_fac_vht:14, /* [28:15] */
+		rtt_fac_vht_status:1, /* [29] */
+		rtt_cfr_status:1, /* [30] */
+		rtt_cir_status:1; /* [31] */
+	volatile
+	uint32_t rtt_fac_sifs:10, /* [9:0] */
+		rtt_fac_sifs_status:2, /* [11:10] */
+		rtt_channel_dump_size:11, /* [22:12] */
+		rtt_mac_phy_phase:2, /* [24:23] */
+		rtt_hw_ifft_mode:1, /* [25] */
+		rtt_btcf_status:1, /* [26] */
+		rtt_preamble_type:2, /* [28:27] */
+		rtt_pkt_bw:2, /* [30:29] */
+		rtt_gi_type:1; /* [31] */
+	volatile
+	uint32_t rtt_mcs_rate:4, /* [3:0] */
+		rtt_strongest_chain:2, /* [5:4] */
+		rtt_phase_jump:7, /* [12:6] */
+		rtt_rx_chain_mask:4, /* [16:13] */
+		rtt_tx_data_start_x_phase:1, /* [17] */
+		reserved_2:13, /* [30:18] */
+		rx_location_info_valid:1; /* [31] */
+};
+
+struct rx_pkt_end {
+	volatile
+	uint32_t rx_success:1, /* [0] */
+		reserved_0a:2, /* [2:1] */
+		error_tx_interrupt_rx:1, /* [3] */
+		error_ofdm_power_drop:1, /* [4] */
+		error_ofdm_restart:1, /* [5] */
+		error_cck_power_drop:1, /* [6] */
+		error_cck_restart:1, /* [7] */
+		reserved_0b:24; /* [31:8] */
+	volatile uint32_t phy_timestamp_1_lower_32:32; /* [31:0] */
+	volatile uint32_t phy_timestamp_1_upper_32:32; /* [31:0] */
+	volatile uint32_t phy_timestamp_2_lower_32:32; /* [31:0] */
+	volatile uint32_t phy_timestamp_2_upper_32:32; /* [31:0] */
+	struct rx_location_info rx_location_info;
+};
+
+struct rx_phy_ppdu_end {
+	volatile
+	uint32_t reserved_0a:2, /* [1:0] */
+		error_radar:1, /* [2] */
+		error_rx_abort:1, /* [3] */
+		error_rx_nap:1, /* [4] */
+		error_ofdm_timing:1, /* [5] */
+		error_ofdm_signal_parity:1, /* [6] */
+		error_ofdm_rate_illegal:1, /* [7] */
+		error_ofdm_length_illegal:1, /* [8] */
+		error_ppdu_ofdm_restart:1, /* [9] */
+		error_ofdm_service:1, /* [10] */
+		error_ppdu_ofdm_power_drop:1, /* [11] */
+		error_cck_blocker:1, /* [12] */
+		error_cck_timing:1, /* [13] */
+		error_cck_header_crc:1, /* [14] */
+		error_cck_rate_illegal:1, /* [15] */
+		error_cck_length_illegal:1, /* [16] */
+		error_ppdu_cck_restart:1, /* [17] */
+		error_cck_service:1, /* [18] */
+		error_ppdu_cck_power_drop:1, /* [19] */
+		error_ht_crc_err:1, /* [20] */
+		error_ht_length_illegal:1, /* [21] */
+		error_ht_rate_illegal:1, /* [22] */
+		error_ht_zlf:1, /* [23] */
+		error_false_radar_ext:1, /* [24] */
+		error_green_field:1, /* [25] */
+		error_spectral_scan:1, /* [26] */
+		error_rx_bw_gt_dyn_bw:1, /* [27] */
+		error_leg_ht_mismatch:1, /* [28] */
+		error_vht_crc_error:1, /* [29] */
+		error_vht_siga_unsupported:1, /* [30] */
+		error_vht_lsig_len_invalid:1; /* [31] */
+	volatile
+	uint32_t error_vht_ndp_or_zlf:1, /* [0] */
+		error_vht_nsym_lt_zero:1, /* [1] */
+		error_vht_rx_extra_symbol_mismatch:1, /* [2] */
+		error_vht_rx_skip_group_id0:1, /* [3] */
+		error_vht_rx_skip_group_id1to62:1, /* [4] */
+		error_vht_rx_skip_group_id63:1, /* [5] */
+		error_ofdm_ldpc_decoder_disabled:1, /* [6] */
+		error_defer_nap:1, /* [7] */
+		error_fdomain_timeout:1, /* [8] */
+		error_lsig_rel_check:1, /* [9] */
+		error_bt_collision:1, /* [10] */
+		error_unsupported_mu_feedback:1, /* [11] */
+		error_ppdu_tx_interrupt_rx:1, /* [12] */
+		error_rx_unsupported_cbf:1, /* [13] */
+		reserved_1:18; /* [31:14] */
+};
+
+struct rx_timing_offset {
+	volatile
+	uint32_t timing_offset:12, /* [11:0] */
+		reserved:20; /* [31:12] */
+};
+
+struct rx_ppdu_end {
+	volatile uint32_t evm_p0:32;
+	volatile uint32_t evm_p1:32;
+	volatile uint32_t evm_p2:32;
+	volatile uint32_t evm_p3:32;
+	volatile uint32_t evm_p4:32;
+	volatile uint32_t evm_p5:32;
+	volatile uint32_t evm_p6:32;
+	volatile uint32_t evm_p7:32;
+	volatile uint32_t evm_p8:32;
+	volatile uint32_t evm_p9:32;
+	volatile uint32_t evm_p10:32;
+	volatile uint32_t evm_p11:32;
+	volatile uint32_t evm_p12:32;
+	volatile uint32_t evm_p13:32;
+	volatile uint32_t evm_p14:32;
+	volatile uint32_t evm_p15:32;
+	volatile uint32_t reserved_16:32;
+	volatile uint32_t reserved_17:32;
+	volatile uint32_t wb_timestamp_lower_32:32;
+	volatile uint32_t wb_timestamp_upper_32:32;
+	struct rx_pkt_end rx_pkt_end;
+	struct rx_phy_ppdu_end rx_phy_ppdu_end;
+	struct rx_timing_offset rx_timing_offset;
+	volatile
+	uint32_t rx_antenna:24, /* [23:0] */
+		tx_ht_vht_ack:1, /* [24] */
+		rx_pkt_end_valid:1, /* [25] */
+		rx_phy_ppdu_end_valid:1, /* [26] */
+		rx_timing_offset_valid:1, /* [27] */
+		bb_captured_channel:1, /* [28] */
+		unsupported_mu_nc:1, /* [29] */
+		otp_txbf_disable:1, /* [30] */
+		reserved_31:1; /* [31] */
+	volatile
+	uint32_t coex_bt_tx_from_start_of_rx:1, /* [0] */
+		coex_bt_tx_after_start_of_rx:1, /* [1] */
+		coex_wan_tx_from_start_of_rx:1, /* [2] */
+		coex_wan_tx_after_start_of_rx:1, /* [3] */
+		coex_wlan_tx_from_start_of_rx:1, /* [4] */
+		coex_wlan_tx_after_start_of_rx:1, /* [5] */
+		mpdu_delimiter_errors_seen:1, /* [6] */
+		ftm:1, /* [7] */
+		ftm_dialog_token:8, /* [15:8] */
+		ftm_follow_up_dialog_token:8, /* [23:16] */
+		reserved_32:8; /* [31:24] */
+	volatile
+	uint32_t before_mpdu_cnt_passing_fcs:8, /* [7:0] */
+		before_mpdu_cnt_failing_fcs:8, /* [15:8] */
+		after_mpdu_cnt_passing_fcs:8, /* [23:16] */
+		after_mpdu_cnt_failing_fcs:8; /* [31:24] */
+	volatile uint32_t phy_timestamp_tx_lower_32:32; /* [31:0] */
+	volatile uint32_t phy_timestamp_tx_upper_32:32; /* [31:0] */
+	volatile
+	uint32_t bb_length:16, /* [15:0] */
+		bb_data:1, /* [16] */
+		peer_idx_valid:1, /* [17] */
+		peer_idx:11, /* [28:18] */
+		reserved_26:2, /* [30:29] */
+		ppdu_done:1; /* [31] */
+};
+#else
+struct rx_ppdu_start {
+	volatile
+	uint32_t rssi_chain0_pri20:8, /* [7:0] */
+		rssi_chain0_sec20:8, /* [15:8] */
+		rssi_chain0_sec40:8, /* [23:16] */
+		rssi_chain0_sec80:8; /* [31:24] */
+	volatile
+	uint32_t rssi_chain1_pri20:8, /* [7:0] */
+		rssi_chain1_sec20:8, /* [15:8] */
+		rssi_chain1_sec40:8, /* [23:16] */
+		rssi_chain1_sec80:8; /* [31:24] */
+	volatile
+	uint32_t rssi_chain2_pri20:8, /* [7:0] */
+		rssi_chain2_sec20:8, /* [15:8] */
+		rssi_chain2_sec40:8, /* [23:16] */
+		rssi_chain2_sec80:8; /* [31:24] */
+	volatile
+	uint32_t rssi_chain3_pri20:8, /* [7:0] */
+		rssi_chain3_sec20:8, /* [15:8] */
+		rssi_chain3_sec40:8, /* [23:16] */
+		rssi_chain3_sec80:8; /* [31:24] */
+	volatile
+	uint32_t rssi_comb:8,  /* [7:0] */
+		reserved_4a:16, /* [23:8] */
+		is_greenfield:1, /* [24] */
+		reserved_4b:7; /* [31:25] */
+	volatile
+	uint32_t l_sig_rate:4, /* [3:0] */
+		l_sig_rate_select:1, /* [4] */
+		l_sig_length:12, /* [16:5] */
+		l_sig_parity:1, /* [17] */
+		l_sig_tail:6, /* [23:18] */
+		preamble_type:8; /* [31:24] */
+	volatile
+	uint32_t ht_sig_vht_sig_a_1:24, /* [23:0] */
+		reserved_6:8; /* [31:24] */
+	volatile
+	uint32_t ht_sig_vht_sig_a_2:24, /* [23:0] */
+		txbf_h_info:1, /* [24] */
+		reserved_7:7; /* [31:25] */
+	volatile
+	uint32_t vht_sig_b:29, /* [28:0] */
+		reserved_8:3; /* [31:29] */
+	volatile
+	uint32_t service:16,   /* [15:0] */
+		reserved_9:16; /* [31:16] */
+};
+
+#define VHT_SIG_A_1(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_a_1)
+#define VHT_SIG_A_2(rx_desc) ((rx_desc)->ppdu_start.ht_sig_vht_sig_a_2)
+
+#define TSF_TIMESTAMP(rx_desc) ((rx_desc)->ppdu_end.tsf_timestamp)
+
+struct rx_mpdu_start {
+	volatile
+	uint32_t peer_idx:11,  /* [10:0] */
+		fr_ds:1, /* [11] */
+		to_ds:1, /* [12] */
+		encrypted:1, /* [13] */
+		retry:1, /* [14] */
+		txbf_h_info:1, /* [15] */
+		seq_num:12, /* [27:16] */
+		encrypt_type:4; /* [31:28] */
+	volatile uint32_t pn_31_0:32;   /* [31:0] */
+	volatile
+	uint32_t pn_47_32:16,  /* [15:0] */
+		directed:1, /* [16] */
+		reserved_2:11, /* [27:17] */
+		tid:4; /* [31:28] */
+};
+
+struct rx_ppdu_end {
+	volatile uint32_t evm_p0:32;    /* [31:0] */
+	volatile uint32_t evm_p1:32;    /* [31:0] */
+	volatile uint32_t evm_p2:32;    /* [31:0] */
+	volatile uint32_t evm_p3:32;    /* [31:0] */
+	volatile uint32_t evm_p4:32;    /* [31:0] */
+	volatile uint32_t evm_p5:32;    /* [31:0] */
+	volatile uint32_t evm_p6:32;    /* [31:0] */
+	volatile uint32_t evm_p7:32;    /* [31:0] */
+	volatile uint32_t evm_p8:32;    /* [31:0] */
+	volatile uint32_t evm_p9:32;    /* [31:0] */
+	volatile uint32_t evm_p10:32;   /* [31:0] */
+	volatile uint32_t evm_p11:32;   /* [31:0] */
+	volatile uint32_t evm_p12:32;   /* [31:0] */
+	volatile uint32_t evm_p13:32;   /* [31:0] */
+	volatile uint32_t evm_p14:32;   /* [31:0] */
+	volatile uint32_t evm_p15:32;   /* [31:0] */
+	volatile uint32_t tsf_timestamp:32; /* [31:0] */
+	volatile uint32_t wb_timestamp:32; /* [31:0] */
+	volatile
+	uint32_t locationing_timestamp:8, /* [7:0] */
+		phy_err_code:8, /* [15:8] */
+		phy_err:1, /* [16] */
+		rx_location:1, /* [17] */
+		txbf_h_info:1, /* [18] */
+		reserved_18:13; /* [31:19] */
+	volatile
+	uint32_t rx_antenna:24, /* [23:0] */
+		tx_ht_vht_ack:1, /* [24] */
+		bb_captured_channel:1, /* [25] */
+		reserved_19:6; /* [31:26] */
+	volatile
+	uint32_t rtt_correction_value:24, /* [23:0] */
+		reserved_20:7, /* [30:24] */
+		rtt_normal_mode:1; /* [31] */
+	volatile
+	uint32_t bb_length:16, /* [15:0] */
+		reserved_21:15, /* [30:16] */
+		ppdu_done:1; /* [31] */
+};
+#endif /* defined(HELIUMPLUS) */
+
+#endif /*_RX_DESC_H_*/
diff --git a/core/dp/ol/inc/cfg_legacy_dp.h b/core/dp/ol/inc/cfg_legacy_dp.h
new file mode 100644
index 0000000..b6053b1
--- /dev/null
+++ b/core/dp/ol/inc/cfg_legacy_dp.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __CFG_LEGACY_DP
+#define __CFG_LEGACY_DP
+
+#include "cfg_define.h"
+#include "cfg_converged.h"
+#include "qdf_types.h"
+
+/*
+ * <ini>
+ * gEnableFlowSteering - Enable rx traffic flow steering
+ * @Default: false
+ *
+ * Enable Rx traffic flow steering to enable Rx interrupts on multiple CEs based
+ * on the flows. Different CEs<==>different IRQs<==>probably different CPUs.
+ * Parallel Rx paths.
+ * 1 - enable  0 - disable
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+ #define CFG_DP_FLOW_STEERING_ENABLED \
+		CFG_INI_BOOL( \
+		"gEnableFlowSteering", \
+		false, \
+		"")
+
+#define CFG_DP_CE_CLASSIFY_ENABLE \
+		CFG_INI_BOOL("gCEClassifyEnable", \
+		true, "enable CE classify")
+
+#define CFG_LEGACY_DP_ALL \
+	CFG(CFG_DP_FLOW_STEERING_ENABLED) \
+	CFG(CFG_DP_CE_CLASSIFY_ENABLE)
+
+#endif
diff --git a/core/dp/ol/inc/ol_cfg.h b/core/dp/ol/inc/ol_cfg.h
new file mode 100644
index 0000000..239c1a9
--- /dev/null
+++ b/core/dp/ol/inc/ol_cfg.h
@@ -0,0 +1,727 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#ifndef _OL_CFG__H_
+#define _OL_CFG__H_
+
+#include <qdf_types.h>          /* uint32_t */
+#include <cdp_txrx_cmn.h>       /* ol_pdev_handle */
+#include <cds_ieee80211_common.h>   /* ieee80211_qosframe_htc_addr4 */
+#include <enet.h>               /* LLC_SNAP_HDR_LEN */
+#if defined(CONFIG_HL_SUPPORT)
+#include "wlan_tgt_def_config_hl.h"
+#else
+#include "wlan_tgt_def_config.h"
+#endif
+#include "ol_txrx_ctrl_api.h"   /* txrx_pdev_cfg_param_t */
+#include <cdp_txrx_handle.h>
+
+/**
+ * @brief format of data frames delivered to/from the WLAN driver by/to the OS
+ */
+enum wlan_frm_fmt {
+	wlan_frm_fmt_unknown,
+	wlan_frm_fmt_raw,
+	wlan_frm_fmt_native_wifi,
+	wlan_frm_fmt_802_3,
+};
+
+/* Throttle period Different level Duty Cycle values*/
+#define THROTTLE_DUTY_CYCLE_LEVEL0 (0)
+#define THROTTLE_DUTY_CYCLE_LEVEL1 (50)
+#define THROTTLE_DUTY_CYCLE_LEVEL2 (75)
+#define THROTTLE_DUTY_CYCLE_LEVEL3 (94)
+
+struct wlan_ipa_uc_rsc_t {
+	u8 uc_offload_enabled;
+	u32 tx_max_buf_cnt;
+	u32 tx_buf_size;
+	u32 rx_ind_ring_size;
+	u32 tx_partition_base;
+};
+
+/* Config parameters for txrx_pdev */
+struct txrx_pdev_cfg_t {
+	u8 is_high_latency;
+	u8 defrag_timeout_check;
+	u8 rx_pn_check;
+	u8 pn_rx_fwd_check;
+	u8 host_addba;
+	u8 tx_free_at_download;
+	u8 rx_fwd_inter_bss;
+	u32 max_thruput_mbps;
+	u32 target_tx_credit;
+	u32 vow_config;
+	u32 tx_download_size;
+	u32 max_peer_id;
+	u32 max_vdev;
+	u32 max_nbuf_frags;
+	u32 throttle_period_ms;
+	u8 dutycycle_level[4];
+	enum wlan_frm_fmt frame_type;
+	u8 rx_fwd_disabled;
+	u8 is_packet_log_enabled;
+	u8 is_full_reorder_offload;
+#ifdef WLAN_FEATURE_TSF_PLUS
+	u8 is_ptp_rx_opt_enabled;
+#endif
+	struct wlan_ipa_uc_rsc_t ipa_uc_rsc;
+	bool ip_tcp_udp_checksum_offload;
+	bool enable_rxthread;
+	bool ce_classify_enabled;
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+	uint32_t tx_flow_stop_queue_th;
+	uint32_t tx_flow_start_queue_offset;
+#endif
+	bool flow_steering_enabled;
+	/*
+	 * To track if credit reporting through
+	 * HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND is enabled/disabled.
+	 * In Genoa(QCN7605) credits are reported through
+	 * HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND only.
+	 */
+	u8 credit_update_enabled;
+	struct ol_tx_sched_wrr_ac_specs_t ac_specs[TX_WMM_AC_NUM];
+	bool gro_enable;
+	bool tso_enable;
+	bool lro_enable;
+	bool enable_data_stall_detection;
+	bool enable_flow_steering;
+	bool disable_intra_bss_fwd;
+	/* IPA Micro controller data path offload TX buffer size */
+	uint32_t uc_tx_buffer_size;
+	/* IPA Micro controller data path offload RX indication ring count */
+	uint32_t uc_rx_indication_ring_count;
+	/* IPA Micro controller data path offload TX partition base */
+	uint32_t uc_tx_partition_base;
+};
+
+/**
+ * ol_tx_set_flow_control_parameters() - set flow control parameters
+ * @cfg_ctx: cfg context
+ * @cfg_param: cfg parameters
+ *
+ * Return: none
+ */
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+void ol_tx_set_flow_control_parameters(struct cdp_cfg *cfg_ctx,
+				       struct txrx_pdev_cfg_param_t *cfg_param);
+#else
+static inline
+void ol_tx_set_flow_control_parameters(struct cdp_cfg *cfg_ctx,
+				       struct txrx_pdev_cfg_param_t *cfg_param)
+{
+}
+#endif
+
+/**
+ * ol_pdev_cfg_attach - setup configuration parameters
+ * @osdev: OS handle needed as an argument for some OS primitives
+ * @cfg_param: configuration parameters
+ *
+ * Allocation configuration context that will be used across data path
+ *
+ * Return: the control device object
+ */
+struct cdp_cfg *ol_pdev_cfg_attach(qdf_device_t osdev, void *pcfg_param);
+
+/**
+ * @brief Specify whether the system is high-latency or low-latency.
+ * @details
+ *  Indicate whether the system is operating in high-latency (message
+ *  based, e.g. USB) mode or low-latency (memory-mapped, e.g. PCIe) mode.
+ *  Some chips support just one type of host / target interface.
+ *  Other chips support both LL and HL interfaces (e.g. PCIe and USB),
+ *  so the selection will be made based on which bus HW is present, or
+ *  which is preferred if both are present.
+ *
+ * @param pdev - handle to the physical device
+ * @return 1 -> high-latency -OR- 0 -> low-latency
+ */
+int ol_cfg_is_high_latency(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief Specify whether credit reporting through
+ * HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND is enabled by default.
+ * In Genoa credits are reported only through
+ * HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND
+ * @details
+ * @param pdev - handle to the physical device
+ * @return 1 -> enabled -OR- 0 -> disabled
+ */
+int ol_cfg_is_credit_update_enabled(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief Specify the range of peer IDs.
+ * @details
+ *  Specify the maximum peer ID.  This is the maximum number of peers,
+ *  minus one.
+ *  This is used by the host to determine the size of arrays indexed by
+ *  peer ID.
+ *
+ * @param pdev - handle to the physical device
+ * @return maximum peer ID
+ */
+int ol_cfg_max_peer_id(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief Specify the max number of virtual devices within a physical device.
+ * @details
+ *  Specify how many virtual devices may exist within a physical device.
+ *
+ * @param pdev - handle to the physical device
+ * @return maximum number of virtual devices
+ */
+int ol_cfg_max_vdevs(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief Check whether host-side rx PN check is enabled or disabled.
+ * @details
+ *  Choose whether to allocate rx PN state information and perform
+ *  rx PN checks (if applicable, based on security type) on the host.
+ *  If the rx PN check is specified to be done on the host, the host SW
+ *  will determine which peers are using a security type (e.g. CCMP) that
+ *  requires a PN check.
+ *
+ * @param pdev - handle to the physical device
+ * @return 1 -> host performs rx PN check -OR- 0 -> no host-side rx PN check
+ */
+int ol_cfg_rx_pn_check(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief Check whether host-side rx forwarding is enabled or disabled.
+ * @details
+ *  Choose whether to check whether to forward rx frames to tx on the host.
+ *  For LL systems, this rx -> tx host-side forwarding check is typically
+ *  enabled.
+ *  For HL systems, the rx -> tx forwarding check is typically done on the
+ *  target.  However, even in HL systems, the host-side rx -> tx forwarding
+ *  will typically be enabled, as a second-tier safety net in case the
+ *  target doesn't have enough memory to store all rx -> tx forwarded frames.
+ *
+ * @param pdev - handle to the physical device
+ * @return 1 -> host does rx->tx forward -OR- 0 -> no host-side rx->tx forward
+ */
+int ol_cfg_rx_fwd_check(struct cdp_cfg *cfg_pdev);
+
+/**
+ * ol_set_cfg_rx_fwd_disabled - set rx fwd disable/enable
+ *
+ * @pdev - handle to the physical device
+ * @disable_rx_fwd 1 -> no rx->tx forward -> rx->tx forward
+ *
+ * Choose whether to forward rx frames to tx (where applicable) within the
+ * WLAN driver, or to leave all forwarding up to the operating system.
+ * Currently only intra-bss fwd is supported.
+ *
+ */
+void ol_set_cfg_rx_fwd_disabled(struct cdp_cfg *ppdev, uint8_t disable_rx_fwd);
+
+/**
+ * ol_set_cfg_packet_log_enabled - Set packet log config in HTT
+ * config based on CFG ini configuration
+ *
+ * @pdev - handle to the physical device
+ * @val - 0 - disable, 1 - enable
+ */
+void ol_set_cfg_packet_log_enabled(struct cdp_cfg *ppdev, uint8_t val);
+
+/**
+ * @brief Check whether rx forwarding is enabled or disabled.
+ * @details
+ *  Choose whether to forward rx frames to tx (where applicable) within the
+ *  WLAN driver, or to leave all forwarding up to the operating system.
+ *
+ * @param pdev - handle to the physical device
+ * @return 1 -> no rx->tx forward -OR- 0 -> rx->tx forward (in host or target)
+ */
+int ol_cfg_rx_fwd_disabled(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief Check whether to perform inter-BSS or intra-BSS rx->tx forwarding.
+ * @details
+ *  Check whether data received by an AP on one virtual device destined
+ *  to a STA associated with a different virtual device within the same
+ *  physical device should be forwarded within the driver, or whether
+ *  forwarding should only be done within a virtual device.
+ *
+ * @param pdev - handle to the physical device
+ * @return
+ *      1 -> forward both within and between vdevs
+ *      -OR-
+ *      0 -> forward only within a vdev
+ */
+int ol_cfg_rx_fwd_inter_bss(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief Specify data frame format used by the OS.
+ * @details
+ *  Specify what type of frame (802.3 or native WiFi) the host data SW
+ *  should expect from and provide to the OS shim.
+ *
+ * @param pdev - handle to the physical device
+ * @return enumerated data frame format
+ */
+enum wlan_frm_fmt ol_cfg_frame_type(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief Specify the peak throughput.
+ * @details
+ *  Specify the peak throughput that a system is expected to support.
+ *  The data SW uses this configuration to help choose the size for its
+ *  tx descriptor pool and rx buffer ring.
+ *  The data SW assumes that the peak throughput applies to either rx or tx,
+ *  rather than having separate specs of the rx max throughput vs. the tx
+ *  max throughput.
+ *
+ * @param pdev - handle to the physical device
+ * @return maximum supported throughput in Mbps (not MBps)
+ */
+int ol_cfg_max_thruput_mbps(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief Specify the maximum number of fragments per tx network buffer.
+ * @details
+ *  Specify the maximum number of fragments that a tx frame provided to
+ *  the WLAN driver by the OS may contain.
+ *  In LL systems, the host data SW uses this maximum fragment count to
+ *  determine how many elements to allocate in the fragmentation descriptor
+ *  it creates to specify to the tx MAC DMA where to locate the tx frame's
+ *  data.
+ *  This maximum fragments count is only for regular frames, not TSO frames,
+ *  since TSO frames are sent in segments with a limited number of fragments
+ *  per segment.
+ *
+ * @param pdev - handle to the physical device
+ * @return maximum number of fragments that can occur in a regular tx frame
+ */
+int ol_cfg_netbuf_frags_max(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief For HL systems, specify when to free tx frames.
+ * @details
+ *  In LL systems, the host's tx frame is referenced by the MAC DMA, and
+ *  thus cannot be freed until the target indicates that it is finished
+ *  transmitting the frame.
+ *  In HL systems, the entire tx frame is downloaded to the target.
+ *  Consequently, the target has its own copy of the tx frame, and the
+ *  host can free the tx frame as soon as the download completes.
+ *  Alternatively, the HL host can keep the frame allocated until the
+ *  target explicitly tells the HL host it is done transmitting the frame.
+ *  This gives the target the option of discarding its copy of the tx
+ *  frame, and then later getting a new copy from the host.
+ *  This function tells the host whether it should retain its copy of the
+ *  transmit frames until the target explicitly indicates it is finished
+ *  transmitting them, or if it should free its copy as soon as the
+ *  tx frame is downloaded to the target.
+ *
+ * @param pdev - handle to the physical device
+ * @return
+ *      0 -> retain the tx frame until the target indicates it is done
+ *          transmitting the frame
+ *      -OR-
+ *      1 -> free the tx frame as soon as the download completes
+ */
+int ol_cfg_tx_free_at_download(struct cdp_cfg *cfg_pdev);
+void ol_cfg_set_tx_free_at_download(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief Low water mark for target tx credit.
+ * Tx completion handler is invoked to reap the buffers when the target tx
+ * credit goes below Low Water Mark.
+ */
+#define OL_CFG_NUM_MSDU_REAP 512
+#define ol_cfg_tx_credit_lwm(pdev)					       \
+	((CFG_TGT_NUM_MSDU_DESC >  OL_CFG_NUM_MSDU_REAP) ?		       \
+	 (CFG_TGT_NUM_MSDU_DESC -  OL_CFG_NUM_MSDU_REAP) : 0)
+
+/**
+ * @brief In a HL system, specify the target initial credit count.
+ * @details
+ *  The HL host tx data SW includes a module for determining which tx frames
+ *  to download to the target at a given time.
+ *  To make this judgement, the HL tx download scheduler has to know
+ *  how many buffers the HL target has available to hold tx frames.
+ *  Due to the possibility that a single target buffer pool can be shared
+ *  between rx and tx frames, the host may not be able to obtain a precise
+ *  specification of the tx buffer space available in the target, but it
+ *  uses the best estimate, as provided by this configuration function,
+ *  to determine how best to schedule the tx frame downloads.
+ *
+ * @param pdev - handle to the physical device
+ * @return the number of tx buffers available in a HL target
+ */
+uint16_t ol_cfg_target_tx_credit(struct cdp_cfg *cfg_pdev);
+
+/**
+ * @brief Specify the LL tx MSDU header download size.
+ * @details
+ *  In LL systems, determine how many bytes from a tx frame to download,
+ *  in order to provide the target FW's Descriptor Engine with enough of
+ *  the packet's payload to interpret what kind of traffic this is,
+ *  and who it is for.
+ *  This download size specification does not include the 802.3 / 802.11
+ *  frame encapsulation headers; it starts with the encapsulated IP packet
+ *  (or whatever ethertype is carried within the ethernet-ish frame).
+ *  The LL host data SW will determine how many bytes of the MSDU header to
+ *  download by adding this download size specification to the size of the
+ *  frame header format specified by the ol_cfg_frame_type configuration
+ *  function.
+ *
+ * @param pdev - handle to the physical device
+ * @return the number of bytes beyond the 802.3 or native WiFi header to
+ *      download to the target for tx classification
+ */
+int ol_cfg_tx_download_size(struct cdp_cfg *cfg_pdev);
+
+/**
+ * brief Specify where defrag timeout and duplicate detection is handled
+ * @details
+ *   non-aggregate duplicate detection and timing out stale fragments
+ *   requires additional target memory. To reach max client
+ *   configurations (128+), non-aggregate duplicate detection and the
+ *   logic to time out stale fragments is moved to the host.
+ *
+ * @param pdev - handle to the physical device
+ * @return
+ *  0 -> target is responsible non-aggregate duplicate detection and
+ *          timing out stale fragments.
+ *
+ *  1 -> host is responsible non-aggregate duplicate detection and
+ *          timing out stale fragments.
+ */
+int ol_cfg_rx_host_defrag_timeout_duplicate_check(struct cdp_cfg *cfg_pdev);
+
+/**
+ * brief Query for the period in ms used for throttling for
+ * thermal mitigation
+ * @details
+ *   In LL systems, transmit data throttling is used for thermal
+ *   mitigation where data is paused and resumed during the
+ *   throttle period i.e. the throttle period consists of an
+ *   "on" phase when transmit is allowed and an "off" phase when
+ *   transmit is suspended. This function returns the total
+ *   period used for throttling.
+ *
+ * @param pdev - handle to the physical device
+ * @return the total throttle period in ms
+ */
+int ol_cfg_throttle_period_ms(struct cdp_cfg *cfg_pdev);
+
+/**
+ * brief Query for the duty cycle in percentage used for throttling for
+ * thermal mitigation
+ *
+ * @param pdev - handle to the physical device
+ * @param level - duty cycle level
+ * @return the duty cycle level in percentage
+ */
+int ol_cfg_throttle_duty_cycle_level(struct cdp_cfg *cfg_pdev, int level);
+
+/**
+ * brief Check whether full reorder offload is
+ * enabled/disable by the host
+ * @details
+ *   If the host does not support receive reorder (i.e. the
+ *   target performs full receive re-ordering) this will return
+ *   "enabled"
+ *
+ * @param pdev - handle to the physical device
+ * @return 1 - enable, 0 - disable
+ */
+int ol_cfg_is_full_reorder_offload(struct cdp_cfg *cfg_pdev);
+
+int ol_cfg_is_rx_thread_enabled(struct cdp_cfg *cfg_pdev);
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+void ol_set_cfg_ptp_rx_opt_enabled(struct cdp_cfg *cfg_pdev, u_int8_t val);
+u_int8_t ol_cfg_is_ptp_rx_opt_enabled(struct cdp_cfg *cfg_pdev);
+#else
+static inline void
+ol_set_cfg_ptp_rx_opt_enabled(struct cdp_cfg *cfg_pdev, u_int8_t val)
+{
+}
+
+static inline u_int8_t
+ol_cfg_is_ptp_rx_opt_enabled(struct cdp_cfg *cfg_pdev)
+{
+	return 0;
+}
+#endif
+
+/**
+ * ol_cfg_is_ip_tcp_udp_checksum_offload_enabled() - return
+ *                        ip_tcp_udp_checksum_offload is enable/disable
+ * @pdev : handle to the physical device
+ *
+ * Return: 1 - enable, 0 - disable
+ */
+static inline
+int ol_cfg_is_ip_tcp_udp_checksum_offload_enabled(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->ip_tcp_udp_checksum_offload;
+}
+
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+int ol_cfg_get_tx_flow_stop_queue_th(struct cdp_cfg *cfg_pdev);
+
+int ol_cfg_get_tx_flow_start_queue_offset(struct cdp_cfg *cfg_pdev);
+#endif
+
+bool ol_cfg_is_ce_classify_enabled(struct cdp_cfg *cfg_pdev);
+
+enum wlan_target_fmt_translation_caps {
+	wlan_frm_tran_cap_raw = 0x01,
+	wlan_frm_tran_cap_native_wifi = 0x02,
+	wlan_frm_tran_cap_8023 = 0x04,
+};
+
+/**
+ * @brief Specify the maximum header size added by SW tx encapsulation
+ * @details
+ *  This function returns the maximum size of the new L2 header, not the
+ *  difference between the new and old L2 headers.
+ *  Thus, this function returns the maximum 802.11 header size that the
+ *  tx SW may need to add to tx data frames.
+ *
+ * @param pdev - handle to the physical device
+ */
+static inline int ol_cfg_sw_encap_hdr_max_size(struct cdp_cfg *cfg_pdev)
+{
+	/*
+	 *  24 byte basic 802.11 header
+	 * + 6 byte 4th addr
+	 * + 2 byte QoS control
+	 * + 4 byte HT control
+	 * + 8 byte LLC/SNAP
+	 */
+	return sizeof(struct ieee80211_qosframe_htc_addr4) + LLC_SNAP_HDR_LEN;
+}
+
+static inline uint8_t ol_cfg_tx_encap(struct cdp_cfg *cfg_pdev)
+{
+	/* tx encap done in HW */
+	return 0;
+}
+
+static inline int ol_cfg_host_addba(struct cdp_cfg *cfg_pdev)
+{
+	/*
+	 * ADDBA negotiation is handled by the target FW for Peregrine + Rome.
+	 */
+	return 0;
+}
+
+/**
+ * @brief If the host SW's ADDBA negotiation fails, should it be retried?
+ *
+ * @param pdev - handle to the physical device
+ */
+static inline int ol_cfg_addba_retry(struct cdp_cfg *cfg_pdev)
+{
+	return 0;               /* disabled for now */
+}
+
+/**
+ * @brief How many frames to hold in a paused vdev's tx queue in LL systems
+ */
+static inline int ol_tx_cfg_max_tx_queue_depth_ll(struct cdp_cfg *cfg_pdev)
+{
+	/*
+	 * Store up to 1500 frames for a paused vdev.
+	 * For example, if the vdev is sending 300 Mbps of traffic, and the
+	 * PHY is capable of 600 Mbps, then it will take 56 ms for the PHY to
+	 * drain both the 700 frames that are queued initially, plus the next
+	 * 700 frames that come in while the PHY is catching up.
+	 * So in this example scenario, the PHY will remain fully utilized
+	 * in a MCC system that has a channel-switching period of 56 ms or less.
+	 * 700 frames calculation was correct when FW drain packet without
+	 * any overhead. Actual situation drain overhead will slowdown drain
+	 * speed. And channel period is less than 56 msec
+	 * Worst scenario, 1500 frames should be stored in host.
+	 */
+	return 1500;
+}
+
+/**
+ * @brief Get packet log config from HTT config
+ */
+uint8_t ol_cfg_is_packet_log_enabled(struct cdp_cfg *cfg_pdev);
+
+#ifdef IPA_OFFLOAD
+/**
+ * @brief IPA micro controller data path offload enable or not
+ * @detail
+ *  This function returns IPA micro controller data path offload
+ *  feature enabled or not
+ *
+ * @param pdev - handle to the physical device
+ */
+unsigned int ol_cfg_ipa_uc_offload_enabled(struct cdp_cfg *cfg_pdev);
+/**
+ * @brief IPA micro controller data path TX buffer size
+ * @detail
+ *  This function returns IPA micro controller data path offload
+ *  TX buffer size which should be pre-allocated by driver.
+ *  Default buffer size is 2K
+ *
+ * @param pdev - handle to the physical device
+ */
+unsigned int ol_cfg_ipa_uc_tx_buf_size(struct cdp_cfg *cfg_pdev);
+/**
+ * @brief IPA micro controller data path TX buffer size
+ * @detail
+ *  This function returns IPA micro controller data path offload
+ *  TX buffer count which should be pre-allocated by driver.
+ *
+ * @param pdev - handle to the physical device
+ */
+unsigned int ol_cfg_ipa_uc_tx_max_buf_cnt(struct cdp_cfg *cfg_pdev);
+/**
+ * @brief IPA micro controller data path TX buffer size
+ * @detail
+ *  This function returns IPA micro controller data path offload
+ *  RX indication ring size which will notified by WLAN FW to IPA
+ *  micro controller
+ *
+ * @param pdev - handle to the physical device
+ */
+unsigned int ol_cfg_ipa_uc_rx_ind_ring_size(struct cdp_cfg *cfg_pdev);
+/**
+ * @brief IPA micro controller data path TX buffer size
+ * @param pdev - handle to the physical device
+ */
+unsigned int ol_cfg_ipa_uc_tx_partition_base(struct cdp_cfg *cfg_pdev);
+void ol_cfg_set_ipa_uc_tx_partition_base(struct cdp_cfg *cfg_pdev,
+					 uint32_t value);
+#else
+static inline unsigned int ol_cfg_ipa_uc_offload_enabled(
+	struct cdp_cfg *cfg_pdev)
+{
+	return 0;
+}
+
+static inline unsigned int ol_cfg_ipa_uc_tx_buf_size(
+	struct cdp_cfg *cfg_pdev)
+{
+	return 0;
+}
+
+static inline unsigned int ol_cfg_ipa_uc_tx_max_buf_cnt(
+	struct cdp_cfg *cfg_pdev)
+{
+	return 0;
+}
+
+static inline unsigned int ol_cfg_ipa_uc_rx_ind_ring_size(
+	struct cdp_cfg *cfg_pdev)
+{
+	return 0;
+}
+
+static inline unsigned int ol_cfg_ipa_uc_tx_partition_base(
+	struct cdp_cfg *cfg_pdev)
+{
+	return 0;
+}
+
+static inline void ol_cfg_set_ipa_uc_tx_partition_base(
+	void *cfg_pdev, uint32_t value)
+{
+}
+#endif /* IPA_OFFLOAD */
+
+/**
+ * ol_set_cfg_flow_steering - Set Rx flow steering config based on CFG ini
+ *			      config.
+ *
+ * @pdev - handle to the physical device
+ * @val - 0 - disable, 1 - enable
+ *
+ * Return: None
+ */
+static inline void ol_set_cfg_flow_steering(struct cdp_cfg *cfg_pdev,
+				uint8_t val)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	cfg->flow_steering_enabled = val;
+}
+
+/**
+ * ol_cfg_is_flow_steering_enabled - Return Rx flow steering config.
+ *
+ * @pdev - handle to the physical device
+ *
+ * Return: value of configured flow steering value.
+ */
+static inline uint8_t ol_cfg_is_flow_steering_enabled(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->flow_steering_enabled;
+}
+
+/**
+ * ol_cfg_get_wrr_skip_weight() - brief Query for the param of wrr_skip_weight
+ * @pdev: handle to the physical device.
+ * @ac: access control, it will be BE, BK, VI, VO
+ *
+ * Return: wrr_skip_weight for specified ac.
+ */
+int ol_cfg_get_wrr_skip_weight(struct cdp_cfg *pdev, int ac);
+
+/**
+ * ol_cfg_get_credit_threshold() - Query for the param of credit_threshold
+ * @pdev: handle to the physical device.
+ * @ac: access control, it will be BE, BK, VI, VO
+ *
+ * Return: credit_threshold for specified ac.
+ */
+uint32_t ol_cfg_get_credit_threshold(struct cdp_cfg *pdev, int ac);
+
+/**
+ * ol_cfg_get_send_limit() - Query for the param of send_limit
+ * @pdev: handle to the physical device.
+ * @ac: access control, it will be BE, BK, VI, VO
+ *
+ * Return: send_limit for specified ac.
+ */
+uint16_t ol_cfg_get_send_limit(struct cdp_cfg *pdev, int ac);
+
+/**
+ * ol_cfg_get_credit_reserve() - Query for the param of credit_reserve
+ * @pdev: handle to the physical device.
+ * @ac: access control, it will be BE, BK, VI, VO
+ *
+ * Return: credit_reserve for specified ac.
+ */
+int ol_cfg_get_credit_reserve(struct cdp_cfg *pdev, int ac);
+
+/**
+ * ol_cfg_get_discard_weight() - Query for the param of discard_weight
+ * @pdev: handle to the physical device.
+ * @ac: access control, it will be BE, BK, VI, VO
+ *
+ * Return: discard_weight for specified ac.
+ */
+int ol_cfg_get_discard_weight(struct cdp_cfg *pdev, int ac);
+#endif /* _OL_CFG__H_ */
diff --git a/core/dp/ol/inc/ol_ctrl_addba_api.h b/core/dp/ol/inc/ol_ctrl_addba_api.h
new file mode 100644
index 0000000..dabafdb
--- /dev/null
+++ b/core/dp/ol/inc/ol_ctrl_addba_api.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013-2015 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.
+ */
+
+#ifndef _OL_CTRL_ADDBA_API_H_
+#define _OL_CTRL_ADDBA_API_H_
+#define ol_ctrl_addba_attach(a, b, c, d, e)             0
+#define ol_ctrl_addba_detach(a)                         0
+#define ol_ctrl_addba_init(a, b, c, d, e)               0
+#define ol_ctrl_addba_cleanup(a)                        0
+#define ol_ctrl_addba_request_setup(a, b, c, d, e, f)   0
+#define ol_ctrl_addba_response_setup(a, b, c, d, e, f)  0
+#define ol_ctrl_addba_request_process(a, b, c, d, e)    0
+#define ol_ctrl_addba_response_process(a, b, c, d)      0
+#define ol_ctrl_addba_clear(a)                          0
+#define ol_ctrl_delba_process(a, b, c)                  0
+#define ol_ctrl_addba_get_status(a, b)                  0
+#define ol_ctrl_addba_set_response(a, b, c)             0
+#define ol_ctrl_addba_clear_response(a)                 0
+#endif
diff --git a/core/dp/ol/inc/ol_defines.h b/core/dp/ol/inc/ol_defines.h
new file mode 100644
index 0000000..3e73310
--- /dev/null
+++ b/core/dp/ol/inc/ol_defines.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013-2014, 2016, 2018 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.
+ */
+
+/*
+ * Offload specific Opaque Data types.
+ */
+#ifndef _DEV_OL_DEFINES_H
+#define _DEV_OL_DEFINES_H
+
+ /**
+  * ol_txrx_pdev_handle - opaque handle for txrx physical device
+  * object
+  */
+struct ol_txrx_pdev_t;
+typedef struct ol_txrx_pdev_t *ol_txrx_pdev_handle;
+
+/**
+ * ol_txrx_vdev_handle - opaque handle for txrx virtual device
+ * object
+ */
+struct ol_txrx_vdev_t;
+typedef struct ol_txrx_vdev_t *ol_txrx_vdev_handle;
+
+/**
+ * ol_pdev_handle - opaque handle for the configuration
+ * associated with the physical device
+ */
+struct ol_pdev_t;
+typedef struct ol_pdev_t *ol_pdev_handle;
+
+/**
+ * ol_txrx_peer_handle - opaque handle for txrx peer object
+ */
+struct ol_txrx_peer_t;
+typedef struct ol_txrx_peer_t *ol_txrx_peer_handle;
+
+#endif /* _DEV_OL_DEFINES_H */
diff --git a/core/dp/ol/inc/ol_htt_api.h b/core/dp/ol/inc/ol_htt_api.h
new file mode 100644
index 0000000..afb04d2
--- /dev/null
+++ b/core/dp/ol/inc/ol_htt_api.h
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2011, 2014-2018 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.
+ */
+
+/**
+ * @file ol_htt_api.h
+ * @brief Specify the general HTT API functions called by the host data SW.
+ * @details
+ *  This file declares the HTT API functions that are not specific to
+ *  either tx nor rx.
+ */
+#ifndef _OL_HTT_API__H_
+#define _OL_HTT_API__H_
+
+#include <qdf_types.h>          /* qdf_device_t */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <athdefs.h>            /* A_STATUS */
+#include <htc_api.h>            /* HTC_HANDLE */
+#include "htt.h"                /* htt_dbg_stats_type, etc. */
+#include <cdp_txrx_cmn.h>       /* ol_pdev_handle */
+#include <ol_defines.h>
+#include <cdp_txrx_handle.h>
+/* TID */
+#define OL_HTT_TID_NON_QOS_UNICAST     16
+#define OL_HTT_TID_NON_QOS_MCAST_BCAST 18
+
+struct htt_pdev_t;
+typedef struct htt_pdev_t *htt_pdev_handle;
+
+htt_pdev_handle
+htt_pdev_alloc(ol_txrx_pdev_handle txrx_pdev,
+	struct cdp_cfg *ctrl_pdev,
+	HTC_HANDLE htc_pdev, qdf_device_t osdev);
+
+/**
+ * @brief Allocate and initialize a HTT instance.
+ * @details
+ *  This function allocates and initializes an HTT instance.
+ *  This involves allocating a pool of HTT tx descriptors in
+ *  consistent memory, allocating and filling a rx ring (LL only),
+ *  and connecting the HTC's HTT_DATA_MSG service.
+ *  The HTC service connect call will block, so this function
+ *  needs to be called in passive context.
+ *  Because HTC setup has not been completed at the time this function
+ *  is called, this function cannot send any HTC messages to the target.
+ *  Messages to configure the target are instead sent in the
+ *  htc_attach_target function.
+ *
+ * @param pdev - data SW's physical device handle
+ *      (used as context pointer during HTT -> txrx calls)
+ * @param desc_pool_size - number of HTT descriptors to (pre)allocate
+ * @return success -> HTT pdev handle; failure -> NULL
+ */
+int
+htt_attach(struct htt_pdev_t *pdev, int desc_pool_size);
+
+/**
+ * @brief Send HTT configuration messages to the target.
+ * @details
+ *  For LL only, this function sends a rx ring configuration message to the
+ *  target.  For HL, this function is a no-op.
+ *
+ * @param htt_pdev - handle to the HTT instance being initialized
+ */
+QDF_STATUS htt_attach_target(htt_pdev_handle htt_pdev);
+
+/**
+ * enum htt_op_mode - Virtual device operation mode
+ *
+ * @htt_op_mode_unknown: Unknown mode
+ * @htt_op_mode_ap: AP mode
+ * @htt_op_mode_ibss: IBSS mode
+ * @htt_op_mode_sta: STA (client) mode
+ * @htt_op_mode_monitor: Monitor mode
+ * @htt_op_mode_ocb: OCB mode
+ */
+enum htt_op_mode {
+	htt_op_mode_unknown,
+	htt_op_mode_ap,
+	htt_op_mode_ibss,
+	htt_op_mode_sta,
+	htt_op_mode_monitor,
+	htt_op_mode_ocb,
+};
+
+/* no-ops */
+#define htt_vdev_attach(htt_pdev, vdev_id, op_mode)
+#define htt_vdev_detach(htt_pdev, vdev_id)
+#define htt_peer_qos_update(htt_pdev, peer_id, qos_capable)
+#define htt_peer_uapsdmask_update(htt_pdev, peer_id, uapsd_mask)
+
+void htt_pdev_free(htt_pdev_handle pdev);
+
+/**
+ * @brief Deallocate a HTT instance.
+ *
+ * @param htt_pdev - handle to the HTT instance being torn down
+ */
+void htt_detach(htt_pdev_handle htt_pdev);
+
+/**
+ * @brief Stop the communication between HTT and target
+ * @details
+ *  For ISOC solution, this function stop the communication between HTT and
+ *  target.
+ *  For Peregrine/Rome, it's already stopped by ol_ath_disconnect_htc
+ *  before ol_txrx_pdev_detach called in ol_ath_detach. So this function is
+ *  a no-op.
+ *  Peregrine/Rome HTT layer is on top of HTC while ISOC solution HTT layer is
+ *  on top of DXE layer.
+ *
+ * @param htt_pdev - handle to the HTT instance being initialized
+ */
+void htt_detach_target(htt_pdev_handle htt_pdev);
+
+/*
+ * @brief Tell the target side of HTT to suspend H2T processing until synced
+ * @param htt_pdev - the host HTT object
+ * @param sync_cnt - what sync count value the target HTT FW should wait for
+ *      before resuming H2T processing
+ */
+A_STATUS htt_h2t_sync_msg(htt_pdev_handle htt_pdev, uint8_t sync_cnt);
+
+int
+htt_h2t_aggr_cfg_msg(htt_pdev_handle htt_pdev,
+		     int max_subfrms_ampdu, int max_subfrms_amsdu);
+
+/**
+ * @brief Get the FW status
+ * @details
+ *  Trigger FW HTT to retrieve FW status.
+ *  A separate HTT message will come back with the statistics we want.
+ *
+ * @param pdev - handle to the HTT instance
+ * @param stats_type_upload_mask - bitmask identifying which stats to upload
+ * @param stats_type_reset_mask - bitmask identifying which stats to reset
+ * @param cookie - unique value to distinguish and identify stats requests
+ * @return 0 - succeed to send the request to FW; otherwise, failed to do so.
+ */
+int
+htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev,
+		      uint32_t stats_type_upload_mask,
+		      uint32_t stats_type_reset_mask,
+		      uint8_t cfg_stats_type,
+		      uint32_t cfg_val, uint8_t cookie);
+
+/**
+ * @brief Get the fields from HTT T2H stats upload message's stats info header
+ * @details
+ *  Parse the a HTT T2H message's stats info tag-length-value header,
+ *  to obtain the stats type, status, data length, and data address.
+ *
+ * @param stats_info_list - address of stats record's header
+ * @param[out] type - which type of FW stats are contained in the record
+ * @param[out] status - whether the stats are (fully) present in the record
+ * @param[out] length - how large the data portion of the stats record is
+ * @param[out] stats_data - where the data portion of the stats record is
+ */
+void
+htt_t2h_dbg_stats_hdr_parse(uint8_t *stats_info_list,
+			    enum htt_dbg_stats_type *type,
+			    enum htt_dbg_stats_status *status,
+			    int *length, uint8_t **stats_data);
+
+/**
+ * @brief Display a stats record from the HTT T2H STATS_CONF message.
+ * @details
+ *  Parse the stats type and status, and invoke a type-specified printout
+ *  to display the stats values.
+ *
+ *  @param stats_data - buffer holding the stats record from the STATS_CONF msg
+ *  @param concise - whether to do a verbose or concise printout
+ */
+void htt_t2h_stats_print(uint8_t *stats_data, int concise);
+
+/**
+ * htt_log_rx_ring_info() - log htt rx ring info during FW_RX_REFILL failure
+ * @pdev: handle to the HTT instance
+ *
+ * Return: None
+ */
+void htt_log_rx_ring_info(htt_pdev_handle pdev);
+
+#ifndef HTT_DEBUG_LEVEL
+#if defined(DEBUG)
+#define HTT_DEBUG_LEVEL 10
+#else
+#define HTT_DEBUG_LEVEL 0
+#endif
+#endif
+
+#if HTT_DEBUG_LEVEL > 5
+void htt_display(htt_pdev_handle pdev, int indent);
+#else
+#define htt_display(pdev, indent)
+#endif
+
+#define HTT_DXE_RX_LOG 0
+#define htt_rx_reorder_log_print(pdev)
+
+#ifdef IPA_OFFLOAD
+int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev);
+
+/**
+ * htt_ipa_uc_get_resource() - Get uc resource from htt and lower layer
+ * @pdev - handle to the HTT instance
+ * @ce_sr - CE source ring DMA mapping info
+ * @tx_comp_ring - tx completion ring DMA mapping info
+ * @rx_rdy_ring - rx Ready ring DMA mapping info
+ * @rx2_rdy_ring - rx2 Ready ring DMA mapping info
+ * @rx_proc_done_idx - rx process done index
+ * @rx2_proc_done_idx - rx2 process done index
+ * @ce_sr_ring_size: copyengine source ring size
+ * @ce_reg_paddr - CE Register address
+ * @tx_num_alloc_buffer - Number of TX allocated buffers
+ *
+ * Return: 0 success
+ */
+int
+htt_ipa_uc_get_resource(htt_pdev_handle pdev,
+			qdf_shared_mem_t **ce_sr,
+			qdf_shared_mem_t **tx_comp_ring,
+			qdf_shared_mem_t **rx_rdy_ring,
+			qdf_shared_mem_t **rx2_rdy_ring,
+			qdf_shared_mem_t **rx_proc_done_idx,
+			qdf_shared_mem_t **rx2_proc_done_idx,
+			uint32_t *ce_sr_ring_size,
+			qdf_dma_addr_t *ce_reg_paddr,
+			uint32_t *tx_num_alloc_buffer);
+
+int
+htt_ipa_uc_set_doorbell_paddr(htt_pdev_handle pdev,
+			      qdf_dma_addr_t ipa_uc_tx_doorbell_paddr,
+			      qdf_dma_addr_t ipa_uc_rx_doorbell_paddr);
+
+int
+htt_h2t_ipa_uc_set_active(struct htt_pdev_t *pdev, bool uc_active, bool is_tx);
+
+int htt_h2t_ipa_uc_get_stats(struct htt_pdev_t *pdev);
+
+int htt_h2t_ipa_uc_get_share_stats(struct htt_pdev_t *pdev,
+				   uint8_t reset_stats);
+
+int htt_h2t_ipa_uc_set_quota(struct htt_pdev_t *pdev, uint64_t quota_bytes);
+
+int htt_ipa_uc_attach(struct htt_pdev_t *pdev);
+
+void htt_ipa_uc_detach(struct htt_pdev_t *pdev);
+#else
+/**
+ * htt_h2t_ipa_uc_rsc_cfg_msg() - Send WDI IPA config message to firmware
+ * @pdev: handle to the HTT instance
+ *
+ * Return: 0 success
+ */
+static inline int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev)
+{
+	return 0;
+}
+
+/**
+ * htt_ipa_uc_set_doorbell_paddr() - Propagate IPA doorbell address
+ * @pdev: handle to the HTT instance
+ * @ipa_uc_tx_doorbell_paddr: TX doorbell base physical address
+ * @ipa_uc_rx_doorbell_paddr: RX doorbell base physical address
+ *
+ * Return: 0 success
+ */
+static inline int
+htt_ipa_uc_set_doorbell_paddr(htt_pdev_handle pdev,
+			      uint32_t ipa_uc_tx_doorbell_paddr,
+			      uint32_t ipa_uc_rx_doorbell_paddr)
+{
+	return 0;
+}
+
+/**
+ * htt_h2t_ipa_uc_set_active() - Propagate WDI path enable/disable to firmware
+ * @pdev: handle to the HTT instance
+ * @uc_active: WDI UC path enable or not
+ * @is_tx: TX path or RX path
+ *
+ * Return: 0 success
+ */
+static inline int
+htt_h2t_ipa_uc_set_active(struct htt_pdev_t *pdev, bool uc_active,
+	bool is_tx)
+{
+	return 0;
+}
+
+/**
+ * htt_h2t_ipa_uc_get_stats() - WDI UC state query request to firmware
+ * @pdev: handle to the HTT instance
+ *
+ * Return: 0 success
+ */
+static inline int htt_h2t_ipa_uc_get_stats(struct htt_pdev_t *pdev)
+{
+	return 0;
+}
+
+/**
+ * htt_h2t_ipa_uc_get_share_stats() - WDI UC wifi sharing state request to FW
+ * @pdev: handle to the HTT instance
+ *
+ * Return: 0 success
+ */
+static inline int htt_h2t_ipa_uc_get_share_stats(struct htt_pdev_t *pdev,
+						uint8_t reset_stats)
+{
+	return 0;
+}
+
+/**
+ * htt_h2t_ipa_uc_set_quota() - WDI UC set quota request to firmware
+ * @pdev: handle to the HTT instance
+ *
+ * Return: 0 success
+ */
+static inline int htt_h2t_ipa_uc_set_quota(struct htt_pdev_t *pdev,
+					   uint64_t quota_bytes)
+{
+	return 0;
+}
+
+/**
+ * htt_ipa_uc_attach() - Allocate UC data path resources
+ * @pdev: handle to the HTT instance
+ *
+ * Return: 0 success
+ */
+static inline int htt_ipa_uc_attach(struct htt_pdev_t *pdev)
+{
+	return 0;
+}
+
+/**
+ * htt_ipa_uc_attach() - Remove UC data path resources
+ * @pdev: handle to the HTT instance
+ *
+ * Return: 0 success
+ */
+static inline void htt_ipa_uc_detach(struct htt_pdev_t *pdev)
+{
+}
+#endif /* IPA_OFFLOAD */
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch);
+
+void ol_htt_mon_note_chan(struct cdp_pdev *ppdev, int mon_ch);
+#else
+static inline
+void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch) {}
+
+static inline
+void ol_htt_mon_note_chan(struct cdp_pdev *ppdev, int mon_ch) {}
+#endif
+
+#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
+
+void htt_dump_bundle_stats(struct htt_pdev_t *pdev);
+void htt_clear_bundle_stats(struct htt_pdev_t *pdev);
+#else
+
+static inline void htt_dump_bundle_stats(struct htt_pdev_t *pdev)
+{
+}
+
+static inline void htt_clear_bundle_stats(struct htt_pdev_t *pdev)
+{
+}
+#endif
+
+void htt_mark_first_wakeup_packet(htt_pdev_handle pdev, uint8_t value);
+
+typedef void (*tp_rx_pkt_dump_cb)(qdf_nbuf_t msdu, uint8_t peer_id,
+			uint8_t status);
+#ifdef REMOVE_PKT_LOG
+static inline
+void htt_register_rx_pkt_dump_callback(struct htt_pdev_t *pdev,
+				       tp_rx_pkt_dump_cb ol_rx_pkt_dump_call)
+{
+}
+
+static inline
+void htt_deregister_rx_pkt_dump_callback(struct htt_pdev_t *pdev)
+{
+}
+
+static inline
+void ol_rx_pkt_dump_call(qdf_nbuf_t msdu, uint8_t peer_id, uint8_t status)
+{
+}
+#else
+void htt_register_rx_pkt_dump_callback(struct htt_pdev_t *pdev,
+				       tp_rx_pkt_dump_cb ol_rx_pkt_dump_call);
+void htt_deregister_rx_pkt_dump_callback(struct htt_pdev_t *pdev);
+void ol_rx_pkt_dump_call(qdf_nbuf_t msdu, uint8_t peer_id, uint8_t status);
+#endif
+
+#endif /* _OL_HTT_API__H_ */
diff --git a/core/dp/ol/inc/ol_htt_rx_api.h b/core/dp/ol/inc/ol_htt_rx_api.h
new file mode 100644
index 0000000..9414856
--- /dev/null
+++ b/core/dp/ol/inc/ol_htt_rx_api.h
@@ -0,0 +1,924 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ * @file ol_htt_rx_api.h
+ * @brief Specify the rx HTT API functions called by the host data SW.
+ * @details
+ *  This file declares the HTT API functions that are specifically
+ *  related to receive processing.
+ *  In particular, this file specifies methods of the abstract HTT rx
+ *  descriptor, and functions to iterate though a series of rx descriptors
+ *  and rx MSDU buffers.
+ */
+#ifndef _OL_HTT_RX_API__H_
+#define _OL_HTT_RX_API__H_
+
+/* #include <osapi_linux.h>     / * uint16_t, etc. * / */
+#include <osdep.h>              /* uint16_t, etc. */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <qdf_types.h>          /* bool */
+
+#include <htt.h>                /* HTT_RX_IND_MPDU_STATUS */
+#include <ol_htt_api.h>         /* htt_pdev_handle */
+
+#include <cds_ieee80211_defines.h>  /* ieee80211_rx_status */
+#include <ol_vowext_dbg_defs.h>
+
+/*================ constants and types used in the rx API ===================*/
+
+#define HTT_RSSI_INVALID 0x7fff
+
+/**
+ * struct ocb_rx_stats_hdr_t - RX stats header
+ * @version:		The version must be 1.
+ * @length:		The length of this structure
+ * @channel_freq:	The center frequency for the packet
+ * @rssi_cmb:		combined RSSI from all chains
+ * @rssi[4]:		rssi for chains 0 through 3 (for 20 MHz bandwidth)
+ * @tsf32:		timestamp in TSF units
+ * @timestamp_microsec:	timestamp in microseconds
+ * @datarate:		MCS index
+ * @timestamp_submicrosec: submicrosecond portion of the timestamp
+ * @ext_tid:		Extended TID
+ * @reserved:		Ensure the size of the structure is a multiple of 4.
+ *			Must be 0.
+ *
+ * When receiving an OCB packet, the RX stats is sent to the user application
+ * so that the user application can do processing based on the RX stats.
+ * This structure will be preceded by an ethernet header with
+ * the proto field set to 0x8152. This struct includes various RX
+ * paramaters including RSSI, data rate, and center frequency.
+ */
+PREPACK struct ocb_rx_stats_hdr_t {
+	uint16_t version;
+	uint16_t length;
+	uint16_t channel_freq;
+	int16_t rssi_cmb;
+	int16_t rssi[4];
+	uint32_t tsf32;
+	uint32_t timestamp_microsec;
+	uint8_t datarate;
+	uint8_t timestamp_submicrosec;
+	uint8_t ext_tid;
+	uint8_t reserved;
+};
+
+/*================ rx indication message field access methods ===============*/
+
+/**
+ * @brief Check if a rx indication message has a rx reorder flush command.
+ * @details
+ *  Space is reserved in each rx indication message for a rx reorder flush
+ *  command, to release specified MPDUs from the rx reorder holding array
+ *  before processing the new MPDUs referenced by the rx indication message.
+ *  This rx reorder flush command contains a flag to show whether the command
+ *  is valid within a given rx indication message.
+ *  This function checks the validity flag from the rx indication
+ *  flush command IE within the rx indication message.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param rx_ind_msg - the netbuf containing the rx indication message
+ * @return
+ *      1 - the message's rx flush command is valid and should be processed
+ *          before processing new rx MPDUs,
+ *      -OR-
+ *      0 - the message's rx flush command is invalid and should be ignored
+ */
+int htt_rx_ind_flush(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg);
+
+/**
+ * @brief Return the sequence number starting the range of MPDUs to flush.
+ * @details
+ *  Read the fields of the rx indication message that identify the start
+ *  and end of the range of MPDUs to flush from the rx reorder holding array
+ *  and send on to subsequent stages of rx processing.
+ *  These sequence numbers are the 6 LSBs of the 12-bit 802.11 sequence
+ *  number.  These sequence numbers are masked with the block ack window size,
+ *  rounded up to a power of two (minus one, to create a bitmask) to obtain
+ *  the corresponding index into the rx reorder holding array.
+ *  The series of MPDUs to flush includes the one specified by the start
+ *  sequence number.
+ *  The series of MPDUs to flush excludes the one specified by the end
+ *  sequence number; the MPDUs up to but not including the end sequence number
+ *  are to be flushed.
+ *  These start and end seq num fields are only valid if the "flush valid"
+ *  flag is set.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param rx_ind_msg - the netbuf containing the rx indication message
+ * @param seq_num_start - (call-by-reference output) sequence number
+ *      for the start of the range of MPDUs to flush
+ * @param seq_num_end - (call-by-reference output) sequence number
+ *      for the end of the range of MPDUs to flush
+ */
+void
+htt_rx_ind_flush_seq_num_range(htt_pdev_handle pdev,
+			       qdf_nbuf_t rx_ind_msg,
+			       unsigned *seq_num_start, unsigned *seq_num_end);
+
+/**
+ * @brief Check if a rx indication message has a rx reorder release command.
+ * @details
+ *  Space is reserved in each rx indication message for a rx reorder release
+ *  command, to release specified MPDUs from the rx reorder holding array
+ *  after processing the new MPDUs referenced by the rx indication message.
+ *  This rx reorder release command contains a flag to show whether the command
+ *  is valid within a given rx indication message.
+ *  This function checks the validity flag from the rx indication
+ *  release command IE within the rx indication message.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param rx_ind_msg - the netbuf containing the rx indication message
+ * @return
+ *      1 - the message's rx release command is valid and should be processed
+ *          after processing new rx MPDUs,
+ *      -OR-
+ *      0 - the message's rx release command is invalid and should be ignored
+ */
+int htt_rx_ind_release(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg);
+
+/**
+ * @brief Return the sequence number starting the range of MPDUs to release.
+ * @details
+ *  Read the fields of the rx indication message that identify the start
+ *  and end of the range of MPDUs to release from the rx reorder holding
+ *  array and send on to subsequent stages of rx processing.
+ *  These sequence numbers are the 6 LSBs of the 12-bit 802.11 sequence
+ *  number.  These sequence numbers are masked with the block ack window size,
+ *  rounded up to a power of two (minus one, to create a bitmask) to obtain
+ *  the corresponding index into the rx reorder holding array.
+ *  The series of MPDUs to release includes the one specified by the start
+ *  sequence number.
+ *  The series of MPDUs to release excludes the one specified by the end
+ *  sequence number; the MPDUs up to but not including the end sequence number
+ *  are to be released.
+ *  These start and end seq num fields are only valid if the "release valid"
+ *  flag is set.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param rx_ind_msg - the netbuf containing the rx indication message
+ * @param seq_num_start - (call-by-reference output) sequence number
+ *        for the start of the range of MPDUs to release
+ * @param seq_num_end - (call-by-reference output) sequence number
+ *        for the end of the range of MPDUs to release
+ */
+void
+htt_rx_ind_release_seq_num_range(htt_pdev_handle pdev,
+				 qdf_nbuf_t rx_ind_msg,
+				 unsigned int *seq_num_start,
+				 unsigned int *seq_num_end);
+
+/*
+ * For now, the host HTT -> host data rx status enum
+ * exactly matches the target HTT -> host HTT rx status enum;
+ * no translation is required.
+ * However, the host data SW should only use the htt_rx_status,
+ * so that in the future a translation from target HTT rx status
+ * to host HTT rx status can be added, if the need ever arises.
+ */
+enum htt_rx_status {
+	htt_rx_status_unknown = HTT_RX_IND_MPDU_STATUS_UNKNOWN,
+	htt_rx_status_ok = HTT_RX_IND_MPDU_STATUS_OK,
+	htt_rx_status_err_fcs = HTT_RX_IND_MPDU_STATUS_ERR_FCS,
+	htt_rx_status_err_dup = HTT_RX_IND_MPDU_STATUS_ERR_DUP,
+	htt_rx_status_err_replay = HTT_RX_IND_MPDU_STATUS_ERR_REPLAY,
+	htt_rx_status_err_inv_peer = HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER,
+	htt_rx_status_ctrl_mgmt_null = HTT_RX_IND_MPDU_STATUS_MGMT_CTRL,
+	htt_rx_status_tkip_mic_err = HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR,
+
+	htt_rx_status_err_misc = HTT_RX_IND_MPDU_STATUS_ERR_MISC
+};
+
+/**
+ * @brief Check the status MPDU range referenced by a rx indication message.
+ * @details
+ *  Check the status of a range of MPDUs referenced by a rx indication message.
+ *  This status determines whether the MPDUs should be processed or discarded.
+ *  If the status is OK, then the MPDUs within the range should be processed
+ *  as usual.
+ *  Otherwise (FCS error, duplicate error, replay error, unknown sender error,
+ *  etc.) the MPDUs within the range should be discarded.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param rx_ind_msg - the netbuf containing the rx indication message
+ * @param mpdu_range_num - which MPDU range within the rx ind msg to check,
+ *        starting from 0
+ * @param status - (call-by-reference output) MPDU status
+ * @param mpdu_count - (call-by-reference output) count of MPDUs comprising
+ *        the specified MPDU range
+ */
+void
+htt_rx_ind_mpdu_range_info(htt_pdev_handle pdev,
+			   qdf_nbuf_t rx_ind_msg,
+			   int mpdu_range_num,
+			   enum htt_rx_status *status, int *mpdu_count);
+
+/**
+ * @brief Return the RSSI provided in a rx indication message.
+ * @details
+ *  Return the RSSI from an rx indication message, converted to dBm units.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param rx_ind_msg - the netbuf containing the rx indication message
+ * @return RSSI in dBm, or HTT_INVALID_RSSI
+ */
+int16_t
+htt_rx_ind_rssi_dbm(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg);
+
+int16_t
+htt_rx_ind_rssi_dbm_chain(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg,
+			  int8_t chain);
+
+void
+htt_rx_ind_legacy_rate(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg,
+		       uint8_t *legacy_rate, uint8_t *legacy_rate_sel);
+
+
+void
+htt_rx_ind_timestamp(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg,
+		     uint32_t *timestamp_microsec,
+		     uint8_t *timestamp_submicrosec);
+
+uint32_t
+htt_rx_ind_tsf32(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg);
+
+uint8_t
+htt_rx_ind_ext_tid(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg);
+
+
+/*==================== rx MPDU descriptor access methods ====================*/
+
+/**
+ * @brief Check if the retry bit is set in Rx-descriptor
+ * @details
+ * This function returns the retry bit of the 802.11 header for the
+ *  provided rx MPDU descriptor.
+ *
+ * @param pdev - the handle of the physical device the rx data was received on
+ * @param msdu_desc - the abstract descriptor for the MSDU in question
+ * @return boolean -- true if retry is set, false otherwise
+ */
+extern
+bool (*htt_rx_mpdu_desc_retry)(
+		htt_pdev_handle pdev, void *mpdu_desc);
+
+/**
+ * @brief Return a rx MPDU's sequence number.
+ * @details
+ *  This function returns the LSBs of the 802.11 sequence number for the
+ *  provided rx MPDU descriptor.
+ *  Depending on the system, 6-12 LSBs from the 802.11 sequence number are
+ *  returned.  (Typically, either the 8 or 12 LSBs are returned.)
+ *  This sequence number is masked with the block ack window size,
+ *  rounded up to a power of two (minus one, to create a bitmask) to obtain
+ *  the corresponding index into the rx reorder holding array.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param mpdu_desc - the abstract descriptor for the MPDU in question
+ * @return the LSBs of the sequence number for the MPDU
+ */
+extern uint16_t
+(*htt_rx_mpdu_desc_seq_num)(htt_pdev_handle pdev, void *mpdu_desc);
+
+/**
+ * @brief Return a rx MPDU's rx reorder array index, based on sequence number.
+ * @details
+ *  This function returns a sequence-number based index into the rx
+ *  reorder array for the specified MPDU.
+ *  In some systems, this rx reorder array is simply the LSBs of the
+ *  sequence number, or possibly even the full sequence number.
+ *  To support such systems, the returned index has to be masked with
+ *  the power-of-two array size before using the value to index the
+ *  rx reorder array.
+ *  In other systems, this rx reorder array index is
+ *      (sequence number) % (block ack window size)
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param mpdu_desc - the abstract descriptor for the MPDU in question
+ * @return the rx reorder array index the MPDU goes into
+ */
+/* use sequence number (or LSBs thereof) as rx reorder array index */
+#define htt_rx_mpdu_desc_reorder_idx htt_rx_mpdu_desc_seq_num
+
+union htt_rx_pn_t {
+	/* WEP: 24-bit PN */
+	uint32_t pn24;
+
+	/* TKIP or CCMP: 48-bit PN */
+	uint64_t pn48;
+
+	/* WAPI: 128-bit PN */
+	uint64_t pn128[2];
+};
+
+/**
+ * @brief Find the packet number (PN) for a MPDU.
+ * @details
+ *  This function only applies when the rx PN check is configured to be
+ *  performed in the host rather than the target, and on peers using a
+ *  security type for which a PN check applies.
+ *  The pn_len_bits argument is used to determine which element of the
+ *  htt_rx_pn_t union to deposit the PN value read from the MPDU descriptor
+ *  into.
+ *  A 24-bit PN is deposited into pn->pn24.
+ *  A 48-bit PN is deposited into pn->pn48.
+ *  A 128-bit PN is deposited in little-endian order into pn->pn128.
+ *  Specifically, bits 63:0 of the PN are copied into pn->pn128[0], while
+ *  bits 127:64 of the PN are copied into pn->pn128[1].
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param mpdu_desc - the abstract descriptor for the MPDU in question
+ * @param pn - the location to copy the packet number into
+ * @param pn_len_bits - the PN size, in bits
+ */
+extern void (*htt_rx_mpdu_desc_pn)(htt_pdev_handle pdev,
+				   void *mpdu_desc,
+				   union htt_rx_pn_t *pn, int pn_len_bits);
+
+/**
+ * @brief This function Returns the TID value from the Rx descriptor
+ *                             for Low Latency driver
+ * @details
+ *  This function returns the TID set in the 802.11 QoS Control for the MPDU
+ *  in the packet header, by looking at the mpdu_start of the Rx descriptor.
+ *  Rx descriptor gets a copy of the TID from the MAC.
+ * @pdev:  Handle (pointer) to HTT pdev.
+ * @param mpdu_desc - the abstract descriptor for the MPDU in question
+ * @return:        Actual TID set in the packet header.
+ */
+extern
+uint8_t (*htt_rx_mpdu_desc_tid)(
+			htt_pdev_handle pdev, void *mpdu_desc);
+
+/**
+ * @brief Return the TSF timestamp indicating when a MPDU was received.
+ * @details
+ *  This function provides the timestamp indicating when the PPDU that
+ *  the specified MPDU belongs to was received.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param mpdu_desc - the abstract descriptor for the MPDU in question
+ * @return 32 LSBs of TSF time at which the MPDU's PPDU was received
+ */
+uint32_t htt_rx_mpdu_desc_tsf32(htt_pdev_handle pdev, void *mpdu_desc);
+
+/**
+ * @brief Return the 802.11 header of the MPDU
+ * @details
+ *  This function provides a pointer to the start of the 802.11 header
+ *  of the Rx MPDU
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param mpdu_desc - the abstract descriptor for the MPDU in question
+ * @return pointer to 802.11 header of the received MPDU
+ */
+char *htt_rx_mpdu_wifi_hdr_retrieve(htt_pdev_handle pdev, void *mpdu_desc);
+
+/**
+ * @brief Return the RSSI provided in a rx descriptor.
+ * @details
+ *  Return the RSSI from a rx descriptor, converted to dBm units.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param mpdu_desc - the abstract descriptor for the MPDU in question
+ * @return RSSI in dBm, or HTT_INVALID_RSSI
+ */
+int16_t htt_rx_mpdu_desc_rssi_dbm(htt_pdev_handle pdev, void *mpdu_desc);
+
+/*==================== rx MSDU descriptor access methods ====================*/
+
+/**
+ * @brief Check if a MSDU completes a MPDU.
+ * @details
+ *  When A-MSDU aggregation is used, a single MPDU will consist of
+ *  multiple MSDUs.  This function checks a MSDU's rx descriptor to
+ *  see whether the MSDU is the final MSDU within a MPDU.
+ *
+ * @param pdev - the handle of the physical device the rx data was received on
+ * @param msdu_desc - the abstract descriptor for the MSDU in question
+ * @return
+ *      0 - there are subsequent MSDUs within the A-MSDU / MPDU
+ *      -OR-
+ *      1 - this is the last MSDU within its MPDU
+ */
+extern bool (*htt_rx_msdu_desc_completes_mpdu)(htt_pdev_handle pdev,
+					       void *msdu_desc);
+
+/**
+ * @brief Check if a MSDU is first msdu of MPDU.
+ * @details
+ *  When A-MSDU aggregation is used, a single MPDU will consist of
+ *  multiple MSDUs.  This function checks a MSDU's rx descriptor to
+ *  see whether the MSDU is the first MSDU within a MPDU.
+ *
+ * @param pdev - the handle of the physical device the rx data was received on
+ * @param msdu_desc - the abstract descriptor for the MSDU in question
+ * @return
+ *      0 - this is interior MSDU in the A-MSDU / MPDU
+ *      -OR-
+ *      1 - this is the first MSDU within its MPDU
+ */
+extern bool (*htt_rx_msdu_first_msdu_flag)(htt_pdev_handle pdev,
+					   void *msdu_desc);
+
+/**
+ * @brief Retrieve encrypt bit from a mpdu desc.
+ * @details
+ *  Fw will pass all the frame  to the host whether encrypted or not, and will
+ *  indicate the encrypt flag in the desc, this function is to get the info
+ *  and used to make a judge whether should make pn check, because
+ *  non-encrypted frames always get the same pn number 0.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param mpdu_desc - the abstract descriptor for the MPDU in question
+ * @return 0 - the frame was not encrypted
+ *         1 - the frame was encrypted
+ */
+extern bool (*htt_rx_mpdu_is_encrypted)(htt_pdev_handle pdev, void *mpdu_desc);
+
+/**
+ * @brief Indicate whether a rx desc has a WLAN unicast vs. mcast/bcast flag.
+ * @details
+ *  A flag indicating whether a MPDU was delivered over WLAN as unicast or
+ *  multicast/broadcast may be only valid once per MPDU (LL), or within each
+ *  rx descriptor for the MSDUs within the MPDU (HL).  (In practice, it is
+ *  unlikely that A-MSDU aggregation will be used in HL, so typically HL will
+ *  only have one MSDU per MPDU anyway.)
+ *  This function indicates whether the specified rx descriptor contains
+ *  a WLAN ucast vs. mcast/bcast flag.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param msdu_desc - the abstract descriptor for the MSDU in question
+ * @return
+ *      0 - The rx descriptor does not contain a WLAN ucast vs. mcast flag.
+ *      -OR-
+ *      1 - The rx descriptor has a valid WLAN ucast vs. mcast flag.
+ */
+extern int (*htt_rx_msdu_has_wlan_mcast_flag)(htt_pdev_handle pdev,
+					      void *msdu_desc);
+
+/**
+ * @brief Indicate whether a MSDU was received as unicast or mcast/bcast
+ * @details
+ *  Indicate whether the MPDU that the specified MSDU belonged to was
+ *  delivered over the WLAN as unicast, or as multicast/broadcast.
+ *  This query can only be performed on rx descriptors for which
+ *  htt_rx_msdu_has_wlan_mcast_flag is true.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param msdu_desc - the abstract descriptor for the MSDU in question
+ * @return
+ *      0 - The MSDU was delivered over the WLAN as unicast.
+ *      -OR-
+ *      1 - The MSDU was delivered over the WLAN as broadcast or multicast.
+ */
+extern bool (*htt_rx_msdu_is_wlan_mcast)(htt_pdev_handle pdev, void *msdu_desc);
+
+/**
+ * @brief Indicate whether a MSDU was received as a fragmented frame
+ * @details
+ *  This query can only be performed on LL system.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param msdu_desc - the abstract descriptor for the MSDU in question
+ * @return
+ *      0 - The MSDU was a non-fragmented frame.
+ *      -OR-
+ *      1 - The MSDU was fragmented frame.
+ */
+extern int (*htt_rx_msdu_is_frag)(htt_pdev_handle pdev, void *msdu_desc);
+
+/**
+ * @brief Indicate if a MSDU should be delivered to the OS shim or discarded.
+ * @details
+ *  Indicate whether a MSDU should be discarded or delivered to the OS shim.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param msdu_desc - the abstract descriptor for the MSDU in question
+ * @return
+ *      0 - The MSDU should be delivered to the OS
+ *      -OR-
+ *      non-zero - The MSDU should not be delivered to the OS.
+ *          If the "forward" flag is set, it should be forwarded to tx.
+ *          Else, it should be discarded.
+ */
+int htt_rx_msdu_discard(htt_pdev_handle pdev, void *msdu_desc);
+
+/**
+ * @brief Indicate whether a MSDU should be forwarded to tx.
+ * @details
+ *  Indicate whether a MSDU should be forwarded to tx, e.g. for intra-BSS
+ *  STA-to-STA forwarding in an AP, or for multicast echo in an AP.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param msdu_desc - the abstract descriptor for the MSDU in question
+ * @return
+ *      0 - The MSDU should not be forwarded
+ *      -OR-
+ *      non-zero - The MSDU should be forwarded.
+ *          If the "discard" flag is set, then the original MSDU can be
+ *          directly forwarded into the tx path.
+ *          Else, a copy (clone?) of the rx MSDU needs to be created to
+ *          send to the tx path.
+ */
+int htt_rx_msdu_forward(htt_pdev_handle pdev, void *msdu_desc);
+
+/**
+ * @brief Indicate whether a MSDU's contents need to be inspected.
+ * @details
+ *  Indicate whether the host data SW needs to examine the contents of the
+ *  received MSDU, and based on the packet type infer what special handling
+ *  to provide for the MSDU.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param msdu_desc - the abstract descriptor for the MSDU in question
+ * @return
+ *      0 - No inspection + special handling is required.
+ *      -OR-
+ *      non-zero - Inspect the MSDU contents to infer what special handling
+ *          to apply to the MSDU.
+ */
+int htt_rx_msdu_inspect(htt_pdev_handle pdev, void *msdu_desc);
+
+/**
+ * @brief Provide all action specifications for a rx MSDU
+ * @details
+ *  Provide all action specifications together.  This provides the same
+ *  information in a single function call as would be provided by calling
+ *  the functions htt_rx_msdu_discard, htt_rx_msdu_forward, and
+ *  htt_rx_msdu_inspect.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param msdu_desc - the abstract descriptor for the MSDU in question
+ * @param[out] discard - 1: discard the MSDU, 0: deliver the MSDU to the OS
+ * @param[out] forward - 1: forward the rx MSDU to tx, 0: no rx->tx forward
+ * @param[out] inspect - 1: process according to MSDU contents, 0: no inspect
+ */
+void
+htt_rx_msdu_actions(htt_pdev_handle pdev,
+		    void *msdu_desc, int *discard, int *forward, int *inspect);
+
+/**
+ * @brief Get the key id sent in IV of the frame
+ * @details
+ *  Provide the key index octet which is taken from IV.
+ *  This is valid only for the first MSDU.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param msdu_desc - the abstract descriptor for the MSDU in question
+ * @key_id - Key id octet
+ * @return indication of whether key id access is successful
+ *   true - Success
+ *   false - if this is not first msdu
+ */
+extern bool
+(*htt_rx_msdu_desc_key_id)(htt_pdev_handle pdev,
+			   void *mpdu_desc, uint8_t *key_id);
+
+extern bool
+(*htt_rx_msdu_chan_info_present)(
+	htt_pdev_handle pdev,
+	void *mpdu_desc);
+
+extern bool
+(*htt_rx_msdu_center_freq)(
+	htt_pdev_handle pdev,
+	struct ol_txrx_peer_t *peer,
+	void *mpdu_desc,
+	uint16_t *primary_chan_center_freq_mhz,
+	uint16_t *contig_chan1_center_freq_mhz,
+	uint16_t *contig_chan2_center_freq_mhz,
+	uint8_t *phy_mode);
+
+/*====================== rx MSDU + descriptor delivery ======================*/
+
+/**
+ * @brief Return a linked-list of network buffer holding the next rx A-MSDU.
+ * @details
+ *  In some systems, the rx MSDUs are uploaded along with the rx
+ *  indication message, while in other systems the rx MSDUs are uploaded
+ *  out of band, via MAC DMA.
+ *  This function provides an abstract way to obtain a linked-list of the
+ *  next MSDUs, regardless of whether the MSDU was delivered in-band with
+ *  the rx indication message, or out of band through MAC DMA.
+ *  In a LL system, this function returns a linked list of the one or more
+ *  MSDUs that together comprise an A-MSDU.
+ *  In a HL system, this function returns a degenerate linked list consisting
+ *  of a single MSDU (head_msdu == tail_msdu).
+ *  This function also makes sure each MSDU's rx descriptor can be found
+ *  through the MSDU's network buffer.
+ *  In most systems, this is trivial - a single network buffer stores both
+ *  the MSDU rx descriptor and the MSDU payload.
+ *  In systems where the rx descriptor is in a separate buffer from the
+ *  network buffer holding the MSDU payload, a pointer to the rx descriptor
+ *  has to be stored in the network buffer.
+ *  After this function call, the descriptor for a given MSDU can be
+ *  obtained via the htt_rx_msdu_desc_retrieve function.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param rx_ind_msg - the netbuf containing the rx indication message
+ * @param head_msdu - call-by-reference network buffer handle, which gets set
+ *      in this function to point to the head MSDU of the A-MSDU
+ * @param tail_msdu - call-by-reference network buffer handle, which gets set
+ *      in this function to point to the tail MSDU of the A-MSDU, or the
+ *      same MSDU that the head_msdu points to if only a single MSDU is
+ *      delivered at a time.
+ * @return indication of whether any MSDUs in the AMSDU use chaining:
+ * 0 - no buffer chaining
+ * 1 - buffers are chained
+ */
+extern int
+(*htt_rx_amsdu_pop)(htt_pdev_handle pdev,
+		    qdf_nbuf_t rx_ind_msg,
+		    qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu,
+		    uint32_t *msdu_count);
+
+extern int
+(*htt_rx_frag_pop)(htt_pdev_handle pdev,
+		   qdf_nbuf_t rx_ind_msg,
+		   qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu,
+		   uint32_t *msdu_count);
+
+/**
+ * @brief Return the maximum number of available msdus currently
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ */
+extern int
+(*htt_rx_offload_msdu_cnt)(
+    htt_pdev_handle pdev);
+
+/**
+ * @brief Return a linked list of buffers holding one MSDU
+ *  In some systems the buffers are delivered along with offload delivery
+ *  indication message itself, while in other systems the buffers are uploaded
+ *  out of band, via MAC DMA.
+ * @details
+ *  This function provides an abstract way to obtain a linked-list of the
+ *  buffers corresponding to an msdu, regardless of whether the MSDU was
+ *  delivered in-band with the rx indication message, or out of band through
+ *  MAC DMA.
+ *  In a LL system, this function returns a linked list of one or more
+ *  buffers corresponding to an MSDU
+ *  In a HL system , TODO
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param offload_deliver_msg - the nebuf containing the offload deliver message
+ * @param head_msdu - call-by-reference network buffer handle, which gets set in
+ *      this function to the head buffer of this MSDU
+ * @param tail_msdu - call-by-reference network buffer handle, which gets set in
+ *      this function to the tail buffer of this MSDU
+ */
+extern int
+(*htt_rx_offload_msdu_pop)(htt_pdev_handle pdev,
+			   qdf_nbuf_t offload_deliver_msg,
+			   int *vdev_id,
+			   int *peer_id,
+			   int *tid,
+			   uint8_t *fw_desc,
+			   qdf_nbuf_t *head_buf, qdf_nbuf_t *tail_buf);
+
+/**
+ * @brief Return the rx descriptor for the next rx MPDU.
+ * @details
+ *  The rx MSDU descriptors may be uploaded as part of the rx indication
+ *  message, or delivered separately out of band.
+ *  This function provides an abstract way to obtain the next MPDU descriptor,
+ *  regardless of whether the MPDU descriptors are delivered in-band with
+ *  the rx indication message, or out of band.
+ *  This is used to iterate through the series of MPDU descriptors referenced
+ *  by a rx indication message.
+ *  The htt_rx_amsdu_pop function should be called before this function
+ *  (or at least before using the returned rx descriptor handle), so that
+ *  the cache location for the rx descriptor will be flushed before the
+ *  rx descriptor gets used.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param rx_ind_msg - the netbuf containing the rx indication message
+ * @return next abstract rx descriptor from the series of MPDUs referenced
+ *      by an rx ind msg
+ */
+extern void *
+(*htt_rx_mpdu_desc_list_next)(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg);
+
+/**
+ * @brief Retrieve a previously-stored rx descriptor from a MSDU buffer.
+ * @details
+ *  The data SW will call the htt_rx_msdu_desc_link macro/function to
+ *  link a MSDU's rx descriptor with the buffer holding the MSDU payload.
+ *  This function retrieves the rx MSDU descriptor.
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param msdu - the buffer containing the MSDU payload
+ * @return the corresponding abstract rx MSDU descriptor
+ */
+extern void *
+(*htt_rx_msdu_desc_retrieve)(htt_pdev_handle pdev, qdf_nbuf_t msdu);
+
+/**
+ * @brief Free both an rx MSDU descriptor and the associated MSDU buffer.
+ * @details
+ *  Usually the WLAN driver does not free rx MSDU buffers, but needs to
+ *  do so when an invalid frame (e.g. FCS error) was deposited into the
+ *  queue of rx buffers.
+ *  This function frees both the rx descriptor and the rx frame.
+ *  On some systems, the rx descriptor and rx frame are stored in the
+ *  same buffer, and thus one free suffices for both objects.
+ *  On other systems, the rx descriptor and rx frame are stored
+ *  separately, so distinct frees are internally needed.
+ *  However, in either case, the rx descriptor has been associated with
+ *  the MSDU buffer, and can be retrieved by htt_rx_msdu_desc_retrieve.
+ *  Hence, it is only necessary to provide the MSDU buffer; the HTT SW
+ *  internally finds the corresponding MSDU rx descriptor.
+ *
+ * @param htt_pdev - the HTT instance the rx data was received on
+ * @param rx_msdu_desc - rx descriptor for the MSDU being freed
+ * @param msdu - rx frame buffer for the MSDU being freed
+ */
+void htt_rx_desc_frame_free(htt_pdev_handle htt_pdev, qdf_nbuf_t msdu);
+
+/**
+ * @brief Look up and free the rx descriptor for a MSDU.
+ * @details
+ *  When the driver delivers rx frames to the OS, it first needs
+ *  to free the associated rx descriptors.
+ *  In some systems the rx descriptors are allocated in the same
+ *  buffer as the rx frames, so this operation is a no-op.
+ *  In other systems, the rx descriptors are stored separately
+ *  from the rx frames, so the rx descriptor has to be freed.
+ *  The descriptor is located from the MSDU buffer with the
+ *  htt_rx_desc_frame_free macro/function.
+ *
+ * @param htt_pdev - the HTT instance the rx data was received on
+ * @param msdu - rx frame buffer for the rx MSDU descriptor being freed
+ */
+void htt_rx_msdu_desc_free(htt_pdev_handle htt_pdev, qdf_nbuf_t msdu);
+
+/**
+ * @brief Add new MSDU buffers for the target to fill.
+ * @details
+ *  In some systems, the underlying upload mechanism (HIF) allocates new rx
+ *  buffers itself.  In other systems, the underlying upload mechanism
+ *  (MAC DMA) needs to be provided with new rx buffers.
+ *  This function is used as an abstract method to indicate to the underlying
+ *  data upload mechanism when it is an appropriate time to allocate new rx
+ *  buffers.
+ *  If the allocation is automatically handled, a la HIF, then this function
+ *  call is ignored.
+ *  If the allocation has to be done explicitly, a la MAC DMA, then this
+ *  function provides the context and timing for such replenishment
+ *  allocations.
+ *
+ * @param pdev - the HTT instance the rx data will be received on
+ */
+void htt_rx_msdu_buff_replenish(htt_pdev_handle pdev);
+
+/**
+ * @brief Add new MSDU buffers for the target to fill.
+ * @details
+ *  This is full_reorder_offload version of the replenish function.
+ *  In full_reorder, FW sends HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND
+ *  msg to host. It includes the number of MSDUs. Thgis will be fed
+ *  into htt_rx_msdu_buff_in_order_replenish function.
+ *  The reason for creating yet another function is to avoid checks
+ *  in real-time.
+ *
+ * @param pdev - the HTT instance the rx data will be received on
+ * @num        - number of buffers to replenish
+ *
+ * Return: number of buffers actually replenished
+ */
+#ifndef CONFIG_HL_SUPPORT
+int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num);
+#else
+static inline
+int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num)
+{
+	return 0;
+}
+#endif
+
+/**
+ * @brief Links list of MSDUs into an single MPDU. Updates RX stats
+ * @details
+ *  When HW MSDU splitting is turned on each MSDU in an AMSDU MPDU occupies
+ *  a separate wbuf for delivery to the network stack. For delivery to the
+ *  monitor mode interface they need to be restitched into an MPDU. This
+ *  function does this. Also updates the RX status if the MPDU starts
+ *  a new PPDU
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ * @param head_msdu - network buffer handle, which points to the first MSDU
+ *      in the list. This is a NULL terminated list
+ * @param rx_staus - pointer to the status associated with this MPDU.
+ *      Updated only if there is a new PPDU and new status associated with it
+ * @param clone_not_reqd - If set the MPDU linking destroys the passed in
+ *      list, else operates on a cloned nbuf
+ * @return network buffer handle to the MPDU
+ */
+#if defined(FEATURE_MONITOR_MODE_SUPPORT)
+#if !defined(QCA6290_HEADERS_DEF) && !defined(QCA6390_HEADERS_DEF)
+qdf_nbuf_t
+htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev,
+				qdf_nbuf_t head_msdu,
+				struct ieee80211_rx_status *rx_status,
+				unsigned clone_not_reqd);
+#else
+static inline qdf_nbuf_t
+htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev,
+				qdf_nbuf_t head_msdu,
+				struct ieee80211_rx_status *rx_status,
+				unsigned clone_not_reqd)
+{
+	return NULL;
+}
+#endif
+#endif
+/**
+ * @brief Return the sequence number of MPDUs to flush.
+ * @param pdev - the HTT instance the rx data was received on
+ * @param rx_frag_ind_msg - the netbuf containing the rx fragment indication
+ *      message
+ * @param seq_num_start - (call-by-reference output) sequence number
+ *      for the start of the range of MPDUs to flush
+ * @param seq_num_end - (call-by-reference output) sequence number
+ *      for the end of the range of MPDUs to flush
+ */
+void
+htt_rx_frag_ind_flush_seq_num_range(htt_pdev_handle pdev,
+				    qdf_nbuf_t rx_frag_ind_msg,
+				    uint16_t *seq_num_start, uint16_t *seq_num_end);
+
+#ifdef CONFIG_HL_SUPPORT
+/**
+ * htt_rx_msdu_rx_desc_size_hl() - Return the HL rx desc size
+ * @pdev: the HTT instance the rx data was received on.
+ * @msdu_desc: the hl rx desc pointer
+ *
+ * Return: HL rx desc size
+ */
+uint16_t htt_rx_msdu_rx_desc_size_hl(htt_pdev_handle pdev, void *msdu_desc);
+#else
+static inline
+uint16_t htt_rx_msdu_rx_desc_size_hl(htt_pdev_handle pdev, void *msdu_desc)
+{
+	return 0;
+}
+#endif
+
+/**
+ * @brief populates vowext stats by processing RX desc.
+ * @param msdu - network buffer handle
+ * @param vowstats - handle to vow ext stats.
+ */
+void htt_rx_get_vowext_stats(qdf_nbuf_t msdu, struct vow_extstats *vowstats);
+
+/**
+ * @brief parses the offload message passed by the target.
+ * @param pdev - pdev handle
+ * @param paddr - physical address of the rx buffer
+ * @param vdev_id - reference to vdev id to be filled
+ * @param peer_id - reference to the peer id to be filled
+ * @param tid - reference to the tid to be filled
+ * @param fw_desc - reference to the fw descriptor to be filled
+ * @param peer_id - reference to the peer id to be filled
+ * @param head_buf - reference to the head buffer
+ * @param tail_buf - reference to the tail buffer
+ */
+int
+htt_rx_offload_paddr_msdu_pop_ll(htt_pdev_handle pdev,
+				 uint32_t *msg_word,
+				 int msdu_iter,
+				 int *vdev_id,
+				 int *peer_id,
+				 int *tid,
+				 uint8_t *fw_desc,
+				 qdf_nbuf_t *head_buf, qdf_nbuf_t *tail_buf);
+
+uint32_t htt_rx_amsdu_rx_in_order_get_pktlog(qdf_nbuf_t rx_ind_msg);
+
+/**
+ * htt_rx_update_smmu_map() - set smmu map/unmap for rx buffers
+ * @pdev: htt pdev handle
+ * @map: value to set smmu map/unmap for rx buffers
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS htt_rx_update_smmu_map(struct htt_pdev_t *pdev, bool map);
+#endif /* _OL_HTT_RX_API__H_ */
diff --git a/core/dp/ol/inc/ol_htt_tx_api.h b/core/dp/ol/inc/ol_htt_tx_api.h
new file mode 100644
index 0000000..99dcece
--- /dev/null
+++ b/core/dp/ol/inc/ol_htt_tx_api.h
@@ -0,0 +1,844 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ * @file ol_htt_tx_api.h
+ * @brief Specify the tx HTT API functions called by the host data SW.
+ * @details
+ *  This file declares the HTT API functions that are specifically
+ *  related to transmit processing.
+ *  In particular, the methods of the abstract HTT tx descriptor are
+ *  specified.
+ */
+#ifndef _OL_HTT_TX_API__H_
+#define _OL_HTT_TX_API__H_
+
+/* #include <osapi_linux.h>    / * uint16_t, etc. * / */
+#include <osdep.h>              /* uint16_t, etc. */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <ol_cfg.h>             /* wlan_frm_fmt */
+
+#include <htt.h>                /* needed by inline functions */
+#include <qdf_net_types.h>
+#include <ol_htt_api.h>         /* htt_pdev_handle */
+#include <htt_types.h>
+#include <qdf_trace.h>
+#include <cds_api.h>
+
+#define HTT_INVALID_CHANNEL -1
+
+/* Remove these macros when they get added to htt.h. */
+#ifndef HTT_TX_DESC_EXTENSION_GET
+#define HTT_TX_DESC_EXTENSION_OFFSET_BYTES 0
+#define HTT_TX_DESC_EXTENSION_OFFSET_DWORD 0
+#define HTT_TX_DESC_EXTENSION_M        0x10000000
+#define HTT_TX_DESC_EXTENSION_S        28
+
+#define HTT_TX_DESC_EXTENSION_GET(_var) \
+	(((_var) & HTT_TX_DESC_EXTENSION_M) >> HTT_TX_DESC_EXTENSION_S)
+#define HTT_TX_DESC_EXTENSION_SET(_var, _val)				\
+	do {								\
+		HTT_CHECK_SET_VAL(HTT_TX_DESC_EXTENSION, _val);		\
+		((_var) |= ((_val) << HTT_TX_DESC_EXTENSION_S));	\
+	} while (0)
+#endif
+
+/*================ meta-info about tx MSDUs =================================*/
+
+/*
+ * For simplicity, use the IEEE 802.11 frame type values.
+ */
+enum htt_frm_type {
+	htt_frm_type_mgmt = 0,
+	htt_frm_type_ctrl = 1,
+	htt_frm_type_data = 2
+};
+
+/*
+ * For simplicity, use the IEEE 802.11 frame sub-type values.
+ */
+enum htt_frm_subtype {
+	htt_frm_subtype_mgmt_assoc_req = 0,
+	htt_frm_subtype_mgmt_assoc_resp = 1,
+	htt_frm_subtype_mgmt_reassoc_req = 2,
+	htt_frm_subtype_mgmt_reassoc_resp = 3,
+	htt_frm_subtype_mgmt_probe_req = 4,
+	htt_frm_subtype_mgmt_probe_resp = 5,
+	htt_frm_subtype_mgmt_timing_adv = 6,
+	htt_frm_subtype_mgmt_beacon = 8,
+	htt_frm_subtype_mgmt_atim = 9,
+	htt_frm_subtype_mgmt_disassoc = 10,
+	htt_frm_subtype_mgmt_auth = 11,
+	htt_frm_subtype_mgmt_deauth = 12,
+	htt_frm_subtype_mgmt_action = 13,
+	htt_frm_subtype_mgmt_action_no_ack = 14,
+
+	htt_frm_subtype_data_data = 0,
+	htt_frm_subtype_data_data_cf_ack = 1,
+	htt_frm_subtype_data_data_cf_poll = 2,
+	htt_frm_subtype_data_data_cf_ack_cf_poll = 3,
+	htt_frm_subtype_data_null = 4,
+	htt_frm_subtype_data_cf_ack = 5,
+	htt_frm_subtype_data_cf_poll = 6,
+	htt_frm_subtype_data_cf_ack_cf_poll = 7,
+	htt_frm_subtype_data_QoS_data = 8,
+	htt_frm_subtype_data_QoS_data_cf_ack = 9,
+	htt_frm_subtype_data_QoS_data_cf_poll = 10,
+	htt_frm_subtype_data_QoS_data_cf_ack_cf_poll = 11,
+	htt_frm_subtype_data_QoS_null = 12,
+	htt_frm_subtype_data_QoS_cf_poll = 14,
+	htt_frm_subtype_data_QoS_cf_ack_cf_poll = 15,
+};
+
+enum htt_ofdm_datarate {		/* Value    MBPS    Modulation  Coding*/
+	htt_ofdm_datarate_6_mbps = 0,	/* 0        6       BPSK        1/2   */
+	htt_ofdm_datarate_9_mbps = 1,	/* 1        9       BPSK        3/4   */
+	htt_ofdm_datarate_12_mbps = 2,	/* 2        12      QPSK        1/2   */
+	htt_ofdm_datarate_18_mbps = 3,	/* 3        18      QPSK        3/4   */
+	htt_ofdm_datarate_24_mbps = 4,	/* 4        24      16-QAM      1/2   */
+	htt_ofdm_datarate_36_mbps = 5,	/* 5        36      16-QAM      3/4   */
+	htt_ofdm_datarate_48_mbps = 6,	/* 6        48      64-QAM      1/2   */
+	htt_ofdm_datarate_54_mbps = 7,	/* 7        54      64-QAM      3/4   */
+	htt_ofdm_datarate_max = 7,
+};
+
+/**
+ * struct ocb_tx_ctrl_hdr_t - TX control header
+ * @version:		must be 1
+ * @length:		length of this structure
+ * @channel_freq:	channel on which to transmit the packet
+ * @valid_pwr:		bit 0: if set, tx pwr spec is valid
+ * @valid_datarate:	bit 1: if set, tx MCS mask spec is valid
+ * @valid_retries:	bit 2: if set, tx retries spec is valid
+ * @valid_chain_mask:	bit 3: if set, chain mask is valid
+ * @valid_expire_tsf:	bit 4: if set, tx expire TSF spec is valid
+ * @valid_tid:		bit 5: if set, TID is valid
+ * @reserved0_15_6:	bits 15:6 - unused, set to 0x0
+ * @all_flags:		union of all the flags
+ * @expire_tsf_lo:	TX expiry time (TSF) LSBs
+ * @expire_tsf_hi:	TX expiry time (TSF) MSBs
+ * @pwr:		Specify what power the tx frame needs to be transmitted
+ *			at. The power a signed (two's complement) value is in
+ *			units of 0.5 dBm. The value needs to be appropriately
+ *			sign-extended when extracting the value from the message
+ *			and storing it in a variable that is larger than A_INT8.
+ *			If the transmission uses multiple tx chains, this power
+ *			spec is the total transmit power, assuming incoherent
+ *			combination of per-chain power to produce the total
+ *			power.
+ * @datarate:		The desired modulation and coding scheme.
+ *			VALUE    DATA RATE   MODULATION  CODING RATE
+ *			@ 20 MHz
+ *			(MBPS)
+ *			0        6           BPSK        1/2
+ *			1        9           BPSK        3/4
+ *			2        12          QPSK        1/2
+ *			3        18          QPSK        3/4
+ *			4        24          16-QAM      1/2
+ *			5        36          16-QAM      3/4
+ *			6        48          64-QAM      1/2
+ *			7        54          64-QAM      3/4
+ * @retry_limit:	Specify the maximum number of transmissions, including
+ *			the initial transmission, to attempt before giving up if
+ *			no ack is received.
+ *			If the tx rate is specified, then all retries shall use
+ *			the same rate as the initial transmission.
+ *			If no tx rate is specified, the target can choose
+ *			whether to retain the original rate during the
+ *			retransmissions, or to fall back to a more robust rate.
+ * @chain_mask:		specify which chains to transmit from
+ * @ext_tid:		Extended Traffic ID (0-15)
+ * @reserved:		Ensure that the size of the structure is a multiple of
+ *			4. Must be 0.
+ *
+ * When sending an OCB packet, the user application has
+ * the option of including the following struct following an ethernet header
+ * with the proto field set to 0x8151. This struct includes various TX
+ * paramaters including the TX power and MCS.
+ */
+PREPACK struct ocb_tx_ctrl_hdr_t {
+	uint16_t version;
+	uint16_t length;
+	uint16_t channel_freq;
+
+	union {
+		struct {
+			uint16_t
+			valid_pwr:1,
+			valid_datarate:1,
+			valid_retries:1,
+			valid_chain_mask:1,
+			valid_expire_tsf:1,
+			valid_tid:1,
+			reserved0_15_6:10;
+		};
+		uint16_t all_flags;
+	};
+
+	uint32_t expire_tsf_lo;
+	uint32_t expire_tsf_hi;
+	int8_t pwr;
+	uint8_t datarate;
+	uint8_t retry_limit;
+	uint8_t chain_mask;
+	uint8_t ext_tid;
+	uint8_t reserved[3];
+} POSTPACK;
+
+/**
+ * @brief tx MSDU meta-data that HTT may use to program the FW/HW tx descriptor
+ */
+struct htt_msdu_info_t {
+	/* the info sub-struct specifies the characteristics of the MSDU */
+	struct {
+		uint16_t ethertype;
+#define HTT_INVALID_PEER_ID 0xffff
+		uint16_t peer_id;
+		uint8_t vdev_id;
+		uint8_t ext_tid;
+		/*
+		 * l2_hdr_type - L2 format (802.3, native WiFi 802.11,
+		 * or raw 802.11)
+		 * Based on attach-time configuration, the tx frames provided
+		 * by the OS to the tx data SW are expected to be either
+		 * 802.3 format or the "native WiFi" variant of 802.11 format.
+		 * Internally, the driver may also inject tx frames into the tx
+		 * datapath, and these frames may be either 802.3 format or
+		 * 802.11 "raw" format, with no further 802.11 encapsulation
+		 * needed.
+		 * The tx frames are tagged with their frame format, so target
+		 * FW/HW will know how to interpret the packet's encapsulation
+		 * headers when doing tx classification, and what form of 802.11
+		 * header encapsulation is needed, if any.
+		 */
+		uint8_t l2_hdr_type;    /* enum htt_pkt_type */
+		/*
+		 * frame_type - is the tx frame management or data?
+		 * Just to avoid confusion, the enum values for this frame type
+		 * field use the 802.11 frame type values, although it is
+		 * unexpected for control frames to be sent through the host
+		 * data path.
+		 */
+		uint8_t frame_type;     /* enum htt_frm_type */
+		/*
+		 * frame subtype - this field specifies the sub-type of
+		 * management frames
+		 * Just to avoid confusion, the enum values for this frame
+		 * subtype field use the 802.11 management frame subtype values.
+		 */
+		uint8_t frame_subtype;  /* enum htt_frm_subtype */
+		uint8_t is_unicast;
+
+		/* dest_addr is not currently used.
+		 * It could be used as an input to a Tx BD (Riva tx descriptor)
+		 * signature computation.
+		   uint8_t *dest_addr;
+		 */
+
+		uint8_t l3_hdr_offset;  /* wrt qdf_nbuf_data(msdu), in bytes */
+
+		/* l4_hdr_offset is not currently used.
+		 * It could be used to specify to a TCP/UDP checksum computation
+		 * engine where the TCP/UDP header starts.
+		 */
+		/* uint8_t l4_hdr_offset; - wrt qdf_nbuf_data(msdu), in bytes */
+	} info;
+	/* the action sub-struct specifies how to process the MSDU */
+	struct {
+		/* mgmt frames: option to force 6 Mbps rate */
+		uint8_t use_6mbps;
+		uint8_t do_encrypt;
+		uint8_t do_tx_complete;
+		uint8_t tx_comp_req;
+
+		/*
+		 * cksum_offload - Specify whether checksum offload is
+		 * enabled or not
+		 * Target FW uses this flag to turn on HW checksumming
+		 * 0x0 - No checksum offload
+		 * 0x1 - L3 header checksum only
+		 * 0x2 - L4 checksum only
+		 * 0x3 - L3 header checksum + L4 checksum
+		 */
+		qdf_nbuf_tx_cksum_t cksum_offload;
+	} action;
+};
+
+static inline void htt_msdu_info_dump(struct htt_msdu_info_t *msdu_info)
+{
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "HTT MSDU info object (%pK)\n", msdu_info);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  ethertype: %#x\n", msdu_info->info.ethertype);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  peer_id: %d\n", msdu_info->info.peer_id);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  vdev_id: %d\n", msdu_info->info.vdev_id);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  ext_tid: %d\n", msdu_info->info.ext_tid);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  l2_hdr_type: %d\n", msdu_info->info.l2_hdr_type);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  frame_type: %d\n", msdu_info->info.frame_type);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  frame_subtype: %d\n", msdu_info->info.frame_subtype);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  is_unicast: %u\n", msdu_info->info.is_unicast);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  l3_hdr_offset: %u\n", msdu_info->info.l3_hdr_offset);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  use 6 Mbps: %d\n", msdu_info->action.use_6mbps);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  do_encrypt: %d\n", msdu_info->action.do_encrypt);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  do_tx_complete: %d\n", msdu_info->action.do_tx_complete);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  is_unicast: %u\n", msdu_info->info.is_unicast);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "  is_unicast: %u\n", msdu_info->info.is_unicast);
+}
+
+/*================ tx completion message field access methods ===============*/
+
+/**
+ * @brief Look up the descriptor ID of the nth MSDU from a tx completion msg.
+ * @details
+ *  A tx completion message tells the host that the target is done
+ *  transmitting a series of MSDUs.  The message uses a descriptor ID
+ *  to identify each such MSDU.  This function/macro is used to
+ *  find the ID of one such MSDU referenced by the tx completion message.
+ *
+ * @param iterator - tx completion message context provided by HTT to the
+ *      tx completion message handler.  This abstract reference to the
+ *      HTT tx completion message's payload allows the data SW's tx
+ *      completion handler to not care about the format of the HTT
+ *      tx completion message.
+ * @param num - (zero-based) index to specify a single MSDU within the
+ *      series of MSDUs referenced by the tx completion message
+ * @return descriptor ID for the specified MSDU
+ */
+uint16_t htt_tx_compl_desc_id(void *iterator, int num);
+
+/*========================= tx descriptor operations ========================*/
+
+/**
+ * @brief Allocate a HTT abstract tx descriptor.
+ * @details
+ *  Allocate a HTT abstract tx descriptor from a pool within "consistent"
+ *  memory, which is accessible by HIF and/or MAC DMA as well as by the
+ *  host CPU.
+ *  It is expected that the tx datapath will allocate HTT tx descriptors
+ *  and link them with datapath SW tx descriptors up front as the driver
+ *  is loaded.  Thereafter, the link from datapath SW tx descriptor to
+ *  HTT tx descriptor will be maintained until the driver is unloaded.
+ *
+ * @param htt_pdev - handle to the HTT instance making the allocation
+ * @param[OUT] paddr_lo - physical address of the HTT descriptor
+ * @return success -> descriptor handle, -OR- failure -> NULL
+ */
+void *htt_tx_desc_alloc(htt_pdev_handle pdev, qdf_dma_addr_t *paddr,
+			uint16_t index);
+
+/**
+ * @brief Free a HTT abstract tx descriptor.
+ *
+ * @param htt_pdev - handle to the HTT instance that made the allocation
+ * @param htt_tx_desc - the descriptor to free
+ */
+void htt_tx_desc_free(htt_pdev_handle htt_pdev, void *htt_tx_desc);
+
+#if defined(HELIUMPLUS)
+/**
+ * @brief Allocate TX frag descriptor
+ * @details
+ *  Allocate TX frag descriptor
+ *
+ * @param pdev - handle to the HTT instance that made the allocation
+ * @param index - tx descriptor index
+ * @param frag_paddr_lo - fragment descriptor physical address lower 32bits
+ * @param frag_ptr - fragment descriptor hlos pointe
+ * @return success 0
+ */
+int htt_tx_frag_alloc(htt_pdev_handle pdev,
+	u_int16_t index, qdf_dma_addr_t *frag_paddr, void **frag_ptr);
+#else
+static inline int htt_tx_frag_alloc(htt_pdev_handle pdev,
+	u_int16_t index, qdf_dma_addr_t *frag_paddr, void **frag_ptr)
+{
+	*frag_ptr = NULL;
+	return 0;
+}
+#endif /* defined(HELIUMPLUS) */
+
+#if defined(CONFIG_HL_SUPPORT)
+
+/**
+ * @brief Discard all tx frames in the process of being downloaded.
+ * @details
+ * This function dicards any tx frames queued in HTT or the layers
+ * under HTT.
+ * The download completion callback is invoked on these frames.
+ *
+ * @param htt_pdev - handle to the HTT instance
+ * @param[OUT] frag_paddr_lo - physical address of the fragment descriptor
+ *                             (MSDU Link Extension Descriptor)
+ */
+static inline void htt_tx_pending_discard(htt_pdev_handle pdev)
+{
+}
+#else
+
+void htt_tx_pending_discard(htt_pdev_handle pdev);
+#endif
+
+/**
+ * @brief Download a MSDU descriptor and (a portion of) the MSDU payload.
+ * @details
+ *  This function is used within LL systems to download a tx descriptor and
+ *  the initial portion of the tx MSDU payload, and within HL systems to
+ *  download the tx descriptor and the entire tx MSDU payload.
+ *  The HTT layer determines internally how much of the tx descriptor
+ *  actually needs to be downloaded. In particular, the HTT layer does not
+ *  download the fragmentation descriptor, and only for the LL case downloads
+ *  the physical address of the fragmentation descriptor.
+ *  In HL systems, the tx descriptor and the entire frame are downloaded.
+ *  In LL systems, only the tx descriptor and the header of the frame are
+ *  downloaded.  To determine how much of the tx frame to download, this
+ *  function assumes the tx frame is the default frame type, as specified
+ *  by ol_cfg_frame_type.  "Raw" frames need to be transmitted through the
+ *  alternate htt_tx_send_nonstd function.
+ *  The tx descriptor has already been attached to the qdf_nbuf object during
+ *  a preceding call to htt_tx_desc_init.
+ *
+ * @param htt_pdev - the handle of the physical device sending the tx data
+ * @param msdu - the frame being transmitted
+ * @param msdu_id - unique ID for the frame being transmitted
+ * @return 0 -> success, -OR- 1 -> failure
+ */
+int
+htt_tx_send_std(htt_pdev_handle htt_pdev, qdf_nbuf_t msdu, uint16_t msdu_id);
+
+/**
+ * @brief Download a Batch Of Tx MSDUs
+ * @details
+ *     Each MSDU already has the MSDU ID stored in the headroom of the
+ *     netbuf data buffer, and has the HTT tx descriptor already attached
+ *     as a prefix fragment to the netbuf.
+ *
+ * @param htt_pdev - the handle of the physical device sending the tx data
+ * @param head_msdu - the MSDU Head for Tx batch being transmitted
+ * @param num_msdus - The total Number of MSDU's provided for batch tx
+ * @return null-terminated linked-list of unaccepted frames
+ */
+qdf_nbuf_t
+htt_tx_send_batch(htt_pdev_handle htt_pdev,
+		  qdf_nbuf_t head_msdu, int num_msdus);
+
+/* The htt scheduler for queued packets in htt
+ * htt when unable to send to HTC because of lack of resource
+ * forms a nbuf queue which is flushed when tx completion event from
+ * target is received
+ */
+
+void htt_tx_sched(htt_pdev_handle pdev);
+
+/**
+ * @brief Same as htt_tx_send_std, but can handle raw frames.
+ */
+int
+htt_tx_send_nonstd(htt_pdev_handle htt_pdev,
+		   qdf_nbuf_t msdu,
+		   uint16_t msdu_id, enum htt_pkt_type pkt_type);
+
+/**
+ * htt_pkt_dl_len_get() Gets the HTT PKT download length.
+ * @pdev: pointer to struct htt_pdev_t
+ *
+ * Return: size of HTT packet download length.
+ */
+int
+htt_pkt_dl_len_get(struct htt_pdev_t *pdev);
+
+/* Used to set classify bit in HTT desc.*/
+#define HTT_TX_CLASSIFY_BIT_S	4
+
+/**
+ * enum htt_ce_tx_pkt_type - enum of packet types to be set in CE
+ *			     descriptor
+ * @tx_pkt_type_raw: Value set for RAW frames
+ * @tx_pkt_type_native_wifi: Value set for NATIVE WIFI frames
+ * @tx_pkt_type_eth2: Value set for Ethernet II frames (mostly default)
+ * @tx_pkt_type_802_3: Value set for 802.3 / original ethernet frames
+ * @tx_pkt_type_mgmt: Value set for MGMT frames over HTT
+ *
+ */
+enum htt_ce_tx_pkt_type {
+	tx_pkt_type_raw = 0,
+	tx_pkt_type_native_wifi = 1,
+	tx_pkt_type_eth2 = 2,
+	tx_pkt_type_802_3 = 3,
+	tx_pkt_type_mgmt = 4
+};
+
+/**
+ * enum extension_header_type - extension header type
+ * @EXT_HEADER_NOT_PRESENT: extension header not present
+ * @OCB_MODE_EXT_HEADER: Extension header for OCB mode
+ * @WISA_MODE_EXT_HEADER_6MBPS: WISA mode 6Mbps header
+ * @WISA_MODE_EXT_HEADER_24MBPS: WISA mode 24Mbps header
+ */
+enum extension_header_type {
+	EXT_HEADER_NOT_PRESENT,
+	OCB_MODE_EXT_HEADER,
+	WISA_MODE_EXT_HEADER_6MBPS,
+	WISA_MODE_EXT_HEADER_24MBPS,
+};
+
+extern const uint32_t htt_to_ce_pkt_type[];
+
+/**
+ * Provide a constant to specify the offset of the HTT portion of the
+ * HTT tx descriptor, to avoid having to export the descriptor definition.
+ * The htt module checks internally that this exported offset is consistent
+ * with the private tx descriptor definition.
+ *
+ * Similarly, export a definition of the HTT tx descriptor size, and then
+ * check internally that this exported constant matches the private tx
+ * descriptor definition.
+ */
+#define HTT_TX_DESC_VADDR_OFFSET 8
+
+/**
+ * htt_tx_desc_init() - Initialize the per packet HTT Tx descriptor
+ * @pdev:		  The handle of the physical device sending the
+ *			  tx data
+ * @htt_tx_desc:	  Abstract handle to the tx descriptor
+ * @htt_tx_desc_paddr_lo: Physical address of the HTT tx descriptor
+ * @msdu_id:		  ID to tag the descriptor with.
+ *			  The FW sends this ID back to host as a cookie
+ *			  during Tx completion, which the host uses to
+ *			  identify the MSDU.
+ *			  This ID is an index into the OL Tx desc. array.
+ * @msdu:		  The MSDU that is being prepared for transmission
+ * @msdu_info:		  Tx MSDU meta-data
+ * @tso_info:		  Storage for TSO meta-data
+ * @ext_header_data:      extension header data
+ * @type:                 extension header type
+ *
+ * This function initializes the HTT tx descriptor.
+ * HTT Tx descriptor is a host-f/w interface structure, and meta-data
+ * accompanying every packet downloaded to f/w via the HTT interface.
+ *
+ * Return QDF_STATUS_SUCCESS for success, otherwise error.
+ */
+QDF_STATUS
+htt_tx_desc_init(htt_pdev_handle pdev,
+		 void *htt_tx_desc,
+		 qdf_dma_addr_t htt_tx_desc_paddr,
+		 uint16_t msdu_id,
+		 qdf_nbuf_t msdu, struct htt_msdu_info_t *msdu_info,
+		 struct qdf_tso_info_t *tso_info,
+		 void *ext_header_data,
+		 enum extension_header_type type);
+
+/**
+ * @brief Set a flag to indicate that the MSDU in question was postponed.
+ * @details
+ *  In systems in which the host retains its tx frame until the target sends
+ *  a tx completion, the target has the option of discarding it's copy of
+ *  the tx descriptor (and frame, for HL) and sending a "postpone" message
+ *  to the host, to inform the host that it must eventually download the
+ *  tx descriptor (and frame, for HL).
+ *  Before the host downloads the postponed tx desc/frame again, it will use
+ *  this function to set a flag in the HTT tx descriptor indicating that this
+ *  is a re-send of a postponed frame, rather than a new frame.  The target
+ *  uses this flag to keep the correct order between re-sent and new tx frames.
+ *  This function is relevant for LL systems.
+ *
+ * @param pdev - the handle of the physical device sending the tx data
+ * @param desc - abstract handle to the tx descriptor
+ */
+void htt_tx_desc_flag_postponed(htt_pdev_handle pdev, void *desc);
+
+/**
+ * @brief Set a flag to tell the target that more tx downloads are en route.
+ * @details
+ *  At times, particularly in response to a U-APSD trigger in a HL system, the
+ *  host will download multiple tx descriptors (+ frames, in HL) in a batch.
+ *  The host will use this function to set a "more" flag in the initial
+ *  and interior frames of the batch, to tell the target that more tx frame
+ *  downloads within the batch are imminent.
+ *
+ * @param pdev - the handle of the physical device sending the tx data
+ * @param desc - abstract handle to the tx descriptor
+ */
+void htt_tx_desc_flag_batch_more(htt_pdev_handle pdev, void *desc);
+
+/**
+ * @brief Specify the number of fragments in the fragmentation descriptor.
+ * @details
+ *  Specify the number of fragments within the MSDU, i.e. the number of
+ *  elements within the fragmentation descriptor.
+ *  For LL, this is used to terminate the list of fragments used by the
+ *  HW's tx MAC DMA.
+ *  For HL, this is used to terminate the list of fragments provided to
+ *  HTC for download.
+ *
+ * @param pdev - the handle of the physical device sending the tx data
+ * @param desc - abstract handle to the tx descriptor
+ * @param num_frags - the number of fragments comprising the MSDU
+ */
+static inline
+void
+htt_tx_desc_num_frags(htt_pdev_handle pdev, void *desc, uint32_t num_frags)
+{
+	/*
+	 * Set the element after the valid frag elems to 0x0,
+	 * to terminate the list of fragments.
+	 */
+#if defined(HELIUMPLUS)
+	if (HTT_WIFI_IP(pdev, 2, 0)) {
+		struct msdu_ext_frag_desc *fdesc;
+
+		/** Skip TSO related 4 dwords WIFI2.0*/
+		fdesc = (struct msdu_ext_frag_desc *)
+			&(((struct msdu_ext_desc_t *)desc)->frags[0]);
+		fdesc[num_frags].u.desc64 = 0;
+	} else {
+		/* This piece of code should never be executed on HELIUMPLUS */
+		*((u_int32_t *)
+		  (((char *) desc) + HTT_TX_DESC_LEN + num_frags * 8)) = 0;
+	}
+#else /* ! HELIUMPLUS */
+	*((uint32_t *)
+	  (((char *)desc) + HTT_TX_DESC_LEN + num_frags * 8)) = 0;
+#endif /* HELIUMPLUS */
+}
+
+/* checksum offload flags for hw */
+#define IPV4_CSUM_EN     0x00010000
+#define UDP_IPV4_CSUM_EN 0x00020000
+#define UDP_IPV6_CSUM_EN 0x00040000
+#define TCP_IPV4_CSUM_EN 0x00080000
+#define TCP_IPV6_CSUM_EN 0x00100000
+#define PARTIAL_CSUM_EN  0x00200000
+
+/**
+ * @brief Specify the location and size of a fragment of a tx MSDU.
+ * @details
+ *  In LL systems, the tx MAC DMA needs to know how the MSDU is constructed
+ *  from fragments.
+ *  In LL and HL systems, the HIF's download DMA to the target (LL: tx desc
+ *  + header of tx payload; HL: tx desc + entire tx payload) needs to know
+ *  where to find the fragments to download.
+ *  The tx data SW uses this function to specify the location and size of
+ *  each of the MSDU's fragments.
+ *
+ * @param pdev - the handle of the physical device sending the tx data
+ * @param desc - abstract handle to the HTT tx descriptor
+ * @param frag_num - which fragment is being specified (zero-based indexing)
+ * @param frag_phys_addr - DMA/physical address of the fragment
+ * @param frag_len - number of bytes within the fragment
+ */
+static inline
+void
+htt_tx_desc_frag(htt_pdev_handle pdev,
+		 void *desc,
+		 int frag_num, qdf_dma_addr_t frag_phys_addr, uint16_t frag_len)
+{
+	uint32_t *word32;
+#if defined(HELIUMPLUS)
+	uint64_t  *word64;
+
+	if (HTT_WIFI_IP(pdev, 2, 0)) {
+		word32 = (u_int32_t *)(desc);
+		/* Initialize top 6 words of TSO flags per packet */
+		*word32++ = 0;
+		*word32++ = 0;
+		*word32++ = 0;
+		if (((struct txrx_pdev_cfg_t *)(pdev->ctrl_pdev))
+		    ->ip_tcp_udp_checksum_offload)
+			*word32 |= (IPV4_CSUM_EN | TCP_IPV4_CSUM_EN |
+					TCP_IPV6_CSUM_EN | UDP_IPV4_CSUM_EN |
+					UDP_IPV6_CSUM_EN);
+		else
+			*word32 = 0;
+		word32++;
+		*word32++ = 0;
+		*word32++ = 0;
+
+		qdf_assert_always(word32 == (uint32_t *)
+				&(((struct msdu_ext_desc_t *)desc)->frags[0]));
+
+		/* Each fragment consumes 2 DWORDS */
+		word32 += (frag_num << 1);
+		word64 = (uint64_t *)word32;
+		*word64 = frag_phys_addr;
+		/*
+		 * The frag_phys address is 37 bits. So, the higher 16 bits will
+		 * be for len
+		 */
+		word32++;
+		*word32 &= 0x0000ffff;
+		*word32 |= (frag_len << 16);
+	} else {
+		/* For Helium+, this block cannot exist */
+		QDF_ASSERT(0);
+	}
+#else /* !defined(HELIUMPLUS) */
+	{
+		uint64_t u64  = (uint64_t)frag_phys_addr;
+		uint32_t u32l = (u64 & 0xffffffff);
+		uint32_t u32h = (uint32_t)((u64 >> 32) & 0x1f);
+		uint64_t *word64;
+
+		word32 = (uint32_t *) (((char *)desc) +
+			 HTT_TX_DESC_LEN + frag_num * 8);
+		word64 = (uint64_t *)word32;
+		*word32 = u32l;
+		word32++;
+		*word32 = (u32h << 16) | frag_len;
+	}
+#endif /* defined(HELIUMPLUS) */
+}
+
+void htt_tx_desc_frags_table_set(htt_pdev_handle pdev,
+				 void *desc,
+				 qdf_dma_addr_t paddr,
+				 qdf_dma_addr_t frag_desc_paddr,
+				 int reset);
+
+/**
+ * @brief Specify the type and subtype of a tx frame.
+ *
+ * @param pdev - the handle of the physical device sending the tx data
+ * @param type - format of the MSDU (802.3, native WiFi, raw, or mgmt)
+ * @param sub_type - sub_type (relevant for raw frames)
+ */
+static inline
+void
+htt_tx_desc_type(htt_pdev_handle pdev,
+		 void *htt_tx_desc, enum htt_pkt_type type, uint8_t sub_type)
+{
+	uint32_t *word0;
+
+	word0 = (uint32_t *) htt_tx_desc;
+	/* clear old values */
+	*word0 &= ~(HTT_TX_DESC_PKT_TYPE_M | HTT_TX_DESC_PKT_SUBTYPE_M);
+	/* write new values */
+	HTT_TX_DESC_PKT_TYPE_SET(*word0, type);
+	HTT_TX_DESC_PKT_SUBTYPE_SET(*word0, sub_type);
+}
+
+/***** TX MGMT DESC management APIs ****/
+
+/* Number of mgmt descriptors in the pool */
+#define HTT_MAX_NUM_MGMT_DESCS 32
+
+/** htt_tx_mgmt_desc_pool_alloc
+ * @description - allocates the memory for mgmt frame descriptors
+ * @param  - htt pdev object
+ * @param  - num of descriptors to be allocated in the pool
+ */
+void htt_tx_mgmt_desc_pool_alloc(struct htt_pdev_t *pdev, A_UINT32 num_elems);
+
+/** htt_tx_mgmt_desc_alloc
+ * @description - reserves a mgmt descriptor from the pool
+ * @param  - htt pdev object
+ * @param  - pointer to variable to hold the allocated desc id
+ * @param  - pointer to the mamangement from UMAC
+ * @return - pointer the allocated mgmt descriptor
+ */
+qdf_nbuf_t
+htt_tx_mgmt_desc_alloc(struct htt_pdev_t *pdev, A_UINT32 *desc_id,
+		       qdf_nbuf_t mgmt_frm);
+
+/** htt_tx_mgmt_desc_free
+ * @description - releases the management descriptor back to the pool
+ * @param  - htt pdev object
+ * @param  - descriptor ID
+ */
+void
+htt_tx_mgmt_desc_free(struct htt_pdev_t *pdev, A_UINT8 desc_id,
+		      A_UINT32 status);
+
+/** htt_tx_mgmt_desc_pool_free
+ * @description - releases all the resources allocated for mgmt desc pool
+ * @param  - htt pdev object
+ */
+void htt_tx_mgmt_desc_pool_free(struct htt_pdev_t *pdev);
+
+/**
+ * @brief Provide a buffer to store a 802.11 header added by SW tx encap
+ *
+ * @param htt_tx_desc - which frame the 802.11 header is being added to
+ * @param new_l2_hdr_size - how large the buffer needs to be
+ */
+#define htt_tx_desc_mpdu_header(htt_tx_desc, new_l2_hdr_size) /*NULL*/
+/**
+ * @brief How many tx credits would be consumed by the specified tx frame.
+ *
+ * @param msdu - the tx frame in question
+ * @return number of credits used for this tx frame
+ */
+#define htt_tx_msdu_credit(msdu) 1      /* 1 credit per buffer */
+#ifdef HTT_DBG
+void htt_tx_desc_display(void *tx_desc);
+#else
+#define htt_tx_desc_display(tx_desc)
+#endif
+
+static inline void htt_tx_desc_set_peer_id(void *htt_tx_desc, uint16_t peer_id)
+{
+	uint16_t *peer_id_field_ptr;
+
+	peer_id_field_ptr = (uint16_t *)
+			    (htt_tx_desc +
+			     HTT_TX_DESC_PEERID_DESC_PADDR_OFFSET_BYTES);
+
+	*peer_id_field_ptr = peer_id;
+}
+
+static inline
+void htt_tx_desc_set_chanfreq(void *htt_tx_desc, uint16_t chanfreq)
+{
+	uint16_t *chanfreq_field_ptr;
+
+	/*
+	 * The reason we dont use CHAN_FREQ_OFFSET_BYTES is because
+	 * it uses DWORD as unit
+	 *
+	 * The reason we dont use the SET macro in htt.h is because
+	 * htt_tx_desc is incomplete type
+	 */
+	chanfreq_field_ptr = (uint16_t *)
+		(htt_tx_desc +
+		 HTT_TX_DESC_PEERID_DESC_PADDR_OFFSET_BYTES
+		 + sizeof(A_UINT16));
+
+	*chanfreq_field_ptr = chanfreq;
+}
+
+#if defined(FEATURE_TSO) && defined(HELIUMPLUS)
+void
+htt_tx_desc_fill_tso_info(htt_pdev_handle pdev, void *desc,
+	 struct qdf_tso_info_t *tso_info);
+#else
+#define htt_tx_desc_fill_tso_info(pdev, desc, tso_info)
+#endif
+#endif /* _OL_HTT_TX_API__H_ */
diff --git a/core/dp/ol/inc/ol_params.h b/core/dp/ol/inc/ol_params.h
new file mode 100644
index 0000000..08b066a
--- /dev/null
+++ b/core/dp/ol/inc/ol_params.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013-2015, 2017-2018 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.
+ */
+
+/*
+ * Definitions for the Atheros Wireless LAN controller driver.
+ */
+#ifndef _DEV_OL_PARAMS_H
+#define _DEV_OL_PARAMS_H
+#include "ol_txrx_stats.h"
+#include "wlan_defs.h"          /* for wlan statst definitions */
+/*
+ * Enumeration of PDEV Configuration parameter
+ */
+
+enum ol_ath_param_t {
+	OL_ATH_PARAM_TXCHAINMASK = 0,
+	OL_ATH_PARAM_RXCHAINMASK,
+	OL_ATH_PARAM_TXCHAINMASKLEGACY,
+	OL_ATH_PARAM_RXCHAINMASKLEGACY,
+	OL_ATH_PARAM_CHAINMASK_SEL,
+	OL_ATH_PARAM_AMPDU,
+	OL_ATH_PARAM_AMPDU_LIMIT,
+	OL_ATH_PARAM_AMPDU_SUBFRAMES,
+	OL_ATH_PARAM_LDPC,
+	OL_ATH_PARAM_NON_AGG_SW_RETRY_TH,
+	OL_ATH_PARAM_AGG_SW_RETRY_TH,
+	OL_ATH_PARAM_STA_KICKOUT_TH,
+	OL_ATH_PARAM_WLAN_PROF_ENABLE,
+	OL_ATH_PARAM_LTR_ENABLE,
+	OL_ATH_PARAM_LTR_AC_LATENCY_BE,
+	OL_ATH_PARAM_LTR_AC_LATENCY_BK,
+	OL_ATH_PARAM_LTR_AC_LATENCY_VI,
+	OL_ATH_PARAM_LTR_AC_LATENCY_VO,
+	OL_ATH_PARAM_LTR_AC_LATENCY_TIMEOUT,
+	OL_ATH_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
+	OL_ATH_PARAM_LTR_SLEEP_OVERRIDE,
+	OL_ATH_PARAM_LTR_RX_OVERRIDE,
+	OL_ATH_PARAM_L1SS_ENABLE,
+	OL_ATH_PARAM_DSLEEP_ENABLE,
+	OL_ATH_PARAM_PCIELP_TXBUF_FLUSH,
+	OL_ATH_PARAM_PCIELP_TXBUF_WATERMARK,
+	OL_ATH_PARAM_PCIELP_TXBUF_TMO_EN,
+	OL_ATH_PARAM_PCIELP_TXBUF_TMO_VALUE,
+	OL_ATH_PARAM_BCN_BURST,
+	OL_ATH_PARAM_ARP_AC_OVERRIDE,
+	OL_ATH_PARAM_TXPOWER_LIMIT2G,
+	OL_ATH_PARAM_TXPOWER_LIMIT5G,
+	OL_ATH_PARAM_TXPOWER_SCALE,
+	OL_ATH_PARAM_DCS,
+	OL_ATH_PARAM_ANI_ENABLE,
+	OL_ATH_PARAM_ANI_POLL_PERIOD,
+	OL_ATH_PARAM_ANI_LISTEN_PERIOD,
+	OL_ATH_PARAM_ANI_OFDM_LEVEL,
+	OL_ATH_PARAM_ANI_CCK_LEVEL,
+	OL_ATH_PARAM_PROXYSTA,
+	OL_ATH_PARAM_DYN_TX_CHAINMASK,
+	OL_ATH_PARAM_VOW_EXT_STATS,
+	OL_ATH_PARAM_PWR_GATING_ENABLE,
+	OL_ATH_PARAM_CHATTER,
+};
+
+/*
+ * Enumeration of PDEV Configuration parameter
+ */
+
+enum ol_hal_param_t {
+	OL_HAL_CONFIG_DMA_BEACON_RESPONSE_TIME = 0
+};
+
+/*
+ * structure to hold all stats information
+ * for offload device interface
+ */
+struct ol_stats {
+	int txrx_stats_level;
+	struct ol_txrx_stats txrx_stats;
+	struct wlan_dbg_stats stats;
+};
+#endif /* _DEV_OL_PARAMS_H  */
diff --git a/core/dp/ol/inc/ol_txrx_api.h b/core/dp/ol/inc/ol_txrx_api.h
new file mode 100644
index 0000000..67adf2c
--- /dev/null
+++ b/core/dp/ol/inc/ol_txrx_api.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011-2014,2016-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.
+ */
+
+/**
+ * @file ol_txrx_api.h
+ * @brief Definitions used in multiple external interfaces to the txrx SW.
+ */
+#ifndef _OL_TXRX_API__H_
+#define _OL_TXRX_API__H_
+
+/**
+ * @brief ADDBA negotiation status, used both during requests and confirmations
+ */
+enum ol_addba_status {
+	/* status: negotiation started or completed successfully */
+	ol_addba_success,
+
+	/* reject: aggregation is not applicable - don't try again */
+	ol_addba_reject,
+
+	/* busy: ADDBA negotiation couldn't be performed - try again later */
+	ol_addba_busy,
+};
+
+enum ol_sec_type {
+	ol_sec_type_none,
+	ol_sec_type_wep128,
+	ol_sec_type_wep104,
+	ol_sec_type_wep40,
+	ol_sec_type_tkip,
+	ol_sec_type_tkip_nomic,
+	ol_sec_type_aes_ccmp,
+	ol_sec_type_wapi,
+
+	/* keep this last! */
+	ol_sec_type_types
+};
+
+typedef void (*tp_ol_packetdump_cb)(qdf_nbuf_t netbuf,
+		uint8_t status, uint8_t vdev_id, uint8_t type);
+void ol_register_packetdump_callback(tp_ol_packetdump_cb ol_tx_packetdump_cb,
+			tp_ol_packetdump_cb ol_rx_packetdump_cb);
+void ol_deregister_packetdump_callback(void);
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+typedef int (*tp_ol_timestamp_cb)(qdf_nbuf_t netbuf, uint64_t target_time);
+
+/**
+ * ol_register_timestamp_callback() - set callbacks for timestamp tx msdu.
+ * @ol_tx_timestamp_cb: callback function for time stamp tx msdu
+ *
+ * This function  register timestamp callback, the callback will
+ * be called when tx a msdu
+ *
+ * Return: nothing
+ */
+void ol_register_timestamp_callback(tp_ol_timestamp_cb ol_tx_timestamp_cb);
+
+/**
+ * ol_deregister_timestamp_callback() - reset callbacks for timestamp
+ * tx msdu to NULL.
+ *
+ * This function  reset the timestamp callbacks for tx
+ *
+ * Return: nothing
+ */
+void ol_deregister_timestamp_callback(void);
+#endif
+#endif /* _OL_TXRX_API__H_ */
diff --git a/core/dp/ol/inc/ol_txrx_ctrl_api.h b/core/dp/ol/inc/ol_txrx_ctrl_api.h
new file mode 100644
index 0000000..858d770
--- /dev/null
+++ b/core/dp/ol/inc/ol_txrx_ctrl_api.h
@@ -0,0 +1,587 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ * @file ol_txrx_ctrl_api.h
+ * @brief Define the host data API functions called by the host control SW.
+ */
+#ifndef _OL_TXRX_CTRL_API__H_
+#define _OL_TXRX_CTRL_API__H_
+
+#include <athdefs.h>            /* A_STATUS */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <qdf_types.h>          /* qdf_device_t */
+#include <htc_api.h>            /* HTC_HANDLE */
+
+#include <ol_txrx_api.h>        /* ol_sec_type */
+#include <wlan_defs.h>          /* MAX_SPATIAL_STREAM */
+#include <cdp_txrx_cmn.h>       /* ol_pdev_handle, ol_vdev_handle, etc */
+#include <cdp_txrx_cfg.h>
+#include <ol_defines.h>
+#include <cdp_txrx_handle.h>
+#define OL_ATH_TX_DRAIN_WAIT_DELAY 50
+
+/**
+ * @brief Set up the data SW subsystem.
+ * @details
+ *  As part of the WLAN device attach, the data SW subsystem has
+ *  to be attached as a component within the WLAN device.
+ *  This attach allocates and initializes the physical device object
+ *  used by the data SW.
+ *  The data SW subsystem attach needs to happen after the target has
+ *  be started, and host / target parameter negotiation has completed,
+ *  since the host data SW uses some of these host/target negotiated
+ *  parameters (e.g. peer ID range) during the initializations within
+ *  its attach function.
+ *  However, the host data SW is not allowed to send HTC messages to the
+ *  target within this pdev_attach function call, since the HTC setup
+ *  has not complete at this stage of initializations.  Any messaging
+ *  to the target has to be done in the separate pdev_attach_target call
+ *  that is invoked after HTC setup is complete.
+ *
+ * @param pdev - txrx_pdev handle
+ * @return 0 for success or error code
+ */
+int
+ol_txrx_pdev_post_attach(struct cdp_pdev *pdev);
+
+/**
+ * @brief Parameter type to be input to ol_txrx_peer_update
+ * @details
+ *  This struct is union,to be used to specify various information to update
+ *   txrx peer object.
+ */
+union ol_txrx_peer_update_param_t {
+	uint8_t qos_capable;
+	uint8_t uapsd_mask;
+	enum ol_sec_type sec_type;
+};
+
+/**
+ * @brief Parameter type to be input to ol_txrx_peer_update
+ * @details
+ *   This enum is used to specify what exact information in
+ *   ol_txrx_peer_update_param_t
+ *   is used to update the txrx peer object.
+ */
+enum ol_txrx_peer_update_select_t {
+	ol_txrx_peer_update_qos_capable = 1,
+	ol_txrx_peer_update_uapsdMask,
+	ol_txrx_peer_update_peer_security,
+};
+
+/**
+ * @brief Update the data peer object as some informaiton changed in node.
+ * @details
+ *  Only a single prarameter can be changed for each call to this func.
+ *
+ * @param peer - pointer to the node's object
+ * @param param - new param to be upated in peer object.
+ * @param select - specify what's parameter needed to be update
+ */
+void
+ol_txrx_peer_update(ol_txrx_vdev_handle data_vdev, uint8_t *peer_mac,
+		    union ol_txrx_peer_update_param_t *param,
+		    enum ol_txrx_peer_update_select_t select);
+
+#if defined(CONFIG_HL_SUPPORT)
+/**
+ * @brief notify tx data SW that a peer-TID is ready to transmit to.
+ * @details
+ *  This function applies only to HL systems - in LL systems, tx flow control
+ *  is handled entirely within the target FW.
+ *  If a peer-TID has tx paused, then the tx datapath will end up queuing
+ *  any tx frames that arrive from the OS shim for that peer-TID.
+ *  In a HL system, the host tx data SW itself will classify the tx frame,
+ *  and determine that it needs to be queued rather than downloaded to the
+ *  target for transmission.
+ *  Once the peer-TID is ready to accept data, the host control SW will call
+ *  this function to notify the host data SW that the queued frames can be
+ *  enabled for transmission, or specifically to download the tx frames
+ *  to the target to transmit.
+ *  The TID parameter is an extended version of the QoS TID.  Values 0-15
+ *  indicate a regular QoS TID, and the value 16 indicates either non-QoS
+ *  data, multicast data, or broadcast data.
+ *
+ * @param data_peer - which peer is being unpaused
+ * @param tid - which TID within the peer is being unpaused, or -1 as a
+ *      wildcard to unpause all TIDs within the peer
+ */
+void
+ol_txrx_peer_tid_unpause(ol_txrx_peer_handle data_peer, int tid);
+
+
+/**
+ * @brief Tell a paused peer to release a specified number of tx frames.
+ * @details
+ *  This function applies only to HL systems - in LL systems, tx flow control
+ *  is handled entirely within the target FW.
+ *  Download up to a specified maximum number of tx frames from the tx
+ *  queues of the specified TIDs within the specified paused peer, usually
+ *  in response to a U-APSD trigger from the peer.
+ *  It is up to the host data SW to determine how to choose frames from the
+ *  tx queues of the specified TIDs.  However, the host data SW does need to
+ *  provide long-term fairness across the U-APSD enabled TIDs.
+ *  The host data SW will notify the target data FW when it is done downloading
+ *  the batch of U-APSD triggered tx frames, so the target data FW can
+ *  differentiate between an in-progress download versus a case when there are
+ *  fewer tx frames available than the specified limit.
+ *  This function is relevant primarily to HL U-APSD, where the frames are
+ *  held in the host.
+ *
+ * @param peer - which peer sent the U-APSD trigger
+ * @param tid_mask - bitmask of U-APSD enabled TIDs from whose tx queues
+ *      tx frames can be released
+ * @param max_frms - limit on the number of tx frames to release from the
+ *      specified TID's queues within the specified peer
+ */
+void ol_txrx_tx_release(ol_txrx_peer_handle peer,
+			u_int32_t tid_mask,
+			int max_frms);
+
+#else
+static inline void
+ol_txrx_peer_tid_unpause(ol_txrx_peer_handle data_peer, int tid)
+{
+}
+
+static inline void
+ol_txrx_tx_release(ol_txrx_peer_handle peer,
+		   u_int32_t tid_mask,
+		   int max_frms)
+{
+}
+
+#endif /* CONFIG_HL_SUPPORT */
+
+#ifdef QCA_SUPPORT_TX_THROTTLE
+/**
+ * @brief Suspend all tx data per thermal event/timer for the
+ *  specified physical device
+ * @details
+ *  This function applies only to HL systerms, and it makes pause and
+ * unpause operations happen in pairs.
+ */
+void
+ol_txrx_throttle_pause(ol_txrx_pdev_handle data_pdev);
+
+
+/**
+ * @brief Resume all tx data per thermal event/timer for the
+ * specified physical device
+ * @details
+ *  This function applies only to HL systerms, and it makes pause and
+ * unpause operations happen in pairs.
+ */
+void
+ol_txrx_throttle_unpause(ol_txrx_pdev_handle data_pdev);
+#else
+
+static inline void
+ol_txrx_throttle_pause(ol_txrx_pdev_handle data_pdev)
+{
+}
+
+static inline void
+ol_txrx_throttle_unpause(ol_txrx_pdev_handle data_pdev)
+{
+}
+#endif
+
+/**
+ * @brief notify tx data SW that a peer's transmissions are suspended.
+ * @details
+ *  This function applies only to HL systems - in LL systems, tx flow control
+ *  is handled entirely within the target FW.
+ *  The HL host tx data SW is doing tx classification and tx download
+ *  scheduling, and therefore also needs to actively participate in tx
+ *  flow control.  Specifically, the HL tx data SW needs to check whether a
+ *  given peer is available to transmit to, or is paused.
+ *  This function is used to tell the HL tx data SW when a peer is paused,
+ *  so the host tx data SW can hold the tx frames for that SW.
+ *
+ * @param data_peer - which peer is being paused
+ */
+static inline void ol_txrx_peer_pause(struct ol_txrx_peer_t *data_peer)
+{
+}
+
+/**
+ * @brief Suspend all tx data for the specified physical device.
+ * @details
+ *  This function applies only to HL systems - in LL systems, tx flow control
+ *  is handled entirely within the target FW.
+ *  In some systems it is necessary to be able to temporarily
+ *  suspend all WLAN traffic, e.g. to allow another device such as bluetooth
+ *  to temporarily have exclusive access to shared RF chain resources.
+ *  This function suspends tx traffic within the specified physical device.
+ *
+ * @param data_pdev - the physical device being paused
+ */
+#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(CONFIG_HL_SUPPORT)
+
+void ol_txrx_pdev_pause(struct ol_txrx_pdev_t *data_pdev, uint32_t reason);
+#else
+static inline
+void ol_txrx_pdev_pause(struct ol_txrx_pdev_t *data_pdev, uint32_t reason)
+{
+}
+#endif
+
+/**
+ * @brief Resume tx for the specified physical device.
+ * @details
+ *  This function applies only to HL systems - in LL systems, tx flow control
+ *  is handled entirely within the target FW.
+ *
+ * @param data_pdev - the physical device being unpaused
+ */
+#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(CONFIG_HL_SUPPORT)
+
+void ol_txrx_pdev_unpause(struct ol_txrx_pdev_t *pdev, uint32_t reason);
+#else
+static inline
+void ol_txrx_pdev_unpause(struct ol_txrx_pdev_t *pdev, uint32_t reason)
+{
+}
+#endif
+
+/**
+ * @brief Synchronize the data-path tx with a control-path target download
+ * @dtails
+ * @param data_pdev - the data-path physical device object
+ * @param sync_cnt - after the host data-path SW downloads this sync request
+ *      to the target data-path FW, the target tx data-path will hold itself
+ *      in suspension until it is given an out-of-band sync counter value that
+ *      is equal to or greater than this counter value
+ */
+void ol_txrx_tx_sync(ol_txrx_pdev_handle data_pdev, uint8_t sync_cnt);
+
+/**
+ * @brief Store a delivery notification callback for specific data frames.
+ * @details
+ *  Through a non-std tx function, the txrx SW can be given tx data frames
+ *  that are specially marked to not be unmapped and freed by the tx SW
+ *  when transmission completes.  Rather, these specially-marked frames
+ *  are provided to the callback registered with this function.
+ *
+ * @param data_vdev - which vdev the callback is being registered with
+ *      (Currently the callback is stored in the pdev rather than the vdev.)
+ * @param callback - the function to call when tx frames marked as "no free"
+ *      are done being transmitted
+ * @param ctxt - the context argument provided to the callback function
+ */
+void
+ol_txrx_data_tx_cb_set(struct cdp_vdev *data_vdev,
+		       ol_txrx_data_tx_cb callback, void *ctxt);
+
+/**
+ * @brief Discard all tx frames that are pending in txrx.
+ * @details
+ *  Mainly used in clean up path to make sure all pending tx packets
+ *  held by txrx are returned back to OS shim immediately.
+ *
+ * @param pdev - the data physical device object
+ * @return - void
+ */
+void ol_txrx_discard_tx_pending(ol_txrx_pdev_handle pdev);
+
+/**
+ * @brief set the safemode of the device
+ * @details
+ *  This flag is used to bypass the encrypt and decrypt processes when send and
+ *  receive packets. It works like open AUTH mode, HW will treate all packets
+ *  as non-encrypt frames because no key installed. For rx fragmented frames,
+ *  it bypasses all the rx defragmentaion.
+ *
+ * @param vdev - the data virtual device object
+ * @param val - the safemode state
+ * @return - void
+ */
+void ol_txrx_set_safemode(ol_txrx_vdev_handle vdev, uint32_t val);
+
+/**
+ * @brief configure the drop unencrypted frame flag
+ * @details
+ *  Rx related. When set this flag, all the unencrypted frames
+ *  received over a secure connection will be discarded
+ *
+ * @param vdev - the data virtual device object
+ * @param val - flag
+ * @return - void
+ */
+void ol_txrx_set_drop_unenc(ol_txrx_vdev_handle vdev, uint32_t val);
+
+void
+ol_txrx_peer_keyinstalled_state_update(ol_txrx_peer_handle data_peer,
+				       uint8_t val);
+
+#define ol_tx_addba_conf(data_peer, tid, status)        /* no-op */
+
+/**
+ * @brief Find a txrx peer handle from the peer's MAC address
+ * @details
+ *  The control SW typically uses the txrx peer handle to refer to the peer.
+ *  In unusual circumstances, if it is infeasible for the control SW maintain
+ *  the txrx peer handle but it can maintain the peer's MAC address,
+ *  this function allows the peer handled to be retrieved, based on the peer's
+ *  MAC address.
+ *  In cases where there are multiple peer objects with the same MAC address,
+ *  it is undefined which such object is returned.
+ *  This function does not increment the peer's reference count.  Thus, it is
+ *  only suitable for use as long as the control SW has assurance that it has
+ *  not deleted the peer object, by calling ol_txrx_peer_detach.
+ *
+ * @param pdev - the data physical device object
+ * @param peer_mac_addr - MAC address of the peer in question
+ * @return handle to the txrx peer object
+ */
+ol_txrx_peer_handle
+ol_txrx_peer_find_by_addr(ol_txrx_pdev_handle pdev, uint8_t *peer_mac_addr);
+
+struct ol_txrx_peer_stats_t {
+	struct {
+		struct {
+			uint32_t ucast;
+			uint32_t mcast;
+			uint32_t bcast;
+		} frms;
+		struct {
+			uint32_t ucast;
+			uint32_t mcast;
+			uint32_t bcast;
+		} bytes;
+	} tx;
+	struct {
+		struct {
+			uint32_t ucast;
+			uint32_t mcast;
+			uint32_t bcast;
+		} frms;
+		struct {
+			uint32_t ucast;
+			uint32_t mcast;
+			uint32_t bcast;
+		} bytes;
+	} rx;
+};
+
+/**
+ * @brief Provide a snapshot of the txrx counters for the specified peer
+ * @details
+ *  The txrx layer optionally maintains per-peer stats counters.
+ *  This function provides the caller with a consistent snapshot of the
+ *  txrx stats counters for the specified peer.
+ *
+ * @param pdev - the data physical device object
+ * @param peer - which peer's stats counters are requested
+ * @param stats - buffer for holding the stats counters snapshot
+ * @return success / failure status
+ */
+#ifdef QCA_ENABLE_OL_TXRX_PEER_STATS
+A_STATUS
+ol_txrx_peer_stats_copy(ol_txrx_pdev_handle pdev,
+			ol_txrx_peer_handle peer, ol_txrx_peer_stats_t *stats);
+#else
+#define ol_txrx_peer_stats_copy(pdev, peer, stats) A_ERROR      /* failure */
+#endif /* QCA_ENABLE_OL_TXRX_PEER_STATS */
+
+
+#define OL_TXRX_RSSI_INVALID 0xffff
+/**
+ * @brief Provide the current RSSI average from data frames sent by a peer.
+ * @details
+ *  If a peer has sent data frames, the data SW will optionally keep
+ *  a running average of the RSSI observed for those data frames.
+ *  This function returns that time-average RSSI if is it available,
+ *  or OL_TXRX_RSSI_INVALID if either RSSI tracking is disabled or if
+ *  no data frame indications with valid RSSI meta-data have been received.
+ *  The RSSI is in approximate dBm units, and is normalized with respect
+ *  to a 20 MHz channel.  For example, if a data frame is received on a
+ *  40 MHz channel, wherein both the primary 20 MHz channel and the
+ *  secondary 20 MHz channel have an RSSI of -77 dBm, the reported RSSI
+ *  will be -77 dBm, rather than the actual -74 dBm RSSI from the
+ *  combination of the primary + extension 20 MHz channels.
+ *  Alternatively, the RSSI may be evaluated only on the primary 20 MHz
+ *  channel.
+ *
+ * @param peer - which peer's RSSI is desired
+ * @return RSSI evaluted from frames sent by the specified peer
+ */
+#ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI
+int16_t ol_txrx_peer_rssi(ol_txrx_peer_handle peer);
+#else
+#define ol_txrx_peer_rssi(peer) OL_TXRX_RSSI_INVALID
+#endif /* QCA_SUPPORT_PEER_DATA_RX_RSSI */
+
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
+
+/**
+ * @brief Configure the bad peer tx limit setting.
+ * @details
+ *
+ * @param pdev - the physics device
+ */
+void
+ol_txrx_bad_peer_txctl_set_setting(
+	struct cdp_pdev *pdev,
+	int enable,
+	int period,
+	int txq_limit);
+
+/**
+ * @brief Configure the bad peer tx threshold limit
+ * @details
+ *
+ * @param pdev - the physics device
+ */
+void
+ol_txrx_bad_peer_txctl_update_threshold(
+	struct cdp_pdev *pdev,
+	int level,
+	int tput_thresh,
+	int tx_limit);
+
+#else
+
+static inline void
+ol_txrx_bad_peer_txctl_set_setting(
+	struct cdp_pdev *pdev,
+	int enable,
+	int period,
+	int txq_limit)
+{
+}
+
+static inline void
+ol_txrx_bad_peer_txctl_update_threshold(
+	struct cdp_pdev *pdev,
+	int level,
+	int tput_thresh,
+	int tx_limit)
+{
+}
+#endif /* defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL) */
+
+
+void ol_txrx_set_ocb_peer(struct ol_txrx_pdev_t *pdev,
+			  struct ol_txrx_peer_t *peer);
+
+bool ol_txrx_get_ocb_peer(struct ol_txrx_pdev_t *pdev,
+			  struct ol_txrx_peer_t **peer);
+
+void ol_tx_set_is_mgmt_over_wmi_enabled(uint8_t value);
+uint8_t ol_tx_get_is_mgmt_over_wmi_enabled(void);
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_RESIZE
+void ol_tx_flow_pool_resize_handler(uint8_t flow_pool_id,
+				    uint16_t flow_pool_size);
+#else
+static inline void ol_tx_flow_pool_resize_handler(uint8_t flow_pool_id,
+						  uint16_t flow_pool_size)
+{
+}
+#endif
+
+/* TX FLOW Control related functions */
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+#define TX_FLOW_MGMT_POOL_ID	0xEF
+
+#ifdef QCA_LL_TX_FLOW_GLOBAL_MGMT_POOL
+#define TX_FLOW_MGMT_POOL_SIZE  32
+#else
+#define TX_FLOW_MGMT_POOL_SIZE  0
+#endif
+
+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_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);
+void ol_tx_flow_pool_unmap_handler(uint8_t flow_id, uint8_t flow_type,
+				   uint8_t flow_pool_id);
+struct ol_tx_flow_pool_t *ol_tx_create_flow_pool(uint8_t flow_pool_id,
+						 uint16_t flow_pool_size);
+
+/**
+ * ol_tx_inc_pool_ref() - increment pool ref count
+ * @pool: flow pool pointer
+ *
+ * Increments pool's ref count, used to make sure that no one is using
+ * pool when it is being deleted.
+ * As this function is taking pool->flow_pool_lock inside it, it should
+ * always be called outside this spinlock.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS ol_tx_inc_pool_ref(struct ol_tx_flow_pool_t *pool);
+
+/**
+ * ol_tx_dec_pool_ref() - decrement pool ref count
+ * @pool: flow pool pointer
+ * @force: free pool forcefully
+ *
+ * Decrements pool's ref count and deletes the pool if ref count gets 0.
+ * As this function is taking pdev->tx_desc.flow_pool_list_lock and
+ * pool->flow_pool_lock inside it, it should always be called outside
+ * these two spinlocks.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS ol_tx_dec_pool_ref(struct ol_tx_flow_pool_t *pool, bool force);
+#else
+
+static inline void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev)
+{
+}
+static inline void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev)
+{
+}
+static inline void ol_tx_dump_flow_pool_info(void *ctx)
+{
+}
+static inline void ol_tx_clear_flow_pool_stats(void)
+{
+}
+static inline 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)
+{
+}
+static inline void ol_tx_flow_pool_unmap_handler(uint8_t flow_id,
+	 uint8_t flow_type, uint8_t flow_pool_id)
+{
+}
+static inline struct ol_tx_flow_pool_t *ol_tx_create_flow_pool(
+		uint8_t flow_pool_id, uint16_t flow_pool_size)
+{
+	return NULL;
+}
+static inline QDF_STATUS
+ol_tx_inc_pool_ref(struct ol_tx_flow_pool_t *pool)
+{
+	return QDF_STATUS_SUCCESS;
+}
+static inline QDF_STATUS
+ol_tx_dec_pool_ref(struct ol_tx_flow_pool_t *pool, bool force)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#endif /* _OL_TXRX_CTRL_API__H_ */
diff --git a/core/dp/ol/inc/ol_txrx_dbg.h b/core/dp/ol/inc/ol_txrx_dbg.h
new file mode 100644
index 0000000..438b406
--- /dev/null
+++ b/core/dp/ol/inc/ol_txrx_dbg.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2011, 2014-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.
+ */
+
+/**
+ * @file ol_txrx_dbg.h
+ * @brief Functions provided for visibility and debugging.
+ */
+#ifndef _OL_TXRX_DBG__H_
+#define _OL_TXRX_DBG__H_
+
+#include <athdefs.h>            /* A_STATUS, uint64_t */
+#include <qdf_lock.h>           /* qdf_semaphore_t */
+#include <htt.h>                /* htt_dbg_stats_type */
+#include <ol_txrx_stats.h>      /* ol_txrx_stats */
+
+#ifndef TXRX_DEBUG_LEVEL
+#define TXRX_DEBUG_LEVEL 0      /* no debug info */
+#endif
+
+enum {
+	TXRX_DBG_MASK_OBJS = 0x01,
+	TXRX_DBG_MASK_STATS = 0x02,
+	TXRX_DBG_MASK_PROT_ANALYZE = 0x04,
+	TXRX_DBG_MASK_RX_REORDER_TRACE = 0x08,
+	TXRX_DBG_MASK_RX_PN_TRACE = 0x10
+};
+
+/*--- txrx printouts ---*/
+
+/*
+ * Uncomment this to enable txrx printouts with dynamically adjustable
+ * verbosity.  These printouts should not impact performance.
+ */
+#define TXRX_PRINT_ENABLE 1
+/* uncomment this for verbose txrx printouts (may impact performance) */
+/* #define TXRX_PRINT_VERBOSE_ENABLE 1 */
+
+/*--- txrx object (pdev, vdev, peer) display debug functions ---*/
+
+#if TXRX_DEBUG_LEVEL > 5
+void ol_txrx_pdev_display(ol_txrx_pdev_handle pdev, int indent);
+void ol_txrx_vdev_display(ol_txrx_vdev_handle vdev, int indent);
+void ol_txrx_peer_display(ol_txrx_peer_handle peer, int indent);
+#else
+#define ol_txrx_pdev_display(pdev, indent)
+#define ol_txrx_vdev_display(vdev, indent)
+#define ol_txrx_peer_display(peer, indent)
+#endif
+
+/*--- txrx stats display debug functions ---*/
+
+/**
+ * ol_txrx_stats_display() - display tx rx stats
+ * @pdev: pdev handle
+ * @level: verbosity level for logs
+ *
+ * Return: none
+ */
+void ol_txrx_stats_display(ol_txrx_pdev_handle pdev,
+			   enum qdf_stats_verbosity_level level);
+
+void ol_txrx_stats_clear(ol_txrx_pdev_handle pdev);
+
+
+/*--- txrx protocol analyzer debug feature ---*/
+
+/* uncomment this to enable the protocol analzyer feature */
+/* #define ENABLE_TXRX_PROT_ANALYZE 1 */
+
+#if defined(ENABLE_TXRX_PROT_ANALYZE)
+
+void ol_txrx_prot_ans_display(ol_txrx_pdev_handle pdev);
+
+#else
+
+#define ol_txrx_prot_ans_display(pdev)
+
+#endif /* ENABLE_TXRX_PROT_ANALYZE */
+
+/*--- txrx sequence number trace debug feature ---*/
+
+/* uncomment this to enable the rx reorder trace feature */
+/* #define ENABLE_RX_REORDER_TRACE 1 */
+
+#define ol_txrx_seq_num_trace_display(pdev) \
+	ol_rx_reorder_trace_display(pdev, 0, 0)
+
+#if defined(ENABLE_RX_REORDER_TRACE)
+
+void
+ol_rx_reorder_trace_display(ol_txrx_pdev_handle pdev, int just_once, int limit);
+
+#else
+
+#define ol_rx_reorder_trace_display(pdev, just_once, limit)
+
+#endif /* ENABLE_RX_REORDER_TRACE */
+
+/*--- txrx packet number trace debug feature ---*/
+
+/* uncomment this to enable the rx PN trace feature */
+/* #define ENABLE_RX_PN_TRACE 1 */
+
+#define ol_txrx_pn_trace_display(pdev) ol_rx_pn_trace_display(pdev, 0)
+
+#if defined(ENABLE_RX_PN_TRACE)
+
+void ol_rx_pn_trace_display(ol_txrx_pdev_handle pdev, int just_once);
+
+#else
+
+#define ol_rx_pn_trace_display(pdev, just_once)
+
+#endif /* ENABLE_RX_PN_TRACE */
+
+/*--- tx queue log debug feature ---*/
+/* uncomment this to enable the tx queue log feature */
+/* #define ENABLE_TX_QUEUE_LOG 1 */
+
+#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
+
+void
+ol_tx_queue_log_display(ol_txrx_pdev_handle pdev);
+void ol_tx_queue_log_clear(ol_txrx_pdev_handle pdev);
+#else
+
+static inline
+void ol_tx_queue_log_display(ol_txrx_pdev_handle pdev)
+{
+}
+
+static inline
+void ol_tx_queue_log_clear(ol_txrx_pdev_handle pdev)
+{
+}
+#endif /* defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT) */
+
+
+/*----------------------------------------*/
+
+#endif /* _OL_TXRX_DBG__H_ */
diff --git a/core/dp/ol/inc/ol_txrx_htt_api.h b/core/dp/ol/inc/ol_txrx_htt_api.h
new file mode 100644
index 0000000..8c342dd
--- /dev/null
+++ b/core/dp/ol/inc/ol_txrx_htt_api.h
@@ -0,0 +1,724 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ * @file ol_txrx_htt_api.h
+ * @brief Define the host data API functions called by the host HTT SW.
+ */
+#ifndef _OL_TXRX_HTT_API__H_
+#define _OL_TXRX_HTT_API__H_
+
+#include <htt.h>                /* HTT_TX_COMPL_IND_STAT */
+#include <athdefs.h>            /* A_STATUS */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+
+#include <cdp_txrx_cmn.h>      /* ol_txrx_pdev_handle */
+#include <ol_defines.h>
+
+#ifdef CONFIG_HL_SUPPORT
+static inline uint16_t *ol_tx_msdu_id_storage(qdf_nbuf_t msdu)
+{
+	return (uint16_t *) (&QDF_NBUF_CB_TX_DESC_ID(msdu));
+
+}
+#else
+static inline uint16_t *ol_tx_msdu_id_storage(qdf_nbuf_t msdu)
+{
+	qdf_assert(qdf_nbuf_headroom(msdu) >= (sizeof(uint16_t) * 2 - 1));
+	return (uint16_t *) (((qdf_size_t) (qdf_nbuf_head(msdu) + 1)) & ~0x1);
+}
+#endif
+/**
+ * @brief Tx MSDU download completion for a LL system
+ * @details
+ *  Release the reference to the downloaded tx descriptor.
+ *  In the unlikely event that the reference count is zero, free
+ *  the tx descriptor and tx frame.
+ *
+ * @param pdev - (abstract) pointer to the txrx physical device
+ * @param status - indication of whether the download succeeded
+ * @param msdu - the downloaded tx frame
+ * @param msdu_id - the txrx ID of the tx frame - this is used for
+ *      locating the frame's tx descriptor
+ */
+void
+ol_tx_download_done_ll(void *pdev,
+		       A_STATUS status, qdf_nbuf_t msdu, uint16_t msdu_id);
+
+/**
+ * @brief Tx MSDU download completion for HL system without tx completion msgs
+ * @details
+ *  Free the tx descriptor and tx frame.
+ *  Invoke the HL tx download scheduler.
+ *
+ * @param pdev - (abstract) pointer to the txrx physical device
+ * @param status - indication of whether the download succeeded
+ * @param msdu - the downloaded tx frame
+ * @param msdu_id - the txrx ID of the tx frame - this is used for
+ *      locating the frame's tx descriptor
+ */
+void
+ol_tx_download_done_hl_free(void *pdev,
+			    A_STATUS status, qdf_nbuf_t msdu, uint16_t msdu_id);
+
+/**
+ * @brief Tx MSDU download completion for HL system with tx completion msgs
+ * @details
+ *  Release the reference to the downloaded tx descriptor.
+ *  In the unlikely event that the reference count is zero, free
+ *  the tx descriptor and tx frame.
+ *  Optionally, invoke the HL tx download scheduler.  (It is probable that
+ *  the HL tx download scheduler would operate in response to tx completion
+ *  messages rather than download completion events.)
+ *
+ * @param pdev - (abstract) pointer to the txrx physical device
+ * @param status - indication of whether the download succeeded
+ * @param msdu - the downloaded tx frame
+ * @param msdu_id - the txrx ID of the tx frame - this is used for
+ *      locating the frame's tx descriptor
+ */
+void
+ol_tx_download_done_hl_retain(void *pdev,
+			      A_STATUS status,
+			      qdf_nbuf_t msdu, uint16_t msdu_id);
+
+/*
+ * For now, make the host HTT -> host txrx tx completion status
+ * match the target HTT -> host HTT tx completion status, so no
+ * translation is needed.
+ */
+/*
+ * host-only statuses use a different part of the number space
+ * than host-target statuses
+ */
+#define HTT_HOST_ONLY_STATUS_CODE_START 128
+enum htt_tx_status {
+	/* ok - successfully sent + acked */
+	htt_tx_status_ok = HTT_TX_COMPL_IND_STAT_OK,
+
+	/* discard - not sent (congestion control) */
+	htt_tx_status_discard = HTT_TX_COMPL_IND_STAT_DISCARD,
+
+	/* no_ack - sent, but no ack */
+	htt_tx_status_no_ack = HTT_TX_COMPL_IND_STAT_NO_ACK,
+
+	/* download_fail - host could not deliver the tx frame to target */
+	htt_tx_status_download_fail = HTT_HOST_ONLY_STATUS_CODE_START,
+};
+
+/**
+ * @brief Process a tx completion message sent by the target.
+ * @details
+ *  When the target is done transmitting a tx frame (either because
+ *  the frame was sent + acknowledged, or because the target gave up)
+ *  it sends a tx completion message to the host.
+ *  This notification function is used regardless of whether the
+ *  transmission succeeded or not; the status argument indicates whether
+ *  the transmission succeeded.
+ *  This tx completion message indicates via the descriptor ID which
+ *  tx frames were completed, and indicates via the status whether the
+ *  frames were transmitted successfully.
+ *  The host frees the completed descriptors / frames (updating stats
+ *  in the process).
+ *
+ * @param pdev - the data physical device that sent the tx frames
+ *      (registered with HTT as a context pointer during attach time)
+ * @param num_msdus - how many MSDUs are referenced by the tx completion
+ *      message
+ * @param status - whether transmission was successful
+ * @param msg_word - the tx completion message
+ */
+void
+ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
+			 int num_msdus,
+			 enum htt_tx_status status, void *msg_word);
+
+void ol_tx_credit_completion_handler(ol_txrx_pdev_handle pdev, int credits);
+
+struct rate_report_t {
+	u_int16_t id;
+	u_int16_t phy:4;
+	u_int32_t rate;
+};
+
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
+
+/**
+ * @brief Process a link status report for all peers.
+ * @details
+ *  The ol_txrx_peer_link_status_handler function performs basic peer link
+ *  status analysis
+ *
+ *  According to the design, there are 3 kinds of peers which will be
+ *  treated differently:
+ *  1) normal: not do any flow control for the peer
+ *  2) limited: will apply flow control for the peer, but frames are allowed
+ *              to send
+ *  3) paused: will apply flow control for the peer, no frame is allowed
+ *             to send
+ *
+ * @param pdev - the data physical device that sent the tx frames
+ * @param status - the number of peers need to be handled
+ * @param peer_link_report - the link status dedail message
+ */
+void
+ol_txrx_peer_link_status_handler(
+	ol_txrx_pdev_handle pdev,
+	u_int16_t peer_num,
+	struct rate_report_t *peer_link_status);
+
+
+#else
+static inline void ol_txrx_peer_link_status_handler(
+	ol_txrx_pdev_handle pdev,
+	u_int16_t peer_num,
+	struct rate_report_t *peer_link_status)
+{
+}
+#endif
+
+
+#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+
+/**
+ * ol_txrx_update_tx_queue_groups() - update vdev tx queue group if
+ *				      vdev id mask and ac mask is not matching
+ * @pdev: the data physical device
+ * @group_id: TXQ group id
+ * @credit: TXQ group credit count
+ * @absolute: TXQ group absolute
+ * @vdev_id_mask: TXQ vdev group id mask
+ * @ac_mask: TQX access category mask
+ *
+ * Return: None
+ */
+void
+ol_txrx_update_tx_queue_groups(
+	ol_txrx_pdev_handle pdev,
+	u_int8_t group_id,
+	int32_t credit,
+	u_int8_t absolute,
+	u_int32_t vdev_id_mask,
+	u_int32_t ac_mask
+);
+
+/**
+ * ol_tx_desc_update_group_credit() - update group credits for txq group
+ * @pdev: the data physical device
+ * @tx_desc_id: desc id of tx completion message
+ * @credit: number of credits to update
+ * @absolute: absolute value
+ * @status: tx completion message status
+ *
+ * Return: None
+ */
+void
+ol_tx_desc_update_group_credit(
+	ol_txrx_pdev_handle pdev,
+	u_int16_t tx_desc_id,
+	int credit, u_int8_t absolute, enum htt_tx_status status);
+
+#ifdef DEBUG_HL_LOGGING
+
+/**
+ * ol_tx_update_group_credit_stats() - update group credits stats for txq groups
+ * @pdev: the data physical device
+ *
+ * Return: None
+ */
+void
+ol_tx_update_group_credit_stats(ol_txrx_pdev_handle pdev);
+
+/**
+ * ol_tx_dump_group_credit_stats() - dump group credits stats for txq groups
+ * @pdev: the data physical device
+ *
+ * Return: None
+ */
+void
+ol_tx_dump_group_credit_stats(ol_txrx_pdev_handle pdev);
+
+/**
+ * ol_tx_clear_group_credit_stats() - clear group credits stats for txq groups
+ * @pdev: the data physical device
+ *
+ * Return: None
+ */
+void
+ol_tx_clear_group_credit_stats(ol_txrx_pdev_handle pdev);
+#else
+
+static inline void ol_tx_update_group_credit_stats(ol_txrx_pdev_handle pdev)
+{
+}
+
+static inline void ol_tx_dump_group_credit_stats(ol_txrx_pdev_handle pdev)
+{
+}
+
+static inline void ol_tx_clear_group_credit_stats(ol_txrx_pdev_handle pdev)
+{
+}
+#endif
+
+#else
+static inline void
+ol_tx_desc_update_group_credit(
+	ol_txrx_pdev_handle pdev,
+	u_int16_t tx_desc_id,
+	int credit, u_int8_t absolute, enum htt_tx_status status)
+{
+}
+#endif
+
+/**
+ * @brief Init the total amount of target credit.
+ * @details
+ *
+ * @param pdev - the data physical device that sent the tx frames
+ * @param credit_delta - how much to increment the target's tx credit by
+ */
+void ol_tx_target_credit_init(struct ol_txrx_pdev_t *pdev, int credit_delta);
+
+/**
+ * @brief Process a tx completion message for a single MSDU.
+ * @details
+ *  The ol_tx_single_completion_handler function performs the same tx
+ *  completion processing as the ol_tx_completion_handler, but for a
+ *  single frame.
+ *  ol_tx_completion_handler is optimized to handle batch completions
+ *  as efficiently as possible; in contrast ol_tx_single_completion_handler
+ *  handles single frames as simply and generally as possible.
+ *  Thus, this ol_tx_single_completion_handler function is suitable for
+ *  intermittent usage, such as for tx mgmt frames.
+ *
+ * @param pdev - the data physical device that sent the tx frames
+ * @param status - whether transmission was successful
+ * @param tx_msdu_id - ID of the frame which completed transmission
+ */
+void
+ol_tx_single_completion_handler(ol_txrx_pdev_handle pdev,
+				enum htt_tx_status status, uint16_t tx_desc_id);
+
+/**
+ * @brief Update the amount of target credit.
+ * @details
+ *  When the target finishes with an old transmit frame, it can use the
+ *  space that was occupied by the old tx frame to store a new tx frame.
+ *  This function is used to inform the txrx layer, where the HL tx download
+ *  scheduler resides, about such updates to the target's tx credit.
+ *  This credit update is done explicitly, rather than having the txrx layer
+ *  update the credit count itself inside the ol_tx_completion handler
+ *  function.  This provides HTT with the flexibility to limit the rate of
+ *  downloads from the TXRX layer's download scheduler, by controlling how
+ *  much credit the download scheduler gets, and also provides the flexibility
+ *  to account for a change in the tx memory pool size within the target.
+ *  This function is only used for HL systems; in LL systems, each tx frame
+ *  is assumed to use exactly one credit (for its target-side tx descriptor),
+ *  and any rate limiting is managed within the target.
+ *
+ * @param pdev - the data physical device that sent the tx frames
+ * @param credit_delta - how much to increment the target's tx credit by
+ */
+void ol_tx_target_credit_update(struct ol_txrx_pdev_t *pdev, int credit_delta);
+
+/**
+ * @brief Process an rx indication message sent by the target.
+ * @details
+ *  The target sends a rx indication message to the host as a
+ *  notification that there are new rx frames available for the
+ *  host to process.
+ *  The HTT host layer locates the rx descriptors and rx frames
+ *  associated with the indication, and calls this function to
+ *  invoke the rx data processing on the new frames.
+ *  (For LL, the rx descriptors and frames are delivered directly
+ *  to the host via MAC DMA, while for HL the rx descriptor and
+ *  frame for individual frames are combined with the rx indication
+ *  message.)
+ *  All MPDUs referenced by a rx indication message belong to the
+ *  same peer-TID.
+ *
+ * @param pdev - the data physical device that received the frames
+ *      (registered with HTT as a context pointer during attach time)
+ * @param rx_ind_msg - the network buffer holding the rx indication message
+ *      (For HL, this netbuf also holds the rx desc and rx payload, but
+ *      the data SW is agnostic to whether the desc and payload are
+ *      piggybacked with the rx indication message.)
+ * @param peer_id - which peer sent this rx data
+ * @param tid - what (extended) traffic type the rx data is
+ * @param num_mpdu_ranges - how many ranges of MPDUs does the message describe.
+ *      Each MPDU within the range has the same rx status.
+ */
+#ifdef WLAN_PARTIAL_REORDER_OFFLOAD
+void
+ol_rx_indication_handler(ol_txrx_pdev_handle pdev,
+			 qdf_nbuf_t rx_ind_msg,
+			 uint16_t peer_id, uint8_t tid, int num_mpdu_ranges);
+#else
+static inline void
+ol_rx_indication_handler(ol_txrx_pdev_handle pdev,
+			 qdf_nbuf_t rx_ind_msg,
+			 uint16_t peer_id, uint8_t tid, int num_mpdu_ranges)
+{
+}
+#endif
+
+/**
+ * @brief Process an rx fragment indication message sent by the target.
+ * @details
+ *  The target sends a rx fragment indication message to the host as a
+ *  notification that there are new rx fragment available for the
+ *  host to process.
+ *  The HTT host layer locates the rx descriptors and rx fragment
+ *  associated with the indication, and calls this function to
+ *  invoke the rx fragment data processing on the new fragment.
+ *
+ * @param pdev - the data physical device that received the frames
+ *               (registered with HTT as a context pointer during attach time)
+ * @param rx_frag_ind_msg - the network buffer holding the rx fragment
+ *                          indication message
+ * @param peer_id - which peer sent this rx data
+ * @param tid - what (extended) traffic type the rx data is
+ */
+void ol_rx_frag_indication_handler(ol_txrx_pdev_handle pdev,
+				   qdf_nbuf_t rx_frag_ind_msg,
+				   uint16_t peer_id, uint8_t tid);
+
+/**
+ * @brief Process rx offload deliver indication message sent by the target.
+ * @details
+ *  When the target exits offload mode, target delivers packets that it has
+ *  held in its memory to the host using this message.
+ *  Low latency case:
+ *  The message contains the number of MSDUs that are being delivered by the
+ *  target to the host. The packet itself resides in host ring along with some
+ *  metadata describing the peer id, vdev id, tid, FW desc and length of
+ *  the packet being delivered.
+ *  Hight letency case:
+ *  The message itself contains the payload of the MSDU being delivered by
+ *  the target to the host. The message also contains meta data describing
+ *  the packet such as peer id, vdev id, tid, FW desc and length of the packet
+ *  being delivered. Refer to htt.h for the exact structure of the message.
+ *  @param pdev - the data physical device that received the frame.
+ *  @param msg - offload deliver indication message
+ *  @param msdu_cnt - number of MSDUs being delivred.
+ */
+void
+ol_rx_offload_deliver_ind_handler(ol_txrx_pdev_handle pdev,
+				  qdf_nbuf_t msg, uint16_t msdu_cnt);
+
+/**
+ * @brief Process a peer map message sent by the target.
+ * @details
+ *  Each time the target allocates a new peer ID, it will inform the
+ *  host via the "peer map" message.  This function processes that
+ *  message.  The host data SW looks for a peer object whose MAC address
+ *  matches the MAC address specified in the peer map message, and then
+ *  sets up a mapping between the peer ID specified in the message and
+ *  the peer object that was found.
+ *
+ * @param pdev - data physical device handle
+ *      (registered with HTT as a context pointer during attach time)
+ * @param peer_id - ID generated by the target to refer to the peer in question
+ *      The target may create multiple IDs for a single peer.
+ * @param vdev_id - Reference to the virtual device the peer is associated with
+ * @param peer_mac_addr - MAC address of the peer in question
+ * @param tx_ready - whether transmits to this peer can be done already, or
+ *      need to wait for a call to peer_tx_ready (only applies to HL systems)
+ */
+void
+ol_rx_peer_map_handler(ol_txrx_pdev_handle pdev,
+		       uint16_t peer_id,
+		       uint8_t vdev_id, uint8_t *peer_mac_addr, int tx_ready);
+
+/**
+ * @brief notify the host that the target is ready to transmit to a new peer.
+ * @details
+ *  Some targets can immediately accept tx frames for a new peer, as soon as
+ *  the peer's association completes.  Other target need a short setup time
+ *  before they are ready to accept tx frames for the new peer.
+ *  If the target needs time for setup, it will provide a peer_tx_ready
+ *  message when it is done with the setup.  This function forwards this
+ *  notification from the target to the host's tx queue manager.
+ *  This function only applies for HL systems, in which the host determines
+ *  which peer a given tx frame is for, and stores the tx frames in queues.
+ *
+ * @param pdev - data physical device handle
+ *      (registered with HTT as a context pointer during attach time)
+ * @param peer_id - ID for the new peer which can now accept tx frames
+ */
+void ol_txrx_peer_tx_ready_handler(ol_txrx_pdev_handle pdev, uint16_t peer_id);
+
+/**
+ * @brief Process a peer unmap message sent by the target.
+ * @details
+ *  Each time the target frees a peer ID, it will inform the host via the
+ *  "peer unmap" message.  This function processes that message.
+ *  The host data SW uses the peer ID from the message to find the peer
+ *  object from peer_map[peer_id], then invalidates peer_map[peer_id]
+ *  (by setting it to NULL), and checks whether there are any remaining
+ *  references to the peer object.  If not, the function deletes the
+ *  peer object.
+ *
+ * @param pdev - data physical device handle
+ *      (registered with HTT as a context pointer during attach time)
+ * @param peer_id - ID that is being freed.
+ *      The target may create multiple IDs for a single peer.
+ */
+void ol_rx_peer_unmap_handler(ol_txrx_pdev_handle pdev, uint16_t peer_id);
+
+/**
+ * @brief Process a security indication message sent by the target.
+ * @details
+ *  When a key is assigned to a peer, the target will inform the host
+ *  with a security indication message.
+ *  The host remembers the security type, and infers whether a rx PN
+ *  check is needed.
+ *
+ * @param pdev - data physical device handle
+ * @param peer_id - which peer the security info is for
+ * @param sec_type - which type of security / key the peer is using
+ * @param is_unicast - whether security spec is for a unicast or multicast key
+ * @param michael_key - key used for TKIP MIC (if sec_type == TKIP)
+ * @param rx_pn - RSC used for WAPI PN replay check (if sec_type == WAPI)
+ */
+void
+ol_rx_sec_ind_handler(ol_txrx_pdev_handle pdev,
+		      uint16_t peer_id,
+		      enum htt_sec_type sec_type,
+		      int is_unicast, uint32_t *michael_key, uint32_t *rx_pn);
+
+enum htt_rx_flush_action {
+	htt_rx_flush_release,
+	htt_rx_flush_discard,
+};
+
+/**
+ * @brief Process a rx reorder flush message sent by the target.
+ * @details
+ *  The target's rx reorder logic can send a flush indication to the
+ *  host's rx reorder buffering either as a flush IE within a rx
+ *  indication message, or as a standalone rx reorder flush message.
+ *  This ol_rx_flush_handler function processes the standalone rx
+ *  reorder flush message from the target.
+ *  The flush message specifies a range of sequence numbers whose
+ *  rx frames are flushed.
+ *  Some sequence numbers within the specified range may not have
+ *  rx frames; the host needs to check for each sequence number in
+ *  the specified range whether there are rx frames held for that
+ *  sequence number.
+ *
+ * @param pdev - data physical device handle
+ *      (registered with HTT as a context pointer during attach time)
+ * @param peer_id - which peer's rx data is being flushed
+ * @param tid - which traffic ID within the peer has the rx data being flushed
+ * @param seq_num_start - Which sequence number within the rx reordering
+ *      buffer the flushing should start with.
+ *      This is the LSBs of the 802.11 sequence number.
+ *      This sequence number is masked with the rounded-to-power-of-two
+ *      window size to generate a reorder buffer index.
+ *      The flush includes this initial sequence number.
+ * @param seq_num_end - Which sequence number within the rx reordering
+ *      buffer the flushing should stop at.
+ *      This is the LSBs of the 802.11 sequence number.
+ *      This sequence number is masked with the rounded-to-power-of-two
+ *      window size to generate a reorder buffer index.
+ *      The flush excludes this final sequence number.
+ * @param action - whether to release or discard the rx frames
+ */
+void
+ol_rx_flush_handler(ol_txrx_pdev_handle pdev,
+		    uint16_t peer_id,
+		    uint8_t tid,
+		    uint16_t seq_num_start,
+		    uint16_t seq_num_end, enum htt_rx_flush_action action);
+
+/**
+ * @brief Process a rx pn indication message
+ * @details
+ *      When the peer is configured to get PN checking done in target,
+ *      the target instead of sending reorder flush/release messages
+ *      sends PN indication messages which contain the start and end
+ *      sequence numbers to be flushed/released along with the sequence
+ *      numbers of MPDUs that failed the PN check in target.
+ *
+ * @param pdev - data physical device handle
+ *      (registered with HTT as a context pointer during attach time)
+ * @param peer_id - which peer's rx data is being flushed
+ * @param tid - which traffic ID within the peer
+ * @param seq_num_start - Which sequence number within the rx reordering
+ *      buffer to start with.
+ *      This is the LSBs of the 802.11 sequence number.
+ *      This sequence number is masked with the rounded-to-power-of-two
+ *      window size to generate a reorder buffer index.
+ *      This is the initial sequence number.
+ * @param seq_num_end - Which sequence number within the rx reordering
+ *      buffer to stop at.
+ *      This is the LSBs of the 802.11 sequence number.
+ *      This sequence number is masked with the rounded-to-power-of-two
+ *      window size to generate a reorder buffer index.
+ *      The processing stops right before this sequence number
+ * @param pn_ie_cnt - Indicates the number of PN information elements.
+ * @param pn_ie - Pointer to the array of PN information elements. Each
+ *      PN information element contains the LSBs of the 802.11 sequence number
+ *      of the MPDU that failed the PN checking in target.
+ */
+void
+ol_rx_pn_ind_handler(ol_txrx_pdev_handle pdev,
+		     uint16_t peer_id,
+		     uint8_t tid,
+		     uint16_t seq_num_start,
+		     uint16_t seq_num_end, uint8_t pn_ie_cnt, uint8_t *pn_ie);
+
+/**
+ * @brief Process a stats message sent by the target.
+ * @details
+ *  The host can request target for stats.
+ *  The target sends the stats to the host via a confirmation message.
+ *  This ol_txrx_fw_stats_handler function processes the confirmation message.
+ *  Currently, this processing consists of copying the stats from the message
+ *  buffer into the txrx pdev object, and waking the sleeping host context
+ *  that requested the stats.
+ *
+ * @param pdev - data physical device handle
+ *      (registered with HTT as a context pointer during attach time)
+ * @param cookie - Value echoed from the cookie in the stats request
+ *      message.  This allows the host SW to find the stats request object.
+ *      (Currently, this cookie is unused.)
+ * @param stats_info_list - stats confirmation message contents, containing
+ *      a list of the stats requested from the target
+ */
+void
+ol_txrx_fw_stats_handler(ol_txrx_pdev_handle pdev,
+			 uint8_t cookie, uint8_t *stats_info_list);
+
+/**
+ * @brief Process a tx inspect message sent by the target.
+ * @details:
+ *  TODO: update
+ *  This tx inspect message indicates via the descriptor ID
+ *  which tx frames are to be inspected by host. The host
+ *  re-injects the packet back to the host for a number of
+ *  cases.
+ *
+ * @param pdev - the data physical device that sent the tx frames
+ *      (registered with HTT as a context pointer during attach time)
+ * @param num_msdus - how many MSDUs are referenced by the tx completion
+ *      message
+ * @param tx_msdu_id_iterator - abstract method of finding the IDs for the
+ *      individual MSDUs referenced by the tx completion message, via the
+ *      htt_tx_compl_desc_id API function
+ */
+void
+ol_tx_inspect_handler(ol_txrx_pdev_handle pdev,
+		      int num_msdus, void *tx_desc_id_iterator);
+
+/**
+ * @brief Get the UAPSD mask.
+ * @details
+ *  This function will return the UAPSD TID mask.
+ *
+ * @param txrx_pdev - pointer to the txrx pdev object
+ * @param peer_id - PeerID.
+ * @return uapsd mask value
+ */
+uint8_t
+ol_txrx_peer_uapsdmask_get(struct ol_txrx_pdev_t *txrx_pdev, uint16_t peer_id);
+
+/**
+ * @brief Get the Qos Capable.
+ * @details
+ *  This function will return the txrx_peer qos_capable.
+ *
+ * @param txrx_pdev - pointer to the txrx pdev object
+ * @param peer_id - PeerID.
+ * @return qos_capable value
+ */
+uint8_t
+ol_txrx_peer_qoscapable_get(struct ol_txrx_pdev_t *txrx_pdev, uint16_t peer_id);
+
+/**
+ * @brief Process an rx indication message sent by the target.
+ * @details
+ *  The target sends a rx indication message to the host as a
+ *  notification that there are new rx frames available for the
+ *  host to process.
+ *  The HTT host layer locates the rx descriptors and rx frames
+ *  associated with the indication, and calls this function to
+ *  invoke the rx data processing on the new frames.
+ *  All MPDUs referenced by a rx indication message belong to the
+ *  same peer-TID. The frames indicated have been re-ordered by
+ *  the target.
+ *
+ * @param pdev - the data physical device that received the frames
+ *      (registered with HTT as a context pointer during attach time)
+ * @param rx_ind_msg - the network buffer holding the rx indication message
+ * @param peer_id - which peer sent this rx data
+ * @param tid - what (extended) traffic type the rx data is
+ * @param is_offload - is this an offload indication?
+ */
+#ifdef WLAN_FULL_REORDER_OFFLOAD
+void
+ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev,
+				  qdf_nbuf_t rx_ind_msg,
+				  uint16_t peer_id,
+				  uint8_t tid, uint8_t is_offload);
+#else
+static inline void
+ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev,
+				  qdf_nbuf_t rx_ind_msg,
+				  uint16_t peer_id,
+				  uint8_t tid, uint8_t is_offload)
+{
+}
+#endif
+
+#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+
+/**
+ * ol_tx_get_max_tx_groups_supported() - get max TCQ groups supported
+ * @pdev: the data physical device that received the frames
+ *
+ * Return: number of max groups supported
+ */
+u_int32_t ol_tx_get_max_tx_groups_supported(struct ol_txrx_pdev_t *pdev);
+#else
+
+static inline u_int32_t
+ol_tx_get_max_tx_groups_supported(struct ol_txrx_pdev_t *pdev)
+{
+	return 0;
+}
+#endif
+
+#if defined(FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL) && \
+	defined(FEATURE_HL_DBS_GROUP_CREDIT_SHARING)
+int ol_txrx_distribute_group_credits(struct ol_txrx_pdev_t *pdev, u8 group_id,
+				     u32 membership_new);
+#else
+static inline int ol_txrx_distribute_group_credits(struct ol_txrx_pdev_t *pdev,
+						   u8 group_id,
+						   u32 membership_new)
+{
+	return 0;
+}
+#endif /*
+	* FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL &&
+	* FEATURE_HL_DBS_GROUP_CREDIT_SHARING
+	*/
+#endif /* _OL_TXRX_HTT_API__H_ */
diff --git a/core/dp/ol/inc/ol_txrx_osif_api.h b/core/dp/ol/inc/ol_txrx_osif_api.h
new file mode 100644
index 0000000..203f277
--- /dev/null
+++ b/core/dp/ol/inc/ol_txrx_osif_api.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, 2014-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.
+ */
+
+/**
+ * @file ol_txrx_osif_api.h
+ * @brief Define the host data API functions called by the host OS shim SW.
+ */
+#ifndef _OL_TXRX_OSIF_API__H_
+#define _OL_TXRX_OSIF_API__H_
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include "cds_sched.h"
+#include "ol_txrx_ctrl_api.h"
+#include <cdp_txrx_peer_ops.h>
+
+/**
+ * struct ol_rx_cached_buf - rx cached buffer
+ * @list: linked list
+ * @buf: skb buffer
+ */
+struct ol_rx_cached_buf {
+	struct list_head list;
+	qdf_nbuf_t buf;
+};
+
+struct txrx_rx_metainfo;
+
+/**
+ * @brief Divide a jumbo TCP frame into smaller segments.
+ * @details
+ *  For efficiency, the protocol stack above the WLAN driver may operate
+ *  on jumbo tx frames, which are larger than the 802.11 MTU.
+ *  The OSIF SW uses this txrx API function to divide the jumbo tx TCP frame
+ *  into a series of segment frames.
+ *  The segments are created as clones of the input jumbo frame.
+ *  The txrx SW generates a new encapsulation header (ethernet + IP + TCP)
+ *  for each of the output segment frames.  The exact format of this header,
+ *  e.g. 802.3 vs. Ethernet II, and IPv4 vs. IPv6, is chosen to match the
+ *  header format of the input jumbo frame.
+ *  The input jumbo frame is not modified.
+ *  After the ol_txrx_osif_tso_segment returns, the OSIF SW needs to perform
+ *  DMA mapping on each of the segment network buffers, and also needs to
+ *
+ * @param txrx_vdev - which virtual device will transmit the TSO segments
+ * @param max_seg_payload_bytes - the maximum size for the TCP payload of
+ *      each segment frame.
+ *      This does not include the ethernet + IP + TCP header sizes.
+ * @param jumbo_tcp_frame - jumbo frame which needs to be cloned+segmented
+ * @return
+ *      NULL if the segmentation fails, - OR -
+ *      a NULL-terminated list of segment network buffers
+ */
+qdf_nbuf_t ol_txrx_osif_tso_segment(ol_txrx_vdev_handle txrx_vdev,
+				    int max_seg_payload_bytes,
+				    qdf_nbuf_t jumbo_tcp_frame);
+
+qdf_nbuf_t ol_tx_data(void *data_vdev, qdf_nbuf_t skb);
+
+void ol_rx_data_process(struct ol_txrx_peer_t *peer,
+			qdf_nbuf_t rx_buf_list);
+
+void ol_txrx_flush_rx_frames(struct ol_txrx_peer_t *peer,
+			     bool drop);
+#endif /* _OL_TXRX_OSIF_API__H_ */
diff --git a/core/dp/ol/inc/ol_txrx_stats.h b/core/dp/ol/inc/ol_txrx_stats.h
new file mode 100644
index 0000000..4c2a073
--- /dev/null
+++ b/core/dp/ol/inc/ol_txrx_stats.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2012, 2014-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.
+ */
+
+/**
+ * @file ol_txrx_status.h
+ * @brief Functions provided for visibility and debugging.
+ * NOTE: This file is used by both kernel driver SW and userspace SW.
+ * Thus, do not reference use any kernel header files or defs in this file!
+ */
+#ifndef _OL_TXRX_STATS__H_
+#define _OL_TXRX_STATS__H_
+
+#include <athdefs.h>            /* uint64_t */
+
+
+
+struct ol_txrx_stats_elem {
+	uint64_t pkts;
+	uint64_t bytes;
+};
+
+#define NUM_MAX_TSO_SEGS 4
+#define NUM_MAX_TSO_SEGS_MASK (NUM_MAX_TSO_SEGS - 1)
+
+#define NUM_MAX_TSO_MSDUS 32
+#define NUM_MAX_TSO_MSDUS_MASK (NUM_MAX_TSO_MSDUS - 1)
+
+struct ol_txrx_stats_tso_msdu {
+	struct qdf_tso_seg_t tso_segs[NUM_MAX_TSO_SEGS];
+	uint8_t num_seg;
+	uint8_t tso_seg_idx;
+	uint32_t total_len;
+	uint32_t gso_size;
+	uint8_t nr_frags;
+};
+
+struct ol_txrx_stats_tso_info {
+	struct ol_txrx_stats_tso_msdu tso_msdu_info[NUM_MAX_TSO_MSDUS];
+	uint32_t tso_msdu_idx;
+};
+
+/**
+ * @brief data stats published by the host txrx layer
+ *
+ * -------------------------
+ *
+ * TX
+ *
+ */
+struct ol_txrx_stats_tx_dropped {
+	/* MSDUs that the host did not accept */
+	struct ol_txrx_stats_elem host_reject;
+	/* MSDUs which could not be downloaded to the target */
+	struct ol_txrx_stats_elem download_fail;
+	/*
+	 * MSDUs which the target discarded
+	 * (lack of memory or old age)
+	 */
+	struct ol_txrx_stats_elem target_discard;
+	/*
+	 * MSDUs which the target sent but
+	 * couldn't get an ack for
+	 */
+	struct ol_txrx_stats_elem no_ack;
+
+	/* MSDU which were dropped for other reasons */
+	struct ol_txrx_stats_elem others;
+};
+
+struct ol_txrx_tso_histogram {
+	uint32_t pkts_1;
+	uint32_t pkts_2_5;
+	uint32_t pkts_6_10;
+	uint32_t pkts_11_15;
+	uint32_t pkts_16_20;
+	uint32_t pkts_20_plus;
+};
+
+struct ol_txrx_stats_tx_histogram {
+	uint32_t pkts_1;
+	uint32_t pkts_2_10;
+	uint32_t pkts_11_20;
+	uint32_t pkts_21_30;
+	uint32_t pkts_31_40;
+	uint32_t pkts_41_50;
+	uint32_t pkts_51_60;
+	uint32_t pkts_61_plus;
+};
+struct ol_txrx_stats_tx_tso {
+	struct ol_txrx_stats_elem tso_pkts;
+#if defined(FEATURE_TSO)
+	struct ol_txrx_stats_tso_info tso_info;
+	struct ol_txrx_tso_histogram tso_hist;
+	qdf_spinlock_t tso_stats_lock;
+#endif
+};
+
+struct ol_txrx_stats_tx {
+	/* MSDUs given to the txrx layer by the management stack */
+	struct ol_txrx_stats_elem mgmt;
+	/* MSDUs received from the stack */
+	struct ol_txrx_stats_elem from_stack;
+	/* MSDUs successfully sent across the WLAN */
+	struct ol_txrx_stats_elem delivered;
+	struct ol_txrx_stats_tx_dropped dropped;
+	/* contains information of packets recevied per tx completion*/
+	struct ol_txrx_stats_tx_histogram comp_histogram;
+	/* TSO (TCP segmentation offload) information */
+	struct ol_txrx_stats_tx_tso tso;
+};
+
+/*
+ * RX
+ */
+struct ol_txrx_stats_rx_histogram {
+	uint32_t pkts_1;
+	uint32_t pkts_2_10;
+	uint32_t pkts_11_20;
+	uint32_t pkts_21_30;
+	uint32_t pkts_31_40;
+	uint32_t pkts_41_50;
+	uint32_t pkts_51_60;
+	uint32_t pkts_61_plus;
+};
+struct ol_txrx_stats_rx_ibss_fwd {
+	/* MSDUs forwarded to network stack */
+	u_int32_t packets_stack;
+	/* MSDUs forwarded from the rx path to the tx path */
+	u_int32_t packets_fwd;
+	/* MSDUs forwarded to stack and tx path */
+	u_int32_t packets_stack_n_fwd;
+};
+struct ol_txrx_stats_rx {
+	/* MSDUs given to the OS shim */
+	struct ol_txrx_stats_elem delivered;
+	struct ol_txrx_stats_elem dropped_err;
+	struct ol_txrx_stats_elem dropped_mic_err;
+	struct ol_txrx_stats_elem dropped_peer_invalid;
+	struct ol_txrx_stats_rx_ibss_fwd intra_bss_fwd;
+	struct ol_txrx_stats_rx_histogram rx_ind_histogram;
+	uint32_t msdus_with_frag_ind;
+	uint32_t msdus_with_offload_ind;
+};
+struct ol_txrx_stats {
+	struct ol_txrx_stats_tx tx;
+	struct ol_txrx_stats_rx rx;
+};
+
+/*
+ * Structure to consolidate host stats
+ */
+struct ieee80211req_ol_ath_host_stats {
+	struct ol_txrx_stats txrx_stats;
+	struct {
+		int pkt_q_fail_count;
+		int pkt_q_empty_count;
+		int send_q_empty_count;
+	} htc;
+	struct {
+		int pipe_no_resrc_count;
+		int ce_ring_delta_fail_count;
+	} hif;
+};
+
+#endif /* _OL_TXRX_STATS__H_ */
diff --git a/core/dp/ol/inc/ol_vowext_dbg_defs.h b/core/dp/ol/inc/ol_vowext_dbg_defs.h
new file mode 100644
index 0000000..ab82d5e
--- /dev/null
+++ b/core/dp/ol/inc/ol_vowext_dbg_defs.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 2014-2016, 2018 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.
+ */
+
+#ifndef _VOW_DEFINES__H_
+#define _VOW_DEFINES__H_
+
+#define UDP_CKSUM_OFFSET   40   /* UDP check sum offset in network buffer */
+#define RTP_HDR_OFFSET  42      /* RTP header offset in network buffer */
+#define EXT_HDR_OFFSET 54       /* Extension header offset in network buffer */
+#define UDP_PDU_RTP_EXT  0x90   /* ((2 << 6) | (1 << 4)) RTP V2 + X bit */
+#define IP_VER4_N_NO_EXTRA_HEADERS 0x45
+#define IPERF3_DATA_OFFSET 12   /* iperf3 data offset from EXT_HDR_OFFSET */
+#define HAL_RX_40  0x08         /* 40 Mhz */
+#define HAL_RX_GI  0x04         /* full gi */
+
+struct vow_extstats {
+	uint8_t rx_rssi_ctl0;   /* control channel chain0 rssi */
+	uint8_t rx_rssi_ctl1;   /* control channel chain1 rssi */
+	uint8_t rx_rssi_ctl2;   /* control channel chain2 rssi */
+	uint8_t rx_rssi_ext0;   /* extension channel chain0 rssi */
+	uint8_t rx_rssi_ext1;   /* extension channel chain1 rssi */
+	uint8_t rx_rssi_ext2;   /* extension channel chain2 rssi */
+	uint8_t rx_rssi_comb;   /* combined RSSI value */
+	uint8_t rx_bw;          /* Band width 0-20, 1-40, 2-80 */
+	uint8_t rx_sgi;         /* Guard interval, 0-Long GI, 1-Short GI */
+	uint8_t rx_nss;         /* Number of spatial streams */
+	uint8_t rx_mcs;         /* Rate MCS value */
+	uint8_t rx_ratecode;    /* Hardware rate code */
+	uint8_t rx_rs_flags;    /* Receive misc flags */
+	uint8_t rx_moreaggr;    /* 0 - non aggr frame */
+	uint32_t rx_macTs;      /* Time stamp */
+	uint16_t rx_seqno;      /* rx sequence number */
+};
+
+/**
+ * @brief populates vow ext stats in given network buffer.
+ * @param msdu - network buffer handle
+ * @param pdev - handle to htt dev.
+ */
+void ol_ath_add_vow_extstats(htt_pdev_handle pdev, qdf_nbuf_t msdu);
+
+#endif /* _VOW_DEFINES__H_ */
diff --git a/core/dp/txrx/ipv6_defs.h b/core/dp/txrx/ipv6_defs.h
new file mode 100644
index 0000000..ffdd656
--- /dev/null
+++ b/core/dp/txrx/ipv6_defs.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012-2014, 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.
+ */
+
+#ifndef _IPV6__H_
+#define _IPV6__H_
+
+#if defined(ATH_TARGET)
+#include <osapi.h>              /* A_UINT8 */
+#else
+#include <a_types.h>            /* A_UINT8 */
+#endif
+
+/* utilities for converting between network byte order and native endianness */
+#ifndef BYTESWAP32
+#define BYTESWAP32(x) \
+	((((x) & 0x000000ff) << 24) /* byte 0 -> byte 3 */ | \
+	 (((x) & 0x0000ff00) <<  8) /* byte 1 -> byte 2 */ | \
+	 (((x) & 0x00ff0000) >>  8) /* byte 2 -> byte 1 */ | \
+	 (((x) & 0xff000000) >> 24) /* byte 3 -> byte 0 */)
+#endif /* BYTESWAP32 */
+
+#ifndef BE_TO_CPU32
+#if defined(ATH_TARGET)
+/* assume target is little-endian */
+#define BE_TO_CPU32(x) BYTESWAP32(x)
+#else
+#ifdef BIG_ENDIAN_HOST
+#define BE_TO_CPU32(x) (x)
+#else
+#define BE_TO_CPU32(x) BYTESWAP32(x)
+#endif
+#endif
+#endif /* BE_TO_CPU32 */
+
+/* IPv6 header definition */
+
+#define IPV6_ADDR_LEN 4         /* bytes */
+struct ipv6_hdr_t {
+	/* version, traffic class, and flow label */
+	A_UINT32 ver_tclass_flowlabel;
+	A_UINT8 pyld_len[2];    /* payload length */
+	A_UINT8 next_hdr;
+	A_UINT8 hop_limit;
+	A_UINT8 src_addr[IPV6_ADDR_LEN];
+	A_UINT8 dst_addr[IPV6_ADDR_LEN];
+};
+
+#define IPV6_HDR_LEN (sizeof(struct ipv6_hdr_t))
+#define IPV6_HDR_OFFSET_NEXT_HDR (offsetof(struct ipv6_hdr_t, next_hdr))
+#define IPV6_HDR_OFFSET_DST_ADDR (offsetof(struct ipv6_hdr_t, dst_addr[0]))
+
+/* IPv6 header field access macros */
+
+#define IPV6_HDR_VERSION_M       0xF0000000
+#define IPV6_HDR_VERSION_S       28
+
+#define IPV6_HDR_TRAFFIC_CLASS_M 0x0FF00000
+#define IPV6_HDR_TRAFFIC_CLASS_S 20
+
+#define IPV6_HDR_FLOW_LABEL_M    0x000FFFFF
+#define IPV6_HDR_FLOW_LABEL_S    0
+
+static inline A_UINT8 ipv6_version(struct ipv6_hdr_t *ipv6_hdr)
+{
+	return (BE_TO_CPU32(ipv6_hdr->ver_tclass_flowlabel) &
+	       IPV6_HDR_VERSION_M) >> IPV6_HDR_VERSION_S;
+}
+
+static inline A_UINT8 ipv6_traffic_class(struct ipv6_hdr_t *ipv6_hdr)
+{
+	return (A_UINT8)((BE_TO_CPU32(ipv6_hdr->ver_tclass_flowlabel) &
+	       IPV6_HDR_TRAFFIC_CLASS_M) >> IPV6_HDR_TRAFFIC_CLASS_S);
+}
+
+static inline A_UINT32 ipv6_flow_label(struct ipv6_hdr_t *ipv6_hdr)
+{
+	return (BE_TO_CPU32(ipv6_hdr->ver_tclass_flowlabel) &
+	       IPV6_HDR_FLOW_LABEL_M) >> IPV6_HDR_FLOW_LABEL_S;
+}
+
+#endif /* _IPV6__H_ */
diff --git a/core/dp/txrx/ol_cfg.c b/core/dp/txrx/ol_cfg.c
new file mode 100644
index 0000000..66622a5
--- /dev/null
+++ b/core/dp/txrx/ol_cfg.c
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#include <ol_cfg.h>
+#include <ol_if_athvar.h>
+#include <cdp_txrx_cfg.h>
+#include <cdp_txrx_handle.h>
+
+unsigned int vow_config;
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+/**
+ * ol_tx_set_flow_control_parameters() - set flow control parameters
+ * @cfg_ctx: cfg context
+ * @cfg_param: cfg parameters
+ *
+ * Return: none
+ */
+void ol_tx_set_flow_control_parameters(struct cdp_cfg *cfg_pdev,
+	struct txrx_pdev_cfg_param_t *cfg_param)
+{
+	struct txrx_pdev_cfg_t *cfg_ctx = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	cfg_ctx->tx_flow_start_queue_offset =
+					cfg_param->tx_flow_start_queue_offset;
+	cfg_ctx->tx_flow_stop_queue_th =
+					cfg_param->tx_flow_stop_queue_th;
+}
+#endif
+
+#ifdef CONFIG_HL_SUPPORT
+
+#ifdef CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE
+static inline
+void ol_pdev_cfg_credit_update(struct txrx_pdev_cfg_t *cfg_ctx)
+{
+	cfg_ctx->tx_free_at_download = 1;
+	cfg_ctx->credit_update_enabled = 1;
+}
+#else
+static inline
+void ol_pdev_cfg_credit_update(struct txrx_pdev_cfg_t *cfg_ctx)
+{
+	cfg_ctx->tx_free_at_download = 0;
+	cfg_ctx->credit_update_enabled = 0;
+}
+#endif /* CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE */
+
+/**
+ * ol_pdev_cfg_param_update() - assign download size of tx frame for txrx
+ *				    pdev that will be used across datapath
+ * @cfg_ctx: ptr to config parameter for txrx pdev
+ *
+ * Return: None
+ */
+static inline
+void ol_pdev_cfg_param_update(struct txrx_pdev_cfg_t *cfg_ctx)
+{
+	cfg_ctx->is_high_latency = 1;
+	/* 802.1Q and SNAP / LLC headers are accounted for elsewhere */
+	cfg_ctx->tx_download_size = 1500;
+	ol_pdev_cfg_credit_update(cfg_ctx);
+}
+#else
+
+static inline
+void ol_pdev_cfg_param_update(struct txrx_pdev_cfg_t *cfg_ctx)
+{
+	/*
+	 * Need to change HTT_LL_TX_HDR_SIZE_IP accordingly.
+	 * Include payload, up to the end of UDP header for IPv4 case
+	 */
+	cfg_ctx->tx_download_size = 16;
+}
+#endif
+
+#if CFG_TGT_DEFAULT_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK
+static inline
+uint8_t ol_defrag_timeout_check(void)
+{
+	return 1;
+}
+#else
+static inline
+uint8_t ol_defrag_timeout_check(void)
+{
+	return 0;
+}
+#endif
+
+/* FIX THIS -
+ * For now, all these configuration parameters are hardcoded.
+ * Many of these should actually be determined dynamically instead.
+ */
+
+struct cdp_cfg *ol_pdev_cfg_attach(qdf_device_t osdev, void *pcfg_param)
+{
+	struct txrx_pdev_cfg_param_t *cfg_param = pcfg_param;
+	struct txrx_pdev_cfg_t *cfg_ctx;
+	int i;
+
+	cfg_ctx = qdf_mem_malloc(sizeof(*cfg_ctx));
+	if (!cfg_ctx) {
+		printk(KERN_ERR "cfg ctx allocation failed\n");
+		return NULL;
+	}
+
+	ol_pdev_cfg_param_update(cfg_ctx);
+
+	/* temporarily disabled PN check for Riva/Pronto */
+	cfg_ctx->rx_pn_check = 1;
+	cfg_ctx->defrag_timeout_check = ol_defrag_timeout_check();
+	cfg_ctx->max_peer_id = 511;
+	cfg_ctx->max_vdev = CFG_TGT_NUM_VDEV;
+	cfg_ctx->pn_rx_fwd_check = 1;
+	cfg_ctx->frame_type = wlan_frm_fmt_802_3;
+	cfg_ctx->max_thruput_mbps = 800;
+	cfg_ctx->max_nbuf_frags = 1;
+	cfg_ctx->vow_config = vow_config;
+	cfg_ctx->target_tx_credit = CFG_TGT_NUM_MSDU_DESC;
+	cfg_ctx->throttle_period_ms = 40;
+	cfg_ctx->dutycycle_level[0] = THROTTLE_DUTY_CYCLE_LEVEL0;
+	cfg_ctx->dutycycle_level[1] = THROTTLE_DUTY_CYCLE_LEVEL1;
+	cfg_ctx->dutycycle_level[2] = THROTTLE_DUTY_CYCLE_LEVEL2;
+	cfg_ctx->dutycycle_level[3] = THROTTLE_DUTY_CYCLE_LEVEL3;
+	cfg_ctx->rx_fwd_disabled = 0;
+	cfg_ctx->is_packet_log_enabled = 0;
+	cfg_ctx->is_full_reorder_offload = cfg_param->is_full_reorder_offload;
+#ifdef WLAN_FEATURE_TSF_PLUS
+	cfg_ctx->is_ptp_rx_opt_enabled = 0;
+#endif
+	cfg_ctx->ipa_uc_rsc.uc_offload_enabled =
+		cfg_param->is_uc_offload_enabled;
+	cfg_ctx->ipa_uc_rsc.tx_max_buf_cnt = cfg_param->uc_tx_buffer_count;
+	cfg_ctx->ipa_uc_rsc.tx_buf_size = cfg_param->uc_tx_buffer_size;
+	cfg_ctx->ipa_uc_rsc.rx_ind_ring_size =
+		cfg_param->uc_rx_indication_ring_count;
+	cfg_ctx->ipa_uc_rsc.tx_partition_base = cfg_param->uc_tx_partition_base;
+	cfg_ctx->enable_rxthread = cfg_param->enable_rxthread;
+	cfg_ctx->ip_tcp_udp_checksum_offload =
+		cfg_param->ip_tcp_udp_checksum_offload;
+	cfg_ctx->ce_classify_enabled = cfg_param->ce_classify_enabled;
+	cfg_ctx->gro_enable = cfg_param->gro_enable;
+	cfg_ctx->tso_enable = cfg_param->tso_enable;
+	cfg_ctx->lro_enable = cfg_param->lro_enable;
+	cfg_ctx->enable_data_stall_detection =
+		cfg_param->enable_data_stall_detection;
+	cfg_ctx->enable_flow_steering = cfg_param->enable_flow_steering;
+	cfg_ctx->disable_intra_bss_fwd = cfg_param->disable_intra_bss_fwd;
+
+	ol_tx_set_flow_control_parameters((struct cdp_cfg *)cfg_ctx, cfg_param);
+
+	for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
+		cfg_ctx->ac_specs[i].wrr_skip_weight =
+			cfg_param->ac_specs[i].wrr_skip_weight;
+		cfg_ctx->ac_specs[i].credit_threshold =
+			cfg_param->ac_specs[i].credit_threshold;
+		cfg_ctx->ac_specs[i].send_limit =
+			cfg_param->ac_specs[i].send_limit;
+		cfg_ctx->ac_specs[i].credit_reserve =
+			cfg_param->ac_specs[i].credit_reserve;
+		cfg_ctx->ac_specs[i].discard_weight =
+			cfg_param->ac_specs[i].discard_weight;
+	}
+
+	return (struct cdp_cfg *)cfg_ctx;
+}
+
+int ol_cfg_is_high_latency(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->is_high_latency;
+}
+
+int ol_cfg_is_credit_update_enabled(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->credit_update_enabled;
+}
+
+int ol_cfg_max_peer_id(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+	/*
+	 * TBDXXX - this value must match the peer table
+	 * size allocated in FW
+	 */
+	return cfg->max_peer_id;
+}
+
+int ol_cfg_max_vdevs(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->max_vdev;
+}
+
+int ol_cfg_rx_pn_check(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->rx_pn_check;
+}
+
+int ol_cfg_rx_fwd_check(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->pn_rx_fwd_check;
+}
+
+void ol_set_cfg_rx_fwd_disabled(struct cdp_cfg *cfg_pdev,
+		uint8_t disable_rx_fwd)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	cfg->rx_fwd_disabled = disable_rx_fwd;
+}
+
+void ol_set_cfg_packet_log_enabled(struct cdp_cfg *cfg_pdev, uint8_t val)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	cfg->is_packet_log_enabled = val;
+}
+
+uint8_t ol_cfg_is_packet_log_enabled(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->is_packet_log_enabled;
+}
+
+int ol_cfg_rx_fwd_disabled(struct cdp_cfg *cfg_pdev)
+{
+#if defined(ATHR_WIN_NWF)
+	/* for Windows, let the OS handle the forwarding */
+	return 1;
+#else
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->rx_fwd_disabled;
+#endif
+}
+
+int ol_cfg_rx_fwd_inter_bss(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->rx_fwd_inter_bss;
+}
+
+enum wlan_frm_fmt ol_cfg_frame_type(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->frame_type;
+}
+
+int ol_cfg_max_thruput_mbps(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->max_thruput_mbps;
+}
+
+int ol_cfg_netbuf_frags_max(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->max_nbuf_frags;
+}
+
+int ol_cfg_tx_free_at_download(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->tx_free_at_download;
+}
+
+void ol_cfg_set_tx_free_at_download(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	cfg->tx_free_at_download = 1;
+}
+
+
+#ifdef CONFIG_HL_SUPPORT
+uint16_t ol_cfg_target_tx_credit(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->target_tx_credit;
+}
+#else
+
+uint16_t ol_cfg_target_tx_credit(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+	uint16_t rc;
+	uint16_t vow_max_sta = (cfg->vow_config & 0xffff0000) >> 16;
+	uint16_t vow_max_desc_persta = cfg->vow_config & 0x0000ffff;
+
+	rc =  (cfg->target_tx_credit + (vow_max_sta * vow_max_desc_persta));
+
+	return rc;
+}
+#endif
+
+int ol_cfg_tx_download_size(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->tx_download_size;
+}
+
+int ol_cfg_rx_host_defrag_timeout_duplicate_check(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->defrag_timeout_check;
+}
+
+int ol_cfg_throttle_period_ms(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->throttle_period_ms;
+}
+
+int ol_cfg_throttle_duty_cycle_level(struct cdp_cfg *cfg_pdev, int level)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->dutycycle_level[level];
+}
+
+#ifdef CONFIG_HL_SUPPORT
+int ol_cfg_is_full_reorder_offload(struct cdp_cfg *cfg_pdev)
+{
+	return 0;
+}
+#else
+int ol_cfg_is_full_reorder_offload(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->is_full_reorder_offload;
+}
+#endif
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+void ol_set_cfg_ptp_rx_opt_enabled(struct cdp_cfg *cfg_pdev, u_int8_t val)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	cfg->is_ptp_rx_opt_enabled = val;
+}
+
+u_int8_t ol_cfg_is_ptp_rx_opt_enabled(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->is_ptp_rx_opt_enabled;
+}
+#endif
+
+/**
+ * ol_cfg_is_rx_thread_enabled() - return rx_thread is enable/disable
+ * @pdev : handle to the physical device
+ *
+ * Return: 1 - enable, 0 - disable
+ */
+int ol_cfg_is_rx_thread_enabled(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->enable_rxthread;
+}
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+/**
+ * ol_cfg_get_tx_flow_stop_queue_th() - return stop queue threshold
+ * @pdev : handle to the physical device
+ *
+ * Return: stop queue threshold
+ */
+int ol_cfg_get_tx_flow_stop_queue_th(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->tx_flow_stop_queue_th;
+}
+
+/**
+ * ol_cfg_get_tx_flow_start_queue_offset() - return start queue offset
+ * @pdev : handle to the physical device
+ *
+ * Return: start queue offset
+ */
+int ol_cfg_get_tx_flow_start_queue_offset(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->tx_flow_start_queue_offset;
+}
+
+#endif
+
+#ifdef IPA_OFFLOAD
+unsigned int ol_cfg_ipa_uc_offload_enabled(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return (unsigned int)cfg->ipa_uc_rsc.uc_offload_enabled;
+}
+
+unsigned int ol_cfg_ipa_uc_tx_buf_size(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->ipa_uc_rsc.tx_buf_size;
+}
+
+unsigned int ol_cfg_ipa_uc_tx_max_buf_cnt(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->ipa_uc_rsc.tx_max_buf_cnt;
+}
+
+unsigned int ol_cfg_ipa_uc_rx_ind_ring_size(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->ipa_uc_rsc.rx_ind_ring_size;
+}
+
+unsigned int ol_cfg_ipa_uc_tx_partition_base(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->ipa_uc_rsc.tx_partition_base;
+}
+
+void ol_cfg_set_ipa_uc_tx_partition_base(struct cdp_cfg *cfg_pdev, uint32_t val)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	cfg->ipa_uc_rsc.tx_partition_base = val;
+}
+#endif /* IPA_OFFLOAD */
+
+/**
+ * ol_cfg_is_ce_classify_enabled() - Return if CE classification is enabled
+ *				     or disabled
+ * @pdev : handle to the physical device
+ *
+ * Return: 1 - enabled, 0 - disabled
+ */
+bool ol_cfg_is_ce_classify_enabled(struct cdp_cfg *cfg_pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev;
+
+	return cfg->ce_classify_enabled;
+}
+
+/**
+ * ol_cfg_get_wrr_skip_weight() - brief Query for the param of wrr_skip_weight
+ * @pdev: handle to the physical device.
+ * @ac: access control, it will be BE, BK, VI, VO
+ *
+ * Return: wrr_skip_weight for specified ac.
+ */
+int ol_cfg_get_wrr_skip_weight(struct cdp_cfg *pdev, int ac)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev;
+
+	if (ac >= OL_TX_WMM_AC_BE && ac <= OL_TX_WMM_AC_VO)
+		return cfg->ac_specs[ac].wrr_skip_weight;
+
+	return 0;
+}
+
+/**
+ * ol_cfg_get_credit_threshold() - Query for the param of credit_threshold
+ * @pdev: handle to the physical device.
+ * @ac: access control, it will be BE, BK, VI, VO
+ *
+ * Return: credit_threshold for specified ac.
+ */
+uint32_t ol_cfg_get_credit_threshold(struct cdp_cfg *pdev, int ac)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev;
+
+	if (ac >= OL_TX_WMM_AC_BE && ac <= OL_TX_WMM_AC_VO)
+		return cfg->ac_specs[ac].credit_threshold;
+
+	return 0;
+}
+
+/**
+ * ol_cfg_get_send_limit() - Query for the param of send_limit
+ * @pdev: handle to the physical device.
+ * @ac: access control, it will be BE, BK, VI, VO
+ *
+ * Return: send_limit for specified ac.
+ */
+uint16_t ol_cfg_get_send_limit(struct cdp_cfg *pdev, int ac)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev;
+
+	if (ac >= OL_TX_WMM_AC_BE && ac <= OL_TX_WMM_AC_VO)
+		return cfg->ac_specs[ac].send_limit;
+
+	return 0;
+}
+
+/**
+ * ol_cfg_get_credit_reserve() - Query for the param of credit_reserve
+ * @pdev: handle to the physical device.
+ * @ac: access control, it will be BE, BK, VI, VO
+ *
+ * Return: credit_reserve for specified ac.
+ */
+int ol_cfg_get_credit_reserve(struct cdp_cfg *pdev, int ac)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev;
+
+	if (ac >= OL_TX_WMM_AC_BE && ac <= OL_TX_WMM_AC_VO)
+		return cfg->ac_specs[ac].credit_reserve;
+
+	return 0;
+}
+
+/**
+ * ol_cfg_get_discard_weight() - Query for the param of discard_weight
+ * @pdev: handle to the physical device.
+ * @ac: access control, it will be BE, BK, VI, VO
+ *
+ * Return: discard_weight for specified ac.
+ */
+int ol_cfg_get_discard_weight(struct cdp_cfg *pdev, int ac)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev;
+
+	if (ac >= OL_TX_WMM_AC_BE && ac <= OL_TX_WMM_AC_VO)
+		return cfg->ac_specs[ac].discard_weight;
+
+	return 0;
+}
diff --git a/core/dp/txrx/ol_ctrl_txrx_api.h b/core/dp/txrx/ol_ctrl_txrx_api.h
new file mode 100644
index 0000000..b31f126
--- /dev/null
+++ b/core/dp/txrx/ol_ctrl_txrx_api.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2011-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.
+ */
+
+/**
+ * @file ol_ctrl_txrx_api.h
+ * @brief Define the host control API functions called by the host data SW.
+ */
+#ifndef _OL_CTRL_TXRX_API__H_
+#define _OL_CTRL_TXRX_API__H_
+
+/* #include <osapi_linux.h>      / * uint8_t * / */
+#include <osdep.h>              /* uint8_t */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+
+#include <cdp_txrx_cmn.h>           /* ol_txrx_pdev_handle */
+#include <ol_txrx_types.h>          /* OL_TXRX_MAC_ADDR_LEN */
+#include <cds_ieee80211_common.h>   /* ieee80211_frame */
+#include <cdp_txrx_handle.h>
+#ifdef SUPPORT_HOST_STATISTICS
+/** * @brief Update tx statistics
+ * @details
+ *  Update tx statistics after tx complete.
+ *
+ * @param pdev - ol_pdev_handle instance
+ * @param vdev_id - ID of the virtual device that tx frame
+ * @param had_error - whether there is error when tx
+ */
+void ol_tx_statistics(struct cdp_cfg *cfg_pdev,
+		     uint16_t vdev_id, int had_error);
+#else
+#define ol_tx_statistics(pdev, vdev_id, had_error)
+#endif
+
+/** * @brief Count on received packets for invalid peer case
+ *
+ * @param pdev - txrx pdev handle
+ * @param wh - received frame
+ * @param err_type - what kind of error occurred
+ */
+void ol_rx_err_inv_peer_statistics(struct cdp_cfg *cfg_pdev,
+				   struct ieee80211_frame *wh,
+				   enum ol_rx_err_type err_type);
+
+/**
+ * @brief Count on received packets, both success and failed
+ *
+ * @param pdev - ol_pdev_handle handle
+ * @param vdev_id - ID of the virtual device received the erroneous rx frame
+ * @param err_type - what kind of error occurred
+ * @param sec_type - The cipher type the peer is using
+ * @param is_mcast - whether this is one multi cast frame
+ */
+void ol_rx_err_statistics(struct cdp_cfg *cfg_pdev,
+			  uint8_t vdev_id,
+			  enum ol_rx_err_type err_type,
+			  enum ol_sec_type sec_type, int is_mcast);
+
+/**
+ * @brief Provide notification of failure during host rx processing
+ * @details
+ *  Indicate an error during host rx data processing, including what
+ *  kind of error happened, when it happened, which peer and TID the
+ *  erroneous rx frame is from, and what the erroneous rx frame itself
+ *  is.
+ *
+ * @param pdev - handle to the ctrl SW's physical device object
+ * @param vdev_id - ID of the virtual device received the erroneous rx frame
+ * @param peer_mac_addr - MAC address of the peer that sent the erroneous
+ *      rx frame
+ * @param tid - which TID within the peer sent the erroneous rx frame
+ * @param tsf32  - the timstamp in TSF units of the erroneous rx frame, or
+ *      one of the fragments that when reassembled, constitute the rx frame
+ * @param err_type - what kind of error occurred
+ * @param rx_frame - the rx frame that had an error
+ * @pn - Packet sequence number
+ * @key_id - Key index octet received in IV of the frame
+ */
+void
+ol_rx_err(struct cdp_cfg *cfg_pdev,
+	  uint8_t vdev_id,
+	  uint8_t *peer_mac_addr,
+	  int tid,
+	  uint32_t tsf32,
+	  enum ol_rx_err_type err_type,
+	  qdf_nbuf_t rx_frame, uint64_t *pn, uint8_t key_id);
+
+#ifdef HL_RX_AGGREGATION_HOLE_DETECTION
+/**
+ * ol_rx_aggregation_hole - ol rx aggregation hole report
+ * @hole_info: hole_info
+ *
+ * Return: void
+ */
+void ol_rx_aggregation_hole(uint32_t hole_info);
+#endif
+
+enum ol_rx_notify_type {
+	OL_RX_NOTIFY_IPV4_IGMP,
+};
+
+/**
+ * @brief Provide notification of reception of data of special interest.
+ * @details
+ *  Indicate when "special" data has been received.  The nature of the
+ *  data that results in it being considered special is specified in the
+ *  notify_type argument.
+ *  This function is currently used by the data-path SW to notify the
+ *  control path SW when the following types of rx data are received:
+ *    + IPv4 IGMP frames
+ *      The control SW can use these to learn about multicast group
+ *      membership, if it so chooses.
+ *
+ * @param pdev - handle to the ctrl SW's physical device object
+ * @param vdev_id - ID of the virtual device received the special data
+ * @param peer_mac_addr - MAC address of the peer that sent the special data
+ * @param tid - which TID within the peer sent the special data
+ * @param tsf32  - the timstamp in TSF units of the special data
+ * @param notify_type - what kind of special data was received
+ * @param rx_frame - the rx frame containing the special data
+ */
+void
+ol_rx_notify(struct cdp_cfg *cfg_pdev,
+	     uint8_t vdev_id,
+	     uint8_t *peer_mac_addr,
+	     int tid,
+	     uint32_t tsf32,
+	     enum ol_rx_notify_type notify_type, qdf_nbuf_t rx_frame);
+
+#define ol_ctrl_addba_req(pdev, peer_mac_addr, tid) ol_addba_req_reject
+#define ol_ctrl_rx_addba_complete(pdev, peer_mac_addr, tid, failed) /* no-op */
+
+#endif /* _OL_CTRL_TXRX_API__H_ */
diff --git a/core/dp/txrx/ol_osif_txrx_api.h b/core/dp/txrx/ol_osif_txrx_api.h
new file mode 100644
index 0000000..ca40d9c
--- /dev/null
+++ b/core/dp/txrx/ol_osif_txrx_api.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 2014-2016 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.
+ */
+
+/**
+ * @file ol_osif_txrx_api.h
+ * @brief Define the OS specific API functions called by txrx SW.
+ */
+#ifndef _OL_OSIF_TXRX_API_H_
+#define _OL_OSIF_TXRX_API_H_
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+
+/**
+ * @brief Call tx completion handler to release the buffers
+ * @details
+ *
+ * Invoke tx completion handler when the tx credit goes below low water mark.
+ * This eliminate the packet drop in the host driver due to send routine not
+ * yielding the cpu when the amount of traffic pumped from the network layer
+ * is very high.
+ *
+ * @param osdev
+ */
+
+void ol_osif_ath_tasklet(qdf_device_t osdev);
+
+#endif /* _OL_OSIF_TXRX_API_H_ */
diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c
new file mode 100644
index 0000000..f2956ba
--- /dev/null
+++ b/core/dp/txrx/ol_rx.c
@@ -0,0 +1,1876 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#include <qdf_nbuf.h>               /* qdf_nbuf_t, etc. */
+#include <qdf_util.h>               /* qdf_cpu_to_le64 */
+#include <qdf_types.h>              /* bool */
+#include <cds_ieee80211_common.h>   /* ieee80211_frame */
+
+/* external API header files */
+#include <ol_ctrl_txrx_api.h>   /* ol_rx_notify */
+#include <ol_txrx_api.h>        /* ol_txrx_pdev_handle */
+#include <ol_txrx_htt_api.h>    /* ol_rx_indication_handler */
+#include <ol_htt_rx_api.h>      /* htt_rx_peer_id, etc. */
+
+/* internal API header files */
+#include <ol_txrx_peer_find.h>  /* ol_txrx_peer_find_by_id */
+#include <ol_rx_reorder.h>      /* ol_rx_reorder_store, etc. */
+#include <ol_rx_reorder_timeout.h>      /* OL_RX_REORDER_TIMEOUT_UPDATE */
+#include <ol_rx_defrag.h>       /* ol_rx_defrag_waitlist_flush */
+#include <ol_txrx_internal.h>
+#include <wdi_event.h>
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+#include <ol_txrx_encap.h>      /* ol_rx_decap_info_t, etc */
+#endif
+#include <ol_rx.h>
+
+/* FIX THIS: txrx should not include private header files of other modules */
+#include <htt_types.h>
+#include <ol_if_athvar.h>
+#include <enet.h>               /* ethernet + SNAP/LLC header defs and
+				 * ethertype values
+				 */
+#include <ip_prot.h>            /* IP protocol values */
+#include <ipv4.h>               /* IPv4 header defs */
+#include <ipv6_defs.h>          /* IPv6 header defs */
+#include <ol_vowext_dbg_defs.h>
+#include <wma.h>
+#include <wlan_policy_mgr_api.h>
+#include "pktlog_ac_fmt.h"
+#include <cdp_txrx_handle.h>
+#include <pld_common.h>
+
+#ifndef OL_RX_INDICATION_MAX_RECORDS
+#define OL_RX_INDICATION_MAX_RECORDS 2048
+#endif
+
+/**
+ * enum ol_rx_ind_record_type - OL rx indication events
+ * @OL_RX_INDICATION_POP_START: event recorded before netbuf pop
+ * @OL_RX_INDICATION_POP_END: event recorded after netbuf pop
+ * @OL_RX_INDICATION_BUF_REPLENISH: event recorded after buffer replenishment
+ */
+enum ol_rx_ind_record_type {
+	OL_RX_INDICATION_POP_START,
+	OL_RX_INDICATION_POP_END,
+	OL_RX_INDICATION_BUF_REPLENISH,
+};
+
+/**
+ * struct ol_rx_ind_record - structure for detailing ol txrx rx ind. event
+ * @value: info corresponding to rx indication event
+ * @type: what the event was
+ * @time: when it happened
+ */
+struct ol_rx_ind_record {
+	uint16_t value;
+	enum ol_rx_ind_record_type type;
+	uint64_t time;
+};
+
+#ifdef OL_RX_INDICATION_RECORD
+static uint32_t ol_rx_ind_record_index;
+static struct ol_rx_ind_record
+	      ol_rx_indication_record_history[OL_RX_INDICATION_MAX_RECORDS];
+
+/**
+ * ol_rx_ind_record_event() - record ol rx indication events
+ * @value: contains rx ind. event related info
+ * @type: ol rx indication message type
+ *
+ * This API record the ol rx indiation event in a rx indication
+ * record buffer.
+ *
+ * Return: None
+ */
+static void ol_rx_ind_record_event(uint32_t value,
+				    enum ol_rx_ind_record_type type)
+{
+	ol_rx_indication_record_history[ol_rx_ind_record_index].value = value;
+	ol_rx_indication_record_history[ol_rx_ind_record_index].type = type;
+	ol_rx_indication_record_history[ol_rx_ind_record_index].time =
+							qdf_get_log_timestamp();
+
+	ol_rx_ind_record_index++;
+	if (ol_rx_ind_record_index >= OL_RX_INDICATION_MAX_RECORDS)
+		ol_rx_ind_record_index = 0;
+}
+#else
+static inline
+void ol_rx_ind_record_event(uint32_t value, enum ol_rx_ind_record_type type)
+{
+}
+
+#endif /* OL_RX_INDICATION_RECORD */
+
+void ol_rx_data_process(struct ol_txrx_peer_t *peer,
+			qdf_nbuf_t rx_buf_list);
+
+#ifdef WDI_EVENT_ENABLE
+/**
+ * ol_rx_send_pktlog_event() - send rx packetlog event
+ * @pdev: pdev handle
+ * @peer: peer handle
+ * @msdu: skb list
+ * @pktlog_bit: packetlog bit from firmware
+ *
+ * Return: none
+ */
+#ifdef HELIUMPLUS
+void ol_rx_send_pktlog_event(struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_peer_t *peer, qdf_nbuf_t msdu, uint8_t pktlog_bit)
+{
+	struct ol_rx_remote_data data;
+
+	/**
+	 * pktlog is meant to log rx_desc information which is
+	 * already overwritten by radio header when monitor mode is ON.
+	 * Therefore, Do not log pktlog event when monitor mode is ON.
+	 */
+	if (!pktlog_bit || (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE))
+		return;
+
+	data.msdu = msdu;
+	if (peer)
+		data.mac_id = peer->vdev->mac_id;
+	else
+		data.mac_id = 0;
+
+	wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE, (struct cdp_pdev *)pdev,
+			  &data);
+}
+#else
+void ol_rx_send_pktlog_event(struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_peer_t *peer, qdf_nbuf_t msdu, uint8_t pktlog_bit)
+{
+	struct ol_rx_remote_data data;
+
+	/**
+	 * pktlog is meant to log rx_desc information which is
+	 * already overwritten by radio header when monitor mode is ON.
+	 * Therefore, Do not log pktlog event when monitor mode is ON.
+	 */
+	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
+		return;
+
+	data.msdu = msdu;
+	if (peer)
+		data.mac_id = peer->vdev->mac_id;
+	else
+		data.mac_id = 0;
+
+	wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE, (struct cdp_pdev *)pdev,
+			  &data);
+}
+#endif
+#endif /* WDI_EVENT_ENABLE */
+
+#ifdef HTT_RX_RESTORE
+
+static void ol_rx_restore_handler(struct work_struct *htt_rx)
+{
+	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		  "Enter: %s", __func__);
+	pld_device_self_recovery(qdf_ctx->dev);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		  "Exit: %s", __func__);
+}
+
+static DECLARE_WORK(ol_rx_restore_work, ol_rx_restore_handler);
+
+void ol_rx_trigger_restore(htt_pdev_handle htt_pdev, qdf_nbuf_t head_msdu,
+			   qdf_nbuf_t tail_msdu)
+{
+	qdf_nbuf_t next;
+
+	while (head_msdu) {
+		next = qdf_nbuf_next(head_msdu);
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+			  "freeing %pK\n", head_msdu);
+		qdf_nbuf_free(head_msdu);
+		head_msdu = next;
+	}
+
+	if (!htt_pdev->rx_ring.htt_rx_restore) {
+		cds_set_recovery_in_progress(true);
+		htt_pdev->rx_ring.htt_rx_restore = 1;
+		schedule_work(&ol_rx_restore_work);
+	}
+}
+#endif
+
+/**
+ * ol_rx_update_histogram_stats() - update rx histogram statistics
+ * @msdu_count: msdu count
+ * @frag_ind: fragment indication set
+ * @offload_ind: offload indication set
+ *
+ * Return: none
+ */
+void ol_rx_update_histogram_stats(uint32_t msdu_count, uint8_t frag_ind,
+		 uint8_t offload_ind)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		ol_txrx_err("%s pdev is NULL\n", __func__);
+		return;
+	}
+
+	if (msdu_count > 60) {
+		TXRX_STATS_ADD(pdev, pub.rx.rx_ind_histogram.pkts_61_plus, 1);
+	} else if (msdu_count > 50) {
+		TXRX_STATS_ADD(pdev, pub.rx.rx_ind_histogram.pkts_51_60, 1);
+	} else if (msdu_count > 40) {
+		TXRX_STATS_ADD(pdev, pub.rx.rx_ind_histogram.pkts_41_50, 1);
+	} else if (msdu_count > 30) {
+		TXRX_STATS_ADD(pdev, pub.rx.rx_ind_histogram.pkts_31_40, 1);
+	} else if (msdu_count > 20) {
+		TXRX_STATS_ADD(pdev, pub.rx.rx_ind_histogram.pkts_21_30, 1);
+	} else if (msdu_count > 10) {
+		TXRX_STATS_ADD(pdev, pub.rx.rx_ind_histogram.pkts_11_20, 1);
+	} else if (msdu_count > 1) {
+		TXRX_STATS_ADD(pdev, pub.rx.rx_ind_histogram.pkts_2_10, 1);
+	} else if (msdu_count == 1) {
+		TXRX_STATS_ADD(pdev, pub.rx.rx_ind_histogram.pkts_1, 1);
+	}
+
+	if (frag_ind)
+		TXRX_STATS_ADD(pdev, pub.rx.msdus_with_frag_ind, msdu_count);
+
+	if (offload_ind)
+		TXRX_STATS_ADD(pdev, pub.rx.msdus_with_offload_ind, msdu_count);
+
+}
+
+#ifdef WLAN_PARTIAL_REORDER_OFFLOAD
+
+#ifdef WDI_EVENT_ENABLE
+static void ol_rx_process_inv_peer(ol_txrx_pdev_handle pdev,
+				   void *rx_mpdu_desc, qdf_nbuf_t msdu)
+{
+	uint8_t a1[IEEE80211_ADDR_LEN];
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+	struct ol_txrx_vdev_t *vdev = NULL;
+	struct ieee80211_frame *wh;
+	struct wdi_event_rx_peer_invalid_msg msg;
+
+	wh = (struct ieee80211_frame *)
+	     htt_rx_mpdu_wifi_hdr_retrieve(htt_pdev, rx_mpdu_desc);
+	/*
+	 * Klocwork issue #6152
+	 *  All targets that send a "INVALID_PEER" rx status provide a
+	 *  802.11 header for each rx MPDU, so it is certain that
+	 *  htt_rx_mpdu_wifi_hdr_retrieve will succeed.
+	 *  However, both for robustness, e.g. if this function is given a
+	 *  MSDU descriptor rather than a MPDU descriptor, and to make it
+	 *  clear to static analysis that this code is safe, add an explicit
+	 *  check that htt_rx_mpdu_wifi_hdr_retrieve provides a non-NULL value.
+	 */
+	if (wh == NULL || !IEEE80211_IS_DATA(wh))
+		return;
+
+	/* ignore frames for non-existent bssids */
+	qdf_mem_copy(a1, wh->i_addr1, IEEE80211_ADDR_LEN);
+	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+		if (qdf_mem_cmp(a1, vdev->mac_addr.raw, IEEE80211_ADDR_LEN))
+			break;
+	}
+	if (!vdev)
+		return;
+
+	msg.wh = wh;
+	msg.msdu = msdu;
+	msg.vdev_id = vdev->vdev_id;
+	wdi_event_handler(WDI_EVENT_RX_PEER_INVALID, (struct cdp_pdev *)pdev,
+			  &msg);
+}
+#else
+static inline
+void ol_rx_process_inv_peer(ol_txrx_pdev_handle pdev,
+			    void *rx_mpdu_desc, qdf_nbuf_t msdu)
+{
+}
+#endif
+
+#ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI
+static inline int16_t
+ol_rx_rssi_avg(struct ol_txrx_pdev_t *pdev, int16_t rssi_old, int16_t rssi_new)
+{
+	int rssi_old_weight;
+
+	if (rssi_new == HTT_RSSI_INVALID)
+		return rssi_old;
+	if (rssi_old == HTT_RSSI_INVALID)
+		return rssi_new;
+
+	rssi_old_weight =
+		(1 << pdev->rssi_update_shift) - pdev->rssi_new_weight;
+	return (rssi_new * pdev->rssi_new_weight +
+		rssi_old * rssi_old_weight) >> pdev->rssi_update_shift;
+}
+
+static void
+ol_rx_ind_rssi_update(struct ol_txrx_peer_t *peer, qdf_nbuf_t rx_ind_msg)
+{
+	struct ol_txrx_pdev_t *pdev = peer->vdev->pdev;
+
+	peer->rssi_dbm = ol_rx_rssi_avg(pdev, peer->rssi_dbm,
+					htt_rx_ind_rssi_dbm(pdev->htt_pdev,
+							    rx_ind_msg));
+}
+
+static void
+ol_rx_mpdu_rssi_update(struct ol_txrx_peer_t *peer, void *rx_mpdu_desc)
+{
+	struct ol_txrx_pdev_t *pdev = peer->vdev->pdev;
+
+	if (!peer)
+		return;
+	peer->rssi_dbm = ol_rx_rssi_avg(pdev, peer->rssi_dbm,
+					htt_rx_mpdu_desc_rssi_dbm(
+						pdev->htt_pdev,
+						rx_mpdu_desc));
+}
+
+#else
+#define ol_rx_ind_rssi_update(peer, rx_ind_msg) /* no-op */
+#define ol_rx_mpdu_rssi_update(peer, rx_mpdu_desc)      /* no-op */
+#endif /* QCA_SUPPORT_PEER_DATA_RX_RSSI */
+
+static void discard_msdus(htt_pdev_handle htt_pdev,
+			  qdf_nbuf_t head_msdu,
+			  qdf_nbuf_t tail_msdu)
+{
+	while (1) {
+		qdf_nbuf_t next;
+
+		next = qdf_nbuf_next(
+			head_msdu);
+		htt_rx_desc_frame_free
+			(htt_pdev,
+			 head_msdu);
+		if (head_msdu ==
+		    tail_msdu) {
+			break;
+		}
+		head_msdu = next;
+	}
+}
+
+static void chain_msdus(htt_pdev_handle htt_pdev,
+			qdf_nbuf_t head_msdu,
+			qdf_nbuf_t tail_msdu)
+{
+	while (1) {
+		qdf_nbuf_t next;
+
+		next = qdf_nbuf_next(head_msdu);
+		htt_rx_desc_frame_free(
+			htt_pdev,
+			head_msdu);
+		if (head_msdu == tail_msdu)
+			break;
+		head_msdu = next;
+	}
+}
+
+static void process_reorder(ol_txrx_pdev_handle pdev,
+			    void *rx_mpdu_desc,
+			    uint8_t tid,
+			    struct ol_txrx_peer_t *peer,
+			    qdf_nbuf_t head_msdu,
+			    qdf_nbuf_t tail_msdu,
+			    int num_mpdu_ranges,
+			    int num_mpdus,
+			    bool rx_ind_release)
+{
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+	enum htt_rx_status mpdu_status;
+	int reorder_idx;
+
+	reorder_idx = htt_rx_mpdu_desc_reorder_idx(htt_pdev, rx_mpdu_desc);
+	OL_RX_REORDER_TRACE_ADD(pdev, tid,
+				reorder_idx,
+				htt_rx_mpdu_desc_seq_num(htt_pdev,
+							 rx_mpdu_desc),
+				1);
+	ol_rx_mpdu_rssi_update(peer, rx_mpdu_desc);
+	/*
+	 * In most cases, out-of-bounds and duplicate sequence number detection
+	 * is performed by the target, but in some cases it is done by the host.
+	 * Specifically, the host does rx out-of-bounds sequence number
+	 * detection for:
+	 * 1.  Peregrine or Rome target
+	 *     for peer-TIDs that do not have aggregation enabled, if the
+	 *     RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK flag
+	 *     is set during the driver build.
+	 * 2.  Riva-family targets, which have rx reorder timeouts handled by
+	 *     the host rather than the target.
+	 *     (The target already does duplicate detection, but the host
+	 *     may have given up waiting for a particular sequence number before
+	 *     it arrives.  In this case, the out-of-bounds sequence number
+	 *     of the late frame allows the host to discard it, rather than
+	 *     sending it out of order.
+	 */
+	mpdu_status = OL_RX_SEQ_NUM_CHECK(pdev,
+						  peer,
+						  tid,
+						  rx_mpdu_desc);
+	if (mpdu_status != htt_rx_status_ok) {
+		/*
+		 * If the sequence number was out of bounds, the MPDU needs
+		 * to be discarded.
+		 */
+		discard_msdus(htt_pdev, head_msdu, tail_msdu);
+		/*
+		 * For Peregrine and Rome,
+		 * OL_RX_REORDER_SEQ_NUM_CHECK should only fail for the case
+		 * of (duplicate) non-aggregates.
+		 *
+		 * For Riva, Pronto and Northstar,
+		 * there should be only one MPDU delivered at a time.
+		 * Thus, there are no further MPDUs that need to be
+		 * processed here.
+		 * Just to be sure this is true, check the assumption
+		 * that this was the only MPDU referenced by the rx
+		 * indication.
+		 */
+		TXRX_ASSERT2((num_mpdu_ranges == 1) && num_mpdus == 1);
+
+		/*
+		 * The MPDU was not stored in the rx reorder array, so
+		 * there's nothing to release.
+		 */
+		rx_ind_release = false;
+	} else {
+		ol_rx_reorder_store(pdev, peer, tid,
+				    reorder_idx, head_msdu, tail_msdu);
+		if (peer->tids_rx_reorder[tid].win_sz_mask == 0) {
+			peer->tids_last_seq[tid] = htt_rx_mpdu_desc_seq_num(
+				htt_pdev,
+				rx_mpdu_desc);
+		}
+	}
+} /* process_reorder */
+
+#ifdef WLAN_FEATURE_DSRC
+static void
+ol_rx_ocb_update_peer(ol_txrx_pdev_handle pdev, qdf_nbuf_t rx_ind_msg,
+		      struct ol_txrx_peer_t *peer)
+{
+	int i;
+
+	htt_rx_ind_legacy_rate(pdev->htt_pdev, rx_ind_msg,
+			       &peer->last_pkt_legacy_rate,
+			       &peer->last_pkt_legacy_rate_sel);
+	peer->last_pkt_rssi_cmb = htt_rx_ind_rssi_dbm(
+				pdev->htt_pdev, rx_ind_msg);
+	for (i = 0; i < 4; i++)
+		peer->last_pkt_rssi[i] =
+		    htt_rx_ind_rssi_dbm_chain(pdev->htt_pdev, rx_ind_msg, i);
+
+	htt_rx_ind_timestamp(pdev->htt_pdev, rx_ind_msg,
+			     &peer->last_pkt_timestamp_microsec,
+			     &peer->last_pkt_timestamp_submicrosec);
+	peer->last_pkt_tsf = htt_rx_ind_tsf32(pdev->htt_pdev, rx_ind_msg);
+	peer->last_pkt_tid = htt_rx_ind_ext_tid(pdev->htt_pdev, rx_ind_msg);
+}
+#else
+static void
+ol_rx_ocb_update_peer(ol_txrx_pdev_handle pdev, qdf_nbuf_t rx_ind_msg,
+		      struct ol_txrx_peer_t *peer)
+{
+}
+#endif
+
+void
+ol_rx_indication_handler(ol_txrx_pdev_handle pdev,
+			 qdf_nbuf_t rx_ind_msg,
+			 uint16_t peer_id, uint8_t tid, int num_mpdu_ranges)
+{
+	int mpdu_range;
+	unsigned int seq_num_start = 0, seq_num_end = 0;
+	bool rx_ind_release = false;
+	struct ol_txrx_vdev_t *vdev = NULL;
+	struct ol_txrx_peer_t *peer;
+	htt_pdev_handle htt_pdev;
+	uint16_t center_freq;
+	uint16_t chan1;
+	uint16_t chan2;
+	uint8_t phymode;
+	bool ret;
+	uint32_t msdu_count = 0;
+
+	htt_pdev = pdev->htt_pdev;
+	peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+	if (!peer) {
+		/*
+		 * If we can't find a peer send this packet to OCB interface
+		 * using OCB self peer
+		 */
+		if (!ol_txrx_get_ocb_peer(pdev, &peer))
+			peer = NULL;
+	}
+
+	if (peer) {
+		vdev = peer->vdev;
+		ol_rx_ind_rssi_update(peer, rx_ind_msg);
+
+		if (vdev->opmode == wlan_op_mode_ocb)
+			ol_rx_ocb_update_peer(pdev, rx_ind_msg, peer);
+	}
+
+	TXRX_STATS_INCR(pdev, priv.rx.normal.ppdus);
+
+	OL_RX_REORDER_TIMEOUT_MUTEX_LOCK(pdev);
+
+	if (htt_rx_ind_flush(pdev->htt_pdev, rx_ind_msg) && peer) {
+		htt_rx_ind_flush_seq_num_range(pdev->htt_pdev, rx_ind_msg,
+					       &seq_num_start, &seq_num_end);
+		if (tid == HTT_INVALID_TID) {
+			/*
+			 * host/FW reorder state went out-of sync
+			 * for a while because FW ran out of Rx indication
+			 * buffer. We have to discard all the buffers in
+			 * reorder queue.
+			 */
+			ol_rx_reorder_peer_cleanup(vdev, peer);
+		} else {
+			if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+				ol_txrx_err("%s:  invalid tid, %u\n",
+					    __func__, tid);
+				WARN_ON(1);
+				return;
+			}
+			ol_rx_reorder_flush(vdev, peer, tid, seq_num_start,
+					    seq_num_end, htt_rx_flush_release);
+		}
+	}
+
+	if (htt_rx_ind_release(pdev->htt_pdev, rx_ind_msg)) {
+		/*
+		 * The ind info of release is saved here and do release at the
+		 * end. This is for the reason of in HL case, the qdf_nbuf_t
+		 * for msg and payload are the same buf. And the buf will be
+		 * changed during processing
+		 */
+		rx_ind_release = true;
+		htt_rx_ind_release_seq_num_range(pdev->htt_pdev, rx_ind_msg,
+						 &seq_num_start, &seq_num_end);
+	}
+#ifdef DEBUG_DMA_DONE
+	pdev->htt_pdev->rx_ring.dbg_initial_msdu_payld =
+		pdev->htt_pdev->rx_ring.sw_rd_idx.msdu_payld;
+#endif
+
+	for (mpdu_range = 0; mpdu_range < num_mpdu_ranges; mpdu_range++) {
+		enum htt_rx_status status;
+		int i, num_mpdus;
+		qdf_nbuf_t head_msdu, tail_msdu, msdu;
+		void *rx_mpdu_desc;
+
+#ifdef DEBUG_DMA_DONE
+		pdev->htt_pdev->rx_ring.dbg_mpdu_range = mpdu_range;
+#endif
+
+		htt_rx_ind_mpdu_range_info(pdev->htt_pdev, rx_ind_msg,
+					   mpdu_range, &status, &num_mpdus);
+		if ((status == htt_rx_status_ok) && peer) {
+			TXRX_STATS_ADD(pdev, priv.rx.normal.mpdus, num_mpdus);
+			/* valid frame - deposit it into rx reordering buffer */
+			for (i = 0; i < num_mpdus; i++) {
+				int msdu_chaining;
+				/*
+				 * Get a linked list of the MSDUs that comprise
+				 * this MPDU.
+				 * This also attaches each rx MSDU descriptor to
+				 * the corresponding rx MSDU network buffer.
+				 * (In some systems, the rx MSDU desc is already
+				 * in the same buffer as the MSDU payload; in
+				 * other systems they are separate, so a pointer
+				 * needs to be set in the netbuf to locate the
+				 * corresponding rx descriptor.)
+				 *
+				 * It is necessary to call htt_rx_amsdu_pop
+				 * before htt_rx_mpdu_desc_list_next, because
+				 * the (MPDU) rx descriptor has DMA unmapping
+				 * done during the htt_rx_amsdu_pop call.
+				 * The rx desc should not be accessed until this
+				 * DMA unmapping has been done, since the DMA
+				 * unmapping involves making sure the cache area
+				 * for the mapped buffer is flushed, so the data
+				 * written by the MAC DMA into memory will be
+				 * fetched, rather than garbage from the cache.
+				 */
+
+#ifdef DEBUG_DMA_DONE
+				pdev->htt_pdev->rx_ring.dbg_mpdu_count = i;
+#endif
+
+				msdu_chaining =
+					htt_rx_amsdu_pop(htt_pdev,
+							 rx_ind_msg,
+							 &head_msdu,
+							 &tail_msdu,
+							 &msdu_count);
+#ifdef HTT_RX_RESTORE
+				if (htt_pdev->rx_ring.rx_reset) {
+					ol_rx_trigger_restore(htt_pdev,
+							      head_msdu,
+							      tail_msdu);
+					OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(
+									pdev);
+					return;
+				}
+#endif
+				rx_mpdu_desc =
+					htt_rx_mpdu_desc_list_next(htt_pdev,
+								   rx_ind_msg);
+				ret = htt_rx_msdu_center_freq(htt_pdev, peer,
+					rx_mpdu_desc, &center_freq, &chan1,
+					&chan2, &phymode);
+				if (ret == true) {
+					peer->last_pkt_center_freq =
+						center_freq;
+				} else {
+					peer->last_pkt_center_freq = 0;
+				}
+
+				/* Pktlog */
+				ol_rx_send_pktlog_event(pdev, peer,
+							head_msdu, 1);
+
+				if (msdu_chaining) {
+					/*
+					 * TBDXXX - to deliver SDU with
+					 * chaining, we need to stitch those
+					 * scattered buffers into one single
+					 * buffer.
+					 * Just discard it now.
+					 */
+					chain_msdus(htt_pdev,
+						    head_msdu,
+						    tail_msdu);
+				} else {
+					process_reorder(pdev, rx_mpdu_desc,
+							tid, peer,
+							head_msdu, tail_msdu,
+							num_mpdu_ranges,
+							num_mpdus,
+							rx_ind_release);
+				}
+
+			}
+		} else {
+			/* invalid frames - discard them */
+			OL_RX_REORDER_TRACE_ADD(pdev, tid,
+						TXRX_SEQ_NUM_ERR(status),
+						TXRX_SEQ_NUM_ERR(status),
+						num_mpdus);
+			TXRX_STATS_ADD(pdev, priv.rx.err.mpdu_bad, num_mpdus);
+			for (i = 0; i < num_mpdus; i++) {
+				/* pull the MPDU's MSDUs off the buffer queue */
+				htt_rx_amsdu_pop(htt_pdev, rx_ind_msg, &msdu,
+						 &tail_msdu, &msdu_count);
+#ifdef HTT_RX_RESTORE
+				if (htt_pdev->rx_ring.rx_reset) {
+					ol_rx_trigger_restore(htt_pdev, msdu,
+							      tail_msdu);
+					OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(
+									pdev);
+					return;
+				}
+#endif
+				/* pull the MPDU desc off the desc queue */
+				rx_mpdu_desc =
+					htt_rx_mpdu_desc_list_next(htt_pdev,
+								   rx_ind_msg);
+				OL_RX_ERR_STATISTICS_2(pdev, vdev, peer,
+						       rx_mpdu_desc, msdu,
+						       status);
+
+				if (status == htt_rx_status_tkip_mic_err &&
+				    vdev != NULL && peer != NULL) {
+					union htt_rx_pn_t pn;
+					uint8_t key_id;
+
+					htt_rx_mpdu_desc_pn(
+						pdev->htt_pdev,
+						htt_rx_msdu_desc_retrieve(
+							pdev->htt_pdev,
+							msdu), &pn, 48);
+					if (htt_rx_msdu_desc_key_id(
+						    pdev->htt_pdev,
+						    htt_rx_msdu_desc_retrieve(
+							    pdev->htt_pdev,
+							    msdu),
+						    &key_id) == true) {
+						ol_rx_err(pdev->ctrl_pdev,
+							  vdev->vdev_id,
+							  peer->mac_addr.raw,
+							  tid, 0,
+							  OL_RX_ERR_TKIP_MIC,
+							  msdu, &pn.pn48,
+							  key_id);
+					}
+				}
+
+				if (status != htt_rx_status_ctrl_mgmt_null) {
+					/* Pktlog */
+					ol_rx_send_pktlog_event(pdev,
+						 peer, msdu, 1);
+				}
+
+				if (status == htt_rx_status_err_inv_peer) {
+					/* once per mpdu */
+					ol_rx_process_inv_peer(pdev,
+							       rx_mpdu_desc,
+							       msdu);
+				}
+
+				while (1) {
+					/* Free the nbuf */
+					qdf_nbuf_t next;
+
+					next = qdf_nbuf_next(msdu);
+					htt_rx_desc_frame_free(htt_pdev, msdu);
+					if (msdu == tail_msdu)
+						break;
+					msdu = next;
+				}
+			}
+		}
+	}
+	/*
+	 * Now that a whole batch of MSDUs have been pulled out of HTT
+	 * and put into the rx reorder array, it is an appropriate time
+	 * to request HTT to provide new rx MSDU buffers for the target
+	 * to fill.
+	 * This could be done after the end of this function, but it's
+	 * better to do it now, rather than waiting until after the driver
+	 * and OS finish processing the batch of rx MSDUs.
+	 */
+	htt_rx_msdu_buff_replenish(htt_pdev);
+
+	if ((true == rx_ind_release) && peer && vdev) {
+		ol_rx_reorder_release(vdev, peer, tid, seq_num_start,
+				      seq_num_end);
+	}
+	OL_RX_REORDER_TIMEOUT_UPDATE(peer, tid);
+	OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev);
+
+	if (pdev->rx.flags.defrag_timeout_check)
+		ol_rx_defrag_waitlist_flush(pdev);
+}
+#endif
+
+void
+ol_rx_sec_ind_handler(ol_txrx_pdev_handle pdev,
+		      uint16_t peer_id,
+		      enum htt_sec_type sec_type,
+		      int is_unicast, uint32_t *michael_key, uint32_t *rx_pn)
+{
+	struct ol_txrx_peer_t *peer;
+	int sec_index, i;
+
+	peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+	if (!peer) {
+		ol_txrx_err(
+			"Couldn't find peer from ID %d - skipping security inits\n",
+			peer_id);
+		return;
+	}
+	ol_txrx_dbg(
+		"sec spec for peer %pK (%02x:%02x:%02x:%02x:%02x:%02x): %s key of type %d\n",
+		peer,
+		peer->mac_addr.raw[0], peer->mac_addr.raw[1],
+		peer->mac_addr.raw[2], peer->mac_addr.raw[3],
+		peer->mac_addr.raw[4], peer->mac_addr.raw[5],
+		is_unicast ? "ucast" : "mcast", sec_type);
+	sec_index = is_unicast ? txrx_sec_ucast : txrx_sec_mcast;
+	peer->security[sec_index].sec_type = sec_type;
+	/*
+	 * michael key only valid for TKIP
+	 * but for simplicity, copy it anyway
+	 */
+	qdf_mem_copy(&peer->security[sec_index].michael_key[0],
+		     michael_key,
+		     sizeof(peer->security[sec_index].michael_key));
+
+	if (sec_type != htt_sec_type_wapi) {
+		qdf_mem_set(peer->tids_last_pn_valid,
+			    OL_TXRX_NUM_EXT_TIDS, 0x00);
+	} else if (sec_index == txrx_sec_mcast || peer->tids_last_pn_valid[0]) {
+		for (i = 0; i < OL_TXRX_NUM_EXT_TIDS; i++) {
+			/*
+			 * Setting PN valid bit for WAPI sec_type,
+			 * since WAPI PN has to be started with predefined value
+			 */
+			peer->tids_last_pn_valid[i] = 1;
+			qdf_mem_copy((uint8_t *) &peer->tids_last_pn[i],
+				     (uint8_t *) rx_pn,
+				     sizeof(union htt_rx_pn_t));
+			peer->tids_last_pn[i].pn128[1] =
+				qdf_cpu_to_le64(
+					peer->tids_last_pn[i].pn128[1]);
+			peer->tids_last_pn[i].pn128[0] =
+				qdf_cpu_to_le64(
+					peer->tids_last_pn[i].pn128[0]);
+			if (sec_index == txrx_sec_ucast)
+				peer->tids_rekey_flag[i] = 1;
+		}
+	}
+}
+
+#if defined(PERE_IP_HDR_ALIGNMENT_WAR)
+
+#include <cds_ieee80211_common.h>
+
+static void transcap_nwifi_to_8023(qdf_nbuf_t msdu)
+{
+	struct ieee80211_frame *wh;
+	uint32_t hdrsize;
+	struct llc *llchdr;
+	struct ether_header *eth_hdr;
+	uint16_t ether_type = 0;
+	uint8_t a1[IEEE80211_ADDR_LEN];
+	uint8_t a2[IEEE80211_ADDR_LEN];
+	uint8_t a3[IEEE80211_ADDR_LEN];
+	uint8_t fc1;
+
+	wh = (struct ieee80211_frame *)qdf_nbuf_data(msdu);
+	qdf_mem_copy(a1, wh->i_addr1, IEEE80211_ADDR_LEN);
+	qdf_mem_copy(a2, wh->i_addr2, IEEE80211_ADDR_LEN);
+	qdf_mem_copy(a3, wh->i_addr3, IEEE80211_ADDR_LEN);
+	fc1 = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
+	/* Native Wifi header is 80211 non-QoS header */
+	hdrsize = sizeof(struct ieee80211_frame);
+
+	llchdr = (struct llc *)(((uint8_t *) qdf_nbuf_data(msdu)) + hdrsize);
+	ether_type = llchdr->llc_un.type_snap.ether_type;
+
+	/*
+	 * Now move the data pointer to the beginning of the mac header :
+	 * new-header = old-hdr + (wifhdrsize + llchdrsize - ethhdrsize)
+	 */
+	qdf_nbuf_pull_head(msdu,
+			   (hdrsize + sizeof(struct llc) -
+			    sizeof(struct ether_header)));
+	eth_hdr = (struct ether_header *)(qdf_nbuf_data(msdu));
+	switch (fc1) {
+	case IEEE80211_FC1_DIR_NODS:
+		qdf_mem_copy(eth_hdr->ether_dhost, a1, IEEE80211_ADDR_LEN);
+		qdf_mem_copy(eth_hdr->ether_shost, a2, IEEE80211_ADDR_LEN);
+		break;
+	case IEEE80211_FC1_DIR_TODS:
+		qdf_mem_copy(eth_hdr->ether_dhost, a3, IEEE80211_ADDR_LEN);
+		qdf_mem_copy(eth_hdr->ether_shost, a2, IEEE80211_ADDR_LEN);
+		break;
+	case IEEE80211_FC1_DIR_FROMDS:
+		qdf_mem_copy(eth_hdr->ether_dhost, a1, IEEE80211_ADDR_LEN);
+		qdf_mem_copy(eth_hdr->ether_shost, a3, IEEE80211_ADDR_LEN);
+		break;
+	case IEEE80211_FC1_DIR_DSTODS:
+		break;
+	}
+	eth_hdr->ether_type = ether_type;
+}
+#endif
+
+void ol_rx_notify(struct cdp_cfg *cfg_pdev,
+		  uint8_t vdev_id,
+		  uint8_t *peer_mac_addr,
+		  int tid,
+		  uint32_t tsf32,
+		  enum ol_rx_notify_type notify_type, qdf_nbuf_t rx_frame)
+{
+	/*
+	 * NOTE: This is used in qca_main for AP mode to handle IGMP
+	 * packets specially. Umac has a corresponding handler for this
+	 * not sure if we need to have this for CLD as well.
+	 */
+}
+
+#ifdef WLAN_PARTIAL_REORDER_OFFLOAD
+/**
+ * @brief Look into a rx MSDU to see what kind of special handling it requires
+ * @details
+ *      This function is called when the host rx SW sees that the target
+ *      rx FW has marked a rx MSDU as needing inspection.
+ *      Based on the results of the inspection, the host rx SW will infer
+ *      what special handling to perform on the rx frame.
+ *      Currently, the only type of frames that require special handling
+ *      are IGMP frames.  The rx data-path SW checks if the frame is IGMP
+ *      (it should be, since the target would not have set the inspect flag
+ *      otherwise), and then calls the ol_rx_notify function so the
+ *      control-path SW can perform multicast group membership learning
+ *      by sniffing the IGMP frame.
+ */
+#define SIZEOF_80211_HDR (sizeof(struct ieee80211_frame))
+static void
+ol_rx_inspect(struct ol_txrx_vdev_t *vdev,
+	      struct ol_txrx_peer_t *peer,
+	      unsigned int tid, qdf_nbuf_t msdu, void *rx_desc)
+{
+	ol_txrx_pdev_handle pdev = vdev->pdev;
+	uint8_t *data, *l3_hdr;
+	uint16_t ethertype;
+	int offset;
+
+	data = qdf_nbuf_data(msdu);
+	if (pdev->frame_format == wlan_frm_fmt_native_wifi) {
+		offset = SIZEOF_80211_HDR + LLC_SNAP_HDR_OFFSET_ETHERTYPE;
+		l3_hdr = data + SIZEOF_80211_HDR + LLC_SNAP_HDR_LEN;
+	} else {
+		offset = ETHERNET_ADDR_LEN * 2;
+		l3_hdr = data + ETHERNET_HDR_LEN;
+	}
+	ethertype = (data[offset] << 8) | data[offset + 1];
+	if (ethertype == ETHERTYPE_IPV4) {
+		offset = IPV4_HDR_OFFSET_PROTOCOL;
+		if (l3_hdr[offset] == IP_PROTOCOL_IGMP) {
+			ol_rx_notify(pdev->ctrl_pdev,
+				     vdev->vdev_id,
+				     peer->mac_addr.raw,
+				     tid,
+				     htt_rx_mpdu_desc_tsf32(pdev->htt_pdev,
+							    rx_desc),
+				     OL_RX_NOTIFY_IPV4_IGMP, msdu);
+		}
+	}
+}
+#endif
+
+void
+ol_rx_offload_deliver_ind_handler(ol_txrx_pdev_handle pdev,
+				  qdf_nbuf_t msg, uint16_t msdu_cnt)
+{
+	int vdev_id, peer_id, tid;
+	qdf_nbuf_t head_buf, tail_buf, buf;
+	struct ol_txrx_peer_t *peer;
+	uint8_t fw_desc;
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+
+	if (msdu_cnt > htt_rx_offload_msdu_cnt(htt_pdev)) {
+		ol_txrx_err("%s: invalid msdu_cnt=%u\n",
+			__func__,
+			msdu_cnt);
+
+		if (pdev->cfg.is_high_latency)
+			htt_rx_desc_frame_free(htt_pdev, msg);
+
+		return;
+	}
+
+	while (msdu_cnt) {
+		if (!htt_rx_offload_msdu_pop(htt_pdev, msg, &vdev_id, &peer_id,
+					&tid, &fw_desc, &head_buf, &tail_buf)) {
+			peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+			if (peer) {
+				ol_rx_data_process(peer, head_buf);
+			} else {
+				buf = head_buf;
+				while (1) {
+					qdf_nbuf_t next;
+
+					next = qdf_nbuf_next(buf);
+					htt_rx_desc_frame_free(htt_pdev, buf);
+					if (buf == tail_buf)
+						break;
+					buf = next;
+				}
+			}
+		}
+		msdu_cnt--;
+	}
+	htt_rx_msdu_buff_replenish(htt_pdev);
+}
+
+void
+ol_rx_mic_error_handler(
+	ol_txrx_pdev_handle pdev,
+	u_int8_t tid,
+	u_int16_t peer_id,
+	void *msdu_desc,
+	qdf_nbuf_t msdu)
+{
+	union htt_rx_pn_t pn = {0};
+	u_int8_t key_id = 0;
+
+	struct ol_txrx_peer_t *peer = NULL;
+	struct ol_txrx_vdev_t *vdev = NULL;
+
+	if (pdev) {
+		TXRX_STATS_MSDU_INCR(pdev, rx.dropped_mic_err, msdu);
+		peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+		if (peer) {
+			vdev = peer->vdev;
+			if (vdev) {
+				htt_rx_mpdu_desc_pn(vdev->pdev->htt_pdev,
+						    msdu_desc, &pn, 48);
+
+				if (htt_rx_msdu_desc_key_id(
+					vdev->pdev->htt_pdev, msdu_desc,
+					&key_id) == true) {
+					ol_rx_err(vdev->pdev->ctrl_pdev,
+						  vdev->vdev_id,
+						  peer->mac_addr.raw, tid, 0,
+						  OL_RX_ERR_TKIP_MIC, msdu,
+						  &pn.pn48, key_id);
+				}
+			}
+		}
+		/* Pktlog */
+		ol_rx_send_pktlog_event(pdev, peer, msdu, 1);
+	}
+}
+
+#ifdef WLAN_PARTIAL_REORDER_OFFLOAD
+/**
+ * @brief Check the first msdu to decide whether the a-msdu should be accepted.
+ */
+static bool
+ol_rx_filter(struct ol_txrx_vdev_t *vdev,
+	     struct ol_txrx_peer_t *peer, qdf_nbuf_t msdu, void *rx_desc)
+{
+#define FILTER_STATUS_REJECT 1
+#define FILTER_STATUS_ACCEPT 0
+	uint8_t *wh;
+	uint32_t offset = 0;
+	uint16_t ether_type = 0;
+	bool is_encrypted = false, is_mcast = false;
+	uint8_t i;
+	enum privacy_filter_packet_type packet_type =
+		PRIVACY_FILTER_PACKET_UNICAST;
+	ol_txrx_pdev_handle pdev = vdev->pdev;
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+	int sec_idx;
+
+	/*
+	 * Safemode must avoid the PrivacyExemptionList and
+	 * ExcludeUnencrypted checking
+	 */
+	if (vdev->safemode)
+		return FILTER_STATUS_ACCEPT;
+
+	is_mcast = htt_rx_msdu_is_wlan_mcast(htt_pdev, rx_desc);
+	if (vdev->num_filters > 0) {
+		if (pdev->frame_format == wlan_frm_fmt_native_wifi) {
+			offset = SIZEOF_80211_HDR +
+				LLC_SNAP_HDR_OFFSET_ETHERTYPE;
+		} else {
+			offset = ETHERNET_ADDR_LEN * 2;
+		}
+		/* get header info from msdu */
+		wh = qdf_nbuf_data(msdu);
+
+		/* get ether type */
+		ether_type = (wh[offset] << 8) | wh[offset + 1];
+		/* get packet type */
+		if (true == is_mcast)
+			packet_type = PRIVACY_FILTER_PACKET_MULTICAST;
+		else
+			packet_type = PRIVACY_FILTER_PACKET_UNICAST;
+	}
+	/* get encrypt info */
+	is_encrypted = htt_rx_mpdu_is_encrypted(htt_pdev, rx_desc);
+#ifdef ATH_SUPPORT_WAPI
+	if ((true == is_encrypted) && (ETHERTYPE_WAI == ether_type)) {
+		/*
+		 * We expect the WAI frames to be always unencrypted when
+		 * the UMAC gets it
+		 */
+		return FILTER_STATUS_REJECT;
+	}
+#endif /* ATH_SUPPORT_WAPI */
+
+	for (i = 0; i < vdev->num_filters; i++) {
+		enum privacy_filter filter_type;
+		enum privacy_filter_packet_type filter_packet_type;
+
+		/* skip if the ether type does not match */
+		if (vdev->privacy_filters[i].ether_type != ether_type)
+			continue;
+
+		/* skip if the packet type does not match */
+		filter_packet_type = vdev->privacy_filters[i].packet_type;
+		if (filter_packet_type != packet_type &&
+		    filter_packet_type != PRIVACY_FILTER_PACKET_BOTH) {
+			continue;
+		}
+
+		filter_type = vdev->privacy_filters[i].filter_type;
+		if (filter_type == PRIVACY_FILTER_ALWAYS) {
+			/*
+			 * In this case, we accept the frame if and only if
+			 * it was originally NOT encrypted.
+			 */
+			if (true == is_encrypted)
+				return FILTER_STATUS_REJECT;
+			else
+				return FILTER_STATUS_ACCEPT;
+
+		} else if (filter_type == PRIVACY_FILTER_KEY_UNAVAILABLE) {
+			/*
+			 * In this case, we reject the frame if it was
+			 * originally NOT encrypted but we have the key mapping
+			 * key for this frame.
+			 */
+			if (!is_encrypted &&
+			    !is_mcast &&
+			    (peer->security[txrx_sec_ucast].sec_type !=
+			     htt_sec_type_none) &&
+			    (peer->keyinstalled || !ETHERTYPE_IS_EAPOL_WAPI(
+				    ether_type))) {
+				return FILTER_STATUS_REJECT;
+			} else {
+				return FILTER_STATUS_ACCEPT;
+			}
+		} else {
+			/*
+			 * The privacy exemption does not apply to this frame.
+			 */
+			break;
+		}
+	}
+
+	/*
+	 * If the privacy exemption list does not apply to the frame,
+	 * check ExcludeUnencrypted.
+	 * If ExcludeUnencrypted is not set, or if this was oringially
+	 * an encrypted frame, it will be accepted.
+	 */
+	if (!vdev->drop_unenc || (true == is_encrypted))
+		return FILTER_STATUS_ACCEPT;
+
+	/*
+	 *  If this is a open connection, it will be accepted.
+	 */
+	sec_idx = (true == is_mcast) ? txrx_sec_mcast : txrx_sec_ucast;
+	if (peer->security[sec_idx].sec_type == htt_sec_type_none)
+		return FILTER_STATUS_ACCEPT;
+
+	if ((false == is_encrypted) && vdev->drop_unenc) {
+		OL_RX_ERR_STATISTICS(pdev, vdev, OL_RX_ERR_PRIVACY,
+				     pdev->sec_types[htt_sec_type_none],
+				     is_mcast);
+	}
+	return FILTER_STATUS_REJECT;
+}
+#endif
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+static inline void ol_rx_timestamp(struct cdp_cfg *cfg_pdev,
+				   void *rx_desc, qdf_nbuf_t msdu)
+{
+	struct htt_rx_ppdu_desc_t *rx_ppdu_desc;
+
+	if (!ol_cfg_is_ptp_rx_opt_enabled(cfg_pdev))
+		return;
+
+	if (!rx_desc || !msdu)
+		return;
+
+	rx_ppdu_desc = (struct htt_rx_ppdu_desc_t *)((uint8_t *)(rx_desc) -
+			HTT_RX_IND_HL_BYTES + HTT_RX_IND_HDR_PREFIX_BYTES);
+	msdu->tstamp = ns_to_ktime((u_int64_t)rx_ppdu_desc->tsf32 *
+				   NSEC_PER_USEC);
+}
+#else
+static inline void ol_rx_timestamp(struct cdp_cfg *cfg_pdev,
+				   void *rx_desc, qdf_nbuf_t msdu)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_DSRC
+static inline
+void ol_rx_ocb_prepare_rx_stats_header(struct ol_txrx_vdev_t *vdev,
+				       struct ol_txrx_peer_t *peer,
+				       qdf_nbuf_t msdu)
+{
+	int i;
+	struct ol_txrx_ocb_chan_info *chan_info = 0;
+	int packet_freq = peer->last_pkt_center_freq;
+
+	for (i = 0; i < vdev->ocb_channel_count; i++) {
+		if (vdev->ocb_channel_info[i].chan_freq == packet_freq) {
+			chan_info = &vdev->ocb_channel_info[i];
+			break;
+		}
+	}
+
+	if (!chan_info || !chan_info->disable_rx_stats_hdr) {
+		struct ether_header eth_header = { {0} };
+		struct ocb_rx_stats_hdr_t rx_header = {0};
+
+		/*
+		 * Construct the RX stats header and
+		 * push that to the frontof the packet.
+		 */
+		rx_header.version = 1;
+		rx_header.length = sizeof(rx_header);
+		rx_header.channel_freq = peer->last_pkt_center_freq;
+		rx_header.rssi_cmb = peer->last_pkt_rssi_cmb;
+		qdf_mem_copy(rx_header.rssi, peer->last_pkt_rssi,
+			     sizeof(rx_header.rssi));
+
+		if (peer->last_pkt_legacy_rate_sel)
+			rx_header.datarate = 0xFF;
+		else if (peer->last_pkt_legacy_rate == 0x8)
+			rx_header.datarate = 6;
+		else if (peer->last_pkt_legacy_rate == 0x9)
+			rx_header.datarate = 4;
+		else if (peer->last_pkt_legacy_rate == 0xA)
+			rx_header.datarate = 2;
+		else if (peer->last_pkt_legacy_rate == 0xB)
+			rx_header.datarate = 0;
+		else if (peer->last_pkt_legacy_rate == 0xC)
+			rx_header.datarate = 7;
+		else if (peer->last_pkt_legacy_rate == 0xD)
+			rx_header.datarate = 5;
+		else if (peer->last_pkt_legacy_rate == 0xE)
+			rx_header.datarate = 3;
+		else if (peer->last_pkt_legacy_rate == 0xF)
+			rx_header.datarate = 1;
+		else
+			rx_header.datarate = 0xFF;
+
+		rx_header.timestamp_microsec =
+			 peer->last_pkt_timestamp_microsec;
+		rx_header.timestamp_submicrosec =
+			 peer->last_pkt_timestamp_submicrosec;
+		rx_header.tsf32 = peer->last_pkt_tsf;
+		rx_header.ext_tid = peer->last_pkt_tid;
+
+		qdf_nbuf_push_head(msdu, sizeof(rx_header));
+		qdf_mem_copy(qdf_nbuf_data(msdu),
+			     &rx_header, sizeof(rx_header));
+
+		/*
+		 * Construct the ethernet header with
+		 * type 0x8152 and push that to the
+		 * front of the packet to indicate the
+		 * RX stats header.
+		 */
+		eth_header.ether_type = QDF_SWAP_U16(ETHERTYPE_OCB_RX);
+		qdf_nbuf_push_head(msdu, sizeof(eth_header));
+		qdf_mem_copy(qdf_nbuf_data(msdu), &eth_header,
+			     sizeof(eth_header));
+	}
+}
+#else
+static inline
+void ol_rx_ocb_prepare_rx_stats_header(struct ol_txrx_vdev_t *vdev,
+				       struct ol_txrx_peer_t *peer,
+				       qdf_nbuf_t msdu)
+{
+}
+#endif
+
+#ifdef WLAN_PARTIAL_REORDER_OFFLOAD
+void
+ol_rx_deliver(struct ol_txrx_vdev_t *vdev,
+	      struct ol_txrx_peer_t *peer, unsigned int tid,
+	      qdf_nbuf_t msdu_list)
+{
+	ol_txrx_pdev_handle pdev = vdev->pdev;
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+	qdf_nbuf_t deliver_list_head = NULL;
+	qdf_nbuf_t deliver_list_tail = NULL;
+	qdf_nbuf_t msdu;
+	bool filter = false;
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+	struct ol_rx_decap_info_t info;
+
+	qdf_mem_set(&info, sizeof(info), 0);
+#endif
+
+	msdu = msdu_list;
+	/*
+	 * Check each MSDU to see whether it requires special handling,
+	 * and free each MSDU's rx descriptor
+	 */
+	while (msdu) {
+		void *rx_desc;
+		int discard, inspect, dummy_fwd;
+		qdf_nbuf_t next = qdf_nbuf_next(msdu);
+
+		rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, msdu);
+		/* for HL, point to payload right now*/
+		if (pdev->cfg.is_high_latency) {
+			qdf_nbuf_pull_head(msdu,
+				htt_rx_msdu_rx_desc_size_hl(htt_pdev, rx_desc));
+		}
+
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+		info.is_msdu_cmpl_mpdu =
+			htt_rx_msdu_desc_completes_mpdu(htt_pdev, rx_desc);
+		info.is_first_subfrm =
+			htt_rx_msdu_first_msdu_flag(htt_pdev, rx_desc);
+		if (OL_RX_DECAP(vdev, peer, msdu, &info) != A_OK) {
+			discard = 1;
+			ol_txrx_dbg(
+				"decap error %pK from peer %pK (%02x:%02x:%02x:%02x:%02x:%02x) len %d\n",
+				msdu, peer,
+				peer->mac_addr.raw[0], peer->mac_addr.raw[1],
+				peer->mac_addr.raw[2], peer->mac_addr.raw[3],
+				peer->mac_addr.raw[4], peer->mac_addr.raw[5],
+				qdf_nbuf_len(msdu));
+			goto DONE;
+		}
+#endif
+		htt_rx_msdu_actions(pdev->htt_pdev, rx_desc, &discard,
+				    &dummy_fwd, &inspect);
+		if (inspect)
+			ol_rx_inspect(vdev, peer, tid, msdu, rx_desc);
+
+		/*
+		 * Check the first msdu in the mpdu, if it will be filtered out,
+		 * then discard the entire mpdu.
+		 */
+		if (htt_rx_msdu_first_msdu_flag(htt_pdev, rx_desc))
+			filter = ol_rx_filter(vdev, peer, msdu, rx_desc);
+
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+DONE:
+#endif
+		htt_rx_msdu_desc_free(htt_pdev, msdu);
+		if (discard || (true == filter)) {
+			ol_txrx_frms_dump("rx discarding:",
+					  pdev, deliver_list_head,
+					  ol_txrx_frm_dump_tcp_seq |
+					  ol_txrx_frm_dump_contents,
+					  0 /* don't print contents */);
+			qdf_nbuf_free(msdu);
+			/*
+			 * If discarding packet is last packet of the delivery
+			 * list, NULL terminator should be added
+			 * for delivery list.
+			 */
+			if (next == NULL && deliver_list_head) {
+				/* add NULL terminator */
+				qdf_nbuf_set_next(deliver_list_tail, NULL);
+			}
+		} else {
+			/*
+			 *  If this is for OCB,
+			 *  then prepend the RX stats header.
+			 */
+			if (vdev->opmode == wlan_op_mode_ocb)
+				ol_rx_ocb_prepare_rx_stats_header(vdev, peer,
+								  msdu);
+
+			OL_RX_PEER_STATS_UPDATE(peer, msdu);
+			OL_RX_ERR_STATISTICS_1(pdev, vdev, peer, rx_desc,
+					       OL_RX_ERR_NONE);
+			TXRX_STATS_MSDU_INCR(vdev->pdev, rx.delivered, msdu);
+
+			ol_rx_timestamp(pdev->ctrl_pdev, rx_desc, msdu);
+			OL_TXRX_LIST_APPEND(deliver_list_head,
+					    deliver_list_tail, msdu);
+		}
+		msdu = next;
+	}
+	/* sanity check - are there any frames left to give to the OS shim? */
+	if (!deliver_list_head)
+		return;
+
+#if defined(PERE_IP_HDR_ALIGNMENT_WAR)
+	if (pdev->host_80211_enable)
+		for (msdu = deliver_list_head; msdu; msdu = qdf_nbuf_next(msdu))
+			transcap_nwifi_to_8023(msdu);
+#endif
+
+	ol_txrx_frms_dump("rx delivering:",
+			  pdev, deliver_list_head,
+			  ol_txrx_frm_dump_tcp_seq | ol_txrx_frm_dump_contents,
+			  0 /* don't print contents */);
+
+	ol_rx_data_process(peer, deliver_list_head);
+}
+#endif
+
+void
+ol_rx_discard(struct ol_txrx_vdev_t *vdev,
+	      struct ol_txrx_peer_t *peer, unsigned int tid,
+	      qdf_nbuf_t msdu_list)
+{
+	ol_txrx_pdev_handle pdev = vdev->pdev;
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+
+	while (msdu_list) {
+		qdf_nbuf_t msdu = msdu_list;
+
+		msdu_list = qdf_nbuf_next(msdu_list);
+		ol_txrx_dbg(
+			"discard rx %pK from partly-deleted peer %pK (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+			msdu, peer,
+			peer->mac_addr.raw[0], peer->mac_addr.raw[1],
+			peer->mac_addr.raw[2], peer->mac_addr.raw[3],
+			peer->mac_addr.raw[4], peer->mac_addr.raw[5]);
+		htt_rx_desc_frame_free(htt_pdev, msdu);
+	}
+}
+
+void ol_rx_peer_init(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t *peer)
+{
+	uint8_t tid;
+
+	for (tid = 0; tid < OL_TXRX_NUM_EXT_TIDS; tid++) {
+		ol_rx_reorder_init(&peer->tids_rx_reorder[tid], tid);
+
+		/* invalid sequence number */
+		peer->tids_last_seq[tid] = IEEE80211_SEQ_MAX;
+		/* invalid reorder index number */
+		peer->tids_next_rel_idx[tid] = INVALID_REORDER_INDEX;
+
+	}
+	/*
+	 * Set security defaults: no PN check, no security.
+	 * The target may send a HTT SEC_IND message to overwrite
+	 * these defaults.
+	 */
+	peer->security[txrx_sec_ucast].sec_type =
+		peer->security[txrx_sec_mcast].sec_type = htt_sec_type_none;
+	peer->keyinstalled = 0;
+
+	peer->last_assoc_rcvd = 0;
+	peer->last_disassoc_rcvd = 0;
+	peer->last_deauth_rcvd = 0;
+
+	qdf_atomic_init(&peer->fw_pn_check);
+}
+
+void
+ol_rx_peer_cleanup(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer)
+{
+	peer->keyinstalled = 0;
+	peer->last_assoc_rcvd = 0;
+	peer->last_disassoc_rcvd = 0;
+	peer->last_deauth_rcvd = 0;
+	ol_rx_reorder_peer_cleanup(vdev, peer);
+}
+
+/*
+ * Free frames including both rx descriptors and buffers
+ */
+void ol_rx_frames_free(htt_pdev_handle htt_pdev, qdf_nbuf_t frames)
+{
+	qdf_nbuf_t next, frag = frames;
+
+	while (frag) {
+		next = qdf_nbuf_next(frag);
+		htt_rx_desc_frame_free(htt_pdev, frag);
+		frag = next;
+	}
+}
+
+#ifdef WLAN_FULL_REORDER_OFFLOAD
+void
+ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev,
+				  qdf_nbuf_t rx_ind_msg,
+				  uint16_t peer_id,
+				  uint8_t tid, uint8_t is_offload)
+{
+	struct ol_txrx_vdev_t *vdev = NULL;
+	struct ol_txrx_peer_t *peer = NULL;
+	htt_pdev_handle htt_pdev = NULL;
+	int status;
+	qdf_nbuf_t head_msdu = NULL, tail_msdu = NULL;
+	uint8_t *rx_ind_data;
+	uint32_t *msg_word;
+	uint32_t msdu_count;
+	uint8_t pktlog_bit;
+	uint32_t filled = 0;
+
+	if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+		ol_txrx_err("%s:  invalid tid, %u\n", __FUNCTION__, tid);
+		WARN_ON(1);
+		return;
+	}
+
+	if (pdev) {
+		if (qdf_unlikely(QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()))
+			peer = pdev->self_peer;
+		else
+			peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+		htt_pdev = pdev->htt_pdev;
+	} else {
+		ol_txrx_err("%s: Invalid pdev passed!\n", __func__);
+		qdf_assert_always(pdev);
+		return;
+	}
+
+#if defined(HELIUMPLUS_DEBUG)
+	qdf_print("%s %d: rx_ind_msg 0x%pK peer_id %d tid %d is_offload %d\n",
+		  __func__, __LINE__, rx_ind_msg, peer_id, tid, is_offload);
+#endif
+
+	pktlog_bit = (htt_rx_amsdu_rx_in_order_get_pktlog(rx_ind_msg) == 0x01);
+	rx_ind_data = qdf_nbuf_data(rx_ind_msg);
+	msg_word = (uint32_t *)rx_ind_data;
+	/* Get the total number of MSDUs */
+	msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1));
+
+	ol_rx_ind_record_event(msdu_count, OL_RX_INDICATION_POP_START);
+
+	/*
+	 * Get a linked list of the MSDUs in the rx in order indication.
+	 * This also attaches each rx MSDU descriptor to the
+	 * corresponding rx MSDU network buffer.
+	 */
+	status = htt_rx_amsdu_pop(htt_pdev, rx_ind_msg, &head_msdu,
+				  &tail_msdu, &msdu_count);
+	ol_rx_ind_record_event(status, OL_RX_INDICATION_POP_END);
+
+	if (qdf_unlikely(0 == status)) {
+		ol_txrx_warn("%s: Pop status is 0, returning here", __func__);
+		return;
+	}
+
+	/*
+	 * Replenish the rx buffer ring first to provide buffers to the target
+	 * rather than waiting for the indeterminate time taken by the OS
+	 * to consume the rx frames
+	 */
+	filled = htt_rx_msdu_buff_in_order_replenish(htt_pdev, msdu_count);
+	ol_rx_ind_record_event(filled, OL_RX_INDICATION_BUF_REPLENISH);
+
+	if (!head_msdu) {
+		ol_txrx_dbg("No packet to send to HDD");
+		return;
+	}
+
+	/* Send the chain of MSDUs to the OS */
+	/* rx_opt_proc takes a NULL-terminated list of msdu netbufs */
+	qdf_nbuf_set_next(tail_msdu, NULL);
+
+	/* Pktlog */
+	ol_rx_send_pktlog_event(pdev, peer, head_msdu, pktlog_bit);
+
+	/*
+	 * if this is an offload indication, peer id is carried in the
+	 * rx buffer
+	 */
+	if (peer) {
+		vdev = peer->vdev;
+	} else {
+		ol_txrx_dbg(
+			   "%s: Couldn't find peer from ID 0x%x\n",
+			   __func__, peer_id);
+		while (head_msdu) {
+			qdf_nbuf_t msdu = head_msdu;
+
+			head_msdu = qdf_nbuf_next(head_msdu);
+			TXRX_STATS_MSDU_INCR(pdev,
+				 rx.dropped_peer_invalid, msdu);
+			htt_rx_desc_frame_free(htt_pdev, msdu);
+		}
+		return;
+	}
+
+	peer->rx_opt_proc(vdev, peer, tid, head_msdu);
+}
+#endif
+
+#ifndef REMOVE_PKT_LOG
+/**
+ * ol_rx_pkt_dump_call() - updates status and
+ * calls packetdump callback to log rx packet
+ *
+ * @msdu: rx packet
+ * @peer_id: peer id
+ * @status: status of rx packet
+ *
+ * This function is used to update the status of rx packet
+ * and then calls packetdump callback to log that packet.
+ *
+ * Return: None
+ *
+ */
+void ol_rx_pkt_dump_call(
+	qdf_nbuf_t msdu,
+	uint8_t peer_id,
+	uint8_t status)
+{
+	ol_txrx_pdev_handle pdev;
+	struct ol_txrx_peer_t *peer = NULL;
+	tp_ol_packetdump_cb packetdump_cb;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		ol_txrx_err("%s: pdev is NULL", __func__);
+		return;
+	}
+
+	peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+	if (!peer) {
+		ol_txrx_dbg("%s: peer with peer id %d is NULL", __func__,
+			peer_id);
+		return;
+	}
+
+	packetdump_cb = pdev->ol_rx_packetdump_cb;
+	if (packetdump_cb)
+		packetdump_cb(msdu, status, peer->vdev->vdev_id, RX_DATA_PKT);
+}
+#endif
+
+#ifdef WLAN_FULL_REORDER_OFFLOAD
+/* the msdu_list passed here must be NULL terminated */
+void
+ol_rx_in_order_deliver(struct ol_txrx_vdev_t *vdev,
+		       struct ol_txrx_peer_t *peer,
+		       unsigned int tid, qdf_nbuf_t msdu_list)
+{
+	qdf_nbuf_t msdu;
+
+	msdu = msdu_list;
+	/*
+	 * Currently, this does not check each MSDU to see whether it requires
+	 * special handling. MSDUs that need special handling (example: IGMP
+	 * frames) should be sent via a separate HTT message. Also, this does
+	 * not do rx->tx forwarding or filtering.
+	 */
+
+	while (msdu) {
+		qdf_nbuf_t next = qdf_nbuf_next(msdu);
+
+		DPTRACE(qdf_dp_trace(msdu,
+			QDF_DP_TRACE_RX_TXRX_PACKET_PTR_RECORD,
+			QDF_TRACE_DEFAULT_PDEV_ID,
+			qdf_nbuf_data_addr(msdu),
+			sizeof(qdf_nbuf_data(msdu)), QDF_RX));
+
+		OL_RX_PEER_STATS_UPDATE(peer, msdu);
+		OL_RX_ERR_STATISTICS_1(vdev->pdev, vdev, peer, rx_desc,
+				       OL_RX_ERR_NONE);
+		TXRX_STATS_MSDU_INCR(vdev->pdev, rx.delivered, msdu);
+
+		msdu = next;
+	}
+
+	ol_txrx_frms_dump("rx delivering:",
+			  pdev, deliver_list_head,
+			  ol_txrx_frm_dump_tcp_seq | ol_txrx_frm_dump_contents,
+			  0 /* don't print contents */);
+
+	ol_rx_data_process(peer, msdu_list);
+}
+#endif
+
+#ifndef CONFIG_HL_SUPPORT
+void
+ol_rx_offload_paddr_deliver_ind_handler(htt_pdev_handle htt_pdev,
+					uint32_t msdu_count,
+					uint32_t *msg_word)
+{
+	int vdev_id, peer_id, tid;
+	qdf_nbuf_t head_buf, tail_buf, buf;
+	struct ol_txrx_peer_t *peer;
+	uint8_t fw_desc;
+	int msdu_iter = 0;
+
+	while (msdu_count) {
+		if (htt_rx_offload_paddr_msdu_pop_ll(
+						htt_pdev, msg_word, msdu_iter,
+						 &vdev_id, &peer_id, &tid,
+						 &fw_desc, &head_buf,
+						 &tail_buf)) {
+			msdu_iter++;
+			msdu_count--;
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+				  "skip msg_word %pK, msdu #%d, continue next",
+				  msg_word, msdu_iter);
+			continue;
+		}
+
+		peer = ol_txrx_peer_find_by_id(htt_pdev->txrx_pdev, peer_id);
+		if (peer) {
+			QDF_NBUF_CB_DP_TRACE_PRINT(head_buf) = false;
+			qdf_dp_trace_set_track(head_buf, QDF_RX);
+			QDF_NBUF_CB_TX_PACKET_TRACK(head_buf) =
+						QDF_NBUF_TX_PKT_DATA_TRACK;
+			qdf_dp_trace_log_pkt(peer->vdev->vdev_id,
+				head_buf, QDF_RX,
+				QDF_TRACE_DEFAULT_PDEV_ID);
+			DPTRACE(qdf_dp_trace(head_buf,
+				QDF_DP_TRACE_RX_OFFLOAD_HTT_PACKET_PTR_RECORD,
+				QDF_TRACE_DEFAULT_PDEV_ID,
+				qdf_nbuf_data_addr(head_buf),
+				sizeof(qdf_nbuf_data(head_buf)), QDF_RX));
+			ol_rx_data_process(peer, head_buf);
+		} else {
+			buf = head_buf;
+			while (1) {
+				qdf_nbuf_t next;
+
+				next = qdf_nbuf_next(buf);
+				htt_rx_desc_frame_free(htt_pdev, buf);
+				if (buf == tail_buf)
+					break;
+				buf = next;
+			}
+		}
+		msdu_iter++;
+		msdu_count--;
+	}
+	htt_rx_msdu_buff_replenish(htt_pdev);
+}
+#endif
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+/**
+ * ol_htt_mon_note_chan() - Update monitor channel information
+ * @pdev:  handle to the physical device
+ * @mon_ch: Monitor channel
+ *
+ * Return: None
+ */
+void ol_htt_mon_note_chan(struct cdp_pdev *ppdev, int mon_ch)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	htt_rx_mon_note_capture_channel(pdev->htt_pdev, mon_ch);
+}
+#endif
+
+#ifdef NEVERDEFINED
+/**
+ * @brief populates vow ext stats in given network buffer.
+ * @param msdu - network buffer handle
+ * @param pdev - handle to htt dev.
+ */
+void ol_ath_add_vow_extstats(htt_pdev_handle pdev, qdf_nbuf_t msdu)
+{
+	/* FIX THIS:
+	 * txrx should not be directly using data types (scn)
+	 * that are internal to other modules.
+	 */
+	struct ol_ath_softc_net80211 *scn =
+		(struct ol_ath_softc_net80211 *)pdev->ctrl_pdev;
+	uint8_t *data, *l3_hdr, *bp;
+	uint16_t ethertype;
+	int offset;
+	struct vow_extstats vowstats;
+
+	if (scn->vow_extstats == 0)
+		return;
+
+	data = qdf_nbuf_data(msdu);
+
+	offset = ETHERNET_ADDR_LEN * 2;
+	l3_hdr = data + ETHERNET_HDR_LEN;
+	ethertype = (data[offset] << 8) | data[offset + 1];
+	if (ethertype == ETHERTYPE_IPV4) {
+		offset = IPV4_HDR_OFFSET_PROTOCOL;
+		if ((l3_hdr[offset] == IP_PROTOCOL_UDP) &&
+				(l3_hdr[0] == IP_VER4_N_NO_EXTRA_HEADERS)) {
+			bp = data + EXT_HDR_OFFSET;
+
+			if ((data[RTP_HDR_OFFSET] == UDP_PDU_RTP_EXT) &&
+					(bp[0] == 0x12) &&
+					(bp[1] == 0x34) &&
+					(bp[2] == 0x00) && (bp[3] == 0x08)) {
+				/*
+				 * Clear UDP checksum so we do not have
+				 * to recalculate it
+				 * after filling in status fields.
+				 */
+				data[UDP_CKSUM_OFFSET] = 0;
+				data[(UDP_CKSUM_OFFSET + 1)] = 0;
+
+				bp += IPERF3_DATA_OFFSET;
+
+				htt_rx_get_vowext_stats(msdu,
+						&vowstats);
+
+				/* control channel RSSI */
+				*bp++ = vowstats.rx_rssi_ctl0;
+				*bp++ = vowstats.rx_rssi_ctl1;
+				*bp++ = vowstats.rx_rssi_ctl2;
+
+				/* rx rate info */
+				*bp++ = vowstats.rx_bw;
+				*bp++ = vowstats.rx_sgi;
+				*bp++ = vowstats.rx_nss;
+
+				*bp++ = vowstats.rx_rssi_comb;
+				/* rsflags */
+				*bp++ = vowstats.rx_rs_flags;
+
+				/* Time stamp Lo */
+				*bp++ = (uint8_t)
+					((vowstats.
+					  rx_macTs & 0x0000ff00) >> 8);
+				*bp++ = (uint8_t)
+					(vowstats.rx_macTs & 0x0000ff);
+				/* rx phy errors */
+				*bp++ = (uint8_t)
+					((scn->chan_stats.
+					  phy_err_cnt >> 8) & 0xff);
+				*bp++ =
+					(uint8_t) (scn->chan_stats.
+							phy_err_cnt & 0xff);
+				/* rx clear count */
+				*bp++ = (uint8_t)
+					((scn->mib_cycle_cnts.
+					  rx_clear_count >> 24) & 0xff);
+				*bp++ = (uint8_t)
+					((scn->mib_cycle_cnts.
+					  rx_clear_count >> 16) & 0xff);
+				*bp++ = (uint8_t)
+					((scn->mib_cycle_cnts.
+					  rx_clear_count >> 8) & 0xff);
+				*bp++ = (uint8_t)
+					(scn->mib_cycle_cnts.
+					 rx_clear_count & 0xff);
+				/* rx cycle count */
+				*bp++ = (uint8_t)
+					((scn->mib_cycle_cnts.
+					  cycle_count >> 24) & 0xff);
+				*bp++ = (uint8_t)
+					((scn->mib_cycle_cnts.
+					  cycle_count >> 16) & 0xff);
+				*bp++ = (uint8_t)
+					((scn->mib_cycle_cnts.
+					  cycle_count >> 8) & 0xff);
+				*bp++ = (uint8_t)
+					(scn->mib_cycle_cnts.
+					 cycle_count & 0xff);
+
+				*bp++ = vowstats.rx_ratecode;
+				*bp++ = vowstats.rx_moreaggr;
+
+				/* sequence number */
+				*bp++ = (uint8_t)
+					((vowstats.rx_seqno >> 8) &
+					 0xff);
+				*bp++ = (uint8_t)
+					(vowstats.rx_seqno & 0xff);
+			}
+		}
+	}
+}
+
+#endif
diff --git a/core/dp/txrx/ol_rx.h b/core/dp/txrx/ol_rx.h
new file mode 100644
index 0000000..a44213f
--- /dev/null
+++ b/core/dp/txrx/ol_rx.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011, 2014-2018 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.
+ */
+
+#ifndef _OL_RX__H_
+#define _OL_RX__H_
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <ol_htt_api.h>         /* htt_pdev_handle */
+#include <cdp_txrx_cmn.h>       /* ol_txrx_vdev_t */
+
+#ifdef WLAN_PARTIAL_REORDER_OFFLOAD
+void
+ol_rx_deliver(struct ol_txrx_vdev_t *vdev,
+	      struct ol_txrx_peer_t *peer, unsigned int tid,
+	      qdf_nbuf_t head_msdu);
+#else
+static inline void
+ol_rx_deliver(struct ol_txrx_vdev_t *vdev,
+	      struct ol_txrx_peer_t *peer, unsigned int tid,
+	      qdf_nbuf_t head_msdu)
+{
+}
+#endif
+
+void
+ol_rx_discard(struct ol_txrx_vdev_t *vdev,
+	      struct ol_txrx_peer_t *peer, unsigned int tid,
+	      qdf_nbuf_t head_msdu);
+
+void ol_rx_frames_free(htt_pdev_handle htt_pdev, qdf_nbuf_t frames);
+
+void ol_rx_peer_init(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t *peer);
+
+void
+ol_rx_peer_cleanup(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer);
+
+#ifdef WDI_EVENT_ENABLE
+void ol_rx_send_pktlog_event(struct ol_txrx_pdev_t *pdev,
+			     struct ol_txrx_peer_t *peer, qdf_nbuf_t msdu,
+			     uint8_t pktlog_bit);
+#else
+static inline
+void ol_rx_send_pktlog_event(struct ol_txrx_pdev_t *pdev,
+			     struct ol_txrx_peer_t *peer, qdf_nbuf_t msdu,
+			     uint8_t pktlog_bit)
+{
+}
+#endif
+
+#ifdef WLAN_FULL_REORDER_OFFLOAD
+void
+ol_rx_in_order_deliver(struct ol_txrx_vdev_t *vdev,
+		       struct ol_txrx_peer_t *peer,
+		       unsigned int tid, qdf_nbuf_t head_msdu);
+#else
+static inline void
+ol_rx_in_order_deliver(struct ol_txrx_vdev_t *vdev,
+		       struct ol_txrx_peer_t *peer,
+		       unsigned int tid, qdf_nbuf_t head_msdu)
+{
+}
+#endif
+
+void ol_rx_log_packet(htt_pdev_handle htt_pdev,
+		 uint8_t peer_id, qdf_nbuf_t msdu);
+void
+ol_rx_offload_paddr_deliver_ind_handler(htt_pdev_handle htt_pdev,
+					uint32_t msdu_count,
+					uint32_t *msg_word);
+void ol_rx_update_histogram_stats(uint32_t msdu_count,
+		uint8_t frag_ind, uint8_t offload_ind);
+
+void
+ol_rx_mic_error_handler(
+	ol_txrx_pdev_handle pdev,
+	u_int8_t tid,
+	u_int16_t peer_id,
+	void *msdu_desc,
+	qdf_nbuf_t msdu);
+
+void htt_rx_fill_ring_count(htt_pdev_handle pdev);
+
+#endif /* _OL_RX__H_ */
diff --git a/core/dp/txrx/ol_rx_defrag.c b/core/dp/txrx/ol_rx_defrag.c
new file mode 100644
index 0000000..c87479d
--- /dev/null
+++ b/core/dp/txrx/ol_rx_defrag.c
@@ -0,0 +1,1278 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*-
+ * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <ol_htt_api.h>
+#include <ol_txrx_api.h>
+#include <ol_txrx_htt_api.h>
+#include <ol_htt_rx_api.h>
+#include <ol_rx_reorder.h>
+#include <ol_rx_pn.h>
+#include <ol_rx_fwd.h>
+#include <ol_rx.h>
+#include <ol_txrx_internal.h>
+#include <ol_ctrl_txrx_api.h>
+#include <ol_txrx_peer_find.h>
+#include <qdf_nbuf.h>
+#include <qdf_util.h>
+#include <athdefs.h>
+#include <qdf_mem.h>
+#include <ol_rx_defrag.h>
+#include <enet.h>
+#include <qdf_time.h>           /* qdf_system_time */
+
+#define DEFRAG_IEEE80211_ADDR_EQ(a1, a2) \
+	(!qdf_mem_cmp(a1, a2, IEEE80211_ADDR_LEN))
+
+#define DEFRAG_IEEE80211_ADDR_COPY(dst, src) \
+	qdf_mem_copy(dst, src, IEEE80211_ADDR_LEN)
+
+#define DEFRAG_IEEE80211_QOS_HAS_SEQ(wh) \
+	(((wh)->i_fc[0] & \
+	  (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == \
+	 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
+
+#define DEFRAG_IEEE80211_QOS_GET_TID(_x) \
+	((_x)->i_qos[0] & IEEE80211_QOS_TID)
+
+const struct ol_rx_defrag_cipher f_ccmp = {
+	"AES-CCM",
+	IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_EXTIVLEN,
+	IEEE80211_WEP_MICLEN,
+	0,
+};
+
+const struct ol_rx_defrag_cipher f_tkip = {
+	"TKIP",
+	IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_EXTIVLEN,
+	IEEE80211_WEP_CRCLEN,
+	IEEE80211_WEP_MICLEN,
+};
+
+const struct ol_rx_defrag_cipher f_wep = {
+	"WEP",
+	IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN,
+	IEEE80211_WEP_CRCLEN,
+	0,
+};
+
+#if defined(CONFIG_HL_SUPPORT)
+
+/**
+ * ol_rx_frag_get_mac_hdr() - retrieve mac header
+ * @htt_pdev: pointer to htt pdev handle
+ * @frag: rx fragment
+ *
+ * Return: pointer to ieee mac header of frag
+ */
+static struct ieee80211_frame *ol_rx_frag_get_mac_hdr(
+	htt_pdev_handle htt_pdev, qdf_nbuf_t frag)
+{
+	void *rx_desc;
+	int rx_desc_len;
+
+	rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev, frag);
+	rx_desc_len = htt_rx_msdu_rx_desc_size_hl(htt_pdev, rx_desc);
+	return (struct ieee80211_frame *)(qdf_nbuf_data(frag) + rx_desc_len);
+}
+
+/**
+ * ol_rx_frag_pull_hdr() - point to payload of rx frag
+ * @htt_pdev: pointer to htt pdev handle
+ * @frag: rx fragment
+ * @hdrsize: header size
+ *
+ * Return: None
+ */
+static void ol_rx_frag_pull_hdr(htt_pdev_handle htt_pdev,
+	qdf_nbuf_t frag, int hdrsize)
+{
+	void *rx_desc;
+	int rx_desc_len;
+
+	rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev, frag);
+	rx_desc_len = htt_rx_msdu_rx_desc_size_hl(htt_pdev, rx_desc);
+	qdf_nbuf_pull_head(frag, rx_desc_len + hdrsize);
+}
+
+/**
+ * ol_rx_frag_desc_adjust() - adjust rx frag descriptor position
+ * @pdev: pointer to txrx handle
+ * @msdu: msdu
+ * @rx_desc_old_position: rx descriptor old position
+ * @ind_old_position:index of old position
+ * @rx_desc_len: rx desciptor length
+ *
+ * Return: None
+ */
+static void
+ol_rx_frag_desc_adjust(ol_txrx_pdev_handle pdev,
+		       qdf_nbuf_t msdu,
+			void **rx_desc_old_position,
+			void **ind_old_position, int *rx_desc_len)
+{
+	*rx_desc_old_position = htt_rx_msdu_desc_retrieve(pdev->htt_pdev,
+									msdu);
+	*ind_old_position = *rx_desc_old_position - HTT_RX_IND_HL_BYTES;
+	*rx_desc_len = htt_rx_msdu_rx_desc_size_hl(pdev->htt_pdev,
+			*rx_desc_old_position);
+}
+
+/**
+ * ol_rx_frag_restructure() - point to payload for HL
+ * @pdev: physical device object
+ * @msdu: the buffer containing the MSDU payload
+ * @rx_desc_old_position: rx MSDU descriptor
+ * @ind_old_position: rx msdu indication
+ * @f_type: pointing to rx defrag cipher
+ * @rx_desc_len: length by which rx descriptor to move
+ *
+ * Return: None
+ */
+static void
+ol_rx_frag_restructure(
+	ol_txrx_pdev_handle pdev,
+	qdf_nbuf_t msdu,
+	void *rx_desc_old_position,
+	void *ind_old_position,
+	const struct ol_rx_defrag_cipher *f_type,
+	int rx_desc_len)
+{
+	if ((ind_old_position == NULL) || (rx_desc_old_position == NULL)) {
+		ol_txrx_err("ind_old_position,rx_desc_old_position is NULL\n");
+		ASSERT(0);
+		return;
+	}
+	/* move rx description*/
+	qdf_mem_move(rx_desc_old_position + f_type->ic_header,
+		     rx_desc_old_position, rx_desc_len);
+	/* move rx indication*/
+	qdf_mem_move(ind_old_position + f_type->ic_header, ind_old_position,
+		     HTT_RX_IND_HL_BYTES);
+}
+
+/**
+ * ol_rx_get_desc_len() - point to payload for HL
+ * @htt_pdev: the HTT instance the rx data was received on
+ * @wbuf: buffer containing the MSDU payload
+ * @rx_desc_old_position: rx MSDU descriptor
+ *
+ * Return: Return the HL rx desc size
+ */
+static
+int ol_rx_get_desc_len(htt_pdev_handle htt_pdev,
+			qdf_nbuf_t wbuf,
+			void **rx_desc_old_position)
+{
+	int rx_desc_len = 0;
+	*rx_desc_old_position = htt_rx_msdu_desc_retrieve(htt_pdev, wbuf);
+	rx_desc_len = htt_rx_msdu_rx_desc_size_hl(htt_pdev,
+			*rx_desc_old_position);
+
+	return rx_desc_len;
+}
+
+/**
+ * ol_rx_defrag_push_rx_desc() - point to payload for HL
+ * @nbuf: buffer containing the MSDU payload
+ * @rx_desc_old_position: rx MSDU descriptor
+ * @ind_old_position: rx msdu indication
+ * @rx_desc_len: HL rx desc size
+ *
+ * Return: Return the HL rx desc size
+ */
+static
+void ol_rx_defrag_push_rx_desc(qdf_nbuf_t nbuf,
+				void *rx_desc_old_position,
+				void *ind_old_position,
+				int rx_desc_len)
+{
+	qdf_nbuf_push_head(nbuf, rx_desc_len);
+	qdf_mem_move(
+		qdf_nbuf_data(nbuf), rx_desc_old_position, rx_desc_len);
+	qdf_mem_move(
+		qdf_nbuf_data(nbuf) - HTT_RX_IND_HL_BYTES, ind_old_position,
+		HTT_RX_IND_HL_BYTES);
+}
+#else
+
+static inline struct ieee80211_frame *ol_rx_frag_get_mac_hdr(
+	htt_pdev_handle htt_pdev,
+	qdf_nbuf_t frag)
+{
+	return
+		(struct ieee80211_frame *) qdf_nbuf_data(frag);
+}
+
+static inline void ol_rx_frag_pull_hdr(htt_pdev_handle htt_pdev,
+	qdf_nbuf_t frag, int hdrsize)
+{
+	qdf_nbuf_pull_head(frag, hdrsize);
+}
+
+static inline void
+ol_rx_frag_desc_adjust(ol_txrx_pdev_handle pdev,
+		       qdf_nbuf_t msdu,
+		       void **rx_desc_old_position,
+		       void **ind_old_position, int *rx_desc_len)
+{
+	*rx_desc_old_position = NULL;
+	*ind_old_position = NULL;
+	*rx_desc_len = 0;
+}
+
+static inline void
+ol_rx_frag_restructure(
+		ol_txrx_pdev_handle pdev,
+		qdf_nbuf_t msdu,
+		void *rx_desc_old_position,
+		void *ind_old_position,
+		const struct ol_rx_defrag_cipher *f_type,
+		int rx_desc_len)
+{
+	/* no op */
+}
+
+static inline
+int ol_rx_get_desc_len(htt_pdev_handle htt_pdev,
+			qdf_nbuf_t wbuf,
+			void **rx_desc_old_position)
+{
+	return 0;
+}
+
+static inline
+void ol_rx_defrag_push_rx_desc(qdf_nbuf_t nbuf,
+			void *rx_desc_old_position,
+			void *ind_old_position,
+			int rx_desc_len)
+{
+	return;
+}
+#endif /* CONFIG_HL_SUPPORT */
+
+/*
+ * Process incoming fragments
+ */
+void
+ol_rx_frag_indication_handler(ol_txrx_pdev_handle pdev,
+			      qdf_nbuf_t rx_frag_ind_msg,
+			      uint16_t peer_id, uint8_t tid)
+{
+	uint16_t seq_num;
+	uint16_t seq_num_start, seq_num_end;
+	struct ol_txrx_peer_t *peer;
+	htt_pdev_handle htt_pdev;
+	qdf_nbuf_t head_msdu, tail_msdu;
+	void *rx_mpdu_desc;
+	uint8_t pktlog_bit;
+	uint32_t msdu_count = 0;
+	int ret;
+
+	if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+		ol_txrx_err("%s:  invalid tid, %u\n", __FUNCTION__, tid);
+		return;
+	}
+
+	htt_pdev = pdev->htt_pdev;
+	peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+
+	if (!ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev) &&
+	    htt_rx_ind_flush(pdev->htt_pdev, rx_frag_ind_msg) && peer) {
+		htt_rx_frag_ind_flush_seq_num_range(pdev->htt_pdev,
+						    rx_frag_ind_msg,
+						    &seq_num_start,
+						    &seq_num_end);
+		/*
+		 * Assuming flush indication for frags sent from target is
+		 * separate from normal frames
+		 */
+		ol_rx_reorder_flush_frag(htt_pdev, peer, tid, seq_num_start);
+	} else {
+		uint32_t *msg_word;
+		uint8_t *rx_ind_data;
+
+		rx_ind_data = qdf_nbuf_data(rx_frag_ind_msg);
+		msg_word = (uint32_t *)rx_ind_data;
+		msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word +
+								    1));
+	}
+
+	pktlog_bit =
+		(htt_rx_amsdu_rx_in_order_get_pktlog(rx_frag_ind_msg) == 0x01);
+	ret = htt_rx_frag_pop(htt_pdev, rx_frag_ind_msg, &head_msdu,
+			      &tail_msdu, &msdu_count);
+	/* Return if msdu pop fails from rx hash table, as recovery
+	 * is triggered and we exit gracefully.
+	 */
+	if (!ret)
+		return;
+	if (peer) {
+		qdf_assert(head_msdu == tail_msdu);
+		if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev)) {
+			rx_mpdu_desc =
+				htt_rx_mpdu_desc_list_next(htt_pdev, head_msdu);
+		} else {
+			rx_mpdu_desc =
+				htt_rx_mpdu_desc_list_next(htt_pdev,
+							   rx_frag_ind_msg);
+		}
+		seq_num = htt_rx_mpdu_desc_seq_num(htt_pdev, rx_mpdu_desc);
+		OL_RX_ERR_STATISTICS_1(pdev, peer->vdev, peer, rx_mpdu_desc,
+				       OL_RX_ERR_NONE_FRAG);
+		ol_rx_send_pktlog_event(pdev, peer, head_msdu, pktlog_bit);
+		ol_rx_reorder_store_frag(pdev, peer, tid, seq_num, head_msdu);
+	} else {
+		/* invalid frame - discard it */
+		if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev))
+			htt_rx_msdu_desc_retrieve(htt_pdev, head_msdu);
+		else
+			htt_rx_mpdu_desc_list_next(htt_pdev, rx_frag_ind_msg);
+
+		ol_rx_send_pktlog_event(pdev, peer, head_msdu, pktlog_bit);
+		htt_rx_desc_frame_free(htt_pdev, head_msdu);
+	}
+	/* request HTT to provide new rx MSDU buffers for the target to fill. */
+	if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev) &&
+	    !pdev->cfg.is_high_latency)
+		htt_rx_msdu_buff_in_order_replenish(htt_pdev, msdu_count);
+	else
+		htt_rx_msdu_buff_replenish(htt_pdev);
+}
+
+/*
+ * Flushing fragments
+ */
+void
+ol_rx_reorder_flush_frag(htt_pdev_handle htt_pdev,
+			 struct ol_txrx_peer_t *peer,
+			 unsigned int tid, uint16_t seq_num)
+{
+	struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
+	int seq;
+
+	seq = seq_num & peer->tids_rx_reorder[tid].win_sz_mask;
+	rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[seq];
+	if (rx_reorder_array_elem->head) {
+		ol_rx_frames_free(htt_pdev, rx_reorder_array_elem->head);
+		rx_reorder_array_elem->head = NULL;
+		rx_reorder_array_elem->tail = NULL;
+	}
+}
+
+/*
+ * Reorder and store fragments
+ */
+void
+ol_rx_reorder_store_frag(ol_txrx_pdev_handle pdev,
+			 struct ol_txrx_peer_t *peer,
+			 unsigned int tid, uint16_t seq_num, qdf_nbuf_t frag)
+{
+	struct ieee80211_frame *fmac_hdr, *mac_hdr;
+	uint8_t fragno, more_frag, all_frag_present = 0;
+	struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
+	uint16_t frxseq, rxseq, seq;
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+
+	seq = seq_num & peer->tids_rx_reorder[tid].win_sz_mask;
+	qdf_assert(seq == 0);
+	rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[seq];
+
+	mac_hdr = (struct ieee80211_frame *)
+		ol_rx_frag_get_mac_hdr(htt_pdev, frag);
+	rxseq = qdf_le16_to_cpu(*(uint16_t *) mac_hdr->i_seq) >>
+		IEEE80211_SEQ_SEQ_SHIFT;
+	fragno = qdf_le16_to_cpu(*(uint16_t *) mac_hdr->i_seq) &
+		IEEE80211_SEQ_FRAG_MASK;
+	more_frag = mac_hdr->i_fc[1] & IEEE80211_FC1_MORE_FRAG;
+
+	if ((!more_frag) && (!fragno) && (!rx_reorder_array_elem->head)) {
+		rx_reorder_array_elem->head = frag;
+		rx_reorder_array_elem->tail = frag;
+		qdf_nbuf_set_next(frag, NULL);
+		ol_rx_defrag(pdev, peer, tid, rx_reorder_array_elem->head);
+		rx_reorder_array_elem->head = NULL;
+		rx_reorder_array_elem->tail = NULL;
+		return;
+	}
+	if (rx_reorder_array_elem->head) {
+		fmac_hdr = (struct ieee80211_frame *)
+			ol_rx_frag_get_mac_hdr(htt_pdev,
+					       rx_reorder_array_elem->head);
+		frxseq = qdf_le16_to_cpu(*(uint16_t *) fmac_hdr->i_seq) >>
+			IEEE80211_SEQ_SEQ_SHIFT;
+		if (rxseq != frxseq
+		    || !DEFRAG_IEEE80211_ADDR_EQ(mac_hdr->i_addr1,
+						 fmac_hdr->i_addr1)
+		    || !DEFRAG_IEEE80211_ADDR_EQ(mac_hdr->i_addr2,
+						 fmac_hdr->i_addr2)) {
+			ol_rx_frames_free(htt_pdev,
+					  rx_reorder_array_elem->head);
+			rx_reorder_array_elem->head = NULL;
+			rx_reorder_array_elem->tail = NULL;
+			ol_txrx_err("\n ol_rx_reorder_store:%s mismatch\n",
+				   (rxseq == frxseq)
+				   ? "address"
+				   : "seq number");
+		}
+	}
+
+	ol_rx_fraglist_insert(htt_pdev, &rx_reorder_array_elem->head,
+			      &rx_reorder_array_elem->tail, frag,
+			      &all_frag_present);
+
+	if (pdev->rx.flags.defrag_timeout_check)
+		ol_rx_defrag_waitlist_remove(peer, tid);
+
+	if (all_frag_present) {
+		ol_rx_defrag(pdev, peer, tid, rx_reorder_array_elem->head);
+		rx_reorder_array_elem->head = NULL;
+		rx_reorder_array_elem->tail = NULL;
+		peer->tids_rx_reorder[tid].defrag_timeout_ms = 0;
+		peer->tids_last_seq[tid] = seq_num;
+	} else if (pdev->rx.flags.defrag_timeout_check) {
+		uint32_t now_ms = qdf_system_ticks_to_msecs(qdf_system_ticks());
+
+		peer->tids_rx_reorder[tid].defrag_timeout_ms =
+			now_ms + pdev->rx.defrag.timeout_ms;
+		ol_rx_defrag_waitlist_add(peer, tid);
+	}
+}
+
+/*
+ * Insert and store fragments
+ */
+void
+ol_rx_fraglist_insert(htt_pdev_handle htt_pdev,
+		      qdf_nbuf_t *head_addr,
+		      qdf_nbuf_t *tail_addr,
+		      qdf_nbuf_t frag, uint8_t *all_frag_present)
+{
+	qdf_nbuf_t next, prev = NULL, cur = *head_addr;
+	struct ieee80211_frame *mac_hdr, *cmac_hdr, *next_hdr, *lmac_hdr;
+	uint8_t fragno, cur_fragno, lfragno, next_fragno;
+	uint8_t last_morefrag = 1, count = 0;
+
+	qdf_assert(frag);
+
+	mac_hdr = (struct ieee80211_frame *)
+		ol_rx_frag_get_mac_hdr(htt_pdev, frag);
+	fragno = qdf_le16_to_cpu(*(uint16_t *) mac_hdr->i_seq) &
+		IEEE80211_SEQ_FRAG_MASK;
+
+	if (!(*head_addr)) {
+		*head_addr = frag;
+		*tail_addr = frag;
+		qdf_nbuf_set_next(*tail_addr, NULL);
+		return;
+	}
+	/* For efficiency, compare with tail first */
+	lmac_hdr = (struct ieee80211_frame *)
+		ol_rx_frag_get_mac_hdr(htt_pdev, *tail_addr);
+	lfragno = qdf_le16_to_cpu(*(uint16_t *) lmac_hdr->i_seq) &
+		  IEEE80211_SEQ_FRAG_MASK;
+	if (fragno > lfragno) {
+		qdf_nbuf_set_next(*tail_addr, frag);
+		*tail_addr = frag;
+		qdf_nbuf_set_next(*tail_addr, NULL);
+	} else {
+		do {
+			cmac_hdr = (struct ieee80211_frame *)
+				ol_rx_frag_get_mac_hdr(htt_pdev, cur);
+			cur_fragno =
+				qdf_le16_to_cpu(*(uint16_t *) cmac_hdr->i_seq) &
+				IEEE80211_SEQ_FRAG_MASK;
+			prev = cur;
+			cur = qdf_nbuf_next(cur);
+		} while (fragno > cur_fragno);
+
+		if (fragno == cur_fragno) {
+			htt_rx_desc_frame_free(htt_pdev, frag);
+			*all_frag_present = 0;
+			return;
+		}
+
+		qdf_nbuf_set_next(prev, frag);
+		qdf_nbuf_set_next(frag, cur);
+	}
+	next = qdf_nbuf_next(*head_addr);
+	lmac_hdr = (struct ieee80211_frame *)ol_rx_frag_get_mac_hdr(htt_pdev,
+								    *tail_addr);
+	last_morefrag = lmac_hdr->i_fc[1] & IEEE80211_FC1_MORE_FRAG;
+	if (!last_morefrag) {
+		do {
+			next_hdr =
+				(struct ieee80211_frame *)
+				ol_rx_frag_get_mac_hdr(htt_pdev, next);
+			next_fragno =
+				qdf_le16_to_cpu(*(uint16_t *) next_hdr->i_seq) &
+				IEEE80211_SEQ_FRAG_MASK;
+			count++;
+			if (next_fragno != count)
+				break;
+
+			next = qdf_nbuf_next(next);
+		} while (next);
+
+		if (!next) {
+			*all_frag_present = 1;
+			return;
+		}
+	}
+	*all_frag_present = 0;
+}
+
+/*
+ * add tid to pending fragment wait list
+ */
+void ol_rx_defrag_waitlist_add(struct ol_txrx_peer_t *peer, unsigned int tid)
+{
+	struct ol_txrx_pdev_t *pdev = peer->vdev->pdev;
+	struct ol_rx_reorder_t *rx_reorder = &peer->tids_rx_reorder[tid];
+
+	TAILQ_INSERT_TAIL(&pdev->rx.defrag.waitlist, rx_reorder,
+			  defrag_waitlist_elem);
+}
+
+/*
+ * remove tid from pending fragment wait list
+ */
+void ol_rx_defrag_waitlist_remove(struct ol_txrx_peer_t *peer, unsigned int tid)
+{
+	struct ol_txrx_pdev_t *pdev = peer->vdev->pdev;
+	struct ol_rx_reorder_t *rx_reorder = &peer->tids_rx_reorder[tid];
+
+	if (rx_reorder->defrag_waitlist_elem.tqe_next != NULL) {
+
+		TAILQ_REMOVE(&pdev->rx.defrag.waitlist, rx_reorder,
+			     defrag_waitlist_elem);
+
+		rx_reorder->defrag_waitlist_elem.tqe_next = NULL;
+		rx_reorder->defrag_waitlist_elem.tqe_prev = NULL;
+	} else if (rx_reorder->defrag_waitlist_elem.tqe_next != NULL) {
+		ol_txrx_alert("waitlist->tqe_prv = NULL\n");
+		QDF_ASSERT(0);
+		rx_reorder->defrag_waitlist_elem.tqe_next = NULL;
+	}
+}
+
+#ifndef container_of
+#define container_of(ptr, type, member) \
+	((type *)((char *)(ptr) - (char *)(&((type *)0)->member)))
+#endif
+
+/*
+ * flush stale fragments from the waitlist
+ */
+void ol_rx_defrag_waitlist_flush(struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_rx_reorder_t *rx_reorder, *tmp;
+	uint32_t now_ms = qdf_system_ticks_to_msecs(qdf_system_ticks());
+
+	TAILQ_FOREACH_SAFE(rx_reorder, &pdev->rx.defrag.waitlist,
+			   defrag_waitlist_elem, tmp) {
+		struct ol_txrx_peer_t *peer;
+		struct ol_rx_reorder_t *rx_reorder_base;
+		unsigned int tid;
+
+		if (rx_reorder->defrag_timeout_ms > now_ms)
+			break;
+
+		tid = rx_reorder->tid;
+		if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+			ol_txrx_err("%s:  invalid tid, %u\n", __FUNCTION__, tid);
+			WARN_ON(1);
+			continue;
+		}
+		/* get index 0 of the rx_reorder array */
+		rx_reorder_base = rx_reorder - tid;
+		peer =
+			container_of(rx_reorder_base, struct ol_txrx_peer_t,
+				     tids_rx_reorder[0]);
+
+		ol_rx_defrag_waitlist_remove(peer, tid);
+		ol_rx_reorder_flush_frag(pdev->htt_pdev, peer, tid,
+					 0 /* frags always stored at seq 0 */);
+	}
+}
+
+/*
+ * Handling security checking and processing fragments
+ */
+void
+ol_rx_defrag(ol_txrx_pdev_handle pdev,
+	     struct ol_txrx_peer_t *peer, unsigned int tid,
+	     qdf_nbuf_t frag_list)
+{
+	struct ol_txrx_vdev_t *vdev = NULL;
+	qdf_nbuf_t tmp_next, msdu, prev = NULL, cur = frag_list;
+	uint8_t index, tkip_demic = 0;
+	uint16_t hdr_space;
+	void *rx_desc;
+	struct ieee80211_frame *wh;
+	uint8_t key[DEFRAG_IEEE80211_KEY_LEN];
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+
+	vdev = peer->vdev;
+
+	/* bypass defrag for safe mode */
+	if (vdev->safemode) {
+		if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev))
+			ol_rx_in_order_deliver(vdev, peer, tid, frag_list);
+		else
+			ol_rx_deliver(vdev, peer, tid, frag_list);
+		return;
+	}
+
+	while (cur) {
+		tmp_next = qdf_nbuf_next(cur);
+		qdf_nbuf_set_next(cur, NULL);
+		if (!ol_rx_pn_check_base(vdev, peer, tid, cur)) {
+			/* PN check failed,discard frags */
+			if (prev) {
+				qdf_nbuf_set_next(prev, NULL);
+				ol_rx_frames_free(htt_pdev, frag_list);
+			}
+			ol_rx_frames_free(htt_pdev, tmp_next);
+			ol_txrx_err("PN Check failed");
+			return;
+		}
+		/* remove FCS from each fragment */
+		qdf_nbuf_trim_tail(cur, DEFRAG_IEEE80211_FCS_LEN);
+		prev = cur;
+		qdf_nbuf_set_next(cur, tmp_next);
+		cur = tmp_next;
+	}
+	cur = frag_list;
+	wh = (struct ieee80211_frame *)ol_rx_frag_get_mac_hdr(htt_pdev, cur);
+	hdr_space = ol_rx_frag_hdrsize(wh);
+	rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev, frag_list);
+	qdf_assert(htt_rx_msdu_has_wlan_mcast_flag(htt_pdev, rx_desc));
+	index = htt_rx_msdu_is_wlan_mcast(htt_pdev, rx_desc) ?
+		txrx_sec_mcast : txrx_sec_ucast;
+
+	switch (peer->security[index].sec_type) {
+	case htt_sec_type_tkip:
+		tkip_demic = 1;
+	/* fall-through to rest of tkip ops */
+	case htt_sec_type_tkip_nomic:
+		while (cur) {
+			tmp_next = qdf_nbuf_next(cur);
+			if (!ol_rx_frag_tkip_decap(pdev, cur, hdr_space)) {
+				/* TKIP decap failed, discard frags */
+				ol_rx_frames_free(htt_pdev, frag_list);
+				ol_txrx_err("TKIP decap failed");
+				return;
+			}
+			cur = tmp_next;
+		}
+		break;
+
+	case htt_sec_type_aes_ccmp:
+		while (cur) {
+			tmp_next = qdf_nbuf_next(cur);
+			if (!ol_rx_frag_ccmp_demic(pdev, cur, hdr_space)) {
+				/* CCMP demic failed, discard frags */
+				ol_rx_frames_free(htt_pdev, frag_list);
+				ol_txrx_err("CCMP demic failed");
+				return;
+			}
+			if (!ol_rx_frag_ccmp_decap(pdev, cur, hdr_space)) {
+				/* CCMP decap failed, discard frags */
+				ol_rx_frames_free(htt_pdev, frag_list);
+				ol_txrx_err("CCMP decap failed");
+				return;
+			}
+			cur = tmp_next;
+		}
+		break;
+
+	case htt_sec_type_wep40:
+	case htt_sec_type_wep104:
+	case htt_sec_type_wep128:
+		while (cur) {
+			tmp_next = qdf_nbuf_next(cur);
+			if (!ol_rx_frag_wep_decap(pdev, cur, hdr_space)) {
+				/* wep decap failed, discard frags */
+				ol_rx_frames_free(htt_pdev, frag_list);
+				ol_txrx_err("wep decap failed");
+				return;
+			}
+			cur = tmp_next;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	msdu = ol_rx_defrag_decap_recombine(htt_pdev, frag_list, hdr_space);
+	if (!msdu)
+		return;
+
+	if (tkip_demic) {
+		qdf_mem_copy(key,
+			     peer->security[index].michael_key,
+			     sizeof(peer->security[index].michael_key));
+		if (!ol_rx_frag_tkip_demic(pdev, key, msdu, hdr_space)) {
+			htt_rx_desc_frame_free(htt_pdev, msdu);
+			ol_rx_err(pdev->ctrl_pdev,
+				  vdev->vdev_id, peer->mac_addr.raw, tid, 0,
+				  OL_RX_DEFRAG_ERR, msdu, NULL, 0);
+			ol_txrx_err("TKIP demic failed");
+			return;
+		}
+	}
+	wh = (struct ieee80211_frame *)ol_rx_frag_get_mac_hdr(htt_pdev, msdu);
+	if (DEFRAG_IEEE80211_QOS_HAS_SEQ(wh))
+		ol_rx_defrag_qos_decap(pdev, msdu, hdr_space);
+	if (ol_cfg_frame_type(pdev->ctrl_pdev) == wlan_frm_fmt_802_3)
+		ol_rx_defrag_nwifi_to_8023(pdev, msdu);
+
+	ol_rx_fwd_check(vdev, peer, tid, msdu);
+}
+
+/*
+ * Handling TKIP processing for defragmentation
+ */
+int
+ol_rx_frag_tkip_decap(ol_txrx_pdev_handle pdev,
+		      qdf_nbuf_t msdu, uint16_t hdrlen)
+{
+	uint8_t *ivp, *origHdr;
+
+	void *rx_desc_old_position = NULL;
+	void *ind_old_position = NULL;
+	int rx_desc_len = 0;
+
+	ol_rx_frag_desc_adjust(pdev,
+			       msdu,
+			       &rx_desc_old_position,
+			       &ind_old_position, &rx_desc_len);
+	/* Header should have extended IV */
+	origHdr = (uint8_t *) (qdf_nbuf_data(msdu) + rx_desc_len);
+
+	ivp = origHdr + hdrlen;
+	if (!(ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV))
+		return OL_RX_DEFRAG_ERR;
+
+	qdf_mem_move(origHdr + f_tkip.ic_header, origHdr, hdrlen);
+	ol_rx_frag_restructure(
+			pdev,
+			msdu,
+			rx_desc_old_position,
+			ind_old_position,
+			&f_tkip,
+			rx_desc_len);
+	qdf_nbuf_pull_head(msdu, f_tkip.ic_header);
+	qdf_nbuf_trim_tail(msdu, f_tkip.ic_trailer);
+	return OL_RX_DEFRAG_OK;
+}
+
+/*
+ * Handling WEP processing for defragmentation
+ */
+int
+ol_rx_frag_wep_decap(ol_txrx_pdev_handle pdev, qdf_nbuf_t msdu, uint16_t hdrlen)
+{
+	uint8_t *origHdr;
+	void *rx_desc_old_position = NULL;
+	void *ind_old_position = NULL;
+	int rx_desc_len = 0;
+
+	ol_rx_frag_desc_adjust(pdev,
+			       msdu,
+			       &rx_desc_old_position,
+			       &ind_old_position, &rx_desc_len);
+	origHdr = (uint8_t *) (qdf_nbuf_data(msdu) + rx_desc_len);
+	qdf_mem_move(origHdr + f_wep.ic_header, origHdr, hdrlen);
+	ol_rx_frag_restructure(
+			pdev,
+			msdu,
+			rx_desc_old_position,
+			ind_old_position,
+			&f_wep,
+			rx_desc_len);
+	qdf_nbuf_pull_head(msdu, f_wep.ic_header);
+	qdf_nbuf_trim_tail(msdu, f_wep.ic_trailer);
+	return OL_RX_DEFRAG_OK;
+}
+
+/*
+ * Verify and strip MIC from the frame.
+ */
+int
+ol_rx_frag_tkip_demic(ol_txrx_pdev_handle pdev, const uint8_t *key,
+		      qdf_nbuf_t msdu, uint16_t hdrlen)
+{
+	int status;
+	uint32_t pktlen;
+	uint8_t mic[IEEE80211_WEP_MICLEN];
+	uint8_t mic0[IEEE80211_WEP_MICLEN];
+	void *rx_desc_old_position = NULL;
+	void *ind_old_position = NULL;
+	int rx_desc_len = 0;
+
+	ol_rx_frag_desc_adjust(pdev,
+			       msdu,
+			       &rx_desc_old_position,
+			       &ind_old_position, &rx_desc_len);
+
+	pktlen = ol_rx_defrag_len(msdu) - rx_desc_len;
+
+	status = ol_rx_defrag_mic(pdev, key, msdu, hdrlen,
+				  pktlen - (hdrlen + f_tkip.ic_miclen), mic);
+	if (status != OL_RX_DEFRAG_OK)
+		return OL_RX_DEFRAG_ERR;
+
+	ol_rx_defrag_copydata(msdu, pktlen - f_tkip.ic_miclen + rx_desc_len,
+			      f_tkip.ic_miclen, (caddr_t) mic0);
+	if (!qdf_mem_cmp(mic, mic0, f_tkip.ic_miclen))
+		return OL_RX_DEFRAG_ERR;
+
+	qdf_nbuf_trim_tail(msdu, f_tkip.ic_miclen);
+	return OL_RX_DEFRAG_OK;
+}
+
+/*
+ * Handling CCMP processing for defragmentation
+ */
+int
+ol_rx_frag_ccmp_decap(ol_txrx_pdev_handle pdev,
+		      qdf_nbuf_t nbuf, uint16_t hdrlen)
+{
+	uint8_t *ivp, *origHdr;
+	void *rx_desc_old_position = NULL;
+	void *ind_old_position = NULL;
+	int rx_desc_len = 0;
+
+	ol_rx_frag_desc_adjust(pdev,
+			       nbuf,
+			       &rx_desc_old_position,
+			       &ind_old_position, &rx_desc_len);
+
+	origHdr = (uint8_t *) (qdf_nbuf_data(nbuf) + rx_desc_len);
+	ivp = origHdr + hdrlen;
+	if (!(ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV))
+		return OL_RX_DEFRAG_ERR;
+
+	qdf_mem_move(origHdr + f_ccmp.ic_header, origHdr, hdrlen);
+	ol_rx_frag_restructure(
+			pdev,
+			nbuf,
+			rx_desc_old_position,
+			ind_old_position,
+			&f_ccmp,
+			rx_desc_len);
+	qdf_nbuf_pull_head(nbuf, f_ccmp.ic_header);
+
+	return OL_RX_DEFRAG_OK;
+}
+
+/*
+ * Verify and strip MIC from the frame.
+ */
+int
+ol_rx_frag_ccmp_demic(ol_txrx_pdev_handle pdev,
+		      qdf_nbuf_t wbuf, uint16_t hdrlen)
+{
+	uint8_t *ivp, *origHdr;
+	void *rx_desc_old_position = NULL;
+	void *ind_old_position = NULL;
+	int rx_desc_len = 0;
+
+	ol_rx_frag_desc_adjust(pdev,
+			       wbuf,
+			       &rx_desc_old_position,
+			       &ind_old_position, &rx_desc_len);
+
+	origHdr = (uint8_t *) (qdf_nbuf_data(wbuf) + rx_desc_len);
+
+	ivp = origHdr + hdrlen;
+	if (!(ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV))
+		return OL_RX_DEFRAG_ERR;
+
+	qdf_nbuf_trim_tail(wbuf, f_ccmp.ic_trailer);
+
+	return OL_RX_DEFRAG_OK;
+}
+
+/*
+ * Craft pseudo header used to calculate the MIC.
+ */
+void ol_rx_defrag_michdr(const struct ieee80211_frame *wh0, uint8_t hdr[])
+{
+	const struct ieee80211_frame_addr4 *wh =
+		(const struct ieee80211_frame_addr4 *)wh0;
+
+	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
+	case IEEE80211_FC1_DIR_NODS:
+		DEFRAG_IEEE80211_ADDR_COPY(hdr, wh->i_addr1);   /* DA */
+		DEFRAG_IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN,
+					   wh->i_addr2);
+		break;
+	case IEEE80211_FC1_DIR_TODS:
+		DEFRAG_IEEE80211_ADDR_COPY(hdr, wh->i_addr3);   /* DA */
+		DEFRAG_IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN,
+					   wh->i_addr2);
+		break;
+	case IEEE80211_FC1_DIR_FROMDS:
+		DEFRAG_IEEE80211_ADDR_COPY(hdr, wh->i_addr1);   /* DA */
+		DEFRAG_IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN,
+					   wh->i_addr3);
+		break;
+	case IEEE80211_FC1_DIR_DSTODS:
+		DEFRAG_IEEE80211_ADDR_COPY(hdr, wh->i_addr3);   /* DA */
+		DEFRAG_IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN,
+					   wh->i_addr4);
+		break;
+	}
+	/*
+	 * Bit 7 is IEEE80211_FC0_SUBTYPE_QOS for data frame, but
+	 * it could also be set for deauth, disassoc, action, etc. for
+	 * a mgt type frame. It comes into picture for MFP.
+	 */
+	if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
+		const struct ieee80211_qosframe *qwh =
+			(const struct ieee80211_qosframe *)wh;
+		hdr[12] = qwh->i_qos[0] & IEEE80211_QOS_TID;
+	} else {
+		hdr[12] = 0;
+	}
+	hdr[13] = hdr[14] = hdr[15] = 0;        /* reserved */
+}
+
+/*
+ * Michael_mic for defragmentation
+ */
+int
+ol_rx_defrag_mic(ol_txrx_pdev_handle pdev,
+		 const uint8_t *key,
+		 qdf_nbuf_t wbuf,
+		 uint16_t off, uint16_t data_len, uint8_t mic[])
+{
+	uint8_t hdr[16] = { 0, };
+	uint32_t l, r;
+	const uint8_t *data;
+	uint32_t space;
+	void *rx_desc_old_position = NULL;
+	void *ind_old_position = NULL;
+	int rx_desc_len = 0;
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+
+	ol_rx_frag_desc_adjust(pdev,
+			       wbuf,
+			       &rx_desc_old_position,
+			       &ind_old_position, &rx_desc_len);
+
+	ol_rx_defrag_michdr((struct ieee80211_frame *)(qdf_nbuf_data(wbuf) +
+						       rx_desc_len), hdr);
+	l = get_le32(key);
+	r = get_le32(key + 4);
+
+	/* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
+	l ^= get_le32(hdr);
+	michael_block(l, r);
+	l ^= get_le32(&hdr[4]);
+	michael_block(l, r);
+	l ^= get_le32(&hdr[8]);
+	michael_block(l, r);
+	l ^= get_le32(&hdr[12]);
+	michael_block(l, r);
+
+	/* first buffer has special handling */
+	data = (uint8_t *) qdf_nbuf_data(wbuf) + rx_desc_len + off;
+	space = ol_rx_defrag_len(wbuf) - rx_desc_len - off;
+	for (;; ) {
+		if (space > data_len)
+			space = data_len;
+
+		/* collect 32-bit blocks from current buffer */
+		while (space >= sizeof(uint32_t)) {
+			l ^= get_le32(data);
+			michael_block(l, r);
+			data += sizeof(uint32_t);
+			space -= sizeof(uint32_t);
+			data_len -= sizeof(uint32_t);
+		}
+		if (data_len < sizeof(uint32_t))
+			break;
+
+		wbuf = qdf_nbuf_next(wbuf);
+		if (wbuf == NULL)
+			return OL_RX_DEFRAG_ERR;
+
+		rx_desc_len = ol_rx_get_desc_len(htt_pdev, wbuf,
+						 &rx_desc_old_position);
+
+		if (space != 0) {
+			const uint8_t *data_next;
+			/*
+			 * Block straddles buffers, split references.
+			 */
+			data_next =
+				(uint8_t *) qdf_nbuf_data(wbuf) + rx_desc_len;
+			if ((ol_rx_defrag_len(wbuf) - rx_desc_len) <
+			    sizeof(uint32_t) - space) {
+				return OL_RX_DEFRAG_ERR;
+			}
+			switch (space) {
+			case 1:
+				l ^= get_le32_split(data[0], data_next[0],
+						    data_next[1], data_next[2]);
+				data = data_next + 3;
+				space = (ol_rx_defrag_len(wbuf) - rx_desc_len)
+					- 3;
+				break;
+			case 2:
+				l ^= get_le32_split(data[0], data[1],
+						    data_next[0], data_next[1]);
+				data = data_next + 2;
+				space = (ol_rx_defrag_len(wbuf) - rx_desc_len)
+					- 2;
+				break;
+			case 3:
+				l ^= get_le32_split(data[0], data[1], data[2],
+						    data_next[0]);
+				data = data_next + 1;
+				space = (ol_rx_defrag_len(wbuf) - rx_desc_len)
+					- 1;
+				break;
+			}
+			michael_block(l, r);
+			data_len -= sizeof(uint32_t);
+		} else {
+			/*
+			 * Setup for next buffer.
+			 */
+			data = (uint8_t *) qdf_nbuf_data(wbuf) + rx_desc_len;
+			space = ol_rx_defrag_len(wbuf) - rx_desc_len;
+		}
+	}
+	/* Last block and padding (0x5a, 4..7 x 0) */
+	switch (data_len) {
+	case 0:
+		l ^= get_le32_split(0x5a, 0, 0, 0);
+		break;
+	case 1:
+		l ^= get_le32_split(data[0], 0x5a, 0, 0);
+		break;
+	case 2:
+		l ^= get_le32_split(data[0], data[1], 0x5a, 0);
+		break;
+	case 3:
+		l ^= get_le32_split(data[0], data[1], data[2], 0x5a);
+		break;
+	}
+	michael_block(l, r);
+	michael_block(l, r);
+	put_le32(mic, l);
+	put_le32(mic + 4, r);
+
+	return OL_RX_DEFRAG_OK;
+}
+
+/*
+ * Calculate headersize
+ */
+uint16_t ol_rx_frag_hdrsize(const void *data)
+{
+	const struct ieee80211_frame *wh = (const struct ieee80211_frame *)data;
+	uint16_t size = sizeof(struct ieee80211_frame);
+
+	if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
+		size += IEEE80211_ADDR_LEN;
+
+	if (DEFRAG_IEEE80211_QOS_HAS_SEQ(wh)) {
+		size += sizeof(uint16_t);
+		if (wh->i_fc[1] & IEEE80211_FC1_ORDER)
+			size += sizeof(struct ieee80211_htc);
+	}
+	return size;
+}
+
+/*
+ * Recombine and decap fragments
+ */
+qdf_nbuf_t
+ol_rx_defrag_decap_recombine(htt_pdev_handle htt_pdev,
+			     qdf_nbuf_t frag_list, uint16_t hdrsize)
+{
+	qdf_nbuf_t tmp;
+	qdf_nbuf_t msdu = frag_list;
+	qdf_nbuf_t rx_nbuf = frag_list;
+	struct ieee80211_frame *wh;
+
+	msdu = qdf_nbuf_next(msdu);
+	qdf_nbuf_set_next(rx_nbuf, NULL);
+	while (msdu) {
+		htt_rx_msdu_desc_free(htt_pdev, msdu);
+		tmp = qdf_nbuf_next(msdu);
+		qdf_nbuf_set_next(msdu, NULL);
+		ol_rx_frag_pull_hdr(htt_pdev, msdu, hdrsize);
+		if (!ol_rx_defrag_concat(rx_nbuf, msdu)) {
+			ol_rx_frames_free(htt_pdev, tmp);
+			htt_rx_desc_frame_free(htt_pdev, rx_nbuf);
+			qdf_nbuf_free(msdu);
+			/* msdu rx desc already freed above */
+			return NULL;
+		}
+		msdu = tmp;
+	}
+	wh = (struct ieee80211_frame *)ol_rx_frag_get_mac_hdr(htt_pdev,
+							      rx_nbuf);
+	wh->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG;
+	*(uint16_t *) wh->i_seq &= ~IEEE80211_SEQ_FRAG_MASK;
+
+	return rx_nbuf;
+}
+
+void ol_rx_defrag_nwifi_to_8023(ol_txrx_pdev_handle pdev, qdf_nbuf_t msdu)
+{
+	struct ieee80211_frame wh;
+	uint32_t hdrsize;
+	struct llc_snap_hdr_t llchdr;
+	struct ethernet_hdr_t *eth_hdr;
+	void *rx_desc_old_position = NULL;
+	void *ind_old_position = NULL;
+	int rx_desc_len = 0;
+	struct ieee80211_frame *wh_ptr;
+
+	ol_rx_frag_desc_adjust(pdev,
+			       msdu,
+			       &rx_desc_old_position,
+			       &ind_old_position, &rx_desc_len);
+
+	wh_ptr = (struct ieee80211_frame *)(qdf_nbuf_data(msdu) + rx_desc_len);
+	qdf_mem_copy(&wh, wh_ptr, sizeof(wh));
+	hdrsize = sizeof(struct ieee80211_frame);
+	qdf_mem_copy(&llchdr, ((uint8_t *) (qdf_nbuf_data(msdu) +
+					    rx_desc_len)) + hdrsize,
+		     sizeof(struct llc_snap_hdr_t));
+
+	/*
+	 * Now move the data pointer to the beginning of the mac header :
+	 * new-header = old-hdr + (wifhdrsize + llchdrsize - ethhdrsize)
+	 */
+	qdf_nbuf_pull_head(msdu, (rx_desc_len + hdrsize +
+				  sizeof(struct llc_snap_hdr_t) -
+				  sizeof(struct ethernet_hdr_t)));
+	eth_hdr = (struct ethernet_hdr_t *)(qdf_nbuf_data(msdu));
+	switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
+	case IEEE80211_FC1_DIR_NODS:
+		qdf_mem_copy(eth_hdr->dest_addr, wh.i_addr1,
+			     IEEE80211_ADDR_LEN);
+		qdf_mem_copy(eth_hdr->src_addr, wh.i_addr2, IEEE80211_ADDR_LEN);
+		break;
+	case IEEE80211_FC1_DIR_TODS:
+		qdf_mem_copy(eth_hdr->dest_addr, wh.i_addr3,
+			     IEEE80211_ADDR_LEN);
+		qdf_mem_copy(eth_hdr->src_addr, wh.i_addr2, IEEE80211_ADDR_LEN);
+		break;
+	case IEEE80211_FC1_DIR_FROMDS:
+		qdf_mem_copy(eth_hdr->dest_addr, wh.i_addr1,
+			     IEEE80211_ADDR_LEN);
+		qdf_mem_copy(eth_hdr->src_addr, wh.i_addr3, IEEE80211_ADDR_LEN);
+		break;
+	case IEEE80211_FC1_DIR_DSTODS:
+		break;
+	}
+
+	qdf_mem_copy(eth_hdr->ethertype, llchdr.ethertype,
+		     sizeof(llchdr.ethertype));
+
+	ol_rx_defrag_push_rx_desc(msdu, rx_desc_old_position,
+					  ind_old_position, rx_desc_len);
+}
+
+/*
+ * Handling QOS for defragmentation
+ */
+void
+ol_rx_defrag_qos_decap(ol_txrx_pdev_handle pdev,
+		       qdf_nbuf_t nbuf, uint16_t hdrlen)
+{
+	struct ieee80211_frame *wh;
+	uint16_t qoslen;
+	void *rx_desc_old_position = NULL;
+	void *ind_old_position = NULL;
+	int rx_desc_len = 0;
+
+	ol_rx_frag_desc_adjust(pdev,
+			       nbuf,
+			       &rx_desc_old_position,
+			       &ind_old_position, &rx_desc_len);
+
+	wh = (struct ieee80211_frame *)(qdf_nbuf_data(nbuf) + rx_desc_len);
+	if (DEFRAG_IEEE80211_QOS_HAS_SEQ(wh)) {
+		qoslen = sizeof(struct ieee80211_qoscntl);
+		/* Qos frame with Order bit set indicates a HTC frame */
+		if (wh->i_fc[1] & IEEE80211_FC1_ORDER)
+			qoslen += sizeof(struct ieee80211_htc);
+
+		/* remove QoS filed from header */
+		hdrlen -= qoslen;
+		qdf_mem_move((uint8_t *) wh + qoslen, wh, hdrlen);
+		wh = (struct ieee80211_frame *)qdf_nbuf_pull_head(nbuf,
+								  rx_desc_len +
+								  qoslen);
+		/* clear QoS bit */
+		/*
+		 * KW# 6154 'qdf_nbuf_pull_head' in turn calls
+		 * __qdf_nbuf_pull_head,
+		 * which returns NULL if there is not sufficient data to pull.
+		 * It's guaranteed that qdf_nbuf_pull_head will succeed rather
+		 * than returning NULL, since the entire rx frame is already
+		 * present in the rx buffer.
+		 * However, to make it obvious to static analyzers that this
+		 * code is safe, add an explicit check that qdf_nbuf_pull_head
+		 * returns a non-NULL value.
+		 * Since this part of the code is not performance-critical,
+		 * adding this explicit check is okay.
+		 */
+		if (wh)
+			wh->i_fc[0] &= ~IEEE80211_FC0_SUBTYPE_QOS;
+
+		ol_rx_defrag_push_rx_desc(nbuf, rx_desc_old_position,
+					  ind_old_position, rx_desc_len);
+
+	}
+}
diff --git a/core/dp/txrx/ol_rx_defrag.h b/core/dp/txrx/ol_rx_defrag.h
new file mode 100644
index 0000000..66b672d
--- /dev/null
+++ b/core/dp/txrx/ol_rx_defrag.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2011-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.
+ */
+
+#ifndef _OL_RX_DEFRAG_H_
+#define _OL_RX_DEFRAG_H_
+
+#include <qdf_nbuf.h>
+#include <cds_ieee80211_common.h>
+#include <qdf_util.h>
+#include <qdf_types.h>
+#include <qdf_mem.h>
+#include <ol_txrx_internal.h>
+#include <ol_txrx_dbg.h>
+
+#define DEFRAG_IEEE80211_ADDR_LEN    6
+#define DEFRAG_IEEE80211_KEY_LEN     8
+#define DEFRAG_IEEE80211_FCS_LEN     4
+
+struct ol_rx_defrag_cipher {
+	const char *ic_name;
+	uint16_t ic_header;
+	uint8_t ic_trailer;
+	uint8_t ic_miclen;
+};
+
+enum {
+	OL_RX_DEFRAG_ERR,
+	OL_RX_DEFRAG_OK,
+	OL_RX_DEFRAG_PN_ERR
+};
+
+#define ol_rx_defrag_copydata(buf, offset, len, _to) \
+	qdf_nbuf_copy_bits(buf, offset, len, _to)
+
+#define ol_rx_defrag_len(buf) \
+	qdf_nbuf_len(buf)
+
+void
+ol_rx_fraglist_insert(htt_pdev_handle htt_pdev,
+		      qdf_nbuf_t *head_addr,
+		      qdf_nbuf_t *tail_addr,
+		      qdf_nbuf_t frag, uint8_t *all_frag_present);
+
+void ol_rx_defrag_waitlist_add(struct ol_txrx_peer_t *peer, unsigned int tid);
+
+void ol_rx_defrag_waitlist_remove(struct ol_txrx_peer_t *peer,
+				  unsigned int tid);
+
+void ol_rx_defrag_waitlist_flush(struct ol_txrx_pdev_t *pdev);
+
+void
+ol_rx_defrag(ol_txrx_pdev_handle pdev,
+	     struct ol_txrx_peer_t *peer, unsigned int tid,
+	     qdf_nbuf_t frag_list);
+
+int
+ol_rx_frag_tkip_decap(ol_txrx_pdev_handle pdev,
+		      qdf_nbuf_t msdu, uint16_t hdrlen);
+
+int
+ol_rx_frag_wep_decap(ol_txrx_pdev_handle pdev,
+		     qdf_nbuf_t nbuf, uint16_t hdrlen);
+
+void ol_rx_defrag_nwifi_to_8023(ol_txrx_pdev_handle pdev, qdf_nbuf_t msdu);
+
+void
+ol_rx_defrag_qos_decap(ol_txrx_pdev_handle pdev,
+		       qdf_nbuf_t nbuf, uint16_t hdrlen);
+
+int
+ol_rx_frag_tkip_demic(ol_txrx_pdev_handle pdev,
+		      const uint8_t *key, qdf_nbuf_t msdu, uint16_t hdrlen);
+
+int
+ol_rx_frag_ccmp_decap(ol_txrx_pdev_handle pdev,
+		      qdf_nbuf_t nbuf, uint16_t hdrlen);
+
+int
+ol_rx_frag_ccmp_demic(ol_txrx_pdev_handle pdev,
+		      qdf_nbuf_t wbuf, uint16_t hdrlen);
+
+uint16_t ol_rx_frag_hdrsize(const void *data);
+
+void ol_rx_defrag_michdr(const struct ieee80211_frame *wh0, uint8_t hdr[]);
+
+void
+ol_rx_reorder_store_frag(ol_txrx_pdev_handle pdev,
+			 struct ol_txrx_peer_t *peer,
+			 unsigned int tid, uint16_t seq_num, qdf_nbuf_t frag);
+
+qdf_nbuf_t
+ol_rx_defrag_decap_recombine(htt_pdev_handle htt_pdev,
+			     qdf_nbuf_t frag_list, uint16_t hdrsize);
+
+int
+ol_rx_defrag_mic(ol_txrx_pdev_handle pdev,
+		 const uint8_t *key,
+		 qdf_nbuf_t wbuf,
+		 uint16_t off, uint16_t data_len, uint8_t mic[]);
+
+void
+ol_rx_reorder_flush_frag(htt_pdev_handle htt_pdev,
+			 struct ol_txrx_peer_t *peer,
+			 unsigned int tid, uint16_t seq_num);
+
+static inline void xor_block(uint8_t *b, const uint8_t *a, qdf_size_t len)
+{
+	qdf_size_t i;
+
+	for (i = 0; i < len; i++)
+		b[i] ^= a[i];
+}
+
+static inline uint32_t rotl(uint32_t val, int bits)
+{
+	return (val << bits) | (val >> (32 - bits));
+}
+
+static inline uint32_t rotr(uint32_t val, int bits)
+{
+	return (val >> bits) | (val << (32 - bits));
+}
+
+static inline uint32_t xswap(uint32_t val)
+{
+	return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
+}
+
+static inline uint32_t
+get_le32_split(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3)
+{
+	return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
+}
+
+static inline uint32_t get_le32(const uint8_t *p)
+{
+	return get_le32_split(p[0], p[1], p[2], p[3]);
+}
+
+static inline void put_le32(uint8_t *p, uint32_t v)
+{
+	p[0] = (v) & 0xff;
+	p[1] = (v >> 8) & 0xff;
+	p[2] = (v >> 16) & 0xff;
+	p[3] = (v >> 24) & 0xff;
+}
+
+static inline uint8_t ol_rx_defrag_concat(qdf_nbuf_t dst, qdf_nbuf_t src)
+{
+	/*
+	 * Inside qdf_nbuf_cat, if it is necessary to reallocate dst
+	 * to provide space for src, the headroom portion is copied from
+	 * the original dst buffer to the larger new dst buffer.
+	 * (This is needed, because the headroom of the dst buffer
+	 * contains the rx desc.)
+	 */
+	if (qdf_nbuf_cat(dst, src))
+		return OL_RX_DEFRAG_ERR;
+
+	/* Free source buffer */
+	qdf_nbuf_free(src);
+
+	return OL_RX_DEFRAG_OK;
+}
+
+#define michael_block(l, r)	\
+	do {					\
+		r ^= rotl(l, 17);	\
+		l += r;				\
+		r ^= xswap(l);		\
+		l += r;				\
+		r ^= rotl(l, 3);	\
+		l += r;				\
+		r ^= rotr(l, 2);	\
+		l += r;				\
+	} while (0)
+
+#endif
diff --git a/core/dp/txrx/ol_rx_fwd.c b/core/dp/txrx/ol_rx_fwd.c
new file mode 100644
index 0000000..f33db74
--- /dev/null
+++ b/core/dp/txrx/ol_rx_fwd.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2011, 2014-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.
+ */
+
+/* standard header files */
+#include <qdf_nbuf.h>           /* qdf_nbuf_map */
+#include <qdf_mem.h>         /* qdf_mem_cmp */
+
+/* external header files */
+#include <ol_cfg.h>                 /* wlan_op_mode_ap, etc. */
+#include <ol_htt_rx_api.h>          /* htt_rx_msdu_desc_retrieve */
+#include <cds_ieee80211_common.h>   /* ieee80211_frame, etc. */
+
+/* internal header files */
+#include <ol_rx_fwd.h>          /* our own defs */
+#include <ol_rx.h>              /* ol_rx_deliver */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT1 */
+#include <ol_tx.h>
+#include <ol_txrx.h>
+
+/*
+ * Porting from Ap11PrepareForwardedPacket.
+ * This routine is called when a RX data frame from an associated station is
+ * to be forwarded to another associated station. We will prepare the
+ * received packet so that it is suitable for transmission again.
+ * Check that this Packet is suitable for forwarding. If yes, then
+ * prepare the new 802.11 header.
+ */
+static inline void ol_ap_fwd_check(struct ol_txrx_vdev_t *vdev, qdf_nbuf_t msdu)
+{
+	struct ieee80211_frame *mac_header;
+	unsigned char tmp_addr[IEEE80211_ADDR_LEN];
+	unsigned char type;
+	unsigned char subtype;
+	unsigned char fromds;
+	unsigned char tods;
+
+	mac_header = (struct ieee80211_frame *)(qdf_nbuf_data(msdu));
+	TXRX_ASSERT1(mac_header);
+
+	type = mac_header->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+	subtype = mac_header->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+	tods = mac_header->i_fc[1] & IEEE80211_FC1_DIR_TODS;
+	fromds = mac_header->i_fc[1] & IEEE80211_FC1_DIR_FROMDS;
+
+	/*
+	 * Make sure no QOS or any other non-data subtype
+	 * Should be a ToDs data frame.
+	 * Make sure that this frame is unicast and not for us.
+	 * These packets should come up through the normal rx path and
+	 * not forwarded.
+	 */
+	if (type != IEEE80211_FC0_TYPE_DATA ||
+	    subtype != 0x0 ||
+	    ((tods != 1) || (fromds != 0)) ||
+	    qdf_mem_cmp
+		     (mac_header->i_addr3, vdev->mac_addr.raw,
+		     IEEE80211_ADDR_LEN)) {
+		ol_txrx_dbg("Exit: %s | Unnecessary to adjust mac header\n",
+			   __func__);
+	} else {
+		/* Flip the ToDs bit to FromDs */
+		mac_header->i_fc[1] &= 0xfe;
+		mac_header->i_fc[1] |= 0x2;
+
+		/*
+		 * Flip the addresses
+		 * (ToDs, addr1, RA=BSSID) move to (FrDs, addr2, TA=BSSID)
+		 * (ToDs, addr2, SA) move to (FrDs, addr3, SA)
+		 * (ToDs, addr3, DA) move to (FrDs, addr1, DA)
+		 */
+
+		memcpy(tmp_addr, mac_header->i_addr2, sizeof(tmp_addr));
+
+		memcpy(mac_header->i_addr2,
+		       mac_header->i_addr1, sizeof(tmp_addr));
+
+		memcpy(mac_header->i_addr1,
+		       mac_header->i_addr3, sizeof(tmp_addr));
+
+		memcpy(mac_header->i_addr3, tmp_addr, sizeof(tmp_addr));
+	}
+}
+
+static inline void ol_rx_fwd_to_tx(struct ol_txrx_vdev_t *vdev, qdf_nbuf_t msdu)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+
+	if (pdev->frame_format == wlan_frm_fmt_native_wifi)
+		ol_ap_fwd_check(vdev, msdu);
+
+	/*
+	 * Map the netbuf, so it's accessible to the DMA that
+	 * sends it to the target.
+	 */
+	qdf_nbuf_set_next(msdu, NULL);  /* add NULL terminator */
+
+	/* for HL, point to payload before send to tx again.*/
+		if (pdev->cfg.is_high_latency) {
+			void *rx_desc;
+
+			rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev,
+							    msdu);
+			qdf_nbuf_pull_head(msdu,
+				htt_rx_msdu_rx_desc_size_hl(pdev->htt_pdev,
+							    rx_desc));
+		}
+
+	/* Clear the msdu control block as it will be re-interpreted */
+	qdf_mem_set(msdu->cb, sizeof(msdu->cb), 0);
+	/* update any cb field expected by OL_TX_SEND */
+
+	msdu = OL_TX_SEND(vdev, msdu);
+
+	if (msdu) {
+		/*
+		 * The frame was not accepted by the tx.
+		 * We could store the frame and try again later,
+		 * but the simplest solution is to discard the frames.
+		 */
+		qdf_nbuf_tx_free(msdu, QDF_NBUF_PKT_ERROR);
+	}
+}
+
+void
+ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev,
+		struct ol_txrx_peer_t *peer,
+		unsigned int tid, qdf_nbuf_t msdu_list)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	qdf_nbuf_t deliver_list_head = NULL;
+	qdf_nbuf_t deliver_list_tail = NULL;
+	qdf_nbuf_t msdu;
+
+	msdu = msdu_list;
+	while (msdu) {
+		struct ol_txrx_vdev_t *tx_vdev;
+		void *rx_desc;
+		/*
+		 * Remember the next list elem, because our processing
+		 * may cause the MSDU to get linked into a different list.
+		 */
+		msdu_list = qdf_nbuf_next(msdu);
+
+		rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, msdu);
+
+		if (!vdev->disable_intrabss_fwd &&
+		    htt_rx_msdu_forward(pdev->htt_pdev, rx_desc)) {
+			/*
+			 * Use the same vdev that received the frame to
+			 * transmit the frame.
+			 * This is exactly what we want for intra-BSS
+			 * forwarding, like STA-to-STA forwarding and
+			 * multicast echo.
+			 * If this is a intra-BSS forwarding case (which is not
+			 * currently supported), then the tx vdev is different
+			 * from the rx vdev.
+			 * On the LL host the vdevs are not actually used
+			 * for tx, so it would still work to use the rx vdev
+			 * rather than the tx vdev.
+			 * For HL, the tx classification searches for the DA
+			 * within the given vdev, so we would want to get the DA
+			 * peer ID from the target, so we can locate
+			 * the tx vdev.
+			 */
+			tx_vdev = vdev;
+			/*
+			 * Copying TID value of RX packet to forwarded
+			 * packet if the tid is other than non qos tid.
+			 * But for non qos tid fill invalid tid so that
+			 * Fw will take care of filling proper tid.
+			 */
+			if (tid != HTT_NON_QOS_TID) {
+				qdf_nbuf_set_tid(msdu, tid);
+			} else {
+				qdf_nbuf_set_tid(msdu,
+						 QDF_NBUF_TX_EXT_TID_INVALID);
+			}
+
+			if (!ol_txrx_fwd_desc_thresh_check(vdev)) {
+				/* Drop the packet*/
+				htt_rx_msdu_desc_free(pdev->htt_pdev, msdu);
+				TXRX_STATS_MSDU_LIST_INCR(
+					pdev, tx.dropped.host_reject, msdu);
+				/* add NULL terminator */
+				qdf_nbuf_set_next(msdu, NULL);
+				qdf_nbuf_tx_free(msdu,
+						 QDF_NBUF_PKT_ERROR);
+				msdu = msdu_list;
+				continue;
+			}
+
+			/*
+			 * This MSDU needs to be forwarded to the tx path.
+			 * Check whether it also needs to be sent to the OS
+			 * shim, in which case we need to make a copy
+			 * (or clone?).
+			 */
+			if (htt_rx_msdu_discard(pdev->htt_pdev, rx_desc)) {
+				htt_rx_msdu_desc_free(pdev->htt_pdev, msdu);
+				ol_rx_fwd_to_tx(tx_vdev, msdu);
+				msdu = NULL;    /* already handled this MSDU */
+				tx_vdev->fwd_tx_packets++;
+				vdev->fwd_rx_packets++;
+				TXRX_STATS_ADD(pdev,
+					 pub.rx.intra_bss_fwd.packets_fwd, 1);
+			} else {
+				qdf_nbuf_t copy;
+
+				copy = qdf_nbuf_copy(msdu);
+				if (copy) {
+					ol_rx_fwd_to_tx(tx_vdev, copy);
+					tx_vdev->fwd_tx_packets++;
+				}
+				TXRX_STATS_ADD(pdev,
+				   pub.rx.intra_bss_fwd.packets_stack_n_fwd, 1);
+			}
+		} else {
+			TXRX_STATS_ADD(pdev,
+				 pub.rx.intra_bss_fwd.packets_stack, 1);
+		}
+		if (msdu) {
+			/* send this frame to the OS */
+			OL_TXRX_LIST_APPEND(deliver_list_head,
+					    deliver_list_tail, msdu);
+		}
+		msdu = msdu_list;
+	}
+	if (deliver_list_head) {
+		/* add NULL terminator */
+		qdf_nbuf_set_next(deliver_list_tail, NULL);
+		if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev)) {
+			ol_rx_in_order_deliver(vdev, peer, tid,
+					       deliver_list_head);
+		} else {
+			ol_rx_deliver(vdev, peer, tid, deliver_list_head);
+		}
+	}
+}
+
+/*
+ * ol_get_intra_bss_fwd_pkts_count() - to get the total tx and rx packets
+ *   that has been forwarded from txrx layer without going to upper layers.
+ * @vdev_id: vdev id
+ * @fwd_tx_packets: pointer to forwarded tx packets count parameter
+ * @fwd_rx_packets: pointer to forwarded rx packets count parameter
+ *
+ * Return: status -> A_OK - success, A_ERROR - failure
+ */
+A_STATUS ol_get_intra_bss_fwd_pkts_count(uint8_t vdev_id,
+		uint64_t *fwd_tx_packets, uint64_t *fwd_rx_packets)
+{
+	struct ol_txrx_vdev_t *vdev = NULL;
+
+	vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
+	if (!vdev)
+		return A_ERROR;
+
+	*fwd_tx_packets = vdev->fwd_tx_packets;
+	*fwd_rx_packets = vdev->fwd_rx_packets;
+	return A_OK;
+}
+
diff --git a/core/dp/txrx/ol_rx_fwd.h b/core/dp/txrx/ol_rx_fwd.h
new file mode 100644
index 0000000..9fc63e7
--- /dev/null
+++ b/core/dp/txrx/ol_rx_fwd.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2011, 2014-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.
+ */
+
+#ifndef _OL_RX_FWD_H_
+#define _OL_RX_FWD_H_
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+
+#include <ol_txrx_api.h>        /* ol_txrx_peer_t, etc. */
+
+qdf_nbuf_t
+ol_rx_fwd_mcast_check_sta(struct ol_txrx_vdev_t *vdev,
+			  struct ol_txrx_peer_t *peer,
+			  qdf_nbuf_t msdu, void *rx_desc, int is_wlan_mcast);
+
+qdf_nbuf_t
+ol_rx_fwd_mcast_check_ap(struct ol_txrx_vdev_t *vdev,
+			 struct ol_txrx_peer_t *peer,
+			 qdf_nbuf_t msdu, void *rx_desc, int is_wlan_mcast);
+
+/**
+ * @brief Check if rx frames should be transmitted over WLAN.
+ * @details
+ *  Check if rx frames should be transmitted back over WLAN, instead of
+ *  or in addition to delivering the rx frames to the OS.
+ *  Rx frames will be forwarded to the transmit path under the following
+ *  conditions:
+ *  1.  If the destination is a STA associated to the same virtual device
+ *      within this physical device, the rx frame will be forwarded to the
+ *      tx path rather than being sent to the OS.  If the destination is a
+ *      STA associated to a different virtual device within this physical
+ *      device, then the rx frame will optionally be forwarded to the tx path.
+ *  2.  If the frame is received by an AP, but the destination is for another
+ *      AP that the current AP is associated with for WDS forwarding, the
+ *      intermediate AP will forward the rx frame to the tx path to transmit
+ *      to send to the destination AP, rather than sending it to the OS.
+ *  3.  If the AP receives a multicast frame, it will retransmit the frame
+ *      within the BSS, in addition to sending the frame to the OS.
+ *
+ * @param vdev - which virtual device the frames were addressed to
+ * @param peer - which peer the rx frames belong to
+ * @param tid  - which TID within the peer the rx frames belong to
+ * @param msdu_list - NULL-terminated list of MSDUs to perform the rx->tx
+ *      forwarding check on
+ */
+void
+ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev,
+		struct ol_txrx_peer_t *peer,
+		unsigned int tid, qdf_nbuf_t msdu_list);
+
+A_STATUS
+ol_get_intra_bss_fwd_pkts_count(
+	uint8_t vdev_id,
+	uint64_t *fwd_tx_packets,
+	uint64_t *fwd_rx_packets);
+
+#endif /* _OL_RX_FWD_H_ */
diff --git a/core/dp/txrx/ol_rx_pn.c b/core/dp/txrx/ol_rx_pn.c
new file mode 100644
index 0000000..dd09c3f
--- /dev/null
+++ b/core/dp/txrx/ol_rx_pn.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2011, 2013-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.
+ */
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+
+#include <ol_htt_rx_api.h>      /* htt_rx_pn_t, etc. */
+#include <ol_ctrl_txrx_api.h>   /* ol_rx_err */
+
+#include <ol_txrx_internal.h>   /* ol_rx_mpdu_list_next */
+#include <ol_rx_pn.h>           /* our own defs */
+#include <ol_rx_fwd.h>          /* ol_rx_fwd_check */
+#include <ol_rx.h>              /* ol_rx_deliver */
+
+/* add the MSDUs from this MPDU to the list of good frames */
+#define ADD_MPDU_TO_LIST(head, tail, mpdu, mpdu_tail) do {		\
+		if (!head) {						\
+			head = mpdu;					\
+		} else {						\
+			qdf_nbuf_set_next(tail, mpdu);			\
+		}							\
+		tail = mpdu_tail;					\
+	} while (0)
+
+int ol_rx_pn_cmp24(union htt_rx_pn_t *new_pn,
+		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
+{
+	int rc = ((new_pn->pn24 & 0xffffff) <= (old_pn->pn24 & 0xffffff));
+	return rc;
+}
+
+int ol_rx_pn_cmp48(union htt_rx_pn_t *new_pn,
+		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
+{
+	int rc = ((new_pn->pn48 & 0xffffffffffffULL) <=
+		  (old_pn->pn48 & 0xffffffffffffULL));
+	return rc;
+}
+
+int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn,
+		      union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
+{
+	int pn_is_replay = 0;
+
+	if (new_pn->pn128[1] == old_pn->pn128[1])
+		pn_is_replay = (new_pn->pn128[0] <= old_pn->pn128[0]);
+	else
+		pn_is_replay = (new_pn->pn128[1] < old_pn->pn128[1]);
+
+	if (is_unicast) {
+		if (opmode == wlan_op_mode_ap)
+			pn_is_replay |= ((new_pn->pn128[0] & 0x1ULL) != 0);
+		else
+			pn_is_replay |= ((new_pn->pn128[0] & 0x1ULL) != 1);
+	}
+	return pn_is_replay;
+}
+
+qdf_nbuf_t
+ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev,
+		    struct ol_txrx_peer_t *peer,
+		    unsigned int tid, qdf_nbuf_t msdu_list)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	union htt_rx_pn_t *last_pn;
+	qdf_nbuf_t out_list_head = NULL;
+	qdf_nbuf_t out_list_tail = NULL;
+	qdf_nbuf_t mpdu;
+	int index;              /* unicast vs. multicast */
+	int pn_len;
+	void *rx_desc;
+	int last_pn_valid;
+
+	/* Make sure host pn check is not redundant */
+	if ((qdf_atomic_read(&peer->fw_pn_check)) ||
+		(vdev->opmode == wlan_op_mode_ibss)) {
+		return msdu_list;
+	}
+
+	/* First, check whether the PN check applies */
+	rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, msdu_list);
+	qdf_assert(htt_rx_msdu_has_wlan_mcast_flag(pdev->htt_pdev, rx_desc));
+	index = htt_rx_msdu_is_wlan_mcast(pdev->htt_pdev, rx_desc) ?
+		txrx_sec_mcast : txrx_sec_ucast;
+	pn_len = pdev->rx_pn[peer->security[index].sec_type].len;
+	if (pn_len == 0)
+		return msdu_list;
+
+	last_pn_valid = peer->tids_last_pn_valid[tid];
+	last_pn = &peer->tids_last_pn[tid];
+	mpdu = msdu_list;
+	while (mpdu) {
+		qdf_nbuf_t mpdu_tail, next_mpdu;
+		union htt_rx_pn_t new_pn;
+		int pn_is_replay = 0;
+
+		rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, mpdu);
+
+		/*
+		 * Find the last MSDU within this MPDU, and
+		 * the find the first MSDU within the next MPDU.
+		 */
+		ol_rx_mpdu_list_next(pdev, mpdu, &mpdu_tail, &next_mpdu);
+
+		/* Don't check the PN replay for non-encrypted frames */
+		if (!htt_rx_mpdu_is_encrypted(pdev->htt_pdev, rx_desc)) {
+			ADD_MPDU_TO_LIST(out_list_head, out_list_tail,
+					       mpdu, mpdu_tail);
+			mpdu = next_mpdu;
+			continue;
+		}
+
+		/* retrieve PN from rx descriptor */
+		htt_rx_mpdu_desc_pn(pdev->htt_pdev, rx_desc, &new_pn, pn_len);
+
+		/* if there was no prior PN, there's nothing to check */
+		if (last_pn_valid) {
+			pn_is_replay =
+				pdev->rx_pn[peer->security[index].sec_type].
+				cmp(&new_pn, last_pn, index == txrx_sec_ucast,
+				    vdev->opmode);
+		} else {
+			last_pn_valid = peer->tids_last_pn_valid[tid] = 1;
+		}
+
+		if (pn_is_replay) {
+			qdf_nbuf_t msdu;
+			static uint32_t last_pncheck_print_time /* = 0 */;
+			uint32_t current_time_ms;
+
+			/*
+			 * This MPDU failed the PN check:
+			 * 1.  notify the control SW of the PN failure
+			 *     (so countermeasures can be taken, if necessary)
+			 * 2.  Discard all the MSDUs from this MPDU.
+			 */
+			msdu = mpdu;
+			current_time_ms =
+				qdf_system_ticks_to_msecs(qdf_system_ticks());
+			if (TXRX_PN_CHECK_FAILURE_PRINT_PERIOD_MS <
+			    (current_time_ms - last_pncheck_print_time)) {
+				last_pncheck_print_time = current_time_ms;
+				ol_txrx_warn(
+				   "PN check failed - TID %d, peer %pK "
+				   "(%02x:%02x:%02x:%02x:%02x:%02x) %s\n"
+				   "    old PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n"
+				   "    new PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n"
+				   "    new seq num = %d\n",
+				   tid, peer,
+				   peer->mac_addr.raw[0], peer->mac_addr.raw[1],
+				   peer->mac_addr.raw[2], peer->mac_addr.raw[3],
+				   peer->mac_addr.raw[4], peer->mac_addr.raw[5],
+				   (index ==
+				    txrx_sec_ucast) ? "ucast" : "mcast",
+				   last_pn->pn128[1], last_pn->pn128[0],
+				   last_pn->pn128[0] & 0xffffffffffffULL,
+				   new_pn.pn128[1], new_pn.pn128[0],
+				   new_pn.pn128[0] & 0xffffffffffffULL,
+				   htt_rx_mpdu_desc_seq_num(pdev->htt_pdev,
+							    rx_desc));
+			} else {
+				ol_txrx_dbg(
+				   "PN check failed - TID %d, peer %pK "
+				   "(%02x:%02x:%02x:%02x:%02x:%02x) %s\n"
+				   "    old PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n"
+				   "    new PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n"
+				   "    new seq num = %d\n",
+				   tid, peer,
+				   peer->mac_addr.raw[0], peer->mac_addr.raw[1],
+				   peer->mac_addr.raw[2], peer->mac_addr.raw[3],
+				   peer->mac_addr.raw[4], peer->mac_addr.raw[5],
+				   (index ==
+				    txrx_sec_ucast) ? "ucast" : "mcast",
+				   last_pn->pn128[1], last_pn->pn128[0],
+				   last_pn->pn128[0] & 0xffffffffffffULL,
+				   new_pn.pn128[1], new_pn.pn128[0],
+				   new_pn.pn128[0] & 0xffffffffffffULL,
+				   htt_rx_mpdu_desc_seq_num(pdev->htt_pdev,
+							    rx_desc));
+			}
+#if defined(ENABLE_RX_PN_TRACE)
+			ol_rx_pn_trace_display(pdev, 1);
+#endif /* ENABLE_RX_PN_TRACE */
+			ol_rx_err(pdev->ctrl_pdev,
+				  vdev->vdev_id, peer->mac_addr.raw, tid,
+				  htt_rx_mpdu_desc_tsf32(pdev->htt_pdev,
+							 rx_desc), OL_RX_ERR_PN,
+				  mpdu, NULL, 0);
+			/* free all MSDUs within this MPDU */
+			do {
+				qdf_nbuf_t next_msdu;
+
+				OL_RX_ERR_STATISTICS_1(pdev, vdev, peer,
+						       rx_desc, OL_RX_ERR_PN);
+				next_msdu = qdf_nbuf_next(msdu);
+				htt_rx_desc_frame_free(pdev->htt_pdev, msdu);
+				if (msdu == mpdu_tail)
+					break;
+				msdu = next_msdu;
+			} while (1);
+		} else {
+			ADD_MPDU_TO_LIST(out_list_head, out_list_tail,
+					       mpdu, mpdu_tail);
+			/*
+			 * Remember the new PN.
+			 * For simplicity, just do 2 64-bit word copies to
+			 * cover the worst case (WAPI), regardless of the length
+			 * of the PN.
+			 * This is more efficient than doing a conditional
+			 * branch to copy only the relevant portion.
+
+			 * IWNCOM AP will send 1 packet with old PN after USK
+			 * rekey, don't update last_pn when recv the packet, or
+			 * PN check failed for later packets
+			 */
+			if ((peer->security[index].sec_type
+				== htt_sec_type_wapi) &&
+			    (peer->tids_rekey_flag[tid] == 1) &&
+			    (index == txrx_sec_ucast)) {
+				peer->tids_rekey_flag[tid] = 0;
+			} else {
+				last_pn->pn128[0] = new_pn.pn128[0];
+				last_pn->pn128[1] = new_pn.pn128[1];
+				OL_RX_PN_TRACE_ADD(pdev, peer, tid, rx_desc);
+			}
+		}
+
+		mpdu = next_mpdu;
+	}
+	/* make sure the list is null-terminated */
+	if (out_list_tail)
+		qdf_nbuf_set_next(out_list_tail, NULL);
+
+	return out_list_head;
+}
+
+void
+ol_rx_pn_check(struct ol_txrx_vdev_t *vdev,
+	       struct ol_txrx_peer_t *peer, unsigned int tid,
+	       qdf_nbuf_t msdu_list)
+{
+	msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list);
+	ol_rx_fwd_check(vdev, peer, tid, msdu_list);
+}
+
+void
+ol_rx_pn_check_only(struct ol_txrx_vdev_t *vdev,
+		    struct ol_txrx_peer_t *peer,
+		    unsigned int tid, qdf_nbuf_t msdu_list)
+{
+	msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list);
+	ol_rx_deliver(vdev, peer, tid, msdu_list);
+}
+
+#if defined(ENABLE_RX_PN_TRACE)
+
+A_STATUS ol_rx_pn_trace_attach(ol_txrx_pdev_handle pdev)
+{
+	int num_elems;
+
+	num_elems = 1 << TXRX_RX_PN_TRACE_SIZE_LOG2;
+	pdev->rx_pn_trace.idx = 0;
+	pdev->rx_pn_trace.cnt = 0;
+	pdev->rx_pn_trace.mask = num_elems - 1;
+	pdev->rx_pn_trace.data =
+		qdf_mem_malloc(sizeof(*pdev->rx_pn_trace.data) * num_elems);
+	if (!pdev->rx_pn_trace.data)
+		return A_NO_MEMORY;
+	return A_OK;
+}
+
+void ol_rx_pn_trace_detach(ol_txrx_pdev_handle pdev)
+{
+	qdf_mem_free(pdev->rx_pn_trace.data);
+}
+
+void
+ol_rx_pn_trace_add(struct ol_txrx_pdev_t *pdev,
+		   struct ol_txrx_peer_t *peer, uint16_t tid, void *rx_desc)
+{
+	uint32_t idx = pdev->rx_pn_trace.idx;
+	union htt_rx_pn_t pn;
+	uint32_t pn32;
+	uint16_t seq_num;
+	uint8_t unicast;
+
+	htt_rx_mpdu_desc_pn(pdev->htt_pdev, rx_desc, &pn, 48);
+	pn32 = pn.pn48 & 0xffffffff;
+	seq_num = htt_rx_mpdu_desc_seq_num(pdev->htt_pdev, rx_desc);
+	unicast = !htt_rx_msdu_is_wlan_mcast(pdev->htt_pdev, rx_desc);
+
+	pdev->rx_pn_trace.data[idx].peer = peer;
+	pdev->rx_pn_trace.data[idx].tid = tid;
+	pdev->rx_pn_trace.data[idx].seq_num = seq_num;
+	pdev->rx_pn_trace.data[idx].unicast = unicast;
+	pdev->rx_pn_trace.data[idx].pn32 = pn32;
+	pdev->rx_pn_trace.cnt++;
+	idx++;
+	pdev->rx_pn_trace.idx = idx & pdev->rx_pn_trace.mask;
+}
+
+void ol_rx_pn_trace_display(ol_txrx_pdev_handle pdev, int just_once)
+{
+	static int print_count /* = 0 */;
+	uint32_t i, start, end;
+	uint64_t cnt;
+	int elems;
+	int limit = 0;          /* move this to the arg list? */
+
+	if (print_count != 0 && just_once)
+		return;
+
+	print_count++;
+
+	end = pdev->rx_pn_trace.idx;
+	if (pdev->rx_pn_trace.cnt <= pdev->rx_pn_trace.mask) {
+		/* trace log has not yet wrapped around - start at the top */
+		start = 0;
+		cnt = 0;
+	} else {
+		start = end;
+		cnt = pdev->rx_pn_trace.cnt - (pdev->rx_pn_trace.mask + 1);
+	}
+	elems = (end - 1 - start) & pdev->rx_pn_trace.mask;
+	if (limit > 0 && elems > limit) {
+		int delta;
+
+		delta = elems - limit;
+		start += delta;
+		start &= pdev->rx_pn_trace.mask;
+		cnt += delta;
+	}
+
+	i = start;
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		  "                                 seq     PN");
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		  "   count  idx    peer   tid uni  num    LSBs");
+	do {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+			  "  %6lld %4d  %pK %2d   %d %4d %8d",
+			  cnt, i,
+			  pdev->rx_pn_trace.data[i].peer,
+			  pdev->rx_pn_trace.data[i].tid,
+			  pdev->rx_pn_trace.data[i].unicast,
+			  pdev->rx_pn_trace.data[i].seq_num,
+			  pdev->rx_pn_trace.data[i].pn32);
+		cnt++;
+		i++;
+		i &= pdev->rx_pn_trace.mask;
+	} while (i != end);
+}
+#endif /* ENABLE_RX_PN_TRACE */
diff --git a/core/dp/txrx/ol_rx_pn.h b/core/dp/txrx/ol_rx_pn.h
new file mode 100644
index 0000000..8e0c007
--- /dev/null
+++ b/core/dp/txrx/ol_rx_pn.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011, 2014-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.
+ */
+
+#ifndef _OL_RX_PN_H_
+#define _OL_RX_PN_H_
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+
+#include <ol_txrx_api.h>        /* ol_txrx_peer_t, etc. */
+
+int ol_rx_pn_cmp24(union htt_rx_pn_t *new_pn,
+		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode);
+
+int ol_rx_pn_cmp48(union htt_rx_pn_t *new_pn,
+		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode);
+
+int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn,
+		      union htt_rx_pn_t *old_pn, int is_unicast, int opmode);
+
+/**
+ * @brief If applicable, check the Packet Number to detect replays.
+ * @details
+ *  Determine whether a PN check is needed, and if so, what the PN size is.
+ *  (A PN size of 0 is used to indirectly bypass the PN check for security
+ *  methods that don't involve a PN check.)
+ *  This function produces event notifications for any PN failures, via the
+ *  ol_rx_err function.
+ *  After the PN check, call the next stage of rx processing (rx --> tx
+ *  forwarding check).
+ *
+ * @param vdev - which virtual device the frames were addressed to
+ * @param peer - which peer the rx frames belong to
+ * @param tid  - which TID within the peer the rx frames belong to
+ * @param msdu_list - NULL-terminated list of MSDUs to perform PN check on
+ *      (if PN check is applicable, i.e. PN length > 0)
+ */
+void
+ol_rx_pn_check(struct ol_txrx_vdev_t *vdev,
+	       struct ol_txrx_peer_t *peer, unsigned int tid,
+	       qdf_nbuf_t msdu_list);
+
+/**
+ * @brief If applicable, check the Packet Number to detect replays.
+ * @details
+ *  Determine whether a PN check is needed, and if so, what the PN size is.
+ *  (A PN size of 0 is used to indirectly bypass the PN check for security
+ *  methods that don't involve a PN check.)
+ *  This function produces event notifications for any PN failures, via the
+ *  ol_rx_err function.
+ *  After the PN check, deliver the valid rx frames to the OS shim.
+ *  (Don't perform a rx --> tx forwarding check.)
+ *
+ * @param vdev - which virtual device the frames were addressed to
+ * @param peer - which peer the rx frames belong to
+ * @param tid  - which TID within the peer the rx frames belong to
+ * @param msdu_list - NULL-terminated list of MSDUs to perform PN check on
+ *      (if PN check is applicable, i.e. PN length > 0)
+ */
+void
+ol_rx_pn_check_only(struct ol_txrx_vdev_t *vdev,
+		    struct ol_txrx_peer_t *peer,
+		    unsigned int tid, qdf_nbuf_t msdu_list);
+
+/**
+ * @brief If applicable, check the Packet Number to detect replays.
+ * @details
+ *  Same as ol_rx_pn_check but return valid rx netbufs
+ *  rather than invoking the rx --> tx forwarding check.
+ *
+ * @param vdev - which virtual device the frames were addressed to
+ * @param peer - which peer the rx frames belong to
+ * @param tid - which TID within the peer the rx frames belong to
+ * @param msdu_list - NULL-terminated list of MSDUs to perform PN check on
+ *      (if PN check is applicable, i.e. PN length > 0)
+ * @return list of netbufs that didn't fail the PN check
+ */
+qdf_nbuf_t
+ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev,
+		    struct ol_txrx_peer_t *peer,
+		    unsigned int tid, qdf_nbuf_t msdu_list);
+
+#endif /* _OL_RX_PN_H_ */
diff --git a/core/dp/txrx/ol_rx_reorder.c b/core/dp/txrx/ol_rx_reorder.c
new file mode 100644
index 0000000..6335a9e
--- /dev/null
+++ b/core/dp/txrx/ol_rx_reorder.c
@@ -0,0 +1,825 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*=== header file includes ===*/
+/* generic utilities */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_mem.h>         /* qdf_mem_malloc */
+
+/* external interfaces */
+#include <ol_txrx_api.h>        /* ol_txrx_pdev_handle */
+#include <ol_txrx_htt_api.h>    /* ol_rx_addba_handler, etc. */
+#include <ol_ctrl_txrx_api.h>   /* ol_ctrl_rx_addba_complete */
+#include <ol_htt_rx_api.h>      /* htt_rx_desc_frame_free */
+#include <ol_ctrl_txrx_api.h>   /* ol_rx_err */
+
+/* datapath internal interfaces */
+#include <ol_txrx_peer_find.h>  /* ol_txrx_peer_find_by_id */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT */
+#include <ol_rx_reorder_timeout.h>      /* OL_RX_REORDER_TIMEOUT_REMOVE, etc. */
+#include <ol_rx_reorder.h>
+#include <ol_rx_defrag.h>
+
+/*=== data types and defines ===*/
+
+/*---*/
+
+/*=== global variables ===*/
+
+/*---*/
+
+/*=== function definitions ===*/
+
+/*---*/
+
+#define QCA_SUPPORT_RX_REORDER_RELEASE_CHECK 0
+#define OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, idx_start)  /* no-op */
+#define OL_RX_REORDER_IDX_WRAP(idx, win_sz, win_sz_mask) { idx &= win_sz_mask; }
+#define OL_RX_REORDER_IDX_MAX(win_sz, win_sz_mask) win_sz_mask
+#define OL_RX_REORDER_IDX_INIT(seq_num, win_sz, win_sz_mask) 0  /* n/a */
+#define OL_RX_REORDER_NO_HOLES(rx_reorder) 0
+#define OL_RX_REORDER_MPDU_CNT_INCR(rx_reorder, incr)   /* n/a */
+#define OL_RX_REORDER_MPDU_CNT_DECR(rx_reorder, decr)   /* n/a */
+
+/*---*/
+
+/* reorder array elements are known to be non-NULL */
+#define OL_RX_REORDER_LIST_APPEND(head_msdu, tail_msdu, rx_reorder_array_elem) \
+	do {								\
+		if (tail_msdu) {					\
+			qdf_nbuf_set_next(tail_msdu,			\
+					  rx_reorder_array_elem->head); \
+		}							\
+	} while (0)
+
+/* functions called by txrx components */
+
+void ol_rx_reorder_init(struct ol_rx_reorder_t *rx_reorder, uint8_t tid)
+{
+	rx_reorder->win_sz = 1;
+	rx_reorder->win_sz_mask = 0;
+	rx_reorder->array = &rx_reorder->base;
+	rx_reorder->base.head = rx_reorder->base.tail = NULL;
+	rx_reorder->tid = tid;
+	rx_reorder->defrag_timeout_ms = 0;
+
+	rx_reorder->defrag_waitlist_elem.tqe_next = NULL;
+	rx_reorder->defrag_waitlist_elem.tqe_prev = NULL;
+}
+
+static enum htt_rx_status
+ol_rx_reorder_seq_num_check(
+			    struct ol_txrx_pdev_t *pdev,
+			    struct ol_txrx_peer_t *peer,
+			    unsigned int tid, unsigned int seq_num)
+{
+	unsigned int seq_num_delta;
+
+	/* don't check the new seq_num against last_seq
+	   if last_seq is not valid */
+	if (peer->tids_last_seq[tid] == IEEE80211_SEQ_MAX)
+		return htt_rx_status_ok;
+
+	/*
+	 * For duplicate detection, it might be helpful to also check
+	 * whether the retry bit is set or not - a strict duplicate packet
+	 * should be the one with retry bit set.
+	 * However, since many implementations do not set the retry bit,
+	 * and since this same function is also used for filtering out
+	 * late-arriving frames (frames that arive after their rx reorder
+	 * timeout has expired) which are not retries, don't bother checking
+	 * the retry bit for now.
+	 */
+	/* note: if new seq_num == old seq_num, seq_num_delta = 4095 */
+	seq_num_delta = (seq_num - 1 - peer->tids_last_seq[tid]) &
+		(IEEE80211_SEQ_MAX - 1);     /* account for wraparound */
+
+	if (seq_num_delta > (IEEE80211_SEQ_MAX >> 1)) {
+		return htt_rx_status_err_replay;
+		/* or maybe htt_rx_status_err_dup */
+	}
+	return htt_rx_status_ok;
+}
+
+/**
+ * ol_rx_seq_num_check() - Does duplicate detection for mcast packets and
+ *                           duplicate detection & check for out-of-order
+ *                           packets for unicast packets.
+ * @pdev:                        Pointer to pdev maintained by OL
+ * @peer:                        Pointer to peer structure maintained by OL
+ * @tid:                         TID value passed as part of HTT msg by f/w
+ * @rx_mpdu_desc:                Pointer to Rx Descriptor for the given MPDU
+ *
+ *  This function
+ *      1) For Multicast Frames -- does duplicate detection
+ *          A frame is considered duplicate & dropped if it has a seq.number
+ *          which is received twice in succession and with the retry bit set
+ *          in the second case.
+ *          A frame which is older than the last sequence number received
+ *          is not considered duplicate but out-of-order. This function does
+ *          perform out-of-order check for multicast frames, which is in
+ *          keeping with the 802.11 2012 spec section 9.3.2.10
+ *      2) For Unicast Frames -- does duplicate detection & out-of-order check
+ *          only for non-aggregation tids.
+ *
+ * Return:        Returns htt_rx_status_err_replay, if packet needs to be
+ *                dropped, htt_rx_status_ok otherwise.
+ */
+enum htt_rx_status
+ol_rx_seq_num_check(struct ol_txrx_pdev_t *pdev,
+					struct ol_txrx_peer_t *peer,
+					uint8_t tid,
+					void *rx_mpdu_desc)
+{
+	uint16_t pkt_tid = 0xffff;
+	uint16_t seq_num = IEEE80211_SEQ_MAX;
+	bool retry = 0;
+
+	seq_num = htt_rx_mpdu_desc_seq_num(pdev->htt_pdev, rx_mpdu_desc);
+
+	 /* For mcast packets, we only the dup-detection, not re-order check */
+
+	if (qdf_unlikely(OL_RX_MCAST_TID == tid)) {
+
+		pkt_tid = htt_rx_mpdu_desc_tid(pdev->htt_pdev, rx_mpdu_desc);
+
+		/* Invalid packet TID, expected only for HL */
+		/* Pass the packet on */
+		if (qdf_unlikely(pkt_tid >= OL_TXRX_NUM_EXT_TIDS))
+			return htt_rx_status_ok;
+
+		retry = htt_rx_mpdu_desc_retry(pdev->htt_pdev, rx_mpdu_desc);
+
+		/*
+		 * At this point, we define frames to be duplicate if they
+		 * arrive "ONLY" in succession with the same sequence number
+		 * and the last one has the retry bit set. For an older frame,
+		 * we consider that as an out of order frame, and hence do not
+		 * perform the dup-detection or out-of-order check for multicast
+		 * frames as per discussions & spec.
+		 * Hence "seq_num <= last_seq_num" check is not necessary.
+		 */
+		if (qdf_unlikely(retry &&
+			(seq_num == peer->tids_mcast_last_seq[pkt_tid]))) {
+			/* drop mcast */
+			TXRX_STATS_INCR(pdev, priv.rx.err.msdu_mc_dup_drop);
+			return htt_rx_status_err_replay;
+		}
+
+		/*
+		 * This is a multicast packet likely to be passed on...
+		 * Set the mcast last seq number here
+		 * This is fairly accurate since:
+		 * a) f/w sends multicast as separate PPDU/HTT messages
+		 * b) Mcast packets are not aggregated & hence single
+		 * c) Result of b) is that, flush / release bit is set
+		 *    always on the mcast packets, so likely to be
+		 *    immediatedly released.
+		 */
+		peer->tids_mcast_last_seq[pkt_tid] = seq_num;
+		return htt_rx_status_ok;
+	} else
+		return ol_rx_reorder_seq_num_check(pdev, peer, tid, seq_num);
+}
+
+
+void
+ol_rx_reorder_store(struct ol_txrx_pdev_t *pdev,
+		    struct ol_txrx_peer_t *peer,
+		    unsigned int tid,
+		    unsigned int idx, qdf_nbuf_t head_msdu,
+		    qdf_nbuf_t tail_msdu)
+{
+	struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
+
+	idx &= peer->tids_rx_reorder[tid].win_sz_mask;
+	rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx];
+	if (rx_reorder_array_elem->head) {
+		qdf_nbuf_set_next(rx_reorder_array_elem->tail, head_msdu);
+	} else {
+		rx_reorder_array_elem->head = head_msdu;
+		OL_RX_REORDER_MPDU_CNT_INCR(&peer->tids_rx_reorder[tid], 1);
+	}
+	rx_reorder_array_elem->tail = tail_msdu;
+}
+
+void
+ol_rx_reorder_release(struct ol_txrx_vdev_t *vdev,
+		      struct ol_txrx_peer_t *peer,
+		      unsigned int tid, unsigned int idx_start,
+		      unsigned int idx_end)
+{
+	unsigned int idx;
+	unsigned int win_sz, win_sz_mask;
+	struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
+	qdf_nbuf_t head_msdu;
+	qdf_nbuf_t tail_msdu;
+
+	OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, &idx_start);
+	/* may get reset below */
+	peer->tids_next_rel_idx[tid] = (uint16_t) idx_end;
+
+	win_sz = peer->tids_rx_reorder[tid].win_sz;
+	win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask;
+	idx_start &= win_sz_mask;
+	idx_end &= win_sz_mask;
+	rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx_start];
+
+	head_msdu = rx_reorder_array_elem->head;
+	tail_msdu = rx_reorder_array_elem->tail;
+	rx_reorder_array_elem->head = rx_reorder_array_elem->tail = NULL;
+	if (head_msdu)
+		OL_RX_REORDER_MPDU_CNT_DECR(&peer->tids_rx_reorder[tid], 1);
+
+	idx = (idx_start + 1);
+	OL_RX_REORDER_IDX_WRAP(idx, win_sz, win_sz_mask);
+	while (idx != idx_end) {
+		rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx];
+		if (rx_reorder_array_elem->head) {
+			OL_RX_REORDER_MPDU_CNT_DECR(&peer->tids_rx_reorder[tid],
+						    1);
+			OL_RX_REORDER_LIST_APPEND(head_msdu, tail_msdu,
+						  rx_reorder_array_elem);
+			tail_msdu = rx_reorder_array_elem->tail;
+		}
+		rx_reorder_array_elem->head = rx_reorder_array_elem->tail =
+						      NULL;
+		idx++;
+		OL_RX_REORDER_IDX_WRAP(idx, win_sz, win_sz_mask);
+	}
+	if (head_msdu) {
+		uint16_t seq_num;
+		htt_pdev_handle htt_pdev = vdev->pdev->htt_pdev;
+
+		/*
+		 * This logic is not quite correct - the last_seq value should
+		 * be the sequence number of the final MPDU released rather than
+		 * the initial MPDU released.
+		 * However, tracking the sequence number of the first MPDU in
+		 * the released batch works well enough:
+		 * For Peregrine and Rome, the last_seq is checked only for
+		 * non-aggregate cases, where only one MPDU at a time is
+		 * released.
+		 * For Riva, Pronto, and Northstar, the last_seq is checked to
+		 * filter out late-arriving rx frames, whose sequence number
+		 * will be less than the first MPDU in this release batch.
+		 */
+		seq_num = htt_rx_mpdu_desc_seq_num(
+			htt_pdev,
+			htt_rx_msdu_desc_retrieve(htt_pdev,
+						  head_msdu));
+		peer->tids_last_seq[tid] = seq_num;
+		/* rx_opt_proc takes a NULL-terminated list of msdu netbufs */
+		qdf_nbuf_set_next(tail_msdu, NULL);
+		peer->rx_opt_proc(vdev, peer, tid, head_msdu);
+	}
+	/*
+	 * If the rx reorder timeout is handled by host SW rather than the
+	 * target's rx reorder logic, then stop the timer here.
+	 * (If there are remaining rx holes, then the timer will be restarted.)
+	 */
+	OL_RX_REORDER_TIMEOUT_REMOVE(peer, tid);
+}
+
+void
+ol_rx_reorder_flush(struct ol_txrx_vdev_t *vdev,
+		    struct ol_txrx_peer_t *peer,
+		    unsigned int tid,
+		    unsigned int idx_start,
+		    unsigned int idx_end, enum htt_rx_flush_action action)
+{
+	struct ol_txrx_pdev_t *pdev;
+	unsigned int win_sz;
+	uint8_t win_sz_mask;
+	struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
+	qdf_nbuf_t head_msdu = NULL;
+	qdf_nbuf_t tail_msdu = NULL;
+
+	pdev = vdev->pdev;
+	win_sz = peer->tids_rx_reorder[tid].win_sz;
+	win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask;
+
+	OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, &idx_start);
+	/* a idx_end value of 0xffff means to flush the entire array */
+	if (idx_end == 0xffff) {
+		idx_end = idx_start;
+		/*
+		 * The array is being flushed in entirety because the block
+		 * ack window has been shifted to a new position that does not
+		 * overlap with the old position.  (Or due to reception of a
+		 * DELBA.)
+		 * Thus, since the block ack window is essentially being reset,
+		 * reset the "next release index".
+		 */
+		peer->tids_next_rel_idx[tid] =
+			OL_RX_REORDER_IDX_INIT(0 /*n/a */, win_sz, win_sz_mask);
+	} else {
+		peer->tids_next_rel_idx[tid] = (uint16_t) idx_end;
+	}
+
+	idx_start &= win_sz_mask;
+	idx_end &= win_sz_mask;
+
+	do {
+		rx_reorder_array_elem =
+			&peer->tids_rx_reorder[tid].array[idx_start];
+		idx_start = (idx_start + 1);
+		OL_RX_REORDER_IDX_WRAP(idx_start, win_sz, win_sz_mask);
+
+		if (rx_reorder_array_elem->head) {
+			OL_RX_REORDER_MPDU_CNT_DECR(&peer->tids_rx_reorder[tid],
+						    1);
+			if (head_msdu == NULL) {
+				head_msdu = rx_reorder_array_elem->head;
+				tail_msdu = rx_reorder_array_elem->tail;
+				rx_reorder_array_elem->head = NULL;
+				rx_reorder_array_elem->tail = NULL;
+				continue;
+			}
+			qdf_nbuf_set_next(tail_msdu,
+					  rx_reorder_array_elem->head);
+			tail_msdu = rx_reorder_array_elem->tail;
+			rx_reorder_array_elem->head =
+				rx_reorder_array_elem->tail = NULL;
+		}
+	} while (idx_start != idx_end);
+
+	ol_rx_defrag_waitlist_remove(peer, tid);
+
+	if (head_msdu) {
+		uint16_t seq_num;
+		htt_pdev_handle htt_pdev = vdev->pdev->htt_pdev;
+
+		seq_num = htt_rx_mpdu_desc_seq_num(
+			htt_pdev,
+			htt_rx_msdu_desc_retrieve(htt_pdev, head_msdu));
+		peer->tids_last_seq[tid] = seq_num;
+		/* rx_opt_proc takes a NULL-terminated list of msdu netbufs */
+		qdf_nbuf_set_next(tail_msdu, NULL);
+		if (action == htt_rx_flush_release) {
+			peer->rx_opt_proc(vdev, peer, tid, head_msdu);
+		} else {
+			do {
+				qdf_nbuf_t next;
+
+				next = qdf_nbuf_next(head_msdu);
+				htt_rx_desc_frame_free(pdev->htt_pdev,
+						       head_msdu);
+				head_msdu = next;
+			} while (head_msdu);
+		}
+	}
+	/*
+	 * If the rx reorder array is empty, then reset the last_seq value -
+	 * it is likely that a BAR or a sequence number shift caused the
+	 * sequence number to jump, so the old last_seq value is not relevant.
+	 */
+	if (OL_RX_REORDER_NO_HOLES(&peer->tids_rx_reorder[tid]))
+		peer->tids_last_seq[tid] = IEEE80211_SEQ_MAX;   /* invalid */
+
+	OL_RX_REORDER_TIMEOUT_REMOVE(peer, tid);
+}
+
+void
+ol_rx_reorder_first_hole(struct ol_txrx_peer_t *peer,
+			 unsigned int tid, unsigned int *idx_end)
+{
+	unsigned int win_sz, win_sz_mask;
+	unsigned int idx_start = 0, tmp_idx = 0;
+
+	win_sz = peer->tids_rx_reorder[tid].win_sz;
+	win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask;
+
+	OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, &idx_start);
+	tmp_idx++;
+	OL_RX_REORDER_IDX_WRAP(tmp_idx, win_sz, win_sz_mask);
+	/* bypass the initial hole */
+	while (tmp_idx != idx_start &&
+	       !peer->tids_rx_reorder[tid].array[tmp_idx].head) {
+		tmp_idx++;
+		OL_RX_REORDER_IDX_WRAP(tmp_idx, win_sz, win_sz_mask);
+	}
+	/* bypass the present frames following the initial hole */
+	while (tmp_idx != idx_start &&
+	       peer->tids_rx_reorder[tid].array[tmp_idx].head) {
+		tmp_idx++;
+		OL_RX_REORDER_IDX_WRAP(tmp_idx, win_sz, win_sz_mask);
+	}
+	/*
+	 * idx_end is exclusive rather than inclusive.
+	 * In other words, it is the index of the first slot of the second
+	 * hole, rather than the index of the final present frame following
+	 * the first hole.
+	 */
+	*idx_end = tmp_idx;
+}
+
+#ifdef HL_RX_AGGREGATION_HOLE_DETECTION
+
+/**
+ * ol_rx_reorder_detect_hole - ol rx reorder detect hole
+ * @peer: ol_txrx_peer_t
+ * @tid: tid
+ * @idx_start: idx_start
+ *
+ * Return: void
+ */
+static void ol_rx_reorder_detect_hole(struct ol_txrx_peer_t *peer,
+					uint32_t tid,
+					uint32_t idx_start)
+{
+	uint32_t win_sz_mask, next_rel_idx, hole_size;
+
+	if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+		ol_txrx_err("%s:  invalid tid, %u\n", __FUNCTION__, tid);
+		return;
+	}
+
+	if (peer->tids_next_rel_idx[tid] == INVALID_REORDER_INDEX)
+		return;
+
+	win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask;
+	/* Return directly if block-ack not enable */
+	if (win_sz_mask == 0)
+		return;
+
+	idx_start &= win_sz_mask;
+	next_rel_idx = peer->tids_next_rel_idx[tid] & win_sz_mask;
+
+	if (idx_start != next_rel_idx) {
+		hole_size = ((int)idx_start - (int)next_rel_idx) & win_sz_mask;
+
+		ol_rx_aggregation_hole(hole_size);
+	}
+
+	return;
+}
+
+#else
+
+/**
+ * ol_rx_reorder_detect_hole - ol rx reorder detect hole
+ * @peer: ol_txrx_peer_t
+ * @tid: tid
+ * @idx_start: idx_start
+ *
+ * Return: void
+ */
+static void ol_rx_reorder_detect_hole(struct ol_txrx_peer_t *peer,
+					uint32_t tid,
+					uint32_t idx_start)
+{
+	/* no-op */
+}
+
+#endif
+
+void
+ol_rx_reorder_peer_cleanup(struct ol_txrx_vdev_t *vdev,
+			   struct ol_txrx_peer_t *peer)
+{
+	int tid;
+
+	for (tid = 0; tid < OL_TXRX_NUM_EXT_TIDS; tid++) {
+		ol_rx_reorder_flush(vdev, peer, tid, 0, 0,
+				    htt_rx_flush_discard);
+	}
+	OL_RX_REORDER_TIMEOUT_PEER_CLEANUP(peer);
+}
+
+/* functions called by HTT */
+
+void
+ol_rx_flush_handler(ol_txrx_pdev_handle pdev,
+		    uint16_t peer_id,
+		    uint8_t tid,
+		    uint16_t idx_start,
+		    uint16_t idx_end, enum htt_rx_flush_action action)
+{
+	struct ol_txrx_vdev_t *vdev = NULL;
+	void *rx_desc;
+	struct ol_txrx_peer_t *peer;
+	int idx;
+	struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+
+	if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+		ol_txrx_err("%s:  invalid tid, %u\n", __FUNCTION__, tid);
+		return;
+	}
+
+	peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+	if (peer)
+		vdev = peer->vdev;
+	else
+		return;
+
+	OL_RX_REORDER_TIMEOUT_MUTEX_LOCK(pdev);
+
+	idx = idx_start & peer->tids_rx_reorder[tid].win_sz_mask;
+	rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx];
+	if (rx_reorder_array_elem->head) {
+		rx_desc =
+			htt_rx_msdu_desc_retrieve(htt_pdev,
+						  rx_reorder_array_elem->head);
+		if (htt_rx_msdu_is_frag(htt_pdev, rx_desc)) {
+			ol_rx_reorder_flush_frag(htt_pdev, peer, tid,
+						 idx_start);
+			/*
+			 * Assuming flush message sent separately for frags
+			 * and for normal frames
+			 */
+			OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev);
+			return;
+		}
+	}
+
+	if (action == htt_rx_flush_release)
+		ol_rx_reorder_detect_hole(peer, tid, idx_start);
+
+	ol_rx_reorder_flush(vdev, peer, tid, idx_start, idx_end, action);
+	/*
+	 * If the rx reorder timeout is handled by host SW, see if there are
+	 * remaining rx holes that require the timer to be restarted.
+	 */
+	OL_RX_REORDER_TIMEOUT_UPDATE(peer, tid);
+	OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev);
+}
+
+void
+ol_rx_pn_ind_handler(ol_txrx_pdev_handle pdev,
+		     uint16_t peer_id,
+		     uint8_t tid,
+		     uint16_t seq_num_start,
+		     uint16_t seq_num_end, uint8_t pn_ie_cnt, uint8_t *pn_ie)
+{
+	struct ol_txrx_vdev_t *vdev = NULL;
+	void *rx_desc;
+	struct ol_txrx_peer_t *peer;
+	struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
+	unsigned int win_sz_mask;
+	qdf_nbuf_t head_msdu = NULL;
+	qdf_nbuf_t tail_msdu = NULL;
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+	uint16_t seq_num;
+	int i = 0;
+
+	if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+		ol_txrx_err("%s:  invalid tid, %u\n", __FUNCTION__, tid);
+		WARN_ON(1);
+		return;
+	}
+	peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+
+	if (!peer) {
+		/*
+		 * If we can't find a peer send this packet to OCB interface
+		 * using OCB self peer
+		 */
+		if (!ol_txrx_get_ocb_peer(pdev, &peer))
+			peer = NULL;
+	}
+
+	if (peer)
+		vdev = peer->vdev;
+	else
+		return;
+
+	qdf_atomic_set(&peer->fw_pn_check, 1);
+	/*TODO: Fragmentation case */
+	win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask;
+	seq_num_start &= win_sz_mask;
+	seq_num_end &= win_sz_mask;
+	seq_num = seq_num_start;
+
+	do {
+		rx_reorder_array_elem =
+			&peer->tids_rx_reorder[tid].array[seq_num];
+
+		if (rx_reorder_array_elem->head) {
+			if (pn_ie_cnt && seq_num == (int)(pn_ie[i])) {
+				qdf_nbuf_t msdu, next_msdu, mpdu_head,
+					   mpdu_tail;
+				static uint32_t last_pncheck_print_time;
+				/* Do not need to initialize as C does it */
+
+				uint32_t current_time_ms;
+				union htt_rx_pn_t pn = { 0 };
+				int index, pn_len;
+
+				mpdu_head = msdu = rx_reorder_array_elem->head;
+				mpdu_tail = rx_reorder_array_elem->tail;
+
+				pn_ie_cnt--;
+				i++;
+				rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev,
+								    msdu);
+				index = htt_rx_msdu_is_wlan_mcast(
+					pdev->htt_pdev, rx_desc)
+					? txrx_sec_mcast
+					: txrx_sec_ucast;
+				pn_len = pdev->rx_pn[peer->security[index].
+						     sec_type].len;
+				htt_rx_mpdu_desc_pn(htt_pdev, rx_desc, &pn,
+						    pn_len);
+
+				current_time_ms = qdf_system_ticks_to_msecs(
+					qdf_system_ticks());
+				if (TXRX_PN_CHECK_FAILURE_PRINT_PERIOD_MS <
+				    (current_time_ms -
+				     last_pncheck_print_time)) {
+					last_pncheck_print_time =
+						current_time_ms;
+					ol_txrx_warn(
+					   "Tgt PN check failed - TID %d, peer %pK "
+					   "(%02x:%02x:%02x:%02x:%02x:%02x)\n"
+					   "    PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n"
+					   "    new seq num = %d\n",
+					   tid, peer,
+					   peer->mac_addr.raw[0],
+					   peer->mac_addr.raw[1],
+					   peer->mac_addr.raw[2],
+					   peer->mac_addr.raw[3],
+					   peer->mac_addr.raw[4],
+					   peer->mac_addr.raw[5], pn.pn128[1],
+					   pn.pn128[0],
+					   pn.pn128[0] & 0xffffffffffffULL,
+					   htt_rx_mpdu_desc_seq_num(htt_pdev,
+								    rx_desc));
+				} else {
+					ol_txrx_dbg(
+					   "Tgt PN check failed - TID %d, peer %pK "
+					   "(%02x:%02x:%02x:%02x:%02x:%02x)\n"
+					   "    PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n"
+					   "    new seq num = %d\n",
+					   tid, peer,
+					   peer->mac_addr.raw[0],
+					   peer->mac_addr.raw[1],
+					   peer->mac_addr.raw[2],
+					   peer->mac_addr.raw[3],
+					   peer->mac_addr.raw[4],
+					   peer->mac_addr.raw[5], pn.pn128[1],
+					   pn.pn128[0],
+					   pn.pn128[0] & 0xffffffffffffULL,
+					   htt_rx_mpdu_desc_seq_num(htt_pdev,
+								    rx_desc));
+				}
+				ol_rx_err(pdev->ctrl_pdev, vdev->vdev_id,
+					  peer->mac_addr.raw, tid,
+					  htt_rx_mpdu_desc_tsf32(htt_pdev,
+								 rx_desc),
+					  OL_RX_ERR_PN, mpdu_head, NULL, 0);
+
+				/* free all MSDUs within this MPDU */
+				do {
+					next_msdu = qdf_nbuf_next(msdu);
+					htt_rx_desc_frame_free(htt_pdev, msdu);
+					if (msdu == mpdu_tail)
+						break;
+					msdu = next_msdu;
+				} while (1);
+
+			} else {
+				if (head_msdu == NULL) {
+					head_msdu = rx_reorder_array_elem->head;
+					tail_msdu = rx_reorder_array_elem->tail;
+				} else {
+					qdf_nbuf_set_next(
+						tail_msdu,
+						rx_reorder_array_elem->head);
+					tail_msdu = rx_reorder_array_elem->tail;
+				}
+			}
+			rx_reorder_array_elem->head = NULL;
+			rx_reorder_array_elem->tail = NULL;
+		}
+		seq_num = (seq_num + 1) & win_sz_mask;
+	} while (seq_num != seq_num_end);
+
+	if (head_msdu) {
+		/* rx_opt_proc takes a NULL-terminated list of msdu netbufs */
+		qdf_nbuf_set_next(tail_msdu, NULL);
+		peer->rx_opt_proc(vdev, peer, tid, head_msdu);
+	}
+}
+
+#if defined(ENABLE_RX_REORDER_TRACE)
+
+A_STATUS ol_rx_reorder_trace_attach(ol_txrx_pdev_handle pdev)
+{
+	int num_elems;
+
+	num_elems = 1 << TXRX_RX_REORDER_TRACE_SIZE_LOG2;
+	pdev->rx_reorder_trace.idx = 0;
+	pdev->rx_reorder_trace.cnt = 0;
+	pdev->rx_reorder_trace.mask = num_elems - 1;
+	pdev->rx_reorder_trace.data = qdf_mem_malloc(
+		sizeof(*pdev->rx_reorder_trace.data) * num_elems);
+	if (!pdev->rx_reorder_trace.data)
+		return A_NO_MEMORY;
+
+	while (--num_elems >= 0)
+		pdev->rx_reorder_trace.data[num_elems].seq_num = 0xffff;
+
+	return A_OK;
+}
+
+void ol_rx_reorder_trace_detach(ol_txrx_pdev_handle pdev)
+{
+	qdf_mem_free(pdev->rx_reorder_trace.data);
+}
+
+void
+ol_rx_reorder_trace_add(ol_txrx_pdev_handle pdev,
+			uint8_t tid,
+			uint16_t reorder_idx, uint16_t seq_num, int num_mpdus)
+{
+	uint32_t idx = pdev->rx_reorder_trace.idx;
+
+	pdev->rx_reorder_trace.data[idx].tid = tid;
+	pdev->rx_reorder_trace.data[idx].reorder_idx = reorder_idx;
+	pdev->rx_reorder_trace.data[idx].seq_num = seq_num;
+	pdev->rx_reorder_trace.data[idx].num_mpdus = num_mpdus;
+	pdev->rx_reorder_trace.cnt++;
+	idx++;
+	pdev->rx_reorder_trace.idx = idx & pdev->rx_reorder_trace.mask;
+}
+
+void
+ol_rx_reorder_trace_display(ol_txrx_pdev_handle pdev, int just_once, int limit)
+{
+	static int print_count;
+	uint32_t i, start, end;
+	uint64_t cnt;
+	int elems;
+
+	if (print_count != 0 && just_once)
+		return;
+
+	print_count++;
+
+	end = pdev->rx_reorder_trace.idx;
+	if (pdev->rx_reorder_trace.data[end].seq_num == 0xffff) {
+		/* trace log has not yet wrapped around - start at the top */
+		start = 0;
+		cnt = 0;
+	} else {
+		start = end;
+		cnt = pdev->rx_reorder_trace.cnt -
+			(pdev->rx_reorder_trace.mask + 1);
+	}
+	elems = (end - 1 - start) & pdev->rx_reorder_trace.mask;
+	if (limit > 0 && elems > limit) {
+		int delta;
+
+		delta = elems - limit;
+		start += delta;
+		start &= pdev->rx_reorder_trace.mask;
+		cnt += delta;
+	}
+
+	i = start;
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		  "           log       array seq");
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		  "   count   idx  tid   idx  num (LSBs)");
+	do {
+		uint16_t seq_num, reorder_idx;
+
+		seq_num = pdev->rx_reorder_trace.data[i].seq_num;
+		reorder_idx = pdev->rx_reorder_trace.data[i].reorder_idx;
+		if (seq_num < (1 << 14)) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+				  "  %6lld  %4d  %3d  %4d  %4d (%d)",
+				  cnt, i, pdev->rx_reorder_trace.data[i].tid,
+				  reorder_idx, seq_num, seq_num & 63);
+		} else {
+			int err = TXRX_SEQ_NUM_ERR(seq_num);
+
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+				  "  %6lld  %4d err %d (%d MPDUs)",
+				  cnt, i, err,
+				  pdev->rx_reorder_trace.data[i].num_mpdus);
+		}
+		cnt++;
+		i++;
+		i &= pdev->rx_reorder_trace.mask;
+	} while (i != end);
+}
+
+#endif /* ENABLE_RX_REORDER_TRACE */
diff --git a/core/dp/txrx/ol_rx_reorder.h b/core/dp/txrx/ol_rx_reorder.h
new file mode 100644
index 0000000..fa64010
--- /dev/null
+++ b/core/dp/txrx/ol_rx_reorder.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011, 2014-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.
+ */
+
+#ifndef _OL_RX_REORDER__H_
+#define _OL_RX_REORDER__H_
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+
+#include <ol_txrx_api.h>        /* ol_txrx_peer_t, etc. */
+
+#include <ol_txrx_types.h>      /* ol_rx_reorder_t */
+
+void
+ol_rx_reorder_store(struct ol_txrx_pdev_t *pdev,
+		    struct ol_txrx_peer_t *peer,
+		    unsigned int tid,
+		    unsigned int reorder_array_index,
+		    qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu);
+
+void
+ol_rx_reorder_release(struct ol_txrx_vdev_t *vdev,
+		      struct ol_txrx_peer_t *peer,
+		      unsigned int tid,
+		      unsigned int seq_num_start, unsigned int seq_num_end);
+
+void
+ol_rx_reorder_flush(struct ol_txrx_vdev_t *vdev,
+		    struct ol_txrx_peer_t *peer,
+		    unsigned int tid,
+		    unsigned int seq_num_start,
+		    unsigned int seq_num_end, enum htt_rx_flush_action action);
+
+/**
+ * @brief - find end of first range of present MPDUs after the initial rx hole
+ * @param[in] peer - which sender's data is being checked
+ * @param[in] tid - which type of data is being checked
+ * @param[out] idx_end - the reorder array index holding the last MPDU in the
+ *      range of in-order MPDUs that following the initial hole.
+ *      Note that this is the index of the last in-order MPDU following the
+ *      first hole, rather than the starting index of the second hole.
+ */
+void
+ol_rx_reorder_first_hole(struct ol_txrx_peer_t *peer,
+			 unsigned int tid, unsigned int *idx_end);
+
+void
+ol_rx_reorder_peer_cleanup(struct ol_txrx_vdev_t *vdev,
+			   struct ol_txrx_peer_t *peer);
+
+void ol_rx_reorder_init(struct ol_rx_reorder_t *rx_reorder, uint8_t tid);
+
+enum htt_rx_status
+ol_rx_seq_num_check(struct ol_txrx_pdev_t *pdev,
+			    struct ol_txrx_peer_t *peer,
+			    uint8_t tid, void *rx_mpdu_desc);
+
+/*
+ * Peregrine and Rome: do sequence number checking in the host
+ * for peer-TIDs without aggregation enabled
+ */
+
+#define OL_RX_SEQ_NUM_CHECK(pdev, peer, tid, rx_mpdu_desc)	\
+	(pdev->rx.flags.dup_check && peer->tids_rx_reorder[tid].win_sz_mask == \
+	0) ? ol_rx_seq_num_check(pdev, peer, tid, rx_mpdu_desc) : \
+	htt_rx_status_ok
+
+#endif /* _OL_RX_REORDER__H_ */
diff --git a/core/dp/txrx/ol_rx_reorder_timeout.c b/core/dp/txrx/ol_rx_reorder_timeout.c
new file mode 100644
index 0000000..487b140
--- /dev/null
+++ b/core/dp/txrx/ol_rx_reorder_timeout.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*=== header file includes ===*/
+/* generic utilities */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_timer.h>
+#include <qdf_time.h>
+
+/* datapath internal interfaces */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT, etc. */
+#include <ol_rx_reorder.h>      /* ol_rx_reorder_flush, etc. */
+#include <ol_rx_reorder_timeout.h>
+
+#ifdef QCA_SUPPORT_OL_RX_REORDER_TIMEOUT
+
+void ol_rx_reorder_timeout_remove(struct ol_txrx_peer_t *peer, unsigned int tid)
+{
+	struct ol_txrx_pdev_t *pdev;
+	struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac;
+	struct ol_rx_reorder_timeout_list_elem_t *list_elem;
+	int ac;
+
+	pdev = peer->vdev->pdev;
+	ac = TXRX_TID_TO_WMM_AC(tid);
+	rx_reorder_timeout_ac = &pdev->rx.reorder_timeout.access_cats[ac];
+	list_elem = &peer->tids_rx_reorder[tid].timeout;
+	if (!list_elem->active) {
+		/* this element has already been removed */
+		return;
+	}
+	list_elem->active = 0;
+	TAILQ_REMOVE(&rx_reorder_timeout_ac->virtual_timer_list, list_elem,
+		     reorder_timeout_list_elem);
+}
+
+static void
+ol_rx_reorder_timeout_start(struct ol_tx_reorder_cat_timeout_t
+			    *rx_reorder_timeout_ac, uint32_t time_now_ms)
+{
+	uint32_t duration_ms;
+	struct ol_rx_reorder_timeout_list_elem_t *list_elem;
+
+	list_elem = TAILQ_FIRST(&rx_reorder_timeout_ac->virtual_timer_list);
+
+	duration_ms = list_elem->timestamp_ms - time_now_ms;
+	qdf_timer_start(&rx_reorder_timeout_ac->timer, duration_ms);
+}
+
+static inline void
+ol_rx_reorder_timeout_add(struct ol_txrx_peer_t *peer, uint8_t tid)
+{
+	uint32_t time_now_ms;
+	struct ol_txrx_pdev_t *pdev;
+	struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac;
+	struct ol_rx_reorder_timeout_list_elem_t *list_elem;
+	int ac;
+	int start;
+
+	pdev = peer->vdev->pdev;
+	ac = TXRX_TID_TO_WMM_AC(tid);
+	rx_reorder_timeout_ac = &pdev->rx.reorder_timeout.access_cats[ac];
+	list_elem = &peer->tids_rx_reorder[tid].timeout;
+
+	list_elem->active = 1;
+	list_elem->peer = peer;
+	list_elem->tid = tid;
+
+	/* set the expiration timestamp */
+	time_now_ms = qdf_system_ticks_to_msecs(qdf_system_ticks());
+	list_elem->timestamp_ms =
+		time_now_ms + rx_reorder_timeout_ac->duration_ms;
+
+	/* add to the queue */
+	start = TAILQ_EMPTY(&rx_reorder_timeout_ac->virtual_timer_list);
+	TAILQ_INSERT_TAIL(&rx_reorder_timeout_ac->virtual_timer_list,
+			  list_elem, reorder_timeout_list_elem);
+	if (start)
+		ol_rx_reorder_timeout_start(rx_reorder_timeout_ac, time_now_ms);
+}
+
+void ol_rx_reorder_timeout_update(struct ol_txrx_peer_t *peer, uint8_t tid)
+{
+	if (!peer)
+		return;
+
+	/*
+	 * If there are no holes, i.e. no queued frames,
+	 * then timeout doesn't apply.
+	 */
+	if (peer->tids_rx_reorder[tid].num_mpdus == 0)
+		return;
+
+	/*
+	 * If the virtual timer for this peer-TID is already running,
+	 * then leave it.
+	 */
+	if (peer->tids_rx_reorder[tid].timeout.active)
+		return;
+
+	ol_rx_reorder_timeout_add(peer, tid);
+}
+
+static void ol_rx_reorder_timeout(void *arg)
+{
+	struct ol_txrx_pdev_t *pdev;
+	struct ol_rx_reorder_timeout_list_elem_t *list_elem, *tmp;
+	uint32_t time_now_ms;
+	struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac;
+
+	rx_reorder_timeout_ac = (struct ol_tx_reorder_cat_timeout_t *)arg;
+	time_now_ms = qdf_system_ticks_to_msecs(qdf_system_ticks());
+
+	pdev = rx_reorder_timeout_ac->pdev;
+	qdf_spin_lock(&pdev->rx.mutex);
+/* TODO: conditionally take mutex lock during regular rx */
+	TAILQ_FOREACH_SAFE(list_elem,
+			   &rx_reorder_timeout_ac->virtual_timer_list,
+			   reorder_timeout_list_elem, tmp) {
+		unsigned int idx_start, idx_end;
+		struct ol_txrx_peer_t *peer;
+
+		if (list_elem->timestamp_ms > time_now_ms)
+			break;  /* time has not expired yet for this element */
+
+		list_elem->active = 0;
+		/* remove the expired element from the list */
+		TAILQ_REMOVE(&rx_reorder_timeout_ac->virtual_timer_list,
+			     list_elem, reorder_timeout_list_elem);
+
+		peer = list_elem->peer;
+
+		idx_start = 0xffff;     /* start from next_rel_idx */
+		ol_rx_reorder_first_hole(peer, list_elem->tid, &idx_end);
+		ol_rx_reorder_flush(peer->vdev,
+				    peer,
+				    list_elem->tid,
+				    idx_start, idx_end, htt_rx_flush_release);
+	}
+	/* restart the timer if unexpired elements are left in the list */
+	if (!TAILQ_EMPTY(&rx_reorder_timeout_ac->virtual_timer_list))
+		ol_rx_reorder_timeout_start(rx_reorder_timeout_ac, time_now_ms);
+
+	qdf_spin_unlock(&pdev->rx.mutex);
+}
+
+void ol_rx_reorder_timeout_init(struct ol_txrx_pdev_t *pdev)
+{
+	int i;
+
+	for (i = 0; i < QDF_ARRAY_SIZE(pdev->rx.reorder_timeout.access_cats);
+		i++) {
+		struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac;
+
+		rx_reorder_timeout_ac =
+			&pdev->rx.reorder_timeout.access_cats[i];
+		/* init the per-AC timers */
+		qdf_timer_init(pdev->osdev,
+				       &rx_reorder_timeout_ac->timer,
+				       ol_rx_reorder_timeout,
+				       rx_reorder_timeout_ac,
+				       QDF_TIMER_TYPE_SW);
+		/* init the virtual timer list */
+		TAILQ_INIT(&rx_reorder_timeout_ac->virtual_timer_list);
+		rx_reorder_timeout_ac->pdev = pdev;
+	}
+	pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_VO].duration_ms = 40;
+	pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_VI].duration_ms = 100;
+	pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_BE].duration_ms = 100;
+	pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_BK].duration_ms = 100;
+}
+
+void ol_rx_reorder_timeout_peer_cleanup(struct ol_txrx_peer_t *peer)
+{
+	int tid;
+
+	for (tid = 0; tid < OL_TXRX_NUM_EXT_TIDS; tid++) {
+		if (peer->tids_rx_reorder[tid].timeout.active)
+			ol_rx_reorder_timeout_remove(peer, tid);
+	}
+}
+
+void ol_rx_reorder_timeout_cleanup(struct ol_txrx_pdev_t *pdev)
+{
+	int i;
+
+	for (i = 0; i < QDF_ARRAY_SIZE(pdev->rx.reorder_timeout.access_cats);
+		i++) {
+		struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac;
+
+		rx_reorder_timeout_ac =
+			&pdev->rx.reorder_timeout.access_cats[i];
+		qdf_timer_stop(&rx_reorder_timeout_ac->timer);
+		qdf_timer_free(&rx_reorder_timeout_ac->timer);
+	}
+}
+
+#endif /* QCA_SUPPORT_OL_RX_REORDER_TIMEOUT */
diff --git a/core/dp/txrx/ol_rx_reorder_timeout.h b/core/dp/txrx/ol_rx_reorder_timeout.h
new file mode 100644
index 0000000..9f09501
--- /dev/null
+++ b/core/dp/txrx/ol_rx_reorder_timeout.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 2014, 2016-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.
+ */
+
+#ifndef _OL_RX_REORDER_TIMEOUT__H_
+#define _OL_RX_REORDER_TIMEOUT__H_
+
+#include <cdp_txrx_cmn.h>       /* ol_txrx_vdev_t, etc. */
+#ifdef QCA_SUPPORT_OL_RX_REORDER_TIMEOUT
+
+void ol_rx_reorder_timeout_init(struct ol_txrx_pdev_t *pdev);
+void ol_rx_reorder_timeout_cleanup(struct ol_txrx_pdev_t *pdev);
+void ol_rx_reorder_timeout_remove(struct ol_txrx_peer_t *peer,
+				  unsigned int tid);
+void ol_rx_reorder_timeout_update(struct ol_txrx_peer_t *peer, uint8_t tid);
+void ol_rx_reorder_timeout_peer_cleanup(struct ol_txrx_peer_t *peer);
+
+#define OL_RX_REORDER_TIMEOUT_INIT    ol_rx_reorder_timeout_init
+#define OL_RX_REORDER_TIMEOUT_PEER_CLEANUP ol_rx_reorder_timeout_peer_cleanup
+#define OL_RX_REORDER_TIMEOUT_CLEANUP ol_rx_reorder_timeout_cleanup
+#define OL_RX_REORDER_TIMEOUT_REMOVE  ol_rx_reorder_timeout_remove
+#define OL_RX_REORDER_TIMEOUT_UPDATE  ol_rx_reorder_timeout_update
+#define OL_RX_REORDER_TIMEOUT_PEER_TID_INIT(peer, tid) \
+	(peer)->tids_rx_reorder[(tid)].timeout.active = 0
+#define OL_RX_REORDER_TIMEOUT_MUTEX_LOCK(pdev) \
+	qdf_spin_lock(&(pdev)->rx.mutex)
+#define OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev) \
+	qdf_spin_unlock(&(pdev)->rx.mutex)
+
+#else
+
+#define OL_RX_REORDER_TIMEOUT_INIT(pdev)        /* no-op */
+#define OL_RX_REORDER_TIMEOUT_PEER_CLEANUP(peer)        /* no-op */
+#define OL_RX_REORDER_TIMEOUT_CLEANUP(pdev)     /* no-op */
+#define OL_RX_REORDER_TIMEOUT_REMOVE(peer, tid) /* no-op */
+#define OL_RX_REORDER_TIMEOUT_UPDATE(peer, tid) /* no-op */
+#define OL_RX_REORDER_TIMEOUT_PEER_TID_INIT(peer, tid)  /* no-op */
+#define OL_RX_REORDER_TIMEOUT_MUTEX_LOCK(pdev)  /* no-op */
+#define OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev)        /* no-op */
+
+#endif /* QCA_SUPPORT_OL_RX_REORDER_TIMEOUT */
+
+#endif /* _OL_RX_REORDER_TIMEOUT__H_ */
diff --git a/core/dp/txrx/ol_tx.c b/core/dp/txrx/ol_tx.c
new file mode 100644
index 0000000..ac48492
--- /dev/null
+++ b/core/dp/txrx/ol_tx.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/* OS abstraction libraries */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_atomic.h>         /* qdf_atomic_read, etc. */
+#include <qdf_util.h>           /* qdf_unlikely */
+
+/* APIs for other modules */
+#include <htt.h>                /* HTT_TX_EXT_TID_MGMT */
+#include <ol_htt_tx_api.h>      /* htt_tx_desc_tid */
+
+/* internal header files relevant for all systems */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT1 */
+#include <ol_tx_desc.h>         /* ol_tx_desc */
+#include <ol_tx_send.h>         /* ol_tx_send */
+#include <ol_txrx.h>
+
+/* internal header files relevant only for HL systems */
+#include <ol_tx_classify.h>   /* ol_tx_classify, ol_tx_classify_mgmt */
+#include <ol_tx_queue.h>        /* ol_tx_enqueue */
+#include <ol_tx_sched.h>      /* ol_tx_sched */
+
+/* internal header files relevant only for specific systems (Pronto) */
+#include <ol_txrx_encap.h>      /* OL_TX_ENCAP, etc */
+#include <ol_tx.h>
+#include <cdp_txrx_ipa.h>
+
+/**
+ * ol_tx_data() - send data frame
+ * @vdev: virtual device handle
+ * @skb: skb
+ *
+ * Return: skb/NULL for success
+ */
+qdf_nbuf_t ol_tx_data(void *data_vdev, qdf_nbuf_t skb)
+{
+	struct ol_txrx_pdev_t *pdev;
+	qdf_nbuf_t ret;
+	ol_txrx_vdev_handle vdev = data_vdev;
+
+	if (qdf_unlikely(!vdev)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s:vdev is null", __func__);
+		return skb;
+	}
+
+	pdev = vdev->pdev;
+
+	if (qdf_unlikely(!pdev)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s:pdev is null", __func__);
+		return skb;
+	}
+
+	if ((ol_cfg_is_ip_tcp_udp_checksum_offload_enabled(pdev->ctrl_pdev))
+		&& (qdf_nbuf_get_protocol(skb) == htons(ETH_P_IP))
+		&& (qdf_nbuf_get_ip_summed(skb) == CHECKSUM_PARTIAL))
+		qdf_nbuf_set_ip_summed(skb, CHECKSUM_COMPLETE);
+
+	/* Terminate the (single-element) list of tx frames */
+	qdf_nbuf_set_next(skb, NULL);
+	ret = OL_TX_SEND(vdev, skb);
+	if (ret) {
+		ol_txrx_dbg("%s: Failed to tx", __func__);
+		return ret;
+	}
+
+	return NULL;
+}
+
+#ifdef IPA_OFFLOAD
+qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	qdf_nbuf_t ret;
+
+	if (qdf_unlikely(!pdev)) {
+		qdf_net_buf_debug_acquire_skb(skb, __FILE__, __LINE__);
+
+		ol_txrx_err("%s: pdev is NULL", __func__);
+		return skb;
+	}
+
+	if ((ol_cfg_is_ip_tcp_udp_checksum_offload_enabled(pdev->ctrl_pdev))
+		&& (qdf_nbuf_get_protocol(skb) == htons(ETH_P_IP))
+		&& (qdf_nbuf_get_ip_summed(skb) == CHECKSUM_PARTIAL))
+		qdf_nbuf_set_ip_summed(skb, CHECKSUM_COMPLETE);
+
+	/* Terminate the (single-element) list of tx frames */
+	qdf_nbuf_set_next(skb, NULL);
+
+	/*
+	 * Add SKB to internal tracking table before further processing
+	 * in WLAN driver.
+	 */
+	qdf_net_buf_debug_acquire_skb(skb, __FILE__, __LINE__);
+
+	ret = OL_TX_SEND((struct ol_txrx_vdev_t *)vdev, skb);
+	if (ret) {
+		ol_txrx_dbg("%s: Failed to tx", __func__);
+		return ret;
+	}
+
+	return NULL;
+}
+#endif
+
+void
+ol_txrx_data_tx_cb_set(struct cdp_vdev *pvdev,
+		       ol_txrx_data_tx_cb callback, void *ctxt)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+
+	pdev->tx_data_callback.func = callback;
+	pdev->tx_data_callback.ctxt = ctxt;
+}
+
+void
+ol_txrx_mgmt_tx_cb_set(struct cdp_pdev *ppdev, uint8_t type,
+		       ol_txrx_mgmt_tx_cb download_cb,
+		       ol_txrx_mgmt_tx_cb ota_ack_cb, void *ctxt)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	TXRX_ASSERT1(type < OL_TXRX_MGMT_NUM_TYPES);
+	pdev->tx_mgmt_cb.download_cb = download_cb;
+	pdev->tx_mgmt_cb.ota_ack_cb = ota_ack_cb;
+	pdev->tx_mgmt_cb.ctxt = ctxt;
+}
+
+int
+ol_txrx_mgmt_send_ext(struct cdp_vdev *pvdev,
+		  qdf_nbuf_t tx_mgmt_frm,
+		  uint8_t type, uint8_t use_6mbps, uint16_t chanfreq)
+{
+	struct ol_txrx_vdev_t *vdev =
+				(struct ol_txrx_vdev_t *)pvdev;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	struct ol_tx_desc_t *tx_desc;
+	struct ol_txrx_msdu_info_t tx_msdu_info;
+	int result = 0;
+
+	tx_msdu_info.tso_info.is_tso = 0;
+
+	tx_msdu_info.htt.action.use_6mbps = use_6mbps;
+	tx_msdu_info.htt.info.ext_tid = HTT_TX_EXT_TID_MGMT;
+	tx_msdu_info.htt.info.vdev_id = vdev->vdev_id;
+	tx_msdu_info.htt.action.do_tx_complete =
+		pdev->tx_mgmt_cb.ota_ack_cb ? 1 : 0;
+
+	/*
+	 * FIX THIS: l2_hdr_type should only specify L2 header type
+	 * The Peregrine/Rome HTT layer provides the FW with a "pkt type"
+	 * that is a combination of L2 header type and 802.11 frame type.
+	 * If the 802.11 frame type is "mgmt", then the HTT pkt type is "mgmt".
+	 * But if the 802.11 frame type is "data", then the HTT pkt type is
+	 * the L2 header type (more or less): 802.3 vs. Native WiFi
+	 * (basic 802.11).
+	 * (Or the header type can be "raw", which is any version of the 802.11
+	 * header, and also implies that some of the offloaded tx data
+	 * processing steps may not apply.)
+	 * For efficiency, the Peregrine/Rome HTT uses the msdu_info's
+	 * l2_hdr_type field to program the HTT pkt type.  Thus, this txrx SW
+	 * needs to overload the l2_hdr_type to indicate whether the frame is
+	 * data vs. mgmt, as well as 802.3 L2 header vs. 802.11 L2 header.
+	 * To fix this, the msdu_info's l2_hdr_type should be left specifying
+	 * just the L2 header type.  For mgmt frames, there should be a
+	 * separate function to patch the HTT pkt type to store a "mgmt" value
+	 * rather than the L2 header type.  Then the HTT pkt type can be
+	 * programmed efficiently for data frames, and the msdu_info's
+	 * l2_hdr_type field won't be confusingly overloaded to hold the 802.11
+	 * frame type rather than the L2 header type.
+	 */
+	/*
+	 * FIX THIS: remove duplication of htt_frm_type_mgmt and
+	 * htt_pkt_type_mgmt
+	 * The htt module expects a "enum htt_pkt_type" value.
+	 * The htt_dxe module expects a "enum htt_frm_type" value.
+	 * This needs to be cleaned up, so both versions of htt use a
+	 * consistent method of specifying the frame type.
+	 */
+#ifdef QCA_SUPPORT_INTEGRATED_SOC
+	/* tx mgmt frames always come with a 802.11 header */
+	tx_msdu_info.htt.info.l2_hdr_type = htt_pkt_type_native_wifi;
+	tx_msdu_info.htt.info.frame_type = htt_frm_type_mgmt;
+#else
+	tx_msdu_info.htt.info.l2_hdr_type = htt_pkt_type_mgmt;
+	tx_msdu_info.htt.info.frame_type = htt_pkt_type_mgmt;
+#endif
+
+	tx_msdu_info.peer = NULL;
+
+	tx_desc = ol_txrx_mgmt_tx_desc_alloc(pdev, vdev, tx_mgmt_frm,
+							&tx_msdu_info);
+	if (!tx_desc)
+		return -EINVAL;       /* can't accept the tx mgmt frame */
+
+	TXRX_STATS_MSDU_INCR(pdev, tx.mgmt, tx_mgmt_frm);
+	TXRX_ASSERT1(type < OL_TXRX_MGMT_NUM_TYPES);
+	tx_desc->pkt_type = type + OL_TXRX_MGMT_TYPE_BASE;
+
+	result = ol_txrx_mgmt_send_frame(vdev, tx_desc, tx_mgmt_frm,
+						&tx_msdu_info, chanfreq);
+
+	return 0;               /* accepted the tx mgmt frame */
+}
diff --git a/core/dp/txrx/ol_tx.h b/core/dp/txrx/ol_tx.h
new file mode 100644
index 0000000..b163e29
--- /dev/null
+++ b/core/dp/txrx/ol_tx.h
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ * @file ol_tx.h
+ * @brief Internal definitions for the high-level tx module.
+ */
+#ifndef _OL_TX__H_
+#define _OL_TX__H_
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <qdf_lock.h>
+#include <cdp_txrx_cmn.h>       /* ol_txrx_vdev_t, etc. */
+#include <cdp_txrx_misc.h>      /* ol_tx_spec */
+#include <cdp_txrx_handle.h>
+#include <ol_txrx_types.h>      /* ol_tx_desc_t, ol_txrx_msdu_info_t */
+#include <hif.h>
+
+#ifdef IPA_OFFLOAD
+/**
+ * ol_tx_send_ipa_data_frame() - send IPA data frame
+ * @vdev: vdev
+ * @skb: skb
+ *
+ * Return: skb/ NULL is for success
+ */
+qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb);
+#endif
+
+#ifdef CONFIG_LL_DP_SUPPORT
+struct ol_tx_desc_t *
+ol_tx_prepare_ll(ol_txrx_vdev_handle vdev,
+		 qdf_nbuf_t msdu,
+		 struct ol_txrx_msdu_info_t *msdu_info);
+#endif
+
+qdf_nbuf_t ol_tx_ll_wrapper(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
+#ifdef WLAN_FEATURE_FASTPATH
+qdf_nbuf_t ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
+
+void ol_tx_setup_fastpath_ce_handles(struct hif_opaque_softc *osc,
+				     struct ol_txrx_pdev_t *pdev);
+#else
+static inline
+void ol_tx_setup_fastpath_ce_handles(struct hif_opaque_softc *osc,
+				     struct ol_txrx_pdev_t *pdev)
+{ }
+
+qdf_nbuf_t ol_tx_ll(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
+#endif
+
+qdf_nbuf_t ol_tx_ll_queue(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
+
+#ifdef CONFIG_HL_SUPPORT
+#define OL_TX_SEND ol_tx_hl
+#else
+#define OL_TX_SEND OL_TX_LL
+#endif
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+#define OL_TX_LL ol_tx_ll_queue
+#else
+#define OL_TX_LL ol_tx_ll_wrapper
+#endif
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+void ol_tx_vdev_ll_pause_queue_send(void *context);
+void ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev);
+#else
+static inline void ol_tx_vdev_ll_pause_queue_send(void *context)
+{
+}
+static inline
+void ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev)
+{
+}
+#endif
+
+static inline
+int ol_txrx_tx_is_raw(enum ol_tx_spec tx_spec)
+{
+	return	tx_spec &
+		(OL_TX_SPEC_RAW | OL_TX_SPEC_NO_AGGR | OL_TX_SPEC_NO_ENCRYPT);
+}
+
+static inline
+uint8_t ol_txrx_tx_raw_subtype(enum ol_tx_spec tx_spec)
+{
+	uint8_t sub_type = 0x1; /* 802.11 MAC header present */
+
+	if (tx_spec & OL_TX_SPEC_NO_AGGR)
+		sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_AGGR_S;
+	if (tx_spec & OL_TX_SPEC_NO_ENCRYPT)
+		sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_S;
+	if (tx_spec & OL_TX_SPEC_NWIFI_NO_ENCRYPT)
+		sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_S;
+	return sub_type;
+}
+
+/**
+ * ol_tx_hl() - transmit tx frames for a HL system.
+ * @vdev: the virtual device transmit the data
+ * @msdu_list: the tx frames to send
+ *
+ * Return: NULL if all MSDUs are accepted
+ */
+qdf_nbuf_t
+ol_tx_hl(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list);
+
+/**
+ * ol_tx_non_std() - Allow the control-path SW to send data frames
+ * @data_vdev: which vdev should transmit the tx data frames
+ * @tx_spec: what non-standard handling to apply to the tx data frames
+ * @msdu_list: NULL-terminated list of tx MSDUs
+ *
+ * Generally, all tx data frames come from the OS shim into the txrx layer.
+ * However, there are rare cases such as TDLS messaging where the UMAC
+ * control-path SW creates tx data frames.
+ *  This UMAC SW can call this function to provide the tx data frames to
+ *  the txrx layer.
+ *  The UMAC SW can request a callback for these data frames after their
+ *  transmission completes, by using the ol_txrx_data_tx_cb_set function
+ *  to register a tx completion callback, and by specifying
+ *  ol_tx_spec_no_free as the tx_spec arg when giving the frames to
+ *  ol_tx_non_std.
+ *  The MSDUs need to have the appropriate L2 header type (802.3 vs. 802.11),
+ *  as specified by ol_cfg_frame_type().
+ *
+ *  Return: null - success, skb - failure
+ */
+#ifdef CONFIG_HL_SUPPORT
+qdf_nbuf_t ol_tx_non_std_hl(struct ol_txrx_vdev_t *vdev,
+			    enum ol_tx_spec tx_spec,
+			    qdf_nbuf_t msdu_list);
+
+static inline qdf_nbuf_t
+ol_tx_non_std(struct cdp_vdev *pvdev,
+	      enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	return ol_tx_non_std_hl(vdev, tx_spec, msdu_list);
+}
+#else
+qdf_nbuf_t ol_tx_non_std_ll(struct ol_txrx_vdev_t *vdev,
+			    enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list);
+
+static inline qdf_nbuf_t
+ol_tx_non_std(struct cdp_vdev *pvdev,
+	      enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	return ol_tx_non_std_ll(vdev, tx_spec, msdu_list);
+}
+#endif
+
+void ol_txrx_mgmt_tx_complete(void *ctxt, qdf_nbuf_t netbuf, int err);
+
+/**
+ * ol_txrx_mgmt_tx_cb_set() - Store a callback for delivery
+ *	notifications for management frames.
+ * @ppdev: the data physical device object
+ * @type: the type of mgmt frame the callback is used for
+ * @download_cb: the callback for notification of delivery to the target
+ * @ota_ack_cb: the callback for notification of delivery to the peer
+ * @ctxt: context to use with the callback
+ *
+ * When the txrx SW receives notifications from the target that a tx frame
+ * has been delivered to its recipient, it will check if the tx frame
+ * is a management frame.  If so, the txrx SW will check the management
+ * frame type specified when the frame was submitted for transmission.
+ * If there is a callback function registered for the type of management
+ * frame in question, the txrx code will invoke the callback to inform
+ * the management + control SW that the mgmt frame was delivered.
+ * This function is used by the control SW to store a callback pointer
+ * for a given type of management frame.
+ */
+void
+ol_txrx_mgmt_tx_cb_set(struct cdp_pdev *ppdev, uint8_t type,
+		       ol_txrx_mgmt_tx_cb download_cb,
+		       ol_txrx_mgmt_tx_cb ota_ack_cb, void *ctxt);
+
+/**
+ * ol_txrx_mgmt_send_ext() - Transmit a management frame
+ * @pvdev: virtual device transmitting the frame
+ * @tx_mgmt_frm: management frame to transmit
+ * @type: the type of management frame (determines what callback to use)
+ * @use_6mbps: specify whether management frame to transmit should
+ *	use 6 Mbps rather than 1 Mbps min rate(for 5GHz band or P2P)
+ * @chanfreq: channel to transmit the frame on
+ *
+ * Send the specified management frame from the specified virtual device.
+ * The type is used for determining whether to invoke a callback to inform
+ * the sender that the tx mgmt frame was delivered, and if so, which
+ * callback to use.
+ *
+ * Return: 0 - the frame is accepted for transmission
+ *         1 - the frame was not accepted
+ */
+int
+ol_txrx_mgmt_send_ext(struct cdp_vdev *pvdev,
+		      qdf_nbuf_t tx_mgmt_frm,
+		      uint8_t type, uint8_t use_6mbps, uint16_t chanfreq);
+
+qdf_nbuf_t
+ol_tx_reinject(struct ol_txrx_vdev_t *vdev, qdf_nbuf_t msdu, uint16_t peer_id);
+
+#if defined(FEATURE_TSO)
+void ol_tso_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg);
+void ol_tso_seg_list_deinit(struct ol_txrx_pdev_t *pdev);
+void ol_tso_num_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg);
+void ol_tso_num_seg_list_deinit(struct ol_txrx_pdev_t *pdev);
+uint32_t ol_tx_tso_get_stats_idx(struct ol_txrx_pdev_t *pdev);
+uint8_t ol_tx_prepare_tso(ol_txrx_vdev_handle vdev,
+			  qdf_nbuf_t msdu,
+			  struct ol_txrx_msdu_info_t *msdu_info);
+void ol_tx_tso_update_stats(struct ol_txrx_pdev_t *pdev,
+			    struct qdf_tso_info_t  *tso_info, qdf_nbuf_t msdu,
+			    uint32_t tso_msdu_idx);
+#else
+static inline uint32_t ol_tx_tso_get_stats_idx(struct ol_txrx_pdev_t *pdev)
+{
+	return 0;
+}
+
+static inline void ol_tso_seg_list_init(struct ol_txrx_pdev_t *pdev,
+	uint32_t num_seg)
+{
+}
+
+static inline void ol_tso_seg_list_deinit(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+static inline void ol_tso_num_seg_list_init(struct ol_txrx_pdev_t *pdev,
+	uint32_t num_seg)
+{
+}
+
+static inline void ol_tso_num_seg_list_deinit(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+static inline uint8_t ol_tx_prepare_tso(ol_txrx_vdev_handle vdev,
+					qdf_nbuf_t msdu,
+					struct ol_txrx_msdu_info_t *msdu_info)
+{
+	return 0;
+}
+
+static inline void ol_tx_tso_update_stats(struct ol_txrx_pdev_t *pdev,
+					  struct qdf_tso_info_t  *tso_info,
+					  qdf_nbuf_t msdu,
+					  uint32_t tso_msdu_idx)
+{
+}
+#endif
+
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+bool ol_tx_desc_is_high_prio(qdf_nbuf_t msdu);
+#endif
+
+#if defined(HELIUMPLUS)
+void ol_txrx_dump_frag_desc(char *msg, struct ol_tx_desc_t *tx_desc);
+#else
+static inline
+void ol_txrx_dump_frag_desc(char *msg, struct ol_tx_desc_t *tx_desc)
+{
+}
+#endif
+
+#endif /* _OL_TX__H_ */
diff --git a/core/dp/txrx/ol_tx_classify.c b/core/dp/txrx/ol_tx_classify.c
new file mode 100644
index 0000000..5a86f5a
--- /dev/null
+++ b/core/dp/txrx/ol_tx_classify.c
@@ -0,0 +1,886 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#include <qdf_nbuf.h>         /* qdf_nbuf_t, etc. */
+#include <htt.h>              /* HTT_TX_EXT_TID_MGMT */
+#include <ol_htt_tx_api.h>    /* htt_tx_desc_tid */
+#include <ol_txrx_api.h>      /* ol_txrx_vdev_handle */
+#include <ol_txrx_ctrl_api.h> /* ol_txrx_sync */
+#include <ol_txrx.h>
+#include <ol_txrx_internal.h> /* TXRX_ASSERT1 */
+#include <ol_txrx_types.h>    /* pdev stats */
+#include <ol_tx_desc.h>       /* ol_tx_desc */
+#include <ol_tx_send.h>       /* ol_tx_send */
+#include <ol_txrx_peer_find.h>
+#include <ol_tx_classify.h>
+#include <ol_tx_queue.h>
+#include <ipv4.h>
+#include <ipv6_defs.h>
+#include <ip_prot.h>
+#include <enet.h>             /* ETHERTYPE_VLAN, etc. */
+#include <cds_ieee80211_common.h>        /* ieee80211_frame */
+#include <cdp_txrx_handle.h>
+/*
+ * In theory, this tx classify code could be used on the host or in the target.
+ * Thus, this code uses generic OS primitives, that can be aliased to either
+ * the host's OS primitives or the target's OS primitives.
+ * For now, the following #defines set up these host-specific or
+ * target-specific aliases.
+ */
+
+#define OL_TX_CLASSIFY_EXTENSION(vdev, tx_desc, netbuf, msdu_info, txq)
+#define OL_TX_CLASSIFY_MGMT_EXTENSION(vdev, tx_desc, netbuf, msdu_info, txq)
+
+#ifdef QCA_TX_HTT2_SUPPORT
+static void
+ol_tx_classify_htt2_frm(
+	struct ol_txrx_vdev_t *vdev,
+	qdf_nbuf_t tx_nbuf,
+	struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	struct htt_msdu_info_t *htt = &tx_msdu_info->htt;
+	A_UINT8 candi_frm = 0;
+
+	/*
+	 * Offload the frame re-order to L3 protocol and ONLY support
+	 * TCP protocol now.
+	 */
+	if ((htt->info.l2_hdr_type == htt_pkt_type_ethernet) &&
+	    (htt->info.frame_type == htt_frm_type_data) &&
+	    htt->info.is_unicast &&
+	    (htt->info.ethertype == ETHERTYPE_IPV4)) {
+		struct ipv4_hdr_t *ipHdr;
+
+		ipHdr = (struct ipv4_hdr_t *)(qdf_nbuf_data(tx_nbuf) +
+			htt->info.l3_hdr_offset);
+		if (ipHdr->protocol == IP_PROTOCOL_TCP)
+			candi_frm = 1;
+	}
+
+	qdf_nbuf_set_tx_parallel_dnload_frm(tx_nbuf, candi_frm);
+}
+
+#define OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, netbuf, msdu_info)      \
+	ol_tx_classify_htt2_frm(vdev, netbuf, msdu_info)
+#else
+#define OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, netbuf, msdu_info)      /* no-op */
+#endif /* QCA_TX_HTT2_SUPPORT */
+/* DHCP go with voice priority; WMM_AC_VO_TID1();*/
+#define TX_DHCP_TID  6
+
+#if defined(QCA_BAD_PEER_TX_FLOW_CL)
+static inline A_BOOL
+ol_if_tx_bad_peer_txq_overflow(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_peer_t *peer,
+	struct ol_tx_frms_queue_t *txq)
+{
+	if (peer && pdev && txq && (peer->tx_limit_flag) &&
+	    (txq->frms >= pdev->tx_peer_bal.peer_bal_txq_limit))
+		return true;
+	else
+		return false;
+}
+#else
+static inline A_BOOL ol_if_tx_bad_peer_txq_overflow(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_peer_t *peer,
+	struct ol_tx_frms_queue_t *txq)
+{
+	return false;
+}
+#endif
+
+/* EAPOL go with voice priority: WMM_AC_TO_TID1(WMM_AC_VO);*/
+#define TX_EAPOL_TID  6
+
+/* ARP go with voice priority: WMM_AC_TO_TID1(pdev->arp_ac_override)*/
+#define TX_ARP_TID  6
+
+/* For non-IP case, use default TID */
+#define TX_DEFAULT_TID  0
+
+/*
+ * Determine IP TOS priority
+ * IP Tos format :
+ *        (Refer Pg 57 WMM-test-plan-v1.2)
+ * IP-TOS - 8bits
+ *            : DSCP(6-bits) ECN(2-bits)
+ *            : DSCP - P2 P1 P0 X X X
+ *                where (P2 P1 P0) form 802.1D
+ */
+static inline A_UINT8
+ol_tx_tid_by_ipv4(A_UINT8 *pkt)
+{
+	A_UINT8 ipPri, tid;
+	struct ipv4_hdr_t *ipHdr = (struct ipv4_hdr_t *)pkt;
+
+	ipPri = ipHdr->tos >> 5;
+	tid = ipPri & 0x7;
+
+	return tid;
+}
+
+static inline A_UINT8
+ol_tx_tid_by_ipv6(A_UINT8 *pkt)
+{
+	return (ipv6_traffic_class((struct ipv6_hdr_t *)pkt) >> 5) & 0x7;
+}
+
+static inline void
+ol_tx_set_ether_type(
+	A_UINT8 *datap,
+	struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	A_UINT16 typeorlength;
+	A_UINT8 *ptr;
+	A_UINT8 *l3_data_ptr;
+
+	if (tx_msdu_info->htt.info.l2_hdr_type == htt_pkt_type_raw) {
+		/* adjust hdr_ptr to RA */
+		struct ieee80211_frame *wh = (struct ieee80211_frame *)datap;
+
+		if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
+					IEEE80211_FC0_TYPE_DATA) {
+			struct llc_snap_hdr_t *llc;
+			/* dot11 encapsulated frame */
+			struct ieee80211_qosframe *whqos =
+					(struct ieee80211_qosframe *)datap;
+			if (whqos->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
+				tx_msdu_info->htt.info.l3_hdr_offset =
+					sizeof(struct ieee80211_qosframe);
+			} else {
+				tx_msdu_info->htt.info.l3_hdr_offset =
+					sizeof(struct ieee80211_frame);
+			}
+			llc = (struct llc_snap_hdr_t *)
+				(datap + tx_msdu_info->htt.info.l3_hdr_offset);
+			tx_msdu_info->htt.info.ethertype =
+				(llc->ethertype[0] << 8) | llc->ethertype[1];
+			/*
+			 * l3_hdr_offset refers to the end of the 802.3 or
+			 * 802.11 header, which may be a LLC/SNAP header rather
+			 * than the IP header.
+			 * Thus, don't increment l3_hdr_offset += sizeof(*llc);
+			 * rather,leave it as is.
+			 */
+		} else {
+			/*
+			 * This function should only be applied to data frames.
+			 * For management frames, we already know to use
+			 * HTT_TX_EXT_TID_MGMT.
+			 */
+			TXRX_ASSERT2(0);
+		}
+	} else if (tx_msdu_info->htt.info.l2_hdr_type ==
+					htt_pkt_type_ethernet) {
+		ptr = (datap + ETHERNET_ADDR_LEN * 2);
+		typeorlength = (ptr[0] << 8) | ptr[1];
+		/*ETHERNET_HDR_LEN;*/
+		l3_data_ptr = datap + sizeof(struct ethernet_hdr_t);
+
+		if (typeorlength == ETHERTYPE_VLAN) {
+			ptr = (datap + ETHERNET_ADDR_LEN * 2
+					+ ETHERTYPE_VLAN_LEN);
+			typeorlength = (ptr[0] << 8) | ptr[1];
+			l3_data_ptr += ETHERTYPE_VLAN_LEN;
+		}
+
+		if (!IS_ETHERTYPE(typeorlength)) {
+			/* 802.3 header*/
+			struct llc_snap_hdr_t *llc_hdr =
+				(struct llc_snap_hdr_t *)l3_data_ptr;
+			typeorlength = (llc_hdr->ethertype[0] << 8) |
+							llc_hdr->ethertype[1];
+			l3_data_ptr += sizeof(struct llc_snap_hdr_t);
+		}
+
+		tx_msdu_info->htt.info.l3_hdr_offset = (A_UINT8)(l3_data_ptr -
+									datap);
+		tx_msdu_info->htt.info.ethertype = typeorlength;
+	}
+}
+
+static inline A_UINT8
+ol_tx_tid_by_ether_type(
+	A_UINT8 *datap,
+	struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	A_UINT8 tid;
+	A_UINT8 *l3_data_ptr;
+	A_UINT16 typeorlength;
+
+	l3_data_ptr = datap + tx_msdu_info->htt.info.l3_hdr_offset;
+	typeorlength = tx_msdu_info->htt.info.ethertype;
+
+	/* IP packet, do packet inspection for TID */
+	if (typeorlength == ETHERTYPE_IPV4) {
+		tid = ol_tx_tid_by_ipv4(l3_data_ptr);
+	} else if (typeorlength == ETHERTYPE_IPV6) {
+		tid = ol_tx_tid_by_ipv6(l3_data_ptr);
+	} else if (ETHERTYPE_IS_EAPOL_WAPI(typeorlength)) {
+		/* EAPOL go with voice priority*/
+		tid = TX_EAPOL_TID;
+	} else if (typeorlength == ETHERTYPE_ARP) {
+		tid = TX_ARP_TID;
+	} else {
+		/* For non-IP case, use default TID */
+		tid = TX_DEFAULT_TID;
+	}
+	return tid;
+}
+
+static inline A_UINT8
+ol_tx_tid_by_raw_type(
+	A_UINT8 *datap,
+	struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	A_UINT8 tid = HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST;
+
+	/* adjust hdr_ptr to RA */
+	struct ieee80211_frame *wh = (struct ieee80211_frame *)datap;
+
+	/* FIXME: This code does not handle 4 address formats. The QOS field
+	 * is not at usual location.
+	 */
+	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
+					IEEE80211_FC0_TYPE_DATA) {
+		/* dot11 encapsulated frame */
+		struct ieee80211_qosframe *whqos =
+					(struct ieee80211_qosframe *)datap;
+		if (whqos->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS)
+			tid = whqos->i_qos[0] & IEEE80211_QOS_TID;
+		else
+			tid = HTT_NON_QOS_TID;
+	} else {
+		/*
+		 * This function should only be applied to data frames.
+		 * For management frames, we already know to use
+		 * HTT_TX_EXT_TID_MGMT.
+		 */
+		qdf_assert(0);
+	}
+	return tid;
+}
+
+static A_UINT8
+ol_tx_tid(
+	struct ol_txrx_pdev_t *pdev,
+	qdf_nbuf_t tx_nbuf,
+	struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	A_UINT8 *datap = qdf_nbuf_data(tx_nbuf);
+	A_UINT8 tid;
+
+	if (pdev->frame_format == wlan_frm_fmt_raw) {
+		tx_msdu_info->htt.info.l2_hdr_type = htt_pkt_type_raw;
+
+		ol_tx_set_ether_type(datap, tx_msdu_info);
+		tid = tx_msdu_info->htt.info.ext_tid ==
+					QDF_NBUF_TX_EXT_TID_INVALID ?
+			ol_tx_tid_by_raw_type(datap, tx_msdu_info) :
+			tx_msdu_info->htt.info.ext_tid;
+	} else if (pdev->frame_format == wlan_frm_fmt_802_3) {
+		tx_msdu_info->htt.info.l2_hdr_type = htt_pkt_type_ethernet;
+
+		ol_tx_set_ether_type(datap, tx_msdu_info);
+		tid =
+			tx_msdu_info->htt.info.ext_tid ==
+					QDF_NBUF_TX_EXT_TID_INVALID ?
+				ol_tx_tid_by_ether_type(datap, tx_msdu_info) :
+				tx_msdu_info->htt.info.ext_tid;
+	} else if (pdev->frame_format == wlan_frm_fmt_native_wifi) {
+		struct llc_snap_hdr_t *llc;
+
+		tx_msdu_info->htt.info.l2_hdr_type = htt_pkt_type_native_wifi;
+		tx_msdu_info->htt.info.l3_hdr_offset =
+						sizeof(struct ieee80211_frame);
+		llc = (struct llc_snap_hdr_t *)
+			(datap + tx_msdu_info->htt.info.l3_hdr_offset);
+		tx_msdu_info->htt.info.ethertype =
+			(llc->ethertype[0] << 8) | llc->ethertype[1];
+		/*
+		 * Native WiFi is a special case of "raw" 802.11 header format.
+		 * However, we expect that for all cases that use native WiFi,
+		 * the TID will be directly specified out of band.
+		 */
+		tid = tx_msdu_info->htt.info.ext_tid;
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_FATAL,
+			  "Invalid standard frame type: %d\n",
+			  pdev->frame_format);
+		qdf_assert(0);
+		tid = HTT_TX_EXT_TID_INVALID;
+	}
+	return tid;
+}
+
+#if defined(FEATURE_WLAN_TDLS)
+static inline
+struct ol_txrx_peer_t *ol_tx_tdls_peer_find(struct ol_txrx_pdev_t *pdev,
+						struct ol_txrx_vdev_t *vdev,
+						uint8_t *peer_id)
+{
+	struct ol_txrx_peer_t *peer = NULL;
+
+	if (vdev->hlTdlsFlag) {
+		peer = ol_txrx_peer_find_hash_find_get_ref(pdev,
+					vdev->hl_tdls_ap_mac_addr.raw, 0, 1,
+					PEER_DEBUG_ID_OL_INTERNAL);
+
+		if (peer &&  (peer->peer_ids[0] == HTT_INVALID_PEER_ID)) {
+			ol_txrx_peer_release_ref(peer,
+						 PEER_DEBUG_ID_OL_INTERNAL);
+			peer = NULL;
+		} else {
+			if (peer)
+				*peer_id = peer->local_id;
+		}
+	}
+	if (!peer)
+		peer = ol_txrx_assoc_peer_find(vdev);
+
+	return peer;
+}
+
+#else
+static struct ol_txrx_peer_t *ol_tx_tdls_peer_find(struct ol_txrx_pdev_t *pdev,
+						struct ol_txrx_vdev_t *vdev,
+						uint8_t *peer_id)
+{
+	struct ol_txrx_peer_t *peer = NULL;
+
+	peer = ol_txrx_assoc_peer_find(vdev);
+
+	return peer;
+}
+#endif
+
+struct ol_tx_frms_queue_t *
+ol_tx_classify(
+	struct ol_txrx_vdev_t *vdev,
+	struct ol_tx_desc_t *tx_desc,
+	qdf_nbuf_t tx_nbuf,
+	struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	struct ol_txrx_peer_t *peer = NULL;
+	struct ol_tx_frms_queue_t *txq = NULL;
+	A_UINT8 *dest_addr;
+	A_UINT8 tid;
+	u_int8_t peer_id;
+
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+	dest_addr = ol_tx_dest_addr_find(pdev, tx_nbuf);
+	if (unlikely(NULL == dest_addr)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX,
+				QDF_TRACE_LEVEL_ERROR,
+				"Error: dest_addr is NULL.\n");
+		return NULL; /*error*/
+	}
+	if ((IEEE80211_IS_MULTICAST(dest_addr)) ||
+	    (vdev->opmode == wlan_op_mode_ocb)) {
+		txq = &vdev->txqs[OL_TX_VDEV_MCAST_BCAST];
+		tx_msdu_info->htt.info.ext_tid =
+					HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST;
+		if (vdev->opmode == wlan_op_mode_sta) {
+			/*
+			 * The STA sends a frame with a broadcast
+			 * dest addr (DA) as a
+			 * unicast frame to the AP's receive addr (RA).
+			 * Find the peer object that represents the AP
+			 * that the STA is associated with.
+			 */
+			peer = ol_txrx_assoc_peer_find(vdev);
+			if (!peer) {
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "Error: STA %pK (%02x:%02x:%02x:%02x:%02x:%02x) trying to send bcast DA tx data frame w/o association\n",
+					  vdev,
+					  vdev->mac_addr.raw[0],
+					  vdev->mac_addr.raw[1],
+					  vdev->mac_addr.raw[2],
+					  vdev->mac_addr.raw[3],
+					  vdev->mac_addr.raw[4],
+					  vdev->mac_addr.raw[5]);
+				return NULL; /* error */
+			} else if ((peer->security[
+				OL_TXRX_PEER_SECURITY_MULTICAST].sec_type
+						!= htt_sec_type_wapi) &&
+				   (qdf_nbuf_is_ipv4_pkt(tx_nbuf) == true)) {
+				if (QDF_NBUF_CB_PACKET_TYPE_DHCP ==
+						QDF_NBUF_CB_GET_PACKET_TYPE(
+								tx_nbuf)) {
+					/* DHCP frame to go with
+					 * voice priority
+					 */
+					txq = &peer->txqs[TX_DHCP_TID];
+					tx_msdu_info->htt.info.ext_tid =
+								TX_DHCP_TID;
+				}
+			}
+			/*
+			 * The following line assumes each peer object has a
+			 * single ID. This is currently true, and is expected
+			 * to remain true.
+			 */
+			tx_msdu_info->htt.info.peer_id = peer->peer_ids[0];
+		} else if (vdev->opmode == wlan_op_mode_ocb) {
+			tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID;
+			/*
+			 * In OCB mode, don't worry about the peer.
+			 * We don't need it.
+			 */
+			peer = NULL;
+		} else {
+			tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID;
+			/*
+			 * Look up the vdev's BSS peer, so that the
+			 * classify_extension function can check whether to
+			 * encrypt multicast / broadcast frames.
+			 */
+			peer = ol_txrx_peer_find_hash_find_get_ref
+						(pdev,
+						 vdev->mac_addr.raw,
+						 0, 1,
+						 PEER_DEBUG_ID_OL_INTERNAL);
+			if (!peer) {
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "Error: vdev %pK (%02x:%02x:%02x:%02x:%02x:%02x) trying to send bcast/mcast, but no self-peer found\n",
+					  vdev,
+					  vdev->mac_addr.raw[0],
+					  vdev->mac_addr.raw[1],
+					  vdev->mac_addr.raw[2],
+					  vdev->mac_addr.raw[3],
+					  vdev->mac_addr.raw[4],
+					  vdev->mac_addr.raw[5]);
+				return NULL; /* error */
+			}
+		}
+		tx_msdu_info->htt.info.is_unicast = false;
+	} else {
+		/* tid would be overwritten for non QoS case*/
+		tid = ol_tx_tid(pdev, tx_nbuf, tx_msdu_info);
+		if ((HTT_TX_EXT_TID_INVALID == tid) ||
+		    (tid >= OL_TX_NUM_TIDS)) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX,
+				  QDF_TRACE_LEVEL_ERROR,
+				  "%s Error: could not classify packet into valid TID(%d).\n",
+				  __func__, tid);
+			return NULL;
+		}
+#ifdef ATH_SUPPORT_WAPI
+		/* Check to see if a frame is a WAI frame */
+		if (tx_msdu_info->htt.info.ethertype == ETHERTYPE_WAI) {
+			/* WAI frames should not be encrypted */
+			tx_msdu_info->htt.action.do_encrypt = 0;
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+				  "Tx Frame is a WAI frame\n");
+		}
+#endif /* ATH_SUPPORT_WAPI */
+
+		/*
+		 * Find the peer and increment its reference count.
+		 * If this vdev is an AP, use the dest addr (DA) to determine
+		 * which peer STA this unicast data frame is for.
+		 * If this vdev is a STA, the unicast data frame is for the
+		 * AP the STA is associated with.
+		 */
+		if (vdev->opmode == wlan_op_mode_sta) {
+			/*
+			 * TO DO:
+			 * To support TDLS, first check if there is a TDLS
+			 * peer STA,
+			 * and if so, check if the DA matches the TDLS peer
+			 * STA's MAC address. If there is no peer TDLS STA,
+			 * or if the DA is not the TDLS STA's address,
+			 * then the frame is either for the AP itself, or is
+			 * supposed to be sent to the AP for forwarding.
+			 */
+			peer = ol_tx_tdls_peer_find(pdev, vdev, &peer_id);
+		} else {
+			peer = ol_txrx_peer_find_hash_find_get_ref(pdev,
+								   dest_addr,
+								   0, 1,
+						PEER_DEBUG_ID_OL_INTERNAL);
+		}
+		tx_msdu_info->htt.info.is_unicast = true;
+		if (!peer) {
+			/*
+			 * Unicast data xfer can only happen to an
+			 * associated peer. It is illegitimate to send unicast
+			 * data if there is no peer to send it to.
+			 */
+			QDF_TRACE(QDF_MODULE_ID_TXRX,
+				  QDF_TRACE_LEVEL_ERROR,
+				  "Error: vdev %pK (%02x:%02x:%02x:%02x:%02x:%02x) trying to send unicast tx data frame to an unknown peer\n",
+				  vdev,
+				  vdev->mac_addr.raw[0], vdev->mac_addr.raw[1],
+				  vdev->mac_addr.raw[2], vdev->mac_addr.raw[3],
+				  vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]);
+			return NULL; /* error */
+		}
+		TX_SCHED_DEBUG_PRINT("Peer found\n");
+		if (!peer->qos_capable) {
+			tid = OL_TX_NON_QOS_TID;
+		} else if ((peer->security[
+				OL_TXRX_PEER_SECURITY_UNICAST].sec_type
+					!= htt_sec_type_wapi) &&
+			   (qdf_nbuf_is_ipv4_pkt(tx_nbuf) == true)) {
+			if (QDF_NBUF_CB_PACKET_TYPE_DHCP ==
+					QDF_NBUF_CB_GET_PACKET_TYPE(tx_nbuf))
+				/* DHCP frame to go with voice priority */
+				tid = TX_DHCP_TID;
+		}
+
+		/* Only allow encryption when in authenticated state */
+		if (OL_TXRX_PEER_STATE_AUTH != peer->state)
+			tx_msdu_info->htt.action.do_encrypt = 0;
+
+		txq = &peer->txqs[tid];
+		tx_msdu_info->htt.info.ext_tid = tid;
+		/*
+		 * The following line assumes each peer object has a single ID.
+		 * This is currently true, and is expected to remain true.
+		 */
+		tx_msdu_info->htt.info.peer_id = peer->peer_ids[0];
+		/*
+		 * WORKAROUND - check that the peer ID is valid.
+		 * If tx data is provided before ol_rx_peer_map_handler is
+		 * called to record the peer ID specified by the target,
+		 * then we could end up here with an invalid peer ID.
+		 * TO DO: rather than dropping the tx frame, pause the txq it
+		 * goes into, then fill in the peer ID for the entries in the
+		 * txq when the peer_map event provides the peer ID, and then
+		 * unpause the txq.
+		 */
+		if (tx_msdu_info->htt.info.peer_id == HTT_INVALID_PEER_ID) {
+			if (peer) {
+				ol_txrx_info(
+					   "%s: remove the peer for invalid peer_id %pK\n",
+					   __func__, peer);
+				/* remove the peer reference added above */
+				ol_txrx_peer_release_ref
+						(peer,
+						 PEER_DEBUG_ID_OL_INTERNAL);
+				tx_msdu_info->peer = NULL;
+			}
+			return NULL;
+		}
+	}
+	tx_msdu_info->peer = peer;
+	if (ol_if_tx_bad_peer_txq_overflow(pdev, peer, txq))
+		return NULL;
+	/*
+	 * If relevant, do a deeper inspection to determine additional
+	 * characteristics of the tx frame.
+	 * If the frame is invalid, then the txq will be set to NULL to
+	 * indicate an error.
+	 */
+	OL_TX_CLASSIFY_EXTENSION(vdev, tx_desc, tx_nbuf, tx_msdu_info, txq);
+	if (IEEE80211_IS_MULTICAST(dest_addr) && vdev->opmode !=
+				wlan_op_mode_sta && tx_msdu_info->peer !=
+								NULL) {
+		ol_txrx_dbg(
+			   "%s: remove the peer reference %pK\n",
+			   __func__, peer);
+		/* remove the peer reference added above */
+		ol_txrx_peer_release_ref(tx_msdu_info->peer,
+					 PEER_DEBUG_ID_OL_INTERNAL);
+		/* Making peer NULL in case if multicast non STA mode */
+		tx_msdu_info->peer = NULL;
+	}
+
+	/* Whether this frame can download though HTT2 data pipe or not. */
+	OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, tx_nbuf, tx_msdu_info);
+
+	/* Update Tx Queue info */
+	tx_desc->txq = txq;
+
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+	return txq;
+}
+
+struct ol_tx_frms_queue_t *
+ol_tx_classify_mgmt(
+	struct ol_txrx_vdev_t *vdev,
+	struct ol_tx_desc_t *tx_desc,
+	qdf_nbuf_t tx_nbuf,
+	struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	struct ol_txrx_peer_t *peer = NULL;
+	struct ol_tx_frms_queue_t *txq = NULL;
+	A_UINT8 *dest_addr;
+	union ol_txrx_align_mac_addr_t local_mac_addr_aligned, *mac_addr;
+
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+	dest_addr = ol_tx_dest_addr_find(pdev, tx_nbuf);
+	if (unlikely(NULL == dest_addr)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX,
+				QDF_TRACE_LEVEL_ERROR,
+				"Error: dest_addr is NULL.\n");
+		return NULL; /*error*/
+	}
+	if (IEEE80211_IS_MULTICAST(dest_addr)) {
+		/*
+		 * AP:  beacons are broadcast,
+		 *      public action frames (e.g. extended channel
+		 *      switch announce) may be broadcast
+		 * STA: probe requests can be either broadcast or unicast
+		 */
+		txq = &vdev->txqs[OL_TX_VDEV_DEFAULT_MGMT];
+		tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID;
+		tx_msdu_info->peer = NULL;
+		tx_msdu_info->htt.info.is_unicast = 0;
+	} else {
+		/*
+		 * Find the peer and increment its reference count.
+		 * If this vdev is an AP, use the receiver addr (RA) to
+		 * determine which peer STA this unicast mgmt frame is for.
+		 * If this vdev is a STA, the unicast mgmt frame is for the
+		 * AP the STA is associated with.
+		 * Probe request / response and Assoc request / response are
+		 * sent before the peer exists - in this case, use the
+		 * vdev's default tx queue.
+		 */
+		if (vdev->opmode == wlan_op_mode_sta) {
+			/*
+			 * TO DO:
+			 * To support TDLS, first check if there is a TDLS
+			 * peer STA, and if so, check if the DA matches
+			 * the TDLS peer STA's MAC address.
+			 */
+			peer = ol_txrx_assoc_peer_find(vdev);
+			/*
+			 * Some special case(preauth for example) needs to send
+			 * unicast mgmt frame to unassociated AP. In such case,
+			 * we need to check if dest addr match the associated
+			 * peer addr. If not, we set peer as NULL to queue this
+			 * frame to vdev queue.
+			 */
+			if (peer) {
+
+				qdf_mem_copy(
+					&local_mac_addr_aligned.raw[0],
+					dest_addr, OL_TXRX_MAC_ADDR_LEN);
+				mac_addr = &local_mac_addr_aligned;
+				if (ol_txrx_peer_find_mac_addr_cmp
+						(mac_addr,
+						 &peer->mac_addr) != 0) {
+					ol_txrx_peer_release_ref
+						(peer,
+						 PEER_DEBUG_ID_OL_INTERNAL);
+					peer = NULL;
+				}
+			}
+		} else {
+			/* find the peer and increment its reference count */
+			peer = ol_txrx_peer_find_hash_find_get_ref(pdev,
+								   dest_addr,
+								   0, 1,
+						PEER_DEBUG_ID_OL_INTERNAL);
+		}
+		tx_msdu_info->peer = peer;
+		if (!peer) {
+			txq = &vdev->txqs[OL_TX_VDEV_DEFAULT_MGMT];
+			tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID;
+		} else {
+			txq = &peer->txqs[HTT_TX_EXT_TID_MGMT];
+			tx_msdu_info->htt.info.ext_tid = HTT_TX_EXT_TID_MGMT;
+			/*
+			 * The following line assumes each peer object has a
+			 * single ID. This is currently true, and is expected
+			 * to remain true.
+			 */
+			tx_msdu_info->htt.info.peer_id = peer->peer_ids[0];
+		}
+		tx_msdu_info->htt.info.is_unicast = 1;
+	}
+	/*
+	 * If relevant, do a deeper inspection to determine additional
+	 * characteristics of the tx frame.
+	 * If the frame is invalid, then the txq will be set to NULL to
+	 * indicate an error.
+	 */
+	OL_TX_CLASSIFY_MGMT_EXTENSION(vdev, tx_desc, tx_nbuf,
+				      tx_msdu_info, txq);
+
+	/* Whether this frame can download though HTT2 data pipe or not. */
+	OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, tx_nbuf, tx_msdu_info);
+
+	/* Update Tx Queue info */
+	tx_desc->txq = txq;
+
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+	return txq;
+}
+
+#ifdef currently_unused
+QDF_STATUS
+ol_tx_classify_extension(
+	struct ol_txrx_vdev_t *vdev,
+	struct ol_tx_desc_t *tx_desc,
+	qdf_nbuf_t tx_msdu,
+	struct ol_txrx_msdu_info_t *msdu_info)
+{
+	u8 *datap = qdf_nbuf_data(tx_msdu);
+	struct ol_txrx_peer_t *peer;
+	int which_key;
+
+	/*
+	 * The following msdu_info fields were already filled in by the
+	 * ol_tx entry function or the regular ol_tx_classify function:
+	 *     htt.info.vdev_id            (ol_tx_hl or ol_tx_non_std_hl)
+	 *     htt.info.ext_tid            (ol_tx_non_std_hl or ol_tx_classify)
+	 *     htt.info.frame_type         (ol_tx_hl or ol_tx_non_std_hl)
+	 *     htt.info.l2_hdr_type        (ol_tx_hl or ol_tx_non_std_hl)
+	 *     htt.info.is_unicast         (ol_tx_classify)
+	 *     htt.info.peer_id            (ol_tx_classify)
+	 *     peer                        (ol_tx_classify)
+	 *     if (is_unicast) {
+	 *         htt.info.ethertype      (ol_tx_classify)
+	 *         htt.info.l3_hdr_offset  (ol_tx_classify)
+	 *     }
+	 * The following fields need to be filled in by this function:
+	 *     if (!is_unicast) {
+	 *         htt.info.ethertype
+	 *         htt.info.l3_hdr_offset
+	 *     }
+	 *     htt.action.band (NOT CURRENTLY USED)
+	 *     htt.action.do_encrypt
+	 *     htt.action.do_tx_complete
+	 * The following fields are not needed for data frames, and can
+	 * be left uninitialized:
+	 *     htt.info.frame_subtype
+	 */
+
+	if (!msdu_info->htt.info.is_unicast) {
+		int l2_hdr_size;
+		u16 ethertype;
+
+		if (msdu_info->htt.info.l2_hdr_type == htt_pkt_type_ethernet) {
+			struct ethernet_hdr_t *eh;
+
+			eh = (struct ethernet_hdr_t *)datap;
+			l2_hdr_size = sizeof(*eh);
+			ethertype = (eh->ethertype[0] << 8) | eh->ethertype[1];
+
+			if (ethertype == ETHERTYPE_VLAN) {
+				struct ethernet_vlan_hdr_t *evh;
+
+				evh = (struct ethernet_vlan_hdr_t *)datap;
+				l2_hdr_size = sizeof(*evh);
+				ethertype = (evh->ethertype[0] << 8) |
+							evh->ethertype[1];
+			}
+
+			if (!IS_ETHERTYPE(ethertype)) {
+				/* 802.3 header*/
+				struct llc_snap_hdr_t *llc =
+					(struct llc_snap_hdr_t *)(datap +
+							l2_hdr_size);
+				ethertype = (llc->ethertype[0] << 8) |
+							llc->ethertype[1];
+				l2_hdr_size += sizeof(*llc);
+			}
+			msdu_info->htt.info.l3_hdr_offset = l2_hdr_size;
+			msdu_info->htt.info.ethertype = ethertype;
+		} else { /* 802.11 */
+			struct llc_snap_hdr_t *llc;
+
+			l2_hdr_size = ol_txrx_ieee80211_hdrsize(datap);
+			llc = (struct llc_snap_hdr_t *)(datap + l2_hdr_size);
+			ethertype = (llc->ethertype[0] << 8) |
+							llc->ethertype[1];
+			/*
+			 * Don't include the LLC/SNAP header in l2_hdr_size,
+			 * because l3_hdr_offset is actually supposed to refer
+			 * to the header after the 802.3 or 802.11 header,
+			 * which could be a LLC/SNAP header rather
+			 * than the L3 header.
+			 */
+		}
+		msdu_info->htt.info.l3_hdr_offset = l2_hdr_size;
+		msdu_info->htt.info.ethertype = ethertype;
+		which_key = txrx_sec_mcast;
+	} else {
+		which_key = txrx_sec_ucast;
+	}
+	peer = msdu_info->peer;
+	/*
+	 * msdu_info->htt.action.do_encrypt is initially set in ol_tx_desc_hl.
+	 * Add more check here.
+	 */
+	msdu_info->htt.action.do_encrypt = (!peer) ? 0 :
+		(peer->security[which_key].sec_type == htt_sec_type_none) ? 0 :
+		msdu_info->htt.action.do_encrypt;
+	/*
+	 * For systems that have a frame by frame spec for whether to receive
+	 * a tx completion notification, use the tx completion notification
+	 * only  for certain management frames, not for data frames.
+	 * (In the future, this may be changed slightly, e.g. to request a
+	 * tx completion notification for the final EAPOL message sent by a
+	 * STA during the key delivery handshake.)
+	 */
+	msdu_info->htt.action.do_tx_complete = 0;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ol_tx_classify_mgmt_extension(
+		struct ol_txrx_vdev_t *vdev,
+		struct ol_tx_desc_t *tx_desc,
+		qdf_nbuf_t tx_msdu,
+		struct ol_txrx_msdu_info_t *msdu_info)
+{
+	struct ieee80211_frame *wh;
+
+	/*
+	 * The following msdu_info fields were already filled in by the
+	 * ol_tx entry function or the regular ol_tx_classify_mgmt function:
+	 *     htt.info.vdev_id          (ol_txrx_mgmt_send)
+	 *     htt.info.frame_type       (ol_txrx_mgmt_send)
+	 *     htt.info.l2_hdr_type      (ol_txrx_mgmt_send)
+	 *     htt.action.do_tx_complete (ol_txrx_mgmt_send)
+	 *     htt.info.peer_id          (ol_tx_classify_mgmt)
+	 *     htt.info.ext_tid          (ol_tx_classify_mgmt)
+	 *     htt.info.is_unicast       (ol_tx_classify_mgmt)
+	 *     peer                      (ol_tx_classify_mgmt)
+	 * The following fields need to be filled in by this function:
+	 *     htt.info.frame_subtype
+	 *     htt.info.l3_hdr_offset
+	 *     htt.action.band (NOT CURRENTLY USED)
+	 * The following fields are not needed for mgmt frames, and can
+	 * be left uninitialized:
+	 *     htt.info.ethertype
+	 *     htt.action.do_encrypt
+	 *         (This will be filled in by other SW, which knows whether
+	 *         the peer has robust-management-frames enabled.)
+	 */
+	wh = (struct ieee80211_frame *)qdf_nbuf_data(tx_msdu);
+	msdu_info->htt.info.frame_subtype =
+		(wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >>
+		IEEE80211_FC0_SUBTYPE_SHIFT;
+	msdu_info->htt.info.l3_hdr_offset = sizeof(struct ieee80211_frame);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
diff --git a/core/dp/txrx/ol_tx_classify.h b/core/dp/txrx/ol_tx_classify.h
new file mode 100644
index 0000000..b88f329
--- /dev/null
+++ b/core/dp/txrx/ol_tx_classify.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012, 2014, 2016 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.
+ */
+
+/**
+ * @file ol_tx_classify.h
+ * @brief API definitions for the tx classify module within the data SW.
+ */
+#ifndef _OL_TX_CLASSIFY__H_
+#define _OL_TX_CLASSIFY__H_
+
+#include <qdf_nbuf.h>      /* qdf_nbuf_t */
+#include <ol_txrx_types.h> /* ol_txrx_vdev_t, etc. */
+
+static inline u_int8_t *
+ol_tx_dest_addr_find(
+	struct ol_txrx_pdev_t *pdev,
+	qdf_nbuf_t tx_nbuf)
+{
+	u_int8_t *hdr_ptr;
+	void *datap = qdf_nbuf_data(tx_nbuf);
+
+	if (pdev->frame_format == wlan_frm_fmt_raw) {
+		/* adjust hdr_ptr to RA */
+		struct ieee80211_frame *wh =
+			(struct ieee80211_frame *)datap;
+		hdr_ptr = wh->i_addr1;
+	} else if (pdev->frame_format ==
+			wlan_frm_fmt_native_wifi) {
+		/* adjust hdr_ptr to RA */
+		struct ieee80211_frame *wh = (
+			struct ieee80211_frame *)datap;
+		hdr_ptr = wh->i_addr1;
+	} else if (pdev->frame_format == wlan_frm_fmt_802_3) {
+		hdr_ptr = datap;
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_TXRX,
+			  QDF_TRACE_LEVEL_ERROR,
+			"Invalid standard frame type: %d\n",
+			pdev->frame_format);
+		qdf_assert(0);
+		hdr_ptr = NULL;
+	}
+	return hdr_ptr;
+}
+
+#if defined(CONFIG_HL_SUPPORT)
+
+/**
+ * @brief Classify a tx frame to which tid queue.
+ *
+ * @param vdev - the virtual device sending the data
+ *      (for specifying the transmitter address for multicast / broadcast data)
+ * @param tx_desc - descriptor object with meta-data about the tx frame
+ * @param netbuf - the tx frame
+ * @param tx_msdu_info - characteristics of the tx frame
+ */
+struct ol_tx_frms_queue_t *
+ol_tx_classify(
+	struct ol_txrx_vdev_t *vdev,
+	struct ol_tx_desc_t *tx_desc,
+	qdf_nbuf_t netbuf,
+	struct ol_txrx_msdu_info_t *tx_msdu_info);
+
+struct ol_tx_frms_queue_t *
+ol_tx_classify_mgmt(
+	struct ol_txrx_vdev_t *vdev,
+	struct ol_tx_desc_t *tx_desc,
+	qdf_nbuf_t netbuf,
+	struct ol_txrx_msdu_info_t *tx_msdu_info);
+
+#else
+
+#define ol_tx_classify(vdev, tx_desc, netbuf, tx_msdu_info) NULL
+#define ol_tx_classify_mgmt(vdev, tx_desc, netbuf, tx_msdu_info) NULL
+
+#endif /* defined(CONFIG_HL_SUPPORT) */
+
+
+#endif /* _OL_TX_CLASSIFY__H_ */
diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c
new file mode 100644
index 0000000..b517702
--- /dev/null
+++ b/core/dp/txrx/ol_tx_desc.c
@@ -0,0 +1,1066 @@
+/*
+ * Copyright (c) 2011, 2014-2018 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.
+ */
+
+#include <qdf_net_types.h>      /* QDF_NBUF_EXEMPT_NO_EXEMPTION, etc. */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_util.h>           /* qdf_assert */
+#include <qdf_lock.h>           /* qdf_spinlock */
+#include <qdf_trace.h>          /* qdf_tso_seg_dbg stuff */
+#ifdef QCA_COMPUTE_TX_DELAY
+#include <qdf_time.h>           /* qdf_system_ticks */
+#endif
+
+#include <ol_htt_tx_api.h>      /* htt_tx_desc_id */
+
+#include <ol_tx_desc.h>
+#include <ol_txrx_internal.h>
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+#include <ol_txrx_encap.h>      /* OL_TX_RESTORE_HDR, etc */
+#endif
+#include <ol_txrx.h>
+
+#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS
+static inline void ol_tx_desc_sanity_checks(struct ol_txrx_pdev_t *pdev,
+					struct ol_tx_desc_t *tx_desc)
+{
+	if (tx_desc->pkt_type != ol_tx_frm_freed) {
+		ol_txrx_err(
+				   "%s Potential tx_desc corruption pkt_type:0x%x pdev:0x%pK",
+				   __func__, tx_desc->pkt_type, pdev);
+		qdf_assert(0);
+	}
+}
+static inline void ol_tx_desc_reset_pkt_type(struct ol_tx_desc_t *tx_desc)
+{
+	tx_desc->pkt_type = ol_tx_frm_freed;
+}
+#ifdef QCA_COMPUTE_TX_DELAY
+static inline void ol_tx_desc_compute_delay(struct ol_tx_desc_t *tx_desc)
+{
+	if (tx_desc->entry_timestamp_ticks != 0xffffffff) {
+		ol_txrx_err("%s Timestamp:0x%x\n",
+				   __func__, tx_desc->entry_timestamp_ticks);
+		qdf_assert(0);
+	}
+	tx_desc->entry_timestamp_ticks = qdf_system_ticks();
+}
+static inline void ol_tx_desc_reset_timestamp(struct ol_tx_desc_t *tx_desc)
+{
+	tx_desc->entry_timestamp_ticks = 0xffffffff;
+}
+#endif
+#else
+static inline void ol_tx_desc_sanity_checks(struct ol_txrx_pdev_t *pdev,
+						struct ol_tx_desc_t *tx_desc)
+{
+}
+static inline void ol_tx_desc_reset_pkt_type(struct ol_tx_desc_t *tx_desc)
+{
+}
+static inline void ol_tx_desc_compute_delay(struct ol_tx_desc_t *tx_desc)
+{
+}
+static inline void ol_tx_desc_reset_timestamp(struct ol_tx_desc_t *tx_desc)
+{
+}
+#endif
+
+#ifdef DESC_TIMESTAMP_DEBUG_INFO
+static inline void ol_tx_desc_update_tx_ts(struct ol_tx_desc_t *tx_desc)
+{
+	tx_desc->desc_debug_info.prev_tx_ts = tx_desc
+						->desc_debug_info.curr_tx_ts;
+	tx_desc->desc_debug_info.curr_tx_ts = qdf_get_log_timestamp();
+}
+#else
+static inline void ol_tx_desc_update_tx_ts(struct ol_tx_desc_t *tx_desc)
+{
+}
+#endif
+
+/**
+ * ol_tx_desc_vdev_update() - vedv assign.
+ * @tx_desc: tx descriptor pointer
+ * @vdev: vdev handle
+ *
+ * Return: None
+ */
+static inline void
+ol_tx_desc_vdev_update(struct ol_tx_desc_t *tx_desc,
+		       struct ol_txrx_vdev_t *vdev)
+{
+	tx_desc->vdev = vdev;
+	tx_desc->vdev_id = vdev->vdev_id;
+}
+
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+
+/**
+ * ol_tx_desc_count_inc() - tx desc count increment for desc allocation.
+ * @vdev: vdev handle
+ *
+ * Return: None
+ */
+static inline void
+ol_tx_desc_count_inc(struct ol_txrx_vdev_t *vdev)
+{
+	qdf_atomic_inc(&vdev->tx_desc_count);
+}
+#else
+
+static inline void
+ol_tx_desc_count_inc(struct ol_txrx_vdev_t *vdev)
+{
+}
+
+#endif
+
+#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+
+/**
+ * ol_tx_desc_alloc() - allocate descriptor from freelist
+ * @pdev: pdev handle
+ * @vdev: vdev handle
+ *
+ * Return: tx descriptor pointer/ NULL in case of error
+ */
+static
+struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev,
+					     struct ol_txrx_vdev_t *vdev)
+{
+	struct ol_tx_desc_t *tx_desc = NULL;
+
+	qdf_spin_lock_bh(&pdev->tx_mutex);
+	if (pdev->tx_desc.freelist) {
+		tx_desc = ol_tx_get_desc_global_pool(pdev);
+		if (!tx_desc) {
+			qdf_spin_unlock_bh(&pdev->tx_mutex);
+			return NULL;
+		}
+		ol_tx_desc_dup_detect_set(pdev, tx_desc);
+		ol_tx_desc_sanity_checks(pdev, tx_desc);
+		ol_tx_desc_compute_delay(tx_desc);
+		ol_tx_desc_vdev_update(tx_desc, vdev);
+		ol_tx_desc_count_inc(vdev);
+		ol_tx_desc_update_tx_ts(tx_desc);
+		qdf_atomic_inc(&tx_desc->ref_cnt);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_mutex);
+	return tx_desc;
+}
+
+/**
+ * ol_tx_desc_alloc_wrapper() -allocate tx descriptor
+ * @pdev: pdev handler
+ * @vdev: vdev handler
+ * @msdu_info: msdu handler
+ *
+ * Return: tx descriptor or NULL
+ */
+struct ol_tx_desc_t *
+ol_tx_desc_alloc_wrapper(struct ol_txrx_pdev_t *pdev,
+			 struct ol_txrx_vdev_t *vdev,
+			 struct ol_txrx_msdu_info_t *msdu_info)
+{
+	return ol_tx_desc_alloc(pdev, vdev);
+}
+
+#else
+/**
+ * ol_tx_desc_alloc() -allocate tx descriptor
+ * @pdev: pdev handler
+ * @vdev: vdev handler
+ * @pool: flow pool
+ *
+ * Return: tx descriptor or NULL
+ */
+static
+struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev,
+				      struct ol_txrx_vdev_t *vdev,
+				      struct ol_tx_flow_pool_t *pool)
+{
+	struct ol_tx_desc_t *tx_desc = NULL;
+
+	if (!pool) {
+		pdev->pool_stats.pkt_drop_no_pool++;
+		goto end;
+	}
+
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	if (pool->avail_desc) {
+		tx_desc = ol_tx_get_desc_flow_pool(pool);
+		ol_tx_desc_dup_detect_set(pdev, tx_desc);
+		if (qdf_unlikely(pool->avail_desc < pool->stop_th &&
+				(pool->avail_desc >= pool->stop_priority_th) &&
+				(pool->status == FLOW_POOL_ACTIVE_UNPAUSED))) {
+			pool->status = FLOW_POOL_NON_PRIO_PAUSED;
+			qdf_spin_unlock_bh(&pool->flow_pool_lock);
+			/* pause network NON PRIORITY queues */
+			pdev->pause_cb(vdev->vdev_id,
+				       WLAN_STOP_NON_PRIORITY_QUEUE,
+				       WLAN_DATA_FLOW_CONTROL);
+		} else if (qdf_unlikely((pool->avail_desc <
+						pool->stop_priority_th) &&
+				pool->status == FLOW_POOL_NON_PRIO_PAUSED)) {
+			pool->status = FLOW_POOL_ACTIVE_PAUSED;
+			qdf_spin_unlock_bh(&pool->flow_pool_lock);
+			/* pause priority queue */
+			pdev->pause_cb(vdev->vdev_id,
+				       WLAN_NETIF_PRIORITY_QUEUE_OFF,
+				       WLAN_DATA_FLOW_CONTROL_PRIORITY);
+		} else {
+			qdf_spin_unlock_bh(&pool->flow_pool_lock);
+		}
+		ol_tx_desc_sanity_checks(pdev, tx_desc);
+		ol_tx_desc_compute_delay(tx_desc);
+		ol_tx_desc_update_tx_ts(tx_desc);
+		ol_tx_desc_vdev_update(tx_desc, vdev);
+		qdf_atomic_inc(&tx_desc->ref_cnt);
+	} else {
+		pool->pkt_drop_no_desc++;
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+	}
+
+end:
+	return tx_desc;
+}
+
+/**
+ * ol_tx_desc_alloc_wrapper() -allocate tx descriptor
+ * @pdev: pdev handler
+ * @vdev: vdev handler
+ * @msdu_info: msdu handler
+ *
+ * Return: tx descriptor or NULL
+ */
+#ifdef QCA_LL_TX_FLOW_GLOBAL_MGMT_POOL
+struct ol_tx_desc_t *
+ol_tx_desc_alloc_wrapper(struct ol_txrx_pdev_t *pdev,
+			 struct ol_txrx_vdev_t *vdev,
+			 struct ol_txrx_msdu_info_t *msdu_info)
+{
+	if (qdf_unlikely(msdu_info->htt.info.frame_type == htt_pkt_type_mgmt))
+		return ol_tx_desc_alloc(pdev, vdev, pdev->mgmt_pool);
+	else
+		return ol_tx_desc_alloc(pdev, vdev, vdev->pool);
+}
+#else
+struct ol_tx_desc_t *
+ol_tx_desc_alloc_wrapper(struct ol_txrx_pdev_t *pdev,
+			 struct ol_txrx_vdev_t *vdev,
+			 struct ol_txrx_msdu_info_t *msdu_info)
+{
+	return ol_tx_desc_alloc(pdev, vdev, vdev->pool);
+}
+#endif
+#endif
+
+/**
+ * ol_tx_desc_alloc_hl() - allocate tx descriptor
+ * @pdev: pdev handle
+ * @vdev: vdev handle
+ * @msdu_info: tx msdu info
+ *
+ * Return: tx descriptor pointer/ NULL in case of error
+ */
+static struct ol_tx_desc_t *
+ol_tx_desc_alloc_hl(struct ol_txrx_pdev_t *pdev,
+		    struct ol_txrx_vdev_t *vdev,
+		    struct ol_txrx_msdu_info_t *msdu_info)
+{
+	struct ol_tx_desc_t *tx_desc;
+
+	tx_desc = ol_tx_desc_alloc_wrapper(pdev, vdev, msdu_info);
+	if (!tx_desc)
+		return NULL;
+
+	qdf_atomic_dec(&pdev->tx_queue.rsrc_cnt);
+
+	return tx_desc;
+}
+
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+
+/**
+ * ol_tx_desc_vdev_rm() - decrement the tx desc count for vdev.
+ * @tx_desc: tx desc
+ *
+ * Return: None
+ */
+static inline void
+ol_tx_desc_vdev_rm(struct ol_tx_desc_t *tx_desc)
+{
+	/*
+	 * In module exit context, vdev handle could be destroyed but still
+	 * we need to free pending completion tx_desc.
+	 */
+	if (!tx_desc || !tx_desc->vdev)
+		return;
+
+	qdf_atomic_dec(&tx_desc->vdev->tx_desc_count);
+	tx_desc->vdev = NULL;
+}
+#else
+
+static inline void
+ol_tx_desc_vdev_rm(struct ol_tx_desc_t *tx_desc)
+{
+}
+#endif
+
+#ifdef FEATURE_TSO
+/**
+ * ol_tso_unmap_tso_segment() - Unmap TSO segment
+ * @pdev: pointer to ol_txrx_pdev_t structure
+ * @tx_desc: pointer to ol_tx_desc_t containing the TSO segment
+ *
+ * Unmap TSO segment (frag[1]). If it is the last TSO segment corresponding the
+ * nbuf, also unmap the EIT header(frag[0]).
+ *
+ * Return: None
+ */
+static void ol_tso_unmap_tso_segment(struct ol_txrx_pdev_t *pdev,
+						struct ol_tx_desc_t *tx_desc)
+{
+	bool is_last_seg = false;
+	struct qdf_tso_num_seg_elem_t *tso_num_desc = NULL;
+
+	if (qdf_unlikely(tx_desc->tso_desc == NULL)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s %d TSO desc is NULL!",
+			  __func__, __LINE__);
+		qdf_assert(0);
+		return;
+	} else if (qdf_unlikely(tx_desc->tso_num_desc == NULL)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s %d TSO common info is NULL!",
+			  __func__, __LINE__);
+		qdf_assert(0);
+		return;
+	}
+
+	tso_num_desc = tx_desc->tso_num_desc;
+
+	qdf_spin_lock_bh(&pdev->tso_seg_pool.tso_mutex);
+
+	tso_num_desc->num_seg.tso_cmn_num_seg--;
+	is_last_seg = (tso_num_desc->num_seg.tso_cmn_num_seg == 0) ?
+								true : false;
+	qdf_nbuf_unmap_tso_segment(pdev->osdev, tx_desc->tso_desc, is_last_seg);
+
+	qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);
+
+}
+
+/**
+ * ol_tx_tso_desc_free() - Add TSO TX descs back to the freelist
+ * @pdev: pointer to ol_txrx_pdev_t structure
+ * @tx_desc: pointer to ol_tx_desc_t containing the TSO segment
+ *
+ * Add qdf_tso_seg_elem_t corresponding to the TSO seg back to freelist.
+ * If it is the last segment of the jumbo skb, also add the
+ * qdf_tso_num_seg_elem_t to the free list.
+ *
+ * Return: None
+ */
+static void ol_tx_tso_desc_free(struct ol_txrx_pdev_t *pdev,
+				struct ol_tx_desc_t *tx_desc)
+{
+	bool is_last_seg;
+	struct qdf_tso_num_seg_elem_t *tso_num_desc = tx_desc->tso_num_desc;
+
+	is_last_seg = (tso_num_desc->num_seg.tso_cmn_num_seg == 0) ?
+								true : false;
+	if (is_last_seg) {
+		ol_tso_num_seg_free(pdev, tx_desc->tso_num_desc);
+		tx_desc->tso_num_desc = NULL;
+	}
+
+	ol_tso_free_segment(pdev, tx_desc->tso_desc);
+	tx_desc->tso_desc = NULL;
+}
+
+#else
+static inline void ol_tx_tso_desc_free(struct ol_txrx_pdev_t *pdev,
+				       struct ol_tx_desc_t *tx_desc)
+{
+}
+
+static inline void ol_tso_unmap_tso_segment(
+					struct ol_txrx_pdev_t *pdev,
+					struct ol_tx_desc_t *tx_desc)
+{
+}
+#endif
+
+/**
+ * ol_tx_desc_free_common() - common funcs to free tx_desc for all flow ctl vers
+ * @pdev: pdev handle
+ * @tx_desc: tx descriptor
+ *
+ * Set of common functions needed for QCA_LL_TX_FLOW_CONTROL_V2 and older
+ * versions of flow control. Needs to be called from within a spinlock.
+ *
+ * Return: None
+ */
+static void ol_tx_desc_free_common(struct ol_txrx_pdev_t *pdev,
+						struct ol_tx_desc_t *tx_desc)
+{
+	ol_tx_desc_dup_detect_reset(pdev, tx_desc);
+
+	if (tx_desc->pkt_type == OL_TX_FRM_TSO)
+		ol_tx_tso_desc_free(pdev, tx_desc);
+
+	ol_tx_desc_reset_pkt_type(tx_desc);
+	ol_tx_desc_reset_timestamp(tx_desc);
+	/* clear the ref cnt */
+	qdf_atomic_init(&tx_desc->ref_cnt);
+	tx_desc->vdev_id = OL_TXRX_INVALID_VDEV_ID;
+}
+
+#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+/**
+ * ol_tx_desc_free() - put descriptor to freelist
+ * @pdev: pdev handle
+ * @tx_desc: tx descriptor
+ *
+ * Return: None
+ */
+void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc)
+{
+	qdf_spin_lock_bh(&pdev->tx_mutex);
+
+	ol_tx_desc_free_common(pdev, tx_desc);
+
+	ol_tx_put_desc_global_pool(pdev, tx_desc);
+	ol_tx_desc_vdev_rm(tx_desc);
+
+	qdf_spin_unlock_bh(&pdev->tx_mutex);
+}
+
+#else
+
+/**
+ * ol_tx_update_free_desc_to_pool() - update free desc to pool
+ * @pdev: pdev handle
+ * @tx_desc: descriptor
+ *
+ * Return : 1 desc distribution required / 0 don't need distribution
+ */
+#ifdef QCA_LL_TX_FLOW_CONTROL_RESIZE
+static inline bool ol_tx_update_free_desc_to_pool(struct ol_txrx_pdev_t *pdev,
+						  struct ol_tx_desc_t *tx_desc)
+{
+	struct ol_tx_flow_pool_t *pool = tx_desc->pool;
+	bool distribute_desc = false;
+
+	if (unlikely(pool->overflow_desc)) {
+		ol_tx_put_desc_global_pool(pdev, tx_desc);
+		--pool->overflow_desc;
+		distribute_desc = true;
+	} else {
+		ol_tx_put_desc_flow_pool(pool, tx_desc);
+	}
+
+	return distribute_desc;
+}
+#else
+static inline bool ol_tx_update_free_desc_to_pool(struct ol_txrx_pdev_t *pdev,
+						  struct ol_tx_desc_t *tx_desc)
+{
+	ol_tx_put_desc_flow_pool(tx_desc->pool, tx_desc);
+	return false;
+}
+#endif
+
+/**
+ * ol_tx_desc_free() - put descriptor to pool freelist
+ * @pdev: pdev handle
+ * @tx_desc: tx descriptor
+ *
+ * Return: None
+ */
+void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc)
+{
+	bool distribute_desc = false;
+	struct ol_tx_flow_pool_t *pool = tx_desc->pool;
+
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+
+	ol_tx_desc_free_common(pdev, tx_desc);
+	distribute_desc = ol_tx_update_free_desc_to_pool(pdev, tx_desc);
+
+	switch (pool->status) {
+	case FLOW_POOL_ACTIVE_PAUSED:
+		if (pool->avail_desc > pool->start_priority_th) {
+			/* unpause priority queue */
+			pdev->pause_cb(pool->member_flow_id,
+			       WLAN_NETIF_PRIORITY_QUEUE_ON,
+			       WLAN_DATA_FLOW_CONTROL_PRIORITY);
+			pool->status = FLOW_POOL_NON_PRIO_PAUSED;
+		}
+		break;
+	case FLOW_POOL_NON_PRIO_PAUSED:
+		if (pool->avail_desc > pool->start_th) {
+			pdev->pause_cb(pool->member_flow_id,
+				       WLAN_WAKE_NON_PRIORITY_QUEUE,
+				       WLAN_DATA_FLOW_CONTROL);
+			pool->status = FLOW_POOL_ACTIVE_UNPAUSED;
+		}
+		break;
+	case FLOW_POOL_INVALID:
+		if (pool->avail_desc == pool->flow_pool_size) {
+			qdf_spin_unlock_bh(&pool->flow_pool_lock);
+			ol_tx_free_invalid_flow_pool(pool);
+			qdf_print("%s %d pool is INVALID State!!\n",
+				 __func__, __LINE__);
+			return;
+		}
+		break;
+	case FLOW_POOL_ACTIVE_UNPAUSED:
+		break;
+	default:
+		qdf_print("%s %d pool is INACTIVE State!!\n",
+				 __func__, __LINE__);
+		break;
+	};
+
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+
+	if (unlikely(distribute_desc))
+		ol_tx_distribute_descs_to_deficient_pools_from_global_pool();
+
+}
+#endif
+
+const uint32_t htt_to_ce_pkt_type[] = {
+	[htt_pkt_type_raw] = tx_pkt_type_raw,
+	[htt_pkt_type_native_wifi] = tx_pkt_type_native_wifi,
+	[htt_pkt_type_ethernet] = tx_pkt_type_802_3,
+	[htt_pkt_type_mgmt] = tx_pkt_type_mgmt,
+	[htt_pkt_type_eth2] = tx_pkt_type_eth2,
+	[htt_pkt_num_types] = 0xffffffff
+};
+
+#define WISA_DEST_PORT_6MBPS	50000
+#define WISA_DEST_PORT_24MBPS	50001
+
+/**
+ * ol_tx_get_wisa_ext_hdr_type() - get header type for WiSA mode
+ * @netbuf: network buffer
+ *
+ * Return: extension header type
+ */
+static enum extension_header_type
+ol_tx_get_wisa_ext_hdr_type(qdf_nbuf_t netbuf)
+{
+	uint8_t *buf = qdf_nbuf_data(netbuf);
+	uint16_t dport;
+
+	if (qdf_is_macaddr_group(
+		(struct qdf_mac_addr *)(buf + QDF_NBUF_DEST_MAC_OFFSET))) {
+
+		dport = (uint16_t)(*(uint16_t *)(buf +
+			QDF_NBUF_TRAC_IPV4_OFFSET +
+			QDF_NBUF_TRAC_IPV4_HEADER_SIZE + sizeof(uint16_t)));
+
+		if (dport == QDF_SWAP_U16(WISA_DEST_PORT_6MBPS))
+			return WISA_MODE_EXT_HEADER_6MBPS;
+		else if (dport == QDF_SWAP_U16(WISA_DEST_PORT_24MBPS))
+			return WISA_MODE_EXT_HEADER_24MBPS;
+		else
+			return EXT_HEADER_NOT_PRESENT;
+	} else {
+		return EXT_HEADER_NOT_PRESENT;
+	}
+}
+
+/**
+ * ol_tx_get_ext_header_type() - extension header is required or not
+ * @vdev: vdev pointer
+ * @netbuf: network buffer
+ *
+ * This function returns header type and if extension header is
+ * not required than returns EXT_HEADER_NOT_PRESENT.
+ *
+ * Return: extension header type
+ */
+enum extension_header_type
+ol_tx_get_ext_header_type(struct ol_txrx_vdev_t *vdev,
+	qdf_nbuf_t netbuf)
+{
+	if (vdev->is_wisa_mode_enable == true)
+		return ol_tx_get_wisa_ext_hdr_type(netbuf);
+	else
+		return EXT_HEADER_NOT_PRESENT;
+}
+
+struct ol_tx_desc_t *ol_tx_desc_ll(struct ol_txrx_pdev_t *pdev,
+				   struct ol_txrx_vdev_t *vdev,
+				   qdf_nbuf_t netbuf,
+				   struct ol_txrx_msdu_info_t *msdu_info)
+{
+	struct ol_tx_desc_t *tx_desc;
+	unsigned int i;
+	uint32_t num_frags;
+	enum extension_header_type type;
+
+	msdu_info->htt.info.vdev_id = vdev->vdev_id;
+	msdu_info->htt.action.cksum_offload = qdf_nbuf_get_tx_cksum(netbuf);
+	switch (qdf_nbuf_get_exemption_type(netbuf)) {
+	case QDF_NBUF_EXEMPT_NO_EXEMPTION:
+	case QDF_NBUF_EXEMPT_ON_KEY_MAPPING_KEY_UNAVAILABLE:
+		/* We want to encrypt this frame */
+		msdu_info->htt.action.do_encrypt = 1;
+		break;
+	case QDF_NBUF_EXEMPT_ALWAYS:
+		/* We don't want to encrypt this frame */
+		msdu_info->htt.action.do_encrypt = 0;
+		break;
+	default:
+		qdf_assert(0);
+		break;
+	}
+
+	/* allocate the descriptor */
+	tx_desc = ol_tx_desc_alloc_wrapper(pdev, vdev, msdu_info);
+	if (!tx_desc)
+		return NULL;
+
+	/* initialize the SW tx descriptor */
+	tx_desc->netbuf = netbuf;
+
+	if (msdu_info->tso_info.is_tso) {
+		tx_desc->tso_desc = msdu_info->tso_info.curr_seg;
+		tx_desc->tso_num_desc = msdu_info->tso_info.tso_num_seg_list;
+		tx_desc->pkt_type = OL_TX_FRM_TSO;
+		TXRX_STATS_MSDU_INCR(pdev, tx.tso.tso_pkts, netbuf);
+	} else {
+		tx_desc->pkt_type = OL_TX_FRM_STD;
+	}
+
+	type = ol_tx_get_ext_header_type(vdev, netbuf);
+
+	/* initialize the HW tx descriptor */
+	if (qdf_unlikely(htt_tx_desc_init(pdev->htt_pdev, tx_desc->htt_tx_desc,
+			 tx_desc->htt_tx_desc_paddr,
+			 ol_tx_desc_id(pdev, tx_desc), netbuf, &msdu_info->htt,
+			 &msdu_info->tso_info, NULL, type))) {
+		/*
+		 * HTT Tx descriptor initialization failed.
+		 * therefore, free the tx desc
+		 */
+		ol_tx_desc_free(pdev, tx_desc);
+		return NULL;
+	}
+
+	/*
+	 * Initialize the fragmentation descriptor.
+	 * Skip the prefix fragment (HTT tx descriptor) that was added
+	 * during the call to htt_tx_desc_init above.
+	 */
+	num_frags = qdf_nbuf_get_num_frags(netbuf);
+	/* num_frags are expected to be 2 max */
+	num_frags = (num_frags > QDF_NBUF_CB_TX_MAX_EXTRA_FRAGS)
+		? QDF_NBUF_CB_TX_MAX_EXTRA_FRAGS
+		: num_frags;
+#if defined(HELIUMPLUS)
+	/*
+	 * Use num_frags - 1, since 1 frag is used to store
+	 * the HTT/HTC descriptor
+	 * Refer to htt_tx_desc_init()
+	 */
+	htt_tx_desc_num_frags(pdev->htt_pdev, tx_desc->htt_frag_desc,
+			      num_frags - 1);
+#else /* ! defined(HELIUMPLUS) */
+	htt_tx_desc_num_frags(pdev->htt_pdev, tx_desc->htt_tx_desc,
+			      num_frags - 1);
+#endif /* defined(HELIUMPLUS) */
+
+	if (msdu_info->tso_info.is_tso) {
+		htt_tx_desc_fill_tso_info(pdev->htt_pdev,
+			 tx_desc->htt_frag_desc, &msdu_info->tso_info);
+		TXRX_STATS_TSO_SEG_UPDATE(pdev,
+			 msdu_info->tso_info.msdu_stats_idx,
+			 msdu_info->tso_info.curr_seg->seg);
+	} else {
+		for (i = 1; i < num_frags; i++) {
+			qdf_size_t frag_len;
+			qdf_dma_addr_t frag_paddr;
+#ifdef HELIUMPLUS_DEBUG
+			void *frag_vaddr;
+
+			frag_vaddr = qdf_nbuf_get_frag_vaddr(netbuf, i);
+#endif
+			frag_len = qdf_nbuf_get_frag_len(netbuf, i);
+			frag_paddr = qdf_nbuf_get_frag_paddr(netbuf, i);
+#if defined(HELIUMPLUS)
+			htt_tx_desc_frag(pdev->htt_pdev, tx_desc->htt_frag_desc,
+					 i - 1, frag_paddr, frag_len);
+#if defined(HELIUMPLUS_DEBUG)
+			qdf_print("%s:%d: htt_fdesc=%pK frag=%d frag_vaddr=0x%pK frag_paddr=0x%llx len=%zu\n",
+				  __func__, __LINE__, tx_desc->htt_frag_desc,
+				  i-1, frag_vaddr, frag_paddr, frag_len);
+			ol_txrx_dump_pkt(netbuf, frag_paddr, 64);
+#endif /* HELIUMPLUS_DEBUG */
+#else /* ! defined(HELIUMPLUS) */
+			htt_tx_desc_frag(pdev->htt_pdev, tx_desc->htt_tx_desc,
+					 i - 1, frag_paddr, frag_len);
+#endif /* defined(HELIUMPLUS) */
+		}
+	}
+
+#if defined(HELIUMPLUS_DEBUG)
+	ol_txrx_dump_frag_desc("ol_tx_desc_ll()", tx_desc);
+#endif
+	return tx_desc;
+}
+
+struct ol_tx_desc_t *
+ol_tx_desc_hl(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_vdev_t *vdev,
+	qdf_nbuf_t netbuf,
+	struct ol_txrx_msdu_info_t *msdu_info)
+{
+	struct ol_tx_desc_t *tx_desc;
+
+	/* FIX THIS: these inits should probably be done by tx classify */
+	msdu_info->htt.info.vdev_id = vdev->vdev_id;
+	msdu_info->htt.info.frame_type = pdev->htt_pkt_type;
+	msdu_info->htt.action.cksum_offload = qdf_nbuf_get_tx_cksum(netbuf);
+	switch (qdf_nbuf_get_exemption_type(netbuf)) {
+	case QDF_NBUF_EXEMPT_NO_EXEMPTION:
+	case QDF_NBUF_EXEMPT_ON_KEY_MAPPING_KEY_UNAVAILABLE:
+		/* We want to encrypt this frame */
+		msdu_info->htt.action.do_encrypt = 1;
+		break;
+	case QDF_NBUF_EXEMPT_ALWAYS:
+		/* We don't want to encrypt this frame */
+		msdu_info->htt.action.do_encrypt = 0;
+		break;
+	default:
+		qdf_assert(0);
+		break;
+	}
+
+	/* allocate the descriptor */
+	tx_desc = ol_tx_desc_alloc_hl(pdev, vdev, msdu_info);
+	if (!tx_desc)
+		return NULL;
+
+	/* initialize the SW tx descriptor */
+	tx_desc->netbuf = netbuf;
+	/* fix this - get pkt_type from msdu_info */
+	tx_desc->pkt_type = OL_TX_FRM_STD;
+
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+	tx_desc->orig_l2_hdr_bytes = 0;
+#endif
+	/* the HW tx descriptor will be initialized later by the caller */
+
+	return tx_desc;
+}
+
+void ol_tx_desc_frame_list_free(struct ol_txrx_pdev_t *pdev,
+				ol_tx_desc_list *tx_descs, int had_error)
+{
+	struct ol_tx_desc_t *tx_desc, *tmp;
+	qdf_nbuf_t msdus = NULL;
+
+	TAILQ_FOREACH_SAFE(tx_desc, tx_descs, tx_desc_list_elem, tmp) {
+		qdf_nbuf_t msdu = tx_desc->netbuf;
+
+		qdf_atomic_init(&tx_desc->ref_cnt);   /* clear the ref cnt */
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+		/* restore original hdr offset */
+		OL_TX_RESTORE_HDR(tx_desc, msdu);
+#endif
+
+		/*
+		 * In MCC IPA tx context, IPA driver provides skb with directly
+		 * DMA mapped address. In such case, there's no need for WLAN
+		 * driver to DMA unmap the skb.
+		 */
+		if (qdf_nbuf_get_users(msdu) <= 1) {
+			if (!qdf_nbuf_ipa_owned_get(msdu))
+				qdf_nbuf_unmap(pdev->osdev, msdu,
+					       QDF_DMA_TO_DEVICE);
+			else if (qdf_mem_smmu_s1_enabled(pdev->osdev))
+				qdf_nbuf_unmap(pdev->osdev, msdu,
+					       QDF_DMA_TO_DEVICE);
+		}
+
+		/* free the tx desc */
+		ol_tx_desc_free(pdev, tx_desc);
+		/* link the netbuf into a list to free as a batch */
+		qdf_nbuf_set_next(msdu, msdus);
+		msdus = msdu;
+	}
+	/* free the netbufs as a batch */
+	qdf_nbuf_tx_free(msdus, had_error);
+}
+
+void ol_tx_desc_frame_free_nonstd(struct ol_txrx_pdev_t *pdev,
+				  struct ol_tx_desc_t *tx_desc, int had_error)
+{
+	int mgmt_type;
+	ol_txrx_mgmt_tx_cb ota_ack_cb;
+
+	qdf_atomic_init(&tx_desc->ref_cnt);     /* clear the ref cnt */
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+	/* restore original hdr offset */
+	OL_TX_RESTORE_HDR(tx_desc, (tx_desc->netbuf));
+#endif
+	if (tx_desc->pkt_type == OL_TX_FRM_NO_FREE) {
+
+		/* free the tx desc but don't unmap or free the frame */
+		if (pdev->tx_data_callback.func) {
+			qdf_nbuf_set_next(tx_desc->netbuf, NULL);
+			pdev->tx_data_callback.func(pdev->tx_data_callback.ctxt,
+						    tx_desc->netbuf, had_error);
+			goto free_tx_desc;
+		}
+		/* let the code below unmap and free the frame */
+	}
+	if (tx_desc->pkt_type == OL_TX_FRM_TSO)
+		ol_tso_unmap_tso_segment(pdev, tx_desc);
+	else
+		qdf_nbuf_unmap(pdev->osdev, tx_desc->netbuf, QDF_DMA_TO_DEVICE);
+	/* check the frame type to see what kind of special steps are needed */
+	if ((tx_desc->pkt_type >= OL_TXRX_MGMT_TYPE_BASE) &&
+		   (tx_desc->pkt_type != ol_tx_frm_freed)) {
+		qdf_dma_addr_t frag_desc_paddr = 0;
+
+#if defined(HELIUMPLUS)
+		frag_desc_paddr = tx_desc->htt_frag_desc_paddr;
+		/* FIX THIS -
+		 * The FW currently has trouble using the host's fragments
+		 * table for management frames.  Until this is fixed,
+		 * rather than specifying the fragment table to the FW,
+		 * the host SW will specify just the address of the initial
+		 * fragment.
+		 * Now that the mgmt frame is done, the HTT tx desc's frags
+		 * table pointer needs to be reset.
+		 */
+#if defined(HELIUMPLUS_DEBUG)
+		qdf_print("%s %d: Frag Descriptor Reset [%d] to 0x%x\n",
+			  __func__, __LINE__, tx_desc->id,
+			  frag_desc_paddr);
+#endif /* HELIUMPLUS_DEBUG */
+#endif /* HELIUMPLUS */
+		htt_tx_desc_frags_table_set(pdev->htt_pdev,
+					    tx_desc->htt_tx_desc, 0,
+					    frag_desc_paddr, 1);
+
+		mgmt_type = tx_desc->pkt_type - OL_TXRX_MGMT_TYPE_BASE;
+		/*
+		 *  we already checked the value when the mgmt frame was
+		 *  provided to the txrx layer.
+		 *  no need to check it a 2nd time.
+		 */
+		ota_ack_cb = pdev->tx_mgmt_cb.ota_ack_cb;
+		if (ota_ack_cb) {
+			void *ctxt;
+			ctxt = pdev->tx_mgmt_cb.ctxt;
+			ota_ack_cb(ctxt, tx_desc->netbuf, had_error);
+		}
+	} else if (had_error == htt_tx_status_download_fail) {
+		/* Failed to send to target */
+
+		/* This is to decrement skb->users count for TSO segment */
+		if (tx_desc->pkt_type == OL_TX_FRM_TSO)
+			qdf_nbuf_tx_free(tx_desc->netbuf, had_error);
+		goto free_tx_desc;
+	} else {
+		/* single regular frame, called from completion path */
+		qdf_nbuf_set_next(tx_desc->netbuf, NULL);
+		qdf_nbuf_tx_free(tx_desc->netbuf, had_error);
+	}
+free_tx_desc:
+	/* free the tx desc */
+	ol_tx_desc_free(pdev, tx_desc);
+}
+
+#if defined(FEATURE_TSO)
+#ifdef TSOSEG_DEBUG
+static int
+ol_tso_seg_dbg_sanitize(struct qdf_tso_seg_elem_t *tsoseg)
+{
+	int rc = -1;
+	struct ol_tx_desc_t *txdesc;
+
+	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
+			rc = 0;
+	}
+	return rc;
+
+};
+#else
+static int
+ol_tso_seg_dbg_sanitize(struct qdf_tso_seg_elem_t *tsoseg)
+{
+	return 0;
+}
+#endif /* TSOSEG_DEBUG */
+
+/**
+ * ol_tso_alloc_segment() - function to allocate a TSO segment
+ * element
+ * @pdev: the data physical device sending the data
+ *
+ * Allocates a TSO segment element from the free list held in
+ * the pdev
+ *
+ * Return: tso_seg
+ */
+struct qdf_tso_seg_elem_t *ol_tso_alloc_segment(struct ol_txrx_pdev_t *pdev)
+{
+	struct qdf_tso_seg_elem_t *tso_seg = NULL;
+
+	qdf_spin_lock_bh(&pdev->tso_seg_pool.tso_mutex);
+	if (pdev->tso_seg_pool.freelist) {
+		pdev->tso_seg_pool.num_free--;
+		tso_seg = pdev->tso_seg_pool.freelist;
+		if (tso_seg->on_freelist != 1) {
+			qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);
+			qdf_print("tso seg alloc failed: not in freelist");
+			QDF_BUG(0);
+			return NULL;
+		} else if (tso_seg->cookie != TSO_SEG_MAGIC_COOKIE) {
+			qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);
+			qdf_print("tso seg alloc failed: bad cookie");
+			QDF_BUG(0);
+			return NULL;
+		}
+		/*this tso seg is not a part of freelist now.*/
+		tso_seg->on_freelist = 0;
+		tso_seg->sent_to_target = 0;
+		tso_seg->force_free = 0;
+		pdev->tso_seg_pool.freelist = pdev->tso_seg_pool.freelist->next;
+		qdf_tso_seg_dbg_record(tso_seg, TSOSEG_LOC_ALLOC);
+	}
+	qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);
+
+	return tso_seg;
+}
+
+/**
+ * ol_tso_free_segment() - function to free a TSO segment
+ * element
+ * @pdev: the data physical device sending the data
+ * @tso_seg: The TSO segment element to be freed
+ *
+ * Returns a TSO segment element to the free list held in the
+ * pdev
+ *
+ * Return: none
+ */
+void ol_tso_free_segment(struct ol_txrx_pdev_t *pdev,
+	 struct qdf_tso_seg_elem_t *tso_seg)
+{
+	qdf_spin_lock_bh(&pdev->tso_seg_pool.tso_mutex);
+	if (tso_seg->on_freelist != 0) {
+		qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);
+		qdf_print("Do not free tso seg, already freed");
+		QDF_BUG(0);
+		return;
+	} else if (tso_seg->cookie != TSO_SEG_MAGIC_COOKIE) {
+		qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);
+		qdf_print("Do not free tso seg: cookie is not good.");
+		QDF_BUG(0);
+		return;
+	} else if ((tso_seg->sent_to_target != 1) &&
+		   (tso_seg->force_free != 1)) {
+		qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);
+		qdf_print("Do not free tso seg:  yet to be sent to target");
+		QDF_BUG(0);
+		return;
+	}
+	/* 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);
+	tso_seg->next = pdev->tso_seg_pool.freelist;
+	tso_seg->on_freelist = 1;
+	tso_seg->sent_to_target = 0;
+	tso_seg->cookie = TSO_SEG_MAGIC_COOKIE;
+	pdev->tso_seg_pool.freelist = tso_seg;
+	pdev->tso_seg_pool.num_free++;
+	qdf_tso_seg_dbg_record(tso_seg, tso_seg->force_free
+			       ? TSOSEG_LOC_FORCE_FREE
+			       : TSOSEG_LOC_FREE);
+	tso_seg->force_free = 0;
+	qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);
+}
+
+/**
+ * ol_tso_num_seg_alloc() - function to allocate a element to count TSO segments
+ *			    in a jumbo skb packet.
+ * @pdev: the data physical device sending the data
+ *
+ * Allocates a element to count TSO segments from the free list held in
+ * the pdev
+ *
+ * Return: tso_num_seg
+ */
+struct qdf_tso_num_seg_elem_t *ol_tso_num_seg_alloc(struct ol_txrx_pdev_t *pdev)
+{
+	struct qdf_tso_num_seg_elem_t *tso_num_seg = NULL;
+
+	qdf_spin_lock_bh(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
+	if (pdev->tso_num_seg_pool.freelist) {
+		pdev->tso_num_seg_pool.num_free--;
+		tso_num_seg = pdev->tso_num_seg_pool.freelist;
+		pdev->tso_num_seg_pool.freelist =
+				pdev->tso_num_seg_pool.freelist->next;
+	}
+	qdf_spin_unlock_bh(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
+
+	return tso_num_seg;
+}
+
+/**
+ * ol_tso_num_seg_free() - function to free a TSO segment
+ * element
+ * @pdev: the data physical device sending the data
+ * @tso_seg: The TSO segment element to be freed
+ *
+ * Returns a element to the free list held in the pdev
+ *
+ * Return: none
+ */
+void ol_tso_num_seg_free(struct ol_txrx_pdev_t *pdev,
+	 struct qdf_tso_num_seg_elem_t *tso_num_seg)
+{
+	qdf_spin_lock_bh(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
+	tso_num_seg->next = pdev->tso_num_seg_pool.freelist;
+	pdev->tso_num_seg_pool.freelist = tso_num_seg;
+		pdev->tso_num_seg_pool.num_free++;
+	qdf_spin_unlock_bh(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
+}
+#endif
diff --git a/core/dp/txrx/ol_tx_desc.h b/core/dp/txrx/ol_tx_desc.h
new file mode 100644
index 0000000..dc1bebf
--- /dev/null
+++ b/core/dp/txrx/ol_tx_desc.h
@@ -0,0 +1,481 @@
+/*
+ * Copyright (c) 2011, 2014-2018 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.
+ */
+
+/**
+ * @file ol_tx_desc.h
+ * @brief API definitions for the tx descriptor module within the data SW.
+ */
+#ifndef _OL_TX_DESC__H_
+#define _OL_TX_DESC__H_
+
+#include <cds_queue.h>          /* TAILQ_HEAD */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <cdp_txrx_cmn.h>       /* ol_txrx_vdev_t, etc. */
+#include <ol_txrx_internal.h>   /*TXRX_ASSERT2 */
+#include <ol_htt_tx_api.h>
+
+#define DIV_BY_8	3
+#define DIV_BY_32	5
+#define MOD_BY_8	0x7
+#define MOD_BY_32	0x1F
+
+struct ol_tx_desc_t *
+ol_tx_desc_alloc_wrapper(struct ol_txrx_pdev_t *pdev,
+			 struct ol_txrx_vdev_t *vdev,
+			 struct ol_txrx_msdu_info_t *msdu_info);
+
+
+/**
+ * @brief Allocate and initialize a tx descriptor for a LL system.
+ * @details
+ *  Allocate a tx descriptor pair for a new tx frame - a SW tx descriptor
+ *  for private use within the host data SW, and a HTT tx descriptor for
+ *  downloading tx meta-data to the target FW/HW.
+ *  Fill in the fields of this pair of tx descriptors based on the
+ *  information in the netbuf.
+ *  For LL, this includes filling in a fragmentation descriptor to
+ *  specify to the MAC HW where to find the tx frame's fragments.
+ *
+ * @param pdev - the data physical device sending the data
+ *      (for accessing the tx desc pool)
+ * @param vdev - the virtual device sending the data
+ *      (for specifying the transmitter address for multicast / broadcast data)
+ * @param netbuf - the tx frame
+ * @param msdu_info - tx meta-data
+ */
+struct ol_tx_desc_t *ol_tx_desc_ll(struct ol_txrx_pdev_t *pdev,
+				   struct ol_txrx_vdev_t *vdev,
+				   qdf_nbuf_t netbuf,
+				   struct ol_txrx_msdu_info_t *msdu_info);
+
+
+/**
+ * @brief Allocate and initialize a tx descriptor for a HL system.
+ * @details
+ *  Allocate a tx descriptor pair for a new tx frame - a SW tx descriptor
+ *  for private use within the host data SW, and a HTT tx descriptor for
+ *  downloading tx meta-data to the target FW/HW.
+ *  Fill in the fields of this pair of tx descriptors based on the
+ *  information in the netbuf.
+ *
+ * @param pdev - the data physical device sending the data
+ *      (for accessing the tx desc pool)
+ * @param vdev - the virtual device sending the data
+ *      (for specifying the transmitter address for multicast / broadcast data)
+ * @param netbuf - the tx frame
+ * @param msdu_info - tx meta-data
+ */
+struct ol_tx_desc_t *
+ol_tx_desc_hl(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_txrx_vdev_t *vdev,
+		qdf_nbuf_t netbuf,
+		struct ol_txrx_msdu_info_t *msdu_info);
+
+
+/**
+ * @brief Use a tx descriptor ID to find the corresponding descriptor object.
+ *
+ * @param pdev - the data physical device sending the data
+ * @param tx_desc_id - the ID of the descriptor in question
+ * @return the descriptor object that has the specified ID
+ */
+static inline struct ol_tx_desc_t *ol_tx_desc_find(
+			struct ol_txrx_pdev_t *pdev, uint16_t tx_desc_id)
+{
+	void **td_base = (void **)pdev->tx_desc.desc_pages.cacheable_pages;
+
+	return &((union ol_tx_desc_list_elem_t *)
+		(td_base[tx_desc_id >> pdev->tx_desc.page_divider] +
+		(pdev->tx_desc.desc_reserved_size *
+		(tx_desc_id & pdev->tx_desc.offset_filter))))->tx_desc;
+}
+
+/**
+ * @brief Use a tx descriptor ID to find the corresponding descriptor object
+ *    and add sanity check.
+ *
+ * @param pdev - the data physical device sending the data
+ * @param tx_desc_id - the ID of the descriptor in question
+ * @return the descriptor object that has the specified ID,
+ *    if failure, will return NULL.
+ */
+
+#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS
+static inline struct ol_tx_desc_t *
+ol_tx_desc_find_check(struct ol_txrx_pdev_t *pdev, u_int16_t tx_desc_id)
+{
+	struct ol_tx_desc_t *tx_desc;
+
+	if (tx_desc_id >= pdev->tx_desc.pool_size)
+		return NULL;
+
+	tx_desc = ol_tx_desc_find(pdev, tx_desc_id);
+
+	if (tx_desc->pkt_type == ol_tx_frm_freed)
+		return NULL;
+
+	return tx_desc;
+}
+
+#else
+
+static inline struct ol_tx_desc_t *
+ol_tx_desc_find_check(struct ol_txrx_pdev_t *pdev, u_int16_t tx_desc_id)
+{
+	struct ol_tx_desc_t *tx_desc;
+
+	if (tx_desc_id >= pdev->tx_desc.pool_size)
+		return NULL;
+
+	tx_desc = ol_tx_desc_find(pdev, tx_desc_id);
+
+	/* check against invalid tx_desc_id */
+	if (ol_cfg_is_high_latency(pdev->ctrl_pdev) && !tx_desc->vdev)
+		return NULL;
+
+	return tx_desc;
+}
+#endif
+
+/**
+ * @brief Free a list of tx descriptors and the tx frames they refer to.
+ * @details
+ *  Free a batch of "standard" tx descriptors and their tx frames.
+ *  Free each tx descriptor, by returning it to the freelist.
+ *  Unmap each netbuf, and free the netbufs as a batch.
+ *  Irregular tx frames like TSO or management frames that require
+ *  special handling are processed by the ol_tx_desc_frame_free_nonstd
+ *  function rather than this function.
+ *
+ * @param pdev - the data physical device that sent the data
+ * @param tx_descs - a list of SW tx descriptors for the tx frames
+ * @param had_error - bool indication of whether the transmission failed.
+ *            This is provided to callback functions that get notified of
+ *            the tx frame completion.
+ */
+void ol_tx_desc_frame_list_free(struct ol_txrx_pdev_t *pdev,
+				ol_tx_desc_list *tx_descs, int had_error);
+
+/**
+ * @brief Free a non-standard tx frame and its tx descriptor.
+ * @details
+ *  Check the tx frame type (e.g. TSO vs. management) to determine what
+ *  special steps, if any, need to be performed prior to freeing the
+ *  tx frame and its tx descriptor.
+ *  This function can also be used to free single standard tx frames.
+ *  After performing any special steps based on tx frame type, free the
+ *  tx descriptor, i.e. return it to the freelist, and unmap and
+ *  free the netbuf referenced by the tx descriptor.
+ *
+ * @param pdev - the data physical device that sent the data
+ * @param tx_desc - the SW tx descriptor for the tx frame that was sent
+ * @param had_error - bool indication of whether the transmission failed.
+ *            This is provided to callback functions that get notified of
+ *            the tx frame completion.
+ */
+void ol_tx_desc_frame_free_nonstd(struct ol_txrx_pdev_t *pdev,
+				  struct ol_tx_desc_t *tx_desc, int had_error);
+
+/*
+ * @brief Determine the ID of a tx descriptor.
+ *
+ * @param pdev - the physical device that is sending the data
+ * @param tx_desc - the descriptor whose ID is being determined
+ * @return numeric ID that uniquely identifies the tx descriptor
+ */
+static inline uint16_t
+ol_tx_desc_id(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc)
+{
+	TXRX_ASSERT2(tx_desc->id < pdev->tx_desc.pool_size);
+	return tx_desc->id;
+}
+
+/*
+ * @brief Retrieves the beacon headr for the vdev
+ * @param pdev - opaque pointe to scn
+ * @param vdevid - vdev id
+ * @return void pointer to the beacon header for the given vdev
+ */
+
+void *ol_ath_get_bcn_header(struct cdp_cfg *cfg_pdev, A_UINT32 vdev_id);
+
+/*
+ * @brief Free a tx descriptor, without freeing the matching frame.
+ * @details
+ *  This function is using during the function call that submits tx frames
+ *  into the txrx layer, for cases where a tx descriptor is successfully
+ *  allocated, but for other reasons the frame could not be accepted.
+ *
+ * @param pdev - the data physical device that is sending the data
+ * @param tx_desc - the descriptor being freed
+ */
+void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc);
+
+#if defined(FEATURE_TSO)
+struct qdf_tso_seg_elem_t *ol_tso_alloc_segment(struct ol_txrx_pdev_t *pdev);
+
+void ol_tso_free_segment(struct ol_txrx_pdev_t *pdev,
+	 struct qdf_tso_seg_elem_t *tso_seg);
+struct qdf_tso_num_seg_elem_t *ol_tso_num_seg_alloc(
+				struct ol_txrx_pdev_t *pdev);
+void ol_tso_num_seg_free(struct ol_txrx_pdev_t *pdev,
+	 struct qdf_tso_num_seg_elem_t *tso_num_seg);
+void ol_free_remaining_tso_segs(ol_txrx_vdev_handle vdev,
+				struct ol_txrx_msdu_info_t *msdu_info,
+				bool is_tso_seg_mapping_done);
+
+#else
+#define ol_tso_alloc_segment(pdev) /*no-op*/
+#define ol_tso_free_segment(pdev, tso_seg) /*no-op*/
+#define ol_tso_num_seg_alloc(pdev) /*no-op*/
+#define ol_tso_num_seg_free(pdev, tso_num_seg) /*no-op*/
+/*no-op*/
+#define ol_free_remaining_tso_segs(vdev, msdu_info, is_tso_seg_mapping_done)
+#endif
+
+/**
+ * ol_tx_get_desc_global_pool() - get descriptor from global pool
+ * @pdev: pdev handler
+ *
+ * Caller needs to take lock and do sanity checks.
+ *
+ * Return: tx descriptor
+ */
+static inline
+struct ol_tx_desc_t *ol_tx_get_desc_global_pool(struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_tx_desc_t *tx_desc = &pdev->tx_desc.freelist->tx_desc;
+
+	pdev->tx_desc.freelist = pdev->tx_desc.freelist->next;
+	pdev->tx_desc.num_free--;
+	return tx_desc;
+}
+
+/**
+ * ol_tx_put_desc_global_pool() - put descriptor to global pool freelist
+ * @pdev: pdev handle
+ * @tx_desc: tx descriptor
+ *
+ * Caller needs to take lock and do sanity checks.
+ *
+ * Return: none
+ */
+static inline
+void ol_tx_put_desc_global_pool(struct ol_txrx_pdev_t *pdev,
+			struct ol_tx_desc_t *tx_desc)
+{
+	((union ol_tx_desc_list_elem_t *)tx_desc)->next =
+					pdev->tx_desc.freelist;
+	pdev->tx_desc.freelist =
+			 (union ol_tx_desc_list_elem_t *)tx_desc;
+	pdev->tx_desc.num_free++;
+}
+
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_RESIZE
+int ol_tx_distribute_descs_to_deficient_pools_from_global_pool(void);
+#else
+static inline
+int ol_tx_distribute_descs_to_deficient_pools_from_global_pool(void)
+{
+	return 0;
+}
+#endif
+
+int ol_tx_free_invalid_flow_pool(struct ol_tx_flow_pool_t *pool);
+/**
+ * ol_tx_get_desc_flow_pool() - get descriptor from flow pool
+ * @pool: flow pool
+ *
+ * Caller needs to take lock and do sanity checks.
+ *
+ * Return: tx descriptor
+ */
+static inline
+struct ol_tx_desc_t *ol_tx_get_desc_flow_pool(struct ol_tx_flow_pool_t *pool)
+{
+	struct ol_tx_desc_t *tx_desc = &pool->freelist->tx_desc;
+
+	pool->freelist = pool->freelist->next;
+	pool->avail_desc--;
+	return tx_desc;
+}
+
+/**
+ * ol_tx_put_desc_flow_pool() - put descriptor to flow pool freelist
+ * @pool: flow pool
+ * @tx_desc: tx descriptor
+ *
+ * Caller needs to take lock and do sanity checks.
+ *
+ * Return: none
+ */
+static inline
+void ol_tx_put_desc_flow_pool(struct ol_tx_flow_pool_t *pool,
+			struct ol_tx_desc_t *tx_desc)
+{
+	tx_desc->pool = pool;
+	((union ol_tx_desc_list_elem_t *)tx_desc)->next = pool->freelist;
+	pool->freelist = (union ol_tx_desc_list_elem_t *)tx_desc;
+	pool->avail_desc++;
+}
+
+#else
+static inline int ol_tx_free_invalid_flow_pool(void *pool)
+{
+	return 0;
+}
+#endif
+
+#ifdef DESC_DUP_DETECT_DEBUG
+/**
+ * ol_tx_desc_dup_detect_init() - initialize descriptor duplication logic
+ * @pdev: pdev handle
+ * @pool_size: global pool size
+ *
+ * Return: none
+ */
+static inline
+void ol_tx_desc_dup_detect_init(struct ol_txrx_pdev_t *pdev, uint16_t pool_size)
+{
+	uint16_t size = (pool_size >> DIV_BY_8) +
+		sizeof(*pdev->tx_desc.free_list_bitmap);
+	pdev->tx_desc.free_list_bitmap = qdf_mem_malloc(size);
+	if (!pdev->tx_desc.free_list_bitmap)
+		qdf_print("%s: malloc failed", __func__);
+}
+
+/**
+ * ol_tx_desc_dup_detect_deinit() - deinit descriptor duplication logic
+ * @pdev: pdev handle
+ *
+ * Return: none
+ */
+static inline
+void ol_tx_desc_dup_detect_deinit(struct ol_txrx_pdev_t *pdev)
+{
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: pool_size %d num_free %d\n", __func__,
+		pdev->tx_desc.pool_size, pdev->tx_desc.num_free);
+	if (pdev->tx_desc.free_list_bitmap)
+		qdf_mem_free(pdev->tx_desc.free_list_bitmap);
+}
+
+/**
+ * ol_tx_desc_dup_detect_set() - set bit for msdu_id
+ * @pdev: pdev handle
+ * @tx_desc: tx descriptor
+ *
+ * Return: none
+ */
+static inline
+void ol_tx_desc_dup_detect_set(struct ol_txrx_pdev_t *pdev,
+				struct ol_tx_desc_t *tx_desc)
+{
+	uint16_t msdu_id = ol_tx_desc_id(pdev, tx_desc);
+	bool test;
+
+	if (!pdev->tx_desc.free_list_bitmap)
+		return;
+
+	if (qdf_unlikely(msdu_id > pdev->tx_desc.pool_size)) {
+		qdf_print("%s: msdu_id %d > pool_size %d",
+			  __func__, msdu_id, pdev->tx_desc.pool_size);
+		QDF_BUG(0);
+	}
+
+	test = test_and_set_bit(msdu_id, pdev->tx_desc.free_list_bitmap);
+	if (qdf_unlikely(test)) {
+		uint16_t size = (pdev->tx_desc.pool_size >> DIV_BY_8) +
+			((pdev->tx_desc.pool_size & MOD_BY_8) ? 1 : 0);
+		qdf_print("duplicate msdu_id %d detected !!\n", msdu_id);
+		qdf_trace_hex_dump(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		(void *)pdev->tx_desc.free_list_bitmap, size);
+		QDF_BUG(0);
+	}
+}
+
+/**
+ * ol_tx_desc_dup_detect_reset() - reset bit for msdu_id
+ * @pdev: pdev handle
+ * @tx_desc: tx descriptor
+ *
+ * Return: none
+ */
+static inline
+void ol_tx_desc_dup_detect_reset(struct ol_txrx_pdev_t *pdev,
+				 struct ol_tx_desc_t *tx_desc)
+{
+	uint16_t msdu_id = ol_tx_desc_id(pdev, tx_desc);
+	bool test;
+
+	if (!pdev->tx_desc.free_list_bitmap)
+		return;
+
+	if (qdf_unlikely(msdu_id > pdev->tx_desc.pool_size)) {
+		qdf_print("%s: msdu_id %d > pool_size %d",
+			  __func__, msdu_id, pdev->tx_desc.pool_size);
+		QDF_BUG(0);
+	}
+
+	test = !test_and_clear_bit(msdu_id, pdev->tx_desc.free_list_bitmap);
+	if (qdf_unlikely(test)) {
+		uint16_t size = (pdev->tx_desc.pool_size >> DIV_BY_8) +
+			((pdev->tx_desc.pool_size & MOD_BY_8) ? 1 : 0);
+		qdf_print("duplicate free msg received for msdu_id %d!!\n",
+								 msdu_id);
+		qdf_trace_hex_dump(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		(void *)pdev->tx_desc.free_list_bitmap, size);
+		QDF_BUG(0);
+	}
+}
+#else
+static inline
+void ol_tx_desc_dup_detect_init(struct ol_txrx_pdev_t *pdev, uint16_t size)
+{
+}
+
+static inline
+void ol_tx_desc_dup_detect_deinit(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+static inline
+void ol_tx_desc_dup_detect_set(struct ol_txrx_pdev_t *pdev,
+				struct ol_tx_desc_t *tx_desc)
+{
+}
+
+static inline
+void ol_tx_desc_dup_detect_reset(struct ol_txrx_pdev_t *pdev,
+				 struct ol_tx_desc_t *tx_desc)
+{
+}
+#endif
+
+enum extension_header_type
+ol_tx_get_ext_header_type(struct ol_txrx_vdev_t *vdev,
+	qdf_nbuf_t netbuf);
+enum extension_header_type
+ol_tx_get_wisa_ext_type(qdf_nbuf_t netbuf);
+
+
+#endif /* _OL_TX_DESC__H_ */
diff --git a/core/dp/txrx/ol_tx_hl.c b/core/dp/txrx/ol_tx_hl.c
new file mode 100644
index 0000000..4c9e0d3
--- /dev/null
+++ b/core/dp/txrx/ol_tx_hl.c
@@ -0,0 +1,1252 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#include <qdf_atomic.h>         /* qdf_atomic_inc, etc. */
+#include <qdf_lock.h>           /* qdf_os_spinlock */
+#include <qdf_time.h>           /* qdf_system_ticks, etc. */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <qdf_net_types.h>      /* QDF_NBUF_TX_EXT_TID_INVALID */
+
+#include <cds_queue.h>          /* TAILQ */
+#ifdef QCA_COMPUTE_TX_DELAY
+#include <enet.h>               /* ethernet_hdr_t, etc. */
+#include <ipv6_defs.h>          /* ipv6_traffic_class */
+#endif
+
+#include <ol_txrx_api.h>        /* ol_txrx_vdev_handle, etc. */
+#include <ol_htt_tx_api.h>      /* htt_tx_compl_desc_id */
+#include <ol_txrx_htt_api.h>    /* htt_tx_status */
+
+#include <ol_ctrl_txrx_api.h>
+#include <cdp_txrx_tx_delay.h>
+#include <ol_txrx_types.h>      /* ol_txrx_vdev_t, etc */
+#include <ol_tx_desc.h>         /* ol_tx_desc_find, ol_tx_desc_frame_free */
+#ifdef QCA_COMPUTE_TX_DELAY
+#include <ol_tx_classify.h>     /* ol_tx_dest_addr_find */
+#endif
+#include <ol_txrx_internal.h>   /* OL_TX_DESC_NO_REFS, etc. */
+#include <ol_osif_txrx_api.h>
+#include <ol_tx.h>              /* ol_tx_reinject */
+#include <ol_tx_send.h>
+
+#include <ol_cfg.h>             /* ol_cfg_is_high_latency */
+#include <ol_tx_sched.h>
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+#include <ol_txrx_encap.h>      /* OL_TX_RESTORE_HDR, etc */
+#endif
+#include <ol_tx_queue.h>
+#include <ol_txrx.h>
+#include <pktlog_ac_fmt.h>
+#include <cdp_txrx_handle.h>
+
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+static u16 ol_txrx_tx_desc_alloc_table[TXRX_FC_MAX] = {
+	[TXRX_FC_5GH_80M_2x2] = 2000,
+	[TXRX_FC_2GH_40M_2x2] = 800,
+};
+#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
+
+/* tx filtering is handled within the target FW */
+#define TX_FILTER_CHECK(tx_msdu_info) 0 /* don't filter */
+
+u_int16_t
+ol_tx_desc_pool_size_hl(struct cdp_cfg *ctrl_pdev)
+{
+	uint16_t desc_pool_size;
+	uint16_t steady_state_tx_lifetime_ms;
+	uint16_t safety_factor;
+
+	/*
+	 * Steady-state tx latency:
+	 *     roughly 1-2 ms flight time
+	 *   + roughly 1-2 ms prep time,
+	 *   + roughly 1-2 ms target->host notification time.
+	 * = roughly 6 ms total
+	 * Thus, steady state number of frames =
+	 * steady state max throughput / frame size * tx latency, e.g.
+	 * 1 Gbps / 1500 bytes * 6 ms = 500
+	 *
+	 */
+	steady_state_tx_lifetime_ms = 6;
+
+	safety_factor = 8;
+
+	desc_pool_size =
+		ol_cfg_max_thruput_mbps(ctrl_pdev) *
+		1000 /* 1e6 bps/mbps / 1e3 ms per sec = 1000 */ /
+		(8 * OL_TX_AVG_FRM_BYTES) *
+		steady_state_tx_lifetime_ms *
+		safety_factor;
+
+	/* minimum */
+	if (desc_pool_size < OL_TX_DESC_POOL_SIZE_MIN_HL)
+		desc_pool_size = OL_TX_DESC_POOL_SIZE_MIN_HL;
+
+	/* maximum */
+	if (desc_pool_size > OL_TX_DESC_POOL_SIZE_MAX_HL)
+		desc_pool_size = OL_TX_DESC_POOL_SIZE_MAX_HL;
+
+	return desc_pool_size;
+}
+
+#ifdef CONFIG_TX_DESC_HI_PRIO_RESERVE
+
+/**
+ * ol_tx_hl_desc_alloc() - Allocate and initialize a tx descriptor
+ *                        for a HL system.
+ * @pdev: the data physical device sending the data
+ * @vdev: the virtual device sending the data
+ * @msdu: the tx frame
+ * @msdu_info: the tx meta data
+ *
+ * Return: the tx decriptor
+ */
+static inline
+struct ol_tx_desc_t *ol_tx_hl_desc_alloc(struct ol_txrx_pdev_t *pdev,
+					 struct ol_txrx_vdev_t *vdev,
+					 qdf_nbuf_t msdu,
+					 struct ol_txrx_msdu_info_t *msdu_info)
+{
+	struct ol_tx_desc_t *tx_desc = NULL;
+
+	if (qdf_atomic_read(&pdev->tx_queue.rsrc_cnt) >
+	    TXRX_HL_TX_DESC_HI_PRIO_RESERVED) {
+		tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, msdu_info);
+	} else if (qdf_nbuf_is_ipv4_pkt(msdu) == true) {
+		if ((QDF_NBUF_CB_GET_PACKET_TYPE(msdu) ==
+		    QDF_NBUF_CB_PACKET_TYPE_DHCP) ||
+		    (QDF_NBUF_CB_GET_PACKET_TYPE(msdu) ==
+		    QDF_NBUF_CB_PACKET_TYPE_EAPOL)) {
+			tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, msdu_info);
+			ol_txrx_info("Got tx desc from resv pool\n");
+		}
+	}
+	return tx_desc;
+}
+
+#elif defined(QCA_HL_NETDEV_FLOW_CONTROL)
+bool ol_tx_desc_is_high_prio(qdf_nbuf_t msdu)
+{
+	enum qdf_proto_subtype proto_subtype;
+	bool high_prio = false;
+
+	if (qdf_nbuf_is_ipv4_pkt(msdu) == true) {
+		if ((QDF_NBUF_CB_GET_PACKET_TYPE(msdu) ==
+		    QDF_NBUF_CB_PACKET_TYPE_DHCP) ||
+		    (QDF_NBUF_CB_GET_PACKET_TYPE(msdu) ==
+		    QDF_NBUF_CB_PACKET_TYPE_EAPOL))
+			high_prio = true;
+	} else if (QDF_NBUF_CB_GET_PACKET_TYPE(msdu) ==
+		   QDF_NBUF_CB_PACKET_TYPE_ARP) {
+		high_prio = true;
+	} else if ((QDF_NBUF_CB_GET_PACKET_TYPE(msdu) ==
+		   QDF_NBUF_CB_PACKET_TYPE_ICMPv6)) {
+		proto_subtype = qdf_nbuf_get_icmpv6_subtype(msdu);
+		switch (proto_subtype) {
+		case QDF_PROTO_ICMPV6_NA:
+		case QDF_PROTO_ICMPV6_NS:
+			high_prio = true;
+		default:
+			high_prio = false;
+		}
+	}
+	return high_prio;
+}
+
+static inline
+struct ol_tx_desc_t *ol_tx_hl_desc_alloc(struct ol_txrx_pdev_t *pdev,
+					 struct ol_txrx_vdev_t *vdev,
+					 qdf_nbuf_t msdu,
+					 struct ol_txrx_msdu_info_t *msdu_info)
+{
+	struct ol_tx_desc_t *tx_desc =
+			ol_tx_desc_hl(pdev, vdev, msdu, msdu_info);
+
+	if (!tx_desc)
+		return NULL;
+
+	qdf_spin_lock_bh(&pdev->tx_mutex);
+	/* return if TX flow control disabled */
+	if (vdev->tx_desc_limit == 0) {
+		qdf_spin_unlock_bh(&pdev->tx_mutex);
+		return tx_desc;
+	}
+
+	if (!qdf_atomic_read(&vdev->os_q_paused) &&
+	    (qdf_atomic_read(&vdev->tx_desc_count) >= vdev->queue_stop_th)) {
+		/*
+		 * Pause normal priority
+		 * netdev queues if tx desc limit crosses
+		 */
+		pdev->pause_cb(vdev->vdev_id,
+			       WLAN_STOP_NON_PRIORITY_QUEUE,
+			       WLAN_DATA_FLOW_CONTROL);
+		qdf_atomic_set(&vdev->os_q_paused, 1);
+	} else if (ol_tx_desc_is_high_prio(msdu) && !vdev->prio_q_paused &&
+		   (qdf_atomic_read(&vdev->tx_desc_count)
+		   == vdev->tx_desc_limit)) {
+		/* Pause high priority queue */
+		pdev->pause_cb(vdev->vdev_id,
+			       WLAN_NETIF_PRIORITY_QUEUE_OFF,
+			       WLAN_DATA_FLOW_CONTROL_PRIORITY);
+		vdev->prio_q_paused = 1;
+	}
+	qdf_spin_unlock_bh(&pdev->tx_mutex);
+
+	return tx_desc;
+}
+
+#else
+
+static inline
+struct ol_tx_desc_t *ol_tx_hl_desc_alloc(struct ol_txrx_pdev_t *pdev,
+					 struct ol_txrx_vdev_t *vdev,
+					 qdf_nbuf_t msdu,
+					 struct ol_txrx_msdu_info_t *msdu_info)
+{
+	struct ol_tx_desc_t *tx_desc = NULL;
+
+	tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, msdu_info);
+	return tx_desc;
+}
+#endif
+
+#ifdef CONFIG_PER_VDEV_TX_DESC_POOL
+/**
+ * ol_txrx_rsrc_threshold_lo() - set threshold low - when to start tx desc
+ *				 margin replenishment
+ * @desc_pool_size: tx desc pool size
+ *
+ * Return: threshold low
+ */
+static inline uint16_t
+ol_txrx_rsrc_threshold_lo(int desc_pool_size)
+{
+	int threshold_low;
+
+	/*
+	 * 5% margin of unallocated desc is too much for per
+	 * vdev mechanism.
+	 * Define the value separately.
+	 */
+	threshold_low = TXRX_HL_TX_FLOW_CTRL_MGMT_RESERVED;
+
+	return threshold_low;
+}
+
+/**
+ * ol_txrx_rsrc_threshold_hi() - set threshold high - where to stop
+ *				 during tx desc margin replenishment
+ * @desc_pool_size: tx desc pool size
+ *
+ * Return: threshold high
+ */
+static inline uint16_t
+ol_txrx_rsrc_threshold_hi(int desc_pool_size)
+{
+	int threshold_high;
+	/* when freeing up descriptors,
+	 * keep going until there's a 7.5% margin
+	 */
+	threshold_high = ((15 * desc_pool_size) / 100) / 2;
+
+	return threshold_high;
+}
+
+#else
+
+static inline uint16_t
+ol_txrx_rsrc_threshold_lo(int desc_pool_size)
+{
+	int threshold_low;
+	/* always maintain a 5% margin of unallocated descriptors */
+	threshold_low = (5 * desc_pool_size) / 100;
+
+	return threshold_low;
+}
+
+static inline uint16_t
+ol_txrx_rsrc_threshold_hi(int desc_pool_size)
+{
+	int threshold_high;
+	/* when freeing up descriptors, keep going until
+	 * there's a 15% margin
+	 */
+	threshold_high = (15 * desc_pool_size) / 100;
+
+	return threshold_high;
+}
+#endif
+
+void ol_tx_init_pdev(ol_txrx_pdev_handle pdev)
+{
+	uint16_t desc_pool_size, i;
+
+	desc_pool_size = ol_tx_desc_pool_size_hl(pdev->ctrl_pdev);
+
+	qdf_atomic_init(&pdev->tx_queue.rsrc_cnt);
+	qdf_atomic_add(desc_pool_size, &pdev->tx_queue.rsrc_cnt);
+
+	pdev->tx_queue.rsrc_threshold_lo =
+		ol_txrx_rsrc_threshold_lo(desc_pool_size);
+	pdev->tx_queue.rsrc_threshold_hi =
+		ol_txrx_rsrc_threshold_hi(desc_pool_size);
+
+	for (i = 0 ; i < OL_TX_MAX_TXQ_GROUPS; i++)
+		qdf_atomic_init(&pdev->txq_grps[i].credit);
+
+	ol_tx_target_credit_init(pdev, desc_pool_size);
+}
+
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+static inline int ol_tx_encap_wrapper(struct ol_txrx_pdev_t *pdev,
+				      ol_txrx_vdev_handle vdev,
+				      struct ol_tx_desc_t *tx_desc,
+				      qdf_nbuf_t msdu,
+				      struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	if (OL_TX_ENCAP(vdev, tx_desc, msdu, tx_msdu_info) != A_OK) {
+		qdf_atomic_inc(&pdev->tx_queue.rsrc_cnt);
+		ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1);
+		if (tx_msdu_info->peer) {
+			/* remove the peer reference added above */
+			ol_txrx_peer_release_ref(tx_msdu_info->peer,
+						 PEER_DEBUG_ID_OL_INTERNAL);
+		}
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#else
+static inline int ol_tx_encap_wrapper(struct ol_txrx_pdev_t *pdev,
+				      ol_txrx_vdev_handle vdev,
+				      struct ol_tx_desc_t *tx_desc,
+				      qdf_nbuf_t msdu,
+				      struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	/* no-op */
+	return 0;
+}
+#endif
+
+/**
+ * parse_ocb_tx_header() - Function to check for OCB
+ * @msdu:   Pointer to OS packet (qdf_nbuf_t)
+ * @tx_ctrl: TX control header on a packet and extract it if present
+ *
+ * Return: true if ocb parsing is successful
+ */
+#ifdef WLAN_FEATURE_DSRC
+#define OCB_HEADER_VERSION     1
+static bool parse_ocb_tx_header(qdf_nbuf_t msdu,
+				struct ocb_tx_ctrl_hdr_t *tx_ctrl)
+{
+	struct ether_header *eth_hdr_p;
+	struct ocb_tx_ctrl_hdr_t *tx_ctrl_hdr;
+
+	/* Check if TX control header is present */
+	eth_hdr_p = (struct ether_header *)qdf_nbuf_data(msdu);
+	if (eth_hdr_p->ether_type != QDF_SWAP_U16(ETHERTYPE_OCB_TX))
+		/* TX control header is not present. Nothing to do.. */
+		return true;
+
+	/* Remove the ethernet header */
+	qdf_nbuf_pull_head(msdu, sizeof(struct ether_header));
+
+	/* Parse the TX control header */
+	tx_ctrl_hdr = (struct ocb_tx_ctrl_hdr_t *)qdf_nbuf_data(msdu);
+
+	if (tx_ctrl_hdr->version == OCB_HEADER_VERSION) {
+		if (tx_ctrl)
+			qdf_mem_copy(tx_ctrl, tx_ctrl_hdr,
+				     sizeof(*tx_ctrl_hdr));
+	} else {
+		/* The TX control header is invalid. */
+		return false;
+	}
+
+	/* Remove the TX control header */
+	qdf_nbuf_pull_head(msdu, tx_ctrl_hdr->length);
+	return true;
+}
+#else
+static bool parse_ocb_tx_header(qdf_nbuf_t msdu,
+				struct ocb_tx_ctrl_hdr_t *tx_ctrl)
+{
+	return true;
+}
+#endif
+
+/**
+ * ol_txrx_mgmt_tx_desc_alloc() - Allocate and initialize a tx descriptor
+ *				 for management frame
+ * @pdev: the data physical device sending the data
+ * @vdev: the virtual device sending the data
+ * @tx_mgmt_frm: the tx management frame
+ * @tx_msdu_info: the tx meta data
+ *
+ * Return: the tx decriptor
+ */
+struct ol_tx_desc_t *
+ol_txrx_mgmt_tx_desc_alloc(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_vdev_t *vdev,
+	qdf_nbuf_t tx_mgmt_frm,
+	struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	struct ol_tx_desc_t *tx_desc;
+
+	tx_msdu_info->htt.action.tx_comp_req = 1;
+	tx_desc = ol_tx_desc_hl(pdev, vdev, tx_mgmt_frm, tx_msdu_info);
+	return tx_desc;
+}
+
+/**
+ * ol_txrx_mgmt_send_frame() - send a management frame
+ * @vdev: virtual device sending the frame
+ * @tx_desc: tx desc
+ * @tx_mgmt_frm: management frame to send
+ * @tx_msdu_info: the tx meta data
+ * @chanfreq: download change frequency
+ *
+ * Return:
+ *      0 -> the frame is accepted for transmission, -OR-
+ *      1 -> the frame was not accepted
+ */
+int ol_txrx_mgmt_send_frame(
+	struct ol_txrx_vdev_t *vdev,
+	struct ol_tx_desc_t *tx_desc,
+	qdf_nbuf_t tx_mgmt_frm,
+	struct ol_txrx_msdu_info_t *tx_msdu_info,
+	uint16_t chanfreq)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	struct ol_tx_frms_queue_t *txq;
+	int status = 1;
+
+	/*
+	 * 1.  Look up the peer and queue the frame in the peer's mgmt queue.
+	 * 2.  Invoke the download scheduler.
+	 */
+	txq = ol_tx_classify_mgmt(vdev, tx_desc, tx_mgmt_frm, tx_msdu_info);
+	if (!txq) {
+		/* TXRX_STATS_MSDU_LIST_INCR(vdev->pdev, tx.dropped.no_txq,
+		 *			     msdu);
+		 */
+		qdf_atomic_inc(&pdev->tx_queue.rsrc_cnt);
+		ol_tx_desc_frame_free_nonstd(vdev->pdev, tx_desc,
+					     1 /* error */);
+		goto out; /* can't accept the tx mgmt frame */
+	}
+	/* Initialize the HTT tx desc l2 header offset field.
+	 * Even though tx encap does not apply to mgmt frames,
+	 * htt_tx_desc_mpdu_header still needs to be called,
+	 * to specifiy that there was no L2 header added by tx encap,
+	 * so the frame's length does not need to be adjusted to account for
+	 * an added L2 header.
+	 */
+	htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc, 0);
+	if (qdf_unlikely(htt_tx_desc_init(
+			pdev->htt_pdev, tx_desc->htt_tx_desc,
+			tx_desc->htt_tx_desc_paddr,
+			ol_tx_desc_id(pdev, tx_desc),
+			tx_mgmt_frm,
+			&tx_msdu_info->htt, &tx_msdu_info->tso_info, NULL, 0)))
+		goto out;
+	htt_tx_desc_display(tx_desc->htt_tx_desc);
+	htt_tx_desc_set_chanfreq(tx_desc->htt_tx_desc, chanfreq);
+
+	ol_tx_enqueue(vdev->pdev, txq, tx_desc, tx_msdu_info);
+	ol_tx_sched(vdev->pdev);
+	status = 0;
+out:
+	if (tx_msdu_info->peer) {
+		/* remove the peer reference added above */
+		ol_txrx_peer_release_ref(tx_msdu_info->peer,
+					 PEER_DEBUG_ID_OL_INTERNAL);
+	}
+
+	return status;
+}
+
+/**
+ * ol_tx_hl_base() - send tx frames for a HL system.
+ * @vdev: the virtual device sending the data
+ * @tx_spec: indicate what non-standard transmission actions to apply
+ * @msdu_list: the tx frames to send
+ * @tx_comp_req: tx completion req
+ *
+ * Return: NULL if all MSDUs are accepted
+ */
+static inline qdf_nbuf_t
+ol_tx_hl_base(
+	ol_txrx_vdev_handle vdev,
+	enum ol_tx_spec tx_spec,
+	qdf_nbuf_t msdu_list,
+	int tx_comp_req)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	qdf_nbuf_t msdu = msdu_list;
+	struct ol_txrx_msdu_info_t tx_msdu_info;
+	struct ocb_tx_ctrl_hdr_t tx_ctrl;
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+
+	tx_msdu_info.tso_info.is_tso = 0;
+
+	/*
+	 * The msdu_list variable could be used instead of the msdu var,
+	 * but just to clarify which operations are done on a single MSDU
+	 * vs. a list of MSDUs, use a distinct variable for single MSDUs
+	 * within the list.
+	 */
+	while (msdu) {
+		qdf_nbuf_t next;
+		struct ol_tx_frms_queue_t *txq;
+		struct ol_tx_desc_t *tx_desc = NULL;
+
+		qdf_mem_zero(&tx_ctrl, sizeof(tx_ctrl));
+		tx_msdu_info.peer = NULL;
+		/*
+		 * The netbuf will get stored into a (peer-TID) tx queue list
+		 * inside the ol_tx_classify_store function or else dropped,
+		 * so store the next pointer immediately.
+		 */
+		next = qdf_nbuf_next(msdu);
+
+		tx_desc = ol_tx_hl_desc_alloc(pdev, vdev, msdu, &tx_msdu_info);
+
+		if (!tx_desc) {
+			/*
+			 * If we're out of tx descs, there's no need to try
+			 * to allocate tx descs for the remaining MSDUs.
+			 */
+			TXRX_STATS_MSDU_LIST_INCR(pdev, tx.dropped.host_reject,
+						  msdu);
+			return msdu; /* the list of unaccepted MSDUs */
+		}
+
+		/* OL_TXRX_PROT_AN_LOG(pdev->prot_an_tx_sent, msdu);*/
+
+		if (tx_spec != OL_TX_SPEC_STD) {
+#if defined(FEATURE_WLAN_TDLS)
+			if (tx_spec & OL_TX_SPEC_NO_FREE) {
+				tx_desc->pkt_type = OL_TX_FRM_NO_FREE;
+			} else if (tx_spec & OL_TX_SPEC_TSO) {
+#else
+				if (tx_spec & OL_TX_SPEC_TSO) {
+#endif
+					tx_desc->pkt_type = OL_TX_FRM_TSO;
+				}
+				if (ol_txrx_tx_is_raw(tx_spec)) {
+					/* CHECK THIS: does this need
+					 * to happen after htt_tx_desc_init?
+					 */
+					/* different types of raw frames */
+					u_int8_t sub_type =
+						ol_txrx_tx_raw_subtype(
+								tx_spec);
+					htt_tx_desc_type(htt_pdev,
+							 tx_desc->htt_tx_desc,
+							 htt_pkt_type_raw,
+							 sub_type);
+				}
+			}
+
+			tx_msdu_info.htt.info.ext_tid = qdf_nbuf_get_tid(msdu);
+			tx_msdu_info.htt.info.vdev_id = vdev->vdev_id;
+			tx_msdu_info.htt.info.frame_type = htt_frm_type_data;
+			tx_msdu_info.htt.info.l2_hdr_type = pdev->htt_pkt_type;
+			tx_msdu_info.htt.action.tx_comp_req = tx_comp_req;
+
+			/* If the vdev is in OCB mode,
+			 * parse the tx control header.
+			 */
+			if (vdev->opmode == wlan_op_mode_ocb) {
+				if (!parse_ocb_tx_header(msdu, &tx_ctrl)) {
+					/* There was an error parsing
+					 * the header.Skip this packet.
+					 */
+					goto MSDU_LOOP_BOTTOM;
+				}
+			}
+
+			txq = ol_tx_classify(vdev, tx_desc, msdu,
+					     &tx_msdu_info);
+
+			/* initialize the HW tx descriptor */
+			htt_tx_desc_init(
+					pdev->htt_pdev, tx_desc->htt_tx_desc,
+					tx_desc->htt_tx_desc_paddr,
+					ol_tx_desc_id(pdev, tx_desc),
+					msdu,
+					&tx_msdu_info.htt,
+					&tx_msdu_info.tso_info,
+					&tx_ctrl,
+					vdev->opmode == wlan_op_mode_ocb);
+
+			if ((!txq) || TX_FILTER_CHECK(&tx_msdu_info)) {
+				/* drop this frame,
+				 * but try sending subsequent frames
+				 */
+				/* TXRX_STATS_MSDU_LIST_INCR(pdev,
+				 * tx.dropped.no_txq, msdu);
+				 */
+				qdf_atomic_inc(&pdev->tx_queue.rsrc_cnt);
+				ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1);
+				if (tx_msdu_info.peer) {
+					/* remove the peer reference
+					 * added above
+					 */
+					ol_txrx_peer_release_ref(
+						tx_msdu_info.peer,
+						PEER_DEBUG_ID_OL_INTERNAL);
+				}
+				goto MSDU_LOOP_BOTTOM;
+			}
+
+			if (tx_msdu_info.peer) {
+				/*
+				 * If the state is not associated then drop all
+				 * the data packets received for that peer
+				 */
+				if (tx_msdu_info.peer->state ==
+						OL_TXRX_PEER_STATE_DISC) {
+					qdf_atomic_inc(
+						&pdev->tx_queue.rsrc_cnt);
+					ol_tx_desc_frame_free_nonstd(pdev,
+								     tx_desc,
+								     1);
+					ol_txrx_peer_release_ref(
+						tx_msdu_info.peer,
+						PEER_DEBUG_ID_OL_INTERNAL);
+					msdu = next;
+					continue;
+				} else if (tx_msdu_info.peer->state !=
+						OL_TXRX_PEER_STATE_AUTH) {
+					if (tx_msdu_info.htt.info.ethertype !=
+						ETHERTYPE_PAE &&
+						tx_msdu_info.htt.info.ethertype
+							!= ETHERTYPE_WAI) {
+						qdf_atomic_inc(
+							&pdev->tx_queue.
+								rsrc_cnt);
+						ol_tx_desc_frame_free_nonstd(
+								pdev,
+								tx_desc, 1);
+						ol_txrx_peer_release_ref(
+						 tx_msdu_info.peer,
+						 PEER_DEBUG_ID_OL_INTERNAL);
+						msdu = next;
+						continue;
+					}
+				}
+			}
+			/*
+			 * Initialize the HTT tx desc l2 header offset field.
+			 * htt_tx_desc_mpdu_header  needs to be called to
+			 * make sure, the l2 header size is initialized
+			 * correctly to handle cases where TX ENCAP is disabled
+			 * or Tx Encap fails to perform Encap
+			 */
+			htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc, 0);
+
+			/*
+			 * Note: when the driver is built without support for
+			 * SW tx encap,the following macro is a no-op.
+			 * When the driver is built with support for SW tx
+			 * encap, it performs encap, and if an error is
+			 * encountered, jumps to the MSDU_LOOP_BOTTOM label.
+			 */
+			if (ol_tx_encap_wrapper(pdev, vdev, tx_desc, msdu,
+						&tx_msdu_info))
+				goto MSDU_LOOP_BOTTOM;
+
+			/*
+			 * If debug display is enabled, show the meta-data
+			 * being downloaded to the target via the
+			 * HTT tx descriptor.
+			 */
+			htt_tx_desc_display(tx_desc->htt_tx_desc);
+
+			ol_tx_enqueue(pdev, txq, tx_desc, &tx_msdu_info);
+			if (tx_msdu_info.peer) {
+				OL_TX_PEER_STATS_UPDATE(tx_msdu_info.peer,
+							msdu);
+				/* remove the peer reference added above */
+				ol_txrx_peer_release_ref
+						(tx_msdu_info.peer,
+						 PEER_DEBUG_ID_OL_INTERNAL);
+			}
+MSDU_LOOP_BOTTOM:
+			msdu = next;
+		}
+		ol_tx_sched(pdev);
+		return NULL; /* all MSDUs were accepted */
+}
+
+qdf_nbuf_t
+ol_tx_hl(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	int tx_comp_req = pdev->cfg.default_tx_comp_req ||
+				pdev->cfg.request_tx_comp;
+
+	return ol_tx_hl_base(vdev, OL_TX_SPEC_STD, msdu_list, tx_comp_req);
+}
+
+qdf_nbuf_t ol_tx_non_std_hl(struct ol_txrx_vdev_t *vdev,
+			    enum ol_tx_spec tx_spec,
+			    qdf_nbuf_t msdu_list)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	int tx_comp_req = pdev->cfg.default_tx_comp_req ||
+				pdev->cfg.request_tx_comp;
+
+	if (!tx_comp_req) {
+		if ((tx_spec == OL_TX_SPEC_NO_FREE) &&
+		    (pdev->tx_data_callback.func))
+			tx_comp_req = 1;
+	}
+	return ol_tx_hl_base(vdev, tx_spec, msdu_list, tx_comp_req);
+}
+
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * ol_txrx_copy_mac_addr_raw() - copy raw mac addr
+ * @vdev: the data virtual device
+ * @bss_addr: bss address
+ *
+ * Return: None
+ */
+void ol_txrx_copy_mac_addr_raw(struct cdp_vdev *pvdev, uint8_t *bss_addr)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t  *)pvdev;
+
+	qdf_spin_lock_bh(&vdev->pdev->last_real_peer_mutex);
+	if (bss_addr && vdev->last_real_peer &&
+	    !qdf_mem_cmp((u8 *)bss_addr,
+			     vdev->last_real_peer->mac_addr.raw,
+			     IEEE80211_ADDR_LEN))
+		qdf_mem_copy(vdev->hl_tdls_ap_mac_addr.raw,
+			     vdev->last_real_peer->mac_addr.raw,
+			     OL_TXRX_MAC_ADDR_LEN);
+	qdf_spin_unlock_bh(&vdev->pdev->last_real_peer_mutex);
+}
+
+/**
+ * ol_txrx_add_last_real_peer() - add last peer
+ * @pdev: the data physical device
+ * @vdev: virtual device
+ * @peer_id: peer id
+ *
+ * Return: None
+ */
+void
+ol_txrx_add_last_real_peer(struct cdp_pdev *ppdev,
+			   struct cdp_vdev *pvdev, uint8_t *peer_id)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	ol_txrx_peer_handle peer;
+
+	peer = ol_txrx_find_peer_by_addr(
+		(struct cdp_pdev *)pdev,
+		vdev->hl_tdls_ap_mac_addr.raw,
+		peer_id);
+
+	qdf_spin_lock_bh(&pdev->last_real_peer_mutex);
+	if (!vdev->last_real_peer && peer &&
+	    (peer->peer_ids[0] != HTT_INVALID_PEER_ID))
+		vdev->last_real_peer = peer;
+	qdf_spin_unlock_bh(&pdev->last_real_peer_mutex);
+}
+
+/**
+ * is_vdev_restore_last_peer() - check for vdev last peer
+ * @peer: peer object
+ *
+ * Return: true if last peer is not null
+ */
+bool is_vdev_restore_last_peer(void *ppeer)
+{
+	struct ol_txrx_peer_t *peer = ppeer;
+	struct ol_txrx_vdev_t *vdev;
+
+	vdev = peer->vdev;
+	return vdev->last_real_peer && (vdev->last_real_peer == peer);
+}
+
+/**
+ * ol_txrx_update_last_real_peer() - check for vdev last peer
+ * @pdev: the data physical device
+ * @peer: peer device
+ * @peer_id: peer id
+ * @restore_last_peer: restore last peer flag
+ *
+ * Return: None
+ */
+void ol_txrx_update_last_real_peer(struct cdp_pdev *ppdev, void *ppeer,
+				   uint8_t *peer_id, bool restore_last_peer)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	struct ol_txrx_peer_t *peer = ppeer;
+	struct ol_txrx_vdev_t *vdev;
+
+	if (!restore_last_peer)
+		return;
+
+	vdev = peer->vdev;
+	peer = ol_txrx_find_peer_by_addr((struct cdp_pdev *)pdev,
+					 vdev->hl_tdls_ap_mac_addr.raw,
+					 peer_id);
+
+	qdf_spin_lock_bh(&pdev->last_real_peer_mutex);
+	if (!vdev->last_real_peer && peer &&
+	    (peer->peer_ids[0] != HTT_INVALID_PEER_ID))
+		vdev->last_real_peer = peer;
+	qdf_spin_unlock_bh(&pdev->last_real_peer_mutex);
+}
+#endif
+
+#if defined(CONFIG_HL_SUPPORT) && defined(DEBUG_HL_LOGGING)
+/**
+ * ol_txrx_pdev_txq_log_init() - initialise pdev txq logs
+ * @pdev: the physical device object
+ *
+ * Return: None
+ */
+void ol_txrx_pdev_txq_log_init(struct ol_txrx_pdev_t *pdev)
+{
+	qdf_spinlock_create(&pdev->txq_log_spinlock);
+	pdev->txq_log.size = OL_TXQ_LOG_SIZE;
+	pdev->txq_log.oldest_record_offset = 0;
+	pdev->txq_log.offset = 0;
+	pdev->txq_log.allow_wrap = 1;
+	pdev->txq_log.wrapped = 0;
+}
+
+/**
+ * ol_txrx_pdev_txq_log_destroy() - remove txq log spinlock for pdev
+ * @pdev: the physical device object
+ *
+ * Return: None
+ */
+void ol_txrx_pdev_txq_log_destroy(struct ol_txrx_pdev_t *pdev)
+{
+	qdf_spinlock_destroy(&pdev->txq_log_spinlock);
+}
+#endif
+
+#if defined(DEBUG_HL_LOGGING)
+
+/**
+ * ol_txrx_pdev_grp_stats_init() - initialise group stat spinlock for pdev
+ * @pdev: the physical device object
+ *
+ * Return: None
+ */
+void ol_txrx_pdev_grp_stats_init(struct ol_txrx_pdev_t *pdev)
+{
+	qdf_spinlock_create(&pdev->grp_stat_spinlock);
+	pdev->grp_stats.last_valid_index = -1;
+	pdev->grp_stats.wrap_around = 0;
+}
+
+/**
+ * ol_txrx_pdev_grp_stat_destroy() - destroy group stat spinlock for pdev
+ * @pdev: the physical device object
+ *
+ * Return: None
+ */
+void ol_txrx_pdev_grp_stat_destroy(struct ol_txrx_pdev_t *pdev)
+{
+	qdf_spinlock_destroy(&pdev->grp_stat_spinlock);
+}
+#endif
+
+#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
+
+/**
+ * ol_txrx_hl_tdls_flag_reset() - reset tdls flag for vdev
+ * @vdev: the virtual device object
+ * @flag: flag
+ *
+ * Return: None
+ */
+void
+ol_txrx_hl_tdls_flag_reset(struct cdp_vdev *pvdev, bool flag)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	vdev->hlTdlsFlag = flag;
+}
+#endif
+
+/**
+ * ol_txrx_vdev_txqs_init() - initialise vdev tx queues
+ * @vdev: the virtual device object
+ *
+ * Return: None
+ */
+void ol_txrx_vdev_txqs_init(struct ol_txrx_vdev_t *vdev)
+{
+	uint8_t i;
+
+	for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) {
+		TAILQ_INIT(&vdev->txqs[i].head);
+		vdev->txqs[i].paused_count.total = 0;
+		vdev->txqs[i].frms = 0;
+		vdev->txqs[i].bytes = 0;
+		vdev->txqs[i].ext_tid = OL_TX_NUM_TIDS + i;
+		vdev->txqs[i].flag = ol_tx_queue_empty;
+		/* aggregation is not applicable for vdev tx queues */
+		vdev->txqs[i].aggr_state = ol_tx_aggr_disabled;
+		ol_tx_txq_set_group_ptr(&vdev->txqs[i], NULL);
+		ol_txrx_set_txq_peer(&vdev->txqs[i], NULL);
+	}
+}
+
+/**
+ * ol_txrx_vdev_tx_queue_free() - free vdev tx queues
+ * @vdev: the virtual device object
+ *
+ * Return: None
+ */
+void ol_txrx_vdev_tx_queue_free(struct ol_txrx_vdev_t *vdev)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	struct ol_tx_frms_queue_t *txq;
+	int i;
+
+	for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) {
+		txq = &vdev->txqs[i];
+		ol_tx_queue_free(pdev, txq, (i + OL_TX_NUM_TIDS), false);
+	}
+}
+
+/**
+ * ol_txrx_peer_txqs_init() - initialise peer tx queues
+ * @pdev: the physical device object
+ * @peer: peer object
+ *
+ * Return: None
+ */
+void ol_txrx_peer_txqs_init(struct ol_txrx_pdev_t *pdev,
+			    struct ol_txrx_peer_t *peer)
+{
+	uint8_t i;
+	struct ol_txrx_vdev_t *vdev = peer->vdev;
+
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+	for (i = 0; i < OL_TX_NUM_TIDS; i++) {
+		TAILQ_INIT(&peer->txqs[i].head);
+		peer->txqs[i].paused_count.total = 0;
+		peer->txqs[i].frms = 0;
+		peer->txqs[i].bytes = 0;
+		peer->txqs[i].ext_tid = i;
+		peer->txqs[i].flag = ol_tx_queue_empty;
+		peer->txqs[i].aggr_state = ol_tx_aggr_untried;
+		ol_tx_set_peer_group_ptr(pdev, peer, vdev->vdev_id, i);
+		ol_txrx_set_txq_peer(&peer->txqs[i], peer);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+
+	/* aggregation is not applicable for mgmt and non-QoS tx queues */
+	for (i = OL_TX_NUM_QOS_TIDS; i < OL_TX_NUM_TIDS; i++)
+		peer->txqs[i].aggr_state = ol_tx_aggr_disabled;
+
+	ol_txrx_peer_pause(peer);
+}
+
+/**
+ * ol_txrx_peer_tx_queue_free() - free peer tx queues
+ * @pdev: the physical device object
+ * @peer: peer object
+ *
+ * Return: None
+ */
+void ol_txrx_peer_tx_queue_free(struct ol_txrx_pdev_t *pdev,
+				struct ol_txrx_peer_t *peer)
+{
+	struct ol_tx_frms_queue_t *txq;
+	uint8_t i;
+
+	for (i = 0; i < OL_TX_NUM_TIDS; i++) {
+		txq = &peer->txqs[i];
+		ol_tx_queue_free(pdev, txq, i, true);
+	}
+}
+
+#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+
+/**
+ * ol_txrx_update_group_credit() - update group credit for tx queue
+ * @group: for which credit needs to be updated
+ * @credit: credits
+ * @absolute: TXQ group absolute
+ *
+ * Return: allocated pool size
+ */
+void ol_txrx_update_group_credit(
+		struct ol_tx_queue_group_t *group,
+		int32_t credit,
+		u_int8_t absolute)
+{
+	if (absolute)
+		qdf_atomic_set(&group->credit, credit);
+	else
+		qdf_atomic_add(credit, &group->credit);
+}
+
+/**
+ * ol_txrx_update_tx_queue_groups() - update vdev tx queue group if
+ *				      vdev id mask and ac mask is not matching
+ * @pdev: the data physical device
+ * @group_id: TXQ group id
+ * @credit: TXQ group credit count
+ * @absolute: TXQ group absolute
+ * @vdev_id_mask: TXQ vdev group id mask
+ * @ac_mask: TQX access category mask
+ *
+ * Return: None
+ */
+void ol_txrx_update_tx_queue_groups(
+		ol_txrx_pdev_handle pdev,
+		u_int8_t group_id,
+		int32_t credit,
+		u_int8_t absolute,
+		u_int32_t vdev_id_mask,
+		u_int32_t ac_mask
+		)
+{
+	struct ol_tx_queue_group_t *group;
+	u_int32_t group_vdev_bit_mask, vdev_bit_mask, group_vdev_id_mask;
+	u_int32_t membership;
+	struct ol_txrx_vdev_t *vdev;
+
+	if (group_id >= OL_TX_MAX_TXQ_GROUPS) {
+		ol_txrx_warn("%s: invalid group_id=%u, ignore update.\n",
+			__func__,
+			group_id);
+		return;
+	}
+
+	group = &pdev->txq_grps[group_id];
+
+	membership = OL_TXQ_GROUP_MEMBERSHIP_GET(vdev_id_mask, ac_mask);
+
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+	/*
+	 * if the membership (vdev id mask and ac mask)
+	 * matches then no need to update tx qeue groups.
+	 */
+	if (group->membership == membership)
+		/* Update Credit Only */
+		goto credit_update;
+
+	credit += ol_txrx_distribute_group_credits(pdev, group_id,
+						   vdev_id_mask);
+	/*
+	 * membership (vdev id mask and ac mask) is not matching
+	 * TODO: ignoring ac mask for now
+	 */
+	qdf_assert(ac_mask == 0xffff);
+	group_vdev_id_mask =
+		OL_TXQ_GROUP_VDEV_ID_MASK_GET(group->membership);
+
+	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+		group_vdev_bit_mask =
+			OL_TXQ_GROUP_VDEV_ID_BIT_MASK_GET(
+					group_vdev_id_mask, vdev->vdev_id);
+		vdev_bit_mask =
+			OL_TXQ_GROUP_VDEV_ID_BIT_MASK_GET(
+					vdev_id_mask, vdev->vdev_id);
+
+		if (group_vdev_bit_mask != vdev_bit_mask) {
+			/*
+			 * Change in vdev tx queue group
+			 */
+			if (!vdev_bit_mask) {
+				/* Set Group Pointer (vdev and peer) to NULL */
+				ol_tx_set_vdev_group_ptr(
+						pdev, vdev->vdev_id, NULL);
+			} else {
+				/* Set Group Pointer (vdev and peer) */
+				ol_tx_set_vdev_group_ptr(
+						pdev, vdev->vdev_id, group);
+			}
+		}
+	}
+	/* Update membership */
+	group->membership = membership;
+credit_update:
+	/* Update Credit */
+	ol_txrx_update_group_credit(group, credit, absolute);
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+}
+#endif
+
+#if defined(FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL) && \
+	defined(FEATURE_HL_DBS_GROUP_CREDIT_SHARING)
+#define MIN_INIT_GROUP_CREDITS	10
+int ol_txrx_distribute_group_credits(struct ol_txrx_pdev_t *pdev,
+				     u8 group_id,
+				     u32 vdevid_mask_new)
+{
+	struct ol_tx_queue_group_t *grp = &pdev->txq_grps[group_id];
+	struct ol_tx_queue_group_t *grp_nxt = &pdev->txq_grps[!group_id];
+	int creds_nxt = qdf_atomic_read(&grp_nxt->credit);
+	int vdevid_mask = OL_TXQ_GROUP_VDEV_ID_MASK_GET(grp->membership);
+	int vdevid_mask_othgrp =
+		OL_TXQ_GROUP_VDEV_ID_MASK_GET(grp_nxt->membership);
+	int creds_distribute = 0;
+
+	/* if vdev added to the group is the first vdev */
+	if ((vdevid_mask == 0) && (vdevid_mask_new != 0)) {
+		/* if other group has members */
+		if (vdevid_mask_othgrp) {
+			if (creds_nxt < MIN_INIT_GROUP_CREDITS)
+				creds_distribute = creds_nxt / 2;
+			else
+				creds_distribute = MIN_INIT_GROUP_CREDITS;
+
+			ol_txrx_update_group_credit(grp_nxt, -creds_distribute,
+						    0);
+		} else {
+			/*
+			 * Other grp has no members, give all credits to this
+			 * grp.
+			 */
+			creds_distribute =
+				qdf_atomic_read(&pdev->target_tx_credit);
+		}
+	/* if all vdevs are removed from this grp */
+	} else if ((vdevid_mask != 0) && (vdevid_mask_new == 0)) {
+		if (vdevid_mask_othgrp)
+			/* Transfer credits to other grp */
+			ol_txrx_update_group_credit(grp_nxt,
+						    qdf_atomic_read(&grp->
+						    credit),
+						    0);
+		/* Set current grp credits to zero */
+		ol_txrx_update_group_credit(grp, 0, 1);
+	}
+
+	return creds_distribute;
+}
+#endif /*
+	* FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL &&
+	* FEATURE_HL_DBS_GROUP_CREDIT_SHARING
+	*/
+
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+/**
+ * ol_txrx_register_hl_flow_control() -register hl netdev flow control callback
+ * @vdev_id: vdev_id
+ * @flowControl: flow control callback
+ *
+ * Return: 0 for success or error code
+ */
+int ol_txrx_register_hl_flow_control(struct cdp_soc_t *soc,
+				     tx_pause_callback flowcontrol)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	u32 desc_pool_size = ol_tx_desc_pool_size_hl(pdev->ctrl_pdev);
+
+	/*
+	 * Assert if the tx descriptor pool size meets the requirements
+	 * Maximum 2 sessions are allowed on a band.
+	 */
+	QDF_ASSERT((2 * ol_txrx_tx_desc_alloc_table[TXRX_FC_5GH_80M_2x2] +
+		    ol_txrx_tx_desc_alloc_table[TXRX_FC_2GH_40M_2x2])
+		    <= desc_pool_size);
+
+	if (!pdev || !flowcontrol) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "pdev or pause_cb is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	pdev->pause_cb = flowcontrol;
+	return 0;
+}
+
+int ol_txrx_set_vdev_os_queue_status(u8 vdev_id,
+				     enum netif_action_type action)
+{
+	struct ol_txrx_vdev_t *vdev =
+	(struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
+
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid vdev_id %d", __func__, vdev_id);
+		return -EINVAL;
+	}
+
+	switch (action) {
+	case WLAN_NETIF_PRIORITY_QUEUE_ON:
+		qdf_spin_lock_bh(&vdev->pdev->tx_mutex);
+		vdev->prio_q_paused = 0;
+		qdf_spin_unlock_bh(&vdev->pdev->tx_mutex);
+		break;
+	case WLAN_WAKE_NON_PRIORITY_QUEUE:
+		qdf_atomic_set(&vdev->os_q_paused, 0);
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid action %d", __func__, action);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * ol_txrx_set_vdev_tx_desc_limit() - Set TX descriptor limits for a vdev
+ * @vdev_id: vdev id for the vdev under consideration.
+ * @chan: Channel on which the vdev has been started.
+ */
+int ol_txrx_set_vdev_tx_desc_limit(u8 vdev_id, u8 chan)
+{
+	struct ol_txrx_vdev_t *vdev =
+	(struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
+	enum ol_txrx_fc_limit_id fc_limit_id;
+	u32 td_limit;
+
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid vdev_id %d", __func__, vdev_id);
+		return -EINVAL;
+	}
+
+	/* TODO: Handle no of spatial streams and channel BW */
+	if (WLAN_REG_IS_5GHZ_CH(chan))
+		fc_limit_id = TXRX_FC_5GH_80M_2x2;
+	else
+		fc_limit_id = TXRX_FC_2GH_40M_2x2;
+
+	qdf_spin_lock_bh(&vdev->pdev->tx_mutex);
+	td_limit = ol_txrx_tx_desc_alloc_table[fc_limit_id];
+	vdev->tx_desc_limit = td_limit;
+	vdev->queue_stop_th = td_limit - TXRX_HL_TX_DESC_HI_PRIO_RESERVED;
+	vdev->queue_restart_th = td_limit - TXRX_HL_TX_DESC_QUEUE_RESTART_TH;
+	qdf_spin_unlock_bh(&vdev->pdev->tx_mutex);
+
+	return 0;
+}
+#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
diff --git a/core/dp/txrx/ol_tx_ll.c b/core/dp/txrx/ol_tx_ll.c
new file mode 100644
index 0000000..656d4be
--- /dev/null
+++ b/core/dp/txrx/ol_tx_ll.c
@@ -0,0 +1,780 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#include <qdf_atomic.h>         /* qdf_atomic_inc, etc. */
+#include <qdf_lock.h>           /* qdf_os_spinlock */
+#include <qdf_time.h>           /* qdf_system_ticks, etc. */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <qdf_net_types.h>      /* QDF_NBUF_TX_EXT_TID_INVALID */
+
+#include <cds_queue.h>          /* TAILQ */
+#ifdef QCA_COMPUTE_TX_DELAY
+#include <enet.h>               /* ethernet_hdr_t, etc. */
+#include <ipv6_defs.h>          /* ipv6_traffic_class */
+#endif
+
+#include <ol_txrx_api.h>        /* ol_txrx_vdev_handle, etc. */
+#include <ol_htt_tx_api.h>      /* htt_tx_compl_desc_id */
+#include <ol_txrx_htt_api.h>    /* htt_tx_status */
+
+#include <ol_ctrl_txrx_api.h>
+#include <cdp_txrx_tx_delay.h>
+#include <ol_txrx_types.h>      /* ol_txrx_vdev_t, etc */
+#include <ol_tx_desc.h>         /* ol_tx_desc_find, ol_tx_desc_frame_free */
+#ifdef QCA_COMPUTE_TX_DELAY
+#include <ol_tx_classify.h>     /* ol_tx_dest_addr_find */
+#endif
+#include <ol_txrx_internal.h>   /* OL_TX_DESC_NO_REFS, etc. */
+#include <ol_osif_txrx_api.h>
+#include <ol_tx.h>              /* ol_tx_reinject */
+#include <ol_tx_send.h>
+
+#include <ol_cfg.h>             /* ol_cfg_is_high_latency */
+#include <ol_tx_sched.h>
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+#include <ol_txrx_encap.h>      /* OL_TX_RESTORE_HDR, etc */
+#endif
+#include <ol_tx_queue.h>
+#include <ol_txrx.h>
+#include <pktlog_ac_fmt.h>
+#include <cdp_txrx_handle.h>
+
+void ol_tx_init_pdev(ol_txrx_pdev_handle pdev)
+{
+	qdf_atomic_add(ol_cfg_target_tx_credit(pdev->ctrl_pdev),
+		       &pdev->target_tx_credit);
+}
+
+qdf_nbuf_t ol_tx_reinject(struct ol_txrx_vdev_t *vdev,
+			  qdf_nbuf_t msdu, uint16_t peer_id)
+{
+	struct ol_tx_desc_t *tx_desc = NULL;
+	struct ol_txrx_msdu_info_t msdu_info;
+
+	msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type;
+	msdu_info.htt.info.ext_tid = HTT_TX_EXT_TID_INVALID;
+	msdu_info.peer = NULL;
+	msdu_info.htt.action.tx_comp_req = 0;
+	msdu_info.tso_info.is_tso = 0;
+
+	tx_desc = ol_tx_prepare_ll(vdev, msdu, &msdu_info);
+	if (!tx_desc)
+		return msdu;
+
+	HTT_TX_DESC_POSTPONED_SET(*((uint32_t *)(tx_desc->htt_tx_desc)), true);
+
+	htt_tx_desc_set_peer_id(tx_desc->htt_tx_desc, peer_id);
+
+	ol_tx_send(vdev->pdev, tx_desc, msdu, vdev->vdev_id);
+
+	return NULL;
+}
+
+/*
+ * The TXRX module doesn't accept tx frames unless the target has
+ * enough descriptors for them.
+ * For LL, the TXRX descriptor pool is sized to match the target's
+ * descriptor pool.  Hence, if the descriptor allocation in TXRX
+ * succeeds, that guarantees that the target has room to accept
+ * the new tx frame.
+ */
+struct ol_tx_desc_t *
+ol_tx_prepare_ll(ol_txrx_vdev_handle vdev,
+		 qdf_nbuf_t msdu,
+		 struct ol_txrx_msdu_info_t *msdu_info)
+{
+	struct ol_tx_desc_t *tx_desc;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+
+	(msdu_info)->htt.info.frame_type = pdev->htt_pkt_type;
+	tx_desc = ol_tx_desc_ll(pdev, vdev, msdu, msdu_info);
+	if (qdf_unlikely(!tx_desc)) {
+		/*
+		 * If TSO packet, free associated
+		 * remaining TSO segment descriptors
+		 */
+		if (qdf_nbuf_is_tso(msdu))
+			ol_free_remaining_tso_segs(
+					vdev, msdu_info, true);
+		TXRX_STATS_MSDU_LIST_INCR(
+				pdev, tx.dropped.host_reject, msdu);
+		return NULL;
+	}
+
+	return tx_desc;
+}
+
+qdf_nbuf_t
+ol_tx_non_std_ll(struct ol_txrx_vdev_t *vdev,
+		 enum ol_tx_spec tx_spec,
+		 qdf_nbuf_t msdu_list)
+{
+	qdf_nbuf_t msdu = msdu_list;
+	htt_pdev_handle htt_pdev = vdev->pdev->htt_pdev;
+	struct ol_txrx_msdu_info_t msdu_info;
+
+	msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type;
+	msdu_info.htt.action.tx_comp_req = 0;
+
+	/*
+	 * The msdu_list variable could be used instead of the msdu var,
+	 * but just to clarify which operations are done on a single MSDU
+	 * vs. a list of MSDUs, use a distinct variable for single MSDUs
+	 * within the list.
+	 */
+	while (msdu) {
+		qdf_nbuf_t next;
+		struct ol_tx_desc_t *tx_desc = NULL;
+
+		msdu_info.htt.info.ext_tid = qdf_nbuf_get_tid(msdu);
+		msdu_info.peer = NULL;
+		msdu_info.tso_info.is_tso = 0;
+
+		tx_desc = ol_tx_prepare_ll(vdev, msdu, &msdu_info);
+		if (!tx_desc)
+			return msdu;
+
+		/*
+		 * The netbuf may get linked into a different list inside the
+		 * ol_tx_send function, so store the next pointer before the
+		 * tx_send call.
+		 */
+		next = qdf_nbuf_next(msdu);
+
+		if (tx_spec != OL_TX_SPEC_STD) {
+			if (tx_spec & OL_TX_SPEC_NO_FREE) {
+				tx_desc->pkt_type = OL_TX_FRM_NO_FREE;
+			} else if (tx_spec & OL_TX_SPEC_TSO) {
+				tx_desc->pkt_type = OL_TX_FRM_TSO;
+			} else if (tx_spec & OL_TX_SPEC_NWIFI_NO_ENCRYPT) {
+				uint8_t sub_type =
+					ol_txrx_tx_raw_subtype(tx_spec);
+				htt_tx_desc_type(htt_pdev, tx_desc->htt_tx_desc,
+						 htt_pkt_type_native_wifi,
+						 sub_type);
+			} else if (ol_txrx_tx_is_raw(tx_spec)) {
+				/* different types of raw frames */
+				uint8_t sub_type =
+					ol_txrx_tx_raw_subtype(tx_spec);
+				htt_tx_desc_type(htt_pdev, tx_desc->htt_tx_desc,
+						 htt_pkt_type_raw, sub_type);
+			}
+		}
+		/*
+		 * If debug display is enabled, show the meta-data being
+		 * downloaded to the target via the HTT tx descriptor.
+		 */
+		htt_tx_desc_display(tx_desc->htt_tx_desc);
+		ol_tx_send(vdev->pdev, tx_desc, msdu, vdev->vdev_id);
+		msdu = next;
+	}
+	return NULL;            /* all MSDUs were accepted */
+}
+
+#if defined(HELIUMPLUS)
+void ol_txrx_dump_frag_desc(char *msg, struct ol_tx_desc_t *tx_desc)
+{
+	uint32_t                *frag_ptr_i_p;
+	int                     i;
+
+	ol_txrx_err("OL TX Descriptor 0x%pK msdu_id %d\n",
+		    tx_desc, tx_desc->id);
+	ol_txrx_err("HTT TX Descriptor vaddr: 0x%pK paddr: %pad",
+		    tx_desc->htt_tx_desc, &tx_desc->htt_tx_desc_paddr);
+	ol_txrx_err("Fragment Descriptor 0x%pK (paddr=%pad)",
+		    tx_desc->htt_frag_desc, &tx_desc->htt_frag_desc_paddr);
+
+	/*
+	 * it looks from htt_tx_desc_frag() that tx_desc->htt_frag_desc
+	 * is already de-referrable (=> in virtual address space)
+	 */
+	frag_ptr_i_p = tx_desc->htt_frag_desc;
+
+	/* Dump 6 words of TSO flags */
+	print_hex_dump(KERN_DEBUG, "MLE Desc:TSO Flags:  ",
+		       DUMP_PREFIX_NONE, 8, 4,
+		       frag_ptr_i_p, 24, true);
+
+	frag_ptr_i_p += 6; /* Skip 6 words of TSO flags */
+
+	i = 0;
+	while (*frag_ptr_i_p) {
+		print_hex_dump(KERN_DEBUG, "MLE Desc:Frag Ptr:  ",
+			       DUMP_PREFIX_NONE, 8, 4,
+			       frag_ptr_i_p, 8, true);
+		i++;
+		if (i > 5) /* max 6 times: frag_ptr0 to frag_ptr5 */
+			break;
+		/* jump to next  pointer - skip length */
+		frag_ptr_i_p += 2;
+	}
+}
+#endif /* HELIUMPLUS */
+
+struct ol_tx_desc_t *
+ol_txrx_mgmt_tx_desc_alloc(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_vdev_t *vdev,
+	qdf_nbuf_t tx_mgmt_frm,
+	struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	struct ol_tx_desc_t *tx_desc;
+
+	/* For LL tx_comp_req is not used so initialized to 0 */
+	tx_msdu_info->htt.action.tx_comp_req = 0;
+	tx_desc = ol_tx_desc_ll(pdev, vdev, tx_mgmt_frm, tx_msdu_info);
+	/* FIX THIS -
+	 * The FW currently has trouble using the host's fragments table
+	 * for management frames.  Until this is fixed, rather than
+	 * specifying the fragment table to the FW, specify just the
+	 * address of the initial fragment.
+	 */
+#if defined(HELIUMPLUS)
+	/* ol_txrx_dump_frag_desc("ol_txrx_mgmt_send(): after ol_tx_desc_ll",
+	 *			  tx_desc);
+	 */
+#endif /* defined(HELIUMPLUS) */
+	if (tx_desc) {
+		/*
+		 * Following the call to ol_tx_desc_ll, frag 0 is the
+		 * HTT tx HW descriptor, and the frame payload is in
+		 * frag 1.
+		 */
+		htt_tx_desc_frags_table_set(
+				pdev->htt_pdev,
+				tx_desc->htt_tx_desc,
+				qdf_nbuf_get_frag_paddr(tx_mgmt_frm, 1),
+				0, 0);
+#if defined(HELIUMPLUS) && defined(HELIUMPLUS_DEBUG)
+		ol_txrx_dump_frag_desc(
+				"after htt_tx_desc_frags_table_set",
+				tx_desc);
+#endif /* defined(HELIUMPLUS) */
+	}
+
+	return tx_desc;
+}
+
+int ol_txrx_mgmt_send_frame(
+	struct ol_txrx_vdev_t *vdev,
+	struct ol_tx_desc_t *tx_desc,
+	qdf_nbuf_t tx_mgmt_frm,
+	struct ol_txrx_msdu_info_t *tx_msdu_info,
+	uint16_t chanfreq)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+
+	htt_tx_desc_set_chanfreq(tx_desc->htt_tx_desc, chanfreq);
+	QDF_NBUF_CB_TX_PACKET_TRACK(tx_desc->netbuf) =
+					QDF_NBUF_TX_PKT_MGMT_TRACK;
+	ol_tx_send_nonstd(pdev, tx_desc, tx_mgmt_frm,
+			  htt_pkt_type_mgmt);
+
+	return 0;
+}
+
+#if defined(FEATURE_TSO)
+void ol_free_remaining_tso_segs(ol_txrx_vdev_handle vdev,
+				struct ol_txrx_msdu_info_t *msdu_info,
+				bool is_tso_seg_mapping_done)
+{
+	struct qdf_tso_seg_elem_t *next_seg;
+	struct qdf_tso_seg_elem_t *free_seg = msdu_info->tso_info.curr_seg;
+	struct ol_txrx_pdev_t *pdev;
+	bool is_last_seg = false;
+
+	if (qdf_unlikely(!vdev)) {
+		ol_txrx_err("vdev is null");
+		return;
+	}
+
+	pdev = vdev->pdev;
+	if (qdf_unlikely(!pdev)) {
+		ol_txrx_err("pdev is null");
+		return;
+	}
+
+	/*
+	 * TSO segment are mapped already, therefore,
+	 * 1. unmap the tso segments,
+	 * 2. free tso num segment if it is a last segment, and
+	 * 3. free the tso segments.
+	 */
+
+	if (is_tso_seg_mapping_done) {
+		struct qdf_tso_num_seg_elem_t *tso_num_desc =
+				msdu_info->tso_info.tso_num_seg_list;
+
+		if (qdf_unlikely(!tso_num_desc)) {
+			ol_txrx_err("TSO common info is NULL!");
+			return;
+		}
+
+		while (free_seg) {
+			qdf_spin_lock_bh(&pdev->tso_seg_pool.tso_mutex);
+			tso_num_desc->num_seg.tso_cmn_num_seg--;
+
+			is_last_seg = (tso_num_desc->num_seg.tso_cmn_num_seg ==
+				       0) ? true : false;
+			qdf_nbuf_unmap_tso_segment(pdev->osdev, free_seg,
+						   is_last_seg);
+			qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);
+
+			if (is_last_seg) {
+				ol_tso_num_seg_free(pdev,
+						    msdu_info->tso_info.
+						    tso_num_seg_list);
+				msdu_info->tso_info.tso_num_seg_list = NULL;
+			}
+
+			next_seg = free_seg->next;
+			free_seg->force_free = 1;
+			ol_tso_free_segment(pdev, free_seg);
+			free_seg = next_seg;
+		}
+	} else {
+		/*
+		 * TSO segment are not mapped therefore,
+		 * free the tso segments only.
+		 */
+		while (free_seg) {
+			next_seg = free_seg->next;
+			free_seg->force_free = 1;
+			ol_tso_free_segment(pdev, free_seg);
+			free_seg = next_seg;
+		}
+	}
+}
+
+/**
+ * ol_tx_prepare_tso() - Given a jumbo msdu, prepare the TSO
+ * related information in the msdu_info meta data
+ * @vdev: virtual device handle
+ * @msdu: network buffer
+ * @msdu_info: meta data associated with the msdu
+ *
+ * Return: 0 - success, >0 - error
+ */
+uint8_t ol_tx_prepare_tso(ol_txrx_vdev_handle vdev,
+			  qdf_nbuf_t msdu,
+			  struct ol_txrx_msdu_info_t *msdu_info)
+{
+	msdu_info->tso_info.curr_seg = NULL;
+	if (qdf_nbuf_is_tso(msdu)) {
+		int num_seg = qdf_nbuf_get_tso_num_seg(msdu);
+		struct qdf_tso_num_seg_elem_t *tso_num_seg;
+
+		msdu_info->tso_info.tso_num_seg_list = NULL;
+		msdu_info->tso_info.tso_seg_list = NULL;
+		msdu_info->tso_info.num_segs = num_seg;
+		while (num_seg) {
+			struct qdf_tso_seg_elem_t *tso_seg =
+				ol_tso_alloc_segment(vdev->pdev);
+			if (tso_seg) {
+				qdf_tso_seg_dbg_record(tso_seg,
+						       TSOSEG_LOC_PREPARETSO);
+				tso_seg->next =
+					msdu_info->tso_info.tso_seg_list;
+				msdu_info->tso_info.tso_seg_list
+					= tso_seg;
+				num_seg--;
+			} else {
+				/* Free above alocated TSO segements till now */
+				msdu_info->tso_info.curr_seg =
+					msdu_info->tso_info.tso_seg_list;
+				ol_free_remaining_tso_segs(vdev, msdu_info,
+							   false);
+				return 1;
+			}
+		}
+		tso_num_seg = ol_tso_num_seg_alloc(vdev->pdev);
+		if (tso_num_seg) {
+			tso_num_seg->next = msdu_info->tso_info.
+						tso_num_seg_list;
+			msdu_info->tso_info.tso_num_seg_list = tso_num_seg;
+		} else {
+			/* Free the already allocated num of segments */
+			msdu_info->tso_info.curr_seg =
+				msdu_info->tso_info.tso_seg_list;
+			ol_free_remaining_tso_segs(vdev, msdu_info, false);
+			return 1;
+		}
+
+		if (qdf_unlikely(!qdf_nbuf_get_tso_info(vdev->pdev->osdev,
+						msdu, &msdu_info->tso_info))) {
+			/* Free the already allocated num of segments */
+			msdu_info->tso_info.curr_seg =
+				msdu_info->tso_info.tso_seg_list;
+			ol_free_remaining_tso_segs(vdev, msdu_info, false);
+			return 1;
+		}
+
+		msdu_info->tso_info.curr_seg =
+			msdu_info->tso_info.tso_seg_list;
+		num_seg = msdu_info->tso_info.num_segs;
+	} else {
+		msdu_info->tso_info.is_tso = 0;
+		msdu_info->tso_info.num_segs = 1;
+	}
+	return 0;
+}
+
+/**
+ * ol_tx_tso_update_stats() - update TSO stats
+ * @pdev: pointer to ol_txrx_pdev_t structure
+ * @msdu_info: tso msdu_info for the msdu
+ * @msdu: tso mdsu for which stats are updated
+ * @tso_msdu_idx: stats index in the global TSO stats array where stats will be
+ *                updated
+ *
+ * Return: None
+ */
+void ol_tx_tso_update_stats(struct ol_txrx_pdev_t *pdev,
+			    struct qdf_tso_info_t  *tso_info, qdf_nbuf_t msdu,
+			    uint32_t tso_msdu_idx)
+{
+	TXRX_STATS_TSO_HISTOGRAM(pdev, tso_info->num_segs);
+	TXRX_STATS_TSO_GSO_SIZE_UPDATE(pdev, tso_msdu_idx,
+				       qdf_nbuf_tcp_tso_size(msdu));
+	TXRX_STATS_TSO_TOTAL_LEN_UPDATE(pdev,
+					tso_msdu_idx, qdf_nbuf_len(msdu));
+	TXRX_STATS_TSO_NUM_FRAGS_UPDATE(pdev, tso_msdu_idx,
+					qdf_nbuf_get_nr_frags(msdu));
+}
+
+/**
+ * ol_tx_tso_get_stats_idx() - retrieve global TSO stats index and increment it
+ * @pdev: pointer to ol_txrx_pdev_t structure
+ *
+ * Retrieve  the current value of the global variable and increment it. This is
+ * done in a spinlock as the global TSO stats may be accessed in parallel by
+ * multiple TX streams.
+ *
+ * Return: The current value of TSO stats index.
+ */
+uint32_t ol_tx_tso_get_stats_idx(struct ol_txrx_pdev_t *pdev)
+{
+	uint32_t msdu_stats_idx = 0;
+
+	qdf_spin_lock_bh(&pdev->stats.pub.tx.tso.tso_stats_lock);
+	msdu_stats_idx = pdev->stats.pub.tx.tso.tso_info.tso_msdu_idx;
+	pdev->stats.pub.tx.tso.tso_info.tso_msdu_idx++;
+	pdev->stats.pub.tx.tso.tso_info.tso_msdu_idx &=
+					NUM_MAX_TSO_MSDUS_MASK;
+	qdf_spin_unlock_bh(&pdev->stats.pub.tx.tso.tso_stats_lock);
+
+	TXRX_STATS_TSO_RESET_MSDU(pdev, msdu_stats_idx);
+
+	return msdu_stats_idx;
+}
+
+/**
+ * ol_tso_seg_list_init() - function to initialise the tso seg freelist
+ * @pdev: the data physical device sending the data
+ * @num_seg: number of segments needs to be intialised
+ *
+ * Return: none
+ */
+void ol_tso_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg)
+{
+	int i = 0;
+	struct qdf_tso_seg_elem_t *c_element;
+
+	/* Host should not allocate any c_element. */
+	if (num_seg <= 0) {
+		ol_txrx_err("Pool size passed is 0");
+		QDF_BUG(0);
+		pdev->tso_seg_pool.pool_size = i;
+		qdf_spinlock_create(&pdev->tso_seg_pool.tso_mutex);
+		return;
+	}
+
+	c_element = qdf_mem_malloc(sizeof(struct qdf_tso_seg_elem_t));
+	pdev->tso_seg_pool.freelist = c_element;
+	for (i = 0; i < (num_seg - 1); i++) {
+		if (qdf_unlikely(!c_element)) {
+			ol_txrx_err("c_element NULL for seg %d", i);
+			QDF_BUG(0);
+			pdev->tso_seg_pool.pool_size = i;
+			pdev->tso_seg_pool.num_free = i;
+			qdf_spinlock_create(&pdev->tso_seg_pool.tso_mutex);
+			return;
+		}
+		/* set the freelist bit and magic cookie*/
+		c_element->on_freelist = 1;
+		c_element->cookie = TSO_SEG_MAGIC_COOKIE;
+#ifdef TSOSEG_DEBUG
+		c_element->dbg.txdesc = NULL;
+		qdf_atomic_init(&c_element->dbg.cur); /* history empty */
+		qdf_tso_seg_dbg_record(c_element, TSOSEG_LOC_INIT1);
+#endif /* TSOSEG_DEBUG */
+		c_element->next =
+			qdf_mem_malloc(sizeof(struct qdf_tso_seg_elem_t));
+		c_element = c_element->next;
+	}
+	/*
+	 * NULL check for the last c_element of the list or
+	 * first c_element if num_seg is equal to 1.
+	 */
+	if (qdf_unlikely(!c_element)) {
+		ol_txrx_err("c_element NULL for seg %d", i);
+		QDF_BUG(0);
+		pdev->tso_seg_pool.pool_size = i;
+		pdev->tso_seg_pool.num_free = i;
+		qdf_spinlock_create(&pdev->tso_seg_pool.tso_mutex);
+		return;
+	}
+	c_element->on_freelist = 1;
+	c_element->cookie = TSO_SEG_MAGIC_COOKIE;
+#ifdef TSOSEG_DEBUG
+	qdf_tso_seg_dbg_init(c_element);
+	qdf_tso_seg_dbg_record(c_element, TSOSEG_LOC_INIT2);
+#endif /* TSOSEG_DEBUG */
+	c_element->next = NULL;
+	pdev->tso_seg_pool.pool_size = num_seg;
+	pdev->tso_seg_pool.num_free = num_seg;
+	qdf_spinlock_create(&pdev->tso_seg_pool.tso_mutex);
+}
+
+/**
+ * ol_tso_seg_list_deinit() - function to de-initialise the tso seg freelist
+ * @pdev: the data physical device sending the data
+ *
+ * Return: none
+ */
+void ol_tso_seg_list_deinit(struct ol_txrx_pdev_t *pdev)
+{
+	int i;
+	struct qdf_tso_seg_elem_t *c_element;
+	struct qdf_tso_seg_elem_t *temp;
+
+	/* pool size 0 implies that tso seg list is not initialised*/
+	if (!pdev->tso_seg_pool.freelist &&
+	    pdev->tso_seg_pool.pool_size == 0)
+		return;
+
+	qdf_spin_lock_bh(&pdev->tso_seg_pool.tso_mutex);
+	c_element = pdev->tso_seg_pool.freelist;
+	i = pdev->tso_seg_pool.pool_size;
+
+	pdev->tso_seg_pool.freelist = NULL;
+	pdev->tso_seg_pool.num_free = 0;
+	pdev->tso_seg_pool.pool_size = 0;
+
+	qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);
+	qdf_spinlock_destroy(&pdev->tso_seg_pool.tso_mutex);
+
+	while (i-- > 0 && c_element) {
+		temp = c_element->next;
+		if (c_element->on_freelist != 1) {
+			qdf_tso_seg_dbg_bug("seg already freed (double?)");
+			return;
+		} else if (c_element->cookie != TSO_SEG_MAGIC_COOKIE) {
+			qdf_tso_seg_dbg_bug("seg cookie is bad (corruption?)");
+			return;
+		}
+		/* free this seg, so reset the cookie value*/
+		c_element->cookie = 0;
+		qdf_mem_free(c_element);
+		c_element = temp;
+	}
+}
+
+/**
+ * ol_tso_num_seg_list_init() - function to initialise the freelist of elements
+ *				use to count the num of tso segments in jumbo
+ *				skb packet freelist
+ * @pdev: the data physical device sending the data
+ * @num_seg: number of elements needs to be intialised
+ *
+ * Return: none
+ */
+void ol_tso_num_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg)
+{
+	int i = 0;
+	struct qdf_tso_num_seg_elem_t *c_element;
+
+	/* Host should not allocate any c_element. */
+	if (num_seg <= 0) {
+		ol_txrx_err("Pool size passed is 0");
+		QDF_BUG(0);
+		pdev->tso_num_seg_pool.num_seg_pool_size = i;
+		qdf_spinlock_create(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
+		return;
+	}
+
+	c_element = qdf_mem_malloc(sizeof(struct qdf_tso_num_seg_elem_t));
+	pdev->tso_num_seg_pool.freelist = c_element;
+	for (i = 0; i < (num_seg - 1); i++) {
+		if (qdf_unlikely(!c_element)) {
+			ol_txrx_err("c_element NULL for num of seg %d", i);
+			QDF_BUG(0);
+			pdev->tso_num_seg_pool.num_seg_pool_size = i;
+			pdev->tso_num_seg_pool.num_free = i;
+			qdf_spinlock_create(&pdev->tso_num_seg_pool.
+							tso_num_seg_mutex);
+			return;
+		}
+		c_element->next =
+			qdf_mem_malloc(sizeof(struct qdf_tso_num_seg_elem_t));
+		c_element = c_element->next;
+	}
+	/*
+	 * NULL check for the last c_element of the list or
+	 * first c_element if num_seg is equal to 1.
+	 */
+	if (qdf_unlikely(!c_element)) {
+		ol_txrx_err("c_element NULL for num of seg %d", i);
+		QDF_BUG(0);
+		pdev->tso_num_seg_pool.num_seg_pool_size = i;
+		pdev->tso_num_seg_pool.num_free = i;
+		qdf_spinlock_create(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
+		return;
+	}
+	c_element->next = NULL;
+	pdev->tso_num_seg_pool.num_seg_pool_size = num_seg;
+	pdev->tso_num_seg_pool.num_free = num_seg;
+	qdf_spinlock_create(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
+}
+
+/**
+ * ol_tso_num_seg_list_deinit() - function to de-initialise the freelist of
+ *				  elements use to count the num of tso segment
+ *				  in a jumbo skb packet freelist
+ * @pdev: the data physical device sending the data
+ *
+ * Return: none
+ */
+void ol_tso_num_seg_list_deinit(struct ol_txrx_pdev_t *pdev)
+{
+	int i;
+	struct qdf_tso_num_seg_elem_t *c_element;
+	struct qdf_tso_num_seg_elem_t *temp;
+
+	/* pool size 0 implies that tso num seg list is not initialised*/
+	if (!pdev->tso_num_seg_pool.freelist &&
+	    pdev->tso_num_seg_pool.num_seg_pool_size == 0)
+		return;
+
+	qdf_spin_lock_bh(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
+	c_element = pdev->tso_num_seg_pool.freelist;
+	i = pdev->tso_num_seg_pool.num_seg_pool_size;
+
+	pdev->tso_num_seg_pool.freelist = NULL;
+	pdev->tso_num_seg_pool.num_free = 0;
+	pdev->tso_num_seg_pool.num_seg_pool_size = 0;
+
+	qdf_spin_unlock_bh(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
+	qdf_spinlock_destroy(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
+
+	while (i-- > 0 && c_element) {
+		temp = c_element->next;
+		qdf_mem_free(c_element);
+		c_element = temp;
+	}
+}
+#endif /* FEATURE_TSO */
+
+#if defined(FEATURE_TSO) && defined(FEATURE_TSO_DEBUG)
+void ol_txrx_tso_stats_init(ol_txrx_pdev_handle pdev)
+{
+	qdf_spinlock_create(&pdev->stats.pub.tx.tso.tso_stats_lock);
+}
+
+void ol_txrx_tso_stats_deinit(ol_txrx_pdev_handle pdev)
+{
+	qdf_spinlock_destroy(&pdev->stats.pub.tx.tso.tso_stats_lock);
+}
+
+void ol_txrx_stats_display_tso(ol_txrx_pdev_handle pdev)
+{
+	int msdu_idx;
+	int seg_idx;
+
+	txrx_nofl_info("TSO Statistics:");
+	txrx_nofl_info("TSO pkts %lld, bytes %lld\n",
+		       pdev->stats.pub.tx.tso.tso_pkts.pkts,
+		       pdev->stats.pub.tx.tso.tso_pkts.bytes);
+
+	txrx_nofl_info("TSO Histogram for numbers of segments:\n"
+		       "Single segment	%d\n"
+		       "  2-5 segments	%d\n"
+		       " 6-10 segments	%d\n"
+		       "11-15 segments	%d\n"
+		       "16-20 segments	%d\n"
+		       "  20+ segments	%d\n",
+		       pdev->stats.pub.tx.tso.tso_hist.pkts_1,
+		       pdev->stats.pub.tx.tso.tso_hist.pkts_2_5,
+		       pdev->stats.pub.tx.tso.tso_hist.pkts_6_10,
+		       pdev->stats.pub.tx.tso.tso_hist.pkts_11_15,
+		       pdev->stats.pub.tx.tso.tso_hist.pkts_16_20,
+		       pdev->stats.pub.tx.tso.tso_hist.pkts_20_plus);
+
+	txrx_nofl_info("TSO History Buffer: Total size %d, current_index %d",
+		       NUM_MAX_TSO_MSDUS,
+		       TXRX_STATS_TSO_MSDU_IDX(pdev));
+
+	for (msdu_idx = 0; msdu_idx < NUM_MAX_TSO_MSDUS; msdu_idx++) {
+		if (TXRX_STATS_TSO_MSDU_TOTAL_LEN(pdev, msdu_idx) == 0)
+			continue;
+		txrx_nofl_info("jumbo pkt idx: %d num segs %d gso_len %d total_len %d nr_frags %d",
+			       msdu_idx,
+			       TXRX_STATS_TSO_MSDU_NUM_SEG(pdev, msdu_idx),
+			       TXRX_STATS_TSO_MSDU_GSO_SIZE(pdev, msdu_idx),
+			       TXRX_STATS_TSO_MSDU_TOTAL_LEN(pdev, msdu_idx),
+			       TXRX_STATS_TSO_MSDU_NR_FRAGS(pdev, msdu_idx));
+
+		for (seg_idx = 0;
+			 ((seg_idx < TXRX_STATS_TSO_MSDU_NUM_SEG(pdev,
+			   msdu_idx)) && (seg_idx < NUM_MAX_TSO_SEGS));
+			 seg_idx++) {
+			struct qdf_tso_seg_t tso_seg =
+				 TXRX_STATS_TSO_SEG(pdev, msdu_idx, seg_idx);
+
+			txrx_nofl_info("seg idx: %d", seg_idx);
+			txrx_nofl_info("tso_enable: %d",
+				       tso_seg.tso_flags.tso_enable);
+			txrx_nofl_info("fin %d syn %d rst %d psh %d ack %d urg %d ece %d cwr %d ns %d",
+				       tso_seg.tso_flags.fin,
+				       tso_seg.tso_flags.syn,
+				       tso_seg.tso_flags.rst,
+				       tso_seg.tso_flags.psh,
+				       tso_seg.tso_flags.ack,
+				       tso_seg.tso_flags.urg,
+				       tso_seg.tso_flags.ece,
+				       tso_seg.tso_flags.cwr,
+				       tso_seg.tso_flags.ns);
+			txrx_nofl_info("tcp_seq_num: 0x%x ip_id: %d",
+				       tso_seg.tso_flags.tcp_seq_num,
+				       tso_seg.tso_flags.ip_id);
+		}
+	}
+}
+
+void ol_txrx_tso_stats_clear(ol_txrx_pdev_handle pdev)
+{
+	qdf_mem_zero(&pdev->stats.pub.tx.tso.tso_pkts,
+		     sizeof(struct ol_txrx_stats_elem));
+#if defined(FEATURE_TSO)
+	qdf_mem_zero(&pdev->stats.pub.tx.tso.tso_info,
+		     sizeof(struct ol_txrx_stats_tso_info));
+	qdf_mem_zero(&pdev->stats.pub.tx.tso.tso_hist,
+		     sizeof(struct ol_txrx_tso_histogram));
+#endif
+}
+#endif /* defined(FEATURE_TSO) && defined(FEATURE_TSO_DEBUG) */
diff --git a/core/dp/txrx/ol_tx_ll_fastpath.c b/core/dp/txrx/ol_tx_ll_fastpath.c
new file mode 100644
index 0000000..4525675
--- /dev/null
+++ b/core/dp/txrx/ol_tx_ll_fastpath.c
@@ -0,0 +1,560 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/* OS abstraction libraries */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_atomic.h>         /* qdf_atomic_read, etc. */
+#include <qdf_util.h>           /* qdf_unlikely */
+
+/* APIs for other modules */
+#include <htt.h>                /* HTT_TX_EXT_TID_MGMT */
+#include <ol_htt_tx_api.h>      /* htt_tx_desc_tid */
+
+/* internal header files relevant for all systems */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT1 */
+#include <ol_tx_desc.h>         /* ol_tx_desc */
+#include <ol_tx_send.h>         /* ol_tx_send */
+#include <ol_txrx.h>
+
+/* internal header files relevant only for HL systems */
+#include <ol_tx_classify.h>   /* ol_tx_classify, ol_tx_classify_mgmt */
+#include <ol_tx_queue.h>        /* ol_tx_enqueue */
+#include <ol_tx_sched.h>      /* ol_tx_sched */
+
+/* internal header files relevant only for specific systems (Pronto) */
+#include <ol_txrx_encap.h>      /* OL_TX_ENCAP, etc */
+#include <ol_tx.h>
+#include <cdp_txrx_ipa.h>
+
+#include <hif.h>              /* HIF_DEVICE */
+#include <htc_api.h>    /* Layering violation, but required for fast path */
+#include <htt_internal.h>
+#include <htt_types.h>        /* htc_endpoint */
+#include <cdp_txrx_peer_ops.h>
+#include <cdp_txrx_handle.h>
+
+#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB)
+#include <ce_api.h>
+#endif
+
+/**
+ * ol_tx_setup_fastpath_ce_handles() Update ce_handle for fastpath use.
+ *
+ * @osc: pointer to HIF context
+ * @pdev: pointer to ol pdev
+ *
+ * Return: void
+ */
+void ol_tx_setup_fastpath_ce_handles(struct hif_opaque_softc *osc,
+				     struct ol_txrx_pdev_t *pdev)
+{
+	/*
+	 * Before the HTT attach, set up the CE handles
+	 * CE handles are (struct CE_state *)
+	 * This is only required in the fast path
+	 */
+	pdev->ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_H2T_MSG);
+}
+
+qdf_nbuf_t
+ol_tx_ll_wrapper(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
+{
+	struct hif_opaque_softc *hif_device =
+		(struct hif_opaque_softc *)cds_get_context(QDF_MODULE_ID_HIF);
+
+	if (qdf_likely(hif_device &&
+		       hif_is_fastpath_mode_enabled(hif_device))) {
+		msdu_list = ol_tx_ll_fast(vdev, msdu_list);
+	} else {
+		qdf_print("Fast path is disabled\n");
+		QDF_BUG(0);
+	}
+	return msdu_list;
+}
+
+/**
+ * ol_tx_trace_pkt() - Trace TX packet at OL layer
+ *
+ * @skb: skb to be traced
+ * @msdu_id: msdu_id of the packet
+ * @vdev_id: vdev_id of the packet
+ *
+ * Return: None
+ */
+static inline void ol_tx_trace_pkt(qdf_nbuf_t skb, uint16_t msdu_id,
+				   uint8_t vdev_id)
+{
+	DPTRACE(qdf_dp_trace_ptr(skb,
+				 QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD,
+				 QDF_TRACE_DEFAULT_PDEV_ID,
+				 qdf_nbuf_data_addr(skb),
+				 sizeof(qdf_nbuf_data(skb)),
+				 msdu_id, vdev_id));
+
+	qdf_dp_trace_log_pkt(vdev_id, skb, QDF_TX, QDF_TRACE_DEFAULT_PDEV_ID);
+
+	qdf_dp_trace_set_track(skb, QDF_TX);
+	DPTRACE(qdf_dp_trace_data_pkt(skb, QDF_TRACE_DEFAULT_PDEV_ID,
+				      QDF_DP_TRACE_TX_PACKET_RECORD,
+				      msdu_id, QDF_TX));
+}
+
+/**
+ * ol_tx_prepare_ll_fast() Alloc and prepare Tx descriptor
+ *
+ * Allocate and prepare Tx descriptor with msdu and fragment descritor
+ * inforamtion.
+ *
+ * @pdev: pointer to ol pdev handle
+ * @vdev: pointer to ol vdev handle
+ * @msdu: linked list of msdu packets
+ * @pkt_download_len: packet download length
+ * @ep_id: endpoint ID
+ * @msdu_info: Handle to msdu_info
+ *
+ * Return: Pointer to Tx descriptor
+ */
+static inline struct ol_tx_desc_t *
+ol_tx_prepare_ll_fast(struct ol_txrx_pdev_t *pdev,
+		      ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu,
+		      uint32_t pkt_download_len, uint32_t ep_id,
+		      struct ol_txrx_msdu_info_t *msdu_info)
+{
+	struct ol_tx_desc_t *tx_desc = NULL;
+	uint32_t *htt_tx_desc;
+	void *htc_hdr_vaddr;
+	u_int32_t num_frags, i;
+	enum extension_header_type type;
+
+	tx_desc = ol_tx_desc_alloc_wrapper(pdev, vdev, msdu_info);
+	if (qdf_unlikely(!tx_desc))
+		return NULL;
+
+	tx_desc->netbuf = msdu;
+	if (msdu_info->tso_info.is_tso) {
+		tx_desc->tso_desc = msdu_info->tso_info.curr_seg;
+		qdf_tso_seg_dbg_setowner(tx_desc->tso_desc, tx_desc);
+		qdf_tso_seg_dbg_record(tx_desc->tso_desc,
+				       TSOSEG_LOC_TXPREPLLFAST);
+		tx_desc->tso_num_desc = msdu_info->tso_info.tso_num_seg_list;
+		tx_desc->pkt_type = OL_TX_FRM_TSO;
+		TXRX_STATS_MSDU_INCR(pdev, tx.tso.tso_pkts, msdu);
+	} else {
+		tx_desc->pkt_type = OL_TX_FRM_STD;
+	}
+
+	htt_tx_desc = tx_desc->htt_tx_desc;
+
+#if defined(HELIUMPLUS)
+	qdf_mem_zero(tx_desc->htt_frag_desc, sizeof(struct msdu_ext_desc_t));
+#endif
+
+	/* Make sure frags num is set to 0 */
+	/*
+	 * Do this here rather than in hardstart, so
+	 * that we can hopefully take only one cache-miss while
+	 * accessing skb->cb.
+	 */
+
+	/* HTT Header */
+	/* TODO : Take care of multiple fragments */
+
+	type = ol_tx_get_ext_header_type(vdev, msdu);
+
+	/* TODO: Precompute and store paddr in ol_tx_desc_t */
+	/* Virtual address of the HTT/HTC header, added by driver */
+	htc_hdr_vaddr = (char *)htt_tx_desc - HTC_HEADER_LEN;
+	if (qdf_unlikely(htt_tx_desc_init(pdev->htt_pdev, htt_tx_desc,
+					  tx_desc->htt_tx_desc_paddr,
+					  tx_desc->id, msdu,
+					  &msdu_info->htt,
+					  &msdu_info->tso_info,
+					  NULL, type))) {
+		/*
+		 * HTT Tx descriptor initialization failed.
+		 * therefore, free the tx desc
+		 */
+		ol_tx_desc_free(pdev, tx_desc);
+		return NULL;
+	}
+
+	num_frags = qdf_nbuf_get_num_frags(msdu);
+	/* num_frags are expected to be 2 max */
+	num_frags = (num_frags > QDF_NBUF_CB_TX_MAX_EXTRA_FRAGS)
+		? QDF_NBUF_CB_TX_MAX_EXTRA_FRAGS
+		: num_frags;
+#if defined(HELIUMPLUS)
+	/*
+	 * Use num_frags - 1, since 1 frag is used to store
+	 * the HTT/HTC descriptor
+	 * Refer to htt_tx_desc_init()
+	 */
+	htt_tx_desc_num_frags(pdev->htt_pdev, tx_desc->htt_frag_desc,
+			      num_frags - 1);
+#else /* ! defined(HELIUMPLUS) */
+	htt_tx_desc_num_frags(pdev->htt_pdev, tx_desc->htt_tx_desc,
+			      num_frags - 1);
+#endif /* defined(HELIUMPLUS) */
+	if (msdu_info->tso_info.is_tso) {
+		htt_tx_desc_fill_tso_info(pdev->htt_pdev,
+					  tx_desc->htt_frag_desc,
+					  &msdu_info->tso_info);
+		TXRX_STATS_TSO_SEG_UPDATE(pdev,
+					  msdu_info->tso_info.msdu_stats_idx,
+					  msdu_info->tso_info.curr_seg->seg);
+	} else {
+		for (i = 1; i < num_frags; i++) {
+			qdf_size_t frag_len;
+			qdf_dma_addr_t frag_paddr;
+
+			frag_len = qdf_nbuf_get_frag_len(msdu, i);
+			frag_paddr = qdf_nbuf_get_frag_paddr(msdu, i);
+			if (type != EXT_HEADER_NOT_PRESENT) {
+				frag_paddr +=
+				    sizeof(struct htt_tx_msdu_desc_ext_t);
+				frag_len -=
+				    sizeof(struct htt_tx_msdu_desc_ext_t);
+			}
+#if defined(HELIUMPLUS)
+			htt_tx_desc_frag(pdev->htt_pdev, tx_desc->htt_frag_desc,
+					 i - 1, frag_paddr, frag_len);
+#if defined(HELIUMPLUS_DEBUG)
+			qdf_print("%s:%d: htt_fdesc=%pK frag=%d frag_paddr=0x%0llx len=%zu",
+				  __func__, __LINE__, tx_desc->htt_frag_desc,
+				  i - 1, frag_paddr, frag_len);
+			ol_txrx_dump_pkt(netbuf, frag_paddr, 64);
+#endif /* HELIUMPLUS_DEBUG */
+#else /* ! defined(HELIUMPLUS) */
+			htt_tx_desc_frag(pdev->htt_pdev, tx_desc->htt_tx_desc,
+					 i - 1, frag_paddr, frag_len);
+#endif /* defined(HELIUMPLUS) */
+		}
+	}
+
+	/*
+	 * Do we want to turn on word_stream bit-map here ? For linux, non-TSO
+	 * this is not required. We still have to mark the swap bit correctly,
+	 * when posting to the ring
+	 */
+	/* Check to make sure, data download length is correct */
+
+	/*
+	 * TODO : Can we remove this check and always download a fixed length ?
+	 */
+
+	if (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_EXT_HEADER(msdu))
+		pkt_download_len += sizeof(struct htt_tx_msdu_desc_ext_t);
+
+	if (qdf_unlikely(qdf_nbuf_len(msdu) < pkt_download_len))
+		pkt_download_len = qdf_nbuf_len(msdu);
+
+	/* Fill the HTC header information */
+	/*
+	 * Passing 0 as the seq_no field, we can probably get away
+	 * with it for the time being, since this is not checked in f/w
+	 */
+	/* TODO : Prefill this, look at multi-fragment case */
+	HTC_TX_DESC_FILL(htc_hdr_vaddr, pkt_download_len, ep_id, 0);
+
+	return tx_desc;
+}
+
+#if defined(FEATURE_TSO)
+/**
+ * ol_tx_ll_fast() Update metadata information and send msdu to HIF/CE
+ *
+ * @vdev: handle to ol_txrx_vdev_t
+ * @msdu_list: msdu list to be sent out.
+ *
+ * Return: on success return NULL, pointer to nbuf when it fails to send.
+ */
+qdf_nbuf_t
+ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
+{
+	qdf_nbuf_t msdu = msdu_list;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	uint32_t pkt_download_len =
+		((struct htt_pdev_t *)(pdev->htt_pdev))->download_len;
+	uint32_t ep_id = HTT_EPID_GET(pdev->htt_pdev);
+	struct ol_txrx_msdu_info_t msdu_info;
+	uint32_t tso_msdu_stats_idx = 0;
+
+	qdf_mem_zero(&msdu_info, sizeof(msdu_info));
+	msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type;
+	msdu_info.htt.action.tx_comp_req = 0;
+	/*
+	 * The msdu_list variable could be used instead of the msdu var,
+	 * but just to clarify which operations are done on a single MSDU
+	 * vs. a list of MSDUs, use a distinct variable for single MSDUs
+	 * within the list.
+	 */
+	while (msdu) {
+		qdf_nbuf_t next;
+		struct ol_tx_desc_t *tx_desc;
+		int segments = 1;
+
+		msdu_info.htt.info.ext_tid = qdf_nbuf_get_tid(msdu);
+		msdu_info.peer = NULL;
+
+		if (qdf_unlikely(ol_tx_prepare_tso(vdev, msdu, &msdu_info))) {
+			ol_txrx_err("ol_tx_prepare_tso failed\n");
+			TXRX_STATS_MSDU_LIST_INCR(vdev->pdev,
+						  tx.dropped.host_reject,
+						  msdu);
+			return msdu;
+		}
+
+		segments = msdu_info.tso_info.num_segs;
+
+		if (msdu_info.tso_info.is_tso) {
+			tso_msdu_stats_idx =
+					ol_tx_tso_get_stats_idx(vdev->pdev);
+			msdu_info.tso_info.msdu_stats_idx = tso_msdu_stats_idx;
+			ol_tx_tso_update_stats(vdev->pdev,
+					       &(msdu_info.tso_info),
+					       msdu, tso_msdu_stats_idx);
+		}
+
+		/*
+		 * The netbuf may get linked into a different list
+		 * inside the ce_send_fast function, so store the next
+		 * pointer before the ce_send call.
+		 */
+		next = qdf_nbuf_next(msdu);
+		/* init the current segment to the 1st segment in the list */
+		while (segments) {
+			if (msdu_info.tso_info.curr_seg)
+				QDF_NBUF_CB_PADDR(msdu) = msdu_info.tso_info.
+					curr_seg->seg.tso_frags[0].paddr;
+
+			segments--;
+
+			msdu_info.htt.info.frame_type = pdev->htt_pkt_type;
+			msdu_info.htt.info.vdev_id = vdev->vdev_id;
+			msdu_info.htt.action.cksum_offload =
+				qdf_nbuf_get_tx_cksum(msdu);
+			switch (qdf_nbuf_get_exemption_type(msdu)) {
+			case QDF_NBUF_EXEMPT_NO_EXEMPTION:
+			case QDF_NBUF_EXEMPT_ON_KEY_MAPPING_KEY_UNAVAILABLE:
+				/* We want to encrypt this frame */
+				msdu_info.htt.action.do_encrypt = 1;
+				break;
+			case QDF_NBUF_EXEMPT_ALWAYS:
+				/* We don't want to encrypt this frame */
+				msdu_info.htt.action.do_encrypt = 0;
+				break;
+			default:
+				msdu_info.htt.action.do_encrypt = 1;
+				qdf_assert(0);
+				break;
+			}
+
+			tx_desc = ol_tx_prepare_ll_fast(pdev, vdev, msdu,
+							pkt_download_len,
+							ep_id, &msdu_info);
+
+			TXRX_STATS_MSDU_INCR(pdev, tx.from_stack, msdu);
+
+			if (qdf_likely(tx_desc)) {
+				struct qdf_tso_seg_elem_t *next_seg;
+
+				/*
+				 * if this is a jumbo nbuf, then increment the
+				 * number of nbuf users for each additional
+				 * segment of the msdu. This will ensure that
+				 * the skb is freed only after receiving tx
+				 * completion for all segments of an nbuf.
+				 */
+				if (segments)
+					qdf_nbuf_inc_users(msdu);
+
+				ol_tx_trace_pkt(msdu, tx_desc->id,
+						vdev->vdev_id);
+				/*
+				 * If debug display is enabled, show the meta
+				 * data being downloaded to the target via the
+				 * HTT tx descriptor.
+				 */
+				if (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_EXT_HEADER
+									 (msdu))
+					pkt_download_len +=
+					  sizeof(struct htt_tx_msdu_desc_ext_t);
+
+				htt_tx_desc_display(tx_desc->htt_tx_desc);
+
+				/* mark the relevant tso_seg free-able */
+				if (msdu_info.tso_info.curr_seg) {
+					msdu_info.tso_info.curr_seg->
+						sent_to_target = 1;
+					next_seg = msdu_info.tso_info.
+						curr_seg->next;
+				} else {
+					next_seg = NULL;
+				}
+
+				if ((ce_send_fast(pdev->ce_tx_hdl, msdu,
+						  ep_id,
+						  pkt_download_len) == 0)) {
+					struct qdf_tso_info_t *tso_info =
+							&msdu_info.tso_info;
+					/*
+					 * If TSO packet, free associated
+					 * remaining TSO segment descriptors
+					 */
+					if (tx_desc->pkt_type ==
+							OL_TX_FRM_TSO) {
+						tso_info->curr_seg = next_seg;
+						ol_free_remaining_tso_segs(vdev,
+							&msdu_info, true);
+					}
+
+					/*
+					 * The packet could not be sent.
+					 * Free the descriptor, return the
+					 * packet to the caller.
+					 */
+					ol_tx_desc_frame_free_nonstd(pdev,
+						tx_desc,
+						htt_tx_status_download_fail);
+					return msdu;
+				}
+				if (msdu_info.tso_info.curr_seg)
+					msdu_info.tso_info.curr_seg = next_seg;
+
+				if (msdu_info.tso_info.is_tso) {
+					TXRX_STATS_TSO_INC_SEG(vdev->pdev,
+						tso_msdu_stats_idx);
+					TXRX_STATS_TSO_INC_SEG_IDX(vdev->pdev,
+						tso_msdu_stats_idx);
+				}
+			} else {
+				/*
+				 * If TSO packet, free associated
+				 * remaining TSO segment descriptors
+				 */
+				if (qdf_nbuf_is_tso(msdu))
+					ol_free_remaining_tso_segs(vdev,
+							&msdu_info, true);
+
+				TXRX_STATS_MSDU_LIST_INCR(
+					pdev, tx.dropped.host_reject, msdu);
+				/* the list of unaccepted MSDUs */
+				return msdu;
+			}
+		} /* while segments */
+
+		msdu = next;
+	} /* while msdus */
+	return NULL; /* all MSDUs were accepted */
+}
+#else
+qdf_nbuf_t
+ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
+{
+	qdf_nbuf_t msdu = msdu_list;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	uint32_t pkt_download_len =
+		((struct htt_pdev_t *)(pdev->htt_pdev))->download_len;
+	uint32_t ep_id = HTT_EPID_GET(pdev->htt_pdev);
+	struct ol_txrx_msdu_info_t msdu_info;
+
+	msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type;
+	msdu_info.htt.action.tx_comp_req = 0;
+	msdu_info.tso_info.is_tso = 0;
+	/*
+	 * The msdu_list variable could be used instead of the msdu var,
+	 * but just to clarify which operations are done on a single MSDU
+	 * vs. a list of MSDUs, use a distinct variable for single MSDUs
+	 * within the list.
+	 */
+	while (msdu) {
+		qdf_nbuf_t next;
+		struct ol_tx_desc_t *tx_desc;
+
+		msdu_info.htt.info.ext_tid = qdf_nbuf_get_tid(msdu);
+		msdu_info.peer = NULL;
+
+		msdu_info.htt.info.frame_type = pdev->htt_pkt_type;
+		msdu_info.htt.info.vdev_id = vdev->vdev_id;
+		msdu_info.htt.action.cksum_offload =
+			qdf_nbuf_get_tx_cksum(msdu);
+		switch (qdf_nbuf_get_exemption_type(msdu)) {
+		case QDF_NBUF_EXEMPT_NO_EXEMPTION:
+		case QDF_NBUF_EXEMPT_ON_KEY_MAPPING_KEY_UNAVAILABLE:
+			/* We want to encrypt this frame */
+			msdu_info.htt.action.do_encrypt = 1;
+			break;
+		case QDF_NBUF_EXEMPT_ALWAYS:
+			/* We don't want to encrypt this frame */
+			msdu_info.htt.action.do_encrypt = 0;
+			break;
+		default:
+			msdu_info.htt.action.do_encrypt = 1;
+			qdf_assert(0);
+			break;
+		}
+
+		tx_desc = ol_tx_prepare_ll_fast(pdev, vdev, msdu,
+						pkt_download_len, ep_id,
+						&msdu_info);
+
+		TXRX_STATS_MSDU_INCR(pdev, tx.from_stack, msdu);
+
+		if (qdf_likely(tx_desc)) {
+			DPTRACE(qdf_dp_trace_ptr(msdu,
+				QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD,
+				QDF_TRACE_DEFAULT_PDEV_ID,
+				qdf_nbuf_data_addr(msdu),
+				sizeof(qdf_nbuf_data(msdu)), tx_desc->id,
+				vdev->vdev_id));
+			/*
+			 * If debug display is enabled, show the meta-data being
+			 * downloaded to the target via the HTT tx descriptor.
+			 */
+			if (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_EXT_HEADER(msdu))
+				pkt_download_len +=
+				   sizeof(struct htt_tx_msdu_desc_ext_t);
+
+			htt_tx_desc_display(tx_desc->htt_tx_desc);
+			/*
+			 * The netbuf may get linked into a different list
+			 * inside the ce_send_fast function, so store the next
+			 * pointer before the ce_send call.
+			 */
+			next = qdf_nbuf_next(msdu);
+			if ((ce_send_fast(pdev->ce_tx_hdl, msdu,
+					  ep_id, pkt_download_len) == 0)) {
+				/*
+				 * The packet could not be sent
+				 * Free the descriptor, return the packet to the
+				 * caller
+				 */
+				ol_tx_desc_free(pdev, tx_desc);
+				return msdu;
+			}
+			msdu = next;
+		} else {
+			TXRX_STATS_MSDU_LIST_INCR(
+				pdev, tx.dropped.host_reject, msdu);
+			return msdu; /* the list of unaccepted MSDUs */
+		}
+	}
+
+	return NULL; /* all MSDUs were accepted */
+}
+#endif /* FEATURE_TSO */
diff --git a/core/dp/txrx/ol_tx_ll_legacy.c b/core/dp/txrx/ol_tx_ll_legacy.c
new file mode 100644
index 0000000..5f905a0
--- /dev/null
+++ b/core/dp/txrx/ol_tx_ll_legacy.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/* OS abstraction libraries */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_atomic.h>         /* qdf_atomic_read, etc. */
+#include <qdf_util.h>           /* qdf_unlikely */
+
+/* APIs for other modules */
+#include <htt.h>                /* HTT_TX_EXT_TID_MGMT */
+#include <ol_htt_tx_api.h>      /* htt_tx_desc_tid */
+
+/* internal header files relevant for all systems */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT1 */
+#include <ol_tx_desc.h>         /* ol_tx_desc */
+#include <ol_tx_send.h>         /* ol_tx_send */
+#include <ol_txrx.h>
+
+/* internal header files relevant only for HL systems */
+#include <ol_tx_classify.h>   /* ol_tx_classify, ol_tx_classify_mgmt */
+#include <ol_tx_queue.h>        /* ol_tx_enqueue */
+#include <ol_tx_sched.h>      /* ol_tx_sched */
+
+/* internal header files relevant only for specific systems (Pronto) */
+#include <ol_txrx_encap.h>      /* OL_TX_ENCAP, etc */
+#include <ol_tx.h>
+#include <cdp_txrx_ipa.h>
+
+/**
+ * ol_tx_ll_wrapper() wrapper to ol_tx_ll
+ *
+ */
+qdf_nbuf_t
+ol_tx_ll_wrapper(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
+{
+	return ol_tx_ll(vdev, msdu_list);
+}
+
+#if defined(FEATURE_TSO)
+qdf_nbuf_t ol_tx_ll(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
+{
+	qdf_nbuf_t msdu = msdu_list;
+	struct ol_txrx_msdu_info_t msdu_info;
+	uint32_t tso_msdu_stats_idx = 0;
+
+	msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type;
+	msdu_info.htt.action.tx_comp_req = 0;
+	/*
+	 * The msdu_list variable could be used instead of the msdu var,
+	 * but just to clarify which operations are done on a single MSDU
+	 * vs. a list of MSDUs, use a distinct variable for single MSDUs
+	 * within the list.
+	 */
+	while (msdu) {
+		qdf_nbuf_t next;
+		struct ol_tx_desc_t *tx_desc = NULL;
+		int segments = 1;
+
+		msdu_info.htt.info.ext_tid = qdf_nbuf_get_tid(msdu);
+		msdu_info.peer = NULL;
+
+		if (qdf_unlikely(ol_tx_prepare_tso(vdev, msdu, &msdu_info))) {
+			qdf_print("ol_tx_prepare_tso failed\n");
+			TXRX_STATS_MSDU_LIST_INCR(vdev->pdev,
+						  tx.dropped.host_reject,
+						   msdu);
+			return msdu;
+		}
+
+		segments = msdu_info.tso_info.num_segs;
+
+		if (msdu_info.tso_info.is_tso) {
+			tso_msdu_stats_idx =
+					ol_tx_tso_get_stats_idx(vdev->pdev);
+			msdu_info.tso_info.msdu_stats_idx = tso_msdu_stats_idx;
+			ol_tx_tso_update_stats(vdev->pdev,
+					       &(msdu_info.tso_info),
+					       msdu, tso_msdu_stats_idx);
+		}
+
+		/*
+		 * The netbuf may get linked into a different list inside the
+		 * ol_tx_send function, so store the next pointer before the
+		 * tx_send call.
+		 */
+		next = qdf_nbuf_next(msdu);
+		/* init the current segment to the 1st segment in the list */
+		while (segments) {
+			if (msdu_info.tso_info.curr_seg)
+				QDF_NBUF_CB_PADDR(msdu) =
+					msdu_info.tso_info.curr_seg->
+					seg.tso_frags[0].paddr;
+
+			segments--;
+
+			tx_desc = ol_tx_prepare_ll(vdev, msdu, &msdu_info);
+			if (!tx_desc)
+				return msdu;
+
+			/*
+			 * If this is a jumbo nbuf, then increment the number
+			 * of nbuf users for each additional segment of the msdu
+			 * This will ensure that the skb is freed only after
+			 * receiving tx completion for all segments of an nbuf.
+			 */
+			if (segments)
+				qdf_nbuf_inc_users(msdu);
+
+			TXRX_STATS_MSDU_INCR(vdev->pdev, tx.from_stack, msdu);
+
+			/*
+			 * If debug display is enabled, show the meta-data being
+			 * downloaded to the target via the HTT tx descriptor.
+			 */
+			htt_tx_desc_display(tx_desc->htt_tx_desc);
+
+			ol_tx_send(vdev->pdev, tx_desc, msdu, vdev->vdev_id);
+
+			if (msdu_info.tso_info.curr_seg) {
+				msdu_info.tso_info.curr_seg =
+					 msdu_info.tso_info.curr_seg->next;
+			}
+
+			if (msdu_info.tso_info.is_tso) {
+				TXRX_STATS_TSO_INC_SEG(vdev->pdev,
+						       tso_msdu_stats_idx);
+				TXRX_STATS_TSO_INC_SEG_IDX(vdev->pdev,
+							   tso_msdu_stats_idx);
+			}
+		} /* while segments */
+
+		msdu = next;
+	} /* while msdus */
+	return NULL;            /* all MSDUs were accepted */
+}
+#else /* TSO */
+
+qdf_nbuf_t ol_tx_ll(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
+{
+	qdf_nbuf_t msdu = msdu_list;
+	struct ol_txrx_msdu_info_t msdu_info;
+
+	msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type;
+	msdu_info.htt.action.tx_comp_req = 0;
+	msdu_info.tso_info.is_tso = 0;
+	/*
+	 * The msdu_list variable could be used instead of the msdu var,
+	 * but just to clarify which operations are done on a single MSDU
+	 * vs. a list of MSDUs, use a distinct variable for single MSDUs
+	 * within the list.
+	 */
+	while (msdu) {
+		qdf_nbuf_t next;
+		struct ol_tx_desc_t *tx_desc = NULL;
+
+		msdu_info.htt.info.ext_tid = qdf_nbuf_get_tid(msdu);
+		msdu_info.peer = NULL;
+		tx_desc = ol_tx_prepare_ll(vdev, msdu, &msdu_info);
+		if (!tx_desc)
+			return msdu;
+
+		TXRX_STATS_MSDU_INCR(vdev->pdev, tx.from_stack, msdu);
+
+		/*
+		 * If debug display is enabled, show the meta-data being
+		 * downloaded to the target via the HTT tx descriptor.
+		 */
+		htt_tx_desc_display(tx_desc->htt_tx_desc);
+		/*
+		 * The netbuf may get linked into a different list inside the
+		 * ol_tx_send function, so store the next pointer before the
+		 * tx_send call.
+		 */
+		next = qdf_nbuf_next(msdu);
+		ol_tx_send(vdev->pdev, tx_desc, msdu, vdev->vdev_id);
+		msdu = next;
+	}
+	return NULL;            /* all MSDUs were accepted */
+}
+#endif /* TSO */
diff --git a/core/dp/txrx/ol_tx_queue.c b/core/dp/txrx/ol_tx_queue.c
new file mode 100644
index 0000000..56c1d84
--- /dev/null
+++ b/core/dp/txrx/ol_tx_queue.c
@@ -0,0 +1,2009 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_atomic.h>         /* qdf_atomic_read, etc. */
+#include <ol_cfg.h>             /* ol_cfg_addba_retry */
+#include <htt.h>                /* HTT_TX_EXT_TID_MGMT */
+#include <ol_htt_tx_api.h>      /* htt_tx_desc_tid */
+#include <ol_txrx_api.h>        /* ol_txrx_vdev_handle */
+#include <ol_txrx_ctrl_api.h>   /* ol_txrx_sync, ol_tx_addba_conf */
+#include <cdp_txrx_tx_throttle.h>
+#include <ol_ctrl_txrx_api.h>   /* ol_ctrl_addba_req */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT1, etc. */
+#include <ol_tx_desc.h>         /* ol_tx_desc, ol_tx_desc_frame_list_free */
+#include <ol_tx.h>              /* ol_tx_vdev_ll_pause_queue_send */
+#include <ol_tx_sched.h>	/* ol_tx_sched_notify, etc. */
+#include <ol_tx_queue.h>
+#include <ol_txrx.h>          /* ol_tx_desc_pool_size_hl */
+#include <ol_txrx_dbg.h>        /* ENABLE_TX_QUEUE_LOG */
+#include <qdf_types.h>          /* bool */
+#include "cdp_txrx_flow_ctrl_legacy.h"
+#include <ol_txrx_peer_find.h>
+#include <cdp_txrx_handle.h>
+#if defined(CONFIG_HL_SUPPORT)
+
+#ifndef offsetof
+#define offsetof(type, field)   ((qdf_size_t)(&((type *)0)->field))
+#endif
+
+/*--- function prototypes for optional host ADDBA negotiation ---------------*/
+
+#define OL_TX_QUEUE_ADDBA_CHECK(pdev, txq, tx_msdu_info) /* no-op */
+
+#ifndef container_of
+#define container_of(ptr, type, member) ((type *)( \
+			(char *)(ptr) - (char *)(&((type *)0)->member)))
+#endif
+/*--- function definitions --------------------------------------------------*/
+
+/**
+ * ol_tx_queue_vdev_flush() - try to flush pending frames in the tx queues
+ *			      no matter it's queued in the TX scheduler or not
+ * @pdev: the physical device object
+ * @vdev: the virtual device object
+ *
+ * Return: None
+ */
+static void
+ol_tx_queue_vdev_flush(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev)
+{
+#define PEER_ARRAY_COUNT        10
+	struct ol_tx_frms_queue_t *txq;
+	struct ol_txrx_peer_t *peer, *peers[PEER_ARRAY_COUNT];
+	int i, j, peer_count;
+
+	/* flush VDEV TX queues */
+	for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) {
+		txq = &vdev->txqs[i];
+		/*
+		 * currently txqs of MCAST_BCAST/DEFAULT_MGMT packet are using
+		 * tid HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST/HTT_TX_EXT_TID_MGMT
+		 * when inserted into scheduler, so use same tid when we flush
+		 * them
+		 */
+		if (i == OL_TX_VDEV_MCAST_BCAST)
+			ol_tx_queue_free(pdev,
+					txq,
+					HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST,
+					false);
+		else if (i == OL_TX_VDEV_DEFAULT_MGMT)
+			ol_tx_queue_free(pdev,
+					txq,
+					HTT_TX_EXT_TID_MGMT,
+					false);
+		else
+			ol_tx_queue_free(pdev,
+					txq,
+					(i + OL_TX_NUM_TIDS),
+					false);
+	}
+	/* flush PEER TX queues */
+	do {
+		peer_count = 0;
+		/* select candidate peers */
+		qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+		TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
+			for (i = 0; i < OL_TX_NUM_TIDS; i++) {
+				txq = &peer->txqs[i];
+				if (txq->frms) {
+					ol_txrx_peer_get_ref
+						(peer,
+						 PEER_DEBUG_ID_OL_TXQ_VDEV_FL);
+					peers[peer_count++] = peer;
+					break;
+				}
+			}
+			if (peer_count >= PEER_ARRAY_COUNT)
+				break;
+		}
+		qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+		/* flush TX queues of candidate peers */
+		for (i = 0; i < peer_count; i++) {
+			for (j = 0; j < OL_TX_NUM_TIDS; j++) {
+				txq = &peers[i]->txqs[j];
+				if (txq->frms)
+					ol_tx_queue_free(pdev, txq, j, true);
+			}
+			ol_txrx_info(
+				   "%s: Delete Peer %pK\n", __func__, peer);
+			ol_txrx_peer_release_ref(peers[i],
+						 PEER_DEBUG_ID_OL_TXQ_VDEV_FL);
+		}
+	} while (peer_count >= PEER_ARRAY_COUNT);
+}
+
+/**
+ * ol_tx_queue_flush() - try to flush pending frames in the tx queues
+ *			 no matter it's queued in the TX scheduler or not
+ * @pdev: the physical device object
+ *
+ * Return: None
+ */
+static inline void
+ol_tx_queue_flush(struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_txrx_vdev_t *vdev;
+
+	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+		ol_tx_queue_vdev_flush(pdev, vdev);
+	}
+}
+
+void
+ol_tx_queue_discard(
+	struct ol_txrx_pdev_t *pdev,
+	bool flush_all,
+	ol_tx_desc_list *tx_descs)
+{
+	u_int16_t num;
+	u_int16_t discarded, actual_discarded = 0;
+
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+
+	if (flush_all == true)
+		/* flush all the pending tx queues in the scheduler */
+		num = ol_tx_desc_pool_size_hl(pdev->ctrl_pdev) -
+			qdf_atomic_read(&pdev->tx_queue.rsrc_cnt);
+	else
+		/*TODO: Discard frames for a particular vdev only */
+		num = pdev->tx_queue.rsrc_threshold_hi -
+			pdev->tx_queue.rsrc_threshold_lo;
+
+	TX_SCHED_DEBUG_PRINT("+%s : %u\n,", __func__,
+			     qdf_atomic_read(&pdev->tx_queue.rsrc_cnt));
+	while (num > 0) {
+		discarded = ol_tx_sched_discard_select(
+				pdev, (u_int16_t)num, tx_descs, flush_all);
+		if (discarded == 0)
+			/*
+			 * No more packets could be discarded.
+			 * Probably tx queues are empty.
+			 */
+			break;
+
+		num -= discarded;
+		actual_discarded += discarded;
+	}
+	qdf_atomic_add(actual_discarded, &pdev->tx_queue.rsrc_cnt);
+	TX_SCHED_DEBUG_PRINT("-%s\n", __func__);
+
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+
+	if (flush_all == true && num > 0)
+		/*
+		 * try to flush pending frames in the tx queues
+		 * which are not queued in the TX scheduler.
+		 */
+		ol_tx_queue_flush(pdev);
+}
+
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+
+/**
+ * is_ol_tx_discard_frames_success() - check whether currently queued tx frames
+ *				       can be discarded or not
+ * @pdev: the physical device object
+ * @tx_desc: tx desciptor ptr
+ *
+ * Return: Success if available tx descriptors are too few
+ */
+static inline bool
+is_ol_tx_discard_frames_success(struct ol_txrx_pdev_t *pdev,
+				struct ol_tx_desc_t *tx_desc)
+{
+	ol_txrx_vdev_handle vdev;
+	bool discard_frames;
+
+	vdev = tx_desc->vdev;
+
+	qdf_spin_lock_bh(&vdev->pdev->tx_mutex);
+	if (vdev->tx_desc_limit == 0) {
+		/* Flow control not enabled */
+		discard_frames = qdf_atomic_read(&pdev->tx_queue.rsrc_cnt) <=
+					pdev->tx_queue.rsrc_threshold_lo;
+	} else {
+	/*
+	 * Discard
+	 * if netbuf is normal priority and tx_desc_count greater than
+	 * queue stop threshold
+	 * AND
+	 * if netbuf is high priority and tx_desc_count greater than
+	 * tx desc limit.
+	 */
+		discard_frames = (!ol_tx_desc_is_high_prio(tx_desc->netbuf) &&
+				  qdf_atomic_read(&vdev->tx_desc_count) >
+				  vdev->queue_stop_th) ||
+				  (ol_tx_desc_is_high_prio(tx_desc->netbuf) &&
+				  qdf_atomic_read(&vdev->tx_desc_count) >
+				  vdev->tx_desc_limit);
+	}
+	qdf_spin_unlock_bh(&vdev->pdev->tx_mutex);
+
+	return discard_frames;
+}
+#else
+
+static inline bool
+is_ol_tx_discard_frames_success(struct ol_txrx_pdev_t *pdev,
+				struct ol_tx_desc_t *tx_desc)
+{
+	return qdf_atomic_read(&pdev->tx_queue.rsrc_cnt) <=
+				pdev->tx_queue.rsrc_threshold_lo;
+}
+#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
+
+void
+ol_tx_enqueue(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	struct ol_tx_desc_t *tx_desc,
+	struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	int bytes;
+	struct ol_tx_sched_notify_ctx_t notify_ctx;
+
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+
+	/*
+	 * If too few tx descriptors are available, drop some currently-queued
+	 * tx frames, to provide enough tx descriptors for new frames, which
+	 * may be higher priority than the current frames.
+	 */
+	if (is_ol_tx_discard_frames_success(pdev, tx_desc)) {
+		ol_tx_desc_list tx_descs;
+
+		TAILQ_INIT(&tx_descs);
+		ol_tx_queue_discard(pdev, false, &tx_descs);
+		/*Discard Frames in Discard List*/
+		ol_tx_desc_frame_list_free(pdev, &tx_descs, 1 /* error */);
+	}
+
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+	TAILQ_INSERT_TAIL(&txq->head, tx_desc, tx_desc_list_elem);
+
+	bytes = qdf_nbuf_len(tx_desc->netbuf);
+	txq->frms++;
+	txq->bytes += bytes;
+	ol_tx_update_grp_frm_count(txq, 1);
+	ol_tx_queue_log_enqueue(pdev, tx_msdu_info, 1, bytes);
+
+	if (txq->flag != ol_tx_queue_paused) {
+		notify_ctx.event = OL_TX_ENQUEUE_FRAME;
+		notify_ctx.frames = 1;
+		notify_ctx.bytes = qdf_nbuf_len(tx_desc->netbuf);
+		notify_ctx.txq = txq;
+		notify_ctx.info.tx_msdu_info = tx_msdu_info;
+		ol_tx_sched_notify(pdev, &notify_ctx);
+		txq->flag = ol_tx_queue_active;
+	}
+
+	if (!ETHERTYPE_IS_EAPOL_WAPI(tx_msdu_info->htt.info.ethertype))
+		OL_TX_QUEUE_ADDBA_CHECK(pdev, txq, tx_msdu_info);
+
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+}
+
+u_int16_t
+ol_tx_dequeue(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	ol_tx_desc_list *head,
+	u_int16_t max_frames,
+	u_int32_t *credit,
+	int *bytes)
+{
+	u_int16_t num_frames;
+	int bytes_sum;
+	unsigned int credit_sum;
+
+	TXRX_ASSERT2(txq->flag != ol_tx_queue_paused);
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+
+	if (txq->frms < max_frames)
+		max_frames = txq->frms;
+
+	bytes_sum = 0;
+	credit_sum = 0;
+	for (num_frames = 0; num_frames < max_frames; num_frames++) {
+		unsigned int frame_credit;
+		struct ol_tx_desc_t *tx_desc;
+
+		tx_desc = TAILQ_FIRST(&txq->head);
+
+		frame_credit = htt_tx_msdu_credit(tx_desc->netbuf);
+		if (credit_sum + frame_credit > *credit)
+			break;
+
+		credit_sum += frame_credit;
+		bytes_sum += qdf_nbuf_len(tx_desc->netbuf);
+		TAILQ_REMOVE(&txq->head, tx_desc, tx_desc_list_elem);
+		TAILQ_INSERT_TAIL(head, tx_desc, tx_desc_list_elem);
+	}
+	txq->frms -= num_frames;
+	txq->bytes -= bytes_sum;
+	ol_tx_update_grp_frm_count(txq, -credit_sum);
+
+	/* a paused queue remains paused, regardless of whether it has frames */
+	if (txq->frms == 0 && txq->flag == ol_tx_queue_active)
+		txq->flag = ol_tx_queue_empty;
+
+	ol_tx_queue_log_dequeue(pdev, txq, num_frames, bytes_sum);
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+
+	*bytes = bytes_sum;
+	*credit = credit_sum;
+	return num_frames;
+}
+
+void
+ol_tx_queue_free(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	int tid, bool is_peer_txq)
+{
+	int frms = 0, bytes = 0;
+	struct ol_tx_desc_t *tx_desc;
+	struct ol_tx_sched_notify_ctx_t notify_ctx;
+	ol_tx_desc_list tx_tmp_list;
+
+	TAILQ_INIT(&tx_tmp_list);
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+
+	notify_ctx.event = OL_TX_DELETE_QUEUE;
+	notify_ctx.txq = txq;
+	notify_ctx.info.ext_tid = tid;
+	ol_tx_sched_notify(pdev, &notify_ctx);
+
+	frms = txq->frms;
+	tx_desc = TAILQ_FIRST(&txq->head);
+	while (txq->frms) {
+		bytes += qdf_nbuf_len(tx_desc->netbuf);
+		txq->frms--;
+		tx_desc = TAILQ_NEXT(tx_desc, tx_desc_list_elem);
+	}
+	ol_tx_queue_log_free(pdev, txq, tid, frms, bytes, is_peer_txq);
+	txq->bytes -= bytes;
+	ol_tx_queue_log_free(pdev, txq, tid, frms, bytes, is_peer_txq);
+	txq->flag = ol_tx_queue_empty;
+	/* txq->head gets reset during the TAILQ_CONCAT call */
+	TAILQ_CONCAT(&tx_tmp_list, &txq->head, tx_desc_list_elem);
+	ol_tx_update_grp_frm_count(txq, -frms);
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+	/* free tx frames without holding tx_queue_spinlock */
+	qdf_atomic_add(frms, &pdev->tx_queue.rsrc_cnt);
+	while (frms) {
+		tx_desc = TAILQ_FIRST(&tx_tmp_list);
+		TAILQ_REMOVE(&tx_tmp_list, tx_desc, tx_desc_list_elem);
+		ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 0);
+		frms--;
+	}
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+}
+
+
+/*--- queue pause / unpause functions ---------------------------------------*/
+
+/**
+ * ol_txrx_peer_tid_pause_base() - suspend/pause txq for a given tid given peer
+ * @pdev: the physical device object
+ * @peer: peer device object
+ * @tid: tid for which queue needs to be paused
+ *
+ * Return: None
+ */
+static void
+ol_txrx_peer_tid_pause_base(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_peer_t *peer,
+	int tid)
+{
+	struct ol_tx_frms_queue_t *txq = &peer->txqs[tid];
+
+	if (txq->paused_count.total++ == 0) {
+		struct ol_tx_sched_notify_ctx_t notify_ctx;
+
+		notify_ctx.event = OL_TX_PAUSE_QUEUE;
+		notify_ctx.txq = txq;
+		notify_ctx.info.ext_tid = tid;
+		ol_tx_sched_notify(pdev, &notify_ctx);
+		txq->flag = ol_tx_queue_paused;
+	}
+}
+#ifdef QCA_BAD_PEER_TX_FLOW_CL
+
+/**
+ * ol_txrx_peer_pause_but_no_mgmt_q_base() - suspend/pause all txqs except
+ *					     management queue for a given peer
+ * @pdev: the physical device object
+ * @peer: peer device object
+ *
+ * Return: None
+ */
+static void
+ol_txrx_peer_pause_but_no_mgmt_q_base(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_peer_t *peer)
+{
+	int i;
+
+	for (i = 0; i < OL_TX_MGMT_TID; i++)
+		ol_txrx_peer_tid_pause_base(pdev, peer, i);
+}
+#endif
+
+
+/**
+ * ol_txrx_peer_pause_base() - suspend/pause all txqs for a given peer
+ * @pdev: the physical device object
+ * @peer: peer device object
+ *
+ * Return: None
+ */
+static void
+ol_txrx_peer_pause_base(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_peer_t *peer)
+{
+	int i;
+
+	for (i = 0; i < QDF_ARRAY_SIZE(peer->txqs); i++)
+		ol_txrx_peer_tid_pause_base(pdev, peer, i);
+}
+
+/**
+ * ol_txrx_peer_tid_unpause_base() - unpause txq for a given tid given peer
+ * @pdev: the physical device object
+ * @peer: peer device object
+ * @tid: tid for which queue needs to be unpaused
+ *
+ * Return: None
+ */
+static void
+ol_txrx_peer_tid_unpause_base(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_peer_t *peer,
+	int tid)
+{
+	struct ol_tx_frms_queue_t *txq = &peer->txqs[tid];
+	/*
+	 * Don't actually unpause the tx queue until all pause requests
+	 * have been removed.
+	 */
+	TXRX_ASSERT2(txq->paused_count.total > 0);
+	/* return, if not already paused */
+	if (txq->paused_count.total == 0)
+		return;
+
+	if (--txq->paused_count.total == 0) {
+		struct ol_tx_sched_notify_ctx_t notify_ctx;
+
+		notify_ctx.event = OL_TX_UNPAUSE_QUEUE;
+		notify_ctx.txq = txq;
+		notify_ctx.info.ext_tid = tid;
+		ol_tx_sched_notify(pdev, &notify_ctx);
+
+		if (txq->frms == 0) {
+			txq->flag = ol_tx_queue_empty;
+		} else {
+			txq->flag = ol_tx_queue_active;
+			/*
+			 * Now that the are new tx frames available to download,
+			 * invoke the scheduling function, to see if it wants to
+			 * download the new frames.
+			 * Since the queue lock is currently held, and since
+			 * the scheduler function takes the lock, temporarily
+			 * release the lock.
+			 */
+			qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+			ol_tx_sched(pdev);
+			qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+		}
+	}
+}
+#ifdef QCA_BAD_PEER_TX_FLOW_CL
+/**
+ * ol_txrx_peer_unpause_but_no_mgmt_q_base() - unpause all txqs except
+ *					       management queue for a given peer
+ * @pdev: the physical device object
+ * @peer: peer device object
+ *
+ * Return: None
+ */
+static void
+ol_txrx_peer_unpause_but_no_mgmt_q_base(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_peer_t *peer)
+{
+	int i;
+
+	for (i = 0; i < OL_TX_MGMT_TID; i++)
+		ol_txrx_peer_tid_unpause_base(pdev, peer, i);
+}
+#endif
+
+void
+ol_txrx_peer_tid_unpause(ol_txrx_peer_handle peer, int tid)
+{
+	struct ol_txrx_pdev_t *pdev = peer->vdev->pdev;
+
+	/* TO DO: log the queue unpause */
+
+	/* acquire the mutex lock, since we'll be modifying the queues */
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+
+	if (tid == -1) {
+		int i;
+
+		for (i = 0; i < QDF_ARRAY_SIZE(peer->txqs); i++)
+			ol_txrx_peer_tid_unpause_base(pdev, peer, i);
+
+	} else {
+		ol_txrx_peer_tid_unpause_base(pdev, peer, tid);
+	}
+
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+}
+
+void
+ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	struct ol_txrx_peer_t *peer;
+	/* TO DO: log the queue pause */
+	/* acquire the mutex lock, since we'll be modifying the queues */
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+
+
+	/* use peer_ref_mutex before accessing peer_list */
+	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+	TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
+		ol_txrx_peer_pause_base(pdev, peer);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+	qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+}
+
+
+void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	struct ol_txrx_peer_t *peer;
+
+	/* TO DO: log the queue unpause */
+	/* acquire the mutex lock, since we'll be modifying the queues */
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+
+
+
+	/* take peer_ref_mutex before accessing peer_list */
+	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+
+	TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
+		int i;
+
+		for (i = 0; i < QDF_ARRAY_SIZE(peer->txqs); i++)
+			ol_txrx_peer_tid_unpause_base(pdev, peer, i);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+	qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+}
+
+void ol_txrx_vdev_flush(struct cdp_vdev *pvdev)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	ol_tx_queue_vdev_flush(vdev->pdev, vdev);
+}
+
+#ifdef QCA_BAD_PEER_TX_FLOW_CL
+
+/**
+ * ol_txrx_peer_bal_add_limit_peer() - add one peer into limit list
+ * @pdev:		Pointer to PDEV structure.
+ * @peer_id:	Peer Identifier.
+ * @peer_limit	Peer limit threshold
+ *
+ * Add one peer into the limit list of pdev
+ * Note that the peer limit info will be also updated
+ * If it is the first time, start the timer
+ *
+ * Return: None
+ */
+void
+ol_txrx_peer_bal_add_limit_peer(struct ol_txrx_pdev_t *pdev,
+				u_int16_t peer_id, u_int16_t peer_limit)
+{
+	u_int16_t i, existed = 0;
+	struct ol_txrx_peer_t *peer = NULL;
+
+	for (i = 0; i < pdev->tx_peer_bal.peer_num; i++) {
+		if (pdev->tx_peer_bal.limit_list[i].peer_id == peer_id) {
+			existed = 1;
+			break;
+		}
+	}
+
+	if (!existed) {
+		u_int32_t peer_num = pdev->tx_peer_bal.peer_num;
+		/* Check if peer_num has reached the capabilit */
+		if (peer_num >= MAX_NO_PEERS_IN_LIMIT) {
+			TX_SCHED_DEBUG_PRINT_ALWAYS(
+				"reach the maxinum peer num %d\n",
+				peer_num);
+				return;
+		}
+		pdev->tx_peer_bal.limit_list[peer_num].peer_id = peer_id;
+		pdev->tx_peer_bal.limit_list[peer_num].limit_flag = true;
+		pdev->tx_peer_bal.limit_list[peer_num].limit = peer_limit;
+		pdev->tx_peer_bal.peer_num++;
+
+		peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+		if (peer) {
+			peer->tx_limit_flag = true;
+			peer->tx_limit = peer_limit;
+		}
+
+		TX_SCHED_DEBUG_PRINT_ALWAYS(
+			"Add one peer into limit queue, peer_id %d, cur peer num %d\n",
+			peer_id,
+			pdev->tx_peer_bal.peer_num);
+	}
+
+	/* Only start the timer once */
+	if (pdev->tx_peer_bal.peer_bal_timer_state ==
+					ol_tx_peer_bal_timer_inactive) {
+		qdf_timer_start(&pdev->tx_peer_bal.peer_bal_timer,
+					pdev->tx_peer_bal.peer_bal_period_ms);
+		pdev->tx_peer_bal.peer_bal_timer_state =
+				ol_tx_peer_bal_timer_active;
+	}
+}
+
+/**
+ * ol_txrx_peer_bal_remove_limit_peer() - remove one peer from limit list
+ * @pdev:		Pointer to PDEV structure.
+ * @peer_id:	Peer Identifier.
+ *
+ * Remove one peer from the limit list of pdev
+ * Note that Only stop the timer if no peer in limit state
+ *
+ * Return: NULL
+ */
+void
+ol_txrx_peer_bal_remove_limit_peer(struct ol_txrx_pdev_t *pdev,
+				   u_int16_t peer_id)
+{
+	u_int16_t i;
+	struct ol_txrx_peer_t *peer = NULL;
+
+	for (i = 0; i < pdev->tx_peer_bal.peer_num; i++) {
+		if (pdev->tx_peer_bal.limit_list[i].peer_id == peer_id) {
+			pdev->tx_peer_bal.limit_list[i] =
+				pdev->tx_peer_bal.limit_list[
+					pdev->tx_peer_bal.peer_num - 1];
+			pdev->tx_peer_bal.peer_num--;
+
+			peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+			if (peer)
+				peer->tx_limit_flag = false;
+
+
+			TX_SCHED_DEBUG_PRINT(
+				"Remove one peer from limitq, peer_id %d, cur peer num %d\n",
+				peer_id,
+				pdev->tx_peer_bal.peer_num);
+			break;
+		}
+	}
+
+	/* Only stop the timer if no peer in limit state */
+	if (pdev->tx_peer_bal.peer_num == 0) {
+		qdf_timer_stop(&pdev->tx_peer_bal.peer_bal_timer);
+		pdev->tx_peer_bal.peer_bal_timer_state =
+				ol_tx_peer_bal_timer_inactive;
+	}
+}
+
+void
+ol_txrx_peer_pause_but_no_mgmt_q(ol_txrx_peer_handle peer)
+{
+	struct ol_txrx_pdev_t *pdev = peer->vdev->pdev;
+
+	/* TO DO: log the queue pause */
+
+	/* acquire the mutex lock, since we'll be modifying the queues */
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+
+	ol_txrx_peer_pause_but_no_mgmt_q_base(pdev, peer);
+
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+}
+
+void
+ol_txrx_peer_unpause_but_no_mgmt_q(ol_txrx_peer_handle peer)
+{
+	struct ol_txrx_pdev_t *pdev = peer->vdev->pdev;
+
+	/* TO DO: log the queue pause */
+
+	/* acquire the mutex lock, since we'll be modifying the queues */
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+
+	ol_txrx_peer_unpause_but_no_mgmt_q_base(pdev, peer);
+
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+}
+
+u_int16_t
+ol_tx_bad_peer_dequeue_check(struct ol_tx_frms_queue_t *txq,
+			     u_int16_t max_frames,
+			     u_int16_t *tx_limit_flag)
+{
+	if (txq && (txq->peer) && (txq->peer->tx_limit_flag) &&
+	    (txq->peer->tx_limit < max_frames)) {
+		TX_SCHED_DEBUG_PRINT(
+			"Peer ID %d goes to limit, threshold is %d\n",
+			txq->peer->peer_ids[0], txq->peer->tx_limit);
+		*tx_limit_flag = 1;
+		return txq->peer->tx_limit;
+	} else {
+		return max_frames;
+	}
+}
+
+void
+ol_tx_bad_peer_update_tx_limit(struct ol_txrx_pdev_t *pdev,
+			       struct ol_tx_frms_queue_t *txq,
+			       u_int16_t frames,
+			       u_int16_t tx_limit_flag)
+{
+	if (unlikely(NULL == pdev)) {
+		TX_SCHED_DEBUG_PRINT_ALWAYS("Error: NULL pdev handler\n");
+		return;
+	}
+
+	if (unlikely(NULL == txq)) {
+		TX_SCHED_DEBUG_PRINT_ALWAYS("Error: NULL txq\n");
+		return;
+	}
+
+	qdf_spin_lock_bh(&pdev->tx_peer_bal.mutex);
+	if (tx_limit_flag && (txq->peer) &&
+	    (txq->peer->tx_limit_flag)) {
+		if (txq->peer->tx_limit < frames)
+			txq->peer->tx_limit = 0;
+		else
+			txq->peer->tx_limit -= frames;
+
+		TX_SCHED_DEBUG_PRINT_ALWAYS(
+				"Peer ID %d in limit, deque %d frms\n",
+				txq->peer->peer_ids[0], frames);
+	} else if (txq->peer) {
+		TX_SCHED_DEBUG_PRINT("Download peer_id %d, num_frames %d\n",
+				     txq->peer->peer_ids[0], frames);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_peer_bal.mutex);
+}
+
+void
+ol_txrx_bad_peer_txctl_set_setting(struct cdp_pdev *ppdev,
+				   int enable, int period, int txq_limit)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	if (enable)
+		pdev->tx_peer_bal.enabled = ol_tx_peer_bal_enable;
+	else
+		pdev->tx_peer_bal.enabled = ol_tx_peer_bal_disable;
+
+	/* Set the current settingl */
+	pdev->tx_peer_bal.peer_bal_period_ms = period;
+	pdev->tx_peer_bal.peer_bal_txq_limit = txq_limit;
+}
+
+void
+ol_txrx_bad_peer_txctl_update_threshold(struct cdp_pdev *ppdev,
+					int level, int tput_thresh,
+					int tx_limit)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	/* Set the current settingl */
+	pdev->tx_peer_bal.ctl_thresh[level].tput_thresh =
+		tput_thresh;
+	pdev->tx_peer_bal.ctl_thresh[level].tx_limit =
+		tx_limit;
+}
+
+/**
+ * ol_tx_pdev_peer_bal_timer() - timer function
+ * @context: context of timer function
+ *
+ * Return: None
+ */
+static void
+ol_tx_pdev_peer_bal_timer(void *context)
+{
+	int i;
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)context;
+
+	qdf_spin_lock_bh(&pdev->tx_peer_bal.mutex);
+
+	for (i = 0; i < pdev->tx_peer_bal.peer_num; i++) {
+		if (pdev->tx_peer_bal.limit_list[i].limit_flag) {
+			u_int16_t peer_id =
+				pdev->tx_peer_bal.limit_list[i].peer_id;
+			u_int16_t tx_limit =
+				pdev->tx_peer_bal.limit_list[i].limit;
+
+			struct ol_txrx_peer_t *peer = NULL;
+
+			peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+			TX_SCHED_DEBUG_PRINT(
+				"%s peer_id %d  peer = 0x%x tx limit %d\n",
+				__func__, peer_id,
+				(int)peer, tx_limit);
+
+			/*
+			 * It is possible the peer limit is still not 0,
+			 * but it is the scenario should not be cared
+			 */
+			if (peer) {
+				peer->tx_limit = tx_limit;
+			} else {
+				ol_txrx_peer_bal_remove_limit_peer(pdev,
+								   peer_id);
+				TX_SCHED_DEBUG_PRINT_ALWAYS(
+					"No such a peer, peer id = %d\n",
+					peer_id);
+			}
+		}
+	}
+
+	qdf_spin_unlock_bh(&pdev->tx_peer_bal.mutex);
+
+	if (pdev->tx_peer_bal.peer_num) {
+		ol_tx_sched(pdev);
+		qdf_timer_start(&pdev->tx_peer_bal.peer_bal_timer,
+					pdev->tx_peer_bal.peer_bal_period_ms);
+	}
+}
+
+void
+ol_txrx_set_txq_peer(
+	struct ol_tx_frms_queue_t *txq,
+	struct ol_txrx_peer_t *peer)
+{
+	if (txq)
+		txq->peer = peer;
+}
+
+void ol_tx_badpeer_flow_cl_init(struct ol_txrx_pdev_t *pdev)
+{
+	u_int32_t timer_period;
+
+	qdf_spinlock_create(&pdev->tx_peer_bal.mutex);
+	pdev->tx_peer_bal.peer_num = 0;
+	pdev->tx_peer_bal.peer_bal_timer_state
+		= ol_tx_peer_bal_timer_inactive;
+
+	timer_period = 2000;
+	pdev->tx_peer_bal.peer_bal_period_ms = timer_period;
+
+	qdf_timer_init(
+			pdev->osdev,
+			&pdev->tx_peer_bal.peer_bal_timer,
+			ol_tx_pdev_peer_bal_timer,
+			pdev, QDF_TIMER_TYPE_SW);
+}
+
+void ol_tx_badpeer_flow_cl_deinit(struct ol_txrx_pdev_t *pdev)
+{
+	qdf_timer_stop(&pdev->tx_peer_bal.peer_bal_timer);
+	pdev->tx_peer_bal.peer_bal_timer_state =
+					ol_tx_peer_bal_timer_inactive;
+	qdf_timer_free(&pdev->tx_peer_bal.peer_bal_timer);
+	qdf_spinlock_destroy(&pdev->tx_peer_bal.mutex);
+}
+
+void
+ol_txrx_peer_link_status_handler(
+	ol_txrx_pdev_handle pdev,
+	u_int16_t peer_num,
+	struct rate_report_t *peer_link_status)
+{
+	u_int16_t i = 0;
+	struct ol_txrx_peer_t *peer = NULL;
+
+	if (NULL == pdev) {
+		TX_SCHED_DEBUG_PRINT_ALWAYS("Error: NULL pdev handler\n");
+		return;
+	}
+
+	if (NULL == peer_link_status) {
+		TX_SCHED_DEBUG_PRINT_ALWAYS(
+			"Error:NULL link report message. peer num %d\n",
+			peer_num);
+		return;
+	}
+
+	/* Check if bad peer tx flow CL is enabled */
+	if (pdev->tx_peer_bal.enabled != ol_tx_peer_bal_enable) {
+		TX_SCHED_DEBUG_PRINT_ALWAYS(
+			"Bad peer tx flow CL is not enabled, ignore it\n");
+		return;
+	}
+
+	/* Check peer_num is reasonable */
+	if (peer_num > MAX_NO_PEERS_IN_LIMIT) {
+		TX_SCHED_DEBUG_PRINT_ALWAYS(
+			"%s: Bad peer_num %d\n", __func__, peer_num);
+		return;
+	}
+
+	TX_SCHED_DEBUG_PRINT_ALWAYS("%s: peer_num %d\n", __func__, peer_num);
+
+	for (i = 0; i < peer_num; i++) {
+		u_int16_t peer_limit, peer_id;
+		u_int16_t pause_flag, unpause_flag;
+		u_int32_t peer_phy, peer_tput;
+
+		peer_id = peer_link_status->id;
+		peer_phy = peer_link_status->phy;
+		peer_tput = peer_link_status->rate;
+
+		TX_SCHED_DEBUG_PRINT("%s: peer id %d tput %d phy %d\n",
+				     __func__, peer_id, peer_tput, peer_phy);
+
+		/* Sanity check for the PHY mode value */
+		if (peer_phy > TXRX_IEEE11_AC) {
+			TX_SCHED_DEBUG_PRINT_ALWAYS(
+				"%s: PHY value is illegal: %d, and the peer_id %d\n",
+				__func__, peer_link_status->phy, peer_id);
+			continue;
+		}
+		pause_flag   = false;
+		unpause_flag = false;
+		peer_limit   = 0;
+
+		/* From now on, PHY, PER info should be all fine */
+		qdf_spin_lock_bh(&pdev->tx_peer_bal.mutex);
+
+		/* Update link status analysis for each peer */
+		peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+		if (peer) {
+			u_int32_t thresh, limit, phy;
+
+			phy = peer_link_status->phy;
+			thresh = pdev->tx_peer_bal.ctl_thresh[phy].tput_thresh;
+			limit = pdev->tx_peer_bal.ctl_thresh[phy].tx_limit;
+
+			if (((peer->tx_pause_flag) || (peer->tx_limit_flag)) &&
+			    (peer_tput) && (peer_tput < thresh))
+				peer_limit = limit;
+
+			if (peer_limit) {
+				ol_txrx_peer_bal_add_limit_peer(pdev, peer_id,
+								peer_limit);
+			} else if (pdev->tx_peer_bal.peer_num) {
+				TX_SCHED_DEBUG_PRINT(
+					"%s: Check if peer_id %d exit limit\n",
+					__func__, peer_id);
+				ol_txrx_peer_bal_remove_limit_peer(pdev,
+								   peer_id);
+			}
+			if ((peer_tput == 0) &&
+			    (peer->tx_pause_flag == false)) {
+				peer->tx_pause_flag = true;
+				pause_flag = true;
+			} else if (peer->tx_pause_flag) {
+				unpause_flag = true;
+				peer->tx_pause_flag = false;
+			}
+		} else {
+			TX_SCHED_DEBUG_PRINT(
+				"%s: Remove peer_id %d from limit list\n",
+				__func__, peer_id);
+			ol_txrx_peer_bal_remove_limit_peer(pdev, peer_id);
+		}
+
+		peer_link_status++;
+		qdf_spin_unlock_bh(&pdev->tx_peer_bal.mutex);
+		if (pause_flag)
+			ol_txrx_peer_pause_but_no_mgmt_q(peer);
+		else if (unpause_flag)
+			ol_txrx_peer_unpause_but_no_mgmt_q(peer);
+	}
+}
+#endif /* QCA_BAD_PEER_TX_FLOW_CL */
+
+/*--- ADDBA triggering functions --------------------------------------------*/
+
+
+/*=== debug functions =======================================================*/
+
+/*--- queue event log -------------------------------------------------------*/
+
+#if defined(DEBUG_HL_LOGGING)
+
+#define negative_sign -1
+
+/**
+ * ol_tx_queue_log_entry_type_info() - log queues entry info
+ * @type: log entry type
+ * @size: size
+ * @align: alignment
+ * @var_size: variable size record
+ *
+ * Return: None
+ */
+static void
+ol_tx_queue_log_entry_type_info(
+	u_int8_t *type, int *size, int *align, int var_size)
+{
+	switch (*type) {
+	case ol_tx_log_entry_type_enqueue:
+	case ol_tx_log_entry_type_dequeue:
+	case ol_tx_log_entry_type_queue_free:
+		*size = sizeof(struct ol_tx_log_queue_add_t);
+		*align = 2;
+		break;
+
+	case ol_tx_log_entry_type_queue_state:
+		*size = offsetof(struct ol_tx_log_queue_state_var_sz_t, data);
+		*align = 4;
+		if (var_size) {
+			/* read the variable-sized record,
+			 * to see how large it is
+			 */
+			int align_pad;
+			struct ol_tx_log_queue_state_var_sz_t *record;
+
+			align_pad =
+			(*align - (uint32_t)(((unsigned long) type) + 1))
+							& (*align - 1);
+			record = (struct ol_tx_log_queue_state_var_sz_t *)
+				(type + 1 + align_pad);
+			*size += record->num_cats_active *
+				(sizeof(u_int32_t) /* bytes */ +
+					sizeof(u_int16_t) /* frms */);
+		}
+		break;
+
+	/*case ol_tx_log_entry_type_drop:*/
+	default:
+		*size = 0;
+		*align = 0;
+	};
+}
+
+/**
+ * ol_tx_queue_log_oldest_update() - log oldest record
+ * @pdev: pointer to txrx handle
+ * @offset: offset value
+ *
+ * Return: None
+ */
+static void
+ol_tx_queue_log_oldest_update(struct ol_txrx_pdev_t *pdev, int offset)
+{
+	int oldest_record_offset;
+
+	/*
+	 * If the offset of the oldest record is between the current and
+	 * new values of the offset of the newest record, then the oldest
+	 * record has to be dropped from the log to provide room for the
+	 * newest record.
+	 * Advance the offset of the oldest record until it points to a
+	 * record that is beyond the new value of the offset of the newest
+	 * record.
+	 */
+	if (!pdev->txq_log.wrapped)
+		/*
+		 * The log has not even filled up yet - no need to remove
+		 * the oldest record to make room for a new record.
+		 */
+		return;
+
+
+	if (offset > pdev->txq_log.offset) {
+		/*
+		 * not wraparound -
+		 * The oldest record offset may have already wrapped around,
+		 * even if the newest record has not.  In this case, then
+		 * the oldest record offset is fine where it is.
+		 */
+		if (pdev->txq_log.oldest_record_offset == 0)
+			return;
+
+		oldest_record_offset = pdev->txq_log.oldest_record_offset;
+	} else
+		/* wraparound */
+		oldest_record_offset = 0;
+
+
+	while (oldest_record_offset < offset) {
+		int size, align, align_pad;
+		u_int8_t type;
+
+		type = pdev->txq_log.data[oldest_record_offset];
+		if (type == ol_tx_log_entry_type_wrap) {
+			oldest_record_offset = 0;
+			break;
+		}
+		ol_tx_queue_log_entry_type_info(
+				&pdev->txq_log.data[oldest_record_offset],
+				&size, &align, 1);
+		align_pad =
+			(align - ((oldest_record_offset + 1/*type*/)))
+							& (align - 1);
+		/*
+		 * QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		 * "TXQ LOG old alloc: offset %d, type %d, size %d (%d)\n",
+		 * oldest_record_offset, type, size, size + 1 + align_pad);
+		 */
+		oldest_record_offset += size + 1 + align_pad;
+	}
+	if (oldest_record_offset >= pdev->txq_log.size)
+		oldest_record_offset = 0;
+
+	pdev->txq_log.oldest_record_offset = oldest_record_offset;
+}
+
+/**
+ * ol_tx_queue_log_alloc() - log data allocation
+ * @pdev: physical device object
+ * @type: ol_tx_log_entry_type
+ * @extra_bytes: extra bytes
+ *
+ *
+ * Return: log element
+ */
+static void *
+ol_tx_queue_log_alloc(
+	struct ol_txrx_pdev_t *pdev,
+	u_int8_t type /* ol_tx_log_entry_type */,
+	int extra_bytes)
+{
+	int size, align, align_pad;
+	int offset;
+
+	ol_tx_queue_log_entry_type_info(&type, &size, &align, 0);
+	size += extra_bytes;
+
+	offset = pdev->txq_log.offset;
+	align_pad = (align - ((offset + 1/*type*/))) & (align - 1);
+
+	if (pdev->txq_log.size - offset >= size + 1 + align_pad)
+		/* no need to wrap around */
+		goto alloc_found;
+
+	if (!pdev->txq_log.allow_wrap)
+		return NULL; /* log is full and can't wrap */
+
+	/* handle wrap-around */
+	pdev->txq_log.wrapped = 1;
+	offset = 0;
+	align_pad = (align - ((offset + 1/*type*/))) & (align - 1);
+	/* sanity check that the log is large enough to hold this entry */
+	if (pdev->txq_log.size <= size + 1 + align_pad)
+		return NULL;
+
+
+alloc_found:
+	ol_tx_queue_log_oldest_update(pdev, offset + size + 1 + align_pad);
+	if (offset == 0)
+		pdev->txq_log.data[pdev->txq_log.offset] =
+						ol_tx_log_entry_type_wrap;
+
+	/*
+	 * QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+	 * "TXQ LOG new alloc: offset %d, type %d, size %d (%d)\n",
+	 * offset, type, size, size + 1 + align_pad);
+	 */
+	pdev->txq_log.data[offset] = type;
+	pdev->txq_log.offset = offset + size + 1 + align_pad;
+	if (pdev->txq_log.offset >= pdev->txq_log.size) {
+		pdev->txq_log.offset = 0;
+		pdev->txq_log.wrapped = 1;
+	}
+	return &pdev->txq_log.data[offset + 1 + align_pad];
+}
+
+/**
+ * ol_tx_queue_log_record_display() - show log record of tx queue
+ * @pdev: pointer to txrx handle
+ * @offset: offset value
+ *
+ * Return: size of record
+ */
+static int
+ol_tx_queue_log_record_display(struct ol_txrx_pdev_t *pdev, int offset)
+{
+	int size, align, align_pad;
+	u_int8_t type;
+	struct ol_txrx_peer_t *peer;
+
+	qdf_spin_lock_bh(&pdev->txq_log_spinlock);
+	type = pdev->txq_log.data[offset];
+	ol_tx_queue_log_entry_type_info(
+			&pdev->txq_log.data[offset], &size, &align, 1);
+	align_pad = (align - ((offset + 1/*type*/))) & (align - 1);
+
+	switch (type) {
+	case ol_tx_log_entry_type_enqueue:
+	{
+		struct ol_tx_log_queue_add_t record;
+
+		qdf_mem_copy(&record,
+			     &pdev->txq_log.data[offset + 1 + align_pad],
+			     sizeof(struct ol_tx_log_queue_add_t));
+		qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+
+		if (record.peer_id != 0xffff) {
+			peer = ol_txrx_peer_find_by_id(pdev,
+						       record.peer_id);
+			if (peer != NULL)
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "Q: %6d  %5d  %3d  %4d (%02x:%02x:%02x:%02x:%02x:%02x)",
+					  record.num_frms, record.num_bytes,
+					  record.tid,
+					  record.peer_id,
+					  peer->mac_addr.raw[0],
+					  peer->mac_addr.raw[1],
+					  peer->mac_addr.raw[2],
+					  peer->mac_addr.raw[3],
+					  peer->mac_addr.raw[4],
+					  peer->mac_addr.raw[5]);
+			else
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "Q: %6d  %5d  %3d  %4d",
+					  record.num_frms, record.num_bytes,
+					  record.tid, record.peer_id);
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_TXRX,
+				  QDF_TRACE_LEVEL_INFO,
+				  "Q: %6d  %5d  %3d  from vdev",
+				  record.num_frms, record.num_bytes,
+				  record.tid);
+		}
+		break;
+	}
+	case ol_tx_log_entry_type_dequeue:
+	{
+		struct ol_tx_log_queue_add_t record;
+
+		qdf_mem_copy(&record,
+			     &pdev->txq_log.data[offset + 1 + align_pad],
+			     sizeof(struct ol_tx_log_queue_add_t));
+		qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+
+		if (record.peer_id != 0xffff) {
+			peer = ol_txrx_peer_find_by_id(pdev, record.peer_id);
+			if (peer != NULL)
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "DQ: %6d  %5d  %3d  %4d (%02x:%02x:%02x:%02x:%02x:%02x)",
+					  record.num_frms, record.num_bytes,
+					  record.tid,
+					  record.peer_id,
+					  peer->mac_addr.raw[0],
+					  peer->mac_addr.raw[1],
+					  peer->mac_addr.raw[2],
+					  peer->mac_addr.raw[3],
+					  peer->mac_addr.raw[4],
+					  peer->mac_addr.raw[5]);
+			else
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "DQ: %6d  %5d  %3d  %4d",
+					  record.num_frms, record.num_bytes,
+					  record.tid, record.peer_id);
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_TXRX,
+				  QDF_TRACE_LEVEL_INFO,
+				  "DQ: %6d  %5d  %3d  from vdev",
+				  record.num_frms, record.num_bytes,
+				  record.tid);
+		}
+		break;
+	}
+	case ol_tx_log_entry_type_queue_free:
+	{
+		struct ol_tx_log_queue_add_t record;
+
+		qdf_mem_copy(&record,
+			     &pdev->txq_log.data[offset + 1 + align_pad],
+			     sizeof(struct ol_tx_log_queue_add_t));
+		qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+
+		if (record.peer_id != 0xffff) {
+			peer = ol_txrx_peer_find_by_id(pdev, record.peer_id);
+			if (peer != NULL)
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "F: %6d  %5d  %3d  %4d (%02x:%02x:%02x:%02x:%02x:%02x)",
+					  record.num_frms, record.num_bytes,
+					  record.tid,
+					  record.peer_id,
+					  peer->mac_addr.raw[0],
+					  peer->mac_addr.raw[1],
+					  peer->mac_addr.raw[2],
+					  peer->mac_addr.raw[3],
+					  peer->mac_addr.raw[4],
+					  peer->mac_addr.raw[5]);
+			else
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "F: %6d  %5d  %3d  %4d",
+					  record.num_frms, record.num_bytes,
+					  record.tid, record.peer_id);
+		} else {
+			/* shouldn't happen */
+			QDF_TRACE(QDF_MODULE_ID_TXRX,
+				  QDF_TRACE_LEVEL_INFO,
+				  "Unexpected vdev queue removal\n");
+		}
+			break;
+	}
+
+	case ol_tx_log_entry_type_queue_state:
+	{
+		int i, j;
+		u_int32_t active_bitmap;
+		struct ol_tx_log_queue_state_var_sz_t record;
+		u_int8_t *data;
+
+		qdf_mem_copy(&record,
+			     &pdev->txq_log.data[offset + 1 + align_pad],
+			     sizeof(struct ol_tx_log_queue_state_var_sz_t));
+		qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "S: bitmap = %#x",
+			  record.active_bitmap);
+		data = &record.data[0];
+		j = 0;
+		i = 0;
+		active_bitmap = record.active_bitmap;
+		while (active_bitmap) {
+			if (active_bitmap & 0x1) {
+				u_int16_t frms;
+				u_int32_t bytes;
+
+				frms = data[0] | (data[1] << 8);
+				bytes = (data[2] <<  0) | (data[3] <<  8) |
+					(data[4] << 16) | (data[5] << 24);
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "cat %2d: %6d  %5d",
+					  i, frms, bytes);
+				data += 6;
+				j++;
+			}
+			i++;
+			active_bitmap >>= 1;
+		}
+		break;
+	}
+
+	/*case ol_tx_log_entry_type_drop:*/
+
+	case ol_tx_log_entry_type_wrap:
+		qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+		return negative_sign * offset; /* go back to the top */
+
+	default:
+		qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "*** invalid tx log entry type (%d)\n", type);
+		return 0; /* error */
+	};
+
+	return size + 1 + align_pad;
+}
+
+/**
+ * ol_tx_queue_log_display() - show tx queue log
+ * @pdev: pointer to txrx handle
+ *
+ * Return: None
+ */
+void
+ol_tx_queue_log_display(struct ol_txrx_pdev_t *pdev)
+{
+	int offset;
+	int unwrap;
+
+	qdf_spin_lock_bh(&pdev->txq_log_spinlock);
+	offset = pdev->txq_log.oldest_record_offset;
+	unwrap = pdev->txq_log.wrapped;
+	qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+	/*
+	 * In theory, this should use mutex to guard against the offset
+	 * being changed while in use, but since this is just for debugging,
+	 * don't bother.
+	 */
+	txrx_nofl_info("Current target credit: %d",
+		       qdf_atomic_read(&pdev->target_tx_credit));
+	txrx_nofl_info("Tx queue log:");
+	txrx_nofl_info(": Frames  Bytes  TID  PEER");
+
+	while (unwrap || offset != pdev->txq_log.offset) {
+		int delta = ol_tx_queue_log_record_display(pdev, offset);
+
+		if (delta == 0)
+			return; /* error */
+
+		if (delta < 0)
+			unwrap = 0;
+
+		offset += delta;
+	}
+}
+
+void
+ol_tx_queue_log_enqueue(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_txrx_msdu_info_t *msdu_info,
+	int frms, int bytes)
+{
+	int tid;
+	u_int16_t peer_id = msdu_info->htt.info.peer_id;
+	struct ol_tx_log_queue_add_t *log_elem;
+
+	tid = msdu_info->htt.info.ext_tid;
+
+	qdf_spin_lock_bh(&pdev->txq_log_spinlock);
+	log_elem = ol_tx_queue_log_alloc(pdev, ol_tx_log_entry_type_enqueue, 0);
+	if (!log_elem) {
+		qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+		return;
+	}
+
+	log_elem->num_frms = frms;
+	log_elem->num_bytes = bytes;
+	log_elem->peer_id = peer_id;
+	log_elem->tid = tid;
+	qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+}
+
+void
+ol_tx_queue_log_dequeue(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	int frms, int bytes)
+{
+	int ext_tid;
+	u_int16_t peer_id;
+	struct ol_tx_log_queue_add_t *log_elem;
+
+	ext_tid = txq->ext_tid;
+	qdf_spin_lock_bh(&pdev->txq_log_spinlock);
+	log_elem = ol_tx_queue_log_alloc(pdev, ol_tx_log_entry_type_dequeue, 0);
+	if (!log_elem) {
+		qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+		return;
+	}
+
+	if (ext_tid < OL_TX_NUM_TIDS) {
+		struct ol_txrx_peer_t *peer;
+		struct ol_tx_frms_queue_t *txq_base;
+
+		txq_base = txq - ext_tid;
+		peer = container_of(txq_base, struct ol_txrx_peer_t, txqs[0]);
+		peer_id = peer->peer_ids[0];
+	} else {
+		peer_id = ~0;
+	}
+
+	log_elem->num_frms = frms;
+	log_elem->num_bytes = bytes;
+	log_elem->peer_id = peer_id;
+	log_elem->tid = ext_tid;
+	qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+}
+
+void
+ol_tx_queue_log_free(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	int tid, int frms, int bytes, bool is_peer_txq)
+{
+	u_int16_t peer_id;
+	struct ol_tx_log_queue_add_t *log_elem;
+
+	qdf_spin_lock_bh(&pdev->txq_log_spinlock);
+	log_elem = ol_tx_queue_log_alloc(pdev, ol_tx_log_entry_type_queue_free,
+									0);
+	if (!log_elem) {
+		qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+		return;
+	}
+
+	if ((tid < OL_TX_NUM_TIDS) && is_peer_txq) {
+		struct ol_txrx_peer_t *peer;
+		struct ol_tx_frms_queue_t *txq_base;
+
+		txq_base = txq - tid;
+		peer = container_of(txq_base, struct ol_txrx_peer_t, txqs[0]);
+		peer_id = peer->peer_ids[0];
+	} else {
+		peer_id = ~0;
+	}
+
+	log_elem->num_frms = frms;
+	log_elem->num_bytes = bytes;
+	log_elem->peer_id = peer_id;
+	log_elem->tid = tid;
+	qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+}
+
+void
+ol_tx_queue_log_sched(
+	struct ol_txrx_pdev_t *pdev,
+	int credit,
+	int *num_cats,
+	u_int32_t **active_bitmap,
+	u_int8_t  **data)
+{
+	int data_size;
+	struct ol_tx_log_queue_state_var_sz_t *log_elem;
+
+	data_size = sizeof(u_int32_t) /* bytes */ +
+				sizeof(u_int16_t) /* frms */;
+	data_size *= *num_cats;
+
+	qdf_spin_lock_bh(&pdev->txq_log_spinlock);
+	log_elem = ol_tx_queue_log_alloc(
+			pdev, ol_tx_log_entry_type_queue_state, data_size);
+	if (!log_elem) {
+		*num_cats = 0;
+		qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+		return;
+	}
+	log_elem->num_cats_active = *num_cats;
+	log_elem->active_bitmap = 0;
+	log_elem->credit = credit;
+
+	*active_bitmap = &log_elem->active_bitmap;
+	*data = &log_elem->data[0];
+	qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+}
+
+/**
+ * ol_tx_queue_log_clear() - clear tx queue log
+ * @pdev: pointer to txrx handle
+ *
+ * Return: None
+ */
+void
+ol_tx_queue_log_clear(struct ol_txrx_pdev_t *pdev)
+{
+	qdf_spin_lock_bh(&pdev->txq_log_spinlock);
+	qdf_mem_zero(&pdev->txq_log, sizeof(pdev->txq_log));
+	pdev->txq_log.size = OL_TXQ_LOG_SIZE;
+	pdev->txq_log.oldest_record_offset = 0;
+	pdev->txq_log.offset = 0;
+	pdev->txq_log.allow_wrap = 1;
+	pdev->txq_log.wrapped = 0;
+	qdf_spin_unlock_bh(&pdev->txq_log_spinlock);
+}
+#endif /* defined(DEBUG_HL_LOGGING) */
+
+/*--- queue state printouts -------------------------------------------------*/
+
+#if TXRX_DEBUG_LEVEL > 5
+
+/**
+ * ol_tx_queue_display() - show tx queue info
+ * @txq: pointer to txq frames
+ * @indent: indent
+ *
+ * Return: None
+ */
+static void
+ol_tx_queue_display(struct ol_tx_frms_queue_t *txq, int indent)
+{
+	char *state;
+
+	state = (txq->flag == ol_tx_queue_active) ? "active" : "paused";
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*stxq %pK (%s): %d frms, %d bytes\n",
+		  indent, " ", txq, state, txq->frms, txq->bytes);
+}
+
+void
+ol_tx_queues_display(struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_txrx_vdev_t *vdev;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "pdev %pK tx queues:\n", pdev);
+	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+		struct ol_txrx_peer_t *peer;
+		int i;
+
+		for (i = 0; i < QDF_ARRAY_SIZE(vdev->txqs); i++) {
+			if (vdev->txqs[i].frms == 0)
+				continue;
+
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+				  "vdev %d (%pK), txq %d\n", vdev->vdev_id,
+				  vdev, i);
+			ol_tx_queue_display(&vdev->txqs[i], 4);
+		}
+		TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
+			for (i = 0; i < QDF_ARRAY_SIZE(peer->txqs); i++) {
+				if (peer->txqs[i].frms == 0)
+					continue;
+
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_INFO_LOW,
+					  "peer %d (%pK), txq %d\n",
+					  peer->peer_ids[0], vdev, i);
+				ol_tx_queue_display(&peer->txqs[i], 6);
+			}
+		}
+	}
+}
+#endif
+
+#endif /* defined(CONFIG_HL_SUPPORT) */
+
+#if defined(CONFIG_HL_SUPPORT)
+
+/**
+ * ol_txrx_pdev_pause() - pause network queues for each vdev
+ * @pdev: pdev handle
+ * @reason: reason
+ *
+ * Return: none
+ */
+void ol_txrx_pdev_pause(struct ol_txrx_pdev_t *pdev, uint32_t reason)
+{
+	struct ol_txrx_vdev_t *vdev = NULL, *tmp;
+
+	TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) {
+		cdp_fc_vdev_pause(
+			cds_get_context(QDF_MODULE_ID_SOC),
+			(struct cdp_vdev *)vdev, reason);
+	}
+
+}
+
+/**
+ * ol_txrx_pdev_unpause() - unpause network queues for each vdev
+ * @pdev: pdev handle
+ * @reason: reason
+ *
+ * Return: none
+ */
+void ol_txrx_pdev_unpause(struct ol_txrx_pdev_t *pdev, uint32_t reason)
+{
+	struct ol_txrx_vdev_t *vdev = NULL, *tmp;
+
+	TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) {
+		cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
+				    (struct cdp_vdev *)vdev, reason);
+	}
+
+}
+#endif
+
+#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+
+/**
+ * ol_tx_vdev_has_tx_queue_group() - check for vdev having txq groups
+ * @group: pointer to tx queue grpup
+ * @vdev_id: vdev id
+ *
+ * Return: true if vedv has txq groups
+ */
+static bool
+ol_tx_vdev_has_tx_queue_group(
+	struct ol_tx_queue_group_t *group,
+	u_int8_t vdev_id)
+{
+	u_int16_t vdev_bitmap;
+
+	vdev_bitmap = OL_TXQ_GROUP_VDEV_ID_MASK_GET(group->membership);
+	if (OL_TXQ_GROUP_VDEV_ID_BIT_MASK_GET(vdev_bitmap, vdev_id))
+		return true;
+
+	return false;
+}
+
+/**
+ * ol_tx_ac_has_tx_queue_group() - check for ac having txq groups
+ * @group: pointer to tx queue grpup
+ * @ac: access category
+ *
+ * Return: true if vedv has txq groups
+ */
+static bool
+ol_tx_ac_has_tx_queue_group(
+	struct ol_tx_queue_group_t *group,
+	u_int8_t ac)
+{
+	u_int16_t ac_bitmap;
+
+	ac_bitmap = OL_TXQ_GROUP_AC_MASK_GET(group->membership);
+	if (OL_TXQ_GROUP_AC_BIT_MASK_GET(ac_bitmap, ac))
+		return true;
+
+	return false;
+}
+
+#ifdef FEATURE_HL_DBS_GROUP_CREDIT_SHARING
+static inline struct ol_tx_queue_group_t *
+ol_tx_txq_find_other_group(struct ol_txrx_pdev_t *pdev,
+			   struct ol_tx_queue_group_t *txq_grp)
+{
+	int i;
+	struct ol_tx_queue_group_t *other_grp = NULL;
+
+	for (i = 0; i < OL_TX_MAX_TXQ_GROUPS; i++) {
+		if (&pdev->txq_grps[i] != txq_grp) {
+			other_grp = &pdev->txq_grps[i];
+			break;
+		}
+	}
+	return other_grp;
+}
+
+u32 ol_tx_txq_group_credit_limit(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	u32 credit)
+{
+	struct ol_tx_queue_group_t *txq_grp = txq->group_ptrs[0];
+	struct ol_tx_queue_group_t *other_grp;
+	u32 ask;
+	u32 updated_credit;
+	u32 credit_oth_grp;
+
+	if (qdf_unlikely(!txq_grp))
+		return credit;
+
+	updated_credit = qdf_atomic_read(&txq_grp->credit);
+
+	if (credit <= updated_credit)
+		/* We have enough credits */
+		return credit;
+
+	ask = credit - updated_credit;
+	other_grp = ol_tx_txq_find_other_group(pdev, txq_grp);
+	if (qdf_unlikely(!other_grp))
+		return credit;
+
+	credit_oth_grp = qdf_atomic_read(&other_grp->credit);
+	if (other_grp->frm_count < credit_oth_grp) {
+		u32 spare = credit_oth_grp - other_grp->frm_count;
+
+		if (pdev->limit_lend) {
+			if (spare > pdev->min_reserve)
+				spare -= pdev->min_reserve;
+			else
+				spare = 0;
+		}
+		updated_credit += min(spare, ask);
+	}
+	return updated_credit;
+}
+
+u32 ol_tx_txq_update_borrowed_group_credits(struct ol_txrx_pdev_t *pdev,
+					    struct ol_tx_frms_queue_t *txq,
+					    u32 credits_used)
+{
+	struct ol_tx_queue_group_t *txq_grp = txq->group_ptrs[0];
+	u32 credits_cur_grp;
+	u32 credits_brwd;
+
+	if (qdf_unlikely(!txq_grp))
+		return credits_used;
+
+	credits_cur_grp = qdf_atomic_read(&txq_grp->credit);
+	if (credits_used > credits_cur_grp) {
+		struct ol_tx_queue_group_t *other_grp =
+			ol_tx_txq_find_other_group(pdev, txq_grp);
+
+		if (qdf_likely(other_grp)) {
+			credits_brwd = credits_used - credits_cur_grp;
+			/*
+			 * All the credits were used from the active txq group.
+			 */
+			credits_used = credits_cur_grp;
+			/* Deduct credits borrowed from other group */
+			ol_txrx_update_group_credit(other_grp, -credits_brwd,
+						    0);
+		}
+	}
+	return credits_used;
+}
+#else /* FEATURE_HL_DBS_GROUP_CREDIT_SHARING */
+u_int32_t ol_tx_txq_group_credit_limit(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	u_int32_t credit)
+{
+	u_int8_t i;
+	int updated_credit = credit;
+
+	/*
+	 * If this tx queue belongs to a group, check whether the group's
+	 * credit limit is more stringent than the global credit limit.
+	 */
+	for (i = 0; i < OL_TX_MAX_GROUPS_PER_QUEUE; i++) {
+		if (txq->group_ptrs[i]) {
+			int group_credit;
+
+			group_credit = qdf_atomic_read(
+					&txq->group_ptrs[i]->credit);
+			updated_credit = QDF_MIN(updated_credit, group_credit);
+		}
+	}
+
+	credit = (updated_credit < 0) ? 0 : updated_credit;
+
+	return credit;
+}
+#endif /* FEATURE_HL_DBS_GROUP_CREDIT_SHARING */
+
+void ol_tx_txq_group_credit_update(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	int32_t credit,
+	u_int8_t absolute)
+{
+	u_int8_t i;
+	/*
+	 * If this tx queue belongs to a group then
+	 * update group credit
+	 */
+	for (i = 0; i < OL_TX_MAX_GROUPS_PER_QUEUE; i++) {
+		if (txq->group_ptrs[i])
+			ol_txrx_update_group_credit(txq->group_ptrs[i],
+						    credit, absolute);
+	}
+	ol_tx_update_group_credit_stats(pdev);
+}
+
+void
+ol_tx_set_vdev_group_ptr(
+	ol_txrx_pdev_handle pdev,
+	u_int8_t vdev_id,
+	struct ol_tx_queue_group_t *grp_ptr)
+{
+	struct ol_txrx_vdev_t *vdev = NULL;
+	struct ol_txrx_peer_t *peer = NULL;
+
+	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+		if (vdev->vdev_id == vdev_id) {
+			u_int8_t i, j;
+
+			/* update vdev queues group pointers */
+			for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) {
+				for (j = 0; j < OL_TX_MAX_GROUPS_PER_QUEUE; j++)
+					vdev->txqs[i].group_ptrs[j] = grp_ptr;
+			}
+			qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+			/* Update peer queue group pointers */
+			TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
+				for (i = 0; i < OL_TX_NUM_TIDS; i++) {
+					for (j = 0;
+						j < OL_TX_MAX_GROUPS_PER_QUEUE;
+							j++)
+						peer->txqs[i].group_ptrs[j] =
+							grp_ptr;
+				}
+			}
+			qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+			break;
+		}
+	}
+}
+
+void ol_tx_txq_set_group_ptr(
+	struct ol_tx_frms_queue_t *txq,
+	struct ol_tx_queue_group_t *grp_ptr)
+{
+	u_int8_t i;
+
+	for (i = 0; i < OL_TX_MAX_GROUPS_PER_QUEUE; i++)
+		txq->group_ptrs[i] = grp_ptr;
+}
+
+void ol_tx_set_peer_group_ptr(
+	ol_txrx_pdev_handle pdev,
+	struct ol_txrx_peer_t *peer,
+	u_int8_t vdev_id,
+	u_int8_t tid)
+{
+	u_int8_t i, j = 0;
+	struct ol_tx_queue_group_t *group = NULL;
+
+	for (i = 0; i < OL_TX_MAX_GROUPS_PER_QUEUE; i++)
+		peer->txqs[tid].group_ptrs[i] = NULL;
+
+	for (i = 0; i < OL_TX_MAX_TXQ_GROUPS; i++) {
+		group = &pdev->txq_grps[i];
+		if (ol_tx_vdev_has_tx_queue_group(group, vdev_id)) {
+			if (tid < OL_TX_NUM_QOS_TIDS) {
+				if (ol_tx_ac_has_tx_queue_group(
+						group,
+						TXRX_TID_TO_WMM_AC(tid))) {
+					peer->txqs[tid].group_ptrs[j] = group;
+					j++;
+				}
+			} else {
+				peer->txqs[tid].group_ptrs[j] = group;
+				j++;
+			}
+		}
+		if (j >= OL_TX_MAX_GROUPS_PER_QUEUE)
+			break;
+	}
+}
+
+u_int32_t ol_tx_get_max_tx_groups_supported(struct ol_txrx_pdev_t *pdev)
+{
+		return OL_TX_MAX_TXQ_GROUPS;
+}
+#endif /* FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL */
+
+#if defined(FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL) && \
+	defined(FEATURE_HL_DBS_GROUP_CREDIT_SHARING)
+void ol_tx_update_grp_frm_count(struct ol_tx_frms_queue_t *txq, int num_frms)
+{
+	int i;
+
+	if (!num_frms || !txq) {
+		ol_txrx_dbg("Invalid params\n");
+		return;
+	}
+
+	for (i = 0; i < OL_TX_MAX_GROUPS_PER_QUEUE; i++) {
+		if (txq->group_ptrs[i]) {
+			txq->group_ptrs[i]->frm_count += num_frms;
+			qdf_assert(txq->group_ptrs[i]->frm_count >= 0);
+		}
+	}
+}
+#endif
+
+/*--- End of LL tx throttle queue code ---------------------------------------*/
diff --git a/core/dp/txrx/ol_tx_queue.h b/core/dp/txrx/ol_tx_queue.h
new file mode 100644
index 0000000..a5e7fbe
--- /dev/null
+++ b/core/dp/txrx/ol_tx_queue.h
@@ -0,0 +1,615 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/**
+ * @file ol_tx_queue.h
+ * @brief API definitions for the tx frame queue module within the data SW.
+ */
+#ifndef _OL_TX_QUEUE__H_
+#define _OL_TX_QUEUE__H_
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <cdp_txrx_cmn.h>       /* ol_txrx_vdev_t, etc. */
+#include <qdf_types.h>          /* bool */
+
+/*--- function prototypes for optional queue log feature --------------------*/
+#if defined(ENABLE_TX_QUEUE_LOG) || \
+	(defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT))
+
+/**
+ * ol_tx_queue_log_enqueue() - enqueue tx queue logs
+ * @pdev: physical device object
+ * @msdu_info: tx msdu meta data
+ * @frms: number of frames for which logs need to be enqueued
+ * @bytes: number of bytes
+ *
+ *
+ * Return: None
+ */
+void
+ol_tx_queue_log_enqueue(struct ol_txrx_pdev_t *pdev,
+			struct ol_txrx_msdu_info_t *msdu_info,
+			int frms, int bytes);
+
+/**
+ * ol_tx_queue_log_dequeue() - dequeue tx queue logs
+ * @pdev: physical device object
+ * @txq: tx queue
+ * @frms: number of frames for which logs need to be dequeued
+ * @bytes: number of bytes
+ *
+ *
+ * Return: None
+ */
+void
+ol_tx_queue_log_dequeue(struct ol_txrx_pdev_t *pdev,
+			struct ol_tx_frms_queue_t *txq, int frms, int bytes);
+
+/**
+ * ol_tx_queue_log_free() - free tx queue logs
+ * @pdev: physical device object
+ * @txq: tx queue
+ * @tid: tid value
+ * @frms: number of frames for which logs need to be freed
+ * @bytes: number of bytes
+ * @is_peer_txq - peer queue or not
+ *
+ *
+ * Return: None
+ */
+void
+ol_tx_queue_log_free(struct ol_txrx_pdev_t *pdev,
+		     struct ol_tx_frms_queue_t *txq,
+		     int tid, int frms, int bytes, bool is_peer_txq);
+
+#else
+
+static inline void
+ol_tx_queue_log_enqueue(struct ol_txrx_pdev_t *pdev,
+			struct ol_txrx_msdu_info_t *msdu_info,
+			int frms, int bytes)
+{
+}
+
+static inline void
+ol_tx_queue_log_dequeue(struct ol_txrx_pdev_t *pdev,
+			struct ol_tx_frms_queue_t *txq, int frms, int bytes)
+{
+}
+
+static inline void
+ol_tx_queue_log_free(struct ol_txrx_pdev_t *pdev,
+		     struct ol_tx_frms_queue_t *txq,
+		     int tid, int frms, int bytes, bool is_peer_txq)
+{
+}
+
+#endif
+
+#if defined(CONFIG_HL_SUPPORT)
+
+/**
+ * @brief Queue a tx frame to the tid queue.
+ *
+ * @param pdev - the data virtual device sending the data
+ *      (for storing the tx desc in the virtual dev's tx_target_list,
+ *      and for accessing the phy dev)
+ * @param txq - which queue the tx frame gets stored in
+ * @param tx_desc - tx meta-data, including prev and next ptrs
+ * @param tx_msdu_info - characteristics of the tx frame
+ */
+void
+ol_tx_enqueue(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_frms_queue_t *txq,
+		struct ol_tx_desc_t *tx_desc,
+		struct ol_txrx_msdu_info_t *tx_msdu_info);
+
+/**
+ * @brief - remove the specified number of frames from the head of a tx queue
+ * @details
+ *  This function removes frames from the head of a tx queue,
+ *  and returns them as a NULL-terminated linked list.
+ *  The function will remove frames until one of the following happens:
+ *  1.  The tx queue is empty
+ *  2.  The specified number of frames have been removed
+ *  3.  Removal of more frames would exceed the specified credit limit
+ *
+ * @param pdev - the physical device object
+ * @param txq - which tx queue to remove frames from
+ * @param head - which contains return linked-list of tx frames (descriptors)
+ * @param num_frames - maximum number of frames to remove
+ * @param[in/out] credit -
+ *     input:  max credit the dequeued frames can consume
+ *     output: how much credit the dequeued frames consume
+ * @param[out] bytes - the sum of the sizes of the dequeued frames
+ * @return number of frames dequeued
+ */
+u_int16_t
+ol_tx_dequeue(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	ol_tx_desc_list *head,
+	u_int16_t num_frames,
+	u_int32_t *credit,
+	int *bytes);
+
+/**
+ * @brief - free all of frames from the tx queue while deletion
+ * @details
+ *  This function frees all of frames from the tx queue.
+ *  This function is called during peer or vdev deletion.
+ *  This function notifies the scheduler, so the scheduler can update
+ *  its state to account for the absence of the queue.
+ *
+ * @param pdev - the physical device object, which stores the txqs
+ * @param txq - which tx queue to free frames from
+ * @param tid - the extended TID that the queue belongs to
+ * @param is_peer_txq - peer queue or not
+ */
+void
+ol_tx_queue_free(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_frms_queue_t *txq,
+		int tid, bool is_peer_txq);
+
+/**
+ * @brief - discard pending tx frames from the tx queue
+ * @details
+ *  This function is called if there are too many queues in tx scheduler.
+ *  This function is called if we wants to flush all pending tx
+ *  queues in tx scheduler.
+ *
+ * @param pdev - the physical device object, which stores the txqs
+ * @param flush_all - flush all pending tx queues if set to true
+ * @param tx_descs - List Of tx_descs to be discarded will be returned by this
+ *                   function
+ */
+
+void
+ol_tx_queue_discard(
+		struct ol_txrx_pdev_t *pdev,
+		bool flush_all,
+		ol_tx_desc_list *tx_descs);
+
+#else
+
+static inline void
+ol_tx_enqueue(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_frms_queue_t *txq,
+		struct ol_tx_desc_t *tx_desc,
+		struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+}
+
+static inline u_int16_t
+ol_tx_dequeue(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	ol_tx_desc_list *head,
+	u_int16_t num_frames,
+	u_int32_t *credit,
+	int *bytes)
+{
+	return 0;
+}
+
+static inline void
+ol_tx_queue_free(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_frms_queue_t *txq,
+		int tid, bool is_peer_txq)
+{
+}
+
+static inline void
+ol_tx_queue_discard(
+		struct ol_txrx_pdev_t *pdev,
+		bool flush_all,
+		ol_tx_desc_list *tx_descs)
+{
+}
+#endif /* defined(CONFIG_HL_SUPPORT) */
+
+#if (!defined(QCA_LL_LEGACY_TX_FLOW_CONTROL)) && (!defined(CONFIG_HL_SUPPORT))
+static inline
+void ol_txrx_vdev_flush(struct cdp_vdev *data_vdev)
+{
+}
+#else
+void ol_txrx_vdev_flush(struct cdp_vdev *pvdev);
+#endif
+
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \
+   (defined(QCA_LL_TX_FLOW_CONTROL_V2)) || \
+   defined(CONFIG_HL_SUPPORT)
+void ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason);
+void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason);
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
+
+void
+ol_txrx_peer_bal_add_limit_peer(
+		struct ol_txrx_pdev_t *pdev,
+		u_int16_t peer_id,
+		u_int16_t peer_limit);
+
+void
+ol_txrx_peer_bal_remove_limit_peer(
+		struct ol_txrx_pdev_t *pdev,
+		u_int16_t peer_id);
+
+/**
+ * ol_txrx_peer_pause_but_no_mgmt_q() - suspend/pause all txqs except
+ *					management queue for a given peer
+ * @peer: peer device object
+ *
+ * Return: None
+ */
+void
+ol_txrx_peer_pause_but_no_mgmt_q(ol_txrx_peer_handle peer);
+
+/**
+ * ol_txrx_peer_unpause_but_no_mgmt_q() - unpause all txqs except management
+ *					  queue for a given peer
+ * @peer: peer device object
+ *
+ * Return: None
+ */
+void
+ol_txrx_peer_unpause_but_no_mgmt_q(ol_txrx_peer_handle peer);
+
+/**
+ * ol_tx_bad_peer_dequeue_check() - retrieve the send limit
+ *				    of the tx queue category
+ * @txq: tx queue of the head of the category list
+ * @max_frames: send limit of the txq category
+ * @tx_limit_flag: set true is tx limit is reached
+ *
+ * Return: send limit
+ */
+u_int16_t
+ol_tx_bad_peer_dequeue_check(struct ol_tx_frms_queue_t *txq,
+			     u_int16_t max_frames,
+			     u_int16_t *tx_limit_flag);
+
+/**
+ * ol_tx_bad_peer_update_tx_limit() - update the send limit of the
+ *				      tx queue category
+ * @pdev: the physical device object
+ * @txq: tx queue of the head of the category list
+ * @frames: frames that has been dequeued
+ * @tx_limit_flag: tx limit reached flag
+ *
+ * Return: None
+ */
+void
+ol_tx_bad_peer_update_tx_limit(struct ol_txrx_pdev_t *pdev,
+			       struct ol_tx_frms_queue_t *txq,
+			       u_int16_t frames,
+			       u_int16_t tx_limit_flag);
+
+/**
+ * ol_txrx_set_txq_peer() - set peer to the tx queue's peer
+ * @txq: tx queue for a given tid
+ * @peer: the peer device object
+ *
+ * Return: None
+ */
+void
+ol_txrx_set_txq_peer(
+	struct ol_tx_frms_queue_t *txq,
+	struct ol_txrx_peer_t *peer);
+
+/**
+ * @brief - initialize the peer balance context
+ * @param pdev - the physical device object, which stores the txqs
+ */
+void ol_tx_badpeer_flow_cl_init(struct ol_txrx_pdev_t *pdev);
+
+/**
+ * @brief - deinitialize the peer balance context
+ * @param pdev - the physical device object, which stores the txqs
+ */
+void ol_tx_badpeer_flow_cl_deinit(struct ol_txrx_pdev_t *pdev);
+
+#else
+
+static inline void ol_txrx_peer_bal_add_limit_peer(
+		struct ol_txrx_pdev_t *pdev,
+		u_int16_t peer_id,
+		u_int16_t peer_limit)
+{
+}
+
+static inline void ol_txrx_peer_bal_remove_limit_peer(
+		struct ol_txrx_pdev_t *pdev,
+		u_int16_t peer_id)
+{
+}
+
+static inline void ol_txrx_peer_pause_but_no_mgmt_q(ol_txrx_peer_handle peer)
+{
+}
+
+static inline void ol_txrx_peer_unpause_but_no_mgmt_q(ol_txrx_peer_handle peer)
+{
+}
+
+static inline u_int16_t
+ol_tx_bad_peer_dequeue_check(struct ol_tx_frms_queue_t *txq,
+			     u_int16_t max_frames,
+			     u_int16_t *tx_limit_flag)
+{
+	/* just return max_frames */
+	return max_frames;
+}
+
+static inline void
+ol_tx_bad_peer_update_tx_limit(struct ol_txrx_pdev_t *pdev,
+			       struct ol_tx_frms_queue_t *txq,
+			       u_int16_t frames,
+			       u_int16_t tx_limit_flag)
+{
+}
+
+static inline void
+ol_txrx_set_txq_peer(
+		struct ol_tx_frms_queue_t *txq,
+		struct ol_txrx_peer_t *peer)
+{
+}
+
+static inline void ol_tx_badpeer_flow_cl_init(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+static inline void ol_tx_badpeer_flow_cl_deinit(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+#endif /* defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL) */
+
+#if defined(CONFIG_HL_SUPPORT) && defined(DEBUG_HL_LOGGING)
+
+/**
+ * ol_tx_queue_log_sched() - start logging of tx queues for HL
+ * @pdev: physical device object
+ * @credit: number of credits
+ * @num_active_tids: number of active tids for which logging needs to be done
+ * @active_bitmap:bitmap
+ * @data: buffer
+ *
+ * Return: None
+ */
+void
+ol_tx_queue_log_sched(struct ol_txrx_pdev_t *pdev,
+		      int credit,
+		      int *num_active_tids,
+		      uint32_t **active_bitmap, uint8_t **data);
+#else
+
+static inline void
+ol_tx_queue_log_sched(struct ol_txrx_pdev_t *pdev,
+		      int credit,
+		      int *num_active_tids,
+		      uint32_t **active_bitmap, uint8_t **data)
+{
+}
+#endif /* defined(CONFIG_HL_SUPPORT) && defined(DEBUG_HL_LOGGING) */
+
+#if defined(CONFIG_HL_SUPPORT) && TXRX_DEBUG_LEVEL > 5
+/**
+ * @brief - show current state of all tx queues
+ * @param pdev - the physical device object, which stores the txqs
+ */
+void
+ol_tx_queues_display(struct ol_txrx_pdev_t *pdev);
+
+#else
+
+static inline void
+ol_tx_queues_display(struct ol_txrx_pdev_t *pdev)
+{
+}
+#endif
+
+#define ol_tx_queue_decs_reinit(peer, peer_id)  /* no-op */
+
+#ifdef QCA_SUPPORT_TX_THROTTLE
+void ol_tx_throttle_set_level(struct cdp_pdev *ppdev, int level);
+void ol_tx_throttle_init_period(struct cdp_pdev *ppdev, int period,
+				uint8_t *dutycycle_level);
+
+/**
+ * @brief - initialize the throttle context
+ * @param pdev - the physical device object, which stores the txqs
+ */
+void ol_tx_throttle_init(struct ol_txrx_pdev_t *pdev);
+#else
+static inline void ol_tx_throttle_init(struct ol_txrx_pdev_t *pdev) {}
+
+static inline void ol_tx_throttle_set_level(struct cdp_pdev *ppdev, int level)
+{}
+
+static inline void ol_tx_throttle_init_period(struct cdp_pdev *ppdev,
+					      int period,
+					      uint8_t *dutycycle_level)
+{}
+#endif
+
+#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+static inline bool
+ol_tx_is_txq_last_serviced_queue(struct ol_txrx_pdev_t *pdev,
+				 struct ol_tx_frms_queue_t *txq)
+{
+	return txq == pdev->tx_sched.last_used_txq;
+}
+
+/**
+ * ol_tx_txq_group_credit_limit() - check for credit limit of a given tx queue
+ * @pdev: physical device object
+ * @txq: tx queue for which credit limit needs be to checked
+ * @credit: number of credits of the selected category
+ *
+ * Return: updated credits
+ */
+u_int32_t ol_tx_txq_group_credit_limit(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_frms_queue_t *txq,
+		u_int32_t credit);
+
+/**
+ * ol_tx_txq_group_credit_update() - update group credits of the
+ *				     selected catoegory
+ * @pdev: physical device object
+ * @txq: tx queue for which credit needs to be updated
+ * @credit: number of credits by which selected category needs to be updated
+ * @absolute: TXQ group absolute value
+ *
+ * Return: None
+ */
+void ol_tx_txq_group_credit_update(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_frms_queue_t *txq,
+		int32_t credit,
+		u_int8_t absolute);
+
+/**
+ * ol_tx_set_vdev_group_ptr() - update vdev queues group pointer
+ * @pdev: physical device object
+ * @vdev_id: vdev id for which group pointer needs to update
+ * @grp_ptr: pointer to ol tx queue group which needs to be set for vdev queues
+ *
+ * Return: None
+ */
+void
+ol_tx_set_vdev_group_ptr(
+		ol_txrx_pdev_handle pdev,
+		u_int8_t vdev_id,
+		struct ol_tx_queue_group_t *grp_ptr);
+
+/**
+ * ol_tx_txq_set_group_ptr() - update tx queue group pointer
+ * @txq: tx queue of which group pointer needs to update
+ * @grp_ptr: pointer to ol tx queue group which needs to be
+ *	     set for given tx queue
+ *
+ *
+ * Return: None
+ */
+void
+ol_tx_txq_set_group_ptr(
+		struct ol_tx_frms_queue_t *txq,
+		struct ol_tx_queue_group_t *grp_ptr);
+
+/**
+ * ol_tx_set_peer_group_ptr() - update peer tx queues group pointer
+ *				for a given tid
+ * @pdev: physical device object
+ * @peer: peer device object
+ * @vdev_id: vdev id
+ * @tid: tid for which group pointer needs to update
+ *
+ *
+ * Return: None
+ */
+void
+ol_tx_set_peer_group_ptr(
+		ol_txrx_pdev_handle pdev,
+		struct ol_txrx_peer_t *peer,
+		u_int8_t vdev_id,
+		u_int8_t tid);
+#else
+
+static inline bool
+ol_tx_is_txq_last_serviced_queue(struct ol_txrx_pdev_t *pdev,
+				 struct ol_tx_frms_queue_t *txq)
+{
+	return 0;
+}
+
+static inline
+u_int32_t ol_tx_txq_group_credit_limit(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_frms_queue_t *txq,
+		u_int32_t credit)
+{
+	return credit;
+}
+
+static inline void ol_tx_txq_group_credit_update(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_frms_queue_t *txq,
+		int32_t credit,
+		u_int8_t absolute)
+{
+}
+
+static inline void
+ol_tx_txq_set_group_ptr(
+		struct ol_tx_frms_queue_t *txq,
+		struct ol_tx_queue_group_t *grp_ptr)
+{
+}
+
+static inline void
+ol_tx_set_peer_group_ptr(
+		ol_txrx_pdev_handle pdev,
+		struct ol_txrx_peer_t *peer,
+		u_int8_t vdev_id,
+		u_int8_t tid)
+{
+}
+#endif
+
+#if defined(FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL) && \
+	defined(FEATURE_HL_DBS_GROUP_CREDIT_SHARING)
+/**
+ * @brief: Update group frame count
+ * @details: This function is used to maintain the count of frames
+ * enqueued in a particular group.
+ *
+ * @param: txq - The txq to which the frame is getting enqueued.
+ * @param: num_frms - Number of frames to be added/removed from the group.
+ */
+void ol_tx_update_grp_frm_count(struct ol_tx_frms_queue_t *txq, int num_frms);
+
+u32 ol_tx_txq_update_borrowed_group_credits(struct ol_txrx_pdev_t *pdev,
+					    struct ol_tx_frms_queue_t *txq,
+					    u32 credits_used);
+#else
+static inline void ol_tx_update_grp_frm_count(struct ol_tx_frms_queue_t *txq,
+					      int num_frms)
+{}
+
+static inline u32
+ol_tx_txq_update_borrowed_group_credits(struct ol_txrx_pdev_t *pdev,
+					struct ol_tx_frms_queue_t *txq,
+					u32 credits_used)
+{
+	return credits_used;
+}
+#endif /*
+	* FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL &&
+	*  FEATURE_HL_DBS_GROUP_CREDIT_SHARING
+	*/
+
+#endif /* _OL_TX_QUEUE__H_ */
diff --git a/core/dp/txrx/ol_tx_sched.c b/core/dp/txrx/ol_tx_sched.c
new file mode 100644
index 0000000..bdfc349
--- /dev/null
+++ b/core/dp/txrx/ol_tx_sched.c
@@ -0,0 +1,1600 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#include <qdf_nbuf.h>         /* qdf_nbuf_t, etc. */
+#include <htt.h>              /* HTT_TX_EXT_TID_MGMT */
+#include <ol_htt_tx_api.h>    /* htt_tx_desc_tid */
+#include <ol_txrx_api.h>      /* ol_txrx_vdev_handle */
+#include <ol_txrx_ctrl_api.h> /* ol_txrx_sync */
+#include <ol_txrx_internal.h> /* TXRX_ASSERT1 */
+#include <ol_txrx_types.h>    /* pdev stats, etc. */
+#include <ol_tx_desc.h>       /* ol_tx_desc */
+#include <ol_tx_send.h>       /* ol_tx_send */
+#include <ol_tx_sched.h>      /* OL_TX_SCHED, etc. */
+#include <ol_tx_queue.h>
+#include <ol_txrx.h>
+#include <qdf_types.h>
+#include <qdf_mem.h>         /* qdf_os_mem_alloc_consistent et al */
+#include <cdp_txrx_handle.h>
+#if defined(CONFIG_HL_SUPPORT)
+
+#if defined(DEBUG_HL_LOGGING)
+static void
+ol_tx_sched_log(struct ol_txrx_pdev_t *pdev);
+
+#else
+static void
+ol_tx_sched_log(struct ol_txrx_pdev_t *pdev)
+{
+}
+#endif /* defined(DEBUG_HL_LOGGING) */
+
+#if DEBUG_HTT_CREDIT
+#define OL_TX_DISPATCH_LOG_CREDIT()                                           \
+	do {								      \
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,	\
+			"TX %d bytes\n", qdf_nbuf_len(msdu));	\
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,	\
+			" <HTT> Decrease credit %d - 1 = %d, len:%d.\n",  \
+			qdf_atomic_read(&pdev->target_tx_credit),	\
+			qdf_atomic_read(&pdev->target_tx_credit) - 1,	\
+			qdf_nbuf_len(msdu));				\
+	} while (0)
+#else
+#define OL_TX_DISPATCH_LOG_CREDIT()
+#endif
+
+/*--- generic definitions used by the scheduler framework for all algs ---*/
+
+struct ol_tx_sched_ctx {
+	ol_tx_desc_list head;
+	int frms;
+};
+
+typedef TAILQ_HEAD(ol_tx_frms_queue_list_s, ol_tx_frms_queue_t)
+	ol_tx_frms_queue_list;
+
+#define OL_A_MAX(_x, _y) ((_x) > (_y) ? (_x) : (_y))
+
+#define OL_A_MIN(_x, _y) ((_x) < (_y) ? (_x) : (_y))
+
+	/*--- scheduler algorithm selection ---*/
+
+	/*--- scheduler options -----------------------------------------------
+	 * 1. Round-robin scheduler:
+	 *    Select the TID that is at the head of the list of active TIDs.
+	 *    Select the head tx queue for this TID.
+	 *    Move the tx queue to the back of the list of tx queues for
+	 *    this TID.
+	 *    Move the TID to the back of the list of active TIDs.
+	 *    Send as many frames from the tx queue as credit allows.
+	 * 2. Weighted-round-robin advanced scheduler:
+	 *    Keep an ordered list of which TID gets selected next.
+	 *    Use a weighted-round-robin scheme to determine when to promote
+	 *    a TID within this list.
+	 *    If a TID at the head of the list is inactive, leave it at the
+	 *    head, but check the next TIDs.
+	 *    If the credit available is less than the credit threshold for the
+	 *    next active TID, don't send anything, and leave the TID at the
+	 *    head of the list.
+	 *    After a TID is selected, move it to the back of the list.
+	 *    Select the head tx queue for this TID.
+	 *    Move the tx queue to the back of the list of tx queues for this
+	 *    TID.
+	 *    Send no more frames than the limit specified for the TID.
+	 */
+#define OL_TX_SCHED_RR  1
+#define OL_TX_SCHED_WRR_ADV 2
+
+#ifndef OL_TX_SCHED
+	/*#define OL_TX_SCHED OL_TX_SCHED_RR*/
+#define OL_TX_SCHED OL_TX_SCHED_WRR_ADV /* default */
+#endif
+
+
+#if OL_TX_SCHED == OL_TX_SCHED_RR
+
+#define ol_tx_sched_rr_t ol_tx_sched_t
+
+#define OL_TX_SCHED_NUM_CATEGORIES (OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES)
+
+#define ol_tx_sched_init                ol_tx_sched_init_rr
+#define ol_tx_sched_select_init(pdev)   /* no-op */
+#define ol_tx_sched_select_batch        ol_tx_sched_select_batch_rr
+#define ol_tx_sched_txq_enqueue         ol_tx_sched_txq_enqueue_rr
+#define ol_tx_sched_txq_deactivate      ol_tx_sched_txq_deactivate_rr
+#define ol_tx_sched_category_tx_queues  ol_tx_sched_category_tx_queues_rr
+#define ol_tx_sched_txq_discard         ol_tx_sched_txq_discard_rr
+#define ol_tx_sched_category_info       ol_tx_sched_category_info_rr
+#define ol_tx_sched_discard_select_category \
+		ol_tx_sched_discard_select_category_rr
+
+#elif OL_TX_SCHED == OL_TX_SCHED_WRR_ADV
+
+#define ol_tx_sched_wrr_adv_t ol_tx_sched_t
+
+#define OL_TX_SCHED_NUM_CATEGORIES OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES
+
+#define ol_tx_sched_init                ol_tx_sched_init_wrr_adv
+#define ol_tx_sched_select_init(pdev) \
+		do { \
+			qdf_spin_lock_bh(&pdev->tx_queue_spinlock); \
+			ol_tx_sched_select_init_wrr_adv(pdev); \
+			qdf_spin_unlock_bh(&pdev->tx_queue_spinlock); \
+		} while (0)
+#define ol_tx_sched_select_batch        ol_tx_sched_select_batch_wrr_adv
+#define ol_tx_sched_txq_enqueue         ol_tx_sched_txq_enqueue_wrr_adv
+#define ol_tx_sched_txq_deactivate      ol_tx_sched_txq_deactivate_wrr_adv
+#define ol_tx_sched_category_tx_queues  ol_tx_sched_category_tx_queues_wrr_adv
+#define ol_tx_sched_txq_discard         ol_tx_sched_txq_discard_wrr_adv
+#define ol_tx_sched_category_info       ol_tx_sched_category_info_wrr_adv
+#define ol_tx_sched_discard_select_category \
+		ol_tx_sched_discard_select_category_wrr_adv
+
+#else
+
+#error Unknown OL TX SCHED specification
+
+#endif /* OL_TX_SCHED */
+
+	/*--- round-robin scheduler ----------------------------------------*/
+#if OL_TX_SCHED == OL_TX_SCHED_RR
+
+	/*--- definitions ---*/
+
+	struct ol_tx_active_queues_in_tid_t {
+		/* list_elem is used to queue up into up level queues*/
+		TAILQ_ENTRY(ol_tx_active_queues_in_tid_t) list_elem;
+		u_int32_t frms;
+		u_int32_t bytes;
+		ol_tx_frms_queue_list head;
+		bool    active;
+		int tid;
+	};
+
+	struct ol_tx_sched_rr_t {
+		struct ol_tx_active_queues_in_tid_t
+			tx_active_queues_in_tid_array[OL_TX_NUM_TIDS
+						+ OL_TX_VDEV_NUM_QUEUES];
+	TAILQ_HEAD(ol_tx_active_tids_s, ol_tx_active_queues_in_tid_t)
+							tx_active_tids_list;
+		u_int8_t discard_weights[OL_TX_NUM_TIDS
+					+ OL_TX_VDEV_NUM_QUEUES];
+	};
+
+#define TX_SCH_MAX_CREDIT_FOR_THIS_TID(tidq) 16
+
+/*--- functions ---*/
+
+/*
+ * The scheduler sync spinlock has been acquired outside this function,
+ * so there is no need to worry about mutex within this function.
+ */
+static int
+ol_tx_sched_select_batch_rr(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_sched_ctx *sctx,
+	u_int32_t credit)
+{
+	struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_active_queues_in_tid_t *txq_queue;
+	struct ol_tx_frms_queue_t *next_tq;
+	u_int16_t frames, used_credits = 0, tx_limit, tx_limit_flag = 0;
+	int bytes;
+
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+
+	if (TAILQ_EMPTY(&scheduler->tx_active_tids_list))
+		return used_credits;
+
+	txq_queue = TAILQ_FIRST(&scheduler->tx_active_tids_list);
+
+	TAILQ_REMOVE(&scheduler->tx_active_tids_list, txq_queue, list_elem);
+	txq_queue->active = false;
+
+	next_tq = TAILQ_FIRST(&txq_queue->head);
+	TAILQ_REMOVE(&txq_queue->head, next_tq, list_elem);
+
+	credit = OL_A_MIN(credit, TX_SCH_MAX_CREDIT_FOR_THIS_TID(next_tq));
+	frames = next_tq->frms; /* download as many frames as credit allows */
+	tx_limit = ol_tx_bad_peer_dequeue_check(next_tq,
+					frames,
+					&tx_limit_flag);
+	frames = ol_tx_dequeue(
+			pdev, next_tq, &sctx->head, tx_limit, &credit, &bytes);
+	ol_tx_bad_peer_update_tx_limit(pdev, next_tq, frames, tx_limit_flag);
+
+	used_credits = credit;
+	txq_queue->frms -= frames;
+	txq_queue->bytes -= bytes;
+
+	if (next_tq->frms > 0) {
+		TAILQ_INSERT_TAIL(&txq_queue->head, next_tq, list_elem);
+		TAILQ_INSERT_TAIL(
+				&scheduler->tx_active_tids_list,
+						txq_queue, list_elem);
+		txq_queue->active = true;
+	} else if (!TAILQ_EMPTY(&txq_queue->head)) {
+		/*
+		 * This tx queue is empty, but there's another tx queue for the
+		 * same TID that is not empty.
+		 *Thus, the TID as a whole is active.
+		 */
+		TAILQ_INSERT_TAIL(
+				&scheduler->tx_active_tids_list,
+						txq_queue, list_elem);
+		txq_queue->active = true;
+	}
+	sctx->frms += frames;
+
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+	return used_credits;
+}
+
+static inline void
+ol_tx_sched_txq_enqueue_rr(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	int tid,
+	int frms,
+	int bytes)
+{
+	struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_active_queues_in_tid_t *txq_queue;
+
+	txq_queue = &scheduler->tx_active_queues_in_tid_array[tid];
+	if (txq->flag != ol_tx_queue_active)
+		TAILQ_INSERT_TAIL(&txq_queue->head, txq, list_elem);
+
+	txq_queue->frms += frms;
+	txq_queue->bytes += bytes;
+
+	if (!txq_queue->active) {
+		TAILQ_INSERT_TAIL(
+				&scheduler->tx_active_tids_list,
+				txq_queue, list_elem);
+		txq_queue->active = true;
+	}
+}
+
+static inline void
+ol_tx_sched_txq_deactivate_rr(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	int tid)
+{
+	struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_active_queues_in_tid_t *txq_queue;
+
+	txq_queue = &scheduler->tx_active_queues_in_tid_array[tid];
+	txq_queue->frms -= txq->frms;
+	txq_queue->bytes -= txq->bytes;
+
+	TAILQ_REMOVE(&txq_queue->head, txq, list_elem);
+	/*if (txq_queue->frms == 0 && txq_queue->active) {*/
+	if (TAILQ_EMPTY(&txq_queue->head) && txq_queue->active) {
+		TAILQ_REMOVE(&scheduler->tx_active_tids_list, txq_queue,
+			     list_elem);
+		txq_queue->active = false;
+	}
+}
+
+ol_tx_frms_queue_list *
+ol_tx_sched_category_tx_queues_rr(struct ol_txrx_pdev_t *pdev, int tid)
+{
+	struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_active_queues_in_tid_t *txq_queue;
+
+	txq_queue = &scheduler->tx_active_queues_in_tid_array[tid];
+	return &txq_queue->head;
+}
+
+int
+ol_tx_sched_discard_select_category_rr(struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_tx_sched_rr_t *scheduler;
+	u_int8_t i, tid = 0;
+	int max_score = 0;
+
+	scheduler = pdev->tx_sched.scheduler;
+	/*
+	 * Choose which TID's tx frames to drop next based on two factors:
+	 * 1.  Which TID has the most tx frames present
+	 * 2.  The TID's priority (high-priority TIDs have a low discard_weight)
+	 */
+	for (i = 0; i < (OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES); i++) {
+		int score;
+
+		score =
+			scheduler->tx_active_queues_in_tid_array[i].frms *
+			scheduler->discard_weights[i];
+		if (max_score == 0 || score > max_score) {
+			max_score = score;
+			tid = i;
+		}
+	}
+	return tid;
+}
+
+void
+ol_tx_sched_txq_discard_rr(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	int tid, int frames, int bytes)
+{
+	struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_active_queues_in_tid_t *txq_queue;
+
+	txq_queue = &scheduler->tx_active_queues_in_tid_array[tid];
+
+	if (0 == txq->frms)
+		TAILQ_REMOVE(&txq_queue->head, txq, list_elem);
+
+	txq_queue->frms -= frames;
+	txq_queue->bytes -= bytes;
+	if (txq_queue->active == true && txq_queue->frms == 0) {
+		TAILQ_REMOVE(&scheduler->tx_active_tids_list, txq_queue,
+			     list_elem);
+		txq_queue->active = false;
+	}
+}
+
+void
+ol_tx_sched_category_info_rr(
+	struct ol_txrx_pdev_t *pdev,
+	int cat, int *active,
+	int *frms, int *bytes)
+{
+	struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_active_queues_in_tid_t *txq_queue;
+
+	txq_queue = &scheduler->tx_active_queues_in_tid_array[cat];
+
+	*active = txq_queue->active;
+	*frms = txq_queue->frms;
+	*bytes = txq_queue->bytes;
+}
+
+enum {
+	ol_tx_sched_discard_weight_voice = 1,
+	ol_tx_sched_discard_weight_video = 4,
+	ol_tx_sched_discard_weight_ucast_default = 8,
+	ol_tx_sched_discard_weight_mgmt_non_qos = 1, /* 0? */
+	ol_tx_sched_discard_weight_mcast = 1, /* 0? also for probe & assoc */
+};
+
+void *
+ol_tx_sched_init_rr(
+	struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_tx_sched_rr_t *scheduler;
+	int i;
+
+	scheduler = qdf_mem_malloc(sizeof(struct ol_tx_sched_rr_t));
+	if (scheduler == NULL)
+		return scheduler;
+
+	for (i = 0; i < (OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES); i++) {
+		scheduler->tx_active_queues_in_tid_array[i].tid = i;
+		TAILQ_INIT(&scheduler->tx_active_queues_in_tid_array[i].head);
+		scheduler->tx_active_queues_in_tid_array[i].active = 0;
+		scheduler->tx_active_queues_in_tid_array[i].frms = 0;
+		scheduler->tx_active_queues_in_tid_array[i].bytes = 0;
+	}
+	for (i = 0; i < OL_TX_NUM_TIDS; i++) {
+		scheduler->tx_active_queues_in_tid_array[i].tid = i;
+		if (i < OL_TX_NON_QOS_TID) {
+			int ac = TXRX_TID_TO_WMM_AC(i);
+
+			switch (ac) {
+			case TXRX_WMM_AC_VO:
+				scheduler->discard_weights[i] =
+					ol_tx_sched_discard_weight_voice;
+			case TXRX_WMM_AC_VI:
+				scheduler->discard_weights[i] =
+					ol_tx_sched_discard_weight_video;
+			default:
+				scheduler->discard_weights[i] =
+				ol_tx_sched_discard_weight_ucast_default;
+			};
+		} else {
+			scheduler->discard_weights[i] =
+				ol_tx_sched_discard_weight_mgmt_non_qos;
+		}
+	}
+	for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) {
+		int j = i + OL_TX_NUM_TIDS;
+
+		scheduler->tx_active_queues_in_tid_array[j].tid =
+							OL_TX_NUM_TIDS - 1;
+		scheduler->discard_weights[j] =
+					ol_tx_sched_discard_weight_mcast;
+	}
+	TAILQ_INIT(&scheduler->tx_active_tids_list);
+
+	return scheduler;
+}
+
+void
+ol_txrx_set_wmm_param(struct cdp_pdev *data_pdev,
+		      struct ol_tx_wmm_param_t wmm_param)
+{
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "Dummy function when OL_TX_SCHED_RR is enabled\n");
+}
+
+/**
+ * ol_tx_sched_stats_display() - tx sched stats display
+ * @pdev: Pointer to the PDEV structure.
+ *
+ * Return: none.
+ */
+void ol_tx_sched_stats_display(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+/**
+ * ol_tx_sched_cur_state_display() - tx sched cur stat display
+ * @pdev: Pointer to the PDEV structure.
+ *
+ * Return: none.
+ */
+void ol_tx_sched_cur_state_display(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+/**
+ * ol_tx_sched_cur_state_display() - reset tx sched stats
+ * @pdev: Pointer to the PDEV structure.
+ *
+ * Return: none.
+ */
+void ol_tx_sched_stats_clear(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+#endif /* OL_TX_SCHED == OL_TX_SCHED_RR */
+
+/*--- advanced scheduler ----------------------------------------------------*/
+#if OL_TX_SCHED == OL_TX_SCHED_WRR_ADV
+
+/*--- definitions ---*/
+
+struct ol_tx_sched_wrr_adv_category_info_t {
+	struct {
+		int wrr_skip_weight;
+		u_int32_t credit_threshold;
+		u_int16_t send_limit;
+		int credit_reserve;
+		int discard_weight;
+	} specs;
+	struct {
+		int wrr_count;
+		int frms;
+		int bytes;
+		ol_tx_frms_queue_list head;
+		bool active;
+	} state;
+#ifdef DEBUG_HL_LOGGING
+	struct {
+		char *cat_name;
+		unsigned int queued;
+		unsigned int dispatched;
+		unsigned int discard;
+	} stat;
+#endif
+};
+
+#define OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(cat, \
+		wrr_skip_weight, \
+		credit_threshold, \
+		send_limit, \
+		credit_reserve, \
+		discard_weights) \
+		enum { OL_TX_SCHED_WRR_ADV_ ## cat ## _WRR_SKIP_WEIGHT = \
+			(wrr_skip_weight) }; \
+		enum { OL_TX_SCHED_WRR_ADV_ ## cat ## _CREDIT_THRESHOLD = \
+			(credit_threshold) }; \
+		enum { OL_TX_SCHED_WRR_ADV_ ## cat ## _SEND_LIMIT = \
+			(send_limit) }; \
+		enum { OL_TX_SCHED_WRR_ADV_ ## cat ## _CREDIT_RESERVE = \
+			(credit_reserve) }; \
+		enum { OL_TX_SCHED_WRR_ADV_ ## cat ## _DISCARD_WEIGHT = \
+			(discard_weights) };
+/* Rome:
+ * For high-volume traffic flows (VI, BE, BK), use a credit threshold
+ * roughly equal to a large A-MPDU (occupying half the target memory
+ * available for holding tx frames) to download AMPDU-sized batches
+ * of traffic.
+ * For high-priority, low-volume traffic flows (VO and mgmt), use no
+ * credit threshold, to minimize download latency.
+ */
+/*                                            WRR           send
+ *                                           skip  credit  limit credit disc
+ *                                            wts  thresh (frms) reserv  wts
+ */
+#ifdef HIF_SDIO
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(VO,           1,     17,    24,     0,  1);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(VI,           3,     17,    16,     1,  4);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(BE,          10,     17,    16,     1,  8);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(BK,          12,      6,     6,     1,  8);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(NON_QOS_DATA,10,     17,    16,     1,  8);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(UCAST_MGMT,   1,      1,     4,     0,  1);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(MCAST_DATA,  10,     17,     4,     1,  4);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(MCAST_MGMT,   1,      1,     4,     0,  1);
+#else
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(VO,           1,     16,    24,     0,  1);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(VI,           3,     16,    16,     1,  4);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(BE,          10,     12,    12,     1,  8);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(BK,          12,      6,     6,     1,  8);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(NON_QOS_DATA, 12,      6,     4,     1,  8);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(UCAST_MGMT,   1,      1,     4,     0,  1);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(MCAST_DATA,  10,     16,     4,     1,  4);
+OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(MCAST_MGMT,   1,      1,     4,     0,  1);
+#endif
+
+#ifdef DEBUG_HL_LOGGING
+
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INIT(category, scheduler)               \
+	do {                                                                 \
+		scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category]  \
+		.stat.queued = 0;					\
+		scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category]  \
+		.stat.discard = 0;					\
+		scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category]  \
+		.stat.dispatched = 0;					\
+		scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category]  \
+		.stat.cat_name = #category;				\
+	} while (0)
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_QUEUED(category, frms)             \
+	category->stat.queued += frms;
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_DISCARD(category, frms)           \
+	category->stat.discard += frms;
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_DISPATCHED(category, frms)         \
+	category->stat.dispatched += frms;
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_DUMP(scheduler)                        \
+	ol_tx_sched_wrr_adv_cat_stat_dump(scheduler)
+#define OL_TX_SCHED_WRR_ADV_CAT_CUR_STATE_DUMP(scheduler)                   \
+	ol_tx_sched_wrr_adv_cat_cur_state_dump(scheduler)
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_CLEAR(scheduler)                       \
+	ol_tx_sched_wrr_adv_cat_stat_clear(scheduler)
+
+#else   /* DEBUG_HL_LOGGING */
+
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INIT(category, scheduler)
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_QUEUED(category, frms)
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_DISCARD(category, frms)
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_DISPATCHED(category, frms)
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_DUMP(scheduler)
+#define OL_TX_SCHED_WRR_ADV_CAT_CUR_STATE_DUMP(scheduler)
+#define OL_TX_SCHED_WRR_ADV_CAT_STAT_CLEAR(scheduler)
+
+#endif  /* DEBUG_HL_LOGGING */
+
+#define OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(category, scheduler) \
+	do { \
+		scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category] \
+		.specs.wrr_skip_weight = \
+		OL_TX_SCHED_WRR_ADV_ ## category ## _WRR_SKIP_WEIGHT; \
+		scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category] \
+		.specs.credit_threshold = \
+		OL_TX_SCHED_WRR_ADV_ ## category ## _CREDIT_THRESHOLD; \
+		scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category] \
+		.specs.send_limit = \
+		OL_TX_SCHED_WRR_ADV_ ## category ## _SEND_LIMIT; \
+		scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category] \
+		.specs.credit_reserve = \
+		OL_TX_SCHED_WRR_ADV_ ## category ## _CREDIT_RESERVE; \
+		scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category] \
+		.specs.discard_weight = \
+		OL_TX_SCHED_WRR_ADV_ ## category ## _DISCARD_WEIGHT; \
+		OL_TX_SCHED_WRR_ADV_CAT_STAT_INIT(category, scheduler); \
+	} while (0)
+
+struct ol_tx_sched_wrr_adv_t {
+	int order[OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES];
+	int index;
+	struct ol_tx_sched_wrr_adv_category_info_t
+		categories[OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES];
+};
+
+#define OL_TX_AIFS_DEFAULT_VO   2
+#define OL_TX_AIFS_DEFAULT_VI   2
+#define OL_TX_AIFS_DEFAULT_BE   3
+#define OL_TX_AIFS_DEFAULT_BK   7
+#define OL_TX_CW_MIN_DEFAULT_VO   3
+#define OL_TX_CW_MIN_DEFAULT_VI   7
+#define OL_TX_CW_MIN_DEFAULT_BE   15
+#define OL_TX_CW_MIN_DEFAULT_BK   15
+
+/*--- functions ---*/
+
+#ifdef DEBUG_HL_LOGGING
+static void ol_tx_sched_wrr_adv_cat_stat_dump(
+	struct ol_tx_sched_wrr_adv_t *scheduler)
+{
+	int i;
+
+	txrx_nofl_info("Scheduler Stats:");
+	txrx_nofl_info("====category(CRR,CRT,WSW): Queued  Discard  Dequeued  frms  wrr===");
+	for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; ++i) {
+		txrx_nofl_info("%12s(%2d, %2d, %2d):  %6d  %7d  %8d  %4d  %3d",
+			       scheduler->categories[i].stat.cat_name,
+			       scheduler->categories[i].specs.credit_reserve,
+			       scheduler->categories[i].specs.
+					credit_threshold,
+			       scheduler->categories[i].
+					specs.wrr_skip_weight,
+			       scheduler->categories[i].stat.queued,
+			       scheduler->categories[i].stat.discard,
+			       scheduler->categories[i].stat.dispatched,
+			       scheduler->categories[i].state.frms,
+			       scheduler->categories[i].state.wrr_count);
+	}
+}
+
+static void ol_tx_sched_wrr_adv_cat_cur_state_dump(
+	struct ol_tx_sched_wrr_adv_t *scheduler)
+{
+	int i;
+
+	txrx_nofl_info("Scheduler State Snapshot:");
+	txrx_nofl_info("====category(CRR,CRT,WSW): IS_Active  Pend_Frames  Pend_bytes  wrr===");
+	for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; ++i) {
+		txrx_nofl_info("%12s(%2d, %2d, %2d):  %9d  %11d  %10d  %3d",
+			       scheduler->categories[i].stat.cat_name,
+			       scheduler->categories[i].specs.credit_reserve,
+			       scheduler->categories[i].specs.
+					credit_threshold,
+			       scheduler->categories[i].specs.
+					wrr_skip_weight,
+			       scheduler->categories[i].state.active,
+			       scheduler->categories[i].state.frms,
+			       scheduler->categories[i].state.bytes,
+			       scheduler->categories[i].state.wrr_count);
+	}
+}
+
+static void ol_tx_sched_wrr_adv_cat_stat_clear(
+	struct ol_tx_sched_wrr_adv_t *scheduler)
+{
+	int i;
+
+	for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; ++i) {
+		scheduler->categories[i].stat.queued = 0;
+		scheduler->categories[i].stat.discard = 0;
+		scheduler->categories[i].stat.dispatched = 0;
+	}
+}
+
+#endif
+
+static void
+ol_tx_sched_select_init_wrr_adv(struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler;
+	/* start selection from the front of the ordered list */
+	scheduler->index = 0;
+	pdev->tx_sched.last_used_txq = NULL;
+}
+
+static void
+ol_tx_sched_wrr_adv_rotate_order_list_tail(
+		struct ol_tx_sched_wrr_adv_t *scheduler, int idx)
+{
+	int value;
+	/* remember the value of the specified element */
+	value = scheduler->order[idx];
+	/* shift all further elements up one space */
+	for (; idx < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES-1; idx++)
+		scheduler->order[idx] = scheduler->order[idx + 1];
+
+	/* put the specified element at the end */
+	scheduler->order[idx] = value;
+}
+
+static void
+ol_tx_sched_wrr_adv_credit_sanity_check(struct ol_txrx_pdev_t *pdev,
+					u_int32_t credit)
+{
+	struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler;
+	int i;
+	int okay = 1;
+
+	for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; i++) {
+		if (scheduler->categories[i].specs.credit_threshold > credit) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				  "*** Config error: credit (%d) not enough to support category %d threshold (%d)\n",
+				  credit, i,
+				  scheduler->categories[i].specs.
+						credit_threshold);
+			okay = 0;
+		}
+	}
+	qdf_assert(okay);
+}
+
+/*
+ * The scheduler sync spinlock has been acquired outside this function,
+ * so there is no need to worry about mutex within this function.
+ */
+static int
+ol_tx_sched_select_batch_wrr_adv(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_sched_ctx *sctx,
+	u_int32_t credit)
+{
+	static int first = 1;
+	int category_index = 0;
+	struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_frms_queue_t *txq;
+	int index;
+	struct ol_tx_sched_wrr_adv_category_info_t *category = NULL;
+	int frames, bytes, used_credits = 0, tx_limit;
+	u_int16_t tx_limit_flag;
+
+	/*
+	 * Just for good measure, do a sanity check that the initial credit
+	 * is enough to cover every category's credit threshold.
+	 */
+	if (first) {
+		first = 0;
+		ol_tx_sched_wrr_adv_credit_sanity_check(pdev, credit);
+	}
+
+	/* choose the traffic category from the ordered list */
+	index = scheduler->index;
+	while (index < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES) {
+		category_index = scheduler->order[index];
+		category = &scheduler->categories[category_index];
+		if (!category->state.active) {
+			/* move on to the next category */
+			index++;
+			continue;
+		}
+		if (++category->state.wrr_count <
+					category->specs.wrr_skip_weight) {
+			/* skip this cateogry (move it to the back) */
+			ol_tx_sched_wrr_adv_rotate_order_list_tail(scheduler,
+								   index);
+			/*
+			 * try again (iterate) on the new element
+			 * that was moved up
+			 */
+			continue;
+		}
+		/* found the first active category whose WRR turn is present */
+		break;
+	}
+	if (index >= OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES) {
+		/* no categories are active */
+		return 0;
+	}
+
+	/* is there enough credit for the selected category? */
+	if (credit < category->specs.credit_threshold) {
+		/*
+		 * Can't send yet - wait until more credit becomes available.
+		 * In the meantime, restore the WRR counter (since we didn't
+		 * service this category after all).
+		 */
+		category->state.wrr_count = category->state.wrr_count - 1;
+		return 0;
+	}
+	/* enough credit is available - go ahead and send some frames */
+	/*
+	 * This category was serviced - reset the WRR counter, and move this
+	 * category to the back of the order list.
+	 */
+	category->state.wrr_count = 0;
+	ol_tx_sched_wrr_adv_rotate_order_list_tail(scheduler, index);
+	/*
+	 * With this category moved to the back, if there's still any credit
+	 * left, set up the next invocation of this function to start from
+	 * where this one left off, by looking at the category that just got
+	 * shifted forward into the position the service category was
+	 * occupying.
+	 */
+	scheduler->index = index;
+
+	/*
+	 * Take the tx queue from the head of the category list.
+	 */
+	txq = TAILQ_FIRST(&category->state.head);
+
+	if (txq) {
+		TAILQ_REMOVE(&category->state.head, txq, list_elem);
+		credit = ol_tx_txq_group_credit_limit(pdev, txq, credit);
+		if (credit > category->specs.credit_reserve) {
+			credit -= category->specs.credit_reserve;
+			/*
+			 * this tx queue will download some frames,
+			 * so update last_used_txq
+			 */
+			pdev->tx_sched.last_used_txq = txq;
+
+			tx_limit = ol_tx_bad_peer_dequeue_check(txq,
+					category->specs.send_limit,
+					&tx_limit_flag);
+			frames = ol_tx_dequeue(
+					pdev, txq, &sctx->head,
+					tx_limit, &credit, &bytes);
+			ol_tx_bad_peer_update_tx_limit(pdev, txq,
+						       frames,
+						       tx_limit_flag);
+
+			OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_DISPATCHED(category,
+								    frames);
+			/* Update used global credits */
+			used_credits = credit;
+			credit =
+			ol_tx_txq_update_borrowed_group_credits(pdev, txq,
+								credit);
+			category->state.frms -= frames;
+			category->state.bytes -= bytes;
+			if (txq->frms > 0) {
+				TAILQ_INSERT_TAIL(&category->state.head,
+						  txq, list_elem);
+			} else {
+				if (category->state.frms == 0)
+					category->state.active = 0;
+			}
+			sctx->frms += frames;
+			ol_tx_txq_group_credit_update(pdev, txq, -credit, 0);
+		} else {
+			if (ol_tx_is_txq_last_serviced_queue(pdev, txq)) {
+				/*
+				 * The scheduler has looked at all the active
+				 * tx queues but none were able to download any
+				 * of their tx frames.
+				 * Nothing is changed, so if none were able
+				 * to download before,
+				 * they wont be able to download now.
+				 * Return that no credit has been used, which
+				 * will cause the scheduler to stop.
+				 */
+				TAILQ_INSERT_HEAD(&category->state.head, txq,
+						  list_elem);
+				return 0;
+			}
+			TAILQ_INSERT_TAIL(&category->state.head, txq,
+					  list_elem);
+			if (!pdev->tx_sched.last_used_txq)
+				pdev->tx_sched.last_used_txq = txq;
+		}
+		TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+	} else {
+		used_credits = 0;
+		/* TODO: find its reason */
+		ol_txrx_err("Error, no TXQ can be popped");
+	}
+	return used_credits;
+}
+
+static inline void
+ol_tx_sched_txq_enqueue_wrr_adv(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	int tid,
+	int frms,
+	int bytes)
+{
+	struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_sched_wrr_adv_category_info_t *category;
+
+	category = &scheduler->categories[pdev->tid_to_ac[tid]];
+	category->state.frms += frms;
+	category->state.bytes += bytes;
+	OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_QUEUED(category, frms);
+	if (txq->flag != ol_tx_queue_active) {
+		TAILQ_INSERT_TAIL(&category->state.head, txq, list_elem);
+		category->state.active = 1; /* may have already been active */
+	}
+}
+
+static inline void
+ol_tx_sched_txq_deactivate_wrr_adv(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	int tid)
+{
+	struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_sched_wrr_adv_category_info_t *category;
+
+	category = &scheduler->categories[pdev->tid_to_ac[tid]];
+	category->state.frms -= txq->frms;
+	category->state.bytes -= txq->bytes;
+
+	TAILQ_REMOVE(&category->state.head, txq, list_elem);
+
+	if (category->state.frms == 0 && category->state.active)
+		category->state.active = 0;
+}
+
+static ol_tx_frms_queue_list *
+ol_tx_sched_category_tx_queues_wrr_adv(struct ol_txrx_pdev_t *pdev, int cat)
+{
+	struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_sched_wrr_adv_category_info_t *category;
+
+	category = &scheduler->categories[cat];
+	return &category->state.head;
+}
+
+static int
+ol_tx_sched_discard_select_category_wrr_adv(struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_tx_sched_wrr_adv_t *scheduler;
+	u_int8_t i, cat = 0;
+	int max_score = 0;
+
+	scheduler = pdev->tx_sched.scheduler;
+	/*
+	 * Choose which category's tx frames to drop next based on two factors:
+	 * 1.  Which category has the most tx frames present
+	 * 2.  The category's priority (high-priority categories have a low
+	 *     discard_weight)
+	 */
+	for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; i++) {
+		int score;
+
+		score =
+			scheduler->categories[i].state.frms *
+			scheduler->categories[i].specs.discard_weight;
+		if (max_score == 0 || score > max_score) {
+			max_score = score;
+			cat = i;
+		}
+	}
+	return cat;
+}
+
+static void
+ol_tx_sched_txq_discard_wrr_adv(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_frms_queue_t *txq,
+	int cat, int frames, int bytes)
+{
+	struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_sched_wrr_adv_category_info_t *category;
+
+	category = &scheduler->categories[cat];
+
+	if (0 == txq->frms)
+		TAILQ_REMOVE(&category->state.head, txq, list_elem);
+
+
+	category->state.frms -= frames;
+	category->state.bytes -= bytes;
+	OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_DISCARD(category, frames);
+	if (category->state.frms == 0)
+		category->state.active = 0;
+}
+
+static void
+ol_tx_sched_category_info_wrr_adv(
+	struct ol_txrx_pdev_t *pdev,
+	int cat, int *active,
+	int *frms, int *bytes)
+{
+	struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler;
+	struct ol_tx_sched_wrr_adv_category_info_t *category;
+
+	category = &scheduler->categories[cat];
+	*active = category->state.active;
+	*frms = category->state.frms;
+	*bytes = category->state.bytes;
+}
+
+/**
+ * ol_tx_sched_wrr_param_update() - update the WRR TX sched params
+ * @pdev: Pointer to PDEV structure.
+ * @scheduler: Pointer to tx scheduler.
+ *
+ * Update the WRR TX schedule parameters for each category if it is
+ * specified in the ini file by user.
+ *
+ * Return: none
+ */
+static void ol_tx_sched_wrr_param_update(struct ol_txrx_pdev_t *pdev,
+					 struct ol_tx_sched_wrr_adv_t *
+					 scheduler)
+{
+	int i;
+	static const char * const tx_sched_wrr_name[4] = {
+		"BE",
+		"BK",
+		"VI",
+		"VO"
+	};
+
+	if (NULL == scheduler)
+		return;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		"%s: Tuning the TX scheduler wrr parameters by ini file:",
+		__func__);
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		"         skip credit limit credit disc");
+
+	for (i = OL_TX_SCHED_WRR_ADV_CAT_BE;
+		i <= OL_TX_SCHED_WRR_ADV_CAT_VO; i++) {
+		if (ol_cfg_get_wrr_skip_weight(pdev->ctrl_pdev, i)) {
+			scheduler->categories[i].specs.wrr_skip_weight =
+				ol_cfg_get_wrr_skip_weight(pdev->ctrl_pdev, i);
+			scheduler->categories[i].specs.credit_threshold =
+				ol_cfg_get_credit_threshold(pdev->ctrl_pdev, i);
+			scheduler->categories[i].specs.send_limit =
+				ol_cfg_get_send_limit(pdev->ctrl_pdev, i);
+			scheduler->categories[i].specs.credit_reserve =
+				ol_cfg_get_credit_reserve(pdev->ctrl_pdev, i);
+			scheduler->categories[i].specs.discard_weight =
+				ol_cfg_get_discard_weight(pdev->ctrl_pdev, i);
+
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+				"%s-update: %d,  %d,    %d,   %d,    %d",
+				tx_sched_wrr_name[i],
+				scheduler->categories[i].specs.wrr_skip_weight,
+				scheduler->categories[i].specs.credit_threshold,
+				scheduler->categories[i].specs.send_limit,
+				scheduler->categories[i].specs.credit_reserve,
+				scheduler->categories[i].specs.discard_weight);
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+				"%s-orig: %d,  %d,    %d,   %d,    %d",
+				tx_sched_wrr_name[i],
+				scheduler->categories[i].specs.wrr_skip_weight,
+				scheduler->categories[i].specs.credit_threshold,
+				scheduler->categories[i].specs.send_limit,
+				scheduler->categories[i].specs.credit_reserve,
+				scheduler->categories[i].specs.discard_weight);
+		}
+	}
+}
+
+static void *
+ol_tx_sched_init_wrr_adv(
+		struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_tx_sched_wrr_adv_t *scheduler;
+	int i;
+
+	scheduler = qdf_mem_malloc(
+			sizeof(struct ol_tx_sched_wrr_adv_t));
+	if (scheduler == NULL)
+		return scheduler;
+
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(VO, scheduler);
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(VI, scheduler);
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(BE, scheduler);
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(BK, scheduler);
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(NON_QOS_DATA, scheduler);
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(UCAST_MGMT, scheduler);
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(MCAST_DATA, scheduler);
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(MCAST_MGMT, scheduler);
+
+	ol_tx_sched_wrr_param_update(pdev, scheduler);
+
+	for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; i++) {
+		scheduler->categories[i].state.active = 0;
+		scheduler->categories[i].state.frms = 0;
+		/*scheduler->categories[i].state.bytes = 0;*/
+		TAILQ_INIT(&scheduler->categories[i].state.head);
+		/*
+		 * init categories to not be skipped before
+		 * their initial selection
+		 */
+		scheduler->categories[i].state.wrr_count =
+			scheduler->categories[i].specs.wrr_skip_weight - 1;
+	}
+
+	/*
+	 * Init the order array - the initial ordering doesn't matter, as the
+	 * order array will get reshuffled as data arrives.
+	 */
+	for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; i++)
+		scheduler->order[i] = i;
+
+	return scheduler;
+}
+
+
+/* WMM parameters are suppposed to be passed when associate with AP.
+ * According to AIFS+CWMin, the function maps each queue to one of four default
+ * settings of the scheduler, ie. VO, VI, BE, or BK.
+ */
+void
+ol_txrx_set_wmm_param(struct cdp_pdev *pdev,
+		      struct ol_tx_wmm_param_t wmm_param)
+{
+	struct ol_txrx_pdev_t *data_pdev = (struct ol_txrx_pdev_t *)pdev;
+	struct ol_tx_sched_wrr_adv_t def_cfg;
+	struct ol_tx_sched_wrr_adv_t *scheduler =
+					data_pdev->tx_sched.scheduler;
+	u_int32_t i, ac_selected;
+	u_int32_t  weight[OL_TX_NUM_WMM_AC], default_edca[OL_TX_NUM_WMM_AC];
+
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(VO, (&def_cfg));
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(VI, (&def_cfg));
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(BE, (&def_cfg));
+	OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(BK, (&def_cfg));
+
+	/* default_eca = AIFS + CWMin */
+	default_edca[OL_TX_SCHED_WRR_ADV_CAT_VO] =
+		OL_TX_AIFS_DEFAULT_VO + OL_TX_CW_MIN_DEFAULT_VO;
+	default_edca[OL_TX_SCHED_WRR_ADV_CAT_VI] =
+		OL_TX_AIFS_DEFAULT_VI + OL_TX_CW_MIN_DEFAULT_VI;
+	default_edca[OL_TX_SCHED_WRR_ADV_CAT_BE] =
+		OL_TX_AIFS_DEFAULT_BE + OL_TX_CW_MIN_DEFAULT_BE;
+	default_edca[OL_TX_SCHED_WRR_ADV_CAT_BK] =
+		OL_TX_AIFS_DEFAULT_BK + OL_TX_CW_MIN_DEFAULT_BK;
+
+	weight[OL_TX_SCHED_WRR_ADV_CAT_VO] =
+		wmm_param.ac[OL_TX_WMM_AC_VO].aifs +
+				wmm_param.ac[OL_TX_WMM_AC_VO].cwmin;
+	weight[OL_TX_SCHED_WRR_ADV_CAT_VI] =
+		wmm_param.ac[OL_TX_WMM_AC_VI].aifs +
+				wmm_param.ac[OL_TX_WMM_AC_VI].cwmin;
+	weight[OL_TX_SCHED_WRR_ADV_CAT_BK] =
+		wmm_param.ac[OL_TX_WMM_AC_BK].aifs +
+				wmm_param.ac[OL_TX_WMM_AC_BK].cwmin;
+	weight[OL_TX_SCHED_WRR_ADV_CAT_BE] =
+		wmm_param.ac[OL_TX_WMM_AC_BE].aifs +
+				wmm_param.ac[OL_TX_WMM_AC_BE].cwmin;
+
+	for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
+		if (default_edca[OL_TX_SCHED_WRR_ADV_CAT_VO] >= weight[i])
+			ac_selected = OL_TX_SCHED_WRR_ADV_CAT_VO;
+		else if (default_edca[OL_TX_SCHED_WRR_ADV_CAT_VI] >= weight[i])
+			ac_selected = OL_TX_SCHED_WRR_ADV_CAT_VI;
+		else if (default_edca[OL_TX_SCHED_WRR_ADV_CAT_BE] >= weight[i])
+			ac_selected = OL_TX_SCHED_WRR_ADV_CAT_BE;
+		else
+			ac_selected = OL_TX_SCHED_WRR_ADV_CAT_BK;
+
+
+		scheduler->categories[i].specs.wrr_skip_weight =
+			def_cfg.categories[ac_selected].specs.wrr_skip_weight;
+		scheduler->categories[i].specs.credit_threshold =
+			def_cfg.categories[ac_selected].specs.credit_threshold;
+		scheduler->categories[i].specs.send_limit =
+			def_cfg.categories[ac_selected].specs.send_limit;
+		scheduler->categories[i].specs.credit_reserve =
+			def_cfg.categories[ac_selected].specs.credit_reserve;
+		scheduler->categories[i].specs.discard_weight =
+			def_cfg.categories[ac_selected].specs.discard_weight;
+	}
+}
+
+/**
+ * ol_tx_sched_stats_display() - tx sched stats display
+ * @pdev: Pointer to the PDEV structure.
+ *
+ * Return: none.
+ */
+void ol_tx_sched_stats_display(struct ol_txrx_pdev_t *pdev)
+{
+	OL_TX_SCHED_WRR_ADV_CAT_STAT_DUMP(pdev->tx_sched.scheduler);
+}
+
+/**
+ * ol_tx_sched_cur_state_display() - tx sched cur stat display
+ * @pdev: Pointer to the PDEV structure.
+ *
+ * Return: none.
+ */
+void ol_tx_sched_cur_state_display(struct ol_txrx_pdev_t *pdev)
+{
+	OL_TX_SCHED_WRR_ADV_CAT_CUR_STATE_DUMP(pdev->tx_sched.scheduler);
+}
+
+/**
+ * ol_tx_sched_cur_state_display() - reset tx sched stats
+ * @pdev: Pointer to the PDEV structure.
+ *
+ * Return: none.
+ */
+void ol_tx_sched_stats_clear(struct ol_txrx_pdev_t *pdev)
+{
+	OL_TX_SCHED_WRR_ADV_CAT_STAT_CLEAR(pdev->tx_sched.scheduler);
+}
+
+#endif /* OL_TX_SCHED == OL_TX_SCHED_WRR_ADV */
+
+/*--- congestion control discard --------------------------------------------*/
+
+static struct ol_tx_frms_queue_t *
+ol_tx_sched_discard_select_txq(
+		struct ol_txrx_pdev_t *pdev,
+		ol_tx_frms_queue_list *tx_queues)
+{
+	struct ol_tx_frms_queue_t *txq;
+	struct ol_tx_frms_queue_t *selected_txq = NULL;
+	int max_frms = 0;
+
+	/* return the tx queue with the most frames */
+	TAILQ_FOREACH(txq, tx_queues, list_elem) {
+		if (txq->frms > max_frms) {
+			max_frms = txq->frms;
+			selected_txq = txq;
+		}
+	}
+	return selected_txq;
+}
+
+u_int16_t
+ol_tx_sched_discard_select(
+		struct ol_txrx_pdev_t *pdev,
+		u_int16_t frms,
+		ol_tx_desc_list *tx_descs,
+		bool force)
+{
+	int cat;
+	struct ol_tx_frms_queue_t *txq;
+	int bytes;
+	u_int32_t credit;
+	struct ol_tx_sched_notify_ctx_t notify_ctx;
+
+	/*
+	 * first decide what category of traffic (e.g. TID or AC)
+	 * to discard next
+	 */
+	cat = ol_tx_sched_discard_select_category(pdev);
+
+	/* then decide which peer within this category to discard from next */
+	txq = ol_tx_sched_discard_select_txq(
+			pdev, ol_tx_sched_category_tx_queues(pdev, cat));
+	if (NULL == txq)
+		/* No More pending Tx Packets in Tx Queue. Exit Discard loop */
+		return 0;
+
+
+	if (force == false) {
+		/*
+		 * Now decide how many frames to discard from this peer-TID.
+		 * Don't discard more frames than the caller has specified.
+		 * Don't discard more than a fixed quantum of frames at a time.
+		 * Don't discard more than 50% of the queue's frames at a time,
+		 * but if there's only 1 frame left, go ahead and discard it.
+		 */
+#define OL_TX_DISCARD_QUANTUM 10
+		if (OL_TX_DISCARD_QUANTUM < frms)
+			frms = OL_TX_DISCARD_QUANTUM;
+
+
+		if (txq->frms > 1 && frms >= (txq->frms >> 1))
+			frms = txq->frms >> 1;
+	}
+
+	/*
+	 * Discard from the head of the queue, because:
+	 * 1.  Front-dropping gives applications like TCP that include ARQ
+	 *     an early notification of congestion.
+	 * 2.  For time-sensitive applications like RTP, the newest frames are
+	 *     most relevant.
+	 */
+	credit = 10000; /* no credit limit */
+	frms = ol_tx_dequeue(pdev, txq, tx_descs, frms, &credit, &bytes);
+
+	notify_ctx.event = OL_TX_DISCARD_FRAMES;
+	notify_ctx.frames = frms;
+	notify_ctx.bytes = bytes;
+	notify_ctx.txq = txq;
+	notify_ctx.info.ext_tid = cat;
+	ol_tx_sched_notify(pdev, &notify_ctx);
+
+	TX_SCHED_DEBUG_PRINT("%s Tx Drop : %d\n", __func__, frms);
+	return frms;
+}
+
+/*--- scheduler framework ---------------------------------------------------*/
+
+/*
+ * The scheduler mutex spinlock has been acquired outside this function,
+ * so there is need to take locks inside this function.
+ */
+void
+ol_tx_sched_notify(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_sched_notify_ctx_t *ctx)
+{
+	struct ol_tx_frms_queue_t *txq = ctx->txq;
+	int tid;
+
+	if (!pdev->tx_sched.scheduler)
+		return;
+
+	switch (ctx->event) {
+	case OL_TX_ENQUEUE_FRAME:
+		tid = ctx->info.tx_msdu_info->htt.info.ext_tid;
+		ol_tx_sched_txq_enqueue(pdev, txq, tid, 1, ctx->bytes);
+		break;
+	case OL_TX_DELETE_QUEUE:
+		tid = ctx->info.ext_tid;
+		if (txq->flag == ol_tx_queue_active)
+			ol_tx_sched_txq_deactivate(pdev, txq, tid);
+
+		break;
+	case OL_TX_PAUSE_QUEUE:
+		tid = ctx->info.ext_tid;
+		if (txq->flag == ol_tx_queue_active)
+			ol_tx_sched_txq_deactivate(pdev, txq, tid);
+
+		break;
+	case OL_TX_UNPAUSE_QUEUE:
+		tid = ctx->info.ext_tid;
+		if (txq->frms != 0)
+			ol_tx_sched_txq_enqueue(pdev, txq, tid,
+						txq->frms, txq->bytes);
+
+		break;
+	case OL_TX_DISCARD_FRAMES:
+		/* not necessarily TID, could be category */
+		tid = ctx->info.ext_tid;
+		ol_tx_sched_txq_discard(pdev, txq, tid,
+					ctx->frames, ctx->bytes);
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Error: unknown sched notification (%d)\n",
+			  ctx->event);
+		qdf_assert(0);
+		break;
+	}
+}
+
+#define OL_TX_MSDU_ID_STORAGE_ERR(ptr) (NULL == ptr)
+
+static void
+ol_tx_sched_dispatch(
+	struct ol_txrx_pdev_t *pdev,
+	struct ol_tx_sched_ctx *sctx)
+{
+	qdf_nbuf_t msdu, prev = NULL, head_msdu = NULL;
+	struct ol_tx_desc_t *tx_desc;
+	u_int16_t *msdu_id_storage;
+	u_int16_t msdu_id;
+	int num_msdus = 0;
+
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+	while (sctx->frms) {
+		tx_desc = TAILQ_FIRST(&sctx->head);
+		if (tx_desc == NULL) {
+			/* TODO: find its reason */
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				  "%s: err, no enough tx_desc from stx->head.\n",
+				  __func__);
+			break;
+		}
+		msdu = tx_desc->netbuf;
+		TAILQ_REMOVE(&sctx->head, tx_desc, tx_desc_list_elem);
+		if (NULL == head_msdu)
+			head_msdu = msdu;
+
+		if (prev)
+			qdf_nbuf_set_next(prev, msdu);
+
+		prev = msdu;
+
+#ifndef ATH_11AC_TXCOMPACT
+		/*
+		 * When the tx frame is downloaded to the target, there are two
+		 * outstanding references:
+		 * 1.  The host download SW (HTT, HTC, HIF)
+		 *     This reference is cleared by the ol_tx_send_done callback
+		 *     functions.
+		 * 2.  The target FW
+		 *     This reference is cleared by the ol_tx_completion_handler
+		 *     function.
+		 * It is extremely probable that the download completion is
+		 * processed before the tx completion message.  However, under
+		 * exceptional conditions the tx completion may be processed
+		 *first. Thus, rather that assuming that reference (1) is
+		 *done before reference (2),
+		 * explicit reference tracking is needed.
+		 * Double-increment the ref count to account for both references
+		 * described above.
+		 */
+		qdf_atomic_init(&tx_desc->ref_cnt);
+		qdf_atomic_inc(&tx_desc->ref_cnt);
+		qdf_atomic_inc(&tx_desc->ref_cnt);
+#endif
+
+		/*Store the MSDU Id for each MSDU*/
+		/* store MSDU ID */
+		msdu_id = ol_tx_desc_id(pdev, tx_desc);
+		msdu_id_storage = ol_tx_msdu_id_storage(msdu);
+		if (OL_TX_MSDU_ID_STORAGE_ERR(msdu_id_storage)) {
+			/*
+			 * Send the prior frames as a batch,
+			 *then send this as a single,
+			 * then resume handling the remaining frames.
+			 */
+			if (head_msdu)
+				ol_tx_send_batch(pdev, head_msdu, num_msdus);
+
+			prev = NULL;
+			head_msdu = prev;
+			num_msdus = 0;
+
+			if (htt_tx_send_std(pdev->htt_pdev, msdu, msdu_id)) {
+				ol_tx_target_credit_incr(pdev, msdu);
+				ol_tx_desc_frame_free_nonstd(pdev, tx_desc,
+							     1 /* error */);
+			}
+		} else {
+			*msdu_id_storage = msdu_id;
+			num_msdus++;
+		}
+		sctx->frms--;
+	}
+
+	/*Send Batch Of Frames*/
+	if (head_msdu)
+		ol_tx_send_batch(pdev, head_msdu, num_msdus);
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+}
+
+	void
+ol_tx_sched(struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_tx_sched_ctx sctx;
+	u_int32_t credit;
+
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+	if (pdev->tx_sched.tx_sched_status != ol_tx_scheduler_idle) {
+		qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+		return;
+	}
+	pdev->tx_sched.tx_sched_status = ol_tx_scheduler_running;
+
+	ol_tx_sched_log(pdev);
+	/*
+	 *adf_os_print("BEFORE tx sched:\n");
+	 *ol_tx_queues_display(pdev);
+	 */
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+
+	TAILQ_INIT(&sctx.head);
+	sctx.frms = 0;
+
+	ol_tx_sched_select_init(pdev);
+	while (qdf_atomic_read(&pdev->target_tx_credit) > 0) {
+		int num_credits;
+
+		qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+		credit = qdf_atomic_read(&pdev->target_tx_credit);
+		num_credits = ol_tx_sched_select_batch(pdev, &sctx, credit);
+		if (num_credits > 0) {
+#if DEBUG_HTT_CREDIT
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+				  " <HTT> Decrease credit %d - %d = %d.\n",
+				  qdf_atomic_read(&pdev->target_tx_credit),
+				  num_credits,
+				  qdf_atomic_read(&pdev->target_tx_credit) -
+				  num_credits);
+#endif
+			qdf_atomic_add(-num_credits, &pdev->target_tx_credit);
+		}
+		qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+
+		if (num_credits == 0)
+			break;
+	}
+	ol_tx_sched_dispatch(pdev, &sctx);
+
+	qdf_spin_lock_bh(&pdev->tx_queue_spinlock);
+	/*
+	 *adf_os_print("AFTER tx sched:\n");
+	 *ol_tx_queues_display(pdev);
+	 */
+
+	pdev->tx_sched.tx_sched_status = ol_tx_scheduler_idle;
+	qdf_spin_unlock_bh(&pdev->tx_queue_spinlock);
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+}
+
+void *
+ol_tx_sched_attach(
+	struct ol_txrx_pdev_t *pdev)
+{
+	pdev->tx_sched.tx_sched_status = ol_tx_scheduler_idle;
+	return ol_tx_sched_init(pdev);
+}
+
+void
+ol_tx_sched_detach(
+	struct ol_txrx_pdev_t *pdev)
+{
+	if (pdev->tx_sched.scheduler) {
+		qdf_mem_free(pdev->tx_sched.scheduler);
+		pdev->tx_sched.scheduler = NULL;
+	}
+}
+
+/*--- debug functions -------------------------------------------------------*/
+
+#if defined(DEBUG_HL_LOGGING)
+
+static void
+ol_tx_sched_log(struct ol_txrx_pdev_t *pdev)
+{
+	u_int8_t  *buf;
+	u_int32_t *active_bitmap;
+	int i, j, num_cats_active;
+	int active, frms, bytes;
+	int credit;
+
+	/* don't bother recording state if credit is zero */
+	credit = qdf_atomic_read(&pdev->target_tx_credit);
+	if (credit == 0)
+		return;
+
+
+	/*
+	 * See how many TIDs are active, so queue state can be stored only
+	 * for those TIDs.
+	 * Do an initial iteration through all categories to see if any
+	 * are active.  Doing an extra iteration is inefficient, but
+	 * efficiency is not a dominant concern when logging is enabled.
+	 */
+	num_cats_active = 0;
+	for (i = 0; i < OL_TX_SCHED_NUM_CATEGORIES; i++) {
+		ol_tx_sched_category_info(pdev, i, &active, &frms, &bytes);
+		if (active)
+			num_cats_active++;
+	}
+	/* don't bother recording state if there are no active queues */
+	if (num_cats_active == 0)
+		return;
+
+
+	ol_tx_queue_log_sched(pdev, credit, &num_cats_active,
+			      &active_bitmap, &buf);
+
+	if (num_cats_active == 0)
+		return;
+
+	*active_bitmap = 0;
+	for (i = 0, j = 0;
+			i < OL_TX_SCHED_NUM_CATEGORIES && j < num_cats_active;
+			i++) {
+		u_int8_t *p;
+
+		ol_tx_sched_category_info(pdev, i, &active, &frms, &bytes);
+		if (!active)
+			continue;
+
+		p = &buf[j*6];
+		p[0]   = (frms >> 0) & 0xff;
+		p[1] = (frms >> 8) & 0xff;
+
+		p[2] = (bytes >> 0) & 0xff;
+		p[3] = (bytes >> 8) & 0xff;
+		p[4] = (bytes >> 16) & 0xff;
+		p[5] = (bytes >> 24) & 0xff;
+		j++;
+		*active_bitmap |= 1 << i;
+	}
+}
+
+#endif /* defined(DEBUG_HL_LOGGING) */
+
+#endif /* defined(CONFIG_HL_SUPPORT) */
diff --git a/core/dp/txrx/ol_tx_sched.h b/core/dp/txrx/ol_tx_sched.h
new file mode 100644
index 0000000..75b554e
--- /dev/null
+++ b/core/dp/txrx/ol_tx_sched.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2012-2013, 2016-2018 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.
+ */
+
+/**
+ * @file ol_tx_sched.h
+ * @brief API definitions for the tx scheduler module within the data SW.
+ */
+#ifndef _OL_TX_SCHED__H_
+#define _OL_TX_SCHED__H_
+
+#include <qdf_types.h>
+
+enum ol_tx_queue_action {
+	OL_TX_ENQUEUE_FRAME,
+	OL_TX_DELETE_QUEUE,
+	OL_TX_PAUSE_QUEUE,
+	OL_TX_UNPAUSE_QUEUE,
+	OL_TX_DISCARD_FRAMES,
+};
+
+struct ol_tx_sched_notify_ctx_t {
+	int event;
+	struct ol_tx_frms_queue_t *txq;
+	union {
+		int ext_tid;
+		struct ol_txrx_msdu_info_t *tx_msdu_info;
+	} info;
+	int frames;
+	int bytes;
+};
+
+#if defined(CONFIG_HL_SUPPORT)
+
+void
+ol_tx_sched_notify(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_sched_notify_ctx_t *ctx);
+
+void
+ol_tx_sched(struct ol_txrx_pdev_t *pdev);
+
+u_int16_t
+ol_tx_sched_discard_select(
+		struct ol_txrx_pdev_t *pdev,
+		u_int16_t frms,
+		ol_tx_desc_list *tx_descs,
+		bool force);
+
+void *
+ol_tx_sched_attach(struct ol_txrx_pdev_t *pdev);
+
+void
+ol_tx_sched_detach(struct ol_txrx_pdev_t *pdev);
+
+void ol_tx_sched_stats_display(struct ol_txrx_pdev_t *pdev);
+
+void ol_tx_sched_cur_state_display(struct ol_txrx_pdev_t *pdev);
+
+void ol_tx_sched_stats_clear(struct ol_txrx_pdev_t *pdev);
+
+void
+ol_txrx_set_wmm_param(struct cdp_pdev *data_pdev,
+		      struct ol_tx_wmm_param_t wmm_param);
+
+#else
+
+static inline void
+ol_tx_sched_notify(
+		struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_sched_notify_ctx_t *ctx)
+{
+}
+
+static inline void
+ol_tx_sched(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+static inline u_int16_t
+ol_tx_sched_discard_select(
+		struct ol_txrx_pdev_t *pdev,
+		u_int16_t frms,
+		ol_tx_desc_list *tx_descs,
+		bool force)
+{
+	return 0;
+}
+
+static inline void *
+ol_tx_sched_attach(struct ol_txrx_pdev_t *pdev)
+{
+	return NULL;
+}
+
+static inline void
+ol_tx_sched_detach(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+static inline void ol_tx_sched_stats_display(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+static inline void ol_tx_sched_cur_state_display(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+static inline void ol_tx_sched_stats_clear(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+#endif /* defined(CONFIG_HL_SUPPORT) */
+
+#if defined(CONFIG_HL_SUPPORT) || defined(TX_CREDIT_RECLAIM_SUPPORT)
+/*
+ * HL needs to keep track of the amount of credit available to download
+ * tx frames to the target - the download scheduler decides when to
+ * download frames, and which frames to download, based on the credit
+ * availability.
+ * LL systems that use TX_CREDIT_RECLAIM_SUPPORT also need to keep track
+ * of the target_tx_credit, to determine when to poll for tx completion
+ * messages.
+ */
+
+static inline void
+ol_tx_target_credit_adjust(int factor,
+			   struct ol_txrx_pdev_t *pdev,
+			   qdf_nbuf_t msdu)
+{
+	qdf_atomic_add(factor * htt_tx_msdu_credit(msdu),
+		       &pdev->target_tx_credit);
+}
+
+static inline void ol_tx_target_credit_decr(struct ol_txrx_pdev_t *pdev,
+					    qdf_nbuf_t msdu)
+{
+	ol_tx_target_credit_adjust(-1, pdev, msdu);
+}
+
+static inline void ol_tx_target_credit_incr(struct ol_txrx_pdev_t *pdev,
+					    qdf_nbuf_t msdu)
+{
+	ol_tx_target_credit_adjust(1, pdev, msdu);
+}
+#else
+/*
+ * LL does not need to keep track of target credit.
+ * Since the host tx descriptor pool size matches the target's,
+ * we know the target has space for the new tx frame if the host's
+ * tx descriptor allocation succeeded.
+ */
+static inline void
+ol_tx_target_credit_adjust(int factor,
+			   struct ol_txrx_pdev_t *pdev,
+			   qdf_nbuf_t msdu)
+{
+}
+
+static inline void ol_tx_target_credit_decr(struct ol_txrx_pdev_t *pdev,
+					    qdf_nbuf_t msdu)
+{
+}
+
+static inline void ol_tx_target_credit_incr(struct ol_txrx_pdev_t *pdev,
+					    qdf_nbuf_t msdu)
+{
+}
+#endif
+#endif /* _OL_TX_SCHED__H_ */
diff --git a/core/dp/txrx/ol_tx_send.c b/core/dp/txrx/ol_tx_send.c
new file mode 100644
index 0000000..a8893a7
--- /dev/null
+++ b/core/dp/txrx/ol_tx_send.c
@@ -0,0 +1,1567 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#include <qdf_atomic.h>         /* qdf_atomic_inc, etc. */
+#include <qdf_lock.h>           /* qdf_os_spinlock */
+#include <qdf_time.h>           /* qdf_system_ticks, etc. */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <qdf_net_types.h>      /* QDF_NBUF_TX_EXT_TID_INVALID */
+
+#include <cds_queue.h>          /* TAILQ */
+#ifdef QCA_COMPUTE_TX_DELAY
+#include <enet.h>               /* ethernet_hdr_t, etc. */
+#include <ipv6_defs.h>          /* ipv6_traffic_class */
+#endif
+
+#include <ol_txrx_api.h>        /* ol_txrx_vdev_handle, etc. */
+#include <ol_htt_tx_api.h>      /* htt_tx_compl_desc_id */
+#include <ol_txrx_htt_api.h>    /* htt_tx_status */
+
+#include <ol_ctrl_txrx_api.h>
+#include <cdp_txrx_tx_delay.h>
+#include <ol_txrx_types.h>      /* ol_txrx_vdev_t, etc */
+#include <ol_tx_desc.h>         /* ol_tx_desc_find, ol_tx_desc_frame_free */
+#ifdef QCA_COMPUTE_TX_DELAY
+#include <ol_tx_classify.h>     /* ol_tx_dest_addr_find */
+#endif
+#include <ol_txrx_internal.h>   /* OL_TX_DESC_NO_REFS, etc. */
+#include <ol_osif_txrx_api.h>
+#include <ol_tx.h>              /* ol_tx_reinject */
+#include <ol_tx_send.h>
+
+#include <ol_cfg.h>             /* ol_cfg_is_high_latency */
+#include <ol_tx_sched.h>
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+#include <ol_txrx_encap.h>      /* OL_TX_RESTORE_HDR, etc */
+#endif
+#include <ol_tx_queue.h>
+#include <ol_txrx.h>
+#include <pktlog_ac_fmt.h>
+#include <cdp_txrx_handle.h>
+
+#ifdef TX_CREDIT_RECLAIM_SUPPORT
+
+#define OL_TX_CREDIT_RECLAIM(pdev)					\
+	do {								\
+		if (qdf_atomic_read(&pdev->target_tx_credit)  <		\
+		    ol_cfg_tx_credit_lwm(pdev->ctrl_pdev)) {		\
+			ol_osif_ath_tasklet(pdev->osdev);		\
+		}							\
+	} while (0)
+
+#else
+
+#define OL_TX_CREDIT_RECLAIM(pdev)
+
+#endif /* TX_CREDIT_RECLAIM_SUPPORT */
+
+#if defined(CONFIG_HL_SUPPORT) || defined(TX_CREDIT_RECLAIM_SUPPORT)
+
+/*
+ * HL needs to keep track of the amount of credit available to download
+ * tx frames to the target - the download scheduler decides when to
+ * download frames, and which frames to download, based on the credit
+ * availability.
+ * LL systems that use TX_CREDIT_RECLAIM_SUPPORT also need to keep track
+ * of the target_tx_credit, to determine when to poll for tx completion
+ * messages.
+ */
+static inline void
+ol_tx_target_credit_decr_int(struct ol_txrx_pdev_t *pdev, int delta)
+{
+	qdf_atomic_add(-1 * delta, &pdev->target_tx_credit);
+}
+
+static inline void
+ol_tx_target_credit_incr_int(struct ol_txrx_pdev_t *pdev, int delta)
+{
+	qdf_atomic_add(delta, &pdev->target_tx_credit);
+}
+#else
+
+static inline void
+ol_tx_target_credit_decr_int(struct ol_txrx_pdev_t *pdev, int delta)
+{
+}
+
+static inline void
+ol_tx_target_credit_incr_int(struct ol_txrx_pdev_t *pdev, int delta)
+{
+}
+#endif
+
+#ifdef DESC_TIMESTAMP_DEBUG_INFO
+static inline void ol_tx_desc_update_comp_ts(struct ol_tx_desc_t *tx_desc)
+{
+	tx_desc->desc_debug_info.last_comp_ts = qdf_get_log_timestamp();
+}
+#else
+static inline void ol_tx_desc_update_comp_ts(struct ol_tx_desc_t *tx_desc)
+{
+}
+#endif
+
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_HL_NETDEV_FLOW_CONTROL)
+void ol_tx_flow_ct_unpause_os_q(ol_txrx_pdev_handle pdev)
+{
+	struct ol_txrx_vdev_t *vdev;
+
+	qdf_spin_lock_bh(&pdev->tx_mutex);
+	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+		if (vdev->tx_desc_limit == 0)
+			continue;
+
+		/* un-pause high priority queue */
+		if (vdev->prio_q_paused &&
+		    (qdf_atomic_read(&vdev->tx_desc_count)
+		     < vdev->tx_desc_limit)) {
+			pdev->pause_cb(vdev->vdev_id,
+				       WLAN_NETIF_PRIORITY_QUEUE_ON,
+				       WLAN_DATA_FLOW_CONTROL_PRIORITY);
+			vdev->prio_q_paused = 0;
+		}
+		/* un-pause non priority queues */
+		if (qdf_atomic_read(&vdev->os_q_paused) &&
+		    (qdf_atomic_read(&vdev->tx_desc_count)
+		    <= vdev->queue_restart_th)) {
+			pdev->pause_cb(vdev->vdev_id,
+				       WLAN_WAKE_NON_PRIORITY_QUEUE,
+				       WLAN_DATA_FLOW_CONTROL);
+			qdf_atomic_set(&vdev->os_q_paused, 0);
+		}
+	}
+	qdf_spin_unlock_bh(&pdev->tx_mutex);
+}
+#endif
+
+static inline uint16_t
+ol_tx_send_base(struct ol_txrx_pdev_t *pdev,
+		struct ol_tx_desc_t *tx_desc, qdf_nbuf_t msdu)
+{
+	int msdu_credit_consumed;
+
+	TX_CREDIT_DEBUG_PRINT("TX %d bytes\n", qdf_nbuf_len(msdu));
+	TX_CREDIT_DEBUG_PRINT(" <HTT> Decrease credit %d - 1 = %d, len:%d.\n",
+			      qdf_atomic_read(&pdev->target_tx_credit),
+			      qdf_atomic_read(&pdev->target_tx_credit) - 1,
+			      qdf_nbuf_len(msdu));
+
+	msdu_credit_consumed = htt_tx_msdu_credit(msdu);
+	ol_tx_target_credit_decr_int(pdev, msdu_credit_consumed);
+	OL_TX_CREDIT_RECLAIM(pdev);
+
+	/*
+	 * When the tx frame is downloaded to the target, there are two
+	 * outstanding references:
+	 * 1.  The host download SW (HTT, HTC, HIF)
+	 *     This reference is cleared by the ol_tx_send_done callback
+	 *     functions.
+	 * 2.  The target FW
+	 *     This reference is cleared by the ol_tx_completion_handler
+	 *     function.
+	 * It is extremely probable that the download completion is processed
+	 * before the tx completion message.  However, under exceptional
+	 * conditions the tx completion may be processed first.  Thus, rather
+	 * that assuming that reference (1) is done before reference (2),
+	 * explicit reference tracking is needed.
+	 * Double-increment the ref count to account for both references
+	 * described above.
+	 */
+
+	OL_TX_DESC_REF_INIT(tx_desc);
+	OL_TX_DESC_REF_INC(tx_desc);
+	OL_TX_DESC_REF_INC(tx_desc);
+
+	return msdu_credit_consumed;
+}
+
+void
+ol_tx_send(struct ol_txrx_pdev_t *pdev,
+	   struct ol_tx_desc_t *tx_desc, qdf_nbuf_t msdu, uint8_t vdev_id)
+{
+	int msdu_credit_consumed;
+	uint16_t id;
+	int failed;
+
+	msdu_credit_consumed = ol_tx_send_base(pdev, tx_desc, msdu);
+	id = ol_tx_desc_id(pdev, tx_desc);
+	QDF_NBUF_UPDATE_TX_PKT_COUNT(msdu, QDF_NBUF_TX_PKT_TXRX);
+	DPTRACE(qdf_dp_trace_ptr(msdu, QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD,
+				QDF_TRACE_DEFAULT_PDEV_ID,
+				qdf_nbuf_data_addr(msdu),
+				sizeof(qdf_nbuf_data(msdu)), tx_desc->id,
+				vdev_id));
+	failed = htt_tx_send_std(pdev->htt_pdev, msdu, id);
+	if (qdf_unlikely(failed)) {
+		ol_tx_target_credit_incr_int(pdev, msdu_credit_consumed);
+		ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1 /* had error */);
+	}
+}
+
+void
+ol_tx_send_batch(struct ol_txrx_pdev_t *pdev,
+		 qdf_nbuf_t head_msdu, int num_msdus)
+{
+	qdf_nbuf_t rejected;
+
+	OL_TX_CREDIT_RECLAIM(pdev);
+
+	rejected = htt_tx_send_batch(pdev->htt_pdev, head_msdu, num_msdus);
+	while (qdf_unlikely(rejected)) {
+		struct ol_tx_desc_t *tx_desc;
+		uint16_t *msdu_id_storage;
+		qdf_nbuf_t next;
+
+		next = qdf_nbuf_next(rejected);
+		msdu_id_storage = ol_tx_msdu_id_storage(rejected);
+		tx_desc = ol_tx_desc_find(pdev, *msdu_id_storage);
+
+		ol_tx_target_credit_incr(pdev, rejected);
+		ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1 /* had error */);
+
+		rejected = next;
+	}
+}
+
+void
+ol_tx_send_nonstd(struct ol_txrx_pdev_t *pdev,
+		  struct ol_tx_desc_t *tx_desc,
+		  qdf_nbuf_t msdu, enum htt_pkt_type pkt_type)
+{
+	int msdu_credit_consumed;
+	uint16_t id;
+	int failed;
+
+	msdu_credit_consumed = ol_tx_send_base(pdev, tx_desc, msdu);
+	id = ol_tx_desc_id(pdev, tx_desc);
+	QDF_NBUF_UPDATE_TX_PKT_COUNT(msdu, QDF_NBUF_TX_PKT_TXRX);
+	failed = htt_tx_send_nonstd(pdev->htt_pdev, msdu, id, pkt_type);
+	if (failed) {
+		ol_txrx_err(
+			   "Error: freeing tx frame after htt_tx failed");
+		ol_tx_target_credit_incr_int(pdev, msdu_credit_consumed);
+		ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1 /* had error */);
+	}
+}
+
+static inline void
+ol_tx_download_done_base(struct ol_txrx_pdev_t *pdev,
+			 A_STATUS status, qdf_nbuf_t msdu, uint16_t msdu_id)
+{
+	struct ol_tx_desc_t *tx_desc;
+
+	tx_desc = ol_tx_desc_find(pdev, msdu_id);
+	qdf_assert(tx_desc);
+
+	/*
+	 * If the download is done for
+	 * the Management frame then
+	 * call the download callback if registered
+	 */
+	if (tx_desc->pkt_type >= OL_TXRX_MGMT_TYPE_BASE) {
+		ol_txrx_mgmt_tx_cb download_cb =
+			pdev->tx_mgmt_cb.download_cb;
+		if (download_cb) {
+			download_cb(pdev->tx_mgmt_cb.ctxt,
+				    tx_desc->netbuf, status != A_OK);
+		}
+	}
+
+	if (status != A_OK) {
+		ol_tx_target_credit_incr(pdev, msdu);
+		ol_tx_desc_frame_free_nonstd(pdev, tx_desc,
+					     1 /* download err */);
+	} else {
+		if (OL_TX_DESC_NO_REFS(tx_desc)) {
+			/*
+			 * The decremented value was zero - free the frame.
+			 * Use the tx status recorded previously during
+			 * tx completion handling.
+			 */
+			ol_tx_desc_frame_free_nonstd(pdev, tx_desc,
+						     tx_desc->status !=
+						     htt_tx_status_ok);
+		}
+	}
+}
+
+void
+ol_tx_download_done_ll(void *pdev,
+		       A_STATUS status, qdf_nbuf_t msdu, uint16_t msdu_id)
+{
+	ol_tx_download_done_base((struct ol_txrx_pdev_t *)pdev, status, msdu,
+				 msdu_id);
+}
+
+void
+ol_tx_download_done_hl_retain(void *txrx_pdev,
+			      A_STATUS status,
+			      qdf_nbuf_t msdu, uint16_t msdu_id)
+{
+	struct ol_txrx_pdev_t *pdev = txrx_pdev;
+
+	ol_tx_download_done_base(pdev, status, msdu, msdu_id);
+}
+
+void
+ol_tx_download_done_hl_free(void *txrx_pdev,
+			    A_STATUS status, qdf_nbuf_t msdu, uint16_t msdu_id)
+{
+	struct ol_txrx_pdev_t *pdev = txrx_pdev;
+	struct ol_tx_desc_t *tx_desc;
+
+	tx_desc = ol_tx_desc_find(pdev, msdu_id);
+	qdf_assert(tx_desc);
+
+	ol_tx_download_done_base(pdev, status, msdu, msdu_id);
+
+	if ((tx_desc->pkt_type != OL_TX_FRM_NO_FREE) &&
+	    (tx_desc->pkt_type < OL_TXRX_MGMT_TYPE_BASE)) {
+		qdf_atomic_add(1, &pdev->tx_queue.rsrc_cnt);
+		ol_tx_desc_frame_free_nonstd(pdev, tx_desc, status != A_OK);
+	}
+}
+
+void ol_tx_target_credit_init(struct ol_txrx_pdev_t *pdev, int credit_delta)
+{
+	qdf_atomic_add(credit_delta, &pdev->orig_target_tx_credit);
+}
+
+void ol_tx_target_credit_update(struct ol_txrx_pdev_t *pdev, int credit_delta)
+{
+	TX_CREDIT_DEBUG_PRINT(" <HTT> Increase credit %d + %d = %d\n",
+			      qdf_atomic_read(&pdev->target_tx_credit),
+			      credit_delta,
+			      qdf_atomic_read(&pdev->target_tx_credit) +
+			      credit_delta);
+	qdf_atomic_add(credit_delta, &pdev->target_tx_credit);
+}
+
+#ifdef QCA_COMPUTE_TX_DELAY
+
+static void
+ol_tx_delay_compute(struct ol_txrx_pdev_t *pdev,
+		    enum htt_tx_status status,
+		    uint16_t *desc_ids, int num_msdus);
+
+#else
+static inline void
+ol_tx_delay_compute(struct ol_txrx_pdev_t *pdev,
+		    enum htt_tx_status status,
+		    uint16_t *desc_ids, int num_msdus)
+{
+}
+#endif /* QCA_COMPUTE_TX_DELAY */
+
+#ifndef OL_TX_RESTORE_HDR
+#define OL_TX_RESTORE_HDR(__tx_desc, __msdu)
+#endif
+/*
+ * The following macros could have been inline functions too.
+ * The only rationale for choosing macros, is to force the compiler to inline
+ * the implementation, which cannot be controlled for actual "inline" functions,
+ * since "inline" is only a hint to the compiler.
+ * In the performance path, we choose to force the inlining, in preference to
+ * type-checking offered by the actual inlined functions.
+ */
+#define ol_tx_msdu_complete_batch(_pdev, _tx_desc, _tx_descs, _status) \
+	TAILQ_INSERT_TAIL(&(_tx_descs), (_tx_desc), tx_desc_list_elem)
+#ifndef ATH_11AC_TXCOMPACT
+#define ol_tx_msdu_complete_single(_pdev, _tx_desc, _netbuf,\
+				   _lcl_freelist, _tx_desc_last)	\
+	do {								\
+		qdf_atomic_init(&(_tx_desc)->ref_cnt);			\
+		/* restore orginal hdr offset */			\
+		OL_TX_RESTORE_HDR((_tx_desc), (_netbuf));		\
+		qdf_nbuf_unmap((_pdev)->osdev, (_netbuf), QDF_DMA_TO_DEVICE); \
+		qdf_nbuf_free((_netbuf));				\
+		((union ol_tx_desc_list_elem_t *)(_tx_desc))->next =	\
+			(_lcl_freelist);				\
+		if (qdf_unlikely(!lcl_freelist)) {			\
+			(_tx_desc_last) = (union ol_tx_desc_list_elem_t *)\
+				(_tx_desc);				\
+		}							\
+		(_lcl_freelist) = (union ol_tx_desc_list_elem_t *)(_tx_desc); \
+	} while (0)
+#else    /*!ATH_11AC_TXCOMPACT */
+#define ol_tx_msdu_complete_single(_pdev, _tx_desc, _netbuf,\
+				   _lcl_freelist, _tx_desc_last)	\
+	do {								\
+		/* restore orginal hdr offset */			\
+		OL_TX_RESTORE_HDR((_tx_desc), (_netbuf));		\
+		qdf_nbuf_unmap((_pdev)->osdev, (_netbuf), QDF_DMA_TO_DEVICE); \
+		qdf_nbuf_free((_netbuf));				\
+		((union ol_tx_desc_list_elem_t *)(_tx_desc))->next =	\
+			(_lcl_freelist);				\
+		if (qdf_unlikely(!lcl_freelist)) {			\
+			(_tx_desc_last) = (union ol_tx_desc_list_elem_t *)\
+				(_tx_desc);				\
+		}							\
+		(_lcl_freelist) = (union ol_tx_desc_list_elem_t *)(_tx_desc); \
+	} while (0)
+
+#endif /*!ATH_11AC_TXCOMPACT */
+
+#ifdef QCA_TX_SINGLE_COMPLETIONS
+#ifdef QCA_TX_STD_PATH_ONLY
+#define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs,			\
+			    _netbuf, _lcl_freelist,			\
+			    _tx_desc_last, _status, is_tx_desc_freed)	\
+	{								\
+		is_tx_desc_freed = 0;					\
+		ol_tx_msdu_complete_single((_pdev), (_tx_desc),		\
+					   (_netbuf), (_lcl_freelist),	\
+					   _tx_desc_last)		\
+	}
+#else                           /* !QCA_TX_STD_PATH_ONLY */
+#define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs,			\
+			    _netbuf, _lcl_freelist,			\
+			    _tx_desc_last, _status, is_tx_desc_freed)	\
+	do {								\
+		if (qdf_likely((_tx_desc)->pkt_type == OL_TX_FRM_STD)) { \
+			is_tx_desc_freed = 0;				\
+			ol_tx_msdu_complete_single((_pdev), (_tx_desc),\
+						   (_netbuf), (_lcl_freelist), \
+						   (_tx_desc_last));	\
+		} else {						\
+			is_tx_desc_freed = 1;				\
+			ol_tx_desc_frame_free_nonstd(			\
+				(_pdev), (_tx_desc),			\
+				(_status) != htt_tx_status_ok);		\
+		}							\
+	} while (0)
+#endif /* !QCA_TX_STD_PATH_ONLY */
+#else                           /* !QCA_TX_SINGLE_COMPLETIONS */
+#ifdef QCA_TX_STD_PATH_ONLY
+#define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs,			\
+			    _netbuf, _lcl_freelist,			\
+			    _tx_desc_last, _status, is_tx_desc_freed)	\
+	{								\
+		is_tx_desc_freed = 0;					\
+		ol_tx_msdu_complete_batch((_pdev), (_tx_desc),		\
+					(_tx_descs), (_status))		\
+	}
+#else                           /* !QCA_TX_STD_PATH_ONLY */
+#define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs,			\
+			    _netbuf, _lcl_freelist,			\
+			    _tx_desc_last, _status, is_tx_desc_freed)	\
+	do {								\
+		if (qdf_likely((_tx_desc)->pkt_type == OL_TX_FRM_STD)) { \
+			is_tx_desc_freed = 0;				\
+			ol_tx_msdu_complete_batch((_pdev), (_tx_desc),	\
+						  (_tx_descs), (_status)); \
+		} else {						\
+			is_tx_desc_freed = 1;				\
+			ol_tx_desc_frame_free_nonstd((_pdev), (_tx_desc), \
+						     (_status) !=	\
+						     htt_tx_status_ok); \
+		}							\
+	} while (0)
+#endif /* !QCA_TX_STD_PATH_ONLY */
+#endif /* QCA_TX_SINGLE_COMPLETIONS */
+
+#if !defined(CONFIG_HL_SUPPORT)
+void ol_tx_discard_target_frms(ol_txrx_pdev_handle pdev)
+{
+	int i = 0;
+	struct ol_tx_desc_t *tx_desc;
+	int num_disarded = 0;
+
+	for (i = 0; i < pdev->tx_desc.pool_size; i++) {
+		tx_desc = ol_tx_desc_find(pdev, i);
+		/*
+		 * Confirm that each tx descriptor is "empty", i.e. it has
+		 * no tx frame attached.
+		 * In particular, check that there are no frames that have
+		 * been given to the target to transmit, for which the
+		 * target has never provided a response.
+		 */
+		if (qdf_atomic_read(&tx_desc->ref_cnt)) {
+			ol_txrx_dbg(
+				   "Warning: freeing tx desc %d", tx_desc->id);
+			ol_tx_desc_frame_free_nonstd(pdev,
+						     tx_desc, 1);
+			num_disarded++;
+		}
+	}
+
+	if (num_disarded)
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+			"Warning: freed %d tx descs for which no tx completion rcvd from the target",
+			num_disarded);
+}
+#endif
+
+void ol_tx_credit_completion_handler(ol_txrx_pdev_handle pdev, int credits)
+{
+	ol_tx_target_credit_update(pdev, credits);
+
+	if (pdev->cfg.is_high_latency)
+		ol_tx_sched(pdev);
+
+	/* UNPAUSE OS Q */
+	ol_tx_flow_ct_unpause_os_q(pdev);
+}
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+/**
+ * ol_tx_flow_pool_lock() - take flow pool lock
+ * @tx_desc: tx desc
+ *
+ * Return: None
+ */
+static inline
+void ol_tx_flow_pool_lock(struct ol_tx_desc_t *tx_desc)
+{
+	struct ol_tx_flow_pool_t *pool;
+
+	pool = tx_desc->pool;
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+}
+
+/**
+ * ol_tx_flow_pool_unlock() - release flow pool lock
+ * @tx_desc: tx desc
+ *
+ * Return: None
+ */
+static inline
+void ol_tx_flow_pool_unlock(struct ol_tx_desc_t *tx_desc)
+{
+	struct ol_tx_flow_pool_t *pool;
+
+	pool = tx_desc->pool;
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+}
+#else
+static inline
+void ol_tx_flow_pool_lock(struct ol_tx_desc_t *tx_desc)
+{
+}
+
+static inline
+void ol_tx_flow_pool_unlock(struct ol_tx_desc_t *tx_desc)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+static inline struct htt_tx_compl_ind_append_tx_tstamp *ol_tx_get_txtstamps(
+		u_int32_t *msg_word, int num_msdus)
+{
+	u_int32_t has_tx_tsf;
+	u_int32_t has_retry;
+	struct htt_tx_compl_ind_append_tx_tstamp *txtstamp_list = NULL;
+	struct htt_tx_compl_ind_append_retries *retry_list = NULL;
+	int offset_dwords;
+
+	has_tx_tsf = HTT_TX_COMPL_IND_APPEND1_GET(*msg_word);
+	if (num_msdus <= 0 || !has_tx_tsf)
+		return NULL;
+
+	offset_dwords = 1 + ((num_msdus + 1) >> 1);
+
+	has_retry = HTT_TX_COMPL_IND_APPEND_GET(*msg_word);
+	if (has_retry) {
+		int retry_index = 0;
+		int width_for_each_retry =
+			(sizeof(struct htt_tx_compl_ind_append_retries) +
+			3) >> 2;
+
+		retry_list = (struct htt_tx_compl_ind_append_retries *)
+			(msg_word + offset_dwords);
+		while (retry_list) {
+			if (retry_list[retry_index++].flag == 0)
+				break;
+		}
+		offset_dwords += retry_index * width_for_each_retry;
+	}
+	txtstamp_list = (struct htt_tx_compl_ind_append_tx_tstamp *)
+		(msg_word + offset_dwords);
+
+	return txtstamp_list;
+}
+
+static inline void ol_tx_timestamp(ol_txrx_pdev_handle pdev,
+				   qdf_nbuf_t netbuf, u_int64_t ts)
+{
+	if (!netbuf)
+		return;
+
+	if (pdev->ol_tx_timestamp_cb)
+		pdev->ol_tx_timestamp_cb(netbuf, ts);
+}
+#else
+static inline struct htt_tx_compl_ind_append_tx_tstamp *ol_tx_get_txtstamps(
+		u_int32_t *msg_word, int num_msdus)
+{
+	return NULL;
+}
+
+static inline void ol_tx_timestamp(ol_txrx_pdev_handle pdev,
+				   qdf_nbuf_t netbuf, u_int64_t ts)
+{
+}
+#endif
+
+static void ol_tx_update_ack_count(struct ol_tx_desc_t *tx_desc,
+				   enum htt_tx_status status)
+{
+	if (!tx_desc->vdev)
+		return;
+
+	if (status == htt_tx_status_ok)
+		++tx_desc->vdev->txrx_stats.txack_success;
+	else
+		++tx_desc->vdev->txrx_stats.txack_failed;
+}
+
+/**
+ * ol_tx_notify_completion() - Notify tx completion for this desc
+ * @tx_desc: tx desc
+ * @netbuf:  buffer
+ *
+ * Return: none
+ */
+static void ol_tx_notify_completion(struct ol_tx_desc_t *tx_desc,
+				    qdf_nbuf_t netbuf)
+{
+	void *osif_dev;
+	ol_txrx_completion_fp tx_compl_cbk = NULL;
+
+	qdf_assert(tx_desc);
+
+	ol_tx_flow_pool_lock(tx_desc);
+
+	if (!tx_desc->vdev ||
+	    !tx_desc->vdev->osif_dev) {
+		ol_tx_flow_pool_unlock(tx_desc);
+		return;
+	}
+	osif_dev = tx_desc->vdev->osif_dev;
+	tx_compl_cbk = tx_desc->vdev->tx_comp;
+	ol_tx_flow_pool_unlock(tx_desc);
+
+	if (tx_compl_cbk)
+		tx_compl_cbk(netbuf, osif_dev);
+}
+
+/**
+ * ol_tx_update_connectivity_stats() - update connectivity stats
+ * @tx_desc: tx desc
+ * @netbuf:  buffer
+ * @status: htt status
+ *
+ *
+ * Return: none
+ */
+static void ol_tx_update_connectivity_stats(struct ol_tx_desc_t *tx_desc,
+					    qdf_nbuf_t netbuf,
+					    enum htt_tx_status status)
+{
+	void *osif_dev;
+	uint32_t pkt_type_bitmap;
+	ol_txrx_stats_rx_fp stats_rx = NULL;
+	uint8_t pkt_type = 0;
+
+	qdf_assert(tx_desc);
+
+	ol_tx_flow_pool_lock(tx_desc);
+	/*
+	 * In cases when vdev has gone down and tx completion
+	 * are received, leads to NULL vdev access.
+	 * So, check for NULL before dereferencing it.
+	 */
+	if (!tx_desc->vdev ||
+	    !tx_desc->vdev->osif_dev ||
+	    !tx_desc->vdev->stats_rx) {
+		ol_tx_flow_pool_unlock(tx_desc);
+		return;
+	}
+	osif_dev = tx_desc->vdev->osif_dev;
+	stats_rx = tx_desc->vdev->stats_rx;
+	ol_tx_flow_pool_unlock(tx_desc);
+
+	pkt_type_bitmap = cds_get_connectivity_stats_pkt_bitmap(osif_dev);
+
+	if (pkt_type_bitmap) {
+		if (status != htt_tx_status_download_fail)
+			stats_rx(netbuf, osif_dev,
+				 PKT_TYPE_TX_HOST_FW_SENT, &pkt_type);
+		if (status == htt_tx_status_ok)
+			stats_rx(netbuf, osif_dev,
+				 PKT_TYPE_TX_ACK_CNT, &pkt_type);
+	}
+}
+
+/**
+ * ol_tx_update_arp_stats() - update ARP packet TX stats
+ * @tx_desc: tx desc
+ * @netbuf:  buffer
+ * @status: htt status
+ *
+ *
+ * Return: none
+ */
+static void ol_tx_update_arp_stats(struct ol_tx_desc_t *tx_desc,
+				   qdf_nbuf_t netbuf,
+				   enum htt_tx_status status)
+{
+	uint32_t tgt_ip;
+
+	qdf_assert(tx_desc);
+
+	ol_tx_flow_pool_lock(tx_desc);
+	if (!tx_desc->vdev) {
+		ol_tx_flow_pool_unlock(tx_desc);
+		return;
+	}
+
+	tgt_ip = cds_get_arp_stats_gw_ip(tx_desc->vdev->osif_dev);
+	ol_tx_flow_pool_unlock(tx_desc);
+
+	if (tgt_ip == qdf_nbuf_get_arp_tgt_ip(netbuf)) {
+		if (status != htt_tx_status_download_fail)
+			cds_incr_arp_stats_tx_tgt_delivered();
+		if (status == htt_tx_status_ok)
+			cds_incr_arp_stats_tx_tgt_acked();
+	}
+}
+
+/**
+ * WARNING: ol_tx_inspect_handler()'s behavior is similar to that of
+ * ol_tx_completion_handler().
+ * any change in ol_tx_completion_handler() must be mirrored in
+ * ol_tx_inspect_handler().
+ */
+void
+ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
+			 int num_msdus,
+			 enum htt_tx_status status, void *msg)
+{
+	int i;
+	uint16_t tx_desc_id;
+	struct ol_tx_desc_t *tx_desc;
+	uint32_t byte_cnt = 0;
+	qdf_nbuf_t netbuf;
+	tp_ol_packetdump_cb packetdump_cb;
+	uint32_t is_tx_desc_freed = 0;
+	struct htt_tx_compl_ind_append_tx_tstamp *txtstamp_list = NULL;
+	u_int32_t *msg_word = (u_int32_t *)msg;
+	u_int16_t *desc_ids = (u_int16_t *)(msg_word + 1);
+	union ol_tx_desc_list_elem_t *lcl_freelist = NULL;
+	union ol_tx_desc_list_elem_t *tx_desc_last = NULL;
+	ol_tx_desc_list tx_descs;
+
+	TAILQ_INIT(&tx_descs);
+
+	ol_tx_delay_compute(pdev, status, desc_ids, num_msdus);
+	if (status == htt_tx_status_ok)
+		txtstamp_list = ol_tx_get_txtstamps(msg_word, num_msdus);
+
+	for (i = 0; i < num_msdus; i++) {
+		tx_desc_id = desc_ids[i];
+		if (tx_desc_id >= pdev->tx_desc.pool_size) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s: drop due to invalid msdu id = %x\n",
+			__func__, tx_desc_id);
+			continue;
+		}
+		tx_desc = ol_tx_desc_find(pdev, tx_desc_id);
+		qdf_assert(tx_desc);
+		ol_tx_desc_update_comp_ts(tx_desc);
+		tx_desc->status = status;
+		netbuf = tx_desc->netbuf;
+
+		if (txtstamp_list)
+			ol_tx_timestamp(pdev, netbuf,
+					(u_int64_t)txtstamp_list->timestamp[i]
+					);
+
+		QDF_NBUF_UPDATE_TX_PKT_COUNT(netbuf, QDF_NBUF_TX_PKT_FREE);
+
+		if (QDF_NBUF_CB_GET_PACKET_TYPE(netbuf) ==
+		    QDF_NBUF_CB_PACKET_TYPE_ARP) {
+			if (qdf_nbuf_data_is_arp_req(netbuf))
+				ol_tx_update_arp_stats(tx_desc, netbuf, status);
+		}
+
+		/* check tx completion notification */
+		if (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(netbuf))
+			ol_tx_notify_completion(tx_desc, netbuf);
+
+		/* track connectivity stats */
+		ol_tx_update_connectivity_stats(tx_desc, netbuf,
+						status);
+		ol_tx_update_ack_count(tx_desc, status);
+
+		if (tx_desc->pkt_type != OL_TX_FRM_TSO) {
+			packetdump_cb = pdev->ol_tx_packetdump_cb;
+			if (packetdump_cb)
+				packetdump_cb(netbuf, status,
+					tx_desc->vdev_id, TX_DATA_PKT);
+		}
+
+		DPTRACE(qdf_dp_trace_ptr(netbuf,
+			QDF_DP_TRACE_FREE_PACKET_PTR_RECORD,
+			QDF_TRACE_DEFAULT_PDEV_ID,
+			qdf_nbuf_data_addr(netbuf),
+			sizeof(qdf_nbuf_data(netbuf)), tx_desc->id, status));
+		htc_pm_runtime_put(pdev->htt_pdev->htc_pdev);
+		/*
+		 * If credits are reported through credit_update_ind then do not
+		 * update group credits on tx_complete_ind.
+		 */
+		if (!pdev->cfg.credit_update_enabled)
+			ol_tx_desc_update_group_credit(pdev,
+						       tx_desc_id,
+						       1, 0, status);
+		/* Per SDU update of byte count */
+		byte_cnt += qdf_nbuf_len(netbuf);
+		if (OL_TX_DESC_NO_REFS(tx_desc)) {
+			ol_tx_statistics(
+				pdev->ctrl_pdev,
+				HTT_TX_DESC_VDEV_ID_GET(*((uint32_t *)
+							  (tx_desc->
+							   htt_tx_desc))),
+				status != htt_tx_status_ok);
+			ol_tx_msdu_complete(pdev, tx_desc, tx_descs, netbuf,
+					    lcl_freelist, tx_desc_last, status,
+					    is_tx_desc_freed);
+
+#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS
+			if (!is_tx_desc_freed) {
+				tx_desc->pkt_type = ol_tx_frm_freed;
+#ifdef QCA_COMPUTE_TX_DELAY
+				tx_desc->entry_timestamp_ticks = 0xffffffff;
+#endif
+			}
+#endif
+		}
+	}
+
+	/* One shot protected access to pdev freelist, when setup */
+	if (lcl_freelist) {
+		qdf_spin_lock(&pdev->tx_mutex);
+		tx_desc_last->next = pdev->tx_desc.freelist;
+		pdev->tx_desc.freelist = lcl_freelist;
+		pdev->tx_desc.num_free += (uint16_t) num_msdus;
+		qdf_spin_unlock(&pdev->tx_mutex);
+	} else {
+		ol_tx_desc_frame_list_free(pdev, &tx_descs,
+					   status != htt_tx_status_ok);
+	}
+
+	if (pdev->cfg.is_high_latency) {
+		/*
+		 * Credit was already explicitly updated by HTT,
+		 * but update the number of available tx descriptors,
+		 * then invoke the scheduler, since new credit is probably
+		 * available now.
+		 */
+		qdf_atomic_add(num_msdus, &pdev->tx_queue.rsrc_cnt);
+		ol_tx_sched(pdev);
+	} else {
+		ol_tx_target_credit_adjust(num_msdus, pdev, NULL);
+	}
+
+	/* UNPAUSE OS Q */
+	ol_tx_flow_ct_unpause_os_q(pdev);
+	/* Do one shot statistics */
+	TXRX_STATS_UPDATE_TX_STATS(pdev, status, num_msdus, byte_cnt);
+}
+
+#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+
+void ol_tx_desc_update_group_credit(ol_txrx_pdev_handle pdev,
+		u_int16_t tx_desc_id, int credit, u_int8_t absolute,
+		enum htt_tx_status status)
+{
+	uint8_t i, is_member;
+	uint16_t vdev_id_mask;
+	struct ol_tx_desc_t *tx_desc;
+
+	if (tx_desc_id >= pdev->tx_desc.pool_size) {
+		qdf_print("%s: Invalid desc id", __func__);
+		return;
+	}
+
+	tx_desc = ol_tx_desc_find(pdev, tx_desc_id);
+	for (i = 0; i < OL_TX_MAX_TXQ_GROUPS; i++) {
+		vdev_id_mask =
+			OL_TXQ_GROUP_VDEV_ID_MASK_GET(
+					pdev->txq_grps[i].membership);
+		is_member = OL_TXQ_GROUP_VDEV_ID_BIT_MASK_GET(vdev_id_mask,
+				tx_desc->vdev_id);
+		if (is_member) {
+			ol_txrx_update_group_credit(&pdev->txq_grps[i],
+						    credit, absolute);
+			break;
+		}
+	}
+	ol_tx_update_group_credit_stats(pdev);
+}
+
+#ifdef DEBUG_HL_LOGGING
+
+void ol_tx_update_group_credit_stats(ol_txrx_pdev_handle pdev)
+{
+	uint16_t curr_index;
+	uint8_t i;
+
+	qdf_spin_lock_bh(&pdev->grp_stat_spinlock);
+	pdev->grp_stats.last_valid_index++;
+	if (pdev->grp_stats.last_valid_index > (OL_TX_GROUP_STATS_LOG_SIZE
+				- 1)) {
+		pdev->grp_stats.last_valid_index -= OL_TX_GROUP_STATS_LOG_SIZE;
+		pdev->grp_stats.wrap_around = 1;
+	}
+	curr_index = pdev->grp_stats.last_valid_index;
+
+	for (i = 0; i < OL_TX_MAX_TXQ_GROUPS; i++) {
+		pdev->grp_stats.stats[curr_index].grp[i].member_vdevs =
+			OL_TXQ_GROUP_VDEV_ID_MASK_GET(
+					pdev->txq_grps[i].membership);
+		pdev->grp_stats.stats[curr_index].grp[i].credit =
+			qdf_atomic_read(&pdev->txq_grps[i].credit);
+	}
+
+	qdf_spin_unlock_bh(&pdev->grp_stat_spinlock);
+}
+
+void ol_tx_dump_group_credit_stats(ol_txrx_pdev_handle pdev)
+{
+	uint16_t i, j, is_break = 0;
+	int16_t curr_index, old_index, wrap_around;
+	uint16_t curr_credit, old_credit, mem_vdevs;
+
+	txrx_nofl_info("Group credit stats:");
+	txrx_nofl_info("  No: GrpID: Credit: Change: vdev_map");
+
+	qdf_spin_lock_bh(&pdev->grp_stat_spinlock);
+	curr_index = pdev->grp_stats.last_valid_index;
+	wrap_around = pdev->grp_stats.wrap_around;
+	qdf_spin_unlock_bh(&pdev->grp_stat_spinlock);
+
+	if (curr_index < 0) {
+		txrx_nofl_info("Not initialized");
+		return;
+	}
+
+	for (i = 0; i < OL_TX_GROUP_STATS_LOG_SIZE; i++) {
+		old_index = curr_index - 1;
+		if (old_index < 0) {
+			if (wrap_around == 0)
+				is_break = 1;
+			else
+				old_index = OL_TX_GROUP_STATS_LOG_SIZE - 1;
+		}
+
+		for (j = 0; j < OL_TX_MAX_TXQ_GROUPS; j++) {
+			qdf_spin_lock_bh(&pdev->grp_stat_spinlock);
+			curr_credit =
+				pdev->grp_stats.stats[curr_index].
+								grp[j].credit;
+			if (!is_break)
+				old_credit =
+					pdev->grp_stats.stats[old_index].
+								grp[j].credit;
+
+			mem_vdevs =
+				pdev->grp_stats.stats[curr_index].grp[j].
+								member_vdevs;
+			qdf_spin_unlock_bh(&pdev->grp_stat_spinlock);
+
+			if (!is_break)
+				txrx_nofl_info("%4d: %5d: %6d %6d %8x",
+					       curr_index, j,
+					       curr_credit,
+					       (curr_credit - old_credit),
+					       mem_vdevs);
+			else
+				txrx_nofl_info("%4d: %5d: %6d %6s %8x",
+					       curr_index, j,
+					       curr_credit, "NA", mem_vdevs);
+		}
+
+		if (is_break)
+			break;
+
+		curr_index = old_index;
+	}
+}
+
+void ol_tx_clear_group_credit_stats(ol_txrx_pdev_handle pdev)
+{
+	qdf_spin_lock_bh(&pdev->grp_stat_spinlock);
+	qdf_mem_zero(&pdev->grp_stats, sizeof(pdev->grp_stats));
+	pdev->grp_stats.last_valid_index = -1;
+	pdev->grp_stats.wrap_around = 0;
+	qdf_spin_unlock_bh(&pdev->grp_stat_spinlock);
+}
+#endif
+#endif
+
+/*
+ * ol_tx_single_completion_handler performs the same tx completion
+ * processing as ol_tx_completion_handler, but for a single frame.
+ * ol_tx_completion_handler is optimized to handle batch completions
+ * as efficiently as possible; in contrast ol_tx_single_completion_handler
+ * handles single frames as simply and generally as possible.
+ * Thus, this ol_tx_single_completion_handler function is suitable for
+ * intermittent usage, such as for tx mgmt frames.
+ */
+void
+ol_tx_single_completion_handler(ol_txrx_pdev_handle pdev,
+				enum htt_tx_status status, uint16_t tx_desc_id)
+{
+	struct ol_tx_desc_t *tx_desc;
+	qdf_nbuf_t netbuf;
+	tp_ol_packetdump_cb packetdump_cb;
+
+	tx_desc = ol_tx_desc_find_check(pdev, tx_desc_id);
+	if (tx_desc == NULL) {
+		ol_txrx_err("%s: invalid desc_id(%u), ignore it.\n",
+			    __func__, tx_desc_id);
+		return;
+	}
+
+	tx_desc->status = status;
+	netbuf = tx_desc->netbuf;
+
+	QDF_NBUF_UPDATE_TX_PKT_COUNT(netbuf, QDF_NBUF_TX_PKT_FREE);
+	/* Do one shot statistics */
+	TXRX_STATS_UPDATE_TX_STATS(pdev, status, 1, qdf_nbuf_len(netbuf));
+
+	packetdump_cb = pdev->ol_tx_packetdump_cb;
+	if (packetdump_cb)
+		packetdump_cb(netbuf, status,
+			tx_desc->vdev->vdev_id, TX_MGMT_PKT);
+
+	if (OL_TX_DESC_NO_REFS(tx_desc)) {
+		ol_tx_desc_frame_free_nonstd(pdev, tx_desc,
+					     status != htt_tx_status_ok);
+	}
+
+	TX_CREDIT_DEBUG_PRINT(" <HTT> Increase credit %d + %d = %d\n",
+			      qdf_atomic_read(&pdev->target_tx_credit),
+			      1, qdf_atomic_read(&pdev->target_tx_credit) + 1);
+
+	if (pdev->cfg.is_high_latency) {
+		/*
+		 * Credit was already explicitly updated by HTT,
+		 * but update the number of available tx descriptors,
+		 * then invoke the scheduler, since new credit is probably
+		 * available now.
+		 */
+		qdf_atomic_add(1, &pdev->tx_queue.rsrc_cnt);
+		ol_tx_sched(pdev);
+	} else {
+		qdf_atomic_add(1, &pdev->target_tx_credit);
+	}
+}
+
+/**
+ * WARNING: ol_tx_inspect_handler()'s behavior is similar to that of
+ * ol_tx_completion_handler().
+ * any change in ol_tx_completion_handler() must be mirrored here.
+ */
+void
+ol_tx_inspect_handler(ol_txrx_pdev_handle pdev,
+		      int num_msdus, void *tx_desc_id_iterator)
+{
+	uint16_t vdev_id, i;
+	struct ol_txrx_vdev_t *vdev;
+	uint16_t *desc_ids = (uint16_t *) tx_desc_id_iterator;
+	uint16_t tx_desc_id;
+	struct ol_tx_desc_t *tx_desc;
+	union ol_tx_desc_list_elem_t *lcl_freelist = NULL;
+	union ol_tx_desc_list_elem_t *tx_desc_last = NULL;
+	qdf_nbuf_t netbuf;
+	ol_tx_desc_list tx_descs;
+	uint32_t is_tx_desc_freed = 0;
+
+	TAILQ_INIT(&tx_descs);
+
+	for (i = 0; i < num_msdus; i++) {
+		tx_desc_id = desc_ids[i];
+		if (tx_desc_id >= pdev->tx_desc.pool_size) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s: drop due to invalid msdu id = %x\n",
+			__func__, tx_desc_id);
+			continue;
+		}
+		tx_desc = ol_tx_desc_find(pdev, tx_desc_id);
+		qdf_assert(tx_desc);
+		ol_tx_desc_update_comp_ts(tx_desc);
+		netbuf = tx_desc->netbuf;
+
+		/* find the "vdev" this tx_desc belongs to */
+		vdev_id = HTT_TX_DESC_VDEV_ID_GET(*((uint32_t *)
+						    (tx_desc->htt_tx_desc)));
+		TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+			if (vdev->vdev_id == vdev_id)
+				break;
+		}
+
+		/* vdev now points to the vdev for this descriptor. */
+
+#ifndef ATH_11AC_TXCOMPACT
+		/* save this multicast packet to local free list */
+		if (qdf_atomic_dec_and_test(&tx_desc->ref_cnt))
+#endif
+		{
+			/*
+			 * For this function only, force htt status to be
+			 * "htt_tx_status_ok"
+			 * for graceful freeing of this multicast frame
+			 */
+			ol_tx_msdu_complete(pdev, tx_desc, tx_descs, netbuf,
+					    lcl_freelist, tx_desc_last,
+					    htt_tx_status_ok,
+					    is_tx_desc_freed);
+#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS
+			if (!is_tx_desc_freed) {
+				tx_desc->pkt_type = ol_tx_frm_freed;
+#ifdef QCA_COMPUTE_TX_DELAY
+				tx_desc->entry_timestamp_ticks = 0xffffffff;
+#endif
+			}
+#endif
+		}
+	}
+
+	if (lcl_freelist) {
+		qdf_spin_lock(&pdev->tx_mutex);
+		tx_desc_last->next = pdev->tx_desc.freelist;
+		pdev->tx_desc.freelist = lcl_freelist;
+		qdf_spin_unlock(&pdev->tx_mutex);
+	} else {
+		ol_tx_desc_frame_list_free(pdev, &tx_descs,
+					   htt_tx_status_discard);
+	}
+	TX_CREDIT_DEBUG_PRINT(" <HTT> Increase HTT credit %d + %d = %d..\n",
+			      qdf_atomic_read(&pdev->target_tx_credit),
+			      num_msdus,
+			      qdf_atomic_read(&pdev->target_tx_credit) +
+			      num_msdus);
+
+	if (pdev->cfg.is_high_latency) {
+		/* credit was already explicitly updated by HTT */
+		ol_tx_sched(pdev);
+	} else {
+		ol_tx_target_credit_adjust(num_msdus, pdev, NULL);
+	}
+}
+
+#ifdef QCA_COMPUTE_TX_DELAY
+/**
+ * @brief updates the compute interval period for TSM stats.
+ * @details
+ * @param interval - interval for stats computation
+ */
+void ol_tx_set_compute_interval(struct cdp_pdev *ppdev, uint32_t interval)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	pdev->tx_delay.avg_period_ticks = qdf_system_msecs_to_ticks(interval);
+}
+
+/**
+ * @brief Return the uplink (transmitted) packet count and loss count.
+ * @details
+ *  This function will be called for getting uplink packet count and
+ *  loss count for given stream (access category) a regular interval.
+ *  This also resets the counters hence, the value returned is packets
+ *  counted in last 5(default) second interval. These counter are
+ *  incremented per access category in ol_tx_completion_handler()
+ *
+ * @param category - access category of interest
+ * @param out_packet_count - number of packets transmitted
+ * @param out_packet_loss_count - number of packets lost
+ */
+void
+ol_tx_packet_count(struct cdp_pdev *ppdev,
+		   uint16_t *out_packet_count,
+		   uint16_t *out_packet_loss_count, int category)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	*out_packet_count = pdev->packet_count[category];
+	*out_packet_loss_count = pdev->packet_loss_count[category];
+	pdev->packet_count[category] = 0;
+	pdev->packet_loss_count[category] = 0;
+}
+
+static uint32_t ol_tx_delay_avg(uint64_t sum, uint32_t num)
+{
+	uint32_t sum32;
+	int shift = 0;
+	/*
+	 * To avoid doing a 64-bit divide, shift the sum down until it is
+	 * no more than 32 bits (and shift the denominator to match).
+	 */
+	while ((sum >> 32) != 0) {
+		sum >>= 1;
+		shift++;
+	}
+	sum32 = (uint32_t) sum;
+	num >>= shift;
+	return (sum32 + (num >> 1)) / num;      /* round to nearest */
+}
+
+void
+ol_tx_delay(struct cdp_pdev *ppdev,
+	    uint32_t *queue_delay_microsec,
+	    uint32_t *tx_delay_microsec, int category)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	int index;
+	uint32_t avg_delay_ticks;
+	struct ol_tx_delay_data *data;
+
+	qdf_assert(category >= 0 && category < QCA_TX_DELAY_NUM_CATEGORIES);
+
+	qdf_spin_lock_bh(&pdev->tx_delay.mutex);
+	index = 1 - pdev->tx_delay.cats[category].in_progress_idx;
+
+	data = &pdev->tx_delay.cats[category].copies[index];
+
+	if (data->avgs.transmit_num > 0) {
+		avg_delay_ticks =
+			ol_tx_delay_avg(data->avgs.transmit_sum_ticks,
+					data->avgs.transmit_num);
+		*tx_delay_microsec =
+			qdf_system_ticks_to_msecs(avg_delay_ticks * 1000);
+	} else {
+		/*
+		 * This case should only happen if there's a query
+		 * within 5 sec after the first tx data frame.
+		 */
+		*tx_delay_microsec = 0;
+	}
+	if (data->avgs.queue_num > 0) {
+		avg_delay_ticks =
+			ol_tx_delay_avg(data->avgs.queue_sum_ticks,
+					data->avgs.queue_num);
+		*queue_delay_microsec =
+			qdf_system_ticks_to_msecs(avg_delay_ticks * 1000);
+	} else {
+		/*
+		 * This case should only happen if there's a query
+		 * within 5 sec after the first tx data frame.
+		 */
+		*queue_delay_microsec = 0;
+	}
+
+	qdf_spin_unlock_bh(&pdev->tx_delay.mutex);
+}
+
+void
+ol_tx_delay_hist(struct cdp_pdev *ppdev,
+		 uint16_t *report_bin_values, int category)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	int index, i, j;
+	struct ol_tx_delay_data *data;
+
+	qdf_assert(category >= 0 && category < QCA_TX_DELAY_NUM_CATEGORIES);
+
+	qdf_spin_lock_bh(&pdev->tx_delay.mutex);
+	index = 1 - pdev->tx_delay.cats[category].in_progress_idx;
+
+	data = &pdev->tx_delay.cats[category].copies[index];
+
+	for (i = 0, j = 0; i < QCA_TX_DELAY_HIST_REPORT_BINS - 1; i++) {
+		uint16_t internal_bin_sum = 0;
+
+		while (j < (1 << i))
+			internal_bin_sum += data->hist_bins_queue[j++];
+
+		report_bin_values[i] = internal_bin_sum;
+	}
+	report_bin_values[i] = data->hist_bins_queue[j];        /* overflow */
+
+	qdf_spin_unlock_bh(&pdev->tx_delay.mutex);
+}
+
+#ifdef QCA_COMPUTE_TX_DELAY_PER_TID
+static uint8_t
+ol_tx_delay_tid_from_l3_hdr(struct ol_txrx_pdev_t *pdev,
+			    qdf_nbuf_t msdu, struct ol_tx_desc_t *tx_desc)
+{
+	uint16_t ethertype;
+	uint8_t *dest_addr, *l3_hdr;
+	int is_mgmt, is_mcast;
+	int l2_hdr_size;
+
+	dest_addr = ol_tx_dest_addr_find(pdev, msdu);
+	if (NULL == dest_addr)
+		return QDF_NBUF_TX_EXT_TID_INVALID;
+
+	is_mcast = IEEE80211_IS_MULTICAST(dest_addr);
+	is_mgmt = tx_desc->pkt_type >= OL_TXRX_MGMT_TYPE_BASE;
+	if (is_mgmt) {
+		return (is_mcast) ?
+		       OL_TX_NUM_TIDS + OL_TX_VDEV_DEFAULT_MGMT :
+		       HTT_TX_EXT_TID_MGMT;
+	}
+	if (is_mcast)
+		return OL_TX_NUM_TIDS + OL_TX_VDEV_MCAST_BCAST;
+
+	if (pdev->frame_format == wlan_frm_fmt_802_3) {
+		struct ethernet_hdr_t *enet_hdr;
+
+		enet_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu);
+		l2_hdr_size = sizeof(struct ethernet_hdr_t);
+		ethertype =
+			(enet_hdr->ethertype[0] << 8) | enet_hdr->ethertype[1];
+		if (!IS_ETHERTYPE(ethertype)) {
+			struct llc_snap_hdr_t *llc_hdr;
+
+			llc_hdr = (struct llc_snap_hdr_t *)
+				  (qdf_nbuf_data(msdu) + l2_hdr_size);
+			l2_hdr_size += sizeof(struct llc_snap_hdr_t);
+			ethertype =
+				(llc_hdr->ethertype[0] << 8) | llc_hdr->
+				ethertype[1];
+		}
+	} else {
+		struct llc_snap_hdr_t *llc_hdr;
+
+		l2_hdr_size = sizeof(struct ieee80211_frame);
+		llc_hdr = (struct llc_snap_hdr_t *)(qdf_nbuf_data(msdu)
+						    + l2_hdr_size);
+		l2_hdr_size += sizeof(struct llc_snap_hdr_t);
+		ethertype =
+			(llc_hdr->ethertype[0] << 8) | llc_hdr->ethertype[1];
+	}
+	l3_hdr = qdf_nbuf_data(msdu) + l2_hdr_size;
+	if (ETHERTYPE_IPV4 == ethertype) {
+		return (((struct ipv4_hdr_t *)l3_hdr)->tos >> 5) & 0x7;
+	} else if (ETHERTYPE_IPV6 == ethertype) {
+		return (ipv6_traffic_class((struct ipv6_hdr_t *)l3_hdr) >> 5) &
+		       0x7;
+	} else {
+		return QDF_NBUF_TX_EXT_TID_INVALID;
+	}
+}
+
+static int ol_tx_delay_category(struct ol_txrx_pdev_t *pdev, uint16_t msdu_id)
+{
+	struct ol_tx_desc_t *tx_desc = ol_tx_desc_find(pdev, msdu_id);
+	uint8_t tid;
+	qdf_nbuf_t msdu = tx_desc->netbuf;
+
+	tid = qdf_nbuf_get_tid(msdu);
+	if (tid == QDF_NBUF_TX_EXT_TID_INVALID) {
+		tid = ol_tx_delay_tid_from_l3_hdr(pdev, msdu, tx_desc);
+		if (tid == QDF_NBUF_TX_EXT_TID_INVALID) {
+			/*
+			 * TID could not be determined
+			 * (this is not an IP frame?)
+			 */
+			return -EINVAL;
+		}
+	}
+	return tid;
+}
+#else
+static int ol_tx_delay_category(struct ol_txrx_pdev_t *pdev, uint16_t msdu_id)
+{
+	return 0;
+}
+#endif
+
+static inline int
+ol_tx_delay_hist_bin(struct ol_txrx_pdev_t *pdev, uint32_t delay_ticks)
+{
+	int bin;
+	/*
+	 * For speed, multiply and shift to approximate a divide. This causes
+	 * a small error, but the approximation error should be much less
+	 * than the other uncertainties in the tx delay computation.
+	 */
+	bin = (delay_ticks * pdev->tx_delay.hist_internal_bin_width_mult) >>
+	      pdev->tx_delay.hist_internal_bin_width_shift;
+	if (bin >= QCA_TX_DELAY_HIST_INTERNAL_BINS)
+		bin = QCA_TX_DELAY_HIST_INTERNAL_BINS - 1;
+
+	return bin;
+}
+
+static void
+ol_tx_delay_compute(struct ol_txrx_pdev_t *pdev,
+		    enum htt_tx_status status,
+		    uint16_t *desc_ids, int num_msdus)
+{
+	int i, index, cat;
+	uint32_t now_ticks = qdf_system_ticks();
+	uint32_t tx_delay_transmit_ticks, tx_delay_queue_ticks;
+	uint32_t avg_time_ticks;
+	struct ol_tx_delay_data *data;
+
+	qdf_assert(num_msdus > 0);
+
+	/*
+	 * keep static counters for total packet and lost packets
+	 * reset them in ol_tx_delay(), function used to fetch the stats
+	 */
+
+	cat = ol_tx_delay_category(pdev, desc_ids[0]);
+	if (cat < 0 || cat >= QCA_TX_DELAY_NUM_CATEGORIES)
+		return;
+
+	pdev->packet_count[cat] = pdev->packet_count[cat] + num_msdus;
+	if (status != htt_tx_status_ok) {
+		for (i = 0; i < num_msdus; i++) {
+			cat = ol_tx_delay_category(pdev, desc_ids[i]);
+			if (cat < 0 || cat >= QCA_TX_DELAY_NUM_CATEGORIES)
+				return;
+			pdev->packet_loss_count[cat]++;
+		}
+		return;
+	}
+
+	/* since we may switch the ping-pong index, provide mutex w. readers */
+	qdf_spin_lock_bh(&pdev->tx_delay.mutex);
+	index = pdev->tx_delay.cats[cat].in_progress_idx;
+
+	data = &pdev->tx_delay.cats[cat].copies[index];
+
+	if (pdev->tx_delay.tx_compl_timestamp_ticks != 0) {
+		tx_delay_transmit_ticks =
+			now_ticks - pdev->tx_delay.tx_compl_timestamp_ticks;
+		/*
+		 * We'd like to account for the number of MSDUs that were
+		 * transmitted together, but we don't know this.  All we know
+		 * is the number of MSDUs that were acked together.
+		 * Since the frame error rate is small, this is nearly the same
+		 * as the number of frames transmitted together.
+		 */
+		data->avgs.transmit_sum_ticks += tx_delay_transmit_ticks;
+		data->avgs.transmit_num += num_msdus;
+	}
+	pdev->tx_delay.tx_compl_timestamp_ticks = now_ticks;
+
+	for (i = 0; i < num_msdus; i++) {
+		int bin;
+		uint16_t id = desc_ids[i];
+		struct ol_tx_desc_t *tx_desc = ol_tx_desc_find(pdev, id);
+
+		tx_delay_queue_ticks =
+			now_ticks - tx_desc->entry_timestamp_ticks;
+
+		data->avgs.queue_sum_ticks += tx_delay_queue_ticks;
+		data->avgs.queue_num++;
+		bin = ol_tx_delay_hist_bin(pdev, tx_delay_queue_ticks);
+		data->hist_bins_queue[bin]++;
+	}
+
+	/* check if it's time to start a new average */
+	avg_time_ticks =
+		now_ticks - pdev->tx_delay.cats[cat].avg_start_time_ticks;
+	if (avg_time_ticks > pdev->tx_delay.avg_period_ticks) {
+		pdev->tx_delay.cats[cat].avg_start_time_ticks = now_ticks;
+		index = 1 - index;
+		pdev->tx_delay.cats[cat].in_progress_idx = index;
+		qdf_mem_zero(&pdev->tx_delay.cats[cat].copies[index],
+			     sizeof(pdev->tx_delay.cats[cat].copies[index]));
+	}
+
+	qdf_spin_unlock_bh(&pdev->tx_delay.mutex);
+}
+
+#endif /* QCA_COMPUTE_TX_DELAY */
+
+/**
+ * ol_register_packetdump_callback() - registers
+ *  tx data packet, tx mgmt. packet and rx data packet
+ *  dump callback handler.
+ *
+ * @ol_tx_packetdump_cb: tx packetdump cb
+ * @ol_rx_packetdump_cb: rx packetdump cb
+ *
+ * This function is used to register tx data pkt, tx mgmt.
+ * pkt and rx data pkt dump callback
+ *
+ * Return: None
+ *
+ */
+void ol_register_packetdump_callback(tp_ol_packetdump_cb ol_tx_packetdump_cb,
+					tp_ol_packetdump_cb ol_rx_packetdump_cb)
+{
+	ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		ol_txrx_err(
+				"%s: pdev is NULL", __func__);
+		return;
+	}
+
+	pdev->ol_tx_packetdump_cb = ol_tx_packetdump_cb;
+	pdev->ol_rx_packetdump_cb = ol_rx_packetdump_cb;
+}
+
+/**
+ * ol_deregister_packetdump_callback() - deregidters
+ *  tx data packet, tx mgmt. packet and rx data packet
+ *  dump callback handler
+ *
+ * This function is used to deregidter tx data pkt.,
+ * tx mgmt. pkt and rx data pkt. dump callback
+ *
+ * Return: None
+ *
+ */
+void ol_deregister_packetdump_callback(void)
+{
+	ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		ol_txrx_err(
+				"%s: pdev is NULL", __func__);
+		return;
+	}
+
+	pdev->ol_tx_packetdump_cb = NULL;
+	pdev->ol_rx_packetdump_cb = NULL;
+}
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+void ol_register_timestamp_callback(tp_ol_timestamp_cb ol_tx_timestamp_cb)
+{
+	ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		ol_txrx_err("%s: pdev is NULL", __func__);
+		return;
+	}
+	pdev->ol_tx_timestamp_cb = ol_tx_timestamp_cb;
+}
+
+void ol_deregister_timestamp_callback(void)
+{
+	ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		ol_txrx_err("%s: pdev is NULL", __func__);
+		return;
+	}
+	pdev->ol_tx_timestamp_cb = NULL;
+}
+#endif
diff --git a/core/dp/txrx/ol_tx_send.h b/core/dp/txrx/ol_tx_send.h
new file mode 100644
index 0000000..666c5ee
--- /dev/null
+++ b/core/dp/txrx/ol_tx_send.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2011, 2014-2018 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.
+ */
+
+/**
+ * @file ol_tx_send.h
+ * @brief API definitions for the tx sendriptor module within the data SW.
+ */
+#ifndef _OL_TX_SEND__H_
+#define _OL_TX_SEND__H_
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <cdp_txrx_cmn.h>       /* ol_txrx_vdev_t, etc. */
+
+#if defined(CONFIG_HL_SUPPORT)
+
+static inline void ol_tx_discard_target_frms(ol_txrx_pdev_handle pdev)
+{
+}
+#else
+
+/**
+ * @flush the ol tx when surprise remove.
+ *
+ */
+void ol_tx_discard_target_frms(ol_txrx_pdev_handle pdev);
+#endif
+
+/**
+ * @brief Send a tx frame to the target.
+ * @details
+ *
+ * @param pdev -  the phy dev
+ * @param vdev - the virtual device sending the data
+ *      (for specifying the transmitter address for multicast / broadcast data)
+ * @param netbuf - the tx frame
+ */
+void
+ol_tx_send(struct ol_txrx_pdev_t *pdev,
+	   struct ol_tx_desc_t *tx_desc, qdf_nbuf_t msdu, uint8_t vdev_id);
+
+/**
+ * @brief Send a tx batch download to the target.
+ * @details
+ *     This function is different from above in that
+ *     it accepts a list of msdu's to be downloaded as a batch
+ *
+ * @param pdev -  the phy dev
+ * @param msdu_list - the Head pointer to the Tx Batch
+ * @param num_msdus - Total msdus chained in msdu_list
+ */
+
+void
+ol_tx_send_batch(struct ol_txrx_pdev_t *pdev,
+		 qdf_nbuf_t msdu_list, int num_msdus);
+
+/**
+ * @brief Send a tx frame with a non-std header or payload type to the target.
+ * @details
+ *
+ * @param pdev -  the phy dev
+ * @param vdev - the virtual device sending the data
+ *      (for specifying the transmitter address for multicast / broadcast data)
+ * @param netbuf - the tx frame
+ * @param pkt_type - what kind of non-std frame is being sent
+ */
+void
+ol_tx_send_nonstd(struct ol_txrx_pdev_t *pdev,
+		  struct ol_tx_desc_t *tx_desc,
+		  qdf_nbuf_t msdu, enum htt_pkt_type pkt_type);
+
+#ifdef QCA_COMPUTE_TX_DELAY
+/**
+ * ol_tx_set_compute_interval() - update compute interval period for TSM stats
+ * @ppdev: physical device instance
+ * @interval: interval for stats computation
+ *
+ * Return: NONE
+ */
+void ol_tx_set_compute_interval(struct cdp_pdev *ppdev, uint32_t interval);
+
+/**
+ * ol_tx_packet_count() - Return the uplink (transmitted) packet counts
+ * @ppdev: physical device instance
+ * @out_packet_count: number of packets transmitted
+ * @out_packet_loss_count: number of packets lost
+ * @category: access category of interest
+ *
+ * This function will be called for getting uplink packet count and
+ * loss count for given stream (access category) a regular interval.
+ * This also resets the counters hence, the value returned is packets
+ * counted in last 5(default) second interval. These counter are
+ * incremented per access category in ol_tx_completion_handler()
+ *
+ * Return: NONE
+ */
+void
+ol_tx_packet_count(struct cdp_pdev *ppdev,
+		   uint16_t *out_packet_count,
+		   uint16_t *out_packet_loss_count, int category);
+
+/**
+ * ol_tx_delay() - get tx packet delay
+ * @ppdev: physical device instance
+ * @queue_delay_microsec: tx packet delay within queue, usec
+ * @tx_delay_microsec: tx packet delay, usec
+ * @category: packet category
+ *
+ * Return: NONE
+ */
+void
+ol_tx_delay(struct cdp_pdev *ppdev,
+	    uint32_t *queue_delay_microsec,
+	    uint32_t *tx_delay_microsec, int category);
+
+/**
+ * ol_tx_delay_hist() - get tx packet delay histogram
+ * @ppdev: physical device instance
+ * @report_bin_values: bin
+ * @category: packet category
+ *
+ * Return: NONE
+ */
+void
+ol_tx_delay_hist(struct cdp_pdev *ppdev,
+		 uint16_t *report_bin_values, int category);
+#endif /* QCA_COMPUTE_TX_DELAY */
+
+/**
+ * ol_txrx_flow_control_cb() - call osif flow control callback
+ * @vdev: vdev handle
+ * @tx_resume: tx resume flag
+ *
+ * Return: none
+ */
+void ol_txrx_flow_control_cb(struct cdp_vdev *vdev, bool tx_resume);
+
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || (defined(CONFIG_HL_SUPPORT) && \
+	 defined(QCA_HL_NETDEV_FLOW_CONTROL))
+void ol_tx_flow_ct_unpause_os_q(ol_txrx_pdev_handle pdev);
+#else
+static inline void ol_tx_flow_ct_unpause_os_q(ol_txrx_pdev_handle pdev)
+{
+}
+#endif
+#endif /* _OL_TX_SEND__H_ */
diff --git a/core/dp/txrx/ol_tx_throttle.c b/core/dp/txrx/ol_tx_throttle.c
new file mode 100644
index 0000000..486b259
--- /dev/null
+++ b/core/dp/txrx/ol_tx_throttle.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_atomic.h>         /* qdf_atomic_read, etc. */
+#include <ol_cfg.h>             /* ol_cfg_addba_retry */
+#include <htt.h>                /* HTT_TX_EXT_TID_MGMT */
+#include <ol_htt_tx_api.h>      /* htt_tx_desc_tid */
+#include <ol_txrx_api.h>        /* ol_txrx_vdev_handle */
+#include <ol_txrx_ctrl_api.h>   /* ol_txrx_sync, ol_tx_addba_conf */
+#include <cdp_txrx_tx_throttle.h>
+#include <ol_ctrl_txrx_api.h>   /* ol_ctrl_addba_req */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT1, etc. */
+#include <ol_tx_desc.h>         /* ol_tx_desc, ol_tx_desc_frame_list_free */
+#include <ol_tx.h>              /* ol_tx_vdev_ll_pause_queue_send */
+#include <ol_tx_sched.h>	/* ol_tx_sched_notify, etc. */
+#include <ol_tx_queue.h>
+#include <ol_txrx.h>          /* ol_tx_desc_pool_size_hl */
+#include <ol_txrx_dbg.h>        /* ENABLE_TX_QUEUE_LOG */
+#include <qdf_types.h>          /* bool */
+#include "cdp_txrx_flow_ctrl_legacy.h"
+#include <ol_txrx_peer_find.h>
+#include <cdp_txrx_handle.h>
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+/**
+ * ol_txrx_thermal_pause() - pause due to thermal mitigation
+ * @pdev: pdev handle
+ *
+ * Return: none
+ */
+static inline
+void ol_txrx_thermal_pause(struct ol_txrx_pdev_t *pdev)
+{
+	ol_txrx_pdev_pause(pdev, OL_TXQ_PAUSE_REASON_THERMAL_MITIGATION);
+}
+
+/**
+ * ol_txrx_thermal_unpause() - unpause due to thermal mitigation
+ * @pdev: pdev handle
+ *
+ * Return: none
+ */
+static inline
+void ol_txrx_thermal_unpause(struct ol_txrx_pdev_t *pdev)
+{
+	ol_txrx_pdev_unpause(pdev, OL_TXQ_PAUSE_REASON_THERMAL_MITIGATION);
+}
+#else
+/**
+ * ol_txrx_thermal_pause() - pause due to thermal mitigation
+ * @pdev: pdev handle
+ *
+ * Return: none
+ */
+static inline
+void ol_txrx_thermal_pause(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+/**
+ * ol_txrx_thermal_unpause() - unpause due to thermal mitigation
+ * @pdev: pdev handle
+ *
+ * Return: none
+ */
+static inline
+void ol_txrx_thermal_unpause(struct ol_txrx_pdev_t *pdev)
+{
+	ol_tx_pdev_ll_pause_queue_send_all(pdev);
+}
+#endif
+
+static void ol_tx_pdev_throttle_phase_timer(void *context)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)context;
+	int ms;
+	enum throttle_level cur_level;
+	enum throttle_phase cur_phase;
+
+	/* update the phase */
+	pdev->tx_throttle.current_throttle_phase++;
+
+	if (pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_MAX)
+		pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF;
+
+	if (pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_OFF) {
+		/* Traffic is stopped */
+		ol_txrx_dbg(
+				   "throttle phase --> OFF\n");
+		ol_txrx_throttle_pause(pdev);
+		ol_txrx_thermal_pause(pdev);
+		cur_level = pdev->tx_throttle.current_throttle_level;
+		cur_phase = pdev->tx_throttle.current_throttle_phase;
+		ms = pdev->tx_throttle.throttle_time_ms[cur_level][cur_phase];
+		if (pdev->tx_throttle.current_throttle_level !=
+				THROTTLE_LEVEL_0) {
+			ol_txrx_dbg(
+					   "start timer %d ms\n", ms);
+			qdf_timer_start(&pdev->tx_throttle.
+							phase_timer, ms);
+		}
+	} else {
+		/* Traffic can go */
+		ol_txrx_dbg(
+					"throttle phase --> ON\n");
+		ol_txrx_throttle_unpause(pdev);
+		ol_txrx_thermal_unpause(pdev);
+		cur_level = pdev->tx_throttle.current_throttle_level;
+		cur_phase = pdev->tx_throttle.current_throttle_phase;
+		ms = pdev->tx_throttle.throttle_time_ms[cur_level][cur_phase];
+		if (pdev->tx_throttle.current_throttle_level !=
+		    THROTTLE_LEVEL_0) {
+			ol_txrx_dbg("start timer %d ms\n", ms);
+			qdf_timer_start(&pdev->tx_throttle.phase_timer,	ms);
+		}
+	}
+}
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+static void ol_tx_pdev_throttle_tx_timer(void *context)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)context;
+
+	ol_tx_pdev_ll_pause_queue_send_all(pdev);
+}
+#endif
+
+#ifdef CONFIG_HL_SUPPORT
+
+/**
+ * ol_tx_set_throttle_phase_time() - Set the thermal mitgation throttle phase
+ *				     and time
+ * @pdev: the peer device object
+ * @level: throttle phase level
+ * @ms: throttle time
+ *
+ * Return: None
+ */
+static void
+ol_tx_set_throttle_phase_time(struct ol_txrx_pdev_t *pdev, int level, int *ms)
+{
+	qdf_timer_stop(&pdev->tx_throttle.phase_timer);
+
+	/* Set the phase */
+	if (level != THROTTLE_LEVEL_0) {
+		pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF;
+		*ms = pdev->tx_throttle.throttle_time_ms[level]
+						[THROTTLE_PHASE_OFF];
+
+		/* pause all */
+		ol_txrx_throttle_pause(pdev);
+	} else {
+		pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_ON;
+		*ms = pdev->tx_throttle.throttle_time_ms[level]
+						[THROTTLE_PHASE_ON];
+
+		/* unpause all */
+		ol_txrx_throttle_unpause(pdev);
+	}
+}
+#else
+
+static void
+ol_tx_set_throttle_phase_time(struct ol_txrx_pdev_t *pdev, int level, int *ms)
+{
+	/* Reset the phase */
+	pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF;
+
+	/* Start with the new time */
+	*ms = pdev->tx_throttle.
+		throttle_time_ms[level][THROTTLE_PHASE_OFF];
+
+	qdf_timer_stop(&pdev->tx_throttle.phase_timer);
+}
+#endif
+
+void ol_tx_throttle_set_level(struct cdp_pdev *ppdev, int level)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	int ms = 0;
+
+	if (level >= THROTTLE_LEVEL_MAX) {
+		ol_txrx_dbg(
+			   "%s invalid throttle level set %d, ignoring\n",
+			   __func__, level);
+		return;
+	}
+
+	ol_txrx_info("Setting throttle level %d\n", level);
+
+	/* Set the current throttle level */
+	pdev->tx_throttle.current_throttle_level = (enum throttle_level)level;
+
+	ol_tx_set_throttle_phase_time(pdev, level, &ms);
+
+	if (level != THROTTLE_LEVEL_0)
+		qdf_timer_start(&pdev->tx_throttle.phase_timer, ms);
+}
+
+void ol_tx_throttle_init_period(struct cdp_pdev *ppdev, int period,
+				uint8_t *dutycycle_level)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	int i;
+
+	/* Set the current throttle level */
+	pdev->tx_throttle.throttle_period_ms = period;
+
+	ol_txrx_dbg("level  OFF  ON\n");
+	for (i = 0; i < THROTTLE_LEVEL_MAX; i++) {
+		pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_ON] =
+			pdev->tx_throttle.throttle_period_ms -
+				((dutycycle_level[i] *
+				  pdev->tx_throttle.throttle_period_ms) / 100);
+		pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_OFF] =
+			pdev->tx_throttle.throttle_period_ms -
+			pdev->tx_throttle.throttle_time_ms[
+				i][THROTTLE_PHASE_ON];
+		ol_txrx_dbg("%d      %d    %d\n", i,
+			    pdev->tx_throttle.
+			    throttle_time_ms[i][THROTTLE_PHASE_OFF],
+			    pdev->tx_throttle.
+			    throttle_time_ms[i][THROTTLE_PHASE_ON]);
+	}
+}
+
+void ol_tx_throttle_init(struct ol_txrx_pdev_t *pdev)
+{
+	uint32_t throttle_period;
+	uint8_t dutycycle_level[THROTTLE_LEVEL_MAX];
+	int i;
+
+	pdev->tx_throttle.current_throttle_level = THROTTLE_LEVEL_0;
+	pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF;
+	qdf_spinlock_create(&pdev->tx_throttle.mutex);
+
+	throttle_period = ol_cfg_throttle_period_ms(pdev->ctrl_pdev);
+
+	for (i = 0; i < THROTTLE_LEVEL_MAX; i++)
+		dutycycle_level[i] =
+			ol_cfg_throttle_duty_cycle_level(pdev->ctrl_pdev, i);
+
+	ol_tx_throttle_init_period((struct cdp_pdev *)pdev,
+				   throttle_period, &dutycycle_level[0]);
+
+	qdf_timer_init(pdev->osdev, &pdev->tx_throttle.phase_timer,
+		       ol_tx_pdev_throttle_phase_timer, pdev,
+		       QDF_TIMER_TYPE_SW);
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+	qdf_timer_init(pdev->osdev, &pdev->tx_throttle.tx_timer,
+		       ol_tx_pdev_throttle_tx_timer, pdev, QDF_TIMER_TYPE_SW);
+#endif
+
+	pdev->tx_throttle.tx_threshold = THROTTLE_TX_THRESHOLD;
+}
+
+void
+ol_txrx_throttle_pause(ol_txrx_pdev_handle pdev)
+{
+	qdf_spin_lock_bh(&pdev->tx_throttle.mutex);
+
+	if (pdev->tx_throttle.is_paused) {
+		qdf_spin_unlock_bh(&pdev->tx_throttle.mutex);
+		return;
+	}
+
+	pdev->tx_throttle.is_paused = true;
+	qdf_spin_unlock_bh(&pdev->tx_throttle.mutex);
+	ol_txrx_pdev_pause(pdev, 0);
+}
+
+void
+ol_txrx_throttle_unpause(ol_txrx_pdev_handle pdev)
+{
+	qdf_spin_lock_bh(&pdev->tx_throttle.mutex);
+
+	if (!pdev->tx_throttle.is_paused) {
+		qdf_spin_unlock_bh(&pdev->tx_throttle.mutex);
+		return;
+	}
+
+	pdev->tx_throttle.is_paused = false;
+	qdf_spin_unlock_bh(&pdev->tx_throttle.mutex);
+	ol_txrx_pdev_unpause(pdev, 0);
+}
diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c
new file mode 100644
index 0000000..6a983e2
--- /dev/null
+++ b/core/dp/txrx/ol_txrx.c
@@ -0,0 +1,5675 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*=== includes ===*/
+/* header files for OS primitives */
+#include <osdep.h>              /* uint32_t, etc. */
+#include <qdf_mem.h>         /* qdf_mem_malloc,free */
+#include <qdf_types.h>          /* qdf_device_t, qdf_print */
+#include <qdf_lock.h>           /* qdf_spinlock */
+#include <qdf_atomic.h>         /* qdf_atomic_read */
+#include <qdf_debugfs.h>
+
+/* header files for utilities */
+#include <cds_queue.h>          /* TAILQ */
+
+/* header files for configuration API */
+#include <ol_cfg.h>             /* ol_cfg_is_high_latency */
+#include <ol_if_athvar.h>
+
+/* header files for HTT API */
+#include <ol_htt_api.h>
+#include <ol_htt_tx_api.h>
+
+/* header files for our own APIs */
+#include <ol_txrx_api.h>
+#include <ol_txrx_dbg.h>
+#include <cdp_txrx_ocb.h>
+#include <ol_txrx_ctrl_api.h>
+#include <cdp_txrx_stats.h>
+#include <ol_txrx_osif_api.h>
+/* header files for our internal definitions */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT, etc. */
+#include <wdi_event.h>          /* WDI events */
+#include <ol_tx.h>              /* ol_tx_ll */
+#include <ol_rx.h>              /* ol_rx_deliver */
+#include <ol_txrx_peer_find.h>  /* ol_txrx_peer_find_attach, etc. */
+#include <ol_rx_pn.h>           /* ol_rx_pn_check, etc. */
+#include <ol_rx_fwd.h>          /* ol_rx_fwd_check, etc. */
+#include <ol_rx_reorder_timeout.h>      /* OL_RX_REORDER_TIMEOUT_INIT, etc. */
+#include <ol_rx_reorder.h>
+#include <ol_tx_send.h>         /* ol_tx_discard_target_frms */
+#include <ol_tx_desc.h>         /* ol_tx_desc_frame_free */
+#include <ol_tx_queue.h>
+#include <ol_tx_sched.h>           /* ol_tx_sched_attach, etc. */
+#include <ol_txrx.h>
+#include <ol_txrx_types.h>
+#include <cdp_txrx_flow_ctrl_legacy.h>
+#include <cdp_txrx_bus.h>
+#include <cdp_txrx_ipa.h>
+#include <cdp_txrx_pmf.h>
+#include "wma.h"
+#include "hif.h"
+#include "hif_main.h"
+#include <cdp_txrx_peer_ops.h>
+#ifndef REMOVE_PKT_LOG
+#include "pktlog_ac.h"
+#endif
+#include <wlan_policy_mgr_api.h>
+#include "epping_main.h"
+#include <a_types.h>
+#include <cdp_txrx_handle.h>
+#include "wlan_qct_sys.h"
+
+#include <htt_internal.h>
+#include <ol_txrx_ipa.h>
+#include "wlan_roam_debug.h"
+#include "cfg_ucfg_api.h"
+
+
+#define DPT_DEBUGFS_PERMS	(QDF_FILE_USR_READ |	\
+				QDF_FILE_USR_WRITE |	\
+				QDF_FILE_GRP_READ |	\
+				QDF_FILE_OTH_READ)
+
+#define DPT_DEBUGFS_NUMBER_BASE	10
+/**
+ * enum dpt_set_param_debugfs - dpt set params
+ * @DPT_SET_PARAM_PROTO_BITMAP : set proto bitmap
+ * @DPT_SET_PARAM_NR_RECORDS: set num of records
+ * @DPT_SET_PARAM_VERBOSITY: set verbosity
+ */
+enum dpt_set_param_debugfs {
+	DPT_SET_PARAM_PROTO_BITMAP = 1,
+	DPT_SET_PARAM_NR_RECORDS = 2,
+	DPT_SET_PARAM_VERBOSITY = 3,
+	DPT_SET_PARAM_MAX,
+};
+
+QDF_STATUS ol_txrx_peer_state_update(struct cdp_pdev *pdev,
+				     uint8_t *peer_mac,
+				     enum ol_txrx_peer_state state);
+static void ol_vdev_rx_set_intrabss_fwd(struct cdp_vdev *vdev,
+		bool val);
+int ol_txrx_get_tx_pending(struct cdp_pdev *pdev_handle);
+extern void
+ol_txrx_set_wmm_param(struct cdp_pdev *data_pdev,
+		      struct ol_tx_wmm_param_t wmm_param);
+
+extern void ol_txrx_get_pn_info(void *ppeer, uint8_t **last_pn_valid,
+		    uint64_t **last_pn, uint32_t **rmf_pn_replays);
+
+/* thresh for peer's cached buf queue beyond which the elements are dropped */
+#define OL_TXRX_CACHED_BUFQ_THRESH 128
+
+/**
+ * ol_tx_mark_first_wakeup_packet() - set flag to indicate that
+ *    fw is compatible for marking first packet after wow wakeup
+ * @value: 1 for enabled/ 0 for disabled
+ *
+ * Return: None
+ */
+static void ol_tx_mark_first_wakeup_packet(uint8_t value)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		ol_txrx_err(
+			"%s: pdev is NULL\n", __func__);
+		return;
+	}
+
+	htt_mark_first_wakeup_packet(pdev->htt_pdev, value);
+}
+
+/**
+ * ol_tx_set_is_mgmt_over_wmi_enabled() - set flag to indicate that mgmt over
+ *                                        wmi is enabled or not.
+ * @value: 1 for enabled/ 0 for disable
+ *
+ * Return: None
+ */
+void ol_tx_set_is_mgmt_over_wmi_enabled(uint8_t value)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		qdf_print("%s: pdev is NULL\n", __func__);
+		return;
+	}
+	pdev->is_mgmt_over_wmi_enabled = value;
+}
+
+/**
+ * ol_tx_get_is_mgmt_over_wmi_enabled() - get value of is_mgmt_over_wmi_enabled
+ *
+ * Return: is_mgmt_over_wmi_enabled
+ */
+uint8_t ol_tx_get_is_mgmt_over_wmi_enabled(void)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		qdf_print("%s: pdev is NULL\n", __func__);
+		return 0;
+	}
+	return pdev->is_mgmt_over_wmi_enabled;
+}
+
+
+#ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID
+static void *
+ol_txrx_find_peer_by_addr_and_vdev(struct cdp_pdev *ppdev,
+	struct cdp_vdev *pvdev, uint8_t *peer_addr, uint8_t *peer_id)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	struct ol_txrx_peer_t *peer;
+
+	peer = ol_txrx_peer_vdev_find_hash(pdev, vdev, peer_addr, 0, 1);
+	if (!peer)
+		return NULL;
+	*peer_id = peer->local_id;
+	ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL);
+	return peer;
+}
+
+static QDF_STATUS ol_txrx_get_vdevid(void *ppeer, uint8_t *vdev_id)
+{
+	struct ol_txrx_peer_t *peer = ppeer;
+
+	if (!peer) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "peer argument is null!!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*vdev_id = peer->vdev->vdev_id;
+	return QDF_STATUS_SUCCESS;
+}
+
+static struct cdp_vdev *ol_txrx_get_vdev_by_sta_id(struct cdp_pdev *ppdev,
+						   uint8_t sta_id)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	struct ol_txrx_peer_t *peer = NULL;
+	ol_txrx_vdev_handle vdev;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "PDEV not found for sta_id [%d]", sta_id);
+		return NULL;
+	}
+
+	peer = ol_txrx_peer_get_ref_by_local_id((struct cdp_pdev *)pdev, sta_id,
+						PEER_DEBUG_ID_OL_INTERNAL);
+	if (!peer) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "PEER [%d] not found", sta_id);
+		return NULL;
+	}
+
+	vdev = peer->vdev;
+	ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL);
+
+	return (struct cdp_vdev *)vdev;
+}
+
+/**
+ * ol_txrx_find_peer_by_addr() - find peer via peer mac addr and peer_id
+ * @ppdev: pointer of type cdp_pdev
+ * @peer_addr: peer mac addr
+ * @peer_id: pointer to fill in the value of peer->local_id for caller
+ *
+ * This function finds a peer with given mac address and returns its peer_id.
+ * Note that this function does not increment the peer->ref_cnt.
+ * This means that the peer may be deleted in some other parallel context after
+ * its been found.
+ *
+ * Return: peer handle if peer is found, NULL if peer is not found.
+ */
+void *ol_txrx_find_peer_by_addr(struct cdp_pdev *ppdev,
+				uint8_t *peer_addr,
+				uint8_t *peer_id)
+{
+	struct ol_txrx_peer_t *peer;
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	peer = ol_txrx_peer_find_hash_find_get_ref(pdev, peer_addr, 0, 1,
+						   PEER_DEBUG_ID_OL_INTERNAL);
+	if (!peer)
+		return NULL;
+	*peer_id = peer->local_id;
+	ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL);
+	return peer;
+}
+
+/**
+ * ol_txrx_peer_get_ref_by_addr() - get peer ref via peer mac addr and peer_id
+ * @pdev: pointer of type ol_txrx_pdev_handle
+ * @peer_addr: peer mac addr
+ * @peer_id: pointer to fill in the value of peer->local_id for caller
+ *
+ * This function finds the peer with given mac address and returns its peer_id.
+ * Note that this function increments the peer->ref_cnt.
+ * This makes sure that peer will be valid. This also means the caller needs to
+ * call the corresponding API - ol_txrx_peer_release_ref to delete the peer
+ * reference.
+ * Sample usage:
+ *    {
+ *      //the API call below increments the peer->ref_cnt
+ *      peer = ol_txrx_peer_get_ref_by_addr(pdev, peer_addr, peer_id, dbg_id);
+ *
+ *      // Once peer usage is done
+ *
+ *      //the API call below decrements the peer->ref_cnt
+ *       ol_txrx_peer_release_ref(peer, dbg_id);
+ *    }
+ *
+ * Return: peer handle if the peer is found, NULL if peer is not found.
+ */
+ol_txrx_peer_handle ol_txrx_peer_get_ref_by_addr(ol_txrx_pdev_handle pdev,
+						 u8 *peer_addr,
+						 u8 *peer_id,
+						 enum peer_debug_id_type dbg_id)
+{
+	struct ol_txrx_peer_t *peer;
+
+	peer = ol_txrx_peer_find_hash_find_get_ref(pdev, peer_addr, 0, 1,
+						   dbg_id);
+	if (!peer)
+		return NULL;
+	*peer_id = peer->local_id;
+	return peer;
+}
+
+static uint16_t ol_txrx_local_peer_id(void *ppeer)
+{
+	ol_txrx_peer_handle peer = ppeer;
+
+	return peer->local_id;
+}
+
+/**
+ * @brief Find a txrx peer handle from a peer's local ID
+ * @details
+ *  The control SW typically uses the txrx peer handle to refer to the peer.
+ *  In unusual circumstances, if it is infeasible for the control SW maintain
+ *  the txrx peer handle but it can maintain a small integer local peer ID,
+ *  this function allows the peer handled to be retrieved, based on the local
+ *  peer ID.
+ *
+ * @param pdev - the data physical device object
+ * @param local_peer_id - the ID txrx assigned locally to the peer in question
+ * @return handle to the txrx peer object
+ */
+ol_txrx_peer_handle
+ol_txrx_peer_find_by_local_id(struct cdp_pdev *ppdev,
+			      uint8_t local_peer_id)
+{
+	struct ol_txrx_peer_t *peer;
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	if ((local_peer_id == OL_TXRX_INVALID_LOCAL_PEER_ID) ||
+	    (local_peer_id >= OL_TXRX_NUM_LOCAL_PEER_IDS)) {
+		return NULL;
+	}
+
+	qdf_spin_lock_bh(&pdev->local_peer_ids.lock);
+	peer = pdev->local_peer_ids.map[local_peer_id];
+	qdf_spin_unlock_bh(&pdev->local_peer_ids.lock);
+	return peer;
+}
+
+/**
+ * @brief Find a txrx peer handle from a peer's local ID
+ * @param pdev - the data physical device object
+ * @param local_peer_id - the ID txrx assigned locally to the peer in question
+ * @dbg_id - debug_id to track caller
+ * @return handle to the txrx peer object
+ * @details
+ *  The control SW typically uses the txrx peer handle to refer to the peer.
+ *  In unusual circumstances, if it is infeasible for the control SW maintain
+ *  the txrx peer handle but it can maintain a small integer local peer ID,
+ *  this function allows the peer handled to be retrieved, based on the local
+ *  peer ID.
+ *
+ * Note that this function increments the peer->ref_cnt.
+ * This makes sure that peer will be valid. This also means the caller needs to
+ * call the corresponding API -
+ *          ol_txrx_peer_release_ref
+ *
+ * reference.
+ * Sample usage:
+ *    {
+ *      //the API call below increments the peer->ref_cnt
+ *      peer = ol_txrx_peer_get_ref_by_local_id(pdev,local_peer_id, dbg_id);
+ *
+ *      // Once peer usage is done
+ *
+ *      //the API call below decrements the peer->ref_cnt
+ *      ol_txrx_peer_release_ref(peer, dbg_id);
+ *    }
+ *
+ * Return: peer handle if the peer is found, NULL if peer is not found.
+ */
+ol_txrx_peer_handle
+ol_txrx_peer_get_ref_by_local_id(struct cdp_pdev *ppdev,
+			      uint8_t local_peer_id,
+			      enum peer_debug_id_type dbg_id)
+{
+	struct ol_txrx_peer_t *peer = NULL;
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	if ((local_peer_id == OL_TXRX_INVALID_LOCAL_PEER_ID) ||
+	    (local_peer_id >= OL_TXRX_NUM_LOCAL_PEER_IDS)) {
+		return NULL;
+	}
+
+	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+	qdf_spin_lock_bh(&pdev->local_peer_ids.lock);
+	peer = pdev->local_peer_ids.map[local_peer_id];
+	qdf_spin_unlock_bh(&pdev->local_peer_ids.lock);
+	if (peer && peer->valid)
+		ol_txrx_peer_get_ref(peer, dbg_id);
+	else
+		peer = NULL;
+	qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+
+	return peer;
+}
+
+static void ol_txrx_local_peer_id_pool_init(struct ol_txrx_pdev_t *pdev)
+{
+	int i;
+
+	/* point the freelist to the first ID */
+	pdev->local_peer_ids.freelist = 0;
+
+	/* link each ID to the next one */
+	for (i = 0; i < OL_TXRX_NUM_LOCAL_PEER_IDS; i++) {
+		pdev->local_peer_ids.pool[i] = i + 1;
+		pdev->local_peer_ids.map[i] = NULL;
+	}
+
+	/* link the last ID to itself, to mark the end of the list */
+	i = OL_TXRX_NUM_LOCAL_PEER_IDS;
+	pdev->local_peer_ids.pool[i] = i;
+
+	qdf_spinlock_create(&pdev->local_peer_ids.lock);
+}
+
+static void
+ol_txrx_local_peer_id_alloc(struct ol_txrx_pdev_t *pdev,
+			    struct ol_txrx_peer_t *peer)
+{
+	int i;
+
+	qdf_spin_lock_bh(&pdev->local_peer_ids.lock);
+	i = pdev->local_peer_ids.freelist;
+	if (pdev->local_peer_ids.pool[i] == i) {
+		/* the list is empty, except for the list-end marker */
+		peer->local_id = OL_TXRX_INVALID_LOCAL_PEER_ID;
+	} else {
+		/* take the head ID and advance the freelist */
+		peer->local_id = i;
+		pdev->local_peer_ids.freelist = pdev->local_peer_ids.pool[i];
+		pdev->local_peer_ids.map[i] = peer;
+	}
+	qdf_spin_unlock_bh(&pdev->local_peer_ids.lock);
+}
+
+static void
+ol_txrx_local_peer_id_free(struct ol_txrx_pdev_t *pdev,
+			   struct ol_txrx_peer_t *peer)
+{
+	int i = peer->local_id;
+
+	if ((i == OL_TXRX_INVALID_LOCAL_PEER_ID) ||
+	    (i >= OL_TXRX_NUM_LOCAL_PEER_IDS)) {
+		return;
+	}
+	/* put this ID on the head of the freelist */
+	qdf_spin_lock_bh(&pdev->local_peer_ids.lock);
+	pdev->local_peer_ids.pool[i] = pdev->local_peer_ids.freelist;
+	pdev->local_peer_ids.freelist = i;
+	pdev->local_peer_ids.map[i] = NULL;
+	qdf_spin_unlock_bh(&pdev->local_peer_ids.lock);
+}
+
+static void ol_txrx_local_peer_id_cleanup(struct ol_txrx_pdev_t *pdev)
+{
+	qdf_spinlock_destroy(&pdev->local_peer_ids.lock);
+}
+
+#else
+#define ol_txrx_local_peer_id_pool_init(pdev)   /* no-op */
+#define ol_txrx_local_peer_id_alloc(pdev, peer) /* no-op */
+#define ol_txrx_local_peer_id_free(pdev, peer)  /* no-op */
+#define ol_txrx_local_peer_id_cleanup(pdev)     /* no-op */
+#endif
+
+#if defined(CONFIG_DP_TRACE) && defined(WLAN_DEBUGFS)
+/**
+ * ol_txrx_read_dpt_buff_debugfs() - read dp trace buffer
+ * @file: file to read
+ * @arg: pdev object
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ol_txrx_read_dpt_buff_debugfs(qdf_debugfs_file_t file,
+						void *arg)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)arg;
+	uint32_t i = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (pdev->state == QDF_DPT_DEBUGFS_STATE_SHOW_STATE_INVALID)
+		return QDF_STATUS_E_INVAL;
+	else if (pdev->state == QDF_DPT_DEBUGFS_STATE_SHOW_COMPLETE) {
+		pdev->state = QDF_DPT_DEBUGFS_STATE_SHOW_STATE_INIT;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	i = qdf_dpt_get_curr_pos_debugfs(file, pdev->state);
+	status =  qdf_dpt_dump_stats_debugfs(file, i);
+	if (status == QDF_STATUS_E_FAILURE)
+		pdev->state = QDF_DPT_DEBUGFS_STATE_SHOW_IN_PROGRESS;
+	else if (status == QDF_STATUS_SUCCESS)
+		pdev->state = QDF_DPT_DEBUGFS_STATE_SHOW_COMPLETE;
+
+	return status;
+}
+
+/**
+ * ol_txrx_conv_str_to_int_debugfs() - convert string to int
+ * @buf: buffer containing string
+ * @len: buffer len
+ * @proto_bitmap: defines the protocol to be tracked
+ * @nr_records: defines the nth packet which is traced
+ * @verbosity: defines the verbosity level
+ *
+ * This function expects char buffer to be null terminated.
+ * Otherwise results could be unexpected values.
+ *
+ * Return: 0 on success
+ */
+static int ol_txrx_conv_str_to_int_debugfs(char *buf, qdf_size_t len,
+					   int *proto_bitmap,
+					   int *nr_records,
+					   int *verbosity)
+{
+	int num_value = DPT_SET_PARAM_PROTO_BITMAP;
+	int ret, param_value = 0;
+	char *buf_param = buf;
+	int i;
+
+	for (i = 1; i < DPT_SET_PARAM_MAX; i++) {
+		/* Loop till you reach space as kstrtoint operates till
+		 * null character. Replace space with null character
+		 * to read each value.
+		 * terminate the loop either at null terminated char or
+		 * len is 0.
+		 */
+		while (*buf && len) {
+			if (*buf == ' ') {
+				*buf = '\0';
+				buf++;
+				len--;
+				break;
+			}
+			buf++;
+			len--;
+		}
+		/* get the parameter */
+		ret = qdf_kstrtoint(buf_param,
+				    DPT_DEBUGFS_NUMBER_BASE,
+				    &param_value);
+		if (ret) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX,
+				  QDF_TRACE_LEVEL_ERROR,
+				  "%s: Error while parsing buffer. ret %d",
+				  __func__, ret);
+			return ret;
+		}
+		switch (num_value) {
+		case DPT_SET_PARAM_PROTO_BITMAP:
+			*proto_bitmap = param_value;
+			break;
+		case DPT_SET_PARAM_NR_RECORDS:
+			*nr_records = param_value;
+			break;
+		case DPT_SET_PARAM_VERBOSITY:
+			*verbosity = param_value;
+			break;
+		default:
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				  "%s %d: :Set command needs exactly 3 arguments in format <proto_bitmap> <number of record> <Verbosity>.",
+				__func__, __LINE__);
+			break;
+		}
+		num_value++;
+		/*buf_param should now point to the next param value. */
+		buf_param = buf;
+	}
+
+	/* buf is not yet NULL implies more than 3 params are passed. */
+	if (*buf) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s %d: :Set command needs exactly 3 arguments in format <proto_bitmap> <number of record> <Verbosity>.",
+			__func__, __LINE__);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * ol_txrx_write_dpt_buff_debugfs() - set dp trace parameters
+ * @priv: pdev object
+ * @buf: buff to get value for dpt parameters
+ * @len: buf length
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ol_txrx_write_dpt_buff_debugfs(void *priv,
+					      const char *buf,
+					      qdf_size_t len)
+{
+	int ret;
+	int proto_bitmap = 0;
+	int nr_records = 0;
+	int verbosity = 0;
+	char *buf1 = NULL;
+
+	if (!buf || !len) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: null buffer or len. len %u",
+				__func__, (uint8_t)len);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	buf1 = (char *)qdf_mem_malloc(len);
+	if (!buf1) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: qdf_mem_malloc failure",
+				__func__);
+		return QDF_STATUS_E_FAULT;
+	}
+	qdf_mem_copy(buf1, buf, len);
+	ret = ol_txrx_conv_str_to_int_debugfs(buf1, len, &proto_bitmap,
+					      &nr_records, &verbosity);
+	if (ret) {
+		qdf_mem_free(buf1);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_dpt_set_value_debugfs(proto_bitmap, nr_records, verbosity);
+	qdf_mem_free(buf1);
+	return QDF_STATUS_SUCCESS;
+}
+
+static int ol_txrx_debugfs_init(struct ol_txrx_pdev_t *pdev)
+{
+	pdev->dpt_debugfs_fops.show = ol_txrx_read_dpt_buff_debugfs;
+	pdev->dpt_debugfs_fops.write = ol_txrx_write_dpt_buff_debugfs;
+	pdev->dpt_debugfs_fops.priv = pdev;
+
+	pdev->dpt_stats_log_dir = qdf_debugfs_create_dir("dpt_stats", NULL);
+
+	if (!pdev->dpt_stats_log_dir) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: error while creating debugfs dir for %s",
+				__func__, "dpt_stats");
+		pdev->state = QDF_DPT_DEBUGFS_STATE_SHOW_STATE_INVALID;
+		return -EBUSY;
+	}
+
+	if (!qdf_debugfs_create_file("dump_set_dpt_logs", DPT_DEBUGFS_PERMS,
+				     pdev->dpt_stats_log_dir,
+				     &pdev->dpt_debugfs_fops)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: debug Entry creation failed!",
+				__func__);
+		pdev->state = QDF_DPT_DEBUGFS_STATE_SHOW_STATE_INVALID;
+		return -EBUSY;
+	}
+
+	pdev->state = QDF_DPT_DEBUGFS_STATE_SHOW_STATE_INIT;
+	return 0;
+}
+
+static void ol_txrx_debugfs_exit(ol_txrx_pdev_handle pdev)
+{
+	qdf_debugfs_remove_dir_recursive(pdev->dpt_stats_log_dir);
+}
+#else
+static inline int ol_txrx_debugfs_init(struct ol_txrx_pdev_t *pdev)
+{
+	return 0;
+}
+
+static inline void ol_txrx_debugfs_exit(ol_txrx_pdev_handle pdev)
+{
+}
+#endif
+
+/**
+ * ol_txrx_pdev_attach() - allocate txrx pdev
+ * @ctrl_pdev: cfg pdev
+ * @htc_pdev: HTC pdev
+ * @osdev: os dev
+ *
+ * Return: txrx pdev handle
+ *		  NULL for failure
+ */
+static struct cdp_pdev *
+ol_txrx_pdev_attach(ol_txrx_soc_handle soc,
+		    struct cdp_ctrl_objmgr_pdev *ctrl_pdev,
+		    HTC_HANDLE htc_pdev, qdf_device_t osdev, uint8_t pdev_id)
+{
+	struct ol_txrx_pdev_t *pdev;
+	struct cdp_cfg *cfg_pdev = (struct cdp_cfg *)ctrl_pdev;
+	int i, tid;
+
+	pdev = qdf_mem_malloc(sizeof(*pdev));
+	if (!pdev)
+		goto fail0;
+
+	/* init LL/HL cfg here */
+	pdev->cfg.is_high_latency = ol_cfg_is_high_latency(cfg_pdev);
+	/*
+	 * Credit reporting through HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND
+	 * enabled or not.
+	 */
+	pdev->cfg.credit_update_enabled =
+		ol_cfg_is_credit_update_enabled(cfg_pdev);
+
+	/* Explicitly request TX Completions from FW */
+	pdev->cfg.request_tx_comp = cds_is_ptp_rx_opt_enabled() ||
+		cds_is_packet_log_enabled();
+
+	pdev->cfg.default_tx_comp_req = !ol_cfg_tx_free_at_download(cfg_pdev);
+
+	/* store provided params */
+	pdev->ctrl_pdev = cfg_pdev;
+	pdev->osdev = osdev;
+
+	for (i = 0; i < htt_num_sec_types; i++)
+		pdev->sec_types[i] = (enum ol_sec_type)i;
+
+	TXRX_STATS_INIT(pdev);
+	ol_txrx_tso_stats_init(pdev);
+	ol_txrx_fw_stats_desc_pool_init(pdev, FW_STATS_DESC_POOL_SIZE);
+
+	TAILQ_INIT(&pdev->vdev_list);
+
+	TAILQ_INIT(&pdev->req_list);
+	pdev->req_list_depth = 0;
+	qdf_spinlock_create(&pdev->req_list_spinlock);
+	qdf_spinlock_create(&pdev->tx_mutex);
+
+	/* do initial set up of the peer ID -> peer object lookup map */
+	if (ol_txrx_peer_find_attach(pdev))
+		goto fail1;
+
+	/* initialize the counter of the target's tx buffer availability */
+	qdf_atomic_init(&pdev->target_tx_credit);
+	qdf_atomic_init(&pdev->orig_target_tx_credit);
+
+	if (ol_cfg_is_high_latency(cfg_pdev)) {
+		qdf_spinlock_create(&pdev->tx_queue_spinlock);
+		pdev->tx_sched.scheduler = ol_tx_sched_attach(pdev);
+		if (pdev->tx_sched.scheduler == NULL)
+			goto fail2;
+	}
+	ol_txrx_pdev_txq_log_init(pdev);
+	ol_txrx_pdev_grp_stats_init(pdev);
+
+	pdev->htt_pdev =
+		htt_pdev_alloc(pdev, cfg_pdev, htc_pdev, osdev);
+	if (!pdev->htt_pdev)
+		goto fail3;
+
+	htt_register_rx_pkt_dump_callback(pdev->htt_pdev,
+			ol_rx_pkt_dump_call);
+
+	/*
+	 * Init the tid --> category table.
+	 * Regular tids (0-15) map to their AC.
+	 * Extension tids get their own categories.
+	 */
+	for (tid = 0; tid < OL_TX_NUM_QOS_TIDS; tid++) {
+		int ac = TXRX_TID_TO_WMM_AC(tid);
+
+		pdev->tid_to_ac[tid] = ac;
+	}
+	pdev->tid_to_ac[OL_TX_NON_QOS_TID] =
+		OL_TX_SCHED_WRR_ADV_CAT_NON_QOS_DATA;
+	pdev->tid_to_ac[OL_TX_MGMT_TID] =
+		OL_TX_SCHED_WRR_ADV_CAT_UCAST_MGMT;
+	pdev->tid_to_ac[OL_TX_NUM_TIDS + OL_TX_VDEV_MCAST_BCAST] =
+		OL_TX_SCHED_WRR_ADV_CAT_MCAST_DATA;
+	pdev->tid_to_ac[OL_TX_NUM_TIDS + OL_TX_VDEV_DEFAULT_MGMT] =
+		OL_TX_SCHED_WRR_ADV_CAT_MCAST_MGMT;
+
+	ol_txrx_debugfs_init(pdev);
+
+	return (struct cdp_pdev *)pdev;
+
+fail3:
+	ol_txrx_peer_find_detach(pdev);
+
+fail2:
+	if (ol_cfg_is_high_latency(cfg_pdev))
+		qdf_spinlock_destroy(&pdev->tx_queue_spinlock);
+
+fail1:
+	qdf_spinlock_destroy(&pdev->tx_mutex);
+	ol_txrx_tso_stats_deinit(pdev);
+	ol_txrx_fw_stats_desc_pool_deinit(pdev);
+	qdf_mem_free(pdev);
+
+fail0:
+	return NULL;
+}
+
+#if !defined(REMOVE_PKT_LOG) && !defined(QVIT)
+/**
+ * htt_pkt_log_init() - API to initialize packet log
+ * @handle: pdev handle
+ * @scn: HIF context
+ *
+ * Return: void
+ */
+void htt_pkt_log_init(struct cdp_pdev *ppdev, void *scn)
+{
+	struct ol_txrx_pdev_t *handle = (struct ol_txrx_pdev_t *)ppdev;
+
+	if (handle->pkt_log_init)
+		return;
+
+	if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE &&
+			!QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
+		pktlog_sethandle(&handle->pl_dev, scn);
+		pktlog_set_callback_regtype(PKTLOG_DEFAULT_CALLBACK_REGISTRATION);
+		if (pktlogmod_init(scn))
+			qdf_print("%s: pktlogmod_init failed", __func__);
+		else
+			handle->pkt_log_init = true;
+	}
+}
+
+/**
+ * htt_pktlogmod_exit() - API to cleanup pktlog info
+ * @handle: Pdev handle
+ * @scn: HIF Context
+ *
+ * Return: void
+ */
+static void htt_pktlogmod_exit(struct ol_txrx_pdev_t *handle)
+{
+	if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE &&
+		!QDF_IS_EPPING_ENABLED(cds_get_conparam()) &&
+			handle->pkt_log_init) {
+		pktlogmod_exit(handle);
+		handle->pkt_log_init = false;
+	}
+}
+
+#else
+void htt_pkt_log_init(struct cdp_pdev *pdev_handle, void *ol_sc) { }
+static void htt_pktlogmod_exit(ol_txrx_pdev_handle handle)  { }
+#endif
+
+/**
+ * ol_txrx_pdev_post_attach() - attach txrx pdev
+ * @pdev: txrx pdev
+ *
+ * Return: 0 for success
+ */
+int
+ol_txrx_pdev_post_attach(struct cdp_pdev *ppdev)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	uint16_t i;
+	uint16_t fail_idx = 0;
+	int ret = 0;
+	uint16_t desc_pool_size;
+	struct hif_opaque_softc *osc =  cds_get_context(QDF_MODULE_ID_HIF);
+
+	uint16_t desc_element_size = sizeof(union ol_tx_desc_list_elem_t);
+	union ol_tx_desc_list_elem_t *c_element;
+	unsigned int sig_bit;
+	uint16_t desc_per_page;
+
+	if (!osc) {
+		ret = -EINVAL;
+		goto ol_attach_fail;
+	}
+
+	/*
+	 * For LL, limit the number of host's tx descriptors to match
+	 * the number of target FW tx descriptors.
+	 * This simplifies the FW, by ensuring the host will never
+	 * download more tx descriptors than the target has space for.
+	 * The FW will drop/free low-priority tx descriptors when it
+	 * starts to run low, so that in theory the host should never
+	 * run out of tx descriptors.
+	 */
+
+	/*
+	 * LL - initialize the target credit outselves.
+	 * HL - wait for a HTT target credit initialization
+	 * during htt_attach.
+	 */
+	desc_pool_size = ol_tx_get_desc_global_pool_size(pdev);
+	ol_tx_init_pdev(pdev);
+
+	ol_tx_desc_dup_detect_init(pdev, desc_pool_size);
+
+	ol_tx_setup_fastpath_ce_handles(osc, pdev);
+
+	ret = htt_attach(pdev->htt_pdev, desc_pool_size);
+	if (ret)
+		goto htt_attach_fail;
+
+	/* Attach micro controller data path offload resource */
+	if (ol_cfg_ipa_uc_offload_enabled(pdev->ctrl_pdev)) {
+		ret = htt_ipa_uc_attach(pdev->htt_pdev);
+		if (ret)
+			goto uc_attach_fail;
+	}
+
+	/* Calculate single element reserved size power of 2 */
+	pdev->tx_desc.desc_reserved_size = qdf_get_pwr2(desc_element_size);
+	qdf_mem_multi_pages_alloc(pdev->osdev, &pdev->tx_desc.desc_pages,
+		pdev->tx_desc.desc_reserved_size, desc_pool_size, 0, true);
+	if ((0 == pdev->tx_desc.desc_pages.num_pages) ||
+		(NULL == pdev->tx_desc.desc_pages.cacheable_pages)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			"Page alloc fail");
+		ret = -ENOMEM;
+		goto page_alloc_fail;
+	}
+	desc_per_page = pdev->tx_desc.desc_pages.num_element_per_page;
+	pdev->tx_desc.offset_filter = desc_per_page - 1;
+	/* Calculate page divider to find page number */
+	sig_bit = 0;
+	while (desc_per_page) {
+		sig_bit++;
+		desc_per_page = desc_per_page >> 1;
+	}
+	pdev->tx_desc.page_divider = (sig_bit - 1);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		"page_divider 0x%x, offset_filter 0x%x num elem %d, ol desc num page %d, ol desc per page %d",
+		pdev->tx_desc.page_divider, pdev->tx_desc.offset_filter,
+		desc_pool_size, pdev->tx_desc.desc_pages.num_pages,
+		pdev->tx_desc.desc_pages.num_element_per_page);
+
+	/*
+	 * Each SW tx desc (used only within the tx datapath SW) has a
+	 * matching HTT tx desc (used for downloading tx meta-data to FW/HW).
+	 * Go ahead and allocate the HTT tx desc and link it with the SW tx
+	 * desc now, to avoid doing it during time-critical transmit.
+	 */
+	pdev->tx_desc.pool_size = desc_pool_size;
+	pdev->tx_desc.freelist =
+		(union ol_tx_desc_list_elem_t *)
+		(*pdev->tx_desc.desc_pages.cacheable_pages);
+	c_element = pdev->tx_desc.freelist;
+	for (i = 0; i < desc_pool_size; i++) {
+		void *htt_tx_desc;
+		void *htt_frag_desc = NULL;
+		qdf_dma_addr_t frag_paddr = 0;
+		qdf_dma_addr_t paddr;
+
+		if (i == (desc_pool_size - 1))
+			c_element->next = NULL;
+		else
+			c_element->next = (union ol_tx_desc_list_elem_t *)
+				ol_tx_desc_find(pdev, i + 1);
+
+		htt_tx_desc = htt_tx_desc_alloc(pdev->htt_pdev, &paddr, i);
+		if (!htt_tx_desc) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_FATAL,
+				  "%s: failed to alloc HTT tx desc (%d of %d)",
+				__func__, i, desc_pool_size);
+			fail_idx = i;
+			ret = -ENOMEM;
+			goto desc_alloc_fail;
+		}
+
+		c_element->tx_desc.htt_tx_desc = htt_tx_desc;
+		c_element->tx_desc.htt_tx_desc_paddr = paddr;
+		ret = htt_tx_frag_alloc(pdev->htt_pdev,
+					i, &frag_paddr, &htt_frag_desc);
+		if (ret) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: failed to alloc HTT frag dsc (%d/%d)",
+				__func__, i, desc_pool_size);
+			/* Is there a leak here, is this handling correct? */
+			fail_idx = i;
+			goto desc_alloc_fail;
+		}
+		if (!ret && htt_frag_desc) {
+			/*
+			 * Initialize the first 6 words (TSO flags)
+			 * of the frag descriptor
+			 */
+			memset(htt_frag_desc, 0, 6 * sizeof(uint32_t));
+			c_element->tx_desc.htt_frag_desc = htt_frag_desc;
+			c_element->tx_desc.htt_frag_desc_paddr = frag_paddr;
+		}
+#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS
+		c_element->tx_desc.pkt_type = 0xff;
+#ifdef QCA_COMPUTE_TX_DELAY
+		c_element->tx_desc.entry_timestamp_ticks =
+			0xffffffff;
+#endif
+#endif
+		c_element->tx_desc.id = i;
+		qdf_atomic_init(&c_element->tx_desc.ref_cnt);
+		c_element = c_element->next;
+		fail_idx = i;
+	}
+
+	/* link SW tx descs into a freelist */
+	pdev->tx_desc.num_free = desc_pool_size;
+	ol_txrx_dbg(
+		   "%s first tx_desc:0x%pK Last tx desc:0x%pK\n", __func__,
+		   (uint32_t *) pdev->tx_desc.freelist,
+		   (uint32_t *) (pdev->tx_desc.freelist + desc_pool_size));
+
+	/* check what format of frames are expected to be delivered by the OS */
+	pdev->frame_format = ol_cfg_frame_type(pdev->ctrl_pdev);
+	if (pdev->frame_format == wlan_frm_fmt_native_wifi)
+		pdev->htt_pkt_type = htt_pkt_type_native_wifi;
+	else if (pdev->frame_format == wlan_frm_fmt_802_3) {
+		if (ol_cfg_is_ce_classify_enabled(pdev->ctrl_pdev))
+			pdev->htt_pkt_type = htt_pkt_type_eth2;
+		else
+			pdev->htt_pkt_type = htt_pkt_type_ethernet;
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s Invalid standard frame type: %d",
+			  __func__, pdev->frame_format);
+		ret = -EINVAL;
+		goto control_init_fail;
+	}
+
+	/* setup the global rx defrag waitlist */
+	TAILQ_INIT(&pdev->rx.defrag.waitlist);
+
+	/* configure where defrag timeout and duplicate detection is handled */
+	pdev->rx.flags.defrag_timeout_check =
+		pdev->rx.flags.dup_check =
+		ol_cfg_rx_host_defrag_timeout_duplicate_check(pdev->ctrl_pdev);
+
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+	/* Need to revisit this part. Currently,hardcode to riva's caps */
+	pdev->target_tx_tran_caps = wlan_frm_tran_cap_raw;
+	pdev->target_rx_tran_caps = wlan_frm_tran_cap_raw;
+	/*
+	 * The Riva HW de-aggregate doesn't have capability to generate 802.11
+	 * header for non-first subframe of A-MSDU.
+	 */
+	pdev->sw_subfrm_hdr_recovery_enable = 1;
+	/*
+	 * The Riva HW doesn't have the capability to set Protected Frame bit
+	 * in the MAC header for encrypted data frame.
+	 */
+	pdev->sw_pf_proc_enable = 1;
+
+	if (pdev->frame_format == wlan_frm_fmt_802_3) {
+		/*
+		 * sw llc process is only needed in
+		 * 802.3 to 802.11 transform case
+		 */
+		pdev->sw_tx_llc_proc_enable = 1;
+		pdev->sw_rx_llc_proc_enable = 1;
+	} else {
+		pdev->sw_tx_llc_proc_enable = 0;
+		pdev->sw_rx_llc_proc_enable = 0;
+	}
+
+	switch (pdev->frame_format) {
+	case wlan_frm_fmt_raw:
+		pdev->sw_tx_encap =
+			pdev->target_tx_tran_caps & wlan_frm_tran_cap_raw
+			? 0 : 1;
+		pdev->sw_rx_decap =
+			pdev->target_rx_tran_caps & wlan_frm_tran_cap_raw
+			? 0 : 1;
+		break;
+	case wlan_frm_fmt_native_wifi:
+		pdev->sw_tx_encap =
+			pdev->
+			target_tx_tran_caps & wlan_frm_tran_cap_native_wifi
+			? 0 : 1;
+		pdev->sw_rx_decap =
+			pdev->
+			target_rx_tran_caps & wlan_frm_tran_cap_native_wifi
+			? 0 : 1;
+		break;
+	case wlan_frm_fmt_802_3:
+		pdev->sw_tx_encap =
+			pdev->target_tx_tran_caps & wlan_frm_tran_cap_8023
+			? 0 : 1;
+		pdev->sw_rx_decap =
+			pdev->target_rx_tran_caps & wlan_frm_tran_cap_8023
+			? 0 : 1;
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid std frame type; [en/de]cap: f:%x t:%x r:%x",
+			  pdev->frame_format,
+			  pdev->target_tx_tran_caps, pdev->target_rx_tran_caps);
+		ret = -EINVAL;
+		goto control_init_fail;
+	}
+#endif
+
+	/*
+	 * Determine what rx processing steps are done within the host.
+	 * Possibilities:
+	 * 1.  Nothing - rx->tx forwarding and rx PN entirely within target.
+	 *     (This is unlikely; even if the target is doing rx->tx forwarding,
+	 *     the host should be doing rx->tx forwarding too, as a back up for
+	 *     the target's rx->tx forwarding, in case the target runs short on
+	 *     memory, and can't store rx->tx frames that are waiting for
+	 *     missing prior rx frames to arrive.)
+	 * 2.  Just rx -> tx forwarding.
+	 *     This is the typical configuration for HL, and a likely
+	 *     configuration for LL STA or small APs (e.g. retail APs).
+	 * 3.  Both PN check and rx -> tx forwarding.
+	 *     This is the typical configuration for large LL APs.
+	 * Host-side PN check without rx->tx forwarding is not a valid
+	 * configuration, since the PN check needs to be done prior to
+	 * the rx->tx forwarding.
+	 */
+	if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev)) {
+		/*
+		 * PN check, rx-tx forwarding and rx reorder is done by
+		 * the target
+		 */
+		if (ol_cfg_rx_fwd_disabled(pdev->ctrl_pdev))
+			pdev->rx_opt_proc = ol_rx_in_order_deliver;
+		else
+			pdev->rx_opt_proc = ol_rx_fwd_check;
+	} else {
+		if (ol_cfg_rx_pn_check(pdev->ctrl_pdev)) {
+			if (ol_cfg_rx_fwd_disabled(pdev->ctrl_pdev)) {
+				/*
+				 * PN check done on host,
+				 * rx->tx forwarding not done at all.
+				 */
+				pdev->rx_opt_proc = ol_rx_pn_check_only;
+			} else if (ol_cfg_rx_fwd_check(pdev->ctrl_pdev)) {
+				/*
+				 * Both PN check and rx->tx forwarding done
+				 * on host.
+				 */
+				pdev->rx_opt_proc = ol_rx_pn_check;
+			} else {
+#define TRACESTR01 "invalid config: if rx PN check is on the host,"\
+"rx->tx forwarding check needs to also be on the host"
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "%s: %s", __func__, TRACESTR01);
+#undef TRACESTR01
+				ret = -EINVAL;
+				goto control_init_fail;
+			}
+		} else {
+			/* PN check done on target */
+			if ((!ol_cfg_rx_fwd_disabled(pdev->ctrl_pdev)) &&
+			    ol_cfg_rx_fwd_check(pdev->ctrl_pdev)) {
+				/*
+				 * rx->tx forwarding done on host (possibly as
+				 * back-up for target-side primary rx->tx
+				 * forwarding)
+				 */
+				pdev->rx_opt_proc = ol_rx_fwd_check;
+			} else {
+				/*
+				 * rx->tx forwarding either done in target,
+				 * or not done at all
+				 */
+				pdev->rx_opt_proc = ol_rx_deliver;
+			}
+		}
+	}
+
+	/* initialize mutexes for tx desc alloc and peer lookup */
+	qdf_spinlock_create(&pdev->peer_ref_mutex);
+	qdf_spinlock_create(&pdev->rx.mutex);
+	qdf_spinlock_create(&pdev->last_real_peer_mutex);
+	qdf_spinlock_create(&pdev->peer_map_unmap_lock);
+	OL_TXRX_PEER_STATS_MUTEX_INIT(pdev);
+
+	if (OL_RX_REORDER_TRACE_ATTACH(pdev) != A_OK) {
+		ret = -ENOMEM;
+		goto reorder_trace_attach_fail;
+	}
+
+	if (OL_RX_PN_TRACE_ATTACH(pdev) != A_OK) {
+		ret = -ENOMEM;
+		goto pn_trace_attach_fail;
+	}
+
+#ifdef PERE_IP_HDR_ALIGNMENT_WAR
+	pdev->host_80211_enable = ol_scn_host_80211_enable_get(pdev->ctrl_pdev);
+#endif
+
+	/*
+	 * WDI event attach
+	 */
+	wdi_event_attach(pdev);
+
+	/*
+	 * Initialize rx PN check characteristics for different security types.
+	 */
+	qdf_mem_set(&pdev->rx_pn[0], sizeof(pdev->rx_pn), 0);
+
+	/* TKIP: 48-bit TSC, CCMP: 48-bit PN */
+	pdev->rx_pn[htt_sec_type_tkip].len =
+		pdev->rx_pn[htt_sec_type_tkip_nomic].len =
+			pdev->rx_pn[htt_sec_type_aes_ccmp].len = 48;
+	pdev->rx_pn[htt_sec_type_tkip].cmp =
+		pdev->rx_pn[htt_sec_type_tkip_nomic].cmp =
+			pdev->rx_pn[htt_sec_type_aes_ccmp].cmp = ol_rx_pn_cmp48;
+
+	/* WAPI: 128-bit PN */
+	pdev->rx_pn[htt_sec_type_wapi].len = 128;
+	pdev->rx_pn[htt_sec_type_wapi].cmp = ol_rx_pn_wapi_cmp;
+
+	OL_RX_REORDER_TIMEOUT_INIT(pdev);
+
+	ol_txrx_dbg("Created pdev %pK\n", pdev);
+
+	pdev->cfg.host_addba = ol_cfg_host_addba(pdev->ctrl_pdev);
+
+#ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI
+#define OL_TXRX_RSSI_UPDATE_SHIFT_DEFAULT 3
+
+/* #if 1 -- TODO: clean this up */
+#define OL_TXRX_RSSI_NEW_WEIGHT_DEFAULT	\
+	/* avg = 100% * new + 0% * old */ \
+	(1 << OL_TXRX_RSSI_UPDATE_SHIFT_DEFAULT)
+/*
+ * #else
+ * #define OL_TXRX_RSSI_NEW_WEIGHT_DEFAULT
+ *	//avg = 25% * new + 25% * old
+ *	(1 << (OL_TXRX_RSSI_UPDATE_SHIFT_DEFAULT-2))
+ * #endif
+ */
+	pdev->rssi_update_shift = OL_TXRX_RSSI_UPDATE_SHIFT_DEFAULT;
+	pdev->rssi_new_weight = OL_TXRX_RSSI_NEW_WEIGHT_DEFAULT;
+#endif
+
+	ol_txrx_local_peer_id_pool_init(pdev);
+
+	pdev->cfg.ll_pause_txq_limit =
+		ol_tx_cfg_max_tx_queue_depth_ll(pdev->ctrl_pdev);
+
+	/* TX flow control for peer who is in very bad link status */
+	ol_tx_badpeer_flow_cl_init(pdev);
+
+#ifdef QCA_COMPUTE_TX_DELAY
+	qdf_mem_zero(&pdev->tx_delay, sizeof(pdev->tx_delay));
+	qdf_spinlock_create(&pdev->tx_delay.mutex);
+
+	/* initialize compute interval with 5 seconds (ESE default) */
+	pdev->tx_delay.avg_period_ticks = qdf_system_msecs_to_ticks(5000);
+	{
+		uint32_t bin_width_1000ticks;
+
+		bin_width_1000ticks =
+			qdf_system_msecs_to_ticks
+				(QCA_TX_DELAY_HIST_INTERNAL_BIN_WIDTH_MS
+				 * 1000);
+		/*
+		 * Compute a factor and shift that together are equal to the
+		 * inverse of the bin_width time, so that rather than dividing
+		 * by the bin width time, approximately the same result can be
+		 * obtained much more efficiently by a multiply + shift.
+		 * multiply_factor >> shift = 1 / bin_width_time, so
+		 * multiply_factor = (1 << shift) / bin_width_time.
+		 *
+		 * Pick the shift semi-arbitrarily.
+		 * If we knew statically what the bin_width would be, we could
+		 * choose a shift that minimizes the error.
+		 * Since the bin_width is determined dynamically, simply use a
+		 * shift that is about half of the uint32_t size.  This should
+		 * result in a relatively large multiplier value, which
+		 * minimizes error from rounding the multiplier to an integer.
+		 * The rounding error only becomes significant if the tick units
+		 * are on the order of 1 microsecond.  In most systems, it is
+		 * expected that the tick units will be relatively low-res,
+		 * on the order of 1 millisecond.  In such systems the rounding
+		 * error is negligible.
+		 * It would be more accurate to dynamically try out different
+		 * shifts and choose the one that results in the smallest
+		 * rounding error, but that extra level of fidelity is
+		 * not needed.
+		 */
+		pdev->tx_delay.hist_internal_bin_width_shift = 16;
+		pdev->tx_delay.hist_internal_bin_width_mult =
+			((1 << pdev->tx_delay.hist_internal_bin_width_shift) *
+			 1000 + (bin_width_1000ticks >> 1)) /
+			bin_width_1000ticks;
+	}
+#endif /* QCA_COMPUTE_TX_DELAY */
+
+	/* Thermal Mitigation */
+	ol_tx_throttle_init(pdev);
+
+	ol_tso_seg_list_init(pdev, desc_pool_size);
+
+	ol_tso_num_seg_list_init(pdev, desc_pool_size);
+
+	ol_tx_register_flow_control(pdev);
+
+	return 0;            /* success */
+
+pn_trace_attach_fail:
+	OL_RX_REORDER_TRACE_DETACH(pdev);
+
+reorder_trace_attach_fail:
+	qdf_spinlock_destroy(&pdev->peer_ref_mutex);
+	qdf_spinlock_destroy(&pdev->rx.mutex);
+	qdf_spinlock_destroy(&pdev->last_real_peer_mutex);
+	qdf_spinlock_destroy(&pdev->peer_map_unmap_lock);
+	OL_TXRX_PEER_STATS_MUTEX_DESTROY(pdev);
+
+control_init_fail:
+desc_alloc_fail:
+	for (i = 0; i < fail_idx; i++)
+		htt_tx_desc_free(pdev->htt_pdev,
+			(ol_tx_desc_find(pdev, i))->htt_tx_desc);
+
+	qdf_mem_multi_pages_free(pdev->osdev,
+		&pdev->tx_desc.desc_pages, 0, true);
+
+page_alloc_fail:
+	if (ol_cfg_ipa_uc_offload_enabled(pdev->ctrl_pdev))
+		htt_ipa_uc_detach(pdev->htt_pdev);
+uc_attach_fail:
+	htt_detach(pdev->htt_pdev);
+htt_attach_fail:
+	ol_tx_desc_dup_detect_deinit(pdev);
+ol_attach_fail:
+	return ret;            /* fail */
+}
+
+/**
+ * ol_txrx_pdev_attach_target() - send target configuration
+ *
+ * @pdev - the physical device being initialized
+ *
+ * The majority of the data SW setup are done by the pdev_attach
+ * functions, but this function completes the data SW setup by
+ * sending datapath configuration messages to the target.
+ *
+ * Return: 0 - success 1 - failure
+ */
+static A_STATUS ol_txrx_pdev_attach_target(struct cdp_pdev *ppdev)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	return htt_attach_target(pdev->htt_pdev) == QDF_STATUS_SUCCESS ? 0:1;
+}
+
+/**
+ * ol_tx_free_descs_inuse - free tx descriptors which are in use
+ * @pdev - the physical device for which tx descs need to be freed
+ *
+ * Cycle through the list of TX descriptors (for a pdev) which are in use,
+ * for which TX completion has not been received and free them. Should be
+ * called only when the interrupts are off and all lower layer RX is stopped.
+ * Otherwise there may be a race condition with TX completions.
+ *
+ * Return: None
+ */
+static void ol_tx_free_descs_inuse(ol_txrx_pdev_handle pdev)
+{
+	int i;
+	void *htt_tx_desc;
+	struct ol_tx_desc_t *tx_desc;
+	int num_freed_tx_desc = 0;
+
+	for (i = 0; i < pdev->tx_desc.pool_size; i++) {
+		tx_desc = ol_tx_desc_find(pdev, i);
+		/*
+		 * Confirm that each tx descriptor is "empty", i.e. it has
+		 * no tx frame attached.
+		 * In particular, check that there are no frames that have
+		 * been given to the target to transmit, for which the
+		 * target has never provided a response.
+		 */
+		if (qdf_atomic_read(&tx_desc->ref_cnt)) {
+			ol_txrx_dbg("Warning: freeing tx frame (no compltn)");
+			ol_tx_desc_frame_free_nonstd(pdev,
+						     tx_desc, 1);
+			num_freed_tx_desc++;
+		}
+		htt_tx_desc = tx_desc->htt_tx_desc;
+		htt_tx_desc_free(pdev->htt_pdev, htt_tx_desc);
+	}
+
+	if (num_freed_tx_desc)
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+		"freed %d tx frames for which no resp from target",
+		num_freed_tx_desc);
+
+}
+
+/**
+ * ol_txrx_pdev_pre_detach() - detach the data SW state
+ * @pdev - the data physical device object being removed
+ * @force - delete the pdev (and its vdevs and peers) even if
+ * there are outstanding references by the target to the vdevs
+ * and peers within the pdev
+ *
+ * This function is used when the WLAN driver is being removed to
+ * detach the host data component within the driver.
+ *
+ * Return: None
+ */
+static void ol_txrx_pdev_pre_detach(struct cdp_pdev *ppdev, int force)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	/* preconditions */
+	TXRX_ASSERT2(pdev);
+
+	/* check that the pdev has no vdevs allocated */
+	TXRX_ASSERT1(TAILQ_EMPTY(&pdev->vdev_list));
+
+#ifdef QCA_SUPPORT_TX_THROTTLE
+	/* Thermal Mitigation */
+	qdf_timer_stop(&pdev->tx_throttle.phase_timer);
+	qdf_timer_free(&pdev->tx_throttle.phase_timer);
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+	qdf_timer_stop(&pdev->tx_throttle.tx_timer);
+	qdf_timer_free(&pdev->tx_throttle.tx_timer);
+#endif
+#endif
+
+	if (force) {
+		/*
+		 * The assertion above confirms that all vdevs within this pdev
+		 * were detached.  However, they may not have actually been
+		 * deleted.
+		 * If the vdev had peers which never received a PEER_UNMAP msg
+		 * from the target, then there are still zombie peer objects,
+		 * and the vdev parents of the zombie peers are also zombies,
+		 * hanging around until their final peer gets deleted.
+		 * Go through the peer hash table and delete any peers left.
+		 * As a side effect, this will complete the deletion of any
+		 * vdevs that are waiting for their peers to finish deletion.
+		 */
+		ol_txrx_dbg("Force delete for pdev %pK\n",
+			   pdev);
+		ol_txrx_peer_find_hash_erase(pdev);
+	}
+
+	/* to get flow pool status before freeing descs */
+	ol_tx_dump_flow_pool_info((void *)pdev);
+	ol_tx_free_descs_inuse(pdev);
+	ol_tx_deregister_flow_control(pdev);
+
+	/*
+	 * ol_tso_seg_list_deinit should happen after
+	 * ol_tx_deinit_tx_desc_inuse as it tries to access the tso seg freelist
+	 * which is being de-initilized in ol_tso_seg_list_deinit
+	 */
+	ol_tso_seg_list_deinit(pdev);
+	ol_tso_num_seg_list_deinit(pdev);
+
+	/* Stop the communication between HTT and target at first */
+	htt_detach_target(pdev->htt_pdev);
+
+	qdf_mem_multi_pages_free(pdev->osdev,
+		&pdev->tx_desc.desc_pages, 0, true);
+	pdev->tx_desc.freelist = NULL;
+
+	/* Detach micro controller data path offload resource */
+	if (ol_cfg_ipa_uc_offload_enabled(pdev->ctrl_pdev))
+		htt_ipa_uc_detach(pdev->htt_pdev);
+
+	htt_detach(pdev->htt_pdev);
+	ol_tx_desc_dup_detect_deinit(pdev);
+
+	qdf_spinlock_destroy(&pdev->peer_ref_mutex);
+	qdf_spinlock_destroy(&pdev->last_real_peer_mutex);
+	qdf_spinlock_destroy(&pdev->rx.mutex);
+	qdf_spinlock_destroy(&pdev->peer_map_unmap_lock);
+#ifdef QCA_SUPPORT_TX_THROTTLE
+	/* Thermal Mitigation */
+	qdf_spinlock_destroy(&pdev->tx_throttle.mutex);
+#endif
+
+	/* TX flow control for peer who is in very bad link status */
+	ol_tx_badpeer_flow_cl_deinit(pdev);
+
+	OL_TXRX_PEER_STATS_MUTEX_DESTROY(pdev);
+
+	OL_RX_REORDER_TRACE_DETACH(pdev);
+	OL_RX_PN_TRACE_DETACH(pdev);
+
+	/*
+	 * WDI event detach
+	 */
+	wdi_event_detach(pdev);
+
+	ol_txrx_local_peer_id_cleanup(pdev);
+
+#ifdef QCA_COMPUTE_TX_DELAY
+	qdf_spinlock_destroy(&pdev->tx_delay.mutex);
+#endif
+}
+
+/**
+ * ol_txrx_pdev_detach() - delete the data SW state
+ * @ppdev - the data physical device object being removed
+ * @force - delete the pdev (and its vdevs and peers) even if
+ * there are outstanding references by the target to the vdevs
+ * and peers within the pdev
+ *
+ * This function is used when the WLAN driver is being removed to
+ * remove the host data component within the driver.
+ * All virtual devices within the physical device need to be deleted
+ * (ol_txrx_vdev_detach) before the physical device itself is deleted.
+ *
+ * Return: None
+ */
+static void ol_txrx_pdev_detach(struct cdp_pdev *ppdev, int force)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	struct ol_txrx_stats_req_internal *req, *temp_req;
+	int i = 0;
+
+	/*checking to ensure txrx pdev structure is not NULL */
+	if (!pdev) {
+		ol_txrx_err(
+			   "NULL pdev passed to %s\n", __func__);
+		return;
+	}
+
+	htt_pktlogmod_exit(pdev);
+
+	qdf_spin_lock_bh(&pdev->req_list_spinlock);
+	if (pdev->req_list_depth > 0)
+		ol_txrx_err(
+			"Warning: the txrx req list is not empty, depth=%d\n",
+			pdev->req_list_depth
+			);
+	TAILQ_FOREACH_SAFE(req, &pdev->req_list, req_list_elem, temp_req) {
+		TAILQ_REMOVE(&pdev->req_list, req, req_list_elem);
+		pdev->req_list_depth--;
+		ol_txrx_err(
+			"%d: %pK,verbose(%d), concise(%d), up_m(0x%x), reset_m(0x%x)\n",
+			i++,
+			req,
+			req->base.print.verbose,
+			req->base.print.concise,
+			req->base.stats_type_upload_mask,
+			req->base.stats_type_reset_mask
+			);
+		qdf_mem_free(req);
+	}
+	qdf_spin_unlock_bh(&pdev->req_list_spinlock);
+
+	qdf_spinlock_destroy(&pdev->req_list_spinlock);
+	qdf_spinlock_destroy(&pdev->tx_mutex);
+
+	OL_RX_REORDER_TIMEOUT_CLEANUP(pdev);
+
+	if (pdev->cfg.is_high_latency)
+		ol_tx_sched_detach(pdev);
+
+	htt_deregister_rx_pkt_dump_callback(pdev->htt_pdev);
+
+	htt_pdev_free(pdev->htt_pdev);
+	ol_txrx_peer_find_detach(pdev);
+	ol_txrx_tso_stats_deinit(pdev);
+	ol_txrx_fw_stats_desc_pool_deinit(pdev);
+
+	ol_txrx_pdev_txq_log_destroy(pdev);
+	ol_txrx_pdev_grp_stat_destroy(pdev);
+
+	ol_txrx_debugfs_exit(pdev);
+
+	qdf_mem_free(pdev);
+}
+
+#if defined(QCA_HL_NETDEV_FLOW_CONTROL)
+
+/**
+ * ol_txrx_vdev_per_vdev_tx_desc_init() - initialise per vdev tx desc count
+ * related variables.
+ * @vdev: the virtual device object
+ *
+ * Return: None
+ */
+static inline void
+ol_txrx_vdev_per_vdev_tx_desc_init(struct ol_txrx_vdev_t *vdev)
+{
+	qdf_atomic_init(&vdev->tx_desc_count);
+	vdev->tx_desc_limit = 0;
+	vdev->queue_restart_th = 0;
+	vdev->prio_q_paused = 0;
+	vdev->queue_stop_th = 0;
+}
+#else
+
+static inline void
+ol_txrx_vdev_per_vdev_tx_desc_init(struct ol_txrx_vdev_t *vdev)
+{
+}
+#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
+
+/**
+ * ol_txrx_vdev_attach - Allocate and initialize the data object
+ * for a new virtual device.
+ *
+ * @data_pdev - the physical device the virtual device belongs to
+ * @vdev_mac_addr - the MAC address of the virtual device
+ * @vdev_id - the ID used to identify the virtual device to the target
+ * @op_mode - whether this virtual device is operating as an AP,
+ * an IBSS, or a STA
+ *
+ * Return: success: handle to new data vdev object, failure: NULL
+ */
+static struct cdp_vdev *
+ol_txrx_vdev_attach(struct cdp_pdev *ppdev,
+		    uint8_t *vdev_mac_addr,
+		    uint8_t vdev_id, enum wlan_op_mode op_mode)
+{
+	struct ol_txrx_pdev_t  *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	struct ol_txrx_vdev_t *vdev;
+	QDF_STATUS qdf_status;
+
+	/* preconditions */
+	TXRX_ASSERT2(pdev);
+	TXRX_ASSERT2(vdev_mac_addr);
+
+	vdev = qdf_mem_malloc(sizeof(*vdev));
+	if (!vdev)
+		return NULL;    /* failure */
+
+	/* store provided params */
+	vdev->pdev = pdev;
+	vdev->vdev_id = vdev_id;
+	vdev->opmode = op_mode;
+
+	vdev->delete.pending = 0;
+	vdev->safemode = 0;
+	vdev->drop_unenc = 1;
+	vdev->num_filters = 0;
+	vdev->fwd_tx_packets = 0;
+	vdev->fwd_rx_packets = 0;
+
+	ol_txrx_vdev_per_vdev_tx_desc_init(vdev);
+
+	qdf_mem_copy(&vdev->mac_addr.raw[0], vdev_mac_addr,
+		     OL_TXRX_MAC_ADDR_LEN);
+
+	TAILQ_INIT(&vdev->peer_list);
+	vdev->last_real_peer = NULL;
+
+	ol_txrx_hl_tdls_flag_reset((struct cdp_vdev *)vdev, false);
+
+#ifdef QCA_IBSS_SUPPORT
+	vdev->ibss_peer_num = 0;
+	vdev->ibss_peer_heart_beat_timer = 0;
+#endif
+
+	ol_txrx_vdev_txqs_init(vdev);
+
+	qdf_spinlock_create(&vdev->ll_pause.mutex);
+	vdev->ll_pause.paused_reason = 0;
+	vdev->ll_pause.txq.head = vdev->ll_pause.txq.tail = NULL;
+	vdev->ll_pause.txq.depth = 0;
+	qdf_atomic_init(&vdev->delete.detaching);
+	qdf_timer_init(pdev->osdev,
+			       &vdev->ll_pause.timer,
+			       ol_tx_vdev_ll_pause_queue_send, vdev,
+			       QDF_TIMER_TYPE_SW);
+	qdf_atomic_init(&vdev->os_q_paused);
+	qdf_atomic_set(&vdev->os_q_paused, 0);
+	vdev->tx_fl_lwm = 0;
+	vdev->tx_fl_hwm = 0;
+	vdev->rx = NULL;
+	vdev->wait_on_peer_id = OL_TXRX_INVALID_LOCAL_PEER_ID;
+	qdf_mem_zero(&vdev->last_peer_mac_addr,
+			sizeof(union ol_txrx_align_mac_addr_t));
+	qdf_spinlock_create(&vdev->flow_control_lock);
+	vdev->osif_flow_control_cb = NULL;
+	vdev->osif_flow_control_is_pause = NULL;
+	vdev->osif_fc_ctx = NULL;
+
+	vdev->txrx_stats.txack_success = 0;
+	vdev->txrx_stats.txack_failed = 0;
+
+	/* Default MAX Q depth for every VDEV */
+	vdev->ll_pause.max_q_depth =
+		ol_tx_cfg_max_tx_queue_depth_ll(vdev->pdev->ctrl_pdev);
+	qdf_status = qdf_event_create(&vdev->wait_delete_comp);
+	/* add this vdev into the pdev's list */
+	TAILQ_INSERT_TAIL(&pdev->vdev_list, vdev, vdev_list_elem);
+
+	ol_txrx_dbg(
+		   "Created vdev %pK (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+		   vdev,
+		   vdev->mac_addr.raw[0], vdev->mac_addr.raw[1],
+		   vdev->mac_addr.raw[2], vdev->mac_addr.raw[3],
+		   vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]);
+
+	/*
+	 * We've verified that htt_op_mode == wlan_op_mode,
+	 * so no translation is needed.
+	 */
+	htt_vdev_attach(pdev->htt_pdev, vdev_id, op_mode);
+
+	return (struct cdp_vdev *)vdev;
+}
+
+/**
+ *ol_txrx_vdev_register - Link a vdev's data object with the
+ * matching OS shim vdev object.
+ *
+ * @txrx_vdev: the virtual device's data object
+ * @osif_vdev: the virtual device's OS shim object
+ * @ctrl_vdev: UMAC vdev objmgr handle
+ * @txrx_ops: (pointers to)functions used for tx and rx data xfer
+ *
+ *  The data object for a virtual device is created by the
+ *  function ol_txrx_vdev_attach.  However, rather than fully
+ *  linking the data vdev object with the vdev objects from the
+ *  other subsystems that the data vdev object interacts with,
+ *  the txrx_vdev_attach function focuses primarily on creating
+ *  the data vdev object. After the creation of both the data
+ *  vdev object and the OS shim vdev object, this
+ *  txrx_osif_vdev_attach function is used to connect the two
+ *  vdev objects, so the data SW can use the OS shim vdev handle
+ *  when passing rx data received by a vdev up to the OS shim.
+ */
+static void ol_txrx_vdev_register(struct cdp_vdev *pvdev, void *osif_vdev,
+				  struct cdp_ctrl_objmgr_vdev *ctrl_vdev,
+				  struct ol_txrx_ops *txrx_ops)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	if (qdf_unlikely(!vdev) || qdf_unlikely(!txrx_ops)) {
+		qdf_print("%s: vdev/txrx_ops is NULL!\n", __func__);
+		qdf_assert(0);
+		return;
+	}
+
+	vdev->osif_dev = osif_vdev;
+	vdev->ctrl_vdev = ctrl_vdev;
+	vdev->rx = txrx_ops->rx.rx;
+	vdev->stats_rx = txrx_ops->rx.stats_rx;
+	vdev->tx_comp = txrx_ops->tx.tx_comp;
+	txrx_ops->tx.tx = ol_tx_data;
+}
+
+void ol_txrx_set_safemode(ol_txrx_vdev_handle vdev, uint32_t val)
+{
+	vdev->safemode = val;
+}
+
+/**
+ * ol_txrx_set_privacy_filters - set the privacy filter
+ * @vdev - the data virtual device object
+ * @filter - filters to be set
+ * @num - the number of filters
+ *
+ * Rx related. Set the privacy filters. When rx packets, check
+ * the ether type, filter type and packet type to decide whether
+ * discard these packets.
+ */
+static void
+ol_txrx_set_privacy_filters(ol_txrx_vdev_handle vdev,
+			    void *filters, uint32_t num)
+{
+	qdf_mem_copy(vdev->privacy_filters, filters,
+		     num * sizeof(struct privacy_exemption));
+	vdev->num_filters = num;
+}
+
+void ol_txrx_set_drop_unenc(ol_txrx_vdev_handle vdev, uint32_t val)
+{
+	vdev->drop_unenc = val;
+}
+
+#if defined(CONFIG_HL_SUPPORT) || defined(QCA_LL_LEGACY_TX_FLOW_CONTROL)
+
+static void
+ol_txrx_tx_desc_reset_vdev(ol_txrx_vdev_handle vdev)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	int i;
+	struct ol_tx_desc_t *tx_desc;
+
+	qdf_spin_lock_bh(&pdev->tx_mutex);
+	for (i = 0; i < pdev->tx_desc.pool_size; i++) {
+		tx_desc = ol_tx_desc_find(pdev, i);
+		if (tx_desc->vdev == vdev)
+			tx_desc->vdev = NULL;
+	}
+	qdf_spin_unlock_bh(&pdev->tx_mutex);
+}
+
+#else
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+static void ol_txrx_tx_desc_reset_vdev(ol_txrx_vdev_handle vdev)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	struct ol_tx_flow_pool_t *pool;
+	int i;
+	struct ol_tx_desc_t *tx_desc;
+
+	qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	for (i = 0; i < pdev->tx_desc.pool_size; i++) {
+		tx_desc = ol_tx_desc_find(pdev, i);
+		if (!qdf_atomic_read(&tx_desc->ref_cnt))
+			/* not in use */
+			continue;
+
+		pool = tx_desc->pool;
+		qdf_spin_lock_bh(&pool->flow_pool_lock);
+		if (tx_desc->vdev == vdev)
+			tx_desc->vdev = NULL;
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+}
+
+#else
+static void
+ol_txrx_tx_desc_reset_vdev(ol_txrx_vdev_handle vdev)
+{
+}
+#endif /* QCA_LL_TX_FLOW_CONTROL_V2 */
+#endif /* CONFIG_HL_SUPPORT */
+
+/**
+ * ol_txrx_vdev_detach - Deallocate the specified data virtual
+ * device object.
+ * @data_vdev: data object for the virtual device in question
+ * @callback: function to call (if non-NULL) once the vdev has
+ * been wholly deleted
+ * @callback_context: context to provide in the callback
+ *
+ * All peers associated with the virtual device need to be deleted
+ * (ol_txrx_peer_detach) before the virtual device itself is deleted.
+ * However, for the peers to be fully deleted, the peer deletion has to
+ * percolate through the target data FW and back up to the host data SW.
+ * Thus, even though the host control SW may have issued a peer_detach
+ * call for each of the vdev's peers, the peer objects may still be
+ * allocated, pending removal of all references to them by the target FW.
+ * In this case, though the vdev_detach function call will still return
+ * immediately, the vdev itself won't actually be deleted, until the
+ * deletions of all its peers complete.
+ * The caller can provide a callback function pointer to be notified when
+ * the vdev deletion actually happens - whether it's directly within the
+ * vdev_detach call, or if it's deferred until all in-progress peer
+ * deletions have completed.
+ */
+static void
+ol_txrx_vdev_detach(struct cdp_vdev *pvdev,
+		    ol_txrx_vdev_delete_cb callback, void *context)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	struct ol_txrx_pdev_t *pdev;
+
+	/* preconditions */
+	TXRX_ASSERT2(vdev);
+	pdev = vdev->pdev;
+
+	/* prevent anyone from restarting the ll_pause timer again */
+	qdf_atomic_set(&vdev->delete.detaching, 1);
+
+	ol_txrx_vdev_tx_queue_free(vdev);
+
+	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
+	qdf_timer_stop(&vdev->ll_pause.timer);
+	vdev->ll_pause.is_q_timer_on = false;
+	while (vdev->ll_pause.txq.head) {
+		qdf_nbuf_t next = qdf_nbuf_next(vdev->ll_pause.txq.head);
+
+		qdf_nbuf_set_next(vdev->ll_pause.txq.head, NULL);
+		qdf_nbuf_tx_free(vdev->ll_pause.txq.head, QDF_NBUF_PKT_ERROR);
+		vdev->ll_pause.txq.head = next;
+	}
+	qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+
+	/* ll_pause timer should be deleted without any locks held, and
+	 * no timer function should be executed after this point because
+	 * qdf_timer_free is deleting the timer synchronously.
+	 */
+	qdf_timer_free(&vdev->ll_pause.timer);
+	qdf_spinlock_destroy(&vdev->ll_pause.mutex);
+
+	qdf_spin_lock_bh(&vdev->flow_control_lock);
+	vdev->osif_flow_control_cb = NULL;
+	vdev->osif_flow_control_is_pause = NULL;
+	vdev->osif_fc_ctx = NULL;
+	qdf_spin_unlock_bh(&vdev->flow_control_lock);
+	qdf_spinlock_destroy(&vdev->flow_control_lock);
+
+	/* remove the vdev from its parent pdev's list */
+	TAILQ_REMOVE(&pdev->vdev_list, vdev, vdev_list_elem);
+
+	/*
+	 * Use peer_ref_mutex while accessing peer_list, in case
+	 * a peer is in the process of being removed from the list.
+	 */
+	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+	/* check that the vdev has no peers allocated */
+	if (!TAILQ_EMPTY(&vdev->peer_list)) {
+		/* debug print - will be removed later */
+		ol_txrx_dbg(
+			   "%s: not deleting vdev object %pK (%02x:%02x:%02x:%02x:%02x:%02x) until deletion finishes for all its peers\n",
+			   __func__, vdev,
+			   vdev->mac_addr.raw[0], vdev->mac_addr.raw[1],
+			   vdev->mac_addr.raw[2], vdev->mac_addr.raw[3],
+			   vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]);
+		/* indicate that the vdev needs to be deleted */
+		vdev->delete.pending = 1;
+		vdev->delete.callback = callback;
+		vdev->delete.context = context;
+		qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+		return;
+	}
+	qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+	qdf_event_destroy(&vdev->wait_delete_comp);
+
+	ol_txrx_dbg(
+		   "%s: deleting vdev obj %pK (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+		   __func__, vdev,
+		   vdev->mac_addr.raw[0], vdev->mac_addr.raw[1],
+		   vdev->mac_addr.raw[2], vdev->mac_addr.raw[3],
+		   vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]);
+
+	htt_vdev_detach(pdev->htt_pdev, vdev->vdev_id);
+
+	/*
+	 * The ol_tx_desc_free might access the invalid content of vdev referred
+	 * by tx desc, since this vdev might be detached in another thread
+	 * asynchronous.
+	 *
+	 * Go through tx desc pool to set corresponding tx desc's vdev to NULL
+	 * when detach this vdev, and add vdev checking in the ol_tx_desc_free
+	 * to avoid crash.
+	 *
+	 */
+	ol_txrx_tx_desc_reset_vdev(vdev);
+
+	/*
+	 * Doesn't matter if there are outstanding tx frames -
+	 * they will be freed once the target sends a tx completion
+	 * message for them.
+	 */
+	qdf_mem_free(vdev);
+	if (callback)
+		callback(context);
+}
+
+/**
+ * ol_txrx_flush_rx_frames() - flush cached rx frames
+ * @peer: peer
+ * @drop: set flag to drop frames
+ *
+ * Return: None
+ */
+void ol_txrx_flush_rx_frames(struct ol_txrx_peer_t *peer,
+			     bool drop)
+{
+	struct ol_txrx_cached_bufq_t *bufqi;
+	struct ol_rx_cached_buf *cache_buf;
+	QDF_STATUS ret;
+	ol_txrx_rx_fp data_rx = NULL;
+
+	if (qdf_atomic_inc_return(&peer->flush_in_progress) > 1) {
+		qdf_atomic_dec(&peer->flush_in_progress);
+		return;
+	}
+
+	qdf_assert(peer->vdev);
+	qdf_spin_lock_bh(&peer->peer_info_lock);
+	bufqi = &peer->bufq_info;
+
+	if (peer->state >= OL_TXRX_PEER_STATE_CONN && peer->vdev->rx)
+		data_rx = peer->vdev->rx;
+	else
+		drop = true;
+	qdf_spin_unlock_bh(&peer->peer_info_lock);
+
+	qdf_spin_lock_bh(&bufqi->bufq_lock);
+	cache_buf = list_entry((&bufqi->cached_bufq)->next,
+				typeof(*cache_buf), list);
+	while (!list_empty(&bufqi->cached_bufq)) {
+		list_del(&cache_buf->list);
+		bufqi->curr--;
+		qdf_assert(bufqi->curr >= 0);
+		qdf_spin_unlock_bh(&bufqi->bufq_lock);
+		if (drop) {
+			qdf_nbuf_free(cache_buf->buf);
+		} else {
+			/* Flush the cached frames to HDD */
+			ret = data_rx(peer->vdev->osif_dev, cache_buf->buf);
+			if (ret != QDF_STATUS_SUCCESS)
+				qdf_nbuf_free(cache_buf->buf);
+		}
+		qdf_mem_free(cache_buf);
+		qdf_spin_lock_bh(&bufqi->bufq_lock);
+		cache_buf = list_entry((&bufqi->cached_bufq)->next,
+				typeof(*cache_buf), list);
+	}
+	bufqi->qdepth_no_thresh = bufqi->curr;
+	qdf_spin_unlock_bh(&bufqi->bufq_lock);
+	qdf_atomic_dec(&peer->flush_in_progress);
+}
+
+static void ol_txrx_flush_cache_rx_queue(void)
+{
+	uint8_t sta_id;
+	struct ol_txrx_peer_t *peer;
+	struct ol_txrx_pdev_t *pdev;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev)
+		return;
+
+	for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
+		peer = ol_txrx_peer_find_by_local_id((struct cdp_pdev *)pdev,
+						    sta_id);
+		if (!peer)
+			continue;
+		ol_txrx_flush_rx_frames(peer, 1);
+	}
+}
+
+/* Define short name to use in cds_trigger_recovery */
+#define PEER_DEL_TIMEOUT QDF_PEER_DELETION_TIMEDOUT
+
+/**
+ * ol_txrx_dump_peer_access_list() - dump peer access list
+ * @peer: peer handle
+ *
+ * This function will dump if any peer debug ids are still accessing peer
+ *
+ * Return: None
+ */
+static void ol_txrx_dump_peer_access_list(ol_txrx_peer_handle peer)
+{
+	u32 i;
+	u32 pending_ref;
+
+	for (i = 0; i < PEER_DEBUG_ID_MAX; i++) {
+		pending_ref = qdf_atomic_read(&peer->access_list[i]);
+		if (pending_ref)
+			ol_txrx_info_high("id %d pending refs %d",
+					  i, pending_ref);
+	}
+}
+
+/**
+ * ol_txrx_peer_attach - Allocate and set up references for a
+ * data peer object.
+ * @data_pdev: data physical device object that will indirectly
+ * own the data_peer object
+ * @data_vdev - data virtual device object that will directly
+ * own the data_peer object
+ * @peer_mac_addr - MAC address of the new peer
+ *
+ * When an association with a peer starts, the host's control SW
+ * uses this function to inform the host data SW.
+ * The host data SW allocates its own peer object, and stores a
+ * reference to the control peer object within the data peer object.
+ * The host data SW also stores a reference to the virtual device
+ * that the peer is associated with.  This virtual device handle is
+ * used when the data SW delivers rx data frames to the OS shim layer.
+ * The host data SW returns a handle to the new peer data object,
+ * so a reference within the control peer object can be set to the
+ * data peer object.
+ *
+ * Return: handle to new data peer object, or NULL if the attach
+ * fails
+ */
+static void *
+ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr,
+		    struct cdp_ctrl_objmgr_peer *ctrl_peer)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	struct ol_txrx_peer_t *peer;
+	struct ol_txrx_peer_t *temp_peer;
+	uint8_t i;
+	bool wait_on_deletion = false;
+	unsigned long rc;
+	struct ol_txrx_pdev_t *pdev;
+	bool cmp_wait_mac = false;
+	uint8_t zero_mac_addr[QDF_MAC_ADDR_SIZE] = { 0, 0, 0, 0, 0, 0 };
+
+	/* preconditions */
+	TXRX_ASSERT2(vdev);
+	TXRX_ASSERT2(peer_mac_addr);
+
+	pdev = vdev->pdev;
+	TXRX_ASSERT2(pdev);
+
+	if (qdf_mem_cmp(&zero_mac_addr, &vdev->last_peer_mac_addr,
+				QDF_MAC_ADDR_SIZE))
+		cmp_wait_mac = true;
+
+	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+	/* check for duplicate existing peer */
+	TAILQ_FOREACH(temp_peer, &vdev->peer_list, peer_list_elem) {
+		if (!ol_txrx_peer_find_mac_addr_cmp(&temp_peer->mac_addr,
+			(union ol_txrx_align_mac_addr_t *)peer_mac_addr)) {
+			ol_txrx_info_high(
+				"vdev_id %d (%02x:%02x:%02x:%02x:%02x:%02x) already exists.\n",
+				vdev->vdev_id,
+				peer_mac_addr[0], peer_mac_addr[1],
+				peer_mac_addr[2], peer_mac_addr[3],
+				peer_mac_addr[4], peer_mac_addr[5]);
+			if (qdf_atomic_read(&temp_peer->delete_in_progress)) {
+				vdev->wait_on_peer_id = temp_peer->local_id;
+				qdf_event_reset(&vdev->wait_delete_comp);
+				wait_on_deletion = true;
+				break;
+			} else {
+				qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+				return NULL;
+			}
+		}
+		if (cmp_wait_mac && !ol_txrx_peer_find_mac_addr_cmp(
+					&temp_peer->mac_addr,
+					&vdev->last_peer_mac_addr)) {
+			ol_txrx_info_high(
+				"vdev_id %d (%02x:%02x:%02x:%02x:%02x:%02x) old peer exists.\n",
+				vdev->vdev_id,
+				vdev->last_peer_mac_addr.raw[0],
+				vdev->last_peer_mac_addr.raw[1],
+				vdev->last_peer_mac_addr.raw[2],
+				vdev->last_peer_mac_addr.raw[3],
+				vdev->last_peer_mac_addr.raw[4],
+				vdev->last_peer_mac_addr.raw[5]);
+			if (qdf_atomic_read(&temp_peer->delete_in_progress)) {
+				vdev->wait_on_peer_id = temp_peer->local_id;
+				qdf_event_reset(&vdev->wait_delete_comp);
+				wait_on_deletion = true;
+				break;
+			} else {
+				qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+				ol_txrx_err("peer not found");
+				return NULL;
+			}
+		}
+	}
+	qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+
+	qdf_mem_zero(&vdev->last_peer_mac_addr,
+			sizeof(union ol_txrx_align_mac_addr_t));
+	if (wait_on_deletion) {
+		/* wait for peer deletion */
+		rc = qdf_wait_for_event_completion(&vdev->wait_delete_comp,
+					   PEER_DELETION_TIMEOUT);
+		if (QDF_STATUS_SUCCESS != rc) {
+			ol_txrx_err("error waiting for peer_id(%d) deletion, status %d\n",
+				    vdev->wait_on_peer_id, (int) rc);
+			/* Added for debugging only */
+			ol_txrx_dump_peer_access_list(temp_peer);
+			wlan_roam_debug_dump_table();
+			vdev->wait_on_peer_id = OL_TXRX_INVALID_LOCAL_PEER_ID;
+
+			return NULL;
+		}
+	}
+
+	peer = qdf_mem_malloc(sizeof(*peer));
+	if (!peer)
+		return NULL;    /* failure */
+
+	/* store provided params */
+	peer->vdev = vdev;
+	peer->ctrl_peer = peer->ctrl_peer;
+	qdf_mem_copy(&peer->mac_addr.raw[0], peer_mac_addr,
+		     OL_TXRX_MAC_ADDR_LEN);
+
+	ol_txrx_peer_txqs_init(pdev, peer);
+
+	INIT_LIST_HEAD(&peer->bufq_info.cached_bufq);
+	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+	/* add this peer into the vdev's list */
+	TAILQ_INSERT_TAIL(&vdev->peer_list, peer, peer_list_elem);
+	qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+	/* check whether this is a real peer (peer mac addr != vdev mac addr) */
+	if (ol_txrx_peer_find_mac_addr_cmp(&vdev->mac_addr, &peer->mac_addr)) {
+		qdf_spin_lock_bh(&pdev->last_real_peer_mutex);
+		vdev->last_real_peer = peer;
+		qdf_spin_unlock_bh(&pdev->last_real_peer_mutex);
+	}
+
+	peer->rx_opt_proc = pdev->rx_opt_proc;
+
+	ol_rx_peer_init(pdev, peer);
+
+	/* initialize the peer_id */
+	for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++)
+		peer->peer_ids[i] = HTT_INVALID_PEER;
+
+	qdf_spinlock_create(&peer->peer_info_lock);
+	qdf_spinlock_create(&peer->bufq_info.bufq_lock);
+
+	peer->bufq_info.thresh = OL_TXRX_CACHED_BUFQ_THRESH;
+
+	qdf_atomic_init(&peer->delete_in_progress);
+	qdf_atomic_init(&peer->flush_in_progress);
+	qdf_atomic_init(&peer->ref_cnt);
+
+	for (i = 0; i < PEER_DEBUG_ID_MAX; i++)
+		qdf_atomic_init(&peer->access_list[i]);
+
+	/* keep one reference for attach */
+	ol_txrx_peer_get_ref(peer, PEER_DEBUG_ID_OL_PEER_ATTACH);
+
+	/* Set a flag to indicate peer create is pending in firmware */
+	qdf_atomic_init(&peer->fw_create_pending);
+	qdf_atomic_set(&peer->fw_create_pending, 1);
+
+	peer->valid = 1;
+	qdf_timer_init(pdev->osdev, &peer->peer_unmap_timer,
+		       peer_unmap_timer_handler, peer, QDF_TIMER_TYPE_SW);
+
+	ol_txrx_peer_find_hash_add(pdev, peer);
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+		   "vdev %pK created peer %pK ref_cnt %d (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+		   vdev, peer, qdf_atomic_read(&peer->ref_cnt),
+		   peer->mac_addr.raw[0], peer->mac_addr.raw[1],
+		   peer->mac_addr.raw[2], peer->mac_addr.raw[3],
+		   peer->mac_addr.raw[4], peer->mac_addr.raw[5]);
+	/*
+	 * For every peer MAp message search and set if bss_peer
+	 */
+	if (qdf_mem_cmp(peer->mac_addr.raw, vdev->mac_addr.raw,
+				OL_TXRX_MAC_ADDR_LEN))
+		peer->bss_peer = 1;
+
+	/*
+	 * The peer starts in the "disc" state while association is in progress.
+	 * Once association completes, the peer will get updated to "auth" state
+	 * by a call to ol_txrx_peer_state_update if the peer is in open mode,
+	 * or else to the "conn" state. For non-open mode, the peer will
+	 * progress to "auth" state once the authentication completes.
+	 */
+	peer->state = OL_TXRX_PEER_STATE_INVALID;
+	ol_txrx_peer_state_update((struct cdp_pdev *)pdev, peer->mac_addr.raw,
+				  OL_TXRX_PEER_STATE_DISC);
+
+#ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI
+	peer->rssi_dbm = HTT_RSSI_INVALID;
+#endif
+	if ((QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) &&
+	    !pdev->self_peer) {
+		pdev->self_peer = peer;
+		/*
+		 * No Tx in monitor mode, otherwise results in target assert.
+		 * Setting disable_intrabss_fwd to true
+		 */
+		ol_vdev_rx_set_intrabss_fwd((struct cdp_vdev *)vdev, true);
+	}
+
+	ol_txrx_local_peer_id_alloc(pdev, peer);
+
+	return (void *)peer;
+}
+
+#undef PEER_DEL_TIMEOUT
+
+/*
+ * Discarding tx filter - removes all data frames (disconnected state)
+ */
+static A_STATUS ol_tx_filter_discard(struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	return A_ERROR;
+}
+
+/*
+ * Non-autentication tx filter - filters out data frames that are not
+ * related to authentication, but allows EAPOL (PAE) or WAPI (WAI)
+ * data frames (connected state)
+ */
+static A_STATUS ol_tx_filter_non_auth(struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	return
+		(tx_msdu_info->htt.info.ethertype == ETHERTYPE_PAE ||
+		 tx_msdu_info->htt.info.ethertype ==
+		 ETHERTYPE_WAI) ? A_OK : A_ERROR;
+}
+
+/*
+ * Pass-through tx filter - lets all data frames through (authenticated state)
+ */
+static A_STATUS ol_tx_filter_pass_thru(struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	return A_OK;
+}
+
+/**
+ * ol_txrx_peer_get_peer_mac_addr() - return mac_addr from peer handle.
+ * @peer: handle to peer
+ *
+ * returns mac addrs for module which do not know peer type
+ *
+ * Return: the mac_addr from peer
+ */
+static uint8_t *
+ol_txrx_peer_get_peer_mac_addr(void *ppeer)
+{
+	ol_txrx_peer_handle peer = ppeer;
+
+	if (!peer)
+		return NULL;
+
+	return peer->mac_addr.raw;
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * ol_txrx_get_pn_info() - Returns pn info from peer
+ * @peer: handle to peer
+ * @last_pn_valid: return last_rmf_pn_valid value from peer.
+ * @last_pn: return last_rmf_pn value from peer.
+ * @rmf_pn_replays: return rmf_pn_replays value from peer.
+ *
+ * Return: NONE
+ */
+void
+ol_txrx_get_pn_info(void *ppeer, uint8_t **last_pn_valid,
+		    uint64_t **last_pn, uint32_t **rmf_pn_replays)
+{
+	ol_txrx_peer_handle peer = ppeer;
+	*last_pn_valid = &peer->last_rmf_pn_valid;
+	*last_pn = &peer->last_rmf_pn;
+	*rmf_pn_replays = &peer->rmf_pn_replays;
+}
+#else
+void
+ol_txrx_get_pn_info(void *ppeer, uint8_t **last_pn_valid,
+		uint64_t **last_pn, uint32_t **rmf_pn_replays)
+{
+}
+#endif
+
+/**
+ * ol_txrx_get_opmode() - Return operation mode of vdev
+ * @vdev: vdev handle
+ *
+ * Return: operation mode.
+ */
+static int ol_txrx_get_opmode(struct cdp_vdev *pvdev)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	return vdev->opmode;
+}
+
+/**
+ * ol_txrx_get_peer_state() - Return peer state of peer
+ * @peer: peer handle
+ *
+ * Return: return peer state
+ */
+static int ol_txrx_get_peer_state(void *ppeer)
+{
+	ol_txrx_peer_handle peer = ppeer;
+
+	return peer->state;
+}
+
+/**
+ * ol_txrx_get_vdev_for_peer() - Return vdev from peer handle
+ * @peer: peer handle
+ *
+ * Return: vdev handle from peer
+ */
+static struct cdp_vdev *ol_txrx_get_vdev_for_peer(void *ppeer)
+{
+	ol_txrx_peer_handle peer = ppeer;
+
+	return (struct cdp_vdev *)peer->vdev;
+}
+
+/**
+ * ol_txrx_get_vdev_mac_addr() - Return mac addr of vdev
+ * @vdev: vdev handle
+ *
+ * Return: vdev mac address
+ */
+static uint8_t *
+ol_txrx_get_vdev_mac_addr(struct cdp_vdev *pvdev)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	if (!vdev)
+		return NULL;
+
+	return vdev->mac_addr.raw;
+}
+
+#ifdef currently_unused
+/**
+ * ol_txrx_get_vdev_struct_mac_addr() - Return handle to struct qdf_mac_addr of
+ * vdev
+ * @vdev: vdev handle
+ *
+ * Return: Handle to struct qdf_mac_addr
+ */
+struct qdf_mac_addr *
+ol_txrx_get_vdev_struct_mac_addr(ol_txrx_vdev_handle vdev)
+{
+	return (struct qdf_mac_addr *)&(vdev->mac_addr);
+}
+#endif
+
+#ifdef currently_unused
+/**
+ * ol_txrx_get_pdev_from_vdev() - Return handle to pdev of vdev
+ * @vdev: vdev handle
+ *
+ * Return: Handle to pdev
+ */
+ol_txrx_pdev_handle ol_txrx_get_pdev_from_vdev(ol_txrx_vdev_handle vdev)
+{
+	return vdev->pdev;
+}
+#endif
+
+/**
+ * ol_txrx_get_ctrl_pdev_from_vdev() - Return control pdev of vdev
+ * @vdev: vdev handle
+ *
+ * Return: Handle to control pdev
+ */
+static struct cdp_cfg *
+ol_txrx_get_ctrl_pdev_from_vdev(struct cdp_vdev *pvdev)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	return vdev->pdev->ctrl_pdev;
+}
+
+/**
+ * ol_txrx_is_rx_fwd_disabled() - returns the rx_fwd_disabled status on vdev
+ * @vdev: vdev handle
+ *
+ * Return: Rx Fwd disabled status
+ */
+static uint8_t
+ol_txrx_is_rx_fwd_disabled(struct cdp_vdev *pvdev)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)
+					vdev->pdev->ctrl_pdev;
+	return cfg->rx_fwd_disabled;
+}
+
+#ifdef QCA_IBSS_SUPPORT
+/**
+ * ol_txrx_update_ibss_add_peer_num_of_vdev() - update and return peer num
+ * @vdev: vdev handle
+ * @peer_num_delta: peer nums to be adjusted
+ *
+ * Return: -1 for failure or total peer nums after adjustment.
+ */
+static int16_t
+ol_txrx_update_ibss_add_peer_num_of_vdev(struct cdp_vdev *pvdev,
+					 int16_t peer_num_delta)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	int16_t new_peer_num;
+
+	new_peer_num = vdev->ibss_peer_num + peer_num_delta;
+	if (new_peer_num > MAX_PEERS || new_peer_num < 0)
+		return OL_TXRX_INVALID_NUM_PEERS;
+
+	vdev->ibss_peer_num = new_peer_num;
+
+	return new_peer_num;
+}
+
+/**
+ * ol_txrx_set_ibss_vdev_heart_beat_timer() - Update ibss vdev heart
+ * beat timer
+ * @vdev: vdev handle
+ * @timer_value_sec: new heart beat timer value
+ *
+ * Return: Old timer value set in vdev.
+ */
+static uint16_t ol_txrx_set_ibss_vdev_heart_beat_timer(struct cdp_vdev *pvdev,
+						uint16_t timer_value_sec)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	uint16_t old_timer_value = vdev->ibss_peer_heart_beat_timer;
+
+	vdev->ibss_peer_heart_beat_timer = timer_value_sec;
+
+	return old_timer_value;
+}
+#endif
+
+/**
+ * ol_txrx_remove_peers_for_vdev() - remove all vdev peers with lock held
+ * @vdev: vdev handle
+ * @callback: callback function to remove the peer.
+ * @callback_context: handle for callback function
+ * @remove_last_peer: Does it required to last peer.
+ *
+ * Return: NONE
+ */
+static void
+ol_txrx_remove_peers_for_vdev(struct cdp_vdev *pvdev,
+			      ol_txrx_vdev_peer_remove_cb callback,
+			      void *callback_context, bool remove_last_peer)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	ol_txrx_peer_handle peer, temp;
+	int self_removed = 0;
+	/* remove all remote peers for vdev */
+	qdf_spin_lock_bh(&vdev->pdev->peer_ref_mutex);
+
+	temp = NULL;
+	TAILQ_FOREACH_REVERSE(peer, &vdev->peer_list, peer_list_t,
+			      peer_list_elem) {
+		if (qdf_atomic_read(&peer->delete_in_progress))
+			continue;
+		if (temp) {
+			qdf_spin_unlock_bh(&vdev->pdev->peer_ref_mutex);
+			callback(callback_context, temp->mac_addr.raw,
+				vdev->vdev_id, temp);
+			qdf_spin_lock_bh(&vdev->pdev->peer_ref_mutex);
+		}
+		/* self peer is deleted last */
+		if (peer == TAILQ_FIRST(&vdev->peer_list)) {
+			self_removed = 1;
+			break;
+		}
+		temp = peer;
+	}
+
+	qdf_spin_unlock_bh(&vdev->pdev->peer_ref_mutex);
+
+	if (self_removed)
+		ol_txrx_info("%s: self peer removed by caller ",
+				   __func__);
+
+	if (remove_last_peer) {
+		/* remove IBSS bss peer last */
+		peer = TAILQ_FIRST(&vdev->peer_list);
+		callback(callback_context, (uint8_t *) &vdev->mac_addr,
+			 vdev->vdev_id, peer);
+	}
+}
+
+/**
+ * ol_txrx_remove_peers_for_vdev_no_lock() - remove vdev peers with no lock.
+ * @vdev: vdev handle
+ * @callback: callback function to remove the peer.
+ * @callback_context: handle for callback function
+ *
+ * Return: NONE
+ */
+static void
+ol_txrx_remove_peers_for_vdev_no_lock(struct cdp_vdev *pvdev,
+			      ol_txrx_vdev_peer_remove_cb callback,
+			      void *callback_context)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	ol_txrx_peer_handle peer = NULL;
+	ol_txrx_peer_handle tmp_peer = NULL;
+
+	TAILQ_FOREACH_SAFE(peer, &vdev->peer_list, peer_list_elem, tmp_peer) {
+		ol_txrx_info_high(
+			   "%s: peer found for vdev id %d. deleting the peer",
+			   __func__, vdev->vdev_id);
+		callback(callback_context, (uint8_t *)&vdev->mac_addr,
+				vdev->vdev_id, peer);
+	}
+}
+
+#ifdef WLAN_FEATURE_DSRC
+/**
+ * ol_txrx_set_ocb_chan_info() - set OCB channel info to vdev.
+ * @vdev: vdev handle
+ * @ocb_set_chan: OCB channel information to be set in vdev.
+ *
+ * Return: NONE
+ */
+static void ol_txrx_set_ocb_chan_info(struct cdp_vdev *pvdev,
+			  struct ol_txrx_ocb_set_chan ocb_set_chan)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	vdev->ocb_channel_info = ocb_set_chan.ocb_channel_info;
+	vdev->ocb_channel_count = ocb_set_chan.ocb_channel_count;
+}
+
+/**
+ * ol_txrx_get_ocb_chan_info() - return handle to vdev ocb_channel_info
+ * @vdev: vdev handle
+ *
+ * Return: handle to struct ol_txrx_ocb_chan_info
+ */
+static struct ol_txrx_ocb_chan_info *
+ol_txrx_get_ocb_chan_info(struct cdp_vdev *pvdev)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	return vdev->ocb_channel_info;
+}
+#endif
+
+/**
+ * @brief specify the peer's authentication state
+ * @details
+ *  Specify the peer's authentication state (none, connected, authenticated)
+ *  to allow the data SW to determine whether to filter out invalid data frames.
+ *  (In the "connected" state, where security is enabled, but authentication
+ *  has not completed, tx and rx data frames other than EAPOL or WAPI should
+ *  be discarded.)
+ *  This function is only relevant for systems in which the tx and rx filtering
+ *  are done in the host rather than in the target.
+ *
+ * @param data_peer - which peer has changed its state
+ * @param state - the new state of the peer
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ol_txrx_peer_state_update(struct cdp_pdev *ppdev,
+				     uint8_t *peer_mac,
+				     enum ol_txrx_peer_state state)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	struct ol_txrx_peer_t *peer;
+	int    peer_ref_cnt;
+
+	if (qdf_unlikely(!pdev)) {
+		ol_txrx_err("Pdev is NULL");
+		qdf_assert(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	peer =  ol_txrx_peer_find_hash_find_get_ref(pdev, peer_mac, 0, 1,
+						    PEER_DEBUG_ID_OL_INTERNAL);
+	if (NULL == peer) {
+		ol_txrx_err(
+			   "%s: peer is null for peer_mac 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+			   __func__,
+			   peer_mac[0], peer_mac[1], peer_mac[2], peer_mac[3],
+			   peer_mac[4], peer_mac[5]);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* TODO: Should we send WMI command of the connection state? */
+	/* avoid multiple auth state change. */
+	if (peer->state == state) {
+#ifdef TXRX_PRINT_VERBOSE_ENABLE
+		ol_txrx_dbg(
+			   "%s: no state change, returns directly\n",
+			   __func__);
+#endif
+		peer_ref_cnt = ol_txrx_peer_release_ref
+						(peer,
+						 PEER_DEBUG_ID_OL_INTERNAL);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	ol_txrx_dbg("%s: change from %d to %d\n",
+		   __func__, peer->state, state);
+
+	peer->tx_filter = (state == OL_TXRX_PEER_STATE_AUTH)
+		? ol_tx_filter_pass_thru
+		: ((state == OL_TXRX_PEER_STATE_CONN)
+		   ? ol_tx_filter_non_auth
+		   : ol_tx_filter_discard);
+
+	if (peer->vdev->pdev->cfg.host_addba) {
+		if (state == OL_TXRX_PEER_STATE_AUTH) {
+			int tid;
+			/*
+			 * Pause all regular (non-extended) TID tx queues until
+			 * data arrives and ADDBA negotiation has completed.
+			 */
+			ol_txrx_dbg(
+				   "%s: pause peer and unpause mgmt/non-qos\n",
+				   __func__);
+			ol_txrx_peer_pause(peer); /* pause all tx queues */
+			/* unpause mgmt and non-QoS tx queues */
+			for (tid = OL_TX_NUM_QOS_TIDS;
+			     tid < OL_TX_NUM_TIDS; tid++)
+				ol_txrx_peer_tid_unpause(peer, tid);
+		}
+	}
+	peer_ref_cnt = ol_txrx_peer_release_ref(peer,
+						PEER_DEBUG_ID_OL_INTERNAL);
+	/*
+	 * after ol_txrx_peer_release_ref, peer object cannot be accessed
+	 * if the return code was 0
+	 */
+	if (peer_ref_cnt > 0)
+		/*
+		 * Set the state after the Pause to avoid the race condiction
+		 * with ADDBA check in tx path
+		 */
+		peer->state = state;
+	return QDF_STATUS_SUCCESS;
+}
+
+void
+ol_txrx_peer_keyinstalled_state_update(struct ol_txrx_peer_t *peer, uint8_t val)
+{
+	peer->keyinstalled = val;
+}
+
+void
+ol_txrx_peer_update(ol_txrx_vdev_handle vdev,
+		    uint8_t *peer_mac,
+		    union ol_txrx_peer_update_param_t *param,
+		    enum ol_txrx_peer_update_select_t select)
+{
+	struct ol_txrx_peer_t *peer;
+
+	peer = ol_txrx_peer_find_hash_find_get_ref(vdev->pdev, peer_mac, 0, 1,
+						   PEER_DEBUG_ID_OL_INTERNAL);
+	if (!peer) {
+		ol_txrx_dbg("%s: peer is null",
+			   __func__);
+		return;
+	}
+
+	switch (select) {
+	case ol_txrx_peer_update_qos_capable:
+	{
+		/* save qos_capable here txrx peer,
+		 * when HTT_ISOC_T2H_MSG_TYPE_PEER_INFO comes then save.
+		 */
+		peer->qos_capable = param->qos_capable;
+		/*
+		 * The following function call assumes that the peer has a
+		 * single ID. This is currently true, and
+		 * is expected to remain true.
+		 */
+		htt_peer_qos_update(peer->vdev->pdev->htt_pdev,
+				    peer->peer_ids[0],
+				    peer->qos_capable);
+		break;
+	}
+	case ol_txrx_peer_update_uapsdMask:
+	{
+		peer->uapsd_mask = param->uapsd_mask;
+		htt_peer_uapsdmask_update(peer->vdev->pdev->htt_pdev,
+					  peer->peer_ids[0],
+					  peer->uapsd_mask);
+		break;
+	}
+	case ol_txrx_peer_update_peer_security:
+	{
+		enum ol_sec_type sec_type = param->sec_type;
+		enum htt_sec_type peer_sec_type = htt_sec_type_none;
+
+		switch (sec_type) {
+		case ol_sec_type_none:
+			peer_sec_type = htt_sec_type_none;
+			break;
+		case ol_sec_type_wep128:
+			peer_sec_type = htt_sec_type_wep128;
+			break;
+		case ol_sec_type_wep104:
+			peer_sec_type = htt_sec_type_wep104;
+			break;
+		case ol_sec_type_wep40:
+			peer_sec_type = htt_sec_type_wep40;
+			break;
+		case ol_sec_type_tkip:
+			peer_sec_type = htt_sec_type_tkip;
+			break;
+		case ol_sec_type_tkip_nomic:
+			peer_sec_type = htt_sec_type_tkip_nomic;
+			break;
+		case ol_sec_type_aes_ccmp:
+			peer_sec_type = htt_sec_type_aes_ccmp;
+			break;
+		case ol_sec_type_wapi:
+			peer_sec_type = htt_sec_type_wapi;
+			break;
+		default:
+			peer_sec_type = htt_sec_type_none;
+			break;
+		}
+
+		peer->security[txrx_sec_ucast].sec_type =
+			peer->security[txrx_sec_mcast].sec_type =
+				peer_sec_type;
+
+		break;
+	}
+	default:
+	{
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "ERROR: unknown param %d in %s", select,
+			  __func__);
+		break;
+	}
+	} /* switch */
+	ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL);
+}
+
+uint8_t
+ol_txrx_peer_uapsdmask_get(struct ol_txrx_pdev_t *txrx_pdev, uint16_t peer_id)
+{
+
+	struct ol_txrx_peer_t *peer;
+
+	peer = ol_txrx_peer_find_by_id(txrx_pdev, peer_id);
+	if (peer)
+		return peer->uapsd_mask;
+	return 0;
+}
+
+uint8_t
+ol_txrx_peer_qoscapable_get(struct ol_txrx_pdev_t *txrx_pdev, uint16_t peer_id)
+{
+
+	struct ol_txrx_peer_t *peer_t =
+		ol_txrx_peer_find_by_id(txrx_pdev, peer_id);
+	if (peer_t != NULL)
+		return peer_t->qos_capable;
+	return 0;
+}
+
+/**
+ * ol_txrx_peer_free_tids() - free tids for the peer
+ * @peer: peer handle
+ *
+ * Return: None
+ */
+static inline void ol_txrx_peer_free_tids(ol_txrx_peer_handle peer)
+{
+	int i = 0;
+	/*
+	 * 'array' is allocated in addba handler and is supposed to be
+	 * freed in delba handler. There is the case (for example, in
+	 * SSR) where delba handler is not called. Because array points
+	 * to address of 'base' by default and is reallocated in addba
+	 * handler later, only free the memory when the array does not
+	 * point to base.
+	 */
+	for (i = 0; i < OL_TXRX_NUM_EXT_TIDS; i++) {
+		if (peer->tids_rx_reorder[i].array !=
+		    &peer->tids_rx_reorder[i].base) {
+			ol_txrx_dbg(
+				   "%s, delete reorder arr, tid:%d\n",
+				   __func__, i);
+			qdf_mem_free(peer->tids_rx_reorder[i].array);
+			ol_rx_reorder_init(&peer->tids_rx_reorder[i],
+					   (uint8_t)i);
+		}
+	}
+}
+
+/**
+ * ol_txrx_peer_release_ref() - release peer reference
+ * @peer: peer handle
+ *
+ * Release peer reference and delete peer if refcount is 0
+ *
+ * Return: Resulting peer ref_cnt after this function is invoked
+ */
+int ol_txrx_peer_release_ref(ol_txrx_peer_handle peer,
+			     enum peer_debug_id_type debug_id)
+{
+	int    rc;
+	struct ol_txrx_vdev_t *vdev;
+	struct ol_txrx_pdev_t *pdev;
+	bool ref_silent = false;
+	int access_list = 0;
+	uint32_t err_code = 0;
+
+	/* preconditions */
+	TXRX_ASSERT2(peer);
+
+	vdev = peer->vdev;
+	if (NULL == vdev) {
+		ol_txrx_err("The vdev is not present anymore\n");
+		return -EINVAL;
+	}
+
+	pdev = vdev->pdev;
+	if (NULL == pdev) {
+		ol_txrx_err("The pdev is not present anymore\n");
+		err_code = 0xbad2;
+		goto ERR_STATE;
+	}
+
+	if (debug_id >= PEER_DEBUG_ID_MAX || debug_id < 0) {
+		ol_txrx_err("incorrect debug_id %d ", debug_id);
+		err_code = 0xbad3;
+		goto ERR_STATE;
+	}
+
+	if (debug_id == PEER_DEBUG_ID_OL_RX_THREAD)
+		ref_silent = true;
+
+	if (!ref_silent)
+		wlan_roam_debug_log(vdev->vdev_id, DEBUG_PEER_UNREF_DELETE,
+				    DEBUG_INVALID_PEER_ID, &peer->mac_addr.raw,
+				    peer, 0xdead,
+				    qdf_atomic_read(&peer->ref_cnt));
+
+
+	/*
+	 * Hold the lock all the way from checking if the peer ref count
+	 * is zero until the peer references are removed from the hash
+	 * table and vdev list (if the peer ref count is zero).
+	 * This protects against a new HL tx operation starting to use the
+	 * peer object just after this function concludes it's done being used.
+	 * Furthermore, the lock needs to be held while checking whether the
+	 * vdev's list of peers is empty, to make sure that list is not modified
+	 * concurrently with the empty check.
+	 */
+	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+
+	/*
+	 * Check for the reference count before deleting the peer
+	 * as we noticed that sometimes we are re-entering this
+	 * function again which is leading to dead-lock.
+	 * (A double-free should never happen, so assert if it does.)
+	 */
+	rc = qdf_atomic_read(&(peer->ref_cnt));
+
+	if (rc == 0) {
+		qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+		ol_txrx_err("The Peer is not present anymore\n");
+		qdf_assert(0);
+		return -EACCES;
+	}
+	/*
+	 * now decrement rc; this will be the return code.
+	 * 0 : peer deleted
+	 * >0: peer ref removed, but still has other references
+	 * <0: sanity failed - no changes to the state of the peer
+	 */
+	rc--;
+
+	if (!qdf_atomic_read(&peer->access_list[debug_id])) {
+		qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+		ol_txrx_err("peer %pK ref was not taken by %d",
+			    peer, debug_id);
+		ol_txrx_dump_peer_access_list(peer);
+		QDF_BUG(0);
+		return -EACCES;
+	}
+	qdf_atomic_dec(&peer->access_list[debug_id]);
+
+	if (qdf_atomic_dec_and_test(&peer->ref_cnt)) {
+		u16 peer_id;
+		wlan_roam_debug_log(vdev->vdev_id,
+				    DEBUG_DELETING_PEER_OBJ,
+				    DEBUG_INVALID_PEER_ID,
+				    &peer->mac_addr.raw, peer, 0,
+				    qdf_atomic_read(&peer->ref_cnt));
+		peer_id = peer->local_id;
+		/* remove the reference to the peer from the hash table */
+		ol_txrx_peer_find_hash_remove(pdev, peer);
+
+		/* remove the peer from its parent vdev's list */
+		TAILQ_REMOVE(&peer->vdev->peer_list, peer, peer_list_elem);
+
+		/* cleanup the Rx reorder queues for this peer */
+		ol_rx_peer_cleanup(vdev, peer);
+
+		qdf_spinlock_destroy(&peer->peer_info_lock);
+		qdf_spinlock_destroy(&peer->bufq_info.bufq_lock);
+
+		/* peer is removed from peer_list */
+		qdf_atomic_set(&peer->delete_in_progress, 0);
+
+		/*
+		 * Set wait_delete_comp event if the current peer id matches
+		 * with registered peer id.
+		 */
+		if (peer_id == vdev->wait_on_peer_id) {
+			qdf_event_set(&vdev->wait_delete_comp);
+			vdev->wait_on_peer_id = OL_TXRX_INVALID_LOCAL_PEER_ID;
+		}
+
+		qdf_timer_sync_cancel(&peer->peer_unmap_timer);
+		qdf_timer_free(&peer->peer_unmap_timer);
+
+		/* check whether the parent vdev has no peers left */
+		if (TAILQ_EMPTY(&vdev->peer_list)) {
+			/*
+			 * Check if the parent vdev was waiting for its peers
+			 * to be deleted, in order for it to be deleted too.
+			 */
+			if (vdev->delete.pending) {
+				ol_txrx_vdev_delete_cb vdev_delete_cb =
+					vdev->delete.callback;
+				void *vdev_delete_context =
+					vdev->delete.context;
+				/*
+				 * Now that there are no references to the peer,
+				 * we can release the peer reference lock.
+				 */
+				qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+
+				/*
+				 * The ol_tx_desc_free might access the invalid
+				 * content of vdev referred by tx desc, since
+				 * this vdev might be detached in another thread
+				 * asynchronous.
+				 *
+				 * Go through tx desc pool to set corresponding
+				 * tx desc's vdev to NULL when detach this vdev,
+				 * and add vdev checking in the ol_tx_desc_free
+				 * to avoid crash.
+				 */
+				ol_txrx_tx_desc_reset_vdev(vdev);
+				ol_txrx_dbg(
+					"%s: deleting vdev object %pK (%02x:%02x:%02x:%02x:%02x:%02x) - its last peer is done",
+					__func__, vdev,
+					vdev->mac_addr.raw[0],
+					vdev->mac_addr.raw[1],
+					vdev->mac_addr.raw[2],
+					vdev->mac_addr.raw[3],
+					vdev->mac_addr.raw[4],
+					vdev->mac_addr.raw[5]);
+				/* all peers are gone, go ahead and delete it */
+				qdf_mem_free(vdev);
+				if (vdev_delete_cb)
+					vdev_delete_cb(vdev_delete_context);
+			} else {
+				qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+			}
+		} else {
+			qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+		}
+
+		ol_txrx_info_high("[%d][%d]: Deleting peer %pK ref_cnt -> %d %s",
+				  debug_id,
+				  qdf_atomic_read(&peer->access_list[debug_id]),
+				  peer, rc,
+				  qdf_atomic_read(&peer->fw_create_pending)
+									== 1 ?
+				  "(No Maps received)" : "");
+
+		ol_txrx_peer_tx_queue_free(pdev, peer);
+
+		/* Remove mappings from peer_id to peer object */
+		ol_txrx_peer_clear_map_peer(pdev, peer);
+
+		/* Remove peer pointer from local peer ID map */
+		ol_txrx_local_peer_id_free(pdev, peer);
+
+		ol_txrx_peer_free_tids(peer);
+
+		ol_txrx_dump_peer_access_list(peer);
+
+		qdf_mem_free(peer);
+	} else {
+		access_list = qdf_atomic_read(&peer->access_list[debug_id]);
+		qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+		if (!ref_silent)
+			ol_txrx_info_high("[%d][%d]: ref delete peer %pK ref_cnt -> %d",
+					  debug_id,
+					  access_list,
+					  peer, rc);
+	}
+	return rc;
+ERR_STATE:
+	wlan_roam_debug_log(vdev->vdev_id, DEBUG_PEER_UNREF_DELETE,
+			    DEBUG_INVALID_PEER_ID, &peer->mac_addr.raw,
+			    peer, err_code, qdf_atomic_read(&peer->ref_cnt));
+	return -EINVAL;
+}
+
+/**
+ * ol_txrx_clear_peer_internal() - ol internal function to clear peer
+ * @peer: pointer to ol txrx peer structure
+ *
+ * Return: QDF Status
+ */
+static QDF_STATUS
+ol_txrx_clear_peer_internal(struct ol_txrx_peer_t *peer)
+{
+	p_cds_sched_context sched_ctx = get_cds_sched_ctxt();
+	/* Drop pending Rx frames in CDS */
+	if (sched_ctx)
+		cds_drop_rxpkt_by_staid(sched_ctx, peer->local_id);
+
+	/* Purge the cached rx frame queue */
+	ol_txrx_flush_rx_frames(peer, 1);
+
+	qdf_spin_lock_bh(&peer->peer_info_lock);
+	peer->state = OL_TXRX_PEER_STATE_DISC;
+	qdf_spin_unlock_bh(&peer->peer_info_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_clear_peer() - clear peer
+ * @sta_id: sta id
+ *
+ * Return: QDF Status
+ */
+static QDF_STATUS ol_txrx_clear_peer(struct cdp_pdev *ppdev, uint8_t sta_id)
+{
+	struct ol_txrx_peer_t *peer;
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	QDF_STATUS status;
+
+	if (!pdev) {
+		ol_txrx_err("Unable to find pdev!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (sta_id >= WLAN_MAX_STA_COUNT) {
+		ol_txrx_err("Invalid sta id %d", sta_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	peer = ol_txrx_peer_get_ref_by_local_id(ppdev, sta_id,
+						PEER_DEBUG_ID_OL_INTERNAL);
+
+	/* Return success, if the peer is already cleared by
+	 * data path via peer detach function.
+	 */
+	if (!peer)
+		return QDF_STATUS_SUCCESS;
+
+	ol_txrx_dbg("Clear peer rx frames: " QDF_MAC_ADDR_STR,
+		    QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw));
+	ol_txrx_clear_peer_internal(peer);
+	status = ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL);
+
+	return status;
+}
+
+void peer_unmap_timer_work_function(void *param)
+{
+	WMA_LOGI("Enter: %s", __func__);
+	/* Added for debugging only */
+	ol_txrx_dump_peer_access_list(param);
+	wlan_roam_debug_dump_table();
+	cds_trigger_recovery(QDF_PEER_UNMAP_TIMEDOUT);
+}
+
+/**
+ * peer_unmap_timer_handler() - peer unmap timer function
+ * @data: peer object pointer
+ *
+ * Return: none
+ */
+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 %pK, ref_cnt %d",
+		    peer, qdf_atomic_read(&peer->ref_cnt));
+	ol_txrx_err("peer %pK (%02x:%02x:%02x:%02x:%02x:%02x)",
+		    peer,
+		    peer->mac_addr.raw[0], peer->mac_addr.raw[1],
+		    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() && !cds_is_fw_down()) {
+		qdf_create_work(0, &txrx_pdev->peer_unmap_timer_work,
+				peer_unmap_timer_work_function,
+				peer);
+		qdf_sched_work(0, &txrx_pdev->peer_unmap_timer_work);
+	} else {
+		ol_txrx_err("Recovery is in progress, ignore!");
+	}
+}
+
+
+/**
+ * ol_txrx_peer_detach() - Delete a peer's data object.
+ * @peer - the object to detach
+ * @bitmap - bitmap indicating special handling of request.
+ *
+ * When the host's control SW disassociates a peer, it calls
+ * this function to detach and delete the peer. The reference
+ * stored in the control peer object to the data peer
+ * object (set up by a call to ol_peer_store()) is provided.
+ *
+ * Return: None
+ */
+static void ol_txrx_peer_detach(void *ppeer, uint32_t bitmap)
+{
+	ol_txrx_peer_handle peer = ppeer;
+	struct ol_txrx_vdev_t *vdev = peer->vdev;
+
+	/* redirect peer's rx delivery function to point to a discard func */
+	peer->rx_opt_proc = ol_rx_discard;
+
+	peer->valid = 0;
+
+	/* flush all rx packets before clearing up the peer local_id */
+	ol_txrx_clear_peer_internal(peer);
+
+	/* debug print to dump rx reorder state */
+	/* htt_rx_reorder_log_print(vdev->pdev->htt_pdev); */
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		   "%s:peer %pK (%02x:%02x:%02x:%02x:%02x:%02x)",
+		   __func__, peer,
+		   peer->mac_addr.raw[0], peer->mac_addr.raw[1],
+		   peer->mac_addr.raw[2], peer->mac_addr.raw[3],
+		   peer->mac_addr.raw[4], peer->mac_addr.raw[5]);
+
+	qdf_spin_lock_bh(&vdev->pdev->last_real_peer_mutex);
+	if (vdev->last_real_peer == peer)
+		vdev->last_real_peer = NULL;
+	qdf_spin_unlock_bh(&vdev->pdev->last_real_peer_mutex);
+	htt_rx_reorder_log_print(peer->vdev->pdev->htt_pdev);
+
+	/*
+	 * set delete_in_progress to identify that wma
+	 * is waiting for unmap massage for this peer
+	 */
+	qdf_atomic_set(&peer->delete_in_progress, 1);
+
+	if (!(bitmap & (1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER))) {
+		if (vdev->opmode == wlan_op_mode_sta) {
+			qdf_mem_copy(&peer->vdev->last_peer_mac_addr,
+				&peer->mac_addr,
+				sizeof(union ol_txrx_align_mac_addr_t));
+
+			/*
+			 * Create a timer to track unmap events when the
+			 * sta peer gets deleted.
+			 */
+			qdf_timer_start(&peer->peer_unmap_timer,
+					OL_TXRX_PEER_UNMAP_TIMEOUT);
+			ol_txrx_info_high
+				("started peer_unmap_timer for peer %pK",
+				  peer);
+		}
+	}
+
+	/*
+	 * Remove the reference added during peer_attach.
+	 * The peer will still be left allocated until the
+	 * PEER_UNMAP message arrives to remove the other
+	 * reference, added by the PEER_MAP message.
+	 */
+	ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_PEER_ATTACH);
+}
+
+/**
+ * ol_txrx_peer_detach_force_delete() - Detach and delete a peer's data object
+ * @ppeer - the object to detach
+ *
+ * Detach a peer and force peer object to be removed. It is called during
+ * roaming scenario when the firmware has already deleted a peer.
+ * Remove it from the peer_id_to_object map. Peer object is actually freed
+ * when last reference is deleted.
+ *
+ * Return: None
+ */
+static void ol_txrx_peer_detach_force_delete(void *ppeer)
+{
+	ol_txrx_peer_handle peer = ppeer;
+	ol_txrx_pdev_handle pdev = peer->vdev->pdev;
+
+	ol_txrx_info_high("%s peer %pK, peer->ref_cnt %d",
+		__func__, peer, qdf_atomic_read(&peer->ref_cnt));
+
+	/* Clear the peer_id_to_obj map entries */
+	ol_txrx_peer_remove_obj_map_entries(pdev, peer);
+	ol_txrx_peer_detach(peer, 1 << CDP_PEER_DELETE_NO_SPECIAL);
+}
+
+/**
+ * ol_txrx_dump_tx_desc() - dump tx desc total and free count
+ * @txrx_pdev: Pointer to txrx pdev
+ *
+ * Return: none
+ */
+static void ol_txrx_dump_tx_desc(ol_txrx_pdev_handle pdev_handle)
+{
+	struct ol_txrx_pdev_t *pdev = (ol_txrx_pdev_handle) pdev_handle;
+	uint32_t total, num_free;
+
+	if (ol_cfg_is_high_latency(pdev->ctrl_pdev))
+		total = qdf_atomic_read(&pdev->orig_target_tx_credit);
+	else
+		total = ol_tx_get_desc_global_pool_size(pdev);
+
+	num_free = ol_tx_get_total_free_desc(pdev);
+
+	ol_txrx_info_high(
+		   "total tx credit %d num_free %d",
+		   total, num_free);
+
+}
+
+/**
+ * ol_txrx_wait_for_pending_tx() - wait for tx queue to be empty
+ * @timeout: timeout in ms
+ *
+ * Wait for tx queue to be empty, return timeout error if
+ * queue doesn't empty before timeout occurs.
+ *
+ * Return:
+ *    QDF_STATUS_SUCCESS if the queue empties,
+ *    QDF_STATUS_E_TIMEOUT in case of timeout,
+ *    QDF_STATUS_E_FAULT in case of missing handle
+ */
+static QDF_STATUS ol_txrx_wait_for_pending_tx(int timeout)
+{
+	struct ol_txrx_pdev_t *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (txrx_pdev == NULL) {
+		ol_txrx_err(
+			   "%s: txrx context is null", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	while (ol_txrx_get_tx_pending((struct cdp_pdev *)txrx_pdev)) {
+		qdf_sleep(OL_ATH_TX_DRAIN_WAIT_DELAY);
+		if (timeout <= 0) {
+			ol_txrx_err(
+				   "%s: tx frames are pending", __func__);
+			ol_txrx_dump_tx_desc(txrx_pdev);
+			return QDF_STATUS_E_TIMEOUT;
+		}
+		timeout = timeout - OL_ATH_TX_DRAIN_WAIT_DELAY;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifndef QCA_WIFI_3_0_EMU
+#define SUSPEND_DRAIN_WAIT 500
+#else
+#define SUSPEND_DRAIN_WAIT 3000
+#endif
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * ol_txrx_runtime_suspend() - ensure TXRX is ready to runtime suspend
+ * @txrx_pdev: TXRX pdev context
+ *
+ * TXRX is ready to runtime suspend if there are no pending packets
+ * in the tx queue.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ol_txrx_runtime_suspend(struct cdp_pdev *ppdev)
+{
+	struct ol_txrx_pdev_t *txrx_pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	if (ol_txrx_get_tx_pending((struct cdp_pdev *)txrx_pdev))
+		return QDF_STATUS_E_BUSY;
+	else
+		return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_runtime_resume() - ensure TXRX is ready to runtime resume
+ * @txrx_pdev: TXRX pdev context
+ *
+ * This is a dummy function for symmetry.
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+static QDF_STATUS ol_txrx_runtime_resume(struct cdp_pdev *ppdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * ol_txrx_bus_suspend() - bus suspend
+ * @ppdev: TXRX pdev context
+ *
+ * Ensure that ol_txrx is ready for bus suspend
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ol_txrx_bus_suspend(struct cdp_pdev *ppdev)
+{
+	return ol_txrx_wait_for_pending_tx(SUSPEND_DRAIN_WAIT);
+}
+
+/**
+ * ol_txrx_bus_resume() - bus resume
+ * @ppdev: TXRX pdev context
+ *
+ * Dummy function for symetry
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+static QDF_STATUS ol_txrx_bus_resume(struct cdp_pdev *ppdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_get_tx_pending - Get the number of pending transmit
+ * frames that are awaiting completion.
+ *
+ * @pdev - the data physical device object
+ *  Mainly used in clean up path to make sure all buffers have been freed
+ *
+ * Return: count of pending frames
+ */
+int ol_txrx_get_tx_pending(struct cdp_pdev *ppdev)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	uint32_t total;
+
+	if (ol_cfg_is_high_latency(pdev->ctrl_pdev))
+		total = qdf_atomic_read(&pdev->orig_target_tx_credit);
+	else
+		total = ol_tx_get_desc_global_pool_size(pdev);
+
+	return total - ol_tx_get_total_free_desc(pdev);
+}
+
+void ol_txrx_discard_tx_pending(ol_txrx_pdev_handle pdev_handle)
+{
+	ol_tx_desc_list tx_descs;
+	/*
+	 * First let hif do the qdf_atomic_dec_and_test(&tx_desc->ref_cnt)
+	 * then let htt do the qdf_atomic_dec_and_test(&tx_desc->ref_cnt)
+	 * which is tha same with normal data send complete path
+	 */
+	htt_tx_pending_discard(pdev_handle->htt_pdev);
+
+	TAILQ_INIT(&tx_descs);
+	ol_tx_queue_discard(pdev_handle, true, &tx_descs);
+	/* Discard Frames in Discard List */
+	ol_tx_desc_frame_list_free(pdev_handle, &tx_descs, 1 /* error */);
+
+	ol_tx_discard_target_frms(pdev_handle);
+}
+
+static inline
+uint64_t ol_txrx_stats_ptr_to_u64(struct ol_txrx_stats_req_internal *req)
+{
+	return (uint64_t) ((size_t) req);
+}
+
+static inline
+struct ol_txrx_stats_req_internal *ol_txrx_u64_to_stats_ptr(uint64_t cookie)
+{
+	return (struct ol_txrx_stats_req_internal *)((size_t) cookie);
+}
+
+#ifdef currently_unused
+void
+ol_txrx_fw_stats_cfg(ol_txrx_vdev_handle vdev,
+		     uint8_t cfg_stats_type, uint32_t cfg_val)
+{
+	uint8_t dummy_cookie = 0;
+
+	htt_h2t_dbg_stats_get(vdev->pdev->htt_pdev, 0 /* upload mask */,
+			      0 /* reset mask */,
+			      cfg_stats_type, cfg_val, dummy_cookie);
+}
+#endif
+
+/**
+ * ol_txrx_fw_stats_desc_pool_init() - Initialize the fw stats descriptor pool
+ * @pdev: handle to ol txrx pdev
+ * @pool_size: Size of fw stats descriptor pool
+ *
+ * Return: 0 for success, error code on failure.
+ */
+int ol_txrx_fw_stats_desc_pool_init(struct ol_txrx_pdev_t *pdev,
+				    uint8_t pool_size)
+{
+	int i;
+
+	if (!pdev) {
+		ol_txrx_err("%s: pdev is NULL", __func__);
+		return -EINVAL;
+	}
+	pdev->ol_txrx_fw_stats_desc_pool.pool = qdf_mem_malloc(pool_size *
+		sizeof(struct ol_txrx_fw_stats_desc_elem_t));
+	if (!pdev->ol_txrx_fw_stats_desc_pool.pool) {
+		ol_txrx_err("%s: failed to allocate desc pool", __func__);
+		return -ENOMEM;
+	}
+	pdev->ol_txrx_fw_stats_desc_pool.freelist =
+		&pdev->ol_txrx_fw_stats_desc_pool.pool[0];
+	pdev->ol_txrx_fw_stats_desc_pool.pool_size = pool_size;
+
+	for (i = 0; i < (pool_size - 1); i++) {
+		pdev->ol_txrx_fw_stats_desc_pool.pool[i].desc.desc_id = i;
+		pdev->ol_txrx_fw_stats_desc_pool.pool[i].desc.req = NULL;
+		pdev->ol_txrx_fw_stats_desc_pool.pool[i].next =
+			&pdev->ol_txrx_fw_stats_desc_pool.pool[i + 1];
+	}
+	pdev->ol_txrx_fw_stats_desc_pool.pool[i].desc.desc_id = i;
+	pdev->ol_txrx_fw_stats_desc_pool.pool[i].desc.req = NULL;
+	pdev->ol_txrx_fw_stats_desc_pool.pool[i].next = NULL;
+	qdf_spinlock_create(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock);
+	qdf_atomic_init(&pdev->ol_txrx_fw_stats_desc_pool.initialized);
+	qdf_atomic_set(&pdev->ol_txrx_fw_stats_desc_pool.initialized, 1);
+	return 0;
+}
+
+/**
+ * ol_txrx_fw_stats_desc_pool_deinit() - Deinitialize the
+ * fw stats descriptor pool
+ * @pdev: handle to ol txrx pdev
+ *
+ * Return: None
+ */
+void ol_txrx_fw_stats_desc_pool_deinit(struct ol_txrx_pdev_t *pdev)
+{
+	if (!pdev) {
+		ol_txrx_err("%s: pdev is NULL", __func__);
+		return;
+	}
+	if (!qdf_atomic_read(&pdev->ol_txrx_fw_stats_desc_pool.initialized)) {
+		ol_txrx_err("%s: Pool is not initialized", __func__);
+		return;
+	}
+	if (!pdev->ol_txrx_fw_stats_desc_pool.pool) {
+		ol_txrx_err("%s: Pool is not allocated", __func__);
+		return;
+	}
+	qdf_spin_lock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock);
+	qdf_atomic_set(&pdev->ol_txrx_fw_stats_desc_pool.initialized, 0);
+	qdf_mem_free(pdev->ol_txrx_fw_stats_desc_pool.pool);
+	pdev->ol_txrx_fw_stats_desc_pool.pool = NULL;
+
+	pdev->ol_txrx_fw_stats_desc_pool.freelist = NULL;
+	pdev->ol_txrx_fw_stats_desc_pool.pool_size = 0;
+	qdf_spin_unlock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock);
+}
+
+/**
+ * ol_txrx_fw_stats_desc_alloc() - Get fw stats descriptor from fw stats
+ * free descriptor pool
+ * @pdev: handle to ol txrx pdev
+ *
+ * Return: pointer to fw stats descriptor, NULL on failure
+ */
+struct ol_txrx_fw_stats_desc_t
+	*ol_txrx_fw_stats_desc_alloc(struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_txrx_fw_stats_desc_t *desc = NULL;
+
+	qdf_spin_lock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock);
+	if (!qdf_atomic_read(&pdev->ol_txrx_fw_stats_desc_pool.initialized)) {
+		qdf_spin_unlock_bh(&pdev->
+				   ol_txrx_fw_stats_desc_pool.pool_lock);
+		ol_txrx_err("%s: Pool deinitialized", __func__);
+		return NULL;
+	}
+	if (pdev->ol_txrx_fw_stats_desc_pool.freelist) {
+		desc = &pdev->ol_txrx_fw_stats_desc_pool.freelist->desc;
+		pdev->ol_txrx_fw_stats_desc_pool.freelist =
+			pdev->ol_txrx_fw_stats_desc_pool.freelist->next;
+	}
+	qdf_spin_unlock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock);
+
+	if (desc)
+		ol_txrx_dbg("%s: desc_id %d allocated",
+			    __func__, desc->desc_id);
+	else
+		ol_txrx_err("%s: fw stats descriptors are exhausted", __func__);
+
+	return desc;
+}
+
+/**
+ * ol_txrx_fw_stats_desc_get_req() - Put fw stats descriptor
+ * back into free pool
+ * @pdev: handle to ol txrx pdev
+ * @fw_stats_desc: fw_stats_desc_get descriptor
+ *
+ * Return: pointer to request
+ */
+struct ol_txrx_stats_req_internal
+	*ol_txrx_fw_stats_desc_get_req(struct ol_txrx_pdev_t *pdev,
+				       unsigned char desc_id)
+{
+	struct ol_txrx_fw_stats_desc_elem_t *desc_elem;
+	struct ol_txrx_stats_req_internal *req;
+
+	qdf_spin_lock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock);
+	if (!qdf_atomic_read(&pdev->ol_txrx_fw_stats_desc_pool.initialized)) {
+		qdf_spin_unlock_bh(&pdev->
+				   ol_txrx_fw_stats_desc_pool.pool_lock);
+		ol_txrx_err("%s: Desc ID %u Pool deinitialized",
+			    __func__, desc_id);
+		return NULL;
+	}
+	desc_elem = &pdev->ol_txrx_fw_stats_desc_pool.pool[desc_id];
+	req = desc_elem->desc.req;
+	desc_elem->desc.req = NULL;
+	desc_elem->next =
+		pdev->ol_txrx_fw_stats_desc_pool.freelist;
+	pdev->ol_txrx_fw_stats_desc_pool.freelist = desc_elem;
+	qdf_spin_unlock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock);
+	return req;
+}
+
+static A_STATUS
+ol_txrx_fw_stats_get(struct cdp_vdev *pvdev, struct ol_txrx_stats_req *req,
+			bool per_vdev, bool response_expected)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	uint8_t cookie = FW_STATS_DESC_POOL_SIZE;
+	struct ol_txrx_stats_req_internal *non_volatile_req;
+	struct ol_txrx_fw_stats_desc_t *desc = NULL;
+	struct ol_txrx_fw_stats_desc_elem_t *elem = NULL;
+
+	if (!pdev ||
+	    req->stats_type_upload_mask >= 1 << HTT_DBG_NUM_STATS ||
+	    req->stats_type_reset_mask >= 1 << HTT_DBG_NUM_STATS) {
+		return A_ERROR;
+	}
+
+	/*
+	 * Allocate a non-transient stats request object.
+	 * (The one provided as an argument is likely allocated on the stack.)
+	 */
+	non_volatile_req = qdf_mem_malloc(sizeof(*non_volatile_req));
+	if (!non_volatile_req)
+		return A_NO_MEMORY;
+
+	/* copy the caller's specifications */
+	non_volatile_req->base = *req;
+	non_volatile_req->serviced = 0;
+	non_volatile_req->offset = 0;
+	if (response_expected) {
+		desc = ol_txrx_fw_stats_desc_alloc(pdev);
+		if (!desc) {
+			qdf_mem_free(non_volatile_req);
+			return A_ERROR;
+		}
+
+		/* use the desc id as the cookie */
+		cookie = desc->desc_id;
+		desc->req = non_volatile_req;
+		qdf_spin_lock_bh(&pdev->req_list_spinlock);
+		TAILQ_INSERT_TAIL(&pdev->req_list, non_volatile_req, req_list_elem);
+		pdev->req_list_depth++;
+		qdf_spin_unlock_bh(&pdev->req_list_spinlock);
+	}
+
+	if (htt_h2t_dbg_stats_get(pdev->htt_pdev,
+				  req->stats_type_upload_mask,
+				  req->stats_type_reset_mask,
+				  HTT_H2T_STATS_REQ_CFG_STAT_TYPE_INVALID, 0,
+				  cookie)) {
+		if (response_expected) {
+			qdf_spin_lock_bh(&pdev->req_list_spinlock);
+			TAILQ_REMOVE(&pdev->req_list, non_volatile_req,
+				     req_list_elem);
+			pdev->req_list_depth--;
+			qdf_spin_unlock_bh(&pdev->req_list_spinlock);
+			if (desc) {
+				qdf_spin_lock_bh(&pdev->ol_txrx_fw_stats_desc_pool.
+						 pool_lock);
+				desc->req = NULL;
+				elem = container_of(desc,
+						    struct ol_txrx_fw_stats_desc_elem_t,
+						    desc);
+				elem->next =
+					pdev->ol_txrx_fw_stats_desc_pool.freelist;
+				pdev->ol_txrx_fw_stats_desc_pool.freelist = elem;
+				qdf_spin_unlock_bh(&pdev->
+						   ol_txrx_fw_stats_desc_pool.
+						   pool_lock);
+			}
+		}
+
+		qdf_mem_free(non_volatile_req);
+		return A_ERROR;
+	}
+
+	if (response_expected == false)
+		qdf_mem_free(non_volatile_req);
+
+	return A_OK;
+}
+
+void
+ol_txrx_fw_stats_handler(ol_txrx_pdev_handle pdev,
+			 uint8_t cookie, uint8_t *stats_info_list)
+{
+	enum htt_dbg_stats_type type;
+	enum htt_cmn_dbg_stats_type cmn_type = HTT_DBG_CMN_NUM_STATS_INVALID;
+	enum htt_dbg_stats_status status;
+	int length;
+	uint8_t *stats_data;
+	struct ol_txrx_stats_req_internal *req, *tmp;
+	int more = 0;
+	int found = 0;
+
+	if (cookie >= FW_STATS_DESC_POOL_SIZE) {
+		ol_txrx_err("%s: Cookie is not valid", __func__);
+		return;
+	}
+	req = ol_txrx_fw_stats_desc_get_req(pdev, (uint8_t)cookie);
+	if (!req) {
+		ol_txrx_err("%s: Request not retrieved for cookie %u", __func__,
+			    (uint8_t)cookie);
+		return;
+	}
+	qdf_spin_lock_bh(&pdev->req_list_spinlock);
+	TAILQ_FOREACH(tmp, &pdev->req_list, req_list_elem) {
+		if (req == tmp) {
+			found = 1;
+			break;
+		}
+	}
+	qdf_spin_unlock_bh(&pdev->req_list_spinlock);
+
+	if (!found) {
+		ol_txrx_err(
+			"req(%pK) from firmware can't be found in the list\n", req);
+		return;
+	}
+
+	do {
+		htt_t2h_dbg_stats_hdr_parse(stats_info_list, &type, &status,
+					    &length, &stats_data);
+		if (status == HTT_DBG_STATS_STATUS_SERIES_DONE)
+			break;
+		if (status == HTT_DBG_STATS_STATUS_PRESENT ||
+		    status == HTT_DBG_STATS_STATUS_PARTIAL) {
+			uint8_t *buf;
+			int bytes = 0;
+
+			if (status == HTT_DBG_STATS_STATUS_PARTIAL)
+				more = 1;
+			if (req->base.print.verbose || req->base.print.concise)
+				/* provide the header along with the data */
+				htt_t2h_stats_print(stats_info_list,
+						    req->base.print.concise);
+
+			switch (type) {
+			case HTT_DBG_STATS_WAL_PDEV_TXRX:
+				bytes = sizeof(struct wlan_dbg_stats);
+				if (req->base.copy.buf) {
+					int lmt;
+
+					lmt = sizeof(struct wlan_dbg_stats);
+					if (req->base.copy.byte_limit < lmt)
+						lmt = req->base.copy.byte_limit;
+					buf = req->base.copy.buf + req->offset;
+					qdf_mem_copy(buf, stats_data, lmt);
+				}
+				break;
+			case HTT_DBG_STATS_RX_REORDER:
+				bytes = sizeof(struct rx_reorder_stats);
+				if (req->base.copy.buf) {
+					int lmt;
+
+					lmt = sizeof(struct rx_reorder_stats);
+					if (req->base.copy.byte_limit < lmt)
+						lmt = req->base.copy.byte_limit;
+					buf = req->base.copy.buf + req->offset;
+					qdf_mem_copy(buf, stats_data, lmt);
+				}
+				break;
+			case HTT_DBG_STATS_RX_RATE_INFO:
+				bytes = sizeof(wlan_dbg_rx_rate_info_t);
+				if (req->base.copy.buf) {
+					int lmt;
+
+					lmt = sizeof(wlan_dbg_rx_rate_info_t);
+					if (req->base.copy.byte_limit < lmt)
+						lmt = req->base.copy.byte_limit;
+					buf = req->base.copy.buf + req->offset;
+					qdf_mem_copy(buf, stats_data, lmt);
+				}
+				break;
+
+			case HTT_DBG_STATS_TX_RATE_INFO:
+				bytes = sizeof(wlan_dbg_tx_rate_info_t);
+				if (req->base.copy.buf) {
+					int lmt;
+
+					lmt = sizeof(wlan_dbg_tx_rate_info_t);
+					if (req->base.copy.byte_limit < lmt)
+						lmt = req->base.copy.byte_limit;
+					buf = req->base.copy.buf + req->offset;
+					qdf_mem_copy(buf, stats_data, lmt);
+				}
+				break;
+
+			case HTT_DBG_STATS_TX_PPDU_LOG:
+				bytes = 0;
+				/* TO DO: specify how many bytes are present */
+				/* TO DO: add copying to the requestor's buf */
+
+			case HTT_DBG_STATS_RX_REMOTE_RING_BUFFER_INFO:
+				bytes = sizeof(struct
+						rx_remote_buffer_mgmt_stats);
+				if (req->base.copy.buf) {
+					int limit;
+
+					limit = sizeof(struct
+						rx_remote_buffer_mgmt_stats);
+					if (req->base.copy.byte_limit < limit)
+						limit = req->base.copy.
+							byte_limit;
+					buf = req->base.copy.buf + req->offset;
+					qdf_mem_copy(buf, stats_data, limit);
+				}
+				break;
+
+			case HTT_DBG_STATS_TXBF_INFO:
+				bytes = sizeof(struct wlan_dbg_txbf_data_stats);
+				if (req->base.copy.buf) {
+					int limit;
+
+					limit = sizeof(struct
+						wlan_dbg_txbf_data_stats);
+					if (req->base.copy.byte_limit < limit)
+						limit = req->base.copy.
+							byte_limit;
+					buf = req->base.copy.buf + req->offset;
+					qdf_mem_copy(buf, stats_data, limit);
+				}
+				break;
+
+			case HTT_DBG_STATS_SND_INFO:
+				bytes = sizeof(struct wlan_dbg_txbf_snd_stats);
+				if (req->base.copy.buf) {
+					int limit;
+
+					limit = sizeof(struct
+						wlan_dbg_txbf_snd_stats);
+					if (req->base.copy.byte_limit < limit)
+						limit = req->base.copy.
+							byte_limit;
+					buf = req->base.copy.buf + req->offset;
+					qdf_mem_copy(buf, stats_data, limit);
+				}
+				break;
+
+			case HTT_DBG_STATS_TX_SELFGEN_INFO:
+				bytes = sizeof(struct
+					wlan_dbg_tx_selfgen_stats);
+				if (req->base.copy.buf) {
+					int limit;
+
+					limit = sizeof(struct
+						wlan_dbg_tx_selfgen_stats);
+					if (req->base.copy.byte_limit < limit)
+						limit = req->base.copy.
+							byte_limit;
+					buf = req->base.copy.buf + req->offset;
+					qdf_mem_copy(buf, stats_data, limit);
+				}
+				break;
+
+			case HTT_DBG_STATS_ERROR_INFO:
+				bytes =
+				  sizeof(struct wlan_dbg_wifi2_error_stats);
+				if (req->base.copy.buf) {
+					int limit;
+
+					limit = sizeof(struct
+						wlan_dbg_wifi2_error_stats);
+					if (req->base.copy.byte_limit < limit)
+						limit = req->base.copy.
+							byte_limit;
+					buf = req->base.copy.buf + req->offset;
+					qdf_mem_copy(buf, stats_data, limit);
+				}
+				break;
+
+			case HTT_DBG_STATS_TXBF_MUSU_NDPA_PKT:
+				bytes =
+				  sizeof(struct rx_txbf_musu_ndpa_pkts_stats);
+				if (req->base.copy.buf) {
+					int limit;
+
+					limit = sizeof(struct
+						rx_txbf_musu_ndpa_pkts_stats);
+					if (req->base.copy.byte_limit <	limit)
+						limit =
+						req->base.copy.byte_limit;
+					buf = req->base.copy.buf + req->offset;
+					qdf_mem_copy(buf, stats_data, limit);
+				}
+				break;
+
+			default:
+				break;
+			}
+			buf = req->base.copy.buf ?
+				req->base.copy.buf : stats_data;
+
+			/* Not implemented for MCL */
+			if (req->base.callback.fp)
+				req->base.callback.fp(req->base.callback.ctxt,
+						      cmn_type, buf, bytes);
+		}
+		stats_info_list += length;
+	} while (1);
+
+	if (!more) {
+		qdf_spin_lock_bh(&pdev->req_list_spinlock);
+		TAILQ_FOREACH(tmp, &pdev->req_list, req_list_elem) {
+			if (req == tmp) {
+				TAILQ_REMOVE(&pdev->req_list, req, req_list_elem);
+				pdev->req_list_depth--;
+				qdf_mem_free(req);
+				break;
+			}
+		}
+		qdf_spin_unlock_bh(&pdev->req_list_spinlock);
+	}
+}
+
+#ifndef ATH_PERF_PWR_OFFLOAD /*---------------------------------------------*/
+int ol_txrx_debug(ol_txrx_vdev_handle vdev, int debug_specs)
+{
+	if (debug_specs & TXRX_DBG_MASK_OBJS) {
+#if defined(TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5
+		ol_txrx_pdev_display(vdev->pdev, 0);
+#else
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_FATAL,
+			  "The pdev,vdev,peer display functions are disabled.\n To enable them, recompile with TXRX_DEBUG_LEVEL > 5");
+#endif
+	}
+	if (debug_specs & TXRX_DBG_MASK_STATS)
+		ol_txrx_stats_display(vdev->pdev,
+				      QDF_STATS_VERBOSITY_LEVEL_HIGH);
+	if (debug_specs & TXRX_DBG_MASK_PROT_ANALYZE) {
+#if defined(ENABLE_TXRX_PROT_ANALYZE)
+		ol_txrx_prot_ans_display(vdev->pdev);
+#else
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_FATAL,
+			  "txrx protocol analysis is disabled.\n To enable it, recompile with ENABLE_TXRX_PROT_ANALYZE defined");
+#endif
+	}
+	if (debug_specs & TXRX_DBG_MASK_RX_REORDER_TRACE) {
+#if defined(ENABLE_RX_REORDER_TRACE)
+		ol_rx_reorder_trace_display(vdev->pdev, 0, 0);
+#else
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_FATAL,
+			  "rx reorder seq num trace is disabled.\n To enable it, recompile with ENABLE_RX_REORDER_TRACE defined");
+#endif
+
+	}
+	return 0;
+}
+#endif
+
+#ifdef currently_unused
+int ol_txrx_aggr_cfg(ol_txrx_vdev_handle vdev,
+		     int max_subfrms_ampdu, int max_subfrms_amsdu)
+{
+	return htt_h2t_aggr_cfg_msg(vdev->pdev->htt_pdev,
+				    max_subfrms_ampdu, max_subfrms_amsdu);
+}
+#endif
+
+#if defined(TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5
+void ol_txrx_pdev_display(ol_txrx_pdev_handle pdev, int indent)
+{
+	struct ol_txrx_vdev_t *vdev;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*s%s:\n", indent, " ", "txrx pdev");
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*spdev object: %pK", indent + 4, " ", pdev);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*svdev list:", indent + 4, " ");
+	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+		      ol_txrx_vdev_display(vdev, indent + 8);
+	}
+	ol_txrx_peer_find_display(pdev, indent + 4);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*stx desc pool: %d elems @ %pK", indent + 4, " ",
+		  pdev->tx_desc.pool_size, pdev->tx_desc.array);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW, " ");
+	htt_display(pdev->htt_pdev, indent);
+}
+
+void ol_txrx_vdev_display(ol_txrx_vdev_handle vdev, int indent)
+{
+	struct ol_txrx_peer_t *peer;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*stxrx vdev: %pK\n", indent, " ", vdev);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*sID: %d\n", indent + 4, " ", vdev->vdev_id);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*sMAC addr: %d:%d:%d:%d:%d:%d",
+		  indent + 4, " ",
+		  vdev->mac_addr.raw[0], vdev->mac_addr.raw[1],
+		  vdev->mac_addr.raw[2], vdev->mac_addr.raw[3],
+		  vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*speer list:", indent + 4, " ");
+	TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
+		      ol_txrx_peer_display(peer, indent + 8);
+	}
+}
+
+void ol_txrx_peer_display(ol_txrx_peer_handle peer, int indent)
+{
+	int i;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*stxrx peer: %pK", indent, " ", peer);
+	for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) {
+		if (peer->peer_ids[i] != HTT_INVALID_PEER) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+				  "%*sID: %d", indent + 4, " ",
+				  peer->peer_ids[i]);
+		}
+	}
+}
+#endif /* TXRX_DEBUG_LEVEL */
+
+/**
+ * ol_txrx_stats() - update ol layer stats
+ * @vdev_id: vdev_id
+ * @buffer: pointer to buffer
+ * @buf_len: length of the buffer
+ *
+ * Return: length of string
+ */
+static int
+ol_txrx_stats(uint8_t vdev_id, char *buffer, unsigned int buf_len)
+{
+	uint32_t len = 0;
+
+	struct ol_txrx_vdev_t *vdev =
+			(struct ol_txrx_vdev_t *)
+			ol_txrx_get_vdev_from_vdev_id(vdev_id);
+
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: vdev is NULL", __func__);
+		snprintf(buffer, buf_len, "vdev not found");
+		return len;
+	}
+
+	len = scnprintf(buffer, buf_len,
+			"\n\nTXRX stats:\nllQueue State : %s\npause %u unpause %u\noverflow %u\nllQueue timer state : %s",
+			((vdev->ll_pause.is_q_paused == false) ?
+			 "UNPAUSED" : "PAUSED"),
+			vdev->ll_pause.q_pause_cnt,
+			vdev->ll_pause.q_unpause_cnt,
+			vdev->ll_pause.q_overflow_cnt,
+			((vdev->ll_pause.is_q_timer_on == false)
+			 ? "NOT-RUNNING" : "RUNNING"));
+	return len;
+}
+
+#ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID
+/**
+ * ol_txrx_disp_peer_cached_bufq_stats() - display peer cached_bufq stats
+ * @peer: peer pointer
+ *
+ * Return: None
+ */
+static void ol_txrx_disp_peer_cached_bufq_stats(struct ol_txrx_peer_t *peer)
+{
+	txrx_nofl_info("cached_bufq: curr %d drops %d hwm %d whatifs %d thresh %d",
+		       peer->bufq_info.curr,
+		       peer->bufq_info.dropped,
+		       peer->bufq_info.high_water_mark,
+		       peer->bufq_info.qdepth_no_thresh,
+		       peer->bufq_info.thresh);
+}
+
+/**
+ * ol_txrx_disp_peer_stats() - display peer stats
+ * @pdev: pdev pointer
+ *
+ * Return: None
+ */
+static void ol_txrx_disp_peer_stats(ol_txrx_pdev_handle pdev)
+{	int i;
+	struct ol_txrx_peer_t *peer;
+	struct hif_opaque_softc *osc =  cds_get_context(QDF_MODULE_ID_HIF);
+
+	if (osc && hif_is_load_or_unload_in_progress(HIF_GET_SOFTC(osc)))
+		return;
+
+	for (i = 0; i < OL_TXRX_NUM_LOCAL_PEER_IDS; i++) {
+		qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+		qdf_spin_lock_bh(&pdev->local_peer_ids.lock);
+		peer = pdev->local_peer_ids.map[i];
+		if (peer) {
+			ol_txrx_peer_get_ref(peer, PEER_DEBUG_ID_OL_INTERNAL);
+		}
+		qdf_spin_unlock_bh(&pdev->local_peer_ids.lock);
+		qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+
+		if (peer) {
+			txrx_nofl_info("stats: peer 0x%pK local peer id %d",
+				       peer, i);
+			ol_txrx_disp_peer_cached_bufq_stats(peer);
+			ol_txrx_peer_release_ref(peer,
+						 PEER_DEBUG_ID_OL_INTERNAL);
+		}
+	}
+}
+#else
+static void ol_txrx_disp_peer_stats(ol_txrx_pdev_handle pdev)
+{
+	txrx_nofl_info("peer stats not supported w/o QCA_SUPPORT_TXRX_LOCAL_PEER_ID");
+}
+#endif
+
+void ol_txrx_stats_display(ol_txrx_pdev_handle pdev,
+			   enum qdf_stats_verbosity_level level)
+{
+	u64 tx_dropped =
+		pdev->stats.pub.tx.dropped.download_fail.pkts
+		  + pdev->stats.pub.tx.dropped.target_discard.pkts
+		  + pdev->stats.pub.tx.dropped.no_ack.pkts
+		  + pdev->stats.pub.tx.dropped.others.pkts;
+
+	if (level == QDF_STATS_VERBOSITY_LEVEL_LOW) {
+		txrx_nofl_dbg("STATS |%u %u|TX: %lld tso %lld ok %lld drops(%u-%lld %u-%lld %u-%lld ?-%lld hR-%lld)|RX: %lld drops(E %lld PI %lld ME %lld) fwd(S %d F %d SF %d)|",
+			      pdev->tx_desc.num_free,
+			      pdev->tx_desc.pool_size,
+			      pdev->stats.pub.tx.from_stack.pkts,
+			      pdev->stats.pub.tx.tso.tso_pkts.pkts,
+			      pdev->stats.pub.tx.delivered.pkts,
+			      htt_tx_status_download_fail,
+			      pdev->stats.pub.tx.dropped.download_fail.pkts,
+			      htt_tx_status_discard,
+			      pdev->stats.pub.tx.dropped.
+					target_discard.pkts,
+			      htt_tx_status_no_ack,
+			      pdev->stats.pub.tx.dropped.no_ack.pkts,
+			      pdev->stats.pub.tx.dropped.others.pkts,
+			      pdev->stats.pub.tx.dropped.host_reject.pkts,
+			      pdev->stats.pub.rx.delivered.pkts,
+			      pdev->stats.pub.rx.dropped_err.pkts,
+			      pdev->stats.pub.rx.dropped_peer_invalid.pkts,
+			      pdev->stats.pub.rx.dropped_mic_err.pkts,
+			      pdev->stats.pub.rx.intra_bss_fwd.
+					packets_stack,
+			      pdev->stats.pub.rx.intra_bss_fwd.
+					packets_fwd,
+			      pdev->stats.pub.rx.intra_bss_fwd.
+					packets_stack_n_fwd);
+		return;
+	}
+
+	txrx_nofl_info("TX PATH Statistics:");
+	txrx_nofl_info("sent %lld msdus (%lld B), host rejected %lld (%lld B), dropped %lld (%lld B)",
+		       pdev->stats.pub.tx.from_stack.pkts,
+		       pdev->stats.pub.tx.from_stack.bytes,
+		       pdev->stats.pub.tx.dropped.host_reject.pkts,
+		       pdev->stats.pub.tx.dropped.host_reject.bytes,
+			  tx_dropped,
+		       pdev->stats.pub.tx.dropped.download_fail.bytes
+			  + pdev->stats.pub.tx.dropped.target_discard.bytes
+			  + pdev->stats.pub.tx.dropped.no_ack.bytes);
+	txrx_nofl_info("successfully delivered: %lld (%lld B), download fail: %lld (%lld B), target discard: %lld (%lld B), no ack: %lld (%lld B) others: %lld (%lld B)",
+		       pdev->stats.pub.tx.delivered.pkts,
+		       pdev->stats.pub.tx.delivered.bytes,
+		       pdev->stats.pub.tx.dropped.download_fail.pkts,
+		       pdev->stats.pub.tx.dropped.download_fail.bytes,
+		       pdev->stats.pub.tx.dropped.target_discard.pkts,
+		       pdev->stats.pub.tx.dropped.target_discard.bytes,
+		       pdev->stats.pub.tx.dropped.no_ack.pkts,
+		       pdev->stats.pub.tx.dropped.no_ack.bytes,
+		       pdev->stats.pub.tx.dropped.others.pkts,
+		       pdev->stats.pub.tx.dropped.others.bytes);
+	txrx_nofl_info("Tx completions per HTT message:\n"
+		       "Single Packet  %d\n"
+		       " 2-10 Packets  %d\n"
+		       "11-20 Packets  %d\n"
+		       "21-30 Packets  %d\n"
+		       "31-40 Packets  %d\n"
+		       "41-50 Packets  %d\n"
+		       "51-60 Packets  %d\n"
+		       "  60+ Packets  %d\n",
+		       pdev->stats.pub.tx.comp_histogram.pkts_1,
+		       pdev->stats.pub.tx.comp_histogram.pkts_2_10,
+		       pdev->stats.pub.tx.comp_histogram.pkts_11_20,
+		       pdev->stats.pub.tx.comp_histogram.pkts_21_30,
+		       pdev->stats.pub.tx.comp_histogram.pkts_31_40,
+		       pdev->stats.pub.tx.comp_histogram.pkts_41_50,
+		       pdev->stats.pub.tx.comp_histogram.pkts_51_60,
+		       pdev->stats.pub.tx.comp_histogram.pkts_61_plus);
+
+	txrx_nofl_info("RX PATH Statistics:");
+	txrx_nofl_info("%lld ppdus, %lld mpdus, %lld msdus, %lld bytes\n"
+		       "dropped: err %lld (%lld B), peer_invalid %lld (%lld B), mic_err %lld (%lld B)\n"
+		       "msdus with frag_ind: %d msdus with offload_ind: %d",
+		       pdev->stats.priv.rx.normal.ppdus,
+		       pdev->stats.priv.rx.normal.mpdus,
+		       pdev->stats.pub.rx.delivered.pkts,
+		       pdev->stats.pub.rx.delivered.bytes,
+		       pdev->stats.pub.rx.dropped_err.pkts,
+		       pdev->stats.pub.rx.dropped_err.bytes,
+		       pdev->stats.pub.rx.dropped_peer_invalid.pkts,
+		       pdev->stats.pub.rx.dropped_peer_invalid.bytes,
+		       pdev->stats.pub.rx.dropped_mic_err.pkts,
+		       pdev->stats.pub.rx.dropped_mic_err.bytes,
+		       pdev->stats.pub.rx.msdus_with_frag_ind,
+		       pdev->stats.pub.rx.msdus_with_offload_ind);
+
+	txrx_nofl_info("  fwd to stack %d, fwd to fw %d, fwd to stack & fw  %d\n",
+		       pdev->stats.pub.rx.intra_bss_fwd.packets_stack,
+		       pdev->stats.pub.rx.intra_bss_fwd.packets_fwd,
+		       pdev->stats.pub.rx.intra_bss_fwd.packets_stack_n_fwd);
+
+	txrx_nofl_info("packets per HTT message:\n"
+		       "Single Packet  %d\n"
+		       " 2-10 Packets  %d\n"
+		       "11-20 Packets  %d\n"
+		       "21-30 Packets  %d\n"
+		       "31-40 Packets  %d\n"
+		       "41-50 Packets  %d\n"
+		       "51-60 Packets  %d\n"
+		       "  60+ Packets  %d\n",
+		       pdev->stats.pub.rx.rx_ind_histogram.pkts_1,
+		       pdev->stats.pub.rx.rx_ind_histogram.pkts_2_10,
+		       pdev->stats.pub.rx.rx_ind_histogram.pkts_11_20,
+		       pdev->stats.pub.rx.rx_ind_histogram.pkts_21_30,
+		       pdev->stats.pub.rx.rx_ind_histogram.pkts_31_40,
+		       pdev->stats.pub.rx.rx_ind_histogram.pkts_41_50,
+		       pdev->stats.pub.rx.rx_ind_histogram.pkts_51_60,
+		       pdev->stats.pub.rx.rx_ind_histogram.pkts_61_plus);
+
+	ol_txrx_disp_peer_stats(pdev);
+}
+
+void ol_txrx_stats_clear(ol_txrx_pdev_handle pdev)
+{
+	qdf_mem_zero(&pdev->stats, sizeof(pdev->stats));
+}
+
+#if defined(ENABLE_TXRX_PROT_ANALYZE)
+
+void ol_txrx_prot_ans_display(ol_txrx_pdev_handle pdev)
+{
+	ol_txrx_prot_an_display(pdev->prot_an_tx_sent);
+	ol_txrx_prot_an_display(pdev->prot_an_rx_sent);
+}
+
+#endif /* ENABLE_TXRX_PROT_ANALYZE */
+
+#ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI
+int16_t ol_txrx_peer_rssi(ol_txrx_peer_handle peer)
+{
+	return (peer->rssi_dbm == HTT_RSSI_INVALID) ?
+	       OL_TXRX_RSSI_INVALID : peer->rssi_dbm;
+}
+#endif /* #ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI */
+
+#ifdef QCA_ENABLE_OL_TXRX_PEER_STATS
+A_STATUS
+ol_txrx_peer_stats_copy(ol_txrx_pdev_handle pdev,
+			ol_txrx_peer_handle peer, ol_txrx_peer_stats_t *stats)
+{
+	qdf_assert(pdev && peer && stats);
+	qdf_spin_lock_bh(&pdev->peer_stat_mutex);
+	qdf_mem_copy(stats, &peer->stats, sizeof(*stats));
+	qdf_spin_unlock_bh(&pdev->peer_stat_mutex);
+	return A_OK;
+}
+#endif /* QCA_ENABLE_OL_TXRX_PEER_STATS */
+
+static void ol_vdev_rx_set_intrabss_fwd(struct cdp_vdev *pvdev, bool val)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	if (NULL == vdev)
+		return;
+
+	vdev->disable_intrabss_fwd = val;
+}
+
+/**
+ * ol_txrx_update_mac_id() - update mac_id for vdev
+ * @vdev_id: vdev id
+ * @mac_id: mac id
+ *
+ * Return: none
+ */
+static void ol_txrx_update_mac_id(uint8_t vdev_id, uint8_t mac_id)
+{
+	struct ol_txrx_vdev_t *vdev =
+			(struct ol_txrx_vdev_t *)
+			ol_txrx_get_vdev_from_vdev_id(vdev_id);
+
+	if (NULL == vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid vdev_id %d", __func__, vdev_id);
+		return;
+	}
+	vdev->mac_id = mac_id;
+}
+
+/**
+ * ol_txrx_get_tx_ack_count() - get tx ack count
+ * @vdev_id: vdev_id
+ *
+ * Return: tx ack count
+ */
+static uint32_t ol_txrx_get_tx_ack_stats(uint8_t vdev_id)
+{
+	struct ol_txrx_vdev_t *vdev =
+		(struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid vdev_id %d", __func__, vdev_id);
+		return 0;
+	}
+	return vdev->txrx_stats.txack_success;
+}
+
+/**
+ * ol_txrx_display_stats() - Display OL TXRX display stats
+ * @value: Module id for which stats needs to be displayed
+ *
+ * Return: status
+ */
+static QDF_STATUS
+ol_txrx_display_stats(void *soc, uint16_t value,
+		      enum qdf_stats_verbosity_level verb_level)
+{
+	ol_txrx_pdev_handle pdev;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: pdev is NULL", __func__);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	switch (value) {
+	case CDP_TXRX_PATH_STATS:
+		ol_txrx_stats_display(pdev, verb_level);
+		break;
+	case CDP_TXRX_TSO_STATS:
+		ol_txrx_stats_display_tso(pdev);
+		break;
+	case CDP_DUMP_TX_FLOW_POOL_INFO:
+		ol_tx_dump_flow_pool_info((void *)pdev);
+		break;
+	case CDP_TXRX_DESC_STATS:
+		qdf_nbuf_tx_desc_count_display();
+		break;
+	case CDP_WLAN_RX_BUF_DEBUG_STATS:
+		htt_display_rx_buf_debug(pdev->htt_pdev);
+		break;
+#ifdef CONFIG_HL_SUPPORT
+	case CDP_SCHEDULER_STATS:
+		ol_tx_sched_cur_state_display(pdev);
+		ol_tx_sched_stats_display(pdev);
+		break;
+	case CDP_TX_QUEUE_STATS:
+		ol_tx_queue_log_display(pdev);
+		break;
+#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+	case CDP_CREDIT_STATS:
+		ol_tx_dump_group_credit_stats(pdev);
+		break;
+#endif
+
+#ifdef DEBUG_HL_LOGGING
+	case CDP_BUNDLE_STATS:
+		htt_dump_bundle_stats(pdev->htt_pdev);
+		break;
+#endif
+#endif
+	default:
+		status = QDF_STATUS_E_INVAL;
+		break;
+	}
+	return status;
+}
+
+/**
+ * ol_txrx_clear_stats() - Clear OL TXRX stats
+ * @value: Module id for which stats needs to be cleared
+ *
+ * Return: None
+ */
+static void ol_txrx_clear_stats(uint16_t value)
+{
+	ol_txrx_pdev_handle pdev;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: pdev is NULL", __func__);
+		return;
+	}
+
+	switch (value) {
+	case CDP_TXRX_PATH_STATS:
+		ol_txrx_stats_clear(pdev);
+		break;
+	case CDP_TXRX_TSO_STATS:
+		ol_txrx_tso_stats_clear(pdev);
+		break;
+	case CDP_DUMP_TX_FLOW_POOL_INFO:
+		ol_tx_clear_flow_pool_stats();
+		break;
+	case CDP_TXRX_DESC_STATS:
+		qdf_nbuf_tx_desc_count_clear();
+		break;
+#ifdef CONFIG_HL_SUPPORT
+	case CDP_SCHEDULER_STATS:
+		ol_tx_sched_stats_clear(pdev);
+		break;
+	case CDP_TX_QUEUE_STATS:
+		ol_tx_queue_log_clear(pdev);
+		break;
+#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+	case CDP_CREDIT_STATS:
+		ol_tx_clear_group_credit_stats(pdev);
+		break;
+#endif
+	case CDP_BUNDLE_STATS:
+		htt_clear_bundle_stats(pdev->htt_pdev);
+		break;
+#endif
+	default:
+		status = QDF_STATUS_E_INVAL;
+		break;
+	}
+
+}
+
+/**
+ * ol_txrx_drop_nbuf_list() - drop an nbuf list
+ * @buf_list: buffer list to be dropepd
+ *
+ * Return: int (number of bufs dropped)
+ */
+static inline int ol_txrx_drop_nbuf_list(qdf_nbuf_t buf_list)
+{
+	int num_dropped = 0;
+	qdf_nbuf_t buf, next_buf;
+	ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	buf = buf_list;
+	while (buf) {
+		QDF_NBUF_CB_RX_PEER_CACHED_FRM(buf) = 1;
+		next_buf = qdf_nbuf_queue_next(buf);
+		if (pdev)
+			TXRX_STATS_MSDU_INCR(pdev,
+				 rx.dropped_peer_invalid, buf);
+		qdf_nbuf_free(buf);
+		buf = next_buf;
+		num_dropped++;
+	}
+	return num_dropped;
+}
+
+/**
+ * ol_rx_data_cb() - data rx callback
+ * @peer: peer
+ * @buf_list: buffer list
+ * @staid: Station id
+ *
+ * Return: None
+ */
+static void ol_rx_data_cb(struct ol_txrx_pdev_t *pdev,
+			  qdf_nbuf_t buf_list, uint16_t staid)
+{
+	void *osif_dev;
+	uint8_t drop_count = 0;
+	qdf_nbuf_t buf, next_buf;
+	QDF_STATUS ret;
+	ol_txrx_rx_fp data_rx = NULL;
+	struct ol_txrx_peer_t *peer;
+
+	if (qdf_unlikely(!pdev))
+		goto free_buf;
+
+	/* Do not use peer directly. Derive peer from staid to
+	 * make sure that peer is valid.
+	 */
+	peer = ol_txrx_peer_get_ref_by_local_id((struct cdp_pdev *)pdev,
+			staid, PEER_DEBUG_ID_OL_RX_THREAD);
+	if (!peer)
+		goto free_buf;
+
+	qdf_spin_lock_bh(&peer->peer_info_lock);
+	if (qdf_unlikely(!(peer->state >= OL_TXRX_PEER_STATE_CONN) ||
+					 !peer->vdev->rx)) {
+		qdf_spin_unlock_bh(&peer->peer_info_lock);
+		ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_RX_THREAD);
+		goto free_buf;
+	}
+
+	data_rx = peer->vdev->rx;
+	osif_dev = peer->vdev->osif_dev;
+	qdf_spin_unlock_bh(&peer->peer_info_lock);
+
+	qdf_spin_lock_bh(&peer->bufq_info.bufq_lock);
+	if (!list_empty(&peer->bufq_info.cached_bufq)) {
+		qdf_spin_unlock_bh(&peer->bufq_info.bufq_lock);
+		/* Flush the cached frames to HDD before passing new rx frame */
+		ol_txrx_flush_rx_frames(peer, 0);
+	} else
+		qdf_spin_unlock_bh(&peer->bufq_info.bufq_lock);
+
+	ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_RX_THREAD);
+
+	buf = buf_list;
+	while (buf) {
+		next_buf = qdf_nbuf_queue_next(buf);
+		qdf_nbuf_set_next(buf, NULL);   /* Add NULL terminator */
+		ret = data_rx(osif_dev, buf);
+		if (ret != QDF_STATUS_SUCCESS) {
+			ol_txrx_err("Frame Rx to HDD failed");
+			if (pdev)
+				TXRX_STATS_MSDU_INCR(pdev, rx.dropped_err, buf);
+			qdf_nbuf_free(buf);
+		}
+		buf = next_buf;
+	}
+	return;
+
+free_buf:
+	drop_count = ol_txrx_drop_nbuf_list(buf_list);
+	ol_txrx_warn("%s:Dropped frames %u", __func__, drop_count);
+}
+
+/* print for every 16th packet */
+#define OL_TXRX_PRINT_RATE_LIMIT_THRESH 0x0f
+struct ol_rx_cached_buf *cache_buf;
+
+/** helper function to drop packets
+ *  Note: caller must hold the cached buq lock before invoking
+ *  this function. Also, it assumes that the pointers passed in
+ *  are valid (non-NULL)
+ */
+static inline void ol_txrx_drop_frames(
+					struct ol_txrx_cached_bufq_t *bufqi,
+					qdf_nbuf_t rx_buf_list)
+{
+	uint32_t dropped = ol_txrx_drop_nbuf_list(rx_buf_list);
+
+	bufqi->dropped += dropped;
+	bufqi->qdepth_no_thresh += dropped;
+
+	if (bufqi->qdepth_no_thresh > bufqi->high_water_mark)
+		bufqi->high_water_mark = bufqi->qdepth_no_thresh;
+}
+
+static QDF_STATUS ol_txrx_enqueue_rx_frames(
+					struct ol_txrx_peer_t *peer,
+					struct ol_txrx_cached_bufq_t *bufqi,
+					qdf_nbuf_t rx_buf_list)
+{
+	struct ol_rx_cached_buf *cache_buf;
+	qdf_nbuf_t buf, next_buf;
+	static uint32_t count;
+
+	if ((count++ & OL_TXRX_PRINT_RATE_LIMIT_THRESH) == 0)
+		ol_txrx_info_high(
+		   "Data on the peer before it is registered bufq->curr %d bufq->drops %d",
+		   bufqi->curr, bufqi->dropped);
+
+	qdf_spin_lock_bh(&bufqi->bufq_lock);
+	if (bufqi->curr >= bufqi->thresh) {
+		ol_txrx_drop_frames(bufqi, rx_buf_list);
+		qdf_spin_unlock_bh(&bufqi->bufq_lock);
+		return QDF_STATUS_E_FAULT;
+	}
+	qdf_spin_unlock_bh(&bufqi->bufq_lock);
+
+	buf = rx_buf_list;
+	while (buf) {
+		next_buf = qdf_nbuf_queue_next(buf);
+		cache_buf = qdf_mem_malloc(sizeof(*cache_buf));
+		if (!cache_buf) {
+			ol_txrx_err(
+				"Failed to allocate buf to cache the rx frames");
+			qdf_nbuf_free(buf);
+		} else {
+			/* Add NULL terminator */
+			qdf_nbuf_set_next(buf, NULL);
+			cache_buf->buf = buf;
+			if (peer && peer->valid) {
+				qdf_spin_lock_bh(&bufqi->bufq_lock);
+				list_add_tail(&cache_buf->list,
+				      &bufqi->cached_bufq);
+				bufqi->curr++;
+				qdf_spin_unlock_bh(&bufqi->bufq_lock);
+			} else {
+				qdf_mem_free(cache_buf);
+				rx_buf_list = buf;
+				qdf_nbuf_set_next(rx_buf_list, next_buf);
+				qdf_spin_lock_bh(&bufqi->bufq_lock);
+				ol_txrx_drop_frames(bufqi, rx_buf_list);
+				qdf_spin_unlock_bh(&bufqi->bufq_lock);
+				return QDF_STATUS_E_FAULT;
+			}
+		}
+		buf = next_buf;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+/**
+ * ol_rx_data_process() - process rx frame
+ * @peer: peer
+ * @rx_buf_list: rx buffer list
+ *
+ * Return: None
+ */
+void ol_rx_data_process(struct ol_txrx_peer_t *peer,
+			qdf_nbuf_t rx_buf_list)
+{
+	/*
+	 * Firmware data path active response will use shim RX thread
+	 * T2H MSG running on SIRQ context,
+	 * IPA kernel module API should not be called on SIRQ CTXT
+	 */
+	ol_txrx_rx_fp data_rx = NULL;
+	ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if ((!peer) || (!pdev)) {
+		ol_txrx_err("peer/pdev is NULL");
+		goto drop_rx_buf;
+	}
+
+	qdf_assert(peer->vdev);
+
+	qdf_spin_lock_bh(&peer->peer_info_lock);
+	if (peer->state >= OL_TXRX_PEER_STATE_CONN)
+		data_rx = peer->vdev->rx;
+	qdf_spin_unlock_bh(&peer->peer_info_lock);
+
+	/*
+	 * If there is a data frame from peer before the peer is
+	 * registered for data service, enqueue them on to pending queue
+	 * which will be flushed to HDD once that station is registered.
+	 */
+	if (!data_rx) {
+		if (ol_txrx_enqueue_rx_frames(peer, &peer->bufq_info,
+					      rx_buf_list)
+				!= QDF_STATUS_SUCCESS)
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s: failed to enqueue rx frm to cached_bufq",
+				  __func__);
+	} else {
+#ifdef QCA_CONFIG_SMP
+		/*
+		 * If the kernel is SMP, schedule rx thread to
+		 * better use multicores.
+		 */
+		if (!ol_cfg_is_rx_thread_enabled(pdev->ctrl_pdev)) {
+			ol_rx_data_cb(pdev, rx_buf_list, peer->local_id);
+		} else {
+			p_cds_sched_context sched_ctx =
+				get_cds_sched_ctxt();
+			struct cds_ol_rx_pkt *pkt;
+
+			if (unlikely(!sched_ctx))
+				goto drop_rx_buf;
+
+			pkt = cds_alloc_ol_rx_pkt(sched_ctx);
+			if (!pkt)
+				goto drop_rx_buf;
+
+			pkt->callback = (cds_ol_rx_thread_cb)
+					ol_rx_data_cb;
+			pkt->context = (void *)pdev;
+			pkt->Rxpkt = (void *)rx_buf_list;
+			pkt->staId = peer->local_id;
+			cds_indicate_rxpkt(sched_ctx, pkt);
+		}
+#else                           /* QCA_CONFIG_SMP */
+		ol_rx_data_cb(pdev, rx_buf_list, peer->local_id);
+#endif /* QCA_CONFIG_SMP */
+	}
+
+	return;
+
+drop_rx_buf:
+	ol_txrx_drop_nbuf_list(rx_buf_list);
+}
+
+/**
+ * ol_txrx_register_peer() - register peer
+ * @sta_desc: sta descriptor
+ *
+ * Return: QDF Status
+ */
+static QDF_STATUS ol_txrx_register_peer(struct ol_txrx_desc_type *sta_desc)
+{
+	struct ol_txrx_peer_t *peer;
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	union ol_txrx_peer_update_param_t param;
+	struct privacy_exemption privacy_filter;
+
+	if (!pdev) {
+		ol_txrx_err("Pdev is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (sta_desc->sta_id >= WLAN_MAX_STA_COUNT) {
+		ol_txrx_err("Invalid sta id :%d",
+			 sta_desc->sta_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	peer = ol_txrx_peer_find_by_local_id((struct cdp_pdev *)pdev,
+					     sta_desc->sta_id);
+	if (!peer)
+		return QDF_STATUS_E_FAULT;
+
+	qdf_spin_lock_bh(&peer->peer_info_lock);
+	peer->state = OL_TXRX_PEER_STATE_CONN;
+	qdf_spin_unlock_bh(&peer->peer_info_lock);
+
+	param.qos_capable = sta_desc->is_qos_enabled;
+	ol_txrx_peer_update(peer->vdev, peer->mac_addr.raw, &param,
+			    ol_txrx_peer_update_qos_capable);
+
+	if (sta_desc->is_wapi_supported) {
+		/*Privacy filter to accept unencrypted WAI frames */
+		privacy_filter.ether_type = ETHERTYPE_WAI;
+		privacy_filter.filter_type = PRIVACY_FILTER_ALWAYS;
+		privacy_filter.packet_type = PRIVACY_FILTER_PACKET_BOTH;
+		ol_txrx_set_privacy_filters(peer->vdev, &privacy_filter, 1);
+	}
+
+	ol_txrx_flush_rx_frames(peer, 0);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_register_ocb_peer - Function to register the OCB peer
+ * @mac_addr: MAC address of the self peer
+ * @peer_id: Pointer to the peer ID
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+static QDF_STATUS ol_txrx_register_ocb_peer(uint8_t *mac_addr,
+				     uint8_t *peer_id)
+{
+	ol_txrx_pdev_handle pdev;
+	ol_txrx_peer_handle peer;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		ol_txrx_err("%s: Unable to find pdev!",
+			   __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	peer = ol_txrx_find_peer_by_addr((struct cdp_pdev *)pdev,
+					 mac_addr, peer_id);
+	if (!peer) {
+		ol_txrx_err("%s: Unable to find OCB peer!",
+			   __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ol_txrx_set_ocb_peer(pdev, peer);
+
+	/* Set peer state to connected */
+	ol_txrx_peer_state_update((struct cdp_pdev *)pdev, peer->mac_addr.raw,
+				  OL_TXRX_PEER_STATE_AUTH);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_set_ocb_peer - Function to store the OCB peer
+ * @pdev: Handle to the HTT instance
+ * @peer: Pointer to the peer
+ */
+void ol_txrx_set_ocb_peer(struct ol_txrx_pdev_t *pdev,
+			  struct ol_txrx_peer_t *peer)
+{
+	if (pdev == NULL)
+		return;
+
+	pdev->ocb_peer = peer;
+	pdev->ocb_peer_valid = (NULL != peer);
+}
+
+/**
+ * ol_txrx_get_ocb_peer - Function to retrieve the OCB peer
+ * @pdev: Handle to the HTT instance
+ * @peer: Pointer to the returned peer
+ *
+ * Return: true if the peer is valid, false if not
+ */
+bool ol_txrx_get_ocb_peer(struct ol_txrx_pdev_t *pdev,
+			  struct ol_txrx_peer_t **peer)
+{
+	int rc;
+
+	if ((pdev == NULL) || (peer == NULL)) {
+		rc = false;
+		goto exit;
+	}
+
+	if (pdev->ocb_peer_valid) {
+		*peer = pdev->ocb_peer;
+		rc = true;
+	} else {
+		rc = false;
+	}
+
+exit:
+	return rc;
+}
+
+#ifdef RECEIVE_OFFLOAD
+/**
+ * ol_txrx_offld_flush_handler() - offld flush handler
+ * @context: dev handle
+ * @rxpkt: rx data
+ * @staid: station id
+ *
+ * This function handles an offld flush indication.
+ * If the rx thread is enabled, it will be invoked by the rx
+ * thread else it will be called in the tasklet context
+ *
+ * Return: none
+ */
+static void ol_txrx_offld_flush_handler(void *context,
+				      void *rxpkt,
+				      uint16_t staid)
+{
+	ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (qdf_unlikely(!pdev)) {
+		ol_txrx_err("Invalid context");
+		qdf_assert(0);
+		return;
+	}
+
+	if (pdev->offld_flush_cb)
+		pdev->offld_flush_cb(context);
+	else
+		ol_txrx_err("offld_flush_cb NULL");
+}
+
+/**
+ * ol_txrx_offld_flush() - offld flush callback
+ * @data: opaque data pointer
+ *
+ * This is the callback registered with CE to trigger
+ * an offld flush
+ *
+ * Return: none
+ */
+static void ol_txrx_offld_flush(void *data)
+{
+	p_cds_sched_context sched_ctx = get_cds_sched_ctxt();
+	struct cds_ol_rx_pkt *pkt;
+	ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (qdf_unlikely(!sched_ctx))
+		return;
+
+	if (qdf_unlikely(!pdev)) {
+		ol_txrx_err("TXRX module context is NULL");
+		return;
+	}
+
+	if (!ol_cfg_is_rx_thread_enabled(pdev->ctrl_pdev)) {
+		ol_txrx_offld_flush_handler(data, NULL, 0);
+	} else {
+		pkt = cds_alloc_ol_rx_pkt(sched_ctx);
+		if (qdf_unlikely(!pkt))
+			return;
+
+		pkt->callback = ol_txrx_offld_flush_handler;
+		pkt->context = data;
+		pkt->Rxpkt = NULL;
+		pkt->staId = 0;
+		cds_indicate_rxpkt(sched_ctx, pkt);
+	}
+}
+
+/**
+ * ol_register_offld_flush_cb() - register the offld flush callback
+ * @offld_flush_cb: flush callback function
+ * @offld_init_cb: Allocate and initialize offld data structure.
+ *
+ * Store the offld flush callback provided and in turn
+ * register OL's offld flush handler with CE
+ *
+ * Return: none
+ */
+static void ol_register_offld_flush_cb(void (offld_flush_cb)(void *))
+{
+	struct hif_opaque_softc *hif_device;
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (pdev == NULL) {
+		ol_txrx_err("pdev NULL!");
+		TXRX_ASSERT2(0);
+		goto out;
+	}
+	if (pdev->offld_flush_cb != NULL) {
+		ol_txrx_info("offld already initialised");
+		if (pdev->offld_flush_cb != offld_flush_cb) {
+			ol_txrx_err(
+				   "offld_flush_cb is differ to previously registered callback")
+			TXRX_ASSERT2(0);
+			goto out;
+		}
+		goto out;
+	}
+	pdev->offld_flush_cb = offld_flush_cb;
+	hif_device = cds_get_context(QDF_MODULE_ID_HIF);
+
+	if (qdf_unlikely(hif_device == NULL)) {
+		ol_txrx_err("hif_device NULL!");
+		qdf_assert(0);
+		goto out;
+	}
+
+	hif_offld_flush_cb_register(hif_device, ol_txrx_offld_flush);
+
+out:
+	return;
+}
+
+/**
+ * ol_deregister_offld_flush_cb() - deregister the offld flush callback
+ *
+ * Remove the offld flush callback provided and in turn
+ * deregister OL's offld flush handler with CE
+ *
+ * Return: none
+ */
+static void ol_deregister_offld_flush_cb(void)
+{
+	struct hif_opaque_softc *hif_device;
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (pdev == NULL) {
+		ol_txrx_err("pdev NULL!");
+		return;
+	}
+	hif_device = cds_get_context(QDF_MODULE_ID_HIF);
+
+	if (qdf_unlikely(hif_device == NULL)) {
+		ol_txrx_err("hif_device NULL!");
+		qdf_assert(0);
+		return;
+	}
+
+	hif_offld_flush_cb_deregister(hif_device);
+
+	pdev->offld_flush_cb = NULL;
+}
+#endif /* RECEIVE_OFFLOAD */
+
+/**
+ * ol_register_data_stall_detect_cb() - register data stall callback
+ * @data_stall_detect_callback: data stall callback function
+ *
+ *
+ * Return: QDF_STATUS Enumeration
+ */
+static QDF_STATUS ol_register_data_stall_detect_cb(
+				data_stall_detect_cb data_stall_detect_callback)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (pdev == NULL) {
+		ol_txrx_err("%s: pdev NULL!", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	pdev->data_stall_detect_callback = data_stall_detect_callback;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_deregister_data_stall_detect_cb() - de-register data stall callback
+ * @data_stall_detect_callback: data stall callback function
+ *
+ *
+ * Return: QDF_STATUS Enumeration
+ */
+static QDF_STATUS ol_deregister_data_stall_detect_cb(
+				data_stall_detect_cb data_stall_detect_callback)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (pdev == NULL) {
+		ol_txrx_err("%s: pdev NULL!", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	pdev->data_stall_detect_callback = NULL;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_post_data_stall_event() - post data stall event
+ * @indicator: Module triggering data stall
+ * @data_stall_type: data stall event type
+ * @pdev_id: pdev id
+ * @vdev_id_bitmap: vdev id bitmap
+ * @recovery_type: data stall recovery type
+ *
+ * Return: None
+ */
+static void ol_txrx_post_data_stall_event(
+				enum data_stall_log_event_indicator indicator,
+				enum data_stall_log_event_type data_stall_type,
+				uint32_t pdev_id, uint32_t vdev_id_bitmap,
+				enum data_stall_log_recovery_type recovery_type)
+{
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+	struct data_stall_event_info *data_stall_info;
+	ol_txrx_pdev_handle pdev;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: pdev is NULL.", __func__);
+		return;
+	}
+	data_stall_info = qdf_mem_malloc(sizeof(*data_stall_info));
+	if (!data_stall_info) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			"%s: data_stall_info is NULL.", __func__);
+		return;
+	}
+	data_stall_info->indicator = indicator;
+	data_stall_info->data_stall_type = data_stall_type;
+	data_stall_info->vdev_id_bitmap = vdev_id_bitmap;
+	data_stall_info->pdev_id = pdev_id;
+	data_stall_info->recovery_type = recovery_type;
+
+	if (data_stall_info->data_stall_type ==
+				DATA_STALL_LOG_FW_RX_REFILL_FAILED)
+		htt_log_rx_ring_info(pdev->htt_pdev);
+
+	sys_build_message_header(SYS_MSG_ID_DATA_STALL_MSG, &msg);
+	/* Save callback and data */
+	msg.callback = pdev->data_stall_detect_callback;
+	msg.bodyptr = data_stall_info;
+	msg.bodyval = 0;
+
+	status = scheduler_post_message(QDF_MODULE_ID_TXRX,
+					QDF_MODULE_ID_HDD,
+					QDF_MODULE_ID_SYS, &msg);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: failed to post data stall msg to SYS", __func__);
+		qdf_mem_free(data_stall_info);
+	}
+}
+
+void
+ol_txrx_dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len)
+{
+	qdf_print("%s: Pkt: VA 0x%pK PA 0x%llx len %d\n", __func__,
+		  qdf_nbuf_data(nbuf), (unsigned long long int)nbuf_paddr, len);
+	print_hex_dump(KERN_DEBUG, "Pkt:   ", DUMP_PREFIX_ADDRESS, 16, 4,
+		       qdf_nbuf_data(nbuf), len, true);
+}
+
+/**
+ * ol_txrx_get_vdev_from_vdev_id() - get vdev from vdev_id
+ * @vdev_id: vdev_id
+ *
+ * Return: vdev handle
+ *            NULL if not found.
+ */
+struct cdp_vdev *ol_txrx_get_vdev_from_vdev_id(uint8_t vdev_id)
+{
+	ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	ol_txrx_vdev_handle vdev = NULL;
+
+	if (qdf_unlikely(!pdev))
+		return NULL;
+
+	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+		if (vdev->vdev_id == vdev_id)
+			break;
+	}
+
+	return (struct cdp_vdev *)vdev;
+}
+
+/**
+ * ol_txrx_set_wisa_mode() - set wisa mode
+ * @vdev: vdev handle
+ * @enable: enable flag
+ *
+ * Return: QDF STATUS
+ */
+static QDF_STATUS ol_txrx_set_wisa_mode(struct cdp_vdev *pvdev, bool enable)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	if (!vdev)
+		return QDF_STATUS_E_INVAL;
+
+	vdev->is_wisa_mode_enable = enable;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_get_vdev_id() - get interface id from interface context
+ * @pvdev: vdev handle
+ *
+ * Return: virtual interface id
+ */
+static uint16_t ol_txrx_get_vdev_id(struct cdp_vdev *pvdev)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	return vdev->vdev_id;
+}
+
+/**
+ * ol_txrx_soc_attach_target() - attach soc target
+ * @soc: soc handle
+ *
+ * MCL legacy OL do nothing here
+ *
+ * Return: 0
+ */
+static QDF_STATUS ol_txrx_soc_attach_target(ol_txrx_soc_handle soc)
+{
+	/* MCL legacy OL do nothing here */
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_soc_detach() - detach soc target
+ * @soc: soc handle
+ *
+ * MCL legacy OL do nothing here
+ *
+ * Return: noe
+ */
+static void ol_txrx_soc_detach(void *soc)
+{
+	qdf_mem_free(soc);
+}
+
+/**
+ * ol_txrx_pkt_log_con_service() - connect packet log service
+ * @ppdev: physical device handle
+ * @scn: device context
+ *
+ * Return: noe
+ */
+#ifdef REMOVE_PKT_LOG
+static void ol_txrx_pkt_log_con_service(struct cdp_pdev *ppdev, void *scn)
+{
+}
+#else
+static void ol_txrx_pkt_log_con_service(struct cdp_pdev *ppdev, void *scn)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+
+	htt_pkt_log_init((struct cdp_pdev *)pdev, scn);
+	pktlog_htc_attach();
+}
+#endif
+
+/* OL wrapper functions for CDP abstraction */
+/**
+ * ol_txrx_wrapper_flush_rx_frames() - flush rx frames on the queue
+ * @peer: peer handle
+ * @drop: rx packets drop or deliver
+ *
+ * Return: none
+ */
+static void ol_txrx_wrapper_flush_rx_frames(void *peer, bool drop)
+{
+	ol_txrx_flush_rx_frames((ol_txrx_peer_handle)peer, drop);
+}
+
+/**
+ * ol_txrx_wrapper_get_vdev_from_vdev_id() - get vdev instance from vdev id
+ * @ppdev: pdev handle
+ * @vdev_id: interface id
+ *
+ * Return: virtual interface instance
+ */
+static
+struct cdp_vdev *ol_txrx_wrapper_get_vdev_from_vdev_id(struct cdp_pdev *ppdev,
+		uint8_t vdev_id)
+{
+	return ol_txrx_get_vdev_from_vdev_id(vdev_id);
+}
+
+/**
+ * ol_txrx_wrapper_register_peer() - register peer
+ * @pdev: pdev handle
+ * @sta_desc: peer description
+ *
+ * Return: QDF STATUS
+ */
+static QDF_STATUS ol_txrx_wrapper_register_peer(struct cdp_pdev *pdev,
+		struct ol_txrx_desc_type *sta_desc)
+{
+	return ol_txrx_register_peer(sta_desc);
+}
+
+/**
+ * ol_txrx_wrapper_peer_find_by_local_id() - Find a txrx peer handle
+ * @pdev - the data physical device object
+ * @local_peer_id - the ID txrx assigned locally to the peer in question
+ *
+ * The control SW typically uses the txrx peer handle to refer to the peer.
+ * In unusual circumstances, if it is infeasible for the control SW maintain
+ * the txrx peer handle but it can maintain a small integer local peer ID,
+ * this function allows the peer handled to be retrieved, based on the local
+ * peer ID.
+ *
+ * @return handle to the txrx peer object
+ */
+static void *
+ol_txrx_wrapper_peer_find_by_local_id(struct cdp_pdev *pdev,
+				      uint8_t local_peer_id)
+{
+	return (void *)ol_txrx_peer_find_by_local_id(
+		pdev, local_peer_id);
+}
+
+/**
+ * ol_txrx_wrapper_cfg_is_high_latency() - device is high or low latency device
+ * @pdev: pdev handle
+ *
+ * Return: 1 high latency bus
+ *         0 low latency bus
+ */
+static int ol_txrx_wrapper_cfg_is_high_latency(struct cdp_cfg *cfg_pdev)
+{
+	return ol_cfg_is_high_latency(cfg_pdev);
+}
+
+/**
+ * ol_txrx_wrapper_peer_state_update() - specify the peer's authentication state
+ * @data_peer - which peer has changed its state
+ * @state - the new state of the peer
+ *
+ *  Specify the peer's authentication state (none, connected, authenticated)
+ *  to allow the data SW to determine whether to filter out invalid data frames.
+ *  (In the "connected" state, where security is enabled, but authentication
+ *  has not completed, tx and rx data frames other than EAPOL or WAPI should
+ *  be discarded.)
+ *  This function is only relevant for systems in which the tx and rx filtering
+ *  are done in the host rather than in the target.
+ *
+ * Return: QDF Status
+ */
+static QDF_STATUS ol_txrx_wrapper_peer_state_update(struct cdp_pdev *pdev,
+		uint8_t *peer_mac, enum ol_txrx_peer_state state)
+{
+	return ol_txrx_peer_state_update(pdev,
+			peer_mac, state);
+}
+
+/**
+ * ol_txrx_wrapper_find_peer_by_addr() - find peer instance by address
+ * @pdev: pdev handle
+ * @peer_addr: peer address want to find
+ * @peer_id: peer id
+ *
+ * Return: peer instance pointer
+ */
+static void *ol_txrx_wrapper_find_peer_by_addr(struct cdp_pdev *pdev,
+		uint8_t *peer_addr, uint8_t *peer_id)
+{
+	return ol_txrx_find_peer_by_addr(pdev,
+				peer_addr, peer_id);
+}
+
+/**
+ * ol_txrx_wrapper_peer_get_ref_by_addr() - get peer reference by address
+ * @pdev: pdev handle
+ * @peer_addr: peer address we want to find
+ * @peer_id: peer id
+ * @debug_id: peer debug id for tracking
+ *
+ * Return: peer instance pointer
+ */
+static void *
+ol_txrx_wrapper_peer_get_ref_by_addr(struct cdp_pdev *pdev,
+				     u8 *peer_addr, uint8_t *peer_id,
+				     enum peer_debug_id_type debug_id)
+{
+	return ol_txrx_peer_get_ref_by_addr((ol_txrx_pdev_handle)pdev,
+					    peer_addr, peer_id, debug_id);
+}
+
+/**
+ * ol_txrx_wrapper_peer_release_ref() - release peer reference
+ * @peer: peer handle
+ * @debug_id: peer debug id for tracking
+ *
+ * Release peer ref acquired by peer get ref api
+ *
+ * Return: void
+ */
+static void ol_txrx_wrapper_peer_release_ref(void *peer,
+					     enum peer_debug_id_type debug_id)
+{
+	ol_txrx_peer_release_ref(peer, debug_id);
+}
+
+/**
+ * ol_txrx_wrapper_set_flow_control_parameters() - set flow control parameters
+ * @cfg_ctx: cfg context
+ * @cfg_param: cfg parameters
+ *
+ * Return: none
+ */
+static void
+ol_txrx_wrapper_set_flow_control_parameters(struct cdp_cfg *cfg_pdev,
+		void *cfg_param)
+{
+	return ol_tx_set_flow_control_parameters(
+		cfg_pdev,
+		(struct txrx_pdev_cfg_param_t *)cfg_param);
+}
+
+/**
+ * ol_txrx_get_cfg() - get ini/cgf values in legacy dp
+ * @soc: soc context
+ * @cfg_param: cfg parameters
+ *
+ * Return: none
+ */
+static uint32_t ol_txrx_get_cfg(void *soc, enum cdp_dp_cfg cfg)
+{
+	struct txrx_pdev_cfg_t *cfg_ctx;
+	ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	uint32_t value = 0;
+
+	cfg_ctx = (struct txrx_pdev_cfg_t *)(pdev->ctrl_pdev);
+	switch (cfg) {
+	case cfg_dp_enable_data_stall:
+		value = cfg_ctx->enable_data_stall_detection;
+		break;
+	case cfg_dp_enable_ip_tcp_udp_checksum_offload:
+		value = cfg_ctx->ip_tcp_udp_checksum_offload;
+		break;
+	case cfg_dp_tso_enable:
+		value = cfg_ctx->tso_enable;
+		break;
+	case cfg_dp_lro_enable:
+		value = cfg_ctx->lro_enable;
+		break;
+	case cfg_dp_gro_enable:
+		value = cfg_ctx->gro_enable;
+		break;
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+	case cfg_dp_tx_flow_start_queue_offset:
+		value = cfg_ctx->tx_flow_start_queue_offset;
+		break;
+	case cfg_dp_tx_flow_stop_queue_threshold:
+		value = cfg_ctx->tx_flow_stop_queue_th;
+		break;
+#endif
+	case cfg_dp_ipa_uc_tx_buf_size:
+		value = cfg_ctx->uc_tx_buffer_size;
+		break;
+	case cfg_dp_ipa_uc_tx_partition_base:
+		value = cfg_ctx->uc_tx_partition_base;
+		break;
+	case cfg_dp_ipa_uc_rx_ind_ring_count:
+		value = cfg_ctx->uc_rx_indication_ring_count;
+		break;
+	case cfg_dp_enable_flow_steering:
+		value = cfg_ctx->enable_flow_steering;
+		break;
+	case cfg_dp_reorder_offload_supported:
+		value = cfg_ctx->is_full_reorder_offload;
+		break;
+	case cfg_dp_ce_classify_enable:
+		value = cfg_ctx->ce_classify_enabled;
+		break;
+	case cfg_dp_disable_intra_bss_fwd:
+		value = cfg_ctx->disable_intra_bss_fwd;
+		break;
+	default:
+		value =  0;
+		break;
+	}
+
+	return value;
+}
+
+#ifdef WDI_EVENT_ENABLE
+void *ol_get_pldev(struct cdp_pdev *txrx_pdev)
+{
+	struct ol_txrx_pdev_t *pdev =
+				 (struct ol_txrx_pdev_t *)txrx_pdev;
+	if (pdev != NULL)
+		return pdev->pl_dev;
+
+	return NULL;
+}
+#endif
+
+static struct cdp_cmn_ops ol_ops_cmn = {
+	.txrx_soc_attach_target = ol_txrx_soc_attach_target,
+	.txrx_vdev_attach = ol_txrx_vdev_attach,
+	.txrx_vdev_detach = ol_txrx_vdev_detach,
+	.txrx_pdev_attach = ol_txrx_pdev_attach,
+	.txrx_pdev_attach_target = ol_txrx_pdev_attach_target,
+	.txrx_pdev_post_attach = ol_txrx_pdev_post_attach,
+	.txrx_pdev_pre_detach = ol_txrx_pdev_pre_detach,
+	.txrx_pdev_detach = ol_txrx_pdev_detach,
+	.txrx_peer_create = ol_txrx_peer_attach,
+	.txrx_peer_setup = NULL,
+	.txrx_peer_teardown = NULL,
+	.txrx_peer_delete = ol_txrx_peer_detach,
+	.txrx_vdev_register = ol_txrx_vdev_register,
+	.txrx_soc_detach = ol_txrx_soc_detach,
+	.txrx_get_vdev_mac_addr = ol_txrx_get_vdev_mac_addr,
+	.txrx_get_vdev_from_vdev_id = ol_txrx_wrapper_get_vdev_from_vdev_id,
+	.txrx_get_ctrl_pdev_from_vdev = ol_txrx_get_ctrl_pdev_from_vdev,
+	.txrx_mgmt_send_ext = ol_txrx_mgmt_send_ext,
+	.txrx_mgmt_tx_cb_set = ol_txrx_mgmt_tx_cb_set,
+	.txrx_data_tx_cb_set = ol_txrx_data_tx_cb_set,
+	.txrx_get_tx_pending = ol_txrx_get_tx_pending,
+	.flush_cache_rx_queue = ol_txrx_flush_cache_rx_queue,
+	.txrx_fw_stats_get = ol_txrx_fw_stats_get,
+	.display_stats = ol_txrx_display_stats,
+	.txrx_get_cfg = ol_txrx_get_cfg,
+	/* TODO: Add other functions */
+};
+
+static struct cdp_misc_ops ol_ops_misc = {
+	.set_ibss_vdev_heart_beat_timer =
+		ol_txrx_set_ibss_vdev_heart_beat_timer,
+#ifdef CONFIG_HL_SUPPORT
+	.set_wmm_param = ol_txrx_set_wmm_param,
+#endif /* CONFIG_HL_SUPPORT */
+	.bad_peer_txctl_set_setting = ol_txrx_bad_peer_txctl_set_setting,
+	.bad_peer_txctl_update_threshold =
+		ol_txrx_bad_peer_txctl_update_threshold,
+	.hl_tdls_flag_reset = ol_txrx_hl_tdls_flag_reset,
+	.tx_non_std = ol_tx_non_std,
+	.get_vdev_id = ol_txrx_get_vdev_id,
+	.get_tx_ack_stats = ol_txrx_get_tx_ack_stats,
+	.set_wisa_mode = ol_txrx_set_wisa_mode,
+	.txrx_data_stall_cb_register = ol_register_data_stall_detect_cb,
+	.txrx_data_stall_cb_deregister = ol_deregister_data_stall_detect_cb,
+	.txrx_post_data_stall_event = ol_txrx_post_data_stall_event,
+#ifdef FEATURE_RUNTIME_PM
+	.runtime_suspend = ol_txrx_runtime_suspend,
+	.runtime_resume = ol_txrx_runtime_resume,
+#endif /* FEATURE_RUNTIME_PM */
+	.get_opmode = ol_txrx_get_opmode,
+	.mark_first_wakeup_packet = ol_tx_mark_first_wakeup_packet,
+	.update_mac_id = ol_txrx_update_mac_id,
+	.flush_rx_frames = ol_txrx_wrapper_flush_rx_frames,
+	.get_intra_bss_fwd_pkts_count = ol_get_intra_bss_fwd_pkts_count,
+	.pkt_log_init = htt_pkt_log_init,
+	.pkt_log_con_service = ol_txrx_pkt_log_con_service
+};
+
+static struct cdp_flowctl_ops ol_ops_flowctl = {
+#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,
+#endif /* QCA_LL_TX_FLOW_CONTROL_V2 */
+};
+
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL)
+static struct cdp_lflowctl_ops ol_ops_l_flowctl = {
+	.register_tx_flow_control = ol_txrx_register_tx_flow_control,
+	.deregister_tx_flow_control_cb = ol_txrx_deregister_tx_flow_control_cb,
+	.flow_control_cb = ol_txrx_flow_control_cb,
+	.get_tx_resource = ol_txrx_get_tx_resource,
+	.ll_set_tx_pause_q_depth = ol_txrx_ll_set_tx_pause_q_depth,
+	.vdev_flush = ol_txrx_vdev_flush,
+	.vdev_pause = ol_txrx_vdev_pause,
+	.vdev_unpause = ol_txrx_vdev_unpause
+}; /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+#elif defined(QCA_HL_NETDEV_FLOW_CONTROL)
+static struct cdp_lflowctl_ops ol_ops_l_flowctl = {
+	.register_tx_flow_control = ol_txrx_register_hl_flow_control,
+	.vdev_flush = ol_txrx_vdev_flush,
+	.vdev_pause = ol_txrx_vdev_pause,
+	.vdev_unpause = ol_txrx_vdev_unpause,
+	.set_vdev_os_queue_status = ol_txrx_set_vdev_os_queue_status,
+	.set_vdev_tx_desc_limit = ol_txrx_set_vdev_tx_desc_limit
+};
+#else /* QCA_HL_NETDEV_FLOW_CONTROL */
+static struct cdp_lflowctl_ops ol_ops_l_flowctl = { };
+#endif
+
+#ifdef IPA_OFFLOAD
+static struct cdp_ipa_ops ol_ops_ipa = {
+	.ipa_get_resource = ol_txrx_ipa_uc_get_resource,
+	.ipa_set_doorbell_paddr = ol_txrx_ipa_uc_set_doorbell_paddr,
+	.ipa_set_active = ol_txrx_ipa_uc_set_active,
+	.ipa_op_response = ol_txrx_ipa_uc_op_response,
+	.ipa_register_op_cb = ol_txrx_ipa_uc_register_op_cb,
+	.ipa_get_stat = ol_txrx_ipa_uc_get_stat,
+	.ipa_tx_data_frame = ol_tx_send_ipa_data_frame,
+	.ipa_set_uc_tx_partition_base = ol_cfg_set_ipa_uc_tx_partition_base,
+	.ipa_enable_autonomy = ol_txrx_ipa_enable_autonomy,
+	.ipa_disable_autonomy = ol_txrx_ipa_disable_autonomy,
+	.ipa_setup = ol_txrx_ipa_setup,
+	.ipa_cleanup = ol_txrx_ipa_cleanup,
+	.ipa_setup_iface = ol_txrx_ipa_setup_iface,
+	.ipa_cleanup_iface = ol_txrx_ipa_cleanup_iface,
+	.ipa_enable_pipes = ol_txrx_ipa_enable_pipes,
+	.ipa_disable_pipes = ol_txrx_ipa_disable_pipes,
+	.ipa_set_perf_level = ol_txrx_ipa_set_perf_level,
+#ifdef FEATURE_METERING
+	.ipa_uc_get_share_stats = ol_txrx_ipa_uc_get_share_stats,
+	.ipa_uc_set_quota = ol_txrx_ipa_uc_set_quota
+#endif
+};
+#endif
+
+#ifdef RECEIVE_OFFLOAD
+static struct cdp_rx_offld_ops ol_rx_offld_ops = {
+	.register_rx_offld_flush_cb = ol_register_offld_flush_cb,
+	.deregister_rx_offld_flush_cb = ol_deregister_offld_flush_cb
+};
+#endif
+
+static struct cdp_bus_ops ol_ops_bus = {
+	.bus_suspend = ol_txrx_bus_suspend,
+	.bus_resume = ol_txrx_bus_resume
+};
+
+#ifdef WLAN_FEATURE_DSRC
+static struct cdp_ocb_ops ol_ops_ocb = {
+	.set_ocb_chan_info = ol_txrx_set_ocb_chan_info,
+	.get_ocb_chan_info = ol_txrx_get_ocb_chan_info
+};
+#endif
+
+static struct cdp_throttle_ops ol_ops_throttle = {
+#ifdef QCA_SUPPORT_TX_THROTTLE
+	.throttle_init_period = ol_tx_throttle_init_period,
+	.throttle_set_level = ol_tx_throttle_set_level
+#endif /* QCA_SUPPORT_TX_THROTTLE */
+};
+
+static struct cdp_mob_stats_ops ol_ops_mob_stats = {
+	.clear_stats = ol_txrx_clear_stats,
+	.stats = ol_txrx_stats
+};
+
+static struct cdp_cfg_ops ol_ops_cfg = {
+	.set_cfg_rx_fwd_disabled = ol_set_cfg_rx_fwd_disabled,
+	.set_cfg_packet_log_enabled = ol_set_cfg_packet_log_enabled,
+	.cfg_attach = ol_pdev_cfg_attach,
+	.vdev_rx_set_intrabss_fwd = ol_vdev_rx_set_intrabss_fwd,
+	.is_rx_fwd_disabled = ol_txrx_is_rx_fwd_disabled,
+	.tx_set_is_mgmt_over_wmi_enabled = ol_tx_set_is_mgmt_over_wmi_enabled,
+	.is_high_latency = ol_txrx_wrapper_cfg_is_high_latency,
+	.set_flow_control_parameters =
+		ol_txrx_wrapper_set_flow_control_parameters,
+	.set_flow_steering = ol_set_cfg_flow_steering,
+	.set_ptp_rx_opt_enabled = ol_set_cfg_ptp_rx_opt_enabled,
+};
+
+static struct cdp_peer_ops ol_ops_peer = {
+	.register_peer = ol_txrx_wrapper_register_peer,
+	.clear_peer = ol_txrx_clear_peer,
+	.peer_get_ref_by_addr = ol_txrx_wrapper_peer_get_ref_by_addr,
+	.peer_release_ref = ol_txrx_wrapper_peer_release_ref,
+	.find_peer_by_addr = ol_txrx_wrapper_find_peer_by_addr,
+	.find_peer_by_addr_and_vdev = ol_txrx_find_peer_by_addr_and_vdev,
+	.local_peer_id = ol_txrx_local_peer_id,
+	.peer_find_by_local_id = ol_txrx_wrapper_peer_find_by_local_id,
+	.peer_state_update = ol_txrx_wrapper_peer_state_update,
+	.get_vdevid = ol_txrx_get_vdevid,
+	.get_vdev_by_sta_id = ol_txrx_get_vdev_by_sta_id,
+	.register_ocb_peer = ol_txrx_register_ocb_peer,
+	.peer_get_peer_mac_addr = ol_txrx_peer_get_peer_mac_addr,
+	.get_peer_state = ol_txrx_get_peer_state,
+	.get_vdev_for_peer = ol_txrx_get_vdev_for_peer,
+	.update_ibss_add_peer_num_of_vdev =
+		ol_txrx_update_ibss_add_peer_num_of_vdev,
+	.remove_peers_for_vdev = ol_txrx_remove_peers_for_vdev,
+	.remove_peers_for_vdev_no_lock = ol_txrx_remove_peers_for_vdev_no_lock,
+#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
+	.copy_mac_addr_raw = ol_txrx_copy_mac_addr_raw,
+	.add_last_real_peer = ol_txrx_add_last_real_peer,
+	.is_vdev_restore_last_peer = is_vdev_restore_last_peer,
+	.update_last_real_peer = ol_txrx_update_last_real_peer,
+#endif /* CONFIG_HL_SUPPORT */
+	.peer_detach_force_delete = ol_txrx_peer_detach_force_delete,
+};
+
+static struct cdp_tx_delay_ops ol_ops_delay = {
+#ifdef QCA_COMPUTE_TX_DELAY
+	.tx_delay = ol_tx_delay,
+	.tx_delay_hist = ol_tx_delay_hist,
+	.tx_packet_count = ol_tx_packet_count,
+	.tx_set_compute_interval = ol_tx_set_compute_interval
+#endif /* QCA_COMPUTE_TX_DELAY */
+};
+
+static struct cdp_pmf_ops ol_ops_pmf = {
+	.get_pn_info = ol_txrx_get_pn_info
+};
+
+static struct cdp_ctrl_ops ol_ops_ctrl = {
+	.txrx_get_pldev = ol_get_pldev,
+	.txrx_wdi_event_sub = wdi_event_sub,
+	.txrx_wdi_event_unsub = wdi_event_unsub,
+};
+
+/* WINplatform specific structures */
+static struct cdp_me_ops ol_ops_me = {
+	/* EMPTY FOR MCL */
+};
+
+static struct cdp_mon_ops ol_ops_mon = {
+	/* EMPTY FOR MCL */
+};
+
+static struct cdp_host_stats_ops ol_ops_host_stats = {
+	/* EMPTY FOR MCL */
+};
+
+static struct cdp_wds_ops ol_ops_wds = {
+	/* EMPTY FOR MCL */
+};
+
+static struct cdp_raw_ops ol_ops_raw = {
+	/* EMPTY FOR MCL */
+};
+
+static struct cdp_ops ol_txrx_ops = {
+	.cmn_drv_ops = &ol_ops_cmn,
+	.ctrl_ops = &ol_ops_ctrl,
+	.me_ops = &ol_ops_me,
+	.mon_ops = &ol_ops_mon,
+	.host_stats_ops = &ol_ops_host_stats,
+	.wds_ops = &ol_ops_wds,
+	.raw_ops = &ol_ops_raw,
+	.misc_ops = &ol_ops_misc,
+	.cfg_ops = &ol_ops_cfg,
+	.flowctl_ops = &ol_ops_flowctl,
+	.l_flowctl_ops = &ol_ops_l_flowctl,
+#ifdef IPA_OFFLOAD
+	.ipa_ops = &ol_ops_ipa,
+#endif
+#ifdef RECEIVE_OFFLOAD
+	.rx_offld_ops = &ol_rx_offld_ops,
+#endif
+	.bus_ops = &ol_ops_bus,
+#ifdef WLAN_FEATURE_DSRC
+	.ocb_ops = &ol_ops_ocb,
+#endif
+	.peer_ops = &ol_ops_peer,
+	.throttle_ops = &ol_ops_throttle,
+	.mob_stats_ops = &ol_ops_mob_stats,
+	.delay_ops = &ol_ops_delay,
+	.pmf_ops = &ol_ops_pmf
+};
+
+/*
+ * Local prototype added to temporarily address warning caused by
+ * -Wmissing-prototypes. A more correct solution, namely to expose
+ * a prototype in an appropriate header file, will come later.
+ */
+struct cdp_soc_t *ol_txrx_soc_attach(void *scn_handle,
+				     struct ol_if_ops *dp_ol_if_ops);
+struct cdp_soc_t *ol_txrx_soc_attach(void *scn_handle,
+				     struct ol_if_ops *dp_ol_if_ops)
+{
+	struct cdp_soc_t *soc = qdf_mem_malloc(sizeof(struct cdp_soc_t));
+
+	if (!soc) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			"%s: OL SOC memory allocation failed\n", __func__);
+		return NULL;
+	}
+
+	soc->ops = &ol_txrx_ops;
+	return soc;
+}
diff --git a/core/dp/txrx/ol_txrx.h b/core/dp/txrx/ol_txrx.h
new file mode 100644
index 0000000..f4db398
--- /dev/null
+++ b/core/dp/txrx/ol_txrx.h
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef _OL_TXRX__H_
+#define _OL_TXRX__H_
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <cdp_txrx_cmn.h>       /* ol_txrx_vdev_t, etc. */
+#include "cds_sched.h"
+#include <cdp_txrx_handle.h>
+#include <ol_txrx_types.h>
+#include <ol_txrx_internal.h>
+
+/*
+ * Pool of tx descriptors reserved for
+ * high-priority traffic, such as ARP/EAPOL etc
+ * only for forwarding path.
+ */
+#define OL_TX_NON_FWD_RESERVE	100
+
+/**
+ * enum ol_txrx_fc_limit_id - Flow control identifier for
+ * vdev limits based on band, channel bw and number of spatial streams
+ * @TXRX_FC_5GH_80M_2x2: Limit for 5GHz, 80MHz BW, 2x2 NSS
+ * @TXRX_FC_5GH_40M_2x2:
+ * @TXRX_FC_5GH_20M_2x2:
+ * @TXRX_FC_5GH_80M_1x1:
+ * @TXRX_FC_5GH_40M_1x1:
+ * @TXRX_FC_5GH_20M_1x1:
+ * @TXRX_FC_2GH_40M_2x2:
+ * @TXRX_FC_2GH_20M_2x2:
+ * @TXRX_FC_2GH_40M_1x1:
+ * @TXRX_FC_2GH_20M_1x1:
+ */
+enum ol_txrx_fc_limit_id {
+	TXRX_FC_5GH_80M_2x2,
+	TXRX_FC_5GH_40M_2x2,
+	TXRX_FC_5GH_20M_2x2,
+	TXRX_FC_5GH_80M_1x1,
+	TXRX_FC_5GH_40M_1x1,
+	TXRX_FC_5GH_20M_1x1,
+	TXRX_FC_2GH_40M_2x2,
+	TXRX_FC_2GH_20M_2x2,
+	TXRX_FC_2GH_40M_1x1,
+	TXRX_FC_2GH_20M_1x1,
+	TXRX_FC_MAX
+};
+
+ol_txrx_peer_handle ol_txrx_peer_get_ref_by_addr(ol_txrx_pdev_handle pdev,
+						 u8 *peer_addr,
+						 u8 *peer_id,
+						 enum peer_debug_id_type
+									dbg_id);
+
+int  ol_txrx_peer_release_ref(ol_txrx_peer_handle peer,
+			      enum peer_debug_id_type dbg_id);
+
+/**
+ * ol_tx_desc_pool_size_hl() - allocate tx descriptor pool size for HL systems
+ * @ctrl_pdev: the control pdev handle
+ *
+ * Return: allocated pool size
+ */
+u_int16_t
+ol_tx_desc_pool_size_hl(struct cdp_cfg *ctrl_pdev);
+
+#ifndef OL_TX_AVG_FRM_BYTES
+#define OL_TX_AVG_FRM_BYTES 1000
+#endif
+
+#ifndef OL_TX_DESC_POOL_SIZE_MIN_HL
+#define OL_TX_DESC_POOL_SIZE_MIN_HL 500
+#endif
+
+#ifndef OL_TX_DESC_POOL_SIZE_MAX_HL
+#define OL_TX_DESC_POOL_SIZE_MAX_HL 5000
+#endif
+
+#ifndef FW_STATS_DESC_POOL_SIZE
+#define FW_STATS_DESC_POOL_SIZE 10
+#endif
+
+#ifdef CONFIG_PER_VDEV_TX_DESC_POOL
+#define TXRX_HL_TX_FLOW_CTRL_VDEV_LOW_WATER_MARK 400
+#define TXRX_HL_TX_FLOW_CTRL_MGMT_RESERVED 100
+#endif
+
+#define TXRX_HL_TX_DESC_HI_PRIO_RESERVED 20
+#define TXRX_HL_TX_DESC_QUEUE_RESTART_TH \
+		(TXRX_HL_TX_DESC_HI_PRIO_RESERVED + 100)
+
+#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
+
+void
+ol_txrx_hl_tdls_flag_reset(struct cdp_vdev *vdev, bool flag);
+#else
+
+static inline void
+ol_txrx_hl_tdls_flag_reset(struct cdp_vdev *vdev, bool flag)
+{
+}
+#endif
+
+#ifdef WDI_EVENT_ENABLE
+void *ol_get_pldev(struct cdp_pdev *txrx_pdev);
+#else
+static inline
+void *ol_get_pldev(struct cdp_pdev *txrx_pdev)
+{
+	return NULL;
+}
+#endif
+
+#ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID
+ol_txrx_peer_handle
+ol_txrx_peer_find_by_local_id(struct cdp_pdev *pdev,
+			      uint8_t local_peer_id);
+ol_txrx_peer_handle
+ol_txrx_peer_get_ref_by_local_id(struct cdp_pdev *ppdev,
+				 uint8_t local_peer_id,
+				 enum peer_debug_id_type dbg_id);
+#endif /* QCA_SUPPORT_TXRX_LOCAL_PEER_ID */
+
+/*
+ * @nbuf: buffer which contains data to be displayed
+ * @nbuf_paddr: physical address of the buffer
+ * @len: defines the size of the data to be displayed
+ *
+ * Return: None
+ */
+void
+ol_txrx_dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len);
+
+struct cdp_vdev *ol_txrx_get_vdev_from_vdev_id(uint8_t vdev_id);
+
+void *ol_txrx_find_peer_by_addr(struct cdp_pdev *pdev,
+				uint8_t *peer_addr,
+				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);
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+int ol_txrx_register_tx_flow_control(uint8_t vdev_id,
+				     ol_txrx_tx_flow_control_fp flow_control,
+				     void *osif_fc_ctx,
+				     ol_txrx_tx_flow_control_is_pause_fp
+				     flow_control_is_pause);
+
+int ol_txrx_deregister_tx_flow_control_cb(uint8_t vdev_id);
+
+bool ol_txrx_get_tx_resource(uint8_t sta_id,
+			     unsigned int low_watermark,
+			     unsigned int high_watermark_offset);
+
+int ol_txrx_ll_set_tx_pause_q_depth(uint8_t vdev_id, int pause_q_depth);
+#endif
+
+void ol_tx_init_pdev(ol_txrx_pdev_handle pdev);
+
+#ifdef CONFIG_HL_SUPPORT
+void ol_txrx_vdev_txqs_init(struct ol_txrx_vdev_t *vdev);
+void ol_txrx_vdev_tx_queue_free(struct ol_txrx_vdev_t *vdev);
+void ol_txrx_peer_txqs_init(struct ol_txrx_pdev_t *pdev,
+			    struct ol_txrx_peer_t *peer);
+void ol_txrx_peer_tx_queue_free(struct ol_txrx_pdev_t *pdev,
+				struct ol_txrx_peer_t *peer);
+#else
+static inline void
+ol_txrx_vdev_txqs_init(struct ol_txrx_vdev_t *vdev) {}
+
+static inline void
+ol_txrx_vdev_tx_queue_free(struct ol_txrx_vdev_t *vdev) {}
+
+static inline void
+ol_txrx_peer_txqs_init(struct ol_txrx_pdev_t *pdev,
+		       struct ol_txrx_peer_t *peer) {}
+
+static inline void
+ol_txrx_peer_tx_queue_free(struct ol_txrx_pdev_t *pdev,
+			   struct ol_txrx_peer_t *peer) {}
+#endif
+
+#if defined(CONFIG_HL_SUPPORT) && defined(DEBUG_HL_LOGGING)
+void ol_txrx_pdev_txq_log_init(struct ol_txrx_pdev_t *pdev);
+void ol_txrx_pdev_txq_log_destroy(struct ol_txrx_pdev_t *pdev);
+void ol_txrx_pdev_grp_stats_init(struct ol_txrx_pdev_t *pdev);
+void ol_txrx_pdev_grp_stat_destroy(struct ol_txrx_pdev_t *pdev);
+#else
+static inline void
+ol_txrx_pdev_txq_log_init(struct ol_txrx_pdev_t *pdev) {}
+
+static inline void
+ol_txrx_pdev_txq_log_destroy(struct ol_txrx_pdev_t *pdev) {}
+
+static inline void
+ol_txrx_pdev_grp_stats_init(struct ol_txrx_pdev_t *pdev) {}
+
+static inline void
+ol_txrx_pdev_grp_stat_destroy(struct ol_txrx_pdev_t *pdev) {}
+#endif
+
+#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
+void ol_txrx_copy_mac_addr_raw(struct cdp_vdev *pvdev, uint8_t *bss_addr);
+void ol_txrx_add_last_real_peer(struct cdp_pdev *ppdev,
+				struct cdp_vdev *pvdev, uint8_t *peer_id);
+bool is_vdev_restore_last_peer(void *ppeer);
+void ol_txrx_update_last_real_peer(struct cdp_pdev *ppdev, void *ppeer,
+				   uint8_t *peer_id, bool restore_last_peer);
+#endif
+
+#if defined(FEATURE_TSO) && defined(FEATURE_TSO_DEBUG)
+void ol_txrx_stats_display_tso(ol_txrx_pdev_handle pdev);
+void ol_txrx_tso_stats_init(ol_txrx_pdev_handle pdev);
+void ol_txrx_tso_stats_deinit(ol_txrx_pdev_handle pdev);
+void ol_txrx_tso_stats_clear(ol_txrx_pdev_handle pdev);
+#else
+static inline
+void ol_txrx_stats_display_tso(ol_txrx_pdev_handle pdev)
+{
+	ol_txrx_err("TSO is not supported\n");
+}
+
+static inline
+void ol_txrx_tso_stats_init(ol_txrx_pdev_handle pdev) {}
+
+static inline
+void ol_txrx_tso_stats_deinit(ol_txrx_pdev_handle pdev) {}
+
+static inline
+void ol_txrx_tso_stats_clear(ol_txrx_pdev_handle pdev) {}
+#endif
+
+struct ol_tx_desc_t *
+ol_txrx_mgmt_tx_desc_alloc(struct ol_txrx_pdev_t *pdev,
+			   struct ol_txrx_vdev_t *vdev,
+			   qdf_nbuf_t tx_mgmt_frm,
+			   struct ol_txrx_msdu_info_t *tx_msdu_info);
+
+int ol_txrx_mgmt_send_frame(struct ol_txrx_vdev_t *vdev,
+			    struct ol_tx_desc_t *tx_desc,
+			    qdf_nbuf_t tx_mgmt_frm,
+			    struct ol_txrx_msdu_info_t *tx_msdu_info,
+			    uint16_t chanfreq);
+
+#ifdef CONFIG_HL_SUPPORT
+static inline
+uint32_t ol_tx_get_desc_global_pool_size(struct ol_txrx_pdev_t *pdev)
+{
+	return ol_tx_desc_pool_size_hl(pdev->ctrl_pdev);
+}
+#else
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+static inline
+uint32_t ol_tx_get_desc_global_pool_size(struct ol_txrx_pdev_t *pdev)
+{
+	return pdev->num_msdu_desc;
+}
+#else
+static inline
+uint32_t ol_tx_get_desc_global_pool_size(struct ol_txrx_pdev_t *pdev)
+{
+	return ol_cfg_target_tx_credit(pdev->ctrl_pdev);
+}
+#endif
+#endif
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+void ol_tx_set_desc_global_pool_size(uint32_t num_msdu_desc);
+uint32_t ol_tx_get_total_free_desc(struct ol_txrx_pdev_t *pdev);
+QDF_STATUS ol_txrx_register_pause_cb(struct cdp_soc_t *soc,
+				     tx_pause_callback pause_cb);
+/**
+ * ol_txrx_fwd_desc_thresh_check() - check to forward packet to tx path
+ * @vdev: which virtual device the frames were addressed to
+ *
+ * This API is to check whether enough descriptors are available or not
+ * to forward packet to tx path. If not enough descriptors left,
+ * start dropping tx-path packets.
+ * Do not pause netif queues as still a pool of descriptors is reserved
+ * for high-priority traffic such as EAPOL/ARP etc.
+ * In case of intra-bss forwarding, it could be possible that tx-path can
+ * consume all the tx descriptors and pause netif queues. Due to this,
+ * there would be some left for stack triggered packets such as ARP packets
+ * which could lead to disconnection of device. To avoid this, reserved
+ * a pool of descriptors for high-priority packets, i.e., reduce the
+ * threshold of drop in the intra-bss forwarding path.
+ *
+ * Return: true ; forward the packet, i.e., below threshold
+ *         false; not enough descriptors, drop the packet
+ */
+bool ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *vdev);
+#else
+/**
+ * ol_tx_get_total_free_desc() - get total free descriptors
+ * @pdev: pdev handle
+ *
+ * Return: total free descriptors
+ */
+static inline
+uint32_t ol_tx_get_total_free_desc(struct ol_txrx_pdev_t *pdev)
+{
+	return pdev->tx_desc.num_free;
+}
+
+static inline
+bool ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *vdev)
+{
+	return true;
+}
+
+#endif
+
+#if defined(FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL) && \
+	defined(FEATURE_HL_DBS_GROUP_CREDIT_SHARING)
+static inline void
+ol_txrx_init_txq_group_limit_lend(struct ol_txrx_pdev_t *pdev)
+{
+	BUILD_BUG_ON(OL_TX_MAX_GROUPS_PER_QUEUE > 1);
+	BUILD_BUG_ON(OL_TX_MAX_TXQ_GROUPS > 2);
+	pdev->limit_lend = 0;
+	pdev->min_reserve = 0;
+}
+#else
+static inline void
+ol_txrx_init_txq_group_limit_lend(struct ol_txrx_pdev_t *pdev)
+{}
+#endif
+
+int ol_txrx_fw_stats_desc_pool_init(struct ol_txrx_pdev_t *pdev,
+				    uint8_t pool_size);
+void ol_txrx_fw_stats_desc_pool_deinit(struct ol_txrx_pdev_t *pdev);
+struct ol_txrx_fw_stats_desc_t
+	*ol_txrx_fw_stats_desc_alloc(struct ol_txrx_pdev_t *pdev);
+struct ol_txrx_stats_req_internal
+	*ol_txrx_fw_stats_desc_get_req(struct ol_txrx_pdev_t *pdev,
+				       uint8_t desc_id);
+
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+int ol_txrx_register_hl_flow_control(struct cdp_soc_t *soc,
+				     tx_pause_callback flowcontrol);
+int ol_txrx_set_vdev_os_queue_status(u8 vdev_id, enum netif_action_type action);
+int ol_txrx_set_vdev_tx_desc_limit(u8 vdev_id, u8 chan);
+#endif
+#endif /* _OL_TXRX__H_ */
diff --git a/core/dp/txrx/ol_txrx_encap.c b/core/dp/txrx/ol_txrx_encap.c
new file mode 100644
index 0000000..1abb37f
--- /dev/null
+++ b/core/dp/txrx/ol_txrx_encap.c
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 2012-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.
+ */
+
+/**
+ * @file ol_txrx_encap.c
+ * @brief Provide functions to encap/decap on txrx frames.
+ * @details
+ *  This file contains functions for data frame encap/decap:
+ *  ol_tx_encap: encap outgoing data frames.
+ *  ol_rx_decap: decap incoming data frames.
+ */
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <cds_ieee80211_common.h>   /* ieee80211_frame */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT1 */
+#include <ol_txrx_encap.h>      /* struct ol_rx_decap_info_t */
+
+static inline A_STATUS
+ol_tx_copy_native_wifi_header(qdf_nbuf_t msdu,
+			      uint8_t *hdsize, uint8_t *localbuf)
+{
+	struct ieee80211_frame *wh =
+		(struct ieee80211_frame *)qdf_nbuf_data(msdu);
+	if ((wh->i_fc[1] &
+	     IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) {
+		*hdsize = sizeof(struct ieee80211_frame_addr4);
+	} else {
+		*hdsize = sizeof(struct ieee80211_frame);
+	}
+	if (qdf_nbuf_len(msdu) < *hdsize)
+		return A_ERROR;
+
+	qdf_mem_copy(localbuf, wh, *hdsize);
+	return A_OK;
+}
+
+static inline A_STATUS
+ol_tx_encap_from_native_wifi(struct ol_txrx_vdev_t *vdev,
+			     struct ol_tx_desc_t *tx_desc,
+			     qdf_nbuf_t msdu,
+			     struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4)];
+	struct ieee80211_frame *wh;
+	uint8_t hdsize, new_hdsize;
+	struct ieee80211_qoscntl *qos_cntl;
+	struct ol_txrx_peer_t *peer;
+
+	if (tx_msdu_info->htt.info.frame_type != htt_frm_type_data)
+		return A_OK;
+
+	peer = tx_msdu_info->peer;
+	/*
+	 * for unicast,the peer should not be NULL.
+	 * for multicast, the peer is AP.
+	 */
+	if (tx_msdu_info->htt.info.is_unicast && peer->qos_capable) {
+		if (A_OK !=
+		    ol_tx_copy_native_wifi_header(msdu, &hdsize, localbuf))
+			return A_ERROR;
+		wh = (struct ieee80211_frame *)localbuf;
+
+		/*add qos cntl */
+		qos_cntl = (struct ieee80211_qoscntl *)(localbuf + hdsize);
+		qos_cntl->i_qos[0] =
+			tx_msdu_info->htt.info.ext_tid & IEEE80211_QOS_TID;
+
+#ifdef NEVERDEFINED
+		if (wmmParam[ac].wmep_noackPolicy)
+			qos_cntl->i_qos[0] |= 1 << IEEE80211_QOS_ACKPOLICY_S;
+#endif
+
+		qos_cntl->i_qos[1] = 0;
+		wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_QOS;
+		/* count for qos field */
+		new_hdsize =
+			hdsize + sizeof(struct ieee80211_qosframe) -
+			sizeof(struct ieee80211_frame);
+
+		/*add ht control field if needed */
+
+		/* copy new hd to bd */
+		qdf_mem_copy((void *)
+			     htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc,
+						     new_hdsize), localbuf,
+			     new_hdsize);
+		qdf_nbuf_pull_head(msdu, hdsize);
+		tx_msdu_info->htt.info.l3_hdr_offset = new_hdsize;
+		tx_desc->orig_l2_hdr_bytes = hdsize;
+	}
+	/* Set Protected Frame bit in MAC header */
+	if (vdev->pdev->sw_pf_proc_enable
+	    && tx_msdu_info->htt.action.do_encrypt) {
+		if (tx_desc->orig_l2_hdr_bytes) {
+			wh = (struct ieee80211_frame *)
+			     htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc,
+						     tx_msdu_info->htt.info.
+						     l3_hdr_offset);
+		} else {
+			if (A_OK !=
+			    ol_tx_copy_native_wifi_header(msdu, &hdsize,
+							  localbuf))
+				return A_ERROR;
+			wh = (struct ieee80211_frame *)
+			     htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc,
+						     hdsize);
+			qdf_mem_copy((void *)wh, localbuf, hdsize);
+			qdf_nbuf_pull_head(msdu, hdsize);
+			tx_msdu_info->htt.info.l3_hdr_offset = hdsize;
+			tx_desc->orig_l2_hdr_bytes = hdsize;
+		}
+		wh->i_fc[1] |= IEEE80211_FC1_WEP;
+	}
+	return A_OK;
+}
+
+static inline A_STATUS
+ol_tx_encap_from_8023(struct ol_txrx_vdev_t *vdev,
+		      struct ol_tx_desc_t *tx_desc,
+		      qdf_nbuf_t msdu, struct ol_txrx_msdu_info_t *tx_msdu_info)
+{
+	uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4)
+			 + sizeof(struct llc_snap_hdr_t)];
+	struct llc_snap_hdr_t *llc_hdr;
+	struct ethernet_hdr_t *eth_hdr;
+	struct ieee80211_frame *wh;
+	uint8_t hdsize, new_l2_hdsize, new_hdsize;
+	struct ieee80211_qoscntl *qos_cntl;
+	const uint8_t ethernet_II_llc_snap_header_prefix[] = {
+		0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+	struct ol_txrx_peer_t *peer;
+	uint16_t ether_type;
+
+	if (tx_msdu_info->htt.info.frame_type != htt_frm_type_data)
+		return A_OK;
+
+	/*
+	 * for unicast,the peer should not be NULL.
+	 * for multicast, the peer is AP.
+	 */
+	peer = tx_msdu_info->peer;
+
+	eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu);
+	hdsize = sizeof(struct ethernet_hdr_t);
+	wh = (struct ieee80211_frame *)localbuf;
+	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
+	*(uint16_t *) wh->i_dur = 0;
+	new_hdsize = 0;
+
+	switch (vdev->opmode) {
+	case wlan_op_mode_ap:
+		/* DA , BSSID , SA */
+		qdf_mem_copy(wh->i_addr1, eth_hdr->dest_addr,
+			     IEEE80211_ADDR_LEN);
+		qdf_mem_copy(wh->i_addr2, &vdev->mac_addr.raw,
+			     IEEE80211_ADDR_LEN);
+		qdf_mem_copy(wh->i_addr3, eth_hdr->src_addr,
+			     IEEE80211_ADDR_LEN);
+		wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
+		new_hdsize = sizeof(struct ieee80211_frame);
+		break;
+	case wlan_op_mode_ibss:
+		/* DA, SA, BSSID */
+		qdf_mem_copy(wh->i_addr1, eth_hdr->dest_addr,
+			     IEEE80211_ADDR_LEN);
+		qdf_mem_copy(wh->i_addr2, eth_hdr->src_addr,
+			     IEEE80211_ADDR_LEN);
+		/* need to check the bssid behaviour for IBSS vdev */
+		qdf_mem_copy(wh->i_addr3, &vdev->mac_addr.raw,
+			     IEEE80211_ADDR_LEN);
+		wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
+		new_hdsize = sizeof(struct ieee80211_frame);
+		break;
+	case wlan_op_mode_sta:
+		/* BSSID, SA , DA */
+		qdf_mem_copy(wh->i_addr1, &peer->mac_addr.raw,
+			     IEEE80211_ADDR_LEN);
+		qdf_mem_copy(wh->i_addr2, eth_hdr->src_addr,
+			     IEEE80211_ADDR_LEN);
+		qdf_mem_copy(wh->i_addr3, eth_hdr->dest_addr,
+			     IEEE80211_ADDR_LEN);
+		wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
+		new_hdsize = sizeof(struct ieee80211_frame);
+		break;
+	case wlan_op_mode_monitor:
+	default:
+		return A_ERROR;
+	}
+	/*add qos cntl */
+	if (tx_msdu_info->htt.info.is_unicast && peer->qos_capable) {
+		qos_cntl = (struct ieee80211_qoscntl *)(localbuf + new_hdsize);
+		qos_cntl->i_qos[0] =
+			tx_msdu_info->htt.info.ext_tid & IEEE80211_QOS_TID;
+		wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_QOS;
+#ifdef NEVERDEFINED
+		if (wmmParam[ac].wmep_noackPolicy)
+			qos_cntl->i_qos[0] |= 1 << IEEE80211_QOS_ACKPOLICY_S;
+#endif
+		qos_cntl->i_qos[1] = 0;
+		new_hdsize += sizeof(struct ieee80211_qoscntl);
+
+		/*add ht control field if needed */
+	}
+	/* Set Protected Frame bit in MAC header */
+	if (vdev->pdev->sw_pf_proc_enable
+	    && tx_msdu_info->htt.action.do_encrypt) {
+		wh->i_fc[1] |= IEEE80211_FC1_WEP;
+	}
+	new_l2_hdsize = new_hdsize;
+	/* add llc snap if needed */
+	if (vdev->pdev->sw_tx_llc_proc_enable) {
+		llc_hdr = (struct llc_snap_hdr_t *)(localbuf + new_hdsize);
+		ether_type =
+			(eth_hdr->ethertype[0] << 8) | (eth_hdr->ethertype[1]);
+		if (ether_type >= IEEE8023_MAX_LEN) {
+			qdf_mem_copy(llc_hdr,
+				     ethernet_II_llc_snap_header_prefix,
+				     sizeof
+				     (ethernet_II_llc_snap_header_prefix));
+			if (ether_type == ETHERTYPE_AARP
+			    || ether_type == ETHERTYPE_IPX) {
+				llc_hdr->org_code[2] = BTEP_SNAP_ORGCODE_2;
+				/* 0xf8; bridge tunnel header */
+			}
+			llc_hdr->ethertype[0] = eth_hdr->ethertype[0];
+			llc_hdr->ethertype[1] = eth_hdr->ethertype[1];
+			new_hdsize += sizeof(struct llc_snap_hdr_t);
+		} else {
+			/*
+			 * llc ready, and it's in payload pdu,
+			 * do we need to move to BD pdu?
+			 */
+		}
+	}
+	qdf_mem_copy((void *)
+		     htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc,
+					     new_l2_hdsize), localbuf,
+		     new_hdsize);
+	qdf_nbuf_pull_head(msdu, hdsize);
+	tx_msdu_info->htt.info.l3_hdr_offset = new_l2_hdsize;
+	tx_desc->orig_l2_hdr_bytes = hdsize;
+	return A_OK;
+}
+
+A_STATUS
+ol_tx_encap(struct ol_txrx_vdev_t *vdev,
+	    struct ol_tx_desc_t *tx_desc,
+	    qdf_nbuf_t msdu, struct ol_txrx_msdu_info_t *msdu_info)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+
+	if (pdev->frame_format == wlan_frm_fmt_native_wifi) {
+		return ol_tx_encap_from_native_wifi(vdev, tx_desc, msdu,
+						    msdu_info);
+	} else if (pdev->frame_format == wlan_frm_fmt_802_3) {
+		return ol_tx_encap_from_8023(vdev, tx_desc, msdu, msdu_info);
+	}
+
+	/* todo for other types */
+	return A_ERROR;
+}
+
+static inline void
+ol_rx_decap_to_native_wifi(struct ol_txrx_vdev_t *vdev,
+			   qdf_nbuf_t msdu,
+			   struct ol_rx_decap_info_t *info,
+			   struct ethernet_hdr_t *ethr_hdr)
+{
+	struct ieee80211_frame_addr4 *wh;
+	uint16_t hdsize;
+
+	/*
+	 * we need to remove Qos control field and HT control.
+	 * MSFT: http://msdn.microsoft.com/en-us/library/windows/
+	 * hardware/ff552608(v=vs.85).aspx
+	 */
+	wh = (struct ieee80211_frame_addr4 *)info->hdr;
+	if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) ==
+	    IEEE80211_FC1_DIR_DSTODS)
+		hdsize = sizeof(struct ieee80211_frame_addr4);
+	else
+		hdsize = sizeof(struct ieee80211_frame);
+
+	wh = (struct ieee80211_frame_addr4 *)qdf_nbuf_push_head(msdu, hdsize);
+	TXRX_ASSERT2(wh != NULL);
+	TXRX_ASSERT2(hdsize <= info->hdr_len);
+	qdf_mem_copy((uint8_t *) wh, info->hdr, hdsize);
+
+	/* amsdu subfrm handling if ethr_hdr is not NULL  */
+	if (ethr_hdr != NULL) {
+		switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
+		case IEEE80211_FC1_DIR_NODS:
+			qdf_mem_copy(wh->i_addr1, ethr_hdr->dest_addr,
+				     ETHERNET_ADDR_LEN);
+			qdf_mem_copy(wh->i_addr2, ethr_hdr->src_addr,
+				     ETHERNET_ADDR_LEN);
+			break;
+		case IEEE80211_FC1_DIR_TODS:
+			qdf_mem_copy(wh->i_addr2, ethr_hdr->src_addr,
+				     ETHERNET_ADDR_LEN);
+			qdf_mem_copy(wh->i_addr3, ethr_hdr->dest_addr,
+				     ETHERNET_ADDR_LEN);
+			break;
+		case IEEE80211_FC1_DIR_FROMDS:
+			qdf_mem_copy(wh->i_addr1, ethr_hdr->dest_addr,
+				     ETHERNET_ADDR_LEN);
+			qdf_mem_copy(wh->i_addr3, ethr_hdr->src_addr,
+				     ETHERNET_ADDR_LEN);
+			break;
+		case IEEE80211_FC1_DIR_DSTODS:
+			qdf_mem_copy(wh->i_addr3, ethr_hdr->dest_addr,
+				     ETHERNET_ADDR_LEN);
+			qdf_mem_copy(wh->i_addr4, ethr_hdr->src_addr,
+				     ETHERNET_ADDR_LEN);
+			break;
+		}
+	}
+	if (IEEE80211_QOS_HAS_SEQ(wh)) {
+		if (wh->i_fc[1] & IEEE80211_FC1_ORDER)
+			wh->i_fc[1] &= ~IEEE80211_FC1_ORDER;
+		wh->i_fc[0] &= ~IEEE80211_FC0_SUBTYPE_QOS;
+	}
+}
+
+static inline void
+ol_rx_decap_to_8023(struct ol_txrx_vdev_t *vdev,
+		    qdf_nbuf_t msdu,
+		    struct ol_rx_decap_info_t *info,
+		    struct ethernet_hdr_t *ethr_hdr)
+{
+	struct llc_snap_hdr_t *llc_hdr;
+	uint16_t ether_type;
+	uint16_t l2_hdr_space;
+	struct ieee80211_frame_addr4 *wh;
+	uint8_t local_buf[ETHERNET_HDR_LEN];
+	uint8_t *buf;
+
+	/*
+	 * populate Ethernet header,
+	 * if ethr_hdr is null, rx frame is 802.11 format(HW ft disabled)
+	 * if ethr_hdr is not null, rx frame is "subfrm of amsdu".
+	 */
+	buf = (uint8_t *) qdf_nbuf_data(msdu);
+	llc_hdr = (struct llc_snap_hdr_t *)buf;
+	ether_type = (llc_hdr->ethertype[0] << 8) | llc_hdr->ethertype[1];
+	/* do llc remove if needed */
+	l2_hdr_space = 0;
+	if (IS_SNAP(llc_hdr)) {
+		if (IS_BTEP(llc_hdr)) {
+			/* remove llc */
+			l2_hdr_space += sizeof(struct llc_snap_hdr_t);
+			llc_hdr = NULL;
+		} else if (IS_RFC1042(llc_hdr)) {
+			if (!(ether_type == ETHERTYPE_AARP ||
+			      ether_type == ETHERTYPE_IPX)) {
+				/* remove llc */
+				l2_hdr_space += sizeof(struct llc_snap_hdr_t);
+				llc_hdr = NULL;
+			}
+		}
+	}
+	if (l2_hdr_space > ETHERNET_HDR_LEN)
+		buf = qdf_nbuf_pull_head(msdu, l2_hdr_space - ETHERNET_HDR_LEN);
+	else if (l2_hdr_space < ETHERNET_HDR_LEN)
+		buf = qdf_nbuf_push_head(msdu, ETHERNET_HDR_LEN - l2_hdr_space);
+
+	/* normal msdu(non-subfrm of A-MSDU) if ethr_hdr is null */
+	if (ethr_hdr == NULL) {
+		/*
+		 * mpdu hdr should be present in info,
+		 * re-create ethr_hdr based on mpdu hdr
+		 */
+		TXRX_ASSERT2(info->hdr_len != 0);
+		wh = (struct ieee80211_frame_addr4 *)info->hdr;
+		ethr_hdr = (struct ethernet_hdr_t *)local_buf;
+		switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
+		case IEEE80211_FC1_DIR_NODS:
+			qdf_mem_copy(ethr_hdr->dest_addr, wh->i_addr1,
+				     ETHERNET_ADDR_LEN);
+			qdf_mem_copy(ethr_hdr->src_addr, wh->i_addr2,
+				     ETHERNET_ADDR_LEN);
+			break;
+		case IEEE80211_FC1_DIR_TODS:
+			qdf_mem_copy(ethr_hdr->dest_addr, wh->i_addr3,
+				     ETHERNET_ADDR_LEN);
+			qdf_mem_copy(ethr_hdr->src_addr, wh->i_addr2,
+				     ETHERNET_ADDR_LEN);
+			break;
+		case IEEE80211_FC1_DIR_FROMDS:
+			qdf_mem_copy(ethr_hdr->dest_addr, wh->i_addr1,
+				     ETHERNET_ADDR_LEN);
+			qdf_mem_copy(ethr_hdr->src_addr, wh->i_addr3,
+				     ETHERNET_ADDR_LEN);
+			break;
+		case IEEE80211_FC1_DIR_DSTODS:
+			qdf_mem_copy(ethr_hdr->dest_addr, wh->i_addr3,
+				     ETHERNET_ADDR_LEN);
+			qdf_mem_copy(ethr_hdr->src_addr, wh->i_addr4,
+				     ETHERNET_ADDR_LEN);
+			break;
+		}
+	}
+	if (llc_hdr == NULL) {
+		ethr_hdr->ethertype[0] = (ether_type >> 8) & 0xff;
+		ethr_hdr->ethertype[1] = (ether_type) & 0xff;
+	} else {
+		uint32_t pktlen =
+			qdf_nbuf_len(msdu) - sizeof(ethr_hdr->ethertype);
+		TXRX_ASSERT2(pktlen <= ETHERNET_MTU);
+		ether_type = (uint16_t) pktlen;
+		ether_type = qdf_nbuf_len(msdu) - sizeof(struct ethernet_hdr_t);
+		ethr_hdr->ethertype[0] = (ether_type >> 8) & 0xff;
+		ethr_hdr->ethertype[1] = (ether_type) & 0xff;
+	}
+	qdf_mem_copy(buf, ethr_hdr, ETHERNET_HDR_LEN);
+}
+
+static inline A_STATUS
+ol_rx_decap_subfrm_amsdu(struct ol_txrx_vdev_t *vdev,
+			 qdf_nbuf_t msdu, struct ol_rx_decap_info_t *info)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	uint8_t *subfrm_hdr;
+	uint8_t localbuf[ETHERNET_HDR_LEN];
+	struct ethernet_hdr_t *ether_hdr = (struct ethernet_hdr_t *)localbuf;
+
+	subfrm_hdr = (uint8_t *) qdf_nbuf_data(msdu);
+	if (pdev->frame_format == wlan_frm_fmt_native_wifi) {
+		/* decap to native wifi */
+		qdf_mem_copy(ether_hdr, subfrm_hdr, ETHERNET_HDR_LEN);
+		qdf_nbuf_pull_head(msdu, ETHERNET_HDR_LEN);
+		ol_rx_decap_to_native_wifi(vdev, msdu, info, ether_hdr);
+	} else if (pdev->frame_format == wlan_frm_fmt_802_3) {
+		if (pdev->sw_rx_llc_proc_enable) {
+			/* remove llc snap hdr if it's necessary according to
+			 * 802.11 table P-3
+			 */
+			qdf_mem_copy(ether_hdr, subfrm_hdr, ETHERNET_HDR_LEN);
+			qdf_nbuf_pull_head(msdu, ETHERNET_HDR_LEN);
+			ol_rx_decap_to_8023(vdev, msdu, info, ether_hdr);
+		} else {
+			/* subfrm of A-MSDU is already in 802.3 format.
+			 * if target HW or FW has done LLC rmv process,
+			 * we do nothing here.
+			 */
+		}
+	} else {
+		/* todo for othertype */
+	}
+	return A_OK;
+
+}
+
+static inline A_STATUS
+ol_rx_decap_msdu(struct ol_txrx_vdev_t *vdev,
+		 qdf_nbuf_t msdu, struct ol_rx_decap_info_t *info)
+{
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	struct ieee80211_frame *wh;
+
+	wh = (struct ieee80211_frame *)qdf_nbuf_data(msdu);
+
+	if (pdev->frame_format == wlan_frm_fmt_native_wifi) {
+		/* Decap to native wifi because according to MSFT(
+		 * MSFT: http://msdn.microsoft.com/en-us/library/windows/
+		 * hardware/ff552608(v=vs.85).aspx),
+		 * we need to remove Qos and HTC field before indicate to OS.
+		 */
+		if (IEEE80211_QOS_HAS_SEQ(wh)) {
+			info->hdr_len = ol_txrx_ieee80211_hdrsize(wh);
+			TXRX_ASSERT2(info->hdr_len <= sizeof(info->hdr));
+			qdf_mem_copy(info->hdr, /* use info->hdr as temp buf. */
+				     wh, info->hdr_len);
+			qdf_nbuf_pull_head(msdu, info->hdr_len);
+			ol_rx_decap_to_native_wifi(vdev, msdu, info, NULL);
+			/*                           802.11 hdr^  eth_hdr^ */
+		}
+	} else if (pdev->frame_format == wlan_frm_fmt_802_3) {
+		if (pdev->sw_rx_llc_proc_enable) {
+			info->hdr_len = ol_txrx_ieee80211_hdrsize(wh);
+			TXRX_ASSERT2(info->hdr_len <= sizeof(info->hdr));
+			qdf_mem_copy(info->hdr, /* use info->hdr as temp buf. */
+				     wh, info->hdr_len);
+			qdf_nbuf_pull_head(msdu, info->hdr_len);
+			/* remove llc snap hdr if it's necessary according to
+			 * 802.11 table P-3
+			 */
+			ol_rx_decap_to_8023(vdev, msdu, info,   /* 802.11 hdr */
+					    NULL);      /* ethernet hdr */
+		} else {
+			/* Subfrm of A-MSDU is already in 802.3 format.
+			 * And if target HW or FW has done LLC rmv process (
+			 * sw_rx_lc_proc_enable == 0), we do nothing here.
+			 */
+		}
+	} else {
+		/* todo for othertype */
+	}
+	return A_OK;
+
+}
+
+A_STATUS
+ol_rx_decap(struct ol_txrx_vdev_t *vdev,
+	    struct ol_txrx_peer_t *peer,
+	    qdf_nbuf_t msdu, struct ol_rx_decap_info_t *info)
+{
+	A_STATUS status;
+	uint8_t *mpdu_hdr;
+
+	if (!info->is_subfrm) {
+		if (info->is_msdu_cmpl_mpdu && !info->is_first_subfrm) {
+			/* It's normal MSDU. */
+		} else {
+			/*
+			 * It's a first subfrm of A-MSDU and
+			 * may also be the last subfrm of A-MSDU
+			 */
+			info->is_subfrm = 1;
+			info->hdr_len = 0;
+			if (vdev->pdev->sw_subfrm_hdr_recovery_enable) {
+				/* we save the first subfrm mpdu hdr for
+				 * subsequent subfrm 802.11 header recovery
+				 * in certain chip(such as Riva).
+				 */
+				mpdu_hdr = qdf_nbuf_data(msdu);
+				info->hdr_len =
+					ol_txrx_ieee80211_hdrsize(mpdu_hdr);
+				TXRX_ASSERT2(info->hdr_len <=
+					     sizeof(info->hdr));
+				qdf_mem_copy(info->hdr, mpdu_hdr,
+					     info->hdr_len);
+				qdf_nbuf_pull_head(msdu, info->hdr_len);
+			}
+		}
+	}
+
+	if (info->is_subfrm && vdev->pdev->sw_subfrm_hdr_recovery_enable) {
+		/*
+		 * This case is enabled for some HWs (such as Riva). The HW
+		 * de-aggregate doesn't have capability to generate 802.11
+		 * header for non-first subframe of A-MSDU. That means sw needs
+		 * to cache the first subfrm mpdu header to generate the
+		 * subsequent subfrm's 802.11 header.
+		 */
+		TXRX_ASSERT2(info->hdr_len != 0);
+		status = ol_rx_decap_subfrm_amsdu(vdev, msdu, info);
+	} else {
+		status = ol_rx_decap_msdu(vdev, msdu, info);
+	}
+
+	if (info->is_msdu_cmpl_mpdu)
+		info->is_subfrm = info->is_first_subfrm = info->hdr_len = 0;
+
+	return status;
+}
+#endif
diff --git a/core/dp/txrx/ol_txrx_encap.h b/core/dp/txrx/ol_txrx_encap.h
new file mode 100644
index 0000000..360717e
--- /dev/null
+++ b/core/dp/txrx/ol_txrx_encap.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2012, 2014-2016, 2018 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.
+ */
+
+/**
+ * @file ol_txrx_encap.h
+ * @brief definitions for txrx encap/decap function and struct
+ */
+#ifndef _OL_TXRX_ENCAP__H_
+#define _OL_TXRX_ENCAP__H_
+
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+
+#include <qdf_nbuf.h>               /* qdf_nbuf_t */
+#include <cds_ieee80211_common.h>   /* ieee80211_qosframe_htc_addr4 */
+#include <cdp_txrx_cmn.h>           /* ol_txrx_vdev_t, etc. */
+
+/**
+ * @brief Encap outgoing frm from OS dependent format to Target
+ *        acceptable frm format
+ * @details
+ *     For native wifi format, the function will add Qos control field
+ *  based on peer's QOS capbabilities .
+ *     For 802.3 format, the function will transform to 802.11 format
+ *  with or without QOS control field based on peer's QOS capabilities.
+ * @param vdev - handle to vdev object
+ * @param tx_desc - tx desc struct,some fields will be updated.
+ * @param msdu - qdf_nbuf_t
+ * @param msdu_info - information from tx classification.
+ * @return
+ *     A_OK: encap operation successful
+ *     other: operation failed,the msdu need be dropped.
+ */
+A_STATUS
+ol_tx_encap(struct ol_txrx_vdev_t *vdev,
+	    struct ol_tx_desc_t *tx_desc,
+	    qdf_nbuf_t msdu, struct ol_txrx_msdu_info_t *msdu_info);
+
+struct ol_rx_decap_info_t {
+	uint8_t hdr[sizeof(struct ieee80211_qosframe_htc_addr4)];
+	int hdr_len;
+	uint8_t is_subfrm:1, is_first_subfrm:1, is_msdu_cmpl_mpdu:1;
+};
+
+/**
+ * @brief decap incoming frm from Target to Host OS
+ *        acceptable frm format
+ * @details
+ *     For native wifi format, the function will remove Qos control field
+ *  and HT control field if any.
+ *     For 802.3 format, the function will will do llc snap header process
+ *  if Target haven't done that.
+ * @param vdev - handle to vdev object
+ * @param peer - the peer object.
+ * @param msdu - qdf_nbuf_t
+ * @param info - ol_rx_decap_info_t: context info for decap
+ * @return
+ *     A_OK: decap operation successful
+ *     other: operation failed,the msdu need be dropped.
+ */
+A_STATUS
+ol_rx_decap(struct ol_txrx_vdev_t *vdev,
+	    struct ol_txrx_peer_t *peer,
+	    qdf_nbuf_t msdu, struct ol_rx_decap_info_t *info);
+
+static inline A_STATUS
+OL_TX_ENCAP(struct ol_txrx_vdev_t *vdev,
+	    struct ol_tx_desc_t *tx_desc,
+	    qdf_nbuf_t msdu, struct ol_txrx_msdu_info_t *msdu_info)
+{
+	if (vdev->pdev->sw_tx_encap)
+		return ol_tx_encap(vdev, tx_desc, msdu, msdu_info);
+	return A_OK;
+}
+
+static inline A_STATUS
+OL_RX_DECAP(struct ol_txrx_vdev_t *vdev,
+	    struct ol_txrx_peer_t *peer,
+	    qdf_nbuf_t msdu, struct ol_rx_decap_info_t *info)
+{
+	if (vdev->pdev->sw_rx_decap)
+		return ol_rx_decap(vdev, peer, msdu, info);
+	return A_OK;
+}
+
+#define OL_TX_RESTORE_HDR(__tx_desc, __msdu)  \
+	do {								\
+		if (__tx_desc->orig_l2_hdr_bytes != 0)			\
+			qdf_nbuf_push_head(__msdu,			\
+					   __tx_desc->orig_l2_hdr_bytes); \
+	} while (0)
+#else
+#define OL_TX_ENCAP(vdev, tx_desc, msdu, msdu_info) A_OK
+#define OL_RX_DECAP(vdev, peer, msdu, info) A_OK
+#define OL_TX_RESTORE_HDR(__tx_desc, __msdu)
+#endif
+#endif /* _OL_TXRX_ENCAP__H_ */
diff --git a/core/dp/txrx/ol_txrx_event.c b/core/dp/txrx/ol_txrx_event.c
new file mode 100644
index 0000000..a144497
--- /dev/null
+++ b/core/dp/txrx/ol_txrx_event.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#include "ol_txrx_types.h"
+
+static inline wdi_event_subscribe *wdi_event_next_sub(wdi_event_subscribe *
+						      wdi_sub)
+{
+	if (!wdi_sub) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid subscriber in %s\n", __func__);
+		return NULL;
+	}
+	return wdi_sub->priv.next;
+}
+
+static inline void
+wdi_event_del_subs(wdi_event_subscribe *wdi_sub, int event_index)
+{
+	wdi_event_notify deallocate_sub;
+
+	while (wdi_sub) {
+		wdi_event_subscribe *next = wdi_event_next_sub(wdi_sub);
+		/*
+		 *  Context is NULL for static allocation of subs
+		 *  In dynamic allocation case notify the user
+		 */
+		if (wdi_sub->context) {
+			deallocate_sub = wdi_sub->context;
+			deallocate_sub(WDI_EVENT_SUB_DEALLOCATE,
+				       WDI_EVENT_BASE + event_index);
+		}
+		wdi_sub = next;
+	}
+	/* qdf_mem_free(wdi_sub); */
+}
+
+static inline void
+wdi_event_iter_sub(struct ol_txrx_pdev_t *pdev,
+		   uint32_t event_index,
+		   wdi_event_subscribe *wdi_sub, void *data)
+{
+	enum WDI_EVENT event = event_index + WDI_EVENT_BASE;
+
+	if (wdi_sub) {
+		do {
+			wdi_sub->callback(pdev, event, data, 0, 0);
+		} while ((wdi_sub = wdi_event_next_sub(wdi_sub)));
+	}
+}
+
+void
+wdi_event_handler(enum WDI_EVENT event,
+		  struct cdp_pdev *ppdev, void *data)
+{
+	uint32_t event_index;
+	wdi_event_subscribe *wdi_sub;
+	struct ol_txrx_pdev_t *txrx_pdev =
+				(struct ol_txrx_pdev_t *)ppdev;
+
+	/*
+	 * Input validation
+	 */
+	if (!event) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid WDI event in %s\n", __func__);
+		return;
+	}
+	if (!txrx_pdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid pdev in WDI event handler\n");
+		return;
+	}
+	/*
+	 *  There can be NULL data, so no validation for the data
+	 *  Subscribers must do the sanity based on the requirements
+	 */
+	event_index = event - WDI_EVENT_BASE;
+
+	wdi_sub = txrx_pdev->wdi_event_list[event_index];
+
+	/* Find the subscriber */
+	wdi_event_iter_sub(txrx_pdev, event_index, wdi_sub, data);
+}
+
+A_STATUS
+wdi_event_sub(struct cdp_pdev *ppdev,
+	      void *pevent_cb_sub, uint32_t event)
+{
+	uint32_t event_index;
+	wdi_event_subscribe *wdi_sub;
+	struct ol_txrx_pdev_t *txrx_pdev =
+				(struct ol_txrx_pdev_t *)ppdev;
+	wdi_event_subscribe *event_cb_sub =
+				(wdi_event_subscribe *)pevent_cb_sub;
+
+	/* Input validation */
+	if (!txrx_pdev || !txrx_pdev->wdi_event_list) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid txrx_pdev or wdi_event_list in %s",
+			  __func__);
+		return A_ERROR;
+	}
+	if (!event_cb_sub) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid callback in %s", __func__);
+		return A_ERROR;
+	}
+	if ((!event) || (event >= WDI_EVENT_LAST) || (event < WDI_EVENT_BASE)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid event in %s", __func__);
+		return A_ERROR;
+	}
+	/* Input validation */
+	event_index = event - WDI_EVENT_BASE;
+
+	wdi_sub = txrx_pdev->wdi_event_list[event_index];
+	/*
+	 *  Check if it is the first subscriber of the event
+	 */
+	if (!wdi_sub) {
+		wdi_sub = event_cb_sub;
+		wdi_sub->priv.next = NULL;
+		wdi_sub->priv.prev = NULL;
+		txrx_pdev->wdi_event_list[event_index] = wdi_sub;
+		return A_OK;
+	}
+	event_cb_sub->priv.next = wdi_sub;
+	event_cb_sub->priv.prev = NULL;
+	wdi_sub->priv.prev = event_cb_sub;
+	txrx_pdev->wdi_event_list[event_index] = event_cb_sub;
+
+	return A_OK;
+}
+
+A_STATUS
+wdi_event_unsub(struct cdp_pdev *ppdev,
+		void *pevent_cb_sub, uint32_t event)
+{
+	uint32_t event_index = event - WDI_EVENT_BASE;
+
+	struct ol_txrx_pdev_t *txrx_pdev =
+				(struct ol_txrx_pdev_t *)ppdev;
+
+	wdi_event_subscribe *event_cb_sub =
+				(wdi_event_subscribe *)pevent_cb_sub;
+
+	/* Input validation */
+	if (!event_cb_sub) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid callback in %s", __func__);
+		return A_ERROR;
+	}
+	if (!event_cb_sub->priv.prev) {
+		txrx_pdev->wdi_event_list[event_index] =
+			event_cb_sub->priv.next;
+	} else {
+		event_cb_sub->priv.prev->priv.next = event_cb_sub->priv.next;
+	}
+	if (event_cb_sub->priv.next)
+		event_cb_sub->priv.next->priv.prev = event_cb_sub->priv.prev;
+
+	/* qdf_mem_free(event_cb_sub); */
+
+	return A_OK;
+}
+
+A_STATUS wdi_event_attach(struct ol_txrx_pdev_t *txrx_pdev)
+{
+	/* Input validation */
+	if (!txrx_pdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid device in %s\nWDI event attach failed",
+			  __func__);
+		return A_ERROR;
+	}
+	/* Separate subscriber list for each event */
+	txrx_pdev->wdi_event_list = (wdi_event_subscribe **)
+				    qdf_mem_malloc(
+					    sizeof(wdi_event_subscribe *) *
+					    WDI_NUM_EVENTS);
+	if (!txrx_pdev->wdi_event_list) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Insufficient memory for the WDI event lists\n");
+		return A_NO_MEMORY;
+	}
+	return A_OK;
+}
+
+A_STATUS wdi_event_detach(struct ol_txrx_pdev_t *txrx_pdev)
+{
+	int i;
+	wdi_event_subscribe *wdi_sub;
+
+	if (!txrx_pdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid device in %s\nWDI detach failed",
+			  __func__);
+		return A_ERROR;
+	}
+	if (!txrx_pdev->wdi_event_list) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: wdi_event_list is NULL", __func__);
+		return A_ERROR;
+	}
+
+	for (i = 0; i < WDI_NUM_EVENTS; i++) {
+		wdi_sub = txrx_pdev->wdi_event_list[i];
+		if (wdi_sub) {
+			/* Delete all the subscribers */
+			wdi_event_del_subs(wdi_sub, i);
+		}
+	}
+	/* txrx_pdev->wdi_event_list would be non-null */
+	qdf_mem_free(txrx_pdev->wdi_event_list);
+	txrx_pdev->wdi_event_list = NULL;
+	return A_OK;
+}
diff --git a/core/dp/txrx/ol_txrx_flow_control.c b/core/dp/txrx/ol_txrx_flow_control.c
new file mode 100644
index 0000000..d4350f1
--- /dev/null
+++ b/core/dp/txrx/ol_txrx_flow_control.c
@@ -0,0 +1,1341 @@
+/*
+ * Copyright (c) 2015-2018 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.
+ */
+
+/* OS abstraction libraries */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_atomic.h>         /* qdf_atomic_read, etc. */
+#include <qdf_util.h>           /* qdf_unlikely */
+
+/* APIs for other modules */
+#include <htt.h>                /* HTT_TX_EXT_TID_MGMT */
+#include <ol_htt_tx_api.h>      /* htt_tx_desc_tid */
+
+/* internal header files relevant for all systems */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT1 */
+#include <ol_tx_desc.h>         /* ol_tx_desc */
+#include <ol_tx_send.h>         /* ol_tx_send */
+#include <ol_txrx.h>            /* ol_txrx_get_vdev_from_vdev_id */
+
+/* internal header files relevant only for HL systems */
+#include <ol_tx_queue.h>        /* ol_tx_enqueue */
+
+/* internal header files relevant only for specific systems (Pronto) */
+#include <ol_txrx_encap.h>      /* OL_TX_ENCAP, etc */
+#include <ol_tx.h>
+#include <ol_cfg.h>
+#include <cdp_txrx_handle.h>
+#define INVALID_FLOW_ID 0xFF
+#define MAX_INVALID_BIN 3
+
+#ifdef QCA_LL_TX_FLOW_GLOBAL_MGMT_POOL
+#define TX_FLOW_MGMT_POOL_ID	0xEF
+#define TX_FLOW_MGMT_POOL_SIZE  32
+
+/**
+ * ol_tx_register_global_mgmt_pool() - register global pool for mgmt packets
+ * @pdev: pdev handler
+ *
+ * Return: none
+ */
+static void
+ol_tx_register_global_mgmt_pool(struct ol_txrx_pdev_t *pdev)
+{
+	pdev->mgmt_pool = ol_tx_create_flow_pool(TX_FLOW_MGMT_POOL_ID,
+						 TX_FLOW_MGMT_POOL_SIZE);
+	if (!pdev->mgmt_pool)
+		ol_txrx_err("Management pool creation failed\n");
+}
+
+/**
+ * ol_tx_deregister_global_mgmt_pool() - Deregister global pool for mgmt packets
+ * @pdev: pdev handler
+ *
+ * Return: none
+ */
+static void
+ol_tx_deregister_global_mgmt_pool(struct ol_txrx_pdev_t *pdev)
+{
+	ol_tx_dec_pool_ref(pdev->mgmt_pool, false);
+}
+#else
+static inline void
+ol_tx_register_global_mgmt_pool(struct ol_txrx_pdev_t *pdev)
+{
+}
+static inline void
+ol_tx_deregister_global_mgmt_pool(struct ol_txrx_pdev_t *pdev)
+{
+}
+#endif
+
+bool
+ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *vdev)
+{
+	struct ol_tx_flow_pool_t *pool;
+	bool enough_desc_flag;
+
+	if (!vdev)
+		return false;
+
+	pool = vdev->pool;
+
+	if (!pool)
+		return false;
+
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	enough_desc_flag = (pool->avail_desc < (pool->stop_th +
+				OL_TX_NON_FWD_RESERVE))
+		? false : true;
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+	return enough_desc_flag;
+}
+
+/**
+ * ol_txrx_register_pause_cb() - register pause callback
+ * @pause_cb: pause callback
+ *
+ * Return: QDF status
+ */
+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);
+
+	if (!pdev || !pause_cb) {
+		ol_txrx_err("pdev or pause_cb is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	pdev->pause_cb = pause_cb;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_tx_set_desc_global_pool_size() - set global pool size
+ * @num_msdu_desc: total number of descriptors
+ *
+ * Return: none
+ */
+void ol_tx_set_desc_global_pool_size(uint32_t num_msdu_desc)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		qdf_print("%s: pdev is NULL\n", __func__);
+		return;
+	}
+	pdev->num_msdu_desc = num_msdu_desc;
+	if (!ol_tx_get_is_mgmt_over_wmi_enabled())
+		pdev->num_msdu_desc += TX_FLOW_MGMT_POOL_SIZE;
+	ol_txrx_info_high("Global pool size: %d\n", pdev->num_msdu_desc);
+}
+
+/**
+ * ol_tx_get_total_free_desc() - get total free descriptors
+ * @pdev: pdev handle
+ *
+ * Return: total free descriptors
+ */
+uint32_t ol_tx_get_total_free_desc(struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_tx_flow_pool_t *pool = NULL;
+	uint32_t free_desc;
+
+	free_desc = pdev->tx_desc.num_free;
+	qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	TAILQ_FOREACH(pool, &pdev->tx_desc.flow_pool_list,
+		      flow_pool_list_elem) {
+		qdf_spin_lock_bh(&pool->flow_pool_lock);
+		free_desc += pool->avail_desc;
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+
+	return free_desc;
+}
+
+/**
+ * ol_tx_register_flow_control() - Register fw based tx flow control
+ * @pdev: pdev handle
+ *
+ * Return: none
+ */
+void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev)
+{
+	qdf_spinlock_create(&pdev->tx_desc.flow_pool_list_lock);
+	TAILQ_INIT(&pdev->tx_desc.flow_pool_list);
+
+	if (!ol_tx_get_is_mgmt_over_wmi_enabled())
+		ol_tx_register_global_mgmt_pool(pdev);
+}
+
+/**
+ * ol_tx_deregister_flow_control() - Deregister fw based tx flow control
+ * @pdev: pdev handle
+ *
+ * Return: none
+ */
+void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev)
+{
+	int i = 0;
+	struct ol_tx_flow_pool_t *pool = NULL;
+
+	if (!ol_tx_get_is_mgmt_over_wmi_enabled())
+		ol_tx_deregister_global_mgmt_pool(pdev);
+
+	qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	while (!TAILQ_EMPTY(&pdev->tx_desc.flow_pool_list)) {
+		pool = TAILQ_FIRST(&pdev->tx_desc.flow_pool_list);
+		if (!pool)
+			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((void *)pdev);
+
+		ol_tx_dec_pool_ref(pool, true);
+		qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	qdf_spinlock_destroy(&pdev->tx_desc.flow_pool_list_lock);
+}
+
+/**
+ * ol_tx_delete_flow_pool() - delete flow pool
+ * @pool: flow pool pointer
+ * @force: free pool forcefully
+ *
+ * Delete flow_pool if all tx descriptors are available.
+ * Otherwise put it in FLOW_POOL_INVALID state.
+ * If force is set then pull all available descriptors to
+ * global pool.
+ *
+ * Return: 0 for success or error
+ */
+static int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool, bool force)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	uint16_t i, size;
+	union ol_tx_desc_list_elem_t *temp_list = NULL;
+	struct ol_tx_desc_t *tx_desc = NULL;
+
+	if (!pool) {
+		ol_txrx_err(
+		   "%s: pool is NULL\n", __func__);
+		QDF_ASSERT(0);
+		return -ENOMEM;
+	}
+	if (!pdev) {
+		ol_txrx_err(
+		   "%s: pdev is NULL\n", __func__);
+		QDF_ASSERT(0);
+		return -ENOMEM;
+	}
+
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	if (pool->avail_desc == pool->flow_pool_size || force == true)
+		pool->status = FLOW_POOL_INACTIVE;
+	else
+		pool->status = FLOW_POOL_INVALID;
+
+	/* Take all free descriptors and put it in temp_list */
+	temp_list = pool->freelist;
+	size = pool->avail_desc;
+	pool->freelist = NULL;
+	pool->avail_desc = 0;
+
+	if (pool->status == FLOW_POOL_INACTIVE) {
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+		/* Free flow_pool */
+		qdf_spinlock_destroy(&pool->flow_pool_lock);
+		qdf_mem_free(pool);
+	} else { /* FLOW_POOL_INVALID case*/
+		pool->flow_pool_size -= size;
+		pool->flow_pool_id = INVALID_FLOW_ID;
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+		ol_tx_inc_pool_ref(pool);
+
+		pdev->tx_desc.num_invalid_bin++;
+		ol_txrx_info(
+			"%s: invalid pool created %d\n",
+			 __func__, pdev->tx_desc.num_invalid_bin);
+		if (pdev->tx_desc.num_invalid_bin > MAX_INVALID_BIN)
+			ASSERT(0);
+
+		qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+		TAILQ_INSERT_TAIL(&pdev->tx_desc.flow_pool_list, pool,
+				 flow_pool_list_elem);
+		qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	}
+
+	/* put free descriptors to global pool */
+	qdf_spin_lock_bh(&pdev->tx_mutex);
+	for (i = 0; i < size; i++) {
+		tx_desc = &temp_list->tx_desc;
+		temp_list = temp_list->next;
+
+		ol_tx_put_desc_global_pool(pdev, tx_desc);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_mutex);
+
+	ol_tx_distribute_descs_to_deficient_pools_from_global_pool();
+
+	return 0;
+}
+
+QDF_STATUS ol_tx_inc_pool_ref(struct ol_tx_flow_pool_t *pool)
+{
+	if (!pool) {
+		ol_txrx_err("flow pool is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	qdf_atomic_inc(&pool->ref_cnt);
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+	ol_txrx_dbg("pool %pK, ref_cnt %x",
+		    pool, qdf_atomic_read(&pool->ref_cnt));
+
+	return  QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ol_tx_dec_pool_ref(struct ol_tx_flow_pool_t *pool, bool force)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pool) {
+		ol_txrx_err("flow pool is NULL");
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!pdev) {
+		ol_txrx_err("pdev is NULL");
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	if (qdf_atomic_dec_and_test(&pool->ref_cnt)) {
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+		TAILQ_REMOVE(&pdev->tx_desc.flow_pool_list, pool,
+			     flow_pool_list_elem);
+		qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+		ol_txrx_dbg("Deleting pool %pK", pool);
+		ol_tx_delete_flow_pool(pool, force);
+	} else {
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+		qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+		ol_txrx_dbg("pool %pK, ref_cnt %x",
+			    pool, qdf_atomic_read(&pool->ref_cnt));
+	}
+
+	return  QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_tx_flow_pool_status_to_str() - convert flow pool status to string
+ * @status - flow pool status
+ *
+ * Returns: String corresponding to flow pool status
+ */
+static const char *ol_tx_flow_pool_status_to_str
+					(enum flow_pool_status status)
+{
+	switch (status) {
+	CASE_RETURN_STRING(FLOW_POOL_ACTIVE_UNPAUSED);
+	CASE_RETURN_STRING(FLOW_POOL_ACTIVE_PAUSED);
+	CASE_RETURN_STRING(FLOW_POOL_NON_PRIO_PAUSED);
+	CASE_RETURN_STRING(FLOW_POOL_INVALID);
+	CASE_RETURN_STRING(FLOW_POOL_INACTIVE);
+	default:
+		return "unknown";
+	}
+}
+
+/**
+ * ol_tx_dump_flow_pool_info() - dump global_pool and flow_pool info
+ * @ctx: cdp_soc context, required only in lithium_dp flow control.
+ *	 Remove void * while cleaning up cds_get_context.
+ *
+ * Return: none
+ */
+void ol_tx_dump_flow_pool_info(void *ctx)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	struct ol_tx_flow_pool_t *pool = NULL, *pool_prev = NULL;
+	struct ol_tx_flow_pool_t tmp_pool;
+
+
+	if (!pdev) {
+		ol_txrx_err("ERROR: pdev NULL");
+		QDF_ASSERT(0); /* traceback */
+		return;
+	}
+
+	txrx_nofl_info("Global total %d :: avail %d invalid flow_pool %d ",
+		       pdev->tx_desc.pool_size,
+		       pdev->tx_desc.num_free,
+		       pdev->tx_desc.num_invalid_bin);
+
+	txrx_nofl_info("maps %d pool unmaps %d pool resize %d pkt drops %d",
+		       pdev->pool_stats.pool_map_count,
+		       pdev->pool_stats.pool_unmap_count,
+		       pdev->pool_stats.pool_resize_count,
+		       pdev->pool_stats.pkt_drop_no_pool);
+	/*
+	 * Nested spin lock.
+	 * Always take in below order.
+	 * flow_pool_list_lock -> flow_pool_lock
+	 */
+	qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	TAILQ_FOREACH(pool, &pdev->tx_desc.flow_pool_list,
+					 flow_pool_list_elem) {
+		ol_tx_inc_pool_ref(pool);
+		qdf_spin_lock_bh(&pool->flow_pool_lock);
+		qdf_mem_copy(&tmp_pool, pool, sizeof(tmp_pool));
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+		qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+
+		if (pool_prev)
+			ol_tx_dec_pool_ref(pool_prev, false);
+
+		txrx_nofl_info("flow_pool_id %d ::", tmp_pool.flow_pool_id);
+		txrx_nofl_info("status %s flow_id %d flow_type %d",
+			       ol_tx_flow_pool_status_to_str
+					(tmp_pool.status),
+			       tmp_pool.member_flow_id, tmp_pool.flow_type);
+		txrx_nofl_info("total %d :: available %d :: deficient %d :: overflow %d :: pkt dropped (no desc) %d",
+			       tmp_pool.flow_pool_size, tmp_pool.avail_desc,
+			       tmp_pool.deficient_desc,
+			       tmp_pool.overflow_desc,
+			       tmp_pool.pkt_drop_no_desc);
+		txrx_nofl_info("thresh: start %d stop %d prio start %d prio stop %d",
+			       tmp_pool.start_th, tmp_pool.stop_th,
+			       tmp_pool.start_priority_th,
+			       tmp_pool.stop_priority_th);
+		pool_prev = pool;
+		qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+
+	/* decrement ref count for last pool in list */
+	if (pool_prev)
+		ol_tx_dec_pool_ref(pool_prev, false);
+
+}
+
+/**
+ * ol_tx_clear_flow_pool_stats() - clear flow pool statistics
+ *
+ * Return: none
+ */
+void ol_tx_clear_flow_pool_stats(void)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		ol_txrx_err("%s: pdev is null\n",
+						 __func__);
+		return;
+	}
+	qdf_mem_zero(&pdev->pool_stats, sizeof(pdev->pool_stats));
+}
+
+/**
+ * ol_tx_move_desc_n() - Move n descriptors from src_pool to dst_pool.
+ * @src_pool: source pool
+ * @dst_pool: destination pool
+ * @desc_move_count: descriptor move count
+ *
+ * Return: actual descriptors moved
+ */
+static int ol_tx_move_desc_n(struct ol_tx_flow_pool_t *src_pool,
+		      struct ol_tx_flow_pool_t *dst_pool,
+		      int desc_move_count)
+{
+	uint16_t count = 0, i;
+	struct ol_tx_desc_t *tx_desc;
+	union ol_tx_desc_list_elem_t *temp_list = NULL;
+
+	/* Take descriptors from source pool and put it in temp_list */
+	qdf_spin_lock_bh(&src_pool->flow_pool_lock);
+	for (i = 0; i < desc_move_count; i++) {
+		tx_desc = ol_tx_get_desc_flow_pool(src_pool);
+		((union ol_tx_desc_list_elem_t *)tx_desc)->next = temp_list;
+		temp_list = (union ol_tx_desc_list_elem_t *)tx_desc;
+
+	}
+	qdf_spin_unlock_bh(&src_pool->flow_pool_lock);
+
+	/* Take descriptors from temp_list and put it in destination pool */
+	qdf_spin_lock_bh(&dst_pool->flow_pool_lock);
+	for (i = 0; i < desc_move_count; i++) {
+		if (dst_pool->deficient_desc)
+			dst_pool->deficient_desc--;
+		else
+			break;
+		tx_desc = &temp_list->tx_desc;
+		temp_list = temp_list->next;
+		ol_tx_put_desc_flow_pool(dst_pool, tx_desc);
+		count++;
+	}
+	qdf_spin_unlock_bh(&dst_pool->flow_pool_lock);
+
+	/* If anything is there in temp_list put it back to source pool */
+	qdf_spin_lock_bh(&src_pool->flow_pool_lock);
+	while (temp_list) {
+		tx_desc = &temp_list->tx_desc;
+		temp_list = temp_list->next;
+		ol_tx_put_desc_flow_pool(src_pool, tx_desc);
+	}
+	qdf_spin_unlock_bh(&src_pool->flow_pool_lock);
+
+	return count;
+}
+
+
+/**
+ * ol_tx_distribute_descs_to_deficient_pools() - Distribute descriptors
+ * @src_pool: source pool
+ *
+ * Distribute all descriptors of source pool to all
+ * deficient pools as per flow_pool_list.
+ *
+ * Return: 0 for success
+ */
+static int
+ol_tx_distribute_descs_to_deficient_pools(struct ol_tx_flow_pool_t *src_pool)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	struct ol_tx_flow_pool_t *dst_pool = NULL;
+	uint16_t desc_count = src_pool->avail_desc;
+	uint16_t desc_move_count = 0;
+
+	if (!pdev) {
+		ol_txrx_err(
+		   "%s: pdev is NULL\n", __func__);
+		return -EINVAL;
+	}
+	qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	TAILQ_FOREACH(dst_pool, &pdev->tx_desc.flow_pool_list,
+					 flow_pool_list_elem) {
+		qdf_spin_lock_bh(&dst_pool->flow_pool_lock);
+		if (dst_pool->deficient_desc) {
+			desc_move_count =
+				(dst_pool->deficient_desc > desc_count) ?
+					desc_count : dst_pool->deficient_desc;
+			qdf_spin_unlock_bh(&dst_pool->flow_pool_lock);
+			desc_move_count = ol_tx_move_desc_n(src_pool,
+						dst_pool, desc_move_count);
+			desc_count -= desc_move_count;
+
+			qdf_spin_lock_bh(&dst_pool->flow_pool_lock);
+			if (dst_pool->status == FLOW_POOL_ACTIVE_PAUSED) {
+				if (dst_pool->avail_desc > dst_pool->start_th) {
+					pdev->pause_cb(dst_pool->member_flow_id,
+						      WLAN_WAKE_ALL_NETIF_QUEUE,
+						      WLAN_DATA_FLOW_CONTROL);
+
+					pdev->pause_cb(dst_pool->member_flow_id,
+					      WLAN_NETIF_PRIORITY_QUEUE_ON,
+					      WLAN_DATA_FLOW_CONTROL_PRIORITY);
+
+					dst_pool->status =
+						FLOW_POOL_ACTIVE_UNPAUSED;
+				}
+			}
+		}
+		qdf_spin_unlock_bh(&dst_pool->flow_pool_lock);
+		if (desc_count == 0)
+			break;
+	}
+	qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+
+	return 0;
+}
+
+/**
+ * ol_tx_create_flow_pool() - create flow pool
+ * @flow_pool_id: flow pool id
+ * @flow_pool_size: flow pool size
+ *
+ * Return: flow_pool pointer / NULL for error
+ */
+struct ol_tx_flow_pool_t *ol_tx_create_flow_pool(uint8_t flow_pool_id,
+						 uint16_t flow_pool_size)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	struct ol_tx_flow_pool_t *pool;
+	uint16_t size = 0, i;
+	struct ol_tx_desc_t *tx_desc;
+	union ol_tx_desc_list_elem_t *temp_list = NULL;
+	uint32_t stop_threshold;
+	uint32_t start_threshold;
+
+	if (!pdev) {
+		ol_txrx_err(
+		   "%s: pdev is NULL\n", __func__);
+		return NULL;
+	}
+	stop_threshold = ol_cfg_get_tx_flow_stop_queue_th(pdev->ctrl_pdev);
+	start_threshold = stop_threshold +
+		ol_cfg_get_tx_flow_start_queue_offset(pdev->ctrl_pdev);
+	pool = qdf_mem_malloc(sizeof(*pool));
+	if (!pool) {
+		ol_txrx_err(
+		   "%s: malloc failed\n", __func__);
+		return NULL;
+	}
+	pool->flow_pool_id = flow_pool_id;
+	pool->flow_pool_size = flow_pool_size;
+	pool->status = FLOW_POOL_ACTIVE_UNPAUSED;
+	pool->start_th = (start_threshold * flow_pool_size)/100;
+	pool->stop_th = (stop_threshold * flow_pool_size)/100;
+	pool->stop_priority_th = (TX_PRIORITY_TH * pool->stop_th)/100;
+	if (pool->stop_priority_th >= MAX_TSO_SEGMENT_DESC)
+		pool->stop_priority_th -= MAX_TSO_SEGMENT_DESC;
+
+	pool->start_priority_th = (TX_PRIORITY_TH * pool->start_th)/100;
+	if (pool->start_priority_th >= MAX_TSO_SEGMENT_DESC)
+			pool->start_priority_th -= MAX_TSO_SEGMENT_DESC;
+
+	qdf_spinlock_create(&pool->flow_pool_lock);
+	qdf_atomic_init(&pool->ref_cnt);
+	ol_tx_inc_pool_ref(pool);
+
+	/* Take TX descriptor from global_pool and put it in temp_list*/
+	qdf_spin_lock_bh(&pdev->tx_mutex);
+	if (pdev->tx_desc.num_free >= pool->flow_pool_size)
+		size = pool->flow_pool_size;
+	else
+		size = pdev->tx_desc.num_free;
+
+	for (i = 0; i < size; i++) {
+		tx_desc = ol_tx_get_desc_global_pool(pdev);
+		tx_desc->pool = pool;
+		((union ol_tx_desc_list_elem_t *)tx_desc)->next = temp_list;
+		temp_list = (union ol_tx_desc_list_elem_t *)tx_desc;
+
+	}
+	qdf_spin_unlock_bh(&pdev->tx_mutex);
+
+	/* put temp_list to flow_pool */
+	pool->freelist = temp_list;
+	pool->avail_desc = size;
+	pool->deficient_desc = pool->flow_pool_size - pool->avail_desc;
+	/* used for resize pool*/
+	pool->overflow_desc = 0;
+
+	/* Add flow_pool to flow_pool_list */
+	qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	TAILQ_INSERT_TAIL(&pdev->tx_desc.flow_pool_list, pool,
+			 flow_pool_list_elem);
+	qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+
+	return pool;
+}
+
+/**
+ * ol_tx_free_invalid_flow_pool() - free invalid pool
+ * @pool: pool
+ *
+ * Return: 0 for success or failure
+ */
+int ol_tx_free_invalid_flow_pool(struct ol_tx_flow_pool_t *pool)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if ((!pdev) || (!pool) || (pool->status != FLOW_POOL_INVALID)) {
+		ol_txrx_err(
+		   "%s: Invalid pool/pdev\n", __func__);
+		return -EINVAL;
+	}
+
+	/* direclty distribute to other deficient pools */
+	ol_tx_distribute_descs_to_deficient_pools(pool);
+
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	pool->flow_pool_size = pool->avail_desc;
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+
+	pdev->tx_desc.num_invalid_bin--;
+	ol_txrx_info(
+		"%s: invalid pool deleted %d\n",
+		 __func__, pdev->tx_desc.num_invalid_bin);
+
+	return ol_tx_dec_pool_ref(pool, false);
+}
+
+/**
+ * ol_tx_get_flow_pool() - get flow_pool from flow_pool_id
+ * @flow_pool_id: flow pool id
+ *
+ * Return: flow_pool ptr / NULL if not found
+ */
+static struct ol_tx_flow_pool_t *ol_tx_get_flow_pool(uint8_t flow_pool_id)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	struct ol_tx_flow_pool_t *pool = NULL;
+	bool is_found = false;
+
+	if (!pdev) {
+		ol_txrx_err("ERROR: pdev NULL");
+		QDF_ASSERT(0); /* traceback */
+		return NULL;
+	}
+
+	qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	TAILQ_FOREACH(pool, &pdev->tx_desc.flow_pool_list,
+					 flow_pool_list_elem) {
+		qdf_spin_lock_bh(&pool->flow_pool_lock);
+		if (pool->flow_pool_id == flow_pool_id) {
+			qdf_spin_unlock_bh(&pool->flow_pool_lock);
+			is_found = true;
+			break;
+		}
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+
+	if (is_found == false)
+		pool = NULL;
+
+	return pool;
+}
+
+/**
+ * ol_tx_flow_pool_vdev_map() - Map flow_pool with vdev
+ * @pool: flow_pool
+ * @vdev_id: flow_id /vdev_id
+ *
+ * Return: none
+ */
+static void ol_tx_flow_pool_vdev_map(struct ol_tx_flow_pool_t *pool,
+				     uint8_t vdev_id)
+{
+	struct ol_txrx_vdev_t *vdev;
+
+	vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
+	if (!vdev) {
+		ol_txrx_err(
+		   "%s: invalid vdev_id %d\n",
+		   __func__, vdev_id);
+		return;
+	}
+
+	vdev->pool = pool;
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	pool->member_flow_id = vdev_id;
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+}
+
+/**
+ * ol_tx_flow_pool_vdev_unmap() - Unmap flow_pool from vdev
+ * @pool: flow_pool
+ * @vdev_id: flow_id /vdev_id
+ *
+ * Return: none
+ */
+static void ol_tx_flow_pool_vdev_unmap(struct ol_tx_flow_pool_t *pool,
+				       uint8_t vdev_id)
+{
+	struct ol_txrx_vdev_t *vdev;
+
+	vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
+	if (!vdev) {
+		ol_txrx_err(
+		   "%s: invalid vdev_id %d\n",
+		   __func__, vdev_id);
+		return;
+	}
+
+	vdev->pool = NULL;
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	pool->member_flow_id = INVALID_FLOW_ID;
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+}
+
+/**
+ * ol_tx_flow_pool_map_handler() - Map flow_id with pool of descriptors
+ * @flow_id: flow id
+ * @flow_type: flow type
+ * @flow_pool_id: pool id
+ * @flow_pool_size: pool size
+ *
+ * Process below target to host message
+ * HTT_T2H_MSG_TYPE_FLOW_POOL_MAP
+ *
+ * Return: none
+ */
+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)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	struct ol_tx_flow_pool_t *pool;
+	uint8_t pool_create = 0;
+	enum htt_flow_type type = flow_type;
+
+	ol_txrx_dbg(
+		"%s: flow_id %d flow_type %d flow_pool_id %d flow_pool_size %d\n",
+		__func__, flow_id, flow_type, flow_pool_id, flow_pool_size);
+
+	if (qdf_unlikely(!pdev)) {
+		ol_txrx_err(
+			"%s: pdev is NULL", __func__);
+		return;
+	}
+	pdev->pool_stats.pool_map_count++;
+
+	pool = ol_tx_get_flow_pool(flow_pool_id);
+	if (!pool) {
+		pool = ol_tx_create_flow_pool(flow_pool_id, flow_pool_size);
+		if (pool == NULL) {
+			ol_txrx_err(
+				   "%s: creation of flow_pool %d size %d failed\n",
+				   __func__, flow_pool_id, flow_pool_size);
+			return;
+		}
+		pool_create = 1;
+	}
+
+	switch (type) {
+
+	case FLOW_TYPE_VDEV:
+		ol_tx_flow_pool_vdev_map(pool, flow_id);
+		pdev->pause_cb(flow_id,
+			       WLAN_WAKE_ALL_NETIF_QUEUE,
+			       WLAN_DATA_FLOW_CONTROL);
+		break;
+	default:
+		if (pool_create)
+			ol_tx_dec_pool_ref(pool, false);
+		ol_txrx_err(
+		   "%s: flow type %d not supported !!!\n",
+		   __func__, type);
+		break;
+	}
+}
+
+/**
+ * ol_tx_flow_pool_unmap_handler() - Unmap flow_id from pool of descriptors
+ * @flow_id: flow id
+ * @flow_type: flow type
+ * @flow_pool_id: pool id
+ *
+ * Process below target to host message
+ * HTT_T2H_MSG_TYPE_FLOW_POOL_UNMAP
+ *
+ * Return: none
+ */
+void ol_tx_flow_pool_unmap_handler(uint8_t flow_id, uint8_t flow_type,
+							  uint8_t flow_pool_id)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	struct ol_tx_flow_pool_t *pool;
+	enum htt_flow_type type = flow_type;
+
+	ol_txrx_dbg(
+		"%s: flow_id %d flow_type %d flow_pool_id %d\n",
+		__func__, flow_id, flow_type, flow_pool_id);
+
+	if (qdf_unlikely(!pdev)) {
+		ol_txrx_err(
+			"%s: pdev is NULL", __func__);
+		return;
+	}
+	pdev->pool_stats.pool_unmap_count++;
+
+	pool = ol_tx_get_flow_pool(flow_pool_id);
+	if (!pool) {
+		ol_txrx_info(
+		   "%s: flow_pool not available flow_pool_id %d\n",
+		   __func__, type);
+		return;
+	}
+
+	switch (type) {
+
+	case FLOW_TYPE_VDEV:
+		ol_tx_flow_pool_vdev_unmap(pool, flow_id);
+		break;
+	default:
+		ol_txrx_info(
+		   "%s: flow type %d not supported !!!\n",
+		   __func__, type);
+		return;
+	}
+
+	/*
+	 * only delete if all descriptors are available
+	 * and pool ref count becomes 0
+	 */
+	ol_tx_dec_pool_ref(pool, false);
+}
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_RESIZE
+/**
+ * ol_tx_distribute_descs_to_deficient_pools_from_global_pool()
+ *
+ * Distribute descriptors of global pool to all
+ * deficient pools as per need.
+ *
+ * Return: 0 for success
+ */
+int ol_tx_distribute_descs_to_deficient_pools_from_global_pool(void)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	struct ol_tx_flow_pool_t *dst_pool = NULL;
+	struct ol_tx_flow_pool_t *tmp_pool = NULL;
+	uint16_t total_desc_req = 0;
+	uint16_t desc_move_count = 0;
+	uint16_t temp_count = 0, i;
+	union ol_tx_desc_list_elem_t *temp_list = NULL;
+	struct ol_tx_desc_t *tx_desc;
+	uint8_t free_invalid_pool = 0;
+
+	if (!pdev) {
+		ol_txrx_err(
+		   "%s: pdev is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Nested locks: maintain flow_pool_list_lock->flow_pool_lock */
+	/* find out total deficient desc required */
+	qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	TAILQ_FOREACH(dst_pool, &pdev->tx_desc.flow_pool_list,
+		      flow_pool_list_elem) {
+		qdf_spin_lock_bh(&dst_pool->flow_pool_lock);
+		total_desc_req += dst_pool->deficient_desc;
+		qdf_spin_unlock_bh(&dst_pool->flow_pool_lock);
+	}
+	qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+
+	qdf_spin_lock_bh(&pdev->tx_mutex);
+	desc_move_count = (pdev->tx_desc.num_free >= total_desc_req) ?
+				 total_desc_req : pdev->tx_desc.num_free;
+
+	for (i = 0; i < desc_move_count; i++) {
+		tx_desc = ol_tx_get_desc_global_pool(pdev);
+		((union ol_tx_desc_list_elem_t *)tx_desc)->next = temp_list;
+		temp_list = (union ol_tx_desc_list_elem_t *)tx_desc;
+	}
+	qdf_spin_unlock_bh(&pdev->tx_mutex);
+
+	if (!desc_move_count)
+		return 0;
+
+	/* destribute desc to deficient pool */
+	qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	TAILQ_FOREACH(dst_pool, &pdev->tx_desc.flow_pool_list,
+		      flow_pool_list_elem) {
+		qdf_spin_lock_bh(&dst_pool->flow_pool_lock);
+		if (dst_pool->deficient_desc) {
+			temp_count =
+				(dst_pool->deficient_desc > desc_move_count) ?
+				desc_move_count : dst_pool->deficient_desc;
+
+			desc_move_count -= temp_count;
+			for (i = 0; i < temp_count; i++) {
+				tx_desc = &temp_list->tx_desc;
+				temp_list = temp_list->next;
+				ol_tx_put_desc_flow_pool(dst_pool, tx_desc);
+			}
+
+			if (dst_pool->status == FLOW_POOL_ACTIVE_PAUSED) {
+				if (dst_pool->avail_desc > dst_pool->start_th) {
+					pdev->pause_cb(dst_pool->member_flow_id,
+						      WLAN_WAKE_ALL_NETIF_QUEUE,
+						      WLAN_DATA_FLOW_CONTROL);
+					dst_pool->status =
+						FLOW_POOL_ACTIVE_UNPAUSED;
+				}
+			} else if ((dst_pool->status == FLOW_POOL_INVALID) &&
+				   (dst_pool->avail_desc ==
+					 dst_pool->flow_pool_size)) {
+				free_invalid_pool = 1;
+				tmp_pool = dst_pool;
+			}
+		}
+		qdf_spin_unlock_bh(&dst_pool->flow_pool_lock);
+		if (desc_move_count == 0)
+			break;
+	}
+	qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+
+	if (free_invalid_pool && tmp_pool)
+		ol_tx_free_invalid_flow_pool(tmp_pool);
+
+	return 0;
+}
+
+/**
+ * ol_tx_flow_pool_update_queue_state() - update network queue for pool based on
+ *                                        new available count.
+ * @pool : pool handle
+ *
+ * Return : none
+ */
+static void ol_tx_flow_pool_update_queue_state(struct ol_txrx_pdev_t *pdev,
+					       struct ol_tx_flow_pool_t *pool)
+{
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	if (pool->avail_desc > pool->start_th) {
+		pool->status = FLOW_POOL_ACTIVE_UNPAUSED;
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+		pdev->pause_cb(pool->member_flow_id,
+			       WLAN_WAKE_ALL_NETIF_QUEUE,
+			       WLAN_DATA_FLOW_CONTROL);
+	} else if (pool->avail_desc < pool->stop_th &&
+		   pool->avail_desc >= pool->stop_priority_th) {
+		pool->status = FLOW_POOL_NON_PRIO_PAUSED;
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+		pdev->pause_cb(pool->member_flow_id,
+			       WLAN_STOP_NON_PRIORITY_QUEUE,
+			       WLAN_DATA_FLOW_CONTROL);
+		pdev->pause_cb(pool->member_flow_id,
+			       WLAN_NETIF_PRIORITY_QUEUE_ON,
+			       WLAN_DATA_FLOW_CONTROL);
+	} else if (pool->avail_desc < pool->stop_priority_th) {
+		pool->status = FLOW_POOL_ACTIVE_PAUSED;
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+		pdev->pause_cb(pool->member_flow_id,
+			       WLAN_STOP_ALL_NETIF_QUEUE,
+			       WLAN_DATA_FLOW_CONTROL);
+	} else {
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+	}
+}
+
+/**
+ * ol_tx_flow_pool_update() - update pool parameters with new size
+ * @pool : pool handle
+ * @new_pool_size : new pool size
+ * @deficient_count : deficient count
+ * @overflow_count : overflow count
+ *
+ * Return : none
+ */
+static void ol_tx_flow_pool_update(struct ol_tx_flow_pool_t *pool,
+				   uint16_t new_pool_size,
+				   uint16_t deficient_count,
+				   uint16_t overflow_count)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	uint32_t stop_threshold =
+			 ol_cfg_get_tx_flow_stop_queue_th(pdev->ctrl_pdev);
+	uint32_t start_threshold = stop_threshold +
+			ol_cfg_get_tx_flow_start_queue_offset(pdev->ctrl_pdev);
+
+	pool->flow_pool_size = new_pool_size;
+	pool->start_th = (start_threshold * new_pool_size) / 100;
+	pool->stop_th = (stop_threshold * new_pool_size) / 100;
+	pool->stop_priority_th = (TX_PRIORITY_TH * pool->stop_th) / 100;
+	if (pool->stop_priority_th >= MAX_TSO_SEGMENT_DESC)
+		pool->stop_priority_th -= MAX_TSO_SEGMENT_DESC;
+
+	pool->start_priority_th = (TX_PRIORITY_TH * pool->start_th) / 100;
+	if (pool->start_priority_th >= MAX_TSO_SEGMENT_DESC)
+		pool->start_priority_th -= MAX_TSO_SEGMENT_DESC;
+
+	if (deficient_count)
+		pool->deficient_desc = deficient_count;
+
+	if (overflow_count)
+		pool->overflow_desc = overflow_count;
+}
+
+/**
+ * ol_tx_flow_pool_resize() - resize pool with new size
+ * @pool: pool pointer
+ * @new_pool_size: new pool size
+ *
+ * Return: none
+ */
+static void ol_tx_flow_pool_resize(struct ol_tx_flow_pool_t *pool,
+				   uint16_t new_pool_size)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	uint16_t diff = 0, overflow_count = 0, deficient_count = 0;
+	uint16_t move_desc_to_global = 0, move_desc_from_global = 0;
+	union ol_tx_desc_list_elem_t *temp_list = NULL;
+	int i = 0, update_done = 0;
+	struct ol_tx_desc_t *tx_desc = NULL;
+	uint16_t temp = 0;
+
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	if (pool->flow_pool_size == new_pool_size) {
+		qdf_spin_unlock_bh(&pool->flow_pool_lock);
+		ol_txrx_info("pool resize received with same size");
+		return;
+	}
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+
+	/* Reduce pool size */
+	/* start_priority_th desc should available after reduction */
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	if (pool->flow_pool_size > new_pool_size) {
+		diff = pool->flow_pool_size - new_pool_size;
+		diff += pool->overflow_desc;
+		pool->overflow_desc = 0;
+		temp = QDF_MIN(pool->deficient_desc, diff);
+		pool->deficient_desc -= temp;
+		diff -= temp;
+
+		if (diff) {
+			/* Have enough descriptors */
+			if (pool->avail_desc >=
+				 (diff + pool->start_priority_th)) {
+				move_desc_to_global = diff;
+			}
+			/* Do not have enough descriptors */
+			else if (pool->avail_desc > pool->start_priority_th) {
+				move_desc_to_global = pool->avail_desc -
+						 pool->start_priority_th;
+				overflow_count = diff - move_desc_to_global;
+			}
+
+			/* Move desc to temp_list */
+			for (i = 0; i < move_desc_to_global; i++) {
+				tx_desc = ol_tx_get_desc_flow_pool(pool);
+				((union ol_tx_desc_list_elem_t *)tx_desc)->next
+								 = temp_list;
+				temp_list =
+				  (union ol_tx_desc_list_elem_t *)tx_desc;
+			}
+		}
+
+		/* update pool size and threshold */
+		ol_tx_flow_pool_update(pool, new_pool_size, 0, overflow_count);
+		update_done = 1;
+	}
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+
+	if (move_desc_to_global && temp_list) {
+		/* put free descriptors to global pool */
+		qdf_spin_lock_bh(&pdev->tx_mutex);
+		for (i = 0; i < move_desc_to_global; i++) {
+			tx_desc = &temp_list->tx_desc;
+			temp_list = temp_list->next;
+			ol_tx_put_desc_global_pool(pdev, tx_desc);
+		}
+		qdf_spin_unlock_bh(&pdev->tx_mutex);
+	}
+
+	if (update_done)
+		goto update_done;
+
+	/* Increase pool size */
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	if (pool->flow_pool_size < new_pool_size) {
+		diff = new_pool_size - pool->flow_pool_size;
+		diff += pool->deficient_desc;
+		pool->deficient_desc = 0;
+		temp = QDF_MIN(pool->overflow_desc, diff);
+		pool->overflow_desc -= temp;
+		diff -= temp;
+	}
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+
+	if (diff) {
+		/* take descriptors from global pool */
+		qdf_spin_lock_bh(&pdev->tx_mutex);
+
+		if (pdev->tx_desc.num_free >= diff) {
+			move_desc_from_global = diff;
+		} else {
+			move_desc_from_global = pdev->tx_desc.num_free;
+			deficient_count = diff - move_desc_from_global;
+		}
+
+		for (i = 0; i < move_desc_from_global; i++) {
+			tx_desc = ol_tx_get_desc_global_pool(pdev);
+			((union ol_tx_desc_list_elem_t *)tx_desc)->next =
+								 temp_list;
+			temp_list = (union ol_tx_desc_list_elem_t *)tx_desc;
+		}
+		qdf_spin_unlock_bh(&pdev->tx_mutex);
+	}
+	/* update desc to pool */
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+	if (move_desc_from_global && temp_list) {
+		for (i = 0; i < move_desc_from_global; i++) {
+			tx_desc = &temp_list->tx_desc;
+			temp_list = temp_list->next;
+			ol_tx_put_desc_flow_pool(pool, tx_desc);
+		}
+	}
+	/* update pool size and threshold */
+	ol_tx_flow_pool_update(pool, new_pool_size, deficient_count, 0);
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+
+update_done:
+
+	ol_tx_flow_pool_update_queue_state(pdev, pool);
+}
+
+/**
+ * ol_tx_flow_pool_resize_handler() - Resize pool with new size
+ * @flow_pool_id: pool id
+ * @flow_pool_size: pool size
+ *
+ * Process below target to host message
+ * HTT_T2H_MSG_TYPE_FLOW_POOL_RESIZE
+ *
+ * Return: none
+ */
+void ol_tx_flow_pool_resize_handler(uint8_t flow_pool_id,
+				    uint16_t flow_pool_size)
+{
+	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	struct ol_tx_flow_pool_t *pool;
+
+	ol_txrx_dbg("%s: flow_pool_id %d flow_pool_size %d\n",
+		    __func__, flow_pool_id, flow_pool_size);
+
+	if (qdf_unlikely(!pdev)) {
+		ol_txrx_err(
+			"%s: pdev is NULL", __func__);
+		return;
+	}
+	pdev->pool_stats.pool_resize_count++;
+
+	pool = ol_tx_get_flow_pool(flow_pool_id);
+	if (!pool) {
+		ol_txrx_err("%s: resize for flow_pool %d size %d failed\n",
+			    __func__, flow_pool_id, flow_pool_size);
+		return;
+	}
+
+	ol_tx_inc_pool_ref(pool);
+	ol_tx_flow_pool_resize(pool, flow_pool_size);
+	ol_tx_dec_pool_ref(pool, false);
+}
+#endif
+
+/**
+ * ol_txrx_map_to_netif_reason_type() - map to netif_reason_type
+ * @reason: network queue pause reason
+ *
+ * Return: netif_reason_type
+ */
+static enum netif_reason_type
+ol_txrx_map_to_netif_reason_type(uint32_t reason)
+{
+	switch (reason) {
+	case OL_TXQ_PAUSE_REASON_FW:
+		return WLAN_FW_PAUSE;
+	case OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED:
+		return WLAN_PEER_UNAUTHORISED;
+	case OL_TXQ_PAUSE_REASON_TX_ABORT:
+		return WLAN_TX_ABORT;
+	case OL_TXQ_PAUSE_REASON_VDEV_STOP:
+		return WLAN_VDEV_STOP;
+	case OL_TXQ_PAUSE_REASON_THERMAL_MITIGATION:
+		return WLAN_THERMAL_MITIGATION;
+	default:
+		ol_txrx_err(
+			   "%s: reason not supported %d\n",
+			   __func__, reason);
+		return WLAN_REASON_TYPE_MAX;
+	}
+}
+
+/*
+ * ol_txrx_vdev_pause() - pause vdev network queues
+ * @vdev: vdev handle
+ * @reason: network queue pause reason
+ *
+ * Return: none
+ */
+void ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	enum netif_reason_type netif_reason;
+
+	if (qdf_unlikely((!pdev) || (!pdev->pause_cb))) {
+		ol_txrx_err("%s: invalid pdev\n", __func__);
+		return;
+	}
+
+	netif_reason = ol_txrx_map_to_netif_reason_type(reason);
+	if (netif_reason == WLAN_REASON_TYPE_MAX)
+		return;
+
+	pdev->pause_cb(vdev->vdev_id, WLAN_STOP_ALL_NETIF_QUEUE, netif_reason);
+}
+
+/**
+ * ol_txrx_vdev_unpause() - unpause vdev network queues
+ * @vdev: vdev handle
+ * @reason: network queue pause reason
+ *
+ * Return: none
+ */
+void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+	enum netif_reason_type netif_reason;
+
+	if (qdf_unlikely((!pdev) || (!pdev->pause_cb))) {
+		ol_txrx_err("%s: invalid pdev\n", __func__);
+		return;
+	}
+
+	netif_reason = ol_txrx_map_to_netif_reason_type(reason);
+	if (netif_reason == WLAN_REASON_TYPE_MAX)
+		return;
+
+	pdev->pause_cb(vdev->vdev_id, WLAN_WAKE_ALL_NETIF_QUEUE,
+			netif_reason);
+}
+
+/**
+ * ol_txrx_pdev_pause() - pause network queues for each vdev
+ * @pdev: pdev handle
+ * @reason: network queue pause reason
+ *
+ * Return: none
+ */
+void ol_txrx_pdev_pause(struct ol_txrx_pdev_t *pdev, uint32_t reason)
+{
+	struct ol_txrx_vdev_t *vdev = NULL, *tmp;
+
+	TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) {
+		ol_txrx_vdev_pause((struct cdp_vdev *)vdev, reason);
+	}
+}
+
+/**
+ * ol_txrx_pdev_unpause() - unpause network queues for each vdev
+ * @pdev: pdev handle
+ * @reason: network queue pause reason
+ *
+ * Return: none
+ */
+void ol_txrx_pdev_unpause(struct ol_txrx_pdev_t *pdev, uint32_t reason)
+{
+	struct ol_txrx_vdev_t *vdev = NULL, *tmp;
+
+	TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) {
+		ol_txrx_vdev_unpause((struct cdp_vdev *)vdev, reason);
+	}
+}
diff --git a/core/dp/txrx/ol_txrx_internal.h b/core/dp/txrx/ol_txrx_internal.h
new file mode 100644
index 0000000..33add1d
--- /dev/null
+++ b/core/dp/txrx/ol_txrx_internal.h
@@ -0,0 +1,812 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#ifndef _OL_TXRX_INTERNAL__H_
+#define _OL_TXRX_INTERNAL__H_
+
+#include <qdf_util.h>               /* qdf_assert */
+#include <qdf_nbuf.h>               /* qdf_nbuf_t */
+#include <qdf_mem.h>             /* qdf_mem_set */
+#include <cds_ieee80211_common.h>   /* ieee80211_frame */
+#include <ol_htt_rx_api.h>          /* htt_rx_msdu_desc_completes_mpdu, etc. */
+
+#include <ol_txrx_types.h>
+
+#include <ol_txrx_dbg.h>
+#include <enet.h>               /* ETHERNET_HDR_LEN, etc. */
+#include <ipv4.h>               /* IPV4_HDR_LEN, etc. */
+#include <ip_prot.h>            /* IP_PROTOCOL_TCP, etc. */
+
+#ifdef ATH_11AC_TXCOMPACT
+#define OL_TX_DESC_NO_REFS(tx_desc) 1
+#define OL_TX_DESC_REF_INIT(tx_desc)    /* no-op */
+#define OL_TX_DESC_REF_INC(tx_desc)     /* no-op */
+#else
+#define OL_TX_DESC_NO_REFS(tx_desc) \
+	qdf_atomic_dec_and_test(&tx_desc->ref_cnt)
+#define OL_TX_DESC_REF_INIT(tx_desc) qdf_atomic_init(&tx_desc->ref_cnt)
+#define OL_TX_DESC_REF_INC(tx_desc) qdf_atomic_inc(&tx_desc->ref_cnt)
+#endif
+
+#ifndef TXRX_ASSERT_LEVEL
+#define TXRX_ASSERT_LEVEL 3
+#endif
+
+#ifdef __KLOCWORK__
+#define TXRX_ASSERT1(x) do { if (!(x)) abort(); } while (0)
+#define TXRX_ASSERT2(x) do { if (!(x)) abort(); } while (0)
+#else                           /* #ifdef __KLOCWORK__ */
+
+#if TXRX_ASSERT_LEVEL > 0
+#define TXRX_ASSERT1(condition) qdf_assert((condition))
+#else
+#define TXRX_ASSERT1(condition)
+#endif
+
+#if TXRX_ASSERT_LEVEL > 1
+#define TXRX_ASSERT2(condition) qdf_assert((condition))
+#else
+#define TXRX_ASSERT2(condition)
+#endif
+#endif /* #ifdef __KLOCWORK__ */
+
+#ifdef TXRX_PRINT_ENABLE
+
+#include <stdarg.h>             /* va_list */
+#include <qdf_types.h>          /* qdf_vprint */
+
+#define ol_txrx_alert(params...) \
+	QDF_TRACE_FATAL(QDF_MODULE_ID_TXRX, params)
+#define ol_txrx_err(params...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_TXRX, params)
+#define ol_txrx_warn(params...) \
+	QDF_TRACE_WARN(QDF_MODULE_ID_TXRX, params)
+#define ol_txrx_info(params...) \
+	QDF_TRACE_INFO(QDF_MODULE_ID_TXRX, params)
+#define ol_txrx_info_high(params...) \
+	QDF_TRACE_INFO(QDF_MODULE_ID_TXRX, params)
+#define ol_txrx_dbg(params...) \
+	QDF_TRACE_DEBUG(QDF_MODULE_ID_TXRX, params)
+
+#define txrx_nofl_alert(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_TXRX, params)
+#define txrx_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_TXRX, params)
+#define txrx_nofl_warn(params...) \
+	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_TXRX, params)
+#define txrx_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_TXRX, params)
+#define txrx_nofl_dbg(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_TXRX, params)
+
+/*
+ * define PN check failure message print rate
+ * as 1 second
+ */
+#define TXRX_PN_CHECK_FAILURE_PRINT_PERIOD_MS  1000
+
+#else
+
+#define ol_txrx_alert(format, args...)
+#define ol_txrx_err(format, args...)
+#define ol_txrx_warn(format, args...)
+#define ol_txrx_info(format, args...)
+#define ol_txrx_info_high(format, args...)
+#define ol_txrx_dbg(format, args...)
+
+#define txrx_nofl_alert(params...)
+#define txrx_nofl_err(params...)
+#define txrx_nofl_warn(params...)
+#define txrx_nofl_info(params...)
+#define txrx_nofl_dbg(params...)
+
+#endif /* TXRX_PRINT_ENABLE */
+
+/*--- tx credit debug printouts ---*/
+
+#ifndef DEBUG_CREDIT
+#define DEBUG_CREDIT 0
+#endif
+
+#if DEBUG_CREDIT
+#define TX_CREDIT_DEBUG_PRINT(fmt, ...) qdf_print(fmt, ## __VA_ARGS__)
+#else
+#define TX_CREDIT_DEBUG_PRINT(fmt, ...)
+#endif
+
+/*--- tx scheduler debug printouts ---*/
+
+#ifdef HOST_TX_SCHED_DEBUG
+#define TX_SCHED_DEBUG_PRINT(fmt, ...) qdf_print(fmt, ## __VA_ARGS__)
+#else
+#define TX_SCHED_DEBUG_PRINT(fmt, ...)
+#endif
+#define TX_SCHED_DEBUG_PRINT_ALWAYS(fmt, ...) qdf_print(fmt, ## __VA_ARGS__)
+
+#define OL_TXRX_LIST_APPEND(head, tail, elem) \
+	do {						\
+		if (!(head)) {				    \
+			(head) = (elem);			\
+		} else {				    \
+			qdf_nbuf_set_next((tail), (elem));	\
+		}					    \
+		(tail) = (elem);			    \
+	} while (0)
+
+static inline void
+ol_rx_mpdu_list_next(struct ol_txrx_pdev_t *pdev,
+		     void *mpdu_list,
+		     qdf_nbuf_t *mpdu_tail, qdf_nbuf_t *next_mpdu)
+{
+	htt_pdev_handle htt_pdev = pdev->htt_pdev;
+	qdf_nbuf_t msdu;
+
+	/*
+	 * For now, we use a simply flat list of MSDUs.
+	 * So, traverse the list until we reach the last MSDU within the MPDU.
+	 */
+	TXRX_ASSERT2(mpdu_list);
+	msdu = mpdu_list;
+	while (!htt_rx_msdu_desc_completes_mpdu
+		       (htt_pdev, htt_rx_msdu_desc_retrieve(htt_pdev, msdu))) {
+		msdu = qdf_nbuf_next(msdu);
+		TXRX_ASSERT2(msdu);
+	}
+	/* msdu now points to the last MSDU within the first MPDU */
+	*mpdu_tail = msdu;
+	*next_mpdu = qdf_nbuf_next(msdu);
+}
+
+/*--- txrx stats macros ---*/
+
+/* unconditional defs */
+#define TXRX_STATS_INCR(pdev, field) TXRX_STATS_ADD(pdev, field, 1)
+
+/* default conditional defs (may be undefed below) */
+
+#define TXRX_STATS_INIT(_pdev) \
+	qdf_mem_set(&((_pdev)->stats), sizeof((_pdev)->stats), 0x0)
+#define TXRX_STATS_ADD(_pdev, _field, _delta) {		\
+		_pdev->stats._field += _delta; }
+#define TXRX_STATS_MSDU_INCR(pdev, field, netbuf) \
+	do { \
+		TXRX_STATS_INCR((pdev), pub.field.pkts); \
+		TXRX_STATS_ADD((pdev), pub.field.bytes, qdf_nbuf_len(netbuf)); \
+	} while (0)
+
+/* conditional defs based on verbosity level */
+
+
+#define TXRX_STATS_MSDU_LIST_INCR(pdev, field, netbuf_list) \
+	do { \
+		qdf_nbuf_t tmp_list = netbuf_list; \
+		while (tmp_list) { \
+			TXRX_STATS_MSDU_INCR(pdev, field, tmp_list); \
+			tmp_list = qdf_nbuf_next(tmp_list); \
+		} \
+	} while (0)
+
+#define TXRX_STATS_MSDU_INCR_TX_STATUS(status, pdev, netbuf) do {	\
+		if (status == htt_tx_status_ok)				\
+			TXRX_STATS_MSDU_INCR(pdev, tx.delivered, netbuf); \
+		else if (status == htt_tx_status_discard)		\
+			TXRX_STATS_MSDU_INCR(pdev, tx.dropped.target_discard, \
+					     netbuf);			\
+		else if (status == htt_tx_status_no_ack)		\
+			TXRX_STATS_MSDU_INCR(pdev, tx.dropped.no_ack, netbuf); \
+		else if (status == htt_tx_status_download_fail)		\
+			TXRX_STATS_MSDU_INCR(pdev, tx.dropped.download_fail, \
+					     netbuf);			\
+		else							\
+			/* NO-OP */;					\
+	} while (0)
+
+#define TXRX_STATS_UPDATE_TX_COMP_HISTOGRAM(_pdev, _p_cntrs)                   \
+	do {                                                                   \
+		if (_p_cntrs == 1) {                                           \
+			TXRX_STATS_ADD(_pdev, pub.tx.comp_histogram.pkts_1, 1);\
+		} else if (_p_cntrs > 2 && _p_cntrs <= 10) {                   \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.comp_histogram.pkts_2_10, 1);          \
+		} else if (_p_cntrs > 10 && _p_cntrs <= 20) {                  \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.comp_histogram.pkts_11_20, 1);         \
+		} else if (_p_cntrs > 20 && _p_cntrs <= 30) {                  \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.comp_histogram.pkts_21_30, 1);         \
+		} else if (_p_cntrs > 30 && _p_cntrs <= 40) {                  \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.comp_histogram.pkts_31_40, 1);         \
+		} else if (_p_cntrs > 40 && _p_cntrs <= 50) {                  \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.comp_histogram.pkts_41_50, 1);         \
+		} else if (_p_cntrs > 50 && _p_cntrs <= 60) {                  \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.comp_histogram.pkts_51_60, 1);         \
+		} else {                                                       \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.comp_histogram.pkts_61_plus, 1);       \
+		}                                                              \
+	} while (0)
+
+#define TXRX_STATS_UPDATE_TX_STATS(_pdev, _status, _p_cntrs, _b_cntrs)         \
+	do {                                                                   \
+		switch (status) {                                              \
+		case htt_tx_status_ok:                                         \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.delivered.pkts, _p_cntrs);             \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.delivered.bytes, _b_cntrs);            \
+			break;                                                 \
+		case htt_tx_status_discard:                                    \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.dropped.target_discard.pkts, _p_cntrs);\
+			TXRX_STATS_ADD(_pdev,				       \
+				pub.tx.dropped.target_discard.bytes, _b_cntrs);\
+			break;                                                 \
+		case htt_tx_status_no_ack:                                     \
+			TXRX_STATS_ADD(_pdev, pub.tx.dropped.no_ack.pkts,      \
+				 _p_cntrs);				       \
+			TXRX_STATS_ADD(_pdev, pub.tx.dropped.no_ack.bytes,     \
+				 _b_cntrs);				       \
+			break;                                                 \
+		case htt_tx_status_download_fail:                              \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.dropped.download_fail.pkts, _p_cntrs); \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.dropped.download_fail.bytes, _b_cntrs);\
+			break;                                                 \
+		default:                                                       \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.dropped.others.pkts, _p_cntrs);        \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.dropped.others.bytes, _b_cntrs);       \
+			break;                                                 \
+		}                                                              \
+		TXRX_STATS_UPDATE_TX_COMP_HISTOGRAM(_pdev, _p_cntrs);          \
+	} while (0)
+
+
+/*--- txrx sequence number trace macros ---*/
+
+#define TXRX_SEQ_NUM_ERR(_status) (0xffff - _status)
+
+#if defined(ENABLE_RX_REORDER_TRACE)
+
+A_STATUS ol_rx_reorder_trace_attach(ol_txrx_pdev_handle pdev);
+void ol_rx_reorder_trace_detach(ol_txrx_pdev_handle pdev);
+void ol_rx_reorder_trace_add(ol_txrx_pdev_handle pdev,
+			     uint8_t tid,
+			     uint16_t reorder_idx,
+			     uint16_t seq_num, int num_mpdus);
+
+#define OL_RX_REORDER_TRACE_ATTACH ol_rx_reorder_trace_attach
+#define OL_RX_REORDER_TRACE_DETACH ol_rx_reorder_trace_detach
+#define OL_RX_REORDER_TRACE_ADD    ol_rx_reorder_trace_add
+
+#else
+
+#define OL_RX_REORDER_TRACE_ATTACH(_pdev) A_OK
+#define OL_RX_REORDER_TRACE_DETACH(_pdev)
+#define OL_RX_REORDER_TRACE_ADD(pdev, tid, reorder_idx, seq_num, num_mpdus)
+
+#endif /* ENABLE_RX_REORDER_TRACE */
+
+/*--- txrx packet number trace macros ---*/
+
+#if defined(ENABLE_RX_PN_TRACE)
+
+A_STATUS ol_rx_pn_trace_attach(ol_txrx_pdev_handle pdev);
+void ol_rx_pn_trace_detach(ol_txrx_pdev_handle pdev);
+void ol_rx_pn_trace_add(struct ol_txrx_pdev_t *pdev,
+			struct ol_txrx_peer_t *peer,
+			uint16_t tid, void *rx_desc);
+
+#define OL_RX_PN_TRACE_ATTACH ol_rx_pn_trace_attach
+#define OL_RX_PN_TRACE_DETACH ol_rx_pn_trace_detach
+#define OL_RX_PN_TRACE_ADD    ol_rx_pn_trace_add
+
+#else
+
+#define OL_RX_PN_TRACE_ATTACH(_pdev) A_OK
+#define OL_RX_PN_TRACE_DETACH(_pdev)
+#define OL_RX_PN_TRACE_ADD(pdev, peer, tid, rx_desc)
+
+#endif /* ENABLE_RX_PN_TRACE */
+
+static inline int ol_txrx_ieee80211_hdrsize(const void *data)
+{
+	const struct ieee80211_frame *wh = (const struct ieee80211_frame *)data;
+	int size = sizeof(struct ieee80211_frame);
+
+	/* NB: we don't handle control frames */
+	TXRX_ASSERT1((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
+		     IEEE80211_FC0_TYPE_CTL);
+	if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) ==
+	    IEEE80211_FC1_DIR_DSTODS)
+		size += IEEE80211_ADDR_LEN;
+	if (IEEE80211_QOS_HAS_SEQ(wh)) {
+		size += sizeof(uint16_t);
+		/* Qos frame with Order bit set indicates an HTC frame */
+		if (wh->i_fc[1] & IEEE80211_FC1_ORDER)
+			size += sizeof(struct ieee80211_htc);
+	}
+	return size;
+}
+
+/*--- frame display utility ---*/
+
+enum ol_txrx_frm_dump_options {
+	ol_txrx_frm_dump_contents = 0x1,
+	ol_txrx_frm_dump_tcp_seq = 0x2,
+};
+
+#ifdef TXRX_DEBUG_DATA
+static inline void
+ol_txrx_frms_dump(const char *name,
+		  struct ol_txrx_pdev_t *pdev,
+		  qdf_nbuf_t frm,
+		  enum ol_txrx_frm_dump_options display_options, int max_len)
+{
+#define TXRX_FRM_DUMP_MAX_LEN 128
+	uint8_t local_buf[TXRX_FRM_DUMP_MAX_LEN] = { 0 };
+	uint8_t *p;
+
+	if (name) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, "%s\n",
+			  name);
+	}
+	while (frm) {
+		p = qdf_nbuf_data(frm);
+		if (display_options & ol_txrx_frm_dump_tcp_seq) {
+			int tcp_offset;
+			int l2_hdr_size;
+			uint16_t ethtype;
+			uint8_t ip_prot;
+
+			if (pdev->frame_format == wlan_frm_fmt_802_3) {
+				struct ethernet_hdr_t *enet_hdr =
+					(struct ethernet_hdr_t *)p;
+				l2_hdr_size = ETHERNET_HDR_LEN;
+
+				/*
+				 * LLC/SNAP present?
+				 */
+				ethtype = (enet_hdr->ethertype[0] << 8) |
+					enet_hdr->ethertype[1];
+				if (!IS_ETHERTYPE(ethertype)) {
+					/* 802.3 format */
+					struct llc_snap_hdr_t *llc_hdr;
+
+					llc_hdr = (struct llc_snap_hdr_t *)
+						(p + l2_hdr_size);
+					l2_hdr_size += LLC_SNAP_HDR_LEN;
+					ethtype = (llc_hdr->ethertype[0] << 8) |
+						llc_hdr->ethertype[1];
+				}
+			} else {
+				struct llc_snap_hdr_t *llc_hdr;
+
+				/* (generic?) 802.11 */
+				l2_hdr_size = sizeof(struct ieee80211_frame);
+				llc_hdr = (struct llc_snap_hdr_t *)
+					(p + l2_hdr_size);
+				l2_hdr_size += LLC_SNAP_HDR_LEN;
+				ethtype = (llc_hdr->ethertype[0] << 8) |
+					llc_hdr->ethertype[1];
+			}
+			if (ethtype == ETHERTYPE_IPV4) {
+				struct ipv4_hdr_t *ipv4_hdr;
+
+				ipv4_hdr =
+					(struct ipv4_hdr_t *)(p + l2_hdr_size);
+				ip_prot = ipv4_hdr->protocol;
+				tcp_offset = l2_hdr_size + IPV4_HDR_LEN;
+			} else if (ethtype == ETHERTYPE_IPV6) {
+				struct ipv6_hdr_t *ipv6_hdr;
+
+				ipv6_hdr =
+					(struct ipv6_hdr_t *)(p + l2_hdr_size);
+				ip_prot = ipv6_hdr->next_hdr;
+				tcp_offset = l2_hdr_size + IPV6_HDR_LEN;
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_INFO,
+					  "frame %pK non-IP ethertype (%x)\n",
+					  frm, ethtype);
+				goto NOT_IP_TCP;
+			}
+			if (ip_prot == IP_PROTOCOL_TCP) {
+#if NEVERDEFINED
+				struct tcp_hdr_t *tcp_hdr;
+				uint32_t tcp_seq_num;
+
+				tcp_hdr = (struct tcp_hdr_t *)(p + tcp_offset);
+				tcp_seq_num =
+					(tcp_hdr->seq_num[0] << 24) |
+					(tcp_hdr->seq_num[1] << 16) |
+					(tcp_hdr->seq_num[1] << 8) |
+					(tcp_hdr->seq_num[1] << 0);
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_INFO,
+					  "frame %pK: TCP seq num = %d\n", frm,
+					  tcp_seq_num);
+#else
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_INFO,
+					  "frame %pK: TCP seq num = %d\n", frm,
+					  ((*(p + tcp_offset + 4)) << 24) |
+					  ((*(p + tcp_offset + 5)) << 16) |
+					  ((*(p + tcp_offset + 6)) << 8) |
+					  (*(p + tcp_offset + 7)));
+#endif
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_INFO,
+					  "frame %pK non-TCP IP protocol (%x)\n",
+					  frm, ip_prot);
+			}
+		}
+NOT_IP_TCP:
+		if (display_options & ol_txrx_frm_dump_contents) {
+			int i, frag_num, len_lim;
+
+			len_lim = max_len;
+			if (len_lim > qdf_nbuf_len(frm))
+				len_lim = qdf_nbuf_len(frm);
+			if (len_lim > TXRX_FRM_DUMP_MAX_LEN)
+				len_lim = TXRX_FRM_DUMP_MAX_LEN;
+
+			/*
+			 * Gather frame contents from netbuf fragments
+			 * into a contiguous buffer.
+			 */
+			frag_num = 0;
+			i = 0;
+			while (i < len_lim) {
+				int frag_bytes;
+
+				frag_bytes =
+					qdf_nbuf_get_frag_len(frm, frag_num);
+				if (frag_bytes > len_lim - i)
+					frag_bytes = len_lim - i;
+				if (frag_bytes > 0) {
+					p = qdf_nbuf_get_frag_vaddr(frm,
+								    frag_num);
+					qdf_mem_copy(&local_buf[i], p,
+						     frag_bytes);
+				}
+				frag_num++;
+				i += frag_bytes;
+			}
+
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+				  "frame %pK data (%pK), hex dump of bytes 0-%d of %d:\n",
+				  frm, p, len_lim - 1, (int)qdf_nbuf_len(frm));
+			p = local_buf;
+			while (len_lim > 16) {
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_INFO,
+					  "  "        /* indent */
+					  "%02x %02x %02x %02x %02x %02x %02x %02x "
+					  "%02x %02x %02x %02x %02x %02x %02x %02x\n",
+					  *(p + 0), *(p + 1), *(p + 2),
+					  *(p + 3), *(p + 4), *(p + 5),
+					  *(p + 6), *(p + 7), *(p + 8),
+					  *(p + 9), *(p + 10), *(p + 11),
+					  *(p + 12), *(p + 13), *(p + 14),
+					  *(p + 15));
+				p += 16;
+				len_lim -= 16;
+			}
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+				  "  " /* indent */);
+			while (len_lim > 0) {
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_INFO, "%02x ", *p);
+				p++;
+				len_lim--;
+			}
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
+				  "\n");
+		}
+		frm = qdf_nbuf_next(frm);
+	}
+}
+#else
+#define ol_txrx_frms_dump(name, pdev, frms, display_options, max_len)
+#endif /* TXRX_DEBUG_DATA */
+
+#ifdef SUPPORT_HOST_STATISTICS
+
+#define OL_RX_ERR_STATISTICS(pdev, vdev, err_type, sec_type, is_mcast) \
+	ol_rx_err_statistics(pdev->ctrl_pdev, vdev->vdev_id, err_type,	   \
+			     sec_type, is_mcast)
+
+#define OL_RX_ERR_STATISTICS_1(pdev, vdev, peer, rx_desc, err_type)	\
+	do {								\
+		int is_mcast;						\
+		enum htt_sec_type sec_type;				\
+		is_mcast = htt_rx_msdu_is_wlan_mcast(			\
+			pdev->htt_pdev, rx_desc);			\
+		sec_type = peer->security[is_mcast			\
+					  ? txrx_sec_mcast		\
+					  : txrx_sec_ucast].sec_type;	\
+		OL_RX_ERR_STATISTICS(pdev, vdev, err_type,		\
+				     pdev->sec_types[sec_type],		\
+				     is_mcast);				\
+	} while (false)
+
+#ifdef CONFIG_HL_SUPPORT
+
+	/**
+	 * ol_rx_err_inv_get_wifi_header() - retrieve wifi header
+	 * @pdev: handle to the physical device
+	 * @rx_msdu: msdu of which header needs to be retrieved
+	 *
+	 * Return: wifi header
+	 */
+	static inline
+	struct ieee80211_frame *ol_rx_err_inv_get_wifi_header(
+		struct ol_pdev_t *pdev, qdf_nbuf_t rx_msdu)
+	{
+		return NULL;
+	}
+#else
+
+	static inline
+	struct ieee80211_frame *ol_rx_err_inv_get_wifi_header(
+		struct ol_pdev_t *pdev, qdf_nbuf_t rx_msdu)
+	{
+		struct ieee80211_frame *wh = NULL;
+
+		if (ol_cfg_frame_type(pdev) == wlan_frm_fmt_native_wifi)
+			/* For windows, it is always native wifi header .*/
+			wh = (struct ieee80211_frame *)qdf_nbuf_data(rx_msdu);
+
+		return wh;
+	}
+#endif
+
+#define OL_RX_ERR_INV_PEER_STATISTICS(pdev, rx_msdu)			\
+	do {								\
+		struct ieee80211_frame *wh = NULL;			\
+		/*FIX THIS : */						\
+		/* Here htt_rx_mpdu_wifi_hdr_retrieve should be used. */ \
+		/*But at present it seems it does not work.*/		\
+		/*wh = (struct ieee80211_frame *) */			\
+		/*htt_rx_mpdu_wifi_hdr_retrieve(pdev->htt_pdev, rx_desc);*/ \
+		/* this only apply to LL device.*/			\
+		wh = ol_rx_err_inv_get_wifi_header(pdev->ctrl_pdev, rx_msdu); \
+		ol_rx_err_inv_peer_statistics(pdev->ctrl_pdev,		\
+					      wh, OL_RX_ERR_UNKNOWN_PEER); \
+	} while (false)
+
+#define OL_RX_ERR_STATISTICS_2(pdev, vdev, peer, rx_desc, rx_msdu, rx_status) \
+	do {								\
+		enum ol_rx_err_type err_type = OL_RX_ERR_NONE;		\
+		if (rx_status == htt_rx_status_decrypt_err)		\
+			err_type = OL_RX_ERR_DECRYPT;			\
+		else if (rx_status == htt_rx_status_tkip_mic_err)	\
+			err_type = OL_RX_ERR_TKIP_MIC;			\
+		else if (rx_status == htt_rx_status_mpdu_length_err)	\
+			err_type = OL_RX_ERR_MPDU_LENGTH;		\
+		else if (rx_status == htt_rx_status_mpdu_encrypt_required_err) \
+			err_type = OL_RX_ERR_ENCRYPT_REQUIRED;		\
+		else if (rx_status == htt_rx_status_err_dup)		\
+			err_type = OL_RX_ERR_DUP;			\
+		else if (rx_status == htt_rx_status_err_fcs)		\
+			err_type = OL_RX_ERR_FCS;			\
+		else							\
+			err_type = OL_RX_ERR_UNKNOWN;			\
+									\
+		if (vdev != NULL && peer != NULL) {			\
+			OL_RX_ERR_STATISTICS_1(pdev, vdev, peer,	\
+					       rx_mpdu_desc, err_type); \
+		} else {						\
+			OL_RX_ERR_INV_PEER_STATISTICS(pdev, rx_msdu);	\
+		}							\
+	} while (false)
+#else
+#define OL_RX_ERR_STATISTICS(pdev, vdev, err_type, sec_type, is_mcast)
+#define OL_RX_ERR_STATISTICS_1(pdev, vdev, peer, rx_desc, err_type)
+#define OL_RX_ERR_STATISTICS_2(pdev, vdev, peer, rx_desc, rx_msdu, rx_status)
+#endif /* SUPPORT_HOST_STATISTICS */
+
+#ifdef QCA_ENABLE_OL_TXRX_PEER_STATS
+#define OL_TXRX_PEER_STATS_UPDATE_BASE(peer, tx_or_rx, type, msdu) \
+	do { \
+		qdf_spin_lock_bh(&peer->vdev->pdev->peer_stat_mutex); \
+		peer->stats.tx_or_rx.frms.type += 1; \
+		peer->stats.tx_or_rx.bytes.type += qdf_nbuf_len(msdu); \
+		qdf_spin_unlock_bh(&peer->vdev->pdev->peer_stat_mutex);	\
+	} while (0)
+#define OL_TXRX_PEER_STATS_UPDATE(peer, tx_or_rx, msdu)	\
+	do { \
+		struct ol_txrx_vdev_t *vdev = peer->vdev; \
+		struct ol_txrx_pdev_t *pdev = vdev->pdev; \
+		uint8_t *dest_addr; \
+		if (pdev->frame_format == wlan_frm_fmt_802_3) {	\
+			dest_addr = qdf_nbuf_data(msdu); \
+		} else { /* 802.11 format */ \
+			struct ieee80211_frame *frm; \
+			frm = (struct ieee80211_frame *) qdf_nbuf_data(msdu); \
+			if (vdev->opmode == wlan_op_mode_ap) { \
+				dest_addr = (uint8_t *) &(frm->i_addr1[0]); \
+			} else { \
+				dest_addr = (uint8_t *) &(frm->i_addr3[0]); \
+			} \
+		} \
+		if (qdf_unlikely(IEEE80211_IS_BROADCAST(dest_addr))) { \
+			OL_TXRX_PEER_STATS_UPDATE_BASE(peer, tx_or_rx,	\
+						       bcast, msdu);	\
+		} else if (qdf_unlikely(IEEE80211_IS_MULTICAST(dest_addr))) { \
+			OL_TXRX_PEER_STATS_UPDATE_BASE(peer, tx_or_rx,	\
+						       mcast, msdu);	\
+		} else { \
+			OL_TXRX_PEER_STATS_UPDATE_BASE(peer, tx_or_rx,	\
+						       ucast, msdu);	\
+		} \
+	} while (0)
+#define OL_TX_PEER_STATS_UPDATE(peer, msdu) \
+	OL_TXRX_PEER_STATS_UPDATE(peer, tx, msdu)
+#define OL_RX_PEER_STATS_UPDATE(peer, msdu) \
+	OL_TXRX_PEER_STATS_UPDATE(peer, rx, msdu)
+#define OL_TXRX_PEER_STATS_MUTEX_INIT(pdev) \
+	qdf_spinlock_create(&pdev->peer_stat_mutex)
+#define OL_TXRX_PEER_STATS_MUTEX_DESTROY(pdev) \
+	qdf_spinlock_destroy(&pdev->peer_stat_mutex)
+#else
+#define OL_TX_PEER_STATS_UPDATE(peer, msdu)     /* no-op */
+#define OL_RX_PEER_STATS_UPDATE(peer, msdu)     /* no-op */
+#define OL_TXRX_PEER_STATS_MUTEX_INIT(peer)     /* no-op */
+#define OL_TXRX_PEER_STATS_MUTEX_DESTROY(peer)  /* no-op */
+#endif
+
+#ifndef DEBUG_HTT_CREDIT
+#define DEBUG_HTT_CREDIT 0
+#endif
+
+#if defined(FEATURE_TSO_DEBUG)
+#define TXRX_STATS_TSO_HISTOGRAM(_pdev, _p_cntrs) \
+	do { \
+		if (_p_cntrs == 1) { \
+			TXRX_STATS_ADD(_pdev, pub.tx.tso.tso_hist.pkts_1, 1); \
+		} else if (_p_cntrs >= 2 && _p_cntrs <= 5) {                  \
+			TXRX_STATS_ADD(_pdev,                                 \
+				pub.tx.tso.tso_hist.pkts_2_5, 1);             \
+		} else if (_p_cntrs > 5 && _p_cntrs <= 10) {                  \
+			TXRX_STATS_ADD(_pdev,                                 \
+				pub.tx.tso.tso_hist.pkts_6_10, 1);            \
+		} else if (_p_cntrs > 10 && _p_cntrs <= 15) {                 \
+			TXRX_STATS_ADD(_pdev,                                 \
+				pub.tx.tso.tso_hist.pkts_11_15, 1);           \
+		} else if (_p_cntrs > 15 && _p_cntrs <= 20) {                 \
+			TXRX_STATS_ADD(_pdev,                                 \
+				pub.tx.tso.tso_hist.pkts_16_20, 1);           \
+		} else if (_p_cntrs > 20) {                                   \
+			TXRX_STATS_ADD(_pdev,                                 \
+				pub.tx.tso.tso_hist.pkts_20_plus, 1);         \
+		}                                                             \
+	} while (0)
+
+#define TXRX_STATS_TSO_RESET_MSDU(pdev, idx) \
+	do { \
+		pdev->stats.pub.tx.tso.tso_info.tso_msdu_info[idx].num_seg     \
+			= 0;						       \
+		pdev->stats.pub.tx.tso.tso_info.tso_msdu_info[idx].tso_seg_idx \
+			= 0;						       \
+	} while (0)
+
+#define TXRX_STATS_TSO_MSDU_IDX(pdev) \
+	pdev->stats.pub.tx.tso.tso_info.tso_msdu_idx
+
+#define TXRX_STATS_TSO_MSDU(pdev, idx) \
+	pdev->stats.pub.tx.tso.tso_info.tso_msdu_info[idx]
+
+#define TXRX_STATS_TSO_MSDU_NUM_SEG(pdev, idx) \
+	pdev->stats.pub.tx.tso.tso_info.tso_msdu_info[idx].num_seg
+
+#define TXRX_STATS_TSO_MSDU_GSO_SIZE(pdev, idx) \
+	pdev->stats.pub.tx.tso.tso_info.tso_msdu_info[idx].gso_size
+
+#define TXRX_STATS_TSO_MSDU_TOTAL_LEN(pdev, idx) \
+	pdev->stats.pub.tx.tso.tso_info.tso_msdu_info[idx].total_len
+
+#define TXRX_STATS_TSO_MSDU_NR_FRAGS(pdev, idx) \
+	pdev->stats.pub.tx.tso.tso_info.tso_msdu_info[idx].nr_frags
+
+#define TXRX_STATS_TSO_CURR_MSDU(pdev, idx) \
+	TXRX_STATS_TSO_MSDU(pdev, idx)
+
+#define TXRX_STATS_TSO_SEG_IDX(pdev, idx) \
+	TXRX_STATS_TSO_CURR_MSDU(pdev, idx).tso_seg_idx
+
+#define TXRX_STATS_TSO_INC_SEG(pdev, idx) \
+	do { \
+		TXRX_STATS_TSO_CURR_MSDU(pdev, idx).num_seg++; \
+		TXRX_STATS_TSO_CURR_MSDU(pdev, idx).num_seg &= \
+					 NUM_MAX_TSO_SEGS_MASK; \
+	} while (0)
+
+#define TXRX_STATS_TSO_RST_SEG(pdev, idx) \
+	TXRX_STATS_TSO_CURR_MSDU(pdev, idx).num_seg = 0
+
+#define TXRX_STATS_TSO_RST_SEG_IDX(pdev, idx) \
+	TXRX_STATS_TSO_CURR_MSDU(pdev, idx).tso_seg_idx = 0
+
+#define TXRX_STATS_TSO_SEG(pdev, msdu_idx, seg_idx) \
+	TXRX_STATS_TSO_MSDU(pdev, msdu_idx).tso_segs[seg_idx]
+
+#define TXRX_STATS_TSO_CURR_SEG(pdev, idx) \
+	TXRX_STATS_TSO_SEG(pdev, idx, \
+	 TXRX_STATS_TSO_SEG_IDX(pdev, idx)) \
+
+#define TXRX_STATS_TSO_INC_SEG_IDX(pdev, idx) \
+	do { \
+		TXRX_STATS_TSO_SEG_IDX(pdev, idx)++; \
+		TXRX_STATS_TSO_SEG_IDX(pdev, idx) &= NUM_MAX_TSO_SEGS_MASK; \
+	} while (0)
+
+#define TXRX_STATS_TSO_SEG_UPDATE(pdev, idx, tso_seg) \
+	(TXRX_STATS_TSO_CURR_SEG(pdev, idx) = tso_seg)
+
+#define TXRX_STATS_TSO_GSO_SIZE_UPDATE(pdev, idx, size) \
+	(TXRX_STATS_TSO_CURR_MSDU(pdev, idx).gso_size = size)
+
+#define TXRX_STATS_TSO_TOTAL_LEN_UPDATE(pdev, idx, len) \
+	(TXRX_STATS_TSO_CURR_MSDU(pdev, idx).total_len = len)
+
+#define TXRX_STATS_TSO_NUM_FRAGS_UPDATE(pdev, idx, frags) \
+	(TXRX_STATS_TSO_CURR_MSDU(pdev, idx).nr_frags = frags)
+
+#else
+#define TXRX_STATS_TSO_HISTOGRAM(_pdev, _p_cntrs)  /* no-op */
+#define TXRX_STATS_TSO_RESET_MSDU(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_MSDU_IDX(pdev) /* no-op */
+#define TXRX_STATS_TSO_MSDU(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_MSDU_NUM_SEG(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_CURR_MSDU(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_INC_MSDU_IDX(pdev) /* no-op */
+#define TXRX_STATS_TSO_SEG_IDX(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_SEG(pdev, msdu_idx, seg_idx) /* no-op */
+#define TXRX_STATS_TSO_CURR_SEG(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_INC_SEG_IDX(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_SEG_UPDATE(pdev, idx, tso_seg) /* no-op */
+#define TXRX_STATS_TSO_INC_SEG(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_RST_SEG(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_RST_SEG_IDX(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_GSO_SIZE_UPDATE(pdev, idx, size) /* no-op */
+#define TXRX_STATS_TSO_TOTAL_LEN_UPDATE(pdev, idx, len) /* no-op */
+#define TXRX_STATS_TSO_NUM_FRAGS_UPDATE(pdev, idx, frags) /* no-op */
+#define TXRX_STATS_TSO_MSDU_GSO_SIZE(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_MSDU_TOTAL_LEN(pdev, idx) /* no-op */
+#define TXRX_STATS_TSO_MSDU_NR_FRAGS(pdev, idx) /* no-op */
+
+#endif /* FEATURE_TSO_DEBUG */
+
+#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
+
+void
+ol_txrx_update_group_credit(
+	struct ol_tx_queue_group_t *group,
+	int32_t credit,
+	u_int8_t absolute);
+#endif
+
+#endif /* _OL_TXRX_INTERNAL__H_ */
diff --git a/core/dp/txrx/ol_txrx_ipa.c b/core/dp/txrx/ol_txrx_ipa.c
new file mode 100644
index 0000000..1dd725b
--- /dev/null
+++ b/core/dp/txrx/ol_txrx_ipa.c
@@ -0,0 +1,1650 @@
+/*
+ * Copyright (c) 2017-2018, 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.
+ */
+
+/*=== includes ===*/
+/* header files for OS primitives */
+#include <osdep.h>              /* uint32_t, etc. */
+#include <qdf_mem.h>         /* qdf_mem_malloc,free */
+#include <qdf_types.h>          /* qdf_device_t, qdf_print */
+#include <qdf_lock.h>           /* qdf_spinlock */
+#include <qdf_atomic.h>         /* qdf_atomic_read */
+
+/* header files for utilities */
+#include <cds_queue.h>          /* TAILQ */
+
+/* header files for configuration API */
+#include <ol_cfg.h>             /* ol_cfg_is_high_latency */
+#include <ol_if_athvar.h>
+
+/* header files for HTT API */
+#include <ol_htt_api.h>
+#include <ol_htt_tx_api.h>
+
+/* header files for our own APIs */
+#include <ol_txrx_api.h>
+#include <ol_txrx_dbg.h>
+#include <cdp_txrx_ocb.h>
+#include <ol_txrx_ctrl_api.h>
+#include <cdp_txrx_stats.h>
+#include <ol_txrx_osif_api.h>
+/* header files for our internal definitions */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT, etc. */
+#include <wdi_event.h>          /* WDI events */
+#include <ol_tx.h>              /* ol_tx_ll */
+#include <ol_rx.h>              /* ol_rx_deliver */
+#include <ol_txrx_peer_find.h>  /* ol_txrx_peer_find_attach, etc. */
+#include <ol_rx_pn.h>           /* ol_rx_pn_check, etc. */
+#include <ol_rx_fwd.h>          /* ol_rx_fwd_check, etc. */
+#include <ol_rx_reorder_timeout.h>      /* OL_RX_REORDER_TIMEOUT_INIT, etc. */
+#include <ol_rx_reorder.h>
+#include <ol_tx_send.h>         /* ol_tx_discard_target_frms */
+#include <ol_tx_desc.h>         /* ol_tx_desc_frame_free */
+#include <ol_tx_queue.h>
+#include <ol_tx_sched.h>           /* ol_tx_sched_attach, etc. */
+#include <ol_txrx.h>
+#include <ol_txrx_types.h>
+#include <cdp_txrx_flow_ctrl_legacy.h>
+#include <cdp_txrx_bus.h>
+#include <cdp_txrx_ipa.h>
+#include <cdp_txrx_pmf.h>
+#include "wma.h"
+#include "hif.h"
+#include <cdp_txrx_peer_ops.h>
+#ifndef REMOVE_PKT_LOG
+#include "pktlog_ac.h"
+#endif
+#include "epping_main.h"
+#include <a_types.h>
+
+#ifdef IPA_OFFLOAD
+#include <ol_txrx_ipa.h>
+
+/* For Tx pipes, use Ethernet-II Header format */
+#ifdef QCA_WIFI_3_0
+struct ol_txrx_ipa_uc_tx_hdr ipa_uc_tx_hdr = {
+	{
+		0x0000,
+		0x00000000,
+		0x00000000
+	},
+	{
+		0x00000000
+	},
+	{
+		{0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc},
+		{0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff},
+		0x0008
+	}
+};
+#else
+struct ol_txrx_ipa_uc_tx_hdr ipa_uc_tx_hdr = {
+	{
+		0x00000000,
+		0x00000000
+	},
+	{
+		0x00000000
+	},
+	{
+		{0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc},
+		{0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff},
+		0x0008
+	}
+};
+#endif
+
+/**
+ * ol_txrx_ipa_uc_get_resource() - Client request resource information
+ * @pdev: handle to the HTT instance
+ *
+ *  OL client will request IPA UC related resource information
+ *  Resource information will be distributted to IPA module
+ *  All of the required resources should be pre-allocated
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
+	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	if (!osdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: qdf device is null!", __func__);
+		return QDF_STATUS_E_NOENT;
+	}
+
+	htt_ipa_uc_get_resource(pdev->htt_pdev,
+				&ipa_res->ce_sr,
+				&ipa_res->tx_comp_ring,
+				&ipa_res->rx_rdy_ring,
+				&ipa_res->rx2_rdy_ring,
+				&ipa_res->rx_proc_done_idx,
+				&ipa_res->rx2_proc_done_idx,
+				&ipa_res->ce_sr_ring_size,
+				&ipa_res->ce_reg_paddr,
+				&ipa_res->tx_num_alloc_buffer);
+
+	if ((0 == qdf_mem_get_dma_addr(osdev,
+				&ipa_res->ce_sr->mem_info)) ||
+	    (0 == qdf_mem_get_dma_addr(osdev,
+				&ipa_res->tx_comp_ring->mem_info)) ||
+	    (0 == qdf_mem_get_dma_addr(osdev,
+				&ipa_res->rx_rdy_ring->mem_info))
+#if defined(QCA_WIFI_3_0) && defined(CONFIG_IPA3)
+	    || (0 == qdf_mem_get_dma_addr(osdev,
+				&ipa_res->rx2_rdy_ring->mem_info))
+#endif
+	   )
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_set_doorbell_paddr() - Client set IPA UC doorbell register
+ * @pdev: handle to the HTT instance
+ *
+ *  IPA UC let know doorbell register physical address
+ *  WLAN firmware will use this physical address to notify IPA UC
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
+	int ret;
+
+	ret = htt_ipa_uc_set_doorbell_paddr(pdev->htt_pdev,
+				      ipa_res->tx_comp_doorbell_dmaaddr,
+				      ipa_res->rx_ready_doorbell_dmaaddr);
+
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "htt_ipa_uc_set_doorbell_dmaaddr fail: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_set_active() - Client notify IPA UC data path active or not
+ * @pdev: handle to the HTT instance
+ * @uc_active: WDI UC path enable or not
+ * @is_tx: TX path or RX path
+ *
+ *  IPA UC let know doorbell register physical address
+ *  WLAN firmware will use this physical address to notify IPA UC
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_uc_set_active(struct cdp_pdev *ppdev, bool uc_active,
+			       bool is_tx)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	int ret;
+
+	ret = htt_h2t_ipa_uc_set_active(pdev->htt_pdev, uc_active, is_tx);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "htt_h2t_ipa_uc_set_active fail: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_op_response() - Handle OP command response from firmware
+ * @pdev: handle to the device instance
+ * @op_msg: op response message from firmware
+ *
+ * Return: none
+ */
+QDF_STATUS ol_txrx_ipa_uc_op_response(struct cdp_pdev *ppdev, uint8_t *op_msg)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+
+	if (pdev->ipa_uc_op_cb) {
+		pdev->ipa_uc_op_cb(op_msg, pdev->usr_ctxt);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		    "%s: IPA callback function is not registered", __func__);
+		qdf_mem_free(op_msg);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_register_op_cb() - Register OP handler function
+ * @pdev: handle to the device instance
+ * @op_cb: handler function pointer
+ *
+ * Return: none
+ */
+QDF_STATUS ol_txrx_ipa_uc_register_op_cb(struct cdp_pdev *ppdev,
+				   ipa_uc_op_cb_type op_cb, void *usr_ctxt)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+
+	pdev->ipa_uc_op_cb = op_cb;
+	pdev->usr_ctxt = usr_ctxt;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_get_stat() - Get firmware wdi status
+ * @pdev: handle to the HTT instance
+ *
+ * Return: none
+ */
+QDF_STATUS ol_txrx_ipa_uc_get_stat(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	int ret;
+
+	ret = htt_h2t_ipa_uc_get_stats(pdev->htt_pdev);
+
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "htt_h2t_ipa_uc_get_stats fail: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_enable_autonomy() - Enable autonomy RX path
+ * @pdev: handle to the device instance
+ *
+ * Set all RX packet route to IPA
+ * Return: none
+ */
+QDF_STATUS ol_txrx_ipa_enable_autonomy(struct cdp_pdev *ppdev)
+{
+	/* TBD */
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_disable_autonomy() - Disable autonomy RX path
+ * @pdev: handle to the device instance
+ *
+ * Disable RX packet route to host
+ * Return: none
+ */
+QDF_STATUS ol_txrx_ipa_disable_autonomy(struct cdp_pdev *ppdev)
+{
+	/* TBD */
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef CONFIG_IPA_WDI_UNIFIED_API
+
+#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+static inline void ol_txrx_setup_mcc_sys_pipes(
+		qdf_ipa_sys_connect_params_t *sys_in,
+		qdf_ipa_wdi_conn_in_params_t *pipe_in)
+{
+	/* Setup MCC sys pipe */
+	QDF_IPA_WDI_CONN_IN_PARAMS_NUM_SYS_PIPE_NEEDED(pipe_in) =
+			OL_TXRX_IPA_MAX_IFACE;
+	for (int i = 0; i < OL_TXRX_IPA_MAX_IFACE; i++)
+		memcpy(&QDF_IPA_WDI_CONN_IN_PARAMS_SYS_IN(pipe_in)[i],
+		       &sys_in[i], sizeof(qdf_ipa_sys_connect_params_t));
+}
+#else
+static inline void ol_txrx_setup_mcc_sys_pipes(
+		qdf_ipa_sys_connect_params_t *sys_in,
+		qdf_ipa_wdi_conn_in_params_t *pipe_in)
+{
+	QDF_IPA_WDI_CONN_IN_PARAMS_NUM_SYS_PIPE_NEEDED(pipe_in) = 0;
+}
+#endif
+
+#ifdef ENABLE_SMMU_S1_TRANSLATION
+/**
+ * ol_txrx_ipa_wdi_tx_smmu_params() - Config IPA TX params
+ * @ipa_res: IPA resources
+ * @tx_smmu: IPA WDI pipe setup info
+ *
+ * Return: None
+ */
+static inline void ol_txrx_ipa_wdi_tx_smmu_params(
+				struct ol_txrx_ipa_resources *ipa_res,
+				qdf_ipa_wdi_pipe_setup_info_smmu_t *tx_smmu)
+{
+	QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(tx_smmu) =
+		IPA_CLIENT_WLAN1_CONS;
+	qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_BASE(
+				tx_smmu),
+		     &ipa_res->tx_comp_ring->sgtable,
+		     sizeof(sgtable_t));
+	QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_SIZE(tx_smmu) =
+		ipa_res->tx_comp_ring->mem_info.size;
+	qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_BASE(
+				tx_smmu),
+		     &ipa_res->ce_sr->sgtable,
+		     sizeof(sgtable_t));
+	QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_SIZE(tx_smmu) =
+		ipa_res->ce_sr_ring_size;
+	QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_DOORBELL_PA(tx_smmu) =
+		ipa_res->ce_reg_paddr;
+	QDF_IPA_WDI_SETUP_INFO_SMMU_NUM_PKT_BUFFERS(tx_smmu) =
+		ipa_res->tx_num_alloc_buffer;
+	QDF_IPA_WDI_SETUP_INFO_SMMU_PKT_OFFSET(tx_smmu) = 0;
+}
+
+/**
+ * ol_txrx_ipa_wdi_rx_smmu_params() - Config IPA RX params
+ * @ipa_res: IPA resources
+ * @rx_smmu: IPA WDI pipe setup info
+ *
+ * Return: None
+ */
+static inline void ol_txrx_ipa_wdi_rx_smmu_params(
+				struct ol_txrx_ipa_resources *ipa_res,
+				qdf_ipa_wdi_pipe_setup_info_smmu_t *rx_smmu)
+{
+	QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(rx_smmu) =
+		IPA_CLIENT_WLAN1_PROD;
+	qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_BASE(
+				rx_smmu),
+		     &ipa_res->rx_rdy_ring->sgtable,
+		     sizeof(sgtable_t));
+	QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_SIZE(rx_smmu) =
+		ipa_res->rx_rdy_ring->mem_info.size;
+	QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_DOORBELL_PA(rx_smmu) =
+		ipa_res->rx_proc_done_idx->mem_info.pa;
+	qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_BASE(
+				rx_smmu),
+		     &ipa_res->rx2_rdy_ring->sgtable,
+		     sizeof(sgtable_t));
+	QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_SIZE(rx_smmu) =
+		ipa_res->rx2_rdy_ring->mem_info.size;
+	QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_DOORBELL_PA(rx_smmu) =
+		ipa_res->rx2_proc_done_idx->mem_info.pa;
+	QDF_IPA_WDI_SETUP_INFO_SMMU_PKT_OFFSET(rx_smmu) = 0;
+
+}
+
+#else
+
+static inline void ol_txrx_ipa_wdi_tx_smmu_params(
+				struct ol_txrx_ipa_resources *ipa_res,
+				qdf_ipa_wdi_pipe_setup_info_smmu_t *tx_smmu)
+{
+}
+
+static inline void ol_txrx_ipa_wdi_rx_smmu_params(
+				struct ol_txrx_ipa_resources *ipa_res,
+				qdf_ipa_wdi_pipe_setup_info_smmu_t *rx_smmu)
+{
+}
+#endif
+
+/**
+ * ol_txrx_ipa_wdi_tx_params() - Config IPA TX params
+ * @ipa_res: IPA resources
+ * @tx: IPA WDI pipe setup info
+ *
+ * Return: None
+ */
+static inline void ol_txrx_ipa_wdi_tx_params(
+				struct ol_txrx_ipa_resources *ipa_res,
+				qdf_ipa_wdi_pipe_setup_info_t *tx)
+{
+	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	if (!osdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: qdf device is null!", __func__);
+		return;
+	}
+
+	QDF_IPA_WDI_SETUP_INFO_CLIENT(tx) = IPA_CLIENT_WLAN1_CONS;
+	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_BASE_PA(tx) =
+		qdf_mem_get_dma_addr(osdev,
+				&ipa_res->tx_comp_ring->mem_info);
+	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_SIZE(tx) =
+		ipa_res->tx_comp_ring->mem_info.size;
+	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_BASE_PA(tx) =
+		qdf_mem_get_dma_addr(osdev,
+				&ipa_res->ce_sr->mem_info);
+	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_SIZE(tx) =
+		ipa_res->ce_sr_ring_size;
+	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_DOORBELL_PA(tx) =
+		ipa_res->ce_reg_paddr;
+	QDF_IPA_WDI_SETUP_INFO_NUM_PKT_BUFFERS(tx) =
+		ipa_res->tx_num_alloc_buffer;
+	QDF_IPA_WDI_SETUP_INFO_PKT_OFFSET(tx) = 0;
+}
+
+/**
+ * ol_txrx_ipa_wdi_rx_params() - Config IPA RX params
+ * @ipa_res: IPA resources
+ * @rx: IPA WDI pipe setup info
+ *
+ * Return: None
+ */
+static inline void ol_txrx_ipa_wdi_rx_params(
+				struct ol_txrx_ipa_resources *ipa_res,
+				qdf_ipa_wdi_pipe_setup_info_t *rx)
+{
+	QDF_IPA_WDI_SETUP_INFO_CLIENT(rx) = IPA_CLIENT_WLAN1_PROD;
+	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_BASE_PA(rx) =
+		ipa_res->rx_rdy_ring->mem_info.pa;
+	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_SIZE(rx) =
+		ipa_res->rx_rdy_ring->mem_info.size;
+	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_DOORBELL_PA(rx) =
+		ipa_res->rx_proc_done_idx->mem_info.pa;
+	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_BASE_PA(rx) =
+		ipa_res->rx2_rdy_ring->mem_info.pa;
+	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_SIZE(rx) =
+		ipa_res->rx2_rdy_ring->mem_info.size;
+	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_DOORBELL_PA(rx) =
+		ipa_res->rx2_proc_done_idx->mem_info.pa;
+	QDF_IPA_WDI_SETUP_INFO_PKT_OFFSET(rx) = 0;
+}
+
+/**
+ * ol_txrx_ipa_setup() - Setup and connect IPA pipes
+ * @pdev: handle to the device instance
+ * @ipa_i2w_cb: IPA to WLAN callback
+ * @ipa_w2i_cb: WLAN to IPA callback
+ * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback
+ * @ipa_desc_size: IPA descriptor size
+ * @ipa_priv: handle to the HTT instance
+ * @is_rm_enabled: Is IPA RM enabled or not
+ * @p_tx_pipe_handle: pointer to Tx pipe handle
+ * @p_rx_pipe_handle: pointer to Rx pipe handle
+ * @is_smmu_enabled: Is SMMU enabled or not
+ * @sys_in: parameters to setup sys pipe in mcc mode
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb,
+			     void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb,
+			     uint32_t ipa_desc_size, void *ipa_priv,
+			     bool is_rm_enabled, uint32_t *p_tx_pipe_handle,
+			     uint32_t *p_rx_pipe_handle, bool is_smmu_enabled,
+			     qdf_ipa_sys_connect_params_t *sys_in)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
+	qdf_ipa_ep_cfg_t *tx_cfg;
+	qdf_ipa_ep_cfg_t *rx_cfg;
+	qdf_ipa_wdi_pipe_setup_info_t *tx;
+	qdf_ipa_wdi_pipe_setup_info_t *rx;
+	qdf_ipa_wdi_pipe_setup_info_smmu_t *tx_smmu;
+	qdf_ipa_wdi_pipe_setup_info_smmu_t *rx_smmu;
+	qdf_ipa_wdi_conn_in_params_t pipe_in;
+	qdf_ipa_wdi_conn_out_params_t pipe_out;
+	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	uint32_t tx_comp_db_dmaaddr = 0, rx_rdy_db_dmaaddr = 0;
+	int ret;
+
+	if (!osdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: qdf device is null!", __func__);
+		return QDF_STATUS_E_NOENT;
+	}
+
+	qdf_mem_zero(&pipe_in, sizeof(pipe_in));
+	qdf_mem_zero(&pipe_out, sizeof(pipe_out));
+
+	ol_txrx_setup_mcc_sys_pipes(sys_in, &pipe_in);
+
+	/* TX PIPE */
+	if (is_smmu_enabled) {
+		QDF_IPA_WDI_CONN_IN_PARAMS_SMMU_ENABLED(&pipe_in) = true;
+		tx_smmu = &QDF_IPA_WDI_CONN_IN_PARAMS_TX_SMMU(&pipe_in);
+		tx_cfg = &QDF_IPA_WDI_SETUP_INFO_SMMU_EP_CFG(tx_smmu);
+	} else {
+		QDF_IPA_WDI_CONN_IN_PARAMS_SMMU_ENABLED(&pipe_in) = false;
+		tx = &QDF_IPA_WDI_CONN_IN_PARAMS_TX(&pipe_in);
+		tx_cfg = &QDF_IPA_WDI_SETUP_INFO_EP_CFG(tx);
+	}
+
+	QDF_IPA_EP_CFG_NAT_EN(tx_cfg) = IPA_BYPASS_NAT;
+	QDF_IPA_EP_CFG_HDR_LEN(tx_cfg) = OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN;
+	QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE_VALID(tx_cfg) = 1;
+	QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE(tx_cfg) = 0;
+	QDF_IPA_EP_CFG_HDR_ADDITIONAL_CONST_LEN(tx_cfg) =
+		OL_TXRX_IPA_UC_WLAN_8023_HDR_SIZE;
+	QDF_IPA_EP_CFG_MODE(tx_cfg) = IPA_BASIC;
+	QDF_IPA_EP_CFG_HDR_LITTLE_ENDIAN(tx_cfg) = true;
+
+	if (is_smmu_enabled)
+		ol_txrx_ipa_wdi_tx_smmu_params(ipa_res, tx_smmu);
+	else
+		ol_txrx_ipa_wdi_tx_params(ipa_res, tx);
+
+
+	/* RX PIPE */
+	if (is_smmu_enabled) {
+		rx_smmu = &QDF_IPA_WDI_CONN_IN_PARAMS_RX_SMMU(&pipe_in);
+		rx_cfg = &QDF_IPA_WDI_SETUP_INFO_EP_CFG(rx_smmu);
+	} else {
+		rx = &QDF_IPA_WDI_CONN_IN_PARAMS_RX(&pipe_in);
+		rx_cfg = &QDF_IPA_WDI_SETUP_INFO_EP_CFG(rx);
+	}
+
+	QDF_IPA_EP_CFG_NAT_EN(rx_cfg) = IPA_BYPASS_NAT;
+	QDF_IPA_EP_CFG_HDR_LEN(rx_cfg) = OL_TXRX_IPA_UC_WLAN_RX_HDR_LEN;
+	QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE_VALID(rx_cfg) = 1;
+	QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE(rx_cfg) = 0;
+	QDF_IPA_EP_CFG_HDR_ADDITIONAL_CONST_LEN(rx_cfg) =
+		OL_TXRX_IPA_UC_WLAN_8023_HDR_SIZE;
+	QDF_IPA_EP_CFG_HDR_OFST_METADATA_VALID(rx_cfg) = 0;
+	QDF_IPA_EP_CFG_HDR_METADATA_REG_VALID(rx_cfg) = 1;
+	QDF_IPA_EP_CFG_MODE(rx_cfg) = IPA_BASIC;
+	QDF_IPA_EP_CFG_HDR_LITTLE_ENDIAN(rx_cfg) = true;
+
+	if (is_smmu_enabled)
+		ol_txrx_ipa_wdi_rx_smmu_params(ipa_res, rx_smmu);
+	else
+		ol_txrx_ipa_wdi_rx_params(ipa_res, rx);
+
+	QDF_IPA_WDI_CONN_IN_PARAMS_NOTIFY(&pipe_in) = ipa_w2i_cb;
+	QDF_IPA_WDI_CONN_IN_PARAMS_PRIV(&pipe_in) = ipa_priv;
+
+	/* Connect WDI IPA PIPE */
+	ret = qdf_ipa_wdi_conn_pipes(&pipe_in, &pipe_out);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: ipa_wdi_conn_pipes: IPA pipe setup failed: ret=%d",
+			  __func__, ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* IPA uC Doorbell registers */
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Tx DB PA=0x%x, Rx DB PA=0x%x", __func__,
+		  (unsigned int)
+			QDF_IPA_WDI_CONN_OUT_PARAMS_TX_UC_DB_PA(&pipe_out),
+		  (unsigned int)
+			QDF_IPA_WDI_CONN_OUT_PARAMS_RX_UC_DB_PA(&pipe_out));
+
+	ipa_res->tx_comp_doorbell_dmaaddr =
+		QDF_IPA_WDI_CONN_OUT_PARAMS_TX_UC_DB_PA(&pipe_out);
+	ipa_res->rx_ready_doorbell_dmaaddr =
+		QDF_IPA_WDI_CONN_OUT_PARAMS_RX_UC_DB_PA(&pipe_out);
+
+	if (is_smmu_enabled) {
+		pld_smmu_map(osdev->dev, ipa_res->tx_comp_doorbell_dmaaddr,
+			     &tx_comp_db_dmaaddr, sizeof(uint32_t));
+		ipa_res->tx_comp_doorbell_dmaaddr = tx_comp_db_dmaaddr;
+
+		pld_smmu_map(osdev->dev, ipa_res->rx_ready_doorbell_dmaaddr,
+			     &rx_rdy_db_dmaaddr, sizeof(uint32_t));
+		ipa_res->rx_ready_doorbell_dmaaddr = rx_rdy_db_dmaaddr;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_cleanup() - Disconnect IPA pipes
+ * @tx_pipe_handle: Tx pipe handle
+ * @rx_pipe_handle: Rx pipe handle
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_cleanup(uint32_t tx_pipe_handle, uint32_t rx_pipe_handle)
+{
+	int ret;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Disconnect IPA pipe", __func__);
+	ret = qdf_ipa_wdi_disconn_pipes();
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "ipa_wdi_disconn_pipes failed: ret=%d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_setup_iface() - Setup IPA header and register interface
+ * @ifname: Interface name
+ * @mac_addr: Interface MAC address
+ * @prod_client: IPA prod client type
+ * @cons_client: IPA cons client type
+ * @session_id: Session ID
+ * @is_ipv6_enabled: Is IPV6 enabled or not
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
+				   qdf_ipa_client_type_t prod_client,
+				   qdf_ipa_client_type_t cons_client,
+				   uint8_t session_id, bool is_ipv6_enabled)
+{
+	qdf_ipa_wdi_reg_intf_in_params_t in;
+	qdf_ipa_wdi_hdr_info_t hdr_info;
+	struct ol_txrx_ipa_uc_tx_hdr uc_tx_hdr;
+	struct ol_txrx_ipa_uc_tx_hdr uc_tx_hdr_v6;
+	int ret = -EINVAL;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Add Partial hdr: %s, %pM",
+		  __func__, ifname, mac_addr);
+
+	qdf_mem_zero(&hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t));
+	memcpy(&uc_tx_hdr, &ipa_uc_tx_hdr, OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN);
+	qdf_ether_addr_copy(uc_tx_hdr.eth.h_source, mac_addr);
+	uc_tx_hdr.ipa_hd.vdev_id = session_id;
+
+	/* IPV4 header */
+	uc_tx_hdr.eth.h_proto = qdf_htons(ETH_P_IP);
+
+	QDF_IPA_WDI_HDR_INFO_HDR(&hdr_info) = (uint8_t *)&uc_tx_hdr;
+	QDF_IPA_WDI_HDR_INFO_HDR_LEN(&hdr_info) =
+		OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN;
+	QDF_IPA_WDI_HDR_INFO_HDR_TYPE(&hdr_info) = IPA_HDR_L2_ETHERNET_II;
+	QDF_IPA_WDI_HDR_INFO_DST_MAC_ADDR_OFFSET(&hdr_info) =
+		OL_TXRX_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
+
+	QDF_IPA_WDI_REG_INTF_IN_PARAMS_NETDEV_NAME(&in) = ifname;
+	memcpy(&(QDF_IPA_WDI_REG_INTF_IN_PARAMS_HDR_INFO(&in)[IPA_IP_v4]),
+	       &hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t));
+	QDF_IPA_WDI_REG_INTF_IN_PARAMS_ALT_DST_PIPE(&in) = cons_client;
+	QDF_IPA_WDI_REG_INTF_IN_PARAMS_IS_META_DATA_VALID(&in) = 1;
+	QDF_IPA_WDI_REG_INTF_IN_PARAMS_META_DATA(&in) =
+		htonl(session_id << 16);
+	QDF_IPA_WDI_REG_INTF_IN_PARAMS_META_DATA_MASK(&in) = htonl(0x00FF0000);
+
+	/* IPV6 header */
+	if (is_ipv6_enabled) {
+		memcpy(&uc_tx_hdr_v6, &uc_tx_hdr,
+		       OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN);
+		uc_tx_hdr_v6.eth.h_proto = qdf_htons(ETH_P_IPV6);
+		QDF_IPA_WDI_HDR_INFO_HDR(&hdr_info) = (uint8_t *)&uc_tx_hdr_v6;
+		memcpy(&(QDF_IPA_WDI_REG_INTF_IN_PARAMS_HDR_INFO(&in)[IPA_IP_v6]),
+		       &hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t));
+	}
+
+	ret = qdf_ipa_wdi_reg_intf(&in);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: ipa_wdi_reg_intf falied: ret=%d", __func__, ret);
+	}
+
+	return ret;
+}
+
+/**
+ * ol_txrx_ipa_cleanup_iface() - Cleanup IPA header and deregister interface
+ * @ifname: Interface name
+ * @is_ipv6_enabled: Is IPV6 enabled or not
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled)
+{
+	int ret;
+
+	/* unregister the interface with IPA */
+	ret = qdf_ipa_wdi_dereg_intf(ifname);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: ipa_wdi_dereg_intf failed: devname=%s, ret=%d",
+			  __func__, ifname, ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_enable_pipes() - Enable and resume traffic on Tx/Rx pipes
+ * @pdev: handle to the device instance
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	QDF_STATUS status;
+	int ret;
+
+	status = htt_rx_update_smmu_map(pdev->htt_pdev, true);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "IPA SMMU map failed status:%d", status);
+		return status;
+	}
+
+	/* ACTIVATE TX PIPE */
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Enable IPA pipes", __func__);
+	ret = qdf_ipa_wdi_enable_pipes();
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: ipa_wdi_enable_pipes failed: ret=%d",
+				__func__, ret);
+		status = htt_rx_update_smmu_map(pdev->htt_pdev, false);
+		if (status != QDF_STATUS_SUCCESS)
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				  "IPA SMMU unmap failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ol_txrx_ipa_uc_set_active((struct cdp_pdev *)pdev, true, true);
+	ol_txrx_ipa_uc_set_active((struct cdp_pdev *)pdev, true, false);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_disable_pipes() – Suspend traffic and disable Tx/Rx pipes
+ * @pdev: handle to the device instance
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	int ret;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Disable IPA pipes", __func__);
+	ret = qdf_ipa_wdi_disable_pipes();
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: ipa_wdi_disable_pipes failed: ret=%d",
+			  __func__, ret);
+	}
+
+	if (htt_rx_update_smmu_map(pdev->htt_pdev, false) !=
+	    QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "IPA SMMU unmap failed");
+	}
+
+	return ret ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_set_perf_level() - Set IPA clock bandwidth based on data rates
+ * @client: Client type
+ * @max_supported_bw_mbps: Maximum bandwidth needed (in Mbps)
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_set_perf_level(int client,
+				      uint32_t max_supported_bw_mbps)
+{
+	qdf_ipa_wdi_perf_profile_t profile;
+	int result;
+
+	QDF_IPA_WDI_PERF_PROFILE_CLIENT(&profile) = client;
+	QDF_IPA_WDI_PERF_PROFILE_MAX_SUPPORTED_BW_MBPS(&profile) =
+		max_supported_bw_mbps;
+	result = qdf_ipa_wdi_set_perf_profile(&profile);
+
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"Set perf profile failed, code %d", result);
+
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#else /* CONFIG_IPA_WDI_UNIFIED_API */
+
+#ifdef ENABLE_SMMU_S1_TRANSLATION
+/**
+ * ol_txrx_ipa_tx_smmu_params() - Config IPA TX params
+ * @ipa_res: IPA resources
+ * @pipe_in: IPA WDI TX pipe params
+ *
+ * Return: None
+ */
+static inline void ol_txrx_ipa_tx_smmu_params(
+					struct ol_txrx_ipa_resources *ipa_res,
+					qdf_ipa_wdi_in_params_t *pipe_in)
+{
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		    "%s: SMMU Enabled", __func__);
+
+	QDF_IPA_PIPE_IN_SMMU_ENABLED(pipe_in) = true;
+	qdf_mem_copy(&QDF_IPA_PIPE_IN_DL_SMMU_COMP_RING(pipe_in),
+		     &ipa_res->tx_comp_ring->sgtable,
+		     sizeof(sgtable_t));
+	QDF_IPA_PIPE_IN_DL_SMMU_COMP_RING_SIZE(pipe_in) =
+					ipa_res->tx_comp_ring->mem_info.size;
+	qdf_mem_copy(&QDF_IPA_PIPE_IN_DL_SMMU_CE_RING(pipe_in),
+		     &ipa_res->ce_sr->sgtable,
+		     sizeof(sgtable_t));
+	QDF_IPA_PIPE_IN_DL_SMMU_CE_DOOR_BELL_PA(pipe_in) =
+					ipa_res->ce_reg_paddr;
+	QDF_IPA_PIPE_IN_DL_SMMU_CE_RING_SIZE(pipe_in) =
+					ipa_res->ce_sr_ring_size;
+	QDF_IPA_PIPE_IN_DL_SMMU_NUM_TX_BUFFERS(pipe_in) =
+					ipa_res->tx_num_alloc_buffer;
+}
+
+/**
+ * ol_txrx_ipa_rx_smmu_params() - Config IPA TX params
+ * @ipa_res: IPA resources
+ * @pipe_in: IPA WDI TX pipe params
+ *
+ * Return: None
+ */
+static inline void ol_txrx_ipa_rx_smmu_params(
+					struct ol_txrx_ipa_resources *ipa_res,
+					qdf_ipa_wdi_in_params_t *pipe_in)
+{
+	qdf_mem_copy(&QDF_IPA_PIPE_IN_UL_SMMU_RDY_RING(pipe_in),
+		     &ipa_res->rx_rdy_ring->sgtable,
+		     sizeof(sgtable_t));
+	QDF_IPA_PIPE_IN_UL_SMMU_RDY_RING_SIZE(pipe_in) =
+				ipa_res->rx_rdy_ring->mem_info.size;
+	QDF_IPA_PIPE_IN_UL_SMMU_RDY_RING_RP_PA(pipe_in) =
+				ipa_res->rx_proc_done_idx->mem_info.pa;
+
+	QDF_IPA_PIPE_IN_UL_SMMU_RDY_RING_RP_VA(pipe_in) =
+				ipa_res->rx_proc_done_idx->vaddr;
+	qdf_mem_copy(&QDF_IPA_PIPE_IN_UL_SMMU_RDY_COMP_RING(pipe_in),
+		     &ipa_res->rx2_rdy_ring->sgtable,
+		     sizeof(sgtable_t));
+	QDF_IPA_PIPE_IN_UL_SMMU_RDY_COMP_RING_SIZE(pipe_in) =
+				ipa_res->rx2_rdy_ring->mem_info.size;
+	QDF_IPA_PIPE_IN_UL_SMMU_RDY_COMP_RING_WP_PA(pipe_in) =
+				ipa_res->rx2_proc_done_idx->mem_info.pa;
+	QDF_IPA_PIPE_IN_UL_SMMU_RDY_COMP_RING_WP_VA(pipe_in) =
+				ipa_res->rx2_proc_done_idx->vaddr;
+}
+#else
+static inline void ol_txrx_ipa_tx_smmu_params(
+				struct ol_txrx_ipa_resources *ipa_res,
+				qdf_ipa_wdi_in_params_t *pipe_in)
+{
+}
+
+static inline void ol_txrx_ipa_rx_smmu_params(
+				struct ol_txrx_ipa_resources *ipa_res,
+				qdf_ipa_wdi_in_params_t *pipe_in)
+{
+}
+#endif
+
+/**
+ * ol_txrx_ipa_tx_params() - Config IPA TX params
+ * @ipa_res: IPA resources
+ * @pipe_in: IPA WDI TX pipe params
+ *
+ * Return: None
+ */
+static inline void ol_txrx_ipa_tx_params(
+					struct ol_txrx_ipa_resources *ipa_res,
+					qdf_ipa_wdi_in_params_t *pipe_in)
+{
+	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	QDF_IPA_PIPE_IN_DL_COMP_RING_BASE_PA(pipe_in) =
+		qdf_mem_get_dma_addr(osdev,
+				&ipa_res->tx_comp_ring->mem_info);
+	QDF_IPA_PIPE_IN_DL_COMP_RING_SIZE(pipe_in) =
+		ipa_res->tx_comp_ring->mem_info.size;
+	QDF_IPA_PIPE_IN_DL_CE_RING_BASE_PA(pipe_in) =
+		qdf_mem_get_dma_addr(osdev,
+				&ipa_res->ce_sr->mem_info);
+	QDF_IPA_PIPE_IN_DL_CE_DOOR_BELL_PA(pipe_in) =
+		ipa_res->ce_reg_paddr;
+	QDF_IPA_PIPE_IN_DL_CE_RING_SIZE(pipe_in) =
+		ipa_res->ce_sr_ring_size;
+	QDF_IPA_PIPE_IN_DL_NUM_TX_BUFFERS(pipe_in) =
+		ipa_res->tx_num_alloc_buffer;
+}
+
+/**
+ * ol_txrx_ipa_rx_params() - Config IPA RX params
+ * @ipa_res: IPA resources
+ * @pipe_in: IPA WDI RX pipe params
+ *
+ * Return: None
+ */
+static inline void ol_txrx_ipa_rx_params(
+					struct ol_txrx_ipa_resources *ipa_res,
+					qdf_ipa_wdi_in_params_t *pipe_in)
+{
+	QDF_IPA_PIPE_IN_UL_RDY_RING_BASE_PA(pipe_in) =
+		ipa_res->rx_rdy_ring->mem_info.pa;
+	QDF_IPA_PIPE_IN_UL_RDY_RING_SIZE(pipe_in) =
+		ipa_res->rx_rdy_ring->mem_info.size;
+	QDF_IPA_PIPE_IN_UL_RDY_RING_RP_PA(pipe_in) =
+		ipa_res->rx_proc_done_idx->mem_info.pa;
+	OL_TXRX_IPA_WDI2_SET(pipe_in, ipa_res,
+			     cds_get_context(QDF_MODULE_ID_QDF_DEVICE));
+}
+
+/**
+ * ol_txrx_ipa_setup() - Setup and connect IPA pipes
+ * @pdev: handle to the device instance
+ * @ipa_i2w_cb: IPA to WLAN callback
+ * @ipa_w2i_cb: WLAN to IPA callback
+ * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback
+ * @ipa_desc_size: IPA descriptor size
+ * @ipa_priv: handle to the HTT instance
+ * @is_rm_enabled: Is IPA RM enabled or not
+ * @p_tx_pipe_handle: pointer to Tx pipe handle
+ * @p_rx_pipe_handle: pointer to Rx pipe handle
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb,
+			     void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb,
+			     uint32_t ipa_desc_size, void *ipa_priv,
+			     bool is_rm_enabled, uint32_t *p_tx_pipe_handle,
+			     uint32_t *p_rx_pipe_handle)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
+	qdf_ipa_wdi_in_params_t pipe_in;
+	qdf_ipa_wdi_out_params_t pipe_out;
+	uint32_t tx_comp_db_dmaaddr = 0, rx_rdy_db_dmaaddr = 0;
+
+	int ret;
+
+	qdf_mem_zero(&pipe_in, sizeof(pipe_in));
+	qdf_mem_zero(&pipe_out, sizeof(pipe_out));
+
+	/* TX PIPE */
+	QDF_IPA_PIPE_IN_NAT_EN(&pipe_in) = IPA_BYPASS_NAT;
+	QDF_IPA_PIPE_IN_HDR_LEN(&pipe_in) = OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN;
+	QDF_IPA_PIPE_IN_HDR_OFST_PKT_SIZE_VALID(&pipe_in) = 1;
+	QDF_IPA_PIPE_IN_HDR_OFST_PKT_SIZE(&pipe_in) = 0;
+	QDF_IPA_PIPE_IN_HDR_ADDITIONAL_CONST_LEN(&pipe_in) =
+		OL_TXRX_IPA_UC_WLAN_8023_HDR_SIZE;
+	QDF_IPA_PIPE_IN_MODE(&pipe_in) = IPA_BASIC;
+	QDF_IPA_PIPE_IN_CLIENT(&pipe_in) = IPA_CLIENT_WLAN1_CONS;
+	QDF_IPA_PIPE_IN_DESC_FIFO_SZ(&pipe_in) = ipa_desc_size;
+	QDF_IPA_PIPE_IN_PRIV(&pipe_in) = ipa_priv;
+	QDF_IPA_PIPE_IN_HDR_LITTLE_ENDIAN(&pipe_in) = true;
+	QDF_IPA_PIPE_IN_NOTIFY(&pipe_in) = ipa_i2w_cb;
+
+	if (!is_rm_enabled) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			    "%s: IPA RM DISABLED, IPA AWAKE", __func__);
+		QDF_IPA_PIPE_IN_KEEP_IPA_AWAKE(&pipe_in) = true;
+	}
+
+	if (qdf_mem_smmu_s1_enabled(osdev))
+		ol_txrx_ipa_tx_smmu_params(ipa_res, &pipe_in);
+	else
+		ol_txrx_ipa_tx_params(ipa_res, &pipe_in);
+
+	/* Connect WDI IPA PIPE */
+	ret = qdf_ipa_connect_wdi_pipe(&pipe_in, &pipe_out);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		    "ipa_connect_wdi_pipe: Tx pipe setup failed: ret=%d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Micro Controller Doorbell register */
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		"%s CONS DB pipe out 0x%x TX PIPE Handle 0x%x", __func__,
+		(unsigned int)QDF_IPA_PIPE_OUT_UC_DOOR_BELL_PA(&pipe_out),
+		pipe_out.clnt_hdl);
+	ipa_res->tx_comp_doorbell_dmaaddr =
+		QDF_IPA_PIPE_OUT_UC_DOOR_BELL_PA(&pipe_out);
+	/* WLAN TX PIPE Handle */
+	ipa_res->tx_pipe_handle = QDF_IPA_PIPE_OUT_CLNT_HDL(&pipe_out);
+	*p_tx_pipe_handle = QDF_IPA_PIPE_OUT_CLNT_HDL(&pipe_out);
+
+	/* RX PIPE */
+	QDF_IPA_PIPE_IN_NAT_EN(&pipe_in) = IPA_BYPASS_NAT;
+	QDF_IPA_PIPE_IN_HDR_LEN(&pipe_in) = OL_TXRX_IPA_UC_WLAN_RX_HDR_LEN;
+	QDF_IPA_PIPE_IN_HDR_OFST_METADATA_VALID(&pipe_in) = 0;
+	QDF_IPA_PIPE_IN_HDR_METADATA_REG_VALID(&pipe_in) = 1;
+	QDF_IPA_PIPE_IN_MODE(&pipe_in) = IPA_BASIC;
+	QDF_IPA_PIPE_IN_CLIENT(&pipe_in) = IPA_CLIENT_WLAN1_PROD;
+	QDF_IPA_PIPE_IN_DESC_FIFO_SZ(&pipe_in) =
+		ipa_desc_size + SPS_DESC_SIZE;
+	QDF_IPA_PIPE_IN_NOTIFY(&pipe_in) = ipa_w2i_cb;
+	if (!is_rm_enabled) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			    "%s: IPA RM DISABLED, IPA AWAKE", __func__);
+		QDF_IPA_PIPE_IN_KEEP_IPA_AWAKE(&pipe_in) = true;
+	}
+
+	if (qdf_mem_smmu_s1_enabled(osdev))
+		ol_txrx_ipa_rx_smmu_params(ipa_res, &pipe_in);
+	else
+		ol_txrx_ipa_rx_params(ipa_res, &pipe_in);
+
+#ifdef FEATURE_METERING
+	QDF_IPA_PIPE_IN_WDI_NOTIFY(&pipe_in) = ipa_wdi_meter_notifier_cb;
+#endif
+
+	ret = qdf_ipa_connect_wdi_pipe(&pipe_in, &pipe_out);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		    "ipa_connect_wdi_pipe: Rx pipe setup failed: ret=%d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+	ipa_res->rx_ready_doorbell_dmaaddr =
+		QDF_IPA_PIPE_OUT_UC_DOOR_BELL_PA(&pipe_out);
+	ipa_res->rx_pipe_handle = QDF_IPA_PIPE_OUT_CLNT_HDL(&pipe_out);
+	*p_rx_pipe_handle = QDF_IPA_PIPE_OUT_CLNT_HDL(&pipe_out);
+
+	if (qdf_mem_smmu_s1_enabled(osdev)) {
+		pld_smmu_map(osdev->dev, ipa_res->tx_comp_doorbell_dmaaddr,
+			     &tx_comp_db_dmaaddr, sizeof(uint32_t));
+		ipa_res->tx_comp_doorbell_dmaaddr = tx_comp_db_dmaaddr;
+
+		pld_smmu_map(osdev->dev, ipa_res->rx_ready_doorbell_dmaaddr,
+			     &rx_rdy_db_dmaaddr, sizeof(uint32_t));
+		ipa_res->rx_ready_doorbell_dmaaddr = rx_rdy_db_dmaaddr;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_cleanup() - Disconnect IPA pipes
+ * @tx_pipe_handle: Tx pipe handle
+ * @rx_pipe_handle: Rx pipe handle
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_cleanup(uint32_t tx_pipe_handle, uint32_t rx_pipe_handle)
+{
+	int ret;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		    "%s: Disconnect TX PIPE tx_pipe_handle=0x%x",
+		    __func__, tx_pipe_handle);
+	ret = qdf_ipa_disconnect_wdi_pipe(tx_pipe_handle);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		    "ipa_disconnect_wdi_pipe: Tx pipe cleanup failed: ret=%d",
+		    ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		    "%s: Disconnect RX PIPE rx_pipe_handle=0x%x",
+		    __func__, rx_pipe_handle);
+	ret = qdf_ipa_disconnect_wdi_pipe(rx_pipe_handle);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		    "ipa_disconnect_wdi_pipe: Rx pipe cleanup failed: ret=%d",
+		    ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_remove_ipa_header() - Remove a specific header from IPA
+ * @name: Name of the header to be removed
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS ol_txrx_ipa_remove_header(char *name)
+{
+	qdf_ipa_ioc_get_hdr_t hdrlookup;
+	int ret = 0, len;
+	qdf_ipa_ioc_del_hdr_t *ipa_hdr;
+
+	qdf_mem_zero(&hdrlookup, sizeof(hdrlookup));
+	strlcpy(hdrlookup.name, name, sizeof(hdrlookup.name));
+	ret = qdf_ipa_get_hdr(&hdrlookup);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			  "Hdr deleted already %s, %d", name, ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "hdl: 0x%x",
+		  hdrlookup.hdl);
+	len = sizeof(qdf_ipa_ioc_del_hdr_t) + sizeof(qdf_ipa_hdr_del_t) * 1;
+	ipa_hdr = (qdf_ipa_ioc_del_hdr_t *)qdf_mem_malloc(len);
+	if (ipa_hdr == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "ipa_hdr allocation failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	QDF_IPA_IOC_DEL_HDR_NUM_HDRS(ipa_hdr) = 1;
+	QDF_IPA_IOC_DEL_HDR_COMMIT(ipa_hdr) = 0;
+	QDF_IPA_IOC_DEL_HDR_HDL(ipa_hdr) = QDF_IPA_IOC_GET_HDR_HDL(&hdrlookup);
+	QDF_IPA_IOC_DEL_HDR_STATUS(ipa_hdr) = -1;
+	ret = qdf_ipa_del_hdr(ipa_hdr);
+	if (ret != 0) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Delete header failed: %d", ret);
+		qdf_mem_free(ipa_hdr);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_free(ipa_hdr);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_add_header_info() - Add IPA header for a given interface
+ * @ifname: Interface name
+ * @mac_addr: Interface MAC address
+ * @is_ipv6_enabled: Is IPV6 enabled or not
+ *
+ * Return: 0 on success, negativer errno value on error
+ */
+static int ol_txrx_ipa_add_header_info(char *ifname, uint8_t *mac_addr,
+				       uint8_t session_id, bool is_ipv6_enabled)
+{
+	qdf_ipa_ioc_add_hdr_t *ipa_hdr = NULL;
+	int ret = -EINVAL;
+	struct ol_txrx_ipa_uc_tx_hdr *uc_tx_hdr = NULL;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "Add Partial hdr: %s, %pM", ifname, mac_addr);
+
+	/* dynamically allocate the memory to add the hdrs */
+	ipa_hdr = qdf_mem_malloc(sizeof(qdf_ipa_ioc_add_hdr_t)
+				 + sizeof(qdf_ipa_hdr_add_t));
+	if (!ipa_hdr) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			    "%s: ipa_hdr allocation failed", ifname);
+		ret = -ENOMEM;
+		goto end;
+	}
+
+	QDF_IPA_IOC_ADD_HDR_COMMIT(ipa_hdr) = 0;
+	QDF_IPA_IOC_ADD_HDR_NUM_HDRS(ipa_hdr) = 1;
+
+	uc_tx_hdr = (struct ol_txrx_ipa_uc_tx_hdr *)
+		QDF_IPA_IOC_ADD_HDR_HDR(ipa_hdr);
+	memcpy(uc_tx_hdr, &ipa_uc_tx_hdr, OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN);
+	memcpy(uc_tx_hdr->eth.h_source, mac_addr, ETH_ALEN);
+	uc_tx_hdr->ipa_hd.vdev_id = session_id;
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "ifname=%s, vdev_id=%d",
+		  ifname, uc_tx_hdr->ipa_hd.vdev_id);
+	snprintf(QDF_IPA_IOC_ADD_HDR_NAME(ipa_hdr), IPA_RESOURCE_NAME_MAX,
+		 "%s%s", ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
+	QDF_IPA_IOC_ADD_HDR_HDR_LEN(ipa_hdr) = OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN;
+	QDF_IPA_IOC_ADD_HDR_TYPE(ipa_hdr) = IPA_HDR_L2_ETHERNET_II;
+	QDF_IPA_IOC_ADD_HDR_IS_PARTIAL(ipa_hdr) = 1;
+	QDF_IPA_IOC_ADD_HDR_HDR_HDL(ipa_hdr) = 0;
+	QDF_IPA_IOC_ADD_HDR_IS_ETH2_OFST_VALID(ipa_hdr) = 1;
+	QDF_IPA_IOC_ADD_HDR_ETH2_OFST(ipa_hdr) =
+		OL_TXRX_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
+
+	ret = qdf_ipa_add_hdr(ipa_hdr);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s IPv4 add hdr failed: %d", ifname, ret);
+		goto end;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		"%s: IPv4 hdr_hdl: 0x%x",
+		QDF_IPA_IOC_ADD_HDR_NAME(ipa_hdr),
+		QDF_IPA_IOC_ADD_HDR_HDR_HDL(ipa_hdr));
+
+	if (is_ipv6_enabled) {
+		snprintf(QDF_IPA_IOC_ADD_HDR_NAME(ipa_hdr),
+			 IPA_RESOURCE_NAME_MAX, "%s%s",
+			 ifname, OL_TXRX_IPA_IPV6_NAME_EXT);
+
+		uc_tx_hdr = (struct ol_txrx_ipa_uc_tx_hdr *)
+			QDF_IPA_IOC_ADD_HDR_HDR(ipa_hdr);
+		uc_tx_hdr->eth.h_proto = cpu_to_be16(ETH_P_IPV6);
+
+		ret = qdf_ipa_add_hdr(ipa_hdr);
+		if (ret) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				    "%s: IPv6 add hdr failed: %d", ifname, ret);
+			goto clean_ipv4_hdr;
+		}
+
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s: IPv6 hdr_hdl: 0x%x",
+			QDF_IPA_IOC_ADD_HDR_NAME(ipa_hdr),
+			QDF_IPA_IOC_ADD_HDR_HDR_HDL(ipa_hdr));
+	}
+
+	qdf_mem_free(ipa_hdr);
+
+	return ret;
+
+clean_ipv4_hdr:
+	snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+		 ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
+	ol_txrx_ipa_remove_header(ipa_hdr->hdr[0].name);
+end:
+	if (ipa_hdr)
+		qdf_mem_free(ipa_hdr);
+
+	return ret;
+}
+
+/**
+ * ol_txrx_ipa_register_interface() - register IPA interface
+ * @ifname: Interface name
+ * @prod_client: IPA prod client type
+ * @cons_client: IPA cons client type
+ * @session_id: Session ID
+ * @is_ipv6_enabled: Is IPV6 enabled or not
+ *
+ * Return: 0 on success, negative errno on error
+ */
+static int ol_txrx_ipa_register_interface(char *ifname,
+					  qdf_ipa_client_type_t prod_client,
+					  qdf_ipa_client_type_t cons_client,
+					  uint8_t session_id,
+					  bool is_ipv6_enabled)
+{
+	qdf_ipa_tx_intf_t tx_intf;
+	qdf_ipa_rx_intf_t rx_intf;
+	qdf_ipa_ioc_tx_intf_prop_t *tx_prop = NULL;
+	qdf_ipa_ioc_rx_intf_prop_t *rx_prop = NULL;
+
+	char ipv4_hdr_name[IPA_RESOURCE_NAME_MAX];
+	char ipv6_hdr_name[IPA_RESOURCE_NAME_MAX];
+
+	int num_prop = 1;
+	int ret = 0;
+
+	if (is_ipv6_enabled)
+		num_prop++;
+
+	/* Allocate TX properties for TOS categories, 1 each for IPv4 & IPv6 */
+	tx_prop =
+		qdf_mem_malloc(sizeof(qdf_ipa_ioc_tx_intf_prop_t) * num_prop);
+	if (!tx_prop) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "tx_prop allocation failed");
+		goto register_interface_fail;
+	}
+
+	/* Allocate RX properties, 1 each for IPv4 & IPv6 */
+	rx_prop =
+		qdf_mem_malloc(sizeof(qdf_ipa_ioc_rx_intf_prop_t) * num_prop);
+	if (!rx_prop) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "rx_prop allocation failed");
+		goto register_interface_fail;
+	}
+
+	qdf_mem_zero(&tx_intf, sizeof(tx_intf));
+	qdf_mem_zero(&rx_intf, sizeof(rx_intf));
+
+	snprintf(ipv4_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s",
+		 ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
+	snprintf(ipv6_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s",
+		 ifname, OL_TXRX_IPA_IPV6_NAME_EXT);
+
+	QDF_IPA_IOC_RX_INTF_PROP_IP(&rx_prop[IPA_IP_v4]) = IPA_IP_v4;
+	QDF_IPA_IOC_RX_INTF_PROP_SRC_PIPE(&rx_prop[IPA_IP_v4]) = prod_client;
+	QDF_IPA_IOC_RX_INTF_PROP_HDR_L2_TYPE(&rx_prop[IPA_IP_v4]) =
+		IPA_HDR_L2_ETHERNET_II;
+	QDF_IPA_IOC_RX_INTF_PROP_ATTRIB_MASK(&rx_prop[IPA_IP_v4]) =
+		IPA_FLT_META_DATA;
+
+	/*
+	 * Interface ID is 3rd byte in the CLD header. Add the meta data and
+	 * mask to identify the interface in IPA hardware
+	 */
+	QDF_IPA_IOC_RX_INTF_PROP_META_DATA(&rx_prop[IPA_IP_v4]) =
+		htonl(session_id << 16);
+	QDF_IPA_IOC_RX_INTF_PROP_META_DATA_MASK(&rx_prop[IPA_IP_v4]) =
+		htonl(0x00FF0000);
+
+	rx_intf.num_props++;
+	if (is_ipv6_enabled) {
+		QDF_IPA_IOC_RX_INTF_PROP_IP(&rx_prop[IPA_IP_v6]) = IPA_IP_v6;
+		QDF_IPA_IOC_RX_INTF_PROP_SRC_PIPE(&rx_prop[IPA_IP_v6]) =
+			prod_client;
+		QDF_IPA_IOC_RX_INTF_PROP_HDR_L2_TYPE(&rx_prop[IPA_IP_v6]) =
+			IPA_HDR_L2_ETHERNET_II;
+		QDF_IPA_IOC_RX_INTF_PROP_ATTRIB_MASK(&rx_prop[IPA_IP_v6]) =
+			IPA_FLT_META_DATA;
+		QDF_IPA_IOC_RX_INTF_PROP_META_DATA(&rx_prop[IPA_IP_v6]) =
+			htonl(session_id << 16);
+		QDF_IPA_IOC_RX_INTF_PROP_META_DATA_MASK(&rx_prop[IPA_IP_v6]) =
+			htonl(0x00FF0000);
+
+		rx_intf.num_props++;
+	}
+
+	QDF_IPA_IOC_TX_INTF_PROP_IP(&tx_prop[IPA_IP_v4]) = IPA_IP_v4;
+	QDF_IPA_IOC_TX_INTF_PROP_HDR_L2_TYPE(&tx_prop[IPA_IP_v4]) =
+			IPA_HDR_L2_ETHERNET_II;
+	QDF_IPA_IOC_TX_INTF_PROP_DST_PIPE(&tx_prop[IPA_IP_v4]) =
+			IPA_CLIENT_WLAN1_CONS;
+	QDF_IPA_IOC_TX_INTF_PROP_ALT_DST_PIPE(&tx_prop[IPA_IP_v4]) =
+			cons_client;
+	strlcpy(QDF_IPA_IOC_TX_INTF_PROP_HDR_NAME(&tx_prop[IPA_IP_v4]),
+		ipv4_hdr_name, IPA_RESOURCE_NAME_MAX);
+	tx_intf.num_props++;
+
+	if (is_ipv6_enabled) {
+		QDF_IPA_IOC_TX_INTF_PROP_IP(&tx_prop[IPA_IP_v6]) = IPA_IP_v6;
+		QDF_IPA_IOC_TX_INTF_PROP_HDR_L2_TYPE(&tx_prop[IPA_IP_v6]) =
+			IPA_HDR_L2_ETHERNET_II;
+		QDF_IPA_IOC_TX_INTF_PROP_DST_PIPE(&tx_prop[IPA_IP_v6]) =
+			IPA_CLIENT_WLAN1_CONS;
+		QDF_IPA_IOC_TX_INTF_PROP_ALT_DST_PIPE(&tx_prop[IPA_IP_v6]) =
+			cons_client;
+		strlcpy(QDF_IPA_IOC_TX_INTF_PROP_HDR_NAME(&tx_prop[IPA_IP_v6]),
+			ipv6_hdr_name, IPA_RESOURCE_NAME_MAX);
+		tx_intf.num_props++;
+	}
+
+	QDF_IPA_TX_INTF_PROP(&tx_intf) = tx_prop;
+	QDF_IPA_RX_INTF_PROP(&rx_intf) = rx_prop;
+
+	/* Call the ipa api to register interface */
+	ret = qdf_ipa_register_intf(ifname, &tx_intf, &rx_intf);
+
+register_interface_fail:
+	qdf_mem_free(tx_prop);
+	qdf_mem_free(rx_prop);
+	return ret;
+}
+
+/**
+ * ol_txrx_ipa_setup_iface() - Setup IPA header and register interface
+ * @ifname: Interface name
+ * @mac_addr: Interface MAC address
+ * @prod_client: IPA prod client type
+ * @cons_client: IPA cons client type
+ * @session_id: Session ID
+ * @is_ipv6_enabled: Is IPV6 enabled or not
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
+				   qdf_ipa_client_type_t prod_client,
+				   qdf_ipa_client_type_t cons_client,
+				   uint8_t session_id, bool is_ipv6_enabled)
+{
+	int ret;
+
+	ret = ol_txrx_ipa_add_header_info(ifname, mac_addr, session_id,
+					  is_ipv6_enabled);
+	if (ret)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Configure the TX and RX pipes filter rules */
+	ret = ol_txrx_ipa_register_interface(ifname,
+					     prod_client,
+					     cons_client,
+					     session_id, is_ipv6_enabled);
+	if (ret)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_cleanup_iface() - Cleanup IPA header and deregister interface
+ * @ifname: Interface name
+ * @is_ipv6_enabled: Is IPV6 enabled or not
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled)
+{
+	char name_ipa[IPA_RESOURCE_NAME_MAX];
+	int ret;
+
+	/* Remove the headers */
+	snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s",
+			ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
+	ol_txrx_ipa_remove_header(name_ipa);
+
+	if (is_ipv6_enabled) {
+		snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s",
+				ifname, OL_TXRX_IPA_IPV6_NAME_EXT);
+		ol_txrx_ipa_remove_header(name_ipa);
+	}
+	/* unregister the interface with IPA */
+	ret = qdf_ipa_deregister_intf(ifname);
+	if (ret) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+				"%s: ipa_deregister_intf fail: %d",
+				ifname, ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_uc_enable_pipes() - Enable and resume traffic on Tx/Rx pipes
+ * @pdev: handle to the device instance
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
+	int result;
+	QDF_STATUS status;
+
+	status = htt_rx_update_smmu_map(pdev->htt_pdev, true);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "IPA SMMU map failed status:%d", status);
+		return status;
+	}
+
+	/* ACTIVATE TX PIPE */
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s: Enable TX PIPE(tx_pipe_handle=%d)",
+			__func__, ipa_res->tx_pipe_handle);
+	result = qdf_ipa_enable_wdi_pipe(ipa_res->tx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Enable TX PIPE fail, code %d",
+				__func__, result);
+		goto smmu_unmap;
+	}
+	result = qdf_ipa_resume_wdi_pipe(ipa_res->tx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Resume TX PIPE fail, code %d",
+				__func__, result);
+		goto smmu_unmap;
+	}
+	ol_txrx_ipa_uc_set_active((struct cdp_pdev *)pdev, true, true);
+
+	/* ACTIVATE RX PIPE */
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s: Enable RX PIPE(rx_pipe_handle=%d)",
+			__func__, ipa_res->rx_pipe_handle);
+	result = qdf_ipa_enable_wdi_pipe(ipa_res->rx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Enable RX PIPE fail, code %d",
+				__func__, result);
+		goto smmu_unmap;
+	}
+	result = qdf_ipa_resume_wdi_pipe(ipa_res->rx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Resume RX PIPE fail, code %d",
+				__func__, result);
+		goto smmu_unmap;
+	}
+	ol_txrx_ipa_uc_set_active((struct cdp_pdev *)pdev, true, false);
+
+	return QDF_STATUS_SUCCESS;
+
+smmu_unmap:
+	if (htt_rx_update_smmu_map(pdev->htt_pdev, false) !=
+	    QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "IPA SMMU unmap failed");
+	}
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * ol_txrx_ipa_uc_disable_pipes() – Suspend traffic and disable Tx/Rx pipes
+ * @pdev: handle to the device instance
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_pdev *ppdev)
+{
+	ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev;
+	struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
+	int result;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s: Disable RX PIPE", __func__);
+	result = qdf_ipa_suspend_wdi_pipe(ipa_res->rx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Suspend RX PIPE fail, code %d",
+				__func__, result);
+		goto smmu_unmap;
+	}
+
+	result = qdf_ipa_disable_wdi_pipe(ipa_res->rx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Disable RX PIPE fail, code %d",
+				__func__, result);
+		goto smmu_unmap;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"%s: Disable TX PIPE", __func__);
+	result = qdf_ipa_suspend_wdi_pipe(ipa_res->tx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Suspend TX PIPE fail, code %d",
+				__func__, result);
+		goto smmu_unmap;
+	}
+	result = qdf_ipa_disable_wdi_pipe(ipa_res->tx_pipe_handle);
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"%s: Disable TX PIPE fail, code %d",
+				__func__, result);
+		goto smmu_unmap;
+	}
+
+smmu_unmap:
+	if (htt_rx_update_smmu_map(pdev->htt_pdev, false) !=
+	    QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "IPA SMMU unmap failed");
+	}
+
+	return result ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
+}
+
+/**
+ * ol_txrx_ipa_set_perf_level() - Set IPA clock bandwidth based on data rates
+ * @client: Client type
+ * @max_supported_bw_mbps: Maximum bandwidth needed (in Mbps)
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ol_txrx_ipa_set_perf_level(int client,
+				      uint32_t max_supported_bw_mbps)
+{
+	qdf_ipa_rm_resource_name_t resource_name;
+	qdf_ipa_rm_perf_profile_t profile;
+	int result;
+
+	if (client == QDF_IPA_CLIENT_WLAN1_PROD) {
+		resource_name = QDF_IPA_RM_RESOURCE_WLAN_PROD;
+	} else if (client == QDF_IPA_CLIENT_WLAN1_CONS) {
+		resource_name = QDF_IPA_RM_RESOURCE_WLAN_CONS;
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"not supported client %d", client);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	QDF_IPA_RM_PERF_PROFILE_MAX_SUPPORTED_BANDWIDTH_MBPS(&profile) =
+		max_supported_bw_mbps;
+	result = qdf_ipa_rm_set_perf_profile(resource_name, &profile);
+
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+				"Set perf profile failed, code %d", result);
+
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif /* CONFIG_IPA_WDI_UNIFIED_API */
+
+#ifdef FEATURE_METERING
+QDF_STATUS ol_txrx_ipa_uc_get_share_stats(struct cdp_pdev *ppdev,
+					   uint8_t reset_stats)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	int result;
+
+	result = htt_h2t_ipa_uc_get_share_stats(pdev->htt_pdev, reset_stats);
+
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Get IPA sharing stats failed, code %d", result);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ol_txrx_ipa_uc_set_quota(struct cdp_pdev *ppdev,
+				     uint64_t quota_bytes)
+{
+	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev;
+	int result;
+
+	result = htt_h2t_ipa_uc_set_quota(pdev->htt_pdev, quota_bytes);
+
+	if (result) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Set IPA quota failed, code %d", result);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#endif /* IPA_UC_OFFLOAD */
diff --git a/core/dp/txrx/ol_txrx_ipa.h b/core/dp/txrx/ol_txrx_ipa.h
new file mode 100644
index 0000000..cadf1a0
--- /dev/null
+++ b/core/dp/txrx/ol_txrx_ipa.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2017-2018, 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.
+ */
+
+#ifndef _OL_TXRX_IPA_H_
+#define _OL_TXRX_IPA_H_
+
+#ifdef IPA_OFFLOAD
+
+#include <cdp_txrx_cmn.h>       /* ol_txrx_vdev_t, etc. */
+#include <ol_txrx_types.h>
+
+/**
+ * struct frag_header - fragment header type registered to IPA hardware
+ * @length:    fragment length
+ * @reserved1: Reserved not used
+ * @reserved2: Reserved not used
+ *
+ */
+#ifdef QCA_WIFI_3_0
+struct frag_header {
+	uint16_t length;
+	uint32_t reserved1;
+	uint32_t reserved2;
+} __packed;
+#else
+struct frag_header {
+	uint32_t
+		length:16,
+		reserved16:16;
+	uint32_t reserved2;
+} __packed;
+#endif
+
+/**
+ * struct ipa_header - ipa header type registered to IPA hardware
+ * @vdev_id:  vdev id
+ * @reserved: Reserved not used
+ *
+ */
+struct ipa_header {
+	uint32_t
+		vdev_id:8,      /* vdev_id field is LSB of IPA DESC */
+		reserved:24;
+} __packed;
+
+/**
+ * struct ol_txrx_ipa_uc_tx_hdr - full tx header registered to IPA hardware
+ * @frag_hd: fragment header
+ * @ipa_hd:  ipa header
+ * @eth:     ether II header
+ *
+ */
+struct ol_txrx_ipa_uc_tx_hdr {
+	struct frag_header frag_hd;
+	struct ipa_header ipa_hd;
+	struct ethhdr eth;
+} __packed;
+
+/**
+ * struct ol_txrx_ipa_uc_rx_hdr - full rx header registered to IPA hardware
+ * @eth:     ether II header
+ *
+ */
+struct ol_txrx_ipa_uc_rx_hdr {
+	struct ethhdr eth;
+} __packed;
+
+#define OL_TXRX_IPA_UC_WLAN_8023_HDR_SIZE      14
+
+#define OL_TXRX_IPA_IPV4_NAME_EXT              "_ipv4"
+#define OL_TXRX_IPA_IPV6_NAME_EXT              "_ipv6"
+
+#define OL_TXRX_IPA_MAX_IFACE                  3
+
+#define OL_TXRX_IPA_WLAN_FRAG_HEADER        sizeof(struct frag_header)
+#define OL_TXRX_IPA_WLAN_IPA_HEADER         sizeof(struct ipa_header)
+#define OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN      sizeof(struct ol_txrx_ipa_uc_tx_hdr)
+#define OL_TXRX_IPA_UC_WLAN_RX_HDR_LEN      sizeof(struct ol_txrx_ipa_uc_rx_hdr)
+#define OL_TXRX_IPA_UC_WLAN_HDR_DES_MAC_OFFSET \
+	(OL_TXRX_IPA_WLAN_FRAG_HEADER + OL_TXRX_IPA_WLAN_IPA_HEADER)
+
+#if defined(QCA_WIFI_3_0) && defined(CONFIG_IPA3)
+#define OL_TXRX_IPA_WDI2_SET(pipe_in, ipa_res, osdev) \
+	do { \
+		QDF_IPA_PIPE_IN_UL_RDY_RING_RP_VA(pipe_in) = \
+			ipa_res->rx_proc_done_idx->vaddr; \
+		QDF_IPA_PIPE_IN_UL_RDY_COMP_RING(pipe_in) = \
+			qdf_mem_get_dma_addr(osdev, \
+				&ipa_res->rx2_rdy_ring->mem_info);\
+		QDF_IPA_PIPE_IN_UL_RDY_COMP_RING_SIZE(pipe_in) = \
+			ipa_res->rx2_rdy_ring->mem_info.size; \
+		QDF_IPA_PIPE_IN_UL_RDY_COMP_RING_WP_PA(pipe_in) = \
+			qdf_mem_get_dma_addr(osdev, \
+				&ipa_res->rx2_proc_done_idx->mem_info); \
+		QDF_IPA_PIPE_IN_UL_RDY_COMP_RING_WP_VA(pipe_in) = \
+			ipa_res->rx2_proc_done_idx->vaddr; \
+	} while (0)
+#else
+/* Do nothing */
+#define OL_TXRX_IPA_WDI2_SET(pipe_in, ipa_res, osdev)
+#endif /* IPA3 */
+
+QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_uc_set_active(struct cdp_pdev *pdev, bool uc_active,
+		bool is_tx);
+QDF_STATUS ol_txrx_ipa_uc_op_response(struct cdp_pdev *pdev, uint8_t *op_msg);
+QDF_STATUS ol_txrx_ipa_uc_register_op_cb(struct cdp_pdev *pdev,
+		ipa_uc_op_cb_type op_cb, void *usr_ctxt);
+QDF_STATUS ol_txrx_ipa_uc_get_stat(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_enable_autonomy(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_disable_autonomy(struct cdp_pdev *pdev);
+#ifdef CONFIG_IPA_WDI_UNIFIED_API
+QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *pdev, void *ipa_i2w_cb,
+		void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb,
+		uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled,
+		uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle,
+		bool is_smmu_enabled, qdf_ipa_sys_connect_params_t *sys_in);
+#else /* CONFIG_IPA_WDI_UNIFIED_API */
+QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *pdev, void *ipa_i2w_cb,
+		void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb,
+		uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled,
+		uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle);
+#endif /* CONFIG_IPA_WDI_UNIFIED_API */
+QDF_STATUS ol_txrx_ipa_cleanup(uint32_t tx_pipe_handle,
+		uint32_t rx_pipe_handle);
+QDF_STATUS ol_txrx_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
+		qdf_ipa_client_type_t prod_client,
+		qdf_ipa_client_type_t cons_client,
+		uint8_t session_id, bool is_ipv6_enabled);
+QDF_STATUS ol_txrx_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled);
+QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_pdev *pdev);
+QDF_STATUS ol_txrx_ipa_set_perf_level(int client,
+		uint32_t max_supported_bw_mbps);
+#ifdef FEATURE_METERING
+QDF_STATUS ol_txrx_ipa_uc_get_share_stats(struct cdp_pdev *pdev,
+		uint8_t reset_stats);
+QDF_STATUS ol_txrx_ipa_uc_set_quota(struct cdp_pdev *pdev,
+		uint64_t quota_bytes);
+#endif
+#endif
+#endif /* _OL_TXRX_IPA_H_*/
diff --git a/core/dp/txrx/ol_txrx_legacy_flow_control.c b/core/dp/txrx/ol_txrx_legacy_flow_control.c
new file mode 100644
index 0000000..2b72a5a
--- /dev/null
+++ b/core/dp/txrx/ol_txrx_legacy_flow_control.c
@@ -0,0 +1,650 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/* OS abstraction libraries */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_atomic.h>         /* qdf_atomic_read, etc. */
+#include <qdf_util.h>           /* qdf_unlikely */
+
+/* APIs for other modules */
+#include <htt.h>                /* HTT_TX_EXT_TID_MGMT */
+#include <ol_htt_tx_api.h>      /* htt_tx_desc_tid */
+
+/* internal header files relevant for all systems */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT1 */
+#include <ol_tx_desc.h>         /* ol_tx_desc */
+#include <ol_tx_send.h>         /* ol_tx_send */
+#include <ol_txrx.h>            /* ol_txrx_get_vdev_from_vdev_id */
+
+/* internal header files relevant only for HL systems */
+#include <ol_tx_queue.h>        /* ol_tx_enqueue */
+
+/* internal header files relevant only for specific systems (Pronto) */
+#include <ol_txrx_encap.h>      /* OL_TX_ENCAP, etc */
+#include <ol_tx.h>
+#include <ol_cfg.h>
+#include <cdp_txrx_handle.h>
+
+/**
+ * ol_txrx_vdev_pause- Suspend all tx data for the specified virtual device
+ *
+ * @data_vdev - the virtual device being paused
+ * @reason - the reason for which vdev queue is getting paused
+ *
+ * This function applies primarily to HL systems, but also
+ * applies to LL systems that use per-vdev tx queues for MCC or
+ * thermal throttling. As an example, this function could be
+ * used when a single-channel physical device supports multiple
+ * channels by jumping back and forth between the channels in a
+ * time-shared manner.  As the device is switched from channel A
+ * to channel B, the virtual devices that operate on channel A
+ * will be paused.
+ *
+ */
+void ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	/* TO DO: log the queue pause */
+	/* acquire the mutex lock, since we'll be modifying the queues */
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+
+	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
+	vdev->ll_pause.paused_reason |= reason;
+	vdev->ll_pause.q_pause_cnt++;
+	vdev->ll_pause.is_q_paused = true;
+	qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+}
+
+/**
+ * ol_txrx_vdev_unpause - Resume tx for the specified virtual device
+ *
+ * @data_vdev - the virtual device being unpaused
+ * @reason - the reason for which vdev queue is getting unpaused
+ *
+ * This function applies primarily to HL systems, but also applies to
+ * LL systems that use per-vdev tx queues for MCC or thermal throttling.
+ *
+ */
+void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+	/* TO DO: log the queue unpause */
+	/* acquire the mutex lock, since we'll be modifying the queues */
+	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
+
+	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
+	if (vdev->ll_pause.paused_reason & reason) {
+		vdev->ll_pause.paused_reason &= ~reason;
+		if (!vdev->ll_pause.paused_reason) {
+			vdev->ll_pause.is_q_paused = false;
+			vdev->ll_pause.q_unpause_cnt++;
+			qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+			ol_tx_vdev_ll_pause_queue_send((void *)vdev);
+		} else {
+			qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+		}
+	} else {
+		qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+	}
+	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
+}
+
+/**
+ * ol_txrx_vdev_flush - Drop all tx data for the specified virtual device
+ *
+ * @data_vdev - the virtual device being flushed
+ *
+ *  This function applies primarily to HL systems, but also applies to
+ *  LL systems that use per-vdev tx queues for MCC or thermal throttling.
+ *  This function would typically be used by the ctrl SW after it parks
+ *  a STA vdev and then resumes it, but to a new AP.  In this case, though
+ *  the same vdev can be used, any old tx frames queued inside it would be
+ *  stale, and would need to be discarded.
+ *
+ */
+void ol_txrx_vdev_flush(struct cdp_vdev *pvdev)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
+	qdf_timer_stop(&vdev->ll_pause.timer);
+	vdev->ll_pause.is_q_timer_on = false;
+	while (vdev->ll_pause.txq.head) {
+		qdf_nbuf_t next =
+			qdf_nbuf_next(vdev->ll_pause.txq.head);
+		qdf_nbuf_set_next(vdev->ll_pause.txq.head, NULL);
+		if (QDF_NBUF_CB_PADDR(vdev->ll_pause.txq.head)) {
+			if (!qdf_nbuf_ipa_owned_get(vdev->ll_pause.txq.head))
+				qdf_nbuf_unmap(vdev->pdev->osdev,
+					       vdev->ll_pause.txq.head,
+					       QDF_DMA_TO_DEVICE);
+			else if (qdf_mem_smmu_s1_enabled(vdev->pdev->osdev))
+				qdf_nbuf_unmap(vdev->pdev->osdev,
+					       vdev->ll_pause.txq.head,
+					       QDF_DMA_TO_DEVICE);
+		}
+		qdf_nbuf_tx_free(vdev->ll_pause.txq.head,
+				 QDF_NBUF_PKT_ERROR);
+		vdev->ll_pause.txq.head = next;
+	}
+	vdev->ll_pause.txq.tail = NULL;
+	vdev->ll_pause.txq.depth = 0;
+	qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+}
+
+#define OL_TX_VDEV_PAUSE_QUEUE_SEND_MARGIN 400
+#define OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS 5
+
+static void ol_tx_vdev_ll_pause_queue_send_base(struct ol_txrx_vdev_t *vdev)
+{
+	int max_to_accept;
+
+	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
+	if (vdev->ll_pause.paused_reason) {
+		qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+		return;
+	}
+
+	/*
+	 * Send as much of the backlog as possible, but leave some margin
+	 * of unallocated tx descriptors that can be used for new frames
+	 * being transmitted by other vdevs.
+	 * Ideally there would be a scheduler, which would not only leave
+	 * some margin for new frames for other vdevs, but also would
+	 * fairly apportion the tx descriptors between multiple vdevs that
+	 * have backlogs in their pause queues.
+	 * However, the fairness benefit of having a scheduler for frames
+	 * from multiple vdev's pause queues is not sufficient to outweigh
+	 * the extra complexity.
+	 */
+	max_to_accept = vdev->pdev->tx_desc.num_free -
+		OL_TX_VDEV_PAUSE_QUEUE_SEND_MARGIN;
+	while (max_to_accept > 0 && vdev->ll_pause.txq.depth) {
+		qdf_nbuf_t tx_msdu;
+
+		max_to_accept--;
+		vdev->ll_pause.txq.depth--;
+		tx_msdu = vdev->ll_pause.txq.head;
+		if (tx_msdu) {
+			vdev->ll_pause.txq.head = qdf_nbuf_next(tx_msdu);
+			if (!vdev->ll_pause.txq.head)
+				vdev->ll_pause.txq.tail = NULL;
+			qdf_nbuf_set_next(tx_msdu, NULL);
+			QDF_NBUF_UPDATE_TX_PKT_COUNT(tx_msdu,
+						QDF_NBUF_TX_PKT_TXRX_DEQUEUE);
+			tx_msdu = ol_tx_ll_wrapper(vdev, tx_msdu);
+			/*
+			 * It is unexpected that ol_tx_ll would reject the frame
+			 * since we checked that there's room for it, though
+			 * there's an infinitesimal possibility that between the
+			 * time we checked the room available and now, a
+			 * concurrent batch of tx frames used up all the room.
+			 * For simplicity, just drop the frame.
+			 */
+			if (tx_msdu) {
+				qdf_nbuf_unmap(vdev->pdev->osdev, tx_msdu,
+					       QDF_DMA_TO_DEVICE);
+				qdf_nbuf_tx_free(tx_msdu, QDF_NBUF_PKT_ERROR);
+			}
+		}
+	}
+	if (vdev->ll_pause.txq.depth) {
+		qdf_timer_stop(&vdev->ll_pause.timer);
+		if (!qdf_atomic_read(&vdev->delete.detaching)) {
+			qdf_timer_start(&vdev->ll_pause.timer,
+					OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS);
+			vdev->ll_pause.is_q_timer_on = true;
+		}
+		if (vdev->ll_pause.txq.depth >= vdev->ll_pause.max_q_depth)
+			vdev->ll_pause.q_overflow_cnt++;
+	}
+
+	qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+}
+
+static qdf_nbuf_t
+ol_tx_vdev_pause_queue_append(struct ol_txrx_vdev_t *vdev,
+			      qdf_nbuf_t msdu_list, uint8_t start_timer)
+{
+	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
+	while (msdu_list &&
+	       vdev->ll_pause.txq.depth < vdev->ll_pause.max_q_depth) {
+		qdf_nbuf_t next = qdf_nbuf_next(msdu_list);
+
+		QDF_NBUF_UPDATE_TX_PKT_COUNT(msdu_list,
+					     QDF_NBUF_TX_PKT_TXRX_ENQUEUE);
+		DPTRACE(qdf_dp_trace(msdu_list,
+			QDF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD,
+			QDF_TRACE_DEFAULT_PDEV_ID,
+			qdf_nbuf_data_addr(msdu_list),
+			sizeof(qdf_nbuf_data(msdu_list)), QDF_TX));
+
+		vdev->ll_pause.txq.depth++;
+		if (!vdev->ll_pause.txq.head) {
+			vdev->ll_pause.txq.head = msdu_list;
+			vdev->ll_pause.txq.tail = msdu_list;
+		} else {
+			qdf_nbuf_set_next(vdev->ll_pause.txq.tail, msdu_list);
+		}
+		vdev->ll_pause.txq.tail = msdu_list;
+
+		msdu_list = next;
+	}
+	if (vdev->ll_pause.txq.tail)
+		qdf_nbuf_set_next(vdev->ll_pause.txq.tail, NULL);
+
+	if (start_timer) {
+		qdf_timer_stop(&vdev->ll_pause.timer);
+		if (!qdf_atomic_read(&vdev->delete.detaching)) {
+			qdf_timer_start(&vdev->ll_pause.timer,
+					OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS);
+			vdev->ll_pause.is_q_timer_on = true;
+		}
+	}
+	qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+
+	return msdu_list;
+}
+
+/*
+ * Store up the tx frame in the vdev's tx queue if the vdev is paused.
+ * If there are too many frames in the tx queue, reject it.
+ */
+qdf_nbuf_t ol_tx_ll_queue(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
+{
+	uint16_t eth_type;
+	uint32_t paused_reason;
+
+	if (!msdu_list)
+		return NULL;
+
+	paused_reason = vdev->ll_pause.paused_reason;
+	if (paused_reason) {
+		if (qdf_unlikely((paused_reason &
+				  OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED) ==
+				 paused_reason)) {
+			eth_type = (((struct ethernet_hdr_t *)
+				     qdf_nbuf_data(msdu_list))->
+				    ethertype[0] << 8) |
+				   (((struct ethernet_hdr_t *)
+				     qdf_nbuf_data(msdu_list))->ethertype[1]);
+			if (ETHERTYPE_IS_EAPOL_WAPI(eth_type)) {
+				msdu_list = ol_tx_ll_wrapper(vdev, msdu_list);
+				return msdu_list;
+			}
+		}
+		msdu_list = ol_tx_vdev_pause_queue_append(vdev, msdu_list, 1);
+	} else {
+		if (vdev->ll_pause.txq.depth > 0 ||
+		    vdev->pdev->tx_throttle.current_throttle_level !=
+		    THROTTLE_LEVEL_0) {
+			/*
+			 * not paused, but there is a backlog of frms
+			 * from a prior pause or throttle off phase
+			 */
+			msdu_list = ol_tx_vdev_pause_queue_append(
+				vdev, msdu_list, 0);
+			/*
+			 * if throttle is disabled or phase is "on",
+			 * send the frame
+			 */
+			if (vdev->pdev->tx_throttle.current_throttle_level ==
+			    THROTTLE_LEVEL_0 ||
+			    vdev->pdev->tx_throttle.current_throttle_phase ==
+			    THROTTLE_PHASE_ON) {
+				/*
+				 * send as many frames as possible
+				 * from the vdevs backlog
+				 */
+				ol_tx_vdev_ll_pause_queue_send_base(vdev);
+			}
+		} else {
+			/*
+			 * not paused, no throttle and no backlog -
+			 * send the new frames
+			 */
+			msdu_list = ol_tx_ll_wrapper(vdev, msdu_list);
+		}
+	}
+	return msdu_list;
+}
+
+/*
+ * Run through the transmit queues for all the vdevs and
+ * send the pending frames
+ */
+void ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev)
+{
+	int max_to_send;        /* tracks how many frames have been sent */
+	qdf_nbuf_t tx_msdu;
+	struct ol_txrx_vdev_t *vdev = NULL;
+	uint8_t more;
+
+	if (!pdev)
+		return;
+
+	if (pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_OFF)
+		return;
+
+	/* ensure that we send no more than tx_threshold frames at once */
+	max_to_send = pdev->tx_throttle.tx_threshold;
+
+	/* round robin through the vdev queues for the given pdev */
+
+	/*
+	 * Potential improvement: download several frames from the same vdev
+	 * at a time, since it is more likely that those frames could be
+	 * aggregated together, remember which vdev was serviced last,
+	 * so the next call this function can resume the round-robin
+	 * traversing where the current invocation left off
+	 */
+	do {
+		more = 0;
+		TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+			qdf_spin_lock_bh(&vdev->ll_pause.mutex);
+			if (vdev->ll_pause.txq.depth) {
+				if (vdev->ll_pause.paused_reason) {
+					qdf_spin_unlock_bh(&vdev->ll_pause.
+							   mutex);
+					continue;
+				}
+
+				tx_msdu = vdev->ll_pause.txq.head;
+				if (!tx_msdu) {
+					qdf_spin_unlock_bh(&vdev->ll_pause.
+							   mutex);
+					continue;
+				}
+
+				max_to_send--;
+				vdev->ll_pause.txq.depth--;
+
+				vdev->ll_pause.txq.head =
+					qdf_nbuf_next(tx_msdu);
+
+				if (!vdev->ll_pause.txq.head)
+					vdev->ll_pause.txq.tail = NULL;
+
+				qdf_nbuf_set_next(tx_msdu, NULL);
+				tx_msdu = ol_tx_ll_wrapper(vdev, tx_msdu);
+				/*
+				 * It is unexpected that ol_tx_ll would reject
+				 * the frame, since we checked that there's
+				 * room for it, though there's an infinitesimal
+				 * possibility that between the time we checked
+				 * the room available and now, a concurrent
+				 * batch of tx frames used up all the room.
+				 * For simplicity, just drop the frame.
+				 */
+				if (tx_msdu) {
+					qdf_nbuf_unmap(pdev->osdev, tx_msdu,
+						       QDF_DMA_TO_DEVICE);
+					qdf_nbuf_tx_free(tx_msdu,
+							 QDF_NBUF_PKT_ERROR);
+				}
+			}
+			/*check if there are more msdus to transmit */
+			if (vdev->ll_pause.txq.depth)
+				more = 1;
+			qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+		}
+	} while (more && max_to_send);
+
+	vdev = NULL;
+	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+		qdf_spin_lock_bh(&vdev->ll_pause.mutex);
+		if (vdev->ll_pause.txq.depth) {
+			qdf_timer_stop(&pdev->tx_throttle.tx_timer);
+			qdf_timer_start(
+				&pdev->tx_throttle.tx_timer,
+				OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS);
+			qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+			return;
+		}
+		qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+	}
+}
+
+void ol_tx_vdev_ll_pause_queue_send(void *context)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)context;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
+
+	if (pdev &&
+	    pdev->tx_throttle.current_throttle_level != THROTTLE_LEVEL_0 &&
+	    pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_OFF)
+		return;
+	ol_tx_vdev_ll_pause_queue_send_base(vdev);
+}
+
+/**
+ * ol_txrx_get_vdev_from_sta_id() - get vdev from sta_id
+ * @sta_id: sta_id
+ *
+ * Return: vdev handle
+ *            NULL if not found.
+ */
+static ol_txrx_vdev_handle ol_txrx_get_vdev_from_sta_id(uint8_t sta_id)
+{
+	struct ol_txrx_peer_t *peer = NULL;
+	ol_txrx_pdev_handle pdev = NULL;
+
+	if (sta_id >= WLAN_MAX_STA_COUNT) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid sta id passed");
+		return NULL;
+	}
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "PDEV not found for sta_id [%d]", sta_id);
+		return NULL;
+	}
+
+	peer = ol_txrx_peer_find_by_local_id((struct cdp_pdev *)pdev, sta_id);
+
+	if (!peer) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "PEER [%d] not found", sta_id);
+		return NULL;
+	}
+
+	return peer->vdev;
+}
+
+/**
+ * ol_txrx_register_tx_flow_control() - register tx flow control callback
+ * @vdev_id: vdev_id
+ * @flowControl: flow control callback
+ * @osif_fc_ctx: callback context
+ * @flow_control_is_pause: is vdev paused by flow control
+ *
+ * Return: 0 for success or error code
+ */
+int ol_txrx_register_tx_flow_control(uint8_t vdev_id,
+				     ol_txrx_tx_flow_control_fp flowControl,
+				     void *osif_fc_ctx,
+				     ol_txrx_tx_flow_control_is_pause_fp
+				     flow_control_is_pause)
+{
+	struct ol_txrx_vdev_t *vdev =
+		(struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
+
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid vdev_id %d", __func__, vdev_id);
+		return -EINVAL;
+	}
+
+	qdf_spin_lock_bh(&vdev->flow_control_lock);
+	vdev->osif_flow_control_cb = flowControl;
+	vdev->osif_flow_control_is_pause = flow_control_is_pause;
+	vdev->osif_fc_ctx = osif_fc_ctx;
+	qdf_spin_unlock_bh(&vdev->flow_control_lock);
+	return 0;
+}
+
+/**
+ * ol_txrx_de_register_tx_flow_control_cb() - deregister tx flow control
+ *                                            callback
+ * @vdev_id: vdev_id
+ *
+ * Return: 0 for success or error code
+ */
+int ol_txrx_deregister_tx_flow_control_cb(uint8_t vdev_id)
+{
+	struct ol_txrx_vdev_t *vdev =
+		(struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
+
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid vdev_id", __func__);
+		return -EINVAL;
+	}
+
+	qdf_spin_lock_bh(&vdev->flow_control_lock);
+	vdev->osif_flow_control_cb = NULL;
+	vdev->osif_flow_control_is_pause = NULL;
+	vdev->osif_fc_ctx = NULL;
+	qdf_spin_unlock_bh(&vdev->flow_control_lock);
+	return 0;
+}
+
+/**
+ * ol_txrx_get_tx_resource() - if tx resource less than low_watermark
+ * @sta_id: sta id
+ * @low_watermark: low watermark
+ * @high_watermark_offset: high watermark offset value
+ *
+ * Return: true/false
+ */
+bool
+ol_txrx_get_tx_resource(uint8_t sta_id,
+			unsigned int low_watermark,
+			unsigned int high_watermark_offset)
+{
+	ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_sta_id(sta_id);
+
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: Invalid sta_id %d", __func__, sta_id);
+		/* Return true so caller do not understand that resource
+		 * is less than low_watermark.
+		 * sta_id validation will be done in ol_tx_send_data_frame
+		 * and if sta_id is not registered then host will drop
+		 * packet.
+		 */
+		return true;
+	}
+
+	qdf_spin_lock_bh(&vdev->pdev->tx_mutex);
+
+	if (vdev->pdev->tx_desc.num_free < (uint16_t)low_watermark) {
+		vdev->tx_fl_lwm = (uint16_t)low_watermark;
+		vdev->tx_fl_hwm =
+			(uint16_t)(low_watermark + high_watermark_offset);
+		/* Not enough free resource, stop TX OS Q */
+		qdf_atomic_set(&vdev->os_q_paused, 1);
+		qdf_spin_unlock_bh(&vdev->pdev->tx_mutex);
+		return false;
+	}
+	qdf_spin_unlock_bh(&vdev->pdev->tx_mutex);
+	return true;
+}
+
+/**
+ * ol_txrx_ll_set_tx_pause_q_depth() - set pause queue depth
+ * @vdev_id: vdev id
+ * @pause_q_depth: pause queue depth
+ *
+ * Return: 0 for success or error code
+ */
+int ol_txrx_ll_set_tx_pause_q_depth(uint8_t vdev_id, int pause_q_depth)
+{
+	struct ol_txrx_vdev_t *vdev =
+		(struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
+
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid vdev_id %d", __func__, vdev_id);
+		return -EINVAL;
+	}
+
+	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
+	vdev->ll_pause.max_q_depth = pause_q_depth;
+	qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
+
+	return 0;
+}
+
+void ol_txrx_flow_control_cb(struct cdp_vdev *pvdev, bool tx_resume)
+{
+	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
+
+	qdf_spin_lock_bh(&vdev->flow_control_lock);
+	if ((vdev->osif_flow_control_cb) && (vdev->osif_fc_ctx))
+		vdev->osif_flow_control_cb(vdev->osif_fc_ctx, tx_resume);
+	qdf_spin_unlock_bh(&vdev->flow_control_lock);
+}
+
+/**
+ * ol_txrx_flow_control_is_pause() - is osif paused by flow control
+ * @vdev: vdev handle
+ *
+ * Return: true if osif is paused by flow control
+ */
+static bool ol_txrx_flow_control_is_pause(ol_txrx_vdev_handle vdev)
+{
+	bool is_pause = false;
+
+	if ((vdev->osif_flow_control_is_pause) && (vdev->osif_fc_ctx))
+		is_pause = vdev->osif_flow_control_is_pause(vdev->osif_fc_ctx);
+
+	return is_pause;
+}
+
+/**
+ * ol_tx_flow_ct_unpause_os_q() - Unpause OS Q
+ * @pdev: physical device object
+ *
+ *
+ * Return: None
+ */
+void ol_tx_flow_ct_unpause_os_q(ol_txrx_pdev_handle pdev)
+{
+	struct ol_txrx_vdev_t *vdev;
+
+	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+		if ((qdf_atomic_read(&vdev->os_q_paused) &&
+		     (vdev->tx_fl_hwm != 0)) ||
+		     ol_txrx_flow_control_is_pause(vdev)) {
+			qdf_spin_lock(&pdev->tx_mutex);
+			if (pdev->tx_desc.num_free > vdev->tx_fl_hwm) {
+				qdf_atomic_set(&vdev->os_q_paused, 0);
+				qdf_spin_unlock(&pdev->tx_mutex);
+				ol_txrx_flow_control_cb((struct cdp_vdev *)vdev,
+							true);
+			} else {
+				qdf_spin_unlock(&pdev->tx_mutex);
+			}
+		}
+	}
+}
+
diff --git a/core/dp/txrx/ol_txrx_peer_find.c b/core/dp/txrx/ol_txrx_peer_find.c
new file mode 100644
index 0000000..5676f83
--- /dev/null
+++ b/core/dp/txrx/ol_txrx_peer_find.c
@@ -0,0 +1,797 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*=== includes ===*/
+/* header files for OS primitives */
+#include <osdep.h>              /* uint32_t, etc. */
+#include <qdf_mem.h>         /* qdf_mem_malloc, etc. */
+#include <qdf_types.h>          /* qdf_device_t, qdf_print */
+/* header files for utilities */
+#include <cds_queue.h>          /* TAILQ */
+
+/* header files for configuration API */
+#include <ol_cfg.h>             /* ol_cfg_max_peer_id */
+
+/* header files for our internal definitions */
+#include <ol_txrx_api.h>        /* ol_txrx_pdev_t, etc. */
+#include <ol_txrx_dbg.h>        /* TXRX_DEBUG_LEVEL */
+#include <ol_txrx_internal.h>   /* ol_txrx_pdev_t, etc. */
+#include <ol_txrx.h>            /* ol_txrx_peer_release_ref */
+#include <ol_txrx_peer_find.h>  /* ol_txrx_peer_find_attach, etc. */
+#include <ol_tx_queue.h>
+#include "wlan_roam_debug.h"
+
+/*=== misc. / utility function definitions ==================================*/
+
+static int ol_txrx_log2_ceil(unsigned int value)
+{
+	/* need to switch to unsigned math so that negative values
+	 * will right-shift towards 0 instead of -1
+	 */
+	unsigned int tmp = value;
+	int log2 = -1;
+
+	if (value == 0) {
+		TXRX_ASSERT2(0);
+		return 0;
+	}
+
+	while (tmp) {
+		log2++;
+		tmp >>= 1;
+	}
+	if (1U << log2 != value)
+		log2++;
+
+	return log2;
+}
+
+int ol_txrx_peer_get_ref(struct ol_txrx_peer_t *peer,
+			  enum peer_debug_id_type dbg_id)
+{
+	int refs_dbg_id;
+
+	if (!peer) {
+		ol_txrx_err("peer is null for ID %d", dbg_id);
+		return -EINVAL;
+	}
+
+	if (dbg_id >= PEER_DEBUG_ID_MAX || dbg_id < 0) {
+		ol_txrx_err("incorrect debug_id %d ", dbg_id);
+		return -EINVAL;
+	}
+
+	qdf_atomic_inc(&peer->ref_cnt);
+	qdf_atomic_inc(&peer->access_list[dbg_id]);
+	refs_dbg_id = qdf_atomic_read(&peer->access_list[dbg_id]);
+
+	return refs_dbg_id;
+}
+
+/*=== function definitions for peer MAC addr --> peer object hash table =====*/
+
+/*
+ * TXRX_PEER_HASH_LOAD_FACTOR:
+ * Multiply by 2 and divide by 2^0 (shift by 0), then round up to a
+ * power of two.
+ * This provides at least twice as many bins in the peer hash table
+ * as there will be entries.
+ * Having substantially more bins than spaces minimizes the probability of
+ * having to compare MAC addresses.
+ * Because the MAC address comparison is fairly efficient, it is okay if the
+ * hash table is sparsely loaded, but it's generally better to use extra mem
+ * to keep the table sparse, to keep the lookups as fast as possible.
+ * An optimization would be to apply a more conservative loading factor for
+ * high latency, where the lookup happens during the tx classification of
+ * every tx frame, than for low-latency, where the lookup only happens
+ * during association, when the PEER_MAP message is received.
+ */
+#define TXRX_PEER_HASH_LOAD_MULT  2
+#define TXRX_PEER_HASH_LOAD_SHIFT 0
+
+static int ol_txrx_peer_find_hash_attach(struct ol_txrx_pdev_t *pdev)
+{
+	int i, hash_elems, log2;
+
+	/* allocate the peer MAC address -> peer object hash table */
+	hash_elems = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1;
+	hash_elems *= TXRX_PEER_HASH_LOAD_MULT;
+	hash_elems >>= TXRX_PEER_HASH_LOAD_SHIFT;
+	log2 = ol_txrx_log2_ceil(hash_elems);
+	hash_elems = 1 << log2;
+
+	pdev->peer_hash.mask = hash_elems - 1;
+	pdev->peer_hash.idx_bits = log2;
+	/* allocate an array of TAILQ peer object lists */
+	pdev->peer_hash.bins =
+		qdf_mem_malloc(hash_elems *
+			       sizeof(TAILQ_HEAD(anonymous_tail_q,
+						 ol_txrx_peer_t)));
+	if (!pdev->peer_hash.bins)
+		return 1;       /* failure */
+
+	for (i = 0; i < hash_elems; i++)
+		TAILQ_INIT(&pdev->peer_hash.bins[i]);
+
+	return 0;               /* success */
+}
+
+static void ol_txrx_peer_find_hash_detach(struct ol_txrx_pdev_t *pdev)
+{
+	qdf_mem_free(pdev->peer_hash.bins);
+}
+
+static inline unsigned int
+ol_txrx_peer_find_hash_index(struct ol_txrx_pdev_t *pdev,
+			     union ol_txrx_align_mac_addr_t *mac_addr)
+{
+	unsigned int index;
+
+	index =
+		mac_addr->align2.bytes_ab ^
+		mac_addr->align2.bytes_cd ^ mac_addr->align2.bytes_ef;
+	index ^= index >> pdev->peer_hash.idx_bits;
+	index &= pdev->peer_hash.mask;
+	return index;
+}
+
+void
+ol_txrx_peer_find_hash_add(struct ol_txrx_pdev_t *pdev,
+			   struct ol_txrx_peer_t *peer)
+{
+	unsigned int index;
+
+	index = ol_txrx_peer_find_hash_index(pdev, &peer->mac_addr);
+	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+	/*
+	 * It is important to add the new peer at the tail of the peer list
+	 * with the bin index.  Together with having the hash_find function
+	 * search from head to tail, this ensures that if two entries with
+	 * the same MAC address are stored, the one added first will be
+	 * found first.
+	 */
+	TAILQ_INSERT_TAIL(&pdev->peer_hash.bins[index], peer, hash_list_elem);
+	qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+}
+
+struct ol_txrx_peer_t *ol_txrx_peer_vdev_find_hash(struct ol_txrx_pdev_t *pdev,
+						   struct ol_txrx_vdev_t *vdev,
+						   uint8_t *peer_mac_addr,
+						   int mac_addr_is_aligned,
+						   uint8_t check_valid)
+{
+	union ol_txrx_align_mac_addr_t local_mac_addr_aligned, *mac_addr;
+	unsigned int index;
+	struct ol_txrx_peer_t *peer;
+
+	if (mac_addr_is_aligned) {
+		mac_addr = (union ol_txrx_align_mac_addr_t *)peer_mac_addr;
+	} else {
+		qdf_mem_copy(&local_mac_addr_aligned.raw[0],
+			     peer_mac_addr, OL_TXRX_MAC_ADDR_LEN);
+		mac_addr = &local_mac_addr_aligned;
+	}
+	index = ol_txrx_peer_find_hash_index(pdev, mac_addr);
+	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+	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)
+		    && peer->vdev == vdev) {
+			/* found it */
+			ol_txrx_peer_get_ref(peer, PEER_DEBUG_ID_OL_INTERNAL);
+			qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+			return peer;
+		}
+	}
+	qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+	return NULL;            /* failure */
+}
+
+struct ol_txrx_peer_t *
+	ol_txrx_peer_find_hash_find_get_ref
+				(struct ol_txrx_pdev_t *pdev,
+				uint8_t *peer_mac_addr,
+				int mac_addr_is_aligned,
+				u8 check_valid,
+				enum peer_debug_id_type dbg_id)
+{
+	union ol_txrx_align_mac_addr_t local_mac_addr_aligned, *mac_addr;
+	unsigned int index;
+	struct ol_txrx_peer_t *peer;
+
+	if (mac_addr_is_aligned) {
+		mac_addr = (union ol_txrx_align_mac_addr_t *)peer_mac_addr;
+	} else {
+		qdf_mem_copy(&local_mac_addr_aligned.raw[0],
+			     peer_mac_addr, OL_TXRX_MAC_ADDR_LEN);
+		mac_addr = &local_mac_addr_aligned;
+	}
+	index = ol_txrx_peer_find_hash_index(pdev, mac_addr);
+	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
+	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 */
+			ol_txrx_peer_get_ref(peer, dbg_id);
+			qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+			return peer;
+		}
+	}
+	qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+	return NULL;            /* failure */
+}
+
+void
+ol_txrx_peer_find_hash_remove(struct ol_txrx_pdev_t *pdev,
+			      struct ol_txrx_peer_t *peer)
+{
+	unsigned int index;
+
+	index = ol_txrx_peer_find_hash_index(pdev, &peer->mac_addr);
+	/*
+	 * DO NOT take the peer_ref_mutex lock here - it needs to be taken
+	 * by the caller.
+	 * The caller needs to hold the lock from the time the peer object's
+	 * reference count is decremented and tested up through the time the
+	 * reference to the peer object is removed from the hash table, by
+	 * this function.
+	 * Holding the lock only while removing the peer object reference
+	 * from the hash table keeps the hash table consistent, but does not
+	 * protect against a new HL tx context starting to use the peer object
+	 * if it looks up the peer object from its MAC address just after the
+	 * peer ref count is decremented to zero, but just before the peer
+	 * object reference is removed from the hash table.
+	 */
+	/* qdf_spin_lock_bh(&pdev->peer_ref_mutex); */
+	TAILQ_REMOVE(&pdev->peer_hash.bins[index], peer, hash_list_elem);
+	/* qdf_spin_unlock_bh(&pdev->peer_ref_mutex); */
+}
+
+void ol_txrx_peer_find_hash_erase(struct ol_txrx_pdev_t *pdev)
+{
+	unsigned int i;
+	/*
+	 * Not really necessary to take peer_ref_mutex lock - by this point,
+	 * it's known that the pdev is no longer in use.
+	 */
+
+	for (i = 0; i <= pdev->peer_hash.mask; i++) {
+		if (!TAILQ_EMPTY(&pdev->peer_hash.bins[i])) {
+			struct ol_txrx_peer_t *peer, *peer_next;
+
+			/*
+			 * TAILQ_FOREACH_SAFE must be used here to avoid any
+			 * memory access violation after peer is freed
+			 */
+			TAILQ_FOREACH_SAFE(peer, &pdev->peer_hash.bins[i],
+					   hash_list_elem, peer_next) {
+				/*
+				 * Don't remove the peer from the hash table -
+				 * that would modify the list we are currently
+				 * traversing,
+				 * and it's not necessary anyway.
+				 */
+				/*
+				 * Artificially adjust the peer's ref count to
+				 * 1, so it will get deleted by
+				 * ol_txrx_peer_release_ref.
+				 */
+				qdf_atomic_init(&peer->ref_cnt); /* set to 0 */
+				ol_txrx_peer_get_ref(peer,
+						     PEER_DEBUG_ID_OL_HASH_ERS);
+				ol_txrx_peer_release_ref(peer,
+						     PEER_DEBUG_ID_OL_HASH_ERS);
+			}
+		}
+	}
+}
+
+/*=== function definitions for peer id --> peer object map ==================*/
+
+static int ol_txrx_peer_find_map_attach(struct ol_txrx_pdev_t *pdev)
+{
+	int max_peers, peer_map_size;
+
+	/* allocate the peer ID -> peer object map */
+	max_peers = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1;
+	peer_map_size = max_peers * sizeof(pdev->peer_id_to_obj_map[0]);
+	pdev->peer_id_to_obj_map = qdf_mem_malloc(peer_map_size);
+	if (!pdev->peer_id_to_obj_map)
+		return 1;       /* failure */
+
+	return 0;               /* success */
+}
+
+static void ol_txrx_peer_find_map_detach(struct ol_txrx_pdev_t *pdev)
+{
+	qdf_mem_free(pdev->peer_id_to_obj_map);
+}
+
+/**
+ * ol_txrx_peer_clear_map_peer() - Remove map entries that refer to a peer.
+ * @pdev: pdev handle
+ * @peer: peer for removing obj map entries
+ *
+ * Run through the entire peer_id_to_obj map and nullify all the entries
+ * that map to a particular peer. Called before deleting the peer object.
+ *
+ * Return: None
+ */
+void ol_txrx_peer_clear_map_peer(ol_txrx_pdev_handle pdev,
+				 struct ol_txrx_peer_t *peer)
+{
+	int max_peers;
+	int i;
+
+	max_peers = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1;
+
+	qdf_spin_lock_bh(&pdev->peer_map_unmap_lock);
+	for (i = 0; i < max_peers; i++) {
+		if (pdev->peer_id_to_obj_map[i].peer == peer) {
+			/* Found a map entry for this peer, clear it. */
+			pdev->peer_id_to_obj_map[i].peer = NULL;
+		}
+	}
+	qdf_spin_unlock_bh(&pdev->peer_map_unmap_lock);
+}
+
+/*
+ * ol_txrx_peer_find_add_id() - Add peer_id entry to peer
+ *
+ * @pdev: Handle to pdev object
+ * @peer_mac_addr: MAC address of peer provided by firmware
+ * @peer_id: peer_id provided by firmware
+ *
+ * Search for peer object for the MAC address, add the peer_id to
+ * its array of peer_id's and update the peer_id_to_obj map entry
+ * for that peer_id. Increment corresponding reference counts.
+ *
+ * Riva/Pronto has one peer id for each peer.
+ * Peregrine/Rome has two peer id for each peer.
+ * iHelium has upto three peer id for each peer.
+ *
+ * Return: None
+ */
+static inline void ol_txrx_peer_find_add_id(struct ol_txrx_pdev_t *pdev,
+				uint8_t *peer_mac_addr, uint16_t peer_id)
+{
+	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 =
+		ol_txrx_peer_find_hash_find_get_ref(pdev, peer_mac_addr,
+						    1 /* is aligned */, 0,
+						    PEER_DEBUG_ID_OL_PEER_MAP);
+
+	if (!peer || peer_id == HTT_INVALID_PEER) {
+		/*
+		 * Currently peer IDs are assigned for vdevs as well as peers.
+		 * If the peer ID is for a vdev, then we will fail to find a
+		 * peer with a matching MAC address.
+		 */
+		ol_txrx_err(
+			  "%s: peer not found or peer ID is %d invalid",
+			  __func__, peer_id);
+		wlan_roam_debug_log(DEBUG_INVALID_VDEV_ID,
+				    DEBUG_PEER_MAP_EVENT,
+				    peer_id, peer_mac_addr,
+				    peer, 0, 0);
+
+		return;
+	}
+
+	qdf_spin_lock(&pdev->peer_map_unmap_lock);
+
+	/* peer's ref count was already incremented by
+	 * peer_find_hash_find
+	 */
+	if (!pdev->peer_id_to_obj_map[peer_id].peer) {
+		pdev->peer_id_to_obj_map[peer_id].peer = peer;
+		qdf_atomic_init
+		  (&pdev->peer_id_to_obj_map[peer_id].peer_id_ref_cnt);
+	}
+	qdf_atomic_inc
+		(&pdev->peer_id_to_obj_map[peer_id].peer_id_ref_cnt);
+
+	status = 1;
+
+	/* find a place in peer_id array and insert peer_id */
+	for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) {
+		if (peer->peer_ids[i] == HTT_INVALID_PEER) {
+			peer->peer_ids[i] = peer_id;
+			status = 0;
+			break;
+		}
+	}
+
+	if (qdf_atomic_read(&peer->fw_create_pending) == 1) {
+		qdf_atomic_set(&peer->fw_create_pending, 0);
+	}
+
+	qdf_spin_unlock(&pdev->peer_map_unmap_lock);
+
+	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 %pK ID %d peer_id[%d] peer_id_ref_cnt %d peer->ref_cnt %d",
+	   __func__, peer, peer_id, i, peer_id_ref_cnt, peer_ref_cnt);
+	wlan_roam_debug_log(DEBUG_INVALID_VDEV_ID,
+			    DEBUG_PEER_MAP_EVENT,
+			    peer_id, &peer->mac_addr.raw, peer,
+			    peer_id_ref_cnt,
+			    peer_ref_cnt);
+
+
+	if (status) {
+		/* TBDXXX: assert for now */
+		qdf_assert(0);
+	}
+}
+
+/*=== allocation / deallocation function definitions ========================*/
+
+int ol_txrx_peer_find_attach(struct ol_txrx_pdev_t *pdev)
+{
+	if (ol_txrx_peer_find_map_attach(pdev))
+		return 1;
+	if (ol_txrx_peer_find_hash_attach(pdev)) {
+		ol_txrx_peer_find_map_detach(pdev);
+		return 1;
+	}
+	return 0;               /* success */
+}
+
+void ol_txrx_peer_find_detach(struct ol_txrx_pdev_t *pdev)
+{
+	ol_txrx_peer_find_map_detach(pdev);
+	ol_txrx_peer_find_hash_detach(pdev);
+}
+
+/*=== function definitions for message handling =============================*/
+
+#if defined(CONFIG_HL_SUPPORT)
+
+void
+ol_rx_peer_map_handler(ol_txrx_pdev_handle pdev,
+		       uint16_t peer_id,
+		       uint8_t vdev_id, uint8_t *peer_mac_addr, int tx_ready)
+{
+	ol_txrx_peer_find_add_id(pdev, peer_mac_addr, peer_id);
+	if (!tx_ready) {
+		struct ol_txrx_peer_t *peer;
+
+		peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+		if (!peer) {
+			/* ol_txrx_peer_detach called before peer map arrived*/
+			return;
+		} else {
+			if (tx_ready) {
+				int i;
+
+				/* unpause all tx queues now, since the
+				 * target is ready
+				 */
+				for (i = 0; i < QDF_ARRAY_SIZE(peer->txqs);
+									i++)
+					ol_txrx_peer_tid_unpause(peer, i);
+
+			} else {
+				/* walk through paused mgmt queue,
+				 * update tx descriptors
+				 */
+				ol_tx_queue_decs_reinit(peer, peer_id);
+
+				/* keep non-mgmt tx queues paused until assoc
+				 * is finished tx queues were paused in
+				 * ol_txrx_peer_attach
+				 */
+				/* unpause tx mgmt queue */
+				ol_txrx_peer_tid_unpause(peer,
+							 HTT_TX_EXT_TID_MGMT);
+			}
+		}
+	}
+}
+
+void ol_txrx_peer_tx_ready_handler(ol_txrx_pdev_handle pdev, uint16_t peer_id)
+{
+	struct ol_txrx_peer_t *peer;
+
+	peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+	if (peer) {
+		int i;
+		/*
+		 * Unpause all data tx queues now that the target is ready.
+		 * The mgmt tx queue was not paused, so skip it.
+		 */
+		for (i = 0; i < QDF_ARRAY_SIZE(peer->txqs); i++) {
+			if (i == HTT_TX_EXT_TID_MGMT)
+				continue; /* mgmt tx queue was not paused */
+
+			ol_txrx_peer_tid_unpause(peer, i);
+		}
+	}
+}
+#else
+
+void
+ol_rx_peer_map_handler(ol_txrx_pdev_handle pdev,
+		       uint16_t peer_id,
+		       uint8_t vdev_id,
+		       uint8_t *peer_mac_addr,
+		       int tx_ready)
+{
+	ol_txrx_peer_find_add_id(pdev, peer_mac_addr, peer_id);
+}
+
+void ol_txrx_peer_tx_ready_handler(ol_txrx_pdev_handle pdev, uint16_t peer_id)
+{
+}
+
+#endif
+
+/*
+ * ol_rx_peer_unmap_handler() - Handle peer unmap event from firmware
+ *
+ * @pdev: Handle to pdev pbject
+ * @peer_id: peer_id unmapped by firmware
+ *
+ * Decrement reference count for the peer_id in peer_id_to_obj_map,
+ * decrement reference count in corresponding peer object and clear the entry
+ * in peer's peer_ids array.
+ * In case of unmap events for a peer that is already deleted, just decrement
+ * del_peer_id_ref_cnt.
+ *
+ * Return: None
+ */
+void ol_rx_peer_unmap_handler(ol_txrx_pdev_handle pdev, uint16_t peer_id)
+{
+	struct ol_txrx_peer_t *peer;
+	int i = 0;
+	int32_t ref_cnt;
+
+	if (peer_id == HTT_INVALID_PEER) {
+		ol_txrx_err(
+		   "%s: invalid peer ID %d\n", __func__, peer_id);
+		wlan_roam_debug_log(DEBUG_INVALID_VDEV_ID,
+				    DEBUG_PEER_UNMAP_EVENT,
+				    peer_id, NULL, NULL, 0, 0x100);
+		return;
+	}
+
+	qdf_spin_lock_bh(&pdev->peer_map_unmap_lock);
+
+	if (qdf_atomic_read(
+		&pdev->peer_id_to_obj_map[peer_id].del_peer_id_ref_cnt)) {
+		/* This peer_id belongs to a peer already deleted */
+		qdf_atomic_dec(&pdev->peer_id_to_obj_map[peer_id].
+					del_peer_id_ref_cnt);
+		ref_cnt = qdf_atomic_read(&pdev->peer_id_to_obj_map[peer_id].
+							del_peer_id_ref_cnt);
+		qdf_spin_unlock_bh(&pdev->peer_map_unmap_lock);
+		wlan_roam_debug_log(DEBUG_INVALID_VDEV_ID,
+				    DEBUG_PEER_UNMAP_EVENT,
+				    peer_id, NULL, NULL, ref_cnt, 0x101);
+		ol_txrx_dbg(
+			   "%s: peer already deleted, peer_id %d del_peer_id_ref_cnt %d",
+			   __func__, peer_id, ref_cnt);
+		return;
+	}
+	peer = pdev->peer_id_to_obj_map[peer_id].peer;
+
+	if (peer == NULL) {
+		/*
+		 * Currently peer IDs are assigned for vdevs as well as peers.
+		 * If the peer ID is for a vdev, then the peer pointer stored
+		 * in peer_id_to_obj_map will be NULL.
+		 */
+		qdf_spin_unlock_bh(&pdev->peer_map_unmap_lock);
+		ol_txrx_info(
+			   "%s: peer not found for peer_id %d",
+			   __func__, peer_id);
+		wlan_roam_debug_log(DEBUG_INVALID_VDEV_ID,
+				    DEBUG_PEER_UNMAP_EVENT,
+				    peer_id, NULL, NULL, 0, 0x102);
+		return;
+	}
+
+	if (qdf_atomic_dec_and_test
+		(&pdev->peer_id_to_obj_map[peer_id].peer_id_ref_cnt)) {
+		pdev->peer_id_to_obj_map[peer_id].peer = NULL;
+		for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) {
+			if (peer->peer_ids[i] == peer_id) {
+				peer->peer_ids[i] = HTT_INVALID_PEER;
+				break;
+			}
+		}
+	}
+
+	ref_cnt = qdf_atomic_read
+		(&pdev->peer_id_to_obj_map[peer_id].peer_id_ref_cnt);
+
+	qdf_spin_unlock_bh(&pdev->peer_map_unmap_lock);
+
+	wlan_roam_debug_log(DEBUG_INVALID_VDEV_ID,
+			    DEBUG_PEER_UNMAP_EVENT,
+			    peer_id, &peer->mac_addr.raw, peer, ref_cnt,
+			    qdf_atomic_read(&peer->ref_cnt));
+
+	/*
+	 * Remove a reference to the peer.
+	 * If there are no more references, delete the peer object.
+	 */
+	ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_PEER_MAP);
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: peer_id %d peer %pK peer_id_ref_cnt %d",
+		  __func__, peer_id, peer, ref_cnt);
+}
+
+/**
+ * ol_txrx_peer_remove_obj_map_entries() - Remove matching pdev peer map entries
+ * @pdev: pdev handle
+ * @peer: peer for removing obj map entries
+ *
+ * Saves peer_id_ref_cnt to a different field and removes the link
+ * to peer object. It also decrements the peer reference count by
+ * the number of references removed.
+ *
+ * Return: None
+ */
+void ol_txrx_peer_remove_obj_map_entries(ol_txrx_pdev_handle pdev,
+					struct ol_txrx_peer_t *peer)
+{
+	int i;
+	uint16_t peer_id;
+	int32_t peer_id_ref_cnt;
+	int32_t num_deleted_maps = 0;
+	uint16_t save_peer_ids[MAX_NUM_PEER_ID_PER_PEER];
+	uint16_t save_peer_id_ref_cnt[MAX_NUM_PEER_ID_PER_PEER] = {0};
+
+	qdf_spin_lock_bh(&pdev->peer_map_unmap_lock);
+	for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) {
+		peer_id = peer->peer_ids[i];
+		save_peer_ids[i] = HTT_INVALID_PEER;
+		if (peer_id == HTT_INVALID_PEER ||
+			pdev->peer_id_to_obj_map[peer_id].peer == NULL) {
+			/* unused peer_id, or object is already dereferenced */
+			continue;
+		}
+		if (pdev->peer_id_to_obj_map[peer_id].peer != peer) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX,
+				QDF_TRACE_LEVEL_ERROR,
+				FL("peer pointer mismatch in peer_id_to_obj"));
+			continue;
+		}
+		peer_id_ref_cnt = qdf_atomic_read(
+					&pdev->peer_id_to_obj_map[peer_id].
+						peer_id_ref_cnt);
+		save_peer_ids[i] = peer_id;
+		save_peer_id_ref_cnt[i] = peer_id_ref_cnt;
+
+		/*
+		 * Transfer peer_id_ref_cnt into del_peer_id_ref_cnt so that
+		 * ol_txrx_peer_release_ref will decrement del_peer_id_ref_cnt
+		 * and any map events will increment peer_id_ref_cnt. Otherwise
+		 * accounting will be messed up.
+		 *
+		 * Add operation will ensure that back to back roaming in the
+		 * middle of unmap/map event sequence will be accounted for.
+		 */
+		qdf_atomic_add(peer_id_ref_cnt,
+			&pdev->peer_id_to_obj_map[peer_id].del_peer_id_ref_cnt);
+		qdf_atomic_init(&pdev->peer_id_to_obj_map[peer_id].
+				peer_id_ref_cnt);
+		num_deleted_maps += peer_id_ref_cnt;
+		pdev->peer_id_to_obj_map[peer_id].peer = NULL;
+		peer->peer_ids[i] = HTT_INVALID_PEER;
+	}
+	qdf_spin_unlock_bh(&pdev->peer_map_unmap_lock);
+
+	/* Debug print the information after releasing bh spinlock */
+	for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) {
+		if (save_peer_ids[i] == HTT_INVALID_PEER)
+			continue;
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+			  FL("peer_id = %d, peer_id_ref_cnt = %d, index = %d"),
+			  save_peer_ids[i], save_peer_id_ref_cnt[i], i);
+	}
+
+	if (num_deleted_maps > qdf_atomic_read(&peer->ref_cnt)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  FL("num_deleted_maps %d ref_cnt %d"),
+			  num_deleted_maps, qdf_atomic_read(&peer->ref_cnt));
+		QDF_BUG(0);
+		return;
+	}
+
+	while (num_deleted_maps-- > 0)
+		ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_PEER_MAP);
+}
+
+struct ol_txrx_peer_t *ol_txrx_assoc_peer_find(struct ol_txrx_vdev_t *vdev)
+{
+	struct ol_txrx_peer_t *peer;
+
+	qdf_spin_lock_bh(&vdev->pdev->last_real_peer_mutex);
+	/*
+	 * Check the TXRX Peer is itself valid And also
+	 * if HTT Peer ID has been setup for this peer
+	 */
+	if (vdev->last_real_peer
+	    && vdev->last_real_peer->peer_ids[0] != HTT_INVALID_PEER_ID) {
+		qdf_spin_lock_bh(&vdev->pdev->peer_ref_mutex);
+		ol_txrx_peer_get_ref(vdev->last_real_peer,
+				     PEER_DEBUG_ID_OL_INTERNAL);
+		qdf_spin_unlock_bh(&vdev->pdev->peer_ref_mutex);
+		peer = vdev->last_real_peer;
+	} else {
+		peer = NULL;
+	}
+	qdf_spin_unlock_bh(&vdev->pdev->last_real_peer_mutex);
+	return peer;
+}
+
+
+/*=== function definitions for debug ========================================*/
+
+#if defined(TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5
+void ol_txrx_peer_find_display(ol_txrx_pdev_handle pdev, int indent)
+{
+	int i, max_peers;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*speer map:\n", indent, " ");
+	max_peers = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1;
+	for (i = 0; i < max_peers; i++) {
+		if (pdev->peer_id_to_obj_map[i].peer) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+				  "%*sid %d -> %pK\n",
+				  indent + 4, " ", i,
+				  pdev->peer_id_to_obj_map[i].peer);
+		}
+	}
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "%*speer hash table:\n", indent, " ");
+	for (i = 0; i <= pdev->peer_hash.mask; i++) {
+		if (!TAILQ_EMPTY(&pdev->peer_hash.bins[i])) {
+			struct ol_txrx_peer_t *peer;
+
+			TAILQ_FOREACH(peer, &pdev->peer_hash.bins[i],
+				      hash_list_elem) {
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					  QDF_TRACE_LEVEL_INFO_LOW,
+					  "%*shash idx %d -> %pK (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+					indent + 4, " ", i, peer,
+					peer->mac_addr.raw[0],
+					peer->mac_addr.raw[1],
+					peer->mac_addr.raw[2],
+					peer->mac_addr.raw[3],
+					peer->mac_addr.raw[4],
+					peer->mac_addr.raw[5]);
+			}
+		}
+	}
+}
+
+#endif /* if TXRX_DEBUG_LEVEL */
diff --git a/core/dp/txrx/ol_txrx_peer_find.h b/core/dp/txrx/ol_txrx_peer_find.h
new file mode 100644
index 0000000..a3d6c37
--- /dev/null
+++ b/core/dp/txrx/ol_txrx_peer_find.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2011, 2015-2018 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.
+ */
+
+/**
+ * @file ol_txrx_peer_find.h
+ * @brief Define the API for the rx peer lookup datapath module.
+ */
+#ifndef _OL_TXRX_PEER_FIND__H_
+#define _OL_TXRX_PEER_FIND__H_
+
+#include <htt.h>                /* HTT_INVALID_PEER */
+#include <cdp_txrx_cmn.h>       /* ol_txrx_pdev_t, etc. */
+#include <ol_txrx_internal.h>   /* TXRX_ASSERT */
+
+/**
+ * ol_txrx_peer_get_ref() - get peer reference
+ * @peer: peer for removing obj map entries
+ * @dbg_id: debug id to keep track of peer references
+ *
+ * The function increments the peer ref count. The ref count can be reduced by
+ * caling ol_txrx_peer_release_ref function. Callers are responsible for
+ * acquiring the peer_ref_mutex lock when needed.
+ *
+ * Return: peer debug id ref count or error
+ */
+int
+ol_txrx_peer_get_ref(struct ol_txrx_peer_t *peer,
+		     enum peer_debug_id_type dbg_id);
+
+int ol_txrx_peer_find_attach(struct ol_txrx_pdev_t *pdev);
+
+void ol_txrx_peer_find_detach(struct ol_txrx_pdev_t *pdev);
+
+static inline
+int
+ol_txrx_peer_find_mac_addr_cmp(union ol_txrx_align_mac_addr_t *mac_addr1,
+			       union ol_txrx_align_mac_addr_t *mac_addr2)
+{
+	return !((mac_addr1->align4.bytes_abcd == mac_addr2->align4.bytes_abcd)
+		 /*
+		  * Intentionally use & rather than &&.
+		  * because the operands are binary rather than generic bool,
+		  * the functionality is equivalent.
+		  * Using && has the advantage of short-circuited evaluation,
+		  * but using & has the advantage of no conditional branching,
+		  * which is a more significant benefit.
+		  */
+		 & (mac_addr1->align4.bytes_ef == mac_addr2->align4.bytes_ef));
+}
+
+static inline
+struct ol_txrx_peer_t *ol_txrx_peer_find_by_id(struct ol_txrx_pdev_t *pdev,
+					       uint16_t peer_id)
+{
+	struct ol_txrx_peer_t *peer;
+
+	peer = (peer_id > ol_cfg_max_peer_id(pdev->ctrl_pdev)) ? NULL :
+	       pdev->peer_id_to_obj_map[peer_id].peer;
+	/*
+	 * Currently, peer IDs are assigned to vdevs as well as peers.
+	 * If the peer ID is for a vdev, the peer_id_to_obj_map entry
+	 * will hold NULL rather than a valid peer pointer.
+	 */
+	/* TXRX_ASSERT2(peer != NULL); */
+	/*
+	 * Only return the peer object if it is valid,
+	 * i.e. it has not already been detached.
+	 * If it has already been detached, then returning the
+	 * peer object could result in unpausing the peer's tx queues
+	 * in HL systems, which is an invalid operation following peer_detach.
+	 */
+	if (peer && peer->valid)
+		return peer;
+
+	return NULL;
+}
+
+void
+ol_txrx_peer_find_hash_add(struct ol_txrx_pdev_t *pdev,
+			   struct ol_txrx_peer_t *peer);
+
+struct ol_txrx_peer_t *
+	ol_txrx_peer_find_hash_find_get_ref
+				(struct ol_txrx_pdev_t *pdev,
+				uint8_t *peer_mac_addr,
+				int mac_addr_is_aligned,
+				u8 check_valid,
+				enum peer_debug_id_type dbg_id);
+
+struct
+ol_txrx_peer_t *ol_txrx_peer_vdev_find_hash(struct ol_txrx_pdev_t *pdev,
+					    struct ol_txrx_vdev_t *vdev,
+					    uint8_t *peer_mac_addr,
+					    int mac_addr_is_aligned,
+					    uint8_t check_valid);
+
+void
+ol_txrx_peer_find_hash_remove(struct ol_txrx_pdev_t *pdev,
+			      struct ol_txrx_peer_t *peer);
+
+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);
+void ol_txrx_peer_clear_map_peer(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
+#define ol_txrx_peer_find_display(pdev, indent)
+#endif /* TXRX_DEBUG_LEVEL */
+
+#endif /* _OL_TXRX_PEER_FIND__H_ */
diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h
new file mode 100644
index 0000000..7a36938
--- /dev/null
+++ b/core/dp/txrx/ol_txrx_types.h
@@ -0,0 +1,1385 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/**
+ * @file ol_txrx_types.h
+ * @brief Define the major data types used internally by the host datapath SW.
+ */
+#ifndef _OL_TXRX_TYPES__H_
+#define _OL_TXRX_TYPES__H_
+
+#include <qdf_nbuf.h>           /* qdf_nbuf_t */
+#include <qdf_mem.h>
+#include <cds_queue.h>          /* TAILQ */
+#include <a_types.h>            /* A_UINT8 */
+#include <htt.h>                /* htt_sec_type, htt_pkt_type, etc. */
+#include <qdf_atomic.h>         /* qdf_atomic_t */
+#include <wdi_event_api.h>      /* wdi_event_subscribe */
+#include <qdf_timer.h>		/* qdf_timer_t */
+#include <qdf_lock.h>           /* qdf_spinlock */
+#include <pktlog.h>             /* ol_pktlog_dev_handle */
+#include <ol_txrx_stats.h>
+#include <txrx.h>
+#include "ol_txrx_htt_api.h"
+#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 */
+#include "cdp_txrx_flow_ctrl_v2.h"
+#include "cdp_txrx_peer_ops.h"
+#include <qdf_trace.h>
+
+/*
+ * The target may allocate multiple IDs for a peer.
+ * In particular, the target may allocate one ID to represent the
+ * multicast key the peer uses, and another ID to represent the
+ * unicast key the peer uses.
+ */
+#define MAX_NUM_PEER_ID_PER_PEER 16
+
+/* OL_TXRX_NUM_EXT_TIDS -
+ * 16 "real" TIDs + 3 pseudo-TIDs for mgmt, mcast/bcast & non-QoS data
+ */
+#define OL_TXRX_NUM_EXT_TIDS 19
+
+#define OL_TX_NUM_QOS_TIDS 16   /* 16 regular TIDs */
+#define OL_TX_NON_QOS_TID 16
+#define OL_TX_MGMT_TID    17
+#define OL_TX_NUM_TIDS    18
+#define OL_RX_MCAST_TID   18  /* Mcast TID only between f/w & host */
+
+#define OL_TX_VDEV_MCAST_BCAST    0 /* HTT_TX_EXT_TID_MCAST_BCAST */
+#define OL_TX_VDEV_DEFAULT_MGMT   1 /* HTT_TX_EXT_TID_DEFALT_MGMT */
+#define OL_TX_VDEV_NUM_QUEUES     2
+
+#define OL_TXRX_MGMT_TYPE_BASE htt_pkt_num_types
+#define OL_TXRX_MGMT_NUM_TYPES 8
+
+#define OL_TX_MUTEX_TYPE qdf_spinlock_t
+#define OL_RX_MUTEX_TYPE qdf_spinlock_t
+
+/* TXRX Histogram defines */
+#define TXRX_DATA_HISTROGRAM_GRANULARITY      1000
+#define TXRX_DATA_HISTROGRAM_NUM_INTERVALS    100
+
+#define OL_TXRX_INVALID_VDEV_ID		(-1)
+
+struct ol_txrx_pdev_t;
+struct ol_txrx_vdev_t;
+struct ol_txrx_peer_t;
+
+/* rx filter related */
+#define MAX_PRIVACY_FILTERS           4 /* max privacy filters */
+
+enum privacy_filter {
+	PRIVACY_FILTER_ALWAYS,
+	PRIVACY_FILTER_KEY_UNAVAILABLE,
+};
+
+enum privacy_filter_packet_type {
+	PRIVACY_FILTER_PACKET_UNICAST,
+	PRIVACY_FILTER_PACKET_MULTICAST,
+	PRIVACY_FILTER_PACKET_BOTH
+};
+
+struct privacy_exemption {
+	/* ethertype -
+	 * type of ethernet frames this filter applies to, in host byte order
+	 */
+	uint16_t ether_type;
+	enum privacy_filter filter_type;
+	enum privacy_filter_packet_type packet_type;
+};
+
+enum ol_tx_frm_type {
+	OL_TX_FRM_STD = 0, /* regular frame - no added header fragments */
+	OL_TX_FRM_TSO,     /* TSO segment, with a modified IP header added */
+	OL_TX_FRM_AUDIO,   /* audio frames, with a custom LLC/SNAP hdr added */
+	OL_TX_FRM_NO_FREE, /* frame requires special tx completion callback */
+	ol_tx_frm_freed = 0xff, /* the tx desc is in free list */
+};
+
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
+
+#define MAX_NO_PEERS_IN_LIMIT (2*10 + 2)
+
+enum ol_tx_peer_bal_state {
+	ol_tx_peer_bal_enable = 0,
+	ol_tx_peer_bal_disable,
+};
+
+enum ol_tx_peer_bal_timer_state {
+	ol_tx_peer_bal_timer_disable = 0,
+	ol_tx_peer_bal_timer_active,
+	ol_tx_peer_bal_timer_inactive,
+};
+
+struct ol_tx_limit_peer_t {
+	u_int16_t limit_flag;
+	u_int16_t peer_id;
+	u_int16_t limit;
+};
+
+enum tx_peer_level {
+	TXRX_IEEE11_B = 0,
+	TXRX_IEEE11_A_G,
+	TXRX_IEEE11_N,
+	TXRX_IEEE11_AC,
+	TXRX_IEEE11_AX,
+	TXRX_IEEE11_MAX,
+};
+
+struct tx_peer_threshold {
+	u_int32_t tput_thresh;
+	u_int32_t tx_limit;
+};
+#endif
+
+
+struct ol_tx_desc_t {
+	qdf_nbuf_t netbuf;
+	void *htt_tx_desc;
+	uint16_t id;
+	qdf_dma_addr_t htt_tx_desc_paddr;
+	void *htt_frag_desc; /* struct msdu_ext_desc_t * */
+	qdf_dma_addr_t htt_frag_desc_paddr;
+	qdf_atomic_t ref_cnt;
+	enum htt_tx_status status;
+
+#ifdef QCA_COMPUTE_TX_DELAY
+	uint32_t entry_timestamp_ticks;
+#endif
+
+#ifdef DESC_TIMESTAMP_DEBUG_INFO
+	struct {
+		uint64_t prev_tx_ts;
+		uint64_t curr_tx_ts;
+		uint64_t last_comp_ts;
+	} desc_debug_info;
+#endif
+
+	/*
+	 * Allow tx descriptors to be stored in (doubly-linked) lists.
+	 * This is mainly used for HL tx queuing and scheduling, but is
+	 * also used by LL+HL for batch processing of tx frames.
+	 */
+	TAILQ_ENTRY(ol_tx_desc_t) tx_desc_list_elem;
+
+	/*
+	 * Remember whether the tx frame is a regular packet, or whether
+	 * the driver added extra header fragments (e.g. a modified IP header
+	 * for TSO fragments, or an added LLC/SNAP header for audio interworking
+	 * data) that need to be handled in a special manner.
+	 * This field is filled in with the ol_tx_frm_type enum.
+	 */
+	uint8_t pkt_type;
+
+	u_int8_t vdev_id;
+
+	struct ol_txrx_vdev_t *vdev;
+
+	void *txq;
+
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+	/*
+	 * used by tx encap, to restore the os buf start offset
+	 * after tx complete
+	 */
+	uint8_t orig_l2_hdr_bytes;
+#endif
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+	struct ol_tx_flow_pool_t *pool;
+#endif
+	void *tso_desc;
+	void *tso_num_desc;
+};
+
+typedef TAILQ_HEAD(some_struct_name, ol_tx_desc_t) ol_tx_desc_list;
+
+union ol_tx_desc_list_elem_t {
+	union ol_tx_desc_list_elem_t *next;
+	struct ol_tx_desc_t tx_desc;
+};
+
+union ol_txrx_align_mac_addr_t {
+	uint8_t raw[OL_TXRX_MAC_ADDR_LEN];
+	struct {
+		uint16_t bytes_ab;
+		uint16_t bytes_cd;
+		uint16_t bytes_ef;
+	} align2;
+	struct {
+		uint32_t bytes_abcd;
+		uint16_t bytes_ef;
+	} align4;
+};
+
+struct ol_rx_reorder_timeout_list_elem_t {
+	TAILQ_ENTRY(ol_rx_reorder_timeout_list_elem_t)
+	reorder_timeout_list_elem;
+	uint32_t timestamp_ms;
+	struct ol_txrx_peer_t *peer;
+	uint8_t tid;
+	uint8_t active;
+};
+
+#define TXRX_TID_TO_WMM_AC(_tid) ( \
+		(((_tid) >> 1) == 3) ? TXRX_WMM_AC_VO :	\
+		(((_tid) >> 1) == 2) ? TXRX_WMM_AC_VI :	\
+		(((_tid) ^ ((_tid) >> 1)) & 0x1) ? TXRX_WMM_AC_BK : \
+		TXRX_WMM_AC_BE)
+
+enum {
+	OL_TX_SCHED_WRR_ADV_CAT_BE,
+	OL_TX_SCHED_WRR_ADV_CAT_BK,
+	OL_TX_SCHED_WRR_ADV_CAT_VI,
+	OL_TX_SCHED_WRR_ADV_CAT_VO,
+	OL_TX_SCHED_WRR_ADV_CAT_NON_QOS_DATA,
+	OL_TX_SCHED_WRR_ADV_CAT_UCAST_MGMT,
+	OL_TX_SCHED_WRR_ADV_CAT_MCAST_DATA,
+	OL_TX_SCHED_WRR_ADV_CAT_MCAST_MGMT,
+
+	OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES /* must be last */
+};
+
+A_COMPILE_TIME_ASSERT(ol_tx_sched_htt_ac_values,
+	/* check that regular WMM AC enum values match */
+	((int)OL_TX_SCHED_WRR_ADV_CAT_VO == (int)HTT_AC_WMM_VO) &&
+	((int)OL_TX_SCHED_WRR_ADV_CAT_VI == (int)HTT_AC_WMM_VI) &&
+	((int)OL_TX_SCHED_WRR_ADV_CAT_BK == (int)HTT_AC_WMM_BK) &&
+	((int)OL_TX_SCHED_WRR_ADV_CAT_BE == (int)HTT_AC_WMM_BE) &&
+
+	/* check that extension AC enum values match */
+	((int)OL_TX_SCHED_WRR_ADV_CAT_NON_QOS_DATA
+		== (int)HTT_AC_EXT_NON_QOS) &&
+	((int)OL_TX_SCHED_WRR_ADV_CAT_UCAST_MGMT
+		== (int)HTT_AC_EXT_UCAST_MGMT) &&
+	((int)OL_TX_SCHED_WRR_ADV_CAT_MCAST_DATA
+		== (int)HTT_AC_EXT_MCAST_DATA) &&
+	((int)OL_TX_SCHED_WRR_ADV_CAT_MCAST_MGMT
+		== (int)HTT_AC_EXT_MCAST_MGMT));
+
+struct ol_tx_reorder_cat_timeout_t {
+	TAILQ_HEAD(, ol_rx_reorder_timeout_list_elem_t) virtual_timer_list;
+	qdf_timer_t timer;
+	uint32_t duration_ms;
+	struct ol_txrx_pdev_t *pdev;
+};
+
+enum ol_tx_scheduler_status {
+	ol_tx_scheduler_idle = 0,
+	ol_tx_scheduler_running,
+};
+
+enum ol_tx_queue_status {
+	ol_tx_queue_empty = 0,
+	ol_tx_queue_active,
+	ol_tx_queue_paused,
+};
+
+struct ol_txrx_msdu_info_t {
+	struct htt_msdu_info_t htt;
+	struct ol_txrx_peer_t *peer;
+	struct qdf_tso_info_t tso_info;
+};
+
+enum {
+	ol_tx_aggr_untried = 0,
+	ol_tx_aggr_enabled,
+	ol_tx_aggr_disabled,
+	ol_tx_aggr_retry,
+	ol_tx_aggr_in_progress,
+};
+
+#define OL_TX_MAX_GROUPS_PER_QUEUE 1
+#define OL_TX_MAX_VDEV_ID 16
+#define OL_TXQ_GROUP_VDEV_ID_MASK_GET(_membership)           \
+	(((_membership) & 0xffff0000) >> 16)
+#define OL_TXQ_GROUP_VDEV_ID_BIT_MASK_GET(_mask, _vdev_id)   \
+	((_mask >> _vdev_id) & 0x01)
+#define OL_TXQ_GROUP_AC_MASK_GET(_membership)           \
+	((_membership) & 0x0000ffff)
+#define OL_TXQ_GROUP_AC_BIT_MASK_GET(_mask, _ac_mask)   \
+	((_mask >> _ac_mask) & 0x01)
+#define OL_TXQ_GROUP_MEMBERSHIP_GET(_vdev_mask, _ac_mask)     \
+	((_vdev_mask << 16) | _ac_mask)
+
+struct ol_tx_frms_queue_t {
+	/* list_elem -
+	 * Allow individual tx frame queues to be linked together into
+	 * scheduler queues of tx frame queues
+	 */
+	TAILQ_ENTRY(ol_tx_frms_queue_t) list_elem;
+	uint8_t aggr_state;
+	struct {
+		uint8_t total;
+		/* pause requested by ctrl SW rather than txrx SW */
+		uint8_t by_ctrl;
+	} paused_count;
+	uint8_t ext_tid;
+	uint16_t frms;
+	uint32_t bytes;
+	ol_tx_desc_list head;
+	enum ol_tx_queue_status flag;
+	struct ol_tx_queue_group_t *group_ptrs[OL_TX_MAX_GROUPS_PER_QUEUE];
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
+	struct ol_txrx_peer_t *peer;
+#endif
+};
+
+enum {
+	ol_tx_log_entry_type_invalid,
+	ol_tx_log_entry_type_queue_state,
+	ol_tx_log_entry_type_enqueue,
+	ol_tx_log_entry_type_dequeue,
+	ol_tx_log_entry_type_drop,
+	ol_tx_log_entry_type_queue_free,
+
+	ol_tx_log_entry_type_wrap,
+};
+
+struct ol_tx_log_queue_state_var_sz_t {
+	uint32_t active_bitmap;
+	uint16_t credit;
+	uint8_t num_cats_active;
+	uint8_t data[1];
+};
+
+struct ol_tx_log_queue_add_t {
+	uint8_t num_frms;
+	uint8_t tid;
+	uint16_t peer_id;
+	uint16_t num_bytes;
+};
+
+struct ol_mac_addr {
+	uint8_t mac_addr[OL_TXRX_MAC_ADDR_LEN];
+};
+
+struct ol_tx_sched_t;
+
+#ifndef ol_txrx_local_peer_id_t
+#define ol_txrx_local_peer_id_t uint8_t /* default */
+#endif
+
+#ifdef QCA_COMPUTE_TX_DELAY
+/*
+ * Delay histogram bins: 16 bins of 10 ms each to count delays
+ * from 0-160 ms, plus one overflow bin for delays > 160 ms.
+ */
+#define QCA_TX_DELAY_HIST_INTERNAL_BINS 17
+#define QCA_TX_DELAY_HIST_INTERNAL_BIN_WIDTH_MS 10
+
+struct ol_tx_delay_data {
+	struct {
+		uint64_t transmit_sum_ticks;
+		uint64_t queue_sum_ticks;
+		uint32_t transmit_num;
+		uint32_t queue_num;
+	} avgs;
+	uint16_t hist_bins_queue[QCA_TX_DELAY_HIST_INTERNAL_BINS];
+};
+
+#endif /* QCA_COMPUTE_TX_DELAY */
+
+/* Thermal Mitigation */
+enum throttle_phase {
+	THROTTLE_PHASE_OFF,
+	THROTTLE_PHASE_ON,
+	/* Invalid */
+	THROTTLE_PHASE_MAX,
+};
+
+#define THROTTLE_TX_THRESHOLD (100)
+
+/*
+ * Threshold to stop/start priority queue in term of % the actual flow start
+ * and stop thresholds. When num of available descriptors falls below
+ * stop_priority_th, priority queue will be paused. When num of available
+ * descriptors are greater than start_priority_th, priority queue will be
+ * un-paused.
+ */
+#define TX_PRIORITY_TH   (80)
+
+/*
+ * No of maximum descriptor used by TSO jumbo packet with
+ * 64K aggregation.
+ */
+#define MAX_TSO_SEGMENT_DESC (44)
+
+struct ol_tx_queue_group_t {
+	qdf_atomic_t credit;
+	u_int32_t membership;
+	int frm_count;
+};
+#define OL_TX_MAX_TXQ_GROUPS 2
+
+#define OL_TX_GROUP_STATS_LOG_SIZE 128
+struct ol_tx_group_credit_stats_t {
+	struct {
+		struct {
+			u_int16_t member_vdevs;
+			u_int16_t credit;
+		} grp[OL_TX_MAX_TXQ_GROUPS];
+	} stats[OL_TX_GROUP_STATS_LOG_SIZE];
+	u_int16_t last_valid_index;
+	u_int16_t wrap_around;
+};
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+
+/**
+ * enum flow_pool_status - flow pool status
+ * @FLOW_POOL_ACTIVE_UNPAUSED : pool is active (can take/put descriptors)
+ *				and network queues are unpaused
+ * @FLOW_POOL_ACTIVE_PAUSED: pool is active (can take/put descriptors)
+ *			   and network queues are paused
+ * @FLOW_POOL_INVALID: pool is invalid (put descriptor)
+ * @FLOW_POOL_INACTIVE: pool is inactive (pool is free)
+ * @FLOW_POOL_NON_PRIO_PAUSED: non-priority queues are paused
+ */
+enum flow_pool_status {
+	FLOW_POOL_ACTIVE_UNPAUSED = 0,
+	FLOW_POOL_ACTIVE_PAUSED = 1,
+	FLOW_POOL_NON_PRIO_PAUSED = 2,
+	FLOW_POOL_INVALID = 3,
+	FLOW_POOL_INACTIVE = 4
+};
+
+/**
+ * struct ol_txrx_pool_stats - flow pool related statistics
+ * @pool_map_count: flow pool map received
+ * @pool_unmap_count: flow pool unmap received
+ * @pool_resize_count: flow pool resize command received
+ * @pkt_drop_no_pool: packets dropped due to unavailablity of pool
+ */
+struct ol_txrx_pool_stats {
+	uint16_t pool_map_count;
+	uint16_t pool_unmap_count;
+	uint16_t pool_resize_count;
+	uint16_t pkt_drop_no_pool;
+};
+
+/**
+ * struct ol_tx_flow_pool_t - flow_pool info
+ * @flow_pool_list_elem: flow_pool_list element
+ * @flow_pool_lock: flow_pool lock
+ * @flow_pool_id: flow_pool id
+ * @flow_pool_size: flow_pool size
+ * @avail_desc: available descriptors
+ * @deficient_desc: deficient descriptors
+ * @overflow_desc: overflow descriptors
+ * @status: flow pool status
+ * @flow_type: flow pool type
+ * @member_flow_id: member flow id
+ * @stop_th: stop threshold
+ * @start_th: start threshold
+ * @freelist: tx descriptor freelist
+ * @pkt_drop_no_desc: drop due to no descriptors
+ * @ref_cnt: pool's ref count
+ * @stop_priority_th: Threshold to stop priority queue
+ * @start_priority_th: Threshold to start priority queue
+ */
+struct ol_tx_flow_pool_t {
+	TAILQ_ENTRY(ol_tx_flow_pool_t) flow_pool_list_elem;
+	qdf_spinlock_t flow_pool_lock;
+	uint8_t flow_pool_id;
+	uint16_t flow_pool_size;
+	uint16_t avail_desc;
+	uint16_t deficient_desc;
+	uint16_t overflow_desc;
+	enum flow_pool_status status;
+	enum htt_flow_type flow_type;
+	uint8_t member_flow_id;
+	uint16_t stop_th;
+	uint16_t start_th;
+	union ol_tx_desc_list_elem_t *freelist;
+	uint16_t pkt_drop_no_desc;
+	qdf_atomic_t ref_cnt;
+	uint16_t stop_priority_th;
+	uint16_t start_priority_th;
+};
+
+#endif
+
+/*
+ * struct ol_txrx_peer_id_map - Map of firmware peer_ids to peers on host
+ * @peer: Pointer to peer object
+ * @peer_id_ref_cnt: No. of firmware references to the peer_id
+ * @del_peer_id_ref_cnt: No. of outstanding unmap events for peer_id
+ *                       after the peer object is deleted on the host.
+ *
+ * peer_id is used as an index into the array of ol_txrx_peer_id_map.
+ */
+struct ol_txrx_peer_id_map {
+	struct ol_txrx_peer_t *peer;
+	qdf_atomic_t peer_id_ref_cnt;
+	qdf_atomic_t del_peer_id_ref_cnt;
+};
+
+/**
+ * ol_txrx_stats_req_internal - specifications of the requested
+ * statistics internally
+ */
+struct ol_txrx_stats_req_internal {
+    struct ol_txrx_stats_req base;
+    TAILQ_ENTRY(ol_txrx_stats_req_internal) req_list_elem;
+    int serviced; /* state of this request */
+    int offset;
+};
+
+struct ol_txrx_fw_stats_desc_t {
+	struct ol_txrx_stats_req_internal *req;
+	unsigned char desc_id;
+};
+
+struct ol_txrx_fw_stats_desc_elem_t {
+	struct ol_txrx_fw_stats_desc_elem_t *next;
+	struct ol_txrx_fw_stats_desc_t desc;
+};
+
+/*
+ * As depicted in the diagram below, the pdev contains an array of
+ * NUM_EXT_TID ol_tx_active_queues_in_tid_t elements.
+ * Each element identifies all the tx queues that are active for
+ * the TID, from the different peers.
+ *
+ * Each peer contains an array of NUM_EXT_TID ol_tx_frms_queue_t elements.
+ * Each element identifies the tx frames for the TID that need to be sent
+ * to the peer.
+ *
+ *
+ *  pdev: ol_tx_active_queues_in_tid_t active_in_tids[NUM_EXT_TIDS]
+ *                                TID
+ *       0            1            2                     17
+ *  +============+============+============+==    ==+============+
+ *  | active (y) | active (n) | active (n) |        | active (y) |
+ *  |------------+------------+------------+--    --+------------|
+ *  | queues     | queues     | queues     |        | queues     |
+ *  +============+============+============+==    ==+============+
+ *       |                                               |
+ *    .--+-----------------------------------------------'
+ *    |  |
+ *    |  |     peer X:                            peer Y:
+ *    |  |     ol_tx_frms_queue_t                 ol_tx_frms_queue_t
+ *    |  |     tx_queues[NUM_EXT_TIDS]            tx_queues[NUM_EXT_TIDS]
+ *    |  | TID +======+                       TID +======+
+ *    |  `---->| next |-------------------------->| next |--X
+ *    |     0  | prev |   .------.   .------.  0  | prev |   .------.
+ *    |        | txq  |-->|txdesc|-->|txdesc|     | txq  |-->|txdesc|
+ *    |        +======+   `------'   `------'     +======+   `------'
+ *    |        | next |      |          |      1  | next |      |
+ *    |     1  | prev |      v          v         | prev |      v
+ *    |        | txq  |   .------.   .------.     | txq  |   .------.
+ *    |        +======+   |netbuf|   |netbuf|     +======+   |netbuf|
+ *    |        | next |   `------'   `------'     | next |   `------'
+ *    |     2  | prev |                        2  | prev |
+ *    |        | txq  |                           | txq  |
+ *    |        +======+                           +======+
+ *    |        |      |                           |      |
+ *    |
+ *    |
+ *    |        |      |                           |      |
+ *    |        +======+                           +======+
+ *    `------->| next |--X                        | next |
+ *          17 | prev |   .------.             17 | prev |
+ *             | txq  |-->|txdesc|                | txq  |
+ *             +======+   `------'                +======+
+ *                           |
+ *                           v
+ *                        .------.
+ *                        |netbuf|
+ *                        `------'
+ */
+struct ol_txrx_pdev_t {
+	/* ctrl_pdev - handle for querying config info */
+	struct cdp_cfg *ctrl_pdev;
+
+	/* osdev - handle for mem alloc / free, map / unmap */
+	qdf_device_t osdev;
+
+	htt_pdev_handle htt_pdev;
+
+#ifdef WLAN_FEATURE_FASTPATH
+	struct CE_handle    *ce_tx_hdl; /* Handle to Tx packet posting CE */
+	struct CE_handle    *ce_htt_msg_hdl; /* Handle to TxRx completion CE */
+#endif /* WLAN_FEATURE_FASTPATH */
+
+	struct {
+		int is_high_latency;
+		int host_addba;
+		int ll_pause_txq_limit;
+		int default_tx_comp_req;
+		u8 credit_update_enabled;
+		u8 request_tx_comp;
+	} cfg;
+
+	/* WDI subscriber's event list */
+	wdi_event_subscribe **wdi_event_list;
+
+#if !defined(REMOVE_PKT_LOG) && !defined(QVIT)
+	bool pkt_log_init;
+	/* Pktlog pdev */
+	struct pktlog_dev_t *pl_dev;
+#endif /* #ifndef REMOVE_PKT_LOG */
+
+	enum ol_sec_type sec_types[htt_num_sec_types];
+	/* standard frame type */
+	enum wlan_frm_fmt frame_format;
+	enum htt_pkt_type htt_pkt_type;
+
+#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
+	/* txrx encap/decap   */
+	uint8_t sw_tx_encap;
+	uint8_t sw_rx_decap;
+	uint8_t target_tx_tran_caps;
+	uint8_t target_rx_tran_caps;
+	/* llc process */
+	uint8_t sw_tx_llc_proc_enable;
+	uint8_t sw_rx_llc_proc_enable;
+	/* A-MSDU */
+	uint8_t sw_subfrm_hdr_recovery_enable;
+	/* Protected Frame bit handling */
+	uint8_t sw_pf_proc_enable;
+#endif
+	/*
+	 * target tx credit -
+	 * not needed for LL, but used for HL download scheduler to keep
+	 * track of roughly how much space is available in the target for
+	 * tx frames
+	 */
+	qdf_atomic_t target_tx_credit;
+	qdf_atomic_t orig_target_tx_credit;
+
+	struct {
+		uint16_t pool_size;
+		struct ol_txrx_fw_stats_desc_elem_t *pool;
+		struct ol_txrx_fw_stats_desc_elem_t *freelist;
+		qdf_spinlock_t pool_lock;
+		qdf_atomic_t initialized;
+	} ol_txrx_fw_stats_desc_pool;
+
+	/* Peer mac address to staid mapping */
+	struct ol_mac_addr mac_to_staid[WLAN_MAX_STA_COUNT + 3];
+
+	/* ol_txrx_vdev list */
+	TAILQ_HEAD(, ol_txrx_vdev_t) vdev_list;
+
+	TAILQ_HEAD(, ol_txrx_stats_req_internal) req_list;
+	int req_list_depth;
+	qdf_spinlock_t req_list_spinlock;
+
+	/* peer ID to peer object map (array of pointers to peer objects) */
+	struct ol_txrx_peer_id_map *peer_id_to_obj_map;
+
+	struct {
+		unsigned int mask;
+		unsigned int idx_bits;
+
+		TAILQ_HEAD(, ol_txrx_peer_t) * bins;
+	} peer_hash;
+
+	/* rx specific processing */
+	struct {
+		struct {
+			TAILQ_HEAD(, ol_rx_reorder_t) waitlist;
+			uint32_t timeout_ms;
+		} defrag;
+		struct {
+			int defrag_timeout_check;
+			int dup_check;
+		} flags;
+
+		struct {
+			struct ol_tx_reorder_cat_timeout_t
+				access_cats[TXRX_NUM_WMM_AC];
+		} reorder_timeout;
+		qdf_spinlock_t mutex;
+	} rx;
+
+	/* rx proc function */
+	void (*rx_opt_proc)(struct ol_txrx_vdev_t *vdev,
+			    struct ol_txrx_peer_t *peer,
+			    unsigned int tid, qdf_nbuf_t msdu_list);
+
+	/* tx data delivery notification callback function */
+	struct {
+		ol_txrx_data_tx_cb func;
+		void *ctxt;
+	} tx_data_callback;
+
+	/* tx management delivery notification callback functions */
+	struct {
+		ol_txrx_mgmt_tx_cb download_cb;
+		ol_txrx_mgmt_tx_cb ota_ack_cb;
+		void *ctxt;
+	} tx_mgmt_cb;
+
+	data_stall_detect_cb data_stall_detect_callback;
+	/* packetdump callback functions */
+	tp_ol_packetdump_cb ol_tx_packetdump_cb;
+	tp_ol_packetdump_cb ol_rx_packetdump_cb;
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+	tp_ol_timestamp_cb ol_tx_timestamp_cb;
+#endif
+
+	struct {
+		uint16_t pool_size;
+		uint16_t num_free;
+		union ol_tx_desc_list_elem_t *array;
+		union ol_tx_desc_list_elem_t *freelist;
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+		uint8_t num_invalid_bin;
+		qdf_spinlock_t flow_pool_list_lock;
+		TAILQ_HEAD(flow_pool_list_t, ol_tx_flow_pool_t) flow_pool_list;
+#endif
+		uint32_t page_size;
+		uint16_t desc_reserved_size;
+		uint8_t page_divider;
+		uint32_t offset_filter;
+		struct qdf_mem_multi_page_t desc_pages;
+#ifdef DESC_DUP_DETECT_DEBUG
+		unsigned long *free_list_bitmap;
+#endif
+	} tx_desc;
+
+	uint8_t is_mgmt_over_wmi_enabled;
+#if defined(QCA_LL_TX_FLOW_CONTROL_V2)
+	struct ol_txrx_pool_stats pool_stats;
+	uint32_t num_msdu_desc;
+#ifdef QCA_LL_TX_FLOW_GLOBAL_MGMT_POOL
+	struct ol_tx_flow_pool_t *mgmt_pool;
+#endif
+#endif
+
+	struct {
+		int (*cmp)(union htt_rx_pn_t *new,
+			   union htt_rx_pn_t *old,
+			   int is_unicast, int opmode);
+		int len;
+	} rx_pn[htt_num_sec_types];
+
+	/* tx mutex */
+	OL_TX_MUTEX_TYPE tx_mutex;
+
+	/*
+	 * peer ref mutex:
+	 * 1. Protect peer object lookups until the returned peer object's
+	 *    reference count is incremented.
+	 * 2. Provide mutex when accessing peer object lookup structures.
+	 */
+	OL_RX_MUTEX_TYPE peer_ref_mutex;
+
+	/*
+	 * last_real_peer_mutex:
+	 * Protect lookups of any vdev's last_real_peer pointer until the
+	 * reference count for the pointed-to peer object is incremented.
+	 * This mutex could be in the vdev struct, but it's slightly simpler
+	 * to have a single lock in the pdev struct.  Since the lock is only
+	 * held for an extremely short time, and since it's very unlikely for
+	 * two vdev's to concurrently access the lock, there's no real
+	 * benefit to having a per-vdev lock.
+	 */
+	OL_RX_MUTEX_TYPE last_real_peer_mutex;
+
+	qdf_spinlock_t peer_map_unmap_lock;
+
+	struct {
+		struct {
+			struct {
+				struct {
+					uint64_t ppdus;
+					uint64_t mpdus;
+				} normal;
+				struct {
+					/*
+					 * mpdu_bad is general -
+					 * replace it with the specific counters
+					 * below
+					 */
+					uint64_t mpdu_bad;
+					/* uint64_t mpdu_fcs; */
+					/* uint64_t mpdu_duplicate; */
+					/* uint64_t mpdu_pn_replay; */
+					/* uint64_t mpdu_bad_sender; */
+					/* ^ comment: peer not found */
+					/* uint64_t mpdu_flushed; */
+					/* uint64_t msdu_defrag_mic_err; */
+					uint64_t msdu_mc_dup_drop;
+				} err;
+			} rx;
+		} priv;
+		struct ol_txrx_stats pub;
+	} stats;
+
+#if defined(ENABLE_RX_REORDER_TRACE)
+	struct {
+		uint32_t mask;
+		uint32_t idx;
+		uint64_t cnt;
+#define TXRX_RX_REORDER_TRACE_SIZE_LOG2 8       /* 256 entries */
+		struct {
+			uint16_t reorder_idx;
+			uint16_t seq_num;
+			uint8_t num_mpdus;
+			uint8_t tid;
+		} *data;
+	} rx_reorder_trace;
+#endif /* ENABLE_RX_REORDER_TRACE */
+
+#if defined(ENABLE_RX_PN_TRACE)
+	struct {
+		uint32_t mask;
+		uint32_t idx;
+		uint64_t cnt;
+#define TXRX_RX_PN_TRACE_SIZE_LOG2 5    /* 32 entries */
+		struct {
+			struct ol_txrx_peer_t *peer;
+			uint32_t pn32;
+			uint16_t seq_num;
+			uint8_t unicast;
+			uint8_t tid;
+		} *data;
+	} rx_pn_trace;
+#endif /* ENABLE_RX_PN_TRACE */
+
+#if defined(PERE_IP_HDR_ALIGNMENT_WAR)
+	bool host_80211_enable;
+#endif
+
+	/*
+	 * tx_sched only applies for HL, but is defined unconditionally
+	 * rather than  only if defined(CONFIG_HL_SUPPORT).
+	 * This is because the struct only
+	 * occupies a few bytes, and to avoid the complexity of
+	 * wrapping references
+	 * to the struct members in "defined(CONFIG_HL_SUPPORT)" conditional
+	 * compilation.
+	 * If this struct gets expanded to a non-trivial size,
+	 * then it should be
+	 * conditionally compiled to only apply if defined(CONFIG_HL_SUPPORT).
+	 */
+	qdf_spinlock_t tx_queue_spinlock;
+	struct {
+		enum ol_tx_scheduler_status tx_sched_status;
+		struct ol_tx_sched_t *scheduler;
+		struct ol_tx_frms_queue_t *last_used_txq;
+	} tx_sched;
+	/*
+	 * tx_queue only applies for HL, but is defined unconditionally to avoid
+	 * wrapping references to tx_queue in "defined(CONFIG_HL_SUPPORT)"
+	 * conditional compilation.
+	 */
+	struct {
+		qdf_atomic_t rsrc_cnt;
+		/* threshold_lo - when to start tx desc margin replenishment */
+		uint16_t rsrc_threshold_lo;
+		/*
+		 * threshold_hi - where to stop during tx desc margin
+		 * replenishment
+		 */
+		uint16_t rsrc_threshold_hi;
+	} tx_queue;
+
+#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
+#define OL_TXQ_LOG_SIZE 512
+	qdf_spinlock_t txq_log_spinlock;
+	struct {
+		int size;
+		int oldest_record_offset;
+		int offset;
+		int allow_wrap;
+		u_int32_t wrapped;
+		/* aligned to u_int32_t boundary */
+		u_int8_t data[OL_TXQ_LOG_SIZE];
+	} txq_log;
+#endif
+
+#ifdef QCA_ENABLE_OL_TXRX_PEER_STATS
+	qdf_spinlock_t peer_stat_mutex;
+#endif
+
+	int rssi_update_shift;
+	int rssi_new_weight;
+#ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID
+	struct {
+		ol_txrx_local_peer_id_t pool[OL_TXRX_NUM_LOCAL_PEER_IDS + 1];
+		ol_txrx_local_peer_id_t freelist;
+		qdf_spinlock_t lock;
+		ol_txrx_peer_handle map[OL_TXRX_NUM_LOCAL_PEER_IDS];
+	} local_peer_ids;
+#endif
+
+#ifdef QCA_COMPUTE_TX_DELAY
+#ifdef QCA_COMPUTE_TX_DELAY_PER_TID
+#define QCA_TX_DELAY_NUM_CATEGORIES \
+	(OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES)
+#else
+#define QCA_TX_DELAY_NUM_CATEGORIES 1
+#endif
+	struct {
+		qdf_spinlock_t mutex;
+		struct {
+			struct ol_tx_delay_data copies[2]; /* ping-pong */
+			int in_progress_idx;
+			uint32_t avg_start_time_ticks;
+		} cats[QCA_TX_DELAY_NUM_CATEGORIES];
+		uint32_t tx_compl_timestamp_ticks;
+		uint32_t avg_period_ticks;
+		uint32_t hist_internal_bin_width_mult;
+		uint32_t hist_internal_bin_width_shift;
+	} tx_delay;
+
+	uint16_t packet_count[QCA_TX_DELAY_NUM_CATEGORIES];
+	uint16_t packet_loss_count[QCA_TX_DELAY_NUM_CATEGORIES];
+
+#endif /* QCA_COMPUTE_TX_DELAY */
+
+	struct {
+		qdf_spinlock_t mutex;
+		/* timer used to monitor the throttle "on" phase and
+		 * "off" phase
+		 */
+		qdf_timer_t phase_timer;
+		/* timer used to send tx frames */
+		qdf_timer_t tx_timer;
+		/* This is the time in ms of the throttling window, it will
+		 * include an "on" phase and an "off" phase
+		 */
+		uint32_t throttle_period_ms;
+		/* Current throttle level set by the client ex. level 0,
+		 * level 1, etc
+		 */
+		enum throttle_level current_throttle_level;
+		/* Index that points to the phase within the throttle period */
+		enum throttle_phase current_throttle_phase;
+		/* Maximum number of frames to send to the target at one time */
+		uint32_t tx_threshold;
+		/* stores time in ms of on/off phase for each throttle level */
+		int throttle_time_ms[THROTTLE_LEVEL_MAX][THROTTLE_PHASE_MAX];
+		/* mark true if traffic is paused due to thermal throttling */
+		bool is_paused;
+	} tx_throttle;
+
+#if defined(FEATURE_TSO)
+	struct {
+		uint16_t pool_size;
+		uint16_t num_free;
+		struct qdf_tso_seg_elem_t *freelist;
+		/* tso mutex */
+		OL_TX_MUTEX_TYPE tso_mutex;
+	} tso_seg_pool;
+	struct {
+		uint16_t num_seg_pool_size;
+		uint16_t num_free;
+		struct qdf_tso_num_seg_elem_t *freelist;
+		/* tso mutex */
+		OL_TX_MUTEX_TYPE tso_num_seg_mutex;
+	} tso_num_seg_pool;
+#endif
+
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
+	struct {
+		enum ol_tx_peer_bal_state enabled;
+		qdf_spinlock_t mutex;
+		/* timer used to trigger more frames for bad peers */
+		qdf_timer_t peer_bal_timer;
+		/*This is the time in ms of the peer balance timer period */
+		u_int32_t peer_bal_period_ms;
+		/*This is the txq limit */
+		u_int32_t peer_bal_txq_limit;
+		/*This is the state of the peer balance timer */
+		enum ol_tx_peer_bal_timer_state peer_bal_timer_state;
+		/*This is the counter about active peers which are under
+		 *tx flow control
+		 */
+		u_int32_t peer_num;
+		/*This is peer list which are under tx flow control */
+		struct ol_tx_limit_peer_t limit_list[MAX_NO_PEERS_IN_LIMIT];
+		/*This is threshold configurationl */
+		struct tx_peer_threshold ctl_thresh[TXRX_IEEE11_MAX];
+	} tx_peer_bal;
+#endif /* CONFIG_Hl_SUPPORT && QCA_BAD_PEER_TX_FLOW_CL */
+
+	struct ol_tx_queue_group_t txq_grps[OL_TX_MAX_TXQ_GROUPS];
+#if defined(FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL) && \
+	defined(FEATURE_HL_DBS_GROUP_CREDIT_SHARING)
+	bool limit_lend;
+	u16 min_reserve;
+#endif
+#ifdef DEBUG_HL_LOGGING
+		qdf_spinlock_t grp_stat_spinlock;
+		struct ol_tx_group_credit_stats_t grp_stats;
+#endif
+	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;
+	tx_pause_callback pause_cb;
+
+	void (*offld_flush_cb)(void *);
+	struct ol_txrx_peer_t *self_peer;
+	qdf_work_t peer_unmap_timer_work;
+
+	/* dp debug fs */
+	struct dentry *dpt_stats_log_dir;
+	enum qdf_dpt_debugfs_state state;
+	struct qdf_debugfs_fops dpt_debugfs_fops;
+
+#ifdef IPA_OFFLOAD
+	ipa_uc_op_cb_type ipa_uc_op_cb;
+	void *usr_ctxt;
+	struct ol_txrx_ipa_resources ipa_resource;
+#endif /* IPA_UC_OFFLOAD */
+};
+
+struct ol_txrx_vdev_t {
+	struct ol_txrx_pdev_t *pdev; /* pdev - the physical device that is
+				      * the parent of this virtual device
+				      */
+	uint8_t vdev_id;             /* ID used to specify a particular vdev
+				      * to the target
+				      */
+	void *osif_dev;
+
+	void *ctrl_vdev; /* vdev objmgr handle */
+
+	union ol_txrx_align_mac_addr_t mac_addr; /* MAC address */
+	/* tx paused - NO LONGER NEEDED? */
+	TAILQ_ENTRY(ol_txrx_vdev_t) vdev_list_elem; /* node in the pdev's list
+						     * of vdevs
+						     */
+	TAILQ_HEAD(peer_list_t, ol_txrx_peer_t) peer_list;
+	struct ol_txrx_peer_t *last_real_peer; /* last real peer created for
+						* this vdev (not "self"
+						* pseudo-peer)
+						*/
+	ol_txrx_rx_fp rx; /* receive function used by this vdev */
+	ol_txrx_stats_rx_fp stats_rx; /* receive function used by this vdev */
+
+	struct {
+		uint32_t txack_success;
+		uint32_t txack_failed;
+	} txrx_stats;
+
+	/* completion function used by this vdev*/
+	ol_txrx_completion_fp tx_comp;
+
+	struct {
+		/*
+		 * If the vdev object couldn't be deleted immediately because
+		 * it still had some peer objects left, remember that a delete
+		 * was requested, so it can be deleted once all its peers have
+		 * been deleted.
+		 */
+		int pending;
+		/*
+		 * Store a function pointer and a context argument to provide a
+		 * notification for when the vdev is deleted.
+		 */
+		ol_txrx_vdev_delete_cb callback;
+		void *context;
+		atomic_t detaching;
+	} delete;
+
+	/* safe mode control to bypass the encrypt and decipher process */
+	uint32_t safemode;
+
+	/* rx filter related */
+	uint32_t drop_unenc;
+	struct privacy_exemption privacy_filters[MAX_PRIVACY_FILTERS];
+	uint32_t num_filters;
+
+	enum wlan_op_mode opmode;
+
+#ifdef QCA_IBSS_SUPPORT
+	/* ibss mode related */
+	int16_t ibss_peer_num;  /* the number of active peers */
+	int16_t ibss_peer_heart_beat_timer; /* for detecting peer departure */
+#endif
+
+#if defined(CONFIG_HL_SUPPORT)
+	struct ol_tx_frms_queue_t txqs[OL_TX_VDEV_NUM_QUEUES];
+#endif
+
+	struct {
+		struct {
+			qdf_nbuf_t head;
+			qdf_nbuf_t tail;
+			int depth;
+		} txq;
+		uint32_t paused_reason;
+		qdf_spinlock_t mutex;
+		qdf_timer_t timer;
+		int max_q_depth;
+		bool is_q_paused;
+		bool is_q_timer_on;
+		uint32_t q_pause_cnt;
+		uint32_t q_unpause_cnt;
+		uint32_t q_overflow_cnt;
+	} ll_pause;
+	bool disable_intrabss_fwd;
+	qdf_atomic_t os_q_paused;
+	uint16_t tx_fl_lwm;
+	uint16_t tx_fl_hwm;
+	qdf_spinlock_t flow_control_lock;
+	ol_txrx_tx_flow_control_fp osif_flow_control_cb;
+	ol_txrx_tx_flow_control_is_pause_fp osif_flow_control_is_pause;
+	void *osif_fc_ctx;
+
+#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
+	union ol_txrx_align_mac_addr_t hl_tdls_ap_mac_addr;
+	bool hlTdlsFlag;
+#endif
+
+#if defined(QCA_HL_NETDEV_FLOW_CONTROL)
+	qdf_atomic_t tx_desc_count;
+	int tx_desc_limit;
+	int queue_restart_th;
+	int queue_stop_th;
+	int prio_q_paused;
+#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
+
+	uint16_t wait_on_peer_id;
+	union ol_txrx_align_mac_addr_t last_peer_mac_addr;
+	qdf_event_t wait_delete_comp;
+#if defined(FEATURE_TSO)
+	struct {
+		int pool_elems; /* total number of elements in the pool */
+		int alloc_cnt; /* number of allocated elements */
+		uint32_t *freelist; /* free list of qdf_tso_seg_elem_t */
+	} tso_pool_t;
+#endif
+
+	/* last channel change event received */
+	struct {
+		bool is_valid;  /* whether the rest of the members are valid */
+		uint16_t mhz;
+		uint16_t band_center_freq1;
+		uint16_t band_center_freq2;
+		WLAN_PHY_MODE phy_mode;
+	} ocb_channel_event;
+
+	/* Information about the schedules in the schedule */
+	struct ol_txrx_ocb_chan_info *ocb_channel_info;
+	uint32_t ocb_channel_count;
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+	struct ol_tx_flow_pool_t *pool;
+#endif
+	/* intra bss forwarded tx and rx packets count */
+	uint64_t fwd_tx_packets;
+	uint64_t fwd_rx_packets;
+	bool is_wisa_mode_enable;
+	uint8_t mac_id;
+};
+
+struct ol_rx_reorder_array_elem_t {
+	qdf_nbuf_t head;
+	qdf_nbuf_t tail;
+};
+
+struct ol_rx_reorder_t {
+	uint8_t win_sz;
+	uint8_t win_sz_mask;
+	uint8_t num_mpdus;
+	struct ol_rx_reorder_array_elem_t *array;
+	/* base - single rx reorder element used for non-aggr cases */
+	struct ol_rx_reorder_array_elem_t base;
+#if defined(QCA_SUPPORT_OL_RX_REORDER_TIMEOUT)
+	struct ol_rx_reorder_timeout_list_elem_t timeout;
+#endif
+	/* only used for defrag right now */
+	TAILQ_ENTRY(ol_rx_reorder_t) defrag_waitlist_elem;
+	uint32_t defrag_timeout_ms;
+	/* get back to parent ol_txrx_peer_t when ol_rx_reorder_t is in a
+	 * waitlist
+	 */
+	uint16_t tid;
+};
+
+enum {
+	txrx_sec_mcast = 0,
+	txrx_sec_ucast
+};
+
+typedef A_STATUS (*ol_tx_filter_func)(struct ol_txrx_msdu_info_t *
+				      tx_msdu_info);
+
+#define OL_TXRX_PEER_SECURITY_MULTICAST  0
+#define OL_TXRX_PEER_SECURITY_UNICAST    1
+#define OL_TXRX_PEER_SECURITY_MAX        2
+
+
+/* Allow 6000 ms to receive peer unmap events after peer is deleted */
+#define OL_TXRX_PEER_UNMAP_TIMEOUT (6000)
+
+struct ol_txrx_cached_bufq_t {
+	/* cached_bufq is used to enqueue the pending RX frames from a peer
+	 * before the peer is registered for data service. The list will be
+	 * flushed to HDD once that station is registered.
+	 */
+	struct list_head cached_bufq;
+	/* mutual exclusion lock to access the cached_bufq queue */
+	qdf_spinlock_t bufq_lock;
+	/* # entries in queue after which  subsequent adds will be dropped */
+	uint32_t thresh;
+	/* # entries in present in cached_bufq */
+	uint32_t curr;
+	/* # max num of entries in the queue if bufq thresh was not in place */
+	uint32_t high_water_mark;
+	/* # max num of entries in the queue if we did not drop packets */
+	uint32_t qdepth_no_thresh;
+	/* # of packes (beyond threshold) dropped from cached_bufq */
+	uint32_t dropped;
+};
+
+struct ol_txrx_peer_t {
+	struct ol_txrx_vdev_t *vdev;
+
+	/* UMAC peer objmgr handle */
+	struct cdp_ctrl_objmgr_peer *ctrl_peer;
+
+	qdf_atomic_t ref_cnt;
+	qdf_atomic_t access_list[PEER_DEBUG_ID_MAX];
+	qdf_atomic_t delete_in_progress;
+	qdf_atomic_t flush_in_progress;
+
+	/* The peer state tracking is used for HL systems
+	 * that don't support tx and rx filtering within the target.
+	 * In such systems, the peer's state determines what kind of
+	 * tx and rx filtering, if any, is done.
+	 * This variable doesn't apply to LL systems, or to HL systems for
+	 * which the target handles tx and rx filtering. However, it is
+	 * simplest to declare and update this variable unconditionally,
+	 * for all systems.
+	 */
+	enum ol_txrx_peer_state state;
+	qdf_spinlock_t peer_info_lock;
+
+	/* Wrapper around the cached_bufq list */
+	struct ol_txrx_cached_bufq_t bufq_info;
+
+	ol_tx_filter_func tx_filter;
+
+	/* peer ID(s) for this peer */
+	uint16_t peer_ids[MAX_NUM_PEER_ID_PER_PEER];
+#ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID
+	uint16_t local_id;
+#endif
+
+	union ol_txrx_align_mac_addr_t mac_addr;
+
+	/* node in the vdev's list of peers */
+	TAILQ_ENTRY(ol_txrx_peer_t) peer_list_elem;
+	/* node in the hash table bin's list of peers */
+	TAILQ_ENTRY(ol_txrx_peer_t) hash_list_elem;
+
+	/*
+	 * per TID info -
+	 * stored in separate arrays to avoid alignment padding mem overhead
+	 */
+	struct ol_rx_reorder_t tids_rx_reorder[OL_TXRX_NUM_EXT_TIDS];
+	union htt_rx_pn_t tids_last_pn[OL_TXRX_NUM_EXT_TIDS];
+	uint8_t tids_last_pn_valid[OL_TXRX_NUM_EXT_TIDS];
+	uint8_t tids_rekey_flag[OL_TXRX_NUM_EXT_TIDS];
+	uint16_t tids_next_rel_idx[OL_TXRX_NUM_EXT_TIDS];
+	uint16_t tids_last_seq[OL_TXRX_NUM_EXT_TIDS];
+	uint16_t tids_mcast_last_seq[OL_TXRX_NUM_EXT_TIDS];
+
+	struct {
+		enum htt_sec_type sec_type;
+		uint32_t michael_key[2];        /* relevant for TKIP */
+	} security[2];          /* 0 -> multicast, 1 -> unicast */
+
+	/*
+	 * rx proc function: this either is a copy of pdev's rx_opt_proc for
+	 * regular rx processing, or has been redirected to a /dev/null discard
+	 * function when peer deletion is in progress.
+	 */
+	void (*rx_opt_proc)(struct ol_txrx_vdev_t *vdev,
+			    struct ol_txrx_peer_t *peer,
+			    unsigned int tid, qdf_nbuf_t msdu_list);
+
+#if defined(CONFIG_HL_SUPPORT)
+	struct ol_tx_frms_queue_t txqs[OL_TX_NUM_TIDS];
+#endif
+
+#ifdef QCA_ENABLE_OL_TXRX_PEER_STATS
+	ol_txrx_peer_stats_t stats;
+#endif
+	int16_t rssi_dbm;
+
+	/* NAWDS Flag and Bss Peer bit */
+	uint16_t nawds_enabled:1, bss_peer:1, valid:1;
+
+	/* QoS info */
+	uint8_t qos_capable;
+	/* U-APSD tid mask */
+	uint8_t uapsd_mask;
+	/*flag indicating key installed */
+	uint8_t keyinstalled;
+
+	/* Bit to indicate if PN check is done in fw */
+	qdf_atomic_t fw_pn_check;
+
+#ifdef WLAN_FEATURE_11W
+	/* PN counter for Robust Management Frames */
+	uint64_t last_rmf_pn;
+	uint32_t rmf_pn_replays;
+	uint8_t last_rmf_pn_valid;
+#endif
+
+	/* Properties of the last received PPDU */
+	int16_t last_pkt_rssi_cmb;
+	int16_t last_pkt_rssi[4];
+	uint8_t last_pkt_legacy_rate;
+	uint8_t last_pkt_legacy_rate_sel;
+	uint32_t last_pkt_timestamp_microsec;
+	uint8_t last_pkt_timestamp_submicrosec;
+	uint32_t last_pkt_tsf;
+	uint8_t last_pkt_tid;
+	uint16_t last_pkt_center_freq;
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
+	u_int16_t tx_limit;
+	u_int16_t tx_limit_flag;
+	u_int16_t tx_pause_flag;
+#endif
+	qdf_time_t last_assoc_rcvd;
+	qdf_time_t last_disassoc_rcvd;
+	qdf_time_t last_deauth_rcvd;
+	qdf_atomic_t fw_create_pending;
+	qdf_timer_t peer_unmap_timer;
+};
+
+struct ol_rx_remote_data {
+	qdf_nbuf_t msdu;
+	uint8_t mac_id;
+};
+
+struct ol_fw_data {
+	void *data;
+	uint32_t len;
+};
+
+#define INVALID_REORDER_INDEX 0xFFFF
+
+#define SPS_DESC_SIZE 8
+
+#endif /* _OL_TXRX_TYPES__H_ */
diff --git a/core/dp/txrx/txrx.h b/core/dp/txrx/txrx.h
new file mode 100644
index 0000000..10a3f6a
--- /dev/null
+++ b/core/dp/txrx/txrx.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2013-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.
+ */
+
+#ifndef TXRX_H
+#define TXRX_H
+
+#include "cds_api.h"
+#include "qdf_nbuf.h"
+#include "csr_api.h"
+#include "sap_api.h"
+#include "ol_txrx_osif_api.h"
+
+/* wait on peer deletion timeout value in milliseconds */
+#define PEER_DELETION_TIMEOUT 500
+
+enum txrx_wmm_ac {
+	TXRX_WMM_AC_BE,
+	TXRX_WMM_AC_BK,
+	TXRX_WMM_AC_VI,
+	TXRX_WMM_AC_VO,
+
+	TXRX_NUM_WMM_AC
+};
+
+struct txrx_rx_metainfo {
+	u8 up;
+	u16 dest_staid;
+};
+
+enum bt_frame_type {
+	/* BT-AMP packet of type data */
+	TXRX_BT_AMP_TYPE_DATA = 0x0001,
+
+	/* BT-AMP packet of type activity report */
+	TXRX_BT_AMP_TYPE_AR = 0x0002,
+
+	/* BT-AMP packet of type security frame */
+	TXRX_BT_AMP_TYPE_SEC = 0x0003,
+
+	/* BT-AMP packet of type Link Supervision request frame */
+	TXRX_BT_AMP_TYPE_LS_REQ = 0x0004,
+
+	/* BT-AMP packet of type Link Supervision reply frame */
+	TXRX_BT_AMP_TYPE_LS_REP = 0x0005,
+
+	/* Invalid Frame */
+	TXRX_BAP_INVALID_FRAME
+};
+
+enum wlan_ts_direction {
+	/* uplink */
+	WLAN_TX_DIR = 0,
+
+	/* downlink */
+	WLAN_RX_DIR = 1,
+
+	/*bidirectional */
+	WLAN_BI_DIR = 2,
+};
+
+enum wlan_sta_state {
+	/* Transition in this state made upon creation */
+	WLAN_STA_INIT = 0,
+
+	/*
+	 * Transition happens after Assoc success if second level authentication
+	 * is needed
+	 */
+	WLAN_STA_CONNECTED,
+
+	/*
+	 * Transition happens when second level auth is successful and keys are
+	 * properly installed
+	 */
+	WLAN_STA_AUTHENTICATED,
+
+	/* Transition happens when connectivity is lost */
+	WLAN_STA_DISCONNECTED,
+
+	WLAN_STA_MAX_STATE
+};
+
+struct wlan_txrx_stats {
+	/* Define various txrx stats here */
+};
+
+struct ol_txrx_vdev_t;
+
+QDF_STATUS wlan_register_mgmt_client(void *pdev_txrx,
+				     QDF_STATUS (*rx_mgmt)(void *g_cdsctx,
+							   void *buf));
+
+/* If RSSI realm is changed, send notification to Clients, SME, HDD */
+typedef QDF_STATUS (*wlan_txrx_rssi_cross_thresh)(void *adapter, u8 rssi,
+						  void *usr_ctx,
+						  int8_t avg_rssi);
+
+/* Rx callback registered with txrx */
+typedef int (*wlan_txrx_cb_type)(void *g_cdsctx, qdf_nbuf_t buf, u8 sta_id,
+				 struct txrx_rx_metainfo *rx_meta_info);
+
+static inline int wlan_txrx_get_rssi(void *g_cdsctx, u8 sta_id, int8_t *rssi)
+{
+	return 0;
+}
+
+static inline int wlan_txrx_enable_uapsd_ac(void *g_cdsctx, u8 sta_id,
+					    enum txrx_wmm_ac ac, u8 tid, u8 up,
+					    u32 srv_int, u32 suspend_int,
+					    enum wlan_ts_direction ts_dir)
+{
+	return 0;
+}
+
+static inline int wlan_txrx_disable_uapsd_ac(void *g_cdsctx, u8 sta_id,
+					     enum txrx_wmm_ac ac)
+{
+	return 0;
+}
+
+static inline int wlan_change_sta_state(void *g_cdsctx, u8 sta_id,
+					enum wlan_sta_state state)
+{
+	return 0;
+}
+
+static inline int wlan_deregister_mgmt_client(void *g_cdsctx)
+{
+	return 0;
+}
+
+static inline void wlan_assoc_failed(u8 staid)
+{
+}
+
+static inline int wlan_get_ap_stats(void *g_cdsctx, tSap_SoftapStats *buf,
+				    bool reset)
+{
+	return 0;
+}
+
+static inline int wlan_get_txrx_stats(void *g_cdsctx,
+				      struct wlan_txrx_stats *stats, u8 sta_id)
+{
+	return 0;
+}
+
+static inline int wlan_txrx_update_rssi_bmps(void *g_cdsctx, u8 sta_id,
+					     int8_t rssi)
+{
+	return 0;
+}
+
+static inline int wlan_txrx_deregister_rssi_indcb(void *g_cdsctx,
+						  int8_t rssi_val,
+						  u8 trigger_event,
+						  wlan_txrx_rssi_cross_thresh
+						  cb, int mod_id)
+{
+	return 0;
+}
+
+static inline int wlan_txrx_register_rssi_indcb(void *g_cdsctx,
+						int8_t rssi_val,
+						u8 trigger_event,
+						wlan_txrx_rssi_cross_thresh cb,
+						int mod_id, void *usr_ctx)
+{
+	return 0;
+}
+
+#endif
diff --git a/core/dp/txrx/wdi_event.h b/core/dp/txrx/wdi_event.h
new file mode 100644
index 0000000..12d67d8
--- /dev/null
+++ b/core/dp/txrx/wdi_event.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#ifndef _WDI_EVENT_H_
+#define _WDI_EVENT_H_
+
+#include "athdefs.h"
+#include "qdf_nbuf.h"
+#define WDI_EVENT_BASE 0x100    /* Event starting number */
+
+#define WDI_NO_VAL (-1)
+enum WDI_EVENT {
+	WDI_EVENT_TX_STATUS = WDI_EVENT_BASE,
+	WDI_EVENT_OFFLOAD_ALL,
+	WDI_EVENT_RX_DESC,
+	WDI_EVENT_RX_DESC_REMOTE,
+	WDI_EVENT_RATE_FIND,
+	WDI_EVENT_RATE_UPDATE,
+	WDI_EVENT_SW_EVENT,
+	WDI_EVENT_RX_PEER_INVALID,
+	/* From WIN definations */
+	WDI_EVENT_LITE_RX,
+	WDI_EVENT_LITE_T2H,
+	/* End of new event items */
+
+	WDI_EVENT_LAST
+};
+
+struct wdi_event_rx_peer_invalid_msg {
+	qdf_nbuf_t msdu;
+	struct ieee80211_frame *wh;
+	uint8_t vdev_id;
+};
+
+#define WDI_NUM_EVENTS  (WDI_EVENT_LAST - WDI_EVENT_BASE)
+
+#define WDI_EVENT_NOTIFY_BASE   0x200
+enum WDI_EVENT_NOTIFY {
+	WDI_EVENT_SUB_DEALLOCATE = WDI_EVENT_NOTIFY_BASE,
+	/* End of new notification types */
+
+	WDI_EVENT_NOTIFY_LAST
+};
+
+/* Opaque event callback */
+typedef void (*wdi_event_cb)(void *pdev, enum WDI_EVENT event, void *data,
+					u_int16_t peer_id, uint32_t status);
+
+/* Opaque event notify */
+typedef void (*wdi_event_notify)(enum WDI_EVENT_NOTIFY notify,
+				 enum WDI_EVENT event);
+
+/**
+ * @typedef wdi_event_subscribe
+ * @brief Used by consumers to subscribe to WDI event notifications.
+ * @details
+ *  The event_subscribe struct includes pointers to other event_subscribe
+ *  objects.  These pointers are simply to simplify the management of
+ *  lists of event subscribers.  These pointers are set during the
+ *  event_sub() function, and shall not be modified except by the
+ *  WDI event management SW, until after the object's event subscription
+ *  is canceled by calling event_unsub().
+ */
+
+typedef struct wdi_event_subscribe_t {
+	/* subscriber event callback structure head */
+	wdi_event_cb callback;
+	/* subscriber object that processes the event callback */
+	void *context;
+	struct {
+		/*
+		 * private - the event subscriber SW shall not use this struct
+		 */
+		struct wdi_event_subscribe_t *next;
+		struct wdi_event_subscribe_t *prev;
+	} priv;
+} wdi_event_subscribe;
+
+#endif
diff --git a/core/dp/txrx/wdi_event_api.h b/core/dp/txrx/wdi_event_api.h
new file mode 100644
index 0000000..85e26de
--- /dev/null
+++ b/core/dp/txrx/wdi_event_api.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012-2014, 2017-2018 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.
+ */
+
+#ifndef _WDI_EVENT_API_H_
+#define _WDI_EVENT_API_H_
+
+#include "wdi_event.h"
+#include <cdp_txrx_handle.h>
+struct ol_txrx_pdev_t;
+
+#ifdef WDI_EVENT_ENABLE
+/**
+ * @brief Subscribe to a specified WDI event.
+ * @details
+ *  This function adds the provided wdi_event_subscribe object to a list of
+ *  subscribers for the specified WDI event.
+ *  When the event in question happens, each subscriber for the event will
+ *  have their callback function invoked.
+ *  The order in which callback functions from multiple subscribers are
+ *  invoked is unspecified.
+ *
+ * @param pdev - the event physical device, that maintains the event lists
+ * @param event_cb_sub - the callback and context for the event subscriber
+ * @param event - which event's notifications are being subscribed to
+ * @return error code, or A_OK for success
+ */
+A_STATUS wdi_event_sub(struct cdp_pdev *ppdev,
+		       void *event_cb_sub,
+		       uint32_t event);
+
+/**
+ * @brief Unsubscribe from a specified WDI event.
+ * @details
+ *  This function removes the provided event subscription object from the
+ *  list of subscribers for its event.
+ *  This function shall only be called if there was a successful prior call
+ *  to event_sub() on the same wdi_event_subscribe object.
+ *
+ * @param pdev - the event physical device with the list of event subscribers
+ * @param event_cb_sub - the event subscription object
+ * @param event - which event is being unsubscribed
+ * @return error code, or A_OK for success
+ */
+A_STATUS wdi_event_unsub(struct cdp_pdev *ppdev,
+			 void *event_cb_sub,
+			 uint32_t event);
+
+
+void wdi_event_handler(enum WDI_EVENT event,
+		       struct cdp_pdev *txrx_pdev, void *data);
+A_STATUS wdi_event_attach(struct ol_txrx_pdev_t *txrx_pdev);
+A_STATUS wdi_event_detach(struct ol_txrx_pdev_t *txrx_pdev);
+
+#else
+
+static inline void wdi_event_handler(enum WDI_EVENT event,
+		       struct cdp_pdev *txrx_pdev, void *data)
+{
+}
+
+static inline A_STATUS wdi_event_attach(struct ol_txrx_pdev_t *txrx_pdev)
+{
+	return A_OK;
+}
+
+static inline A_STATUS wdi_event_detach(struct ol_txrx_pdev_t *txrx_pdev)
+{
+	return A_OK;
+}
+
+static inline A_STATUS wdi_event_sub(struct cdp_pdev *ppdev, void *event_cb_sub,
+				     uint32_t event)
+{
+	return A_OK;
+}
+
+static inline A_STATUS wdi_event_unsub(struct cdp_pdev *ppdev,
+				       void *event_cb_sub,
+				       uint32_t event)
+{
+	return A_OK;
+}
+#endif /* WDI_EVENT_ENABLE */
+
+#endif /* _WDI_EVENT_API_H_ */
diff --git a/core/dp/txrx3.0/dp_rx_thread.c b/core/dp/txrx3.0/dp_rx_thread.c
new file mode 100644
index 0000000..4d701dc
--- /dev/null
+++ b/core/dp/txrx3.0/dp_rx_thread.c
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#include <dp_txrx.h>
+#include <cdp_txrx_cmn_struct.h>
+#include <cdp_txrx_peer_ops.h>
+#include <cds_sched.h>
+
+/* Timeout in ms to wait for a DP rx thread */
+#define DP_RX_THREAD_WAIT_TIMEOUT 200
+
+#define DP_RX_TM_DEBUG 0
+#if DP_RX_TM_DEBUG
+/**
+ * dp_rx_tm_walk_skb_list() - Walk skb list and print members
+ * @nbuf_list - nbuf list to print
+ *
+ * Returns: None
+ */
+static inline void dp_rx_tm_walk_skb_list(qdf_nbuf_t nbuf_list)
+{
+	qdf_nbuf_t nbuf;
+	int i = 0;
+
+	nbuf = nbuf_list;
+	while (nbuf) {
+		dp_debug("%d nbuf:%pk nbuf->next:%pK nbuf->data:%pk ", i,
+			 nbuf, qdf_nbuf_next(nbuf), qdf_nbuf_data(nbuf));
+		nbuf = qdf_nbuf_next(nbuf);
+		i++;
+	}
+}
+#else
+static inline void dp_rx_tm_walk_skb_list(qdf_nbuf_t nbuf_list)
+{ }
+#endif /* DP_RX_TM_DEBUG */
+
+/**
+ * dp_rx_tm_thread_dump_stats() - display stats for a rx_thread
+ * @rx_thread - rx_thread pointer for which the stats need to be
+ *            displayed
+ *
+ * Returns: None
+ */
+static void dp_rx_tm_thread_dump_stats(struct dp_rx_thread *rx_thread)
+{
+	uint8_t reo_ring_num;
+	uint32_t off = 0;
+	char nbuf_queued_string[100];
+	uint32_t total_queued = 0;
+	uint32_t temp = 0;
+
+	qdf_mem_set(nbuf_queued_string, 0, sizeof(nbuf_queued_string));
+
+	for (reo_ring_num = 0; reo_ring_num < DP_RX_TM_MAX_REO_RINGS;
+	     reo_ring_num++) {
+		temp = rx_thread->stats.nbuf_queued[reo_ring_num];
+		if (!temp)
+			continue;
+		total_queued += temp;
+		if (off >= sizeof(nbuf_queued_string))
+			continue;
+		off += qdf_scnprintf(&nbuf_queued_string[off],
+				     sizeof(nbuf_queued_string) - off,
+				     "reo[%u]:%u ", reo_ring_num, temp);
+	}
+	dp_info("thread:%u - qlen:%u queued:(total:%u %s) dequeued:%u stack:%u max_len:%u invalid(peer:%u vdev:%u others:%u)",
+		rx_thread->id,
+		qdf_nbuf_queue_head_qlen(&rx_thread->nbuf_queue),
+		total_queued,
+		nbuf_queued_string,
+		rx_thread->stats.nbuf_dequeued,
+		rx_thread->stats.nbuf_sent_to_stack,
+		rx_thread->stats.nbufq_max_len,
+		rx_thread->stats.dropped_invalid_peer,
+		rx_thread->stats.dropped_invalid_vdev,
+		rx_thread->stats.dropped_others);
+}
+
+QDF_STATUS dp_rx_tm_dump_stats(struct dp_rx_tm_handle *rx_tm_hdl)
+{
+	int i;
+
+	for (i = 0; i < DP_MAX_RX_THREADS; i++) {
+		if (!rx_tm_hdl->rx_thread[i])
+			continue;
+		dp_rx_tm_thread_dump_stats(rx_tm_hdl->rx_thread[i]);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * dp_rx_tm_thread_enqueue() - enqueue nbuf list into rx_thread
+ * @rx_thread - rx_thread in which the nbuf needs to be queued
+ * @nbuf_list - list of packets to be queued into the thread
+ *
+ * Enqueue packet into rx_thread and wake it up. The function
+ * moves the next pointer of the nbuf_list into the ext list of
+ * the first nbuf for storage into the thread. Only the first
+ * nbuf is queued into the thread nbuf queue. The reverse is
+ * done at the time of dequeue.
+ *
+ * Returns: QDF_STATUS_SUCCESS on success or qdf error code on
+ * failure
+ */
+static QDF_STATUS dp_rx_tm_thread_enqueue(struct dp_rx_thread *rx_thread,
+					  qdf_nbuf_t nbuf_list)
+{
+	qdf_nbuf_t head_ptr, next_ptr_list;
+	uint32_t temp_qlen;
+	uint32_t num_elements_in_nbuf;
+	struct dp_rx_tm_handle_cmn *tm_handle_cmn;
+	uint8_t reo_ring_num = QDF_NBUF_CB_RX_CTX_ID(nbuf_list);
+	qdf_wait_queue_head_t *wait_q_ptr;
+
+	tm_handle_cmn = rx_thread->rtm_handle_cmn;
+
+	if (!tm_handle_cmn) {
+		dp_alert("tm_handle_cmn is null!");
+		QDF_BUG(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wait_q_ptr = dp_rx_thread_get_wait_queue(tm_handle_cmn);
+
+	if (reo_ring_num >= DP_RX_TM_MAX_REO_RINGS) {
+		dp_alert("incorrect ring %u", reo_ring_num);
+		QDF_BUG(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	num_elements_in_nbuf = QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(nbuf_list);
+
+	dp_rx_tm_walk_skb_list(nbuf_list);
+
+	head_ptr = nbuf_list;
+
+	/* Ensure head doesn't have an ext list */
+	while (qdf_unlikely(head_ptr && qdf_nbuf_get_ext_list(head_ptr))) {
+		QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(head_ptr) = 1;
+		num_elements_in_nbuf--;
+		next_ptr_list = head_ptr->next;
+		qdf_nbuf_set_next(head_ptr, NULL);
+		qdf_nbuf_queue_head_enqueue_tail(&rx_thread->nbuf_queue,
+						 head_ptr);
+		head_ptr = next_ptr_list;
+	}
+
+	if (!head_ptr)
+		goto enq_done;
+
+	next_ptr_list = head_ptr->next;
+
+	if (next_ptr_list) {
+		/* move ->next pointer to ext list */
+		qdf_nbuf_append_ext_list(head_ptr, next_ptr_list, 0);
+		dp_debug("appended next_ptr_list %pK to nbuf %pK ext list %pK",
+			 qdf_nbuf_next(nbuf_list), nbuf_list,
+			 qdf_nbuf_get_ext_list(nbuf_list));
+	}
+	qdf_nbuf_set_next(head_ptr, NULL);
+
+	qdf_nbuf_queue_head_enqueue_tail(&rx_thread->nbuf_queue, head_ptr);
+
+enq_done:
+	temp_qlen = qdf_nbuf_queue_head_qlen(&rx_thread->nbuf_queue);
+
+	rx_thread->stats.nbuf_queued[reo_ring_num] += num_elements_in_nbuf;
+
+	if (temp_qlen > rx_thread->stats.nbufq_max_len)
+		rx_thread->stats.nbufq_max_len = temp_qlen;
+
+	qdf_set_bit(RX_POST_EVENT, &rx_thread->event_flag);
+	qdf_wake_up_interruptible(wait_q_ptr);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * dp_rx_tm_thread_dequeue() - dequeue nbuf list from rx_thread
+ * @rx_thread - rx_thread from which the nbuf needs to be dequeued
+ *
+ * Returns: nbuf or nbuf_list dequeued from rx_thread
+ */
+static qdf_nbuf_t dp_rx_tm_thread_dequeue(struct dp_rx_thread *rx_thread)
+{
+	qdf_nbuf_t head, next_ptr_list, nbuf_list;
+
+	head = qdf_nbuf_queue_head_dequeue(&rx_thread->nbuf_queue);
+	nbuf_list = head;
+	if (head && QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(head) > 1) {
+		/* move ext list to ->next pointer */
+		next_ptr_list = qdf_nbuf_get_ext_list(head);
+		qdf_nbuf_append_ext_list(head, NULL, 0);
+		qdf_nbuf_set_next(nbuf_list, next_ptr_list);
+		dp_rx_tm_walk_skb_list(nbuf_list);
+	}
+	return nbuf_list;
+}
+
+/**
+ * dp_rx_thread_process_nbufq() - process nbuf queue of a thread
+ * @rx_thread - rx_thread whose nbuf queue needs to be processed
+ *
+ * Returns: 0 on success, error code on failure
+ */
+static int dp_rx_thread_process_nbufq(struct dp_rx_thread *rx_thread)
+{
+	qdf_nbuf_t nbuf_list;
+	uint32_t peer_local_id;
+	void *peer;
+	struct cdp_vdev *vdev;
+	ol_txrx_rx_fp stack_fn;
+	ol_osif_vdev_handle osif_vdev;
+	ol_txrx_soc_handle soc;
+	uint32_t num_list_elements = 0;
+	struct cdp_pdev *pdev;
+
+	struct dp_txrx_handle_cmn *txrx_handle_cmn;
+
+	txrx_handle_cmn =
+		dp_rx_thread_get_txrx_handle(rx_thread->rtm_handle_cmn);
+
+	soc = dp_txrx_get_soc_from_ext_handle(txrx_handle_cmn);
+	pdev = dp_txrx_get_pdev_from_ext_handle(txrx_handle_cmn);
+
+	if (!soc || !pdev) {
+		dp_err("invalid soc or pdev!");
+		QDF_BUG(0);
+		return -EFAULT;
+	}
+
+	nbuf_list = dp_rx_tm_thread_dequeue(rx_thread);
+	while (nbuf_list) {
+		num_list_elements =
+			QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(nbuf_list);
+		rx_thread->stats.nbuf_dequeued += num_list_elements;
+
+		peer_local_id = QDF_NBUF_CB_RX_PEER_LOCAL_ID(nbuf_list);
+		peer = cdp_peer_find_by_local_id(soc, pdev, peer_local_id);
+
+		if (!peer) {
+			rx_thread->stats.dropped_invalid_peer +=
+							num_list_elements;
+			dp_err("peer not found for local_id %u!",
+			       peer_local_id);
+			qdf_nbuf_list_free(nbuf_list);
+			goto dequeue_rx_thread;
+		}
+
+		vdev = cdp_peer_get_vdev(soc, peer);
+		if (!vdev) {
+			rx_thread->stats.dropped_invalid_vdev +=
+							num_list_elements;
+			dp_err("vdev not found for local_id %u!, pkt dropped",
+			       peer_local_id);
+			qdf_nbuf_list_free(nbuf_list);
+			goto dequeue_rx_thread;
+		}
+
+		cdp_get_os_rx_handles_from_vdev(soc, vdev, &stack_fn,
+						&osif_vdev);
+		if (!stack_fn || !osif_vdev) {
+			dp_alert("stack_fn or osif_vdev is null, pkt dropped!");
+			QDF_BUG(0);
+			rx_thread->stats.dropped_others +=
+							num_list_elements;
+			qdf_nbuf_list_free(nbuf_list);
+			goto dequeue_rx_thread;
+		}
+		stack_fn(osif_vdev, nbuf_list);
+		rx_thread->stats.nbuf_sent_to_stack += num_list_elements;
+
+dequeue_rx_thread:
+		nbuf_list = dp_rx_tm_thread_dequeue(rx_thread);
+	}
+
+	return 0;
+}
+
+/**
+ * dp_rx_thread_sub_loop() - rx thread subloop
+ * @rx_thread - rx_thread to be processed
+ * @shutdown - pointer to shutdown variable
+ *
+ * The function handles shutdown and suspend events from other
+ * threads and processes nbuf queue of a rx thread. In case a
+ * shutdown event is received from some other wlan thread, the
+ * function sets the shutdown pointer to true and returns
+ *
+ * Returns: 0 on success, error code on failure
+ */
+static int dp_rx_thread_sub_loop(struct dp_rx_thread *rx_thread, bool *shutdown)
+{
+	while (true) {
+		if (qdf_atomic_test_and_clear_bit(RX_SHUTDOWN_EVENT,
+						  &rx_thread->event_flag)) {
+			if (qdf_atomic_test_and_clear_bit(RX_SUSPEND_EVENT,
+							  &rx_thread->event_flag)) {
+				qdf_event_set(&rx_thread->suspend_event);
+			}
+			dp_debug("shutting down (%s) id %d pid %d",
+				 qdf_get_current_comm(), rx_thread->id,
+				 qdf_get_current_pid());
+			*shutdown = true;
+			break;
+		}
+
+		dp_rx_thread_process_nbufq(rx_thread);
+
+		if (qdf_atomic_test_and_clear_bit(RX_SUSPEND_EVENT,
+						  &rx_thread->event_flag)) {
+			dp_debug("received suspend ind (%s) id %d pid %d",
+				 qdf_get_current_comm(), rx_thread->id,
+				 qdf_get_current_pid());
+			qdf_spin_lock(&rx_thread->lock);
+			qdf_event_reset(&rx_thread->resume_event);
+			qdf_event_set(&rx_thread->suspend_event);
+			qdf_spin_unlock(&rx_thread->lock);
+			dp_debug("waiting for resume (%s) id %d pid %d",
+				 qdf_get_current_comm(), rx_thread->id,
+				 qdf_get_current_pid());
+			qdf_wait_single_event(&rx_thread->resume_event, 0);
+		}
+		break;
+	}
+	return 0;
+}
+
+/**
+ * dp_rx_thread_loop() - main dp rx thread loop
+ * @arg: pointer to dp_rx_thread structure for the rx thread
+ *
+ * Return: thread exit code
+ */
+static int dp_rx_thread_loop(void *arg)
+{
+	struct dp_rx_thread *rx_thread = arg;
+	bool shutdown = false;
+	int status;
+	struct dp_rx_tm_handle_cmn *tm_handle_cmn;
+
+	tm_handle_cmn = rx_thread->rtm_handle_cmn;
+
+	if (!arg) {
+		dp_err("bad Args passed");
+		return 0;
+	}
+
+	qdf_set_user_nice(qdf_get_current_task(), -1);
+	qdf_set_wake_up_idle(true);
+
+	qdf_event_set(&rx_thread->start_event);
+	dp_info("starting rx_thread (%s) id %d pid %d", qdf_get_current_comm(),
+		rx_thread->id, qdf_get_current_pid());
+	while (!shutdown) {
+		/* This implements the execution model algorithm */
+		dp_debug("sleeping");
+		status =
+		    qdf_wait_queue_interruptible
+				(DP_RX_THREAD_GET_WAIT_QUEUE_OBJ(tm_handle_cmn),
+				 qdf_atomic_test_bit(RX_POST_EVENT,
+						     &rx_thread->event_flag) ||
+				 qdf_atomic_test_bit(RX_SUSPEND_EVENT,
+						     &rx_thread->event_flag));
+		dp_debug("woken up");
+
+		if (status == -ERESTARTSYS) {
+			dp_err("wait_event_interruptible returned -ERESTARTSYS");
+			QDF_DEBUG_PANIC();
+			break;
+		}
+		qdf_atomic_clear_bit(RX_POST_EVENT, &rx_thread->event_flag);
+		dp_rx_thread_sub_loop(rx_thread, &shutdown);
+	}
+
+	/* If we get here the scheduler thread must exit */
+	dp_info("exiting (%s) id %d pid %d", qdf_get_current_comm(),
+		rx_thread->id, qdf_get_current_pid());
+	qdf_event_set(&rx_thread->shutdown_event);
+	qdf_exit_thread(QDF_STATUS_SUCCESS);
+
+	return 0;
+}
+
+/*
+ * dp_rx_tm_thread_init() - Initialize dp_rx_thread structure and thread
+ *
+ * @rx_thread: dp_rx_thread structure to be initialized
+ * @id: id of the thread to be initialized
+ *
+ * Return: QDF_STATUS on success, QDF error code on failure
+ */
+static QDF_STATUS dp_rx_tm_thread_init(struct dp_rx_thread *rx_thread,
+				       uint8_t id)
+{
+	char thread_name[15];
+	QDF_STATUS qdf_status;
+
+	qdf_mem_set(thread_name, 0, sizeof(thread_name));
+
+	if (!rx_thread) {
+		dp_err("rx_thread is null!");
+		return QDF_STATUS_E_FAULT;
+	}
+	rx_thread->id = id;
+	rx_thread->event_flag = 0;
+	qdf_nbuf_queue_head_init(&rx_thread->nbuf_queue);
+	qdf_event_create(&rx_thread->start_event);
+	qdf_event_create(&rx_thread->suspend_event);
+	qdf_event_create(&rx_thread->resume_event);
+	qdf_event_create(&rx_thread->shutdown_event);
+	qdf_scnprintf(thread_name, sizeof(thread_name), "dp_rx_thread_%u", id);
+	dp_info("%s %u", thread_name, id);
+	rx_thread->task = qdf_create_thread(dp_rx_thread_loop,
+					    rx_thread, thread_name);
+	if (!rx_thread->task) {
+		dp_err("could not create dp_rx_thread %d", id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_wake_up_process(rx_thread->task);
+	qdf_status = qdf_wait_single_event(&rx_thread->start_event, 0);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		dp_err("failed waiting for thread creation id %d", id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * dp_rx_tm_thread_deinit() - De-Initialize dp_rx_thread structure and thread
+ * @rx_thread: dp_rx_thread structure to be de-initialized
+ * @id: id of the thread to be initialized
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+static QDF_STATUS dp_rx_tm_thread_deinit(struct dp_rx_thread *rx_thread)
+{
+	qdf_event_destroy(&rx_thread->start_event);
+	qdf_event_destroy(&rx_thread->suspend_event);
+	qdf_event_destroy(&rx_thread->resume_event);
+	qdf_event_destroy(&rx_thread->shutdown_event);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS dp_rx_tm_init(struct dp_rx_tm_handle *rx_tm_hdl,
+			 uint8_t num_dp_rx_threads)
+{
+	int i;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	/* ignoring num_dp_rx_threads for now */
+	qdf_init_waitqueue_head(&rx_tm_hdl->wait_q);
+
+	for (i = 0; i < DP_MAX_RX_THREADS; i++) {
+		rx_tm_hdl->rx_thread[i] =
+			(struct dp_rx_thread *)
+			qdf_mem_malloc(sizeof(struct dp_rx_thread));
+		if (qdf_unlikely(!rx_tm_hdl->rx_thread[i])) {
+			QDF_ASSERT(0);
+			qdf_status = QDF_STATUS_E_NOMEM;
+			dp_err("failed to allocate memory for dp_rx_thread");
+			goto ret;
+		}
+		rx_tm_hdl->rx_thread[i]->rtm_handle_cmn =
+				(struct dp_rx_tm_handle_cmn *)rx_tm_hdl;
+		qdf_status =
+			dp_rx_tm_thread_init(rx_tm_hdl->rx_thread[i], i);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			break;
+	}
+ret:
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		dp_rx_tm_deinit(rx_tm_hdl);
+
+	return qdf_status;
+}
+
+/**
+ * dp_rx_tm_resume() - suspend DP RX threads
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread
+ *            infrastructure
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS dp_rx_tm_suspend(struct dp_rx_tm_handle *rx_tm_hdl)
+{
+	int i;
+	QDF_STATUS qdf_status;
+	struct dp_rx_thread *rx_thread;
+
+	for (i = 0; i < DP_MAX_RX_THREADS; i++) {
+		if (!rx_tm_hdl->rx_thread[i])
+			continue;
+		qdf_set_bit(RX_SUSPEND_EVENT,
+			    &rx_tm_hdl->rx_thread[i]->event_flag);
+	}
+
+	qdf_wake_up_interruptible(&rx_tm_hdl->wait_q);
+
+	for (i = 0; i < DP_MAX_RX_THREADS; i++) {
+		rx_thread = rx_tm_hdl->rx_thread[i];
+		if (!rx_thread)
+			continue;
+		dp_debug("thread %d", i);
+		qdf_status = qdf_wait_single_event(&rx_thread->suspend_event,
+						   DP_RX_THREAD_WAIT_TIMEOUT);
+		if (QDF_IS_STATUS_SUCCESS(qdf_status))
+			dp_debug("thread:%d suspended", rx_thread->id);
+		else if (qdf_status == QDF_STATUS_E_TIMEOUT)
+			dp_err("thread:%d timed out waiting for suspend",
+			       rx_thread->id);
+		else
+			dp_err("thread:%d failed while waiting for suspend",
+			       rx_thread->id);
+	}
+	rx_tm_hdl->state = DP_RX_THREAD_SUSPENDED;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * dp_rx_tm_resume() - resume DP RX threads
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread
+ *            infrastructure
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS dp_rx_tm_resume(struct dp_rx_tm_handle *rx_tm_hdl)
+{
+	int i;
+
+	if (rx_tm_hdl->state != DP_RX_THREAD_SUSPENDED) {
+		dp_err("resume callback received without suspend");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	for (i = 0; i < DP_MAX_RX_THREADS; i++) {
+		if (!rx_tm_hdl->rx_thread[i])
+			continue;
+		dp_debug("calling thread %d to resume", i);
+		qdf_event_set(&rx_tm_hdl->rx_thread[i]->resume_event);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * dp_rx_tm_shutdown() - shutdown all DP RX threads
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread infrastructure
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+static QDF_STATUS dp_rx_tm_shutdown(struct dp_rx_tm_handle *rx_tm_hdl)
+{
+	int i;
+
+	for (i = 0; i < DP_MAX_RX_THREADS; i++) {
+		if (!rx_tm_hdl->rx_thread[i])
+			continue;
+		qdf_set_bit(RX_SHUTDOWN_EVENT,
+			    &rx_tm_hdl->rx_thread[i]->event_flag);
+		qdf_set_bit(RX_POST_EVENT,
+			    &rx_tm_hdl->rx_thread[i]->event_flag);
+	}
+
+	qdf_wake_up_interruptible(&rx_tm_hdl->wait_q);
+
+	for (i = 0; i < DP_MAX_RX_THREADS; i++) {
+		if (!rx_tm_hdl->rx_thread[i])
+			continue;
+		dp_debug("waiting for shutdown of thread %d", i);
+		qdf_wait_single_event(&rx_tm_hdl->rx_thread[i]->shutdown_event,
+				      0);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * dp_rx_tm_deinit() - de-initialize RX thread infrastructure
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread
+ *            infrastructure
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS dp_rx_tm_deinit(struct dp_rx_tm_handle *rx_tm_hdl)
+{
+	int i = 0;
+
+	dp_rx_tm_shutdown(rx_tm_hdl);
+
+	for (i = 0; i < DP_MAX_RX_THREADS; i++) {
+		if (!rx_tm_hdl->rx_thread[i])
+			continue;
+		dp_rx_tm_thread_deinit(rx_tm_hdl->rx_thread[i]);
+		qdf_mem_free(rx_tm_hdl->rx_thread[i]);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * dp_rx_tm_select_thread() - select a DP RX thread for a nbuf
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread
+ *            infrastructure
+ * @nbuf_list: list of nbufs to be enqueued in to the thread
+ *
+ * The function relies on the presence of QDF_NBUF_CB_RX_CTX_ID
+ * in the nbuf list. Depending on the RX_CTX (copy engine or reo
+ * ring) on which the packet was received, the function selects
+ * a corresponding rx_thread.
+ * The function uses a simplistic mapping -
+ *
+ * RX_THREAD = RX_CTX % number of RX threads in the system.
+ *
+ * This also means that if RX_CTX < # rx threads, more than one
+ * interrupt source may end up on the same rx_thread.
+ *
+ * Return: rx thread ID selected for the nbuf
+ */
+static uint8_t dp_rx_tm_select_thread(struct dp_rx_tm_handle *rx_tm_hdl,
+				      qdf_nbuf_t nbuf_list)
+{
+	uint8_t selected_rx_thread;
+	uint8_t reo_ring_num = QDF_NBUF_CB_RX_CTX_ID(nbuf_list);
+
+	selected_rx_thread = reo_ring_num % DP_MAX_RX_THREADS;
+
+	return selected_rx_thread;
+}
+
+QDF_STATUS dp_rx_tm_enqueue_pkt(struct dp_rx_tm_handle *rx_tm_hdl,
+				qdf_nbuf_t nbuf_list)
+{
+	uint8_t selected_thread_id;
+
+	selected_thread_id = dp_rx_tm_select_thread(rx_tm_hdl, nbuf_list);
+
+	dp_rx_tm_thread_enqueue(rx_tm_hdl->rx_thread[selected_thread_id],
+				nbuf_list);
+	return QDF_STATUS_SUCCESS;
+}
+
diff --git a/core/dp/txrx3.0/dp_rx_thread.h b/core/dp/txrx3.0/dp_rx_thread.h
new file mode 100644
index 0000000..6b7d661
--- /dev/null
+++ b/core/dp/txrx3.0/dp_rx_thread.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#if !defined(__DP_RX_THREAD_H)
+#define __DP_RX_THREAD_H
+
+#include <qdf_lock.h>
+#include <qdf_event.h>
+#include <qdf_threads.h>
+#include <wlan_objmgr_vdev_obj.h>
+/* Maximum number of REO rings supported (for stats tracking) */
+#define DP_RX_TM_MAX_REO_RINGS 4
+
+/* Number of DP RX threads supported */
+#define DP_MAX_RX_THREADS 3
+
+/*
+ * Macro to get to wait_queue structure. Needed since wait_q is an object.
+ * API qdf_wait_queue_interruptible needs the object be passed to it and not a
+ * pointer
+ */
+#define DP_RX_THREAD_GET_WAIT_QUEUE_OBJ(rx_tm_handle_cmn) \
+		(((struct dp_rx_tm_handle *)rx_tm_handle_cmn)->wait_q)
+/*
+ * struct dp_rx_tm_handle_cmn - Opaque handle for rx_threads to store
+ * rx_tm_handle. This handle will be common for all the threads.
+ * Individual threads should not be accessing
+ * elements from dp_rx_tm_handle. It should be via an API.
+ */
+struct dp_rx_tm_handle_cmn;
+
+/**
+ * struct dp_rx_thread_stats - structure holding stats for DP RX thread
+ * @nbuf_queued: packets queued into the thread per reo ring
+ * @nbuf_dequeued: packets de-queued from the thread
+ * @nbuf_sent_to_stack: packets sent to the stack. some dequeued packets may be
+ *			dropped due to no peer or vdev, hence this stat.
+ * @nbufq_max_len: maximum number of nbuf_lists queued for the thread
+ * @dropped_invalid_vdev: packets(nbuf_list) dropped due to no vdev
+ * @dropped_invalid_peer: packets(nbuf_list) dropped due to no peer
+ * @dropped_others: packets dropped due to other reasons
+
+ */
+struct dp_rx_thread_stats {
+	unsigned int nbuf_queued[DP_RX_TM_MAX_REO_RINGS];
+	unsigned int nbuf_dequeued;
+	unsigned int nbuf_sent_to_stack;
+	unsigned int nbufq_max_len;
+	unsigned int dropped_invalid_vdev;
+	unsigned int dropped_invalid_peer;
+	unsigned int dropped_others;
+};
+
+/**
+ * struct dp_rx_thread - structure holding variables for a single DP RX thread
+ * @task: task structure corresponding to the thread
+ * @start_event: handle of Event for DP Rx thread to signal startup
+ * @suspend_event: handle of Event for DP Rx thread to signal suspend
+ * @resume_event: handle of Event for DP Rx thread to signal resume
+ * @shutdown_event: handle of Event for DP Rx thread to signal shutdown
+ * @event_flag: event flag to post events to DP Rx thread
+ * @nbuf_queue:nbuf queue used to store RX packets
+ * @nbufq_len: length of the nbuf queue
+ * @aff_mask: cuurent affinity mask of the DP Rx thread
+ * @stats: per thread stats
+ * @id: id of the dp_rx_thread (0 or 1 or 2..DP_MAX_RX_THREADS - 1)
+ * @rtm_handle_cmn: abstract RX TM handle. This allows access to the dp_rx_tm
+ *		    structures via APIs.
+ */
+struct dp_rx_thread {
+	qdf_thread_t *task;
+	qdf_spinlock_t lock;
+	qdf_event_t start_event;
+	qdf_event_t suspend_event;
+	qdf_event_t resume_event;
+	qdf_event_t shutdown_event;
+	unsigned long event_flag;
+	qdf_nbuf_queue_head_t nbuf_queue;
+	unsigned long aff_mask;
+	struct dp_rx_thread_stats stats;
+	uint8_t id;
+	struct dp_rx_tm_handle_cmn *rtm_handle_cmn;
+};
+
+/**
+ * enum dp_rx_thread_state - enum to keep track of the state of the rx thread
+ * @DP_RX_THREAD_INVALID: initial invalid state
+ * @DP_RX_THREAD_INIT: state after being initialized
+ * @DP_RX_THREAD_RUNNING: rx thread is functional(NOT suspended, processing
+ *			  packets or waiting on a wait_queue)
+ * @DP_RX_THREAD_SUSPENDED: rx_thread operation is suspeded from cfg8011 suspend
+ */
+enum dp_rx_thread_state {
+	DP_RX_THREAD_INVALID,
+	DP_RX_THREAD_INIT,
+	DP_RX_THREAD_RUNNING,
+	DP_RX_THREAD_SUSPENDED
+};
+
+/**
+ * struct dp_rx_tm_handle - DP RX thread infrastructure handle
+ * @txrx_handle_cmn: opaque txrx handle to get to pdev and soc
+ * wait_q: wait_queue for the rx_threads to wait on and expect an event
+ * @state: state of the rx_threads. All of them should be in the same state.
+ * @rx_thread: array of pointers of type struct dp_rx_thread
+ */
+struct dp_rx_tm_handle {
+	struct dp_txrx_handle_cmn *txrx_handle_cmn;
+	qdf_wait_queue_head_t wait_q;
+	enum dp_rx_thread_state state;
+	struct dp_rx_thread *rx_thread[DP_MAX_RX_THREADS];
+};
+
+/**
+ * dp_rx_tm_init() - initialize DP Rx thread infrastructure
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread infrastructure
+ * @num_dp_rx_threads: number of DP Rx threads to be initialized
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS dp_rx_tm_init(struct dp_rx_tm_handle *rx_tm_hdl,
+			 uint8_t num_dp_rx_threads);
+
+/**
+ * dp_rx_tm_deinit() - de-initialize DP Rx thread infrastructure
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread infrastructure
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_rx_tm_deinit(struct dp_rx_tm_handle *rx_tm_hdl);
+
+/**
+ * dp_rx_tm_enqueue_pkt() - enqueue RX packet into RXTI
+ * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread infrastructure
+ * @nbuf_list: single or a list of nbufs to be enqueued into RXTI
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS dp_rx_tm_enqueue_pkt(struct dp_rx_tm_handle *rx_tm_hdl,
+				qdf_nbuf_t nbuf_list);
+
+/**
+ * dp_rx_tm_suspend() - suspend all threads in RXTI
+ * @rx_tm_handle: pointer to dp_rx_tm_handle object
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_rx_tm_suspend(struct dp_rx_tm_handle *rx_tm_handle);
+
+/**
+ * dp_rx_tm_resume() - resume all threads in RXTI
+ * @rx_tm_handle: pointer to dp_rx_tm_handle object
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_rx_tm_resume(struct dp_rx_tm_handle *rx_tm_handle);
+
+/**
+ * dp_rx_tm_dump_stats() - dump stats for all threads in RXTI
+ * @rx_tm_handle: pointer to dp_rx_tm_handle object
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_rx_tm_dump_stats(struct dp_rx_tm_handle *rx_tm_handle);
+
+/**
+ * dp_rx_thread_get_txrx_handle() - get txrx handle from rx_tm_handle_cmn
+ * @rx_tm_handle_cmn: opaque pointer to dp_rx_tm_handle_cmn struct
+ *
+ * Return: pointer to dp_txrx_handle_cmn handle
+ */
+static inline struct dp_txrx_handle_cmn*
+dp_rx_thread_get_txrx_handle(struct dp_rx_tm_handle_cmn *rx_tm_handle_cmn)
+{
+	return (((struct dp_rx_tm_handle *)rx_tm_handle_cmn)->txrx_handle_cmn);
+}
+
+/**
+ * dp_rx_thread_get_wait_queue() - get wait_q from dp_rx_tm_handle
+ * @rx_tm_handle_cmn: opaque pointer to dp_rx_tm_handle_cmn struct
+ *
+ * The function is needed since dp_rx_thread does not have access to the real
+ * dp_rx_tm_handle structure, but only an opaque dp_rx_tm_handle_cmn handle
+ *
+ * Return: pointer to dp_txrx_handle_cmn handle
+ */
+static inline qdf_wait_queue_head_t*
+dp_rx_thread_get_wait_queue(struct dp_rx_tm_handle_cmn *rx_tm_handle_cmn)
+{
+	struct dp_rx_tm_handle *rx_tm_handle;
+
+	rx_tm_handle = (struct dp_rx_tm_handle *)rx_tm_handle_cmn;
+	return &rx_tm_handle->wait_q;
+}
+
+#endif /* __DP_RX_THREAD_H */
diff --git a/core/dp/txrx3.0/dp_txrx.c b/core/dp/txrx3.0/dp_txrx.c
new file mode 100644
index 0000000..cd89228
--- /dev/null
+++ b/core/dp/txrx3.0/dp_txrx.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include <wlan_objmgr_pdev_obj.h>
+#include <dp_txrx.h>
+#include <cdp_txrx_cmn.h>
+
+QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
+			struct dp_txrx_config *config)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	dp_ext_hdl = qdf_mem_malloc(sizeof(*dp_ext_hdl));
+	if (!dp_ext_hdl) {
+		dp_err("failed to alloc dp_txrx_handle");
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	dp_info("dp_txrx_handle allocated");
+	dp_ext_hdl->soc = soc;
+	dp_ext_hdl->pdev = pdev;
+	cdp_soc_set_dp_txrx_handle(soc, dp_ext_hdl);
+	qdf_mem_copy(&dp_ext_hdl->config, config, sizeof(*config));
+	dp_ext_hdl->rx_tm_hdl.txrx_handle_cmn =
+				dp_txrx_get_cmn_hdl_frm_ext_hdl(dp_ext_hdl);
+
+	if (dp_ext_hdl->config.enable_rx_threads) {
+		qdf_status = dp_rx_tm_init(&dp_ext_hdl->rx_tm_hdl,
+					   dp_ext_hdl->config.num_rx_threads);
+	}
+
+	return qdf_status;
+}
+
+QDF_STATUS dp_txrx_deinit(ol_txrx_soc_handle soc)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+
+	if (!soc)
+		return QDF_STATUS_E_INVAL;
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl)
+		return QDF_STATUS_E_FAULT;
+
+	if (dp_ext_hdl->config.enable_rx_threads)
+		dp_rx_tm_deinit(&dp_ext_hdl->rx_tm_hdl);
+
+	qdf_mem_free(dp_ext_hdl);
+	dp_info("dp_txrx_handle_t de-allocated");
+
+	cdp_soc_set_dp_txrx_handle(soc, NULL);
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/core/dp/txrx3.0/dp_txrx.h b/core/dp/txrx3.0/dp_txrx.h
new file mode 100644
index 0000000..da46293
--- /dev/null
+++ b/core/dp/txrx3.0/dp_txrx.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#ifndef _DP_TXRX_H
+#define _DP_TXRX_H
+
+#include <wlan_objmgr_psoc_obj.h>
+#include <dp_rx_thread.h>
+#include <qdf_trace.h>
+#include <cdp_txrx_cmn_struct.h>
+#include <cdp_txrx_cmn.h>
+
+/**
+ * struct dp_txrx_config - dp txrx configuration passed to dp txrx modules
+ * @enable_dp_rx_threads: enable DP rx threads or not
+ * @num_rx_threads: number of DP RX threads
+ */
+struct dp_txrx_config {
+	bool enable_rx_threads;
+	uint8_t num_rx_threads;
+};
+
+struct dp_txrx_handle_cmn;
+/**
+ * struct dp_txrx_handle - main dp txrx container handle
+ * @soc: ol_txrx_soc_handle soc handle
+ * @rx_tm_hdl: rx thread infrastructure handle
+ */
+struct dp_txrx_handle {
+	ol_txrx_soc_handle soc;
+	struct cdp_pdev *pdev;
+	struct dp_rx_tm_handle rx_tm_hdl;
+	struct dp_txrx_config config;
+};
+
+#ifdef FEATURE_WLAN_DP_RX_THREADS
+/**
+ * dp_txrx_get_cmn_hdl_frm_ext_hdl() - conversion func ext_hdl->txrx_handle_cmn
+ * @dp_ext_hdl: pointer to dp_txrx_handle structure
+ *
+ * Return: typecasted pointer of type - struct dp_txrx_handle_cmn
+ */
+static inline struct dp_txrx_handle_cmn *
+dp_txrx_get_cmn_hdl_frm_ext_hdl(struct dp_txrx_handle *dp_ext_hdl)
+{
+	return (struct dp_txrx_handle_cmn *)dp_ext_hdl;
+}
+
+/**
+ * dp_txrx_get_ext_hdl_frm_cmn_hdl() - conversion func txrx_handle_cmn->ext_hdl
+ * @txrx_cmn_hdl: pointer to dp_txrx_handle_cmn structure
+ *
+ * Return: typecasted pointer of type - struct dp_txrx_handle
+ */
+static inline struct dp_txrx_handle *
+dp_txrx_get_ext_hdl_frm_cmn_hdl(struct dp_txrx_handle_cmn *txrx_cmn_hdl)
+{
+	return (struct dp_txrx_handle *)txrx_cmn_hdl;
+}
+
+static inline ol_txrx_soc_handle
+dp_txrx_get_soc_from_ext_handle(struct dp_txrx_handle_cmn *txrx_cmn_hdl)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+
+	dp_ext_hdl = dp_txrx_get_ext_hdl_frm_cmn_hdl(txrx_cmn_hdl);
+
+	return dp_ext_hdl->soc;
+}
+
+static inline struct cdp_pdev*
+dp_txrx_get_pdev_from_ext_handle(struct dp_txrx_handle_cmn *txrx_cmn_hdl)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+
+	dp_ext_hdl = dp_txrx_get_ext_hdl_frm_cmn_hdl(txrx_cmn_hdl);
+
+	return dp_ext_hdl->pdev;
+}
+
+/**
+ * dp_txrx_init() - initialize DP TXRX module
+ * @soc: ol_txrx_soc_handle
+ * @config: configuration for DP TXRX modules
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
+			struct dp_txrx_config *config);
+
+/**
+ * dp_txrx_deinit() - de-initialize DP TXRX module
+ * @soc: ol_txrx_soc_handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+QDF_STATUS dp_txrx_deinit(ol_txrx_soc_handle soc);
+
+/**
+ * dp_txrx_resume() - resume all threads
+ * @soc: ol_txrx_soc_handle object
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+static inline QDF_STATUS dp_txrx_resume(ol_txrx_soc_handle soc)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	if (!soc) {
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto ret;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl) {
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto ret;
+	}
+
+	qdf_status = dp_rx_tm_resume(&dp_ext_hdl->rx_tm_hdl);
+ret:
+	return qdf_status;
+}
+
+/**
+ * dp_txrx_suspend() - suspend all threads
+ * @soc: ol_txrx_soc_handle object
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
+ */
+static inline QDF_STATUS dp_txrx_suspend(ol_txrx_soc_handle soc)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	if (!soc) {
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto ret;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl) {
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto ret;
+	}
+
+	qdf_status = dp_rx_tm_suspend(&dp_ext_hdl->rx_tm_hdl);
+
+ret:
+	return qdf_status;
+}
+
+static inline
+QDF_STATUS dp_rx_enqueue_pkt(ol_txrx_soc_handle soc, qdf_nbuf_t nbuf_list)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	if (!soc || !nbuf_list) {
+		qdf_status = QDF_STATUS_E_INVAL;
+		dp_err("invalid input params soc %pK nbuf %pK"
+		       , soc, nbuf_list);
+		goto ret;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl) {
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto ret;
+	}
+
+	qdf_status = dp_rx_tm_enqueue_pkt(&dp_ext_hdl->rx_tm_hdl, nbuf_list);
+ret:
+	return qdf_status;
+}
+
+static inline QDF_STATUS dp_txrx_dump_stats(ol_txrx_soc_handle soc)
+{
+	struct dp_txrx_handle *dp_ext_hdl;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	if (!soc) {
+		qdf_status = QDF_STATUS_E_INVAL;
+		dp_err("invalid input params soc %pK", soc);
+		goto ret;
+	}
+
+	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
+	if (!dp_ext_hdl) {
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto ret;
+	}
+
+	qdf_status = dp_rx_tm_dump_stats(&dp_ext_hdl->rx_tm_hdl);
+ret:
+	return qdf_status;
+}
+#else
+static inline
+QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
+			    struct dp_txrx_config *config)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS dp_txrx_deinit(ol_txrx_soc_handle soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS dp_txrx_resume(ol_txrx_soc_handle soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS dp_txrx_suspend(ol_txrx_soc_handle soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS dp_rx_enqueue_pkt(ol_txrx_soc_handle soc, qdf_nbuf_t nbuf_list)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS dp_txrx_dump_stats(ol_txrx_soc_handle soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_DP_RX_THREADS */
+#endif /* _DP_TXRX_H */
diff --git a/core/hdd/inc/hdd_config.h b/core/hdd/inc/hdd_config.h
new file mode 100644
index 0000000..f46672d
--- /dev/null
+++ b/core/hdd/inc/hdd_config.h
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __HDD_CONFIG_H
+#define __HDD_CONFIG_H
+
+/**
+ * enum hdd_wext_control - knob for wireless extensions
+ * @hdd_wext_disabled - interface is completely disabled. An access
+ *      control error log will be generated for each attempted use.
+ * @hdd_wext_deprecated - interface is available but should not be
+ *      used. An access control warning log will be generated for each
+ *      use.
+ * @hdd_wext_enabled - interface is available without restriction. No
+ *      access control logs will be generated.
+ *
+ * enum hdd_wext_control is used to enable coarse grained control on
+ * wireless extensions ioctls. This control is used by configuration
+ * item private_wext_control.
+ *
+ */
+enum hdd_wext_control {
+	hdd_wext_disabled = 0,
+	hdd_wext_deprecated = 1,
+	hdd_wext_enabled = 2,
+};
+
+/*
+ * <ini>
+ * private_wext_control - Private wireless extensions control
+ * @Min: 0
+ * @Max: 2
+ * @Default: 1
+ *
+ * Values are per enum hdd_wext_control.
+ * This ini is used to control access to private wireless extensions
+ * ioctls SIOCIWFIRSTPRIV (0x8BE0) thru SIOCIWLASTPRIV (0x8BFF). The
+ * functionality provided by some of these ioctls has been superceeded
+ * by cfg80211 (either standard commands or vendor commands), but many
+ * of the private ioctls do not have a cfg80211-based equivalent, so
+ * by default support for these ioctls is deprecated.
+ *
+ * Related: None
+ *
+ * Supported Feature: All
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PRIVATE_WEXT_CONTROL CFG_INI_UINT( \
+			"private_wext_control", \
+			hdd_wext_disabled, \
+			hdd_wext_enabled, \
+			hdd_wext_deprecated, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Private WEXT Control")
+
+/*
+ * <ini>
+ * gInterfaceChangeWait - Interface change wait
+ * @Min: 10,
+ * @Max: 500000
+ * @Default: 10000
+ *
+ * Timer waiting for interface up from the upper layer. If
+ * this timer expires all the cds modules shall be closed.
+ * Time Units: ms
+ *
+ * Related: None
+ *
+ * Supported Feature: All
+ *
+ * </ini>
+ */
+#define CFG_INTERFACE_CHANGE_WAIT CFG_INI_UINT( \
+			"gInterfaceChangeWait", \
+			10, \
+			500000, \
+			10000, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Interface change wait")
+
+#ifdef QCA_WIFI_NAPIER_EMULATION
+#define CFG_TIMER_MULTIPLIER_DEFAULT	100
+#else
+#define CFG_TIMER_MULTIPLIER_DEFAULT	1
+#endif
+
+/*
+ * <ini>
+ * gTimerMultiplier - Scale QDF timers by this value
+ * @Min: 1
+ * @Max: 0xFFFFFFFF
+ * @Default: 1 (100 for emulation)
+ *
+ * To assist in debugging emulation setups, scale QDF timers by this factor.
+ *
+ * @E.g.
+ *	# QDF timers expire in real time
+ *	gTimerMultiplier=1
+ *	# QDF timers expire after 100 times real time
+ *	gTimerMultiplier=100
+ *
+ * Related: None
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_TIMER_MULTIPLIER CFG_INI_UINT( \
+			"gTimerMultiplier", \
+			1, \
+			0xFFFFFFFF, \
+			CFG_TIMER_MULTIPLIER_DEFAULT, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Timer Multiplier")
+
+#define CFG_BUG_ON_REINIT_FAILURE_DEFAULT 1
+/*
+ * <ini>
+ * g_bug_on_reinit_failure  - Enable/Disable bug on reinit
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to debug ssr reinit failure issues by raising vos bug so
+ * dumps can be collected.
+ * g_bug_on_reinit_failure = 0 wlan driver will only recover after driver
+ * unload and load
+ * g_bug_on_reinit_failure = 1 raise vos bug to collect dumps
+ *
+ * Related: gEnableSSR
+ *
+ * Supported Feature: SSR
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BUG_ON_REINIT_FAILURE CFG_INI_BOOL( \
+		"g_bug_on_reinit_failure", \
+		CFG_BUG_ON_REINIT_FAILURE_DEFAULT, \
+		"BUG on reinit failure")
+
+/*
+ * <ini>
+ * gEnableDumpCollect - It will use for collect the dumps
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set collect default dump
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_RAMDUMP_COLLECTION CFG_INI_BOOL( \
+			"gEnableDumpCollect", \
+			1, \
+			"Enable dump collect")
+
+#if defined(MDM_PLATFORM) && !defined(FEATURE_MULTICAST_HOST_FW_MSGS)
+#define CFG_MULTICAST_HOST_FW_MSGS_DEFAULT	0
+#else
+#define CFG_MULTICAST_HOST_FW_MSGS_DEFAULT	1
+#endif
+
+/*
+ * <ini>
+ * gMulticastHostFwMsgs - Multicast host FW messages
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0 for MDM platform and 1 for other
+ *
+ * </ini>
+ */
+#define CFG_MULTICAST_HOST_FW_MSGS CFG_INI_UINT( \
+			"gMulticastHostFwMsgs", \
+			0, \
+			1, \
+			CFG_MULTICAST_HOST_FW_MSGS_DEFAULT, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Multicast host FW msgs")
+
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+/*
+ * <ini>
+ * wlanLoggingEnable - Wlan logging enable
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * </ini>
+ */
+#define CFG_WLAN_LOGGING_SUPPORT CFG_INI_BOOL( \
+				"wlanLoggingEnable", \
+				1, \
+				"Wlan logging enable")
+
+/*
+ * <ini>
+ * wlanLoggingToConsole - Wlan logging to console
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * </ini>
+ */
+#define CFG_WLAN_LOGGING_CONSOLE_SUPPORT CFG_INI_BOOL( \
+				"wlanLoggingToConsole", \
+				1, \
+				"Wlan logging to console")
+
+#define CFG_WLAN_LOGGING_SUPPORT_ALL \
+	CFG(CFG_WLAN_LOGGING_SUPPORT) \
+	CFG(CFG_WLAN_LOGGING_CONSOLE_SUPPORT)
+#else
+#define CFG_WLAN_LOGGING_SUPPORT_ALL
+#endif
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+/*
+ * <ini>
+ * gWlanAutoShutdown - Wlan auto shutdown
+ * @Min: 0
+ * @Max: 86400
+ * @Default: 0
+ *
+ * </ini>
+ */
+#define CFG_WLAN_AUTO_SHUTDOWN CFG_INI_UINT( \
+			"gWlanAutoShutdown", \
+			0, \
+			86400, \
+			0, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Wlan auto shutdown")
+#define CFG_WLAN_AUTO_SHUTDOWN_ALL \
+	CFG(CFG_WLAN_AUTO_SHUTDOWN)
+#else
+#define CFG_WLAN_AUTO_SHUTDOWN_ALL
+#endif
+
+/*
+ * <ini>
+ * gEnablefwprint - Enable FW uart print
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_FW_UART_PRINT CFG_INI_BOOL( \
+			"gEnablefwprint", \
+			0, \
+			"Enable FW uart print")
+
+/*
+ * <ini>
+ * gEnablefwlog - Enable FW log
+ * @Min: 0
+ * @Max: 2
+ * @Default: 1
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_FW_LOG CFG_INI_UINT( \
+			"gEnablefwlog", \
+			0, \
+			2, \
+			1, \
+			CFG_VALUE_OR_DEFAULT, \
+			"Enable FW log")
+
+#ifndef REMOVE_PKT_LOG
+
+#ifdef FEATURE_PKTLOG
+#define CFG_ENABLE_PACKET_LOG_DEFAULT	1
+#else
+#define CFG_ENABLE_PACKET_LOG_DEFAULT	0
+#endif
+
+/*
+ * <ini>
+ * gEnablePacketLog - Enale packet log
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1 if feature packet log define, 0 elsewhere
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_PACKET_LOG CFG_INI_BOOL( \
+			"gEnablePacketLog", \
+			CFG_ENABLE_PACKET_LOG_DEFAULT, \
+			"Enable packet log")
+
+#define CFG_ENABLE_PACKET_LOG_ALL \
+	CFG(CFG_ENABLE_PACKET_LOG)
+#else
+#define CFG_ENABLE_PACKET_LOG_ALL
+#endif
+
+#define CFG_HDD_ALL \
+	CFG_ENABLE_PACKET_LOG_ALL \
+	CFG_WLAN_AUTO_SHUTDOWN_ALL \
+	CFG_WLAN_LOGGING_SUPPORT_ALL \
+	CFG(CFG_BUG_ON_REINIT_FAILURE) \
+	CFG(CFG_ENABLE_FW_LOG) \
+	CFG(CFG_ENABLE_FW_UART_PRINT) \
+	CFG(CFG_ENABLE_RAMDUMP_COLLECTION) \
+	CFG(CFG_INTERFACE_CHANGE_WAIT) \
+	CFG(CFG_MULTICAST_HOST_FW_MSGS) \
+	CFG(CFG_PRIVATE_WEXT_CONTROL) \
+	CFG(CFG_TIMER_MULTIPLIER)
+#endif
diff --git a/core/hdd/inc/hdd_dp_cfg.h b/core/hdd/inc/hdd_dp_cfg.h
new file mode 100644
index 0000000..f8adede
--- /dev/null
+++ b/core/hdd/inc/hdd_dp_cfg.h
@@ -0,0 +1,821 @@
+/*
+ * Copyright (c) 2012-2018 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 centralized definitions of converged configuration.
+ */
+
+#ifndef __HDD_DP_CONFIG_H
+#define __HDD_DP_CONFIG_H
+
+#define CFG_ENABLE_RX_THREAD		BIT(0)
+#define CFG_ENABLE_RPS			BIT(1)
+#define CFG_ENABLE_NAPI			BIT(2)
+#define CFG_ENABLE_DYNAMIC_RPS		BIT(3)
+#define CFG_ENABLE_DP_RX_THREADS	BIT(4)
+#define CFG_RX_MODE_MAX (CFG_ENABLE_RX_THREAD | \
+					  CFG_ENABLE_RPS | \
+					  CFG_ENABLE_NAPI | \
+					  CFG_ENABLE_DYNAMIC_RPS | \
+					  CFG_ENABLE_DP_RX_THREADS)
+#ifdef MDM_PLATFORM
+#define CFG_RX_MODE_DEFAULT 0
+#elif defined(HELIUMPLUS)
+#define CFG_RX_MODE_DEFAULT CFG_ENABLE_NAPI
+#elif defined(QCA_WIFI_QCA6290_11AX)
+#define CFG_RX_MODE_DEFAULT (CFG_ENABLE_DP_RX_THREADS | CFG_ENABLE_NAPI)
+#else
+#define CFG_RX_MODE_DEFAULT (CFG_ENABLE_RX_THREAD | CFG_ENABLE_NAPI)
+#endif
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+
+/*
+ * <ini>
+ * TxFlowLowWaterMark - Low watermark for pausing network queues
+ *
+ * @Min: 0
+ * @Max: 1000
+ * @Default: 300
+ *
+ * This ini specifies the low watermark of data packets transmitted
+ * before pausing netif queues in tx flow path. It is only applicable
+ * where legacy flow control is used i.e.for Rome.
+ *
+ * Related: TxFlowHighWaterMarkOffset, TxFlowMaxQueueDepth,
+ *          TxLbwFlowLowWaterMark, TxLbwFlowHighWaterMarkOffset,
+ *          TxLbwFlowMaxQueueDepth, TxHbwFlowLowWaterMark,
+ *          TxHbwFlowHighWaterMarkOffset, TxHbwFlowMaxQueueDepth
+ *
+ * Supported Feature: Dynamic Flow Control
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_LL_TX_FLOW_LWM \
+		CFG_INI_UINT( \
+		"TxFlowLowWaterMark", \
+		0, \
+		1000, \
+		300, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Low watermark for pausing network queues")
+
+/*
+ * <ini>
+ * TxFlowHighWaterMarkOffset - High Watermark offset to unpause Netif queues
+ * @Min: 0
+ * @Max: 300
+ * @Default: 94
+ *
+ * This ini specifies the offset to upause the netif queues
+ * when they are paused due to insufficient descriptors as guided by
+ * ini TxFlowLowWaterMark. It is only applicable where legacy flow control
+ * is used i.e.for Rome.
+ *
+ * Related: TxFlowLowWaterMark, TxFlowMaxQueueDepth,
+ *          TxLbwFlowLowWaterMark, TxLbwFlowHighWaterMarkOffset,
+ *          TxLbwFlowMaxQueueDepth, TxHbwFlowLowWaterMark,
+ *          TxHbwFlowHighWaterMarkOffset, TxHbwFlowMaxQueueDepth
+ *
+ * Supported Feature: Dynamic Flow Control
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_LL_TX_FLOW_HWM_OFFSET \
+		CFG_INI_UINT( \
+		"TxFlowHighWaterMarkOffset", \
+		0, \
+		300, \
+		94, \
+		CFG_VALUE_OR_DEFAULT, \
+		"High Watermark offset to unpause Netif queues")
+
+/*
+ * <ini>
+ * TxFlowMaxQueueDepth - Max pause queue depth.
+ *
+ * @Min: 400
+ * @Max: 3500
+ * @Default: 1500
+ *
+ * This ini specifies the max queue pause depth.It is only applicable
+ * where legacy flow control is used i.e.for Rome.
+ *
+ * Related: TxFlowLowWaterMark, TxFlowHighWaterMarkOffset,
+ *          TxLbwFlowLowWaterMark, TxLbwFlowHighWaterMarkOffset,
+ *          TxLbwFlowMaxQueueDepth, TxHbwFlowLowWaterMark,
+ *          TxHbwFlowHighWaterMarkOffset, TxHbwFlowMaxQueueDepth
+ *
+ * Supported Feature: Dynamic Flow Control
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_LL_TX_FLOW_MAX_Q_DEPTH \
+		CFG_INI_UINT( \
+		"TxFlowMaxQueueDepth", \
+		400, \
+		3500, \
+		1500, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Max pause queue depth")
+
+/*
+ * <ini>
+ * TxLbwFlowLowWaterMark - Low watermark for pausing network queues
+ *                         in low bandwidth band
+ * @Min: 0
+ * @Max: 1000
+ * @Default: 450
+ *
+ * This ini specifies the low watermark of data packets transmitted
+ * before pausing netif queues in tx flow path in low bandwidth band.
+ * It is only applicable where legacy flow control is used i.e.for Rome.
+ *
+ * Related: TxFlowLowWaterMark, TxFlowHighWaterMarkOffset,
+ *          TxFlowMaxQueueDepth, TxLbwFlowHighWaterMarkOffset,
+ *          TxLbwFlowMaxQueueDepth, TxHbwFlowLowWaterMark,
+ *          TxHbwFlowHighWaterMarkOffset, TxHbwFlowMaxQueueDepth
+ *
+ * Supported Feature: Dynamic Flow Control
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_LL_TX_LBW_FLOW_LWM \
+		CFG_INI_UINT( \
+		"TxLbwFlowLowWaterMark", \
+		0, \
+		1000, \
+		450, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Low watermark for pausing network queues")
+
+/*
+ * <ini>
+ * TxLbwFlowHighWaterMarkOffset - High Watermark offset to unpause Netif queues
+ *                                in low bandwidth band.
+ * @Min: 0
+ * @Max: 300
+ * @Default: 50
+ *
+ * This ini specifies the offset to upause the netif queues
+ * when they are paused due to insufficient descriptors as guided by
+ * ini TxLbwFlowLowWaterMark in low bandwidth band. It is only applicable
+ * where legacy flow control is used i.e.for Rome.
+ *
+ * Related: TxFlowLowWaterMark, TxFlowHighWaterMarkOffset,
+ *          TxFlowMaxQueueDepth, TxLbwFlowLowWaterMark,
+ *          TxLbwFlowMaxQueueDepth, TxHbwFlowLowWaterMark,
+ *          TxHbwFlowHighWaterMarkOffset, TxHbwFlowMaxQueueDepth
+ *
+ * Supported Feature: Dynamic Flow Control
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_LL_TX_LBW_FLOW_HWM_OFFSET \
+		CFG_INI_UINT( \
+		"TxLbwFlowHighWaterMarkOffset", \
+		0, \
+		300, \
+		50, \
+		CFG_VALUE_OR_DEFAULT, \
+		"High Watermark offset to unpause Netif queues")
+
+/*
+ * <ini>
+ * TxLbwFlowMaxQueueDepth - Max pause queue depth in low bandwidth band
+ *
+ * @Min: 400
+ * @Max: 3500
+ * @Default: 750
+ *
+ * This ini specifies the max queue pause depth in low bandwidth band.
+ * It is only applicable where legacy flow control is used i.e.for Rome.
+ *
+ * Related: TxFlowLowWaterMark, TxFlowHighWaterMarkOffset,
+ *          TxFlowMaxQueueDepth, TxLbwFlowLowWaterMark,
+ *          TxLbwFlowHighWaterMarkOffset, TxHbwFlowLowWaterMark,
+ *          TxHbwFlowHighWaterMarkOffset, TxHbwFlowMaxQueueDepth
+ *
+ * Supported Feature: Dynamic Flow Control
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_LL_TX_LBW_FLOW_MAX_Q_DEPTH \
+		CFG_INI_UINT( \
+		"TxLbwFlowMaxQueueDepth", \
+		400, \
+		3500, \
+		750, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Max pause queue depth in low bandwidth band")
+
+/*
+ * <ini>
+ * TxHbwFlowLowWaterMark - Low watermark for pausing network queues
+ *                         in high bandwidth band
+ * @Min: 0
+ * @Max: 1000
+ * @Default: 406
+ *
+ * This ini specifies the threshold of data packets transmitted
+ * before pausing netif queues.It is only applicable where
+ * legacy flow control is used i.e.for Rome.
+ *
+ * Related: TxFlowLowWaterMark, TxFlowHighWaterMarkOffset,
+ *          TxFlowMaxQueueDepth, TxLbwFlowLowWaterMark,
+ *          TxLbwFlowHighWaterMarkOffset, TxLbwFlowMaxQueueDepth,
+ *          TxHbwFlowHighWaterMarkOffset, TxHbwFlowMaxQueueDepth
+ *
+ * Supported Feature: Dynamic Flow Control
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_LL_TX_HBW_FLOW_LWM \
+		CFG_INI_UINT( \
+		"TxHbwFlowLowWaterMark", \
+		0, \
+		1000, \
+		406, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Low watermark for pausing network queues")
+
+/*
+ * <ini>
+ * TxHbwFlowHighWaterMarkOffset - High Watermark offset to unpause Netif queues
+ *                                in high bandwidth band.
+ * @Min: 0
+ * @Max: 300
+ * @Default: 94
+ *
+ * This ini specifies the offset to upause the netif queues
+ * when they are paused due to insufficient descriptors as guided by
+ * ini TxHbwFlowLowWaterMark in high bandwidth band. It is only applicable
+ * where legacy flow control is used i.e.for Rome.
+ *
+ * Related: TxFlowLowWaterMark, TxFlowHighWaterMarkOffset,
+ *          TxFlowMaxQueueDepth, TxLbwFlowLowWaterMark,
+ *          TxLbwFlowHighWaterMarkOffset, TxLbwFlowMaxQueueDepth,
+ *          TxHbwFlowLowWaterMark, TxHbwFlowMaxQueueDepth
+ *
+ * Supported Feature: Dynamic Flow Control
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_LL_TX_HBW_FLOW_HWM_OFFSET \
+		CFG_INI_UINT( \
+		"TxHbwFlowHighWaterMarkOffset", \
+		0, \
+		300, \
+		94, \
+		CFG_VALUE_OR_DEFAULT, \
+		"High Watermark offset to unpause Netif queues")
+
+/*
+ * <ini>
+ * TxHbwFlowMaxQueueDepth - Max pause queue depth in high bandwidth band
+ * @Min: 4000
+ * @Max: 3500
+ * @Default: 1500
+ *
+ * This ini specifies the max queue pause depth in high bandwidth band.
+ * It is only applicable where legacy flow control is used i.e.for Rome.
+ *
+ * Related: TxFlowLowWaterMark, TxFlowHighWaterMarkOffset,
+ *          TxFlowMaxQueueDepth, TxLbwFlowLowWaterMark,
+ *          TxLbwFlowHighWaterMarkOffset, TxLbwFlowMaxQueueDepth,
+ *          TxHbwFlowLowWaterMark, TxHbwFlowHighWaterMarkOffset
+ *
+ * Supported Feature: Dynamic Flow Control
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_LL_TX_HBW_FLOW_MAX_Q_DEPTH \
+		CFG_INI_UINT( \
+		"TxHbwFlowMaxQueueDepth", \
+		400, \
+		3500, \
+		1500, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Max pause queue depth in high bandwidth band")
+
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+#ifdef MSM_PLATFORM
+/*
+ * <ini>
+ * gBusBandwidthHighThreshold - bus bandwidth high threshold
+ *
+ * @Min: 0
+ * @Max: 4294967295UL
+ * @Default: 2000
+ *
+ * This ini specifies thebus bandwidth high threshold
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_BUS_BANDWIDTH_HIGH_THRESHOLD \
+		CFG_INI_UINT( \
+		"gBusBandwidthHighThreshold", \
+		0, \
+		4294967295UL, \
+		2000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Bus bandwidth high threshold")
+
+/*
+ * <ini>
+ * gBusBandwidthMediumThreshold - bus bandwidth medium threshold
+ *
+ * @Min: 0
+ * @Max: 4294967295UL
+ * @Default: 500
+ *
+ * This ini specifies thebus bandwidth medium threshold
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_BUS_BANDWIDTH_MEDIUM_THRESHOLD \
+		CFG_INI_UINT( \
+		"gBusBandwidthMediumThreshold", \
+		0, \
+		4294967295UL, \
+		500, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Bus bandwidth medium threshold")
+
+/*
+ * <ini>
+ * gBusBandwidthLowThreshold - bus bandwidth low threshold
+ *
+ * @Min: 0
+ * @Max: 4294967295UL
+ * @Default: 150
+ *
+ * This ini specifies thebus bandwidth low threshold
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_BUS_BANDWIDTH_LOW_THRESHOLD \
+		CFG_INI_UINT( \
+		"gBusBandwidthLowThreshold", \
+		0, \
+		4294967295UL, \
+		150, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Bus bandwidth low threshold")
+
+/*
+ * <ini>
+ * gBusBandwidthComputeInterval - bus bandwidth compute interval
+ *
+ * @Min: 0
+ * @Max: 10000
+ * @Default: 100
+ *
+ * This ini specifies thebus bandwidth compute interval
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_BUS_BANDWIDTH_COMPUTE_INTERVAL \
+		CFG_INI_UINT( \
+		"gBusBandwidthComputeInterval", \
+		0, \
+		10000, \
+		100, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Bus bandwidth compute interval")
+
+/*
+ * <ini>
+ * gEnableTcpLimitOutput - Control to enable TCP limit output byte
+ * @Default: true
+ *
+ * This ini is used to enable dynamic configuration of TCP limit output bytes
+ * tcp_limit_output_bytes param. Enabling this will let driver post message to
+ * cnss-daemon, accordingly cnss-daemon will modify the tcp_limit_output_bytes.
+ *
+ * Supported Feature: Tcp limit output bytes
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_ENABLE_TCP_LIMIT_OUTPUT \
+		CFG_INI_BOOL( \
+		"gTcpLimitOutputEnable", \
+		true, \
+		"Control to enable TCP limit output byte")
+
+/*
+ * <ini>
+ * gTcpAdvWinScaleEnable - Control to enable  TCP adv window scaling
+ * @Default: true
+ *
+ * This ini is used to enable dynamic configuration of TCP adv window scaling
+ * system parameter.
+ *
+ * Supported Feature: Tcp Advance Window Scaling
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_ENABLE_TCP_ADV_WIN_SCALE \
+		CFG_INI_BOOL( \
+		"gTcpAdvWinScaleEnable", \
+		true, \
+		"Control to enable  TCP adv window scaling")
+
+/*
+ * <ini>
+ * gTcpDelAckEnable - Control to enable Dynamic Configuration of Tcp Delayed Ack
+ * @Default: true
+ *
+ * This ini is used to enable Dynamic Configuration of Tcp Delayed Ack
+ *
+ * Related: gTcpDelAckThresholdHigh, gTcpDelAckThresholdLow,
+ *          gTcpDelAckTimerCount
+ *
+ * Supported Feature: Tcp Delayed Ack
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_ENABLE_TCP_DELACK \
+		CFG_INI_BOOL( \
+		"gTcpDelAckEnable", \
+		true, \
+		"Control to enable Dynamic Config of Tcp Delayed Ack")
+
+/*
+ * <ini>
+ * gTcpDelAckThresholdHigh - High Threshold inorder to trigger TCP Del Ack
+ *                                          indication
+ * @Min: 0
+ * @Max: 16000
+ * @Default: 500
+ *
+ * This ini is used to mention the High Threshold inorder to trigger TCP Del Ack
+ * indication i.e the threshold of packets received over a period of 100 ms.
+ * i.e to have a low RX throughput requirement
+ * Related: gTcpDelAckEnable, gTcpDelAckThresholdLow, gTcpDelAckTimerCount
+ *
+ * Supported Feature: Tcp Delayed Ack
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_TCP_DELACK_THRESHOLD_HIGH \
+		CFG_INI_UINT( \
+		"gTcpDelAckThresholdHigh", \
+		0, \
+		16000, \
+		500, \
+		CFG_VALUE_OR_DEFAULT, \
+		"High Threshold inorder to trigger TCP Del Ack")
+
+/*
+ * <ini>
+ * gTcpDelAckThresholdLow - Low Threshold inorder to trigger TCP Del Ack
+ *                                          indication
+ * @Min: 0
+ * @Max: 10000
+ * @Default: 1000
+ *
+ * This ini is used to mention the Low Threshold inorder to trigger TCP Del Ack
+ * indication i.e the threshold of packets received over a period of 100 ms.
+ * i.e to have a low RX throughput requirement
+ *
+ * Related: gTcpDelAckEnable, gTcpDelAckThresholdHigh, gTcpDelAckTimerCount
+ *
+ * Supported Feature: Tcp Delayed Ack
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_TCP_DELACK_THRESHOLD_LOW \
+		CFG_INI_UINT( \
+		"gTcpDelAckThresholdLow", \
+		0, \
+		10000, \
+		1000, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Low Threshold inorder to trigger TCP Del Ack")
+
+/*
+ * <ini>
+ * gTcpDelAckTimerCount - Del Ack Timer Count inorder to trigger TCP Del Ack
+ *                                      indication
+ * @Min: 1
+ * @Max: 1000
+ * @Default: 30
+ *
+ * This ini is used to mention the Del Ack Timer Count inorder to
+ * trigger TCP Del Ack indication i.e number of 100 ms periods
+ *
+ * Related: gTcpDelAckEnable, gTcpDelAckThresholdHigh, gTcpDelAckThresholdLow
+ *
+ * Supported Feature: Tcp Delayed Ack
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_TCP_DELACK_TIMER_COUNT \
+		CFG_INI_UINT( \
+		"gTcpDelAckTimerCount", \
+		1, \
+		1000, \
+		30, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Del Ack Timer Count inorder to trigger TCP Del Ack")
+
+/*
+ * <ini>
+ * gTcpTxHighTputThreshold - High Threshold inorder to trigger High
+ *                                          Tx Throughput requirement.
+ * @Min: 0
+ * @Max: 16000
+ * @Default: 500
+ *
+ * This ini specifies the threshold of packets transmitted
+ * over a period of 100 ms beyond which TCP can be considered to have a high
+ * TX throughput requirement. The driver uses this condition to tweak TCP TX
+ * specific parameters (via cnss-daemon)
+ *
+ * Supported Feature: To tweak TCP TX n/w parameters
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_TCP_TX_HIGH_TPUT_THRESHOLD \
+		CFG_INI_UINT( \
+		"gTcpTxHighTputThreshold", \
+		0, \
+		16000, \
+		500, \
+		CFG_VALUE_OR_DEFAULT, \
+		"High Threshold inorder to trigger High Tx Tp")
+
+#endif /* MSM_PLATFORM */
+
+/*
+ * <ini>
+ * NAPI_CPU_AFFINITY_MASK - CPU mask to affine NAPIs
+ *
+ * @Min: 0
+ * @Max: 0xFF
+ * @Default: 0
+ *
+ * This ini is used to set NAPI IRQ CPU affinity
+ *
+ * Supported Feature: NAPI
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_NAPI_CE_CPU_MASK \
+		CFG_INI_UINT( \
+		"NAPI_CPU_AFFINITY_MASK", \
+		0, \
+		0xFF, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"CPU mask to affine NAPIs")
+
+/*
+ * <ini>
+ * RX_THREAD_CPU_AFFINITY_MASK - CPU mask to affine Rx_thread
+ *
+ * @Default: e
+ *
+ * This ini is used to set Rx_thread CPU affinity
+ *
+ * Supported Feature: Rx_thread
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_RX_THREAD_CPU_MASK \
+		CFG_INI_UINT( \
+		"RX_THREAD_CPU_AFFINITY_MASK", \
+		0, \
+		0xFF, \
+		0, \
+		CFG_VALUE_OR_DEFAULT, \
+		"CPU mask to affine Rx_thread")
+
+/*
+ * <ini>
+ * RX_THREAD_CPU_AFFINITY_MASK - CPU mask to affine Rx_thread
+ *
+ * @Min: 0
+ * @Max: 0xFF
+ * @Default: 0
+ *
+ * This ini is used to set Rx_thread CPU affinity
+ *
+ * List of RPS CPU maps for different rx queues registered by WLAN driver
+ * Ref - Kernel/Documentation/networking/scaling.txt
+ * RPS CPU map for a particular RX queue, selects CPU(s) for bottom half
+ * processing of RX packets. For example, for a system with 4 CPUs,
+ * 0xe: Use CPU1 - CPU3 and donot use CPU0.
+ * 0x0: RPS is disabled, packets are processed on the interrupting CPU.
+.*
+ * WLAN driver registers NUM_TX_QUEUES queues for tx and rx each during
+ * alloc_netdev_mq. Hence, we need to have a cpu mask for each of the rx queues.
+ *
+ * For example, if the NUM_TX_QUEUES is 4, a sample WLAN ini entry may look like
+ * rpsRxQueueCpuMapList=a b c d
+ * For a 4 CPU system (CPU0 - CPU3), this implies:
+ * 0xa - (1010) use CPU1, CPU3 for rx queue 0
+ * 0xb - (1011) use CPU0, CPU1 and CPU3 for rx queue 1
+ * 0xc - (1100) use CPU2, CPU3 for rx queue 2
+ * 0xd - (1101) use CPU0, CPU2 and CPU3 for rx queue 3
+
+ * In practice, we may want to avoid the cores which are heavily loaded.
+ *
+ * Default value of rpsRxQueueCpuMapList. Different platforms may have
+ * different configurations for NUM_TX_QUEUES and # of cpus, and will need to
+ * configure an appropriate value via ini file. Setting default value to 'e' to
+ * avoid use of CPU0 (since its heavily used by other system processes) by rx
+ * queue 0, which is currently being used for rx packet processing.
+ *
+ * Maximum length of string used to hold a list of cpu maps for various rx
+ * queues. Considering a 16 core system with 5 rx queues, a RPS CPU map
+ * list may look like -
+ * rpsRxQueueCpuMapList = ffff ffff ffff ffff ffff
+ * (all 5 rx queues can be processed on all 16 cores)
+ * max string len = 24 + 1(for '\0'). Considering 30 to be on safe side.
+ *
+ * Supported Feature: Rx_thread
+ *
+ * Usage: Internal
+ * </ini>
+ */
+#define CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST \
+		CFG_INI_STRING( \
+		"rpsRxQueueCpuMapList", \
+		1, \
+		30, \
+		"e", \
+		"specify RPS map for different RX queus")
+
+/*
+ * <ini>
+ * gEnableTxOrphan- Enable/Disable orphaning of Tx packets
+ * @Default: false
+ *
+ * This ini is used to enable/disable orphaning of Tx packets.
+ *
+ * Related: None
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_DP_TX_ORPHAN_ENABLE \
+		CFG_INI_BOOL( \
+		"gEnableTxOrphan", \
+		false, \
+		"orphaning of Tx packets")
+
+/*
+ * <ini>
+ * rx_mode - Control to decide rx mode for packet procesing
+ *
+ * @Min: 0
+ * @Max: (CFG_ENABLE_RX_THREAD | CFG_ENABLE_RPS | CFG_ENABLE_NAPI | \
+ *	 CFG_ENABLE_DYNAMIC_RPS)
+ *
+ * Some possible configurations:
+ * rx_mode=0 - Uses tasklets for bottom half
+ * CFG_ENABLE_NAPI (rx_mode=4) - Uses NAPI for bottom half
+ * CFG_ENABLE_RX_THREAD | CFG_ENABLE_NAPI (rx_mode=5) - NAPI for bottom half,
+ * rx_thread for stack. Single threaded.
+ * CFG_ENABLE_DP_RX_THREAD | CFG_ENABLE_NAPI (rx_mode=10) - NAPI for bottom
+ * half, dp_rx_thread for stack processing. Supports multiple rx threads.
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DP_RX_MODE \
+		CFG_INI_UINT("rx_mode", \
+		0, CFG_RX_MODE_MAX, CFG_RX_MODE_DEFAULT, \
+		CFG_VALUE_OR_DEFAULT, \
+		"Control to decide rx mode for packet procesing")
+
+#define CFG_DP_CE_SERVICE_MAX_RX_IND_FLUSH \
+		CFG_INI_UINT("ce_service_max_rx_ind_flush", \
+		1, 32, 32, \
+		CFG_VALUE_OR_DEFAULT, "Ctrl to set ce service max rx ind flsh")
+
+#define CFG_DP_CE_SERVICE_MAX_YIELD_TIME \
+		CFG_INI_UINT("ce_service_max_yield_time", \
+		500, 10000, 10000, \
+		CFG_VALUE_OR_DEFAULT, "Ctrl to set ce service max yield time")
+
+#ifdef WLAN_FEATURE_FASTPATH
+#define CFG_DP_ENABLE_FASTPATH \
+		CFG_INI_BOOL("gEnableFastPath", \
+		false, "Ctrl to enable fastpath feature")
+
+#define CFG_DP_ENABLE_FASTPATH_ALL \
+	CFG(CFG_DP_ENABLE_FASTPATH)
+#else
+#define CFG_DP_ENABLE_FASTPATH_ALL
+#endif
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+#define CFG_HDD_DP_LEGACY_TX_FLOW \
+	CFG(CFG_DP_LL_TX_FLOW_LWM) \
+	CFG(CFG_DP_LL_TX_FLOW_HWM_OFFSET) \
+	CFG(CFG_DP_LL_TX_FLOW_MAX_Q_DEPTH) \
+	CFG(CFG_DP_LL_TX_LBW_FLOW_LWM) \
+	CFG(CFG_DP_LL_TX_LBW_FLOW_HWM_OFFSET) \
+	CFG(CFG_DP_LL_TX_LBW_FLOW_MAX_Q_DEPTH) \
+	CFG(CFG_DP_LL_TX_HBW_FLOW_LWM) \
+	CFG(CFG_DP_LL_TX_HBW_FLOW_HWM_OFFSET) \
+	CFG(CFG_DP_LL_TX_HBW_FLOW_MAX_Q_DEPTH)
+#else
+#define CFG_HDD_DP_LEGACY_TX_FLOW
+#endif
+
+#ifdef MSM_PLATFORM
+#define CFG_HDD_DP_MSM_PLATFORM \
+	CFG(CFG_DP_BUS_BANDWIDTH_HIGH_THRESHOLD) \
+	CFG(CFG_DP_BUS_BANDWIDTH_MEDIUM_THRESHOLD) \
+	CFG(CFG_DP_BUS_BANDWIDTH_LOW_THRESHOLD) \
+	CFG(CFG_DP_BUS_BANDWIDTH_COMPUTE_INTERVAL) \
+	CFG(CFG_DP_ENABLE_TCP_LIMIT_OUTPUT) \
+	CFG(CFG_DP_ENABLE_TCP_ADV_WIN_SCALE) \
+	CFG(CFG_DP_ENABLE_TCP_DELACK) \
+	CFG(CFG_DP_TCP_DELACK_THRESHOLD_HIGH) \
+	CFG(CFG_DP_TCP_DELACK_THRESHOLD_LOW) \
+	CFG(CFG_DP_TCP_DELACK_TIMER_COUNT) \
+	CFG(CFG_DP_TCP_TX_HIGH_TPUT_THRESHOLD)
+#else
+#define CFG_HDD_DP_MSM_PLATFORM
+#endif
+
+#define CFG_HDD_DP \
+	CFG(CFG_DP_NAPI_CE_CPU_MASK) \
+	CFG(CFG_DP_RX_THREAD_CPU_MASK) \
+	CFG(CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST) \
+	CFG(CFG_DP_TX_ORPHAN_ENABLE) \
+	CFG(CFG_DP_RX_MODE) \
+	CFG(CFG_DP_CE_SERVICE_MAX_RX_IND_FLUSH) \
+	CFG(CFG_DP_CE_SERVICE_MAX_YIELD_TIME) \
+	CFG_DP_ENABLE_FASTPATH_ALL
+#define CFG_HDD_DP_ALL \
+	CFG_HDD_DP \
+	CFG_HDD_DP_MSM_PLATFORM \
+	CFG_HDD_DP_LEGACY_TX_FLOW
+#endif
diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h
new file mode 100644
index 0000000..60ef74b
--- /dev/null
+++ b/core/hdd/inc/qc_sap_ioctl.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef _QC_SAP_IOCTL_H_
+#define _QC_SAP_IOCTL_H_
+
+/*
+ * QCSAP ioctls.
+ */
+
+#define QCSAP_ADDR_LEN  6
+
+typedef uint8_t qcmacaddr[QCSAP_ADDR_LEN];
+
+/*
+ * Channel List Info
+ */
+
+struct channel_list_info {
+	uint8_t num_channels;
+	uint8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+};
+
+#ifdef __linux__
+/*
+ * Wireless Extensions API, private ioctl interfaces.
+ *
+ * NB: Even-numbered ioctl numbers have set semantics and are privileged!
+ *     (regardless of the incorrect comment in wireless.h!)
+ */
+
+#define QCSAP_IOCTL_SETPARAM          (SIOCIWFIRSTPRIV + 0)
+#define QCSAP_IOCTL_GETPARAM          (SIOCIWFIRSTPRIV + 1)
+/* (SIOCIWFIRSTPRIV+2) is unused */
+#define QCSAP_IOCTL_SET_NONE_GET_THREE (SIOCIWFIRSTPRIV + 3)
+#define WE_GET_TSF 1
+#define QCSAP_IOCTL_GET_STAWPAIE      (SIOCIWFIRSTPRIV + 4)
+#define QCSAP_IOCTL_STOPBSS           (SIOCIWFIRSTPRIV + 6)
+#define QCSAP_IOCTL_VERSION           (SIOCIWFIRSTPRIV + 7)
+/* (SIOCIWFIRSTPRIV + 8) is unused */
+#define QCSAP_IOCTL_GET_CHANNEL       (SIOCIWFIRSTPRIV + 9)
+#define QCSAP_IOCTL_ASSOC_STA_MACADDR (SIOCIWFIRSTPRIV + 10)
+#define QCSAP_IOCTL_DISASSOC_STA      (SIOCIWFIRSTPRIV + 11)
+#define QCSAP_IOCTL_SET_PKTLOG        (SIOCIWFIRSTPRIV + 12)
+
+/* Private ioctls and their sub-ioctls */
+#define QCSAP_PRIV_GET_CHAR_SET_NONE   (SIOCIWFIRSTPRIV + 13)
+#define QCSAP_GET_STATS 1
+#define QCSAP_LIST_FW_PROFILE 2
+#define QCSAP_IOCTL_CLR_STATS         (SIOCIWFIRSTPRIV + 14)
+
+#define QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 15)
+#define WE_SET_WLAN_DBG 1
+#define WE_SET_DP_TRACE 2
+#define QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 16)
+#define WE_UNIT_TEST_CMD   7
+/*
+ * <ioctl>
+ * ch_avoid - unit test SAP channel avoidance
+ *
+ * @INPUT: chan avoid ranges
+ *
+ * @OUTPUT: none
+ *
+ * This IOCTL is used to fake a channel avoidance event.
+ * To test SAP/GO chan switch during chan avoid event process.
+ *
+ * @E.g: iwpriv wlan0 ch_avoid 2452 2462
+ *
+ * Supported Feature: SAP chan avoidance.
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_SET_CHAN_AVOID 21
+
+#define WE_P2P_NOA_CMD  2
+
+#define QCSAP_IOCTL_MODIFY_ACL          (SIOCIWFIRSTPRIV + 18)
+#define QCSAP_IOCTL_GET_CHANNEL_LIST    (SIOCIWFIRSTPRIV + 19)
+#define QCSAP_IOCTL_SET_TX_POWER        (SIOCIWFIRSTPRIV + 20)
+#define QCSAP_IOCTL_GET_STA_INFO        (SIOCIWFIRSTPRIV + 21)
+#define QCSAP_IOCTL_SET_MAX_TX_POWER    (SIOCIWFIRSTPRIV + 22)
+#define QCSAP_IOCTL_GET_INI_CFG         (SIOCIWFIRSTPRIV + 25)
+#define QCSAP_IOCTL_SET_INI_CFG         (SIOCIWFIRSTPRIV + 26)
+#define QCSAP_IOCTL_SET_TWO_INT_GET_NONE (SIOCIWFIRSTPRIV + 28)
+#define QCSAP_IOCTL_PRIV_GET_RSSI       (SIOCIWFIRSTPRIV + 29)
+#define QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED (SIOCIWFIRSTPRIV + 31)
+#define QCSAP_IOCTL_GET_BA_AGEING_TIMEOUT (SIOCIWFIRSTPRIV + 32)
+#define QCSAP_IOCTL_SET_FW_CRASH_INJECT 1
+#define QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL 2
+#define QCSAP_ENABLE_FW_PROFILE          3
+#define QCSAP_SET_FW_PROFILE_HIST_INTVL  4
+
+/* Private sub-ioctl for initiating WoW suspend without Apps suspend */
+#define QCSAP_SET_WLAN_SUSPEND  5
+#define QCSAP_SET_WLAN_RESUME   6
+#define QCSAP_SET_BA_AGEING_TIMEOUT 7
+
+#define MAX_VAR_ARGS         7
+
+#define QCSAP_IOCTL_MAX_STR_LEN 1024
+
+#define RC_2_RATE_IDX(_rc)              ((_rc) & 0x7)
+#define HT_RC_2_STREAMS(_rc)            ((((_rc) & 0x78) >> 3) + 1)
+
+#define RC_2_RATE_IDX_11AC(_rc)         ((_rc) & 0xf)
+#define HT_RC_2_STREAMS_11AC(_rc)       ((((_rc) & 0x30) >> 4) + 1)
+
+#define RC_2_RATE_IDX_11AX(_rc)         ((_rc) & 0x1f)
+#define HT_RC_2_STREAMS_11AX(_rc)       (((_rc) >> 5) & 0x7)
+
+/*
+ * <ioctl>
+ * setRadar - simulate a radar event
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to simulate a radar event, state machines for
+ * SAP will behave as same way in which a radar event is reported by WMA
+ *
+ * @E.g: iwpriv wlan0 setRadar
+ *
+ * Supported Feature: DFS
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+
+/*
+ * <ioctl>
+ * setRadarDbg - enable/disable radar specific logs
+ *
+ * @INPUT: 1/0
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is enable radar phyerror info in wma
+ *
+ * @E.g: iwpriv wlan0 setRadarDbg <enable>
+ *  iwpriv wlan0 setRadarDbg 1
+ *
+ * Supported Feature: DFS
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+enum {
+	QCSAP_PARAM_MAX_ASSOC = 1,
+	QCSAP_PARAM_GET_WLAN_DBG,
+	QCSAP_PARAM_CLR_ACL = 4,
+	QCSAP_PARAM_ACL_MODE,
+	QCSAP_PARAM_HIDE_SSID,
+	QCSAP_PARAM_SET_MC_RATE,
+	QCSAP_PARAM_SET_TXRX_FW_STATS,
+	QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY,
+	QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA,
+	QCSAP_DBGLOG_LOG_LEVEL,
+	QCSAP_DBGLOG_VAP_ENABLE,
+	QCSAP_DBGLOG_VAP_DISABLE,
+	QCSAP_DBGLOG_MODULE_ENABLE,
+	QCSAP_DBGLOG_MODULE_DISABLE,
+	QCSAP_DBGLOG_MOD_LOG_LEVEL,
+	QCSAP_DBGLOG_TYPE,
+	QCSAP_DBGLOG_REPORT_ENABLE,
+	QCASAP_TXRX_FWSTATS_RESET,
+	QCSAP_PARAM_RTSCTS,
+	QCASAP_SET_11N_RATE,
+	QCASAP_SET_VHT_RATE,
+	QCASAP_SHORT_GI,
+	QCSAP_SET_AMPDU,
+	QCSAP_SET_AMSDU,
+	QCSAP_GTX_HT_MCS,
+	QCSAP_GTX_VHT_MCS,
+	QCSAP_GTX_USRCFG,
+	QCSAP_GTX_THRE,
+	QCSAP_GTX_MARGIN,
+	QCSAP_GTX_STEP,
+	QCSAP_GTX_MINTPC,
+	QCSAP_GTX_BWMASK,
+	QCASAP_SET_TM_LEVEL,
+	QCASAP_SET_DFS_IGNORE_CAC,
+	QCASAP_GET_DFS_NOL,
+	QCASAP_SET_DFS_NOL,
+	QCSAP_PARAM_SET_CHANNEL_CHANGE,
+	QCASAP_SET_DFS_TARGET_CHNL,
+	QCASAP_SET_RADAR_CMD,
+	QCSAP_GET_ACL,
+	QCASAP_TX_CHAINMASK_CMD,
+	QCASAP_RX_CHAINMASK_CMD,
+	QCASAP_NSS_CMD,
+	QCSAP_IPA_UC_STAT,
+	QCASAP_SET_PHYMODE,
+	QCASAP_GET_TEMP_CMD,
+	QCASAP_DUMP_STATS,
+	QCASAP_CLEAR_STATS,
+	QCASAP_SET_RADAR_DBG,
+	QCSAP_GET_FW_PROFILE_DATA,
+	QCSAP_START_FW_PROFILING,
+	QCSAP_CAP_TSF,
+	QCSAP_GET_TSF,
+	QCSAP_PARAM_CONC_SYSTEM_PREF,
+	QCASAP_PARAM_LDPC,
+	QCASAP_PARAM_TX_STBC,
+	QCASAP_PARAM_RX_STBC,
+	QCSAP_PARAM_CHAN_WIDTH,
+	QCSAP_PARAM_SET_TXRX_STATS,
+	QCASAP_SET_11AX_RATE,
+	QCASAP_SET_PEER_RATE,
+	QCASAP_PARAM_DCM,
+	QCASAP_PARAM_RANGE_EXT,
+	QCSAP_SET_DEFAULT_AMPDU,
+	QCSAP_ENABLE_RTS_BURSTING,
+	QCASAP_SET_HE_BSS_COLOR,
+};
+
+int iw_get_channel_list(struct net_device *dev,
+		struct iw_request_info *info,
+		union iwreq_data *wrqu, char *extra);
+
+#endif /* __linux__ */
+
+#endif /*_QC_SAP_IOCTL_H_*/
diff --git a/core/hdd/inc/wlan_hdd_apf.h b/core/hdd/inc/wlan_hdd_apf.h
new file mode 100644
index 0000000..eeee392
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_apf.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**
+ * DOC: wlan_hdd_apf.h
+ *
+ * Android Packet Filter related API's and definitions
+ */
+
+#ifndef __WLAN_HDD_APF_H
+#define __WLAN_HDD_APF_H
+
+#ifdef FEATURE_WLAN_APF
+
+#include <net/cfg80211.h>
+#include "sir_api.h"
+#include "wlan_hdd_main.h"
+#include "wmi_unified_param.h"
+
+#define APF_CONTEXT_MAGIC 0x4575354
+
+#define MAX_APF_MEMORY_LEN	4096
+
+/* APF commands wait times in msec */
+#define WLAN_WAIT_TIME_APF_GET_CAPS     1000
+#define WLAN_WAIT_TIME_APF_READ_MEM     10000
+
+/**
+ * wlan_hdd_cfg80211_apf_offload() - SSR Wrapper to APF Offload
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success; errno on failure
+ */
+
+int wlan_hdd_cfg80211_apf_offload(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  const void *data, int data_len);
+
+/**
+ * hdd_apf_context_init - APF Context initialization operations
+ * @adapter: hdd adapter
+ *
+ * Return: None
+ */
+void hdd_apf_context_init(struct hdd_adapter *adapter);
+
+/**
+ * hdd_apf_context_destroy - APF Context de-init operations
+ * @adapter: hdd adapter
+ *
+ * Return: None
+ */
+void hdd_apf_context_destroy(struct hdd_adapter *adapter);
+
+/**
+ * hdd_get_apf_capabilities_cb() - Callback function to get APF capabilities
+ * @hdd_context: pointer to the hdd context
+ * @apf_get_offload: struct for get offload
+ *
+ * This function receives the response/data from the lower layer and
+ * checks to see if the thread is still waiting then post the results to
+ * upper layer, if the request has timed out then ignore.
+ *
+ * Return: None
+ */
+void hdd_get_apf_capabilities_cb(void *hdd_context,
+				 struct sir_apf_get_offload *data);
+#else /* FEATURE_WLAN_APF */
+
+static inline void hdd_apf_context_init(struct hdd_adapter *adapter)
+{
+}
+
+static inline void hdd_apf_context_destroy(struct hdd_adapter *adapter)
+{
+}
+
+#endif /* FEATURE_WLAN_APF */
+
+#endif /* WLAN_HDD_APF_H */
diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h
new file mode 100644
index 0000000..41d9667
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_assoc.h
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#if !defined(WLAN_HDD_ASSOC_H__)
+#define WLAN_HDD_ASSOC_H__
+
+/**
+ * DOC: wlan_hdd_assoc.h
+ *
+ */
+
+/* Include files */
+#include <sme_api.h>
+#include <wlan_defs.h>
+#include "cdp_txrx_peer_ops.h"
+#include <net/cfg80211.h>
+#include <linux/ieee80211.h>
+
+#define HDD_TIME_STRING_LEN 24
+
+/* Preprocessor Definitions and Constants */
+#ifdef FEATURE_WLAN_TDLS
+#define HDD_MAX_NUM_TDLS_STA          8
+#define HDD_MAX_NUM_TDLS_STA_P_UAPSD_OFFCHAN  1
+#define TDLS_STA_INDEX_VALID(staId) \
+	(((staId) >= 0) && ((staId) < 0xFF))
+#else
+#define HDD_MAX_NUM_TDLS_STA          0
+
+#endif
+/* Timeout (in ms) for Link to Up before Registering Station */
+#define ASSOC_LINKUP_TIMEOUT 60
+
+/* Timeout in ms for peer info request commpletion */
+#define IBSS_PEER_INFO_REQ_TIMOEUT 1000
+
+#define INVALID_PEER_IDX -1
+
+/**
+ * enum eConnectionState - connection state values at HDD
+ * @eConnectionState_NotConnected: Not associated in Infra or participating in
+ *			in an IBSS / Ad-hoc network
+ * @eConnectionState_Connecting: While connection in progress
+ * @eConnectionState_Associated: Associated in an Infrastructure network
+ * @eConnectionState_IbssDisconnected: Participating in an IBSS network though
+ *			disconnected (no partner stations in the IBSS)
+ * @eConnectionState_IbssConnected: Participating in an IBSS network with
+ *			partner stations also present
+ * @eConnectionState_Disconnecting: Disconnecting in an Infrastructure network.
+ * @eConnectionState_NdiDisconnected: NDI in disconnected state - no peers
+ * @eConnectionState_NdiConnected: NDI in connected state - at least one peer
+ */
+typedef enum {
+	eConnectionState_NotConnected,
+	eConnectionState_Connecting,
+	eConnectionState_Associated,
+	eConnectionState_IbssDisconnected,
+	eConnectionState_IbssConnected,
+	eConnectionState_Disconnecting,
+	eConnectionState_NdiDisconnected,
+	eConnectionState_NdiConnected,
+} eConnectionState;
+
+/**
+ * enum peer_status - Peer status
+ * @ePeerConnected: peer connected
+ * @ePeerDisconnected: peer disconnected
+ */
+enum peer_status {
+	ePeerConnected = 1,
+	ePeerDisconnected
+};
+
+/**
+ * struct hdd_conn_flag - connection flags
+ * @ht_present: ht element present or not
+ * @vht_present: vht element present or not
+ * @hs20_present: hs20 element present or not
+ * @ht_op_present: ht operation present or not
+ * @vht_op_present: vht operation present or not
+ */
+struct hdd_conn_flag {
+	uint8_t ht_present:1;
+	uint8_t vht_present:1;
+	uint8_t hs20_present:1;
+	uint8_t ht_op_present:1;
+	uint8_t vht_op_present:1;
+	uint8_t reserved:3;
+};
+
+/*defines for tx_BF_cap_info */
+#define TX_BF_CAP_INFO_TX_BF			0x00000001
+#define TX_BF_CAP_INFO_RX_STAG_RED_SOUNDING	0x00000002
+#define TX_BF_CAP_INFO_TX_STAG_RED_SOUNDING	0x00000004
+#define TX_BF_CAP_INFO_RX_ZFL			0x00000008
+#define TX_BF_CAP_INFO_TX_ZFL			0x00000010
+#define TX_BF_CAP_INFO_IMP_TX_BF		0x00000020
+#define TX_BF_CAP_INFO_CALIBRATION		0x000000c0
+#define TX_BF_CAP_INFO_CALIBRATION_SHIFT	6
+#define TX_BF_CAP_INFO_EXP_CSIT_BF		0x00000100
+#define TX_BF_CAP_INFO_EXP_UNCOMP_STEER_MAT	0x00000200
+#define TX_BF_CAP_INFO_EXP_BF_CSI_FB		0x00001c00
+#define TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT	10
+#define TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT	0x0000e000
+#define TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT 13
+#define TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB	0x00070000
+#define TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT 16
+#define TX_BF_CAP_INFO_CSI_NUM_BF_ANT		0x00180000
+#define TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT	18
+#define TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT	0x00600000
+#define TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT 20
+#define TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT	0x01800000
+#define TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT 22
+#define TX_BF_CAP_INFO_RSVD			0xfe000000
+
+/* defines for antenna selection info */
+#define ANTENNA_SEL_INFO			0x01
+#define ANTENNA_SEL_INFO_EXP_CSI_FB_TX		0x02
+#define ANTENNA_SEL_INFO_ANT_ID_FB_TX		0x04
+#define ANTENNA_SEL_INFO_EXP_CSI_FB		0x08
+#define ANTENNA_SEL_INFO_ANT_ID_FB		0x10
+#define ANTENNA_SEL_INFO_RX_AS			0x20
+#define ANTENNA_SEL_INFO_TX_SOUNDING_PPDU	0x40
+#define ANTENNA_SEL_INFO_RSVD			0x80
+
+/**
+ * struct hdd_connection_info - structure to store connection information
+ * @connState: connection state of the NIC
+ * @bssId: BSSID
+ * @SSID: SSID Info
+ * @staId: Station ID
+ * @peerMacAddress:Peer Mac Address of the IBSS Stations
+ * @authType: Auth Type
+ * @ucEncryptionType: Unicast Encryption Type
+ * @mcEncryptionType: Multicast Encryption Type
+ * @Keys: Keys
+ * @operationChannel: Operation Channel
+ * @uIsAuthenticated: Remembers authenticated state
+ * @dot11Mode: dot11Mode
+ * @proxyARPService: proxy arp service
+ * @ptk_installed: ptk installed state
+ * @gtk_installed: gtk installed state
+ * @nss: number of spatial streams negotiated
+ * @rate_flags: rate flags for current connection
+ * @freq: channel frequency
+ * @txrate: txrate structure holds nss & datarate info
+ * @noise: holds noise information
+ * @ht_caps: holds ht capabilities info
+ * @vht_caps: holds vht capabilities info
+ * @hs20vendor_ie: holds passpoint/hs20 info
+ * @conn_flag: flag conn info params is present or not
+ * @roam_count: roaming counter
+ * @signal: holds rssi info
+ * @assoc_status_code: holds assoc fail reason
+ * @congestion: holds congestion percentage
+ * @last_ssid: holds last ssid
+ * @last_auth_type: holds last auth type
+ * @auth_time: last authentication established time
+ * @connect_time: last association established time
+ * @ch_width: channel width of operating channel
+ */
+struct hdd_connection_info {
+	eConnectionState connState;
+	struct qdf_mac_addr bssId;
+	tCsrSSIDInfo SSID;
+	uint8_t staId[MAX_PEERS];
+	struct qdf_mac_addr peerMacAddress[MAX_PEERS];
+	eCsrAuthType authType;
+	eCsrEncryptionType ucEncryptionType;
+	eCsrEncryptionType mcEncryptionType;
+	tCsrKeys Keys;
+	uint8_t operationChannel;
+	uint8_t uIsAuthenticated;
+	uint32_t dot11Mode;
+	uint8_t proxyARPService;
+	bool ptk_installed;
+	bool gtk_installed;
+	uint8_t nss;
+	uint32_t rate_flags;
+	uint32_t freq;
+	struct rate_info txrate;
+	int8_t noise;
+	struct ieee80211_ht_cap ht_caps;
+	struct ieee80211_vht_cap vht_caps;
+	struct hdd_conn_flag conn_flag;
+	tDot11fIEhs20vendor_ie hs20vendor_ie;
+	struct ieee80211_ht_operation ht_operation;
+	struct ieee80211_vht_operation vht_operation;
+	uint32_t roam_count;
+	int8_t signal;
+	int32_t assoc_status_code;
+	uint32_t cca;
+	tCsrSSIDInfo last_ssid;
+	eCsrAuthType last_auth_type;
+	char auth_time[HDD_TIME_STRING_LEN];
+	char connect_time[HDD_TIME_STRING_LEN];
+	enum phy_ch_width ch_width;
+};
+
+/* Forward declarations */
+struct hdd_adapter;
+struct hdd_station_ctx;
+struct hdd_context;
+
+/**
+ * hdd_is_connecting() - Function to check connection progress
+ * @hdd_sta_ctx:    pointer to global HDD Station context
+ *
+ * Return: true if connecting, false otherwise
+ */
+bool hdd_is_connecting(struct hdd_station_ctx *hdd_sta_ctx);
+
+/*
+ * hdd_is_fils_connection: API to determine if connection is FILS
+ * @adapter: hdd adapter
+ *
+ * Return: true if fils connection else false
+ */
+bool hdd_is_fils_connection(struct hdd_adapter *adapter);
+
+/**
+ * hdd_conn_is_connected() - Function to check connection status
+ * @sta_ctx:    pointer to global HDD Station context
+ *
+ * Return: false if any errors encountered, true otherwise
+ */
+bool hdd_conn_is_connected(struct hdd_station_ctx *sta_ctx);
+
+/**
+ * hdd_adapter_is_connected_sta() - check if @adapter is a connected station
+ * @adapter: the adapter to check
+ *
+ * Return: true if @adapter is a connected station
+ */
+bool hdd_adapter_is_connected_sta(struct hdd_adapter *adapter);
+
+/**
+ * hdd_conn_get_connected_band() - get current connection radio band
+ * @sta_ctx:    pointer to global HDD Station context
+ *
+ * Return: BAND_2G or BAND_5G based on current AP connection
+ *      BAND_ALL if not connected
+ */
+enum band_info hdd_conn_get_connected_band(struct hdd_station_ctx *sta_ctx);
+
+/**
+ * hdd_get_sta_connection_in_progress() - get STA for which connection
+ *                                        is in progress
+ * @hdd_ctx: hdd context
+ *
+ * Return: hdd adpater for which connection is in progress
+ */
+struct hdd_adapter *hdd_get_sta_connection_in_progress(
+			struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_sme_roam_callback() - hdd sme roam callback
+ * @pContext: pointer to adapter context
+ * @roam_info: pointer to roam info
+ * @roamId: roam id
+ * @roamStatus: roam status
+ * @roamResult: roam result
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_sme_roam_callback(void *pContext,
+				 struct csr_roam_info *roam_info,
+				 uint32_t roamId,
+				 eRoamCmdStatus roamStatus,
+				 eCsrRoamResult roamResult);
+
+/**
+ * hdd_set_genie_to_csr() - set genie to csr
+ * @adapter: pointer to adapter
+ * @RSNAuthType: pointer to auth type
+ *
+ * Return: 0 on success, error number otherwise
+ */
+int hdd_set_genie_to_csr(struct hdd_adapter *adapter,
+			 eCsrAuthType *RSNAuthType);
+
+/**
+ * hdd_set_csr_auth_type() - set csr auth type
+ * @adapter: pointer to adapter
+ * @RSNAuthType: auth type
+ *
+ * Return: 0 on success, error number otherwise
+ */
+int hdd_set_csr_auth_type(struct hdd_adapter *adapter,
+			  eCsrAuthType RSNAuthType);
+
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * hdd_roam_register_tdlssta() - register new TDLS station
+ * @adapter: pointer to adapter
+ * @peerMac: pointer to peer MAC address
+ * @staId: station identifier
+ * @qos: Quality of service
+ *
+ * Construct the staDesc and register the new STA with the Data Plane.
+ * This is called as part of ADD_STA in the TDLS setup.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_roam_register_tdlssta(struct hdd_adapter *adapter,
+				     const uint8_t *peerMac, uint16_t staId,
+				     uint8_t qos);
+#endif
+
+QDF_STATUS hdd_roam_deregister_tdlssta(struct hdd_adapter *adapter,
+				       uint8_t staId);
+
+/**
+ * hdd_perform_roam_set_key_complete() - perform set key complete
+ * @adapter: pointer to adapter
+ *
+ * Return: none
+ */
+void hdd_perform_roam_set_key_complete(struct hdd_adapter *adapter);
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
+ * @adapter: pointer to adapter
+ * @measurementToken: measurement token
+ * @flag: flag
+ * @numBss: number of bss
+ *
+ * If the measurement is none and no scan results found,
+ * indicate the supplicant about measurement done.
+ *
+ * Return: none
+ */
+void
+hdd_indicate_ese_bcn_report_no_results(const struct hdd_adapter *adapter,
+					    const uint16_t measurementToken,
+					    const bool flag,
+					    const uint8_t numBss);
+#endif /* FEATURE_WLAN_ESE */
+
+QDF_STATUS hdd_change_peer_state(struct hdd_adapter *adapter,
+				 uint8_t sta_id,
+				 enum ol_txrx_peer_state sta_state,
+				 bool roam_synch_in_progress);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+bool hdd_is_roam_sync_in_progress(struct csr_roam_info *roaminfo);
+#else
+static inline bool hdd_is_roam_sync_in_progress(struct csr_roam_info *roaminfo)
+{
+	return false;
+}
+#endif
+
+QDF_STATUS hdd_update_dp_vdev_flags(void *cbk_data,
+				    uint8_t sta_id,
+				    uint32_t vdev_param,
+				    bool is_link_up);
+
+QDF_STATUS hdd_roam_register_sta(struct hdd_adapter *adapter,
+				 struct csr_roam_info *roam_info,
+				 uint8_t sta_id,
+				 struct qdf_mac_addr *peer_mac_addr,
+				 struct bss_description *bss_desc);
+
+bool hdd_save_peer(struct hdd_station_ctx *sta_ctx, uint8_t sta_id,
+		   struct qdf_mac_addr *peer_mac_addr);
+void hdd_delete_peer(struct hdd_station_ctx *sta_ctx, uint8_t sta_id);
+QDF_STATUS hdd_roam_deregister_sta(struct hdd_adapter *adapter, uint8_t sta_id);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS
+hdd_wma_send_fastreassoc_cmd(struct hdd_adapter *adapter,
+			     const tSirMacAddr bssid, int channel);
+/**
+ * hdd_save_gtk_params() - Save GTK offload params
+ * @adapter: HDD adapter
+ * @csr_roam_info: CSR roam info
+ * @is_reassoc: boolean to indicate roaming
+ *
+ * Return: None
+ */
+void hdd_save_gtk_params(struct hdd_adapter *adapter,
+			 struct csr_roam_info *csr_roam_info, bool is_reassoc);
+#else
+static inline QDF_STATUS
+hdd_wma_send_fastreassoc_cmd(struct hdd_adapter *adapter,
+			     const tSirMacAddr bssid, int channel)
+{
+	return QDF_STATUS_SUCCESS;
+}
+static inline void hdd_save_gtk_params(struct hdd_adapter *adapter,
+				       struct csr_roam_info *csr_roam_info,
+				       bool is_reassoc)
+{
+}
+#endif
+
+/**
+ * hdd_copy_ht_caps()- copy ht caps info from roam ht caps
+ * info to source ht_cap info of type ieee80211_ht_cap.
+ * @hdd_ht_cap: pointer to Source ht_cap info of type ieee80211_ht_cap
+ * @roam_ht_cap: pointer to roam ht_caps info
+ *
+ * Return: None
+ */
+
+void hdd_copy_ht_caps(struct ieee80211_ht_cap *hdd_ht_cap,
+		      tDot11fIEHTCaps *roam_ht_cap);
+
+/**
+ * hdd_copy_vht_caps()- copy vht caps info from roam vht caps
+ * info to source vht_cap info of type ieee80211_vht_cap.
+ * @hdd_vht_cap: pointer to Source vht_cap info of type ieee80211_vht_cap
+ * @roam_vht_cap: pointer to roam vht_caps info
+ *
+ * Return: None
+ */
+void hdd_copy_vht_caps(struct ieee80211_vht_cap *hdd_vht_cap,
+		       tDot11fIEVHTCaps *roam_vht_cap);
+
+/**
+ * hdd_roam_profile_init() - initialize adapter roam profile
+ * @adapter: The HDD adapter being initialized
+ *
+ * This function initializes the roam profile that is embedded within
+ * the adapter.
+ *
+ * Return: void
+ */
+void hdd_roam_profile_init(struct hdd_adapter *adapter);
+
+#endif
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
new file mode 100644
index 0000000..7be7b35
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -0,0 +1,7028 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#if !defined(HDD_CONFIG_H__)
+#define HDD_CONFIG_H__
+
+/**
+ *
+ * DOC: wlan_hdd_config.h
+ *
+ * WLAN Adapter Configuration functions
+ */
+
+/* $HEADER$ */
+
+/* Include files */
+#include <wlan_hdd_includes.h>
+#include <wlan_hdd_wmm.h>
+#include <qdf_types.h>
+#include <csr_api.h>
+#include <sap_api.h>
+#include "osapi_linux.h"
+#include <wmi_unified.h>
+#include "wlan_pmo_hw_filter_public_struct.h"
+#include "wlan_action_oui_public_struct.h"
+#include "hdd_config.h"
+
+struct hdd_context;
+
+#define CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST_LEN 30
+
+#define FW_MODULE_LOG_LEVEL_STRING_LENGTH  (512)
+#define TX_SCHED_WRR_PARAM_STRING_LENGTH   (50)
+#define TX_SCHED_WRR_PARAMS_NUM            (5)
+
+#ifdef DHCP_SERVER_OFFLOAD
+#define IPADDR_NUM_ENTRIES     (4)
+#define IPADDR_STRING_LENGTH   (16)
+#endif
+
+#define CFG_DBS_SCAN_PARAM_LENGTH          (42)
+
+/* Number of items that can be configured */
+#define MAX_CFG_INI_ITEMS   1024
+
+#define CFG_CONCURRENT_IFACE_MAX_LEN 16
+
+#define CFG_TX_AGGREGATION_SIZE_MIN  0
+#define CFG_TX_AGGREGATION_SIZE_MAX  64
+#define CFG_RX_AGGREGATION_SIZE_MIN  1
+#define CFG_RX_AGGREGATION_SIZE_MAX  64
+
+/* Defines for all of the things we read from the configuration (registry). */
+/*
+ * <ini>
+ * gEnableConnectedScan - Will enable or disable scan in connected state
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable or disable the scanning in
+ * Connected state
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * <ini>
+ */
+
+#define CFG_ENABLE_CONNECTED_SCAN_NAME        "gEnableConnectedScan"
+#define CFG_ENABLE_CONNECTED_SCAN_MIN         (0)
+#define CFG_ENABLE_CONNECTED_SCAN_MAX         (1)
+#define CFG_ENABLE_CONNECTED_SCAN_DEFAULT     (1)
+
+#ifdef WLAN_NUD_TRACKING
+/*
+ * <ini>
+ * gEnableNUDTracking - Will enable or disable NUD tracking within driver
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable or disable NUD tracking within driver
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * <ini>
+ */
+
+#define CFG_ENABLE_NUD_TRACKING_NAME            "gEnableNUDTracking"
+#define CFG_ENABLE_NUD_TRACKING_MIN             (0)
+#define CFG_ENABLE_NUD_TRACKING_MAX             (1)
+#define CFG_ENABLE_NUD_TRACKING_DEFAULT         (1)
+#endif
+
+#define CFG_OPERATING_CHANNEL_NAME             "gOperatingChannel"
+#define CFG_OPERATING_CHANNEL_MIN              (0)
+#define CFG_OPERATING_CHANNEL_MAX              (14)
+#define CFG_OPERATING_CHANNEL_DEFAULT          (1)
+
+/*
+ * <ini>
+ * gShortSlotTimeEnabled - It will set slot timing slot.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set default timing slot.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_SHORT_SLOT_TIME_ENABLED_NAME       "gShortSlotTimeEnabled"
+#define CFG_SHORT_SLOT_TIME_ENABLED_MIN        WNI_CFG_SHORT_SLOT_TIME_STAMIN
+#define CFG_SHORT_SLOT_TIME_ENABLED_MAX        WNI_CFG_SHORT_SLOT_TIME_STAMAX
+#define CFG_SHORT_SLOT_TIME_ENABLED_DEFAULT    WNI_CFG_SHORT_SLOT_TIME_STADEF
+
+#define CFG_11D_SUPPORT_ENABLED_NAME           "g11dSupportEnabled"
+#define CFG_11D_SUPPORT_ENABLED_MIN            WNI_CFG_11D_ENABLED_STAMIN
+#define CFG_11D_SUPPORT_ENABLED_MAX            WNI_CFG_11D_ENABLED_STAMAX
+#define CFG_11D_SUPPORT_ENABLED_DEFAULT        WNI_CFG_11D_ENABLED_STADEF       /* Default is ON */
+
+/*
+ * <ini>
+ * enable_11d_in_world_mode - enable 11d in world mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini enables 11d in world mode, irrespective of value of
+ * g11dSupportEnabled
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+ #define CFG_ENABLE_11D_IN_WORLD_MODE_NAME "enable_11d_in_world_mode"
+ #define CFG_ENABLE_11D_IN_WORLD_MODE_MIN     (0)
+ #define CFG_ENABLE_11D_IN_WORLD_MODE_MAX     (1)
+ #define CFG_ENABLE_11D_IN_WORLD_MODE_DEFAULT (0)
+
+#define CFG_11H_SUPPORT_ENABLED_NAME           "g11hSupportEnabled"
+#define CFG_11H_SUPPORT_ENABLED_MIN            (0)
+#define CFG_11H_SUPPORT_ENABLED_MAX            (1)
+#define CFG_11H_SUPPORT_ENABLED_DEFAULT        (1)    /* Default is ON */
+
+/* COUNTRY Code Priority */
+#define CFG_COUNTRY_CODE_PRIORITY_NAME         "gCountryCodePriority"
+#define CFG_COUNTRY_CODE_PRIORITY_MIN          (0)
+#define CFG_COUNTRY_CODE_PRIORITY_MAX          (1)
+#define CFG_COUNTRY_CODE_PRIORITY_DEFAULT      (0)
+
+#define CFG_REG_CHANGE_DEF_COUNTRY_NAME          "gRegulatoryChangeCountry"
+#define CFG_REG_CHANGE_DEF_COUNTRY_DEFAULT       (0)
+#define CFG_REG_CHANGE_DEF_COUNTRY_MIN           (0)
+#define CFG_REG_CHANGE_DEF_COUNTRY_MAX           (1)
+
+#define CFG_ADVERTISE_CONCURRENT_OPERATION_NAME    "gAdvertiseConcurrentOperation"
+#define CFG_ADVERTISE_CONCURRENT_OPERATION_DEFAULT (1)
+#define CFG_ADVERTISE_CONCURRENT_OPERATION_MIN     (0)
+#define CFG_ADVERTISE_CONCURRENT_OPERATION_MAX     (1)
+
+enum hdd_dot11_mode {
+	eHDD_DOT11_MODE_AUTO = 0,       /* covers all things we support */
+	eHDD_DOT11_MODE_abg,    /* 11a/b/g only, no HT, no proprietary */
+	eHDD_DOT11_MODE_11b,
+	eHDD_DOT11_MODE_11g,
+	eHDD_DOT11_MODE_11n,
+	eHDD_DOT11_MODE_11g_ONLY,
+	eHDD_DOT11_MODE_11n_ONLY,
+	eHDD_DOT11_MODE_11b_ONLY,
+	eHDD_DOT11_MODE_11ac_ONLY,
+	eHDD_DOT11_MODE_11ac,
+	eHDD_DOT11_MODE_11a,
+	eHDD_DOT11_MODE_11ax_ONLY,
+	eHDD_DOT11_MODE_11ax,
+};
+
+/*
+ * <ini>
+ * gChannelBondingMode24GHz - Configures Channel Bonding in 24 GHz
+ * @Min: 0
+ * @Max: 10
+ * @Default: 0
+ *
+ * This ini is used to set default channel bonding mode 24GHZ
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_CHANNEL_BONDING_MODE_24GHZ_NAME    "gChannelBondingMode24GHz"
+#define CFG_CHANNEL_BONDING_MODE_MIN           WNI_CFG_CHANNEL_BONDING_MODE_STAMIN
+#define CFG_CHANNEL_BONDING_MODE_MAX           WNI_CFG_CHANNEL_BONDING_MODE_STAMAX
+#define CFG_CHANNEL_BONDING_MODE_DEFAULT       WNI_CFG_CHANNEL_BONDING_MODE_STADEF
+
+/*
+ * <ini>
+ * override_ht20_40_24g - use channel Bonding in 24 GHz from supplicant
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to use channel Bonding in 24 GHz from supplicant if
+ * gChannelBondingMode24GHz is set
+ *
+ * Related: gChannelBondingMode24GHz
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_OVERRIDE_HT40_20_24GHZ_NAME    "override_ht20_40_24g"
+#define CFG_OVERRIDE_HT40_20_24GHZ_MIN           0
+#define CFG_OVERRIDE_HT40_20_24GHZ_MAX           1
+#define CFG_OVERRIDE_HT40_20_24GHZ_DEFAULT       0
+
+/*
+ * <ini>
+ * gChannelBondingMode5GHz - Configures Channel Bonding in 5 GHz
+ * @Min: 0
+ * @Max: 10
+ * @Default: 0
+ *
+ * This ini is used to set default channel bonding mode 5GHZ
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_CHANNEL_BONDING_MODE_5GHZ_NAME     "gChannelBondingMode5GHz"
+#define CFG_CHANNEL_BONDING_MODE_MIN           WNI_CFG_CHANNEL_BONDING_MODE_STAMIN
+#define CFG_CHANNEL_BONDING_MODE_MAX           WNI_CFG_CHANNEL_BONDING_MODE_STAMAX
+#define CFG_CHANNEL_BONDING_MODE_DEFAULT       WNI_CFG_CHANNEL_BONDING_MODE_STADEF
+
+/*
+ * <ini>
+ * gScanResultAgeCount - Set scan result age count
+ * @Min: 1
+ * @Max: 100
+ * @Default: 1
+ *
+ * This ini parameter is the number of times a scan
+ * doesn't find it before it is removed from results.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCAN_RESULT_AGE_COUNT_NAME         "gScanResultAgeCount"
+#define CFG_SCAN_RESULT_AGE_COUNT_MIN          (1)
+#define CFG_SCAN_RESULT_AGE_COUNT_MAX          (100)
+#define CFG_SCAN_RESULT_AGE_COUNT_DEFAULT      (1)
+
+/*
+ * <ini>
+ * gNeighborScanTimerPeriod - Set neighbor scan timer period
+ * @Min: 3
+ * @Max: 300
+ * @Default: 200
+ *
+ * This ini is used to set the timer period in secs after
+ * which neighbor scan is trigerred.
+ *
+ * Related: None
+ *
+ * Supported Feature: LFR Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_NAME             "gNeighborScanTimerPeriod"
+#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN              (3)
+#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX              (300)
+#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT          (100)
+
+/*
+ * <ini>
+ * gRoamRestTimeMin - Set min neighbor scan timer period
+ * @Min: 3
+ * @Max: 300
+ * @Default: 200
+ *
+ * This is the min rest time after which firmware will check for traffic
+ * and if there no traffic it will move to a new channel to scan
+ * else it will stay on the home channel till gNeighborScanTimerPeriod time
+ * and then will move to a new channel to scan.
+ *
+ * Related: None
+ *
+ * Supported Feature: LFR Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_NEIGHBOR_SCAN_MIN_TIMER_PERIOD_NAME         "gRoamRestTimeMin"
+#define CFG_NEIGHBOR_SCAN_MIN_TIMER_PERIOD_MIN          (3)
+#define CFG_NEIGHBOR_SCAN_MIN_TIMER_PERIOD_MAX          (300)
+#define CFG_NEIGHBOR_SCAN_MIN_TIMER_PERIOD_DEFAULT      (50)
+
+/*
+ * <ini>
+ * gOpportunisticThresholdDiff - Set oppurtunistic threshold diff
+ * @Min: 0
+ * @Max: 127
+ * @Default: 0
+ *
+ * This ini is used to set opportunistic threshold diff.
+ * This parameter is the RSSI diff above neighbor lookup
+ * threshold, when opportunistic scan should be triggered.
+ * MAX value is chosen so that this type of scan can be
+ * always enabled by user.
+ * MIN value will cause opportunistic scan to be triggered
+ * in neighbor lookup RSSI range.
+ *
+ * Related: None
+ *
+ * Supported Feature: LFR Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_NAME            "gOpportunisticThresholdDiff"
+#define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_MIN             (0)
+#define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_MAX             (127)
+#define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_DEFAULT         (0)
+
+/*
+ * <ini>
+ * gNeighborScanChannelList - Set channels to be scanned
+ * by firmware for LFR scan
+ * @Default: ""
+ *
+ * This ini is used to set the channels to be scanned
+ * by firmware for LFR scan.
+ *
+ * Related: None
+ *
+ * Supported Feature: LFR Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_NEIGHBOR_SCAN_CHAN_LIST_NAME                      "gNeighborScanChannelList"
+#define CFG_NEIGHBOR_SCAN_CHAN_LIST_DEFAULT                   ""
+
+/*
+ * <ini>
+ * gNeighborScanChannelMinTime - Set neighbor scan channel min time
+ * @Min: 10
+ * @Max: 40
+ * @Default: 20
+ *
+ * This ini is used to set the minimum time in secs spent on each
+ * channel in LFR scan inside firmware.
+ *
+ * Related: None
+ *
+ * Supported Feature: LFR Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_NAME                  "gNeighborScanChannelMinTime"
+#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN                   (10)
+#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX                   (40)
+#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT               (20)
+
+/*
+ * <ini>
+ * gNeighborScanChannelMaxTime - Set neighbor scan channel max time
+ * @Min: 3
+ * @Max: 300
+ * @Default: 30
+ *
+ * This ini is used to set the maximum time in secs spent on each
+ * channel in LFR scan inside firmware.
+ *
+ * Related: None
+ *
+ * Supported Feature: LFR Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_NAME                  "gNeighborScanChannelMaxTime"
+#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN                   (3)
+#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX                   (300)
+#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT               (30)
+
+/*
+ * <ini>
+ * gNeighborScanRefreshPeriod - Set neighbor scan refresh period
+ * @Min: 1000
+ * @Max: 60000
+ * @Default: 20000
+ *
+ * This ini is used by firmware to set scan refresh period
+ * in msecs for lfr scan.
+ *
+ * Related: None
+ *
+ * Supported Feature: LFR Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_NAME         "gNeighborScanRefreshPeriod"
+#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN          (1000)
+#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX          (60000)
+#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT      (20000)
+
+/*
+ * <ini>
+ * gEmptyScanRefreshPeriod - Set empty scan refresh period
+ * @Min: 0
+ * @Max: 60000
+ * @Default: 0
+ *
+ * This ini is used by firmware to set scan period in msecs
+ * following empty scan results.
+ *
+ * Related: None
+ *
+ * Supported Feature: LFR Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_EMPTY_SCAN_REFRESH_PERIOD_NAME         "gEmptyScanRefreshPeriod"
+#define CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN          (0)
+#define CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX          (60000)
+#define CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT      (0)
+
+/*
+ * <ini>
+ * gEnableDFSChnlScan - Enable DFS channel scan
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable or disable DFS channel
+ * scan
+ */
+#define CFG_ENABLE_DFS_CHNL_SCAN_NAME              "gEnableDFSChnlScan"
+#define CFG_ENABLE_DFS_CHNL_SCAN_MIN               (0)
+#define CFG_ENABLE_DFS_CHNL_SCAN_MAX               (1)
+#define CFG_ENABLE_DFS_CHNL_SCAN_DEFAULT           (1)
+
+/*
+ * <ini>
+ * gEnableDFSPnoChnlScan - enable dfs channels in PNO scan
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable dfs channels in PNO scan request,
+ * enabling this ini enables driver to include dfs channels in its
+ * PNO scan request
+ * Related: NA
+ *
+ * Supported Feature: DFS, PNO
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_DFS_PNO_CHNL_SCAN_NAME              "gEnableDFSPnoChnlScan"
+#define CFG_ENABLE_DFS_PNO_CHNL_SCAN_MIN               (0)
+#define CFG_ENABLE_DFS_PNO_CHNL_SCAN_MAX               (1)
+#define CFG_ENABLE_DFS_PNO_CHNL_SCAN_DEFAULT           (1)
+
+/*
+ * <ini>
+ * gEnableFirstScan2GOnly - Enable first scan 2G only
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to scan 2G channels only in first scan.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_NAME            "gEnableFirstScan2GOnly"
+#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_MIN        (0)
+#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_MAX        (1)
+#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_DEFAULT    (0)
+
+/*
+ * <ini>
+ * gScanAgingTime - Set scan aging time
+ * @Min: 0
+ * @Max: 200
+ * @Default: 30
+ *
+ * This ini is used to set scan aging timeout value
+ * in secs. For example after 30 secs the bss results
+ * greater than 30secs age will be flushed.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCAN_AGING_PARAM_NAME          "gScanAgingTime"
+#define CFG_SCAN_AGING_PARAM_MIN           (0)
+#define CFG_SCAN_AGING_PARAM_MAX           (200)
+#ifdef QCA_WIFI_NAPIER_EMULATION
+#define CFG_SCAN_AGING_PARAM_DEFAULT       (90)
+#else
+#define CFG_SCAN_AGING_PARAM_DEFAULT       (30)
+#endif
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+/*
+ * <ini>
+ * gPNOScanSupport - Enable or Disable PNO scan
+ * @Min: 1
+ * @Max: 0
+ * @Default: 1
+ *
+ * This ini is used to Enable or Disable PNO scan
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PNO_SCAN_SUPPORT                         "gPNOScanSupport"
+#define CFG_PNO_SCAN_SUPPORT_ENABLE                  (1)
+#define CFG_PNO_SCAN_SUPPORT_DISABLE                 (0)
+#define CFG_PNO_SCAN_SUPPORT_DEFAULT                 (1)
+
+/*
+ * <ini>
+ * gPNOScanTimerRepeatValue - Set PNO scan timer repeat value
+ * @Min: 30
+ * @Max: 0
+ * @Default: 0xffffffff
+ *
+ * This ini is used by firmware to set fast scan max cycles
+ * equal to gPNOScanTimerRepeatValue. Taking power consumption
+ * into account firmware after gPNOScanTimerRepeatValue times
+ * fast_scan_period switches to slow_scan_period.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE              "gPNOScanTimerRepeatValue"
+#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE_DEFAULT      (30)
+#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MIN          (0)
+#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MAX          (0xffffffff)
+
+/*
+ * <ini>
+ * gPNOSlowScanMultiplier - Set PNO slow scan multiplier
+ * @Min: 6
+ * @Max: 0
+ * @Default: 30
+ *
+ * This ini is used by firmware to set slow scan period
+ * as gPNOSlowScanMultiplier times fast_scan_period.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PNO_SLOW_SCAN_MULTIPLIER                 "gPNOSlowScanMultiplier"
+#define CFG_PNO_SLOW_SCAN_MULTIPLIER_DEFAULT         (6)
+#define CFG_PNO_SLOW_SCAN_MULTIPLIER_MIN             (0)
+#define CFG_PNO_SLOW_SCAN_MULTIPLIER_MAX             (30)
+#endif
+
+/*
+ * <ini>
+ * max_scan_count - Set maximum number of scans
+ * @Min: 1
+ * @Max: 8
+ * @Default: 4
+ *
+ * This ini is used to set the maximum number of
+ * scans that host can queue at firmware.
+ * Rome firmware support 8 scan queue size and 4
+ * are reserved for internal scan requests like
+ * roaming. So host can send 4 scan requests.
+ * In iHelium, there is no constraint in number of
+ * scan queue size at firmware but the current use
+ * cases needs support of maximum of 4 scan request
+ * from host.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_MAX_SCAN_COUNT_NAME           "max_scan_count"
+#define CFG_MAX_SCAN_COUNT_MIN            (1)
+#define CFG_MAX_SCAN_COUNT_MAX            (8)
+#define CFG_MAX_SCAN_COUNT_DEFAULT        (4)
+
+/*
+ * <ini>
+ * gPassiveMaxChannelTime - Set max channel time for passive scan
+ * @Min: 0
+ * @Max: 10000
+ * @Default: 110
+ *
+ * This ini is used to set maximum channel time in secs spent in
+ * passive scan
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_PASSIVE_MAX_CHANNEL_TIME_NAME      "gPassiveMaxChannelTime"
+#define CFG_PASSIVE_MAX_CHANNEL_TIME_MIN       (0)
+#define CFG_PASSIVE_MAX_CHANNEL_TIME_MAX       (10000)
+#define CFG_PASSIVE_MAX_CHANNEL_TIME_DEFAULT   (110)
+
+/*
+ * <ini>
+ * gActiveMaxChannelTime - Set max channel time for active scan
+ * @Min: 0
+ * @Max: 10000
+ * @Default: 40
+ *
+ * This ini is used to set maximum channel time in secs spent in
+ * active scan
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTIVE_MAX_CHANNEL_TIME_NAME       "gActiveMaxChannelTime"
+#define CFG_ACTIVE_MAX_CHANNEL_TIME_MIN        (0)
+#define CFG_ACTIVE_MAX_CHANNEL_TIME_MAX        (10000)
+#define CFG_ACTIVE_MAX_CHANNEL_TIME_DEFAULT    (40)
+
+/*
+ * <ini>
+ * gScanNumProbes - Set the number of probes on each channel for active scan
+ * @Min: 0
+ * @Max: 20
+ * @Default: 0
+ *
+ * This ini is used to set number of probes on each channel for
+ * active scan
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCAN_NUM_PROBES_NAME       "gScanNumProbes"
+#define CFG_SCAN_NUM_PROBES_MIN        (0)
+#define CFG_SCAN_NUM_PROBES_MAX        (20)
+#define CFG_SCAN_NUM_PROBES_DEFAULT    (0)
+
+/*
+ * <ini>
+ * gScanProbeRepeatTime - Set the probe repeat time on each channel for active scan
+ * @Min: 0
+ * @Max: 30
+ * @Default: 0
+ *
+ * This ini is used to set probe repeat time on each channel for
+ * active scan
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SCAN_PROBE_REPEAT_TIME_NAME       "gScanProbeRepeatTime"
+#define CFG_SCAN_PROBE_REPEAT_TIME_MIN        (0)
+#define CFG_SCAN_PROBE_REPEAT_TIME_MAX        (30)
+#define CFG_SCAN_PROBE_REPEAT_TIME_DEFAULT    (0)
+
+/*
+ * <ini>
+ * gChPredictionFullScanMs - Set periodic timer for channel
+ * prediction
+ * @Min: 3000
+ * @Max: 0x7fffffff
+ * @Default: 60000
+ *
+ * This ini is used to set the periodic timer upon which
+ * a full scan needs to be triggered when PNO channel
+ * prediction feature is enabled. This parameter is intended
+ * to tweak the internal algortihm for experiments.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_NAME      "gChPredictionFullScanMs"
+#define CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_MIN       (30000)
+#define CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_MAX       (0x7fffffff)
+#define CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_DEFAULT   (60000)
+
+/*
+ * <ini>
+ * gbug_report_for_scan_results - Enable bug report
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to create bug report in
+ * case of nil scan results.
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_CREATE_BUG_REPORT_FOR_SCAN       "gbug_report_for_scan_results"
+#define CFG_CREATE_BUG_REPORT_FOR_SCAN_DISABLE    (0)
+#define CFG_CREATE_BUG_REPORT_FOR_SCAN_ENABLE     (1)
+#define CFG_CREATE_BUG_REPORT_FOR_SCAN_DEFAULT    (0)
+
+/*
+ * <ini>
+ * hostscan_adaptive_dwell_mode - Enable adaptive dwell mode
+ * during host scan with conneciton
+ * @Min: 0
+ * @Max: 4
+ * @Default: 2
+ *
+ * This ini will set the algo used in dwell time optimization
+ * during host scan with connection.
+ * See enum scan_dwelltime_adaptive_mode.
+ * Acceptable values for this:
+ * 0: Default (Use firmware default mode)
+ * 1: Conservative optimization
+ * 2: Moderate optimization
+ * 3: Aggressive optimization
+ * 4: Static
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_NAME        "hostscan_adaptive_dwell_mode"
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_MIN         (0)
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_MAX         (4)
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_DEFAULT     (2)
+
+/*
+ * <ini>
+ * hostscan_adaptive_dwell_mode_no_conn - Enable adaptive dwell mode
+ * during host scan without connection
+ * @Min: 0
+ * @Max: 4
+ * @Default: 1
+ *
+ * This ini will set the algo used in dwell time optimization
+ * during host scan without connection.
+ * See enum scan_dwelltime_adaptive_mode.
+ * Acceptable values for this:
+ * 0: Default (Use firmware default mode)
+ * 1: Conservative optimization
+ * 2: Moderate optimization
+ * 3: Aggressive optimization
+ * 4: Static
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_NC_NAME    "hostscan_adaptive_dwell_mode_no_conn"
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_NC_MIN     (0)
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_NC_MAX     (4)
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_NC_DEFAULT (1)
+
+/*
+ * <ini>
+ * extscan_adaptive_dwell_mode - Enable adaptive dwell mode
+ * during ext scan
+ * @Min: 0
+ * @Max: 4
+ * @Default: 1
+ *
+ * This ini will set the algo used in dwell time optimization
+ * during ext scan. see enum scan_dwelltime_adaptive_mode.
+ * Acceptable values for this:
+ * 0: Default (Use firmware default mode)
+ * 1: Conservative optimization
+ * 2: Moderate optimization
+ * 3: Aggressive optimization
+ * 4: Static
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_NAME     "extscan_adaptive_dwell_mode"
+#define CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_MIN      (0)
+#define CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_MAX      (4)
+#define CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_DEFAULT  (1)
+
+/*
+ * <ini>
+ * pnoscan_adaptive_dwell_mode - Enable adaptive dwell mode
+ * during pno scan
+ * @Min: 0
+ * @Max: 4
+ * @Default: 1
+ *
+ * This ini will set the algo used in dwell time optimization
+ * during pno scan. see enum scan_dwelltime_adaptive_mode.
+ * Acceptable values for this:
+ * 0: Default (Use firmware default mode)
+ * 1: Conservative optimization
+ * 2: Moderate optimization
+ * 3: Aggressive optimization
+ * 4: Static
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_NAME     "pnoscan_adaptive_dwell_mode"
+#define CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_MIN      (0)
+#define CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_MAX      (4)
+#define CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_DEFAULT  (1)
+
+/*
+ * <ini>
+ * adaptive_dwell_mode_enabled - Enable adaptive dwell mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This parameter will globally disable/enable the adaptive dwell config.
+ * Following parameters will set different values of attributes for dwell
+ * time optimization thus reducing total scan time.
+ * Acceptable values for this:
+ * 0: Config is disabled
+ * 1: Config is enabled
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ADAPTIVE_DWELL_MODE_ENABLED_NAME      "adaptive_dwell_mode_enabled"
+#define CFG_ADAPTIVE_DWELL_MODE_ENABLED_MIN       (0)
+#define CFG_ADAPTIVE_DWELL_MODE_ENABLED_MAX       (1)
+#define CFG_ADAPTIVE_DWELL_MODE_ENABLED_DEFAULT   (1)
+
+/*
+ * <ini>
+ * global_adapt_dwelltime_mode - Set default adaptive mode
+ * @Min: 0
+ * @Max: 4
+ * @Default: 0
+ *
+ * This parameter will set default adaptive mode, will be used if any of the
+ * scan dwell mode is set to default.
+ * For uses : see enum scan_dwelltime_adaptive_mode
+ *
+ * Related: None
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_GLOBAL_ADAPTIVE_DWELL_MODE_NAME       "global_adapt_dwelltime_mode"
+#define CFG_GLOBAL_ADAPTIVE_DWELL_MODE_MIN        (0)
+#define CFG_GLOBAL_ADAPTIVE_DWELL_MODE_MAX        (4)
+#define CFG_GLOBAL_ADAPTIVE_DWELL_MODE_DEFAULT    (0)
+
+/*
+ * <ini>
+ * gRssiCatGap - Set Rssi CatGap
+ * @Min: 5
+ * @Max: 100
+ * @Default: 5
+ *
+ * This ini is used to set default RssiCatGap
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_RSSI_CATEGORY_GAP_NAME             "gRssiCatGap"
+#define CFG_RSSI_CATEGORY_GAP_MIN              (5)
+#define CFG_RSSI_CATEGORY_GAP_MAX              (100)
+#define CFG_RSSI_CATEGORY_GAP_DEFAULT          (5)
+
+/*
+ * <ini>
+ * gRoamPrefer5GHz - Prefer roaming to 5GHz Bss
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to inform FW to prefer roaming to 5GHz BSS
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_PREFER_5GHZ                  "gRoamPrefer5GHz"
+#define CFG_ROAM_PREFER_5GHZ_MIN              (0)
+#define CFG_ROAM_PREFER_5GHZ_MAX              (1)
+#define CFG_ROAM_PREFER_5GHZ_DEFAULT          (1)
+
+/*
+ * <ini>
+ * gRoamIntraBand - Prefer roaming within Band
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to inform FW to prefer roaming within band
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_INTRA_BAND                   "gRoamIntraBand"
+#define CFG_ROAM_INTRA_BAND_MIN               (0)
+#define CFG_ROAM_INTRA_BAND_MAX               (1)
+#define CFG_ROAM_INTRA_BAND_DEFAULT           (0)
+
+/*
+ * <ini>
+ * FastRoamEnabled - Enable fast roaming
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to inform FW to enable fast roaming
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_LFR_FEATURE_ENABLED_NAME                        "FastRoamEnabled"
+#define CFG_LFR_FEATURE_ENABLED_MIN                         (0)
+#define CFG_LFR_FEATURE_ENABLED_MAX                         (1)
+#define CFG_LFR_FEATURE_ENABLED_DEFAULT                     (0)
+
+/*
+ * <ini>
+ * FastTransitionEnabled - Enable fast transition in case of 11r and ese.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to turn ON/OFF the whole neighbor roam, pre-auth, reassoc.
+ * With this turned OFF 11r will completely not work. For 11r this flag has to
+ * be ON. For ESE fastroam will not work.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_FAST_TRANSITION_ENABLED_NAME                    "FastTransitionEnabled"
+#define CFG_FAST_TRANSITION_ENABLED_NAME_MIN                (0)
+#define CFG_FAST_TRANSITION_ENABLED_NAME_MAX                (1)
+#define CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT            (1)
+
+/*
+ * <ini>
+ * RoamRssiDiff - Enable roam based on rssi
+ * @Min: 0
+ * @Max: 30
+ * @Default: 5
+ *
+ * This INI is used to decide whether to Roam or not based on RSSI. AP1 is the
+ * currently associated AP and AP2 is chosen for roaming. The Roaming will
+ * happen only if AP2 has better Signal Quality and it has a RSSI better than
+ * AP2. RoamRssiDiff is the number of units (typically measured in dB) AP2
+ * is better than AP1.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_RSSI_DIFF_NAME                             "RoamRssiDiff"
+#define CFG_ROAM_RSSI_DIFF_MIN                              (0)
+#define CFG_ROAM_RSSI_DIFF_MAX                              (30)
+#define CFG_ROAM_RSSI_DIFF_DEFAULT                          (5)
+
+/*
+ * <ini>
+ * gRoamScanNProbes - Sets the number of probes to be sent for firmware roaming
+ * @Min: 1
+ * @Max: 10
+ * @Default: 2
+ *
+ * This INI is used to set the maximum number of probes the firmware can send
+ * for firmware internal roaming cases.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_SCAN_N_PROBES                              "gRoamScanNProbes"
+#define CFG_ROAM_SCAN_N_PROBES_MIN                          (1)
+#define CFG_ROAM_SCAN_N_PROBES_MAX                          (10)
+#define CFG_ROAM_SCAN_N_PROBES_DEFAULT                      (2)
+
+/*
+ * <ini>
+ * gRoamScanHomeAwayTime - Sets the Home Away Time to firmware
+ * @Min: 0
+ * @Max: 300
+ * @Default: 0
+ *
+ * Home Away Time should be at least equal to (gNeighborScanChannelMaxTime
+ * + (2*RFS)), where RFS is the RF Switching time(3). It is twice RFS
+ * to consider the time to go off channel and return to the home channel.
+ *
+ * Related: gNeighborScanChannelMaxTime
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_SCAN_HOME_AWAY_TIME                        "gRoamScanHomeAwayTime"
+#define CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN                    (0)
+#define CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX                    (300)
+#define CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT                (0)
+
+/*
+ * <ini>
+ * OkcEnabled - Enable OKC(Oppurtunistic Key Caching)
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This INI is used to enable OKC feature
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OKC_FEATURE_ENABLED_NAME                       "OkcEnabled"
+#define CFG_OKC_FEATURE_ENABLED_MIN                        (0)
+#define CFG_OKC_FEATURE_ENABLED_MAX                        (1)
+#define CFG_OKC_FEATURE_ENABLED_DEFAULT                    (1)
+
+/*
+ * <ini>
+ * gRoamScanOffloadEnabled - Enable Roam Scan Offload
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This INI is used to enable Roam Scan Offload in firmware
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_SCAN_OFFLOAD_ENABLED                       "gRoamScanOffloadEnabled"
+#define CFG_ROAM_SCAN_OFFLOAD_ENABLED_MIN                   (0)
+#define CFG_ROAM_SCAN_OFFLOAD_ENABLED_MAX                   (1)
+#define CFG_ROAM_SCAN_OFFLOAD_ENABLED_DEFAULT               (1)
+
+/*
+ * <ini>
+ * gRoamRescanRssiDiff - Sets RSSI for Scan trigger in firmware
+ * @Min: 0
+ * @Max: 100
+ * @Default: 5
+ *
+ * This INI is the drop in RSSI value that will trigger a precautionary
+ * scan by firmware. Max value is chosen in such a way that this type
+ * of scan can be disabled by user.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_RESCAN_RSSI_DIFF_NAME                  "gRoamRescanRssiDiff"
+#define CFG_ROAM_RESCAN_RSSI_DIFF_MIN                   (0)
+#define CFG_ROAM_RESCAN_RSSI_DIFF_MAX                   (100)
+#define CFG_ROAM_RESCAN_RSSI_DIFF_DEFAULT               (5)
+
+/*
+ * <ini>
+ * gForce1x1Exception - force 1x1 when connecting to certain peer
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This INI when enabled will force 1x1 connection with certain peer.
+ *
+ *
+ * Related: None
+ *
+ * Supported Feature: connection
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_FORCE_1X1_NAME      "gForce1x1Exception"
+#define CFG_FORCE_1X1_MIN       (0)
+#define CFG_FORCE_1X1_MAX       (1)
+#define CFG_FORCE_1X1_DEFAULT   (1)
+
+/*
+ * <ini>
+ * gEnableFastRoamInConcurrency - Enable LFR roaming on STA during concurrency
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This INI is used to enable Legacy fast roaming(LFR) on STA link during
+ * concurrent sessions.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY          "gEnableFastRoamInConcurrency"
+#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MIN      (0)
+#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MAX      (1)
+#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_DEFAULT  (1)
+
+/*
+ * <ini>
+ * gRoamScanHiRssiMaxCount - Sets 5GHz maximum scan count
+ * @Min: 0
+ * @Max: 10
+ * @Default: 3
+ *
+ * This INI is used to set maximum scan count in 5GHz
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_SCAN_HI_RSSI_MAXCOUNT_NAME         "gRoamScanHiRssiMaxCount"
+#define CFG_ROAM_SCAN_HI_RSSI_MAXCOUNT_MIN          (0)
+#define CFG_ROAM_SCAN_HI_RSSI_MAXCOUNT_MAX          (10)
+#define CFG_ROAM_SCAN_HI_RSSI_MAXCOUNT_DEFAULT      (3)
+
+/*
+ * <ini>
+ * gRoamScanHiRssiDelta - Sets RSSI Delta for scan trigger
+ * @Min: 0
+ * @Max: 16
+ * @Default: 10
+ *
+ * This INI is used to set change in RSSI at which scan is triggered
+ * in 5GHz.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_SCAN_HI_RSSI_DELTA_NAME           "gRoamScanHiRssiDelta"
+#define CFG_ROAM_SCAN_HI_RSSI_DELTA_MIN            (0)
+#define CFG_ROAM_SCAN_HI_RSSI_DELTA_MAX            (16)
+#define CFG_ROAM_SCAN_HI_RSSI_DELTA_DEFAULT        (10)
+
+/*
+ * <ini>
+ * gRoamScanHiRssiDelay - Sets minimum delay between 5GHz scans
+ * @Min: 5000
+ * @Max: 0x7fffffff
+ * @Default: 15000
+ *
+ * This INI is used to set the minimum delay between 5GHz scans.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_SCAN_HI_RSSI_DELAY_NAME            "gRoamScanHiRssiDelay"
+#define CFG_ROAM_SCAN_HI_RSSI_DELAY_MIN             (5000)
+#define CFG_ROAM_SCAN_HI_RSSI_DELAY_MAX             (0x7fffffff)
+#define CFG_ROAM_SCAN_HI_RSSI_DELAY_DEFAULT         (15000)
+
+/*
+ * <ini>
+ * gRoamScanHiRssiUpperBound - Sets upper bound after which 5GHz scan
+ * @Min: -66
+ * @Max: 0
+ * @Default: -30
+ *
+ * This INI is used to set the RSSI upper bound above which the 5GHz scan
+ * will not be performed.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_SCAN_HI_RSSI_UB_NAME              "gRoamScanHiRssiUpperBound"
+#define CFG_ROAM_SCAN_HI_RSSI_UB_MIN               (-66)
+#define CFG_ROAM_SCAN_HI_RSSI_UB_MAX               (0)
+#define CFG_ROAM_SCAN_HI_RSSI_UB_DEFAULT           (-30)
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+/*
+ * <ini>
+ * gLFRSubnetDetectionEnable - Enable LFR3 subnet detection
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * Enable IP subnet detection during legacy fast roming version 3. Legacy fast
+ * roaming could roam across IP subnets without host processors' knowledge.
+ * This feature enables firmware to wake up the host processor if it
+ * successfully determines change in the IP subnet. Change in IP subnet could
+ * potentially cause disruption in IP connnectivity if IP address is not
+ * refreshed.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_LFR_SUBNET_DETECTION    "gLFRSubnetDetectionEnable"
+#define CFG_ENABLE_LFR_SUBNET_MIN          (0)
+#define CFG_ENABLE_LFR_SUBNET_MAX          (1)
+#define CFG_ENABLE_LFR_SUBNET_DEFAULT      (1)
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+
+/*
+ * <ini>
+ * enable_ftopen - enable/disable FT open feature
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This INI is used to enable/disable FT open feature
+*
+* Related: None
+*
+* Supported Feature: Roaming
+*
+* Usage: External
+*
+* </ini>
+*/
+#define CFG_ROAM_FT_OPEN_ENABLE_NAME                "enable_ftopen"
+#define CFG_ROAM_FT_OPEN_ENABLE_MIN                 (0)
+#define CFG_ROAM_FT_OPEN_ENABLE_MAX                 (1)
+#define CFG_ROAM_FT_OPEN_ENABLE_DEFAULT             (1)
+
+/*
+ * <ini>
+ * min_delay_btw_roam_scans - Min duration (in sec) allowed btw two
+ * consecutive roam scans
+ * @Min: 0
+ * @Max: 60
+ * @Default: 10
+ *
+ * Roam scan is not allowed if duration between two consecutive
+ * roam scans is less than this time.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_MIN_DELAY_BTW_ROAM_SCAN_NAME    "min_delay_btw_roam_scans"
+#define CFG_MIN_DELAY_BTW_ROAM_SCAN_MIN     (0)
+#define CFG_MIN_DELAY_BTW_ROAM_SCAN_MAX     (60)
+#define CFG_MIN_DELAY_BTW_ROAM_SCAN_DEFAULT (10)
+
+/*
+ * <ini>
+ * roam_trigger_reason_bitmask - Contains roam_trigger_reasons
+ * @Min: 0
+ * @Max: 0xFFFFFFFF
+ * @Default: 0xDA
+ *
+ * Bitmask containing roam_trigger_reasons for which
+ * min_delay_btw_roam_scans constraint should be applied.
+ * Currently supported bit positions are as follows:
+ * Bit 0 is reserved in the firmware.
+ * WMI_ROAM_TRIGGER_REASON_PER - 1
+ * WMI_ROAM_TRIGGER_REASON_BMISS - 2
+ * WMI_ROAM_TRIGGER_REASON_LOW_RSSI - 3
+ * WMI_ROAM_TRIGGER_REASON_HIGH_RSSI - 4
+ * WMI_ROAM_TRIGGER_REASON_PERIODIC - 5
+ * WMI_ROAM_TRIGGER_REASON_MAWC - 6
+ * WMI_ROAM_TRIGGER_REASON_DENSE - 7
+ * WMI_ROAM_TRIGGER_REASON_BACKGROUND - 8
+ * WMI_ROAM_TRIGGER_REASON_FORCED - 9
+ * WMI_ROAM_TRIGGER_REASON_BTM - 10
+ * WMI_ROAM_TRIGGER_REASON_UNIT_TEST - 11
+ * WMI_ROAM_TRIGGER_REASON_MAX - 12
+ *
+ * For Ex: 0xDA (PER, LOW_RSSI, HIGH_RSSI, MAWC, DENSE)
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_NAME "roam_trigger_reason_bitmask"
+#define CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_MIN     (0)
+#define CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_MAX     (0xFFFFFFFF)
+#define CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_DEFAULT (0xDA)
+
+/*
+ * <ini>
+ * roam_bad_rssi_thresh_offset_2g - RSSI threshold offset for 2G to 5G roam
+ * @Min: 0
+ * @Max: 86
+ * @Default: 40
+ *
+ * If the DUT is connected to an AP with weak signal in 2G band, then the
+ * bad RSSI offset for 2g would be used as offset from the bad RSSI
+ * threshold configured and then use the resulting rssi for an opportunity
+ * to use the scan results from other scan clients and try to roam to
+ * 5G Band ONLY if there is a better AP available in the environment.
+ *
+ * For example if the roam_bg_scan_bad_rssi_thresh is -76 and
+ * roam_bad_rssi_thresh_offset_2g is 40 then the difference of -36 would be
+ * used as a trigger to roam to a 5G AP if DUT initially connected to a 2G AP
+ *
+ * Related: roam_bg_scan_bad_rssi_thresh
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_NAME "roam_bad_rssi_thresh_offset_2g"
+#define CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_MIN     (0)
+#define CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_MAX     (86)
+#define CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_DEFAULT (40)
+
+/*
+ * <ini>
+ * ho_delay_for_rx - Delay Hand-off (In msec) by this duration to receive
+ * pending rx frames from current BSS
+ * @Min: 0
+ * @Max: 200
+ * @Default: 0
+ *
+ * For LFR 3.0 roaming scenario, once roam candidate is found, firmware
+ * waits for minimum this much duration to receive pending rx frames from
+ * current BSS before switching to new channel for handoff to new AP.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_HO_DELAY_FOR_RX_NAME    "ho_delay_for_rx"
+#define CFG_ROAM_HO_DELAY_FOR_RX_MIN     (0)
+#define CFG_ROAM_HO_DELAY_FOR_RX_MAX     (200)
+#define CFG_ROAM_HO_DELAY_FOR_RX_DEFAULT (0)
+
+/*
+ * <ini>
+ * roam_force_rssi_trigger - To force RSSI trigger
+ * irrespective of channel list type
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set roam scan mode
+ * WMI_ROAM_SCAN_MODE_RSSI_CHANGE, irrespective of whether
+ * channel list type is CHANNEL_LIST_STATIC or not
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ROAM_FORCE_RSSI_TRIGGER_NAME  "roam_force_rssi_trigger"
+#define CFG_ROAM_FORCE_RSSI_TRIGGER_MIN     (0)
+#define CFG_ROAM_FORCE_RSSI_TRIGGER_MAX     (1)
+#define CFG_ROAM_FORCE_RSSI_TRIGGER_DEFAULT (1)
+
+/*
+ * <ini>
+ * gIbssBssid - Default IBSS BSSID if BSSID is not provided by supplicant
+ * @Min: "000000000000"
+ * @Max: "ffffffffffff"
+ * @Default: "000AF5040506"
+ *
+ * This ini is used to set Default IBSS BSSID if BSSID
+ * is not provided by supplicant and Coalesing is disabled
+ *
+ * Related: Only applicable if gCoalesingInIBSS is 0
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IBSS_BSSID_NAME                    "gIbssBssid"
+#define CFG_IBSS_BSSID_MIN                     "000000000000"
+#define CFG_IBSS_BSSID_MAX                     "ffffffffffff"
+#define CFG_IBSS_BSSID_DEFAULT                 "000AF5040506"
+
+/*
+ * <ini>
+ * gAdHocChannel5G - Default 5Ghz IBSS channel if channel is not
+ * provided by supplicant.
+ * @Min: 36
+ * @Max: 165
+ * @Default: 44
+ *
+ * This ini is used to set default 5Ghz IBSS channel
+ * if channel is not provided by supplicant and band is 5Ghz
+ *
+ * Related: None
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_NAME          "gAdHocChannel5G"
+#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_MIN           (36)
+#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_MAX           (165)
+#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_DEFAULT       (44)
+
+/*
+ * <ini>
+ * gAdHocChannel24G - Default 2.4Ghz IBSS channel if channel is not
+ * provided by supplicant.
+ * @Min: 1
+ * @Max: 14
+ * @Default: 6
+ *
+ * This ini is used to set default 2.4Ghz IBSS channel
+ * if channel is not provided by supplicant and band is 2.4Ghz
+ *
+ * Related: None
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_NAME         "gAdHocChannel24G"
+#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_MIN          (1)
+#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_MAX          (14)
+#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_DEFAULT      (6)
+
+/*
+ * <ini>
+ * gCoalesingInIBSS - If IBSS coalesing is enabled.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set IBSS coalesing
+ *
+ * Related: None
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_COALESING_IN_IBSS_NAME                "gCoalesingInIBSS"
+#define CFG_COALESING_IN_IBSS_MIN                 (0)
+#define CFG_COALESING_IN_IBSS_MAX                 (1)
+#define CFG_COALESING_IN_IBSS_DEFAULT             (0)   /* disabled */
+
+/*
+ * <ini>
+ * gIbssATIMWinSize - Set IBSS ATIM window size
+ * @Min: 0
+ * @Max: 50
+ * @Default: 0
+ *
+ * This ini is used to set IBSS ATIM window size
+ *
+ * Related: None
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IBSS_ATIM_WIN_SIZE_NAME                "gIbssATIMWinSize"
+#define CFG_IBSS_ATIM_WIN_SIZE_MIN                 (0)
+#define CFG_IBSS_ATIM_WIN_SIZE_MAX                 (50)
+#define CFG_IBSS_ATIM_WIN_SIZE_DEFAULT             (0)
+
+
+/*
+ * <ini>
+ * gIbssIsPowerSaveAllowed - Indicates if IBSS Power Save is
+ * supported or not
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to Indicates if IBSS Power Save is
+ * supported or not. When not allowed,IBSS station has
+ * to stay awake all the time and should never set PM=1
+ * in its transmitted frames.
+ *
+ * Related: valid only when gIbssATIMWinSize is non-zero
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IBSS_IS_POWER_SAVE_ALLOWED_NAME        "gIbssIsPowerSaveAllowed"
+#define CFG_IBSS_IS_POWER_SAVE_ALLOWED_MIN         (0)
+#define CFG_IBSS_IS_POWER_SAVE_ALLOWED_MAX         (1)
+#define CFG_IBSS_IS_POWER_SAVE_ALLOWED_DEFAULT     (1)
+
+/*
+ * <ini>
+ * gIbssIsPowerCollapseAllowed - Indicates if IBSS Power Collapse
+ * is allowed
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to indicates if IBSS Power Collapse
+ * is allowed
+ *
+ * Related: None
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_NAME    "gIbssIsPowerCollapseAllowed"
+#define CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_MIN     (0)
+#define CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_MAX     (1)
+#define CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_DEFAULT (1)
+
+/*
+ * <ini>
+ * gIbssAwakeOnTxRx - Indicates whether IBSS station
+ * can exit power save mode and enter power active
+ * state whenever there is a TX/RX activity.
+ *
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to ndicates whether IBSS station
+ * can exit power save mode and enter power active
+ * state whenever there is a TX/RX activity.
+ *
+ * Related: None
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IBSS_AWAKE_ON_TX_RX_NAME               "gIbssAwakeOnTxRx"
+#define CFG_IBSS_AWAKE_ON_TX_RX_MIN                (0)
+#define CFG_IBSS_AWAKE_ON_TX_RX_MAX                (1)
+#define CFG_IBSS_AWAKE_ON_TX_RX_DEFAULT            (0)
+
+/*
+ * <ini>
+ * gIbssInactivityTime - Indicates the data
+ * inactivity time in number of beacon intervals
+ * after which IBSS station re-inters power save
+ *
+ * @Min: 1
+ * @Max: 10
+ * @Default: 1
+ *
+ * In IBSS mode if Awake on TX/RX activity is enabled
+ * Ibss Inactivity parameter indicates the data
+ * inactivity time in number of beacon intervals
+ * after which IBSS station re-inters power save
+ * by sending Null frame with PM=1
+ *
+ * Related: Aplicable if gIbssAwakeOnTxRx is enabled
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IBSS_INACTIVITY_TIME_NAME              "gIbssInactivityTime"
+#define CFG_IBSS_INACTIVITY_TIME_MIN               (1)
+#define CFG_IBSS_INACTIVITY_TIME_MAX               (10)
+#define CFG_IBSS_INACTIVITY_TIME_DEFAULT           (1)
+
+/*
+ * <ini>
+ * gIbssTxSpEndInactivityTime - Indicates the time after
+ * which TX Service Period is terminated by
+ * sending a Qos Null frame with EOSP.
+ *
+ * @Min: 0
+ * @Max: 100
+ * @Default: 0
+ *
+ * In IBSS mode Tx Service Period Inactivity
+ * time in msecs indicates the time after
+ * which TX Service Period is terminated by
+ * sending a Qos Null frame with EOSP.
+ * If value is 0, TX SP is terminated with the
+ * last buffered packet itself instead of waiting
+ * for the inactivity.
+ *
+ * Related: None
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IBSS_TXSP_END_INACTIVITY_NAME          "gIbssTxSpEndInactivityTime"
+#define CFG_IBSS_TXSP_END_INACTIVITY_MIN           (0)
+#define CFG_IBSS_TXSP_END_INACTIVITY_MAX           (100)
+#define CFG_IBSS_TXSP_END_INACTIVITY_DEFAULT       (0)
+
+/*
+ * <ini>
+ * gIbssPsWarmupTime - PS-supporting device
+ * does not enter protocol sleep state during first
+ * gIbssPsWarmupTime seconds.
+ *
+ * @Min: 0
+ * @Max: 65535
+ * @Default: 0
+ *
+ * When IBSS network is initialized, PS-supporting device
+ * does not enter protocol sleep state during first
+ * gIbssPsWarmupTime seconds.
+ *
+ * Related: valid if gIbssIsPowerSaveAllowed is set
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IBSS_PS_WARMUP_TIME_NAME               "gIbssPsWarmupTime"
+#define CFG_IBSS_PS_WARMUP_TIME_MIN                (0)
+/* Allow unsigned Int Max for now */
+#define CFG_IBSS_PS_WARMUP_TIME_MAX                (65535)
+#define CFG_IBSS_PS_WARMUP_TIME_DEFAULT            (0)
+
+/*
+ * <ini>
+ * gIbssPs1RxChainInAtim - IBSS Power Save Enable/Disable 1 RX
+ * chain usage during the ATIM window
+ *
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * IBSS Power Save Enable/Disable 1 RX
+ * chain usage during the ATIM window
+ *
+ * Related: Depend on gIbssIsPowerSaveAllowed
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_NAME    "gIbssPs1RxChainInAtim"
+#define CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_MIN     (0)
+#define CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_MAX     (1)
+#define CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_DEFAULT (0)
+
+/*
+ * <ini>
+ * wlm_latency_enable - WLM latency Enable
+ *
+ * @min: 0
+ * @max: 1
+ * @default: 0
+ *
+ * 0 - disable
+ * 1 - enable
+ *
+ * </ini>
+ */
+#define CFG_LATENCY_ENABLE_NAME    "wlm_latency_enable"
+#define CFG_LATENCY_ENABLE_MIN     (0)
+#define CFG_LATENCY_ENABLE_MAX     (1)
+#define CFG_LATENCY_ENABLE_DEFAULT (0)
+
+/*
+ * <ini>
+ * wlm_latency_level - WLM latency level
+ * Define 4 latency level to gain latency
+ *
+ * @min: 0
+ * @max: 3
+ * @defalut: 0
+ *
+ * 0 - normal
+ * 1 - moderate
+ * 2 - low
+ * 3 - ultralow
+ *
+ * </ini>
+ */
+#define CFG_LATENCY_LEVEL_NAME    "wlm_latency_level"
+#define CFG_LATENCY_LEVEL_MIN     (0)
+#define CFG_LATENCY_LEVEL_MAX     (3)
+#define CFG_LATENCY_LEVEL_DEFAULT (0)
+
+/*
+ * <ini>
+ * wlm_latency_flags_normal - WLM flags setting for normal level
+ *
+ * @min: 0x0
+ * @max: 0xffffffff
+ * @defalut: 0x0
+ *
+ * |31  12|  11  |  10  |9    8|7    6|5    4|3    2|  1  |  0  |
+ * +------+------+------+------+------+------+------+-----+-----+
+ * | RSVD | SSLP | CSLP | RSVD | Roam | RSVD | DWLT | DFS | SUP |
+ * +------+-------------+-------------+-------------------------+
+ * |  WAL |      PS     |     Roam    |         Scan            |
+ *
+ * bit 0: Avoid scan request from HLOS if setting
+ * bit 1: Skip DFS channel SCAN if setting
+ * bit 2-3: Define policy of dwell time/duration for each foreign channel
+ *     (b2 b3)
+ *     (0  0 ): Default scan dwell time
+ *     (0  1 ): Reserve
+ *     (1  0 ): Shrink off channel dwell time
+ *     (1  1 ): Reserve
+ * bit 4-5: Reserve for scan
+ * bit 6-7: Define roaming policy
+ *     (b6 b7)
+ *     (0  0 ): Default roaming behavior, allow roaming in all scenarios
+ *     (0  1 ): Disallow all roaming
+ *     (1  0 ): Allow roaming when final bmissed
+ *     (1  1 ): Reserve
+ * bit 8-9: Reserve for roaming
+ * bit 10: Disable css power collapse if setting
+ * bit 11: Disable sys sleep if setting
+ * bit 12-31: Reserve for future useage
+ *
+ * </ini>
+ */
+#define CFG_LATENCY_FLAGS_NORMAL_NAME    "wlm_latency_flags_normal"
+#define CFG_LATENCY_FLAGS_NORMAL_MIN     (0x0)
+#define CFG_LATENCY_FLAGS_NORMAL_MAX     (0xffffffff)
+#define CFG_LATENCY_FLAGS_NORMAL_DEFAULT (0x0)
+
+/*
+ * <ini>
+ * wlm_latency_flags_moderate - WLM flags setting for moderate level
+ *
+ * @min: 0x0
+ * @max: 0xffffffff
+ * @defalut: 0x8
+ *
+ * |31  12|  11  |  10  |9    8|7    6|5    4|3    2|  1  |  0  |
+ * +------+------+------+------+------+------+------+-----+-----+
+ * | RSVD | SSLP | CSLP | RSVD | Roam | RSVD | DWLT | DFS | SUP |
+ * +------+-------------+-------------+-------------------------+
+ * |  WAL |      PS     |     Roam    |         Scan            |
+ *
+ * bit 0: Avoid scan request from HLOS if setting
+ * bit 1: Skip DFS channel SCAN if setting
+ * bit 2-3: Define policy of dwell time/duration for each foreign channel
+ *     (b2 b3)
+ *     (0  0 ): Default scan dwell time
+ *     (0  1 ): Reserve
+ *     (1  0 ): Shrink off channel dwell time
+ *     (1  1 ): Reserve
+ * bit 4-5: Reserve for scan
+ * bit 6-7: Define roaming policy
+ *     (b6 b7)
+ *     (0  0 ): Default roaming behavior, allow roaming in all scenarios
+ *     (0  1 ): Disallow all roaming
+ *     (1  0 ): Allow roaming when final bmissed
+ *     (1  1 ): Reserve
+ * bit 8-9: Reserve for roaming
+ * bit 10: Disable css power collapse if setting
+ * bit 11: Disable sys sleep if setting
+ * bit 12-31: Reserve for future useage
+ *
+ * </ini>
+ */
+#define CFG_LATENCY_FLAGS_MODERATE_NAME    "wlm_latency_flags_moderate"
+#define CFG_LATENCY_FLAGS_MODERATE_MIN     (0x0)
+#define CFG_LATENCY_FLAGS_MODERATE_MAX     (0xffffffff)
+#define CFG_LATENCY_FLAGS_MODERATE_DEFAULT (0x8)
+
+/*
+ * <ini>
+ * wlm_latency_flags_low - WLM flags setting for low level
+ *
+ * @min: 0x0
+ * @max: 0xffffffff
+ * @defalut: 0xa
+ *
+ * |31  12|  11  |  10  |9    8|7    6|5    4|3    2|  1  |  0  |
+ * +------+------+------+------+------+------+------+-----+-----+
+ * | RSVD | SSLP | CSLP | RSVD | Roam | RSVD | DWLT | DFS | SUP |
+ * +------+-------------+-------------+-------------------------+
+ * |  WAL |      PS     |     Roam    |         Scan            |
+ *
+ * bit 0: Avoid scan request from HLOS if setting
+ * bit 1: Skip DFS channel SCAN if setting
+ * bit 2-3: Define policy of dwell time/duration for each foreign channel
+ *     (b2 b3)
+ *     (0  0 ): Default scan dwell time
+ *     (0  1 ): Reserve
+ *     (1  0 ): Shrink off channel dwell time
+ *     (1  1 ): Reserve
+ * bit 4-5: Reserve for scan
+ * bit 6-7: Define roaming policy
+ *     (b6 b7)
+ *     (0  0 ): Default roaming behavior, allow roaming in all scenarios
+ *     (0  1 ): Disallow all roaming
+ *     (1  0 ): Allow roaming when final bmissed
+ *     (1  1 ): Reserve
+ * bit 8-9: Reserve for roaming
+ * bit 10: Disable css power collapse if setting
+ * bit 11: Disable sys sleep if setting
+ * bit 12-31: Reserve for future useage
+ *
+ * </ini>
+ */
+#define CFG_LATENCY_FLAGS_LOW_NAME    "wlm_latency_flags_low"
+#define CFG_LATENCY_FLAGS_LOW_MIN     (0x0)
+#define CFG_LATENCY_FLAGS_LOW_MAX     (0xffffffff)
+#define CFG_LATENCY_FLAGS_LOW_DEFAULT (0xa)
+
+/*
+ * <ini>
+ * wlm_latency_flags_ultralow - WLM flags setting for ultralow level
+ *
+ * @min: 0x0
+ * @max: 0xffffffff
+ * @defalut: 0xc83
+ *
+ * |31  12|  11  |  10  |9    8|7    6|5    4|3    2|  1  |  0  |
+ * +------+------+------+------+------+------+------+-----+-----+
+ * | RSVD | SSLP | CSLP | RSVD | Roam | RSVD | DWLT | DFS | SUP |
+ * +------+-------------+-------------+-------------------------+
+ * |  WAL |      PS     |     Roam    |         Scan            |
+ *
+ * bit 0: Avoid scan request from HLOS if setting
+ * bit 1: Skip DFS channel SCAN if setting
+ * bit 2-3: Define policy of dwell time/duration for each foreign channel
+ *     (b2 b3)
+ *     (0  0 ): Default scan dwell time
+ *     (0  1 ): Reserve
+ *     (1  0 ): Shrink off channel dwell time
+ *     (1  1 ): Reserve
+ * bit 4-5: Reserve for scan
+ * bit 6-7: Define roaming policy
+ *     (b6 b7)
+ *     (0  0 ): Default roaming behavior, allow roaming in all scenarios
+ *     (0  1 ): Disallow all roaming
+ *     (1  0 ): Allow roaming when final bmissed
+ *     (1  1 ): Reserve
+ * bit 8-9: Reserve for roaming
+ * bit 10: Disable css power collapse if setting
+ * bit 11: Disable sys sleep if setting
+ * bit 12-31: Reserve for future useage
+ *
+ * </ini>
+ */
+#define CFG_LATENCY_FLAGS_ULTRALOW_NAME    "wlm_latency_flags_ultralow"
+#define CFG_LATENCY_FLAGS_ULTRALOW_MIN     (0x0)
+#define CFG_LATENCY_FLAGS_ULTRALOW_MAX     (0xffffffff)
+#define CFG_LATENCY_FLAGS_ULTRALOW_DEFAULT (0xc83)
+
+#define CFG_INTF0_MAC_ADDR_NAME                  "Intf0MacAddress"
+#define CFG_INTF0_MAC_ADDR_MIN                   "000000000000"
+#define CFG_INTF0_MAC_ADDR_MAX                   "ffffffffffff"
+#define CFG_INTF0_MAC_ADDR_DEFAULT               "000AF58989FF"
+
+#define CFG_INTF1_MAC_ADDR_NAME                  "Intf1MacAddress"
+#define CFG_INTF1_MAC_ADDR_MIN                   "000000000000"
+#define CFG_INTF1_MAC_ADDR_MAX                   "ffffffffffff"
+#define CFG_INTF1_MAC_ADDR_DEFAULT               "000AF58989FE"
+
+#define CFG_INTF2_MAC_ADDR_NAME                  "Intf2MacAddress"
+#define CFG_INTF2_MAC_ADDR_MIN                   "000000000000"
+#define CFG_INTF2_MAC_ADDR_MAX                   "ffffffffffff"
+#define CFG_INTF2_MAC_ADDR_DEFAULT               "000AF58989FD"
+
+#define CFG_INTF3_MAC_ADDR_NAME                  "Intf3MacAddress"
+#define CFG_INTF3_MAC_ADDR_MIN                   "000000000000"
+#define CFG_INTF3_MAC_ADDR_MAX                   "ffffffffffff"
+#define CFG_INTF3_MAC_ADDR_DEFAULT               "000AF58989FC"
+
+/*
+ * <ini>
+ * gDot11Mode - SAP phy mode
+ * @Min: 0
+ * @Max: 12 (11ax)
+ * @Default: 12 (11ax)
+ *
+ * This ini is used to set Phy Mode (auto, b, g, n, etc/) Valid values are
+ * 0-12, with 0 = Auto, 12 = 11ax.
+ *
+ * Related: None.
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_DOT11_MODE_NAME                    "gDot11Mode"
+#define CFG_DOT11_MODE_MIN                     eHDD_DOT11_MODE_AUTO
+#define CFG_DOT11_MODE_DEFAULT                 eHDD_DOT11_MODE_11ax
+#define CFG_DOT11_MODE_MAX                     eHDD_DOT11_MODE_11ax
+
+/*
+ * <ini>
+ * gEnableApUapsd - Enable/disable UAPSD for SoftAP
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to setup setup U-APSD for Acs at association
+ *
+ * Related: None.
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_AP_QOS_UAPSD_MODE_NAME             "gEnableApUapsd"
+#define CFG_AP_QOS_UAPSD_MODE_MIN              (0)
+#define CFG_AP_QOS_UAPSD_MODE_MAX              (1)
+#define CFG_AP_QOS_UAPSD_MODE_DEFAULT          (1)
+
+/*
+ * <ini>
+ * gEnableApRandomBssid - Create ramdom BSSID
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to create a random BSSID in SoftAP mode to meet
+ * the Android requirement.
+ *
+ * Related: None.
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_AP_ENABLE_RANDOM_BSSID_NAME            "gEnableApRandomBssid"
+#define CFG_AP_ENABLE_RANDOM_BSSID_MIN             (0)
+#define CFG_AP_ENABLE_RANDOM_BSSID_MAX             (1)
+#define CFG_AP_ENABLE_RANDOM_BSSID_DEFAULT         (0)
+
+/*
+ * <ini>
+ * gEnableApProt - Enable/Disable AP protection
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable AP protection
+ *
+ * Related: None.
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_AP_ENABLE_PROTECTION_MODE_NAME            "gEnableApProt"
+#define CFG_AP_ENABLE_PROTECTION_MODE_MIN             (0)
+#define CFG_AP_ENABLE_PROTECTION_MODE_MAX             (1)
+#define CFG_AP_ENABLE_PROTECTION_MODE_DEFAULT         (1)
+
+/*
+ * <ini>
+ * gApProtection - Set AP protection parameter
+ * @Min: 0x0
+ * @Max: 0xFFFF
+ * @Default: 0xBFFF
+ *
+ * This ini is used to set AP protection parameter
+ * Bit map for CFG_AP_PROTECTION_MODE_DEFAULT
+ * LOWER byte for associated stations
+ * UPPER byte for overlapping stations
+ * each byte will have the following info
+ * bit15 bit14 bit13     bit12  bit11 bit10    bit9     bit8
+ * OBSS  RIFS  LSIG_TXOP NON_GF HT20  FROM_11G FROM_11B FROM_11A
+ * bit7  bit6  bit5      bit4   bit3  bit2     bit1     bit0
+ * OBSS  RIFS  LSIG_TXOP NON_GF HT_20 FROM_11G FROM_11B FROM_11A
+ *
+ * Related: None.
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_AP_PROTECTION_MODE_NAME            "gApProtection"
+#define CFG_AP_PROTECTION_MODE_MIN             (0x0)
+#define CFG_AP_PROTECTION_MODE_MAX             (0xFFFF)
+#define CFG_AP_PROTECTION_MODE_DEFAULT         (0xBFFF)
+
+/*
+ * <ini>
+ * gEnableApOBSSProt - Enable/Disable AP OBSS protection
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable AP OBSS protection
+ *
+ * Related: None.
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_AP_OBSS_PROTECTION_MODE_NAME       "gEnableApOBSSProt"
+#define CFG_AP_OBSS_PROTECTION_MODE_MIN        (0)
+#define CFG_AP_OBSS_PROTECTION_MODE_MAX        (1)
+#define CFG_AP_OBSS_PROTECTION_MODE_DEFAULT    (0)
+
+/*
+ * <ini>
+ * gDisableIntraBssFwd - Disable intrs BSS Rx packets
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to disbale to forward Intra-BSS Rx packets when
+ * ap_isolate=1 in hostapd.conf
+ *
+ * Related: None.
+ *
+ * Supported Feature: SAP
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_AP_STA_SECURITY_SEPERATION_NAME    "gDisableIntraBssFwd"
+#define CFG_AP_STA_SECURITY_SEPERATION_MIN     (0)
+#define CFG_AP_STA_SECURITY_SEPERATION_MAX     (1)
+#define CFG_AP_STA_SECURITY_SEPERATION_DEFAULT (0)
+
+#define CFG_DISABLE_PACKET_FILTER		"gDisablePacketFilter"
+#define CFG_DISABLE_PACKET_FILTER_MIN		(0)
+#define CFG_DISABLE_PACKET_FILTER_MAX		(1)
+#define CFG_DISABLE_PACKET_FILTER_DEFAULT	(1)
+
+#define CFG_VCC_RSSI_TRIGGER_NAME             "gVccRssiTrigger"
+#define CFG_VCC_RSSI_TRIGGER_MIN              (0)
+#define CFG_VCC_RSSI_TRIGGER_MAX              (80)
+#define CFG_VCC_RSSI_TRIGGER_DEFAULT          (80)
+
+#define CFG_VCC_UL_MAC_LOSS_THRESH_NAME       "gVccUlMacLossThresh"
+#define CFG_VCC_UL_MAC_LOSS_THRESH_MIN        (0)
+#define CFG_VCC_UL_MAC_LOSS_THRESH_MAX        (9)
+#define CFG_VCC_UL_MAC_LOSS_THRESH_DEFAULT    (9)
+
+/*
+ * <ini>
+ * gPassiveMaxChannelTimeConc - Maximum passive scan time in milliseconds.
+ * @Min: 0
+ * @Max: 10000
+ * @Default: 110
+ *
+ * This ini is used to set maximum passive scan time in STA+SAP concurrent
+ * mode.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_NAME      "gPassiveMaxChannelTimeConc"
+#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN       (0)
+#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX       (10000)
+#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_DEFAULT   (110)
+
+/*
+ * <ini>
+ * gPassiveMinChannelTimeConc - Minimum passive scan time in milliseconds.
+ * @Min: 0
+ * @Max: 10000
+ * @Default: 60
+ *
+ * This ini is used to set minimum passive scan time in STA+SAP concurrent
+ * mode.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_NAME      "gPassiveMinChannelTimeConc"
+#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN       (0)
+#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX       (10000)
+#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_DEFAULT   (60)
+
+/*
+ * <ini>
+ * gActiveMaxChannelTimeConc - Maximum active scan time in milliseconds.
+ * @Min: 0
+ * @Max: 10000
+ * @Default: 40
+ *
+ * This ini is used to set maximum active scan time in STA+SAP concurrent
+ * mode.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_NAME       "gActiveMaxChannelTimeConc"
+#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN        (0)
+#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX        (10000)
+#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_DEFAULT    (40)
+
+/*
+ * <ini>
+ * gActiveMinChannelTimeConc - Minimum active scan time in milliseconds..
+ * @Min: 0
+ * @Max: 10000
+ * @Default: 20
+ *
+ * This ini is used to set minimum active scan time in STA+SAP concurrent
+ * mode.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_NAME       "gActiveMinChannelTimeConc"
+#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN        (0)
+#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX        (10000)
+#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_DEFAULT    (20)
+
+/*
+ * <ini>
+ * gRestTimeConc - Rest time before moving to a new channel to scan.
+ * @Min: 0
+ * @Max: 10000
+ * @Default: 100
+ *
+ * This ini is used to configure rest time.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_REST_TIME_CONC_NAME                     "gRestTimeConc"
+#define CFG_REST_TIME_CONC_MIN                      (0)
+#define CFG_REST_TIME_CONC_MAX                      (10000)
+#define CFG_REST_TIME_CONC_DEFAULT                  (100)
+
+/*
+ * <ini>
+ * gMinRestTimeConc - Mininum time spent on home channel before moving to a
+ * new channel to scan.
+ * @Min: 0
+ * @Max: 50
+ * @Default: 50
+ *
+ * This ini is used to configure minimum time spent on home channel before
+ * moving to a new channel to scan.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_MIN_REST_TIME_NAME                      "gMinRestTimeConc"
+#define CFG_MIN_REST_TIME_MIN                       (0)
+#define CFG_MIN_REST_TIME_MAX                       (50)
+#define CFG_MIN_REST_TIME_DEFAULT                   (50)
+
+/*
+ * <ini>
+ * gIdleTimeConc - Data inactivity time in msec.
+ * @Min: 0
+ * @Max: 25
+ * @Default: 25
+ *
+ * This ini is used to configure data inactivity time in msec on bss channel
+ * that will be used by scan engine in firmware.
+ * For example if this value is 25ms then firmware will check for data
+ * inactivity every 25ms till gRestTimeConc is reached.
+ * If inactive then scan engine will move from home channel to scan the next
+ * frequency.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_IDLE_TIME_NAME                          "gIdleTimeConc"
+#define CFG_IDLE_TIME_MIN                           (0)
+#define CFG_IDLE_TIME_MAX                           (25)
+#define CFG_IDLE_TIME_DEFAULT                       (25)
+
+#define CFG_MAX_PS_POLL_NAME                   "gMaxPsPoll"
+#define CFG_MAX_PS_POLL_MIN                    WNI_CFG_MAX_PS_POLL_STAMIN
+#define CFG_MAX_PS_POLL_MAX                    WNI_CFG_MAX_PS_POLL_STAMAX
+#define CFG_MAX_PS_POLL_DEFAULT                WNI_CFG_MAX_PS_POLL_STADEF
+
+#define CFG_MAX_TX_POWER_NAME                   "gTxPowerCap"
+#define CFG_MAX_TX_POWER_MIN                    WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMIN
+#define CFG_MAX_TX_POWER_MAX                    WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX
+/* Not to use CFG default because if no registry setting, this is ignored by SME. */
+#define CFG_MAX_TX_POWER_DEFAULT                WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX
+
+/* This ini controls driver to honor/dishonor power constraint from AP */
+#define CFG_TX_POWER_CTRL_NAME                 "gAllowTPCfromAP"
+#define CFG_TX_POWER_CTRL_DEFAULT              (1)
+#define CFG_TX_POWER_CTRL_MIN                  (0)
+#define CFG_TX_POWER_CTRL_MAX                  (1)
+
+/*
+ * <ini>
+ * gMaxLIModulatedDTIM - Set MaxLIModulate Dtim
+ * @Min: 1
+ * @Max: 10
+ * @Default: 10
+ *
+ * This ini is used to set default MaxLIModulatedDTIM
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_MAX_LI_MODULATED_DTIM_NAME         "gMaxLIModulatedDTIM"
+#define CFG_MAX_LI_MODULATED_DTIM_MIN          (1)
+#define CFG_MAX_LI_MODULATED_DTIM_MAX          (10)
+#define CFG_MAX_LI_MODULATED_DTIM_DEFAULT      (10)
+
+/*
+ * <ini>
+ * gFWMccRtsCtsProtection - RTS-CTS protection in MCC.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable use of long duration RTS-CTS protection
+ * when SAP goes off channel in MCC mode.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_FW_MCC_RTS_CTS_PROT_NAME           "gFWMccRtsCtsProtection"
+#define CFG_FW_MCC_RTS_CTS_PROT_MIN            (0)
+#define CFG_FW_MCC_RTS_CTS_PROT_MAX            (1)
+#define CFG_FW_MCC_RTS_CTS_PROT_DEFAULT        (0)
+
+/*
+ * <ini>
+ * gFWMccBCastProbeResponse - Broadcast Probe Response in MCC.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable use of broadcast probe response to
+ * increase the detectability of SAP in MCC mode.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_FW_MCC_BCAST_PROB_RESP_NAME        "gFWMccBCastProbeResponse"
+#define CFG_FW_MCC_BCAST_PROB_RESP_MIN         (0)
+#define CFG_FW_MCC_BCAST_PROB_RESP_MAX         (1)
+#define CFG_FW_MCC_BCAST_PROB_RESP_DEFAULT     (0)
+
+/*
+ * <ini>
+ * g_wow_data_inactivity_timeout - Data activity timeout in wow mode.
+ * @Min: 1
+ * @Max: 255
+ * @Default: 50
+ *
+ * This ini is used to set data inactivity timeout in wow mode.
+ *
+ * Supported Feature: inactivity timeout in wow mode
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_WOW_DATA_INACTIVITY_TIMEOUT_NAME     "g_wow_data_inactivity_timeout"
+#define CFG_WOW_DATA_INACTIVITY_TIMEOUT_MIN      (1)
+#define CFG_WOW_DATA_INACTIVITY_TIMEOUT_MAX      (255)
+#define CFG_WOW_DATA_INACTIVITY_TIMEOUT_DEFAULT  (50)
+
+/**
+ * enum station_keepalive_method - available keepalive methods for stations
+ * @HDD_STA_KEEPALIVE_NULL_DATA: null data packet
+ * @HDD_STA_KEEPALIVE_GRAT_ARP: gratuitous ARP packet
+ * @HDD_STA_KEEPALIVE_COUNT: number of method options available
+ */
+enum station_keepalive_method {
+	HDD_STA_KEEPALIVE_NULL_DATA,
+	HDD_STA_KEEPALIVE_GRAT_ARP,
+	/* keep at the end */
+	HDD_STA_KEEPALIVE_COUNT
+};
+
+/*
+ * <ini>
+ * gStaKeepAliveMethod - Which keepalive method to use
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini determines which keepalive method to use for station interfaces
+ *       1) Use null data packets
+ *       2) Use gratuitous ARP packets
+ *
+ * Related: gStaKeepAlivePeriod, gApKeepAlivePeriod, gGoKeepAlivePeriod
+ *
+ * Supported Feature: STA, Keepalive
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_STA_KEEPALIVE_METHOD_NAME              "gStaKeepAliveMethod"
+#define CFG_STA_KEEPALIVE_METHOD_MIN               (HDD_STA_KEEPALIVE_NULL_DATA)
+#define CFG_STA_KEEPALIVE_METHOD_MAX               (HDD_STA_KEEPALIVE_COUNT - 1)
+#define CFG_STA_KEEPALIVE_METHOD_DEFAULT           (HDD_STA_KEEPALIVE_GRAT_ARP)
+
+/* WMM configuration */
+/*
+ * <ini>
+ * ImplicitQosIsEnabled - Enableimplicit QOS
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable implicit QOS.
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_IMPLICIT_SETUP_ENABLED_NAME             "ImplicitQosIsEnabled"
+#define CFG_QOS_IMPLICIT_SETUP_ENABLED_MIN              (0)
+#define CFG_QOS_IMPLICIT_SETUP_ENABLED_MAX              (1)
+#define CFG_QOS_IMPLICIT_SETUP_ENABLED_DEFAULT          (0)
+
+/*
+ * <ini>
+ * burstSizeDefinition - Set TS burst size
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set TS burst size
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_BURST_SIZE_DEFN_NAME                "burstSizeDefinition"
+#define CFG_QOS_WMM_BURST_SIZE_DEFN_MIN                  (0)
+#define CFG_QOS_WMM_BURST_SIZE_DEFN_MAX                  (1)
+#define CFG_QOS_WMM_BURST_SIZE_DEFN_DEFAULT              (0)
+
+/*
+ * <ini>
+ * tsInfoAckPolicy - Set TS ack policy
+ * @Min: 0x00
+ * @Max: 0x01
+ * @Default: 0x00
+ *
+ * This ini is used to set TS ack policy
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_NAME              "tsInfoAckPolicy"
+#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_MIN                (0x00)
+#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_MAX                (0x01)
+#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_DEFAULT            (0x00)
+
+/*
+ * <ini>
+ * gAddTSWhenACMIsOff - Set ACM value for AC
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set ACM value for AC
+ *
+ * Related: None.
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_NAME               "gAddTSWhenACMIsOff"
+#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MIN                (0)
+/* Send AddTs even when ACM is not set for the AC */
+#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MAX                (1)
+#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_DEFAULT            (0)
+
+#ifdef FEATURE_WLAN_ESE
+#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_NAME    "InfraInactivityInterval"
+#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MIN      (0)
+#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MAX      (4294967295UL)
+#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_DEFAULT  (0) /* disabled */
+
+#define CFG_ESE_FEATURE_ENABLED_NAME                       "EseEnabled"
+#define CFG_ESE_FEATURE_ENABLED_MIN                         (0)
+#define CFG_ESE_FEATURE_ENABLED_MAX                         (1)
+#define CFG_ESE_FEATURE_ENABLED_DEFAULT                     (0) /* disabled */
+#endif /* FEATURE_WLAN_ESE */
+
+/*
+ * <ini>
+ * MAWCEnabled - Enable/Disable Motion Aided Wireless Connectivity Global
+ * @Min: 0 - Disabled
+ * @Max: 1 - Enabled
+ * @Default: 0
+ *
+ * This ini is used to controls the MAWC feature globally.
+ * MAWC is Motion Aided Wireless Connectivity.
+ *
+ * Related: mawc_roam_enabled.
+ *
+ * Supported Feature: Roaming and PNO/NLO
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_LFR_MAWC_FEATURE_ENABLED_NAME                   "MAWCEnabled"
+#define CFG_LFR_MAWC_FEATURE_ENABLED_MIN                    (0)
+#define CFG_LFR_MAWC_FEATURE_ENABLED_MAX                    (1)
+#define CFG_LFR_MAWC_FEATURE_ENABLED_DEFAULT                (0)
+
+/*This parameter is used to set Wireless Extended Security Mode.*/
+#define CFG_ENABLE_WES_MODE_NAME                            "gWESModeEnabled"
+#define CFG_ENABLE_WES_MODE_NAME_MIN                        (0)
+#define CFG_ENABLE_WES_MODE_NAME_MAX                        (1)
+#define CFG_ENABLE_WES_MODE_NAME_DEFAULT                    (0)
+
+#define CFG_TL_DELAYED_TRGR_FRM_INT_NAME                   "DelayedTriggerFrmInt"
+#define CFG_TL_DELAYED_TRGR_FRM_INT_MIN                     1
+#define CFG_TL_DELAYED_TRGR_FRM_INT_MAX                     (4294967295UL)
+#define CFG_TL_DELAYED_TRGR_FRM_INT_DEFAULT                 3000
+
+/*
+ * <ini>
+ * gRrmEnable - Enable/Disable RRM
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to controls the capabilities (11 k) included
+ * in the capabilities field.
+ *
+ * Related: None.
+ *
+ * Supported Feature: 11k
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_RRM_ENABLE_NAME                              "gRrmEnable"
+#define CFG_RRM_ENABLE_MIN                               (0)
+#define CFG_RRM_ENABLE_MAX                               (1)
+#define CFG_RRM_ENABLE_DEFAULT                           (0)
+
+/*
+ * <ini>
+ * gRrmRandnIntvl - Randomization interval
+ * @Min: 10
+ * @Max: 100
+ * @Default: 100
+ *
+ * This ini is used to set randomization interval which is used to start a timer
+ * of a random value within randomization interval. Next RRM Scan request
+ * will be issued after the expiry of this random interval.
+ *
+ * Related: None.
+ *
+ * Supported Feature: 11k
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_NAME            "gRrmRandnIntvl"
+#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_MIN             (10)
+#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_MAX             (100)
+#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_DEFAULT         (100)
+
+/*
+ * <ini>
+ * rm_capability - Configure RM enabled capabilities IE
+ * @Default: 73,10,91,00,04
+ *
+ * This ini is used to configure RM enabled capabilities IE.
+ * Using this INI, we can set/unset any of the bits in 5 bytes
+ * (last 4bytes are reserved). Bit details are updated as per
+ * Draft version of 11mc spec. (Draft P802.11REVmc_D4.2)
+ *
+ * Bitwise details are defined as bit mask in rrm_global.h
+ * Comma is used as a separator for each byte.
+ *
+ * Related: None.
+ *
+ * Supported Feature: 11k
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_RM_CAPABILITY_NAME            "rm_capability"
+#define CFG_RM_CAPABILITY_DEFAULT         "73,10,91,00,04"
+
+#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_NAME      "gNeighborLookupThreshold"
+#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN       (10)
+#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX       (120)
+#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT   (78)
+
+#define CFG_DELAY_BEFORE_VDEV_STOP_NAME              "gDelayBeforeVdevStop"
+#define CFG_DELAY_BEFORE_VDEV_STOP_MIN               (2)
+#define CFG_DELAY_BEFORE_VDEV_STOP_MAX               (200)
+#define CFG_DELAY_BEFORE_VDEV_STOP_DEFAULT           (20)
+
+#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_NAME           "gMaxNeighborReqTries"
+#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_MIN            (1)
+#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_MAX            (4)
+#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_DEFAULT        (3)
+
+#define CFG_ROAM_BMISS_FIRST_BCNT_NAME                  "gRoamBmissFirstBcnt"
+#define CFG_ROAM_BMISS_FIRST_BCNT_MIN                   (5)
+#define CFG_ROAM_BMISS_FIRST_BCNT_MAX                   (100)
+#define CFG_ROAM_BMISS_FIRST_BCNT_DEFAULT               (10)
+
+#define CFG_ROAM_BMISS_FINAL_BCNT_NAME                  "gRoamBmissFinalBcnt"
+#define CFG_ROAM_BMISS_FINAL_BCNT_MIN                   (5)
+#define CFG_ROAM_BMISS_FINAL_BCNT_MAX                   (100)
+#define CFG_ROAM_BMISS_FINAL_BCNT_DEFAULT               (20)
+
+#define CFG_ROAM_BEACON_RSSI_WEIGHT_NAME                "gRoamBeaconRssiWeight"
+#define CFG_ROAM_BEACON_RSSI_WEIGHT_MIN                 (0)
+#define CFG_ROAM_BEACON_RSSI_WEIGHT_MAX                 (16)
+#define CFG_ROAM_BEACON_RSSI_WEIGHT_DEFAULT             (14)
+
+#define CFG_AP_DATA_AVAIL_POLL_PERIOD_NAME      "gApDataAvailPollInterval"
+#define CFG_AP_DATA_AVAIL_POLL_PERIOD_MIN       (WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMIN)
+#define CFG_AP_DATA_AVAIL_POLL_PERIOD_MAX       (WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMAX)
+#define CFG_AP_DATA_AVAIL_POLL_PERIOD_DEFAULT   (WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STADEF)
+
+/*
+ * <ini>
+ * gHwFilterMode - configure hardware filter for DTIM mode
+ * @Min: 0
+ * @Max: 3
+ * @Default: 1
+ *
+ * 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
+ *
+ * Takes a bitmap of frame types to drop
+ * @E.g.
+ *	# disable feature
+ *	gHwFilterMode=0
+ *	# drop all broadcast frames, except ARP (default)
+ *	gHwFilterMode=1
+ *	# drop all multicast frames, except ICMPv6
+ *	gHwFilterMode=2
+ *	# drop all broadcast and multicast frames, except ARP and ICMPv6
+ *	gHwFilterMode=3
+ *
+ * Related: N/A
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_HW_FILTER_MODE_BITMAP_NAME	"gHwFilterMode"
+#define CFG_HW_FILTER_MODE_BITMAP_MIN		(0)
+#define CFG_HW_FILTER_MODE_BITMAP_MAX		(3)
+#define CFG_HW_FILTER_MODE_BITMAP_DEFAULT	(1)
+
+#define CFG_ENABLE_BYPASS_11D_NAME                 "gEnableBypass11d"
+#define CFG_ENABLE_BYPASS_11D_MIN                  (0)
+#define CFG_ENABLE_BYPASS_11D_MAX                  (1)
+#define CFG_ENABLE_BYPASS_11D_DEFAULT              (1)
+
+/*
+ * gEnableDFSChnlScan - enable dfs channel scan.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable dfs channels in scan, enabling this
+ * will enable driver to include dfs channels in its scan list.
+ * Related: NA
+ *
+ * Supported Feature: DFS, Scan
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_DFS_CHNL_SCAN_NAME              "gEnableDFSChnlScan"
+#define CFG_ENABLE_DFS_CHNL_SCAN_MIN               (0)
+#define CFG_ENABLE_DFS_CHNL_SCAN_MAX               (1)
+#define CFG_ENABLE_DFS_CHNL_SCAN_DEFAULT           (1)
+
+enum hdd_link_speed_rpt_type {
+	eHDD_LINK_SPEED_REPORT_ACTUAL = 0,
+	eHDD_LINK_SPEED_REPORT_MAX = 1,
+	eHDD_LINK_SPEED_REPORT_MAX_SCALED = 2,
+};
+
+/*
+ * <ini>
+ * enable_bt_chain_separation - Enables/disables bt /wlan chainmask assignment
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini disables/enables chainmask setting on 2x2, mainly used for ROME
+ * BT/WLAN chainmask assignment.
+ *
+ * 0, Disable
+ * 1, Enable
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11n/11ac
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_BT_CHAIN_SEPARATION         "enableBTChainSeparation"
+#define CFG_ENABLE_BT_CHAIN_SEPARATION_MIN     (0)
+#define CFG_ENABLE_BT_CHAIN_SEPARATION_MAX     (1)
+#define CFG_ENABLE_BT_CHAIN_SEPARATION_DEFAULT (0)
+
+/*
+ * <ini>
+ * gVdevTypeNss_2g - set Number of streams per VDEV for 2G band.
+ * @Min: 0x5555
+ * @Max: 0xAAAA
+ * @Default: 0xAAAA
+ *
+ * This ini is  used to set set Number of streams per VDEV for 2G band
+ *
+ * These Nss parameters will have 32-bit configuration value, 2 bits are
+ * allocated for each vdev.
+ * Valid values are:
+ * Min value – 0x5555
+ * Max value – 0xAAAA
+ * Default value will be 0xAAAA for both the parameters.
+ * Value 0x5555 will configure all vdevs in 1x1 mode in 2.4G band.
+ * Value 0xAAAA will configure all vdevs in 2x2 mode in 2.4G band.
+ *
+ * The max value is defined based on the valid max Nss of the vdev, the valid
+ * values for each vdev 2-bits are 0x1 and 0x2. 0x3 and 0x0 are not valid vdev
+ * Nss values.
+ *
+ * NSS cfg bit definition.
+ * STA          BIT[0:1]
+ * SAP          BIT[2:3]
+ * P2P_GO       BIT[4:5]
+ * P2P_CLIENT   BIT[6:7]
+ * IBSS         BIT[8:9]
+ * TDLS         BIT[10:11]
+ * P2P_DEVICE   BIT[12:13]
+ * OCB          BIT[14:15]
+ *
+ * Related: NA
+ *
+ * Supported Feature: Antenna Sharing
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_VDEV_TYPE_NSS_2G         "gVdevTypeNss_2g"
+#define CFG_VDEV_TYPE_NSS_2G_MIN     (0x5555)
+#define CFG_VDEV_TYPE_NSS_2G_MAX     (0xAAAA)
+#define CFG_VDEV_TYPE_NSS_2G_DEFAULT (0xAAAA)
+
+/*
+ * <ini>
+ * gVdevTypeNss_5g - set Number of streams per VDEV for 5G band.
+ * @Min: 0x5555
+ * @Max: 0xAAAA
+ * @Default: 0xAAAA
+ *
+ * This ini is  used to set set Number of streams per VDEV for 2G band
+ *
+ * These Nss parameters will have 32-bit configuration value, 2 bits are
+ * allocated for each vdev.
+ * Valid values are:
+ * Min value – 0x5555
+ * Max value – 0xAAAA
+ * Default value will be 0xAAAA for both the parameters.
+ * Value 0x5555 will configure all vdevs in 1x1 mode in 5 band.
+ * Value 0xAAAA will configure all vdevs in 2x2 mode in 5 band.
+ *
+ * The max value is defined based on the valid max Nss of the vdev, the valid
+ * values for each vdev 2-bits are 0x1 and 0x2. 0x3 and 0x0 are not valid vdev
+ * Nss values.
+ *
+ * NSS cfg bit definition.
+ * STA          BIT[0:1]
+ * SAP          BIT[2:3]
+ * P2P_GO       BIT[4:5]
+ * P2P_CLIENT   BIT[6:7]
+ * IBSS         BIT[8:9]
+ * TDLS         BIT[10:11]
+ * P2P_DEVICE   BIT[12:13]
+ * OCB          BIT[14:15]
+ *
+ * Related: NA
+ *
+ * Supported Feature: Antenna Sharing
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_VDEV_TYPE_NSS_5G         "gVdevTypeNss_5g"
+#define CFG_VDEV_TYPE_NSS_5G_MIN     (0x5555)
+#define CFG_VDEV_TYPE_NSS_5G_MAX     (0xAAAA)
+#define CFG_VDEV_TYPE_NSS_5G_DEFAULT (0xAAAA)
+
+/*
+ * <ini>
+ * gDisableDFSChSwitch - Disable channel switch if radar is found
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to disable channel switch if radar is found
+ * on that channel.
+ * Related: NA.
+ *
+ * Supported Feature: DFS
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_DISABLE_DFS_CH_SWITCH                 "gDisableDFSChSwitch"
+#define CFG_DISABLE_DFS_CH_SWITCH_MIN             (0)
+#define CFG_DISABLE_DFS_CH_SWITCH_MAX             (1)
+#define CFG_DISABLE_DFS_CH_SWITCH_DEFAULT         (0)
+
+/*
+ * <ini>
+ * gSapPreferredChanLocation - Restrict channel switches between ondoor and
+ * outdoor.
+ * @Min: 0
+ * @Max: 2
+ * @Default: 0
+ *
+ * This ini is used for restricting channel switches between Indoor and outdoor
+ * channels after radar detection.
+ * 0- No preferred channel location
+ * 1- Use indoor channels only
+ * 2- Use outdoor channels only
+ * Related: NA.
+ *
+ * Supported Feature: DFS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_SAP_PREFERRED_CHANNEL_LOCATION          "gSapPreferredChanLocation"
+#define CFG_SAP_PREFERRED_CHANNEL_LOCATION_MIN      (0)
+#define CFG_SAP_PREFERRED_CHANNEL_LOCATION_MAX      (2)
+#define CFG_SAP_PREFERRED_CHANNEL_LOCATION_DEFAULT  (0)
+
+/*
+ * <ini>
+ * gDisableDfsJapanW53 - Block W53 channels in random channel selection
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to block W53 Japan channel in random channel selection
+ * Related: NA.
+ *
+ * Supported Feature: DFS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_DISABLE_DFS_JAPAN_W53                      "gDisableDfsJapanW53"
+#define CFG_DISABLE_DFS_JAPAN_W53_MIN                  (0)
+#define CFG_DISABLE_DFS_JAPAN_W53_MAX                  (1)
+#define CFG_DISABLE_DFS_JAPAN_W53_DEFAULT              (0)
+
+/*
+ * <ini>
+ * gDisableDfsJapanW53 - Enable dfs phyerror filtering offload in FW
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to to enable dfs phyerror filtering offload to firmware
+ * Enabling it will cause basic phy error to be discarding in firmware.
+ * Related: NA.
+ *
+ * Supported Feature: DFS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_NAME       "dfsPhyerrFilterOffload"
+#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MIN        (0)
+#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MAX        (1)
+#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_DEFAULT    (0)
+
+#define CFG_REPORT_MAX_LINK_SPEED                  "gReportMaxLinkSpeed"
+#define CFG_REPORT_MAX_LINK_SPEED_MIN              (eHDD_LINK_SPEED_REPORT_ACTUAL)
+#define CFG_REPORT_MAX_LINK_SPEED_MAX              (eHDD_LINK_SPEED_REPORT_MAX_SCALED)
+#define CFG_REPORT_MAX_LINK_SPEED_DEFAULT          (eHDD_LINK_SPEED_REPORT_ACTUAL)
+
+/*
+ * <ini>
+ * gLinkSpeedRssiHigh - Report the max possible speed with RSSI scaling
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set default eHDD_LINK_SPEED_REPORT
+ * Used when eHDD_LINK_SPEED_REPORT_SCALED is selected
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_LINK_SPEED_RSSI_HIGH                   "gLinkSpeedRssiHigh"
+#define CFG_LINK_SPEED_RSSI_HIGH_MIN               (-127)
+#define CFG_LINK_SPEED_RSSI_HIGH_MAX               (0)
+#define CFG_LINK_SPEED_RSSI_HIGH_DEFAULT           (-55)
+
+/*
+ * <ini>
+ * gLinkSpeedRssiMed - Used when eHDD_LINK_SPEED_REPORT_SCALED is selected
+ * @Min: -127
+ * @Max: 0
+ * @Default: -65
+ *
+ * This ini is used to set medium rssi link speed
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_LINK_SPEED_RSSI_MID                    "gLinkSpeedRssiMed"
+#define CFG_LINK_SPEED_RSSI_MID_MIN                (-127)
+#define CFG_LINK_SPEED_RSSI_MID_MAX                (0)
+#define CFG_LINK_SPEED_RSSI_MID_DEFAULT            (-65)
+
+/*
+ * <ini>
+ * gLinkSpeedRssiLow - Used when eHDD_LINK_SPEED_REPORT_SCALED is selected
+ * @Min: -127
+ * @Max: 0
+ * @Default: -80
+ *
+ * This ini is used to set low rssi link speed
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_LINK_SPEED_RSSI_LOW                    "gLinkSpeedRssiLow"
+#define CFG_LINK_SPEED_RSSI_LOW_MIN                (-127)
+#define CFG_LINK_SPEED_RSSI_LOW_MAX                (0)
+#define CFG_LINK_SPEED_RSSI_LOW_DEFAULT            (-80)
+
+/*
+ * <ini>
+ * gEnableSSR - Enable/Disable SSR
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable System Self Recovery at the times of
+ * System crash or fatal errors
+ * gEnableSSR = 0 Disabled
+ * gEnableSSR = 1 wlan shutdown and re-init happens
+ *
+ * Related: None
+ *
+ * Supported Feature: SSR
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_SSR                      "gEnableSSR"
+#define CFG_ENABLE_SSR_MIN                  (0)
+#define CFG_ENABLE_SSR_MAX                  (1)
+#define CFG_ENABLE_SSR_DEFAULT              (1)
+
+/*
+ * <ini>
+ * gEnableOverLapCh - Enables Overlap Channel. If set, allow overlapping
+ *                    channels to be selected for the SoftAP
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set Overlap Channel
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_OVERLAP_CH               "gEnableOverLapCh"
+#define CFG_ENABLE_OVERLAP_CH_MIN           (0)
+#define CFG_ENABLE_OVERLAP_CH_MAX           (1)
+#define CFG_ENABLE_OVERLAP_CH_DEFAULT       (0)
+
+/* For valid values of log levels check enum DBGLOG_LOG_LVL and
+ * for valid values of module ids check enum WLAN_MODULE_ID.
+ */
+#define CFG_ENABLE_FW_MODULE_LOG_LEVEL    "gFwDebugModuleLoglevel"
+#define CFG_ENABLE_FW_MODULE_LOG_DEFAULT  "2,1,3,1,5,1,9,1,13,1,14,1,18,1,19,1,26,1,28,1,29,1,31,1,36,1,38,1,46,1,47,1,50,1,52,1,53,1,56,1,60,1,61,1,4,1"
+
+/*
+ * <ini>
+ * gEnableConcurrentSTA - This will control the creation of concurrent STA
+ * interface
+ * @Default: NULL
+ *
+ * This ini is used for providing control to create a concurrent STA session
+ * along with the creation of wlan0 and p2p0. The name of the interface is
+ * specified as the parameter
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_CONCURRENT_STA           "gEnableConcurrentSTA"
+#define CFG_ENABLE_CONCURRENT_STA_DEFAULT   ""
+
+/*
+ * QDF Trace Enable Control
+ * Notes:
+ *  the MIN/MAX/DEFAULT values apply for all modules
+ *  the DEFAULT value is outside the valid range.  if the DEFAULT
+ *    value is not overridden, then no change will be made to the
+ *    "built in" default values compiled into the code
+ *  values are a bitmap indicating which log levels are to enabled
+ *    (must match order of qdf_trace_level enumerations)
+ *    00000001  FATAL
+ *    00000010  ERROR
+ *    00000100  WARN
+ *    00001000  INFO
+ *    00010000  INFO HIGH
+ *    00100000  INFO MED
+ *    01000000  INFO LOW
+ *    10000000  DEBUG
+ *
+ *  hence a value of 0xFF would set all bits (enable all logs)
+ */
+
+#define CFG_QDF_TRACE_ENABLE_WDI_NAME     "qdf_trace_enable_wdi"
+#define CFG_QDF_TRACE_ENABLE_HDD_NAME     "qdf_trace_enable_hdd"
+#define CFG_QDF_TRACE_ENABLE_SME_NAME     "qdf_trace_enable_sme"
+#define CFG_QDF_TRACE_ENABLE_PE_NAME      "qdf_trace_enable_pe"
+#define CFG_QDF_TRACE_ENABLE_PMC_NAME     "qdf_trace_enable_pmc"
+#define CFG_QDF_TRACE_ENABLE_WMA_NAME     "qdf_trace_enable_wma"
+#define CFG_QDF_TRACE_ENABLE_SYS_NAME     "qdf_trace_enable_sys"
+#define CFG_QDF_TRACE_ENABLE_QDF_NAME     "qdf_trace_enable_qdf"
+#define CFG_QDF_TRACE_ENABLE_SAP_NAME     "qdf_trace_enable_sap"
+#define CFG_QDF_TRACE_ENABLE_HDD_SAP_NAME "qdf_trace_enable_hdd_sap"
+#define CFG_QDF_TRACE_ENABLE_BMI_NAME     "qdf_trace_enable_bmi"
+#define CFG_QDF_TRACE_ENABLE_CFG_NAME     "qdf_trace_enable_cfg"
+#define CFG_QDF_TRACE_ENABLE_EPPING       "qdf_trace_enable_epping"
+#define CFG_QDF_TRACE_ENABLE_QDF_DEVICES  "qdf_trace_enable_qdf_devices"
+#define CFG_QDF_TRACE_ENABLE_TXRX_NAME    "qdf_trace_enable_txrx"
+#define CFG_QDF_TRACE_ENABLE_DP_NAME      "qdf_trace_enable_dp"
+#define CFG_QDF_TRACE_ENABLE_HTC_NAME     "qdf_trace_enable_htc"
+#define CFG_QDF_TRACE_ENABLE_HIF_NAME     "qdf_trace_enable_hif"
+#define CFG_CDR_TRACE_ENABLE_HDD_SAP_DATA_NAME   "qdf_trace_enable_hdd_sap_data"
+#define CFG_QDF_TRACE_ENABLE_HDD_DATA_NAME       "qdf_trace_enable_hdd_data"
+#define CFG_QDF_TRACE_ENABLE_WIFI_POS     "qdf_trace_enable_wifi_pos"
+#define CFG_QDF_TRACE_ENABLE_NAN          "qdf_trace_enable_nan"
+#define CFG_QDF_TRACE_ENABLE_REGULATORY   "qdf_trace_enable_regulatory"
+#define CFG_QDF_TRACE_ENABLE_CP_STATS     "qdf_trace_enable_cp_stats"
+
+#define CFG_QDF_TRACE_ENABLE_MIN          (0)
+#define CFG_QDF_TRACE_ENABLE_MAX          (0xff)
+#define CFG_QDF_TRACE_ENABLE_DEFAULT      (0xffff)
+/* disable debug logs for DP by default */
+#define CFG_QDF_TRACE_ENABLE_DP_DEFAULT   (0x7f)
+
+#ifdef ENABLE_MTRACE_LOG
+/*
+ * Enable MTRACE for all modules
+ */
+#define CFG_ENABLE_MTRACE            "enable_mtrace"
+#define CFG_ENABLE_MTRACE_MIN        (0)
+#define CFG_ENABLE_MTRACE_MAX        (1)
+#define CFG_ENABLE_MTRACE_DEFAULT    (0)
+#endif
+
+#define HDD_MCASTBCASTFILTER_FILTER_NONE                       0x00
+#define HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST              0x01
+#define HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST              0x02
+#define HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST    0x03
+#define HDD_MULTICAST_FILTER_LIST                              0x04
+#define HDD_MULTICAST_FILTER_LIST_CLEAR                        0x05
+
+/*
+ * <ini>
+ * gConfigVCmodeBitmap - Bitmap for operating voltage corner mode
+ * @Min: 0x00000000
+ * @Max: 0x0fffffff
+ * @Default: 0x0000000a
+ * This ini is used to set operating voltage corner mode for differenet
+ * phymode and bw configurations. Every 2 bits till BIT27 are dedicated
+ * for a specific configuration. Bit values decide the type of voltage
+ * corner mode. All the details below -
+ *
+ * Configure operating voltage corner mode based on phymode and bw.
+ * bit 0-1 -   operating voltage corner mode for 11a/b.
+ * bit 2-3 -   operating voltage corner mode for 11g.
+ * bit 4-5 -   operating voltage corner mode for 11n, 20MHz, 1x1.
+ * bit 6-7 -   operating voltage corner mode for 11n, 20MHz, 2x2.
+ * bit 8-9 -   operating voltage corner mode for 11n, 40MHz, 1x1.
+ * bit 10-11 - operating voltage corner mode for 11n, 40MHz, 2x2.
+ * bit 12-13 - operating voltage corner mode for 11ac, 20MHz, 1x1.
+ * bit 14-15 - operating voltage corner mode for 11ac, 20MHz, 2x2.
+ * bit 16-17 - operating voltage corner mode for 11ac, 40MHz, 1x1.
+ * bit 18-19 - operating voltage corner mode for 11ac, 40MHz, 2x2.
+ * bit 20-21 - operating voltage corner mode for 11ac, 80MHz, 1x1.
+ * bit 22-23 - operating voltage corner mode for 11ac, 80MHz, 2x2.
+ * bit 24-25 - operating voltage corner mode for 11ac, 160MHz, 1x1.
+ * bit 26-27 - operating voltage corner mode for 11ac, 160MHz, 2x2.
+ * ---------------------------------------------
+ * 00 - Static voltage corner SVS
+ * 01 - static voltage corner LOW SVS
+ * 10 - Dynamic voltage corner selection based on TPUT
+ * 11 - Dynamic voltage corner selection based on TPUT and Tx Flush counters
+
+ * Related: None
+ *
+ * Supported Feature: None
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_VC_MODE_BITMAP                  "gConfigVCmode"
+#define CFG_VC_MODE_BITMAP_MIN              (0x00000000)
+#define CFG_VC_MODE_BITMAP_MAX              (0x0fffffff)
+#define CFG_VC_MODE_BITMAP_DEFAULT          (0x00000005)
+
+/*
+ * <ini>
+ * gEnableSAPManadatoryChanList - Enable SAP Mandatory channel list
+ * Options.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable the SAP manadatory chan list
+ * 0 - Disable SAP mandatory chan list
+ * 1 - Enable SAP mandatory chan list
+ *
+ * Supported Feature: SAP
+ *
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_SAP_MANDATORY_CHAN_LIST       "gEnableSAPManadatoryChanList"
+#define CFG_ENABLE_SAP_MANDATORY_CHAN_LIST_MIN   (0)
+#define CFG_ENABLE_SAP_MANDATORY_CHAN_LIST_MAX   (1)
+#define CFG_ENABLE_SAP_MANDATORY_CHAN_LIST_DEFAULT (0)
+
+/*
+ * <ini>
+ * gShortGI40Mhz - It will check gShortGI20Mhz and
+ * gShortGI40Mhz from session entry
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set default gShortGI40Mhz
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_SHORT_GI_40MHZ_NAME                "gShortGI40Mhz"
+#define CFG_SHORT_GI_40MHZ_MIN                 0
+#define CFG_SHORT_GI_40MHZ_MAX                 1
+#define CFG_SHORT_GI_40MHZ_DEFAULT             1
+
+/*
+ * <ini>
+ * gEnableMCCMode - Enable/Disable MCC feature.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable MCC feature.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_MCC_ENABLED_NAME             "gEnableMCCMode"
+#define CFG_ENABLE_MCC_ENABLED_MIN              (0)
+#define CFG_ENABLE_MCC_ENABLED_MAX              (1)
+#define CFG_ENABLE_MCC_ENABLED_DEFAULT          (1)
+
+/*
+ * <ini>
+ * gAllowMCCGODiffBI - Allow GO in MCC mode to accept different beacon interval
+ * than STA's.
+ * @Min: 0
+ * @Max: 4
+ * @Default: 4
+ *
+ * This ini is used to allow GO in MCC mode to accept different beacon interval
+ * than STA's.
+ * Added for Wi-Fi Cert. 5.1.12
+ * If gAllowMCCGODiffBI = 1
+ *	Set to 1 for WFA certification. GO Beacon interval is not changed.
+ *	MCC GO doesn't work well in optimized way. In worst scenario, it may
+ *	invite STA disconnection.
+ * If gAllowMCCGODiffBI = 2
+ *	If set to 2 workaround 1 disassoc all the clients and update beacon
+ *	Interval.
+ * If gAllowMCCGODiffBI = 3
+ *	If set to 3 tear down the P2P link in auto/Non-autonomous -GO case.
+ * If gAllowMCCGODiffBI = 4
+ *	If set to 4 don't disconnect the P2P client in autonomous/Non-auto-
+ *	nomous -GO case update the BI dynamically
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ALLOW_MCC_GO_DIFF_BI_NAME           "gAllowMCCGODiffBI"
+#define CFG_ALLOW_MCC_GO_DIFF_BI_MIN            (0)
+#define CFG_ALLOW_MCC_GO_DIFF_BI_MAX            (4)
+#define CFG_ALLOW_MCC_GO_DIFF_BI_DEFAULT        (4)
+
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
+/*
+ * Enable/Disable Bad Peer TX CTL feature
+ * Default: Enable
+ */
+#define CFG_BAD_PEER_TX_CTL_ENABLE_NAME		"gBadPeerTxCtlEnable"
+#define CFG_BAD_PEER_TX_CTL_ENABLE_MIN         (0)
+#define CFG_BAD_PEER_TX_CTL_ENABLE_MAX         (1)
+#define CFG_BAD_PEER_TX_CTL_ENABLE_DEFAULT     (1)
+
+#define CFG_BAD_PEER_TX_CTL_PERIOD_NAME		"gBadPeerTxCtlPeriod"
+#define CFG_BAD_PEER_TX_CTL_PERIOD_MIN         (10)
+#define CFG_BAD_PEER_TX_CTL_PERIOD_MAX         (10000)
+#define CFG_BAD_PEER_TX_CTL_PERIOD_DEFAULT     (50)
+
+#define CFG_BAD_PEER_TX_CTL_TXQ_LIMIT_NAME	"gBadPeerTxCtlTxqLimit"
+#define CFG_BAD_PEER_TX_CTL_TXQ_LIMIT_MIN      (1)
+#define CFG_BAD_PEER_TX_CTL_TXQ_LIMIT_MAX      (5000)
+#define CFG_BAD_PEER_TX_CTL_TXQ_LIMIT_DEFAULT  (100)
+
+#define CFG_BAD_PEER_TX_CTL_TGT_BACKOFF_T_NAME	"gBadPeerTxCtlTgtBackoffTime"
+#define CFG_BAD_PEER_TX_CTL_TGT_BACKOFF_T_MIN     (1)
+#define CFG_BAD_PEER_TX_CTL_TGT_BACKOFF_T_MAX     (5000)
+#define CFG_BAD_PEER_TX_CTL_TGT_BACKOFF_T_DEFAULT (20)
+
+#define CFG_BAD_PEER_TX_CTL_TGT_REPORT_PRD_NAME	"gBadPeerTxCtlTgtReportPeriod"
+#define CFG_BAD_PEER_TX_CTL_TGT_REPORT_PRD_MIN     (1)
+#define CFG_BAD_PEER_TX_CTL_TGT_REPORT_PRD_MAX     (5000)
+#define CFG_BAD_PEER_TX_CTL_TGT_REPORT_PRD_DEFAULT (500)
+
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEB_NAME	"gBadPeerTxCtlCondLevelIeeeB"
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEB_MIN     (1)
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEB_MAX     (2)
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEB_DEFAULT (2)
+
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEB_NAME	"gBadPeerTxCtlDeltaLevelIeeeB"
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEB_MIN     (1)
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEB_MAX     (11)
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEB_DEFAULT (2)
+
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEB_NAME	"gBadPeerTxCtlPctLevelIeeeB"
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEB_MIN        (1)
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEB_MAX        (8)
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEB_DEFAULT    (1)
+
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEB_NAME	"gBadPeerTxCtlTputLevelIeeeB"
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEB_MIN       (1)
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEB_MAX       (11)
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEB_DEFAULT   (2)
+
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEB_NAME	"gBadPeerTxCtlTxLimitLevelIeeeB"
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEB_MIN      (0)
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEB_MAX      (50)
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEB_DEFAULT  (3)
+
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEAG_NAME	"gBadPeerTxCtlCondLevelIeeeAG"
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEAG_MIN         (1)
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEAG_MAX         (2)
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEAG_DEFAULT     (2)
+
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEAG_NAME	"gBadPeerTxCtlDeltaLevelIeeeAG"
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEAG_MIN        (6)
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEAG_MAX        (54)
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEAG_DEFAULT    (6)
+
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEAG_NAME	"gBadPeerTxCtlPctLevelIeeeAG"
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEAG_MIN          (1)
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEAG_MAX          (8)
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEAG_DEFAULT      (1)
+
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEAG_NAME	"gBadPeerTxCtlTputLevelIeeeAG"
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEAG_MIN         (6)
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEAG_MAX         (54)
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEAG_DEFAULT     (6)
+
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEAG_NAME	"gBadPeerTxCtlTxLimitLevelIeeeAG"
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEAG_MIN     (0)
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEAG_MAX     (50)
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEAG_DEFAULT (3)
+
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEN_NAME	"gBadPeerTxCtlCondLevelIeeeN"
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEN_MIN          (1)
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEN_MAX          (2)
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEN_DEFAULT      (2)
+
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEN_NAME	"gBadPeerTxCtlDeltaLevelIeeeN"
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEN_MIN         (6)
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEN_MAX         (72)
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEN_DEFAULT     (6)
+
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEN_NAME	"gBadPeerTxCtlPctLevelIeeeN"
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEN_MIN           (1)
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEN_MAX           (8)
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEN_DEFAULT       (1)
+
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEN_NAME	"gBadPeerTxCtlTputLevelIeeeN"
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEN_MIN          (6)
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEN_MAX          (72)
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEN_DEFAULT      (15)
+
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEN_NAME	"gBadPeerTxCtlTxLimitLevelIeeeN"
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEN_MIN      (0)
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEN_MAX      (50)
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEN_DEFAULT  (3)
+
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEAC_NAME	"gBadPeerTxCtlCondLevelIeeeAC"
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEAC_MIN         (1)
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEAC_MAX         (2)
+#define CFG_BAD_PEER_TX_CTL_COND_LEVEL_IEEEAC_DEFAULT     (2)
+
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEAC_NAME	"gBadPeerTxCtlDeltaLevelIeeeAC"
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEAC_MIN        (6)
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEAC_MAX        (433)
+#define CFG_BAD_PEER_TX_CTL_DELTA_LEVEL_IEEEAC_DEFAULT    (6)
+
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEAC_NAME	"gBadPeerTxCtlPctLevelIeeeAC"
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEAC_MIN          (1)
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEAC_MAX          (8)
+#define CFG_BAD_PEER_TX_CTL_PCT_LEVEL_IEEEAC_DEFAULT      (1)
+
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEAC_NAME	"gBadPeerTxCtlTputLevelIeeeAC"
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEAC_MIN         (6)
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEAC_MAX         (433)
+#define CFG_BAD_PEER_TX_CTL_TPUT_LEVEL_IEEEAC_DEFAULT     (15)
+
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEAC_NAME    "gBadPeerTxCtlTxLimitLevelIeeeAC"
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEAC_MIN     (0)
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEAC_MAX     (50)
+#define CFG_BAD_PEER_TX_CTL_TX_LIMIT_LEVEL_IEEEAC_DEFAULT (3)
+#endif
+
+
+/*
+ * Enable/Disable Thermal Mitigation feature
+ * Default: Enable
+ */
+#define CFG_THERMAL_MIGRATION_ENABLE_NAME      "gThermalMitigationEnable"
+#define CFG_THERMAL_MIGRATION_ENABLE_MIN       (0)
+#define CFG_THERMAL_MIGRATION_ENABLE_MAX       (1)
+#define CFG_THERMAL_MIGRATION_ENABLE_DEFAULT   (0)
+
+#define CFG_THROTTLE_PERIOD_NAME               "gThrottlePeriod"
+#define CFG_THROTTLE_PERIOD_MIN                (10)
+#define CFG_THROTTLE_PERIOD_MAX                (10000)
+#define CFG_THROTTLE_PERIOD_DEFAULT            (4000)
+
+/*
+ * Configure Throttle Period Different Level Duty Cycle in percentage
+ * When temperature measured is greater than threshold at particular level,
+ * then throtling level will get increased by one level and
+ * will reduce TX duty by the given percentage
+ */
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL0_NAME    "gThrottleDutyCycleLevel0"
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL0_MIN     (0)
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL0_MAX     (0)
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL0_DEFAULT (0)
+
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL1_NAME    "gThrottleDutyCycleLevel1"
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL1_MIN     (0)
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL1_MAX     (100)
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL1_DEFAULT (50)
+
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL2_NAME    "gThrottleDutyCycleLevel2"
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL2_MIN     (0)
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL2_MAX     (100)
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL2_DEFAULT (75)
+
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL3_NAME    "gThrottleDutyCycleLevel3"
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL3_MIN     (0)
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL3_MAX     (100)
+#define CFG_THROTTLE_DUTY_CYCLE_LEVEL3_DEFAULT (94)
+
+/*
+ * <ini>
+ * gMCAddrListEnable - Enable/Disable Multicast MAC Address List feature
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set default MAC Address
+ * Default: Enable
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_MC_ADDR_LIST_ENABLE_NAME          "gMCAddrListEnable"
+#define CFG_MC_ADDR_LIST_ENABLE_MIN           (0)
+#define CFG_MC_ADDR_LIST_ENABLE_MAX           (1)
+#define CFG_MC_ADDR_LIST_ENABLE_DEFAULT       (1)
+
+/*
+ * <ini>
+ * gEnableRXSTBC - Enables/disables Rx STBC capability in STA mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set default Rx STBC capability
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_RX_STBC                       "gEnableRXSTBC"
+#define CFG_ENABLE_RX_STBC_MIN                   (0)
+#define CFG_ENABLE_RX_STBC_MAX                   (1)
+#define CFG_ENABLE_RX_STBC_DEFAULT               (1)
+
+/*
+ * <ini>
+ * gEnableTXSTBC - Enables/disables Tx STBC capability in STA mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set default Tx STBC capability
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_TX_STBC                       "gEnableTXSTBC"
+#define CFG_ENABLE_TX_STBC_MIN                   (0)
+#define CFG_ENABLE_TX_STBC_MAX                   (1)
+#define CFG_ENABLE_TX_STBC_DEFAULT               (0)
+
+/*
+ * <ini>
+ * gTxLdpcEnable - Config Param to enable Tx LDPC capability
+ * @Min: 0
+ * @Max: 3
+ * @Default: 3
+ *
+ * This ini is used to enable/disable Tx LDPC capability
+ * 0 - disable
+ * 1 - HT LDPC enable
+ * 2 - VHT LDPC enable
+ * 3 - HT & VHT LDPC enable
+ *
+ * Related: STA/SAP/P2P/IBSS/NAN.
+ *
+ * Supported Feature: Concurrency/Standalone
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_TX_LDPC_ENABLE_FEATURE         "gTxLdpcEnable"
+#define CFG_TX_LDPC_ENABLE_FEATURE_MIN     (0)
+#define CFG_TX_LDPC_ENABLE_FEATURE_MAX     (3)
+#define CFG_TX_LDPC_ENABLE_FEATURE_DEFAULT (3)
+
+/*
+ * <ini>
+ * gEnableRXLDPC - Config Param to enable Rx LDPC capability
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable Rx LDPC capability
+ *
+ * Related: STA/SAP/P2P/IBSS/NAN.
+ *
+ * Supported Feature: Concurrency/Standalone
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_RX_LDPC                       "gEnableRXLDPC"
+#define CFG_ENABLE_RX_LDPC_MIN                   (0)
+#define CFG_ENABLE_RX_LDPC_MAX                   (1)
+#define CFG_ENABLE_RX_LDPC_DEFAULT               (0)
+
+
+#define CFG_DISABLE_LDPC_WITH_TXBF_AP             "gDisableLDPCWithTxbfAP"
+#define CFG_DISABLE_LDPC_WITH_TXBF_AP_MIN         (0)
+#define CFG_DISABLE_LDPC_WITH_TXBF_AP_MAX         (1)
+#define CFG_DISABLE_LDPC_WITH_TXBF_AP_DEFAULT     (0)
+
+/*
+ * <ini>
+ * gEnableSNRMonitoring - Enables SNR Monitoring
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set default snr monitor
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_SNR_MONITORING_NAME              "gEnableSNRMonitoring"
+#define CFG_ENABLE_SNR_MONITORING_MIN               (0)
+#define CFG_ENABLE_SNR_MONITORING_MAX               (1)
+#define CFG_ENABLE_SNR_MONITORING_DEFAULT           (0)
+
+/* SAR Thermal limit values for 2g and 5g */
+
+#define CFG_SET_TXPOWER_LIMIT2G_NAME               "TxPower2g"
+#define CFG_SET_TXPOWER_LIMIT2G_MIN                (0)
+#define CFG_SET_TXPOWER_LIMIT2G_MAX                (30)
+#define CFG_SET_TXPOWER_LIMIT2G_DEFAULT            (30)
+
+#define CFG_SET_TXPOWER_LIMIT5G_NAME               "TxPower5g"
+#define CFG_SET_TXPOWER_LIMIT5G_MIN                (0)
+#define CFG_SET_TXPOWER_LIMIT5G_MAX                (30)
+#define CFG_SET_TXPOWER_LIMIT5G_DEFAULT            (30)
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+
+/*
+ * <ini>
+ * TxFlowStopQueueThreshold - Stop queue Threshold to pause
+ *                            Netif queues when it reaches
+ * @Min: 0
+ * @Max: 50
+ * @Default: 15
+ *
+ * This ini specifies the threshold of data packets transmitted
+ * before pausing netif queues.
+ *
+ * Related: TxFlowStartQueueOffset
+ *
+ * Supported Feature: Dynamic Flow Control
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_LL_TX_FLOW_STOP_QUEUE_TH               "TxFlowStopQueueThreshold"
+#define CFG_LL_TX_FLOW_STOP_QUEUE_TH_DEFAULT       (15)
+#define CFG_LL_TX_FLOW_STOP_QUEUE_TH_MIN           (0)
+#define CFG_LL_TX_FLOW_STOP_QUEUE_TH_MAX           (50)
+
+/*
+ * <ini>
+ * TxFlowStartQueueOffset - Start queue offset to unpause
+ *                          Netif queues
+ * @Min: 0
+ * @Max: 30
+ * @Default: 11
+ *
+ * This ini specifies the offset to upause the netif queues
+ * when they are paused due to insufficient descriptors as guided by
+ * ini TxFlowStopQueueThreshold.
+ *
+ * Related: TxFlowStopQueueThreshold
+ *
+ * Supported Feature: Dynamic Flow Control
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_LL_TX_FLOW_START_QUEUE_OFFSET          "TxFlowStartQueueOffset"
+#define CFG_LL_TX_FLOW_START_QUEUE_OFFSET_DEFAULT  (10)
+#define CFG_LL_TX_FLOW_START_QUEUE_OFFSET_MIN      (0)
+#define CFG_LL_TX_FLOW_START_QUEUE_OFFSET_MAX      (30)
+
+#endif /* QCA_LL_TX_FLOW_CONTROL_V2 */
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+#define CFG_RA_RATE_LIMIT_INTERVAL_NAME            "gRArateLimitInterval"
+#define CFG_RA_RATE_LIMIT_INTERVAL_MIN             (60)
+#define CFG_RA_RATE_LIMIT_INTERVAL_MAX             (3600)
+#define CFG_RA_RATE_LIMIT_INTERVAL_DEFAULT         (60) /*60 SEC */
+#endif
+
+/*
+ * <ini>
+ * gEnableMemoryDebug - Enables the memory debug
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable default memory debug
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#ifdef MEMORY_DEBUG
+#define CFG_ENABLE_MEMORY_DEBUG_NAME             "gEnableMemoryDebug"
+#define CFG_ENABLE_MEMORY_DEBUG_MIN              (0)
+#define CFG_ENABLE_MEMORY_DEBUG_MAX              (1)
+#define CFG_ENABLE_MEMORY_DEBUG_DEFAULT          (1)
+#endif
+
+/*
+ * <ini>
+ * gInitialDwellTime - Used to set initial dwell time
+ * @Min: 0
+ * @Max: 0
+ * @Default: 100
+ *
+ * This ini is used to set default initial dwell time
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_INITIAL_DWELL_TIME_NAME            "gInitialDwellTime"
+#define CFG_INITIAL_DWELL_TIME_DEFAULT         (0)
+#define CFG_INITIAL_DWELL_TIME_MIN             (0)
+#define CFG_INITIAL_DWELL_TIME_MAX             (100)
+
+/*
+ * <ini>
+ * gInitialScanNoDFSChnl - WLAN skips scanning the DFS channels
+ * @Min: 0
+ * @Max: 0
+ * @Default: 1
+ *
+ * This ini is used to set for the first scan after driver
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_INITIAL_SCAN_NO_DFS_CHNL_NAME         "gInitialScanNoDFSChnl"
+#define CFG_INITIAL_SCAN_NO_DFS_CHNL_DEFAULT      (0)
+#define CFG_INITIAL_SCAN_NO_DFS_CHNL_MIN          (0)
+#define CFG_INITIAL_SCAN_NO_DFS_CHNL_MAX          (1)
+
+/*
+ * <ini>
+ * gAllowDFSChannelRoam - Allow dfs channel in roam
+ * @Min: 0
+ * @Max: 1
+ * @Default: 2
+ *
+ * This ini is used to set default dfs channel
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_ROAMING_DFS_CHANNEL_NAME               "gAllowDFSChannelRoam"
+#define CFG_ROAMING_DFS_CHANNEL_DISABLED           (0)
+#define CFG_ROAMING_DFS_CHANNEL_ENABLED_NORMAL     (1)
+#define CFG_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE     (2)
+#define CFG_ROAMING_DFS_CHANNEL_MIN                (CFG_ROAMING_DFS_CHANNEL_DISABLED)
+#define CFG_ROAMING_DFS_CHANNEL_MAX                (CFG_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE)
+#define CFG_ROAMING_DFS_CHANNEL_DEFAULT            (CFG_ROAMING_DFS_CHANNEL_DISABLED)
+
+#ifdef MSM_PLATFORM
+/*
+ * <ini>
+ * periodic_stats_display_time - time(seconds) after which stats will be printed
+ * @Min: 0
+ * @Max: 256
+ * @Default: 10
+ *
+ * This values specifies the recurring time period after which stats will be
+ * printed in wlan driver logs.
+ *
+ * Usage: Internal / External
+ *
+ * </ini>
+ */
+#define CFG_PERIODIC_STATS_DISPLAY_TIME_NAME       "periodic_stats_display_time"
+#define CFG_PERIODIC_STATS_DISPLAY_TIME_DEFAULT    (10)
+#define CFG_PERIODIC_STATS_DISPLAY_TIME_MIN        (0)
+#define CFG_PERIODIC_STATS_DISPLAY_TIME_MAX        (256)
+
+#endif /* MSM_PLATFORM */
+
+/*
+ * <ini>
+ * gIgnoreCAC - Used to ignore CAC
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set default CAC
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_IGNORE_CAC_NAME                        "gIgnoreCAC"
+#define CFG_IGNORE_CAC_MIN                         (0)
+#define CFG_IGNORE_CAC_MAX                         (1)
+#define CFG_IGNORE_CAC_DEFAULT                     (0)
+
+#define CFG_DFS_RADAR_PRI_MULTIPLIER_NAME          "gDFSradarMappingPriMultiplier"
+#define CFG_DFS_RADAR_PRI_MULTIPLIER_DEFAULT       (4)
+#define CFG_DFS_RADAR_PRI_MULTIPLIER_MIN           (0)
+#define CFG_DFS_RADAR_PRI_MULTIPLIER_MAX           (10)
+
+/*
+ * <ini>
+ * gReorderOffloadSupported - Packet reordering offload to firmware
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set default Packet reordering
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_REORDER_OFFLOAD_SUPPORT_NAME    "gReorderOffloadSupported"
+#define CFG_REORDER_OFFLOAD_SUPPORT_MIN     (0)
+#define CFG_REORDER_OFFLOAD_SUPPORT_MAX     (1)
+#define CFG_REORDER_OFFLOAD_SUPPORT_DEFAULT (1)
+
+#define CFG_ENABLE_SAP_SUSPEND                     "gEnableSapSuspend"
+#define CFG_ENABLE_SAP_SUSPEND_MIN                 (0)
+#define CFG_ENABLE_SAP_SUSPEND_MAX                 (1)
+#define CFG_ENABLE_SAP_SUSPEND_DEFAULT             (1)
+
+/*
+ * <ini>
+ * gEnableDeauthToDisassocMap - Enables deauth to disassoc map
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to set default  disassoc map
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_NAME    "gEnableDeauthToDisassocMap"
+#define CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_MIN     (0)
+#define CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_MAX     (1)
+#define CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_DEFAULT (0)
+
+#ifdef DHCP_SERVER_OFFLOAD
+#define CFG_DHCP_SERVER_IP_NAME     "gDHCPServerIP"
+#define CFG_DHCP_SERVER_IP_DEFAULT  ""
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#define CFG_ENABLE_MAC_ADDR_SPOOFING                "gEnableMacAddrSpoof"
+#define CFG_ENABLE_MAC_ADDR_SPOOFING_MIN            (0)
+#define CFG_ENABLE_MAC_ADDR_SPOOFING_MAX            (1)
+#define CFG_ENABLE_MAC_ADDR_SPOOFING_DEFAULT        (1)
+
+/*
+ * <ini>
+ * gStaMiracastMccRestTimeVal - Rest time when Miracast is running.
+ * @Min: 100
+ * @Max: 500
+ * @Default: 400
+ *
+ * This ini is used to set rest time for home channel for Miracast before
+ * going for scan.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_STA_MIRACAST_MCC_REST_TIME_VAL          "gStaMiracastMccRestTimeVal"
+#define CFG_STA_MIRACAST_MCC_REST_TIME_VAL_MIN     (100)
+#define CFG_STA_MIRACAST_MCC_REST_TIME_VAL_MAX     (500)
+#define CFG_STA_MIRACAST_MCC_REST_TIME_VAL_DEFAULT (400)
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+/*
+ * <ini>
+ * gSapChannelAvoidance - SAP MCC channel avoidance.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to sets sap mcc channel avoidance.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_SAP_MCC_CHANNEL_AVOIDANCE_NAME         "gSapChannelAvoidance"
+#define CFG_SAP_MCC_CHANNEL_AVOIDANCE_MIN          (0)
+#define CFG_SAP_MCC_CHANNEL_AVOIDANCE_MAX          (1)
+#define CFG_SAP_MCC_CHANNEL_AVOIDANCE_DEFAULT      (0)
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+/*
+ * <ini>
+ * gSAP11ACOverride - Override bw to 11ac for SAP in driver even if supplicant
+ *                    or hostapd configures HT.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable 11AC override for SAP.
+ * Android UI does not provide advanced configuration options
+ * for SoftAP for Android O and below.
+ * Default override disabled for android. Can be enabled from
+ * ini for Android O and below.
+ *
+ *
+ * Supported Feature: SAP
+ *
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_SAP_11AC_OVERRIDE_NAME             "gSAP11ACOverride"
+#define CFG_SAP_11AC_OVERRIDE_MIN              (0)
+#define CFG_SAP_11AC_OVERRIDE_MAX              (1)
+#define CFG_SAP_11AC_OVERRIDE_DEFAULT          (0)
+
+/*
+ * <ini>
+ * gGO11ACOverride - Override bw to 11ac for P2P GO
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable 11AC override for GO.
+ * P2P GO also follows start_bss and since P2P GO could not be
+ * configured to setup VHT channel width in wpa_supplicant, driver
+ * can override 11AC.
+ *
+ *
+ * Supported Feature: P2P
+ *
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_GO_11AC_OVERRIDE_NAME             "gGO11ACOverride"
+#define CFG_GO_11AC_OVERRIDE_MIN              (0)
+#define CFG_GO_11AC_OVERRIDE_MAX              (1)
+#define CFG_GO_11AC_OVERRIDE_DEFAULT          (1)
+
+#define CFG_ENABLE_NON_DFS_CHAN_ON_RADAR           "gPreferNonDfsChanOnRadar"
+#define CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_MIN       (0)
+#define CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_MAX       (1)
+#define CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_DEFAULT   (0)
+
+/*
+ * <ini>
+ * Max number of MSDUs per HTT RX IN ORDER INDICATION msg.
+ * Note that this has a direct impact on the size of source CE rings.
+ * It is possible to go below 8, but would require testing; so we are
+ * restricting the lower limit to 8 artificially
+ *
+ * It is recommended that this value is a POWER OF 2.
+ *
+ * Values lower than 8 are for experimental purposes only.
+ */
+#define CFG_MAX_MSDUS_PER_RXIND_NAME          "maxMSDUsPerRxInd"
+#define CFG_MAX_MSDUS_PER_RXIND_MIN           (4)
+#define CFG_MAX_MSDUS_PER_RXIND_MAX           (32)
+#define CFG_MAX_MSDUS_PER_RXIND_DEFAULT       (32)
+
+/*
+ * set the self gen power value from
+ * 0 to 0xffff
+ */
+#define CFG_SELF_GEN_FRM_PWR        "gSelfGenFrmPwr"
+#define CFG_SELF_GEN_FRM_PWR_MIN      (0)
+#define CFG_SELF_GEN_FRM_PWR_MAX      (0xffff)
+#define CFG_SELF_GEN_FRM_PWR_DEFAULT  (0)
+
+/*
+ * fine timing measurement capability information
+ *
+ * <----- fine_time_meas_cap (in bits) ----->
+ *+----------+-----+-----+------+------+-------+-------+-----+-----+
+ *|   8-31   |  7  |  6  |   5  |   4  |   3   |   2   |  1  |  0  |
+ *+----------+-----+-----+------+------+-------+-------+-----+-----+
+ *| reserved | SAP | SAP |P2P-GO|P2P-GO|P2P-CLI|P2P-CLI| STA | STA |
+ *|          |resp |init |resp  |init  |resp   |init   |resp |init |
+ *+----------+-----+-----+------+------+-------+-------+-----+-----+
+ *
+ * resp - responder role; init- initiator role
+ *
+ * CFG_FINE_TIME_MEAS_CAPABILITY_MAX computed based on the table
+ * +-----------------+-----------------+-----------+
+ * |  Device Role    |   Initiator     | Responder |
+ * +-----------------+-----------------+-----------+
+ * |   Station       |       Y         |     N     |
+ * |   P2P-CLI       |       Y         |     Y     |
+ * |   P2P-GO        |       Y         |     Y     |
+ * |   SAP           |       N         |     Y     |
+ * +-----------------+-----------------+-----------+
+ */
+#define CFG_FINE_TIME_MEAS_CAPABILITY              "gfine_time_meas_cap"
+#define CFG_FINE_TIME_MEAS_CAPABILITY_MIN          (0x0000)
+#define CFG_FINE_TIME_MEAS_CAPABILITY_MAX          (0x00BD)
+#define CFG_FINE_TIME_MEAS_CAPABILITY_DEFAULT      (0x000D)
+
+/*
+ * <ini>
+ * etsi13_srd_chan_in_master_mode - Enable/disable ETSI SRD channels in
+ * master mode PCL and ACS functionality
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * etsi13_srd_chan_in_master_mode is to enable/disable ETSI SRD channels in
+ * master mode PCL and ACS functionality
+ *
+ * Related: None
+ *
+ * Supported Feature: SAP/P2P-GO
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE    "etsi13_srd_chan_in_master_mode"
+#define CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE_DEF (0)
+#define CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE_MIN (0)
+#define CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE_MAX (1)
+
+/*
+ *
+ * <ini>
+ * gDualMacFeatureDisable - Disable Dual MAC feature.
+ * @Min: 0
+ * @Max: 4
+ * @Default: 0
+ *
+ * This ini is used to enable/disable dual MAC feature.
+ * 0 - enable DBS
+ * 1 - disable DBS
+ * 2 - disable DBS for connection but keep DBS for scan
+ * 3 - disable DBS for connection but keep DBS scan with async
+ * scan policy disabled
+ * 4 - enable DBS for connection as well as for scan with async
+ * scan policy disabled
+ * 5 - enable DBS for connection but disable DBS for scan.
+ * 6 - enable DBS for connection but disable simultaneous scan
+ * from upper layer (DBS scan remains enabled in FW).
+ *
+ * Note: INI item value should match 'enum dbs_support'
+ *
+ * Related: None.
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_DUAL_MAC_FEATURE_DISABLE              "gDualMacFeatureDisable"
+#define CFG_DUAL_MAC_FEATURE_DISABLE_MIN          (0)
+#define CFG_DUAL_MAC_FEATURE_DISABLE_MAX          (6)
+#define CFG_DUAL_MAC_FEATURE_DISABLE_DEFAULT      (0)
+
+/*
+ * <ini>
+ * gdbs_scan_selection - DBS Scan Selection.
+ * @Default: ""
+ *
+ * This ini is used to enable DBS scan selection.
+ * Example
+ * @Value: "5,2,2,16,2,2"
+ * 1st argument is module_id, 2nd argument is number of DBS scan,
+ * 3rd argument is number of non-DBS scan,
+ * and other arguments follows.
+ * 5,2,2,16,2,2 means:
+ * 5 is module id, 2 is num of DBS scan, 2 is num of non-DBS scan.
+ * 16 is module id, 2 is num of DBS scan, 2 is num of non-DBS scan.
+ *
+ * Related: None.
+ *
+ * Supported Feature: DBS Scan
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_DBS_SCAN_SELECTION_NAME          "gdbs_scan_selection"
+#define CFG_DBS_SCAN_SELECTION_DEFAULT       ""
+
+/*
+ * <ini>
+ * g_sta_sap_scc_on_dfs_chan - Allow STA+SAP SCC on DFS channel with master
+ * mode support disabled.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to allow STA+SAP SCC on DFS channel with master mode
+ * support disabled.
+ * 0 - Disallow STA+SAP SCC on DFS channel
+ * 1 - Allow STA+SAP SCC on DFS channel with master mode disabled
+ *
+ * Related: None.
+ *
+ * Supported Feature: Non-DBS, DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_STA_SAP_SCC_ON_DFS_CHAN              "g_sta_sap_scc_on_dfs_chan"
+#define CFG_STA_SAP_SCC_ON_DFS_CHAN_MIN          (0)
+#define CFG_STA_SAP_SCC_ON_DFS_CHAN_MAX          (1)
+#define CFG_STA_SAP_SCC_ON_DFS_CHAN_DEFAULT      (0)
+
+/*
+ * <ini>
+ * g_sta_sap_scc_on_lte_coex_chan - Allow STA+SAP SCC on LTE coex channel
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to allow STA+SAP SCC on LTE coex channel
+ * 0 - Disallow STA+SAP SCC on LTE coex channel
+ * 1 - Allow STA+SAP SCC on LTE coex channel
+ *
+ * Related: None.
+ *
+ * Supported Feature: Non-DBS, DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN              "g_sta_sap_scc_on_lte_coex_chan"
+#define CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN_MIN          (0)
+#define CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN_MAX          (1)
+#define CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN_DEFAULT      (0)
+
+/*
+ * gPNOChannelPrediction will allow user to enable/disable the
+ * PNO channel prediction feature.
+ * In current PNO implementation, scan is always done until all configured
+ * channels are scanned. If we can determine DUT is stationary based on
+ * scanning a subset of channels, we may cancel the remaining channels.
+ * Hence, we can save additional power consumption.
+ */
+#define CFG_PNO_CHANNEL_PREDICTION_NAME      "gPNOChannelPrediction"
+#define CFG_PNO_CHANNEL_PREDICTION_MIN       (0)
+#define CFG_PNO_CHANNEL_PREDICTION_MAX       (1)
+#define CFG_PNO_CHANNEL_PREDICTION_DEFAULT   (0)
+/*
+ * The top K number of channels are used for tanimoto distance
+ * calculation. These are the top channels on which the probability
+ * of finding the AP's is extremely high. This number is intended
+ * for tweaking the internal algorithm for experiments. This should
+ * not be changed externally.
+ */
+#define CFG_TOP_K_NUM_OF_CHANNELS_NAME      "gTopKNumOfChannels"
+#define CFG_TOP_K_NUM_OF_CHANNELS_MIN       (1)
+#define CFG_TOP_K_NUM_OF_CHANNELS_MAX       (5)
+#define CFG_TOP_K_NUM_OF_CHANNELS_DEFAULT   (3)
+/*
+ * This is the threshold value to determine that the STA is
+ * stationary. If the tanimoto distance is less than this
+ * value, then the device is considered to be stationary.
+ * This parameter is intended to tweak the internal algorithm
+ * for experiments. This should not be changed externally.
+ */
+#define CFG_STATIONARY_THRESHOLD_NAME      "gStationaryThreshold"
+#define CFG_STATIONARY_THRESHOLD_MIN       (0)
+#define CFG_STATIONARY_THRESHOLD_MAX       (100)
+#define CFG_STATIONARY_THRESHOLD_DEFAULT   (10)
+
+/* Option to report rssi in cfg80211_inform_bss_frame()
+ * 0 = use rssi value based on noise floor = -96 dBm
+ * 1 = use rssi value based on actual noise floor in hardware
+ */
+#define CFG_INFORM_BSS_RSSI_RAW_NAME               "gInformBssRssiRaw"
+#define CFG_INFORM_BSS_RSSI_RAW_MIN                (0)
+#define CFG_INFORM_BSS_RSSI_RAW_MAX                (1)
+#define CFG_INFORM_BSS_RSSI_RAW_DEFAULT            (1)
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+/* PTP options */
+#define CFG_SET_TSF_PTP_OPT_NAME                  "gtsf_ptp_options"
+#define CFG_SET_TSF_PTP_OPT_MIN                   (0)
+#define CFG_SET_TSF_PTP_OPT_MAX                   (0xff)
+#define CFG_SET_TSF_PTP_OPT_RX                    (0x1)
+#define CFG_SET_TSF_PTP_OPT_TX                    (0x2)
+#define CFG_SET_TSF_PTP_OPT_RAW                   (0x4)
+#define CFG_SET_TSF_DBG_FS                        (0x8)
+#define CFG_SET_TSF_PTP_OPT_DEFAULT               (0xf)
+#endif
+
+/*
+ * <ini>
+ * gEnableTxSchedWrrVO - Set TX sched parameters for VO
+ * @Default:
+ *
+ * This key is mapping to VO defined in data path module through
+ * OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC. The user can tune the
+ * WRR TX sched parameters such as skip, credit, limit, credit, disc for VO.
+ * e.g., gEnableTxSchedWrrVO = 10, 9, 8, 1, 8
+ */
+#define CFG_ENABLE_TX_SCHED_WRR_VO_NAME     "gEnableTxSchedWrrVO"
+#define CFG_ENABLE_TX_SCHED_WRR_VO_DEFAULT  ""
+
+/*
+ * <ini>
+ * gEnableTxSchedWrrVI - Set TX sched parameters for VI
+ * @Default:
+ *
+ * This key is mapping to VI defined in data path module through
+ * OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC. The user can tune the
+ * WRR TX sched parameters such as skip, credit, limit, credit, disc for VI.
+ * e.g., gEnableTxSchedWrrVI = 10, 9, 8, 1, 8
+ */
+#define CFG_ENABLE_TX_SCHED_WRR_VI_NAME     "gEnableTxSchedWrrVI"
+#define CFG_ENABLE_TX_SCHED_WRR_VI_DEFAULT  ""
+
+/*
+ * <ini>
+ * gEnableTxSchedWrrBE - Set TX sched parameters for BE
+ * @Default:
+ *
+ * This key is mapping to BE defined in data path module through
+ * OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC. The user can tune the
+ * WRR TX sched parameters such as skip, credit, limit, credit, disc for BE.
+ * e.g., gEnableTxSchedWrrBE = 10, 9, 8, 1, 8
+ */
+#define CFG_ENABLE_TX_SCHED_WRR_BE_NAME     "gEnableTxSchedWrrBE"
+#define CFG_ENABLE_TX_SCHED_WRR_BE_DEFAULT  ""
+
+/*
+ * <ini>
+ * gEnableTxSchedWrrBK - Set TX sched parameters for BK
+ * @Default:
+ *
+ * This key is mapping to BK defined in data path module through
+ * OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC. The user can tune the
+ * WRR TX sched parameters such as skip, credit, limit, credit, disc for BK.
+ * e.g., gEnableTxSchedWrrBK = 10, 9, 8, 1, 8
+ */
+#define CFG_ENABLE_TX_SCHED_WRR_BK_NAME     "gEnableTxSchedWrrBK"
+#define CFG_ENABLE_TX_SCHED_WRR_BK_DEFAULT  ""
+
+#ifdef CONFIG_DP_TRACE
+/*
+ * Enable/disable DPTRACE
+ * Enabling this might have performace impact.
+ */
+#define CFG_ENABLE_DP_TRACE		"enable_dp_trace"
+#define CFG_ENABLE_DP_TRACE_MIN		(0)
+#define CFG_ENABLE_DP_TRACE_MAX	(1)
+#define CFG_ENABLE_DP_TRACE_DEFAULT	(1)
+
+/* Max length of gDptraceConfig string. e.g.- "1, 6, 1, 62" */
+#define DP_TRACE_CONFIG_STRING_LENGTH		(20)
+
+/* At max 4 DP Trace config parameters are allowed. Refer - gDptraceConfig */
+#define DP_TRACE_CONFIG_NUM_PARAMS		(4)
+
+/*
+ * Default value of live mode in case it cannot be determined from cfg string
+ * gDptraceConfig
+ */
+#define DP_TRACE_CONFIG_DEFAULT_LIVE_MODE	(1)
+
+/*
+ * Default value of thresh (packets/second) beyond which DP Trace is disabled.
+ * Use this default in case the value cannot be determined from cfg string
+ * gDptraceConfig
+ */
+#define DP_TRACE_CONFIG_DEFAULT_THRESH		(6)
+
+/*
+ * Number of intervals of BW timer to wait before enabling/disabling DP Trace.
+ * Since throughput threshold to disable live logging for DP Trace is very low,
+ * we calculate throughput based on # packets received in a second.
+ * For example assuming bandwidth timer interval is 100ms, and if more than 6
+ * prints are received in 10 * 100 ms interval, we want to disable DP Trace
+ * live logging. DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT is the default
+ * value, to be used in case the real value cannot be derived from
+ * bw timer interval
+ */
+#define DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT (10)
+
+/* Default proto bitmap in case its missing in gDptraceConfig string */
+#define DP_TRACE_CONFIG_DEFAULT_BITMAP \
+			(QDF_NBUF_PKT_TRAC_TYPE_EAPOL |\
+			QDF_NBUF_PKT_TRAC_TYPE_DHCP |\
+			QDF_NBUF_PKT_TRAC_TYPE_MGMT_ACTION |\
+			QDF_NBUF_PKT_TRAC_TYPE_ARP |\
+			QDF_NBUF_PKT_TRAC_TYPE_ICMP |\
+			QDF_NBUF_PKT_TRAC_TYPE_ICMPv6)\
+
+/* Default verbosity, in case its missing in gDptraceConfig string*/
+#define DP_TRACE_CONFIG_DEFAULT_VERBOSTY QDF_DP_TRACE_VERBOSITY_LOW
+/*
+ * Config DPTRACE
+ * The sequence of params is important. If some param is missing, defaults are
+ * considered.
+ * Param 1: Enable/Disable DP Trace live mode (uint8_t)
+ * Param 2: DP Trace live mode high bandwidth thresh.(uint8_t)
+ *         (packets/second) beyond which DP Trace is disabled. Decimal Val.
+ *          MGMT, DHCP, EAPOL, ARP pkts are not counted. ICMP and Data are.
+ * Param 3: Default Verbosity (0-4)
+ * Param 4: Proto Bitmap (uint8_t). Decimal Value.
+ *          (decimal 62 = 0x3e)
+ * e.g., to disable live mode, use the following param in the ini file.
+ * gDptraceConfig = 0
+ * e.g., to enable dptrace live mode and set the thresh as 6,
+ * use the following param in the ini file.
+ * gDptraceConfig = 1, 6
+ */
+#define CFG_ENABLE_DP_TRACE_CONFIG		"gDptraceConfig"
+#define CFG_ENABLE_DP_TRACE_CONFIG_DEFAULT	"1, 6, 2, 126"
+#endif
+
+/*
+ * This parameter will set the weight to calculate the average low pass
+ * filter for channel congestion.
+ * Acceptable values for this: 0-100 (In %)
+ */
+#define CFG_ADAPT_DWELL_LPF_WEIGHT_NAME       "adapt_dwell_lpf_weight"
+#define CFG_ADAPT_DWELL_LPF_WEIGHT_MIN        (0)
+#define CFG_ADAPT_DWELL_LPF_WEIGHT_MAX        (100)
+#define CFG_ADAPT_DWELL_LPF_WEIGHT_DEFAULT    (80)
+
+/*
+ * This parameter will set interval to monitor wifi activity
+ * in passive scan in msec.
+ * Acceptable values for this: 0-25
+ */
+#define CFG_ADAPT_DWELL_PASMON_INTVAL_NAME     "adapt_dwell_passive_mon_intval"
+#define CFG_ADAPT_DWELL_PASMON_INTVAL_MIN      (0)
+#define CFG_ADAPT_DWELL_PASMON_INTVAL_MAX      (25)
+#define CFG_ADAPT_DWELL_PASMON_INTVAL_DEFAULT  (10)
+
+/*
+ * This parameter will set % of wifi activity used in passive scan 0-100.
+ * Acceptable values for this: 0-100 (in %)
+ */
+#define CFG_ADAPT_DWELL_WIFI_THRESH_NAME       "adapt_dwell_wifi_act_threshold"
+#define CFG_ADAPT_DWELL_WIFI_THRESH_MIN        (0)
+#define CFG_ADAPT_DWELL_WIFI_THRESH_MAX        (100)
+#define CFG_ADAPT_DWELL_WIFI_THRESH_DEFAULT    (10)
+
+/*
+ * <ini>
+ * restart_beaconing_on_chan_avoid_event - control the beaconing entity to move
+ * away from active LTE channels
+ * @Min: 0
+ * @Max: 2
+ * @Default: 1
+ *
+ * This ini is used to control the beaconing entity (SAP/GO) to move away from
+ * active LTE channels when channel avoidance event is received
+ * restart_beaconing_on_chan_avoid_event=0: Don't allow beaconing entity move
+ * from active LTE channels
+ * restart_beaconing_on_chan_avoid_event=1: Allow beaconing entity move from
+ * active LTE channels
+ * restart_beaconing_on_chan_avoid_event=2: Allow beaconing entity move from
+ * 2.4G active LTE channels only
+ *
+ * Related: None
+ *
+ * Supported Feature: channel avoidance
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_RESTART_BEACONING_ON_CH_AVOID_NAME    "restart_beaconing_on_chan_avoid_event"
+#define CFG_RESTART_BEACONING_ON_CH_AVOID_MIN     (CH_AVOID_RULE_DO_NOT_RESTART)
+#define CFG_RESTART_BEACONING_ON_CH_AVOID_MAX     (CH_AVOID_RULE_RESTART_24G_ONLY)
+#define CFG_RESTART_BEACONING_ON_CH_AVOID_DEFAULT (CH_AVOID_RULE_RESTART)
+
+/*
+ * <ini>
+ * num_dp_rx_threads - Control to set the number of dp rx threads
+ *
+ * @Min: 1
+ * @Max: 4
+ * @Default: 1
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_NUM_DP_RX_THREADS_NAME     "num_dp_rx_threads"
+#define CFG_NUM_DP_RX_THREADS_MIN      (1)
+#define CFG_NUM_DP_RX_THREADS_MAX      (4)
+#define CFG_NUM_DP_RX_THREADS_DEFAULT  (1)
+
+/*
+ * Support to start sap in indoor channel
+ * Customer can config this item to enable/disable sap in indoor channel
+ * Default: Disable
+ */
+#define CFG_INDOOR_CHANNEL_SUPPORT_NAME     "gindoor_channel_support"
+#define CFG_INDOOR_CHANNEL_SUPPORT_MIN      (0)
+#define CFG_INDOOR_CHANNEL_SUPPORT_MAX      (1)
+#define CFG_INDOOR_CHANNEL_SUPPORT_DEFAULT  (0)
+
+/*
+ * <ini>
+ * g_mark_sap_indoor_as_disable - Enable/Disable Indoor channel
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to mark the Indoor channel as
+ * disable when SAP start and revert it on SAP stop,
+ * so SAP will not turn on indoor channel and
+ * sta will not scan/associate and roam on indoor
+ * channels.
+ *
+ * Related: If g_mark_sap_indoor_as_disable set, turn the
+ * indoor channels to disable and update Wiphy & fw.
+ *
+ * Supported Feature: SAP/STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_MARK_INDOOR_AS_DISABLE_NAME     "g_mark_sap_indoor_as_disable"
+#define CFG_MARK_INDOOR_AS_DISABLE_MIN      (0)
+#define CFG_MARK_INDOOR_AS_DISABLE_MAX      (1)
+#define CFG_MARK_INDOOR_AS_DISABLE_DEFAULT  (0)
+
+/*
+ * Force softap to 11n, when gSapForce11NFor11AC is set to 1 from ini
+ * despite of hostapd.conf request for 11ac
+ */
+#define CFG_SAP_FORCE_11N_FOR_11AC_NAME    "gSapForce11NFor11AC"
+#define CFG_SAP_FORCE_11N_FOR_11AC_MIN     (0)
+#define CFG_SAP_FORCE_11N_FOR_11AC_MAX     (1)
+#define CFG_SAP_FORCE_11N_FOR_11AC_DEFAULT (0)
+
+#define CFG_GO_FORCE_11N_FOR_11AC_NAME    "gGoForce11NFor11AC"
+#define CFG_GO_FORCE_11N_FOR_11AC_MIN     (0)
+#define CFG_GO_FORCE_11N_FOR_11AC_MAX     (1)
+#define CFG_GO_FORCE_11N_FOR_11AC_DEFAULT (0)
+
+/*
+ * sap tx leakage threshold
+ * customer can set this value from 100 to 1000 which means
+ * sap tx leakage threshold is -10db to -100db
+ */
+#define CFG_SAP_TX_LEAKAGE_THRESHOLD_NAME    "gsap_tx_leakage_threshold"
+#define CFG_SAP_TX_LEAKAGE_THRESHOLD_MIN     (100)
+#define CFG_SAP_TX_LEAKAGE_THRESHOLD_MAX     (1000)
+#define CFG_SAP_TX_LEAKAGE_THRESHOLD_DEFAULT (310)
+
+
+/*
+ * Enable filtering of replayed multicast packets
+ * In a typical infrastructure setup, it is quite normal to receive
+ * replayed multicast packets. These packets may cause more harm than
+ * help if not handled properly. Providing a configuration option
+ * to enable filtering of such packets
+ */
+#define CFG_FILTER_MULTICAST_REPLAY_NAME    "enable_multicast_replay_filter"
+#define CFG_FILTER_MULTICAST_REPLAY_MIN      (0)
+#define CFG_FILTER_MULTICAST_REPLAY_MAX      (1)
+#define CFG_FILTER_MULTICAST_REPLAY_DEFAULT  (1)
+
+/*
+ * <ini>
+ * rx_wakelock_timeout - Amount of time to hold wakelock for RX unicast packets
+ * @Min: 0
+ * @Max: 100
+ * @Default: 50
+ *
+ * This ini item configures the amount of time, in milliseconds, that the driver
+ * should prevent system power collapse after receiving an RX unicast packet.
+ * A conigured value of 0 disables the RX Wakelock feature completely.
+ *
+ * Related: None.
+ *
+ * Supported Feature: RX Wakelock
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_RX_WAKELOCK_TIMEOUT_NAME     "rx_wakelock_timeout"
+#define CFG_RX_WAKELOCK_TIMEOUT_DEFAULT  (50)
+#define CFG_RX_WAKELOCK_TIMEOUT_MIN      (0)
+#define CFG_RX_WAKELOCK_TIMEOUT_MAX      (100)
+
+/*
+ * <ini>
+ * enable_5g_band_pref - Enable preference for 5G from INI.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ * This ini is used to enable 5G preference parameters.
+ *
+ * Related: 5g_rssi_boost_threshold, 5g_rssi_boost_factor, 5g_max_rssi_boost
+ * 5g_rssi_penalize_threshold, 5g_rssi_penalize_factor, 5g_max_rssi_penalize
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_5G_BAND_PREF_NAME             "enable_5g_band_pref"
+#define CFG_ENABLE_5G_BAND_PREF_MIN              (0)
+#define CFG_ENABLE_5G_BAND_PREF_MAX              (1)
+#define CFG_ENABLE_5G_BAND_PREF_DEFAULT          (0)
+
+/*
+ * <ini>
+ * 5g_rssi_boost_threshold - A_band_boost_threshold above which 5 GHz is favored.
+ * @Min: -55
+ * @Max: -70
+ * @Default: -60
+ * This ini is used to set threshold for 5GHz band preference.
+ *
+ * Related: 5g_rssi_boost_factor, 5g_max_rssi_boost
+ * 5g_rssi_penalize_threshold, 5g_rssi_penalize_factor, 5g_max_rssi_penalize
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_5G_RSSI_BOOST_THRESHOLD_NAME         "5g_rssi_boost_threshold"
+#define CFG_5G_RSSI_BOOST_THRESHOLD_MIN          (-55)
+#define CFG_5G_RSSI_BOOST_THRESHOLD_MAX          (-70)
+#define CFG_5G_RSSI_BOOST_THRESHOLD_DEFAULT      (-60)
+
+/*
+ * <ini>
+ * 5g_rssi_boost_factor - Factor by which 5GHz RSSI is boosted.
+ * @Min: 0
+ * @Max: 2
+ * @Default: 1
+ * This ini is used to set the 5Ghz boost factor.
+ *
+ * Related: 5g_rssi_boost_threshold, 5g_max_rssi_boost
+ * 5g_rssi_penalize_threshold, 5g_rssi_penalize_factor, 5g_max_rssi_penalize
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_5G_RSSI_BOOST_FACTOR_NAME            "5g_rssi_boost_factor"
+#define CFG_5G_RSSI_BOOST_FACTOR_MIN             (0)
+#define CFG_5G_RSSI_BOOST_FACTOR_MAX             (2)
+#define CFG_5G_RSSI_BOOST_FACTOR_DEFAULT         (1)
+
+/*
+ * <ini>
+ * 5g_max_rssi_boost - Maximum boost that can be applied to 5GHz RSSI.
+ * @Min: 0
+ * @Max: 20
+ * @Default: 10
+ * This ini is used to set maximum boost which can be given to a 5Ghz network.
+ *
+ * Related: 5g_rssi_boost_threshold, 5g_rssi_boost_factor
+ * 5g_rssi_penalize_threshold, 5g_rssi_penalize_factor, 5g_max_rssi_penalize
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_5G_MAX_RSSI_BOOST_NAME               "5g_max_rssi_boost"
+#define CFG_5G_MAX_RSSI_BOOST_MIN                (0)
+#define CFG_5G_MAX_RSSI_BOOST_MAX                (20)
+#define CFG_5G_MAX_RSSI_BOOST_DEFAULT            (10)
+
+/*
+ * <ini>
+ * 5g_rssi_penalize_threshold - A_band_penalize_threshold above which
+ * 5 GHz is not favored.
+ * @Min: -65
+ * @Max: -80
+ * @Default: -70
+ * This ini is used to set threshold for 5GHz band preference.
+ *
+ * Related: 5g_rssi_penalize_factor, 5g_max_rssi_penalize
+ * 5g_rssi_boost_threshold, 5g_rssi_boost_factor, 5g_max_rssi_boost
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_5G_RSSI_PENALIZE_THRESHOLD_NAME      "5g_rssi_penalize_threshold"
+#define CFG_5G_RSSI_PENALIZE_THRESHOLD_MIN       (-65)
+#define CFG_5G_RSSI_PENALIZE_THRESHOLD_MAX       (-80)
+#define CFG_5G_RSSI_PENALIZE_THRESHOLD_DEFAULT   (-70)
+
+/*
+ * <ini>
+ * 5g_rssi_penalize_factor - Factor by which 5GHz RSSI is penalizeed.
+ * @Min: 0
+ * @Max: 2
+ * @Default: 1
+ * This ini is used to set the 5Ghz penalize factor.
+ *
+ * Related: 5g_rssi_penalize_threshold, 5g_max_rssi_penalize
+ * 5g_rssi_boost_threshold, 5g_rssi_boost_factor, 5g_max_rssi_boost
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_5G_RSSI_PENALIZE_FACTOR_NAME         "5g_rssi_penalize_factor"
+#define CFG_5G_RSSI_PENALIZE_FACTOR_MIN          (0)
+#define CFG_5G_RSSI_PENALIZE_FACTOR_MAX          (2)
+#define CFG_5G_RSSI_PENALIZE_FACTOR_DEFAULT      (1)
+
+/*
+ * <ini>
+ * 5g_max_rssi_penalize - Maximum penalty that can be applied to 5GHz RSSI.
+ * @Min: 0
+ * @Max: 20
+ * @Default: 10
+ * This ini is used to set maximum penalty which can be given to a 5Ghz network.
+ *
+ * Related: 5g_rssi_penalize_threshold, 5g_rssi_penalize_factor
+ * 5g_rssi_boost_threshold, 5g_rssi_boost_factor, 5g_max_rssi_boost
+ *
+ * Supported Feature: 5G band preference
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_5G_MAX_RSSI_PENALIZE_NAME            "5g_max_rssi_penalize"
+#define CFG_5G_MAX_RSSI_PENALIZE_MIN             (0)
+#define CFG_5G_MAX_RSSI_PENALIZE_MAX             (20)
+#define CFG_5G_MAX_RSSI_PENALIZE_DEFAULT         (10)
+
+/*
+ * <ini>
+ * gPowerUsage - Preferred Power Usage
+ * @Min: Min
+ * @Max: Max
+ * @Default: Mod
+ *
+ * This ini is used to set the preferred power usage
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_POWER_USAGE_NAME                   "gPowerUsage"
+#define CFG_POWER_USAGE_MIN                    "Min"
+#define CFG_POWER_USAGE_MAX                    "Max"
+#define CFG_POWER_USAGE_DEFAULT                "Mod"
+
+/*
+ * <ini>
+ * gEnableImps - Enable/Disable IMPS
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/Disable IMPS(IdleModePowerSave) Mode
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_IMPS_NAME                   "gEnableImps"
+#define CFG_ENABLE_IMPS_MIN                    (0)
+#define CFG_ENABLE_IMPS_MAX                    (1)
+#define CFG_ENABLE_IMPS_DEFAULT                (1)
+
+/*
+ * <ini>
+ * gEnableBmps - Enable/Disable BMPS
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/Disable BMPS(BeaconModePowerSave) Mode
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_PS_NAME                     "gEnableBmps"
+#define CFG_ENABLE_PS_MIN                      (0)
+#define CFG_ENABLE_PS_MAX                      (1)
+#define CFG_ENABLE_PS_DEFAULT                  (1)
+
+/*
+ * <ini>
+ * gAutoBmpsTimerValue - Set Auto BMPS Timer value
+ * @Min: 0
+ * @Max: 120
+ * @Default: 90
+ *
+ * This ini is used to set Auto BMPS Timer value in seconds
+ *
+ * Related: gEnableBmps
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_AUTO_PS_ENABLE_TIMER_NAME          "gAutoBmpsTimerValue"
+#define CFG_AUTO_PS_ENABLE_TIMER_MIN           (0)
+#define CFG_AUTO_PS_ENABLE_TIMER_MAX           (120)
+#define CFG_AUTO_PS_ENABLE_TIMER_DEFAULT       (90)
+
+#ifdef WLAN_ICMP_DISABLE_PS
+/*
+ * <ini>
+ * gIcmpDisablePsValue - Set ICMP packet disable power save value
+ * @Min:     0
+ * @Max:     10000
+ * @Default: 5000
+ *
+ * This ini is used to set ICMP packet disable power save value in
+ * millisecond.
+ *
+ * Related: gEnableBmps
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ICMP_DISABLE_PS_NAME               "gIcmpDisablePsValue"
+#define CFG_ICMP_DISABLE_PS_MIN                (0)
+#define CFG_ICMP_DISABLE_PS_MAX                (10000)
+#define CFG_ICMP_DISABLE_PS_DEFAULT            (5000)
+#endif
+
+/*
+ * <ini>
+ * gBmpsMinListenInterval - Set BMPS Minimum Listen Interval
+ * @Min: 1
+ * @Max: 65535
+ * @Default: 1
+ *
+ * This ini is used to set BMPS Minimum Listen Interval. If gPowerUsage
+ * is set "Min", this INI need to be set.
+ *
+ * Related: gEnableBmps, gPowerUsage
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BMPS_MINIMUM_LI_NAME               "gBmpsMinListenInterval"
+#define CFG_BMPS_MINIMUM_LI_MIN                (1)
+#define CFG_BMPS_MINIMUM_LI_MAX                (65535)
+#define CFG_BMPS_MINIMUM_LI_DEFAULT            (1)
+
+/*
+ * <ini>
+ * gBmpsMaxListenInterval - Set BMPS Maximum Listen Interval
+ * @Min: 1
+ * @Max: 65535
+ * @Default: 1
+ *
+ * This ini is used to set BMPS Maximum Listen Interval. If gPowerUsage
+ * is set "Max", this INI need to be set.
+ *
+ * Related: gEnableBmps, gPowerUsage
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BMPS_MAXIMUM_LI_NAME               "gBmpsMaxListenInterval"
+#define CFG_BMPS_MAXIMUM_LI_MIN                (1)
+#define CFG_BMPS_MAXIMUM_LI_MAX                (65535)
+#define CFG_BMPS_MAXIMUM_LI_DEFAULT            (1)
+
+#ifdef FEATURE_RUNTIME_PM
+/*
+ * <ini>
+ * gRuntimePM - enable runtime suspend
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable runtime_suspend
+ *
+ * Related: None
+ *
+ * Supported Feature: Power Save
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_RUNTIME_PM                  "gRuntimePM"
+#define CFG_ENABLE_RUNTIME_PM_MIN              (0)
+#define CFG_ENABLE_RUNTIME_PM_MAX              (1)
+#define CFG_ENABLE_RUNTIME_PM_DEFAULT          (0)
+#endif
+
+/*
+ * <ini>
+ * gActiveUcBpfMode - Control UC active APF mode
+ * @Min: 0 (disabled)
+ * @Max: 2 (adaptive)
+ * @Default: 0 (disabled)
+ *
+ * This config item controls UC APF in active mode. There are 3 modes:
+ *	0) disabled - APF is disabled in active mode
+ *	1) enabled - APF is enabled for all packets in active mode
+ *	2) adaptive - APF is enabled for packets up to some throughput threshold
+ *
+ * Related: gActiveMcBcBpfMode
+ *
+ * Supported Feature: Active Mode APF
+ *
+ * Usage: Internal/External
+ * </ini>
+ */
+#define CFG_ACTIVE_UC_APF_MODE_NAME    "gActiveUcBpfMode"
+#define CFG_ACTIVE_UC_APF_MODE_MIN     (ACTIVE_APF_DISABLED)
+#define CFG_ACTIVE_UC_APF_MODE_MAX     (ACTIVE_APF_MODE_COUNT - 1)
+#define CFG_ACTIVE_UC_APF_MODE_DEFAULT (ACTIVE_APF_DISABLED)
+
+/*
+ * <ini>
+ * gActiveMcBcBpfMode - Control MC/BC active APF mode
+ * @Min: 0 (disabled)
+ * @Max: 1 (enabled)
+ * @Default: 0 (disabled)
+ *
+ * This config item controls MC/BC APF in active mode. There are 3 modes:
+ *	0) disabled - APF is disabled in active mode
+ *	1) enabled - APF is enabled for all packets in active mode
+ *	2) adaptive - APF is enabled for packets up to some throughput threshold
+ *
+ * Related: gActiveUcBpfMode
+ *
+ * Supported Feature: Active Mode APF
+ *
+ * Usage: Internal/External
+ * </ini>
+ */
+#define CFG_ACTIVE_MC_BC_APF_MODE_NAME    "gActiveMcBcBpfMode"
+#define CFG_ACTIVE_MC_BC_APF_MODE_MIN     (ACTIVE_APF_DISABLED)
+#define CFG_ACTIVE_MC_BC_APF_MODE_MAX     (ACTIVE_APF_ENABLED)
+#define CFG_ACTIVE_MC_BC_APF_MODE_DEFAULT (ACTIVE_APF_DISABLED)
+
+#ifdef WLAN_FEATURE_11AX
+/* 11AX related INI configuration */
+/*
+ * <ini>
+ * he_dynamic_frag_support - configure dynamic fragmentation
+ * @Min: 0
+ * @Max: 3
+ * @Default: 1
+ *
+ * This ini is used to configure dynamic fragmentation.
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AX
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_HE_DYNAMIC_FRAGMENTATION_NAME    "he_dynamic_frag_support"
+#define CFG_HE_DYNAMIC_FRAGMENTATION_MIN     (0)
+#define CFG_HE_DYNAMIC_FRAGMENTATION_MAX     (3)
+#define CFG_HE_DYNAMIC_FRAGMENTATION_DEFAULT (0)
+
+/*
+ * <ini>
+ * enable_ul_mimo- Enable UL MIMO.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable or disable UL MIMO.
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AX
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_UL_MIMO_NAME    "enable_ul_mimo"
+#define CFG_ENABLE_UL_MIMO_MIN     (0)
+#define CFG_ENABLE_UL_MIMO_MAX     (1)
+#define CFG_ENABLE_UL_MIMO_DEFAULT (0)
+
+/*
+ * <ini>
+ * enable_ul_ofdma- Enable UL OFDMA.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable or disable UL OFDMA.
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AX
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_UL_OFDMA_NAME    "enable_ul_ofdma"
+#define CFG_ENABLE_UL_OFDMA_MIN     (0)
+#define CFG_ENABLE_UL_OFDMA_MAX     (1)
+#define CFG_ENABLE_UL_OFDMA_DEFAULT (0)
+
+/*
+ * <ini>
+ * he_sta_obsspd- 11AX HE OBSS PD bit field
+ * @Min: 0
+ * @Max: uin32_t max
+ * @Default: 0x15b8c2ae
+ *
+ * 4 Byte value with each byte representing a signed value for following params:
+ * Param                   Bit position    Default
+ * OBSS_PD min (primary)   7:0             -82 (0xae)
+ * OBSS_PD max (primary)   15:8            -62 (0xc2)
+ * Secondary channel Ed    23:16           -72 (0xb8)
+ * TX_PWR(ref)             31:24           21  (0x15)
+ * This bit field value is directly applied to FW
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AX
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_HE_STA_OBSSPD_NAME    "he_sta_obsspd"
+#define CFG_HE_STA_OBSSPD_MIN     (0)
+#define CFG_HE_STA_OBSSPD_MAX     (0xffffffff)
+#define CFG_HE_STA_OBSSPD_DEFAULT (0x15b8c2ae)
+
+#endif /* WLAN_FEATURE_11AX */
+#ifdef WLAN_SUPPORT_TWT
+/*
+ * <ini>
+ * enable_twt - Enable Target Wake Time support.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable or disable TWT support.
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AX
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_TWT_NAME    "enable_twt"
+#define CFG_ENABLE_TWT_MIN     (0)
+#define CFG_ENABLE_TWT_MAX     (1)
+#define CFG_ENABLE_TWT_DEFAULT (1)
+
+/*
+ * <ini>
+ * twt_congestion_timeout - Target wake time congestion timeout.
+ * @Min: 0
+ * @Max: 10000
+ * @Default: 100
+ *
+ * STA uses this timer to continuously monitor channel congestion levels to
+ * decide whether to start or stop TWT. This ini is used to configure the
+ * target wake time congestion timeout value in the units of milliseconds.
+ * A value of Zero indicates that this is a host triggered TWT and all the
+ * necessary configuration for TWT will be directed from the host.
+ *
+ * Related: NA
+ *
+ * Supported Feature: 11AX
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_TWT_CONGESTION_TIMEOUT_NAME    "twt_congestion_timeout"
+#define CFG_TWT_CONGESTION_TIMEOUT_MIN     (0)
+#define CFG_TWT_CONGESTION_TIMEOUT_MAX     (10000)
+#define CFG_TWT_CONGESTION_TIMEOUT_DEFAULT (100)
+
+#endif /* WLAN_SUPPORT_TWT */
+
+/*
+ * <ini>
+ * gScanBackoffMultiplier - For NLO/PNO, multiply fast scan period by this every
+ *	max cycles
+ * @Min: 0
+ * @Max: 255
+ * @Default: 0
+ *
+ * For Network Listen Offload and Perfered Network Offload, multiply the fast
+ * scan period by this value after max cycles have occurred. Setting this to 0
+ * disables the feature.
+ *
+ * @E.g.
+ *	# Disable scan backoff multiplier
+ *	gScanBackoffMultiplier=0
+ *	# Effectively the same
+ *	gScanBackoffMultiplier=1
+ *	# Double the scan period after each max cycles have occurred
+ *	gScanBackoffMultiplier=2
+ *
+ * Related: NLO, PNO
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_SCAN_BACKOFF_MULTIPLIER_NAME	"gScanBackoffMultiplier"
+#define CFG_SCAN_BACKOFF_MULTIPLIER_MIN		(0)
+#define CFG_SCAN_BACKOFF_MULTIPLIER_MAX		(255)
+#define CFG_SCAN_BACKOFF_MULTIPLIER_DEFAULT	(0)
+
+/*
+ * <ini>
+ * mawc_nlo_enabled - For NLO/PNO, enable MAWC based scan
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * Enable/Disable the Motion Aided Wireless Connectivity
+ * based NLO using this parameter
+ *
+ * Related: NLO, PNO
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_MAWC_NLO_ENABLED_NAME	"mawc_nlo_enabled"
+#define CFG_MAWC_NLO_ENABLED_MIN	(0)
+#define CFG_MAWC_NLO_ENABLED_MAX	(1)
+#define CFG_MAWC_NLO_ENABLED_DEFAULT	(1)
+
+/*
+ * <ini>
+ * mawc_nlo_exp_backoff_ratio - Exponential back off ratio
+ * @Min: 0
+ * @Max: 300
+ * @Default: 3
+ *
+ * Configure the exponential back off ratio using this
+ * parameter for MAWC based NLO
+ * ratio of exponential backoff, next = current + current*ratio/100
+ *
+ * Related: NLO, PNO
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_MAWC_NLO_EXP_BACKOFF_RATIO_NAME     "mawc_nlo_exp_backoff_ratio"
+#define CFG_MAWC_NLO_EXP_BACKOFF_RATIO_MIN      (0)
+#define CFG_MAWC_NLO_EXP_BACKOFF_RATIO_MAX      (300)
+#define CFG_MAWC_NLO_EXP_BACKOFF_RATIO_DEFAULT  (3)
+
+/*
+ * <ini>
+ * mawc_nlo_init_scan_interval - Initial Scan Interval
+ * @Min: 1000
+ * @Max: 0xFFFFFFFF
+ * @Default: 10000
+ *
+ * Configure the initial scan interval  using this
+ * parameter for MAWC based NLO (Units in Milliseconds)
+ *
+ * Related: NLO, PNO
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_MAWC_NLO_INIT_SCAN_INTERVAL_NAME     "mawc_nlo_init_scan_interval"
+#define CFG_MAWC_NLO_INIT_SCAN_INTERVAL_MIN      (1000)
+#define CFG_MAWC_NLO_INIT_SCAN_INTERVAL_MAX      (0xFFFFFFFF)
+#define CFG_MAWC_NLO_INIT_SCAN_INTERVAL_DEFAULT  (10000)
+
+/*
+ * <ini>
+ * mawc_nlo_max_scan_interval - Maximum Scan Interval
+ * @Min: 1000
+ * @Max: 0xFFFFFFFF
+ * @Default: 60000
+ *
+ * Configure the maximum scan interval  using this
+ * parameter for MAWC based NLO (Units in Milliseconds)
+ *
+ * Related: NLO, PNO
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_MAWC_NLO_MAX_SCAN_INTERVAL_NAME     "mawc_nlo_max_scan_interval"
+#define CFG_MAWC_NLO_MAX_SCAN_INTERVAL_MIN      (1000)
+#define CFG_MAWC_NLO_MAX_SCAN_INTERVAL_MAX      (0xFFFFFFFF)
+#define CFG_MAWC_NLO_MAX_SCAN_INTERVAL_DEFAULT  (60000)
+
+/*
+ * <ini>
+ * gEnableLPRx - Enable/Disable LPRx
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini Enables or disables the LPRx in FW
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_LPRx_NAME       "gEnableLPRx"
+#define CFG_LPRx_MIN         (0)
+#define CFG_LPRx_MAX         (1)
+#define CFG_LPRx_DEFAULT     (1)
+
+/*
+ * <ini>
+ * scan_11d_interval - 11d scan interval in ms
+ * @Min: 1 sec
+ * @Max: 10 hr
+ * @Default: 1 hr
+ *
+ * This ini sets the 11d scan interval in FW
+ *
+ *
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_SCAN_11D_INTERVAL_NAME      "scan_11d_interval"
+#define CFG_SCAN_11D_INTERVAL_DEFAULT   (3600000)
+#define CFG_SCAN_11D_INTERVAL_MIN       (1000)
+#define CFG_SCAN_11D_INTERVAL_MAX       (36000000)
+/*
+ * <ini>
+ * is_bssid_hint_priority - Set priority for connection with bssid_hint
+ * BSSID.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to give priority to BSS for connection which comes
+ * as part of bssid_hint
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_IS_BSSID_HINT_PRIORITY_NAME    "is_bssid_hint_priority"
+#define CFG_IS_BSSID_HINT_PRIORITY_DEFAULT (0)
+#define CFG_IS_BSSID_HINT_PRIORITY_MIN     (0)
+#define CFG_IS_BSSID_HINT_PRIORITY_MAX     (1)
+
+/*
+ * <ini>
+ * sae_enabled - Enable/Disable SAE support in driver
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable SAE support in driver
+ * Driver will update config to supplicant based on this config.
+ *
+ * Related: None
+ *
+ * Supported Feature: SAE
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_IS_SAE_ENABLED_NAME    "sae_enabled"
+#define CFG_IS_SAE_ENABLED_DEFAULT (1)
+#define CFG_IS_SAE_ENABLED_MIN     (0)
+#define CFG_IS_SAE_ENABLED_MAX     (1)
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+/*
+ * <ini>
+ * g_enable_packet_filter_bitmap - Enable Packet filters before going into
+ * suspend mode
+ * @Min: 0
+ * @Max: 63
+ * @Default: 0
+ * Below is the Detailed bit map of the Filters
+ * bit-0 : IPv6 multicast
+ * bit-1 : IPv4 multicast
+ * bit-2 : IPv4 broadcast
+ * bit-3 : XID - Exchange station Identification packet, solicits the
+ * identification of the receiving station
+ * bit-4 : STP - Spanning Tree Protocol, builds logical loop free topology
+ * bit-5 : DTP/LLC/CDP
+ * DTP - Dynamic Trunking Protocol is used by Ciscoswitches to negotiate
+ * whether an interconnection between two switches should be put into access or
+ * trunk mode
+ * LLC - Logical link control, used for multiplexing, flow & error control
+ * CDP - Cisco Discovery Protocol packet contains information about the cisco
+ * devices in the network
+ *
+ * This ini support to enable above mentioned packet filters
+ * when target goes to suspend mode, clear those when resume
+ *
+ * Related: None
+ *
+ * Supported Feature: PACKET FILTERING
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_PACKET_FILTERS_NAME     "g_enable_packet_filter_bitmap"
+#define CFG_ENABLE_PACKET_FILTERS_DEFAULT  (0)
+#define CFG_ENABLE_PACKET_FILTERS_MIN      (0)
+#define CFG_ENABLE_PACKET_FILTERS_MAX      (63)
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+
+/*
+ * <ini>
+ * gDfsBeaconTxEnhanced - beacon tx enhanced
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enhance dfs beacon tx
+ *
+ * Related: none
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_DFS_BEACON_TX_ENHANCED         "gDfsBeaconTxEnhanced"
+#define CFG_DFS_BEACON_TX_ENHANCED_MIN     (0)
+#define CFG_DFS_BEACON_TX_ENHANCED_MAX     (1)
+#define CFG_DFS_BEACON_TX_ENHANCED_DEFAULT (0)
+
+/*
+ * <ini>
+ * btm_offload_config - Configure BTM
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * This ini is used to configure BTM
+ *
+ * Bit 0: Enable/Disable the BTM offload. Set this to 1 will
+ * enable and 0 will disable BTM offload.
+ *
+ * BIT 2, 1: Action on non matching candidate with cache. If a BTM request
+ * is received from AP then the candidate AP's may/may-not be present in
+ * the firmware scan cache . Based on below config firmware will decide
+ * whether to forward BTM frame to host or consume with firmware and proceed
+ * with Roaming to candidate AP.
+ * 00 scan and consume
+ * 01 no scan and forward to host
+ * 10, 11 reserved
+ *
+ * BIT 5, 4, 3: Roaming handoff decisions on multiple candidates match
+ * 000 match if exact BSSIDs are found
+ * 001 match if at least one top priority BSSID only
+ * 010, 011, 100, 101, 110, 111 reserved
+ *
+ * BIT 6: Set this to 1 will send BTM query frame and 0 not sent.
+ *
+ * BIT 7-31: Reserved
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BTM_ENABLE_NAME      "btm_offload_config"
+#define CFG_BTM_ENABLE_MIN       (0x00000000)
+#define CFG_BTM_ENABLE_MAX       (0xffffffff)
+#define CFG_BTM_ENABLE_DEFAULT   (0x00000001)
+
+/*
+ * <ini>
+ * btm_solicited_timeout - timeout value for waiting BTM request
+ * @Min: 1
+ * @Max: 10000
+ * @Default: 100
+ *
+ * This ini is used to configure timeout value for waiting BTM request.
+ * Unit: millionsecond
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BTM_SOLICITED_TIMEOUT           "btm_solicited_timeout"
+#define CFG_BTM_SOLICITED_TIMEOUT_MIN       (1)
+#define CFG_BTM_SOLICITED_TIMEOUT_MAX       (10000)
+#define CFG_BTM_SOLICITED_TIMEOUT_DEFAULT   (100)
+
+/*
+ * <ini>
+ * btm_max_attempt_cnt - Maximum attempt for sending BTM query to ESS
+ * @Min: 1
+ * @Max: 0xFFFFFFFF
+ * @Default: 3
+ *
+ * This ini is used to configure maximum attempt for sending BTM query to ESS.
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BTM_MAX_ATTEMPT_CNT           "btm_max_attempt_cnt"
+#define CFG_BTM_MAX_ATTEMPT_CNT_MIN       (0x00000001)
+#define CFG_BTM_MAX_ATTEMPT_CNT_MAX       (0xFFFFFFFF)
+#define CFG_BTM_MAX_ATTEMPT_CNT_DEFAULT   (0x00000003)
+
+/*
+ * <ini>
+ * sticky_time - Stick time after roaming to new AP by BTM
+ * @Min: 0
+ * @Max: 0x0000FFFF
+ * @Default: 300
+ *
+ * This ini is used to configure Stick time after roaming to new AP by BTM.
+ * Unit: seconds
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_BTM_STICKY_TIME           "btm_sticky_time"
+#define CFG_BTM_STICKY_TIME_MIN       (0x00000000)
+#define CFG_BTM_STICKY_TIME_MAX       (0x0000FFFF)
+#define CFG_BTM_STICKY_TIME_DEFAULT   (300)
+
+/*
+ * <ini>
+ * gcmp_enabled - ini to enable/disable GCMP
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Currently Firmware update the sequence number for each TID with 2^3
+ * because of security issues. But with this PN mechanism, throughput drop
+ * is observed. With this ini FW takes the decision to trade off between
+ * security and throughput
+ *
+ * Supported Feature: STA/SAP/P2P
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_ENABLE_GCMP_NAME    "gcmp_enabled"
+#define CFG_ENABLE_GCMP_MIN     (0)
+#define CFG_ENABLE_GCMP_MAX     (1)
+#define CFG_ENABLE_GCMP_DEFAULT (1)
+
+/*
+ * <ini>
+ * 11k_offload_enable_bitmask - Bitmask to enable 11k offload to FW
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set which of the 11k features is offloaded to FW
+ * Currently Neighbor Report Request is supported for offload and is enabled
+ * by default
+ * B0: Offload 11k neighbor report requests
+ * B1-B31: Reserved
+ *
+ * Related : None
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_OFFLOAD_11K_ENABLE_BITMASK_NAME    "11k_offload_enable_bitmask"
+#define CFG_OFFLOAD_11K_ENABLE_BITMASK_MIN     (0)
+#define CFG_OFFLOAD_11K_ENABLE_BITMASK_MAX     (1)
+#define CFG_OFFLOAD_11K_ENABLE_BITMASK_DEFAULT (1)
+
+#define OFFLOAD_11K_BITMASK_NEIGHBOR_REPORT_REQUEST  0x1
+/*
+ * <ini>
+ * nr_offload_params_bitmask - bitmask to specify which of the
+ * neighbor report offload params are valid in the ini
+ * frame
+ * @Min: 0
+ * @Max: 63
+ * @Default: 63
+ *
+ * This ini specifies which of the neighbor report offload params are valid
+ * and should be considered by the FW. The bitmask is as follows
+ * B0: nr_offload_time_offset
+ * B1: nr_offload_low_rssi_offset
+ * B2: nr_offload_bmiss_count_trigger
+ * B3: nr_offload_per_threshold_offset
+ * B4: nr_offload_cache_timeout
+ * B5: nr_offload_max_req_cap
+ * B6-B7: Reserved
+ *
+ * Related : 11k_offload_enable_bitmask
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_PARAMS_BITMASK_NAME \
+	"nr_offload_params_bitmask"
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_PARAMS_BITMASK_MIN      (0)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_PARAMS_BITMASK_MAX      (63)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_PARAMS_BITMASK_DEFAULT  (63)
+
+/*
+ * <ini>
+ * nr_offload_time_offset - time interval in seconds after the
+ * neighbor report offload command to send the first neighbor report request
+ * frame
+ * @Min: 0
+ * @Max: 3600
+ * @Default: 30
+ *
+ * Related : nr_offload_params_bitmask
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_TIME_OFFSET_NAME \
+	"nr_offload_time_offset"
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_TIME_OFFSET_MIN      (0)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_TIME_OFFSET_MAX      (3600)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_TIME_OFFSET_DEFAULT  (30)
+
+/*
+ * <ini>
+ * nr_offload_low_rssi_offset - offset from the roam RSSI threshold
+ * to trigger the neighbor report request frame (in dBm)
+ * @Min: 4
+ * @Max: 10
+ * @Default: 4
+ *
+ * Related : nr_offload_params_bitmask
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_LOW_RSSI_OFFSET_NAME \
+	"nr_offload_low_rssi_offset"
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_LOW_RSSI_OFFSET_MIN     (4)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_LOW_RSSI_OFFSET_MAX     (10)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_LOW_RSSI_OFFSET_DEFAULT (4)
+
+/*
+ * <ini>
+ * nr_offload_bmiss_count_trigger - Number of beacon miss events to
+ * trigger a neighbor report request frame
+ * @Min: 1
+ * @Max: 5
+ * @Default: 1
+ *
+ * Related : nr_offload_params_bitmask
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_BMISS_COUNT_TRIGGER_NAME \
+	"nr_offload_bmiss_count_trigger"
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_BMISS_COUNT_TRIGGER_MIN     (1)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_BMISS_COUNT_TRIGGER_MAX     (5)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_BMISS_COUNT_TRIGGER_DEFAULT (1)
+
+/*
+ * <ini>
+ * nr_offload_per_threshold_offset - offset from PER threshold to
+ * trigger a neighbor report request frame (in %)
+ * @Min: 5
+ * @Max: 20
+ * @Default: 5
+ *
+ * This ini is used to set the neighbor report offload parameter:
+ *
+ * Related : nr_offload_params_bitmask
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_PER_THRESHOLD_OFFSET_NAME \
+	"nr_offload_per_threshold_offset"
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_PER_THRESHOLD_OFFSET_MIN     (5)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_PER_THRESHOLD_OFFSET_MAX     (20)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_PER_THRESHOLD_OFFSET_DEFAULT (5)
+
+/*
+ * <ini>
+ * nr_offload_cache_timeout - time in seconds after which the
+ * neighbor report cache is marked as timed out and any of the triggers would
+ * cause a neighbor report request frame to be sent.
+ * @Min: 5
+ * @Max: 86400
+ * @Default: 1200
+ *
+ * Related : nr_offload_params_bitmask
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_CACHE_TIMEOUT_NAME \
+	"nr_offload_cache_timeout"
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_CACHE_TIMEOUT_MIN     (5)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_CACHE_TIMEOUT_MAX     (86400)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_CACHE_TIMEOUT_DEFAULT (1200)
+
+/*
+ * <ini>
+ * nr_offload_max_req_cap - Max number of neighbor
+ * report requests that can be sent to a connected peer in the current session.
+ * This counter is reset once a successful roam happens or at cache timeout
+ * @Min: 3
+ * @Max: 300
+ * @Default: 3
+ *
+ * Related : nr_offload_params_bitmask
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_NAME \
+	"nr_offload_max_req_cap"
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_MIN     (3)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_MAX     (300)
+#define CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_DEFAULT (3)
+
+/*
+ * <ini>
+ * wmi_wq_watchdog - Sets timeout period for wmi watchdog bite
+ * @Min: 0
+ * @Max: 30
+ * @Default: 20
+ *
+ * This ini is used to set timeout period for wmi watchdog bite. If it is
+ * 0 then wmi watchdog bite is disabled.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_WMI_WQ_WATCHDOG          "wmi_wq_watchdog"
+#define CFG_WMI_WQ_WATCHDOG_MIN      (0)
+#define CFG_WMI_WQ_WATCHDOG_MAX      (30) /* 30s */
+#define CFG_WMI_WQ_WATCHDOG_DEFAULT  (20) /* 20s */
+
+/*
+ * <ini>
+ * gEnableDTIMSelectionDiversity - Enable/Disable chain
+ * selection optimization for one chain dtim
+ * @Min: 0
+ * @Max: 30
+ * @Default: 5
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_DTIM_SELECTION_DIVERSITY_NAME    "gEnableDTIMSelectionDiversity"
+#define CFG_DTIM_SELECTION_DIVERSITY_MIN     (0)
+#define CFG_DTIM_SELECTION_DIVERSITY_MAX     (30)
+#define CFG_DTIM_SELECTION_DIVERSITY_DEFAULT (5)
+
+/*
+ * <ini>
+ * gTxSchDelay - Enable/Disable Tx sch delay
+ * @Min: 0
+ * @Max: 5
+ * @Default: 0
+ *
+ * Usage: Internal/External
+ *
+ * </ini>
+ */
+
+#define CFG_TX_SCH_DELAY_NAME          "gTxSchDelay"
+#define CFG_TX_SCH_DELAY_MIN           (0)
+#define CFG_TX_SCH_DELAY_MAX           (5)
+#define CFG_TX_SCH_DELAY_DEFAULT       (0)
+
+/*
+ * Start of action oui inis
+ *
+ * To enable action oui feature, set gEnableActionOUI
+ *
+ * Each action oui is expected in the following format:
+ * <Extension 1> <Extension 2> ..... <Extension 10> (maximum 10)
+ *
+ * whereas, each Extension is separated by space and have the following format:
+ * <Token1> <Token2> <Token3> <Token4> <Token5> <Token6> <Token7> <Token8>
+ * where each Token is a string of hexa-decimal digits and
+ * following are the details about each token
+ *
+ * Token1 = OUI
+ * Token2 = Data_Length
+ * Token3 = Data
+ * Token4 = Data_Mask
+ * Token5 = Info_Presence_Bit
+ * Token6 = MAC_Address
+ * Token7 = Mac_Address Mask
+ * Token8 = Capability
+ *
+ * <OUI> is mandatory and it can be either 3 or 5 bytes means 6 or 10
+ * hexa-decimal characters
+ * If the OUI and Data checks needs to be ignored, the oui FFFFFF
+ * needs to be provided as OUI and bit 0 of Info_Presence_Bit should
+ * be set to 0.
+ *
+ * <Data_Length> is mandatory field and should give length of
+ * the <Data> if present else zero
+ *
+ * Presence of <Data> is controlled by <Data_Length>, if <Data_Length> is 0,
+ * then <Data> is not expected else Data of the size Data Length bytes are
+ * expected which means the length of Data string is 2 * Data Length,
+ * since every byte constitutes two hexa-decimal characters.
+ *
+ * <Data_Mask> is mandatory if <Data> is present and length of the
+ * Data mask string depends on the <Data Length>
+ * If <Data Length> is 06, then length of Data Mask string is
+ * 2 characters (represents 1 byte)
+ * data_mask_length = ((Data_Length - (Data_Length % 8)) / 8) +
+ *                    ((Data_Length % 8) ? 1 : 0)
+ * and <Data_Mask> has to be constructed from left to right.
+ *
+ * Presence of <Mac_Address> and <Capability> is
+ * controlled by <Info_Presence_Bit> which is mandatory
+ * <Info_Presence_Bit> will give the information for
+ *   OUI – bit 0 Should be set to 1
+ *               Setting to 0 will ignore OUI and data check
+ *   Mac Address present – bit 1
+ *   NSS – bit 2
+ *   HT check – bit 3
+ *   VHT check – bit 4
+ *   Band info – bit 5
+ *   reserved – bit 6 (should always be zero)
+ *   reserved – bit 7 (should always be zero)
+ * and should be constructed from right to left (b7b6b5b4b3b2b1b0)
+ *
+ * <Mac_Address_Mask> for <Mac_Address> should be constructed from left to right
+ *
+ * <Capability> is 1 byte long and it contains the below info
+ *   NSS – 4 bits starting from LSB (b0 – b3)
+ *   HT enabled – bit 4
+ *   VHT enabled – bit 5
+ *   2G band – bit 6
+ *   5G band – bit 7
+ * and should be constructed from right to left (b7b6b5b4b3b2b1b0)
+ * <Capability> is present if atleast one of the bit is set
+ * from b2 - b6 in <Info_Presence_Bit>
+ *
+ * Example 1:
+ *
+ * OUI is 00-10-18, data length is 05 (hex form), data is 02-11-04-5C-DE and
+ * need to consider first 3 bytes and last byte of data for comparision
+ * mac-addr EE-1A-59-FE-FD-AF is present and first 3 bytes and last byte of
+ * mac address should be considered for comparision
+ * capability is not present
+ * then action OUI for gActionOUIITOExtension is as follows:
+ *
+ * gActionOUIITOExtension=001018 05 0211045CDE E8 03 EE1A59FEFDAF E4
+ *
+ * data mask calculation in above example:
+ * Data[0] = 02 ---- d0 = 1
+ * Data[1] = 11 ---- d1 = 1
+ * Data[2] = 04 ---- d2 = 1
+ * Data[3] = 5C ---- d3 = 0
+ * Data[4] = DE ---- d4 = 1
+ * data_mask = d0d1d2d3d4 + append with zeros to complete 8-bit = 11101000 = E8
+ *
+ * mac mask calculation in above example:
+ * mac_addr[0] = EE ---- m0 = 1
+ * mac_addr[1] = 1A ---- m1 = 1
+ * mac_addr[2] = 59 ---- m2 = 1
+ * mac_addr[3] = FE ---- m3 = 0
+ * mac_addr[4] = FD ---- m4 = 0
+ * mac_addr[5] = AF ---- m5 = 1
+ * mac_mask = m0m1m2m3m4m5 + append with zeros to complete 8-bit = 11100100 = E4
+ *
+ * Example 2:
+ *
+ * OUI is 00-10-18, data length is 00 and no Mac Address and capability
+ *
+ * gActionOUIITOExtension=001018 00 01
+ *
+ */
+
+/*
+ * <ini>
+ * gEnableActionOUI - Enable/Disable action oui feature
+ * @Min: 0 (disable)
+ * @Max: 1 (enable)
+ * @Default: 1 (enable)
+ *
+ * This ini is used to enable the action oui feature to control
+ * mode of connection, connected AP's in-activity time, Tx rate etc.,
+ *
+ * Related: If gEnableActionOUI is set, then at least one of the following inis
+ * must be set with the proper action oui extensions:
+ * gActionOUIConnect1x1, gActionOUIITOExtension, gActionOUICCKM1X1
+ *
+ * Supported Feature: action ouis
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_ACTION_OUI         "gEnableActionOUI"
+#define CFG_ENABLE_ACTION_OUI_MIN     (0)
+#define CFG_ENABLE_ACTION_OUI_MAX     (1)
+#define CFG_ENABLE_ACTION_OUI_DEFAULT (1)
+
+/*
+ * <ini>
+ * gActionOUIConnect1x1 - Used to specify action OUIs for 1x1 connection
+ * @Default: 000C43 00 25 42 001018 06 02FFF02C0000 BC 25 42 001018 06 02FF040C0000 BC 25 42 00037F 00 35 6C
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1 : 000C43
+ *   OUI data Len : 00
+ *   Info Mask : 25 - Check for NSS and Band
+ *   Capabilities: 42 - NSS == 2 && Band == 2G
+ * OUI 2 : 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FFF02C0000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 25 - Check for NSS and Band
+ *   Capabilities: 42 - NSS == 2 && Band == 2G
+ * OUI 3 : 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FF040C0000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 25 - Check for NSS and Band
+ *   Capabilities: 42 - NSS == 2 && Band == 2G
+ * OUI 4 : 00037F
+ *   OUI data Len : 00
+ *   Info Mask : 35 - Check for NSS, VHT Caps and Band
+ *   Capabilities: 6C - (NSS == 3 or 4) && VHT Caps Preset && Band == 2G
+ *
+ * This ini is used to specify the AP OUIs with which only 1x1 connection
+ * is allowed.
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_CONNECT_1X1_NAME    "gActionOUIConnect1x1"
+#define CFG_ACTION_OUI_CONNECT_1X1_DEFAULT "000C43 00 25 42 001018 06 02FFF02C0000 BC 25 42 001018 06 02FF040C0000 BC 25 42 00037F 00 35 6C"
+
+/*
+ * <ini>
+ * gActionOUIITOExtension - Used to extend in-activity time for specified APs
+ * @Default: 00037F 06 01010000FF7F FC 01 000AEB 02 0100 C0 01 000B86 03 010408 E0 01
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1: 00037F
+ *   OUI data Len: 06
+ *   OUI Data: 01010000FF7F
+ *   OUI data Mask: FC - 11111100
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * OUI 2: 000AEB
+ *   OUI data Len: 02
+ *   OUI Data: 0100
+ *   OUI data Mask: C0 - 11000000
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * OUI 3: 000B86
+ *   OUI data Len: 03
+ *   OUI Data: 010408
+ *   OUI data Mask: E0 - 11100000
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * This ini is used to specify AP OUIs using which station's in-activity time
+ * can be extended with the respective APs
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_ITO_EXTENSION_NAME    "gActionOUIITOExtension"
+#define CFG_ACTION_OUI_ITO_EXTENSION_DEFAULT "00037F 06 01010000FF7F FC 01 000AEB 02 0100 C0 01 000B86 03 010408 E0 01"
+
+/*
+ * <ini>
+ * gActionOUICCKM1X1 - Used to specify action OUIs to control station's TX rates
+ *
+ * This ini is used to specify AP OUIs for which station's CCKM TX rates
+ * should be 1x1 only.
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_CCKM_1X1_NAME    "gActionOUICCKM1X1"
+#define CFG_ACTION_OUI_CCKM_1X1_DEFAULT ""
+
+/*
+ * <ini>
+ * gActionOUIITOAlternate - Used to specify action OUIs to have alternate ITO in
+ * weak RSSI state
+ *
+ * This ini is used to specify AP OUIs for which the stations will have
+ * alternate ITOs for the case when the RSSI is weak.
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+ #define CFG_ACTION_OUI_ITO_ALTERNATE_NAME    "gActionOUIITOAlternate"
+ #define CFG_ACTION_OUI_ITO_ALTERNATE_DEFAULT "001018 06 0202001c0000 FC 01"
+
+/*
+ * <ini>
+ * gActionOUISwitchTo11nMode - Used to specify action OUIs for switching to 11n
+ *
+ * This ini is used to specify which AP for which the connection has to be
+ * made in 2x2 mode with HT capabilities only and not VHT.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1 : 00904C
+ *   OUI data Len : 03
+ *   OUI Data : 0418BF
+ *   OUI data Mask: E0 - 11100000
+ *   Info Mask : 21 - Check for Band
+ *   Capabilities: 40 - Band == 2G
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_SWITCH_TO_11N_MODE_NAME    "gActionOUISwitchTo11nMode"
+#define CFG_ACTION_OUI_SWITCH_TO_11N_MODE_DEFAULT "00904C 03 0418BF E0 21 40"
+
+/*
+ * <ini>
+ * gActionOUIConnect1x1with1TxRxChain - Used to specify action OUIs for
+ *					 1x1 connection with one Tx/Rx Chain
+ * @Default:
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1 : 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FFF0040000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 21 - Check for Band
+ *   Capabilities: 40 - Band == 2G
+ *
+ * OUI 2 : 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FFF0050000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 21 - Check for Band
+ *   Capabilities: 40 - Band == 2G
+ *
+ * OUI 3 : 001018
+ *   OUI data Len : 06
+ *   OUI Data : 02FFF4050000
+ *   OUI data Mask: BC - 10111100
+ *   Info Mask : 21 - Check for Band
+ *   Capabilities: 40 - Band == 2G
+ *
+ * This ini is used to specify the AP OUIs with which only 1x1 connection
+ * with one Tx/Rx Chain is allowed.
+ *
+ * Related: gEnableActionOUI
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN_NAME    "gActionOUIConnect1x1with1TxRxChain"
+#define CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN_DEFAULT "001018 06 02FFF0040000 BC 21 40 001018 06 02FFF0050000 BC 21 40 001018 06 02FFF4050000 BC 21 40"
+
+ /* End of action oui inis */
+
+
+/*
+ * <ini>
+ * gEnableUnitTestFramework - Enable/Disable unit test framework
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Usage: Internal (only for dev and test team)
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_UNIT_TEST_FRAMEWORK_NAME    "gEnableUnitTestFramework"
+#define CFG_ENABLE_UNIT_TEST_FRAMEWORK_MIN     (0)
+#define CFG_ENABLE_UNIT_TEST_FRAMEWORK_MAX     (1)
+#define CFG_ENABLE_UINT_TEST_FRAMEWORK_DEFAULT (0)
+
+/*
+ * <ini>
+ * enable_rtt_mac_randomization - Enable/Disable rtt mac randomization
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_RTT_MAC_RANDOMIZATION_NAME    "enable_rtt_mac_randomization"
+#define CFG_ENABLE_RTT_MAC_RANDOMIZATION_MIN     (0)
+#define CFG_ENABLE_RTT_MAC_RANDOMIZATION_MAX     (1)
+#define CFG_ENABLE_RTT_MAC_RANDOMIZATION_DEFAULT (0)
+
+/*
+ * <ini>
+ * gEnableSecondaryRate - Enable/Disable Secondary Retry Rate feature subset
+ *
+ * @Min: 0x0
+ * @Max: 0x3F
+ * @Default: 0x17
+ *
+ * It is a 32 bit value such that the various bits represent as below -
+ * Bit-0 : is Enable/Disable Control for "PPDU Secondary Retry Support"
+ * Bit-1 : is Enable/Disable Control for "RTS Black/White-listing Support"
+ * Bit-2 : is Enable/Disable Control for "Higher MCS retry restriction
+ *         on XRETRY failures"
+ * Bit 3-5 : is "Xretry threshold" to use
+ * Bit 3~31 : reserved for future use.
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_SECONDARY_RATE_NAME          "gEnableSecondaryRate"
+#define CFG_ENABLE_SECONDARY_RATE_MIN           (0)
+#define CFG_ENABLE_SECONDARY_RATE_MAX           (0x3F)
+#define CFG_ENABLE_SECONDARY_RATE_DEFAULT       (0x17)
+
+/*
+ * <ini>
+ * gNumVdevs - max number of VDEVs supported
+ *
+ * @Min: 0x1
+ * @Max: 0x4
+ * @Default: CFG_TGT_NUM_VDEV
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_NUM_VDEV_ENABLE_NAME      "gNumVdevs"
+#define CFG_NUM_VDEV_ENABLE_MIN       (0x1)
+#define CFG_NUM_VDEV_ENABLE_MAX       (0x4)
+#define CFG_NUM_VDEV_ENABLE_DEFAULT   (CFG_TGT_NUM_VDEV)
+
+#ifdef MWS_COEX
+/*
+ * <ini>
+ * gMwsCoex4gQuickTdm - Bitmap to control MWS-COEX 4G quick FTDM policy
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * It is a 32 bit value such that the various bits represent as below:
+ * Bit-0 : 0 - Don't allow quick FTDM policy (Default)
+ *        1 - Allow quick FTDM policy
+ * Bit 1-31 : reserved for future use
+ *
+ * It is used to enable or disable MWS-COEX 4G (LTE) Quick FTDM
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+
+#define CFG_MWS_COEX_4G_QUICK_FTDM_NAME      "gMwsCoex4gQuickTdm"
+#define CFG_MWS_COEX_4G_QUICK_FTDM_MIN       (0x00000000)
+#define CFG_MWS_COEX_4G_QUICK_FTDM_MAX       (0xFFFFFFFF)
+#define CFG_MWS_COEX_4G_QUICK_FTDM_DEFAULT   (0x00000000)
+
+/*
+ * <ini>
+ * gMwsCoex5gnrPwrLimit - Bitmap to set MWS-COEX 5G-NR power limit
+ * @Min: 0x00000000
+ * @Max: 0xFFFFFFFF
+ * @Default: 0x00000000
+ *
+ * It is a 32 bit value such that the various bits represent as below:
+ * Bit-0 : Don't apply user specific power limit,
+ *        use internal power limit (Default)
+ * Bit 1-2 : Invalid value (Ignored)
+ * Bit 3-21 : Apply the specified value as the external power limit, in dBm
+ * Bit 22-31 : Invalid value (Ignored)
+ *
+ * It is used to set MWS-COEX 5G-NR power limit
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+
+#define CFG_MWS_COEX_5G_NR_PWR_LIMIT_NAME      "gMwsCoex5gnrPwrLimit"
+#define CFG_MWS_COEX_5G_NR_PWR_LIMIT_MIN       (0x00000000)
+#define CFG_MWS_COEX_5G_NR_PWR_LIMIT_MAX       (0xFFFFFFFF)
+#define CFG_MWS_COEX_5G_NR_PWR_LIMIT_DEFAULT   (0x00000000)
+#endif
+
+/*
+ * <ini>
+ * gEnableChangeChannelBandWidth - Enable/Disable change
+ * channel&bandwidth in the mission mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * 0 - not allow change channel&bandwidth by setMonChan
+ * 1 - allow change channel&bandwidth by setMonChan
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_CHANGE_CHANNEL_BANDWIDTH_NAME    "gEnableChangeChannelBandWidth"
+#define CFG_CHANGE_CHANNEL_BANDWIDTH_MIN     (0)
+#define CFG_CHANGE_CHANNEL_BANDWIDTH_MAX     (1)
+#define CFG_CHANGE_CHANNEL_BANDWIDTH_DEFAULT (0)
+
+/*
+ * Type declarations
+ */
+
+struct hdd_config {
+	/* Bitmap to track what is explicitly configured */
+	DECLARE_BITMAP(bExplicitCfg, MAX_CFG_INI_ITEMS);
+
+	/* Config parameters */
+#ifdef WLAN_NUD_TRACKING
+	bool enable_nud_tracking;
+#endif
+	bool enable_connected_scan;
+	uint8_t OperatingChannel;
+	bool ShortSlotTimeEnabled;
+	bool Is11dSupportEnabled;
+	bool Is11hSupportEnabled;
+	bool fSupplicantCountryCodeHasPriority;
+	char PowerUsageControl[4];
+	bool fIsImpsEnabled;
+	bool is_ps_enabled;
+	uint32_t auto_bmps_timer_val;
+	uint32_t icmp_disable_ps_val;
+	uint32_t nBmpsMaxListenInterval;
+	uint32_t nBmpsMinListenInterval;
+	enum hdd_dot11_mode dot11Mode;
+	uint32_t nChannelBondingMode24GHz;
+	bool override_ht20_40_24g;
+	uint32_t nChannelBondingMode5GHz;
+	uint32_t ScanResultAgeCount;
+	uint8_t nRssiCatGap;
+	struct qdf_mac_addr IbssBssid;
+	uint32_t AdHocChannel5G;
+	uint32_t AdHocChannel24G;
+	uint8_t intfAddrMask;
+	struct qdf_mac_addr intfMacAddr[QDF_MAX_CONCURRENCY_PERSONA];
+
+	bool apUapsdEnabled;
+	bool apRandomBssidEnabled;
+	bool apProtEnabled;
+	uint16_t apProtection;
+	bool apOBSSProtEnabled;
+	bool apDisableIntraBssFwd;
+	enum station_keepalive_method sta_keepalive_method;
+	uint8_t nTxPowerCap;    /* In dBm */
+	bool allow_tpc_from_ap;
+	uint8_t disablePacketFilter;
+	bool fRrmEnable;
+	uint16_t nRrmRandnIntvl;
+	/* length includes separator */
+	char rm_capability[3 * DOT11F_IE_RRMENABLEDCAP_MAX_LEN];
+
+#ifdef FEATURE_WLAN_DYNAMIC_CVM
+	/* Bitmap for operating voltage corner mode */
+	uint32_t vc_mode_cfg_bitmap;
+#endif
+
+#ifdef MWS_COEX
+	/* Bitmap for MWS-COEX 4G Quick FTDM */
+	uint32_t mws_coex_4g_quick_tdm;
+
+	/* Bitmap for MWS-COEX 5G-NR power limit */
+	uint32_t mws_coex_5g_nr_pwr_limit;
+#endif
+
+	uint16_t nNeighborScanPeriod;
+	uint16_t neighbor_scan_min_period;
+	uint8_t nNeighborLookupRssiThreshold;
+	uint8_t delay_before_vdev_stop;
+	uint8_t nOpportunisticThresholdDiff;
+	uint8_t nRoamRescanRssiDiff;
+	uint8_t neighborScanChanList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	uint16_t nNeighborScanMinChanTime;
+	uint16_t nNeighborScanMaxChanTime;
+	uint16_t nNeighborResultsRefreshPeriod;
+	uint16_t nEmptyScanRefreshPeriod;
+	uint8_t nRoamBmissFirstBcnt;
+	uint8_t nRoamBmissFinalBcnt;
+	uint8_t nRoamBeaconRssiWeight;
+	uint32_t nhi_rssi_scan_max_count;
+	uint32_t nhi_rssi_scan_rssi_delta;
+	uint32_t nhi_rssi_scan_delay;
+	int32_t nhi_rssi_scan_rssi_ub;
+
+	/* Additional Handoff params */
+	uint16_t nVccRssiTrigger;
+	uint32_t nVccUlMacLossThreshold;
+	uint32_t nPassiveMaxChnTime;    /* in units of milliseconds */
+	uint32_t nActiveMaxChnTime;     /* in units of milliseconds */
+	uint32_t scan_probe_repeat_time;
+	uint32_t scan_num_probes;
+
+	uint32_t nInitialDwellTime;     /* in units of milliseconds */
+	bool initial_scan_no_dfs_chnl;
+
+	uint32_t nPassiveMinChnTimeConc;        /* in units of milliseconds */
+	uint32_t nPassiveMaxChnTimeConc;        /* in units of milliseconds */
+	uint32_t nActiveMinChnTimeConc; /* in units of milliseconds */
+	uint32_t nActiveMaxChnTimeConc; /* in units of milliseconds */
+	uint32_t nRestTimeConc; /* in units of milliseconds */
+	/* In units of milliseconds */
+	uint32_t       min_rest_time_conc;
+	/* In units of milliseconds */
+	uint32_t       idle_time_conc;
+
+	uint8_t nRssiFilterPeriod;
+	uint8_t fMaxLIModulatedDTIM;
+
+	bool mcc_rts_cts_prot_enable;
+	bool mcc_bcast_prob_resp_enable;
+	uint8_t wow_data_inactivity_timeout;
+
+	/* WMM QoS Configuration */
+	bool isFastRoamIniFeatureEnabled;
+	bool MAWCEnabled;
+#ifdef FEATURE_WLAN_ESE
+	uint32_t InfraInactivityInterval;
+	bool isEseIniFeatureEnabled;
+#endif
+	bool isFastTransitionEnabled;
+	uint8_t RoamRssiDiff;
+	bool isWESModeEnabled;
+	bool isRoamOffloadScanEnabled;
+
+	uint32_t DelayedTriggerFrmInt;
+
+	char enableConcurrentSTA[CFG_CONCURRENT_IFACE_MAX_LEN];
+
+#ifdef FEATURE_RUNTIME_PM
+	bool runtime_pm;
+#endif
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+	uint16_t RArateLimitInterval;
+#endif
+#ifdef FEATURE_WLAN_SCAN_PNO
+	bool PnoOffload;
+#endif
+	bool burstSizeDefinition;
+	uint8_t tsInfoAckPolicy;
+
+	bool AddTSWhenACMIsOff;
+
+/* QDF Trace Control*/
+	uint16_t qdf_trace_enable_wdi;
+	uint16_t qdf_trace_enable_hdd;
+	uint16_t qdf_trace_enable_sme;
+	uint16_t qdf_trace_enable_pe;
+	uint16_t qdf_trace_enable_pmc;
+	uint16_t qdf_trace_enable_wma;
+	uint16_t qdf_trace_enable_sys;
+	uint16_t qdf_trace_enable_qdf;
+	uint16_t qdf_trace_enable_sap;
+	uint16_t qdf_trace_enable_hdd_sap;
+	uint16_t qdf_trace_enable_bmi;
+	uint16_t qdf_trace_enable_cfg;
+	uint16_t qdf_trace_enable_txrx;
+	uint16_t qdf_trace_enable_dp;
+	uint16_t qdf_trace_enable_htc;
+	uint16_t qdf_trace_enable_hif;
+	uint16_t qdf_trace_enable_hdd_sap_data;
+	uint16_t qdf_trace_enable_hdd_data;
+	uint16_t qdf_trace_enable_epping;
+	uint16_t qdf_trace_enable_qdf_devices;
+	uint16_t qdf_trace_enable_wifi_pos;
+	uint16_t qdf_trace_enable_nan;
+	uint16_t qdf_trace_enable_regulatory;
+	uint16_t qdf_trace_enable_cp_stats;
+#ifdef ENABLE_MTRACE_LOG
+	bool enable_mtrace;
+#endif
+	uint8_t enableBypass11d;
+	uint8_t enableDFSChnlScan;
+	uint8_t enable_dfs_pno_chnl_scan;
+	uint8_t ShortGI40MhzEnable;
+	enum hdd_link_speed_rpt_type reportMaxLinkSpeed;
+	int32_t linkSpeedRssiHigh;
+	int32_t linkSpeedRssiMid;
+	int32_t linkSpeedRssiLow;
+	bool nRoamPrefer5GHz;
+	bool nRoamIntraBand;
+	uint8_t nProbes;
+	uint16_t nRoamScanHomeAwayTime;
+	uint8_t enableMCC;
+	uint8_t allowMCCGODiffBI;
+	uint8_t thermalMitigationEnable;
+	uint32_t throttlePeriod;
+	uint32_t throttle_dutycycle_level0;
+	uint32_t throttle_dutycycle_level1;
+	uint32_t throttle_dutycycle_level2;
+	uint32_t throttle_dutycycle_level3;
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
+	bool bad_peer_txctl_enable;
+	uint32_t bad_peer_txctl_prd;
+	uint32_t bad_peer_txctl_txq_lmt;
+	uint32_t bad_peer_tgt_backoff;
+	uint32_t bad_peer_tgt_report_prd;
+	uint32_t bad_peer_cond_ieee80211b;
+	uint32_t bad_peer_delta_ieee80211b;
+	uint32_t bad_peer_pct_ieee80211b;
+	uint32_t bad_peer_tput_ieee80211b;
+	uint32_t bad_peer_limit_ieee80211b;
+	uint32_t bad_peer_cond_ieee80211ag;
+	uint32_t bad_peer_delta_ieee80211ag;
+	uint32_t bad_peer_pct_ieee80211ag;
+	uint32_t bad_peer_tput_ieee80211ag;
+	uint32_t bad_peer_limit_ieee80211ag;
+	uint32_t bad_peer_cond_ieee80211n;
+	uint32_t bad_peer_delta_ieee80211n;
+	uint32_t bad_peer_pct_ieee80211n;
+	uint32_t bad_peer_tput_ieee80211n;
+	uint32_t bad_peer_limit_ieee80211n;
+	uint32_t bad_peer_cond_ieee80211ac;
+	uint32_t bad_peer_delta_ieee80211ac;
+	uint32_t bad_peer_pct_ieee80211ac;
+	uint32_t bad_peer_tput_ieee80211ac;
+	uint32_t bad_peer_limit_ieee80211ac;
+#endif
+	uint32_t vdev_type_nss_2g;
+	uint32_t vdev_type_nss_5g;
+	bool enableFirstScan2GOnly;
+	uint8_t enable_tx_ldpc;
+	uint8_t enable_rx_ldpc;
+	bool prevent_link_down;
+	uint8_t scanAgingTimeout;
+	uint8_t disableLDPCWithTxbfAP;
+	bool enableSSR;
+	bool bFastRoamInConIniFeatureEnabled;
+	bool fEnableSNRMonitoring;
+	/*PNO related parameters */
+#ifdef FEATURE_WLAN_SCAN_PNO
+	bool configPNOScanSupport;
+	uint32_t configPNOScanTimerRepeatValue;
+	uint32_t pno_slow_scan_multiplier;
+#endif
+	uint8_t isCoalesingInIBSSAllowed;
+
+	/* IBSS Power Save related parameters */
+	uint32_t ibssATIMWinSize;
+	uint8_t isIbssPowerSaveAllowed;
+	uint8_t isIbssPowerCollapseAllowed;
+	uint8_t isIbssAwakeOnTxRx;
+	uint32_t ibssInactivityCount;
+	uint32_t ibssTxSpEndInactivityTime;
+	uint32_t ibssPsWarmupTime;
+	uint32_t ibssPs1RxChainInAtimEnable;
+	uint32_t IpaConfig;
+	bool IpaClkScalingEnable;
+	uint8_t disableDFSChSwitch;
+	uint32_t TxPower2g;
+	uint32_t TxPower5g;
+	bool fDfsPhyerrFilterOffload;
+	uint8_t gSapPreferredChanLocation;
+	uint8_t gDisableDfsJapanW53;
+	bool gEnableOverLapCh;
+	bool fRegChangeDefCountry;
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+	uint32_t TxFlowStopQueueThreshold;
+	uint32_t TxFlowStartQueueOffset;
+#endif
+	bool advertiseConcurrentOperation;
+
+	uint8_t allowDFSChannelRoam;
+
+	uint8_t enableFwModuleLogLevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH];
+
+	uint8_t ignoreCAC;
+
+	bool enable_sap_mandatory_chan_list;
+
+	int32_t dfsRadarPriMultiplier;
+	uint8_t reorderOffloadSupport;
+
+#ifdef FEATURE_WLAN_FORCE_SAP_SCC
+	uint8_t SapSccChanAvoidance;
+#endif /* FEATURE_WLAN_FORCE_SAP_SCC */
+
+	bool enable_sap_suspend;
+
+	bool gEnableDeauthToDisassocMap;
+#ifdef DHCP_SERVER_OFFLOAD
+	uint8_t dhcpServerIP[IPADDR_STRING_LENGTH];
+#endif /* DHCP_SERVER_OFFLOAD */
+	bool enable_mac_spoofing;
+	uint32_t sta_miracast_mcc_rest_time_val;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	bool sap_channel_avoidance;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+	uint8_t sap_11ac_override;
+	uint8_t go_11ac_override;
+	uint8_t prefer_non_dfs_on_radar;
+	uint8_t max_msdus_per_rxinorderind;
+	/* parameter for defer timer for enabling TDLS on p2p listen */
+	uint32_t fine_time_meas_cap;
+	uint8_t max_scan_count;
+	bool etsi13_srd_chan_in_master_mode;
+	uint8_t num_dp_rx_threads;
+	uint32_t dual_mac_feature_disable;
+	uint8_t dbs_scan_selection[CFG_DBS_SCAN_PARAM_LENGTH];
+	uint32_t sta_sap_scc_on_dfs_chan;
+	uint32_t sta_sap_scc_on_lte_coex_chan;
+	uint16_t  self_gen_frm_pwr;
+#ifdef FEATURE_WLAN_SCAN_PNO
+	bool pno_channel_prediction;
+	uint8_t top_k_num_of_channels;
+	uint8_t stationary_thresh;
+	uint32_t channel_prediction_full_scan;
+#endif
+	bool early_stop_scan_enable;
+	int8_t early_stop_scan_min_threshold;
+	int8_t early_stop_scan_max_threshold;
+	int8_t first_scan_bucket_threshold;
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+	bool enable_lfr_subnet_detection;
+#endif
+	uint8_t inform_bss_rssi_raw;
+#ifdef WLAN_FEATURE_TSF
+#ifdef WLAN_FEATURE_TSF_PLUS
+	uint8_t tsf_ptp_options;
+#endif /* WLAN_FEATURE_TSF_PLUS */
+#endif
+	uint32_t ho_delay_for_rx;
+	uint32_t min_delay_btw_roam_scans;
+	uint32_t roam_trigger_reason_bitmask;
+	uint32_t roam_bg_scan_client_bitmap;
+
+	/* Tuning TX sched parameters for VO (skip credit limit credit disc) */
+	uint8_t  tx_sched_wrr_vo[TX_SCHED_WRR_PARAM_STRING_LENGTH];
+	/* Tuning TX sched parameters for VI (skip credit limit credit disc) */
+	uint8_t  tx_sched_wrr_vi[TX_SCHED_WRR_PARAM_STRING_LENGTH];
+	/* Tuning TX sched parameters for BE (skip credit limit credit disc) */
+	uint8_t  tx_sched_wrr_be[TX_SCHED_WRR_PARAM_STRING_LENGTH];
+	/* Tuning TX sched parameters for BK (skip credit limit credit disc) */
+	uint8_t  tx_sched_wrr_bk[TX_SCHED_WRR_PARAM_STRING_LENGTH];
+
+	bool apf_enabled;
+#ifdef CONFIG_DP_TRACE
+	bool enable_dp_trace;
+	uint8_t dp_trace_config[DP_TRACE_CONFIG_STRING_LENGTH];
+#endif
+	bool adaptive_dwell_mode_enabled;
+	enum scan_dwelltime_adaptive_mode scan_adaptive_dwell_mode;
+	enum scan_dwelltime_adaptive_mode scan_adaptive_dwell_mode_nc;
+	enum scan_dwelltime_adaptive_mode extscan_adaptive_dwell_mode;
+	enum scan_dwelltime_adaptive_mode pnoscan_adaptive_dwell_mode;
+	enum scan_dwelltime_adaptive_mode global_adapt_dwelltime_mode;
+	uint8_t adapt_dwell_lpf_weight;
+	uint8_t adapt_dwell_passive_mon_intval;
+	uint8_t adapt_dwell_wifi_act_threshold;
+	bool bug_report_for_no_scan_results;
+	bool indoor_channel_support;
+	/* control marking indoor channel passive to disable */
+	bool force_ssc_disable_indoor_channel;
+	/* parameter to force sap into 11n */
+	bool sap_force_11n_for_11ac;
+	bool go_force_11n_for_11ac;
+	uint16_t sap_tx_leakage_threshold;
+	bool multicast_replay_filter;
+	uint32_t rx_wakelock_timeout;
+	bool sap_internal_restart;
+	enum restart_beaconing_on_ch_avoid_rule
+		restart_beaconing_on_chan_avoid_event;
+	enum active_apf_mode active_uc_apf_mode;
+	enum active_apf_mode active_mc_bc_apf_mode;
+	uint8_t he_dynamic_frag_support;
+#ifdef WLAN_FEATURE_11AX
+	bool enable_ul_mimo;
+	bool enable_ul_ofdma;
+	uint32_t he_sta_obsspd;
+#endif
+#ifdef WLAN_SUPPORT_TWT
+	bool enable_twt;
+	uint32_t twt_congestion_timeout;
+#endif
+	bool tx_orphan_enable;
+
+	uint8_t scan_backoff_multiplier;
+	bool mawc_nlo_enabled;
+	uint32_t mawc_nlo_exp_backoff_ratio;
+	uint32_t mawc_nlo_init_scan_interval;
+	uint32_t mawc_nlo_max_scan_interval;
+	bool is_force_1x1;
+	enum pmo_auto_pwr_detect_failure_mode auto_pwr_save_fail_mode;
+	bool enable_11d_in_world_mode;
+	/* 5G preference parameters for boosting RSSI */
+	bool                        enable_5g_band_pref;
+	int8_t                      rssi_boost_threshold_5g;
+	uint8_t                     rssi_boost_factor_5g;
+	uint8_t                     max_rssi_boost_5g;
+	/* 5G preference parameters for dropping RSSI*/
+	int8_t                      rssi_penalize_threshold_5g;
+	uint8_t                     rssi_penalize_factor_5g;
+	uint8_t                     max_rssi_penalize_5g;
+	bool enable_lprx;
+	int8_t rssi_thresh_offset_5g;
+	uint32_t scan_11d_interval;
+	bool is_bssid_hint_priority;
+	uint16_t wlm_latency_enable;
+	uint16_t wlm_latency_level;
+	uint32_t wlm_latency_flags_normal;
+	uint32_t wlm_latency_flags_moderate;
+	uint32_t wlm_latency_flags_low;
+	uint32_t wlm_latency_flags_ultralow;
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+	uint8_t packet_filters_bitmap;
+#endif
+	uint8_t dfs_beacon_tx_enhanced;
+	uint32_t btm_offload_config;
+#ifdef WLAN_FEATURE_SAE
+	bool is_sae_enabled;
+#endif
+	bool enable_dtim_selection_diversity;
+	bool gcmp_enabled;
+	bool is_11k_offload_supported;
+	uint32_t btm_solicited_timeout;
+	uint32_t btm_max_attempt_cnt;
+	uint32_t btm_sticky_time;
+	uint32_t num_vdevs;
+	uint32_t offload_11k_enable_bitmask;
+	uint32_t neighbor_report_offload_params_bitmask;
+	uint32_t neighbor_report_offload_time_offset;
+	uint32_t neighbor_report_offload_low_rssi_offset;
+	uint32_t neighbor_report_offload_bmiss_count_trigger;
+	uint32_t neighbor_report_offload_per_threshold_offset;
+	uint32_t neighbor_report_offload_cache_timeout;
+	uint32_t neighbor_report_offload_max_req_cap;
+	bool action_oui_enable;
+	uint8_t action_oui_str[ACTION_OUI_MAXIMUM_ID][ACTION_OUI_MAX_STR_LEN];
+	uint16_t wmi_wq_watchdog_timeout;
+	bool enable_bt_chain_separation;
+	uint8_t enable_tx_sch_delay;
+	uint32_t enable_secondary_rate;
+	bool is_unit_test_framework_enabled;
+	bool enable_ftopen;
+	bool enable_rtt_mac_randomization;
+	bool roam_force_rssi_trigger;
+	bool enable_change_channel_bandwidth;
+
+	/* HDD converged ini items are listed below this*/
+	bool bug_on_reinit_failure;
+	bool is_ramdump_enabled;
+	uint32_t iface_change_wait_time;
+	uint8_t multicast_host_fw_msgs;
+	enum hdd_wext_control private_wext_control;
+	uint32_t timer_multiplier;
+	bool enablefwprint;
+	uint8_t enable_fw_log;
+
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+	/* WLAN Logging */
+	bool wlan_logging_enable;
+	bool wlan_logging_to_console;
+#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+	uint32_t wlan_auto_shutdown;
+#endif
+
+#ifndef REMOVE_PKT_LOG
+	bool enable_packet_log;
+#endif
+	uint32_t rx_mode;
+#ifdef MSM_PLATFORM
+	uint32_t bus_bw_high_threshold;
+	uint32_t bus_bw_medium_threshold;
+	uint32_t bus_bw_low_threshold;
+	uint32_t bus_bw_compute_interval;
+	uint32_t enable_tcp_delack;
+	bool     enable_tcp_limit_output;
+	uint32_t enable_tcp_adv_win_scale;
+	uint32_t tcp_delack_thres_high;
+	uint32_t tcp_delack_thres_low;
+	uint32_t tcp_tx_high_tput_thres;
+	uint32_t tcp_delack_timer_count;
+	u8  periodic_stats_disp_time;
+#endif /* MSM_PLATFORM */
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+	uint32_t tx_flow_low_watermark;
+	uint32_t tx_flow_hi_watermark_offset;
+	uint32_t tx_flow_max_queue_depth;
+	uint32_t tx_lbw_flow_low_watermark;
+	uint32_t tx_lbw_flow_hi_watermark_offset;
+	uint32_t tx_lbw_flow_max_queue_depth;
+	uint32_t tx_hbw_flow_low_watermark;
+	uint32_t tx_hbw_flow_hi_watermark_offset;
+	uint32_t tx_hbw_flow_max_queue_depth;
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+	uint32_t napi_cpu_affinity_mask;
+	/* CPU affinity mask for rx_thread */
+	uint32_t rx_thread_affinity_mask;
+	uint8_t cpu_map_list[CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST_LEN];
+};
+
+#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
+#define VAR_SIZE(_Struct, _Var) (sizeof(((_Struct *)0)->_Var))
+
+#define VAR_FLAGS_NONE         (0)
+
+/* bit 0 is Required or Optional */
+#define VAR_FLAGS_REQUIRED     (1 << 0)
+#define VAR_FLAGS_OPTIONAL     (0 << 0)
+
+/*
+ * bit 1 tells if range checking is required.
+ * If less than MIN, assume MIN.
+ * If greater than MAX, assume MAX.
+ */
+#define VAR_FLAGS_RANGE_CHECK  (1 << 1)
+#define VAR_FLAGS_RANGE_CHECK_ASSUME_MINMAX (VAR_FLAGS_RANGE_CHECK)
+
+/*
+ * bit 2 is range checking that assumes the DEFAULT value
+ * If less than MIN, assume DEFAULT,
+ * If greater than MAX, assume DEFAULT.
+ */
+#define VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT (1 << 2)
+
+/*
+ * Bit 3 indicates that the config item can be modified dynamicially
+ * on a running system
+ */
+#define VAR_FLAGS_DYNAMIC_CFG (1 << 3)
+
+enum wlan_parameter_type {
+	WLAN_PARAM_Integer,
+	WLAN_PARAM_SignedInteger,
+	WLAN_PARAM_HexInteger,
+	WLAN_PARAM_String,
+	WLAN_PARAM_MacAddr,
+};
+
+#define REG_VARIABLE(_Name, _Type,  _Struct, _VarName,		\
+		      _Flags, _Default, _Min, _Max)		\
+	{							\
+		(_Name),					\
+		(_Type),					\
+		(_Flags),					\
+		0,						\
+		VAR_OFFSET(_Struct, _VarName),			\
+		VAR_SIZE(_Struct, _VarName),			\
+		(_Default),					\
+		(_Min),						\
+		(_Max),						\
+		NULL						\
+	}
+
+#define REG_DYNAMIC_VARIABLE(_Name, _Type,  _Struct, _VarName,	\
+			      _Flags, _Default, _Min, _Max,	\
+			      _CBFunc, _CBParam)		\
+	{							\
+		(_Name),					\
+		(_Type),					\
+		(VAR_FLAGS_DYNAMIC_CFG | (_Flags)),		\
+		(_CBParam),					\
+		VAR_OFFSET(_Struct, _VarName),			\
+		VAR_SIZE(_Struct, _VarName),			\
+		(_Default),					\
+		(_Min),						\
+		(_Max),						\
+		(_CBFunc)					\
+	}
+
+#define REG_VARIABLE_STRING(_Name, _Type,  _Struct, _VarName,	\
+			     _Flags, _Default)			\
+	{							\
+		(_Name),					\
+		(_Type),					\
+		(_Flags),					\
+		0,						\
+		VAR_OFFSET(_Struct, _VarName),			\
+		VAR_SIZE(_Struct, _VarName),			\
+		(unsigned long)(_Default),			\
+		0,						\
+		0,						\
+		NULL						\
+	}
+
+struct reg_table_entry {
+	char *RegName;          /* variable name in the qcom_cfg.ini file */
+	unsigned char RegType;    /* variable type in hdd_config struct */
+	unsigned char Flags;    /* Specify optional parms and if RangeCheck is performed */
+	unsigned char notifyId; /* Dynamic modification identifier */
+	unsigned short VarOffset;       /* offset to field from the base address of the structure */
+	unsigned short VarSize; /* size (in bytes) of the field */
+	unsigned long VarDefault;       /* default value to use */
+	unsigned long VarMin;   /* minimum value, for range checking */
+	unsigned long VarMax;   /* maximum value, for range checking */
+	/* Dynamic modification notifier */
+	void (*pfnDynamicnotify)(struct hdd_context *hdd_ctx,
+				 unsigned long notifyId);
+};
+
+/**
+ * hdd_to_csr_wmm_mode() - Utility function to convert HDD to CSR WMM mode
+ *
+ * @uint8_t mode - hdd WMM user mode
+ *
+ * Return: CSR WMM mode
+ */
+eCsrRoamWmmUserModeType hdd_to_csr_wmm_mode(uint8_t mode);
+
+/* Function declarations and documenation */
+QDF_STATUS hdd_parse_config_ini(struct hdd_context *hdd_ctx);
+
+QDF_STATUS hdd_update_mac_config(struct hdd_context *hdd_ctx);
+QDF_STATUS hdd_set_sme_config(struct hdd_context *hdd_ctx);
+QDF_STATUS hdd_set_policy_mgr_user_cfg(struct hdd_context *hdd_ctx);
+QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx);
+bool hdd_update_config_cfg(struct hdd_context *hdd_ctx);
+void hdd_cfg_get_global_config(struct hdd_context *hdd_ctx, char *buf,
+			       int buflen);
+
+eCsrPhyMode hdd_cfg_xlate_to_csr_phy_mode(enum hdd_dot11_mode dot11Mode);
+QDF_STATUS hdd_execute_global_config_command(struct hdd_context *hdd_ctx,
+					     char *command);
+
+bool hdd_is_okc_mode_enabled(struct hdd_context *hdd_ctx);
+QDF_STATUS hdd_set_idle_ps_config(struct hdd_context *hdd_ctx, bool val);
+void hdd_get_pmkid_modes(struct hdd_context *hdd_ctx,
+			 struct pmkid_mode_bits *pmkid_modes);
+
+void hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg);
+
+/**
+ * hdd_string_to_u8_array() - used to convert decimal string into u8 array
+ * @str: Decimal string
+ * @array: Array where converted value is stored
+ * @len: Length of the populated array
+ * @array_max_len: Maximum length of the array
+ *
+ * This API is called to convert decimal string (each byte separated by
+ * a comma) into an u8 array
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS hdd_string_to_u8_array(char *str, uint8_t *array,
+				  uint8_t *len, uint16_t array_max_len);
+
+QDF_STATUS hdd_hex_string_to_u16_array(char *str, uint16_t *int_array,
+				uint8_t *len, uint8_t int_array_max_len);
+
+void hdd_cfg_print_global_config(struct hdd_context *hdd_ctx);
+
+QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss);
+
+/**
+ * hdd_dfs_indicate_radar() - Block tx as radar found on the channel
+ * @hdd_ctxt: HDD context pointer
+ *
+ * This function is invoked in atomic context when a radar
+ * is found on the SAP current operating channel and Data Tx
+ * from netif has to be stopped to honor the DFS regulations.
+ * Actions: Stop the netif Tx queues,Indicate Radar present
+ * in HDD context for future usage.
+ *
+ * Return: true on success, else false
+ */
+bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx);
+#endif
diff --git a/core/hdd/inc/wlan_hdd_conc_ut.h b/core/hdd/inc/wlan_hdd_conc_ut.h
new file mode 100644
index 0000000..c1cc042
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_conc_ut.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015-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.
+ */
+
+#ifndef __WLAN_HDD_CONC_UT_H
+#define __WLAN_HDD_CONC_UT_H
+
+/* Include files */
+
+#include "wlan_hdd_main.h"
+#include "wlan_policy_mgr_api.h"
+#ifdef MPC_UT_FRAMEWORK
+void clean_report(struct hdd_context *hdd_ctx);
+void fill_report(struct hdd_context *hdd_ctx, char *title,
+	uint32_t first_persona, uint32_t second_persona, uint32_t third_persona,
+	uint32_t chnl_1st_conn, uint32_t chnl_2nd_conn, uint32_t chnl_3rd_conn,
+	bool status, enum policy_mgr_pcl_type pcl_type, char *reason,
+	uint8_t *pcl);
+void print_report(struct hdd_context *hdd_ctx);
+void wlan_hdd_one_connection_scenario(struct hdd_context *hdd_ctx);
+void wlan_hdd_two_connections_scenario(struct hdd_context *hdd_ctx,
+	uint8_t first_chnl, enum policy_mgr_chain_mode first_chain_mask);
+void wlan_hdd_three_connections_scenario(struct hdd_context *hdd_ctx,
+	uint8_t first_chnl, uint8_t second_chnl,
+	enum policy_mgr_chain_mode chain_mask, uint8_t use_same_mac);
+#else
+static inline
+void clean_report(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+void fill_report(struct hdd_context *hdd_ctx, char *title,
+	uint32_t first_persona, uint32_t second_persona, uint32_t third_persona,
+	uint32_t chnl_1st_conn, uint32_t chnl_2nd_conn, uint32_t chnl_3rd_conn,
+	bool status, enum policy_mgr_pcl_type pcl_type, char *reason,
+	uint8_t *pcl)
+{
+}
+
+static inline
+void print_report(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+void wlan_hdd_one_connection_scenario(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+void wlan_hdd_two_connections_scenario(struct hdd_context *hdd_ctx,
+		uint8_t first_chnl, enum policy_mgr_chain_mode first_chain_mask)
+{
+}
+
+static inline
+void wlan_hdd_three_connections_scenario(struct hdd_context *hdd_ctx,
+		uint8_t first_chnl, uint8_t second_chnl,
+		enum policy_mgr_chain_mode chain_mask, uint8_t use_same_mac)
+{
+}
+#endif
+#endif
diff --git a/core/hdd/inc/wlan_hdd_data_stall_detection.h b/core/hdd/inc/wlan_hdd_data_stall_detection.h
new file mode 100644
index 0000000..4104ba5
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_data_stall_detection.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef __WLAN_HDD_DATA_STALL_DETECTION_H
+#define __WLAN_HDD_DATA_STALL_DETECTION_H
+
+/**
+ * DOC: wlan_hdd_data_stall_detection.h
+ *
+ * WLAN Host Device Driver data stall detection API specification
+ */
+
+/**
+ * hdd_register_data_stall_detect_cb() - register data stall callback
+ *
+ * Return: 0 for success or Error code for failure
+ */
+int hdd_register_data_stall_detect_cb(void);
+
+/**
+ * hdd_deregister_data_stall_detect_cb() - de-register data stall callback
+ *
+ * Return: 0 for success or Error code for failure
+ */
+int hdd_deregister_data_stall_detect_cb(void);
+#endif /* __WLAN_HDD_DATA_STALL_DETECTION_H */
diff --git a/core/hdd/inc/wlan_hdd_debugfs.h b/core/hdd/inc/wlan_hdd_debugfs.h
new file mode 100644
index 0000000..daa4795
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_debugfs.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#ifndef _WLAN_HDD_DEBUGFS_H
+#define _WLAN_HDD_DEBUGFS_H
+
+#ifdef WLAN_DEBUGFS
+
+#define HDD_DEBUGFS_FILE_NAME_MAX 24
+
+/**
+ * enum hdd_debugfs_file_id - Debugfs file Identifier
+ * @HDD_DEBUFS_FILE_ID_CONNECT_INFO: connect_info file id
+ * @HDD_DEBUFS_FILE_ID_ROAM_SCAN_STATS_INFO: roam_scan_stats file id
+ * @HDD_DEBUFS_FILE_ID_OFFLOAD_INFO: offload_info file id
+ * @HDD_DEBUGFS_FILE_ID_MAX: maximum id of csr debugfs file
+ */
+enum hdd_debugfs_file_id {
+	HDD_DEBUFS_FILE_ID_CONNECT_INFO = 0,
+	HDD_DEBUFS_FILE_ID_ROAM_SCAN_STATS_INFO = 1,
+	HDD_DEBUFS_FILE_ID_OFFLOAD_INFO = 2,
+
+	HDD_DEBUGFS_FILE_ID_MAX,
+};
+
+/**
+ * struct hdd_debugfs_file_info - Debugfs file info
+ * @name: name of debugfs file
+ * @id: id from enum hdd_debugfs_file_id used to identify file
+ * @buf_max_size: max size of buffer from which debugfs file is updated
+ * @entry: dentry pointer to debugfs file
+ */
+struct hdd_debugfs_file_info {
+	uint8_t name[HDD_DEBUGFS_FILE_NAME_MAX];
+	enum hdd_debugfs_file_id id;
+	ssize_t buf_max_size;
+	struct dentry *entry;
+};
+
+QDF_STATUS hdd_debugfs_init(struct hdd_adapter *adapter);
+void hdd_debugfs_exit(struct hdd_adapter *adapter);
+
+/**
+ * hdd_wait_for_debugfs_threads_completion() - Wait for debugfs threads
+ * completion before proceeding further to stop modules
+ *
+ * Return: true if there is no debugfs open
+ *         false if there is at least one debugfs open
+ */
+bool hdd_wait_for_debugfs_threads_completion(void);
+
+/**
+ * hdd_return_debugfs_threads_count() - Return active debugfs threads
+ *
+ * Return: total number of active debugfs threads in driver
+ */
+int hdd_return_debugfs_threads_count(void);
+
+/**
+ * hdd_debugfs_thread_increment() - Increment debugfs thread count
+ *
+ * This function is used to increment and keep track of debugfs thread count.
+ * This is invoked for every file open operation.
+ *
+ * Return: None
+ */
+void hdd_debugfs_thread_increment(void);
+
+/**
+ * hdd_debugfs_thread_decrement() - Decrement debugfs thread count
+ *
+ * This function is used to decrement and keep track of debugfs thread count.
+ * This is invoked for every file release operation.
+ *
+ * Return: None
+ */
+void hdd_debugfs_thread_decrement(void);
+
+#else
+static inline QDF_STATUS hdd_debugfs_init(struct hdd_adapter *adapter)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void hdd_debugfs_exit(struct hdd_adapter *adapter)
+{
+}
+
+/**
+ * hdd_wait_for_debugfs_threads_completion() - Wait for debugfs threads
+ * completion before proceeding further to stop modules
+ *
+ * Return: true if there is no debugfs open
+ *         false if there is at least one debugfs open
+ */
+static inline
+bool hdd_wait_for_debugfs_threads_completion(void)
+{
+	return true;
+}
+
+/**
+ * hdd_return_debugfs_threads_count() - Return active debugfs threads
+ *
+ * Return: total number of active debugfs threads in driver
+ */
+static inline
+int hdd_return_debugfs_threads_count(void)
+{
+	return 0;
+}
+
+/**
+ * hdd_debugfs_thread_increment() - Increment debugfs thread count
+ *
+ * This function is used to increment and keep track of debugfs thread count.
+ * This is invoked for every file open operation.
+ *
+ * Return: None
+ */
+static inline
+void hdd_debugfs_thread_increment(void)
+{
+}
+
+/**
+ * hdd_debugfs_thread_decrement() - Decrement debugfs thread count
+ *
+ * This function is used to decrement and keep track of debugfs thread count.
+ * This is invoked for every file release operation.
+ *
+ * Return: None
+ */
+static inline
+void hdd_debugfs_thread_decrement(void)
+{
+}
+
+#endif /* #ifdef WLAN_DEBUGFS */
+#endif /* #ifndef _WLAN_HDD_DEBUGFS_H */
diff --git a/core/hdd/inc/wlan_hdd_debugfs_csr.h b/core/hdd/inc/wlan_hdd_debugfs_csr.h
new file mode 100644
index 0000000..b8ca56e
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_debugfs_csr.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * 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.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**
+ * DOC: wlan_hdd_debugfs_csr.h
+ *
+ * WLAN Host Device Driver implementation to update
+ * debugfs with connect, scan and roam information
+ */
+
+#ifndef _WLAN_HDD_DEBUGFS_CSR_H
+#define _WLAN_HDD_DEBUGFS_CSR_H
+
+#include <wlan_hdd_includes.h>
+
+#ifdef WLAN_DEBUGFS
+
+#define DEBUGFS_CONNECT_INFO_BUF_SIZE    (4 * 1024)
+#define DEBUGFS_OFFLOAD_INFO_BUF_SIZE    (4 * 1024)
+#define DEBUGFS_ROAM_SCAN_STATS_INFO_BUF_SIZE (4 * 1024)
+
+/**
+ * struct wlan_hdd_debugfs_buffer_info - Debugfs buffer info
+ * @length: current length of the debugfs buffer
+ * @max_buf_len: maximum buffer length of the debugfs buffer
+ * @id: id from enum hdd_debugfs_file_id used to identify file
+ * @data: start of debugfs buffer from which file read starts
+ * @adapter: pointer to adapter
+ *
+ * This structure is used to hold the debugfs buffer details and is stored in
+ * private data of file argument in file open operation.
+ */
+struct wlan_hdd_debugfs_buffer_info {
+	ssize_t length;
+	ssize_t max_buf_len;
+	enum hdd_debugfs_file_id id;
+	uint8_t *data;
+	struct hdd_adapter *adapter;
+};
+
+/**
+ * struct hdd_roam_scan_stats_debugfs_priv - private data for request mgr
+ * @res: pointer to roam scan stats response
+ */
+struct hdd_roam_scan_stats_debugfs_priv {
+	struct wmi_roam_scan_stats_res *roam_scan_stats_res;
+};
+
+/**
+ * wlan_hdd_debugfs_csr_init() - Create wifi diagnostic debugfs files
+ * @adapter: pointer to adapter for which debugfs files are to be created
+ *
+ * Return: None
+ */
+void wlan_hdd_debugfs_csr_init(struct hdd_adapter *adapter);
+
+/**
+ * wlan_hdd_debugfs_csr_deinit() - Remove wifi diagnostic debugfs files
+ * @adapter: pointer to adapter for which debugfs files are to be removed
+ *
+ * Return: None
+ */
+void wlan_hdd_debugfs_csr_deinit(struct hdd_adapter *adapter);
+
+/**
+ * wlan_hdd_current_time_info_debugfs() - API to get time into user buffer
+ * @buf: output buffer to hold current time when queried
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes copied
+ */
+ssize_t
+wlan_hdd_current_time_info_debugfs(uint8_t *buf, ssize_t buf_avail_len);
+
+/**
+ * wlan_hdd_debugfs_update_connect_info() - API to get connect info
+ * into user buffer
+ * @buf: output buffer to hold connect info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes copied
+ */
+ssize_t
+wlan_hdd_debugfs_update_connect_info(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter,
+				     uint8_t *buf, ssize_t buf_avail_len);
+
+/**
+ * wlan_hdd_debugfs_update_filters_info() - API to get offload info
+ * into user buffer
+ * @buf: output buffer to hold offload info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes copied
+ */
+ssize_t
+wlan_hdd_debugfs_update_filters_info(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter,
+				     uint8_t *buf, ssize_t buf_avail_len);
+
+/**
+ * wlan_hdd_debugfs_update_roam_stats() - API to get roam scan stats info
+ * into user buffer
+ * @buf: output buffer to hold roam scan stats info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes copied
+ */
+ssize_t
+wlan_hdd_debugfs_update_roam_stats(struct hdd_context *hdd_ctx,
+				   struct hdd_adapter *adapter,
+				   uint8_t *buf, ssize_t buf_avail_len);
+
+#else
+/**
+ * wlan_hdd_debugfs_csr_init() - Create wifi diagnostic debugfs files
+ * @adapter: pointer to adapter for which debugfs files are to be created
+ *
+ * Return: None
+ */
+static inline void wlan_hdd_debugfs_csr_init(struct hdd_adapter *adapter)
+{
+}
+
+/**
+ * wlan_hdd_debugfs_csr_deinit() - Remove wifi diagnostic debugfs files
+ * @adapter: pointer to adapter for which debugfs files are to be removed
+ *
+ * Return: None
+ */
+static inline void wlan_hdd_debugfs_csr_deinit(struct hdd_adapter *adapter)
+{
+}
+
+/**
+ * wlan_hdd_current_time_info_debugfs() - API to get time into user buffer
+ * @buf: output buffer to hold current time when queried
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes copied
+ */
+static inline ssize_t
+wlan_hdd_current_time_info_debugfs(uint8_t *buf, ssize_t buf_avail_len)
+{
+	return 0;
+}
+
+/**
+ * wlan_hdd_debugfs_update_connect_info() - API to get connect info
+ * into user buffer
+ * @buf: output buffer to hold connect info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes copied
+ */
+static inline ssize_t
+wlan_hdd_debugfs_update_connect_info(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter,
+				     uint8_t *buf, ssize_t buf_avail_len)
+{
+	return 0;
+}
+
+/**
+ * wlan_hdd_debugfs_update_filters_info() - API to get offload info
+ * into user buffer
+ * @buf: output buffer to hold offload info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes copied
+ */
+static inline ssize_t
+wlan_hdd_debugfs_update_filters_info(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter,
+				     uint8_t *buf, ssize_t buf_avail_len)
+{
+	return 0;
+}
+
+/**
+ * wlan_hdd_debugfs_update_roam_stats() - API to get roam scan stats info
+ * into user buffer
+ * @buf: output buffer to hold roam scan stats info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes copied
+ */
+static inline ssize_t
+wlan_hdd_debugfs_update_roam_stats(struct hdd_context *hdd_ctx,
+				   struct hdd_adapter *adapter,
+				   uint8_t *buf, ssize_t buf_avail_len)
+{
+	return 0;
+}
+
+#endif
+
+#endif /* _WLAN_HDD_DEBUGFS_CSR_H */
diff --git a/core/hdd/inc/wlan_hdd_debugfs_llstat.h b/core/hdd/inc/wlan_hdd_debugfs_llstat.h
new file mode 100644
index 0000000..8b7b04e
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_debugfs_llstat.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2013-2018 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: wlan_hdd_debugfs_llstat.h
+ *
+ * WLAN Host Device Driver implementation to update
+ * debugfs with Link Layer statistics
+ */
+
+#ifndef _WLAN_HDD_DEBUGFS_LLSTAT_H
+#define _WLAN_HDD_DEBUGFS_LLSTAT_H
+
+#define DEBUGFS_LLSTATS_BUF_SIZE 12288
+#define DEBUGFS_LLSTATS_REQID   4294967295UL
+#define DEBUGFS_LLSTATS_REQMASK 0x7
+
+#include <wlan_hdd_main.h>
+
+#if defined(WLAN_FEATURE_LINK_LAYER_STATS) && defined(WLAN_DEBUGFS)
+/**
+ * hdd_debugfs_process_peer_stats() - Parse Peer stats and add it to buffer
+ * @adapter: Pointer to device adapter
+ * @data: Pointer to stats data
+ *
+ * Receiving Link Layer peer statistics from FW. This function stores the
+ * firmware data in a buffer to be written into debugfs.
+ *
+ * Return: None
+ */
+void hdd_debugfs_process_peer_stats(struct hdd_adapter *adapter, void *data);
+
+/**
+ * hdd_debugfs_process_radio_stats() - Parse Radio stats and add it to buffer
+ * @adapter: Pointer to device adapter
+ * @more_data: More data
+ * @data: Pointer to stats data
+ * @num_radio: Number of radios
+ *
+ * Receiving Link Layer Radio statistics from FW. This function stores the
+ * firmware data in a buffer to be written into debugfs.
+ *
+ * Return: None
+ */
+void hdd_debugfs_process_radio_stats(struct hdd_adapter *adapter,
+		uint32_t more_data, void *data, uint32_t num_radio);
+
+/**
+ * hdd_link_layer_process_iface_stats() - This function is called after
+ * @adapter: Pointer to device adapter
+ * @data: Pointer to stats data
+ * @num_peers: Number of peers
+ *
+ * Receiving Link Layer Interface statistics from FW.This function converts
+ * the firmware data to the NL data and sends the same to the kernel/upper
+ * layers.
+ *
+ * Return: None
+ */
+void hdd_debugfs_process_iface_stats(struct hdd_adapter *adapter,
+		void *data, uint32_t num_peers);
+
+/**
+ * wlan_hdd_create_ll_stats_file() - API to create Link Layer stats file
+ * @adapter: interface adapter pointer
+ *
+ * Return: 0 on success and errno on failure
+ */
+int wlan_hdd_create_ll_stats_file(struct hdd_adapter *adapter);
+#else
+static inline void hdd_debugfs_process_peer_stats(struct hdd_adapter *adapter,
+						  void *data)
+{
+}
+
+static inline void hdd_debugfs_process_radio_stats(
+			struct hdd_adapter *adapter,
+			uint32_t more_data, void *data, uint32_t num_radio)
+{
+}
+
+static inline void hdd_debugfs_process_iface_stats(
+				struct hdd_adapter *adapter,
+				void *data, uint32_t num_peers)
+{
+}
+static inline int wlan_hdd_create_ll_stats_file(struct hdd_adapter *adapter)
+{
+	return 0;
+}
+#endif
+#endif /* #ifndef _WLAN_HDD_DEBUGFS_LLSTAT_H */
diff --git a/core/hdd/inc/wlan_hdd_driver_ops.h b/core/hdd/inc/wlan_hdd_driver_ops.h
new file mode 100644
index 0000000..d1cc09d
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_driver_ops.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2015-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.
+ */
+
+#ifndef __WLAN_HDD_DRIVER_OPS_H__
+#define __WLAN_HDD_DRIVER_OPS_H__
+
+#include "hif.h"
+
+struct hdd_context;
+
+/**
+ * DOC: wlan_hdd_driver_ops.h
+ *
+ * Functions to register the wlan driver.
+ */
+
+/**
+ * wlan_hdd_register_driver() - Register with platform layer
+ *
+ * This function is used to register HDD callbacks with the platform
+ * layer.
+ *
+ * Return: 0 if registration is successful, negative errno if
+ * registration fails
+ */
+int wlan_hdd_register_driver(void);
+
+/**
+ * wlan_hdd_unregister_driver() - Unregister from platform layer
+ *
+ * This function is used to unregister HDD callbacks from the platform
+ * layer.
+ *
+ * Return: void
+ */
+
+void wlan_hdd_unregister_driver(void);
+
+/**
+ * wlan_hdd_bus_suspend() - suspend the wlan bus
+ *
+ * This function is called by the platform driver to suspend the
+ * wlan bus
+ *
+ * Return: 0 on success, negative errno on error
+ */
+int wlan_hdd_bus_suspend(void);
+
+/**
+ * wlan_hdd_bus_suspend_noirq() - handle .suspend_noirq callback
+ *
+ * This function is called by the platform driver to complete the
+ * bus suspend callback when device interrupts are disabled by kernel.
+ * Call HIF and WMA suspend_noirq callbacks to make sure there is no
+ * wake up pending from FW before allowing suspend.
+ *
+ * Return: 0 for success and -EBUSY if FW is requesting wake up
+ */
+int wlan_hdd_bus_suspend_noirq(void);
+
+/**
+ * wlan_hdd_bus_resume() - wake up the bus
+ *
+ * This function is called by the platform driver to resume wlan
+ * bus
+ *
+ * Return: 0 for success and negative errno if failure
+ */
+int wlan_hdd_bus_resume(void);
+
+/**
+ * wlan_hdd_bus_resume_noirq() - handle bus resume no irq
+ *
+ * This function is called by the platform driver to do bus
+ * resume no IRQ before calling resume callback. Call WMA and HIF
+ * layers to complete the resume_noirq.
+ *
+ * Return: 0 for success and negative error code for failure
+ */
+int wlan_hdd_bus_resume_noirq(void);
+
+/**
+ * hdd_hif_close() - HIF close helper
+ * @hdd_ctx: HDD context
+ * @hif_ctx: HIF context
+ *
+ * Helper function to close HIF
+ */
+void hdd_hif_close(struct hdd_context *hdd_ctx, void *hif_ctx);
+
+/**
+ * hdd_hif_open() - HIF open helper
+ * @dev: wlan device structure
+ * @bdev: bus device structure
+ * @bid: bus identifier for shared busses
+ * @bus_type: underlying bus type
+ * @reinit: true if we are reinitializing the driver during recovery phase
+ *
+ * This function brings-up HIF layer during load/recovery phase.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+int hdd_hif_open(struct device *dev, void *bdev, const struct hif_bus_id *bid,
+		 enum qdf_bus_type bus_type, bool reinit);
+
+#endif /* __WLAN_HDD_DRIVER_OPS_H__ */
diff --git a/core/hdd/inc/wlan_hdd_ether.h b/core/hdd/inc/wlan_hdd_ether.h
new file mode 100644
index 0000000..1c71e01
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_ether.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+#ifndef _WLAN_HDD_ETHER_H
+#define _WLAN_HDD_ETHER_H
+/**
+ * DOC: wlan_hdd_ether.h
+ *
+ * This module describes Ethernet packet formats for processing by HDD.
+ */
+
+/*
+ * Include Files
+ */
+#include <linux/version.h>
+#include <linux/byteorder/generic.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+
+/*
+ * Preprocessor Definitions and Constants
+ */
+#define WLAN_SNAP_OUI_LEN 3
+#define WLAN_SNAP_DSAP 0xAAU
+#define WLAN_SNAP_SSAP 0xAAU
+#define WLAN_SNAP_CTRL 0x03
+#define WLAN_MIN_PROTO 0x0600
+
+/*
+ * Type Declarations
+ */
+struct wlan_snap_hdr {
+	unsigned char dsap;
+	unsigned char ssap;
+	unsigned char ctrl;
+	unsigned char oui[WLAN_SNAP_OUI_LEN];
+} __packed;
+
+struct wlan_8023 {
+	unsigned char h_dest[ETH_ALEN];
+	unsigned char h_source[ETH_ALEN];
+	__be16 h_len;
+	struct wlan_snap_hdr h_snap;
+	__be16 h_proto;
+} __packed;
+
+struct wlan_8023_vlan {
+	unsigned char h_dest[ETH_ALEN];
+	unsigned char h_source[ETH_ALEN];
+	__be16 h_vlan_proto;
+	__be16 h_vlan_TCI;
+	__be16 h_len;
+	struct wlan_snap_hdr h_snap;
+	__be16 h_proto;
+} __packed;
+
+union generic_ethhdr {
+	struct ethhdr eth_II;
+	struct vlan_ethhdr eth_IIv;
+	struct wlan_8023 eth_8023;
+	struct wlan_8023_vlan eth_8023v;
+};
+
+#endif /* #ifndef _WLAN_HDD_ETHER_H */
diff --git a/core/hdd/inc/wlan_hdd_ftm.h b/core/hdd/inc/wlan_hdd_ftm.h
new file mode 100644
index 0000000..d72dd88
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_ftm.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#ifndef WLAN_HDD_FTM_H
+#define WLAN_HDD_FTM_H
+
+/**
+ * DOC: wlan_hdd_ftm.h
+ *
+ * WLAN Host Device Driver Factory Test Mode header file
+ */
+
+#include "qdf_status.h"
+#include "scheduler_api.h"
+#include "cds_api.h"
+#include "qdf_types.h"
+#include <wlan_ptt_sock_svc.h>
+
+struct hdd_context;
+
+#if  defined(QCA_WIFI_FTM)
+int wlan_hdd_qcmbr_unified_ioctl(struct hdd_adapter *adapter,
+				 struct ifreq *ifr);
+int hdd_update_cds_config_ftm(struct hdd_context *hdd_ctx);
+#else
+static inline int hdd_update_cds_config_ftm(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+#endif /* QCA_WIFI_FTM */
+#endif /* WLAN_HDD_FTM_H */
diff --git a/core/hdd/inc/wlan_hdd_he.h b/core/hdd/inc/wlan_hdd_he.h
new file mode 100644
index 0000000..dfa85f6
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_he.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2017-2018 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 : wlan_hdd_he.h
+ *
+ * WLAN Host Device Driver file for 802.11ax (High Efficiency) support.
+ *
+ */
+
+#if !defined(WLAN_HDD_HE_H)
+#define WLAN_HDD_HE_H
+
+struct hdd_context;
+struct wma_tgt_cfg;
+struct hdd_beacon_data;
+struct sap_config;
+
+#ifdef WLAN_FEATURE_11AX
+/**
+ * enum qca_wlan_vendor_attr_get_he_capabilities - attributes for HE caps.
+ *						  vendor command.
+ * @QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_INVALID - invalid
+ * @QCA_WLAN_VENDOR_ATTR_HE_SUPPORTED - to check if HE capabilities is supported
+ * @QCA_WLAN_VENDOR_ATTR_PHY_CAPAB - to get HE PHY capabilities
+ * @QCA_WLAN_VENDOR_ATTR_MAC_CAPAB - to get HE MAC capabilities
+ * @QCA_WLAN_VENDOR_ATTR_HE_MCS - to get HE MCS
+ * @QCA_WLAN_VENDOR_ATTR_NUM_SS - to get NUM SS
+ * @QCA_WLAN_VENDOR_ATTR_RU_IDX_MASK - to get RU index mask
+ * @QCA_WLAN_VENDOR_ATTR_RU_COUNT - to get RU count,
+ * @QCA_WLAN_VENDOR_ATTR_PPE_THRESHOLD - to get PPE Threshold,
+ * @QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_AFTER_LAST - next to last valid enum
+ * @QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_MAX - max value supported
+ *
+ * enum values are used for NL attributes for data used by
+ * QCA_NL80211_VENDOR_SUBCMD_GET_HE_CAPABILITIES sub command.
+ */
+enum qca_wlan_vendor_attr_get_he_capabilities {
+	QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_HE_SUPPORTED,
+	QCA_WLAN_VENDOR_ATTR_PHY_CAPAB,
+	QCA_WLAN_VENDOR_ATTR_MAC_CAPAB,
+	QCA_WLAN_VENDOR_ATTR_HE_MCS,
+	QCA_WLAN_VENDOR_ATTR_NUM_SS = 5,
+	QCA_WLAN_VENDOR_ATTR_RU_IDX_MASK,
+	QCA_WLAN_VENDOR_ATTR_PPE_THRESHOLD,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_MAX =
+	QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_AFTER_LAST - 1,
+};
+
+/**
+ * hdd_update_tgt_he_cap() - Update HE related capabilities
+ * @hdd_ctx: HDD context
+ * @he_cap: Target HE capabilities
+ *
+ * This function updaates WNI CFG with Target capabilities received as part of
+ * Default values present in WNI CFG are the values supported by FW/HW.
+ * INI should be introduced if user control is required to control the value.
+ *
+ * Return: None
+ */
+void hdd_update_tgt_he_cap(struct hdd_context *hdd_ctx,
+			   struct wma_tgt_cfg *cfg);
+
+/**
+ * wlan_hdd_check_11ax_support() - check if beacon IE and update hw mode
+ * @beacon: beacon IE buffer
+ * @config: pointer to sap config
+ *
+ * Check if HE cap IE is present in beacon IE, if present update hw mode
+ * to 11ax.
+ *
+ * Return: None
+ */
+void wlan_hdd_check_11ax_support(struct hdd_beacon_data *beacon,
+				 struct sap_config *config);
+
+/**
+ * hdd_update_he_cap_in_cfg() - update HE cap in global CFG
+ * @hdd_ctx: pointer to hdd context
+ *
+ * This API will update the HE config in CFG after taking intersection
+ * of INI and firmware capabilities provided reading CFG
+ *
+ * Return: 0 on success and errno on failure
+ */
+int hdd_update_he_cap_in_cfg(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_he_set_sme_config() - set HE related SME config param
+ * @sme_config: pointer to SME config
+ * @config: pointer to INI config
+ *
+ * Return: None
+ */
+void hdd_he_set_sme_config(tSmeConfigParams *sme_config,
+			   struct hdd_config *config);
+
+/**
+ * wlan_hdd_cfg80211_get_he_cap() - get HE Capabilities
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 if success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_get_he_cap(struct wiphy *wiphy,
+				 struct wireless_dev *wdev, const void *data,
+				 int data_len);
+#define FEATURE_11AX_VENDOR_COMMANDS					\
+{									\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,			\
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_HE_CAPABILITIES,	\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |				\
+		 WIPHY_VENDOR_CMD_NEED_NETDEV,				\
+	.doit = wlan_hdd_cfg80211_get_he_cap				\
+},
+
+#else
+static inline void hdd_update_tgt_he_cap(struct hdd_context *hdd_ctx,
+					 struct wma_tgt_cfg *cfg)
+{
+}
+
+static inline void wlan_hdd_check_11ax_support(struct hdd_beacon_data *beacon,
+					       struct sap_config *config)
+{
+}
+
+static inline int hdd_update_he_cap_in_cfg(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+
+static inline void hdd_he_set_sme_config(tSmeConfigParams *sme_config,
+					 struct hdd_config *config)
+{
+}
+
+/* dummy definition */
+#define FEATURE_11AX_VENDOR_COMMANDS
+
+#endif
+#endif /* if !defined(WLAN_HDD_HE_H)*/
diff --git a/core/hdd/inc/wlan_hdd_host_offload.h b/core/hdd/inc/wlan_hdd_host_offload.h
new file mode 100644
index 0000000..b1a30dc
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_host_offload.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014-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.
+ */
+
+#ifndef __WLAN_HDD_HOST_OFFLOAD_H__
+#define __WLAN_HDD_HOST_OFFLOAD_H__
+
+/**
+ * DOC: wlan_hdd_host_offload.h
+ *
+ * Android WLAN HDD Host Offload API
+ */
+
+/* Offload types. */
+#define WLAN_IPV4_ARP_REPLY_OFFLOAD           0
+#define WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD  1
+
+/* Enable or disable offload. */
+#define WLAN_OFFLOAD_DISABLE                     0
+#define WLAN_OFFLOAD_ENABLE                      0x1
+#define WLAN_OFFLOAD_BC_FILTER_ENABLE            0x2
+#define WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE    \
+			(WLAN_OFFLOAD_ENABLE | WLAN_OFFLOAD_BC_FILTER_ENABLE)
+
+/* Offload request. */
+struct host_offload_req {
+	uint8_t offloadType;
+	uint8_t enableOrDisable;
+	union {
+		uint8_t hostIpv4Addr[SIR_IPV4_ADDR_LEN];
+		uint8_t hostIpv6Addr[SIR_MAC_IPV6_ADDR_LEN];
+	} params;
+	struct qdf_mac_addr bssId;
+};
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void hdd_wlan_offload_event(uint8_t type, uint8_t state);
+#else
+static inline
+void hdd_wlan_offload_event(uint8_t type, uint8_t state)
+{
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+#endif /* __WLAN_HDD_HOST_OFFLOAD_H__ */
diff --git a/core/hdd/inc/wlan_hdd_includes.h b/core/hdd/inc/wlan_hdd_includes.h
new file mode 100644
index 0000000..1c1c90a
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_includes.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014, 2016-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.
+ */
+
+#if !defined(HDD_INCLUDES_H__)
+#define HDD_INCLUDES_H__
+
+/**
+ * DOC: wlan_hdd_includes.h
+ *
+ * Internal includes for the Linux HDD
+ */
+
+/*
+ * Include files
+ *
+ * throw all the includes in here to get the .c files in the HDD to compile.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/wireless.h>
+#include <linux/if_arp.h>
+#include <cds_api.h>
+#include <sme_api.h>
+#include "wlan_hdd_assoc.h"
+#include "wlan_hdd_wext.h"
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_tx_rx.h"
+#include <cdp_txrx_ops.h>
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+#include "wlan_hdd_oemdata.h"
+#endif
+
+#endif /* end #if !defined(HDD_INCLUDES_H__) */
diff --git a/core/hdd/inc/wlan_hdd_ipa.h b/core/hdd/inc/wlan_hdd_ipa.h
new file mode 100644
index 0000000..72f0c37
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_ipa.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#ifndef HDD_IPA_H__
+#define HDD_IPA_H__
+
+/**
+ * DOC: wlan_hdd_ipa.h
+ *
+ * WLAN IPA interface module headers
+ */
+
+#include <qdf_nbuf.h>
+
+#ifdef IPA_OFFLOAD
+
+/**
+ * hdd_ipa_send_skb_to_network() - Send skb to kernel
+ * @skb: network buffer
+ * @adapter: network adapter
+ *
+ * Called when a network buffer is received which should not be routed
+ * to the IPA module.
+ *
+ * Return: None
+ */
+void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb, qdf_netdev_t dev);
+
+/**
+ * hdd_ipa_set_tx_flow_info() - To set TX flow info if IPA is
+ * enabled
+ *
+ * This routine is called to set TX flow info if IPA is enabled
+ *
+ * Return: None
+ */
+void hdd_ipa_set_tx_flow_info(void);
+
+/**
+ * hdd_ipa_set_mcc_mode() - To set mcc mode if IPA is enabled
+ * @mcc_mode: mcc mode
+ *
+ * This routine is called to set mcc mode if IPA is enabled
+ *
+ * Return: None
+ */
+void hdd_ipa_set_mcc_mode(bool mcc_mode);
+
+#else
+static inline
+void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb, qdf_netdev_t dev)
+{
+}
+
+static inline void hdd_ipa_set_tx_flow_info(void)
+{
+}
+
+static inline void hdd_ipa_set_mcc_mode(bool mcc_mode)
+{
+}
+
+#endif
+#endif /* HDD_IPA_H__ */
diff --git a/core/hdd/inc/wlan_hdd_lro.h b/core/hdd/inc/wlan_hdd_lro.h
new file mode 100644
index 0000000..8377857
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_lro.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015-2018 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.
+ */
+
+#ifndef __WLAN_HDD_LRO_H__
+#define __WLAN_HDD_LRO_H__
+/**
+ * DOC: wlan_hdd_lro.h
+ *
+ * WLAN LRO interface module headers
+ */
+
+struct hdd_context;
+
+#if defined(FEATURE_LRO)
+/**
+ * hdd_lro_rx() - Handle Rx procesing via LRO
+ * @adapter: pointer to adapter context
+ * @skb: pointer to sk_buff
+ *
+ * Return: QDF_STATUS_SUCCESS if processed via LRO or non zero return code
+ */
+QDF_STATUS hdd_lro_rx(struct hdd_adapter *adapter, struct sk_buff *skb);
+
+void hdd_lro_display_stats(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_lro_set_reset() - vendor command for Disable/Enable LRO
+ * @hdd_ctx: hdd context
+ * @hdd_adapter_t: adapter
+ * @enable_flag: enable or disable LRO.
+ *
+ * Return: none
+ */
+QDF_STATUS hdd_lro_set_reset(struct hdd_context *hdd_ctx,
+			     struct hdd_adapter *adapter,
+			     uint8_t enable_flag);
+
+/**
+ * hdd_is_lro_enabled() - Is LRO enabled
+ * @hdd_ctx: HDD context
+ *
+ * This function checks if LRO is enabled in HDD context.
+ *
+ * Return: 0 - success, < 0 - failure
+ */
+int hdd_is_lro_enabled(struct hdd_context *hdd_ctx);
+
+#else
+static inline int hdd_lro_init(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+
+static inline QDF_STATUS hdd_lro_rx(struct hdd_adapter *adapter,
+				    struct sk_buff *skb)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline void hdd_lro_display_stats(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline QDF_STATUS hdd_lro_set_reset(struct hdd_context *hdd_ctx,
+					   struct hdd_adapter *adapter,
+					   uint8_t enable_flag)
+{
+	return 0;
+}
+
+static inline int hdd_is_lro_enabled(struct hdd_context *hdd_ctx)
+{
+	return -EOPNOTSUPP;
+}
+#endif /* FEATURE_LRO */
+#endif /* __WLAN_HDD_LRO_H__ */
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
new file mode 100644
index 0000000..e91c290
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -0,0 +1,3608 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#if !defined(WLAN_HDD_MAIN_H)
+#define WLAN_HDD_MAIN_H
+/**
+ * DOC: wlan_hdd_main.h
+ *
+ * Linux HDD Adapter Type
+ */
+
+/*
+ * The following terms were in use in prior versions of the driver but
+ * have now been replaced with terms that are aligned with the Linux
+ * Coding style. Macros are defined to hopefully prevent new instances
+ * from being introduced, primarily by code propagation.
+ */
+#define pHddCtx
+#define pAdapter
+#define pHostapdAdapter
+#define pHddApCtx
+#define pHddStaCtx
+#define pHostapdState
+#define pRoamInfo
+#define pScanInfo
+#define pBeaconIes
+
+/*
+ * Include files
+ */
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <net/cfg80211.h>
+#include <linux/ieee80211.h>
+#include <qdf_list.h>
+#include <qdf_types.h>
+#include "sir_mac_prot_def.h"
+#include "csr_api.h"
+#include "wlan_dsc.h"
+#include <wlan_hdd_assoc.h>
+#include <wlan_hdd_wmm.h>
+#include <wlan_hdd_cfg.h>
+#include <linux/spinlock.h>
+#if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK)
+#include <linux/wakelock.h>
+#endif
+#include <wlan_hdd_ftm.h>
+#include "wlan_hdd_tdls.h"
+#include "wlan_hdd_tsf.h"
+#include "wlan_hdd_cfg80211.h"
+#include "wlan_hdd_debugfs.h"
+#include <qdf_defer.h>
+#include "sap_api.h"
+#include <wlan_hdd_lro.h>
+#include "cdp_txrx_flow_ctrl_legacy.h"
+#include <cdp_txrx_peer_ops.h>
+#include "wlan_hdd_nan_datapath.h"
+#if defined(CONFIG_HL_SUPPORT)
+#include "wlan_tgt_def_config_hl.h"
+#else
+#include "wlan_tgt_def_config.h"
+#endif
+#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 "wlan_pmo_ucfg_api.h"
+#ifdef WIFI_POS_CONVERGED
+#include "os_if_wifi_pos.h"
+#include "wifi_pos_api.h"
+#else
+#include "wlan_hdd_oemdata.h"
+#endif
+#include "wlan_hdd_he.h"
+
+#include <net/neighbour.h>
+#include <net/netevent.h>
+#include "wlan_hdd_nud_tracking.h"
+#include "wlan_hdd_twt.h"
+#include "wma_sar_public_structs.h"
+#include "wlan_mlme_ucfg_api.h"
+
+/*
+ * Preprocessor definitions and constants
+ */
+
+#ifdef FEATURE_WLAN_APF
+/**
+ * struct hdd_apf_context - hdd Context for apf
+ * @magic: magic number
+ * @qdf_apf_event: Completion variable for APF get operations
+ * @capability_response: capabilities response received from fw
+ * @apf_enabled: True: APF Interpreter enabled, False: Disabled
+ * @cmd_in_progress: Flag that indicates an APF command is in progress
+ * @buf: Buffer to accumulate read memory chunks
+ * @buf_len: Length of the read memory requested
+ * @offset: APF work memory offset to fetch from
+ * @lock: APF Context lock
+ */
+struct hdd_apf_context {
+	unsigned int magic;
+	qdf_event_t qdf_apf_event;
+	bool apf_enabled;
+	bool cmd_in_progress;
+	uint8_t *buf;
+	uint32_t buf_len;
+	uint32_t offset;
+	qdf_spinlock_t lock;
+};
+#endif /* FEATURE_WLAN_APF */
+
+/** Number of Tx Queues */
+#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_HL_NETDEV_FLOW_CONTROL)
+#define NUM_TX_QUEUES 5
+#else
+#define NUM_TX_QUEUES 4
+#endif
+
+/*
+ * API in_compat_syscall() is introduced in 4.6 kernel to check whether we're
+ * in a compat syscall or not. It is a new way to query the syscall type, which
+ * works properly on all architectures.
+ *
+ */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
+static inline bool in_compat_syscall(void) { return is_compat_task(); }
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) || \
+	defined(CFG80211_REMOVE_IEEE80211_BACKPORT)
+#define HDD_NL80211_BAND_2GHZ   NL80211_BAND_2GHZ
+#define HDD_NL80211_BAND_5GHZ   NL80211_BAND_5GHZ
+#define HDD_NUM_NL80211_BANDS   NUM_NL80211_BANDS
+#else
+#define HDD_NL80211_BAND_2GHZ   IEEE80211_BAND_2GHZ
+#define HDD_NL80211_BAND_5GHZ   IEEE80211_BAND_5GHZ
+#define HDD_NUM_NL80211_BANDS   ((enum nl80211_band)IEEE80211_NUM_BANDS)
+#endif
+
+#define TSF_GPIO_PIN_INVALID 255
+
+/** Length of the TX queue for the netdev */
+#define HDD_NETDEV_TX_QUEUE_LEN (3000)
+
+/** Hdd Tx Time out value */
+#ifdef LIBRA_LINUX_PC
+#define HDD_TX_TIMEOUT          (8000)
+#else
+#define HDD_TX_TIMEOUT          msecs_to_jiffies(5000)
+#endif
+
+#define HDD_TX_STALL_THRESHOLD 4
+
+/** Hdd Default MTU */
+#define HDD_DEFAULT_MTU         (1500)
+
+#ifdef QCA_CONFIG_SMP
+#define NUM_CPUS NR_CPUS
+#else
+#define NUM_CPUS 1
+#endif
+
+/**
+ * enum hdd_adapter_flags - event bitmap flags registered net device
+ * @NET_DEVICE_REGISTERED: Adapter is registered with the kernel
+ * @SME_SESSION_OPENED: Firmware vdev has been created
+ * @INIT_TX_RX_SUCCESS: Adapter datapath is initialized
+ * @WMM_INIT_DONE: Adapter is initialized
+ * @SOFTAP_BSS_STARTED: Software Access Point (SAP) is running
+ * @DEVICE_IFACE_OPENED: Adapter has been "opened" via the kernel
+ * @ACS_PENDING: Auto Channel Selection (ACS) is pending
+ * @SOFTAP_INIT_DONE: Software Access Point (SAP) is initialized
+ * @VENDOR_ACS_RESPONSE_PENDING: Waiting for event for vendor acs
+ * @DOWN_DURING_SSR: Mark interface is down during SSR
+ */
+enum hdd_adapter_flags {
+	NET_DEVICE_REGISTERED,
+	SME_SESSION_OPENED,
+	INIT_TX_RX_SUCCESS,
+	WMM_INIT_DONE,
+	SOFTAP_BSS_STARTED,
+	DEVICE_IFACE_OPENED,
+	ACS_PENDING,
+	SOFTAP_INIT_DONE,
+	VENDOR_ACS_RESPONSE_PENDING,
+	DOWN_DURING_SSR,
+};
+
+/**
+ * enum hdd_driver_flags - HDD global event bitmap flags
+ * @ACS_IN_PROGRESS: Auto Channel Selection (ACS) in progress
+ */
+enum hdd_driver_flags {
+	ACS_IN_PROGRESS,
+};
+
+/** Maximum time(ms)to wait for disconnect to complete **/
+/*  This value should be larger than the timeout used by WMA to wait for
+ *  stop vdev response from FW
+ */
+#ifdef QCA_WIFI_3_0_EMU
+#define WLAN_WAIT_TIME_DISCONNECT  7000
+#else
+#define WLAN_WAIT_TIME_DISCONNECT  7000
+#endif
+#define WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS  1000
+#define WLAN_WAIT_TIME_STOP_ROAM  4000
+#define WLAN_WAIT_TIME_STATS       800
+#define WLAN_WAIT_TIME_POWER       800
+#define WLAN_WAIT_TIME_COUNTRY     1000
+#define WLAN_WAIT_TIME_LINK_STATUS 800
+#define WLAN_WAIT_TIME_POWER_STATS 800
+
+#define WLAN_WAIT_TIME_ABORTSCAN         2000
+
+/** Maximum time(ms) to wait for mc thread suspend **/
+#define WLAN_WAIT_TIME_MCTHREAD_SUSPEND  1200
+
+/** Maximum time(ms) to wait for target to be ready for suspend **/
+#define WLAN_WAIT_TIME_READY_TO_SUSPEND  2000
+
+/** Maximum time(ms) to wait for Link Establish Req to complete **/
+#define WAIT_TIME_TDLS_LINK_ESTABLISH_REQ      1500
+
+/** Maximum time(ms) to wait for tdls mgmt to complete **/
+#define WAIT_TIME_TDLS_MGMT         11000
+
+/* Scan Req Timeout */
+#define WLAN_WAIT_TIME_SCAN_REQ 100
+
+#define WLAN_WAIT_TIME_ANTENNA_MODE_REQ 3000
+#define WLAN_WAIT_TIME_SET_DUAL_MAC_CFG 1500
+
+#define WLAN_WAIT_TIME_APF     1000
+
+#define WLAN_WAIT_TIME_FW_ROAM_STATS 1000
+
+/* Maximum time(ms) to wait for RSO CMD status event */
+#define WAIT_TIME_RSO_CMD_STATUS 2000
+
+/* rcpi request timeout in milli seconds */
+#define WLAN_WAIT_TIME_RCPI 500
+
+#define MAX_CFG_STRING_LEN  255
+
+/* Maximum time(ms) to wait for external acs response */
+#define WLAN_VENDOR_ACS_WAIT_TIME 1000
+
+#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+/** Mac Address string **/
+#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC_ADDRESS_STR_LEN 18  /* Including null terminator */
+/* Max and min IEs length in bytes */
+#define MAX_GENIE_LEN (512)
+#define MIN_GENIE_LEN (2)
+
+/** Maximum Length of WPA/RSN IE */
+#define MAX_WPA_RSN_IE_LEN 255
+
+#define WPS_OUI_TYPE   "\x00\x50\xf2\x04"
+#define WPS_OUI_TYPE_SIZE  4
+
+#define SS_OUI_TYPE    "\x00\x16\x32"
+#define SS_OUI_TYPE_SIZE   3
+
+#define P2P_OUI_TYPE   "\x50\x6f\x9a\x09"
+#define P2P_OUI_TYPE_SIZE  4
+
+#define HS20_OUI_TYPE   "\x50\x6f\x9a\x10"
+#define HS20_OUI_TYPE_SIZE  4
+
+#define OSEN_OUI_TYPE   "\x50\x6f\x9a\x12"
+#define OSEN_OUI_TYPE_SIZE  4
+
+#ifdef WLAN_FEATURE_WFD
+#define WFD_OUI_TYPE   "\x50\x6f\x9a\x0a"
+#define WFD_OUI_TYPE_SIZE  4
+#endif
+
+#define MBO_OUI_TYPE   "\x50\x6f\x9a\x16"
+#define MBO_OUI_TYPE_SIZE  4
+
+#define QCN_OUI_TYPE   "\x8c\xfd\xf0\x01"
+#define QCN_OUI_TYPE_SIZE  4
+
+#define wlan_hdd_get_wps_ie_ptr(ie, ie_len) \
+	wlan_get_vendor_ie_ptr_from_oui(WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE, \
+	ie, ie_len)
+
+#define wlan_hdd_get_p2p_ie_ptr(ie, ie_len) \
+	wlan_get_vendor_ie_ptr_from_oui(P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE, \
+	ie, ie_len)
+
+#ifdef WLAN_FEATURE_WFD
+#define wlan_hdd_get_wfd_ie_ptr(ie, ie_len) \
+	wlan_get_vendor_ie_ptr_from_oui(WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE, \
+	ie, ie_len)
+#endif
+
+#define wlan_hdd_get_mbo_ie_ptr(ie, ie_len) \
+	wlan_get_vendor_ie_ptr_from_oui(MBO_OUI_TYPE, MBO_OUI_TYPE_SIZE, \
+	ie, ie_len)
+
+#define WLAN_CHIP_VERSION   "WCNSS"
+
+#define hdd_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_HDD, params)
+#define hdd_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_HDD, params)
+#define hdd_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_HDD, params)
+#define hdd_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_HDD, params)
+#define hdd_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_HDD, params)
+
+#define hdd_nofl_alert(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_HDD, params)
+#define hdd_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_HDD, params)
+#define hdd_nofl_warn(params...) \
+	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_HDD, params)
+#define hdd_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_HDD, params)
+#define hdd_nofl_debug(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_HDD, params)
+
+#define hdd_alert_rl(params...) QDF_TRACE_FATAL_RL(QDF_MODULE_ID_HDD, params)
+#define hdd_err_rl(params...) QDF_TRACE_ERROR_RL(QDF_MODULE_ID_HDD, params)
+#define hdd_warn_rl(params...) QDF_TRACE_WARN_RL(QDF_MODULE_ID_HDD, params)
+#define hdd_info_rl(params...) QDF_TRACE_INFO_RL(QDF_MODULE_ID_HDD, params)
+#define hdd_debug_rl(params...) QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_HDD, params)
+
+#define hdd_enter() QDF_TRACE_ENTER(QDF_MODULE_ID_HDD, "enter")
+#define hdd_enter_dev(dev) \
+	QDF_TRACE_ENTER(QDF_MODULE_ID_HDD, "enter(%s)", (dev)->name)
+#define hdd_exit() QDF_TRACE_EXIT(QDF_MODULE_ID_HDD, "exit")
+
+#define WLAN_HDD_GET_PRIV_PTR(__dev__) \
+		(struct hdd_adapter *)(netdev_priv((__dev__)))
+
+#define MAX_NO_OF_2_4_CHANNELS 14
+
+#define WLAN_HDD_PUBLIC_ACTION_FRAME 4
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET 24
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET 24
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET 30
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET 0
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET 1
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_OFFSET 2
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_TYPE_OFFSET 5
+#define WLAN_HDD_VENDOR_SPECIFIC_ACTION 0x09
+#define WLAN_HDD_WFA_OUI   0x506F9A
+#define WLAN_HDD_WFA_P2P_OUI_TYPE 0x09
+#define WLAN_HDD_P2P_SOCIAL_CHANNELS 3
+#define WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN 1
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET 6
+
+#define WLAN_HDD_IS_SOCIAL_CHANNEL(center_freq)	\
+	(((center_freq) == 2412) || ((center_freq) == 2437) || \
+	((center_freq) == 2462))
+
+#define WLAN_HDD_CHANNEL_IN_UNII_1_BAND(center_freq) \
+	(((center_freq) == 5180) || ((center_freq) == 5200) \
+	 || ((center_freq) == 5220) || ((center_freq) == 5240))
+
+#ifdef WLAN_FEATURE_11W
+#define WLAN_HDD_SA_QUERY_ACTION_FRAME 8
+#endif
+
+#define WLAN_HDD_PUBLIC_ACTION_TDLS_DISC_RESP 14
+#define WLAN_HDD_TDLS_ACTION_FRAME 12
+
+#define WLAN_HDD_QOS_ACTION_FRAME 1
+#define WLAN_HDD_QOS_MAP_CONFIGURE 4
+#define HDD_SAP_WAKE_LOCK_DURATION WAKELOCK_DURATION_RECOMMENDED
+
+/* SAP client disconnect wake lock duration in milli seconds */
+#define HDD_SAP_CLIENT_DISCONNECT_WAKE_LOCK_DURATION \
+	WAKELOCK_DURATION_RECOMMENDED
+
+#if defined(CONFIG_HL_SUPPORT)
+#define HDD_MOD_EXIT_SSR_MAX_RETRIES 200
+#else
+#define HDD_MOD_EXIT_SSR_MAX_RETRIES 75
+#endif
+
+#define HDD_CFG_REQUEST_FIRMWARE_RETRIES (3)
+#define HDD_CFG_REQUEST_FIRMWARE_DELAY (20)
+
+#define MAX_USER_COMMAND_SIZE 4096
+#define DNS_DOMAIN_NAME_MAX_LEN 255
+#define ICMPv6_ADDR_LEN 16
+
+
+#define HDD_MIN_TX_POWER (-100) /* minimum tx power */
+#define HDD_MAX_TX_POWER (+100) /* maximum tx power */
+
+#define HDD_ENABLE_SIFS_BURST_DEFAULT	(1)
+/* If IPA UC data path is enabled, target should reserve extra tx descriptors
+ * for IPA data path.
+ * Then host data path should allow less TX packet pumping in case
+ * IPA data path enabled
+ */
+#define WLAN_TFC_IPAUC_TX_DESC_RESERVE   100
+
+/*
+ * NET_NAME_UNKNOWN is only introduced after Kernel 3.17, to have a macro
+ * here if the Kernel version is less than 3.17 to avoid the interleave
+ * conditional compilation.
+ */
+#if !((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) ||\
+	defined(WITH_BACKPORTS))
+#define NET_NAME_UNKNOWN	0
+#endif
+
+#define PRE_CAC_SSID "pre_cac_ssid"
+
+/* session ID invalid */
+#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
+
+/* wait time for nud stats in milliseconds */
+#define WLAN_WAIT_TIME_NUD_STATS 800
+/* nud stats skb max length */
+#define WLAN_NUD_STATS_LEN 800
+/* ARP packet type for NUD debug stats */
+#define WLAN_NUD_STATS_ARP_PKT_TYPE 1
+/* Assigned size of driver memory dump is 4096 bytes */
+#define DRIVER_MEM_DUMP_SIZE    4096
+
+/*
+ * Generic asynchronous request/response support
+ *
+ * Many of the APIs supported by HDD require a call to SME to
+ * perform an action or to retrieve some data.  In most cases SME
+ * performs the operation asynchronously, and will execute a provided
+ * callback function when the request has completed.  In order to
+ * synchronize this the HDD API allocates a context which is then
+ * passed to SME, and which is then, in turn, passed back to the
+ * callback function when the operation completes.  The callback
+ * function then sets a completion variable inside the context which
+ * the HDD API is waiting on.  In an ideal world the HDD API would
+ * wait forever (or at least for a long time) for the response to be
+ * received and for the completion variable to be set.  However in
+ * most cases these HDD APIs are being invoked in the context of a
+ * user space thread which has invoked either a cfg80211 API or a
+ * wireless extensions ioctl and which has taken the kernel rtnl_lock.
+ * Since this lock is used to synchronize many of the kernel tasks, we
+ * do not want to hold it for a long time.  In addition we do not want
+ * to block user space threads (such as the wpa supplicant's main
+ * thread) for an extended time.  Therefore we only block for a short
+ * time waiting for the response before we timeout.  This means that
+ * it is possible for the HDD API to timeout, and for the callback to
+ * be invoked afterwards.  In order for the callback function to
+ * determine if the HDD API is still waiting, a magic value is also
+ * stored in the shared context.  Only if the context has a valid
+ * magic will the callback routine do any work.  In order to further
+ * synchronize these activities a spinlock is used so that if any HDD
+ * API timeout coincides with its callback, the operations of the two
+ * threads will be serialized.
+ */
+
+extern spinlock_t hdd_context_lock;
+extern struct mutex hdd_init_deinit_lock;
+
+/* MAX OS Q block time value in msec
+ * Prevent from permanent stall, resume OS Q if timer expired
+ */
+#define WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME 1000
+#define WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME 100
+#define WLAN_HDD_TX_FLOW_CONTROL_MAX_24BAND_CH   14
+
+#ifndef NUM_TX_RX_HISTOGRAM
+#define NUM_TX_RX_HISTOGRAM 128
+#endif
+
+#define NUM_TX_RX_HISTOGRAM_MASK (NUM_TX_RX_HISTOGRAM - 1)
+
+/**
+ * enum hdd_auth_key_mgmt - auth key mgmt protocols
+ * @HDD_AUTH_KEY_MGMT_802_1X: 802.1x
+ * @HDD_AUTH_KEY_MGMT_PSK: PSK
+ * @HDD_AUTH_KEY_MGMT_CCKM: CCKM
+ */
+enum hdd_auth_key_mgmt {
+	HDD_AUTH_KEY_MGMT_802_1X = BIT(0),
+	HDD_AUTH_KEY_MGMT_PSK = BIT(1),
+	HDD_AUTH_KEY_MGMT_CCKM = BIT(2)
+};
+
+/**
+ * struct hdd_tx_rx_histogram - structure to keep track of tx and rx packets
+ *				received over 100ms intervals
+ * @interval_rx:	# of rx packets received in the last 100ms interval
+ * @interval_tx:	# of tx packets received in the last 100ms interval
+ * @next_vote_level:	pld_bus_width_type voting level (high or low)
+ *			determined on the basis of total tx and rx packets
+ *			received in the last 100ms interval
+ * @next_rx_level:	pld_bus_width_type voting level (high or low)
+ *			determined on the basis of rx packets received in the
+ *			last 100ms interval
+ * @next_tx_level:	pld_bus_width_type voting level (high or low)
+ *			determined on the basis of tx packets received in the
+ *			last 100ms interval
+ * @qtime		timestamp when the record is added
+ *
+ * The structure keeps track of throughput requirements of wlan driver.
+ * An entry is added if either of next_vote_level, next_rx_level or
+ * next_tx_level changes. An entry is not added for every 100ms interval.
+ */
+struct hdd_tx_rx_histogram {
+	uint64_t interval_rx;
+	uint64_t interval_tx;
+	uint32_t next_vote_level;
+	uint32_t next_rx_level;
+	uint32_t next_tx_level;
+	uint64_t qtime;
+};
+
+struct hdd_tx_rx_stats {
+	/* start_xmit stats */
+	__u32    tx_called;
+	__u32    tx_dropped;
+	__u32    tx_orphaned;
+	__u32    tx_classified_ac[NUM_TX_QUEUES];
+	__u32    tx_dropped_ac[NUM_TX_QUEUES];
+
+	/* rx stats */
+	__u32 rx_packets[NUM_CPUS];
+	__u32 rx_dropped[NUM_CPUS];
+	__u32 rx_delivered[NUM_CPUS];
+	__u32 rx_refused[NUM_CPUS];
+
+	/* txflow stats */
+	bool     is_txflow_paused;
+	__u32    txflow_pause_cnt;
+	__u32    txflow_unpause_cnt;
+	__u32    txflow_timer_cnt;
+
+	/*tx timeout stats*/
+	__u32 tx_timeout_cnt;
+	__u32 cont_txtimeout_cnt;
+	u64 jiffies_last_txtimeout;
+};
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * struct hdd_pmf_stats - Protected Management Frame statistics
+ * @num_unprot_deauth_rx: Number of unprotected deauth frames received
+ * @num_unprot_disassoc_rx: Number of unprotected disassoc frames received
+ */
+struct hdd_pmf_stats {
+	uint8_t num_unprot_deauth_rx;
+	uint8_t num_unprot_disassoc_rx;
+};
+#endif
+
+/**
+ * struct hdd_arp_stats_s - arp debug stats count
+ * @tx_arp_req_count: no. of arp req received from network stack
+ * @rx_arp_rsp_count: no. of arp res received from FW
+ * @tx_dropped: no. of arp req dropped at hdd layer
+ * @rx_dropped: no. of arp res dropped
+ * @rx_delivered: no. of arp res delivered to network stack
+ * @rx_refused: no of arp rsp refused (not delivered) to network stack
+ * @tx_host_fw_sent: no of arp req sent by FW OTA
+ * @rx_host_drop_reorder: no of arp res dropped by host
+ * @rx_fw_cnt: no of arp res received by FW
+ * @tx_ack_cnt: no of arp req acked by FW
+ */
+struct hdd_arp_stats_s {
+	uint16_t tx_arp_req_count;
+	uint16_t rx_arp_rsp_count;
+	uint16_t tx_dropped;
+	uint16_t rx_dropped;
+	uint16_t rx_delivered;
+	uint16_t rx_refused;
+	uint16_t tx_host_fw_sent;
+	uint16_t rx_host_drop_reorder;
+	uint16_t rx_fw_cnt;
+	uint16_t tx_ack_cnt;
+};
+
+/**
+ * struct hdd_dns_stats_s - dns debug stats count
+ * @tx_dns_req_count: no. of dns query received from network stack
+ * @rx_dns_rsp_count: no. of dns res received from FW
+ * @tx_dropped: no. of dns query dropped at hdd layer
+ * @rx_delivered: no. of dns res delivered to network stack
+ * @rx_refused: no of dns res refused (not delivered) to network stack
+ * @tx_host_fw_sent: no of dns query sent by FW OTA
+ * @rx_host_drop: no of dns res dropped by host
+ * @tx_ack_cnt: no of dns req acked by FW
+ */
+struct hdd_dns_stats_s {
+	uint16_t tx_dns_req_count;
+	uint16_t rx_dns_rsp_count;
+	uint16_t tx_dropped;
+	uint16_t rx_delivered;
+	uint16_t rx_refused;
+	uint16_t tx_host_fw_sent;
+	uint16_t rx_host_drop;
+	uint16_t tx_ack_cnt;
+};
+
+/**
+ * struct hdd_tcp_stats_s - tcp debug stats count
+ * @tx_tcp_syn_count: no. of tcp syn received from network stack
+ * @@tx_tcp_ack_count: no. of tcp ack received from network stack
+ * @rx_tcp_syn_ack_count: no. of tcp syn ack received from FW
+ * @tx_tcp_syn_dropped: no. of tcp syn dropped at hdd layer
+ * @tx_tcp_ack_dropped: no. of tcp ack dropped at hdd layer
+ * @rx_delivered: no. of tcp syn ack delivered to network stack
+ * @rx_refused: no of tcp syn ack refused (not delivered) to network stack
+ * @tx_tcp_syn_host_fw_sent: no of tcp syn sent by FW OTA
+ * @@tx_tcp_ack_host_fw_sent: no of tcp ack sent by FW OTA
+ * @rx_host_drop: no of tcp syn ack dropped by host
+ * @tx_tcp_syn_ack_cnt: no of tcp syn acked by FW
+ * @tx_tcp_syn_ack_cnt: no of tcp ack acked by FW
+ * @is_tcp_syn_ack_rcv: flag to check tcp syn ack received or not
+ * @is_tcp_ack_sent: flag to check tcp ack sent or not
+ */
+struct hdd_tcp_stats_s {
+	uint16_t tx_tcp_syn_count;
+	uint16_t tx_tcp_ack_count;
+	uint16_t rx_tcp_syn_ack_count;
+	uint16_t tx_tcp_syn_dropped;
+	uint16_t tx_tcp_ack_dropped;
+	uint16_t rx_delivered;
+	uint16_t rx_refused;
+	uint16_t tx_tcp_syn_host_fw_sent;
+	uint16_t tx_tcp_ack_host_fw_sent;
+	uint16_t rx_host_drop;
+	uint16_t rx_fw_cnt;
+	uint16_t tx_tcp_syn_ack_cnt;
+	uint16_t tx_tcp_ack_ack_cnt;
+	bool is_tcp_syn_ack_rcv;
+	bool is_tcp_ack_sent;
+
+};
+
+/**
+ * struct hdd_icmpv4_stats_s - icmpv4 debug stats count
+ * @tx_icmpv4_req_count: no. of icmpv4 req received from network stack
+ * @rx_icmpv4_rsp_count: no. of icmpv4 res received from FW
+ * @tx_dropped: no. of icmpv4 req dropped at hdd layer
+ * @rx_delivered: no. of icmpv4 res delivered to network stack
+ * @rx_refused: no of icmpv4 res refused (not delivered) to network stack
+ * @tx_host_fw_sent: no of icmpv4 req sent by FW OTA
+ * @rx_host_drop: no of icmpv4 res dropped by host
+ * @rx_fw_cnt: no of icmpv4 res received by FW
+ * @tx_ack_cnt: no of icmpv4 req acked by FW
+ */
+struct hdd_icmpv4_stats_s {
+	uint16_t tx_icmpv4_req_count;
+	uint16_t rx_icmpv4_rsp_count;
+	uint16_t tx_dropped;
+	uint16_t rx_delivered;
+	uint16_t rx_refused;
+	uint16_t tx_host_fw_sent;
+	uint16_t rx_host_drop;
+	uint16_t rx_fw_cnt;
+	uint16_t tx_ack_cnt;
+};
+
+struct hdd_stats {
+	tCsrSummaryStatsInfo summary_stat;
+	tCsrGlobalClassAStatsInfo class_a_stat;
+	tCsrGlobalClassDStatsInfo class_d_stat;
+	struct csr_per_chain_rssi_stats_info  per_chain_rssi_stats;
+	struct hdd_tx_rx_stats tx_rx_stats;
+	struct hdd_arp_stats_s hdd_arp_stats;
+	struct hdd_dns_stats_s hdd_dns_stats;
+	struct hdd_tcp_stats_s hdd_tcp_stats;
+	struct hdd_icmpv4_stats_s hdd_icmpv4_stats;
+#ifdef WLAN_FEATURE_11W
+	struct hdd_pmf_stats hdd_pmf_stats;
+#endif
+};
+
+/**
+ * struct hdd_roaming_info - HDD Internal Roaming Information
+ * @bssid: BSSID to which we are connected
+ * @peer_mac: Peer MAC address for IBSS connection
+ * @roam_id: Unique identifier for a roaming instance
+ * @roam_status: Current roam command status
+ * @defer_key_complete: Should key complete be deferred?
+ *
+ */
+struct hdd_roaming_info {
+	tSirMacAddr bssid;
+	tSirMacAddr peer_mac;
+	uint32_t roam_id;
+	eRoamCmdStatus roam_status;
+	bool defer_key_complete;
+
+};
+
+#ifdef FEATURE_WLAN_WAPI
+/* Define WAPI macros for Length, BKID count etc*/
+#define MAC_ADDR_LEN           6
+#define MAX_NUM_AKM_SUITES    16
+
+/** WAPI AUTH mode definition */
+enum wapi_auth_mode {
+	WAPI_AUTH_MODE_OPEN = 0,
+	WAPI_AUTH_MODE_PSK = 1,
+	WAPI_AUTH_MODE_CERT
+} __packed;
+
+#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
+#define WPA_GET_BE24(a) ((u32) ((a[0] << 16) | (a[1] << 8) | a[2]))
+#define WLAN_EID_WAPI 68
+#define WAPI_PSK_AKM_SUITE  0x02721400
+#define WAPI_CERT_AKM_SUITE 0x01721400
+
+/**
+ * struct hdd_wapi_info - WAPI Information structure definition
+ * @wapi_mode: Is WAPI enabled on this adapter?
+ * @is_wapi_sta: Is the STA associated with WAPI?
+ * @wapi_auth_mode: WAPI authentication mode used by this adapter
+ */
+struct hdd_wapi_info {
+	bool wapi_mode;
+	bool is_wapi_sta;
+	enum wapi_auth_mode wapi_auth_mode;
+};
+#endif /* FEATURE_WLAN_WAPI */
+
+struct hdd_beacon_data {
+	u8 *head;
+	u8 *tail;
+	u8 *proberesp_ies;
+	u8 *assocresp_ies;
+	int head_len;
+	int tail_len;
+	int proberesp_ies_len;
+	int assocresp_ies_len;
+	int dtim_period;
+};
+
+struct action_pkt_buffer {
+	uint8_t *frame_ptr;
+	uint32_t frame_length;
+	uint16_t freq;
+};
+
+/**
+ * struct hdd_scan_req - Scan Request entry
+ * @node : List entry element
+ * @adapter: Adapter address
+ * @scan_request: scan request holder
+ * @scan_id: scan identifier used across host layers which is generated at WMI
+ * @cookie: scan request identifier sent to userspace
+ * @source: scan request originator (NL/Vendor scan)
+ * @timestamp: scan request timestamp
+ *
+ * Scan request linked list element
+ */
+struct hdd_scan_req {
+	qdf_list_node_t node;
+	struct hdd_adapter *adapter;
+	struct cfg80211_scan_request *scan_request;
+	uint32_t scan_id;
+	uint8_t source;
+	uint32_t timestamp;
+	qdf_timer_t hdd_scan_inactivity_timer;
+	uint32_t scan_req_flags;
+};
+
+/**
+ * struct hdd_mon_set_ch_info - Holds monitor mode channel switch params
+ * @channel: Channel number.
+ * @cb_mode: Channel bonding
+ * @channel_width: Channel width 0/1/2 for 20/40/80MHz respectively.
+ * @phy_mode: PHY mode
+ */
+struct hdd_mon_set_ch_info {
+	uint8_t channel;
+	uint8_t cb_mode;
+	uint32_t channel_width;
+	eCsrPhyMode phy_mode;
+};
+
+/**
+ * struct hdd_station_ctx -- STA-specific information
+ * @roam_profile: current roaming profile
+ * @security_ie: WPA or RSN IE used by the @roam_profile
+ * @assoc_additional_ie: association additional IE used by the @roam_profile
+ * @wpa_versions: bitmap of supported WPA versions
+ * @auth_key_mgmt: bitmap of supported auth key mgmt protocols
+ * @requested_bssid: Specific BSSID to which to connect
+ * @conn_info: current connection information
+ * @roam_info: current roaming information
+ * @ft_carrier_on: is carrier on
+ * @ibss_sta_generation: current ibss generation. Incremented whenever
+ *    ibss New peer joins and departs the network
+ * @ibss_enc_key_installed: is the ibss wep/wpa-none encryptions key
+ *    installed?
+ * @ibss_enc_key: current ibss wep/wpa-none encryption key (if
+ *    @ibss_enc_key_installed is %true)
+ * @ibss_peer_info: information about the ibss peer
+ * @hdd_reassoc_scenario: is station in the middle of reassociation?
+ * @sta_debug_state: STA context debug variable
+ * @broadcast_staid: STA ID assigned for broadcast frames
+ * @ch_info: monitor mode channel information
+ * @ndp_ctx: NAN data path context
+ * @ap_supports_immediate_power_save: Does the current AP allow our STA
+ *    to immediately go into power save?
+ */
+struct hdd_station_ctx {
+	struct csr_roam_profile roam_profile;
+	uint8_t security_ie[MAX_WPA_RSN_IE_LEN];
+	tSirAddie assoc_additional_ie;
+	enum nl80211_wpa_versions wpa_versions;
+	enum hdd_auth_key_mgmt auth_key_mgmt;
+	struct qdf_mac_addr requested_bssid;
+	struct hdd_connection_info conn_info;
+	struct hdd_connection_info cache_conn_info;
+	struct hdd_roaming_info roam_info;
+	int ft_carrier_on;
+	int ibss_sta_generation;
+	bool ibss_enc_key_installed;
+	tCsrRoamSetKey ibss_enc_key;
+	tSirPeerInfoRspParams ibss_peer_info;
+	bool hdd_reassoc_scenario;
+	int sta_debug_state;
+	uint8_t broadcast_staid;
+	struct hdd_mon_set_ch_info ch_info;
+	bool ap_supports_immediate_power_save;
+};
+
+/**
+ * enum bss_state - current state of the BSS
+ * @BSS_STOP: BSS is stopped
+ * @BSS_START: BSS is started
+ */
+enum bss_state {
+	BSS_STOP,
+	BSS_START,
+};
+
+/**
+ * struct hdd_hostapd_state - hostapd-related state information
+ * @bss_state: Current state of the BSS
+ * @qdf_event: Event to synchronize actions between hostapd thread and
+ *    internal callback threads
+ * @qdf_stop_bss_event: Event to synchronize Stop BSS. When Stop BSS
+ *    is issued userspace thread can wait on this event. The event will
+ *    be set when the Stop BSS processing in UMAC has completed.
+ * @qdf_sta_disassoc_event: Event to synchronize STA Disassociation.
+ *    When a STA is disassociated userspace thread can wait on this
+ *    event. The event will be set when the STA Disassociation
+ *    processing in UMAC has completed.
+ * @qdf_status: Used to communicate state from other threads to the
+ *    userspace thread.
+ */
+struct hdd_hostapd_state {
+	enum bss_state bss_state;
+	qdf_event_t qdf_event;
+	qdf_event_t qdf_stop_bss_event;
+	qdf_event_t qdf_sta_disassoc_event;
+	QDF_STATUS qdf_status;
+};
+
+/**
+ * enum bss_stop_reason - reasons why a BSS is stopped.
+ * @BSS_STOP_REASON_INVALID: no reason specified explicitly.
+ * @BSS_STOP_DUE_TO_MCC_SCC_SWITCH: BSS stopped due to host
+ *  driver is trying to switch AP role to a different channel
+ *  to maintain SCC mode with the STA role on the same card.
+ *  this usually happens when STA is connected to an external
+ *  AP that runs on a different channel
+ * @BSS_STOP_DUE_TO_VENDOR_CONFIG_CHAN: BSS stopped due to
+ *  vendor subcmd set sap config channel
+ */
+enum bss_stop_reason {
+	BSS_STOP_REASON_INVALID = 0,
+	BSS_STOP_DUE_TO_MCC_SCC_SWITCH = 1,
+	BSS_STOP_DUE_TO_VENDOR_CONFIG_CHAN = 2,
+};
+
+/**
+ * struct hdd_rate_info - rate_info in HDD
+ * @rate: tx/rx rate (kbps)
+ * @mode: 0->11abg legacy, 1->HT, 2->VHT (refer to sir_sme_phy_mode)
+ * @nss: number of streams
+ * @mcs: mcs index for HT/VHT mode
+ * @rate_flags: rate flags for last tx/rx
+ *
+ * rate info in HDD
+ */
+struct hdd_rate_info {
+	uint32_t rate;
+	uint8_t mode;
+	uint8_t nss;
+	uint8_t mcs;
+	uint8_t rate_flags;
+};
+
+/**
+ * struct hdd_fw_txrx_stats - fw txrx status in HDD
+ *                            (refer to station_info struct in Kernel)
+ * @tx_packets: packets transmitted to this station
+ * @tx_bytes: bytes transmitted to this station
+ * @rx_packets: packets received from this station
+ * @rx_bytes: bytes received from this station
+ * @rx_retries: cumulative retry counts
+ * @tx_failed: number of failed transmissions
+ * @rssi: The signal strength (dbm)
+ * @tx_rate: last used tx rate info
+ * @rx_rate: last used rx rate info
+ *
+ * fw txrx status in HDD
+ */
+struct hdd_fw_txrx_stats {
+	uint32_t tx_packets;
+	uint64_t tx_bytes;
+	uint32_t rx_packets;
+	uint64_t rx_bytes;
+	uint32_t tx_retries;
+	uint32_t tx_failed;
+	int8_t rssi;
+	struct hdd_rate_info tx_rate;
+	struct hdd_rate_info rx_rate;
+};
+
+/**
+ * struct dhcp_phase - Per Peer DHCP Phases
+ * @DHCP_PHASE_ACK: upon receiving DHCP_ACK/NAK message in REQUEST phase or
+ *         DHCP_DELINE message in OFFER phase
+ * @DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase
+ * @DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase
+ * @DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase or
+ *         ACK phase (Renewal process)
+ */
+enum dhcp_phase {
+	DHCP_PHASE_ACK,
+	DHCP_PHASE_DISCOVER,
+	DHCP_PHASE_OFFER,
+	DHCP_PHASE_REQUEST
+};
+
+/**
+ * struct dhcp_nego_status - Per Peer DHCP Negotiation Status
+ * @DHCP_NEGO_STOP: when the peer is in ACK phase or client disassociated
+ * @DHCP_NEGO_IN_PROGRESS: when the peer is in DISCOVER or REQUEST
+ *         (Renewal process) phase
+ */
+enum dhcp_nego_status {
+	DHCP_NEGO_STOP,
+	DHCP_NEGO_IN_PROGRESS
+};
+
+/**
+ * struct hdd_station_info - Per station structure kept in HDD for
+ *                                     multiple station support for SoftAP
+ * @in_use: Is the station entry in use?
+ * @sta_id: Station ID reported back from HAL (through SAP).
+ *           Broadcast uses station ID zero by default.
+ * @sta_type: Type of station i.e. p2p client or infrastructure station
+ * @sta_mac: MAC address of the station
+ * @peer_state: Current Station state so HDD knows how to deal with packet
+ *              queue. Most recent states used to change TLSHIM STA state.
+ * @is_qos_enabled: Track QoS status of station
+ * @is_deauth_in_progress: The station entry for which Deauth is in progress
+ * @nss: Number of spatial streams supported
+ * @rate_flags: Rate Flags for this connection
+ * @ecsa_capable: Extended CSA capabilities
+ * @max_phy_rate: Calcuated maximum phy rate based on mode, nss, mcs etc.
+ * @tx_packets: Packets send to current station
+ * @tx_bytes: Bytes send to current station
+ * @rx_packets: Packets received from current station
+ * @rx_bytes: Bytes received from current station
+ * @last_tx_rx_ts: Last tx/rx timestamp with current station
+ * @assoc_ts: Current station association timestamp
+ * @tx_rate: Tx rate with current station reported from F/W
+ * @rx_rate: Rx rate with current station reported from F/W
+ * @ampdu: Ampdu enable or not of the station
+ * @sgi_enable: Short GI enable or not of the station
+ * @tx_stbc: Tx Space-time block coding enable/disable
+ * @rx_stbc: Rx Space-time block coding enable/disable
+ * @ch_width: Channel Width of the connection
+ * @mode: Mode of the connection
+ * @max_supp_idx: Max supported rate index of the station
+ * @max_ext_idx: Max extended supported rate index of the station
+ * @max_mcs_idx: Max supported mcs index of the station
+ * @rx_mcs_map: VHT Rx mcs map
+ * @tx_mcs_map: VHT Tx mcs map
+ * @freq : Frequency of the current station
+ * @dot11_mode: 802.11 Mode of the connection
+ * @ht_present: HT caps present or not in the current station
+ * @vht_present: VHT caps present or not in the current station
+ * @ht_caps: HT capabilities of current station
+ * @vht_caps: VHT capabilities of current station
+ * @reason_code: Disconnection reason code for current station
+ * @rssi: RSSI of the current station reported from F/W
+ */
+struct hdd_station_info {
+	bool in_use;
+	uint8_t sta_id;
+	eStationType sta_type;
+	struct qdf_mac_addr sta_mac;
+	enum ol_txrx_peer_state peer_state;
+	bool is_qos_enabled;
+	bool is_deauth_in_progress;
+	uint8_t   nss;
+	uint32_t  rate_flags;
+	uint8_t   ecsa_capable;
+	uint32_t max_phy_rate;
+	uint32_t tx_packets;
+	uint64_t tx_bytes;
+	uint32_t rx_packets;
+	uint64_t rx_bytes;
+	qdf_time_t last_tx_rx_ts;
+	qdf_time_t assoc_ts;
+	qdf_time_t disassoc_ts;
+	uint32_t tx_rate;
+	uint32_t rx_rate;
+	bool ampdu;
+	bool sgi_enable;
+	bool tx_stbc;
+	bool rx_stbc;
+	tSirMacHTChannelWidth ch_width;
+	uint8_t 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;
+	uint32_t freq;
+	uint8_t dot11_mode;
+	bool ht_present;
+	bool vht_present;
+	struct ieee80211_ht_cap ht_caps;
+	struct ieee80211_vht_cap vht_caps;
+	uint32_t reason_code;
+	int8_t rssi;
+	enum dhcp_phase dhcp_phase;
+	enum dhcp_nego_status dhcp_nego_status;
+};
+
+/**
+ * struct hdd_ap_ctx - SAP/P2PGO specific information
+ * @hostapd_state: state control information
+ * @dfs_cac_block_tx: Is data tramsmission blocked due to DFS CAC?
+ * @ap_active: Are any stations active?
+ * @disable_intrabss_fwd: Prevent forwarding between stations
+ * @broadcast_sta_id: Station ID assigned after BSS starts
+ * @privacy: The privacy bits of configuration
+ * @encryption_type: The encryption being used
+ * @group_key: Group Encryption Key
+ * @wep_key: WEP key array
+ * @wep_def_key_idx: WEP default key index
+ * @sap_context: Pointer to context maintained by SAP (opaque to HDD)
+ * @sap_config: SAP configuration
+ * @operating_channel: channel upon which the SAP is operating
+ * @beacon: Beacon information
+ * @vendor_acs_timer: Timer for ACS
+ * @vendor_acs_timer_initialized: Is @vendor_acs_timer initialized?
+ * @bss_stop_reason: Reason why the BSS was stopped
+ * @txrx_stats: TX RX statistics from firmware
+ * @acs_in_progress: In progress acs flag for an adapter
+ */
+struct hdd_ap_ctx {
+	struct hdd_hostapd_state hostapd_state;
+	bool dfs_cac_block_tx;
+	bool ap_active;
+	bool disable_intrabss_fwd;
+	uint8_t broadcast_sta_id;
+	uint8_t privacy;
+	eCsrEncryptionType encryption_type;
+	tCsrRoamSetKey group_key;
+	tCsrRoamSetKey wep_key[CSR_MAX_NUM_KEY];
+	uint8_t wep_def_key_idx;
+	struct sap_context *sap_context;
+	tsap_config_t sap_config;
+	uint8_t operating_channel;
+	struct hdd_beacon_data *beacon;
+	qdf_mc_timer_t vendor_acs_timer;
+	bool vendor_acs_timer_initialized;
+	enum bss_stop_reason bss_stop_reason;
+	struct hdd_fw_txrx_stats txrx_stats;
+	qdf_atomic_t acs_in_progress;
+};
+
+/**
+ * struct hdd_scan_info - Per-adapter scan information
+ * @scan_add_ie: Additional IE for scan
+ * @default_scan_ies: Default scan IEs
+ * @default_scan_ies_len: Length of @default_scan_ies
+ * @scan_mode: Scan mode
+ */
+struct hdd_scan_info {
+	tSirAddie scan_add_ie;
+	uint8_t *default_scan_ies;
+	uint16_t default_scan_ies_len;
+	tSirScanType scan_mode;
+};
+
+#define WLAN_HDD_MAX_MC_ADDR_LIST CFG_TGT_MAX_MULTICAST_FILTER_ENTRIES
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+struct hdd_multicast_addr_list {
+	uint8_t mc_cnt;
+	uint8_t addr[WLAN_HDD_MAX_MC_ADDR_LIST][ETH_ALEN];
+};
+#endif
+
+#define WLAN_HDD_MAX_HISTORY_ENTRY		10
+
+/**
+ * struct hdd_netif_queue_stats - netif queue operation statistics
+ * @pause_count - pause counter
+ * @unpause_count - unpause counter
+ */
+struct hdd_netif_queue_stats {
+	u32 pause_count;
+	u32 unpause_count;
+	qdf_time_t total_pause_time;
+};
+
+/**
+ * struct hdd_netif_queue_history - netif queue operation history
+ * @time: timestamp
+ * @netif_action: action type
+ * @netif_reason: reason type
+ * @pause_map: pause map
+ */
+struct hdd_netif_queue_history {
+	qdf_time_t time;
+	uint16_t netif_action;
+	uint16_t netif_reason;
+	uint32_t pause_map;
+};
+
+/**
+ * struct hdd_chan_change_params - channel related information
+ * @chan: operating channel
+ * @chan_params: channel parameters
+ */
+struct hdd_chan_change_params {
+	uint8_t chan;
+	struct ch_params chan_params;
+};
+
+/**
+ * struct hdd_runtime_pm_context - context to prevent/allow runtime pm
+ * @dfs: dfs context to prevent/allow runtime pm
+ * @connect: connect context to prevent/allow runtime pm
+ *
+ * Runtime PM control for underlying activities
+ */
+struct hdd_runtime_pm_context {
+	qdf_runtime_lock_t dfs;
+	qdf_runtime_lock_t connect;
+};
+
+/**
+ * struct hdd_connect_pm_context - Runtime PM connect context per adapter
+ * @connect: Runtime Connect Context
+ *
+ * Structure to hold runtime pm connect context for each adapter.
+ */
+struct hdd_connect_pm_context {
+	qdf_runtime_lock_t connect;
+};
+
+/*
+ * WLAN_HDD_ADAPTER_MAGIC is a magic number used to identify net devices
+ * belonging to this driver from net devices belonging to other devices.
+ * Therefore, the magic number must be unique relative to the numbers for
+ * other drivers in the system. If WLAN_HDD_ADAPTER_MAGIC is already defined
+ * (e.g. by compiler argument), then use that. If it's not already defined,
+ * then use the first 4 characters of MULTI_IF_NAME to construct the magic
+ * number. If MULTI_IF_NAME is not defined, then use a default magic number.
+ */
+#ifndef WLAN_HDD_ADAPTER_MAGIC
+#ifdef MULTI_IF_NAME
+#define WLAN_HDD_ADAPTER_MAGIC                                          \
+	(MULTI_IF_NAME[0] == 0 ? 0x574c414e :                           \
+	(MULTI_IF_NAME[1] == 0 ? (MULTI_IF_NAME[0] << 24) :             \
+	(MULTI_IF_NAME[2] == 0 ? (MULTI_IF_NAME[0] << 24) |             \
+		(MULTI_IF_NAME[1] << 16) :                              \
+	(MULTI_IF_NAME[0] << 24) | (MULTI_IF_NAME[1] << 16) |           \
+	(MULTI_IF_NAME[2] << 8) | MULTI_IF_NAME[3])))
+#else
+#define WLAN_HDD_ADAPTER_MAGIC 0x574c414e       /* ASCII "WLAN" */
+#endif
+#endif
+
+/**
+ * struct rcpi_info - rcpi info
+ * @rcpi: computed value in dB
+ * @mac_addr: peer mac addr for which rcpi is computed
+ */
+struct rcpi_info {
+	int32_t rcpi;
+	struct qdf_mac_addr mac_addr;
+};
+
+struct hdd_context;
+
+/**
+ * struct hdd_adapter - hdd vdev/net_device context
+ * @vdev: object manager vdev context
+ * @event_flags: a bitmap of hdd_adapter_flags
+ */
+struct hdd_adapter {
+	/* Magic cookie for adapter sanity verification.  Note that this
+	 * needs to be at the beginning of the private data structure so
+	 * that it will exist at the beginning of dev->priv and hence
+	 * will always be in mapped memory
+	 */
+	uint32_t magic;
+
+	/* list node for membership in the adapter list */
+	qdf_list_node_t node;
+
+	struct hdd_context *hdd_ctx;
+	struct wlan_objmgr_vdev *vdev;
+
+	void *txrx_vdev;
+
+	/** Handle to the network device */
+	struct net_device *dev;
+
+	enum QDF_OPMODE device_mode;
+
+	/** IPv4 notifier callback for handling ARP offload on change in IP */
+	struct work_struct ipv4_notifier_work;
+#ifdef WLAN_NS_OFFLOAD
+	/** IPv6 notifier callback for handling NS offload on change in IP */
+	struct work_struct ipv6_notifier_work;
+#endif
+
+	/* TODO Move this to sta Ctx */
+	struct wireless_dev wdev;
+
+	/** ops checks if Opportunistic Power Save is Enable or Not
+	 * ctw stores ctWindow value once we receive Opps command from
+	 * wpa_supplicant then using ctWindow value we need to Enable
+	 * Opportunistic Power Save
+	 */
+	uint8_t ops;
+	uint32_t ctw;
+
+	/** Current MAC Address for the adapter  */
+	struct qdf_mac_addr mac_addr;
+
+#ifdef WLAN_NUD_TRACKING
+	struct hdd_nud_tracking_info nud_tracking;
+#endif
+	bool disconnection_in_progress;
+	qdf_mutex_t disconnection_status_lock;
+	unsigned long event_flags;
+
+	/**Device TX/RX statistics*/
+	struct net_device_stats stats;
+	/** HDD statistics*/
+	struct hdd_stats hdd_stats;
+
+	/* estimated link speed */
+	uint32_t estimated_linkspeed;
+
+	uint8_t session_id;
+
+	/* QDF event for session close */
+	qdf_event_t qdf_session_close_event;
+
+	/* QDF event for session open */
+	qdf_event_t qdf_session_open_event;
+
+	/* TODO: move these to sta ctx. These may not be used in AP */
+	/** completion variable for disconnect callback */
+	struct completion disconnect_comp_var;
+
+	struct completion roaming_comp_var;
+
+	/* completion variable for Linkup Event */
+	struct completion linkup_event_var;
+
+	/* completion variable for cancel remain on channel Event */
+	struct completion cancel_rem_on_chan_var;
+
+	/* completion variable for off channel  remain on channel Event */
+	struct completion offchannel_tx_event;
+	/* Completion variable for action frame */
+	struct completion tx_action_cnf_event;
+	/* Completion variable for remain on channel ready */
+	struct completion rem_on_chan_ready_event;
+
+	struct completion sta_authorized_event;
+
+	struct completion ibss_peer_info_comp;
+
+	/* Track whether the linkup handling is needed  */
+	bool is_link_up_service_needed;
+
+	/* WMM Status */
+	struct hdd_wmm_status hdd_wmm_status;
+
+	/** Multiple station supports */
+	/** Per-station structure */
+	spinlock_t sta_info_lock;        /* To protect access to station Info */
+	struct hdd_station_info sta_info[WLAN_MAX_STA_COUNT];
+	struct hdd_station_info cache_sta_info[WLAN_MAX_STA_COUNT];
+
+
+#ifdef FEATURE_WLAN_WAPI
+	struct hdd_wapi_info wapi_info;
+#endif
+
+	int8_t rssi;
+	int32_t rssi_on_disconnect;
+#ifdef WLAN_FEATURE_LPSS
+	bool rssi_send;
+#endif
+
+	uint8_t snr;
+
+	struct work_struct  sap_stop_bss_work;
+
+	union {
+		struct hdd_station_ctx station;
+		struct hdd_ap_ctx ap;
+	} session;
+
+	qdf_atomic_t dfs_radar_found;
+
+#ifdef WLAN_FEATURE_TSF
+	/* tsf value received from firmware */
+	uint64_t cur_target_time;
+	uint64_t tsf_sync_soc_timer;
+	qdf_mc_timer_t host_capture_req_timer;
+#ifdef WLAN_FEATURE_TSF_PLUS
+	/* spin lock for read/write timestamps */
+	qdf_spinlock_t host_target_sync_lock;
+	qdf_mc_timer_t host_target_sync_timer;
+	uint64_t cur_host_time;
+	uint64_t last_host_time;
+	uint64_t last_target_time;
+	/* to store the count of continuous invalid tstamp-pair */
+	int continuous_error_count;
+	/* to indicate whether tsf_sync has been initialized */
+	qdf_atomic_t tsf_sync_ready_flag;
+#endif /* WLAN_FEATURE_TSF_PLUS */
+#endif
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+	struct hdd_multicast_addr_list mc_addr_list;
+#endif
+	uint8_t addr_filter_pattern;
+
+	bool survey_idx;
+
+	struct hdd_scan_info scan_info;
+
+	/* Flag to ensure PSB is configured through framework */
+	uint8_t psb_changed;
+	/* UAPSD psb value configured through framework */
+	uint8_t configured_psb;
+#ifdef IPA_OFFLOAD
+	void *ipa_context;
+#endif
+	/* Use delayed work for Sec AP ACS as Pri AP Startup need to complete
+	 * since CSR (PMAC Struct) Config is same for both AP
+	 */
+	struct delayed_work acs_pending_work;
+
+	struct work_struct scan_block_work;
+	qdf_list_t blocked_scan_request_q;
+	qdf_mutex_t blocked_scan_request_q_lock;
+#ifdef MSM_PLATFORM
+	unsigned long prev_rx_packets;
+	unsigned long prev_tx_packets;
+	uint64_t prev_fwd_tx_packets;
+	uint64_t prev_fwd_rx_packets;
+	int connection;
+#endif
+#if  defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \
+				defined(QCA_HL_NETDEV_FLOW_CONTROL)
+	qdf_mc_timer_t tx_flow_control_timer;
+	bool tx_flow_timer_initialized;
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL || QCA_HL_NETDEV_FLOW_CONTROL */
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+	unsigned int tx_flow_low_watermark;
+	unsigned int tx_flow_hi_watermark_offset;
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+
+	bool offloads_configured;
+
+	/* DSCP to UP QoS Mapping */
+	enum sme_qos_wmmuptype dscp_to_up_map[WLAN_HDD_MAX_DSCP + 1];
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+	bool is_link_layer_stats_set;
+#endif
+	uint8_t link_status;
+
+	/* variable for temperature in Celsius */
+	int temperature;
+
+#ifdef WLAN_FEATURE_DSRC
+	/* MAC addresses used for OCB interfaces */
+	struct qdf_mac_addr ocb_mac_address[QDF_MAX_CONCURRENCY_PERSONA];
+	int ocb_mac_addr_count;
+#endif
+
+	/* BITMAP indicating pause reason */
+	uint32_t pause_map;
+	spinlock_t pause_map_lock;
+	qdf_time_t start_time;
+	qdf_time_t last_time;
+	qdf_time_t total_pause_time;
+	qdf_time_t total_unpause_time;
+	uint8_t history_index;
+	struct hdd_netif_queue_history
+		 queue_oper_history[WLAN_HDD_MAX_HISTORY_ENTRY];
+	struct hdd_netif_queue_stats queue_oper_stats[WLAN_REASON_TYPE_MAX];
+	ol_txrx_tx_fp tx_fn;
+	/* debugfs entry */
+	struct dentry *debugfs_phy;
+	/*
+	 * The pre cac channel is saved here and will be used when the SAP's
+	 * channel needs to be moved from the existing 2.4GHz channel.
+	 */
+	uint8_t pre_cac_chan;
+
+	/*
+	 * Indicate if HO fails during disconnect so that
+	 * disconnect is not initiated by HDD as its already
+	 * initiated by CSR
+	 */
+	bool roam_ho_fail;
+	struct lfr_firmware_status lfr_fw_status;
+	bool con_status;
+	bool dad;
+	uint8_t active_ac;
+	uint32_t pkt_type_bitmap;
+	uint32_t track_arp_ip;
+	uint8_t dns_payload[256];
+	uint32_t track_dns_domain_len;
+	uint32_t track_src_port;
+	uint32_t track_dest_port;
+	uint32_t track_dest_ipv4;
+	uint32_t mon_chan;
+	uint32_t mon_bandwidth;
+
+	/* rcpi information */
+	struct rcpi_info rcpi;
+	bool send_mode_change;
+#ifdef FEATURE_WLAN_APF
+	struct hdd_apf_context apf_context;
+#endif /* FEATURE_WLAN_APF */
+
+#ifdef WLAN_DEBUGFS
+	struct hdd_debugfs_file_info csr_file[HDD_DEBUGFS_FILE_ID_MAX];
+#endif /* WLAN_DEBUGFS */
+};
+
+#define WLAN_HDD_GET_STATION_CTX_PTR(adapter) (&(adapter)->session.station)
+#define WLAN_HDD_GET_AP_CTX_PTR(adapter) (&(adapter)->session.ap)
+#define WLAN_HDD_GET_CTX(adapter) ((adapter)->hdd_ctx)
+#define WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter) \
+				(&(adapter)->session.ap.hostapd_state)
+#define WLAN_HDD_GET_SAP_CTX_PTR(adapter) ((adapter)->session.ap.sap_context)
+
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+#define WLAN_HDD_IS_NDP_ENABLED(hdd_ctx) ((hdd_ctx)->nan_datapath_enabled)
+#else
+/* WLAN_HDD_GET_NDP_CTX_PTR and WLAN_HDD_GET_NDP_WEXT_STATE_PTR are not defined
+ * intentionally so that all references to these must be within NDP code.
+ * non-NDP code can call WLAN_HDD_IS_NDP_ENABLED(), and when it is enabled,
+ * invoke NDP code to do all work.
+ */
+#define WLAN_HDD_IS_NDP_ENABLED(hdd_ctx) (false)
+#endif
+
+/* Set mac address locally administered bit */
+#define WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macaddr) (macaddr[0] &= 0xFD)
+
+#define HDD_DEFAULT_MCC_P2P_QUOTA    70
+#define HDD_RESET_MCC_P2P_QUOTA      50
+
+/*
+ * struct hdd_priv_data - driver ioctl private data payload
+ * @buf: pointer to command buffer (may be in userspace)
+ * @used_len: length of the command/data currently in @buf
+ * @total_len: total length of the @buf memory allocation
+ */
+struct hdd_priv_data {
+	uint8_t *buf;
+	int used_len;
+	int total_len;
+};
+
+#define  MAX_MOD_LOGLEVEL 10
+struct fw_log_info {
+	uint8_t enable;
+	uint8_t dl_type;
+	uint8_t dl_report;
+	uint8_t dl_loglevel;
+	uint8_t index;
+	uint32_t dl_mod_loglevel[MAX_MOD_LOGLEVEL];
+
+};
+
+/**
+ * enum antenna_mode - number of TX/RX chains
+ * @HDD_ANTENNA_MODE_INVALID: Invalid mode place holder
+ * @HDD_ANTENNA_MODE_1X1: Number of TX/RX chains equals 1
+ * @HDD_ANTENNA_MODE_2X2: Number of TX/RX chains equals 2
+ * @HDD_ANTENNA_MODE_MAX: Place holder for max mode
+ */
+enum antenna_mode {
+	HDD_ANTENNA_MODE_INVALID,
+	HDD_ANTENNA_MODE_1X1,
+	HDD_ANTENNA_MODE_2X2,
+	HDD_ANTENNA_MODE_MAX
+};
+
+/**
+ * enum smps_mode - SM power save mode
+ * @HDD_SMPS_MODE_STATIC: Static power save
+ * @HDD_SMPS_MODE_DYNAMIC: Dynamic power save
+ * @HDD_SMPS_MODE_RESERVED: Reserved
+ * @HDD_SMPS_MODE_DISABLED: Disable power save
+ * @HDD_SMPS_MODE_MAX: Place holder for max mode
+ */
+enum smps_mode {
+	HDD_SMPS_MODE_STATIC,
+	HDD_SMPS_MODE_DYNAMIC,
+	HDD_SMPS_MODE_RESERVED,
+	HDD_SMPS_MODE_DISABLED,
+	HDD_SMPS_MODE_MAX
+};
+
+#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
+/**
+ * struct hdd_offloaded_packets - request id to pattern id mapping
+ * @request_id: request id
+ * @pattern_id: pattern id
+ *
+ */
+struct hdd_offloaded_packets {
+	uint32_t request_id;
+	uint8_t  pattern_id;
+};
+
+/**
+ * struct hdd_offloaded_packets_ctx - offloaded packets context
+ * @op_table: request id to pattern id table
+ * @op_lock: mutex lock
+ */
+struct hdd_offloaded_packets_ctx {
+	struct hdd_offloaded_packets op_table[MAXNUM_PERIODIC_TX_PTRNS];
+	struct mutex op_lock;
+};
+#endif
+
+/**
+ * enum driver_status: Driver Modules status
+ * @DRIVER_MODULES_UNINITIALIZED: Driver CDS modules uninitialized
+ * @DRIVER_MODULES_ENABLED: Driver CDS modules opened
+ * @DRIVER_MODULES_CLOSED: Driver CDS modules closed
+ */
+enum driver_modules_status {
+	DRIVER_MODULES_UNINITIALIZED,
+	DRIVER_MODULES_ENABLED,
+	DRIVER_MODULES_CLOSED
+};
+
+/**
+ * struct acs_dfs_policy - Define ACS policies
+ * @acs_dfs_mode: Dfs mode enabled/disabled.
+ * @acs_channel: pre defined channel to avoid ACS.
+ */
+struct acs_dfs_policy {
+	enum dfs_mode acs_dfs_mode;
+	uint8_t acs_channel;
+};
+
+/**
+ * enum suspend_fail_reason: Reasons a WLAN suspend might fail
+ * SUSPEND_FAIL_IPA: IPA in progress
+ * SUSPEND_FAIL_RADAR: radar scan in progress
+ * SUSPEND_FAIL_ROAM: roaming in progress
+ * SUSPEND_FAIL_SCAN: scan in progress
+ * SUSPEND_FAIL_INITIAL_WAKEUP: received initial wakeup from firmware
+ * SUSPEND_FAIL_MAX_COUNT: the number of wakeup reasons, always at the end
+ */
+enum suspend_fail_reason {
+	SUSPEND_FAIL_IPA,
+	SUSPEND_FAIL_RADAR,
+	SUSPEND_FAIL_ROAM,
+	SUSPEND_FAIL_SCAN,
+	SUSPEND_FAIL_INITIAL_WAKEUP,
+	SUSPEND_FAIL_MAX_COUNT
+};
+
+/**
+ * suspend_resume_stats - Collection of counters for suspend/resume events
+ * @suspends: number of suspends completed
+ * @resumes: number of resumes completed
+ * @suspend_fail: counters for failed suspend reasons
+ */
+struct suspend_resume_stats {
+	uint32_t suspends;
+	uint32_t resumes;
+	uint32_t suspend_fail[SUSPEND_FAIL_MAX_COUNT];
+};
+
+/**
+ * hdd_sta_smps_param  - SMPS parameters to configure from hdd
+ * HDD_STA_SMPS_PARAM_UPPER_RSSI_THRESH: RSSI threshold to enter Dynamic SMPS
+ * mode from inactive mode
+ * HDD_STA_SMPS_PARAM_STALL_RSSI_THRESH:  RSSI threshold to enter
+ * Stalled-D-SMPS mode from D-SMPS mode or to enter D-SMPS mode from
+ * Stalled-D-SMPS mode
+ * HDD_STA_SMPS_PARAM_LOWER_RSSI_THRESH:  RSSI threshold to disable SMPS modes
+ * HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH: Upper threshold for beacon-RSSI.
+ * Used to reduce RX chainmask.
+ * HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH:  Lower threshold for beacon-RSSI.
+ * Used to increase RX chainmask.
+ * HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE: Enable/Disable DTIM 1chRx feature
+ */
+enum hdd_sta_smps_param {
+	HDD_STA_SMPS_PARAM_UPPER_RSSI_THRESH = 0,
+	HDD_STA_SMPS_PARAM_STALL_RSSI_THRESH = 1,
+	HDD_STA_SMPS_PARAM_LOWER_RSSI_THRESH = 2,
+	HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH = 3,
+	HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH = 4,
+	HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE = 5
+};
+
+/**
+ * enum RX_OFFLOAD - Receive offload modes
+ * @CFG_LRO_ENABLED: Large Rx offload
+ * @CFG_GRO_ENABLED: Generic Rx Offload
+ */
+enum RX_OFFLOAD {
+	CFG_LRO_ENABLED = 1,
+	CFG_GRO_ENABLED,
+};
+
+/* One per STA: 1 for BCMC_STA_ID, 1 for each SAP_SELF_STA_ID,
+ * 1 for WDS_STAID
+ */
+#define HDD_MAX_ADAPTERS (WLAN_MAX_STA_COUNT + QDF_MAX_NO_OF_SAP_MODE + 2)
+
+#ifdef DISABLE_CHANNEL_LIST
+
+/**
+ * struct hdd_cache_channel_info - Structure of the channel info
+ * which needs to be cached
+ * @channel_num: channel number
+ * @reg_status: Current regulatory status of the channel
+ * Enable
+ * Disable
+ * DFS
+ * Invalid
+ * @wiphy_status: Current wiphy status
+ */
+struct hdd_cache_channel_info {
+	uint32_t channel_num;
+	enum channel_state reg_status;
+	uint32_t wiphy_status;
+};
+
+/**
+ * struct hdd_cache_channels - Structure of the channels to be cached
+ * @num_channels: Number of channels to be cached
+ * @channel_info: Structure of the channel info
+ */
+struct hdd_cache_channels {
+	uint32_t num_channels;
+	struct hdd_cache_channel_info *channel_info;
+};
+#endif
+
+enum hdd_driver_state {
+	driver_state_uninit,
+	driver_state_deinit,
+	driver_state_loaded,
+};
+
+/**
+ * struct hdd_driver - HDD driver-level context information
+ * @dsc_driver: driver synchronization driver context handle
+ * @state: the current stable state of the driver
+ */
+struct hdd_driver {
+	struct dsc_driver *dsc_driver;
+	enum hdd_driver_state state;
+};
+
+struct hdd_driver *hdd_driver_get(void);
+
+/**
+ * struct hdd_context - hdd shared driver and psoc/device context
+ * @psoc: object manager psoc context
+ * @pdev: object manager pdev context
+ * @g_event_flags: a bitmap of hdd_driver_flags
+ * @psoc_idle_timeout_work: delayed work for psoc idle shutdown
+ */
+struct hdd_context {
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	mac_handle_t mac_handle;
+	struct wiphy *wiphy;
+	qdf_spinlock_t hdd_adapter_lock;
+	qdf_list_t hdd_adapters; /* List of adapters */
+
+	struct hdd_adapter *sta_to_adapter[HDD_MAX_ADAPTERS];
+
+	/** Pointer for firmware image data */
+	const struct firmware *fw;
+
+	/** Pointer for configuration data */
+	const struct firmware *cfg;
+
+	/** Pointer to the parent device */
+	struct device *parent_dev;
+
+	/** Config values read from qcom_cfg.ini file */
+	struct hdd_config *config;
+
+	/* Completion  variable to indicate Mc Thread Suspended */
+	struct completion mc_sus_event_var;
+
+	bool is_scheduler_suspended;
+
+#ifdef QCA_CONFIG_SMP
+	bool is_ol_rx_thread_suspended;
+#endif
+
+	bool hdd_wlan_suspended;
+	bool suspended;
+	/* flag to start pktlog after SSR/PDR if previously enabled */
+	bool is_pktlog_enabled;
+
+	/* Lock to avoid race condition during start/stop bss */
+	struct mutex sap_lock;
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+	/* OEM App registered or not */
+	bool oem_app_registered;
+
+	/* OEM App Process ID */
+	int32_t oem_pid;
+#endif
+
+	/** Concurrency Parameters*/
+	uint32_t concurrency_mode;
+
+	uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE];
+	uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE];
+
+	/** P2P Device MAC Address for the adapter  */
+	struct qdf_mac_addr p2p_device_address;
+
+	qdf_wake_lock_t rx_wake_lock;
+	qdf_wake_lock_t sap_wake_lock;
+
+	void *hdd_ipa;
+
+	/* Flag keeps track of wiphy suspend/resume */
+	bool is_wiphy_suspended;
+
+#ifdef MSM_PLATFORM
+	/* DDR bus bandwidth compute timer
+	 */
+	qdf_timer_t bus_bw_timer;
+	bool bus_bw_timer_running;
+	qdf_spinlock_t bus_bw_timer_lock;
+	struct work_struct bus_bw_work;
+	int cur_vote_level;
+	spinlock_t bus_bw_lock;
+	int cur_rx_level;
+	uint64_t prev_no_rx_offload_pkts;
+	uint64_t prev_rx_offload_pkts;
+	int cur_tx_level;
+	uint64_t prev_tx;
+#endif
+
+	struct completion ready_to_suspend;
+	/* defining the solution type */
+	uint32_t target_type;
+
+	qdf_atomic_t con_mode_flag;
+	/* defining the firmware version */
+	uint32_t target_fw_version;
+	uint32_t target_fw_vers_ext;
+
+	/* defining the chip/rom version */
+	uint32_t target_hw_version;
+	/* defining the chip/rom revision */
+	uint32_t target_hw_revision;
+	/* chip/rom name */
+	char *target_hw_name;
+	struct regulatory reg;
+#ifdef FEATURE_WLAN_CH_AVOID
+	uint16_t unsafe_channel_count;
+	uint16_t unsafe_channel_list[NUM_CHANNELS];
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+	uint8_t max_intf_count;
+	uint8_t current_intf_count;
+#ifdef WLAN_FEATURE_LPSS
+	uint8_t lpss_support;
+#endif
+	uint8_t ap_arpns_support;
+	tSirScanType ioctl_scan_mode;
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	qdf_work_t sta_ap_intf_check_work;
+#endif
+
+	struct work_struct  sap_start_work;
+	bool is_sap_restart_required;
+	bool is_sta_connection_pending;
+	qdf_spinlock_t sap_update_info_lock;
+	qdf_spinlock_t sta_update_info_lock;
+
+	uint8_t dev_dfs_cac_status;
+
+	bool bt_coex_mode_set;
+	struct fw_log_info fw_log_settings;
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+	qdf_mc_timer_t skip_acs_scan_timer;
+	uint8_t skip_acs_scan_status;
+	uint8_t *last_acs_channel_list;
+	uint8_t num_of_channels;
+	qdf_spinlock_t acs_skip_lock;
+#endif
+
+	qdf_wake_lock_t sap_dfs_wakelock;
+	atomic_t sap_dfs_ref_cnt;
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+	bool is_extwow_app_type1_param_set;
+	bool is_extwow_app_type2_param_set;
+#endif
+
+	/* Time since boot up to extscan start (in micro seconds) */
+	uint64_t ext_scan_start_since_boot;
+	unsigned long g_event_flags;
+	uint8_t miracast_value;
+
+#ifdef WLAN_NS_OFFLOAD
+	/* IPv6 notifier callback for handling NS offload on change in IP */
+	struct notifier_block ipv6_notifier;
+#endif
+	bool ns_offload_enable;
+	/* IPv4 notifier callback for handling ARP offload on change in IP */
+	struct notifier_block ipv4_notifier;
+
+	/* number of rf chains supported by target */
+	uint32_t  num_rf_chains;
+	/* Is htTxSTBC supported by target */
+	uint8_t   ht_tx_stbc_supported;
+#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
+	struct hdd_offloaded_packets_ctx op_ctx;
+#endif
+	bool mcc_mode;
+	struct mutex memdump_lock;
+	uint16_t driver_dump_size;
+	uint8_t *driver_dump_mem;
+
+	bool connection_in_progress;
+	qdf_spinlock_t connection_status_lock;
+
+	uint16_t hdd_txrx_hist_idx;
+	struct hdd_tx_rx_histogram *hdd_txrx_hist;
+
+	/*
+	 * place to store FTM capab of target. This allows changing of FTM capab
+	 * at runtime and intersecting it with target capab before updating.
+	 */
+	uint32_t fine_time_meas_cap_target;
+	uint32_t rx_high_ind_cnt;
+	/* For Rx thread non GRO/LRO packet accounting */
+	uint64_t no_rx_offload_pkt_cnt;
+	/* Current number of TX X RX chains being used */
+	enum antenna_mode current_antenna_mode;
+
+	/* the radio index assigned by cnss_logger */
+	int radio_index;
+	qdf_work_t sap_pre_cac_work;
+	bool hbw_requested;
+	uint32_t last_nil_scan_bug_report_timestamp;
+	enum RX_OFFLOAD ol_enable;
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+	bool nan_datapath_enabled;
+#endif
+	/* Present state of driver cds modules */
+	enum driver_modules_status driver_status;
+	qdf_delayed_work_t psoc_idle_timeout_work;
+	/* Interface change lock */
+	struct mutex iface_change_lock;
+	bool rps;
+	bool dynamic_rps;
+	bool enable_rxthread;
+	/* support for DP RX threads */
+	bool enable_dp_rx_threads;
+	bool napi_enable;
+	bool stop_modules_in_progress;
+	bool start_modules_in_progress;
+	bool update_mac_addr_to_fw;
+	struct acs_dfs_policy acs_policy;
+	uint16_t wmi_max_len;
+	struct suspend_resume_stats suspend_resume_stats;
+	struct hdd_runtime_pm_context runtime_context;
+	bool roaming_in_progress;
+	struct scan_chan_info *chan_info;
+	struct mutex chan_info_lock;
+	/* bit map to set/reset TDLS by different sources */
+	unsigned long tdls_source_bitmap;
+	bool tdls_umac_comp_active;
+	bool tdls_nap_active;
+	uint8_t beacon_probe_rsp_cnt_per_scan;
+	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;
+	bool rcpi_enabled;
+#ifdef FEATURE_WLAN_CH_AVOID
+	struct ch_avoid_ind_type coex_avoid_freq_list;
+	struct ch_avoid_ind_type dnbs_avoid_freq_list;
+	/* Lock to control access to dnbs and coex avoid freq list */
+	struct mutex avoid_freq_lock;
+#endif
+#ifdef WLAN_FEATURE_TSF
+	/* indicate whether tsf has been initialized */
+	qdf_atomic_t tsf_ready_flag;
+	/* indicate whether it's now capturing tsf(updating tstamp-pair) */
+	qdf_atomic_t cap_tsf_flag;
+	/* the context that is capturing tsf */
+	struct hdd_adapter *cap_tsf_context;
+#endif
+	uint8_t bt_a2dp_active:1;
+	uint8_t bt_vo_active:1;
+	enum band_info curr_band;
+	bool imps_enabled;
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+	int user_configured_pkt_filter_rules;
+#endif
+	bool is_fils_roaming_supported;
+	QDF_STATUS (*receive_offload_cb)(struct hdd_adapter *,
+					 struct sk_buff *);
+	qdf_atomic_t vendor_disable_lro_flag;
+	qdf_atomic_t disable_lro_in_concurrency;
+	qdf_atomic_t disable_lro_in_low_tput;
+	bool en_tcp_delack_no_lro;
+	bool force_rsne_override;
+	qdf_wake_lock_t monitor_mode_wakelock;
+	bool lte_coex_ant_share;
+	bool obss_scan_offload;
+	int sscan_pid;
+	uint32_t track_arp_ip;
+
+	/* defining the board related information */
+	uint32_t hw_bd_id;
+	struct board_info hw_bd_info;
+#ifdef WLAN_SUPPORT_TWT
+	enum twt_status twt_state;
+#endif
+#ifdef FEATURE_WLAN_APF
+	uint32_t apf_version;
+	bool apf_enabled_v2;
+#endif
+
+#ifdef DISABLE_CHANNEL_LIST
+	struct hdd_cache_channels *original_channels;
+	qdf_mutex_t cache_channel_lock;
+#endif
+	enum sar_version sar_version;
+	struct qdf_mac_addr dynamic_mac_list[QDF_MAX_CONCURRENCY_PERSONA];
+};
+
+/**
+ * struct hdd_vendor_acs_chan_params - vendor acs channel parameters
+ * @channel_count: channel count
+ * @channel_list: pointer to channel list
+ * @pcl_count: pcl list count
+ * @vendor_pcl_list: pointer to pcl list
+ * @vendor_weight_list: pointer to pcl weight list
+ */
+struct hdd_vendor_acs_chan_params {
+	uint32_t channel_count;
+	uint8_t *channel_list;
+	uint32_t pcl_count;
+	uint8_t *vendor_pcl_list;
+	uint8_t *vendor_weight_list;
+};
+
+/**
+ * struct hdd_external_acs_timer_context - acs timer context
+ * @reason: reason for acs trigger
+ * @adapter: hdd adapter for acs
+ */
+struct hdd_external_acs_timer_context {
+	int8_t reason;
+	struct hdd_adapter *adapter;
+};
+
+/**
+ * struct hdd_vendor_chan_info - vendor channel info
+ * @band: channel operating band
+ * @pri_ch: primary channel
+ * @ht_sec_ch: secondary channel
+ * @vht_seg0_center_ch: segment0 for vht
+ * @vht_seg1_center_ch: vht segment 1
+ * @chan_width: channel width
+ */
+struct hdd_vendor_chan_info {
+	uint8_t band;
+	uint8_t pri_ch;
+	uint8_t ht_sec_ch;
+	uint8_t vht_seg0_center_ch;
+	uint8_t vht_seg1_center_ch;
+	uint8_t chan_width;
+};
+
+/**
+ * struct  hdd_channel_info - standard channel info
+ * @freq: Freq in Mhz
+ * @flags: channel info flags
+ * @flagext: extended channel info flags
+ * @ieee_chan_number: channel number
+ * @max_reg_power: max tx power according to regulatory
+ * @max_radio_power: max radio power
+ * @min_radio_power: min radio power
+ * @reg_class_id: regulatory class
+ * @max_antenna_gain: max antenna gain allowed on channel
+ * @vht_center_freq_seg0: vht center freq segment 0
+ * @vht_center_freq_seg1: vht center freq segment 1
+ */
+struct hdd_channel_info {
+	u_int16_t freq;
+	u_int32_t flags;
+	u_int16_t flagext;
+	u_int8_t ieee_chan_number;
+	int8_t max_reg_power;
+	int8_t max_radio_power;
+	int8_t min_radio_power;
+	u_int8_t reg_class_id;
+	u_int8_t max_antenna_gain;
+	u_int8_t vht_center_freq_seg0;
+	u_int8_t vht_center_freq_seg1;
+};
+
+/*
+ * @eHDD_DRV_OP_PROBE: Refers to .probe operation
+ * @eHDD_DRV_OP_REMOVE: Refers to .remove operation
+ * @eHDD_DRV_OP_SHUTDOWN: Refers to .shutdown operation
+ * @eHDD_DRV_OP_REINIT: Refers to .reinit operation
+ * @eHDD_DRV_OP_IFF_UP: Refers to IFF_UP operation
+ */
+enum {
+	eHDD_DRV_OP_PROBE = 0,
+	eHDD_DRV_OP_REMOVE,
+	eHDD_DRV_OP_SHUTDOWN,
+	eHDD_DRV_OP_REINIT,
+	eHDD_DRV_OP_IFF_UP
+};
+
+/*
+ * Function declarations and documentation
+ */
+
+int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
+				uint32_t chan_number,
+				enum phy_ch_width chan_bw);
+
+QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
+				 struct hdd_adapter **out_adapter);
+
+QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
+				struct hdd_adapter *current_adapter,
+				struct hdd_adapter **out_adapter);
+
+QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
+			      struct hdd_adapter *adapter);
+
+QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
+				    struct hdd_adapter **out_adapter);
+
+QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
+				struct hdd_adapter *adapter);
+
+QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
+				 struct hdd_adapter *adapter);
+
+/**
+ * hdd_for_each_adapter - adapter iterator macro
+ * @hdd_ctx: the global HDD context
+ * @adapter: an hdd_adapter pointer to use as a cursor
+ */
+#define hdd_for_each_adapter(hdd_ctx, adapter) \
+	for (hdd_get_front_adapter(hdd_ctx, &adapter); \
+	     adapter; \
+	     hdd_get_next_adapter(hdd_ctx, adapter, &adapter))
+
+struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx,
+				     uint8_t session_type,
+				     const char *name, tSirMacAddr macAddr,
+				     unsigned char name_assign_type,
+				     bool rtnl_held);
+
+/**
+ * hdd_close_adapter() - remove and free @adapter from the adapter list
+ * @hdd_ctx: The Hdd context containing the adapter list
+ * @adapter: the adapter to remove and free
+ * @rtnl_held: if the caller is already holding the RTNL lock
+ *
+ * Return: None
+ */
+void hdd_close_adapter(struct hdd_context *hdd_ctx,
+		       struct hdd_adapter *adapter,
+		       bool rtnl_held);
+
+/**
+ * hdd_close_all_adapters() - remove and free all adapters from the adapter list
+ * @hdd_ctx: The Hdd context containing the adapter list
+ * @rtnl_held: if the caller is already holding the RTNL lock
+ *
+ * Return: None
+ */
+void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held);
+
+QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx);
+void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held);
+QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx);
+QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx);
+struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
+				       uint32_t vdev_id);
+struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
+					  tSirMacAddr macAddr);
+
+/*
+ * hdd_get_adapter_by_rand_macaddr() - find Random mac adapter
+ * @hdd_ctx: hdd context
+ * @mac_addr: random mac addr
+ *
+ * Find the Adapter based on random mac addr. Adapter's vdev
+ * have active random mac list.
+ *
+ * Return: adapter ptr or null
+ */
+struct hdd_adapter *
+hdd_get_adapter_by_rand_macaddr(struct hdd_context *hdd_ctx,
+				tSirMacAddr mac_addr);
+
+int hdd_vdev_create(struct hdd_adapter *adapter,
+		    csr_roam_complete_cb callback, void *ctx);
+int hdd_vdev_destroy(struct hdd_adapter *adapter);
+int hdd_vdev_ready(struct hdd_adapter *adapter);
+
+QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter);
+struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
+			enum QDF_OPMODE mode);
+/*
+ * hdd_get_device_mode() - Get device mode
+ * @session_id: Session id
+ *
+ * Return: Device mode
+ */
+enum QDF_OPMODE hdd_get_device_mode(uint32_t session_id);
+void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
+			struct hdd_adapter *adapter,
+			bool rtnl_held);
+QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
+			    struct hdd_adapter *adapter);
+
+enum hdd_adapter_stop_flag_t {
+	HDD_IN_CAC_WORK_TH_CONTEXT = 0x00000001,
+};
+
+QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx,
+				struct hdd_adapter *adapter,
+				enum hdd_adapter_stop_flag_t flag);
+
+void hdd_set_station_ops(struct net_device *dev);
+uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx);
+void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
+				uint8_t *releaseAddr);
+uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
+			enum QDF_OPMODE mode);
+
+void hdd_set_conparam(int32_t con_param);
+enum QDF_GLOBAL_MODE hdd_get_conparam(void);
+void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter);
+void hdd_prevent_suspend(uint32_t reason);
+
+/*
+ * hdd_get_first_valid_adapter() - Get the first valid adapter from adapter list
+ *
+ * This function is used to fetch the first valid adapter from the adapter
+ * list. If there is no valid adapter then it returns NULL
+ *
+ * @hdd_ctx: HDD context handler
+ *
+ * Return: NULL if no valid adapter found in the adapter list
+ *
+ */
+struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx);
+
+void hdd_allow_suspend(uint32_t reason);
+void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason);
+
+void wlan_hdd_cfg80211_update_wiphy_caps(struct wiphy *wiphy);
+QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter);
+
+/**
+ * wlan_hdd_validate_context() - check the HDD context
+ * @hdd_ctx: Global HDD context pointer
+ *
+ * Return: 0 if the context is valid. Error code otherwise
+ */
+#define wlan_hdd_validate_context(hdd_ctx) \
+	__wlan_hdd_validate_context(hdd_ctx, __func__)
+
+int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func);
+
+/**
+ * hdd_validate_adapter() - Validate the given adapter
+ * @adapter: the adapter to validate
+ *
+ * This function validates the given adapter, and ensures that it is open.
+ *
+ * Return: Errno
+ */
+#define hdd_validate_adapter(adapter) \
+	__hdd_validate_adapter(adapter, __func__)
+
+int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func);
+
+/**
+ * wlan_hdd_validate_session_id() - ensure the given session Id is valid
+ * @session_id: the session Id to validate
+ *
+ * Return: Errno
+ */
+#define wlan_hdd_validate_session_id(session_id) \
+	__wlan_hdd_validate_session_id(session_id, __func__)
+
+int __wlan_hdd_validate_session_id(uint8_t session_id, const char *func);
+
+bool hdd_is_valid_mac_address(const uint8_t *pMacAddr);
+QDF_STATUS hdd_issta_p2p_clientconnected(struct hdd_context *hdd_ctx);
+bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx);
+
+/**
+ * wlan_hdd_validate_mac_address() - Function to validate mac address
+ * @mac_addr: input mac address
+ *
+ * Return QDF_STATUS
+ */
+#define wlan_hdd_validate_mac_address(mac_addr) \
+	__wlan_hdd_validate_mac_address(mac_addr, __func__)
+
+QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr,
+					   const char *func);
+#ifdef MSM_PLATFORM
+/**
+ * hdd_bus_bw_compute_timer_start() - start the bandwidth timer
+ * @hdd_ctx: the global hdd context
+ *
+ * Return: None
+ */
+void hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_bus_bw_compute_timer_try_start() - try to start the bandwidth timer
+ * @hdd_ctx: the global hdd context
+ *
+ * This function ensures there is at least one adapter in the associated state
+ * before starting the bandwidth timer.
+ *
+ * Return: None
+ */
+void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_bus_bw_compute_timer_stop() - stop the bandwidth timer
+ * @hdd_ctx: the global hdd context
+ *
+ * Return: None
+ */
+void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_bus_bw_compute_timer_try_stop() - try to stop the bandwidth timer
+ * @hdd_ctx: the global hdd context
+ *
+ * This function ensures there are no adapters in the associated state before
+ * stopping the bandwidth timer.
+ *
+ * Return: None
+ */
+void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_bus_bandwidth_init() - Initialize bus bandwidth data structures.
+ * @hdd_ctx: HDD context
+ *
+ * Initialize bus bandwidth related data structures like spinlock and timer.
+ *
+ * Return: None.
+ */
+int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_bus_bandwidth_deinit() - De-initialize bus bandwidth data structures.
+ * @hdd_ctx: HDD context
+ *
+ * De-initialize bus bandwidth related data structures like timer.
+ *
+ * Return: None.
+ */
+void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx);
+
+#define GET_CUR_RX_LVL(config) ((config)->cur_rx_level)
+#define GET_BW_COMPUTE_INTV(config) ((config)->bus_bw_compute_interval)
+
+#else
+
+static inline
+void hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+
+static inline
+void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx)
+{
+}
+
+#define GET_CUR_RX_LVL(config) 0
+#define GET_BW_COMPUTE_INTV(config) 0
+
+#endif
+
+int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask);
+
+int hdd_init(void);
+void hdd_deinit(void);
+
+/**
+ * hdd_wlan_startup() - HDD init function
+ * @dev: pointer to the underlying device
+ * @out_hdd_ctx: output hdd context pointer for the newly created context
+ *
+ * Return: Errno
+ */
+int hdd_wlan_startup(struct device *dev, struct hdd_context **out_hdd_ctx);
+
+/**
+ * hdd_wlan_exit() - HDD WLAN exit function
+ * @hdd_ctx: pointer to the HDD Context
+ *
+ * Return: None
+ */
+void hdd_wlan_exit(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_psoc_create_vdevs() - create the default vdevs for a psoc
+ * @hdd_ctx: the HDD context for the psoc to operate against
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx);
+
+int hdd_wlan_notify_modem_power_state(int state);
+#ifdef QCA_HT_2040_COEX
+/**
+ * hdd_wlan_set_ht2040_mode() - notify FW with HT20/HT40 mode
+ * @adapter: pointer to adapter
+ * @sta_id: station id
+ * @sta_mac: station MAC address
+ * @channel_type: channel type
+ *
+ * This function notifies FW with HT20/HT40 mode
+ *
+ * Return: 0 if successful, error number otherwise
+ */
+int hdd_wlan_set_ht2040_mode(struct hdd_adapter *adapter, uint16_t sta_id,
+			     struct qdf_mac_addr sta_mac, int channel_type);
+#endif
+
+void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len);
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable);
+#endif
+
+struct hdd_adapter *
+hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
+			bool check_start_bss);
+
+bool hdd_is_5g_supported(struct hdd_context *hdd_ctx);
+
+int wlan_hdd_scan_abort(struct hdd_adapter *adapter);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static inline bool roaming_offload_enabled(struct hdd_context *hdd_ctx)
+{
+	bool is_roam_offload;
+
+	ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &is_roam_offload);
+
+	return is_roam_offload;
+}
+#else
+static inline bool roaming_offload_enabled(struct hdd_context *hdd_ctx)
+{
+	return false;
+}
+#endif
+
+#ifdef WLAN_FEATURE_HOST_ROAM
+static inline bool hdd_driver_roaming_supported(struct hdd_context *hdd_ctx)
+{
+	return hdd_ctx->config->isFastRoamIniFeatureEnabled;
+}
+#else
+static inline bool hdd_driver_roaming_supported(struct hdd_context *hdd_ctx)
+{
+	return false;
+}
+#endif
+
+static inline bool hdd_roaming_supported(struct hdd_context *hdd_ctx)
+{
+	bool val;
+
+	val = hdd_driver_roaming_supported(hdd_ctx) ||
+		roaming_offload_enabled(hdd_ctx);
+
+	return val;
+}
+
+#ifdef CFG80211_SCAN_RANDOM_MAC_ADDR
+static inline bool hdd_scan_random_mac_addr_supported(void)
+{
+	return true;
+}
+#else
+static inline bool hdd_scan_random_mac_addr_supported(void)
+{
+	return false;
+}
+#endif
+
+/**
+ * hdd_start_vendor_acs(): Start vendor ACS procedure
+ * @adapter: pointer to SAP adapter struct
+ *
+ * This function sends the ACS config to the ACS daemon and
+ * starts the vendor ACS timer to wait for the next command.
+ *
+ * Return: Status of vendor ACS procedure
+ */
+int hdd_start_vendor_acs(struct hdd_adapter *adapter);
+
+void hdd_get_fw_version(struct hdd_context *hdd_ctx,
+			uint32_t *major_spid, uint32_t *minor_spid,
+			uint32_t *siid, uint32_t *crmid);
+/**
+ * hdd_acs_response_timeout_handler() - timeout handler for acs_timer
+ * @context : timeout handler context
+ *
+ * Return: None
+ */
+void hdd_acs_response_timeout_handler(void *context);
+
+/**
+ * wlan_hdd_cfg80211_start_acs(): Start ACS Procedure for SAP
+ * @adapter: pointer to SAP adapter struct
+ *
+ * This function starts the ACS procedure if there are no
+ * constraints like MBSSID DFS restrictions.
+ *
+ * Return: Status of ACS Start procedure
+ */
+int wlan_hdd_cfg80211_start_acs(struct hdd_adapter *adapter);
+
+/**
+ * hdd_cfg80211_update_acs_config() - update acs config to application
+ * @adapter: hdd adapter
+ * @reason: channel change reason
+ *
+ * Return: 0 for success else error code
+ */
+int hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter,
+				   uint8_t reason);
+
+/**
+ * hdd_update_acs_timer_reason() - update acs timer start reason
+ * @adapter: hdd adapter
+ * @reason: channel change reason
+ *
+ * Return: 0 for success
+ */
+int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason);
+
+/**
+ * hdd_switch_sap_channel() - Move SAP to the given channel
+ * @adapter: AP adapter
+ * @channel: Channel
+ * @forced: Force to switch channel, ignore SCC/MCC check
+ *
+ * Moves the SAP interface by invoking the function which
+ * executes the callback to perform channel switch using (E)CSA.
+ *
+ * Return: None
+ */
+void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel,
+			    bool forced);
+
+#if defined(FEATURE_WLAN_CH_AVOID)
+void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctx);
+
+void hdd_ch_avoid_ind(struct hdd_context *hdd_ctxt,
+		      struct unsafe_ch_list *unsafe_chan_list,
+		      struct ch_avoid_ind_type *avoid_freq_list);
+#else
+static inline
+void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+void hdd_ch_avoid_ind(struct hdd_context *hdd_ctxt,
+		      struct unsafe_ch_list *unsafe_chan_list,
+		      struct ch_avoid_ind_type *avoid_freq_list)
+{
+}
+#endif
+
+void hdd_update_macaddr(struct hdd_config *config,
+			struct qdf_mac_addr hw_macaddr);
+
+/**
+ * wlan_hdd_disable_roaming() - disable roaming on all STAs except the input one
+ * @cur_adapter: Current HDD adapter passed from caller
+ *
+ * This function loops through all adapters and disables roaming on each STA
+ * mode adapter except the current adapter passed from the caller
+ *
+ * Return: None
+ */
+void wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter);
+
+/**
+ * wlan_hdd_enable_roaming() - enable roaming on all STAs except the input one
+ * @cur_adapter: Current HDD adapter passed from caller
+ *
+ * This function loops through all adapters and enables roaming on each STA
+ * mode adapter except the current adapter passed from the caller
+ *
+ * Return: None
+ */
+void wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter);
+
+QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx);
+
+QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx);
+
+QDF_STATUS
+wlan_hdd_check_custom_con_channel_rules(struct hdd_adapter *sta_adapter,
+					struct hdd_adapter *ap_adapter,
+					struct csr_roam_profile *roam_profile,
+					tScanResultHandle *scan_cache,
+					bool *concurrent_chnl_same);
+
+void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter);
+void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit);
+
+#ifdef QCA_CONFIG_SMP
+int wlan_hdd_get_cpu(void);
+#else
+static inline int wlan_hdd_get_cpu(void)
+{
+	return 0;
+}
+#endif
+
+void wlan_hdd_sap_pre_cac_failure(void *data);
+void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx);
+
+void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
+	enum netif_action_type action, enum netif_reason_type reason);
+
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter,
+			   enum netif_action_type action);
+#else
+static inline void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter,
+					 enum netif_action_type action)
+{
+}
+#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
+
+int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int value);
+void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx);
+void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx);
+void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx);
+
+void
+wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
+				     enum qdf_stats_verbosity_level verb_lvl);
+void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx);
+const char *hdd_get_fwpath(void);
+void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind);
+
+struct hdd_adapter *
+hdd_get_adapter_by_sme_session_id(struct hdd_context *hdd_ctx,
+				  uint32_t sme_session_id);
+
+/**
+ * hdd_get_adapter_by_iface_name() - Return adapter with given interface name
+ * @hdd_ctx: hdd context.
+ * @iface_name: interface name
+ *
+ * This function is used to get the adapter with given interface name
+ *
+ * Return: adapter pointer if found, NULL otherwise
+ *
+ */
+struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
+					     const char *iface_name);
+enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width);
+
+/**
+ * hdd_nl_to_qdf_iface_type() - map nl80211_iftype to QDF_OPMODE
+ * @nl_type: the input NL80211 interface type to map
+ * @out_qdf_type: the output, equivalent QDF operating mode
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,
+				    enum QDF_OPMODE *out_qdf_type);
+
+/**
+ * wlan_hdd_find_opclass() - Find operating class for a channel
+ * @mac_handle: global MAC handle
+ * @channel: channel id
+ * @bw_offset: bandwidth offset
+ *
+ * Function invokes sme api to find the operating class
+ *
+ * Return: operating class
+ */
+uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel,
+			      uint8_t bw_offset);
+
+int hdd_update_config(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_update_components_config() - Initialize driver per module ini parameters
+ * @hdd_ctx: HDD Context
+ *
+ * API is used to initialize components configuration parameters
+ * Return: 0 for success, errno for failure
+ */
+int hdd_update_components_config(struct hdd_context *hdd_ctx);
+
+QDF_STATUS hdd_chan_change_notify(struct hdd_adapter *adapter,
+		struct net_device *dev,
+		struct hdd_chan_change_params chan_change,
+		bool legacy_phymode);
+int wlan_hdd_set_channel(struct wiphy *wiphy,
+		struct net_device *dev,
+		struct cfg80211_chan_def *chandef,
+		enum nl80211_channel_type channel_type);
+int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter,
+		struct cfg80211_beacon_data *params,
+		const u8 *ssid, size_t ssid_len,
+		enum nl80211_hidden_ssid hidden_ssid,
+		bool check_for_concurrency);
+
+#if !defined(REMOVE_PKT_LOG)
+int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
+			       int set_value2);
+int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, bool enable,
+			      uint8_t user_triggered, int size);
+
+#else
+static inline
+int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, bool enable,
+			      uint8_t user_triggered, int size)
+{
+	return 0;
+}
+
+static inline
+int hdd_process_pktlog_command(struct hdd_context *hdd_ctx,
+			       uint32_t set_value, int set_value2)
+{
+	return 0;
+}
+#endif /* REMOVE_PKT_LOG */
+
+#ifdef FEATURE_SG
+/**
+ * hdd_set_sg_flags() - enable SG flag in the network device
+ * @hdd_ctx: HDD context
+ * @wlan_dev: network device structure
+ *
+ * This function enables the SG feature flag in the
+ * given network device.
+ *
+ * Return: none
+ */
+static inline void hdd_set_sg_flags(struct hdd_context *hdd_ctx,
+				struct net_device *wlan_dev)
+{
+	hdd_debug("SG Enabled");
+	wlan_dev->features |= NETIF_F_SG;
+}
+#else
+static inline void hdd_set_sg_flags(struct hdd_context *hdd_ctx,
+				struct net_device *wlan_dev){}
+#endif
+
+#ifdef FEATURE_TSO
+/**
+ * hdd_set_tso_flags() - enable TSO flags in the network device
+ * @hdd_ctx: HDD context
+ * @wlan_dev: network device structure
+ *
+ * This function enables the TSO related feature flags in the
+ * given network device.
+ *
+ * Return: none
+ */
+static inline void hdd_set_tso_flags(struct hdd_context *hdd_ctx,
+	 struct net_device *wlan_dev)
+{
+	if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
+			cfg_dp_tso_enable) &&
+			cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
+				    cfg_dp_enable_ip_tcp_udp_checksum_offload)){
+	    /*
+	     * We want to enable TSO only if IP/UDP/TCP TX checksum flag is
+	     * enabled.
+	     */
+		hdd_debug("TSO Enabled");
+		wlan_dev->features |=
+			 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+			 NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG;
+	}
+}
+#else
+static inline void hdd_set_tso_flags(struct hdd_context *hdd_ctx,
+	 struct net_device *wlan_dev)
+{
+	hdd_set_sg_flags(hdd_ctx, wlan_dev);
+}
+#endif /* FEATURE_TSO */
+
+void hdd_get_ibss_peer_info_cb(void *pUserData,
+				tSirPeerInfoRspParams *pPeerInfo);
+
+#ifdef CONFIG_CNSS_LOGGER
+/**
+ * wlan_hdd_nl_init() - wrapper function to CNSS_LOGGER case
+ * @hdd_ctx:	the hdd context pointer
+ *
+ * The nl_srv_init() will call to cnss_logger_device_register() and
+ * expect to get a radio_index from cnss_logger module and assign to
+ * hdd_ctx->radio_index, then to maintain the consistency to original
+ * design, adding the radio_index check here, then return the error
+ * code if radio_index is not assigned correctly, which means the nl_init
+ * from cnss_logger is failed.
+ *
+ * Return: 0 if successfully, otherwise error code
+ */
+static inline int wlan_hdd_nl_init(struct hdd_context *hdd_ctx)
+{
+	hdd_ctx->radio_index = nl_srv_init(hdd_ctx->wiphy);
+
+	/* radio_index is assigned from 0, so only >=0 will be valid index  */
+	if (hdd_ctx->radio_index >= 0)
+		return 0;
+	else
+		return -EINVAL;
+}
+#else
+/**
+ * wlan_hdd_nl_init() - wrapper function to non CNSS_LOGGER case
+ * @hdd_ctx:	the hdd context pointer
+ *
+ * In case of non CNSS_LOGGER case, the nl_srv_init() will initialize
+ * the netlink socket and return the success or not.
+ *
+ * Return: the return value from  nl_srv_init()
+ */
+static inline int wlan_hdd_nl_init(struct hdd_context *hdd_ctx)
+{
+	return nl_srv_init(hdd_ctx->wiphy);
+}
+#endif
+QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id,
+					 QDF_STATUS qdf_status);
+QDF_STATUS hdd_sme_close_session_callback(uint8_t session_id);
+
+int hdd_reassoc(struct hdd_adapter *adapter, const uint8_t *bssid,
+		uint8_t channel, const handoff_src src);
+int hdd_register_cb(struct hdd_context *hdd_ctx);
+void hdd_deregister_cb(struct hdd_context *hdd_ctx);
+int hdd_start_station_adapter(struct hdd_adapter *adapter);
+int hdd_start_ap_adapter(struct hdd_adapter *adapter);
+int hdd_configure_cds(struct hdd_context *hdd_ctx);
+int hdd_set_fw_params(struct hdd_adapter *adapter);
+int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit);
+int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode);
+
+/**
+ * hdd_psoc_idle_timer_start() - start the idle psoc detection timer
+ * @hdd_ctx: the hdd context for which the timer should be started
+ *
+ * Return: None
+ */
+void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_psoc_idle_timer_stop() - stop the idle psoc detection timer
+ * @hdd_ctx: the hdd context for which the timer should be stopped
+ *
+ * Return: None
+ */
+void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx);
+
+int hdd_start_adapter(struct hdd_adapter *adapter);
+void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num);
+/**
+ * hdd_is_interface_up()- Checkfor interface up before ssr
+ * @hdd_ctx: HDD context
+ *
+ * check  if there are any wlan interfaces before SSR accordingly start
+ * the interface.
+ *
+ * Return: 0 if interface was opened else false
+ */
+bool hdd_is_interface_up(struct hdd_adapter *adapter);
+/**
+ * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
+ * @wiphy: wiphy
+ * @channel: channel of the BSS to find
+ * @bssid: bssid of the BSS to find
+ * @ssid: ssid of the BSS to find
+ * @ssid_len: ssid len of of the BSS to find
+ *
+ * The API is a wrapper to get bss from kernel matching the chan,
+ * bssid and ssid
+ *
+ * Return: bss structure if found else NULL
+ */
+struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
+	struct ieee80211_channel *channel,
+	const u8 *bssid,
+	const u8 *ssid, size_t ssid_len);
+
+void hdd_connect_result(struct net_device *dev, const u8 *bssid,
+			struct csr_roam_info *roam_info, const u8 *req_ie,
+			size_t req_ie_len, const u8 *resp_ie,
+			size_t resp_ie_len, u16 status, gfp_t gfp,
+			bool connect_timeout,
+			tSirResultCodes timeout_reason);
+
+#ifdef WLAN_FEATURE_FASTPATH
+void hdd_enable_fastpath(struct hdd_context *hdd_ctx,
+			 void *context);
+#else
+static inline void hdd_enable_fastpath(struct hdd_context *hdd_ctx,
+				       void *context)
+{
+}
+#endif
+void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context);
+
+enum  sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode);
+void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctx);
+/**
+ * hdd_clone_local_unsafe_chan() - clone hdd ctx unsafe chan list
+ * @hdd_ctx: hdd context pointer
+ * @local_unsafe_list: copied unsafe chan list array
+ * @local_unsafe_list_count: channel number in returned local_unsafe_list
+ *
+ * The function will allocate memory and make a copy the current unsafe
+ * channels from hdd ctx. The caller need to free the local_unsafe_list
+ * memory after use.
+ *
+ * Return: 0 if successfully clone unsafe chan list.
+ */
+int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
+	uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count);
+
+/**
+ * hdd_local_unsafe_channel_updated() - check unsafe chan list same or not
+ * @hdd_ctx: hdd context pointer
+ * @local_unsafe_list: unsafe chan list to be compared with hdd_ctx's list
+ * @local_unsafe_list_count: channel number in local_unsafe_list
+ *
+ * The function checked the input channel is same as current unsafe chan
+ * list in hdd_ctx.
+ *
+ * Return: true if input channel list is same as the list in hdd_ctx
+ */
+bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
+	uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count);
+
+int hdd_enable_disable_ca_event(struct hdd_context *hddctx,
+				uint8_t set_value);
+void wlan_hdd_undo_acs(struct hdd_adapter *adapter);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0))
+static inline int
+hdd_wlan_nla_put_u64(struct sk_buff *skb, int attrtype, u64 value)
+{
+	return nla_put_u64(skb, attrtype, value);
+}
+#else
+static inline int
+hdd_wlan_nla_put_u64(struct sk_buff *skb, int attrtype, u64 value)
+{
+	return nla_put_u64_64bit(skb, attrtype, value, NL80211_ATTR_PAD);
+}
+#endif
+
+/**
+ * hdd_roam_profile() - Get adapter's roam profile
+ * @adapter: The adapter being queried
+ *
+ * Given an adapter this function returns a pointer to its roam profile.
+ *
+ * NOTE WELL: Caller is responsible for ensuring this interface is only
+ * invoked for STA-type interfaces
+ *
+ * Return: pointer to the adapter's roam profile
+ */
+static inline
+struct csr_roam_profile *hdd_roam_profile(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx;
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	return &sta_ctx->roam_profile;
+}
+
+/**
+ * hdd_security_ie() - Get adapter's security IE
+ * @adapter: The adapter being queried
+ *
+ * Given an adapter this function returns a pointer to its security IE
+ * buffer. Note that this buffer is maintained outside the roam
+ * profile but, when in use, is referenced by a pointer within the
+ * roam profile.
+ *
+ * NOTE WELL: Caller is responsible for ensuring this interface is only
+ * invoked for STA-type interfaces
+ *
+ * Return: pointer to the adapter's roam profile security IE buffer
+ */
+static inline
+uint8_t *hdd_security_ie(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx;
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	return sta_ctx->security_ie;
+}
+
+/**
+ * hdd_assoc_additional_ie() - Get adapter's assoc additional IE
+ * @adapter: The adapter being queried
+ *
+ * Given an adapter this function returns a pointer to its assoc
+ * additional IE buffer. Note that this buffer is maintained outside
+ * the roam profile but, when in use, is referenced by a pointer
+ * within the roam profile.
+ *
+ * NOTE WELL: Caller is responsible for ensuring this interface is only
+ * invoked for STA-type interfaces
+ *
+ * Return: pointer to the adapter's assoc additional IE buffer
+ */
+static inline
+tSirAddie *hdd_assoc_additional_ie(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx;
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	return &sta_ctx->assoc_additional_ie;
+}
+
+/**
+ * hdd_is_roaming_in_progress() - check if roaming is in progress
+ * @hdd_ctx - Global HDD context
+ *
+ * Checks if roaming is in progress on any of the adapters
+ *
+ * Return: true if roaming is in progress else false
+ */
+bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx);
+void hdd_set_roaming_in_progress(bool value);
+bool hdd_is_connection_in_progress(uint8_t *session_id,
+	enum scan_reject_states *reason);
+void hdd_restart_sap(struct hdd_adapter *ap_adapter);
+void hdd_check_and_restart_sap_with_non_dfs_acs(void);
+bool hdd_set_connection_in_progress(bool value);
+
+/**
+ * wlan_hdd_init_chan_info() - initialize channel info variables
+ * @hdd_ctx: hdd ctx
+ *
+ * This API initialize channel info variables
+ *
+ * Return: None
+ */
+void wlan_hdd_init_chan_info(struct hdd_context *hdd_ctx);
+
+/**
+ * wlan_hdd_deinit_chan_info() - deinitialize channel info variables
+ * @hdd_ctx: hdd ctx
+ *
+ * This API deinitialize channel info variables
+ *
+ * Return: None
+ */
+void wlan_hdd_deinit_chan_info(struct hdd_context *hdd_ctx);
+void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit);
+
+/**
+ * hdd_is_any_interface_open() - Check for interface up
+ * @hdd_ctx: HDD context
+ *
+ * Return: true if any interface is open
+ */
+bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx);
+
+#ifdef WIFI_POS_CONVERGED
+/**
+ * hdd_send_peer_status_ind_to_app() - wrapper to call legacy or new wifi_pos
+ * function to send peer status to a registered application
+ * @peer_mac: MAC address of peer
+ * @peer_status: ePeerConnected or ePeerDisconnected
+ * @peer_timing_meas_cap: 0: RTT/RTT2, 1: RTT3. Default is 0
+ * @sessionId: SME session id, i.e. vdev_id
+ * @chan_info: operating channel information
+ * @dev_mode: dev mode for which indication is sent
+ *
+ * Return: none
+ */
+static inline void hdd_send_peer_status_ind_to_app(
+					struct qdf_mac_addr *peer_mac,
+					uint8_t peer_status,
+					uint8_t peer_timing_meas_cap,
+					uint8_t sessionId,
+					tSirSmeChanInfo *chan_info,
+					enum QDF_OPMODE dev_mode)
+{
+	struct wifi_pos_ch_info ch_info;
+
+	if (!chan_info) {
+		os_if_wifi_pos_send_peer_status(peer_mac, peer_status,
+					peer_timing_meas_cap, sessionId,
+					NULL, dev_mode);
+		return;
+	}
+
+	ch_info.chan_id = chan_info->chan_id;
+	ch_info.mhz = chan_info->mhz;
+	ch_info.band_center_freq1 = chan_info->band_center_freq1;
+	ch_info.band_center_freq2 = chan_info->band_center_freq2;
+	ch_info.info = chan_info->info;
+	ch_info.reg_info_1 = chan_info->reg_info_1;
+	ch_info.reg_info_2 = chan_info->reg_info_2;
+	ch_info.nss = chan_info->nss;
+	ch_info.rate_flags = chan_info->rate_flags;
+	ch_info.sec_ch_offset = chan_info->sec_ch_offset;
+	ch_info.ch_width = chan_info->ch_width;
+	os_if_wifi_pos_send_peer_status(peer_mac, peer_status,
+					peer_timing_meas_cap, sessionId,
+					&ch_info, dev_mode);
+}
+#else
+static inline void hdd_send_peer_status_ind_to_app(
+					struct qdf_mac_addr *peer_mac,
+					uint8_t peer_status,
+					uint8_t peer_timing_meas_cap,
+					uint8_t sessionId,
+					tSirSmeChanInfo *chan_info,
+					enum QDF_OPMODE dev_mode)
+{
+	hdd_send_peer_status_ind_to_oem_app(peer_mac, peer_status,
+			peer_timing_meas_cap, sessionId, chan_info, dev_mode);
+}
+#endif /* WIFI_POS_CONVERGENCE */
+
+/**
+ * wlan_hdd_send_p2p_quota()- Send P2P Quota value to FW
+ * @adapter: Adapter data
+ * @sval:    P2P quota value
+ *
+ * Send P2P quota value to FW
+ *
+ * Return: 0 success else failure
+ */
+int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int sval);
+
+/**
+ * wlan_hdd_send_p2p_quota()- Send MCC latency to FW
+ * @adapter: Adapter data
+ * @sval:    MCC latency value
+ *
+ * Send MCC latency value to FW
+ *
+ * Return: 0 success else failure
+ */
+int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int sval);
+
+/**
+ * wlan_hdd_get_adapter_from_vdev()- Get adapter from vdev id
+ * and PSOC object data
+ * @psoc: Psoc object data
+ * @vdev_id: vdev id
+ *
+ * Get adapter from vdev id and PSOC object data
+ *
+ * Return: adapter pointer
+ */
+struct hdd_adapter *wlan_hdd_get_adapter_from_vdev(struct wlan_objmgr_psoc
+					*psoc, uint8_t vdev_id);
+/**
+ * hdd_unregister_notifiers()- unregister kernel notifiers
+ * @hdd_ctx: Hdd Context
+ *
+ * Unregister netdev notifiers like Netdevice,IPv4 and IPv6.
+ *
+ */
+void hdd_unregister_notifiers(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_dbs_scan_selection_init() - initialization for DBS scan selection config
+ * @hdd_ctx: HDD context
+ *
+ * This function sends the DBS scan selection config configuration to the
+ * firmware via WMA
+ *
+ * Return: 0 - success, < 0 - failure
+ */
+int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_start_complete()- complete the start event
+ * @ret: return value for complete event.
+ *
+ * complete the startup event and set the return in
+ * global variable
+ *
+ * Return: void
+ */
+
+void hdd_start_complete(int ret);
+
+/**
+ * hdd_chip_pwr_save_fail_detected_cb() - chip power save failure detected
+ * callback
+ * @hdd_handle: HDD handle
+ * @data: chip power save failure detected data
+ *
+ * This function reads the chip power save failure detected data and fill in
+ * the skb with NL attributes and send up the NL event.
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
+ * Return: none
+ */
+
+void hdd_chip_pwr_save_fail_detected_cb(hdd_handle_t hdd_handle,
+				struct chip_pwr_save_fail_detected_params
+				*data);
+
+/**
+ * hdd_update_ie_whitelist_attr() - Copy probe req ie whitelist attrs from cfg
+ * @ie_whitelist: output parameter
+ * @hdd_ctx: pointer to hdd context
+ *
+ * Return: None
+ */
+void hdd_update_ie_whitelist_attr(struct probe_req_whitelist_attr *ie_whitelist,
+				  struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_get_rssi_snr_by_bssid() - gets the rssi and snr by bssid from scan cache
+ * @adapter: adapter handle
+ * @bssid: bssid to look for in scan cache
+ * @rssi: rssi value found
+ * @snr: snr value found
+ *
+ * Return: QDF_STATUS
+ */
+int hdd_get_rssi_snr_by_bssid(struct hdd_adapter *adapter, const uint8_t *bssid,
+			      int8_t *rssi, int8_t *snr);
+
+/**
+ * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
+ * @adapter - HDD adapter
+ *
+ * Return: 0 on success and non zero value on failure
+ */
+int hdd_reset_limit_off_chan(struct hdd_adapter *adapter);
+
+#if defined(WLAN_FEATURE_FILS_SK) && \
+	(defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
+		 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)))
+/**
+ * hdd_clear_fils_connection_info: API to clear fils info from roam profile and
+ * free allocated memory
+ * @adapter: pointer to hdd adapter
+ *
+ * Return: None
+ */
+void hdd_clear_fils_connection_info(struct hdd_adapter *adapter);
+
+/**
+ * hdd_update_hlp_info() - Update HLP packet received in FILS (re)assoc rsp
+ * @dev: net device
+ * @roam_fils_params: Fils join rsp params
+ *
+ * This API is used to send the received HLP packet in Assoc rsp(FILS AKM)
+ * to the network layer.
+ *
+ * Return: None
+ */
+void hdd_update_hlp_info(struct net_device *dev,
+			 struct csr_roam_info *roam_info);
+#else
+static inline void hdd_clear_fils_connection_info(struct hdd_adapter *adapter)
+{ }
+static inline void hdd_update_hlp_info(struct net_device *dev,
+				       struct csr_roam_info *roam_info)
+{}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
+static inline void hdd_dev_setup_destructor(struct net_device *dev)
+{
+	dev->destructor = free_netdev;
+}
+#else
+static inline void hdd_dev_setup_destructor(struct net_device *dev)
+{
+	dev->needs_free_netdev = true;
+}
+#endif /* KERNEL_VERSION(4, 12, 0) */
+
+/**
+ * hdd_dp_trace_init() - initialize DP Trace by calling the QDF API
+ * @config: hdd config
+ *
+ * Return: NONE
+ */
+#ifdef CONFIG_DP_TRACE
+void hdd_dp_trace_init(struct hdd_config *config);
+#else
+static inline
+void hdd_dp_trace_init(struct hdd_config *config) {}
+#endif
+
+void hdd_set_rx_mode_rps(bool enable);
+
+/**
+ * hdd_drv_ops_inactivity_handler() - Timeout handler for driver ops
+ * inactivity timer
+ *
+ * Return: None
+ */
+void hdd_drv_ops_inactivity_handler(void);
+
+/**
+ * hdd_start_driver_ops_timer() - Starts driver ops inactivity timer
+ * @drv_op: Enum indicating driver op
+ *
+ * Return: none
+ */
+void hdd_start_driver_ops_timer(int drv_op);
+
+/**
+ * hdd_stop_driver_ops_timer() - Stops driver ops inactivity timer
+ *
+ * Return: none
+ */
+void hdd_stop_driver_ops_timer(void);
+
+/**
+ * hdd_limit_max_per_index_score() -check if per index score doesn't exceed 100%
+ * (0x64). If it exceed make it 100%
+ *
+ * @per_index_score: per_index_score as input
+ *
+ * Return: per_index_score within the max limit
+ */
+uint32_t hdd_limit_max_per_index_score(uint32_t per_index_score);
+
+/**
+ * hdd_update_score_config - API to update candidate scoring related params
+ * configuration parameters
+ * @score_config: score config to update
+ * @cfg: config params
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS hdd_update_score_config(
+	struct scoring_config *score_config, struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_get_stainfo() - get stainfo for the specified peer
+ * @astainfo: array of the station info in which the sta info
+ * corresponding to mac_addr needs to be searched
+ * @mac_addr: mac address of requested peer
+ *
+ * This function find the stainfo for the peer with mac_addr
+ *
+ * Return: stainfo if found, NULL if not found
+ */
+struct hdd_station_info *hdd_get_stainfo(struct hdd_station_info *astainfo,
+					 struct qdf_mac_addr mac_addr);
+
+/**
+ * hdd_component_psoc_open() - Open the legacy components
+ * @psoc: Pointer to psoc object
+ *
+ * This function opens the legacy components and initializes the
+ * component's private objects.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * hdd_component_psoc_close() - Close the legacy components
+ * @psoc: Pointer to psoc object
+ *
+ * This function closes the legacy components and resets the
+ * component's private objects.
+ *
+ * Return: None
+ */
+void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * hdd_component_psoc_enable() - Trigger psoc enable for CLD Components
+ *
+ * Return: None
+ */
+void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * hdd_component_psoc_disable() - Trigger psoc disable for CLD Components
+ *
+ * Return: None
+ */
+void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * hdd_component_pdev_open() - Trigger pdev open for CLD Components
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * hdd_component_pdev_close() - Trigger pdev close for CLD Components
+ *
+ * Return: None
+ */
+void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev);
+
+#ifdef WLAN_FEATURE_MEMDUMP_ENABLE
+int hdd_driver_memdump_init(void);
+void hdd_driver_memdump_deinit(void);
+#else /* WLAN_FEATURE_MEMDUMP_ENABLE */
+static inline int hdd_driver_memdump_init(void)
+{
+	return 0;
+}
+static inline void hdd_driver_memdump_deinit(void)
+{
+}
+#endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
+/**
+ * hdd_is_cli_iface_up() - check if there is any cli iface up
+ * @hdd_ctx: HDD context
+ *
+ * Return: return true if there is any cli iface(STA/P2P_CLI) is up
+ *         else return false
+ */
+bool hdd_is_cli_iface_up(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_set_disconnect_status() - set adapter disconnection status
+ * @hdd_adapter: Pointer to hdd adapter
+ * @disconnecting: Disconnect status to set
+ *
+ * Return: None
+ */
+void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool disconnecting);
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+/**
+ * wlan_hdd_set_mon_chan() - Set capture channel on the monitor mode interface.
+ * @adapter: Handle to adapter
+ * @chan: Monitor mode channel
+ * @bandwidth: Capture channel bandwidth
+ *
+ * Return: 0 on success else error code.
+ */
+int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
+			  uint32_t bandwidth);
+#else
+static inline
+int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
+			  uint32_t bandwidth)
+{
+	return 0;
+}
+#endif
+
+/**
+ * hdd_wlan_get_version() - Get version information
+ * @hdd_ctx: Global HDD context
+ * @version_len: length of the version buffer size
+ * @version: the buffer to the version string
+ *
+ * This function is used to get Wlan Driver, Firmware, Hardware Version
+ * & the Board related information.
+ *
+ * Return: the length of the version string
+ */
+uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx,
+			      const size_t version_len, uint8_t *version);
+/**
+ * hdd_assemble_rate_code() - assemble rate code to be sent to FW
+ * @preamble: rate preamble
+ * @nss: number of streams
+ * @rate: rate index
+ *
+ * Rate code assembling is different for targets which are 11ax capable.
+ * Check for the target support and assemble the rate code accordingly.
+ *
+ * Return: assembled rate code
+ */
+int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate);
+
+/**
+ * hdd_set_11ax_rate() - set 11ax rate
+ * @adapter: adapter being modified
+ * @value: new 11ax rate code
+ * @sap_config: pointer to SAP config to check HW mode
+ *		this will be NULL for call from STA persona
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int hdd_set_11ax_rate(struct hdd_adapter *adapter, int value,
+		      struct sap_config *sap_config);
+
+/**
+ * hdd_update_hw_sw_info() - API to update the HW/SW information
+ * @hdd_ctx: Global HDD context
+ *
+ * API to update the HW and SW information in the driver
+ *
+ * Note:
+ * All the version/revision information would only be retrieved after
+ * firmware download
+ *
+ * Return: None
+ */
+void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_get_nud_stats_cb() - callback api to update the stats received from FW
+ * @data: pointer to hdd context.
+ * @rsp: pointer to data received from FW.
+ * @context: callback context
+ *
+ * This is called when wlan driver received response event for
+ * get arp stats to firmware.
+ *
+ * Return: None
+ */
+void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp, void *context);
+
+/**
+ * hdd_context_get_mac_handle() - get mac handle from hdd context
+ * @hdd_ctx: Global HDD context pointer
+ *
+ * Retrieves the global MAC handle from the HDD context
+ *
+ * Return: The global MAC handle (which may be NULL)
+ */
+static inline
+mac_handle_t hdd_context_get_mac_handle(struct hdd_context *hdd_ctx)
+{
+	return hdd_ctx ? hdd_ctx->mac_handle : NULL;
+}
+
+/**
+ * hdd_adapter_get_mac_handle() - get mac handle from hdd adapter
+ * @adapter: HDD adapter pointer
+ *
+ * Retrieves the global MAC handle given an HDD adapter
+ *
+ * Return: The global MAC handle (which may be NULL)
+ */
+static inline
+mac_handle_t hdd_adapter_get_mac_handle(struct hdd_adapter *adapter)
+{
+	return adapter ?
+		hdd_context_get_mac_handle(adapter->hdd_ctx) : NULL;
+}
+
+/**
+ * hdd_handle_to_context() - turn an HDD handle into an HDD context
+ * @hdd_handle: HDD handle to be converted
+ *
+ * Return: HDD context referenced by @hdd_handle
+ */
+static inline
+struct hdd_context *hdd_handle_to_context(hdd_handle_t hdd_handle)
+{
+	return (struct hdd_context *)hdd_handle;
+}
+
+/**
+ * wlan_hdd_free_cache_channels() - Free the cache channels list
+ * @hdd_ctx: Pointer to HDD context
+ *
+ * Return: None
+ */
+void wlan_hdd_free_cache_channels(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_update_dynamic_mac() - Updates the dynamic MAC list
+ * @hdd_ctx: Pointer to HDD context
+ * @curr_mac_addr: Current interface mac address
+ * @new_mac_addr: New mac address which needs to be updated
+ *
+ * This function updates newly configured MAC address to the
+ * dynamic MAC address list corresponding to the current
+ * adapter MAC address
+ *
+ * Return: None
+ */
+void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx,
+			    struct qdf_mac_addr *curr_mac_addr,
+			    struct qdf_mac_addr *new_mac_addr);
+
+#endif /* end #if !defined(WLAN_HDD_MAIN_H) */
diff --git a/core/hdd/inc/wlan_hdd_misc.h b/core/hdd/inc/wlan_hdd_misc.h
new file mode 100644
index 0000000..609e07b
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_misc.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012-2014,2016-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.
+ */
+
+#ifndef WLAN_HDD_MISC_H
+#define WLAN_HDD_MISC_H
+/*
+ * If MULTI_IF_NAME is defined, then prepend MULTI_IF_NAME to the filename
+ * to prevent name conflicts when loading multiple instances of the driver.
+ */
+#ifdef MULTI_IF_NAME
+#define PREFIX MULTI_IF_NAME "/"
+#else
+#define PREFIX ""
+#endif
+
+#ifdef MSM_PLATFORM
+#define WLAN_INI_FILE              "wlan/qca_cld/" PREFIX "WCNSS_qcom_cfg.ini"
+#define WLAN_MAC_FILE              "wlan/qca_cld/" PREFIX "wlan_mac.bin"
+#else
+#define WLAN_INI_FILE              "wlan/" PREFIX "qcom_cfg.ini"
+#define WLAN_MAC_FILE              "wlan/" PREFIX "wlan_mac.bin"
+#endif /* MSM_PLATFORM */
+
+#endif /* WLAN_HDD_MISC_H */
diff --git a/core/hdd/inc/wlan_hdd_nan.h b/core/hdd/inc/wlan_hdd_nan.h
new file mode 100644
index 0000000..57ec6b2
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_nan.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#ifndef __WLAN_HDD_NAN_H
+#define __WLAN_HDD_NAN_H
+
+/**
+ * DOC: wlan_hdd_nan.h
+ *
+ * WLAN Host Device Driver NAN API specification
+ */
+
+struct hdd_context;
+
+#ifdef WLAN_FEATURE_NAN
+struct wiphy;
+struct wireless_dev;
+
+int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  const void *data,
+				  int data_len);
+
+bool wlan_hdd_nan_is_supported(struct hdd_context *hdd_ctx);
+
+/**
+ * wlan_hdd_cfg80211_nan_callback() - cfg80211 NAN event handler
+ * @hdd_handle: opaque handle to the global HDD context
+ * @msg: NAN event message
+ *
+ * This is a callback function and it gets called when we need to report
+ * a nan event to userspace.  The wlan host driver simply encapsulates the
+ * event into a netlink payload and then forwards it to userspace via a
+ * cfg80211 vendor event.
+ *
+ * Return: nothing
+ */
+void wlan_hdd_cfg80211_nan_callback(hdd_handle_t hdd_handle, tSirNanEvent *msg);
+#else
+static inline bool wlan_hdd_nan_is_supported(struct hdd_context *hdd_ctx)
+{
+	return false;
+}
+static inline void hdd_nan_populate_cds_config(struct cds_config_info *cds_cfg,
+			struct hdd_context *hdd_ctx)
+{
+}
+
+static inline void hdd_nan_populate_pmo_config(struct pmo_psoc_cfg *pmo_cfg,
+			struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+void wlan_hdd_cfg80211_nan_callback(hdd_handle_t hdd_handle, tSirNanEvent *msg)
+{
+}
+#endif /* WLAN_FEATURE_NAN */
+#endif /* __WLAN_HDD_NAN_H */
diff --git a/core/hdd/inc/wlan_hdd_napi.h b/core/hdd/inc/wlan_hdd_napi.h
new file mode 100644
index 0000000..9e00821
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_napi.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015-2018 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.
+ */
+
+#ifndef __HDD_NAPI_H__
+#define __HDD_NAPI_H__
+
+#ifdef FEATURE_NAPI
+/**
+ * DOC: wlan_hdd_napi.h
+ *
+ * WLAN NAPI interface module headers
+ */
+
+/* CLD headers */
+#include "hif_napi.h"
+
+/* Linux headers */
+#include <linux/netdevice.h> /* net_device */
+
+struct hdd_context;
+
+#define HDD_NAPI_ANY (-1)
+
+int hdd_napi_enabled(int id);
+int hdd_napi_create(void);
+int hdd_napi_destroy(int force);
+int hdd_display_napi_stats(void);
+int hdd_clear_napi_stats(void);
+
+/* the following triggers napi_enable/disable as required */
+int hdd_napi_event(enum qca_napi_event event, void *data);
+
+int hdd_napi_poll(struct napi_struct *napi, int budget);
+
+struct qca_napi_data *hdd_napi_get_all(void);
+
+#if defined HELIUMPLUS && defined MSM_PLATFORM
+int hdd_napi_apply_throughput_policy(struct hdd_context *hddctx,
+				     uint64_t              tx_packets,
+				     uint64_t              rx_packets);
+int hdd_napi_serialize(int is_on);
+#else
+static inline int hdd_napi_apply_throughput_policy(struct hdd_context *hddctx,
+						   uint64_t tx_packets,
+						   uint64_t rx_packets)
+{
+	return 0;
+}
+static inline int hdd_napi_serialize(int is_on)
+{
+	return -EINVAL;
+}
+#endif /* HELIUMPLUS && MSM_PLATFORM */
+
+#else /* ! defined(FEATURE_NAPI) */
+#include "hif_napi.h"
+/**
+ * Stub API
+ *
+ */
+
+#define HDD_NAPI_ANY (-1)
+
+static inline int hdd_napi_enabled(int id) { return 0; }
+static inline int hdd_napi_create(void) { return 0; }
+static inline int hdd_napi_destroy(int force) { return 0; }
+static inline int hdd_display_napi_stats(void) { return 0; }
+static inline int hdd_clear_napi_stats(void) { return 0; }
+static inline int hdd_napi_event(enum qca_napi_event event, void *data)
+{
+	return 0;
+}
+static inline struct qca_napi_data *hdd_napi_get_all(void) { return NULL; }
+static inline int hdd_napi_apply_throughput_policy(void *hdd_ctx,
+				uint64_t tx_packets, uint64_t rx_packets)
+{
+	return 0;
+}
+
+static inline int hdd_napi_serialize(int is_on)
+{
+	return -EINVAL;
+}
+#endif /* FEATURE_NAPI */
+
+#endif /*  HDD_NAPI_H__ */
diff --git a/core/hdd/inc/wlan_hdd_oemdata.h b/core/hdd/inc/wlan_hdd_oemdata.h
new file mode 100644
index 0000000..c8cd09d
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_oemdata.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_oemdata.h
+ *
+ * Internal includes for the oem data
+ */
+
+#ifndef __WLAN_HDD_OEM_DATA_H__
+#define __WLAN_HDD_OEM_DATA_H__
+
+struct hdd_context;
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
+#ifndef OEM_DATA_REQ_SIZE
+#define OEM_DATA_REQ_SIZE 500
+#endif
+
+#ifndef OEM_DATA_RSP_SIZE
+#define OEM_DATA_RSP_SIZE 1724
+#endif
+
+#define OEM_APP_SIGNATURE_LEN      16
+#define OEM_APP_SIGNATURE_STR      "QUALCOMM-OEM-APP"
+
+#define OEM_TARGET_SIGNATURE_LEN   8
+#define OEM_TARGET_SIGNATURE       "QUALCOMM"
+
+#define OEM_CAP_MAX_NUM_CHANNELS   128
+
+/**
+ * typedef eOemErrorCode - OEM error codes
+ * @OEM_ERR_NULL_CONTEXT: %NULL context
+ * @OEM_ERR_APP_NOT_REGISTERED: OEM App is not registered
+ * @OEM_ERR_INVALID_SIGNATURE: Invalid signature
+ * @OEM_ERR_NULL_MESSAGE_HEADER: Invalid message header
+ * @OEM_ERR_INVALID_MESSAGE_TYPE: Invalid message type
+ * @OEM_ERR_INVALID_MESSAGE_LENGTH: Invalid length in message body
+ */
+enum oem_err_code {
+	OEM_ERR_NULL_CONTEXT = 1,
+	OEM_ERR_APP_NOT_REGISTERED,
+	OEM_ERR_INVALID_SIGNATURE,
+	OEM_ERR_NULL_MESSAGE_HEADER,
+	OEM_ERR_INVALID_MESSAGE_TYPE,
+	OEM_ERR_INVALID_MESSAGE_LENGTH
+};
+
+/**
+ * struct driver_version - Driver version identifier (w.x.y.z)
+ * @major: Version ID major number
+ * @minor: Version ID minor number
+ * @patch: Version ID patch number
+ * @build: Version ID build number
+ */
+struct driver_version {
+	uint8_t major;
+	uint8_t minor;
+	uint8_t patch;
+	uint8_t build;
+};
+
+/**
+ * struct oem_data_cap - OEM Data Capabilities
+ * @oem_target_signature: Signature of chipset vendor, e.g. QUALCOMM
+ * @oem_target_type: Chip type
+ * @oem_fw_version: Firmware version
+ * @driver_version: Host software version
+ * @allowed_dwell_time_min: Channel dwell time - allowed minimum
+ * @allowed_dwell_time_max: Channel dwell time - allowed maximum
+ * @curr_dwell_time_min: Channel dwell time - current minimim
+ * @curr_dwell_time_max: Channel dwell time - current maximum
+ * @supported_bands: Supported bands, 2.4G or 5G Hz
+ * @num_channels: Num of channels IDs to follow
+ * @channel_list: List of channel IDs
+ */
+struct oem_data_cap {
+	uint8_t oem_target_signature[OEM_TARGET_SIGNATURE_LEN];
+	uint32_t oem_target_type;
+	uint32_t oem_fw_version;
+	struct driver_version driver_version;
+	uint16_t allowed_dwell_time_min;
+	uint16_t allowed_dwell_time_max;
+	uint16_t curr_dwell_time_min;
+	uint16_t curr_dwell_time_max;
+	uint16_t supported_bands;
+	uint16_t num_channels;
+	uint8_t channel_list[OEM_CAP_MAX_NUM_CHANNELS];
+};
+
+/**
+ * struct hdd_channel_info - Channel information
+ * @chan_id: channel id
+ * @reserved0: reserved for padding and future use
+ * @mhz: primary 20 MHz channel frequency in mhz
+ * @band_center_freq1: Center frequency 1 in MHz
+ * @band_center_freq2: Center frequency 2 in MHz, valid only for 11ac
+ *	VHT 80+80 mode
+ * @info: channel info
+ * @reg_info_1: regulatory information field 1 which contains min power,
+ *	max power, reg power and reg class id
+ * @reg_info_2: regulatory information field 2 which contains antennamax
+ */
+struct hdd_channel_info {
+	uint32_t chan_id;
+	uint32_t reserved0;
+	uint32_t mhz;
+	uint32_t band_center_freq1;
+	uint32_t band_center_freq2;
+	uint32_t info;
+	uint32_t reg_info_1;
+	uint32_t reg_info_2;
+};
+
+/**
+ * struct peer_status_info - Status information for a given peer
+ * @peer_mac_addr: peer mac address
+ * @peer_status: peer status: 1: CONNECTED, 2: DISCONNECTED
+ * @vdev_id: vdev_id for the peer mac
+ * @peer_capability: peer capability: 0: RTT/RTT2, 1: RTT3. Default is 0
+ * @reserved0: reserved0
+ * @peer_chan_info: channel info on which peer is connected
+ */
+struct peer_status_info {
+	uint8_t peer_mac_addr[ETH_ALEN];
+	uint8_t peer_status;
+	uint8_t vdev_id;
+	uint32_t peer_capability;
+	uint32_t reserved0;
+	struct hdd_channel_info peer_chan_info;
+};
+
+/**
+ * enum oem_capability_mask - mask field for userspace client capabilities
+ * @OEM_CAP_RM_FTMRR: FTM range report mask bit
+ * @OEM_CAP_RM_LCI: LCI capability mask bit
+ */
+enum oem_capability_mask {
+	OEM_CAP_RM_FTMRR = (1 << (0)),
+	OEM_CAP_RM_LCI = (1 << (1)),
+};
+
+/**
+ * struct oem_get_capability_rsp - capabilities set by userspace and target.
+ * @target_cap: target capabilities
+ * @client_capabilities: capabilities set by userspace via set request
+ */
+struct oem_get_capability_rsp {
+	struct oem_data_cap target_cap;
+	struct sme_oem_capability cap;
+};
+
+void hdd_send_peer_status_ind_to_oem_app(struct qdf_mac_addr *peerMac,
+					 uint8_t peerStatus,
+					 uint8_t peerTimingMeasCap,
+					 uint8_t sessionId,
+					 struct sSirSmeChanInfo *chan_info,
+					 enum QDF_OPMODE dev_mode);
+
+int iw_get_oem_data_cap(struct net_device *dev, struct iw_request_info *info,
+			union iwreq_data *wrqu, char *extra);
+
+/**
+ * oem_activate_service() - API to register the oem command handler
+ * @hdd_ctx: Pointer to HDD Context
+ *
+ * This API is used to register the handler to receive netlink message
+ * from an OEM application process
+ *
+ * Return: 0 on success and errno on failure
+ */
+int oem_activate_service(struct hdd_context *hdd_ctx);
+
+/**
+ * oem_deactivate_service() - API to unregister the oem command handler
+ *
+ * This API is used to deregister the handler to receive netlink message
+ * from an OEM application process
+ *
+ * Return: 0 on success and errno on failure
+ */
+int oem_deactivate_service(void);
+
+void hdd_send_oem_data_rsp_msg(struct oem_data_rsp *oem_rsp);
+void hdd_update_channel_bw_info(struct hdd_context *hdd_ctx,
+				uint16_t chan,
+				void *hdd_chan_info);
+#else
+static inline int oem_activate_service(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+
+static inline int oem_deactivate_service(void)
+{
+	return 0;
+}
+
+static inline void hdd_send_oem_data_rsp_msg(void *oem_rsp) {}
+
+static inline void hdd_update_channel_bw_info(struct hdd_context *hdd_ctx,
+					      uint16_t chan,
+					      void *hdd_chan_info) {}
+#endif /* FEATURE_OEM_DATA_SUPPORT */
+#endif /* __WLAN_HDD_OEM_DATA_H__ */
diff --git a/core/hdd/inc/wlan_hdd_p2p.h b/core/hdd/inc/wlan_hdd_p2p.h
new file mode 100644
index 0000000..9796b28
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_p2p.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __P2P_H
+#define __P2P_H
+
+/**
+ * DOC: wlan_hdd_p2p.h
+ *
+ * Linux HDD P2P include file
+ */
+
+#define WLAN_HDD_GET_TYPE_FRM_FC(__fc__)         (((__fc__) & 0x0F) >> 2)
+#define WLAN_HDD_GET_SUBTYPE_FRM_FC(__fc__)      (((__fc__) & 0xF0) >> 4)
+#define WLAN_HDD_80211_FRM_DA_OFFSET             4
+#define WLAN_HDD_80211_PEER_ADDR_OFFSET (WLAN_HDD_80211_FRM_DA_OFFSET + \
+					 MAC_ADDR_LEN)
+
+#define P2P_POWER_SAVE_TYPE_OPPORTUNISTIC        (1 << 0)
+#define P2P_POWER_SAVE_TYPE_PERIODIC_NOA         (1 << 1)
+#define P2P_POWER_SAVE_TYPE_SINGLE_NOA           (1 << 2)
+
+struct p2p_app_set_ps {
+	uint8_t opp_ps;
+	uint32_t ctWindow;
+	uint8_t count;
+	uint32_t duration;
+	uint32_t interval;
+	uint32_t single_noa_duration;
+	uint8_t psSelection;
+};
+
+int wlan_hdd_cfg80211_remain_on_channel(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					struct ieee80211_channel *chan,
+					unsigned int duration, u64 *cookie);
+
+int wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
+					       struct wireless_dev *wdev,
+					       u64 cookie);
+
+int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+					  struct wireless_dev *wdev,
+					  u64 cookie);
+
+int hdd_set_p2p_ps(struct net_device *dev, void *msgData);
+int hdd_set_p2p_opps(struct net_device *dev, uint8_t *command);
+int hdd_set_p2p_noa(struct net_device *dev, uint8_t *command);
+
+void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
+			     uint32_t nFrameLength, uint8_t *pbFrames,
+			     uint8_t frameType, uint32_t rxChan, int8_t rxRssi);
+
+int wlan_hdd_check_remain_on_channel(struct hdd_adapter *adapter);
+void wlan_hdd_cancel_existing_remain_on_channel(struct hdd_adapter *adapter);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
+		     struct cfg80211_mgmt_tx_params *params, u64 *cookie);
+#else
+int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
+		     struct ieee80211_channel *chan, bool offchan,
+		     unsigned int wait,
+		     const u8 *buf, size_t len, bool no_cck,
+		     bool dont_wait_for_ack, u64 *cookie);
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
+					       const char *name,
+					       unsigned char name_assign_type,
+					       enum nl80211_iftype type,
+					       struct vif_params *params);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) || defined(WITH_BACKPORTS)
+struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
+					       const char *name,
+					       unsigned char name_assign_type,
+					       enum nl80211_iftype type,
+					       u32 *flags,
+					       struct vif_params *params);
+#else
+struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
+					       const char *name,
+					       enum nl80211_iftype type,
+					       u32 *flags,
+					       struct vif_params *params);
+
+#endif
+
+int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev);
+int __wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev);
+
+
+void wlan_hdd_cleanup_remain_on_channel_ctx(struct hdd_adapter *adapter);
+
+void wlan_hdd_roc_request_dequeue(struct work_struct *work);
+
+/**
+ * wlan_hdd_set_power_save() - hdd set power save
+ * @adapter:    adapter context
+ * @ps_config:  pointer to power save configure
+ *
+ * This function sets power save parameters.
+ *
+ * Return: 0 - success
+ *    others - failure
+ */
+int wlan_hdd_set_power_save(struct hdd_adapter *adapter,
+	struct p2p_ps_config *ps_config);
+
+/**
+ * wlan_hdd_set_mas() - Function to set MAS value to FW
+ * @adapter:            Pointer to HDD adapter
+ * @mas_value:          0-Disable, 1-Enable MAS
+ *
+ * This function passes down the value of MAS to FW
+ *
+ * Return: Configuration message posting status, SUCCESS or Fail
+ *
+ */
+int32_t wlan_hdd_set_mas(struct hdd_adapter *adapter, uint8_t mas_value);
+
+/**
+ * wlan_hdd_set_mcc_p2p_quota() - Function to set quota for P2P
+ * to FW
+ * @adapter:            Pointer to HDD adapter
+ * @set_value:          Quota value for the interface
+ *
+ * This function is used to set the quota for P2P cases
+ *
+ * Return: Configuration message posting status, SUCCESS or Fail
+ *
+ */
+int wlan_hdd_set_mcc_p2p_quota(struct hdd_adapter *adapter,
+			       uint32_t set_value);
+
+/**
+ * wlan_hdd_go_set_mcc_p2p_quota() - Function to set quota for
+ * P2P GO to FW
+ * @hostapd_adapter:    Pointer to HDD adapter
+ * @set_value:          Quota value for the interface
+ *
+ * This function is used to set the quota for P2P GO cases
+ *
+ * Return: Configuration message posting status, SUCCESS or Fail
+ *
+ */
+int wlan_hdd_go_set_mcc_p2p_quota(struct hdd_adapter *hostapd_adapter,
+				  uint32_t set_value);
+/**
+ * wlan_hdd_set_mcc_latency() - Set MCC latency to FW
+ * @adapter: Pointer to HDD adapter
+ * @set_value: Latency value
+ *
+ * Sets the MCC latency value during STA-P2P concurrency
+ *
+ * Return: None
+ */
+void wlan_hdd_set_mcc_latency(struct hdd_adapter *adapter, int set_value);
+
+/**
+ * wlan_hdd_cleanup_actionframe() - Cleanup action frame
+ * @adapter: Pointer to HDD adapter
+ *
+ * This function cleans up action frame.
+ *
+ * Return: None
+ */
+void wlan_hdd_cleanup_actionframe(struct hdd_adapter *adapter);
+#endif /* __P2P_H */
diff --git a/core/hdd/inc/wlan_hdd_packet_filter_api.h b/core/hdd/inc/wlan_hdd_packet_filter_api.h
new file mode 100644
index 0000000..77e5dfa
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_packet_filter_api.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#if !defined(WLAN_HDD_PACKET_FILTER_API_H__)
+#define WLAN_HDD_PACKET_FILTER_API_H__
+
+/**
+ * DOC: wlan_hdd_packet_filter_rules.h
+ *
+ */
+
+/* Include files */
+#include "wlan_hdd_assoc.h"
+#include "wlan_hdd_power.h"
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+
+/**
+ * hdd_enable_default_pkt_filters() - Enable default packet filters based
+ * on, filters bit map provided in INI, when target goes to suspend mode
+ * @adapter: Adapter context for which default filters to be configure
+ *
+ * Return: zero if success, non-zero otherwise
+ */
+int hdd_enable_default_pkt_filters(struct hdd_adapter *pAadapter);
+
+/**
+ * hdd_disable_default_pkt_filters() - Disable default packet filters based
+ * on, filters bit map provided in INI, when target resumes
+ * @adapter: Adapter context for which default filters to be cleared
+ *
+ * Return: zero if success, non-zero otherwise
+ */
+int hdd_disable_default_pkt_filters(struct hdd_adapter *adapter);
+
+/**
+ * wlan_hdd_set_filter() - Set packet filter
+ * @hdd_ctx: Global HDD context
+ * @request: Packet filter request struct
+ * @sessionId: Target session for the request
+ *
+ * Return: 0 on success, non-zero on error
+ */
+int wlan_hdd_set_filter(struct hdd_context *hdd_ctx,
+			struct pkt_filter_cfg *request,
+			uint8_t sessionId);
+
+#else /* WLAN_FEATURE_PACKET_FILTERING */
+
+static inline int
+hdd_enable_default_pkt_filters(struct hdd_adapter *adapter)
+{
+	return 0;
+}
+
+static inline int
+hdd_disable_default_pkt_filters(struct hdd_adapter *adapter)
+{
+	return 0;
+}
+
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+#endif
diff --git a/core/hdd/inc/wlan_hdd_packet_filter_rules.h b/core/hdd/inc/wlan_hdd_packet_filter_rules.h
new file mode 100644
index 0000000..8d2bbfc
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_packet_filter_rules.h
@@ -0,0 +1,180 @@
+/*
+ * 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.
+ */
+
+#if !defined(WLAN_HDD_PACKET_FILTER_RULES_H__)
+#define WLAN_HDD_PACKET_FILTER_RULES_H__
+
+/**
+ * DOC: wlan_hdd_packet_filter_rules.h
+ *
+ */
+
+/* Include files */
+
+#define MAX_NUM_PACKET_FILTERS 6
+
+/**
+ * @filter_action: Filter action, set/clear the filter
+ * Ex: filter_action = 1 set the filter
+ *     filter_action = 2 clear the filter
+ * @filter_id: Filter id  Ex: 1/2/3/4/5 .... MAX_NUM_FILTERS
+ * @num_params: Number of parameters Ex: 1/2/3/4/5
+ * @params_data: Packet filter parameters details
+ *
+ * @protocol_layer: the type of protocol layer header to which the data
+ *                  being configured correspond
+ * Ex: protocol_layer = 1 - MAC Header
+ *     protocol_layer = 2 - ARP Header
+ *     protocol_layer = 3 - IP Header
+ * @compare_flag: comparison type
+ * EX: compare_flag = 0 - comparison is invalid
+ *     compare_flag = 1 - compare for equality of the data present in received
+ *                        packet to the corresponding  configured data
+ *     compare_flag = 2 - compare for equality of the data present in received
+ *                        packet to the corresponding configured data after
+ *                        applying the mask
+ *     compare_flag = 3 - compare for non-equality of the data present in
+ *                        received packet to the corresponding configured data
+ *     compare_flag = 4 - compare for non-equality of the data present in
+ *                        received packet to the corresponding configured data
+ *                        after applying the mask
+ * @data_fffset: Offset of the data to compare from the respective protocol
+ *               layer header start (as per the respective protocol
+ *               specification) in terms of bytes
+ * @data_length: length of data to compare
+ * @compare_data: Array of 8 bytes
+ * @data_mask: Mask to be applied on the received packet data (Array of 8 bytes)
+ */
+static struct pkt_filter_cfg
+		packet_filter_default_rules[MAX_NUM_PACKET_FILTERS] = {
+	{ .filter_action = 1,
+	  .filter_id = 0,
+	  .num_params = 3,
+	  .params_data = {
+		 { .protocol_layer = 1,
+		   .compare_flag = 5,
+		   .data_offset = 0,
+		   .data_length = 1,
+		   .compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
+		 { .protocol_layer = 2,
+		   .compare_flag = 3,
+		   .data_offset = 6,
+		   .data_length = 2,
+		   .compare_data = {134, 221, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
+		 { .protocol_layer = 3,
+		   .compare_flag = 4,
+		   .data_offset = 24,
+		   .data_length = 2,
+		   .compare_data = {255, 0, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {255, 0, 0, 0, 0, 0, 0, 0} } } },
+
+	{ .filter_action = 1,
+	  .filter_id = 0,
+	  .num_params = 3,
+	  .params_data = {
+		 { .protocol_layer = 1,
+		   .compare_flag = 5,
+		   .data_offset = 0,
+		   .data_length = 1,
+		   .compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
+		 { .protocol_layer = 2,
+		   .compare_flag = 3,
+		   .data_offset = 6,
+		   .data_length = 2,
+		   .compare_data = {8, 0, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
+		 { .protocol_layer = 3,
+		   .compare_flag = 4,
+		   .data_offset = 16,
+		   .data_length = 1,
+		   .compare_data = {224, 0, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {240, 0, 0, 0, 0, 0, 0, 0} } } },
+	{ .filter_action = 1,
+	  .filter_id = 0,
+	  .num_params = 3,
+	  .params_data = {
+		 { .protocol_layer = 1,
+		   .compare_flag = 5,
+		   .data_offset = 0,
+		   .data_length = 1,
+		   .compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
+		 { .protocol_layer = 2,
+		   .compare_flag = 3,
+		   .data_offset = 6,
+		   .data_length = 2,
+		   .compare_data = {8, 0, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
+		 { .protocol_layer = 3,
+		   .compare_flag = 4,
+		   .data_offset = 18,
+		   .data_length = 2,
+		   .compare_data = {0, 255, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 255, 0, 0, 0, 0, 0, 0} } } },
+	{ .filter_action = 1,
+	  .filter_id = 0,
+	  .num_params = 2,
+	  .params_data = {
+		 { .protocol_layer = 1,
+		   .compare_flag = 5,
+		   .data_offset = 0,
+		   .data_length = 1,
+		   .compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
+		 { .protocol_layer = 2,
+		   .compare_flag = 3,
+		   .data_offset = 8,
+		   .data_length = 4,
+		   .compare_data = {0, 1, 175, 129, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} } } },
+	{ .filter_action = 1,
+	  .filter_id = 0,
+	  .num_params = 2,
+	  .params_data = {
+		 { .protocol_layer = 1,
+		   .compare_flag = 5,
+		   .data_offset = 0,
+		   .data_length = 1,
+		   .compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
+		 { .protocol_layer = 2,
+		   .compare_flag = 3,
+		   .data_offset = 6,
+		   .data_length = 2,
+		   .compare_data = {0, 39, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} } } },
+	{ .filter_action = 1,
+	  .filter_id = 0,
+	  .num_params = 2,
+	  .params_data = {
+		 { .protocol_layer = 1,
+		   .compare_flag = 5,
+		   .data_offset = 0,
+		   .data_length = 1,
+		   .compare_data = {1, 0, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} },
+		 { .protocol_layer = 2,
+		   .compare_flag = 3,
+		   .data_offset = 4,
+		   .data_length = 2,
+		   .compare_data = {0, 12, 0, 0, 0, 0, 0, 0},
+		   .data_mask = {0, 0, 0, 0, 0, 0, 0, 0} } } } };
+#endif
diff --git a/core/hdd/inc/wlan_hdd_power.h b/core/hdd/inc/wlan_hdd_power.h
new file mode 100644
index 0000000..764ee50
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_power.h
@@ -0,0 +1,554 @@
+/*
+ * Copyright (c) 2012, 2014-2018 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.
+ */
+
+#ifndef __WLAN_HDD_POWER_H
+#define __WLAN_HDD_POWER_H
+
+/**
+ * DOC: wlan_hdd_power.h
+ *
+ * HDD Power Management API
+ */
+
+#include "wlan_hdd_main.h"
+
+#define HDD_WAKELOCK_TIMEOUT_CONNECT 1000
+#define HDD_WAKELOCK_TIMEOUT_RESUME 1000
+
+/*
+ * HDD_WAKELOCK_CONNECT_COMPLETE = CSR_JOIN_FAILURE_TIMEOUT_DEFAULT (3000) +
+ *                      WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STADEF (1000) +
+ *                      WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STADEF  (2000)
+ */
+#define HDD_WAKELOCK_CONNECT_COMPLETE 6000
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+
+#define HDD_MAX_CMP_PER_PACKET_FILTER	5
+
+/**
+ * enum pkt_filter_protocol_layer - packet filter protocol layer
+ * @HDD_FILTER_PROTO_TYPE_INVALID: Invalid initial value
+ * @HDD_FILTER_PROTO_TYPE_MAC: MAC protocol
+ * @HDD_FILTER_PROTO_TYPE_ARP: ARP protocol
+ * @HDD_FILTER_PROTO_TYPE_IPV4: IP V4 protocol
+ * @HDD_FILTER_PROTO_TYPE_IPV6: IP V6 protocol
+ * @HDD_FILTER_PROTO_TYPE_UDP: UDP protocol
+ * @HDD_FILTER_PROTO_TYPE_INVALID: Max place holder value
+ */
+enum pkt_filter_protocol_layer {
+	HDD_FILTER_PROTO_TYPE_INVALID = 0,
+	HDD_FILTER_PROTO_TYPE_MAC = 1,
+	HDD_FILTER_PROTO_TYPE_ARP = 2,
+	HDD_FILTER_PROTO_TYPE_IPV4 = 3,
+	HDD_FILTER_PROTO_TYPE_IPV6 = 4,
+	HDD_FILTER_PROTO_TYPE_UDP = 5,
+	HDD_FILTER_PROTO_TYPE_MAX
+};
+
+/**
+ * enum pkt_filter_action - packet filter action
+ * @HDD_RCV_FILTER_INVALID: Invalid initial value
+ * @HDD_RCV_FILTER_SET: Packet filter set
+ * @HDD_RCV_FILTER_CLEAR: Packet filter clear
+ * @HDD_RCV_FILTER_MAX: Max place holder value
+ */
+enum pkt_filter_action {
+	HDD_RCV_FILTER_INVALID = 0,
+	HDD_RCV_FILTER_SET = 1,
+	HDD_RCV_FILTER_CLEAR = 2,
+	HDD_RCV_FILTER_MAX
+};
+
+/**
+ * enum pkt_filter_compare_flag - packet filter compare flag
+ * @HDD_FILTER_CMP_TYPE_INVALID: Invalid initial value
+ * @HDD_FILTER_CMP_TYPE_EQUAL: Compare if filter is equal
+ * @HDD_FILTER_CMP_TYPE_MASK_EQUAL: Compare if filter mask is equal
+ * @HDD_FILTER_CMP_TYPE_NOT_EQUAL: Compare if filter is not equal
+ * @HDD_FILTER_CMP_TYPE_MASK_NOT_EQUAL: Compare if filter mask is not equal
+ * @HDD_FILTER_CMP_TYPE_MAX: Max place holder value
+ */
+enum pkt_filter_compare_flag {
+	HDD_FILTER_CMP_TYPE_INVALID = 0,
+	HDD_FILTER_CMP_TYPE_EQUAL = 1,
+	HDD_FILTER_CMP_TYPE_MASK_EQUAL = 2,
+	HDD_FILTER_CMP_TYPE_NOT_EQUAL = 3,
+	HDD_FILTER_CMP_TYPE_MASK_NOT_EQUAL = 4,
+	HDD_FILTER_CMP_TYPE_MAX
+};
+
+/**
+ * struct pkt_filter_param_cfg - packet filter parameter config
+ * @protocol_layer: Protocol layer
+ * @compare_flag: Compare flag
+ * @data_fffset: Data offset
+ * @data_length: Data length
+ * @compare_data: Compare data
+ * @data_mask: Data mask
+ */
+struct pkt_filter_param_cfg {
+	uint8_t protocol_layer;
+	uint8_t compare_flag;
+	uint8_t data_offset;
+	uint8_t data_length;
+	uint8_t compare_data[SIR_MAX_FILTER_TEST_DATA_LEN];
+	uint8_t data_mask[SIR_MAX_FILTER_TEST_DATA_LEN];
+};
+
+/**
+ * struct pkt_filter_cfg - packet filter config received from user space
+ * @filter_action: Filter action
+ * @filter_id: Filter id
+ * @num_params: Number of parameters
+ * @params_data: Packet filter parameters detail
+ */
+struct pkt_filter_cfg {
+	uint8_t filter_action;
+	uint8_t filter_id;
+	uint8_t num_params;
+	struct pkt_filter_param_cfg params_data[HDD_MAX_CMP_PER_PACKET_FILTER];
+};
+
+#endif
+
+/**
+ * enum suspend_resume_state - Suspend resume state
+ * @HDD_WLAN_EARLY_SUSPEND: Early suspend state.
+ * @HDD_WLAN_SUSPEND: Suspend state.
+ * @HDD_WLAN_EARLY_RESUME: Early resume state.
+ * @HDD_WLAN_RESUME: Resume state.
+ *
+ * Suspend state to indicate in diag event of suspend resume.
+ */
+enum suspend_resume_state {
+	 HDD_WLAN_EARLY_SUSPEND,
+	 HDD_WLAN_SUSPEND,
+	 HDD_WLAN_EARLY_RESUME,
+	 HDD_WLAN_RESUME
+};
+
+/**
+ * hdd_svc_fw_shutdown_ind() - API to send FW SHUTDOWN IND to Userspace
+ * @dev: Device Pointer
+ *
+ * Return: None
+ */
+void hdd_svc_fw_shutdown_ind(struct device *dev);
+
+/**
+ * hdd_wlan_shutdown() - HDD SSR shutdown function
+ *
+ * This function is called by the HIF to shutdown the driver during SSR.
+ *
+ * Return: QDF_STATUS_SUCCESS if the driver was shut down,
+ *	or an error status otherwise
+ */
+QDF_STATUS hdd_wlan_shutdown(void);
+
+/**
+ * hdd_wlan_re_init() - HDD SSR re-init function
+ *
+ * This function is called by the HIF to re-initialize the driver after SSR.
+ *
+ * Return: QDF_STATUS_SUCCESS if the driver was re-initialized,
+ *	or an error status otherwise
+ */
+QDF_STATUS hdd_wlan_re_init(void);
+
+/**
+ * hdd_enable_arp_offload() - API to enable ARP offload
+ * @adapter: Adapter context for which ARP offload is to be configured
+ * @trigger: trigger reason for request
+ *
+ * Return: None
+ */
+void hdd_enable_arp_offload(struct hdd_adapter *adapter,
+			    enum pmo_offload_trigger trigger);
+
+/**
+ * hdd_disable_arp_offload() - API to disable ARP offload
+ * @adapter: Adapter context for which ARP offload is to be configured
+ * @trigger: trigger reason for request
+ *
+ * Return: None
+ */
+void hdd_disable_arp_offload(struct hdd_adapter *adapter,
+			     enum pmo_offload_trigger trigger);
+
+/**
+ * hdd_enable_host_offloads() - Central API to enable the supported offloads
+ * @adapter:   pointer to the adapter
+ * @trigger: trigger reason for request
+ *
+ * Central function to enable the supported offloads
+ *
+ * Return: nothing
+ */
+void hdd_enable_host_offloads(struct hdd_adapter *adapter,
+			      enum pmo_offload_trigger trigger);
+
+/**
+ * hdd_disable_host_offloads() - Central API to disable the supported offloads
+ * @adapter:   pointer to the adapter
+ * @trigger: trigger reason for request
+ *
+ * Central function to disable the supported offloads
+ *
+ * Return: nothing
+ */
+void hdd_disable_host_offloads(struct hdd_adapter *adapter,
+			       enum pmo_offload_trigger trigger);
+
+/**
+ * hdd_enable_mc_addr_filtering() - enable MC address list in FW
+ * @adapter: adapter whose MC list is being set
+ * @trigger: trigger reason for request
+ *
+ * Return: nothing
+ */
+void hdd_enable_mc_addr_filtering(struct hdd_adapter *adapter,
+				  enum pmo_offload_trigger trigger);
+
+/**
+ * hdd_disable_mc_addr_filtering() - disable MC address list in FW
+ * @adapter: adapter whose MC list is being set
+ * @trigger: trigger reason for request
+ *
+ * Return: nothing
+ */
+void hdd_disable_mc_addr_filtering(struct hdd_adapter *adapter,
+				   enum pmo_offload_trigger trigger);
+
+/**
+ * hdd_cache_mc_addr_list() - API to cache MC address list
+ * @mc_list_config: set of mc address list configurations
+ *
+ * Return: 0 on success else error code
+ */
+int hdd_cache_mc_addr_list(struct pmo_mc_addr_list_params *mc_list_config);
+
+/**
+ * hdd_disable_and_flush_mc_addr_list() - API to Disable & Flush cached MC list
+ * @adapter: adapter whose MC list is being set
+ * @trigger: trigger reason for request
+ *
+ * Return: nothing
+ */
+void hdd_disable_and_flush_mc_addr_list(struct hdd_adapter *adapter,
+					enum pmo_offload_trigger trigger);
+
+/**
+ * wlan_hdd_cfg80211_update_replay_counter_cb() - replay counter callback
+ * @cb_ctx: Callback context as void* as PMO do not about HDD adapter type
+ * @gtk_rsp_param: Pointer to gtk offload response parameter
+ *
+ * Callback routine called upon receiving of gtk offload rsp from fwr
+ *
+ * Return: none
+ */
+void wlan_hdd_cfg80211_update_replay_counter_cb(
+	void *cb_ctx,
+	struct pmo_gtk_rsp_params *gtk_rsp_param);
+
+/**
+ * wlan_hdd_cfg80211_suspend_wlan() - cfg80211 suspend callback
+ * @wiphy: Pointer to wiphy
+ * @wow: Pointer to wow
+ *
+ * This API is called when cfg80211 driver suspends
+ *
+ * Return: integer status
+ */
+int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
+				   struct cfg80211_wowlan *wow);
+
+/**
+ * wlan_hdd_cfg80211_resume_wlan() - cfg80211 resume callback
+ * @wiphy: Pointer to wiphy
+ *
+ * This API is called when cfg80211 driver resumes driver updates
+ * latest sched_scan scan result(if any) to cfg80211 database
+ *
+ * Return: integer status
+ */
+int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy);
+
+/**
+ * hdd_ipv4_notifier_work_queue() - IP V4 change notifier work handler
+ * @work: Pointer to work context
+ *
+ * Return: none
+ */
+void hdd_ipv4_notifier_work_queue(struct work_struct *work);
+
+#ifdef WLAN_NS_OFFLOAD
+/**
+ * hdd_enable_ns_offload() - enable NS offload
+ * @adapter:   pointer to the adapter
+ *
+ * Return: nothing
+ */
+void hdd_enable_ns_offload(struct hdd_adapter *adapter,
+			   enum pmo_offload_trigger trigger);
+
+/**
+ * hdd_disable_ns_offload() - disable NS offload
+ * @adapter:   pointer to the adapter
+ *
+ * Return: nothing
+ */
+void hdd_disable_ns_offload(struct hdd_adapter *adapter,
+	enum pmo_offload_trigger trigger);
+#else /* WLAN_NS_OFFLOAD */
+static inline
+void hdd_enable_ns_offload(struct hdd_adapter *adapter,
+			   enum pmo_offload_trigger trigger)
+{
+}
+
+static inline
+void hdd_disable_ns_offload(struct hdd_adapter *adapter,
+			    enum pmo_offload_trigger trigger)
+{
+}
+#endif /* WLAN_NS_OFFLOAD */
+
+/**
+ * hdd_ipv6_notifier_work_queue() - IP V6 change notifier work handler
+ * @work: Pointer to work context
+ *
+ * Return: none
+ */
+void hdd_ipv6_notifier_work_queue(struct work_struct *work);
+
+/**
+ * wlan_hdd_cfg80211_get_txpower() - cfg80211 get power handler function
+ * @wiphy: Pointer to wiphy structure.
+ * @wdev: Pointer to wireless_dev structure.
+ * @dbm: dbm
+ *
+ * This is the cfg80211 get txpower handler function which invokes
+ * the internal function @__wlan_hdd_cfg80211_get_txpower with
+ * SSR protection.
+ *
+ * Return: 0 for success, error number on failure.
+ */
+int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  int *dbm);
+
+/**
+ * wlan_hdd_cfg80211_set_txpower() - set TX power
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to network device
+ * @type: TX power setting type
+ * @dbm: TX power in dbm
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  enum nl80211_tx_power_setting type,
+				  int dbm);
+
+/**
+ * wlan_hdd_cfg80211_set_power_mgmt() - set cfg80211 power management config
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @allow_power_save: is wlan allowed to go into power save mode
+ * @timeout: Timeout value
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+				     struct net_device *dev,
+				     bool allow_power_save,
+				     int timeout);
+
+/**
+ * wlan_hdd_ipv4_changed() - IPv4 change notifier callback
+ * @nb: pointer to notifier block
+ * @data: data
+ * @arg: arg
+ *
+ * This is the IPv4 notifier callback function gets invoked
+ * if any change in IP and then invoke the function @__wlan_hdd_ipv4_changed
+ * to reconfigure the offload parameters.
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+int wlan_hdd_ipv4_changed(struct notifier_block *nb,
+			  unsigned long data, void *arg);
+
+/**
+ * wlan_hdd_ipv6_changed() - IPv6 change notifier callback
+ * @nb: pointer to notifier block
+ * @data: data
+ * @arg: arg
+ *
+ * This is the IPv6 notifier callback function gets invoked
+ * if any change in IP and then invoke the function @__wlan_hdd_ipv6_changed
+ * to reconfigure the offload parameters.
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+int wlan_hdd_ipv6_changed(struct notifier_block *nb,
+			  unsigned long data, void *arg);
+
+/**
+ * hdd_set_qpower_config() - set qpower config to firmware
+ * @hddctx: HDD context
+ * @adapter: HDD adapter
+ * @qpower: new qpower config value
+ *
+ * Return: 0 on success; Errno on failure
+ */
+int hdd_set_qpower_config(struct hdd_context *hddctx,
+			  struct hdd_adapter *adapter,
+			  uint8_t qpower);
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * hdd_wlan_suspend_resume_event()- send suspend/resume state
+ * @state: suspend/resume state
+ *
+ * This Function sends suspend resume state diag event
+ *
+ * Return: void.
+ */
+void hdd_wlan_suspend_resume_event(uint8_t state);
+
+#else
+static inline
+void hdd_wlan_suspend_resume_event(uint8_t state) {}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+/**
+ * wlan_hdd_set_powersave() - Set powersave mode
+ * @adapter: adapter upon which the request was received
+ * @allow_power_save: is wlan allowed to go into power save mode
+ * @timeout: timeout period in ms
+ *
+ * Return: 0 on success, non-zero on any error
+ */
+int wlan_hdd_set_powersave(struct hdd_adapter *adapter,
+			   bool allow_power_save, uint32_t timeout);
+
+/**
+ * wlan_hdd_inc_suspend_stats() - Prints, then increments, then prints suspend
+ *	failed statistics.
+ * @hdd_ctx:	The HDD context to operate on
+ * @reason:	The suspend failed reason to increment
+ *
+ * This function prints all of the suspend failed statistics, increments the
+ * specified suspend fail reason statistic, and prints the them all again. This
+ * is for easily keeping track of the most common reasons suspend fails.
+ *
+ * Return: none
+ */
+void wlan_hdd_inc_suspend_stats(struct hdd_context *hdd_ctx,
+				enum suspend_fail_reason reason);
+
+/*
+ * Unit-test suspend/resume is a testing feature that allows putting firmware
+ * into WoW suspend irrespective of Apps suspend status. It emulates the chain
+ * of events that occur durring normal system-level suspend/resume, such as
+ * initiating all of the suspend/resume stages in the correct order, and
+ * enabling/disabling appropriate copy engine irqs.
+ */
+#ifdef WLAN_SUSPEND_RESUME_TEST
+/**
+ * wlan_hdd_unit_test_bus_suspend() - suspend the wlan bus
+ * @wow_params: collection of wow enable override parameters
+ *
+ * This function does the same as wlan_hdd_bus_suspend, but additionally passes
+ * the appropriate flags to FW, indicating this is a unit-test suspend and it
+ * should use an HTC wakeup method to resume.
+ *
+ * Return: 0 for success or error code
+ */
+int wlan_hdd_unit_test_bus_suspend(struct wow_enable_params wow_params);
+
+/**
+ * hdd_wlan_fake_apps_resume() - Resume from unit-test triggered suspend
+ * @wiphy: the kernel wiphy struct for the device being resumed
+ * @dev: the kernel net_device struct for the device being resumed
+ *
+ * Return: Zero on success, calls QDF_BUG() on failure
+ */
+int hdd_wlan_fake_apps_resume(struct wiphy *wiphy, struct net_device *dev);
+
+/**
+ * hdd_wlan_fake_apps_suspend() - Initiate a unit-test triggered suspend
+ * @wiphy: the kernel wiphy struct for the device being suspended
+ * @dev: the kernel net_device struct for the device being suspended
+ * @pause_setting: interface pause override setting
+ * @resume_setting: resume trigger override setting
+ *
+ * Return: Zero on success, suspend related non-zero error code on failure
+ */
+int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev,
+			       enum wow_interface_pause pause_setting,
+			       enum wow_resume_trigger resume_setting);
+#else
+static inline int
+hdd_wlan_fake_apps_resume(struct wiphy *wiphy, struct net_device *dev)
+{
+	return 0;
+}
+
+static inline int
+hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev,
+			   enum wow_interface_pause pause_setting,
+			   enum wow_resume_trigger resume_setting)
+{
+	return 0;
+}
+#endif /* WLAN_SUSPEND_RESUME_TEST */
+
+#ifdef QCA_CONFIG_SMP
+/**
+ * wlan_hdd_rx_thread_resume() - Resume RX thread
+ * @hdd_ctx: HDD context
+ *
+ * Check if RX thread suspended, and resume if yes.
+ *
+ * Return: None
+ */
+void wlan_hdd_rx_thread_resume(struct hdd_context *hdd_ctx);
+
+/**
+ * wlan_hdd_rx_thread_suspend() - Suspend RX thread
+ * @hdd_ctx: HDD context
+ *
+ * To suspend RX thread
+ *
+ * Return: 0 for success
+ */
+int wlan_hdd_rx_thread_suspend(struct hdd_context *hdd_ctx);
+
+#else
+static inline void wlan_hdd_rx_thread_resume(struct hdd_context *hdd_ctx) {}
+static inline int wlan_hdd_rx_thread_suspend(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+#endif
+
+#endif /* __WLAN_HDD_POWER_H */
diff --git a/core/hdd/inc/wlan_hdd_regulatory.h b/core/hdd/inc/wlan_hdd_regulatory.h
new file mode 100644
index 0000000..87493f5
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_regulatory.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+#if !defined __HDD_REGULATORY_H
+#define __HDD_REGULATORY_H
+
+/**
+ * DOC: wlan_hdd_regulatory.h
+ *
+ * HDD Regulatory prototype implementation
+ */
+
+struct hdd_context;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(WITH_BACKPORTS)
+#define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR
+#define IEEE80211_CHAN_NO_IBSS IEEE80211_CHAN_NO_IR
+#endif
+
+int hdd_regulatory_init(struct hdd_context *hdd_ctx, struct wiphy *wiphy);
+void hdd_program_country_code(struct hdd_context *hdd_ctx);
+void hdd_reset_global_reg_params(void);
+
+/**
+ * hdd_send_wiphy_regd_sync_event() - sends the regulatory sync event
+ * @hdd_ctx: HDD context
+ *
+ * Return: None
+ */
+void hdd_send_wiphy_regd_sync_event(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_reg_set_country() - helper function for setting the regulatory country
+ * @hdd_ctx: the HDD context to set the country for
+ * @country_code: the two character country code to configure
+ *
+ * Return: zero for success, non-zero error code for failure
+ */
+int hdd_reg_set_country(struct hdd_context *hdd_ctx, char *country_code);
+
+/**
+ * hdd_reg_set_band() - helper function for setting the regulatory band
+ * @hdd_ctx: the HDD context to set the band for
+ * @ui_band: the UI band to configure
+ *
+ * Return: zero for success, non-zero error code for failure
+ */
+int hdd_reg_set_band(struct net_device *dev, u8 ui_band);
+
+/**
+ * hdd_update_indoor_channel() - enable/disable indoor channel
+ * @hdd_ctx: hdd context
+ * @disable: whether to enable / disable indoor channel
+ *
+ * enable/disable indoor channel in wiphy/cds
+ *
+ * Return: void
+ */
+void hdd_update_indoor_channel(struct  hdd_context *hdd_ctx,
+					bool disable);
+/**
+ * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
+ * @wiphy_chan: wiphy channel number
+ * @cds_chan: cds channel structure
+ * @chan_enum: channel enum maintain in reg db
+ * @chan_num: channel index
+ * @disable: Disable/enable the flags
+ *
+ * Modify wiphy flags and cds state if channel is indoor.
+ *
+ * Return: void
+ */
+void hdd_modify_indoor_channel_state_flags(
+	struct hdd_context *hdd_ctx,
+	struct ieee80211_channel *wiphy_chan,
+	struct regulatory_channel *cds_chan,
+	enum channel_enum chan_enum, int chan_num, bool disable);
+
+#endif
diff --git a/core/hdd/inc/wlan_hdd_softap_tx_rx.h b/core/hdd/inc/wlan_hdd_softap_tx_rx.h
new file mode 100644
index 0000000..fa968bd
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_softap_tx_rx.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#if !defined(WLAN_HDD_SOFTAP_TX_RX_H)
+#define WLAN_HDD_SOFTAP_TX_RX_H
+
+/**
+ * DOC: wlan_hdd_softap_tx_rx.h
+ *
+ * Linux HDD SOFTAP Tx/Rx APIs
+ */
+
+#include <wlan_hdd_hostapd.h>
+#include <cdp_txrx_peer_ops.h>
+
+/**
+ * hdd_softap_hard_start_xmit() - Transmit a frame
+ * @skb: pointer to OS packet
+ * @dev: pointer to net_device structure
+ *
+ * Function registered as a net_device .ndo_start_xmit() method for
+ * master mode interfaces (SoftAP/P2P GO), called by the OS if any
+ * packet needs to be transmitted.
+ *
+ * Return: Status of the transmission
+ */
+netdev_tx_t hdd_softap_hard_start_xmit(struct sk_buff *skb,
+				       struct net_device *dev);
+
+/**
+ * hdd_softap_tx_timeout() - TX timeout handler
+ * @dev: pointer to network device
+ *
+ * Function registered as a net_device .ndo_tx_timeout() method for
+ * master mode interfaces (SoftAP/P2P GO), called by the OS if the
+ * driver takes too long to transmit a frame.
+ *
+ * Return: None
+ */
+void hdd_softap_tx_timeout(struct net_device *dev);
+
+/**
+ * hdd_softap_init_tx_rx() - Initialize Tx/Rx module
+ * @adapter: pointer to adapter context
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS hdd_softap_init_tx_rx(struct hdd_adapter *adapter);
+
+/**
+ * hdd_softap_deinit_tx_rx() - Deinitialize Tx/Rx module
+ * @adapter: pointer to adapter context
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS hdd_softap_deinit_tx_rx(struct hdd_adapter *adapter);
+
+/**
+ * hdd_softap_init_tx_rx_sta() - Initialize Tx/Rx for a softap station
+ * @adapter: pointer to adapter context
+ * @sta_id: Station ID to initialize
+ * @sta_mac: pointer to the MAC address of the station
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS hdd_softap_init_tx_rx_sta(struct hdd_adapter *adapter,
+				     uint8_t sta_id,
+				     struct qdf_mac_addr *sta_mac);
+
+/**
+ * hdd_softap_deinit_tx_rx_sta() - Deinitialize Tx/Rx for a softap station
+ * @adapter: pointer to adapter context
+ * @sta_id: Station ID to deinitialize
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS hdd_softap_deinit_tx_rx_sta(struct hdd_adapter *adapter,
+				       uint8_t sta_id);
+
+/**
+ * hdd_softap_rx_packet_cbk() - Receive packet handler
+ * @adapter_context: pointer to HDD adapter
+ * @rx_buf: pointer to rx qdf_nbuf chain
+ *
+ * Receive callback registered with the Data Path.  The Data Path will
+ * call this to notify the HDD when one or more packets were received
+ * for a registered STA.
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf);
+
+/**
+ * hdd_softap_deregister_sta() - Deregister a STA with the Data Path
+ * @adapter: pointer to adapter context
+ * @sta_id: Station ID to deregister
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS hdd_softap_deregister_sta(struct hdd_adapter *adapter,
+				     uint8_t sta_id);
+
+/**
+ * hdd_softap_register_sta() - Register a SoftAP STA
+ * @adapter: pointer to adapter context
+ * @auth_required: is additional authentication required?
+ * @privacy_required: should 802.11 privacy bit be set?
+ * @sta_id: station ID assigned to this station
+ * @sta_mac: station MAC address
+ * @wmm_enabled: is WMM enabled for this STA?
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter,
+				   bool auth_required,
+				   bool privacy_required,
+				   uint8_t sta_id,
+				   struct qdf_mac_addr *sta_mac,
+				   bool wmm_enabled);
+
+/**
+ * hdd_softap_register_bc_sta() - Register the SoftAP broadcast STA
+ * @adapter: pointer to adapter context
+ * @privacy_required: should 802.11 privacy bit be set?
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS hdd_softap_register_bc_sta(struct hdd_adapter *adapter,
+				      bool privacy_required);
+
+/**
+ * hdd_softap_stop_bss() - Stop the BSS
+ * @adapter: pointer to adapter context
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS hdd_softap_stop_bss(struct hdd_adapter *adapter);
+
+/**
+ * hdd_softap_change_sta_state() - Change the state of a SoftAP station
+ * @adapter: pointer to adapter context
+ * @sta_mac: MAC address of the station
+ * @state: new state of the station
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS hdd_softap_change_sta_state(struct hdd_adapter *adapter,
+				       struct qdf_mac_addr *sta_mac,
+				       enum ol_txrx_peer_state state);
+
+/**
+ * hdd_softap_get_sta_id() - Find station ID from MAC address
+ * @adapter: pointer to adapter context
+ * @sta_mac: MAC address of the destination
+ * @sta_id: Station ID associated with the MAC address
+ *
+ * Return: QDF_STATUS_SUCCESS if a match was found, in which case
+ *	   @sta_id is populated, QDF_STATUS_E_FAILURE if a match is
+ *	   not found
+ */
+QDF_STATUS hdd_softap_get_sta_id(struct hdd_adapter *adapter,
+				 struct qdf_mac_addr *sta_mac,
+				 uint8_t *sta_id);
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+/**
+ * hdd_softap_tx_resume_timer_expired_handler() - TX Q resume timer handler
+ * @adapter_context: pointer to vdev adapter
+ *
+ * TX Q resume timer handler for SAP and P2P GO interface.  If Blocked
+ * OS Q is not resumed during timeout period, to prevent permanent
+ * stall, resume OS Q forcefully for SAP and P2P GO interface.
+ *
+ * Return: None
+ */
+void hdd_softap_tx_resume_timer_expired_handler(void *adapter_context);
+
+/**
+ * hdd_softap_tx_resume_cb() - Resume OS TX Q.
+ * @adapter_context: pointer to vdev apdapter
+ * @tx_resume: TX Q resume trigger
+ *
+ * Q was stopped due to WLAN TX path low resource condition
+ *
+ * Return: None
+ */
+void hdd_softap_tx_resume_cb(void *adapter_context, bool tx_resume);
+#else
+static inline
+void hdd_softap_tx_resume_timer_expired_handler(void *adapter_context)
+{
+}
+
+static inline
+void hdd_softap_tx_resume_cb(void *adapter_context, bool tx_resume)
+{
+}
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+
+/**
+ * hdd_post_dhcp_ind() - Send DHCP START/STOP indication to FW
+ * @adapter: pointer to hdd adapter
+ * @sta_id: peer station ID
+ * @type: WMA message type
+ *
+ * Return: error number
+ */
+int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
+		      uint8_t sta_id, uint16_t type);
+
+/**
+ * hdd_inspect_dhcp_packet() -  Inspect DHCP packet
+ * @adapter: pointer to hdd adapter
+ * @sta_id: peer station ID
+ * @skb: pointer to OS packet (sk_buff)
+ * @dir: direction
+ *
+ * Return: error number
+ */
+int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
+			    uint8_t sta_id,
+			    struct sk_buff *skb,
+			    enum qdf_proto_dir dir);
+
+#endif /* end #if !defined(WLAN_HDD_SOFTAP_TX_RX_H) */
diff --git a/core/hdd/inc/wlan_hdd_spectralscan.h b/core/hdd/inc/wlan_hdd_spectralscan.h
new file mode 100644
index 0000000..be1b55f
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_spectralscan.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2017-2018 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 : wlan_hdd_spectralscan.h
+ *
+ * WLAN Host Device Driver spectral scan implementation
+ *
+ */
+
+#if !defined(WLAN_HDD_SPECTRALSCAN_H)
+#define WLAN_HDD_SPECTRALSCAN_H
+
+#ifdef WLAN_CONV_SPECTRAL_ENABLE
+/*
+ * enum spectral_scan_msg_type - spectral scan registration
+ * @SPECTRAL_SCAN_REGISTER_REQ: spectral scan app register request
+ * @SPECTRAL_SCAN_REGISTER_RSP: spectral scan app register response
+ */
+enum spectral_scan_msg_type {
+	SPECTRAL_SCAN_REGISTER_REQ,
+	SPECTRAL_SCAN_REGISTER_RSP,
+};
+
+/*
+ * struct spectral_scan_msg - spectral scan request message
+ * @msg_type: message type
+ * @pid: process id
+ */
+struct spectral_scan_msg {
+	uint32_t msg_type;
+	uint32_t pid;
+};
+
+#define FEATURE_SPECTRAL_SCAN_VENDOR_COMMANDS \
+{ \
+	.info.vendor_id = QCA_NL80211_VENDOR_ID, \
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START, \
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
+			WIPHY_VENDOR_CMD_NEED_NETDEV, \
+	.doit = wlan_hdd_cfg80211_spectral_scan_start \
+}, \
+{ \
+	.info.vendor_id = QCA_NL80211_VENDOR_ID, \
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_STOP, \
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
+		WIPHY_VENDOR_CMD_NEED_NETDEV, \
+	.doit = wlan_hdd_cfg80211_spectral_scan_stop \
+}, \
+{ \
+	.info.vendor_id = QCA_NL80211_VENDOR_ID, \
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CONFIG, \
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
+			WIPHY_VENDOR_CMD_NEED_NETDEV, \
+	.doit = wlan_hdd_cfg80211_spectral_scam_get_config \
+}, \
+{ \
+	.info.vendor_id = QCA_NL80211_VENDOR_ID, \
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_DIAG_STATS, \
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
+		WIPHY_VENDOR_CMD_NEED_NETDEV, \
+	.doit = wlan_hdd_cfg80211_spectral_scan_get_diag_stats \
+}, \
+{ \
+	.info.vendor_id = QCA_NL80211_VENDOR_ID, \
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO, \
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
+			WIPHY_VENDOR_CMD_NEED_NETDEV, \
+	.doit = wlan_hdd_cfg80211_spectral_scan_get_cap_info \
+}, \
+{ \
+	.info.vendor_id = QCA_NL80211_VENDOR_ID, \
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_STATUS, \
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
+		WIPHY_VENDOR_CMD_NEED_NETDEV, \
+	.doit = wlan_hdd_cfg80211_spectral_scan_get_status \
+},
+
+/**
+ * wlan_hdd_cfg80211_spectral_scan_start() - start spectral scan
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function starts spectral scan
+ *
+ * Return: 0 on success and errno on failure
+ */
+int wlan_hdd_cfg80211_spectral_scan_start(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len);
+
+/**
+ * wlan_hdd_cfg80211_spectral_scan_stop() - stop spectral scan
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function stops spectral scan
+ *
+ * Return: 0 on success and errno on failure
+ */
+int wlan_hdd_cfg80211_spectral_scan_stop(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len);
+
+/**
+ * wlan_hdd_cfg80211_spectral_scan_start() - start spectral scan
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function starts spectral scan
+ *
+ * Return: 0 on success and errno on failure
+ */
+int wlan_hdd_cfg80211_spectral_scam_get_config(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len);
+
+/**
+ * wlan_hdd_cfg80211_spectral_scan_start() - start spectral scan
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function starts spectral scan
+ *
+ * Return: 0 on success and errno on failure
+ */
+int wlan_hdd_cfg80211_spectral_scan_get_diag_stats(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len);
+
+/**
+ * wlan_hdd_cfg80211_spectral_scan_start() - start spectral scan
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function starts spectral scan
+ *
+ * Return: 0 on success and errno on failure
+ */
+int wlan_hdd_cfg80211_spectral_scan_get_cap_info(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len);
+
+/**
+ * wlan_hdd_cfg80211_spectral_scan_start() - start spectral scan
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function starts spectral scan
+ *
+ * Return: 0 on success and errno on failure
+ */
+int wlan_hdd_cfg80211_spectral_scan_get_status(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len);
+#else
+#define FEATURE_SPECTRAL_SCAN_VENDOR_COMMANDS
+#endif
+
+#if defined(CNSS_GENL) && defined(WLAN_CONV_SPECTRAL_ENABLE)
+/**
+ * spectral_scan_activate_service() - Activate spectral scan  message handler
+ *
+ * This function registers a handler to receive netlink message from
+ * the spectral scan application process.
+ *
+ * Return: None
+ */
+void spectral_scan_activate_service(void);
+
+/**
+ * spectral_scan_deactivate_service() - Deactivate spectral scan message handler
+ *
+ * This function deregisters a handler to receive netlink message from
+ * the spectral scan application process.
+ *
+ * Return: None
+ */
+void spectral_scan_deactivate_service(void);
+#else
+static inline void spectral_scan_activate_service(void)
+{
+}
+
+static inline void spectral_scan_deactivate_service(void)
+{
+}
+#endif
+#endif
diff --git a/core/hdd/inc/wlan_hdd_sysfs.h b/core/hdd/inc/wlan_hdd_sysfs.h
new file mode 100644
index 0000000..fead7ab
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_sysfs.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#ifndef _WLAN_HDD_SYSFS_H_
+#define _WLAN_HDD_SYSFS_H_
+
+#ifdef WLAN_SYSFS
+/**
+ * hdd_sysfs_create_driver_root_obj() - create driver root kobject
+ *
+ * Return: none
+ */
+void hdd_sysfs_create_driver_root_obj(void);
+
+/**
+ * hdd_sysfs_destroy_driver_root_obj() - destroy driver root kobject
+ *
+ * Return: none
+ */
+void hdd_sysfs_destroy_driver_root_obj(void);
+
+/**
+ * hdd_sysfs_create_version_interface() - create version interface
+ * @psoc: PSOC ptr
+ *
+ * Return: none
+ */
+void hdd_sysfs_create_version_interface(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * hdd_sysfs_destroy_version_interface() - destroy version interface
+ *
+ * Return: none
+ */
+void hdd_sysfs_destroy_version_interface(void);
+/**
+ * hdd_sysfs_create_powerstats_interface() - create power_stats interface
+ *
+ * Return: none
+ */
+void hdd_sysfs_create_powerstats_interface(void);
+/**
+ * hdd_sysfs_destroy_powerstats_interface() - destroy power_stats interface
+ *
+ * Return: none
+ */
+void hdd_sysfs_destroy_powerstats_interface(void);
+#else
+static inline
+void hdd_sysfs_create_driver_root_obj(void)
+{
+}
+
+static inline
+void hdd_sysfs_destroy_driver_root_obj(void)
+{
+}
+
+static inline
+void hdd_sysfs_create_version_interface(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline
+void hdd_sysfs_destroy_version_interface(void)
+{
+}
+
+static inline
+void hdd_sysfs_create_powerstats_interface(void)
+{
+}
+
+static inline
+void hdd_sysfs_destroy_powerstats_interface(void)
+{
+}
+#endif
+#endif
diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h
new file mode 100644
index 0000000..0339213
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_tdls.h
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __HDD_TDLS_H
+#define __HDD_TDLS_H
+/**
+ * DOC: wlan_hdd_tdls.h
+ * WLAN Host Device Driver TDLS include file
+ */
+
+struct hdd_context;
+
+/**
+ * enum tdls_concerned_external_events - External events that affect TDLS
+ * @P2P_ROC_START: P2P remain on channel starts
+ * @P2P_ROC_END: P2P remain on channel ends
+ */
+enum tdls_concerned_external_events {
+	P2P_ROC_START,
+	P2P_ROC_END,
+};
+
+#ifdef FEATURE_WLAN_TDLS
+
+/* Bit mask flag for tdls_option to FW */
+#define ENA_TDLS_OFFCHAN      (1 << 0)  /* TDLS Off Channel support */
+#define ENA_TDLS_BUFFER_STA   (1 << 1)  /* TDLS Buffer STA support */
+#define ENA_TDLS_SLEEP_STA    (1 << 2)  /* TDLS Sleep STA support */
+/**
+ * struct hdd_tdls_config_params - tdls config params
+ *
+ * @tdls: tdls
+ * @tx_period_t: tx period
+ * @tx_packet_n: tx packets number
+ * @discovery_tries_n: discovery tries
+ * @idle_timeout_t: idle traffic time out value
+ * @idle_packet_n: idle packet number
+ * @rssi_trigger_threshold: rssi trigger threshold
+ * @rssi_teardown_threshold: rssi tear down threshold
+ * @rssi_delta: rssi delta
+ */
+struct hdd_tdls_config_params {
+	uint32_t tdls;
+	uint32_t tx_period_t;
+	uint32_t tx_packet_n;
+	uint32_t discovery_tries_n;
+	uint32_t idle_timeout_t;
+	uint32_t idle_packet_n;
+	int32_t rssi_trigger_threshold;
+	int32_t rssi_teardown_threshold;
+	int32_t rssi_delta;
+};
+
+typedef int (*cfg80211_exttdls_callback)(const uint8_t *mac,
+					 uint32_t opclass,
+					 uint32_t channel,
+					 uint32_t state,
+					 int32_t reason, void *ctx);
+
+/**
+ * struct tdlsInfo_t - tdls info
+ *
+ * @vdev_id: vdev id
+ * @tdls_state: tdls state
+ * @notification_interval_ms: notification interval in ms
+ * @tx_discovery_threshold: tx discovery threshold
+ * @tx_teardown_threshold: tx teardown threshold
+ * @rssi_teardown_threshold: rx teardown threshold
+ * @rssi_delta: rssi delta
+ * @tdls_options: tdls options
+ * @peer_traffic_ind_window: peer traffic indication window
+ * @peer_traffic_response_timeout: peer traffic response timeout
+ * @puapsd_mask: puapsd mask
+ * @puapsd_inactivity_time: puapsd inactivity time
+ * @puapsd_rx_frame_threshold: puapsd rx frame threshold
+ * @teardown_notification_ms: tdls teardown notification interval
+ * @tdls_peer_kickout_threshold: tdls packets threshold
+ *    for peer kickout operation
+ */
+typedef struct {
+	uint32_t vdev_id;
+	uint32_t tdls_state;
+	uint32_t notification_interval_ms;
+	uint32_t tx_discovery_threshold;
+	uint32_t tx_teardown_threshold;
+	int32_t rssi_teardown_threshold;
+	int32_t rssi_delta;
+	uint32_t tdls_options;
+	uint32_t peer_traffic_ind_window;
+	uint32_t peer_traffic_response_timeout;
+	uint32_t puapsd_mask;
+	uint32_t puapsd_inactivity_time;
+	uint32_t puapsd_rx_frame_threshold;
+	uint32_t teardown_notification_ms;
+	uint32_t tdls_peer_kickout_threshold;
+} tdlsInfo_t;
+
+int wlan_hdd_tdls_set_params(struct net_device *dev,
+			     struct hdd_tdls_config_params *config);
+
+int wlan_hdd_tdls_get_all_peers(struct hdd_adapter *adapter, char *buf,
+				int buflen);
+
+int wlan_hdd_tdls_extctrl_deconfig_peer(struct hdd_adapter *adapter,
+					const uint8_t *peer);
+int wlan_hdd_tdls_extctrl_config_peer(struct hdd_adapter *adapter,
+				      const uint8_t *peer,
+				      cfg80211_exttdls_callback callback,
+				      uint32_t chan,
+				      uint32_t max_latency,
+				      uint32_t op_class,
+				      uint32_t min_bandwidth);
+
+int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     const void *data,
+				     int data_len);
+
+int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
+				      struct wireless_dev *wdev,
+				      const void *data,
+				      int data_len);
+
+int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 const void *data,
+					 int data_len);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
+				struct net_device *dev,
+				const uint8_t *peer,
+				enum nl80211_tdls_operation oper);
+#else
+int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
+				struct net_device *dev,
+				uint8_t *peer,
+				enum nl80211_tdls_operation oper);
+#endif
+
+#ifdef TDLS_MGMT_VERSION2
+int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+				struct net_device *dev, u8 *peer,
+				u8 action_code, u8 dialog_token,
+				u16 status_code, u32 peer_capability,
+				const u8 *buf, size_t len);
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
+int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+				struct net_device *dev, const uint8_t *peer,
+				uint8_t action_code, uint8_t dialog_token,
+				uint16_t status_code, uint32_t peer_capability,
+				bool initiator, const uint8_t *buf,
+				size_t len);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+				struct net_device *dev, const uint8_t *peer,
+				uint8_t action_code, uint8_t dialog_token,
+				uint16_t status_code, uint32_t peer_capability,
+				const uint8_t *buf, size_t len);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
+int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+				struct net_device *dev, uint8_t *peer,
+				uint8_t action_code, uint8_t dialog_token,
+				uint16_t status_code, uint32_t peer_capability,
+				const uint8_t *buf, size_t len);
+#else
+int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+				struct net_device *dev, uint8_t *peer,
+				uint8_t action_code, uint8_t dialog_token,
+				uint16_t status_code, const uint8_t *buf,
+				size_t len);
+#endif
+#endif
+
+/**
+ * hdd_set_tdls_offchannel() - set tdls off-channel number
+ * @hdd_ctx:     Pointer to the HDD context
+ * @adapter: Pointer to the HDD adapter
+ * @offchannel: tdls off-channel number
+ *
+ * This function sets tdls off-channel number
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+int hdd_set_tdls_offchannel(struct hdd_context *hdd_ctx,
+			    struct hdd_adapter *adapter,
+			    int offchannel);
+
+/**
+ * hdd_set_tdls_secoffchanneloffset() - set secondary tdls off-channel offset
+ * @hdd_ctx:     Pointer to the HDD context
+ * @adapter: Pointer to the HDD adapter
+ * @offchanoffset: tdls off-channel offset
+ *
+ * This function sets secondary tdls off-channel offset
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+int hdd_set_tdls_secoffchanneloffset(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter,
+				     int offchanoffset);
+
+/**
+ * hdd_set_tdls_offchannelmode() - set tdls off-channel mode
+ * @hdd_ctx:     Pointer to the HDD context
+ * @adapter: Pointer to the HDD adapter
+ * @offchanmode: tdls off-channel mode
+ * 1-Enable Channel Switch
+ * 2-Disable Channel Switch
+ *
+ * This function sets tdls off-channel mode
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+int hdd_set_tdls_offchannelmode(struct hdd_context *hdd_ctx,
+				struct hdd_adapter *adapter,
+				int offchanmode);
+int hdd_set_tdls_scan_type(struct hdd_context *hdd_ctx, int val);
+int wlan_hdd_tdls_antenna_switch(struct hdd_context *hdd_ctx,
+				 struct hdd_adapter *adapter,
+				 uint32_t mode);
+
+/**
+ * wlan_hdd_cfg80211_configure_tdls_mode() - configure tdls mode
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Return:   Return the Success or Failure code.
+ */
+int wlan_hdd_cfg80211_configure_tdls_mode(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len);
+
+QDF_STATUS hdd_tdls_register_peer(void *userdata, uint32_t vdev_id,
+				  const uint8_t *mac, uint16_t sta_id,
+				  uint8_t qos);
+
+QDF_STATUS hdd_tdls_deregister_peer(void *userdata, uint32_t vdev_id,
+				    uint8_t sta_id);
+
+#else
+
+static inline int wlan_hdd_tdls_antenna_switch(struct hdd_context *hdd_ctx,
+					       struct hdd_adapter *adapter,
+					       uint32_t mode)
+{
+	return 0;
+}
+
+static inline int wlan_hdd_cfg80211_configure_tdls_mode(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	return 0;
+}
+
+static inline void
+hdd_tdls_notify_p2p_roc(struct hdd_context *hdd_ctx,
+			enum tdls_concerned_external_events event)
+{
+}
+
+static inline
+QDF_STATUS hdd_tdls_register_peer(void *userdata, uint32_t vdev_id,
+				  const uint8_t *mac, uint16_t sta_id,
+				  uint8_t qos);
+{
+}
+
+static inline
+QDF_STATUS hdd_tdls_deregister_peer(void *userdata, uint32_t vdev_id,
+				    uint8_t sta_id)
+{
+}
+#endif /* End of FEATURE_WLAN_TDLS */
+#endif /* __HDD_TDLS_H */
diff --git a/core/hdd/inc/wlan_hdd_trace.h b/core/hdd/inc/wlan_hdd_trace.h
new file mode 100644
index 0000000..41d12a3
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_trace.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#ifndef __WLAN_HDD_TRACE_H__
+#define __WLAN_HDD_TRACE_H__
+
+#include "mac_trace.h"
+
+#define NO_SESSION 0xFF
+
+#undef ENUMS
+#define ENUMS \
+	ENUM(TRACE_CODE_HDD_OPEN_REQUEST) \
+	ENUM(TRACE_CODE_HDD_STOP_REQUEST) \
+	ENUM(TRACE_CODE_HDD_TX_TIMEOUT) \
+	ENUM(TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL) \
+	ENUM(TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL) \
+	ENUM(TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL) \
+	ENUM(TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL) \
+	ENUM(TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL) \
+	ENUM(TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL) \
+	ENUM(TRACE_CODE_HDD_SETROAMDELTA_IOCTL) \
+	ENUM(TRACE_CODE_HDD_GETROAMDELTA_IOCTL) \
+	ENUM(TRACE_CODE_HDD_GETBAND_IOCTL) \
+	ENUM(TRACE_CODE_HDD_GETCOUNTRYREV_IOCTL) \
+	ENUM(TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL) \
+	ENUM(TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL) \
+	ENUM(TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST) \
+	ENUM(TRACE_CODE_HDD_HOSTAPD_STOP_REQUEST) \
+	ENUM(TRACE_CODE_HDD_HOSTAPD_UNINIT_REQUEST) \
+	ENUM(TRACE_CODE_HDD_SOFTAP_TX_TIMEOUT) \
+	ENUM(TRACE_CODE_HDD_HOSTAPD_SET_MAC_ADDR) \
+	ENUM(TRACE_CODE_HDD_HOSTAPD_P2P_SET_NOA_IOCTL) \
+	ENUM(TRACE_CODE_HDD_HOSTAPD_P2P_SET_PS_IOCTL) \
+	ENUM(TRACE_CODE_HDD_HOSTAPD_SET_SAP_CHANNEL_LIST_IOCTL) \
+	ENUM(TRACE_CODE_HDD_ADD_VIRTUAL_INTF) \
+	ENUM(TRACE_CODE_HDD_DEL_VIRTUAL_INTF) \
+	ENUM(TRACE_CODE_HDD_CHANGE_VIRTUAL_INTF) \
+	ENUM(TRACE_CODE_HDD_CFG80211_START_AP) \
+	ENUM(TRACE_CODE_HDD_CFG80211_CHANGE_BEACON) \
+	ENUM(TRACE_CODE_HDD_CFG80211_STOP_AP) \
+	ENUM(TRACE_CODE_HDD_CFG80211_CHANGE_BSS) \
+	ENUM(TRACE_CODE_HDD_CFG80211_ADD_KEY) \
+	ENUM(TRACE_CODE_HDD_CFG80211_GET_KEY) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY) \
+	ENUM(TRACE_CODE_HDD_CFG80211_CONNECT) \
+	ENUM(TRACE_CODE_HDD_CFG80211_DISCONNECT) \
+	ENUM(TRACE_CODE_HDD_CFG80211_JOIN_IBSS) \
+	ENUM(TRACE_CODE_HDD_CFG80211_LEAVE_IBSS) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SET_TXPOWER) \
+	ENUM(TRACE_CODE_HDD_CFG80211_GET_TXPOWER) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SET_CHANNEL) \
+	ENUM(TRACE_CODE_HDD_CFG80211_ADD_BEACON) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SET_BEACON) \
+	ENUM(TRACE_CODE_HDD_CFG80211_CHANGE_IFACE) \
+	ENUM(TRACE_CODE_HDD_CHANGE_STATION) \
+	ENUM(TRACE_CODE_HDD_CFG80211_UPDATE_BSS) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SCAN) \
+	ENUM(TRACE_CODE_HDD_REMAIN_ON_CHANNEL) \
+	ENUM(TRACE_CODE_HDD_REMAINCHANREADYHANDLER) \
+	ENUM(TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL) \
+	ENUM(TRACE_CODE_HDD_ACTION) \
+	ENUM(TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT) \
+	ENUM(TRACE_CODE_HDD_CFG80211_GET_STA) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT) \
+	ENUM(TRACE_CODE_HDD_CFG80211_DEL_STA) \
+	ENUM(TRACE_CODE_HDD_CFG80211_ADD_STA) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SET_PMKSA) \
+	ENUM(TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES) \
+	ENUM(TRACE_CODE_HDD_CFG80211_TDLS_MGMT) \
+	ENUM(TRACE_CODE_HDD_CFG80211_TDLS_OPER) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA) \
+	ENUM(TRACE_CODE_HDD_UNSUPPORTED_IOCTL) \
+	ENUM(TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL) \
+	ENUM(TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL) \
+	ENUM(TRACE_CODE_HDD_STORE_JOIN_REQ) \
+	ENUM(TRACE_CODE_HDD_CLEAR_JOIN_REQ) \
+	ENUM(TRACE_CODE_HDD_ISSUE_JOIN_REQ) \
+	ENUM(TRACE_CODE_HDD_CFG80211_RESUME_WLAN) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SET_MAC_ACL) \
+	ENUM(TRACE_CODE_HDD_CFG80211_TESTMODE) \
+	ENUM(TRACE_CODE_HDD_CFG80211_DUMP_SURVEY) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START) \
+	ENUM(TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP) \
+	ENUM(TRACE_CODE_HDD_CFG80211_DEL_PMKSA) \
+	ENUM(TRACE_CODE_HDD_SEND_MGMT_TX) \
+	/*
+	 * New CFG80211 enums to be added before this comment.
+	 * TRACE_CODE_HDD_RX_SME_MSG is used as code for MTRACE commands.
+	 */ \
+	ENUM(TRACE_CODE_HDD_RX_SME_MSG)
+
+enum {
+#undef ENUM
+#define ENUM(enum) enum,
+	ENUMS
+};
+
+/**
+ * hdd_trace_event_string() - Convert trace event to string
+ * @code: trace event enumeration to convert
+ *
+ * Return: string representation of the input enumeration
+ */
+static inline const char *hdd_trace_event_string(uint32_t code)
+{
+	switch (code) {
+	default:
+		return "UNKNOWN";
+#undef ENUM
+#define ENUM(enum) CASE_RETURN_STRING(enum)
+	ENUMS
+	}
+}
+
+#undef ENUMS
+#undef ENUM
+
+#ifdef HDD_TRACE_RECORD
+void hdd_trace_init(void);
+#else
+static inline void hdd_trace_init(void) {}
+#endif
+
+#endif
diff --git a/core/hdd/inc/wlan_hdd_tsf.h b/core/hdd/inc/wlan_hdd_tsf.h
new file mode 100644
index 0000000..81235ec
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_tsf.h
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+#if !defined WLAN_HDD_TSF_H
+#define WLAN_HDD_TSF_H
+#include "wlan_hdd_cfg.h"
+#include "wlan_hdd_main.h"
+
+/**
+ * enum hdd_tsf_get_state - status of get tsf action
+ * @TSF_RETURN:                   get tsf
+ * @TSF_STA_NOT_CONNECTED_NO_TSF: sta not connected to ap
+ * @TSF_NOT_RETURNED_BY_FW:       fw not returned tsf
+ * @TSF_CURRENT_IN_CAP_STATE:     driver in capture state
+ * @TSF_CAPTURE_FAIL:             capture fail
+ * @TSF_GET_FAIL:                 get fail
+ * @TSF_RESET_GPIO_FAIL:          GPIO reset fail
+ * @TSF_SAP_NOT_STARTED_NO_TSF    SAP not started
+ * @TSF_NOT_READY: TSF module is not initialized or init failed
+ * @TSF_DISABLED_BY_TSFPLUS: cap_tsf/get_tsf are disabled due to TSF_PLUS
+ */
+enum hdd_tsf_get_state {
+	TSF_RETURN = 0,
+	TSF_STA_NOT_CONNECTED_NO_TSF,
+	TSF_NOT_RETURNED_BY_FW,
+	TSF_CURRENT_IN_CAP_STATE,
+	TSF_CAPTURE_FAIL,
+	TSF_GET_FAIL,
+	TSF_RESET_GPIO_FAIL,
+	TSF_SAP_NOT_STARTED_NO_TSF,
+	TSF_NOT_READY,
+	TSF_DISABLED_BY_TSFPLUS
+};
+
+/**
+ * enum hdd_tsf_capture_state - status of capture
+ * @TSF_IDLE:      idle
+ * @TSF_CAP_STATE: current is in capture state
+ */
+enum hdd_tsf_capture_state {
+	TSF_IDLE = 0,
+	TSF_CAP_STATE
+};
+
+#ifdef WLAN_FEATURE_TSF
+/**
+ * wlan_hdd_tsf_init() - set gpio and callbacks for
+ *     capturing tsf and init tsf_plus
+ * @hdd_ctx: pointer to the struct hdd_context
+ *
+ * This function set the callback to sme module, the callback will be
+ * called when a tsf event is reported by firmware; set gpio number
+ * to FW, FW will toggle this gpio when received a CAP_TSF command;
+ * do tsf_plus init
+ *
+ * Return: nothing
+ */
+void wlan_hdd_tsf_init(struct hdd_context *hdd_ctx);
+
+/**
+ * wlan_hdd_tsf_deinit() - reset callbacks for capturing tsf, deinit tsf_plus
+ * @hdd_ctx: pointer to the struct hdd_context
+ *
+ * This function reset the callback to sme module, and deinit tsf_plus
+ *
+ * Return: nothing
+ */
+void wlan_hdd_tsf_deinit(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_capture_tsf() - capture tsf
+ * @adapter: pointer to adapter
+ * @buf: pointer to uplayer buf
+ * @len : the length of buf
+ *
+ * This function returns tsf value to uplayer.
+ *
+ * Return: 0 for success or non-zero negative failure code
+ */
+int hdd_capture_tsf(struct hdd_adapter *adapter, uint32_t *buf, int len);
+
+/**
+ * hdd_indicate_tsf() - return tsf to uplayer
+ *
+ * @adapter: pointer to adapter
+ * @buf: pointer to uplayer buf
+ * @len : the length of buf
+ *
+ * This function returns tsf value to uplayer.
+ *
+ * Return: Describe the execute result of this routine
+ */
+int hdd_indicate_tsf(struct hdd_adapter *adapter, uint32_t *buf, int len);
+
+/**
+ * wlan_hdd_cfg80211_handle_tsf_cmd(): Setup TSF operations
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Handle TSF SET / GET operation from userspace
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len);
+
+int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf);
+
+#else
+static inline void wlan_hdd_tsf_init(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline void wlan_hdd_tsf_deinit(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline int hdd_indicate_tsf(struct hdd_adapter *adapter, uint32_t *buf,
+				int len)
+{
+	return -ENOTSUPP;
+}
+
+static inline int
+hdd_capture_tsf(struct hdd_adapter *adapter, uint32_t *buf, int len)
+{
+	return -ENOTSUPP;
+}
+
+static inline int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	return -ENOTSUPP;
+}
+static inline int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf)
+{
+	return -ENOTSUPP;
+}
+
+#endif
+
+#if defined(WLAN_FEATURE_TSF_PLUS) && defined(WLAN_FEATURE_TSF)
+/**
+ * hdd_tsf_is_ptp_enabled() - check ini configuration
+ * @hdd: pointer to hdd context
+ *
+ * This function checks tsf configuration for ptp
+ *
+ * Return: true on enable, false on disable
+ */
+bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd);
+/**
+ * hdd_tsf_is_tx_set() - check ini configuration
+ * @hdd: pointer to hdd context
+ *
+ * This function checks tsf configuration for ptp on tx
+ *
+ * Return: true on enable, false on disable
+ */
+
+bool hdd_tsf_is_tx_set(struct hdd_context *hdd);
+/**
+ * hdd_tsf_is_rx_set() - check ini configuration
+ * @hdd: pointer to hdd context
+ *
+ * This function checks tsf configuration for ptp on rx
+ *
+ * Return: true on enable, false on disable
+ */
+bool hdd_tsf_is_rx_set(struct hdd_context *hdd);
+/**
+ * hdd_tsf_is_raw_set() - check ini configuration
+ * @hdd: pointer to hdd context
+ *
+ * This function checks tsf configuration for ptp on raw
+ *
+ * Return: true on enable, false on disable
+ */
+bool hdd_tsf_is_raw_set(struct hdd_context *hdd);
+/**
+ * hdd_tsf_is_dbg_fs_set() - check ini configuration
+ * @hdd: pointer to hdd context
+ *
+ * This function checks tsf configuration for ptp on dbg fs
+ *
+ * Return: true on enable, false on disable
+ */
+bool hdd_tsf_is_dbg_fs_set(struct hdd_context *hdd);
+
+/**
+ * hdd_start_tsf_sync() - start tsf sync
+ * @adapter: pointer to adapter
+ *
+ * This function initialize and start TSF synchronization
+ *
+ * Return: Describe the execute result of this routine
+ */
+int hdd_start_tsf_sync(struct hdd_adapter *adapter);
+
+/**
+ * hdd_stop_tsf_sync() - stop tsf sync
+ * @adapter: pointer to adapter
+ *
+ * This function stop and de-initialize TSF synchronization
+ *
+ * Return: Describe the execute result of this routine
+ */
+int hdd_stop_tsf_sync(struct hdd_adapter *adapter);
+
+/**
+ * hdd_tsf_notify_wlan_state_change() -
+ *     notify tsf module of wlan connection state
+ * @old_state: old wlan state
+ * @new_state: new wlan state
+ *
+ * This function check the old and new connection state, determine whether
+ * to start or stop tsf sync
+ *
+ * Return: nothing
+ */
+void hdd_tsf_notify_wlan_state_change(struct hdd_adapter *adapter,
+				      eConnectionState old_state,
+				      eConnectionState new_state);
+
+/**
+ * hdd_tx_timestamp() - time stamp TX netbuf
+ *
+ * @netbuf: pointer to a TX netbuf
+ * @target_time: TX time for the netbuf
+ *
+ * This function  get corresponding host time from target time,
+ * and time stamp the TX netbuf with this time
+ *
+ * Return: Describe the execute result of this routine
+ */
+int hdd_tx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time);
+
+/**
+ * hdd_rx_timestamp() - time stamp RX netbuf
+ *
+ * @netbuf: pointer to a RX netbuf
+ * @target_time: RX time for the netbuf
+ *
+ * This function get corresponding host time from target time,
+ * and time stamp the RX netbuf with this time
+ *
+ * Return: Describe the execute result of this routine
+ */
+int hdd_rx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time);
+/**
+ * hdd_capture_req_timer_expired_handler() - capture req timer handler
+ * @arg: pointer to a adapter
+ *
+ * This function set a timeout handler for TSF capture timer.
+ *
+ * Return: none
+ */
+
+void hdd_capture_req_timer_expired_handler(void *arg);
+
+#else
+static inline int hdd_start_tsf_sync(struct hdd_adapter *adapter)
+{
+	return -ENOTSUPP;
+}
+
+static inline int hdd_stop_tsf_sync(struct hdd_adapter *adapter)
+{
+	return -ENOTSUPP;
+}
+
+static inline
+void hdd_tsf_notify_wlan_state_change(struct hdd_adapter *adapter,
+				      eConnectionState old_state,
+				      eConnectionState new_state)
+
+{
+}
+
+static inline
+int hdd_tx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time)
+{
+	return -ENOTSUPP;
+}
+
+static inline
+int hdd_rx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time)
+{
+	return -ENOTSUPP;
+}
+
+static inline
+void hdd_capture_req_timer_expired_handler(void *arg)
+{
+}
+#endif
+
+#endif
diff --git a/core/hdd/inc/wlan_hdd_twt.h b/core/hdd/inc/wlan_hdd_twt.h
new file mode 100644
index 0000000..81e0435
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_twt.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2018 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 : wlan_hdd_twt.h
+ *
+ * WLAN Host Device Driver file for TWT (Target Wake Time) support.
+ *
+ */
+
+#if !defined(WLAN_HDD_TWT_H)
+#define WLAN_HDD_TWT_H
+
+#include "qdf_types.h"
+#include "qdf_status.h"
+
+struct hdd_context;
+struct wma_tgt_cfg;
+struct wmi_twt_enable_complete_event_param;
+
+#ifdef WLAN_SUPPORT_TWT
+/**
+ * enum twt_status - TWT target state
+ * @TWT_INIT: Init State
+ * @TWT_DISABLED: TWT is disabled
+ * @TWT_FW_TRIGGER_ENABLE_REQUESTED: FW triggered enable requested
+ * @TWT_FW_TRIGGER_ENABLED: FW triggered twt enabled
+ * @TWT_HOST_TRIGGER_ENABLE_REQUESTED: Host triggered TWT requested
+ * @TWT_HOST_TRIGGER_ENABLED: Host triggered TWT enabled
+ * @TWT_DISABLE_REQUESTED: TWT disable requested
+ * @TWT_SUSPEND_REQUESTED: TWT suspend requested
+ * @TWT_SUSPENDED: Successfully suspended TWT
+ * @TWT_RESUME_REQUESTED: TWT Resume requested
+ * @TWT_RESUMED: Successfully resumed TWT
+ * @TWT_CLOSED: Deinitialized TWT feature and closed
+ */
+enum twt_status {
+	TWT_INIT,
+	TWT_DISABLED,
+	TWT_FW_TRIGGER_ENABLE_REQUESTED,
+	TWT_FW_TRIGGER_ENABLED,
+	TWT_HOST_TRIGGER_ENABLE_REQUESTED,
+	TWT_HOST_TRIGGER_ENABLED,
+	TWT_DISABLE_REQUESTED,
+	TWT_SUSPEND_REQUESTED,
+	TWT_SUSPENDED,
+	TWT_RESUME_REQUESTED,
+	TWT_RESUMED,
+	TWT_CLOSED,
+};
+
+/**
+ * hdd_update_tgt_twt_cap() - Update TWT target capabilities
+ * @hdd_ctx: HDD Context
+ * @cfg: Pointer to target configuration
+ *
+ * Return: None
+ */
+void hdd_update_tgt_twt_cap(struct hdd_context *hdd_ctx,
+			    struct wma_tgt_cfg *cfg);
+
+/**
+ * hdd_send_twt_enable_cmd() - Send TWT enable command to target
+ * @hdd_ctx: HDD Context
+ *
+ * Return: None
+ */
+void hdd_send_twt_enable_cmd(struct hdd_context *hdd_ctx);
+
+/**
+ * wlan_hdd_twt_init() - Initialize TWT
+ * @hdd_ctx: pointer to global HDD Context
+ *
+ * Initialize the TWT feature by registering the callbacks
+ * with the lower layers.
+ *
+ * Return: None
+ */
+void wlan_hdd_twt_init(struct hdd_context *hdd_ctx);
+
+/**
+ * wlan_hdd_twt_deinit() - Deinitialize TWT
+ * @hdd_ctx: pointer to global HDD Context
+ *
+ * Deinitialize the TWT feature by deregistering the
+ * callbacks with the lower layers.
+ *
+ * Return: None
+ */
+void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx);
+
+#else
+static inline void hdd_update_tgt_twt_cap(struct hdd_context *hdd_ctx,
+					  struct wma_tgt_cfg *cfg)
+{
+}
+
+static inline void hdd_send_twt_enable_cmd(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline void wlan_hdd_twt_init(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx)
+{
+}
+
+#endif
+#endif /* if !defined(WLAN_HDD_TWT_H)*/
diff --git a/core/hdd/inc/wlan_hdd_tx_rx.h b/core/hdd/inc/wlan_hdd_tx_rx.h
new file mode 100644
index 0000000..938d89f
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_tx_rx.h
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#if !defined(WLAN_HDD_TX_RX_H)
+#define WLAN_HDD_TX_RX_H
+
+/**
+ *
+ * DOC: wlan_hdd_tx_rx.h
+ *
+ * Linux HDD Tx/RX APIs
+ */
+
+#include <wlan_hdd_includes.h>
+#include <cds_api.h>
+#include <linux/skbuff.h>
+#include "cdp_txrx_flow_ctrl_legacy.h"
+
+struct hdd_context;
+
+#define hdd_dp_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_HDD_DATA, params)
+#define hdd_dp_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_HDD_DATA, params)
+#define hdd_dp_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_HDD_DATA, params)
+#define hdd_dp_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_HDD_DATA, params)
+#define hdd_dp_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_HDD_DATA, params)
+
+#define hdd_dp_alert_rl(params...) \
+			QDF_TRACE_FATAL_RL(QDF_MODULE_ID_HDD_DATA, params)
+#define hdd_dp_err_rl(params...) \
+			QDF_TRACE_ERROR_RL(QDF_MODULE_ID_HDD_DATA, params)
+#define hdd_dp_warn_rl(params...) \
+			QDF_TRACE_WARN_RL(QDF_MODULE_ID_HDD_DATA, params)
+#define hdd_dp_info_rl(params...) \
+			QDF_TRACE_INFO_RL(QDF_MODULE_ID_HDD_DATA, params)
+#define hdd_dp_debug_rl(params...) \
+			QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_HDD_DATA, params)
+
+#define hdd_dp_enter() hdd_dp_debug("enter")
+#define hdd_dp_enter_dev(dev) hdd_dp_debug("enter(%s)", (dev)->name)
+#define hdd_dp_exit() hdd_dp_debug("exit")
+
+#define HDD_ETHERTYPE_802_1_X              0x888E
+#define HDD_ETHERTYPE_802_1_X_FRAME_OFFSET 12
+#ifdef FEATURE_WLAN_WAPI
+#define HDD_ETHERTYPE_WAI                  0x88b4
+#define IS_HDD_ETHERTYPE_WAI(_skb) (ntohs(_skb->protocol) == \
+					HDD_ETHERTYPE_WAI)
+#else
+#define IS_HDD_ETHERTYPE_WAI(_skb) (false)
+#endif
+
+#define HDD_PSB_CFG_INVALID                   0xFF
+#define HDD_PSB_CHANGED                       0xFF
+#define SME_QOS_UAPSD_CFG_BK_CHANGED_MASK     0xF1
+#define SME_QOS_UAPSD_CFG_BE_CHANGED_MASK     0xF2
+#define SME_QOS_UAPSD_CFG_VI_CHANGED_MASK     0xF4
+#define SME_QOS_UAPSD_CFG_VO_CHANGED_MASK     0xF8
+
+netdev_tx_t hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
+void hdd_tx_timeout(struct net_device *dev);
+
+QDF_STATUS hdd_init_tx_rx(struct hdd_adapter *adapter);
+QDF_STATUS hdd_deinit_tx_rx(struct hdd_adapter *adapter);
+
+/**
+ * hdd_rx_packet_cbk() - Receive packet handler
+ * @adapter_context: pointer to HDD adapter context
+ * @rxBuf: pointer to rx qdf_nbuf
+ *
+ * Receive callback registered with data path.  DP will call this to notify
+ * the HDD when one or more packets were received for a registered
+ * STA.
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS hdd_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rxBuf);
+
+/**
+ * hdd_rx_pkt_thread_enqueue_cbk() - receive pkt handler to enqueue into thread
+ * @adapter: pointer to HDD adapter
+ * @rxBuf: pointer to rx qdf_nbuf
+ *
+ * Receive callback registered with DP layer which enqueues packets into dp rx
+ * thread
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS hdd_rx_pkt_thread_enqueue_cbk(void *adapter_context,
+					 qdf_nbuf_t nbuf_list);
+
+/**
+ * hdd_rx_ol_init() - Initialize Rx mode(LRO or GRO) method
+ * @hdd_ctx: pointer to HDD Station Context
+ *
+ * Return: 0 on success and non zero on failure.
+ */
+int hdd_rx_ol_init(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_disable_rx_ol_in_concurrency() - Disable Rx offload due to concurrency
+ * @disable: true/false to disable/enable the Rx offload
+ *
+ * Return: none
+ */
+void hdd_disable_rx_ol_in_concurrency(bool disable);
+
+/**
+ * hdd_disable_rx_ol_for_low_tput() - Disable Rx offload in low TPUT scenario
+ * @hdd_ctx: hdd context
+ * @disable: true/false to disable/enable the Rx offload
+ *
+ * Return: none
+ */
+void hdd_disable_rx_ol_for_low_tput(struct hdd_context *hdd_ctx, bool disable);
+
+QDF_STATUS hdd_get_peer_sta_id(struct hdd_station_ctx *sta_ctx,
+				struct qdf_mac_addr *peer_mac_addr,
+				uint8_t *sta_id);
+/**
+ * hdd_reset_all_adapters_connectivity_stats() - reset connectivity stats
+ * @hdd_ctx: pointer to HDD Station Context
+ *
+ * Return: None
+ */
+void hdd_reset_all_adapters_connectivity_stats(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_tx_rx_collect_connectivity_stats_info() - collect connectivity stats
+ * @skb: pointer to skb data
+ * @adapter: pointer to vdev apdapter
+ * @action: action done on pkt.
+ * @pkt_type: data pkt type
+ *
+ * Return: None
+ */
+void hdd_tx_rx_collect_connectivity_stats_info(struct sk_buff *skb,
+		void *adapter, enum connectivity_stats_pkt_status action,
+		uint8_t *pkt_type);
+
+/**
+ * hdd_tx_queue_cb() - Disable/Enable the Transmit Queues
+ * @hdd_handle: HDD handle
+ * @vdev_id: vdev id
+ * @action: Action to be taken on the Tx Queues
+ * @reason: Reason for the netif action
+ *
+ * Return: None
+ */
+void hdd_tx_queue_cb(hdd_handle_t hdd_handle, uint32_t vdev_id,
+		     enum netif_action_type action,
+		     enum netif_reason_type reason);
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+void hdd_tx_resume_cb(void *adapter_context, bool tx_resume);
+
+/**
+ * hdd_tx_flow_control_is_pause() - Is TX Q paused by flow control
+ * @adapter_context: pointer to vdev apdapter
+ *
+ * Return: true if TX Q is paused by flow control
+ */
+bool hdd_tx_flow_control_is_pause(void *adapter_context);
+
+/**
+ * hdd_register_tx_flow_control() - Register TX Flow control
+ * @adapter: adapter handle
+ * @timer_callback: timer callback
+ * @flow_control_fp: txrx flow control
+ * @flow_control_is_pause_fp: is txrx paused by flow control
+ *
+ * Return: none
+ */
+void hdd_register_tx_flow_control(struct hdd_adapter *adapter,
+		qdf_mc_timer_callback_t timer_callback,
+		ol_txrx_tx_flow_control_fp flowControl,
+		ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause);
+void hdd_deregister_tx_flow_control(struct hdd_adapter *adapter);
+void hdd_get_tx_resource(struct hdd_adapter *adapter,
+			uint8_t STAId, uint16_t timer_value);
+
+#else
+static inline void hdd_tx_resume_cb(void *adapter_context, bool tx_resume)
+{
+}
+static inline bool hdd_tx_flow_control_is_pause(void *adapter_context)
+{
+	return false;
+}
+static inline void hdd_register_tx_flow_control(struct hdd_adapter *adapter,
+		qdf_mc_timer_callback_t timer_callback,
+		ol_txrx_tx_flow_control_fp flowControl,
+		ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause)
+{
+}
+static inline void hdd_deregister_tx_flow_control(struct hdd_adapter *adapter)
+{
+}
+static inline void hdd_get_tx_resource(struct hdd_adapter *adapter,
+			uint8_t STAId, uint16_t timer_value)
+{
+}
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \
+		defined(QCA_HL_NETDEV_FLOW_CONTROL)
+void hdd_tx_resume_timer_expired_handler(void *adapter_context);
+#else
+static inline void hdd_tx_resume_timer_expired_handler(void *adapter_context)
+{
+}
+#endif
+
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+void hdd_register_hl_netdev_fc_timer(struct hdd_adapter *adapter,
+				     qdf_mc_timer_callback_t timer_callback);
+void hdd_deregister_hl_netdev_fc_timer(struct hdd_adapter *adapter);
+#else
+static inline void hdd_register_hl_netdev_fc_timer(struct hdd_adapter *adapter,
+						   qdf_mc_timer_callback_t
+						   timer_callback)
+{}
+
+static inline void
+	hdd_deregister_hl_netdev_fc_timer(struct hdd_adapter *adapter)
+{}
+#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
+
+int hdd_get_peer_idx(struct hdd_station_ctx *sta_ctx,
+		     struct qdf_mac_addr *addr);
+
+const char *hdd_reason_type_to_string(enum netif_reason_type reason);
+const char *hdd_action_type_to_string(enum netif_action_type action);
+void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter,
+		enum netif_action_type action, enum netif_reason_type reason);
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+int hdd_set_mon_rx_cb(struct net_device *dev);
+#else
+static inline
+int hdd_set_mon_rx_cb(struct net_device *dev)
+{
+	return 0;
+}
+#endif
+
+void hdd_send_rps_ind(struct hdd_adapter *adapter);
+void hdd_send_rps_disable_ind(struct hdd_adapter *adapter);
+void wlan_hdd_classify_pkt(struct sk_buff *skb);
+
+#ifdef MSM_PLATFORM
+void hdd_reset_tcp_delack(struct hdd_context *hdd_ctx);
+#define HDD_MSM_CFG(msm_cfg)	msm_cfg
+#else
+static inline void hdd_reset_tcp_delack(struct hdd_context *hdd_ctx) {}
+#define HDD_MSM_CFG(msm_cfg)	0
+#endif
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void hdd_event_eapol_log(struct sk_buff *skb, enum qdf_proto_dir dir);
+#else
+static inline
+void hdd_event_eapol_log(struct sk_buff *skb, enum qdf_proto_dir dir)
+{}
+#endif
+
+/*
+ * As of the 4.7 kernel, net_device->trans_start is removed. Create shims to
+ * support compiling against older versions of the kernel.
+ */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0))
+static inline void netif_trans_update(struct net_device *dev)
+{
+	dev->trans_start = jiffies;
+}
+
+#define TX_TIMEOUT_TRACE(dev, module_id) QDF_TRACE( \
+	module_id, QDF_TRACE_LEVEL_ERROR, \
+	"%s: Transmission timeout occurred jiffies %lu trans_start %lu", \
+	__func__, jiffies, dev->trans_start)
+#else
+#define TX_TIMEOUT_TRACE(dev, module_id) QDF_TRACE( \
+	module_id, QDF_TRACE_LEVEL_ERROR, \
+	"%s: Transmission timeout occurred jiffies %lu", \
+	__func__, jiffies)
+#endif
+
+static inline void
+hdd_skb_fill_gso_size(struct net_device *dev, struct sk_buff *skb)
+{
+	if (skb_cloned(skb) && skb_is_nonlinear(skb) &&
+	    skb_shinfo(skb)->gso_size == 0 &&
+	    ip_hdr(skb)->protocol == IPPROTO_TCP) {
+		skb_shinfo(skb)->gso_size = dev->mtu -
+			((skb_transport_header(skb) - skb_network_header(skb))
+				+ tcp_hdrlen(skb));
+	}
+}
+
+/**
+ * hdd_txrx_get_tx_ack_count() - get tx acked count
+ * @adapter: Pointer to adapter
+ *
+ * Return: tx acked count
+ */
+uint32_t hdd_txrx_get_tx_ack_count(struct hdd_adapter *adapter);
+
+#ifdef CONFIG_HL_SUPPORT
+static inline QDF_STATUS
+hdd_skb_nontso_linearize(struct sk_buff *skb)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS
+hdd_skb_nontso_linearize(struct sk_buff *skb)
+{
+	if (qdf_nbuf_is_nonlinear(skb) && qdf_nbuf_is_tso(skb) == false) {
+		if (qdf_unlikely(skb_linearize(skb)))
+			return QDF_STATUS_E_NOMEM;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * hdd_dp_cfg_update() - update hdd config for HDD DP INIs
+ * @psoc: Pointer to psoc obj
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Return: None
+ */
+void hdd_dp_cfg_update(struct wlan_objmgr_psoc *psoc,
+		       struct hdd_context *hdd_ctx);
+
+#endif /* end #if !defined(WLAN_HDD_TX_RX_H) */
diff --git a/core/hdd/inc/wlan_hdd_wext.h b/core/hdd/inc/wlan_hdd_wext.h
new file mode 100644
index 0000000..edecdc5
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_wext.h
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __WEXT_IW_H__
+#define __WEXT_IW_H__
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <linux/timer.h>
+#include "qdf_event.h"
+
+struct hdd_context;
+struct sap_config;
+
+/*
+ * order of parameters in addTs private ioctl
+ */
+#define HDD_WLAN_WMM_PARAM_HANDLE                       0
+#define HDD_WLAN_WMM_PARAM_TID                          1
+#define HDD_WLAN_WMM_PARAM_DIRECTION                    2
+#define HDD_WLAN_WMM_PARAM_APSD                         3
+#define HDD_WLAN_WMM_PARAM_USER_PRIORITY                4
+#define HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE            5
+#define HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE            6
+#define HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE            7
+#define HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE               8
+#define HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE               9
+#define HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE              10
+#define HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE            11
+#define HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE 12
+#define HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL            13
+#define HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL         14
+#define HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN             15
+#define HDD_WLAN_WMM_PARAM_ACK_POLICY                  16
+#define HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL         17
+#define HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL        18
+#define HDD_WLAN_WMM_PARAM_COUNT                       19
+
+#define MHZ 6
+
+#define WE_MAX_STR_LEN                                 IW_PRIV_SIZE_MASK
+#define WLAN_HDD_UI_BAND_AUTO                          0
+#define WLAN_HDD_UI_BAND_5_GHZ                         1
+#define WLAN_HDD_UI_BAND_2_4_GHZ                       2
+
+enum hdd_wlan_wmm_direction {
+	HDD_WLAN_WMM_DIRECTION_UPSTREAM = 0,
+	HDD_WLAN_WMM_DIRECTION_DOWNSTREAM = 1,
+	HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL = 2,
+};
+
+enum hdd_wlan_wmm_power_save {
+	HDD_WLAN_WMM_POWER_SAVE_LEGACY = 0,
+	HDD_WLAN_WMM_POWER_SAVE_UAPSD = 1,
+};
+
+typedef enum {
+	/* TSPEC/re-assoc done, async */
+	HDD_WLAN_WMM_STATUS_SETUP_SUCCESS = 0,
+	/* no need to setup TSPEC since ACM=0 and no UAPSD desired,
+	 * sync + async
+	 */
+	HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD = 1,
+	/* no need to setup TSPEC since ACM=0 and UAPSD already exists,
+	 * sync + async
+	 */
+	HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING = 2,
+	/* TSPEC result pending, sync */
+	HDD_WLAN_WMM_STATUS_SETUP_PENDING = 3,
+	/* TSPEC/re-assoc failed, sync + async */
+	HDD_WLAN_WMM_STATUS_SETUP_FAILED = 4,
+	/* Request rejected due to invalid params, sync + async */
+	HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM = 5,
+	/* TSPEC request rejected since AP!=QAP, sync */
+	HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM = 6,
+
+	/* TSPEC modification/re-assoc successful, async */
+	HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS = 7,
+	/* TSPEC modification a no-op since ACM=0 and
+	 * no change in UAPSD, sync + async
+	 */
+	HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD = 8,
+	/* TSPEC modification a no-op since ACM=0 and
+	 * requested U-APSD already exists, sync + async
+	 */
+	HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING = 9,
+	/* TSPEC result pending, sync */
+	HDD_WLAN_WMM_STATUS_MODIFY_PENDING = 10,
+	/* TSPEC modification failed, prev TSPEC in effect, sync + async */
+	HDD_WLAN_WMM_STATUS_MODIFY_FAILED = 11,
+	/* TSPEC modification request rejected due to invalid params,
+	 * sync + async
+	 */
+	HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM = 12,
+
+	/* TSPEC release successful, sync and also async */
+	HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS = 13,
+	/* TSPEC release pending, sync */
+	HDD_WLAN_WMM_STATUS_RELEASE_PENDING = 14,
+	/* TSPEC release failed, sync + async */
+	HDD_WLAN_WMM_STATUS_RELEASE_FAILED = 15,
+	/* TSPEC release rejected due to invalid params, sync */
+	HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM = 16,
+	/* TSPEC modified due to the mux'ing of requests on ACs, async */
+
+	HDD_WLAN_WMM_STATUS_MODIFIED = 17,
+	/* TSPEC revoked by AP, async */
+	HDD_WLAN_WMM_STATUS_LOST = 18,
+	/* some internal failure like memory allocation failure, etc, sync */
+	HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE = 19,
+
+	/* U-APSD failed during setup but OTA setup (whether TSPEC exchnage or
+	 * re-assoc) was done so app should release this QoS, async
+	 */
+	HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED = 20,
+	/* U-APSD failed during modify, but OTA setup (whether TSPEC exchnage or
+	 * re-assoc) was done so app should release this QoS, async
+	 */
+	HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED = 21
+} hdd_wlan_wmm_status_e;
+
+/** TS Info Ack Policy */
+enum hdd_wlan_wmm_ts_info_ack_policy {
+	HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK = 0,
+	HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK = 1,
+};
+
+/** Enable 11d */
+#define ENABLE_11D  1
+
+/** Disable 11d */
+#define DISABLE_11D 0
+
+/*
+ * refer wpa.h in wpa supplicant code for REASON_MICHAEL_MIC_FAILURE
+ *
+ * supplicant sets REASON_MICHAEL_MIC_FAILURE as the reason code when it
+ * sends the MLME deauth IOCTL for TKIP counter measures
+ */
+#define HDD_REASON_MICHAEL_MIC_FAILURE 14
+
+#define HDD_RTSCTS_EN_MASK                  0xF
+#define HDD_RTSCTS_ENABLE                   1
+#define HDD_CTS_ENABLE                      2
+
+#define HDD_AUTO_RATE_SGI    0x8
+
+/* Packet Types. */
+#define WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP     2
+#define WLAN_KEEP_ALIVE_NULL_PKT              1
+
+/*
+ * Defines for fw_test command
+ */
+#define HDD_FWTEST_PARAMS 3
+#define HDD_FWTEST_SU_PARAM_ID 53
+#define HDD_FWTEST_MU_PARAM_ID 2
+#define HDD_FWTEST_SU_DEFAULT_VALUE 100
+#define HDD_FWTEST_MU_DEFAULT_VALUE 40
+#define HDD_FWTEST_MAX_VALUE 500
+
+#ifdef WLAN_WEXT_SUPPORT_ENABLE
+/**
+ * hdd_unregister_wext() - unregister wext context
+ * @dev: net device handle
+ *
+ * Unregisters wext interface context for a given net device
+ *
+ * Returns: None
+ */
+void hdd_unregister_wext(struct net_device *dev);
+
+/**
+ * hdd_register_wext() - register wext context
+ * @dev: net device handle
+ *
+ * Registers wext interface context for a given net device
+ *
+ * Returns: None
+ */
+void hdd_register_wext(struct net_device *dev);
+
+void hdd_wlan_get_stats(struct hdd_adapter *adapter, uint16_t *length,
+		       char *buffer, uint16_t buf_len);
+void hdd_wlan_list_fw_profile(uint16_t *length,
+			      char *buffer, uint16_t buf_len);
+
+int iw_set_var_ints_getnone(struct net_device *dev,
+			   struct iw_request_info *info,
+			   union iwreq_data *wrqu, char *extra);
+
+int iw_set_three_ints_getnone(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+int hdd_priv_get_data(struct iw_point *p_priv_data,
+		     union iwreq_data *wrqu);
+
+void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len);
+
+int hdd_get_ldpc(struct hdd_adapter *adapter, int *value);
+
+/**
+ * hdd_set_ldpc() - Set adapter LDPC
+ * @adapter: adapter being modified
+ * @value: new LDPC value
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int hdd_set_ldpc(struct hdd_adapter *adapter, int value);
+
+int hdd_get_tx_stbc(struct hdd_adapter *adapter, int *value);
+
+/**
+ * hdd_set_tx_stbc() - Set adapter TX STBC
+ * @adapter: adapter being modified
+ * @value: new TX STBC value
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int hdd_set_tx_stbc(struct hdd_adapter *adapter, int value);
+
+int hdd_get_rx_stbc(struct hdd_adapter *adapter, int *value);
+
+/**
+ * hdd_set_rx_stbc() - Set adapter RX STBC
+ * @adapter: adapter being modified
+ * @value: new RX STBC value
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int hdd_set_rx_stbc(struct hdd_adapter *adapter, int value);
+
+/**
+ * hdd_assemble_rate_code() - assemble rate code to be sent to FW
+ * @preamble: rate preamble
+ * @nss: number of streams
+ * @rate: rate index
+ *
+ * Rate code assembling is different for targets which are 11ax capable.
+ * Check for the target support and assemble the rate code accordingly.
+ *
+ * Return: assembled rate code
+ */
+int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate);
+
+/**
+ * hdd_set_11ax_rate() - set 11ax rate
+ * @adapter: adapter being modified
+ * @value: new 11ax rate code
+ * @sap_config: pointer to SAP config to check HW mode
+ *              this will be NULL for call from STA persona
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int hdd_set_11ax_rate(struct hdd_adapter *adapter, int value,
+		      struct sap_config *sap_config);
+
+/**
+ * wlan_hdd_update_phymode() - handle change in PHY mode
+ * @adapter: adapter being modified
+ * @new_phymode: new PHY mode for the device
+ *
+ * This function is called when the device is set to a new PHY mode.
+ * It takes a holistic look at the desired PHY mode along with the
+ * configured capabilities of the driver and the reported capabilities
+ * of the hardware in order to correctly configure all PHY-related
+ * parameters.
+ *
+ * Return: 0 on success, negative errno value on error
+ */
+int wlan_hdd_update_phymode(struct hdd_adapter *adapter, int new_phymode);
+
+struct iw_request_info;
+
+/**
+ * hdd_check_private_wext_control() - Check to see if private
+ *      wireless extensions ioctls are allowed
+ * @hdd_ctx: Global HDD context
+ * @info: Wireless extensions ioctl information passed by the kernel
+ *
+ * This function will examine the "private_wext_control" configuration
+ * item to determine whether or not private wireless extensions ioctls
+ * are allowed.
+ *
+ * Return: 0 if the ioctl is allowed to be processed, -ENOTSUPP if the
+ * ioctls have been disabled. Note that in addition to returning
+ * status, this function will log a message if the ioctls are disabled
+ * or deprecated.
+ */
+int hdd_check_private_wext_control(struct hdd_context *hdd_ctx,
+				   struct iw_request_info *info);
+
+/**
+ * hdd_crash_inject() - Inject a crash
+ * @adapter: Adapter upon which the command was received
+ * @v1: first value to inject
+ * @v2: second value to inject
+ *
+ * This function is the handler for the crash inject debug feature.
+ * This feature only exists for internal testing and must not be
+ * enabled on a production device.
+ *
+ * Return: result of the command
+ */
+#ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT
+int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2);
+#else
+static inline
+int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2)
+{
+	return -ENOTSUPP;
+}
+#endif
+
+#ifdef CONFIG_DP_TRACE
+void hdd_set_dump_dp_trace(uint16_t cmd_type, uint16_t count);
+#else
+static inline
+void hdd_set_dump_dp_trace(uint16_t cmd_type, uint16_t count) {}
+#endif
+#else /* WLAN_WEXT_SUPPORT_ENABLE */
+
+static inline void hdd_unregister_wext(struct net_device *dev)
+{
+}
+
+static inline void hdd_register_wext(struct net_device *dev)
+{
+}
+#endif /* WLAN_WEXT_SUPPORT_ENABLE */
+
+#endif /* __WEXT_IW_H__ */
diff --git a/core/hdd/inc/wlan_hdd_wmm.h b/core/hdd/inc/wlan_hdd_wmm.h
new file mode 100644
index 0000000..ead0a78
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_wmm.h
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2011-2012,2016-2018 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.
+ */
+
+#ifndef _WLAN_HDD_WMM_H
+#define _WLAN_HDD_WMM_H
+
+/**
+ * DOC: HDD WMM
+ *
+ * This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation)
+ * houses all the logic for WMM in HDD.
+ *
+ * On the control path, it has the logic to setup QoS, modify QoS and delete
+ * QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an
+ * explicit application invoked and an internal HDD invoked.  The implicit QoS
+ * is for applications that do NOT call the custom QCT WLAN OIDs for QoS but
+ * which DO mark their traffic for priortization. It also has logic to start,
+ * update and stop the U-APSD trigger frame generation. It also has logic to
+ * read WMM related config parameters from the registry.
+ *
+ * On the data path, it has the logic to figure out the WMM AC of an egress
+ * packet and when to signal TL to serve a particular AC queue. It also has the
+ * logic to retrieve a packet based on WMM priority in response to a fetch from
+ * TL.
+ *
+ * The remaining functions are utility functions for information hiding.
+ */
+
+/* Include files */
+#include <linux/workqueue.h>
+#include <linux/list.h>
+#include <wlan_hdd_main.h>
+#include <wlan_hdd_wext.h>
+#include <sme_qos_api.h>
+
+/*Maximum number of ACs */
+#define WLAN_MAX_AC                         4
+
+
+/* Preprocessor Definitions and Constants */
+
+/* #define HDD_WMM_DEBUG 1 */
+
+#define HDD_WMM_CTX_MAGIC 0x574d4d58    /* "WMMX" */
+
+#define HDD_WMM_HANDLE_IMPLICIT 0xFFFFFFFF
+
+#define HDD_WLAN_INVALID_STA_ID 0xFF
+
+/* Type Declarations */
+
+/**
+ * enum hdd_wmm_user_mode - WMM modes of operation
+ *
+ * @HDD_WMM_USER_MODE_AUTO: STA can associate with any AP, & HDD looks at
+ *	the SME notification after association to find out if associated
+ *	with QAP and acts accordingly
+ * @HDD_WMM_USER_MODE_QBSS_ONLY - SME will add the extra logic to make sure
+ *	STA associates with a QAP only
+ * @HDD_WMM_USER_MODE_NO_QOS - Join any AP, but uapsd is disabled
+ */
+enum hdd_wmm_user_mode {
+	HDD_WMM_USER_MODE_AUTO = 0,
+	HDD_WMM_USER_MODE_QBSS_ONLY = 1,
+	HDD_WMM_USER_MODE_NO_QOS = 2,
+};
+
+/* UAPSD Mask bits */
+/* (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored) */
+#define HDD_AC_VO 0x1
+#define HDD_AC_VI 0x2
+#define HDD_AC_BK 0x4
+#define HDD_AC_BE 0x8
+
+/**
+ * enum hdd_wmm_linuxac: AC/Queue Index values for Linux Qdisc to
+ * operate on different traffic.
+ */
+enum hdd_wmm_linuxac {
+	HDD_LINUX_AC_VO = 0,
+	HDD_LINUX_AC_VI = 1,
+	HDD_LINUX_AC_BE = 2,
+	HDD_LINUX_AC_BK = 3,
+	HDD_LINUX_AC_HI_PRIO = 4,
+};
+
+/**
+ * struct hdd_wmm_qos_context - HDD WMM QoS Context
+ *
+ * This structure holds the context for a single flow which has either
+ * been confgured explicitly from userspace or implicitly via the
+ * Implicit QoS feature.
+ *
+ * @node: list node which can be used to put the context into a list
+ *	of contexts
+ * @handle: identifer which uniquely identifies this context to userspace
+ * @qosFlowID: identifier which uniquely identifies this flow to SME
+ * @adapter: adapter upon which this flow was configured
+ * @acType: access category for this flow
+ * @lastStatus: the status of the last operation performed on this flow by SME
+ * @wmmAcSetupImplicitQos: work structure used for deferring implicit QoS work
+ *	from softirq context to thread context
+ * @magic: magic number used to verify that this is a valid context when
+ *	referenced anonymously
+ */
+struct hdd_wmm_qos_context {
+	struct list_head node;
+	uint32_t handle;
+	uint32_t qosFlowId;
+	struct hdd_adapter *adapter;
+	sme_ac_enum_type acType;
+	hdd_wlan_wmm_status_e lastStatus;
+	struct work_struct wmmAcSetupImplicitQos;
+	uint32_t magic;
+	bool is_inactivity_timer_running;
+};
+
+/**
+ * struct hdd_wmm_ac_status - WMM related per-AC state & status info
+ * @wmmAcAccessRequired - does the AP require access to this AC?
+ * @wmmAcAccessNeeded - does the worker thread need to acquire access to
+ *	this AC?
+ * @wmmAcAccessPending - is implicit QoS negotiation currently taking place?
+ * @wmmAcAccessFailed - has implicit QoS negotiation already failed?
+ * @wmmAcAccessGranted - has implicit QoS negotiation already succeeded?
+ * @wmmAcAccessAllowed - is access to this AC allowed, either because we
+ *	are not doing WMM, we are not doing implicit QoS, implict QoS has
+ *	completed, or explicit QoS has completed?
+ * @wmmAcTspecValid - is the wmmAcTspecInfo valid?
+ * @wmmAcUapsdInfoValid - are the wmmAcUapsd* fields valid?
+ * @wmmAcTspecInfo - current (possibly aggregate) Tspec for this AC
+ * @wmmAcIsUapsdEnabled - is UAPSD enabled on this AC?
+ * @wmmAcUapsdServiceInterval - service interval for this AC
+ * @wmmAcUapsdSuspensionInterval - suspension interval for this AC
+ * @wmmAcUapsdDirection - direction for this AC
+ * @wmmInactivityTime - inactivity time for this AC
+ * @wmmPrevTrafficCnt - TX counter used for inactivity detection
+ * @wmmInactivityTimer - timer used for inactivity detection
+ */
+struct hdd_wmm_ac_status {
+	bool wmmAcAccessRequired;
+	bool wmmAcAccessNeeded;
+	bool wmmAcAccessPending;
+	bool wmmAcAccessFailed;
+	bool wmmAcAccessGranted;
+	bool wmmAcAccessAllowed;
+	bool wmmAcTspecValid;
+	bool wmmAcUapsdInfoValid;
+	struct sme_qos_wmmtspecinfo wmmAcTspecInfo;
+	bool wmmAcIsUapsdEnabled;
+	uint32_t wmmAcUapsdServiceInterval;
+	uint32_t wmmAcUapsdSuspensionInterval;
+	enum sme_qos_wmm_dir_type wmmAcUapsdDirection;
+
+#ifdef FEATURE_WLAN_ESE
+	uint32_t wmmInactivityTime;
+	uint32_t wmmPrevTrafficCnt;
+	qdf_mc_timer_t wmmInactivityTimer;
+#endif
+};
+
+/**
+ * struct hdd_wmm_status - WMM status maintained per-adapter
+ * @wmmContextList - list of WMM contexts active on the adapter
+ * @wmmLock - mutex used for exclusive access to this adapter's WMM status
+ * @wmmACStatus - per-AC WMM status
+ * @wmmQap - is this connected to a QoS-enabled AP?
+ * @wmmQosConnection - is this a QoS connection?
+ */
+struct hdd_wmm_status {
+	struct list_head wmmContextList;
+	struct mutex wmmLock;
+	struct hdd_wmm_ac_status wmmAcStatus[WLAN_MAX_AC];
+	bool wmmQap;
+	bool wmmQosConnection;
+};
+
+extern const uint8_t hdd_qdisc_ac_to_tl_ac[];
+extern const uint8_t hdd_wmm_up_to_ac_map[];
+extern const uint8_t hdd_linux_up_to_ac_map[];
+
+#define WLAN_HDD_MAX_DSCP 0x3f
+
+/**
+ * hdd_wmmps_helper() - Function to set uapsd psb dynamically
+ *
+ * @adapter: [in] pointer to adapter structure
+ * @ptr: [in] pointer to command buffer
+ *
+ * Return: Zero on success, appropriate error on failure.
+ */
+int hdd_wmmps_helper(struct hdd_adapter *adapter, uint8_t *ptr);
+
+/**
+ * hdd_wmm_init() - initialize the WMM DSCP configuation
+ * @adapter : [in]  pointer to Adapter context
+ *
+ * This function will initialize the WMM DSCP configuation of an
+ * adapter to an initial state.  The configuration can later be
+ * overwritten via application APIs or via QoS Map sent OTA.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_init(struct hdd_adapter *adapter);
+
+/**
+ * hdd_wmm_adapter_init() - initialize the WMM configuration of an adapter
+ * @adapter: [in]  pointer to Adapter context
+ *
+ * This function will initialize the WMM configuation and status of an
+ * adapter to an initial state.  The configuration can later be
+ * overwritten via application APIs
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_adapter_init(struct hdd_adapter *adapter);
+
+/**
+ * hdd_wmm_close() - WMM close function
+ * @adapter: [in]  pointer to adapter context
+ *
+ * Function which will perform any necessary work to to clean up the
+ * WMM functionality prior to the kernel module unload.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_adapter_close(struct hdd_adapter *adapter);
+
+/**
+ * hdd_wmm_select_queue() - Function which will classify the packet
+ *       according to linux qdisc expectation.
+ *
+ * @dev: [in] pointer to net_device structure
+ * @skb: [in] pointer to os packet
+ *
+ * Return: Qdisc queue index
+ */
+uint16_t hdd_wmm_select_queue(struct net_device *dev, struct sk_buff *skb);
+
+/**
+ * hdd_hostapd_select_queue() - Function which will classify the packet
+ *       according to linux qdisc expectation.
+ *
+ * @dev: [in] pointer to net_device structure
+ * @skb: [in] pointer to os packet
+ *
+ * Return: Qdisc queue index
+ */
+uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
+				  , void *accel_priv
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+				  , select_queue_fallback_t fallback
+#endif
+);
+
+/**
+ * hdd_wmm_acquire_access_required() - Function which will determine
+ * acquire admittance for a WMM AC is required or not based on psb configuration
+ * done in framework
+ *
+ * @adapter: [in] pointer to adapter structure
+ * @acType: [in] WMM AC type of OS packet
+ *
+ * Return: void
+ */
+void hdd_wmm_acquire_access_required(struct hdd_adapter *adapter,
+				     sme_ac_enum_type acType);
+
+/**
+ * hdd_wmm_acquire_access() - Function which will attempt to acquire
+ * admittance for a WMM AC
+ *
+ * @adapter: [in]  pointer to adapter context
+ * @acType: [in]  WMM AC type of OS packet
+ * @pGranted: [out] pointer to bool flag when indicates if access
+ *	      has been granted or not
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_acquire_access(struct hdd_adapter *adapter,
+				  sme_ac_enum_type acType, bool *pGranted);
+
+/**
+ * hdd_wmm_assoc() - Function which will handle the housekeeping
+ * required by WMM when association takes place
+ *
+ * @adapter: [in]  pointer to adapter context
+ * @roam_info: [in]  pointer to roam information
+ * @eBssType: [in]  type of BSS
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_assoc(struct hdd_adapter *adapter,
+			 struct csr_roam_info *roam_info,
+			 eCsrRoamBssType eBssType);
+
+/**
+ * hdd_wmm_connect() - Function which will handle the housekeeping
+ * required by WMM when a connection is established
+ *
+ * @adapter : [in]  pointer to adapter context
+ * @roam_info: [in]  pointer to roam information
+ * @eBssType : [in]  type of BSS
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_connect(struct hdd_adapter *adapter,
+			   struct csr_roam_info *roam_info,
+			   eCsrRoamBssType eBssType);
+
+/**
+ * hdd_wmm_get_uapsd_mask() - Function which will calculate the
+ * initial value of the UAPSD mask based upon the device configuration
+ *
+ * @adapter  : [in]  pointer to adapter context
+ * @pUapsdMask: [out] pointer to where the UAPSD Mask is to be stored
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_get_uapsd_mask(struct hdd_adapter *adapter,
+				  uint8_t *pUapsdMask);
+
+/**
+ * hdd_wmm_is_active() - Function which will determine if WMM is
+ * active on the current connection
+ *
+ * @adapter: [in]  pointer to adapter context
+ *
+ * Return: true if WMM is enabled, false if WMM is not enabled
+ */
+bool hdd_wmm_is_active(struct hdd_adapter *adapter);
+
+/**
+ * hdd_wmm_is_acm_allowed() - Function which will determine if WMM is
+ * active on the current connection
+ *
+ * @vdev_id: vdev id
+ *
+ * Return: true if WMM is enabled, false if WMM is not enabled
+ */
+bool hdd_wmm_is_acm_allowed(uint8_t vdev_id);
+
+
+/**
+ * hdd_wmm_addts() - Function which will add a traffic spec at the
+ * request of an application
+ *
+ * @adapter  : [in]  pointer to adapter context
+ * @handle    : [in]  handle to uniquely identify a TS
+ * @pTspec    : [in]  pointer to the traffic spec
+ *
+ * Return: HDD_WLAN_WMM_STATUS_*
+ */
+hdd_wlan_wmm_status_e hdd_wmm_addts(struct hdd_adapter *adapter,
+				    uint32_t handle,
+				    struct sme_qos_wmmtspecinfo *pTspec);
+
+/**
+ * hdd_wmm_delts() - Function which will delete a traffic spec at the
+ * request of an application
+ *
+ * @adapter: [in]  pointer to adapter context
+ * @handle: [in]  handle to uniquely identify a TS
+ *
+ * Return: HDD_WLAN_WMM_STATUS_*
+ */
+hdd_wlan_wmm_status_e hdd_wmm_delts(struct hdd_adapter *adapter,
+				    uint32_t handle);
+
+/**
+ * hdd_wmm_checkts() - Function which will return the status of a traffic
+ * spec at the request of an application
+ *
+ * @adapter: [in]  pointer to adapter context
+ * @handle: [in]  handle to uniquely identify a TS
+ *
+ * Return: HDD_WLAN_WMM_STATUS_*
+ */
+hdd_wlan_wmm_status_e hdd_wmm_checkts(struct hdd_adapter *adapter,
+				      uint32_t handle);
+/**
+ * hdd_wmm_adapter_clear() - Function which will clear the WMM status
+ * for all the ACs
+ *
+ * @adapter: [in]  pointer to Adapter context
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_adapter_clear(struct hdd_adapter *adapter);
+
+void wlan_hdd_process_peer_unauthorised_pause(struct hdd_adapter *adapter);
+#endif /* #ifndef _WLAN_HDD_WMM_H */
diff --git a/core/hdd/inc/wlan_hdd_wowl.h b/core/hdd/inc/wlan_hdd_wowl.h
new file mode 100644
index 0000000..1a6c35c
--- /dev/null
+++ b/core/hdd/inc/wlan_hdd_wowl.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#ifndef _WLAN_HDD_WOWL_H
+#define _WLAN_HDD_WOWL_H
+
+/**
+ * DOC: wlan_hdd_wowl
+ *
+ * This module houses all the logic for WOWL in HDD.
+ *
+ * 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:
+ * typedef 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
+ *
+ * HDD 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 HDD. WoWL
+ * needs to enabled explcitly by exercising the iwpriv command.
+ *
+ * HDD 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
+ * defaults (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.
+ */
+
+#include <qdf_types.h>
+#include "wlan_pmo_wow_public_struct.h"
+
+#define WOWL_PTRN_MAX_SIZE	146
+#define WOWL_PTRN_MASK_MAX_SIZE	19
+#define WOWL_MAX_PTRNS_ALLOWED	PMO_WOW_FILTERS_MAX
+
+/**
+ * hdd_add_wowl_ptrn() - Function which will add the WoWL pattern to be
+ *			 used when PBM filtering is enabled
+ * @adapter: pointer to the adapter
+ * @ptrn: pointer to the pattern string to be added
+ *
+ * Return: false if any errors encountered, true otherwise
+ */
+bool hdd_add_wowl_ptrn(struct hdd_adapter *adapter, const char *ptrn);
+
+/**
+ * hdd_del_wowl_ptrn() - Function which will remove a WoWL pattern
+ * @adapter: pointer to the adapter
+ * @ptrn: pointer to the pattern string to be removed
+ *
+ * Return: false if any errors encountered, true otherwise
+ */
+bool hdd_del_wowl_ptrn(struct hdd_adapter *adapter, const char *ptrn);
+
+/**
+ * hdd_add_wowl_ptrn_debugfs() - Function which will add a WoW pattern
+ *				 sent from debugfs interface
+ * @adapter: pointer to the adapter
+ * @pattern_idx: index of the pattern to be added
+ * @pattern_offset: offset of the pattern in the frame payload
+ * @pattern_buf: pointer to the pattern hex string to be added
+ * @pattern_mask: pointer to the pattern mask hex string
+ *
+ * Return: false if any errors encountered, true otherwise
+ */
+bool hdd_add_wowl_ptrn_debugfs(struct hdd_adapter *adapter, uint8_t pattern_idx,
+			       uint8_t pattern_offset, char *pattern_buf,
+			       char *pattern_mask);
+
+/**
+ * hdd_del_wowl_ptrn_debugfs() - Function which will remove a WoW pattern
+ *				 sent from debugfs interface
+ * @adapter: pointer to the adapter
+ * @pattern_idx: index of the pattern to be removed
+ *
+ * Return: false if any errors encountered, true otherwise
+ */
+bool hdd_del_wowl_ptrn_debugfs(struct hdd_adapter *adapter,
+			       uint8_t pattern_idx);
+
+/**
+ * hdd_free_user_wowl_ptrns() - Deinit function to cleanup WoWL allocated memory
+ *
+ * Return: None
+ */
+void hdd_free_user_wowl_ptrns(void);
+
+#endif /* #ifndef _WLAN_HDD_WOWL_H */
diff --git a/core/hdd/src/wlan_hdd_active_tos.c b/core/hdd/src/wlan_hdd_active_tos.c
new file mode 100644
index 0000000..fbcaf63
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_active_tos.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_active_tos.c
+ *
+ * WLAN active tos functions
+ *
+ */
+
+#include <wlan_hdd_includes.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <wlan_hdd_active_tos.h>
+#include "wlan_policy_mgr_ucfg.h"
+
+/**
+ * tos - Type of service requested by the application
+ * TOS_BK: Back ground traffic
+ * TOS_BE: Best effort traffic
+ * TOS_VI: Video traffic
+ * TOS_VO: Voice traffic
+ */
+enum tos {
+	TOS_BK = 0,
+	TOS_BE = 1,
+	TOS_VI = 2,
+	TOS_VO = 3,
+};
+
+#define HDD_AC_BK_BIT                   1
+#define HDD_AC_BE_BIT                   2
+#define HDD_AC_VI_BIT                   4
+#define HDD_AC_VO_BIT                   8
+
+#define HDD_MAX_OFF_CHAN_TIME_FOR_VO    20
+#define HDD_MAX_OFF_CHAN_TIME_FOR_VI    20
+#define HDD_MAX_OFF_CHAN_TIME_FOR_BE    40
+#define HDD_MAX_OFF_CHAN_TIME_FOR_BK    40
+
+#define HDD_MAX_AC                      4
+#define HDD_MAX_OFF_CHAN_ENTRIES        2
+
+#define HDD_AC_BIT_INDX                 0
+#define HDD_DWELL_TIME_INDX             1
+
+static int limit_off_chan_tbl[HDD_MAX_AC][HDD_MAX_OFF_CHAN_ENTRIES] = {
+		{ HDD_AC_BK_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BK },
+		{ HDD_AC_BE_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BE },
+		{ HDD_AC_VI_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VI },
+		{ HDD_AC_VO_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VO },
+};
+
+static const struct nla_policy
+wlan_hdd_set_limit_off_channel_param_policy
+[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_START] = {.type = NLA_U8 },
+};
+
+/**
+ * hdd_set_limit_off_chan_for_tos() - set limit off-channel command parameters
+ * @adapter: HDD adapter
+ * @tos: type of service
+ * @is_tos_active: status of the traffic
+ *
+ * Return: 0 on success and non zero value on failure
+ */
+
+static int
+hdd_set_limit_off_chan_for_tos(struct hdd_adapter *adapter,
+			       enum tos tos,
+			       bool is_tos_active)
+{
+	int ac_bit;
+	struct hdd_context *hdd_ctx;
+	uint32_t max_off_chan_time = 0;
+	QDF_STATUS status;
+	int ret;
+	uint8_t def_sys_pref = 0;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+
+	if (ret < 0)
+		return ret;
+	ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc,
+				     &def_sys_pref);
+
+	ac_bit = limit_off_chan_tbl[tos][HDD_AC_BIT_INDX];
+
+	if (is_tos_active)
+		adapter->active_ac |= ac_bit;
+	else
+		adapter->active_ac &= ~ac_bit;
+
+	if (adapter->active_ac) {
+		if (adapter->active_ac & HDD_AC_VO_BIT) {
+			max_off_chan_time =
+				limit_off_chan_tbl[TOS_VO][HDD_DWELL_TIME_INDX];
+			policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc,
+							    PM_LATENCY);
+		} else if (adapter->active_ac & HDD_AC_VI_BIT) {
+			max_off_chan_time =
+				limit_off_chan_tbl[TOS_VI][HDD_DWELL_TIME_INDX];
+			policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc,
+							    PM_LATENCY);
+		} else {
+			/*ignore this command if only BE/BK is active */
+			is_tos_active = false;
+			policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc,
+							    def_sys_pref);
+		}
+	} else {
+		/* No active tos */
+		policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc,
+						    def_sys_pref);
+	}
+
+	status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
+					adapter->session_id,
+					is_tos_active,
+					max_off_chan_time,
+					hdd_ctx->config->nRestTimeConc,
+					true);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("failed to set limit off chan params");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_limit_offchan_param() - set limit off-channel cmd
+ * parameters
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to limit off-channel command parameters.
+ * @data_len: the length in byte of  limit off-channel command parameters.
+ *
+ * This is called when application wants to limit the off channel time due to
+ * active voip traffic.
+ *
+ * Return: An error code or 0 on success.
+ */
+static int
+__wlan_hdd_cfg80211_set_limit_offchan_param(struct wiphy *wiphy,
+					    struct wireless_dev *wdev,
+					    const void *data,
+					    int data_len)
+{
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_MAX + 1];
+	struct net_device   *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int ret = 0;
+	uint8_t tos;
+	uint8_t tos_status;
+
+	hdd_enter();
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret < 0)
+		return ret;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_MAX,
+				 data, data_len,
+				 wlan_hdd_set_limit_off_channel_param_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS]) {
+		hdd_err("attr tos failed");
+		goto fail;
+	}
+
+	tos = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS]);
+	if (tos >= HDD_MAX_AC) {
+		hdd_err("tos value %d exceeded Max value %d",
+			tos, HDD_MAX_AC);
+		goto fail;
+	}
+	hdd_debug("tos %d", tos);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_START]) {
+		hdd_err("attr tos active failed");
+		goto fail;
+	}
+	tos_status = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_START]);
+
+	hdd_debug("tos status %d", tos_status);
+	ret = hdd_set_limit_off_chan_for_tos(adapter, tos, tos_status);
+
+fail:
+	return ret;
+}
+
+int wlan_hdd_cfg80211_set_limit_offchan_param(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      const void *data, int data_len)
+
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_limit_offchan_param(wiphy, wdev, data,
+							  data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
diff --git a/core/hdd/src/wlan_hdd_active_tos.h b/core/hdd/src/wlan_hdd_active_tos.h
new file mode 100644
index 0000000..80f39c4
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_active_tos.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __WLAN_HDD_ACTIVE_TOS_H
+#define __WLAN_HDD_ACTIVE_TOS_H
+
+/**
+ * DOC: wlan_hdd_active_tos_h
+ *
+ * WLAN Host Device Driver ACTIVE TOS API specification
+ */
+
+#ifdef FEATURE_ACTIVE_TOS
+/**
+ * wlan_hdd_cfg80211_set_limit_offchan_param() - set limit off-channel cmd
+ * parameters
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to limit off-channel command parameters.
+ * @data_len: the length in byte of  limit off-channel command parameters.
+ *
+ * This is called when application wants to limit the off channel time due to
+ * active voip traffic.
+ *
+ * Return: An error code or 0 on success.
+ */
+int wlan_hdd_cfg80211_set_limit_offchan_param(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      const void *data, int data_len);
+
+#define FEATURE_ACTIVE_TOS_VENDOR_COMMANDS			\
+{								\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,		\
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ACTIVE_TOS,	\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |			\
+		WIPHY_VENDOR_CMD_NEED_NETDEV |			\
+		WIPHY_VENDOR_CMD_NEED_RUNNING,			\
+	.doit = wlan_hdd_cfg80211_set_limit_offchan_param	\
+},
+#else /* FEATURE_ACTIVE_TOS */
+#define FEATURE_ACTIVE_TOS_VENDOR_COMMANDS
+#endif /* FEATURE_ACTIVE_TOS */
+
+#endif /* __WLAN_HDD_ACTIVE_TOS_H */
+
diff --git a/core/hdd/src/wlan_hdd_apf.c b/core/hdd/src/wlan_hdd_apf.c
new file mode 100644
index 0000000..353d527
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_apf.c
@@ -0,0 +1,713 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_apf.c
+ *
+ * Android Packet Filter support and implementation
+ */
+
+#include "wlan_hdd_apf.h"
+#include "qca_vendor.h"
+#include "wlan_osif_request_manager.h"
+
+/*
+ * define short names for the global vendor params
+ * used by __wlan_hdd_cfg80211_apf_offload()
+ */
+#define APF_INVALID \
+	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_INVALID
+#define APF_SUBCMD \
+	QCA_WLAN_VENDOR_ATTR_SET_RESET_PACKET_FILTER
+#define APF_VERSION \
+	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION
+#define APF_FILTER_ID \
+	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID
+#define APF_PACKET_SIZE \
+	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE
+#define APF_CURRENT_OFFSET \
+	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET
+#define APF_PROGRAM \
+	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM
+#define APF_PROG_LEN \
+	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROG_LENGTH
+#define APF_MAX \
+	QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX
+
+static const struct nla_policy
+wlan_hdd_apf_offload_policy[APF_MAX + 1] = {
+	[APF_SUBCMD] = {.type = NLA_U32},
+	[APF_VERSION] = {.type = NLA_U32},
+	[APF_FILTER_ID] = {.type = NLA_U32},
+	[APF_PACKET_SIZE] = {.type = NLA_U32},
+	[APF_CURRENT_OFFSET] = {.type = NLA_U32},
+	[APF_PROGRAM] = {.type = NLA_BINARY,
+			 .len = MAX_APF_MEMORY_LEN},
+	[APF_PROG_LEN] = {.type = NLA_U32},
+};
+
+void hdd_apf_context_init(struct hdd_adapter *adapter)
+{
+	qdf_event_create(&adapter->apf_context.qdf_apf_event);
+	qdf_spinlock_create(&adapter->apf_context.lock);
+	adapter->apf_context.apf_enabled = true;
+}
+
+void hdd_apf_context_destroy(struct hdd_adapter *adapter)
+{
+	qdf_event_destroy(&adapter->apf_context.qdf_apf_event);
+	qdf_spinlock_destroy(&adapter->apf_context.lock);
+	qdf_mem_zero(&adapter->apf_context,
+		     sizeof(struct hdd_apf_context));
+}
+
+struct apf_offload_priv {
+	struct sir_apf_get_offload apf_get_offload;
+};
+
+void hdd_get_apf_capabilities_cb(void *context,
+				 struct sir_apf_get_offload *data)
+{
+	struct osif_request *request;
+	struct apf_offload_priv *priv;
+
+	hdd_enter();
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+	priv->apf_get_offload = *data;
+	osif_request_complete(request);
+	osif_request_put(request);
+
+	hdd_exit();
+}
+
+/**
+ * hdd_post_get_apf_capabilities_rsp() - Callback function to APF Offload
+ * @hdd_context: hdd_context
+ * @apf_get_offload: struct for get offload
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+static int
+hdd_post_get_apf_capabilities_rsp(struct hdd_context *hdd_ctx,
+				  struct sir_apf_get_offload *apf_get_offload)
+{
+	struct sk_buff *skb;
+	uint32_t nl_buf_len;
+
+	hdd_enter();
+
+	nl_buf_len = NLMSG_HDRLEN;
+	nl_buf_len +=
+		(sizeof(apf_get_offload->max_bytes_for_apf_inst) + NLA_HDRLEN) +
+		(sizeof(apf_get_offload->apf_version) + NLA_HDRLEN);
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	hdd_ctx->apf_version = apf_get_offload->apf_version;
+	hdd_debug("APF Version: %u APF max bytes: %u",
+		  apf_get_offload->apf_version,
+		  apf_get_offload->max_bytes_for_apf_inst);
+
+	if (nla_put_u32(skb, APF_PACKET_SIZE,
+			apf_get_offload->max_bytes_for_apf_inst) ||
+	    nla_put_u32(skb, APF_VERSION, apf_get_offload->apf_version)) {
+		hdd_err("nla put failure");
+		goto nla_put_failure;
+	}
+
+	cfg80211_vendor_cmd_reply(skb);
+	hdd_exit();
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EINVAL;
+}
+
+/**
+ * hdd_get_apf_capabilities - Get APF offload Capabilities
+ * @hdd_ctx: Hdd context
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int hdd_get_apf_capabilities(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	int ret;
+	void *cookie;
+	struct osif_request *request;
+	struct apf_offload_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_APF,
+	};
+
+	hdd_enter();
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Unable to allocate request");
+		return -EINVAL;
+	}
+	cookie = osif_request_cookie(request);
+
+	status = sme_get_apf_capabilities(hdd_ctx->mac_handle,
+					  hdd_get_apf_capabilities_cb,
+					  cookie);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Unable to retrieve APF caps");
+		ret = qdf_status_to_os_return(status);
+		goto cleanup;
+	}
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_err("Target response timed out");
+		goto cleanup;
+	}
+	priv = osif_request_priv(request);
+	ret = hdd_post_get_apf_capabilities_rsp(hdd_ctx,
+						&priv->apf_get_offload);
+	if (ret)
+		hdd_err("Failed to post get apf capabilities");
+
+cleanup:
+	/*
+	 * either we never sent a request to SME, we sent a request to
+	 * SME and timed out, or we sent a request to SME, received a
+	 * response from SME, and posted the response to userspace.
+	 * regardless we are done with the request.
+	 */
+	osif_request_put(request);
+	hdd_exit();
+
+	return ret;
+}
+
+/**
+ * hdd_set_reset_apf_offload - Post set/reset apf to SME
+ * @hdd_ctx: Hdd context
+ * @tb: Length of @data
+ * @adapter: pointer to adapter struct
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int hdd_set_reset_apf_offload(struct hdd_context *hdd_ctx,
+				     struct nlattr **tb,
+				     struct hdd_adapter *adapter)
+{
+	struct sir_apf_set_offload *apf_set_offload;
+	QDF_STATUS status;
+	int prog_len;
+	int ret = 0;
+
+	hdd_enter();
+
+	if (!hdd_conn_is_connected(
+	    WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
+		hdd_err("Not in Connected state!");
+		return -ENOTSUPP;
+	}
+
+	apf_set_offload = qdf_mem_malloc(sizeof(*apf_set_offload));
+	if (!apf_set_offload)
+		return -ENOMEM;
+
+	/* Parse and fetch apf packet size */
+	if (!tb[APF_PACKET_SIZE]) {
+		hdd_err("attr apf packet size failed");
+		ret = -EINVAL;
+		goto fail;
+	}
+	apf_set_offload->total_length = nla_get_u32(tb[APF_PACKET_SIZE]);
+
+	if (!apf_set_offload->total_length) {
+		hdd_debug("APF reset packet filter received");
+		goto post_sme;
+	}
+
+	/* Parse and fetch apf program */
+	if (!tb[APF_PROGRAM]) {
+		hdd_err("attr apf program failed");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	prog_len = nla_len(tb[APF_PROGRAM]);
+	apf_set_offload->program = qdf_mem_malloc(sizeof(uint8_t) * prog_len);
+
+	if (!apf_set_offload->program) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	apf_set_offload->current_length = prog_len;
+	nla_memcpy(apf_set_offload->program, tb[APF_PROGRAM], prog_len);
+	apf_set_offload->session_id = adapter->session_id;
+
+	hdd_debug("APF set instructions");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
+			   apf_set_offload->program, prog_len);
+
+	/* Parse and fetch filter Id */
+	if (!tb[APF_FILTER_ID]) {
+		hdd_err("attr filter id failed");
+		ret = -EINVAL;
+		goto fail;
+	}
+	apf_set_offload->filter_id = nla_get_u32(tb[APF_FILTER_ID]);
+
+	/* Parse and fetch current offset */
+	if (!tb[APF_CURRENT_OFFSET]) {
+		hdd_err("attr current offset failed");
+		ret = -EINVAL;
+		goto fail;
+	}
+	apf_set_offload->current_offset = nla_get_u32(tb[APF_CURRENT_OFFSET]);
+
+post_sme:
+	hdd_debug("Posting APF SET/RESET to SME, session_id: %d APF Version: %d filter ID: %d total_length: %d current_length: %d current offset: %d",
+		  apf_set_offload->session_id, apf_set_offload->version,
+		  apf_set_offload->filter_id, apf_set_offload->total_length,
+		  apf_set_offload->current_length,
+		  apf_set_offload->current_offset);
+
+	status = sme_set_apf_instructions(hdd_ctx->mac_handle, apf_set_offload);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_set_apf_instructions failed(err=%d)", status);
+		ret = -EINVAL;
+		goto fail;
+	}
+	hdd_exit();
+
+fail:
+	if (apf_set_offload->current_length)
+		qdf_mem_free(apf_set_offload->program);
+	qdf_mem_free(apf_set_offload);
+
+	if (!ret)
+		hdd_ctx->apf_enabled_v2 = true;
+
+	return ret;
+}
+
+/**
+ * hdd_enable_disable_apf - Enable or Disable the APF interpreter
+ * @adapter: HDD Adapter
+ * @apf_enable: true: Enable APF Int., false: disable APF Int.
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int
+hdd_enable_disable_apf(struct hdd_adapter *adapter, bool apf_enable)
+{
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	status = sme_set_apf_enable_disable(hdd_adapter_get_mac_handle(adapter),
+					    adapter->session_id, apf_enable);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Unable to post sme apf enable/disable message (status-%d)",
+				status);
+		return -EINVAL;
+	}
+
+	adapter->apf_context.apf_enabled = apf_enable;
+
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * hdd_apf_write_memory - Write into the apf work memory
+ * @adapter: HDD Adapter
+ * @tb: list of attributes
+ *
+ * This function writes code/data into the APF work memory and
+ * provides program length that is passed on to the interpreter.
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int
+hdd_apf_write_memory(struct hdd_adapter *adapter, struct nlattr **tb)
+{
+	struct wmi_apf_write_memory_params write_mem_params = {0};
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	QDF_STATUS status;
+	int ret = 0;
+
+	hdd_enter();
+
+
+	write_mem_params.vdev_id = adapter->session_id;
+	if (adapter->apf_context.apf_enabled) {
+		hdd_err("Cannot get/set when APF interpreter is enabled");
+		return -EINVAL;
+	}
+
+	/* Read program length */
+	if (!tb[APF_PROG_LEN]) {
+		hdd_err("attr program length failed");
+		return -EINVAL;
+	}
+	write_mem_params.program_len = nla_get_u32(tb[APF_PROG_LEN]);
+
+	/* Read APF work memory offset */
+	if (!tb[APF_CURRENT_OFFSET]) {
+		hdd_err("attr apf packet size failed");
+		return -EINVAL;
+	}
+	write_mem_params.addr_offset = nla_get_u32(tb[APF_CURRENT_OFFSET]);
+
+	/* Parse and fetch apf program */
+	if (!tb[APF_PROGRAM]) {
+		hdd_err("attr apf program failed");
+		return -EINVAL;
+	}
+
+	write_mem_params.length = nla_len(tb[APF_PROGRAM]);
+	if (!write_mem_params.length) {
+		hdd_err("Program attr with empty data");
+		return -EINVAL;
+	}
+
+	write_mem_params.buf = qdf_mem_malloc(sizeof(uint8_t)
+						* write_mem_params.length);
+	if (!write_mem_params.buf)
+		return -EINVAL;
+	nla_memcpy(write_mem_params.buf, tb[APF_PROGRAM],
+		   write_mem_params.length);
+
+	write_mem_params.apf_version = hdd_ctx->apf_version;
+
+	status = sme_apf_write_work_memory(hdd_adapter_get_mac_handle(adapter),
+					   &write_mem_params);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Unable to retrieve APF caps");
+		ret = -EINVAL;
+	}
+
+	if (write_mem_params.buf)
+		qdf_mem_free(write_mem_params.buf);
+
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * hdd_apf_read_memory_callback - HDD Callback for the APF read memory
+ *	operation
+ * @context: Hdd context
+ * @evt: APF read memory event response parameters
+ *
+ * Return: 0 on success, errno on failure
+ */
+static void
+hdd_apf_read_memory_callback(void *hdd_context,
+			     struct wmi_apf_read_memory_resp_event_params *evt)
+{
+	struct hdd_context *hdd_ctx = hdd_context;
+	struct hdd_adapter *adapter;
+	struct hdd_apf_context *context;
+	uint8_t *buf_ptr;
+	uint32_t pkt_offset;
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx) || !evt) {
+		hdd_err("HDD context is invalid or event buf(%pK) is null",
+			evt);
+		return;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, evt->vdev_id);
+	if (hdd_validate_adapter(adapter))
+		return;
+	context = &adapter->apf_context;
+
+	if (context->magic != APF_CONTEXT_MAGIC) {
+		/* The caller presumably timed out, nothing to do */
+		hdd_err("Caller timed out or corrupt magic, simply return");
+		return;
+	}
+
+	if (evt->offset <  context->offset) {
+		hdd_err("Offset in read event(%d) smaller than offset in request(%d)!",
+					evt->offset, context->offset);
+		return;
+	}
+
+	/*
+	 * offset in the event is relative to the APF work memory.
+	 * Calculate the packet offset, which gives us the relative
+	 * location in the buffer to start copy into.
+	 */
+	pkt_offset = evt->offset - context->offset;
+
+	if (context->buf_len < pkt_offset + evt->length) {
+		hdd_err("Read chunk exceeding allocated space");
+		return;
+	}
+	buf_ptr = context->buf + pkt_offset;
+
+	qdf_mem_copy(buf_ptr, evt->data, evt->length);
+
+	if (!evt->more_data) {
+		/* Release the caller after last event, clear magic */
+		context->magic = 0;
+		qdf_event_set(&context->qdf_apf_event);
+	}
+
+	hdd_exit();
+}
+
+/**
+ * hdd_apf_read_memory - Read part of the apf work memory
+ * @adapter: HDD Adapter
+ * @tb: list of attributes
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int hdd_apf_read_memory(struct hdd_adapter *adapter, struct nlattr **tb)
+{
+	struct wmi_apf_read_memory_params read_mem_params = {0};
+	struct hdd_apf_context *context = &adapter->apf_context;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	QDF_STATUS status;
+	unsigned long nl_buf_len = NLMSG_HDRLEN;
+	int ret = 0;
+	struct sk_buff *skb = NULL;
+	uint8_t *bufptr;
+
+	hdd_enter();
+
+	if (context->apf_enabled) {
+		hdd_err("Cannot get/set while interpreter is enabled");
+		return -EINVAL;
+	}
+
+	read_mem_params.vdev_id = adapter->session_id;
+
+	/* Read APF work memory offset */
+	if (!tb[APF_CURRENT_OFFSET]) {
+		hdd_err("attr apf memory offset failed");
+		return -EINVAL;
+	}
+	read_mem_params.addr_offset = nla_get_u32(tb[APF_CURRENT_OFFSET]);
+
+	/* Read length */
+	if (!tb[APF_PACKET_SIZE]) {
+		hdd_err("attr apf packet size failed");
+		return -EINVAL;
+	}
+	read_mem_params.length = nla_get_u32(tb[APF_PACKET_SIZE]);
+	if (!read_mem_params.length) {
+		hdd_err("apf read length cannot be zero!");
+		return -EINVAL;
+	}
+	bufptr = qdf_mem_malloc(read_mem_params.length);
+	if (!bufptr)
+		return -ENOMEM;
+
+	qdf_event_reset(&context->qdf_apf_event);
+	context->offset = read_mem_params.addr_offset;
+
+	context->buf = bufptr;
+	context->buf_len = read_mem_params.length;
+	context->magic = APF_CONTEXT_MAGIC;
+
+	status = sme_apf_read_work_memory(hdd_adapter_get_mac_handle(adapter),
+					  &read_mem_params,
+					  hdd_apf_read_memory_callback);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Unable to post sme APF read memory message (status-%d)",
+				status);
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	/* request was sent -- wait for the response */
+	status = qdf_wait_for_event_completion(&context->qdf_apf_event,
+					       WLAN_WAIT_TIME_APF_READ_MEM);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Target response timed out");
+		context->magic = 0;
+		ret = -ETIMEDOUT;
+		goto fail;
+	}
+
+	nl_buf_len += sizeof(uint32_t) + NLA_HDRLEN;
+	nl_buf_len += context->buf_len + NLA_HDRLEN;
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	if (nla_put_u32(skb, APF_SUBCMD, QCA_WLAN_READ_PACKET_FILTER) ||
+	    nla_put(skb, APF_PROGRAM, read_mem_params.length, context->buf)) {
+		hdd_err("put fail");
+		kfree_skb(skb);
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	cfg80211_vendor_cmd_reply(skb);
+fail:
+	if (context->buf) {
+		qdf_mem_free(context->buf);
+		context->buf = NULL;
+	}
+
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_apf_offload() - Set/Reset to APF Offload
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_apf_offload(struct wiphy *wiphy,
+				struct wireless_dev *wdev,
+				const void *data, int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter =  WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[APF_MAX + 1];
+	int ret_val = 0, apf_subcmd;
+	struct hdd_apf_context *context;
+
+	hdd_enter();
+
+	if (!adapter) {
+		hdd_err("Adapter is null");
+		return -EINVAL;
+	}
+
+	context = &adapter->apf_context;
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		return ret_val;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (!ucfg_pmo_is_apf_enabled(hdd_ctx->psoc)) {
+		hdd_err("APF is not supported or disabled through INI");
+		return -ENOTSUPP;
+	}
+
+	if (!(adapter->device_mode == QDF_STA_MODE ||
+	      adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
+		hdd_err("APF only supported in STA or P2P CLI modes!");
+		return -ENOTSUPP;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, APF_MAX, data, data_len,
+				    wlan_hdd_apf_offload_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (!tb[APF_SUBCMD]) {
+		hdd_err("attr apf sub-command failed");
+		return -EINVAL;
+	}
+	apf_subcmd = nla_get_u32(tb[APF_SUBCMD]);
+
+	/* Do not allow simultaneous new APF commands on the same adapter */
+	qdf_spin_lock(&context->lock);
+	if (context->cmd_in_progress) {
+		qdf_spin_unlock(&context->lock);
+		hdd_err("Another cmd in progress for same session!");
+		return -EAGAIN;
+	}
+	context->cmd_in_progress = true;
+	qdf_spin_unlock(&context->lock);
+
+	switch (apf_subcmd) {
+	/* Legacy APF sub-commands */
+	case QCA_WLAN_SET_PACKET_FILTER:
+		ret_val = hdd_set_reset_apf_offload(hdd_ctx, tb,
+						    adapter);
+		break;
+	case QCA_WLAN_GET_PACKET_FILTER:
+		ret_val = hdd_get_apf_capabilities(hdd_ctx);
+		break;
+
+	/* APF 3.0 sub-commands */
+	case QCA_WLAN_WRITE_PACKET_FILTER:
+		ret_val = hdd_apf_write_memory(adapter, tb);
+		break;
+	case QCA_WLAN_READ_PACKET_FILTER:
+		ret_val = hdd_apf_read_memory(adapter, tb);
+		break;
+	case QCA_WLAN_ENABLE_PACKET_FILTER:
+		ret_val = hdd_enable_disable_apf(adapter, true);
+		break;
+	case QCA_WLAN_DISABLE_PACKET_FILTER:
+		ret_val = hdd_enable_disable_apf(adapter, false);
+		break;
+	default:
+		hdd_err("Unknown APF Sub-command: %d", apf_subcmd);
+		ret_val = -ENOTSUPP;
+	}
+
+	qdf_spin_lock(&context->lock);
+	context->cmd_in_progress = false;
+	qdf_spin_unlock(&context->lock);
+
+	return ret_val;
+}
+
+int
+wlan_hdd_cfg80211_apf_offload(struct wiphy *wiphy, struct wireless_dev *wdev,
+			      const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_apf_offload(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
new file mode 100644
index 0000000..91d1fb6
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -0,0 +1,5673 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_assoc.c
+ *
+ *  WLAN Host Device Driver implementation
+ *
+ */
+
+#include "wlan_hdd_includes.h"
+#include <ani_global.h>
+#include "dot11f.h"
+#include "wlan_hdd_power.h"
+#include "wlan_hdd_trace.h"
+#include <linux/ieee80211.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <net/cfg80211.h>
+#include "wlan_hdd_cfg80211.h"
+#include "csr_inside_api.h"
+#include "wlan_hdd_p2p.h"
+#include "wlan_hdd_tdls.h"
+#include "sme_api.h"
+#include "wlan_hdd_hostapd.h"
+#include <wlan_hdd_green_ap.h>
+#include <wlan_hdd_ipa.h>
+#include "wlan_hdd_lpass.h"
+#include <wlan_logging_sock_svc.h>
+#include <cds_sched.h>
+#include "wlan_policy_mgr_api.h"
+#include <cds_utils.h>
+#include "sme_power_save_api.h"
+#include "wlan_hdd_napi.h"
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_flow_ctrl_legacy.h>
+#include <cdp_txrx_peer_ops.h>
+#include <cdp_txrx_misc.h>
+#include <cdp_txrx_ctrl.h>
+#include <wlan_logging_sock_svc.h>
+#include <wlan_hdd_object_manager.h>
+#include <cdp_txrx_handle.h>
+#include "wlan_pmo_ucfg_api.h"
+#include "wlan_hdd_tsf.h"
+#include "wlan_utility.h"
+#include "wlan_p2p_ucfg_api.h"
+#include "wlan_ipa_ucfg_api.h"
+#include "wlan_hdd_stats.h"
+#include "wlan_hdd_scan.h"
+
+#include "wlan_hdd_nud_tracking.h"
+/* These are needed to recognize WPA and RSN suite types */
+#define HDD_WPA_OUI_SIZE 4
+#define HDD_RSN_OUI_SIZE 4
+uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 };
+uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 };
+uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
+uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 };
+uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 };
+uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 };
+
+#ifdef FEATURE_WLAN_ESE
+/* CCKM */
+uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
+/* CCKM */
+uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
+#endif /* FEATURE_WLAN_ESE */
+
+/* group cipher */
+uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 };
+
+/* WEP-40 or RSN */
+uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 };
+
+/* TKIP or RSN-PSK */
+uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 };
+
+/* Reserved */
+uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 };
+
+/* AES-CCMP */
+uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 };
+
+/* WEP-104 */
+uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
+
+#ifdef WLAN_FEATURE_11W
+/* RSN-PSK-SHA256 */
+uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 };
+
+/* RSN-8021X-SHA256 */
+uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
+#endif
+
+/* AES-GCMP-128 */
+uint8_t ccp_rsn_oui09[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x08 };
+
+/* AES-GCMP-256 */
+uint8_t ccp_rsn_oui0a[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x09 };
+#ifdef WLAN_FEATURE_FILS_SK
+uint8_t ccp_rsn_oui_0e[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0E};
+uint8_t ccp_rsn_oui_0f[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0F};
+uint8_t ccp_rsn_oui_10[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x10};
+uint8_t ccp_rsn_oui_11[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x11};
+#endif
+uint8_t ccp_rsn_oui_12[HDD_RSN_OUI_SIZE] = {0x50, 0x6F, 0x9A, 0x02};
+uint8_t ccp_rsn_oui_0b[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0B};
+uint8_t ccp_rsn_oui_0c[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0C};
+
+/* OWE https://tools.ietf.org/html/rfc8110 */
+uint8_t ccp_rsn_oui_18[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x12};
+
+#ifdef WLAN_FEATURE_SAE
+uint8_t ccp_rsn_oui_80[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x08};
+uint8_t ccp_rsn_oui_90[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x09};
+#endif
+
+/* Offset where the EID-Len-IE, start. */
+#define FT_ASSOC_RSP_IES_OFFSET 6  /* Capability(2) + AID(2) + Status Code(2) */
+#define FT_ASSOC_REQ_IES_OFFSET 4  /* Capability(2) + LI(2) */
+
+#define BEACON_FRAME_IES_OFFSET 12
+#define HDD_PEER_AUTHORIZE_WAIT 10
+
+/**
+ * beacon_filter_table - table of IEs used for beacon filtering
+ */
+static const int beacon_filter_table[] = {
+	SIR_MAC_DS_PARAM_SET_EID,
+	SIR_MAC_ERP_INFO_EID,
+	SIR_MAC_EDCA_PARAM_SET_EID,
+	SIR_MAC_QOS_CAPABILITY_EID,
+	SIR_MAC_HT_INFO_EID,
+	SIR_MAC_VHT_OPMODE_EID,
+	SIR_MAC_VHT_OPERATION_EID,
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+	/*
+	 * EID: 221 vendor IE is being used temporarily by 11AX
+	 * bss-color-change IE till it gets any fixed number. This
+	 * vendor EID needs to be replaced with bss-color-change IE
+	 * number.
+	 */
+	SIR_MAC_EID_VENDOR,
+#endif
+};
+
+#if defined(WLAN_FEATURE_SAE) && \
+		defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+/**
+ * wlan_hdd_sae_callback() - Sends SAE info to supplicant
+ * @adapter: pointer adapter context
+ * @roam_info: pointer to roam info
+ *
+ * This API is used to send required SAE info to trigger SAE in supplicant.
+ *
+ * Return: None
+ */
+static void wlan_hdd_sae_callback(struct hdd_adapter *adapter,
+				  struct csr_roam_info *roam_info)
+{
+	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
+	int flags;
+	struct sir_sae_info *sae_info = roam_info->sae_info;
+	struct cfg80211_external_auth_params params = {0};
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	if (!sae_info) {
+		hdd_err("SAE info in NULL");
+		return;
+	}
+
+	flags = cds_get_gfp_flags();
+
+	params.key_mgmt_suite = 0x00;
+	params.key_mgmt_suite |= 0x0F << 8;
+	params.key_mgmt_suite |= 0xAC << 16;
+	params.key_mgmt_suite |= 0x8 << 24;
+
+	params.action = NL80211_EXTERNAL_AUTH_START;
+	qdf_mem_copy(params.bssid, sae_info->peer_mac_addr.bytes,
+		     QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(params.ssid.ssid, sae_info->ssid.ssId,
+		     sae_info->ssid.length);
+	params.ssid.ssid_len = sae_info->ssid.length;
+
+	cfg80211_external_auth_request(adapter->dev, &params, flags);
+	hdd_debug("SAE: sent cmd");
+}
+#else
+static inline void wlan_hdd_sae_callback(struct hdd_adapter *adapter,
+					 struct csr_roam_info *roam_info)
+{ }
+#endif
+
+/**
+ * hdd_conn_set_authenticated() - set authentication state
+ * @adapter: pointer to the adapter
+ * @auth_state: authentication state
+ *
+ * This function updates the global HDD station context
+ * authentication state.
+ *
+ * Return: none
+ */
+static void
+hdd_conn_set_authenticated(struct hdd_adapter *adapter, uint8_t auth_state)
+{
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	char *auth_time;
+	uint32_t time_buffer_size;
+
+	/* save the new connection state */
+	hdd_debug("Authenticated state Changed from oldState:%d to State:%d",
+		   sta_ctx->conn_info.uIsAuthenticated, auth_state);
+	sta_ctx->conn_info.uIsAuthenticated = auth_state;
+
+	auth_time = sta_ctx->conn_info.auth_time;
+	time_buffer_size = sizeof(sta_ctx->conn_info.auth_time);
+
+	if (auth_state)
+		qdf_get_time_of_the_day_in_hr_min_sec_usec(auth_time,
+							   time_buffer_size);
+	else
+		qdf_mem_set(auth_time, 0x00, time_buffer_size);
+
+}
+
+/**
+ * hdd_conn_set_connection_state() - set 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(struct hdd_adapter *adapter,
+				   eConnectionState conn_state)
+{
+	struct hdd_station_ctx *hdd_sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	char *connect_time;
+	uint32_t time_buffer_size;
+
+	/* save the new connection state */
+	hdd_debug("Changed conn state from old:%d to new:%d for dev %s",
+		  hdd_sta_ctx->conn_info.connState, conn_state,
+		  adapter->dev->name);
+
+	hdd_tsf_notify_wlan_state_change(adapter,
+					 hdd_sta_ctx->conn_info.connState,
+					 conn_state);
+	hdd_sta_ctx->conn_info.connState = conn_state;
+
+	connect_time = hdd_sta_ctx->conn_info.connect_time;
+	time_buffer_size = sizeof(hdd_sta_ctx->conn_info.connect_time);
+	if (conn_state == eConnectionState_Associated)
+		qdf_get_time_of_the_day_in_hr_min_sec_usec(connect_time,
+							   time_buffer_size);
+	else
+		qdf_mem_set(connect_time, 0x00, time_buffer_size);
+
+}
+
+/**
+ * hdd_conn_get_connection_state() - get connection state
+ * @adapter: pointer to the adapter
+ * @pConnState: pointer to connection state
+ *
+ * This function updates the global HDD station context connection state.
+ *
+ * Return: true if (Infra Associated or IBSS Connected)
+ *	and sets output parameter pConnState;
+ *	false otherwise
+ */
+static inline bool
+hdd_conn_get_connection_state(struct hdd_station_ctx *sta_ctx,
+			      eConnectionState *out_state)
+{
+	eConnectionState state = sta_ctx->conn_info.connState;
+
+	if (out_state)
+		*out_state = state;
+
+	switch (state) {
+	case eConnectionState_Associated:
+	case eConnectionState_IbssConnected:
+	case eConnectionState_IbssDisconnected:
+	case eConnectionState_NdiConnected:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool hdd_is_connecting(struct hdd_station_ctx *hdd_sta_ctx)
+{
+	return hdd_sta_ctx->conn_info.connState ==
+		eConnectionState_Connecting;
+}
+
+bool hdd_conn_is_connected(struct hdd_station_ctx *sta_ctx)
+{
+	return hdd_conn_get_connection_state(sta_ctx, NULL);
+}
+
+bool hdd_adapter_is_connected_sta(struct hdd_adapter *adapter)
+{
+	switch (adapter->device_mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_NDI_MODE:
+		return hdd_conn_is_connected(&adapter->session.station);
+	default:
+		return false;
+	}
+}
+
+enum band_info hdd_conn_get_connected_band(struct hdd_station_ctx *sta_ctx)
+{
+	uint8_t staChannel = 0;
+
+	if (eConnectionState_Associated == sta_ctx->conn_info.connState)
+		staChannel = sta_ctx->conn_info.operationChannel;
+
+	if (staChannel > 0 && staChannel < 14)
+		return BAND_2G;
+	else if (staChannel >= 36 && staChannel <= 184)
+		return BAND_5G;
+	else   /* If station is not connected return as BAND_ALL */
+		return BAND_ALL;
+}
+
+/**
+ * hdd_conn_get_connected_cipher_algo() - get current connection cipher type
+ * @sta_ctx: pointer to global HDD Station context
+ * @pConnectedCipherAlgo: pointer to connected cipher algo
+ *
+ * Return: false if any errors encountered, true otherwise
+ */
+static inline bool
+hdd_conn_get_connected_cipher_algo(struct hdd_station_ctx *sta_ctx,
+				   eCsrEncryptionType *pConnectedCipherAlgo)
+{
+	bool connected = false;
+
+	connected = hdd_conn_get_connection_state(sta_ctx, NULL);
+
+	if (pConnectedCipherAlgo)
+		*pConnectedCipherAlgo = sta_ctx->conn_info.ucEncryptionType;
+
+	return connected;
+}
+
+struct hdd_adapter *hdd_get_sta_connection_in_progress(
+			struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter = NULL;
+	struct hdd_station_ctx *hdd_sta_ctx;
+
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return NULL;
+	}
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		if ((QDF_STA_MODE == adapter->device_mode) ||
+		    (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
+		    (QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
+			if (eConnectionState_Connecting ==
+			    hdd_sta_ctx->conn_info.connState) {
+				hdd_debug("session_id %d: Connection is in progress",
+					  adapter->session_id);
+				return adapter;
+			} else if ((eConnectionState_Associated ==
+				   hdd_sta_ctx->conn_info.connState) &&
+				   sme_is_sta_key_exchange_in_progress(
+							hdd_ctx->mac_handle,
+							adapter->session_id)) {
+				hdd_debug("session_id %d: Key exchange is in progress",
+					  adapter->session_id);
+				return adapter;
+			}
+		}
+	}
+	return NULL;
+}
+
+/**
+ * hdd_remove_beacon_filter() - remove beacon filter
+ * @adapter: Pointer to the hdd adapter
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int hdd_remove_beacon_filter(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	status = sme_remove_beacon_filter(hdd_ctx->mac_handle,
+					  adapter->session_id);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_remove_beacon_filter() failed");
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_add_beacon_filter() - add beacon filter
+ * @adapter: Pointer to the hdd adapter
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int hdd_add_beacon_filter(struct hdd_adapter *adapter)
+{
+	int i;
+	uint32_t ie_map[SIR_BCN_FLT_MAX_ELEMS_IE_LIST] = {0};
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	for (i = 0; i < ARRAY_SIZE(beacon_filter_table); i++)
+		qdf_set_bit((beacon_filter_table[i]),
+				(unsigned long int *)ie_map);
+
+	status = sme_add_beacon_filter(hdd_ctx->mac_handle,
+				       adapter->session_id, ie_map);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_add_beacon_filter() failed");
+		return -EFAULT;
+	}
+	return 0;
+}
+
+void hdd_copy_ht_caps(struct ieee80211_ht_cap *hdd_ht_cap,
+		      tDot11fIEHTCaps *roam_ht_cap)
+
+{
+	uint32_t i, temp_ht_cap;
+
+	qdf_mem_zero(hdd_ht_cap, sizeof(struct ieee80211_ht_cap));
+
+	if (roam_ht_cap->advCodingCap)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
+	if (roam_ht_cap->supportedChannelWidthSet)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+	temp_ht_cap = roam_ht_cap->mimoPowerSave &
+	    (IEEE80211_HT_CAP_SM_PS >> IEEE80211_HT_CAP_SM_PS_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->cap_info |=
+			temp_ht_cap << IEEE80211_HT_CAP_SM_PS_SHIFT;
+	if (roam_ht_cap->greenField)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_GRN_FLD;
+	if (roam_ht_cap->shortGI20MHz)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_20;
+	if (roam_ht_cap->shortGI40MHz)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_40;
+	if (roam_ht_cap->txSTBC)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_TX_STBC;
+	temp_ht_cap = roam_ht_cap->rxSTBC & (IEEE80211_HT_CAP_RX_STBC >>
+	    IEEE80211_HT_CAP_RX_STBC_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->cap_info |=
+			temp_ht_cap << IEEE80211_HT_CAP_RX_STBC_SHIFT;
+	if (roam_ht_cap->delayedBA)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DELAY_BA;
+	if (roam_ht_cap->maximalAMSDUsize)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_MAX_AMSDU;
+	if (roam_ht_cap->dsssCckMode40MHz)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DSSSCCK40;
+	if (roam_ht_cap->psmp)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_RESERVED;
+	if (roam_ht_cap->stbcControlFrame)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_40MHZ_INTOLERANT;
+	if (roam_ht_cap->lsigTXOPProtection)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
+
+	/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */
+	if (roam_ht_cap->maxRxAMPDUFactor)
+		hdd_ht_cap->ampdu_params_info |=
+			IEEE80211_HT_AMPDU_PARM_FACTOR;
+	temp_ht_cap = roam_ht_cap->mpduDensity &
+	    (IEEE80211_HT_AMPDU_PARM_DENSITY >>
+	     IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->ampdu_params_info |=
+		temp_ht_cap << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT;
+
+	/* 802.11n HT extended capabilities masks */
+	if (roam_ht_cap->pco)
+		hdd_ht_cap->extended_ht_cap_info |=
+			IEEE80211_HT_EXT_CAP_PCO;
+	temp_ht_cap = roam_ht_cap->transitionTime &
+	    (IEEE80211_HT_EXT_CAP_PCO_TIME >>
+	    IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->extended_ht_cap_info |=
+			temp_ht_cap << IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT;
+	temp_ht_cap = roam_ht_cap->mcsFeedback &
+	    (IEEE80211_HT_EXT_CAP_MCS_FB >> IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->extended_ht_cap_info |=
+			temp_ht_cap << IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT;
+
+	/* tx_bf_cap_info capabilities */
+	if (roam_ht_cap->txBF)
+		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_BF;
+	if (roam_ht_cap->rxStaggeredSounding)
+		hdd_ht_cap->tx_BF_cap_info |=
+			TX_BF_CAP_INFO_RX_STAG_RED_SOUNDING;
+	if (roam_ht_cap->txStaggeredSounding)
+		hdd_ht_cap->tx_BF_cap_info |=
+			TX_BF_CAP_INFO_TX_STAG_RED_SOUNDING;
+	if (roam_ht_cap->rxZLF)
+		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_RX_ZFL;
+	if (roam_ht_cap->txZLF)
+		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_ZFL;
+	if (roam_ht_cap->implicitTxBF)
+		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_IMP_TX_BF;
+	temp_ht_cap = roam_ht_cap->calibration &
+	    (TX_BF_CAP_INFO_CALIBRATION >> TX_BF_CAP_INFO_CALIBRATION_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap << TX_BF_CAP_INFO_CALIBRATION_SHIFT;
+	if (roam_ht_cap->explicitCSITxBF)
+		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_EXP_CSIT_BF;
+	if (roam_ht_cap->explicitUncompressedSteeringMatrix)
+		hdd_ht_cap->tx_BF_cap_info |=
+			TX_BF_CAP_INFO_EXP_UNCOMP_STEER_MAT;
+	temp_ht_cap = roam_ht_cap->explicitBFCSIFeedback &
+	    (TX_BF_CAP_INFO_EXP_BF_CSI_FB >>
+	     TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap << TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT;
+	temp_ht_cap =
+	    roam_ht_cap->explicitUncompressedSteeringMatrixFeedback &
+	    (TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT >>
+	     TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap <<
+			TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT;
+	temp_ht_cap =
+	    roam_ht_cap->explicitCompressedSteeringMatrixFeedback &
+	    (TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB >>
+	     TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap <<
+				TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT;
+	temp_ht_cap = roam_ht_cap->csiNumBFAntennae &
+	    (TX_BF_CAP_INFO_CSI_NUM_BF_ANT >>
+	     TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap << TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT;
+	temp_ht_cap = roam_ht_cap->uncompressedSteeringMatrixBFAntennae &
+	    (TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT >>
+	     TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap <<
+				TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT;
+	temp_ht_cap = roam_ht_cap->compressedSteeringMatrixBFAntennae &
+	    (TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT >>
+	     TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap <<
+				TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT;
+
+	/* antenna selection */
+	if (roam_ht_cap->antennaSelection)
+		hdd_ht_cap->antenna_selection_info |= ANTENNA_SEL_INFO;
+	if (roam_ht_cap->explicitCSIFeedbackTx)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_EXP_CSI_FB_TX;
+	if (roam_ht_cap->antennaIndicesFeedbackTx)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_ANT_ID_FB_TX;
+	if (roam_ht_cap->explicitCSIFeedback)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_EXP_CSI_FB;
+	if (roam_ht_cap->antennaIndicesFeedback)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_ANT_ID_FB;
+	if (roam_ht_cap->rxAS)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_RX_AS;
+	if (roam_ht_cap->txSoundingPPDUs)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_TX_SOUNDING_PPDU;
+
+	/* mcs data rate */
+	for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; ++i)
+		hdd_ht_cap->mcs.rx_mask[i] =
+			roam_ht_cap->supportedMCSSet[i];
+	hdd_ht_cap->mcs.rx_highest =
+			((short) (roam_ht_cap->supportedMCSSet[11]) << 8) |
+			((short) (roam_ht_cap->supportedMCSSet[10]));
+	hdd_ht_cap->mcs.tx_params =
+			roam_ht_cap->supportedMCSSet[12];
+}
+
+#define VHT_CAP_MAX_MPDU_LENGTH_MASK 0x00000003
+#define VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT 2
+#define VHT_CAP_RXSTBC_MASK_SHIFT 8
+#define VHT_CAP_BEAMFORMEE_STS_SHIFT 13
+#define VHT_CAP_BEAMFORMEE_STS_MASK \
+	(0x0000e000 >> VHT_CAP_BEAMFORMEE_STS_SHIFT)
+#define VHT_CAP_SOUNDING_DIMENSIONS_SHIFT 16
+#define VHT_CAP_SOUNDING_DIMENSIONS_MASK \
+	(0x00070000 >> VHT_CAP_SOUNDING_DIMENSIONS_SHIFT)
+#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT 23
+#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \
+	(0x03800000 >> VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT)
+#define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT 26
+
+void hdd_copy_vht_caps(struct ieee80211_vht_cap *hdd_vht_cap,
+		       tDot11fIEVHTCaps *roam_vht_cap)
+{
+	uint32_t temp_vht_cap;
+
+	qdf_mem_zero(hdd_vht_cap, sizeof(struct ieee80211_vht_cap));
+
+	temp_vht_cap = roam_vht_cap->maxMPDULen & VHT_CAP_MAX_MPDU_LENGTH_MASK;
+	hdd_vht_cap->vht_cap_info |= temp_vht_cap;
+	temp_vht_cap = roam_vht_cap->supportedChannelWidthSet &
+		(IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK >>
+			VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT);
+	if (temp_vht_cap) {
+		if (roam_vht_cap->supportedChannelWidthSet &
+		    (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ >>
+			VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT))
+			hdd_vht_cap->vht_cap_info |=
+				temp_vht_cap <<
+				IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
+		if (roam_vht_cap->supportedChannelWidthSet &
+		    (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ >>
+			VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT))
+			hdd_vht_cap->vht_cap_info |=
+			temp_vht_cap <<
+			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
+	}
+	if (roam_vht_cap->ldpcCodingCap)
+		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_RXLDPC;
+	if (roam_vht_cap->shortGI80MHz)
+		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_80;
+	if (roam_vht_cap->shortGI160and80plus80MHz)
+		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_160;
+	if (roam_vht_cap->txSTBC)
+		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_TXSTBC;
+	temp_vht_cap = roam_vht_cap->rxSTBC & (IEEE80211_VHT_CAP_RXSTBC_MASK >>
+		VHT_CAP_RXSTBC_MASK_SHIFT);
+	if (temp_vht_cap)
+		hdd_vht_cap->vht_cap_info |=
+			temp_vht_cap << VHT_CAP_RXSTBC_MASK_SHIFT;
+	if (roam_vht_cap->suBeamFormerCap)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
+	if (roam_vht_cap->suBeamformeeCap)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
+	temp_vht_cap = roam_vht_cap->csnofBeamformerAntSup &
+			(VHT_CAP_BEAMFORMEE_STS_MASK);
+	if (temp_vht_cap)
+		hdd_vht_cap->vht_cap_info |=
+			temp_vht_cap << VHT_CAP_BEAMFORMEE_STS_SHIFT;
+	temp_vht_cap = roam_vht_cap->numSoundingDim &
+			(VHT_CAP_SOUNDING_DIMENSIONS_MASK);
+	if (temp_vht_cap)
+		hdd_vht_cap->vht_cap_info |=
+			temp_vht_cap << VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
+	if (roam_vht_cap->muBeamformerCap)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
+	if (roam_vht_cap->muBeamformeeCap)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
+	if (roam_vht_cap->vhtTXOPPS)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_VHT_TXOP_PS;
+	if (roam_vht_cap->htcVHTCap)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_HTC_VHT;
+	temp_vht_cap = roam_vht_cap->maxAMPDULenExp &
+			(VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK);
+	if (temp_vht_cap)
+		hdd_vht_cap->vht_cap_info |=
+			temp_vht_cap <<
+			VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT;
+	temp_vht_cap = roam_vht_cap->vhtLinkAdaptCap &
+		(IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB >>
+		 VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT);
+	if (temp_vht_cap)
+		hdd_vht_cap->vht_cap_info |= temp_vht_cap <<
+			VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT;
+	if (roam_vht_cap->rxAntPattern)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
+	if (roam_vht_cap->txAntPattern)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
+	hdd_vht_cap->supp_mcs.rx_mcs_map = roam_vht_cap->rxMCSMap;
+	hdd_vht_cap->supp_mcs.rx_highest =
+		((uint16_t)roam_vht_cap->rxHighSupDataRate);
+	hdd_vht_cap->supp_mcs.tx_mcs_map = roam_vht_cap->txMCSMap;
+	hdd_vht_cap->supp_mcs.tx_highest =
+		((uint16_t)roam_vht_cap->txSupDataRate);
+}
+
+/* ht param */
+#define HT_PARAM_CONTROLLED_ACCESS_ONLY 0x10
+#define HT_PARAM_SERVICE_INT_GRAN 0xe0
+#define HT_PARAM_SERVICE_INT_GRAN_SHIFT 5
+
+/* operatinon mode */
+#define HT_OP_MODE_TX_BURST_LIMIT 0x0008
+
+/* stbc_param */
+#define HT_STBC_PARAM_MCS 0x007f
+
+/**
+ * hdd_copy_ht_operation()- copy HT operation element from roam info to
+ *  hdd station context.
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_copy_ht_operation(struct hdd_station_ctx *hdd_sta_ctx,
+					    struct csr_roam_info *roam_info)
+{
+	tDot11fIEHTInfo *roam_ht_ops = &roam_info->ht_operation;
+	struct ieee80211_ht_operation *hdd_ht_ops =
+		&hdd_sta_ctx->conn_info.ht_operation;
+	uint32_t i, temp_ht_ops;
+
+	qdf_mem_zero(hdd_ht_ops, sizeof(struct ieee80211_ht_operation));
+
+	hdd_ht_ops->primary_chan = roam_ht_ops->primaryChannel;
+
+	/* HT_PARAMS */
+	temp_ht_ops = roam_ht_ops->secondaryChannelOffset &
+		IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
+	if (temp_ht_ops)
+		hdd_ht_ops->ht_param |= temp_ht_ops;
+	else
+		hdd_ht_ops->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+	if (roam_ht_ops->recommendedTxWidthSet)
+		hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
+	if (roam_ht_ops->rifsMode)
+		hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_RIFS_MODE;
+	if (roam_ht_ops->controlledAccessOnly)
+		hdd_ht_ops->ht_param |= HT_PARAM_CONTROLLED_ACCESS_ONLY;
+	temp_ht_ops = roam_ht_ops->serviceIntervalGranularity &
+		(HT_PARAM_SERVICE_INT_GRAN >> HT_PARAM_SERVICE_INT_GRAN_SHIFT);
+	if (temp_ht_ops)
+		hdd_ht_ops->ht_param |= temp_ht_ops <<
+			HT_PARAM_SERVICE_INT_GRAN_SHIFT;
+
+	/* operation mode */
+	temp_ht_ops = roam_ht_ops->opMode &
+			IEEE80211_HT_OP_MODE_PROTECTION;
+	switch (temp_ht_ops) {
+	case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER;
+		break;
+	case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
+		break;
+	case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
+		break;
+	case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
+	default:
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+	}
+	if (roam_ht_ops->nonGFDevicesPresent)
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT;
+	if (roam_ht_ops->transmitBurstLimit)
+		hdd_ht_ops->operation_mode |=
+			HT_OP_MODE_TX_BURST_LIMIT;
+	if (roam_ht_ops->obssNonHTStaPresent)
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
+
+	/* stbc_param */
+	temp_ht_ops = roam_ht_ops->basicSTBCMCS &
+			HT_STBC_PARAM_MCS;
+	if (temp_ht_ops)
+		hdd_ht_ops->stbc_param |= temp_ht_ops;
+	if (roam_ht_ops->dualCTSProtection)
+		hdd_ht_ops->stbc_param |=
+			IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT;
+	if (roam_ht_ops->secondaryBeacon)
+		hdd_ht_ops->stbc_param |=
+			IEEE80211_HT_STBC_PARAM_STBC_BEACON;
+	if (roam_ht_ops->lsigTXOPProtectionFullSupport)
+		hdd_ht_ops->stbc_param |=
+			IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT;
+	if (roam_ht_ops->pcoActive)
+		hdd_ht_ops->stbc_param |=
+			IEEE80211_HT_STBC_PARAM_PCO_ACTIVE;
+	if (roam_ht_ops->pcoPhase)
+		hdd_ht_ops->stbc_param |=
+			IEEE80211_HT_STBC_PARAM_PCO_PHASE;
+
+	/* basic MCs set */
+	for (i = 0; i < 16; ++i)
+		hdd_ht_ops->basic_set[i] =
+			roam_ht_ops->basicMCSSet[i];
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+static void hdd_copy_vht_center_freq(struct ieee80211_vht_operation *ieee_ops,
+				     tDot11fIEVHTOperation *roam_ops)
+{
+	ieee_ops->center_freq_seg0_idx = roam_ops->chanCenterFreqSeg1;
+	ieee_ops->center_freq_seg1_idx = roam_ops->chanCenterFreqSeg2;
+}
+#else
+static void hdd_copy_vht_center_freq(struct ieee80211_vht_operation *ieee_ops,
+				     tDot11fIEVHTOperation *roam_ops)
+{
+	ieee_ops->center_freq_seg1_idx = roam_ops->chanCenterFreqSeg1;
+	ieee_ops->center_freq_seg2_idx = roam_ops->chanCenterFreqSeg2;
+}
+#endif /* KERNEL_VERSION(4, 12, 0) */
+
+/**
+ * hdd_copy_vht_operation()- copy VHT operations element from roam info to
+ *  hdd station context.
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_copy_vht_operation(struct hdd_station_ctx *hdd_sta_ctx,
+					      struct csr_roam_info *roam_info)
+{
+	tDot11fIEVHTOperation *roam_vht_ops = &roam_info->vht_operation;
+	struct ieee80211_vht_operation *hdd_vht_ops =
+		&hdd_sta_ctx->conn_info.vht_operation;
+
+	qdf_mem_zero(hdd_vht_ops, sizeof(struct ieee80211_vht_operation));
+
+	hdd_vht_ops->chan_width = roam_vht_ops->chanWidth;
+	hdd_copy_vht_center_freq(hdd_vht_ops, roam_vht_ops);
+	hdd_vht_ops->basic_mcs_set = roam_vht_ops->basicMCSSet;
+}
+
+
+/**
+ * hdd_save_bss_info() - save connection info in hdd sta ctx
+ * @adapter: Pointer to adapter
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_save_bss_info(struct hdd_adapter *adapter,
+						struct csr_roam_info *roam_info)
+{
+	struct hdd_station_ctx *hdd_sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	hdd_sta_ctx->conn_info.freq = cds_chan_to_freq(
+		hdd_sta_ctx->conn_info.operationChannel);
+	if (roam_info->vht_caps.present) {
+		hdd_sta_ctx->conn_info.conn_flag.vht_present = true;
+		hdd_copy_vht_caps(&hdd_sta_ctx->conn_info.vht_caps,
+				  &roam_info->vht_caps);
+	} else {
+		hdd_sta_ctx->conn_info.conn_flag.vht_present = false;
+	}
+	if (roam_info->ht_caps.present) {
+		hdd_sta_ctx->conn_info.conn_flag.ht_present = true;
+		hdd_copy_ht_caps(&hdd_sta_ctx->conn_info.ht_caps,
+				 &roam_info->ht_caps);
+	} else {
+		hdd_sta_ctx->conn_info.conn_flag.ht_present = false;
+	}
+	if (roam_info->reassoc)
+		hdd_sta_ctx->conn_info.roam_count++;
+	if (roam_info->hs20vendor_ie.present) {
+		hdd_sta_ctx->conn_info.conn_flag.hs20_present = true;
+		qdf_mem_copy(&hdd_sta_ctx->conn_info.hs20vendor_ie,
+			     &roam_info->hs20vendor_ie,
+			     sizeof(roam_info->hs20vendor_ie));
+	} else {
+		hdd_sta_ctx->conn_info.conn_flag.hs20_present = false;
+	}
+	if (roam_info->ht_operation.present) {
+		hdd_sta_ctx->conn_info.conn_flag.ht_op_present = true;
+		hdd_copy_ht_operation(hdd_sta_ctx, roam_info);
+	} else {
+		hdd_sta_ctx->conn_info.conn_flag.ht_op_present = false;
+	}
+	if (roam_info->vht_operation.present) {
+		hdd_sta_ctx->conn_info.conn_flag.vht_op_present = true;
+		hdd_copy_vht_operation(hdd_sta_ctx, roam_info);
+	} else {
+		hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false;
+	}
+	/* Cache last connection info */
+	qdf_mem_copy(&hdd_sta_ctx->cache_conn_info, &hdd_sta_ctx->conn_info,
+		     sizeof(struct hdd_connection_info));
+}
+
+/**
+ * hdd_conn_save_connect_info() - save current connection information
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ * @eBssType: bss type
+ *
+ * Return: none
+ */
+static void
+hdd_conn_save_connect_info(struct hdd_adapter *adapter,
+			   struct csr_roam_info *roam_info,
+			   eCsrRoamBssType eBssType)
+{
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
+
+	QDF_ASSERT(roam_info);
+
+	if (roam_info) {
+		/* Save the BSSID for the connection */
+		if (eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) {
+			QDF_ASSERT(roam_info->pBssDesc);
+			qdf_copy_macaddr(&sta_ctx->conn_info.bssId,
+					 &roam_info->bssid);
+
+			/*
+			 * Save the Station ID for this station from
+			 * the 'Roam Info'. For IBSS mode, staId is
+			 * assigned in NEW_PEER_IND. For reassoc,
+			 * the staID doesn't change and it may be invalid
+			 * in this structure so no change here.
+			 */
+			if (!roam_info->fReassocReq) {
+				sta_ctx->conn_info.staId[0] =
+					roam_info->staId;
+			}
+		} else if (eCSR_BSS_TYPE_IBSS == eBssType) {
+			qdf_copy_macaddr(&sta_ctx->conn_info.bssId,
+					 &roam_info->bssid);
+		} else {
+			/*
+			 * can't happen. We need a valid IBSS or Infra setting
+			 * in the BSSDescription or we can't function.
+			 */
+			QDF_ASSERT(0);
+		}
+
+		/* notify WMM */
+		hdd_wmm_connect(adapter, roam_info, eBssType);
+
+		if (!roam_info->u.pConnectedProfile) {
+			QDF_ASSERT(roam_info->u.pConnectedProfile);
+		} else {
+			/* Get Multicast Encryption Type */
+			encryptType =
+			    roam_info->u.pConnectedProfile->mcEncryptionType;
+			sta_ctx->conn_info.mcEncryptionType = encryptType;
+			/* Get Unicast Encryption Type */
+			encryptType =
+				roam_info->u.pConnectedProfile->EncryptionType;
+			sta_ctx->conn_info.ucEncryptionType = encryptType;
+
+			sta_ctx->conn_info.authType =
+				roam_info->u.pConnectedProfile->AuthType;
+			sta_ctx->conn_info.last_auth_type =
+				sta_ctx->conn_info.authType;
+
+			sta_ctx->conn_info.operationChannel =
+			    roam_info->u.pConnectedProfile->operationChannel;
+
+			/* Save the ssid for the connection */
+			qdf_mem_copy(&sta_ctx->conn_info.SSID.SSID,
+				     &roam_info->u.pConnectedProfile->SSID,
+				     sizeof(tSirMacSSid));
+			qdf_mem_copy(&sta_ctx->conn_info.last_ssid.SSID,
+				     &roam_info->u.pConnectedProfile->SSID,
+				     sizeof(tSirMacSSid));
+
+			/* Save dot11mode in which STA associated to AP */
+			sta_ctx->conn_info.dot11Mode =
+				roam_info->u.pConnectedProfile->dot11Mode;
+
+			sta_ctx->conn_info.proxyARPService =
+				roam_info->u.pConnectedProfile->proxyARPService;
+
+			sta_ctx->conn_info.nss = roam_info->chan_info.nss;
+
+			sta_ctx->conn_info.rate_flags =
+				roam_info->chan_info.rate_flags;
+
+			sta_ctx->conn_info.ch_width =
+				roam_info->chan_info.ch_width;
+		}
+		hdd_save_bss_info(adapter, roam_info);
+	}
+}
+
+/**
+ * hdd_send_ft_assoc_response() - send fast transition assoc response
+ * @dev: pointer to net device
+ * @adapter: pointer to adapter
+ * @pCsrRoamInfo: pointer to roam info
+ *
+ * Send the 11R key information to the supplicant. Only then can the supplicant
+ * generate the PMK-R1. (BTW, the ESE supplicant also needs the Assoc Resp IEs
+ * for the same purpose.)
+ *
+ * Mainly the Assoc Rsp IEs are passed here. For the IMDA this contains the
+ * R1KHID, R0KHID and the MDID. For FT, this consists of the Reassoc Rsp FTIEs.
+ * This is the Assoc Response.
+ *
+ * Return: none
+ */
+static void
+hdd_send_ft_assoc_response(struct net_device *dev,
+			   struct hdd_adapter *adapter,
+			   struct csr_roam_info *pCsrRoamInfo)
+{
+	union iwreq_data wrqu;
+	char *buff;
+	unsigned int len = 0;
+	u8 *pFTAssocRsp = NULL;
+
+	if (pCsrRoamInfo->nAssocRspLength == 0) {
+		hdd_debug("assoc rsp length is 0");
+		return;
+	}
+
+	pFTAssocRsp =
+		(u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
+			pCsrRoamInfo->nAssocReqLength);
+	if (pFTAssocRsp == NULL) {
+		hdd_debug("AssocReq or AssocRsp is NULL");
+		return;
+	}
+	/* pFTAssocRsp needs to point to the IEs */
+	pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
+	hdd_debug("AssocRsp is now at %02x%02x",
+		   (unsigned int)pFTAssocRsp[0],
+		   (unsigned int)pFTAssocRsp[1]);
+
+	/* We need to send the IEs to the supplicant. */
+	buff = qdf_mem_malloc(IW_GENERIC_IE_MAX);
+	if (!buff)
+		return;
+
+	/* Send the Assoc Resp, the supplicant needs this for initial Auth. */
+	len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
+	wrqu.data.length = len;
+	memcpy(buff, pFTAssocRsp, len);
+	wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
+
+	qdf_mem_free(buff);
+}
+
+/**
+ * hdd_send_ft_event() - send fast transition event
+ * @adapter: pointer to adapter
+ *
+ * Send the FTIEs, RIC IEs during FT. This is eventually used to send the
+ * FT events to the supplicant. At the reception of Auth2 we send the RIC
+ * followed by the auth response IEs to the supplicant.
+ * Once both are received in the supplicant, an FT event is generated
+ * to the supplicant.
+ *
+ * Return: none
+ */
+static void hdd_send_ft_event(struct hdd_adapter *adapter)
+{
+	uint16_t auth_resp_len = 0;
+	uint32_t ric_ies_length = 0;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle;
+
+#if defined(KERNEL_SUPPORT_11R_CFG80211)
+	struct cfg80211_ft_event_params ftEvent;
+	uint8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
+	uint8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
+	struct net_device *dev = adapter->dev;
+#else
+	char *buff;
+	union iwreq_data wrqu;
+	uint16_t str_len;
+#endif
+
+	mac_handle = hdd_ctx->mac_handle;
+#if defined(KERNEL_SUPPORT_11R_CFG80211)
+	qdf_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
+	qdf_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);
+
+	sme_get_rici_es(mac_handle, adapter->session_id, (u8 *) ricIe,
+			DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length);
+	if (ric_ies_length == 0)
+		hdd_warn("Do not send RIC IEs as length is 0");
+
+	ftEvent.ric_ies = ricIe;
+	ftEvent.ric_ies_len = ric_ies_length;
+	hdd_debug("RIC IEs is of length %d", (int)ric_ies_length);
+
+	sme_get_ft_pre_auth_response(mac_handle, adapter->session_id,
+				     (u8 *) ftIe, DOT11F_IE_FTINFO_MAX_LEN,
+				     &auth_resp_len);
+
+	if (auth_resp_len == 0) {
+		hdd_debug("AuthRsp FTIES is of length 0");
+		return;
+	}
+
+	sme_set_ft_pre_auth_state(mac_handle, adapter->session_id, true);
+
+	ftEvent.target_ap = ftIe;
+
+	ftEvent.ies = (u8 *) (ftIe + QDF_MAC_ADDR_SIZE);
+	ftEvent.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE;
+
+	hdd_debug("ftEvent.ies_len %zu", ftEvent.ies_len);
+	hdd_debug("ftEvent.ric_ies_len %zu", ftEvent.ric_ies_len);
+	hdd_debug("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x",
+	       ftEvent.target_ap[0], ftEvent.target_ap[1],
+	       ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
+	       ftEvent.target_ap[5]);
+
+	(void)cfg80211_ft_event(dev, &ftEvent);
+
+#else
+	/* We need to send the IEs to the supplicant */
+	buff = qdf_mem_malloc(IW_CUSTOM_MAX);
+	if (!buff)
+		return;
+
+	/* Sme needs to send the RIC IEs first */
+	str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
+	sme_get_rici_es(mac_handle, adapter->session_id,
+			(u8 *) &(buff[str_len]), (IW_CUSTOM_MAX - str_len),
+			&ric_ies_length);
+	if (ric_ies_length == 0) {
+		hdd_warn("Do not send RIC IEs as length is 0");
+	} else {
+		wrqu.data.length = str_len + ric_ies_length;
+		wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buff);
+	}
+
+	/* Sme needs to provide the Auth Resp */
+	qdf_mem_zero(buff, IW_CUSTOM_MAX);
+	str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
+	sme_get_ft_pre_auth_response(mac_handle, adapter->session_id,
+				     (u8 *) &buff[str_len],
+				     (IW_CUSTOM_MAX - str_len), &auth_resp_len);
+
+	if (auth_resp_len == 0) {
+		qdf_mem_free(buff);
+		hdd_debug("AuthRsp FTIES is of length 0");
+		return;
+	}
+
+	wrqu.data.length = str_len + auth_resp_len;
+	wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buff);
+
+	qdf_mem_free(buff);
+#endif
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * hdd_send_new_ap_channel_info() - send new ap channel info
+ * @dev: pointer to net device
+ * @adapter: pointer to adapter
+ * @pCsrRoamInfo: pointer to roam info
+ *
+ * Send the ESE required "new AP Channel info" to the supplicant.
+ * (This keeps the supplicant "up to date" on the current channel.)
+ *
+ * The current (new AP) channel information is passed in.
+ *
+ * Return: none
+ */
+static void
+hdd_send_new_ap_channel_info(struct net_device *dev,
+			     struct hdd_adapter *adapter,
+			     struct csr_roam_info *pCsrRoamInfo)
+{
+	union iwreq_data wrqu;
+	struct bss_description *descriptor = pCsrRoamInfo->pBssDesc;
+
+	if (descriptor == NULL) {
+		hdd_err("bss descriptor is null");
+		return;
+	}
+	/*
+	 * Send the Channel event, the supplicant needs this to generate
+	 * the Adjacent AP report.
+	 */
+	hdd_debug("Sending up an SIOCGIWFREQ, channelId: %d",
+		 descriptor->channelId);
+	memset(&wrqu, '\0', sizeof(wrqu));
+	wrqu.freq.m = descriptor->channelId;
+	wrqu.freq.e = 0;
+	wrqu.freq.i = 0;
+	wireless_send_event(adapter->dev, SIOCGIWFREQ, &wrqu, NULL);
+}
+
+#endif /* FEATURE_WLAN_ESE */
+
+/**
+ * hdd_send_update_beacon_ies_event() - send update beacons ie event
+ * @adapter: pointer to adapter
+ * @pCsrRoamInfo: pointer to roam info
+ *
+ * Return: none
+ */
+static void
+hdd_send_update_beacon_ies_event(struct hdd_adapter *adapter,
+				 struct csr_roam_info *pCsrRoamInfo)
+{
+	union iwreq_data wrqu;
+	u8 *beacon_ies;
+	u8 currentLen = 0;
+	char *buff;
+	int totalIeLen = 0, currentOffset = 0, strLen;
+
+	memset(&wrqu, '\0', sizeof(wrqu));
+
+	if (0 == pCsrRoamInfo->nBeaconLength) {
+		hdd_debug("beacon frame length is 0");
+		return;
+	}
+	beacon_ies = (u8 *) (pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
+	if (beacon_ies == NULL) {
+		hdd_warn("Beacon IEs is NULL");
+		return;
+	}
+	/* beacon_ies needs to point to the IEs */
+	hdd_debug("Beacon IEs is now at %02x%02x",
+		   (unsigned int)beacon_ies[0],
+		   (unsigned int)beacon_ies[1]);
+	hdd_debug("Beacon IEs length = %d",
+		   pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
+
+	/* We need to send the IEs to the supplicant. */
+	buff = qdf_mem_malloc(IW_CUSTOM_MAX);
+	if (!buff)
+		return;
+
+	strLen = strlcpy(buff, "BEACONIEs=", IW_CUSTOM_MAX);
+	currentLen = strLen + 1;
+
+	totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
+	do {
+		/*
+		 * If the beacon size exceeds max CUSTOM event size, break it
+		 * into chunks of CUSTOM event max size and send it to
+		 * supplicant. Changes are done in supplicant to handle this.
+		 */
+		qdf_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
+		currentLen =
+			QDF_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
+		qdf_mem_copy(&buff[strLen + 1], beacon_ies + currentOffset,
+			     currentLen);
+		currentOffset += currentLen;
+		totalIeLen -= currentLen;
+		wrqu.data.length = strLen + 1 + currentLen;
+		if (totalIeLen)
+			buff[strLen] = 1; /* more chunks pending */
+		else
+			buff[strLen] = 0; /* last chunk */
+
+		hdd_debug("Beacon IEs length to supplicant = %d",
+			   currentLen);
+		wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buff);
+	} while (totalIeLen > 0);
+
+	qdf_mem_free(buff);
+}
+
+/**
+ * hdd_send_association_event() - send association event
+ * @dev: pointer to net device
+ * @pCsrRoamInfo: pointer to roam info
+ *
+ * Return: none
+ */
+static void hdd_send_association_event(struct net_device *dev,
+				       struct csr_roam_info *pCsrRoamInfo)
+{
+	int ret;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	union iwreq_data wrqu;
+	int we_event;
+	char *msg;
+	struct qdf_mac_addr peerMacAddr;
+	struct csr_roam_profile *roam_profile;
+
+	roam_profile = hdd_roam_profile(adapter);
+	memset(&wrqu, '\0', sizeof(wrqu));
+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	we_event = SIOCGIWAP;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (NULL != pCsrRoamInfo)
+		if (pCsrRoamInfo->roamSynchInProgress) {
+			/* Update tdls module about the disconnection event */
+			hdd_notify_sta_disconnect(adapter->session_id,
+						 true, false,
+						 adapter->vdev);
+		}
+#endif
+	if (eConnectionState_Associated == sta_ctx->conn_info.connState) {
+		tSirSmeChanInfo chan_info = {0};
+
+		if (!pCsrRoamInfo || !pCsrRoamInfo->pBssDesc) {
+			hdd_warn("STA in associated state but pCsrRoamInfo is null");
+			return;
+		}
+
+		if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo)) {
+			policy_mgr_incr_active_session(hdd_ctx->psoc,
+				adapter->device_mode, adapter->session_id);
+			hdd_green_ap_start_state_mc(hdd_ctx,
+						    adapter->device_mode, true);
+		}
+		memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
+		       sizeof(pCsrRoamInfo->pBssDesc->bssId));
+
+		ucfg_p2p_status_connect(adapter->vdev);
+
+		hdd_info("wlan: " MAC_ADDRESS_STR " connected to "
+			MAC_ADDRESS_STR "\n",
+			MAC_ADDR_ARRAY(adapter->mac_addr.bytes),
+			MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
+		hdd_send_update_beacon_ies_event(adapter, pCsrRoamInfo);
+
+		/*
+		 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS
+		 * is Enabled Or Send IWEVASSOCRESPIE Event if
+		 * fFTEnable is true.
+		 * Send FT Keys to the supplicant when FT is enabled
+		 */
+		if ((roam_profile->AuthType.authType[0] ==
+		     eCSR_AUTH_TYPE_FT_RSN_PSK)
+		    || (roam_profile->AuthType.authType[0] ==
+			eCSR_AUTH_TYPE_FT_RSN)
+#ifdef FEATURE_WLAN_ESE
+		    || (roam_profile->AuthType.authType[0] ==
+			eCSR_AUTH_TYPE_CCKM_RSN)
+		    || (roam_profile->AuthType.authType[0] ==
+			eCSR_AUTH_TYPE_CCKM_WPA)
+#endif
+		    ) {
+			hdd_send_ft_assoc_response(dev, adapter, pCsrRoamInfo);
+		}
+		qdf_copy_macaddr(&peerMacAddr,
+				 &sta_ctx->conn_info.bssId);
+		chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
+		chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
+		chan_info.info = pCsrRoamInfo->chan_info.info;
+		chan_info.band_center_freq1 =
+			pCsrRoamInfo->chan_info.band_center_freq1;
+		chan_info.band_center_freq2 =
+			pCsrRoamInfo->chan_info.band_center_freq2;
+		chan_info.reg_info_1 =
+			pCsrRoamInfo->chan_info.reg_info_1;
+		chan_info.reg_info_2 =
+			pCsrRoamInfo->chan_info.reg_info_2;
+
+		ret = hdd_objmgr_set_peer_mlme_state(adapter->vdev,
+						     WLAN_ASSOC_STATE);
+		if (ret)
+			hdd_err("Peer object %pM fail to set associated state",
+					peerMacAddr.bytes);
+
+		/* send peer status indication to oem app */
+		hdd_send_peer_status_ind_to_app(&peerMacAddr,
+						ePeerConnected,
+						pCsrRoamInfo->timingMeasCap,
+						adapter->session_id, &chan_info,
+						adapter->device_mode);
+		/* Update tdls module about connection event */
+		hdd_notify_sta_connect(adapter->session_id,
+				       pCsrRoamInfo->tdls_chan_swit_prohibited,
+				       pCsrRoamInfo->tdls_prohibited,
+				       adapter->vdev);
+
+#ifdef MSM_PLATFORM
+		/* start timer in sta/p2p_cli */
+		spin_lock_bh(&hdd_ctx->bus_bw_lock);
+		adapter->prev_tx_packets = adapter->stats.tx_packets;
+		adapter->prev_rx_packets = adapter->stats.rx_packets;
+		cdp_get_intra_bss_fwd_pkts_count(
+			cds_get_context(QDF_MODULE_ID_SOC), adapter->session_id,
+			&adapter->prev_fwd_tx_packets,
+			&adapter->prev_fwd_rx_packets);
+		spin_unlock_bh(&hdd_ctx->bus_bw_lock);
+		hdd_bus_bw_compute_timer_start(hdd_ctx);
+#endif
+	} else if (eConnectionState_IbssConnected ==    /* IBss Associated */
+			sta_ctx->conn_info.connState) {
+		policy_mgr_update_connection_info(hdd_ctx->psoc,
+				adapter->session_id);
+		memcpy(wrqu.ap_addr.sa_data, sta_ctx->conn_info.bssId.bytes,
+				ETH_ALEN);
+		hdd_debug("wlan: new IBSS peer connection to BSSID " MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(sta_ctx->conn_info.bssId.bytes));
+	} else {                /* Not Associated */
+		hdd_debug("wlan: disconnected");
+		memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
+		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
+				adapter->device_mode, adapter->session_id);
+		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+		wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
+#endif
+
+		if ((adapter->device_mode == QDF_STA_MODE) ||
+		    (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
+			qdf_copy_macaddr(&peerMacAddr,
+					 &sta_ctx->conn_info.bssId);
+
+			/* send peer status indication to oem app */
+			hdd_send_peer_status_ind_to_app(&peerMacAddr,
+							ePeerDisconnected, 0,
+							adapter->session_id,
+							NULL,
+							adapter->device_mode);
+		}
+
+		hdd_lpass_notify_disconnect(adapter);
+		/* Update tdls module about the disconnection event */
+		hdd_notify_sta_disconnect(adapter->session_id,
+					  false,
+					  false,
+					  adapter->vdev);
+
+#ifdef MSM_PLATFORM
+		/* stop timer in sta/p2p_cli */
+		spin_lock_bh(&hdd_ctx->bus_bw_lock);
+		adapter->prev_tx_packets = 0;
+		adapter->prev_rx_packets = 0;
+		adapter->prev_fwd_tx_packets = 0;
+		adapter->prev_fwd_rx_packets = 0;
+		spin_unlock_bh(&hdd_ctx->bus_bw_lock);
+		hdd_bus_bw_compute_timer_try_stop(hdd_ctx);
+#endif
+	}
+	hdd_ipa_set_tx_flow_info();
+
+	msg = NULL;
+	/* During the WLAN uninitialization,supplicant is stopped before the
+	 * driver so not sending the status of the connection to supplicant
+	 */
+	if (cds_is_load_or_unload_in_progress()) {
+		wireless_send_event(dev, we_event, &wrqu, msg);
+#ifdef FEATURE_WLAN_ESE
+		if (eConnectionState_Associated ==
+			 sta_ctx->conn_info.connState) {
+			if ((roam_profile->AuthType.authType[0] ==
+			     eCSR_AUTH_TYPE_CCKM_RSN) ||
+			    (roam_profile->AuthType.authType[0] ==
+				eCSR_AUTH_TYPE_CCKM_WPA))
+				hdd_send_new_ap_channel_info(dev, adapter,
+							     pCsrRoamInfo);
+		}
+#endif
+	}
+}
+
+/**
+ * hdd_conn_remove_connect_info() - remove connection info
+ * @sta_ctx: pointer to global HDD station context
+ * @pCsrRoamInfo: pointer to roam info
+ *
+ * Return: none
+ */
+static void hdd_conn_remove_connect_info(struct hdd_station_ctx *sta_ctx)
+{
+	/* Remove staId, bssId and peerMacAddress */
+	sta_ctx->conn_info.staId[0] = HDD_WLAN_INVALID_STA_ID;
+	qdf_mem_zero(&sta_ctx->conn_info.bssId, QDF_MAC_ADDR_SIZE);
+	qdf_mem_zero(&sta_ctx->conn_info.peerMacAddress[0],
+		     QDF_MAC_ADDR_SIZE);
+
+	/* Clear all security settings */
+	sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+	sta_ctx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
+	sta_ctx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
+
+	qdf_mem_zero(&sta_ctx->conn_info.Keys, sizeof(tCsrKeys));
+	qdf_mem_zero(&sta_ctx->ibss_enc_key, sizeof(tCsrRoamSetKey));
+
+	sta_ctx->conn_info.proxyARPService = 0;
+
+	qdf_mem_zero(&sta_ctx->conn_info.SSID, sizeof(tCsrSSIDInfo));
+}
+
+/**
+ * hdd_clear_roam_profile_ie() - Clear Roam Profile IEs
+ * @adapter: adapter who's IEs are to be cleared
+ *
+ * Return: None
+ */
+static void hdd_clear_roam_profile_ie(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx;
+	struct csr_roam_profile *roam_profile;
+
+	hdd_enter();
+
+	/* clear WPA/RSN/WSC IE information in the profile */
+	roam_profile = hdd_roam_profile(adapter);
+
+	roam_profile->nWPAReqIELength = 0;
+	roam_profile->pWPAReqIE = NULL;
+	roam_profile->nRSNReqIELength = 0;
+	roam_profile->pRSNReqIE = NULL;
+
+#ifdef FEATURE_WLAN_WAPI
+	roam_profile->nWAPIReqIELength = 0;
+	roam_profile->pWAPIReqIE = NULL;
+#endif
+
+	roam_profile->bWPSAssociation = false;
+	roam_profile->bOSENAssociation = false;
+	roam_profile->pAddIEScan = NULL;
+	roam_profile->nAddIEScanLength = 0;
+	roam_profile->pAddIEAssoc = NULL;
+	roam_profile->nAddIEAssocLength = 0;
+
+	roam_profile->EncryptionType.numEntries = 1;
+	roam_profile->EncryptionType.encryptionType[0] =
+		eCSR_ENCRYPT_TYPE_NONE;
+
+	roam_profile->mcEncryptionType.numEntries = 1;
+	roam_profile->mcEncryptionType.encryptionType[0] =
+		eCSR_ENCRYPT_TYPE_NONE;
+
+	roam_profile->AuthType.numEntries = 1;
+	roam_profile->AuthType.authType[0] =
+		eCSR_AUTH_TYPE_OPEN_SYSTEM;
+
+	qdf_mem_zero(roam_profile->bssid_hint.bytes, QDF_MAC_ADDR_SIZE);
+
+#ifdef WLAN_FEATURE_11W
+	roam_profile->MFPEnabled = false;
+	roam_profile->MFPRequired = 0;
+	roam_profile->MFPCapable = 0;
+#endif
+
+	qdf_mem_zero(roam_profile->Keys.KeyLength, CSR_MAX_NUM_KEY);
+
+#ifdef FEATURE_WLAN_WAPI
+	adapter->wapi_info.wapi_auth_mode = WAPI_AUTH_MODE_OPEN;
+	adapter->wapi_info.wapi_mode = false;
+#endif
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	sta_ctx->auth_key_mgmt = 0;
+	qdf_zero_macaddr(&sta_ctx->requested_bssid);
+	hdd_exit();
+}
+
+/**
+ * hdd_roam_deregister_sta() - deregister station
+ * @adapter: pointer to adapter
+ * @staId: station identifier
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_roam_deregister_sta(struct hdd_adapter *adapter, uint8_t staid)
+{
+	QDF_STATUS qdf_status;
+
+	qdf_status = cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
+			(struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX),
+			staid);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("cdp_clear_peer() failed for staid %d. Status(%d) [0x%08X]",
+			staid, qdf_status, qdf_status);
+	}
+
+	return qdf_status;
+}
+
+/**
+ * hdd_print_bss_info() - print bss info
+ * @hdd_sta_ctx: pointer to hdd station context
+ *
+ * Return: None
+ */
+static void hdd_print_bss_info(struct hdd_station_ctx *hdd_sta_ctx)
+{
+	uint32_t *cap_info;
+
+	hdd_debug("WIFI DATA LOGGER");
+	hdd_debug("channel: %d",
+		 hdd_sta_ctx->conn_info.freq);
+	hdd_debug("dot11mode: %d",
+		 hdd_sta_ctx->conn_info.dot11Mode);
+	hdd_debug("AKM: %d",
+		  hdd_sta_ctx->conn_info.last_auth_type);
+	hdd_debug("ssid: %.*s",
+		 hdd_sta_ctx->conn_info.last_ssid.SSID.length,
+		 hdd_sta_ctx->conn_info.last_ssid.SSID.ssId);
+	hdd_debug("roam count: %d",
+		 hdd_sta_ctx->conn_info.roam_count);
+	hdd_debug("ant_info: %d",
+		 hdd_sta_ctx->conn_info.txrate.nss);
+	hdd_debug("datarate legacy %d",
+		 hdd_sta_ctx->conn_info.txrate.legacy);
+	hdd_debug("datarate mcs: %d",
+		 hdd_sta_ctx->conn_info.txrate.mcs);
+	if (hdd_sta_ctx->conn_info.conn_flag.ht_present) {
+		cap_info = (uint32_t *)&hdd_sta_ctx->conn_info.ht_caps;
+		hdd_debug("ht caps: %x", *cap_info);
+	}
+	if (hdd_sta_ctx->conn_info.conn_flag.vht_present) {
+		cap_info = (uint32_t *)&hdd_sta_ctx->conn_info.vht_caps;
+		hdd_debug("vht caps: %x", *cap_info);
+	}
+	if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
+		hdd_debug("hs20 info: %x",
+			 hdd_sta_ctx->conn_info.hs20vendor_ie.release_num);
+	hdd_debug("signal: %d",
+		 hdd_sta_ctx->conn_info.signal);
+	hdd_debug("noise: %d",
+		 hdd_sta_ctx->conn_info.noise);
+}
+
+/**
+ * hdd_dis_connect_handler() - disconnect event handler
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ * @roamId: roam identifier
+ * @roamStatus: roam status
+ * @roamResult: roam result
+ *
+ * This function handles disconnect event:
+ * 1. Disable transmit queues;
+ * 2. Clean up internal connection states and data structures;
+ * 3. Send disconnect indication to supplicant.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter,
+					  struct csr_roam_info *roam_info,
+					  uint32_t roamId,
+					  eRoamCmdStatus roamStatus,
+					  eCsrRoamResult roamResult)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS vstatus;
+	struct net_device *dev = adapter->dev;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	uint8_t sta_id;
+	bool sendDisconInd = true;
+	mac_handle_t mac_handle;
+
+	if (dev == NULL) {
+		hdd_err("net_dev is released return");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* notify apps that we can't pass traffic anymore */
+	hdd_debug("Disabling queues");
+	wlan_hdd_netif_queue_control(adapter,
+				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+				     WLAN_CONTROL_PATH);
+
+	if (ucfg_ipa_is_enabled() &&
+	    (sta_ctx->conn_info.staId[0] != HDD_WLAN_INVALID_STA_ID))
+		ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev,
+				  adapter->device_mode,
+				  sta_ctx->conn_info.staId[0],
+				  adapter->session_id,
+				  WLAN_IPA_STA_DISCONNECT,
+				  sta_ctx->conn_info.bssId.bytes);
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+	wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
+#endif
+
+	DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
+				adapter->session_id,
+				QDF_TRACE_DEFAULT_PDEV_ID,
+				QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC));
+
+	/* HDD has initiated disconnect, do not send disconnect indication
+	 * to kernel. Sending disconnected event to kernel for userspace
+	 * initiated disconnect will be handled by disconnect handler call
+	 * to cfg80211_disconnected.
+	 */
+	if ((eConnectionState_Disconnecting ==
+	    sta_ctx->conn_info.connState) ||
+	    (eConnectionState_NotConnected ==
+	    sta_ctx->conn_info.connState) ||
+	    (eConnectionState_Connecting ==
+	    sta_ctx->conn_info.connState)) {
+		hdd_debug("HDD has initiated a disconnect, no need to send disconnect indication to kernel");
+		sendDisconInd = false;
+	} else {
+		INIT_COMPLETION(adapter->disconnect_comp_var);
+		hdd_conn_set_connection_state(adapter,
+					      eConnectionState_Disconnecting);
+	}
+
+	hdd_clear_roam_profile_ie(adapter);
+	hdd_wmm_init(adapter);
+	hdd_debug("Invoking packetdump deregistration API");
+	wlan_deregister_txrx_packetdump();
+
+	/* indicate 'disconnect' status to wpa_supplicant... */
+	hdd_send_association_event(dev, roam_info);
+	/* indicate disconnected event to nl80211 */
+	if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
+		/*
+		 * Only send indication to kernel if not initiated
+		 * by kernel
+		 */
+		if (sendDisconInd) {
+			/*
+			 * To avoid wpa_supplicant sending "HANGED" CMD
+			 * to ICS UI.
+			 */
+			if (eCSR_ROAM_LOSTLINK == roamStatus) {
+				if (roam_info->reasonCode ==
+				    eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
+					pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n",
+						roam_info->rxRssi);
+				wlan_hdd_cfg80211_indicate_disconnect(
+							dev, false,
+							roam_info->reasonCode);
+			} else {
+				wlan_hdd_cfg80211_indicate_disconnect(
+							dev, false,
+							WLAN_REASON_UNSPECIFIED
+							);
+			}
+
+			hdd_debug("sent disconnected event to nl80211, reason code %d",
+				(eCSR_ROAM_LOSTLINK == roamStatus) ?
+				roam_info->reasonCode :
+				WLAN_REASON_UNSPECIFIED);
+		}
+
+		/* update P2P connection status */
+		ucfg_p2p_status_disconnect(adapter->vdev);
+	}
+
+	hdd_wmm_adapter_clear(adapter);
+	mac_handle = hdd_ctx->mac_handle;
+	sme_ft_reset(mac_handle, adapter->session_id);
+	if (hdd_remove_beacon_filter(adapter) != 0)
+		hdd_err("hdd_remove_beacon_filter() failed");
+
+	if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
+		uint8_t i;
+
+		sta_id = sta_ctx->broadcast_staid;
+		vstatus = hdd_roam_deregister_sta(adapter, sta_id);
+		if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
+			hdd_err("hdd_roam_deregister_sta() failed for staID %d Status: %d [0x%x]",
+					sta_id, status, status);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		if (sta_id < HDD_MAX_ADAPTERS)
+			hdd_ctx->sta_to_adapter[sta_id] = NULL;
+		else
+			hdd_debug("invalid sta id %d", sta_id);
+		/* Clear all the peer sta register with TL. */
+		for (i = 0; i < MAX_PEERS; i++) {
+			if (HDD_WLAN_INVALID_STA_ID ==
+				sta_ctx->conn_info.staId[i])
+				continue;
+			sta_id = sta_ctx->conn_info.staId[i];
+			hdd_debug("Deregister StaID %d", sta_id);
+			vstatus = hdd_roam_deregister_sta(adapter, sta_id);
+			if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
+				hdd_err("hdd_roam_deregister_sta() failed to for staID %d Status: %d [0x%x]",
+					sta_id, status, status);
+				status = QDF_STATUS_E_FAILURE;
+			}
+			/* set the staid and peer mac as 0, all other
+			 * reset are done in hdd_connRemoveConnectInfo.
+			 */
+			sta_ctx->conn_info.staId[i] =
+						HDD_WLAN_INVALID_STA_ID;
+			qdf_mem_zero(&sta_ctx->conn_info.peerMacAddress[i],
+				sizeof(struct qdf_mac_addr));
+			if (sta_id < HDD_MAX_ADAPTERS)
+				hdd_ctx->sta_to_adapter[sta_id] = NULL;
+			else
+				hdd_debug("invalid sta_id %d", sta_id);
+		}
+	} else {
+		sta_id = sta_ctx->conn_info.staId[0];
+		hdd_debug("roamResult: %d", roamResult);
+
+		/* clear scan cache for Link Lost */
+		if (eCSR_ROAM_RESULT_DEAUTH_IND == roamResult ||
+		    eCSR_ROAM_RESULT_DISASSOC_IND == roamResult ||
+		    eCSR_ROAM_LOSTLINK == roamStatus) {
+			wlan_hdd_cfg80211_update_bss_list(adapter,
+				sta_ctx->conn_info.bssId.bytes);
+			sme_remove_bssid_from_scan_list(mac_handle,
+			sta_ctx->conn_info.bssId.bytes);
+		}
+		if (sta_id < HDD_MAX_ADAPTERS)
+			hdd_ctx->sta_to_adapter[sta_id] = NULL;
+		else
+			hdd_debug("invalid sta_id %d", sta_id);
+	}
+	/* Clear saved connection information in HDD */
+	hdd_conn_remove_connect_info(sta_ctx);
+	/*
+	* eConnectionState_Connecting state mean that connection is in
+	* progress so no need to set state to eConnectionState_NotConnected
+	*/
+	if ((eConnectionState_Connecting != sta_ctx->conn_info.connState)) {
+		hdd_conn_set_connection_state(adapter,
+					       eConnectionState_NotConnected);
+		 hdd_set_roaming_in_progress(false);
+	}
+	ucfg_pmo_flush_gtk_offload_req(adapter->vdev);
+
+	if ((QDF_STA_MODE == adapter->device_mode) ||
+	    (QDF_P2P_CLIENT_MODE == adapter->device_mode)) {
+		sme_ps_disable_auto_ps_timer(mac_handle,
+					     adapter->session_id);
+		adapter->send_mode_change = true;
+	}
+	wlan_hdd_clear_link_layer_stats(adapter);
+
+	hdd_debug("check for SAP restart");
+	policy_mgr_check_concurrent_intf_and_restart_sap(hdd_ctx->psoc);
+	adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0;
+
+	/* Unblock anyone waiting for disconnect to complete */
+	complete(&adapter->disconnect_comp_var);
+
+	hdd_nud_reset_tracking(adapter);
+
+	hdd_set_disconnect_status(adapter, false);
+
+	hdd_reset_limit_off_chan(adapter);
+
+	hdd_print_bss_info(sta_ctx);
+
+	if (policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
+		sme_enable_roaming_on_connected_sta(mac_handle);
+
+	return status;
+}
+
+/**
+ * hdd_set_peer_authorized_event() - set peer_authorized_event
+ * @vdev_id: vdevid
+ *
+ * Return: None
+ */
+static void hdd_set_peer_authorized_event(uint32_t vdev_id)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	struct hdd_adapter *adapter = NULL;
+
+	if (!hdd_ctx) {
+		hdd_err("Invalid hdd context");
+		return;
+	}
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (adapter == NULL) {
+		hdd_err("Invalid vdev_id");
+		return;
+	}
+	complete(&adapter->sta_authorized_event);
+}
+
+/**
+ * hdd_change_peer_state() - change peer state
+ * @adapter: HDD adapter
+ * @sta_state: peer state
+ * @roam_synch_in_progress: roam synch in progress
+ *
+ * Return: QDF status
+ */
+QDF_STATUS hdd_change_peer_state(struct hdd_adapter *adapter,
+				 uint8_t sta_id,
+				 enum ol_txrx_peer_state sta_state,
+				 bool roam_synch_in_progress)
+{
+	QDF_STATUS err;
+	uint8_t *peer_mac_addr;
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *peer;
+
+	if (!pdev) {
+		hdd_err("Failed to get txrx context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	if (sta_id >= WLAN_MAX_STA_COUNT) {
+		hdd_err("Invalid sta id: %d", sta_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	peer = cdp_peer_find_by_local_id(soc,
+			(struct cdp_pdev *)pdev, sta_id);
+	if (!peer)
+		return QDF_STATUS_E_FAULT;
+
+	peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer);
+	if (peer_mac_addr == NULL) {
+		hdd_err("peer mac addr is NULL");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	err = cdp_peer_state_update(soc, pdev, peer_mac_addr, sta_state);
+	if (err != QDF_STATUS_SUCCESS) {
+		hdd_err("peer state update failed");
+		return QDF_STATUS_E_FAULT;
+	}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (roam_synch_in_progress)
+		return QDF_STATUS_SUCCESS;
+#endif
+
+	if (sta_state == OL_TXRX_PEER_STATE_AUTH) {
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+		/* make sure event is reset */
+		INIT_COMPLETION(adapter->sta_authorized_event);
+#endif
+
+		err = sme_set_peer_authorized(peer_mac_addr,
+				hdd_set_peer_authorized_event,
+				adapter->session_id);
+		if (err != QDF_STATUS_SUCCESS) {
+			hdd_err("Failed to set the peer state to authorized");
+			return QDF_STATUS_E_FAULT;
+		}
+
+		if (adapter->device_mode == QDF_STA_MODE ||
+		    adapter->device_mode == QDF_P2P_CLIENT_MODE) {
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
+			void *vdev;
+			unsigned long rc;
+
+			/* wait for event from firmware to set the event */
+			rc = wait_for_completion_timeout(
+				&adapter->sta_authorized_event,
+				msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
+			if (!rc)
+				hdd_debug("timeout waiting for sta_authorized_event");
+
+			vdev = (void *)cdp_peer_get_vdev(soc, peer);
+			cdp_fc_vdev_unpause(soc, (struct cdp_vdev *)vdev,
+					OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
+#endif
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_update_dp_vdev_flags() - update datapath vdev flags
+ * @cbk_data: callback data
+ * @sta_id: station id
+ * @vdev_param: vdev parameter
+ * @is_link_up: link state up or down
+ *
+ * Return: QDF status
+ */
+QDF_STATUS hdd_update_dp_vdev_flags(void *cbk_data,
+				    uint8_t sta_id,
+				    uint32_t vdev_param,
+				    bool is_link_up)
+{
+	struct cdp_vdev *data_vdev;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct hdd_context *hdd_ctx;
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	struct wlan_objmgr_psoc **psoc;
+
+	if (!cbk_data)
+		return status;
+
+	psoc = cbk_data;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("Invalid HDD Context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!hdd_ctx->tdls_nap_active)
+		return status;
+
+	data_vdev = cdp_peer_get_vdev_by_sta_id(soc, pdev, sta_id);
+	if (NULL == data_vdev) {
+		status = QDF_STATUS_E_FAILURE;
+		return status;
+	}
+
+	cdp_txrx_set_vdev_param(soc, data_vdev, vdev_param, is_link_up);
+
+	return status;
+}
+
+/**
+ * hdd_roam_register_sta() - register station
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ * @staId: station identifier
+ * @pPeerMacAddress: peer MAC address
+ * @pBssDesc: pointer to BSS description
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_roam_register_sta(struct hdd_adapter *adapter,
+					struct csr_roam_info *roam_info,
+					uint8_t staId,
+					struct qdf_mac_addr *pPeerMacAddress,
+					struct bss_description *pBssDesc)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	struct ol_txrx_desc_type staDesc = { 0 };
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct ol_txrx_ops txrx_ops;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pBssDesc)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Get the Station ID from the one saved during the association */
+	staDesc.sta_id = staId;
+
+	/* set the QoS field appropriately */
+	if (hdd_wmm_is_active(adapter))
+		staDesc.is_qos_enabled = 1;
+	else
+		staDesc.is_qos_enabled = 0;
+
+#ifdef FEATURE_WLAN_WAPI
+	hdd_debug("WAPI STA Registered: %d",
+		   adapter->wapi_info.is_wapi_sta);
+	if (adapter->wapi_info.is_wapi_sta)
+		staDesc.is_wapi_supported = 1;
+	else
+		staDesc.is_wapi_supported = 0;
+#endif /* FEATURE_WLAN_WAPI */
+
+	/* Register the vdev transmit and receive functions */
+	qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
+
+	if (adapter->hdd_ctx->enable_dp_rx_threads) {
+		txrx_ops.rx.rx = hdd_rx_pkt_thread_enqueue_cbk;
+		txrx_ops.rx.rx_stack = hdd_rx_packet_cbk;
+	} else {
+		txrx_ops.rx.rx = hdd_rx_packet_cbk;
+		txrx_ops.rx.rx_stack = NULL;
+	}
+
+	txrx_ops.rx.stats_rx = hdd_tx_rx_collect_connectivity_stats_info;
+
+	adapter->txrx_vdev = (void *)cdp_get_vdev_from_vdev_id(soc,
+				(struct cdp_pdev *)pdev,
+				adapter->session_id);
+	if (!adapter->txrx_vdev) {
+		hdd_err("%s find vdev fail", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	txrx_ops.tx.tx = NULL;
+	cdp_vdev_register(soc,
+		(struct cdp_vdev *)adapter->txrx_vdev, adapter,
+		(struct cdp_ctrl_objmgr_vdev *)adapter->vdev, &txrx_ops);
+	if (!txrx_ops.tx.tx) {
+		hdd_err("%s vdev register fail", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	adapter->tx_fn = txrx_ops.tx.tx;
+	qdf_status = cdp_peer_register(soc,
+			(struct cdp_pdev *)pdev, &staDesc);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("cdp_peer_register() failed Status: %d [0x%08X]",
+			 qdf_status, qdf_status);
+		return qdf_status;
+	}
+
+	if (!roam_info->fAuthRequired) {
+		/*
+		 * Connections that do not need Upper layer auth, transition
+		 * TLSHIM directly to 'Authenticated' state
+		 */
+		qdf_status =
+			hdd_change_peer_state(adapter, staDesc.sta_id,
+						OL_TXRX_PEER_STATE_AUTH,
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+						roam_info->roamSynchInProgress
+#else
+						false
+#endif
+						);
+
+		hdd_conn_set_authenticated(adapter, true);
+		hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, true);
+	} else {
+		hdd_debug("ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
+			 sta_ctx->conn_info.staId[0]);
+		qdf_status =
+			hdd_change_peer_state(adapter, staDesc.sta_id,
+						OL_TXRX_PEER_STATE_CONN,
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+						roam_info->roamSynchInProgress
+#else
+						false
+#endif
+						);
+		hdd_conn_set_authenticated(adapter, false);
+		hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, false);
+	}
+	return qdf_status;
+}
+
+/**
+ * hdd_send_roamed_ind() - send roamed indication to cfg80211
+ * @dev: network device
+ * @bss: cfg80211 roamed bss pointer
+ * @req_ie: IEs used in reassociation request
+ * @req_ie_len: Length of the @req_ie
+ * @resp_ie: IEs received in successful reassociation response
+ * @resp_ie_len: Length of @resp_ie
+ *
+ * Return: none
+ */
+#if defined CFG80211_ROAMED_API_UNIFIED || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
+static void hdd_send_roamed_ind(struct net_device *dev,
+				struct cfg80211_bss *bss, const uint8_t *req_ie,
+				size_t req_ie_len, const uint8_t *resp_ie,
+				size_t resp_ie_len)
+{
+	struct cfg80211_roam_info info = {0};
+
+	info.bss = bss;
+	info.req_ie = req_ie;
+	info.req_ie_len = req_ie_len;
+	info.resp_ie = resp_ie;
+	info.resp_ie_len = resp_ie_len;
+	cfg80211_roamed(dev, &info, GFP_KERNEL);
+}
+#else
+static inline void hdd_send_roamed_ind(struct net_device *dev,
+				       struct cfg80211_bss *bss,
+				       const uint8_t *req_ie, size_t req_ie_len,
+				       const uint8_t *resp_ie,
+				       size_t resp_ie_len)
+{
+	cfg80211_roamed_bss(dev, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
+			    GFP_KERNEL);
+}
+#endif
+
+#if defined(WLAN_FEATURE_ROAM_OFFLOAD)
+#if defined(WLAN_FEATURE_FILS_SK)
+void hdd_save_gtk_params(struct hdd_adapter *adapter,
+			 struct csr_roam_info *csr_roam_info, bool is_reassoc)
+{
+	uint8_t *kek;
+	uint32_t kek_len;
+
+	if (is_reassoc) {
+		kek = csr_roam_info->kek;
+		kek_len = csr_roam_info->kek_len;
+	} else {
+		/*
+		 * This should come for FILS case only.
+		 * Caller should make sure fils_join_rsp is
+		 * not NULL, if there is need to use else where.
+		 */
+		kek = csr_roam_info->fils_join_rsp->kek;
+		kek_len = csr_roam_info->fils_join_rsp->kek_len;
+	}
+
+	wlan_hdd_save_gtk_offload_params(adapter, NULL, kek, kek_len,
+					 csr_roam_info->replay_ctr, true);
+
+	hdd_debug("Kek len %d", kek_len);
+}
+#else
+void hdd_save_gtk_params(struct hdd_adapter *adapter,
+			 struct csr_roam_info *csr_roam_info, bool is_reassoc)
+{
+	uint8_t *kek;
+	uint32_t kek_len;
+
+	/*
+	 * is_reassoc is set to true always for Legacy GTK offload
+	 * case, It is false only for FILS case
+	 */
+	kek = csr_roam_info->kek;
+	kek_len = csr_roam_info->kek_len;
+
+	wlan_hdd_save_gtk_offload_params(adapter, NULL, kek, kek_len,
+					 csr_roam_info->replay_ctr, true);
+
+	hdd_debug("Kek len %d", kek_len);
+}
+#endif
+#endif
+/**
+ * hdd_send_re_assoc_event() - send reassoc event
+ * @dev: pointer to net device
+ * @adapter: pointer to adapter
+ * @pCsrRoamInfo: pointer to roam info
+ * @reqRsnIe: pointer to RSN Information element
+ * @reqRsnLength: length of RSN IE
+ *
+ * Return: none
+ */
+static void hdd_send_re_assoc_event(struct net_device *dev,
+	struct hdd_adapter *adapter, struct csr_roam_info *pCsrRoamInfo,
+	uint8_t *reqRsnIe, uint32_t reqRsnLength)
+{
+	unsigned int len = 0;
+	u8 *pFTAssocRsp = NULL;
+	uint8_t *rspRsnIe = qdf_mem_malloc(IW_GENERIC_IE_MAX);
+	uint8_t *assoc_req_ies = qdf_mem_malloc(IW_GENERIC_IE_MAX);
+	uint32_t rspRsnLength = 0;
+	struct ieee80211_channel *chan;
+	uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes-EID and len */
+	uint8_t *buf_ptr, ssid_ie_len;
+	struct cfg80211_bss *bss = NULL;
+	uint8_t *final_req_ie = NULL;
+	tCsrRoamConnectedProfile roam_profile;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int chan_no;
+	int freq;
+
+	qdf_mem_zero(&roam_profile, sizeof(roam_profile));
+
+	if (!rspRsnIe) {
+		hdd_err("Unable to allocate RSN IE");
+		goto done;
+	}
+
+	if (!assoc_req_ies) {
+		hdd_err("Unable to allocate Assoc Req IE");
+		goto done;
+	}
+
+	if (!pCsrRoamInfo || !pCsrRoamInfo->pBssDesc) {
+		hdd_err("Invalid CSR roam info");
+		goto done;
+	}
+
+	if (pCsrRoamInfo->nAssocRspLength == 0) {
+		hdd_err("Assoc rsp length is 0");
+		goto done;
+	}
+
+	pFTAssocRsp =
+		(u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
+			pCsrRoamInfo->nAssocReqLength);
+	if (pFTAssocRsp == NULL)
+		goto done;
+
+	/* pFTAssocRsp needs to point to the IEs */
+	pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
+	hdd_debug("AssocRsp is now at %02x%02x",
+		 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
+
+	/*
+	 * Active session count is decremented upon disconnection, but during
+	 * roaming, there is no disconnect indication and hence active session
+	 * count is not decremented.
+	 * After roaming is completed, active session count is incremented
+	 * as a part of connect indication but effectively after roaming the
+	 * active session count should still be the same and hence upon
+	 * successful reassoc decrement the active session count here.
+	 */
+	if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo)) {
+		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
+				adapter->device_mode, adapter->session_id);
+		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
+	}
+
+	/* Send the Assoc Resp, the supplicant needs this for initial Auth */
+	len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
+	rspRsnLength = len;
+	qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
+	qdf_mem_zero(rspRsnIe + len, IW_GENERIC_IE_MAX - len);
+
+	chan_no = pCsrRoamInfo->pBssDesc->channelId;
+	if (chan_no <= 14)
+		freq = ieee80211_channel_to_frequency(chan_no,
+							NL80211_BAND_2GHZ);
+	else
+		freq = ieee80211_channel_to_frequency(chan_no,
+							NL80211_BAND_5GHZ);
+	chan = ieee80211_get_channel(adapter->wdev.wiphy, freq);
+
+	sme_roam_get_connect_profile(hdd_ctx->mac_handle, adapter->session_id,
+				     &roam_profile);
+
+	bss = hdd_cfg80211_get_bss(adapter->wdev.wiphy,
+			chan, pCsrRoamInfo->bssid.bytes,
+			&roam_profile.SSID.ssId[0],
+			roam_profile.SSID.length);
+
+	if (bss == NULL)
+		hdd_warn("Get BSS returned NULL");
+	buf_ptr = buf_ssid_ie;
+	*buf_ptr = SIR_MAC_SSID_EID;
+	buf_ptr++;
+	*buf_ptr = roam_profile.SSID.length; /*len of ssid*/
+	buf_ptr++;
+	qdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
+			roam_profile.SSID.length);
+	ssid_ie_len = 2 + roam_profile.SSID.length;
+	hdd_debug("SSIDIE:");
+	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 (bss)
+			cfg80211_put_bss(adapter->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;
+	qdf_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
+	qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
+	qdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
+		IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
+	hdd_debug("Req RSN IE:");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
+			   final_req_ie, (ssid_ie_len + reqRsnLength));
+	hdd_send_roamed_ind(dev, bss, final_req_ie,
+			    (ssid_ie_len + reqRsnLength), rspRsnIe,
+			    rspRsnLength);
+
+	qdf_mem_copy(assoc_req_ies,
+		(u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength,
+		pCsrRoamInfo->nAssocReqLength);
+
+	hdd_save_gtk_params(adapter, pCsrRoamInfo, true);
+
+	hdd_debug("ReAssoc Req IE dump");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
+		assoc_req_ies, pCsrRoamInfo->nAssocReqLength);
+
+	wlan_hdd_send_roam_auth_event(adapter, pCsrRoamInfo->bssid.bytes,
+			assoc_req_ies, pCsrRoamInfo->nAssocReqLength,
+			rspRsnIe, rspRsnLength,
+			pCsrRoamInfo);
+
+	hdd_update_hlp_info(dev, pCsrRoamInfo);
+
+done:
+	sme_roam_free_connect_profile(&roam_profile);
+	if (final_req_ie)
+		qdf_mem_free(final_req_ie);
+	qdf_mem_free(rspRsnIe);
+	qdf_mem_free(assoc_req_ies);
+}
+
+/**
+ * hdd_is_roam_sync_in_progress()- Check if roam offloaded
+ * @roaminfo - Roaming Information
+ *
+ * Return: roam sync status if roaming offloaded else false
+ */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+bool hdd_is_roam_sync_in_progress(struct csr_roam_info *roaminfo)
+{
+	if (roaminfo)
+		return roaminfo->roamSynchInProgress;
+	else
+		return false;
+}
+#endif
+
+/**
+ * hdd_get_ibss_peer_staid() - get sta id for IBSS peer
+ * @hddstactx: pointer to HDD sta context
+ * @roaminfo: pointer to roaminfo structure
+ *
+ * This function returns staid for IBSS peer. If peer is broadcast
+ * MAC address return self staid(0) else find the peer sta id of
+ * the peer.
+ *
+ * Return: sta_id (HDD_WLAN_INVALID_STA_ID if peer not found).
+ */
+static uint8_t hdd_get_ibss_peer_staid(struct hdd_station_ctx *hddstactx,
+				       struct csr_roam_info *roaminfo)
+{
+	uint8_t staid = HDD_WLAN_INVALID_STA_ID;
+	QDF_STATUS status;
+
+	if (qdf_is_macaddr_broadcast(&roaminfo->peerMac)) {
+		staid = 0;
+	} else {
+		status = hdd_get_peer_sta_id(hddstactx,
+				&roaminfo->peerMac, &staid);
+		if (status != QDF_STATUS_SUCCESS) {
+			hdd_err("Unable to find staid for " MAC_ADDRESS_STR,
+			    MAC_ADDR_ARRAY(roaminfo->peerMac.bytes));
+		}
+	}
+
+	return staid;
+}
+
+/**
+ * hdd_change_sta_state_authenticated()-
+ * This function changes STA state to authenticated
+ * @adapter:  pointer to the adapter structure.
+ * @roaminfo: pointer to the RoamInfo structure.
+ *
+ * This is called from hdd_RoamSetKeyCompleteHandler
+ * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw.
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int hdd_change_sta_state_authenticated(struct hdd_adapter *adapter,
+						 struct csr_roam_info *roaminfo)
+{
+	QDF_STATUS status;
+	uint32_t timeout;
+	uint8_t staid = HDD_WLAN_INVALID_STA_ID;
+	struct hdd_station_ctx *hddstactx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	timeout = hddstactx->hdd_reassoc_scenario ?
+		AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE :
+		hdd_ctx->config->auto_bmps_timer_val * 1000;
+
+	if (QDF_IBSS_MODE == adapter->device_mode)
+		staid = hdd_get_ibss_peer_staid(hddstactx, roaminfo);
+	else
+		staid = hddstactx->conn_info.staId[0];
+
+	hdd_debug("Changing Peer state to AUTHENTICATED for StaId = %d", staid);
+
+	/* Connections that do not need Upper layer authentication,
+	 * transition TL to 'Authenticated' state after the keys are set
+	 */
+	status = hdd_change_peer_state(adapter, staid, OL_TXRX_PEER_STATE_AUTH,
+			hdd_is_roam_sync_in_progress(roaminfo));
+	hdd_conn_set_authenticated(adapter, true);
+	hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, true);
+
+	if ((QDF_STA_MODE == adapter->device_mode) ||
+	    (QDF_P2P_CLIENT_MODE == adapter->device_mode)) {
+		sme_ps_enable_auto_ps_timer(hdd_ctx->mac_handle,
+					    adapter->session_id,
+					    timeout);
+	}
+
+	return qdf_status_to_os_return(status);
+}
+
+/**
+ * hdd_is_key_install_required_for_ibss() - check encryption type to identify
+ *                                          if key installation is required
+ * @encr_type: encryption type
+ *
+ * Return: true if key installation is required and false otherwise.
+ */
+static inline bool hdd_is_key_install_required_for_ibss(
+				eCsrEncryptionType encr_type)
+{
+	if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == encr_type ||
+	    eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == encr_type ||
+	    eCSR_ENCRYPT_TYPE_TKIP == encr_type ||
+	    eCSR_ENCRYPT_TYPE_AES_GCMP == encr_type ||
+	    eCSR_ENCRYPT_TYPE_AES_GCMP_256 == encr_type ||
+	    eCSR_ENCRYPT_TYPE_AES == encr_type)
+		return true;
+	else
+		return false;
+}
+
+/**
+ * hdd_change_peer_state_after_set_key() - change the peer state on set key
+ *                                         complete
+ * @adapter: pointer to HDD adapter
+ * @roaminfo: pointer to roam info
+ * @roam_result: roam result
+ *
+ * Peer state will be OL_TXRX_PEER_STATE_CONN until set key is complete.
+ * This function checks for the successful set key completion and update
+ * the peer state to OL_TXRX_PEER_STATE_AUTH.
+ *
+ * Return: None
+ */
+static void hdd_change_peer_state_after_set_key(struct hdd_adapter *adapter,
+						struct csr_roam_info *roaminfo,
+						eCsrRoamResult roam_result)
+{
+	struct hdd_station_ctx *hdd_sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	eCsrEncryptionType encr_type = hdd_sta_ctx->conn_info.ucEncryptionType;
+
+	/*
+	 * If the security mode is one of the following, IBSS peer will be
+	 * waiting in CONN state and we will move the peer state to AUTH
+	 * here. For non-secure connection, no need to wait for set-key complete
+	 * peer will be moved to AUTH in hdd_roam_register_sta.
+	 */
+	if (QDF_IBSS_MODE == adapter->device_mode) {
+		if (hdd_is_key_install_required_for_ibss(encr_type))
+			hdd_change_sta_state_authenticated(adapter, roaminfo);
+
+		return;
+	}
+
+	if (eCSR_ROAM_RESULT_AUTHENTICATED == roam_result) {
+		hdd_sta_ctx->conn_info.gtk_installed = true;
+		/*
+		 * PTK exchange happens in preauthentication itself if key_mgmt
+		 * is FT-PSK, ptk_installed was false as there is no set PTK
+		 * after roaming. STA TL state moves to authenticated only if
+		 * ptk_installed is true. So, make ptk_installed to true in
+		 * case of 11R roaming.
+		 */
+		if (sme_neighbor_roam_is11r_assoc(adapter->hdd_ctx->mac_handle,
+						  adapter->session_id))
+			hdd_sta_ctx->conn_info.ptk_installed = true;
+	} else {
+		hdd_sta_ctx->conn_info.ptk_installed = true;
+	}
+
+	/* In WPA case move STA to authenticated when ptk is installed. Earlier
+	 * in WEP case STA was moved to AUTHENTICATED prior to setting the
+	 * unicast key and it was resulting in sending few un-encrypted packet.
+	 * Now in WEP case STA state will be moved to AUTHENTICATED after we
+	 * set the unicast and broadcast key.
+	 */
+	if ((encr_type == eCSR_ENCRYPT_TYPE_WEP40) ||
+	    (encr_type == eCSR_ENCRYPT_TYPE_WEP104) ||
+	    (encr_type == eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
+	    (encr_type == eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
+		if (hdd_sta_ctx->conn_info.gtk_installed &&
+		    hdd_sta_ctx->conn_info.ptk_installed)
+			hdd_change_sta_state_authenticated(adapter, roaminfo);
+	} else if (hdd_sta_ctx->conn_info.ptk_installed) {
+		hdd_change_sta_state_authenticated(adapter, roaminfo);
+	}
+
+	if (hdd_sta_ctx->conn_info.gtk_installed &&
+		hdd_sta_ctx->conn_info.ptk_installed) {
+		hdd_sta_ctx->conn_info.gtk_installed = false;
+		hdd_sta_ctx->conn_info.ptk_installed = false;
+	}
+}
+
+/**
+ * hdd_roam_set_key_complete_handler() - Update the security parameters
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ * @roamId: roam id
+ * @roamStatus: roam status
+ * @roamResult: roam result
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS
+hdd_roam_set_key_complete_handler(struct hdd_adapter *adapter,
+				  struct csr_roam_info *roam_info,
+				  uint32_t roamId,
+				  eRoamCmdStatus roamStatus,
+				  eCsrRoamResult roamResult)
+{
+	eCsrEncryptionType connectedCipherAlgo;
+	bool connected = false;
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	hdd_enter();
+
+	if (NULL == roam_info) {
+		hdd_err("roam_info is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/*
+	 * if (WPA), tell TL to go to 'authenticated' after the keys are set.
+	 * then go to 'authenticated'.  For all other authentication types
+	 * (those that do not require upper layer authentication) we can put TL
+	 * directly into 'authenticated' state.
+	 */
+	hdd_debug("Set Key completion roamStatus =%d roamResult=%d "
+		  MAC_ADDRESS_STR, roamStatus, roamResult,
+		  MAC_ADDR_ARRAY(roam_info->peerMac.bytes));
+
+	connected = hdd_conn_get_connected_cipher_algo(sta_ctx,
+						   &connectedCipherAlgo);
+	if (connected) {
+		hdd_change_peer_state_after_set_key(adapter, roam_info,
+						    roamResult);
+	}
+
+	hdd_exit();
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_perform_roam_set_key_complete() - perform set key complete
+ * @adapter: pointer to adapter
+ *
+ * Return: none
+ */
+void hdd_perform_roam_set_key_complete(struct hdd_adapter *adapter)
+{
+	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct csr_roam_info roamInfo;
+
+	roamInfo.fAuthRequired = false;
+	qdf_mem_copy(roamInfo.bssid.bytes,
+		     sta_ctx->roam_info.bssid, QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(roamInfo.peerMac.bytes,
+		     sta_ctx->roam_info.peer_mac, QDF_MAC_ADDR_SIZE);
+
+	qdf_ret_status =
+			hdd_roam_set_key_complete_handler(adapter,
+					   &roamInfo,
+					   sta_ctx->roam_info.roam_id,
+					   sta_ctx->roam_info.roam_status,
+					   eCSR_ROAM_RESULT_AUTHENTICATED);
+	if (qdf_ret_status != QDF_STATUS_SUCCESS)
+		hdd_err("Set Key complete failure");
+
+	sta_ctx->roam_info.defer_key_complete = false;
+}
+
+#if defined(WLAN_FEATURE_FILS_SK) && \
+	(defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
+		 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)))
+void hdd_clear_fils_connection_info(struct hdd_adapter *adapter)
+{
+	struct csr_roam_profile *roam_profile;
+
+	if ((adapter->device_mode == QDF_SAP_MODE) ||
+	    (adapter->device_mode == QDF_P2P_GO_MODE))
+		return;
+
+	roam_profile = hdd_roam_profile(adapter);
+	if (roam_profile->fils_con_info) {
+		qdf_mem_free(roam_profile->fils_con_info);
+		roam_profile->fils_con_info = NULL;
+	}
+
+	if (roam_profile->hlp_ie) {
+		qdf_mem_free(roam_profile->hlp_ie);
+		roam_profile->hlp_ie = NULL;
+		roam_profile->hlp_ie_len = 0;
+	}
+}
+#endif
+
+/**
+ * hdd_association_completion_handler() - association completion handler
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ * @roamId: roam id
+ * @roamStatus: roam status
+ * @roamResult: roam result
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS
+hdd_association_completion_handler(struct hdd_adapter *adapter,
+				   struct csr_roam_info *roam_info,
+				   uint32_t roamId,
+				   eRoamCmdStatus roamStatus,
+				   eCsrRoamResult roamResult)
+{
+	struct net_device *dev = adapter->dev;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
+	uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN, ie_len;
+	int ft_carrier_on = false;
+	bool hddDisconInProgress = false;
+	unsigned long rc;
+	tSirResultCodes timeout_reason = 0;
+	bool ok;
+	mac_handle_t mac_handle;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* validate config */
+	if (!hdd_ctx->config) {
+		hdd_err("config is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	/*
+	 * reset scan reject params if connection is success or we received
+	 * final failure from CSR after trying with all APs.
+	 */
+	hdd_reset_scan_reject_params(hdd_ctx, roamStatus, roamResult);
+
+	/*
+	 * Enable roaming on other STA iface except this one.
+	 * Firmware dosent support connection on one STA iface while
+	 * roaming on other STA iface
+	 */
+	wlan_hdd_enable_roaming(adapter);
+
+	/* HDD has initiated disconnect, do not send connect result indication
+	 * to kernel as it will be handled by __cfg80211_disconnect.
+	 */
+	if (((eConnectionState_Disconnecting ==
+	    sta_ctx->conn_info.connState) ||
+	    (eConnectionState_NotConnected ==
+	    sta_ctx->conn_info.connState)) &&
+	    ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult) ||
+	    (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
+		hdd_info("hddDisconInProgress state=%d, result=%d, status=%d",
+				sta_ctx->conn_info.connState,
+				roamResult, roamStatus);
+		hddDisconInProgress = true;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) {
+		if (NULL == roam_info) {
+			hdd_err("roam_info is NULL");
+			return QDF_STATUS_E_FAILURE;
+		}
+		if (!hddDisconInProgress) {
+			hdd_conn_set_connection_state(adapter,
+						   eConnectionState_Associated);
+		}
+
+		/* Save the connection info from CSR... */
+		hdd_conn_save_connect_info(adapter, roam_info,
+					   eCSR_BSS_TYPE_INFRASTRUCTURE);
+
+		if (hdd_add_beacon_filter(adapter) != 0)
+			hdd_err("hdd_add_beacon_filter() failed");
+#ifdef FEATURE_WLAN_WAPI
+		if (roam_info->u.pConnectedProfile->AuthType ==
+		    eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
+		    || roam_info->u.pConnectedProfile->AuthType ==
+		    eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
+			adapter->wapi_info.is_wapi_sta = true;
+		} else {
+			adapter->wapi_info.is_wapi_sta = false;
+		}
+#endif /* FEATURE_WLAN_WAPI */
+		hdd_debug("bss_descr[%d] devicemode[%d]", !!roam_info->pBssDesc,
+				adapter->device_mode);
+		if ((QDF_STA_MODE == adapter->device_mode) &&
+						roam_info->pBssDesc) {
+			ie_len = GET_IE_LEN_IN_BSS(roam_info->pBssDesc->length);
+			sta_ctx->ap_supports_immediate_power_save =
+				wlan_hdd_is_ap_supports_immediate_power_save(
+				     (uint8_t *) roam_info->pBssDesc->ieFields,
+				     ie_len);
+			hdd_debug("ap_supports_immediate_power_save flag [%d]",
+				  sta_ctx->ap_supports_immediate_power_save);
+		}
+
+		/* Indicate 'connect' status to user space */
+		hdd_send_association_event(dev, roam_info);
+
+		if (policy_mgr_is_mcc_in_24G(hdd_ctx->psoc)) {
+			if (hdd_ctx->miracast_value)
+				wlan_hdd_set_mas(adapter,
+					hdd_ctx->miracast_value);
+		}
+
+		/* Initialize the Linkup event completion variable */
+		INIT_COMPLETION(adapter->linkup_event_var);
+
+		/*
+		 * Sometimes Switching ON the Carrier is taking time to activate
+		 * the device properly. Before allowing any packet to go up to
+		 * the application, device activation has to be ensured for
+		 * proper queue mapping by the kernel. we have registered net
+		 * device notifier for device change notification. With this we
+		 * will come to know that the device is getting
+		 * activated properly.
+		 */
+		if (sta_ctx->ft_carrier_on == false) {
+			/*
+			 * Enable Linkup Event Servicing which allows the net
+			 * device notifier to set the linkup event variable.
+			 */
+			adapter->is_link_up_service_needed = true;
+
+			/* Switch on the Carrier to activate the device */
+			wlan_hdd_netif_queue_control(adapter,
+						WLAN_NETIF_CARRIER_ON,
+						WLAN_CONTROL_PATH);
+
+			/*
+			 * Wait for the Link to up to ensure all the queues
+			 * are set properly by the kernel.
+			 */
+			rc = wait_for_completion_timeout(
+					&adapter->linkup_event_var,
+					msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)
+					);
+			if (!rc)
+				hdd_warn("Warning:ASSOC_LINKUP_TIMEOUT");
+
+			/*
+			 * Disable Linkup Event Servicing - no more service
+			 * required from the net device notifier call.
+			 */
+			adapter->is_link_up_service_needed = false;
+		} else {
+			sta_ctx->ft_carrier_on = false;
+			ft_carrier_on = true;
+		}
+		if (roam_info->staId < HDD_MAX_ADAPTERS)
+			hdd_ctx->sta_to_adapter[roam_info->staId] = adapter;
+		else
+			hdd_err("Wrong Staid: %d", roam_info->staId);
+
+		if (ucfg_ipa_is_enabled())
+			ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev,
+					  adapter->device_mode,
+					  roam_info->staId,
+					  adapter->session_id,
+					  WLAN_IPA_STA_CONNECT,
+					  roam_info->bssid.bytes);
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+		wlan_hdd_auto_shutdown_enable(hdd_ctx, false);
+#endif
+
+		hdd_debug("check if STA chan ok for DNBS");
+		if (policy_mgr_is_chan_ok_for_dnbs(hdd_ctx->psoc,
+					sta_ctx->conn_info.operationChannel,
+					&ok)) {
+			hdd_err("Unable to check DNBS eligibility for chan:%d",
+					sta_ctx->conn_info.operationChannel);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (!ok) {
+			hdd_err("Chan:%d not suitable for DNBS",
+				sta_ctx->conn_info.operationChannel);
+			wlan_hdd_netif_queue_control(adapter,
+				WLAN_NETIF_CARRIER_OFF,
+				WLAN_CONTROL_PATH);
+			if (!hddDisconInProgress) {
+				hdd_err("Disconnecting...");
+				sme_roam_disconnect(
+					mac_handle,
+					adapter->session_id,
+					eCSR_DISCONNECT_REASON_UNSPECIFIED);
+			}
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
+			adapter->session_id,
+			QDF_TRACE_DEFAULT_PDEV_ID,
+			QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC));
+
+		/*
+		 * For reassoc, the station is already registered, all we need
+		 * is to change the state of the STA in TL.
+		 * If authentication is required (WPA/WPA2/DWEP), change TL to
+		 * CONNECTED instead of AUTHENTICATED.
+		 */
+		if (!roam_info->fReassocReq) {
+			struct cfg80211_bss *bss;
+			u8 *pFTAssocRsp = NULL;
+			unsigned int assocRsplen = 0;
+			u8 *pFTAssocReq = NULL;
+			unsigned int assocReqlen = 0;
+			struct ieee80211_channel *chan;
+			uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
+			uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
+
+			/* add bss_id to cfg80211 data base */
+			bss =
+				wlan_hdd_cfg80211_update_bss_db(adapter,
+								roam_info);
+			if (NULL == bss) {
+				hdd_err("wlan: Not able to create BSS entry");
+				wlan_hdd_netif_queue_control(adapter,
+					WLAN_NETIF_CARRIER_OFF,
+					WLAN_CONTROL_PATH);
+				if (!hddDisconInProgress) {
+					/*
+					 * Here driver was not able to add bss
+					 * in cfg80211 database this can happen
+					 * if connected channel is not valid,
+					 * i.e reg domain was changed during
+					 * connection. Queue disconnect for the
+					 * session if disconnect is not in
+					 * progress.
+					 */
+					hdd_debug("Disconnecting...");
+					sme_roam_disconnect(
+					   mac_handle,
+					   adapter->session_id,
+					   eCSR_DISCONNECT_REASON_UNSPECIFIED);
+				}
+				return QDF_STATUS_E_FAILURE;
+			}
+
+			cfg80211_put_bss(hdd_ctx->wiphy, bss);
+
+			/* Association Response */
+			pFTAssocRsp =
+				(u8 *) (roam_info->pbFrames +
+					roam_info->nBeaconLength +
+					roam_info->nAssocReqLength);
+			if (pFTAssocRsp != NULL) {
+				/*
+				 * pFTAssocRsp needs to point to the IEs
+				 */
+				pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
+				hdd_debug("AssocRsp is now at %02x%02x",
+					 (unsigned int)pFTAssocRsp[0],
+					 (unsigned int)pFTAssocRsp[1]);
+				assocRsplen =
+					roam_info->nAssocRspLength -
+					FT_ASSOC_RSP_IES_OFFSET;
+
+				hdd_debug("assocRsplen %d", assocRsplen);
+				hdd_debug("Assoc Rsp IE dump");
+				QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
+						   QDF_TRACE_LEVEL_DEBUG,
+						   pFTAssocRsp,
+						   assocRsplen);
+			} else {
+				hdd_debug("AssocRsp is NULL");
+				assocRsplen = 0;
+			}
+
+			/* Association Request */
+			pFTAssocReq = (u8 *) (roam_info->pbFrames +
+					      roam_info->nBeaconLength);
+			if (pFTAssocReq != NULL) {
+				if (!ft_carrier_on) {
+					/*
+					 * pFTAssocReq needs to point to
+					 * the IEs
+					 */
+					pFTAssocReq +=
+						FT_ASSOC_REQ_IES_OFFSET;
+					hdd_debug("pFTAssocReq is now at %02x%02x",
+						 (unsigned int)
+						 pFTAssocReq[0],
+						 (unsigned int)
+						 pFTAssocReq[1]);
+					assocReqlen =
+					    roam_info->nAssocReqLength -
+						FT_ASSOC_REQ_IES_OFFSET;
+				} else {
+					/*
+					 * This should contain only the
+					 * FTIEs
+					 */
+					assocReqlen =
+					    roam_info->nAssocReqLength;
+				}
+
+				hdd_debug("assocReqlen %d", assocReqlen);
+				hdd_debug("Assoc/Reassoc Req IE dump");
+				QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
+						   QDF_TRACE_LEVEL_DEBUG,
+						   pFTAssocReq,
+						   assocReqlen);
+			} else {
+				hdd_debug("AssocReq is NULL");
+				assocReqlen = 0;
+			}
+
+			if (roam_info->u.pConnectedProfile->AuthType ==
+			    eCSR_AUTH_TYPE_FT_RSN
+			    || roam_info->u.pConnectedProfile->AuthType ==
+			    eCSR_AUTH_TYPE_FT_RSN_PSK) {
+				if (ft_carrier_on) {
+					if (!hddDisconInProgress &&
+						roam_info->pBssDesc) {
+						struct cfg80211_bss *roam_bss;
+
+						/*
+						 * After roaming is completed,
+						 * active session count is
+						 * incremented as a part of
+						 * connect indication but
+						 * effectively the active
+						 * session count should still
+						 * be the same and hence upon
+						 * successful reassoc
+						 * decrement the active session
+						 * count here.
+						 */
+						if (!hdd_is_roam_sync_in_progress
+								(roam_info)) {
+						policy_mgr_decr_session_set_pcl(
+							hdd_ctx->psoc,
+							adapter->device_mode,
+							adapter->session_id);
+						hdd_green_ap_start_state_mc(
+							hdd_ctx,
+							adapter->device_mode,
+							false);
+						}
+						hdd_debug("ft_carrier_on is %d, sending roamed indication",
+							 ft_carrier_on);
+						chan =
+							ieee80211_get_channel
+								(adapter->wdev.wiphy,
+								(int)roam_info->pBssDesc->
+								channelId);
+
+						roam_bss =
+							hdd_cfg80211_get_bss(
+							adapter->wdev.wiphy,
+							chan,
+							roam_info->bssid.bytes,
+							roam_info->u.
+							pConnectedProfile->SSID.ssId,
+							roam_info->u.
+							pConnectedProfile->SSID.length);
+
+						cdp_hl_fc_set_td_limit(soc,
+						adapter->session_id,
+						sta_ctx->
+						conn_info.operationChannel);
+
+						hdd_send_roamed_ind(
+								dev,
+								roam_bss,
+								pFTAssocReq,
+								assocReqlen,
+								pFTAssocRsp,
+								assocRsplen);
+						wlan_hdd_send_roam_auth_event(
+							adapter,
+							roam_info->bssid.bytes,
+							pFTAssocReq,
+							assocReqlen,
+							pFTAssocRsp,
+							assocRsplen,
+							roam_info);
+					}
+					if (sme_get_ftptk_state
+						    (mac_handle,
+						    adapter->session_id)) {
+						sme_set_ftptk_state
+							(mac_handle,
+							adapter->session_id,
+							false);
+						roam_info->fAuthRequired =
+							false;
+
+						qdf_mem_copy(sta_ctx->
+							     roam_info.bssid,
+							     roam_info->bssid.bytes,
+							     QDF_MAC_ADDR_SIZE);
+						qdf_mem_copy(sta_ctx->
+							     roam_info.peer_mac,
+							     roam_info->peerMac.bytes,
+							     QDF_MAC_ADDR_SIZE);
+						sta_ctx->roam_info.roam_id =
+							roamId;
+						sta_ctx->roam_info.roam_status =
+							roamStatus;
+						sta_ctx->roam_info.
+						defer_key_complete = true;
+					}
+				} else if (!hddDisconInProgress) {
+					hdd_debug("ft_carrier_on is %d, sending connect indication",
+						 ft_carrier_on);
+					cdp_hl_fc_set_td_limit(soc,
+					adapter->session_id,
+					sta_ctx->conn_info.operationChannel);
+					hdd_connect_result(dev,
+							   roam_info->
+							   bssid.bytes,
+							   roam_info,
+							   pFTAssocReq,
+							   assocReqlen,
+							   pFTAssocRsp,
+							   assocRsplen,
+							   WLAN_STATUS_SUCCESS,
+							   GFP_KERNEL,
+							   false,
+							   roam_info->statusCode);
+				}
+			} else {
+				/*
+				 * wpa supplicant expecting WPA/RSN IE in
+				 * connect result.
+				 */
+				sme_roam_get_wpa_rsn_req_ie(mac_handle,
+							    adapter->session_id,
+							    &reqRsnLength,
+							    reqRsnIe);
+
+				sme_roam_get_wpa_rsn_rsp_ie(mac_handle,
+							    adapter->session_id,
+							    &rspRsnLength,
+							    rspRsnIe);
+				if (!hddDisconInProgress) {
+					if (ft_carrier_on)
+						hdd_send_re_assoc_event(dev,
+									adapter,
+									roam_info,
+									reqRsnIe,
+									reqRsnLength);
+					else {
+						hdd_debug("sending connect indication to nl80211:for bssid "
+							 MAC_ADDRESS_STR
+							 " result:%d and Status:%d",
+							 MAC_ADDR_ARRAY
+							 (roam_info->bssid.bytes),
+							 roamResult, roamStatus);
+
+						/* inform connect result to nl80211 */
+						hdd_connect_result(dev,
+								   roam_info->
+								   bssid.bytes,
+								   roam_info,
+								   pFTAssocReq,
+								   assocReqlen,
+								   pFTAssocRsp,
+								   assocRsplen,
+								   WLAN_STATUS_SUCCESS,
+								   GFP_KERNEL,
+								   false,
+								   roam_info->statusCode);
+					}
+					cdp_hl_fc_set_td_limit(soc,
+					adapter->session_id,
+					sta_ctx->conn_info.operationChannel);
+				}
+			}
+			if (!hddDisconInProgress) {
+				/*
+				 * Perform any WMM-related association
+				 * processing.
+				 */
+				hdd_wmm_assoc(adapter, roam_info,
+					      eCSR_BSS_TYPE_INFRASTRUCTURE);
+
+				/*
+				 * Register the Station with DP after associated
+				 */
+				qdf_status = hdd_roam_register_sta(adapter,
+						roam_info,
+						sta_ctx->conn_info.staId[0],
+						NULL, roam_info->pBssDesc);
+				hdd_debug("Enabling queues");
+				wlan_hdd_netif_queue_control(adapter,
+						WLAN_WAKE_ALL_NETIF_QUEUE,
+						WLAN_CONTROL_PATH);
+
+			}
+		} else {
+			/*
+			 * wpa supplicant expecting WPA/RSN IE in connect result
+			 * in case of reassociation also need to indicate it to
+			 * supplicant.
+			 */
+			sme_roam_get_wpa_rsn_req_ie(
+						mac_handle,
+						adapter->session_id,
+						&reqRsnLength, reqRsnIe);
+
+			cdp_hl_fc_set_td_limit(soc,
+				adapter->session_id,
+				sta_ctx->conn_info.operationChannel);
+			hdd_send_re_assoc_event(dev, adapter, roam_info,
+						reqRsnIe, reqRsnLength);
+			/* Reassoc successfully */
+			if (roam_info->fAuthRequired) {
+				qdf_status =
+					hdd_change_peer_state(adapter,
+						sta_ctx->conn_info.staId[0],
+						OL_TXRX_PEER_STATE_CONN,
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+						roam_info->roamSynchInProgress
+#else
+						false
+#endif
+						);
+				hdd_conn_set_authenticated(adapter, false);
+				hdd_objmgr_set_peer_mlme_auth_state(
+							adapter->vdev,
+							false);
+			} else {
+				hdd_debug("staId: %d Changing TL state to AUTHENTICATED",
+					 sta_ctx->conn_info.staId[0]);
+				qdf_status =
+					hdd_change_peer_state(adapter,
+						sta_ctx->conn_info.staId[0],
+						OL_TXRX_PEER_STATE_AUTH,
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+						roam_info->roamSynchInProgress
+#else
+						false
+#endif
+						);
+				hdd_conn_set_authenticated(adapter, true);
+				hdd_objmgr_set_peer_mlme_auth_state(
+							adapter->vdev,
+							true);
+			}
+
+			if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
+				/*
+				 * Perform any WMM-related association
+				 * processing
+				 */
+				hdd_wmm_assoc(adapter, roam_info,
+					      eCSR_BSS_TYPE_INFRASTRUCTURE);
+			}
+
+			/* Start the tx queues */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+			if (roam_info->roamSynchInProgress)
+				hdd_debug("LFR3:netif_tx_wake_all_queues");
+#endif
+			hdd_debug("Enabling queues");
+			wlan_hdd_netif_queue_control(adapter,
+						   WLAN_WAKE_ALL_NETIF_QUEUE,
+						   WLAN_CONTROL_PATH);
+		}
+
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			hdd_err("STA register with TL failed status: %d [%08X]",
+				qdf_status, qdf_status);
+		}
+#ifdef WLAN_FEATURE_11W
+		qdf_mem_zero(&adapter->hdd_stats.hdd_pmf_stats,
+			     sizeof(adapter->hdd_stats.hdd_pmf_stats));
+#endif
+		hdd_debug("check for SAP restart");
+		policy_mgr_check_concurrent_intf_and_restart_sap(
+			hdd_ctx->psoc);
+		if (roam_info->pBssDesc)
+			policy_mgr_checkn_update_hw_mode_single_mac_mode
+				(hdd_ctx->psoc,
+				 roam_info->pBssDesc->channelId);
+	} else {
+		bool connect_timeout = false;
+		/* do we need to change the HW mode */
+		policy_mgr_check_n_start_opportunistic_timer(hdd_ctx->psoc);
+		if (roam_info && roam_info->is_fils_connection &&
+		    eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE == roamResult)
+			qdf_copy_macaddr(&roam_info->bssid,
+					 &sta_ctx->requested_bssid);
+		if (roam_info)
+			hdd_err("wlan: connection failed with " MAC_ADDRESS_STR
+				 " result: %d and Status: %d",
+				 MAC_ADDR_ARRAY(roam_info->bssid.bytes),
+				 roamResult, roamStatus);
+		else
+			hdd_err("wlan: connection failed with " MAC_ADDRESS_STR
+				 " result: %d and Status: %d",
+				 MAC_ADDR_ARRAY(sta_ctx->requested_bssid.bytes),
+				 roamResult, roamStatus);
+
+		if ((eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE == roamResult) ||
+		   (roam_info &&
+		   ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
+					roam_info->statusCode) ||
+		   (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
+					roam_info->statusCode) ||
+		   (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
+					roam_info->statusCode)))) {
+			wlan_hdd_cfg80211_update_bss_list(adapter,
+				roam_info ?
+				roam_info->bssid.bytes :
+				sta_ctx->requested_bssid.bytes);
+			sme_remove_bssid_from_scan_list(mac_handle,
+				roam_info ?
+				roam_info->bssid.bytes :
+				sta_ctx->requested_bssid.bytes);
+			connect_timeout = true;
+		}
+
+		/*
+		 * CR465478: Only send up a connection failure result when CSR
+		 * has completed operation - with a ASSOCIATION_FAILURE status.
+		 */
+		if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
+		    && !hddDisconInProgress) {
+			if (roam_info) {
+				hdd_err("send connect failure to nl80211: for bssid "
+					MAC_ADDRESS_STR
+					" result: %d and Status: %d reasoncode: %d",
+					MAC_ADDR_ARRAY(roam_info->bssid.bytes),
+					roamResult, roamStatus,
+					roam_info->reasonCode);
+				sta_ctx->conn_info.assoc_status_code =
+					roam_info->statusCode;
+			} else {
+				hdd_err("connect failed: for bssid "
+				       MAC_ADDRESS_STR
+				       " result: %d and status: %d ",
+				       MAC_ADDR_ARRAY(sta_ctx->requested_bssid.bytes),
+				       roamResult, roamStatus);
+			}
+			hdd_debug("Invoking packetdump deregistration API");
+			wlan_deregister_txrx_packetdump();
+
+			/* inform association failure event to nl80211 */
+			if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
+			    roamResult) {
+				if (roam_info)
+					hdd_connect_result(dev,
+						roam_info->bssid.bytes,
+						roam_info, NULL, 0, NULL, 0,
+						WLAN_STATUS_ASSOC_DENIED_UNSPEC,
+						GFP_KERNEL,
+						connect_timeout,
+						roam_info->statusCode);
+				else
+					hdd_connect_result(dev,
+						sta_ctx->requested_bssid.bytes,
+						NULL, NULL, 0, NULL, 0,
+						WLAN_STATUS_ASSOC_DENIED_UNSPEC,
+						GFP_KERNEL,
+						connect_timeout,
+						timeout_reason);
+			} else {
+				if (roam_info)
+					hdd_connect_result(dev,
+						roam_info->bssid.bytes,
+						roam_info, NULL, 0, NULL, 0,
+						roam_info->reasonCode ?
+						roam_info->reasonCode :
+						WLAN_STATUS_UNSPECIFIED_FAILURE,
+						GFP_KERNEL,
+						connect_timeout,
+						roam_info->statusCode);
+				else
+					hdd_connect_result(dev,
+						sta_ctx->requested_bssid.bytes,
+						NULL, NULL, 0, NULL, 0,
+						WLAN_STATUS_UNSPECIFIED_FAILURE,
+						GFP_KERNEL,
+						connect_timeout,
+						timeout_reason);
+			}
+			hdd_clear_roam_profile_ie(adapter);
+		} else  if ((eCSR_ROAM_CANCELLED == roamStatus
+		    && !hddDisconInProgress)) {
+			hdd_connect_result(dev,
+					   sta_ctx->requested_bssid.bytes,
+					   NULL, NULL, 0, NULL, 0,
+					   WLAN_STATUS_UNSPECIFIED_FAILURE,
+					   GFP_KERNEL,
+					   connect_timeout,
+					   timeout_reason);
+		}
+
+		/*
+		 * Set connection state to eConnectionState_NotConnected only
+		 * when CSR has completed operation - with a
+		 * ASSOCIATION_FAILURE or eCSR_ROAM_CANCELLED status.
+		 */
+		if (((eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus) ||
+			(eCSR_ROAM_CANCELLED == roamStatus))
+		    && !hddDisconInProgress) {
+			hdd_conn_set_connection_state(adapter,
+					eConnectionState_NotConnected);
+		}
+		hdd_wmm_init(adapter);
+
+		hdd_debug("Disabling queues");
+		wlan_hdd_netif_queue_control(adapter,
+					   WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+					   WLAN_CONTROL_PATH);
+		/*
+		 * if hddDisconInProgress is set and roamResult is
+		 * eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE that mean HDD is
+		 * waiting on disconnect_comp_var so unblock anyone waiting for
+		 * disconnect to complete.
+		 */
+		if ((roamResult == eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE) &&
+		    hddDisconInProgress)
+			complete(&adapter->disconnect_comp_var);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_roam_ibss_indication_handler() - update the status of the IBSS
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ * @roamId: roam id
+ * @roamStatus: roam status
+ * @roamResult: roam result
+ *
+ * Here we update the status of the Ibss when we receive information that we
+ * have started/joined an ibss session.
+ *
+ * Return: none
+ */
+static void hdd_roam_ibss_indication_handler(struct hdd_adapter *adapter,
+					     struct csr_roam_info *roam_info,
+					     uint32_t roamId,
+					     eRoamCmdStatus roamStatus,
+					     eCsrRoamResult roamResult)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_debug("%s: id %d, status %d, result %d",
+		 adapter->dev->name, roamId,
+		 roamStatus, roamResult);
+
+	switch (roamResult) {
+	/* both IBSS Started and IBSS Join should come in here. */
+	case eCSR_ROAM_RESULT_IBSS_STARTED:
+	case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
+	case eCSR_ROAM_RESULT_IBSS_COALESCED:
+	{
+		struct hdd_station_ctx *hdd_sta_ctx =
+			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		struct qdf_mac_addr broadcastMacAddr = QDF_MAC_ADDR_BCAST_INIT;
+
+		if (NULL == roam_info) {
+			QDF_ASSERT(0);
+			return;
+		}
+
+		/* When IBSS Started comes from CSR, we need to move
+		 * connection state to IBSS Disconnected (meaning no peers
+		 * are in the IBSS).
+		 */
+		hdd_conn_set_connection_state(adapter,
+				      eConnectionState_IbssDisconnected);
+		/* notify wmm */
+		hdd_wmm_connect(adapter, roam_info,
+				eCSR_BSS_TYPE_IBSS);
+
+		hdd_sta_ctx->broadcast_staid = roam_info->staId;
+
+		if (roam_info->staId < HDD_MAX_ADAPTERS)
+			hdd_ctx->sta_to_adapter[roam_info->staId] =
+				adapter;
+		else
+			hdd_debug("invalid sta id %d", roam_info->staId);
+
+		hdd_roam_register_sta(adapter, roam_info,
+				      roam_info->staId,
+				      &broadcastMacAddr,
+				      roam_info->pBssDesc);
+
+		if (roam_info->pBssDesc) {
+			struct cfg80211_bss *bss;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
+			struct ieee80211_channel *chan;
+			int chan_no;
+			unsigned int freq;
+#endif
+			/* we created the IBSS, notify supplicant */
+			hdd_debug("%s: created ibss " MAC_ADDRESS_STR,
+				adapter->dev->name,
+				MAC_ADDR_ARRAY(
+					roam_info->pBssDesc->bssId));
+
+			/* we must first give cfg80211 the BSS information */
+			bss = wlan_hdd_cfg80211_update_bss_db(adapter,
+								roam_info);
+			if (NULL == bss) {
+				hdd_err("%s: unable to create IBSS entry",
+					adapter->dev->name);
+				return;
+			}
+			hdd_debug("Enabling queues");
+			wlan_hdd_netif_queue_control(adapter,
+					WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
+					WLAN_CONTROL_PATH);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
+			chan_no = roam_info->pBssDesc->channelId;
+
+			if (chan_no <= 14)
+				freq = ieee80211_channel_to_frequency(chan_no,
+					  HDD_NL80211_BAND_2GHZ);
+			else
+				freq = ieee80211_channel_to_frequency(chan_no,
+					  HDD_NL80211_BAND_5GHZ);
+
+			chan = ieee80211_get_channel(adapter->wdev.wiphy, freq);
+
+			if (chan)
+				cfg80211_ibss_joined(adapter->dev,
+						     bss->bssid, chan,
+						     GFP_KERNEL);
+			else
+				hdd_warn("%s: chanId: %d, can't find channel",
+				adapter->dev->name,
+				(int)roam_info->pBssDesc->channelId);
+#else
+			cfg80211_ibss_joined(adapter->dev, bss->bssid,
+					     GFP_KERNEL);
+#endif
+			cfg80211_put_bss(
+				hdd_ctx->wiphy,
+				bss);
+		}
+		if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
+			policy_mgr_incr_active_session(hdd_ctx->psoc,
+				adapter->device_mode, adapter->session_id);
+			hdd_green_ap_start_state_mc(hdd_ctx,
+						    adapter->device_mode, true);
+		} else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
+				eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
+			policy_mgr_update_connection_info(hdd_ctx->psoc,
+					adapter->session_id);
+		}
+		break;
+	}
+
+	case eCSR_ROAM_RESULT_IBSS_START_FAILED:
+	{
+		hdd_err("%s: unable to create IBSS", adapter->dev->name);
+		break;
+	}
+
+	default:
+		hdd_err("%s: unexpected result %d",
+			adapter->dev->name, (int)roamResult);
+		break;
+	}
+}
+
+/**
+ * hdd_save_peer() - Save peer MAC address in adapter peer table.
+ * @sta_ctx: pointer to hdd station context
+ * @sta_id: station ID
+ * @peer_mac_addr: mac address of new peer
+ *
+ * This information is passed to iwconfig later. The peer that joined
+ * last is passed as information to iwconfig.
+
+ * Return: true if success, false otherwise
+ */
+bool hdd_save_peer(struct hdd_station_ctx *sta_ctx, uint8_t sta_id,
+		   struct qdf_mac_addr *peer_mac_addr)
+{
+	int idx;
+
+	for (idx = 0; idx < SIR_MAX_NUM_STA_IN_IBSS; idx++) {
+		if (HDD_WLAN_INVALID_STA_ID == sta_ctx->conn_info.staId[idx]) {
+			hdd_debug("adding peer: %pM, sta_id: %d, at idx: %d",
+				 peer_mac_addr, sta_id, idx);
+			sta_ctx->conn_info.staId[idx] = sta_id;
+			qdf_copy_macaddr(
+				&sta_ctx->conn_info.peerMacAddress[idx],
+				peer_mac_addr);
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * hdd_delete_peer() - removes peer from hdd station context peer table
+ * @sta_ctx: pointer to hdd station context
+ * @sta_id: station ID
+ *
+ * Return: None
+ */
+void hdd_delete_peer(struct hdd_station_ctx *sta_ctx, uint8_t sta_id)
+{
+	int i;
+
+	for (i = 0; i < SIR_MAX_NUM_STA_IN_IBSS; i++) {
+		if (sta_id == sta_ctx->conn_info.staId[i]) {
+			sta_ctx->conn_info.staId[i] = HDD_WLAN_INVALID_STA_ID;
+			return;
+		}
+	}
+}
+
+/**
+ * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
+ * @adapter: pointer to adapter
+ * @staId: station id
+ *
+ * Return:
+ *	true if we remove MAX_PEERS or less STA
+ *	false otherwise.
+ */
+static bool roam_remove_ibss_station(struct hdd_adapter *adapter, uint8_t staId)
+{
+	bool fSuccess = false;
+	int idx = 0;
+	uint8_t valid_idx = 0;
+	uint8_t del_idx = 0;
+	uint8_t empty_slots = 0;
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	for (idx = 0; idx < MAX_PEERS; idx++) {
+		if (staId == sta_ctx->conn_info.staId[idx]) {
+			sta_ctx->conn_info.staId[idx] =
+						HDD_WLAN_INVALID_STA_ID;
+
+			qdf_zero_macaddr(&sta_ctx->conn_info.
+					 peerMacAddress[idx]);
+
+			fSuccess = true;
+
+			/*
+			 * Note the deleted Index, if its 0 we need special
+			 * handling.
+			 */
+			del_idx = idx;
+
+			empty_slots++;
+		} else {
+			if (sta_ctx->conn_info.staId[idx] !=
+					HDD_WLAN_INVALID_STA_ID) {
+				valid_idx = idx;
+			} else {
+				/* Found an empty slot */
+				empty_slots++;
+			}
+		}
+	}
+
+	if (MAX_PEERS == empty_slots) {
+		/* Last peer departed, set the IBSS state appropriately */
+		hdd_conn_set_connection_state(adapter,
+				eConnectionState_IbssDisconnected);
+		hdd_debug("Last IBSS Peer Departed!!!");
+	}
+	/* Find next active staId, to have a valid sta trigger for TL. */
+	if (fSuccess == true) {
+		if (del_idx == 0) {
+			if (sta_ctx->conn_info.staId[valid_idx] !=
+					HDD_WLAN_INVALID_STA_ID) {
+				sta_ctx->conn_info.staId[0] =
+					sta_ctx->conn_info.staId[valid_idx];
+				qdf_copy_macaddr(&sta_ctx->conn_info.
+						 peerMacAddress[0],
+						 &sta_ctx->conn_info.
+						 peerMacAddress[valid_idx]);
+
+				sta_ctx->conn_info.staId[valid_idx] =
+							HDD_WLAN_INVALID_STA_ID;
+				qdf_zero_macaddr(&sta_ctx->conn_info.
+						 peerMacAddress[valid_idx]);
+			}
+		}
+	}
+	return fSuccess;
+}
+
+/**
+ * roam_ibss_connect_handler() - IBSS connection handler
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ *
+ * We update the status of the IBSS to connected in this function.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS roam_ibss_connect_handler(struct hdd_adapter *adapter,
+					    struct csr_roam_info *roam_info)
+{
+	struct cfg80211_bss *bss;
+	/*
+	 * Set the internal connection state to show 'IBSS Connected' (IBSS with
+	 * a partner stations).
+	 */
+	hdd_conn_set_connection_state(adapter, eConnectionState_IbssConnected);
+
+	/* Save the connection info from CSR... */
+	hdd_conn_save_connect_info(adapter, roam_info, eCSR_BSS_TYPE_IBSS);
+
+	/* Send the bssid address to the wext. */
+	hdd_send_association_event(adapter->dev, roam_info);
+	/* add bss_id to cfg80211 data base */
+	bss = wlan_hdd_cfg80211_update_bss_db(adapter, roam_info);
+	if (NULL == bss) {
+		hdd_err("%s: unable to create IBSS entry",
+		       adapter->dev->name);
+		return QDF_STATUS_E_FAILURE;
+	}
+	cfg80211_put_bss(
+		WLAN_HDD_GET_CTX(adapter)->wiphy,
+		bss);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_roam_mic_error_indication_handler() - MIC error indication handler
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ * @roamId: roam id
+ * @roamStatus: roam status
+ * @roamResult: roam result
+ *
+ * This function indicates the Mic failure to the supplicant
+ *
+ * Return: None
+ */
+static void
+hdd_roam_mic_error_indication_handler(struct hdd_adapter *adapter,
+				      struct csr_roam_info *roam_info)
+{
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	tSirMicFailureInfo *mic_failure_info;
+
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState)
+		return;
+
+	mic_failure_info = roam_info->u.pMICFailureInfo;
+	cfg80211_michael_mic_failure(adapter->dev,
+				     mic_failure_info->taMacAddr,
+				     mic_failure_info->multicast ?
+					NL80211_KEYTYPE_GROUP :
+					NL80211_KEYTYPE_PAIRWISE,
+				     mic_failure_info->keyId,
+				     mic_failure_info->TSC,
+				     GFP_KERNEL);
+}
+
+/**
+ * roam_roam_connect_status_update_handler() - IBSS connect status update
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ * @roamId: roam id
+ * @roamStatus: roam status
+ * @roamResult: roam result
+ *
+ * The Ibss connection status is updated regularly here in this function.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS
+roam_roam_connect_status_update_handler(struct hdd_adapter *adapter,
+					struct csr_roam_info *roam_info,
+					uint32_t roamId,
+					eRoamCmdStatus roamStatus,
+					eCsrRoamResult roamResult)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	QDF_STATUS qdf_status;
+
+	switch (roamResult) {
+	case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
+	{
+		struct hdd_station_ctx *sta_ctx =
+			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		struct station_info *stainfo;
+		eCsrEncryptionType encr_type = sta_ctx->ibss_enc_key.encType;
+
+		hdd_debug("IBSS New Peer indication from SME "
+			 "with peerMac " MAC_ADDRESS_STR " BSSID: "
+			 MAC_ADDRESS_STR " and stationID= %d",
+			 MAC_ADDR_ARRAY(roam_info->peerMac.bytes),
+			 MAC_ADDR_ARRAY(sta_ctx->conn_info.bssId.bytes),
+			 roam_info->staId);
+
+		if (!hdd_save_peer
+			    (WLAN_HDD_GET_STATION_CTX_PTR(adapter),
+			    roam_info->staId,
+			    &roam_info->peerMac)) {
+			hdd_warn("Max reached: Can't register new IBSS peer");
+			break;
+		}
+
+		if (roam_info->staId < HDD_MAX_ADAPTERS)
+			hdd_ctx->sta_to_adapter[roam_info->staId] = adapter;
+		else
+			hdd_debug("invalid sta id %d", roam_info->staId);
+
+		if (hdd_is_key_install_required_for_ibss(encr_type))
+			roam_info->fAuthRequired = true;
+
+		/* Register the Station with TL for the new peer. */
+		qdf_status = hdd_roam_register_sta(adapter,
+						   roam_info,
+						   roam_info->staId,
+						   &roam_info->peerMac,
+						   roam_info->pBssDesc);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			hdd_err("Cannot register STA with TL for IBSS. qdf_status: %d [%08X]",
+				qdf_status, qdf_status);
+		}
+		sta_ctx->ibss_sta_generation++;
+		stainfo = qdf_mem_malloc(sizeof(*stainfo));
+		if (!stainfo)
+			return QDF_STATUS_E_NOMEM;
+
+		stainfo->filled = 0;
+		stainfo->generation = sta_ctx->ibss_sta_generation;
+
+		cfg80211_new_sta(adapter->dev,
+				 (const u8 *)roam_info->peerMac.bytes,
+				 stainfo, GFP_KERNEL);
+		qdf_mem_free(stainfo);
+
+		if (hdd_is_key_install_required_for_ibss(encr_type)) {
+			sta_ctx->ibss_enc_key.keyDirection =
+				eSIR_TX_RX;
+			qdf_copy_macaddr(&sta_ctx->ibss_enc_key.peerMac,
+					 &roam_info->peerMac);
+
+			hdd_debug("New peer joined set PTK encType=%d",
+				 encr_type);
+
+			qdf_status =
+				sme_roam_set_key(hdd_ctx->mac_handle,
+						 adapter->session_id,
+						 &sta_ctx->ibss_enc_key,
+						 &roamId);
+
+			if (QDF_STATUS_SUCCESS != qdf_status) {
+				hdd_err("sme_roam_set_key failed, status: %d",
+					qdf_status);
+				return QDF_STATUS_E_FAILURE;
+			}
+		}
+		hdd_debug("Enabling queues");
+		wlan_hdd_netif_queue_control(adapter,
+					   WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
+					   WLAN_CONTROL_PATH);
+		break;
+	}
+
+	case eCSR_ROAM_RESULT_IBSS_CONNECT:
+	{
+
+		roam_ibss_connect_handler(adapter, roam_info);
+
+		break;
+	}
+	case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
+	{
+		struct hdd_station_ctx *sta_ctx =
+			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+		if (!roam_remove_ibss_station(adapter, roam_info->staId))
+			hdd_warn("IBSS peer departed by cannot find peer in our registration table with TL");
+
+		hdd_debug("IBSS Peer Departed from SME "
+			 "with peerMac " MAC_ADDRESS_STR " BSSID: "
+			 MAC_ADDRESS_STR " and stationID= %d",
+			 MAC_ADDR_ARRAY(roam_info->peerMac.bytes),
+			 MAC_ADDR_ARRAY(sta_ctx->conn_info.bssId.bytes),
+			 roam_info->staId);
+
+		hdd_roam_deregister_sta(adapter, roam_info->staId);
+
+		if (roam_info->staId < HDD_MAX_ADAPTERS)
+			hdd_ctx->sta_to_adapter[roam_info->staId] = NULL;
+		else
+			hdd_debug("invalid sta id %d", roam_info->staId);
+
+		sta_ctx->ibss_sta_generation++;
+
+		cfg80211_del_sta(adapter->dev,
+				 (const u8 *)&roam_info->peerMac.bytes,
+				 GFP_KERNEL);
+		break;
+	}
+	case eCSR_ROAM_RESULT_IBSS_INACTIVE:
+	{
+		hdd_debug("Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
+		/* Stop only when we are inactive */
+		hdd_debug("Disabling queues");
+		wlan_hdd_netif_queue_control(adapter,
+					   WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+					   WLAN_CONTROL_PATH);
+		hdd_conn_set_connection_state(adapter,
+					      eConnectionState_NotConnected);
+
+		/* Send the bssid address to the wext. */
+		hdd_send_association_event(adapter->dev, roam_info);
+		break;
+	}
+	default:
+		break;
+
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_WLAN_TDLS
+QDF_STATUS hdd_roam_register_tdlssta(struct hdd_adapter *adapter,
+				     const uint8_t *peerMac, uint16_t staId,
+				     uint8_t qos)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	struct ol_txrx_desc_type staDesc = { 0 };
+	struct ol_txrx_ops txrx_ops;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	/*
+	 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
+	 * be peer MAC, here we are working on direct Link
+	 */
+	staDesc.sta_id = staId;
+
+	/* set the QoS field appropriately .. */
+	staDesc.is_qos_enabled = qos;
+
+	/* Register the vdev transmit and receive functions */
+	qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
+	txrx_ops.rx.rx = hdd_rx_packet_cbk;
+	cdp_vdev_register(soc,
+		(struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
+		(struct cdp_pdev *)pdev, adapter->session_id),
+		adapter, (struct cdp_ctrl_objmgr_vdev *)adapter->vdev,
+		&txrx_ops);
+	adapter->tx_fn = txrx_ops.tx.tx;
+	txrx_ops.rx.stats_rx = hdd_tx_rx_collect_connectivity_stats_info;
+
+	/* Register the Station with TL...  */
+	qdf_status = cdp_peer_register(soc,
+			(struct cdp_pdev *)pdev, &staDesc);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("cdp_peer_register() failed Status: %d [0x%08X]",
+			qdf_status, qdf_status);
+		return qdf_status;
+	}
+
+	return qdf_status;
+}
+
+/**
+ * hdd_roam_deregister_tdlssta() - deregister new TDLS station
+ * @adapter: pointer to adapter
+ * @staId: station identifier
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_roam_deregister_tdlssta(struct hdd_adapter *adapter,
+				       uint8_t staId)
+{
+	QDF_STATUS qdf_status;
+
+	qdf_status = cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
+			(struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX),
+			staId);
+
+	return qdf_status;
+}
+
+#else
+
+inline QDF_STATUS hdd_roam_deregister_tdlssta(struct hdd_adapter *adapter,
+					      uint8_t staId)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+hdd_roam_tdls_status_update_handler(struct hdd_adapter *adapter,
+				    struct csr_roam_info *roam_info,
+				    uint32_t roamId,
+				    eRoamCmdStatus roamStatus,
+				    eCsrRoamResult roamResult)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
+ * @adapter:     pointer to the adapter
+ * @nFrameLength: Length of the unprotected frame being passed
+ * @pbFrames:     Pointer to the frame buffer
+ * @frameType:    802.11 frame type
+ *
+ * This function forwards the unprotected management frame to the supplicant.
+ *
+ * Return: nothing
+ */
+static void
+hdd_indicate_unprot_mgmt_frame(struct hdd_adapter *adapter,
+			       uint32_t nFrameLength,
+			       uint8_t *pbFrames, uint8_t frameType)
+{
+	uint8_t type = 0;
+	uint8_t subType = 0;
+
+	hdd_debug("Frame Type = %d Frame Length = %d",
+		 frameType, nFrameLength);
+
+	/* Sanity Checks */
+	if (NULL == adapter) {
+		hdd_err("adapter is NULL");
+		return;
+	}
+
+	if (NULL == adapter->dev) {
+		hdd_err("adapter->dev is NULL");
+		return;
+	}
+
+	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
+		hdd_err("adapter has invalid magic");
+		return;
+	}
+
+	if (!nFrameLength) {
+		hdd_err("Frame Length is Invalid ZERO");
+		return;
+	}
+
+	if (NULL == pbFrames) {
+		hdd_err("pbFrames is NULL");
+		return;
+	}
+
+	type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
+	subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
+
+	/* Get adapter from Destination mac address of the frame */
+	if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
+		cfg80211_rx_unprot_mlme_mgmt(adapter->dev, pbFrames,
+					     nFrameLength);
+#else
+		cfg80211_send_unprot_disassoc(adapter->dev, pbFrames,
+					      nFrameLength);
+#endif
+		adapter->hdd_stats.hdd_pmf_stats.num_unprot_disassoc_rx++;
+	} else if (type == SIR_MAC_MGMT_FRAME &&
+		   subType == SIR_MAC_MGMT_DEAUTH) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
+		cfg80211_rx_unprot_mlme_mgmt(adapter->dev, pbFrames,
+					     nFrameLength);
+#else
+		cfg80211_send_unprot_deauth(adapter->dev, pbFrames,
+					    nFrameLength);
+#endif
+		adapter->hdd_stats.hdd_pmf_stats.num_unprot_deauth_rx++;
+	} else {
+		hdd_warn("Frame type %d and subtype %d are not valid",
+			type, subType);
+		return;
+	}
+}
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * hdd_indicate_tsm_ie() - send traffic stream metrics ie
+ * @adapter: pointer to adapter
+ * @tid: traffic identifier
+ * @state: state
+ * @measInterval: measurement interval
+ *
+ * This function sends traffic stream metrics IE information to
+ * the supplicant via wireless event.
+ *
+ * Return: none
+ */
+static void
+hdd_indicate_tsm_ie(struct hdd_adapter *adapter, uint8_t tid,
+		    uint8_t state, uint16_t measInterval)
+{
+	union iwreq_data wrqu;
+	char buf[IW_CUSTOM_MAX + 1];
+	int nBytes = 0;
+
+	if (NULL == adapter)
+		return;
+
+	/* create the event */
+	memset(&wrqu, '\0', sizeof(wrqu));
+	memset(buf, '\0', sizeof(buf));
+
+	hdd_debug("TSM Ind tid(%d) state(%d) MeasInt(%d)",
+		 tid, state, measInterval);
+
+	nBytes =
+		snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
+			 measInterval);
+
+	wrqu.data.pointer = buf;
+	wrqu.data.length = nBytes;
+	/* send the event */
+	wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buf);
+}
+
+/**
+ * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ *
+ * This function sends cckm preauth indication to the supplicant
+ * via wireless custom event.
+ *
+ * Return: none
+ */
+static void
+hdd_indicate_cckm_pre_auth(struct hdd_adapter *adapter,
+			   struct csr_roam_info *roam_info)
+{
+	union iwreq_data wrqu;
+	char buf[IW_CUSTOM_MAX + 1];
+	char *pos = buf;
+	int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
+
+	if ((NULL == adapter) || (NULL == roam_info))
+		return;
+
+	/* create the event */
+	memset(&wrqu, '\0', sizeof(wrqu));
+	memset(buf, '\0', sizeof(buf));
+
+	/* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
+	hdd_debug("CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
+		 MAC_ADDR_ARRAY(roam_info->bssid.bytes),
+		 roam_info->timestamp[0], roam_info->timestamp[1]);
+
+	nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
+	pos += nBytes;
+	freeBytes -= nBytes;
+
+	qdf_mem_copy(pos, roam_info->bssid.bytes, QDF_MAC_ADDR_SIZE);
+	pos += QDF_MAC_ADDR_SIZE;
+	freeBytes -= QDF_MAC_ADDR_SIZE;
+
+	nBytes = snprintf(pos, freeBytes, " %u:%u",
+			  roam_info->timestamp[0], roam_info->timestamp[1]);
+	freeBytes -= nBytes;
+
+	wrqu.data.pointer = buf;
+	wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
+
+	/* send the event */
+	wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buf);
+}
+
+/**
+ * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ *
+ * Return: none
+ */
+static void
+hdd_indicate_ese_adj_ap_rep_ind(struct hdd_adapter *adapter,
+				struct csr_roam_info *roam_info)
+{
+	union iwreq_data wrqu;
+	char buf[IW_CUSTOM_MAX + 1];
+	int nBytes = 0;
+
+	if ((NULL == adapter) || (NULL == roam_info))
+		return;
+
+	/* create the event */
+	memset(&wrqu, '\0', sizeof(wrqu));
+	memset(buf, '\0', sizeof(buf));
+
+	hdd_debug("CCXADJAPREP=%u", roam_info->tsmRoamDelay);
+
+	nBytes =
+		snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
+			 roam_info->tsmRoamDelay);
+
+	wrqu.data.pointer = buf;
+	wrqu.data.length = nBytes;
+
+	/* send the event */
+	wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buf);
+}
+
+/**
+ * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
+ * @adapter: pointer to adapter
+ * @measurementToken: measurement token
+ * @flag: flag
+ * @numBss: number of bss
+ *
+ * If the measurement is none and no scan results found,
+ * indicate the supplicant about measurement done.
+ *
+ * Return: none
+ */
+void
+hdd_indicate_ese_bcn_report_no_results(const struct hdd_adapter *adapter,
+				       const uint16_t measurementToken,
+				       const bool flag, const uint8_t numBss)
+{
+	union iwreq_data wrqu;
+	char buf[IW_CUSTOM_MAX];
+	char *pos = buf;
+	int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
+
+	memset(&wrqu, '\0', sizeof(wrqu));
+	memset(buf, '\0', sizeof(buf));
+
+	hdd_debug("CCXBCNREP=%d %d %d", measurementToken,
+		 flag, numBss);
+
+	nBytes =
+		snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
+			 flag, numBss);
+
+	wrqu.data.pointer = buf;
+	wrqu.data.length = nBytes;
+	/* send the event */
+	wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buf);
+}
+
+/**
+ * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ *
+ * If the measurement is none and no scan results found,
+ * indicate the supplicant about measurement done.
+ *
+ * Return: none
+ */
+static void
+hdd_indicate_ese_bcn_report_ind(const struct hdd_adapter *adapter,
+				const struct csr_roam_info *roam_info)
+{
+	union iwreq_data wrqu;
+	char buf[IW_CUSTOM_MAX];
+	char *pos = buf;
+	int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
+	uint8_t i = 0, len = 0;
+	uint8_t tot_bcn_ieLen = 0;  /* total size of the beacon report data */
+	uint8_t lastSent = 0, sendBss = 0;
+	int bcnRepFieldSize =
+		sizeof(roam_info->pEseBcnReportRsp->bcnRepBssInfo[0].
+		       bcnReportFields);
+	uint8_t ieLenByte = 1;
+	/*
+	 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
+	 */
+#define ESEBCNREPHEADER_LEN  (18)
+
+	if ((NULL == adapter) || (NULL == roam_info))
+		return;
+
+	/*
+	 * Custom event can pass maximum of 256 bytes of data,
+	 * based on the IE len we need to identify how many BSS info can
+	 * be filled in to custom event data.
+	 */
+	/*
+	 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
+	 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
+	 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
+	 */
+
+	if ((roam_info->pEseBcnReportRsp->flag >> 1)
+	    && (!roam_info->pEseBcnReportRsp->numBss)) {
+		hdd_debug("Measurement Done but no scan results");
+		/* If the measurement is none and no scan results found,
+		 * indicate the supplicant about measurement done
+		 */
+		hdd_indicate_ese_bcn_report_no_results(
+				adapter,
+				roam_info->pEseBcnReportRsp->
+				measurementToken,
+				roam_info->pEseBcnReportRsp->flag,
+				roam_info->pEseBcnReportRsp->numBss);
+	} else {
+		while (lastSent < roam_info->pEseBcnReportRsp->numBss) {
+			memset(&wrqu, '\0', sizeof(wrqu));
+			memset(buf, '\0', sizeof(buf));
+			tot_bcn_ieLen = 0;
+			sendBss = 0;
+			pos = buf;
+			freeBytes = IW_CUSTOM_MAX;
+
+			for (i = lastSent;
+			     i < roam_info->pEseBcnReportRsp->numBss; i++) {
+				len =
+					bcnRepFieldSize + ieLenByte +
+					roam_info->pEseBcnReportRsp->
+					bcnRepBssInfo[i].ieLen;
+				if ((len + tot_bcn_ieLen) >
+				    (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
+					break;
+				}
+				tot_bcn_ieLen += len;
+				sendBss++;
+				hdd_debug("i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
+					 i, bcnRepFieldSize, 1,
+					 roam_info->pEseBcnReportRsp->
+					 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
+			}
+
+			hdd_debug("Sending %d BSS Info", sendBss);
+			hdd_debug("CCXBCNREP=%d %d %d %d",
+				 roam_info->pEseBcnReportRsp->measurementToken,
+				 roam_info->pEseBcnReportRsp->flag, sendBss,
+				 tot_bcn_ieLen);
+
+			nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
+					  roam_info->pEseBcnReportRsp->
+					  measurementToken,
+					  roam_info->pEseBcnReportRsp->flag,
+					  sendBss);
+			pos += nBytes;
+			freeBytes -= nBytes;
+
+			/* Copy total Beacon report data length */
+			qdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
+				     sizeof(tot_bcn_ieLen));
+			pos += sizeof(tot_bcn_ieLen);
+			freeBytes -= sizeof(tot_bcn_ieLen);
+
+			for (i = 0; i < sendBss; i++) {
+				hdd_debug("ChanNum(%d) Spare(%d) MeasDuration(%d)"
+				       " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
+				       " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
+				       " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       ChanNum,
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       Spare,
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       MeasDuration,
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       PhyType,
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       RecvSigPower,
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       ParentTsf,
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       TargetTsf[0],
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       TargetTsf[1],
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       BcnInterval,
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       CapabilityInfo,
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       Bssid[0],
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       Bssid[1],
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       Bssid[2],
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       Bssid[3],
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       Bssid[4],
+				       roam_info->pEseBcnReportRsp->
+				       bcnRepBssInfo[i +
+						     lastSent].bcnReportFields.
+				       Bssid[5]);
+
+				/* bcn report fields are copied */
+				len =
+					sizeof(roam_info->pEseBcnReportRsp->
+					       bcnRepBssInfo[i +
+							     lastSent].
+					       bcnReportFields);
+				qdf_mem_copy(pos,
+					     (char *)&roam_info->
+					     pEseBcnReportRsp->bcnRepBssInfo[i +
+									     lastSent].
+					     bcnReportFields, len);
+				pos += len;
+				freeBytes -= len;
+
+				/* Add 1 byte of ie len */
+				len =
+					roam_info->pEseBcnReportRsp->
+					bcnRepBssInfo[i + lastSent].ieLen;
+				qdf_mem_copy(pos, (char *)&len, sizeof(len));
+				pos += sizeof(len);
+				freeBytes -= sizeof(len);
+
+				/* copy IE from scan results */
+				qdf_mem_copy(pos,
+					     (char *)roam_info->
+					     pEseBcnReportRsp->bcnRepBssInfo[i +
+									     lastSent].
+					     pBuf, len);
+				pos += len;
+				freeBytes -= len;
+			}
+
+			wrqu.data.pointer = buf;
+			wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
+
+			/* send the event */
+			wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu,
+					    buf);
+			lastSent += sendBss;
+		}
+	}
+}
+
+#endif /* FEATURE_WLAN_ESE */
+
+/**
+ * hdd_is_8021x_sha256_auth_type() - check authentication type to 8021x_sha256
+ * @sta_ctx:	Station Context
+ *
+ * API to check if the connection authentication type is 8021x_sha256.
+ *
+ * Return: bool
+ */
+#ifdef WLAN_FEATURE_11W
+static inline bool
+hdd_is_8021x_sha256_auth_type(struct hdd_station_ctx *sta_ctx)
+{
+	return eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
+				sta_ctx->conn_info.authType;
+}
+#else
+static inline bool
+hdd_is_8021x_sha256_auth_type(struct hdd_station_ctx *sta_ctx)
+{
+	return false;
+}
+#endif
+
+/*
+ * hdd_roam_channel_switch_handler() - hdd channel switch handler
+ * @adapter: Pointer to adapter context
+ * @roam_info: Pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_roam_channel_switch_handler(struct hdd_adapter *adapter,
+					    struct csr_roam_info *roam_info)
+{
+	struct hdd_chan_change_params chan_change;
+	struct cfg80211_bss *bss;
+	struct net_device *dev = adapter->dev;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
+
+	hdd_debug("channel switch for session:%d to channel:%d",
+		adapter->session_id, roam_info->chan_info.chan_id);
+
+	/* Enable Roaming on STA interface which was disabled before CSA */
+	if (adapter->device_mode == QDF_STA_MODE)
+		sme_start_roaming(mac_handle, adapter->session_id,
+				  REASON_DRIVER_ENABLED);
+
+	chan_change.chan = roam_info->chan_info.chan_id;
+	chan_change.chan_params.ch_width =
+		roam_info->chan_info.ch_width;
+	chan_change.chan_params.sec_ch_offset =
+		roam_info->chan_info.sec_ch_offset;
+	chan_change.chan_params.center_freq_seg0 =
+		roam_info->chan_info.band_center_freq1;
+	chan_change.chan_params.center_freq_seg1 =
+		roam_info->chan_info.band_center_freq2;
+
+	bss = wlan_hdd_cfg80211_update_bss_db(adapter, roam_info);
+	if (NULL == bss)
+		hdd_err("%s: unable to create BSS entry", adapter->dev->name);
+	else
+		cfg80211_put_bss(wiphy, bss);
+
+	status = hdd_chan_change_notify(adapter, adapter->dev, chan_change,
+				roam_info->mode == SIR_SME_PHY_MODE_LEGACY);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("channel change notification failed");
+
+	hdd_debug("check for SAP restart");
+	policy_mgr_check_concurrent_intf_and_restart_sap(hdd_ctx->psoc);
+
+	status = policy_mgr_set_hw_mode_on_channel_switch(hdd_ctx->psoc,
+		adapter->session_id);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_debug("set hw mode change not done");
+}
+
+/**
+ * hdd_sme_roam_callback() - hdd sme roam callback
+ * @pContext: pointer to adapter context
+ * @roam_info: pointer to roam info
+ * @roamId: roam id
+ * @roamStatus: roam status
+ * @roamResult: roam result
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS
+hdd_sme_roam_callback(void *pContext, struct csr_roam_info *roam_info,
+		      uint32_t roamId,
+		      eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
+{
+	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
+	struct hdd_adapter *adapter = (struct hdd_adapter *) pContext;
+	struct hdd_station_ctx *sta_ctx = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct cfg80211_bss *bss_status;
+	struct hdd_context *hdd_ctx;
+
+	hdd_debug("CSR Callback: status= %d result= %d roamID=%d",
+			  roamStatus, roamResult, roamId);
+
+	/* Sanity check */
+	if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		hdd_err("Invalid adapter or adapter has invalid magic");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
+				 adapter->session_id, roamStatus));
+
+	switch (roamStatus) {
+	/*
+	 * We did pre-auth,then we attempted a 11r or ese reassoc.
+	 * reassoc failed due to failure, timeout, reject from ap
+	 * in any case tell the OS, our carrier is off and mark
+	 * interface down.
+	 */
+	case eCSR_ROAM_FT_REASSOC_FAILED:
+		hdd_err("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d",
+			 roamStatus, roamResult, adapter->session_id);
+		qdf_ret_status =
+			hdd_dis_connect_handler(adapter, roam_info, roamId,
+						roamStatus, roamResult);
+		sta_ctx->ft_carrier_on = false;
+		sta_ctx->hdd_reassoc_scenario = false;
+		hdd_debug("hdd_reassoc_scenario set to: %d, ReAssoc Failed, session: %d",
+			  sta_ctx->hdd_reassoc_scenario, adapter->session_id);
+		break;
+
+	case eCSR_ROAM_FT_START:
+		/*
+		 * When we roam for ESE and 11r, we dont want the OS to be
+		 * informed that the link is down. So mark the link ready for
+		 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
+		 * be received. Where in we will not mark the link down
+		 * Also we want to stop tx at this point when we will be
+		 * doing disassoc at this time. This saves 30-60 msec
+		 * after reassoc.
+		 */
+		hdd_debug("Disabling queues");
+		hdd_debug("Roam Synch Ind: NAPI Serialize ON");
+		hdd_napi_serialize(1);
+		wlan_hdd_netif_queue_control(adapter,
+				WLAN_STOP_ALL_NETIF_QUEUE,
+				WLAN_CONTROL_PATH);
+		status = hdd_roam_deregister_sta(adapter,
+					sta_ctx->conn_info.staId[0]);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		sta_ctx->ft_carrier_on = true;
+		sta_ctx->hdd_reassoc_scenario = true;
+		hdd_debug("hdd_reassoc_scenario set to: %d, due to eCSR_ROAM_FT_START, session: %d",
+			  sta_ctx->hdd_reassoc_scenario, adapter->session_id);
+		break;
+	case eCSR_ROAM_NAPI_OFF:
+		hdd_debug("After Roam Synch Comp: NAPI Serialize OFF");
+		hdd_napi_serialize(0);
+		hdd_set_roaming_in_progress(false);
+		if (roamResult == eCSR_ROAM_RESULT_FAILURE)
+			adapter->roam_ho_fail = true;
+		else
+			adapter->roam_ho_fail = false;
+		complete(&adapter->roaming_comp_var);
+		break;
+	case eCSR_ROAM_SHOULD_ROAM:
+		/* notify apps that we can't pass traffic anymore */
+		hdd_debug("Disabling queues");
+		wlan_hdd_netif_queue_control(adapter,
+					   WLAN_STOP_ALL_NETIF_QUEUE,
+					   WLAN_CONTROL_PATH);
+		if (sta_ctx->ft_carrier_on == false) {
+			wlan_hdd_netif_queue_control(adapter,
+					   WLAN_NETIF_CARRIER_OFF,
+					   WLAN_CONTROL_PATH);
+		}
+		break;
+	case eCSR_ROAM_LOSTLINK:
+		if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
+			hdd_debug("Roaming started due to connection lost");
+			hdd_debug("Disabling queues");
+			wlan_hdd_netif_queue_control(adapter,
+					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+					WLAN_CONTROL_PATH);
+			break;
+		}
+	case eCSR_ROAM_DISASSOCIATED:
+	{
+		hdd_debug("****eCSR_ROAM_DISASSOCIATED****");
+		hdd_napi_serialize(0);
+		hdd_set_connection_in_progress(false);
+		hdd_set_roaming_in_progress(false);
+		adapter->roam_ho_fail = false;
+		complete(&adapter->roaming_comp_var);
+
+		/* Call to clear any MC Addr List filter applied after
+		 * successful connection.
+		 */
+		hdd_disable_and_flush_mc_addr_list(adapter,
+			pmo_peer_disconnect);
+		qdf_ret_status =
+			hdd_dis_connect_handler(adapter, roam_info, roamId,
+						roamStatus, roamResult);
+	}
+	break;
+	case eCSR_ROAM_IBSS_LEAVE:
+		hdd_debug("****eCSR_ROAM_IBSS_LEAVE****");
+		qdf_ret_status =
+			hdd_dis_connect_handler(adapter, roam_info, roamId,
+						roamStatus, roamResult);
+		break;
+	case eCSR_ROAM_ASSOCIATION_COMPLETION:
+		hdd_debug("****eCSR_ROAM_ASSOCIATION_COMPLETION****");
+		/*
+		 * To Do - address probable memory leak with WEP encryption upon
+		 * successful association.
+		 */
+		if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
+			/* Clear saved connection information in HDD */
+			hdd_conn_remove_connect_info(
+				WLAN_HDD_GET_STATION_CTX_PTR(adapter));
+		}
+		qdf_ret_status =
+			hdd_association_completion_handler(adapter, roam_info,
+							   roamId, roamStatus,
+							   roamResult);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		if (roam_info)
+			roam_info->roamSynchInProgress = false;
+#endif
+		break;
+	case eCSR_ROAM_CANCELLED:
+		hdd_debug("****eCSR_ROAM_CANCELLED****");
+		/* fallthrough */
+	case eCSR_ROAM_ASSOCIATION_FAILURE:
+		qdf_ret_status = hdd_association_completion_handler(adapter,
+								    roam_info,
+								    roamId,
+								    roamStatus,
+								    roamResult);
+		break;
+	case eCSR_ROAM_IBSS_IND:
+		hdd_roam_ibss_indication_handler(adapter, roam_info, roamId,
+						 roamStatus, roamResult);
+		break;
+
+	case eCSR_ROAM_CONNECT_STATUS_UPDATE:
+		qdf_ret_status =
+			roam_roam_connect_status_update_handler(adapter,
+								roam_info,
+								roamId,
+								roamStatus,
+								roamResult);
+		break;
+
+	case eCSR_ROAM_MIC_ERROR_IND:
+		hdd_roam_mic_error_indication_handler(adapter, roam_info);
+		break;
+
+	case eCSR_ROAM_SET_KEY_COMPLETE:
+	{
+		qdf_ret_status =
+			hdd_roam_set_key_complete_handler(adapter, roam_info,
+							  roamId, roamStatus,
+							  roamResult);
+		if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
+			sta_ctx->hdd_reassoc_scenario = false;
+			hdd_debug("hdd_reassoc_scenario set to: %d, set key complete, session: %d",
+				  sta_ctx->hdd_reassoc_scenario,
+				  adapter->session_id);
+		}
+	}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		if (roam_info != NULL)
+			roam_info->roamSynchInProgress = false;
+#endif
+		break;
+
+	case eCSR_ROAM_FT_RESPONSE:
+		hdd_send_ft_event(adapter);
+		break;
+
+	case eCSR_ROAM_PMK_NOTIFY:
+		if (eCSR_AUTH_TYPE_RSN == sta_ctx->conn_info.authType
+				|| hdd_is_8021x_sha256_auth_type(sta_ctx)) {
+			/* notify the supplicant of a new candidate */
+			qdf_ret_status =
+				wlan_hdd_cfg80211_pmksa_candidate_notify(
+						adapter, roam_info, 1, false);
+		}
+		break;
+
+#ifdef FEATURE_WLAN_LFR_METRICS
+	case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
+		/* This event is to notify pre-auth initiation */
+		if (QDF_STATUS_SUCCESS !=
+		    wlan_hdd_cfg80211_roam_metrics_preauth(adapter,
+							   roam_info)) {
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		}
+		break;
+	case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
+		/*
+		 * This event will notify pre-auth completion in case of success
+		 */
+		if (QDF_STATUS_SUCCESS !=
+		    wlan_hdd_cfg80211_roam_metrics_preauth_status(adapter,
+							 roam_info, 1)) {
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		}
+		break;
+	case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
+		/*
+		 * This event will notify pre-auth completion incase of failure.
+		 */
+		if (QDF_STATUS_SUCCESS !=
+		    wlan_hdd_cfg80211_roam_metrics_preauth_status(adapter,
+								roam_info, 0)) {
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		}
+		break;
+	case eCSR_ROAM_HANDOVER_SUCCESS:
+		/* This event is to notify handover success.
+		 * It will be only invoked on success
+		 */
+		if (QDF_STATUS_SUCCESS !=
+		    wlan_hdd_cfg80211_roam_metrics_handover(adapter,
+							    roam_info)) {
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		}
+		break;
+#endif
+#ifdef WLAN_FEATURE_11W
+	case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
+		if (roam_info)
+			hdd_indicate_unprot_mgmt_frame(adapter,
+					       roam_info->nFrameLength,
+					       roam_info->pbFrames,
+					       roam_info->frameType);
+		break;
+#endif
+#ifdef FEATURE_WLAN_ESE
+	case eCSR_ROAM_TSM_IE_IND:
+		if (roam_info)
+			hdd_indicate_tsm_ie(adapter, roam_info->tsmIe.tsid,
+				    roam_info->tsmIe.state,
+				    roam_info->tsmIe.msmt_interval);
+		break;
+
+	case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
+	{
+		if (eCSR_AUTH_TYPE_CCKM_WPA ==
+		    sta_ctx->conn_info.authType
+		    || eCSR_AUTH_TYPE_CCKM_RSN ==
+		    sta_ctx->conn_info.authType) {
+			hdd_indicate_cckm_pre_auth(adapter, roam_info);
+		}
+		break;
+	}
+
+	case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
+	{
+		hdd_indicate_ese_adj_ap_rep_ind(adapter, roam_info);
+		break;
+	}
+
+	case eCSR_ROAM_ESE_BCN_REPORT_IND:
+	{
+		hdd_indicate_ese_bcn_report_ind(adapter, roam_info);
+		break;
+	}
+#endif /* FEATURE_WLAN_ESE */
+	case eCSR_ROAM_STA_CHANNEL_SWITCH:
+		hdd_roam_channel_switch_handler(adapter, roam_info);
+		break;
+
+	case eCSR_ROAM_UPDATE_SCAN_RESULT:
+		if ((NULL != roam_info) && (NULL != roam_info->pBssDesc)) {
+			bss_status = wlan_hdd_inform_bss_frame(adapter,
+							roam_info->pBssDesc);
+			if (NULL == bss_status)
+				hdd_debug("UPDATE_SCAN_RESULT returned NULL");
+			else
+				cfg80211_put_bss(
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) || defined(WITH_BACKPORTS)
+					(WLAN_HDD_GET_CTX(adapter))->wiphy,
+#endif
+					bss_status);
+		}
+		break;
+	case eCSR_ROAM_NDP_STATUS_UPDATE:
+		hdd_ndp_event_handler(adapter, roam_info, roamId, roamStatus,
+			roamResult);
+		break;
+	case eCSR_ROAM_START:
+		hdd_debug("Process ROAM_START from firmware");
+		wlan_hdd_netif_queue_control(adapter,
+				WLAN_STOP_ALL_NETIF_QUEUE,
+				WLAN_CONTROL_PATH);
+		hdd_napi_serialize(1);
+		hdd_set_connection_in_progress(true);
+		hdd_set_roaming_in_progress(true);
+		policy_mgr_restart_opportunistic_timer(hdd_ctx->psoc, true);
+		break;
+	case eCSR_ROAM_ABORT:
+		hdd_debug("Firmware aborted roaming operation, previous connection is still valid");
+		hdd_napi_serialize(0);
+		wlan_hdd_netif_queue_control(adapter,
+				WLAN_WAKE_ALL_NETIF_QUEUE,
+				WLAN_CONTROL_PATH);
+		hdd_set_connection_in_progress(false);
+		hdd_set_roaming_in_progress(false);
+		adapter->roam_ho_fail = false;
+		sta_ctx->ft_carrier_on = false;
+		complete(&adapter->roaming_comp_var);
+		break;
+
+	case eCSR_ROAM_SAE_COMPUTE:
+		if (roam_info)
+			wlan_hdd_sae_callback(adapter, roam_info);
+		break;
+
+	case eCSR_ROAM_ROAMING_START:
+		/*
+		 * For LFR2, Handle roaming start to remove disassociated
+		 * session
+		 */
+		if (roaming_offload_enabled(hdd_ctx))
+			break;
+		if (roamResult == eCSR_ROAM_RESULT_NOT_ASSOCIATED) {
+			hdd_debug("Decrement session of disassociated AP device_mode %d sessionId %d",
+				  adapter->device_mode,
+				  adapter->session_id);
+			policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
+							adapter->device_mode,
+							adapter->session_id);
+		}
+		break;
+
+	default:
+		break;
+	}
+	return qdf_ret_status;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * hdd_translate_fils_rsn_to_csr_auth() - Translate FILS RSN to CSR auth type
+ * @auth_suite: auth suite
+ * @auth_type: pointer to eCsrAuthType
+ *
+ * Return: None
+ */
+static void hdd_translate_fils_rsn_to_csr_auth(int8_t auth_suite[4],
+					eCsrAuthType *auth_type)
+{
+	if (!memcmp(auth_suite, ccp_rsn_oui_0e, 4))
+		*auth_type = eCSR_AUTH_TYPE_FILS_SHA256;
+	else if (!memcmp(auth_suite, ccp_rsn_oui_0f, 4))
+		*auth_type = eCSR_AUTH_TYPE_FILS_SHA384;
+	else if (!memcmp(auth_suite, ccp_rsn_oui_10, 4))
+		*auth_type = eCSR_AUTH_TYPE_FT_FILS_SHA256;
+	else if (!memcmp(auth_suite, ccp_rsn_oui_11, 4))
+		*auth_type = eCSR_AUTH_TYPE_FT_FILS_SHA384;
+}
+#else
+static inline void hdd_translate_fils_rsn_to_csr_auth(int8_t auth_suite[4],
+					eCsrAuthType *auth_type)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * hdd_translate_sae_rsn_to_csr_auth() - Translate SAE RSN to CSR auth type
+ * @auth_suite: auth suite
+ * @auth_type: pointer to eCsrAuthType
+ *
+ * Return: None
+ */
+static void hdd_translate_sae_rsn_to_csr_auth(int8_t auth_suite[4],
+					eCsrAuthType *auth_type)
+{
+	if (qdf_mem_cmp(auth_suite, ccp_rsn_oui_80, 4) == 0)
+		*auth_type = eCSR_AUTH_TYPE_SAE;
+}
+#else
+static inline void hdd_translate_sae_rsn_to_csr_auth(int8_t auth_suite[4],
+					eCsrAuthType *auth_type)
+{
+}
+#endif
+
+/**
+ * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
+ * @auth_suite: auth suite
+ *
+ * Return: eCsrAuthType enumeration
+ */
+eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
+{
+	eCsrAuthType auth_type = eCSR_AUTH_TYPE_UNKNOWN;
+	/* is the auth type supported? */
+	if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
+		auth_type = eCSR_AUTH_TYPE_RSN;
+	} else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
+		auth_type = eCSR_AUTH_TYPE_RSN_PSK;
+	} else if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
+		/* Check for 11r FT Authentication with PSK */
+		auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
+	} else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
+		/* Check for 11R FT Authentication with 802.1X */
+		auth_type = eCSR_AUTH_TYPE_FT_RSN;
+	} else
+#ifdef FEATURE_WLAN_ESE
+	if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
+		auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
+	} else
+#endif /* FEATURE_WLAN_ESE */
+#ifdef WLAN_FEATURE_11W
+	if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
+		auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
+	} else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
+		auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
+	} else if (memcmp(auth_suite, ccp_rsn_oui_18, 4) == 0) {
+		auth_type = eCSR_AUTH_TYPE_OWE;
+	} else
+#endif
+	if (memcmp(auth_suite, ccp_rsn_oui_12, 4) == 0) {
+		auth_type = eCSR_AUTH_TYPE_DPP_RSN;
+	} else if (memcmp(auth_suite, ccp_rsn_oui_0b, 4) == 0) {
+		/* Check for Suite B EAP 256 */
+		auth_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256;
+	} else if (memcmp(auth_suite, ccp_rsn_oui_0c, 4) == 0) {
+		/* Check for Suite B EAP 384 */
+		auth_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384;
+	} else {
+		hdd_translate_fils_rsn_to_csr_auth(auth_suite, &auth_type);
+		hdd_translate_sae_rsn_to_csr_auth(auth_suite, &auth_type);
+	}
+	hdd_debug("auth_type: %d", auth_type);
+	return auth_type;
+}
+
+/**
+ * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
+ * @auth_suite: auth suite
+ *
+ * Return: eCsrAuthType enumeration
+ */
+eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
+{
+	eCsrAuthType auth_type = eCSR_AUTH_TYPE_UNKNOWN;
+	/* is the auth type supported? */
+	if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
+		auth_type = eCSR_AUTH_TYPE_WPA;
+	} else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
+		auth_type = eCSR_AUTH_TYPE_WPA_PSK;
+	} else
+#ifdef FEATURE_WLAN_ESE
+	if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
+		auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
+	} else
+#endif /* FEATURE_WLAN_ESE */
+	{
+		hdd_translate_fils_rsn_to_csr_auth(auth_suite, &auth_type);
+	}
+	hdd_debug("auth_type: %d", auth_type);
+	return auth_type;
+}
+
+/**
+ * hdd_translate_rsn_to_csr_encryption_type() -
+ *	Translate RSN to CSR encryption type
+ * @cipher_suite: cipher suite
+ *
+ * Return: eCsrEncryptionType enumeration
+ */
+eCsrEncryptionType
+hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
+{
+	eCsrEncryptionType cipher_type;
+
+	if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_AES;
+	else if (memcmp(cipher_suite, ccp_rsn_oui09, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_AES_GCMP;
+	else if (memcmp(cipher_suite, ccp_rsn_oui0a, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_AES_GCMP_256;
+	else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
+	else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_NONE;
+	else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
+	else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
+	else
+		cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
+
+	hdd_debug("cipher_type: %d", cipher_type);
+	return cipher_type;
+}
+
+/**
+ * hdd_translate_wpa_to_csr_encryption_type() -
+ *	Translate WPA to CSR encryption type
+ * @cipher_suite: cipher suite
+ *
+ * Return: eCsrEncryptionType enumeration
+ */
+eCsrEncryptionType
+hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
+{
+	eCsrEncryptionType cipher_type;
+
+	if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_AES;
+	else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
+	else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_NONE;
+	else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
+	else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
+	else
+		cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
+
+	hdd_debug("cipher_type: %d", cipher_type);
+	return cipher_type;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+bool hdd_is_fils_connection(struct hdd_adapter *adapter)
+{
+	struct csr_roam_profile *roam_profile;
+
+	roam_profile = hdd_roam_profile(adapter);
+	if (roam_profile->fils_con_info)
+		return roam_profile->fils_con_info->is_fils_connection;
+
+	return false;
+}
+#else
+bool hdd_is_fils_connection(struct hdd_adapter *adapter)
+{
+	return false;
+}
+#endif
+
+/**
+ * hdd_process_genie() - process gen ie
+ * @adapter: pointer to adapter
+ * @bssid: pointer to mac address
+ * @pEncryptType: pointer to encryption type
+ * @mcEncryptType: pointer to multicast encryption type
+ * @pAuthType: pointer to auth type
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int32_t hdd_process_genie(struct hdd_adapter *adapter,
+				 u8 *bssid,
+				 eCsrEncryptionType *pEncryptType,
+				 eCsrEncryptionType *mcEncryptType,
+				 eCsrAuthType *pAuthType,
+#ifdef WLAN_FEATURE_11W
+				 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
+#endif
+				 uint16_t gen_ie_len, uint8_t *gen_ie)
+{
+	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
+	tDot11fIERSN dot11RSNIE = {0};
+	tDot11fIEWPA dot11WPAIE = {0};
+	uint8_t *pRsnIe;
+	uint16_t RSNIeLen;
+	uint32_t parse_status;
+
+	/*
+	 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
+	 * setting present flag to 0.
+	 */
+	memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
+	memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
+
+	/* Type check */
+	if (gen_ie[0] == DOT11F_EID_RSN) {
+		/* Validity checks */
+		if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
+		    (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
+			hdd_err("Invalid DOT11F RSN IE length: %d",
+				gen_ie_len);
+			return -EINVAL;
+		}
+		/* Skip past the EID byte and length byte */
+		pRsnIe = gen_ie + 2;
+		RSNIeLen = gen_ie_len - 2;
+		/* Unpack the RSN IE */
+		parse_status = sme_unpack_rsn_ie(mac_handle, pRsnIe, RSNIeLen,
+						 &dot11RSNIE, false);
+		if (!DOT11F_SUCCEEDED(parse_status)) {
+			hdd_err("Invalid RSN IE: parse status %d",
+				parse_status);
+			return -EINVAL;
+		}
+		hdd_debug("gp_cipher_suite_present: %d",
+			 dot11RSNIE.gp_cipher_suite_present);
+		/* Copy out the encryption and authentication types */
+		hdd_debug("pairwise cipher suite count: %d",
+			 dot11RSNIE.pwise_cipher_suite_count);
+		hdd_debug("authentication suite count: %d",
+			 dot11RSNIE.akm_suite_cnt);
+		/* dot11RSNIE.akm_suite_cnt */
+		/* Just translate the FIRST one */
+		*pAuthType =
+			hdd_translate_rsn_to_csr_auth_type(
+					dot11RSNIE.akm_suite[0]);
+		/* dot11RSNIE.pwise_cipher_suite_count */
+		*pEncryptType =
+			hdd_translate_rsn_to_csr_encryption_type(
+					dot11RSNIE.pwise_cipher_suites[0]);
+		/* dot11RSNIE.gp_cipher_suite_count */
+		*mcEncryptType =
+			hdd_translate_rsn_to_csr_encryption_type(
+					dot11RSNIE.gp_cipher_suite);
+#ifdef WLAN_FEATURE_11W
+		*pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
+		*pMfpCapable = csr_is_mfpc_capable(&dot11RSNIE);
+#endif
+	} else if (gen_ie[0] == DOT11F_EID_WPA) {
+		/* Validity checks */
+		if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
+		    (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
+			hdd_err("Invalid DOT11F WPA IE length: %d",
+				gen_ie_len);
+			return -EINVAL;
+		}
+		/* Skip past the EID and length byte - and four byte WiFi OUI */
+		pRsnIe = gen_ie + 2 + 4;
+		RSNIeLen = gen_ie_len - (2 + 4);
+		/* Unpack the WPA IE */
+		parse_status = dot11f_unpack_ie_wpa((tpAniSirGlobal)mac_handle,
+				     pRsnIe, RSNIeLen, &dot11WPAIE, false);
+		if (!DOT11F_SUCCEEDED(parse_status)) {
+			hdd_err("Invalid WPA IE: parse status %d",
+				parse_status);
+			return -EINVAL;
+		}
+		/* Copy out the encryption and authentication types */
+		hdd_debug("WPA unicast cipher suite count: %d",
+			 dot11WPAIE.unicast_cipher_count);
+		hdd_debug("WPA authentication suite count: %d",
+			 dot11WPAIE.auth_suite_count);
+		/* dot11WPAIE.auth_suite_count */
+		/* Just translate the FIRST one */
+		*pAuthType =
+			hdd_translate_wpa_to_csr_auth_type(
+					dot11WPAIE.auth_suites[0]);
+		/* dot11WPAIE.unicast_cipher_count */
+		*pEncryptType =
+			hdd_translate_wpa_to_csr_encryption_type(
+					dot11WPAIE.unicast_ciphers[0]);
+		/* dot11WPAIE.unicast_cipher_count */
+		*mcEncryptType =
+			hdd_translate_wpa_to_csr_encryption_type(
+					dot11WPAIE.multicast_cipher);
+	} else {
+		hdd_warn("gen_ie[0]: %d", gen_ie[0]);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * hdd_set_def_rsne_override() - set default encryption type and auth type
+ * in profile.
+ * @roam_profile: pointer to adapter
+ * @auth_type: pointer to auth type
+ *
+ * Set default value of encryption type and auth type in profile to
+ * search the AP using filter, as in force_rsne_override the RSNIE can be
+ * currupt and we might not get the proper encryption type and auth type
+ * while parsing the RSNIE.
+ *
+ * Return: void
+ */
+static void hdd_set_def_rsne_override(
+	struct csr_roam_profile *roam_profile, eCsrAuthType *auth_type)
+{
+
+	hdd_debug("Set def values in roam profile");
+	roam_profile->MFPCapable = roam_profile->MFPEnabled;
+	roam_profile->EncryptionType.numEntries = 2;
+	roam_profile->mcEncryptionType.numEntries = 2;
+		/* Use the cipher type in the RSN IE */
+	roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_AES;
+	roam_profile->EncryptionType.encryptionType[1] = eCSR_ENCRYPT_TYPE_TKIP;
+	roam_profile->mcEncryptionType.encryptionType[0] =
+		eCSR_ENCRYPT_TYPE_AES;
+	roam_profile->mcEncryptionType.encryptionType[1] =
+		eCSR_ENCRYPT_TYPE_TKIP;
+	*auth_type = eCSR_AUTH_TYPE_RSN_PSK;
+}
+
+/**
+ * hdd_set_genie_to_csr() - set genie to csr
+ * @adapter: pointer to adapter
+ * @RSNAuthType: pointer to auth type
+ *
+ * Return: 0 on success, error number otherwise
+ */
+int hdd_set_genie_to_csr(struct hdd_adapter *adapter,
+			 eCsrAuthType *RSNAuthType)
+{
+	struct csr_roam_profile *roam_profile;
+	uint8_t *security_ie;
+	uint32_t status = 0;
+	eCsrEncryptionType RSNEncryptType;
+	eCsrEncryptionType mcRSNEncryptType;
+	struct hdd_context *hdd_ctx;
+#ifdef WLAN_FEATURE_11W
+	uint8_t RSNMfpRequired = 0;
+	uint8_t RSNMfpCapable = 0;
+#endif
+	u8 bssid[ETH_ALEN];        /* MAC address of assoc peer */
+
+	roam_profile = hdd_roam_profile(adapter);
+	security_ie = hdd_security_ie(adapter);
+
+	/* MAC address of assoc peer */
+	/* But, this routine is only called when we are NOT associated. */
+	qdf_mem_copy(bssid, roam_profile->BSSIDs.bssid, sizeof(bssid));
+	if (security_ie[0] == DOT11F_EID_RSN ||
+	    security_ie[0] == DOT11F_EID_WPA) {
+		/* continue */
+	} else {
+		return 0;
+	}
+
+	/* The actual processing may eventually be more extensive than this. */
+	/* Right now, just consume any PMKIDs that are  sent in by the app. */
+	status = hdd_process_genie(adapter, bssid,
+				   &RSNEncryptType,
+				   &mcRSNEncryptType, RSNAuthType,
+#ifdef WLAN_FEATURE_11W
+				   &RSNMfpRequired, &RSNMfpCapable,
+#endif
+				   security_ie[1] + 2,
+				   security_ie);
+
+	if (status == 0) {
+		/*
+		 * Now copy over all the security attributes
+		 * you have parsed out.
+		 */
+		roam_profile->EncryptionType.numEntries = 1;
+		roam_profile->mcEncryptionType.numEntries = 1;
+
+		/* Use the cipher type in the RSN IE */
+		roam_profile->EncryptionType.encryptionType[0] =
+			RSNEncryptType;
+		roam_profile->mcEncryptionType.encryptionType[0] =
+			mcRSNEncryptType;
+
+		if ((QDF_IBSS_MODE == adapter->device_mode) &&
+		    ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
+		     (eCSR_ENCRYPT_TYPE_AES_GCMP == mcRSNEncryptType) ||
+		     (eCSR_ENCRYPT_TYPE_AES_GCMP_256 == mcRSNEncryptType) ||
+		     (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
+			/*
+			 * For wpa none supplicant sends the WPA IE with unicast
+			 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
+			 * multicast cipher as either AES/TKIP based on group
+			 * cipher configuration mentioned in the
+			 * wpa_supplicant.conf.
+			 */
+
+			/* Set the unicast cipher same as multicast cipher */
+			roam_profile->EncryptionType.encryptionType[0]
+				= mcRSNEncryptType;
+		}
+#ifdef WLAN_FEATURE_11W
+		hdd_debug("RSNMfpRequired = %d, RSNMfpCapable = %d",
+			 RSNMfpRequired, RSNMfpCapable);
+		roam_profile->MFPRequired = RSNMfpRequired;
+		roam_profile->MFPCapable = RSNMfpCapable;
+#endif
+		hdd_debug("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d",
+			 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (hdd_ctx->force_rsne_override &&
+	    (security_ie[0] == DOT11F_EID_RSN)) {
+		hdd_warn("Test mode enabled set def Auth and enc type. RSN IE passed in connect req: ");
+		qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN,
+				   roam_profile->pRSNReqIE,
+				   roam_profile->nRSNReqIELength);
+
+		roam_profile->force_rsne_override = true;
+
+		hdd_debug("MFPEnabled %d", roam_profile->MFPEnabled);
+		/*
+		 * Reset MFPEnabled if testmode RSNE passed doesn't have MFPR
+		 * or MFPC bit set
+		 */
+		if (roam_profile->MFPEnabled &&
+		    !(roam_profile->MFPRequired ||
+		      roam_profile->MFPCapable)) {
+			hdd_debug("Reset MFPEnabled");
+			roam_profile->MFPEnabled = 0;
+		}
+		/* If parsing failed set the def value for the roam profile */
+		if (status)
+			hdd_set_def_rsne_override(roam_profile, RSNAuthType);
+		return 0;
+	}
+	return status;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * hdd_check_fils_rsn_n_set_auth_type() - This API checks whether a give
+ * auth type is fils if yes, sets it in profile.
+ * @rsn_auth_type: auth type
+ *
+ * Return: true if FILS auth else false
+ */
+static
+bool hdd_check_fils_rsn_n_set_auth_type(struct csr_roam_profile *roam_profile,
+					eCsrAuthType rsn_auth_type)
+{
+	bool is_fils_rsn = false;
+
+	if (!roam_profile->fils_con_info)
+		return false;
+
+	if ((rsn_auth_type == eCSR_AUTH_TYPE_FILS_SHA256) ||
+	   (rsn_auth_type == eCSR_AUTH_TYPE_FILS_SHA384) ||
+	   (rsn_auth_type == eCSR_AUTH_TYPE_FT_FILS_SHA256) ||
+	   (rsn_auth_type == eCSR_AUTH_TYPE_FT_FILS_SHA384))
+		is_fils_rsn = true;
+	if (is_fils_rsn)
+		roam_profile->fils_con_info->akm_type = rsn_auth_type;
+
+	return is_fils_rsn;
+}
+#else
+static
+bool hdd_check_fils_rsn_n_set_auth_type(struct csr_roam_profile *roam_profile,
+					eCsrAuthType rsn_auth_type)
+{
+	return false;
+}
+#endif
+
+/**
+ * hdd_set_csr_auth_type() - set csr auth type
+ * @adapter: pointer to adapter
+ * @RSNAuthType: auth type
+ *
+ * Return: 0 on success, error number otherwise
+ */
+int hdd_set_csr_auth_type(struct hdd_adapter *adapter,
+			  eCsrAuthType RSNAuthType)
+{
+	struct csr_roam_profile *roam_profile;
+	struct hdd_station_ctx *sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	enum hdd_auth_key_mgmt key_mgmt = sta_ctx->auth_key_mgmt;
+
+	roam_profile = hdd_roam_profile(adapter);
+	roam_profile->AuthType.numEntries = 1;
+	hdd_debug("authType = %d RSNAuthType %d wpa_versions %d",
+		  sta_ctx->conn_info.authType, RSNAuthType,
+		  sta_ctx->wpa_versions);
+
+	switch (sta_ctx->conn_info.authType) {
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+#ifdef FEATURE_WLAN_ESE
+	case eCSR_AUTH_TYPE_CCKM_WPA:
+	case eCSR_AUTH_TYPE_CCKM_RSN:
+#endif
+		if (!sta_ctx->wpa_versions) {
+
+			roam_profile->AuthType.authType[0] =
+				eCSR_AUTH_TYPE_OPEN_SYSTEM;
+		} else if (sta_ctx->wpa_versions & NL80211_WPA_VERSION_1) {
+
+#ifdef FEATURE_WLAN_ESE
+			if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
+			    ((key_mgmt & HDD_AUTH_KEY_MGMT_802_1X)
+			     == HDD_AUTH_KEY_MGMT_802_1X)) {
+				hdd_debug("set authType to CCKM WPA. AKM also 802.1X.");
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_CCKM_WPA;
+			} else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
+				hdd_debug("Last chance to set authType to CCKM WPA.");
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_CCKM_WPA;
+			} else
+#endif
+			if ((key_mgmt & HDD_AUTH_KEY_MGMT_802_1X)
+			    == HDD_AUTH_KEY_MGMT_802_1X) {
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_WPA;
+			} else
+			if ((key_mgmt & HDD_AUTH_KEY_MGMT_PSK)
+			    == HDD_AUTH_KEY_MGMT_PSK) {
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_WPA_PSK;
+			} else {
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_WPA_NONE;
+			}
+		}
+		if (sta_ctx->wpa_versions & NL80211_WPA_VERSION_2) {
+#ifdef FEATURE_WLAN_ESE
+			if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
+			    ((key_mgmt & HDD_AUTH_KEY_MGMT_802_1X)
+			     == HDD_AUTH_KEY_MGMT_802_1X)) {
+				hdd_debug("set authType to CCKM RSN. AKM also 802.1X.");
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_CCKM_RSN;
+			} else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
+				hdd_debug("Last chance to set authType to CCKM RSN.");
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_CCKM_RSN;
+			} else
+#endif
+			if (RSNAuthType == eCSR_AUTH_TYPE_DPP_RSN) {
+				roam_profile->AuthType.authType[0] =
+							eCSR_AUTH_TYPE_DPP_RSN;
+			} else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
+			    ((key_mgmt & HDD_AUTH_KEY_MGMT_802_1X)
+			     == HDD_AUTH_KEY_MGMT_802_1X)) {
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_FT_RSN;
+			} else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
+				   &&
+				   ((key_mgmt & HDD_AUTH_KEY_MGMT_PSK)
+				    == HDD_AUTH_KEY_MGMT_PSK)) {
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_FT_RSN_PSK;
+			} else
+
+#ifdef WLAN_FEATURE_11W
+			if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_RSN_PSK_SHA256;
+			} else if (RSNAuthType ==
+				   eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_RSN_8021X_SHA256;
+			} else
+#endif
+			if (hdd_check_fils_rsn_n_set_auth_type(roam_profile,
+				RSNAuthType)) {
+				roam_profile->AuthType.authType[0] =
+					RSNAuthType;
+				hdd_debug("updated profile authtype as %d",
+					RSNAuthType);
+
+			} else if ((RSNAuthType == eCSR_AUTH_TYPE_OWE) &&
+				  ((key_mgmt & HDD_AUTH_KEY_MGMT_802_1X)
+				  == HDD_AUTH_KEY_MGMT_802_1X)) {
+				/* OWE case */
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_OWE;
+			} else if ((RSNAuthType ==
+				  eCSR_AUTH_TYPE_SUITEB_EAP_SHA256) &&
+				  ((key_mgmt & HDD_AUTH_KEY_MGMT_802_1X)
+				  == HDD_AUTH_KEY_MGMT_802_1X)) {
+				/* Suite B EAP SHA 256 */
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_SUITEB_EAP_SHA256;
+			} else if ((RSNAuthType ==
+				  eCSR_AUTH_TYPE_SUITEB_EAP_SHA384) &&
+				  ((key_mgmt & HDD_AUTH_KEY_MGMT_802_1X)
+				  == HDD_AUTH_KEY_MGMT_802_1X)) {
+				/* Suite B EAP SHA 384 */
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_SUITEB_EAP_SHA384;
+			} else if ((key_mgmt & HDD_AUTH_KEY_MGMT_802_1X)
+			    == HDD_AUTH_KEY_MGMT_802_1X) {
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_RSN;
+			} else
+			if ((key_mgmt & HDD_AUTH_KEY_MGMT_PSK)
+			    == HDD_AUTH_KEY_MGMT_PSK) {
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_RSN_PSK;
+			} else {
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_UNKNOWN;
+			}
+		}
+		break;
+
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+
+		roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
+		break;
+
+	case eCSR_AUTH_TYPE_SAE:
+		roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SAE;
+		break;
+
+	default:
+
+#ifdef FEATURE_WLAN_ESE
+		hdd_debug("In default, unknown auth type.");
+#endif /* FEATURE_WLAN_ESE */
+		roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
+		break;
+	}
+
+	hdd_debug("Set roam Authtype to %d",
+		 roam_profile->AuthType.authType[0]);
+
+	return 0;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+static void hdd_initialize_fils_info(struct hdd_adapter *adapter)
+{
+	struct csr_roam_profile *roam_profile;
+
+	roam_profile = hdd_roam_profile(adapter);
+	roam_profile->fils_con_info = NULL;
+	roam_profile->hlp_ie = NULL;
+	roam_profile->hlp_ie_len = 0;
+}
+#else
+static void hdd_initialize_fils_info(struct hdd_adapter *adapter)
+{ }
+#endif
+
+void hdd_roam_profile_init(struct hdd_adapter *adapter)
+{
+	struct csr_roam_profile *roam_profile;
+	uint8_t *security_ie;
+	tSirAddie *assoc_additional_ie;
+	struct hdd_station_ctx *sta_ctx;
+
+	hdd_enter();
+
+	roam_profile = hdd_roam_profile(adapter);
+	qdf_mem_zero(roam_profile, sizeof(*roam_profile));
+
+	security_ie = hdd_security_ie(adapter);
+	qdf_mem_zero(security_ie, MAX_WPA_RSN_IE_LEN);
+
+	assoc_additional_ie = hdd_assoc_additional_ie(adapter);
+	qdf_mem_zero(assoc_additional_ie, sizeof(*assoc_additional_ie));
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	/* Configure the roaming profile links to SSID and bssid. */
+	roam_profile->SSIDs.numOfSSIDs = 0;
+	roam_profile->SSIDs.SSIDList = &sta_ctx->conn_info.SSID;
+
+	roam_profile->BSSIDs.numOfBSSIDs = 0;
+	roam_profile->BSSIDs.bssid = &sta_ctx->conn_info.bssId;
+
+	/* Set the numOfChannels to zero to scan all the channels */
+	roam_profile->ChannelInfo.numOfChannels = 0;
+	roam_profile->ChannelInfo.ChannelList = NULL;
+
+	roam_profile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
+
+	roam_profile->phyMode = eCSR_DOT11_MODE_AUTO;
+	sta_ctx->wpa_versions = 0;
+
+	/* Set the default scan mode */
+	adapter->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
+
+	hdd_clear_roam_profile_ie(adapter);
+
+	hdd_initialize_fils_info(adapter);
+
+	hdd_exit();
+}
diff --git a/core/hdd/src/wlan_hdd_bss_transition.c b/core/hdd/src/wlan_hdd_bss_transition.c
new file mode 100644
index 0000000..fd4b012
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_bss_transition.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_bss_transition.c
+ *
+ * WLAN bss transition functions
+ *
+ */
+
+#include <wlan_hdd_includes.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <wlan_hdd_bss_transition.h>
+
+/**
+ * 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 bool wlan_hdd_is_bt_in_progress(struct hdd_context *hdd_ctx)
+{
+	if (hdd_ctx->bt_a2dp_active || hdd_ctx->bt_vo_active)
+		return true;
+
+	return false;
+}
+
+/**
+ * wlan_hdd_fill_btm_resp() - Fill bss candidate response buffer
+ * @reply_skb : pointer to reply_skb
+ * @info : bss candidate information
+ * @index : attribute type index for nla_next_start()
+ *
+ * Return : 0 on success and errno on failure
+ */
+static int wlan_hdd_fill_btm_resp(struct sk_buff *reply_skb,
+				  struct bss_candidate_info *info,
+				  int index)
+{
+	struct nlattr *attr;
+
+	attr = nla_nest_start(reply_skb, index);
+	if (!attr) {
+		hdd_err("nla_nest_start failed");
+		kfree_skb(reply_skb);
+		return -EINVAL;
+	}
+
+	if (nla_put(reply_skb,
+		  QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID,
+		  ETH_ALEN, info->bssid.bytes) ||
+	    nla_put_u32(reply_skb,
+		 QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_STATUS,
+		 info->status)) {
+		hdd_err("nla_put failed");
+		kfree_skb(reply_skb);
+		return -EINVAL;
+	}
+
+	nla_nest_end(reply_skb, attr);
+
+	return 0;
+}
+
+/**
+ * __wlan_hdd_cfg80211_fetch_bss_transition_status() - fetch bss transition
+ * status
+ * @wiphy : WIPHY structure pointer
+ * @wdev : Wireless device structure pointer
+ * @data : Pointer to the data received
+ * @data_len : Length of the data received
+ *
+ * This function is used to fetch transition status for candidate bss. The
+ * transition status is either accept or reason for reject.
+ *
+ * Return : 0 on success and errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_fetch_bss_transition_status(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data, int data_len)
+{
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
+	struct nlattr *tb_msg[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_MAX + 1];
+	uint8_t transition_reason;
+	struct nlattr *attr;
+	struct sk_buff *reply_skb;
+	int rem, j;
+	int ret;
+	bool is_bt_in_progress;
+	struct bss_candidate_info candidate_info[MAX_CANDIDATE_INFO];
+	uint16_t nof_candidates, i = 0;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_station_ctx *hdd_sta_ctx =
+					WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	mac_handle_t mac_handle;
+
+	const struct nla_policy
+	btm_params_policy[QCA_WLAN_VENDOR_ATTR_MAX + 1] = {
+		[QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON] = {
+							.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO] = {
+							.type = NLA_NESTED},
+	};
+	const struct nla_policy
+	btm_cand_list_policy[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_MAX + 1]
+		= {[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID] = {
+						.len = QDF_MAC_ADDR_SIZE},
+		   [QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_STATUS] = {
+							.type = NLA_U32},
+		};
+
+	hdd_enter();
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (adapter->device_mode != QDF_STA_MODE ||
+	    hdd_sta_ctx->conn_info.connState != eConnectionState_Associated) {
+		hdd_err("Command is either not invoked for STA mode (device mode: %d) or STA is not associated (Connection state: %d)",
+			adapter->device_mode, hdd_sta_ctx->conn_info.connState);
+		return -EINVAL;
+	}
+
+	ret = wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data,
+				      data_len, btm_params_policy);
+	if (ret) {
+		hdd_err("Attribute parse failed");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON] ||
+	    !tb[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO]) {
+		hdd_err("Missing attributes");
+		return -EINVAL;
+	}
+
+	transition_reason = nla_get_u8(
+			    tb[QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON]);
+
+	nla_for_each_nested(attr,
+			    tb[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO],
+			    rem) {
+		ret = wlan_cfg80211_nla_parse_nested(tb_msg,
+				    QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_MAX,
+				    attr, btm_cand_list_policy);
+		if (ret) {
+			hdd_err("Attribute parse failed");
+			return -EINVAL;
+		}
+
+		if (!tb_msg[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID]) {
+			hdd_err("Missing BSSID attribute");
+			return -EINVAL;
+		}
+
+		qdf_mem_copy((void *)candidate_info[i].bssid.bytes,
+			     nla_data(tb_msg[
+			     QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID]),
+			     QDF_MAC_ADDR_SIZE);
+		i++;
+		if (i == MAX_CANDIDATE_INFO)
+			break;
+	}
+
+	/*
+	 * Determine status for each candidate and fill in the status field.
+	 * Also arrange the candidates in the order of preference.
+	 */
+	nof_candidates = i;
+
+	is_bt_in_progress = wlan_hdd_is_bt_in_progress(hdd_ctx);
+
+	mac_handle = hdd_ctx->mac_handle;
+	ret = sme_get_bss_transition_status(mac_handle, transition_reason,
+					    &hdd_sta_ctx->conn_info.bssId,
+					    candidate_info,
+					    nof_candidates,
+					    is_bt_in_progress);
+	if (ret)
+		return -EINVAL;
+
+	/* Prepare the reply and send it to userspace */
+	reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
+			((QDF_MAC_ADDR_SIZE + sizeof(uint32_t)) *
+			 nof_candidates) + NLMSG_HDRLEN);
+	if (!reply_skb) {
+		hdd_err("reply buffer alloc failed");
+		return -ENOMEM;
+	}
+
+	attr = nla_nest_start(reply_skb,
+			      QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO);
+	if (!attr) {
+		hdd_err("nla_nest_start failed");
+		kfree_skb(reply_skb);
+		return -EINVAL;
+	}
+
+	/*
+	 * Order candidates as - accepted candidate list followed by rejected
+	 * candidate list
+	 */
+	for (i = 0, j = 0; i < nof_candidates; i++) {
+		/* copy accepted candidate list */
+		if (candidate_info[i].status == QCA_STATUS_ACCEPT) {
+			if (wlan_hdd_fill_btm_resp(reply_skb,
+						   &candidate_info[i], j))
+				return -EINVAL;
+			j++;
+		}
+	}
+	for (i = 0; i < nof_candidates; i++) {
+		/* copy rejected candidate list */
+		if (candidate_info[i].status != QCA_STATUS_ACCEPT) {
+			if (wlan_hdd_fill_btm_resp(reply_skb,
+						   &candidate_info[i], j))
+				return -EINVAL;
+			j++;
+		}
+	}
+	nla_nest_end(reply_skb, attr);
+
+	hdd_exit();
+
+	return cfg80211_vendor_cmd_reply(reply_skb);
+}
+
+int wlan_hdd_cfg80211_fetch_bss_transition_status(struct wiphy *wiphy,
+						  struct wireless_dev *wdev,
+						  const void *data,
+						  int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_fetch_bss_transition_status(wiphy, wdev,
+							      data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
diff --git a/core/hdd/src/wlan_hdd_bss_transition.h b/core/hdd/src/wlan_hdd_bss_transition.h
new file mode 100644
index 0000000..86ba247
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_bss_transition.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __WLAN_HDD_BSS_TRANSITION_H
+#define __WLAN_HDD_BSS_TRANSITION_H
+
+/**
+ * DOC: wlan_hdd_bss_transition_h
+ *
+ * WLAN Host Device Driver BSS transition API specification
+ */
+
+#ifdef FEATURE_BSS_TRANSITION
+/**
+ * wlan_hdd_cfg80211_fetch_bss_transition_status() - fetch bss transition status
+ * @wiphy: WIPHY structure pointer
+ * @wdev: Wireless device structure pointer
+ * @data: Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function is used to fetch transition status for candidate bss. The
+ * transition status is either accept or reason for reject.
+ *
+ * Return: 0 on success and errno on failure
+ */
+int
+wlan_hdd_cfg80211_fetch_bss_transition_status(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      const void *data, int data_len);
+
+#define FEATURE_BSS_TRANSITION_VENDOR_COMMANDS				\
+{									\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,			\
+	.info.subcmd =							\
+		QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS,	\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |				\
+		 WIPHY_VENDOR_CMD_NEED_NETDEV |				\
+		 WIPHY_VENDOR_CMD_NEED_RUNNING,				\
+	.doit = wlan_hdd_cfg80211_fetch_bss_transition_status		\
+},
+#else /* FEATURE_BSS_TRANSITION */
+#define FEATURE_BSS_TRANSITION_VENDOR_COMMANDS
+#endif /* FEATURE_BSS_TRANSITION */
+
+#endif /* __WLAN_HDD_BSS_TRANSITION_H */
+
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
new file mode 100644
index 0000000..3dc4d2e
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -0,0 +1,4500 @@
+/*
+ * Copyright (c) 2012-2018 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:  wlan_hdd_cfg.c
+ *
+ * WLAN Host Device Driver configuration interface implementation
+ */
+
+/* Include Files */
+
+#include <linux/firmware.h>
+#include <linux/string.h>
+#include <wlan_hdd_includes.h>
+#include <wlan_hdd_main.h>
+#include <wlan_hdd_assoc.h>
+#include <wlan_hdd_cfg.h>
+#include <linux/string.h>
+#include <qdf_types.h>
+#include <csr_api.h>
+#include <wlan_hdd_misc.h>
+#include <wlan_hdd_napi.h>
+#include <cds_api.h>
+#include "wlan_hdd_he.h"
+#include <wlan_policy_mgr_api.h>
+#include "wifi_pos_api.h"
+#include "wlan_hdd_green_ap.h"
+#include "wlan_hdd_twt.h"
+#include "wlan_policy_mgr_ucfg.h"
+#include "wlan_mlme_ucfg_api.h"
+#include "wlan_mlme_public_struct.h"
+#include "wlan_fwol_ucfg_api.h"
+#include "cfg_ucfg_api.h"
+#include "hdd_dp_cfg.h"
+
+static void
+cb_notify_set_roam_prefer5_g_hz(struct hdd_context *hdd_ctx,
+				unsigned long notify_id)
+{
+	sme_update_roam_prefer5_g_hz(hdd_ctx->mac_handle,
+				     hdd_ctx->config->nRoamPrefer5GHz);
+}
+
+static void
+cb_notify_set_roam_rssi_diff(struct hdd_context *hdd_ctx,
+			     unsigned long notify_id)
+{
+	sme_update_roam_rssi_diff(hdd_ctx->mac_handle,
+				  0, hdd_ctx->config->RoamRssiDiff);
+}
+
+static void
+cb_notify_set_fast_transition_enabled(struct hdd_context *hdd_ctx,
+				      unsigned long notify_id)
+{
+	bool enabled = hdd_ctx->config->isFastTransitionEnabled;
+
+	sme_update_fast_transition_enabled(hdd_ctx->mac_handle, enabled);
+}
+
+static void
+cb_notify_set_roam_intra_band(struct hdd_context *hdd_ctx,
+			      unsigned long notify_id)
+{
+	sme_set_roam_intra_band(hdd_ctx->mac_handle,
+				hdd_ctx->config->nRoamIntraBand);
+}
+
+static void cb_notify_set_wes_mode(struct hdd_context *hdd_ctx,
+				   unsigned long notify_id)
+{
+	sme_update_wes_mode(hdd_ctx->mac_handle,
+			    hdd_ctx->config->isWESModeEnabled, 0);
+}
+
+static void
+cb_notify_set_roam_scan_n_probes(struct hdd_context *hdd_ctx,
+				 unsigned long notify_id)
+{
+	sme_update_roam_scan_n_probes(hdd_ctx->mac_handle, 0,
+				      hdd_ctx->config->nProbes);
+}
+
+static void
+cb_notify_set_roam_scan_home_away_time(struct hdd_context *hdd_ctx,
+				       unsigned long notify_id)
+{
+	uint16_t away_time = hdd_ctx->config->nRoamScanHomeAwayTime;
+
+	sme_update_roam_scan_home_away_time(hdd_ctx->mac_handle, 0,
+					    away_time, true);
+}
+
+static void
+notify_is_fast_roam_ini_feature_enabled(struct hdd_context *hdd_ctx,
+					unsigned long notify_id)
+{
+	bool enabled = hdd_ctx->config->isFastRoamIniFeatureEnabled;
+
+	sme_update_is_fast_roam_ini_feature_enabled(hdd_ctx->mac_handle, 0,
+						    enabled);
+}
+
+static void
+notify_is_mawc_ini_feature_enabled(struct hdd_context *hdd_ctx,
+				   unsigned long notify_id)
+{
+	sme_update_is_mawc_ini_feature_enabled(hdd_ctx->mac_handle,
+					       hdd_ctx->config->MAWCEnabled);
+}
+
+#ifdef FEATURE_WLAN_ESE
+static void
+cb_notify_set_ese_feature_enabled(struct hdd_context *hdd_ctx,
+				  unsigned long notify_id)
+{
+	bool enabled = hdd_ctx->config->isEseIniFeatureEnabled;
+
+	sme_update_is_ese_feature_enabled(hdd_ctx->mac_handle, 0, enabled);
+}
+#endif
+
+static void
+cb_notify_set_opportunistic_scan_threshold_diff(struct hdd_context *hdd_ctx,
+						unsigned long notify_id)
+{
+	uint8_t diff = hdd_ctx->config->nOpportunisticThresholdDiff;
+
+	sme_set_roam_opportunistic_scan_threshold_diff(hdd_ctx->mac_handle,
+						       0, diff);
+}
+
+static void cb_notify_set_roam_rescan_rssi_diff(struct hdd_context *hdd_ctx,
+						unsigned long notify_id)
+{
+	sme_set_roam_rescan_rssi_diff(hdd_ctx->mac_handle,
+				      0, hdd_ctx->config->nRoamRescanRssiDiff);
+}
+
+static void
+cb_notify_set_neighbor_lookup_rssi_threshold(struct hdd_context *hdd_ctx,
+					     unsigned long notify_id)
+{
+	uint8_t threshold = hdd_ctx->config->nNeighborLookupRssiThreshold;
+
+	sme_set_neighbor_lookup_rssi_threshold(hdd_ctx->mac_handle, 0,
+					       threshold);
+}
+
+static void
+cb_notify_set_delay_before_vdev_stop(struct hdd_context *hdd_ctx,
+				     unsigned long notify_id)
+{
+	sme_set_delay_before_vdev_stop(hdd_ctx->mac_handle, 0,
+				       hdd_ctx->config->delay_before_vdev_stop);
+}
+
+static void
+cb_notify_set_neighbor_scan_period(struct hdd_context *hdd_ctx,
+				   unsigned long notify_id)
+{
+	sme_set_neighbor_scan_period(hdd_ctx->mac_handle, 0,
+				     hdd_ctx->config->nNeighborScanPeriod);
+}
+
+/*
+ * cb_notify_set_neighbor_scan_min_period() - configure min rest
+ * time during roaming scan
+ *
+ * @hdd_ctx: HDD context data structure
+ * @notify_id: Identifies 1 of the 4 parameters to be modified
+ *
+ * Picks up the value from hdd configuration and passes it to SME.
+ * Return: void
+ */
+static void
+cb_notify_set_neighbor_scan_min_period(struct hdd_context *hdd_ctx,
+				       unsigned long notify_id)
+{
+	uint16_t period = hdd_ctx->config->neighbor_scan_min_period;
+
+	sme_set_neighbor_scan_min_period(hdd_ctx->mac_handle, 0,
+					 period);
+}
+
+static void
+cb_notify_set_neighbor_results_refresh_period(struct hdd_context *hdd_ctx,
+					      unsigned long notify_id)
+{
+	uint16_t period = hdd_ctx->config->nNeighborResultsRefreshPeriod;
+
+	sme_set_neighbor_scan_refresh_period(hdd_ctx->mac_handle, 0,
+					     period);
+}
+
+static void
+cb_notify_set_empty_scan_refresh_period(struct hdd_context *hdd_ctx,
+					unsigned long notify_id)
+{
+	uint16_t period = hdd_ctx->config->nEmptyScanRefreshPeriod;
+
+	sme_update_empty_scan_refresh_period(hdd_ctx->mac_handle, 0,
+					     period);
+}
+
+static void
+cb_notify_set_neighbor_scan_min_chan_time(struct hdd_context *hdd_ctx,
+					  unsigned long notify_id)
+{
+	uint16_t min_chan_time = hdd_ctx->config->nNeighborScanMinChanTime;
+
+	sme_set_neighbor_scan_min_chan_time(hdd_ctx->mac_handle,
+					    min_chan_time, 0);
+}
+
+static void
+cb_notify_set_neighbor_scan_max_chan_time(struct hdd_context *hdd_ctx,
+					  unsigned long notify_id)
+{
+	uint16_t max_chan_time = hdd_ctx->config->nNeighborScanMaxChanTime;
+
+	sme_set_neighbor_scan_max_chan_time(hdd_ctx->mac_handle, 0,
+					    max_chan_time);
+}
+
+static void cb_notify_set_roam_bmiss_first_bcnt(struct hdd_context *hdd_ctx,
+						unsigned long notify_id)
+{
+	sme_set_roam_bmiss_first_bcnt(hdd_ctx->mac_handle,
+				      0, hdd_ctx->config->nRoamBmissFirstBcnt);
+}
+
+static void cb_notify_set_roam_bmiss_final_bcnt(struct hdd_context *hdd_ctx,
+						unsigned long notify_id)
+{
+	sme_set_roam_bmiss_final_bcnt(hdd_ctx->mac_handle, 0,
+				      hdd_ctx->config->nRoamBmissFinalBcnt);
+}
+
+static void cb_notify_set_roam_beacon_rssi_weight(struct hdd_context *hdd_ctx,
+						  unsigned long notify_id)
+{
+	sme_set_roam_beacon_rssi_weight(hdd_ctx->mac_handle, 0,
+					hdd_ctx->config->nRoamBeaconRssiWeight);
+}
+
+static void
+cb_notify_set_dfs_scan_mode(struct hdd_context *hdd_ctx,
+			    unsigned long notify_id)
+{
+	sme_update_dfs_scan_mode(hdd_ctx->mac_handle, 0,
+				 hdd_ctx->config->allowDFSChannelRoam);
+}
+
+static void cb_notify_set_enable_ssr(struct hdd_context *hdd_ctx,
+				     unsigned long notify_id)
+{
+	sme_update_enable_ssr(hdd_ctx->mac_handle, hdd_ctx->config->enableSSR);
+}
+
+static void
+cb_notify_set_g_sap_preferred_chan_location(struct hdd_context *hdd_ctx,
+					    unsigned long notify_id)
+{
+	uint8_t location = hdd_ctx->config->gSapPreferredChanLocation;
+
+	wlansap_set_dfs_preferred_channel_location(hdd_ctx->mac_handle,
+						   location);
+}
+
+static void ch_notify_set_g_disable_dfs_japan_w53(struct hdd_context *hdd_ctx,
+						  unsigned long notify_id)
+{
+	bool disabled = hdd_ctx->config->gDisableDfsJapanW53;
+
+	wlansap_set_dfs_restrict_japan_w53(hdd_ctx->mac_handle, disabled);
+}
+
+static void
+cb_notify_update_roam_scan_offload_enabled(struct hdd_context *hdd_ctx,
+					   unsigned long notify_id)
+{
+	bool enabled = hdd_ctx->config->isRoamOffloadScanEnabled;
+
+	sme_update_roam_scan_offload_enabled(hdd_ctx->mac_handle, enabled);
+	if (enabled)
+		return;
+
+	/* fate sharing */
+	hdd_ctx->config->bFastRoamInConIniFeatureEnabled = false;
+	sme_update_enable_fast_roam_in_concurrency(hdd_ctx->mac_handle, false);
+}
+
+static void
+cb_notify_set_enable_fast_roam_in_concurrency(struct hdd_context *hdd_ctx,
+					      unsigned long notify_id)
+{
+	bool enabled = hdd_ctx->config->bFastRoamInConIniFeatureEnabled;
+
+	sme_update_enable_fast_roam_in_concurrency(hdd_ctx->mac_handle,
+						   enabled);
+}
+
+/**
+ * cb_notify_set_roam_scan_hi_rssi_scan_params() - configure hi rssi
+ * scan params from cfg to sme.
+ * @hdd_ctx: HDD context data structure
+ * @notify_id: Identifies 1 of the 4 parameters to be modified
+ *
+ * Picks up the value from hdd configuration and passes it to SME.
+ * Return: void
+ */
+
+static void
+cb_notify_set_roam_scan_hi_rssi_scan_params(struct hdd_context *hdd_ctx,
+					    unsigned long notify_id)
+{
+	int32_t val;
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	switch (notify_id) {
+	case eCSR_HI_RSSI_SCAN_MAXCOUNT_ID:
+		val = hdd_ctx->config->nhi_rssi_scan_max_count;
+		break;
+
+	case eCSR_HI_RSSI_SCAN_RSSI_DELTA_ID:
+		val = hdd_ctx->config->nhi_rssi_scan_rssi_delta;
+		break;
+
+	case eCSR_HI_RSSI_SCAN_DELAY_ID:
+		val = hdd_ctx->config->nhi_rssi_scan_delay;
+		break;
+
+	case eCSR_HI_RSSI_SCAN_RSSI_UB_ID:
+		val = hdd_ctx->config->nhi_rssi_scan_rssi_ub;
+		break;
+
+	default:
+		return;
+	}
+
+	sme_update_roam_scan_hi_rssi_scan_params(hdd_ctx->mac_handle, 0,
+						 notify_id, val);
+}
+
+
+struct reg_table_entry g_registry_table[] = {
+#ifdef WLAN_NUD_TRACKING
+	REG_VARIABLE(CFG_ENABLE_NUD_TRACKING_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_nud_tracking,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_NUD_TRACKING_DEFAULT,
+		     CFG_ENABLE_NUD_TRACKING_MIN,
+		     CFG_ENABLE_NUD_TRACKING_MAX),
+#endif
+
+	REG_VARIABLE(CFG_ENABLE_CONNECTED_SCAN_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_connected_scan,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_CONNECTED_SCAN_DEFAULT,
+		     CFG_ENABLE_CONNECTED_SCAN_MIN,
+		     CFG_ENABLE_CONNECTED_SCAN_MAX),
+
+	REG_VARIABLE(CFG_OPERATING_CHANNEL_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, OperatingChannel,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_OPERATING_CHANNEL_DEFAULT,
+		     CFG_OPERATING_CHANNEL_MIN,
+		     CFG_OPERATING_CHANNEL_MAX),
+
+	REG_VARIABLE(CFG_SHORT_SLOT_TIME_ENABLED_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, ShortSlotTimeEnabled,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+		     CFG_SHORT_SLOT_TIME_ENABLED_DEFAULT,
+		     CFG_SHORT_SLOT_TIME_ENABLED_MIN,
+		     CFG_SHORT_SLOT_TIME_ENABLED_MAX),
+
+	REG_VARIABLE(CFG_11D_SUPPORT_ENABLED_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, Is11dSupportEnabled,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+		     CFG_11D_SUPPORT_ENABLED_DEFAULT,
+		     CFG_11D_SUPPORT_ENABLED_MIN,
+		     CFG_11D_SUPPORT_ENABLED_MAX),
+
+	REG_VARIABLE(CFG_11H_SUPPORT_ENABLED_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, Is11hSupportEnabled,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+		     CFG_11H_SUPPORT_ENABLED_DEFAULT,
+		     CFG_11H_SUPPORT_ENABLED_MIN,
+		     CFG_11H_SUPPORT_ENABLED_MAX),
+
+	REG_VARIABLE(CFG_COUNTRY_CODE_PRIORITY_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, fSupplicantCountryCodeHasPriority,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+		     CFG_COUNTRY_CODE_PRIORITY_DEFAULT,
+		     CFG_COUNTRY_CODE_PRIORITY_MIN,
+		     CFG_COUNTRY_CODE_PRIORITY_MAX),
+
+	REG_VARIABLE_STRING(CFG_POWER_USAGE_NAME, WLAN_PARAM_String,
+			    struct hdd_config, PowerUsageControl,
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_POWER_USAGE_DEFAULT),
+
+	REG_VARIABLE(CFG_ENABLE_IMPS_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, fIsImpsEnabled,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_IMPS_DEFAULT,
+		     CFG_ENABLE_IMPS_MIN,
+		     CFG_ENABLE_IMPS_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_PS_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, is_ps_enabled,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_PS_DEFAULT,
+		     CFG_ENABLE_PS_MIN,
+		     CFG_ENABLE_PS_MAX),
+
+	REG_VARIABLE(CFG_AUTO_PS_ENABLE_TIMER_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, auto_bmps_timer_val,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_AUTO_PS_ENABLE_TIMER_DEFAULT,
+		     CFG_AUTO_PS_ENABLE_TIMER_MIN,
+		     CFG_AUTO_PS_ENABLE_TIMER_MAX),
+
+#ifdef WLAN_ICMP_DISABLE_PS
+	REG_VARIABLE(CFG_ICMP_DISABLE_PS_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, icmp_disable_ps_val,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ICMP_DISABLE_PS_DEFAULT,
+		     CFG_ICMP_DISABLE_PS_MIN,
+		     CFG_ICMP_DISABLE_PS_MAX),
+#endif
+
+	REG_VARIABLE(CFG_BMPS_MINIMUM_LI_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nBmpsMinListenInterval,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_BMPS_MINIMUM_LI_DEFAULT,
+		     CFG_BMPS_MINIMUM_LI_MIN,
+		     CFG_BMPS_MINIMUM_LI_MAX),
+
+	REG_VARIABLE(CFG_BMPS_MAXIMUM_LI_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nBmpsMaxListenInterval,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_BMPS_MAXIMUM_LI_DEFAULT,
+		     CFG_BMPS_MAXIMUM_LI_MIN,
+		     CFG_BMPS_MAXIMUM_LI_MAX),
+
+	REG_VARIABLE(CFG_DOT11_MODE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, dot11Mode,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+		     CFG_DOT11_MODE_DEFAULT,
+		     CFG_DOT11_MODE_MIN,
+		     CFG_DOT11_MODE_MAX),
+
+	REG_VARIABLE(CFG_CHANNEL_BONDING_MODE_24GHZ_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nChannelBondingMode24GHz,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+		     CFG_CHANNEL_BONDING_MODE_DEFAULT,
+		     CFG_CHANNEL_BONDING_MODE_MIN,
+		     CFG_CHANNEL_BONDING_MODE_MAX),
+
+	REG_VARIABLE(CFG_OVERRIDE_HT40_20_24GHZ_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, override_ht20_40_24g,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_OVERRIDE_HT40_20_24GHZ_DEFAULT,
+		     CFG_OVERRIDE_HT40_20_24GHZ_MIN,
+		     CFG_OVERRIDE_HT40_20_24GHZ_MAX),
+
+	REG_VARIABLE(CFG_CHANNEL_BONDING_MODE_5GHZ_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nChannelBondingMode5GHz,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+		     CFG_CHANNEL_BONDING_MODE_DEFAULT,
+		     CFG_CHANNEL_BONDING_MODE_MIN,
+		     CFG_CHANNEL_BONDING_MODE_MAX),
+
+	REG_VARIABLE(CFG_SCAN_RESULT_AGE_COUNT_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, ScanResultAgeCount,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+		     CFG_SCAN_RESULT_AGE_COUNT_DEFAULT,
+		     CFG_SCAN_RESULT_AGE_COUNT_MIN,
+		     CFG_SCAN_RESULT_AGE_COUNT_MAX),
+
+	REG_VARIABLE(CFG_RSSI_CATEGORY_GAP_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nRssiCatGap,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_RSSI_CATEGORY_GAP_DEFAULT,
+		     CFG_RSSI_CATEGORY_GAP_MIN,
+		     CFG_RSSI_CATEGORY_GAP_MAX),
+
+	REG_VARIABLE_STRING(CFG_IBSS_BSSID_NAME, WLAN_PARAM_MacAddr,
+			    struct hdd_config, IbssBssid,
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_IBSS_BSSID_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_INTF0_MAC_ADDR_NAME, WLAN_PARAM_MacAddr,
+			    struct hdd_config, intfMacAddr[0],
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_INTF0_MAC_ADDR_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_INTF1_MAC_ADDR_NAME, WLAN_PARAM_MacAddr,
+			    struct hdd_config, intfMacAddr[1],
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_INTF1_MAC_ADDR_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_INTF2_MAC_ADDR_NAME, WLAN_PARAM_MacAddr,
+			    struct hdd_config, intfMacAddr[2],
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_INTF2_MAC_ADDR_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_INTF3_MAC_ADDR_NAME, WLAN_PARAM_MacAddr,
+			    struct hdd_config, intfMacAddr[3],
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_INTF3_MAC_ADDR_DEFAULT),
+
+	REG_VARIABLE(CFG_AP_QOS_UAPSD_MODE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, apUapsdEnabled,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_AP_QOS_UAPSD_MODE_DEFAULT,
+		     CFG_AP_QOS_UAPSD_MODE_MIN,
+		     CFG_AP_QOS_UAPSD_MODE_MAX),
+
+	REG_VARIABLE(CFG_AP_ENABLE_RANDOM_BSSID_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, apRandomBssidEnabled,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_AP_ENABLE_RANDOM_BSSID_DEFAULT,
+		     CFG_AP_ENABLE_RANDOM_BSSID_MIN,
+		     CFG_AP_ENABLE_RANDOM_BSSID_MAX),
+
+	REG_VARIABLE(CFG_AP_ENABLE_PROTECTION_MODE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, apProtEnabled,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_AP_ENABLE_PROTECTION_MODE_DEFAULT,
+		     CFG_AP_ENABLE_PROTECTION_MODE_MIN,
+		     CFG_AP_ENABLE_PROTECTION_MODE_MAX),
+
+	REG_VARIABLE(CFG_AP_PROTECTION_MODE_NAME, WLAN_PARAM_HexInteger,
+		     struct hdd_config, apProtection,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_AP_PROTECTION_MODE_DEFAULT,
+		     CFG_AP_PROTECTION_MODE_MIN,
+		     CFG_AP_PROTECTION_MODE_MAX),
+
+	REG_VARIABLE(CFG_AP_OBSS_PROTECTION_MODE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, apOBSSProtEnabled,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_AP_OBSS_PROTECTION_MODE_DEFAULT,
+		     CFG_AP_OBSS_PROTECTION_MODE_MIN,
+		     CFG_AP_OBSS_PROTECTION_MODE_MAX),
+
+	REG_VARIABLE(CFG_AP_STA_SECURITY_SEPERATION_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, apDisableIntraBssFwd,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_AP_STA_SECURITY_SEPERATION_DEFAULT,
+		     CFG_AP_STA_SECURITY_SEPERATION_MIN,
+		     CFG_AP_STA_SECURITY_SEPERATION_MAX),
+
+#ifdef FEATURE_WLAN_DYNAMIC_CVM
+	REG_VARIABLE(CFG_VC_MODE_BITMAP, WLAN_PARAM_HexInteger,
+		struct hdd_config, vc_mode_cfg_bitmap,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_VC_MODE_BITMAP_DEFAULT,
+		CFG_VC_MODE_BITMAP_MIN,
+		CFG_VC_MODE_BITMAP_MAX),
+#endif
+
+	REG_VARIABLE(CFG_ENABLE_SAP_MANDATORY_CHAN_LIST, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_sap_mandatory_chan_list,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_SAP_MANDATORY_CHAN_LIST_DEFAULT,
+		     CFG_ENABLE_SAP_MANDATORY_CHAN_LIST_MIN,
+		     CFG_ENABLE_SAP_MANDATORY_CHAN_LIST_MAX),
+
+	REG_VARIABLE(CFG_DISABLE_PACKET_FILTER, WLAN_PARAM_Integer,
+		     struct hdd_config, disablePacketFilter,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_DISABLE_PACKET_FILTER_DEFAULT,
+		     CFG_DISABLE_PACKET_FILTER_MIN,
+		     CFG_DISABLE_PACKET_FILTER_MAX),
+
+	REG_VARIABLE(CFG_VCC_RSSI_TRIGGER_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nVccRssiTrigger,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_VCC_RSSI_TRIGGER_DEFAULT,
+		     CFG_VCC_RSSI_TRIGGER_MIN,
+		     CFG_VCC_RSSI_TRIGGER_MAX),
+
+	REG_VARIABLE(CFG_VCC_UL_MAC_LOSS_THRESH_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nVccUlMacLossThreshold,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_VCC_UL_MAC_LOSS_THRESH_DEFAULT,
+		     CFG_VCC_UL_MAC_LOSS_THRESH_MIN,
+		     CFG_VCC_UL_MAC_LOSS_THRESH_MAX),
+
+	REG_VARIABLE(CFG_PASSIVE_MAX_CHANNEL_TIME_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nPassiveMaxChnTime,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_PASSIVE_MAX_CHANNEL_TIME_DEFAULT,
+		     CFG_PASSIVE_MAX_CHANNEL_TIME_MIN,
+		     CFG_PASSIVE_MAX_CHANNEL_TIME_MAX),
+
+	REG_VARIABLE(CFG_ACTIVE_MAX_CHANNEL_TIME_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nActiveMaxChnTime,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ACTIVE_MAX_CHANNEL_TIME_DEFAULT,
+		     CFG_ACTIVE_MAX_CHANNEL_TIME_MIN,
+		     CFG_ACTIVE_MAX_CHANNEL_TIME_MAX),
+
+	REG_VARIABLE(CFG_SCAN_NUM_PROBES_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, scan_num_probes,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_SCAN_NUM_PROBES_DEFAULT,
+		     CFG_SCAN_NUM_PROBES_MIN,
+		     CFG_SCAN_NUM_PROBES_MAX),
+
+	REG_VARIABLE(CFG_SCAN_PROBE_REPEAT_TIME_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, scan_probe_repeat_time,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_SCAN_PROBE_REPEAT_TIME_DEFAULT,
+		     CFG_SCAN_PROBE_REPEAT_TIME_MIN,
+		     CFG_SCAN_PROBE_REPEAT_TIME_MAX),
+
+	REG_VARIABLE(CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nPassiveMaxChnTimeConc,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_DEFAULT,
+		     CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN,
+		     CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX),
+
+	REG_VARIABLE(CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nPassiveMinChnTimeConc,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_DEFAULT,
+		     CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN,
+		     CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX),
+
+	REG_VARIABLE(CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nActiveMaxChnTimeConc,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_DEFAULT,
+		     CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN,
+		     CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX),
+
+	REG_VARIABLE(CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nActiveMinChnTimeConc,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_DEFAULT,
+		     CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN,
+		     CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX),
+
+	REG_VARIABLE(CFG_REST_TIME_CONC_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nRestTimeConc,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_REST_TIME_CONC_DEFAULT,
+		     CFG_REST_TIME_CONC_MIN,
+		     CFG_REST_TIME_CONC_MAX),
+
+	REG_VARIABLE(CFG_MIN_REST_TIME_NAME, WLAN_PARAM_Integer,
+		      struct hdd_config, min_rest_time_conc,
+		      VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		      CFG_MIN_REST_TIME_DEFAULT,
+		      CFG_MIN_REST_TIME_MIN,
+		      CFG_MIN_REST_TIME_MAX),
+
+	REG_VARIABLE(CFG_IDLE_TIME_NAME, WLAN_PARAM_Integer,
+		      struct hdd_config, idle_time_conc,
+		      VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		      CFG_IDLE_TIME_DEFAULT,
+		      CFG_IDLE_TIME_MIN,
+		      CFG_IDLE_TIME_MAX),
+
+	REG_VARIABLE(CFG_MAX_TX_POWER_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nTxPowerCap,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_MAX_TX_POWER_DEFAULT,
+		     CFG_MAX_TX_POWER_MIN,
+		     CFG_MAX_TX_POWER_MAX),
+
+	REG_VARIABLE(CFG_TX_POWER_CTRL_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, allow_tpc_from_ap,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_TX_POWER_CTRL_DEFAULT,
+		     CFG_TX_POWER_CTRL_MIN,
+		     CFG_TX_POWER_CTRL_MAX),
+
+	REG_VARIABLE(CFG_MAX_LI_MODULATED_DTIM_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, fMaxLIModulatedDTIM,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_MAX_LI_MODULATED_DTIM_DEFAULT,
+		     CFG_MAX_LI_MODULATED_DTIM_MIN,
+		     CFG_MAX_LI_MODULATED_DTIM_MAX),
+
+	REG_VARIABLE(CFG_FW_MCC_RTS_CTS_PROT_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, mcc_rts_cts_prot_enable,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_FW_MCC_RTS_CTS_PROT_DEFAULT,
+		CFG_FW_MCC_RTS_CTS_PROT_MIN,
+		CFG_FW_MCC_RTS_CTS_PROT_MAX),
+
+	REG_VARIABLE(CFG_FW_MCC_BCAST_PROB_RESP_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, mcc_bcast_prob_resp_enable,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_FW_MCC_BCAST_PROB_RESP_DEFAULT,
+		CFG_FW_MCC_BCAST_PROB_RESP_MIN,
+		CFG_FW_MCC_BCAST_PROB_RESP_MAX),
+
+	REG_VARIABLE(CFG_WOW_DATA_INACTIVITY_TIMEOUT_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, wow_data_inactivity_timeout,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_WOW_DATA_INACTIVITY_TIMEOUT_DEFAULT,
+		     CFG_WOW_DATA_INACTIVITY_TIMEOUT_MIN,
+		     CFG_WOW_DATA_INACTIVITY_TIMEOUT_MAX),
+
+#ifdef FEATURE_WLAN_ESE
+	REG_VARIABLE(CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, InfraInactivityInterval,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_DEFAULT,
+		     CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MIN,
+		     CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MAX),
+
+	REG_DYNAMIC_VARIABLE(CFG_ESE_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer,
+			     struct hdd_config, isEseIniFeatureEnabled,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ESE_FEATURE_ENABLED_DEFAULT,
+			     CFG_ESE_FEATURE_ENABLED_MIN,
+			     CFG_ESE_FEATURE_ENABLED_MAX,
+			     cb_notify_set_ese_feature_enabled, 0),
+#endif /* FEATURE_WLAN_ESE */
+
+	/* flag to turn ON/OFF Legacy Fast Roaming */
+	REG_DYNAMIC_VARIABLE(CFG_LFR_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer,
+			     struct hdd_config, isFastRoamIniFeatureEnabled,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_LFR_FEATURE_ENABLED_DEFAULT,
+			     CFG_LFR_FEATURE_ENABLED_MIN,
+			     CFG_LFR_FEATURE_ENABLED_MAX,
+			     notify_is_fast_roam_ini_feature_enabled, 0),
+
+	/* flag to turn ON/OFF Motion assistance for Legacy Fast Roaming */
+	REG_DYNAMIC_VARIABLE(CFG_LFR_MAWC_FEATURE_ENABLED_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, MAWCEnabled,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_LFR_MAWC_FEATURE_ENABLED_DEFAULT,
+			     CFG_LFR_MAWC_FEATURE_ENABLED_MIN,
+			     CFG_LFR_MAWC_FEATURE_ENABLED_MAX,
+			     notify_is_mawc_ini_feature_enabled, 0),
+
+	/* flag to turn ON/OFF 11r and ESE FastTransition */
+	REG_DYNAMIC_VARIABLE(CFG_FAST_TRANSITION_ENABLED_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, isFastTransitionEnabled,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT,
+			     CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
+			     CFG_FAST_TRANSITION_ENABLED_NAME_MAX,
+			     cb_notify_set_fast_transition_enabled, 0),
+
+	/* Variable to specify the delta/difference between the
+	 * RSSI of current AP and roamable AP while roaming
+	 */
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_RSSI_DIFF_NAME, WLAN_PARAM_Integer,
+			     struct hdd_config, RoamRssiDiff,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_RSSI_DIFF_DEFAULT,
+			     CFG_ROAM_RSSI_DIFF_MIN,
+			     CFG_ROAM_RSSI_DIFF_MAX,
+			     cb_notify_set_roam_rssi_diff, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ENABLE_WES_MODE_NAME, WLAN_PARAM_Integer,
+			     struct hdd_config, isWESModeEnabled,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ENABLE_WES_MODE_NAME_DEFAULT,
+			     CFG_ENABLE_WES_MODE_NAME_MIN,
+			     CFG_ENABLE_WES_MODE_NAME_MAX,
+			     cb_notify_set_wes_mode, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_SCAN_OFFLOAD_ENABLED, WLAN_PARAM_Integer,
+			     struct hdd_config, isRoamOffloadScanEnabled,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_SCAN_OFFLOAD_ENABLED_DEFAULT,
+			     CFG_ROAM_SCAN_OFFLOAD_ENABLED_MIN,
+			     CFG_ROAM_SCAN_OFFLOAD_ENABLED_MAX,
+			     cb_notify_update_roam_scan_offload_enabled, 0),
+
+	REG_VARIABLE(CFG_TL_DELAYED_TRGR_FRM_INT_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, DelayedTriggerFrmInt,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_TL_DELAYED_TRGR_FRM_INT_DEFAULT,
+		     CFG_TL_DELAYED_TRGR_FRM_INT_MIN,
+		     CFG_TL_DELAYED_TRGR_FRM_INT_MAX),
+
+	REG_VARIABLE(CFG_RRM_ENABLE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, fRrmEnable,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_RRM_ENABLE_DEFAULT,
+		     CFG_RRM_ENABLE_MIN,
+		     CFG_RRM_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_RRM_MEAS_RANDOMIZATION_INTVL_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nRrmRandnIntvl,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_RRM_MEAS_RANDOMIZATION_INTVL_DEFAULT,
+		     CFG_RRM_MEAS_RANDOMIZATION_INTVL_MIN,
+		     CFG_RRM_MEAS_RANDOMIZATION_INTVL_MAX),
+
+	REG_VARIABLE_STRING(CFG_RM_CAPABILITY_NAME, WLAN_PARAM_String,
+			    struct hdd_config, rm_capability,
+			    VAR_FLAGS_OPTIONAL,
+			    (void *) CFG_RM_CAPABILITY_DEFAULT),
+
+	REG_DYNAMIC_VARIABLE(CFG_NEIGHBOR_SCAN_TIMER_PERIOD_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, nNeighborScanPeriod,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT,
+			     CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
+			     CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX,
+			     cb_notify_set_neighbor_scan_period, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_NEIGHBOR_SCAN_MIN_TIMER_PERIOD_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, neighbor_scan_min_period,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_NEIGHBOR_SCAN_MIN_TIMER_PERIOD_DEFAULT,
+			     CFG_NEIGHBOR_SCAN_MIN_TIMER_PERIOD_MIN,
+			     CFG_NEIGHBOR_SCAN_MIN_TIMER_PERIOD_MAX,
+			     cb_notify_set_neighbor_scan_min_period, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, nNeighborLookupRssiThreshold,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT,
+			     CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
+			     CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX,
+			     cb_notify_set_neighbor_lookup_rssi_threshold, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, nOpportunisticThresholdDiff,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_DEFAULT,
+			     CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_MIN,
+			     CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_MAX,
+			     cb_notify_set_opportunistic_scan_threshold_diff,
+			     0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_RESCAN_RSSI_DIFF_NAME, WLAN_PARAM_Integer,
+			     struct hdd_config, nRoamRescanRssiDiff,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_RESCAN_RSSI_DIFF_DEFAULT,
+			     CFG_ROAM_RESCAN_RSSI_DIFF_MIN,
+			     CFG_ROAM_RESCAN_RSSI_DIFF_MAX,
+			     cb_notify_set_roam_rescan_rssi_diff, 0),
+
+	REG_VARIABLE_STRING(CFG_NEIGHBOR_SCAN_CHAN_LIST_NAME, WLAN_PARAM_String,
+			    struct hdd_config, neighborScanChanList,
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_NEIGHBOR_SCAN_CHAN_LIST_DEFAULT),
+
+	REG_DYNAMIC_VARIABLE(CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, nNeighborScanMinChanTime,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT,
+			     CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
+			     CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX,
+			     cb_notify_set_neighbor_scan_min_chan_time, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, nNeighborScanMaxChanTime,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT,
+			     CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
+			     CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX,
+			     cb_notify_set_neighbor_scan_max_chan_time, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, nNeighborResultsRefreshPeriod,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT,
+			     CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN,
+			     CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX,
+			     cb_notify_set_neighbor_results_refresh_period, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_EMPTY_SCAN_REFRESH_PERIOD_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, nEmptyScanRefreshPeriod,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT,
+			     CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN,
+			     CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX,
+			     cb_notify_set_empty_scan_refresh_period, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_BMISS_FIRST_BCNT_NAME, WLAN_PARAM_Integer,
+			     struct hdd_config, nRoamBmissFirstBcnt,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_BMISS_FIRST_BCNT_DEFAULT,
+			     CFG_ROAM_BMISS_FIRST_BCNT_MIN,
+			     CFG_ROAM_BMISS_FIRST_BCNT_MAX,
+			     cb_notify_set_roam_bmiss_first_bcnt, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_BMISS_FINAL_BCNT_NAME, WLAN_PARAM_Integer,
+			     struct hdd_config, nRoamBmissFinalBcnt,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_BMISS_FINAL_BCNT_DEFAULT,
+			     CFG_ROAM_BMISS_FINAL_BCNT_MIN,
+			     CFG_ROAM_BMISS_FINAL_BCNT_MAX,
+			     cb_notify_set_roam_bmiss_final_bcnt, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_BEACON_RSSI_WEIGHT_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, nRoamBeaconRssiWeight,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_BEACON_RSSI_WEIGHT_DEFAULT,
+			     CFG_ROAM_BEACON_RSSI_WEIGHT_MIN,
+			     CFG_ROAM_BEACON_RSSI_WEIGHT_MAX,
+			     cb_notify_set_roam_beacon_rssi_weight, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAMING_DFS_CHANNEL_NAME, WLAN_PARAM_Integer,
+			     struct hdd_config, allowDFSChannelRoam,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAMING_DFS_CHANNEL_DEFAULT,
+			     CFG_ROAMING_DFS_CHANNEL_MIN,
+			     CFG_ROAMING_DFS_CHANNEL_MAX,
+			     cb_notify_set_dfs_scan_mode, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_DELAY_BEFORE_VDEV_STOP_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config,
+			     delay_before_vdev_stop,
+			     VAR_FLAGS_OPTIONAL |
+				VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_DELAY_BEFORE_VDEV_STOP_DEFAULT,
+			     CFG_DELAY_BEFORE_VDEV_STOP_MIN,
+			     CFG_DELAY_BEFORE_VDEV_STOP_MAX,
+			     cb_notify_set_delay_before_vdev_stop,
+			     0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_SCAN_HI_RSSI_MAXCOUNT_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config,
+			     nhi_rssi_scan_max_count,
+			     VAR_FLAGS_OPTIONAL |
+				VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_SCAN_HI_RSSI_MAXCOUNT_DEFAULT,
+			     CFG_ROAM_SCAN_HI_RSSI_MAXCOUNT_MIN,
+			     CFG_ROAM_SCAN_HI_RSSI_MAXCOUNT_MAX,
+			     cb_notify_set_roam_scan_hi_rssi_scan_params,
+			     eCSR_HI_RSSI_SCAN_MAXCOUNT_ID),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_SCAN_HI_RSSI_DELTA_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config,
+			     nhi_rssi_scan_rssi_delta,
+			     VAR_FLAGS_OPTIONAL |
+				VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_SCAN_HI_RSSI_DELTA_DEFAULT,
+			     CFG_ROAM_SCAN_HI_RSSI_DELTA_MIN,
+			     CFG_ROAM_SCAN_HI_RSSI_DELTA_MAX,
+			     cb_notify_set_roam_scan_hi_rssi_scan_params,
+			     eCSR_HI_RSSI_SCAN_RSSI_DELTA_ID),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_SCAN_HI_RSSI_DELAY_NAME,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config,
+			     nhi_rssi_scan_delay,
+			     VAR_FLAGS_OPTIONAL |
+				VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_SCAN_HI_RSSI_DELAY_DEFAULT,
+			     CFG_ROAM_SCAN_HI_RSSI_DELAY_MIN,
+			     CFG_ROAM_SCAN_HI_RSSI_DELAY_MAX,
+			     cb_notify_set_roam_scan_hi_rssi_scan_params,
+			     eCSR_HI_RSSI_SCAN_DELAY_ID),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_SCAN_HI_RSSI_UB_NAME,
+			     WLAN_PARAM_SignedInteger,
+			     struct hdd_config,
+			     nhi_rssi_scan_rssi_ub,
+			     VAR_FLAGS_OPTIONAL |
+				VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_SCAN_HI_RSSI_UB_DEFAULT,
+			     CFG_ROAM_SCAN_HI_RSSI_UB_MIN,
+			     CFG_ROAM_SCAN_HI_RSSI_UB_MAX,
+			     cb_notify_set_roam_scan_hi_rssi_scan_params,
+			     eCSR_HI_RSSI_SCAN_RSSI_UB_ID),
+
+	REG_VARIABLE(CFG_QOS_WMM_BURST_SIZE_DEFN_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, burstSizeDefinition,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_QOS_WMM_BURST_SIZE_DEFN_DEFAULT,
+		     CFG_QOS_WMM_BURST_SIZE_DEFN_MIN,
+		     CFG_QOS_WMM_BURST_SIZE_DEFN_MAX),
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+
+	REG_VARIABLE(CFG_RA_RATE_LIMIT_INTERVAL_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, RArateLimitInterval,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_RA_RATE_LIMIT_INTERVAL_DEFAULT,
+		     CFG_RA_RATE_LIMIT_INTERVAL_MIN,
+		     CFG_RA_RATE_LIMIT_INTERVAL_MAX),
+#endif
+
+#ifdef FEATURE_RUNTIME_PM
+	REG_VARIABLE(CFG_ENABLE_RUNTIME_PM, WLAN_PARAM_Integer,
+		     struct hdd_config, runtime_pm,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_RUNTIME_PM_DEFAULT,
+		     CFG_ENABLE_RUNTIME_PM_MIN,
+		     CFG_ENABLE_RUNTIME_PM_MAX),
+#endif
+
+	REG_VARIABLE(CFG_QOS_WMM_TS_INFO_ACK_POLICY_NAME, WLAN_PARAM_HexInteger,
+		     struct hdd_config, tsInfoAckPolicy,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_QOS_WMM_TS_INFO_ACK_POLICY_DEFAULT,
+		     CFG_QOS_WMM_TS_INFO_ACK_POLICY_MIN,
+		     CFG_QOS_WMM_TS_INFO_ACK_POLICY_MAX),
+
+	REG_VARIABLE(CFG_STA_KEEPALIVE_METHOD_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, sta_keepalive_method,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_STA_KEEPALIVE_METHOD_DEFAULT,
+		     CFG_STA_KEEPALIVE_METHOD_MIN,
+		     CFG_STA_KEEPALIVE_METHOD_MAX),
+
+	REG_VARIABLE(CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, AddTSWhenACMIsOff,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_DEFAULT,
+		     CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MIN,
+		     CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MAX),
+
+/* CFG_QDF_TRACE_ENABLE Parameters */
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_WDI_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_wdi,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_HDD_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_hdd,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_BMI_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_bmi,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_SME_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_sme,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_PE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_pe,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_WMA_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_wma,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_SYS_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_sys,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_QDF_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_qdf,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_SAP_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_sap,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_HDD_SAP_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_hdd_sap,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_CFG_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_cfg,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_TXRX_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_txrx,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_DP_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_dp,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DP_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_HTC_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_htc,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_HIF_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_hif,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_CDR_TRACE_ENABLE_HDD_SAP_DATA_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_hdd_sap_data,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_HDD_DATA_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_hdd_data,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_EPPING, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_epping,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_QDF_DEVICES, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_qdf_devices,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_WIFI_POS, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_wifi_pos,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_NAN, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_nan,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_REGULATORY, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_regulatory,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_QDF_TRACE_ENABLE_CP_STATS, WLAN_PARAM_Integer,
+		     struct hdd_config, qdf_trace_enable_cp_stats,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_QDF_TRACE_ENABLE_DEFAULT,
+		     CFG_QDF_TRACE_ENABLE_MIN,
+		     CFG_QDF_TRACE_ENABLE_MAX),
+
+#ifdef ENABLE_MTRACE_LOG
+	REG_VARIABLE(CFG_ENABLE_MTRACE, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_mtrace,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_ENABLE_MTRACE_DEFAULT,
+		     CFG_ENABLE_MTRACE_MIN,
+		     CFG_ENABLE_MTRACE_MAX),
+#endif
+
+	REG_VARIABLE(CFG_ENABLE_BYPASS_11D_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enableBypass11d,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_BYPASS_11D_DEFAULT,
+		     CFG_ENABLE_BYPASS_11D_MIN,
+		     CFG_ENABLE_BYPASS_11D_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_DFS_CHNL_SCAN_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enableDFSChnlScan,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_DFS_CHNL_SCAN_DEFAULT,
+		     CFG_ENABLE_DFS_CHNL_SCAN_MIN,
+		     CFG_ENABLE_DFS_CHNL_SCAN_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_DFS_PNO_CHNL_SCAN_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_dfs_pno_chnl_scan,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_DFS_PNO_CHNL_SCAN_DEFAULT,
+		     CFG_ENABLE_DFS_PNO_CHNL_SCAN_MIN,
+		     CFG_ENABLE_DFS_PNO_CHNL_SCAN_MAX),
+
+	REG_VARIABLE(CFG_SHORT_GI_40MHZ_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, ShortGI40MhzEnable,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_SHORT_GI_40MHZ_DEFAULT,
+		     CFG_SHORT_GI_40MHZ_MIN,
+		     CFG_SHORT_GI_40MHZ_MAX),
+
+	REG_DYNAMIC_VARIABLE(CFG_REPORT_MAX_LINK_SPEED, WLAN_PARAM_Integer,
+			     struct hdd_config, reportMaxLinkSpeed,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_REPORT_MAX_LINK_SPEED_DEFAULT,
+			     CFG_REPORT_MAX_LINK_SPEED_MIN,
+			     CFG_REPORT_MAX_LINK_SPEED_MAX,
+			     NULL, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_LINK_SPEED_RSSI_HIGH, WLAN_PARAM_SignedInteger,
+			     struct hdd_config, linkSpeedRssiHigh,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_LINK_SPEED_RSSI_HIGH_DEFAULT,
+			     CFG_LINK_SPEED_RSSI_HIGH_MIN,
+			     CFG_LINK_SPEED_RSSI_HIGH_MAX,
+			     NULL, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_LINK_SPEED_RSSI_MID, WLAN_PARAM_SignedInteger,
+			     struct hdd_config, linkSpeedRssiMid,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_LINK_SPEED_RSSI_MID_DEFAULT,
+			     CFG_LINK_SPEED_RSSI_MID_MIN,
+			     CFG_LINK_SPEED_RSSI_MID_MAX,
+			     NULL, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_LINK_SPEED_RSSI_LOW, WLAN_PARAM_SignedInteger,
+			     struct hdd_config, linkSpeedRssiLow,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_LINK_SPEED_RSSI_LOW_DEFAULT,
+			     CFG_LINK_SPEED_RSSI_LOW_MIN,
+			     CFG_LINK_SPEED_RSSI_LOW_MAX,
+			     NULL, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_PREFER_5GHZ, WLAN_PARAM_Integer,
+			     struct hdd_config, nRoamPrefer5GHz,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_PREFER_5GHZ_DEFAULT,
+			     CFG_ROAM_PREFER_5GHZ_MIN,
+			     CFG_ROAM_PREFER_5GHZ_MAX,
+			     cb_notify_set_roam_prefer5_g_hz, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_INTRA_BAND, WLAN_PARAM_Integer,
+			     struct hdd_config, nRoamIntraBand,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_INTRA_BAND_DEFAULT,
+			     CFG_ROAM_INTRA_BAND_MIN,
+			     CFG_ROAM_INTRA_BAND_MAX,
+			     cb_notify_set_roam_intra_band, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_SCAN_N_PROBES, WLAN_PARAM_Integer,
+			     struct hdd_config, nProbes,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_SCAN_N_PROBES_DEFAULT,
+			     CFG_ROAM_SCAN_N_PROBES_MIN,
+			     CFG_ROAM_SCAN_N_PROBES_MAX,
+			     cb_notify_set_roam_scan_n_probes, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ROAM_SCAN_HOME_AWAY_TIME, WLAN_PARAM_Integer,
+			     struct hdd_config, nRoamScanHomeAwayTime,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT,
+			     CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
+			     CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX,
+			     cb_notify_set_roam_scan_home_away_time, 0),
+
+	REG_VARIABLE(CFG_ENABLE_MCC_ENABLED_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enableMCC,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_MCC_ENABLED_DEFAULT,
+		     CFG_ENABLE_MCC_ENABLED_MIN,
+		     CFG_ENABLE_MCC_ENABLED_MAX),
+
+	REG_VARIABLE(CFG_ALLOW_MCC_GO_DIFF_BI_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, allowMCCGODiffBI,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ALLOW_MCC_GO_DIFF_BI_DEFAULT,
+		     CFG_ALLOW_MCC_GO_DIFF_BI_MIN,
+		     CFG_ALLOW_MCC_GO_DIFF_BI_MAX),
+
+	REG_VARIABLE(CFG_THERMAL_MIGRATION_ENABLE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, thermalMitigationEnable,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_THERMAL_MIGRATION_ENABLE_DEFAULT,
+		     CFG_THERMAL_MIGRATION_ENABLE_MIN,
+		     CFG_THERMAL_MIGRATION_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_THROTTLE_PERIOD_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, throttlePeriod,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_THROTTLE_PERIOD_DEFAULT,
+		     CFG_THROTTLE_PERIOD_MIN,
+		     CFG_THROTTLE_PERIOD_MAX),
+
+	REG_VARIABLE(CFG_THROTTLE_DUTY_CYCLE_LEVEL0_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, throttle_dutycycle_level0,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL0_DEFAULT,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL0_MIN,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL0_MAX),
+
+	REG_VARIABLE(CFG_THROTTLE_DUTY_CYCLE_LEVEL1_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, throttle_dutycycle_level1,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL1_DEFAULT,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL1_MIN,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL1_MAX),
+
+	REG_VARIABLE(CFG_THROTTLE_DUTY_CYCLE_LEVEL2_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, throttle_dutycycle_level2,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL2_DEFAULT,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL2_MIN,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL2_MAX),
+
+	REG_VARIABLE(CFG_THROTTLE_DUTY_CYCLE_LEVEL3_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, throttle_dutycycle_level3,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL3_DEFAULT,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL3_MIN,
+		     CFG_THROTTLE_DUTY_CYCLE_LEVEL3_MAX),
+
+	REG_VARIABLE(CFG_VDEV_TYPE_NSS_2G, WLAN_PARAM_Integer,
+		     struct hdd_config, vdev_type_nss_2g,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_VDEV_TYPE_NSS_2G_DEFAULT,
+		     CFG_VDEV_TYPE_NSS_2G_MIN,
+		     CFG_VDEV_TYPE_NSS_2G_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_BT_CHAIN_SEPARATION, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_bt_chain_separation,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_BT_CHAIN_SEPARATION_DEFAULT,
+		     CFG_ENABLE_BT_CHAIN_SEPARATION_MIN,
+		     CFG_ENABLE_BT_CHAIN_SEPARATION_MAX),
+
+	REG_VARIABLE(CFG_VDEV_TYPE_NSS_5G, WLAN_PARAM_Integer,
+		     struct hdd_config, vdev_type_nss_5g,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_VDEV_TYPE_NSS_5G_DEFAULT,
+		     CFG_VDEV_TYPE_NSS_5G_MIN,
+		     CFG_VDEV_TYPE_NSS_5G_MAX),
+
+	REG_VARIABLE(CFG_DISABLE_DFS_CH_SWITCH, WLAN_PARAM_Integer,
+		     struct hdd_config, disableDFSChSwitch,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_DISABLE_DFS_CH_SWITCH_DEFAULT,
+		     CFG_DISABLE_DFS_CH_SWITCH_MIN,
+		     CFG_DISABLE_DFS_CH_SWITCH_MAX),
+
+	REG_DYNAMIC_VARIABLE(CFG_SAP_PREFERRED_CHANNEL_LOCATION,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, gSapPreferredChanLocation,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_SAP_PREFERRED_CHANNEL_LOCATION_DEFAULT,
+			     CFG_SAP_PREFERRED_CHANNEL_LOCATION_MIN,
+			     CFG_SAP_PREFERRED_CHANNEL_LOCATION_MAX,
+			     cb_notify_set_g_sap_preferred_chan_location, 0),
+	REG_DYNAMIC_VARIABLE(CFG_DISABLE_DFS_JAPAN_W53, WLAN_PARAM_Integer,
+			     struct hdd_config, gDisableDfsJapanW53,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_DISABLE_DFS_JAPAN_W53_DEFAULT,
+			     CFG_DISABLE_DFS_JAPAN_W53_MIN,
+			     CFG_DISABLE_DFS_JAPAN_W53_MAX,
+			     ch_notify_set_g_disable_dfs_japan_w53, 0),
+
+	REG_VARIABLE(CFG_ENABLE_FIRST_SCAN_2G_ONLY_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enableFirstScan2GOnly,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_FIRST_SCAN_2G_ONLY_DEFAULT,
+		     CFG_ENABLE_FIRST_SCAN_2G_ONLY_MIN,
+		     CFG_ENABLE_FIRST_SCAN_2G_ONLY_MAX),
+
+	REG_VARIABLE(CFG_SCAN_AGING_PARAM_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, scanAgingTimeout,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_SCAN_AGING_PARAM_DEFAULT,
+		     CFG_SCAN_AGING_PARAM_MIN,
+		     CFG_SCAN_AGING_PARAM_MAX),
+
+	REG_VARIABLE(CFG_TX_LDPC_ENABLE_FEATURE, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_tx_ldpc,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_TX_LDPC_ENABLE_FEATURE_DEFAULT,
+		     CFG_TX_LDPC_ENABLE_FEATURE_MIN,
+		     CFG_TX_LDPC_ENABLE_FEATURE_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_RX_LDPC, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_rx_ldpc,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_RX_LDPC_DEFAULT,
+		     CFG_ENABLE_RX_LDPC_MIN,
+		     CFG_ENABLE_RX_LDPC_MAX),
+
+	REG_VARIABLE(CFG_IBSS_ADHOC_CHANNEL_5GHZ_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, AdHocChannel5G,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_IBSS_ADHOC_CHANNEL_5GHZ_DEFAULT,
+		     CFG_IBSS_ADHOC_CHANNEL_5GHZ_MIN,
+		     CFG_IBSS_ADHOC_CHANNEL_5GHZ_MAX),
+
+	REG_VARIABLE(CFG_IBSS_ADHOC_CHANNEL_24GHZ_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, AdHocChannel24G,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_IBSS_ADHOC_CHANNEL_24GHZ_DEFAULT,
+		     CFG_IBSS_ADHOC_CHANNEL_24GHZ_MIN,
+		     CFG_IBSS_ADHOC_CHANNEL_24GHZ_MAX),
+
+	REG_VARIABLE(CFG_DISABLE_LDPC_WITH_TXBF_AP, WLAN_PARAM_Integer,
+		     struct hdd_config, disableLDPCWithTxbfAP,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_DISABLE_LDPC_WITH_TXBF_AP_DEFAULT,
+		     CFG_DISABLE_LDPC_WITH_TXBF_AP_MIN,
+		     CFG_DISABLE_LDPC_WITH_TXBF_AP_MAX),
+
+	REG_DYNAMIC_VARIABLE(CFG_ENABLE_SSR, WLAN_PARAM_Integer,
+			     struct hdd_config, enableSSR,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ENABLE_SSR_DEFAULT,
+			     CFG_ENABLE_SSR_MIN,
+			     CFG_ENABLE_SSR_MAX,
+			     cb_notify_set_enable_ssr, 0),
+
+	REG_DYNAMIC_VARIABLE(CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY,
+			     WLAN_PARAM_Integer,
+			     struct hdd_config, bFastRoamInConIniFeatureEnabled,
+			     VAR_FLAGS_OPTIONAL |
+			     VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			     CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_DEFAULT,
+			     CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MIN,
+			     CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MAX,
+			     cb_notify_set_enable_fast_roam_in_concurrency, 0),
+
+	REG_VARIABLE(CFG_ENABLE_SNR_MONITORING_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, fEnableSNRMonitoring,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+		     CFG_ENABLE_SNR_MONITORING_DEFAULT,
+		     CFG_ENABLE_SNR_MONITORING_MIN,
+		     CFG_ENABLE_SNR_MONITORING_MAX),
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+	REG_VARIABLE(CFG_PNO_SCAN_SUPPORT, WLAN_PARAM_Integer,
+		     struct hdd_config, configPNOScanSupport,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_PNO_SCAN_SUPPORT_DEFAULT,
+		     CFG_PNO_SCAN_SUPPORT_DISABLE,
+		     CFG_PNO_SCAN_SUPPORT_ENABLE),
+
+	REG_VARIABLE(CFG_PNO_SCAN_TIMER_REPEAT_VALUE, WLAN_PARAM_Integer,
+		     struct hdd_config, configPNOScanTimerRepeatValue,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_PNO_SCAN_TIMER_REPEAT_VALUE_DEFAULT,
+		     CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MIN,
+		     CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MAX),
+
+	REG_VARIABLE(CFG_PNO_SLOW_SCAN_MULTIPLIER, WLAN_PARAM_Integer,
+		     struct hdd_config, pno_slow_scan_multiplier,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_PNO_SLOW_SCAN_MULTIPLIER_DEFAULT,
+		     CFG_PNO_SLOW_SCAN_MULTIPLIER_MIN,
+		     CFG_PNO_SLOW_SCAN_MULTIPLIER_MAX),
+#endif
+	REG_VARIABLE(CFG_COALESING_IN_IBSS_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, isCoalesingInIBSSAllowed,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_COALESING_IN_IBSS_DEFAULT,
+		     CFG_COALESING_IN_IBSS_MIN,
+		     CFG_COALESING_IN_IBSS_MAX),
+
+	REG_VARIABLE(CFG_IBSS_ATIM_WIN_SIZE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, ibssATIMWinSize,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_IBSS_ATIM_WIN_SIZE_DEFAULT,
+		     CFG_IBSS_ATIM_WIN_SIZE_MIN,
+		     CFG_IBSS_ATIM_WIN_SIZE_MAX),
+
+	REG_VARIABLE(CFG_IBSS_IS_POWER_SAVE_ALLOWED_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, isIbssPowerSaveAllowed,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_IBSS_IS_POWER_SAVE_ALLOWED_DEFAULT,
+		     CFG_IBSS_IS_POWER_SAVE_ALLOWED_MIN,
+		     CFG_IBSS_IS_POWER_SAVE_ALLOWED_MAX),
+
+	REG_VARIABLE(CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, isIbssPowerCollapseAllowed,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_DEFAULT,
+		     CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_MIN,
+		     CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_MAX),
+
+	REG_VARIABLE(CFG_IBSS_AWAKE_ON_TX_RX_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, isIbssAwakeOnTxRx,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_IBSS_AWAKE_ON_TX_RX_DEFAULT,
+		     CFG_IBSS_AWAKE_ON_TX_RX_MIN,
+		     CFG_IBSS_AWAKE_ON_TX_RX_MAX),
+
+	REG_VARIABLE(CFG_IBSS_INACTIVITY_TIME_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, ibssInactivityCount,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_IBSS_INACTIVITY_TIME_DEFAULT,
+		     CFG_IBSS_INACTIVITY_TIME_MIN,
+		     CFG_IBSS_INACTIVITY_TIME_MAX),
+
+	REG_VARIABLE(CFG_IBSS_TXSP_END_INACTIVITY_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, ibssTxSpEndInactivityTime,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_IBSS_TXSP_END_INACTIVITY_DEFAULT,
+		     CFG_IBSS_TXSP_END_INACTIVITY_MIN,
+		     CFG_IBSS_TXSP_END_INACTIVITY_MAX),
+
+	REG_VARIABLE(CFG_IBSS_PS_WARMUP_TIME_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, ibssPsWarmupTime,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_IBSS_PS_WARMUP_TIME_DEFAULT,
+		     CFG_IBSS_PS_WARMUP_TIME_MIN,
+		     CFG_IBSS_PS_WARMUP_TIME_MAX),
+
+	REG_VARIABLE(CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, ibssPs1RxChainInAtimEnable,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_DEFAULT,
+		     CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_MIN,
+		     CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_MAX),
+
+	REG_VARIABLE(CFG_SET_TXPOWER_LIMIT2G_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, TxPower2g,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_SET_TXPOWER_LIMIT2G_DEFAULT,
+		     CFG_SET_TXPOWER_LIMIT2G_MIN,
+		     CFG_SET_TXPOWER_LIMIT2G_MAX),
+
+	REG_VARIABLE(CFG_SET_TXPOWER_LIMIT5G_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, TxPower5g,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_SET_TXPOWER_LIMIT5G_DEFAULT,
+		     CFG_SET_TXPOWER_LIMIT5G_MIN,
+		     CFG_SET_TXPOWER_LIMIT5G_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, fDfsPhyerrFilterOffload,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_DEFAULT,
+		     CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MIN,
+		     CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_OVERLAP_CH, WLAN_PARAM_Integer,
+		     struct hdd_config, gEnableOverLapCh,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+		     CFG_ENABLE_OVERLAP_CH_DEFAULT,
+		     CFG_ENABLE_OVERLAP_CH_MIN,
+		     CFG_ENABLE_OVERLAP_CH_MAX),
+
+	REG_VARIABLE(CFG_REG_CHANGE_DEF_COUNTRY_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, fRegChangeDefCountry,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_REG_CHANGE_DEF_COUNTRY_DEFAULT,
+		     CFG_REG_CHANGE_DEF_COUNTRY_MIN,
+		     CFG_REG_CHANGE_DEF_COUNTRY_MAX),
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+
+	REG_VARIABLE(CFG_LL_TX_FLOW_STOP_QUEUE_TH, WLAN_PARAM_Integer,
+		     struct hdd_config, TxFlowStopQueueThreshold,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_LL_TX_FLOW_STOP_QUEUE_TH_DEFAULT,
+		     CFG_LL_TX_FLOW_STOP_QUEUE_TH_MIN,
+		     CFG_LL_TX_FLOW_STOP_QUEUE_TH_MAX),
+
+	REG_VARIABLE(CFG_LL_TX_FLOW_START_QUEUE_OFFSET, WLAN_PARAM_Integer,
+		     struct hdd_config, TxFlowStartQueueOffset,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_LL_TX_FLOW_START_QUEUE_OFFSET_DEFAULT,
+		     CFG_LL_TX_FLOW_START_QUEUE_OFFSET_MIN,
+		     CFG_LL_TX_FLOW_START_QUEUE_OFFSET_MAX),
+
+#endif
+	REG_VARIABLE(CFG_INITIAL_DWELL_TIME_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, nInitialDwellTime,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_INITIAL_DWELL_TIME_DEFAULT,
+		     CFG_INITIAL_DWELL_TIME_MIN,
+		     CFG_INITIAL_DWELL_TIME_MAX),
+
+	REG_VARIABLE(CFG_INITIAL_SCAN_NO_DFS_CHNL_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, initial_scan_no_dfs_chnl,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_INITIAL_SCAN_NO_DFS_CHNL_DEFAULT,
+		     CFG_INITIAL_SCAN_NO_DFS_CHNL_MIN,
+		     CFG_INITIAL_SCAN_NO_DFS_CHNL_MAX),
+
+	REG_VARIABLE(CFG_ADVERTISE_CONCURRENT_OPERATION_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, advertiseConcurrentOperation,
+		     VAR_FLAGS_OPTIONAL,
+		     CFG_ADVERTISE_CONCURRENT_OPERATION_DEFAULT,
+		     CFG_ADVERTISE_CONCURRENT_OPERATION_MIN,
+		     CFG_ADVERTISE_CONCURRENT_OPERATION_MAX),
+
+#ifdef MSM_PLATFORM
+	REG_VARIABLE(CFG_PERIODIC_STATS_DISPLAY_TIME_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, periodic_stats_disp_time,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_PERIODIC_STATS_DISPLAY_TIME_DEFAULT,
+		     CFG_PERIODIC_STATS_DISPLAY_TIME_MIN,
+		     CFG_PERIODIC_STATS_DISPLAY_TIME_MAX),
+#endif
+
+	REG_VARIABLE_STRING(CFG_ENABLE_FW_MODULE_LOG_LEVEL, WLAN_PARAM_String,
+			    struct hdd_config, enableFwModuleLogLevel,
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_ENABLE_FW_MODULE_LOG_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_ENABLE_CONCURRENT_STA, WLAN_PARAM_String,
+			    struct hdd_config, enableConcurrentSTA,
+			    VAR_FLAGS_NONE,
+			    (void *)CFG_ENABLE_CONCURRENT_STA_DEFAULT),
+
+	REG_VARIABLE(CFG_IGNORE_CAC_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, ignoreCAC,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_IGNORE_CAC_DEFAULT,
+		     CFG_IGNORE_CAC_MIN,
+		     CFG_IGNORE_CAC_MAX),
+
+	REG_VARIABLE(CFG_DFS_RADAR_PRI_MULTIPLIER_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, dfsRadarPriMultiplier,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_DFS_RADAR_PRI_MULTIPLIER_DEFAULT,
+		     CFG_DFS_RADAR_PRI_MULTIPLIER_MIN,
+		     CFG_DFS_RADAR_PRI_MULTIPLIER_MAX),
+
+	REG_VARIABLE(CFG_REORDER_OFFLOAD_SUPPORT_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, reorderOffloadSupport,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_REORDER_OFFLOAD_SUPPORT_DEFAULT,
+		     CFG_REORDER_OFFLOAD_SUPPORT_MIN,
+		     CFG_REORDER_OFFLOAD_SUPPORT_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_SAP_SUSPEND, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_sap_suspend,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_SAP_SUSPEND_DEFAULT,
+		     CFG_ENABLE_SAP_SUSPEND_MIN,
+		     CFG_ENABLE_SAP_SUSPEND_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, gEnableDeauthToDisassocMap,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_DEFAULT,
+		     CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_MIN,
+		     CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_MAX),
+#ifdef DHCP_SERVER_OFFLOAD
+	REG_VARIABLE_STRING(CFG_DHCP_SERVER_IP_NAME, WLAN_PARAM_String,
+			    struct hdd_config, dhcpServerIP,
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_DHCP_SERVER_IP_DEFAULT),
+#endif /* DHCP_SERVER_OFFLOAD */
+
+	REG_VARIABLE(CFG_ENABLE_MAC_ADDR_SPOOFING, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_mac_spoofing,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_MAC_ADDR_SPOOFING_DEFAULT,
+		     CFG_ENABLE_MAC_ADDR_SPOOFING_MIN,
+		     CFG_ENABLE_MAC_ADDR_SPOOFING_MAX),
+
+	REG_VARIABLE(CFG_STA_MIRACAST_MCC_REST_TIME_VAL, WLAN_PARAM_Integer,
+		     struct hdd_config, sta_miracast_mcc_rest_time_val,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_STA_MIRACAST_MCC_REST_TIME_VAL_DEFAULT,
+		     CFG_STA_MIRACAST_MCC_REST_TIME_VAL_MIN,
+		     CFG_STA_MIRACAST_MCC_REST_TIME_VAL_MAX),
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	REG_VARIABLE(CFG_SAP_MCC_CHANNEL_AVOIDANCE_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config,
+		     sap_channel_avoidance,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+		     CFG_SAP_MCC_CHANNEL_AVOIDANCE_DEFAULT,
+		     CFG_SAP_MCC_CHANNEL_AVOIDANCE_MIN,
+		     CFG_SAP_MCC_CHANNEL_AVOIDANCE_MAX),
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+	REG_VARIABLE(CFG_SAP_11AC_OVERRIDE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, sap_11ac_override,
+		     VAR_FLAGS_OPTIONAL |
+				VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_SAP_11AC_OVERRIDE_DEFAULT,
+		     CFG_SAP_11AC_OVERRIDE_MIN,
+		     CFG_SAP_11AC_OVERRIDE_MAX),
+
+	REG_VARIABLE(CFG_GO_11AC_OVERRIDE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, go_11ac_override,
+		     VAR_FLAGS_OPTIONAL |
+				VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_GO_11AC_OVERRIDE_DEFAULT,
+		     CFG_GO_11AC_OVERRIDE_MIN,
+		     CFG_GO_11AC_OVERRIDE_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_NON_DFS_CHAN_ON_RADAR, WLAN_PARAM_Integer,
+		     struct hdd_config, prefer_non_dfs_on_radar,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_DEFAULT,
+		     CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_MIN,
+		     CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_MAX),
+
+	REG_VARIABLE(CFG_MAX_MSDUS_PER_RXIND_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, max_msdus_per_rxinorderind,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_MAX_MSDUS_PER_RXIND_DEFAULT,
+		     CFG_MAX_MSDUS_PER_RXIND_MIN,
+		     CFG_MAX_MSDUS_PER_RXIND_MAX),
+
+	REG_VARIABLE(CFG_FINE_TIME_MEAS_CAPABILITY, WLAN_PARAM_HexInteger,
+		struct hdd_config, fine_time_meas_cap,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_FINE_TIME_MEAS_CAPABILITY_DEFAULT,
+		CFG_FINE_TIME_MEAS_CAPABILITY_MIN,
+		CFG_FINE_TIME_MEAS_CAPABILITY_MAX),
+
+	REG_VARIABLE(CFG_MAX_SCAN_COUNT_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, max_scan_count,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_MAX_SCAN_COUNT_DEFAULT,
+		     CFG_MAX_SCAN_COUNT_MIN,
+		     CFG_MAX_SCAN_COUNT_MAX),
+
+	REG_VARIABLE(CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE, WLAN_PARAM_Integer,
+		     struct hdd_config, etsi13_srd_chan_in_master_mode,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE_DEF,
+		     CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE_MIN,
+		     CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE_MAX),
+
+	REG_VARIABLE(CFG_DUAL_MAC_FEATURE_DISABLE, WLAN_PARAM_HexInteger,
+		     struct hdd_config, dual_mac_feature_disable,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_DUAL_MAC_FEATURE_DISABLE_DEFAULT,
+		     CFG_DUAL_MAC_FEATURE_DISABLE_MIN,
+		     CFG_DUAL_MAC_FEATURE_DISABLE_MAX),
+
+	REG_VARIABLE_STRING(CFG_DBS_SCAN_SELECTION_NAME, WLAN_PARAM_String,
+		     struct hdd_config, dbs_scan_selection,
+		     VAR_FLAGS_OPTIONAL,
+		     (void *)CFG_DBS_SCAN_SELECTION_DEFAULT),
+
+	REG_VARIABLE(CFG_STA_SAP_SCC_ON_DFS_CHAN, WLAN_PARAM_HexInteger,
+		     struct hdd_config, sta_sap_scc_on_dfs_chan,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_STA_SAP_SCC_ON_DFS_CHAN_DEFAULT,
+		     CFG_STA_SAP_SCC_ON_DFS_CHAN_MIN,
+		     CFG_STA_SAP_SCC_ON_DFS_CHAN_MAX),
+
+	REG_VARIABLE(CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN, WLAN_PARAM_HexInteger,
+		     struct hdd_config, sta_sap_scc_on_lte_coex_chan,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN_DEFAULT,
+		     CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN_MIN,
+		     CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN_MAX),
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+	REG_VARIABLE(CFG_PNO_CHANNEL_PREDICTION_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, pno_channel_prediction,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_PNO_CHANNEL_PREDICTION_DEFAULT,
+		     CFG_PNO_CHANNEL_PREDICTION_MIN,
+		     CFG_PNO_CHANNEL_PREDICTION_MAX),
+
+	REG_VARIABLE(CFG_TOP_K_NUM_OF_CHANNELS_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, top_k_num_of_channels,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_TOP_K_NUM_OF_CHANNELS_DEFAULT,
+		     CFG_TOP_K_NUM_OF_CHANNELS_MIN,
+		     CFG_TOP_K_NUM_OF_CHANNELS_MAX),
+
+	REG_VARIABLE(CFG_STATIONARY_THRESHOLD_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, stationary_thresh,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_STATIONARY_THRESHOLD_DEFAULT,
+		     CFG_STATIONARY_THRESHOLD_MIN,
+		     CFG_STATIONARY_THRESHOLD_MAX),
+
+	REG_VARIABLE(CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, channel_prediction_full_scan,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_DEFAULT,
+		     CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_MIN,
+		     CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_MAX),
+
+	REG_VARIABLE(CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, pnoscan_adaptive_dwell_mode,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_DEFAULT,
+		     CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_MIN,
+		     CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_MAX),
+#endif
+	REG_VARIABLE(CFG_SELF_GEN_FRM_PWR, WLAN_PARAM_Integer,
+		     struct hdd_config, self_gen_frm_pwr,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_SELF_GEN_FRM_PWR_DEFAULT,
+		     CFG_SELF_GEN_FRM_PWR_MIN,
+		     CFG_SELF_GEN_FRM_PWR_MAX),
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+	REG_VARIABLE(CFG_ENABLE_LFR_SUBNET_DETECTION, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_lfr_subnet_detection,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_LFR_SUBNET_DEFAULT,
+		     CFG_ENABLE_LFR_SUBNET_MIN,
+		     CFG_ENABLE_LFR_SUBNET_MAX),
+#endif
+	REG_VARIABLE(CFG_INFORM_BSS_RSSI_RAW_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, inform_bss_rssi_raw,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_INFORM_BSS_RSSI_RAW_DEFAULT,
+		CFG_INFORM_BSS_RSSI_RAW_MIN,
+		CFG_INFORM_BSS_RSSI_RAW_MAX),
+
+#ifdef WLAN_FEATURE_TSF
+#ifdef WLAN_FEATURE_TSF_PLUS
+	REG_VARIABLE(CFG_SET_TSF_PTP_OPT_NAME, WLAN_PARAM_HexInteger,
+		     struct hdd_config, tsf_ptp_options,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_SET_TSF_PTP_OPT_DEFAULT,
+		     CFG_SET_TSF_PTP_OPT_MIN,
+		     CFG_SET_TSF_PTP_OPT_MAX),
+#endif /* WLAN_FEATURE_TSF_PLUS */
+#endif
+
+	REG_VARIABLE(CFG_ROAM_HO_DELAY_FOR_RX_NAME,
+		WLAN_PARAM_Integer, struct hdd_config,
+		ho_delay_for_rx,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ROAM_HO_DELAY_FOR_RX_DEFAULT,
+		CFG_ROAM_HO_DELAY_FOR_RX_MIN,
+		CFG_ROAM_HO_DELAY_FOR_RX_MAX),
+
+	REG_VARIABLE(CFG_MIN_DELAY_BTW_ROAM_SCAN_NAME,
+		WLAN_PARAM_Integer, struct hdd_config,
+		min_delay_btw_roam_scans,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_MIN_DELAY_BTW_ROAM_SCAN_DEFAULT,
+		CFG_MIN_DELAY_BTW_ROAM_SCAN_MIN,
+		CFG_MIN_DELAY_BTW_ROAM_SCAN_MAX),
+
+	REG_VARIABLE(CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_NAME,
+		WLAN_PARAM_HexInteger, struct hdd_config,
+		roam_trigger_reason_bitmask,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_DEFAULT,
+		CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_MIN,
+		CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_MAX),
+
+	REG_VARIABLE_STRING(CFG_ENABLE_TX_SCHED_WRR_VO_NAME,
+			WLAN_PARAM_String,
+			struct hdd_config, tx_sched_wrr_vo,
+			VAR_FLAGS_OPTIONAL,
+			(void *) CFG_ENABLE_TX_SCHED_WRR_VO_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_ENABLE_TX_SCHED_WRR_VI_NAME,
+			WLAN_PARAM_String,
+			struct hdd_config, tx_sched_wrr_vi,
+			VAR_FLAGS_OPTIONAL,
+			(void *) CFG_ENABLE_TX_SCHED_WRR_VI_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_ENABLE_TX_SCHED_WRR_BE_NAME,
+			WLAN_PARAM_String,
+			struct hdd_config, tx_sched_wrr_be,
+			VAR_FLAGS_OPTIONAL,
+			(void *) CFG_ENABLE_TX_SCHED_WRR_BE_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_ENABLE_TX_SCHED_WRR_BK_NAME,
+			WLAN_PARAM_String,
+			struct hdd_config, tx_sched_wrr_bk,
+			VAR_FLAGS_OPTIONAL,
+			(void *) CFG_ENABLE_TX_SCHED_WRR_BK_DEFAULT),
+
+	REG_VARIABLE(CFG_CREATE_BUG_REPORT_FOR_SCAN, WLAN_PARAM_Integer,
+		struct hdd_config, bug_report_for_no_scan_results,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_CREATE_BUG_REPORT_FOR_SCAN_DEFAULT,
+		CFG_CREATE_BUG_REPORT_FOR_SCAN_DISABLE,
+		CFG_CREATE_BUG_REPORT_FOR_SCAN_ENABLE),
+
+#ifdef CONFIG_DP_TRACE
+	REG_VARIABLE(CFG_ENABLE_DP_TRACE, WLAN_PARAM_Integer,
+		struct hdd_config, enable_dp_trace,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ENABLE_DP_TRACE_DEFAULT,
+		CFG_ENABLE_DP_TRACE_MIN,
+		CFG_ENABLE_DP_TRACE_MAX),
+
+	REG_VARIABLE_STRING(CFG_ENABLE_DP_TRACE_CONFIG, WLAN_PARAM_String,
+			struct hdd_config, dp_trace_config,
+			VAR_FLAGS_OPTIONAL,
+			(void *) CFG_ENABLE_DP_TRACE_CONFIG_DEFAULT),
+#endif
+
+	REG_VARIABLE(CFG_ADAPTIVE_SCAN_DWELL_MODE_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, scan_adaptive_dwell_mode,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPTIVE_SCAN_DWELL_MODE_DEFAULT,
+		CFG_ADAPTIVE_SCAN_DWELL_MODE_MIN,
+		CFG_ADAPTIVE_SCAN_DWELL_MODE_MAX),
+
+	REG_VARIABLE(CFG_ADAPTIVE_SCAN_DWELL_MODE_NC_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, scan_adaptive_dwell_mode_nc,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ADAPTIVE_SCAN_DWELL_MODE_NC_DEFAULT,
+		     CFG_ADAPTIVE_SCAN_DWELL_MODE_NC_MIN,
+		     CFG_ADAPTIVE_SCAN_DWELL_MODE_NC_MAX),
+
+	REG_VARIABLE(CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, extscan_adaptive_dwell_mode,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_DEFAULT,
+		CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_MIN,
+		CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_MAX),
+
+	REG_VARIABLE(CFG_ADAPTIVE_DWELL_MODE_ENABLED_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, adaptive_dwell_mode_enabled,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPTIVE_DWELL_MODE_ENABLED_DEFAULT,
+		CFG_ADAPTIVE_DWELL_MODE_ENABLED_MIN,
+		CFG_ADAPTIVE_DWELL_MODE_ENABLED_MAX),
+
+	REG_VARIABLE(CFG_GLOBAL_ADAPTIVE_DWELL_MODE_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, global_adapt_dwelltime_mode,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_GLOBAL_ADAPTIVE_DWELL_MODE_DEFAULT,
+		CFG_GLOBAL_ADAPTIVE_DWELL_MODE_MIN,
+		CFG_GLOBAL_ADAPTIVE_DWELL_MODE_MAX),
+
+	REG_VARIABLE(CFG_ADAPT_DWELL_LPF_WEIGHT_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, adapt_dwell_lpf_weight,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPT_DWELL_LPF_WEIGHT_DEFAULT,
+		CFG_ADAPT_DWELL_LPF_WEIGHT_MIN,
+		CFG_ADAPT_DWELL_LPF_WEIGHT_MAX),
+
+	REG_VARIABLE(CFG_ADAPT_DWELL_PASMON_INTVAL_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, adapt_dwell_passive_mon_intval,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPT_DWELL_PASMON_INTVAL_DEFAULT,
+		CFG_ADAPT_DWELL_PASMON_INTVAL_MIN,
+		CFG_ADAPT_DWELL_PASMON_INTVAL_MAX),
+
+	REG_VARIABLE(CFG_ADAPT_DWELL_WIFI_THRESH_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, adapt_dwell_wifi_act_threshold,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPT_DWELL_WIFI_THRESH_DEFAULT,
+		CFG_ADAPT_DWELL_WIFI_THRESH_MIN,
+		CFG_ADAPT_DWELL_WIFI_THRESH_MAX),
+
+	REG_VARIABLE(CFG_NUM_DP_RX_THREADS_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, num_dp_rx_threads,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_NUM_DP_RX_THREADS_DEFAULT,
+		     CFG_NUM_DP_RX_THREADS_MIN,
+		     CFG_NUM_DP_RX_THREADS_MAX),
+
+	REG_VARIABLE(CFG_INDOOR_CHANNEL_SUPPORT_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, indoor_channel_support,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_INDOOR_CHANNEL_SUPPORT_DEFAULT,
+		     CFG_INDOOR_CHANNEL_SUPPORT_MIN,
+		     CFG_INDOOR_CHANNEL_SUPPORT_MAX),
+
+	REG_VARIABLE(CFG_MARK_INDOOR_AS_DISABLE_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, force_ssc_disable_indoor_channel,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_MARK_INDOOR_AS_DISABLE_DEFAULT,
+		     CFG_MARK_INDOOR_AS_DISABLE_MIN,
+		     CFG_MARK_INDOOR_AS_DISABLE_MAX),
+
+	REG_VARIABLE(CFG_SAP_TX_LEAKAGE_THRESHOLD_NAME,
+		WLAN_PARAM_Integer,
+		struct hdd_config, sap_tx_leakage_threshold,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_SAP_TX_LEAKAGE_THRESHOLD_DEFAULT,
+		CFG_SAP_TX_LEAKAGE_THRESHOLD_MIN,
+		CFG_SAP_TX_LEAKAGE_THRESHOLD_MAX),
+
+	REG_VARIABLE(CFG_SAP_FORCE_11N_FOR_11AC_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, sap_force_11n_for_11ac,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_SAP_FORCE_11N_FOR_11AC_DEFAULT,
+		     CFG_SAP_FORCE_11N_FOR_11AC_MIN,
+		     CFG_SAP_FORCE_11N_FOR_11AC_MAX),
+
+	REG_VARIABLE(CFG_GO_FORCE_11N_FOR_11AC_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, go_force_11n_for_11ac,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_GO_FORCE_11N_FOR_11AC_DEFAULT,
+		     CFG_GO_FORCE_11N_FOR_11AC_MIN,
+		     CFG_GO_FORCE_11N_FOR_11AC_MAX),
+
+	REG_VARIABLE(CFG_FILTER_MULTICAST_REPLAY_NAME,
+		WLAN_PARAM_Integer,
+		struct hdd_config, multicast_replay_filter,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_FILTER_MULTICAST_REPLAY_DEFAULT,
+		CFG_FILTER_MULTICAST_REPLAY_MIN,
+		CFG_FILTER_MULTICAST_REPLAY_MAX),
+
+	REG_VARIABLE(CFG_RX_WAKELOCK_TIMEOUT_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, rx_wakelock_timeout,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_RX_WAKELOCK_TIMEOUT_DEFAULT,
+		CFG_RX_WAKELOCK_TIMEOUT_MIN,
+		CFG_RX_WAKELOCK_TIMEOUT_MAX),
+
+	REG_VARIABLE(CFG_RESTART_BEACONING_ON_CH_AVOID_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, restart_beaconing_on_chan_avoid_event,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_RESTART_BEACONING_ON_CH_AVOID_DEFAULT,
+		CFG_RESTART_BEACONING_ON_CH_AVOID_MIN,
+		CFG_RESTART_BEACONING_ON_CH_AVOID_MAX),
+
+	REG_VARIABLE(CFG_ACTIVE_UC_APF_MODE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, active_uc_apf_mode,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ACTIVE_UC_APF_MODE_DEFAULT,
+		     CFG_ACTIVE_UC_APF_MODE_MIN,
+		     CFG_ACTIVE_UC_APF_MODE_MAX),
+
+	REG_VARIABLE(CFG_ACTIVE_MC_BC_APF_MODE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, active_mc_bc_apf_mode,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ACTIVE_MC_BC_APF_MODE_DEFAULT,
+		     CFG_ACTIVE_MC_BC_APF_MODE_MIN,
+		     CFG_ACTIVE_MC_BC_APF_MODE_MAX),
+
+#ifdef WLAN_FEATURE_11AX
+	REG_VARIABLE(CFG_ENABLE_UL_MIMO_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_ul_mimo,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_UL_MIMO_DEFAULT,
+		     CFG_ENABLE_UL_MIMO_MIN,
+		     CFG_ENABLE_UL_MIMO_MAX),
+
+	REG_VARIABLE(CFG_HE_DYNAMIC_FRAGMENTATION_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, he_dynamic_frag_support,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_HE_DYNAMIC_FRAGMENTATION_DEFAULT,
+		     CFG_HE_DYNAMIC_FRAGMENTATION_MIN,
+		     CFG_HE_DYNAMIC_FRAGMENTATION_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_UL_OFDMA_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_ul_ofdma,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_UL_OFDMA_DEFAULT,
+		     CFG_ENABLE_UL_OFDMA_MIN,
+		     CFG_ENABLE_UL_OFDMA_MAX),
+
+	REG_VARIABLE(CFG_HE_STA_OBSSPD_NAME, WLAN_PARAM_HexInteger,
+		     struct hdd_config, he_sta_obsspd,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_HE_STA_OBSSPD_DEFAULT,
+		     CFG_HE_STA_OBSSPD_MIN,
+		     CFG_HE_STA_OBSSPD_MAX),
+#endif
+#ifdef WLAN_SUPPORT_TWT
+	REG_VARIABLE(CFG_ENABLE_TWT_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_twt,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_TWT_DEFAULT,
+		     CFG_ENABLE_TWT_MIN,
+		     CFG_ENABLE_TWT_MAX),
+
+	REG_VARIABLE(CFG_TWT_CONGESTION_TIMEOUT_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, twt_congestion_timeout,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_TWT_CONGESTION_TIMEOUT_DEFAULT,
+		     CFG_TWT_CONGESTION_TIMEOUT_MIN,
+		     CFG_TWT_CONGESTION_TIMEOUT_MAX),
+#endif
+
+	REG_VARIABLE(CFG_SCAN_BACKOFF_MULTIPLIER_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, scan_backoff_multiplier,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_SCAN_BACKOFF_MULTIPLIER_DEFAULT,
+		CFG_SCAN_BACKOFF_MULTIPLIER_MIN,
+		CFG_SCAN_BACKOFF_MULTIPLIER_MAX),
+
+	REG_VARIABLE(CFG_MAWC_NLO_ENABLED_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, mawc_nlo_enabled,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_MAWC_NLO_ENABLED_DEFAULT,
+		CFG_MAWC_NLO_ENABLED_MIN,
+		CFG_MAWC_NLO_ENABLED_MAX),
+
+	REG_VARIABLE(CFG_MAWC_NLO_EXP_BACKOFF_RATIO_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, mawc_nlo_exp_backoff_ratio,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_MAWC_NLO_EXP_BACKOFF_RATIO_DEFAULT,
+		CFG_MAWC_NLO_EXP_BACKOFF_RATIO_MIN,
+		CFG_MAWC_NLO_EXP_BACKOFF_RATIO_MAX),
+
+	REG_VARIABLE(CFG_MAWC_NLO_INIT_SCAN_INTERVAL_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, mawc_nlo_init_scan_interval,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_MAWC_NLO_INIT_SCAN_INTERVAL_DEFAULT,
+		CFG_MAWC_NLO_INIT_SCAN_INTERVAL_MIN,
+		CFG_MAWC_NLO_INIT_SCAN_INTERVAL_MAX),
+
+	REG_VARIABLE(CFG_MAWC_NLO_MAX_SCAN_INTERVAL_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, mawc_nlo_max_scan_interval,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_MAWC_NLO_MAX_SCAN_INTERVAL_DEFAULT,
+		CFG_MAWC_NLO_MAX_SCAN_INTERVAL_MIN,
+		CFG_MAWC_NLO_MAX_SCAN_INTERVAL_MAX),
+
+	REG_VARIABLE(CFG_FORCE_1X1_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, is_force_1x1,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_FORCE_1X1_DEFAULT,
+		CFG_FORCE_1X1_MIN,
+		CFG_FORCE_1X1_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_11D_IN_WORLD_MODE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_11d_in_world_mode,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_11D_IN_WORLD_MODE_DEFAULT,
+		     CFG_ENABLE_11D_IN_WORLD_MODE_MIN,
+		     CFG_ENABLE_11D_IN_WORLD_MODE_MAX),
+
+	REG_VARIABLE(CFG_LPRx_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, enable_lprx,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_LPRx_DEFAULT,
+		CFG_LPRx_MIN,
+		CFG_LPRx_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_ACTION_OUI, WLAN_PARAM_Integer,
+		     struct hdd_config, action_oui_enable,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_ACTION_OUI_DEFAULT,
+		     CFG_ENABLE_ACTION_OUI_MIN,
+		     CFG_ENABLE_ACTION_OUI_MAX),
+
+	REG_VARIABLE_STRING(CFG_ACTION_OUI_CONNECT_1X1_NAME, WLAN_PARAM_String,
+			    struct hdd_config, action_oui_str[0],
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_ACTION_OUI_CONNECT_1X1_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_ACTION_OUI_ITO_EXTENSION_NAME,
+			    WLAN_PARAM_String,
+			    struct hdd_config, action_oui_str[1],
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_ACTION_OUI_ITO_EXTENSION_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_ACTION_OUI_CCKM_1X1_NAME, WLAN_PARAM_String,
+			    struct hdd_config, action_oui_str[2],
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_ACTION_OUI_CCKM_1X1_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_ACTION_OUI_ITO_ALTERNATE_NAME,
+			    WLAN_PARAM_String,
+			    struct hdd_config, action_oui_str[3],
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_ACTION_OUI_ITO_ALTERNATE_DEFAULT),
+	REG_VARIABLE_STRING(CFG_ACTION_OUI_SWITCH_TO_11N_MODE_NAME,
+			    WLAN_PARAM_String,
+			    struct hdd_config, action_oui_str[4],
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)CFG_ACTION_OUI_SWITCH_TO_11N_MODE_DEFAULT),
+
+	REG_VARIABLE_STRING(CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN_NAME,
+			    WLAN_PARAM_String,
+			    struct hdd_config, action_oui_str[5],
+			    VAR_FLAGS_OPTIONAL,
+			    (void *)
+			    CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN_DEFAULT),
+
+	REG_VARIABLE(CFG_SCAN_11D_INTERVAL_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, scan_11d_interval,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_SCAN_11D_INTERVAL_DEFAULT,
+		CFG_SCAN_11D_INTERVAL_MIN,
+		CFG_SCAN_11D_INTERVAL_MAX),
+
+	REG_VARIABLE(CFG_IS_BSSID_HINT_PRIORITY_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, is_bssid_hint_priority,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_IS_BSSID_HINT_PRIORITY_DEFAULT,
+		CFG_IS_BSSID_HINT_PRIORITY_MIN,
+		CFG_IS_BSSID_HINT_PRIORITY_MAX),
+
+	REG_VARIABLE(CFG_LATENCY_ENABLE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, wlm_latency_enable,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_LATENCY_ENABLE_DEFAULT,
+		     CFG_LATENCY_ENABLE_MIN,
+		     CFG_LATENCY_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_LATENCY_LEVEL_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, wlm_latency_level,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_LATENCY_LEVEL_DEFAULT,
+		     CFG_LATENCY_LEVEL_MIN,
+		     CFG_LATENCY_LEVEL_MAX),
+
+	REG_VARIABLE(CFG_LATENCY_FLAGS_NORMAL_NAME, WLAN_PARAM_HexInteger,
+		     struct hdd_config, wlm_latency_flags_normal,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_LATENCY_FLAGS_NORMAL_DEFAULT,
+		     CFG_LATENCY_FLAGS_NORMAL_MIN,
+		     CFG_LATENCY_FLAGS_NORMAL_MAX),
+
+	REG_VARIABLE(CFG_LATENCY_FLAGS_MODERATE_NAME, WLAN_PARAM_HexInteger,
+		     struct hdd_config, wlm_latency_flags_moderate,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_LATENCY_FLAGS_MODERATE_DEFAULT,
+		     CFG_LATENCY_FLAGS_MODERATE_MIN,
+		     CFG_LATENCY_FLAGS_MODERATE_MAX),
+
+	REG_VARIABLE(CFG_LATENCY_FLAGS_LOW_NAME, WLAN_PARAM_HexInteger,
+		     struct hdd_config, wlm_latency_flags_low,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_LATENCY_FLAGS_LOW_DEFAULT,
+		     CFG_LATENCY_FLAGS_LOW_MIN,
+		     CFG_LATENCY_FLAGS_LOW_MAX),
+
+	REG_VARIABLE(CFG_LATENCY_FLAGS_ULTRALOW_NAME, WLAN_PARAM_HexInteger,
+		     struct hdd_config, wlm_latency_flags_ultralow,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_LATENCY_FLAGS_ULTRALOW_DEFAULT,
+		     CFG_LATENCY_FLAGS_ULTRALOW_MIN,
+		     CFG_LATENCY_FLAGS_ULTRALOW_MAX),
+
+
+	REG_VARIABLE(CFG_DFS_BEACON_TX_ENHANCED, WLAN_PARAM_Integer,
+		struct hdd_config, dfs_beacon_tx_enhanced,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_DFS_BEACON_TX_ENHANCED_DEFAULT,
+		CFG_DFS_BEACON_TX_ENHANCED_MIN,
+		CFG_DFS_BEACON_TX_ENHANCED_MAX),
+
+	REG_VARIABLE(CFG_BTM_ENABLE_NAME, WLAN_PARAM_HexInteger,
+		     struct hdd_config, btm_offload_config,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_BTM_ENABLE_DEFAULT,
+		     CFG_BTM_ENABLE_MIN,
+		     CFG_BTM_ENABLE_MAX),
+
+#ifdef WLAN_FEATURE_SAE
+	REG_VARIABLE(CFG_IS_SAE_ENABLED_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, is_sae_enabled,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_IS_SAE_ENABLED_DEFAULT,
+		CFG_IS_SAE_ENABLED_MIN,
+		CFG_IS_SAE_ENABLED_MAX),
+#endif
+
+	REG_VARIABLE(CFG_BTM_SOLICITED_TIMEOUT, WLAN_PARAM_Integer,
+		     struct hdd_config, btm_solicited_timeout,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_BTM_SOLICITED_TIMEOUT_DEFAULT,
+		     CFG_BTM_SOLICITED_TIMEOUT_MIN,
+		     CFG_BTM_SOLICITED_TIMEOUT_MAX),
+
+	REG_VARIABLE(CFG_BTM_MAX_ATTEMPT_CNT, WLAN_PARAM_Integer,
+		     struct hdd_config, btm_max_attempt_cnt,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_BTM_MAX_ATTEMPT_CNT_DEFAULT,
+		     CFG_BTM_MAX_ATTEMPT_CNT_MIN,
+		     CFG_BTM_MAX_ATTEMPT_CNT_MAX),
+
+	REG_VARIABLE(CFG_BTM_STICKY_TIME, WLAN_PARAM_Integer,
+		     struct hdd_config, btm_sticky_time,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_BTM_STICKY_TIME_DEFAULT,
+		     CFG_BTM_STICKY_TIME_MIN,
+		     CFG_BTM_STICKY_TIME_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_GCMP_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, gcmp_enabled,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_GCMP_DEFAULT,
+		     CFG_ENABLE_GCMP_MIN,
+		     CFG_ENABLE_GCMP_MAX),
+
+	REG_VARIABLE(CFG_OFFLOAD_11K_ENABLE_BITMASK_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, offload_11k_enable_bitmask,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_OFFLOAD_11K_ENABLE_BITMASK_DEFAULT,
+		     CFG_OFFLOAD_11K_ENABLE_BITMASK_MIN,
+		     CFG_OFFLOAD_11K_ENABLE_BITMASK_MAX),
+
+	REG_VARIABLE(CFG_OFFLOAD_NEIGHBOR_REPORT_PARAMS_BITMASK_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, neighbor_report_offload_params_bitmask,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_PARAMS_BITMASK_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_PARAMS_BITMASK_MIN,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_PARAMS_BITMASK_MAX),
+
+	REG_VARIABLE(CFG_OFFLOAD_NEIGHBOR_REPORT_TIME_OFFSET_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, neighbor_report_offload_time_offset,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_TIME_OFFSET_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_TIME_OFFSET_MIN,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_TIME_OFFSET_MAX),
+
+	REG_VARIABLE(CFG_OFFLOAD_NEIGHBOR_REPORT_LOW_RSSI_OFFSET_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, neighbor_report_offload_low_rssi_offset,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_LOW_RSSI_OFFSET_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_LOW_RSSI_OFFSET_MIN,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_LOW_RSSI_OFFSET_MAX),
+
+	REG_VARIABLE(CFG_OFFLOAD_NEIGHBOR_REPORT_BMISS_COUNT_TRIGGER_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config,
+		     neighbor_report_offload_bmiss_count_trigger,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_BMISS_COUNT_TRIGGER_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_BMISS_COUNT_TRIGGER_MIN,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_BMISS_COUNT_TRIGGER_MAX),
+
+	REG_VARIABLE(CFG_OFFLOAD_NEIGHBOR_REPORT_PER_THRESHOLD_OFFSET_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config,
+		     neighbor_report_offload_per_threshold_offset,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_PER_THRESHOLD_OFFSET_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_PER_THRESHOLD_OFFSET_MIN,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_PER_THRESHOLD_OFFSET_MAX),
+
+	REG_VARIABLE(CFG_OFFLOAD_NEIGHBOR_REPORT_CACHE_TIMEOUT_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, neighbor_report_offload_cache_timeout,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_CACHE_TIMEOUT_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_CACHE_TIMEOUT_MIN,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_CACHE_TIMEOUT_MAX),
+
+	REG_VARIABLE(CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, neighbor_report_offload_max_req_cap,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_DEFAULT,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_MIN,
+		     CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_MAX),
+
+	REG_VARIABLE(CFG_WMI_WQ_WATCHDOG, WLAN_PARAM_Integer,
+		     struct hdd_config, wmi_wq_watchdog_timeout,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_WMI_WQ_WATCHDOG_DEFAULT,
+		     CFG_WMI_WQ_WATCHDOG_MIN,
+		     CFG_WMI_WQ_WATCHDOG_MAX),
+
+	REG_VARIABLE(CFG_DTIM_SELECTION_DIVERSITY_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, enable_dtim_selection_diversity,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_DTIM_SELECTION_DIVERSITY_DEFAULT,
+		     CFG_DTIM_SELECTION_DIVERSITY_MIN,
+		     CFG_DTIM_SELECTION_DIVERSITY_MAX),
+
+	REG_VARIABLE(CFG_TX_SCH_DELAY_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, enable_tx_sch_delay,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_TX_SCH_DELAY_DEFAULT,
+		     CFG_TX_SCH_DELAY_MIN,
+		     CFG_TX_SCH_DELAY_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_UNIT_TEST_FRAMEWORK_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, is_unit_test_framework_enabled,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_UINT_TEST_FRAMEWORK_DEFAULT,
+		     CFG_ENABLE_UNIT_TEST_FRAMEWORK_MIN,
+		     CFG_ENABLE_UNIT_TEST_FRAMEWORK_MAX),
+
+	REG_VARIABLE(CFG_ROAM_FT_OPEN_ENABLE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_ftopen,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ROAM_FT_OPEN_ENABLE_DEFAULT,
+		     CFG_ROAM_FT_OPEN_ENABLE_MIN,
+		     CFG_ROAM_FT_OPEN_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_RTT_MAC_RANDOMIZATION_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, enable_rtt_mac_randomization,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_RTT_MAC_RANDOMIZATION_DEFAULT,
+		     CFG_ENABLE_RTT_MAC_RANDOMIZATION_MIN,
+		     CFG_ENABLE_RTT_MAC_RANDOMIZATION_MAX),
+
+	REG_VARIABLE(CFG_ENABLE_SECONDARY_RATE_NAME,
+		     WLAN_PARAM_HexInteger,
+		     struct hdd_config, enable_secondary_rate,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_SECONDARY_RATE_DEFAULT,
+		     CFG_ENABLE_SECONDARY_RATE_MIN,
+		     CFG_ENABLE_SECONDARY_RATE_MAX),
+
+	REG_VARIABLE(CFG_ROAM_FORCE_RSSI_TRIGGER_NAME,
+		     WLAN_PARAM_Integer, struct hdd_config,
+		     roam_force_rssi_trigger,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ROAM_FORCE_RSSI_TRIGGER_DEFAULT,
+		     CFG_ROAM_FORCE_RSSI_TRIGGER_MIN,
+		     CFG_ROAM_FORCE_RSSI_TRIGGER_MAX),
+
+	REG_VARIABLE(CFG_NUM_VDEV_ENABLE_NAME,
+		     WLAN_PARAM_HexInteger,
+		     struct hdd_config, num_vdevs,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_NUM_VDEV_ENABLE_DEFAULT,
+		     CFG_NUM_VDEV_ENABLE_MIN,
+		     CFG_NUM_VDEV_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_CHANGE_CHANNEL_BANDWIDTH_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, enable_change_channel_bandwidth,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_CHANGE_CHANNEL_BANDWIDTH_DEFAULT,
+		     CFG_CHANGE_CHANNEL_BANDWIDTH_MIN,
+		     CFG_CHANGE_CHANNEL_BANDWIDTH_MAX),
+#ifdef MWS_COEX
+	REG_VARIABLE(CFG_MWS_COEX_4G_QUICK_FTDM_NAME, WLAN_PARAM_HexInteger,
+		     struct hdd_config, mws_coex_4g_quick_tdm,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_MWS_COEX_4G_QUICK_FTDM_DEFAULT,
+		     CFG_MWS_COEX_4G_QUICK_FTDM_MIN,
+		     CFG_MWS_COEX_4G_QUICK_FTDM_MAX),
+	REG_VARIABLE(CFG_MWS_COEX_5G_NR_PWR_LIMIT_NAME, WLAN_PARAM_HexInteger,
+		     struct hdd_config, mws_coex_5g_nr_pwr_limit,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_MWS_COEX_5G_NR_PWR_LIMIT_DEFAULT,
+		     CFG_MWS_COEX_5G_NR_PWR_LIMIT_MIN,
+		     CFG_MWS_COEX_5G_NR_PWR_LIMIT_MAX),
+#endif
+};
+
+
+/**
+ * get_next_line() - find and locate the new line pointer
+ * @str: pointer to string
+ *
+ * This function returns a pointer to the character after the occurrence
+ * of a new line character. It also modifies the original string by replacing
+ * the '\n' character with the null character.
+ *
+ * Return: the pointer to the character at new line,
+ *            or NULL if no new line character was found
+ */
+static char *get_next_line(char *str)
+{
+	char c;
+
+	if (str == NULL || *str == '\0')
+		return NULL;
+
+	c = *str;
+	while (c != '\n' && c != '\0' && c != 0xd) {
+		str = str + 1;
+		c = *str;
+	}
+
+	if (c == '\0')
+		return NULL;
+
+	*str = '\0';
+	return str + 1;
+}
+
+/** look for space. Ascii values to look are
+ * 0x09 == horizontal tab
+ * 0x0a == Newline ("\n")
+ * 0x0b == vertical tab
+ * 0x0c == Newpage or feed form.
+ * 0x0d == carriage return (CR or "\r")
+ * Null ('\0') should not considered as space.
+ */
+#define i_isspace(ch)  (((ch) >= 0x09 && (ch) <= 0x0d) || (ch) == ' ')
+
+/**
+ * i_trim() - trims any leading and trailing white spaces
+ * @str: pointer to string
+ *
+ * Return: the pointer of the string
+ */
+static char *i_trim(char *str)
+{
+	char *ptr;
+
+	if (*str == '\0')
+		return str;
+
+	/* Find the first non white-space */
+	ptr = str;
+	while (i_isspace(*ptr))
+		ptr++;
+
+	if (*ptr == '\0')
+		return str;
+
+	/* This is the new start of the string */
+	str = ptr;
+
+	/* Find the last non white-space */
+	ptr += strlen(ptr) - 1;
+
+	while (ptr != str && i_isspace(*ptr))
+		ptr--;
+
+	/* Null terminate the following character */
+	ptr[1] = '\0';
+
+	return str;
+}
+
+/* Maximum length of the confgiuration name and value */
+#define CFG_VALUE_MAX_LEN 256
+#define CFG_ENTRY_MAX_LEN (32+CFG_VALUE_MAX_LEN)
+
+/**
+ * hdd_cfg_get_config() - get the configuration content
+ * @reg_table: pointer to configuration table
+ * @cRegTableEntries: number of the configuration entries
+ * @ini_struct: pointer to the hdd config knob
+ * @hdd_ctx: pointer to hdd context
+ * @print_fn: print function pointer
+ *
+ * Return: none
+ */
+static void hdd_cfg_get_config(struct reg_table_entry *reg_table,
+			       unsigned long cRegTableEntries,
+			       uint8_t *ini_struct, struct hdd_context *hdd_ctx,
+			       void (*print_fn)(const char *))
+{
+	unsigned int idx;
+	struct reg_table_entry *pRegEntry = reg_table;
+	uint32_t value;
+	char valueStr[CFG_VALUE_MAX_LEN];
+	char config_str[CFG_ENTRY_MAX_LEN];
+	char *fmt;
+	void *pField;
+	struct qdf_mac_addr *pMacAddr;
+	int curlen;
+
+	for (idx = 0; idx < cRegTableEntries; idx++, pRegEntry++) {
+		pField = ini_struct + pRegEntry->VarOffset;
+
+		if ((WLAN_PARAM_Integer == pRegEntry->RegType) ||
+		    (WLAN_PARAM_SignedInteger == pRegEntry->RegType) ||
+		    (WLAN_PARAM_HexInteger == pRegEntry->RegType)) {
+			value = 0;
+
+			if ((pRegEntry->VarSize > sizeof(value)) ||
+			    (pRegEntry->VarSize == 0)) {
+				pr_warn("Invalid length of %s: %d",
+					pRegEntry->RegName, pRegEntry->VarSize);
+				continue;
+			}
+
+			memcpy(&value, pField, pRegEntry->VarSize);
+			if (WLAN_PARAM_HexInteger == pRegEntry->RegType) {
+				fmt = "%x";
+			} else if (WLAN_PARAM_SignedInteger ==
+				   pRegEntry->RegType) {
+				fmt = "%d";
+				value = sign_extend32(
+						value,
+						pRegEntry->VarSize * 8 - 1);
+			} else {
+				fmt = "%u";
+			}
+			snprintf(valueStr, CFG_VALUE_MAX_LEN, fmt, value);
+		} else if (WLAN_PARAM_String == pRegEntry->RegType) {
+			snprintf(valueStr, CFG_VALUE_MAX_LEN, "%s",
+				 (char *)pField);
+		} else if (WLAN_PARAM_MacAddr == pRegEntry->RegType) {
+			pMacAddr = (struct qdf_mac_addr *) pField;
+			snprintf(valueStr, CFG_VALUE_MAX_LEN,
+				 "%02x:%02x:%02x:%02x:%02x:%02x",
+				 pMacAddr->bytes[0],
+				 pMacAddr->bytes[1],
+				 pMacAddr->bytes[2],
+				 pMacAddr->bytes[3],
+				 pMacAddr->bytes[4], pMacAddr->bytes[5]);
+		} else {
+			snprintf(valueStr, CFG_VALUE_MAX_LEN, "(unhandled)");
+		}
+		curlen = scnprintf(config_str, CFG_ENTRY_MAX_LEN,
+				   "%s=%s%s\n",
+				   pRegEntry->RegName,
+				   valueStr,
+				   test_bit(idx,
+					    (void *)&hdd_ctx->config->
+					    bExplicitCfg) ? "*" : "");
+		(*print_fn)(config_str);
+	}
+}
+
+/** struct hdd_cfg_entry - ini configuration entry
+ * @name: name of the entry
+ * @value: value of the entry
+ */
+struct hdd_cfg_entry {
+	char *name;
+	char *value;
+};
+
+/**
+ * find_cfg_item() - find the configuration item
+ * @iniTable: pointer to configuration table
+ * @entries: number fo the configuration entries
+ * @name: the interested configuration to find
+ * @value: the value to read back
+ *
+ * Return: QDF_STATUS_SUCCESS if the interested configuration is found,
+ *		otherwise QDF_STATUS_E_FAILURE
+ */
+static QDF_STATUS find_cfg_item(struct hdd_cfg_entry *iniTable,
+				unsigned long entries,
+				char *name, char **value)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	unsigned long i;
+
+	for (i = 0; i < entries; i++) {
+		if (strcmp(iniTable[i].name, name) == 0) {
+			*value = iniTable[i].value;
+			hdd_debug("Found %s entry for Name=[%s] Value=[%s] ",
+				  WLAN_INI_FILE, name, *value);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	return status;
+}
+
+/**
+ * parse_hex_digit() - conversion to hex value
+ * @c: the character to convert
+ *
+ * Return: the hex value, otherwise 0
+ */
+static int parse_hex_digit(char c)
+{
+	if (c >= '0' && c <= '9')
+		return c - '0';
+	if (c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	if (c >= 'A' && c <= 'F')
+		return c - 'A' + 10;
+
+	return 0;
+}
+
+/**
+ * update_mac_from_string() - convert string to 6 bytes mac address
+ * @hdd_ctx: the pointer to hdd context
+ * @macTable: the macTable to carry the conversion
+ * @num: number of the interface
+ *
+ * 00AA00BB00CC -> 0x00 0xAA 0x00 0xBB 0x00 0xCC
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS update_mac_from_string(struct hdd_context *hdd_ctx,
+					 struct hdd_cfg_entry *macTable,
+					 int num)
+{
+	int i = 0, j = 0, res = 0;
+	char *candidate = NULL;
+	struct qdf_mac_addr macaddr[QDF_MAX_CONCURRENCY_PERSONA];
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	memset(macaddr, 0, sizeof(macaddr));
+
+	for (i = 0; i < num; i++) {
+		candidate = macTable[i].value;
+		for (j = 0; j < QDF_MAC_ADDR_SIZE; j++) {
+			res =
+				hex2bin(&macaddr[i].bytes[j], &candidate[(j << 1)],
+					1);
+			if (res < 0)
+				break;
+		}
+		if (res == 0 && !qdf_is_macaddr_zero(&macaddr[i])) {
+			qdf_mem_copy((uint8_t *) &hdd_ctx->config->
+				     intfMacAddr[i].bytes[0],
+				     (uint8_t *) &macaddr[i].bytes[0],
+				     QDF_MAC_ADDR_SIZE);
+		} else {
+			status = QDF_STATUS_E_FAILURE;
+			break;
+		}
+	}
+	return status;
+}
+
+/**
+ * hdd_apply_cfg_ini() - apply the ini configuration file
+ * @hdd_ctx: the pointer to hdd context
+ * @iniTable: pointer to configuration table
+ * @entries: number fo the configuration entries
+ * It overwrites the MAC address if config file exist.
+ *
+ * Return: QDF_STATUS_SUCCESS if the ini configuration file is correctly parsed,
+ *		otherwise QDF_STATUS_E_INVAL
+ */
+static QDF_STATUS hdd_apply_cfg_ini(struct hdd_context *hdd_ctx,
+				    struct hdd_cfg_entry *iniTable,
+				    unsigned long entries)
+{
+	QDF_STATUS match_status = QDF_STATUS_E_FAILURE;
+	QDF_STATUS ret_status = QDF_STATUS_SUCCESS;
+	unsigned int idx;
+	void *pField;
+	char *value_str = NULL;
+	unsigned long len_value_str;
+	char *candidate;
+	uint32_t value;
+	int32_t svalue;
+	void *pStructBase = hdd_ctx->config;
+	struct reg_table_entry *pRegEntry = g_registry_table;
+	unsigned long cRegTableEntries = QDF_ARRAY_SIZE(g_registry_table);
+	uint32_t cbOutString;
+	int i;
+	int rv;
+
+	BUILD_BUG_ON(MAX_CFG_INI_ITEMS < cRegTableEntries);
+
+	for (idx = 0; idx < cRegTableEntries; idx++, pRegEntry++) {
+		/* Calculate the address of the destination field in the structure. */
+		pField = ((uint8_t *) pStructBase) + pRegEntry->VarOffset;
+
+		match_status =
+			find_cfg_item(iniTable, entries, pRegEntry->RegName,
+				      &value_str);
+
+		if ((match_status != QDF_STATUS_SUCCESS)
+		    && (pRegEntry->Flags & VAR_FLAGS_REQUIRED)) {
+			/* If we could not read the cfg item and it is required, this is an error. */
+			hdd_err("Failed to read required config parameter %s", pRegEntry->RegName);
+			ret_status = QDF_STATUS_E_FAILURE;
+			break;
+		}
+
+		if ((WLAN_PARAM_Integer == pRegEntry->RegType) ||
+		    (WLAN_PARAM_HexInteger == pRegEntry->RegType)) {
+			/* If successfully read from the registry, use the value read.
+			 * If not, use the default value.
+			 */
+			if (match_status == QDF_STATUS_SUCCESS
+			    && (WLAN_PARAM_Integer == pRegEntry->RegType)) {
+				rv = kstrtou32(value_str, 10, &value);
+				if (rv < 0) {
+					hdd_warn("Reg Parameter %s invalid. Enforcing default", pRegEntry->RegName);
+					value = pRegEntry->VarDefault;
+				}
+			} else if (match_status == QDF_STATUS_SUCCESS
+				   && (WLAN_PARAM_HexInteger ==
+				       pRegEntry->RegType)) {
+				rv = kstrtou32(value_str, 16, &value);
+				if (rv < 0) {
+					hdd_warn("Reg parameter %s invalid. Enforcing default", pRegEntry->RegName);
+					value = pRegEntry->VarDefault;
+				}
+			} else {
+				value = pRegEntry->VarDefault;
+			}
+
+			/* Only if the parameter is set in the ini file, do the range check here */
+			if (match_status == QDF_STATUS_SUCCESS &&
+			    pRegEntry->Flags & VAR_FLAGS_RANGE_CHECK) {
+				if (value > pRegEntry->VarMax) {
+					hdd_warn("Reg Parameter %s > allowed Maximum [%u > %lu]. Enforcing Maximum", pRegEntry->RegName,
+					       value, pRegEntry->VarMax);
+					value = pRegEntry->VarMax;
+				}
+
+				if (value < pRegEntry->VarMin) {
+					hdd_warn("Reg Parameter %s < allowed Minimum [%u < %lu]. Enforcing Minimum", pRegEntry->RegName,
+					       value, pRegEntry->VarMin);
+					value = pRegEntry->VarMin;
+				}
+			}
+			/* Only if the parameter is set in the ini file, do the range check here */
+			else if (match_status == QDF_STATUS_SUCCESS &&
+				 pRegEntry->Flags &
+					VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT) {
+				if (value > pRegEntry->VarMax) {
+					hdd_warn("Reg Parameter %s > allowed Maximum [%u > %lu]. Enforcing Default: %lu", pRegEntry->RegName,
+					       value, pRegEntry->VarMax,
+					       pRegEntry->VarDefault);
+					value = pRegEntry->VarDefault;
+				}
+
+				if (value < pRegEntry->VarMin) {
+					hdd_warn("Reg Parameter %s < allowed Minimum [%u < %lu]. Enforcing Default: %lu", pRegEntry->RegName,
+					       value, pRegEntry->VarMin,
+					       pRegEntry->VarDefault);
+					value = pRegEntry->VarDefault;
+				}
+			}
+			/* Move the variable into the output field. */
+			memcpy(pField, &value, pRegEntry->VarSize);
+		} else if (WLAN_PARAM_SignedInteger == pRegEntry->RegType) {
+			/* If successfully read from the registry, use the value read.
+			 * If not, use the default value.
+			 */
+			if (QDF_STATUS_SUCCESS == match_status) {
+				rv = kstrtos32(value_str, 10, &svalue);
+				if (rv < 0) {
+					hdd_warn("Reg Parameter %s invalid. Enforcing Default", pRegEntry->RegName);
+					svalue =
+						(int32_t) pRegEntry->VarDefault;
+				}
+			} else {
+				svalue = (int32_t) pRegEntry->VarDefault;
+			}
+
+			/* Only if the parameter is set in the ini file, do the range check here */
+			if (match_status == QDF_STATUS_SUCCESS &&
+			    pRegEntry->Flags & VAR_FLAGS_RANGE_CHECK) {
+				if (svalue > (int32_t) pRegEntry->VarMax) {
+					hdd_warn("Reg Parameter %s > allowed Maximum "
+					       "[%d > %d]. Enforcing Maximum", pRegEntry->RegName,
+					       svalue, (int)pRegEntry->VarMax);
+					svalue = (int32_t) pRegEntry->VarMax;
+				}
+
+				if (svalue < (int32_t) pRegEntry->VarMin) {
+					hdd_warn("Reg Parameter %s < allowed Minimum "
+					       "[%d < %d]. Enforcing Minimum", pRegEntry->RegName,
+					       svalue, (int)pRegEntry->VarMin);
+					svalue = (int32_t) pRegEntry->VarMin;
+				}
+			}
+			/* Only if the parameter is set in the ini file, do the range check here */
+			else if (match_status == QDF_STATUS_SUCCESS &&
+				 pRegEntry->Flags &
+					VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT) {
+				if (svalue > (int32_t) pRegEntry->VarMax) {
+					hdd_warn("Reg Parameter %s > allowed Maximum "
+					       "[%d > %d]. Enforcing Default: %d", pRegEntry->RegName,
+					       svalue, (int)pRegEntry->VarMax,
+					       (int)pRegEntry->VarDefault);
+					svalue =
+						(int32_t) pRegEntry->VarDefault;
+				}
+
+				if (svalue < (int32_t) pRegEntry->VarMin) {
+					hdd_warn("Reg Parameter %s < allowed Minimum "
+					       "[%d < %d]. Enforcing Default: %d", pRegEntry->RegName,
+					       svalue, (int)pRegEntry->VarMin,
+					       (int)pRegEntry->VarDefault);
+					svalue = pRegEntry->VarDefault;
+				}
+			}
+			/* Move the variable into the output field. */
+			memcpy(pField, &svalue, pRegEntry->VarSize);
+		}
+		/* Handle string parameters */
+		else if (WLAN_PARAM_String == pRegEntry->RegType) {
+#ifdef WLAN_CFG_DEBUG
+			hdd_debug("RegName = %s, VarOffset %u VarSize %u VarDefault %s",
+				  pRegEntry->RegName, pRegEntry->VarOffset,
+				  pRegEntry->VarSize,
+				  (char *)pRegEntry->VarDefault);
+#endif
+
+			if (match_status == QDF_STATUS_SUCCESS) {
+				len_value_str = strlen(value_str);
+
+				if (len_value_str > (pRegEntry->VarSize - 1)) {
+					hdd_err("Invalid Value=[%s] specified for Name=[%s] in %s", value_str,
+					       pRegEntry->RegName,
+					       WLAN_INI_FILE);
+					cbOutString =
+						QDF_MIN(strlen
+							 ((char *)pRegEntry->
+								 VarDefault),
+							 pRegEntry->VarSize - 1);
+					memcpy(pField,
+					       (void *)(pRegEntry->VarDefault),
+					       cbOutString);
+					((uint8_t *) pField)[cbOutString] =
+						'\0';
+				} else {
+					memcpy(pField, (void *)(value_str),
+					       len_value_str);
+					((uint8_t *) pField)[len_value_str] =
+						'\0';
+				}
+			} else {
+				/* Failed to read the string parameter from the registry.  Use the default. */
+				cbOutString =
+					QDF_MIN(strlen((char *)pRegEntry->VarDefault),
+						 pRegEntry->VarSize - 1);
+				memcpy(pField, (void *)(pRegEntry->VarDefault),
+				       cbOutString);
+				((uint8_t *) pField)[cbOutString] = '\0';
+			}
+		} else if (WLAN_PARAM_MacAddr == pRegEntry->RegType) {
+			if (pRegEntry->VarSize != QDF_MAC_ADDR_SIZE) {
+				hdd_warn("Invalid VarSize %u for Name=[%s]", pRegEntry->VarSize,
+				       pRegEntry->RegName);
+				continue;
+			}
+			candidate = (char *)pRegEntry->VarDefault;
+			if (match_status == QDF_STATUS_SUCCESS) {
+				len_value_str = strlen(value_str);
+				if (len_value_str != (QDF_MAC_ADDR_SIZE * 2)) {
+					hdd_err("Invalid MAC addr [%s] specified for Name=[%s] in %s", value_str,
+					       pRegEntry->RegName,
+					       WLAN_INI_FILE);
+				} else
+					candidate = value_str;
+			}
+			/* parse the string and store it in the byte array */
+			for (i = 0; i < QDF_MAC_ADDR_SIZE; i++) {
+				((char *)pField)[i] =
+					(char)(parse_hex_digit(candidate[i * 2]) *
+					       16 +
+					       parse_hex_digit(candidate[i * 2 + 1]));
+			}
+		} else {
+			hdd_warn("Unknown param type for name[%s] in registry table", pRegEntry->RegName);
+		}
+
+		/* did we successfully parse a cfg item for this parameter? */
+		if ((match_status == QDF_STATUS_SUCCESS) &&
+		    (idx < MAX_CFG_INI_ITEMS)) {
+			set_bit(idx, (void *)&hdd_ctx->config->bExplicitCfg);
+		}
+	}
+
+	return ret_status;
+}
+
+/**
+ * hdd_execute_config_command() - executes an arbitrary configuration command
+ * @reg_table: the pointer to configuration table
+ * @tableSize: the size of the configuration table
+ * @ini_struct: pointer to the hdd config knob
+ * @hdd_ctx: the pointer to hdd context
+ * @command: the command to run
+ *
+ * Return: QDF_STATUS_SUCCESS if the command is found and able to execute,
+ *		otherwise the appropriate QDF_STATUS will be returned
+ */
+static QDF_STATUS hdd_execute_config_command(struct reg_table_entry *reg_table,
+					     unsigned long tableSize,
+					     uint8_t *ini_struct,
+					     struct hdd_context *hdd_ctx,
+					     char *command)
+{
+	struct reg_table_entry *pRegEntry;
+	char *clone;
+	char *pCmd;
+	void *pField;
+	char *name;
+	char *value_str;
+	uint32_t value;
+	int32_t svalue;
+	size_t len_value_str;
+	unsigned int idx;
+	unsigned int i;
+	QDF_STATUS vstatus;
+	int rv;
+
+	/* assume failure until proven otherwise */
+	vstatus = QDF_STATUS_E_FAILURE;
+
+	/* clone the command so that we can manipulate it */
+	clone = kstrdup(command, GFP_ATOMIC);
+	if (NULL == clone)
+		return vstatus;
+
+	/* 'clone' will point to the beginning of the string so it can be freed
+	 * 'pCmd' will be used to walk/parse the command
+	 */
+	pCmd = clone;
+
+	/* get rid of leading/trailing whitespace */
+	pCmd = i_trim(pCmd);
+	if ('\0' == *pCmd) {
+		/* only whitespace */
+		hdd_err("invalid command, only whitespace:[%s]", command);
+		goto done;
+	}
+	/* parse the <name> = <value> */
+	name = pCmd;
+	while (('=' != *pCmd) && ('\0' != *pCmd))
+		pCmd++;
+
+	if ('\0' == *pCmd) {
+		/* did not find '=' */
+		hdd_err("invalid command, no '=':[%s]", command);
+		goto done;
+	}
+	/* replace '=' with NUL to terminate the <name> */
+	*pCmd++ = '\0';
+	name = i_trim(name);
+	if ('\0' == *name) {
+		/* did not find a name */
+		hdd_err("invalid command, no <name>:[%s]", command);
+		goto done;
+	}
+
+	value_str = i_trim(pCmd);
+	if ('\0' == *value_str) {
+		/* did not find a value */
+		hdd_err("invalid command, no <value>:[%s]", command);
+		goto done;
+	}
+	/* lookup the configuration item */
+	for (idx = 0; idx < tableSize; idx++) {
+		if (0 == strcmp(name, reg_table[idx].RegName)) {
+			/* found a match */
+			break;
+		}
+	}
+	if (tableSize == idx) {
+		/* did not match the name */
+		hdd_err("invalid command, unknown configuration item:[%s]", command);
+		goto done;
+	}
+
+	pRegEntry = &reg_table[idx];
+	if (!(pRegEntry->Flags & VAR_FLAGS_DYNAMIC_CFG)) {
+		/* does not support dynamic configuration */
+		hdd_err("Global_Registry_Table. %s does not support "
+		       "dynamic configuration", name);
+		vstatus = QDF_STATUS_E_PERM;
+		goto done;
+	}
+
+	pField = ini_struct + pRegEntry->VarOffset;
+
+	switch (pRegEntry->RegType) {
+	case WLAN_PARAM_Integer:
+		rv = kstrtou32(value_str, 10, &value);
+		if (rv < 0)
+			goto done;
+		if (value < pRegEntry->VarMin) {
+			/* out of range */
+			hdd_err("Invalid command, value %u < min value %lu", value, pRegEntry->VarMin);
+			goto done;
+		}
+		if (value > pRegEntry->VarMax) {
+			/* out of range */
+			hdd_err("Invalid command, value %u > max value %lu", value, pRegEntry->VarMax);
+			goto done;
+		}
+		memcpy(pField, &value, pRegEntry->VarSize);
+		break;
+
+	case WLAN_PARAM_HexInteger:
+		rv = kstrtou32(value_str, 16, &value);
+		if (rv < 0)
+			goto done;
+		if (value < pRegEntry->VarMin) {
+			/* out of range */
+			hdd_err("Invalid command, value %x < min value %lx", value, pRegEntry->VarMin);
+			goto done;
+		}
+		if (value > pRegEntry->VarMax) {
+			/* out of range */
+			hdd_err("Invalid command, value %x > max value %lx", value, pRegEntry->VarMax);
+			goto done;
+		}
+		memcpy(pField, &value, pRegEntry->VarSize);
+		break;
+
+	case WLAN_PARAM_SignedInteger:
+		rv = kstrtos32(value_str, 10, &svalue);
+		if (rv < 0)
+			goto done;
+		if (svalue < (int32_t) pRegEntry->VarMin) {
+			/* out of range */
+			hdd_err("Invalid command, value %d < min value %d", svalue, (int)pRegEntry->VarMin);
+			goto done;
+		}
+		if (svalue > (int32_t) pRegEntry->VarMax) {
+			/* out of range */
+			hdd_err("Invalid command, value %d > max value %d", svalue, (int)pRegEntry->VarMax);
+			goto done;
+		}
+		memcpy(pField, &svalue, pRegEntry->VarSize);
+		break;
+
+	case WLAN_PARAM_String:
+		len_value_str = strlen(value_str);
+		if (len_value_str > (pRegEntry->VarSize - 1)) {
+			/* too big */
+			hdd_err("Invalid command, string [%s] length "
+			       "%zu exceeds maximum length %u", value_str,
+			       len_value_str, (pRegEntry->VarSize - 1));
+			goto done;
+		}
+		/* copy string plus NUL */
+		memcpy(pField, value_str, (len_value_str + 1));
+		break;
+
+	case WLAN_PARAM_MacAddr:
+		len_value_str = strlen(value_str);
+		if (len_value_str != (QDF_MAC_ADDR_SIZE * 2)) {
+			/* out of range */
+			hdd_err("Invalid command, MAC address [%s] length "
+			       "%zu is not expected length %u", value_str,
+			       len_value_str, (QDF_MAC_ADDR_SIZE * 2));
+			goto done;
+		}
+		/* parse the string and store it in the byte array */
+		for (i = 0; i < QDF_MAC_ADDR_SIZE; i++) {
+			((char *)pField)[i] = (char)
+					      ((parse_hex_digit(value_str[(i * 2)]) * 16) +
+					       parse_hex_digit(value_str[(i * 2) + 1]));
+		}
+		break;
+
+	default:
+		goto done;
+	}
+
+	/* if we get here, we had a successful modification */
+	vstatus = QDF_STATUS_SUCCESS;
+
+	/* config table has been modified, is there a notifier? */
+	if (NULL != pRegEntry->pfnDynamicnotify)
+		(pRegEntry->pfnDynamicnotify)(hdd_ctx, pRegEntry->notifyId);
+
+	/* note that this item was explicitly configured */
+	if (idx < MAX_CFG_INI_ITEMS)
+		set_bit(idx, (void *)&hdd_ctx->config->bExplicitCfg);
+
+done:
+	kfree(clone);
+	return vstatus;
+}
+
+/**
+ * hdd_set_power_save_offload_config() - set power save offload configuration
+ * @hdd_ctx: the pointer to hdd context
+ *
+ * Return: none
+ */
+static void hdd_set_power_save_offload_config(struct hdd_context *hdd_ctx)
+{
+	struct hdd_config *pConfig = hdd_ctx->config;
+	uint32_t listenInterval = 0;
+
+	if (strcmp(pConfig->PowerUsageControl, "Min") == 0)
+		listenInterval = pConfig->nBmpsMinListenInterval;
+	else if (strcmp(pConfig->PowerUsageControl, "Max") == 0)
+		listenInterval = pConfig->nBmpsMaxListenInterval;
+
+	/*
+	 * Based on Mode Set the LI
+	 * Otherwise default LI value of 1 will
+	 * be taken
+	 */
+	if (listenInterval) {
+		/*
+		 * setcfg for listenInterval.
+		 * Make sure CFG is updated because PE reads this
+		 * from CFG at the time of assoc or reassoc
+		 */
+		ucfg_mlme_set_sap_listen_interval(hdd_ctx->psoc,
+						  listenInterval);
+	}
+}
+
+/**
+ * hdd_update_mac_config() - update MAC address from cfg file
+ * @hdd_ctx: the pointer to hdd context
+ *
+ * It overwrites the MAC address if config file exist.
+ *
+ * Return: QDF_STATUS_SUCCESS if the MAC address is found from cfg file
+ *      and overwritten, otherwise QDF_STATUS_E_INVAL
+ */
+QDF_STATUS hdd_update_mac_config(struct hdd_context *hdd_ctx)
+{
+	int status, i = 0;
+	const struct firmware *fw = NULL;
+	char *line, *buffer = NULL;
+	char *temp = NULL;
+	char *name, *value;
+	int max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
+	struct hdd_cfg_entry macTable[QDF_MAX_CONCURRENCY_PERSONA];
+	tSirMacAddr customMacAddr;
+
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	memset(macTable, 0, sizeof(macTable));
+	status = request_firmware(&fw, WLAN_MAC_FILE, hdd_ctx->parent_dev);
+	if (status) {
+		/*
+		 * request_firmware "fails" if the file is not found, which is a
+		 * valid setup for us, so log using debug instead of error
+		 */
+		hdd_debug("request_firmware failed; status:%d", status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!fw || !fw->data || !fw->size) {
+		hdd_alert("invalid firmware");
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto config_exit;
+	}
+
+	hdd_debug("wlan_mac.bin size %zu", fw->size);
+
+	temp = qdf_mem_malloc(fw->size + 1);
+
+	if (temp == NULL) {
+		hdd_err("fail to alloc memory");
+		qdf_status = QDF_STATUS_E_NOMEM;
+		goto config_exit;
+	}
+	buffer = temp;
+	qdf_mem_copy(buffer, fw->data, fw->size);
+	buffer[fw->size] = 0x0;
+
+	/* data format:
+	 * Intf0MacAddress=00AA00BB00CC
+	 * Intf1MacAddress=00AA00BB00CD
+	 * END
+	 */
+	while (buffer != NULL) {
+		line = get_next_line(buffer);
+		buffer = i_trim(buffer);
+
+		if (strlen((char *)buffer) == 0 || *buffer == '#') {
+			buffer = line;
+			continue;
+		}
+		if (strncmp(buffer, "END", 3) == 0)
+			break;
+
+		name = buffer;
+		buffer = strnchr(buffer, strlen(buffer), '=');
+		if (buffer) {
+			*buffer++ = '\0';
+			i_trim(name);
+			if (strlen(name) != 0) {
+				buffer = i_trim(buffer);
+				if (strlen(buffer) == 12) {
+					value = buffer;
+					macTable[i].name = name;
+					macTable[i++].value = value;
+					if (i >= QDF_MAX_CONCURRENCY_PERSONA)
+						break;
+				}
+			}
+		}
+		buffer = line;
+	}
+
+	if (i != 0 && i <= QDF_MAX_CONCURRENCY_PERSONA) {
+		hdd_debug("%d Mac addresses provided", i);
+	} else {
+		hdd_err("invalid number of Mac address provided, nMac = %d", i);
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto config_exit;
+	}
+
+	qdf_status = update_mac_from_string(hdd_ctx, &macTable[0], i);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		hdd_err("Invalid MAC addresses provided");
+		goto config_exit;
+	}
+	hdd_debug("Populating remaining %d Mac addresses",
+		   max_mac_addr - i);
+	hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr - i);
+
+	qdf_mem_copy(&customMacAddr,
+		     &hdd_ctx->config->intfMacAddr[0].bytes[0],
+		     sizeof(tSirMacAddr));
+	sme_set_custom_mac_addr(customMacAddr);
+
+config_exit:
+	qdf_mem_free(temp);
+	release_firmware(fw);
+	return qdf_status;
+}
+
+/**
+ * hdd_disable_runtime_pm() - Override to disable runtime_pm.
+ * @cfg_ini: Handle to struct hdd_config
+ *
+ * Return: None
+ */
+#ifdef FEATURE_RUNTIME_PM
+static void hdd_disable_runtime_pm(struct hdd_config *cfg_ini)
+{
+	cfg_ini->runtime_pm = 0;
+}
+#else
+static void hdd_disable_runtime_pm(struct hdd_config *cfg_ini)
+{
+}
+#endif
+
+/**
+ * hdd_disable_auto_shutdown() - Override to disable auto_shutdown.
+ * @cfg_ini: Handle to struct hdd_config
+ *
+ * Return: None
+ */
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+static void hdd_disable_auto_shutdown(struct hdd_config *cfg_ini)
+{
+	cfg_ini->wlan_auto_shutdown = 0;
+}
+#else
+static void hdd_disable_auto_shutdown(struct hdd_config *cfg_ini)
+{
+}
+#endif
+
+/**
+ * hdd_override_all_ps() - overrides to disables all the powersave features.
+ * @hdd_ctx: Pointer to HDD context.
+ * Overrides below powersave ini configurations.
+ * gEnableImps=0
+ * gEnableBmps=0
+ * gRuntimePM=0
+ * gWlanAutoShutdown = 0
+ * gEnableSuspend=0
+ * gEnablePowerSaveOffload=0
+ * gEnableWoW=0
+ *
+ * Return: None
+ */
+static void hdd_override_all_ps(struct hdd_context *hdd_ctx)
+{
+	struct hdd_config *cfg_ini = hdd_ctx->config;
+
+	cfg_ini->fIsImpsEnabled = 0;
+	cfg_ini->is_ps_enabled = 0;
+	hdd_disable_runtime_pm(cfg_ini);
+	hdd_disable_auto_shutdown(cfg_ini);
+}
+
+/**
+ * hdd_parse_config_ini() - parse the ini configuration file
+ * @hdd_ctx: the pointer to hdd context
+ *
+ * This function reads the qcom_cfg.ini file and
+ * parses each 'Name=Value' pair in the ini file
+ *
+ * Return: QDF_STATUS_SUCCESS if the qcom_cfg.ini is correctly read,
+ *		otherwise QDF_STATUS_E_INVAL
+ */
+QDF_STATUS hdd_parse_config_ini(struct hdd_context *hdd_ctx)
+{
+	int status = 0;
+	int i = 0;
+	int retry = 0;
+	/** Pointer for firmware image data */
+	const struct firmware *fw = NULL;
+	char *buffer, *line, *pTemp = NULL;
+	size_t size;
+	char *name, *value;
+	struct hdd_cfg_entry *cfg_ini_table;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	size = MAX_CFG_INI_ITEMS * sizeof(*cfg_ini_table);
+	cfg_ini_table = qdf_mem_malloc(size);
+
+	if (!cfg_ini_table) {
+		hdd_err("Failed to alloc %zu bytes for cfg_ini_table", size);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	do {
+		if (status == -EAGAIN)
+			msleep(HDD_CFG_REQUEST_FIRMWARE_DELAY);
+
+		status = request_firmware(&fw, WLAN_INI_FILE,
+					  hdd_ctx->parent_dev);
+
+		retry++;
+	} while ((retry < HDD_CFG_REQUEST_FIRMWARE_RETRIES) &&
+		 (status == -EAGAIN));
+
+	if (status) {
+		hdd_alert("request_firmware failed %d", status);
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto config_exit;
+	}
+	if (!fw || !fw->data || !fw->size) {
+		hdd_alert("%s download failed", WLAN_INI_FILE);
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto config_exit;
+	}
+
+	hdd_debug("qcom_cfg.ini Size %zu", fw->size);
+
+	buffer = (char *)qdf_mem_malloc(fw->size);
+
+	if (NULL == buffer) {
+		hdd_err("qdf_mem_malloc failure");
+		qdf_status = QDF_STATUS_E_NOMEM;
+		goto config_exit;
+	}
+	pTemp = buffer;
+
+	qdf_mem_copy((void *)buffer, (void *)fw->data, fw->size);
+	size = fw->size;
+
+	while (buffer != NULL) {
+		line = get_next_line(buffer);
+		buffer = i_trim(buffer);
+
+		hdd_debug("%s: item", buffer);
+
+		if (strlen((char *)buffer) == 0 || *buffer == '#') {
+			buffer = line;
+			continue;
+		}
+
+		if (strncmp(buffer, "END", 3) == 0)
+			break;
+
+		name = buffer;
+		while (*buffer != '=' && *buffer != '\0')
+			buffer++;
+		if (*buffer != '\0') {
+			*buffer++ = '\0';
+			i_trim(name);
+			if (strlen(name) != 0) {
+				buffer = i_trim(buffer);
+				if (strlen(buffer) > 0) {
+					value = buffer;
+					while (*buffer != '\0')
+						buffer++;
+					*buffer = '\0';
+					cfg_ini_table[i].name = name;
+					cfg_ini_table[i++].value = value;
+					if (i >= MAX_CFG_INI_ITEMS) {
+						hdd_err("Number of items in %s > %d",
+							WLAN_INI_FILE,
+							MAX_CFG_INI_ITEMS);
+						break;
+					}
+				}
+			}
+		}
+		buffer = line;
+	}
+
+	/* Loop through the registry table and apply all these configs */
+	qdf_status = hdd_apply_cfg_ini(hdd_ctx, cfg_ini_table, i);
+	if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
+		hdd_override_all_ps(hdd_ctx);
+
+config_exit:
+	release_firmware(fw);
+	qdf_mem_free(pTemp);
+	qdf_mem_free(cfg_ini_table);
+	return qdf_status;
+}
+
+/**
+ * hdd_cfg_xlate_to_csr_phy_mode() - convert PHY mode
+ * @dot11Mode: the mode to convert
+ *
+ * Convert the configuration PHY mode to CSR PHY mode
+ *
+ * Return: the CSR phy mode value
+ */
+eCsrPhyMode hdd_cfg_xlate_to_csr_phy_mode(enum hdd_dot11_mode dot11Mode)
+{
+	if (cds_is_sub_20_mhz_enabled())
+		return eCSR_DOT11_MODE_abg;
+
+	switch (dot11Mode) {
+	case (eHDD_DOT11_MODE_abg):
+		return eCSR_DOT11_MODE_abg;
+	case (eHDD_DOT11_MODE_11b):
+		return eCSR_DOT11_MODE_11b;
+	case (eHDD_DOT11_MODE_11g):
+		return eCSR_DOT11_MODE_11g;
+	default:
+	case (eHDD_DOT11_MODE_11n):
+		return eCSR_DOT11_MODE_11n;
+	case (eHDD_DOT11_MODE_11g_ONLY):
+		return eCSR_DOT11_MODE_11g_ONLY;
+	case (eHDD_DOT11_MODE_11n_ONLY):
+		return eCSR_DOT11_MODE_11n_ONLY;
+	case (eHDD_DOT11_MODE_11b_ONLY):
+		return eCSR_DOT11_MODE_11b_ONLY;
+	case (eHDD_DOT11_MODE_11ac_ONLY):
+		return eCSR_DOT11_MODE_11ac_ONLY;
+	case (eHDD_DOT11_MODE_11ac):
+		return eCSR_DOT11_MODE_11ac;
+	case (eHDD_DOT11_MODE_AUTO):
+		return eCSR_DOT11_MODE_AUTO;
+	case (eHDD_DOT11_MODE_11a):
+		return eCSR_DOT11_MODE_11a;
+	case (eHDD_DOT11_MODE_11ax_ONLY):
+		return eCSR_DOT11_MODE_11ax_ONLY;
+	case (eHDD_DOT11_MODE_11ax):
+		return eCSR_DOT11_MODE_11ax;
+	}
+
+}
+
+/**
+ * hdd_set_idle_ps_config() - set idle power save configuration
+ * @hdd_ctx: the pointer to hdd context
+ * @val: the value to configure
+ *
+ * Return: QDF_STATUS_SUCCESS if command set correctly,
+ *		otherwise the QDF_STATUS return from SME layer
+ */
+QDF_STATUS hdd_set_idle_ps_config(struct hdd_context *hdd_ctx, bool val)
+{
+	QDF_STATUS status;
+
+	hdd_debug("Enter Val %d", val);
+
+	if (hdd_ctx->imps_enabled == val) {
+		hdd_info("Already in the requested power state:%d", val);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	status = sme_set_idle_powersave_config(val);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Fail to Set Idle PS Config val %d", val);
+		return status;
+	}
+
+	hdd_ctx->imps_enabled = val;
+
+	return status;
+}
+
+/**
+ * hdd_set_fine_time_meas_cap() - set fine timing measurement capability
+ * @hdd_ctx: HDD context
+ *
+ * This function is used to pass fine timing measurement capability coming
+ * from INI to SME. This function make sure that configure INI is supported
+ * by the device. Use bit mask to mask out the unsupported capabilities.
+ *
+ * Return: None
+ */
+static void hdd_set_fine_time_meas_cap(struct hdd_context *hdd_ctx)
+{
+	struct hdd_config *config = hdd_ctx->config;
+	uint32_t capability = config->fine_time_meas_cap;
+
+	/* Make sure only supported capabilities are enabled in INI */
+	capability &= CFG_FINE_TIME_MEAS_CAPABILITY_MAX;
+	ucfg_wifi_pos_set_ftm_cap(hdd_ctx->psoc, capability);
+
+	hdd_debug("fine time meas capability - INI: %04x Enabled: %04x",
+		config->fine_time_meas_cap,
+		capability);
+}
+
+/**
+ * hdd_convert_string_to_u8_array() - used to convert string into u8 array
+ * @str: String to be converted
+ * @hex_array: Array where converted value is stored
+ * @len: Length of the populated array
+ * @array_max_len: Maximum length of the array
+ * @to_hex: true, if conversion required for hex string
+ *
+ * This API is called to convert string (each byte separated by
+ * a comma) into an u8 array
+ *
+ * Return: QDF_STATUS
+ */
+
+static QDF_STATUS hdd_convert_string_to_array(char *str, uint8_t *array,
+			     uint8_t *len, uint16_t array_max_len, bool to_hex)
+{
+	char *format, *s = str;
+
+	if (str == NULL || array == NULL || len == NULL)
+		return QDF_STATUS_E_INVAL;
+
+	format = (to_hex) ? "%02x" : "%d";
+
+	*len = 0;
+	while ((s != NULL) && (*len < array_max_len)) {
+		int val;
+		/* Increment length only if sscanf successfully extracted
+		 * one element. Any other return value means error.
+		 * Ignore it.
+		 */
+		if (sscanf(s, format, &val) == 1) {
+			array[*len] = (uint8_t) val;
+			*len += 1;
+		}
+
+		s = strpbrk(s, ",");
+		if (s)
+			s++;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_hex_string_to_u8_array() - used to convert hex string into u8 array
+ * @str: Hexadecimal string
+ * @hex_array: Array where converted value is stored
+ * @len: Length of the populated array
+ * @array_max_len: Maximum length of the array
+ *
+ * This API is called to convert hexadecimal string (each byte separated by
+ * a comma) into an u8 array
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS hdd_hex_string_to_u8_array(char *str, uint8_t *hex_array,
+					     uint8_t *len,
+					     uint8_t array_max_len)
+{
+	return hdd_convert_string_to_array(str, hex_array, len,
+					   array_max_len, true);
+}
+
+QDF_STATUS hdd_string_to_u8_array(char *str, uint8_t *array,
+				  uint8_t *len, uint16_t array_max_len)
+{
+	return hdd_convert_string_to_array(str, array, len,
+					   array_max_len, false);
+}
+
+/**
+ * hdd_hex_string_to_u16_array() - convert a hex string to a uint16 array
+ * @str: input string
+ * @int_array: pointer to input array of type uint16
+ * @len: pointer to number of elements which the function adds to the array
+ * @int_array_max_len: maximum number of elements in input uint16 array
+ *
+ * This function is used to convert a space separated hex string to an array of
+ * uint16_t. For example, an input string str = "a b c d" would be converted to
+ * a unint16 array, int_array = {0xa, 0xb, 0xc, 0xd}, *len = 4.
+ * This assumes that input value int_array_max_len >= 4.
+ *
+ * Return: QDF_STATUS_SUCCESS - if the conversion is successful
+ *         non zero value     - if the conversion is a failure
+ */
+QDF_STATUS hdd_hex_string_to_u16_array(char *str,
+		uint16_t *int_array, uint8_t *len, uint8_t int_array_max_len)
+{
+	char *s = str;
+	uint32_t val = 0;
+
+	if (str == NULL || int_array == NULL || len == NULL)
+		return QDF_STATUS_E_INVAL;
+
+	hdd_debug("str %pK intArray %pK intArrayMaxLen %d",
+		s, int_array, int_array_max_len);
+
+	*len = 0;
+
+	while ((s != NULL) && (*len < int_array_max_len)) {
+		/*
+		 * Increment length only if sscanf successfully extracted one
+		 * element. Any other return value means error. Ignore it.
+		 */
+		if (sscanf(s, "%x", &val) == 1) {
+			int_array[*len] = (uint16_t) val;
+			hdd_debug("s %pK val %x intArray[%d]=0x%x",
+				s, val, *len, int_array[*len]);
+			*len += 1;
+		}
+		s = strpbrk(s, " ");
+		if (s)
+			s++;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_update_config_cfg() - API to update INI setting based on hw/fw caps
+ * @hdd_ctx: pointer to hdd_ctx
+ *
+ * This API reads the cfg file which is updated with hardware/firmware
+ * capabilities and intersect it with INI setting provided by user. After
+ * taking intersection it adjust cfg it self. For example, if user has enabled
+ * RX LDPC through INI but hardware/firmware doesn't support it then disable
+ * it in CFG file here.
+ *
+ * Return: true or false based on outcome.
+ */
+bool hdd_update_config_cfg(struct hdd_context *hdd_ctx)
+{
+	bool status = true;
+	struct hdd_config *config = hdd_ctx->config;
+	mac_handle_t mac_handle;
+	uint8_t mcc_adaptive_sch = 0;
+
+	/*
+	 * During the initialization both 2G and 5G capabilities should be same.
+	 * So read 5G HT capablity and update 2G and 5G capablities.
+	 */
+
+	if (0 != hdd_update_he_cap_in_cfg(hdd_ctx)) {
+		status = false;
+		hdd_err("Couldn't set HE CAP in cfg");
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	if (sme_cfg_set_int(mac_handle,
+				WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
+				config->nPassiveMaxChnTime)
+				== QDF_STATUS_E_FAILURE) {
+		status = false;
+		hdd_err("Couldn't pass on WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME to CFG");
+	}
+
+	if (sme_cfg_set_int(mac_handle,
+		WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT,
+		config->wow_data_inactivity_timeout) == QDF_STATUS_E_FAILURE) {
+		status = false;
+		hdd_err("Fail to pass WNI_CFG_PS_WOW_DATA_INACTIVITY_TO CFG");
+	}
+
+	if (sme_cfg_set_int(mac_handle, WNI_CFG_11D_ENABLED,
+		     config->Is11dSupportEnabled) == QDF_STATUS_E_FAILURE) {
+		status = false;
+		hdd_err("Couldn't pass on WNI_CFG_11D_ENABLED to CFG");
+	}
+
+	if (sme_cfg_set_int(mac_handle, WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP,
+		    config->disableLDPCWithTxbfAP) == QDF_STATUS_E_FAILURE) {
+		status = false;
+		hdd_err("Couldn't pass on WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP to CFG");
+	}
+
+	if (sme_cfg_set_int(mac_handle, WNI_CFG_IBSS_ATIM_WIN_SIZE,
+			    config->ibssATIMWinSize) ==
+			QDF_STATUS_E_FAILURE) {
+		status = false;
+		hdd_err("Couldn't pass on WNI_CFG_IBSS_ATIM_WIN_SIZE to CFG");
+	}
+
+	ucfg_policy_mgr_get_mcc_adaptive_sch(hdd_ctx->psoc,
+					     &mcc_adaptive_sch);
+	if (sme_cfg_set_int(mac_handle, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED,
+			    mcc_adaptive_sch) == QDF_STATUS_E_FAILURE) {
+		status = false;
+		hdd_err("Couldn't pass on WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED to CFG");
+	}
+	return status;
+}
+
+/**
+ * hdd_set_policy_mgr_user_cfg() -initializes the policy manager
+ * configuration parameters
+ *
+ * @hdd_ctx: the pointer to hdd context
+ *
+ * Return: QDF_STATUS_SUCCESS if configuration is correctly applied,
+ *		otherwise the appropriate QDF_STATUS would be returned
+ */
+QDF_STATUS hdd_set_policy_mgr_user_cfg(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	struct policy_mgr_user_cfg *user_cfg;
+
+	user_cfg = qdf_mem_malloc(sizeof(*user_cfg));
+	if (NULL == user_cfg) {
+		hdd_err("unable to allocate user_cfg");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc,
+					     &user_cfg->enable2x2);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+
+	user_cfg->sub_20_mhz_enabled = cds_is_sub_20_mhz_enabled();
+	user_cfg->is_sta_sap_scc_allowed_on_dfs_chan =
+		hdd_ctx->config->sta_sap_scc_on_dfs_chan;
+	user_cfg->sta_sap_scc_on_lte_coex_chan =
+		hdd_ctx->config->sta_sap_scc_on_lte_coex_chan;
+	status = policy_mgr_set_user_cfg(hdd_ctx->psoc, user_cfg);
+	qdf_mem_free(user_cfg);
+
+	return status;
+}
+
+eCsrRoamWmmUserModeType hdd_to_csr_wmm_mode(uint8_t 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_update_11k_offload_params() - initializes the 11k offload related params
+ *
+ * @config: pointer to hdd_config structure
+ * @csr_config: pointer to the csr config structure
+ *
+ * Return: None
+ */
+static
+void hdd_update_11k_offload_params(struct hdd_config *config,
+				tCsrConfigParam *csr_config)
+{
+	csr_config->offload_11k_enable_bitmask =
+		config->offload_11k_enable_bitmask;
+	csr_config->neighbor_report_offload.params_bitmask =
+		config->neighbor_report_offload_params_bitmask;
+	csr_config->neighbor_report_offload.time_offset =
+		config->neighbor_report_offload_time_offset;
+	csr_config->neighbor_report_offload.low_rssi_offset =
+		config->neighbor_report_offload_low_rssi_offset;
+	csr_config->neighbor_report_offload.bmiss_count_trigger =
+		config->neighbor_report_offload_bmiss_count_trigger;
+	csr_config->neighbor_report_offload.per_threshold_offset =
+		config->neighbor_report_offload_per_threshold_offset;
+	csr_config->neighbor_report_offload.neighbor_report_cache_timeout =
+		config->neighbor_report_offload_cache_timeout;
+	csr_config->neighbor_report_offload.max_neighbor_report_req_cap =
+		config->neighbor_report_offload_max_req_cap;
+}
+
+static
+QDF_STATUS hdd_set_sme_cfgs_related_to_plcy_mgr(struct hdd_context *hdd_ctx,
+						tSmeConfigParams *sme_cfg)
+{
+	uint8_t mcc_to_scc_switch = 0;
+	uint8_t conc_rule1 = 0, conc_rule2 = 0, sta_cxn_5g = 0;
+
+	if (QDF_STATUS_SUCCESS !=
+	    ucfg_policy_mgr_get_mcc_scc_switch(hdd_ctx->psoc,
+					       &mcc_to_scc_switch)) {
+		hdd_err("can't get mcc to scc switch");
+		return QDF_STATUS_E_FAILURE;
+	}
+	sme_cfg->csrConfig.cc_switch_mode = mcc_to_scc_switch;
+
+	if (QDF_STATUS_SUCCESS !=
+	    ucfg_policy_mgr_get_conc_rule1(hdd_ctx->psoc,
+					   &conc_rule1)) {
+		hdd_err("can't get conc rule1");
+		return QDF_STATUS_E_FAILURE;
+	}
+	sme_cfg->csrConfig.conc_custom_rule1 = conc_rule1;
+
+	if (QDF_STATUS_SUCCESS !=
+	    ucfg_policy_mgr_get_conc_rule2(hdd_ctx->psoc,
+					   &conc_rule2)) {
+		hdd_err("can't get conc rule2");
+		return QDF_STATUS_E_FAILURE;
+	}
+	sme_cfg->csrConfig.conc_custom_rule2 = conc_rule2;
+
+	if (QDF_STATUS_SUCCESS !=
+	    ucfg_policy_mgr_get_sta_cxn_5g_band(hdd_ctx->psoc,
+						&sta_cxn_5g)) {
+		hdd_err("can't get conc rule2");
+		return QDF_STATUS_E_FAILURE;
+	}
+	sme_cfg->csrConfig.is_sta_connection_in_5gz_enabled = sta_cxn_5g;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_set_sme_config() -initializes the sme configuration parameters
+ *
+ * @hdd_ctx: the pointer to hdd context
+ *
+ * Return: QDF_STATUS_SUCCESS if configuration is correctly applied,
+ *		otherwise the appropriate QDF_STATUS would be returned
+ */
+QDF_STATUS hdd_set_sme_config(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeConfigParams *smeConfig;
+	uint8_t rrm_capab_len;
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	uint8_t wmm_mode = 0;
+	bool b80211e_is_enabled;
+
+	struct hdd_config *pConfig = hdd_ctx->config;
+
+	smeConfig = qdf_mem_malloc(sizeof(*smeConfig));
+	if (NULL == smeConfig) {
+		hdd_err("unable to allocate smeConfig");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	/* Config params obtained from the registry
+	 * To Do: set regulatory information here
+	 */
+	smeConfig->csrConfig.shortSlotTime = pConfig->ShortSlotTimeEnabled;
+	smeConfig->csrConfig.Is11dSupportEnabled = pConfig->Is11dSupportEnabled;
+
+	smeConfig->csrConfig.phyMode =
+		hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
+
+	if (pConfig->dot11Mode == eHDD_DOT11_MODE_abg ||
+	    pConfig->dot11Mode == eHDD_DOT11_MODE_11b ||
+	    pConfig->dot11Mode == eHDD_DOT11_MODE_11g ||
+	    pConfig->dot11Mode == eHDD_DOT11_MODE_11b_ONLY ||
+	    pConfig->dot11Mode == eHDD_DOT11_MODE_11g_ONLY) {
+		smeConfig->csrConfig.channelBondingMode24GHz = 0;
+		smeConfig->csrConfig.channelBondingMode5GHz = 0;
+	} else {
+		smeConfig->csrConfig.channelBondingMode24GHz =
+			pConfig->nChannelBondingMode24GHz;
+		smeConfig->csrConfig.channelBondingMode5GHz =
+			pConfig->nChannelBondingMode5GHz;
+	}
+	smeConfig->csrConfig.nScanResultAgeCount = pConfig->ScanResultAgeCount;
+	smeConfig->csrConfig.AdHocChannel24 = pConfig->OperatingChannel;
+	smeConfig->csrConfig.fSupplicantCountryCodeHasPriority =
+		pConfig->fSupplicantCountryCodeHasPriority;
+	smeConfig->csrConfig.bCatRssiOffset = pConfig->nRssiCatGap;
+	smeConfig->csrConfig.vccRssiThreshold = pConfig->nVccRssiTrigger;
+	smeConfig->csrConfig.vccUlMacLossThreshold =
+		pConfig->nVccUlMacLossThreshold;
+	smeConfig->csrConfig.nInitialDwellTime = pConfig->nInitialDwellTime;
+	smeConfig->csrConfig.initial_scan_no_dfs_chnl =
+					pConfig->initial_scan_no_dfs_chnl;
+	smeConfig->csrConfig.nActiveMaxChnTime = pConfig->nActiveMaxChnTime;
+	smeConfig->csrConfig.nPassiveMaxChnTime = pConfig->nPassiveMaxChnTime;
+	smeConfig->csrConfig.nActiveMaxChnTimeConc =
+		pConfig->nActiveMaxChnTimeConc;
+	smeConfig->csrConfig.nActiveMinChnTimeConc =
+		pConfig->nActiveMinChnTimeConc;
+	smeConfig->csrConfig.nPassiveMaxChnTimeConc =
+		pConfig->nPassiveMaxChnTimeConc;
+	smeConfig->csrConfig.nPassiveMinChnTimeConc =
+		pConfig->nPassiveMinChnTimeConc;
+	smeConfig->csrConfig.nRestTimeConc = pConfig->nRestTimeConc;
+	smeConfig->csrConfig.min_rest_time_conc = pConfig->min_rest_time_conc;
+	smeConfig->csrConfig.idle_time_conc     = pConfig->idle_time_conc;
+
+	status = ucfg_mlme_get_80211e_is_enabled(hdd_ctx->psoc,
+						 &b80211e_is_enabled);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Get b80211e_is_enabled failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	smeConfig->csrConfig.Is11eSupportEnabled = b80211e_is_enabled;
+
+	status = ucfg_mlme_get_wmm_mode(hdd_ctx->psoc, &wmm_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Get wmm_mode failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	smeConfig->csrConfig.WMMSupportMode = hdd_to_csr_wmm_mode(wmm_mode);
+
+	hdd_debug("%s bWmmIsEnabled=%d 802_11e_enabled=%d dot11Mode=%d",
+		  __func__, wmm_mode, b80211e_is_enabled,
+		  pConfig->dot11Mode);
+
+	smeConfig->rrmConfig.rrm_enabled = pConfig->fRrmEnable;
+	smeConfig->rrmConfig.max_randn_interval = pConfig->nRrmRandnIntvl;
+	hdd_hex_string_to_u8_array(pConfig->rm_capability,
+			smeConfig->rrmConfig.rm_capability, &rrm_capab_len,
+			DOT11F_IE_RRMENABLEDCAP_MAX_LEN);
+	/* Remaining config params not obtained from registry
+	 * On RF EVB beacon using channel 1.
+	 */
+	/* This param cannot be configured from INI */
+	smeConfig->csrConfig.send_smps_action = true;
+	smeConfig->csrConfig.AdHocChannel5G = pConfig->AdHocChannel5G;
+	smeConfig->csrConfig.AdHocChannel24 = pConfig->AdHocChannel24G;
+	smeConfig->csrConfig.ProprietaryRatesEnabled = 0;
+	smeConfig->csrConfig.HeartbeatThresh50 = 40;
+	smeConfig->csrConfig.Is11hSupportEnabled = pConfig->Is11hSupportEnabled;
+	smeConfig->csrConfig.nTxPowerCap = pConfig->nTxPowerCap;
+	smeConfig->csrConfig.allow_tpc_from_ap = pConfig->allow_tpc_from_ap;
+	smeConfig->csrConfig.fEnableBypass11d = pConfig->enableBypass11d;
+	smeConfig->csrConfig.fEnableDFSChnlScan = pConfig->enableDFSChnlScan;
+	smeConfig->csrConfig.nRoamPrefer5GHz = pConfig->nRoamPrefer5GHz;
+	smeConfig->csrConfig.nRoamIntraBand = pConfig->nRoamIntraBand;
+	smeConfig->csrConfig.nProbes = pConfig->nProbes;
+
+	smeConfig->csrConfig.nRoamScanHomeAwayTime =
+		pConfig->nRoamScanHomeAwayTime;
+	smeConfig->csrConfig.fFirstScanOnly2GChnl =
+		pConfig->enableFirstScan2GOnly;
+
+	smeConfig->csrConfig.Csr11dinfo.Channels.numChannels = 0;
+
+	hdd_set_power_save_offload_config(hdd_ctx);
+
+	smeConfig->csrConfig.isFastRoamIniFeatureEnabled =
+		pConfig->isFastRoamIniFeatureEnabled;
+	smeConfig->csrConfig.csr_mawc_config.mawc_enabled =
+		pConfig->MAWCEnabled;
+
+#ifdef FEATURE_WLAN_ESE
+	smeConfig->csrConfig.isEseIniFeatureEnabled =
+		pConfig->isEseIniFeatureEnabled;
+	if (pConfig->isEseIniFeatureEnabled)
+		pConfig->isFastTransitionEnabled = true;
+#endif
+	smeConfig->csrConfig.isFastTransitionEnabled =
+		pConfig->isFastTransitionEnabled;
+	smeConfig->csrConfig.RoamRssiDiff = pConfig->RoamRssiDiff;
+	smeConfig->csrConfig.isWESModeEnabled = pConfig->isWESModeEnabled;
+	smeConfig->csrConfig.isRoamOffloadScanEnabled =
+		pConfig->isRoamOffloadScanEnabled;
+	smeConfig->csrConfig.bFastRoamInConIniFeatureEnabled =
+		pConfig->bFastRoamInConIniFeatureEnabled;
+
+	if (0 == smeConfig->csrConfig.isRoamOffloadScanEnabled) {
+		/* Disable roaming in concurrency if roam scan
+		 * offload is disabled
+		 */
+		smeConfig->csrConfig.bFastRoamInConIniFeatureEnabled = 0;
+	}
+	smeConfig->csrConfig.neighborRoamConfig.nNeighborLookupRssiThreshold =
+		pConfig->nNeighborLookupRssiThreshold;
+	smeConfig->csrConfig.neighborRoamConfig.rssi_thresh_offset_5g =
+		pConfig->rssi_thresh_offset_5g;
+	smeConfig->csrConfig.neighborRoamConfig.delay_before_vdev_stop =
+		pConfig->delay_before_vdev_stop;
+	smeConfig->csrConfig.neighborRoamConfig.nOpportunisticThresholdDiff =
+		pConfig->nOpportunisticThresholdDiff;
+	smeConfig->csrConfig.neighborRoamConfig.nRoamRescanRssiDiff =
+		pConfig->nRoamRescanRssiDiff;
+	smeConfig->csrConfig.neighborRoamConfig.nNeighborScanMaxChanTime =
+		pConfig->nNeighborScanMaxChanTime;
+	smeConfig->csrConfig.neighborRoamConfig.nNeighborScanMinChanTime =
+		pConfig->nNeighborScanMinChanTime;
+	smeConfig->csrConfig.neighborRoamConfig.nNeighborScanTimerPeriod =
+		pConfig->nNeighborScanPeriod;
+	smeConfig->csrConfig.neighborRoamConfig.
+		neighbor_scan_min_timer_period =
+		pConfig->neighbor_scan_min_period;
+	smeConfig->csrConfig.neighborRoamConfig.nNeighborResultsRefreshPeriod =
+		pConfig->nNeighborResultsRefreshPeriod;
+	smeConfig->csrConfig.neighborRoamConfig.nEmptyScanRefreshPeriod =
+		pConfig->nEmptyScanRefreshPeriod;
+	hdd_string_to_u8_array(pConfig->neighborScanChanList,
+			       smeConfig->csrConfig.neighborRoamConfig.
+			       neighborScanChanList.channelList,
+			       &smeConfig->csrConfig.neighborRoamConfig.
+			       neighborScanChanList.numChannels,
+			       WNI_CFG_VALID_CHANNEL_LIST_LEN);
+	smeConfig->csrConfig.neighborRoamConfig.nRoamBmissFirstBcnt =
+		pConfig->nRoamBmissFirstBcnt;
+	smeConfig->csrConfig.neighborRoamConfig.nRoamBmissFinalBcnt =
+		pConfig->nRoamBmissFinalBcnt;
+	smeConfig->csrConfig.neighborRoamConfig.nRoamBeaconRssiWeight =
+		pConfig->nRoamBeaconRssiWeight;
+	smeConfig->csrConfig.neighborRoamConfig.nhi_rssi_scan_max_count =
+		pConfig->nhi_rssi_scan_max_count;
+	smeConfig->csrConfig.neighborRoamConfig.nhi_rssi_scan_rssi_delta =
+		pConfig->nhi_rssi_scan_rssi_delta;
+	smeConfig->csrConfig.neighborRoamConfig.nhi_rssi_scan_delay =
+		pConfig->nhi_rssi_scan_delay;
+	smeConfig->csrConfig.neighborRoamConfig.nhi_rssi_scan_rssi_ub =
+		pConfig->nhi_rssi_scan_rssi_ub;
+	smeConfig->csrConfig.addTSWhenACMIsOff = pConfig->AddTSWhenACMIsOff;
+	smeConfig->csrConfig.allowDFSChannelRoam = pConfig->allowDFSChannelRoam;
+
+	/* Enable/Disable MCC */
+	smeConfig->csrConfig.fEnableMCCMode = pConfig->enableMCC;
+	smeConfig->csrConfig.mcc_rts_cts_prot_enable =
+					pConfig->mcc_rts_cts_prot_enable;
+	smeConfig->csrConfig.mcc_bcast_prob_resp_enable =
+					pConfig->mcc_bcast_prob_resp_enable;
+	smeConfig->csrConfig.fAllowMCCGODiffBI = pConfig->allowMCCGODiffBI;
+
+	/* Scan Results Aging Time out value */
+	smeConfig->csrConfig.scanCfgAgingTime = pConfig->scanAgingTimeout;
+
+	smeConfig->csrConfig.enable_tx_ldpc = pConfig->enable_tx_ldpc;
+	smeConfig->csrConfig.enable_rx_ldpc = pConfig->enable_rx_ldpc;
+
+	smeConfig->csrConfig.isCoalesingInIBSSAllowed =
+		hdd_ctx->config->isCoalesingInIBSSAllowed;
+	/* update SSR config */
+	sme_update_enable_ssr(mac_handle, hdd_ctx->config->enableSSR);
+
+	/* Update maximum interfaces information */
+	smeConfig->csrConfig.max_intf_count = hdd_ctx->max_intf_count;
+
+	smeConfig->csrConfig.f_sta_miracast_mcc_rest_time_val =
+		hdd_ctx->config->sta_miracast_mcc_rest_time_val;
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	smeConfig->csrConfig.sap_channel_avoidance =
+		hdd_ctx->config->sap_channel_avoidance;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+	smeConfig->csrConfig.f_prefer_non_dfs_on_radar =
+		hdd_ctx->config->prefer_non_dfs_on_radar;
+
+	smeConfig->csrConfig.is_ps_enabled = hdd_ctx->config->is_ps_enabled;
+	smeConfig->csrConfig.auto_bmps_timer_val =
+		hdd_ctx->config->auto_bmps_timer_val;
+	hdd_set_fine_time_meas_cap(hdd_ctx);
+
+	cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
+
+	smeConfig->csrConfig.max_scan_count =
+			hdd_ctx->config->max_scan_count;
+
+	smeConfig->csrConfig.ho_delay_for_rx =
+		hdd_ctx->config->ho_delay_for_rx;
+	smeConfig->csrConfig.min_delay_btw_roam_scans =
+		hdd_ctx->config->min_delay_btw_roam_scans;
+	smeConfig->csrConfig.roam_trigger_reason_bitmask =
+		hdd_ctx->config->roam_trigger_reason_bitmask;
+	smeConfig->csrConfig.scan_adaptive_dwell_mode =
+			hdd_ctx->config->scan_adaptive_dwell_mode;
+	smeConfig->csrConfig.scan_adaptive_dwell_mode_nc =
+			hdd_ctx->config->scan_adaptive_dwell_mode_nc;
+	smeConfig->csrConfig.enable_ftopen =
+			hdd_ctx->config->enable_ftopen;
+	smeConfig->csrConfig.roam_force_rssi_trigger =
+			hdd_ctx->config->roam_force_rssi_trigger;
+
+	smeConfig->csrConfig.sta_roam_policy_params.dfs_mode =
+		CSR_STA_ROAM_POLICY_DFS_ENABLED;
+	smeConfig->csrConfig.sta_roam_policy_params.skip_unsafe_channels = 0;
+
+	smeConfig->snr_monitor_enabled = hdd_ctx->config->fEnableSNRMonitoring;
+
+	hdd_he_set_sme_config(smeConfig, pConfig);
+
+	smeConfig->csrConfig.wlm_latency_enable =
+			hdd_ctx->config->wlm_latency_enable;
+	smeConfig->csrConfig.wlm_latency_level =
+			hdd_ctx->config->wlm_latency_level;
+	smeConfig->csrConfig.wlm_latency_flags[0] =
+			hdd_ctx->config->wlm_latency_flags_normal;
+	smeConfig->csrConfig.wlm_latency_flags[1] =
+			hdd_ctx->config->wlm_latency_flags_moderate;
+	smeConfig->csrConfig.wlm_latency_flags[2] =
+			hdd_ctx->config->wlm_latency_flags_low;
+	smeConfig->csrConfig.wlm_latency_flags[3] =
+			hdd_ctx->config->wlm_latency_flags_ultralow;
+
+	smeConfig->csrConfig.is_force_1x1 =
+			hdd_ctx->config->is_force_1x1;
+
+	smeConfig->csrConfig.btm_offload_config =
+			hdd_ctx->config->btm_offload_config;
+	smeConfig->csrConfig.btm_solicited_timeout =
+			hdd_ctx->config->btm_solicited_timeout;
+	smeConfig->csrConfig.btm_max_attempt_cnt =
+			hdd_ctx->config->btm_max_attempt_cnt;
+	smeConfig->csrConfig.btm_sticky_time =
+			hdd_ctx->config->btm_sticky_time;
+	hdd_set_sme_cfgs_related_to_plcy_mgr(hdd_ctx, smeConfig);
+	hdd_update_11k_offload_params(hdd_ctx->config,
+					&smeConfig->csrConfig);
+
+	status = sme_update_config(mac_handle, smeConfig);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("sme_update_config() failure: %d", status);
+
+	qdf_mem_free(smeConfig);
+	return status;
+}
+
+/**
+ * hdd_execute_global_config_command() - execute the global config command
+ * @hdd_ctx: the pointer to hdd context
+ * @command: the command to run
+ *
+ * Return: the QDF_STATUS return from hdd_execute_config_command
+ */
+QDF_STATUS hdd_execute_global_config_command(struct hdd_context *hdd_ctx,
+					     char *command)
+{
+	return hdd_execute_config_command(g_registry_table,
+					  ARRAY_SIZE(g_registry_table),
+					  (uint8_t *) hdd_ctx->config,
+					  hdd_ctx, command);
+}
+
+static void print_info_handler(const char *buf)
+{
+	hdd_nofl_info("%s", buf);
+}
+
+static void print_debug_handler(const char *buf)
+{
+	hdd_nofl_debug("%s", buf);
+}
+
+/**
+ * hdd_cfg_get_global_config() - get the configuration table
+ * @hdd_ctx: pointer to hdd context
+ * @pBuf: buffer to store the configuration
+ * @buflen: size of the buffer
+ *
+ * Return: none
+ */
+void hdd_cfg_get_global_config(struct hdd_context *hdd_ctx, char *buf,
+			       int buflen)
+{
+	hdd_cfg_get_config(g_registry_table,
+			   ARRAY_SIZE(g_registry_table),
+			   (uint8_t *)hdd_ctx->config, hdd_ctx,
+			   &print_info_handler);
+
+	snprintf(buf, buflen,
+		 "WLAN configuration written to system log");
+}
+
+/**
+ * hdd_cfg_print_global_config() - print the configuration table
+ * @hdd_ctx: pointer to hdd context
+ *
+ * Return: none
+ */
+void hdd_cfg_print_global_config(struct hdd_context *hdd_ctx)
+{
+	hdd_cfg_get_config(g_registry_table,
+			   ARRAY_SIZE(g_registry_table),
+			   (uint8_t *)hdd_ctx->config, hdd_ctx,
+			   &print_debug_handler);
+}
+
+/**
+ * hdd_get_pmkid_modes() - returns PMKID mode bits
+ * @hdd_ctx: the pointer to hdd context
+ *
+ * Return: value of pmkid_modes
+ */
+void hdd_get_pmkid_modes(struct hdd_context *hdd_ctx,
+			 struct pmkid_mode_bits *pmkid_modes)
+{
+	uint32_t cur_pmkid_modes;
+	QDF_STATUS status;
+
+	status = ucfg_mlme_get_pmkid_modes(hdd_ctx->psoc, &cur_pmkid_modes);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_err("get pmkid modes fail");
+
+	pmkid_modes->fw_okc = (cur_pmkid_modes &
+			       CFG_PMKID_MODES_OKC) ? 1 : 0;
+	pmkid_modes->fw_pmksa_cache = (cur_pmkid_modes &
+				       CFG_PMKID_MODES_PMKSA_CACHING) ? 1 : 0;
+}
+
+/**
+ * hdd_update_nss() - Update the number of spatial streams supported.
+ * Ensure that nss is either 1 or 2 before calling this.
+ *
+ * @adapter: the pointer to adapter
+ * @nss: the number of spatial streams to be updated
+ *
+ * This function is used to modify the number of spatial streams
+ * supported when not in connected state.
+ *
+ * Return: QDF_STATUS_SUCCESS if nss is correctly updated,
+ *              otherwise QDF_STATUS_E_FAILURE would be returned
+ */
+QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	uint32_t rx_supp_data_rate, tx_supp_data_rate;
+	bool status = true;
+	QDF_STATUS qdf_status;
+	qdf_size_t val_len;
+	struct mlme_ht_capabilities_info ht_cap_info;
+	uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET] = {0};
+	uint8_t mcs_set_temp[SIZE_OF_SUPPORTED_MCS_SET];
+	uint8_t enable2x2;
+	mac_handle_t mac_handle;
+	bool bval = 0;
+
+	if ((nss == 2) && (hdd_ctx->num_rf_chains != 2)) {
+		hdd_err("No support for 2 spatial streams");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	enable2x2 = (nss == 1) ? 0 : 1;
+
+	qdf_status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("unable to get vht_enable2x2");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (bval == enable2x2) {
+		hdd_debug("NSS same as requested");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!mac_handle) {
+		hdd_err("NULL MAC handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (sme_is_any_session_in_connected_state(mac_handle)) {
+		hdd_err("Connected sessions present, Do not change NSS");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, enable2x2);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Failed to set vht_enable2x2");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!enable2x2) {
+		/* 1x1 */
+		rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+		tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+	} else {
+		/* 2x2 */
+		rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
+		tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
+	}
+
+	/* Update Rx Highest Long GI data Rate */
+	qdf_status =
+		ucfg_mlme_cfg_set_vht_rx_supp_data_rate(hdd_ctx->psoc,
+							rx_supp_data_rate);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Failed to set rx_supp_data_rate");
+		status = false;
+	}
+	/* Update Tx Highest Long GI data Rate */
+	qdf_status =
+		ucfg_mlme_cfg_set_vht_tx_supp_data_rate(hdd_ctx->psoc,
+							tx_supp_data_rate);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Failed to set tx_supp_data_rate");
+		status = false;
+	}
+
+	qdf_status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Failed to get HT Cap info");
+		goto skip_ht_cap_update;
+	}
+
+	if (!(hdd_ctx->ht_tx_stbc_supported && enable2x2)) {
+		ht_cap_info.tx_stbc = 0;
+	} else {
+		qdf_status =
+			ucfg_mlme_cfg_get_vht_tx_stbc(hdd_ctx->psoc, &bval);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			hdd_err("Failed to get vht_tx_stbc");
+			ht_cap_info.tx_stbc = bval;
+		}
+	}
+
+	qdf_status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Could not set the HT_CAP_INFO");
+	}
+skip_ht_cap_update:
+	qdf_status = ucfg_mlme_update_nss_vht_cap(hdd_ctx->psoc);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Failed to set update_nss_vht_cap");
+		status = false;
+	}
+
+#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
+	val_len = SIZE_OF_SUPPORTED_MCS_SET;
+	qdf_status = ucfg_mlme_get_supported_mcs_set(hdd_ctx->psoc,
+						     mcs_set_temp,
+						     &val_len);
+	if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		mcs_set[0] = mcs_set_temp[0];
+		if (enable2x2)
+			for (val_len = 0; val_len < nss; val_len++)
+				mcs_set[val_len] =
+				WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
+		if (ucfg_mlme_set_supported_mcs_set(
+			hdd_ctx->psoc, mcs_set,
+			(qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET) ==
+			QDF_STATUS_E_FAILURE) {
+			status = false;
+			hdd_err("Could not pass on MCS SET to CFG");
+		}
+	} else {
+		status = false;
+		hdd_err("Could not get MCS SET from CFG");
+	}
+	sme_update_he_cap_nss(mac_handle, adapter->session_id, nss);
+#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
+
+	if (QDF_STATUS_SUCCESS != sme_update_nss(mac_handle, nss))
+		status = false;
+
+	hdd_set_policy_mgr_user_cfg(hdd_ctx);
+	return (status == false) ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
+}
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
new file mode 100644
index 0000000..3902073
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -0,0 +1,19959 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_cfg80211.c
+ *
+ * WLAN Host Device Driver cfg80211 APIs implementation
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <wlan_hdd_includes.h>
+#include <net/arp.h>
+#include <net/cfg80211.h>
+#include <wlan_hdd_wowl.h>
+#include <ani_global.h>
+#include "sir_params.h"
+#include "dot11f.h"
+#include "wlan_hdd_assoc.h"
+#include "wlan_hdd_wext.h"
+#include "sme_api.h"
+#include "sme_power_save_api.h"
+#include "wlan_hdd_p2p.h"
+#include "wlan_hdd_cfg80211.h"
+#include "wlan_hdd_hostapd.h"
+#include "wlan_hdd_softap_tx_rx.h"
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_power.h"
+#include "wlan_hdd_trace.h"
+#include "qdf_str.h"
+#include "qdf_trace.h"
+#include "qdf_types.h"
+#include "cds_utils.h"
+#include "cds_sched.h"
+#include "wlan_hdd_scan.h"
+#include <qc_sap_ioctl.h>
+#include "wlan_hdd_tdls.h"
+#include "wlan_hdd_wmm.h"
+#include "wma_types.h"
+#include "wma.h"
+#include "wlan_hdd_misc.h"
+#include "wlan_hdd_nan.h"
+#include "wlan_logging_sock_svc.h"
+#include "sap_api.h"
+#include "csr_api.h"
+#include "pld_common.h"
+#include "wmi_unified_param.h"
+
+#ifdef WLAN_UMAC_CONVERGENCE
+#include "wlan_cfg80211.h"
+#endif
+#include <cdp_txrx_handle.h>
+#include <wlan_cfg80211_scan.h>
+#include <wlan_cfg80211_ftm.h>
+
+#include "wlan_hdd_ext_scan.h"
+
+#include "wlan_hdd_stats.h"
+#include "cds_api.h"
+#include "wlan_policy_mgr_api.h"
+#include "qwlan_version.h"
+
+#include "wlan_hdd_ocb.h"
+#include "wlan_hdd_tsf.h"
+
+#include "wlan_hdd_subnet_detect.h"
+#include <wlan_hdd_regulatory.h>
+#include "wlan_hdd_lpass.h"
+#include "wlan_hdd_nan_datapath.h"
+#include "wlan_hdd_disa.h"
+#include "wlan_osif_request_manager.h"
+#include "wlan_hdd_he.h"
+#ifdef FEATURE_WLAN_APF
+#include "wlan_hdd_apf.h"
+#endif
+
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_misc.h>
+#include <qca_vendor.h>
+#include "wlan_pmo_ucfg_api.h"
+#include "os_if_wifi_pos.h"
+#include "wlan_utility.h"
+#include "wlan_reg_ucfg_api.h"
+#include "wifi_pos_api.h"
+#include "wlan_hdd_spectralscan.h"
+#include "wlan_ipa_ucfg_api.h"
+#include <wlan_cfg80211_mc_cp_stats.h>
+#include <wlan_cp_stats_mc_ucfg_api.h>
+#include "wlan_tdls_cfg_api.h"
+#include <wlan_hdd_bss_transition.h>
+#include <wlan_hdd_concurrency_matrix.h>
+#include <wlan_hdd_p2p_listen_offload.h>
+#include <wlan_hdd_rssi_monitor.h>
+#include <wlan_hdd_sap_cond_chan_switch.h>
+#include <wlan_hdd_station_info.h>
+#include <wlan_hdd_tx_power.h>
+#include <wlan_hdd_active_tos.h>
+#include <wlan_hdd_sar_limits.h>
+#include <wlan_hdd_ota_test.h>
+#include "wlan_policy_mgr_ucfg.h"
+#include "wlan_extscan_ucfg_api.h"
+#include "wlan_mlme_ucfg_api.h"
+#include "wlan_pmo_cfg.h"
+#include "cfg_ucfg_api.h"
+
+#include "wlan_crypto_global_api.h"
+#include "wlan_nl_to_crypto_params.h"
+#include "wlan_crypto_global_def.h"
+#include "cdp_txrx_cfg.h"
+
+#define g_mode_rates_size (12)
+#define a_mode_rates_size (8)
+
+/*
+ * Android CTS verifier needs atleast this much wait time (in msec)
+ */
+#define MAX_REMAIN_ON_CHANNEL_DURATION (5000)
+
+/*
+ * Refer @tCfgProtection structure for definition of the bit map.
+ * below value is obtained by setting the following bit-fields.
+ * enable obss, fromllb, overlapOBSS and overlapFromllb protection.
+ */
+#define IBSS_CFG_PROTECTION_ENABLE_MASK 0x8282
+
+#define HDD2GHZCHAN(freq, chan, flag)   {     \
+		.band = HDD_NL80211_BAND_2GHZ, \
+		.center_freq = (freq), \
+		.hw_value = (chan), \
+		.flags = (flag), \
+		.max_antenna_gain = 0, \
+		.max_power = 0, \
+}
+
+#define HDD5GHZCHAN(freq, chan, flag)   {     \
+		.band =  HDD_NL80211_BAND_5GHZ, \
+		.center_freq = (freq), \
+		.hw_value = (chan), \
+		.flags = (flag), \
+		.max_antenna_gain = 0, \
+		.max_power = 0, \
+}
+
+#define HDD_G_MODE_RATETAB(rate, rate_id, flag)	\
+	{ \
+		.bitrate = rate, \
+		.hw_value = rate_id, \
+		.flags = flag, \
+	}
+
+#ifndef WLAN_AKM_SUITE_FT_8021X
+#define WLAN_AKM_SUITE_FT_8021X         0x000FAC03
+#endif
+
+#ifndef WLAN_AKM_SUITE_FT_PSK
+#define WLAN_AKM_SUITE_FT_PSK           0x000FAC04
+#endif
+
+#define HDD_CHANNEL_14 14
+
+#define IS_DFS_MODE_VALID(mode) ((mode >= DFS_MODE_NONE && \
+			mode <= DFS_MODE_DEPRIORITIZE))
+/*
+ * Number of DPTRACE records to dump when a cfg80211 disconnect with reason
+ * WLAN_REASON_DEAUTH_LEAVING DEAUTH is received from user-space.
+ */
+#define WLAN_DEAUTH_DPTRACE_DUMP_COUNT 100
+#ifndef WLAN_CIPHER_SUITE_GCMP
+#define WLAN_CIPHER_SUITE_GCMP 0x000FAC08
+#endif
+#ifndef WLAN_CIPHER_SUITE_GCMP_256
+#define WLAN_CIPHER_SUITE_GCMP_256 0x000FAC09
+#endif
+
+static const u32 hdd_gcmp_cipher_suits[] = {
+	WLAN_CIPHER_SUITE_GCMP,
+	WLAN_CIPHER_SUITE_GCMP_256,
+};
+
+static const u32 hdd_cipher_suites[] = {
+	WLAN_CIPHER_SUITE_WEP40,
+	WLAN_CIPHER_SUITE_WEP104,
+	WLAN_CIPHER_SUITE_TKIP,
+#ifdef FEATURE_WLAN_ESE
+#define WLAN_CIPHER_SUITE_BTK 0x004096fe        /* use for BTK */
+#define WLAN_CIPHER_SUITE_KRK 0x004096ff        /* use for KRK */
+	WLAN_CIPHER_SUITE_BTK,
+	WLAN_CIPHER_SUITE_KRK,
+	WLAN_CIPHER_SUITE_CCMP,
+#else
+	WLAN_CIPHER_SUITE_CCMP,
+#endif
+#ifdef FEATURE_WLAN_WAPI
+	WLAN_CIPHER_SUITE_SMS4,
+#endif
+#ifdef WLAN_FEATURE_11W
+	WLAN_CIPHER_SUITE_AES_CMAC,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+	WLAN_CIPHER_SUITE_BIP_GMAC_128,
+	WLAN_CIPHER_SUITE_BIP_GMAC_256,
+#endif
+#endif
+};
+
+static const struct ieee80211_channel hdd_channels_2_4_ghz[] = {
+	HDD2GHZCHAN(2412, 1, 0),
+	HDD2GHZCHAN(2417, 2, 0),
+	HDD2GHZCHAN(2422, 3, 0),
+	HDD2GHZCHAN(2427, 4, 0),
+	HDD2GHZCHAN(2432, 5, 0),
+	HDD2GHZCHAN(2437, 6, 0),
+	HDD2GHZCHAN(2442, 7, 0),
+	HDD2GHZCHAN(2447, 8, 0),
+	HDD2GHZCHAN(2452, 9, 0),
+	HDD2GHZCHAN(2457, 10, 0),
+	HDD2GHZCHAN(2462, 11, 0),
+	HDD2GHZCHAN(2467, 12, 0),
+	HDD2GHZCHAN(2472, 13, 0),
+	HDD2GHZCHAN(2484, 14, 0),
+};
+
+static const struct ieee80211_channel hdd_channels_5_ghz[] = {
+	HDD5GHZCHAN(5180, 36, 0),
+	HDD5GHZCHAN(5200, 40, 0),
+	HDD5GHZCHAN(5220, 44, 0),
+	HDD5GHZCHAN(5240, 48, 0),
+	HDD5GHZCHAN(5260, 52, 0),
+	HDD5GHZCHAN(5280, 56, 0),
+	HDD5GHZCHAN(5300, 60, 0),
+	HDD5GHZCHAN(5320, 64, 0),
+	HDD5GHZCHAN(5500, 100, 0),
+	HDD5GHZCHAN(5520, 104, 0),
+	HDD5GHZCHAN(5540, 108, 0),
+	HDD5GHZCHAN(5560, 112, 0),
+	HDD5GHZCHAN(5580, 116, 0),
+	HDD5GHZCHAN(5600, 120, 0),
+	HDD5GHZCHAN(5620, 124, 0),
+	HDD5GHZCHAN(5640, 128, 0),
+	HDD5GHZCHAN(5660, 132, 0),
+	HDD5GHZCHAN(5680, 136, 0),
+	HDD5GHZCHAN(5700, 140, 0),
+	HDD5GHZCHAN(5720, 144, 0),
+	HDD5GHZCHAN(5745, 149, 0),
+	HDD5GHZCHAN(5765, 153, 0),
+	HDD5GHZCHAN(5785, 157, 0),
+	HDD5GHZCHAN(5805, 161, 0),
+	HDD5GHZCHAN(5825, 165, 0),
+};
+
+#ifdef WLAN_FEATURE_DSRC
+static const struct ieee80211_channel hdd_channels_dot11p[] = {
+	HDD5GHZCHAN(5852, 170, 0),
+	HDD5GHZCHAN(5855, 171, 0),
+	HDD5GHZCHAN(5860, 172, 0),
+	HDD5GHZCHAN(5865, 173, 0),
+	HDD5GHZCHAN(5870, 174, 0),
+	HDD5GHZCHAN(5875, 175, 0),
+	HDD5GHZCHAN(5880, 176, 0),
+	HDD5GHZCHAN(5885, 177, 0),
+	HDD5GHZCHAN(5890, 178, 0),
+	HDD5GHZCHAN(5895, 179, 0),
+	HDD5GHZCHAN(5900, 180, 0),
+	HDD5GHZCHAN(5905, 181, 0),
+	HDD5GHZCHAN(5910, 182, 0),
+	HDD5GHZCHAN(5915, 183, 0),
+	HDD5GHZCHAN(5920, 184, 0),
+};
+#else
+static const struct ieee80211_channel hdd_etsi13_srd_ch[] = {
+	HDD5GHZCHAN(5845, 169, 0),
+	HDD5GHZCHAN(5865, 173, 0),
+};
+#endif
+
+static struct ieee80211_rate g_mode_rates[] = {
+	HDD_G_MODE_RATETAB(10, 0x1, 0),
+	HDD_G_MODE_RATETAB(20, 0x2, 0),
+	HDD_G_MODE_RATETAB(55, 0x4, 0),
+	HDD_G_MODE_RATETAB(110, 0x8, 0),
+	HDD_G_MODE_RATETAB(60, 0x10, 0),
+	HDD_G_MODE_RATETAB(90, 0x20, 0),
+	HDD_G_MODE_RATETAB(120, 0x40, 0),
+	HDD_G_MODE_RATETAB(180, 0x80, 0),
+	HDD_G_MODE_RATETAB(240, 0x100, 0),
+	HDD_G_MODE_RATETAB(360, 0x200, 0),
+	HDD_G_MODE_RATETAB(480, 0x400, 0),
+	HDD_G_MODE_RATETAB(540, 0x800, 0),
+};
+
+static struct ieee80211_rate a_mode_rates[] = {
+	HDD_G_MODE_RATETAB(60, 0x10, 0),
+	HDD_G_MODE_RATETAB(90, 0x20, 0),
+	HDD_G_MODE_RATETAB(120, 0x40, 0),
+	HDD_G_MODE_RATETAB(180, 0x80, 0),
+	HDD_G_MODE_RATETAB(240, 0x100, 0),
+	HDD_G_MODE_RATETAB(360, 0x200, 0),
+	HDD_G_MODE_RATETAB(480, 0x400, 0),
+	HDD_G_MODE_RATETAB(540, 0x800, 0),
+};
+
+static struct ieee80211_supported_band wlan_hdd_band_2_4_ghz = {
+	.channels = NULL,
+	.n_channels = ARRAY_SIZE(hdd_channels_2_4_ghz),
+	.band = HDD_NL80211_BAND_2GHZ,
+	.bitrates = g_mode_rates,
+	.n_bitrates = g_mode_rates_size,
+	.ht_cap.ht_supported = 1,
+	.ht_cap.cap = IEEE80211_HT_CAP_SGI_20
+		      | IEEE80211_HT_CAP_GRN_FLD
+		      | IEEE80211_HT_CAP_DSSSCCK40
+		      | IEEE80211_HT_CAP_LSIG_TXOP_PROT
+		      | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
+	.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
+	.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
+	.ht_cap.mcs.rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
+	.ht_cap.mcs.rx_highest = cpu_to_le16(72),
+	.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
+};
+
+static struct ieee80211_supported_band wlan_hdd_band_5_ghz = {
+	.channels = NULL,
+	.n_channels = ARRAY_SIZE(hdd_channels_5_ghz),
+	.band = HDD_NL80211_BAND_5GHZ,
+	.bitrates = a_mode_rates,
+	.n_bitrates = a_mode_rates_size,
+	.ht_cap.ht_supported = 1,
+	.ht_cap.cap = IEEE80211_HT_CAP_SGI_20
+		      | IEEE80211_HT_CAP_GRN_FLD
+		      | IEEE80211_HT_CAP_DSSSCCK40
+		      | IEEE80211_HT_CAP_LSIG_TXOP_PROT
+		      | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
+	.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
+	.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
+	.ht_cap.mcs.rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
+	.ht_cap.mcs.rx_highest = cpu_to_le16(72),
+	.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
+	.vht_cap.vht_supported = 1,
+};
+
+/* This structure contain information what kind of frame are expected in
+ * TX/RX direction for each kind of interface
+ */
+static const struct ieee80211_txrx_stypes
+	wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
+	[NL80211_IFTYPE_STATION] = {
+		.tx = 0xffff,
+		.rx = BIT(SIR_MAC_MGMT_ACTION) |
+		      BIT(SIR_MAC_MGMT_PROBE_REQ) |
+		      BIT(SIR_MAC_MGMT_AUTH),
+	},
+	[NL80211_IFTYPE_AP] = {
+		.tx = 0xffff,
+		.rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
+		      BIT(SIR_MAC_MGMT_REASSOC_REQ) |
+		      BIT(SIR_MAC_MGMT_PROBE_REQ) |
+		      BIT(SIR_MAC_MGMT_DISASSOC) |
+		      BIT(SIR_MAC_MGMT_AUTH) |
+		      BIT(SIR_MAC_MGMT_DEAUTH) |
+		      BIT(SIR_MAC_MGMT_ACTION),
+	},
+	[NL80211_IFTYPE_ADHOC] = {
+		.tx = 0xffff,
+		.rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
+		      BIT(SIR_MAC_MGMT_REASSOC_REQ) |
+		      BIT(SIR_MAC_MGMT_PROBE_REQ) |
+		      BIT(SIR_MAC_MGMT_DISASSOC) |
+		      BIT(SIR_MAC_MGMT_AUTH) |
+		      BIT(SIR_MAC_MGMT_DEAUTH) |
+		      BIT(SIR_MAC_MGMT_ACTION),
+	},
+	[NL80211_IFTYPE_P2P_CLIENT] = {
+		.tx = 0xffff,
+		.rx = BIT(SIR_MAC_MGMT_ACTION) |
+		      BIT(SIR_MAC_MGMT_PROBE_REQ),
+	},
+	[NL80211_IFTYPE_P2P_GO] = {
+		/* This is also same as for SoftAP */
+		.tx = 0xffff,
+		.rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
+		      BIT(SIR_MAC_MGMT_REASSOC_REQ) |
+		      BIT(SIR_MAC_MGMT_PROBE_REQ) |
+		      BIT(SIR_MAC_MGMT_DISASSOC) |
+		      BIT(SIR_MAC_MGMT_AUTH) |
+		      BIT(SIR_MAC_MGMT_DEAUTH) |
+		      BIT(SIR_MAC_MGMT_ACTION),
+	},
+};
+
+/* Interface limits and combinations registered by the driver */
+
+/* STA ( + STA ) combination */
+static const struct ieee80211_iface_limit
+	wlan_hdd_sta_iface_limit[] = {
+	{
+		.max = 3,       /* p2p0 is a STA as well */
+		.types = BIT(NL80211_IFTYPE_STATION),
+	},
+};
+
+/* ADHOC (IBSS) limit */
+static const struct ieee80211_iface_limit
+	wlan_hdd_adhoc_iface_limit[] = {
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_STATION),
+	},
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_ADHOC),
+	},
+};
+
+/* AP ( + AP ) combination */
+static const struct ieee80211_iface_limit
+	wlan_hdd_ap_iface_limit[] = {
+	{
+		.max = (QDF_MAX_NO_OF_SAP_MODE + SAP_MAX_OBSS_STA_CNT),
+		.types = BIT(NL80211_IFTYPE_AP),
+	},
+};
+
+/* P2P limit */
+static const struct ieee80211_iface_limit
+	wlan_hdd_p2p_iface_limit[] = {
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_P2P_CLIENT),
+	},
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_P2P_GO),
+	},
+};
+
+static const struct ieee80211_iface_limit
+	wlan_hdd_sta_ap_iface_limit[] = {
+	{
+		/* We need 1 extra STA interface for OBSS scan when SAP starts
+		 * with HT40 in STA+SAP concurrency mode
+		 */
+		.max = (1 + SAP_MAX_OBSS_STA_CNT),
+		.types = BIT(NL80211_IFTYPE_STATION),
+	},
+	{
+		.max = QDF_MAX_NO_OF_SAP_MODE,
+		.types = BIT(NL80211_IFTYPE_AP),
+	},
+};
+
+/* STA + P2P combination */
+static const struct ieee80211_iface_limit
+	wlan_hdd_sta_p2p_iface_limit[] = {
+	{
+		/* One reserved for dedicated P2PDEV usage */
+		.max = 2,
+		.types = BIT(NL80211_IFTYPE_STATION)
+	},
+	{
+		/* Support for two identical (GO + GO or CLI + CLI)
+		 * or dissimilar (GO + CLI) P2P interfaces
+		 */
+		.max = 2,
+		.types = BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT),
+	},
+};
+
+/* STA + AP + P2PGO combination */
+static const struct ieee80211_iface_limit
+wlan_hdd_sta_ap_p2pgo_iface_limit[] = {
+	/* Support for AP+P2PGO interfaces */
+	{
+	   .max = 2,
+	   .types = BIT(NL80211_IFTYPE_STATION)
+	},
+	{
+	   .max = 1,
+	   .types = BIT(NL80211_IFTYPE_P2P_GO)
+	},
+	{
+	   .max = 1,
+	   .types = BIT(NL80211_IFTYPE_AP)
+	}
+};
+
+/* SAP + P2P combination */
+static const struct ieee80211_iface_limit
+wlan_hdd_sap_p2p_iface_limit[] = {
+	{
+	   /* 1 dedicated for p2p0 which is a STA type */
+	   .max = 1,
+	   .types = BIT(NL80211_IFTYPE_STATION)
+	},
+	{
+	   /* The p2p interface in SAP+P2P can be GO/CLI.
+	    * The p2p connection can be formed on p2p0 or p2p-p2p0-x.
+	    */
+	   .max = 1,
+	   .types = BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT)
+	},
+	{
+	   /* SAP+GO to support only one SAP interface */
+	   .max = 1,
+	   .types = BIT(NL80211_IFTYPE_AP)
+	}
+};
+
+/* P2P + P2P combination */
+static const struct ieee80211_iface_limit
+wlan_hdd_p2p_p2p_iface_limit[] = {
+	{
+	   /* 1 dedicated for p2p0 which is a STA type */
+	   .max = 1,
+	   .types = BIT(NL80211_IFTYPE_STATION)
+	},
+	{
+	   /* The p2p interface in P2P+P2P can be GO/CLI.
+	    * For P2P+P2P, the new interfaces are formed on p2p-p2p0-x.
+	    */
+	   .max = 2,
+	   .types = BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT)
+	},
+};
+
+static const struct ieee80211_iface_limit
+	wlan_hdd_mon_iface_limit[] = {
+	{
+		.max = 3,       /* Monitor interface */
+		.types = BIT(NL80211_IFTYPE_MONITOR),
+	},
+};
+
+static struct ieee80211_iface_combination
+	wlan_hdd_iface_combination[] = {
+	/* STA */
+	{
+		.limits = wlan_hdd_sta_iface_limit,
+		.num_different_channels = 2,
+		.max_interfaces = 3,
+		.n_limits = ARRAY_SIZE(wlan_hdd_sta_iface_limit),
+	},
+	/* ADHOC */
+	{
+		.limits = wlan_hdd_adhoc_iface_limit,
+		.num_different_channels = 2,
+		.max_interfaces = 2,
+		.n_limits = ARRAY_SIZE(wlan_hdd_adhoc_iface_limit),
+	},
+	/* AP */
+	{
+		.limits = wlan_hdd_ap_iface_limit,
+		.num_different_channels = 2,
+		.max_interfaces = (SAP_MAX_OBSS_STA_CNT + QDF_MAX_NO_OF_SAP_MODE),
+		.n_limits = ARRAY_SIZE(wlan_hdd_ap_iface_limit),
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) || \
+	defined(CFG80211_BEACON_INTERVAL_BACKPORT)
+		.beacon_int_min_gcd = 1,
+#endif
+	},
+	/* P2P */
+	{
+		.limits = wlan_hdd_p2p_iface_limit,
+		.num_different_channels = 2,
+		.max_interfaces = 2,
+		.n_limits = ARRAY_SIZE(wlan_hdd_p2p_iface_limit),
+	},
+	/* STA + AP */
+	{
+		.limits = wlan_hdd_sta_ap_iface_limit,
+		.num_different_channels = 2,
+		.max_interfaces = (1 + SAP_MAX_OBSS_STA_CNT + QDF_MAX_NO_OF_SAP_MODE),
+		.n_limits = ARRAY_SIZE(wlan_hdd_sta_ap_iface_limit),
+		.beacon_int_infra_match = true,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) || \
+	defined(CFG80211_BEACON_INTERVAL_BACKPORT)
+		.beacon_int_min_gcd = 1,
+#endif
+	},
+	/* STA + P2P */
+	{
+		.limits = wlan_hdd_sta_p2p_iface_limit,
+		.num_different_channels = 2,
+		/* one interface reserved for P2PDEV dedicated usage */
+		.max_interfaces = 4,
+		.n_limits = ARRAY_SIZE(wlan_hdd_sta_p2p_iface_limit),
+		.beacon_int_infra_match = true,
+	},
+	/* STA + P2P GO + SAP */
+	{
+		.limits = wlan_hdd_sta_ap_p2pgo_iface_limit,
+		/* we can allow 3 channels for three different persona
+		 * but due to firmware limitation, allow max 2 concrnt channels.
+		 */
+		.num_different_channels = 2,
+		/* one interface reserved for P2PDEV dedicated usage */
+		.max_interfaces = 4,
+		.n_limits = ARRAY_SIZE(wlan_hdd_sta_ap_p2pgo_iface_limit),
+		.beacon_int_infra_match = true,
+	},
+	/* SAP + P2P */
+	{
+		.limits = wlan_hdd_sap_p2p_iface_limit,
+		.num_different_channels = 2,
+		/* 1-p2p0 + 1-SAP + 1-P2P (on p2p0 or p2p-p2p0-x) */
+		.max_interfaces = 3,
+		.n_limits = ARRAY_SIZE(wlan_hdd_sap_p2p_iface_limit),
+		.beacon_int_infra_match = true,
+	},
+	/* P2P + P2P */
+	{
+		.limits = wlan_hdd_p2p_p2p_iface_limit,
+		.num_different_channels = 2,
+		/* 1-p2p0 + 2-P2P (on p2p-p2p0-x) */
+		.max_interfaces = 3,
+		.n_limits = ARRAY_SIZE(wlan_hdd_p2p_p2p_iface_limit),
+		.beacon_int_infra_match = true,
+	},
+	/* Monitor */
+	{
+		.limits = wlan_hdd_mon_iface_limit,
+		.max_interfaces = 3,
+		.num_different_channels = 2,
+		.n_limits = ARRAY_SIZE(wlan_hdd_mon_iface_limit),
+	},
+};
+
+static struct cfg80211_ops wlan_hdd_cfg80211_ops;
+
+#ifdef WLAN_NL80211_TESTMODE
+enum wlan_hdd_tm_attr {
+	WLAN_HDD_TM_ATTR_INVALID = 0,
+	WLAN_HDD_TM_ATTR_CMD = 1,
+	WLAN_HDD_TM_ATTR_DATA = 2,
+	WLAN_HDD_TM_ATTR_STREAM_ID = 3,
+	WLAN_HDD_TM_ATTR_TYPE = 4,
+	/* keep last */
+	WLAN_HDD_TM_ATTR_AFTER_LAST,
+	WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
+};
+
+enum wlan_hdd_tm_cmd {
+	WLAN_HDD_TM_CMD_WLAN_FTM = 0,
+	WLAN_HDD_TM_CMD_WLAN_HB = 1,
+};
+
+#define WLAN_HDD_TM_DATA_MAX_LEN    5000
+
+static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] = {
+	[WLAN_HDD_TM_ATTR_CMD] = {.type = NLA_U32},
+	[WLAN_HDD_TM_ATTR_DATA] = {.type = NLA_BINARY,
+				   .len = WLAN_HDD_TM_DATA_MAX_LEN},
+};
+#endif /* WLAN_NL80211_TESTMODE */
+
+enum wlan_hdd_vendor_ie_access_policy {
+	WLAN_HDD_VENDOR_IE_ACCESS_NONE = 0,
+	WLAN_HDD_VENDOR_IE_ACCESS_ALLOW_IF_LISTED,
+};
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
+static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
+	.flags = WIPHY_WOWLAN_MAGIC_PKT,
+	.n_patterns = WOWL_MAX_PTRNS_ALLOWED,
+	.pattern_min_len = 1,
+	.pattern_max_len = WOWL_PTRN_MAX_SIZE,
+};
+#endif
+
+/**
+ * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
+ * @flags: Pointer to the flags to Add channel switch flag.
+ *
+ * This Function adds Channel Switch support flag, if channel switch is
+ * supported by kernel.
+ * Return: void.
+ */
+#ifdef CHANNEL_SWITCH_SUPPORTED
+static inline void hdd_add_channel_switch_support(uint32_t *flags)
+{
+	*flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
+}
+#else
+static inline void hdd_add_channel_switch_support(uint32_t *flags)
+{
+}
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+
+/* TDLS capabilities params */
+#define PARAM_MAX_TDLS_SESSION \
+		QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS
+#define PARAM_TDLS_FEATURE_SUPPORT \
+		QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED
+
+/**
+ * __wlan_hdd_cfg80211_get_tdls_capabilities() - Provide TDLS Capabilities.
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function provides TDLS capabilities
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int __wlan_hdd_cfg80211_get_tdls_capabilities(struct wiphy *wiphy,
+						     struct wireless_dev *wdev,
+						     const void *data,
+						     int data_len)
+{
+	int status;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct sk_buff *skb;
+	uint32_t set = 0;
+	uint32_t max_num_tdls_sta = 0;
+	bool tdls_support;
+	bool tdls_external_control;
+	bool tdls_sleep_sta_enable;
+	bool tdls_buffer_sta;
+	bool tdls_off_channel;
+
+	hdd_enter_dev(wdev->netdev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, (2 * sizeof(u32)) +
+						   NLMSG_HDRLEN);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		goto fail;
+	}
+
+	if ((cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support) ==
+	     QDF_STATUS_SUCCESS) && tdls_support) {
+		hdd_debug("TDLS feature not Enabled or Not supported in FW");
+		if (nla_put_u32(skb, PARAM_MAX_TDLS_SESSION, 0) ||
+			nla_put_u32(skb, PARAM_TDLS_FEATURE_SUPPORT, 0)) {
+			hdd_err("nla put fail");
+			goto fail;
+		}
+	} else {
+		cfg_tdls_get_external_control(hdd_ctx->psoc,
+					      &tdls_external_control);
+		cfg_tdls_get_sleep_sta_enable(hdd_ctx->psoc,
+					      &tdls_sleep_sta_enable);
+		cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc,
+					       &tdls_buffer_sta);
+		cfg_tdls_get_off_channel_enable(hdd_ctx->psoc,
+						&tdls_off_channel);
+		set = set | WIFI_TDLS_SUPPORT;
+		set = set | (tdls_external_control ?
+					WIFI_TDLS_EXTERNAL_CONTROL_SUPPORT : 0);
+		set = set | (tdls_off_channel ?
+					WIIF_TDLS_OFFCHANNEL_SUPPORT : 0);
+		if (tdls_sleep_sta_enable || tdls_buffer_sta ||
+		    tdls_off_channel)
+			max_num_tdls_sta = HDD_MAX_NUM_TDLS_STA_P_UAPSD_OFFCHAN;
+		else
+			max_num_tdls_sta = HDD_MAX_NUM_TDLS_STA;
+
+		hdd_debug("TDLS Feature supported value %x", set);
+		if (nla_put_u32(skb, PARAM_MAX_TDLS_SESSION,
+				max_num_tdls_sta) ||
+		    nla_put_u32(skb, PARAM_TDLS_FEATURE_SUPPORT, set)) {
+			hdd_err("nla put fail");
+			goto fail;
+		}
+	}
+	return cfg80211_vendor_cmd_reply(skb);
+fail:
+	if (skb)
+		kfree_skb(skb);
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_get_tdls_capabilities() - Provide TDLS Capabilities.
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function provides TDLS capabilities
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int
+wlan_hdd_cfg80211_get_tdls_capabilities(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_tdls_capabilities(wiphy, wdev,
+							data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
+#ifdef QCA_HT_2040_COEX
+static void wlan_hdd_cfg80211_start_pending_acs(struct work_struct *work);
+#endif
+
+int wlan_hdd_merge_avoid_freqs(struct ch_avoid_ind_type *destFreqList,
+		struct ch_avoid_ind_type *srcFreqList)
+{
+	int i;
+	struct ch_avoid_freq_type *avoid_range =
+	&destFreqList->avoid_freq_range[destFreqList->ch_avoid_range_cnt];
+
+	destFreqList->ch_avoid_range_cnt += srcFreqList->ch_avoid_range_cnt;
+	if (destFreqList->ch_avoid_range_cnt > CH_AVOID_MAX_RANGE) {
+		hdd_err("avoid freq overflow");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < srcFreqList->ch_avoid_range_cnt; i++) {
+		avoid_range->start_freq =
+			srcFreqList->avoid_freq_range[i].start_freq;
+		avoid_range->end_freq =
+			srcFreqList->avoid_freq_range[i].end_freq;
+		avoid_range++;
+	}
+	return 0;
+}
+/*
+ * FUNCTION: wlan_hdd_send_avoid_freq_event
+ * This is called when wlan driver needs to send vendor specific
+ * avoid frequency range event to userspace
+ */
+int wlan_hdd_send_avoid_freq_event(struct hdd_context *hdd_ctx,
+				   struct ch_avoid_ind_type *avoid_freq_list)
+{
+	struct sk_buff *vendor_event;
+
+	hdd_enter();
+
+	if (!hdd_ctx) {
+		hdd_err("HDD context is null");
+		return -EINVAL;
+	}
+
+	if (!avoid_freq_list) {
+		hdd_err("avoid_freq_list is null");
+		return -EINVAL;
+	}
+
+	vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+			NULL, sizeof(struct ch_avoid_ind_type),
+			QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
+			GFP_KERNEL);
+
+	if (!vendor_event) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return -EINVAL;
+	}
+
+	memcpy(skb_put(vendor_event, sizeof(struct ch_avoid_ind_type)),
+	       (void *)avoid_freq_list, sizeof(struct ch_avoid_ind_type));
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+
+	hdd_exit();
+	return 0;
+}
+
+/*
+ * define short names for the global vendor params
+ * used by QCA_NL80211_VENDOR_SUBCMD_HANG
+ */
+#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
+
+/**
+ * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
+ * hang reason
+ * @reason: cds recovery reason
+ *
+ * Return: Vendor specific reason code
+ */
+static enum qca_wlan_vendor_hang_reason
+hdd_convert_hang_reason(enum qdf_hang_reason reason)
+{
+	u32 ret_val;
+
+	switch (reason) {
+	case QDF_RX_HASH_NO_ENTRY_FOUND:
+		ret_val = QCA_WLAN_HANG_RX_HASH_NO_ENTRY_FOUND;
+		break;
+	case QDF_PEER_DELETION_TIMEDOUT:
+		ret_val = QCA_WLAN_HANG_PEER_DELETION_TIMEDOUT;
+		break;
+	case QDF_PEER_UNMAP_TIMEDOUT:
+		ret_val = QCA_WLAN_HANG_PEER_UNMAP_TIMEDOUT;
+		break;
+	case QDF_SCAN_REQ_EXPIRED:
+		ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
+		break;
+	case QDF_SCAN_ATTEMPT_FAILURES:
+		ret_val = QCA_WLAN_HANG_SCAN_ATTEMPT_FAILURES;
+		break;
+	case QDF_GET_MSG_BUFF_FAILURE:
+		ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
+		break;
+	case QDF_ACTIVE_LIST_TIMEOUT:
+		ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
+		break;
+	case QDF_SUSPEND_TIMEOUT:
+		ret_val = QCA_WLAN_HANG_SUSPEND_TIMEOUT;
+		break;
+	case QDF_RESUME_TIMEOUT:
+		ret_val = QCA_WLAN_HANG_RESUME_TIMEOUT;
+		break;
+	case QDF_REASON_UNSPECIFIED:
+	default:
+		ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
+	}
+	return ret_val;
+}
+
+/**
+ * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
+ * @hdd_ctx: Pointer to hdd context
+ * @reason: cds recovery reason
+ *
+ * Return: 0 on success or failure reason
+ */
+int wlan_hdd_send_hang_reason_event(struct hdd_context *hdd_ctx,
+				    enum qdf_hang_reason reason)
+{
+	struct sk_buff *vendor_event;
+	enum qca_wlan_vendor_hang_reason hang_reason;
+
+	hdd_enter();
+
+	if (!hdd_ctx) {
+		hdd_err("HDD context is null");
+		return -EINVAL;
+	}
+
+	vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+						   NULL,
+						   sizeof(uint32_t),
+						   HANG_REASON_INDEX,
+						   GFP_KERNEL);
+	if (!vendor_event) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return -ENOMEM;
+	}
+
+	hang_reason = hdd_convert_hang_reason(reason);
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
+			(uint32_t)hang_reason)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
+		kfree_skb(vendor_event);
+		return -EINVAL;
+	}
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+
+	hdd_exit();
+	return 0;
+}
+
+#undef HANG_REASON_INDEX
+
+/**
+ * wlan_hdd_get_adjacent_chan(): Gets next/previous channel
+ * with respect to the channel passed.
+ * @chan: Channel
+ * @upper: If "true" then next channel is returned or else
+ * previous channel is returned.
+ *
+ * This function returns the next/previous adjacent-channel to
+ * the channel passed. If "upper = true" then next channel is
+ * returned else previous is returned.
+ */
+int wlan_hdd_get_adjacent_chan(uint8_t chan, bool upper)
+{
+	enum channel_enum ch_idx = reg_get_chan_enum(chan);
+
+	if (ch_idx == INVALID_CHANNEL)
+		return -EINVAL;
+
+	if (upper && (ch_idx < (NUM_CHANNELS - 1)))
+		ch_idx++;
+	else if (!upper && (ch_idx > CHAN_ENUM_1))
+		ch_idx--;
+	else
+		return -EINVAL;
+
+	return WLAN_REG_CH_NUM(ch_idx);
+}
+
+/**
+ * wlan_hdd_send_avoid_freq_for_dnbs(): Sends list of frequencies to be
+ * avoided when Do_Not_Break_Stream is active.
+ * @hdd_ctx:  HDD Context
+ * @op_chan:  AP/P2P-GO operating channel
+ *
+ * This function sends list of frequencies to be avoided when
+ * Do_Not_Break_Stream is active.
+ * To clear the avoid_frequency_list in the application,
+ * op_chan = 0 can be passed.
+ *
+ * Return: 0 on success and errno on failure
+ */
+int wlan_hdd_send_avoid_freq_for_dnbs(struct hdd_context *hdd_ctx, uint8_t op_chan)
+{
+	struct ch_avoid_ind_type p2p_avoid_freq_list;
+	uint8_t min_chan, max_chan;
+	int ret;
+	int chan;
+
+	hdd_enter();
+
+	if (!hdd_ctx) {
+		hdd_err("invalid param");
+		return -EINVAL;
+	}
+
+	qdf_mem_zero(&p2p_avoid_freq_list, sizeof(struct ch_avoid_ind_type));
+	/*
+	 * If channel passed is zero, clear the avoid_freq list in application.
+	 */
+	if (!op_chan) {
+#ifdef FEATURE_WLAN_CH_AVOID
+		mutex_lock(&hdd_ctx->avoid_freq_lock);
+		qdf_mem_zero(&hdd_ctx->dnbs_avoid_freq_list,
+				sizeof(struct ch_avoid_ind_type));
+		if (hdd_ctx->coex_avoid_freq_list.ch_avoid_range_cnt)
+			memcpy(&p2p_avoid_freq_list,
+			       &hdd_ctx->coex_avoid_freq_list,
+			       sizeof(struct ch_avoid_ind_type));
+		mutex_unlock(&hdd_ctx->avoid_freq_lock);
+#endif
+		ret = wlan_hdd_send_avoid_freq_event(hdd_ctx,
+						     &p2p_avoid_freq_list);
+		if (ret)
+			hdd_err("wlan_hdd_send_avoid_freq_event error:%d",
+				ret);
+
+		return ret;
+	}
+
+	if (WLAN_REG_IS_24GHZ_CH(op_chan)) {
+		min_chan = REG_MIN_24GHZ_CH_NUM;
+		max_chan = REG_MAX_24GHZ_CH_NUM;
+	} else if WLAN_REG_IS_5GHZ_CH(op_chan) {
+		min_chan = REG_MIN_5GHZ_CH_NUM;
+		max_chan = REG_MAX_5GHZ_CH_NUM;
+	} else {
+		hdd_err("invalid channel:%d", op_chan);
+		return -EINVAL;
+	}
+
+	if ((op_chan > min_chan) && (op_chan < max_chan)) {
+		p2p_avoid_freq_list.ch_avoid_range_cnt = 2;
+		p2p_avoid_freq_list.avoid_freq_range[0].start_freq =
+			wlan_chan_to_freq(min_chan);
+
+		/* Get channel before the op_chan */
+		chan = wlan_hdd_get_adjacent_chan(op_chan, false);
+		if (chan < 0)
+			return -EINVAL;
+		p2p_avoid_freq_list.avoid_freq_range[0].end_freq =
+			wlan_chan_to_freq(chan);
+
+		/* Get channel next to the op_chan */
+		chan = wlan_hdd_get_adjacent_chan(op_chan, true);
+		if (chan < 0)
+			return -EINVAL;
+		p2p_avoid_freq_list.avoid_freq_range[1].start_freq =
+			wlan_chan_to_freq(chan);
+
+		p2p_avoid_freq_list.avoid_freq_range[1].end_freq =
+			wlan_chan_to_freq(max_chan);
+	} else if (op_chan == min_chan) {
+		p2p_avoid_freq_list.ch_avoid_range_cnt = 1;
+
+		chan = wlan_hdd_get_adjacent_chan(op_chan, true);
+		if (chan < 0)
+			return -EINVAL;
+		p2p_avoid_freq_list.avoid_freq_range[0].start_freq =
+			wlan_chan_to_freq(chan);
+
+		p2p_avoid_freq_list.avoid_freq_range[0].end_freq =
+			wlan_chan_to_freq(max_chan);
+	} else {
+		p2p_avoid_freq_list.ch_avoid_range_cnt = 1;
+		p2p_avoid_freq_list.avoid_freq_range[0].start_freq =
+			wlan_chan_to_freq(min_chan);
+
+		chan = wlan_hdd_get_adjacent_chan(op_chan, false);
+		if (chan < 0)
+			return -EINVAL;
+		p2p_avoid_freq_list.avoid_freq_range[0].end_freq =
+			wlan_chan_to_freq(chan);
+	}
+#ifdef FEATURE_WLAN_CH_AVOID
+	mutex_lock(&hdd_ctx->avoid_freq_lock);
+	hdd_ctx->dnbs_avoid_freq_list = p2p_avoid_freq_list;
+	if (hdd_ctx->coex_avoid_freq_list.ch_avoid_range_cnt) {
+		ret = wlan_hdd_merge_avoid_freqs(&p2p_avoid_freq_list,
+				&hdd_ctx->coex_avoid_freq_list);
+		if (ret) {
+			mutex_unlock(&hdd_ctx->avoid_freq_lock);
+			hdd_err("avoid freq merge failed");
+			return ret;
+		}
+	}
+	mutex_unlock(&hdd_ctx->avoid_freq_lock);
+#endif
+	ret = wlan_hdd_send_avoid_freq_event(hdd_ctx, &p2p_avoid_freq_list);
+	if (ret)
+		hdd_err("wlan_hdd_send_avoid_freq_event error:%d", ret);
+
+	return ret;
+}
+
+/* vendor specific events */
+static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = {
+	[QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
+	},
+
+#ifdef WLAN_FEATURE_NAN
+	[QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_NAN
+	},
+#endif
+
+#ifdef WLAN_FEATURE_STATS_EXT
+	[QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_STATS_EXT
+	},
+#endif /* WLAN_FEATURE_STATS_EXT */
+#ifdef FEATURE_WLAN_EXTSCAN
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX] = {
+		.
+		vendor_id
+			=
+				QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX] = {
+		.
+		vendor_id
+			=
+				QCA_NL80211_VENDOR_ID,
+		.
+		subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX] = {
+		.
+		vendor_id
+			=
+				QCA_NL80211_VENDOR_ID,
+		.
+		subcmd
+			=
+				QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX] = {
+		.
+		vendor_id
+			=
+				QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX] = {
+		.
+		vendor_id
+			=
+				QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX] = {
+		.
+		vendor_id
+			=
+				QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX] = {
+		.
+		vendor_id
+			=
+				QCA_NL80211_VENDOR_ID,
+		.
+		subcmd
+			=
+				QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX] = {
+		.
+		vendor_id
+			=
+				QCA_NL80211_VENDOR_ID,
+		.
+		subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX] = {
+		.
+		vendor_id
+			=
+				QCA_NL80211_VENDOR_ID,
+		.
+		subcmd
+			=
+				QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX] = {
+		.
+		vendor_id
+			=
+				QCA_NL80211_VENDOR_ID,
+		.
+		subcmd
+			=
+				QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
+	},
+#endif /* FEATURE_WLAN_EXTSCAN */
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+	[QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT
+	},
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+	[QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_DO_ACS
+	},
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	[QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX] = {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH
+	},
+#endif
+	[QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX] =  {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX] =  {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED_INDEX] =  {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED_INDEX] =  {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX] =  {
+		.vendor_id =
+			QCA_NL80211_VENDOR_ID,
+		.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED
+	},
+#ifdef FEATURE_WLAN_EXTSCAN
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_NETWORK_FOUND_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_NETWORK_FOUND
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_PASSPOINT_NETWORK_FOUND_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_PASSPOINT_NETWORK_FOUND
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
+	},
+#endif /* FEATURE_WLAN_EXTSCAN */
+
+	FEATURE_RSSI_MONITOR_VENDOR_EVENTS
+
+#ifdef WLAN_FEATURE_TSF
+	[QCA_NL80211_VENDOR_SUBCMD_TSF_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_TSF
+	},
+#endif
+	[QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN
+	},
+	/* OCB events */
+	[QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT
+	},
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+	[QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG
+	},
+#endif /*FEATURE_LFR_SUBNET_DETECTION */
+
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+	[QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_NDP
+	},
+#endif /* WLAN_FEATURE_NAN_DATAPATH */
+
+	[QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_UPDATE_EXTERNAL_ACS_CONFIG] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_PWR_SAVE_FAIL_DETECTED_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
+	},
+	[QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO,
+	},
+#ifdef WLAN_UMAC_CONVERGENCE
+	COMMON_VENDOR_EVENTS
+#endif
+};
+
+/**
+ * __is_driver_dfs_capable() - get driver DFS capability
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This function is called by userspace to indicate whether or not
+ * the driver supports DFS offload.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __is_driver_dfs_capable(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data,
+				   int data_len)
+{
+	u32 dfs_capability = 0;
+	struct sk_buff *temp_skbuff;
+	int ret_val;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter_dev(wdev->netdev);
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		return ret_val;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) || \
+	defined(CFG80211_DFS_OFFLOAD_BACKPORT)
+	dfs_capability =
+		wiphy_ext_feature_isset(wiphy,
+					NL80211_EXT_FEATURE_DFS_OFFLOAD);
+#else
+	dfs_capability = !!(wiphy->flags & WIPHY_FLAG_DFS_OFFLOAD);
+#endif
+
+	temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
+							  NLMSG_HDRLEN);
+
+	if (temp_skbuff != NULL) {
+		ret_val = nla_put_u32(temp_skbuff, QCA_WLAN_VENDOR_ATTR_DFS,
+				      dfs_capability);
+		if (ret_val) {
+			hdd_err("QCA_WLAN_VENDOR_ATTR_DFS put fail");
+			kfree_skb(temp_skbuff);
+
+			return ret_val;
+		}
+
+		return cfg80211_vendor_cmd_reply(temp_skbuff);
+	}
+
+	hdd_err("dfs capability: buffer alloc fail");
+	return -ENOMEM;
+}
+
+/**
+ * is_driver_dfs_capable() - get driver DFS capability
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This function is called by userspace to indicate whether or not
+ * the driver supports DFS offload.  This is an SSR-protected
+ * wrapper function.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int is_driver_dfs_capable(struct wiphy *wiphy,
+				 struct wireless_dev *wdev,
+				 const void *data,
+				 int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __is_driver_dfs_capable(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_sap_cfg_dfs_override() - DFS MCC restriction check
+ *
+ * @adapter: SAP adapter pointer
+ *
+ * DFS in MCC is not supported for Multi bssid SAP mode due to single physical
+ * radio. So in case of DFS MCC scenario override current SAP given config
+ * to follow concurrent SAP DFS config
+ *
+ * Return: 0 - No DFS issue, 1 - Override done and negative error codes
+ */
+int wlan_hdd_sap_cfg_dfs_override(struct hdd_adapter *adapter)
+{
+	struct hdd_adapter *con_sap_adapter;
+	tsap_config_t *sap_config, *con_sap_config;
+	int con_ch;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	if (!hdd_ctx) {
+		hdd_err("hdd context is NULL");
+		return 0;
+	}
+
+	/*
+	 * Check if AP+AP case, once primary AP chooses a DFS
+	 * channel secondary AP should always follow primary APs channel
+	 */
+	if (!policy_mgr_concurrent_beaconing_sessions_running(
+		hdd_ctx->psoc))
+		return 0;
+
+	con_sap_adapter = hdd_get_con_sap_adapter(adapter, true);
+	if (!con_sap_adapter)
+		return 0;
+
+	sap_config = &adapter->session.ap.sap_config;
+	con_sap_config = &con_sap_adapter->session.ap.sap_config;
+	con_ch = con_sap_adapter->session.ap.operating_channel;
+
+	if (!wlan_reg_is_dfs_ch(hdd_ctx->pdev, con_ch))
+		return 0;
+
+	hdd_debug("Only SCC AP-AP DFS Permitted (ch=%d, con_ch=%d)",
+						sap_config->channel, con_ch);
+	hdd_debug("Overriding guest AP's channel");
+	sap_config->channel = con_ch;
+
+	if (con_sap_config->acs_cfg.acs_mode == true) {
+		if (con_ch != con_sap_config->acs_cfg.pri_ch &&
+				con_ch != con_sap_config->acs_cfg.ht_sec_ch) {
+			hdd_err("Primary AP channel config error");
+			hdd_err("Operating ch: %d ACS ch: %d %d",
+				con_ch, con_sap_config->acs_cfg.pri_ch,
+				con_sap_config->acs_cfg.ht_sec_ch);
+			return -EINVAL;
+		}
+		/* Sec AP ACS info is overwritten with Pri AP due to DFS
+		 * MCC restriction. So free ch list allocated in do_acs
+		 * func for Sec AP and realloc for Pri AP ch list size
+		 */
+		if (sap_config->acs_cfg.ch_list)
+			qdf_mem_free(sap_config->acs_cfg.ch_list);
+
+		qdf_mem_copy(&sap_config->acs_cfg,
+					&con_sap_config->acs_cfg,
+					sizeof(struct sap_acs_cfg));
+		sap_config->acs_cfg.ch_list = qdf_mem_malloc(
+					sizeof(uint8_t) *
+					con_sap_config->acs_cfg.ch_list_count);
+		if (!sap_config->acs_cfg.ch_list)
+			return -ENOMEM;
+
+		qdf_mem_copy(sap_config->acs_cfg.ch_list,
+					con_sap_config->acs_cfg.ch_list,
+					con_sap_config->acs_cfg.ch_list_count);
+
+	} else {
+		sap_config->acs_cfg.pri_ch = con_ch;
+		if (sap_config->acs_cfg.ch_width > eHT_CHANNEL_WIDTH_20MHZ)
+			sap_config->acs_cfg.ht_sec_ch = con_sap_config->sec_ch;
+	}
+
+	return con_ch;
+}
+
+/**
+ * wlan_hdd_set_acs_ch_range : Populate ACS hw mode and channel range values
+ * @sap_cfg: pointer to SAP config struct
+ * @hw_mode: hw mode retrieved from vendor command buffer
+ * @ht_enabled: whether HT phy mode is enabled
+ * @vht_enabled: whether VHT phy mode is enabled
+ *
+ * This function populates the ACS hw mode based on the configuration retrieved
+ * from the vendor command buffer; and sets ACS start and end channel for the
+ * given band.
+ *
+ * Return: 0 if success; -EINVAL if ACS channel list is NULL
+ */
+static int wlan_hdd_set_acs_ch_range(
+	tsap_config_t *sap_cfg, enum qca_wlan_vendor_acs_hw_mode hw_mode,
+	bool ht_enabled, bool vht_enabled)
+{
+	int i;
+
+	if (hw_mode == QCA_ACS_MODE_IEEE80211B) {
+		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11b;
+		sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_1);
+		sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_14);
+	} else if (hw_mode == QCA_ACS_MODE_IEEE80211G) {
+		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11g;
+		sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_1);
+		sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_13);
+	} else if (hw_mode == QCA_ACS_MODE_IEEE80211A) {
+		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11a;
+		sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_36);
+		sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_173);
+	} else if (hw_mode == QCA_ACS_MODE_IEEE80211ANY) {
+		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_abg;
+		sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_1);
+		sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_173);
+	}
+
+	if (ht_enabled)
+		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11n;
+
+	if (vht_enabled)
+		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11ac;
+
+	/* Parse ACS Chan list from hostapd */
+	if (!sap_cfg->acs_cfg.ch_list)
+		return -EINVAL;
+
+	sap_cfg->acs_cfg.start_ch = sap_cfg->acs_cfg.ch_list[0];
+	sap_cfg->acs_cfg.end_ch =
+		sap_cfg->acs_cfg.ch_list[sap_cfg->acs_cfg.ch_list_count - 1];
+	for (i = 0; i < sap_cfg->acs_cfg.ch_list_count; i++) {
+		/* avoid channel as start channel */
+		if (sap_cfg->acs_cfg.start_ch > sap_cfg->acs_cfg.ch_list[i] &&
+		    sap_cfg->acs_cfg.ch_list[i] != 0)
+			sap_cfg->acs_cfg.start_ch = sap_cfg->acs_cfg.ch_list[i];
+		if (sap_cfg->acs_cfg.end_ch < sap_cfg->acs_cfg.ch_list[i])
+			sap_cfg->acs_cfg.end_ch = sap_cfg->acs_cfg.ch_list[i];
+	}
+
+	return 0;
+}
+
+
+static void wlan_hdd_cfg80211_start_pending_acs(struct work_struct *work);
+
+
+static void hdd_update_acs_channel_list(tsap_config_t *sap_config,
+					enum band_info band)
+{
+	int i, temp_count = 0;
+	int acs_list_count = sap_config->acs_cfg.ch_list_count;
+
+	for (i = 0; i < acs_list_count; i++) {
+		if (BAND_2G == band) {
+			if (WLAN_REG_IS_24GHZ_CH(
+				sap_config->acs_cfg.ch_list[i])) {
+				sap_config->acs_cfg.ch_list[temp_count] =
+					sap_config->acs_cfg.ch_list[i];
+				temp_count++;
+			}
+		} else if (BAND_5G == band) {
+			if (WLAN_REG_IS_5GHZ_CH(
+				sap_config->acs_cfg.ch_list[i])) {
+				sap_config->acs_cfg.ch_list[temp_count] =
+					sap_config->acs_cfg.ch_list[i];
+				temp_count++;
+			}
+		}
+	}
+	sap_config->acs_cfg.ch_list_count = temp_count;
+}
+
+
+/**
+ * wlan_hdd_cfg80211_start_acs : Start ACS Procedure for SAP
+ * @adapter: pointer to SAP adapter struct
+ *
+ * This function starts the ACS procedure if there are no
+ * constraints like MBSSID DFS restrictions.
+ *
+ * Return: Status of ACS Start procedure
+ */
+int wlan_hdd_cfg80211_start_acs(struct hdd_adapter *adapter)
+{
+
+	struct hdd_context *hdd_ctx;
+	tsap_config_t *sap_config;
+	tpWLAN_SAPEventCB acs_event_callback;
+	uint8_t mcc_to_scc_switch = 0;
+	int status;
+
+	if (!adapter) {
+		hdd_err("adapter is NULL");
+		return -EINVAL;
+	}
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is NULL");
+		return -EINVAL;
+	}
+	sap_config = &adapter->session.ap.sap_config;
+	if (!sap_config) {
+		hdd_err("SAP config is NULL");
+		return -EINVAL;
+	}
+	if (hdd_ctx->acs_policy.acs_channel)
+		sap_config->channel = hdd_ctx->acs_policy.acs_channel;
+	else
+		sap_config->channel = AUTO_CHANNEL_SELECT;
+	ucfg_policy_mgr_get_mcc_scc_switch(hdd_ctx->psoc,
+					   &mcc_to_scc_switch);
+	/*
+	 * No DFS SCC is allowed in Auto use case. Hence not
+	 * calling DFS override
+	 */
+	if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION !=
+	    mcc_to_scc_switch) {
+		status = wlan_hdd_sap_cfg_dfs_override(adapter);
+		if (status < 0)
+			return status;
+
+		if (status > 0) {
+			/*notify hostapd about channel override */
+			wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
+			clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
+			return 0;
+		}
+	}
+	/* When first 2 connections are on the same frequency band,
+	 * then PCL would include only channels from the other
+	 * frequency band on which no connections are active
+	 */
+	if ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 2) &&
+		(sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211ANY)) {
+		struct policy_mgr_conc_connection_info *conc_connection_info;
+		uint32_t i;
+
+		conc_connection_info = policy_mgr_get_conn_info(&i);
+		if (conc_connection_info[0].mac ==
+			conc_connection_info[1].mac) {
+			if (WLAN_REG_IS_5GHZ_CH(sap_config->acs_cfg.
+				pcl_channels[0])) {
+				sap_config->acs_cfg.band =
+					QCA_ACS_MODE_IEEE80211A;
+				hdd_update_acs_channel_list(sap_config,
+					BAND_5G);
+			} else {
+				sap_config->acs_cfg.band =
+					QCA_ACS_MODE_IEEE80211G;
+				hdd_update_acs_channel_list(sap_config,
+					BAND_2G);
+			}
+		}
+	}
+	status = wlan_hdd_config_acs(hdd_ctx, adapter);
+	if (status) {
+		hdd_err("ACS config failed");
+		return -EINVAL;
+	}
+
+	acs_event_callback = hdd_hostapd_sap_event_cb;
+
+	qdf_mem_copy(sap_config->self_macaddr.bytes,
+		adapter->mac_addr.bytes, sizeof(struct qdf_mac_addr));
+	hdd_info("ACS Started for %s", adapter->dev->name);
+	status = wlansap_acs_chselect(
+		WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+		acs_event_callback, sap_config, adapter->dev);
+
+
+	if (status) {
+		hdd_err("ACS channel select failed");
+		return -EINVAL;
+	}
+	if (sap_is_auto_channel_select(WLAN_HDD_GET_SAP_CTX_PTR(adapter)))
+		sap_config->acs_cfg.acs_mode = true;
+	set_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
+
+	return 0;
+}
+
+/**
+ * hdd_update_vendor_pcl_list() - This API will return unsorted pcl list
+ * @hdd_ctx: hdd context
+ * @acs_chan_params: external acs channel params
+ * @sap_config: SAP config
+ *
+ * This API provides unsorted pcl list.
+ * this list is a subset of the valid channel list given by hostapd.
+ * if channel is not present in pcl, weightage will be given as zero
+ *
+ * Return: Zero on success, non-zero on failure
+ */
+static void hdd_update_vendor_pcl_list(struct hdd_context *hdd_ctx,
+		struct hdd_vendor_acs_chan_params *acs_chan_params,
+		tsap_config_t *sap_config)
+{
+	int i, j;
+	/*
+	 * PCL shall contain only the preferred channels from the
+	 * application. If those channels are not present in the
+	 * driver PCL, then set the weight to zero
+	 */
+	for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) {
+		acs_chan_params->vendor_pcl_list[i] =
+			sap_config->acs_cfg.ch_list[i];
+		acs_chan_params->vendor_weight_list[i] = 0;
+		for (j = 0; j < sap_config->acs_cfg.pcl_ch_count; j++) {
+			if (sap_config->acs_cfg.ch_list[i] ==
+			sap_config->acs_cfg.pcl_channels[j]) {
+				acs_chan_params->vendor_weight_list[i] =
+				sap_config->
+				acs_cfg.pcl_channels_weight_list[j];
+				break;
+			}
+		}
+	}
+	acs_chan_params->pcl_count = sap_config->acs_cfg.ch_list_count;
+}
+
+/**
+ * hdd_update_reg_chan_info : This API contructs channel info
+ * for all the given channel
+ * @adapter: pointer to SAP adapter struct
+ * @channel_count: channel count
+ * @channel_list: channel list
+ *
+ * Return: Status of of channel information updation
+ */
+static int hdd_update_reg_chan_info(struct hdd_adapter *adapter,
+			uint32_t channel_count,
+			uint8_t *channel_list)
+{
+	int i;
+	struct hdd_channel_info *icv;
+	struct ch_params ch_params = {0};
+	uint8_t bw_offset = 0, chan = 0;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	tsap_config_t *sap_config = &adapter->session.ap.sap_config;
+	mac_handle_t mac_handle;
+	uint8_t sub_20_chan_width = 0;
+	QDF_STATUS status;
+
+	mac_handle = hdd_ctx->mac_handle;
+	sap_config->channel_info_count = channel_count;
+
+	status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
+						 &sub_20_chan_width);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to get sub_20_chan_width config");
+
+	for (i = 0; i < channel_count; i++) {
+		icv = &sap_config->channel_info[i];
+		chan = channel_list[i];
+
+		if (chan == 0)
+			continue;
+
+		if (sap_config->acs_cfg.ch_width == CH_WIDTH_40MHZ)
+			bw_offset = 1 << BW_40_OFFSET_BIT;
+		else if (sap_config->acs_cfg.ch_width == CH_WIDTH_20MHZ)
+			bw_offset = 1 << BW_20_OFFSET_BIT;
+		icv->freq = wlan_reg_get_channel_freq(hdd_ctx->pdev, chan);
+		icv->ieee_chan_number = chan;
+		icv->max_reg_power = wlan_reg_get_channel_reg_power(
+				hdd_ctx->pdev, chan);
+
+		/* filling demo values */
+		icv->max_radio_power = HDD_MAX_TX_POWER;
+		icv->min_radio_power = HDD_MIN_TX_POWER;
+		/* not supported in current driver */
+		icv->max_antenna_gain = 0;
+
+		icv->reg_class_id =
+			wlan_hdd_find_opclass(mac_handle, chan, bw_offset);
+
+		if (WLAN_REG_IS_5GHZ_CH(chan)) {
+			ch_params.ch_width = sap_config->acs_cfg.ch_width;
+			wlan_reg_set_channel_params(hdd_ctx->pdev, chan,
+						    0, &ch_params);
+			icv->vht_center_freq_seg0 = ch_params.center_freq_seg0;
+			icv->vht_center_freq_seg1 = ch_params.center_freq_seg1;
+		}
+
+		icv->flags = 0;
+		icv->flags = cds_get_vendor_reg_flags(hdd_ctx->pdev, chan,
+				sap_config->acs_cfg.ch_width,
+				sap_config->acs_cfg.is_ht_enabled,
+				sap_config->acs_cfg.is_vht_enabled,
+				sub_20_chan_width);
+		if (icv->flags & IEEE80211_CHAN_PASSIVE)
+			icv->flagext |= IEEE80211_CHAN_DFS;
+
+		hdd_debug("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,
+			icv->flagext, icv->ieee_chan_number,
+			icv->max_reg_power, icv->max_radio_power,
+			icv->min_radio_power, icv->reg_class_id,
+			icv->max_antenna_gain, icv->vht_center_freq_seg0,
+			icv->vht_center_freq_seg1);
+	}
+	return 0;
+}
+
+/* Short name for QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO event */
+#define CHAN_INFO_ATTR_FLAGS \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS
+#define CHAN_INFO_ATTR_FLAG_EXT \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAG_EXT
+#define CHAN_INFO_ATTR_FREQ \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ
+#define CHAN_INFO_ATTR_MAX_REG_POWER \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_REG_POWER
+#define CHAN_INFO_ATTR_MAX_POWER \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_POWER
+#define CHAN_INFO_ATTR_MIN_POWER \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MIN_POWER
+#define CHAN_INFO_ATTR_REG_CLASS_ID \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_REG_CLASS_ID
+#define CHAN_INFO_ATTR_ANTENNA_GAIN \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_ANTENNA_GAIN
+#define CHAN_INFO_ATTR_VHT_SEG_0 \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0
+#define CHAN_INFO_ATTR_VHT_SEG_1 \
+	QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1
+
+/**
+ * hdd_cfg80211_update_channel_info() - add channel info attributes
+ * @skb: pointer to sk buff
+ * @hdd_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t
+hdd_cfg80211_update_channel_info(struct sk_buff *skb,
+			   tsap_config_t *sap_config, int idx)
+{
+	struct nlattr *nla_attr, *channel;
+	struct hdd_channel_info *icv;
+	int i;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr)
+		goto fail;
+
+	for (i = 0; i < sap_config->channel_info_count; i++) {
+		channel = nla_nest_start(skb, i);
+		if (!channel)
+			goto fail;
+
+		icv = &sap_config->channel_info[i];
+		if (!icv) {
+			hdd_err("channel info not found");
+			goto fail;
+		}
+		if (nla_put_u16(skb, CHAN_INFO_ATTR_FREQ,
+				icv->freq) ||
+		    nla_put_u32(skb, CHAN_INFO_ATTR_FLAGS,
+				icv->flags) ||
+		    nla_put_u32(skb, CHAN_INFO_ATTR_FLAG_EXT,
+				icv->flagext) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_MAX_REG_POWER,
+				icv->max_reg_power) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_MAX_POWER,
+				icv->max_radio_power) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_MIN_POWER,
+				icv->min_radio_power) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_REG_CLASS_ID,
+				icv->reg_class_id) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_ANTENNA_GAIN,
+				icv->max_antenna_gain) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_VHT_SEG_0,
+				icv->vht_center_freq_seg0) ||
+		    nla_put_u8(skb, CHAN_INFO_ATTR_VHT_SEG_1,
+				icv->vht_center_freq_seg1)) {
+			hdd_err("put fail");
+			goto fail;
+		}
+		nla_nest_end(skb, channel);
+	}
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	hdd_err("nl channel update failed");
+	return -EINVAL;
+}
+#undef CHAN_INFO_ATTR_FLAGS
+#undef CHAN_INFO_ATTR_FLAG_EXT
+#undef CHAN_INFO_ATTR_FREQ
+#undef CHAN_INFO_ATTR_MAX_REG_POWER
+#undef CHAN_INFO_ATTR_MAX_POWER
+#undef CHAN_INFO_ATTR_MIN_POWER
+#undef CHAN_INFO_ATTR_REG_CLASS_ID
+#undef CHAN_INFO_ATTR_ANTENNA_GAIN
+#undef CHAN_INFO_ATTR_VHT_SEG_0
+#undef CHAN_INFO_ATTR_VHT_SEG_1
+
+/**
+ * hdd_cfg80211_update_pcl() - add pcl info attributes
+ * @skb: pointer to sk buff
+ * @hdd_ctx: pointer to hdd station context
+ * @idx: attribute index
+ * @vendor_pcl_list: PCL list
+ * @vendor_weight_list: PCL weights
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t
+hdd_cfg80211_update_pcl(struct sk_buff *skb,
+			uint8_t ch_list_count, int idx,
+			uint8_t *vendor_pcl_list, uint8_t *vendor_weight_list)
+{
+	struct nlattr *nla_attr, *channel;
+	int i;
+
+	nla_attr = nla_nest_start(skb, idx);
+
+	if (!nla_attr)
+		goto fail;
+
+	for (i = 0; i < ch_list_count; i++) {
+		channel = nla_nest_start(skb, i);
+		if (!channel)
+			goto fail;
+		if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_PCL_CHANNEL,
+			       vendor_pcl_list[i]) ||
+		    nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_PCL_WEIGHT,
+			       vendor_weight_list[i])) {
+			hdd_err("put fail");
+			goto fail;
+		}
+		nla_nest_end(skb, channel);
+	}
+	nla_nest_end(skb, nla_attr);
+
+	return 0;
+fail:
+	hdd_err("updating pcl list failed");
+	return -EINVAL;
+}
+
+static void hdd_get_scan_band(struct hdd_context *hdd_ctx,
+			      tsap_config_t *sap_config,
+			      enum band_info *band)
+{
+	/* Get scan band */
+	if ((sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211B) ||
+	   (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211G)) {
+		*band = BAND_2G;
+	} else if (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211A) {
+		*band = BAND_5G;
+	} else if (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211ANY) {
+		*band = BAND_ALL;
+	}
+}
+
+
+/**
+ * hdd_get_freq_list: API to get Frequency list based on channel list
+ * @channel_list: channel list
+ * @freq_list: frequency list
+ * @channel_count: channel count
+ *
+ * Return: None
+ */
+static void hdd_get_freq_list(uint8_t *channel_list, uint32_t *freq_list,
+				uint32_t channel_count)
+{
+	int count;
+
+	for (count = 0; count < channel_count ; count++)
+		freq_list[count] = cds_chan_to_freq(channel_list[count]);
+}
+
+/**
+ * wlan_hdd_sap_get_valid_channellist() - Get SAPs valid channel list
+ * @ap_adapter: adapter
+ * @channel_count: valid channel count
+ * @channel_list: valid channel list
+ * @band: frequency band
+ *
+ * This API returns valid channel list for SAP after removing nol and
+ * channel which lies outside of configuration.
+ *
+ * Return: Zero on success, non-zero on failure
+ */
+static int wlan_hdd_sap_get_valid_channellist(struct hdd_adapter *adapter,
+					      uint32_t *channel_count,
+					      uint8_t *channel_list,
+					      enum band_info band)
+{
+	tsap_config_t *sap_config;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	uint8_t tmp_chan_list[QDF_MAX_NUM_CHAN] = {0};
+	uint32_t chan_count;
+	uint8_t i;
+	QDF_STATUS status;
+	struct wlan_objmgr_pdev *pdev = hdd_ctx->pdev;
+	uint8_t tmp_chan;
+
+	sap_config = &adapter->session.ap.sap_config;
+
+	status =
+		policy_mgr_get_valid_chans(hdd_ctx->psoc,
+					   tmp_chan_list,
+					   &chan_count);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get channel list");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < chan_count; i++) {
+		tmp_chan = tmp_chan_list[i];
+		if (*channel_count < QDF_MAX_NUM_CHAN) {
+			if ((band == BAND_2G) &&
+			    (WLAN_REG_IS_24GHZ_CH(tmp_chan)) &&
+			    (!wlan_reg_is_disable_ch(pdev, tmp_chan))) {
+				channel_list[*channel_count] = tmp_chan;
+				*channel_count += 1;
+			} else if ((band == BAND_5G) &&
+				(WLAN_REG_IS_5GHZ_CH(tmp_chan)) &&
+				(!wlan_reg_is_disable_ch(pdev, tmp_chan))) {
+				channel_list[*channel_count] = tmp_chan;
+				*channel_count += 1;
+			}
+		} else {
+			break;
+		}
+	}
+
+	if (*channel_count == 0) {
+		hdd_err("no valid channel found");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter,
+				   uint8_t reason)
+{
+	struct sk_buff *skb;
+	tsap_config_t *sap_config;
+	uint32_t channel_count = 0, status = -EINVAL;
+	uint8_t channel_list[QDF_MAX_NUM_CHAN] = {0};
+	uint32_t freq_list[QDF_MAX_NUM_CHAN] = {0};
+	uint8_t vendor_pcl_list[QDF_MAX_NUM_CHAN] = {0};
+	uint8_t vendor_weight_list[QDF_MAX_NUM_CHAN] = {0};
+	struct hdd_vendor_acs_chan_params acs_chan_params;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	enum band_info band = BAND_2G;
+	eCsrPhyMode phy_mode;
+	enum qca_wlan_vendor_attr_external_acs_policy acs_policy;
+	uint32_t i;
+	QDF_STATUS qdf_status;
+	bool is_external_acs_policy = cfg_default(CFG_EXTERNAL_ACS_POLICY);
+
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return -EINVAL;
+	}
+
+	hdd_enter();
+	sap_config = &adapter->session.ap.sap_config;
+	/* When first 2 connections are on the same frequency band,
+	 * then PCL would include only channels from the other
+	 * frequency band on which no connections are active
+	 */
+	if ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 2) &&
+	    (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211ANY)) {
+		struct policy_mgr_conc_connection_info	*conc_connection_info;
+
+		conc_connection_info = policy_mgr_get_conn_info(&i);
+		if (conc_connection_info[0].mac ==
+			conc_connection_info[1].mac) {
+
+			if (WLAN_REG_IS_5GHZ_CH(sap_config->acs_cfg.
+				pcl_channels[0])) {
+				sap_config->acs_cfg.band =
+					QCA_ACS_MODE_IEEE80211A;
+				hdd_update_acs_channel_list(sap_config,
+					BAND_5G);
+			} else {
+				sap_config->acs_cfg.band =
+					QCA_ACS_MODE_IEEE80211G;
+				hdd_update_acs_channel_list(sap_config,
+					BAND_2G);
+			}
+		}
+	}
+
+	hdd_get_scan_band(hdd_ctx, &adapter->session.ap.sap_config, &band);
+
+	if (sap_config->acs_cfg.ch_list) {
+		/* Copy INI or hostapd provided ACS channel range*/
+		qdf_mem_copy(channel_list, sap_config->acs_cfg.ch_list,
+				sap_config->acs_cfg.ch_list_count);
+		channel_count = sap_config->acs_cfg.ch_list_count;
+	} else {
+		/* No channel list provided, copy all valid channels */
+		wlan_hdd_sap_get_valid_channellist(adapter,
+			&channel_count,
+			channel_list,
+			band);
+	}
+
+	sap_config->channel_info = qdf_mem_malloc(
+					sizeof(struct hdd_channel_info) *
+					channel_count);
+	if (!sap_config->channel_info)
+		return -ENOMEM;
+
+	hdd_update_reg_chan_info(adapter, channel_count, channel_list);
+	hdd_get_freq_list(channel_list, freq_list, channel_count);
+	/* Get phymode */
+	phy_mode = adapter->session.ap.sap_config.acs_cfg.hw_mode;
+
+	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+			&(adapter->wdev),
+			EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
+			QCA_NL80211_VENDOR_SUBCMD_UPDATE_EXTERNAL_ACS_CONFIG,
+			GFP_KERNEL);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		qdf_mem_free(sap_config->channel_info);
+		return -ENOMEM;
+	}
+	/*
+	 * Application expects pcl to be a subset of channel list
+	 * Remove all channels which are not in channel list from pcl
+	 * and add weight as zero
+	 */
+	acs_chan_params.channel_count = channel_count;
+	acs_chan_params.channel_list = channel_list;
+	acs_chan_params.vendor_pcl_list = vendor_pcl_list;
+	acs_chan_params.vendor_weight_list = vendor_weight_list;
+
+	hdd_update_vendor_pcl_list(hdd_ctx, &acs_chan_params,
+				   sap_config);
+
+	if (acs_chan_params.channel_count) {
+		hdd_debug("ACS channel list: len: %d",
+			  acs_chan_params.channel_count);
+		for (i = 0; i < acs_chan_params.channel_count; i++)
+			hdd_debug("%d ", acs_chan_params.channel_list[i]);
+	}
+
+	if (acs_chan_params.pcl_count) {
+		hdd_debug("ACS PCL list: len: %d",
+			  acs_chan_params.pcl_count);
+		for (i = 0; i < acs_chan_params.pcl_count; i++)
+			hdd_debug("channel:%d, weight:%d ",
+				  acs_chan_params.
+				  vendor_pcl_list[i],
+				  acs_chan_params.
+				  vendor_weight_list[i]);
+	}
+
+	qdf_status = ucfg_mlme_get_external_acs_policy(hdd_ctx->psoc,
+						       &is_external_acs_policy);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		hdd_err("get_external_acs_policy failed, set default");
+
+	if (is_external_acs_policy) {
+		acs_policy =
+			QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_MANDATORY;
+	} else {
+		acs_policy =
+			QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_PREFERRED;
+	}
+	/* Update values in NL buffer */
+	if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_REASON,
+		       reason) ||
+	    nla_put_flag(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_IS_OFFLOAD_ENABLED) ||
+	    nla_put_flag(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_ADD_CHAN_STATS_SUPPORT)
+		||
+	    nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_WIDTH,
+		       sap_config->acs_cfg.ch_width) ||
+	    nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_BAND,
+		       band) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PHY_MODE,
+		       phy_mode) ||
+	    nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_FREQ_LIST,
+		    channel_count * sizeof(uint32_t), freq_list)) {
+		hdd_err("nla put fail");
+		goto fail;
+	}
+	status =
+	hdd_cfg80211_update_pcl(skb,
+				acs_chan_params.
+				pcl_count,
+				QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL,
+				vendor_pcl_list,
+				vendor_weight_list);
+
+	if (status != 0)
+		goto fail;
+
+	status = hdd_cfg80211_update_channel_info(skb, sap_config,
+			QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO);
+
+	if (status != 0)
+		goto fail;
+
+	status = nla_put_u32(skb,
+			     QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_POLICY,
+			     acs_policy);
+
+	if (status != 0)
+		goto fail;
+
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+	qdf_mem_free(sap_config->channel_info);
+
+	return 0;
+fail:
+	qdf_mem_free(sap_config->channel_info);
+	if (skb)
+		kfree_skb(skb);
+	return status;
+}
+
+/**
+ * hdd_create_acs_timer(): Initialize vendor ACS timer
+ * @adapter: pointer to SAP adapter struct
+ *
+ * This function initializes the vendor ACS timer.
+ *
+ * Return: Status of create vendor ACS timer
+ */
+static int hdd_create_acs_timer(struct hdd_adapter *adapter)
+{
+	struct hdd_external_acs_timer_context *timer_context;
+	QDF_STATUS status;
+
+	if (adapter->session.ap.vendor_acs_timer_initialized)
+		return 0;
+
+	hdd_debug("Starting vendor app based ACS");
+	timer_context = qdf_mem_malloc(sizeof(*timer_context));
+	if (!timer_context)
+		return -ENOMEM;
+
+	timer_context->adapter = adapter;
+
+	set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
+	status = qdf_mc_timer_init(&adapter->session.ap.vendor_acs_timer,
+		  QDF_TIMER_TYPE_SW,
+		  hdd_acs_response_timeout_handler, timer_context);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to initialize acs response timeout timer");
+		return -EFAULT;
+	}
+	adapter->session.ap.vendor_acs_timer_initialized = true;
+	return 0;
+}
+
+static const struct nla_policy
+wlan_hdd_cfg80211_do_acs_policy[QCA_WLAN_VENDOR_ATTR_ACS_MAX+1] = {
+	[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE] = { .type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED] = { .type = NLA_FLAG },
+	[QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED] = { .type = NLA_FLAG },
+	[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED] = { .type = NLA_FLAG },
+	[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH] = { .type = NLA_U16 },
+	[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST] = { .type = NLA_UNSPEC },
+	[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST] = { .type = NLA_UNSPEC },
+};
+
+int hdd_start_vendor_acs(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int status;
+	QDF_STATUS qdf_status;
+	bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE);
+
+	status = hdd_create_acs_timer(adapter);
+	if (status != 0) {
+		hdd_err("failed to create acs timer");
+		return status;
+	}
+	status = hdd_update_acs_timer_reason(adapter,
+		QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT);
+	if (status != 0) {
+		hdd_err("failed to update acs timer reason");
+		return status;
+	}
+	qdf_status = ucfg_mlme_get_acs_support_for_dfs_ltecoex(
+				hdd_ctx->psoc,
+				&is_acs_support_for_dfs_ltecoex);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		hdd_err("get_acs_support_for_dfs_ltecoex failed, set def");
+
+	if (is_acs_support_for_dfs_ltecoex)
+		status = qdf_status_to_os_return(wlan_sap_set_vendor_acs(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+				true));
+	else
+		status = qdf_status_to_os_return(wlan_sap_set_vendor_acs(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+				false));
+
+	return status;
+}
+
+/**
+ * __wlan_hdd_cfg80211_do_acs(): CFG80211 handler function for DO_ACS Vendor CMD
+ * @wiphy:  Linux wiphy struct pointer
+ * @wdev:   Linux wireless device struct pointer
+ * @data:   ACS information from hostapd
+ * @data_len: ACS information length
+ *
+ * This function handle DO_ACS Vendor command from hostapd, parses ACS config
+ * and starts ACS procedure.
+ *
+ * Return: ACS procedure start status
+ */
+static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data, int data_len)
+{
+	struct net_device *ndev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	tsap_config_t *sap_config;
+	struct sk_buff *temp_skbuff;
+	int ret, i, ch_cnt = 0;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
+	bool ht_enabled, ht40_enabled, vht_enabled;
+	uint8_t ch_width;
+	enum qca_wlan_vendor_acs_hw_mode hw_mode;
+	QDF_STATUS qdf_status;
+	uint8_t conc_channel;
+	mac_handle_t mac_handle;
+	bool skip_etsi13_srd_chan = false;
+	uint32_t auto_channel_select_weight =
+		cfg_default(CFG_AUTO_CHANNEL_SELECT_WEIGHT);
+	bool is_vendor_acs_support =
+		cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
+	bool is_external_acs_policy =
+		cfg_default(CFG_EXTERNAL_ACS_POLICY);
+
+	/* ***Note*** Donot set SME config related to ACS operation here because
+	 * ACS operation is not synchronouse and ACS for Second AP may come when
+	 * ACS operation for first AP is going on. So only do_acs is split to
+	 * separate start_acs routine. Also SME-PMAC struct that is used to
+	 * pass paremeters from HDD to SAP is global. Thus All ACS related SME
+	 * config shall be set only from start_acs.
+	 */
+
+	hdd_enter_dev(ndev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	hdd_debug("current country is %s", hdd_ctx->reg.alpha2);
+
+	if (!((adapter->device_mode == QDF_SAP_MODE) ||
+	      (adapter->device_mode == QDF_P2P_GO_MODE))) {
+		hdd_err("Invalid device mode %d", adapter->device_mode);
+		return -EINVAL;
+	}
+
+	if (cds_is_sub_20_mhz_enabled()) {
+		hdd_err("ACS not supported in sub 20 MHz ch wd.");
+		return -EINVAL;
+	}
+
+	if (qdf_atomic_read(&adapter->session.ap.acs_in_progress) > 0) {
+		hdd_err("ACS rejected as previous req already in progress");
+		return -EINVAL;
+	} else {
+		qdf_atomic_set(&adapter->session.ap.acs_in_progress, 1);
+	}
+
+	ret = wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX, data,
+					 data_len,
+					 wlan_hdd_cfg80211_do_acs_policy);
+	if (ret) {
+		hdd_err("Invalid ATTR");
+		goto out;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
+		hdd_err("Attr hw_mode failed");
+		ret = -EINVAL;
+		goto out;
+	}
+	hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED])
+		ht_enabled =
+			nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED]);
+	else
+		ht_enabled = 0;
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED])
+		ht40_enabled =
+			nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED]);
+	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]);
+	else
+		vht_enabled = 0;
+
+	if (((adapter->device_mode == QDF_SAP_MODE) &&
+	     (hdd_ctx->config->sap_force_11n_for_11ac)) ||
+	     ((adapter->device_mode == QDF_P2P_GO_MODE) &&
+	     (hdd_ctx->config->go_force_11n_for_11ac))) {
+		vht_enabled = 0;
+		hdd_info("VHT is Disabled in ACS");
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]) {
+		ch_width = nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]);
+	} else {
+		if (ht_enabled && ht40_enabled)
+			ch_width = 40;
+		else
+			ch_width = 20;
+	}
+
+	/* this may be possible, when sap_force_11n_for_11ac or
+	 * go_force_11n_for_11ac is set
+	 */
+	if ((ch_width == 80 || ch_width == 160) && !vht_enabled) {
+		if (ht_enabled && ht40_enabled)
+			ch_width = 40;
+		else
+			ch_width = 20;
+	}
+
+	sap_config = &adapter->session.ap.sap_config;
+
+	/* Check and free if memory is already allocated for acs channel list */
+	wlan_hdd_undo_acs(adapter);
+
+	qdf_mem_zero(&sap_config->acs_cfg, sizeof(struct sap_acs_cfg));
+
+	hdd_debug("channel width =%d", ch_width);
+	if (ch_width == 160)
+		sap_config->acs_cfg.ch_width = CH_WIDTH_160MHZ;
+	else if (ch_width == 80)
+		sap_config->acs_cfg.ch_width = CH_WIDTH_80MHZ;
+	else if (ch_width == 40)
+		sap_config->acs_cfg.ch_width = CH_WIDTH_40MHZ;
+	else
+		sap_config->acs_cfg.ch_width = CH_WIDTH_20MHZ;
+
+	/* hw_mode = a/b/g: QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST and
+	 * QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST attrs are present, and
+	 * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST is used for obtaining the
+	 * channel list, QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST is ignored
+	 * since it contains the frequency values of the channels in
+	 * the channel list.
+	 * hw_mode = any: only QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST attr
+	 * is present
+	 */
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]) {
+		char *tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]);
+
+		sap_config->acs_cfg.ch_list_count = nla_len(
+					tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]);
+		if (sap_config->acs_cfg.ch_list_count) {
+			sap_config->acs_cfg.ch_list = qdf_mem_malloc(
+					sizeof(uint8_t) *
+					sap_config->acs_cfg.ch_list_count);
+			if (!sap_config->acs_cfg.ch_list) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			qdf_mem_copy(sap_config->acs_cfg.ch_list, tmp,
+					sap_config->acs_cfg.ch_list_count);
+		}
+	} else if (tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]) {
+		uint32_t *freq =
+			nla_data(tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]);
+		sap_config->acs_cfg.ch_list_count = nla_len(
+			tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]) /
+				sizeof(uint32_t);
+		if (sap_config->acs_cfg.ch_list_count) {
+			sap_config->acs_cfg.ch_list = qdf_mem_malloc(
+				sap_config->acs_cfg.ch_list_count);
+			if (!sap_config->acs_cfg.ch_list) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			/* convert frequency to channel */
+			for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++)
+				sap_config->acs_cfg.ch_list[i] =
+					ieee80211_frequency_to_channel(freq[i]);
+		}
+	}
+
+	if (!sap_config->acs_cfg.ch_list_count) {
+		hdd_err("acs config chan count 0");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	skip_etsi13_srd_chan =
+		!hdd_ctx->config->etsi13_srd_chan_in_master_mode &&
+		wlan_reg_is_etsi13_regdmn(hdd_ctx->pdev);
+
+	if (skip_etsi13_srd_chan) {
+		for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) {
+			if (wlan_reg_is_etsi13_srd_chan(hdd_ctx->pdev,
+							sap_config->acs_cfg.
+							ch_list[i]))
+				sap_config->acs_cfg.ch_list[i] = 0;
+			else
+				sap_config->acs_cfg.ch_list[ch_cnt++] =
+						sap_config->acs_cfg.ch_list[i];
+		}
+		sap_config->acs_cfg.ch_list_count = ch_cnt;
+	}
+	hdd_debug("get pcl for DO_ACS vendor command");
+
+	/* consult policy manager to get PCL */
+	qdf_status = policy_mgr_get_pcl(hdd_ctx->psoc, PM_SAP_MODE,
+				sap_config->acs_cfg.pcl_channels,
+				&sap_config->acs_cfg.pcl_ch_count,
+				sap_config->acs_cfg.pcl_channels_weight_list,
+				QDF_MAX_NUM_CHAN);
+	if (qdf_status != QDF_STATUS_SUCCESS)
+		hdd_err("Get PCL failed");
+
+	if (sap_config->acs_cfg.pcl_ch_count) {
+		hdd_debug("ACS config PCL: len: %d",
+			  sap_config->acs_cfg.pcl_ch_count);
+		for (i = 0; i < sap_config->acs_cfg.pcl_ch_count; i++)
+			hdd_debug("channel:%d, weight:%d ",
+				  sap_config->acs_cfg.
+				  pcl_channels[i],
+				  sap_config->acs_cfg.
+				  pcl_channels_weight_list[i]);
+	}
+
+	if (hw_mode == QCA_ACS_MODE_IEEE80211ANY)
+		policy_mgr_trim_acs_channel_list(hdd_ctx->psoc,
+			sap_config->acs_cfg.ch_list,
+			&sap_config->acs_cfg.ch_list_count);
+
+	sap_config->acs_cfg.band = hw_mode;
+	ret = wlan_hdd_set_acs_ch_range(sap_config, hw_mode,
+					   ht_enabled, vht_enabled);
+	if (ret) {
+		hdd_err("set acs channel range failed");
+		goto out;
+	}
+
+	/* ACS override for android */
+	if (ht_enabled &&
+	    sap_config->acs_cfg.end_ch >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
+	    ((adapter->device_mode == QDF_SAP_MODE &&
+	      !hdd_ctx->config->sap_force_11n_for_11ac &&
+	      hdd_ctx->config->sap_11ac_override) ||
+	      (adapter->device_mode == QDF_P2P_GO_MODE &&
+	      !hdd_ctx->config->go_force_11n_for_11ac &&
+	      hdd_ctx->config->go_11ac_override))) {
+		vht_enabled = 1;
+		sap_config->acs_cfg.hw_mode = eCSR_DOT11_MODE_11ac;
+		qdf_status =
+			ucfg_mlme_get_vht_channel_width(hdd_ctx->psoc,
+							&ch_width);
+		sap_config->acs_cfg.ch_width = ch_width;
+	}
+
+	/* 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;
+		hdd_debug("resetting to 40Mhz in 2.4Ghz");
+	}
+
+	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,
+		sap_config->acs_cfg.ch_width, ht_enabled, vht_enabled,
+		sap_config->acs_cfg.start_ch, sap_config->acs_cfg.end_ch,
+		sap_config->acs_cfg.band);
+	host_log_acs_req_event(adapter->dev->name,
+			  csr_phy_mode_str(sap_config->acs_cfg.hw_mode),
+			  ch_width, ht_enabled, vht_enabled,
+			  sap_config->acs_cfg.start_ch,
+			  sap_config->acs_cfg.end_ch);
+
+	qdf_status =
+		ucfg_mlme_get_auto_channel_weight(hdd_ctx->psoc,
+						  &auto_channel_select_weight);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		hdd_err("get_auto_channel_weight failed");
+
+	if (auto_channel_select_weight)
+		sap_config->auto_channel_select_weight =
+				auto_channel_select_weight;
+
+	sap_config->acs_cfg.is_ht_enabled = ht_enabled;
+	sap_config->acs_cfg.is_vht_enabled = vht_enabled;
+
+	if (sap_config->acs_cfg.ch_list_count) {
+		hdd_debug("ACS channel list: len: %d",
+					sap_config->acs_cfg.ch_list_count);
+		for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++)
+			hdd_debug("%d ", sap_config->acs_cfg.ch_list[i]);
+	}
+
+	conc_channel = policy_mgr_mode_specific_get_channel(hdd_ctx->psoc,
+							    PM_STA_MODE);
+
+	qdf_status = ucfg_mlme_get_external_acs_policy(hdd_ctx->psoc,
+						       &is_external_acs_policy);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		hdd_err("get_external_acs_policy failed");
+
+	if (is_external_acs_policy) {
+		if ((conc_channel >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
+		     sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211A) ||
+		     (conc_channel <= WLAN_REG_CH_NUM(CHAN_ENUM_14) &&
+		      (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211B ||
+		       sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211A))) {
+			sap_config->acs_cfg.pri_ch = conc_channel;
+			wlan_sap_set_sap_ctx_acs_cfg(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter), sap_config);
+			mac_handle = hdd_ctx->mac_handle;
+			sap_config_acs_result(mac_handle,
+					      WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+					      sap_config->acs_cfg.ht_sec_ch);
+			sap_config->ch_params.ch_width =
+					sap_config->acs_cfg.ch_width;
+			sap_config->ch_params.sec_ch_offset =
+					sap_config->acs_cfg.ht_sec_ch;
+			sap_config->ch_params.center_freq_seg0 =
+					sap_config->acs_cfg.vht_seg0_center_ch;
+			sap_config->ch_params.center_freq_seg1 =
+					sap_config->acs_cfg.vht_seg1_center_ch;
+			/*notify hostapd about channel override */
+			wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
+			ret = 0;
+			goto out;
+		}
+	}
+
+	sap_config->acs_cfg.acs_mode = true;
+	if (test_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags)) {
+		/* ***Note*** Completion variable usage is not allowed
+		 * here since ACS scan operation may take max 2.2 sec
+		 * for 5G band:
+		 *   9 Active channel X 40 ms active scan time +
+		 *   16 Passive channel X 110ms passive scan time
+		 * Since this CFG80211 call lock rtnl mutex, we cannot hold on
+		 * for this long. So we split up the scanning part.
+		 */
+		set_bit(ACS_PENDING, &adapter->event_flags);
+		hdd_debug("ACS Pending for %s", adapter->dev->name);
+		ret = 0;
+	} else {
+		qdf_status =
+			ucfg_mlme_get_vendor_acs_support(
+					hdd_ctx->psoc,
+					&is_vendor_acs_support);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			hdd_err("get_vendor_acs_support failed, set default");
+
+		/* Check if vendor specific acs is enabled */
+		if (is_vendor_acs_support)
+			ret = hdd_start_vendor_acs(adapter);
+		else
+			ret = wlan_hdd_cfg80211_start_acs(adapter);
+	}
+
+out:
+	if (ret == 0) {
+		temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
+							      NLMSG_HDRLEN);
+		if (temp_skbuff != NULL)
+			return cfg80211_vendor_cmd_reply(temp_skbuff);
+	}
+	qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
+	wlan_hdd_undo_acs(adapter);
+	clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_do_acs : CFG80211 handler function for DO_ACS Vendor CMD
+ * @wiphy:  Linux wiphy struct pointer
+ * @wdev:   Linux wireless device struct pointer
+ * @data:   ACS information from hostapd
+ * @data_len: ACS information len
+ *
+ * This function handle DO_ACS Vendor command from hostapd, parses ACS config
+ * and starts ACS procedure.
+ *
+ * Return: ACS procedure start status
+ */
+
+static int wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
+				    struct wireless_dev *wdev,
+				    const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_do_acs(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_undo_acs : Do cleanup of DO_ACS
+ * @adapter:  Pointer to adapter struct
+ *
+ * This function handle cleanup of what was done in DO_ACS, including free
+ * memory.
+ *
+ * Return: void
+ */
+
+void wlan_hdd_undo_acs(struct hdd_adapter *adapter)
+{
+	if (adapter == NULL)
+		return;
+	if (adapter->session.ap.sap_config.acs_cfg.ch_list) {
+		qdf_mem_free(adapter->session.ap.sap_config.acs_cfg.ch_list);
+		adapter->session.ap.sap_config.acs_cfg.ch_list = NULL;
+	}
+}
+
+/**
+ * wlan_hdd_cfg80211_start_pending_acs : Start pending ACS procedure for SAP
+ * @work:  Linux workqueue struct pointer for ACS work
+ *
+ * This function starts the ACS procedure which was marked pending when an ACS
+ * procedure was in progress for a concurrent SAP interface.
+ *
+ * Return: None
+ */
+
+static void wlan_hdd_cfg80211_start_pending_acs(struct work_struct *work)
+{
+	struct hdd_adapter *adapter = container_of(work, struct hdd_adapter,
+						   acs_pending_work.work);
+
+	wlan_hdd_cfg80211_start_acs(adapter);
+	clear_bit(ACS_PENDING, &adapter->event_flags);
+}
+
+/**
+ * wlan_hdd_cfg80211_acs_ch_select_evt: Callback function for ACS evt
+ * @adapter: Pointer to SAP adapter struct
+ * @pri_channel: SAP ACS procedure selected Primary channel
+ * @sec_channel: SAP ACS procedure selected secondary channel
+ *
+ * This is a callback function from SAP module on ACS procedure is completed.
+ * This function send the ACS selected channel information to hostapd
+ *
+ * Return: None
+ */
+
+void wlan_hdd_cfg80211_acs_ch_select_evt(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	tsap_config_t *sap_cfg = &(WLAN_HDD_GET_AP_CTX_PTR(adapter))->sap_config;
+	struct sk_buff *vendor_event;
+	int ret_val;
+	struct hdd_adapter *con_sap_adapter;
+	uint16_t ch_width;
+
+	vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+			&(adapter->wdev),
+			4 * sizeof(u8) + 1 * sizeof(u16) + 4 + NLMSG_HDRLEN,
+			QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX,
+			GFP_KERNEL);
+
+	if (!vendor_event) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	ret_val = nla_put_u8(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL,
+				sap_cfg->acs_cfg.pri_ch);
+	if (ret_val) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL put fail");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	ret_val = nla_put_u8(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL,
+				sap_cfg->acs_cfg.ht_sec_ch);
+	if (ret_val) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL put fail");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	ret_val = nla_put_u8(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL,
+			sap_cfg->acs_cfg.vht_seg0_center_ch);
+	if (ret_val) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL put fail");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	ret_val = nla_put_u8(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL,
+			sap_cfg->acs_cfg.vht_seg1_center_ch);
+	if (ret_val) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL put fail");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	if (sap_cfg->acs_cfg.ch_width == CH_WIDTH_160MHZ)
+		ch_width = 160;
+	else if (sap_cfg->acs_cfg.ch_width == CH_WIDTH_80MHZ)
+		ch_width = 80;
+	else if (sap_cfg->acs_cfg.ch_width == CH_WIDTH_40MHZ)
+		ch_width = 40;
+	else
+		ch_width = 20;
+
+	ret_val = nla_put_u16(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH,
+				ch_width);
+	if (ret_val) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH put fail");
+		kfree_skb(vendor_event);
+		return;
+	}
+	if (sap_cfg->acs_cfg.pri_ch > 14)
+		ret_val = nla_put_u8(vendor_event,
+					QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE,
+					QCA_ACS_MODE_IEEE80211A);
+	else
+		ret_val = nla_put_u8(vendor_event,
+					QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE,
+					QCA_ACS_MODE_IEEE80211G);
+
+	if (ret_val) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE put fail");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	hdd_debug("ACS result for %s: PRI_CH: %d SEC_CH: %d VHT_SEG0: %d VHT_SEG1: %d ACS_BW: %d",
+		adapter->dev->name, sap_cfg->acs_cfg.pri_ch,
+		sap_cfg->acs_cfg.ht_sec_ch, sap_cfg->acs_cfg.vht_seg0_center_ch,
+		sap_cfg->acs_cfg.vht_seg1_center_ch, ch_width);
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+	/* ***Note*** As already mentioned Completion variable usage is not
+	 * allowed here since ACS scan operation may take max 2.2 sec.
+	 * Further in AP-AP mode pending ACS is resumed here to serailize ACS
+	 * operation.
+	 * TODO: Delayed operation is used since SME-PMAC strut is global. Thus
+	 * when Primary AP ACS is complete and secondary AP ACS is started here
+	 * immediately, Primary AP start_bss may come inbetween ACS operation
+	 * and overwrite Sec AP ACS parameters. Thus Sec AP ACS is executed with
+	 * delay. This path and below constraint will be removed on sessionizing
+	 * SAP acs parameters and decoupling SAP from PMAC (WIP).
+	 * As per design constraint user space control application must take
+	 * care of serailizing hostapd start for each VIF in AP-AP mode to avoid
+	 * this code path. Sec AP hostapd should be started after Primary AP
+	 * start beaconing which can be confirmed by getchannel iwpriv command
+	 */
+
+	con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
+	if (con_sap_adapter &&
+		test_bit(ACS_PENDING, &con_sap_adapter->event_flags)) {
+		INIT_DELAYED_WORK(&con_sap_adapter->acs_pending_work,
+				      wlan_hdd_cfg80211_start_pending_acs);
+		/* Lets give 1500ms for OBSS + START_BSS to complete */
+		schedule_delayed_work(&con_sap_adapter->acs_pending_work,
+					msecs_to_jiffies(1500));
+	}
+}
+
+static int
+__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 const void *data,
+					 int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct sk_buff *skb = NULL;
+	uint32_t fset = 0;
+	int ret;
+#ifdef FEATURE_WLAN_TDLS
+	bool bvalue;
+#endif
+
+	/* ENTER_DEV() intentionally not used in a frequently invoked API */
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
+		hdd_debug("Infra Station mode is supported by driver");
+		fset |= WIFI_FEATURE_INFRA;
+	}
+	if (true == hdd_is_5g_supported(hdd_ctx)) {
+		hdd_debug("INFRA_5G is supported by firmware");
+		fset |= WIFI_FEATURE_INFRA_5G;
+	}
+#ifdef WLAN_FEATURE_P2P
+	if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
+	    (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
+		hdd_debug("WiFi-Direct is supported by driver");
+		fset |= WIFI_FEATURE_P2P;
+	}
+#endif
+	fset |= WIFI_FEATURE_SOFT_AP;
+
+	/* HOTSPOT is a supplicant feature, enable it by default */
+	fset |= WIFI_FEATURE_HOTSPOT;
+
+	if (ucfg_extscan_get_enable(hdd_ctx->psoc) &&
+	    sme_is_feature_supported_by_fw(EXTENDED_SCAN)) {
+		hdd_debug("EXTScan is supported by firmware");
+		fset |= WIFI_FEATURE_EXTSCAN | WIFI_FEATURE_HAL_EPNO;
+	}
+	if (wlan_hdd_nan_is_supported(hdd_ctx)) {
+		hdd_debug("NAN is supported by firmware");
+		fset |= WIFI_FEATURE_NAN;
+	}
+	if (sme_is_feature_supported_by_fw(RTT)) {
+		hdd_debug("RTT is supported by firmware");
+		fset |= WIFI_FEATURE_D2D_RTT;
+		fset |= WIFI_FEATURE_D2AP_RTT;
+	}
+#ifdef FEATURE_WLAN_SCAN_PNO
+	if (hdd_ctx->config->configPNOScanSupport &&
+	    sme_is_feature_supported_by_fw(PNO)) {
+		hdd_debug("PNO is supported by firmware");
+		fset |= WIFI_FEATURE_PNO;
+	}
+#endif
+	fset |= WIFI_FEATURE_ADDITIONAL_STA;
+#ifdef FEATURE_WLAN_TDLS
+	cfg_tdls_get_support_enable(hdd_ctx->psoc, &bvalue);
+	if ((bvalue) && sme_is_feature_supported_by_fw(TDLS)) {
+		hdd_debug("TDLS is supported by firmware");
+		fset |= WIFI_FEATURE_TDLS;
+	}
+
+	cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &bvalue);
+	if (sme_is_feature_supported_by_fw(TDLS) &&
+	    bvalue && sme_is_feature_supported_by_fw(TDLS_OFF_CHANNEL)) {
+		hdd_debug("TDLS off-channel is supported by firmware");
+		fset |= WIFI_FEATURE_TDLS_OFFCHANNEL;
+	}
+#endif
+	fset |= WIFI_FEATURE_AP_STA;
+	fset |= WIFI_FEATURE_RSSI_MONITOR;
+	fset |= WIFI_FEATURE_TX_TRANSMIT_POWER;
+	fset |= WIFI_FEATURE_SET_TX_POWER_LIMIT;
+	fset |= WIFI_FEATURE_CONFIG_NDO;
+
+	if (hdd_link_layer_stats_supported())
+		fset |= WIFI_FEATURE_LINK_LAYER_STATS;
+
+	if (hdd_roaming_supported(hdd_ctx))
+		fset |= WIFI_FEATURE_CONTROL_ROAMING;
+
+	if (hdd_scan_random_mac_addr_supported())
+		fset |= WIFI_FEATURE_SCAN_RAND;
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
+						  NLMSG_HDRLEN);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -EINVAL;
+	}
+	hdd_debug("Supported Features : 0x%x", fset);
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
+		hdd_err("nla put fail");
+		goto nla_put_failure;
+	}
+	ret = cfg80211_vendor_cmd_reply(skb);
+	return ret;
+nla_put_failure:
+	kfree_skb(skb);
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_get_supported_features() - get supported features
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int
+wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data, int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev,
+						data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_scanning_mac_oui() - set scan MAC
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Set the MAC address that is to be used for scanning.
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int
+__wlan_hdd_cfg80211_set_scanning_mac_oui(struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 const void *data,
+					 int data_len)
+{
+	tpSirScanMacOui pReqMsg = NULL;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
+	QDF_STATUS status;
+	int ret;
+	int len;
+	struct net_device *ndev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	mac_handle_t mac_handle;
+
+	hdd_enter_dev(wdev->netdev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (!hdd_ctx->config->enable_mac_spoofing) {
+		hdd_debug("MAC address spoofing is not enabled");
+		return -ENOTSUPP;
+	}
+
+	/*
+	 * audit note: it is ok to pass a NULL policy here since only
+	 * one attribute is parsed and it is explicitly validated
+	 */
+	if (wlan_cfg80211_nla_parse(tb,
+				  QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
+				  data, data_len, NULL)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+	pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg));
+	if (!pReqMsg)
+		return -ENOMEM;
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
+		hdd_err("attr mac oui failed");
+		goto fail;
+	}
+
+	len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]);
+	if (len != sizeof(pReqMsg->oui)) {
+		hdd_err("attr mac oui invalid size %d expected %zu",
+			len, sizeof(pReqMsg->oui));
+		goto fail;
+	}
+
+	nla_memcpy(&pReqMsg->oui[0],
+		   tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI],
+		   sizeof(pReqMsg->oui));
+
+	/* populate pReqMsg for mac addr randomization */
+	pReqMsg->vdev_id = adapter->session_id;
+	pReqMsg->enb_probe_req_sno_randomization = true;
+
+	hdd_debug("Oui (%02x:%02x:%02x), vdev_id = %d", pReqMsg->oui[0],
+		  pReqMsg->oui[1], pReqMsg->oui[2], pReqMsg->vdev_id);
+
+	hdd_update_ie_whitelist_attr(&pReqMsg->ie_whitelist, hdd_ctx);
+
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_set_scanning_mac_oui(mac_handle, pReqMsg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_set_scanning_mac_oui failed(err=%d)", status);
+		goto fail;
+	}
+	return 0;
+fail:
+	qdf_mem_free(pReqMsg);
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_scanning_mac_oui() - set scan MAC
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Set the MAC address that is to be used for scanning.  This is an
+ * SSR-protecting wrapper function.
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int
+wlan_hdd_cfg80211_set_scanning_mac_oui(struct wiphy *wiphy,
+				       struct wireless_dev *wdev,
+				       const void *data,
+				       int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_scanning_mac_oui(wiphy, wdev,
+						       data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_feature() - Set the bitmask for supported features
+ * @feature_flags: pointer to the byte array of features.
+ * @feature: Feature to be turned ON in the byte array.
+ *
+ * Return: None
+ *
+ * This is called to turn ON or SET the feature flag for the requested feature.
+ **/
+#define NUM_BITS_IN_BYTE       8
+static void wlan_hdd_cfg80211_set_feature(uint8_t *feature_flags,
+					  uint8_t feature)
+{
+	uint32_t index;
+	uint8_t bit_mask;
+
+	index = feature / NUM_BITS_IN_BYTE;
+	bit_mask = 1 << (feature % NUM_BITS_IN_BYTE);
+	feature_flags[index] |= bit_mask;
+}
+
+/**
+ * __wlan_hdd_cfg80211_get_features() - Get the Driver Supported features
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This is called when wlan driver needs to send supported feature set to
+ * supplicant upon a request/query from the supplicant.
+ *
+ * Return: Return the Success or Failure code.
+ **/
+#define MAX_CONCURRENT_CHAN_ON_24G    2
+#define MAX_CONCURRENT_CHAN_ON_5G     2
+static int
+__wlan_hdd_cfg80211_get_features(struct wiphy *wiphy,
+				 struct wireless_dev *wdev,
+				 const void *data, int data_len)
+{
+	struct sk_buff *skb = NULL;
+	uint32_t dbs_capability = 0;
+	bool one_by_one_dbs, two_by_two_dbs;
+	bool value;
+	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
+	QDF_STATUS status;
+	int ret_val;
+
+	uint8_t feature_flags[(NUM_QCA_WLAN_VENDOR_FEATURES + 7) / 8] = {0};
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter_dev(wdev->netdev);
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		return ret_val;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (roaming_offload_enabled(hdd_ctx)) {
+		hdd_debug("Key Mgmt Offload is supported");
+		wlan_hdd_cfg80211_set_feature(feature_flags,
+				QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD);
+	}
+
+	wlan_hdd_cfg80211_set_feature(feature_flags,
+				QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY);
+	if (policy_mgr_is_scan_simultaneous_capable(hdd_ctx->psoc))
+		wlan_hdd_cfg80211_set_feature(feature_flags,
+			QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS);
+
+	if (wma_is_p2p_lo_capable())
+		wlan_hdd_cfg80211_set_feature(feature_flags,
+			QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD);
+
+	value = 0;
+	status = ucfg_mlme_get_oce_sta_enabled_info(hdd_ctx->psoc, &value);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("could not get OCE STA enable info");
+	if (value)
+		wlan_hdd_cfg80211_set_feature(feature_flags,
+					      QCA_WLAN_VENDOR_FEATURE_OCE_STA);
+
+	value = 0;
+	status = ucfg_mlme_get_oce_sap_enabled_info(hdd_ctx->psoc, &value);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("could not get OCE SAP enable info");
+	if (value)
+		wlan_hdd_cfg80211_set_feature(feature_flags,
+					  QCA_WLAN_VENDOR_FEATURE_OCE_STA_CFON);
+
+	/* Check the kernel version for upstream commit aced43ce780dc5 that
+	 * has support for processing user cell_base hints when wiphy is
+	 * self managed or check the backport flag for the same.
+	 */
+#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
+	    (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
+	wlan_hdd_cfg80211_set_feature(feature_flags,
+			QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY);
+#endif
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(feature_flags) +
+			NLMSG_HDRLEN);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS,
+			sizeof(feature_flags), feature_flags))
+		goto nla_put_failure;
+
+	ret = policy_mgr_get_dbs_hw_modes(hdd_ctx->psoc,
+					  &one_by_one_dbs, &two_by_two_dbs);
+	if (QDF_STATUS_SUCCESS == ret) {
+		if (one_by_one_dbs)
+			dbs_capability = DRV_DBS_CAPABILITY_1X1;
+
+		if (two_by_two_dbs)
+			dbs_capability = DRV_DBS_CAPABILITY_2X2;
+
+		if (!one_by_one_dbs && !two_by_two_dbs)
+			dbs_capability = DRV_DBS_CAPABILITY_DISABLED;
+	} else {
+		hdd_err("wma_get_dbs_hw_mode failed");
+		dbs_capability = DRV_DBS_CAPABILITY_DISABLED;
+	}
+
+	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;
+
+	if (nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_5_0_BAND,
+			MAX_CONCURRENT_CHAN_ON_5G))
+		goto nla_put_failure;
+
+	return cfg80211_vendor_cmd_reply(skb);
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_get_features() - Get the Driver Supported features
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This is called when wlan driver needs to send supported feature set to
+ * supplicant upon a request/query from the supplicant.
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int
+wlan_hdd_cfg80211_get_features(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_features(wiphy, wdev,
+					       data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#define PARAM_NUM_NW \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS
+#define PARAM_SET_BSSID \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID
+#define PARAM_SSID_LIST QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST
+#define PARAM_LIST_SSID  QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID
+#define MAX_ROAMING_PARAM \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX
+#define PARAM_NUM_BSSID \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID
+#define PARAM_BSSID_PREFS \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS
+#define PARAM_ROAM_BSSID \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_BSSID
+#define PARAM_RSSI_MODIFIER \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_RSSI_MODIFIER
+#define PARAMS_NUM_BSSID \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID
+#define PARAM_BSSID_PARAMS \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS
+#define PARAM_A_BAND_BOOST_THLD \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD
+#define PARAM_A_BAND_PELT_THLD \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_THRESHOLD
+#define PARAM_A_BAND_BOOST_FACTOR \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_FACTOR
+#define PARAM_A_BAND_PELT_FACTOR \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_FACTOR
+#define PARAM_A_BAND_MAX_BOOST \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_MAX_BOOST
+#define PARAM_ROAM_HISTERESYS \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_LAZY_ROAM_HISTERESYS
+#define PARAM_RSSI_TRIGGER \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALERT_ROAM_RSSI_TRIGGER
+#define PARAM_ROAM_ENABLE \
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE
+
+
+static const struct nla_policy
+wlan_hdd_set_roam_param_policy[MAX_ROAMING_PARAM + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID] = {.type = NLA_U32},
+	[PARAM_NUM_NW] = {.type = NLA_U32},
+	[PARAM_A_BAND_BOOST_FACTOR] = {.type = NLA_U32},
+	[PARAM_A_BAND_PELT_FACTOR] = {.type = NLA_U32},
+	[PARAM_A_BAND_MAX_BOOST] = {.type = NLA_U32},
+	[PARAM_ROAM_HISTERESYS] = {.type = NLA_S32},
+	[PARAM_A_BAND_BOOST_THLD] = {.type = NLA_S32},
+	[PARAM_A_BAND_PELT_THLD] = {.type = NLA_S32},
+	[PARAM_RSSI_TRIGGER] = {.type = NLA_U32},
+	[PARAM_ROAM_ENABLE] = {	.type = NLA_S32},
+	[PARAM_NUM_BSSID] = {.type = NLA_U32},
+	[PARAM_RSSI_MODIFIER] = {.type = NLA_U32},
+	[PARAMS_NUM_BSSID] = {.type = NLA_U32},
+	[PARAM_ROAM_BSSID] = {.type = NLA_UNSPEC, .len = QDF_MAC_ADDR_SIZE},
+	[PARAM_SET_BSSID] = {.type = NLA_UNSPEC, .len = QDF_MAC_ADDR_SIZE},
+};
+
+/**
+ * hdd_set_white_list() - parse white list
+ * @hdd_ctx:        HDD context
+ * @roam_params:   roam params
+ * @tb:            list of attributes
+ * @session_id:    session id
+ *
+ * Return: 0 on success; error number on failure
+ */
+static int hdd_set_white_list(struct hdd_context *hdd_ctx,
+			      struct roam_ext_params *roam_params,
+			      struct nlattr **tb, uint8_t session_id)
+{
+	int rem, i;
+	uint32_t buf_len = 0, count;
+	struct nlattr *tb2[MAX_ROAMING_PARAM + 1];
+	struct nlattr *curr_attr = NULL;
+	mac_handle_t mac_handle;
+
+	i = 0;
+	if (tb[PARAM_NUM_NW]) {
+		count = nla_get_u32(tb[PARAM_NUM_NW]);
+	} else {
+		hdd_err("Number of networks is not provided");
+		goto fail;
+	}
+
+	if (count && tb[PARAM_SSID_LIST]) {
+		nla_for_each_nested(curr_attr,
+			tb[PARAM_SSID_LIST], rem) {
+			if (wlan_cfg80211_nla_parse(tb2,
+					   QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_MAX,
+					   nla_data(curr_attr),
+					   nla_len(curr_attr),
+					   wlan_hdd_set_roam_param_policy)) {
+				hdd_err("nla_parse failed");
+				goto fail;
+			}
+			/* Parse and Fetch allowed SSID list*/
+			if (!tb2[PARAM_LIST_SSID]) {
+				hdd_err("attr allowed ssid failed");
+				goto fail;
+			}
+			buf_len = nla_len(tb2[PARAM_LIST_SSID]);
+			/*
+			 * Upper Layers include a null termination
+			 * character. Check for the actual permissible
+			 * length of SSID and also ensure not to copy
+			 * the NULL termination character to the driver
+			 * buffer.
+			 */
+			if (buf_len && (i < MAX_SSID_ALLOWED_LIST) &&
+			    ((buf_len - 1) <= SIR_MAC_MAX_SSID_LENGTH)) {
+				nla_memcpy(roam_params->ssid_allowed_list[i].ssId,
+					tb2[PARAM_LIST_SSID], buf_len - 1);
+				roam_params->ssid_allowed_list[i].length = buf_len - 1;
+				hdd_debug("SSID[%d]: %.*s,length = %d",
+					i,
+					roam_params->ssid_allowed_list[i].length,
+					roam_params->ssid_allowed_list[i].ssId,
+					roam_params->ssid_allowed_list[i].length);
+					i++;
+			} else {
+				hdd_err("Invalid buffer length");
+			}
+		}
+	}
+
+	if (i != count) {
+		hdd_err("Invalid number of SSIDs i = %d, count = %d", i, count);
+		goto fail;
+	}
+
+	roam_params->num_ssid_allowed_list = i;
+	hdd_debug("Num of Allowed SSID %d", roam_params->num_ssid_allowed_list);
+	mac_handle = hdd_ctx->mac_handle;
+	sme_update_roam_params(mac_handle, session_id,
+			       roam_params, REASON_ROAM_SET_SSID_ALLOWED);
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_set_bssid_prefs() - parse set bssid prefs
+ * @hdd_ctx:        HDD context
+ * @roam_params:   roam params
+ * @tb:            list of attributes
+ * @session_id:    session id
+ *
+ * Return: 0 on success; error number on failure
+ */
+static int hdd_set_bssid_prefs(struct hdd_context *hdd_ctx,
+			       struct roam_ext_params *roam_params,
+			       struct nlattr **tb, uint8_t session_id)
+{
+	int rem, i;
+	uint32_t count;
+	struct nlattr *tb2[MAX_ROAMING_PARAM + 1];
+	struct nlattr *curr_attr = NULL;
+	mac_handle_t mac_handle;
+
+	/* Parse and fetch number of preferred BSSID */
+	if (!tb[PARAM_NUM_BSSID]) {
+		hdd_err("attr num of preferred bssid failed");
+		goto fail;
+	}
+	count = nla_get_u32(tb[PARAM_NUM_BSSID]);
+	if (count > MAX_BSSID_FAVORED) {
+		hdd_err("Preferred BSSID count %u exceeds max %u",
+			count, MAX_BSSID_FAVORED);
+		goto fail;
+	}
+	hdd_debug("Num of Preferred BSSID (%d)", count);
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS]) {
+		hdd_err("attr Preferred BSSID failed");
+		goto fail;
+	}
+
+	i = 0;
+	nla_for_each_nested(curr_attr,
+		tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS],
+		rem) {
+		if (i == count) {
+			hdd_warn("Ignoring excess Preferred BSSID");
+			break;
+		}
+
+		if (wlan_cfg80211_nla_parse(tb2,
+					 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX,
+					 nla_data(curr_attr),
+					 nla_len(curr_attr),
+					 wlan_hdd_set_roam_param_policy)) {
+			hdd_err("nla_parse failed");
+			goto fail;
+		}
+		/* Parse and fetch MAC address */
+		if (!tb2[PARAM_ROAM_BSSID]) {
+			hdd_err("attr mac address failed");
+			goto fail;
+		}
+		nla_memcpy(roam_params->bssid_favored[i].bytes,
+			  tb2[PARAM_ROAM_BSSID],
+			  QDF_MAC_ADDR_SIZE);
+		hdd_debug(MAC_ADDRESS_STR,
+			  MAC_ADDR_ARRAY(roam_params->bssid_favored[i].bytes));
+		/* Parse and fetch preference factor*/
+		if (!tb2[PARAM_RSSI_MODIFIER]) {
+			hdd_err("BSSID Preference score failed");
+			goto fail;
+		}
+		roam_params->bssid_favored_factor[i] = nla_get_u32(
+			tb2[PARAM_RSSI_MODIFIER]);
+		hdd_debug("BSSID Preference score (%d)",
+			  roam_params->bssid_favored_factor[i]);
+		i++;
+	}
+	if (i < count)
+		hdd_warn("Num Preferred BSSID %u less than expected %u",
+				 i, count);
+
+	roam_params->num_bssid_favored = i;
+	mac_handle = hdd_ctx->mac_handle;
+	sme_update_roam_params(mac_handle, session_id,
+			       roam_params, REASON_ROAM_SET_FAVORED_BSSID);
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_set_blacklist_bssid() - parse set blacklist bssid
+ * @hdd_ctx:        HDD context
+ * @roam_params:   roam params
+ * @tb:            list of attributes
+ * @session_id:    session id
+ *
+ * Return: 0 on success; error number on failure
+ */
+static int hdd_set_blacklist_bssid(struct hdd_context *hdd_ctx,
+				   struct roam_ext_params *roam_params,
+				   struct nlattr **tb,
+				   uint8_t session_id)
+{
+	int rem, i;
+	uint32_t count;
+	struct nlattr *tb2[MAX_ROAMING_PARAM + 1];
+	struct nlattr *curr_attr = NULL;
+	mac_handle_t mac_handle;
+
+	/* Parse and fetch number of blacklist BSSID */
+	if (!tb[PARAMS_NUM_BSSID]) {
+		hdd_err("attr num of blacklist bssid failed");
+		goto fail;
+	}
+	count = nla_get_u32(tb[PARAMS_NUM_BSSID]);
+	if (count > MAX_BSSID_AVOID_LIST) {
+		hdd_err("Blacklist BSSID count %u exceeds max %u",
+			count, MAX_BSSID_AVOID_LIST);
+		goto fail;
+	}
+	hdd_debug("Num of blacklist BSSID (%d)", count);
+
+	i = 0;
+	if (count && tb[PARAM_BSSID_PARAMS]) {
+		nla_for_each_nested(curr_attr,
+			tb[PARAM_BSSID_PARAMS],
+			rem) {
+			if (i == count) {
+				hdd_warn("Ignoring excess Blacklist BSSID");
+				break;
+			}
+
+			if (wlan_cfg80211_nla_parse(tb2,
+					 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX,
+					 nla_data(curr_attr),
+					 nla_len(curr_attr),
+					 wlan_hdd_set_roam_param_policy)) {
+				hdd_err("nla_parse failed");
+				goto fail;
+			}
+			/* Parse and fetch MAC address */
+			if (!tb2[PARAM_SET_BSSID]) {
+				hdd_err("attr blacklist addr failed");
+				goto fail;
+			}
+			nla_memcpy(roam_params->bssid_avoid_list[i].bytes,
+				   tb2[PARAM_SET_BSSID], QDF_MAC_ADDR_SIZE);
+			hdd_debug(MAC_ADDRESS_STR,
+				  MAC_ADDR_ARRAY(roam_params->bssid_avoid_list[i].bytes));
+			i++;
+		}
+	}
+
+	if (i < count)
+		hdd_warn("Num Blacklist BSSID %u less than expected %u",
+			 i, count);
+
+	roam_params->num_bssid_avoid_list = i;
+	mac_handle = hdd_ctx->mac_handle;
+	sme_update_roam_params(mac_handle, session_id,
+			       roam_params, REASON_ROAM_SET_BLACKLIST_BSSID);
+
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_set_ext_roam_params() - parse ext roam params
+ * @hdd_ctx:        HDD context
+ * @roam_params:   roam params
+ * @tb:            list of attributes
+ * @session_id:    session id
+ *
+ * Return: 0 on success; error number on failure
+ */
+static int hdd_set_ext_roam_params(struct hdd_context *hdd_ctx,
+				   const void *data, int data_len,
+				   uint8_t session_id,
+				   struct roam_ext_params *roam_params)
+{
+	uint32_t cmd_type, req_id;
+	struct nlattr *tb[MAX_ROAMING_PARAM + 1];
+	int ret;
+	mac_handle_t mac_handle;
+
+	if (wlan_cfg80211_nla_parse(tb, MAX_ROAMING_PARAM, data, data_len,
+				    wlan_hdd_set_roam_param_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+	/* Parse and fetch Command Type */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD]) {
+		hdd_err("roam cmd type failed");
+		goto fail;
+	}
+
+	cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD]);
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID]) {
+		hdd_err("attr request id failed");
+		goto fail;
+	}
+	mac_handle = hdd_ctx->mac_handle;
+	req_id = nla_get_u32(
+		tb[QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID]);
+	hdd_debug("Req Id: %u Cmd Type: %u", req_id, cmd_type);
+	switch (cmd_type) {
+	case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SSID_WHITE_LIST:
+		ret = hdd_set_white_list(hdd_ctx, roam_params, tb, session_id);
+		if (ret)
+			goto fail;
+		break;
+
+	case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_EXTSCAN_ROAM_PARAMS:
+		/* Parse and fetch 5G Boost Threshold */
+		if (!tb[PARAM_A_BAND_BOOST_THLD]) {
+			hdd_err("5G boost threshold failed");
+			goto fail;
+		}
+		roam_params->raise_rssi_thresh_5g = nla_get_s32(
+			tb[PARAM_A_BAND_BOOST_THLD]);
+		hdd_debug("5G Boost Threshold (%d)",
+			roam_params->raise_rssi_thresh_5g);
+		/* Parse and fetch 5G Penalty Threshold */
+		if (!tb[PARAM_A_BAND_PELT_THLD]) {
+			hdd_err("5G penalty threshold failed");
+			goto fail;
+		}
+		roam_params->drop_rssi_thresh_5g = nla_get_s32(
+			tb[PARAM_A_BAND_PELT_THLD]);
+		hdd_debug("5G Penalty Threshold (%d)",
+			roam_params->drop_rssi_thresh_5g);
+		/* Parse and fetch 5G Boost Factor */
+		if (!tb[PARAM_A_BAND_BOOST_FACTOR]) {
+			hdd_err("5G boost Factor failed");
+			goto fail;
+		}
+		roam_params->raise_factor_5g = nla_get_u32(
+			tb[PARAM_A_BAND_BOOST_FACTOR]);
+		hdd_debug("5G Boost Factor (%d)",
+			roam_params->raise_factor_5g);
+		/* Parse and fetch 5G Penalty factor */
+		if (!tb[PARAM_A_BAND_PELT_FACTOR]) {
+			hdd_err("5G Penalty Factor failed");
+			goto fail;
+		}
+		roam_params->drop_factor_5g = nla_get_u32(
+			tb[PARAM_A_BAND_PELT_FACTOR]);
+		hdd_debug("5G Penalty factor (%d)",
+			roam_params->drop_factor_5g);
+		/* Parse and fetch 5G Max Boost */
+		if (!tb[PARAM_A_BAND_MAX_BOOST]) {
+			hdd_err("5G Max Boost failed");
+			goto fail;
+		}
+		roam_params->max_raise_rssi_5g = nla_get_u32(
+			tb[PARAM_A_BAND_MAX_BOOST]);
+		hdd_debug("5G Max Boost (%d)",
+			roam_params->max_raise_rssi_5g);
+		/* Parse and fetch Rssi Diff */
+		if (!tb[PARAM_ROAM_HISTERESYS]) {
+			hdd_err("Rssi Diff failed");
+			goto fail;
+		}
+		roam_params->rssi_diff = nla_get_s32(
+			tb[PARAM_ROAM_HISTERESYS]);
+		hdd_debug("RSSI Diff (%d)",
+			roam_params->rssi_diff);
+		/* Parse and fetch Alert Rssi Threshold */
+		if (!tb[PARAM_RSSI_TRIGGER]) {
+			hdd_err("Alert Rssi Threshold failed");
+			goto fail;
+		}
+		roam_params->alert_rssi_threshold = nla_get_u32(
+			tb[PARAM_RSSI_TRIGGER]);
+		hdd_debug("Alert RSSI Threshold (%d)",
+			roam_params->alert_rssi_threshold);
+		sme_update_roam_params(mac_handle, session_id,
+				       roam_params,
+				       REASON_ROAM_EXT_SCAN_PARAMS_CHANGED);
+		break;
+	case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_LAZY_ROAM:
+		/* Parse and fetch Activate Good Rssi Roam */
+		if (!tb[PARAM_ROAM_ENABLE]) {
+			hdd_err("Activate Good Rssi Roam failed");
+			goto fail;
+		}
+		roam_params->good_rssi_roam = nla_get_s32(
+			tb[PARAM_ROAM_ENABLE]);
+		hdd_debug("Activate Good Rssi Roam (%d)",
+			  roam_params->good_rssi_roam);
+		sme_update_roam_params(mac_handle, session_id,
+				       roam_params,
+				       REASON_ROAM_GOOD_RSSI_CHANGED);
+		break;
+	case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_BSSID_PREFS:
+		ret = hdd_set_bssid_prefs(hdd_ctx, roam_params, tb, session_id);
+		if (ret)
+			goto fail;
+		break;
+	case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_BLACKLIST_BSSID:
+		ret = hdd_set_blacklist_bssid(hdd_ctx, roam_params,
+					      tb, session_id);
+		if (ret)
+			goto fail;
+		break;
+	}
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_ext_roam_params() - Settings for roaming parameters
+ * @wiphy:                 The wiphy structure
+ * @wdev:                  The wireless device
+ * @data:                  Data passed by framework
+ * @data_len:              Parameters to be configured passed as data
+ *
+ * The roaming related parameters are configured by the framework
+ * using this interface.
+ *
+ * Return: Return either success or failure code.
+ */
+static int
+__wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void *data, int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct roam_ext_params *roam_params = NULL;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
+		hdd_err("Driver Modules are closed");
+		return -EINVAL;
+	}
+
+	roam_params = qdf_mem_malloc(sizeof(*roam_params));
+	if (!roam_params)
+		return -ENOMEM;
+
+	ret = hdd_set_ext_roam_params(hdd_ctx, data, data_len,
+				      adapter->session_id, roam_params);
+	if (ret)
+		goto fail;
+
+	if (roam_params)
+		qdf_mem_free(roam_params);
+	return 0;
+fail:
+	if (roam_params)
+		qdf_mem_free(roam_params);
+
+	return ret;
+}
+#undef PARAM_NUM_NW
+#undef PARAM_SET_BSSID
+#undef PARAM_SSID_LIST
+#undef PARAM_LIST_SSID
+#undef MAX_ROAMING_PARAM
+#undef PARAM_NUM_BSSID
+#undef PARAM_BSSID_PREFS
+#undef PARAM_ROAM_BSSID
+#undef PARAM_RSSI_MODIFIER
+#undef PARAMS_NUM_BSSID
+#undef PARAM_BSSID_PARAMS
+#undef PARAM_A_BAND_BOOST_THLD
+#undef PARAM_A_BAND_PELT_THLD
+#undef PARAM_A_BAND_BOOST_FACTOR
+#undef PARAM_A_BAND_PELT_FACTOR
+#undef PARAM_A_BAND_MAX_BOOST
+#undef PARAM_ROAM_HISTERESYS
+#undef PARAM_RSSI_TRIGGER
+#undef PARAM_ROAM_ENABLE
+
+
+/**
+ * wlan_hdd_cfg80211_set_ext_roam_params() - set ext scan roam params
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int
+wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy,
+				struct wireless_dev *wdev,
+				const void *data,
+				int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_ext_roam_params(wiphy, wdev,
+							data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#define PWR_SAVE_FAIL_CMD_INDEX \
+	QCA_NL80211_VENDOR_SUBCMD_PWR_SAVE_FAIL_DETECTED_INDEX
+
+void hdd_chip_pwr_save_fail_detected_cb(hdd_handle_t hdd_handle,
+			struct chip_pwr_save_fail_detected_params
+			*data)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	struct sk_buff *skb;
+	int flags = cds_get_gfp_flags();
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	if (!data) {
+		hdd_debug("data is null");
+		return;
+	}
+
+	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+			  NULL, NLMSG_HDRLEN +
+			  sizeof(data->failure_reason_code) +
+			  NLMSG_HDRLEN, PWR_SAVE_FAIL_CMD_INDEX,
+			  flags);
+
+	if (!skb) {
+		hdd_info("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	hdd_debug("failure reason code: %u", data->failure_reason_code);
+
+	if (nla_put_u32(skb,
+		QCA_ATTR_CHIP_POWER_SAVE_FAILURE_REASON,
+		data->failure_reason_code))
+		goto fail;
+
+	cfg80211_vendor_event(skb, flags);
+	hdd_exit();
+	return;
+
+fail:
+	kfree_skb(skb);
+}
+#undef PWR_SAVE_FAIL_CMD_INDEX
+
+static const struct nla_policy
+wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
+				       +1] = {
+	[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
+};
+
+/**
+ *  wlan_hdd_check_dfs_channel_for_adapter() - check dfs channel in adapter
+ *  @hdd_ctx:      HDD context
+ *  @device_mode:    device mode
+ *  Return:         bool
+ */
+static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx,
+				enum QDF_OPMODE device_mode)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_ap_ctx *ap_ctx;
+	struct hdd_station_ctx *sta_ctx;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if ((device_mode == adapter->device_mode) &&
+		    (device_mode == QDF_SAP_MODE)) {
+			ap_ctx =
+				WLAN_HDD_GET_AP_CTX_PTR(adapter);
+
+			/*
+			 *  if there is SAP already running on DFS channel,
+			 *  do not disable scan on dfs channels. Note that
+			 *  with SAP on DFS, there cannot be conurrency on
+			 *  single radio. But then we can have multiple
+			 *  radios !!
+			 */
+			if (CHANNEL_STATE_DFS == wlan_reg_get_channel_state(
+						hdd_ctx->pdev,
+						ap_ctx->operating_channel)) {
+				hdd_err("SAP running on DFS channel");
+				return true;
+			}
+		}
+
+		if ((device_mode == adapter->device_mode) &&
+		    (device_mode == QDF_STA_MODE)) {
+			sta_ctx =
+				WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+			/*
+			 *  if STA is already connected on DFS channel,
+			 *  do not disable scan on dfs channels
+			 */
+			if (hdd_conn_is_connected(sta_ctx) &&
+				(CHANNEL_STATE_DFS ==
+				wlan_reg_get_channel_state(hdd_ctx->pdev,
+					sta_ctx->conn_info.operationChannel))) {
+				hdd_err("client connected on DFS channel");
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+/**
+ * wlan_hdd_enable_dfs_chan_scan() - disable/enable DFS channels
+ * @hdd_ctx: HDD context within host driver
+ * @enable_dfs_channels: If true, DFS channels can be used for scanning
+ *
+ * Loops through devices to see who is operating on DFS channels
+ * and then disables/enables DFS channels.
+ * Fails the disable request if any device is active on a DFS channel.
+ *
+ * Return: 0 or other error codes.
+ */
+
+int wlan_hdd_enable_dfs_chan_scan(struct hdd_context *hdd_ctx,
+				  bool enable_dfs_channels)
+{
+	QDF_STATUS status;
+	bool err;
+	mac_handle_t mac_handle;
+
+	if (enable_dfs_channels == hdd_ctx->config->enableDFSChnlScan) {
+		hdd_debug("DFS channels are already %s",
+			  enable_dfs_channels ? "enabled" : "disabled");
+		return 0;
+	}
+
+	if (!enable_dfs_channels) {
+		err = wlan_hdd_check_dfs_channel_for_adapter(hdd_ctx,
+							     QDF_STA_MODE);
+		if (err)
+			return -EOPNOTSUPP;
+
+		err = wlan_hdd_check_dfs_channel_for_adapter(hdd_ctx,
+							     QDF_SAP_MODE);
+		if (err)
+			return -EOPNOTSUPP;
+	}
+
+	hdd_ctx->config->enableDFSChnlScan = enable_dfs_channels;
+
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_enable_dfs_chan_scan(mac_handle, enable_dfs_channels);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to set DFS channel scan flag to %d",
+			enable_dfs_channels);
+		return qdf_status_to_os_return(status);
+	}
+
+	hdd_abort_mac_scan_all_adapters(hdd_ctx);
+
+	/* pass dfs channel status to regulatory component */
+	status = ucfg_reg_enable_dfs_channels(hdd_ctx->pdev,
+					      enable_dfs_channels);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to %s DFS channels",
+			enable_dfs_channels ? "enable" : "disable");
+
+	return qdf_status_to_os_return(status);
+}
+
+/**
+ *  __wlan_hdd_cfg80211_disable_dfs_chan_scan() - DFS channel configuration
+ *  @wiphy:          corestack handler
+ *  @wdev:           wireless device
+ *  @data:           data
+ *  @data_len:       data length
+ *  Return:         success(0) or reason code for failure
+ */
+static int __wlan_hdd_cfg80211_disable_dfs_chan_scan(struct wiphy *wiphy,
+						     struct wireless_dev *wdev,
+						     const void *data,
+						     int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_context *hdd_ctx  = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
+	int ret_val;
+	uint32_t no_dfs_flag = 0;
+
+	hdd_enter_dev(dev);
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		return ret_val;
+
+	if (wlan_cfg80211_nla_parse(tb,
+				    QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
+				    data, data_len,
+				    wlan_hdd_set_no_dfs_flag_config_policy)) {
+		hdd_err("invalid attr");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
+		hdd_err("attr dfs flag failed");
+		return -EINVAL;
+	}
+
+	no_dfs_flag = nla_get_u32(
+		tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
+
+	hdd_debug("DFS flag: %d", no_dfs_flag);
+
+	if (no_dfs_flag > 1) {
+		hdd_err("invalid value of dfs flag");
+		return -EINVAL;
+	}
+
+	ret_val = wlan_hdd_enable_dfs_chan_scan(hdd_ctx, !no_dfs_flag);
+	return ret_val;
+}
+
+/**
+ * wlan_hdd_cfg80211_disable_dfs_chan_scan () - DFS scan vendor command
+ *
+ * @wiphy: wiphy device pointer
+ * @wdev: wireless device pointer
+ * @data: Vendor command data buffer
+ * @data_len: Buffer length
+ *
+ * Handles QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX. Validate it and
+ * call wlan_hdd_disable_dfs_chan_scan to send it to firmware.
+ *
+ * Return: EOK or other error codes.
+ */
+
+static int wlan_hdd_cfg80211_disable_dfs_chan_scan(struct wiphy *wiphy,
+						   struct wireless_dev *wdev,
+						   const void *data,
+						   int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_disable_dfs_chan_scan(wiphy, wdev,
+							data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static const struct nla_policy
+wlan_hdd_wisa_cmd_policy[QCA_WLAN_VENDOR_ATTR_WISA_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_WISA_MODE] = {.type = NLA_U32 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_handle_wisa_cmd() - Handle WISA vendor cmd
+ * @wiphy: wiphy device pointer
+ * @wdev: wireless device pointer
+ * @data: Vendor command data buffer
+ * @data_len: Buffer length
+ *
+ * Handles QCA_WLAN_VENDOR_SUBCMD_WISA. Validate cmd attributes and
+ * setup WISA Mode features.
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int __wlan_hdd_cfg80211_handle_wisa_cmd(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data, int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx  = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WISA_MAX + 1];
+	struct sir_wisa_params wisa;
+	int ret_val;
+	QDF_STATUS status;
+	bool wisa_mode;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	mac_handle_t mac_handle;
+
+	hdd_enter_dev(dev);
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		goto err;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WISA_MAX, data,
+				    data_len, wlan_hdd_wisa_cmd_policy)) {
+		hdd_err("Invalid WISA cmd attributes");
+		ret_val = -EINVAL;
+		goto err;
+	}
+	if (!tb[QCA_WLAN_VENDOR_ATTR_WISA_MODE]) {
+		hdd_err("Invalid WISA mode");
+		ret_val = -EINVAL;
+		goto err;
+	}
+
+	wisa_mode = !!nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_WISA_MODE]);
+	hdd_debug("WISA Mode: %d", wisa_mode);
+	wisa.mode = wisa_mode;
+	wisa.vdev_id = adapter->session_id;
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_set_wisa_params(mac_handle, &wisa);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Unable to set WISA mode: %d to FW", wisa_mode);
+		ret_val = -EINVAL;
+	}
+	if (QDF_IS_STATUS_SUCCESS(status) || wisa_mode == false)
+		cdp_set_wisa_mode(soc,
+			(struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
+				(struct cdp_pdev *)pdev,
+				adapter->session_id),
+			wisa_mode);
+err:
+	hdd_exit();
+	return ret_val;
+}
+
+/**
+ * wlan_hdd_cfg80211_handle_wisa_cmd() - Handle WISA vendor cmd
+ * @wiphy:          corestack handler
+ * @wdev:           wireless device
+ * @data:           data
+ * @data_len:       data length
+ *
+ * Handles QCA_WLAN_VENDOR_SUBCMD_WISA. Validate cmd attributes and
+ * setup WISA mode features.
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int wlan_hdd_cfg80211_handle_wisa_cmd(struct wiphy *wiphy,
+						   struct wireless_dev *wdev,
+						   const void *data,
+						   int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_handle_wisa_cmd(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+struct hdd_station_info *hdd_get_stainfo(struct hdd_station_info *astainfo,
+					 struct qdf_mac_addr mac_addr)
+{
+	struct hdd_station_info *stainfo = NULL;
+	int i;
+
+	for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
+		if (!qdf_mem_cmp(&astainfo[i].sta_mac,
+				 &mac_addr,
+				 QDF_MAC_ADDR_SIZE)) {
+			stainfo = &astainfo[i];
+			break;
+		}
+	}
+
+	return stainfo;
+}
+
+/*
+ * undef short names defined for get station command
+ * used by __wlan_hdd_cfg80211_get_station_cmd()
+ */
+#undef STATION_INVALID
+#undef STATION_INFO
+#undef STATION_ASSOC_FAIL_REASON
+#undef STATION_REMOTE
+#undef STATION_MAX
+#undef LINK_INFO_STANDARD_NL80211_ATTR
+#undef AP_INFO_STANDARD_NL80211_ATTR
+#undef INFO_ROAM_COUNT
+#undef INFO_AKM
+#undef WLAN802_11_MODE
+#undef AP_INFO_HS20_INDICATION
+#undef HT_OPERATION
+#undef VHT_OPERATION
+#undef INFO_ASSOC_FAIL_REASON
+#undef REMOTE_MAX_PHY_RATE
+#undef REMOTE_TX_PACKETS
+#undef REMOTE_TX_BYTES
+#undef REMOTE_RX_PACKETS
+#undef REMOTE_RX_BYTES
+#undef REMOTE_LAST_TX_RATE
+#undef REMOTE_LAST_RX_RATE
+#undef REMOTE_WMM
+#undef REMOTE_SUPPORTED_MODE
+#undef REMOTE_AMPDU
+#undef REMOTE_TX_STBC
+#undef REMOTE_RX_STBC
+#undef REMOTE_CH_WIDTH
+#undef REMOTE_SGI_ENABLE
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+#undef REMOTE_PAD
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * __wlan_hdd_cfg80211_keymgmt_set_key() - Store the Keys in the driver session
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: Pointer to the Key data
+ * @data_len:Length of the data passed
+ *
+ * This is called when wlan driver needs to save the keys received via
+ * vendor specific command.
+ *
+ * Return: Return the Success or Failure code.
+ */
+static int __wlan_hdd_cfg80211_keymgmt_set_key(struct wiphy *wiphy,
+					       struct wireless_dev *wdev,
+					       const void *data, int data_len)
+{
+	uint8_t local_pmk[SIR_ROAM_SCAN_PSK_SIZE];
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *hdd_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	int status;
+	struct pmkid_mode_bits pmkid_modes;
+	mac_handle_t mac_handle;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if ((data == NULL) || (data_len <= 0) ||
+	    (data_len > SIR_ROAM_SCAN_PSK_SIZE)) {
+		hdd_err("Invalid data");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(hdd_adapter);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is null");
+		return -EINVAL;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	hdd_get_pmkid_modes(hdd_ctx, &pmkid_modes);
+
+	mac_handle = hdd_ctx->mac_handle;
+	sme_update_roam_key_mgmt_offload_enabled(mac_handle,
+						 hdd_adapter->session_id,
+						 true, &pmkid_modes);
+	qdf_mem_zero(&local_pmk, SIR_ROAM_SCAN_PSK_SIZE);
+	qdf_mem_copy(local_pmk, data, data_len);
+	sme_roam_set_psk_pmk(mac_handle, hdd_adapter->session_id,
+			     local_pmk, data_len);
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_keymgmt_set_key() - Store the Keys in the driver session
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the Key data
+ * @data_len:Length of the data passed
+ *
+ * This is called when wlan driver needs to save the keys received via
+ * vendor specific command.
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int wlan_hdd_cfg80211_keymgmt_set_key(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_keymgmt_set_key(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
+static const struct nla_policy qca_wlan_vendor_get_wifi_info_policy[
+			QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX] = {.type = NLA_U32 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This is called when wlan driver needs to send wifi driver related info
+ * (driver/fw version) to the user space application upon request.
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int
+__wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  const void *data, int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
+	tSirVersionString driver_version;
+	tSirVersionString firmware_version;
+	const char *hw_version;
+	uint32_t major_spid = 0, minor_spid = 0, siid = 0, crmid = 0;
+	uint32_t sub_id = 0;
+	int status;
+	struct sk_buff *reply_skb;
+	uint32_t skb_len = 0, count = 0;
+
+	hdd_enter_dev(wdev->netdev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	if (wlan_cfg80211_nla_parse(tb_vendor,
+				    QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX,
+				    data, data_len,
+				    qca_wlan_vendor_get_wifi_info_policy)) {
+		hdd_err("WIFI_INFO_GET NL CMD parsing failed");
+		return -EINVAL;
+	}
+
+	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
+		hdd_debug("Rcvd req for Driver version");
+		strlcpy(driver_version, QWLAN_VERSIONSTR,
+			sizeof(driver_version));
+		skb_len += strlen(driver_version) + 1;
+		count++;
+	}
+
+	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
+		hdd_debug("Rcvd req for FW version");
+		hdd_get_fw_version(hdd_ctx, &major_spid, &minor_spid, &siid,
+				   &crmid);
+		sub_id = (hdd_ctx->target_fw_vers_ext & 0xf0000000) >> 28;
+		hw_version = hdd_ctx->target_hw_name;
+		snprintf(firmware_version, sizeof(firmware_version),
+			"FW:%d.%d.%d.%d.%d HW:%s", major_spid, minor_spid,
+			siid, crmid, sub_id, hw_version);
+		skb_len += strlen(firmware_version) + 1;
+		count++;
+	}
+
+	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX]) {
+		hdd_debug("Rcvd req for Radio index");
+		skb_len += sizeof(uint32_t);
+		count++;
+	}
+
+	if (count == 0) {
+		hdd_err("unknown attribute in get_wifi_info request");
+		return -EINVAL;
+	}
+
+	skb_len += (NLA_HDRLEN * count) + NLMSG_HDRLEN;
+	reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, skb_len);
+
+	if (!reply_skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
+		if (nla_put_string(reply_skb,
+			    QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION,
+			    driver_version))
+			goto error_nla_fail;
+	}
+
+	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
+		if (nla_put_string(reply_skb,
+			    QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION,
+			    firmware_version))
+			goto error_nla_fail;
+	}
+
+	if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX]) {
+		if (nla_put_u32(reply_skb,
+				QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX,
+				hdd_ctx->radio_index))
+			goto error_nla_fail;
+	}
+
+	return cfg80211_vendor_cmd_reply(reply_skb);
+
+error_nla_fail:
+	hdd_err("nla put fail");
+	kfree_skb(reply_skb);
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This is called when wlan driver needs to send wifi driver related info
+ * (driver/fw version) to the user space application upon request.
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int
+wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This is called by userspace to know the supported logger features
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int
+__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int status;
+	uint32_t features;
+	struct sk_buff *reply_skb = NULL;
+
+	hdd_enter_dev(wdev->netdev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	features = 0;
+
+	features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
+	features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
+	features |= WIFI_LOGGER_WAKE_LOCK_SUPPORTED;
+	features |= WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
+	features |= WIFI_LOGGER_PACKET_FATE_SUPPORTED;
+
+	reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
+			sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
+	if (!reply_skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	hdd_debug("Supported logger features: 0x%0x", features);
+	if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
+				   features)) {
+		hdd_err("nla put fail");
+		kfree_skb(reply_skb);
+		return -EINVAL;
+	}
+
+	return cfg80211_vendor_cmd_reply(reply_skb);
+}
+
+/**
+ * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This is called by userspace to know the supported logger features
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int
+wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
+							  data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+void wlan_hdd_save_gtk_offload_params(struct hdd_adapter *adapter,
+				      uint8_t *kck_ptr, uint8_t *kek_ptr,
+				      uint32_t kek_len, uint8_t *replay_ctr,
+				      bool big_endian)
+{
+	struct hdd_station_ctx *hdd_sta_ctx;
+	uint8_t *buf;
+	int i;
+	struct pmo_gtk_req *gtk_req = NULL;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	gtk_req = qdf_mem_malloc(sizeof(*gtk_req));
+	if (!gtk_req)
+		return;
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (kck_ptr)
+		qdf_mem_copy(gtk_req->kck, kck_ptr, NL80211_KCK_LEN);
+
+	if (kek_ptr) {
+		/* paranoia */
+		if (kek_len > sizeof(gtk_req->kek)) {
+			kek_len = sizeof(gtk_req->kek);
+			QDF_ASSERT(0);
+		}
+		qdf_mem_copy(gtk_req->kek, kek_ptr, kek_len);
+	}
+
+	qdf_copy_macaddr(&gtk_req->bssid, &hdd_sta_ctx->conn_info.bssId);
+
+	gtk_req->kek_len = kek_len;
+	gtk_req->is_fils_connection = hdd_is_fils_connection(adapter);
+
+	/* convert big to little endian since driver work on little endian */
+	buf = (uint8_t *)&gtk_req->replay_counter;
+	for (i = 0; i < 8; i++)
+		buf[7 - i] = replay_ctr[i];
+
+	status = ucfg_pmo_cache_gtk_offload_req(adapter->vdev, gtk_req);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_err("Failed to cache GTK Offload");
+
+	qdf_mem_free(gtk_req);
+}
+#else
+void wlan_hdd_save_gtk_offload_params(struct hdd_adapter *adapter,
+					     uint8_t *kck_ptr,
+					     uint8_t *kek_ptr,
+					     uint32_t kek_len,
+					     uint8_t *replay_ctr,
+					     bool big_endian)
+{
+}
+#endif
+
+#if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * wlan_hdd_add_fils_params_roam_auth_event() - Adds FILS params in roam auth
+ * @skb: SK buffer
+ * @roam_info: Roam info
+ *
+ * API adds fils params[pmk, pmkid, next sequence number] to roam auth event
+ *
+ * Return: zero on success, error code on failure
+ */
+static int
+wlan_hdd_add_fils_params_roam_auth_event(struct sk_buff *skb,
+					 struct csr_roam_info *roam_info)
+{
+	if (roam_info->pmk_len &&
+	    nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMK,
+		    roam_info->pmk_len, roam_info->pmk)) {
+		hdd_err("pmk send fail");
+		return -EINVAL;
+	}
+
+	if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMKID,
+		    SIR_PMKID_LEN, roam_info->pmkid)) {
+		hdd_err("pmkid send fail");
+		return -EINVAL;
+	}
+
+	hdd_debug("Update ERP Seq Num %d, Next ERP Seq Num %d",
+			roam_info->update_erp_next_seq_num,
+			roam_info->next_erp_seq_num);
+	if (roam_info->update_erp_next_seq_num &&
+	    nla_put_u16(skb,
+			QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_FILS_ERP_NEXT_SEQ_NUM,
+			roam_info->next_erp_seq_num)) {
+		hdd_err("ERP seq num send fail");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#else
+static inline int
+wlan_hdd_add_fils_params_roam_auth_event(struct sk_buff *skb,
+					 struct csr_roam_info *roam_info)
+{
+	return 0;
+}
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * wlan_hdd_send_roam_auth_event() - Send the roamed and authorized event
+ * @adapter: Pointer to adapter struct
+ * @bssid: pointer to bssid of roamed AP.
+ * @req_rsn_ie: Pointer to request RSN IE
+ * @req_rsn_len: Length of the request RSN IE
+ * @rsp_rsn_ie: Pointer to response RSN IE
+ * @rsp_rsn_len: Length of the response RSN IE
+ * @roam_info_ptr: Pointer to the roaming related information
+ *
+ * This is called when wlan driver needs to send the roaming and
+ * authorization information after roaming.
+ *
+ * The information that would be sent is the request RSN IE, response
+ * RSN IE and BSSID of the newly roamed AP.
+ *
+ * If the Authorized status is authenticated, then additional parameters
+ * like PTK's KCK and KEK and Replay Counter would also be passed to the
+ * supplicant.
+ *
+ * The supplicant upon receiving this event would ignore the legacy
+ * cfg80211_roamed call and use the entire information from this event.
+ * The cfg80211_roamed should still co-exist since the kernel will
+ * make use of the parameters even if the supplicant ignores it.
+ *
+ * Return: Return the Success or Failure code.
+ */
+int wlan_hdd_send_roam_auth_event(struct hdd_adapter *adapter, uint8_t *bssid,
+		uint8_t *req_rsn_ie, uint32_t req_rsn_len, uint8_t *rsp_rsn_ie,
+		uint32_t rsp_rsn_len, struct csr_roam_info *roam_info_ptr)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct sk_buff *skb = NULL;
+	eCsrAuthType auth_type;
+	uint32_t fils_params_len;
+	int status;
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	if (!roaming_offload_enabled(hdd_ctx) ||
+	    !roam_info_ptr->roamSynchInProgress)
+		return 0;
+
+	/*
+	 * PMK is sent from FW in Roam Synch Event for FILS Roaming.
+	 * In that case, add three more NL attributes.ie. PMK, PMKID
+	 * and ERP next sequence number. Add corresponding lengths
+	 * with 3 extra NL message headers for each of the
+	 * aforementioned params.
+	 */
+	fils_params_len = roam_info_ptr->pmk_len + SIR_PMKID_LEN +
+			  sizeof(uint16_t) + (3 * NLMSG_HDRLEN);
+
+	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+			&(adapter->wdev),
+			ETH_ALEN + req_rsn_len + rsp_rsn_len +
+			sizeof(uint8_t) + SIR_REPLAY_CTR_LEN +
+			SIR_KCK_KEY_LEN + roam_info_ptr->kek_len +
+			sizeof(uint8_t) + (8 * NLMSG_HDRLEN) +
+			fils_params_len,
+			QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX,
+			GFP_KERNEL);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return -EINVAL;
+	}
+
+	if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID,
+				ETH_ALEN, bssid) ||
+			nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE,
+				req_rsn_len, req_rsn_ie) ||
+			nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE,
+				rsp_rsn_len, rsp_rsn_ie)) {
+		hdd_err("nla put fail");
+		goto nla_put_failure;
+	}
+	if (roam_info_ptr->synchAuthStatus ==
+			CSR_ROAM_AUTH_STATUS_AUTHENTICATED) {
+		hdd_debug("Include Auth Params TLV's");
+		if (nla_put_u8(skb,
+			QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, true)) {
+			hdd_err("nla put fail");
+			goto nla_put_failure;
+		}
+		auth_type = roam_info_ptr->u.pConnectedProfile->AuthType;
+		/* if FT or CCKM connection: dont send replay counter */
+		if (auth_type != eCSR_AUTH_TYPE_FT_RSN &&
+		    auth_type != eCSR_AUTH_TYPE_FT_RSN_PSK &&
+		    auth_type != eCSR_AUTH_TYPE_CCKM_WPA &&
+		    auth_type != eCSR_AUTH_TYPE_CCKM_RSN &&
+		    nla_put(skb,
+			    QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR,
+			    SIR_REPLAY_CTR_LEN,
+			    roam_info_ptr->replay_ctr)) {
+			hdd_err("non FT/non CCKM connection");
+			hdd_err("failed to send replay counter");
+			goto nla_put_failure;
+		}
+		if (roam_info_ptr->kek_len > SIR_KEK_KEY_LEN_FILS ||
+		    nla_put(skb,
+			QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK,
+			SIR_KCK_KEY_LEN, roam_info_ptr->kck) ||
+		    nla_put(skb,
+			QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK,
+			roam_info_ptr->kek_len, roam_info_ptr->kek)) {
+			hdd_err("nla put fail, kek_len %d",
+				roam_info_ptr->kek_len);
+			goto nla_put_failure;
+		}
+
+		status = wlan_hdd_add_fils_params_roam_auth_event(skb,
+							roam_info_ptr);
+		if (status)
+			goto nla_put_failure;
+
+		/*
+		 * Save the gtk rekey parameters in HDD STA context. They will
+		 * be used next time when host enables GTK offload and goes
+		 * into power save state.
+		 */
+		wlan_hdd_save_gtk_offload_params(adapter, roam_info_ptr->kck,
+						 roam_info_ptr->kek,
+						 roam_info_ptr->kek_len,
+						 roam_info_ptr->replay_ctr,
+						 true);
+		hdd_debug("roam_info_ptr->replay_ctr 0x%llx",
+			*((uint64_t *)roam_info_ptr->replay_ctr));
+
+	} else {
+		hdd_debug("No Auth Params TLV's");
+		if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
+					false)) {
+			hdd_err("nla put fail");
+			goto nla_put_failure;
+		}
+	}
+
+	hdd_debug("Auth Status = %d Subnet Change Status = %d",
+		  roam_info_ptr->synchAuthStatus,
+		  roam_info_ptr->subnet_change_status);
+
+	/*
+	 * Add subnet change status if subnet has changed
+	 * 0 = unchanged
+	 * 1 = changed
+	 * 2 = unknown
+	 */
+	if (roam_info_ptr->subnet_change_status) {
+		if (nla_put_u8(skb,
+				QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS,
+				roam_info_ptr->subnet_change_status)) {
+			hdd_err("nla put fail");
+			goto nla_put_failure;
+		}
+	}
+
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EINVAL;
+}
+#endif
+
+#define ANT_DIV_PROBE_PERIOD \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_PERIOD
+#define ANT_DIV_STAY_PERIOD \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_STAY_PERIOD
+#define ANT_DIV_SNR_DIFF \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SNR_DIFF
+#define ANT_DIV_PROBE_DWELL_TIME \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_DWELL_TIME
+#define ANT_DIV_MGMT_SNR_WEIGHT \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_MGMT_SNR_WEIGHT
+#define ANT_DIV_DATA_SNR_WEIGHT \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_DATA_SNR_WEIGHT
+#define ANT_DIV_ACK_SNR_WEIGHT \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ACK_SNR_WEIGHT
+#define RX_REORDER_TIMEOUT_VOICE \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE
+#define RX_REORDER_TIMEOUT_VIDEO \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO
+#define RX_REORDER_TIMEOUT_BESTEFFORT \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT
+#define RX_REORDER_TIMEOUT_BACKGROUND \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND
+#define RX_BLOCKSIZE_PEER_MAC \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC
+#define RX_BLOCKSIZE_WINLIMIT \
+	QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT
+static const struct nla_policy
+wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = {
+
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR] = {.type = NLA_U16 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_NON_AGG_RETRY] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_AGG_RETRY] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_MGMT_RETRY] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_CTRL_RETRY] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_DELAY] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_FAIL_COUNT] = {.type = NLA_U32 },
+	[ANT_DIV_PROBE_PERIOD] = {.type = NLA_U32},
+	[ANT_DIV_STAY_PERIOD] = {.type = NLA_U32},
+	[ANT_DIV_SNR_DIFF] = {.type = NLA_U32},
+	[ANT_DIV_PROBE_DWELL_TIME] = {.type = NLA_U32},
+	[ANT_DIV_MGMT_SNR_WEIGHT] = {.type = NLA_U32},
+	[ANT_DIV_DATA_SNR_WEIGHT] = {.type = NLA_U32},
+	[ANT_DIV_ACK_SNR_WEIGHT] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_RESTRICT_OFFCHANNEL] = {.type = NLA_U8},
+	[RX_REORDER_TIMEOUT_VOICE] = {.type = NLA_U32},
+	[RX_REORDER_TIMEOUT_VIDEO] = {.type = NLA_U32},
+	[RX_REORDER_TIMEOUT_BESTEFFORT] = {.type = NLA_U32},
+	[RX_REORDER_TIMEOUT_BACKGROUND] = {.type = NLA_U32},
+	[RX_BLOCKSIZE_PEER_MAC] = {
+		.type = NLA_UNSPEC,
+		.len = QDF_MAC_ADDR_SIZE},
+	[RX_BLOCKSIZE_WINLIMIT] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_LISTEN_INTERVAL] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_LRO] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL] = {.type = NLA_U16 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_TOTAL_BEACON_MISS_COUNT] = {.type = NLA_U8},
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] = {.type = NLA_U8},
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_GTX] = {.type = NLA_U8},
+};
+
+static const struct nla_policy
+wlan_hdd_wifi_test_config_policy[
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX + 1] = {
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE] = {
+			.type = NLA_U16},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_AC] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_BW] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_NSS] = {
+			.type = NLA_U8},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG] = {
+			.type = NLA_FLAG},
+		[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU] = {
+			.type = NLA_U8},
+};
+
+/**
+ * wlan_hdd_add_qcn_ie() - Add QCN IE to a given IE buffer
+ * @ie_data: IE buffer
+ * @ie_len: length of the @ie_data
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS wlan_hdd_add_qcn_ie(uint8_t *ie_data, uint16_t *ie_len)
+{
+	tDot11fIEQCN_IE qcn_ie;
+	uint8_t qcn_ie_hdr[QCN_IE_HDR_LEN]
+		= {IE_EID_VENDOR, DOT11F_IE_QCN_IE_MAX_LEN,
+			0x8C, 0xFD, 0xF0, 0x1};
+
+	if (((*ie_len) + QCN_IE_HDR_LEN +
+		QCN_IE_VERSION_SUBATTR_DATA_LEN) > MAX_DEFAULT_SCAN_IE_LEN) {
+		hdd_err("IE buffer not enough for QCN IE");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Add QCN IE header */
+	qdf_mem_copy(ie_data + (*ie_len), qcn_ie_hdr, QCN_IE_HDR_LEN);
+	(*ie_len) += QCN_IE_HDR_LEN;
+
+	/* Retrieve Version sub-attribute data */
+	populate_dot11f_qcn_ie(&qcn_ie);
+
+	/* Add QCN IE data[version sub attribute] */
+	qdf_mem_copy(ie_data + (*ie_len), qcn_ie.version,
+				 (QCN_IE_VERSION_SUBATTR_LEN));
+	(*ie_len) += (QCN_IE_VERSION_SUBATTR_LEN);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_hdd_save_default_scan_ies() - API to store the default scan IEs
+ * @hdd_ctx: HDD context
+ * @adapter: Pointer to HDD adapter
+ * @ie_data: Pointer to Scan IEs buffer
+ * @ie_len: Length of Scan IEs
+ *
+ * This API is used to store the default scan ies received from
+ * supplicant. Also saves QCN IE if g_qcn_ie_support INI is enabled
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int wlan_hdd_save_default_scan_ies(struct hdd_context *hdd_ctx,
+					  struct hdd_adapter *adapter,
+					  uint8_t *ie_data, uint16_t ie_len)
+{
+	struct hdd_scan_info *scan_info = &adapter->scan_info;
+	bool add_qcn_ie;
+
+	if (!scan_info)
+		return -EINVAL;
+
+	if (scan_info->default_scan_ies) {
+		qdf_mem_free(scan_info->default_scan_ies);
+		scan_info->default_scan_ies = NULL;
+	}
+
+	scan_info->default_scan_ies_len = ie_len;
+	ucfg_mlme_get_qcn_ie_support(hdd_ctx->psoc, &add_qcn_ie);
+	if (add_qcn_ie)
+		ie_len += (QCN_IE_HDR_LEN + QCN_IE_VERSION_SUBATTR_LEN);
+
+	scan_info->default_scan_ies = qdf_mem_malloc(ie_len);
+	if (!scan_info->default_scan_ies) {
+		scan_info->default_scan_ies_len = 0;
+		return -ENOMEM;
+	}
+
+	qdf_mem_copy(scan_info->default_scan_ies, ie_data,
+			  scan_info->default_scan_ies_len);
+
+	/* Add QCN IE if g_qcn_ie_support INI is enabled */
+	if (add_qcn_ie)
+		wlan_hdd_add_qcn_ie(scan_info->default_scan_ies,
+					&(scan_info->default_scan_ies_len));
+
+	hdd_debug("Saved default scan IE:");
+	qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
+				(uint8_t *) scan_info->default_scan_ies,
+				scan_info->default_scan_ies_len);
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_handle_restrict_offchan_config() -
+ * Handle wifi configuration attribute :
+ * QCA_WLAN_VENDOR_ATTR_CONFIG_RESTRICT_OFFCHANNEL
+ * @adapter: Pointer to HDD adapter
+ * @restrict_offchan: Restrict offchannel setting done by
+ * application
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int wlan_hdd_handle_restrict_offchan_config(struct hdd_adapter *adapter,
+						   u8 restrict_offchan)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	enum QDF_OPMODE dev_mode = adapter->device_mode;
+	int ret_val = 0;
+	QDF_STATUS status;
+
+	if (!(dev_mode == QDF_SAP_MODE || dev_mode == QDF_P2P_GO_MODE)) {
+		hdd_err("Invalid interface type:%d", dev_mode);
+		return -EINVAL;
+	}
+	status = wlan_objmgr_vdev_try_get_ref(adapter->vdev, WLAN_OSIF_ID);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Access hdd_vdev failed: %d", status);
+		return -EINVAL;
+	}
+	if (restrict_offchan == 1) {
+		enum policy_mgr_con_mode pmode =
+		policy_mgr_convert_device_mode_to_qdf_type(dev_mode);
+		int chan;
+
+		u32 vdev_id = wlan_vdev_get_id(adapter->vdev);
+
+		wlan_vdev_obj_lock(adapter->vdev);
+		wlan_vdev_mlme_cap_set(adapter->vdev,
+				       WLAN_VDEV_C_RESTRICT_OFFCHAN);
+		wlan_vdev_obj_unlock(adapter->vdev);
+		chan = policy_mgr_get_channel(hdd_ctx->psoc, pmode,
+					      &vdev_id);
+		if (!chan ||
+		    wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, chan)) {
+			hdd_err("unable to send avoid_freq");
+			ret_val = -EINVAL;
+		}
+		hdd_info("vdev %d mode %d dnbs enabled", vdev_id, dev_mode);
+	} else if (restrict_offchan == 0) {
+		wlan_vdev_obj_lock(adapter->vdev);
+		wlan_vdev_mlme_cap_clear(adapter->vdev,
+					 WLAN_VDEV_C_RESTRICT_OFFCHAN);
+		wlan_vdev_obj_unlock(adapter->vdev);
+		if (wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0)) {
+			hdd_err("unable to clear avoid_freq");
+			ret_val = -EINVAL;
+		}
+		hdd_info("vdev mode %d dnbs disabled", dev_mode);
+	} else {
+		ret_val = -EINVAL;
+		hdd_err("Invalid RESTRICT_OFFCHAN setting");
+	}
+	wlan_objmgr_vdev_release_ref(adapter->vdev, WLAN_OSIF_ID);
+	return ret_val;
+}
+
+/**
+ * wlan_hdd_cfg80211_wifi_set_reorder_timeout - set reorder timeout
+ * @hdd_ctx: hdd context
+ * @tb: array of pointer to struct nlattr
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static
+int wlan_hdd_cfg80211_wifi_set_reorder_timeout(struct hdd_context *hdd_ctx,
+					       struct nlattr *tb[])
+{
+	int ret_val = 0;
+	QDF_STATUS qdf_status;
+	struct sir_set_rx_reorder_timeout_val reorder_timeout;
+	mac_handle_t mac_handle;
+
+#define RX_TIMEOUT_VAL_MIN 10
+#define RX_TIMEOUT_VAL_MAX 1000
+
+	if (tb[RX_REORDER_TIMEOUT_VOICE] ||
+	    tb[RX_REORDER_TIMEOUT_VIDEO] ||
+	    tb[RX_REORDER_TIMEOUT_BESTEFFORT] ||
+	    tb[RX_REORDER_TIMEOUT_BACKGROUND]) {
+
+		/* if one is specified, all must be specified */
+		if (!tb[RX_REORDER_TIMEOUT_VOICE] ||
+		    !tb[RX_REORDER_TIMEOUT_VIDEO] ||
+		    !tb[RX_REORDER_TIMEOUT_BESTEFFORT] ||
+		    !tb[RX_REORDER_TIMEOUT_BACKGROUND]) {
+			hdd_err("four AC timeout val are required MAC");
+			return -EINVAL;
+		}
+
+		reorder_timeout.rx_timeout_pri[0] = nla_get_u32(
+			tb[RX_REORDER_TIMEOUT_VOICE]);
+		reorder_timeout.rx_timeout_pri[1] = nla_get_u32(
+			tb[RX_REORDER_TIMEOUT_VIDEO]);
+		reorder_timeout.rx_timeout_pri[2] = nla_get_u32(
+			tb[RX_REORDER_TIMEOUT_BESTEFFORT]);
+		reorder_timeout.rx_timeout_pri[3] = nla_get_u32(
+			tb[RX_REORDER_TIMEOUT_BACKGROUND]);
+		/* timeout value is required to be in the rang 10 to 1000ms */
+		if (reorder_timeout.rx_timeout_pri[0] >= RX_TIMEOUT_VAL_MIN &&
+		    reorder_timeout.rx_timeout_pri[0] <= RX_TIMEOUT_VAL_MAX &&
+		    reorder_timeout.rx_timeout_pri[1] >= RX_TIMEOUT_VAL_MIN &&
+		    reorder_timeout.rx_timeout_pri[1] <= RX_TIMEOUT_VAL_MAX &&
+		    reorder_timeout.rx_timeout_pri[2] >= RX_TIMEOUT_VAL_MIN &&
+		    reorder_timeout.rx_timeout_pri[2] <= RX_TIMEOUT_VAL_MAX &&
+		    reorder_timeout.rx_timeout_pri[3] >= RX_TIMEOUT_VAL_MIN &&
+		    reorder_timeout.rx_timeout_pri[3] <= RX_TIMEOUT_VAL_MAX) {
+			mac_handle = hdd_ctx->mac_handle;
+			qdf_status = sme_set_reorder_timeout(mac_handle,
+							     &reorder_timeout);
+			if (qdf_status != QDF_STATUS_SUCCESS) {
+				hdd_err("failed to set reorder timeout err %d",
+					qdf_status);
+				ret_val = -EPERM;
+			}
+		} else {
+			hdd_err("one of the timeout value is not in range");
+			ret_val = -EINVAL;
+		}
+	}
+
+	return ret_val;
+}
+
+/**
+ * wlan_hdd_cfg80211_wifi_set_rx_blocksize - set rx blocksize
+ *
+ * @hdd_ctx: hdd context
+ * @adapter: hdd adapter
+ * @tb: array of pointer to struct nlattr
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int wlan_hdd_cfg80211_wifi_set_rx_blocksize(struct hdd_context *hdd_ctx,
+						   struct hdd_adapter *adapter,
+						   struct nlattr *tb[])
+{
+	int ret_val = 0;
+	uint32_t set_value;
+	QDF_STATUS qdf_status;
+	struct sir_peer_set_rx_blocksize rx_blocksize;
+	mac_handle_t mac_handle;
+
+#define WINDOW_SIZE_VAL_MIN 1
+#define WINDOW_SIZE_VAL_MAX 64
+
+	if (tb[RX_BLOCKSIZE_PEER_MAC] ||
+	    tb[RX_BLOCKSIZE_WINLIMIT]) {
+
+		/* if one is specified, both must be specified */
+		if (!tb[RX_BLOCKSIZE_PEER_MAC] ||
+		    !tb[RX_BLOCKSIZE_WINLIMIT]) {
+			hdd_err("Both Peer MAC and windows limit required");
+			return -EINVAL;
+		}
+
+		memcpy(&rx_blocksize.peer_macaddr,
+		       nla_data(tb[RX_BLOCKSIZE_PEER_MAC]),
+		       sizeof(rx_blocksize.peer_macaddr)),
+
+		rx_blocksize.vdev_id = adapter->session_id;
+		set_value = nla_get_u32(tb[RX_BLOCKSIZE_WINLIMIT]);
+		/* maximum window size is 64 */
+		if (set_value >= WINDOW_SIZE_VAL_MIN &&
+		    set_value <= WINDOW_SIZE_VAL_MAX) {
+			rx_blocksize.rx_block_ack_win_limit = set_value;
+			mac_handle = hdd_ctx->mac_handle;
+			qdf_status = sme_set_rx_set_blocksize(mac_handle,
+							      &rx_blocksize);
+			if (qdf_status != QDF_STATUS_SUCCESS) {
+				hdd_err("failed to set aggr sizes err %d",
+					qdf_status);
+				ret_val = -EPERM;
+			}
+		} else {
+			hdd_err("window size val is not in range");
+			ret_val = -EINVAL;
+		}
+	}
+
+	return ret_val;
+}
+
+static int hdd_config_scan_default_ies(struct hdd_adapter *adapter,
+				       const struct nlattr *attr)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	uint8_t *scan_ie;
+	uint16_t scan_ie_len;
+	QDF_STATUS status;
+	mac_handle_t mac_handle;
+
+	if (!attr)
+		return 0;
+
+	scan_ie_len = nla_len(attr);
+	hdd_debug("IE len %d session %d device mode %d",
+		  scan_ie_len, adapter->session_id, adapter->device_mode);
+
+	if (!scan_ie_len) {
+		hdd_err("zero-length IE prohibited");
+		return -EINVAL;
+	}
+
+	if (scan_ie_len > MAX_DEFAULT_SCAN_IE_LEN) {
+		hdd_err("IE length %d exceeds max of %d",
+			scan_ie_len, MAX_DEFAULT_SCAN_IE_LEN);
+		return -EINVAL;
+	}
+
+	scan_ie = nla_data(attr);
+	if (!wlan_is_ie_valid(scan_ie, scan_ie_len)) {
+		hdd_err("Invalid default scan IEs");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_save_default_scan_ies(hdd_ctx, adapter,
+					   scan_ie, scan_ie_len))
+		hdd_err("Failed to save default scan IEs");
+
+	if (adapter->device_mode == QDF_STA_MODE) {
+		mac_handle = hdd_ctx->mac_handle;
+		status = sme_set_default_scan_ie(mac_handle,
+						 adapter->session_id, scan_ie,
+						 scan_ie_len);
+		if (QDF_STATUS_SUCCESS != status) {
+			hdd_err("failed to set default scan IEs in sme: %d",
+				status);
+			return -EPERM;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
+ * vendor command
+ *
+ * @wiphy: wiphy device pointer
+ * @wdev: wireless device pointer
+ * @data: Vendor command data buffer
+ * @data_len: Buffer length
+ *
+ * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
+ *
+ * Return: Error code.
+ */
+static int
+__wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data,
+					   int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx  = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1];
+	const struct nlattr *attr;
+	int ret;
+	int ret_val = 0;
+	u32 modulated_dtim, override_li;
+	u16 stats_avg_factor;
+	u32 guard_time;
+	uint8_t set_value;
+	u32 ftm_capab;
+	u8 qpower;
+	QDF_STATUS status;
+	int attr_len;
+	int access_policy = 0;
+	char vendor_ie[SIR_MAC_MAX_IE_LENGTH + 2];
+	bool vendor_ie_present = false, access_policy_present = false;
+	struct sir_set_tx_rx_aggregation_size request;
+	QDF_STATUS qdf_status;
+	uint8_t retry, delay, enable_flag;
+	uint32_t abs_delay;
+	int param_id;
+	uint32_t tx_fail_count;
+	uint32_t ant_div_usrcfg;
+	uint32_t antdiv_enable, antdiv_chain;
+	uint32_t antdiv_selftest, antdiv_selftest_intvl;
+	uint8_t bmiss_bcnt;
+	uint16_t latency_level;
+	mac_handle_t mac_handle;
+	bool b_value;
+
+	hdd_enter_dev(dev);
+	qdf_mem_zero(&request, sizeof(request));
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		return ret_val;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_CONFIG_MAX, data,
+				    data_len, wlan_hdd_wifi_config_policy)) {
+		hdd_err("invalid attr");
+		return -EINVAL;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT]) {
+		ftm_capab = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT]);
+		hdd_ctx->config->fine_time_meas_cap =
+			hdd_ctx->fine_time_meas_cap_target & ftm_capab;
+		sme_update_fine_time_measurement_capab(mac_handle,
+			adapter->session_id,
+			hdd_ctx->config->fine_time_meas_cap);
+		ucfg_wifi_pos_set_ftm_cap(hdd_ctx->psoc,
+			hdd_ctx->config->fine_time_meas_cap);
+		hdd_debug("FTM capability: user value: 0x%x, target value: 0x%x, final value: 0x%x",
+			 ftm_capab, hdd_ctx->fine_time_meas_cap_target,
+			 hdd_ctx->config->fine_time_meas_cap);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM]) {
+		modulated_dtim = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM]);
+
+		status = ucfg_pmo_config_modulated_dtim(adapter->vdev,
+							modulated_dtim);
+		if (QDF_STATUS_SUCCESS != status)
+			ret_val = -EPERM;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_LISTEN_INTERVAL]) {
+		override_li = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_LISTEN_INTERVAL]);
+
+		if (override_li > cfg_max(CFG_PMO_ENABLE_DYNAMIC_DTIM)) {
+			hdd_err_rl("Invalid value for listen interval - %d",
+				   override_li);
+			return -EINVAL;
+		}
+
+		status = ucfg_pmo_config_listen_interval(adapter->vdev,
+							 override_li);
+		if (status != QDF_STATUS_SUCCESS)
+			ret_val = -EPERM;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_LRO]) {
+		enable_flag = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_LRO]);
+		ret_val = hdd_lro_set_reset(hdd_ctx, adapter,
+							 enable_flag);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE]) {
+		enable_flag =
+			nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE]);
+		sme_set_scan_disable(mac_handle, !enable_flag);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
+		qpower = nla_get_u8(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
+		if (hdd_set_qpower_config(hdd_ctx, adapter, qpower) != 0)
+			ret_val = -EINVAL;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR]) {
+		stats_avg_factor = nla_get_u16(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR]);
+		status = sme_configure_stats_avg_factor(mac_handle,
+							adapter->session_id,
+							stats_avg_factor);
+
+		if (QDF_STATUS_SUCCESS != status)
+			ret_val = -EPERM;
+	}
+
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME]) {
+		guard_time = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME]);
+		status = sme_configure_guard_time(mac_handle,
+						  adapter->session_id,
+						  guard_time);
+
+		if (QDF_STATUS_SUCCESS != status)
+			ret_val = -EPERM;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST]) {
+		qdf_mem_zero(&vendor_ie[0], SIR_MAC_MAX_IE_LENGTH + 2);
+		attr_len = nla_len(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST]);
+		if (attr_len < 0 || attr_len > SIR_MAC_MAX_IE_LENGTH + 2) {
+			hdd_err("Invalid value. attr_len %d",
+				attr_len);
+			return -EINVAL;
+		}
+
+		nla_memcpy(&vendor_ie,
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST],
+			attr_len);
+		vendor_ie_present = true;
+		hdd_debug("Access policy vendor ie present.attr_len %d",
+			attr_len);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY]) {
+		access_policy = (int) nla_get_u32(
+		tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY]);
+		if ((access_policy < QCA_ACCESS_POLICY_ACCEPT_UNLESS_LISTED) ||
+			(access_policy >
+				QCA_ACCESS_POLICY_DENY_UNLESS_LISTED)) {
+			hdd_err("Invalid value. access_policy %d",
+				access_policy);
+			return -EINVAL;
+		}
+		access_policy_present = true;
+		hdd_debug("Access policy present. access_policy %d",
+			access_policy);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_NON_AGG_RETRY]) {
+		retry = nla_get_u8(tb[
+				QCA_WLAN_VENDOR_ATTR_CONFIG_NON_AGG_RETRY]);
+		retry = retry > CFG_NON_AGG_RETRY_MAX ?
+				CFG_NON_AGG_RETRY_MAX : retry;
+		param_id = WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH;
+		ret_val = wma_cli_set_command(adapter->session_id, param_id,
+					      retry, PDEV_CMD);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_AGG_RETRY]) {
+		retry = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_AGG_RETRY]);
+		retry = retry > CFG_AGG_RETRY_MAX ?
+			CFG_AGG_RETRY_MAX : retry;
+
+		/* Value less than CFG_AGG_RETRY_MIN has side effect to t-put */
+		retry = ((retry > 0) && (retry < CFG_AGG_RETRY_MIN)) ?
+				CFG_AGG_RETRY_MIN : retry;
+		param_id = WMI_PDEV_PARAM_AGG_SW_RETRY_TH;
+		ret_val = wma_cli_set_command(adapter->session_id, param_id,
+					      retry, PDEV_CMD);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MGMT_RETRY]) {
+		retry = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MGMT_RETRY]);
+		retry = retry > CFG_MGMT_RETRY_MAX ?
+				CFG_MGMT_RETRY_MAX : retry;
+		param_id = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT;
+		ret_val = wma_cli_set_command(adapter->session_id, param_id,
+					      retry, PDEV_CMD);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_CTRL_RETRY]) {
+		retry = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_CTRL_RETRY]);
+		retry = retry > CFG_CTRL_RETRY_MAX ?
+				CFG_CTRL_RETRY_MAX : retry;
+		param_id = WMI_PDEV_PARAM_CTRL_RETRY_LIMIT;
+		ret_val = wma_cli_set_command(adapter->session_id, param_id,
+					      retry, PDEV_CMD);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_DELAY]) {
+		delay = nla_get_u8(tb[
+				QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_DELAY]);
+		delay = delay > CFG_PROPAGATION_DELAY_MAX ?
+				CFG_PROPAGATION_DELAY_MAX : delay;
+		abs_delay = delay + CFG_PROPAGATION_DELAY_BASE;
+		param_id = WMI_PDEV_PARAM_PROPAGATION_DELAY;
+		ret_val = wma_cli_set_command(adapter->session_id, param_id,
+					      abs_delay, PDEV_CMD);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_ABS_DELAY]) {
+		abs_delay = nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_ABS_DELAY]);
+		param_id = WMI_PDEV_PARAM_PROPAGATION_DELAY;
+		ret_val = wma_cli_set_command(adapter->session_id, param_id,
+					      abs_delay, PDEV_CMD);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_FAIL_COUNT]) {
+		tx_fail_count = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_FAIL_COUNT]);
+		if (tx_fail_count) {
+			status = sme_update_tx_fail_cnt_threshold(mac_handle,
+					adapter->session_id, tx_fail_count);
+			if (QDF_STATUS_SUCCESS != status) {
+				hdd_err("sme_update_tx_fail_cnt_threshold (err=%d)",
+					status);
+				return -EINVAL;
+			}
+		}
+	}
+
+	if (vendor_ie_present && access_policy_present) {
+		if (access_policy == QCA_ACCESS_POLICY_DENY_UNLESS_LISTED) {
+			access_policy =
+				WLAN_HDD_VENDOR_IE_ACCESS_ALLOW_IF_LISTED;
+		} else {
+			access_policy = WLAN_HDD_VENDOR_IE_ACCESS_NONE;
+		}
+
+		hdd_debug("calling sme_update_access_policy_vendor_ie");
+		status = sme_update_access_policy_vendor_ie(mac_handle,
+				adapter->session_id, &vendor_ie[0],
+				access_policy);
+		if (QDF_STATUS_SUCCESS != status) {
+			hdd_err("Failed to set vendor ie and access policy.");
+			return -EINVAL;
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND]) {
+		set_value = nla_get_u8(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND]);
+		hdd_debug("set_value: %d", set_value);
+		ret_val = hdd_enable_disable_ca_event(hdd_ctx, set_value);
+	}
+
+	attr = tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES];
+	ret = hdd_config_scan_default_ies(adapter, attr);
+	if (ret)
+		ret_val = ret;
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION] ||
+	    tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION]) {
+		/* if one is specified, both must be specified */
+		if (!tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION] ||
+		    !tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION]) {
+			hdd_err("Both TX and RX MPDU Aggregation required");
+			return -EINVAL;
+		}
+
+		request.tx_aggregation_size = nla_get_u8(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION]);
+		request.rx_aggregation_size = nla_get_u8(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION]);
+		request.vdev_id = adapter->session_id;
+		request.aggr_type = WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU;
+
+		if (cfg_in_range(CFG_TX_AGGREGATION_SIZE,
+				 request.tx_aggregation_size) &&
+		    cfg_in_range(CFG_RX_AGGREGATION_SIZE,
+				 request.rx_aggregation_size)) {
+			qdf_status = wma_set_tx_rx_aggregation_size(&request);
+			if (qdf_status != QDF_STATUS_SUCCESS) {
+				hdd_err("failed to set aggr sizes err %d",
+					qdf_status);
+				ret_val = -EPERM;
+			}
+		} else {
+			hdd_err("TX %d RX %d MPDU aggr size not in range",
+				request.tx_aggregation_size,
+				request.rx_aggregation_size);
+			ret_val = -EINVAL;
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_IGNORE_ASSOC_DISALLOWED]) {
+		uint8_t ignore_assoc_disallowed;
+
+		ignore_assoc_disallowed
+			= nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_CONFIG_IGNORE_ASSOC_DISALLOWED]);
+		hdd_debug("Set ignore_assoc_disallowed value - %d",
+					ignore_assoc_disallowed);
+		if ((ignore_assoc_disallowed <
+			QCA_IGNORE_ASSOC_DISALLOWED_DISABLE) ||
+			(ignore_assoc_disallowed >
+				QCA_IGNORE_ASSOC_DISALLOWED_ENABLE))
+			return -EPERM;
+
+		sme_update_session_param(mac_handle,
+					 adapter->session_id,
+					 SIR_PARAM_IGNORE_ASSOC_DISALLOWED,
+					 ignore_assoc_disallowed);
+	}
+
+#define ANT_DIV_SET_PERIOD(probe_period, stay_period) \
+	((1<<26)|((probe_period&0x1fff)<<13)|(stay_period&0x1fff))
+
+#define ANT_DIV_SET_SNR_DIFF(snr_diff) \
+	((1<<27)|(snr_diff&0x1fff))
+
+#define ANT_DIV_SET_PROBE_DWELL_TIME(probe_dwell_time) \
+	((1<<28)|(probe_dwell_time&0x1fff))
+
+#define ANT_DIV_SET_WEIGHT(mgmt_snr_weight, data_snr_weight, ack_snr_weight) \
+	((1<<29)|((mgmt_snr_weight&0xff)<<16)|((data_snr_weight&0xff)<<8)| \
+	(ack_snr_weight&0xff))
+
+	if (tb[ANT_DIV_PROBE_PERIOD] ||
+	    tb[ANT_DIV_STAY_PERIOD]) {
+
+		if (!tb[ANT_DIV_PROBE_PERIOD] ||
+		    !tb[ANT_DIV_STAY_PERIOD]) {
+			hdd_err("Both probe and stay period required");
+			return -EINVAL;
+		}
+
+		ant_div_usrcfg = ANT_DIV_SET_PERIOD(
+			nla_get_u32(tb[ANT_DIV_PROBE_PERIOD]),
+			nla_get_u32(tb[ANT_DIV_STAY_PERIOD]));
+		hdd_debug("ant div set period: %x", ant_div_usrcfg);
+		ret_val = wma_cli_set_command((int)adapter->session_id,
+					(int)WMI_PDEV_PARAM_ANT_DIV_USRCFG,
+					ant_div_usrcfg, PDEV_CMD);
+		if (ret_val) {
+			hdd_err("Failed to set ant div period");
+			return ret_val;
+		}
+	}
+
+	if (tb[ANT_DIV_SNR_DIFF]) {
+		ant_div_usrcfg = ANT_DIV_SET_SNR_DIFF(
+			nla_get_u32(tb[ANT_DIV_SNR_DIFF]));
+		hdd_debug("ant div set snr diff: %x", ant_div_usrcfg);
+		ret_val = wma_cli_set_command((int)adapter->session_id,
+					(int)WMI_PDEV_PARAM_ANT_DIV_USRCFG,
+					ant_div_usrcfg, PDEV_CMD);
+		if (ret_val) {
+			hdd_err("Failed to set ant snr diff");
+			return ret_val;
+		}
+	}
+
+	if (tb[ANT_DIV_PROBE_DWELL_TIME]) {
+		ant_div_usrcfg = ANT_DIV_SET_PROBE_DWELL_TIME(
+			nla_get_u32(tb[ANT_DIV_PROBE_DWELL_TIME]));
+		hdd_debug("ant div set probe dewll time: %x",
+					ant_div_usrcfg);
+		ret_val = wma_cli_set_command((int)adapter->session_id,
+					(int)WMI_PDEV_PARAM_ANT_DIV_USRCFG,
+					ant_div_usrcfg, PDEV_CMD);
+		if (ret_val) {
+			hdd_err("Failed to set ant div probe dewll time");
+			return ret_val;
+		}
+	}
+
+	if (tb[ANT_DIV_MGMT_SNR_WEIGHT] ||
+	    tb[ANT_DIV_DATA_SNR_WEIGHT] ||
+	    tb[ANT_DIV_ACK_SNR_WEIGHT]) {
+
+		if (!tb[ANT_DIV_MGMT_SNR_WEIGHT] ||
+		    !tb[ANT_DIV_DATA_SNR_WEIGHT] ||
+		    !tb[ANT_DIV_ACK_SNR_WEIGHT]) {
+			hdd_err("Mgmt snr, data snr and ack snr weight are required");
+			return -EINVAL;
+		}
+
+		ant_div_usrcfg = ANT_DIV_SET_WEIGHT(
+			nla_get_u32(tb[ANT_DIV_MGMT_SNR_WEIGHT]),
+			nla_get_u32(tb[ANT_DIV_DATA_SNR_WEIGHT]),
+			nla_get_u32(tb[ANT_DIV_ACK_SNR_WEIGHT]));
+		hdd_debug("ant div set weight: %x", ant_div_usrcfg);
+		ret_val = wma_cli_set_command((int)adapter->session_id,
+					(int)WMI_PDEV_PARAM_ANT_DIV_USRCFG,
+					ant_div_usrcfg, PDEV_CMD);
+		if (ret_val) {
+			hdd_err("Failed to set ant div weight");
+			return ret_val;
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RESTRICT_OFFCHANNEL]) {
+		u8 restrict_offchan = nla_get_u8(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RESTRICT_OFFCHANNEL]);
+
+		hdd_debug("Restrict offchannel:%d", restrict_offchan);
+		if (restrict_offchan <= 1)
+			ret_val =
+			wlan_hdd_handle_restrict_offchan_config(adapter,
+							restrict_offchan);
+		else {
+			ret_val = -EINVAL;
+			hdd_err("Invalid RESTRICT_OFFCHAN setting");
+		}
+	}
+
+	ret_val =
+		wlan_hdd_cfg80211_wifi_set_reorder_timeout(hdd_ctx, tb);
+	if (ret_val != 0)
+		return ret_val;
+
+	ret_val =
+		wlan_hdd_cfg80211_wifi_set_rx_blocksize(hdd_ctx, adapter, tb);
+	if (ret_val != 0)
+		return ret_val;
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA]) {
+		antdiv_enable = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA]);
+		hdd_debug("antdiv_enable: %d", antdiv_enable);
+		ret_val = wma_cli_set_command((int)adapter->session_id,
+					(int)WMI_PDEV_PARAM_ENA_ANT_DIV,
+					antdiv_enable, PDEV_CMD);
+		if (ret_val) {
+			hdd_err("Failed to set antdiv_enable");
+			return ret_val;
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN]) {
+		antdiv_chain = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN]);
+		hdd_debug("antdiv_chain: %d", antdiv_chain);
+		ret_val = wma_cli_set_command((int)adapter->session_id,
+					(int)WMI_PDEV_PARAM_FORCE_CHAIN_ANT,
+					antdiv_chain, PDEV_CMD);
+		if (ret_val) {
+			hdd_err("Failed to set antdiv_chain");
+			return ret_val;
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST]) {
+		antdiv_selftest = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST]);
+		hdd_debug("antdiv_selftest: %d", antdiv_selftest);
+		ret_val = wma_cli_set_command((int)adapter->session_id,
+					(int)WMI_PDEV_PARAM_ANT_DIV_SELFTEST,
+					antdiv_selftest, PDEV_CMD);
+		if (ret_val) {
+			hdd_err("Failed to set antdiv_selftest");
+			return ret_val;
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL]) {
+		antdiv_selftest_intvl = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL]);
+		hdd_debug("antdiv_selftest_intvl: %d",
+			antdiv_selftest_intvl);
+		ret_val = wma_cli_set_command((int)adapter->session_id,
+				(int)WMI_PDEV_PARAM_ANT_DIV_SELFTEST_INTVL,
+				antdiv_selftest_intvl, PDEV_CMD);
+		if (ret_val) {
+			hdd_err("Failed to set antdiv_selftest_intvl");
+			return ret_val;
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TOTAL_BEACON_MISS_COUNT]) {
+		bmiss_bcnt = nla_get_u8(
+		tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TOTAL_BEACON_MISS_COUNT]);
+		if (hdd_ctx->config->nRoamBmissFirstBcnt < bmiss_bcnt) {
+			hdd_ctx->config->nRoamBmissFinalBcnt = bmiss_bcnt
+				- hdd_ctx->config->nRoamBmissFirstBcnt;
+			hdd_debug("Bmiss first cnt(%d), Bmiss final cnt(%d)",
+				hdd_ctx->config->nRoamBmissFirstBcnt,
+				hdd_ctx->config->nRoamBmissFinalBcnt);
+			ret_val = sme_set_roam_bmiss_final_bcnt(mac_handle,
+				0, hdd_ctx->config->nRoamBmissFinalBcnt);
+
+			if (ret_val) {
+				hdd_err("Failed to set bmiss final Bcnt");
+				return ret_val;
+			}
+
+			ret_val = sme_set_bmiss_bcnt(adapter->session_id,
+				hdd_ctx->config->nRoamBmissFirstBcnt,
+				hdd_ctx->config->nRoamBmissFinalBcnt);
+			if (ret_val) {
+				hdd_err("Failed to set bmiss Bcnt");
+				return ret_val;
+			}
+		} else {
+			hdd_err("Bcnt(%d) needs to exceed BmissFirstBcnt(%d)",
+				bmiss_bcnt,
+				hdd_ctx->config->nRoamBmissFirstBcnt);
+			return -EINVAL;
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL]) {
+		latency_level = nla_get_u16(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL]);
+
+		if ((latency_level >
+		    QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MAX) ||
+		    (latency_level ==
+		    QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_INVALID)) {
+			hdd_err("Invalid Wlan latency level value");
+			return -EINVAL;
+		}
+
+		/* Mapping the latency value to the level which fw expected
+		 * 0 - normal, 1 - moderate, 2 - low, 3 - ultralow
+		 */
+		latency_level = latency_level - 1;
+		qdf_status = sme_set_wlm_latency_level(mac_handle,
+						       adapter->session_id,
+						       latency_level);
+		if (qdf_status != QDF_STATUS_SUCCESS) {
+			hdd_err("set Wlan latency level failed");
+			ret_val = -EINVAL;
+		}
+	}
+
+	if (adapter->device_mode == QDF_STA_MODE &&
+	    tb[QCA_WLAN_VENDOR_ATTR_CONFIG_DISABLE_FILS]) {
+		uint8_t disable_fils;
+		bool value;
+
+		disable_fils = nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_CONFIG_DISABLE_FILS]);
+		hdd_debug("Set disable_fils - %d", disable_fils);
+		value = !disable_fils;
+
+		qdf_status = ucfg_mlme_set_fils_enabled_info(hdd_ctx->psoc,
+							     value);
+		if (QDF_IS_STATUS_ERROR(qdf_status))
+			hdd_err("could not set fils enabled info");
+
+		qdf_status = ucfg_mlme_set_enable_bcast_probe_rsp(hdd_ctx->psoc,
+								  value);
+		if (QDF_IS_STATUS_ERROR(qdf_status))
+			hdd_err("could not set enable bcast probe resp info");
+
+		qdf_status = wma_cli_set_command(
+				(int)adapter->session_id,
+				(int)WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE,
+				!disable_fils, VDEV_CMD);
+		if (qdf_status != QDF_STATUS_SUCCESS) {
+			hdd_err("failed to set enable bcast probe resp");
+			ret_val = -EINVAL;
+		}
+	}
+
+	ucfg_mlme_get_force_rsne_override(hdd_ctx->psoc, &b_value);
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] && b_value) {
+		uint8_t force_rsne_override;
+
+		force_rsne_override =
+			nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
+		if (force_rsne_override > 1) {
+			hdd_err("Invalid test_mode %d", force_rsne_override);
+			ret_val = -EINVAL;
+		}
+
+		hdd_ctx->force_rsne_override = force_rsne_override;
+		hdd_debug("force_rsne_override - %d",
+			   hdd_ctx->force_rsne_override);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GTX]) {
+		uint8_t config_gtx;
+
+		config_gtx = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GTX]);
+		if (config_gtx > 1) {
+			hdd_err_rl("Invalid config_gtx value %d", config_gtx);
+			return -EINVAL;
+		}
+		ret_val = sme_cli_set_command(adapter->session_id,
+					      WMI_VDEV_PARAM_GTX_ENABLE,
+					      config_gtx, VDEV_CMD);
+		if (ret_val)
+			hdd_err("Failed to set GTX");
+	}
+
+	return ret_val;
+}
+
+/**
+ * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
+ * vendor command
+ *
+ * @wiphy: wiphy device pointer
+ * @wdev: wireless device pointer
+ * @data: Vendor command data buffer
+ * @data_len: Buffer length
+ *
+ * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
+ *
+ * Return: EOK or other error codes.
+ */
+static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
+						    struct wireless_dev *wdev,
+						    const void *data,
+						    int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
+							 data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_wifi_test_config() - Wifi test configuration
+ * vendor command
+ *
+ * @wiphy: wiphy device pointer
+ * @wdev: wireless device pointer
+ * @data: Vendor command data buffer
+ * @data_len: Buffer length
+ *
+ * Handles QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX
+ *
+ * Return: Error code.
+ */
+static int
+__wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data, int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx  = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX + 1];
+	int ret_val = 0;
+	uint8_t cfg_val = 0;
+	uint8_t set_val = 0;
+	tSmeConfigParams *sme_config;
+	bool update_sme_cfg = false;
+	uint8_t tid = 0, ac;
+	uint16_t buff_size = 0;
+	mac_handle_t mac_handle;
+	QDF_STATUS status;
+	bool bval = false;
+	uint8_t value = 0;
+	uint8_t wmm_mode = 0;
+	uint32_t cmd_id;
+
+	hdd_enter_dev(dev);
+
+	sme_config = qdf_mem_malloc(sizeof(*sme_config));
+	if (!sme_config)
+		return -ENOMEM;
+
+	mac_handle = hdd_ctx->mac_handle;
+	sme_get_config_param(mac_handle, sme_config);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		ret_val = -EPERM;
+		goto send_err;
+	}
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		goto send_err;
+
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
+		hdd_err("Driver Modules are closed, can not start logger");
+		ret_val = -EINVAL;
+		goto send_err;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb,
+			QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX,
+			data, data_len, wlan_hdd_wifi_test_config_policy)) {
+		hdd_err("invalid attr");
+		ret_val = -EINVAL;
+		goto send_err;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ]) {
+		cfg_val = nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ]
+			);
+		hdd_debug("set addba accept req from peer value %d", cfg_val);
+		ret_val = sme_set_addba_accept(mac_handle, adapter->session_id,
+					       cfg_val);
+		if (ret_val)
+			goto send_err;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS]) {
+		cfg_val = nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS]);
+		hdd_debug("set HE MCS value 0x%0X", cfg_val);
+		ret_val = sme_update_he_mcs(mac_handle, adapter->session_id,
+					    cfg_val);
+		if (ret_val)
+			goto send_err;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE]) {
+		cfg_val = nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE]);
+		if (!cfg_val) {
+			sme_config->csrConfig.WMMSupportMode =
+				hdd_to_csr_wmm_mode(HDD_WMM_USER_MODE_NO_QOS);
+			hdd_debug("wmm is disabled");
+		} else {
+			status = ucfg_mlme_get_wmm_mode(hdd_ctx->psoc,
+							&wmm_mode);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				hdd_err("Get wmm_mode failed");
+				return QDF_STATUS_E_FAILURE;
+			}
+			sme_config->csrConfig.WMMSupportMode =
+				hdd_to_csr_wmm_mode(wmm_mode);
+			hdd_debug("using wmm default value");
+		}
+		update_sme_cfg = true;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ]) {
+		cfg_val = nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ]);
+		if (cfg_val) {
+			/*Auto BA mode*/
+			set_val = 0;
+			hdd_debug("BA operating mode is set to auto");
+		} else {
+			/*Manual BA mode*/
+			set_val = 1;
+			hdd_debug("BA operating mode is set to Manual");
+		}
+
+		ret_val = wma_cli_set_command(adapter->session_id,
+				WMI_VDEV_PARAM_BA_MODE, set_val, VDEV_CMD);
+		if (ret_val) {
+			hdd_err("Set BA operating mode failed");
+			goto send_err;
+		}
+		if (!cfg_val) {
+			ret_val = wma_cli_set_command(adapter->session_id,
+				WMI_VDEV_PARAM_AMSDU_AGGREGATION_SIZE_OPTIMIZATION,
+				0, VDEV_CMD);
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION]) {
+		cfg_val = nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION]
+			);
+		if (cfg_val > HE_FRAG_LEVEL1)
+			set_val = HE_FRAG_LEVEL1;
+		else
+			set_val = cfg_val;
+
+		hdd_debug("set HE fragmention to %d", set_val);
+		ret_val = sme_update_he_frag_supp(mac_handle,
+						  adapter->session_id, set_val);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE]) {
+		cfg_val = nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE]);
+		sme_config->csrConfig.wep_tkip_in_he = cfg_val;
+		hdd_debug("Set WEP/TKIP allow in HE %d", cfg_val);
+
+		update_sme_cfg = true;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION]) {
+		if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID]) {
+			tid = nla_get_u8(tb[
+				QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID]);
+		} else {
+			hdd_err("TID is not set for ADD/DEL BA cfg");
+			ret_val = -EINVAL;
+			goto send_err;
+		}
+		cfg_val = nla_get_u8(tb[
+		QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION]);
+		if (cfg_val == QCA_WLAN_ADD_BA) {
+			if (tb[
+			QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE])
+				buff_size = nla_get_u16(tb[
+				QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE]);
+			ret_val = sme_send_addba_req(mac_handle,
+						     adapter->session_id,
+						     tid, buff_size);
+		} else if (cfg_val == QCA_WLAN_DELETE_BA) {
+		} else {
+			hdd_err("Invalid BA session cfg");
+			ret_val = -EINVAL;
+			goto send_err;
+		}
+	} else if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE]) {
+		buff_size = nla_get_u16(tb[
+		QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE]);
+		hdd_debug("set buff size to %d for all tids", buff_size);
+		ret_val = sme_set_ba_buff_size(mac_handle,
+					       adapter->session_id, buff_size);
+		if (ret_val)
+			goto send_err;
+		if (buff_size > 64)
+			/* Configure ADDBA req buffer size to 256 */
+			set_val = 3;
+		else
+			/* Configure ADDBA req buffer size to 64 */
+			set_val = 2;
+		ret_val = wma_cli_set_command(adapter->session_id,
+				WMI_VDEV_PARAM_BA_MODE, set_val, VDEV_CMD);
+		if (ret_val)
+			hdd_err("Failed to set BA operating mode %d", set_val);
+		ret_val = wma_cli_set_command(adapter->session_id,
+					      GEN_VDEV_PARAM_AMPDU,
+					      buff_size, GEN_CMD);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK]) {
+		int he_mcs_val;
+
+		if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC]) {
+			ac = nla_get_u8(tb[
+			     QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC]);
+		} else {
+			hdd_err("AC is not set for NO ACK policy config");
+			ret_val = -EINVAL;
+			goto send_err;
+		}
+		cfg_val = nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK]);
+		hdd_debug("Set NO_ACK to %d for ac %d", cfg_val, ac);
+		ret_val = sme_set_no_ack_policy(mac_handle,
+						adapter->session_id,
+						cfg_val, ac);
+		if (cfg_val) {
+			status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc,
+							     &bval);
+			if (!QDF_IS_STATUS_SUCCESS(status))
+				hdd_err("unable to get vht_enable2x2");
+			if (bval)
+				/*2x2 MCS 5 value*/
+				he_mcs_val = 0x45;
+			else
+				/*1x1 MCS 5 value*/
+				he_mcs_val = 0x25;
+
+			if (hdd_set_11ax_rate(adapter, he_mcs_val, NULL))
+				hdd_err("HE MCS set failed, MCS val %0x",
+						he_mcs_val);
+		} else {
+			if (hdd_set_11ax_rate(adapter, 0xFF, NULL))
+				hdd_err("disable fixed rate failed");
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF]) {
+		cfg_val = nla_get_u8(tb[
+				QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF]);
+		hdd_debug("Set HE LTF to %d", cfg_val);
+		ret_val = sme_set_auto_rate_he_ltf(mac_handle,
+						   adapter->session_id,
+						   cfg_val);
+		if (ret_val)
+			sme_err("Failed to set auto rate HE LTF");
+
+		ret_val = wma_cli_set_command(adapter->session_id,
+					      WMI_VDEV_PARAM_HE_LTF,
+					      cfg_val, VDEV_CMD);
+		if (ret_val)
+			goto send_err;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE]) {
+		cfg_val = nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE]);
+		hdd_debug("Set Tx beamformee to %d", cfg_val);
+		ret_val = sme_update_tx_bfee_supp(mac_handle,
+						  adapter->session_id,
+						  cfg_val);
+		if (ret_val)
+			sme_err("Failed to set Tx beamformee cap");
+
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS]) {
+		cfg_val = nla_get_u8(tb[
+			QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS]);
+		status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
+								&value);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("unable to get tx_bfee_ant_supp");
+
+		if (cfg_val > value) {
+			hdd_err("NSTS %d not supported, supp_val %d", cfg_val,
+				value);
+			ret_val = -ENOTSUPP;
+			goto send_err;
+		}
+		hdd_debug("Set Tx beamformee NSTS to %d", cfg_val);
+		ret_val = sme_update_tx_bfee_nsts(hdd_ctx->mac_handle,
+						  adapter->session_id,
+						  cfg_val,
+						  value);
+		if (ret_val)
+			sme_err("Failed to set Tx beamformee cap");
+
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR]) {
+		cfg_val = nla_get_u8(tb[
+				     QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR]);
+		if (cfg_val) {
+			hdd_debug("Set HE mac padding dur to %d", cfg_val);
+			ret_val = sme_cli_set_command(adapter->session_id,
+					WMI_VDEV_PARAM_MU_EDCA_FW_UPDATE_EN,
+					0, VDEV_CMD);
+			if (ret_val)
+				hdd_err("MU_EDCA update disable failed");
+			sme_set_usr_cfg_mu_edca(hdd_ctx->mac_handle, true);
+			sme_set_he_mu_edca_def_cfg(hdd_ctx->mac_handle);
+			if (sme_update_mu_edca_params(hdd_ctx->mac_handle,
+						      adapter->session_id))
+				hdd_err("Failed to send mu edca params");
+		} else {
+			ret_val = sme_cli_set_command(adapter->session_id,
+					WMI_VDEV_PARAM_MU_EDCA_FW_UPDATE_EN,
+					1, VDEV_CMD);
+			sme_set_usr_cfg_mu_edca(hdd_ctx->mac_handle, false);
+		}
+		ret_val = sme_update_he_trigger_frm_mac_pad(hdd_ctx->mac_handle,
+							    adapter->session_id,
+							    cfg_val);
+		if (ret_val)
+			hdd_err("Failed to set Trig frame mac padding cap");
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA]) {
+		cfg_val = nla_get_u8(tb[
+				     QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA]);
+		if (cfg_val) {
+			ret_val = sme_cli_set_command(adapter->session_id,
+					WMI_VDEV_PARAM_MU_EDCA_FW_UPDATE_EN,
+					0, VDEV_CMD);
+			if (ret_val)
+				hdd_err("MU_EDCA update disable failed");
+			sme_set_usr_cfg_mu_edca(hdd_ctx->mac_handle, true);
+			sme_set_he_mu_edca_def_cfg(hdd_ctx->mac_handle);
+			if (sme_update_mu_edca_params(hdd_ctx->mac_handle,
+						      adapter->session_id))
+				hdd_err("Failed to send mu edca params");
+		} else {
+			ret_val = sme_cli_set_command(adapter->session_id,
+					WMI_VDEV_PARAM_MU_EDCA_FW_UPDATE_EN,
+					1, VDEV_CMD);
+			sme_set_usr_cfg_mu_edca(hdd_ctx->mac_handle, false);
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP]) {
+		cfg_val = nla_get_u8(tb[
+				     QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP]);
+		ret_val = sme_update_he_om_ctrl_supp(hdd_ctx->mac_handle,
+						     adapter->session_id,
+						     cfg_val);
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_BW;
+	if (tb[cmd_id]) {
+		cfg_val = nla_get_u8(tb[cmd_id]);
+		ret_val = sme_send_he_om_ctrl_bw_update(hdd_ctx->mac_handle,
+							adapter->session_id,
+							cfg_val);
+	}
+	cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_NSS;
+	if (tb[cmd_id]) {
+		cfg_val = nla_get_u8(tb[cmd_id]);
+		ret_val = sme_send_he_om_ctrl_nss_update(hdd_ctx->mac_handle,
+							 adapter->session_id,
+							 cfg_val);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG])
+		sme_reset_he_om_ctrl(hdd_ctx->mac_handle);
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU;
+	if (tb[cmd_id]) {
+		cfg_val = nla_get_u8(tb[cmd_id]);
+		hdd_debug("Configure Tx SU PPDU enable %d", cfg_val);
+		if (cfg_val)
+			sme_config_su_ppdu_queue(adapter->session_id, true);
+		else
+			sme_config_su_ppdu_queue(adapter->session_id, false);
+	}
+
+	if (update_sme_cfg)
+		sme_update_config(mac_handle, sme_config);
+
+send_err:
+	qdf_mem_free(sme_config);
+
+	return ret_val;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_wifi_test_config() - Wifi test configuration
+ * vendor command
+ *
+ * @wiphy: wiphy device pointer
+ * @wdev: wireless device pointer
+ * @data: Vendor command data buffer
+ * @data_len: Buffer length
+ *
+ * Handles QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX
+ *
+ * Return: EOK or other error codes.
+ */
+static int wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_wifi_test_config(wiphy, wdev,
+			data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static const struct
+nla_policy
+qca_wlan_vendor_wifi_logger_start_policy
+[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
+		= {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
+		= {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
+		= {.type = NLA_U32 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
+ * or disable the collection of packet statistics from the firmware
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function enables or disables the collection of packet statistics from
+ * the firmware
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
+	struct sir_wifi_start_log start_log = { 0 };
+	mac_handle_t mac_handle;
+
+	hdd_enter_dev(wdev->netdev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
+		hdd_err("Driver Modules are closed, can not start logger");
+		return -EINVAL;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb,
+				    QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
+				    data, data_len,
+				    qca_wlan_vendor_wifi_logger_start_policy)) {
+		hdd_err("Invalid attribute");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch ring id */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
+		hdd_err("attr ATTR failed");
+		return -EINVAL;
+	}
+	start_log.ring_id = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
+	hdd_debug("Ring ID=%d", start_log.ring_id);
+
+	/* Parse and fetch verbose level */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
+		hdd_err("attr verbose_level failed");
+		return -EINVAL;
+	}
+	start_log.verbose_level = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
+	hdd_debug("verbose_level=%d", start_log.verbose_level);
+
+	/* Parse and fetch flag */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
+		hdd_err("attr flag failed");
+		return -EINVAL;
+	}
+	start_log.is_iwpriv_command = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
+
+	start_log.user_triggered = 1;
+
+	/* size is buff size which can be set using iwpriv command*/
+	start_log.size = 0;
+	start_log.is_pktlog_buff_clear = false;
+
+	cds_set_ring_log_level(start_log.ring_id, start_log.verbose_level);
+
+	if (start_log.ring_id == RING_ID_WAKELOCK) {
+		/* Start/stop wakelock events */
+		if (start_log.verbose_level > WLAN_LOG_LEVEL_OFF)
+			cds_set_wakelock_logging(true);
+		else
+			cds_set_wakelock_logging(false);
+		return 0;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_wifi_start_logger(mac_handle, start_log);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_wifi_start_logger failed(err=%d)",
+				status);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
+ * or disable the collection of packet statistics from the firmware
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function is used to enable or disable the collection of packet
+ * statistics from the firmware
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
+			wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static const struct
+nla_policy
+qca_wlan_vendor_wifi_logger_get_ring_data_policy
+[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
+		= {.type = NLA_U32 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_wifi_logger_get_ring_data() - Flush per packet stats
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function is used to flush or retrieve the per packet statistics from
+ * the driver
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	QDF_STATUS status;
+	uint32_t ring_id;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb
+		[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
+
+	hdd_enter_dev(wdev->netdev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	if (wlan_cfg80211_nla_parse(tb,
+			    QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
+			    data, data_len,
+			    qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
+		hdd_err("Invalid attribute");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch ring id */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
+		hdd_err("attr ATTR failed");
+		return -EINVAL;
+	}
+
+	ring_id = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
+
+	if (ring_id == RING_ID_PER_PACKET_STATS) {
+		wlan_logging_set_per_pkt_stats();
+		hdd_debug("Flushing/Retrieving packet stats");
+	} else if (ring_id == RING_ID_DRIVER_DEBUG) {
+		/*
+		 * As part of DRIVER ring ID, flush both driver and fw logs.
+		 * For other Ring ID's driver doesn't have any rings to flush
+		 */
+		hdd_info("Bug report triggered by framework");
+
+		status = cds_flush_logs(WLAN_LOG_TYPE_NON_FATAL,
+				WLAN_LOG_INDICATOR_FRAMEWORK,
+				WLAN_LOG_REASON_CODE_UNUSED,
+				true, false);
+		if (QDF_STATUS_SUCCESS != status) {
+			hdd_err("Failed to trigger bug report");
+			return -EINVAL;
+		}
+	} else {
+		wlan_report_log_completion(WLAN_LOG_TYPE_NON_FATAL,
+					   WLAN_LOG_INDICATOR_FRAMEWORK,
+					   WLAN_LOG_REASON_CODE_UNUSED,
+					   ring_id);
+	}
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_wifi_logger_get_ring_data() - Wrapper to flush packet stats
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function is used to flush or retrieve the per packet statistics from
+ * the driver
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
+			wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
+/**
+ * hdd_map_req_id_to_pattern_id() - map request id to pattern id
+ * @hdd_ctx: HDD context
+ * @request_id: [input] request id
+ * @pattern_id: [output] pattern id
+ *
+ * This function loops through request id to pattern id array
+ * if the slot is available, store the request id and return pattern id
+ * if entry exists, return the pattern id
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int hdd_map_req_id_to_pattern_id(struct hdd_context *hdd_ctx,
+					  uint32_t request_id,
+					  uint8_t *pattern_id)
+{
+	uint32_t i;
+
+	mutex_lock(&hdd_ctx->op_ctx.op_lock);
+	for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
+		if (hdd_ctx->op_ctx.op_table[i].request_id == MAX_REQUEST_ID) {
+			hdd_ctx->op_ctx.op_table[i].request_id = request_id;
+			*pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
+			mutex_unlock(&hdd_ctx->op_ctx.op_lock);
+			return 0;
+		} else if (hdd_ctx->op_ctx.op_table[i].request_id ==
+					request_id) {
+			*pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
+			mutex_unlock(&hdd_ctx->op_ctx.op_lock);
+			return 0;
+		}
+	}
+	mutex_unlock(&hdd_ctx->op_ctx.op_lock);
+	return -EINVAL;
+}
+
+/**
+ * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
+ * @hdd_ctx: HDD context
+ * @request_id: [input] request id
+ * @pattern_id: [output] pattern id
+ *
+ * This function loops through request id to pattern id array
+ * reset request id to 0 (slot available again) and
+ * return pattern id
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int hdd_unmap_req_id_to_pattern_id(struct hdd_context *hdd_ctx,
+					  uint32_t request_id,
+					  uint8_t *pattern_id)
+{
+	uint32_t i;
+
+	mutex_lock(&hdd_ctx->op_ctx.op_lock);
+	for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
+		if (hdd_ctx->op_ctx.op_table[i].request_id == request_id) {
+			hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
+			*pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
+			mutex_unlock(&hdd_ctx->op_ctx.op_lock);
+			return 0;
+		}
+	}
+	mutex_unlock(&hdd_ctx->op_ctx.op_lock);
+	return -EINVAL;
+}
+
+
+/*
+ * define short names for the global vendor params
+ * used by __wlan_hdd_cfg80211_offloaded_packets()
+ */
+#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
+#define PARAM_REQUEST_ID \
+		QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
+#define PARAM_CONTROL \
+		QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
+#define PARAM_IP_PACKET \
+		QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
+#define PARAM_SRC_MAC_ADDR \
+		QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
+#define PARAM_DST_MAC_ADDR \
+		QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
+#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
+
+/**
+ * wlan_hdd_add_tx_ptrn() - add tx pattern
+ * @adapter: adapter pointer
+ * @hdd_ctx: hdd context
+ * @tb: nl attributes
+ *
+ * This function reads the NL attributes and forms a AddTxPtrn message
+ * posts it to SME.
+ *
+ */
+static int
+wlan_hdd_add_tx_ptrn(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx,
+			struct nlattr **tb)
+{
+	struct sSirAddPeriodicTxPtrn *add_req;
+	QDF_STATUS status;
+	uint32_t request_id, ret, len;
+	uint8_t pattern_id = 0;
+	struct qdf_mac_addr dst_addr;
+	uint16_t eth_type = htons(ETH_P_IP);
+	mac_handle_t mac_handle;
+
+	if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
+		hdd_err("Not in Connected state!");
+		return -ENOTSUPP;
+	}
+
+	add_req = qdf_mem_malloc(sizeof(*add_req));
+	if (!add_req)
+		return -ENOMEM;
+
+	/* Parse and fetch request Id */
+	if (!tb[PARAM_REQUEST_ID]) {
+		hdd_err("attr request id failed");
+		goto fail;
+	}
+
+	request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
+	if (request_id == MAX_REQUEST_ID) {
+		hdd_err("request_id cannot be MAX");
+		goto fail;
+	}
+	hdd_debug("Request Id: %u", request_id);
+
+	if (!tb[PARAM_PERIOD]) {
+		hdd_err("attr period failed");
+		goto fail;
+	}
+	add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
+	hdd_debug("Period: %u ms", add_req->usPtrnIntervalMs);
+	if (add_req->usPtrnIntervalMs == 0) {
+		hdd_err("Invalid interval zero, return failure");
+		goto fail;
+	}
+
+	if (!tb[PARAM_SRC_MAC_ADDR]) {
+		hdd_err("attr source mac address failed");
+		goto fail;
+	}
+	nla_memcpy(add_req->mac_address.bytes, tb[PARAM_SRC_MAC_ADDR],
+			QDF_MAC_ADDR_SIZE);
+	hdd_debug("input src mac address: "MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(add_req->mac_address.bytes));
+
+	if (!qdf_is_macaddr_equal(&add_req->mac_address,
+				  &adapter->mac_addr)) {
+		hdd_err("input src mac address and connected ap bssid are different");
+		goto fail;
+	}
+
+	if (!tb[PARAM_DST_MAC_ADDR]) {
+		hdd_err("attr dst mac address failed");
+		goto fail;
+	}
+	nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], QDF_MAC_ADDR_SIZE);
+	hdd_debug("input dst mac address: "MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(dst_addr.bytes));
+
+	if (!tb[PARAM_IP_PACKET]) {
+		hdd_err("attr ip packet failed");
+		goto fail;
+	}
+	add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
+	hdd_debug("IP packet len: %u", add_req->ucPtrnSize);
+
+	if (add_req->ucPtrnSize < 0 ||
+		add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
+					ETH_HLEN)) {
+		hdd_err("Invalid IP packet len: %d",
+				add_req->ucPtrnSize);
+		goto fail;
+	}
+
+	len = 0;
+	qdf_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, QDF_MAC_ADDR_SIZE);
+	len += QDF_MAC_ADDR_SIZE;
+	qdf_mem_copy(&add_req->ucPattern[len], add_req->mac_address.bytes,
+			QDF_MAC_ADDR_SIZE);
+	len += QDF_MAC_ADDR_SIZE;
+	qdf_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
+	len += 2;
+
+	/*
+	 * This is the IP packet, add 14 bytes Ethernet (802.3) header
+	 * ------------------------------------------------------------
+	 * | 14 bytes Ethernet (802.3) header | IP header and payload |
+	 * ------------------------------------------------------------
+	 */
+	qdf_mem_copy(&add_req->ucPattern[len],
+			nla_data(tb[PARAM_IP_PACKET]),
+			add_req->ucPtrnSize);
+	add_req->ucPtrnSize += len;
+
+	ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
+	if (ret) {
+		hdd_err("req id to pattern id failed (ret=%d)", ret);
+		goto fail;
+	}
+	add_req->ucPtrnId = pattern_id;
+	hdd_debug("pattern id: %d", add_req->ucPtrnId);
+
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_add_periodic_tx_ptrn(mac_handle, add_req);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_add_periodic_tx_ptrn failed (err=%d)", status);
+		goto fail;
+	}
+
+	hdd_exit();
+	qdf_mem_free(add_req);
+	return 0;
+
+fail:
+	qdf_mem_free(add_req);
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_del_tx_ptrn() - delete tx pattern
+ * @adapter: adapter pointer
+ * @hdd_ctx: hdd context
+ * @tb: nl attributes
+ *
+ * This function reads the NL attributes and forms a DelTxPtrn message
+ * posts it to SME.
+ *
+ */
+static int
+wlan_hdd_del_tx_ptrn(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx,
+			struct nlattr **tb)
+{
+	struct sSirDelPeriodicTxPtrn *del_req;
+	QDF_STATUS status;
+	uint32_t request_id, ret;
+	uint8_t pattern_id = 0;
+	mac_handle_t mac_handle;
+
+	/* Parse and fetch request Id */
+	if (!tb[PARAM_REQUEST_ID]) {
+		hdd_err("attr request id failed");
+		return -EINVAL;
+	}
+	request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
+	if (request_id == MAX_REQUEST_ID) {
+		hdd_err("request_id cannot be MAX");
+		return -EINVAL;
+	}
+
+	ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
+	if (ret) {
+		hdd_err("req id to pattern id failed (ret=%d)", ret);
+		return -EINVAL;
+	}
+
+	del_req = qdf_mem_malloc(sizeof(*del_req));
+	if (!del_req)
+		return -ENOMEM;
+
+	qdf_copy_macaddr(&del_req->mac_address, &adapter->mac_addr);
+	hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->mac_address.bytes));
+	del_req->ucPtrnId = pattern_id;
+	hdd_debug("Request Id: %u Pattern id: %d",
+			 request_id, del_req->ucPtrnId);
+
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_del_periodic_tx_ptrn(mac_handle, del_req);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_del_periodic_tx_ptrn failed (err=%d)", status);
+		goto fail;
+	}
+
+	hdd_exit();
+	qdf_mem_free(del_req);
+	return 0;
+
+fail:
+	qdf_mem_free(del_req);
+	return -EINVAL;
+}
+
+
+/**
+ * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     const void *data,
+				     int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[PARAM_MAX + 1];
+	uint8_t control;
+	int ret;
+	static const struct nla_policy policy[PARAM_MAX + 1] = {
+			[PARAM_REQUEST_ID] = { .type = NLA_U32 },
+			[PARAM_CONTROL] = { .type = NLA_U32 },
+			[PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
+						.len = QDF_MAC_ADDR_SIZE },
+			[PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
+						.len = QDF_MAC_ADDR_SIZE },
+			[PARAM_PERIOD] = { .type = NLA_U32 },
+	};
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (!sme_is_feature_supported_by_fw(WLAN_PERIODIC_TX_PTRN)) {
+		hdd_err("Periodic Tx Pattern Offload feature is not supported in FW!");
+		return -ENOTSUPP;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (!tb[PARAM_CONTROL]) {
+		hdd_err("attr control failed");
+		return -EINVAL;
+	}
+	control = nla_get_u32(tb[PARAM_CONTROL]);
+	hdd_debug("Control: %d", control);
+
+	if (control == WLAN_START_OFFLOADED_PACKETS)
+		return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
+	if (control == WLAN_STOP_OFFLOADED_PACKETS)
+		return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
+
+	hdd_err("Invalid control: %d", control);
+	return -EINVAL;
+}
+
+/*
+ * done with short names for the global vendor params
+ * used by __wlan_hdd_cfg80211_offloaded_packets()
+ */
+#undef PARAM_MAX
+#undef PARAM_REQUEST_ID
+#undef PARAM_CONTROL
+#undef PARAM_IP_PACKET
+#undef PARAM_SRC_MAC_ADDR
+#undef PARAM_DST_MAC_ADDR
+#undef PARAM_PERIOD
+
+/**
+ * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
+					wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
+#ifdef WLAN_NS_OFFLOAD
+static const struct nla_policy
+ns_offload_set_policy[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG] = {.type = NLA_U8},
+};
+
+/**
+ * __wlan_hdd_cfg80211_set_ns_offload() - enable/disable NS offload
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_set_ns_offload(struct wiphy *wiphy,
+			struct wireless_dev *wdev,
+			const void *data, int data_len)
+{
+	int status;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX + 1];
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter =  WLAN_HDD_GET_PRIV_PTR(dev);
+
+	hdd_enter_dev(wdev->netdev);
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return status;
+
+	if (!ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc)) {
+		hdd_err("ND Offload not supported");
+		return -EINVAL;
+	}
+
+	if (!ucfg_pmo_is_active_mode_offloaded(hdd_ctx->psoc)) {
+		hdd_warn("Active mode offload is disabled");
+		return -EINVAL;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX,
+				    (struct nlattr *)data, data_len,
+				    ns_offload_set_policy)) {
+		hdd_err("nla_parse failed");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG]) {
+		hdd_err("ND Offload flag attribute not present");
+		return -EINVAL;
+	}
+
+	hdd_ctx->ns_offload_enable =
+		nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG]);
+
+	if (QDF_IBSS_MODE == adapter->device_mode) {
+		hdd_debug("NS Offload is not supported in IBSS mode");
+		return -EINVAL;
+	}
+
+	/* update ns offload in case it is already enabled/disabled */
+	if (hdd_ctx->ns_offload_enable)
+		hdd_enable_ns_offload(adapter, pmo_ns_offload_dynamic_update);
+	else
+		hdd_disable_ns_offload(adapter, pmo_ns_offload_dynamic_update);
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_ns_offload() - enable/disable NS offload
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int wlan_hdd_cfg80211_set_ns_offload(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_ns_offload(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif /* WLAN_NS_OFFLOAD */
+
+static const struct nla_policy get_preferred_freq_list_policy
+		[QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE] = {
+		.type = NLA_U32},
+};
+
+/** __wlan_hdd_cfg80211_get_preferred_freq_list() - get preferred frequency list
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * This function return the preferred frequency list generated by the policy
+ * manager.
+ *
+ * Return: success or failure code
+ */
+static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy,
+						 struct wireless_dev
+						 *wdev, const void *data,
+						 int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int i, ret = 0;
+	QDF_STATUS status;
+	uint8_t pcl[QDF_MAX_NUM_CHAN], weight_list[QDF_MAX_NUM_CHAN];
+	uint32_t pcl_len = 0;
+	uint32_t freq_list[QDF_MAX_NUM_CHAN];
+	enum policy_mgr_con_mode intf_mode;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_MAX + 1];
+	struct sk_buff *reply_skb;
+
+	hdd_enter_dev(wdev->netdev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return -EINVAL;
+
+	if (wlan_cfg80211_nla_parse(tb,
+			       QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_MAX,
+			       data, data_len,
+			       get_preferred_freq_list_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE]) {
+		hdd_err("attr interface type failed");
+		return -EINVAL;
+	}
+
+	intf_mode = nla_get_u32(tb
+		    [QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE]);
+
+	if (intf_mode < PM_STA_MODE || intf_mode >= PM_MAX_NUM_OF_MODE) {
+		hdd_err("Invalid interface type");
+		return -EINVAL;
+	}
+
+	hdd_debug("Userspace requested pref freq list");
+
+	status = policy_mgr_get_pcl(hdd_ctx->psoc,
+				intf_mode, pcl, &pcl_len,
+				weight_list, QDF_ARRAY_SIZE(weight_list));
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Get pcl failed");
+		return -EINVAL;
+	}
+
+	/* convert channel number to frequency */
+	for (i = 0; i < pcl_len; i++) {
+		if (pcl[i] <= ARRAY_SIZE(hdd_channels_2_4_ghz))
+			freq_list[i] =
+				ieee80211_channel_to_frequency(pcl[i],
+							HDD_NL80211_BAND_2GHZ);
+		else
+			freq_list[i] =
+				ieee80211_channel_to_frequency(pcl[i],
+							HDD_NL80211_BAND_5GHZ);
+	}
+
+	/* send the freq_list back to supplicant */
+	reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
+							sizeof(u32) *
+							pcl_len +
+							NLMSG_HDRLEN);
+
+	if (!reply_skb) {
+		hdd_err("Allocate reply_skb failed");
+		return -EINVAL;
+	}
+
+	if (nla_put_u32(reply_skb,
+		QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE,
+			intf_mode) ||
+		nla_put(reply_skb,
+			QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST,
+			sizeof(uint32_t) * pcl_len,
+			freq_list)) {
+		hdd_err("nla put fail");
+		kfree_skb(reply_skb);
+		return -EINVAL;
+	}
+
+	return cfg80211_vendor_cmd_reply(reply_skb);
+}
+
+/** wlan_hdd_cfg80211_get_preferred_freq_list () - get preferred frequency list
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * This function return the preferred frequency list generated by the policy
+ * manager.
+ *
+ * Return: success or failure code
+ */
+static int wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy,
+						 struct wireless_dev
+						 *wdev, const void *data,
+						 int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_preferred_freq_list(wiphy, wdev,
+						data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static const struct nla_policy set_probable_oper_channel_policy
+		[QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE] = {
+		.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ] = {
+		.type = NLA_U32},
+};
+
+/**
+ * __wlan_hdd_cfg80211_set_probable_oper_channel () - set probable channel
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_set_probable_oper_channel(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	struct net_device *ndev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int ret = 0;
+	enum policy_mgr_con_mode intf_mode;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_MAX + 1];
+	uint32_t channel_hint;
+
+	hdd_enter_dev(ndev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (wlan_cfg80211_nla_parse(tb,
+				 QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_MAX,
+				 data, data_len,
+				 set_probable_oper_channel_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE]) {
+		hdd_err("attr interface type failed");
+		return -EINVAL;
+	}
+
+	intf_mode = nla_get_u32(tb
+		    [QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE]);
+
+	if (intf_mode < PM_STA_MODE || intf_mode >= PM_MAX_NUM_OF_MODE) {
+		hdd_err("Invalid interface type");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ]) {
+		hdd_err("attr probable freq failed");
+		return -EINVAL;
+	}
+
+	channel_hint = cds_freq_to_chan(nla_get_u32(tb
+			[QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ]));
+
+	/* check pcl table */
+	if (!policy_mgr_allow_concurrency(hdd_ctx->psoc, intf_mode,
+					channel_hint, HW_MODE_20_MHZ)) {
+		hdd_err("Set channel hint failed due to concurrency check");
+		return -EINVAL;
+	}
+
+	if (0 != wlan_hdd_check_remain_on_channel(adapter))
+		hdd_warn("Remain On Channel Pending");
+
+	if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, channel_hint,
+				POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
+		hdd_err("Failed to change hw mode");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_probable_oper_channel () - set probable channel
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int wlan_hdd_cfg80211_set_probable_oper_channel(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_probable_oper_channel(wiphy, wdev,
+						data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static const struct
+nla_policy
+qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
+	[QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
+		.type = NLA_BINARY, .len = QDF_MAC_ADDR_SIZE },
+};
+
+/**
+ * __wlan_hdd_cfg80211_get_link_properties() - Get link properties
+ * @wiphy: WIPHY structure pointer
+ * @wdev: Wireless device structure pointer
+ * @data: Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function is used to get link properties like nss, rate flags and
+ * operating frequency for the active connection with the given peer.
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int __wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
+						   struct wireless_dev *wdev,
+						   const void *data,
+						   int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_station_ctx *hdd_sta_ctx;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
+	uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
+	uint32_t sta_id;
+	struct sk_buff *reply_skb;
+	uint32_t rate_flags = 0;
+	uint8_t nss;
+	uint8_t final_rate_flags = 0;
+	uint32_t freq;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (0 != wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data,
+				    data_len, qca_wlan_vendor_attr_policy)) {
+		hdd_err("Invalid attribute");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
+		hdd_err("Attribute peerMac not provided for mode=%d",
+		       adapter->device_mode);
+		return -EINVAL;
+	}
+
+	if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < QDF_MAC_ADDR_SIZE) {
+		hdd_err("Attribute peerMac is invalid for mode=%d",
+			adapter->device_mode);
+		return -EINVAL;
+	}
+
+	qdf_mem_copy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
+		     QDF_MAC_ADDR_SIZE);
+	hdd_debug("peerMac="MAC_ADDRESS_STR" for device_mode:%d",
+	       MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
+
+	if (adapter->device_mode == QDF_STA_MODE ||
+	    adapter->device_mode == QDF_P2P_CLIENT_MODE) {
+		hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		if ((hdd_sta_ctx->conn_info.connState !=
+			eConnectionState_Associated) ||
+		    qdf_mem_cmp(hdd_sta_ctx->conn_info.bssId.bytes,
+			peer_mac, QDF_MAC_ADDR_SIZE)) {
+			hdd_err("Not Associated to mac "MAC_ADDRESS_STR,
+			       MAC_ADDR_ARRAY(peer_mac));
+			return -EINVAL;
+		}
+
+		nss  = hdd_sta_ctx->conn_info.nss;
+		freq = cds_chan_to_freq(
+				hdd_sta_ctx->conn_info.operationChannel);
+		rate_flags = hdd_sta_ctx->conn_info.rate_flags;
+	} else if (adapter->device_mode == QDF_P2P_GO_MODE ||
+		   adapter->device_mode == QDF_SAP_MODE) {
+
+		for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
+			if (adapter->sta_info[sta_id].in_use &&
+			    !qdf_is_macaddr_broadcast(
+				&adapter->sta_info[sta_id].sta_mac) &&
+			    !qdf_mem_cmp(
+				&adapter->sta_info[sta_id].sta_mac.bytes,
+				peer_mac, QDF_MAC_ADDR_SIZE))
+				break;
+		}
+
+		if (WLAN_MAX_STA_COUNT == sta_id) {
+			hdd_err("No active peer with mac="MAC_ADDRESS_STR,
+			       MAC_ADDR_ARRAY(peer_mac));
+			return -EINVAL;
+		}
+
+		nss = adapter->sta_info[sta_id].nss;
+		freq = cds_chan_to_freq(
+			(WLAN_HDD_GET_AP_CTX_PTR(adapter))->operating_channel);
+		rate_flags = adapter->sta_info[sta_id].rate_flags;
+	} else {
+		hdd_err("Not Associated! with mac "MAC_ADDRESS_STR,
+		       MAC_ADDR_ARRAY(peer_mac));
+		return -EINVAL;
+	}
+
+	if (!(rate_flags & TX_RATE_LEGACY)) {
+		if (rate_flags & TX_RATE_VHT80) {
+			final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
+			final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
+#endif
+		} else if (rate_flags & TX_RATE_VHT40) {
+			final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
+			final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+#endif
+		} else if (rate_flags & TX_RATE_VHT20) {
+			final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
+		} else if (rate_flags &
+				(TX_RATE_HT20 | TX_RATE_HT40)) {
+			final_rate_flags |= RATE_INFO_FLAGS_MCS;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
+			if (rate_flags & TX_RATE_HT40)
+				final_rate_flags |=
+					RATE_INFO_FLAGS_40_MHZ_WIDTH;
+#endif
+		}
+
+		if (rate_flags & TX_RATE_SGI) {
+			if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
+				final_rate_flags |= RATE_INFO_FLAGS_MCS;
+			final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
+		}
+	}
+
+	reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
+			sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
+
+	if (NULL == reply_skb) {
+		hdd_err("getLinkProperties: skb alloc failed");
+		return -EINVAL;
+	}
+
+	if (nla_put_u8(reply_skb,
+		QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
+		nss) ||
+	    nla_put_u8(reply_skb,
+		QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
+		final_rate_flags) ||
+	    nla_put_u32(reply_skb,
+		QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
+		freq)) {
+		hdd_err("nla_put failed");
+		kfree_skb(reply_skb);
+		return -EINVAL;
+	}
+
+	return cfg80211_vendor_cmd_reply(reply_skb);
+}
+
+/**
+ * wlan_hdd_cfg80211_get_link_properties() - Wrapper function to get link
+ * properties.
+ * @wiphy: WIPHY structure pointer
+ * @wdev: Wireless device structure pointer
+ * @data: Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function is used to get link properties like nss, rate flags and
+ * operating frequency for the active connection with the given peer.
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
+						 struct wireless_dev *wdev,
+						 const void *data,
+						 int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_link_properties(wiphy,
+			wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+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
+wlan_hdd_set_acs_dfs_config_policy[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT] = {.type = NLA_U8 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_acs_dfs_mode() - set ACS DFS mode and channel
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * This function parses the incoming NL vendor command data attributes and
+ * updates the SAP context about channel_hint and DFS mode.
+ * If channel_hint is set, SAP will choose that channel
+ * as operating channel.
+ *
+ * If DFS mode is enabled, driver will include DFS channels
+ * in ACS else driver will skip DFS channels.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX + 1];
+	int ret;
+	struct acs_dfs_policy *acs_policy;
+	int mode = DFS_MODE_NONE;
+	int channel_hint = 0;
+
+	hdd_enter_dev(wdev->netdev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX,
+				    data, data_len,
+				    wlan_hdd_set_acs_dfs_config_policy)) {
+		hdd_err("invalid attr");
+		return -EINVAL;
+	}
+
+	acs_policy = &hdd_ctx->acs_policy;
+	/*
+	 * SCM sends this attribute to restrict SAP from choosing
+	 * DFS channels from ACS.
+	 */
+	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE])
+		mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE]);
+
+	if (!IS_DFS_MODE_VALID(mode)) {
+		hdd_err("attr acs dfs mode is not valid");
+		return -EINVAL;
+	}
+	acs_policy->acs_dfs_mode = mode;
+
+	/*
+	 * SCM sends this attribute to provide an active channel,
+	 * to skip redundant ACS between drivers, and save driver start up time
+	 */
+	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT])
+		channel_hint = nla_get_u8(
+				tb[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT]);
+
+	if (!IS_CHANNEL_VALID(channel_hint)) {
+		hdd_err("acs channel is not valid");
+		return -EINVAL;
+	}
+	acs_policy->acs_channel = channel_hint;
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_acs_dfs_mode() - Wrapper to set ACS DFS mode
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * This function parses the incoming NL vendor command data attributes and
+ * updates the SAP context about channel_hint and DFS mode.
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_acs_dfs_mode(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_get_sta_roam_dfs_mode() - get sta roam dfs mode policy
+ * @mode : cfg80211 dfs mode
+ *
+ * Return: return csr sta roam dfs mode else return NONE
+ */
+static enum sta_roam_policy_dfs_mode wlan_hdd_get_sta_roam_dfs_mode(
+		enum dfs_mode mode)
+{
+	switch (mode) {
+	case DFS_MODE_ENABLE:
+		return CSR_STA_ROAM_POLICY_DFS_ENABLED;
+	case DFS_MODE_DISABLE:
+		return CSR_STA_ROAM_POLICY_DFS_DISABLED;
+	case DFS_MODE_DEPRIORITIZE:
+		return CSR_STA_ROAM_POLICY_DFS_DEPRIORITIZE;
+	default:
+		hdd_err("STA Roam policy dfs mode is NONE");
+		return  CSR_STA_ROAM_POLICY_NONE;
+	}
+}
+
+/*
+ * hdd_get_sap_operating_band:  Get current operating channel
+ * for sap.
+ * @hdd_ctx: hdd context
+ *
+ * Return : Corresponding band for SAP operating channel
+ */
+uint8_t hdd_get_sap_operating_band(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+	uint8_t  operating_channel = 0;
+	uint8_t sap_operating_band = 0;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter->device_mode != QDF_SAP_MODE)
+			continue;
+
+		operating_channel = adapter->session.ap.operating_channel;
+		if (IS_24G_CH(operating_channel))
+			sap_operating_band = BAND_2G;
+		else if (IS_5G_CH(operating_channel))
+			sap_operating_band = BAND_5G;
+		else
+			sap_operating_band = BAND_ALL;
+	}
+
+	return sap_operating_band;
+}
+
+static const struct nla_policy
+wlan_hdd_set_sta_roam_config_policy[
+QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL] = {.type = NLA_U8 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_sta_roam_policy() - Set params to restrict scan channels
+ * for station connection or roaming.
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * __wlan_hdd_cfg80211_sta_roam_policy will decide if DFS channels or unsafe
+ * channels needs to be skipped in scanning or not.
+ * If dfs_mode is disabled, driver will not scan DFS channels.
+ * If skip_unsafe_channels is set, driver will skip unsafe channels
+ * in Scanning.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_sta_roam_policy(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[
+		QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX + 1];
+	int ret;
+	enum sta_roam_policy_dfs_mode sta_roam_dfs_mode;
+	enum dfs_mode mode = DFS_MODE_NONE;
+	bool skip_unsafe_channels = false;
+	QDF_STATUS status;
+	uint8_t sap_operating_band;
+	mac_handle_t mac_handle;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+	if (wlan_cfg80211_nla_parse(tb,
+			       QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX,
+			       data, data_len,
+			       wlan_hdd_set_sta_roam_config_policy)) {
+		hdd_err("invalid attr");
+		return -EINVAL;
+	}
+	if (tb[QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE])
+		mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE]);
+	if (!IS_DFS_MODE_VALID(mode)) {
+		hdd_err("attr sta roam dfs mode policy is not valid");
+		return -EINVAL;
+	}
+
+	sta_roam_dfs_mode = wlan_hdd_get_sta_roam_dfs_mode(mode);
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL])
+		skip_unsafe_channels = nla_get_u8(
+			tb[QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL]);
+	sap_operating_band = hdd_get_sap_operating_band(hdd_ctx);
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_update_sta_roam_policy(mac_handle, sta_roam_dfs_mode,
+					    skip_unsafe_channels,
+					    adapter->session_id,
+					    sap_operating_band);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_update_sta_roam_policy (err=%d)", status);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_sta_roam_policy() - Wrapper to restrict scan channels,
+ * connection and roaming for station.
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * __wlan_hdd_cfg80211_sta_roam_policy will decide if DFS channels or unsafe
+ * channels needs to be skipped in scanning or not.
+ * If dfs_mode is disabled, driver will not scan DFS channels.
+ * If skip_unsafe_channels is set, driver will skip unsafe channels
+ * in Scanning.
+ * Return: 0 on success; errno on failure
+ */
+static int wlan_hdd_cfg80211_sta_roam_policy(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_sta_roam_policy(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_CH_AVOID
+
+static int hdd_validate_avoid_freq_chanlist(
+					struct hdd_context *hdd_ctx,
+					struct ch_avoid_ind_type *channel_list)
+{
+	unsigned int range_idx, ch_idx;
+	unsigned int unsafe_channel_index, unsafe_channel_count = 0;
+	bool ch_found = false;
+
+	unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
+				       (uint16_t)NUM_CHANNELS);
+
+	for (range_idx = 0; range_idx < channel_list->ch_avoid_range_cnt;
+					range_idx++) {
+		if ((channel_list->avoid_freq_range[range_idx].start_freq <
+		     CDS_24_GHZ_CHANNEL_1) ||
+		    (channel_list->avoid_freq_range[range_idx].end_freq >
+		     CDS_5_GHZ_CHANNEL_165) ||
+		    (channel_list->avoid_freq_range[range_idx].start_freq >
+		     channel_list->avoid_freq_range[range_idx].end_freq))
+			continue;
+
+		for (ch_idx = channel_list->
+				avoid_freq_range[range_idx].start_freq;
+		     ch_idx <= channel_list->
+					avoid_freq_range[range_idx].end_freq;
+		     ch_idx++) {
+			for (unsafe_channel_index = 0;
+			     unsafe_channel_index < unsafe_channel_count;
+			     unsafe_channel_index++) {
+				if (ch_idx ==
+					hdd_ctx->unsafe_channel_list[
+					unsafe_channel_index]) {
+					hdd_info("Duplicate channel %d",
+						 ch_idx);
+					ch_found = true;
+					break;
+				}
+			}
+			if (!ch_found) {
+				hdd_ctx->unsafe_channel_list[
+				unsafe_channel_count++] = ch_idx;
+			}
+			ch_found = false;
+		}
+	}
+	return unsafe_channel_count;
+}
+
+/**
+ * __wlan_hdd_cfg80211_avoid_freq() - ask driver to restart SAP if SAP
+ * is on unsafe channel.
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * wlan_hdd_cfg80211_avoid_freq do restart the sap if sap is already
+ * on any of unsafe channels.
+ * If sap is on any of unsafe channel, hdd_unsafe_channel_restart_sap
+ * will send WLAN_SVC_LTE_COEX_IND indication to userspace to restart.
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int ret;
+	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	uint16_t *local_unsafe_list;
+	uint16_t unsafe_channel_count;
+	uint16_t unsafe_channel_index, local_unsafe_list_count;
+	struct ch_avoid_ind_type *channel_list;
+	enum QDF_GLOBAL_MODE curr_mode;
+	uint8_t num_args = 0;
+	bool user_set_avoid_channel = true;
+
+	hdd_enter_dev(wdev->netdev);
+
+	if (!qdf_ctx) {
+		hdd_err("qdf_ctx is NULL");
+		return -EINVAL;
+	}
+	curr_mode = hdd_get_conparam();
+	if (QDF_GLOBAL_FTM_MODE == curr_mode ||
+	    QDF_GLOBAL_MONITOR_MODE == curr_mode) {
+		hdd_err("Command not allowed in FTM/MONITOR mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+	if (!data && data_len == 0) {
+		hdd_debug("Userspace doesn't set avoid frequency channel list");
+		user_set_avoid_channel = false;
+		goto process_unsafe_channel;
+	}
+	if (!data || data_len < (sizeof(channel_list->ch_avoid_range_cnt) +
+				 sizeof(struct ch_avoid_freq_type))) {
+		hdd_err("Avoid frequency channel list empty");
+		return -EINVAL;
+	}
+	num_args = (data_len - sizeof(channel_list->ch_avoid_range_cnt)) /
+		sizeof(channel_list->avoid_freq_range[0].start_freq);
+
+	if (num_args < 2 || num_args > CH_AVOID_MAX_RANGE * 2 ||
+	    num_args % 2 != 0) {
+		hdd_err("Invalid avoid frequency channel list");
+		return -EINVAL;
+	}
+
+	channel_list = (struct ch_avoid_ind_type *)data;
+	if (channel_list->ch_avoid_range_cnt == 0 ||
+	    channel_list->ch_avoid_range_cnt > CH_AVOID_MAX_RANGE ||
+	    2 * channel_list->ch_avoid_range_cnt != num_args) {
+		hdd_err("Invalid frequency range count %d",
+			channel_list->ch_avoid_range_cnt);
+		return -EINVAL;
+	}
+
+process_unsafe_channel:
+	ret = hdd_clone_local_unsafe_chan(hdd_ctx,
+					  &local_unsafe_list,
+					  &local_unsafe_list_count);
+	if (0 != ret) {
+		hdd_err("failed to clone the cur unsafe chan list");
+		return ret;
+	}
+
+	pld_get_wlan_unsafe_channel(qdf_ctx->dev, hdd_ctx->unsafe_channel_list,
+			&(hdd_ctx->unsafe_channel_count),
+			sizeof(hdd_ctx->unsafe_channel_list));
+	if (user_set_avoid_channel) {
+		hdd_ctx->unsafe_channel_count =
+					hdd_validate_avoid_freq_chanlist(
+								hdd_ctx,
+								channel_list);
+		unsafe_channel_count = hdd_ctx->unsafe_channel_count;
+
+		pld_set_wlan_unsafe_channel(qdf_ctx->dev,
+					    hdd_ctx->unsafe_channel_list,
+					    hdd_ctx->unsafe_channel_count);
+	} else {
+		unsafe_channel_count = QDF_MIN(
+					(uint16_t)hdd_ctx->unsafe_channel_count,
+					(uint16_t)NUM_CHANNELS);
+	}
+
+	for (unsafe_channel_index = 0;
+	     unsafe_channel_index < unsafe_channel_count;
+	     unsafe_channel_index++) {
+		hdd_debug("Channel %d is not safe",
+			  hdd_ctx->unsafe_channel_list[unsafe_channel_index]);
+	}
+	if (hdd_local_unsafe_channel_updated(hdd_ctx, local_unsafe_list,
+					     local_unsafe_list_count))
+		hdd_unsafe_channel_restart_sap(hdd_ctx);
+	qdf_mem_free(local_unsafe_list);
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_avoid_freq() - ask driver to restart SAP if SAP
+ * is on unsafe channel.
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * wlan_hdd_cfg80211_avoid_freq do restart the sap if sap is already
+ * on any of unsafe channels.
+ * If sap is on any of unsafe channel, hdd_unsafe_channel_restart_sap
+ * will send WLAN_SVC_LTE_COEX_IND indication to userspace to restart.
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_avoid_freq(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#endif
+/**
+ * __wlan_hdd_cfg80211_sap_configuration_set() - ask driver to restart SAP if
+ * SAP is on unsafe channel.
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * __wlan_hdd_cfg80211_sap_configuration_set function set SAP params to
+ * driver.
+ * QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHAN will set sap config channel and
+ * will initiate restart of sap.
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	struct net_device *ndev = wdev->netdev;
+	struct hdd_adapter *hostapd_adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX + 1];
+	uint8_t config_channel = 0;
+	struct hdd_ap_ctx *ap_ctx;
+	int ret;
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return -EINVAL;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX,
+				    data, data_len,
+				    wlan_hdd_sap_config_policy)) {
+		hdd_err("invalid attr");
+		return -EINVAL;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL]) {
+		if (!test_bit(SOFTAP_BSS_STARTED,
+					&hostapd_adapter->event_flags)) {
+			hdd_err("SAP is not started yet. Restart sap will be invalid");
+			return -EINVAL;
+		}
+
+		config_channel =
+			nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL]);
+
+		if (!((IS_24G_CH(config_channel)) ||
+			(IS_5G_CH(config_channel)))) {
+			hdd_err("Channel  %d is not valid to restart SAP",
+					config_channel);
+			return -ENOTSUPP;
+		}
+
+		ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(hostapd_adapter);
+		ap_ctx->sap_config.channel = config_channel;
+		ap_ctx->sap_config.ch_params.ch_width =
+					ap_ctx->sap_config.ch_width_orig;
+		ap_ctx->bss_stop_reason = BSS_STOP_DUE_TO_VENDOR_CONFIG_CHAN;
+
+		wlan_reg_set_channel_params(hdd_ctx->pdev,
+					    ap_ctx->sap_config.channel,
+					    ap_ctx->sap_config.sec_ch,
+					    &ap_ctx->sap_config.ch_params);
+
+		hdd_restart_sap(hostapd_adapter);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST]) {
+		uint32_t freq_len, i;
+		uint32_t *freq;
+		uint8_t chans[QDF_MAX_NUM_CHAN];
+
+		hdd_debug("setting mandatory freq/chan list");
+
+		freq_len = nla_len(
+		    tb[QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST])/
+		    sizeof(uint32_t);
+
+		if (freq_len > QDF_MAX_NUM_CHAN) {
+			hdd_err("insufficient space to hold channels");
+			return -ENOMEM;
+		}
+
+		freq = nla_data(
+		    tb[QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST]);
+
+		hdd_debug("freq_len=%d", freq_len);
+
+		for (i = 0; i < freq_len; i++) {
+			chans[i] = ieee80211_frequency_to_channel(freq[i]);
+			hdd_debug("freq[%d]=%d", i, freq[i]);
+		}
+
+		status = policy_mgr_set_sap_mandatory_channels(
+			hdd_ctx->psoc, chans, freq_len);
+		if (QDF_IS_STATUS_ERROR(status))
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_sap_configuration_set() - sap configuration vendor command
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * __wlan_hdd_cfg80211_sap_configuration_set function set SAP params to
+ * driver.
+ * QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHAN will set sap config channel and
+ * will initiate restart of sap.
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_sap_configuration_set(wiphy,
+			wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#undef APF_INVALID
+#undef APF_SET_RESET
+#undef APF_VERSION
+#undef APF_ID
+#undef APF_PACKET_SIZE
+#undef APF_CURRENT_OFFSET
+#undef APF_PROGRAM
+#undef APF_MAX
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * define short names for the global vendor params
+ * used by wlan_hdd_cfg80211_wakelock_stats_rsp_callback()
+ */
+#define PARAM_TOTAL_CMD_EVENT_WAKE \
+		QCA_WLAN_VENDOR_ATTR_TOTAL_CMD_EVENT_WAKE
+#define PARAM_CMD_EVENT_WAKE_CNT_PTR \
+		QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_PTR
+#define PARAM_CMD_EVENT_WAKE_CNT_SZ \
+		QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_SZ
+#define PARAM_TOTAL_DRIVER_FW_LOCAL_WAKE \
+		QCA_WLAN_VENDOR_ATTR_TOTAL_DRIVER_FW_LOCAL_WAKE
+#define PARAM_DRIVER_FW_LOCAL_WAKE_CNT_PTR \
+		QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_PTR
+#define PARAM_DRIVER_FW_LOCAL_WAKE_CNT_SZ \
+		QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_SZ
+#define PARAM_TOTAL_RX_DATA_WAKE \
+		QCA_WLAN_VENDOR_ATTR_TOTAL_RX_DATA_WAKE
+#define PARAM_RX_UNICAST_CNT \
+		QCA_WLAN_VENDOR_ATTR_RX_UNICAST_CNT
+#define PARAM_RX_MULTICAST_CNT \
+		QCA_WLAN_VENDOR_ATTR_RX_MULTICAST_CNT
+#define PARAM_RX_BROADCAST_CNT \
+		QCA_WLAN_VENDOR_ATTR_RX_BROADCAST_CNT
+#define PARAM_ICMP_PKT \
+		QCA_WLAN_VENDOR_ATTR_ICMP_PKT
+#define PARAM_ICMP6_PKT \
+		QCA_WLAN_VENDOR_ATTR_ICMP6_PKT
+#define PARAM_ICMP6_RA \
+		QCA_WLAN_VENDOR_ATTR_ICMP6_RA
+#define PARAM_ICMP6_NA \
+		QCA_WLAN_VENDOR_ATTR_ICMP6_NA
+#define PARAM_ICMP6_NS \
+		QCA_WLAN_VENDOR_ATTR_ICMP6_NS
+#define PARAM_ICMP4_RX_MULTICAST_CNT \
+		QCA_WLAN_VENDOR_ATTR_ICMP4_RX_MULTICAST_CNT
+#define PARAM_ICMP6_RX_MULTICAST_CNT \
+		QCA_WLAN_VENDOR_ATTR_ICMP6_RX_MULTICAST_CNT
+#define PARAM_OTHER_RX_MULTICAST_CNT \
+		QCA_WLAN_VENDOR_ATTR_OTHER_RX_MULTICAST_CNT
+#define PARAM_RSSI_BREACH_CNT \
+		QCA_WLAN_VENDOR_ATTR_RSSI_BREACH_CNT
+#define PARAM_LOW_RSSI_CNT \
+		QCA_WLAN_VENDOR_ATTR_LOW_RSSI_CNT
+#define PARAM_GSCAN_CNT \
+		QCA_WLAN_VENDOR_ATTR_GSCAN_CNT
+#define PARAM_PNO_COMPLETE_CNT \
+		QCA_WLAN_VENDOR_ATTR_PNO_COMPLETE_CNT
+#define PARAM_PNO_MATCH_CNT \
+		QCA_WLAN_VENDOR_ATTR_PNO_MATCH_CNT
+
+/**
+ * hdd_send_wakelock_stats() - API to send wakelock stats
+ * @ctx: context to be passed to callback
+ * @data: data passed to callback
+ *
+ * This function is used to send wake lock stats to HAL layer
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+static uint32_t hdd_send_wakelock_stats(struct hdd_context *hdd_ctx,
+					const struct sir_wake_lock_stats *data)
+{
+	struct sk_buff *skb;
+	uint32_t nl_buf_len;
+	uint32_t total_rx_data_wake, rx_multicast_cnt;
+	uint32_t ipv6_rx_multicast_addr_cnt;
+	uint32_t icmpv6_cnt;
+
+	hdd_enter();
+
+	nl_buf_len = NLMSG_HDRLEN;
+	nl_buf_len +=
+		QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX *
+				(NLMSG_HDRLEN + sizeof(uint32_t));
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	hdd_debug("wow_ucast_wake_up_count %d",
+			data->wow_ucast_wake_up_count);
+	hdd_debug("wow_bcast_wake_up_count %d",
+			data->wow_bcast_wake_up_count);
+	hdd_debug("wow_ipv4_mcast_wake_up_count %d",
+			data->wow_ipv4_mcast_wake_up_count);
+	hdd_debug("wow_ipv6_mcast_wake_up_count %d",
+			data->wow_ipv6_mcast_wake_up_count);
+	hdd_debug("wow_ipv6_mcast_ra_stats %d",
+			data->wow_ipv6_mcast_ra_stats);
+	hdd_debug("wow_ipv6_mcast_ns_stats %d",
+			data->wow_ipv6_mcast_ns_stats);
+	hdd_debug("wow_ipv6_mcast_na_stats %d",
+			data->wow_ipv6_mcast_na_stats);
+	hdd_debug("wow_icmpv4_count %d", data->wow_icmpv4_count);
+	hdd_debug("wow_icmpv6_count %d",
+			data->wow_icmpv6_count);
+	hdd_debug("wow_rssi_breach_wake_up_count %d",
+			data->wow_rssi_breach_wake_up_count);
+	hdd_debug("wow_low_rssi_wake_up_count %d",
+			data->wow_low_rssi_wake_up_count);
+	hdd_debug("wow_gscan_wake_up_count %d",
+			data->wow_gscan_wake_up_count);
+	hdd_debug("wow_pno_complete_wake_up_count %d",
+			data->wow_pno_complete_wake_up_count);
+	hdd_debug("wow_pno_match_wake_up_count %d",
+			data->wow_pno_match_wake_up_count);
+
+	ipv6_rx_multicast_addr_cnt =
+		data->wow_ipv6_mcast_wake_up_count;
+
+	icmpv6_cnt =
+		data->wow_icmpv6_count;
+
+	rx_multicast_cnt =
+		data->wow_ipv4_mcast_wake_up_count +
+		ipv6_rx_multicast_addr_cnt;
+
+	total_rx_data_wake =
+		data->wow_ucast_wake_up_count +
+		data->wow_bcast_wake_up_count +
+		rx_multicast_cnt;
+
+	if (nla_put_u32(skb, PARAM_TOTAL_CMD_EVENT_WAKE, 0) ||
+	    nla_put_u32(skb, PARAM_CMD_EVENT_WAKE_CNT_PTR, 0) ||
+	    nla_put_u32(skb, PARAM_CMD_EVENT_WAKE_CNT_SZ, 0) ||
+	    nla_put_u32(skb, PARAM_TOTAL_DRIVER_FW_LOCAL_WAKE, 0) ||
+	    nla_put_u32(skb, PARAM_DRIVER_FW_LOCAL_WAKE_CNT_PTR, 0) ||
+	    nla_put_u32(skb, PARAM_DRIVER_FW_LOCAL_WAKE_CNT_SZ, 0) ||
+	    nla_put_u32(skb, PARAM_TOTAL_RX_DATA_WAKE,
+				total_rx_data_wake) ||
+	    nla_put_u32(skb, PARAM_RX_UNICAST_CNT,
+				data->wow_ucast_wake_up_count) ||
+	    nla_put_u32(skb, PARAM_RX_MULTICAST_CNT,
+				rx_multicast_cnt) ||
+	    nla_put_u32(skb, PARAM_RX_BROADCAST_CNT,
+				data->wow_bcast_wake_up_count) ||
+	    nla_put_u32(skb, PARAM_ICMP_PKT,
+				data->wow_icmpv4_count) ||
+	    nla_put_u32(skb, PARAM_ICMP6_PKT,
+				icmpv6_cnt) ||
+	    nla_put_u32(skb, PARAM_ICMP6_RA,
+				data->wow_ipv6_mcast_ra_stats) ||
+	    nla_put_u32(skb, PARAM_ICMP6_NA,
+				data->wow_ipv6_mcast_na_stats) ||
+	    nla_put_u32(skb, PARAM_ICMP6_NS,
+				data->wow_ipv6_mcast_ns_stats) ||
+	    nla_put_u32(skb, PARAM_ICMP4_RX_MULTICAST_CNT,
+				data->wow_ipv4_mcast_wake_up_count) ||
+	    nla_put_u32(skb, PARAM_ICMP6_RX_MULTICAST_CNT,
+				ipv6_rx_multicast_addr_cnt) ||
+	    nla_put_u32(skb, PARAM_OTHER_RX_MULTICAST_CNT, 0) ||
+	    nla_put_u32(skb, PARAM_RSSI_BREACH_CNT,
+				data->wow_rssi_breach_wake_up_count) ||
+	    nla_put_u32(skb, PARAM_LOW_RSSI_CNT,
+				data->wow_low_rssi_wake_up_count) ||
+	    nla_put_u32(skb, PARAM_GSCAN_CNT,
+				data->wow_gscan_wake_up_count) ||
+	    nla_put_u32(skb, PARAM_PNO_COMPLETE_CNT,
+				data->wow_pno_complete_wake_up_count) ||
+	    nla_put_u32(skb, PARAM_PNO_MATCH_CNT,
+				data->wow_pno_match_wake_up_count)) {
+		hdd_err("nla put fail");
+		goto nla_put_failure;
+	}
+
+	cfg80211_vendor_cmd_reply(skb);
+
+	hdd_exit();
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EINVAL;
+}
+#endif
+
+#ifdef QCA_SUPPORT_CP_STATS
+static int wlan_hdd_process_wake_lock_stats(struct hdd_context *hdd_ctx)
+{
+	return wlan_cfg80211_mc_cp_stats_get_wakelock_stats(hdd_ctx->psoc,
+							    hdd_ctx->wiphy);
+}
+#else
+/**
+ * wlan_hdd_process_wake_lock_stats() - wrapper function to absract cp_stats
+ * or legacy get_wake_lock_stats API.
+ * @hdd_ctx: pointer to hdd_ctx
+ *
+ * Return: 0 on success; error number otherwise.
+ */
+static int wlan_hdd_process_wake_lock_stats(struct hdd_context *hdd_ctx)
+{
+	int ret;
+	QDF_STATUS qdf_status;
+	struct sir_wake_lock_stats wake_lock_stats = {0};
+
+	qdf_status = wma_get_wakelock_stats(&wake_lock_stats);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		hdd_err("failed to get wakelock stats(err=%d)", qdf_status);
+		return -EINVAL;
+	}
+
+	ret = hdd_send_wakelock_stats(hdd_ctx, &wake_lock_stats);
+	if (ret)
+		hdd_err("Failed to post wake lock stats");
+
+	return ret;
+}
+#endif
+
+/**
+ * __wlan_hdd_cfg80211_get_wakelock_stats() - gets wake lock stats
+ * @wiphy: wiphy pointer
+ * @wdev: pointer to struct wireless_dev
+ * @data: pointer to incoming NL vendor data
+ * @data_len: length of @data
+ *
+ * This function parses the incoming NL vendor command data attributes and
+ * invokes the SME Api and blocks on a completion variable.
+ * WMA copies required data and invokes callback
+ * wlan_hdd_cfg80211_wakelock_stats_rsp_callback to send wake lock stats.
+ *
+ * Return: 0 on success; error number otherwise.
+ */
+static int __wlan_hdd_cfg80211_get_wakelock_stats(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return -EINVAL;
+
+	ret = wlan_hdd_process_wake_lock_stats(hdd_ctx);
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_get_wakelock_stats() - gets wake lock stats
+ * @wiphy: wiphy pointer
+ * @wdev: pointer to struct wireless_dev
+ * @data: pointer to incoming NL vendor data
+ * @data_len: length of @data
+ *
+ * This function parses the incoming NL vendor command data attributes and
+ * invokes the SME Api and blocks on a completion variable.
+ * WMA copies required data and invokes callback
+ * wlan_hdd_cfg80211_wakelock_stats_rsp_callback to send wake lock stats.
+ *
+ * Return: 0 on success; error number otherwise.
+ */
+static int wlan_hdd_cfg80211_get_wakelock_stats(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_wakelock_stats(wiphy, wdev, data,
+								data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_get_bus_size() - Get WMI Bus size
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * This function reads wmi max bus size and fill in the skb with
+ * NL attributes and send up the NL event.
+ * Return: 0 on success; errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_get_bus_size(struct wiphy *wiphy,
+				 struct wireless_dev *wdev,
+				 const void *data, int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int ret_val;
+	struct sk_buff *skb;
+	uint32_t nl_buf_len;
+
+	hdd_enter();
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		return ret_val;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	hdd_debug("WMI Max Bus size: %d", hdd_ctx->wmi_max_len);
+
+	nl_buf_len = NLMSG_HDRLEN;
+	nl_buf_len +=  (sizeof(hdd_ctx->wmi_max_len) + NLA_HDRLEN);
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	if (nla_put_u16(skb, QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE,
+			hdd_ctx->wmi_max_len)) {
+		hdd_err("nla put failure");
+		goto nla_put_failure;
+	}
+
+	cfg80211_vendor_cmd_reply(skb);
+
+	hdd_exit();
+
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_get_bus_size() - SSR Wrapper to Get Bus size
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int wlan_hdd_cfg80211_get_bus_size(struct wiphy *wiphy,
+					  struct wireless_dev *wdev,
+					  const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_bus_size(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ *__wlan_hdd_cfg80211_setband() - set band
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
+				       struct wireless_dev *wdev,
+				       const void *data, int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
+	int ret;
+	static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
+		= {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 } };
+
+	hdd_enter();
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
+				    data, data_len, policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
+		hdd_err("attr SETBAND_VALUE failed");
+		return -EINVAL;
+	}
+
+	ret = hdd_reg_set_band(dev,
+		nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
+
+	hdd_exit();
+	return ret;
+}
+
+/**
+ *wlan_hdd_validate_acs_channel() - validate channel provided by ACS
+ * @adapter: hdd adapter
+ * @channel: channel number
+ *
+ * return: QDF status based on success or failure
+ */
+static QDF_STATUS wlan_hdd_validate_acs_channel(struct hdd_adapter *adapter,
+						int channel, int chan_bw)
+{
+	if (QDF_STATUS_SUCCESS !=
+	    wlan_hdd_validate_operation_channel(adapter, channel))
+		return QDF_STATUS_E_FAILURE;
+	if ((wlansap_is_channel_in_nol_list(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+				channel,
+				PHY_SINGLE_CHANNEL_CENTERED))) {
+		hdd_info("channel %d is in nol", channel);
+		return -EINVAL;
+	}
+
+	if ((wlansap_is_channel_leaking_in_nol(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+				channel, chan_bw))) {
+		hdd_info("channel %d is leaking in nol", channel);
+		return -EINVAL;
+	}
+
+	return 0;
+
+}
+
+static void hdd_update_acs_sap_config(struct hdd_context *hdd_ctx,
+				     tsap_config_t *sap_config,
+				     struct hdd_vendor_chan_info *channel_list)
+{
+	uint8_t ch_width;
+	QDF_STATUS status;
+	sap_config->channel = channel_list->pri_ch;
+
+	sap_config->ch_params.center_freq_seg0 =
+				channel_list->vht_seg0_center_ch;
+	sap_config->ch_params.center_freq_seg1 =
+				channel_list->vht_seg1_center_ch;
+
+	sap_config->ch_params.sec_ch_offset = channel_list->ht_sec_ch;
+	sap_config->ch_params.ch_width = channel_list->chan_width;
+	if (sap_config->channel >= 36) {
+		status =
+			ucfg_mlme_get_vht_channel_width(hdd_ctx->psoc,
+							&ch_width);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("Failed to set channel_width");
+		sap_config->ch_width_orig = ch_width;
+	} else {
+		sap_config->ch_width_orig =
+			hdd_ctx->config->nChannelBondingMode24GHz ?
+			eHT_CHANNEL_WIDTH_40MHZ :
+			eHT_CHANNEL_WIDTH_20MHZ;
+	}
+	sap_config->acs_cfg.pri_ch = channel_list->pri_ch;
+	sap_config->acs_cfg.ch_width = channel_list->chan_width;
+	sap_config->acs_cfg.vht_seg0_center_ch =
+				channel_list->vht_seg0_center_ch;
+	sap_config->acs_cfg.vht_seg1_center_ch =
+				channel_list->vht_seg1_center_ch;
+	sap_config->acs_cfg.ht_sec_ch = channel_list->ht_sec_ch;
+}
+
+static int hdd_update_acs_channel(struct hdd_adapter *adapter, uint8_t reason,
+				  uint8_t channel_cnt,
+				  struct hdd_vendor_chan_info *channel_list)
+{
+	tsap_config_t *sap_config;
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	mac_handle_t mac_handle;
+
+	if (!channel_list) {
+		hdd_err("channel_list is NULL");
+		return -EINVAL;
+	}
+
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+	sap_config = &adapter->session.ap.sap_config;
+
+	if (QDF_TIMER_STATE_RUNNING ==
+	    qdf_mc_timer_get_current_state(&adapter->session.
+					ap.vendor_acs_timer)) {
+		qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer);
+	}
+
+	if (channel_list->pri_ch == 0) {
+		/* Check mode, set default channel */
+		channel_list->pri_ch = 6;
+		/*
+		 * sap_select_default_oper_chan(mac_handle,
+		 *      sap_config->acs_cfg.hw_mode);
+		 */
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	switch (reason) {
+	/* SAP init case */
+	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
+		hdd_update_acs_sap_config(hdd_ctx, sap_config, channel_list);
+		/* Update Hostapd */
+		wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
+		break;
+
+	/* DFS detected on current channel */
+	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
+		wlan_sap_update_next_channel(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+				channel_list->pri_ch,
+				channel_list->chan_width);
+		status = sme_update_new_channel_event(
+					mac_handle,
+					adapter->session_id);
+		break;
+
+	/* LTE coex event on current channel */
+	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
+		sap_config->acs_cfg.pri_ch = channel_list->pri_ch;
+		sap_config->acs_cfg.ch_width = channel_list->chan_width;
+		hdd_ap_ctx->sap_config.ch_width_orig =
+				channel_list->chan_width;
+		hdd_switch_sap_channel(adapter, sap_config->acs_cfg.pri_ch,
+				       true);
+		break;
+
+	default:
+		hdd_info("invalid reason for timer invoke");
+	}
+	hdd_exit();
+	return qdf_status_to_os_return(status);
+}
+
+/**
+ * Define short name for vendor channel set config
+ */
+#define SET_CHAN_REASON QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON
+#define SET_CHAN_CHAN_LIST QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST
+#define SET_CHAN_PRIMARY_CHANNEL \
+	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY
+#define SET_CHAN_SECONDARY_CHANNEL \
+	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY
+#define SET_CHAN_SEG0_CENTER_CHANNEL \
+	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0
+#define	SET_CHAN_SEG1_CENTER_CHANNEL \
+	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1
+#define	SET_CHAN_CHANNEL_WIDTH \
+	QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH
+#define	SET_CHAN_MAX QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_MAX
+#define SET_EXT_ACS_BAND QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_BAND
+
+/**
+ * hdd_parse_vendor_acs_chan_config() - API to parse vendor acs channel config
+ * @channel_list: pointer to hdd_vendor_chan_info
+ * @reason: channel change reason
+ * @channel_cnt: channel count
+ * @data: data
+ * @data_len: data len
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int hdd_parse_vendor_acs_chan_config(struct hdd_vendor_chan_info
+		**chan_list_ptr, uint8_t *reason, uint8_t *channel_cnt,
+		const void *data, int data_len)
+{
+	int rem, i = 0;
+	struct nlattr *tb[SET_CHAN_MAX + 1];
+	struct nlattr *tb2[SET_CHAN_MAX + 1];
+	struct nlattr *curr_attr;
+	struct hdd_vendor_chan_info *channel_list;
+
+	if (wlan_cfg80211_nla_parse(tb, SET_CHAN_MAX, data, data_len, NULL)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (tb[SET_CHAN_REASON])
+		*reason = nla_get_u8(tb[SET_CHAN_REASON]);
+
+	nla_for_each_nested(curr_attr, tb[SET_CHAN_CHAN_LIST], rem)
+		i++;
+
+	*channel_cnt = i;
+
+	if (i == 0)
+		hdd_err("incorrect channel count");
+
+	channel_list = qdf_mem_malloc(sizeof(struct hdd_vendor_chan_info) *
+					(*channel_cnt));
+	if (!channel_list)
+		return -ENOMEM;
+
+	i = 0;
+	nla_for_each_nested(curr_attr, tb[SET_CHAN_CHAN_LIST], rem) {
+		if (wlan_cfg80211_nla_parse(tb2, SET_CHAN_MAX,
+					    nla_data(curr_attr),
+					    nla_len(curr_attr), NULL)) {
+			hdd_err("nla_parse failed");
+			return -EINVAL;
+		}
+		if (tb2[SET_EXT_ACS_BAND]) {
+			channel_list[i].band =
+				nla_get_u8(tb2[SET_EXT_ACS_BAND]);
+		}
+		/* Parse and Fetch allowed SSID list*/
+		if (tb2[SET_CHAN_PRIMARY_CHANNEL]) {
+			channel_list[i].pri_ch =
+				nla_get_u8(
+					tb2[SET_CHAN_PRIMARY_CHANNEL]);
+		}
+		if (tb2[SET_CHAN_SECONDARY_CHANNEL]) {
+			channel_list[i].ht_sec_ch =
+				nla_get_u8(tb2[SET_CHAN_SECONDARY_CHANNEL]);
+		}
+		if (tb2[SET_CHAN_SEG0_CENTER_CHANNEL]) {
+			channel_list[i].vht_seg0_center_ch =
+				nla_get_u8(tb2[SET_CHAN_SEG0_CENTER_CHANNEL]);
+		}
+		if (tb2[SET_CHAN_SEG1_CENTER_CHANNEL]) {
+			channel_list[i].vht_seg1_center_ch =
+				nla_get_u8(tb2[SET_CHAN_SEG1_CENTER_CHANNEL]);
+		}
+		if (tb2[SET_CHAN_CHANNEL_WIDTH]) {
+			channel_list[i].chan_width =
+				nla_get_u8(tb2[SET_CHAN_CHANNEL_WIDTH]);
+		}
+		hdd_debug("index %d pri %d sec %d seg0 %d seg1 %d width %d",
+			i, channel_list[i].pri_ch,
+			channel_list[i].ht_sec_ch,
+			channel_list[i].vht_seg0_center_ch,
+			channel_list[i].vht_seg1_center_ch,
+			channel_list[i].chan_width);
+		i++;
+	}
+	*chan_list_ptr = channel_list;
+
+	return 0;
+}
+
+/**
+ * Undef short names for vendor set channel configuration
+ */
+#undef SET_CHAN_REASON
+#undef SET_CHAN_CHANNEL_COUNT
+#undef SET_CHAN_CHAN_LIST
+#undef SET_CHAN_PRIMARY_CHANNEL
+#undef SET_CHAN_SECONDARY_CHANNEL
+#undef SET_CHAN_SEG0_CENTER_CHANNEL
+#undef SET_CHAN_SEG1_CENTER_CHANNEL
+#undef SET_CHAN_CHANNEL_WIDTH
+#undef SET_CHAN_MAX
+
+/**
+ * __wlan_hdd_cfg80211_update_vendor_channel() - update vendor channel
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_update_vendor_channel(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data, int data_len)
+{
+	int ret_val;
+	QDF_STATUS qdf_status;
+	uint8_t channel_cnt = 0, reason = -1;
+	struct hdd_vendor_chan_info *channel_list = NULL;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct hdd_vendor_chan_info *channel_list_ptr;
+
+	hdd_enter();
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		return ret_val;
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
+		clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
+	else {
+		hdd_err("already timeout happened for acs");
+		return -EINVAL;
+	}
+
+	ret_val = hdd_parse_vendor_acs_chan_config(&channel_list, &reason,
+					&channel_cnt, data, data_len);
+	channel_list_ptr = channel_list;
+	if (ret_val)
+		return ret_val;
+
+	/* Validate channel to be set */
+	while (channel_cnt && channel_list) {
+		qdf_status = wlan_hdd_validate_acs_channel(adapter,
+					channel_list->pri_ch,
+					channel_list->chan_width);
+		if (qdf_status == QDF_STATUS_SUCCESS)
+			break;
+		else if (channel_cnt == 1) {
+			hdd_err("invalid channel %d received from app",
+				channel_list->pri_ch);
+			channel_list->pri_ch = 0;
+			break;
+		}
+
+		channel_cnt--;
+		channel_list++;
+	}
+
+	if ((channel_cnt <= 0) || !channel_list) {
+		hdd_err("no available channel/chanlist %d/%pK", channel_cnt,
+			channel_list);
+		qdf_mem_free(channel_list_ptr);
+		return -EINVAL;
+	}
+
+	hdd_debug("received primary channel as %d", channel_list->pri_ch);
+
+	ret_val = hdd_update_acs_channel(adapter, reason,
+				      channel_cnt, channel_list);
+	qdf_mem_free(channel_list_ptr);
+	return ret_val;
+}
+
+/**
+ * wlan_hdd_cfg80211_update_vendor_channel() - update vendor channel
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int wlan_hdd_cfg80211_update_vendor_channel(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_update_vendor_channel(wiphy, wdev, data,
+								data_len);
+	cds_ssr_protect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_setband() - Wrapper to setband
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
+				    struct wireless_dev *wdev,
+				    const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_setband(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_sar_convert_limit_set() - Convert limit set value
+ * @nl80211_value:    Vendor command attribute value
+ * @wmi_value:        Pointer to return converted WMI return value
+ *
+ * Convert NL80211 vendor command value for SAR limit set to WMI value
+ * Return: 0 on success, -1 on invalid value
+ */
+static int wlan_hdd_cfg80211_sar_convert_limit_set(u32 nl80211_value,
+						   u32 *wmi_value)
+{
+	int ret = 0;
+
+	switch (nl80211_value) {
+	case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE:
+		*wmi_value = WMI_SAR_FEATURE_OFF;
+		break;
+	case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0:
+		*wmi_value = WMI_SAR_FEATURE_ON_SET_0;
+		break;
+	case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1:
+		*wmi_value = WMI_SAR_FEATURE_ON_SET_1;
+		break;
+	case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2:
+		*wmi_value = WMI_SAR_FEATURE_ON_SET_2;
+		break;
+	case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3:
+		*wmi_value = WMI_SAR_FEATURE_ON_SET_3;
+		break;
+	case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4:
+		*wmi_value = WMI_SAR_FEATURE_ON_SET_4;
+		break;
+	case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER:
+		*wmi_value = WMI_SAR_FEATURE_ON_USER_DEFINED;
+		break;
+	case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0:
+		*wmi_value = WMI_SAR_FEATURE_ON_SAR_V2_0;
+		break;
+
+	default:
+		ret = -1;
+	}
+	return ret;
+}
+
+#ifdef WLAN_FEATURE_SARV1_TO_SARV2
+/**
+ * hdd_convert_sarv1_to_sarv2() - convert SAR V1 BDF reference to SAR V2
+ * @hdd_ctx: The HDD global context
+ * @tb: The parsed array of netlink attributes
+ * @sar_limit_cmd: The WMI command to be filled
+ *
+ * This feature/function is designed to solve the following problem:
+ * 1) Userspace application was written to use SARv1 BDF entries
+ * 2) Product is configured with SAR V2 BDF entries
+ *
+ * So if this feature is enabled, and if the firmware is configured
+ * with SAR V2 support, and if the incoming request is to enable a SAR
+ * V1 BDF entry, then the WMI command is generated to actually
+ * configure a SAR V2 BDF entry.
+ *
+ * Return: true if conversion was performed and @sar_limit_cmd is
+ * ready to be sent to firmware. Otherwise false in which case the
+ * normal parsing logic should be applied.
+ */
+
+static bool
+hdd_convert_sarv1_to_sarv2(struct hdd_context *hdd_ctx,
+			   struct nlattr *tb[],
+			   struct sar_limit_cmd_params *sar_limit_cmd)
+{
+	struct nlattr *attr;
+	uint32_t bdf_index, set;
+	struct sar_limit_cmd_row *row;
+
+	if (hdd_ctx->sar_version != SAR_VERSION_2) {
+		hdd_debug("SAR version: %d", hdd_ctx->sar_version);
+		return false;
+	}
+
+	attr = tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE];
+	if (!attr)
+		return false;
+
+	bdf_index = nla_get_u32(attr);
+
+	if ((bdf_index >= QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0) &&
+	    (bdf_index <= QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4)) {
+		set = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0;
+	} else if (bdf_index == QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE) {
+		set = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE;
+		bdf_index = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0;
+	} else {
+		return false;
+	}
+
+	/* Need two rows to hold the per-chain V2 power index
+	 * To disable SARv2 limit, send chain, num_limits_row and
+	 * power limit set to 0 (except power index 0xff)
+	 */
+	row = qdf_mem_malloc(2 * sizeof(*row));
+	if (!row)
+		return false;
+
+	if (wlan_hdd_cfg80211_sar_convert_limit_set(
+		set, &sar_limit_cmd->sar_enable)) {
+		hdd_err("Failed to convert SAR limit to WMI value");
+		return false;
+	}
+
+	sar_limit_cmd->commit_limits = 1;
+	sar_limit_cmd->num_limit_rows = 2;
+	sar_limit_cmd->sar_limit_row_list = row;
+	row[0].limit_value = bdf_index;
+	row[1].limit_value = row[0].limit_value;
+	row[0].chain_id = 0;
+	row[1].chain_id = 1;
+	row[0].validity_bitmap = WMI_SAR_CHAIN_ID_VALID_MASK;
+	row[1].validity_bitmap = WMI_SAR_CHAIN_ID_VALID_MASK;
+
+	return true;
+}
+
+#else /* WLAN_FEATURE_SARV1_TO_SARV2 */
+
+static bool
+hdd_convert_sarv1_to_sarv2(struct hdd_context *hdd_ctx,
+			   struct nlattr *tb[],
+			   struct sar_limit_cmd_params *sar_limit_cmd)
+{
+	return false;
+}
+
+#endif /* WLAN_FEATURE_SARV1_TO_SARV2 */
+
+/**
+ * wlan_hdd_cfg80211_sar_convert_band() - Convert WLAN band value
+ * @nl80211_value:    Vendor command attribute value
+ * @wmi_value:        Pointer to return converted WMI return value
+ *
+ * Convert NL80211 vendor command value for SAR BAND to WMI value
+ * Return: 0 on success, -1 on invalid value
+ */
+static int wlan_hdd_cfg80211_sar_convert_band(u32 nl80211_value, u32 *wmi_value)
+{
+	int ret = 0;
+
+	switch (nl80211_value) {
+	case HDD_NL80211_BAND_2GHZ:
+		*wmi_value = WMI_SAR_2G_ID;
+		break;
+	case HDD_NL80211_BAND_5GHZ:
+		*wmi_value = WMI_SAR_5G_ID;
+		break;
+	default:
+		ret = -1;
+	}
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_sar_convert_modulation() - Convert WLAN modulation value
+ * @nl80211_value:    Vendor command attribute value
+ * @wmi_value:        Pointer to return converted WMI return value
+ *
+ * Convert NL80211 vendor command value for SAR Modulation to WMI value
+ * Return: 0 on success, -1 on invalid value
+ */
+static int wlan_hdd_cfg80211_sar_convert_modulation(u32 nl80211_value,
+						    u32 *wmi_value)
+{
+	int ret = 0;
+
+	switch (nl80211_value) {
+	case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_CCK:
+		*wmi_value = WMI_SAR_MOD_CCK;
+		break;
+	case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_OFDM:
+		*wmi_value = WMI_SAR_MOD_OFDM;
+		break;
+	default:
+		ret = -1;
+	}
+	return ret;
+}
+
+static const struct nla_policy
+sar_limits_policy[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX] = {.type = NLA_U32},
+};
+
+/**
+ * __wlan_hdd_set_sar_power_limits() - Set SAR power limits
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * This function is used to setup Specific Absorption Rate limit specs.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_set_sar_power_limits(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data, int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX + 1],
+		      *tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX + 1],
+		      *sar_spec_list;
+	struct sar_limit_cmd_params sar_limit_cmd = {0};
+	int ret = -EINVAL, i = 0, rem = 0;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX,
+				    data, data_len, sar_limits_policy)) {
+		hdd_err("Invalid SAR attributes");
+		return -EINVAL;
+	}
+
+	/* is special SAR V1 => SAR V2 logic enabled and applicable? */
+	if (hdd_convert_sarv1_to_sarv2(hdd_ctx, tb, &sar_limit_cmd))
+		goto send_sar_limits;
+
+	/* Vendor command manadates all SAR Specs in single call */
+	sar_limit_cmd.commit_limits = 1;
+	sar_limit_cmd.sar_enable = WMI_SAR_FEATURE_NO_CHANGE;
+	if (tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE]) {
+		if (wlan_hdd_cfg80211_sar_convert_limit_set(nla_get_u32(
+				tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE]),
+				&sar_limit_cmd.sar_enable) < 0) {
+			hdd_err("Invalid SAR Enable attr");
+			goto fail;
+		}
+	}
+	hdd_debug("attr sar sar_enable %d", sar_limit_cmd.sar_enable);
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS]) {
+		sar_limit_cmd.num_limit_rows = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS]);
+		hdd_debug("attr sar num_limit_rows %d",
+			sar_limit_cmd.num_limit_rows);
+	}
+	if (sar_limit_cmd.num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) {
+		hdd_err("SAR Spec list exceed supported size");
+		goto fail;
+	}
+	if (sar_limit_cmd.num_limit_rows == 0)
+		goto send_sar_limits;
+	sar_limit_cmd.sar_limit_row_list = qdf_mem_malloc(sizeof(
+						struct sar_limit_cmd_row) *
+						sar_limit_cmd.num_limit_rows);
+	if (!sar_limit_cmd.sar_limit_row_list) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+	if (!tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC]) {
+		hdd_err("Invalid SAR SPECs list");
+		goto fail;
+	}
+
+	nla_for_each_nested(sar_spec_list,
+			    tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC], rem) {
+		if (i == sar_limit_cmd.num_limit_rows) {
+			hdd_warn("SAR Cmd has excess SPECs in list");
+			break;
+		}
+
+		if (wlan_cfg80211_nla_parse(sar_spec,
+					    QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX,
+					    nla_data(sar_spec_list),
+					    nla_len(sar_spec_list),
+					    sar_limits_policy)) {
+			hdd_err("nla_parse failed for SAR Spec list");
+			goto fail;
+		}
+		sar_limit_cmd.sar_limit_row_list[i].validity_bitmap = 0;
+		if (sar_spec[
+			    QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT]) {
+			sar_limit_cmd.sar_limit_row_list[i].limit_value =
+				nla_get_u32(sar_spec[
+				QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT]);
+		} else if (sar_spec[
+			    QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX]) {
+			sar_limit_cmd.sar_limit_row_list[i].limit_value =
+				nla_get_u32(sar_spec[
+				QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX]);
+		} else {
+			hdd_err("SAR Spec does not have power limit or index value");
+			goto fail;
+		}
+
+		if (sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND]) {
+			if (wlan_hdd_cfg80211_sar_convert_band(nla_get_u32(
+					sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND]),
+					&sar_limit_cmd.sar_limit_row_list[i].band_id)
+					< 0) {
+				hdd_err("Invalid SAR Band attr");
+				goto fail;
+			}
+			sar_limit_cmd.sar_limit_row_list[i].validity_bitmap |=
+						WMI_SAR_BAND_ID_VALID_MASK;
+		}
+		if (sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN]) {
+			sar_limit_cmd.sar_limit_row_list[i].chain_id =
+				nla_get_u32(sar_spec[
+				QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN]);
+			sar_limit_cmd.sar_limit_row_list[i].validity_bitmap |=
+						WMI_SAR_CHAIN_ID_VALID_MASK;
+		}
+		if (sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION]) {
+			if (wlan_hdd_cfg80211_sar_convert_modulation(nla_get_u32(
+					sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION]),
+					&sar_limit_cmd.sar_limit_row_list[i].mod_id)
+					< 0) {
+				hdd_err("Invalid SAR Modulation attr");
+				goto fail;
+			}
+			sar_limit_cmd.sar_limit_row_list[i].validity_bitmap |=
+						WMI_SAR_MOD_ID_VALID_MASK;
+		}
+		hdd_debug("Spec_ID: %d, Band: %d Chain: %d Mod: %d POW_Limit: %d Validity_Bitmap: %d",
+			 i, sar_limit_cmd.sar_limit_row_list[i].band_id,
+			 sar_limit_cmd.sar_limit_row_list[i].chain_id,
+			 sar_limit_cmd.sar_limit_row_list[i].mod_id,
+			 sar_limit_cmd.sar_limit_row_list[i].limit_value,
+			 sar_limit_cmd.sar_limit_row_list[i].validity_bitmap);
+		i++;
+	}
+
+	if (i < sar_limit_cmd.num_limit_rows) {
+		hdd_warn("SAR Cmd has less SPECs in list");
+		sar_limit_cmd.num_limit_rows = i;
+	}
+
+send_sar_limits:
+	mac_handle = hdd_ctx->mac_handle;
+	if (sme_set_sar_power_limits(mac_handle, &sar_limit_cmd) ==
+							QDF_STATUS_SUCCESS)
+		ret = 0;
+fail:
+	qdf_mem_free(sar_limit_cmd.sar_limit_row_list);
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_sar_power_limits() - Set SAR power limits
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Wrapper function of __wlan_hdd_cfg80211_set_sar_power_limits()
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int wlan_hdd_cfg80211_set_sar_power_limits(struct wiphy *wiphy,
+						  struct wireless_dev *wdev,
+						  const void *data,
+						  int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_set_sar_power_limits(wiphy, wdev, data,
+					      data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static const struct
+nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
+	[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]       = {.type = NLA_BINARY,
+						 .len = QDF_MAC_ADDR_SIZE},
+};
+
+void wlan_hdd_rso_cmd_status_cb(hdd_handle_t hdd_handle,
+				struct rso_cmd_status *rso_status)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	struct hdd_adapter *adapter;
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, rso_status->vdev_id);
+	if (!adapter) {
+		hdd_err("adapter NULL");
+		return;
+	}
+
+	adapter->lfr_fw_status.is_disabled = rso_status->status;
+	complete(&adapter->lfr_fw_status.disable_lfr_event);
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_fast_roaming() - enable/disable roaming
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * This function is used to enable/disable roaming using vendor commands
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
+					    struct wireless_dev *wdev,
+					    const void *data, int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
+	uint32_t is_fast_roam_enabled;
+	int ret;
+	QDF_STATUS qdf_status;
+	unsigned long rc;
+	struct hdd_station_ctx *hdd_sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	mac_handle_t mac_handle;
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_cfg80211_nla_parse(tb,
+				      QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
+				      qca_wlan_vendor_attr);
+	if (ret) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch Enable flag */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
+		hdd_err("attr enable failed");
+		return -EINVAL;
+	}
+
+	is_fast_roam_enabled = nla_get_u32(
+				tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
+	hdd_debug("isFastRoamEnabled %d", is_fast_roam_enabled);
+
+	/* Update roaming */
+	mac_handle = hdd_ctx->mac_handle;
+	qdf_status = sme_config_fast_roaming(mac_handle, adapter->session_id,
+					     is_fast_roam_enabled);
+	if (qdf_status != QDF_STATUS_SUCCESS)
+		hdd_err("sme_config_fast_roaming failed with status=%d",
+				qdf_status);
+	ret = qdf_status_to_os_return(qdf_status);
+
+	if (eConnectionState_Associated == hdd_sta_ctx->conn_info.connState &&
+		QDF_IS_STATUS_SUCCESS(qdf_status) && !is_fast_roam_enabled) {
+
+		INIT_COMPLETION(adapter->lfr_fw_status.disable_lfr_event);
+		/*
+		 * wait only for LFR disable in fw as LFR enable
+		 * is always success
+		 */
+		rc = wait_for_completion_timeout(
+				&adapter->lfr_fw_status.disable_lfr_event,
+				msecs_to_jiffies(WAIT_TIME_RSO_CMD_STATUS));
+		if (!rc) {
+			hdd_err("Timed out waiting for RSO CMD status");
+			return -ETIMEDOUT;
+		}
+
+		if (!adapter->lfr_fw_status.is_disabled) {
+			hdd_err("Roam disable attempt in FW fails");
+			return -EBUSY;
+		}
+	}
+
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_fast_roaming() - enable/disable roaming
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Wrapper function of __wlan_hdd_cfg80211_set_fast_roaming()
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
+					  struct wireless_dev *wdev,
+					  const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_fast_roaming(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/*
+ * define short names for the global vendor params
+ * used by wlan_hdd_cfg80211_setarp_stats_cmd()
+ */
+#define STATS_SET_INVALID \
+	QCA_ATTR_NUD_STATS_SET_INVALID
+#define STATS_SET_START \
+	QCA_ATTR_NUD_STATS_SET_START
+#define STATS_GW_IPV4 \
+	QCA_ATTR_NUD_STATS_GW_IPV4
+#define STATS_SET_DATA_PKT_INFO \
+		QCA_ATTR_NUD_STATS_SET_DATA_PKT_INFO
+#define STATS_SET_MAX \
+	QCA_ATTR_NUD_STATS_SET_MAX
+
+const struct nla_policy
+qca_wlan_vendor_set_nud_stats[STATS_SET_MAX + 1] = {
+	[STATS_SET_START] = {.type = NLA_FLAG },
+	[STATS_GW_IPV4] = {.type = NLA_U32 },
+	[STATS_SET_DATA_PKT_INFO] = {.type = NLA_U32 },
+};
+
+/* define short names for the global vendor params */
+#define CONNECTIVITY_STATS_SET_INVALID \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_SET_INVALID
+#define STATS_PKT_INFO_TYPE \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_STATS_PKT_INFO_TYPE
+#define STATS_DNS_DOMAIN_NAME \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_DNS_DOMAIN_NAME
+#define STATS_SRC_PORT \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_SRC_PORT
+#define STATS_DEST_PORT \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_DEST_PORT
+#define STATS_DEST_IPV4 \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_DEST_IPV4
+#define STATS_DEST_IPV6 \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_DEST_IPV6
+#define CONNECTIVITY_STATS_SET_MAX \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_SET_MAX
+
+const struct nla_policy
+qca_wlan_vendor_set_connectivity_check_stats[CONNECTIVITY_STATS_SET_MAX + 1] = {
+	[STATS_PKT_INFO_TYPE] = {.type = NLA_U32 },
+	[STATS_DNS_DOMAIN_NAME] = {.type = NLA_BINARY,
+					.len = DNS_DOMAIN_NAME_MAX_LEN },
+	[STATS_SRC_PORT] = {.type = NLA_U32 },
+	[STATS_DEST_PORT] = {.type = NLA_U32 },
+	[STATS_DEST_IPV4] = {.type = NLA_U32 },
+	[STATS_DEST_IPV6] = {.type = NLA_BINARY,
+					.len = ICMPv6_ADDR_LEN },
+};
+
+/**
+ * hdd_dns_unmake_name_query() - Convert an uncompressed DNS name to a
+ *			     NUL-terminated string
+ * @name: DNS name
+ *
+ * Return: Produce a printable version of a DNS name.
+ */
+static inline uint8_t *hdd_dns_unmake_name_query(uint8_t *name)
+{
+	uint8_t *p;
+	unsigned int len;
+
+	p = name;
+	while ((len = *p)) {
+		*(p++) = '.';
+		p += len;
+	}
+
+	return name + 1;
+}
+
+/**
+ * hdd_dns_make_name_query() - Convert a standard NUL-terminated string
+ *				to DNS name
+ * @string: Name as a NUL-terminated string
+ * @buf: Buffer in which to place DNS name
+ *
+ * DNS names consist of "<length>element" pairs.
+ *
+ * Return: Byte following constructed DNS name
+ */
+static uint8_t *hdd_dns_make_name_query(const uint8_t *string, uint8_t *buf)
+{
+	uint8_t *length_byte = buf++;
+	uint8_t c;
+
+	while ((c = *(string++))) {
+		if (c == '.') {
+			*length_byte = buf - length_byte - 1;
+			length_byte = buf;
+		}
+		*(buf++) = c;
+	}
+	*length_byte = buf - length_byte - 1;
+	*(buf++) = '\0';
+	return buf;
+}
+
+/**
+ * hdd_set_clear_connectivity_check_stats_info() - set/clear stats info
+ * @adapter: Pointer to hdd adapter
+ * @arp_stats_params: arp stats structure to be sent to FW
+ * @tb: nl attribute
+ * @is_set_stats: set/clear stats
+ *
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int hdd_set_clear_connectivity_check_stats_info(
+		struct hdd_adapter *adapter,
+		struct set_arp_stats_params *arp_stats_params,
+		struct nlattr **tb, bool is_set_stats)
+{
+	struct nlattr *tb2[CONNECTIVITY_STATS_SET_MAX + 1];
+	struct nlattr *curr_attr = NULL;
+	int err = 0;
+	uint32_t pkt_bitmap;
+	int rem;
+
+	/* Set NUD command for start tracking is received. */
+	nla_for_each_nested(curr_attr,
+			    tb[STATS_SET_DATA_PKT_INFO],
+			    rem) {
+
+		if (wlan_cfg80211_nla_parse(tb2,
+				CONNECTIVITY_STATS_SET_MAX,
+				nla_data(curr_attr), nla_len(curr_attr),
+				qca_wlan_vendor_set_connectivity_check_stats)) {
+			hdd_err("nla_parse failed");
+			err = -EINVAL;
+			goto end;
+		}
+
+		if (tb2[STATS_PKT_INFO_TYPE]) {
+			pkt_bitmap = nla_get_u32(tb2[STATS_PKT_INFO_TYPE]);
+			if (!pkt_bitmap) {
+				hdd_err("pkt tracking bitmap is empty");
+				err = -EINVAL;
+				goto end;
+			}
+
+			if (is_set_stats) {
+				arp_stats_params->pkt_type_bitmap = pkt_bitmap;
+				arp_stats_params->flag = true;
+				adapter->pkt_type_bitmap |=
+					arp_stats_params->pkt_type_bitmap;
+
+				if (pkt_bitmap & CONNECTIVITY_CHECK_SET_ARP) {
+					if (!tb[STATS_GW_IPV4]) {
+						hdd_err("GW ipv4 address is not present");
+						err = -EINVAL;
+						goto end;
+					}
+					arp_stats_params->ip_addr =
+						nla_get_u32(tb[STATS_GW_IPV4]);
+					arp_stats_params->pkt_type =
+						WLAN_NUD_STATS_ARP_PKT_TYPE;
+					adapter->track_arp_ip =
+						arp_stats_params->ip_addr;
+				}
+
+				if (pkt_bitmap & CONNECTIVITY_CHECK_SET_DNS) {
+					uint8_t *domain_name;
+
+					if (!tb2[STATS_DNS_DOMAIN_NAME]) {
+						hdd_err("DNS domain id is not present");
+						err = -EINVAL;
+						goto end;
+					}
+					domain_name = nla_data(
+						tb2[STATS_DNS_DOMAIN_NAME]);
+					adapter->track_dns_domain_len =
+						nla_len(tb2[
+							STATS_DNS_DOMAIN_NAME]);
+					hdd_dns_make_name_query(domain_name,
+							adapter->dns_payload);
+					/* DNStracking isn't supported in FW. */
+					arp_stats_params->pkt_type_bitmap &=
+						~CONNECTIVITY_CHECK_SET_DNS;
+				}
+
+				if (pkt_bitmap &
+				    CONNECTIVITY_CHECK_SET_TCP_HANDSHAKE) {
+					if (!tb2[STATS_SRC_PORT] ||
+					    !tb2[STATS_DEST_PORT]) {
+						hdd_err("Source/Dest port is not present");
+						err = -EINVAL;
+						goto end;
+					}
+					arp_stats_params->tcp_src_port =
+						nla_get_u32(
+							tb2[STATS_SRC_PORT]);
+					arp_stats_params->tcp_dst_port =
+						nla_get_u32(
+							tb2[STATS_DEST_PORT]);
+					adapter->track_src_port =
+						arp_stats_params->tcp_src_port;
+					adapter->track_dest_port =
+						arp_stats_params->tcp_dst_port;
+				}
+
+				if (pkt_bitmap &
+				    CONNECTIVITY_CHECK_SET_ICMPV4) {
+					if (!tb2[STATS_DEST_IPV4]) {
+						hdd_err("destination ipv4 address to track ping packets is not present");
+						err = -EINVAL;
+						goto end;
+					}
+					arp_stats_params->icmp_ipv4 =
+						nla_get_u32(
+							tb2[STATS_DEST_IPV4]);
+					adapter->track_dest_ipv4 =
+						arp_stats_params->icmp_ipv4;
+				}
+			} else {
+				/* clear stats command received */
+				arp_stats_params->pkt_type_bitmap = pkt_bitmap;
+				arp_stats_params->flag = false;
+				adapter->pkt_type_bitmap &=
+					(~arp_stats_params->pkt_type_bitmap);
+
+				if (pkt_bitmap & CONNECTIVITY_CHECK_SET_ARP) {
+					arp_stats_params->pkt_type =
+						WLAN_NUD_STATS_ARP_PKT_TYPE;
+					qdf_mem_zero(&adapter->hdd_stats.
+								hdd_arp_stats,
+						     sizeof(adapter->hdd_stats.
+								hdd_arp_stats));
+					adapter->track_arp_ip = 0;
+				}
+
+				if (pkt_bitmap & CONNECTIVITY_CHECK_SET_DNS) {
+					/* DNStracking isn't supported in FW. */
+					arp_stats_params->pkt_type_bitmap &=
+						~CONNECTIVITY_CHECK_SET_DNS;
+					qdf_mem_zero(&adapter->hdd_stats.
+								hdd_dns_stats,
+						     sizeof(adapter->hdd_stats.
+								hdd_dns_stats));
+					qdf_mem_zero(adapter->dns_payload,
+						adapter->track_dns_domain_len);
+					adapter->track_dns_domain_len = 0;
+				}
+
+				if (pkt_bitmap &
+				    CONNECTIVITY_CHECK_SET_TCP_HANDSHAKE) {
+					qdf_mem_zero(&adapter->hdd_stats.
+								hdd_tcp_stats,
+						     sizeof(adapter->hdd_stats.
+								hdd_tcp_stats));
+					adapter->track_src_port = 0;
+					adapter->track_dest_port = 0;
+				}
+
+				if (pkt_bitmap &
+				    CONNECTIVITY_CHECK_SET_ICMPV4) {
+					qdf_mem_zero(&adapter->hdd_stats.
+							hdd_icmpv4_stats,
+						     sizeof(adapter->hdd_stats.
+							hdd_icmpv4_stats));
+					adapter->track_dest_ipv4 = 0;
+				}
+			}
+		} else {
+			hdd_err("stats list empty");
+			err = -EINVAL;
+			goto end;
+		}
+	}
+
+end:
+	return err;
+}
+
+void hdd_update_cca_info_cb(hdd_handle_t hdd_handle, uint32_t congestion,
+			    uint32_t vdev_id)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	int status;
+	struct hdd_adapter *adapter = NULL;
+	struct hdd_station_ctx *hdd_sta_ctx;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status != 0)
+		return;
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (adapter == NULL) {
+		hdd_err("vdev_id %d does not exist with host", vdev_id);
+		return;
+	}
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	hdd_sta_ctx->conn_info.cca = congestion;
+	hdd_info("congestion:%d", congestion);
+}
+
+static const struct nla_policy qca_wlan_vendor_set_trace_level_policy[
+		QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM] = {.type = NLA_NESTED },
+	[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MODULE_ID] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_TRACE_MASK] = {.type = NLA_U32 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_set_trace_level() - Set the trace level
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_set_trace_level(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb1[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX + 1];
+	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX + 1];
+	struct nlattr *apth;
+	int rem;
+	int ret = 1;
+	int print_idx = -1;
+	int module_id = -1;
+	int bit_mask = -1;
+	int status;
+
+	hdd_enter();
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return -EINVAL;
+
+	print_idx = qdf_get_pidx();
+	if (print_idx < 0 || print_idx >= MAX_PRINT_CONFIG_SUPPORTED) {
+		hdd_err("Invalid print controle object index");
+		return -EINVAL;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb1,
+				    QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX,
+				    data, data_len,
+				    qca_wlan_vendor_set_trace_level_policy)) {
+		hdd_err("Invalid attr");
+		return -EINVAL;
+	}
+
+	if (!tb1[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM]) {
+		hdd_err("attr trace level param failed");
+		return -EINVAL;
+	}
+
+	nla_for_each_nested(apth,
+			tb1[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM], rem) {
+		if (wlan_cfg80211_nla_parse(tb2,
+				       QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX,
+				       nla_data(apth), nla_len(apth), NULL)) {
+			hdd_err("Invalid attr");
+			return -EINVAL;
+		}
+
+		if (!tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MODULE_ID]) {
+			hdd_err("attr Module ID failed");
+			return -EINVAL;
+		}
+		module_id = nla_get_u32
+			(tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MODULE_ID]);
+
+		if (!tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_TRACE_MASK]) {
+			hdd_err("attr Verbose mask failed");
+			return -EINVAL;
+		}
+		bit_mask = nla_get_u32
+		      (tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_TRACE_MASK]);
+
+		status = hdd_qdf_trace_enable(module_id, bit_mask);
+
+		if (status != 0)
+			hdd_err("can not set verbose mask %d for the category %d",
+				bit_mask, module_id);
+	}
+
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_trace_level() - Set the trace level
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Wrapper function of __wlan_hdd_cfg80211_set_trace_level()
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+
+static int wlan_hdd_cfg80211_set_trace_level(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_trace_level(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to apfind configuration data.
+ * @data_len: the length in byte of apfind data.
+ *
+ * This is called when wlan driver needs to send arp stats to
+ * firmware.
+ *
+ * Return: An error code or 0 on success.
+ */
+static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data, int data_len)
+{
+	struct nlattr *tb[STATS_SET_MAX + 1];
+	struct net_device   *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct set_arp_stats_params arp_stats_params = {0};
+	int err = 0;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	err = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != err)
+		return err;
+
+	err = wlan_cfg80211_nla_parse(tb, STATS_SET_MAX, data, data_len,
+				      qca_wlan_vendor_set_nud_stats);
+	if (err) {
+		hdd_err("STATS_SET_START ATTR");
+		return err;
+	}
+
+	if (adapter->session_id == HDD_SESSION_ID_INVALID) {
+		hdd_err("Invalid session id");
+		return -EINVAL;
+	}
+
+	if (adapter->device_mode != QDF_STA_MODE) {
+		hdd_err("STATS supported in only STA mode!");
+		return -EINVAL;
+	}
+
+	if (tb[STATS_SET_START]) {
+		/* tracking is enabled for stats other than arp. */
+		if (tb[STATS_SET_DATA_PKT_INFO]) {
+			err = hdd_set_clear_connectivity_check_stats_info(
+						adapter,
+						&arp_stats_params, tb, true);
+			if (err)
+				return -EINVAL;
+
+			/*
+			 * if only tracking dns, then don't send
+			 * wmi command to FW.
+			 */
+			if (!arp_stats_params.pkt_type_bitmap)
+				return err;
+		} else {
+			if (!tb[STATS_GW_IPV4]) {
+				hdd_err("STATS_SET_START CMD");
+				return -EINVAL;
+			}
+
+			arp_stats_params.pkt_type_bitmap =
+						CONNECTIVITY_CHECK_SET_ARP;
+			adapter->pkt_type_bitmap |=
+					arp_stats_params.pkt_type_bitmap;
+			arp_stats_params.flag = true;
+			arp_stats_params.ip_addr =
+					nla_get_u32(tb[STATS_GW_IPV4]);
+			adapter->track_arp_ip = arp_stats_params.ip_addr;
+			arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
+		}
+	} else {
+		/* clear stats command received. */
+		if (tb[STATS_SET_DATA_PKT_INFO]) {
+			err = hdd_set_clear_connectivity_check_stats_info(
+						adapter,
+						&arp_stats_params, tb, false);
+			if (err)
+				return -EINVAL;
+
+			/*
+			 * if only tracking dns, then don't send
+			 * wmi command to FW.
+			 */
+			if (!arp_stats_params.pkt_type_bitmap)
+				return err;
+		} else {
+			arp_stats_params.pkt_type_bitmap =
+						CONNECTIVITY_CHECK_SET_ARP;
+			adapter->pkt_type_bitmap &=
+					(~arp_stats_params.pkt_type_bitmap);
+			arp_stats_params.flag = false;
+			qdf_mem_zero(&adapter->hdd_stats.hdd_arp_stats,
+				     sizeof(adapter->hdd_stats.hdd_arp_stats));
+			arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
+		}
+	}
+
+	hdd_debug("STATS_SET_START Received flag %d!", arp_stats_params.flag);
+
+	arp_stats_params.vdev_id = adapter->session_id;
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (QDF_STATUS_SUCCESS !=
+	    sme_set_nud_debug_stats(mac_handle, &arp_stats_params)) {
+		hdd_err("STATS_SET_START CMD Failed!");
+		return -EINVAL;
+	}
+
+	hdd_exit();
+
+	return err;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to apfind configuration data.
+ * @data_len: the length in byte of apfind data.
+ *
+ * This is called when wlan driver needs to send arp stats to
+ * firmware.
+ *
+ * Return: An error code or 0 on success.
+ */
+static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#undef STATS_SET_INVALID
+#undef STATS_SET_START
+#undef STATS_GW_IPV4
+#undef STATS_SET_MAX
+
+/*
+ * define short names for the global vendor params
+ * used by wlan_hdd_cfg80211_setarp_stats_cmd()
+ */
+#define STATS_GET_INVALID \
+	QCA_ATTR_NUD_STATS_SET_INVALID
+#define COUNT_FROM_NETDEV \
+	QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
+#define COUNT_TO_LOWER_MAC \
+	QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
+#define RX_COUNT_BY_LOWER_MAC \
+	QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
+#define COUNT_TX_SUCCESS \
+	QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
+#define RSP_RX_COUNT_BY_LOWER_MAC \
+	QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
+#define RSP_RX_COUNT_BY_UPPER_MAC \
+	QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
+#define RSP_COUNT_TO_NETDEV \
+	QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
+#define RSP_COUNT_OUT_OF_ORDER_DROP \
+	QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
+#define AP_LINK_ACTIVE \
+	QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
+#define AP_LINK_DAD \
+	QCA_ATTR_NUD_STATS_IS_DAD
+#define DATA_PKT_STATS \
+	QCA_ATTR_NUD_STATS_DATA_PKT_STATS
+#define STATS_GET_MAX \
+	QCA_ATTR_NUD_STATS_GET_MAX
+
+#define CHECK_STATS_INVALID \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_INVALID
+#define CHECK_STATS_PKT_TYPE \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_TYPE
+#define CHECK_STATS_PKT_DNS_DOMAIN_NAME \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_DNS_DOMAIN_NAME
+#define CHECK_STATS_PKT_SRC_PORT \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_SRC_PORT
+#define CHECK_STATS_PKT_DEST_PORT \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_DEST_PORT
+#define CHECK_STATS_PKT_DEST_IPV4 \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_DEST_IPV4
+#define CHECK_STATS_PKT_DEST_IPV6 \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_DEST_IPV6
+#define CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV
+#define CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC
+#define CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC
+#define CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS
+#define CHECK_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC
+#define CHECK_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC
+#define CHECK_STATS_PKT_RSP_COUNT_TO_NETDEV \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_RSP_COUNT_TO_NETDEV
+#define CHECK_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP \
+	QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP
+#define CHECK_DATA_STATS_MAX \
+	QCA_ATTR_CONNECTIVITY_CHECK_DATA_STATS_MAX
+
+
+const struct nla_policy
+qca_wlan_vendor_get_nud_stats[STATS_GET_MAX + 1] = {
+	[COUNT_FROM_NETDEV] = {.type = NLA_U16 },
+	[COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
+	[RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
+	[COUNT_TX_SUCCESS] = {.type = NLA_U16 },
+	[RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
+	[RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
+	[RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
+	[RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
+	[AP_LINK_ACTIVE] = {.type = NLA_FLAG },
+	[AP_LINK_DAD] = {.type = NLA_FLAG },
+	[DATA_PKT_STATS] = {.type = NLA_U16 },
+};
+
+/**
+ * hdd_populate_dns_stats_info() - send dns stats info to network stack
+ * @adapter: pointer to adapter context
+ * @skb: pointer to skb
+ *
+ *
+ * Return: An error code or 0 on success.
+ */
+static int hdd_populate_dns_stats_info(struct hdd_adapter *adapter,
+				       struct sk_buff *skb)
+{
+	uint8_t *dns_query;
+
+	dns_query = qdf_mem_malloc(adapter->track_dns_domain_len + 1);
+	if (!dns_query)
+		return -EINVAL;
+
+	qdf_mem_copy(dns_query, adapter->dns_payload,
+		     adapter->track_dns_domain_len);
+
+	if (nla_put_u16(skb, CHECK_STATS_PKT_TYPE,
+		CONNECTIVITY_CHECK_SET_DNS) ||
+	    nla_put(skb, CHECK_STATS_PKT_DNS_DOMAIN_NAME,
+		adapter->track_dns_domain_len,
+		hdd_dns_unmake_name_query(dns_query)) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV,
+		adapter->hdd_stats.hdd_dns_stats.tx_dns_req_count) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC,
+		adapter->hdd_stats.hdd_dns_stats.tx_host_fw_sent) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC,
+		adapter->hdd_stats.hdd_dns_stats.tx_host_fw_sent) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS,
+		adapter->hdd_stats.hdd_dns_stats.tx_ack_cnt) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC,
+		adapter->hdd_stats.hdd_dns_stats.rx_dns_rsp_count) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_RSP_COUNT_TO_NETDEV,
+		adapter->hdd_stats.hdd_dns_stats.rx_delivered) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP,
+		adapter->hdd_stats.hdd_dns_stats.rx_host_drop)) {
+		hdd_err("nla put fail");
+		qdf_mem_free(dns_query);
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+	qdf_mem_free(dns_query);
+	return 0;
+}
+
+/**
+ * hdd_populate_tcp_stats_info() - send tcp stats info to network stack
+ * @adapter: pointer to adapter context
+ * @skb: pointer to skb
+ * @pkt_type: tcp pkt type
+ *
+ * Return: An error code or 0 on success.
+ */
+static int hdd_populate_tcp_stats_info(struct hdd_adapter *adapter,
+				       struct sk_buff *skb,
+				       uint8_t pkt_type)
+{
+	switch (pkt_type) {
+	case CONNECTIVITY_CHECK_SET_TCP_SYN:
+		/* Fill info for tcp syn packets (tx packet) */
+		if (nla_put_u16(skb, CHECK_STATS_PKT_TYPE,
+			CONNECTIVITY_CHECK_SET_TCP_SYN) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_SRC_PORT,
+			adapter->track_src_port) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_DEST_PORT,
+			adapter->track_dest_port) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV,
+			adapter->hdd_stats.hdd_tcp_stats.tx_tcp_syn_count) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC,
+			adapter->hdd_stats.hdd_tcp_stats.
+						tx_tcp_syn_host_fw_sent) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC,
+			adapter->hdd_stats.hdd_tcp_stats.
+						tx_tcp_syn_host_fw_sent) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS,
+			adapter->hdd_stats.hdd_tcp_stats.tx_tcp_syn_ack_cnt)) {
+			hdd_err("nla put fail");
+			kfree_skb(skb);
+			return -EINVAL;
+		}
+		break;
+	case CONNECTIVITY_CHECK_SET_TCP_SYN_ACK:
+		/* Fill info for tcp syn-ack packets (rx packet) */
+		if (nla_put_u16(skb, CHECK_STATS_PKT_TYPE,
+			CONNECTIVITY_CHECK_SET_TCP_SYN_ACK) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_SRC_PORT,
+			adapter->track_src_port) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_DEST_PORT,
+			adapter->track_dest_port) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC,
+			adapter->hdd_stats.hdd_tcp_stats.rx_fw_cnt) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC,
+			adapter->hdd_stats.hdd_tcp_stats.
+							rx_tcp_syn_ack_count) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_RSP_COUNT_TO_NETDEV,
+			adapter->hdd_stats.hdd_tcp_stats.rx_delivered) ||
+		    nla_put_u16(skb,
+			CHECK_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP,
+			adapter->hdd_stats.hdd_tcp_stats.rx_host_drop)) {
+			hdd_err("nla put fail");
+			kfree_skb(skb);
+			return -EINVAL;
+		}
+		break;
+	case CONNECTIVITY_CHECK_SET_TCP_ACK:
+		/* Fill info for tcp ack packets (tx packet) */
+		if (nla_put_u16(skb, CHECK_STATS_PKT_TYPE,
+			CONNECTIVITY_CHECK_SET_TCP_ACK) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_SRC_PORT,
+			adapter->track_src_port) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_DEST_PORT,
+			adapter->track_dest_port) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV,
+			adapter->hdd_stats.hdd_tcp_stats.tx_tcp_ack_count) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC,
+			adapter->hdd_stats.hdd_tcp_stats.
+						tx_tcp_ack_host_fw_sent) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC,
+			adapter->hdd_stats.hdd_tcp_stats.
+						tx_tcp_ack_host_fw_sent) ||
+		    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS,
+			adapter->hdd_stats.hdd_tcp_stats.tx_tcp_ack_ack_cnt)) {
+			hdd_err("nla put fail");
+			kfree_skb(skb);
+			return -EINVAL;
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+/**
+ * hdd_populate_icmpv4_stats_info() - send icmpv4 stats info to network stack
+ * @adapter: pointer to adapter context
+ * @skb: pointer to skb
+ *
+ *
+ * Return: An error code or 0 on success.
+ */
+static int hdd_populate_icmpv4_stats_info(struct hdd_adapter *adapter,
+					  struct sk_buff *skb)
+{
+	if (nla_put_u16(skb, CHECK_STATS_PKT_TYPE,
+		CONNECTIVITY_CHECK_SET_ICMPV4) ||
+	    nla_put_u32(skb, CHECK_STATS_PKT_DEST_IPV4,
+		adapter->track_dest_ipv4) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV,
+		adapter->hdd_stats.hdd_icmpv4_stats.tx_icmpv4_req_count) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC,
+		adapter->hdd_stats.hdd_icmpv4_stats.tx_host_fw_sent) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC,
+		adapter->hdd_stats.hdd_icmpv4_stats.tx_host_fw_sent) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS,
+		adapter->hdd_stats.hdd_icmpv4_stats.tx_ack_cnt) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC,
+		adapter->hdd_stats.hdd_icmpv4_stats.rx_fw_cnt) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC,
+		adapter->hdd_stats.hdd_icmpv4_stats.rx_icmpv4_rsp_count) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_RSP_COUNT_TO_NETDEV,
+		adapter->hdd_stats.hdd_icmpv4_stats.rx_delivered) ||
+	    nla_put_u16(skb, CHECK_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP,
+		adapter->hdd_stats.hdd_icmpv4_stats.rx_host_drop)) {
+		hdd_err("nla put fail");
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * hdd_populate_connectivity_check_stats_info() - send connectivity stats info
+ *						  to network stack
+ * @adapter: pointer to adapter context
+ * @skb: pointer to skb
+ *
+ *
+ * Return: An error code or 0 on success.
+ */
+
+static int hdd_populate_connectivity_check_stats_info(
+	struct hdd_adapter *adapter, struct sk_buff *skb)
+{
+	struct nlattr *connect_stats, *connect_info;
+	uint32_t count = 0;
+
+	connect_stats = nla_nest_start(skb, DATA_PKT_STATS);
+	if (connect_stats == NULL) {
+		hdd_err("nla_nest_start failed");
+		return -EINVAL;
+	}
+
+	if (adapter->pkt_type_bitmap & CONNECTIVITY_CHECK_SET_DNS) {
+		connect_info = nla_nest_start(skb, count);
+		if (connect_info == NULL) {
+			hdd_err("nla_nest_start failed count %u", count);
+			return -EINVAL;
+		}
+
+		if (hdd_populate_dns_stats_info(adapter, skb))
+			goto put_attr_fail;
+		nla_nest_end(skb, connect_info);
+		count++;
+	}
+
+	if (adapter->pkt_type_bitmap & CONNECTIVITY_CHECK_SET_TCP_HANDSHAKE) {
+		connect_info = nla_nest_start(skb, count);
+		if (connect_info == NULL) {
+			hdd_err("nla_nest_start failed count %u", count);
+			return -EINVAL;
+		}
+		if (hdd_populate_tcp_stats_info(adapter, skb,
+					CONNECTIVITY_CHECK_SET_TCP_SYN))
+			goto put_attr_fail;
+		nla_nest_end(skb, connect_info);
+		count++;
+
+		connect_info = nla_nest_start(skb, count);
+		if (connect_info == NULL) {
+			hdd_err("nla_nest_start failed count %u", count);
+			return -EINVAL;
+		}
+		if (hdd_populate_tcp_stats_info(adapter, skb,
+					CONNECTIVITY_CHECK_SET_TCP_SYN_ACK))
+			goto put_attr_fail;
+		nla_nest_end(skb, connect_info);
+		count++;
+
+		connect_info = nla_nest_start(skb, count);
+		if (connect_info == NULL) {
+			hdd_err("nla_nest_start failed count %u", count);
+			return -EINVAL;
+		}
+		if (hdd_populate_tcp_stats_info(adapter, skb,
+					CONNECTIVITY_CHECK_SET_TCP_ACK))
+			goto put_attr_fail;
+		nla_nest_end(skb, connect_info);
+		count++;
+	}
+
+	if (adapter->pkt_type_bitmap & CONNECTIVITY_CHECK_SET_ICMPV4) {
+		connect_info = nla_nest_start(skb, count);
+		if (connect_info == NULL) {
+			hdd_err("nla_nest_start failed count %u", count);
+			return -EINVAL;
+		}
+
+		if (hdd_populate_icmpv4_stats_info(adapter, skb))
+			goto put_attr_fail;
+		nla_nest_end(skb, connect_info);
+		count++;
+	}
+
+	nla_nest_end(skb, connect_stats);
+	return 0;
+
+put_attr_fail:
+	hdd_err("QCA_WLAN_VENDOR_ATTR put fail. count %u", count);
+	return -EINVAL;
+}
+
+
+/**
+ * __wlan_hdd_cfg80211_get_nud_stats() - get arp stats command to firmware
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to apfind configuration data.
+ * @data_len: the length in byte of apfind data.
+ *
+ * This is called when wlan driver needs to get arp stats to
+ * firmware.
+ *
+ * Return: An error code or 0 on success.
+ */
+static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data, int data_len)
+{
+	int err = 0;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct get_arp_stats_params arp_stats_params;
+	mac_handle_t mac_handle;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	uint32_t pkt_type_bitmap;
+	struct sk_buff *skb;
+	struct osif_request *request = NULL;
+	static const struct osif_request_params params = {
+		.priv_size = 0,
+		.timeout_ms = WLAN_WAIT_TIME_NUD_STATS,
+	};
+	void *cookie = NULL;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	err = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != err)
+		return err;
+
+	err = hdd_validate_adapter(adapter);
+	if (err)
+		return err;
+
+	if (adapter->device_mode != QDF_STA_MODE) {
+		hdd_err("STATS supported in only STA mode!");
+		return -EINVAL;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+
+	cookie = osif_request_cookie(request);
+
+	arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
+	arp_stats_params.vdev_id = adapter->session_id;
+
+	pkt_type_bitmap = adapter->pkt_type_bitmap;
+
+	/* send NUD failure event only when ARP tracking is enabled. */
+	if (cdp_cfg_get(soc, cfg_dp_enable_data_stall) &&
+	    (pkt_type_bitmap & CONNECTIVITY_CHECK_SET_ARP))
+		cdp_post_data_stall_event(soc,
+				      DATA_STALL_LOG_INDICATOR_FRAMEWORK,
+				      DATA_STALL_LOG_NUD_FAILURE,
+				      0xFF, 0XFF,
+				      DATA_STALL_LOG_RECOVERY_TRIGGER_PDR);
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (sme_set_nud_debug_stats_cb(mac_handle, hdd_get_nud_stats_cb,
+				       cookie) != QDF_STATUS_SUCCESS) {
+		hdd_err("Setting NUD debug stats callback failure");
+		err = -EINVAL;
+		goto exit;
+	}
+
+	if (QDF_STATUS_SUCCESS !=
+	    sme_get_nud_debug_stats(mac_handle, &arp_stats_params)) {
+		hdd_err("STATS_SET_START CMD Failed!");
+		err = -EINVAL;
+		goto exit;
+	}
+
+	err = osif_request_wait_for_response(request);
+	if (err) {
+		hdd_err("SME timedout while retrieving NUD stats");
+		err = -ETIMEDOUT;
+		goto exit;
+	}
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
+						  WLAN_NUD_STATS_LEN);
+	if (!skb) {
+		hdd_err("%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
+			__func__);
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	if (nla_put_u16(skb, COUNT_FROM_NETDEV,
+			adapter->hdd_stats.hdd_arp_stats.tx_arp_req_count) ||
+	    nla_put_u16(skb, COUNT_TO_LOWER_MAC,
+			adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent) ||
+	    nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
+			adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent) ||
+	    nla_put_u16(skb, COUNT_TX_SUCCESS,
+			adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt) ||
+	    nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
+			adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt) ||
+	    nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
+			adapter->hdd_stats.hdd_arp_stats.rx_arp_rsp_count) ||
+	    nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
+			adapter->hdd_stats.hdd_arp_stats.rx_delivered) ||
+	    nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
+			adapter->hdd_stats.hdd_arp_stats.
+			rx_host_drop_reorder)) {
+		hdd_err("nla put fail");
+		kfree_skb(skb);
+		err = -EINVAL;
+		goto exit;
+	}
+	if (adapter->con_status)
+		nla_put_flag(skb, AP_LINK_ACTIVE);
+	if (adapter->dad)
+		nla_put_flag(skb, AP_LINK_DAD);
+
+	/* ARP tracking is done above. */
+	pkt_type_bitmap &= ~CONNECTIVITY_CHECK_SET_ARP;
+
+	if (pkt_type_bitmap) {
+		if (hdd_populate_connectivity_check_stats_info(adapter, skb)) {
+			err = -EINVAL;
+			goto exit;
+		}
+	}
+
+	cfg80211_vendor_cmd_reply(skb);
+exit:
+	osif_request_put(request);
+	return err;
+}
+
+/**
+ * wlan_hdd_cfg80211_get_nud_stats() - get arp stats command to firmware
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to apfind configuration data.
+ * @data_len: the length in byte of apfind data.
+ *
+ * This is called when wlan driver needs to get arp stats to
+ * firmware.
+ *
+ * Return: An error code or 0 on success.
+ */
+static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#undef QCA_ATTR_NUD_STATS_SET_INVALID
+#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
+#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
+#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
+#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
+#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
+#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
+#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
+#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
+#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
+#undef QCA_ATTR_NUD_STATS_GET_MAX
+
+void hdd_bt_activity_cb(hdd_handle_t hdd_handle, uint32_t bt_activity)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	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;
+
+	ucfg_scan_set_bt_activity(hdd_ctx->psoc, hdd_ctx->bt_a2dp_active);
+	hdd_debug("a2dp_active: %d vo_active: %d", hdd_ctx->bt_a2dp_active,
+		 hdd_ctx->bt_vo_active);
+}
+
+struct chain_rssi_priv {
+	struct chain_rssi_result chain_rssi;
+};
+
+/**
+ * hdd_get_chain_rssi_cb() - Callback function to get chain rssi
+ * @context: opaque context originally passed to SME. HDD always passes
+ * a cookie for the request context
+ * @data: struct for get chain rssi
+ *
+ * This function receives the response/data from the lower layer and
+ * checks to see if the thread is still waiting then post the results to
+ * upper layer, if the request has timed out then ignore.
+ *
+ * Return: None
+ */
+static void hdd_get_chain_rssi_cb(void *context,
+				  struct chain_rssi_result *data)
+{
+	struct osif_request *request;
+	struct chain_rssi_priv *priv;
+
+	hdd_enter();
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+	priv->chain_rssi = *data;
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+/**
+ * hdd_post_get_chain_rssi_rsp - send rsp to user space
+ * @hdd_ctx: pointer to hdd context
+ * @result: chain rssi result
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int hdd_post_get_chain_rssi_rsp(struct hdd_context *hdd_ctx,
+				       struct chain_rssi_result *result)
+{
+	struct sk_buff *skb;
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
+		(sizeof(result->chain_rssi) + NLA_HDRLEN) +
+		(sizeof(result->ant_id) + NLA_HDRLEN) +
+		NLMSG_HDRLEN);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return -ENOMEM;
+	}
+
+	if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_CHAIN_RSSI,
+			sizeof(result->chain_rssi),
+			result->chain_rssi)) {
+		hdd_err("put fail");
+		goto nla_put_failure;
+	}
+
+	if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ANTENNA_INFO,
+			sizeof(result->ant_id),
+			result->ant_id)) {
+		hdd_err("put fail");
+		goto nla_put_failure;
+	}
+
+	cfg80211_vendor_cmd_reply(skb);
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EINVAL;
+}
+
+/**
+ * __wlan_hdd_cfg80211_get_chain_rssi() - get chain rssi
+ * @wiphy: wiphy pointer
+ * @wdev: pointer to struct wireless_dev
+ * @data: pointer to incoming NL vendor data
+ * @data_len: length of @data
+ *
+ * Return: 0 on success; error number otherwise.
+ */
+static int __wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      const void *data,
+					      int data_len)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	mac_handle_t mac_handle;
+	struct get_chain_rssi_req_params req_msg;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
+	QDF_STATUS status;
+	int retval;
+	void *cookie;
+	struct osif_request *request;
+	struct chain_rssi_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
+
+	hdd_enter();
+
+	retval = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != retval)
+		return retval;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
+				    data, data_len, NULL)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
+		hdd_err("attr mac addr failed");
+		return -EINVAL;
+	}
+	if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) !=
+		QDF_MAC_ADDR_SIZE) {
+		hdd_err("incorrect mac size");
+		return -EINVAL;
+	}
+	memcpy(&req_msg.peer_macaddr,
+		nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
+		QDF_MAC_ADDR_SIZE);
+	req_msg.session_id = adapter->session_id;
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_get_chain_rssi(mac_handle,
+				    &req_msg,
+				    hdd_get_chain_rssi_cb,
+				    cookie);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Unable to get chain rssi");
+		retval = qdf_status_to_os_return(status);
+	} else {
+		retval = osif_request_wait_for_response(request);
+		if (retval) {
+			hdd_err("Target response timed out");
+		} else {
+			priv = osif_request_priv(request);
+			retval = hdd_post_get_chain_rssi_rsp(hdd_ctx,
+					&priv->chain_rssi);
+			if (retval)
+				hdd_err("Failed to post chain rssi");
+		}
+	}
+	osif_request_put(request);
+
+	hdd_exit();
+	return retval;
+}
+
+/**
+ * wlan_hdd_cfg80211_get_chain_rssi() - get chain rssi
+ * @wiphy: wiphy pointer
+ * @wdev: pointer to struct wireless_dev
+ * @data: pointer to incoming NL vendor data
+ * @data_len: length of @data
+ *
+ * Return: 0 on success; error number otherwise.
+ */
+static int wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy,
+					    struct wireless_dev *wdev,
+					    const void *data,
+					    int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_chain_rssi(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_fill_intf_info() - Fill skb buffer with interface info
+ * @skb: Pointer to skb
+ * @info: mac mode info
+ * @index: attribute type index for nla_nest_start()
+ *
+ * Return : 0 on success and errno on failure
+ */
+static int wlan_hdd_fill_intf_info(struct sk_buff *skb,
+				   struct connection_info *info, int index)
+{
+	struct nlattr *attr;
+	uint32_t freq;
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *hdd_adapter;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx)
+		goto error;
+
+	hdd_adapter = hdd_get_adapter_by_vdev(hdd_ctx, info->vdev_id);
+	if (!hdd_adapter)
+		goto error;
+
+	attr = nla_nest_start(skb, index);
+	if (!attr)
+		goto error;
+
+	freq = sme_chn_to_freq(info->channel);
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX,
+	    hdd_adapter->dev->ifindex) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ, freq))
+		goto error;
+
+	nla_nest_end(skb, attr);
+
+	return 0;
+error:
+	hdd_err("Fill buffer with interface info failed");
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_fill_mac_info() - Fill skb buffer with mac info
+ * @skb: Pointer to skb
+ * @info: mac mode info
+ * @mac_id: MAC id
+ * @conn_count: number of current connections
+ *
+ * Return : 0 on success and errno on failure
+ */
+static int wlan_hdd_fill_mac_info(struct sk_buff *skb,
+				  struct connection_info *info, uint32_t mac_id,
+				  uint32_t conn_count)
+{
+	struct nlattr *attr, *intf_attr;
+	uint32_t band = 0, i = 0, j = 0;
+	bool present = false;
+
+	while (i < conn_count) {
+		if (info[i].mac_id == mac_id) {
+			present = true;
+			if (info[i].channel <= SIR_11B_CHANNEL_END)
+				band |= 1 << NL80211_BAND_2GHZ;
+			else if (info[i].channel <= SIR_11A_CHANNEL_END)
+				band |= 1 << NL80211_BAND_5GHZ;
+		}
+		i++;
+	}
+
+	if (!present)
+		return 0;
+
+	i = 0;
+	attr = nla_nest_start(skb, mac_id);
+	if (!attr)
+		goto error;
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID, mac_id) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND, band))
+		goto error;
+
+	intf_attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO);
+	if (!intf_attr)
+		goto error;
+
+	while (i < conn_count) {
+		if (info[i].mac_id == mac_id) {
+			if (wlan_hdd_fill_intf_info(skb, &info[i], j))
+				return -EINVAL;
+			j++;
+		}
+		i++;
+	}
+
+	nla_nest_end(skb, intf_attr);
+
+	nla_nest_end(skb, attr);
+
+	return 0;
+error:
+	hdd_err("Fill buffer with mac info failed");
+	return -EINVAL;
+}
+
+
+int wlan_hdd_send_mode_change_event(void)
+{
+	int err;
+	struct hdd_context *hdd_ctx;
+	struct sk_buff *skb;
+	struct nlattr *attr;
+	struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t conn_count, mac_id;
+
+	hdd_enter();
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return -EINVAL;
+	}
+
+	err = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != err)
+		return err;
+
+	conn_count = policy_mgr_get_connection_info(hdd_ctx->psoc, info);
+	if (!conn_count)
+		return -EINVAL;
+
+	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
+				  (sizeof(uint32_t) * 4) *
+				  MAX_NUMBER_OF_CONC_CONNECTIONS + NLMSG_HDRLEN,
+				  QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO_INDEX,
+				  GFP_KERNEL);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_MAC_INFO);
+	if (!attr) {
+		hdd_err("nla_nest_start failed");
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+
+	for (mac_id = 0; mac_id < MAX_MAC; mac_id++) {
+		if (wlan_hdd_fill_mac_info(skb, info, mac_id, conn_count)) {
+			kfree_skb(skb);
+			return -EINVAL;
+		}
+	}
+
+	nla_nest_end(skb, attr);
+
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+	hdd_exit();
+
+	return err;
+}
+
+const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = is_driver_dfs_capable
+	},
+
+#ifdef WLAN_FEATURE_NAN
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_nan_request
+	},
+#endif
+
+#ifdef WLAN_FEATURE_STATS_EXT
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_STATS_EXT,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_stats_ext_request
+	},
+#endif
+#ifdef FEATURE_WLAN_EXTSCAN
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_extscan_start
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_extscan_stop
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_extscan_get_valid_channels
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_extscan_get_capabilities
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_extscan_get_cached_results
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
+		.flags =
+			WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_extscan_set_significant_change
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
+		.flags =
+			WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_extscan_reset_significant_change
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_SET_LIST,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_epno_list
+	},
+#endif /* FEATURE_WLAN_EXTSCAN */
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_ll_stats_clear
+	},
+
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_ll_stats_set
+	},
+
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_ll_stats_get
+	},
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+#ifdef FEATURE_WLAN_TDLS
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_exttdls_enable
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_exttdls_disable
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wlan_hdd_cfg80211_exttdls_get_status
+	},
+#endif
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wlan_hdd_cfg80211_get_supported_features
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SCANNING_MAC_OUI,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_scanning_mac_oui
+	},
+
+	FEATURE_CONCURRENCY_MATRIX_VENDOR_COMMANDS
+
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_disable_dfs_chan_scan
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WISA,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_handle_wisa_cmd
+	},
+
+	FEATURE_STATION_INFO_VENDOR_COMMANDS
+
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DO_ACS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				WIPHY_VENDOR_CMD_NEED_NETDEV |
+				WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_do_acs
+	},
+
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wlan_hdd_cfg80211_get_features
+	},
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_keymgmt_set_key
+	},
+#endif
+#ifdef FEATURE_WLAN_EXTSCAN
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_SET_PASSPOINT_LIST,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_passpoint_list
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_RESET_PASSPOINT_LIST,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_reset_passpoint_list
+	},
+#endif /* FEATURE_WLAN_EXTSCAN */
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wlan_hdd_cfg80211_get_wifi_info
+	},
+#ifndef WLAN_UMAC_CONVERGENCE
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_wifi_configuration_set
+	},
+#endif
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_wifi_test_config
+	},
+
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAM,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_ext_roam_params
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_wifi_logger_start
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_get_preferred_freq_list
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_probable_oper_channel
+	},
+#ifdef WLAN_FEATURE_TSF
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TSF,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_handle_tsf_cmd
+	},
+#endif
+#ifdef FEATURE_WLAN_TDLS
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_get_tdls_capabilities
+	},
+#endif
+#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_offloaded_packets
+	},
+#endif
+	FEATURE_RSSI_MONITOR_VENDOR_COMMANDS
+
+#ifdef WLAN_NS_OFFLOAD
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_ns_offload
+	},
+#endif /* WLAN_NS_OFFLOAD */
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wlan_hdd_cfg80211_get_logger_supp_feature
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_vendor_scan
+	},
+
+	/* Vendor abort scan */
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_vendor_abort_scan
+	},
+
+	/* OCB commands */
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_SET_CONFIG,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				 WIPHY_VENDOR_CMD_NEED_NETDEV |
+				 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_ocb_set_config
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_SET_UTC_TIME,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				 WIPHY_VENDOR_CMD_NEED_NETDEV |
+				 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_ocb_set_utc_time
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_OCB_START_TIMING_ADVERT,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				 WIPHY_VENDOR_CMD_NEED_NETDEV |
+				 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_ocb_start_timing_advert
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_STOP_TIMING_ADVERT,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				 WIPHY_VENDOR_CMD_NEED_NETDEV |
+				 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_ocb_stop_timing_advert
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_GET_TSF_TIMER,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				 WIPHY_VENDOR_CMD_NEED_NETDEV |
+				 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_ocb_get_tsf_timer
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_GET_STATS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				 WIPHY_VENDOR_CMD_NEED_NETDEV |
+				 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_dcc_get_stats
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_CLEAR_STATS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				 WIPHY_VENDOR_CMD_NEED_NETDEV |
+				 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_dcc_clear_stats
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_UPDATE_NDL,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				 WIPHY_VENDOR_CMD_NEED_NETDEV |
+				 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_dcc_update_ndl
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_get_link_properties
+	},
+
+	FEATURE_OTA_TEST_VENDOR_COMMANDS
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				WIPHY_VENDOR_CMD_NEED_NETDEV |
+				WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_gateway_params
+	},
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+
+	FEATURE_TX_POWER_VENDOR_COMMANDS
+
+#ifdef FEATURE_WLAN_APF
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_apf_offload
+	},
+#endif /* FEATURE_WLAN_APF */
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_acs_dfs_mode
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_STA_CONNECT_ROAM_POLICY,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_sta_roam_policy
+	},
+#ifdef FEATURE_WLAN_CH_AVOID
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_avoid_freq
+	},
+#endif
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_SAP_CONFIG,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_sap_configuration_set
+	},
+
+	FEATURE_P2P_LISTEN_OFFLOAD_VENDOR_COMMANDS
+
+	FEATURE_SAP_COND_CHAN_SWITCH_VENDOR_COMMANDS
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NDP,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_process_ndp_cmd
+	},
+#endif
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_get_wakelock_stats
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_get_bus_size
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_update_vendor_channel
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+					WIPHY_VENDOR_CMD_NEED_NETDEV |
+					WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_setband
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_fast_roaming
+	},
+#ifdef WLAN_FEATURE_DISA
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_ENCRYPTION_TEST,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				 WIPHY_VENDOR_CMD_NEED_NETDEV |
+				 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_encrypt_decrypt_msg
+	},
+#endif
+#ifdef FEATURE_WLAN_TDLS
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_CONFIGURE_TDLS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_configure_tdls_mode
+	},
+#endif
+	FEATURE_SAR_LIMITS_VENDOR_COMMANDS
+
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_sar_power_limits
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_TRACE_LEVEL,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_trace_level
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd =
+			QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				 WIPHY_VENDOR_CMD_NEED_NETDEV |
+				 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_ll_stats_ext_set_param
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_nud_stats
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_get_nud_stats
+	},
+
+	FEATURE_BSS_TRANSITION_VENDOR_COMMANDS
+	FEATURE_SPECTRAL_SCAN_VENDOR_COMMANDS
+#ifdef WLAN_UMAC_CONVERGENCE
+	COMMON_VENDOR_COMMANDS
+#endif
+	FEATURE_11AX_VENDOR_COMMANDS
+
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_get_chain_rssi
+	},
+
+	FEATURE_ACTIVE_TOS_VENDOR_COMMANDS
+
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
+static inline void
+hdd_wiphy_set_max_sched_scans(struct wiphy *wiphy, uint8_t max_scans)
+{
+	if (max_scans == 0)
+		wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+	else
+		wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+}
+#else
+static inline void
+hdd_wiphy_set_max_sched_scans(struct wiphy *wiphy, uint8_t max_scans)
+{
+	wiphy->max_sched_scan_reqs = max_scans;
+}
+#endif /* KERNEL_VERSION(4, 12, 0) */
+
+/**
+ * wlan_hdd_cfg80211_add_connected_pno_support() - Set connected PNO support
+ * @wiphy: Pointer to wireless phy
+ *
+ * This function is used to set connected PNO support to kernel
+ *
+ * Return: None
+ */
+#if defined(CFG80211_REPORT_BETTER_BSS_IN_SCHED_SCAN) || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+static void wlan_hdd_cfg80211_add_connected_pno_support(struct wiphy *wiphy)
+{
+	wiphy_ext_feature_set(wiphy,
+		NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI);
+}
+#else
+static void wlan_hdd_cfg80211_add_connected_pno_support(struct wiphy *wiphy)
+{
+}
+#endif
+
+#if ((LINUX_VERSION_CODE > KERNEL_VERSION(4, 4, 0)) || \
+	defined(CFG80211_MULTI_SCAN_PLAN_BACKPORT)) && \
+	defined(FEATURE_WLAN_SCAN_PNO)
+/**
+ * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
+ * @wiphy: pointer to wiphy
+ * @config: pointer to config
+ *
+ * Return: None
+ */
+static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
+						 struct hdd_config *config)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	psoc = hdd_ctx->psoc;
+
+	if (!psoc) {
+		hdd_err("Invalid psoc");
+		return;
+	}
+
+	if (config->configPNOScanSupport) {
+		hdd_wiphy_set_max_sched_scans(wiphy, 1);
+		wiphy->max_sched_scan_ssids = SCAN_PNO_MAX_SUPP_NETWORKS;
+		wiphy->max_match_sets = SCAN_PNO_MAX_SUPP_NETWORKS;
+		wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
+		wiphy->max_sched_scan_plans = SCAN_PNO_MAX_PLAN_REQUEST;
+
+		/*
+		 * Exception: Using cfg_get() here because these two
+		 * schedule scan params are used only at this place
+		 * to copy to wiphy structure
+		 */
+		wiphy->max_sched_scan_plan_interval =
+			cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_INTERVAL);
+
+		wiphy->max_sched_scan_plan_iterations =
+			cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS);
+	}
+}
+#else
+static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
+						 struct hdd_config *config)
+{
+}
+#endif
+
+struct hdd_context *hdd_cfg80211_wiphy_alloc(void)
+{
+	struct wiphy *wiphy;
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter();
+
+	wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, sizeof(*hdd_ctx));
+	if (!wiphy) {
+		hdd_err("failed to allocate wiphy!");
+		return NULL;
+	}
+
+	hdd_ctx = wiphy_priv(wiphy);
+	hdd_ctx->wiphy = wiphy;
+
+	return hdd_ctx;
+}
+
+/*
+ * FUNCTION: wlan_hdd_cfg80211_update_band
+ * This function is called from the supplicant through a
+ * private ioctl to change the band value
+ */
+int wlan_hdd_cfg80211_update_band(struct hdd_context *hdd_ctx, struct wiphy *wiphy,
+		enum band_info eBand)
+{
+	int i, j;
+	enum channel_state channelEnabledState;
+
+	hdd_enter();
+
+	for (i = 0; i < HDD_NUM_NL80211_BANDS; i++) {
+
+		if (NULL == wiphy->bands[i])
+			continue;
+
+		for (j = 0; j < wiphy->bands[i]->n_channels; j++) {
+			struct ieee80211_supported_band *band = wiphy->bands[i];
+
+			channelEnabledState = wlan_reg_get_channel_state(
+					hdd_ctx->pdev,
+					band->channels[j].hw_value);
+
+			if (HDD_NL80211_BAND_2GHZ == i &&
+				BAND_5G == eBand) {
+				/* 5G only */
+#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
+				/* Enable Social channels for P2P */
+				if (WLAN_HDD_IS_SOCIAL_CHANNEL
+					    (band->channels[j].center_freq)
+				    && CHANNEL_STATE_ENABLE ==
+				    channelEnabledState)
+					band->channels[j].flags &=
+						~IEEE80211_CHAN_DISABLED;
+				else
+#endif
+				band->channels[j].flags |=
+					IEEE80211_CHAN_DISABLED;
+				continue;
+			} else if (HDD_NL80211_BAND_5GHZ == i &&
+					BAND_2G == eBand) {
+				/* 2G only */
+				band->channels[j].flags |=
+					IEEE80211_CHAN_DISABLED;
+				continue;
+			}
+
+			if (CHANNEL_STATE_DISABLE != channelEnabledState)
+				band->channels[j].flags &=
+					~IEEE80211_CHAN_DISABLED;
+		}
+	}
+	return 0;
+}
+
+#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+static void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = wiphy_priv(wiphy);
+
+	if (false == hdd_ctx->config->enable_mac_spoofing) {
+		hdd_warn("MAC address spoofing is not enabled");
+	} else {
+		wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
+		wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
+	}
+}
+#else
+static void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy)
+{
+}
+#endif
+
+#define WLAN_HDD_MAX_NUM_CSA_COUNTERS 2
+
+#if defined(CFG80211_RAND_TA_FOR_PUBLIC_ACTION_FRAME) || \
+		(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+/**
+ * wlan_hdd_cfg80211_action_frame_randomization_init() - Randomize SA of MA
+ * frames
+ * @wiphy: Pointer to wiphy
+ *
+ * This function is used to indicate the support of source mac address
+ * randomization of management action frames
+ *
+ * Return: None
+ */
+static void
+wlan_hdd_cfg80211_action_frame_randomization_init(struct wiphy *wiphy)
+{
+	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA);
+}
+#else
+static void
+wlan_hdd_cfg80211_action_frame_randomization_init(struct wiphy *wiphy)
+{
+}
+#endif
+
+#if defined(WLAN_FEATURE_FILS_SK) && \
+	(defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
+		 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)))
+static void wlan_hdd_cfg80211_set_wiphy_fils_feature(struct wiphy *wiphy)
+{
+	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
+}
+#else
+static void wlan_hdd_cfg80211_set_wiphy_fils_feature(struct wiphy *wiphy)
+{
+}
+#endif
+
+#if defined (CFG80211_SCAN_DBS_CONTROL_SUPPORT) || \
+	    (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0))
+static void wlan_hdd_cfg80211_set_wiphy_scan_flags(struct wiphy *wiphy)
+{
+	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_LOW_SPAN_SCAN);
+	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_LOW_POWER_SCAN);
+	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN);
+}
+#else
+static void wlan_hdd_cfg80211_set_wiphy_scan_flags(struct wiphy *wiphy)
+{
+}
+#endif
+
+#if defined(WLAN_FEATURE_SAE) && \
+	defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+/**
+ * wlan_hdd_cfg80211_set_wiphy_sae_feature() - Indicates support of SAE feature
+ * @wiphy: Pointer to wiphy
+ * @config: pointer to config
+ *
+ * This function is used to indicate the support of SAE
+ *
+ * Return: None
+ */
+static void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
+			struct hdd_config *config)
+{
+	if (config->is_sae_enabled)
+		wiphy->features |= NL80211_FEATURE_SAE;
+}
+#else
+static void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
+			struct hdd_config *config)
+{
+}
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) || \
+	defined(CFG80211_DFS_OFFLOAD_BACKPORT)
+static void wlan_hdd_cfg80211_set_dfs_offload_feature(struct wiphy *wiphy)
+{
+	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD);
+}
+#else
+static void wlan_hdd_cfg80211_set_dfs_offload_feature(struct wiphy *wiphy)
+{
+	wiphy->flags |= WIPHY_FLAG_DFS_OFFLOAD;
+}
+#endif
+
+#ifdef WLAN_FEATURE_DSRC
+static void wlan_hdd_get_num_dsrc_ch_and_len(struct hdd_config *hdd_cfg,
+					     int *num_ch, int *ch_len)
+{
+	*num_ch = QDF_ARRAY_SIZE(hdd_channels_dot11p);
+	*ch_len = sizeof(hdd_channels_dot11p);
+}
+
+static void wlan_hdd_copy_dsrc_ch(char *ch_ptr, int ch_arr_len)
+{
+	if (!ch_arr_len)
+		return;
+	qdf_mem_copy(ch_ptr, &hdd_channels_dot11p[0], ch_arr_len);
+}
+
+static void wlan_hdd_get_num_srd_ch_and_len(struct hdd_config *hdd_cfg,
+					    int *num_ch, int *ch_len)
+{
+	*num_ch = 0;
+	*ch_len = 0;
+}
+
+static void wlan_hdd_copy_srd_ch(char *ch_ptr, int ch_arr_len)
+{
+}
+
+/**
+ * wlan_hdd_populate_srd_chan_info() - Populate SRD chan info in hdd context
+ * @hdd_ctx: pointer to hdd context
+ * @index: SRD channel beginning index in chan_info of @hdd_ctx
+ *
+ * Return: Number of SRD channels populated
+ */
+static uint32_t
+wlan_hdd_populate_srd_chan_info(struct hdd_context *hdd_ctx, uint32_t index)
+{
+	return 0;
+}
+
+#else
+
+static void wlan_hdd_get_num_dsrc_ch_and_len(struct hdd_config *hdd_cfg,
+					     int *num_ch, int *ch_len)
+{
+	*num_ch = 0;
+	*ch_len = 0;
+}
+
+static void wlan_hdd_copy_dsrc_ch(char *ch_ptr, int ch_arr_len)
+{
+}
+
+static void wlan_hdd_get_num_srd_ch_and_len(struct hdd_config *hdd_cfg,
+					    int *num_ch, int *ch_len)
+{
+	*num_ch = QDF_ARRAY_SIZE(hdd_etsi13_srd_ch);
+	*ch_len = sizeof(hdd_etsi13_srd_ch);
+}
+
+static void wlan_hdd_copy_srd_ch(char *ch_ptr, int ch_arr_len)
+{
+	if (!ch_arr_len)
+		return;
+	qdf_mem_copy(ch_ptr, &hdd_etsi13_srd_ch[0], ch_arr_len);
+}
+
+/**
+ * wlan_hdd_populate_srd_chan_info() - Populate SRD chan info in hdd context
+ * @hdd_ctx: pointer to hdd context
+ * @index: SRD channel beginning index in chan_info of @hdd_ctx
+ *
+ * Return: Number of SRD channels populated
+ */
+static uint32_t
+wlan_hdd_populate_srd_chan_info(struct hdd_context *hdd_ctx, uint32_t index)
+{
+	uint32_t num_srd_ch, i;
+	struct scan_chan_info *chan_info;
+
+	num_srd_ch = QDF_ARRAY_SIZE(hdd_etsi13_srd_ch);
+	chan_info = hdd_ctx->chan_info;
+
+	for (i = 0; i < num_srd_ch; i++)
+		chan_info[index + i].freq = hdd_etsi13_srd_ch[i].center_freq;
+
+	return num_srd_ch;
+}
+
+#endif
+
+/*
+ * FUNCTION: wlan_hdd_cfg80211_init
+ * This function is called by hdd_wlan_startup()
+ * during initialization.
+ * This function is used to initialize and register wiphy structure.
+ */
+int wlan_hdd_cfg80211_init(struct device *dev,
+			   struct wiphy *wiphy, struct hdd_config *pCfg)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int len_5g_ch = 0, num_ch, ch_arr_size;
+	int num_dsrc_ch, len_dsrc_ch, num_srd_ch, len_srd_ch;
+	uint32_t *cipher_suites;
+
+	hdd_enter();
+
+	/* Now bind the underlying wlan device with wiphy */
+	set_wiphy_dev(wiphy, dev);
+
+	wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
+
+	wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
+			| WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
+			| WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
+#ifdef FEATURE_WLAN_STA_4ADDR_SCHEME
+			| WIPHY_FLAG_4ADDR_STATION
+#endif
+			| WIPHY_FLAG_OFFCHAN_TX;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
+	wiphy->wowlan = &wowlan_support_cfg80211_init;
+#else
+	wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;
+	wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
+	wiphy->wowlan.pattern_min_len = 1;
+	wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
+#endif
+
+	if (pCfg->isFastTransitionEnabled || pCfg->isFastRoamIniFeatureEnabled
+#ifdef FEATURE_WLAN_ESE
+	    || pCfg->isEseIniFeatureEnabled
+#endif
+	    ) {
+		wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
+	}
+#ifdef FEATURE_WLAN_TDLS
+	wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
+			| WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
+#endif
+
+	wiphy->features |= NL80211_FEATURE_HT_IBSS;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
+	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
+#endif
+
+	wlan_hdd_cfg80211_set_wiphy_scan_flags(wiphy);
+
+	wlan_hdd_cfg80211_set_wiphy_sae_feature(wiphy, pCfg);
+
+	hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
+	wlan_hdd_cfg80211_add_connected_pno_support(wiphy);
+
+	wiphy->max_scan_ssids = MAX_SCAN_SSID;
+
+	wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
+
+	wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
+
+	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
+				 | BIT(NL80211_IFTYPE_ADHOC)
+				 | BIT(NL80211_IFTYPE_P2P_CLIENT)
+				 | BIT(NL80211_IFTYPE_P2P_GO)
+				 | BIT(NL80211_IFTYPE_AP)
+				 | BIT(NL80211_IFTYPE_MONITOR);
+
+	if (pCfg->advertiseConcurrentOperation) {
+		if (pCfg->enableMCC) {
+			int i;
+
+			for (i = 0;
+			     i < ARRAY_SIZE(wlan_hdd_iface_combination);
+			     i++) {
+				if (!pCfg->allowMCCGODiffBI)
+					wlan_hdd_iface_combination[i].
+					beacon_int_infra_match = true;
+			}
+		}
+		wiphy->n_iface_combinations =
+			ARRAY_SIZE(wlan_hdd_iface_combination);
+		wiphy->iface_combinations = wlan_hdd_iface_combination;
+	}
+
+	if (!pCfg->nChannelBondingMode5GHz)
+		wlan_hdd_band_5_ghz.ht_cap.cap &=
+			~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
+	/*
+	 * In case of static linked driver at the time of driver unload,
+	 * module exit doesn't happens. Module cleanup helps in cleaning
+	 * of static memory.
+	 * If driver load happens statically, at the time of driver unload,
+	 * wiphy flags don't get reset because of static memory.
+	 * It's better not to store channel in static memory.
+	 */
+	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[HDD_NL80211_BAND_2GHZ]->channels)
+		return -ENOMEM;
+	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(hdd_ctx)) &&
+		((eHDD_DOT11_MODE_11b != pCfg->dot11Mode) &&
+		 (eHDD_DOT11_MODE_11g != pCfg->dot11Mode) &&
+		 (eHDD_DOT11_MODE_11b_ONLY != pCfg->dot11Mode) &&
+		 (eHDD_DOT11_MODE_11g_ONLY != pCfg->dot11Mode))) {
+		wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_ghz;
+		wlan_hdd_get_num_dsrc_ch_and_len(pCfg, &num_dsrc_ch,
+						 &len_dsrc_ch);
+		wlan_hdd_get_num_srd_ch_and_len(pCfg, &num_srd_ch, &len_srd_ch);
+		num_ch = QDF_ARRAY_SIZE(hdd_channels_5_ghz) + num_dsrc_ch +
+			 num_srd_ch;
+		len_5g_ch = sizeof(hdd_channels_5_ghz);
+		ch_arr_size = len_5g_ch + len_dsrc_ch + len_srd_ch;
+
+		wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
+			qdf_mem_malloc(ch_arr_size);
+		if (!wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels)
+			goto mem_fail;
+		wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels = num_ch;
+
+		qdf_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
+			     &hdd_channels_5_ghz[0], len_5g_ch);
+		if (num_dsrc_ch)
+			wlan_hdd_copy_dsrc_ch((char *)wiphy->bands[
+					      HDD_NL80211_BAND_5GHZ]->channels +
+					      len_5g_ch, len_dsrc_ch);
+		if (num_srd_ch)
+			wlan_hdd_copy_srd_ch((char *)wiphy->bands[
+					     HDD_NL80211_BAND_5GHZ]->channels +
+					     len_5g_ch, len_srd_ch);
+	}
+
+	/*Initialise the supported cipher suite details */
+	if (pCfg->gcmp_enabled) {
+		cipher_suites = qdf_mem_malloc(sizeof(hdd_cipher_suites) +
+					       sizeof(hdd_gcmp_cipher_suits));
+		if (!cipher_suites)
+			return -ENOMEM;
+		wiphy->n_cipher_suites = QDF_ARRAY_SIZE(hdd_cipher_suites) +
+			 QDF_ARRAY_SIZE(hdd_gcmp_cipher_suits);
+		qdf_mem_copy(cipher_suites, &hdd_cipher_suites,
+			     sizeof(hdd_cipher_suites));
+		qdf_mem_copy(cipher_suites + QDF_ARRAY_SIZE(hdd_cipher_suites),
+			     &hdd_gcmp_cipher_suits,
+			     sizeof(hdd_gcmp_cipher_suits));
+	} else {
+		cipher_suites = qdf_mem_malloc(sizeof(hdd_cipher_suites));
+		if (!cipher_suites)
+			return -ENOMEM;
+		wiphy->n_cipher_suites = QDF_ARRAY_SIZE(hdd_cipher_suites);
+		qdf_mem_copy(cipher_suites, &hdd_cipher_suites,
+			     sizeof(hdd_cipher_suites));
+	}
+	wiphy->cipher_suites = cipher_suites;
+	cipher_suites = NULL;
+	/*signal strength in mBm (100*dBm) */
+	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+	wiphy->max_remain_on_channel_duration = MAX_REMAIN_ON_CHANNEL_DURATION;
+
+	if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE) {
+		wiphy->n_vendor_commands =
+				ARRAY_SIZE(hdd_wiphy_vendor_commands);
+		wiphy->vendor_commands = hdd_wiphy_vendor_commands;
+
+		wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
+		wiphy->n_vendor_events =
+				ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
+	}
+
+#ifdef QCA_HT_2040_COEX
+	wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
+#endif
+	wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) || \
+	defined(CFG80211_BEACON_TX_RATE_CUSTOM_BACKPORT)
+	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
+	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);
+	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
+#endif
+
+	hdd_add_channel_switch_support(&wiphy->flags);
+	wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
+	if (pCfg->enable_mac_spoofing)
+		wlan_hdd_cfg80211_scan_randomization_init(wiphy);
+	wlan_hdd_cfg80211_action_frame_randomization_init(wiphy);
+
+	hdd_exit();
+	return 0;
+
+mem_fail:
+	hdd_err("Not enough memory to allocate channels");
+	if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels != NULL) {
+		qdf_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
+		wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
+	}
+	return -ENOMEM;
+}
+
+/**
+ * wlan_hdd_cfg80211_deinit() - Deinit cfg80211
+ * @wiphy: the wiphy to validate against
+ *
+ * this function deinit cfg80211 and cleanup the
+ * memory allocated in wlan_hdd_cfg80211_init also
+ * reset the global reg params.
+ *
+ * Return: void
+ */
+void wlan_hdd_cfg80211_deinit(struct wiphy *wiphy)
+{
+	int i;
+	const uint32_t *cipher_suites;
+
+	for (i = 0; i < HDD_NUM_NL80211_BANDS; i++) {
+		if (NULL != wiphy->bands[i] &&
+		   (NULL != wiphy->bands[i]->channels)) {
+			qdf_mem_free(wiphy->bands[i]->channels);
+			wiphy->bands[i]->channels = NULL;
+		}
+	}
+
+	cipher_suites = wiphy->cipher_suites;
+	wiphy->cipher_suites = NULL;
+	wiphy->n_cipher_suites = 0;
+	qdf_mem_free((uint32_t *)cipher_suites);
+	cipher_suites = NULL;
+	hdd_reset_global_reg_params();
+}
+
+/**
+ * wlan_hdd_update_band_cap() - update capabilities for supported bands
+ * @hdd_ctx: HDD context
+ *
+ * this function will update capabilities for supported bands
+ *
+ * Return: void
+ */
+static void wlan_hdd_update_ht_cap(struct hdd_context *hdd_ctx)
+{
+	struct mlme_ht_capabilities_info ht_cap_info = {0};
+	QDF_STATUS status;
+
+	status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
+	if (QDF_STATUS_SUCCESS != status)
+		hdd_err("could not get HT capability info");
+
+	if (ht_cap_info.tx_stbc) {
+		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[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[HDD_NL80211_BAND_2GHZ]->
+						vht_cap.vht_supported = 0;
+		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[HDD_NL80211_BAND_5GHZ]->vht_cap.cap = 0;
+	}
+
+	if (!ht_cap_info.short_gi_20_mhz) {
+		wlan_hdd_band_2_4_ghz.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
+		wlan_hdd_band_5_ghz.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
+	}
+
+	if (!ht_cap_info.short_gi_40_mhz)
+		wlan_hdd_band_5_ghz.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
+}
+
+/**
+ * wlan_hdd_update_band_cap_in_wiphy() - update channel flags based on band cap
+ * @hdd_ctx: HDD context
+ *
+ * This function updates the channel flags based on the band capability set
+ * in the MLME CFG
+ *
+ * Return: void
+ */
+static void wlan_hdd_update_band_cap_in_wiphy(struct hdd_context *hdd_ctx)
+{
+	int i, j;
+	uint8_t band_capability;
+	QDF_STATUS status;
+	struct ieee80211_supported_band *band;
+
+	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get MLME Band Capability");
+		return;
+	}
+
+	for (i = 0; i < HDD_NUM_NL80211_BANDS; i++) {
+		if (NULL == hdd_ctx->wiphy->bands[i])
+			continue;
+
+		for (j = 0; j < hdd_ctx->wiphy->bands[i]->n_channels; j++) {
+			band = hdd_ctx->wiphy->bands[i];
+
+			if (HDD_NL80211_BAND_2GHZ == i &&
+			    BAND_5G == band_capability) {
+				/* 5G only */
+#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
+				/* Enable social channels for P2P */
+				if (WLAN_HDD_IS_SOCIAL_CHANNEL
+				    (band->channels[j].center_freq))
+					band->channels[j].flags &=
+						~IEEE80211_CHAN_DISABLED;
+				else
+#endif
+				band->channels[j].flags |=
+					IEEE80211_CHAN_DISABLED;
+				continue;
+			} else if (HDD_NL80211_BAND_5GHZ == i &&
+				   BAND_2G == band_capability) {
+				/* 2G only */
+				band->channels[j].flags |=
+					IEEE80211_CHAN_DISABLED;
+				continue;
+			}
+		}
+	}
+}
+
+/*
+ * In this function, wiphy structure is updated after QDF
+ * initialization. In wlan_hdd_cfg80211_init, only the
+ * default values will be initialized. The final initialization
+ * of all required members can be done here.
+ */
+void wlan_hdd_update_wiphy(struct hdd_context *hdd_ctx)
+{
+	int value;
+	bool fils_enabled;
+	bool dfs_master_capable = true;
+	QDF_STATUS status;
+
+	ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
+	hdd_ctx->wiphy->max_ap_assoc_sta = value;
+	wlan_hdd_update_ht_cap(hdd_ctx);
+	wlan_hdd_update_band_cap_in_wiphy(hdd_ctx);
+
+	fils_enabled = 0;
+	status = ucfg_mlme_get_fils_enabled_info(hdd_ctx->psoc,
+						 &fils_enabled);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("could not get fils enabled info");
+	if (fils_enabled)
+		wlan_hdd_cfg80211_set_wiphy_fils_feature(hdd_ctx->wiphy);
+
+	status = ucfg_mlme_get_dfs_master_capability(hdd_ctx->psoc,
+						     &dfs_master_capable);
+	if (QDF_IS_STATUS_SUCCESS(status) && dfs_master_capable)
+		wlan_hdd_cfg80211_set_dfs_offload_feature(hdd_ctx->wiphy);
+}
+
+/**
+ * wlan_hdd_update_11n_mode - update 11n mode in hdd cfg
+ * @cfg: hdd cfg
+ *
+ * this function update 11n mode in hdd cfg
+ *
+ * Return: void
+ */
+void wlan_hdd_update_11n_mode(struct hdd_config *cfg)
+{
+	if (sme_is_feature_supported_by_fw(DOT11AC)) {
+		hdd_debug("support 11ac");
+	} else {
+		hdd_debug("not support 11ac");
+		if ((cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) ||
+		    (cfg->dot11Mode == eHDD_DOT11_MODE_11ac)) {
+			cfg->dot11Mode = eHDD_DOT11_MODE_11n;
+			cfg->sap_11ac_override = 0;
+			cfg->go_11ac_override = 0;
+		}
+	}
+}
+
+/* In this function we are registering wiphy. */
+int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
+{
+	hdd_enter();
+	/* Register our wiphy dev with cfg80211 */
+	if (0 > wiphy_register(wiphy)) {
+		hdd_err("wiphy register failed");
+		return -EIO;
+	}
+
+	hdd_exit();
+	return 0;
+}
+
+/*
+ * HDD function to update wiphy capability based on target offload status.
+ *
+ * wlan_hdd_cfg80211_init() does initialization of all wiphy related
+ * capability even before downloading firmware to the target. In discrete
+ * case, host will get know certain offload capability (say sched_scan
+ * caps) only after downloading firmware to the target and target boots up.
+ * This function is used to override setting done in wlan_hdd_cfg80211_init()
+ * based on target capability.
+ */
+void wlan_hdd_cfg80211_update_wiphy_caps(struct wiphy *wiphy)
+{
+#ifdef FEATURE_WLAN_SCAN_PNO
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct hdd_config *pCfg = hdd_ctx->config;
+
+	/* wlan_hdd_cfg80211_init() sets sched_scan caps already in wiphy before
+	 * control comes here. Here just we need to clear it if firmware doesn't
+	 * have PNO support.
+	 */
+	if (!pCfg->PnoOffload) {
+		hdd_wiphy_set_max_sched_scans(wiphy, 0);
+		wiphy->max_sched_scan_ssids = 0;
+		wiphy->max_match_sets = 0;
+		wiphy->max_sched_scan_ie_len = 0;
+	}
+#endif
+}
+
+/* This function registers for all frame which supplicant is interested in */
+int wlan_hdd_cfg80211_register_frames(struct hdd_adapter *adapter)
+{
+	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
+	/* Register for all P2P action, public action etc frames */
+	uint16_t type = (SIR_MAC_MGMT_FRAME << 2) | (SIR_MAC_MGMT_ACTION << 4);
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	/* Register frame indication call back */
+	status = sme_register_mgmt_frame_ind_callback(mac_handle,
+						      hdd_indicate_mgmt_frame);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register hdd_indicate_mgmt_frame");
+		goto ret_status;
+	}
+
+	/* Right now we are registering these frame when driver is getting
+	 * initialized. Once we will move to 2.6.37 kernel, in which we have
+	 * frame register ops, we will move this code as a part of that
+	 */
+
+	/* GAS Initial Request */
+	status = sme_register_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+					 (uint8_t *) GAS_INITIAL_REQ,
+					 GAS_INITIAL_REQ_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register GAS_INITIAL_REQ");
+		goto ret_status;
+	}
+
+	/* GAS Initial Response */
+	status = sme_register_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+					 (uint8_t *) GAS_INITIAL_RSP,
+					 GAS_INITIAL_RSP_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register GAS_INITIAL_RSP");
+		goto dereg_gas_initial_req;
+	}
+
+	/* GAS Comeback Request */
+	status = sme_register_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+					 (uint8_t *) GAS_COMEBACK_REQ,
+					 GAS_COMEBACK_REQ_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register GAS_COMEBACK_REQ");
+		goto dereg_gas_initial_rsp;
+	}
+
+	/* GAS Comeback Response */
+	status = sme_register_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+					 (uint8_t *) GAS_COMEBACK_RSP,
+					 GAS_COMEBACK_RSP_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register GAS_COMEBACK_RSP");
+		goto dereg_gas_comeback_req;
+	}
+
+	/* WNM BSS Transition Request frame */
+	status = sme_register_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+					 (uint8_t *) WNM_BSS_ACTION_FRAME,
+					 WNM_BSS_ACTION_FRAME_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register WNM_BSS_ACTION_FRAME");
+		goto dereg_gas_comeback_rsp;
+	}
+
+	/* WNM-Notification */
+	status = sme_register_mgmt_frame(mac_handle, adapter->session_id, type,
+					 (uint8_t *) WNM_NOTIFICATION_FRAME,
+					 WNM_NOTIFICATION_FRAME_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register WNM_NOTIFICATION_FRAME");
+		goto dereg_wnm_bss_action_frm;
+	}
+
+	return 0;
+
+dereg_wnm_bss_action_frm:
+	sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+				  (uint8_t *) WNM_BSS_ACTION_FRAME,
+				  WNM_BSS_ACTION_FRAME_SIZE);
+dereg_gas_comeback_rsp:
+	sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+				  (uint8_t *) GAS_COMEBACK_RSP,
+				  GAS_COMEBACK_RSP_SIZE);
+dereg_gas_comeback_req:
+	sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+				  (uint8_t *) GAS_COMEBACK_REQ,
+				  GAS_COMEBACK_REQ_SIZE);
+dereg_gas_initial_rsp:
+	sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+				  (uint8_t *) GAS_INITIAL_RSP,
+				  GAS_INITIAL_RSP_SIZE);
+dereg_gas_initial_req:
+	sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+				  (uint8_t *) GAS_INITIAL_REQ,
+				  GAS_INITIAL_REQ_SIZE);
+ret_status:
+	return qdf_status_to_os_return(status);
+}
+
+void wlan_hdd_cfg80211_deregister_frames(struct hdd_adapter *adapter)
+{
+	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
+	/* Deregister for all P2P action, public action etc frames */
+	uint16_t type = (SIR_MAC_MGMT_FRAME << 2) | (SIR_MAC_MGMT_ACTION << 4);
+
+	hdd_enter();
+
+	/* Right now we are registering these frame when driver is getting
+	 * initialized. Once we will move to 2.6.37 kernel, in which we have
+	 * frame register ops, we will move this code as a part of that
+	 */
+
+	/* GAS Initial Request */
+
+	sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+				  (uint8_t *) GAS_INITIAL_REQ,
+				  GAS_INITIAL_REQ_SIZE);
+
+	/* GAS Initial Response */
+	sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+				  (uint8_t *) GAS_INITIAL_RSP,
+				  GAS_INITIAL_RSP_SIZE);
+
+	/* GAS Comeback Request */
+	sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+				  (uint8_t *) GAS_COMEBACK_REQ,
+				  GAS_COMEBACK_REQ_SIZE);
+
+	/* GAS Comeback Response */
+	sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+				  (uint8_t *) GAS_COMEBACK_RSP,
+				  GAS_COMEBACK_RSP_SIZE);
+
+	/* P2P Public Action */
+	sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+				  (uint8_t *) P2P_PUBLIC_ACTION_FRAME,
+				  P2P_PUBLIC_ACTION_FRAME_SIZE);
+
+	/* P2P Action */
+	sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
+				  (uint8_t *) P2P_ACTION_FRAME,
+				  P2P_ACTION_FRAME_SIZE);
+
+	/* WNM-Notification */
+	sme_deregister_mgmt_frame(mac_handle, adapter->session_id, type,
+				  (uint8_t *) WNM_NOTIFICATION_FRAME,
+				  WNM_NOTIFICATION_FRAME_SIZE);
+}
+
+#ifdef FEATURE_WLAN_WAPI
+static void wlan_hdd_cfg80211_set_key_wapi(struct hdd_adapter *adapter,
+					   uint8_t key_index,
+					   const uint8_t *mac_addr,
+					   const uint8_t *key,
+					   int key_Len)
+{
+	tCsrRoamSetKey setKey;
+	bool isConnected = true;
+	QDF_STATUS status;
+	uint32_t roamId = INVALID_ROAM_ID;
+	uint8_t *pKeyPtr = NULL;
+	mac_handle_t mac_handle;
+
+	hdd_debug("Device_mode %s(%d)",
+		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
+
+	qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
+	setKey.keyId = key_index;       /* Store Key ID */
+	setKey.encType = eCSR_ENCRYPT_TYPE_WPI; /* SET WAPI Encryption */
+	setKey.keyDirection = eSIR_TX_RX;       /* Key Directionn both TX and RX */
+	setKey.paeRole = 0;     /* the PAE role */
+	if (!mac_addr || is_broadcast_ether_addr(mac_addr))
+		qdf_set_macaddr_broadcast(&setKey.peerMac);
+	else
+		qdf_mem_copy(setKey.peerMac.bytes, mac_addr, QDF_MAC_ADDR_SIZE);
+
+	setKey.keyLength = key_Len;
+	pKeyPtr = setKey.Key;
+	memcpy(pKeyPtr, key, key_Len);
+
+	hdd_debug("WAPI KEY LENGTH:0x%04x", key_Len);
+
+	if (isConnected) {
+		mac_handle = hdd_adapter_get_mac_handle(adapter);
+		status = sme_roam_set_key(mac_handle,
+					  adapter->session_id,
+					  &setKey, &roamId);
+		if (status != QDF_STATUS_SUCCESS)
+			hdd_err("sme_roam_set_key failed status: %d", status);
+	}
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+bool wlan_hdd_is_ap_supports_immediate_power_save(uint8_t *ies, int length)
+{
+	const uint8_t *vendor_ie;
+
+	if (length < 2) {
+		hdd_debug("bss size is less than expected");
+		return true;
+	}
+	if (!ies) {
+		hdd_debug("invalid IE pointer");
+		return true;
+	}
+	vendor_ie = wlan_get_vendor_ie_ptr_from_oui(VENDOR1_AP_OUI_TYPE,
+				VENDOR1_AP_OUI_TYPE_SIZE, ies, length);
+	if (vendor_ie) {
+		hdd_debug("AP can't support immediate powersave. defer it");
+		return false;
+	}
+	return true;
+}
+
+/*
+ * FUNCTION: wlan_hdd_validate_operation_channel
+ * called by wlan_hdd_cfg80211_start_bss() and
+ * wlan_hdd_set_channel()
+ * This function validates whether given channel is part of valid
+ * channel list.
+ */
+QDF_STATUS wlan_hdd_validate_operation_channel(struct hdd_adapter *adapter,
+					       int channel)
+{
+	uint32_t num_ch = 0;
+	u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	u32 indx = 0;
+	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
+	uint8_t fValidChannel = false, count = 0;
+	QDF_STATUS status;
+	bool value;
+	struct hdd_context *hdd_ctx;
+
+	num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = ucfg_mlme_get_sap_allow_all_channels(hdd_ctx->psoc, &value);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_err("Unable to fetch sap allow all channels");
+	if (value) {
+		/* Validate the channel */
+		for (count = CHAN_ENUM_1; count <= CHAN_ENUM_173; count++) {
+			if (channel == WLAN_REG_CH_NUM(count)) {
+				fValidChannel = true;
+				break;
+			}
+		}
+		if (fValidChannel != true) {
+			hdd_err("Invalid Channel: %d", channel);
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		if (0 != sme_cfg_get_str(mac_handle, WNI_CFG_VALID_CHANNEL_LIST,
+					 valid_ch, &num_ch)) {
+			hdd_err("failed to get valid channel list");
+			return QDF_STATUS_E_FAILURE;
+		}
+		for (indx = 0; indx < num_ch; indx++) {
+			if (channel == valid_ch[indx])
+				break;
+		}
+
+		if (indx >= num_ch) {
+			hdd_err("Invalid Channel: %d", channel);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+
+}
+
+#ifdef DHCP_SERVER_OFFLOAD
+static void wlan_hdd_set_dhcp_server_offload(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	tpSirDhcpSrvOffloadInfo pDhcpSrvInfo;
+	uint8_t numEntries = 0;
+	uint8_t srv_ip[IPADDR_NUM_ENTRIES];
+	uint8_t num;
+	uint32_t temp;
+	uint32_t dhcp_max_num_clients;
+	mac_handle_t mac_handle;
+	QDF_STATUS status;
+
+	pDhcpSrvInfo = qdf_mem_malloc(sizeof(*pDhcpSrvInfo));
+	if (!pDhcpSrvInfo)
+		return;
+	pDhcpSrvInfo->vdev_id = adapter->session_id;
+	pDhcpSrvInfo->dhcpSrvOffloadEnabled = true;
+
+	status = ucfg_fwol_get_dhcp_max_num_clients(hdd_ctx->psoc,
+						    &dhcp_max_num_clients);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+
+	pDhcpSrvInfo->dhcpClientNum = dhcp_max_num_clients;
+	hdd_string_to_u8_array(hdd_ctx->config->dhcpServerIP,
+			       srv_ip, &numEntries, IPADDR_NUM_ENTRIES);
+	if (numEntries != IPADDR_NUM_ENTRIES) {
+		hdd_err("Incorrect IP address (%s) assigned for DHCP server!", hdd_ctx->config->dhcpServerIP);
+		goto end;
+	}
+	if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
+		hdd_err("Invalid IP address (%s)! It could NOT be multicast IP address!", hdd_ctx->config->dhcpServerIP);
+		goto end;
+	}
+	if (srv_ip[IPADDR_NUM_ENTRIES - 1] >= 100) {
+		hdd_err("Invalid IP address (%s)! The last field must be less than 100!", hdd_ctx->config->dhcpServerIP);
+		goto end;
+	}
+	for (num = 0; num < numEntries; num++) {
+		temp = srv_ip[num];
+		pDhcpSrvInfo->dhcpSrvIP |= (temp << (8 * num));
+	}
+	mac_handle = hdd_ctx->mac_handle;
+	if (QDF_STATUS_SUCCESS !=
+	    sme_set_dhcp_srv_offload(mac_handle, pDhcpSrvInfo)) {
+		hdd_err("sme_setDHCPSrvOffload fail!");
+		goto end;
+	}
+	hdd_debug("enable DHCP Server offload successfully!");
+end:
+	qdf_mem_free(pDhcpSrvInfo);
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
+static int __wlan_hdd_cfg80211_change_bss(struct wiphy *wiphy,
+					  struct net_device *dev,
+					  struct bss_parameters *params)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int ret = 0;
+	QDF_STATUS qdf_ret_status;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
+			 adapter->session_id, params->ap_isolate));
+	hdd_debug("Device_mode %s(%d), ap_isolate = %d",
+		  qdf_opmode_str(adapter->device_mode),
+		  adapter->device_mode, params->ap_isolate);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	if (!(adapter->device_mode == QDF_SAP_MODE ||
+	      adapter->device_mode == QDF_P2P_GO_MODE)) {
+		return -EOPNOTSUPP;
+	}
+
+	/* ap_isolate == -1 means that in change bss, upper layer doesn't
+	 * want to update this parameter
+	 */
+	if (-1 != params->ap_isolate) {
+		adapter->session.ap.disable_intrabss_fwd =
+			!!params->ap_isolate;
+
+		mac_handle = hdd_ctx->mac_handle;
+		qdf_ret_status = sme_ap_disable_intra_bss_fwd(mac_handle,
+							      adapter->session_id,
+							      adapter->session.
+							      ap.
+							      disable_intrabss_fwd);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status))
+			ret = -EINVAL;
+
+		ucfg_ipa_set_ap_ibss_fwd(hdd_ctx->pdev,
+					 adapter->session.ap.
+					 disable_intrabss_fwd);
+	}
+
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * hdd_change_adapter_mode() - change @adapter's operating mode to @new_mode
+ * @adapter: the adapter to change modes on
+ * @new_mode: the new operating mode to change to
+ *
+ * Return: Errno
+ */
+static int hdd_change_adapter_mode(struct hdd_adapter *adapter,
+				   enum QDF_OPMODE new_mode)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct net_device *netdev = adapter->dev;
+	struct hdd_config *config = hdd_ctx->config;
+	struct csr_roam_profile *roam_profile;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	hdd_enter();
+
+	if (test_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags)) {
+		hdd_warn("Can't change interface: ACS in progress");
+		return -EBUSY;
+	}
+
+	hdd_stop_adapter(hdd_ctx, adapter);
+	hdd_deinit_adapter(hdd_ctx, adapter, true);
+	adapter->device_mode = new_mode;
+	memset(&adapter->session, 0, sizeof(adapter->session));
+	hdd_set_station_ops(netdev);
+
+	roam_profile = hdd_roam_profile(adapter);
+	roam_profile->pAddIEScan = adapter->scan_info.scan_add_ie.addIEdata;
+	roam_profile->nAddIEScanLength = adapter->scan_info.scan_add_ie.length;
+
+	if (new_mode == QDF_IBSS_MODE) {
+		status = hdd_start_station_adapter(adapter);
+		roam_profile->BSSType = eCSR_BSS_TYPE_START_IBSS;
+		roam_profile->phyMode =
+			hdd_cfg_xlate_to_csr_phy_mode(config->dot11Mode);
+	}
+
+	hdd_exit();
+
+	return qdf_status_to_os_return(status);
+}
+
+static int wlan_hdd_cfg80211_change_bss(struct wiphy *wiphy,
+					struct net_device *dev,
+					struct bss_parameters *params)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_nl_to_policy_mgr_iface_type() - map nl80211_iftype to policy_mgr_con_mode
+ * @type: the input NL80211 interface type to map
+ *
+ * Return: policy_mgr_con_mode
+ */
+static enum policy_mgr_con_mode
+hdd_nl_to_policy_mgr_iface_type(enum nl80211_iftype type)
+{
+	switch (type) {
+	case NL80211_IFTYPE_STATION:
+		return PM_STA_MODE;
+	case NL80211_IFTYPE_P2P_CLIENT:
+		return PM_P2P_CLIENT_MODE;
+	case NL80211_IFTYPE_P2P_GO:
+		return PM_P2P_GO_MODE;
+	case NL80211_IFTYPE_AP:
+		return PM_SAP_MODE;
+	case NL80211_IFTYPE_ADHOC:
+		return PM_IBSS_MODE;
+	default:
+		hdd_err("Unsupported interface type: %d", type);
+		return PM_MAX_NUM_OF_MODE;
+	}
+}
+
+static bool hdd_is_client_mode(enum QDF_OPMODE mode)
+{
+	switch (mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_P2P_DEVICE_MODE:
+	case QDF_IBSS_MODE:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool hdd_is_ap_mode(enum QDF_OPMODE mode)
+{
+	switch (mode) {
+	case QDF_SAP_MODE:
+	case QDF_P2P_GO_MODE:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/**
+ * __wlan_hdd_cfg80211_change_iface() - change interface cfg80211 op
+ * @wiphy: Pointer to the wiphy structure
+ * @ndev: Pointer to the net device
+ * @type: Interface type
+ * @flags: Flags for change interface
+ * @params: Pointer to change interface parameters
+ *
+ * Return: 0 for success, error number on failure.
+ */
+static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
+					    struct net_device *ndev,
+					    enum nl80211_iftype type,
+					    u32 *flags,
+					    struct vif_params *params)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	struct hdd_context *hdd_ctx;
+	bool iff_up = ndev->flags & IFF_UP;
+	enum QDF_OPMODE new_mode;
+	QDF_STATUS status;
+	int errno;
+
+	hdd_enter();
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
+			 adapter->session_id, type));
+
+	status = hdd_nl_to_qdf_iface_type(type, &new_mode);
+	if (QDF_IS_STATUS_ERROR(status))
+		return qdf_status_to_os_return(status);
+
+	/* A userspace issue leads to it sending a 'change to station mode'
+	 * request on a "p2p" device, expecting the driver do execute a 'change
+	 * to p2p-device mode' request instead. The (unfortunate) work around
+	 * here is implemented by overriding the new mode if the net_device name
+	 * starts with "p2p" and the requested mode was station.
+	 */
+	if (strnstr(ndev->name, "p2p", 3) && new_mode == QDF_STA_MODE)
+		new_mode = QDF_P2P_DEVICE_MODE;
+
+	hdd_debug("Changing mode for '%s' from %s to %s",
+		  ndev->name,
+		  qdf_opmode_str(adapter->device_mode),
+		  qdf_opmode_str(new_mode));
+
+	errno = hdd_wlan_start_modules(hdd_ctx, false);
+	if (errno) {
+		hdd_err("Failed to start modules; errno:%d", errno);
+		return -EINVAL;
+	}
+
+	if (!policy_mgr_allow_concurrency(hdd_ctx->psoc,
+					  hdd_nl_to_policy_mgr_iface_type(type),
+					  0, HW_MODE_20_MHZ)) {
+		hdd_debug("This concurrency combination is not allowed");
+		return -EINVAL;
+	}
+
+	/* Reset the current device mode bit mask */
+	policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
+
+	/* TDLS ignores p2p-device mode for concurrency considerations */
+	if (new_mode != QDF_P2P_DEVICE_MODE) {
+		hdd_debug("Disable tdls; new interface is coming up");
+		hdd_notify_teardown_tdls_links(adapter->vdev);
+	}
+
+	if (hdd_is_client_mode(adapter->device_mode)) {
+		if (hdd_is_client_mode(new_mode)) {
+			if (new_mode == QDF_IBSS_MODE)
+				hdd_deregister_tx_flow_control(adapter);
+
+			errno = hdd_change_adapter_mode(adapter, new_mode);
+			if (errno) {
+				hdd_err("change intf mode fail %d", errno);
+				goto err;
+			}
+		} else if (hdd_is_ap_mode(new_mode)) {
+			if (new_mode == QDF_P2P_GO_MODE)
+				wlan_hdd_cancel_existing_remain_on_channel
+					(adapter);
+
+			hdd_stop_adapter(hdd_ctx, adapter);
+			hdd_deinit_adapter(hdd_ctx, adapter, true);
+			memset(&adapter->session, 0, sizeof(adapter->session));
+			adapter->device_mode = new_mode;
+
+			if (adapter->device_mode == QDF_SAP_MODE &&
+			    hdd_ctx->config->apRandomBssidEnabled) {
+				/* To meet Android requirements create
+				 * a randomized MAC address of the
+				 * form 02:1A:11:Fx:xx:xx
+				 */
+				get_random_bytes(&ndev->dev_addr[3], 3);
+				ndev->dev_addr[0] = 0x02;
+				ndev->dev_addr[1] = 0x1A;
+				ndev->dev_addr[2] = 0x11;
+				ndev->dev_addr[3] |= 0xF0;
+				memcpy(adapter->mac_addr.bytes, ndev->dev_addr,
+				       QDF_MAC_ADDR_SIZE);
+				pr_info("wlan: Generated HotSpot BSSID "
+					MAC_ADDRESS_STR "\n",
+					MAC_ADDR_ARRAY(ndev->dev_addr));
+			}
+
+			hdd_set_ap_ops(adapter->dev);
+		} else {
+			hdd_err("Changing to device mode '%s' is not supported",
+				qdf_opmode_str(new_mode));
+			errno = -EOPNOTSUPP;
+			goto err;
+		}
+	} else if (hdd_is_ap_mode(adapter->device_mode)) {
+		if (hdd_is_client_mode(new_mode)) {
+			errno = hdd_change_adapter_mode(adapter, new_mode);
+			if (errno) {
+				hdd_err("change mode fail %d", errno);
+				goto err;
+			}
+		} else if (hdd_is_ap_mode(new_mode)) {
+			adapter->device_mode = new_mode;
+
+			/* avoid starting the adapter, since it never stopped */
+			iff_up = false;
+		} else {
+			hdd_err("Changing to device mode '%s' is not supported",
+				qdf_opmode_str(new_mode));
+			errno = -EOPNOTSUPP;
+			goto err;
+		}
+	} else {
+		hdd_err("Changing from device mode '%s' is not supported",
+			qdf_opmode_str(adapter->device_mode));
+		errno = -EOPNOTSUPP;
+		goto err;
+	}
+
+	/* restart the adapter if it was up before the change iface request */
+	if (iff_up) {
+		errno = hdd_start_adapter(adapter);
+		if (errno) {
+			hdd_err("Failed to start adapter");
+			errno = -EINVAL;
+			goto err;
+		}
+	}
+
+	ndev->ieee80211_ptr->iftype = type;
+	hdd_lpass_notify_mode_change(adapter);
+err:
+	/* Set bitmask based on updated value */
+	policy_mgr_set_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
+
+	hdd_exit();
+
+	return errno;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
+/**
+ * wlan_hdd_cfg80211_change_iface() - change interface cfg80211 op
+ * @wiphy: Pointer to the wiphy structure
+ * @ndev: Pointer to the net device
+ * @type: Interface type
+ * @flags: Flags for change interface
+ * @params: Pointer to change interface parameters
+ *
+ * Return: 0 for success, error number on failure.
+ */
+static int wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
+					  struct net_device *ndev,
+					  enum nl80211_iftype type,
+					  u32 *flags,
+					  struct vif_params *params)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret =
+		__wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#else
+static int wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
+					  struct net_device *ndev,
+					  enum nl80211_iftype type,
+					  struct vif_params *params)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type,
+					       &params->flags, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif /* KERNEL_VERSION(4, 12, 0) */
+
+/**
+ * __wlan_hdd_change_station() - change station
+ * @wiphy: Pointer to the wiphy structure
+ * @dev: Pointer to the net device.
+ * @mac: bssid
+ * @params: Pointer to station parameters
+ *
+ * Return: 0 for success, error number on failure.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+static int __wlan_hdd_change_station(struct wiphy *wiphy,
+				   struct net_device *dev,
+				   const uint8_t *mac,
+				   struct station_parameters *params)
+#else
+static int __wlan_hdd_change_station(struct wiphy *wiphy,
+				   struct net_device *dev,
+				   uint8_t *mac,
+				   struct station_parameters *params)
+#endif
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	struct hdd_station_ctx *sta_ctx;
+	struct hdd_ap_ctx *ap_ctx;
+	struct qdf_mac_addr STAMacAddress;
+	int ret;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CHANGE_STATION,
+			 adapter->session_id, params->listen_interval));
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	qdf_mem_copy(STAMacAddress.bytes, mac, QDF_MAC_ADDR_SIZE);
+
+	if ((adapter->device_mode == QDF_SAP_MODE) ||
+	    (adapter->device_mode == QDF_P2P_GO_MODE)) {
+		if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
+			ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+			/*
+			 * For Encrypted SAP session, this will be done as
+			 * part of eSAP_STA_SET_KEY_EVENT
+			 */
+			if (ap_ctx->encryption_type !=
+			    eCSR_ENCRYPT_TYPE_NONE) {
+				hdd_debug("Encrypt type %d, not setting peer authorized now",
+					  ap_ctx->encryption_type);
+				return 0;
+			}
+
+			status =
+				hdd_softap_change_sta_state(adapter,
+							    &STAMacAddress,
+							    OL_TXRX_PEER_STATE_AUTH);
+
+			if (status != QDF_STATUS_SUCCESS) {
+				hdd_debug("Not able to change TL state to AUTHENTICATED");
+				return -EINVAL;
+			}
+		}
+	} else if ((adapter->device_mode == QDF_STA_MODE) ||
+		   (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
+		if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
+#if defined(FEATURE_WLAN_TDLS)
+			ret = wlan_cfg80211_tdls_update_peer(hdd_ctx->pdev,
+							     dev, mac, params);
+#endif
+		}
+	}
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * wlan_hdd_change_station() - cfg80211 change station handler function
+ * @wiphy: Pointer to the wiphy structure
+ * @dev: Pointer to the net device.
+ * @mac: bssid
+ * @params: Pointer to station parameters
+ *
+ * This is the cfg80211 change station handler function which invokes
+ * the internal function @__wlan_hdd_change_station with
+ * SSR protection.
+ *
+ * Return: 0 for success, error number on failure.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) || defined(WITH_BACKPORTS)
+static int wlan_hdd_change_station(struct wiphy *wiphy,
+				   struct net_device *dev,
+				   const u8 *mac,
+				   struct station_parameters *params)
+#else
+static int wlan_hdd_change_station(struct wiphy *wiphy,
+				   struct net_device *dev,
+				   u8 *mac,
+				   struct station_parameters *params)
+#endif
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/*
+ * FUNCTION: __wlan_hdd_cfg80211_add_key
+ * This function is used to initialize the key information
+ */
+static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
+				       struct net_device *ndev,
+				       u8 key_index, bool pairwise,
+				       const u8 *mac_addr,
+				       struct key_params *params)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	tCsrRoamSetKey setKey;
+	int status;
+	uint32_t roamId = INVALID_ROAM_ID;
+	QDF_STATUS qdf_ret_status;
+	struct hdd_context *hdd_ctx;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_ADD_KEY,
+			 adapter->session_id, params->key_len));
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	hdd_debug("Device_mode %s(%d)",
+		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
+
+	if (CSR_MAX_NUM_KEY <= key_index) {
+		hdd_err("Invalid key index %d", key_index);
+
+		return -EINVAL;
+	}
+
+	if (CSR_MAX_KEY_LEN < params->key_len) {
+		hdd_err("Invalid key length %d", params->key_len);
+
+		return -EINVAL;
+	}
+
+	if (CSR_MAX_RSC_LEN < params->seq_len) {
+		hdd_err("Invalid seq length %d", params->seq_len);
+
+		return -EINVAL;
+	}
+
+	hdd_debug("key index %d, key length %d, seq length %d",
+		  key_index, params->key_len, params->seq_len);
+
+	/*extract key idx, key len and key */
+	qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
+	setKey.keyId = key_index;
+	setKey.keyLength = params->key_len;
+	qdf_mem_copy(&setKey.Key[0], params->key, params->key_len);
+	qdf_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	switch (params->cipher) {
+	case WLAN_CIPHER_SUITE_WEP40:
+		setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
+		break;
+
+	case WLAN_CIPHER_SUITE_WEP104:
+		setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
+		break;
+
+	case WLAN_CIPHER_SUITE_TKIP:
+	{
+		u8 *pKey = &setKey.Key[0];
+
+		setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
+		qdf_mem_zero(pKey, CSR_MAX_KEY_LEN);
+
+		/* Supplicant sends the 32bytes key in this order
+		 *
+		 * |--------------|----------|----------|
+		 * |   Tk1        |TX-MIC    |  RX Mic  |
+		 * |--------------|----------|----------|
+		 * <---16bytes---><--8bytes--><--8bytes-->
+		 *
+		 * Sme expects the 32 bytes key to be in the below order
+		 *
+		 * |--------------|----------|----------|
+		 * |   Tk1        |RX-MIC    |  TX Mic  |
+		 * |--------------|----------|----------|
+		 * <---16bytes---><--8bytes--><--8bytes-->
+		 */
+		/* Copy the Temporal Key 1 (TK1) */
+		qdf_mem_copy(pKey, params->key, 16);
+
+		/*Copy the rx mic first */
+		qdf_mem_copy(&pKey[16], &params->key[24], 8);
+
+		/*Copy the tx mic */
+		qdf_mem_copy(&pKey[24], &params->key[16], 8);
+
+		break;
+	}
+
+	case WLAN_CIPHER_SUITE_CCMP:
+		setKey.encType = eCSR_ENCRYPT_TYPE_AES;
+		break;
+
+#ifdef FEATURE_WLAN_WAPI
+	case WLAN_CIPHER_SUITE_SMS4:
+	{
+		qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
+		wlan_hdd_cfg80211_set_key_wapi(adapter, key_index,
+					       mac_addr, params->key,
+					       params->key_len);
+		return 0;
+	}
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+	case WLAN_CIPHER_SUITE_KRK:
+		setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
+		break;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	case WLAN_CIPHER_SUITE_BTK:
+		setKey.encType = eCSR_ENCRYPT_TYPE_BTK;
+		break;
+#endif
+#endif
+
+#ifdef WLAN_FEATURE_11W
+	case WLAN_CIPHER_SUITE_AES_CMAC:
+		setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
+		break;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+		setKey.encType = eCSR_ENCRYPT_TYPE_AES_GMAC_128;
+		break;
+	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+		setKey.encType = eCSR_ENCRYPT_TYPE_AES_GMAC_256;
+		break;
+#endif
+#endif
+	case WLAN_CIPHER_SUITE_GCMP:
+		setKey.encType = eCSR_ENCRYPT_TYPE_AES_GCMP;
+		break;
+	case WLAN_CIPHER_SUITE_GCMP_256:
+		setKey.encType = eCSR_ENCRYPT_TYPE_AES_GCMP_256;
+		break;
+
+	default:
+		hdd_err("Unsupported cipher type: %u", params->cipher);
+		return -EOPNOTSUPP;
+	}
+
+	hdd_debug("encryption type %d", setKey.encType);
+
+	if (!pairwise) {
+		/* set group key */
+		hdd_debug("setting Broadcast key");
+		setKey.keyDirection = eSIR_RX_ONLY;
+		qdf_set_macaddr_broadcast(&setKey.peerMac);
+	} else {
+		/* set pairwise key */
+		hdd_debug("setting pairwise key");
+		setKey.keyDirection = eSIR_TX_RX;
+		qdf_mem_copy(setKey.peerMac.bytes, mac_addr, QDF_MAC_ADDR_SIZE);
+	}
+	if ((QDF_IBSS_MODE == adapter->device_mode) && !pairwise) {
+		/* if a key is already installed, block all subsequent ones */
+		if (adapter->session.station.ibss_enc_key_installed) {
+			hdd_debug("IBSS key installed already");
+			return 0;
+		}
+
+		setKey.keyDirection = eSIR_TX_RX;
+		/*Set the group key */
+		status = sme_roam_set_key(mac_handle,
+					  adapter->session_id, &setKey, &roamId);
+
+		if (0 != status) {
+			hdd_err("sme_roam_set_key failed, status: %d", status);
+			return -EINVAL;
+		}
+		/* Save the keys here and call sme_roam_set_key for setting
+		 * the PTK after peer joins the IBSS network
+		 */
+		qdf_mem_copy(&adapter->session.station.ibss_enc_key,
+			     &setKey, sizeof(tCsrRoamSetKey));
+
+		adapter->session.station.ibss_enc_key_installed = 1;
+		return status;
+	}
+	if ((adapter->device_mode == QDF_SAP_MODE) ||
+	    (adapter->device_mode == QDF_P2P_GO_MODE)) {
+		struct hdd_hostapd_state *hostapd_state =
+			WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+		struct hdd_ap_ctx *ap_ctx =
+			WLAN_HDD_GET_AP_CTX_PTR(adapter);
+
+		if (hostapd_state->bss_state == BSS_START) {
+			status = wlansap_set_key_sta(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter), &setKey);
+			if (status != QDF_STATUS_SUCCESS) {
+				hdd_err("wlansap_set_key_sta failed status: %d",
+					status);
+			}
+		}
+
+		/* Save the key in ap ctx for use on START_BSS and restart */
+		if (pairwise ||
+			eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
+			eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType)
+			qdf_mem_copy(&ap_ctx->wep_key[key_index], &setKey,
+				     sizeof(tCsrRoamSetKey));
+		else
+			qdf_mem_copy(&ap_ctx->group_key, &setKey,
+				     sizeof(tCsrRoamSetKey));
+
+	} else if ((adapter->device_mode == QDF_STA_MODE) ||
+		   (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
+		struct hdd_station_ctx *sta_ctx =
+			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		struct csr_roam_profile *roam_profile;
+
+		if (!pairwise) {
+			/* set group key */
+			if (sta_ctx->roam_info.defer_key_complete) {
+				hdd_debug("Perform Set key Complete");
+				hdd_perform_roam_set_key_complete(adapter);
+			}
+		}
+
+		roam_profile = hdd_roam_profile(adapter);
+		roam_profile->Keys.KeyLength[key_index] = params->key_len;
+
+		roam_profile->Keys.defaultIndex = key_index;
+
+		qdf_mem_copy(&roam_profile->Keys.KeyMaterial[key_index][0],
+			     params->key, params->key_len);
+
+		hdd_debug("Set key for peerMac "MAC_ADDRESS_STR" direction %d",
+		       MAC_ADDR_ARRAY(setKey.peerMac.bytes),
+		       setKey.keyDirection);
+
+		/* The supplicant may attempt to set the PTK once
+		 * pre-authentication is done. Save the key in the
+		 * UMAC and include it in the ADD BSS request
+		 */
+		qdf_ret_status = sme_ft_update_key(mac_handle,
+						   adapter->session_id, &setKey);
+		if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) {
+			hdd_debug("Update PreAuth Key success");
+			return 0;
+		} else if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) {
+			hdd_err("Update PreAuth Key failed");
+			return -EINVAL;
+		}
+
+		/* issue set key request to SME */
+		status = sme_roam_set_key(mac_handle,
+					  adapter->session_id, &setKey, &roamId);
+
+		if (0 != status) {
+			hdd_err("sme_roam_set_key failed, status: %d", status);
+			return -EINVAL;
+		}
+
+		if (adapter->send_mode_change) {
+			wlan_hdd_send_mode_change_event();
+			adapter->send_mode_change = false;
+		}
+
+		/* in case of IBSS as there was no information
+		 * available about WEP keys during IBSS join, group
+		 * key initialized with NULL key, so re-initialize
+		 * group key with correct value
+		 */
+		if ((eCSR_BSS_TYPE_START_IBSS == roam_profile->BSSType) &&
+		    !((HDD_AUTH_KEY_MGMT_802_1X ==
+		       (sta_ctx->auth_key_mgmt & HDD_AUTH_KEY_MGMT_802_1X))
+		      && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
+			  sta_ctx->conn_info.authType)
+		      )
+		    && ((WLAN_CIPHER_SUITE_WEP40 == params->cipher)
+			|| (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
+			)
+		    ) {
+			setKey.keyDirection = eSIR_RX_ONLY;
+			qdf_set_macaddr_broadcast(&setKey.peerMac);
+
+			hdd_debug("Set key peerMac "MAC_ADDRESS_STR" direction %d",
+			       MAC_ADDR_ARRAY(setKey.peerMac.bytes),
+			       setKey.keyDirection);
+
+			status = sme_roam_set_key(mac_handle,
+						  adapter->session_id, &setKey,
+						  &roamId);
+
+			if (0 != status) {
+				hdd_err("sme_roam_set_key failed for group key (IBSS), returned %d", status);
+				return -EINVAL;
+			}
+		}
+	}
+	hdd_exit();
+	return 0;
+}
+
+static int wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
+				     struct net_device *ndev,
+				     u8 key_index, bool pairwise,
+				     const u8 *mac_addr,
+				     struct key_params *params)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
+					  mac_addr, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/*
+ * FUNCTION: __wlan_hdd_cfg80211_get_key
+ * This function is used to get the key information
+ */
+static int __wlan_hdd_cfg80211_get_key(struct wiphy *wiphy,
+				       struct net_device *ndev,
+				       u8 key_index, bool pairwise,
+				       const u8 *mac_addr, void *cookie,
+				       void (*callback)(void *cookie,
+							struct key_params *)
+				       )
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	struct csr_roam_profile *roam_profile;
+	struct key_params params;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	hdd_debug("Device_mode %s(%d)",
+		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
+
+	memset(&params, 0, sizeof(params));
+
+	if (CSR_MAX_NUM_KEY <= key_index) {
+		hdd_err("Invalid key index: %d", key_index);
+		return -EINVAL;
+	}
+
+	if ((adapter->device_mode == QDF_SAP_MODE) ||
+	    (adapter->device_mode == QDF_P2P_GO_MODE)) {
+		struct hdd_ap_ctx *ap_ctx =
+			WLAN_HDD_GET_AP_CTX_PTR(adapter);
+
+		roam_profile =
+			wlan_sap_get_roam_profile(ap_ctx->sap_context);
+	} else {
+		roam_profile = hdd_roam_profile(adapter);
+	}
+
+	if (roam_profile == NULL) {
+		hdd_err("Get roam profile failed!");
+		return -EINVAL;
+	}
+
+	switch (roam_profile->EncryptionType.encryptionType[0]) {
+	case eCSR_ENCRYPT_TYPE_NONE:
+		params.cipher = IW_AUTH_CIPHER_NONE;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP40:
+		params.cipher = WLAN_CIPHER_SUITE_WEP40;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP104:
+		params.cipher = WLAN_CIPHER_SUITE_WEP104;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_TKIP:
+		params.cipher = WLAN_CIPHER_SUITE_TKIP;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_AES:
+		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP:
+		params.cipher = WLAN_CIPHER_SUITE_GCMP;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
+		params.cipher = WLAN_CIPHER_SUITE_GCMP_256;
+		break;
+	default:
+		params.cipher = IW_AUTH_CIPHER_NONE;
+		break;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_GET_KEY,
+			 adapter->session_id, params.cipher));
+
+	params.key_len = roam_profile->Keys.KeyLength[key_index];
+	params.seq_len = 0;
+	params.seq = NULL;
+	params.key = &roam_profile->Keys.KeyMaterial[key_index][0];
+	callback(cookie, &params);
+
+	hdd_exit();
+	return 0;
+}
+
+static int wlan_hdd_cfg80211_get_key(struct wiphy *wiphy,
+				     struct net_device *ndev,
+				     u8 key_index, bool pairwise,
+				     const u8 *mac_addr, void *cookie,
+				     void (*callback)(void *cookie,
+						      struct key_params *)
+				     )
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
+					  mac_addr, cookie, callback);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_del_key() - Delete the encryption key for station
+ * @wiphy: wiphy interface context
+ * @ndev: pointer to net device
+ * @key_index: Key index used in 802.11 frames
+ * @unicast: true if it is unicast key
+ * @multicast: true if it is multicast key
+ *
+ * This function is required for cfg80211_ops API.
+ * It is used to delete the key information
+ * Underlying hardware implementation does not have API to delete the
+ * encryption key. It is automatically deleted when the peer is
+ * removed. Hence this function currently does nothing.
+ * Future implementation may interprete delete key operation to
+ * replacing the key with a random junk value, effectively making it
+ * useless.
+ *
+ * Return: status code, always 0.
+ */
+
+static int __wlan_hdd_cfg80211_del_key(struct wiphy *wiphy,
+				     struct net_device *ndev,
+				     u8 key_index,
+				     bool pairwise, const u8 *mac_addr)
+{
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_del_key() - cfg80211 delete key handler function
+ * @wiphy: Pointer to wiphy structure.
+ * @dev: Pointer to net_device structure.
+ * @key_index: key index
+ * @pairwise: pairwise
+ * @mac_addr: mac address
+ *
+ * This is the cfg80211 delete key handler function which invokes
+ * the internal function @__wlan_hdd_cfg80211_del_key with
+ * SSR protection.
+ *
+ * Return: 0 for success, error number on failure.
+ */
+static int wlan_hdd_cfg80211_del_key(struct wiphy *wiphy,
+					struct net_device *dev,
+					u8 key_index,
+					bool pairwise, const u8 *mac_addr)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_del_key(wiphy, dev, key_index,
+					  pairwise, mac_addr);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+static bool hdd_is_wapi_enc_type(eCsrEncryptionType ucEncryptionType)
+{
+	if (ucEncryptionType == eCSR_ENCRYPT_TYPE_WPI)
+		return true;
+
+	return false;
+}
+#else
+static bool hdd_is_wapi_enc_type(eCsrEncryptionType ucEncryptionType)
+{
+	return false;
+}
+#endif
+
+/*
+ * FUNCTION: __wlan_hdd_cfg80211_set_default_key
+ * This function is used to set the default tx key index
+ */
+static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy,
+					       struct net_device *ndev,
+					       u8 key_index,
+					       bool unicast, bool multicast)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	struct hdd_context *hdd_ctx;
+	mac_handle_t mac_handle;
+	int status;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
+			 adapter->session_id, key_index));
+
+	hdd_debug("Device_mode %s(%d) key_index = %d",
+		  qdf_opmode_str(adapter->device_mode),
+		  adapter->device_mode, key_index);
+
+	if (CSR_MAX_NUM_KEY <= key_index) {
+		hdd_err("Invalid key index: %d", key_index);
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	if ((adapter->device_mode == QDF_STA_MODE) ||
+	    (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
+		struct hdd_station_ctx *sta_ctx =
+			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		struct csr_roam_profile *roam_profile;
+
+		roam_profile = hdd_roam_profile(adapter);
+
+		if ((eCSR_ENCRYPT_TYPE_TKIP !=
+		     sta_ctx->conn_info.ucEncryptionType) &&
+		    !hdd_is_wapi_enc_type(
+		     sta_ctx->conn_info.ucEncryptionType) &&
+		    (eCSR_ENCRYPT_TYPE_AES !=
+		     sta_ctx->conn_info.ucEncryptionType) &&
+		    (eCSR_ENCRYPT_TYPE_AES_GCMP !=
+			sta_ctx->conn_info.ucEncryptionType) &&
+		    (eCSR_ENCRYPT_TYPE_AES_GCMP_256 !=
+		     sta_ctx->conn_info.ucEncryptionType)) {
+			/* If default key index is not same as previous one,
+			 * then update the default key index
+			 */
+
+			tCsrRoamSetKey setKey;
+			uint32_t roamId = INVALID_ROAM_ID;
+			tCsrKeys *Keys = &roam_profile->Keys;
+
+			hdd_debug("Default tx key index %d", key_index);
+
+			Keys->defaultIndex = (u8) key_index;
+			qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
+			setKey.keyId = key_index;
+			setKey.keyLength = Keys->KeyLength[key_index];
+
+			qdf_mem_copy(&setKey.Key[0],
+				     &Keys->KeyMaterial[key_index][0],
+				     Keys->KeyLength[key_index]);
+
+			setKey.keyDirection = eSIR_TX_RX;
+
+			qdf_copy_macaddr(&setKey.peerMac,
+					 &sta_ctx->conn_info.bssId);
+
+			if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
+			    roam_profile->EncryptionType.
+			    encryptionType[0] == eCSR_ENCRYPT_TYPE_WEP104) {
+				/* In the case of dynamic wep
+				 * supplicant hardcodes DWEP type to
+				 * eCSR_ENCRYPT_TYPE_WEP104 even
+				 * though ap is configured for WEP-40
+				 * encryption. In this canse the key
+				 * length is 5 but the encryption type
+				 * is 104 hence checking the key
+				 * length(5) and encryption type(104)
+				 * and switching encryption type to 40
+				 */
+				roam_profile->EncryptionType.
+				encryptionType[0] = eCSR_ENCRYPT_TYPE_WEP40;
+				roam_profile->mcEncryptionType.
+				encryptionType[0] = eCSR_ENCRYPT_TYPE_WEP40;
+			}
+
+			setKey.encType =
+				roam_profile->EncryptionType.
+				encryptionType[0];
+
+			/* Issue set key request */
+			status = sme_roam_set_key(mac_handle,
+						  adapter->session_id, &setKey,
+						  &roamId);
+
+			if (0 != status) {
+				hdd_err("sme_roam_set_key failed, status: %d",
+				       status);
+				return -EINVAL;
+			}
+		}
+	} else if (QDF_SAP_MODE == adapter->device_mode) {
+		struct hdd_ap_ctx *ap_ctx =
+			WLAN_HDD_GET_AP_CTX_PTR(adapter);
+		struct csr_roam_profile *profile =
+			wlan_sap_get_roam_profile(ap_ctx->sap_context);
+
+		if (!profile) {
+			hdd_err("Failed to get SAP Roam Profile");
+			return -EINVAL;
+		}
+		/* In SoftAp mode setting key direction for default mode */
+		if ((eCSR_ENCRYPT_TYPE_TKIP !=
+		    profile->EncryptionType.encryptionType[0]) &&
+		    (eCSR_ENCRYPT_TYPE_AES !=
+		    profile->EncryptionType.encryptionType[0]) &&
+		    (eCSR_ENCRYPT_TYPE_AES_GCMP !=
+		    profile->EncryptionType.encryptionType[0]) &&
+		    (eCSR_ENCRYPT_TYPE_AES_GCMP_256 !=
+		    profile->EncryptionType.encryptionType[0])) {
+			/* Saving key direction for default key index to TX default */
+			ap_ctx->wep_key[key_index].keyDirection =
+				eSIR_TX_DEFAULT;
+			hdd_debug("WEP default key index set to SAP context %d",
+				key_index);
+			ap_ctx->wep_def_key_idx = key_index;
+		}
+	}
+
+	hdd_exit();
+	return status;
+}
+
+static int wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy,
+					     struct net_device *ndev,
+					     u8 key_index,
+					     bool unicast, bool multicast)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret =
+		__wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
+						    multicast);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/*
+ * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
+ * interface that BSS might have been lost.
+ * @adapter: adaptor
+ * @bssid: bssid which might have been lost
+ *
+ * Return: bss which is unlinked from kernel cache
+ */
+struct cfg80211_bss *wlan_hdd_cfg80211_update_bss_list(
+	struct hdd_adapter *adapter, tSirMacAddr bssid)
+{
+	struct net_device *dev = adapter->dev;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_bss *bss = NULL;
+
+	bss = hdd_cfg80211_get_bss(wiphy, NULL, bssid,
+			NULL, 0);
+	if (bss == NULL) {
+		hdd_err("BSS not present");
+	} else {
+		hdd_debug("cfg80211_unlink_bss called for BSSID "
+			MAC_ADDRESS_STR, MAC_ADDR_ARRAY(bssid));
+		cfg80211_unlink_bss(wiphy, bss);
+	}
+	return bss;
+}
+
+#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
+static inline int
+wlan_hdd_get_frame_len(struct bss_description *bss_desc)
+{
+	return GET_IE_LEN_IN_BSS(bss_desc->length) + sizeof(qcom_ie_age);
+}
+
+static inline void wlan_hdd_add_age_ie(struct ieee80211_mgmt *mgmt,
+	uint32_t *ie_length, struct bss_description *bss_desc)
+{
+	qcom_ie_age *qie_age = NULL;
+
+	/*
+	 * GPS Requirement: need age ie per entry. Using vendor specific.
+	 * Assuming this is the last IE, copy at the end
+	 */
+	*ie_length -= sizeof(qcom_ie_age);
+	qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + *ie_length);
+	qie_age->element_id = QCOM_VENDOR_IE_ID;
+	qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
+	qie_age->oui_1 = QCOM_OUI1;
+	qie_age->oui_2 = QCOM_OUI2;
+	qie_age->oui_3 = QCOM_OUI3;
+	qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
+	/*
+	 * Lowi expects the timestamp of bss in units of 1/10 ms. In driver
+	 * all bss related timestamp is in units of ms. Due to this when scan
+	 * results are sent to lowi the scan age is high.To address this,
+	 * send age in units of 1/10 ms.
+	 */
+	qie_age->age = (uint32_t)(qdf_mc_timer_get_system_time() -
+				  bss_desc->received_time)/10;
+	qie_age->tsf_delta = bss_desc->tsf_delta;
+	memcpy(&qie_age->beacon_tsf, bss_desc->timeStamp,
+	       sizeof(qie_age->beacon_tsf));
+	memcpy(&qie_age->seq_ctrl, &bss_desc->seq_ctrl,
+	       sizeof(qie_age->seq_ctrl));
+}
+#else
+static inline int
+wlan_hdd_get_frame_len(struct bss_description *bss_desc)
+{
+	return GET_IE_LEN_IN_BSS(bss_desc->length);
+}
+static inline void wlan_hdd_add_age_ie(struct ieee80211_mgmt *mgmt,
+	uint32_t *ie_length, struct bss_description *bss_desc)
+{
+}
+#endif /* WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS */
+
+
+struct cfg80211_bss *
+wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter,
+				     struct bss_description *bss_desc)
+{
+	struct wireless_dev *wdev = adapter->dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
+	uint32_t ie_length = wlan_hdd_get_frame_len(bss_desc);
+	const char *ie =
+		((ie_length != 0) ? (const char *)&bss_desc->ieFields : NULL);
+	uint32_t freq, i;
+	struct cfg80211_bss *bss_status = NULL;
+	struct hdd_context *hdd_ctx;
+	struct timespec ts;
+	struct hdd_config *cfg_param;
+	struct wlan_cfg80211_inform_bss bss_data = {0};
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	/*
+	 * wlan_hdd_validate_context should not be used here, In validate ctx
+	 * start_modules_in_progress or stop_modules_in_progress is validated,
+	 * If the start_modules_in_progress is set to true means the interface
+	 * is not UP yet if the stop_modules_in_progress means that interface
+	 * is already down. So in both the two scenario's driver should not be
+	 * informing bss to kernel. Hence removing the validate context.
+	 */
+
+	if (!hdd_ctx || !hdd_ctx->config) {
+		hdd_debug("HDD context is Null");
+		return NULL;
+	}
+
+	if (cds_is_driver_recovering() ||
+	    cds_is_load_or_unload_in_progress()) {
+		hdd_debug("Recovery or load/unload in progress. State: 0x%x",
+			  cds_get_driver_state());
+		return NULL;
+	}
+
+	cfg_param = hdd_ctx->config;
+	bss_data.frame_len = ie_length + offsetof(struct ieee80211_mgmt,
+						  u.probe_resp.variable);
+	bss_data.mgmt = qdf_mem_malloc(bss_data.frame_len);
+	if (!bss_data.mgmt)
+		return NULL;
+
+	memcpy(bss_data.mgmt->bssid, bss_desc->bssId, ETH_ALEN);
+
+	/* Android does not want the timestamp from the frame.
+	 * Instead it wants a monotonic increasing value
+	 */
+	get_monotonic_boottime(&ts);
+	bss_data.mgmt->u.probe_resp.timestamp =
+		((u64) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
+
+	bss_data.mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
+	bss_data.mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
+
+	wlan_hdd_add_age_ie(bss_data.mgmt, &ie_length, bss_desc);
+
+	memcpy(bss_data.mgmt->u.probe_resp.variable, ie, ie_length);
+	if (bss_desc->fProbeRsp) {
+		bss_data.mgmt->frame_control |=
+			(u16) (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
+	} else {
+		bss_data.mgmt->frame_control |=
+			(u16) (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
+	}
+
+	if (bss_desc->channelId <= ARRAY_SIZE(hdd_channels_2_4_ghz) &&
+	    (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL)) {
+		freq =
+			ieee80211_channel_to_frequency(bss_desc->channelId,
+						       HDD_NL80211_BAND_2GHZ);
+	} else if ((bss_desc->channelId > ARRAY_SIZE(hdd_channels_2_4_ghz))
+		   && (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL)) {
+		freq =
+			ieee80211_channel_to_frequency(bss_desc->channelId,
+						       HDD_NL80211_BAND_5GHZ);
+	} else {
+		hdd_err("Invalid channel: %d", bss_desc->channelId);
+		qdf_mem_free(bss_data.mgmt);
+		return NULL;
+	}
+
+	bss_data.chan = ieee80211_get_channel(wiphy, freq);
+	if (!bss_data.chan) {
+		hdd_err("chan pointer is NULL, chan_no: %d freq: %d",
+			bss_desc->channelId, freq);
+		qdf_mem_free(bss_data.mgmt);
+		return NULL;
+	}
+
+	/*
+	 * Based on .ini configuration, raw rssi can be reported for bss.
+	 * Raw rssi is typically used for estimating power.
+	 */
+	bss_data.rssi = (cfg_param->inform_bss_rssi_raw) ? bss_desc->rssi_raw :
+			bss_desc->rssi;
+
+	/* Supplicant takes the signal strength in terms of mBm(100*dBm) */
+	bss_data.rssi = QDF_MIN(bss_data.rssi, 0) * 100;
+
+	bss_data.boottime_ns = bss_desc->scansystimensec;
+
+	/* Set all per chain rssi as invalid */
+	for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++)
+		bss_data.per_chain_snr[i] = WLAN_INVALID_PER_CHAIN_RSSI;
+
+	hdd_debug("BSSID: " MAC_ADDRESS_STR " Channel:%d RSSI:%d TSF %u",
+	       MAC_ADDR_ARRAY(bss_data.mgmt->bssid), bss_data.chan->center_freq,
+	       (int)(bss_data.rssi / 100),
+	       bss_desc->timeStamp[0]);
+
+	bss_status = wlan_cfg80211_inform_bss_frame_data(wiphy, &bss_data);
+	hdd_ctx->beacon_probe_rsp_cnt_per_scan++;
+	qdf_mem_free(bss_data.mgmt);
+	return bss_status;
+}
+
+/**
+ * wlan_hdd_cfg80211_update_bss_db() - update bss database of CF80211
+ * @adapter: Pointer to adapter
+ * @roam_info: Pointer to roam info
+ *
+ * This function is used to update the BSS data base of CFG8011
+ *
+ * Return: struct cfg80211_bss pointer
+ */
+struct cfg80211_bss *
+wlan_hdd_cfg80211_update_bss_db(struct hdd_adapter *adapter,
+				struct csr_roam_info *roam_info)
+{
+	tCsrRoamConnectedProfile roamProfile;
+	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
+	struct cfg80211_bss *bss = NULL;
+
+	memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
+	sme_roam_get_connect_profile(mac_handle, adapter->session_id,
+				     &roamProfile);
+
+	if (NULL != roamProfile.pBssDesc) {
+		bss = wlan_hdd_inform_bss_frame(adapter, roamProfile.pBssDesc);
+
+		if (NULL == bss)
+			hdd_debug("wlan_hdd_inform_bss_frame returned NULL");
+
+		sme_roam_free_connect_profile(&roamProfile);
+	} else {
+		hdd_err("roamProfile.pBssDesc is NULL");
+	}
+	return bss;
+}
+
+/**
+ * wlan_hdd_cfg80211_pmksa_candidate_notify() - notify a new PMSKA candidate
+ * @adapter: Pointer to adapter
+ * @roam_info: Pointer to roam info
+ * @index: Index
+ * @preauth: Preauth flag
+ *
+ * This function is used to notify the supplicant of a new PMKSA candidate.
+ * PMK value is notified to supplicant whether PMK caching or OKC is enabled
+ * in firmware or not. Supplicant needs this value becaue it uses PMK caching
+ * by default.
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_pmksa_candidate_notify(struct hdd_adapter *adapter,
+					     struct csr_roam_info *roam_info,
+					     int index, bool preauth)
+{
+	struct net_device *dev = adapter->dev;
+
+	hdd_enter();
+	hdd_debug("is going to notify supplicant of:");
+
+	if (NULL == roam_info) {
+		hdd_err("roam_info is NULL");
+		return -EINVAL;
+	}
+
+	hdd_info(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(roam_info->bssid.bytes));
+	cfg80211_pmksa_candidate_notify(dev, index,
+					roam_info->bssid.bytes,
+					preauth, GFP_KERNEL);
+	return 0;
+}
+
+#ifdef FEATURE_WLAN_LFR_METRICS
+/**
+ * wlan_hdd_cfg80211_roam_metrics_preauth() - roam metrics preauth
+ * @adapter: Pointer to adapter
+ * @roam_info: Pointer to roam info
+ *
+ * 802.11r/LFR metrics reporting function to report preauth initiation
+ *
+ * Return: QDF status
+ */
+#define MAX_LFR_METRICS_EVENT_LENGTH 100
+QDF_STATUS
+wlan_hdd_cfg80211_roam_metrics_preauth(struct hdd_adapter *adapter,
+				       struct csr_roam_info *roam_info)
+{
+	unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
+	union iwreq_data wrqu;
+
+	hdd_enter();
+
+	if (NULL == adapter) {
+		hdd_err("adapter is NULL!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* create the event */
+	memset(&wrqu, 0, sizeof(wrqu));
+	memset(metrics_notification, 0, sizeof(metrics_notification));
+
+	wrqu.data.pointer = metrics_notification;
+	wrqu.data.length = scnprintf(metrics_notification,
+				     sizeof(metrics_notification),
+				     "QCOM: LFR_PREAUTH_INIT " MAC_ADDRESS_STR,
+				     MAC_ADDR_ARRAY(roam_info->bssid.bytes));
+
+	wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu,
+			    metrics_notification);
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_hdd_cfg80211_roam_metrics_handover() - roam metrics hand over
+ * @adapter: Pointer to adapter
+ * @roam_info: Pointer to roam info
+ * @preauth_status: Preauth status
+ *
+ * 802.11r/LFR metrics reporting function to report handover initiation
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+wlan_hdd_cfg80211_roam_metrics_preauth_status(struct hdd_adapter *adapter,
+					      struct csr_roam_info *roam_info,
+					      bool preauth_status)
+{
+	unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
+	union iwreq_data wrqu;
+
+	hdd_enter();
+
+	if (NULL == adapter) {
+		hdd_err("adapter is NULL!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* create the event */
+	memset(&wrqu, 0, sizeof(wrqu));
+	memset(metrics_notification, 0, sizeof(metrics_notification));
+
+	scnprintf(metrics_notification, sizeof(metrics_notification),
+		  "QCOM: LFR_PREAUTH_STATUS " MAC_ADDRESS_STR,
+		  MAC_ADDR_ARRAY(roam_info->bssid.bytes));
+
+	if (1 == preauth_status)
+		strlcat(metrics_notification, " true",
+				sizeof(metrics_notification));
+	else
+		strlcat(metrics_notification, " false",
+				sizeof(metrics_notification));
+
+	wrqu.data.pointer = metrics_notification;
+	wrqu.data.length = strlen(metrics_notification);
+
+	wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu,
+			    metrics_notification);
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_hdd_cfg80211_roam_metrics_handover() - roam metrics hand over
+ * @adapter: Pointer to adapter
+ * @roam_info: Pointer to roam info
+ *
+ * 802.11r/LFR metrics reporting function to report handover initiation
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+wlan_hdd_cfg80211_roam_metrics_handover(struct hdd_adapter *adapter,
+					struct csr_roam_info *roam_info)
+{
+	unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
+	union iwreq_data wrqu;
+
+	hdd_enter();
+
+	if (NULL == adapter) {
+		hdd_err("adapter is NULL!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* create the event */
+	memset(&wrqu, 0, sizeof(wrqu));
+	memset(metrics_notification, 0, sizeof(metrics_notification));
+
+	wrqu.data.pointer = metrics_notification;
+	wrqu.data.length = scnprintf(metrics_notification,
+				     sizeof(metrics_notification),
+				     "QCOM: LFR_PREAUTH_HANDOVER "
+				     MAC_ADDRESS_STR,
+				     MAC_ADDR_ARRAY(roam_info->bssid.bytes));
+
+	wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu,
+			    metrics_notification);
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+static
+void hdd_mon_select_cbmode(struct hdd_adapter *adapter,
+			   uint8_t operationChannel,
+			   struct ch_params *ch_params)
+{
+	struct hdd_station_ctx *station_ctx =
+			 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct hdd_mon_set_ch_info *ch_info = &station_ctx->ch_info;
+	enum hdd_dot11_mode hdd_dot11_mode;
+	uint8_t ini_dot11_mode =
+			(WLAN_HDD_GET_CTX(adapter))->config->dot11Mode;
+
+	hdd_debug("Dot11Mode is %u", ini_dot11_mode);
+	switch (ini_dot11_mode) {
+	case eHDD_DOT11_MODE_AUTO:
+	case eHDD_DOT11_MODE_11ax:
+	case eHDD_DOT11_MODE_11ax_ONLY:
+		if (sme_is_feature_supported_by_fw(DOT11AX))
+			hdd_dot11_mode = eHDD_DOT11_MODE_11ax;
+		else if (sme_is_feature_supported_by_fw(DOT11AC))
+			hdd_dot11_mode = eHDD_DOT11_MODE_11ac;
+		else
+			hdd_dot11_mode = eHDD_DOT11_MODE_11n;
+		break;
+	case eHDD_DOT11_MODE_11ac:
+	case eHDD_DOT11_MODE_11ac_ONLY:
+		if (sme_is_feature_supported_by_fw(DOT11AC))
+			hdd_dot11_mode = eHDD_DOT11_MODE_11ac;
+		else
+			hdd_dot11_mode = eHDD_DOT11_MODE_11n;
+		break;
+	case eHDD_DOT11_MODE_11n:
+	case eHDD_DOT11_MODE_11n_ONLY:
+		hdd_dot11_mode = eHDD_DOT11_MODE_11n;
+		break;
+	default:
+		hdd_dot11_mode = ini_dot11_mode;
+		break;
+	}
+	ch_info->channel_width = ch_params->ch_width;
+	ch_info->phy_mode =
+		hdd_cfg_xlate_to_csr_phy_mode(hdd_dot11_mode);
+	ch_info->channel = operationChannel;
+	ch_info->cb_mode = ch_params->ch_width;
+	hdd_debug("ch_info width %d, phymode %d channel %d",
+		  ch_info->channel_width, ch_info->phy_mode,
+		  ch_info->channel);
+}
+#else
+static
+void hdd_mon_select_cbmode(struct hdd_adapter *adapter,
+			   uint8_t operationChannel,
+			   struct ch_params *ch_params)
+{
+}
+#endif
+
+/**
+ * hdd_select_cbmode() - select channel bonding mode
+ * @adapter: Pointer to adapter
+ * @operatingChannel: Operating channel
+ * @ch_params: channel info struct to populate
+ *
+ * Return: none
+ */
+void hdd_select_cbmode(struct hdd_adapter *adapter, uint8_t operationChannel,
+			struct ch_params *ch_params)
+{
+	uint8_t sec_ch = 0;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_station_ctx *station_ctx =
+				 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	eConnectionState connstate;
+	bool cbmode_select = false;
+
+	/*
+	 * CDS api expects secondary channel for calculating
+	 * the channel params
+	 */
+	if ((ch_params->ch_width == CH_WIDTH_40MHZ) &&
+	    (WLAN_REG_IS_24GHZ_CH(operationChannel))) {
+		if (operationChannel >= 1 && operationChannel <= 5)
+			sec_ch = operationChannel + 4;
+		else if (operationChannel >= 6 && operationChannel <= 13)
+			sec_ch = operationChannel - 4;
+	}
+
+	/* This call decides required channel bonding mode */
+	wlan_reg_set_channel_params(hdd_ctx->pdev, operationChannel,
+				    sec_ch, ch_params);
+
+	if (adapter->device_mode == QDF_STA_MODE &&
+	    hdd_ctx->config->enable_change_channel_bandwidth) {
+		connstate = station_ctx->conn_info.connState;
+		if (!(eConnectionState_Associated == connstate ||
+		      eConnectionState_Connecting == connstate)) {
+			cbmode_select = true;
+		}
+	}
+
+	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE || cbmode_select)
+		hdd_mon_select_cbmode(adapter, operationChannel, ch_params);
+}
+
+/**
+ * wlan_hdd_handle_sap_sta_dfs_conc() - to handle SAP STA DFS conc
+ * @adapter: STA adapter
+ * @roam_profile: STA roam profile
+ *
+ * This routine will move SAP from dfs to non-dfs, if sta is coming up.
+ *
+ * Return: false if sta-sap conc is not allowed, else return true
+ */
+static
+bool wlan_hdd_handle_sap_sta_dfs_conc(struct hdd_adapter *adapter,
+				      struct csr_roam_profile *roam_profile)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *ap_adapter;
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	struct hdd_hostapd_state *hostapd_state;
+	uint8_t channel = 0;
+	QDF_STATUS status;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return true;
+	}
+
+	ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
+	/* probably no sap running, no handling required */
+	if (ap_adapter == NULL)
+		return true;
+
+	/*
+	 * sap is not in started state, so it is fine to go ahead with sta.
+	 * if sap is currently doing CAC then don't allow sta to go further.
+	 */
+	if (!test_bit(SOFTAP_BSS_STARTED, &(ap_adapter)->event_flags) &&
+	    (hdd_ctx->dev_dfs_cac_status != DFS_CAC_IN_PROGRESS))
+		return true;
+
+	if (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS) {
+		hdd_err("Concurrent SAP is in CAC state, STA is not allowed");
+		return false;
+	}
+
+	/*
+	 * log and return error, if we allow STA to go through, we don't
+	 * know what is going to happen better stop sta connection
+	 */
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
+	if (NULL == hdd_ap_ctx) {
+		hdd_err("AP context not found");
+		return false;
+	}
+
+	/* sap is on non-dfs channel, nothing to handle */
+	if (!wlan_reg_is_dfs_ch(hdd_ctx->pdev,
+				hdd_ap_ctx->operating_channel)) {
+		hdd_info("sap is on non-dfs channel, sta is allowed");
+		return true;
+	}
+	/*
+	 * find out by looking in to scan cache where sta is going to
+	 * connect by passing its roam_profile.
+	 */
+	status = policy_mgr_get_channel_from_scan_result(hdd_ctx->psoc,
+			roam_profile, &channel);
+
+	/*
+	 * If the STA's channel is 2.4 GHz, then set pcl with only 2.4 GHz
+	 * channels for roaming case.
+	 */
+	if (WLAN_REG_IS_24GHZ_CH(channel)) {
+		hdd_info("sap is on dfs, new sta conn on 2.4 is allowed");
+		return true;
+	}
+
+	/*
+	 * If channel is 0 or DFS or LTE unsafe then better to call pcl and
+	 * find out the best channel. If channel is non-dfs 5 GHz then
+	 * better move SAP to STA's channel to make scc, so we have room
+	 * for 3port MCC scenario.
+	 */
+	if (!channel || wlan_reg_is_dfs_ch(hdd_ctx->pdev, channel) ||
+	    !policy_mgr_is_safe_channel(hdd_ctx->psoc, channel))
+		channel = policy_mgr_get_nondfs_preferred_channel(
+			hdd_ctx->psoc, PM_SAP_MODE, true);
+
+	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
+	qdf_event_reset(&hostapd_state->qdf_event);
+	status = wlansap_set_channel_change_with_csa(
+			WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter), channel,
+			hdd_ap_ctx->sap_config.ch_width_orig, false);
+
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Set channel with CSA IE failed, can't allow STA");
+		return false;
+	}
+
+	/*
+	 * wait here for SAP to finish the channel switch. When channel
+	 * switch happens, SAP sends few beacons with CSA_IE. After
+	 * successfully Transmission of those beacons, it will move its
+	 * state from started to disconnected and move to new channel.
+	 * once it moves to new channel, sap again moves its state
+	 * machine from disconnected to started and set this event.
+	 * wait for 10 secs to finish this.
+	 */
+	status = qdf_wait_for_event_completion(&hostapd_state->qdf_event, 10000);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("wait for qdf_event failed, STA not allowed!!");
+		return false;
+	}
+
+	return true;
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * wlan_hdd_cfg80211_check_pmf_valid() - check if pmf status is ok
+ * @roam_profile: pointer to roam profile
+ *
+ * if MFPEnabled is set but the peer AP is non-PMF i.e 80211w=2
+ * or pmf=2 is an explicit configuration in the supplicant
+ * configuration, drop the connection request.
+ *
+ * Return: 0 if check result is valid, otherwise return error code
+ */
+static
+int wlan_hdd_cfg80211_check_pmf_valid(struct csr_roam_profile *roam_profile)
+{
+	if (roam_profile->MFPEnabled &&
+	    !(roam_profile->MFPRequired || roam_profile->MFPCapable)) {
+		hdd_err("Drop connect req as supplicant has indicated PMF required for the non-PMF peer. MFPEnabled %d MFPRequired %d MFPCapable %d",
+				roam_profile->MFPEnabled,
+				roam_profile->MFPRequired,
+				roam_profile->MFPCapable);
+		return -EINVAL;
+	}
+	return 0;
+}
+#else
+static inline
+int wlan_hdd_cfg80211_check_pmf_valid(struct csr_roam_profile *roam_profile)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wlan_hdd_cfg80211_connect_start() - to start the association process
+ * @adapter: Pointer to adapter
+ * @ssid: Pointer to ssid
+ * @ssid_len: Length of ssid
+ * @bssid: Pointer to bssid
+ * @bssid_hint: Pointer to bssid hint
+ * @operatingChannel: Operating channel
+ * @ch_width: channel width. this is needed only for IBSS
+ *
+ * This function is used to start the association process
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter,
+				    const u8 *ssid, size_t ssid_len,
+				    const u8 *bssid, const u8 *bssid_hint,
+				    u8 operatingChannel,
+				    enum nl80211_chan_width ch_width)
+{
+	int status = 0;
+	QDF_STATUS qdf_status;
+	struct hdd_context *hdd_ctx;
+	struct hdd_station_ctx *hdd_sta_ctx;
+	uint32_t roamId = INVALID_ROAM_ID;
+	struct csr_roam_profile *roam_profile;
+	eCsrAuthType RSNAuthType;
+	tSmeConfigParams *sme_config;
+	uint8_t channel = 0;
+	mac_handle_t mac_handle;
+	uint8_t wmm_mode = 0;
+	uint8_t value = 0;
+
+	hdd_enter();
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		goto ret_status;
+
+	if (SIR_MAC_MAX_SSID_LENGTH < ssid_len) {
+		hdd_err("wrong SSID len");
+		status = -EINVAL;
+		goto ret_status;
+	}
+
+	if (true == hdd_is_connection_in_progress(NULL, NULL)) {
+		hdd_err("Connection refused: conn in progress");
+		status = -EINVAL;
+		goto ret_status;
+	}
+
+	/* Disable roaming on all other adapters before connect start */
+	wlan_hdd_disable_roaming(adapter);
+
+	hdd_notify_teardown_tdls_links(adapter->vdev);
+
+	qdf_mem_zero(&hdd_sta_ctx->conn_info.conn_flag,
+		     sizeof(hdd_sta_ctx->conn_info.conn_flag));
+
+	roam_profile = hdd_roam_profile(adapter);
+	if (roam_profile) {
+		struct hdd_station_ctx *sta_ctx;
+
+		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+		/* Restart the opportunistic timer
+		 *
+		 * If hw_mode_change_in_progress is true, then wait
+		 * till firmware sends the callback for hw_mode change.
+		 *
+		 * Else set connect_in_progress as true and proceed.
+		 */
+		policy_mgr_restart_opportunistic_timer(
+			hdd_ctx->psoc, false);
+		if (policy_mgr_is_hw_mode_change_in_progress(
+			hdd_ctx->psoc)) {
+			qdf_status = policy_mgr_wait_for_connection_update(
+				hdd_ctx->psoc);
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+				hdd_err("qdf wait for event failed!!");
+				status = -EINVAL;
+				goto ret_status;
+			}
+		}
+		hdd_set_connection_in_progress(true);
+
+		status = ucfg_mlme_get_wmm_mode(hdd_ctx->psoc, &wmm_mode);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get wmm_mode failed");
+			status = -EINVAL;
+			goto ret_status;
+		}
+		if (HDD_WMM_USER_MODE_NO_QOS == wmm_mode) {
+			/*QoS not enabled in cfg file */
+			roam_profile->uapsd_mask = 0;
+		} else {
+			/*QoS enabled, update uapsd mask from cfg file */
+			status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
+							      &value);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				hdd_err("Get uapsd_mask failed");
+				status = -EINVAL;
+				goto ret_status;
+			}
+			roam_profile->uapsd_mask = value;
+		}
+
+		roam_profile->SSIDs.numOfSSIDs = 1;
+		roam_profile->SSIDs.SSIDList->SSID.length = ssid_len;
+		qdf_mem_zero(roam_profile->SSIDs.SSIDList->SSID.ssId,
+			     sizeof(roam_profile->SSIDs.SSIDList->SSID.ssId));
+		qdf_mem_copy((void *)(roam_profile->SSIDs.SSIDList->SSID.ssId),
+			     ssid, ssid_len);
+
+		roam_profile->supplicant_disabled_roaming = false;
+
+		/* cleanup bssid hint */
+		qdf_mem_zero(roam_profile->bssid_hint.bytes,
+			QDF_MAC_ADDR_SIZE);
+		qdf_mem_zero((void *)(roam_profile->BSSIDs.bssid),
+			QDF_MAC_ADDR_SIZE);
+
+		if (bssid) {
+			roam_profile->BSSIDs.numOfBSSIDs = 1;
+			roam_profile->supplicant_disabled_roaming = true;
+			qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
+				     bssid, QDF_MAC_ADDR_SIZE);
+			/*
+			 * Save BSSID in separate variable as
+			 * roam_profile's BSSID is getting zeroed out in the
+			 * association process. In case of join failure
+			 * we should send valid BSSID to supplicant
+			 */
+			qdf_mem_copy(sta_ctx->requested_bssid.bytes,
+				     bssid, QDF_MAC_ADDR_SIZE);
+			hdd_debug("bssid is given by upper layer %pM", bssid);
+		} else if (bssid_hint) {
+			qdf_mem_copy(roam_profile->bssid_hint.bytes,
+				bssid_hint, QDF_MAC_ADDR_SIZE);
+			/*
+			 * Save BSSID in a separate variable as
+			 * roam_profile's BSSID is getting zeroed out in the
+			 * association process. In case of join failure
+			 * we should send valid BSSID to supplicant
+			 */
+			qdf_mem_copy(sta_ctx->requested_bssid.bytes,
+					bssid_hint, QDF_MAC_ADDR_SIZE);
+			hdd_debug("bssid_hint is given by upper layer %pM",
+					bssid_hint);
+		}
+
+		hdd_debug("Connect to SSID: %.*s operating Channel: %u",
+		       roam_profile->SSIDs.SSIDList->SSID.length,
+		       roam_profile->SSIDs.SSIDList->SSID.ssId,
+		       operatingChannel);
+
+		if (hdd_sta_ctx->wpa_versions) {
+			hdd_set_genie_to_csr(adapter, &RSNAuthType);
+			hdd_set_csr_auth_type(adapter, RSNAuthType);
+		}
+#ifdef FEATURE_WLAN_WAPI
+		if (adapter->wapi_info.wapi_mode) {
+			hdd_debug("Setting WAPI AUTH Type and Encryption Mode values");
+			switch (adapter->wapi_info.wapi_auth_mode) {
+			case WAPI_AUTH_MODE_PSK:
+			{
+				hdd_debug("WAPI AUTH TYPE: PSK: %d",
+				       adapter->wapi_info.wapi_auth_mode);
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_WAPI_WAI_PSK;
+				break;
+			}
+			case WAPI_AUTH_MODE_CERT:
+			{
+				hdd_debug("WAPI AUTH TYPE: CERT: %d",
+				       adapter->wapi_info.wapi_auth_mode);
+				roam_profile->AuthType.authType[0] =
+					eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
+				break;
+			}
+			default:
+				break;
+			} /* End of switch */
+			if (adapter->wapi_info.wapi_auth_mode ==
+			    WAPI_AUTH_MODE_PSK
+			    || adapter->wapi_info.wapi_auth_mode ==
+			    WAPI_AUTH_MODE_CERT) {
+				hdd_debug("WAPI PAIRWISE/GROUP ENCRYPTION: WPI");
+				roam_profile->AuthType.numEntries = 1;
+				roam_profile->EncryptionType.numEntries = 1;
+				roam_profile->EncryptionType.encryptionType[0] =
+					eCSR_ENCRYPT_TYPE_WPI;
+				roam_profile->mcEncryptionType.numEntries = 1;
+				roam_profile->mcEncryptionType.
+				encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
+			}
+		}
+#endif
+		ucfg_pmo_flush_gtk_offload_req(adapter->vdev);
+		roam_profile->csrPersona = adapter->device_mode;
+
+		if (operatingChannel) {
+			roam_profile->ChannelInfo.ChannelList =
+				&operatingChannel;
+			roam_profile->ChannelInfo.numOfChannels = 1;
+		} else {
+			roam_profile->ChannelInfo.ChannelList = NULL;
+			roam_profile->ChannelInfo.numOfChannels = 0;
+		}
+		if ((QDF_IBSS_MODE == adapter->device_mode)
+		    && operatingChannel) {
+			/*
+			 * Need to post the IBSS power save parameters
+			 * to WMA. WMA will configure this parameters
+			 * to firmware if power save is enabled by the
+			 * firmware.
+			 */
+			qdf_status = hdd_set_ibss_power_save_params(adapter);
+
+			if (QDF_STATUS_SUCCESS != qdf_status) {
+				hdd_err("Set IBSS Power Save Params Failed");
+				status = -EINVAL;
+				goto conn_failure;
+			}
+			roam_profile->ch_params.ch_width =
+				hdd_map_nl_chan_width(ch_width);
+			/*
+			 * In IBSS mode while operating in 2.4 GHz,
+			 * the device supports only 20 MHz.
+			 */
+			if (WLAN_REG_IS_24GHZ_CH(operatingChannel))
+				roam_profile->ch_params.ch_width =
+					CH_WIDTH_20MHZ;
+			hdd_select_cbmode(adapter, operatingChannel,
+					  &roam_profile->ch_params);
+		}
+
+		if (wlan_hdd_cfg80211_check_pmf_valid(roam_profile)) {
+			status = -EINVAL;
+			goto conn_failure;
+		}
+
+		/*
+		 * After 8-way handshake supplicant should give the scan command
+		 * in that it update the additional IEs, But because of scan
+		 * enhancements, the supplicant is not issuing the scan command
+		 * now. So the unicast frames which are sent from the host are
+		 * not having the additional IEs. If it is P2P CLIENT and there
+		 * is no additional IE present in roamProfile, then use the
+		 * addtional IE form scan_info
+		 */
+
+		if ((adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
+		    (!roam_profile->pAddIEScan)) {
+			roam_profile->pAddIEScan =
+				&adapter->scan_info.scan_add_ie.addIEdata[0];
+			roam_profile->nAddIEScanLength =
+				adapter->scan_info.scan_add_ie.length;
+		}
+
+		if ((policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) == true)
+			&& (false == wlan_hdd_handle_sap_sta_dfs_conc(adapter,
+				roam_profile))) {
+			hdd_err("sap-sta conc will fail, can't allow sta");
+			hdd_conn_set_connection_state(adapter,
+					eConnectionState_NotConnected);
+			status = -ENOMEM;
+			goto conn_failure;
+		}
+
+		sme_config = qdf_mem_malloc(sizeof(*sme_config));
+		if (!sme_config) {
+			hdd_conn_set_connection_state(adapter,
+					eConnectionState_NotConnected);
+			status = -ENOMEM;
+			goto conn_failure;
+		}
+
+		mac_handle = hdd_ctx->mac_handle;
+		sme_get_config_param(mac_handle, sme_config);
+		/* These values are not sessionized. So, any change in these SME
+		 * configs on an older or parallel interface will affect the
+		 * cb mode. So, restoring the default INI params before starting
+		 * interfaces such as sta, cli etc.,
+		 */
+		sme_config->csrConfig.channelBondingMode5GHz =
+			hdd_ctx->config->nChannelBondingMode5GHz;
+		sme_config->csrConfig.channelBondingMode24GHz =
+			hdd_ctx->config->nChannelBondingMode24GHz;
+		sme_update_config(mac_handle, sme_config);
+		qdf_mem_free(sme_config);
+		/*
+		 * Change conn_state to connecting before sme_roam_connect(),
+		 * because sme_roam_connect() has a direct path to call
+		 * hdd_sme_roam_callback(), which will change the conn_state
+		 * If direct path, conn_state will be accordingly changed to
+		 * NotConnected or Associated by either
+		 * hdd_association_completion_handler() or
+		 * hdd_dis_connect_handler() in sme_RoamCallback()if
+		 * sme_RomConnect is to be queued,
+		 * Connecting state will remain until it is completed.
+		 *
+		 * If connection state is not changed, connection state will
+		 * remain in eConnectionState_NotConnected state.
+		 * In hdd_association_completion_handler, "hddDisconInProgress"
+		 * is set to true if conn state is
+		 * eConnectionState_NotConnected.
+		 * If "hddDisconInProgress" is set to true then cfg80211 layer
+		 * is not informed of connect result indication which
+		 * is an issue.
+		 */
+		if (QDF_STA_MODE == adapter->device_mode ||
+			QDF_P2P_CLIENT_MODE == adapter->device_mode)
+			hdd_conn_set_connection_state(adapter,
+			eConnectionState_Connecting);
+
+		hdd_set_disconnect_status(adapter, false);
+
+		qdf_runtime_pm_prevent_suspend(
+				&hdd_ctx->runtime_context.connect);
+		hdd_prevent_suspend_timeout(HDD_WAKELOCK_CONNECT_COMPLETE,
+					    WIFI_POWER_EVENT_WAKELOCK_CONNECT);
+		qdf_status = sme_roam_connect(mac_handle,
+					      adapter->session_id, roam_profile,
+					      &roamId);
+		if (QDF_IS_STATUS_ERROR(qdf_status))
+			status = qdf_status_to_os_return(qdf_status);
+
+		if ((QDF_STATUS_SUCCESS != qdf_status) &&
+		    (QDF_STA_MODE == adapter->device_mode ||
+		     QDF_P2P_CLIENT_MODE == adapter->device_mode)) {
+			hdd_err("sme_roam_connect (session %d) failed with "
+			       "qdf_status %d. -> NotConnected",
+			       adapter->session_id, qdf_status);
+			/* change back to NotAssociated */
+			hdd_conn_set_connection_state(adapter,
+						      eConnectionState_NotConnected);
+			qdf_runtime_pm_allow_suspend(
+					&hdd_ctx->runtime_context.connect);
+			hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
+		}
+
+		/* Reset connect_in_progress */
+		hdd_set_connection_in_progress(false);
+
+		roam_profile->ChannelInfo.ChannelList = NULL;
+		roam_profile->ChannelInfo.numOfChannels = 0;
+
+		if ((QDF_STA_MODE == adapter->device_mode)
+			&& policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc)
+			&& !policy_mgr_is_hw_dbs_2x2_capable(
+			hdd_ctx->psoc)) {
+			policy_mgr_get_channel_from_scan_result(
+				hdd_ctx->psoc,
+				roam_profile, &channel);
+			hdd_info("Move to single MAC mode(optimization) if applicable");
+			if (channel)
+				policy_mgr_checkn_update_hw_mode_single_mac_mode(
+					hdd_ctx->psoc, channel);
+		}
+
+	} else {
+		hdd_err("No valid Roam profile");
+		status = -EINVAL;
+	}
+	goto ret_status;
+
+conn_failure:
+	/* Reset connect_in_progress */
+	hdd_set_connection_in_progress(false);
+
+ret_status:
+	/*
+	 * Enable roaming on other STA adapter for failure case.
+	 * For success case, it is enabled in assoc completion handler
+	 */
+	if (status)
+		wlan_hdd_enable_roaming(adapter);
+
+	hdd_exit();
+	return status;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_auth_type() - set auth type
+ * @adapter: Pointer to adapter
+ * @auth_type: Auth type
+ *
+ * This function is used to set the authentication type (OPEN/SHARED).
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_set_auth_type(struct hdd_adapter *adapter,
+					   enum nl80211_auth_type auth_type)
+{
+	struct hdd_station_ctx *sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct csr_roam_profile *roam_profile;
+
+	/*set authentication type */
+	switch (auth_type) {
+	case NL80211_AUTHTYPE_AUTOMATIC:
+		hdd_debug("set authentication type to AUTOSWITCH");
+		sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
+		break;
+
+	case NL80211_AUTHTYPE_OPEN_SYSTEM:
+	case NL80211_AUTHTYPE_FT:
+		hdd_debug("set authentication type to OPEN");
+		sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+		break;
+
+	case NL80211_AUTHTYPE_SHARED_KEY:
+		hdd_debug("set authentication type to SHARED");
+		sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
+		break;
+#ifdef FEATURE_WLAN_ESE
+	case NL80211_AUTHTYPE_NETWORK_EAP:
+		hdd_debug("set authentication type to CCKM WPA");
+		sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;
+		break;
+#endif
+#if defined(WLAN_FEATURE_FILS_SK) && \
+	(defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
+		 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)))
+	case NL80211_AUTHTYPE_FILS_SK:
+		hdd_debug("set authentication type to FILS SHARED");
+		sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+		break;
+#endif
+	case NL80211_AUTHTYPE_SAE:
+		hdd_debug("set authentication type to SAE");
+		sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_SAE;
+		break;
+	default:
+		hdd_err("Unsupported authentication type: %d", auth_type);
+		sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
+		return -EINVAL;
+	}
+
+	roam_profile = hdd_roam_profile(adapter);
+	roam_profile->AuthType.authType[0] = sta_ctx->conn_info.authType;
+	return 0;
+}
+
+#if defined(WLAN_FEATURE_FILS_SK) && \
+	(defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
+		 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)))
+static bool hdd_validate_fils_info_ptr(struct csr_roam_profile *roam_profile)
+{
+	struct cds_fils_connection_info *fils_con_info;
+
+	fils_con_info = roam_profile->fils_con_info;
+	if (!fils_con_info) {
+		hdd_err("No valid Roam profile");
+		return false;
+	}
+
+	return true;
+}
+
+static enum eAniAuthType wlan_hdd_get_fils_auth_type(
+		enum nl80211_auth_type auth)
+{
+	switch (auth) {
+	case NL80211_AUTHTYPE_FILS_SK:
+		return SIR_FILS_SK_WITHOUT_PFS;
+	case NL80211_AUTHTYPE_FILS_SK_PFS:
+		return SIR_FILS_SK_WITH_PFS;
+	case NL80211_AUTHTYPE_FILS_PK:
+		return SIR_FILS_PK_AUTH;
+	default:
+		return eSIR_DONOT_USE_AUTH_TYPE;
+	}
+}
+
+static bool wlan_hdd_fils_data_in_limits(struct cfg80211_connect_params *req)
+{
+	hdd_debug("seq=%d auth=%d lengths: user=%zu rrk=%zu realm=%zu",
+		  req->fils_erp_next_seq_num, req->auth_type,
+		  req->fils_erp_username_len, req->fils_erp_rrk_len,
+		  req->fils_erp_realm_len);
+	if (!req->fils_erp_rrk_len || !req->fils_erp_realm_len ||
+	    !req->fils_erp_username_len ||
+	    req->fils_erp_rrk_len > FILS_MAX_RRK_LENGTH ||
+	    req->fils_erp_realm_len > FILS_MAX_REALM_LEN ||
+	    req->fils_erp_username_len > FILS_MAX_KEYNAME_NAI_LENGTH) {
+		hdd_err("length incorrect, user=%zu rrk=%zu realm=%zu",
+			req->fils_erp_username_len, req->fils_erp_rrk_len,
+			req->fils_erp_realm_len);
+		return false;
+	}
+
+	if (!req->fils_erp_rrk || !req->fils_erp_realm ||
+	    !req->fils_erp_username) {
+		hdd_err("buffer incorrect, user=%pK rrk=%pK realm=%pK",
+			req->fils_erp_username, req->fils_erp_rrk,
+			req->fils_erp_realm);
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_fils_config() - set fils config params during connect
+ * @adapter: Pointer to adapter
+ * @req: Pointer to fils parameters
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_set_fils_config(struct hdd_adapter *adapter,
+					 struct cfg80211_connect_params *req)
+{
+	struct csr_roam_profile *roam_profile;
+	enum eAniAuthType auth_type;
+	uint8_t *buf;
+	bool value;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	roam_profile = hdd_roam_profile(adapter);
+
+	value = 0;
+	status = ucfg_mlme_get_fils_enabled_info(hdd_ctx->psoc, &value);
+	if (QDF_IS_STATUS_ERROR(status) || !value) {
+		hdd_err("get_fils_enabled status: %d fils_enabled: %d",
+			status, value);
+		return -EINVAL;
+	}
+
+	hdd_clear_fils_connection_info(adapter);
+	roam_profile->fils_con_info =
+		qdf_mem_malloc(sizeof(*roam_profile->fils_con_info));
+
+	if (!roam_profile->fils_con_info)
+		return -EINVAL;
+	/*
+	 * The initial connection for FILS may happen with an OPEN
+	 * auth type. Hence we need to allow the connection to go
+	 * through in that case as well. Below is_fils_connection
+	 * flag is propagated down to CSR and PE sessions through
+	 * the JOIN request. As the flag is used, do not free the
+	 * memory allocated to fils_con_info and return success.
+	 */
+	if (req->auth_type != NL80211_AUTHTYPE_FILS_SK) {
+		roam_profile->fils_con_info->is_fils_connection = false;
+		return 0;
+	}
+
+	/*
+	 * Once above check is done, then we can check for valid FILS
+	 * auth types. Currently only NL80211_AUTHTYPE_FILS_SK is
+	 * supported. Once all auth types are supported, then we can
+	 * merge these 2 conditions into one.
+	 */
+	auth_type = wlan_hdd_get_fils_auth_type(req->auth_type);
+	if (auth_type == eSIR_DONOT_USE_AUTH_TYPE) {
+		hdd_err("invalid auth type for fils %d", req->auth_type);
+		goto fils_conn_fail;
+	}
+	if (!wlan_hdd_fils_data_in_limits(req))
+		goto fils_conn_fail;
+
+	roam_profile->fils_con_info->is_fils_connection = true;
+	roam_profile->fils_con_info->sequence_number =
+		req->fils_erp_next_seq_num;
+	roam_profile->fils_con_info->auth_type = auth_type;
+
+	roam_profile->fils_con_info->r_rk_length =
+			req->fils_erp_rrk_len;
+	if (req->fils_erp_rrk_len)
+		qdf_mem_copy(roam_profile->fils_con_info->r_rk,
+			req->fils_erp_rrk,
+			roam_profile->fils_con_info->r_rk_length);
+
+	roam_profile->fils_con_info->realm_len = req->fils_erp_realm_len;
+	if (req->fils_erp_realm_len)
+		qdf_mem_copy(roam_profile->fils_con_info->realm,
+			req->fils_erp_realm,
+			roam_profile->fils_con_info->realm_len);
+
+	roam_profile->fils_con_info->key_nai_length =
+		req->fils_erp_username_len + sizeof(char) +
+				req->fils_erp_realm_len;
+	hdd_debug("key_nai_length = %d",
+		  roam_profile->fils_con_info->key_nai_length);
+	if (roam_profile->fils_con_info->key_nai_length >
+		FILS_MAX_KEYNAME_NAI_LENGTH) {
+		hdd_err("Do not allow FILS conn due to excess NAI Length %d",
+			roam_profile->fils_con_info->key_nai_length);
+		goto fils_conn_fail;
+	}
+	buf = roam_profile->fils_con_info->keyname_nai;
+	qdf_mem_copy(buf, req->fils_erp_username, req->fils_erp_username_len);
+	buf += req->fils_erp_username_len;
+	*buf++ = '@';
+	qdf_mem_copy(buf, req->fils_erp_realm, req->fils_erp_realm_len);
+
+	return 0;
+
+fils_conn_fail:
+	if (roam_profile->fils_con_info) {
+		qdf_mem_free(roam_profile->fils_con_info);
+		roam_profile->fils_con_info = NULL;
+	}
+	return -EINVAL;
+}
+
+static bool wlan_hdd_is_akm_suite_fils(uint32_t key_mgmt)
+{
+	switch (key_mgmt) {
+	case WLAN_AKM_SUITE_FILS_SHA256:
+	case WLAN_AKM_SUITE_FILS_SHA384:
+	case WLAN_AKM_SUITE_FT_FILS_SHA256:
+	case WLAN_AKM_SUITE_FT_FILS_SHA384:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool wlan_hdd_is_conn_type_fils(struct cfg80211_connect_params *req)
+{
+	enum nl80211_auth_type auth_type = req->auth_type;
+	/*
+	 * Below n_akm_suites is defined as int in the kernel, even though it
+	 * is supposed to be unsigned.
+	 */
+	int num_akm_suites = req->crypto.n_akm_suites;
+	uint32_t key_mgmt = req->crypto.akm_suites[0];
+	enum eAniAuthType fils_auth_type =
+		wlan_hdd_get_fils_auth_type(req->auth_type);
+
+	hdd_debug("Num of AKM suites = %d", num_akm_suites);
+	if (num_akm_suites <= 0)
+		return false;
+
+	/*
+	 * Auth type will be either be OPEN or FILS type for a FILS connection
+	 */
+	if ((auth_type != NL80211_AUTHTYPE_OPEN_SYSTEM) &&
+	    (fils_auth_type == eSIR_DONOT_USE_AUTH_TYPE)) {
+		hdd_debug("Not a FILS auth type, auth = %d, fils auth = %d",
+			  auth_type, fils_auth_type);
+		return false;
+	}
+
+	if (!wlan_hdd_is_akm_suite_fils(key_mgmt)) {
+		hdd_debug("Not a FILS AKM SUITE %d", key_mgmt);
+		return false;
+	}
+
+	return true;
+}
+
+#else
+static bool hdd_validate_fils_info_ptr(struct csr_roam_profile *roam_profile)
+{
+	return true;
+}
+
+static int wlan_hdd_cfg80211_set_fils_config(struct hdd_adapter *adapter,
+					 struct cfg80211_connect_params *req)
+{
+	return 0;
+}
+
+static bool wlan_hdd_is_akm_suite_fils(uint32_t key_mgmt)
+{
+	return false;
+}
+
+static bool wlan_hdd_is_conn_type_fils(struct cfg80211_connect_params *req)
+{
+	return false;
+}
+#endif
+
+/**
+ * wlan_hdd_set_akm_suite() - set key management type
+ * @adapter: Pointer to adapter
+ * @key_mgmt: Key management type
+ *
+ * This function is used to set the key mgmt type(PSK/8021x).
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_set_akm_suite(struct hdd_adapter *adapter, u32 key_mgmt)
+{
+	struct hdd_station_ctx *sta_ctx;
+	struct csr_roam_profile *roam_profile;
+
+	roam_profile = hdd_roam_profile(adapter);
+
+	if (wlan_hdd_is_akm_suite_fils(key_mgmt) &&
+	    !hdd_validate_fils_info_ptr(roam_profile))
+		return -EINVAL;
+#ifndef WLAN_AKM_SUITE_8021X_SHA256
+#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
+#endif
+#ifndef WLAN_AKM_SUITE_PSK_SHA256
+#define WLAN_AKM_SUITE_PSK_SHA256   0x000FAC06
+#endif
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	/*set key mgmt type */
+	switch (key_mgmt) {
+	case WLAN_AKM_SUITE_PSK:
+	case WLAN_AKM_SUITE_PSK_SHA256:
+	case WLAN_AKM_SUITE_FT_PSK:
+	case WLAN_AKM_SUITE_DPP_RSN:
+		hdd_debug("setting key mgmt type to PSK");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_PSK;
+		break;
+
+	case WLAN_AKM_SUITE_8021X_SHA256:
+	case WLAN_AKM_SUITE_8021X:
+	case WLAN_AKM_SUITE_FT_8021X:
+		hdd_debug("setting key mgmt type to 8021x");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
+		break;
+#ifdef FEATURE_WLAN_ESE
+#define WLAN_AKM_SUITE_CCKM         0x00409600  /* Should be in ieee802_11_defs.h */
+	case WLAN_AKM_SUITE_CCKM:
+		hdd_debug("setting key mgmt type to CCKM");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_CCKM;
+		break;
+#endif
+#ifndef WLAN_AKM_SUITE_OSEN
+#define WLAN_AKM_SUITE_OSEN         0x506f9a01  /* Should be in ieee802_11_defs.h */
+#endif
+	case WLAN_AKM_SUITE_OSEN:
+		hdd_debug("setting key mgmt type to OSEN");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
+		break;
+#if defined(WLAN_FEATURE_FILS_SK) && \
+	(defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
+		 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)))
+	case WLAN_AKM_SUITE_FILS_SHA256:
+		hdd_debug("setting key mgmt type to FILS SHA256");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
+		roam_profile->fils_con_info->akm_type =
+			eCSR_AUTH_TYPE_FILS_SHA256;
+		break;
+
+	case WLAN_AKM_SUITE_FILS_SHA384:
+		hdd_debug("setting key mgmt type to FILS SHA384");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
+		roam_profile->fils_con_info->akm_type =
+			eCSR_AUTH_TYPE_FILS_SHA384;
+		break;
+
+	case WLAN_AKM_SUITE_FT_FILS_SHA256:
+		hdd_debug("setting key mgmt type to FILS FT SHA256");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
+		roam_profile->fils_con_info->akm_type =
+			eCSR_AUTH_TYPE_FT_FILS_SHA256;
+		break;
+
+	case WLAN_AKM_SUITE_FT_FILS_SHA384:
+		hdd_debug("setting key mgmt type to FILS FT SHA384");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
+		roam_profile->fils_con_info->akm_type =
+			eCSR_AUTH_TYPE_FT_FILS_SHA384;
+		break;
+#endif
+
+	case WLAN_AKM_SUITE_OWE:
+		hdd_debug("setting key mgmt type to OWE");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
+		break;
+
+	case WLAN_AKM_SUITE_EAP_SHA256:
+		hdd_debug("setting key mgmt type to EAP_SHA256");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
+		break;
+	case WLAN_AKM_SUITE_EAP_SHA384:
+		hdd_debug("setting key mgmt type to EAP_SHA384");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
+		break;
+
+	case WLAN_AKM_SUITE_SAE:
+		hdd_debug("setting key mgmt type to SAE");
+		sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
+		break;
+
+	default:
+		hdd_err("Unsupported key mgmt type: %d", key_mgmt);
+		return -EINVAL;
+
+	}
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_cipher() - set encryption type
+ * @adapter: Pointer to adapter
+ * @cipher: Cipher type
+ * @ucast: Unicast flag
+ *
+ * This function is used to set the encryption type
+ * (NONE/WEP40/WEP104/TKIP/CCMP).
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_set_cipher(struct hdd_adapter *adapter,
+					u32 cipher, bool ucast)
+{
+	eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
+	struct hdd_station_ctx *sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct csr_roam_profile *roam_profile;
+
+	if (!cipher) {
+		hdd_debug("received cipher %d - considering none", cipher);
+		encryptionType = eCSR_ENCRYPT_TYPE_NONE;
+	} else {
+
+		/*set encryption method */
+		switch (cipher) {
+		case IW_AUTH_CIPHER_NONE:
+			encryptionType = eCSR_ENCRYPT_TYPE_NONE;
+			break;
+
+		case WLAN_CIPHER_SUITE_WEP40:
+			encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
+			break;
+
+		case WLAN_CIPHER_SUITE_WEP104:
+			encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
+			break;
+
+		case WLAN_CIPHER_SUITE_TKIP:
+			encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
+			break;
+
+		case WLAN_CIPHER_SUITE_CCMP:
+			encryptionType = eCSR_ENCRYPT_TYPE_AES;
+			break;
+#ifdef FEATURE_WLAN_WAPI
+		case WLAN_CIPHER_SUITE_SMS4:
+			encryptionType = eCSR_ENCRYPT_TYPE_WPI;
+			break;
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+		case WLAN_CIPHER_SUITE_KRK:
+			encryptionType = eCSR_ENCRYPT_TYPE_KRK;
+			break;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		case WLAN_CIPHER_SUITE_BTK:
+			encryptionType = eCSR_ENCRYPT_TYPE_BTK;
+			break;
+#endif
+#endif
+		case WLAN_CIPHER_SUITE_GCMP:
+			encryptionType = eCSR_ENCRYPT_TYPE_AES_GCMP;
+			break;
+		case WLAN_CIPHER_SUITE_GCMP_256:
+			encryptionType = eCSR_ENCRYPT_TYPE_AES_GCMP_256;
+			break;
+		default:
+			hdd_err("Unsupported cipher type: %d", cipher);
+			return -EOPNOTSUPP;
+		}
+	}
+
+	roam_profile = hdd_roam_profile(adapter);
+	if (ucast) {
+		hdd_debug("setting unicast cipher type to %d", encryptionType);
+		sta_ctx->conn_info.ucEncryptionType = encryptionType;
+		roam_profile->EncryptionType.numEntries = 1;
+		roam_profile->EncryptionType.encryptionType[0] =
+			encryptionType;
+	} else {
+		hdd_debug("setting mcast cipher type to %d", encryptionType);
+		sta_ctx->conn_info.mcEncryptionType = encryptionType;
+		roam_profile->mcEncryptionType.numEntries = 1;
+		roam_profile->mcEncryptionType.encryptionType[0] =
+			encryptionType;
+	}
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_add_assoc_ie() - Add Assoc IE to roamProfile
+ * @adapter: Pointer to adapter
+ * @gen_ie: Pointer to IE data
+ * @len: length of IE data
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_add_assoc_ie(struct hdd_adapter *adapter,
+				 const uint8_t *gen_ie, uint16_t len)
+{
+	struct csr_roam_profile *roam_profile;
+	tSirAddie *assoc_add_ie;
+	uint16_t cur_add_ie_len;
+
+	assoc_add_ie = hdd_assoc_additional_ie(adapter);
+	cur_add_ie_len = assoc_add_ie->length;
+	if (SIR_MAC_MAX_ADD_IE_LENGTH < (cur_add_ie_len + len)) {
+		hdd_err("current len %u, new ie of len %u will overflow",
+			cur_add_ie_len, len);
+		return -ENOMEM;
+	}
+	memcpy(assoc_add_ie->addIEdata + cur_add_ie_len, gen_ie, len);
+	assoc_add_ie->length += len;
+
+	roam_profile = hdd_roam_profile(adapter);
+	roam_profile->pAddIEAssoc = assoc_add_ie->addIEdata;
+	roam_profile->nAddIEAssocLength = assoc_add_ie->length;
+
+	return 0;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * wlan_hdd_save_hlp_ie - API to save HLP IE
+ * @roam_profile: Pointer to roam profile
+ * @gen_ie: IE buffer to store
+ * @len: length of the IE buffer @gen_ie
+ * @flush: Flush the older saved HLP if any
+ *
+ * Return: None
+ */
+static void wlan_hdd_save_hlp_ie(struct csr_roam_profile *roam_profile,
+				 const uint8_t *gen_ie, uint16_t len,
+				 bool flush)
+{
+	uint8_t *hlp_ie = roam_profile->hlp_ie;
+
+	if (flush) {
+		roam_profile->hlp_ie_len = 0;
+		if (hlp_ie) {
+			qdf_mem_free(hlp_ie);
+			roam_profile->hlp_ie = NULL;
+		}
+	}
+
+	if ((roam_profile->hlp_ie_len +
+			len) > FILS_MAX_HLP_DATA_LEN) {
+		hdd_err("HLP len exceeds: hlp_ie_len %d len %d",
+			roam_profile->hlp_ie_len, len);
+		return;
+	}
+
+	if (!roam_profile->hlp_ie) {
+		roam_profile->hlp_ie =
+				qdf_mem_malloc(FILS_MAX_HLP_DATA_LEN);
+		hlp_ie = roam_profile->hlp_ie;
+		if (!hlp_ie)
+			return;
+	}
+
+	qdf_mem_copy(hlp_ie + roam_profile->hlp_ie_len, gen_ie, len);
+	roam_profile->hlp_ie_len += len;
+}
+#else
+static inline void wlan_hdd_save_hlp_ie(struct csr_roam_profile *roam_profile,
+					const uint8_t *gen_ie, uint16_t len,
+					bool flush)
+{}
+#endif
+/**
+ * wlan_hdd_cfg80211_set_ie() - set IEs
+ * @adapter: Pointer to adapter
+ * @ie: Pointer ot ie
+ * @ie: IE length
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_set_ie(struct hdd_adapter *adapter,
+				    const uint8_t *ie,
+				    size_t ie_len)
+{
+	struct csr_roam_profile *roam_profile;
+	tSirAddie *assoc_add_ie;
+	const uint8_t *genie = ie;
+	uint16_t remLen = ie_len;
+#ifdef FEATURE_WLAN_WAPI
+	uint32_t akmsuite[MAX_NUM_AKM_SUITES];
+	uint8_t *tmp;
+	uint16_t akmsuiteCount;
+	uint32_t *akmlist;
+#endif
+	int status;
+	uint8_t *security_ie;
+
+	roam_profile = hdd_roam_profile(adapter);
+
+	/* clear previous assocAddIE */
+	assoc_add_ie = hdd_assoc_additional_ie(adapter);
+	assoc_add_ie->length = 0;
+	roam_profile->bWPSAssociation = false;
+	roam_profile->bOSENAssociation = false;
+	security_ie = hdd_security_ie(adapter);
+
+	while (remLen >= 2) {
+		uint16_t eLen = 0;
+		uint8_t elementId;
+
+		elementId = *genie++;
+		eLen = *genie++;
+		remLen -= 2;
+
+		/* Sanity check on eLen */
+		if (eLen > remLen) {
+			hdd_err("%s: Invalid IE length[%d] for IE[0x%X]",
+				__func__, eLen, elementId);
+			QDF_ASSERT(0);
+			return -EINVAL;
+		}
+
+		hdd_debug("IE[0x%X], LEN[%d]", elementId, eLen);
+
+		switch (elementId) {
+		case DOT11F_EID_WPA:
+			if (4 > eLen) { /* should have at least OUI which is 4 bytes so extra 2 bytes not needed */
+				hdd_err("Invalid WPA IE");
+				return -EINVAL;
+			} else if (0 ==
+				   memcmp(&genie[0], "\x00\x50\xf2\x04", 4)) {
+				uint16_t curAddIELen = assoc_add_ie->length;
+
+				hdd_debug("Set WPS IE(len %d)", eLen + 2);
+
+				if (SIR_MAC_MAX_ADD_IE_LENGTH <
+				    (assoc_add_ie->length + eLen)) {
+					hdd_err("Cannot accommodate assocAddIE. Need bigger buffer space");
+					QDF_ASSERT(0);
+					return -ENOMEM;
+				}
+				/* WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE */
+				memcpy(assoc_add_ie->addIEdata +
+				       curAddIELen, genie - 2, eLen + 2);
+				assoc_add_ie->length += eLen + 2;
+
+				roam_profile->bWPSAssociation = true;
+				roam_profile->pAddIEAssoc =
+					assoc_add_ie->addIEdata;
+				roam_profile->nAddIEAssocLength =
+					assoc_add_ie->length;
+			} else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3)) {
+				if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
+					hdd_err("%s: Invalid WPA IE length[%d]",
+						__func__, eLen);
+					QDF_ASSERT(0);
+					return -EINVAL;
+				}
+				hdd_debug("Set WPA IE (len %d)", eLen + 2);
+				memset(security_ie, 0, MAX_WPA_RSN_IE_LEN);
+				memcpy(security_ie, genie - 2, (eLen + 2));
+				roam_profile->pWPAReqIE = security_ie;
+				roam_profile->nWPAReqIELength = eLen + 2;     /* ie_len; */
+			} else if ((0 == memcmp(&genie[0], P2P_OUI_TYPE,
+						P2P_OUI_TYPE_SIZE))) {
+				uint16_t curAddIELen =
+					assoc_add_ie->length;
+				hdd_debug("Set P2P IE(len %d)", eLen + 2);
+
+				if (SIR_MAC_MAX_ADD_IE_LENGTH <
+				    (assoc_add_ie->length + eLen)) {
+					hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
+					QDF_ASSERT(0);
+					return -ENOMEM;
+				}
+				/* P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE */
+				memcpy(assoc_add_ie->addIEdata +
+				       curAddIELen, genie - 2, eLen + 2);
+				assoc_add_ie->length += eLen + 2;
+
+				roam_profile->pAddIEAssoc =
+					assoc_add_ie->addIEdata;
+				roam_profile->nAddIEAssocLength =
+					assoc_add_ie->length;
+			}
+#ifdef WLAN_FEATURE_WFD
+			else if ((0 == memcmp(&genie[0], WFD_OUI_TYPE,
+					      WFD_OUI_TYPE_SIZE)) &&
+				/* Consider WFD IE, only for P2P Client */
+				 (QDF_P2P_CLIENT_MODE ==
+				     adapter->device_mode)) {
+				uint16_t curAddIELen =
+					assoc_add_ie->length;
+				hdd_debug("Set WFD IE(len %d)", eLen + 2);
+
+				if (SIR_MAC_MAX_ADD_IE_LENGTH <
+				    (assoc_add_ie->length + eLen)) {
+					hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
+					QDF_ASSERT(0);
+					return -ENOMEM;
+				}
+				/* WFD IE is saved to Additional IE ; it should
+				 * be accumulated to handle WPS IE + P2P IE +
+				 * WFD IE
+				 */
+				memcpy(assoc_add_ie->addIEdata +
+				       curAddIELen, genie - 2, eLen + 2);
+				assoc_add_ie->length += eLen + 2;
+
+				roam_profile->pAddIEAssoc =
+					assoc_add_ie->addIEdata;
+				roam_profile->nAddIEAssocLength =
+					assoc_add_ie->length;
+			}
+#endif
+			/* Appending HS 2.0 Indication Element in Assiciation Request */
+			else if ((0 == memcmp(&genie[0], HS20_OUI_TYPE,
+					      HS20_OUI_TYPE_SIZE))) {
+				uint16_t curAddIELen =
+					assoc_add_ie->length;
+				hdd_debug("Set HS20 IE(len %d)", eLen + 2);
+
+				if (SIR_MAC_MAX_ADD_IE_LENGTH <
+				    (assoc_add_ie->length + eLen)) {
+					hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
+					QDF_ASSERT(0);
+					return -ENOMEM;
+				}
+				memcpy(assoc_add_ie->addIEdata +
+				       curAddIELen, genie - 2, eLen + 2);
+				assoc_add_ie->length += eLen + 2;
+
+				roam_profile->pAddIEAssoc =
+					assoc_add_ie->addIEdata;
+				roam_profile->nAddIEAssocLength =
+					assoc_add_ie->length;
+			}
+			/* Appending OSEN Information  Element in Assiciation Request */
+			else if ((0 == memcmp(&genie[0], OSEN_OUI_TYPE,
+					      OSEN_OUI_TYPE_SIZE))) {
+				uint16_t curAddIELen =
+					assoc_add_ie->length;
+				hdd_debug("Set OSEN IE(len %d)", eLen + 2);
+
+				if (SIR_MAC_MAX_ADD_IE_LENGTH <
+				    (assoc_add_ie->length + eLen)) {
+					hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
+					QDF_ASSERT(0);
+					return -ENOMEM;
+				}
+				memcpy(assoc_add_ie->addIEdata +
+				       curAddIELen, genie - 2, eLen + 2);
+				assoc_add_ie->length += eLen + 2;
+
+				roam_profile->bOSENAssociation = true;
+				roam_profile->pAddIEAssoc =
+					assoc_add_ie->addIEdata;
+				roam_profile->nAddIEAssocLength =
+					assoc_add_ie->length;
+			} else if ((0 == memcmp(&genie[0], MBO_OUI_TYPE,
+							MBO_OUI_TYPE_SIZE))){
+				hdd_debug("Set MBO IE(len %d)", eLen + 2);
+				status = wlan_hdd_add_assoc_ie(adapter,
+							genie - 2, eLen + 2);
+				if (status)
+					return status;
+			} else {
+				uint16_t add_ie_len =
+					assoc_add_ie->length;
+
+				hdd_debug("Set OSEN IE(len %d)", eLen + 2);
+
+				if (SIR_MAC_MAX_ADD_IE_LENGTH <
+				    (assoc_add_ie->length + eLen)) {
+					hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
+					QDF_ASSERT(0);
+					return -ENOMEM;
+				}
+
+				memcpy(assoc_add_ie->addIEdata +
+				       add_ie_len, genie - 2, eLen + 2);
+				assoc_add_ie->length += eLen + 2;
+
+				roam_profile->pAddIEAssoc =
+					assoc_add_ie->addIEdata;
+				roam_profile->nAddIEAssocLength =
+					assoc_add_ie->length;
+			}
+			break;
+		case DOT11F_EID_RSN:
+			if  (eLen  > DOT11F_IE_RSN_MAX_LEN) {
+				hdd_err("%s: Invalid WPA RSN IE length[%d]",
+						__func__, eLen);
+				return -EINVAL;
+			}
+			memset(security_ie, 0, MAX_WPA_RSN_IE_LEN);
+			memcpy(security_ie, genie - 2, (eLen + 2));
+			roam_profile->pRSNReqIE = security_ie;
+			roam_profile->nRSNReqIELength = eLen + 2;     /* ie_len; */
+			hdd_debug("Set RSN IE(len %d)", eLen + 2);
+			break;
+		/*
+		 * Appending Extended Capabilities with Interworking bit set
+		 * in Assoc Req.
+		 *
+		 * In assoc req this EXT Cap will only be taken into account if
+		 * interworkingService bit is set to 1. Currently
+		 * driver is only interested in interworkingService capability
+		 * from supplicant. If in future any other EXT Cap info is
+		 * required from supplicat, it needs to be handled while
+		 * sending Assoc Req in LIM.
+		 */
+		case DOT11F_EID_EXTCAP:
+		{
+			uint16_t curAddIELen =
+				assoc_add_ie->length;
+			hdd_debug("Set Extended CAPS IE(len %d)", eLen + 2);
+
+			if (SIR_MAC_MAX_ADD_IE_LENGTH <
+			    (assoc_add_ie->length + eLen)) {
+				hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
+				QDF_ASSERT(0);
+				return -ENOMEM;
+			}
+			memcpy(assoc_add_ie->addIEdata + curAddIELen, genie - 2, eLen + 2);
+			assoc_add_ie->length += eLen + 2;
+
+			roam_profile->pAddIEAssoc = assoc_add_ie->addIEdata;
+			roam_profile->nAddIEAssocLength = assoc_add_ie->length;
+			break;
+		}
+#ifdef FEATURE_WLAN_WAPI
+		case WLAN_EID_WAPI:
+			/* Setting WAPI Mode to ON=1 */
+			adapter->wapi_info.wapi_mode = 1;
+			hdd_debug("WAPI MODE IS %u", adapter->wapi_info.wapi_mode);
+			/* genie is pointing to data field of WAPI IE's buffer */
+			tmp = (uint8_t *)genie;
+			/* Validate length for Version(2 bytes) and Number
+			 * of AKM suite (2 bytes) in WAPI IE buffer, coming from
+			 * supplicant*/
+			if (eLen < 4) {
+				hdd_err("Invalid IE Len: %u", eLen);
+				return -EINVAL;
+			}
+			tmp = tmp + 2;  /* Skip Version */
+			/* Get the number of AKM suite */
+			akmsuiteCount = WPA_GET_LE16(tmp);
+			/* Skip the number of AKM suite */
+			tmp = tmp + 2;
+			/* Validate total length for WAPI IE's buffer */
+			if (eLen < (4 + (akmsuiteCount * sizeof(uint32_t)))) {
+				hdd_err("Invalid IE Len: %u", eLen);
+				return -EINVAL;
+			}
+			/* AKM suite list, each OUI contains 4 bytes */
+			akmlist = (uint32_t *)(tmp);
+			if (akmsuiteCount <= MAX_NUM_AKM_SUITES) {
+				qdf_mem_copy(akmsuite, akmlist,
+					     sizeof(uint32_t) * akmsuiteCount);
+			} else {
+				hdd_err("Invalid akmSuite count: %u",
+					akmsuiteCount);
+				QDF_ASSERT(0);
+				return -EINVAL;
+			}
+
+			if (WAPI_PSK_AKM_SUITE == akmsuite[0]) {
+				hdd_debug("WAPI AUTH MODE SET TO PSK");
+				adapter->wapi_info.wapi_auth_mode =
+					WAPI_AUTH_MODE_PSK;
+			}
+			if (WAPI_CERT_AKM_SUITE == akmsuite[0]) {
+				hdd_debug("WAPI AUTH MODE SET TO CERTIFICATE");
+				adapter->wapi_info.wapi_auth_mode =
+					WAPI_AUTH_MODE_CERT;
+			}
+			break;
+#endif
+		case DOT11F_EID_SUPPOPERATINGCLASSES:
+			{
+				hdd_debug("Set Supported Operating Classes IE(len %d)", eLen + 2);
+				status = wlan_hdd_add_assoc_ie(adapter,
+							genie - 2, eLen + 2);
+				if (status)
+					return status;
+				break;
+			}
+		case SIR_MAC_REQUEST_EID_MAX:
+			{
+				if (genie[0] == SIR_FILS_HLP_EXT_EID) {
+					hdd_debug("Set HLP EXT IE(len %d)",
+							eLen + 2);
+					wlan_hdd_save_hlp_ie(roam_profile,
+							genie - 2, eLen + 2,
+							true);
+					status = wlan_hdd_add_assoc_ie(
+							adapter, genie - 2,
+							eLen + 2);
+					if (status)
+						return status;
+				} else if (genie[0] ==
+					   SIR_DH_PARAMETER_ELEMENT_EXT_EID) {
+					hdd_debug("Set DH EXT IE(len %d)",
+							eLen + 2);
+					status = wlan_hdd_add_assoc_ie(
+							adapter, genie - 2,
+							eLen + 2);
+					if (status)
+						return status;
+				} else {
+					hdd_err("UNKNOWN EID: %X", genie[0]);
+				}
+				break;
+			}
+		case DOT11F_EID_FRAGMENT_IE:
+			{
+				hdd_debug("Set Fragment IE(len %d)", eLen + 2);
+				wlan_hdd_save_hlp_ie(roam_profile,
+							genie - 2, eLen + 2,
+							false);
+				status = wlan_hdd_add_assoc_ie(adapter,
+							genie - 2, eLen + 2);
+				if (status)
+					return status;
+				break;
+			}
+		default:
+			hdd_err("Set UNKNOWN IE: %X", elementId);
+			/* when Unknown IE is received we break
+			 * and continue to the next IE in the buffer
+			 */
+			break;
+		}
+		genie += eLen;
+		remLen -= eLen;
+	}
+	return 0;
+}
+
+/**
+ * hdd_is_wpaie_present() - check for WPA ie
+ * @ie: Pointer to ie
+ * @ie_len: Ie length
+ *
+ * Parse the received IE to find the WPA IE
+ *
+ * Return: true if wpa ie is found else false
+ */
+static bool hdd_is_wpaie_present(const uint8_t *ie, uint8_t ie_len)
+{
+	uint8_t eLen = 0;
+	uint16_t remLen = ie_len;
+	uint8_t elementId = 0;
+
+	while (remLen >= 2) {
+		elementId = *ie++;
+		eLen = *ie++;
+		remLen -= 2;
+		if (eLen > remLen) {
+			hdd_err("Invalid IE length: %d", eLen);
+			return false;
+		}
+		if ((elementId == DOT11F_EID_WPA) && (remLen > 5)) {
+			/* OUI - 0x00 0X50 0XF2
+			 * WPA Information Element - 0x01
+			 * WPA version - 0x01
+			 */
+			if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
+				return true;
+		}
+		ie += eLen;
+		remLen -= eLen;
+	}
+	return false;
+}
+
+#ifdef CONFIG_CRYPTO_COMPONENT
+
+/**
+ * hdd_populate_crypto_auth_type() - populate auth type for crypto
+ * @vdev: pointed to vdev obmgr
+ * @auth_type: legacy auth_type
+ *
+ * set the crypto auth type for corresponding auth type received
+ * from NL
+ *
+ * Return: None
+ */
+static void hdd_populate_crypto_auth_type(struct wlan_objmgr_vdev *vdev,
+					  enum nl80211_auth_type auth_type)
+{
+	wlan_crypto_auth_mode crypto_auth_type =
+			osif_nl_to_crypto_auth_type(auth_type);
+
+	wlan_crypto_set_vdev_param(vdev,
+				   WLAN_CRYPTO_PARAM_AUTH_MODE,
+				   crypto_auth_type);
+}
+
+/**
+ * hdd_populate_crypto_akm_type() - populate akm type for crypto
+ * @vdev: pointed to vdev obmgr
+ * @akm_type: legacy akm_type
+ *
+ * set the crypto akm type for corresponding akm type received
+ * from NL
+ *
+ * Return: None
+ */
+static void hdd_populate_crypto_akm_type(struct wlan_objmgr_vdev *vdev,
+					 u32 key_mgmt)
+{
+	wlan_crypto_key_mgmt crypto_akm_type =
+			osif_nl_to_crypto_akm_type(key_mgmt);
+
+	wlan_crypto_set_vdev_param(vdev,
+				   WLAN_CRYPTO_PARAM_KEY_MGMT,
+				   crypto_akm_type);
+}
+
+/**
+ * hdd_populate_crypto_cipher_type() - populate cipher type for crypto
+ * @cipher: legacy cipher type
+ * @vdev: pointed to vdev obmgr
+ * @cipher_param_type: param type, UCST/MCAST
+ *
+ * set the crypto cipher type for corresponding cipher type received
+ * from NL
+ *
+ * Return: None
+ */
+static void hdd_populate_crypto_cipher_type(u32 cipher,
+					    struct wlan_objmgr_vdev *vdev,
+					    wlan_crypto_param_type
+					    cipher_param_type)
+{
+	wlan_crypto_cipher_type crypto_cipher_type =
+			osif_nl_to_crypto_cipher_type(cipher);
+
+	wlan_crypto_set_vdev_param(vdev,
+				   cipher_param_type,
+				   crypto_cipher_type);
+}
+
+/**
+ * hdd_populate_crypto_params() - set crypto params
+ * @vdev: Pointer to vdev obh mgr
+ * @req: Pointer to security parameters
+ *
+ * Set Auth, Akm and Cipher type for crypto
+ *
+ * Return: None
+ */
+static void hdd_populate_crypto_params(struct wlan_objmgr_vdev *vdev,
+				       struct cfg80211_connect_params *req)
+{
+	hdd_populate_crypto_auth_type(vdev, req->auth_type);
+
+	if (req->crypto.n_akm_suites)
+		hdd_populate_crypto_akm_type(vdev, req->crypto.akm_suites[0]);
+
+	if (req->crypto.n_ciphers_pairwise) {
+		hdd_populate_crypto_cipher_type(req->crypto.ciphers_pairwise[0],
+						vdev,
+						WLAN_CRYPTO_PARAM_UCAST_CIPHER);
+	} else {
+		/* Reset previous cipher suite to none */
+		hdd_populate_crypto_cipher_type(0, vdev,
+						WLAN_CRYPTO_PARAM_UCAST_CIPHER);
+	}
+
+	hdd_populate_crypto_cipher_type(req->crypto.cipher_group,
+					vdev,
+					WLAN_CRYPTO_PARAM_MCAST_CIPHER);
+}
+
+#else
+
+static inline
+void hdd_populate_crypto_auth_type(struct wlan_objmgr_vdev *vdev,
+				   enum nl80211_auth_type auth_type)
+{
+}
+
+static inline
+void hdd_populate_crypto_akm_type(struct wlan_objmgr_vdev *vdev,
+				  u32 key_mgmt)
+{
+}
+
+static inline
+void hdd_populate_crypto_cipher_type(u32 cipher,
+				     struct wlan_objmgr_vdev *vdev,
+				     wlan_crypto_param_type
+				     cipher_param_type)
+{
+}
+
+static inline
+void hdd_populate_crypto_params(struct wlan_objmgr_vdev *vdev,
+				struct cfg80211_connect_params *req)
+{
+}
+
+#endif
+
+/**
+ * wlan_hdd_cfg80211_set_privacy() - set security parameters during connection
+ * @adapter: Pointer to adapter
+ * @req: Pointer to security parameters
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_set_privacy(struct hdd_adapter *adapter,
+					 struct cfg80211_connect_params *req)
+{
+	int status = 0;
+	struct hdd_station_ctx *sta_ctx;
+	struct csr_roam_profile *roam_profile;
+
+	hdd_enter();
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	sta_ctx->wpa_versions = req->crypto.wpa_versions;
+	hdd_debug("set wpa version to %d", sta_ctx->wpa_versions);
+
+	roam_profile = hdd_roam_profile(adapter);
+
+	/* populate auth,akm and cipher params for crypto */
+	hdd_populate_crypto_params(adapter->vdev, req);
+
+	/*set authentication type */
+	status = wlan_hdd_cfg80211_set_auth_type(adapter, req->auth_type);
+
+	if (wlan_hdd_is_conn_type_fils(req)) {
+		status = wlan_hdd_cfg80211_set_fils_config(adapter, req);
+
+		if (0 > status) {
+			hdd_err("Failed to set fils config");
+			return status;
+		}
+	}
+
+	/*set key mgmt type */
+	if (req->crypto.n_akm_suites) {
+		status =
+			wlan_hdd_set_akm_suite(adapter, req->crypto.akm_suites[0]);
+		if (0 > status) {
+			hdd_err("Failed to set akm suite");
+			return status;
+		}
+	}
+
+	/*set pairwise cipher type */
+	if (req->crypto.n_ciphers_pairwise) {
+		status = wlan_hdd_cfg80211_set_cipher(adapter,
+						      req->crypto.
+						      ciphers_pairwise[0],
+						      true);
+		if (0 > status) {
+			hdd_err("Failed to set unicast cipher type");
+			return status;
+		}
+	} else {
+		/*Reset previous cipher suite to none */
+		status = wlan_hdd_cfg80211_set_cipher(adapter, 0, true);
+		if (0 > status) {
+			hdd_err("Failed to set unicast cipher type");
+			return status;
+		}
+	}
+
+	/*set group cipher type */
+	status =
+		wlan_hdd_cfg80211_set_cipher(adapter, req->crypto.cipher_group,
+					     false);
+
+	if (0 > status) {
+		hdd_err("Failed to set mcast cipher type");
+		return status;
+	}
+#ifdef WLAN_FEATURE_11W
+	roam_profile->MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
+#endif
+
+	/*parse WPA/RSN IE, and set the correspoing fileds in Roam profile */
+	if (req->ie_len) {
+		status =
+			wlan_hdd_cfg80211_set_ie(adapter, req->ie, req->ie_len);
+		if (0 > status) {
+			hdd_err("Failed to parse the WPA/RSN IE");
+			return status;
+		}
+	}
+
+	/*incase of WEP set default key information */
+	if (req->key && req->key_len) {
+		u8 key_len = req->key_len;
+		u8 key_idx = req->key_idx;
+		u32 cipher = req->crypto.ciphers_pairwise[0];
+
+		if ((WLAN_CIPHER_SUITE_WEP40 == cipher) ||
+		    (WLAN_CIPHER_SUITE_WEP104 == cipher)) {
+			enum hdd_auth_key_mgmt key_mgmt =
+				sta_ctx->auth_key_mgmt;
+
+			if (key_mgmt & HDD_AUTH_KEY_MGMT_802_1X) {
+				hdd_err("Dynamic WEP not supported");
+				return -EOPNOTSUPP;
+			}
+
+			if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
+			    && (CSR_MAX_NUM_KEY > key_idx)) {
+				hdd_debug("setting default wep key, key_idx = %hu key_len %hu",
+					   key_idx, key_len);
+				qdf_mem_copy(&roam_profile->Keys.
+					     KeyMaterial[key_idx][0],
+					     req->key, key_len);
+				roam_profile->Keys.
+					KeyLength[key_idx] = (u8) key_len;
+				roam_profile->Keys.
+					defaultIndex = (u8) key_idx;
+			}
+		}
+	}
+
+	return status;
+}
+
+/**
+ * wlan_hdd_clear_wapi_privacy() - reset WAPI settings in HDD layer
+ * @adapter: pointer to HDD adapter object
+ *
+ * This function resets all WAPI related parameters imposed before STA
+ * connection starts. It's invoked when privacy checking against concurrency
+ * fails, to make sure no improper WAPI settings are still populated before
+ * returning an error to the upper layer requester.
+ *
+ * Return: none
+ */
+#ifdef FEATURE_WLAN_WAPI
+static inline void wlan_hdd_clear_wapi_privacy(struct hdd_adapter *adapter)
+{
+	adapter->wapi_info.wapi_mode = 0;
+	adapter->wapi_info.wapi_auth_mode = WAPI_AUTH_MODE_OPEN;
+}
+#else
+static inline void wlan_hdd_clear_wapi_privacy(struct hdd_adapter *adapter)
+{
+}
+#endif
+
+/**
+ * wlan_hdd_cfg80211_clear_privacy() - reset STA security parameters
+ * @adapter: pointer to HDD adapter object
+ *
+ * This function resets all privacy related parameters imposed
+ * before STA connection starts. It's invoked when privacy checking
+ * against concurrency fails, to make sure no improper settings are
+ * still populated before returning an error to the upper layer requester.
+ *
+ * Return: none
+ */
+static void wlan_hdd_cfg80211_clear_privacy(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *hdd_sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	hdd_debug("resetting all privacy configurations");
+
+	hdd_sta_ctx->wpa_versions = 0;
+
+	hdd_sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_NONE;
+	hdd_sta_ctx->roam_profile.AuthType.authType[0] = eCSR_AUTH_TYPE_NONE;
+
+	hdd_sta_ctx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
+	hdd_sta_ctx->roam_profile.EncryptionType.numEntries = 0;
+	hdd_sta_ctx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
+	hdd_sta_ctx->roam_profile.mcEncryptionType.numEntries = 0;
+
+	wlan_hdd_clear_wapi_privacy(adapter);
+}
+
+int wlan_hdd_try_disconnect(struct hdd_adapter *adapter)
+{
+	unsigned long rc;
+	struct hdd_station_ctx *sta_ctx;
+	int status, result = 0;
+	mac_handle_t mac_handle;
+	uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	mac_handle = hdd_adapter_get_mac_handle(adapter);
+	if (adapter->device_mode ==  QDF_STA_MODE) {
+		hdd_debug("Stop firmware roaming");
+		sme_stop_roaming(mac_handle, adapter->session_id,
+				 eCsrForcedDisassoc);
+
+		/*
+		 * If firmware has already started roaming process, driver
+		 * needs to wait for processing of this disconnect request.
+		 *
+		 */
+		INIT_COMPLETION(adapter->roaming_comp_var);
+		if (hdd_is_roaming_in_progress(hdd_ctx)) {
+			rc = wait_for_completion_timeout(
+				&adapter->roaming_comp_var,
+				msecs_to_jiffies(WLAN_WAIT_TIME_STOP_ROAM));
+			if (!rc) {
+				hdd_err("roaming comp var timed out session Id: %d",
+					adapter->session_id);
+			}
+			if (adapter->roam_ho_fail) {
+				INIT_COMPLETION(adapter->disconnect_comp_var);
+				hdd_conn_set_connection_state(adapter,
+						eConnectionState_Disconnecting);
+			}
+		}
+	}
+
+	if ((QDF_IBSS_MODE == adapter->device_mode) ||
+	  (eConnectionState_Associated == sta_ctx->conn_info.connState) ||
+	  (eConnectionState_Connecting == sta_ctx->conn_info.connState) ||
+	  (eConnectionState_IbssConnected == sta_ctx->conn_info.connState)) {
+		eConnectionState prev_conn_state;
+
+		prev_conn_state = sta_ctx->conn_info.connState;
+		hdd_conn_set_connection_state(adapter,
+					      eConnectionState_Disconnecting);
+		/* Issue disconnect to CSR */
+		INIT_COMPLETION(adapter->disconnect_comp_var);
+
+		status = sme_roam_disconnect(mac_handle,
+				adapter->session_id,
+				eCSR_DISCONNECT_REASON_UNSPECIFIED);
+
+		if ((status == QDF_STATUS_CMD_NOT_QUEUED) &&
+		    prev_conn_state != eConnectionState_Connecting) {
+			hdd_debug("Already disconnect in progress");
+			result = 0;
+			/*
+			 * Wait here instead of returning directly. This will
+			 * block the connect command and allow processing
+			 * of the disconnect in SME. As disconnect is already
+			 * in progress, wait here for 1 sec instead of 5 sec.
+			 */
+			wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
+		} else if (status == QDF_STATUS_CMD_NOT_QUEUED) {
+			/*
+			 * Wait here instead of returning directly, this will
+			 * block the connect command and allow processing
+			 * of the scan for ssid and the previous connect command
+			 * in CSR.
+			 */
+			hdd_debug("Already disconnected or connect was in sme/roam pending list and removed by disconnect");
+		} else if (0 != status) {
+			hdd_err("sme_roam_disconnect failure, status: %d",
+				(int)status);
+			sta_ctx->sta_debug_state = status;
+			result = -EINVAL;
+			goto disconnected;
+		}
+
+		rc = wait_for_completion_timeout(&adapter->disconnect_comp_var,
+						 msecs_to_jiffies(wait_time));
+		if (!rc && (QDF_STATUS_CMD_NOT_QUEUED != status)) {
+			hdd_err("Sme disconnect event timed out session Id: %d sta_debug_state: %d",
+				adapter->session_id, sta_ctx->sta_debug_state);
+			result = -ETIMEDOUT;
+		}
+	} else if (eConnectionState_Disconnecting ==
+				sta_ctx->conn_info.connState) {
+		rc = wait_for_completion_timeout(&adapter->disconnect_comp_var,
+						 msecs_to_jiffies(wait_time));
+		if (!rc) {
+			hdd_err("Disconnect event timed out session Id: %d sta_debug_state: %d",
+				adapter->session_id, sta_ctx->sta_debug_state);
+			result = -ETIMEDOUT;
+		}
+	}
+disconnected:
+	hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
+	return result;
+}
+
+/**
+ * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
+ * @adapter: Pointer to the HDD adapter
+ * @req: Pointer to the structure cfg_connect_params receieved from user space
+ *
+ * This function will start reassociation if prev_bssid is set and bssid/
+ * bssid_hint, channel/channel_hint parameters are present in connect request.
+ *
+ * Return: 0 if connect was for ReAssociation, non-zero error code otherwise
+ */
+#if defined(CFG80211_CONNECT_PREV_BSSID) || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+static int wlan_hdd_reassoc_bssid_hint(struct hdd_adapter *adapter,
+					struct cfg80211_connect_params *req)
+{
+	int status = -EINVAL;
+	const uint8_t *bssid = NULL;
+	uint16_t channel = 0;
+	struct hdd_station_ctx *sta_ctx;
+
+	if (req->bssid)
+		bssid = req->bssid;
+	else if (req->bssid_hint)
+		bssid = req->bssid_hint;
+
+	if (req->channel)
+		channel = req->channel->hw_value;
+	else if (req->channel_hint)
+		channel = req->channel_hint->hw_value;
+
+	if (bssid && channel && req->prev_bssid) {
+		hdd_debug("REASSOC Attempt on channel %d to " MAC_ADDRESS_STR,
+			  channel, MAC_ADDR_ARRAY(bssid));
+		/*
+		 * Save BSSID in a separate variable as
+		 * roam_profile's BSSID is getting zeroed out in the
+		 * association process. In case of join failure
+		 * we should send valid BSSID to supplicant
+		 */
+		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		qdf_mem_copy(sta_ctx->requested_bssid.bytes, bssid,
+			     QDF_MAC_ADDR_SIZE);
+
+		status = hdd_reassoc(adapter, bssid, channel,
+				      CONNECT_CMD_USERSPACE);
+		hdd_debug("hdd_reassoc: status: %d", status);
+	}
+	return status;
+}
+#else
+static int wlan_hdd_reassoc_bssid_hint(struct hdd_adapter *adapter,
+					struct cfg80211_connect_params *req)
+{
+	return -ENOTSUPP;
+}
+#endif
+
+
+/**
+ * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
+ * connect in HT20 mode
+ * @hdd_ctx: hdd context
+ * @adapter: Pointer to the HDD adapter
+ * @req: Pointer to the structure cfg_connect_params receieved from user space
+ *
+ * This function will check if supplicant has indicated to to connect in HT20
+ * mode. this is currently applicable only for 2.4Ghz mode only.
+ * if feature is enabled and supplicant indicate HT20 set
+ * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
+ *
+ * Return: void
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+static void
+wlan_hdd_check_ht20_ht40_ind(struct hdd_context *hdd_ctx,
+			     struct hdd_adapter *adapter,
+			     struct cfg80211_connect_params *req)
+{
+	struct csr_roam_profile *roam_profile;
+
+	roam_profile = hdd_roam_profile(adapter);
+
+	roam_profile->force_24ghz_in_ht20 = false;
+
+	if (hdd_ctx->config->override_ht20_40_24g &&
+	    !(req->ht_capa.cap_info & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+		roam_profile->force_24ghz_in_ht20 = true;
+
+	hdd_debug("req->ht_capa.cap_info %x override_ht20_40_24g %d",
+		  req->ht_capa.cap_info,
+		  hdd_ctx->config->override_ht20_40_24g);
+}
+#else
+static inline void
+wlan_hdd_check_ht20_ht40_ind(struct hdd_context *hdd_ctx,
+			     struct hdd_adapter *adapter,
+			     struct cfg80211_connect_params *req)
+{
+	struct csr_roam_profile *roam_profile;
+
+	roam_profile = hdd_roam_profile(adapter);
+
+	roam_profile->force_24ghz_in_ht20 = false;
+}
+#endif
+
+/**
+ * __wlan_hdd_cfg80211_connect() - cfg80211 connect api
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @req: Pointer to cfg80211 connect request
+ *
+ * This function is used to start the association process
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
+				       struct net_device *ndev,
+				       struct cfg80211_connect_params *req)
+{
+	int status;
+	u16 channel;
+	const u8 *bssid = NULL;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
+	const u8 *bssid_hint = req->bssid_hint;
+#else
+	const u8 *bssid_hint = NULL;
+#endif
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_CONNECT,
+			 adapter->session_id, adapter->device_mode));
+	hdd_debug("Device_mode %s(%d)",
+		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
+
+	if (adapter->device_mode != QDF_STA_MODE &&
+	    adapter->device_mode != QDF_P2P_CLIENT_MODE) {
+		hdd_err("Device_mode %s(%d) is not supported",
+			qdf_opmode_str(adapter->device_mode),
+			adapter->device_mode);
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is null");
+		return -EINVAL;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return status;
+
+	if (req->bssid)
+		bssid = req->bssid;
+	else if (bssid_hint)
+		bssid = bssid_hint;
+
+	if (bssid && hdd_get_adapter_by_macaddr(hdd_ctx, (uint8_t *)bssid)) {
+		hdd_err("adapter exist with same mac address " MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(bssid));
+		return -EINVAL;
+	}
+
+	/*
+	 * Check if this is reassoc to same bssid, if reassoc is success, return
+	 */
+	status = wlan_hdd_reassoc_bssid_hint(adapter, req);
+	if (!status) {
+		hdd_set_roaming_in_progress(true);
+		return status;
+	}
+
+	/* Try disconnecting if already in connected state */
+	status = wlan_hdd_try_disconnect(adapter);
+	if (0 > status) {
+		hdd_err("Failed to disconnect the existing connection");
+		return -EALREADY;
+	}
+
+	/*initialise security parameters */
+	status = wlan_hdd_cfg80211_set_privacy(adapter, req);
+
+	if (status < 0) {
+		hdd_err("Failed to set security params");
+		return status;
+	}
+
+	/*
+	 * Check for max concurrent connections after doing disconnect if any,
+	 * must be called after the invocation of wlan_hdd_cfg80211_set_privacy
+	 * so privacy is already set for the current adapter before it's
+	 * checked against concurrency.
+	 */
+	if (req->channel) {
+		bool ok = false;
+
+		if (req->channel->hw_value && policy_mgr_is_chan_ok_for_dnbs(
+						hdd_ctx->psoc,
+						req->channel->hw_value,
+						&ok)) {
+			hdd_warn("Unable to get channel:%d eligibility for DNBS",
+					req->channel->hw_value);
+			return -EINVAL;
+		}
+		/**
+		 * Send connection timedout, so that Android framework does not
+		 * blacklist us.
+		 */
+		if (!ok) {
+			struct ieee80211_channel *chan =
+				ieee80211_get_channel(wiphy,
+				wlan_chan_to_freq(req->channel->hw_value));
+			struct cfg80211_bss *bss;
+
+			hdd_warn("Channel:%d not OK for DNBS",
+				req->channel->hw_value);
+			if (chan) {
+				bss = hdd_cfg80211_get_bss(wiphy,
+							chan,
+							req->bssid, req->ssid,
+							req->ssid_len);
+				if (bss) {
+					cfg80211_assoc_timeout(ndev, bss);
+					return -ETIMEDOUT;
+				}
+			}
+			return -EINVAL;
+		}
+
+		if (!policy_mgr_allow_concurrency(hdd_ctx->psoc,
+				policy_mgr_convert_device_mode_to_qdf_type(
+				adapter->device_mode),
+				req->channel->hw_value, HW_MODE_20_MHZ)) {
+			hdd_warn("This concurrency combination is not allowed");
+			status = -ECONNREFUSED;
+			goto con_chk_failed;
+		}
+	} else {
+		if (!policy_mgr_allow_concurrency(hdd_ctx->psoc,
+				policy_mgr_convert_device_mode_to_qdf_type(
+				adapter->device_mode), 0, HW_MODE_20_MHZ)) {
+			hdd_warn("This concurrency combination is not allowed");
+			status = -ECONNREFUSED;
+			goto con_chk_failed;
+		}
+	}
+
+	if (req->channel)
+		channel = req->channel->hw_value;
+	else
+		channel = 0;
+
+	wlan_hdd_check_ht20_ht40_ind(hdd_ctx, adapter, req);
+
+	status = wlan_hdd_cfg80211_connect_start(adapter, req->ssid,
+						 req->ssid_len, req->bssid,
+						 bssid_hint, channel, 0);
+	if (0 > status)
+		hdd_err("connect failed");
+
+	return status;
+
+con_chk_failed:
+	wlan_hdd_cfg80211_clear_privacy(adapter);
+	hdd_exit();
+	return status;
+}
+
+/**
+ * wlan_hdd_cfg80211_connect() - cfg80211 connect api
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @req: Pointer to cfg80211 connect request
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
+				     struct net_device *ndev,
+				     struct cfg80211_connect_params *req)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason)
+{
+	QDF_STATUS status;
+	int result = 0;
+	unsigned long rc;
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	eConnectionState prev_conn_state;
+	mac_handle_t mac_handle;
+	uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
+
+	hdd_enter();
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (adapter->device_mode ==  QDF_STA_MODE) {
+		hdd_debug("Stop firmware roaming");
+		status = sme_stop_roaming(mac_handle, adapter->session_id,
+					  eCsrForcedDisassoc);
+		/*
+		 * If firmware has already started roaming process, driver
+		 * needs to wait for processing of this disconnect request.
+		 *
+		 */
+		INIT_COMPLETION(adapter->roaming_comp_var);
+		if (hdd_is_roaming_in_progress(hdd_ctx)) {
+			rc = wait_for_completion_timeout(
+				&adapter->roaming_comp_var,
+				msecs_to_jiffies(WLAN_WAIT_TIME_STOP_ROAM));
+			if (!rc) {
+				hdd_err("roaming comp var timed out session Id: %d",
+					adapter->session_id);
+			}
+			if (adapter->roam_ho_fail) {
+				INIT_COMPLETION(adapter->disconnect_comp_var);
+				hdd_debug("Disabling queues");
+				wlan_hdd_netif_queue_control(adapter,
+					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+					WLAN_CONTROL_PATH);
+				hdd_conn_set_connection_state(adapter,
+						eConnectionState_Disconnecting);
+				goto wait_for_disconnect;
+			}
+		}
+	}
+
+	prev_conn_state = sta_ctx->conn_info.connState;
+	/*stop tx queues */
+	hdd_info("Disabling queues");
+	wlan_hdd_netif_queue_control(adapter,
+		WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH);
+	hdd_debug("Set HDD connState to eConnectionState_Disconnecting");
+	hdd_conn_set_connection_state(adapter, eConnectionState_Disconnecting);
+
+	INIT_COMPLETION(adapter->disconnect_comp_var);
+
+	/* issue disconnect */
+
+	status = sme_roam_disconnect(mac_handle,
+				     adapter->session_id, reason);
+	if ((QDF_STATUS_CMD_NOT_QUEUED == status) &&
+			prev_conn_state != eConnectionState_Connecting) {
+		hdd_debug("status = %d, already disconnected", status);
+		result = 0;
+		/*
+		 * Wait here instead of returning directly. This will block the
+		 * next connect command and allow processing of the disconnect
+		 * in SME else we might hit some race conditions leading to SME
+		 * and HDD out of sync. As disconnect is already in progress,
+		 * wait here for 1 sec instead of 5 sec.
+		 */
+		wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
+	} else if (QDF_STATUS_CMD_NOT_QUEUED == status) {
+		/*
+		 * Wait here instead of returning directly, this will block the
+		 * next connect command and allow processing of the scan for
+		 * ssid and the previous connect command in CSR. Else we might
+		 * hit some race conditions leading to SME and HDD out of sync.
+		 */
+		hdd_debug("Already disconnected or connect was in sme/roam pending list and removed by disconnect");
+	} else if (0 != status) {
+		hdd_err("csr_roam_disconnect failure, status: %d", (int)status);
+		sta_ctx->sta_debug_state = status;
+		result = -EINVAL;
+		goto disconnected;
+	}
+wait_for_disconnect:
+	rc = wait_for_completion_timeout(&adapter->disconnect_comp_var,
+					 msecs_to_jiffies(wait_time));
+
+	if (!rc && (QDF_STATUS_CMD_NOT_QUEUED != status)) {
+		hdd_err("Failed to disconnect, timed out");
+		result = -ETIMEDOUT;
+	}
+disconnected:
+	hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
+	/* Sending disconnect event to userspace for kernel version < 3.11
+	 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
+	 */
+	hdd_debug("Send disconnected event to userspace");
+	wlan_hdd_cfg80211_indicate_disconnect(adapter->dev, true,
+						WLAN_REASON_UNSPECIFIED);
+#endif
+
+	return result;
+}
+
+/**
+ * hdd_ieee80211_reason_code_to_str() - return string conversion of reason code
+ * @reason: ieee80211 reason code.
+ *
+ * This utility function helps log string conversion of reason code.
+ *
+ * Return: string conversion of reason code, if match found;
+ *         "Unknown" otherwise.
+ */
+static const char *hdd_ieee80211_reason_code_to_str(uint16_t reason)
+{
+	switch (reason) {
+	CASE_RETURN_STRING(WLAN_REASON_UNSPECIFIED);
+	CASE_RETURN_STRING(WLAN_REASON_PREV_AUTH_NOT_VALID);
+	CASE_RETURN_STRING(WLAN_REASON_DEAUTH_LEAVING);
+	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
+	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_AP_BUSY);
+	CASE_RETURN_STRING(WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
+	CASE_RETURN_STRING(WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
+	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_STA_HAS_LEFT);
+	CASE_RETURN_STRING(WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH);
+	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_BAD_POWER);
+	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_BAD_SUPP_CHAN);
+	CASE_RETURN_STRING(WLAN_REASON_INVALID_IE);
+	CASE_RETURN_STRING(WLAN_REASON_MIC_FAILURE);
+	CASE_RETURN_STRING(WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT);
+	CASE_RETURN_STRING(WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT);
+	CASE_RETURN_STRING(WLAN_REASON_IE_DIFFERENT);
+	CASE_RETURN_STRING(WLAN_REASON_INVALID_GROUP_CIPHER);
+	CASE_RETURN_STRING(WLAN_REASON_INVALID_PAIRWISE_CIPHER);
+	CASE_RETURN_STRING(WLAN_REASON_INVALID_AKMP);
+	CASE_RETURN_STRING(WLAN_REASON_UNSUPP_RSN_VERSION);
+	CASE_RETURN_STRING(WLAN_REASON_INVALID_RSN_IE_CAP);
+	CASE_RETURN_STRING(WLAN_REASON_IEEE8021X_FAILED);
+	CASE_RETURN_STRING(WLAN_REASON_CIPHER_SUITE_REJECTED);
+	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_UNSPECIFIED_QOS);
+	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH);
+	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_LOW_ACK);
+	CASE_RETURN_STRING(WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP);
+	CASE_RETURN_STRING(WLAN_REASON_QSTA_LEAVE_QBSS);
+	CASE_RETURN_STRING(WLAN_REASON_QSTA_NOT_USE);
+	CASE_RETURN_STRING(WLAN_REASON_QSTA_REQUIRE_SETUP);
+	CASE_RETURN_STRING(WLAN_REASON_QSTA_TIMEOUT);
+	CASE_RETURN_STRING(WLAN_REASON_QSTA_CIPHER_NOT_SUPP);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_PEER_CANCELED);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_MAX_PEERS);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_CONFIG);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_CLOSE);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_MAX_RETRIES);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_INVALID_GTK);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_INCONSISTENT_PARAM);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_INVALID_SECURITY);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_ERROR);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_NOFORWARD);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE);
+	CASE_RETURN_STRING(WLAN_REASON_MAC_EXISTS_IN_MBSS);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_CHAN_REGULATORY);
+	CASE_RETURN_STRING(WLAN_REASON_MESH_CHAN);
+	default:
+		return "Unknown";
+	}
+}
+
+/**
+ * hdd_print_netdev_txq_status() - print netdev tx queue status
+ * @dev: Pointer to network device
+ *
+ * This function is used to print netdev tx queue status
+ *
+ * Return: none
+ */
+static void hdd_print_netdev_txq_status(struct net_device *dev)
+{
+	unsigned int i;
+
+	if (!dev)
+		return;
+
+	for (i = 0; i < dev->num_tx_queues; i++) {
+		struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
+
+		hdd_debug("netdev tx queue[%u] state: 0x%lx", i, txq->state);
+	}
+}
+
+/**
+ * __wlan_hdd_cfg80211_disconnect() - cfg80211 disconnect api
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @reason: Disconnect reason code
+ *
+ * This function is used to issue a disconnect request to SME
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy,
+					  struct net_device *dev, u16 reason)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int status;
+	struct hdd_station_ctx *sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_DISCONNECT,
+			 adapter->session_id, reason));
+	hdd_print_netdev_txq_status(dev);
+	hdd_debug("Device_mode %s(%d) reason code(%d)",
+		  qdf_opmode_str(adapter->device_mode),
+		  adapter->device_mode, reason);
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	qdf_mutex_acquire(&adapter->disconnection_status_lock);
+	if (adapter->disconnection_in_progress) {
+		qdf_mutex_release(&adapter->disconnection_status_lock);
+		hdd_debug("Disconnect is already in progress");
+		return 0;
+	}
+	adapter->disconnection_in_progress = true;
+	qdf_mutex_release(&adapter->disconnection_status_lock);
+
+	/* Issue disconnect request to SME, if station is in connected state */
+	if ((sta_ctx->conn_info.connState == eConnectionState_Associated) ||
+	    (sta_ctx->conn_info.connState == eConnectionState_Connecting)) {
+		eCsrRoamDisconnectReason reasonCode =
+			eCSR_DISCONNECT_REASON_UNSPECIFIED;
+
+		switch (reason) {
+		case WLAN_REASON_MIC_FAILURE:
+			reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
+			break;
+
+		case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
+		case WLAN_REASON_DISASSOC_AP_BUSY:
+		case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
+			reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
+			break;
+
+		case WLAN_REASON_PREV_AUTH_NOT_VALID:
+		case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
+			reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
+			break;
+
+		case WLAN_REASON_DEAUTH_LEAVING:
+			reasonCode =
+				hdd_ctx->config->
+				gEnableDeauthToDisassocMap ?
+				eCSR_DISCONNECT_REASON_STA_HAS_LEFT :
+				eCSR_DISCONNECT_REASON_DEAUTH;
+			qdf_dp_trace_dump_all(
+				WLAN_DEAUTH_DPTRACE_DUMP_COUNT,
+				QDF_TRACE_DEFAULT_PDEV_ID);
+			break;
+		case WLAN_REASON_DISASSOC_STA_HAS_LEFT:
+			reasonCode = eCSR_DISCONNECT_REASON_STA_HAS_LEFT;
+			break;
+		default:
+			reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
+			break;
+		}
+		if (ucfg_scan_get_vdev_status(adapter->vdev) !=
+				SCAN_NOT_IN_PROGRESS) {
+			hdd_debug("Disconnect is in progress, Aborting Scan");
+			wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
+					adapter->session_id, INVALID_SCAN_ID,
+					false);
+		}
+		wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
+		/* First clean up the tdls peers if any */
+		hdd_notify_sta_disconnect(adapter->session_id,
+			  false, true, adapter->vdev);
+
+		hdd_info("Disconnect from userspace; reason:%d (%s)",
+			 reason, hdd_ieee80211_reason_code_to_str(reason));
+		status = wlan_hdd_disconnect(adapter, reasonCode);
+		if (0 != status) {
+			hdd_err("wlan_hdd_disconnect failed, status: %d", status);
+			hdd_set_disconnect_status(adapter, false);
+			return -EINVAL;
+		}
+	} else {
+		hdd_err("Unexpected cfg disconnect called while in state: %d",
+		       sta_ctx->conn_info.connState);
+		hdd_set_disconnect_status(adapter, false);
+	}
+
+	return status;
+}
+
+/**
+ * wlan_hdd_cfg80211_disconnect() - cfg80211 disconnect api
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @reason: Disconnect reason code
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy,
+					struct net_device *dev, u16 reason)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_privacy_ibss() - set ibss privacy
+ * @adapter: Pointer to adapter
+ * @param: Pointer to IBSS parameters
+ *
+ * This function is used to initialize the security settings in IBSS mode
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_set_privacy_ibss(struct hdd_adapter *adapter,
+					      struct cfg80211_ibss_params
+					      *params)
+{
+	uint32_t ret;
+	int status = 0;
+	eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
+	struct hdd_station_ctx *sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct csr_roam_profile *roam_profile;
+
+	hdd_enter();
+
+	sta_ctx->wpa_versions = 0;
+	qdf_mem_zero(&sta_ctx->ibss_enc_key, sizeof(tCsrRoamSetKey));
+	sta_ctx->ibss_enc_key_installed = 0;
+
+	if (params->ie_len && (NULL != params->ie)) {
+		if (wlan_get_ie_ptr_from_eid(WLAN_EID_RSN, params->ie,
+					     params->ie_len)) {
+			sta_ctx->wpa_versions = NL80211_WPA_VERSION_2;
+			encryptionType = eCSR_ENCRYPT_TYPE_AES;
+		} else if (hdd_is_wpaie_present(params->ie, params->ie_len)) {
+			tDot11fIEWPA dot11WPAIE;
+			mac_handle_t mac_handle =
+				hdd_adapter_get_mac_handle(adapter);
+			const u8 *ie;
+
+			memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
+			ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_WPA,
+						params->ie, params->ie_len);
+			if (NULL != ie) {
+				sta_ctx->wpa_versions = NL80211_WPA_VERSION_1;
+				/* Unpack the WPA IE
+				 * Skip past the EID byte and length byte
+				 * and four byte WiFi OUI
+				 */
+				if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
+				    ie[1] > DOT11F_IE_WPA_MAX_LEN) {
+					hdd_err("invalid ie len:%d", ie[1]);
+					return -EINVAL;
+				}
+				ret = dot11f_unpack_ie_wpa(
+						(tpAniSirGlobal) mac_handle,
+						(uint8_t *)&ie[2 + 4],
+						ie[1] - 4, &dot11WPAIE, false);
+				if (DOT11F_FAILED(ret)) {
+					hdd_err("unpack failed ret: 0x%x", ret);
+					return -EINVAL;
+				}
+				/*
+				 * Extract the multicast cipher, the
+				 * encType for unicast cipher for
+				 * wpa-none is none
+				 */
+				encryptionType =
+					hdd_translate_wpa_to_csr_encryption_type
+						(dot11WPAIE.multicast_cipher);
+			}
+		}
+
+		status =
+			wlan_hdd_cfg80211_set_ie(adapter, params->ie,
+						 params->ie_len);
+
+		if (0 > status) {
+			hdd_err("Failed to parse WPA/RSN IE");
+			return status;
+		}
+	}
+
+	roam_profile = hdd_roam_profile(adapter);
+	roam_profile->AuthType.authType[0] =
+		sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+
+	if (params->privacy) {
+		/* Security enabled IBSS, At this time there is no information
+		 * available about the security parameters, so initialise the
+		 * encryption type to eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
+		 * The correct security parameters will be updated later in
+		 * wlan_hdd_cfg80211_add_key Hal expects encryption type to be
+		 * set inorder enable privacy bit in beacons
+		 */
+
+		encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
+	}
+	hdd_debug("encryptionType=%d", encryptionType);
+	sta_ctx->conn_info.ucEncryptionType = encryptionType;
+	roam_profile->EncryptionType.numEntries = 1;
+	roam_profile->EncryptionType.encryptionType[0] =
+		encryptionType;
+	return status;
+}
+
+/**
+ * __wlan_hdd_cfg80211_join_ibss() - join ibss
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @param: Pointer to IBSS join parameters
+ *
+ * This function is used to create/join an IBSS network
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy,
+					 struct net_device *dev,
+					 struct cfg80211_ibss_params *params)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct csr_roam_profile *roam_profile;
+	int status;
+	struct hdd_station_ctx *sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct qdf_mac_addr bssid;
+	u8 channelNum = 0;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
+			 adapter->session_id, adapter->device_mode));
+	hdd_debug("Device_mode %s(%d)",
+		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (NULL !=
+		params->chandef.chan) {
+		uint32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+		uint8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+		int indx;
+
+		/* Get channel number */
+		channelNum = ieee80211_frequency_to_channel(
+			params->
+			chandef.
+			chan->
+			center_freq);
+
+		if (0 != sme_cfg_get_str(mac_handle, WNI_CFG_VALID_CHANNEL_LIST,
+					 validChan, &numChans)) {
+			hdd_err("No valid channel list");
+			return -EOPNOTSUPP;
+		}
+
+		for (indx = 0; indx < numChans; indx++) {
+			if (channelNum == validChan[indx])
+				break;
+		}
+		if (indx >= numChans) {
+			hdd_err("Not valid Channel: %d", channelNum);
+			return -EINVAL;
+		}
+	}
+
+	if (!policy_mgr_allow_concurrency(hdd_ctx->psoc,
+		PM_IBSS_MODE, channelNum, HW_MODE_20_MHZ)) {
+		hdd_err("This concurrency combination is not allowed");
+		return -ECONNREFUSED;
+	}
+
+	status = policy_mgr_reset_connection_update(hdd_ctx->psoc);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("qdf_reset_connection_update failed status: %d", status);
+
+	status = policy_mgr_current_connections_update(hdd_ctx->psoc,
+					adapter->session_id, channelNum,
+					POLICY_MGR_UPDATE_REASON_JOIN_IBSS);
+	if (QDF_STATUS_E_FAILURE == status) {
+		hdd_err("connections update failed!!");
+		return -EINVAL;
+	}
+
+	if (QDF_STATUS_SUCCESS == status) {
+		status = policy_mgr_wait_for_connection_update(
+			hdd_ctx->psoc);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("qdf wait for event failed!!");
+			return -EINVAL;
+		}
+	}
+
+	/*Try disconnecting if already in connected state */
+	status = wlan_hdd_try_disconnect(adapter);
+	if (0 > status) {
+		hdd_err("Failed to disconnect the existing IBSS connection");
+		return -EALREADY;
+	}
+
+	roam_profile = hdd_roam_profile(adapter);
+
+	if (eCSR_BSS_TYPE_START_IBSS != roam_profile->BSSType) {
+		hdd_err("Interface type is not set to IBSS");
+		return -EINVAL;
+	}
+
+	/* enable selected protection checks in IBSS mode */
+	roam_profile->cfg_protection = IBSS_CFG_PROTECTION_ENABLE_MASK;
+
+	if (QDF_STATUS_E_FAILURE == sme_cfg_set_int(mac_handle,
+						    WNI_CFG_IBSS_ATIM_WIN_SIZE,
+						    hdd_ctx->config->
+						    ibssATIMWinSize)) {
+		hdd_err("Could not pass on WNI_CFG_IBSS_ATIM_WIN_SIZE to CCM");
+	}
+
+	/* BSSID is provided by upper layers hence no need to AUTO generate */
+	if (NULL != params->bssid) {
+		if (sme_cfg_set_int(mac_handle, WNI_CFG_IBSS_AUTO_BSSID, 0)
+				== QDF_STATUS_E_FAILURE) {
+			hdd_err("ccmCfgStInt failed for WNI_CFG_IBSS_AUTO_BSSID");
+			return -EIO;
+		}
+		qdf_mem_copy(bssid.bytes, params->bssid, QDF_MAC_ADDR_SIZE);
+	} else if (hdd_ctx->config->isCoalesingInIBSSAllowed == 0) {
+		if (sme_cfg_set_int(mac_handle, WNI_CFG_IBSS_AUTO_BSSID, 0)
+				== QDF_STATUS_E_FAILURE) {
+			hdd_err("ccmCfgStInt failed for WNI_CFG_IBSS_AUTO_BSSID");
+			return -EIO;
+		}
+		qdf_copy_macaddr(&bssid, &hdd_ctx->config->IbssBssid);
+	}
+
+	if (cfg_in_range(CFG_BEACON_INTERVAL, params->beacon_interval))
+		roam_profile->beaconInterval = params->beacon_interval;
+	else
+		roam_profile->beaconInterval = cfg_get(hdd_ctx->psoc,
+						       CFG_BEACON_INTERVAL);
+
+	/* Set Channel */
+	if (channelNum)	{
+		/* Set the Operational Channel */
+		hdd_debug("set channel %d", channelNum);
+		roam_profile->ChannelInfo.numOfChannels = 1;
+		sta_ctx->conn_info.operationChannel = channelNum;
+		roam_profile->ChannelInfo.ChannelList =
+			&sta_ctx->conn_info.operationChannel;
+	}
+
+	/* Initialize security parameters */
+	status = wlan_hdd_cfg80211_set_privacy_ibss(adapter, params);
+	if (status < 0) {
+		hdd_err("failed to set security parameters");
+		return status;
+	}
+
+	/* Issue connect start */
+	status = wlan_hdd_cfg80211_connect_start(adapter, params->ssid,
+						 params->ssid_len,
+						 bssid.bytes, NULL,
+						 sta_ctx->conn_info.
+						 operationChannel,
+						 params->chandef.width);
+
+	if (0 > status) {
+		hdd_err("connect failed");
+		return status;
+	}
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_join_ibss() - join ibss
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @param: Pointer to IBSS join parameters
+ *
+ * This function is used to create/join an IBSS network
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy,
+				       struct net_device *dev,
+				       struct cfg80211_ibss_params *params)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_leave_ibss() - leave ibss
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ *
+ * This function is used to leave an IBSS network
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy,
+					  struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct csr_roam_profile *roam_profile;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int status;
+	mac_handle_t mac_handle;
+	unsigned long rc;
+	tSirUpdateIE updateIE;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
+			 adapter->session_id,
+			 eCSR_DISCONNECT_REASON_IBSS_LEAVE));
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return status;
+
+	hdd_debug("Device_mode %s(%d)",
+		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
+
+	roam_profile = hdd_roam_profile(adapter);
+
+	/* Issue disconnect only if interface type is set to IBSS */
+	if (eCSR_BSS_TYPE_START_IBSS != roam_profile->BSSType) {
+		hdd_err("BSS Type is not set to IBSS");
+		return -EINVAL;
+	}
+	/* Clearing add IE of beacon */
+	qdf_mem_copy(updateIE.bssid.bytes, adapter->mac_addr.bytes,
+		     sizeof(tSirMacAddr));
+	updateIE.smeSessionId = adapter->session_id;
+	updateIE.ieBufferlength = 0;
+	updateIE.pAdditionIEBuffer = NULL;
+	updateIE.append = true;
+	updateIE.notify = true;
+	mac_handle = hdd_ctx->mac_handle;
+	if (sme_update_add_ie(mac_handle,
+			      &updateIE,
+			      eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) {
+		hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
+	}
+
+	/* Reset WNI_CFG_PROBE_RSP Flags */
+	wlan_hdd_reset_prob_rspies(adapter);
+
+	/* Issue Disconnect request */
+	INIT_COMPLETION(adapter->disconnect_comp_var);
+	status = sme_roam_disconnect(mac_handle,
+				     adapter->session_id,
+				     eCSR_DISCONNECT_REASON_IBSS_LEAVE);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_roam_disconnect failed status: %d",
+		       status);
+		return -EAGAIN;
+	}
+
+	/* wait for mc thread to cleanup and then return to upper stack
+	 * so by the time upper layer calls the change interface, we are
+	 * all set to proceed further
+	 */
+	rc = wait_for_completion_timeout(&adapter->disconnect_comp_var,
+			msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
+	if (!rc) {
+		hdd_err("Failed to disconnect, timed out");
+		return -ETIMEDOUT;
+	}
+
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_leave_ibss() - leave ibss
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ *
+ * This function is used to leave an IBSS network
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy,
+					struct net_device *dev)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_wiphy_params() - set wiphy parameters
+ * @wiphy: Pointer to wiphy
+ * @changed: Parameters changed
+ *
+ * This function is used to set the phy parameters. RTS Threshold/FRAG
+ * Threshold/Retry Count etc.
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
+						u32 changed)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int status;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
+			 NO_SESSION, wiphy->rts_threshold));
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+		u32 rts_threshold = (wiphy->rts_threshold == -1) ?
+				     cfg_max(CFG_RTS_THRESHOLD) :
+				     wiphy->rts_threshold;
+
+		if ((cfg_min(CFG_RTS_THRESHOLD) > rts_threshold) ||
+		    (cfg_max(CFG_RTS_THRESHOLD) < rts_threshold)) {
+			hdd_err("Invalid RTS Threshold value: %u",
+				rts_threshold);
+			return -EINVAL;
+		}
+
+		if (0 != ucfg_mlme_set_rts_threshold(hdd_ctx->psoc,
+		    rts_threshold)) {
+			hdd_err("mlme_set_rts_threshold failed for val %u",
+				rts_threshold);
+			return -EIO;
+		}
+
+		hdd_debug("set rts threshold %u", rts_threshold);
+	}
+
+	if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
+		u16 frag_threshold = (wiphy->frag_threshold == -1) ?
+				     cfg_max(CFG_FRAG_THRESHOLD) :
+				     wiphy->frag_threshold;
+
+		if ((cfg_min(CFG_FRAG_THRESHOLD) > frag_threshold) ||
+		    (cfg_max(CFG_FRAG_THRESHOLD) < frag_threshold)) {
+			hdd_err("Invalid frag_threshold value %hu",
+				frag_threshold);
+			return -EINVAL;
+		}
+
+		if (0 != ucfg_mlme_set_frag_threshold(hdd_ctx->psoc,
+						      frag_threshold)) {
+			hdd_err("mlme_set_frag_threshold failed for val %hu",
+				frag_threshold);
+			return -EIO;
+		}
+
+		hdd_debug("set frag threshold %hu", frag_threshold);
+	}
+
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_wiphy_params() - set wiphy parameters
+ * @wiphy: Pointer to wiphy
+ * @changed: Parameters changed
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_set_default_mgmt_key() - dummy implementation of set default mgmt
+ *				     key
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @key_index: Key index
+ *
+ * Return: 0
+ */
+static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
+					 struct net_device *netdev,
+					 u8 key_index)
+{
+	hdd_enter();
+	return 0;
+}
+
+/**
+ * wlan_hdd_set_default_mgmt_key() - SSR wrapper for
+ *				wlan_hdd_set_default_mgmt_key
+ * @wiphy: pointer to wiphy
+ * @netdev: pointer to net_device structure
+ * @key_index: key index
+ *
+ * Return: 0 on success, error number on failure
+ */
+static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
+					   struct net_device *netdev,
+					   u8 key_index)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_set_txq_params() - dummy implementation of set tx queue params
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @params: Pointer to tx queue parameters
+ *
+ * Return: 0
+ */
+static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
+				   struct net_device *dev,
+				   struct ieee80211_txq_params *params)
+{
+	hdd_enter();
+	return 0;
+}
+
+/**
+ * wlan_hdd_set_txq_params() - SSR wrapper for wlan_hdd_set_txq_params
+ * @wiphy: pointer to wiphy
+ * @netdev: pointer to net_device structure
+ * @params: pointer to ieee80211_txq_params
+ *
+ * Return: 0 on success, error number on failure
+ */
+static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
+				   struct net_device *dev,
+				   struct ieee80211_txq_params *params)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_del_station() - delete station v2
+ * @wiphy: Pointer to wiphy
+ * @param: Pointer to delete station parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static
+int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
+				    struct net_device *dev,
+				    struct csr_del_sta_params *pDelStaParams)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	struct hdd_hostapd_state *hapd_state;
+	int status;
+	uint8_t staId;
+	uint8_t *mac;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_DEL_STA,
+			 adapter->session_id, adapter->device_mode));
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	mac = (uint8_t *) pDelStaParams->peerMacAddr.bytes;
+	mac_handle = hdd_ctx->mac_handle;
+
+	if ((QDF_SAP_MODE == adapter->device_mode) ||
+	    (QDF_P2P_GO_MODE == adapter->device_mode)) {
+
+		hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+		if (!hapd_state) {
+			hdd_err("Hostapd State is Null");
+			return 0;
+		}
+
+		if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *) mac)) {
+			uint16_t i;
+
+			for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
+				if ((adapter->sta_info[i].in_use) &&
+				    (!adapter->sta_info[i].
+				     is_deauth_in_progress)) {
+					qdf_mem_copy(
+						mac,
+						adapter->sta_info[i].
+							sta_mac.bytes,
+						QDF_MAC_ADDR_SIZE);
+
+					hdd_debug("Delete STA with MAC::"
+						  MAC_ADDRESS_STR,
+					       MAC_ADDR_ARRAY(mac));
+
+					if (hdd_ctx->dev_dfs_cac_status ==
+							DFS_CAC_IN_PROGRESS)
+						goto fn_end;
+
+					qdf_event_reset(&hapd_state->qdf_sta_disassoc_event);
+					hdd_softap_sta_disassoc(adapter,
+								pDelStaParams);
+					qdf_status =
+						hdd_softap_sta_deauth(adapter,
+							pDelStaParams);
+					if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
+						adapter->sta_info[i].
+						is_deauth_in_progress = true;
+						qdf_status =
+							qdf_wait_for_event_completion(
+							 &hapd_state->
+							 qdf_sta_disassoc_event,
+							 SME_CMD_TIMEOUT_VALUE);
+						if (!QDF_IS_STATUS_SUCCESS(
+								qdf_status))
+							hdd_warn("Deauth wait time expired");
+					}
+				}
+			}
+		} else {
+			qdf_status =
+				hdd_softap_get_sta_id(adapter,
+					      (struct qdf_mac_addr *) mac,
+					      &staId);
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+				hdd_debug("Skip DEL STA as this is not used::"
+					  MAC_ADDRESS_STR,
+				       MAC_ADDR_ARRAY(mac));
+				return -ENOENT;
+			}
+
+			if (adapter->sta_info[staId].is_deauth_in_progress ==
+			    true) {
+				hdd_debug("Skip DEL STA as deauth is in progress::"
+					  MAC_ADDRESS_STR,
+					  MAC_ADDR_ARRAY(mac));
+				return -ENOENT;
+			}
+
+			adapter->sta_info[staId].is_deauth_in_progress = true;
+
+			hdd_debug("Delete STA with MAC::" MAC_ADDRESS_STR,
+			       MAC_ADDR_ARRAY(mac));
+
+			/* Case: SAP in ACS selected DFS ch and client connected
+			 * Now Radar detected. Then if random channel is another
+			 * DFS ch then new CAC is initiated and no TX allowed.
+			 * So do not send any mgmt frames as it will timeout
+			 * during CAC.
+			 */
+
+			if (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS)
+				goto fn_end;
+
+			qdf_event_reset(&hapd_state->qdf_sta_disassoc_event);
+			sme_send_disassoc_req_frame(mac_handle,
+					adapter->session_id,
+					(uint8_t *)&pDelStaParams->peerMacAddr,
+					pDelStaParams->reason_code, 0);
+			qdf_status = hdd_softap_sta_deauth(adapter,
+							   pDelStaParams);
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+				adapter->sta_info[staId].is_deauth_in_progress =
+					false;
+				hdd_debug("STA removal failed for ::"
+					  MAC_ADDRESS_STR,
+				       MAC_ADDR_ARRAY(mac));
+				return -ENOENT;
+			}
+			qdf_status = qdf_wait_for_event_completion(
+					&hapd_state->
+					qdf_sta_disassoc_event,
+					SME_CMD_TIMEOUT_VALUE);
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+				hdd_warn("Deauth wait time expired");
+
+		}
+	}
+
+fn_end:
+	hdd_exit();
+	return 0;
+}
+
+#if defined(USE_CFG80211_DEL_STA_V2)
+/**
+ * wlan_hdd_del_station() - delete station wrapper
+ * @adapter: pointer to the hdd adapter
+ *
+ * Return: None
+ */
+void wlan_hdd_del_station(struct hdd_adapter *adapter)
+{
+	struct station_del_parameters del_sta;
+
+	del_sta.mac = NULL;
+	del_sta.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
+	del_sta.reason_code = eCsrForcedDeauthSta;
+
+	wlan_hdd_cfg80211_del_station(adapter->wdev.wiphy, adapter->dev,
+				      &del_sta);
+}
+#else
+void wlan_hdd_del_station(struct hdd_adapter *adapter)
+{
+	wlan_hdd_cfg80211_del_station(adapter->wdev.wiphy, adapter->dev, NULL);
+}
+#endif
+
+#if defined(USE_CFG80211_DEL_STA_V2)
+/**
+ * wlan_hdd_cfg80211_del_station() - delete station v2
+ * @wiphy: Pointer to wiphy
+ * @param: Pointer to delete station parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
+				  struct net_device *dev,
+				  struct station_del_parameters *param)
+#else
+/**
+ * wlan_hdd_cfg80211_del_station() - delete station
+ * @wiphy: Pointer to wiphy
+ * @mac: Pointer to station mac address
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
+				  struct net_device *dev,
+				  const uint8_t *mac)
+#else
+int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
+				  struct net_device *dev,
+				  uint8_t *mac)
+#endif
+#endif
+{
+	int ret;
+	struct csr_del_sta_params delStaParams;
+
+	cds_ssr_protect(__func__);
+#if defined(USE_CFG80211_DEL_STA_V2)
+	if (NULL == param) {
+		hdd_err("Invalid argument passed");
+		return -EINVAL;
+	}
+	wlansap_populate_del_sta_params(param->mac, param->reason_code,
+					param->subtype, &delStaParams);
+#else
+	wlansap_populate_del_sta_params(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
+					(SIR_MAC_MGMT_DEAUTH >> 4),
+					&delStaParams);
+#endif
+	ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_add_station() - add station
+ * @wiphy: Pointer to wiphy
+ * @mac: Pointer to station mac address
+ * @pmksa: Pointer to add station parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
+					   struct net_device *dev,
+					   const uint8_t *mac,
+					   struct station_parameters *params)
+{
+	int status = -EPERM;
+#ifdef FEATURE_WLAN_TDLS
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	u32 mask, set;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_ADD_STA,
+			 adapter->session_id, params->listen_interval));
+
+	if (0 != wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	mask = params->sta_flags_mask;
+
+	set = params->sta_flags_set;
+
+	hdd_debug("mask 0x%x set 0x%x " MAC_ADDRESS_STR, mask, set,
+		MAC_ADDR_ARRAY(mac));
+
+	if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
+		if (set & BIT(NL80211_STA_FLAG_TDLS_PEER))
+			status = wlan_cfg80211_tdls_add_peer(hdd_ctx->pdev,
+							     dev, mac);
+	}
+#endif
+	hdd_exit();
+	return status;
+}
+
+/**
+ * wlan_hdd_cfg80211_add_station() - add station
+ * @wiphy: Pointer to wiphy
+ * @mac: Pointer to station mac address
+ * @pmksa: Pointer to add station parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
+					 struct net_device *dev,
+					 const uint8_t *mac,
+					 struct station_parameters *params)
+#else
+static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
+					 struct net_device *dev, uint8_t *mac,
+					 struct station_parameters *params)
+#endif
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
+	 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
+/*
+ * wlan_hdd_is_pmksa_valid: API to validate pmksa
+ * @pmksa: pointer to cfg80211_pmksa structure
+ *
+ * Return: True if valid else false
+ */
+static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
+{
+	if (!pmksa->bssid) {
+		hdd_warn("bssid (%pK) is NULL",
+					pmksa->bssid);
+		if (!pmksa->ssid || !pmksa->cache_id) {
+			hdd_err("either ssid (%pK) or cache_id (%pK) are NULL",
+					pmksa->ssid, pmksa->cache_id);
+			return false;
+		}
+	}
+	return true;
+}
+
+/*
+ * hdd_fill_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
+ * @adapter: Pointer to hdd adapter
+ * @pmk_cache: pmk that needs to be udated
+ * @pmksa: pmk from supplicant
+ * @is_delete: Bool to decide set or delete PMK
+ * Return: None
+ */
+static void hdd_fill_pmksa_info(struct hdd_adapter *adapter,
+				tPmkidCacheInfo *pmk_cache,
+				struct cfg80211_pmksa *pmksa, bool is_delete)
+{
+	if (pmksa->bssid) {
+		hdd_debug("%s PMKSA for " MAC_ADDRESS_STR,
+			  is_delete ? "Delete" : "Set",
+			  MAC_ADDR_ARRAY(pmksa->bssid));
+		qdf_mem_copy(pmk_cache->BSSID.bytes,
+			     pmksa->bssid, QDF_MAC_ADDR_SIZE);
+	} else {
+		qdf_mem_copy(pmk_cache->ssid, pmksa->ssid, pmksa->ssid_len);
+		qdf_mem_copy(pmk_cache->cache_id, pmksa->cache_id,
+			     CACHE_ID_LEN);
+		pmk_cache->ssid_len = pmksa->ssid_len;
+		hdd_debug("%s PMKSA for ssid %*.*s cache_id %x %x",
+			  is_delete ? "Delete" : "Set",
+			  pmk_cache->ssid_len, pmk_cache->ssid_len,
+			  pmk_cache->ssid, pmk_cache->cache_id[0],
+			  pmk_cache->cache_id[1]);
+	}
+
+	if (is_delete)
+		return;
+
+	qdf_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
+	if (pmksa->pmk_len && (pmksa->pmk_len <= CSR_RSN_MAX_PMK_LEN)) {
+		qdf_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len);
+		pmk_cache->pmk_len = pmksa->pmk_len;
+	} else
+		hdd_debug("pmk len is %zu", pmksa->pmk_len);
+}
+#else
+/*
+ * wlan_hdd_is_pmksa_valid: API to validate pmksa
+ * @pmksa: pointer to cfg80211_pmksa structure
+ *
+ * Return: True if valid else false
+ */
+static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
+{
+	if (!pmksa->bssid) {
+		hdd_err("both bssid is NULL %pK", pmksa->bssid);
+		return false;
+	}
+	return true;
+}
+
+/*
+ * hdd_fill_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
+ * @adapter: Pointer to hdd adapter
+ * @pmk_cache: pmk which needs to be updated
+ * @pmksa: pmk from supplicant
+ * @is_delete: Bool to decide whether to set or delete PMK
+ *
+ * Return: None
+ */
+static void hdd_fill_pmksa_info(struct hdd_adapter *adapter,
+				tPmkidCacheInfo *pmk_cache,
+				struct cfg80211_pmksa *pmksa, bool is_delete)
+{
+	mac_handle_t mac_handle;
+
+	hdd_debug("%s PMKSA for " MAC_ADDRESS_STR, is_delete ? "Delete" : "Set",
+	MAC_ADDR_ARRAY(pmksa->bssid));
+	qdf_mem_copy(pmk_cache->BSSID.bytes,
+				pmksa->bssid, QDF_MAC_ADDR_SIZE);
+
+	if (is_delete)
+		return;
+	mac_handle = hdd_adapter_get_mac_handle(adapter);
+	sme_get_pmk_info(mac_handle, adapter->session_id, pmk_cache);
+	qdf_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
+}
+#endif
+
+/**
+ * __wlan_hdd_cfg80211_set_pmksa() - set pmksa
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @pmksa: Pointer to set pmksa parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy,
+					 struct net_device *dev,
+					 struct cfg80211_pmksa *pmksa)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle;
+	QDF_STATUS result = QDF_STATUS_SUCCESS;
+	int status;
+	tPmkidCacheInfo pmk_cache;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	if (!pmksa) {
+		hdd_err("pmksa is NULL");
+		return -EINVAL;
+	}
+
+	if (!pmksa->pmkid) {
+		hdd_err("pmksa->pmkid(%pK) is NULL",
+		       pmksa->pmkid);
+		return -EINVAL;
+	}
+
+	if (!wlan_hdd_is_pmksa_valid(pmksa))
+		return -EINVAL;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	qdf_mem_zero(&pmk_cache, sizeof(pmk_cache));
+
+	hdd_fill_pmksa_info(adapter, &pmk_cache, pmksa, false);
+
+	/*
+	 * Add to the PMKSA Cache in CSR
+	 * PMKSA cache will be having following
+	 * 1. pmkid id
+	 * 2. pmk
+	 * 3. bssid or cache identifier
+	 */
+	result = sme_roam_set_pmkid_cache(mac_handle, adapter->session_id,
+					  &pmk_cache, 1, false);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
+			 adapter->session_id, result));
+
+	sme_set_del_pmkid_cache(mac_handle, adapter->session_id,
+				&pmk_cache, true);
+
+	hdd_exit();
+	return QDF_IS_STATUS_SUCCESS(result) ? 0 : -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_pmksa() - set pmksa
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @pmksa: Pointer to set pmksa parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy,
+				       struct net_device *dev,
+				       struct cfg80211_pmksa *pmksa)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_del_pmksa() - delete pmksa
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @pmksa: Pointer to pmksa parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy,
+					 struct net_device *dev,
+					 struct cfg80211_pmksa *pmksa)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle;
+	int status = 0;
+	tPmkidCacheInfo pmk_cache;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	if (!pmksa) {
+		hdd_err("pmksa is NULL");
+		return -EINVAL;
+	}
+
+	if (!wlan_hdd_is_pmksa_valid(pmksa))
+		return -EINVAL;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
+			 adapter->session_id, 0));
+
+	qdf_mem_zero(&pmk_cache, sizeof(pmk_cache));
+
+	hdd_fill_pmksa_info(adapter, &pmk_cache, pmksa, true);
+
+	/* Delete the PMKID CSR cache */
+	if (QDF_STATUS_SUCCESS !=
+	    sme_roam_del_pmkid_from_cache(mac_handle,
+					  adapter->session_id, &pmk_cache,
+					  false)) {
+		hdd_err("Failed to delete PMKSA for " MAC_ADDRESS_STR,
+		       MAC_ADDR_ARRAY(pmksa->bssid));
+		status = -EINVAL;
+	}
+
+	sme_set_del_pmkid_cache(mac_handle, adapter->session_id, &pmk_cache,
+				false);
+	hdd_exit();
+	return status;
+}
+
+/**
+ * wlan_hdd_cfg80211_del_pmksa() - delete pmksa
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @pmksa: Pointer to pmksa parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy,
+				       struct net_device *dev,
+				       struct cfg80211_pmksa *pmksa)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+
+}
+
+/**
+ * __wlan_hdd_cfg80211_flush_pmksa() - flush pmksa
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy,
+					   struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle;
+	int errno;
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	hdd_debug("Flushing PMKSA");
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	errno  = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	status = sme_roam_del_pmkid_from_cache(mac_handle,
+					       adapter->session_id,
+					       NULL, true);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Cannot flush PMKIDCache");
+		errno = -EINVAL;
+	}
+
+	sme_set_del_pmkid_cache(mac_handle, adapter->session_id, NULL, false);
+	hdd_exit();
+	return errno;
+}
+
+/**
+ * wlan_hdd_cfg80211_flush_pmksa() - flush pmksa
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy,
+					 struct net_device *dev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#if defined(KERNEL_SUPPORT_11R_CFG80211)
+/**
+ * __wlan_hdd_cfg80211_update_ft_ies() - update fast transition ies
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @ftie: Pointer to fast transition ie parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int
+__wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
+				  struct net_device *dev,
+				  struct cfg80211_update_ft_ies_params *ftie)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	int status;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
+			 adapter->session_id, sta_ctx->conn_info.connState));
+	/* Added for debug on reception of Re-assoc Req. */
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		hdd_err("Called with Ie of length = %zu when not associated",
+		       ftie->ie_len);
+		hdd_err("Should be Re-assoc Req IEs");
+	}
+	hdd_debug("%s called with Ie of length = %zu", __func__,
+	       ftie->ie_len);
+
+	/* Pass the received FT IEs to SME */
+	mac_handle = hdd_ctx->mac_handle;
+	sme_set_ft_ies(mac_handle, adapter->session_id,
+		       (const u8 *)ftie->ie, ftie->ie_len);
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_update_ft_ies() - update fast transition ies
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @ftie: Pointer to fast transition ie parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int
+wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
+				struct net_device *dev,
+				struct cfg80211_update_ft_ies_params *ftie)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
+void wlan_hdd_cfg80211_update_replay_counter_cb(
+		void *cb_ctx, struct pmo_gtk_rsp_params *gtk_rsp_param)
+
+{
+	struct hdd_adapter *adapter = (struct hdd_adapter *)cb_ctx;
+	uint8_t temp_replay_counter[8];
+	int i;
+	uint8_t *p;
+
+	hdd_enter();
+
+	if (!adapter) {
+		hdd_err("HDD adapter is Null");
+		goto out;
+	}
+
+	if (!gtk_rsp_param) {
+		hdd_err("gtk_rsp_param is Null");
+		goto out;
+	}
+
+	if (gtk_rsp_param->status_flag != QDF_STATUS_SUCCESS) {
+		hdd_err("wlan Failed to get replay counter value");
+		goto out;
+	}
+
+	hdd_debug("updated replay counter: %llu from fwr",
+		gtk_rsp_param->replay_counter);
+	/* convert little to big endian since supplicant works on big endian */
+	p = (uint8_t *)&gtk_rsp_param->replay_counter;
+	for (i = 0; i < 8; i++)
+		temp_replay_counter[7 - i] = (uint8_t) p[i];
+
+	hdd_debug("gtk_rsp_param bssid %pM", gtk_rsp_param->bssid.bytes);
+	/* Update replay counter to NL */
+	cfg80211_gtk_rekey_notify(adapter->dev,
+					gtk_rsp_param->bssid.bytes,
+					temp_replay_counter, GFP_KERNEL);
+out:
+	hdd_exit();
+
+}
+
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+/**
+ * wlan_hdd_copy_gtk_kek - Copy the KEK from GTK rekey data to GTK request
+ * @gtk_req: Pointer to GTK request
+ * @data: Pointer to rekey data
+ *
+ * Return: none
+ */
+#ifdef CFG80211_REKEY_DATA_KEK_LEN
+static
+void wlan_hdd_copy_gtk_kek(struct pmo_gtk_req *gtk_req,
+			   struct cfg80211_gtk_rekey_data *data)
+{
+	qdf_mem_copy(gtk_req->kek, data->kek, data->kek_len);
+	gtk_req->kek_len = data->kek_len;
+}
+#else
+static
+void wlan_hdd_copy_gtk_kek(struct pmo_gtk_req *gtk_req,
+			   struct cfg80211_gtk_rekey_data *data)
+{
+	qdf_mem_copy(gtk_req->kek, data->kek, NL80211_KEK_LEN);
+	gtk_req->kek_len = NL80211_KEK_LEN;
+}
+#endif
+
+/**
+ * __wlan_hdd_cfg80211_set_rekey_data() - set rekey data
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @data: Pointer to rekey data
+ *
+ * This function is used to offload GTK rekeying job to the firmware.
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static
+int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy,
+		struct net_device *dev,
+		struct cfg80211_gtk_rekey_data *data)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int result, i;
+	struct pmo_gtk_req *gtk_req = NULL;
+	struct hdd_context *hdd_ctx =  WLAN_HDD_GET_CTX(adapter);
+	uint8_t *buf;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		result = -EINVAL;
+		goto out;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id)) {
+		result = -EINVAL;
+		goto out;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
+			 adapter->session_id, adapter->device_mode));
+
+	result = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != result)
+		goto out;
+
+	gtk_req = qdf_mem_malloc(sizeof(*gtk_req));
+	if (!gtk_req) {
+		result = -ENOMEM;
+		goto out;
+	}
+
+	/* convert big to little endian since driver work on little endian */
+	buf = (uint8_t *)&gtk_req->replay_counter;
+	for (i = 0; i < 8; i++)
+		buf[7 - i] = data->replay_ctr[i];
+
+	hdd_debug("current replay counter: %llu in user space",
+		gtk_req->replay_counter);
+
+	wlan_hdd_copy_gtk_kek(gtk_req, data);
+	qdf_mem_copy(gtk_req->kck, data->kck, NL80211_KCK_LEN);
+	gtk_req->is_fils_connection = hdd_is_fils_connection(adapter);
+	status = ucfg_pmo_cache_gtk_offload_req(adapter->vdev, gtk_req);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to cache GTK Offload");
+		result = qdf_status_to_os_return(status);
+	}
+out:
+	if (gtk_req)
+		qdf_mem_free(gtk_req);
+	hdd_exit();
+
+	return result;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_rekey_data() - set rekey data
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @data: Pointer to rekey data
+ *
+ * This function is used to offload GTK rekeying job to the firmware.
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static
+int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy,
+				     struct net_device *dev,
+				     struct cfg80211_gtk_rekey_data *data)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif /* WLAN_FEATURE_GTK_OFFLOAD */
+
+/**
+ * __wlan_hdd_cfg80211_set_mac_acl() - set access control policy
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @param: Pointer to access control parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
+					 struct net_device *dev,
+					 const struct cfg80211_acl_data *params)
+{
+	int i;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_hostapd_state *hostapd_state;
+	tsap_config_t *pConfig;
+	struct hdd_context *hdd_ctx;
+	int status;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (NULL == params) {
+		hdd_err("params is Null");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+
+	if (NULL == hostapd_state) {
+		hdd_err("hostapd_state is Null");
+		return -EINVAL;
+	}
+
+	hdd_debug("acl policy: %d num acl entries: %d", params->acl_policy,
+		params->n_acl_entries);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
+			 adapter->session_id, adapter->device_mode));
+	if (QDF_SAP_MODE == adapter->device_mode) {
+		pConfig = &adapter->session.ap.sap_config;
+
+		/* default value */
+		pConfig->num_accept_mac = 0;
+		pConfig->num_deny_mac = 0;
+
+		/**
+		 * access control policy
+		 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
+		 *   listed in hostapd.deny file.
+		 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
+		 *   listed in hostapd.accept file.
+		 */
+		if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy) {
+			pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
+		} else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED ==
+			   params->acl_policy) {
+			pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
+		} else {
+			hdd_warn("Acl Policy : %d is not supported",
+				params->acl_policy);
+			return -ENOTSUPP;
+		}
+
+		if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl) {
+			pConfig->num_accept_mac = params->n_acl_entries;
+			for (i = 0; i < params->n_acl_entries; i++) {
+				hdd_debug("** Add ACL MAC entry %i in WhiletList :"
+					MAC_ADDRESS_STR, i,
+					MAC_ADDR_ARRAY(
+						params->mac_addrs[i].addr));
+
+				qdf_mem_copy(&pConfig->accept_mac[i],
+					     params->mac_addrs[i].addr,
+					     sizeof(qcmacaddr));
+			}
+		} else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl) {
+			pConfig->num_deny_mac = params->n_acl_entries;
+			for (i = 0; i < params->n_acl_entries; i++) {
+				hdd_debug("** Add ACL MAC entry %i in BlackList :"
+					MAC_ADDRESS_STR, i,
+					MAC_ADDR_ARRAY(
+						params->mac_addrs[i].addr));
+
+				qdf_mem_copy(&pConfig->deny_mac[i],
+					     params->mac_addrs[i].addr,
+					     sizeof(qcmacaddr));
+			}
+		}
+		qdf_status = wlansap_set_mac_acl(
+			WLAN_HDD_GET_SAP_CTX_PTR(adapter), pConfig);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			hdd_err("SAP Set Mac Acl fail");
+			return -EINVAL;
+		}
+	} else {
+		hdd_debug("Invalid device_mode %s(%d)",
+			  qdf_opmode_str(adapter->device_mode),
+			  adapter->device_mode);
+		return -EINVAL;
+	}
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_mac_acl() - SSR wrapper for
+ *				__wlan_hdd_cfg80211_set_mac_acl
+ * @wiphy: pointer to wiphy structure
+ * @dev: pointer to net_device
+ * @params: pointer to cfg80211_acl_data
+ *
+ * Return; 0 on success, error number otherwise
+ */
+static int
+wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
+			      struct net_device *dev,
+			      const struct cfg80211_acl_data *params)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef WLAN_NL80211_TESTMODE
+#ifdef FEATURE_WLAN_LPHB
+/**
+ * wlan_hdd_cfg80211_lphb_ind_handler() - handle low power heart beat indication
+ * @hdd_ctx: Pointer to hdd context
+ * @lphbInd: Pointer to low power heart beat indication parameter
+ *
+ * Return: none
+ */
+static void wlan_hdd_cfg80211_lphb_ind_handler(void *hdd_ctx,
+		struct pmo_lphb_rsp *lphb_ind)
+{
+	struct sk_buff *skb;
+
+	hdd_debug("LPHB indication arrived");
+
+	if (0 != wlan_hdd_validate_context((struct hdd_context *) hdd_ctx))
+		return;
+
+	if (!lphb_ind) {
+		hdd_err("invalid argument lphbInd");
+		return;
+	}
+
+	skb = cfg80211_testmode_alloc_event_skb(((struct hdd_context *) hdd_ctx)->
+			wiphy, sizeof(*lphb_ind), GFP_ATOMIC);
+	if (!skb) {
+		hdd_err("LPHB timeout, NL buffer alloc fail");
+		return;
+	}
+
+	if (nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB)) {
+		hdd_err("WLAN_HDD_TM_ATTR_CMD put fail");
+		goto nla_put_failure;
+	}
+	if (nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphb_ind->protocol_type)) {
+		hdd_err("WLAN_HDD_TM_ATTR_TYPE put fail");
+		goto nla_put_failure;
+	}
+	if (nla_put(skb, WLAN_HDD_TM_ATTR_DATA, sizeof(*lphb_ind),
+			lphb_ind)) {
+		hdd_err("WLAN_HDD_TM_ATTR_DATA put fail");
+		goto nla_put_failure;
+	}
+	cfg80211_testmode_event(skb, GFP_ATOMIC);
+	return;
+
+nla_put_failure:
+	hdd_err("NLA Put fail");
+	kfree_skb(skb);
+}
+#endif /* FEATURE_WLAN_LPHB */
+
+/**
+ * __wlan_hdd_cfg80211_testmode() - test mode
+ * @wiphy: Pointer to wiphy
+ * @data: Data pointer
+ * @len: Data length
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
+					void *data, int len)
+{
+	struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
+	int err;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter();
+
+	err = wlan_hdd_validate_context(hdd_ctx);
+	if (err)
+		return err;
+
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
+		hdd_err("Driver Modules are closed");
+		return -EINVAL;
+	}
+
+	err = wlan_cfg80211_nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data,
+				      len, wlan_hdd_tm_policy);
+	if (err) {
+		hdd_err("Testmode INV ATTR");
+		return err;
+	}
+
+	if (!tb[WLAN_HDD_TM_ATTR_CMD]) {
+		hdd_err("Testmode INV CMD");
+		return -EINVAL;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_TESTMODE,
+			 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
+	switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])) {
+#ifdef FEATURE_WLAN_LPHB
+	/* Low Power Heartbeat configuration request */
+	case WLAN_HDD_TM_CMD_WLAN_HB:
+	{
+		int buf_len;
+		void *buf;
+		struct pmo_lphb_req *hb_params = NULL;
+		struct pmo_lphb_req *hb_params_temp = NULL;
+		QDF_STATUS status;
+
+		if (!tb[WLAN_HDD_TM_ATTR_DATA]) {
+			hdd_err("Testmode INV DATA");
+			return -EINVAL;
+		}
+
+		buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
+		buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
+
+		hb_params_temp = (struct pmo_lphb_req *) buf;
+		if ((hb_params_temp->cmd == pmo_lphb_set_tcp_pararm_indid)
+		    && (hb_params_temp->params.lphb_tcp_params.
+			time_period_sec == 0))
+			return -EINVAL;
+
+		if (buf_len > sizeof(*hb_params)) {
+			hdd_err("buf_len=%d exceeded hb_params size limit",
+				buf_len);
+			return -ERANGE;
+		}
+
+		hb_params = (struct pmo_lphb_req *)qdf_mem_malloc(
+				sizeof(*hb_params));
+		if (!hb_params)
+			return -ENOMEM;
+
+		qdf_mem_zero(hb_params, sizeof(*hb_params));
+		qdf_mem_copy(hb_params, buf, buf_len);
+		status = ucfg_pmo_lphb_config_req(
+					hdd_ctx->psoc,
+					hb_params, (void *)hdd_ctx,
+					wlan_hdd_cfg80211_lphb_ind_handler);
+		if (status != QDF_STATUS_SUCCESS)
+			hdd_err("LPHB Config Fail, disable");
+
+		qdf_mem_free(hb_params);
+		return 0;
+	}
+#endif /* FEATURE_WLAN_LPHB */
+
+#if  defined(QCA_WIFI_FTM)
+	case WLAN_HDD_TM_CMD_WLAN_FTM:
+	{
+		if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam()) {
+			hdd_err("Command not allowed in FTM mode, mode %d",
+				hdd_get_conparam());
+			return -EINVAL;
+		}
+
+		err = wlan_cfg80211_ftm_testmode_cmd(hdd_ctx->pdev,
+						     data, len);
+		break;
+	}
+#endif
+	default:
+		hdd_err("command: %d not supported",
+			nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]));
+		return -EOPNOTSUPP;
+	}
+
+	hdd_exit();
+	return err;
+}
+
+/**
+ * wlan_hdd_cfg80211_testmode() - test mode
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @data: Data pointer
+ * @len: Data length
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
+				      struct wireless_dev *wdev,
+#endif
+				      void *data, int len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#endif /* CONFIG_NL80211_TESTMODE */
+
+#ifdef QCA_HT_2040_COEX
+/**
+ * __wlan_hdd_cfg80211_set_ap_channel_width() - set ap channel bandwidth
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @chandef: Pointer to channel definition parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int
+__wlan_hdd_cfg80211_set_ap_channel_width(struct wiphy *wiphy,
+					 struct net_device *dev,
+					 struct cfg80211_chan_def *chandef)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+	int retval = 0;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	if (!(adapter->device_mode == QDF_SAP_MODE ||
+	      adapter->device_mode == QDF_P2P_GO_MODE))
+		return -EOPNOTSUPP;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	hdd_debug("Channel width changed to %d ",
+		  cfg80211_get_chandef_type(chandef));
+
+	/* Change SAP ht2040 mode */
+	status = hdd_set_sap_ht2040_mode(adapter,
+					 cfg80211_get_chandef_type(chandef));
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Cannot set SAP HT20/40 mode!");
+		retval = -EINVAL;
+	}
+
+	return retval;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_ap_channel_width() - set ap channel bandwidth
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @chandef: Pointer to channel definition parameter
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int
+wlan_hdd_cfg80211_set_ap_channel_width(struct wiphy *wiphy,
+				       struct net_device *dev,
+				       struct cfg80211_chan_def *chandef)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_ap_channel_width(wiphy, dev, chandef);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
+#ifdef CHANNEL_SWITCH_SUPPORTED
+/**
+ * __wlan_hdd_cfg80211_channel_switch()- function to switch
+ * channel in SAP/GO
+ * @wiphy:  wiphy pointer
+ * @dev: dev pointer.
+ * @csa_params: Change channel params
+ *
+ * This function is called to switch channel in SAP/GO
+ *
+ * Return: 0 if success else return non zero
+ */
+static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
+				struct net_device *dev,
+				struct cfg80211_csa_settings *csa_params)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	uint8_t channel;
+	uint16_t freq;
+	int ret;
+	enum phy_ch_width ch_width;
+
+	hdd_debug("Set Freq %d",
+		  csa_params->chandef.chan->center_freq);
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != ret)
+		return ret;
+
+	if ((QDF_P2P_GO_MODE != adapter->device_mode) &&
+		(QDF_SAP_MODE != adapter->device_mode))
+		return -ENOTSUPP;
+
+	freq = csa_params->chandef.chan->center_freq;
+	channel = cds_freq_to_chan(freq);
+
+	ch_width = hdd_map_nl_chan_width(csa_params->chandef.width);
+
+	ret = hdd_softap_set_channel_change(dev, channel, ch_width, false);
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_channel_switch()- function to switch
+ * channel in SAP/GO
+ * @wiphy:  wiphy pointer
+ * @dev: dev pointer.
+ * @csa_params: Change channel params
+ *
+ * This function is called to switch channel in SAP/GO
+ *
+ * Return: 0 if success else return non zero
+ */
+static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
+				struct net_device *dev,
+				struct cfg80211_csa_settings *csa_params)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
+#endif
+
+int wlan_hdd_change_hw_mode_for_given_chnl(struct hdd_adapter *adapter,
+			uint8_t channel,
+			enum policy_mgr_conn_update_reason reason)
+{
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter();
+	if (0 != wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	status = policy_mgr_reset_connection_update(hdd_ctx->psoc);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("clearing event failed");
+
+	status = policy_mgr_current_connections_update(hdd_ctx->psoc,
+			adapter->session_id, channel, reason);
+	switch (status) {
+	case QDF_STATUS_E_FAILURE:
+		/*
+		 * QDF_STATUS_E_FAILURE indicates that some error has occurred
+		 * while changing the hw mode
+		 */
+		hdd_err("ERROR: connections update failed!!");
+		return -EINVAL;
+
+	case QDF_STATUS_SUCCESS:
+		/*
+		 * QDF_STATUS_SUCCESS indicates that HW mode change has been
+		 * triggered and wait for it to finish.
+		 */
+		status = policy_mgr_wait_for_connection_update(
+						hdd_ctx->psoc);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("ERROR: qdf wait for event failed!!");
+			return -EINVAL;
+		}
+		if (QDF_MONITOR_MODE == adapter->device_mode)
+			hdd_info("Monitor mode:channel:%d (SMM->DBS)", channel);
+		break;
+
+	default:
+		/*
+		 * QDF_STATUS_E_NOSUPPORT indicates that no HW mode change is
+		 * required, so caller can proceed further.
+		 */
+		break;
+
+	}
+	hdd_exit();
+
+	return 0;
+}
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+/**
+ * wlan_hdd_cfg80211_set_mon_ch() - Set monitor mode capture channel
+ * @wiphy: Handle to struct wiphy to get handle to module context.
+ * @chandef: Contains information about the capture channel to be set.
+ *
+ * This interface is called if and only if monitor mode interface alone is
+ * active.
+ *
+ * Return: 0 success or error code on failure.
+ */
+static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy,
+				       struct cfg80211_chan_def *chandef)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct hdd_adapter *adapter;
+	struct hdd_station_ctx *sta_ctx;
+	struct hdd_mon_set_ch_info *ch_info;
+	QDF_STATUS status;
+	mac_handle_t mac_handle;
+	struct qdf_mac_addr bssid;
+	struct csr_roam_profile roam_profile;
+	struct ch_params ch_params;
+	uint8_t sec_ch = 0;
+	int ret;
+	uint16_t chan_num = cds_freq_to_chan(chandef->chan->center_freq);
+
+	hdd_enter();
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
+	if (!adapter)
+		return -EIO;
+
+	hdd_debug("%s: set monitor mode Channel %d and freq %d",
+		 adapter->dev->name, chan_num, chandef->chan->center_freq);
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	ch_info = &sta_ctx->ch_info;
+	roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
+	roam_profile.ChannelInfo.numOfChannels = 1;
+	roam_profile.phyMode = ch_info->phy_mode;
+	roam_profile.ch_params.ch_width = hdd_map_nl_chan_width(chandef->width);
+	hdd_select_cbmode(adapter, chan_num, &roam_profile.ch_params);
+
+	qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
+		     QDF_MAC_ADDR_SIZE);
+
+	ch_params.ch_width = hdd_map_nl_chan_width(chandef->width);
+	/*
+	 * CDS api expects secondary channel for calculating
+	 * the channel params
+	 */
+	if ((ch_params.ch_width == CH_WIDTH_40MHZ) &&
+	    (WLAN_REG_IS_24GHZ_CH(chan_num))) {
+		if (chan_num >= 1 && chan_num <= 5)
+			sec_ch = chan_num + 4;
+		else if (chan_num >= 6 && chan_num <= 13)
+			sec_ch = chan_num - 4;
+	}
+	wlan_reg_set_channel_params(hdd_ctx->pdev, chan_num,
+				    sec_ch, &ch_params);
+	if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan_num,
+				POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
+		hdd_err("Failed to change hw mode");
+		return -EINVAL;
+	}
+	status = sme_roam_channel_change_req(mac_handle, bssid, &ch_params,
+					     &roam_profile);
+	if (status) {
+		hdd_err("Failed to set sme_RoamChannel for monitor mode status: %d",
+			status);
+		ret = qdf_status_to_os_return(status);
+		return ret;
+	}
+	hdd_exit();
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_mon_ch() - Set monitor mode capture channel
+ * @wiphy: Handle to struct wiphy to get handle to module context.
+ * @chandef: Contains information about the capture channel to be set.
+ *
+ * This interface is called if and only if monitor mode interface alone is
+ * active.
+ *
+ * Return: 0 success or error code on failure.
+ */
+static int wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy,
+				       struct cfg80211_chan_def *chandef)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_mon_ch(wiphy, chandef);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
+#endif
+
+#define CNT_DIFF(cur, prev) \
+	((cur >= prev) ? (cur - prev) : (cur + (MAX_COUNT - (prev) + 1)))
+#define MAX_COUNT 0xffffffff
+static void hdd_update_chan_info(struct hdd_context *hdd_ctx,
+			struct scan_chan_info *chan,
+			struct scan_chan_info *info, uint32_t cmd_flag)
+{
+	if ((info->cmd_flag != WMI_CHAN_InFO_START_RESP) &&
+	   (info->cmd_flag != WMI_CHAN_InFO_END_RESP))
+		hdd_err("cmd flag is invalid: %d", info->cmd_flag);
+
+	mutex_lock(&hdd_ctx->chan_info_lock);
+
+	if (info->cmd_flag == WMI_CHAN_InFO_START_RESP)
+		qdf_mem_zero(chan, sizeof(*chan));
+
+	chan->freq = info->freq;
+	chan->noise_floor = info->noise_floor;
+	chan->clock_freq = info->clock_freq;
+	chan->cmd_flag = info->cmd_flag;
+	chan->cycle_count = CNT_DIFF(info->cycle_count, chan->cycle_count);
+
+	chan->rx_clear_count =
+			CNT_DIFF(info->rx_clear_count, chan->rx_clear_count);
+
+	chan->tx_frame_count =
+			CNT_DIFF(info->tx_frame_count, chan->tx_frame_count);
+
+	mutex_unlock(&hdd_ctx->chan_info_lock);
+
+}
+#undef CNT_DIFF
+#undef MAX_COUNT
+
+#if defined(WLAN_FEATURE_FILS_SK) &&\
+	defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) &&\
+	(defined(CFG80211_UPDATE_CONNECT_PARAMS) ||\
+		(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)))
+
+#ifndef UPDATE_FILS_ERP_INFO
+#define UPDATE_FILS_ERP_INFO BIT(1)
+#endif
+
+#ifndef UPDATE_FILS_AUTH_TYPE
+#define UPDATE_FILS_AUTH_TYPE BIT(2)
+#endif
+
+/**
+ * __wlan_hdd_cfg80211_update_connect_params - update connect params
+ * @wiphy: Handle to struct wiphy to get handle to module context.
+ * @dev: Pointer to network device
+ * @req: Pointer to connect params
+ * @changed: Bitmap used to indicate the changed params
+ *
+ * Update the connect parameters while connected to a BSS. The updated
+ * parameters can be used by driver/firmware for subsequent BSS selection
+ * (roaming) decisions and to form the Authentication/(Re)Association
+ * Request frames. This call does not request an immediate disassociation
+ * or reassociation with the current BSS, i.e., this impacts only
+ * subsequent (re)associations. The bits in changed are defined in enum
+ * cfg80211_connect_params_changed
+ *
+ * Return: zero for success, non-zero for failure
+ */
+static int
+__wlan_hdd_cfg80211_update_connect_params(struct wiphy *wiphy,
+					  struct net_device *dev,
+					  struct cfg80211_connect_params *req,
+					  uint32_t changed)
+{
+	struct csr_roam_profile *roam_profile;
+	uint8_t *buf;
+	int ret;
+	enum eAniAuthType auth_type;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	QDF_STATUS status;
+	struct cds_fils_connection_info *fils_info;
+	mac_handle_t mac_handle;
+
+	hdd_enter_dev(dev);
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return -EINVAL;
+
+	roam_profile = hdd_roam_profile(adapter);
+	fils_info = roam_profile->fils_con_info;
+
+	if (!fils_info) {
+		hdd_err("No valid FILS conn info");
+		return -EINVAL;
+	}
+
+	if (req->ie_len)
+		wlan_hdd_cfg80211_set_ie(adapter, req->ie, req->ie_len);
+
+	if (changed)
+		fils_info->is_fils_connection = true;
+
+	if (changed & UPDATE_FILS_ERP_INFO) {
+		if (!wlan_hdd_fils_data_in_limits(req))
+			return -EINVAL;
+		fils_info->key_nai_length = req->fils_erp_username_len +
+					    sizeof(char) +
+					    req->fils_erp_realm_len;
+		if (fils_info->key_nai_length >
+		    FILS_MAX_KEYNAME_NAI_LENGTH) {
+			hdd_err("Key NAI Length %d",
+				fils_info->key_nai_length);
+			return -EINVAL;
+		}
+		if (req->fils_erp_username_len && req->fils_erp_username) {
+			buf = fils_info->keyname_nai;
+			qdf_mem_copy(buf, req->fils_erp_username,
+					req->fils_erp_username_len);
+			buf += req->fils_erp_username_len;
+			*buf++ = '@';
+			qdf_mem_copy(buf, req->fils_erp_realm,
+					req->fils_erp_realm_len);
+		}
+
+		fils_info->sequence_number = req->fils_erp_next_seq_num;
+		fils_info->r_rk_length = req->fils_erp_rrk_len;
+
+		if (req->fils_erp_rrk_len && req->fils_erp_rrk)
+			qdf_mem_copy(fils_info->r_rk, req->fils_erp_rrk,
+						fils_info->r_rk_length);
+
+		fils_info->realm_len = req->fils_erp_realm_len;
+		if (req->fils_erp_realm_len && req->fils_erp_realm)
+			qdf_mem_copy(fils_info->realm, req->fils_erp_realm,
+						fils_info->realm_len);
+	}
+
+	if (changed & UPDATE_FILS_AUTH_TYPE) {
+		auth_type = wlan_hdd_get_fils_auth_type(req->auth_type);
+		if (auth_type == eSIR_DONOT_USE_AUTH_TYPE) {
+			hdd_err("invalid auth type for fils %d",
+				req->auth_type);
+			return -EINVAL;
+		}
+
+		roam_profile->fils_con_info->auth_type = auth_type;
+	}
+
+	hdd_debug("fils conn update: changed %x is_fils %d keyname nai len %d",
+		  changed, roam_profile->fils_con_info->is_fils_connection,
+		  roam_profile->fils_con_info->key_nai_length);
+
+	if (!hdd_ctx->is_fils_roaming_supported) {
+		hdd_debug("FILS roaming support %d",
+			  hdd_ctx->is_fils_roaming_supported);
+		return 0;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_update_fils_config(mac_handle, adapter->session_id,
+					roam_profile);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Update FILS connect params to Fw failed %d", status);
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_update_connect_params - SSR wrapper for
+ *                __wlan_hdd_cfg80211_update_connect_params
+ * @wiphy: Pointer to wiphy structure
+ * @dev: Pointer to net_device
+ * @req: Pointer to connect params
+ * @changed: flags used to indicate the changed params
+ *
+ * Return: zero for success, non-zero for failure
+ */
+static int
+wlan_hdd_cfg80211_update_connect_params(struct wiphy *wiphy,
+					struct net_device *dev,
+					struct cfg80211_connect_params *req,
+					uint32_t changed)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_update_connect_params(wiphy, dev,
+							req, changed);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
+#if defined(WLAN_FEATURE_SAE) && \
+	defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+/**
+ * __wlan_hdd_cfg80211_external_auth() - Handle external auth
+ * @wiphy: Pointer to wireless phy
+ * @dev: net device
+ * @params: Pointer to external auth params
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
+				  struct net_device *dev,
+				  struct cfg80211_external_auth_params *params)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int ret;
+	mac_handle_t mac_handle;
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+
+	hdd_debug("external_auth status: %d", params->status);
+	mac_handle = hdd_ctx->mac_handle;
+	sme_handle_sae_msg(mac_handle, adapter->session_id, params->status);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_external_auth() - Handle external auth
+ * @wiphy: Pointer to wireless phy
+ * @dev: net device
+ * @params: Pointer to external auth params
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
+				struct net_device *dev,
+				struct cfg80211_external_auth_params *params)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_external_auth(wiphy, dev, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
+/**
+ * wlan_hdd_chan_info_cb() - channel info callback
+ * @chan_info: struct scan_chan_info
+ *
+ * Store channel info into HDD context
+ *
+ * Return: None.
+ */
+static void wlan_hdd_chan_info_cb(struct scan_chan_info *info)
+{
+	struct hdd_context *hdd_ctx;
+	struct scan_chan_info *chan;
+	uint8_t idx;
+
+	hdd_enter();
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (wlan_hdd_validate_context(hdd_ctx) != 0) {
+		hdd_err("hdd_ctx is invalid");
+		return;
+	}
+
+	if (!hdd_ctx->chan_info) {
+		hdd_err("chan_info is NULL");
+		return;
+	}
+
+	chan = hdd_ctx->chan_info;
+	for (idx = 0; idx < SIR_MAX_NUM_CHANNELS; idx++) {
+		if (chan[idx].freq == info->freq) {
+			hdd_update_chan_info(hdd_ctx, &chan[idx], info,
+				info->cmd_flag);
+			hdd_debug("cmd:%d freq:%u nf:%d cc:%u rcc:%u clk:%u cmd:%d tfc:%d index:%d",
+				  chan[idx].cmd_flag, chan[idx].freq,
+				  chan[idx].noise_floor,
+				  chan[idx].cycle_count,
+				  chan[idx].rx_clear_count,
+				  chan[idx].clock_freq, chan[idx].cmd_flag,
+				  chan[idx].tx_frame_count, idx);
+			if (chan[idx].freq == 0)
+				break;
+
+		}
+	}
+
+	hdd_exit();
+}
+
+/**
+ * wlan_hdd_init_chan_info() - init chan info in hdd context
+ * @hdd_ctx: HDD context pointer
+ *
+ * Return: none
+ */
+void wlan_hdd_init_chan_info(struct hdd_context *hdd_ctx)
+{
+	uint32_t num_2g, num_5g, index = 0;
+	mac_handle_t mac_handle;
+
+	hdd_ctx->chan_info = NULL;
+	if (!hdd_ctx->config->fEnableSNRMonitoring) {
+		hdd_debug("SNR monitoring is disabled");
+		return;
+	}
+
+	hdd_ctx->chan_info =
+		qdf_mem_malloc(sizeof(struct scan_chan_info)
+					* QDF_MAX_NUM_CHAN);
+	if (!hdd_ctx->chan_info)
+		return;
+	mutex_init(&hdd_ctx->chan_info_lock);
+
+	num_2g = QDF_ARRAY_SIZE(hdd_channels_2_4_ghz);
+	for (; index < num_2g; index++) {
+		hdd_ctx->chan_info[index].freq =
+			hdd_channels_2_4_ghz[index].center_freq;
+	}
+
+	num_5g = QDF_ARRAY_SIZE(hdd_channels_5_ghz);
+	for (; (index - num_2g) < num_5g; index++) {
+		if (wlan_reg_is_dsrc_chan(hdd_ctx->pdev,
+		    hdd_channels_5_ghz[index - num_2g].hw_value))
+			continue;
+		hdd_ctx->chan_info[index].freq =
+			hdd_channels_5_ghz[index - num_2g].center_freq;
+	}
+
+	index = num_2g + num_5g;
+	index = wlan_hdd_populate_srd_chan_info(hdd_ctx, index);
+
+	mac_handle = hdd_ctx->mac_handle;
+	sme_set_chan_info_callback(mac_handle,
+				   &wlan_hdd_chan_info_cb);
+}
+
+/**
+ * wlan_hdd_deinit_chan_info() - deinit chan info in hdd context
+ * @hdd_ctx: hdd context pointer
+ *
+ * Return: none
+ */
+void wlan_hdd_deinit_chan_info(struct hdd_context *hdd_ctx)
+{
+	struct scan_chan_info *chan;
+
+	chan = hdd_ctx->chan_info;
+	hdd_ctx->chan_info = NULL;
+	if (chan)
+		qdf_mem_free(chan);
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
+static enum rate_info_bw hdd_map_hdd_bw_to_os(enum hdd_rate_info_bw hdd_bw)
+{
+	switch (hdd_bw) {
+	case HDD_RATE_BW_5:
+		return RATE_INFO_BW_5;
+	case HDD_RATE_BW_10:
+		return RATE_INFO_BW_10;
+	case HDD_RATE_BW_20:
+		return RATE_INFO_BW_20;
+	case HDD_RATE_BW_40:
+		return RATE_INFO_BW_40;
+	case HDD_RATE_BW_80:
+		return RATE_INFO_BW_80;
+	case HDD_RATE_BW_160:
+		return RATE_INFO_BW_160;
+	}
+
+	hdd_err("Unhandled HDD_RATE_BW: %d", hdd_bw);
+
+	return RATE_INFO_BW_20;
+}
+
+void hdd_set_rate_bw(struct rate_info *info, enum hdd_rate_info_bw hdd_bw)
+{
+	info->bw = hdd_map_hdd_bw_to_os(hdd_bw);
+}
+#else
+static enum rate_info_flags hdd_map_hdd_bw_to_os(enum hdd_rate_info_bw hdd_bw)
+{
+	switch (hdd_bw) {
+	case HDD_RATE_BW_5:
+	case HDD_RATE_BW_10:
+	case HDD_RATE_BW_20:
+		return (enum rate_info_flags)0;
+	case HDD_RATE_BW_40:
+		return RATE_INFO_FLAGS_40_MHZ_WIDTH;
+	case HDD_RATE_BW_80:
+		return RATE_INFO_FLAGS_80_MHZ_WIDTH;
+	case HDD_RATE_BW_160:
+		return RATE_INFO_FLAGS_160_MHZ_WIDTH;
+	}
+
+	hdd_err("Unhandled HDD_RATE_BW: %d", hdd_bw);
+
+	return (enum rate_info_flags)0;
+}
+
+void hdd_set_rate_bw(struct rate_info *info, enum hdd_rate_info_bw hdd_bw)
+{
+	const enum rate_info_flags all_bws =
+		RATE_INFO_FLAGS_40_MHZ_WIDTH |
+		RATE_INFO_FLAGS_80_MHZ_WIDTH |
+		RATE_INFO_FLAGS_80P80_MHZ_WIDTH |
+		RATE_INFO_FLAGS_160_MHZ_WIDTH;
+
+	info->flags &= ~all_bws;
+	info->flags |= hdd_map_hdd_bw_to_os(hdd_bw);
+}
+#endif
+
+/**
+ * struct cfg80211_ops - cfg80211_ops
+ *
+ * @add_virtual_intf: Add virtual interface
+ * @del_virtual_intf: Delete virtual interface
+ * @change_virtual_intf: Change virtual interface
+ * @change_station: Change station
+ * @add_beacon: Add beacon in sap mode
+ * @del_beacon: Delete beacon in sap mode
+ * @set_beacon: Set beacon in sap mode
+ * @start_ap: Start ap
+ * @change_beacon: Change beacon
+ * @stop_ap: Stop ap
+ * @change_bss: Change bss
+ * @add_key: Add key
+ * @get_key: Get key
+ * @del_key: Delete key
+ * @set_default_key: Set default key
+ * @set_channel: Set channel
+ * @scan: Scan
+ * @connect: Connect
+ * @disconnect: Disconnect
+ * @join_ibss = Join ibss
+ * @leave_ibss = Leave ibss
+ * @set_wiphy_params = Set wiphy params
+ * @set_tx_power = Set tx power
+ * @get_tx_power = get tx power
+ * @remain_on_channel = Remain on channel
+ * @cancel_remain_on_channel = Cancel remain on channel
+ * @mgmt_tx = Tx management frame
+ * @mgmt_tx_cancel_wait = Cancel management tx wait
+ * @set_default_mgmt_key = Set default management key
+ * @set_txq_params = Set tx queue parameters
+ * @get_station = Get station
+ * @set_power_mgmt = Set power management
+ * @del_station = Delete station
+ * @add_station = Add station
+ * @set_pmksa = Set pmksa
+ * @del_pmksa = Delete pmksa
+ * @flush_pmksa = Flush pmksa
+ * @update_ft_ies = Update FT IEs
+ * @tdls_mgmt = Tdls management
+ * @tdls_oper = Tdls operation
+ * @set_rekey_data = Set rekey data
+ * @sched_scan_start = Scheduled scan start
+ * @sched_scan_stop = Scheduled scan stop
+ * @resume = Resume wlan
+ * @suspend = Suspend wlan
+ * @set_mac_acl = Set mac acl
+ * @testmode_cmd = Test mode command
+ * @set_ap_chanwidth = Set AP channel bandwidth
+ * @dump_survey = Dump survey
+ * @key_mgmt_set_pmk = Set pmk key management
+ * @update_connect_params = Update connect params
+ */
+static struct cfg80211_ops wlan_hdd_cfg80211_ops = {
+	.add_virtual_intf = wlan_hdd_add_virtual_intf,
+	.del_virtual_intf = wlan_hdd_del_virtual_intf,
+	.change_virtual_intf = wlan_hdd_cfg80211_change_iface,
+	.change_station = wlan_hdd_change_station,
+	.start_ap = wlan_hdd_cfg80211_start_ap,
+	.change_beacon = wlan_hdd_cfg80211_change_beacon,
+	.stop_ap = wlan_hdd_cfg80211_stop_ap,
+	.change_bss = wlan_hdd_cfg80211_change_bss,
+	.add_key = wlan_hdd_cfg80211_add_key,
+	.get_key = wlan_hdd_cfg80211_get_key,
+	.del_key = wlan_hdd_cfg80211_del_key,
+	.set_default_key = wlan_hdd_cfg80211_set_default_key,
+	.scan = wlan_hdd_cfg80211_scan,
+	.connect = wlan_hdd_cfg80211_connect,
+	.disconnect = wlan_hdd_cfg80211_disconnect,
+	.join_ibss = wlan_hdd_cfg80211_join_ibss,
+	.leave_ibss = wlan_hdd_cfg80211_leave_ibss,
+	.set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
+	.set_tx_power = wlan_hdd_cfg80211_set_txpower,
+	.get_tx_power = wlan_hdd_cfg80211_get_txpower,
+	.remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
+	.cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
+	.mgmt_tx = wlan_hdd_mgmt_tx,
+	.mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
+	.set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
+	.set_txq_params = wlan_hdd_set_txq_params,
+	.dump_station = wlan_hdd_cfg80211_dump_station,
+	.get_station = wlan_hdd_cfg80211_get_station,
+	.set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
+	.del_station = wlan_hdd_cfg80211_del_station,
+	.add_station = wlan_hdd_cfg80211_add_station,
+	.set_pmksa = wlan_hdd_cfg80211_set_pmksa,
+	.del_pmksa = wlan_hdd_cfg80211_del_pmksa,
+	.flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
+#if defined(KERNEL_SUPPORT_11R_CFG80211)
+	.update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
+#endif
+#ifdef FEATURE_WLAN_TDLS
+	.tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
+	.tdls_oper = wlan_hdd_cfg80211_tdls_oper,
+#endif
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+	.set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
+#endif /* WLAN_FEATURE_GTK_OFFLOAD */
+#ifdef FEATURE_WLAN_SCAN_PNO
+	.sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
+	.sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
+#endif /*FEATURE_WLAN_SCAN_PNO */
+	.resume = wlan_hdd_cfg80211_resume_wlan,
+	.suspend = wlan_hdd_cfg80211_suspend_wlan,
+	.set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
+#ifdef WLAN_NL80211_TESTMODE
+	.testmode_cmd = wlan_hdd_cfg80211_testmode,
+#endif
+#ifdef QCA_HT_2040_COEX
+	.set_ap_chanwidth = wlan_hdd_cfg80211_set_ap_channel_width,
+#endif
+	.dump_survey = wlan_hdd_cfg80211_dump_survey,
+#ifdef CHANNEL_SWITCH_SUPPORTED
+	.channel_switch = wlan_hdd_cfg80211_channel_switch,
+#endif
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+	.set_monitor_channel = wlan_hdd_cfg80211_set_mon_ch,
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \
+	defined(CFG80211_ABORT_SCAN)
+	.abort_scan = wlan_hdd_cfg80211_abort_scan,
+#endif
+#if defined(WLAN_FEATURE_FILS_SK) &&\
+	defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) &&\
+	(defined(CFG80211_UPDATE_CONNECT_PARAMS) ||\
+		(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)))
+	.update_connect_params = wlan_hdd_cfg80211_update_connect_params,
+#endif
+#if defined(WLAN_FEATURE_SAE) && \
+		defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+	.external_auth = wlan_hdd_cfg80211_external_auth,
+#endif
+};
diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h
new file mode 100644
index 0000000..7b15050
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_cfg80211.h
@@ -0,0 +1,606 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_cfg80211.h
+ *
+ * WLAN host device driver cfg80211 functions declaration
+ */
+
+#if !defined(HDD_CFG80211_H__)
+#define HDD_CFG80211_H__
+
+#include <wlan_cfg80211_scan.h>
+#include <wlan_cfg80211.h>
+#include <wlan_cfg80211_tdls.h>
+#include <qca_vendor.h>
+
+struct hdd_context;
+
+/* value for initial part of frames and number of bytes to be compared */
+#define GAS_INITIAL_REQ "\x04\x0a"
+#define GAS_INITIAL_REQ_SIZE 2
+
+#define GAS_INITIAL_RSP "\x04\x0b"
+#define GAS_INITIAL_RSP_SIZE 2
+
+#define GAS_COMEBACK_REQ "\x04\x0c"
+#define GAS_COMEBACK_REQ_SIZE 2
+
+#define GAS_COMEBACK_RSP "\x04\x0d"
+#define GAS_COMEBACK_RSP_SIZE 2
+
+#define P2P_PUBLIC_ACTION_FRAME "\x04\x09\x50\x6f\x9a\x09"
+#define P2P_PUBLIC_ACTION_FRAME_SIZE 6
+
+#define P2P_ACTION_FRAME "\x7f\x50\x6f\x9a\x09"
+#define P2P_ACTION_FRAME_SIZE 5
+
+#define SA_QUERY_FRAME_REQ "\x08\x00"
+#define SA_QUERY_FRAME_REQ_SIZE 2
+
+#define SA_QUERY_FRAME_RSP "\x08\x01"
+#define SA_QUERY_FRAME_RSP_SIZE 2
+
+#define HDD_P2P_WILDCARD_SSID "DIRECT-"
+#define HDD_P2P_WILDCARD_SSID_LEN 7
+
+#define WNM_BSS_ACTION_FRAME "\x0a\x07"
+#define WNM_BSS_ACTION_FRAME_SIZE 2
+
+#define WNM_NOTIFICATION_FRAME "\x0a\x1a"
+#define WNM_NOTIFICATION_FRAME_SIZE 2
+
+#define WPA_OUI_TYPE   "\x00\x50\xf2\x01"
+#define BLACKLIST_OUI_TYPE   "\x00\x50\x00\x00"
+#define WHITELIST_OUI_TYPE   "\x00\x50\x00\x01"
+#define WPA_OUI_TYPE_SIZE  4
+#define WMM_OUI_TYPE   "\x00\x50\xf2\x02\x01"
+#define WMM_OUI_TYPE_SIZE  5
+
+#define VENDOR1_AP_OUI_TYPE "\x00\xE0\x4C"
+#define VENDOR1_AP_OUI_TYPE_SIZE 3
+
+#define WLAN_BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126
+#define WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY 127
+#define BASIC_RATE_MASK   0x80
+#define RATE_MASK         0x7f
+
+#ifndef NL80211_AUTHTYPE_FILS_SK
+#define NL80211_AUTHTYPE_FILS_SK 5
+#endif
+#ifndef NL80211_AUTHTYPE_FILS_SK_PFS
+#define NL80211_AUTHTYPE_FILS_SK_PFS 6
+#endif
+#ifndef NL80211_AUTHTYPE_FILS_PK
+#define NL80211_AUTHTYPE_FILS_PK 7
+#endif
+#ifndef WLAN_AKM_SUITE_FILS_SHA256
+#define WLAN_AKM_SUITE_FILS_SHA256 0x000FAC0E
+#endif
+#ifndef WLAN_AKM_SUITE_FILS_SHA384
+#define WLAN_AKM_SUITE_FILS_SHA384 0x000FAC0F
+#endif
+#ifndef WLAN_AKM_SUITE_FT_FILS_SHA256
+#define WLAN_AKM_SUITE_FT_FILS_SHA256 0x000FAC10
+#endif
+#ifndef WLAN_AKM_SUITE_FT_FILS_SHA384
+#define WLAN_AKM_SUITE_FT_FILS_SHA384 0x000FAC11
+#endif
+#ifndef WLAN_AKM_SUITE_DPP_RSN
+#define WLAN_AKM_SUITE_DPP_RSN 0x506f9a02
+#endif
+
+#define WLAN_AKM_SUITE_OWE 0x000FAC12
+#define WLAN_AKM_SUITE_EAP_SHA256 0x000FAC0B
+#define WLAN_AKM_SUITE_EAP_SHA384 0x000FAC0C
+
+
+#ifndef WLAN_AKM_SUITE_SAE
+#define WLAN_AKM_SUITE_SAE 0x000FAC08
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+#define WLAN_IS_TDLS_SETUP_ACTION(action) \
+	((SIR_MAC_TDLS_SETUP_REQ <= action) && \
+	(SIR_MAC_TDLS_SETUP_CNF >= action))
+#if !defined(TDLS_MGMT_VERSION2)
+#define TDLS_MGMT_VERSION2 0
+#endif
+
+#endif
+
+#define MAX_CHANNEL (NUM_24GHZ_CHANNELS + NUM_5GHZ_CHANNELS)
+#define MAX_SCAN_SSID 10
+
+#define IS_CHANNEL_VALID(channel) ((channel >= 0 && channel < 15) \
+			|| (channel >= 36 && channel <= 184))
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) \
+	|| defined(BACKPORTED_CHANNEL_SWITCH_PRESENT)
+#define CHANNEL_SWITCH_SUPPORTED
+#endif
+
+#if defined(CFG80211_DEL_STA_V2) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) || defined(WITH_BACKPORTS)
+#define USE_CFG80211_DEL_STA_V2
+#endif
+
+#define OL_TXRX_INVALID_TDLS_PEER_ID 0xff
+
+/**
+ * enum eDFS_CAC_STATUS: CAC status
+ *
+ * @DFS_CAC_NEVER_DONE: CAC never done
+ * @DFS_CAC_IN_PROGRESS: CAC is in progress
+ * @DFS_CAC_IN_PROGRESS: CAC already done
+ */
+typedef enum {
+	DFS_CAC_NEVER_DONE,
+	DFS_CAC_IN_PROGRESS,
+	DFS_CAC_ALREADY_DONE,
+} eDFS_CAC_STATUS;
+
+#define MAX_REQUEST_ID			0xFFFFFFFF
+
+/* Feature defines */
+#define WIFI_FEATURE_INFRA              0x0001  /* Basic infrastructure mode */
+#define WIFI_FEATURE_INFRA_5G           0x0002  /* Support for 5 GHz Band */
+#define WIFI_FEATURE_HOTSPOT            0x0004  /* Support for GAS/ANQP */
+#define WIFI_FEATURE_P2P                0x0008  /* Wifi-Direct */
+#define WIFI_FEATURE_SOFT_AP            0x0010  /* Soft AP */
+#define WIFI_FEATURE_EXTSCAN            0x0020  /* Extended Scan APIs */
+#define WIFI_FEATURE_NAN                0x0040  /* Neighbor Awareness
+						 * Networking
+						 */
+#define WIFI_FEATURE_D2D_RTT		0x0080  /* Device-to-device RTT */
+#define WIFI_FEATURE_D2AP_RTT           0x0100  /* Device-to-AP RTT */
+#define WIFI_FEATURE_BATCH_SCAN         0x0200  /* Batched Scan (legacy) */
+#define WIFI_FEATURE_PNO                0x0400  /* Preferred network offload */
+#define WIFI_FEATURE_ADDITIONAL_STA     0x0800  /* Support for two STAs */
+#define WIFI_FEATURE_TDLS               0x1000  /* Tunnel directed link
+						 * setup
+						 */
+#define WIFI_FEATURE_TDLS_OFFCHANNEL	0x2000  /* Support for TDLS off
+						 * channel
+						 */
+#define WIFI_FEATURE_EPR                0x4000  /* Enhanced power reporting */
+#define WIFI_FEATURE_AP_STA             0x8000  /* Support for AP STA
+						 * Concurrency
+						 */
+#define WIFI_FEATURE_LINK_LAYER_STATS   0x10000  /* Link layer stats */
+#define WIFI_FEATURE_LOGGER             0x20000  /* WiFi Logger */
+#define WIFI_FEATURE_HAL_EPNO           0x40000  /* WiFi PNO enhanced */
+#define WIFI_FEATURE_RSSI_MONITOR       0x80000  /* RSSI Monitor */
+#define WIFI_FEATURE_MKEEP_ALIVE        0x100000  /* WiFi mkeep_alive */
+#define WIFI_FEATURE_CONFIG_NDO         0x200000  /* ND offload configure */
+#define WIFI_FEATURE_TX_TRANSMIT_POWER  0x400000  /* Tx transmit power levels */
+#define WIFI_FEATURE_CONTROL_ROAMING    0x800000  /* Enable/Disable roaming */
+#define WIFI_FEATURE_IE_WHITELIST       0x1000000 /* Support Probe IE white listing */
+#define WIFI_FEATURE_SCAN_RAND          0x2000000 /* Support MAC & Probe Sequence Number randomization */
+
+/* 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)
+#define WIIF_TDLS_OFFCHANNEL_SUPPORT		BIT(2)
+
+#define CFG_NON_AGG_RETRY_MAX                  (31)
+#define CFG_AGG_RETRY_MAX                      (31)
+#define CFG_MGMT_RETRY_MAX                     (31)
+#define CFG_CTRL_RETRY_MAX                     (31)
+#define CFG_PROPAGATION_DELAY_MAX              (63)
+#define CFG_PROPAGATION_DELAY_BASE             (64)
+#define CFG_AGG_RETRY_MIN                      (5)
+
+struct cfg80211_bss *
+wlan_hdd_cfg80211_update_bss_db(struct hdd_adapter *adapter,
+				struct csr_roam_info *roam_info);
+
+#define CONNECTIVITY_CHECK_SET_ARP \
+	QCA_WLAN_VENDOR_CONNECTIVITY_CHECK_SET_ARP
+#define CONNECTIVITY_CHECK_SET_DNS \
+	QCA_WLAN_VENDOR_CONNECTIVITY_CHECK_SET_DNS
+#define CONNECTIVITY_CHECK_SET_TCP_HANDSHAKE \
+	QCA_WLAN_VENDOR_CONNECTIVITY_CHECK_SET_TCP_HANDSHAKE
+#define CONNECTIVITY_CHECK_SET_ICMPV4 \
+	QCA_WLAN_VENDOR_CONNECTIVITY_CHECK_SET_ICMPV4
+#define CONNECTIVITY_CHECK_SET_ICMPV6 \
+	QCA_WLAN_VENDOR_CONNECTIVITY_CHECK_SET_ICMPV6
+#define CONNECTIVITY_CHECK_SET_TCP_SYN \
+	QCA_WLAN_VENDOR_CONNECTIVITY_CHECK_SET_TCP_SYN
+#define CONNECTIVITY_CHECK_SET_TCP_SYN_ACK \
+	QCA_WLAN_VENDOR_CONNECTIVITY_CHECK_SET_TCP_SYN_ACK
+#define CONNECTIVITY_CHECK_SET_TCP_ACK \
+	QCA_WLAN_VENDOR_CONNECTIVITY_CHECK_SET_TCP_ACK
+
+
+int wlan_hdd_cfg80211_pmksa_candidate_notify(struct hdd_adapter *adapter,
+					struct csr_roam_info *roam_info,
+					int index, bool preauth);
+
+#ifdef FEATURE_WLAN_LFR_METRICS
+QDF_STATUS
+wlan_hdd_cfg80211_roam_metrics_preauth(struct hdd_adapter *adapter,
+				       struct csr_roam_info *roam_info);
+
+QDF_STATUS
+wlan_hdd_cfg80211_roam_metrics_preauth_status(struct hdd_adapter *adapter,
+					      struct csr_roam_info *roam_info,
+					      bool preauth_status);
+
+QDF_STATUS
+wlan_hdd_cfg80211_roam_metrics_handover(struct hdd_adapter *adapter,
+					struct csr_roam_info *roam_info);
+#endif
+
+/**
+ * hdd_cfg80211_wiphy_alloc() - Allocate wiphy
+ *
+ * Allocate wiphy and hdd context.
+ *
+ * Return: hdd context on success and NULL on failure.
+ */
+struct hdd_context *hdd_cfg80211_wiphy_alloc(void);
+
+int wlan_hdd_cfg80211_tdls_scan(struct wiphy *wiphy,
+				struct cfg80211_scan_request *request,
+				uint8_t source);
+
+int wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
+			   struct cfg80211_scan_request *request);
+
+int wlan_hdd_cfg80211_init(struct device *dev,
+			   struct wiphy *wiphy, struct hdd_config *pCfg);
+
+void wlan_hdd_cfg80211_deinit(struct wiphy *wiphy);
+
+void wlan_hdd_update_wiphy(struct hdd_context *hdd_ctx);
+
+void wlan_hdd_update_11n_mode(struct hdd_config *cfg);
+
+int wlan_hdd_cfg80211_register(struct wiphy *wiphy);
+
+/**
+ * wlan_hdd_cfg80211_register_frames() - register frame types and callbacks
+ * with the PE.
+ * @adapter: pointer to adapter
+ *
+ * This function is used by HDD to register frame types which are interested
+ * by supplicant, callbacks for rx frame indication and ack.
+ *
+ * Return: 0 on success and non zero value on failure
+ */
+int wlan_hdd_cfg80211_register_frames(struct hdd_adapter *adapter);
+
+void wlan_hdd_cfg80211_deregister_frames(struct hdd_adapter *adapter);
+
+void hdd_reg_notifier(struct wiphy *wiphy,
+				 struct regulatory_request *request);
+
+extern void hdd_conn_set_connection_state(struct hdd_adapter *adapter,
+					  eConnectionState connState);
+QDF_STATUS wlan_hdd_validate_operation_channel(struct hdd_adapter *adapter,
+					       int channel);
+#ifdef FEATURE_WLAN_TDLS
+int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
+					     struct net_device *dev, u8 *peer);
+#endif
+
+void hdd_select_cbmode(struct hdd_adapter *adapter, uint8_t operationChannel,
+		       struct ch_params *ch_params);
+
+/**
+ * wlan_hdd_is_ap_supports_immediate_power_save() - to find certain vendor APs
+ *				which do not support immediate power-save.
+ * @ies: beacon IE of the AP which STA is connecting/connected to
+ * @length: beacon IE length only
+ *
+ * This API takes the IE of connected/connecting AP and determines that
+ * whether it has specific vendor OUI. If it finds then it will return false to
+ * notify that AP doesn't support immediate power-save.
+ *
+ * Return: true or false based on findings
+ */
+bool wlan_hdd_is_ap_supports_immediate_power_save(uint8_t *ies, int length);
+void wlan_hdd_del_station(struct hdd_adapter *adapter);
+
+#if defined(USE_CFG80211_DEL_STA_V2)
+int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
+				  struct net_device *dev,
+				  struct station_del_parameters *param);
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
+				  struct net_device *dev,
+				  const uint8_t *mac);
+#else
+int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
+				  struct net_device *dev,
+				  uint8_t *mac);
+#endif
+#endif /* USE_CFG80211_DEL_STA_V2 */
+
+int wlan_hdd_send_avoid_freq_event(struct hdd_context *hdd_ctx,
+				   struct ch_avoid_ind_type *avoid_freq_list);
+
+/**
+ * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
+ * @hdd_ctx: Pointer to hdd context
+ * @reason: cds recovery reason
+ *
+ * Return: 0 on success or failure reason
+ */
+int wlan_hdd_send_hang_reason_event(struct hdd_context *hdd_ctx,
+				    uint32_t reason);
+
+int wlan_hdd_send_avoid_freq_for_dnbs(struct hdd_context *hdd_ctx,
+				      uint8_t op_chan);
+
+#ifdef FEATURE_WLAN_EXTSCAN
+void wlan_hdd_cfg80211_extscan_callback(hdd_handle_t hdd_handle,
+					const uint16_t evType, void *pMsg);
+#else
+static inline
+void wlan_hdd_cfg80211_extscan_callback(hdd_handle_t hdd_handle,
+					const uint16_t evType, void *pMsg)
+{
+}
+#endif /* FEATURE_WLAN_EXTSCAN */
+/**
+ * wlan_hdd_rso_cmd_status_cb() - HDD callback to read RSO command status
+ * @hdd_handle: opaque handle for the hdd context
+ * @rso_status: rso command status
+ *
+ * This callback function is invoked by firmware to update
+ * the RSO(ROAM SCAN OFFLOAD) command status.
+ *
+ * Return: None
+ */
+void wlan_hdd_rso_cmd_status_cb(hdd_handle_t hdd_handle,
+				struct rso_cmd_status *rso_status);
+
+struct cfg80211_bss *
+wlan_hdd_cfg80211_update_bss_list(struct hdd_adapter *adapter,
+				  tSirMacAddr bssid);
+
+void wlan_hdd_cfg80211_acs_ch_select_evt(struct hdd_adapter *adapter);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+int wlan_hdd_send_roam_auth_event(struct hdd_adapter *adapter, uint8_t *bssid,
+		uint8_t *req_rsn_ie, uint32_t req_rsn_length, uint8_t
+		*rsp_rsn_ie, uint32_t rsp_rsn_length, struct csr_roam_info
+		*roam_info_ptr);
+#else
+static inline int wlan_hdd_send_roam_auth_event(struct hdd_adapter *adapter,
+		uint8_t *bssid, uint8_t *req_rsn_ie, uint32_t req_rsn_length,
+		uint8_t *rsp_rsn_ie, uint32_t rsp_rsn_length,
+		struct csr_roam_info *roam_info_ptr)
+{
+	return 0;
+}
+#endif
+
+int wlan_hdd_cfg80211_update_apies(struct hdd_adapter *adapter);
+int wlan_hdd_request_pre_cac(uint8_t channel);
+int wlan_hdd_sap_cfg_dfs_override(struct hdd_adapter *adapter);
+
+int wlan_hdd_enable_dfs_chan_scan(struct hdd_context *hdd_ctx,
+				  bool enable_dfs_channels);
+
+int wlan_hdd_cfg80211_update_band(struct hdd_context *hdd_ctx,
+				  struct wiphy *wiphy,
+				  enum band_info eBand);
+
+/**
+ * wlan_hdd_try_disconnect() - try disconnnect from previous connection
+ * @adapter: Pointer to adapter
+ *
+ * This function is used to disconnect from previous connection
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_try_disconnect(struct hdd_adapter *adapter);
+
+#if defined(CFG80211_DISCONNECTED_V2) || \
+(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
+static inline void wlan_hdd_cfg80211_indicate_disconnect(struct net_device *dev,
+							bool locally_generated,
+							int reason)
+{
+	cfg80211_disconnected(dev, reason, NULL, 0,
+				locally_generated, GFP_KERNEL);
+}
+#else
+static inline void wlan_hdd_cfg80211_indicate_disconnect(struct net_device *dev,
+							bool locally_generated,
+							int reason)
+{
+	cfg80211_disconnected(dev, reason, NULL, 0,
+				GFP_KERNEL);
+}
+#endif
+
+/**
+ * wlan_hdd_inform_bss_frame() - inform bss details to NL80211
+ * @adapter: Pointer to adapter
+ * @bss_desc: Pointer to bss descriptor
+ *
+ * This function is used to inform the BSS details to nl80211 interface.
+ *
+ * Return: struct cfg80211_bss pointer
+ */
+struct cfg80211_bss *
+wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter,
+				     struct bss_description *bss_desc);
+
+/**
+ * wlan_hdd_change_hw_mode_for_given_chnl() - change HW mode for given channel
+ * @adapter: pointer to adapter
+ * @channel: given channel number
+ * @reason: reason for HW mode change is needed
+ *
+ * This API decides and sets hardware mode to DBS based on given channel.
+ * For example, some of the platforms require DBS hardware mode to operate
+ * in 2.4G channel
+ *
+ * Return: 0 for success and non-zero for failure
+ */
+int wlan_hdd_change_hw_mode_for_given_chnl(struct hdd_adapter *adapter,
+				uint8_t channel,
+				enum policy_mgr_conn_update_reason reason);
+
+/**
+ * hdd_rate_info_bw: an HDD internal rate bandwidth representation
+ * @HDD_RATE_BW_5: 5MHz
+ * @HDD_RATE_BW_10: 10MHz
+ * @HDD_RATE_BW_20: 20MHz
+ * @HDD_RATE_BW_40: 40MHz
+ * @HDD_RATE_BW_80: 80MHz
+ * @HDD_RATE_BW_160: 160 MHz
+ */
+enum hdd_rate_info_bw {
+	HDD_RATE_BW_5,
+	HDD_RATE_BW_10,
+	HDD_RATE_BW_20,
+	HDD_RATE_BW_40,
+	HDD_RATE_BW_80,
+	HDD_RATE_BW_160,
+};
+
+/**
+ * hdd_set_rate_bw(): Set the bandwidth for the given rate_info
+ * @info: The rate info for which the bandwidth should be set
+ * @hdd_bw: HDD representation of a rate info bandwidth
+ */
+void hdd_set_rate_bw(struct rate_info *info, enum hdd_rate_info_bw hdd_bw);
+
+/*
+ * hdd_get_sap_operating_band:  Get current operating channel
+ * for sap.
+ * @hdd_ctx: hdd context
+ *
+ * Return : Corresponding band for SAP operating channel
+ */
+uint8_t hdd_get_sap_operating_band(struct hdd_context *hdd_ctx);
+
+/**
+ * wlan_hdd_try_disconnect() - try disconnnect from previous connection
+ * @adapter: Pointer to adapter
+ *
+ * This function is used to disconnect from previous connection
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_try_disconnect(struct hdd_adapter *adapter);
+
+/**
+ * wlan_hdd_disconnect() - hdd disconnect api
+ * @adapter: Pointer to adapter
+ * @reason: Disconnect reason code
+ *
+ * This function is used to issue a disconnect request to SME
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason);
+
+/**
+ * hdd_update_cca_info_cb() - stores congestion value in station context
+ * @hdd_handle: HDD handle
+ * @congestion: congestion
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void hdd_update_cca_info_cb(hdd_handle_t hdd_handle, uint32_t congestion,
+			    uint32_t vdev_id);
+
+/**
+ * wlan_hdd_get_adjacent_chan(): Gets next/previous channel
+ * to the channel passed.
+ * @chan: Channel
+ * @upper: If "true" then next channel is returned or else
+ * previous channel is returned.
+ *
+ * This function returns the next/previous adjacent-channel to
+ * the channel passed. If "upper = true" then next channel is
+ * returned else previous is returned.
+ */
+int wlan_hdd_get_adjacent_chan(uint8_t chan, bool upper);
+
+/**
+ * wlan_hdd_merge_avoid_freqs(): Merge two tHddAvoidFreqList
+ * @destFreqList: Destination list in which merged frequency
+ * list will be available.
+ * @srcFreqList: Source frequency list.
+ *
+ * Merges two avoid_frequency lists
+ */
+int wlan_hdd_merge_avoid_freqs(struct ch_avoid_ind_type *destFreqList,
+		struct ch_avoid_ind_type *srcFreqList);
+
+
+/**
+ * hdd_bt_activity_cb() - callback function to receive bt activity
+ * @hdd_handle: Opaque handle to the HDD context
+ * @bt_activity: specifies the kind of bt activity
+ *
+ * Return: none
+ */
+void hdd_bt_activity_cb(hdd_handle_t hdd_handle, uint32_t bt_activity);
+
+/**
+ * wlan_hdd_save_gtk_offload_params() - Save gtk offload parameters in STA
+ *                                      context for offload operations.
+ * @adapter: Adapter context
+ * @kck_ptr: KCK buffer pointer
+ * @kek_ptr: KEK buffer pointer
+ * @kek_len: KEK length
+ * @replay_ctr: Pointer to 64 bit long replay counter
+ * @big_endian: true if replay_ctr is in big endian format
+ *
+ * Return: None
+ */
+void wlan_hdd_save_gtk_offload_params(struct hdd_adapter *adapter,
+					     uint8_t *kck_ptr,
+					     uint8_t *kek_ptr,
+					     uint32_t kek_len,
+					     uint8_t *replay_ctr,
+					     bool big_endian);
+/*
+ * wlan_hdd_send_mode_change_event() - API to send hw mode change event to
+ * userspace
+ *
+ * Return : 0 on success and errno on failure
+ */
+int wlan_hdd_send_mode_change_event(void);
+
+/**
+ * wlan_hdd_restore_channels() - Restore the channels which were cached
+ * and disabled in wlan_hdd_disable_channels api.
+ * @hdd_ctx: Pointer to the HDD context
+ * @notify_sap_event: Indicates if SAP event needs to be notified
+ *
+ * Return: 0 on success, Error code on failure
+ */
+int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx,
+			      bool notify_sap_event);
+
+#endif
diff --git a/core/hdd/src/wlan_hdd_conc_ut.c b/core/hdd/src/wlan_hdd_conc_ut.c
new file mode 100644
index 0000000..fc5f1ba
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_conc_ut.c
@@ -0,0 +1,888 @@
+/*
+ * Copyright (c) 2015-2018 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.
+ */
+
+/* Include files */
+
+#include <wlan_hdd_includes.h>
+#include <cds_api.h>
+#include <cds_sched.h>
+#include <wni_api.h>
+#include <wlan_hdd_cfg.h>
+#include "wlan_hdd_trace.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_hdd_conc_ut.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "cds_utils.h"
+#include "wma_types.h"
+#include "wma.h"
+#include "wma_api.h"
+#include "wlan_policy_mgr_ucfg.h"
+
+#define NUMBER_OF_SCENARIO 300
+#define MAX_ALLOWED_CHAR_IN_REPORT 50
+
+/**
+ * struct report_t: Data structure to fill report
+ *
+ * @title: title of the concurrency case scenario
+ * @first_persona: device type of first persona
+ * @second_persona: device type of second persona
+ * @third_persona: device type of third persona
+ * @dbs_value: string to mention whether dbs enable or disable
+ * @system_conf: string to mention what is system's configuration
+ * @status: status field
+ * @result_code: string to mention whether test case passed or failed
+ * @reason: reason why test case failed
+ * @pcl: preferred channel list
+ *
+ * This structure will be used by unit test framework to fill
+ * report after running various concurrency scenarios.
+ */
+struct report_t {
+	char title[2 * MAX_ALLOWED_CHAR_IN_REPORT];
+	char first_persona[MAX_ALLOWED_CHAR_IN_REPORT];
+	char second_persona[MAX_ALLOWED_CHAR_IN_REPORT];
+	char third_persona[MAX_ALLOWED_CHAR_IN_REPORT];
+	char dbs_value[MAX_ALLOWED_CHAR_IN_REPORT];
+	char system_conf[MAX_ALLOWED_CHAR_IN_REPORT];
+	bool status;
+	char result_code[MAX_ALLOWED_CHAR_IN_REPORT];
+	char reason[MAX_ALLOWED_CHAR_IN_REPORT];
+	char pcl[2 * QDF_MAX_NUM_CHAN];
+};
+
+static struct report_t report[NUMBER_OF_SCENARIO];
+static uint32_t report_idx;
+
+static uint8_t wlan_hdd_valid_type_of_persona(uint32_t sub_type)
+{
+	switch (sub_type) {
+	case PM_STA_MODE:
+		return WMI_VDEV_TYPE_STA;
+	case PM_IBSS_MODE:
+		return WMI_VDEV_TYPE_IBSS;
+	case PM_SAP_MODE:
+	case PM_P2P_CLIENT_MODE:
+	case PM_P2P_GO_MODE:
+		return WMI_VDEV_TYPE_AP;
+	default:
+		return WMI_VDEV_TYPE_STA;
+	}
+}
+
+static const char *system_config_to_string(uint8_t idx)
+{
+	switch (idx) {
+	CASE_RETURN_STRING(PM_THROUGHPUT);
+	CASE_RETURN_STRING(PM_POWERSAVE);
+	CASE_RETURN_STRING(PM_LATENCY);
+	default:
+		return "Unknown";
+	}
+
+}
+
+static const char *device_mode_to_string(uint8_t idx)
+{
+	switch (idx) {
+	CASE_RETURN_STRING(PM_STA_MODE);
+	CASE_RETURN_STRING(PM_SAP_MODE);
+	CASE_RETURN_STRING(PM_P2P_CLIENT_MODE);
+	CASE_RETURN_STRING(PM_P2P_GO_MODE);
+	CASE_RETURN_STRING(PM_IBSS_MODE);
+	default:
+		return "none";
+	}
+}
+
+static const char *pcl_type_to_string(uint8_t idx)
+{
+	switch (idx) {
+	CASE_RETURN_STRING(PM_NONE);
+	CASE_RETURN_STRING(PM_24G);
+	CASE_RETURN_STRING(PM_5G);
+	CASE_RETURN_STRING(PM_SCC_CH);
+	CASE_RETURN_STRING(PM_MCC_CH);
+	CASE_RETURN_STRING(PM_SCC_CH_24G);
+	CASE_RETURN_STRING(PM_SCC_CH_5G);
+	CASE_RETURN_STRING(PM_24G_SCC_CH);
+	CASE_RETURN_STRING(PM_5G_SCC_CH);
+	CASE_RETURN_STRING(PM_SCC_ON_5_SCC_ON_24_24G);
+	CASE_RETURN_STRING(PM_SCC_ON_5_SCC_ON_24_5G);
+	CASE_RETURN_STRING(PM_SCC_ON_24_SCC_ON_5_24G);
+	CASE_RETURN_STRING(PM_SCC_ON_24_SCC_ON_5_5G);
+	CASE_RETURN_STRING(PM_SCC_ON_5_SCC_ON_24);
+	CASE_RETURN_STRING(PM_SCC_ON_24_SCC_ON_5);
+	CASE_RETURN_STRING(PM_MCC_CH_24G);
+	CASE_RETURN_STRING(PM_MCC_CH_5G);
+	CASE_RETURN_STRING(PM_24G_MCC_CH);
+	CASE_RETURN_STRING(PM_5G_MCC_CH);
+	default:
+		return "Unknown";
+	}
+}
+
+void clean_report(struct hdd_context *hdd_ctx)
+{
+	uint32_t idx = 0;
+
+	while (idx < NUMBER_OF_SCENARIO) {
+		qdf_mem_zero(&report[idx], sizeof(struct report_t));
+		idx++;
+	}
+	report_idx = 0;
+}
+
+void print_report(struct hdd_context *hdd_ctx)
+{
+	uint32_t idx = 0;
+
+	pr_info("+----------Report start -----------+\n");
+	while (idx < report_idx) {
+		pr_info("Idx:[%d]\nTitle:%s\nResult:[%s]\n\t1st_person[%s]\n\t2nd_persona[%s]\n\t3rd_persona[%s]\n\tDBS[%s]\n\tsystem_config[%s]\n\treason[%s]\n\tpcl[%s]\n",
+			idx,
+			report[idx].title, report[idx].result_code,
+			report[idx].first_persona, report[idx].second_persona,
+			report[idx].third_persona, report[idx].dbs_value,
+			report[idx].system_conf, report[idx].reason,
+			report[idx].pcl);
+		idx++;
+	}
+	pr_info("+----------Report end -----------+\n");
+}
+
+void fill_report(struct hdd_context *hdd_ctx, char *title,
+	uint32_t first_persona, uint32_t second_persona, uint32_t third_persona,
+	uint32_t chnl_1st_conn, uint32_t chnl_2nd_conn, uint32_t chnl_3rd_conn,
+	bool status, enum policy_mgr_pcl_type pcl_type, char *reason,
+	uint8_t *pcl)
+{
+	int i;
+	char buf[4] = {0};
+	uint8_t sys_pref = 0;
+
+	if (report_idx >= NUMBER_OF_SCENARIO)
+		return;
+
+	ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc, &sys_pref);
+
+	snprintf(report[report_idx].title,
+		2 * MAX_ALLOWED_CHAR_IN_REPORT, "pcl for[%s] pcl_type[%s]",
+		title, pcl_type_to_string(pcl_type));
+	if (chnl_1st_conn == 0)
+		snprintf(report[report_idx].first_persona,
+			MAX_ALLOWED_CHAR_IN_REPORT, "%s",
+			device_mode_to_string(first_persona));
+	else
+		snprintf(report[report_idx].first_persona,
+			MAX_ALLOWED_CHAR_IN_REPORT,
+			"%s-chnl{%d}",
+			device_mode_to_string(first_persona), chnl_1st_conn);
+	if (chnl_2nd_conn == 0)
+		snprintf(report[report_idx].second_persona,
+			MAX_ALLOWED_CHAR_IN_REPORT, "%s",
+			device_mode_to_string(second_persona));
+	else
+		snprintf(report[report_idx].second_persona,
+			MAX_ALLOWED_CHAR_IN_REPORT,
+			"%s-chnl{%d}",
+			device_mode_to_string(second_persona), chnl_2nd_conn);
+	if (chnl_3rd_conn == 0)
+		snprintf(report[report_idx].third_persona,
+			MAX_ALLOWED_CHAR_IN_REPORT, "%s",
+			device_mode_to_string(third_persona));
+	else
+		snprintf(report[report_idx].third_persona,
+			MAX_ALLOWED_CHAR_IN_REPORT,
+			"%s-chnl{%d}",
+			device_mode_to_string(third_persona), chnl_3rd_conn);
+
+	report[report_idx].status = status;
+	snprintf(report[report_idx].dbs_value,
+		MAX_ALLOWED_CHAR_IN_REPORT, "%s",
+		policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)
+		? "enable" : "disable");
+	snprintf(report[report_idx].system_conf,
+		MAX_ALLOWED_CHAR_IN_REPORT, "%s",
+		system_config_to_string(sys_pref));
+	snprintf(report[report_idx].result_code,
+		MAX_ALLOWED_CHAR_IN_REPORT, "%s",
+		status ? "PASS" : "FAIL");
+	snprintf(report[report_idx].reason,
+		MAX_ALLOWED_CHAR_IN_REPORT,
+		reason);
+	if (pcl) {
+		qdf_mem_zero(report[report_idx].pcl,
+				sizeof(report[report_idx].pcl));
+		for (i = 0; i < QDF_MAX_NUM_CHAN; i++) {
+			if (pcl[i] == 0)
+				break;
+			qdf_mem_zero(buf, sizeof(buf));
+			snprintf(buf, sizeof(buf), "%d ", pcl[i]);
+			strlcat(report[report_idx].pcl, buf,
+				sizeof(report[report_idx].pcl));
+			strlcat(report[report_idx].pcl, ", ",
+				sizeof(report[report_idx].pcl));
+		}
+	}
+	report_idx++;
+}
+
+static bool wlan_hdd_validate_pcl(struct hdd_context *hdd_ctx,
+	enum policy_mgr_pcl_type pcl_type, uint8_t *pcl, uint32_t pcl_len,
+	uint8_t first_connection_chnl, uint8_t second_connection_chnl,
+	char *reason, uint32_t reason_length)
+{
+	bool status = true;
+	uint32_t first_idx = 0;
+
+	if ((pcl_type != PM_NONE) && (pcl_len == 0)) {
+		snprintf(reason, reason_length, "no of channels = 0");
+		return false;
+	}
+
+	switch (pcl_type) {
+	case PM_NONE:
+		if (pcl_len != 0) {
+			snprintf(reason, reason_length, "no of channels>0");
+			return false;
+		}
+		break;
+	case PM_5G:
+		for (first_idx = 0; first_idx < pcl_len; first_idx++) {
+			if (!WLAN_REG_IS_5GHZ_CH(pcl[first_idx])) {
+				snprintf(reason, reason_length,
+					"2G channel found");
+				return false;
+			}
+		}
+		break;
+	case PM_24G:
+		for (first_idx = 0; first_idx < pcl_len; first_idx++) {
+			if (!WLAN_REG_IS_24GHZ_CH(pcl[first_idx])) {
+				snprintf(reason, reason_length,
+					"5G channel found");
+				return false;
+			}
+		}
+		break;
+	case PM_SCC_CH:
+		if (second_connection_chnl > 0 &&
+			(first_connection_chnl != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"invalid connections");
+			return false;
+		}
+		if (pcl[0] != first_connection_chnl) {
+			snprintf(reason, reason_length,
+				"No SCC found");
+			return false;
+		}
+		break;
+	case PM_MCC_CH:
+		if ((pcl[0] != first_connection_chnl) &&
+				((second_connection_chnl > 0) &&
+				 (pcl[0] != second_connection_chnl))) {
+			snprintf(reason, reason_length,
+				"MCC invalid");
+			return false;
+		}
+		if ((second_connection_chnl > 0) &&
+				(pcl[1] != first_connection_chnl &&
+				 pcl[1] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"MCC invalid");
+			return false;
+		}
+		break;
+	case PM_SCC_CH_24G:
+		if (second_connection_chnl > 0 &&
+			(first_connection_chnl != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"invalid connections");
+			return false;
+		}
+		if (pcl[0] != first_connection_chnl) {
+			snprintf(reason, reason_length,
+				"No SCC found");
+			return false;
+		}
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[pcl_len - 1])) {
+			snprintf(reason, reason_length,
+				"No 2.4Ghz chnl");
+			return false;
+		}
+		break;
+	case PM_SCC_CH_5G:
+		if (second_connection_chnl > 0 &&
+			(first_connection_chnl != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"invalid connections");
+			return false;
+		}
+		if (pcl[0] != first_connection_chnl) {
+			snprintf(reason, reason_length,
+				"No SCC found");
+			return false;
+		}
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[pcl_len - 1])) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnl");
+			return false;
+		}
+		break;
+	case PM_24G_SCC_CH:
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[0])) {
+			snprintf(reason, reason_length,
+				"No 2.4Ghz chnl");
+			return false;
+		}
+		if (second_connection_chnl > 0 &&
+			(first_connection_chnl != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"invalid connections");
+			return false;
+		}
+		if (pcl[pcl_len-1] != first_connection_chnl) {
+			snprintf(reason, reason_length,
+				"No SCC found");
+			return false;
+		}
+		break;
+	case PM_5G_SCC_CH:
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[0])) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnl");
+			return false;
+		}
+		if (second_connection_chnl > 0 &&
+			(first_connection_chnl != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"invalid connections");
+			return false;
+		}
+		if (pcl[pcl_len-1] != first_connection_chnl) {
+			snprintf(reason, reason_length,
+				"No SCC found");
+			return false;
+		}
+		break;
+	case PM_MCC_CH_24G:
+		if ((pcl[0] != first_connection_chnl) &&
+			((second_connection_chnl > 0) &&
+			 (pcl[0] != second_connection_chnl))) {
+			snprintf(reason, reason_length,
+				"MCC invalid");
+			return false;
+		}
+		if ((second_connection_chnl > 0) &&
+			(pcl[1] != first_connection_chnl &&
+			 pcl[1] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"MCC invalid");
+			return false;
+		}
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[pcl_len - 1])) {
+			snprintf(reason, reason_length,
+				"No 24Ghz chnl");
+			return false;
+		}
+		break;
+	case PM_MCC_CH_5G:
+		if ((pcl[0] != first_connection_chnl) &&
+			((second_connection_chnl > 0) &&
+			 (pcl[0] != second_connection_chnl))) {
+			snprintf(reason, reason_length,
+				"MCC invalid");
+			return false;
+		}
+		if ((second_connection_chnl > 0) &&
+			(pcl[1] != first_connection_chnl &&
+			 pcl[1] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"MCC invalid");
+			return false;
+		}
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[pcl_len - 1])) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnl");
+			return false;
+		}
+		break;
+	case PM_24G_MCC_CH:
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[0])) {
+			snprintf(reason, reason_length,
+				"No 24Ghz chnl");
+			return false;
+		}
+		if ((pcl[pcl_len-1] != first_connection_chnl) &&
+			((second_connection_chnl > 0) &&
+			 (pcl[pcl_len-1] != second_connection_chnl))) {
+			snprintf(reason, reason_length,
+				"MCC invalid");
+			return false;
+		}
+		if ((second_connection_chnl > 0) &&
+			(pcl[pcl_len-2] != first_connection_chnl &&
+			 pcl[pcl_len-2] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"MCC invalid");
+			return false;
+		}
+		break;
+	case PM_5G_MCC_CH:
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[0])) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnl");
+			return false;
+		}
+		if ((pcl[pcl_len-1] != first_connection_chnl) &&
+			((second_connection_chnl > 0) &&
+			 (pcl[pcl_len-1] != second_connection_chnl))) {
+			snprintf(reason, reason_length,
+				"MCC invalid");
+			return false;
+		}
+		if ((second_connection_chnl > 0) &&
+			(pcl[pcl_len-2] != first_connection_chnl &&
+			 pcl[pcl_len-2] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"MCC invalid");
+			return false;
+		}
+		break;
+	case PM_SCC_ON_5_SCC_ON_24_24G:
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[0]) ||
+			(pcl[0] != first_connection_chnl &&
+			 pcl[0] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnl/scc");
+			return false;
+		}
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[1]) ||
+			(pcl[1] != first_connection_chnl &&
+			 pcl[1] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 24Ghz chnl/scc");
+			return false;
+		}
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[pcl_len - 1])) {
+			snprintf(reason, reason_length,
+				"No 24Ghz chnls");
+			return false;
+		}
+		break;
+	case PM_SCC_ON_5_SCC_ON_24_5G:
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[0]) ||
+			(pcl[0] != first_connection_chnl &&
+			 pcl[0] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnl/scc");
+			return false;
+		}
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[1]) ||
+			(pcl[1] != first_connection_chnl &&
+			 pcl[1] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 24Ghz chnl/scc");
+			return false;
+		}
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[pcl_len - 1])) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnls");
+			return false;
+		}
+		break;
+	case PM_SCC_ON_24_SCC_ON_5_24G:
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[0]) ||
+			(pcl[0] != first_connection_chnl &&
+			 pcl[0] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 24Ghz chnl/scc");
+			return false;
+		}
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[1]) ||
+			(pcl[1] != first_connection_chnl &&
+			 pcl[1] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnl/scc");
+			return false;
+		}
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[pcl_len - 1])) {
+			snprintf(reason, reason_length,
+				"No 24Ghz chnls");
+			return false;
+		}
+		break;
+	case PM_SCC_ON_24_SCC_ON_5_5G:
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[0]) ||
+			(pcl[0] != first_connection_chnl &&
+			 pcl[0] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 24Ghz chnl/scc");
+			return false;
+		}
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[1]) ||
+			(pcl[1] != first_connection_chnl &&
+			 pcl[1] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnl/scc");
+			return false;
+		}
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[pcl_len - 1])) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnls");
+			return false;
+		}
+		break;
+	case PM_SCC_ON_5_SCC_ON_24:
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[0]) ||
+			(pcl[0] != first_connection_chnl &&
+			 pcl[0] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnl/scc");
+			return false;
+		}
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[1]) ||
+			(pcl[1] != first_connection_chnl &&
+			 pcl[1] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 24Ghz chnl/scc");
+			return false;
+		}
+		if (pcl_len != 2) {
+			snprintf(reason, reason_length,
+				"more than 2 chnls");
+			return false;
+		}
+		break;
+	case PM_SCC_ON_24_SCC_ON_5:
+		if (!WLAN_REG_IS_24GHZ_CH(pcl[0]) ||
+			(pcl[0] != first_connection_chnl &&
+			 pcl[0] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 24Ghz chnl/scc");
+			return false;
+		}
+		if (!WLAN_REG_IS_5GHZ_CH(pcl[1]) ||
+			(pcl[1] != first_connection_chnl &&
+			 pcl[1] != second_connection_chnl)) {
+			snprintf(reason, reason_length,
+				"No 5Ghz chnl/scc");
+			return false;
+		}
+		if (pcl_len != 2) {
+			snprintf(reason, reason_length,
+				"more than 2 chnls");
+			return false;
+		}
+		break;
+	default:
+		snprintf(reason, reason_length,
+			"Unknown option");
+		status = false;
+	}
+	if (status == true) {
+		snprintf(reason, reason_length,
+			"success");
+	}
+	return status;
+}
+
+static void wlan_hdd_map_subtypes_hdd_wma(enum policy_mgr_con_mode *dst,
+		enum policy_mgr_con_mode *src)
+{
+	/*
+	 * wma defined sap subtype as 0
+	 * Rest of the mappings are same
+	 * In future, if mapping gets changed then re-map it here
+	 */
+	if (*src == PM_SAP_MODE)
+		*dst = 0;
+	else
+		*dst = *src;
+}
+
+void wlan_hdd_one_connection_scenario(struct hdd_context *hdd_ctx)
+{
+	enum policy_mgr_con_mode sub_type;
+	uint8_t pcl[QDF_MAX_NUM_CHAN] = {0},
+		weight_list[QDF_MAX_NUM_CHAN] = {0};
+	uint32_t pcl_len = 0;
+	bool status = false;
+	enum policy_mgr_pcl_type pcl_type;
+	char reason[20] = {0};
+	QDF_STATUS ret;
+	struct policy_mgr_sme_cbacks sme_cbacks;
+	uint8_t system_pref = 0;
+
+	ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc, &system_pref);
+
+	sme_cbacks.sme_get_valid_channels = sme_get_valid_channels;
+	sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss;
+	/* flush the entire table first */
+	ret = policy_mgr_psoc_enable(hdd_ctx->psoc);
+	if (!QDF_IS_STATUS_SUCCESS(ret)) {
+		hdd_err("Policy manager initialization failed");
+		return;
+	}
+
+	for (sub_type = 0; sub_type < PM_MAX_NUM_OF_MODE; sub_type++) {
+		/* validate one connection is created or no */
+		if (policy_mgr_get_connection_count(hdd_ctx->psoc) != 0) {
+			hdd_err("Test failed - No. of connection is not 0");
+			return;
+		}
+		qdf_mem_zero(pcl, sizeof(pcl));
+		pcl_len = 0;
+		pcl_type = policy_mgr_get_pcl_from_first_conn_table(
+			sub_type, system_pref);
+
+		/* check PCL value for second connection is correct or no */
+		policy_mgr_get_pcl(hdd_ctx->psoc, sub_type, pcl, &pcl_len,
+				weight_list, QDF_ARRAY_SIZE(weight_list));
+		status = wlan_hdd_validate_pcl(hdd_ctx,
+				pcl_type, pcl, pcl_len, 0, 0,
+				reason, sizeof(reason));
+		if ((pcl_type == PM_MAX_PCL_TYPE) && (pcl[0] == 0))
+			continue;
+
+		fill_report(hdd_ctx, "1 connection", sub_type,
+				PM_MAX_NUM_OF_MODE,
+				PM_MAX_NUM_OF_MODE,
+				0, 0, 0,
+				status, pcl_type, reason, pcl);
+	}
+}
+
+void wlan_hdd_two_connections_scenario(struct hdd_context *hdd_ctx,
+		uint8_t first_chnl, enum policy_mgr_chain_mode first_chain_mask)
+{
+	uint8_t vdevid = 0, tx_stream = 2, rx_stream = 2;
+	uint8_t type = WMI_VDEV_TYPE_STA, channel_id = first_chnl, mac_id = 1;
+	uint8_t pcl[QDF_MAX_NUM_CHAN] = {0},
+			weight_list[QDF_MAX_NUM_CHAN] = {0};
+	uint32_t pcl_len = 0;
+	enum policy_mgr_chain_mode chain_mask = first_chain_mask;
+	enum policy_mgr_con_mode sub_type, next_sub_type, dummy_type;
+	enum policy_mgr_pcl_type pcl_type;
+	enum policy_mgr_one_connection_mode second_index;
+	char reason[20] = {0};
+	bool status = false;
+	QDF_STATUS ret;
+	struct policy_mgr_sme_cbacks sme_cbacks;
+	uint8_t system_pref = 0;
+
+	ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc, &system_pref);
+
+	for (sub_type = PM_STA_MODE;
+		sub_type < PM_MAX_NUM_OF_MODE; sub_type++) {
+		type = wlan_hdd_valid_type_of_persona(sub_type);
+
+		sme_cbacks.sme_get_valid_channels = sme_get_valid_channels;
+		sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss;
+		/* flush the entire table first */
+		ret = policy_mgr_psoc_enable(hdd_ctx->psoc);
+		if (!QDF_IS_STATUS_SUCCESS(ret)) {
+			hdd_err("Policy manager initialization failed");
+			return;
+		}
+
+		/* sub_type mapping between HDD and WMA are different */
+		wlan_hdd_map_subtypes_hdd_wma(&dummy_type, &sub_type);
+		/* add first connection as STA */
+		policy_mgr_incr_connection_count_utfw(hdd_ctx->psoc,
+				vdevid, tx_stream,
+				rx_stream, chain_mask, type, dummy_type,
+				channel_id, mac_id);
+		/* validate one connection is created or no */
+		if (policy_mgr_get_connection_count(hdd_ctx->psoc) != 1) {
+			hdd_err("Test failed - No. of connection is not 1");
+			return;
+		}
+		next_sub_type = PM_STA_MODE;
+		while (next_sub_type < PM_MAX_NUM_OF_MODE) {
+			/* get the PCL value & check the channels accordingly */
+			second_index =
+			policy_mgr_get_second_connection_pcl_table_index(
+				hdd_ctx->psoc);
+			if (PM_MAX_ONE_CONNECTION_MODE == second_index) {
+				/* not valid combination*/
+				hdd_err("couldn't find index for 2nd connection pcl table");
+				next_sub_type++;
+				continue;
+			}
+			qdf_mem_zero(pcl, sizeof(pcl));
+			pcl_len = 0;
+			pcl_type = policy_mgr_get_pcl_from_second_conn_table(
+				second_index, next_sub_type, system_pref,
+				policy_mgr_is_hw_dbs_capable(
+					hdd_ctx->psoc));
+			/* check PCL for second connection is correct or no */
+			policy_mgr_get_pcl(hdd_ctx->psoc,
+				next_sub_type, pcl, &pcl_len,
+				weight_list, QDF_ARRAY_SIZE(weight_list));
+			status = wlan_hdd_validate_pcl(hdd_ctx,
+					pcl_type, pcl, pcl_len, channel_id, 0,
+					reason, sizeof(reason));
+			if ((pcl_type == PM_MAX_PCL_TYPE) && (pcl[0] == 0)) {
+				next_sub_type++;
+				continue;
+			}
+			fill_report(hdd_ctx, "2 connections", sub_type,
+					next_sub_type,
+					PM_MAX_NUM_OF_MODE, first_chnl,
+					0, 0, status, pcl_type, reason, pcl);
+			next_sub_type++;
+		}
+	}
+}
+
+void wlan_hdd_three_connections_scenario(struct hdd_context *hdd_ctx,
+		uint8_t first_chnl, uint8_t second_chnl,
+		enum policy_mgr_chain_mode chain_mask, uint8_t use_same_mac)
+{
+	uint8_t vdevid_1 = 0, tx_stream_1 = 2, rx_stream_1 = 2;
+	uint8_t vdevid_2 = 1, tx_stream_2 = 2, rx_stream_2 = 2;
+	uint8_t channel_id_1 = first_chnl, channel_id_2 = second_chnl;
+	uint8_t mac_id_1, mac_id_2;
+	uint8_t type_1 = WMI_VDEV_TYPE_STA, type_2 = WMI_VDEV_TYPE_STA;
+	uint8_t pcl[MAX_NUM_CHAN] = {0}, weight_list[MAX_NUM_CHAN] = {0};
+	uint32_t pcl_len = 0;
+	enum policy_mgr_chain_mode chain_mask_1;
+	enum policy_mgr_chain_mode chain_mask_2;
+	enum policy_mgr_con_mode sub_type_1, sub_type_2, next_sub_type;
+	enum policy_mgr_con_mode dummy_type_1, dummy_type_2;
+	enum policy_mgr_pcl_type pcl_type;
+	enum policy_mgr_two_connection_mode third_index;
+	char reason[20] = {0};
+	bool status = false;
+	QDF_STATUS ret;
+	struct policy_mgr_sme_cbacks sme_cbacks;
+	uint8_t system_pref = 0;
+
+	ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc, &system_pref);
+
+	/* let's set the chain_mask, mac_ids*/
+	if (chain_mask == POLICY_MGR_TWO_TWO) {
+		mac_id_1 = 1;
+		mac_id_2 = 1;
+		chain_mask_1 = POLICY_MGR_TWO_TWO;
+		chain_mask_2 = POLICY_MGR_TWO_TWO;
+	} else if (use_same_mac == 1) {
+		mac_id_1 = 1;
+		mac_id_2 = 1;
+		chain_mask_1 = POLICY_MGR_ONE_ONE;
+		chain_mask_2 = POLICY_MGR_ONE_ONE;
+	} else {
+		mac_id_1 = 1;
+		mac_id_2 = 2;
+		chain_mask_1 = POLICY_MGR_ONE_ONE;
+		chain_mask_2 = POLICY_MGR_ONE_ONE;
+	}
+
+	for (sub_type_1 = PM_STA_MODE;
+		sub_type_1 < PM_MAX_NUM_OF_MODE; sub_type_1++) {
+
+		type_1 = wlan_hdd_valid_type_of_persona(sub_type_1);
+
+		sme_cbacks.sme_get_valid_channels = sme_get_valid_channels;
+		sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss;
+		/* flush the entire table first */
+		ret = policy_mgr_psoc_enable(hdd_ctx->psoc);
+		if (!QDF_IS_STATUS_SUCCESS(ret)) {
+			hdd_err("Policy manager initialization failed");
+			return;
+		}
+
+		/* sub_type mapping between HDD and WMA are different */
+		wlan_hdd_map_subtypes_hdd_wma(&dummy_type_1, &sub_type_1);
+		/* add first connection as STA */
+		policy_mgr_incr_connection_count_utfw(hdd_ctx->psoc,
+			vdevid_1, tx_stream_1, rx_stream_1, chain_mask_1,
+			type_1,	dummy_type_1, channel_id_1, mac_id_1);
+		/* validate one connection is created or no */
+		if (policy_mgr_get_connection_count(hdd_ctx->psoc) != 1) {
+			hdd_err("Test fail - No. of connection not 1");
+			return;
+		}
+		for (sub_type_2 = PM_STA_MODE;
+			sub_type_2 < PM_MAX_NUM_OF_MODE; sub_type_2++) {
+
+			type_2 = wlan_hdd_valid_type_of_persona(sub_type_2);
+			/* sub_type mapping between HDD and WMA are different */
+			wlan_hdd_map_subtypes_hdd_wma(&dummy_type_2,
+					&sub_type_2);
+			policy_mgr_incr_connection_count_utfw(hdd_ctx->psoc,
+				vdevid_2, tx_stream_2, rx_stream_2,
+				chain_mask_2, type_2,
+				dummy_type_2, channel_id_2, mac_id_2);
+			/* validate two connections are created or no */
+			if (policy_mgr_get_connection_count(hdd_ctx->psoc)
+				!= 2) {
+				hdd_err("Test fail - No. connection not 2");
+				return;
+			}
+			next_sub_type = PM_STA_MODE;
+			while (next_sub_type < PM_MAX_NUM_OF_MODE) {
+				third_index =
+				policy_mgr_get_third_connection_pcl_table_index(
+						hdd_ctx->psoc);
+				if (PM_MAX_TWO_CONNECTION_MODE ==
+						third_index) {
+					/* not valid combination */
+					next_sub_type++;
+					continue;
+				}
+				qdf_mem_zero(pcl, sizeof(pcl));
+				pcl_len = 0;
+				pcl_type =
+				policy_mgr_get_pcl_from_third_conn_table(
+					third_index, next_sub_type,
+					system_pref,
+					policy_mgr_is_hw_dbs_capable(
+					hdd_ctx->psoc));
+				policy_mgr_get_pcl(hdd_ctx->psoc,
+					next_sub_type,
+					pcl, &pcl_len,
+					weight_list,
+					QDF_ARRAY_SIZE(weight_list));
+				status = wlan_hdd_validate_pcl(hdd_ctx,
+					pcl_type, pcl, pcl_len,
+					channel_id_1, channel_id_2,
+					reason, sizeof(reason));
+				if ((pcl_type == PM_MAX_PCL_TYPE) &&
+					(pcl[0] == 0)) {
+					next_sub_type++;
+					continue;
+				}
+				fill_report(hdd_ctx, "3 connections",
+					sub_type_1, sub_type_2,
+					next_sub_type, first_chnl,
+					second_chnl, 0, status,
+					pcl_type, reason, pcl);
+				next_sub_type++;
+			}
+			/* remove entry to make a room for next iteration */
+			policy_mgr_decr_connection_count(hdd_ctx->psoc,
+				vdevid_2);
+		}
+		next_sub_type = PM_STA_MODE;
+	}
+}
diff --git a/core/hdd/src/wlan_hdd_concurrency_matrix.c b/core/hdd/src/wlan_hdd_concurrency_matrix.c
new file mode 100644
index 0000000..bb96208
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_concurrency_matrix.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_concurrency_matrix.c
+ *
+ * WLAN concurrency matrix functions
+ *
+ */
+
+#include <wlan_hdd_includes.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <wlan_hdd_concurrency_matrix.h>
+
+#define CDS_MAX_FEATURE_SET   8
+#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
+ * @wdev: pointer to wireless device structure
+ * @data: pointer to data buffer
+ * @data_len: length of data
+ *
+ * This routine will give concurrency matrix
+ *
+ * Return: int status code
+ */
+static int
+__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data,
+					   int data_len)
+{
+	uint32_t feature_set_matrix[CDS_MAX_FEATURE_SET] = {0};
+	uint8_t i, feature_sets, max_feature_sets;
+	struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
+	struct sk_buff *reply_skb;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int ret;
+
+	hdd_enter_dev(wdev->netdev);
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (wlan_cfg80211_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[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
+		hdd_err("Attr max feature set size failed");
+		return -EINVAL;
+	}
+	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 */
+	feature_sets = 0;
+	feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
+						WIFI_FEATURE_P2P;
+	feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
+						WIFI_FEATURE_NAN;
+	/* Add more feature combinations here */
+
+	feature_sets = QDF_MIN(feature_sets, max_feature_sets);
+	hdd_debug("Number of feature sets: %d", feature_sets);
+	hdd_debug("Feature set matrix");
+	for (i = 0; i < feature_sets; i++)
+		hdd_debug("[%d] 0x%02X", i, feature_set_matrix[i]);
+
+	reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
+			sizeof(u32) * feature_sets + NLMSG_HDRLEN);
+	if (!reply_skb) {
+		hdd_err("Feature set matrix: buffer alloc fail");
+		return -ENOMEM;
+	}
+
+	if (nla_put_u32(reply_skb,
+		QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
+		feature_sets) ||
+	    nla_put(reply_skb,
+		    QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
+		    sizeof(u32) * feature_sets,
+		    feature_set_matrix)) {
+		hdd_err("nla put fail");
+		kfree_skb(reply_skb);
+		return -EINVAL;
+	}
+	return cfg80211_vendor_cmd_reply(reply_skb);
+}
+
+#undef MAX_CONCURRENT_MATRIX
+#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
+
+int wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data,
+					     int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev,
+							 data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
diff --git a/core/hdd/src/wlan_hdd_concurrency_matrix.h b/core/hdd/src/wlan_hdd_concurrency_matrix.h
new file mode 100644
index 0000000..1bdc6f7
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_concurrency_matrix.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __WLAN_HDD_CONCURRENCY_MATRIX_H
+#define __WLAN_HDD_CONCURRENCY_MATRIX_H
+
+/**
+ * DOC: wlan_hdd_concurrency_matrix_h
+ *
+ * WLAN Host Device Driver concurrency matrix API specification
+ */
+
+#ifdef FEATURE_CONCURRENCY_MATRIX
+/**
+ * wlan_hdd_cfg80211_get_concurrency_matrix() - get concurrency matrix
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Retrieves the concurrency feature set matrix
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data,
+					     int data_len);
+
+#define FEATURE_CONCURRENCY_MATRIX_VENDOR_COMMANDS			\
+{									\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,			\
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,\
+	.doit = wlan_hdd_cfg80211_get_concurrency_matrix		\
+},
+#else /* FEATURE_CONCURRENCY_MATRIX */
+#define FEATURE_CONCURRENCY_MATRIX_VENDOR_COMMANDS
+#endif /* FEATURE_CONCURRENCY_MATRIX */
+
+#endif /* __WLAN_HDD_CONCURRENCY_MATRIX_H */
+
diff --git a/core/hdd/src/wlan_hdd_data_stall_detection.c b/core/hdd/src/wlan_hdd_data_stall_detection.c
new file mode 100644
index 0000000..b7f3917
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_data_stall_detection.c
@@ -0,0 +1,85 @@
+/*
+ * 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: wlan_hdd_data_stall_detection.c
+ *
+ * WLAN Host Device Driver Data Stall detection API implementation
+ */
+
+#include "wlan_hdd_data_stall_detection.h"
+#include "cdp_txrx_cmn.h"
+#include "cdp_txrx_misc.h"
+#include "ol_txrx_types.h"
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+
+/**
+ * hdd_data_stall_send_event()- send data stall information
+ * @reason: data stall event subtype
+ * This Function sends data stall status diag event
+ *
+ * Return: void.
+ */
+static void hdd_data_stall_send_event(uint32_t reason)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(sta_data_stall,
+				struct host_event_wlan_datastall);
+	qdf_mem_zero(&sta_data_stall, sizeof(sta_data_stall));
+	sta_data_stall.reason = reason;
+	WLAN_HOST_DIAG_EVENT_REPORT(&sta_data_stall, EVENT_WLAN_STA_DATASTALL);
+}
+#else
+static inline void hdd_data_stall_send_event(uint32_t reason)
+{
+}
+#endif
+
+/**
+ * hdd_data_stall_process_cb() - Process data stall message
+ * @message: data stall message
+ *
+ * Process data stall message
+ *
+ * Return: void
+ */
+static void hdd_data_stall_process_cb(
+			struct data_stall_event_info *data_stall_info)
+{
+	hdd_data_stall_send_event(data_stall_info->data_stall_type);
+}
+
+int hdd_register_data_stall_detect_cb(void)
+{
+	QDF_STATUS status;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	/* Register the data stall callback */
+	status = cdp_data_stall_cb_register(soc, hdd_data_stall_process_cb);
+	return qdf_status_to_os_return(status);
+}
+
+int hdd_deregister_data_stall_detect_cb(void)
+{
+	QDF_STATUS status;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	/* De-Register the data stall callback */
+	status = cdp_data_stall_cb_deregister(soc, hdd_data_stall_process_cb);
+	return qdf_status_to_os_return(status);
+}
diff --git a/core/hdd/src/wlan_hdd_debugfs.c b/core/hdd/src/wlan_hdd_debugfs.c
new file mode 100644
index 0000000..eeb2bf4
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_debugfs.c
@@ -0,0 +1,536 @@
+/*
+ * Copyright (c) 2013-2018 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: wlan_hdd_debugfs.c
+ *
+ * This driver currently supports the following debugfs files:
+ * wlan_wcnss/wow_enable to enable/disable WoWL.
+ * wlan_wcnss/wow_pattern to configure WoWL patterns.
+ * wlan_wcnss/pattern_gen to configure periodic TX patterns.
+ */
+
+#ifdef WLAN_OPEN_SOURCE
+#include <wlan_hdd_includes.h>
+#include <wlan_hdd_debugfs.h>
+#include <wlan_osif_request_manager.h>
+#include <wlan_hdd_wowl.h>
+#include <cds_sched.h>
+#include <wlan_hdd_debugfs_llstat.h>
+
+#define MAX_USER_COMMAND_SIZE_WOWL_ENABLE 8
+#define MAX_USER_COMMAND_SIZE_WOWL_PATTERN 512
+#define MAX_USER_COMMAND_SIZE_FRAME 4096
+
+#define MAX_DEBUGFS_WAIT_ITERATIONS 20
+#define DEBUGFS_WAIT_SLEEP_TIME 100
+
+static qdf_atomic_t debugfs_thread_count;
+
+void hdd_debugfs_thread_increment(void)
+{
+	qdf_atomic_inc(&debugfs_thread_count);
+}
+
+void hdd_debugfs_thread_decrement(void)
+{
+	qdf_atomic_dec(&debugfs_thread_count);
+}
+
+int hdd_return_debugfs_threads_count(void)
+{
+	return qdf_atomic_read(&debugfs_thread_count);
+}
+
+bool hdd_wait_for_debugfs_threads_completion(void)
+{
+	int count = MAX_DEBUGFS_WAIT_ITERATIONS;
+	int r;
+
+	while (count) {
+		r = hdd_return_debugfs_threads_count();
+		if (!r)
+			break;
+
+		if (--count) {
+			hdd_debug("Waiting for %d debugfs threads to exit", r);
+			qdf_sleep(DEBUGFS_WAIT_SLEEP_TIME);
+		}
+	}
+
+	/* at least one debugfs thread is executing */
+	if (!count) {
+		hdd_err("Timed-out waiting for debugfs threads");
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * __wcnss_wowpattern_write() - wow_pattern debugfs handler
+ * @file: debugfs file handle
+ * @buf: text being written to the debugfs
+ * @count: size of @buf
+ * @ppos: (unused) offset into the virtual file system
+ *
+ * Return: number of bytes processed
+ */
+static ssize_t __wcnss_wowpattern_write(struct file *file,
+				      const char __user *buf, size_t count,
+				      loff_t *ppos)
+{
+	struct hdd_adapter *adapter = (struct hdd_adapter *) file->private_data;
+	struct hdd_context *hdd_ctx;
+	char cmd[MAX_USER_COMMAND_SIZE_WOWL_PATTERN + 1];
+	char *sptr, *token;
+	uint8_t pattern_idx = 0;
+	uint8_t pattern_offset = 0;
+	char *pattern_buf;
+	char *pattern_mask;
+	int ret;
+
+	hdd_enter();
+
+	if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		hdd_err("Invalid adapter or adapter has invalid magic");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	if (!wlan_hdd_validate_modules_state(hdd_ctx))
+		return -EINVAL;
+
+	if (!sme_is_feature_supported_by_fw(WOW)) {
+		hdd_err("Wake-on-Wireless feature is not supported in firmware!");
+		return -EINVAL;
+	}
+
+	if (count > MAX_USER_COMMAND_SIZE_WOWL_PATTERN) {
+		hdd_err("Command length is larger than %d bytes",
+			MAX_USER_COMMAND_SIZE_WOWL_PATTERN);
+		return -EINVAL;
+	}
+
+	/* Get command from user */
+	if (copy_from_user(cmd, buf, count))
+		return -EFAULT;
+	cmd[count] = '\0';
+	sptr = cmd;
+
+	/* Get pattern idx */
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+
+	if (kstrtou8(token, 0, &pattern_idx))
+		return -EINVAL;
+
+	/* Get pattern offset */
+	token = strsep(&sptr, " ");
+
+	/* Delete pattern if no further argument */
+	if (!token) {
+		hdd_del_wowl_ptrn_debugfs(adapter, pattern_idx);
+
+		return count;
+	}
+
+	if (kstrtou8(token, 0, &pattern_offset))
+		return -EINVAL;
+
+	/* Get pattern */
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+
+	pattern_buf = token;
+
+	/* Get pattern mask */
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+
+	pattern_mask = token;
+	pattern_mask[strlen(pattern_mask) - 1] = '\0';
+
+	hdd_add_wowl_ptrn_debugfs(adapter, pattern_idx, pattern_offset,
+				  pattern_buf, pattern_mask);
+	hdd_exit();
+	return count;
+}
+
+/**
+ * wcnss_wowpattern_write() - SSR wrapper for __wcnss_wowpattern_write
+ * @file: file pointer
+ * @buf: buffer
+ * @count: count
+ * @ppos: position pointer
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static ssize_t wcnss_wowpattern_write(struct file *file,
+				      const char __user *buf,
+				      size_t count, loff_t *ppos)
+{
+	ssize_t ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wcnss_wowpattern_write(file, buf, count, ppos);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wcnss_patterngen_write() - pattern_gen debugfs handler
+ * @file: debugfs file handle
+ * @buf: text being written to the debugfs
+ * @count: size of @buf
+ * @ppos: (unused) offset into the virtual file system
+ *
+ * Return: number of bytes processed
+ */
+static ssize_t __wcnss_patterngen_write(struct file *file,
+				      const char __user *buf, size_t count,
+				      loff_t *ppos)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	tSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams;
+	tSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams;
+
+	char *cmd, *sptr, *token;
+	uint8_t pattern_idx = 0;
+	uint8_t pattern_duration = 0;
+	char *pattern_buf;
+	uint16_t pattern_len = 0;
+	uint16_t i = 0;
+	QDF_STATUS status;
+	int ret;
+
+	hdd_enter();
+
+	adapter = (struct hdd_adapter *)file->private_data;
+	if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		hdd_err("Invalid adapter or adapter has invalid magic");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	if (!wlan_hdd_validate_modules_state(hdd_ctx))
+		return -EINVAL;
+
+	if (!sme_is_feature_supported_by_fw(WLAN_PERIODIC_TX_PTRN)) {
+		hdd_err("Periodic Tx Pattern Offload feature is not supported in firmware!");
+		return -EINVAL;
+	}
+
+	/* Get command from user */
+	if (count <= MAX_USER_COMMAND_SIZE_FRAME)
+		cmd = qdf_mem_malloc(count + 1);
+	else {
+		hdd_err("Command length is larger than %d bytes",
+			MAX_USER_COMMAND_SIZE_FRAME);
+
+		return -EINVAL;
+	}
+
+	if (!cmd) {
+		hdd_err("Memory allocation for cmd failed!");
+		return -ENOMEM;
+	}
+
+	if (copy_from_user(cmd, buf, count)) {
+		qdf_mem_free(cmd);
+		return -EFAULT;
+	}
+	cmd[count] = '\0';
+	sptr = cmd;
+
+	/* Get pattern idx */
+	token = strsep(&sptr, " ");
+	if (!token)
+		goto failure;
+	if (kstrtou8(token, 0, &pattern_idx))
+		goto failure;
+
+	if (pattern_idx > (MAXNUM_PERIODIC_TX_PTRNS - 1)) {
+		hdd_err("Pattern index: %d is not in the range (0 ~ %d)",
+			pattern_idx, MAXNUM_PERIODIC_TX_PTRNS - 1);
+
+		goto failure;
+	}
+
+	/* Get pattern duration */
+	token = strsep(&sptr, " ");
+	if (!token)
+		goto failure;
+	if (kstrtou8(token, 0, &pattern_duration))
+		goto failure;
+
+	/* Delete pattern using index if duration is 0 */
+	if (!pattern_duration) {
+		delPeriodicTxPtrnParams =
+			qdf_mem_malloc(sizeof(tSirDelPeriodicTxPtrn));
+		if (!delPeriodicTxPtrnParams) {
+			hdd_err("Memory allocation failed!");
+			qdf_mem_free(cmd);
+			return -ENOMEM;
+		}
+		delPeriodicTxPtrnParams->ucPtrnId = pattern_idx;
+		delPeriodicTxPtrnParams->ucPatternIdBitmap = 1 << pattern_idx;
+		qdf_copy_macaddr(&delPeriodicTxPtrnParams->mac_address,
+				 &adapter->mac_addr);
+
+		/* Delete pattern */
+		status = sme_del_periodic_tx_ptrn(hdd_ctx->mac_handle,
+						  delPeriodicTxPtrnParams);
+		if (QDF_STATUS_SUCCESS != status) {
+			hdd_err("sme_del_periodic_tx_ptrn() failed!");
+
+			qdf_mem_free(delPeriodicTxPtrnParams);
+			goto failure;
+		}
+		qdf_mem_free(cmd);
+		qdf_mem_free(delPeriodicTxPtrnParams);
+		return count;
+	}
+
+	/*
+	 * In SAP mode allow configuration without any connection check
+	 * In STA mode check if it's in connected state before adding
+	 * patterns
+	 */
+	hdd_debug("device mode %d", adapter->device_mode);
+	if ((QDF_STA_MODE == adapter->device_mode) &&
+	    (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))) {
+		hdd_err("Not in Connected state!");
+		goto failure;
+	}
+
+	/* Get pattern */
+	token = strsep(&sptr, " ");
+	if (!token)
+		goto failure;
+
+	pattern_buf = token;
+	pattern_buf[strlen(pattern_buf) - 1] = '\0';
+	pattern_len = strlen(pattern_buf);
+
+	/* Since the pattern is a hex string, 2 characters represent 1 byte. */
+	if (pattern_len % 2) {
+		hdd_err("Malformed pattern!");
+
+		goto failure;
+	} else
+		pattern_len >>= 1;
+
+	if (pattern_len < 14 || pattern_len > PERIODIC_TX_PTRN_MAX_SIZE) {
+		hdd_err("Not an 802.3 frame!");
+
+		goto failure;
+	}
+
+	addPeriodicTxPtrnParams = qdf_mem_malloc(sizeof(tSirAddPeriodicTxPtrn));
+	if (!addPeriodicTxPtrnParams) {
+		hdd_err("Memory allocation failed!");
+		qdf_mem_free(cmd);
+		return -ENOMEM;
+	}
+
+	addPeriodicTxPtrnParams->ucPtrnId = pattern_idx;
+	addPeriodicTxPtrnParams->usPtrnIntervalMs = pattern_duration * 500;
+	addPeriodicTxPtrnParams->ucPtrnSize = pattern_len;
+	qdf_copy_macaddr(&addPeriodicTxPtrnParams->mac_address,
+			 &adapter->mac_addr);
+
+	/* Extract the pattern */
+	for (i = 0; i < addPeriodicTxPtrnParams->ucPtrnSize; i++) {
+		addPeriodicTxPtrnParams->ucPattern[i] =
+			(hex_to_bin(pattern_buf[0]) << 4) +
+			hex_to_bin(pattern_buf[1]);
+
+		/* Skip to next byte */
+		pattern_buf += 2;
+	}
+
+	/* Add pattern */
+	status = sme_add_periodic_tx_ptrn(hdd_ctx->mac_handle,
+					  addPeriodicTxPtrnParams);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("sme_add_periodic_tx_ptrn() failed!");
+
+		qdf_mem_free(addPeriodicTxPtrnParams);
+		goto failure;
+	}
+	qdf_mem_free(cmd);
+	qdf_mem_free(addPeriodicTxPtrnParams);
+	hdd_exit();
+	return count;
+
+failure:
+	hdd_err("Invalid input. Input format is: ptrn_idx duration pattern");
+	qdf_mem_free(cmd);
+	return -EINVAL;
+}
+
+/**
+ * wcnss_patterngen_write() - SSR wrapper for __wcnss_patterngen_write
+ * @file: file pointer
+ * @buf: buffer
+ * @count: count
+ * @ppos: position pointer
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static ssize_t wcnss_patterngen_write(struct file *file,
+				      const char __user *buf,
+				      size_t count, loff_t *ppos)
+{
+	ssize_t ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wcnss_patterngen_write(file, buf, count, ppos);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wcnss_debugfs_open() - Generic debugfs open() handler
+ * @inode: inode of the debugfs file
+ * @file: file handle of the debugfs file
+ *
+ * Return: 0
+ */
+static int __wcnss_debugfs_open(struct inode *inode, struct file *file)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter();
+
+	if (inode->i_private)
+		file->private_data = inode->i_private;
+
+	adapter = (struct hdd_adapter *)file->private_data;
+	if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		hdd_err("Invalid adapter or adapter has invalid magic");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * wcnss_debugfs_open() - SSR wrapper for __wcnss_debugfs_open
+ * @inode: inode pointer
+ * @file: file pointer
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int wcnss_debugfs_open(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wcnss_debugfs_open(inode, file);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static const struct file_operations fops_wowpattern = {
+	.write = wcnss_wowpattern_write,
+	.open = wcnss_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static const struct file_operations fops_patterngen = {
+	.write = wcnss_patterngen_write,
+	.open = wcnss_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+/**
+ * hdd_debugfs_init() - Initialize debugfs interface
+ * @adapter: interface adapter pointer
+ *
+ * Register support for the debugfs files supported by the driver.
+ *
+ * NB: The current implementation only supports debugfs operations
+ * on the primary interface, i.e. wlan0
+ *
+ * Return: QDF_STATUS_SUCCESS if all files registered,
+ *	   QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS hdd_debugfs_init(struct hdd_adapter *adapter)
+{
+	struct net_device *dev = adapter->dev;
+
+	adapter->debugfs_phy = debugfs_create_dir(dev->name, 0);
+
+	if (NULL == adapter->debugfs_phy)
+		return QDF_STATUS_E_FAILURE;
+
+	if (NULL == debugfs_create_file("wow_pattern", 00400 | 00200,
+					adapter->debugfs_phy, adapter,
+					&fops_wowpattern))
+		return QDF_STATUS_E_FAILURE;
+
+	if (NULL == debugfs_create_file("pattern_gen", 00400 | 00200,
+					adapter->debugfs_phy, adapter,
+					&fops_patterngen))
+		return QDF_STATUS_E_FAILURE;
+
+	if (0 != wlan_hdd_create_ll_stats_file(adapter))
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_debugfs_exit() - Shutdown debugfs interface
+ * @adapter: interface adapter pointer
+ *
+ * Unregister support for the debugfs files supported by the driver.
+ *
+ * Return: None
+ */
+void hdd_debugfs_exit(struct hdd_adapter *adapter)
+{
+	debugfs_remove_recursive(adapter->debugfs_phy);
+}
+#endif /* #ifdef WLAN_OPEN_SOURCE */
diff --git a/core/hdd/src/wlan_hdd_debugfs_connect.c b/core/hdd/src/wlan_hdd_debugfs_connect.c
new file mode 100644
index 0000000..107a74b
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_debugfs_connect.c
@@ -0,0 +1,452 @@
+
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * 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: wlan_hdd_debugfs_connect.c
+ *
+ * WLAN Host Device Driver implementation to update
+ * debugfs with connect information
+ */
+
+#include <wlan_hdd_debugfs_csr.h>
+#include <wlan_hdd_main.h>
+#include <cds_sched.h>
+#include <wma_api.h>
+#include "qwlan_version.h"
+#include "wmi_unified_param.h"
+
+/**
+ * wlan_hdd_version_info_debugfs() - Populate driver, FW and HW version
+ * @hdd_ctx: pointer to hdd context
+ * @buf: output buffer to hold version info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_version_info_debugfs(struct hdd_context *hdd_ctx, uint8_t *buf,
+			      ssize_t buf_avail_len)
+{
+	uint32_t major_spid = 0, minor_spid = 0, siid = 0, crmid = 0, sub_id;
+	ssize_t length = 0;
+	int ret_val;
+
+	hdd_get_fw_version(hdd_ctx, &major_spid, &minor_spid, &siid, &crmid);
+	sub_id = (hdd_ctx->target_fw_vers_ext & 0xf0000000) >> 28;
+
+	ret_val = scnprintf(buf, buf_avail_len,
+			    "\nVERSION DETAILS\n");
+	if (ret_val <= 0)
+		return length;
+	length += ret_val;
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+
+	ret_val = scnprintf(buf + length, buf_avail_len - length,
+			    "Host Driver Version: %s\n"
+			    "Firmware Version: %d.%d.%d.%d.%d\n"
+			    "Hardware Version: %s\n",
+			    QWLAN_VERSIONSTR,
+			    major_spid, minor_spid, siid, crmid, sub_id,
+			    hdd_ctx->target_hw_name);
+	if (ret_val <= 0)
+		return length;
+
+	length += ret_val;
+
+	return length;
+}
+
+/**
+ * wlan_hdd_add_nss_info() - Populate NSS info
+ * @conn_info: station connection information
+ * @buf: output buffer to hold version info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_add_nss_info(struct hdd_connection_info *conn_info,
+		      uint8_t *buf, ssize_t buf_avail_len)
+{
+	ssize_t length = 0;
+	int ret_val;
+
+	if (!conn_info->conn_flag.ht_present &&
+	    !conn_info->conn_flag.vht_present)
+		return length;
+
+	ret_val = scnprintf(buf, buf_avail_len,
+			    "nss = %u\n",
+			    conn_info->txrate.nss);
+	if (ret_val <= 0)
+		return length;
+
+	length = ret_val;
+	return length;
+}
+
+/**
+ * wlan_hdd_add_ht_cap_info() - Populate HT info
+ * @conn_info: station connection information
+ * @buf: output buffer to hold version info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_add_ht_cap_info(struct hdd_connection_info *conn_info,
+			 uint8_t *buf, ssize_t buf_avail_len)
+{
+	struct ieee80211_ht_cap *ht_caps;
+	ssize_t length = 0;
+	int ret;
+
+	if (!conn_info->conn_flag.ht_present)
+		return length;
+
+	ht_caps = &conn_info->ht_caps;
+	ret = scnprintf(buf, buf_avail_len,
+			"ht_cap_info = %x\n"
+			"ampdu_params_info = %x\n"
+			"extended_ht_cap_info = %x\n"
+			"tx_BF_cap_info = %x\n"
+			"antenna_selection_info = %x\n"
+			"ht_rx_higest = %x\n"
+			"ht_tx_params = %x\n",
+			ht_caps->cap_info,
+			ht_caps->ampdu_params_info,
+			ht_caps->extended_ht_cap_info,
+			ht_caps->tx_BF_cap_info,
+			ht_caps->antenna_selection_info,
+			ht_caps->mcs.rx_highest,
+			ht_caps->mcs.tx_params);
+	if (ret <= 0)
+		return length;
+
+	length = ret;
+	return length;
+}
+
+/**
+ * wlan_hdd_add_vht_cap_info() - Populate VHT info
+ * @conn_info: station connection information
+ * @buf: output buffer to hold version info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_add_vht_cap_info(struct hdd_connection_info *conn_info,
+			  uint8_t *buf, ssize_t buf_avail_len)
+{
+	struct ieee80211_vht_cap *vht_caps;
+	ssize_t length = 0;
+	int ret;
+
+	if (!conn_info->conn_flag.vht_present)
+		return length;
+
+	vht_caps = &conn_info->vht_caps;
+	ret = scnprintf(buf, buf_avail_len,
+			"vht_cap_info = %x\n"
+			"rx_mcs_map = %x\n"
+			"rx_highest = %x\n"
+			"tx_mcs_map = %x\n"
+			"tx_highest = %x\n",
+			vht_caps->vht_cap_info,
+			vht_caps->supp_mcs.rx_mcs_map,
+			vht_caps->supp_mcs.rx_highest,
+			vht_caps->supp_mcs.tx_mcs_map,
+			vht_caps->supp_mcs.tx_highest);
+	if (ret <= 0)
+		return length;
+
+	length = ret;
+	return length;
+}
+
+/**
+ * hdd_auth_type_str() - Get string for enum csr auth type
+ * @auth_type: authentication id
+ *
+ * Return: Meaningful string for enum csr auth type
+ */
+static
+uint8_t *hdd_auth_type_str(uint32_t auth_type)
+{
+	switch (auth_type) {
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		return "OPEN SYSTEM";
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		return "SHARED KEY";
+	case eCSR_AUTH_TYPE_WPA:
+		return "WPA";
+	case eCSR_AUTH_TYPE_WPA_PSK:
+		return "WPA PSK";
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+		return "AUTO SWITCH";
+	case eCSR_AUTH_TYPE_WPA_NONE:
+		return "WPA NONE";
+	case eCSR_AUTH_TYPE_RSN:
+		return "RSN";
+	case eCSR_AUTH_TYPE_RSN_PSK:
+		return "RSN PSK";
+	case eCSR_AUTH_TYPE_FT_RSN:
+		return "FT RSN";
+	case eCSR_AUTH_TYPE_FT_RSN_PSK:
+		return "FT RSN PSK";
+	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
+		return "WAPI WAI CERTIFICATE";
+	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
+		return "WAPI WAI PSK";
+	case eCSR_AUTH_TYPE_CCKM_WPA:
+		return "CCKM WPA";
+	case eCSR_AUTH_TYPE_CCKM_RSN:
+		return "CCKM RSN";
+	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+		return "RSN PSK SHA256";
+	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
+		return "RSN 8021X SHA256";
+	case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
+		return "NUM OF SUPPORT AUTH TYPE";
+	case eCSR_AUTH_TYPE_FAILED:
+		return "FAILED";
+	case eCSR_AUTH_TYPE_NONE:
+		return "NONE";
+	}
+
+	return "UNKNOWN";
+}
+
+/**
+ * hdd_dot11_mode_str() - Get string for enum csr dot11 mode
+ * @dot11mode: dot11 mode ID
+ *
+ * Return: Meaningful string for enum csr dot11 mode
+ */
+static
+uint8_t *hdd_dot11_mode_str(uint32_t dot11mode)
+{
+	switch (dot11mode) {
+	case eCSR_CFG_DOT11_MODE_11A:
+		return "DOT11 MODE 11A";
+	case eCSR_CFG_DOT11_MODE_11B:
+		return "DOT11 MODE 11B";
+	case eCSR_CFG_DOT11_MODE_11G:
+		return "DOT11 MODE 11G";
+	case eCSR_CFG_DOT11_MODE_11N:
+		return "DOT11 MODE 11N";
+	case eCSR_CFG_DOT11_MODE_11AC:
+		return "DOT11 MODE 11AC";
+	case eCSR_CFG_DOT11_MODE_AUTO:
+		return "DOT11 MODE AUTO";
+	case eCSR_CFG_DOT11_MODE_ABG:
+		return "DOT11 MODE 11ABG";
+	}
+
+	return "UNKNOWN";
+}
+
+/**
+ * hdd_ch_width_str() - Get string for channel width
+ * @ch_width: channel width from connect info
+ *
+ * Return: User readable string for channel width
+ */
+static
+uint8_t *hdd_ch_width_str(enum phy_ch_width ch_width)
+{
+	switch (ch_width) {
+	case CH_WIDTH_20MHZ:
+		return "20MHz";
+	case CH_WIDTH_40MHZ:
+		return "40MHz";
+	case CH_WIDTH_80MHZ:
+		return "80MHz";
+	case CH_WIDTH_160MHZ:
+		return "160MHz";
+	case CH_WIDTH_80P80MHZ:
+		return "(80 + 80)MHz";
+	case CH_WIDTH_5MHZ:
+		return "5MHz";
+	case CH_WIDTH_10MHZ:
+		return "10MHz";
+	case CH_WIDTH_INVALID:
+		/* Fallthrough */
+	case CH_WIDTH_MAX:
+		/* Fallthrough */
+	default:
+		return "UNKNOWN";
+	}
+}
+
+/**
+ * wlan_hdd_connect_info_debugfs() - Populate connect info
+ * @adapter: pointer to sta adapter for which connect info is required
+ * @buf: output buffer to hold version info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_connect_info_debugfs(struct hdd_adapter *adapter, uint8_t *buf,
+			      ssize_t buf_avail_len)
+{
+	ssize_t length = 0;
+	struct hdd_station_ctx *hdd_sta_ctx;
+	struct hdd_connection_info *conn_info;
+	uint32_t bit_rate;
+	int ret_val;
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (hdd_sta_ctx->conn_info.connState != eConnectionState_Associated) {
+		ret_val = scnprintf(buf, buf_avail_len,
+				    "\nSTA is not connected\n");
+		if (ret_val >= 0)
+			length = ret_val;
+		return length;
+	}
+
+	ret_val = scnprintf(buf, buf_avail_len,
+			    "\nCONNECTION DETAILS\n");
+	if (ret_val <= 0)
+		return length;
+	length += ret_val;
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+
+	if (hdd_sta_ctx->hdd_reassoc_scenario) {
+		ret_val = scnprintf(buf + length, buf_avail_len - length,
+				    "Roaming is in progress");
+		if (ret_val <= 0)
+			return length;
+		length += ret_val;
+	}
+
+	conn_info = &hdd_sta_ctx->conn_info;
+	bit_rate = cfg80211_calculate_bitrate(&conn_info->txrate);
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	ret_val = scnprintf(buf + length, buf_avail_len - length,
+			    "ssid = %s\n"
+			    "bssid = " MAC_ADDRESS_STR "\n"
+			    "connect_time = %s\n"
+			    "auth_time = %s\n"
+			    "freq = %u\n"
+			    "ch_width = %s\n"
+			    "signal = %ddBm\n"
+			    "bit_rate = %u\n"
+			    "last_auth_type = %s\n"
+			    "dot11Mode = %s\n",
+			    conn_info->last_ssid.SSID.ssId,
+			    MAC_ADDR_ARRAY(conn_info->bssId.bytes),
+			    conn_info->connect_time,
+			    conn_info->auth_time,
+			    conn_info->freq,
+			    hdd_ch_width_str(conn_info->ch_width),
+			    conn_info->signal,
+			    bit_rate,
+			    hdd_auth_type_str(conn_info->last_auth_type),
+			    hdd_dot11_mode_str(conn_info->dot11Mode));
+
+	if (ret_val <= 0)
+		return length;
+	length += ret_val;
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	length += wlan_hdd_add_nss_info(conn_info, buf + length,
+					buf_avail_len - length);
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+
+	length += wlan_hdd_add_ht_cap_info(conn_info, buf + length,
+					   buf_avail_len - length);
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	length += wlan_hdd_add_vht_cap_info(conn_info, buf + length,
+					    buf_avail_len - length);
+	return length;
+}
+
+ssize_t
+wlan_hdd_debugfs_update_connect_info(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter,
+				     uint8_t *buf, ssize_t buf_avail_len)
+{
+	ssize_t len;
+	int ret_val;
+
+	hdd_enter();
+
+	len = wlan_hdd_current_time_info_debugfs(buf, buf_avail_len);
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+
+	if (adapter->device_mode != QDF_STA_MODE) {
+		ret_val = scnprintf(buf + len, buf_avail_len - len,
+				    "Interface is not operating STA Mode\n");
+		if (ret_val <= 0)
+			return len;
+
+		len += ret_val;
+		return len;
+	}
+
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	len += wlan_hdd_version_info_debugfs(hdd_ctx, buf + len,
+					     buf_avail_len - len);
+
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	len += wlan_hdd_connect_info_debugfs(adapter, buf + len,
+					     buf_avail_len - len);
+
+	hdd_exit();
+
+	return len;
+}
diff --git a/core/hdd/src/wlan_hdd_debugfs_csr.c b/core/hdd/src/wlan_hdd_debugfs_csr.c
new file mode 100644
index 0000000..f6da1e2
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_debugfs_csr.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * 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: wlan_hdd_debugfs_csr.c
+ *
+ * WLAN Host Device Driver implementation to update
+ * debugfs with roaming related information
+ */
+
+#include <wlan_hdd_debugfs_csr.h>
+#include <wlan_hdd_main.h>
+#include <cds_sched.h>
+#include <wma_api.h>
+#include "qwlan_version.h"
+#include "wmi_unified_param.h"
+#include "wlan_hdd_debugfs.h"
+
+ssize_t
+wlan_hdd_current_time_info_debugfs(uint8_t *buf, ssize_t buf_avail_len)
+{
+	ssize_t length;
+	char time_buffer[HDD_TIME_STRING_LEN];
+	int ret_val;
+
+	qdf_get_time_of_the_day_in_hr_min_sec_usec(time_buffer,
+						   sizeof(time_buffer));
+	ret_val = scnprintf(buf, buf_avail_len,
+			    "\nTime at which this file generated = %s\n",
+			    time_buffer);
+	if (ret_val < 0)
+		return 0;
+	length = ret_val;
+
+	return length;
+}
+
+/**
+ * wlan_hdd_debugfs_update_csr() - Function to update internal debugfs buffer
+ * and write into user-space buffer
+ * @hdd_ctx: hdd context
+ * @adapter: adapter
+ * @id: used to identify file for which this info has to be read
+ * @buf: output buffer to write
+ * @buf_avail_len: length of the available buffer
+ *
+ * Return: Number of bytes read on success, zero otherwise
+ */
+static ssize_t
+wlan_hdd_debugfs_update_csr(struct hdd_context *hdd_ctx,
+			    struct hdd_adapter *adapter,
+			    enum hdd_debugfs_file_id id,
+			    uint8_t *buf,
+			    ssize_t buf_avail_len)
+{
+	ssize_t len = 0;
+
+	switch (id) {
+	case HDD_DEBUFS_FILE_ID_CONNECT_INFO:
+		/* populate connect info */
+		len = wlan_hdd_debugfs_update_connect_info(hdd_ctx, adapter,
+							   buf, buf_avail_len);
+		break;
+	case HDD_DEBUFS_FILE_ID_ROAM_SCAN_STATS_INFO:
+		/* populate roam scan stats info */
+		len = wlan_hdd_debugfs_update_roam_stats(hdd_ctx, adapter,
+							 buf, buf_avail_len);
+		break;
+	case HDD_DEBUFS_FILE_ID_OFFLOAD_INFO:
+		/* populate offload info */
+		len = wlan_hdd_debugfs_update_filters_info(hdd_ctx, adapter,
+							   buf, buf_avail_len);
+		break;
+	default:
+		hdd_err("Failed to fetch stats, unknown stats type");
+	}
+
+	return len;
+}
+
+/**
+ * __wlan_hdd_read_debugfs_csr() - Function to read debug stats
+ * @file: file pointer
+ * @buf: buffer
+ * @count: count
+ * @pos: position pointer
+ *
+ * Return: Number of bytes read on success, zero otherwise
+ */
+static ssize_t
+__wlan_hdd_read_debugfs_csr(struct file *file, char __user *buf,
+			    size_t count, loff_t *pos)
+{
+	struct wlan_hdd_debugfs_buffer_info *info;
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	int ret;
+	ssize_t length;
+
+	hdd_enter();
+
+	info = file->private_data;
+	if (!info || !info->data) {
+		hdd_err("No valid private data");
+		return 0;
+	}
+
+	adapter = info->adapter;
+	if ((!adapter) || (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
+		hdd_err("Invalid adapter or adapter has invalid magic");
+		return 0;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return 0;
+
+	if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
+		hdd_err("Interface is not enabled");
+		return 0;
+	}
+
+	if (*pos == 0) {
+		info->length = wlan_hdd_debugfs_update_csr(hdd_ctx, adapter,
+							   info->id,
+							   info->data,
+							   info->max_buf_len);
+	}
+
+	length = simple_read_from_buffer(buf, count, pos,
+					 info->data, info->length);
+	hdd_debug("length written = %zu, count: %zu, pos: %lld",
+		  length, count, *pos);
+
+	hdd_exit();
+	return length;
+}
+
+/**
+ * wlan_hdd_read_debugfs_csr() - SSR wrapper function to read stats
+ * @file: file pointer
+ * @buf: buffer
+ * @count: count
+ * @pos: position pointer
+ *
+ * Return: Number of bytes read on success, zero otherwise
+ */
+static ssize_t
+wlan_hdd_read_debugfs_csr(struct file *file, char __user *buf,
+			  size_t count, loff_t *pos)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_read_debugfs_csr(file, buf, count, pos);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_open_debugfs_csr() - Allocates memory for private data
+ * @inode: Pointer to inode structure
+ * @file: file pointer
+ *
+ * Return: zero
+ */
+static int __wlan_hdd_open_debugfs_csr(struct inode *inode,
+				       struct file *file)
+{
+	struct wlan_hdd_debugfs_buffer_info *info;
+	struct hdd_debugfs_file_info *csr;
+	struct hdd_adapter *adapter = NULL;
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter();
+
+	csr = inode->i_private;
+	if (!csr) {
+		hdd_err("No private data");
+		return -EINVAL;
+	}
+
+	adapter = qdf_container_of(csr, struct hdd_adapter,
+				   csr_file[csr->id]);
+	if (!adapter || (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
+		hdd_err("Invalid adapter or adapter has invalid magic");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return -EINVAL;
+
+	if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
+		hdd_err("Interface is not enabled");
+		return -EINVAL;
+	}
+
+	info = qdf_mem_malloc(sizeof(*info));
+	if (!info) {
+		hdd_err("Not enough memory for file private data");
+		return -ENOMEM;
+	}
+
+	info->data = qdf_mem_malloc(csr->buf_max_size);
+	if (!info->data) {
+		hdd_err("roam stats debugfs buffer allocation failed");
+		qdf_mem_free(info);
+		return -ENOMEM;
+	}
+	info->length = 0;
+	info->max_buf_len = csr->buf_max_size;
+	info->id = csr->id;
+	info->adapter = adapter;
+
+	file->private_data = info;
+	hdd_exit();
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_open_debugfs_csr() - SSR wrapper function to allocate memory for
+ * private data on file open
+ * @inode: Pointer to inode structure
+ * @file: file pointer
+ *
+ * Return: zero
+ */
+static int wlan_hdd_open_debugfs_csr(struct inode *inode,
+				     struct file *file)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+
+	hdd_debugfs_thread_increment();
+	ret = __wlan_hdd_open_debugfs_csr(inode, file);
+	if (ret)
+		hdd_debugfs_thread_decrement();
+
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_release_debugfs_csr() - Function to free private memory on
+ * release
+ * @inode: Pointer to inode structure
+ * @file: file pointer
+ *
+ * Return: zero
+ */
+static int __wlan_hdd_release_debugfs_csr(struct inode *inode,
+					  struct file *file)
+{
+	struct wlan_hdd_debugfs_buffer_info *info = file->private_data;
+
+	hdd_enter();
+
+	if (!info)
+		return 0;
+
+	file->private_data = NULL;
+	qdf_mem_free(info->data);
+	qdf_mem_free(info);
+
+	hdd_exit();
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_release_debugfs_csr() - SSR wrapper function to free
+ * private data on release
+ * @inode: Pointer to inode structure
+ * @file: file pointer
+ *
+ * Return: zero
+ */
+static int wlan_hdd_release_debugfs_csr(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_release_debugfs_csr(inode, file);
+	hdd_debugfs_thread_decrement();
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static const struct file_operations fops_csr_debugfs = {
+	.read = wlan_hdd_read_debugfs_csr,
+	.open = wlan_hdd_open_debugfs_csr,
+	.release = wlan_hdd_release_debugfs_csr,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+void wlan_hdd_debugfs_csr_init(struct hdd_adapter *adapter)
+{
+	struct hdd_debugfs_file_info *csr;
+	const uint32_t max_len = HDD_DEBUGFS_FILE_NAME_MAX;
+
+	/*
+	 * Create debufs diagnostic files for connect, offload info
+	 * and roam info and store in csr_file member of adapter
+	 */
+
+	csr = &adapter->csr_file[HDD_DEBUFS_FILE_ID_CONNECT_INFO];
+	if (!csr->entry) {
+		strlcpy(csr->name, "connect_info", max_len);
+		csr->id = HDD_DEBUFS_FILE_ID_CONNECT_INFO;
+		csr->buf_max_size = DEBUGFS_CONNECT_INFO_BUF_SIZE;
+		csr->entry = debugfs_create_file(csr->name, 0444,
+						 adapter->debugfs_phy,
+						 csr, &fops_csr_debugfs);
+		if (!csr->entry)
+			hdd_err("Failed to create debugfs file: %s",
+				csr->name);
+	}
+
+	csr = &adapter->csr_file[HDD_DEBUFS_FILE_ID_OFFLOAD_INFO];
+	if (!csr->entry) {
+		strlcpy(csr->name, "offload_info", max_len);
+		csr->id = HDD_DEBUFS_FILE_ID_OFFLOAD_INFO;
+		csr->buf_max_size = DEBUGFS_OFFLOAD_INFO_BUF_SIZE;
+		csr->entry = debugfs_create_file(csr->name, 0444,
+						 adapter->debugfs_phy,
+						 csr, &fops_csr_debugfs);
+		if (!csr->entry)
+			hdd_err("Failed to create generic_info debugfs file");
+	}
+
+	csr = &adapter->csr_file[HDD_DEBUFS_FILE_ID_ROAM_SCAN_STATS_INFO];
+	if (!csr->entry) {
+		strlcpy(csr->name, "roam_stats", max_len);
+		csr->id = HDD_DEBUFS_FILE_ID_ROAM_SCAN_STATS_INFO;
+		csr->buf_max_size = DEBUGFS_ROAM_SCAN_STATS_INFO_BUF_SIZE;
+		csr->entry = debugfs_create_file(csr->name, 0444,
+						 adapter->debugfs_phy,
+						 csr, &fops_csr_debugfs);
+		if (!csr->entry)
+			hdd_err("Failed to create generic_info debugfs file");
+	}
+}
+
+void wlan_hdd_debugfs_csr_deinit(struct hdd_adapter *adapter)
+{
+	uint32_t i;
+	struct dentry *entry;
+
+	for (i = 0; i < HDD_DEBUGFS_FILE_ID_MAX; i++) {
+		entry = adapter->csr_file[i].entry;
+		if (!entry)
+			continue;
+
+		adapter->csr_file[i].entry = NULL;
+		debugfs_remove(entry);
+		entry = NULL;
+	}
+}
diff --git a/core/hdd/src/wlan_hdd_debugfs_llstat.c b/core/hdd/src/wlan_hdd_debugfs_llstat.c
new file mode 100644
index 0000000..de530c2
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_debugfs_llstat.c
@@ -0,0 +1,559 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_debugfs_llstat.c
+ *
+ * WLAN Host Device Driver implementation to update
+ * debugfs with Link Layer statistics
+ */
+
+#include <wlan_hdd_debugfs_llstat.h>
+#include <cds_sched.h>
+#include <wlan_hdd_stats.h>
+#include <wma_api.h>
+
+struct ll_stats_buf {
+	ssize_t len;
+	uint8_t *result;
+};
+
+static struct ll_stats_buf ll_stats;
+
+static DEFINE_MUTEX(llstats_mutex);
+
+void hdd_debugfs_process_iface_stats(struct hdd_adapter *adapter,
+		void *data, uint32_t num_peers)
+{
+	tpSirWifiIfaceStat iface_stat;
+	tpSirWifiInterfaceInfo iface_info;
+	wmi_iface_link_stats *link_stats;
+	wmi_wmm_ac_stats *ac_stats;
+	wmi_iface_offload_stats *offload_stats;
+	uint64_t average_tsf_offset;
+	int i;
+	ssize_t len = 0;
+	uint8_t *buffer;
+
+	hdd_enter();
+
+	mutex_lock(&llstats_mutex);
+	if (!ll_stats.result) {
+		mutex_unlock(&llstats_mutex);
+		hdd_err("LL statistics buffer is NULL");
+		return;
+	}
+
+	iface_stat = data;
+	buffer = ll_stats.result;
+	buffer += ll_stats.len;
+	len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+			"\n\n===LL_STATS_IFACE: num_peers: %d===", num_peers);
+
+	if (false == hdd_get_interface_info(adapter, &iface_stat->info)) {
+		mutex_unlock(&llstats_mutex);
+		hdd_err("hdd_get_interface_info get fail");
+		return;
+	}
+
+	iface_info = &iface_stat->info;
+	buffer += len;
+	ll_stats.len += len;
+	len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+			"\nmode: %u, MAC_ADDR: %pM, state: %u, roaming: %u, capabilities: %u, SSID: %s, BSSID_MAC: %pM, ap_country_str: %s, country_str: %s",
+			iface_info->mode, &iface_info->macAddr.bytes[0],
+			iface_info->state, iface_info->roaming,
+			iface_info->capabilities, iface_info->ssid,
+			&iface_info->bssid.bytes[0], iface_info->apCountryStr,
+			iface_info->countryStr);
+
+	link_stats = &iface_stat->link_stats;
+	average_tsf_offset =  link_stats->avg_bcn_spread_offset_high;
+	average_tsf_offset =  (average_tsf_offset << 32) |
+				link_stats->avg_bcn_spread_offset_low;
+
+	buffer += len;
+	ll_stats.len += len;
+	len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+			"\nbeacon_rx: %u, mgmt_rx: %u, mgmt_action_rx: %u, mgmt_action_tx: %u, rssi_mgmt: %u, rssi_data: %u, rssi_ack: %u, is_leaky_ap: %u, avg_rx_frms_leaked: %u, rx_leak_window: %u, average_tsf_offset: %llu, Tx RTS success count: %u, Tx RTS fail count: %u, Tx ppdu success count: %u, Tx ppdu fail count: %u, Connected duration: %u, Disconnected duration: %u, RTT ranging duration: %u, RTT responder duration: %u, Num tx probes: %u, Num beacon miss: %u,\n\nNumber of AC: %d",
+			link_stats->beacon_rx, link_stats->mgmt_rx,
+			link_stats->mgmt_action_rx, link_stats->mgmt_action_tx,
+			link_stats->rssi_mgmt, link_stats->rssi_data,
+			link_stats->rssi_ack, link_stats->is_leaky_ap,
+			link_stats->avg_rx_frms_leaked,
+			link_stats->rx_leak_window, average_tsf_offset,
+			link_stats->tx_rts_succ_cnt,
+			link_stats->tx_rts_fail_cnt,
+			link_stats->tx_ppdu_succ_cnt,
+			link_stats->tx_ppdu_fail_cnt,
+			link_stats->connected_duration,
+			link_stats->disconnected_duration,
+			link_stats->rtt_ranging_duration,
+			link_stats->rtt_responder_duration,
+			link_stats->num_probes_tx, link_stats->num_beacon_miss,
+			link_stats->num_ac);
+
+	for (i = 0; i < link_stats->num_ac; i++) {
+		ac_stats = &iface_stat->ac_stats[i];
+		buffer += len;
+		ll_stats.len += len;
+		len = scnprintf(buffer,
+				DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+				"\nac_type: %d, tx_mpdu: %u, rx_mpdu: %u, tx_mcast: %u, rx_mcast: %u, rx_ampdu: %u tx_ampdu: %u, mpdu_lost: %u, retries: %u, retries_short: %u, retries_long: %u, contention_time: min-%u max-%u avg-%u, contention num samples: %u, tx_pending_msdu: %u",
+				ac_stats->ac_type,
+				ac_stats->tx_mpdu, ac_stats->rx_mpdu,
+				ac_stats->tx_mcast, ac_stats->rx_mcast,
+				ac_stats->rx_ampdu, ac_stats->rx_ampdu,
+				ac_stats->mpdu_lost, ac_stats->retries,
+				ac_stats->retries_short, ac_stats->retries_long,
+				ac_stats->contention_time_min,
+				ac_stats->contention_time_max,
+				ac_stats->contention_time_avg,
+				ac_stats->contention_num_samples,
+				ac_stats->tx_pending_msdu);
+	}
+
+	buffer += len;
+	ll_stats.len += len;
+	len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+			"\n\nNumber of offload stats: %d",
+			iface_stat->num_offload_stats);
+
+	for (i = 0; i < iface_stat->num_offload_stats; i++) {
+		offload_stats = &iface_stat->offload_stats[i];
+		buffer += len;
+		ll_stats.len += len;
+		len = scnprintf(buffer,
+				DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+				"\ntype: %d, rx_count: %u, drp_count: %u, fwd_count: %u",
+				offload_stats->type, offload_stats->rx_count,
+				offload_stats->drp_count,
+				offload_stats->fwd_count);
+	}
+
+	ll_stats.len += len;
+	mutex_unlock(&llstats_mutex);
+	hdd_exit();
+}
+
+void hdd_debugfs_process_peer_stats(struct hdd_adapter *adapter, void *data)
+{
+	tpSirWifiPeerStat peer_stat;
+	tpSirWifiPeerInfo peer_info;
+	tpSirWifiRateStat rate_stat;
+	int i, j, num_rate;
+	ssize_t len = 0;
+	uint8_t *buffer;
+
+	hdd_enter();
+
+	mutex_lock(&llstats_mutex);
+	if (!ll_stats.result) {
+		mutex_unlock(&llstats_mutex);
+		hdd_err("LL statistics buffer is NULL");
+		return;
+	}
+
+	peer_stat = (tpSirWifiPeerStat) data;
+
+	buffer = ll_stats.result;
+	buffer += ll_stats.len;
+	len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+			"\n\n===LL_STATS_PEER_ALL : num_peers %u===",
+			peer_stat->numPeers);
+
+	peer_info = (tpSirWifiPeerInfo) ((uint8_t *) peer_stat->peerInfo);
+	for (i = 1; i <= peer_stat->numPeers; i++) {
+		buffer += len;
+		ll_stats.len += len;
+		len = scnprintf(buffer,
+				DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+				"\nType: %d, peer_mac: %pM, capabilities: %u\nnum_rates: %d",
+				wmi_to_sir_peer_type(peer_info->type),
+				&peer_info->peerMacAddress.bytes[0],
+				peer_info->capabilities, peer_info->numRate);
+
+		num_rate = peer_info->numRate;
+		for (j = 0; j < num_rate; j++) {
+			rate_stat = (tpSirWifiRateStat) ((uint8_t *)
+					peer_info->rateStats + (j *
+					sizeof(tSirWifiRateStat)));
+			buffer += len;
+			ll_stats.len += len;
+			len = scnprintf(buffer,
+				DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+				"\npreamble: %0x, nss: %0x, bw: %0x, mcs: %0x, bitrate: %0x, txmpdu: %u, rxmpdu: %u, mpdu_lost: %u, retries: %u, retries_short: %u, retries_long: %u",
+				rate_stat->rate.preamble, rate_stat->rate.nss,
+				rate_stat->rate.bw, rate_stat->rate.rateMcsIdx,
+				rate_stat->rate.bitrate, rate_stat->txMpdu,
+				rate_stat->rxMpdu, rate_stat->mpduLost,
+				rate_stat->retries, rate_stat->retriesShort,
+				rate_stat->retriesLong);
+		}
+		peer_info = (tpSirWifiPeerInfo) ((uint8_t *)
+				peer_stat->peerInfo + (i *
+				sizeof(tSirWifiPeerInfo)) +
+				(num_rate * sizeof(tSirWifiRateStat)));
+	}
+	ll_stats.len += len;
+	mutex_unlock(&llstats_mutex);
+	hdd_exit();
+
+}
+
+void hdd_debugfs_process_radio_stats(struct hdd_adapter *adapter,
+		uint32_t more_data, void *data, uint32_t num_radio)
+{
+	int i, j;
+	ssize_t len = 0;
+	uint8_t *buffer;
+	tSirWifiRadioStat *radio_stat = (tpSirWifiRadioStat) data;
+	tSirWifiChannelStats *chan_stat;
+
+	hdd_enter();
+
+	mutex_lock(&llstats_mutex);
+	if (!ll_stats.result) {
+		mutex_unlock(&llstats_mutex);
+		hdd_err("LL statistics buffer is NULL");
+		return;
+	}
+
+	buffer = ll_stats.result;
+	buffer += ll_stats.len;
+	len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE,
+			 "\n\n===LL_STATS_RADIO: number of radios: %u===",
+			  num_radio);
+
+	for (i = 0; i < num_radio; i++) {
+		buffer += len;
+		ll_stats.len += len;
+		len = scnprintf(buffer,
+			DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+			"\nRadio: %u on_time: %u, tx_time: %u, rx_time: %u, on_time_scan: %u, on_time_nbd: %u, on_time_gscan: %u, on_time_roam_scan: %u, on_time_pno_scan: %u  on_time_hs20: %u, on_time_host_scan: %u, on_time_lpi_scan: %u\ntotal_num_tx_pwr_levels: %u\n",
+			radio_stat->radio, radio_stat->onTime,
+			radio_stat->txTime, radio_stat->rxTime,
+			radio_stat->onTimeScan, radio_stat->onTimeNbd,
+			radio_stat->onTimeGscan,
+			radio_stat->onTimeRoamScan,
+			radio_stat->onTimePnoScan,
+			radio_stat->onTimeHs20,
+			radio_stat->on_time_host_scan,
+			radio_stat->on_time_lpi_scan,
+			radio_stat->total_num_tx_power_levels);
+
+		for (j = 0; j < radio_stat->total_num_tx_power_levels; j++) {
+			buffer += len;
+			ll_stats.len += len;
+			len = scnprintf(buffer,
+				DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+				"%d ", radio_stat->tx_time_per_power_level[j]);
+		}
+
+		buffer += len;
+		ll_stats.len += len;
+		len = scnprintf(buffer,
+			DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+			"\nNum channels: %d", radio_stat->numChannels);
+
+		for (j = 0; j < radio_stat->numChannels; j++) {
+			chan_stat = (tSirWifiChannelStats *)
+					((uint8_t *)radio_stat->channels +
+					  (j * sizeof(tSirWifiChannelStats)));
+
+			buffer += len;
+			ll_stats.len += len;
+			len = scnprintf(buffer,
+				DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len,
+				"\nChan width: %d, center_freq: %d, center_freq0: %d, center_freq1: %d, on_time: %d, cca_busy_time: %d",
+				chan_stat->channel.width,
+				chan_stat->channel.centerFreq,
+				chan_stat->channel.centerFreq0,
+				chan_stat->channel.centerFreq1,
+				chan_stat->onTime, chan_stat->ccaBusyTime);
+		}
+
+		radio_stat++;
+	}
+	ll_stats.len += len;
+	mutex_unlock(&llstats_mutex);
+	hdd_exit();
+}
+
+static inline void wlan_hdd_llstats_free_buf(void)
+{
+	mutex_lock(&llstats_mutex);
+	qdf_mem_free(ll_stats.result);
+	ll_stats.result = NULL;
+	ll_stats.len =  0;
+	mutex_unlock(&llstats_mutex);
+}
+
+static int wlan_hdd_llstats_alloc_buf(void)
+{
+	mutex_lock(&llstats_mutex);
+	if (ll_stats.result) {
+		mutex_unlock(&llstats_mutex);
+		hdd_err("Buffer is already allocated");
+		return 0;
+	}
+	ll_stats.len = 0;
+	ll_stats.result = qdf_mem_malloc(DEBUGFS_LLSTATS_BUF_SIZE);
+	if (!ll_stats.result) {
+		mutex_unlock(&llstats_mutex);
+		return -EINVAL;
+	}
+	mutex_unlock(&llstats_mutex);
+	return 0;
+}
+
+/**
+ * hdd_debugfs_stats_update() - Update userspace with local statistics buffer
+ * @buf: userspace buffer (to which data is being copied into)
+ * @count: max data that can be copied into buf
+ * @pos: offset (where data should be copied into)
+ *
+ * This function should copies link layer statistics buffer into debugfs
+ * entry.
+ *
+ * Return: number of characters copied; 0 on no-copy
+ */
+static ssize_t hdd_debugfs_stats_update(char __user *buf, size_t count,
+				     loff_t *pos)
+{
+	ssize_t ret_cnt;
+
+	hdd_enter();
+	mutex_lock(&llstats_mutex);
+	if (!ll_stats.result) {
+		mutex_unlock(&llstats_mutex);
+		hdd_err("Trying to read from NULL buffer");
+		return 0;
+	}
+
+	ret_cnt = simple_read_from_buffer(buf, count, pos,
+			ll_stats.result, ll_stats.len);
+	mutex_unlock(&llstats_mutex);
+	hdd_debug("LL stats read req: count: %zu, pos: %lld", count, *pos);
+
+	hdd_exit();
+	return ret_cnt;
+}
+
+/**
+ * __wlan_hdd_read_ll_stats_debugfs() - API to collect LL stats from FW
+ * @file: file pointer
+ * @buf: buffer
+ * @count: count
+ * @pos: position pointer
+ *
+ * Return: Number of bytes read on success, error number otherwise
+ */
+static ssize_t __wlan_hdd_read_ll_stats_debugfs(struct file *file,
+			char __user *buf, size_t count, loff_t *pos)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	ssize_t ret = 0;
+
+	hdd_enter();
+
+	adapter = (struct hdd_adapter *)file->private_data;
+	if ((!adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		hdd_err("Invalid adapter or adapter has invalid magic");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	/* All the events are received and buffer is populated */
+	ret = hdd_debugfs_stats_update(buf, count, pos);
+	hdd_info("%zu characters written into debugfs", ret);
+
+	hdd_exit();
+	return ret;
+
+}
+
+/**
+ * wlan_hdd_read_ll_stats_debugfs() - SSR wrapper function to read LL debugfs
+ * @file: file pointer
+ * @buf: buffer
+ * @count: count
+ * @pos: position pointer
+ *
+ * Return: Number of bytes read on success, error number otherwise
+ */
+static ssize_t wlan_hdd_read_ll_stats_debugfs(struct file *file,
+		char __user *buf,
+		size_t count, loff_t *pos)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_read_ll_stats_debugfs(file, buf, count, pos);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_open_ll_stats_debugfs() - Function to save private on open
+ * @inode: Pointer to inode structure
+ * @file: file pointer
+ *
+ * Return: zero
+ */
+static int __wlan_hdd_open_ll_stats_debugfs(struct inode *inode,
+					    struct file *file)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	int errno;
+
+	hdd_enter();
+
+	if (inode->i_private)
+		file->private_data = inode->i_private;
+
+	adapter = (struct hdd_adapter *)file->private_data;
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		return errno;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	errno = wlan_hdd_llstats_alloc_buf();
+	if (errno)
+		return errno;
+
+	errno = wlan_hdd_ll_stats_get(adapter, DEBUGFS_LLSTATS_REQID,
+				      DEBUGFS_LLSTATS_REQMASK);
+	if (errno)
+		goto free_buf;
+
+	hdd_exit();
+
+	return 0;
+
+free_buf:
+	wlan_hdd_llstats_free_buf();
+
+	hdd_exit();
+
+	return errno;
+}
+
+/**
+ * wlan_hdd_open_ll_stats_debugfs() - SSR wrapper function to save private
+ *                                    on open
+ * @inode: Pointer to inode structure
+ * @file: file pointer
+ *
+ * Return: zero
+ */
+static int wlan_hdd_open_ll_stats_debugfs(struct inode *inode,
+					  struct file *file)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_open_ll_stats_debugfs(inode, file);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_release_ll_stats_debugfs() - Function to save private on release
+ * @inode: Pointer to inode structure
+ * @file: file pointer
+ *
+ * Return: zero
+ */
+static int __wlan_hdd_release_ll_stats_debugfs(struct inode *inode,
+					    struct file *file)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter();
+
+	if (inode->i_private)
+		file->private_data = inode->i_private;
+
+	adapter = (struct hdd_adapter *)file->private_data;
+	if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		hdd_err("Invalid adapter or adapter has invalid magic");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	wlan_hdd_llstats_free_buf();
+
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * wlan_hdd_release_ll_stats_debugfs() - SSR wrapper function to save private
+ *                                       on release
+ * @inode: Pointer to inode structure
+ * @file: file pointer
+ *
+ * Return: zero
+ */
+static int wlan_hdd_release_ll_stats_debugfs(struct inode *inode,
+					  struct file *file)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_release_ll_stats_debugfs(inode, file);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static const struct file_operations fops_ll_stats_debugfs = {
+	.read = wlan_hdd_read_ll_stats_debugfs,
+	.open = wlan_hdd_open_ll_stats_debugfs,
+	.release = wlan_hdd_release_ll_stats_debugfs,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+int wlan_hdd_create_ll_stats_file(struct hdd_adapter *adapter)
+{
+	if (!debugfs_create_file("ll_stats", 0444, adapter->debugfs_phy,
+				 adapter, &fops_ll_stats_debugfs))
+		return -EINVAL;
+
+	return 0;
+}
diff --git a/core/hdd/src/wlan_hdd_debugfs_offload.c b/core/hdd/src/wlan_hdd_debugfs_offload.c
new file mode 100644
index 0000000..211db5f
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_debugfs_offload.c
@@ -0,0 +1,423 @@
+
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * 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: wlan_hdd_debugfs_offload.c
+ *
+ * WLAN Host Device Driver implementation to update
+ * debugfs with offload information
+ */
+
+#include <wlan_hdd_debugfs_csr.h>
+#include <wlan_hdd_main.h>
+#include <cds_sched.h>
+#include <wma_api.h>
+#include "qwlan_version.h"
+#include "wmi_unified_param.h"
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+#include "wlan_pmo_ucfg_api.h"
+
+/* IPv6 address string */
+#define IPV6_MAC_ADDRESS_STR_LEN 47  /* Including null terminator */
+
+/**
+ * wlan_hdd_mc_addr_list_info_debugfs() - Populate mc addr list info
+ * @hdd_ctx: pointer to hdd context
+ * @adapter: pointer to adapter
+ * @buf: output buffer to hold mc addr list info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_mc_addr_list_info_debugfs(struct hdd_context *hdd_ctx,
+				   struct hdd_adapter *adapter, uint8_t *buf,
+				   ssize_t buf_avail_len)
+{
+	ssize_t length = 0;
+	int ret;
+	uint8_t i;
+	struct pmo_mc_addr_list mc_addr_list = {0};
+	QDF_STATUS status;
+
+	if (!ucfg_pmo_is_mc_addr_list_enabled(hdd_ctx->psoc)) {
+		ret = scnprintf(buf, buf_avail_len,
+				"\nMC addr ini is disabled\n");
+		if (ret > 0)
+			length = ret;
+		return length;
+	}
+
+	status = ucfg_pmo_get_mc_addr_list(hdd_ctx->psoc,
+					   adapter->session_id,
+					   &mc_addr_list);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		ret = scnprintf(buf, buf_avail_len,
+				"\nMC addr list query is failed\n");
+		if (ret > 0)
+			length = ret;
+		return length;
+	}
+
+	if (mc_addr_list.mc_cnt == 0) {
+		ret = scnprintf(buf, buf_avail_len,
+				"\nMC addr list is empty\n");
+		if (ret > 0)
+			length = ret;
+		return length;
+	}
+
+	ret = scnprintf(buf, buf_avail_len,
+			"\nMC ADDR LIST DETAILS (mc_cnt = %u)\n",
+			mc_addr_list.mc_cnt);
+	if (ret <= 0)
+		return length;
+	length += ret;
+
+	for (i = 0; i < mc_addr_list.mc_cnt; i++) {
+		if (length >= buf_avail_len) {
+			hdd_err("No sufficient buf_avail_len");
+			return buf_avail_len;
+		}
+
+		ret = scnprintf(buf + length, buf_avail_len - length,
+				MAC_ADDRESS_STR "\n",
+				MAC_ADDR_ARRAY(mc_addr_list.mc_addr[i].bytes));
+		if (ret <= 0)
+			return length;
+		length += ret;
+	}
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	ret = scnprintf(buf + length, buf_avail_len - length,
+			"mc_filter_applied = %u\n",
+			mc_addr_list.is_filter_applied);
+	if (ret <= 0)
+		return length;
+
+	length += ret;
+	return length;
+}
+
+/**
+ * wlan_hdd_arp_offload_info_debugfs() - Populate arp offload info
+ * @hdd_ctx: pointer to hdd context
+ * @adapter: pointer to adapter
+ * @buf: output buffer to hold arp offload info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_arp_offload_info_debugfs(struct hdd_context *hdd_ctx,
+				  struct hdd_adapter *adapter, uint8_t *buf,
+				  ssize_t buf_avail_len)
+{
+	ssize_t length = 0;
+	int ret_val;
+	struct pmo_arp_offload_params info = {0};
+	QDF_STATUS status;
+
+	status = ucfg_pmo_get_arp_offload_params(adapter->vdev,
+						 &info);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		ret_val = scnprintf(buf, buf_avail_len,
+				    "\nARP OFFLOAD QUERY FAILED\n");
+		goto len_adj;
+	}
+
+	if (!info.is_offload_applied)
+		ret_val = scnprintf(buf, buf_avail_len,
+				    "\nARP OFFLOAD: DISABLED\n");
+	else
+		ret_val = scnprintf(buf, buf_avail_len,
+				    "\nARP OFFLOAD: ENABLED (%u.%u.%u.%u)\n",
+				    info.host_ipv4_addr[0],
+				    info.host_ipv4_addr[1],
+				    info.host_ipv4_addr[2],
+				    info.host_ipv4_addr[3]);
+len_adj:
+	if (ret_val <= 0)
+		return length;
+	length = ret_val;
+
+	return length;
+}
+
+#ifdef WLAN_NS_OFFLOAD
+/**
+ * ipv6_addr_string() - Get IPv6 addr string from array of octets
+ * @buffer: output buffer to hold string, caller should ensure size of
+ *          buffer is atleast IPV6_MAC_ADDRESS_STR_LEN
+ * @ipv6_addr: IPv6 address array
+ *
+ * Return: None
+ */
+static void ipv6_addr_string(uint8_t *buffer, uint8_t *ipv6_addr)
+{
+	uint8_t *a = ipv6_addr;
+
+	scnprintf(buffer, IPV6_MAC_ADDRESS_STR_LEN,
+		  "%02x%02x::%02x%02x::%02x%02x::%02x%02x::%02x%02x::%02x%02x::%02x%02x::%02x%02x",
+		  (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6],
+		  (a)[7], (a)[8], (a)[9], (a)[10], (a)[11], (a)[12], (a)[13],
+		  (a)[14], (a)[15]);
+}
+
+/**
+ * hdd_ipv6_scope_str() - Get string for PMO NS (IPv6) Addr scope
+ * @scope: scope id from enum pmo_ns_addr_scope
+ *
+ * Return: Meaningful string for enum pmo_ns_addr_scope
+ */
+static uint8_t *hdd_ipv6_scope_str(enum pmo_ns_addr_scope scope)
+{
+	switch (scope) {
+	case PMO_NS_ADDR_SCOPE_NODELOCAL:
+		return "Node Local";
+	case PMO_NS_ADDR_SCOPE_LINKLOCAL:
+		return "Link Local";
+	case PMO_NS_ADDR_SCOPE_SITELOCAL:
+		return "Site Local";
+	case PMO_NS_ADDR_SCOPE_ORGLOCAL:
+		return "Org Local";
+	case PMO_NS_ADDR_SCOPE_GLOBAL:
+		return "Global";
+	default:
+		return "Invalid";
+	}
+}
+
+/**
+ * wlan_hdd_ns_offload_info_debugfs() - Populate ns offload info
+ * @hdd_ctx: pointer to hdd context
+ * @adapter: pointer to adapter
+ * @buf: output buffer to hold ns offload info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_ns_offload_info_debugfs(struct hdd_context *hdd_ctx,
+				 struct hdd_adapter *adapter, uint8_t *buf,
+				 ssize_t buf_avail_len)
+{
+	ssize_t length = 0;
+	int ret;
+	struct pmo_ns_offload_params info = {0};
+	QDF_STATUS status;
+	uint32_t i;
+
+	status = ucfg_pmo_get_ns_offload_params(adapter->vdev,
+						&info);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		ret = scnprintf(buf, buf_avail_len,
+				"\nNS OFFLOAD QUERY FAILED\n");
+		if (ret <= 0)
+			return length;
+		length += ret;
+
+		return length;
+	}
+
+	ret = scnprintf(buf, buf_avail_len,
+			"\nNS OFFLOAD DETAILS\n");
+	if (ret <= 0)
+		return length;
+	length += ret;
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+
+	if (!info.is_offload_applied) {
+		ret = scnprintf(buf + length, buf_avail_len - length,
+				"NS offload is not enabled\n");
+		if (ret <= 0)
+			return length;
+		length += ret;
+
+		return length;
+	}
+
+	ret = scnprintf(buf + length, buf_avail_len - length,
+			"NS offload enabled, %u ns addresses offloaded\n",
+			info.num_ns_offload_count);
+	if (ret <= 0)
+		return length;
+	length += ret;
+
+	for (i = 0; i < info.num_ns_offload_count; i++) {
+		uint8_t ipv6_str[IPV6_MAC_ADDRESS_STR_LEN];
+		uint8_t cast_string[12];
+		uint8_t *scope_string;
+
+		if (length >= buf_avail_len) {
+			hdd_err("No sufficient buf_avail_len");
+			return buf_avail_len;
+		}
+
+		ipv6_addr_string(ipv6_str, info.target_ipv6_addr[i]);
+		scope_string = hdd_ipv6_scope_str(info.scope[i]);
+
+		if (info.target_ipv6_addr_ac_type[i] ==
+		    PMO_IPV6_ADDR_AC_TYPE)
+			strlcpy(cast_string, "(ANY CAST)", 12);
+		else
+			strlcpy(cast_string, "(UNI CAST)", 12);
+
+		ret = scnprintf(buf + length, buf_avail_len - length,
+				"%u. %s %s and scope is: %s\n",
+				(i + 1), ipv6_str, cast_string,
+				scope_string);
+		if (ret <= 0)
+			return length;
+		length += ret;
+	}
+
+	return length;
+}
+#else
+/**
+ * wlan_hdd_ns_offload_info_debugfs() - Populate ns offload info
+ * @hdd_ctx: pointer to hdd context
+ * @adapter: pointer to adapter
+ * @buf: output buffer to hold ns offload info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_ns_offload_info_debugfs(struct hdd_context *hdd_ctx,
+				 struct hdd_adapter *adapter, uint8_t *buf,
+				 ssize_t buf_avail_len)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wlan_hdd_apf_info_debugfs() - Populate apf offload info
+ * @hdd_ctx: pointer to hdd context
+ * @adapter: pointer to adapter
+ * @buf: output buffer to hold apf offload info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_apf_info_debugfs(struct hdd_context *hdd_ctx,
+			  struct hdd_adapter *adapter, uint8_t *buf,
+			  ssize_t buf_avail_len)
+{
+	ssize_t length = 0;
+	int ret_val;
+	bool apf_enabled;
+
+	if (hdd_ctx->apf_version > 2)
+		apf_enabled = adapter->apf_context.apf_enabled;
+	else
+		apf_enabled = hdd_ctx->apf_enabled_v2;
+
+	ret_val = scnprintf(buf, buf_avail_len,
+			    "\nAPF OFFLOAD DETAILS, offload_applied: %u\n\n",
+			    apf_enabled);
+	if (ret_val <= 0)
+		return length;
+	length = ret_val;
+
+	return length;
+}
+
+ssize_t
+wlan_hdd_debugfs_update_filters_info(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter,
+				     uint8_t *buf, ssize_t buf_avail_len)
+{
+	ssize_t len;
+	int ret_val;
+	struct hdd_station_ctx *hdd_sta_ctx;
+
+	hdd_enter();
+
+	len = wlan_hdd_current_time_info_debugfs(buf, buf_avail_len);
+
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+
+	if (adapter->device_mode != QDF_STA_MODE) {
+		ret_val = scnprintf(buf + len, buf_avail_len - len,
+				    "Interface is not operating in STA mode\n");
+		if (ret_val <= 0)
+			return len;
+
+		len += ret_val;
+		return len;
+	}
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (hdd_sta_ctx->conn_info.connState != eConnectionState_Associated) {
+		ret_val = scnprintf(buf + len, buf_avail_len - len,
+				    "\nSTA is not connected\n");
+		if (ret_val <= 0)
+			return len;
+
+		len += ret_val;
+		return len;
+	}
+
+	len += wlan_hdd_mc_addr_list_info_debugfs(hdd_ctx, adapter, buf + len,
+						  buf_avail_len - len);
+
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	len += wlan_hdd_arp_offload_info_debugfs(hdd_ctx, adapter, buf + len,
+						 buf_avail_len - len);
+
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	len += wlan_hdd_ns_offload_info_debugfs(hdd_ctx, adapter, buf + len,
+						buf_avail_len - len);
+
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	len += wlan_hdd_apf_info_debugfs(hdd_ctx, adapter, buf + len,
+					 buf_avail_len - len);
+
+	hdd_exit();
+
+	return len;
+}
diff --git a/core/hdd/src/wlan_hdd_debugfs_roam.c b/core/hdd/src/wlan_hdd_debugfs_roam.c
new file mode 100644
index 0000000..6b3b210
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_debugfs_roam.c
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * 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: wlan_hdd_debugfs_roam.c
+ *
+ * WLAN Host Device Driver implementation to update
+ * debugfs with roaming information
+ */
+
+#include <wlan_hdd_debugfs_csr.h>
+#include <wlan_hdd_main.h>
+#include <cds_sched.h>
+#include <wma_api.h>
+#include "qwlan_version.h"
+#include "wmi_unified_param.h"
+#include "wlan_osif_request_manager.h"
+
+/**
+ * hdd_roam_scan_stats_debugfs_dealloc() - Dealloc objects in hdd request mgr
+ * @priv: Pointer to private data of hdd request object
+ *
+ * Return: None
+ */
+static void hdd_roam_scan_stats_debugfs_dealloc(void *priv)
+{
+	struct hdd_roam_scan_stats_debugfs_priv *local_priv = priv;
+	struct wmi_roam_scan_stats_res *roam_scan_stats_res;
+
+	if (!local_priv)
+		return;
+
+	roam_scan_stats_res = local_priv->roam_scan_stats_res;
+	local_priv->roam_scan_stats_res = NULL;
+
+	qdf_mem_free(roam_scan_stats_res);
+}
+
+/**
+ * hdd_roam_scan_stats_cb() - Call back invoked from roam scan stats evt
+ * @context: cookie to get request object
+ * @res: roam scan stats response from firmware
+ *
+ * Return: None
+ */
+static void
+hdd_roam_scan_stats_cb(void *context, struct wmi_roam_scan_stats_res *res)
+{
+	struct osif_request *request;
+	struct hdd_roam_scan_stats_debugfs_priv *priv;
+	struct wmi_roam_scan_stats_res *stats_res;
+	uint32_t total_len;
+
+	hdd_enter();
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete roam scan stats request");
+		return;
+	}
+
+	if (!res) {
+		hdd_err("Invalid response");
+		goto end;
+	}
+
+	priv = osif_request_priv(request);
+
+	total_len = sizeof(*res) + res->num_roam_scans *
+		    sizeof(struct wmi_roam_scan_stats_params);
+
+	stats_res = qdf_mem_malloc(total_len);
+	if (!stats_res) {
+		hdd_err("No memory for response");
+		goto end;
+	}
+
+	qdf_mem_copy(stats_res, res, total_len);
+	priv->roam_scan_stats_res = stats_res;
+
+end:
+	osif_request_complete(request);
+	osif_request_put(request);
+
+	hdd_exit();
+}
+
+/**
+ * hdd_get_roam_scan_stats() - Get roam scan stats using request manager
+ * @hdd_ctx: hdd context
+ * @adapter: pointer to adapter
+ *
+ * Return: Pointer to struct wmi_roam_scan_stats_res which conatins response
+ * from firmware
+ */
+static struct
+wmi_roam_scan_stats_res *hdd_get_roam_scan_stats(struct hdd_context *hdd_ctx,
+						 struct hdd_adapter *adapter)
+{
+	struct wmi_roam_scan_stats_res *res;
+	struct wmi_roam_scan_stats_res *stats_res = NULL;
+	void *context;
+	struct osif_request *request;
+	struct hdd_roam_scan_stats_debugfs_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_FW_ROAM_STATS,
+		.dealloc = hdd_roam_scan_stats_debugfs_dealloc,
+	};
+	QDF_STATUS status;
+	int ret;
+	uint32_t total_len;
+
+	hdd_enter();
+
+	if (!wlan_hdd_validate_modules_state(hdd_ctx))
+		return NULL;
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return NULL;
+	}
+
+	context = osif_request_cookie(request);
+
+	status = sme_get_roam_scan_stats(hdd_ctx->mac_handle,
+					 hdd_roam_scan_stats_cb,
+					 context, adapter->session_id);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("roam scan stats request failed");
+		goto cleanup;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_err("roam scan stats response time out");
+		goto cleanup;
+	}
+
+	priv = osif_request_priv(request);
+	res = priv->roam_scan_stats_res;
+	if (!res) {
+		hdd_err("Failure of roam scan stats response retrieval");
+		goto cleanup;
+	}
+
+	total_len = sizeof(*res) + res->num_roam_scans *
+		    sizeof(struct wmi_roam_scan_stats_params);
+
+	stats_res = qdf_mem_malloc(total_len);
+	if (!stats_res) {
+		hdd_err("No memory for response");
+		goto cleanup;
+	}
+
+	qdf_mem_copy(stats_res, res, total_len);
+
+cleanup:
+	osif_request_put(request);
+	hdd_exit();
+
+	return stats_res;
+}
+
+/**
+ * hdd_roam_scan_trigger_to_str() - Get string for
+ * enum WMI_ROAM_TRIGGER_REASON_ID
+ * @roam_scan_trigger: roam scan trigger ID
+ *
+ * Return: Meaningful string from enum WMI_ROAM_TRIGGER_REASON_ID
+ */
+static char *hdd_roam_scan_trigger_to_str(uint32_t roam_scan_trigger)
+{
+	switch (roam_scan_trigger) {
+	case WMI_ROAM_TRIGGER_REASON_PER:
+		return "PER";
+	case WMI_ROAM_TRIGGER_REASON_BMISS:
+		return "BEACON MISS";
+	case WMI_ROAM_TRIGGER_REASON_LOW_RSSI:
+		return "LOW RSSI";
+	case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI:
+		return "HIGH RSSI";
+	case WMI_ROAM_TRIGGER_REASON_PERIODIC:
+		return "PERIODIC SCAN";
+	case WMI_ROAM_TRIGGER_REASON_MAWC:
+		return "WMI_ROAM_TRIGGER_REASON_MAWC";
+	case WMI_ROAM_TRIGGER_REASON_DENSE:
+		return "DENSE ENVIRONMENT";
+	case WMI_ROAM_TRIGGER_REASON_BACKGROUND:
+		return "BACKGROUND SCAN";
+	case WMI_ROAM_TRIGGER_REASON_FORCED:
+		return "FORCED SCAN";
+	case WMI_ROAM_TRIGGER_REASON_BTM:
+		return "BTM TRIGGER";
+	case WMI_ROAM_TRIGGER_REASON_UNIT_TEST:
+		return "TEST COMMMAND";
+	default:
+		return "UNKNOWN REASON";
+	}
+	return "UNKNOWN REASON";
+}
+
+/**
+ * hdd_roam_scan_trigger_value_to_str() - Get trigger value string for
+ * enum WMI_ROAM_TRIGGER_REASON_ID
+ * @roam_scan_trigger: roam scan trigger ID
+ * @bool: output pointer to hold whether to print trigger value
+ *
+ * Return: Meaningful string from trigger value
+ */
+static char *hdd_roam_scan_trigger_value(uint32_t roam_scan_trigger,
+					 bool *print)
+{
+	*print = true;
+
+	switch (roam_scan_trigger) {
+	case WMI_ROAM_TRIGGER_REASON_PER:
+		return "percentage";
+	case WMI_ROAM_TRIGGER_REASON_LOW_RSSI:
+		return "dB";
+	case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI:
+		return "dB";
+	case WMI_ROAM_TRIGGER_REASON_PERIODIC:
+		return "ms";
+	case WMI_ROAM_TRIGGER_REASON_DENSE:
+		return "(1 - Rx, 2 - Tx)";
+	default:
+		*print = false;
+		return NULL;
+	}
+}
+
+/**
+ * hdd_client_id_to_str() - Helper func to get meaninful string from client id
+ * @client_id: Id of the client which triggered roam scan in firmware
+ *
+ * Return: Meaningful string from enum WMI_SCAN_CLIENT_ID
+ */
+static char *hdd_client_id_to_str(uint32_t client_id)
+{
+	switch (client_id) {
+	case WMI_SCAN_CLIENT_NLO:
+		return "PNO";
+	case WMI_SCAN_CLIENT_EXTSCAN:
+		return "GSCAN";
+	case WMI_SCAN_CLIENT_ROAM:
+		return "ROAM";
+	case WMI_SCAN_CLIENT_P2P:
+		return "P2P";
+	case WMI_SCAN_CLIENT_LPI:
+		return "LPI";
+	case WMI_SCAN_CLIENT_NAN:
+		return "NAN";
+	case WMI_SCAN_CLIENT_ANQP:
+		return "ANQP";
+	case WMI_SCAN_CLIENT_OBSS:
+		return "OBSS";
+	case WMI_SCAN_CLIENT_PLM:
+		return "PLM";
+	case WMI_SCAN_CLIENT_HOST:
+		return "HOST";
+	default:
+		return "UNKNOWN";
+	}
+	return "UNKNOWN";
+}
+
+/**
+ * hdd_roam_scan_trigger() - Print roam scan trigger info into buffer
+ * @scan: roam scan event data
+ * @buf: buffer to write roam scan trigger info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+hdd_roam_scan_trigger(struct wmi_roam_scan_stats_params *scan,
+		      uint8_t *buf, ssize_t buf_avail_len)
+{
+	ssize_t length = 0;
+	int ret;
+	char *str;
+	bool print_trigger_value;
+
+	ret = scnprintf(buf, buf_avail_len,
+			"Trigger reason is %s\n",
+			hdd_roam_scan_trigger_to_str(scan->trigger_id));
+	if (ret <= 0)
+		return length;
+
+	length = ret;
+
+	str = hdd_roam_scan_trigger_value(scan->trigger_id,
+					  &print_trigger_value);
+	if (!print_trigger_value || !str)
+		return length;
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		length = buf_avail_len;
+		return length;
+	}
+
+	ret = scnprintf(buf + length, buf_avail_len - length,
+			"Trigger value is: %u %s\n",
+			scan->trigger_value, str);
+	if (ret <= 0)
+		return length;
+
+	length += ret;
+	return length;
+}
+
+/**
+ * hdd_roam_scan_chan() - Print roam scan chan freq info into buffer
+ * @scan: roam scan event data
+ * @buf: buffer to write roam scan freq info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+hdd_roam_scan_chan(struct wmi_roam_scan_stats_params *scan,
+		   uint8_t *buf, ssize_t buf_avail_len)
+{
+	ssize_t length = 0;
+	uint32_t i;
+	int ret;
+
+	ret = scnprintf(buf, buf_avail_len,
+			"Num of scan channels: %u\n"
+			"scan channel list:",
+			scan->num_scan_chans);
+	if (ret <= 0)
+		return length;
+
+	length = ret;
+
+	for (i = 0; i < scan->num_scan_chans; i++) {
+		if (length >= buf_avail_len) {
+			hdd_err("No sufficient buf_avail_len");
+			length = buf_avail_len;
+			return length;
+		}
+
+		ret = scnprintf(buf + length, buf_avail_len - length,
+				"%u ", scan->scan_freqs[i]);
+		if (ret <= 0)
+			return length;
+
+		length += ret;
+	}
+
+	return length;
+}
+
+/**
+ * wlan_hdd_update_roam_stats() - Internal function to get roam scan stats
+ * @hdd_ctx: hdd context
+ * @adapter: pointer to adapter
+ * @buf: buffer to hold the stats
+ * @len: maximum available length in response buffer
+ *
+ * Return: Size of formatted roam scan response stats
+ */
+static ssize_t
+wlan_hdd_update_roam_stats(struct hdd_context *hdd_ctx,
+			   struct hdd_adapter *adapter,
+			   uint8_t *buf, ssize_t buf_avail_len)
+{
+	ssize_t length = 0;
+	struct wmi_roam_scan_stats_res *roam_stats;
+	struct wmi_roam_scan_stats_params *scan;
+	int ret;
+	int rsi; /* roam scan iterator */
+	int rci; /* roam candidate iterator */
+
+	roam_stats = hdd_get_roam_scan_stats(hdd_ctx, adapter);
+	if (!roam_stats) {
+		hdd_err("Couldn't get roam stats");
+		ret = scnprintf(buf, buf_avail_len,
+				"Failed to fetch roam stats\n");
+		if (ret <= 0)
+			return length;
+		length += ret;
+		return length;
+	}
+
+	ret = scnprintf(buf, buf_avail_len,
+			"\n\nStats of last %u roam scans\n",
+			roam_stats->num_roam_scans);
+	if (ret <= 0)
+		goto free_mem;
+	length += ret;
+
+	for (rsi = 0; rsi < roam_stats->num_roam_scans; rsi++) {
+		if (length >= buf_avail_len) {
+			hdd_err("No sufficient buf_avail_len");
+			length = buf_avail_len;
+			goto free_mem;
+		}
+
+		scan = &roam_stats->roam_scan[rsi];
+		ret = scnprintf(buf + length, buf_avail_len - length,
+				"\nRoam scan[%u] details\n", rsi);
+		if (ret <= 0)
+			goto free_mem;
+		length += ret;
+
+		if (length >= buf_avail_len) {
+			hdd_err("No sufficient buf_avail_len");
+			length = buf_avail_len;
+			goto free_mem;
+		}
+
+		ret = scnprintf(buf + length, buf_avail_len - length,
+				"This scan is triggered by \"%s\" scan client\n",
+				hdd_client_id_to_str(scan->client_id));
+
+		if (ret <= 0)
+			goto free_mem;
+		length += ret;
+
+		if (length >= buf_avail_len) {
+			hdd_err("No sufficient buf_avail_len");
+			length = buf_avail_len;
+			goto free_mem;
+		}
+
+		length += hdd_roam_scan_trigger(scan, buf + length,
+						buf_avail_len - length);
+		if (length >= buf_avail_len) {
+			hdd_err("No sufficient buf_avail_len");
+			length = buf_avail_len;
+			goto free_mem;
+		}
+
+		length += hdd_roam_scan_chan(scan, buf + length,
+					     buf_avail_len - length);
+		if (length >= buf_avail_len) {
+			hdd_err("No sufficient buf_avail_len");
+			length = buf_avail_len;
+			goto free_mem;
+		}
+
+		if (scan->is_roam_successful) {
+			ret = scnprintf(buf + length,
+					buf_avail_len - length,
+					"\nSTA roamed from "
+					MAC_ADDRESS_STR " to "
+					MAC_ADDRESS_STR "\n",
+					MAC_ADDR_ARRAY(scan->old_bssid),
+					MAC_ADDR_ARRAY(scan->new_bssid));
+		} else {
+			ret = scnprintf(buf + length,
+					buf_avail_len - length,
+					"\nSTA is connected to " MAC_ADDRESS_STR
+					" before and after scan, not roamed\n",
+					MAC_ADDR_ARRAY(scan->old_bssid));
+		}
+		if (ret <= 0)
+			goto free_mem;
+		length += ret;
+
+		if (length >= buf_avail_len) {
+			hdd_err("No sufficient buf_avail_len");
+			length = buf_avail_len;
+			goto free_mem;
+		}
+
+		ret = scnprintf(buf + length, buf_avail_len - length,
+				"Roam candidate details\n");
+		if (ret <= 0)
+			goto free_mem;
+		length += ret;
+
+		if (length >= buf_avail_len) {
+			hdd_err("No sufficient buf_avail_len");
+			length = buf_avail_len;
+			goto free_mem;
+		}
+
+		ret = scnprintf(buf + length, buf_avail_len - length,
+				"      BSSID     FREQ   SCORE  RSSI\n");
+		if (ret <= 0)
+			goto free_mem;
+		length += ret;
+
+		for (rci = 0; rci < scan->num_roam_candidates; rci++) {
+			uint8_t *bssid = scan->cand[rci].bssid;
+
+			if (length >= buf_avail_len) {
+				hdd_err("No sufficient buf_avail_len");
+				length = buf_avail_len;
+				goto free_mem;
+			}
+
+			ret = scnprintf(buf + length,
+					buf_avail_len - length,
+					MAC_ADDRESS_STR " %4u  %3u   %3u\n",
+					MAC_ADDR_ARRAY(bssid),
+					scan->cand[rci].freq,
+					scan->cand[rci].score,
+					scan->cand[rci].rssi);
+			if (ret <= 0)
+				goto free_mem;
+			length += ret;
+		}
+	}
+
+free_mem:
+	qdf_mem_free(roam_stats);
+	return length;
+}
+
+ssize_t
+wlan_hdd_debugfs_update_roam_stats(struct hdd_context *hdd_ctx,
+				   struct hdd_adapter *adapter,
+				   uint8_t *buf, ssize_t buf_avail_len)
+{
+	ssize_t len = 0;
+	int ret_val;
+
+	hdd_enter();
+
+	len = wlan_hdd_current_time_info_debugfs(buf, buf_avail_len - len);
+
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	if (adapter->device_mode != QDF_STA_MODE) {
+		ret_val = scnprintf(buf + len, buf_avail_len - len,
+				    "Interface is not in STA Mode\n");
+		if (ret_val <= 0)
+			return len;
+
+		len += ret_val;
+		return len;
+	}
+
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	len += wlan_hdd_update_roam_stats(hdd_ctx, adapter, buf + len,
+					  buf_avail_len - len);
+
+	hdd_exit();
+
+	return len;
+}
diff --git a/core/hdd/src/wlan_hdd_disa.c b/core/hdd/src/wlan_hdd_disa.c
new file mode 100644
index 0000000..374b2e1
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_disa.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 2016-2018 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 : wlan_hdd_disa.c
+ *
+ * WLAN Host Device Driver file for DISA certification
+ *
+ */
+
+#include "wlan_hdd_disa.h"
+#include "wlan_disa_ucfg_api.h"
+#include "wlan_osif_request_manager.h"
+#include "sme_api.h"
+#include <qca_vendor.h>
+
+#define WLAN_WAIT_TIME_ENCRYPT_DECRYPT 1000
+
+
+/**
+ * hdd_encrypt_decrypt_msg_context - hdd encrypt/decrypt message context
+ * @status: status of response. 0: no error, -ENOMEM: unable to allocate
+ *   memory for the response payload
+ * @request: encrypt/decrypt request
+ * @response: encrypt/decrypt response
+ */
+struct hdd_encrypt_decrypt_msg_context {
+	int status;
+	struct disa_encrypt_decrypt_req_params request;
+	struct disa_encrypt_decrypt_resp_params response;
+};
+
+/**
+ * hdd_encrypt_decrypt_msg_cb () - encrypt/decrypt response message handler
+ * @cookie: hdd request cookie
+ * @resp: encrypt/decrypt response parameters
+ *
+ * Return: none
+ */
+static void hdd_encrypt_decrypt_msg_cb(void *cookie,
+	struct disa_encrypt_decrypt_resp_params *resp)
+{
+	struct osif_request *request;
+	struct hdd_encrypt_decrypt_msg_context *context;
+
+	hdd_enter();
+
+	if (!resp) {
+		hdd_err("rsp params is NULL");
+		return;
+	}
+
+	request = osif_request_get(cookie);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	print_hex_dump(KERN_INFO, "Data in hdd_encrypt_decrypt_msg_cb: ",
+		DUMP_PREFIX_NONE, 16, 1,
+		resp->data,
+		resp->data_len, 0);
+
+	hdd_debug("vdev_id: %d status:%d data_length: %d",
+		resp->vdev_id,
+		resp->status,
+		resp->data_len);
+
+	context = osif_request_priv(request);
+	context->response = *resp;
+	context->status = 0;
+	if (resp->data_len) {
+		context->response.data =
+			qdf_mem_malloc(sizeof(uint8_t) *
+				resp->data_len);
+		if (!context->response.data) {
+			hdd_err("memory allocation failed");
+			context->status = -ENOMEM;
+		} else {
+			qdf_mem_copy(context->response.data,
+				     resp->data,
+				     resp->data_len);
+		}
+	} else {
+		/* make sure we don't have a rogue pointer */
+		context->response.data = NULL;
+	}
+
+	osif_request_complete(request);
+	osif_request_put(request);
+	hdd_exit();
+}
+
+/**
+ * hdd_post_encrypt_decrypt_msg_rsp () - send encrypt/decrypt data to user space
+ * @encrypt_decrypt_rsp_params: encrypt/decrypt response parameters
+ *
+ * Return: none
+ */
+static int hdd_post_encrypt_decrypt_msg_rsp(struct hdd_context *hdd_ctx,
+	struct disa_encrypt_decrypt_resp_params *resp)
+{
+	struct sk_buff *skb;
+	uint32_t nl_buf_len;
+
+	hdd_enter();
+
+	nl_buf_len = resp->data_len + NLA_HDRLEN;
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	if (resp->data_len) {
+		if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA,
+				resp->data_len, resp->data)) {
+			hdd_err("put fail");
+			goto nla_put_failure;
+		}
+	}
+
+	cfg80211_vendor_cmd_reply(skb);
+	hdd_exit();
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EINVAL;
+}
+
+static const struct nla_policy
+encrypt_decrypt_policy[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION] = {
+		.type = NLA_FLAG},
+	[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER] = {
+		.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID] = {
+		.type = NLA_U8},
+};
+
+/**
+ * hdd_fill_encrypt_decrypt_params () - parses data from user space
+ * and fills encrypt/decrypt parameters
+ * @encrypt_decrypt_params: encrypt/decrypt request parameters
+ * @adapter : adapter context
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ Return: 0 on success, negative errno on failure
+ */
+static int
+hdd_fill_encrypt_decrypt_params(struct disa_encrypt_decrypt_req_params
+				*encrypt_decrypt_params,
+				struct hdd_adapter *adapter,
+				const void *data,
+				int data_len)
+{
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX + 1];
+	uint8_t len, mac_hdr_len;
+	uint8_t *tmp;
+	uint8_t fc[2];
+
+	if (wlan_cfg80211_nla_parse(tb,
+				    QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX,
+				    data, data_len, encrypt_decrypt_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	encrypt_decrypt_params->vdev_id = adapter->session_id;
+	hdd_debug("vdev_id: %d", encrypt_decrypt_params->vdev_id);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION]) {
+		hdd_err("attr flag NEEDS_DECRYPTION not present");
+		encrypt_decrypt_params->key_flag = WMI_ENCRYPT;
+	} else {
+		hdd_err("attr flag NEEDS_DECRYPTION present");
+		encrypt_decrypt_params->key_flag = WMI_DECRYPT;
+	}
+	hdd_debug("Key flag: %d", encrypt_decrypt_params->key_flag);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID]) {
+		hdd_err("attr key id failed");
+		return -EINVAL;
+	}
+	encrypt_decrypt_params->key_idx = nla_get_u8(tb
+		    [QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID]);
+	hdd_debug("Key Idx: %d", encrypt_decrypt_params->key_idx);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER]) {
+		hdd_err("attr Cipher failed");
+		return -EINVAL;
+	}
+	encrypt_decrypt_params->key_cipher = nla_get_u32(tb
+		    [QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER]);
+	hdd_debug("key_cipher: %d", encrypt_decrypt_params->key_cipher);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK]) {
+		hdd_err("attr TK failed");
+		return -EINVAL;
+	}
+	encrypt_decrypt_params->key_len =
+		nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK]);
+	if (!encrypt_decrypt_params->key_len) {
+		hdd_err("Invalid TK length");
+		return -EINVAL;
+	}
+	hdd_debug("Key len: %d", encrypt_decrypt_params->key_len);
+
+	if (encrypt_decrypt_params->key_len > SIR_MAC_MAX_KEY_LENGTH)
+		encrypt_decrypt_params->key_len = SIR_MAC_MAX_KEY_LENGTH;
+
+	tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK]);
+
+	qdf_mem_copy(encrypt_decrypt_params->key_data, tmp,
+			encrypt_decrypt_params->key_len);
+
+	print_hex_dump(KERN_INFO, "Key : ", DUMP_PREFIX_NONE, 16, 1,
+			&encrypt_decrypt_params->key_data,
+			encrypt_decrypt_params->key_len, 0);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]) {
+		hdd_err("attr PN failed");
+		return -EINVAL;
+	}
+	len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]);
+	if (!len || len > sizeof(encrypt_decrypt_params->pn)) {
+		hdd_err("Invalid PN length %u", len);
+		return -EINVAL;
+	}
+
+	tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]);
+
+	qdf_mem_copy(encrypt_decrypt_params->pn, tmp, len);
+
+	print_hex_dump(KERN_INFO, "PN received : ", DUMP_PREFIX_NONE, 16, 1,
+			&encrypt_decrypt_params->pn, len, 0);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]) {
+		hdd_err("attr header failed");
+		return -EINVAL;
+	}
+	len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]);
+	if (len < MIN_MAC_HEADER_LEN) {
+		hdd_err("Invalid header and payload length %u", len);
+		return -EINVAL;
+	}
+
+	hdd_debug("Header and Payload length: %d", len);
+
+	tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]);
+
+	print_hex_dump(KERN_INFO, "Header and Payload received: ",
+			DUMP_PREFIX_NONE, 16, 1,
+			tmp, len, 0);
+
+	mac_hdr_len = MIN_MAC_HEADER_LEN;
+
+	/*
+	 * Check to find out address 4. Address 4 is present if ToDS and FromDS
+	 * are 1 and data representation is little endian.
+	 */
+	fc[1] = *tmp;
+	fc[0] = *(tmp + 1);
+	if ((fc[0] & 0x03) == 0x03) {
+		hdd_err("Address 4 is present");
+		mac_hdr_len += IEEE80211_ADDR_LEN;
+	}
+
+	/*
+	 * Check to find out Qos control field. Qos control field is present
+	 * if msb of subtype field is 1 and data representation is
+	 * little endian.
+	 */
+	if (fc[1] & 0x80) {
+		hdd_err("Qos control is present");
+		mac_hdr_len += QOS_CONTROL_LEN;
+	}
+
+	hdd_debug("mac_hdr_len: %d", mac_hdr_len);
+
+	if (len < mac_hdr_len) {
+		hdd_err("Invalid header and payload length %u", len);
+		return -EINVAL;
+	}
+	qdf_mem_copy(encrypt_decrypt_params->mac_header,
+			tmp, mac_hdr_len);
+
+	print_hex_dump(KERN_INFO, "Header received in request: ",
+			DUMP_PREFIX_NONE, 16, 1,
+			encrypt_decrypt_params->mac_header,
+			mac_hdr_len, 0);
+
+	encrypt_decrypt_params->data_len =
+			len - mac_hdr_len;
+
+	hdd_debug("Payload length: %d", encrypt_decrypt_params->data_len);
+
+	if (encrypt_decrypt_params->data_len) {
+		encrypt_decrypt_params->data =
+			qdf_mem_malloc(sizeof(uint8_t) *
+				encrypt_decrypt_params->data_len);
+
+		if (encrypt_decrypt_params->data == NULL) {
+			hdd_err("memory allocation failed");
+			return -ENOMEM;
+		}
+
+		qdf_mem_copy(encrypt_decrypt_params->data,
+			tmp + mac_hdr_len,
+			encrypt_decrypt_params->data_len);
+
+		print_hex_dump(KERN_INFO, "Data received in request: ",
+			DUMP_PREFIX_NONE, 16, 1,
+			encrypt_decrypt_params->data,
+			encrypt_decrypt_params->data_len, 0);
+	}
+
+	return 0;
+}
+
+static void hdd_encrypt_decrypt_context_dealloc(void *priv)
+{
+	struct hdd_encrypt_decrypt_msg_context *context = priv;
+
+	qdf_mem_free(context->request.data);
+	qdf_mem_free(context->response.data);
+}
+
+/**
+ * hdd_encrypt_decrypt_msg () - process encrypt/decrypt message
+ * @adapter : adapter context
+ * @hdd_ctx: hdd context
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ Return: 0 on success, negative errno on failure
+ */
+static int hdd_encrypt_decrypt_msg(struct hdd_adapter *adapter,
+				   struct hdd_context *hdd_ctx,
+				   const void *data,
+				   int data_len)
+{
+	QDF_STATUS qdf_status;
+	int ret;
+	void *cookie;
+	struct osif_request *request;
+	struct hdd_encrypt_decrypt_msg_context *context;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*context),
+		.timeout_ms = WLAN_WAIT_TIME_ENCRYPT_DECRYPT,
+		.dealloc = hdd_encrypt_decrypt_context_dealloc,
+	};
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	context = osif_request_priv(request);
+
+	ret = hdd_fill_encrypt_decrypt_params(&context->request, adapter,
+					      data, data_len);
+	if (ret)
+		goto cleanup;
+
+	cookie = osif_request_cookie(request);
+
+	qdf_status = ucfg_disa_encrypt_decrypt_req(hdd_ctx->psoc,
+				&context->request,
+				hdd_encrypt_decrypt_msg_cb,
+				cookie);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Unable to post encrypt/decrypt message");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_err("Target response timed out");
+		goto cleanup;
+	}
+
+	ret = context->status;
+	if (ret) {
+		hdd_err("Target response processing failed");
+		goto cleanup;
+	}
+
+	ret = hdd_post_encrypt_decrypt_msg_rsp(hdd_ctx, &context->response);
+	if (ret)
+		hdd_err("Failed to post encrypt/decrypt message response");
+
+cleanup:
+	osif_request_put(request);
+
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_encrypt_decrypt_msg () - Encrypt/Decrypt msg
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_encrypt_decrypt_msg(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = NULL;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+	if (hdd_ctx->config->is_ps_enabled) {
+		hdd_debug("DISA is not supported when PS is enabled");
+		return -EINVAL;
+	}
+
+	ret = hdd_encrypt_decrypt_msg(adapter, hdd_ctx, data, data_len);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_encrypt_decrypt_msg () - Encrypt/Decrypt msg
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_encrypt_decrypt_msg(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_encrypt_decrypt_msg(wiphy, wdev,
+						data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
diff --git a/core/hdd/src/wlan_hdd_disa.h b/core/hdd/src/wlan_hdd_disa.h
new file mode 100644
index 0000000..2116ea1
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_disa.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016-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.
+ */
+
+#ifndef _WLAN_HDD_DISA_H
+#define _WLAN_HDD_DISA_H
+
+#include "wlan_hdd_main.h"
+#include "sir_api.h"
+
+#ifdef WLAN_FEATURE_DISA
+/**
+ * wlan_hdd_cfg80211_encrypt_decrypt_msg () - Encrypt/Decrypt msg
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_encrypt_decrypt_msg(struct wiphy *wiphy,
+			struct wireless_dev *wdev,
+			const void *data,
+			int data_len);
+#endif
+
+#endif
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
new file mode 100644
index 0000000..d3e766e
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_driver_ops.c
@@ -0,0 +1,1623 @@
+/*
+ * Copyright (c) 2015-2018 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include "cds_api.h"
+#include "qdf_status.h"
+#include "qdf_lock.h"
+#include "cds_sched.h"
+#include "osdep.h"
+#include "hif.h"
+#include "htc.h"
+#include "epping_main.h"
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_power.h"
+#include "wlan_logging_sock_svc.h"
+#include "wma_api.h"
+#include "wlan_hdd_napi.h"
+#include "wlan_policy_mgr_api.h"
+#include "qwlan_version.h"
+#include "bmi.h"
+#include "cdp_txrx_bus.h"
+#include "cdp_txrx_misc.h"
+#include "pld_common.h"
+#include "wlan_hdd_driver_ops.h"
+#include "wlan_ipa_ucfg_api.h"
+#include "wlan_hdd_debugfs.h"
+#include "cfg_ucfg_api.h"
+
+#ifdef MODULE
+#define WLAN_MODULE_NAME  module_name(THIS_MODULE)
+#else
+#define WLAN_MODULE_NAME  "wlan"
+#endif
+
+#define DISABLE_KRAIT_IDLE_PS_VAL      1
+
+#define SSR_MAX_FAIL_CNT 3
+static uint8_t re_init_fail_cnt, probe_fail_cnt;
+
+/*
+ * In BMI Phase we are only sending small chunk (256 bytes) of the FW image at
+ * a time, and wait for the completion interrupt to start the next transfer.
+ * During this phase, the KRAIT is entering IDLE/StandAlone(SA) Power Save(PS).
+ * The delay incurred for resuming from IDLE/SA PS is huge during driver load.
+ * So prevent APPS IDLE/SA PS durint driver load for reducing interrupt latency.
+ */
+
+static inline void hdd_request_pm_qos(struct device *dev, int val)
+{
+	pld_request_pm_qos(dev, val);
+}
+
+static inline void hdd_remove_pm_qos(struct device *dev)
+{
+	pld_remove_pm_qos(dev);
+}
+
+/**
+ * hdd_set_recovery_in_progress() - API to set recovery in progress
+ * @data: Context
+ * @val: Value to set
+ *
+ * Return: None
+ */
+static void hdd_set_recovery_in_progress(void *data, uint8_t val)
+{
+	cds_set_recovery_in_progress(val);
+}
+
+/**
+ * hdd_is_driver_unloading() - API to query if driver is unloading
+ * @data: Private Data
+ *
+ * Return: True/False
+ */
+static bool hdd_is_driver_unloading(void *data)
+{
+	return cds_is_driver_unloading();
+}
+
+/**
+ * hdd_is_load_or_unload_in_progress() - API to query if driver is
+ * loading/unloading
+ * @data: Private Data
+ *
+ * Return: bool
+ */
+static bool hdd_is_load_or_unload_in_progress(void *data)
+{
+	return cds_is_load_or_unload_in_progress();
+}
+
+/**
+ * hdd_is_recovery_in_progress() - API to query if recovery in progress
+ * @data: Private Data
+ *
+ * Return: bool
+ */
+static bool hdd_is_recovery_in_progress(void *data)
+{
+	return cds_is_driver_recovering();
+}
+
+/**
+ * hdd_is_target_ready() - API to query if target is in ready state
+ * @data: Private Data
+ *
+ * Return: bool
+ */
+static bool hdd_is_target_ready(void *data)
+{
+	return cds_is_target_ready();
+}
+
+/**
+ * hdd_hif_init_driver_state_callbacks() - API to initialize HIF callbacks
+ * @data: Private Data
+ * @cbk: HIF Driver State callbacks
+ *
+ * HIF should be independent of CDS calls. Pass CDS Callbacks to HIF, HIF will
+ * call the callbacks.
+ *
+ * Return: void
+ */
+static void hdd_hif_init_driver_state_callbacks(void *data,
+			struct hif_driver_state_callbacks *cbk)
+{
+	cbk->context = data;
+	cbk->set_recovery_in_progress = hdd_set_recovery_in_progress;
+	cbk->is_recovery_in_progress = hdd_is_recovery_in_progress;
+	cbk->is_load_unload_in_progress = hdd_is_load_or_unload_in_progress;
+	cbk->is_driver_unloading = hdd_is_driver_unloading;
+	cbk->is_target_ready = hdd_is_target_ready;
+}
+
+/**
+ * hdd_init_cds_hif_context() - API to set CDS HIF Context
+ * @hif: HIF Context
+ *
+ * Return: success/failure
+ */
+static int hdd_init_cds_hif_context(void *hif)
+{
+	QDF_STATUS status;
+
+	status = cds_set_context(QDF_MODULE_ID_HIF, hif);
+
+	if (status)
+		return -ENOENT;
+
+	return 0;
+}
+
+/**
+ * hdd_deinit_cds_hif_context() - API to clear CDS HIF COntext
+ *
+ * Return: None
+ */
+static void hdd_deinit_cds_hif_context(void)
+{
+	QDF_STATUS status;
+
+	status = cds_set_context(QDF_MODULE_ID_HIF, NULL);
+
+	if (status)
+		hdd_err("Failed to reset CDS HIF Context");
+}
+
+/**
+ * to_bus_type() - Map PLD bus type to low level bus type
+ * @bus_type: PLD bus type
+ *
+ * Map PLD bus type to low level bus type.
+ *
+ * Return: low level bus type.
+ */
+static enum qdf_bus_type to_bus_type(enum pld_bus_type bus_type)
+{
+	switch (bus_type) {
+	case PLD_BUS_TYPE_PCIE:
+		return QDF_BUS_TYPE_PCI;
+	case PLD_BUS_TYPE_SNOC:
+		return QDF_BUS_TYPE_SNOC;
+	case PLD_BUS_TYPE_SDIO:
+		return QDF_BUS_TYPE_SDIO;
+	case PLD_BUS_TYPE_USB:
+		return QDF_BUS_TYPE_USB;
+	default:
+		return QDF_BUS_TYPE_NONE;
+	}
+}
+
+int hdd_hif_open(struct device *dev, void *bdev, const struct hif_bus_id *bid,
+			enum qdf_bus_type bus_type, bool reinit)
+{
+	QDF_STATUS status;
+	int ret = 0;
+	struct hif_opaque_softc *hif_ctx;
+	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	struct hif_driver_state_callbacks cbk;
+	uint32_t mode = cds_get_conparam();
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx error");
+		return -EFAULT;
+	}
+
+	hdd_hif_init_driver_state_callbacks(dev, &cbk);
+
+	hif_ctx = hif_open(qdf_ctx, mode, bus_type, &cbk);
+	if (!hif_ctx) {
+		hdd_err("hif_open error");
+		return -ENOMEM;
+	}
+
+	ret = hdd_init_cds_hif_context(hif_ctx);
+	if (ret) {
+		hdd_err("Failed to set global HIF CDS Context err: %d", ret);
+		goto err_hif_close;
+	}
+
+	status = hif_enable(hif_ctx, dev, bdev, bid, bus_type,
+			    (reinit == true) ?  HIF_ENABLE_TYPE_REINIT :
+			    HIF_ENABLE_TYPE_PROBE);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("hif_enable failed status: %d, reinit: %d",
+			status, reinit);
+
+		ret = qdf_status_to_os_return(status);
+		goto err_hif_close;
+	} else {
+		cds_set_target_ready(true);
+		ret = hdd_napi_create();
+		hdd_debug("hdd_napi_create returned: %d", ret);
+		if (ret == 0)
+			hdd_warn("NAPI: no instances are created");
+		else if (ret < 0) {
+			hdd_err("NAPI creation error, rc: 0x%x, reinit: %d",
+				ret, reinit);
+			ret = -EFAULT;
+			goto mark_target_not_ready;
+		} else {
+			hdd_napi_event(NAPI_EVT_INI_FILE,
+				(void *)hdd_ctx->napi_enable);
+		}
+	}
+
+	hif_set_ce_service_max_yield_time(hif_ctx,
+				cfg_get(hdd_ctx->psoc,
+					CFG_DP_CE_SERVICE_MAX_YIELD_TIME));
+	ucfg_pmo_psoc_set_hif_handle(hdd_ctx->psoc, hif_ctx);
+	hif_set_ce_service_max_rx_ind_flush(hif_ctx,
+				cfg_get(hdd_ctx->psoc,
+					CFG_DP_CE_SERVICE_MAX_RX_IND_FLUSH));
+	return 0;
+
+mark_target_not_ready:
+	cds_set_target_ready(false);
+
+err_hif_close:
+	hdd_deinit_cds_hif_context();
+	hif_close(hif_ctx);
+	return ret;
+}
+
+void hdd_hif_close(struct hdd_context *hdd_ctx, void *hif_ctx)
+{
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx error");
+		return;
+	}
+
+	if (hif_ctx == NULL)
+		return;
+
+	cds_set_target_ready(false);
+	hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
+
+	hdd_napi_destroy(true);
+
+	hdd_deinit_cds_hif_context();
+	hif_close(hif_ctx);
+
+	ucfg_pmo_psoc_set_hif_handle(hdd_ctx->psoc, NULL);
+}
+
+/**
+ * hdd_init_qdf_ctx() - API to initialize global QDF Device structure
+ * @dev: Device Pointer
+ * @bdev: Bus Device pointer
+ * @bus_type: Underlying bus type
+ * @bid: Bus id passed by platform driver
+ *
+ * Return: 0 - success, < 0 - failure
+ */
+static int hdd_init_qdf_ctx(struct device *dev, void *bdev,
+			    enum qdf_bus_type bus_type,
+			    const struct hif_bus_id *bid)
+{
+	qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	if (!qdf_dev) {
+		hdd_err("Invalid QDF device");
+		return -EINVAL;
+	}
+
+	qdf_dev->dev = dev;
+	qdf_dev->drv_hdl = bdev;
+	qdf_dev->bus_type = bus_type;
+	qdf_dev->bid = bid;
+
+	if (cds_smmu_mem_map_setup(qdf_dev, ucfg_ipa_is_present()) !=
+		QDF_STATUS_SUCCESS) {
+		hdd_err("cds_smmu_mem_map_setup() failed");
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/**
+ * check_for_probe_defer() - API to check return value
+ * @ret: Return Value
+ *
+ * Return: return -EPROBE_DEFER to platform driver if return value
+ * is -ENOMEM. Platform driver will try to re-probe.
+ */
+#ifdef MODULE
+static int check_for_probe_defer(int ret)
+{
+	return ret;
+}
+#else
+static int check_for_probe_defer(int ret)
+{
+	if (ret == -ENOMEM)
+		return -EPROBE_DEFER;
+	return ret;
+}
+#endif
+
+static void hdd_soc_load_lock(struct device *dev, int load_op)
+{
+	mutex_lock(&hdd_init_deinit_lock);
+	hdd_start_driver_ops_timer(load_op);
+	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
+	hdd_request_pm_qos(dev, DISABLE_KRAIT_IDLE_PS_VAL);
+}
+
+static void hdd_soc_load_unlock(struct device *dev)
+{
+	hdd_remove_pm_qos(dev);
+	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
+	hdd_stop_driver_ops_timer();
+	mutex_unlock(&hdd_init_deinit_lock);
+}
+
+/**
+ * hdd_soc_probe() - perform SoC probe
+ * @dev: kernel device being probed
+ * @bdev: bus device structure
+ * @bid: bus identifier for shared busses
+ * @bus_type: underlying bus type
+ *
+ * A SoC probe indicates new SoC hardware has become available and needs to be
+ * initialized.
+ *
+ * Return: Errno
+ */
+static int hdd_soc_probe(struct device *dev,
+			 void *bdev,
+			 const struct hif_bus_id *bid,
+			 enum qdf_bus_type bus_type)
+{
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+	int errno;
+
+	hdd_info("probing driver");
+
+	hdd_soc_load_lock(dev, eHDD_DRV_OP_PROBE);
+	cds_set_load_in_progress(true);
+	cds_set_driver_in_bad_state(false);
+
+	errno = hdd_init_qdf_ctx(dev, bdev, bus_type, bid);
+	if (errno)
+		goto unlock;
+
+	errno = hdd_wlan_startup(dev, &hdd_ctx);
+	if (errno)
+		goto assert_fail_count;
+
+	status = hdd_psoc_create_vdevs(hdd_ctx);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		errno = qdf_status_to_os_return(status);
+		goto wlan_exit;
+	}
+
+	probe_fail_cnt = 0;
+	cds_set_driver_loaded(true);
+	hdd_start_complete(0);
+	cds_set_load_in_progress(false);
+
+	hdd_soc_load_unlock(dev);
+
+	return 0;
+
+wlan_exit:
+	hdd_wlan_exit(hdd_ctx);
+
+assert_fail_count:
+	probe_fail_cnt++;
+	hdd_err("consecutive probe failures:%u", probe_fail_cnt);
+	QDF_BUG(probe_fail_cnt < SSR_MAX_FAIL_CNT);
+
+unlock:
+	cds_set_load_in_progress(false);
+	hdd_soc_load_unlock(dev);
+
+	return check_for_probe_defer(errno);
+}
+
+/**
+ * hdd_soc_recovery_reinit() - perform PDR/SSR SoC reinit
+ * @dev: the kernel device being re-initialized
+ * @bdev: bus device structure
+ * @bid: bus identifier for shared busses
+ * @bus_type: underlying bus type
+ *
+ * When communication with firmware breaks down, a SoC recovery process kicks in
+ * with two phases: shutdown and reinit.
+ *
+ * SSR reinit is similar to a 'probe' but happens in response to an SSR
+ * shutdown. The idea is to re-initialize the SoC to as close to its old,
+ * pre-communications-breakdown configuration as possible. This is completely
+ * transparent from a userspace point of view.
+ *
+ * Return: Errno
+ */
+static int hdd_soc_recovery_reinit(struct device *dev,
+				   void *bdev,
+				   const struct hif_bus_id *bid,
+				   enum qdf_bus_type bus_type)
+{
+	int errno;
+
+	hdd_info("re-probing driver");
+
+	hdd_soc_load_lock(dev, eHDD_DRV_OP_REINIT);
+	cds_set_driver_in_bad_state(false);
+
+	errno = hdd_init_qdf_ctx(dev, bdev, bus_type, bid);
+	if (errno)
+		goto unlock;
+
+	errno = hdd_wlan_re_init();
+	if (errno) {
+		re_init_fail_cnt++;
+		goto assert_fail_count;
+	}
+
+	re_init_fail_cnt = 0;
+	cds_set_recovery_in_progress(false);
+
+	hdd_soc_load_unlock(dev);
+
+	return 0;
+
+assert_fail_count:
+	hdd_err("consecutive reinit failures:%u", re_init_fail_cnt);
+	QDF_BUG(re_init_fail_cnt < SSR_MAX_FAIL_CNT);
+
+unlock:
+	cds_set_driver_in_bad_state(true);
+	hdd_soc_load_unlock(dev);
+
+	return check_for_probe_defer(errno);
+}
+
+/**
+ * hdd_soc_remove() - perform SoC remove
+ * @dev: the kernel device being removed
+ *
+ * A SoC remove indicates the attached SoC hardware is about to go away and
+ * needs to be cleaned up.
+ *
+ * Return: void
+ */
+static void hdd_soc_remove(struct device *dev)
+{
+	pr_info("%s: Removing driver v%s\n", WLAN_MODULE_NAME,
+		QWLAN_VERSIONSTR);
+
+	cds_set_driver_loaded(false);
+	cds_set_unload_in_progress(true);
+
+	if (!cds_wait_for_external_threads_completion(__func__))
+		hdd_warn("External threads are still active attempting driver unload anyway");
+
+	if (!hdd_wait_for_debugfs_threads_completion())
+		hdd_warn("Debugfs threads are still active attempting driver unload anyway");
+
+	mutex_lock(&hdd_init_deinit_lock);
+	hdd_start_driver_ops_timer(eHDD_DRV_OP_REMOVE);
+	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
+		epping_disable();
+		epping_close();
+	} else {
+		struct hdd_context *hdd_ctx;
+
+		hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+		if (hdd_ctx)
+			hdd_wlan_exit(hdd_ctx);
+		else
+			hdd_err("invalid hdd context");
+
+	}
+	hdd_stop_driver_ops_timer();
+	mutex_unlock(&hdd_init_deinit_lock);
+
+	cds_set_driver_in_bad_state(false);
+	cds_set_unload_in_progress(false);
+
+	pr_info("%s: Driver De-initialized\n", WLAN_MODULE_NAME);
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * hdd_wlan_ssr_shutdown_event()- send ssr shutdown state
+ *
+ * This Function send send ssr shutdown state diag event
+ *
+ * Return: void.
+ */
+static void hdd_wlan_ssr_shutdown_event(void)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(ssr_shutdown,
+					struct host_event_wlan_ssr_shutdown);
+	qdf_mem_zero(&ssr_shutdown, sizeof(ssr_shutdown));
+	ssr_shutdown.status = SSR_SUB_SYSTEM_SHUTDOWN;
+	WLAN_HOST_DIAG_EVENT_REPORT(&ssr_shutdown,
+					EVENT_WLAN_SSR_SHUTDOWN_SUBSYSTEM);
+}
+#else
+static inline void hdd_wlan_ssr_shutdown_event(void) { }
+#endif
+
+/**
+ * hdd_send_hang_reason() - Send hang reason to the userspace
+ *
+ * Return: None
+ */
+static void hdd_send_hang_reason(void)
+{
+	enum qdf_hang_reason reason = QDF_REASON_UNSPECIFIED;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	cds_get_recovery_reason(&reason);
+	cds_reset_recovery_reason();
+	wlan_hdd_send_hang_reason_event(hdd_ctx, reason);
+}
+
+/**
+ * hdd_psoc_shutdown_notify() - notify the various interested parties that the
+ *	soc is starting recovery shutdown
+ * @hdd_ctx: the HDD context corresponding to the soc undergoing shutdown
+ *
+ * Return: None
+ */
+static void hdd_psoc_shutdown_notify(struct hdd_context *hdd_ctx)
+{
+	/* Notify external threads currently waiting on firmware by forcefully
+	 * completing waiting events with a "reset" status. This will cause the
+	 * event to fail early instead of timing out.
+	 */
+	qdf_complete_wait_events();
+
+	wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
+
+	if (ucfg_ipa_is_enabled()) {
+		ucfg_ipa_uc_force_pipe_shutdown(hdd_ctx->pdev);
+
+		if (pld_is_fw_rejuvenate(hdd_ctx->parent_dev))
+			ucfg_ipa_fw_rejuvenate_send_msg(hdd_ctx->pdev);
+	}
+
+	cds_shutdown_notifier_call();
+	cds_shutdown_notifier_purge();
+
+	hdd_wlan_ssr_shutdown_event();
+	hdd_send_hang_reason();
+}
+
+/**
+ * hdd_soc_recovery_shutdown() - perform PDR/SSR SoC shutdown
+ *
+ * When communication with firmware breaks down, a SoC recovery process kicks in
+ * with two phases: shutdown and reinit.
+ *
+ * SSR shutdown is similar to a 'remove' but without communication with
+ * firmware. The idea is to retain as much SoC configuration as possible, so it
+ * can be re-initialized to the same state after a reset. This is completely
+ * transparent from a userspace point of view.
+ *
+ * Return: void
+ */
+static void hdd_soc_recovery_shutdown(void)
+{
+	struct hdd_context *hdd_ctx;
+	void *hif_ctx;
+
+	/* recovery starts via firmware down indication; ensure we got one */
+	QDF_BUG(cds_is_driver_recovering());
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is null");
+		return;
+	}
+
+	/* cancel/flush any pending/active idle shutdown work */
+	hdd_psoc_idle_timer_stop(hdd_ctx);
+
+	/* nothing to do if the soc is already unloaded */
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
+		hdd_info("Driver modules are already closed");
+		return;
+	}
+
+	if (cds_is_load_or_unload_in_progress()) {
+		hdd_info("Load/unload in progress, ignore SSR shutdown");
+		return;
+	}
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	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);
+
+	hdd_psoc_shutdown_notify(hdd_ctx);
+
+	if (!cds_wait_for_external_threads_completion(__func__))
+		hdd_err("Host is not ready for SSR, attempting anyway");
+
+	if (!hdd_wait_for_debugfs_threads_completion())
+		hdd_err("Debufs threads are still pending, attempting SSR anyway");
+
+	if (!QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
+		hif_disable_isr(hif_ctx);
+		hdd_wlan_shutdown();
+	}
+}
+
+/**
+ * wlan_hdd_crash_shutdown() - wlan_hdd_crash_shutdown
+ *
+ * HDD crash shutdown function: This function is called by
+ * platform driver's crash shutdown routine
+ *
+ * Return: void
+ */
+static void wlan_hdd_crash_shutdown(void)
+{
+	QDF_STATUS ret;
+	WMA_HANDLE wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		hdd_err("wma_handle is null");
+		return;
+	}
+
+	/*
+	 * When kernel panic happen, if WiFi FW is still active
+	 * it may cause NOC errors/memory corruption, to avoid
+	 * this, inject a fw crash first.
+	 * send crash_inject to FW directly, because we are now
+	 * in an atomic context, and preempt has been disabled,
+	 * MCThread won't be scheduled at the moment, at the same
+	 * time, TargetFailure event wont't be received after inject
+	 * crash due to the same reason.
+	 */
+	ret = wma_crash_inject(wma_handle, RECOVERY_SIM_ASSERT, 0);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		hdd_err("Failed to send crash inject:%d", ret);
+		return;
+	}
+
+	hif_crash_shutdown(cds_get_context(QDF_MODULE_ID_HIF));
+}
+
+/**
+ * wlan_hdd_notify_handler() - wlan_hdd_notify_handler
+ *
+ * This function is called by the platform driver to notify the
+ * COEX
+ *
+ * @state: state
+ *
+ * Return: void
+ */
+static void wlan_hdd_notify_handler(int state)
+{
+	if (!QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
+		int ret;
+
+		ret = hdd_wlan_notify_modem_power_state(state);
+		if (ret < 0)
+			hdd_err("Fail to send notify");
+	}
+}
+
+static int hdd_to_pmo_interface_pause(enum wow_interface_pause hdd_pause,
+				      enum pmo_wow_interface_pause *pmo_pause)
+{
+	switch (hdd_pause) {
+	case WOW_INTERFACE_PAUSE_DEFAULT:
+		*pmo_pause = PMO_WOW_INTERFACE_PAUSE_DEFAULT;
+		break;
+	case WOW_INTERFACE_PAUSE_ENABLE:
+		*pmo_pause = PMO_WOW_INTERFACE_PAUSE_ENABLE;
+		break;
+	case WOW_INTERFACE_PAUSE_DISABLE:
+		*pmo_pause = PMO_WOW_INTERFACE_PAUSE_DISABLE;
+		break;
+	default:
+		hdd_err("Invalid interface pause: %d", hdd_pause);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int hdd_to_pmo_resume_trigger(enum wow_resume_trigger hdd_trigger,
+				     enum pmo_wow_resume_trigger *pmo_trigger)
+{
+	switch (hdd_trigger) {
+	case WOW_RESUME_TRIGGER_DEFAULT:
+		*pmo_trigger = PMO_WOW_RESUME_TRIGGER_DEFAULT;
+		break;
+	case WOW_RESUME_TRIGGER_HTC_WAKEUP:
+		*pmo_trigger = PMO_WOW_RESUME_TRIGGER_HTC_WAKEUP;
+		break;
+	case WOW_RESUME_TRIGGER_GPIO:
+		*pmo_trigger = PMO_WOW_RESUME_TRIGGER_GPIO;
+		break;
+	default:
+		hdd_err("Invalid resume trigger: %d", hdd_trigger);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+hdd_to_pmo_wow_enable_params(struct wow_enable_params *in_params,
+			     struct pmo_wow_enable_params *out_params)
+{
+	int err;
+
+	/* unit-test suspend */
+	out_params->is_unit_test = in_params->is_unit_test;
+
+	/* interface pause */
+	err = hdd_to_pmo_interface_pause(in_params->interface_pause,
+					 &out_params->interface_pause);
+	if (err)
+		return err;
+
+	/* resume trigger */
+	err = hdd_to_pmo_resume_trigger(in_params->resume_trigger,
+					&out_params->resume_trigger);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+/**
+ * __wlan_hdd_bus_suspend() - handles platform supsend
+ * @wow_params: collection of wow enable override parameters
+ *
+ * Does precondtion validation. Ensures that a subsystem restart isn't in
+ * progress. Ensures that no load or unload is in progress. Does:
+ *	data path suspend
+ *	component (pmo) suspend
+ *	hif (bus) suspend
+ *
+ * Return: 0 for success, -EFAULT for null pointers,
+ *     -EBUSY or -EAGAIN if another opperation is in progress and
+ *     wlan will not be ready to suspend in time.
+ */
+static int __wlan_hdd_bus_suspend(struct wow_enable_params wow_params)
+{
+	int err;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx;
+	void *hif_ctx;
+	void *dp_soc;
+	void *dp_pdev;
+	struct pmo_wow_enable_params pmo_params;
+
+	hdd_info("starting bus suspend");
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	err = wlan_hdd_validate_context(hdd_ctx);
+	if (err) {
+		hdd_err("Invalid hdd context: %d", err);
+		return err;
+	}
+
+	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+		hdd_debug("Driver Module closed; skipping suspend");
+		return 0;
+	}
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!hif_ctx) {
+		hdd_err("Failed to get hif context");
+		return -EINVAL;
+	}
+
+	err = hdd_to_pmo_wow_enable_params(&wow_params, &pmo_params);
+	if (err) {
+		hdd_err("Invalid WoW enable parameters: %d", err);
+		return err;
+	}
+
+	dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
+	dp_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	err = qdf_status_to_os_return(cdp_bus_suspend(dp_soc, dp_pdev));
+	if (err) {
+		hdd_err("Failed cdp bus suspend: %d", err);
+		return err;
+	}
+
+	err = hif_bus_early_suspend(hif_ctx);
+	if (err) {
+		hdd_err("Failed hif bus early suspend");
+		goto resume_cdp;
+	}
+
+	status = ucfg_pmo_psoc_bus_suspend_req(hdd_ctx->psoc,
+					       QDF_SYSTEM_SUSPEND,
+					       &pmo_params);
+	err = qdf_status_to_os_return(status);
+	if (err) {
+		hdd_err("Failed pmo bus suspend: %d", status);
+		goto late_hif_resume;
+	}
+
+	err = hif_bus_suspend(hif_ctx);
+	if (err) {
+		hdd_err("Failed hif bus suspend: %d", err);
+		goto resume_pmo;
+	}
+
+	hdd_info("bus suspend succeeded");
+	return 0;
+
+resume_pmo:
+	status = ucfg_pmo_psoc_bus_resume_req(hdd_ctx->psoc,
+					      QDF_SYSTEM_SUSPEND);
+	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+
+late_hif_resume:
+	status = hif_bus_late_resume(hif_ctx);
+	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+
+resume_cdp:
+	status = cdp_bus_resume(dp_soc, dp_pdev);
+	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+
+	return err;
+}
+
+int wlan_hdd_bus_suspend(void)
+{
+	int ret;
+	struct wow_enable_params default_params = {0};
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_bus_suspend(default_params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef WLAN_SUSPEND_RESUME_TEST
+int wlan_hdd_unit_test_bus_suspend(struct wow_enable_params wow_params)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_bus_suspend(wow_params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
+/**
+ * __wlan_hdd_bus_suspend_noirq() - handle .suspend_noirq callback
+ *
+ * This function is called by the platform driver to complete the
+ * bus suspend callback when device interrupts are disabled by kernel.
+ * Call HIF and WMA suspend_noirq callbacks to make sure there is no
+ * wake up pending from FW before allowing suspend.
+ *
+ * Return: 0 for success and -EBUSY if FW is requesting wake up
+ */
+static int __wlan_hdd_bus_suspend_noirq(void)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	void *hif_ctx;
+	int errno;
+	uint32_t pending_events;
+
+	hdd_info("start bus_suspend_noirq");
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno) {
+		hdd_err("Invalid HDD context: errno %d", errno);
+		return errno;
+	}
+
+	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+		hdd_debug("Driver module closed; skip bus-noirq suspend");
+		return 0;
+	}
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!hif_ctx) {
+		hdd_err("hif_ctx is null");
+		return -EINVAL;
+	}
+
+	errno = hif_bus_suspend_noirq(hif_ctx);
+	if (errno)
+		goto done;
+
+	errno = ucfg_pmo_psoc_is_target_wake_up_received(hdd_ctx->psoc);
+	if (errno == -EAGAIN) {
+		hdd_err("Firmware attempting wakeup, try again");
+		wlan_hdd_inc_suspend_stats(hdd_ctx,
+					   SUSPEND_FAIL_INITIAL_WAKEUP);
+	}
+	if (errno)
+		goto resume_hif_noirq;
+
+	pending_events = wma_critical_events_in_flight();
+	if (pending_events) {
+		hdd_err("%d critical event(s) in flight; try again",
+			pending_events);
+		errno = -EAGAIN;
+		goto resume_hif_noirq;
+	}
+
+	hdd_ctx->suspend_resume_stats.suspends++;
+
+	hdd_info("bus_suspend_noirq done");
+	return 0;
+
+resume_hif_noirq:
+	QDF_BUG(!hif_bus_resume_noirq(hif_ctx));
+
+done:
+	hdd_err("suspend_noirq failed, status: %d", errno);
+
+	return errno;
+}
+
+int wlan_hdd_bus_suspend_noirq(void)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_bus_suspend_noirq();
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_bus_resume() - handles platform resume
+ *
+ * Does precondtion validation. Ensures that a subsystem restart isn't in
+ * progress.  Ensures that no load or unload is in progress.  Ensures that
+ * it has valid pointers for the required contexts.
+ * Calls into hif to resume the bus opperation.
+ * Calls into wma to handshake with firmware and notify it that the bus is up.
+ * Calls into ol_txrx for symetry.
+ * Failures are treated as catastrophic.
+ *
+ * return: error code or 0 for success
+ */
+static int __wlan_hdd_bus_resume(void)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	void *hif_ctx;
+	int status;
+	QDF_STATUS qdf_status;
+	void *dp_soc;
+	void *dp_pdev;
+
+	if (cds_is_driver_recovering())
+		return 0;
+
+	hdd_info("starting bus resume");
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status) {
+		hdd_err("Invalid hdd context");
+		return status;
+	}
+
+	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+		hdd_debug("Driver Module closed; return success");
+		return 0;
+	}
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (NULL == hif_ctx) {
+		hdd_err("Failed to get hif context");
+		return -EINVAL;
+	}
+
+	status = hif_bus_resume(hif_ctx);
+	if (status) {
+		hdd_err("Failed hif bus resume");
+		goto out;
+	}
+
+	qdf_status = ucfg_pmo_psoc_bus_resume_req(hdd_ctx->psoc,
+						  QDF_SYSTEM_SUSPEND);
+	status = qdf_status_to_os_return(qdf_status);
+	if (status) {
+		hdd_err("Failed pmo bus resume");
+		goto out;
+	}
+
+	status = hif_bus_late_resume(hif_ctx);
+	if (status) {
+		hdd_err("Failed hif bus late resume");
+		goto out;
+	}
+
+	dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
+	dp_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	qdf_status = cdp_bus_resume(dp_soc, dp_pdev);
+	status = qdf_status_to_os_return(qdf_status);
+	if (status) {
+		hdd_err("Failed cdp bus resume");
+		goto out;
+	}
+
+	hdd_info("bus resume succeeded");
+	return 0;
+
+out:
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state() ||
+		cds_is_fw_down())
+		return 0;
+
+	QDF_BUG(false);
+
+	return status;
+}
+
+int wlan_hdd_bus_resume(void)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_bus_resume();
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_bus_resume_noirq(): handle bus resume no irq
+ *
+ * This function is called by the platform driver to do bus
+ * resume no IRQ before calling resume callback. Call WMA and HIF
+ * layers to complete the resume_noirq.
+ *
+ * Return: 0 for success and negative error code for failure
+ */
+static int __wlan_hdd_bus_resume_noirq(void)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	void *hif_ctx;
+	int status;
+	QDF_STATUS qdf_status;
+
+	hdd_info("starting bus_resume_noirq");
+	if (cds_is_driver_recovering())
+		return 0;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status) {
+		hdd_err("Invalid HDD context: %d", status);
+		return status;
+	}
+
+	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+		hdd_debug("Driver Module closed return success");
+		return 0;
+	}
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (NULL == hif_ctx)
+		return -EINVAL;
+
+	qdf_status = ucfg_pmo_psoc_clear_target_wake_up(hdd_ctx->psoc);
+	QDF_BUG(!qdf_status);
+
+	status = hif_bus_resume_noirq(hif_ctx);
+	QDF_BUG(!status);
+
+	hdd_info("bus_resume_noirq done");
+	return status;
+}
+
+int wlan_hdd_bus_resume_noirq(void)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_bus_resume_noirq();
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_bus_reset_resume() - resume wlan bus after reset
+ *
+ * This function is called to tell the driver that the device has been resumed
+ * and it has also been reset. The driver should redo any necessary
+ * initialization. It is mainly used by the USB bus
+ *
+ * Return: int 0 for success, non zero for failure
+ */
+static int wlan_hdd_bus_reset_resume(void)
+{
+	int ret;
+	struct hif_opaque_softc *scn = NULL;
+
+	scn = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!scn) {
+		hdd_err("Failed to get HIF context");
+		return -EFAULT;
+	}
+
+	cds_ssr_protect(__func__);
+	ret = hif_bus_reset_resume(scn);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * hdd_pld_runtime_suspend_cb() - Runtime suspend callback from PMO
+ *
+ * Return: 0 on success or error value otherwise
+ */
+static int hdd_pld_runtime_suspend_cb(void)
+{
+	qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	if (!qdf_dev) {
+		hdd_err("Invalid context");
+		return -EINVAL;
+	}
+
+	return pld_auto_suspend(qdf_dev->dev);
+}
+
+/**
+ * __wlan_hdd_runtime_suspend() - suspend the wlan bus without apps suspend
+ *
+ * Each layer is responsible for its own suspend actions.  wma_runtime_suspend
+ * takes care of the parts of the 802.11 suspend that we want to do for runtime
+ * suspend.
+ *
+ * Return: 0 or errno
+ */
+static int __wlan_hdd_runtime_suspend(struct device *dev)
+{
+	int err;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx;
+
+	hdd_debug("Starting runtime suspend");
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	err = wlan_hdd_validate_context(hdd_ctx);
+	if (err)
+		return err;
+
+	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+		hdd_debug("Driver module closed skipping runtime suspend");
+		return 0;
+	}
+
+	if (ucfg_scan_get_pdev_status(hdd_ctx->pdev) !=
+	    SCAN_NOT_IN_PROGRESS) {
+		hdd_debug("Scan in progress, ignore runtime suspend");
+		return -EBUSY;
+	}
+
+	status = ucfg_pmo_psoc_bus_runtime_suspend(hdd_ctx->psoc,
+						   hdd_pld_runtime_suspend_cb);
+	err = qdf_status_to_os_return(status);
+
+	hdd_debug("Runtime suspend done result: %d", err);
+
+	return err;
+}
+
+/**
+ * wlan_hdd_runtime_suspend() - suspend the wlan bus without apps suspend
+ *
+ * This function is called by the platform driver to suspend the
+ * wlan bus separately from system suspend
+ *
+ * Return: 0 or errno
+ */
+static int wlan_hdd_runtime_suspend(struct device *dev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_runtime_suspend(dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_pld_runtime_resume_cb() - Runtime resume callback from PMO
+ *
+ * Return: 0 on success or error value otherwise
+ */
+static int hdd_pld_runtime_resume_cb(void)
+{
+	qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	if (!qdf_dev) {
+		hdd_err("Invalid context");
+		return -EINVAL;
+	}
+
+	return pld_auto_resume(qdf_dev->dev);
+}
+
+/**
+ * __wlan_hdd_runtime_resume() - resume the wlan bus from runtime suspend
+ *
+ * Sets the runtime pm state and coordinates resume between hif wma and
+ * ol_txrx.
+ *
+ * Return: success since failure is a bug
+ */
+static int __wlan_hdd_runtime_resume(struct device *dev)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	QDF_STATUS status;
+
+	hdd_debug("Starting runtime resume");
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return 0;
+
+	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+		hdd_debug("Driver module closed skipping runtime resume");
+		return 0;
+	}
+
+	status = ucfg_pmo_psoc_bus_runtime_resume(hdd_ctx->psoc,
+						  hdd_pld_runtime_resume_cb);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_err("PMO Runtime resume failed: %d", status);
+
+	hdd_debug("Runtime resume done");
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_runtime_resume() - resume the wlan bus from runtime suspend
+ *
+ * This function is called by the platform driver to resume the
+ * wlan bus separately from system suspend
+ *
+ * Return: success since failure is a bug
+ */
+static int wlan_hdd_runtime_resume(struct device *dev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_runtime_resume(dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
+/**
+ * wlan_hdd_pld_probe() - probe function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ * @bdev: bus device structure
+ * @id: bus identifier for shared busses
+ *
+ * Return: 0 on success
+ */
+static int wlan_hdd_pld_probe(struct device *dev,
+			      enum pld_bus_type pld_bus_type,
+			      void *bdev,
+			      void *id)
+{
+	enum qdf_bus_type bus_type = to_bus_type(pld_bus_type);
+
+	if (bus_type == QDF_BUS_TYPE_NONE) {
+		hdd_err("Invalid bus type %d->%d", pld_bus_type, bus_type);
+		return -EINVAL;
+	}
+
+	return hdd_soc_probe(dev, bdev, id, bus_type);
+}
+
+/**
+ * wlan_hdd_pld_remove() - remove function registered to PLD
+ * @dev: device to remove
+ * @pld_bus_type: PLD bus type
+ *
+ * Return: void
+ */
+static void wlan_hdd_pld_remove(struct device *dev, enum pld_bus_type bus_type)
+{
+	hdd_enter();
+
+	hdd_soc_remove(dev);
+
+	hdd_exit();
+}
+
+/**
+ * wlan_hdd_pld_shutdown() - shutdown function registered to PLD
+ * @dev: device to shutdown
+ * @pld_bus_type: PLD bus type
+ *
+ * Return: void
+ */
+static void wlan_hdd_pld_shutdown(struct device *dev,
+				  enum pld_bus_type bus_type)
+{
+	hdd_enter();
+
+	mutex_lock(&hdd_init_deinit_lock);
+	hdd_start_driver_ops_timer(eHDD_DRV_OP_SHUTDOWN);
+
+	hdd_soc_recovery_shutdown();
+
+	hdd_stop_driver_ops_timer();
+	mutex_unlock(&hdd_init_deinit_lock);
+
+	hdd_exit();
+}
+
+/**
+ * wlan_hdd_pld_reinit() - reinit function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ * @bdev: bus device structure
+ * @id: bus identifier for shared busses
+ *
+ * Return: 0 on success
+ */
+static int wlan_hdd_pld_reinit(struct device *dev,
+			       enum pld_bus_type pld_bus_type,
+			       void *bdev,
+			       void *id)
+{
+	enum qdf_bus_type bus_type = to_bus_type(pld_bus_type);
+
+	if (bus_type == QDF_BUS_TYPE_NONE) {
+		hdd_err("Invalid bus type %d->%d", pld_bus_type, bus_type);
+		return -EINVAL;
+	}
+
+	return hdd_soc_recovery_reinit(dev, bdev, id, bus_type);
+}
+
+/**
+ * wlan_hdd_pld_crash_shutdown() - crash_shutdown function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ *
+ * Return: void
+ */
+static void wlan_hdd_pld_crash_shutdown(struct device *dev,
+			     enum pld_bus_type bus_type)
+{
+	wlan_hdd_crash_shutdown();
+}
+
+/**
+ * wlan_hdd_pld_suspend() - suspend function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ * @state: PM state
+ *
+ * Return: 0 on success
+ */
+static int wlan_hdd_pld_suspend(struct device *dev,
+				enum pld_bus_type bus_type,
+				pm_message_t state)
+
+{
+	return wlan_hdd_bus_suspend();
+}
+
+/**
+ * wlan_hdd_pld_resume() - resume function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ *
+ * Return: 0 on success
+ */
+static int wlan_hdd_pld_resume(struct device *dev,
+		    enum pld_bus_type bus_type)
+{
+	return wlan_hdd_bus_resume();
+}
+
+
+/**
+ * wlan_hdd_pld_suspend_noirq() - handle suspend no irq
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ *
+ * Complete the actions started by suspend().  Carry out any
+ * additional operations required for suspending the device that might be
+ * racing with its driver's interrupt handler, which is guaranteed not to
+ * run while suspend_noirq() is being executed. Make sure to resume device
+ * if FW has sent initial wake up message and expecting APPS to wake up.
+ *
+ * Return: 0 on success
+ */
+static int wlan_hdd_pld_suspend_noirq(struct device *dev,
+		     enum pld_bus_type bus_type)
+{
+	return wlan_hdd_bus_suspend_noirq();
+}
+
+/**
+ * wlan_hdd_pld_resume_noirq() - handle resume no irq
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ *
+ * Prepare for the execution of resume() by carrying out any
+ * operations required for resuming the device that might be racing with
+ * its driver's interrupt handler, which is guaranteed not to run while
+ * resume_noirq() is being executed. Make sure to clear target initial
+ * wake up request such that next suspend can happen cleanly.
+ *
+ * Return: 0 on success
+ */
+static int wlan_hdd_pld_resume_noirq(struct device *dev,
+		    enum pld_bus_type bus_type)
+{
+	return wlan_hdd_bus_resume_noirq();
+}
+
+/**
+ * wlan_hdd_pld_reset_resume() - reset resume function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ *
+ * Return: 0 on success
+ */
+static int wlan_hdd_pld_reset_resume(struct device *dev,
+		    enum pld_bus_type bus_type)
+{
+	return wlan_hdd_bus_reset_resume();
+}
+
+/**
+ * wlan_hdd_pld_notify_handler() - notify_handler function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ * @state: Modem power state
+ *
+ * Return: void
+ */
+static void wlan_hdd_pld_notify_handler(struct device *dev,
+			     enum pld_bus_type bus_type,
+			     int state)
+{
+	wlan_hdd_notify_handler(state);
+}
+
+/**
+ * wlan_hdd_pld_uevent() - platform uevent handler
+ * @dev: device on which the uevent occurred
+ * @event_data: uevent parameters
+ *
+ * Return: None
+ */
+static void
+wlan_hdd_pld_uevent(struct device *dev, struct pld_uevent_data *event_data)
+{
+	switch (event_data->uevent) {
+	case PLD_FW_DOWN:
+		hdd_info("Received firmware down indication");
+
+		/* NOTE! SSR cleanup logic goes in pld shutdown, not here */
+
+		cds_set_target_ready(false);
+		cds_set_recovery_in_progress(true);
+
+		/* SSR cleanup happens in pld shutdown, which is serialized by
+		 * the platform driver. Other operations are also serialized by
+		 * platform driver, such as probe, remove, and reinit. If the
+		 * firmware goes down during one of these operations, the driver
+		 * would normally have to wait for a timeout before shutdown
+		 * could begin. Instead, forcefully complete events waiting on
+		 * firmware with a "reset" status to avoid waiting to time out
+		 * on a firmware we already know is down.
+		 */
+		qdf_complete_wait_events();
+
+		break;
+	default:
+		/* other events intentionally not handled */
+		hdd_debug("Received uevent %d", event_data->uevent);
+		break;
+	}
+}
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * wlan_hdd_pld_runtime_suspend() - runtime suspend function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ *
+ * Return: 0 on success
+ */
+static int wlan_hdd_pld_runtime_suspend(struct device *dev,
+					enum pld_bus_type bus_type)
+{
+	return wlan_hdd_runtime_suspend(dev);
+}
+
+/**
+ * wlan_hdd_pld_runtime_resume() - runtime resume function registered to PLD
+ * @dev: device
+ * @pld_bus_type: PLD bus type
+ *
+ * Return: 0 on success
+ */
+static int wlan_hdd_pld_runtime_resume(struct device *dev,
+				       enum pld_bus_type bus_type)
+{
+	return wlan_hdd_runtime_resume(dev);
+}
+#endif
+
+struct pld_driver_ops wlan_drv_ops = {
+	.probe      = wlan_hdd_pld_probe,
+	.remove     = wlan_hdd_pld_remove,
+	.shutdown   = wlan_hdd_pld_shutdown,
+	.reinit     = wlan_hdd_pld_reinit,
+	.crash_shutdown = wlan_hdd_pld_crash_shutdown,
+	.suspend    = wlan_hdd_pld_suspend,
+	.resume     = wlan_hdd_pld_resume,
+	.suspend_noirq = wlan_hdd_pld_suspend_noirq,
+	.resume_noirq  = wlan_hdd_pld_resume_noirq,
+	.reset_resume = wlan_hdd_pld_reset_resume,
+	.modem_status = wlan_hdd_pld_notify_handler,
+	.uevent = wlan_hdd_pld_uevent,
+#ifdef FEATURE_RUNTIME_PM
+	.runtime_suspend = wlan_hdd_pld_runtime_suspend,
+	.runtime_resume = wlan_hdd_pld_runtime_resume,
+#endif
+};
+
+int wlan_hdd_register_driver(void)
+{
+	return pld_register_driver(&wlan_drv_ops);
+}
+
+void wlan_hdd_unregister_driver(void)
+{
+	pld_unregister_driver();
+}
diff --git a/core/hdd/src/wlan_hdd_ext_scan.c b/core/hdd/src/wlan_hdd_ext_scan.c
new file mode 100644
index 0000000..9a3e9d2
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_ext_scan.c
@@ -0,0 +1,4265 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_ext_scan.c
+ *
+ * WLAN Host Device Driver EXT SCAN feature implementation
+ *
+ */
+
+#ifdef FEATURE_WLAN_EXTSCAN
+
+#include "wlan_hdd_ext_scan.h"
+#include "wlan_hdd_regulatory.h"
+#include "cds_utils.h"
+#include "cds_sched.h"
+#include <qca_vendor.h>
+#include "wlan_extscan_ucfg_api.h"
+
+#define EXTSCAN_PARAM_MAX QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
+
+/* amount of time to wait for a synchronous request/response operation */
+#define WLAN_WAIT_TIME_EXTSCAN  1000
+
+/**
+ * struct hdd_ext_scan_context - hdd ext scan context
+ * @request_id: userspace-assigned ID associated with the request
+ * @response_event: Ext scan wait event
+ * @response_status: Status returned by FW in response to a request
+ * @ignore_cached_results: Flag to ignore cached results or not
+ * @context_lock: Spinlock to serialize all context accesses
+ * @capability_response: Ext scan capability response data from target
+ * @buckets_scanned: bitmask of buckets scanned in extscan cycle
+ */
+struct hdd_ext_scan_context {
+	uint32_t request_id;
+	int response_status;
+	bool ignore_cached_results;
+	struct completion response_event;
+	spinlock_t context_lock;
+	struct ext_scan_capabilities_response capability_response;
+	uint32_t buckets_scanned;
+};
+static struct hdd_ext_scan_context ext_scan_context;
+
+static const
+struct nla_policy wlan_hdd_extscan_config_policy[EXTSCAN_PARAM_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = {.type = NLA_U8},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = {.type = NLA_U8},
+
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = {.type = NLA_U8},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = {.type = NLA_U8},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] = {
+				.type = NLA_U8},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] = {
+				.type = NLA_U8},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] = {
+				.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] = {
+				.type = NLA_U8},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] = {
+				.type = NLA_U8},
+
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
+				.type = NLA_UNSPEC,
+				.len = QDF_MAC_ADDR_SIZE},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] = {
+				.type = NLA_S32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] = {
+				.type = NLA_S32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] = {
+				.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] = {
+				.type = NLA_BINARY,
+				.len = IEEE80211_MAX_SSID_LEN + 1 },
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] = {
+				.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] = {
+				.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] = {
+				.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] = {
+				.type = NLA_S32 },
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] = {
+				.type = NLA_S32 },
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] = {
+				.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] = {
+				.type = NLA_U32},
+};
+
+static const struct nla_policy
+wlan_hdd_pno_config_policy[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID] = {
+		.type = NLA_BINARY,
+		.len = IEEE80211_MAX_SSID_LEN + 1
+	},
+	[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS] = {
+		.type = NLA_U8
+	},
+	[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT] = {
+		.type = NLA_U8
+	},
+	[QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_PNO_CONFIG_REQUEST_ID] = {
+		.type = NLA_U32
+	},
+};
+
+static const struct nla_policy
+wlan_hdd_extscan_results_policy[QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD] = {
+				.type = NLA_U16},
+	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY] = {
+				.type = NLA_U16},
+};
+
+/**
+ * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
+ * @hdd_ctx: Pointer to hdd context
+ * @data: Pointer to ext scan capabilities response from fw
+ *
+ * Return: None
+ */
+static void
+wlan_hdd_cfg80211_extscan_get_capabilities_rsp(struct hdd_context *hdd_ctx,
+	struct ext_scan_capabilities_response *data)
+{
+	struct hdd_ext_scan_context *context;
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+	if (!data) {
+		hdd_err("data is null");
+		return;
+	}
+
+	context = &ext_scan_context;
+
+	spin_lock(&context->context_lock);
+	/* validate response received from target*/
+	if (context->request_id != data->requestId) {
+		spin_unlock(&context->context_lock);
+		hdd_err("Target response id did not match. request_id: %d response_id: %d",
+			context->request_id, data->requestId);
+		return;
+	}
+
+	context->capability_response = *data;
+	complete(&context->response_event);
+	spin_unlock(&context->context_lock);
+}
+
+/*
+ * define short names for the global vendor params
+ * used by hdd_extscan_nl_fill_bss()
+ */
+#define PARAM_TIME_STAMP \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
+#define PARAM_SSID \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID
+#define PARAM_BSSID \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID
+#define PARAM_CHANNEL \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL
+#define PARAM_RSSI \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI
+#define PARAM_RTT \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT
+#define PARAM_RTT_SD \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD
+#define PARAM_BEACON_PERIOD \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD
+#define PARAM_CAPABILITY \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY
+#define PARAM_IE_LENGTH \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH
+#define PARAM_IE_DATA \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA
+
+/** hdd_extscan_nl_fill_bss() - extscan nl fill bss
+ * @skb: socket buffer
+ * @ap: bss information
+ * @idx: nesting index
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int hdd_extscan_nl_fill_bss(struct sk_buff *skb, tSirWifiScanResult *ap,
+					int idx)
+{
+	struct nlattr *nla_ap;
+
+	nla_ap = nla_nest_start(skb, idx);
+	if (!nla_ap)
+		return -EINVAL;
+
+	if (hdd_wlan_nla_put_u64(skb, PARAM_TIME_STAMP, ap->ts) ||
+	    nla_put(skb, PARAM_SSID, sizeof(ap->ssid), ap->ssid) ||
+	    nla_put(skb, PARAM_BSSID, sizeof(ap->bssid), ap->bssid.bytes) ||
+	    nla_put_u32(skb, PARAM_CHANNEL, ap->channel) ||
+	    nla_put_s32(skb, PARAM_RSSI, ap->rssi) ||
+	    nla_put_u32(skb, PARAM_RTT, ap->rtt) ||
+	    nla_put_u32(skb, PARAM_RTT_SD, ap->rtt_sd) ||
+	    nla_put_u16(skb, PARAM_BEACON_PERIOD, ap->beaconPeriod) ||
+	    nla_put_u16(skb, PARAM_CAPABILITY, ap->capability) ||
+	    nla_put_u16(skb, PARAM_IE_LENGTH, ap->ieLength)) {
+		hdd_err("put fail");
+		return -EINVAL;
+	}
+
+	if (ap->ieLength)
+		if (nla_put(skb, PARAM_IE_DATA, ap->ieLength, ap->ieData)) {
+			hdd_err("put fail");
+			return -EINVAL;
+		}
+
+	nla_nest_end(skb, nla_ap);
+
+	return 0;
+}
+/*
+ * done with short names for the global vendor params
+ * used by hdd_extscan_nl_fill_bss()
+ */
+#undef PARAM_TIME_STAMP
+#undef PARAM_SSID
+#undef PARAM_BSSID
+#undef PARAM_CHANNEL
+#undef PARAM_RSSI
+#undef PARAM_RTT
+#undef PARAM_RTT_SD
+#undef PARAM_BEACON_PERIOD
+#undef PARAM_CAPABILITY
+#undef PARAM_IE_LENGTH
+#undef PARAM_IE_DATA
+
+/**
+ * wlan_hdd_cfg80211_extscan_cached_results_ind() - get cached results
+ * @hdd_ctx: hdd global context
+ * @data: cached results
+ *
+ * This function reads the cached results %data, populated the NL
+ * attributes and sends the NL event to the upper layer.
+ *
+ * Return: none
+ */
+static void
+wlan_hdd_cfg80211_extscan_cached_results_ind(struct hdd_context *hdd_ctx,
+				struct extscan_cached_scan_results *data)
+{
+	struct sk_buff *skb = NULL;
+	struct hdd_ext_scan_context *context;
+	struct extscan_cached_scan_result *result;
+	tSirWifiScanResult *ap;
+	uint32_t i, j, nl_buf_len;
+	bool ignore_cached_results = false;
+
+	/* ENTER() intentionally not used in a frequently invoked API */
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+	if (!data) {
+		hdd_err("data is null");
+		return;
+	}
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	ignore_cached_results = context->ignore_cached_results;
+	spin_unlock(&context->context_lock);
+
+	if (ignore_cached_results) {
+		hdd_err("Ignore the cached results received after timeout");
+		return;
+	}
+
+#define EXTSCAN_CACHED_NEST_HDRLEN NLA_HDRLEN
+#define EXTSCAN_CACHED_NL_FIXED_TLV \
+		((sizeof(data->request_id) + NLA_HDRLEN) + \
+		(sizeof(data->num_scan_ids) + NLA_HDRLEN) + \
+		(sizeof(data->more_data) + NLA_HDRLEN))
+#define EXTSCAN_CACHED_NL_SCAN_ID_TLV \
+		((sizeof(result->scan_id) + NLA_HDRLEN) + \
+		(sizeof(result->flags) + NLA_HDRLEN) + \
+		(sizeof(result->num_results) + NLA_HDRLEN))+ \
+		(sizeof(result->buckets_scanned) + NLA_HDRLEN)
+#define EXTSCAN_CACHED_NL_SCAN_RESULTS_TLV \
+		((sizeof(ap->ts) + NLA_HDRLEN) + \
+		(sizeof(ap->ssid) + NLA_HDRLEN) + \
+		(sizeof(ap->bssid) + NLA_HDRLEN) + \
+		(sizeof(ap->channel) + NLA_HDRLEN) + \
+		(sizeof(ap->rssi) + NLA_HDRLEN) + \
+		(sizeof(ap->rtt) + NLA_HDRLEN) + \
+		(sizeof(ap->rtt_sd) + NLA_HDRLEN) + \
+		(sizeof(ap->beaconPeriod) + NLA_HDRLEN) + \
+		(sizeof(ap->capability) + NLA_HDRLEN) + \
+		(sizeof(ap->ieLength) + NLA_HDRLEN))
+#define EXTSCAN_CACHED_NL_SCAN_RESULTS_IE_DATA_TLV \
+		(ap->ieLength + NLA_HDRLEN)
+
+	nl_buf_len = NLMSG_HDRLEN;
+	nl_buf_len += EXTSCAN_CACHED_NL_FIXED_TLV;
+	if (data->num_scan_ids) {
+		nl_buf_len += sizeof(result->scan_id) + NLA_HDRLEN;
+		nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;
+		result = &data->result[0];
+		for (i = 0; i < data->num_scan_ids; i++) {
+			nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;
+			nl_buf_len += EXTSCAN_CACHED_NL_SCAN_ID_TLV;
+			nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;
+
+			ap = &result->ap[0];
+			for (j = 0; j < result->num_results; j++) {
+				nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;
+				nl_buf_len +=
+					EXTSCAN_CACHED_NL_SCAN_RESULTS_TLV;
+				if (ap->ieLength)
+					nl_buf_len +=
+					EXTSCAN_CACHED_NL_SCAN_RESULTS_IE_DATA_TLV;
+				ap++;
+			}
+			result++;
+		}
+	}
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		goto fail;
+	}
+	hdd_debug("Req Id %u Num_scan_ids %u More Data %u",
+		data->request_id, data->num_scan_ids, data->more_data);
+
+	result = &data->result[0];
+	for (i = 0; i < data->num_scan_ids; i++) {
+		hdd_debug("[i=%d] scan_id %u flags %u num_results %u buckets scanned %u",
+			i, result->scan_id, result->flags, result->num_results,
+			result->buckets_scanned);
+
+		ap = &result->ap[0];
+		for (j = 0; j < result->num_results; j++) {
+			/*
+			 * Firmware returns timestamp from ext scan start till
+			 * BSSID was cached (in micro seconds). Add this with
+			 * time gap between system boot up to ext scan start
+			 * to derive the time since boot when the
+			 * BSSID was cached.
+			 */
+			ap->ts += hdd_ctx->ext_scan_start_since_boot;
+			hdd_debug("Timestamp %llu "
+				"Ssid: %s "
+				"Bssid (" MAC_ADDRESS_STR ") "
+				"Channel %u "
+				"Rssi %d "
+				"RTT %u "
+				"RTT_SD %u "
+				"Beacon Period %u "
+				"Capability 0x%x "
+				"Ie length %d",
+				ap->ts,
+				ap->ssid,
+				MAC_ADDR_ARRAY(ap->bssid.bytes),
+				ap->channel,
+				ap->rssi,
+				ap->rtt,
+				ap->rtt_sd,
+				ap->beaconPeriod,
+				ap->capability,
+				ap->ieLength);
+			ap++;
+		}
+		result++;
+	}
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
+		data->request_id) ||
+	    nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
+		data->num_scan_ids) ||
+	    nla_put_u8(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
+		data->more_data)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+
+	if (data->num_scan_ids) {
+		struct nlattr *nla_results;
+
+		result = &data->result[0];
+
+		if (nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
+			result->scan_id)) {
+			hdd_err("put fail");
+			goto fail;
+		}
+		nla_results = nla_nest_start(skb,
+			      QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
+		if (!nla_results)
+			goto fail;
+
+		for (i = 0; i < data->num_scan_ids; i++) {
+			struct nlattr *nla_result;
+			struct nlattr *nla_aps;
+
+			nla_result = nla_nest_start(skb, i);
+			if (!nla_result)
+				goto fail;
+
+			if (nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
+				result->scan_id) ||
+			    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
+				result->flags) ||
+			    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_BUCKETS_SCANNED,
+				result->buckets_scanned) ||
+			    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
+				result->num_results)) {
+				hdd_err("put fail");
+				goto fail;
+			}
+
+			nla_aps = nla_nest_start(skb,
+				     QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
+			if (!nla_aps)
+				goto fail;
+
+			ap = &result->ap[0];
+			for (j = 0; j < result->num_results; j++) {
+				if (hdd_extscan_nl_fill_bss(skb, ap, j))
+					goto fail;
+
+				ap++;
+			}
+			nla_nest_end(skb, nla_aps);
+			nla_nest_end(skb, nla_result);
+			result++;
+		}
+		nla_nest_end(skb, nla_results);
+	}
+
+	cfg80211_vendor_cmd_reply(skb);
+
+	if (!data->more_data) {
+		spin_lock(&context->context_lock);
+		context->response_status = 0;
+		complete(&context->response_event);
+		spin_unlock(&context->context_lock);
+	}
+	return;
+
+fail:
+	if (skb)
+		kfree_skb(skb);
+
+	spin_lock(&context->context_lock);
+	context->response_status = -EINVAL;
+	spin_unlock(&context->context_lock);
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_hotlist_match_ind() - hot list match ind
+ * @hdd_ctx: Pointer to hdd context
+ * @data: Pointer to ext scan result event
+ *
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
+ * Return: none
+ */
+static void
+wlan_hdd_cfg80211_extscan_hotlist_match_ind(struct hdd_context *hdd_ctx,
+					    struct extscan_hotlist_match *data)
+{
+	struct sk_buff *skb = NULL;
+	uint32_t i, index;
+	int flags = cds_get_gfp_flags();
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+	if (!data) {
+		hdd_err("data is null");
+		return;
+	}
+
+	if (data->ap_found)
+		index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
+	else
+		index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
+
+	skb = cfg80211_vendor_event_alloc(
+		  hdd_ctx->wiphy,
+		  NULL,
+		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
+		  index, flags);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+	hdd_debug("Req Id: %u Num_APs: %u MoreData: %u ap_found: %u",
+			data->requestId, data->numOfAps, data->moreData,
+			data->ap_found);
+
+	for (i = 0; i < data->numOfAps; i++) {
+		data->ap[i].ts = qdf_get_monotonic_boottime();
+
+		hdd_debug("[i=%d] Timestamp %llu "
+		       "Ssid: %s "
+		       "Bssid (" MAC_ADDRESS_STR ") "
+		       "Channel %u "
+		       "Rssi %d "
+		       "RTT %u "
+		       "RTT_SD %u",
+		       i,
+		       data->ap[i].ts,
+		       data->ap[i].ssid,
+		       MAC_ADDR_ARRAY(data->ap[i].bssid.bytes),
+		       data->ap[i].channel,
+		       data->ap[i].rssi,
+		       data->ap[i].rtt, data->ap[i].rtt_sd);
+	}
+
+	if (nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
+		data->requestId) ||
+	    nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
+		data->numOfAps)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+
+	if (data->numOfAps) {
+		struct nlattr *aps;
+
+		aps = nla_nest_start(skb,
+			       QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
+		if (!aps)
+			goto fail;
+
+		for (i = 0; i < data->numOfAps; i++) {
+			struct nlattr *ap;
+
+			ap = nla_nest_start(skb, i);
+			if (!ap)
+				goto fail;
+
+			if (hdd_wlan_nla_put_u64(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
+				data->ap[i].ts) ||
+			    nla_put(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
+				sizeof(data->ap[i].ssid),
+				data->ap[i].ssid) ||
+			    nla_put(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
+				sizeof(data->ap[i].bssid),
+				data->ap[i].bssid.bytes) ||
+			    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
+				data->ap[i].channel) ||
+			    nla_put_s32(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
+				data->ap[i].rssi) ||
+			    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
+				data->ap[i].rtt) ||
+			    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
+				data->ap[i].rtt_sd))
+				goto fail;
+
+			nla_nest_end(skb, ap);
+		}
+		nla_nest_end(skb, aps);
+
+		if (nla_put_u8(skb,
+		       QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
+		       data->moreData))
+			goto fail;
+	}
+
+	cfg80211_vendor_event(skb, flags);
+	hdd_exit();
+	return;
+
+fail:
+	kfree_skb(skb);
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind() -
+ *	significant wifi change results indication
+ * @hdd_ctx: Pointer to hdd context
+ * @data: Pointer to signif wifi change event
+ *
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
+ * Return: none
+ */
+static void
+wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(
+			struct hdd_context *hdd_ctx,
+			tpSirWifiSignificantChangeEvent data)
+{
+	struct sk_buff *skb = NULL;
+	tSirWifiSignificantChange *ap_info;
+	int32_t *rssi;
+	uint32_t i, j;
+	int flags = cds_get_gfp_flags();
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+	if (!data) {
+		hdd_err("data is null");
+		return;
+	}
+
+	skb = cfg80211_vendor_event_alloc(
+		hdd_ctx->wiphy,
+		NULL,
+		EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
+		QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
+		flags);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+	hdd_debug("Req Id %u Num results %u More Data %u",
+		data->requestId, data->numResults, data->moreData);
+
+	ap_info = &data->ap[0];
+	for (i = 0; i < data->numResults; i++) {
+		hdd_debug("[i=%d] "
+		       "Bssid (" MAC_ADDRESS_STR ") "
+		       "Channel %u "
+		       "numOfRssi %d",
+		       i,
+		       MAC_ADDR_ARRAY(ap_info->bssid.bytes),
+		       ap_info->channel, ap_info->numOfRssi);
+		rssi = &(ap_info)->rssi[0];
+		for (j = 0; j < ap_info->numOfRssi; j++)
+			hdd_debug("Rssi %d", *rssi++);
+
+		ap_info = (tSirWifiSignificantChange *)((char *)ap_info +
+				ap_info->numOfRssi * sizeof(*rssi) +
+				sizeof(*ap_info));
+	}
+
+	if (nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
+		data->requestId) ||
+	    nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
+		data->numResults)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+
+	if (data->numResults) {
+		struct nlattr *aps;
+
+		aps = nla_nest_start(skb,
+			       QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
+		if (!aps)
+			goto fail;
+
+		ap_info = &data->ap[0];
+		for (i = 0; i < data->numResults; i++) {
+			struct nlattr *ap;
+
+			ap = nla_nest_start(skb, i);
+			if (!ap)
+				goto fail;
+
+			if (nla_put(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
+				QDF_MAC_ADDR_SIZE, ap_info->bssid.bytes) ||
+			    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
+				ap_info->channel) ||
+			    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
+				ap_info->numOfRssi) ||
+			    nla_put(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
+				sizeof(s32) * ap_info->numOfRssi,
+				&(ap_info)->rssi[0]))
+				goto fail;
+
+			nla_nest_end(skb, ap);
+
+			ap_info = (tSirWifiSignificantChange *)((char *)ap_info
+					+ ap_info->numOfRssi * sizeof(*rssi) +
+					sizeof(*ap_info));
+		}
+		nla_nest_end(skb, aps);
+
+		if (nla_put_u8(skb,
+		     QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
+		     data->moreData))
+			goto fail;
+	}
+
+	cfg80211_vendor_event(skb, flags);
+	return;
+
+fail:
+	kfree_skb(skb);
+	return;
+
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_full_scan_result_event() - full scan result event
+ * @hdd_ctx: Pointer to hdd context
+ * @data: Pointer to full scan result event
+ *
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
+ * Return: none
+ */
+static void
+wlan_hdd_cfg80211_extscan_full_scan_result_event(struct hdd_context *hdd_ctx,
+						 tpSirWifiFullScanResultEvent
+						 data)
+{
+	struct sk_buff *skb;
+	struct timespec ts;
+	struct hdd_ext_scan_context *context;
+
+	int flags = cds_get_gfp_flags();
+
+	/* ENTER() intentionally not used in a frequently invoked API */
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+	if (!data) {
+		hdd_err("data is null");
+		return;
+	}
+
+	if ((sizeof(*data) + data->ap.ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
+		hdd_err("Frame exceeded NL size limitation, drop it!!");
+		return;
+	}
+	skb = cfg80211_vendor_event_alloc(
+		  hdd_ctx->wiphy,
+		  NULL,
+		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
+		  QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
+		  flags);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	data->ap.channel = cds_chan_to_freq(data->ap.channel);
+
+	/*
+	 * Android does not want the time stamp from the frame.
+	 * Instead it wants a monotonic increasing value since boot
+	 */
+	get_monotonic_boottime(&ts);
+	data->ap.ts = ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
+
+	hdd_debug("Req Id %u More Data %u", data->requestId,
+		  data->moreData);
+	hdd_debug("AP Info: Timestamp %llu Ssid: %s "
+	       "Bssid (" MAC_ADDRESS_STR ") "
+	       "Channel %u "
+	       "Rssi %d "
+	       "RTT %u "
+	       "RTT_SD %u "
+	       "Bcn Period %d "
+	       "Capability 0x%X "
+	       "IE Length %d",
+	       data->ap.ts,
+	       data->ap.ssid,
+	       MAC_ADDR_ARRAY(data->ap.bssid.bytes),
+	       data->ap.channel,
+	       data->ap.rssi,
+	       data->ap.rtt,
+	       data->ap.rtt_sd,
+	       data->ap.beaconPeriod,
+	       data->ap.capability, data->ap.ieLength);
+
+	if (nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
+		data->requestId) ||
+	    hdd_wlan_nla_put_u64(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
+		data->ap.ts) ||
+	    nla_put(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
+		sizeof(data->ap.ssid),
+		data->ap.ssid) ||
+	    nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
+		sizeof(data->ap.bssid),
+		data->ap.bssid.bytes) ||
+	    nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
+		data->ap.channel) ||
+	    nla_put_s32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
+		data->ap.rssi) ||
+	    nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
+		data->ap.rtt) ||
+	    nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
+		data->ap.rtt_sd) ||
+	    nla_put_u16(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
+		data->ap.beaconPeriod) ||
+	    nla_put_u16(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
+		data->ap.capability) ||
+	    nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
+		data->ap.ieLength) ||
+	    nla_put_u8(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
+		data->moreData)) {
+		hdd_err("nla put fail");
+		goto nla_put_failure;
+	}
+
+	if (data->ap.ieLength) {
+		if (nla_put(skb,
+		    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
+		    data->ap.ieLength, data->ap.ieData))
+			goto nla_put_failure;
+	}
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	if (nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_BUCKETS_SCANNED,
+		context->buckets_scanned)) {
+		spin_unlock(&context->context_lock);
+		hdd_debug("Failed to include buckets_scanned");
+		goto nla_put_failure;
+	}
+	spin_unlock(&context->context_lock);
+
+	cfg80211_vendor_event(skb, flags);
+	return;
+
+nla_put_failure:
+	kfree_skb(skb);
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_scan_res_available_event() - scan result event
+ * @hdd_ctx: Pointer to hdd context
+ * @data: Pointer to scan results available indication param
+ *
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
+ * Return: none
+ */
+static void
+wlan_hdd_cfg80211_extscan_scan_res_available_event(
+			struct hdd_context *hdd_ctx,
+			tpSirExtScanResultsAvailableIndParams data)
+{
+	struct sk_buff *skb;
+	int flags = cds_get_gfp_flags();
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+	if (!data) {
+		hdd_err("data is null");
+		return;
+	}
+
+	skb = cfg80211_vendor_event_alloc(
+		 hdd_ctx->wiphy,
+		 NULL,
+		 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
+		 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
+		 flags);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	hdd_debug("Req Id %u Num results %u",
+	       data->requestId, data->numResultsAvailable);
+	if (nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
+		data->requestId) ||
+	    nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
+		data->numResultsAvailable)) {
+		hdd_err("nla put fail");
+		goto nla_put_failure;
+	}
+
+	cfg80211_vendor_event(skb, flags);
+	hdd_exit();
+	return;
+
+nla_put_failure:
+	kfree_skb(skb);
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_scan_progress_event() - scan progress event
+ * @hdd_ctx: Pointer to hdd context
+ * @data: Pointer to scan event indication param
+ *
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
+ * Return: none
+ */
+static void
+wlan_hdd_cfg80211_extscan_scan_progress_event(struct hdd_context *hdd_ctx,
+					      tpSirExtScanOnScanEventIndParams
+					      data)
+{
+	struct sk_buff *skb;
+	int flags = cds_get_gfp_flags();
+	struct hdd_ext_scan_context *context;
+
+	/* ENTER() intentionally not used in a frequently invoked API */
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+	if (!data) {
+		hdd_err("data is null");
+		return;
+	}
+
+	skb = cfg80211_vendor_event_alloc(
+			hdd_ctx->wiphy,
+			NULL,
+			EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
+			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
+			flags);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	hdd_debug("Request Id: %u Scan event type: %u Scan event status: %u buckets scanned: %u",
+		  data->requestId, data->scanEventType, data->status,
+		  data->buckets_scanned);
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	if (data->scanEventType == WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT) {
+		context->buckets_scanned = 0;
+		data->scanEventType = WIFI_EXTSCAN_RESULTS_AVAILABLE;
+		spin_unlock(&context->context_lock);
+	} else if (data->scanEventType == WIFI_EXTSCAN_CYCLE_STARTED_EVENT) {
+		context->buckets_scanned = data->buckets_scanned;
+		/* No need to report to user space */
+		spin_unlock(&context->context_lock);
+		goto nla_put_failure;
+	} else {
+		spin_unlock(&context->context_lock);
+	}
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
+			data->requestId) ||
+	    nla_put_u8(skb,
+		       QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
+		       data->scanEventType)) {
+		hdd_err("nla put fail");
+		goto nla_put_failure;
+	}
+
+	cfg80211_vendor_event(skb, flags);
+	return;
+
+nla_put_failure:
+	kfree_skb(skb);
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_epno_match_found() - pno match found
+ * @hdd_ctx: HDD context
+ * @data: matched network data
+ *
+ * This function reads the matched network data and fills NL vendor attributes
+ * and send it to upper layer.
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static void
+wlan_hdd_cfg80211_extscan_epno_match_found(struct hdd_context *hdd_ctx,
+					   struct pno_match_found *data)
+{
+	struct sk_buff *skb;
+	uint32_t len, i;
+	int flags = cds_get_gfp_flags();
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+	if (!data) {
+		hdd_err("data is null");
+		return;
+	}
+
+	/*
+	 * If the number of match found APs including IE data exceeds NL 4K size
+	 * limitation, drop that beacon/probe rsp frame.
+	 */
+	len = sizeof(*data) +
+			(data->num_results + sizeof(tSirWifiScanResult));
+	for (i = 0; i < data->num_results; i++)
+		len += data->ap[i].ieLength;
+
+	if (len >= EXTSCAN_EVENT_BUF_SIZE) {
+		hdd_err("Frame exceeded NL size limitation, drop it!");
+		return;
+	}
+
+	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+		  NULL,
+		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
+		QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_NETWORK_FOUND_INDEX,
+		  flags);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	hdd_debug("Req Id %u More Data %u num_results %d",
+		data->request_id, data->more_data, data->num_results);
+	for (i = 0; i < data->num_results; i++) {
+		data->ap[i].channel = cds_chan_to_freq(data->ap[i].channel);
+		hdd_debug("AP Info: Timestamp %llu) Ssid: %s "
+					"Bssid (" MAC_ADDRESS_STR ") "
+					"Channel %u "
+					"Rssi %d "
+					"RTT %u "
+					"RTT_SD %u "
+					"Bcn Period %d "
+					"Capability 0x%X "
+					"IE Length %d",
+					data->ap[i].ts,
+					data->ap[i].ssid,
+					MAC_ADDR_ARRAY(data->ap[i].bssid.bytes),
+					data->ap[i].channel,
+					data->ap[i].rssi,
+					data->ap[i].rtt,
+					data->ap[i].rtt_sd,
+					data->ap[i].beaconPeriod,
+					data->ap[i].capability,
+					data->ap[i].ieLength);
+	}
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
+		data->request_id) ||
+	    nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
+		data->num_results) ||
+	    nla_put_u8(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
+		data->more_data)) {
+		hdd_err("nla put fail");
+		goto fail;
+	}
+
+	if (data->num_results) {
+		struct nlattr *nla_aps;
+
+		nla_aps = nla_nest_start(skb,
+			QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
+		if (!nla_aps)
+			goto fail;
+
+		for (i = 0; i < data->num_results; i++) {
+			if (hdd_extscan_nl_fill_bss(skb, &data->ap[i], i))
+				goto fail;
+		}
+		nla_nest_end(skb, nla_aps);
+	}
+
+	cfg80211_vendor_event(skb, flags);
+	return;
+
+fail:
+	kfree_skb(skb);
+}
+
+/**
+ * wlan_hdd_cfg80211_passpoint_match_found() - passpoint match found
+ * @hddctx: HDD context
+ * @data: matched network data
+ *
+ * This function reads the match network %data and fill in the skb with
+ * NL attributes and send up the NL event
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
+ * Return: none
+ */
+static void
+wlan_hdd_cfg80211_passpoint_match_found(void *ctx,
+					struct wifi_passpoint_match *data)
+{
+	struct hdd_context *hdd_ctx  = ctx;
+	struct sk_buff *skb     = NULL;
+	uint32_t len, i, num_matches = 1, more_data = 0;
+	struct nlattr *nla_aps, *nla_bss;
+	int flags = cds_get_gfp_flags();
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+	if (!data) {
+		hdd_err("data is null");
+		return;
+	}
+
+	len = sizeof(*data) + data->ap.ieLength + data->anqp_len;
+	if (len >= EXTSCAN_EVENT_BUF_SIZE) {
+		hdd_err("Result exceeded NL size limitation, drop it");
+		return;
+	}
+
+	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+		  NULL,
+		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
+		  QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_PASSPOINT_NETWORK_FOUND_INDEX,
+		  flags);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	hdd_debug("Req Id %u Id %u ANQP length %u num_matches %u",
+		data->request_id, data->id, data->anqp_len, num_matches);
+	for (i = 0; i < num_matches; i++) {
+		hdd_debug("AP Info: Timestamp %llu Ssid: %s "
+					"Bssid (" MAC_ADDRESS_STR ") "
+					"Channel %u "
+					"Rssi %d "
+					"RTT %u "
+					"RTT_SD %u "
+					"Bcn Period %d "
+					"Capability 0x%X "
+					"IE Length %d",
+					data->ap.ts,
+					data->ap.ssid,
+					MAC_ADDR_ARRAY(data->ap.bssid.bytes),
+					data->ap.channel,
+					data->ap.rssi,
+					data->ap.rtt,
+					data->ap.rtt_sd,
+					data->ap.beaconPeriod,
+					data->ap.capability,
+					data->ap.ieLength);
+	}
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
+		data->request_id) ||
+	    nla_put_u32(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_NETWORK_FOUND_NUM_MATCHES,
+		num_matches) ||
+	    nla_put_u8(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
+		more_data)) {
+		hdd_err("nla put fail");
+		goto fail;
+	}
+
+	nla_aps = nla_nest_start(skb,
+		QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_RESULT_LIST);
+	if (!nla_aps)
+		goto fail;
+
+	for (i = 0; i < num_matches; i++) {
+		struct nlattr *nla_ap;
+
+		nla_ap = nla_nest_start(skb, i);
+		if (!nla_ap)
+			goto fail;
+
+		if (nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID,
+			data->id) ||
+		    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN,
+			data->anqp_len)) {
+			goto fail;
+		}
+
+		if (data->anqp_len)
+			if (nla_put(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP,
+				data->anqp_len, data->anqp))
+				goto fail;
+
+		nla_bss = nla_nest_start(skb,
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
+		if (!nla_bss)
+			goto fail;
+
+		if (hdd_extscan_nl_fill_bss(skb, &data->ap, 0))
+			goto fail;
+
+		nla_nest_end(skb, nla_bss);
+		nla_nest_end(skb, nla_ap);
+	}
+	nla_nest_end(skb, nla_aps);
+
+	cfg80211_vendor_event(skb, flags);
+	return;
+
+fail:
+	kfree_skb(skb);
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_generic_rsp() -
+ *	Handle a generic ExtScan Response message
+ * @ctx: HDD context registered with SME
+ * @response: The ExtScan response from firmware
+ *
+ * This function will handle a generic ExtScan response message from
+ * firmware and will communicate the result to the userspace thread
+ * that is waiting for the response.
+ *
+ * Return: none
+ */
+static void
+wlan_hdd_cfg80211_extscan_generic_rsp(struct hdd_context *hdd_ctx,
+	 struct sir_extscan_generic_response *response)
+{
+	struct hdd_ext_scan_context *context;
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx) || !response) {
+		hdd_err("HDD context is not valid or response(%pK) is null",
+		       response);
+		return;
+	}
+
+	hdd_debug("request %u status %u",
+	       response->request_id, response->status);
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	if (context->request_id == response->request_id) {
+		context->response_status = response->status ? -EINVAL : 0;
+		complete(&context->response_event);
+	}
+	spin_unlock(&context->context_lock);
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_callback() - ext scan callback
+ * @hdd_handle: Opaque handle to hdd context
+ * @event_id: Event identifier
+ * @msg: Pointer to message
+ *
+ * Return: none
+ */
+void wlan_hdd_cfg80211_extscan_callback(hdd_handle_t hdd_handle,
+					const uint16_t event_id, void *msg)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+
+	/* ENTER() intentionally not used in a frequently invoked API */
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	hdd_debug("Rcvd Event %d", event_id);
+
+	switch (event_id) {
+	case eSIR_EXTSCAN_CACHED_RESULTS_RSP:
+		/* There is no need to send this response to upper layer
+		 * Just log the message
+		 */
+		hdd_debug("Rcvd eSIR_EXTSCAN_CACHED_RESULTS_RSP");
+		break;
+
+	case eSIR_EXTSCAN_GET_CAPABILITIES_IND:
+		wlan_hdd_cfg80211_extscan_get_capabilities_rsp(hdd_ctx, msg);
+		break;
+
+	case eSIR_EXTSCAN_HOTLIST_MATCH_IND:
+		wlan_hdd_cfg80211_extscan_hotlist_match_ind(hdd_ctx, msg);
+		break;
+
+	case eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND:
+		wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(hdd_ctx,
+									 msg);
+		break;
+
+	case eSIR_EXTSCAN_CACHED_RESULTS_IND:
+		wlan_hdd_cfg80211_extscan_cached_results_ind(hdd_ctx, msg);
+		break;
+
+	case eSIR_EXTSCAN_SCAN_RES_AVAILABLE_IND:
+		wlan_hdd_cfg80211_extscan_scan_res_available_event(hdd_ctx,
+								   msg);
+		break;
+
+	case eSIR_EXTSCAN_FULL_SCAN_RESULT_IND:
+		wlan_hdd_cfg80211_extscan_full_scan_result_event(hdd_ctx, msg);
+		break;
+
+	case eSIR_EPNO_NETWORK_FOUND_IND:
+		wlan_hdd_cfg80211_extscan_epno_match_found(hdd_ctx, msg);
+		break;
+
+	case eSIR_EXTSCAN_SCAN_PROGRESS_EVENT_IND:
+		wlan_hdd_cfg80211_extscan_scan_progress_event(hdd_ctx, msg);
+		break;
+
+	case eSIR_PASSPOINT_NETWORK_FOUND_IND:
+		wlan_hdd_cfg80211_passpoint_match_found(hdd_ctx, msg);
+		break;
+
+	case eSIR_EXTSCAN_START_RSP:
+	case eSIR_EXTSCAN_STOP_RSP:
+	case eSIR_EXTSCAN_SET_BSSID_HOTLIST_RSP:
+	case eSIR_EXTSCAN_RESET_BSSID_HOTLIST_RSP:
+	case eSIR_EXTSCAN_SET_SIGNIFICANT_WIFI_CHANGE_RSP:
+	case eSIR_EXTSCAN_RESET_SIGNIFICANT_WIFI_CHANGE_RSP:
+	case eSIR_EXTSCAN_SET_SSID_HOTLIST_RSP:
+	case eSIR_EXTSCAN_RESET_SSID_HOTLIST_RSP:
+		wlan_hdd_cfg80211_extscan_generic_rsp(hdd_ctx, msg);
+		break;
+
+	default:
+		hdd_err("Unknown event type: %u", event_id);
+		break;
+	}
+}
+
+/*
+ * define short names for the global vendor params
+ * used by wlan_hdd_send_ext_scan_capability()
+ */
+#define PARAM_REQUEST_ID \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
+#define PARAM_STATUS \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
+#define MAX_EXTSCAN_CACHE_SIZE \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
+#define MAX_SCAN_BUCKETS \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
+#define MAX_AP_CACHE_PER_SCAN \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
+#define MAX_RSSI_SAMPLE_SIZE \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
+#define MAX_SCAN_RPT_THRHOLD \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
+#define MAX_HOTLIST_BSSIDS \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
+#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
+#define MAX_BSSID_HISTORY_ENTRIES \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
+#define MAX_HOTLIST_SSIDS \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
+#define MAX_NUM_EPNO_NETS \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS
+#define MAX_NUM_EPNO_NETS_BY_SSID \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID
+#define MAX_NUM_WHITELISTED_SSID \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID
+#define MAX_NUM_BLACKLISTED_BSSID \
+	QCA_WLAN_VENDOR_ATTR_EXTSCAN_MAX_NUM_BLACKLISTED_BSSID
+/**
+ * wlan_hdd_send_ext_scan_capability - send ext scan capability to user space
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int wlan_hdd_send_ext_scan_capability(struct hdd_context *hdd_ctx)
+{
+	int ret;
+	struct sk_buff *skb;
+	struct ext_scan_capabilities_response *data;
+	uint32_t nl_buf_len;
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	data = &(ext_scan_context.capability_response);
+
+	nl_buf_len = NLMSG_HDRLEN;
+	nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
+	(sizeof(data->status) + NLA_HDRLEN) +
+	(sizeof(data->max_scan_cache_size) + NLA_HDRLEN) +
+	(sizeof(data->max_scan_buckets) + NLA_HDRLEN) +
+	(sizeof(data->max_ap_cache_per_scan) + NLA_HDRLEN) +
+	(sizeof(data->max_rssi_sample_size) + NLA_HDRLEN) +
+	(sizeof(data->max_scan_reporting_threshold) + NLA_HDRLEN) +
+	(sizeof(data->max_hotlist_bssids) + NLA_HDRLEN) +
+	(sizeof(data->max_significant_wifi_change_aps) + NLA_HDRLEN) +
+	(sizeof(data->max_bssid_history_entries) + NLA_HDRLEN) +
+	(sizeof(data->max_hotlist_ssids) + NLA_HDRLEN) +
+	(sizeof(data->max_number_epno_networks) + NLA_HDRLEN) +
+	(sizeof(data->max_number_epno_networks_by_ssid) + NLA_HDRLEN) +
+	(sizeof(data->max_number_of_white_listed_ssid) + NLA_HDRLEN) +
+	(sizeof(data->max_number_of_black_listed_bssid) + NLA_HDRLEN);
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+
+	hdd_debug("Req Id %u", data->requestId);
+	hdd_debug("Status %u", data->status);
+	hdd_debug("Scan cache size %u",
+	       data->max_scan_cache_size);
+	hdd_debug("Scan buckets %u", data->max_scan_buckets);
+	hdd_debug("Max AP per scan %u",
+	       data->max_ap_cache_per_scan);
+	hdd_debug("max_rssi_sample_size %u",
+	       data->max_rssi_sample_size);
+	hdd_debug("max_scan_reporting_threshold %u",
+	       data->max_scan_reporting_threshold);
+	hdd_debug("max_hotlist_bssids %u",
+	       data->max_hotlist_bssids);
+	hdd_debug("max_significant_wifi_change_aps %u",
+	       data->max_significant_wifi_change_aps);
+	hdd_debug("max_bssid_history_entries %u",
+	       data->max_bssid_history_entries);
+	hdd_debug("max_hotlist_ssids %u", data->max_hotlist_ssids);
+	hdd_debug("max_number_epno_networks %u",
+					data->max_number_epno_networks);
+	hdd_debug("max_number_epno_networks_by_ssid %u",
+					data->max_number_epno_networks_by_ssid);
+	hdd_debug("max_number_of_white_listed_ssid %u",
+					data->max_number_of_white_listed_ssid);
+	hdd_debug("max_number_of_black_listed_bssid (%u)",
+					data->max_number_of_black_listed_bssid);
+
+	if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
+	    nla_put_u32(skb, PARAM_STATUS, data->status) ||
+	    nla_put_u32(skb, MAX_EXTSCAN_CACHE_SIZE,
+					data->max_scan_cache_size) ||
+	    nla_put_u32(skb, MAX_SCAN_BUCKETS, data->max_scan_buckets) ||
+	    nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
+			data->max_ap_cache_per_scan) ||
+	    nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
+			data->max_rssi_sample_size) ||
+	    nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
+			data->max_scan_reporting_threshold) ||
+	    nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->max_hotlist_bssids) ||
+	    nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS,
+			data->max_significant_wifi_change_aps) ||
+	    nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
+			data->max_bssid_history_entries) ||
+	    nla_put_u32(skb, MAX_HOTLIST_SSIDS,	data->max_hotlist_ssids) ||
+	    nla_put_u32(skb, MAX_NUM_EPNO_NETS,
+			data->max_number_epno_networks) ||
+	    nla_put_u32(skb, MAX_NUM_EPNO_NETS_BY_SSID,
+			data->max_number_epno_networks_by_ssid) ||
+	    nla_put_u32(skb, MAX_NUM_WHITELISTED_SSID,
+			data->max_number_of_white_listed_ssid) ||
+	    nla_put_u32(skb, MAX_NUM_BLACKLISTED_BSSID,
+			data->max_number_of_black_listed_bssid)) {
+		hdd_err("nla put fail");
+		goto nla_put_failure;
+	}
+
+	cfg80211_vendor_cmd_reply(skb);
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EINVAL;
+}
+/*
+ * done with short names for the global vendor params
+ * used by wlan_hdd_send_ext_scan_capability()
+ */
+#undef PARAM_REQUEST_ID
+#undef PARAM_STATUS
+#undef MAX_EXTSCAN_CACHE_SIZE
+#undef MAX_SCAN_BUCKETS
+#undef MAX_AP_CACHE_PER_SCAN
+#undef MAX_RSSI_SAMPLE_SIZE
+#undef MAX_SCAN_RPT_THRHOLD
+#undef MAX_HOTLIST_BSSIDS
+#undef MAX_SIGNIFICANT_WIFI_CHANGE_APS
+#undef MAX_BSSID_HISTORY_ENTRIES
+#undef MAX_HOTLIST_SSIDS
+#undef MAX_NUM_EPNO_NETS
+#undef MAX_NUM_EPNO_NETS_BY_SSID
+#undef MAX_NUM_WHITELISTED_SSID
+#undef MAX_NUM_BLACKLISTED_BSSID
+
+/**
+ * __wlan_hdd_cfg80211_extscan_get_capabilities() - get ext scan capabilities
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: none
+ */
+static int
+__wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data, int data_len)
+{
+	int id, ret;
+	unsigned long rc;
+	struct hdd_ext_scan_context *context;
+	struct extscan_capabilities_params params;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[EXTSCAN_PARAM_MAX + 1];
+	QDF_STATUS status;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return -EINVAL;
+
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
+		hdd_err("Driver Modules are closed");
+		return -EINVAL;
+	}
+
+	if (!ucfg_extscan_get_enable(hdd_ctx->psoc)) {
+		hdd_err("extscan not supported");
+		return -ENOTSUPP;
+	}
+	if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX, data, data_len,
+				    wlan_hdd_extscan_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch request Id */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID;
+	if (!tb[id]) {
+		hdd_err("attr request id failed");
+		return -EINVAL;
+	}
+
+	params.request_id = nla_get_u32(tb[id]);
+	params.vdev_id = adapter->session_id;
+	hdd_debug("Req Id %d Vdev Id %d", params.request_id, params.vdev_id);
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	context->request_id = params.request_id;
+	INIT_COMPLETION(context->response_event);
+	spin_unlock(&context->context_lock);
+
+	status = sme_ext_scan_get_capabilities(hdd_ctx->mac_handle, &params);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_ext_scan_get_capabilities failed(err=%d)",
+			status);
+		return -EINVAL;
+	}
+
+	rc = wait_for_completion_timeout(&context->response_event,
+		msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
+	if (!rc) {
+		hdd_err("Target response timed out");
+		return -ETIMEDOUT;
+	}
+
+	ret = wlan_hdd_send_ext_scan_capability(hdd_ctx);
+	if (ret)
+		hdd_err("Failed to send ext scan capability to user space");
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_get_capabilities() - get ext scan capabilities
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data, int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data,
+		data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_extscan_get_cached_results() - extscan get cached results
+ * @wiphy: wiphy pointer
+ * @wdev: pointer to struct wireless_dev
+ * @data: pointer to incoming NL vendor data
+ * @data_len: length of @data
+ *
+ * This function parses the incoming NL vendor command data attributes and
+ * invokes the SME Api and blocks on a completion variable.
+ * Each WMI event with cached scan results data chunk results in
+ * function call wlan_hdd_cfg80211_extscan_cached_results_ind and each
+ * data chunk is sent up the layer in cfg80211_vendor_cmd_alloc_reply_skb.
+ *
+ * If timeout happens before receiving all of the data, this function sets
+ * a context variable @ignore_cached_results to %true, all of the next data
+ * chunks are checked against this variable and dropped.
+ *
+ * Return: 0 on success; error number otherwise.
+ */
+static int
+__wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
+					       struct wireless_dev *wdev,
+					       const void *data,
+					       int data_len)
+{
+	struct extscan_cached_result_params params;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[EXTSCAN_PARAM_MAX + 1];
+	struct hdd_ext_scan_context *context;
+	QDF_STATUS status;
+	int id, retval;
+	unsigned long rc;
+
+	/* ENTER_DEV() intentionally not used in a frequently invoked API */
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	retval = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != retval)
+		return -EINVAL;
+
+	if (!ucfg_extscan_get_enable(hdd_ctx->psoc)) {
+		hdd_err("extscan not supported");
+		return -ENOTSUPP;
+	}
+	if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX, data, data_len,
+				    wlan_hdd_extscan_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch request Id */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID;
+	if (!tb[id]) {
+		hdd_err("attr request id failed");
+		return -EINVAL;
+	}
+
+	params.request_id = nla_get_u32(tb[id]);
+	params.vdev_id = adapter->session_id;
+
+	/* Parse and fetch flush parameter */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH;
+	if (!tb[id]) {
+		hdd_err("attr flush failed");
+		return -EINVAL;
+	}
+	params.flush = nla_get_u8(tb[id]);
+	hdd_debug("Req Id: %u Vdev Id: %d Flush: %d",
+		  params.request_id, params.vdev_id, params.flush);
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	context->request_id = params.request_id;
+	context->ignore_cached_results = false;
+	INIT_COMPLETION(context->response_event);
+	spin_unlock(&context->context_lock);
+
+	status = sme_get_cached_results(hdd_ctx->mac_handle, &params);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_get_cached_results failed(err=%d)", status);
+		return -EINVAL;
+	}
+
+	rc = wait_for_completion_timeout(&context->response_event,
+			msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
+	if (!rc) {
+		hdd_err("Target response timed out");
+		retval = -ETIMEDOUT;
+		spin_lock(&context->context_lock);
+		context->ignore_cached_results = true;
+		spin_unlock(&context->context_lock);
+	} else {
+		spin_lock(&context->context_lock);
+		retval = context->response_status;
+		spin_unlock(&context->context_lock);
+	}
+	return retval;
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_get_cached_results() - extscan get cached results
+ * @wiphy: wiphy pointer
+ * @wdev: pointer to struct wireless_dev
+ * @data: pointer to incoming NL vendor data
+ * @data_len: length of @data
+ *
+ * This function parses the incoming NL vendor command data attributes and
+ * invokes the SME Api and blocks on a completion variable.
+ * Each WMI event with cached scan results data chunk results in
+ * function call wlan_hdd_cfg80211_extscan_cached_results_ind and each
+ * data chunk is sent up the layer in cfg80211_vendor_cmd_alloc_reply_skb.
+ *
+ * If timeout happens before receiving all of the data, this function sets
+ * a context variable @ignore_cached_results to %true, all of the next data
+ * chunks are checked against this variable and dropped.
+ *
+ * Return: 0 on success; error number otherwise.
+ */
+int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data, int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data,
+								data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_parse_ap_rssi_threshold() - parse AP RSSI threshold parameters
+ * @attr: netlink attribute containing the AP RSSI threshold parameters
+ * @ap: destination buffer for the parsed parameters
+ *
+ * This function parses the BSSID, low RSSI and high RSSI values from
+ * the @attr netlink attribute, storing the parsed values in @ap.
+ *
+ * Return: 0 if @attr is parsed and all required attributes are
+ * present, otherwise a negative errno.
+ */
+static int hdd_parse_ap_rssi_threshold(struct nlattr *attr,
+				       struct ap_threshold_params *ap)
+{
+	struct nlattr *tb[EXTSCAN_PARAM_MAX + 1];
+	int id;
+
+	if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX,
+				    nla_data(attr), nla_len(attr),
+				    wlan_hdd_extscan_config_policy)) {
+		hdd_err("nla_parse failed");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch MAC address */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID;
+	if (!tb[id]) {
+		hdd_err("attr mac address failed");
+		return -EINVAL;
+	}
+	nla_memcpy(ap->bssid.bytes, tb[id], QDF_MAC_ADDR_SIZE);
+	hdd_debug("BSSID: " MAC_ADDRESS_STR, MAC_ADDR_ARRAY(ap->bssid.bytes));
+
+	/* Parse and fetch low RSSI */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW;
+	if (!tb[id]) {
+		hdd_err("attr low RSSI failed");
+		return -EINVAL;
+	}
+	ap->low = nla_get_s32(tb[id]);
+	hdd_debug("RSSI low %d", ap->low);
+
+	/* Parse and fetch high RSSI */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH;
+	if (!tb[id]) {
+		hdd_err("attr high RSSI failed");
+		return -EINVAL;
+	}
+	ap->high = nla_get_s32(tb[id]);
+	hdd_debug("RSSI High %d", ap->high);
+
+	return 0;
+}
+
+/**
+ * __wlan_hdd_cfg80211_extscan_set_bssid_hotlist() - set bssid hot list
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: none
+ */
+static int
+__wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      const void *data,
+					      int data_len)
+{
+	struct extscan_bssid_hotlist_set_params *params;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[EXTSCAN_PARAM_MAX + 1];
+	struct nlattr *apth;
+	struct hdd_ext_scan_context *context;
+	QDF_STATUS status;
+	uint8_t i;
+	int id, rem, retval;
+	unsigned long rc;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	retval = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != retval)
+		return -EINVAL;
+
+	if (!ucfg_extscan_get_enable(hdd_ctx->psoc)) {
+		hdd_err("extscan not supported");
+		return -ENOTSUPP;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX,
+				    data, data_len,
+				    wlan_hdd_extscan_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	params = qdf_mem_malloc(sizeof(*params));
+	if (!params) {
+		hdd_err("qdf_mem_malloc failed");
+		return -ENOMEM;
+	}
+
+	/* assume the worst until proven otherwise */
+	retval = -EINVAL;
+
+	/* Parse and fetch request Id */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID;
+	if (!tb[id]) {
+		hdd_err("attr request id failed");
+		goto fail;
+	}
+
+	params->request_id = nla_get_u32(tb[id]);
+	hdd_debug("Req Id %d", params->request_id);
+
+	/* Parse and fetch number of APs */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP;
+	if (!tb[id]) {
+		hdd_err("attr number of AP failed");
+		goto fail;
+	}
+
+	params->num_ap = nla_get_u32(tb[id]);
+	if (params->num_ap > WMI_WLAN_EXTSCAN_MAX_HOTLIST_APS) {
+		hdd_err("Number of AP: %u exceeds max: %u",
+			params->num_ap, WMI_WLAN_EXTSCAN_MAX_HOTLIST_APS);
+		goto fail;
+	}
+	params->vdev_id = adapter->session_id;
+	hdd_debug("Number of AP %d vdev Id %d",
+		  params->num_ap, params->vdev_id);
+
+	/* Parse and fetch lost ap sample size */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE;
+	if (!tb[id]) {
+		hdd_err("attr lost ap sample size failed");
+		goto fail;
+	}
+
+	params->lost_ap_sample_size = nla_get_u32(tb[id]);
+	hdd_debug("Lost ap sample size %d",
+		  params->lost_ap_sample_size);
+
+	/* Parse the AP Threshold array */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM;
+	if (!tb[id]) {
+		hdd_err("attr ap threshold failed");
+		goto fail;
+	}
+
+	i = 0;
+	nla_for_each_nested(apth, tb[id], rem) {
+		if (i == params->num_ap) {
+			hdd_warn("Ignoring excess AP");
+			break;
+		}
+
+		retval = hdd_parse_ap_rssi_threshold(apth, &params->ap[i]);
+		if (retval)
+			goto fail;
+
+		i++;
+	}
+
+	if (i < params->num_ap) {
+		hdd_warn("Number of AP %u less than expected %u",
+			 i, params->num_ap);
+		params->num_ap = i;
+	}
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	INIT_COMPLETION(context->response_event);
+	context->request_id = params->request_id;
+	spin_unlock(&context->context_lock);
+
+	status = sme_set_bss_hotlist(hdd_ctx->mac_handle, params);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_set_bss_hotlist failed(err=%d)", status);
+		retval = qdf_status_to_os_return(status);
+		goto fail;
+	}
+
+	/* request was sent -- wait for the response */
+	rc = wait_for_completion_timeout
+		(&context->response_event,
+		 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
+
+	if (!rc) {
+		hdd_err("sme_set_bss_hotlist timed out");
+		retval = -ETIMEDOUT;
+	} else {
+		spin_lock(&context->context_lock);
+		if (context->request_id == params->request_id)
+			retval = context->response_status;
+		else
+			retval = -EINVAL;
+		spin_unlock(&context->context_lock);
+	}
+	hdd_exit();
+
+fail:
+	qdf_mem_free(params);
+	return retval;
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_set_bssid_hotlist() - set ext scan bssid hotlist
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data, int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
+					data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+
+/**
+ * __wlan_hdd_cfg80211_extscan_set_significant_change() - set significant change
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: none
+ */
+static int
+__wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
+						   struct wireless_dev *wdev,
+						   const void *data,
+						   int data_len)
+{
+	struct extscan_set_sig_changereq_params *params;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[EXTSCAN_PARAM_MAX + 1];
+	struct nlattr *apth;
+	struct hdd_ext_scan_context *context;
+	QDF_STATUS status;
+	uint8_t i;
+	int id, rem, retval;
+	unsigned long rc;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	retval = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != retval)
+		return -EINVAL;
+
+	if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX,
+				    data, data_len,
+				    wlan_hdd_extscan_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	params = qdf_mem_malloc(sizeof(*params));
+	if (!params) {
+		hdd_err("qdf_mem_malloc failed");
+		return -ENOMEM;
+	}
+
+	/* assume the worst until proven otherwise */
+	retval = -EINVAL;
+
+	/* Parse and fetch request Id */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID;
+	if (!tb[id]) {
+		hdd_err("attr request id failed");
+		goto fail;
+	}
+
+	params->request_id = nla_get_u32(tb[id]);
+	hdd_debug("Req Id %d", params->request_id);
+
+	/* Parse and fetch RSSI sample size */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE;
+	if (!tb[id]) {
+		hdd_err("attr RSSI sample size failed");
+		goto fail;
+	}
+	params->rssi_sample_size = nla_get_u32(tb[id]);
+	hdd_debug("RSSI sample size %u", params->rssi_sample_size);
+
+	/* Parse and fetch lost AP sample size */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE;
+	if (!tb[id]) {
+		hdd_err("attr lost AP sample size failed");
+		goto fail;
+	}
+	params->lostap_sample_size = nla_get_u32(tb[id]);
+	hdd_debug("Lost AP sample size %u", params->lostap_sample_size);
+
+	/* Parse and fetch AP min breaching */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING;
+	if (!tb[id]) {
+		hdd_err("attr AP min breaching");
+		goto fail;
+	}
+	params->min_breaching = nla_get_u32(tb[id]);
+	hdd_debug("AP min breaching %u", params->min_breaching);
+
+	/* Parse and fetch number of APs */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP;
+	if (!tb[id]) {
+		hdd_err("attr number of AP failed");
+		goto fail;
+	}
+	params->num_ap = nla_get_u32(tb[id]);
+	if (params->num_ap > WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS) {
+		hdd_err("Number of AP %u exceeds max %u",
+			params->num_ap,
+			WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS);
+		goto fail;
+	}
+
+	params->vdev_id = adapter->session_id;
+	hdd_debug("Number of AP %d Vdev Id %d",
+		  params->num_ap, params->vdev_id);
+
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM;
+	if (!tb[id]) {
+		hdd_err("attr ap threshold failed");
+		goto fail;
+	}
+	i = 0;
+	nla_for_each_nested(apth, tb[id], rem) {
+
+		if (i == params->num_ap) {
+			hdd_warn("Ignoring excess AP");
+			break;
+		}
+
+		retval = hdd_parse_ap_rssi_threshold(apth, &params->ap[i]);
+		if (retval)
+			goto fail;
+
+		i++;
+	}
+	if (i < params->num_ap) {
+		hdd_warn("Number of AP %u less than expected %u",
+			 i, params->num_ap);
+		params->num_ap = i;
+	}
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	INIT_COMPLETION(context->response_event);
+	context->request_id = params->request_id;
+	spin_unlock(&context->context_lock);
+
+	status = sme_set_significant_change(hdd_ctx->mac_handle, params);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_set_significant_change failed(err=%d)", status);
+		retval = qdf_status_to_os_return(status);
+		goto fail;
+	}
+
+	/* request was sent -- wait for the response */
+	rc = wait_for_completion_timeout(&context->response_event,
+				 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
+
+	if (!rc) {
+		hdd_err("sme_set_significant_change timed out");
+		retval = -ETIMEDOUT;
+	} else {
+		spin_lock(&context->context_lock);
+		if (context->request_id == params->request_id)
+			retval = context->response_status;
+		else
+			retval = -EINVAL;
+		spin_unlock(&context->context_lock);
+	}
+	hdd_exit();
+
+fail:
+	qdf_mem_free(params);
+	return retval;
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_set_significant_change() - set significant change
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
+				struct wireless_dev *wdev,
+				const void *data, int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev,
+					data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_remove_dsrc_channels () - remove dsrc chanels
+ * @hdd_ctx: hdd context
+ * @wiphy: Pointer to wireless phy
+ * @chan_list: channel list
+ * @num_channels: number of channels
+ *
+ * Return: none
+ */
+static void hdd_remove_dsrc_channels(struct hdd_context *hdd_ctx,
+				     struct wiphy *wiphy, uint32_t *chan_list,
+				     uint8_t *num_channels)
+{
+	uint8_t num_chan_temp = 0;
+	int i;
+
+	for (i = 0; i < *num_channels; i++) {
+		if (!wlan_reg_is_dsrc_chan(hdd_ctx->pdev,
+					   wlan_reg_freq_to_chan(
+					   hdd_ctx->pdev,
+					   chan_list[i]))) {
+			chan_list[num_chan_temp] = chan_list[i];
+			num_chan_temp++;
+		}
+	}
+	*num_channels = num_chan_temp;
+}
+
+/**
+ * hdd_remove_passive_channels () - remove passive channels
+ * @wiphy: Pointer to wireless phy
+ * @chan_list: channel list
+ * @num_channels: number of channels
+ *
+ * Return: none
+ */
+static void hdd_remove_passive_channels(struct wiphy *wiphy,
+					uint32_t *chan_list,
+					uint8_t *num_channels)
+{
+	uint8_t num_chan_temp = 0;
+	int i, j, k;
+
+	for (i = 0; i < *num_channels; i++)
+		for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
+			if (wiphy->bands[j] == NULL)
+				continue;
+			for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
+				if ((chan_list[i] ==
+				     wiphy->bands[j]->channels[k].center_freq)
+				    && (!(wiphy->bands[j]->channels[k].flags &
+				       IEEE80211_CHAN_PASSIVE_SCAN))
+				) {
+					chan_list[num_chan_temp] = chan_list[i];
+					num_chan_temp++;
+				}
+			}
+		}
+
+	*num_channels = num_chan_temp;
+}
+
+/**
+ * __wlan_hdd_cfg80211_extscan_get_valid_channels () - get valid channels
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: none
+ */
+static int
+__wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
+						 struct wireless_dev
+						 *wdev, const void *data,
+						 int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
+	uint8_t num_channels  = 0, i, buf[256] = {0};
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +
+			  1];
+	uint32_t requestId, maxChannels;
+	tWifiBand wifiBand;
+	QDF_STATUS status;
+	struct sk_buff *reply_skb;
+	int ret, len = 0;
+
+	/* ENTER_DEV() intentionally not used in a frequently invoked API */
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return -EINVAL;
+
+	if (!ucfg_extscan_get_enable(hdd_ctx->psoc)) {
+		hdd_err("extscan not supported");
+		return -ENOTSUPP;
+	}
+	if (wlan_cfg80211_nla_parse(tb,
+			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
+			   data, data_len, wlan_hdd_extscan_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch request Id */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
+		hdd_err("attr request id failed");
+		return -EINVAL;
+	}
+	requestId =
+		nla_get_u32(tb
+		 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
+
+	/* Parse and fetch wifi band */
+	if (!tb
+	    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]) {
+		hdd_err("attr wifi band failed");
+		return -EINVAL;
+	}
+	wifiBand =
+		nla_get_u32(tb
+		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
+
+	if (!tb
+	    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]) {
+		hdd_err("attr max channels failed");
+		return -EINVAL;
+	}
+	maxChannels =
+		nla_get_u32(tb
+		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
+
+	if (maxChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		hdd_err("Max channels %d exceeded Valid channel list len %d",
+			maxChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
+		return -EINVAL;
+	}
+
+	hdd_debug("Req Id: %u Wifi band: %d Max channels: %d", requestId,
+		    wifiBand, maxChannels);
+	status = sme_get_valid_channels_by_band(hdd_ctx->mac_handle,
+						wifiBand, chan_list,
+						&num_channels);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("sme_get_valid_channels_by_band failed (err=%d)",
+		       status);
+		return -EINVAL;
+	}
+
+	num_channels = QDF_MIN(num_channels, maxChannels);
+
+	hdd_remove_dsrc_channels(hdd_ctx, wiphy, chan_list, &num_channels);
+	if ((QDF_SAP_MODE == adapter->device_mode) ||
+	    !strncmp(hdd_get_fwpath(), "ap", 2))
+		hdd_remove_passive_channels(wiphy, chan_list,
+					    &num_channels);
+
+	hdd_debug("Number of channels: %d", num_channels);
+	for (i = 0; i < num_channels; i++)
+		len += scnprintf(buf + len, sizeof(buf) - len,
+				 "%u ", chan_list[i]);
+
+	hdd_debug("Channels: %s", buf);
+
+	reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
+							sizeof(u32) *
+							num_channels +
+							NLMSG_HDRLEN);
+
+	if (reply_skb) {
+		if (nla_put_u32(reply_skb,
+			QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
+			num_channels) ||
+		    nla_put(reply_skb,
+			QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
+			sizeof(u32) * num_channels, chan_list)) {
+			hdd_err("nla put fail");
+			kfree_skb(reply_skb);
+			return -EINVAL;
+		}
+		ret = cfg80211_vendor_cmd_reply(reply_skb);
+		return ret;
+	}
+
+	hdd_err("valid channels: buffer alloc fail");
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_get_valid_channels() - get ext scan valid channels
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data, int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
+			data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_extscan_update_dwell_time_limits() - update dwell times
+ * @req_msg: Pointer to request message
+ * @bkt_idx: Index of current bucket being processed
+ * @active_min: minimum active dwell time
+ * @active_max: maximum active dwell time
+ * @passive_min: minimum passive dwell time
+ * @passive_max: maximum passive dwell time
+ *
+ * Return: none
+ */
+static void
+hdd_extscan_update_dwell_time_limits(struct wifi_scan_cmd_req_params *req_msg,
+				     uint32_t bkt_idx, uint32_t active_min,
+				     uint32_t active_max, uint32_t passive_min,
+				     uint32_t passive_max)
+{
+	/* update per-bucket dwell times */
+	if (req_msg->buckets[bkt_idx].min_dwell_time_active >
+			active_min) {
+		req_msg->buckets[bkt_idx].min_dwell_time_active =
+			active_min;
+	}
+	if (req_msg->buckets[bkt_idx].max_dwell_time_active <
+			active_max) {
+		req_msg->buckets[bkt_idx].max_dwell_time_active =
+			active_max;
+	}
+	if (req_msg->buckets[bkt_idx].min_dwell_time_passive >
+			passive_min) {
+		req_msg->buckets[bkt_idx].min_dwell_time_passive =
+			passive_min;
+	}
+	if (req_msg->buckets[bkt_idx].max_dwell_time_passive <
+			passive_max) {
+		req_msg->buckets[bkt_idx].max_dwell_time_passive =
+			passive_max;
+	}
+	/* update dwell-time across all buckets */
+	if (req_msg->min_dwell_time_active >
+			req_msg->buckets[bkt_idx].min_dwell_time_active) {
+		req_msg->min_dwell_time_active =
+			req_msg->buckets[bkt_idx].min_dwell_time_active;
+	}
+	if (req_msg->max_dwell_time_active <
+			req_msg->buckets[bkt_idx].max_dwell_time_active) {
+		req_msg->max_dwell_time_active =
+			req_msg->buckets[bkt_idx].max_dwell_time_active;
+	}
+	if (req_msg->min_dwell_time_passive >
+			req_msg->buckets[bkt_idx].min_dwell_time_passive) {
+		req_msg->min_dwell_time_passive =
+			req_msg->buckets[bkt_idx].min_dwell_time_passive;
+	}
+	if (req_msg->max_dwell_time_passive >
+			req_msg->buckets[bkt_idx].max_dwell_time_passive) {
+		req_msg->max_dwell_time_passive =
+			req_msg->buckets[bkt_idx].max_dwell_time_passive;
+	}
+}
+
+/**
+ * hdd_extscan_channel_max_reached() - channel max reached
+ * @req: extscan request structure
+ * @total_channels: total number of channels
+ *
+ * Return: true if total channels reached max, false otherwise
+ */
+static bool
+hdd_extscan_channel_max_reached(struct wifi_scan_cmd_req_params *req,
+				uint8_t total_channels)
+{
+	if (total_channels == WMI_WLAN_EXTSCAN_MAX_CHANNELS) {
+		hdd_warn("max #of channels %d reached, take only first %d bucket(s)",
+			 total_channels, req->num_buckets);
+		return true;
+	}
+	return false;
+}
+
+/**
+ * hdd_extscan_start_fill_bucket_channel_spec() - fill bucket channel spec
+ * @hdd_ctx: HDD global context
+ * @req_msg: Pointer to request structure
+ * @bucket_attr: pointer to bucket attribute
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int hdd_extscan_start_fill_bucket_channel_spec(
+			struct hdd_context *hdd_ctx,
+			struct wifi_scan_cmd_req_params *req_msg,
+			struct nlattr *bucket_attr)
+{
+	mac_handle_t mac_handle;
+	struct nlattr *bucket_tb[EXTSCAN_PARAM_MAX + 1];
+	struct nlattr *channel_tb[EXTSCAN_PARAM_MAX + 1];
+	struct nlattr *buckets;
+	struct nlattr *channels;
+	int id, rem1, rem2;
+	QDF_STATUS status;
+	uint8_t bkt_index, j, num_channels, total_channels = 0;
+	uint32_t expected_buckets;
+	uint32_t expected_channels;
+	uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
+	uint32_t extscan_active_min_chn_time;
+	uint32_t min_dwell_time_active_bucket;
+	uint32_t max_dwell_time_active_bucket;
+	uint32_t min_dwell_time_passive_bucket;
+	uint32_t max_dwell_time_passive_bucket;
+	struct wifi_scan_bucket_params *bucket;
+	struct wifi_scan_channelspec_params *channel;
+	struct nlattr *channel_attr;
+
+	ucfg_extscan_get_active_min_time(hdd_ctx->psoc,
+					&extscan_active_min_chn_time);
+	ucfg_extscan_get_active_max_time(hdd_ctx->psoc,
+					 &max_dwell_time_active_bucket);
+	ucfg_extscan_get_passive_max_time(hdd_ctx->psoc,
+					 &max_dwell_time_passive_bucket);
+
+	min_dwell_time_active_bucket = max_dwell_time_active_bucket;
+	min_dwell_time_passive_bucket = max_dwell_time_passive_bucket;
+
+	req_msg->min_dwell_time_active =
+		req_msg->max_dwell_time_active = max_dwell_time_active_bucket;
+
+	req_msg->min_dwell_time_passive =
+		req_msg->max_dwell_time_passive = max_dwell_time_passive_bucket;
+
+	expected_buckets = req_msg->num_buckets;
+	req_msg->num_buckets = 0;
+	bkt_index = 0;
+
+	mac_handle = hdd_ctx->mac_handle;
+	nla_for_each_nested(buckets, bucket_attr, rem1) {
+
+		if (bkt_index >= expected_buckets) {
+			hdd_warn("ignoring excess buckets");
+			break;
+		}
+
+		if (wlan_cfg80211_nla_parse(bucket_tb, EXTSCAN_PARAM_MAX,
+					    nla_data(buckets), nla_len(buckets),
+					    wlan_hdd_extscan_config_policy)) {
+			hdd_err("nla_parse failed");
+			return -EINVAL;
+		}
+
+		bucket = &req_msg->buckets[bkt_index];
+
+		/* Parse and fetch bucket spec */
+		id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX;
+		if (!bucket_tb[id]) {
+			hdd_err("attr bucket index failed");
+			return -EINVAL;
+		}
+		bucket->bucket = nla_get_u8(bucket_tb[id]);
+
+		/* Parse and fetch wifi band */
+		id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND;
+		if (!bucket_tb[id]) {
+			hdd_err("attr wifi band failed");
+			return -EINVAL;
+		}
+		bucket->band = nla_get_u8(bucket_tb[id]);
+
+		/* Parse and fetch period */
+		id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD;
+		if (!bucket_tb[id]) {
+			hdd_err("attr period failed");
+			return -EINVAL;
+		}
+		bucket->period = nla_get_u32(bucket_tb[id]);
+
+		/* Parse and fetch report events */
+		id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS;
+		if (!bucket_tb[id]) {
+			hdd_err("attr report events failed");
+			return -EINVAL;
+		}
+		bucket->report_events = nla_get_u8(bucket_tb[id]);
+
+		/* Parse and fetch max period */
+		id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD;
+		if (!bucket_tb[id]) {
+			hdd_err("attr max period failed");
+			return -EINVAL;
+		}
+		bucket->max_period = nla_get_u32(bucket_tb[id]);
+
+		/* Parse and fetch base */
+		id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE;
+		if (!bucket_tb[id]) {
+			hdd_err("attr base failed");
+			return -EINVAL;
+		}
+		bucket->exponent = nla_get_u32(bucket_tb[id]);
+
+		/* Parse and fetch step count */
+		id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT;
+		if (!bucket_tb[id]) {
+			hdd_err("attr step count failed");
+			return -EINVAL;
+		}
+		bucket->step_count = nla_get_u32(bucket_tb[id]);
+
+		hdd_debug("Bucket spec Index: %d Wifi band: %d period: %d report events: %d max period: %u base: %u Step count: %u",
+			  bucket->bucket,
+			  bucket->band,
+			  bucket->period,
+			  bucket->report_events,
+			  bucket->max_period,
+			  bucket->exponent,
+			  bucket->step_count);
+
+		/* start with known good values for bucket dwell times */
+		bucket->min_dwell_time_active = max_dwell_time_active_bucket;
+		bucket->max_dwell_time_active = max_dwell_time_active_bucket;
+		bucket->min_dwell_time_passive = max_dwell_time_passive_bucket;
+		bucket->max_dwell_time_passive = max_dwell_time_passive_bucket;
+
+		/* Framework shall pass the channel list if the input
+		 * WiFi band is WMI_WIFI_BAND_UNSPECIFIED.  If the
+		 * input WiFi band is specified (any value other than
+		 * WMI_WIFI_BAND_UNSPECIFIED) then driver populates
+		 * the channel list.
+		 */
+		if (bucket->band != WMI_WIFI_BAND_UNSPECIFIED) {
+			if (hdd_extscan_channel_max_reached(req_msg,
+							    total_channels))
+				return 0;
+
+			num_channels = 0;
+			hdd_debug("WiFi band is specified, driver to fill channel list");
+			status = sme_get_valid_channels_by_band(mac_handle,
+								bucket->band,
+								chan_list,
+								&num_channels);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				hdd_err("sme_get_valid_channels_by_band failed (err=%d)",
+					status);
+				return -EINVAL;
+			}
+			hdd_debug("before trimming, num_channels: %d",
+				  num_channels);
+
+			bucket->num_channels =
+				QDF_MIN(num_channels,
+					(WMI_WLAN_EXTSCAN_MAX_CHANNELS -
+						total_channels));
+			hdd_debug("Adj Num channels/bucket: %d total_channels: %d",
+				  bucket->num_channels, total_channels);
+			total_channels += bucket->num_channels;
+
+			for (j = 0; j < bucket->num_channels; j++) {
+				channel = &bucket->channels[j];
+
+				channel->channel = chan_list[j];
+				channel->channel_class = 0;
+				if ((wlan_reg_get_channel_state(
+					hdd_ctx->pdev,
+					cds_freq_to_chan(chan_list[j]))) !=
+						CHANNEL_STATE_ENABLE) {
+					channel->passive = 1;
+					channel->dwell_time_ms =
+						max_dwell_time_passive_bucket;
+					/* reconfigure per-bucket dwell time */
+					if (min_dwell_time_passive_bucket >
+							channel->dwell_time_ms) {
+						min_dwell_time_passive_bucket =
+							channel->dwell_time_ms;
+					}
+					if (max_dwell_time_passive_bucket <
+							channel->dwell_time_ms) {
+						max_dwell_time_passive_bucket =
+							channel->dwell_time_ms;
+					}
+
+				} else {
+					channel->passive = 0;
+					channel->dwell_time_ms =
+						max_dwell_time_active_bucket;
+					/* reconfigure per-bucket dwell times */
+					if (min_dwell_time_active_bucket >
+							channel->dwell_time_ms) {
+						min_dwell_time_active_bucket =
+							channel->dwell_time_ms;
+					}
+					if (max_dwell_time_active_bucket <
+							channel->dwell_time_ms) {
+						max_dwell_time_active_bucket =
+							channel->dwell_time_ms;
+					}
+
+				}
+
+				hdd_debug("Channel: %u Passive: %u Dwell time: %u ms Class: %u",
+					  channel->channel,
+					  channel->passive,
+					  channel->dwell_time_ms,
+					  channel->channel_class);
+			}
+
+			hdd_extscan_update_dwell_time_limits(
+					req_msg, bkt_index,
+					min_dwell_time_active_bucket,
+					max_dwell_time_active_bucket,
+					min_dwell_time_passive_bucket,
+					max_dwell_time_passive_bucket);
+
+			hdd_debug("bkt_index:%d actv_min:%d actv_max:%d pass_min:%d pass_max:%d",
+					bkt_index,
+					bucket->min_dwell_time_active,
+					bucket->max_dwell_time_active,
+					bucket->min_dwell_time_passive,
+					bucket->max_dwell_time_passive);
+
+			bkt_index++;
+			req_msg->num_buckets++;
+			continue;
+		}
+
+		/* Parse and fetch number of channels */
+		id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS;
+		if (!bucket_tb[id]) {
+			hdd_err("attr num channels failed");
+			return -EINVAL;
+		}
+		bucket->num_channels = nla_get_u32(bucket_tb[id]);
+		hdd_debug("before trimming: num channels %d",
+			  bucket->num_channels);
+
+		bucket->num_channels =
+			QDF_MIN(bucket->num_channels,
+				(WMI_WLAN_EXTSCAN_MAX_CHANNELS -
+							total_channels));
+		hdd_debug("Num channels/bucket: %d total_channels: %d",
+			  bucket->num_channels, total_channels);
+
+		if (hdd_extscan_channel_max_reached(req_msg, total_channels))
+			return 0;
+
+		id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC;
+		channel_attr = bucket_tb[id];
+		if (!channel_attr) {
+			hdd_err("attr channel spec failed");
+			return -EINVAL;
+		}
+
+		expected_channels = bucket->num_channels;
+		bucket->num_channels = 0;
+
+		nla_for_each_nested(channels, channel_attr, rem2) {
+			if ((bucket->num_channels >= expected_channels) ||
+			    hdd_extscan_channel_max_reached(req_msg,
+							    total_channels))
+				break;
+
+			if (wlan_cfg80211_nla_parse(channel_tb,
+						    EXTSCAN_PARAM_MAX,
+						    nla_data(channels),
+						    nla_len(channels),
+						    wlan_hdd_extscan_config_policy)) {
+				hdd_err("nla_parse failed");
+				return -EINVAL;
+			}
+
+			channel = &bucket->channels[bucket->num_channels];
+			/* Parse and fetch channel */
+			if (!channel_tb[
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
+				hdd_err("attr channel failed");
+				return -EINVAL;
+			}
+			channel->channel =
+				nla_get_u32(channel_tb[
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
+			hdd_debug("channel %u",
+				channel->channel);
+
+			/* Parse and fetch dwell time */
+			if (!channel_tb[
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
+				hdd_err("attr dwelltime failed");
+				return -EINVAL;
+			}
+			channel->dwell_time_ms =
+				nla_get_u32(channel_tb[
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
+
+			/* Override dwell time if required */
+			if (channel->dwell_time_ms <
+						extscan_active_min_chn_time ||
+			    channel->dwell_time_ms >
+						max_dwell_time_active_bucket) {
+				hdd_debug("WiFi band is unspecified, dwellTime:%d",
+						channel->dwell_time_ms);
+
+				if ((wlan_reg_get_channel_state(
+					hdd_ctx->pdev,
+					cds_freq_to_chan(
+					channel->channel)))
+						!= CHANNEL_STATE_ENABLE) {
+					channel->dwell_time_ms =
+						max_dwell_time_passive_bucket;
+				} else {
+					channel->dwell_time_ms =
+						max_dwell_time_active_bucket;
+				}
+			}
+
+			hdd_debug("New Dwell time %u ms",
+				channel->dwell_time_ms);
+
+			if ((wlan_reg_get_channel_state(hdd_ctx->pdev,
+					cds_freq_to_chan(
+					channel->channel)))
+					!= CHANNEL_STATE_ENABLE) {
+				if (min_dwell_time_passive_bucket >
+						channel->dwell_time_ms) {
+					min_dwell_time_passive_bucket =
+						channel->dwell_time_ms;
+				}
+				if (max_dwell_time_passive_bucket <
+						channel->dwell_time_ms) {
+					max_dwell_time_passive_bucket =
+						channel->dwell_time_ms;
+				}
+			} else {
+				if (min_dwell_time_active_bucket >
+						channel->dwell_time_ms) {
+					min_dwell_time_active_bucket =
+						channel->dwell_time_ms;
+				}
+				if (max_dwell_time_active_bucket <
+						channel->dwell_time_ms) {
+					max_dwell_time_active_bucket =
+						channel->dwell_time_ms;
+				}
+			}
+
+			/* Parse and fetch channel spec passive */
+			if (!channel_tb[
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
+				hdd_err("attr channel spec passive failed");
+				return -EINVAL;
+			}
+			channel->passive =
+				nla_get_u8(channel_tb[
+				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
+			hdd_debug("Chnl spec passive %u",
+				channel->passive);
+			/* Override scan type if required */
+			if ((wlan_reg_get_channel_state(hdd_ctx->pdev,
+					cds_freq_to_chan(
+					channel->channel)))
+					!= CHANNEL_STATE_ENABLE) {
+				channel->passive = true;
+			} else {
+				channel->passive = false;
+			}
+			total_channels++;
+			bucket->num_channels++;
+		}
+
+		if (bucket->num_channels != expected_channels)
+			hdd_warn("channels: Expected %u got %u",
+				 expected_channels,
+				 bucket->num_channels);
+
+		hdd_extscan_update_dwell_time_limits(
+					req_msg, bkt_index,
+					min_dwell_time_active_bucket,
+					max_dwell_time_active_bucket,
+					min_dwell_time_passive_bucket,
+					max_dwell_time_passive_bucket);
+
+		hdd_debug("bktIndex:%d actv_min:%d actv_max:%d pass_min:%d pass_max:%d",
+				bkt_index,
+				bucket->min_dwell_time_active,
+				bucket->max_dwell_time_active,
+				bucket->min_dwell_time_passive,
+				bucket->max_dwell_time_passive);
+
+		bkt_index++;
+		req_msg->num_buckets++;
+	}
+
+	hdd_debug("Global: actv_min:%d actv_max:%d pass_min:%d pass_max:%d",
+				req_msg->min_dwell_time_active,
+				req_msg->max_dwell_time_active,
+				req_msg->min_dwell_time_passive,
+				req_msg->max_dwell_time_passive);
+	return 0;
+}
+
+/*
+ * hdd_extscan_map_usr_drv_config_flags() - map userspace to driver config flags
+ * @config_flags - [input] configuration flags.
+ *
+ * This function maps user space received configuration flags to
+ * driver representation.
+ *
+ * Return: configuration flags
+ */
+static uint32_t hdd_extscan_map_usr_drv_config_flags(uint32_t config_flags)
+{
+	uint32_t configuration_flags = 0;
+
+	if (config_flags & EXTSCAN_LP_EXTENDED_BATCHING)
+		configuration_flags |= EXTSCAN_LP_EXTENDED_BATCHING;
+
+	return configuration_flags;
+}
+
+/**
+ * __wlan_hdd_cfg80211_extscan_start() - ext scan start
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int
+__wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  const void *data,
+				  int data_len)
+{
+	struct wifi_scan_cmd_req_params *params;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[EXTSCAN_PARAM_MAX + 1];
+	struct hdd_ext_scan_context *context;
+	uint32_t num_buckets;
+	QDF_STATUS status;
+	int retval, id;
+	unsigned long rc;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (QDF_NDI_MODE == adapter->device_mode) {
+		hdd_err("Command not allowed for NDI interface");
+		return -EPERM;
+	}
+
+	retval = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != retval)
+		return -EINVAL;
+
+	if (!ucfg_extscan_get_enable(hdd_ctx->psoc)) {
+		hdd_err("extscan not supported");
+		return -ENOTSUPP;
+	}
+	if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX, data, data_len,
+				    wlan_hdd_extscan_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	params = qdf_mem_malloc(sizeof(*params));
+	if (!params)
+		return -ENOMEM;
+
+	/* assume the worst until proven otherwise */
+	retval = -EINVAL;
+
+	/* Parse and fetch request Id */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID;
+	if (!tb[id]) {
+		hdd_err("attr request id failed");
+		goto fail;
+	}
+
+	params->request_id = nla_get_u32(tb[id]);
+	params->vdev_id = adapter->session_id;
+
+	/* Parse and fetch base period */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD;
+	if (!tb[id]) {
+		hdd_err("attr base period failed");
+		goto fail;
+	}
+	params->base_period = nla_get_u32(tb[id]);
+
+	/* Parse and fetch max AP per scan */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN;
+	if (!tb[id]) {
+		hdd_err("attr max_ap_per_scan failed");
+		goto fail;
+	}
+	params->max_ap_per_scan = nla_get_u32(tb[id]);
+
+	/* Parse and fetch report threshold percent */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT;
+	if (!tb[id]) {
+		hdd_err("attr report_threshold percent failed");
+		goto fail;
+	}
+	params->report_threshold_percent = nla_get_u8(tb[id]);
+
+	/* Parse and fetch report threshold num scans */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS;
+	if (!tb[id]) {
+		hdd_err("attr report_threshold num scans failed");
+		goto fail;
+	}
+	params->report_threshold_num_scans = nla_get_u8(tb[id]);
+	hdd_debug("Req Id: %d Vdev Id: %d Base Period: %d Max AP per Scan: %d Report Threshold percent: %d Report Threshold num scans: %d",
+		  params->request_id, params->vdev_id,
+		  params->base_period, params->max_ap_per_scan,
+		  params->report_threshold_percent,
+		  params->report_threshold_num_scans);
+
+	/* Parse and fetch number of buckets */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS;
+	if (!tb[id]) {
+		hdd_err("attr number of buckets failed");
+		goto fail;
+	}
+	num_buckets = nla_get_u8(tb[id]);
+
+	if (num_buckets > WMI_WLAN_EXTSCAN_MAX_BUCKETS) {
+		hdd_warn("Exceeded MAX number of buckets: %d",
+			 WMI_WLAN_EXTSCAN_MAX_BUCKETS);
+		num_buckets = WMI_WLAN_EXTSCAN_MAX_BUCKETS;
+	}
+	hdd_debug("Input: Number of Buckets %d", num_buckets);
+	params->num_buckets = num_buckets;
+
+	/* This is optional attribute, if not present set it to 0 */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS;
+	if (!tb[id])
+		params->configuration_flags = 0;
+	else
+		params->configuration_flags =
+			hdd_extscan_map_usr_drv_config_flags(
+				nla_get_u32(tb[id]));
+
+	params->extscan_adaptive_dwell_mode =
+		hdd_ctx->config->extscan_adaptive_dwell_mode;
+
+	hdd_debug("Configuration flags: %u",
+		  params->configuration_flags);
+
+	/* Parse and fetch number the array of buckets */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC;
+	if (!tb[id]) {
+		hdd_err("attr bucket spec failed");
+		goto fail;
+	}
+	retval = hdd_extscan_start_fill_bucket_channel_spec(hdd_ctx, params,
+							    tb[id]);
+	if (retval)
+		goto fail;
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	INIT_COMPLETION(context->response_event);
+	context->request_id = params->request_id;
+	context->buckets_scanned = 0;
+	spin_unlock(&context->context_lock);
+
+	status = sme_ext_scan_start(hdd_ctx->mac_handle, params);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_ext_scan_start failed(err=%d)", status);
+		retval = qdf_status_to_os_return(status);
+		goto fail;
+	}
+
+	hdd_ctx->ext_scan_start_since_boot = qdf_get_monotonic_boottime();
+	hdd_debug("Timestamp since boot: %llu",
+		  hdd_ctx->ext_scan_start_since_boot);
+
+	/* request was sent -- wait for the response */
+	rc = wait_for_completion_timeout(&context->response_event,
+				msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
+
+	if (!rc) {
+		hdd_err("sme_ext_scan_start timed out");
+		retval = -ETIMEDOUT;
+	} else {
+		spin_lock(&context->context_lock);
+		if (context->request_id == params->request_id)
+			retval = context->response_status;
+		else
+			retval = -EINVAL;
+		spin_unlock(&context->context_lock);
+	}
+	hdd_exit();
+
+fail:
+	qdf_mem_free(params);
+	return retval;
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_start() - start extscan
+ * @wiphy: Pointer to wireless phy.
+ * @wdev: Pointer to wireless device.
+ * @data: Pointer to input data.
+ * @data_len: Length of @data.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
+				    struct wireless_dev *wdev,
+				    const void *data, int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+
+/**
+ * __wlan_hdd_cfg80211_extscan_stop() - ext scan stop
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: none
+ */
+static int
+__wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
+				 struct wireless_dev *wdev,
+				 const void *data, int data_len)
+{
+	struct extscan_stop_req_params params;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[EXTSCAN_PARAM_MAX + 1];
+	struct hdd_ext_scan_context *context;
+	QDF_STATUS status;
+	int id, retval;
+	unsigned long rc;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	retval = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != retval)
+		return -EINVAL;
+
+	if (!ucfg_extscan_get_enable(hdd_ctx->psoc)) {
+		hdd_err("extscan not supported");
+		return -ENOTSUPP;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX, data, data_len,
+				    wlan_hdd_extscan_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch request Id */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID;
+	if (!tb[id]) {
+		hdd_err("attr request id failed");
+		return -EINVAL;
+	}
+	params.request_id = nla_get_u32(tb[id]);
+	params.vdev_id = adapter->session_id;
+	hdd_debug("Req Id %d Vdev Id %d",
+		  params.request_id, params.vdev_id);
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	INIT_COMPLETION(context->response_event);
+	context->request_id = params.request_id;
+	spin_unlock(&context->context_lock);
+
+	status = sme_ext_scan_stop(hdd_ctx->mac_handle, &params);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_ext_scan_stop failed(err=%d)", status);
+		return qdf_status_to_os_return(status);
+	}
+
+	/* request was sent -- wait for the response */
+	rc = wait_for_completion_timeout(&context->response_event,
+				msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
+
+	if (!rc) {
+		hdd_err("sme_ext_scan_stop timed out");
+		retval = -ETIMEDOUT;
+	} else {
+		spin_lock(&context->context_lock);
+		if (context->request_id == params.request_id)
+			retval = context->response_status;
+		else
+			retval = -EINVAL;
+		spin_unlock(&context->context_lock);
+	}
+	hdd_exit();
+	return retval;
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_stop() - stop extscan
+ * @wiphy: Pointer to wireless phy.
+ * @wdev: Pointer to wireless device.
+ * @data: Pointer to input data.
+ * @data_len: Length of @data.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data, int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+
+/**
+ * __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist() - reset bssid hotlist
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: none
+ */
+static int
+__wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	struct extscan_bssid_hotlist_reset_params params;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[EXTSCAN_PARAM_MAX + 1];
+	struct hdd_ext_scan_context *context;
+	QDF_STATUS status;
+	int id, retval;
+	unsigned long rc;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	retval = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != retval)
+		return -EINVAL;
+
+	if (!ucfg_extscan_get_enable(hdd_ctx->psoc)) {
+		hdd_err("extscan not supported");
+		return -ENOTSUPP;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX,
+				    data, data_len,
+				    wlan_hdd_extscan_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch request Id */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID;
+	if (!tb[id]) {
+		hdd_err("attr request id failed");
+		return -EINVAL;
+	}
+
+	params.request_id = nla_get_u32(tb[id]);
+	params.vdev_id = adapter->session_id;
+	hdd_debug("Req Id %d vdev Id %d", params.request_id, params.vdev_id);
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	INIT_COMPLETION(context->response_event);
+	context->request_id = params.request_id;
+	spin_unlock(&context->context_lock);
+
+	status = sme_reset_bss_hotlist(hdd_ctx->mac_handle, &params);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_reset_bss_hotlist failed(err=%d)", status);
+		return qdf_status_to_os_return(status);
+	}
+
+	/* request was sent -- wait for the response */
+	rc = wait_for_completion_timeout
+		(&context->response_event,
+		 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
+	if (!rc) {
+		hdd_err("sme_reset_bss_hotlist timed out");
+		retval = -ETIMEDOUT;
+	} else {
+		spin_lock(&context->context_lock);
+		if (context->request_id == params.request_id)
+			retval = context->response_status;
+		else
+			retval = -EINVAL;
+		spin_unlock(&context->context_lock);
+	}
+	hdd_exit();
+	return retval;
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_reset_bssid_hotlist() - reset bssid hot list
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
+						  struct wireless_dev *wdev,
+						  const void *data,
+						  int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev,
+							      data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_extscan_reset_significant_change() -
+ *		reset significant change
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: none
+ */
+static int
+__wlan_hdd_cfg80211_extscan_reset_significant_change(struct wiphy *wiphy,
+						     struct wireless_dev *wdev,
+						     const void *data,
+						     int data_len)
+{
+	struct extscan_capabilities_reset_params params;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[EXTSCAN_PARAM_MAX + 1];
+	struct hdd_ext_scan_context *context;
+	QDF_STATUS status;
+	int id, retval;
+	unsigned long rc;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	retval = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != retval)
+		return -EINVAL;
+
+	if (!ucfg_extscan_get_enable(hdd_ctx->psoc)) {
+		hdd_err("extscan not supported");
+		return -ENOTSUPP;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX, data, data_len,
+				    wlan_hdd_extscan_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch request Id */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID;
+	if (!tb[id]) {
+		hdd_err("attr request id failed");
+		return -EINVAL;
+	}
+
+	params.request_id = nla_get_u32(tb[id]);
+	params.vdev_id = adapter->session_id;
+	hdd_debug("Req Id %d Vdev Id %d", params.request_id, params.vdev_id);
+
+	context = &ext_scan_context;
+	spin_lock(&context->context_lock);
+	INIT_COMPLETION(context->response_event);
+	context->request_id = params.request_id;
+	spin_unlock(&context->context_lock);
+
+	status = sme_reset_significant_change(hdd_ctx->mac_handle, &params);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_reset_significant_change failed(err=%d)",
+			status);
+		return -EINVAL;
+	}
+
+	/* request was sent -- wait for the response */
+	rc = wait_for_completion_timeout(&context->response_event,
+				msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
+
+	if (!rc) {
+		hdd_err("sme_ResetSignificantChange timed out");
+		retval = -ETIMEDOUT;
+	} else {
+		spin_lock(&context->context_lock);
+		if (context->request_id == params.request_id)
+			retval = context->response_status;
+		else
+			retval = -EINVAL;
+		spin_unlock(&context->context_lock);
+	}
+	hdd_exit();
+	return retval;
+}
+
+/**
+ * wlan_hdd_cfg80211_extscan_reset_significant_change() - reset significant
+ *							change
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_extscan_reset_significant_change(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data, int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy, wdev,
+						data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+
+/**
+ * hdd_extscan_epno_fill_network() - epno fill single network
+ * @network: aggregate network attribute
+ * @nw: epno network record to be filled
+ *
+ * This function takes a single network block NL vendor attribute from
+ * @network and decodes it into the internal record @nw.
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int
+hdd_extscan_epno_fill_network(struct nlattr *network,
+			      struct wifi_epno_network_params *nw)
+{
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
+	int id, ssid_len;
+	uint8_t *ssid;
+
+	if (!network) {
+		hdd_err("attr network attr failed");
+		return -EINVAL;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_PNO_MAX,
+				    nla_data(network),
+				    nla_len(network),
+				    wlan_hdd_pno_config_policy)) {
+		hdd_err("nla_parse failed");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch ssid */
+	id = QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID;
+	if (!tb[id]) {
+		hdd_err("attr network ssid failed");
+		return -EINVAL;
+	}
+	ssid_len = nla_len(tb[id]);
+
+	/* nla_parse will detect overflow but not underflow */
+	if (0 == ssid_len) {
+		hdd_err("zero ssid length");
+		return -EINVAL;
+	}
+
+	/* Decrement by 1, don't count null character */
+	ssid_len--;
+
+	nw->ssid.length = ssid_len;
+	hdd_debug("network ssid length %d", ssid_len);
+	ssid = nla_data(tb[id]);
+	qdf_mem_copy(nw->ssid.mac_ssid, ssid, ssid_len);
+	hdd_debug("Ssid (%.*s)", nw->ssid.length, nw->ssid.mac_ssid);
+
+	/* Parse and fetch epno flags */
+	id = QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS;
+	if (!tb[id]) {
+		hdd_err("attr epno flags failed");
+		return -EINVAL;
+	}
+	nw->flags = nla_get_u8(tb[id]);
+	hdd_debug("flags %u", nw->flags);
+
+	/* Parse and fetch auth bit */
+	id = QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT;
+	if (!tb[id]) {
+		hdd_err("attr auth bit failed");
+		return -EINVAL;
+	}
+	nw->auth_bit_field = nla_get_u8(tb[id]);
+	hdd_debug("auth bit %u", nw->auth_bit_field);
+
+	return 0;
+}
+
+/**
+ * hdd_extscan_epno_fill_network_list() - epno fill network list
+ * @req_msg: request message
+ * @networks: aggregate network list attribute
+ *
+ * This function reads the network block NL vendor attributes from
+ * @networks and fills in the epno request message @req_msg.
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int
+hdd_extscan_epno_fill_network_list(struct wifi_enhanced_pno_params *req_msg,
+				   struct nlattr *networks)
+{
+	struct nlattr *network;
+	int rem;
+	uint32_t index;
+	uint32_t expected_networks;
+	struct wifi_epno_network_params *nw;
+
+	if (!networks) {
+		hdd_err("attr networks list failed");
+		return -EINVAL;
+	}
+
+	expected_networks = req_msg->num_networks;
+	index = 0;
+
+	nla_for_each_nested(network, networks, rem) {
+		if (index == expected_networks) {
+			hdd_warn("ignoring excess networks");
+			break;
+		}
+
+		nw = &req_msg->networks[index++];
+		if (hdd_extscan_epno_fill_network(network, nw))
+			return -EINVAL;
+	}
+	req_msg->num_networks = index;
+	return 0;
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_epno_list() - epno set network list
+ * @wiphy: wiphy
+ * @wdev: pointer to wireless dev
+ * @data: data pointer
+ * @data_len: data length
+ *
+ * This function reads the NL vendor attributes from @data and
+ * fills in the epno request message.
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int __wlan_hdd_cfg80211_set_epno_list(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data,
+					     int data_len)
+{
+	struct wifi_enhanced_pno_params *req_msg;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
+	struct nlattr *networks;
+	QDF_STATUS status;
+	uint32_t num_networks, len;
+	int id, ret_val;
+
+	hdd_enter_dev(dev);
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		return ret_val;
+
+	if (!ucfg_extscan_get_enable(hdd_ctx->psoc)) {
+		hdd_err("extscan not supported");
+		return -ENOTSUPP;
+	}
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_PNO_MAX, data,
+				    data_len, wlan_hdd_pno_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch number of networks */
+	id = QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS;
+	if (!tb[id]) {
+		hdd_err("attr num networks failed");
+		return -EINVAL;
+	}
+
+	/*
+	 * num_networks is also used as EPNO SET/RESET request.
+	 * if num_networks is zero then it is treated as RESET.
+	 */
+	num_networks = nla_get_u32(tb[id]);
+
+	if (num_networks > MAX_EPNO_NETWORKS) {
+		hdd_debug("num of nw: %d exceeded max: %d, resetting to: %d",
+			num_networks, MAX_EPNO_NETWORKS, MAX_EPNO_NETWORKS);
+		num_networks = MAX_EPNO_NETWORKS;
+	}
+
+	hdd_debug("num networks %u", num_networks);
+	len = sizeof(*req_msg) +
+			(num_networks * sizeof(req_msg->networks[0]));
+
+	req_msg = qdf_mem_malloc(len);
+	if (!req_msg) {
+		hdd_err("qdf_mem_malloc failed");
+		return -ENOMEM;
+	}
+	req_msg->num_networks = num_networks;
+
+	/* Parse and fetch request Id */
+	id = QCA_WLAN_VENDOR_ATTR_PNO_CONFIG_REQUEST_ID;
+	if (!tb[id]) {
+		hdd_err("attr request id failed");
+		goto fail;
+	}
+	req_msg->request_id = nla_get_u32(tb[id]);
+	hdd_debug("Req Id %u", req_msg->request_id);
+
+	req_msg->vdev_id = adapter->session_id;
+	hdd_debug("Vdev Id %d", req_msg->vdev_id);
+
+	if (num_networks) {
+		/* Parse and fetch min_5ghz_rssi */
+		id = QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI;
+		if (!tb[id]) {
+			hdd_err("min_5ghz_rssi id failed");
+			goto fail;
+		}
+		req_msg->min_5ghz_rssi = nla_get_u32(tb[id]);
+
+		/* Parse and fetch min_24ghz_rssi */
+		id = QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI;
+		if (!tb[id]) {
+			hdd_err("min_24ghz_rssi id failed");
+			goto fail;
+		}
+		req_msg->min_24ghz_rssi = nla_get_u32(tb[id]);
+
+		/* Parse and fetch initial_score_max */
+		id = QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX;
+		if (!tb[id]) {
+			hdd_err("initial_score_max id failed");
+			goto fail;
+		}
+		req_msg->initial_score_max = nla_get_u32(tb[id]);
+
+		/* Parse and fetch current_connection_bonus */
+		id = QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS;
+		if (!tb[id]) {
+			hdd_err("current_connection_bonus id failed");
+			goto fail;
+		}
+		req_msg->current_connection_bonus = nla_get_u32(tb[id]);
+
+		/* Parse and fetch same_network_bonus */
+		id = QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS;
+		if (!tb[id]) {
+			hdd_err("same_network_bonus id failed");
+			goto fail;
+		}
+		req_msg->same_network_bonus = nla_get_u32(tb[id]);
+
+		/* Parse and fetch secure_bonus */
+		id = QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS;
+		if (!tb[id]) {
+			hdd_err("secure_bonus id failed");
+			goto fail;
+		}
+		req_msg->secure_bonus = nla_get_u32(tb[id]);
+
+		/* Parse and fetch band_5ghz_bonus */
+		id = QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS;
+		if (!tb[id]) {
+			hdd_err("band_5ghz_bonus id failed");
+			goto fail;
+		}
+		req_msg->band_5ghz_bonus = nla_get_u32(tb[id]);
+
+		hdd_debug("min_5ghz_rssi: %d min_24ghz_rssi: %d",
+			req_msg->min_5ghz_rssi,
+			req_msg->min_24ghz_rssi);
+		hdd_debug("initial_score_max: %d current_connection_bonus:%d",
+			req_msg->initial_score_max,
+			req_msg->current_connection_bonus);
+		hdd_debug("Bonuses same_network: %d secure: %d band_5ghz: %d",
+			req_msg->same_network_bonus,
+			req_msg->secure_bonus,
+			req_msg->band_5ghz_bonus);
+
+		id = QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST;
+		networks = tb[id];
+		if (hdd_extscan_epno_fill_network_list(req_msg, networks))
+			goto fail;
+
+	}
+
+	status = sme_set_epno_list(hdd_ctx->mac_handle, req_msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_set_epno_list failed(err=%d)", status);
+		goto fail;
+	}
+
+	hdd_exit();
+	qdf_mem_free(req_msg);
+	return 0;
+
+fail:
+	qdf_mem_free(req_msg);
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_epno_list() - epno set network list
+ * @wiphy: wiphy
+ * @wdev: pointer to wireless dev
+ * @data: data pointer
+ * @data_len: data length
+ *
+ * This function reads the NL vendor attributes from %tb and
+ * fill in the epno request message.
+ *
+ * Return: 0 on success, error number otherwise
+ */
+int wlan_hdd_cfg80211_set_epno_list(struct wiphy *wiphy,
+				    struct wireless_dev *wdev,
+				    const void *data,
+				    int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_epno_list(wiphy, wdev,
+						data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_extscan_passpoint_fill_network() - passpoint fill single network
+ * @network: aggregate network attribute
+ * @nw: passpoint network record to be filled
+ *
+ * This function takes a single network block NL vendor attribute from
+ * @network and decodes it into the internal record @nw.
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int
+hdd_extscan_passpoint_fill_network(struct nlattr *network,
+				   struct wifi_passpoint_network_param *nw)
+{
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
+	int id;
+	size_t len;
+
+	if (!network) {
+		hdd_err("attr network attr failed");
+		return -EINVAL;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_PNO_MAX,
+				    nla_data(network),
+				    nla_len(network),
+				    wlan_hdd_pno_config_policy)) {
+		hdd_err("nla_parse failed");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch identifier */
+	id = QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID;
+	if (!tb[id]) {
+		hdd_err("attr passpoint id failed");
+		return -EINVAL;
+	}
+	nw->id = nla_get_u32(tb[id]);
+	hdd_debug("Id %u", nw->id);
+
+	/* Parse and fetch realm */
+	id = QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM;
+	if (!tb[id]) {
+		hdd_err("attr realm failed");
+		return -EINVAL;
+	}
+	len = nla_strlcpy(nw->realm, tb[id],
+			  WMI_PASSPOINT_REALM_LEN);
+	/* Don't send partial realm to firmware */
+	if (len >= WMI_PASSPOINT_REALM_LEN) {
+		hdd_err("user passed invalid realm, len:%zu", len);
+		return -EINVAL;
+	}
+
+	hdd_debug("realm: %s", nw->realm);
+
+	/* Parse and fetch roaming consortium ids */
+	id = QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_CNSRTM_ID;
+	if (!tb[id]) {
+		hdd_err("attr roaming consortium ids failed");
+		return -EINVAL;
+	}
+	nla_memcpy(&nw->roaming_consortium_ids, tb[id],
+		   sizeof(nw->roaming_consortium_ids));
+	hdd_debug("roaming consortium ids");
+
+	/* Parse and fetch plmn */
+	id = QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_PLMN;
+	if (!tb[id]) {
+		hdd_err("attr plmn failed");
+		return -EINVAL;
+	}
+	nla_memcpy(&nw->plmn, tb[id],
+		   WMI_PASSPOINT_PLMN_LEN);
+	hdd_debug("plmn %02x:%02x:%02x)",
+		  nw->plmn[0],
+		  nw->plmn[1],
+		  nw->plmn[2]);
+
+	return 0;
+}
+
+/**
+ * hdd_extscan_passpoint_fill_networks() - passpoint fill network list
+ * @req_msg: request message
+ * @networks: aggregate network list attribute
+ *
+ * This function reads the network block NL vendor attributes from
+ * @networks and fills in the passpoint request message.
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int
+hdd_extscan_passpoint_fill_networks(struct wifi_passpoint_req_param *req_msg,
+				    struct nlattr *networks)
+{
+	struct nlattr *network;
+	int rem;
+	uint32_t index;
+	uint32_t expected_networks;
+	struct wifi_passpoint_network_param *nw;
+
+	if (!networks) {
+		hdd_err("attr networks list failed");
+		return -EINVAL;
+	}
+
+	expected_networks = req_msg->num_networks;
+	index = 0;
+
+	nla_for_each_nested(network, networks, rem) {
+		if (index == expected_networks) {
+			hdd_warn("ignoring excess networks");
+			break;
+		}
+
+		nw = &req_msg->networks[index++];
+		if (hdd_extscan_passpoint_fill_network(network, nw))
+			return -EINVAL;
+	}
+	req_msg->num_networks = index;
+	return 0;
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_passpoint_list() - set passpoint network list
+ * @wiphy: wiphy
+ * @wdev: pointer to wireless dev
+ * @data: data pointer
+ * @data_len: data length
+ *
+ * This function reads the NL vendor attributes from %tb and
+ * fill in the passpoint request message.
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int __wlan_hdd_cfg80211_set_passpoint_list(struct wiphy *wiphy,
+						  struct wireless_dev *wdev,
+						  const void *data,
+						  int data_len)
+{
+	struct wifi_passpoint_req_param *req_msg;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
+	struct nlattr *networks;
+	uint32_t num_networks;
+	QDF_STATUS status;
+	int id, ret;
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_PNO_MAX, data,
+				    data_len, wlan_hdd_pno_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch number of networks */
+	id = QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM;
+	if (!tb[id]) {
+		hdd_err("attr num networks failed");
+		return -EINVAL;
+	}
+	num_networks = nla_get_u32(tb[id]);
+	if (num_networks > SIR_PASSPOINT_LIST_MAX_NETWORKS) {
+		hdd_err("num networks %u exceeds max %u",
+			num_networks, SIR_PASSPOINT_LIST_MAX_NETWORKS);
+		return -EINVAL;
+	}
+
+	hdd_debug("num networks %u", num_networks);
+
+	req_msg = qdf_mem_malloc(sizeof(*req_msg) +
+			(num_networks * sizeof(req_msg->networks[0])));
+	if (!req_msg) {
+		hdd_err("qdf_mem_malloc failed");
+		return -ENOMEM;
+	}
+	req_msg->num_networks = num_networks;
+
+	/* Parse and fetch request Id */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID;
+	if (!tb[id]) {
+		hdd_err("attr request id failed");
+		goto fail;
+	}
+	req_msg->request_id = nla_get_u32(tb[id]);
+
+	req_msg->vdev_id = adapter->session_id;
+	hdd_debug("Req Id %u Vdev Id %d",
+		  req_msg->request_id, req_msg->vdev_id);
+
+	id = QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NETWORK_ARRAY;
+	networks = tb[id];
+	if (hdd_extscan_passpoint_fill_networks(req_msg, networks))
+		goto fail;
+
+	status = sme_set_passpoint_list(hdd_ctx->mac_handle, req_msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_set_passpoint_list failed(err=%d)", status);
+		goto fail;
+	}
+
+	hdd_exit();
+	qdf_mem_free(req_msg);
+	return 0;
+
+fail:
+	qdf_mem_free(req_msg);
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_passpoint_list() - set passpoint network list
+ * @wiphy: wiphy
+ * @wdev: pointer to wireless dev
+ * @data: data pointer
+ * @data_len: data length
+ *
+ * This function reads the NL vendor attributes from %tb and
+ * fill in the passpoint request message.
+ *
+ * Return: 0 on success, error number otherwise
+ */
+int wlan_hdd_cfg80211_set_passpoint_list(struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 const void *data,
+					 int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_passpoint_list(wiphy, wdev,
+						     data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_reset_passpoint_list() - reset passpoint network list
+ * @wiphy: wiphy
+ * @wdev: pointer to wireless dev
+ * @data: data pointer
+ * @data_len: data length
+ *
+ * This function resets passpoint networks list
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int __wlan_hdd_cfg80211_reset_passpoint_list(struct wiphy *wiphy,
+						    struct wireless_dev *wdev,
+						    const void *data,
+						    int data_len)
+{
+	struct wifi_passpoint_req_param *req_msg;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
+	QDF_STATUS status;
+	int id, ret;
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_PNO_MAX, data,
+				    data_len, wlan_hdd_extscan_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	req_msg = qdf_mem_malloc(sizeof(*req_msg));
+	if (!req_msg) {
+		hdd_err("qdf_mem_malloc failed");
+		return -ENOMEM;
+	}
+
+	/* Parse and fetch request Id */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID;
+	if (!tb[id]) {
+		hdd_err("attr request id failed");
+		goto fail;
+	}
+	req_msg->request_id = nla_get_u32(tb[id]);
+
+	req_msg->vdev_id = adapter->session_id;
+	hdd_debug("Req Id %u Vdev Id %d",
+		  req_msg->request_id, req_msg->vdev_id);
+
+	status = sme_reset_passpoint_list(hdd_ctx->mac_handle, req_msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_reset_passpoint_list failed(err=%d)", status);
+		goto fail;
+	}
+
+	hdd_exit();
+	qdf_mem_free(req_msg);
+	return 0;
+
+fail:
+	qdf_mem_free(req_msg);
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_reset_passpoint_list() - reset passpoint network list
+ * @wiphy: wiphy
+ * @wdev: pointer to wireless dev
+ * @data: data pointer
+ * @data_len: data length
+ *
+ * This function resets passpoint networks list
+ *
+ * Return: 0 on success, error number otherwise
+ */
+int wlan_hdd_cfg80211_reset_passpoint_list(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data,
+					   int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_reset_passpoint_list(wiphy, wdev,
+						       data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#undef PARAM_ID
+#undef PARAM_REALM
+#undef PARAM_ROAM_ID
+#undef PARAM_ROAM_PLMN
+
+/**
+ * wlan_hdd_cfg80211_extscan_init() - Initialize the ExtScan feature
+ * @hdd_ctx: Global HDD context
+ *
+ * Return: none
+ */
+void wlan_hdd_cfg80211_extscan_init(struct hdd_context *hdd_ctx)
+{
+	init_completion(&ext_scan_context.response_event);
+	spin_lock_init(&ext_scan_context.context_lock);
+}
+
+#endif /* FEATURE_WLAN_EXTSCAN */
diff --git a/core/hdd/src/wlan_hdd_ext_scan.h b/core/hdd/src/wlan_hdd_ext_scan.h
new file mode 100644
index 0000000..3c98fe2
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_ext_scan.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2012-2014, 2017-2018 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.
+ */
+
+#if !defined(WLAN_HDD_EXT_SCAN_H)
+#define WLAN_HDD_EXT_SCAN_H
+
+/**
+ * DOC: wlan_hdd_ext_scan.h
+ *
+ * WLAN Host Device Driver EXT SCAN feature implementation
+ *
+ */
+
+struct hdd_context;
+
+#define EXTSCAN_EVENT_BUF_SIZE 4096
+
+#ifdef FEATURE_WLAN_EXTSCAN
+
+#include "wlan_hdd_main.h"
+
+/*
+ * Used to allocate the size of 4096 for the EXTScan NL data.
+ * The size of 4096 is considered assuming that all data per
+ * respective event fit with in the limit.Please take a call
+ * on the limit based on the data requirements.
+ */
+
+int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
+				    struct wireless_dev *wdev,
+				    const void *data, int data_len);
+
+int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data, int data_len);
+
+int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
+						 struct wireless_dev
+						 *wdev, const void *data,
+						 int data_len);
+
+int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
+					       struct wireless_dev *wdev,
+					       const void *data, int data_len);
+
+int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
+						 struct wireless_dev
+						 *wdev, const void *data,
+						 int data_len);
+
+int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
+						struct wireless_dev
+						*wdev, const void *data,
+						int data_len);
+
+int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
+						  struct wireless_dev
+						  *wdev, const void *data,
+						  int data_len);
+
+int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
+						     struct wireless_dev
+						     *wdev, const void *data,
+						     int data_len);
+
+int wlan_hdd_cfg80211_extscan_reset_significant_change(struct wiphy
+						       *wiphy,
+						       struct
+						       wireless_dev
+						       *wdev, const void *data,
+						       int data_len);
+
+int wlan_hdd_cfg80211_set_epno_list(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data,
+				   int data_len);
+
+int wlan_hdd_cfg80211_set_passpoint_list(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len);
+
+int wlan_hdd_cfg80211_reset_passpoint_list(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len);
+
+void wlan_hdd_cfg80211_extscan_init(struct hdd_context *hdd_ctx);
+
+#else /* FEATURE_WLAN_EXTSCAN */
+
+static inline void wlan_hdd_cfg80211_extscan_init(struct hdd_context *hdd_ctx)
+{
+}
+
+#endif /* End of FEATURE_WLAN_EXTSCAN */
+
+#endif /* end #if !defined(WLAN_HDD_EXT_SCAN_H) */
+
diff --git a/core/hdd/src/wlan_hdd_fips.c b/core/hdd/src/wlan_hdd_fips.c
new file mode 100644
index 0000000..a2bf8ce
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_fips.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2017-2018 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: wlan_hdd_fips.c
+ *
+ * WLAN Host Device Driver FIPS Certification Feature
+ */
+
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_fips.h"
+#include "wlan_osif_request_manager.h"
+#include "qdf_mem.h"
+#include "sme_api.h"
+
+#define WLAN_WAIT_TIME_FIPS 5000
+
+/**
+ * hdd_fips_context - hdd fips context
+ * @status: status of response. 0: no error, -ENOMEM: unable to allocate
+ *   memory for the response payload
+ * @request: fips request
+ * @response: fips response
+ */
+struct hdd_fips_context {
+	int status;
+	struct fips_params request;
+	struct wmi_host_fips_event_param response;
+};
+
+/**
+ * hdd_fips_event_dup () - duplicate a fips event
+ * @dest: destination event
+ * @src: source event
+ *
+ * Make a "deep" duplicate of a FIPS event
+ *
+ * Return: 0 if the event was duplicated, otherwise an error
+ */
+static int hdd_fips_event_dup(struct wmi_host_fips_event_param *dest,
+			      const struct wmi_host_fips_event_param *src)
+{
+	*dest = *src;
+	if  (dest->data_len) {
+		dest->data = qdf_mem_malloc(dest->data_len);
+		if (!dest->data) {
+			hdd_err("memory allocation failed");
+			return -ENOMEM;
+		}
+		qdf_mem_copy(dest->data, src->data, src->data_len);
+	} else {
+		/* make sure we don't have a rogue pointer */
+		dest->data = NULL;
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_fips_cb () - fips response message handler
+ * @cookie: hdd request cookie
+ * @response: fips response parameters
+ *
+ * Return: none
+ */
+static void hdd_fips_cb(void *cookie,
+			struct wmi_host_fips_event_param *response)
+{
+	struct osif_request *request;
+	struct hdd_fips_context *context;
+
+	hdd_enter();
+
+	if (!response) {
+		hdd_err("response is NULL");
+		return;
+	}
+
+	request = osif_request_get(cookie);
+	if (!request) {
+		hdd_debug("Obsolete request");
+		return;
+	}
+
+	hdd_debug("pdev_id %u, status %u, data_len %u",
+		  response->pdev_id,
+		  response->error_status,
+		  response->data_len);
+	qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
+			   response->data, response->data_len);
+
+	context = osif_request_priv(request);
+	if (response->error_status) {
+		context->status = -ETIMEDOUT;
+	} else {
+		context->status = hdd_fips_event_dup(&context->response,
+						     response);
+	}
+
+	osif_request_complete(request);
+	osif_request_put(request);
+	hdd_exit();
+}
+
+static void hdd_fips_context_dealloc(void *priv)
+{
+	struct hdd_fips_context *context = priv;
+
+	qdf_mem_free(context->response.data);
+}
+
+
+static int hdd_fips_validate_request(struct iw_fips_test_request *user_request,
+				     uint32_t request_len)
+{
+	uint32_t expected_data_len;
+
+	if (request_len < sizeof(*user_request)) {
+		hdd_debug("Request len %u is too small", request_len);
+		return -EINVAL;
+	}
+
+	if ((user_request->key_len != FIPS_KEY_LENGTH_128) &&
+	    (user_request->key_len != FIPS_KEY_LENGTH_256)) {
+		hdd_debug("Invalid key len %u", user_request->key_len);
+		return -EINVAL;
+	}
+
+	expected_data_len = request_len - sizeof(*user_request);
+	if (expected_data_len != user_request->data_len) {
+		hdd_debug("Unexpected data_len %u for request_len %u",
+			  user_request->data_len, request_len);
+		return -EINVAL;
+	}
+
+	if ((user_request->mode != FIPS_ENGINE_AES_CTR) &&
+	    (user_request->mode != FIPS_ENGINE_AES_MIC)) {
+		hdd_debug("Invalid mode %u", user_request->mode);
+		return -EINVAL;
+	}
+
+	if ((user_request->operation != FIPS_ENCRYPT_CMD) &&
+	    (user_request->operation != FIPS_DECRYPT_CMD)) {
+		hdd_debug("Invalid operation %u", user_request->operation);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int __hdd_fips_test(struct net_device *dev,
+			  struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	struct iw_fips_test_request *user_request;
+	struct iw_fips_test_response *user_response;
+	uint32_t request_len;
+	int ret;
+	QDF_STATUS qdf_status;
+	void *cookie;
+	struct osif_request *request;
+	struct hdd_fips_context *context;
+	struct fips_params *fips_request;
+	struct wmi_host_fips_event_param *fips_response;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*context),
+		.timeout_ms = WLAN_WAIT_TIME_FIPS,
+		.dealloc = hdd_fips_context_dealloc,
+	};
+
+	hdd_enter_dev(dev);
+
+	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	user_request = (struct iw_fips_test_request *)extra;
+	request_len = wrqu->data.length;
+	ret = hdd_fips_validate_request(user_request, request_len);
+	if (ret)
+		return ret;
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	context = osif_request_priv(request);
+	fips_request = &context->request;
+	fips_request->key = &user_request->key[0];
+	fips_request->key_len = user_request->key_len;
+	fips_request->data = &user_request->data[0];
+	fips_request->data_len = user_request->data_len;
+	fips_request->mode = user_request->mode;
+	fips_request->op = user_request->operation;
+	fips_request->pdev_id = WMI_PDEV_ID_1ST;
+
+	cookie = osif_request_cookie(request);
+	qdf_status = sme_fips_request(hdd_ctx->mac_handle, &context->request,
+				      hdd_fips_cb, cookie);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Unable to post fips message");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_err("Target response timed out");
+		goto cleanup;
+	}
+
+	ret = context->status;
+	if (ret) {
+		hdd_err("Target response processing failed");
+		goto cleanup;
+	}
+
+	fips_response = &context->response;
+	if (fips_response->data_len != fips_request->data_len) {
+		hdd_err("Data length mismatch, got %u, expected %u",
+			fips_response->data_len, fips_request->data_len);
+		ret = -EINVAL;
+		goto cleanup;
+	}
+	user_response = (struct iw_fips_test_response *)extra;
+	user_response->status = context->status;
+	if (user_response->status) {
+		user_response->data_len = 0;
+	} else {
+		user_response->data_len = fips_response->data_len;
+		qdf_mem_copy(user_response->data, fips_response->data,
+			     fips_response->data_len);
+	}
+
+	/*
+	 * By default wireless extensions private ioctls have either
+	 * SET semantics (even numbered ioctls) or GET semantics (odd
+	 * numbered ioctls). This is an even numbered ioctl so the SET
+	 * semantics apply. This means the core kernel ioctl code took
+	 * care of copying the request parameters from userspace to
+	 * kernel space. However this ioctl also needs to return the
+	 * response. Since the core kernel ioctl code doesn't support
+	 * SET ioctls returning anything other than status, we have to
+	 * explicitly copy the result to userspace.
+	 */
+	wrqu->data.length = sizeof(*user_response) + user_response->data_len;
+	if (copy_to_user(wrqu->data.pointer, user_response, wrqu->data.length))
+		ret = -EFAULT;
+
+cleanup:
+	osif_request_put(request);
+
+	hdd_exit();
+	return ret;
+}
+
+int hdd_fips_test(struct net_device *dev,
+		  struct iw_request_info *info,
+		  union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_fips_test(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
diff --git a/core/hdd/src/wlan_hdd_fips.h b/core/hdd/src/wlan_hdd_fips.h
new file mode 100644
index 0000000..945d5c6
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_fips.h
@@ -0,0 +1,73 @@
+/*
+ * 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: wlan_hdd_fips.h
+ *
+ * WLAN Host Device Driver FIPS Certification Feature
+ */
+
+#ifndef __WLAN_HDD_FIPS_H__
+#define __WLAN_HDD_FIPS_H__
+
+struct net_device;
+struct iw_request_info;
+union iwreq_data;
+struct hdd_adapter;
+void fips_test(struct hdd_adapter *adapter);
+
+#define FIPS_KEY_LEN 32
+struct iw_fips_test_request {
+	uint32_t operation;
+	uint32_t mode;
+	uint32_t key_len;
+	uint8_t  key[FIPS_KEY_LEN];
+	uint32_t data_len;
+	uint8_t  data[0];
+};
+
+struct iw_fips_test_response {
+	uint32_t status;
+	uint32_t data_len;
+	uint8_t  data[0];
+};
+
+
+/**
+ * hdd_fips_test() - Perform FIPS test
+ * @dev: netdev upon which the FIPS test ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data structure
+ * @extra: extra payload for wireless extensions ioctl
+ *
+ * This API implements the FIPS test interface. Upon entry the @extra
+ * buffer will contain a FIPS test vector formated as a &struct
+ * iw_fips_test_request. This vector will be sent to firmware where it
+ * will be run through the appropriate hardware. The result of the
+ * operation will be sent back to userspace via @extra encoded as a
+ * &struct iw_fips_test_response.
+ *
+ * Return: 0 if the test vector was processed, otherwise a negative
+ *         errno.
+ */
+
+int hdd_fips_test(struct net_device *dev,
+		  struct iw_request_info *info,
+		  union iwreq_data *wrqu, char *extra);
+
+#endif /* __WLAN_HDD_FIPS_H__ */
diff --git a/core/hdd/src/wlan_hdd_ftm.c b/core/hdd/src/wlan_hdd_ftm.c
new file mode 100644
index 0000000..28bba06
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_ftm.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_ftm.c
+ *
+ * This file contains the WLAN factory test mode implementation
+ */
+
+#include "cds_sched.h"
+#include <cds_api.h>
+#include "sir_types.h"
+#include "qdf_types.h"
+#include "sir_api.h"
+#include "sir_mac_prot_def.h"
+#include "sme_api.h"
+#include "mac_init_api.h"
+#include "wlan_qct_sys.h"
+#include "wlan_hdd_misc.h"
+#include "i_cds_packet.h"
+#include "cds_reg_service.h"
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_lpass.h"
+#include "qwlan_version.h"
+#include "wma_types.h"
+#include "cfg_api.h"
+
+#ifdef QCA_WIFI_FTM
+
+#include "wlan_hdd_cfg80211.h"
+#include "hif.h"
+#include <wlan_ioctl_ftm.h>
+#include <wlan_cfg80211_ftm.h>
+
+struct qcmbr_data {
+	unsigned int cmd;
+	unsigned int length;
+	unsigned char buf[WLAN_FTM_DATA_MAX_LEN + 4];
+	unsigned int copy_to_user;
+};
+
+/**
+ * hdd_update_cds_config_ftm() - API to update cds configuration parameters
+ * for FTM mode.
+ * @hdd_ctx: HDD Context
+ *
+ * Return: 0 on success; errno on failure
+ */
+
+int hdd_update_cds_config_ftm(struct hdd_context *hdd_ctx)
+{
+	struct cds_config_info *cds_cfg;
+	QDF_STATUS status;
+	bool self_recovery;
+
+	cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
+	if (!cds_cfg) {
+		hdd_err("failed to allocate cds config");
+		return -ENOMEM;
+	}
+
+	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get self recovery ini config");
+		return -EIO;
+	}
+
+	cds_cfg->driver_type = QDF_DRIVER_TYPE_MFG;
+	hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
+	cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
+	cds_cfg->self_recovery_enabled = self_recovery;
+	cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs;
+	cds_init_ini_config(cds_cfg);
+
+	return 0;
+}
+
+#ifdef LINUX_QCMBR
+
+/**
+ * wlan_hdd_qcmbr_command() - QCMBR command handler
+ * @adapter: adapter upon which the command was received
+ * @pqcmbr_data: QCMBR command
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int wlan_hdd_qcmbr_command(struct hdd_adapter *adapter,
+				  struct qcmbr_data *pqcmbr_data)
+{
+	int ret = 0;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	ret = wlan_ioctl_ftm_testmode_cmd(hdd_ctx->pdev,
+					  pqcmbr_data->cmd,
+					  pqcmbr_data->buf,
+					  pqcmbr_data->length);
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+
+/**
+ * wlan_hdd_qcmbr_ioctl() - Compatibility-mode QCMBR ioctl handler
+ * @adapter: adapter upon which the ioctl was received
+ * @ifr: the ioctl request
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int wlan_hdd_qcmbr_compat_ioctl(struct hdd_adapter *adapter,
+				       struct ifreq *ifr)
+{
+	struct qcmbr_data *qcmbr_data;
+	int ret = 0;
+
+	qcmbr_data = qdf_mem_malloc(sizeof(*qcmbr_data));
+	if (qcmbr_data == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(qcmbr_data, ifr->ifr_data, sizeof(*qcmbr_data))) {
+		ret = -EFAULT;
+		goto exit;
+	}
+
+	ret = wlan_hdd_qcmbr_command(adapter, qcmbr_data);
+	if ((ret == 0) && (qcmbr_data->cmd == 0x1001)) {
+		ret = copy_to_user(ifr->ifr_data, qcmbr_data->buf,
+				   (WLAN_FTM_DATA_MAX_LEN + 4));
+	}
+
+exit:
+	qdf_mem_free(qcmbr_data);
+	return ret;
+}
+#else                           /* CONFIG_COMPAT */
+static int wlan_hdd_qcmbr_compat_ioctl(struct hdd_adapter *adapter,
+				       struct ifreq *ifr)
+{
+	return 0;
+}
+#endif /* CONFIG_COMPAT */
+
+/**
+ * wlan_hdd_qcmbr_ioctl() - Standard QCMBR ioctl handler
+ * @adapter: adapter upon which the ioctl was received
+ * @ifr: the ioctl request
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int wlan_hdd_qcmbr_ioctl(struct hdd_adapter *adapter, struct ifreq *ifr)
+{
+	struct qcmbr_data *qcmbr_data;
+	int ret = 0;
+
+	qcmbr_data = qdf_mem_malloc(sizeof(*qcmbr_data));
+	if (qcmbr_data == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(qcmbr_data, ifr->ifr_data, sizeof(*qcmbr_data))) {
+		ret = -EFAULT;
+		goto exit;
+	}
+
+	ret = wlan_hdd_qcmbr_command(adapter, qcmbr_data);
+	if ((ret == 0) && (qcmbr_data->cmd == 0x1001)) {
+		ret = copy_to_user(ifr->ifr_data, qcmbr_data->buf,
+				   (WLAN_FTM_DATA_MAX_LEN + 4));
+	}
+
+exit:
+	qdf_mem_free(qcmbr_data);
+	return ret;
+}
+
+/**
+ * wlan_hdd_qcmbr_unified_ioctl() - Unified QCMBR ioctl handler
+ * @adapter: adapter upon which the ioctl was received
+ * @ifr: the ioctl request
+ *
+ * Return: 0 on success, non-zero on error
+ */
+int wlan_hdd_qcmbr_unified_ioctl(struct hdd_adapter *adapter,
+				 struct ifreq *ifr)
+{
+	int ret = 0;
+
+	if (in_compat_syscall())
+		ret = wlan_hdd_qcmbr_compat_ioctl(adapter, ifr);
+	else
+		ret = wlan_hdd_qcmbr_ioctl(adapter, ifr);
+
+	return ret;
+}
+
+#endif /* LINUX_QCMBR */
+#endif /* QCA_WIFI_FTM */
diff --git a/core/hdd/src/wlan_hdd_green_ap.c b/core/hdd/src/wlan_hdd_green_ap.c
new file mode 100644
index 0000000..77ee425
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_green_ap.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_green_ap.c
+ *
+ *  WLAN Host Device Driver Green AP implementation
+ *
+ */
+
+#include <wlan_hdd_green_ap.h>
+#include <wlan_hdd_main.h>
+#include <wlan_policy_mgr_api.h>
+#include <wlan_green_ap_ucfg_api.h>
+#include "wlan_mlme_ucfg_api.h"
+
+/**
+ * hdd_green_ap_check_enable() - to check whether to enable green ap or not
+ * @hdd_ctx: hdd context
+ * @enable_green_ap: 1 - enable green ap enabled, 0 - disbale green ap
+ *
+ * Return: 0 - success, < 0 - failure
+ */
+static int hdd_green_ap_check_enable(struct hdd_context *hdd_ctx,
+				     bool *enable_green_ap)
+{
+	uint8_t num_sessions, mode;
+	QDF_STATUS status;
+
+	for (mode = 0;
+	     mode < QDF_MAX_NO_OF_MODE;
+	     mode++) {
+		if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
+			continue;
+
+		status = policy_mgr_mode_specific_num_active_sessions(
+					hdd_ctx->psoc, mode, &num_sessions);
+		hdd_debug("No. of active sessions for mode: %d is %d",
+			  mode, num_sessions);
+		if (status != QDF_STATUS_SUCCESS) {
+			hdd_err("Failed to get num sessions for mode: %d",
+				mode);
+			return -EINVAL;
+		} else if (num_sessions) {
+			*enable_green_ap = false;
+			return 0;
+		}
+	}
+	*enable_green_ap = true;
+	return 0;
+}
+
+void hdd_green_ap_add_sta(struct hdd_context *hdd_ctx)
+{
+	wlan_green_ap_add_sta(hdd_ctx->pdev);
+}
+
+void hdd_green_ap_del_sta(struct hdd_context *hdd_ctx)
+{
+	wlan_green_ap_del_sta(hdd_ctx->pdev);
+}
+
+int hdd_green_ap_enable_egap(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+
+	status = ucfg_green_ap_enable_egap(hdd_ctx->pdev);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_debug("enhance green ap is not enabled, status %d",
+			  status);
+		return qdf_status_to_os_return(status);
+	}
+
+	return 0;
+}
+
+int hdd_green_ap_start_state_mc(struct hdd_context *hdd_ctx,
+				enum QDF_OPMODE mode, bool is_session_start)
+{
+	struct hdd_config *cfg;
+	bool enable_green_ap = false;
+	uint8_t num_sap_sessions = 0, num_p2p_go_sessions = 0, ret = 0;
+	QDF_STATUS status;
+	bool bval = false;
+	uint8_t ps_enable;
+
+	cfg = hdd_ctx->config;
+	if (!cfg) {
+		hdd_err("NULL hdd config");
+		return -EINVAL;
+	}
+
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("unable to get vht_enable2x2");
+		return -EINVAL;
+	}
+
+	if (!bval) {
+		hdd_debug(" 2x2 not enabled");
+	}
+
+	if (QDF_IS_STATUS_ERROR(ucfg_green_ap_get_ps_config(hdd_ctx->pdev,
+							     &ps_enable)))
+		return 0;
+
+	if (!ps_enable) {
+		hdd_debug("Green AP not enabled");
+		return 0;
+	}
+
+	policy_mgr_mode_specific_num_active_sessions(hdd_ctx->psoc,
+						     QDF_SAP_MODE,
+						     &num_sap_sessions);
+	policy_mgr_mode_specific_num_active_sessions(hdd_ctx->psoc,
+						     QDF_P2P_GO_MODE,
+						     &num_p2p_go_sessions);
+
+	switch (mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_IBSS_MODE:
+		if (!num_sap_sessions && !num_p2p_go_sessions)
+			return 0;
+
+		if (is_session_start) {
+			hdd_debug("Disabling Green AP");
+			ucfg_green_ap_set_ps_config(hdd_ctx->pdev,
+						    false);
+			wlan_green_ap_stop(hdd_ctx->pdev);
+		} else {
+			ret = hdd_green_ap_check_enable(hdd_ctx,
+							&enable_green_ap);
+			if (!ret) {
+				if (enable_green_ap) {
+					hdd_debug("Enabling Green AP");
+					ucfg_green_ap_set_ps_config(
+						hdd_ctx->pdev, true);
+					wlan_green_ap_start(hdd_ctx->pdev);
+				}
+			} else {
+				hdd_err("Failed to check Green AP enable status");
+			}
+		}
+		break;
+	case QDF_SAP_MODE:
+	case QDF_P2P_GO_MODE:
+		if (is_session_start) {
+			ret = hdd_green_ap_check_enable(hdd_ctx,
+							&enable_green_ap);
+			if (!ret) {
+				if (enable_green_ap) {
+					hdd_debug("Enabling Green AP");
+					ucfg_green_ap_set_ps_config(
+						hdd_ctx->pdev, true);
+					wlan_green_ap_start(hdd_ctx->pdev);
+				}
+			} else {
+				hdd_err("Failed to check Green AP enable status");
+			}
+		} else {
+			if (!num_sap_sessions && !num_p2p_go_sessions) {
+				hdd_debug("Disabling Green AP");
+				ucfg_green_ap_set_ps_config(hdd_ctx->pdev,
+							    false);
+				wlan_green_ap_stop(hdd_ctx->pdev);
+			}
+		}
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
diff --git a/core/hdd/src/wlan_hdd_green_ap.h b/core/hdd/src/wlan_hdd_green_ap.h
new file mode 100644
index 0000000..1c2be8d
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_green_ap.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#if !defined(WLAN_HDD_GREEN_AP_H)
+#define WLAN_HDD_GREEN_AP_H
+
+#include "qdf_types.h"
+
+struct hdd_context;
+
+#ifdef WLAN_SUPPORT_GREEN_AP
+
+/**
+ * hdd_green_ap_add_sta() - Notify Green AP on STA association
+ * @hdd_ctx: Global HDD context
+ *
+ * Call this function when new node is associated
+ *
+ * Return: void
+ */
+void hdd_green_ap_add_sta(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_green_ap_del_sta() - Notify Green AP on STA disassociation
+ * @hdd_ctx: Global HDD context
+ *
+ * Call this function when new node is disassociated
+ *
+ * Return: void
+ */
+void hdd_green_ap_del_sta(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_green_ap_enable_egap() - Enable Enhanced Green AP
+ * @hdd_ctx: Global HDD context
+ *
+ * This function will enable the Enhanced Green AP feature if it is supported
+ * by the Green AP component.
+ *
+ * Return: 0 on success, negative errno on any failure
+ */
+int hdd_green_ap_enable_egap(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_green_ap_start_state_mc() - to start green AP state mc based on
+ *        present concurrency and state of green AP state machine.
+ * @hdd_ctx: hdd context
+ * @mode: device mode
+ * @is_session_start: BSS start/stop
+ *
+ * Return: 0 on success, negative errno on any failure
+ */
+int hdd_green_ap_start_state_mc(struct hdd_context *hdd_ctx,
+				enum QDF_OPMODE mode, bool is_session_start);
+
+#else /* WLAN_SUPPORT_GREEN_AP */
+static inline
+void hdd_green_ap_add_sta(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+void hdd_green_ap_del_sta(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+int hdd_green_ap_enable_egap(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+
+static inline
+int hdd_green_ap_update_config(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+
+static inline
+int hdd_green_ap_start_state_mc(struct hdd_context *hdd_ctx,
+				enum QDF_OPMODE mode, bool is_session_start)
+{
+	return 0;
+}
+
+#endif /* WLAN_SUPPORT_GREEN_AP */
+
+#endif /* !defined(WLAN_HDD_GREEN_AP_H) */
diff --git a/core/hdd/src/wlan_hdd_he.c b/core/hdd/src/wlan_hdd_he.c
new file mode 100644
index 0000000..67f01c1
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_he.c
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2017-2018 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 : wlan_hdd_he.c
+ *
+ * WLAN Host Device Driver file for 802.11ax (High Efficiency) support.
+ *
+ */
+
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_he.h"
+#include "wma_he.h"
+#include "wlan_utility.h"
+
+/**
+ * hdd_he_set_wni_cfg() - Update WNI CFG
+ * @hdd_ctx: HDD context
+ * @cfg_id: CFG to be updated
+ * @new_value: Value to be updated
+ *
+ * Update WNI CFG with the value passed.
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int hdd_he_set_wni_cfg(struct hdd_context *hdd_ctx,
+				     uint16_t cfg_id, uint32_t new_value)
+{
+	QDF_STATUS status;
+
+	status = sme_cfg_set_int(hdd_ctx->mac_handle, cfg_id, new_value);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("could not set %s", cfg_get_string(cfg_id));
+
+	return qdf_status_to_os_return(status);
+}
+
+void hdd_update_tgt_he_cap(struct hdd_context *hdd_ctx,
+			   struct wma_tgt_cfg *cfg)
+{
+	uint8_t chan_width;
+	QDF_STATUS status;
+	tDot11fIEhe_cap *he_cap = &cfg->he_cap;
+	tDot11fIEhe_cap he_cap_ini = {0};
+	uint8_t value = 0;
+	bool bval;
+
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CONTROL, he_cap->htc_he);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TWT_REQUESTOR,
+			   he_cap->twt_request);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TWT_RESPONDER,
+			   he_cap->twt_responder);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_FRAGMENTATION,
+			QDF_MIN(he_cap->fragmentation,
+				hdd_ctx->config->he_dynamic_frag_support));
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MAX_FRAG_MSDU,
+			   he_cap->max_num_frag_msdu_amsdu_exp);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MIN_FRAG_SIZE,
+			   he_cap->min_frag_size);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TRIG_PAD,
+			   he_cap->trigger_frm_mac_pad);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MTID_AGGR_RX,
+			   he_cap->multi_tid_aggr_rx_supp);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MTID_AGGR_TX,
+			   he_cap->multi_tid_aggr_tx_supp);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_LINK_ADAPTATION,
+			   he_cap->he_link_adaptation);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_ALL_ACK, he_cap->all_ack);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TRIGD_RSP_SCHEDULING,
+			   he_cap->trigd_rsp_sched);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BUFFER_STATUS_RPT,
+			   he_cap->a_bsr);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BCAST_TWT,
+			   he_cap->broadcast_twt);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BA_32BIT,
+			   he_cap->ba_32bit_bitmap);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MU_CASCADING,
+			   he_cap->mu_cascade);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MULTI_TID,
+			   he_cap->ack_enabled_multitid);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_OMI, he_cap->omi_a_ctrl);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_OFDMA_RA, he_cap->ofdma_ra);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MAX_AMPDU_LEN,
+			   he_cap->max_ampdu_len_exp_ext);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_AMSDU_FRAG, he_cap->amsdu_frag);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_FLEX_TWT_SCHED,
+			   he_cap->flex_twt_sched);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_CTRL, he_cap->rx_ctrl_frame);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BSRP_AMPDU_AGGR,
+			   he_cap->bsrp_ampdu_aggr);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_QTP, he_cap->qtp);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_A_BQR, he_cap->a_bqr);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SR_RESPONDER,
+			   he_cap->spatial_reuse_param_rspder);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NDP_FEEDBACK_SUPP,
+			   he_cap->ndp_feedback_supp);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_OPS_SUPP,
+			   he_cap->ops_supp);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_AMSDU_IN_AMPDU,
+			   he_cap->amsdu_in_ampdu);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SUB_CH_SEL_TX,
+			   he_cap->he_sub_ch_sel_tx_supp);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_UL_2X996_RU,
+			   he_cap->ul_2x996_tone_ru_supp);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX,
+			   he_cap->om_ctrl_ul_mu_data_dis_rx);
+	chan_width = HE_CH_WIDTH_COMBINE(he_cap->chan_width_0,
+				he_cap->chan_width_1, he_cap->chan_width_2,
+				he_cap->chan_width_3, he_cap->chan_width_4,
+				he_cap->chan_width_5, he_cap->chan_width_6);
+
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CHAN_WIDTH, chan_width);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_PREAM_PUNC,
+			   he_cap->rx_pream_puncturing);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CLASS_OF_DEVICE,
+			   he_cap->device_class);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_LDPC, he_cap->ldpc_coding);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_LTF_PPDU,
+			   he_cap->he_1x_ltf_800_gi_ppdu);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS,
+			   he_cap->midamble_tx_rx_max_nsts);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_LTF_NDP,
+			   he_cap->he_4x_ltf_3200_gi_ndp);
+
+	status = ucfg_mlme_cfg_get_vht_rx_stbc(hdd_ctx->psoc, &bval);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("unable to get vht_enable_rx_su_beam");
+
+	if (bval) {
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_STBC_LT80,
+				   he_cap->rx_stbc_lt_80mhz);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_STBC_GT80,
+				   he_cap->rx_stbc_gt_80mhz);
+	} else {
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_STBC_LT80, 0);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_STBC_GT80, 0);
+	}
+
+	status = ucfg_mlme_cfg_get_vht_tx_stbc(hdd_ctx->psoc,
+					       &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable_tx_su_beam");
+
+	if (bval) {
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TX_STBC_LT80,
+				   he_cap->tx_stbc_lt_80mhz);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TX_STBC_GT80,
+				   he_cap->tx_stbc_gt_80mhz);
+	} else {
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TX_STBC_LT80, 0);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TX_STBC_GT80, 0);
+	}
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DOPPLER, he_cap->doppler);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_UL_MUMIMO, he_cap->ul_mu);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DCM_TX, he_cap->dcm_enc_tx);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DCM_RX, he_cap->dcm_enc_rx);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MU_PPDU, he_cap->ul_he_mu);
+
+	status = ucfg_mlme_get_vht_tx_su_beamformer(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable_tx_su_beam");
+
+	if (bval) {
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SU_BEAMFORMER,
+				he_cap->su_beamformer);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NUM_SOUND_LT80,
+				he_cap->num_sounding_lt_80);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NUM_SOUND_GT80,
+				he_cap->num_sounding_gt_80);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MU_BEAMFORMER,
+				he_cap->mu_beamformer);
+	} else {
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SU_BEAMFORMER, 0);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NUM_SOUND_LT80, 0);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NUM_SOUND_GT80, 0);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MU_BEAMFORMER, 0);
+	}
+
+	status = ucfg_mlme_get_vht_enable_tx_bf(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable_tx_bf");
+	if (bval) {
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SU_BEAMFORMEE,
+				he_cap->su_beamformee);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BFEE_STS_LT80,
+				he_cap->bfee_sts_lt_80);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BFEE_STS_GT80,
+				he_cap->bfee_sts_gt_80);
+	} else {
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SU_BEAMFORMEE, 0);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BFEE_STS_LT80, 0);
+		hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BFEE_STS_GT80, 0);
+	}
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SU_FEED_TONE16,
+			   he_cap->su_feedback_tone16);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MU_FEED_TONE16,
+			   he_cap->mu_feedback_tone16);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CODEBOOK_SU,
+			   he_cap->codebook_su);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CODEBOOK_MU,
+			   he_cap->codebook_mu);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BFRM_FEED,
+			   he_cap->beamforming_feedback);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_ER_SU_PPDU,
+			   he_cap->he_er_su_ppdu);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DL_PART_BW,
+			   he_cap->dl_mu_mimo_part_bw);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_PPET_PRESENT,
+			   he_cap->ppet_present);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SRP, he_cap->srp);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_POWER_BOOST,
+			   he_cap->power_boost);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_4x_LTF_GI,
+			   he_cap->he_ltf_800_gi_4x);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MAX_NC, he_cap->max_nc);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_ER_4x_LTF_GI,
+			   he_cap->er_he_ltf_800_gi_4x);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_PPDU_20_IN_40MHZ_2G,
+			   he_cap->he_ppdu_20_in_40Mhz_2G);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ,
+			   he_cap->he_ppdu_20_in_160_80p80Mhz);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ,
+			   he_cap->he_ppdu_80_in_160_80p80Mhz);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_ER_1X_HE_LTF_GI,
+			   he_cap->er_1x_he_ltf_gi);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF,
+			   he_cap->midamble_tx_rx_1x_he_ltf);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DCM_MAX_BW,
+			   he_cap->dcm_max_bw);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM,
+			   he_cap->longer_than_16_he_sigb_ofdm_sym);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TX_1024_QAM_LT_242_RU,
+			   he_cap->tx_1024_qam_lt_242_tone_ru);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_1024_QAM_LT_242_RU,
+			   he_cap->rx_1024_qam_lt_242_tone_ru);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NON_TRIG_CQI_FEEDBACK,
+			   he_cap->non_trig_cqi_feedback);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB,
+			   he_cap->rx_full_bw_su_he_mu_compress_sigb);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB,
+			   he_cap->rx_full_bw_su_he_mu_non_cmpr_sigb);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_MCS_MAP_LT_80,
+			he_cap->rx_he_mcs_map_lt_80);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TX_MCS_MAP_LT_80,
+			he_cap->tx_he_mcs_map_lt_80);
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_MCS_MAP_160,
+		*((uint16_t *)he_cap->rx_he_mcs_map_160));
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TX_MCS_MAP_160,
+		*((uint16_t *)he_cap->tx_he_mcs_map_160));
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_MCS_MAP_80_80,
+		*((uint16_t *)he_cap->rx_he_mcs_map_80_80));
+	hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TX_MCS_MAP_80_80,
+		*((uint16_t *)he_cap->tx_he_mcs_map_80_80));
+
+	/* PPET can not be configured by user - Set per band values from FW */
+	status = sme_cfg_set_str(hdd_ctx->mac_handle, WNI_CFG_HE_PPET_2G,
+				 cfg->ppet_2g, HE_MAX_PPET_SIZE);
+	if (status == QDF_STATUS_E_FAILURE)
+		hdd_alert("could not set 2G HE PPET");
+
+	status = sme_cfg_set_str(hdd_ctx->mac_handle, WNI_CFG_HE_PPET_5G,
+				 cfg->ppet_5g, HE_MAX_PPET_SIZE);
+	if (status == QDF_STATUS_E_FAILURE)
+		hdd_alert("could not set 5G HE PPET");
+
+	status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
+							&value);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get tx_bfee_ant_supp");
+
+	he_cap_ini.bfee_sts_lt_80 = value;
+	sme_update_tgt_he_cap(hdd_ctx->mac_handle, cfg, &he_cap_ini);
+}
+
+void wlan_hdd_check_11ax_support(struct hdd_beacon_data *beacon,
+				 tsap_config_t *config)
+{
+	const uint8_t *ie;
+
+	ie = wlan_get_ext_ie_ptr_from_ext_id(HE_CAP_OUI_TYPE, HE_CAP_OUI_SIZE,
+					    beacon->tail, beacon->tail_len);
+	if (ie)
+		config->SapHw_mode = eCSR_DOT11_MODE_11ax;
+}
+
+int hdd_update_he_cap_in_cfg(struct hdd_context *hdd_ctx)
+{
+	uint32_t val, val1 = 0;
+	QDF_STATUS status;
+	int ret;
+	struct hdd_config *config = hdd_ctx->config;
+
+	ret = hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_STA_OBSSPD,
+				 config->he_sta_obsspd);
+	if (ret)
+		return ret;
+
+	status = sme_cfg_get_int(hdd_ctx->mac_handle,
+				 WNI_CFG_HE_UL_MUMIMO, &val);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("could not get WNI_CFG_HE_UL_MUMIMO");
+		return qdf_status_to_os_return(status);
+	}
+
+	/* In val,
+	 * Bit 1 - corresponds to UL MIMO
+	 * Bit 2 - corresponds to UL OFDMA
+	 */
+	if (val & 0x1)
+		val1 = config->enable_ul_mimo & 0x1;
+
+	if ((val >> 1) & 0x1)
+		val1 |= ((config->enable_ul_ofdma & 0x1) << 1);
+
+	ret = hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_UL_MUMIMO, val1);
+
+	return ret;
+}
+
+void hdd_he_set_sme_config(tSmeConfigParams *sme_config,
+			   struct hdd_config *config)
+{
+	sme_config->csrConfig.enable_ul_ofdma = config->enable_ul_ofdma;
+	sme_config->csrConfig.enable_ul_mimo = config->enable_ul_mimo;
+}
+
+/*
+ * __wlan_hdd_cfg80211_get_he_cap() - get HE Capabilities
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 if success, non-zero for failure
+ */
+static int
+__wlan_hdd_cfg80211_get_he_cap(struct wiphy *wiphy,
+			       struct wireless_dev *wdev,
+			       const void *data,
+			       int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int ret;
+	QDF_STATUS status;
+	struct sk_buff *reply_skb;
+	uint32_t nl_buf_len;
+	struct he_capability he_cap;
+	uint8_t he_supported = 0;
+
+	hdd_enter();
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	nl_buf_len = NLMSG_HDRLEN;
+	if (sme_is_feature_supported_by_fw(DOT11AX)) {
+		he_supported = 1;
+
+		status = wma_get_he_capabilities(&he_cap);
+		if (QDF_STATUS_SUCCESS != status)
+			return -EINVAL;
+	} else {
+		hdd_info("11AX: HE not supported, send only QCA_WLAN_VENDOR_ATTR_HE_SUPPORTED");
+	}
+
+	if (he_supported) {
+		nl_buf_len += NLA_HDRLEN + sizeof(he_supported) +
+			      NLA_HDRLEN + sizeof(he_cap.phy_cap) +
+			      NLA_HDRLEN + sizeof(he_cap.mac_cap) +
+			      NLA_HDRLEN + sizeof(he_cap.mcs) +
+			      NLA_HDRLEN + sizeof(he_cap.ppet.numss_m1) +
+			      NLA_HDRLEN + sizeof(he_cap.ppet.ru_bit_mask) +
+			      NLA_HDRLEN +
+				sizeof(he_cap.ppet.ppet16_ppet8_ru3_ru0);
+	} else {
+		nl_buf_len += NLA_HDRLEN + sizeof(he_supported);
+	}
+
+	hdd_info("11AX: he_supported: %d", he_supported);
+
+	reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, nl_buf_len);
+
+	if (!reply_skb) {
+		hdd_err("Allocate reply_skb failed");
+		return -EINVAL;
+	}
+
+	if (nla_put_u8(reply_skb,
+		       QCA_WLAN_VENDOR_ATTR_HE_SUPPORTED, he_supported))
+		goto nla_put_failure;
+
+	/* No need to populate other attributes if HE is not supported */
+	if (0 == he_supported)
+		goto end;
+
+	if (nla_put_u32(reply_skb,
+			QCA_WLAN_VENDOR_ATTR_MAC_CAPAB, he_cap.mac_cap) ||
+	    nla_put_u32(reply_skb,
+			QCA_WLAN_VENDOR_ATTR_HE_MCS, he_cap.mcs) ||
+	    nla_put_u32(reply_skb,
+			QCA_WLAN_VENDOR_ATTR_NUM_SS, he_cap.ppet.numss_m1) ||
+	    nla_put_u32(reply_skb,
+			QCA_WLAN_VENDOR_ATTR_RU_IDX_MASK,
+			he_cap.ppet.ru_bit_mask) ||
+	    nla_put(reply_skb,
+		    QCA_WLAN_VENDOR_ATTR_PHY_CAPAB,
+		    sizeof(u32) * HE_MAX_PHY_CAP_SIZE, he_cap.phy_cap) ||
+	    nla_put(reply_skb, QCA_WLAN_VENDOR_ATTR_PPE_THRESHOLD,
+		    sizeof(u32) * PSOC_HOST_MAX_NUM_SS,
+		    he_cap.ppet.ppet16_ppet8_ru3_ru0))
+		goto nla_put_failure;
+end:
+	ret = cfg80211_vendor_cmd_reply(reply_skb);
+	hdd_exit();
+	return ret;
+
+nla_put_failure:
+	hdd_err("nla put fail");
+	kfree_skb(reply_skb);
+	return -EINVAL;
+}
+
+int wlan_hdd_cfg80211_get_he_cap(struct wiphy *wiphy,
+				 struct wireless_dev *wdev,
+				 const void *data,
+				 int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_he_cap(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
new file mode 100644
index 0000000..2229919
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -0,0 +1,6120 @@
+/*
+ * Copyright (c) 2012-2018 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:  wlan_hdd_hostapd.c
+ *
+ * WLAN Host Device Driver implementation
+ */
+
+/* Include Files */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/wireless.h>
+#include <linux/semaphore.h>
+#include <linux/compat.h>
+#include <cdp_txrx_cmn.h>
+#include <cds_api.h>
+#include <cds_sched.h>
+#include <linux/etherdevice.h>
+#include <wlan_hdd_includes.h>
+#include <qc_sap_ioctl.h>
+#include <wlan_hdd_hostapd.h>
+#include <wlan_hdd_hostapd_wext.h>
+#include <wlan_hdd_green_ap.h>
+#include <sap_api.h>
+#include <sap_internal.h>
+#include <wlan_hdd_softap_tx_rx.h>
+#include <wlan_hdd_main.h>
+#include <wlan_hdd_ioctl.h>
+#include <wlan_hdd_stats.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/mmc/sdio_func.h>
+#include "wlan_hdd_p2p.h"
+#include <wlan_hdd_ipa.h>
+#include "cfg_api.h"
+#include "wni_cfg.h"
+#include "wlan_hdd_misc.h"
+#include <cds_utils.h>
+#include "pld_common.h"
+#include "wma.h"
+#ifdef WLAN_DEBUG
+#include "wma_api.h"
+#endif
+#include "wlan_hdd_trace.h"
+#include "qdf_str.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "wlan_hdd_cfg.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_hdd_tsf.h"
+#include <cdp_txrx_misc.h>
+#include "wlan_hdd_object_manager.h"
+#include <qca_vendor.h>
+#include <cds_api.h>
+#include "wlan_hdd_he.h"
+#include "wlan_dfs_tgt_api.h"
+#include <wlan_reg_ucfg_api.h>
+#include "wlan_utility.h"
+#include <wlan_p2p_ucfg_api.h>
+#include "sir_api.h"
+#include "wlan_policy_mgr_ucfg.h"
+#include "sme_api.h"
+#include "wlan_hdd_regulatory.h"
+#include <wlan_ipa_ucfg_api.h>
+#include <wlan_cp_stats_mc_ucfg_api.h>
+#include "wlan_mlme_ucfg_api.h"
+#include "cfg_ucfg_api.h"
+
+#define ACS_SCAN_EXPIRY_TIMEOUT_S 4
+
+/*
+ * 11B, 11G Rate table include Basic rate and Extended rate
+ * The IDX field is the rate index
+ * The HI field is the rate when RSSI is strong or being ignored
+ * (in this case we report actual rate)
+ * The MID field is the rate when RSSI is moderate
+ * (in this case we cap 11b rates at 5.5 and 11g rates at 24)
+ * The LO field is the rate when RSSI is low
+ * (in this case we don't report rates, actual current rate used)
+ */
+static const struct index_data_rate_type supported_data_rate[] = {
+	/* IDX     HI  HM  LM LO (RSSI-based index */
+	{2,   { 10,  10, 10, 0} },
+	{4,   { 20,  20, 10, 0} },
+	{11,  { 55,  20, 10, 0} },
+	{12,  { 60,  55, 20, 0} },
+	{18,  { 90,  55, 20, 0} },
+	{22,  {110,  55, 20, 0} },
+	{24,  {120,  90, 60, 0} },
+	{36,  {180, 120, 60, 0} },
+	{44,  {220, 180, 60, 0} },
+	{48,  {240, 180, 90, 0} },
+	{66,  {330, 180, 90, 0} },
+	{72,  {360, 240, 90, 0} },
+	{96,  {480, 240, 120, 0} },
+	{108, {540, 240, 120, 0} }
+};
+
+/* MCS Based rate table */
+/* HT MCS parameters with Nss = 1 */
+static const struct index_data_rate_type supported_mcs_rate_nss1[] = {
+	/* MCS  L20   L40   S20  S40 */
+	{0,  { 65,  135,  72,  150} },
+	{1,  { 130, 270,  144, 300} },
+	{2,  { 195, 405,  217, 450} },
+	{3,  { 260, 540,  289, 600} },
+	{4,  { 390, 810,  433, 900} },
+	{5,  { 520, 1080, 578, 1200} },
+	{6,  { 585, 1215, 650, 1350} },
+	{7,  { 650, 1350, 722, 1500} }
+};
+
+/* HT MCS parameters with Nss = 2 */
+static const struct index_data_rate_type supported_mcs_rate_nss2[] = {
+	/* MCS  L20    L40   S20   S40 */
+	{0,  {130,  270,  144,  300} },
+	{1,  {260,  540,  289,  600} },
+	{2,  {390,  810,  433,  900} },
+	{3,  {520,  1080, 578,  1200} },
+	{4,  {780,  1620, 867,  1800} },
+	{5,  {1040, 2160, 1156, 2400} },
+	{6,  {1170, 2430, 1300, 2700} },
+	{7,  {1300, 2700, 1444, 3000} }
+};
+
+/* MCS Based VHT rate table */
+/* MCS parameters with Nss = 1*/
+static const struct index_vht_data_rate_type supported_vht_mcs_rate_nss1[] = {
+	/* MCS  L80    S80     L40   S40    L20   S40*/
+	{0,  {293,  325},  {135,  150},  {65,   72} },
+	{1,  {585,  650},  {270,  300},  {130,  144} },
+	{2,  {878,  975},  {405,  450},  {195,  217} },
+	{3,  {1170, 1300}, {540,  600},  {260,  289} },
+	{4,  {1755, 1950}, {810,  900},  {390,  433} },
+	{5,  {2340, 2600}, {1080, 1200}, {520,  578} },
+	{6,  {2633, 2925}, {1215, 1350}, {585,  650} },
+	{7,  {2925, 3250}, {1350, 1500}, {650,  722} },
+	{8,  {3510, 3900}, {1620, 1800}, {780,  867} },
+	{9,  {3900, 4333}, {1800, 2000}, {780,  867} }
+};
+
+/*MCS parameters with Nss = 2*/
+static const struct index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = {
+	/* MCS  L80    S80     L40   S40    L20   S40*/
+	{0,  {585,  650},  {270,  300},  {130,  144} },
+	{1,  {1170, 1300}, {540,  600},  {260,  289} },
+	{2,  {1755, 1950}, {810,  900},  {390,  433} },
+	{3,  {2340, 2600}, {1080, 1200}, {520,  578} },
+	{4,  {3510, 3900}, {1620, 1800}, {780,  867} },
+	{5,  {4680, 5200}, {2160, 2400}, {1040, 1156} },
+	{6,  {5265, 5850}, {2430, 2700}, {1170, 1300} },
+	{7,  {5850, 6500}, {2700, 3000}, {1300, 1444} },
+	{8,  {7020, 7800}, {3240, 3600}, {1560, 1733} },
+	{9,  {7800, 8667}, {3600, 4000}, {1560, 1733} }
+};
+
+/* Function definitions */
+
+/**
+ * hdd_sap_context_init() - Initialize SAP context.
+ * @hdd_ctx:	HDD context.
+ *
+ * Initialize SAP context.
+ *
+ * Return: 0 on success.
+ */
+int hdd_sap_context_init(struct hdd_context *hdd_ctx)
+{
+	qdf_wake_lock_create(&hdd_ctx->sap_dfs_wakelock, "sap_dfs_wakelock");
+	atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0);
+
+	mutex_init(&hdd_ctx->sap_lock);
+	qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock");
+	qdf_spinlock_create(&hdd_ctx->sap_update_info_lock);
+
+	return 0;
+}
+
+/**
+ * hdd_hostapd_init_sap_session() - To init the sap session completely
+ * @adapter: SAP/GO adapter
+ * @reinit: if called as part of reinit
+ *
+ * This API will do
+ * 1) sap_init_ctx()
+ *
+ * Return: 0 if success else non-zero value.
+ */
+static struct sap_context *
+hdd_hostapd_init_sap_session(struct hdd_adapter *adapter, bool reinit)
+{
+	struct sap_context *sap_ctx;
+	QDF_STATUS status;
+
+	if (!adapter) {
+		hdd_err("invalid adapter");
+		return NULL;
+	}
+
+	sap_ctx = adapter->session.ap.sap_context;
+
+	if (!sap_ctx) {
+		hdd_err("can't allocate the sap_ctx");
+		return NULL;
+	}
+	status = sap_init_ctx(sap_ctx, adapter->device_mode,
+			       adapter->mac_addr.bytes,
+			       adapter->session_id, reinit);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("wlansap_start failed!! status: %d", status);
+		adapter->session.ap.sap_context = NULL;
+		goto error;
+	}
+	return sap_ctx;
+error:
+	wlansap_context_put(sap_ctx);
+	hdd_err("releasing the sap context for session-id:%d",
+		adapter->session_id);
+
+	return NULL;
+}
+
+/**
+ * hdd_hostapd_deinit_sap_session() - To de-init the sap session completely
+ * @adapter: SAP/GO adapter
+ *
+ * This API will do
+ * 1) sap_init_ctx()
+ * 2) sap_destroy_ctx()
+ *
+ * Return: 0 if success else non-zero value.
+ */
+static int hdd_hostapd_deinit_sap_session(struct hdd_adapter *adapter)
+{
+	struct sap_context *sap_ctx;
+	int status = 0;
+
+	if (!adapter) {
+		hdd_err("invalid adapter");
+		return -EINVAL;
+	}
+
+	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
+	if (!sap_ctx) {
+		hdd_debug("sap context already released, nothing to be done");
+		return 0;
+	}
+
+	if (!QDF_IS_STATUS_SUCCESS(sap_deinit_ctx(sap_ctx))) {
+		hdd_err("Error stopping the sap session");
+		status = -EINVAL;
+	}
+
+	if (!QDF_IS_STATUS_SUCCESS(sap_destroy_ctx(sap_ctx))) {
+		hdd_err("Error closing the sap session");
+		status = -EINVAL;
+	}
+	adapter->session.ap.sap_context = NULL;
+
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_debug("sap has issue closing the session");
+	else
+		hdd_debug("sap has been closed successfully");
+
+
+	return status;
+}
+
+/**
+ * hdd_hostapd_channel_allow_suspend() - allow suspend in a channel.
+ * Called when, 1. bss stopped, 2. channel switch
+ *
+ * @adapter: pointer to hdd adapter
+ * @channel: current channel
+ *
+ * Return: None
+ */
+static void hdd_hostapd_channel_allow_suspend(struct hdd_adapter *adapter,
+					      uint8_t channel)
+{
+
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_hostapd_state *hostapd_state =
+		WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+
+	hdd_debug("bss_state: %d, channel: %d, dfs_ref_cnt: %d",
+	       hostapd_state->bss_state, channel,
+	       atomic_read(&hdd_ctx->sap_dfs_ref_cnt));
+
+	/* Return if BSS is already stopped */
+	if (hostapd_state->bss_state == BSS_STOP)
+		return;
+
+	if (wlan_reg_get_channel_state(hdd_ctx->pdev, channel) !=
+	    CHANNEL_STATE_DFS)
+		return;
+
+	/* Release wakelock when no more DFS channels are used */
+	if (atomic_dec_and_test(&hdd_ctx->sap_dfs_ref_cnt)) {
+		hdd_err("DFS: allowing suspend (chan: %d)", channel);
+		qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock,
+				      WIFI_POWER_EVENT_WAKELOCK_DFS);
+		qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.dfs);
+
+	}
+}
+
+/**
+ * hdd_hostapd_channel_prevent_suspend() - prevent suspend in a channel.
+ * Called when, 1. bss started, 2. channel switch
+ *
+ * @adapter: pointer to hdd adapter
+ * @channel: current channel
+ *
+ * Return - None
+ */
+static void hdd_hostapd_channel_prevent_suspend(struct hdd_adapter *adapter,
+						uint8_t channel)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_hostapd_state *hostapd_state =
+		WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+
+	hdd_debug("bss_state: %d, channel: %d, dfs_ref_cnt: %d",
+	       hostapd_state->bss_state, channel,
+	       atomic_read(&hdd_ctx->sap_dfs_ref_cnt));
+
+	/* Return if BSS is already started && wakelock is acquired */
+	if ((hostapd_state->bss_state == BSS_START) &&
+		(atomic_read(&hdd_ctx->sap_dfs_ref_cnt) >= 1))
+		return;
+
+	if (wlan_reg_get_channel_state(hdd_ctx->pdev, channel) !=
+	    CHANNEL_STATE_DFS)
+		return;
+
+	/* Acquire wakelock if we have at least one DFS channel in use */
+	if (atomic_inc_return(&hdd_ctx->sap_dfs_ref_cnt) == 1) {
+		hdd_err("DFS: preventing suspend (chan: %d)", channel);
+		qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.dfs);
+		qdf_wake_lock_acquire(&hdd_ctx->sap_dfs_wakelock,
+				      WIFI_POWER_EVENT_WAKELOCK_DFS);
+	}
+}
+
+/**
+ * hdd_sap_context_destroy() - Destroy SAP context
+ *
+ * @hdd_ctx:	HDD context.
+ *
+ * Destroy SAP context.
+ *
+ * Return: None
+ */
+void hdd_sap_context_destroy(struct hdd_context *hdd_ctx)
+{
+	if (atomic_read(&hdd_ctx->sap_dfs_ref_cnt)) {
+		qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock,
+				      WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT);
+
+		atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0);
+		hdd_debug("DFS: Allowing suspend");
+	}
+
+	qdf_wake_lock_destroy(&hdd_ctx->sap_dfs_wakelock);
+
+	mutex_destroy(&hdd_ctx->sap_lock);
+	qdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock);
+
+	qdf_spinlock_destroy(&hdd_ctx->sap_update_info_lock);
+
+}
+
+/**
+ * __hdd_hostapd_open() - hdd open function for hostapd interface
+ * This is called in response to ifconfig up
+ * @dev: pointer to net_device structure
+ *
+ * Return - 0 for success non-zero for failure
+ */
+static int __hdd_hostapd_open(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = netdev_priv(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
+	/* Nothing to be done if device is unloading */
+	if (cds_is_driver_unloading()) {
+		hdd_err("Driver is unloading can not open the hdd");
+		return -EBUSY;
+	}
+
+	if (cds_is_driver_recovering()) {
+		hdd_err("WLAN is currently recovering; Please try again.");
+		return -EBUSY;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+	/*
+	 * Check statemachine state and also stop iface change timer if running
+	 */
+	ret = hdd_wlan_start_modules(hdd_ctx, false);
+
+	if (ret) {
+		hdd_err("Failed to start WLAN modules return");
+		return ret;
+	}
+
+	ret = hdd_start_adapter(adapter);
+	if (ret) {
+		hdd_err("Error Initializing the AP mode: %d", ret);
+		return ret;
+	}
+
+	set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
+
+	/* Enable all Tx queues */
+	hdd_debug("Enabling queues");
+	wlan_hdd_netif_queue_control(adapter,
+				   WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
+				   WLAN_CONTROL_PATH);
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * hdd_hostapd_open() - SSR wrapper for __hdd_hostapd_open
+ * @dev: pointer to net device
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int hdd_hostapd_open(struct net_device *dev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_hostapd_open(dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __hdd_hostapd_stop() - hdd stop function for hostapd interface
+ * This is called in response to ifconfig down
+ *
+ * @dev: pointer to net_device structure
+ *
+ * Return - 0 for success non-zero for failure
+ */
+static int __hdd_hostapd_stop(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int ret;
+
+	hdd_enter_dev(dev);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret) {
+		set_bit(DOWN_DURING_SSR, &adapter->event_flags);
+		return ret;
+	}
+
+	/*
+	 * Some tests requires to do "ifconfig down" only to bring
+	 * down the SAP/GO without killing hostapd/wpa_supplicant.
+	 * In such case, user will do "ifconfig up" to bring-back
+	 * the SAP/GO session. to fulfill this requirement, driver
+	 * needs to de-init the sap session here and re-init when
+	 * __hdd_hostapd_open() API
+	 */
+	hdd_stop_adapter(hdd_ctx, adapter);
+	hdd_deinit_adapter(hdd_ctx, adapter, true);
+	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
+
+	if (!hdd_is_cli_iface_up(hdd_ctx))
+		sme_scan_flush_result(hdd_ctx->mac_handle);
+
+	/* Stop all tx queues */
+	hdd_debug("Disabling queues");
+	wlan_hdd_netif_queue_control(adapter,
+				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+				     WLAN_CONTROL_PATH);
+
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * hdd_hostapd_stop() - SSR wrapper for__hdd_hostapd_stop
+ * @dev: pointer to net_device
+ *
+ * This is called in response to ifconfig down
+ *
+ * Return: 0 on success, error number otherwise
+ */
+int hdd_hostapd_stop(struct net_device *dev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_hostapd_stop(dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __hdd_hostapd_uninit() - hdd uninit function
+ * This is called during the netdev unregister to uninitialize all data
+ * associated with the device.
+ *
+ * @dev: pointer to net_device structure
+ *
+ * Return: None
+ */
+static void __hdd_hostapd_uninit(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = netdev_priv(dev);
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter_dev(dev);
+
+	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
+		hdd_err("Invalid magic");
+		return;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (NULL == hdd_ctx) {
+		hdd_err("NULL hdd_ctx");
+		return;
+	}
+
+	hdd_deinit_adapter(hdd_ctx, adapter, true);
+
+	/* after uninit our adapter structure will no longer be valid */
+	adapter->dev = NULL;
+	adapter->magic = 0;
+
+	hdd_exit();
+}
+
+/**
+ * hdd_hostapd_uninit() - SSR wrapper for __hdd_hostapd_uninit
+ * @dev: pointer to net_device
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static void hdd_hostapd_uninit(struct net_device *dev)
+{
+	cds_ssr_protect(__func__);
+	__hdd_hostapd_uninit(dev);
+	cds_ssr_unprotect(__func__);
+}
+
+/**
+ * __hdd_hostapd_change_mtu() - change mtu
+ * @dev: pointer to net_device
+ * @new_mtu: new mtu
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
+{
+	hdd_enter_dev(dev);
+
+	return 0;
+}
+
+/**
+ * hdd_hostapd_change_mtu() - SSR wrapper for __hdd_hostapd_change_mtu
+ * @dev: pointer to net_device
+ * @new_mtu: new mtu
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_hostapd_change_mtu(dev, new_mtu);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef QCA_HT_2040_COEX
+QDF_STATUS hdd_set_sap_ht2040_mode(struct hdd_adapter *adapter,
+				   uint8_t channel_type)
+{
+	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
+	mac_handle_t mac_handle;
+
+	hdd_debug("change HT20/40 mode");
+
+	if (QDF_SAP_MODE == adapter->device_mode) {
+		mac_handle = adapter->hdd_ctx->mac_handle;
+		if (!mac_handle) {
+			hdd_err("mac handle is null");
+			return QDF_STATUS_E_FAULT;
+		}
+		qdf_ret_status =
+			sme_set_ht2040_mode(mac_handle, adapter->session_id,
+					    channel_type, true);
+		if (qdf_ret_status == QDF_STATUS_E_FAILURE) {
+			hdd_err("Failed to change HT20/40 mode");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * __hdd_hostapd_set_mac_address() -
+ * This function sets the user specified mac address using
+ * the command ifconfig wlanX hw ether <mac address>.
+ *
+ * @dev: pointer to the net device.
+ * @addr: pointer to the sockaddr.
+ *
+ * Return: 0 for success, non zero for failure
+ */
+static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct sockaddr *psta_mac_addr = addr;
+	struct hdd_adapter *adapter, *adapter_temp;
+	struct hdd_context *hdd_ctx;
+	int ret = 0;
+	struct qdf_mac_addr mac_addr;
+
+	hdd_enter_dev(dev);
+
+	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
+	adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
+	if (adapter_temp) {
+		if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
+			return 0;
+		hdd_err("%s adapter exist with same address " MAC_ADDRESS_STR,
+			adapter_temp->dev->name,
+			MAC_ADDR_ARRAY(mac_addr.bytes));
+		return -EINVAL;
+	}
+
+	if (qdf_is_macaddr_zero(&mac_addr)) {
+		hdd_err("MAC is all zero");
+		return -EINVAL;
+	}
+
+	if (qdf_is_macaddr_broadcast(&mac_addr)) {
+		hdd_err("MAC is Broadcast");
+		return -EINVAL;
+	}
+
+	if (ETHER_IS_MULTICAST(psta_mac_addr->sa_data)) {
+		hdd_err("MAC is Multicast");
+		return -EINVAL;
+	}
+
+	hdd_info("Changing MAC to " MAC_ADDRESS_STR " of interface %s ",
+		 MAC_ADDR_ARRAY(mac_addr.bytes),
+		 dev->name);
+	hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
+	memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
+	memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * hdd_hostapd_set_mac_address() - set mac address
+ * @dev: pointer to net_device
+ * @addr: mac address
+ *
+ * Return: 0 on success, error number otherwise
+ */
+static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_hostapd_set_mac_address(dev, addr);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static void hdd_clear_sta(struct hdd_adapter *adapter, uint8_t sta_id)
+{
+	struct hdd_ap_ctx *ap_ctx;
+	struct hdd_station_info *sta_info;
+	struct csr_del_sta_params del_sta_params;
+
+	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+
+	if (sta_id == ap_ctx->broadcast_sta_id)
+		return;
+
+	sta_info = &adapter->sta_info[sta_id];
+	if (!sta_info->in_use)
+		return;
+
+	wlansap_populate_del_sta_params(sta_info->sta_mac.bytes,
+					eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
+					(SIR_MAC_MGMT_DISASSOC >> 4),
+					&del_sta_params);
+
+	hdd_softap_sta_disassoc(adapter, &del_sta_params);
+}
+
+static void hdd_clear_all_sta(struct hdd_adapter *adapter)
+{
+	uint8_t sta_id;
+
+	hdd_enter_dev(adapter->dev);
+	for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++)
+		hdd_clear_sta(adapter, sta_id);
+}
+
+static int hdd_stop_bss_link(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx;
+	int errno;
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
+		status = wlansap_stop_bss(
+			WLAN_HDD_GET_SAP_CTX_PTR(adapter));
+		if (QDF_IS_STATUS_SUCCESS(status))
+			hdd_debug("Deleting SAP/P2P link!!!!!!");
+
+		clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
+		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
+					adapter->device_mode,
+					adapter->session_id);
+		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
+		errno = (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY;
+	}
+	hdd_exit();
+	return errno;
+}
+
+/**
+ * hdd_chan_change_notify() - Function to notify hostapd about channel change
+ * @hostapd_adapter:	hostapd adapter
+ * @dev:		Net device structure
+ * @chan_change:	New channel change parameters
+ * @legacy_phymode:	is the phymode legacy
+ *
+ * This function is used to notify hostapd about the channel change
+ *
+ * Return: Success on intimating userspace
+ *
+ */
+QDF_STATUS hdd_chan_change_notify(struct hdd_adapter *adapter,
+		struct net_device *dev,
+		struct hdd_chan_change_params chan_change,
+		bool legacy_phymode)
+{
+	struct ieee80211_channel *chan;
+	struct cfg80211_chan_def chandef;
+	enum nl80211_channel_type channel_type;
+	uint32_t freq;
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+
+	if (!mac_handle) {
+		hdd_err("mac_handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hdd_debug("chan:%d width:%d sec_ch_offset:%d seg0:%d seg1:%d",
+		chan_change.chan, chan_change.chan_params.ch_width,
+		chan_change.chan_params.sec_ch_offset,
+		chan_change.chan_params.center_freq_seg0,
+		chan_change.chan_params.center_freq_seg1);
+
+	freq = cds_chan_to_freq(chan_change.chan);
+
+	chan = ieee80211_get_channel(adapter->wdev.wiphy, freq);
+
+	if (!chan) {
+		hdd_err("Invalid input frequency for channel conversion");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (legacy_phymode) {
+		channel_type = NL80211_CHAN_NO_HT;
+	} else {
+		switch (chan_change.chan_params.sec_ch_offset) {
+		case PHY_SINGLE_CHANNEL_CENTERED:
+			channel_type = NL80211_CHAN_HT20;
+			break;
+		case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+			channel_type = NL80211_CHAN_HT40MINUS;
+			break;
+		case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+			channel_type = NL80211_CHAN_HT40PLUS;
+			break;
+		default:
+			channel_type = NL80211_CHAN_NO_HT;
+			break;
+		}
+	}
+
+	cfg80211_chandef_create(&chandef, chan, channel_type);
+
+	/* cfg80211_chandef_create() does update of width and center_freq1
+	 * only for NL80211_CHAN_NO_HT, NL80211_CHAN_HT20, NL80211_CHAN_HT40PLUS
+	 * and NL80211_CHAN_HT40MINUS.
+	 */
+	if (chan_change.chan_params.ch_width == CH_WIDTH_80MHZ)
+		chandef.width = NL80211_CHAN_WIDTH_80;
+	else if (chan_change.chan_params.ch_width == CH_WIDTH_80P80MHZ)
+		chandef.width = NL80211_CHAN_WIDTH_80P80;
+	else if (chan_change.chan_params.ch_width == CH_WIDTH_160MHZ)
+		chandef.width = NL80211_CHAN_WIDTH_160;
+
+	if ((chan_change.chan_params.ch_width == CH_WIDTH_80MHZ) ||
+	    (chan_change.chan_params.ch_width == CH_WIDTH_80P80MHZ) ||
+	    (chan_change.chan_params.ch_width == CH_WIDTH_160MHZ)) {
+		if (chan_change.chan_params.center_freq_seg0)
+			chandef.center_freq1 = cds_chan_to_freq(
+				chan_change.chan_params.center_freq_seg0);
+
+		if (chan_change.chan_params.center_freq_seg1)
+			chandef.center_freq2 = cds_chan_to_freq(
+				chan_change.chan_params.center_freq_seg1);
+	}
+
+	hdd_debug("notify: chan:%d width:%d freq1:%d freq2:%d",
+		chandef.chan->center_freq, chandef.width, chandef.center_freq1,
+		chandef.center_freq2);
+
+	cfg80211_ch_switch_notify(dev, &chandef);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_send_radar_event() - Function to send radar events to user space
+ * @hdd_context:	HDD context
+ * @event:		Type of radar event
+ * @dfs_info:		Structure containing DFS channel and country
+ * @wdev:		Wireless device structure
+ *
+ * This function is used to send radar events such as CAC start, CAC
+ * end etc., to userspace
+ *
+ * Return: Success on sending notifying userspace
+ *
+ */
+static QDF_STATUS hdd_send_radar_event(struct hdd_context *hdd_context,
+				       eSapHddEvent event,
+				       struct wlan_dfs_info dfs_info,
+				       struct wireless_dev *wdev)
+{
+
+	struct sk_buff *vendor_event;
+	enum qca_nl80211_vendor_subcmds_index index;
+	uint32_t freq, ret;
+	uint32_t data_size;
+
+	if (!hdd_context) {
+		hdd_err("HDD context is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	freq = cds_chan_to_freq(dfs_info.channel);
+
+	switch (event) {
+	case eSAP_DFS_CAC_START:
+		index =
+		    QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX;
+		data_size = sizeof(uint32_t);
+		break;
+	case eSAP_DFS_CAC_END:
+		index =
+		    QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX;
+		data_size = sizeof(uint32_t);
+		break;
+	case eSAP_DFS_RADAR_DETECT:
+		index =
+		    QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX;
+		data_size = sizeof(uint32_t);
+		break;
+	default:
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vendor_event = cfg80211_vendor_event_alloc(hdd_context->wiphy,
+			wdev,
+			data_size + NLMSG_HDRLEN,
+			index,
+			GFP_KERNEL);
+	if (!vendor_event) {
+		hdd_err("cfg80211_vendor_event_alloc failed for %d", index);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = nla_put_u32(vendor_event, NL80211_ATTR_WIPHY_FREQ, freq);
+
+	if (ret) {
+		hdd_err("NL80211_ATTR_WIPHY_FREQ put fail");
+		kfree_skb(vendor_event);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_send_conditional_chan_switch_status() - Send conditional channel switch
+ * status
+ * @hdd_ctx: HDD context
+ * @wdev: Wireless device structure
+ * @status: Status of conditional channel switch
+ * (0: Success, Non-zero: Failure)
+ *
+ * Sends the status of conditional channel switch to user space. This is named
+ * conditional channel switch because the SAP will move to the provided channel
+ * after some condition (pre-cac) is met.
+ *
+ * Return: None
+ */
+static void hdd_send_conditional_chan_switch_status(struct hdd_context *hdd_ctx,
+						struct wireless_dev *wdev,
+						bool status)
+{
+	struct sk_buff *event;
+
+	hdd_enter_dev(wdev->netdev);
+
+	if (!hdd_ctx) {
+		hdd_err("Invalid HDD context pointer");
+		return;
+	}
+
+	event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+		  wdev, sizeof(uint32_t) + NLMSG_HDRLEN,
+		  QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH_INDEX,
+		  GFP_KERNEL);
+	if (!event) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	if (nla_put_u32(event,
+			QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_STATUS,
+			status)) {
+		hdd_err("nla put failed");
+		kfree_skb(event);
+		return;
+	}
+
+	cfg80211_vendor_event(event, GFP_KERNEL);
+}
+
+/**
+ * wlan_hdd_set_pre_cac_complete_status() - Set pre cac complete status
+ * @ap_adapter: AP adapter
+ * @status: Status which can be true or false
+ *
+ * Sets the status of pre cac i.e., whether it is complete or not
+ *
+ * Return: Zero on success, non-zero on failure
+ */
+static int wlan_hdd_set_pre_cac_complete_status(struct hdd_adapter *ap_adapter,
+		bool status)
+{
+	QDF_STATUS ret;
+
+	ret = wlan_sap_set_pre_cac_complete_status(
+			WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter), status);
+	if (QDF_IS_STATUS_ERROR(ret))
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * hdd_check_adapter() - check adapter existing or not
+ * @adapter: adapter
+ *
+ * Check adapter in the hdd global list or not
+ *
+ * Return: true if adapter exists.
+ */
+static bool hdd_check_adapter(struct hdd_adapter *adapter)
+{
+	struct hdd_adapter *temp;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is null");
+		return false;
+	}
+	hdd_for_each_adapter(hdd_ctx, temp) {
+		if (temp == adapter)
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * __wlan_hdd_sap_pre_cac_failure() - Process the pre cac failure
+ * @data: AP adapter
+ *
+ * Deletes the pre cac adapter
+ *
+ * Return: None
+ */
+static void __wlan_hdd_sap_pre_cac_failure(void *data)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter();
+
+	adapter = (struct hdd_adapter *) data;
+	if (!adapter || !hdd_check_adapter(adapter) ||
+	    adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
+		hdd_err("SAP Pre CAC adapter invalid");
+		return;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (wlan_hdd_validate_context(hdd_ctx)) {
+		hdd_err("HDD context is null");
+		return;
+	}
+
+	wlan_hdd_release_intf_addr(hdd_ctx,
+				   adapter->mac_addr.bytes);
+	hdd_stop_adapter_ext(hdd_ctx, adapter, HDD_IN_CAC_WORK_TH_CONTEXT);
+	hdd_close_adapter(hdd_ctx, adapter, false);
+}
+
+/**
+ * wlan_hdd_sap_pre_cac_failure() - Process the pre cac failure
+ * @data: AP adapter
+ *
+ * Deletes the pre cac adapter
+ *
+ * Return: None
+ */
+void wlan_hdd_sap_pre_cac_failure(void *data)
+{
+	cds_ssr_protect(__func__);
+	__wlan_hdd_sap_pre_cac_failure(data);
+	cds_ssr_unprotect(__func__);
+}
+
+/**
+ * wlan_hdd_sap_pre_cac_success() - Process the pre cac result
+ * @data: AP adapter
+ *
+ * Deletes the pre cac adapter and moves the existing SAP to the pre cac
+ * channel
+ *
+ * Return: None
+ */
+static void wlan_hdd_sap_pre_cac_success(void *data)
+{
+	struct hdd_adapter *adapter, *ap_adapter;
+	int i;
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter();
+
+	adapter = (struct hdd_adapter *) data;
+	if (!adapter || !hdd_check_adapter(adapter) ||
+	    adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
+		hdd_err("SAP Pre CAC adapter invalid");
+		return;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is null");
+		return;
+	}
+
+	cds_ssr_protect(__func__);
+	wlan_hdd_release_intf_addr(hdd_ctx,
+				   adapter->mac_addr.bytes);
+	hdd_stop_adapter_ext(hdd_ctx, adapter, HDD_IN_CAC_WORK_TH_CONTEXT);
+	hdd_close_adapter(hdd_ctx, adapter, false);
+	cds_ssr_unprotect(__func__);
+
+	/* Prepare to switch AP from 2.4GHz channel to the pre CAC channel */
+	ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
+	if (!ap_adapter) {
+		hdd_err("failed to get SAP adapter, no restart on pre CAC channel");
+		return;
+	}
+
+	/*
+	 * Setting of the pre cac complete status will ensure that on channel
+	 * switch to the pre CAC DFS channel, there is no CAC again.
+	 */
+	wlan_hdd_set_pre_cac_complete_status(ap_adapter, true);
+	i = hdd_softap_set_channel_change(ap_adapter->dev,
+			ap_adapter->pre_cac_chan,
+			CH_WIDTH_MAX, false);
+	if (0 != i) {
+		hdd_err("failed to change channel");
+		wlan_hdd_set_pre_cac_complete_status(ap_adapter, false);
+	}
+}
+
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+/**
+ * hdd_handle_acs_scan_event() - handle acs scan event for SAP
+ * @sap_event: tpSap_Event
+ * @adapter: struct hdd_adapter for SAP
+ *
+ * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event.
+ * It will update scan result to cfg80211 and start a timer to flush the
+ * cached acs scan result.
+ *
+ * Return: QDF_STATUS_SUCCESS on success,
+ *      other value on failure
+ */
+static QDF_STATUS hdd_handle_acs_scan_event(tpSap_Event sap_event,
+		struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx;
+	struct sap_acs_scan_complete_event *comp_evt;
+	QDF_STATUS qdf_status;
+	int chan_list_size;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+	comp_evt = &sap_event->sapevt.sap_acs_scan_comp;
+	hdd_ctx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN;
+	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
+	qdf_mem_free(hdd_ctx->last_acs_channel_list);
+	hdd_ctx->last_acs_channel_list = NULL;
+	hdd_ctx->num_of_channels = 0;
+	/* cache the previous ACS scan channel list .
+	 * If the following OBSS scan chan list is covered by ACS chan list,
+	 * we can skip OBSS Scan to save SAP starting total time.
+	 */
+	if (comp_evt->num_of_channels && comp_evt->channellist) {
+		chan_list_size = comp_evt->num_of_channels *
+			sizeof(comp_evt->channellist[0]);
+		hdd_ctx->last_acs_channel_list = qdf_mem_malloc(
+			chan_list_size);
+		if (hdd_ctx->last_acs_channel_list) {
+			qdf_mem_copy(hdd_ctx->last_acs_channel_list,
+				comp_evt->channellist,
+				chan_list_size);
+			hdd_ctx->num_of_channels = comp_evt->num_of_channels;
+		}
+	}
+	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
+
+	hdd_debug("Reusing Last ACS scan result for %d sec",
+		ACS_SCAN_EXPIRY_TIMEOUT_S);
+	qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
+	qdf_status = qdf_mc_timer_start(&hdd_ctx->skip_acs_scan_timer,
+			ACS_SCAN_EXPIRY_TIMEOUT_S * 1000);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		hdd_err("Failed to start ACS scan expiry timer");
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static QDF_STATUS hdd_handle_acs_scan_event(tpSap_Event sap_event,
+		struct hdd_adapter *adapter)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * get_max_rate_vht() - calculate max rate for VHT mode
+ * @nss: num of streams
+ * @ch_width: channel width
+ * @sgi: short gi
+ * @vht_mcs_map: vht mcs map
+ *
+ * This function calculate max rate for VHT mode
+ *
+ * Return: max rate
+ */
+static int get_max_rate_vht(int nss, int ch_width, int sgi, int vht_mcs_map)
+{
+	const struct index_vht_data_rate_type *supported_vht_mcs_rate;
+	enum data_rate_11ac_max_mcs vht_max_mcs;
+	int maxrate = 0;
+	int maxidx;
+
+	if (nss == 1) {
+		supported_vht_mcs_rate = supported_vht_mcs_rate_nss1;
+	} else if (nss == 2) {
+		supported_vht_mcs_rate = supported_vht_mcs_rate_nss2;
+	} else {
+		/* Not Supported */
+		hdd_err("nss %d not supported", nss);
+		return maxrate;
+	}
+
+	vht_max_mcs =
+		(enum data_rate_11ac_max_mcs)
+		(vht_mcs_map & DATA_RATE_11AC_MCS_MASK);
+
+	if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_7) {
+		maxidx = 7;
+	} else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_8) {
+		maxidx = 8;
+	} else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_9) {
+		if (ch_width == eHT_CHANNEL_WIDTH_20MHZ)
+			/* MCS9 is not valid for VHT20 when nss=1,2 */
+			maxidx = 8;
+		else
+			maxidx = 9;
+	} else {
+		hdd_err("vht mcs map %x not supported",
+			vht_mcs_map & DATA_RATE_11AC_MCS_MASK);
+		return maxrate;
+	}
+
+	if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) {
+		maxrate =
+		supported_vht_mcs_rate[maxidx].supported_VHT20_rate[sgi];
+	} else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) {
+		maxrate =
+		supported_vht_mcs_rate[maxidx].supported_VHT40_rate[sgi];
+	} else if (ch_width == eHT_CHANNEL_WIDTH_80MHZ) {
+		maxrate =
+		supported_vht_mcs_rate[maxidx].supported_VHT80_rate[sgi];
+	} else {
+		hdd_err("ch_width %d not supported", ch_width);
+		return maxrate;
+	}
+
+	return maxrate;
+}
+
+/**
+ * calculate_max_phy_rate() - calcuate maximum phy rate (100kbps)
+ * @mode: phymode: Legacy, 11a/b/g, HT, VHT
+ * @nss: num of stream (maximum num is 2)
+ * @ch_width: channel width
+ * @sgi: short gi enabled or not
+ * @supp_idx: max supported idx
+ * @ext_idx: max extended idx
+ * @ht_mcs_idx: max mcs index for HT
+ * @vht_mcs_map: mcs map for VHT
+ *
+ * return: maximum phy rate in 100kbps
+ */
+static int calcuate_max_phy_rate(int mode, int nss, int ch_width,
+				 int sgi, int supp_idx, int ext_idx,
+				 int ht_mcs_idx, int vht_mcs_map)
+{
+	const struct index_data_rate_type *supported_mcs_rate;
+	int maxidx = 12; /*default 6M mode*/
+	int maxrate = 0, tmprate;
+	int i;
+
+	/* check supported rates */
+	if (supp_idx != 0xff && maxidx < supp_idx)
+		maxidx = supp_idx;
+
+	/* check extended rates */
+	if (ext_idx != 0xff && maxidx < ext_idx)
+		maxidx = ext_idx;
+
+	for (i = 0; i < QDF_ARRAY_SIZE(supported_data_rate); i++) {
+		if (supported_data_rate[i].beacon_rate_index == maxidx)
+			maxrate = supported_data_rate[i].supported_rate[0];
+	}
+
+	if (mode == SIR_SME_PHY_MODE_HT) {
+		/* check for HT Mode */
+		maxidx = ht_mcs_idx;
+		if (nss == 1) {
+			supported_mcs_rate = supported_mcs_rate_nss1;
+		} else if (nss == 2) {
+			supported_mcs_rate = supported_mcs_rate_nss2;
+		} else {
+			/* Not Supported */
+			hdd_err("nss %d not supported", nss);
+			return maxrate;
+		}
+
+		if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) {
+			tmprate = sgi ?
+				supported_mcs_rate[maxidx].supported_rate[2] :
+				supported_mcs_rate[maxidx].supported_rate[0];
+		} else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) {
+			tmprate = sgi ?
+				supported_mcs_rate[maxidx].supported_rate[3] :
+				supported_mcs_rate[maxidx].supported_rate[1];
+		} else {
+			hdd_err("invalid mode %d ch_width %d",
+				mode, ch_width);
+			return maxrate;
+		}
+
+		if (maxrate < tmprate)
+			maxrate = tmprate;
+	}
+
+	if (mode == SIR_SME_PHY_MODE_VHT) {
+		/* check for VHT Mode */
+		tmprate = get_max_rate_vht(nss, ch_width, sgi, vht_mcs_map);
+		if (maxrate < tmprate)
+			maxrate = tmprate;
+	}
+
+	return maxrate;
+}
+
+/**
+ * hdd_convert_dot11mode_from_phymode() - get dot11 mode from phymode
+ * @phymode: phymode of sta associated to SAP
+ *
+ * The function is to convert the phymode to corresponding dot11 mode
+ *
+ * Return: dot11mode.
+ */
+
+
+static int hdd_convert_dot11mode_from_phymode(int phymode)
+{
+
+	switch (phymode) {
+
+	case MODE_11A:
+		return QCA_WLAN_802_11_MODE_11A;
+
+	case MODE_11B:
+		return QCA_WLAN_802_11_MODE_11B;
+
+	case MODE_11G:
+	case MODE_11GONLY:
+		return QCA_WLAN_802_11_MODE_11G;
+
+	case MODE_11NA_HT20:
+	case MODE_11NG_HT20:
+	case MODE_11NA_HT40:
+	case MODE_11NG_HT40:
+		return QCA_WLAN_802_11_MODE_11N;
+
+	case MODE_11AC_VHT20:
+	case MODE_11AC_VHT40:
+	case MODE_11AC_VHT80:
+	case MODE_11AC_VHT20_2G:
+	case MODE_11AC_VHT40_2G:
+	case MODE_11AC_VHT80_2G:
+#ifdef CONFIG_160MHZ_SUPPORT
+	case MODE_11AC_VHT80_80:
+	case MODE_11AC_VHT160:
+#endif
+		return QCA_WLAN_802_11_MODE_11AC;
+
+	default:
+		return QCA_WLAN_802_11_MODE_INVALID;
+	}
+
+}
+
+/**
+ * hdd_fill_station_info() - fill stainfo once connected
+ * @stainfo: peer stainfo associate to SAP
+ * @event: associate/reassociate event received
+ *
+ * The function is to update rate stats to stainfo
+ *
+ * Return: None.
+ */
+static void hdd_fill_station_info(struct hdd_adapter *adapter,
+				  tSap_StationAssocReassocCompleteEvent *event)
+{
+	struct hdd_station_info *stainfo;
+	uint8_t i = 0, oldest_disassoc_sta_idx = WLAN_MAX_STA_COUNT + 1;
+	qdf_time_t oldest_disassoc_sta_ts = 0;
+
+	if (event->staId >= WLAN_MAX_STA_COUNT) {
+		hdd_err("invalid sta id");
+		return;
+	}
+
+	stainfo = &adapter->sta_info[event->staId];
+
+	if (!stainfo) {
+		hdd_err("invalid stainfo");
+		return;
+	}
+
+	stainfo->freq = cds_chan_to_freq(event->chan_info.chan_id);
+	stainfo->sta_type = event->staType;
+	stainfo->dot11_mode =
+		hdd_convert_dot11mode_from_phymode(event->chan_info.info);
+
+	stainfo->nss = event->chan_info.nss;
+	stainfo->rate_flags = event->chan_info.rate_flags;
+	stainfo->ampdu = event->ampdu;
+	stainfo->sgi_enable = event->sgi_enable;
+	stainfo->tx_stbc = event->tx_stbc;
+	stainfo->rx_stbc = event->rx_stbc;
+	stainfo->ch_width = event->ch_width;
+	stainfo->mode = event->mode;
+	stainfo->max_supp_idx = event->max_supp_idx;
+	stainfo->max_ext_idx = event->max_ext_idx;
+	stainfo->max_mcs_idx = event->max_mcs_idx;
+	stainfo->rx_mcs_map = event->rx_mcs_map;
+	stainfo->tx_mcs_map = event->tx_mcs_map;
+	stainfo->assoc_ts = qdf_system_ticks();
+	stainfo->max_phy_rate =
+		calcuate_max_phy_rate(stainfo->mode,
+				      stainfo->nss,
+				      stainfo->ch_width,
+				      stainfo->sgi_enable,
+				      stainfo->max_supp_idx,
+				      stainfo->max_ext_idx,
+				      stainfo->max_mcs_idx,
+				      stainfo->rx_mcs_map);
+	/* expect max_phy_rate report in kbps */
+	stainfo->max_phy_rate *= 100;
+
+	if (event->vht_caps.present) {
+		stainfo->vht_present = true;
+		hdd_copy_vht_caps(&stainfo->vht_caps, &event->vht_caps);
+	}
+	if (event->ht_caps.present) {
+		stainfo->ht_present = true;
+		hdd_copy_ht_caps(&stainfo->ht_caps, &event->ht_caps);
+	}
+
+	/* Initialize DHCP info */
+	stainfo->dhcp_phase = DHCP_PHASE_ACK;
+	stainfo->dhcp_nego_status = DHCP_NEGO_STOP;
+
+	while (i < WLAN_MAX_STA_COUNT) {
+		if (!qdf_mem_cmp(adapter->cache_sta_info[i].sta_mac.bytes,
+				 event->staMac.bytes,
+				 QDF_MAC_ADDR_SIZE))
+			break;
+		i++;
+	}
+	if (i >= WLAN_MAX_STA_COUNT) {
+		i = 0;
+		while (i < WLAN_MAX_STA_COUNT) {
+			if (adapter->cache_sta_info[i].in_use != TRUE)
+				break;
+
+			if (adapter->cache_sta_info[i].disassoc_ts &&
+			    (!oldest_disassoc_sta_ts ||
+			    (qdf_system_time_after(
+					oldest_disassoc_sta_ts,
+					adapter->
+					cache_sta_info[i].disassoc_ts)))) {
+				oldest_disassoc_sta_ts =
+					adapter->
+						cache_sta_info[i].disassoc_ts;
+				oldest_disassoc_sta_idx = i;
+			}
+			i++;
+		}
+	}
+
+	if ((i == WLAN_MAX_STA_COUNT) && oldest_disassoc_sta_ts) {
+		hdd_debug("reached max cached staid, removing oldest stainfo");
+		i = oldest_disassoc_sta_idx;
+	}
+	if (i < WLAN_MAX_STA_COUNT) {
+		qdf_mem_zero(&adapter->cache_sta_info[i],
+			     sizeof(*stainfo));
+		qdf_mem_copy(&adapter->cache_sta_info[i],
+				     stainfo, sizeof(struct hdd_station_info));
+
+	} else {
+		hdd_debug("reached max staid, stainfo can't be cached");
+	}
+
+	hdd_debug("cap %d %d %d %d %d %d %d %d %d %x %d",
+		  stainfo->ampdu,
+		  stainfo->sgi_enable,
+		  stainfo->tx_stbc,
+		  stainfo->rx_stbc,
+		  stainfo->is_qos_enabled,
+		  stainfo->ch_width,
+		  stainfo->mode,
+		  event->wmmEnabled,
+		  event->chan_info.nss,
+		  event->chan_info.rate_flags,
+		  stainfo->max_phy_rate);
+	hdd_debug("rate info %d %d %d %d %d",
+		  stainfo->max_supp_idx,
+		  stainfo->max_ext_idx,
+		  stainfo->max_mcs_idx,
+		  stainfo->rx_mcs_map,
+		  stainfo->tx_mcs_map);
+}
+
+/**
+ * hdd_stop_sap_due_to_invalid_channel() - to stop sap in case of invalid chnl
+ * @work: pointer to work structure
+ *
+ * Let's say SAP detected RADAR and trying to select the new channel and if no
+ * valid channel is found due to none of the channels are available or
+ * regulatory restriction then SAP needs to be stopped. so SAP state-machine
+ * will create a work to stop the bss
+ *
+ * stop bss has to happen through worker thread because radar indication comes
+ * from FW through mc thread or main host thread and if same thread is used to
+ * do stopbss then waiting for stopbss to finish operation will halt mc thread
+ * to freeze which will trigger stopbss timeout. Instead worker thread can do
+ * the stopbss operation while mc thread waits for stopbss to finish.
+ *
+ * Return: none
+ */
+static void
+hdd_stop_sap_due_to_invalid_channel(struct work_struct *work)
+{
+	/*
+	 * Extract the adapter from work structure. sap_stop_bss_work
+	 * is part of adapter context.
+	 */
+	struct hdd_adapter *sap_adapter = container_of(work,
+						  struct hdd_adapter,
+						  sap_stop_bss_work);
+	cds_ssr_protect(__func__);
+	if (sap_adapter == NULL) {
+		cds_err("sap_adapter is NULL, no work needed");
+		cds_ssr_unprotect(__func__);
+		return;
+	}
+	hdd_debug("work started for sap session[%d]", sap_adapter->session_id);
+	wlan_hdd_stop_sap(sap_adapter);
+	wlansap_cleanup_cac_timer(WLAN_HDD_GET_SAP_CTX_PTR(sap_adapter));
+	hdd_debug("work finished for sap");
+	cds_ssr_unprotect(__func__);
+}
+
+QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
+				    void *context)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_ap_ctx *ap_ctx;
+	struct hdd_hostapd_state *hostapd_state;
+	struct net_device *dev;
+	eSapHddEvent sapEvent;
+	union iwreq_data wrqu;
+	uint8_t *we_custom_event_generic = NULL;
+	int we_event = 0;
+	int i = 0;
+	uint8_t staId;
+	QDF_STATUS qdf_status;
+	bool bAuthRequired = true;
+	tpSap_AssocMacAddr pAssocStasArray = NULL;
+	char unknownSTAEvent[IW_CUSTOM_MAX + 1];
+	char maxAssocExceededEvent[IW_CUSTOM_MAX + 1];
+	uint8_t we_custom_start_event[64];
+	char *startBssEvent;
+	struct hdd_context *hdd_ctx;
+	struct iw_michaelmicfailure msg;
+	uint8_t ignoreCAC = 0;
+	struct hdd_config *cfg = NULL;
+	struct wlan_dfs_info dfs_info;
+	uint8_t cc_len = WLAN_SVC_COUNTRY_CODE_LEN;
+	struct hdd_adapter *con_sap_adapter;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct hdd_chan_change_params chan_change;
+	tSap_StationAssocReassocCompleteEvent *event;
+	tSap_StationSetKeyCompleteEvent *key_complete;
+	int ret = 0;
+	struct ch_params sap_ch_param = {0};
+	eCsrPhyMode phy_mode;
+	bool legacy_phymode;
+	tSap_StationDisassocCompleteEvent *disassoc_comp;
+	struct hdd_station_info *stainfo, *cache_stainfo;
+	mac_handle_t mac_handle;
+	tsap_config_t *sap_config;
+
+	dev = context;
+	if (!dev) {
+		hdd_err("context is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	adapter = netdev_priv(dev);
+
+	if ((NULL == adapter) ||
+	    (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		hdd_err("invalid adapter or adapter has invalid magic");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+
+	if (!pSapEvent) {
+		hdd_err("pSapEvent is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sapEvent = pSapEvent->sapHddEventCode;
+	memset(&wrqu, '\0', sizeof(wrqu));
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	if (!hdd_ctx) {
+		hdd_err("HDD context is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cfg = hdd_ctx->config;
+
+	if (!cfg) {
+		hdd_err("HDD config is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	dfs_info.channel = ap_ctx->operating_channel;
+	sme_get_country_code(mac_handle, dfs_info.country_code, &cc_len);
+	staId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
+	sap_config = &adapter->session.ap.sap_config;
+
+	switch (sapEvent) {
+	case eSAP_START_BSS_EVENT:
+		hdd_debug("BSS status = %s, channel = %u, bc sta Id = %d",
+		       pSapEvent->sapevt.sapStartBssCompleteEvent.
+		       status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
+		       pSapEvent->sapevt.sapStartBssCompleteEvent.
+		       operatingChannel,
+		       pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
+
+		adapter->session_id =
+			pSapEvent->sapevt.sapStartBssCompleteEvent.sessionId;
+
+		sap_config->channel =
+			pSapEvent->sapevt.sapStartBssCompleteEvent.
+			operatingChannel;
+
+		sap_config->ch_params.ch_width =
+			pSapEvent->sapevt.sapStartBssCompleteEvent.ch_width;
+
+		wlan_reg_set_channel_params(hdd_ctx->pdev,
+					    sap_config->channel, 0,
+					    &sap_config->ch_params);
+
+		hostapd_state->qdf_status =
+			pSapEvent->sapevt.sapStartBssCompleteEvent.status;
+
+		qdf_atomic_set(&adapter->dfs_radar_found, 0);
+
+		status = policy_mgr_set_chan_switch_complete_evt(
+						hdd_ctx->psoc);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("set event failed");
+			goto stopbss;
+		}
+		wlansap_get_dfs_ignore_cac(mac_handle, &ignoreCAC);
+
+		/* DFS requirement: DO NOT transmit during CAC. */
+		if (CHANNEL_STATE_DFS !=
+			wlan_reg_get_channel_state(hdd_ctx->pdev,
+						   ap_ctx->operating_channel)
+			|| ignoreCAC
+			|| hdd_ctx->dev_dfs_cac_status == DFS_CAC_ALREADY_DONE)
+			ap_ctx->dfs_cac_block_tx = false;
+		else
+			ap_ctx->dfs_cac_block_tx = true;
+
+		ucfg_ipa_set_dfs_cac_tx(hdd_ctx->pdev,
+					ap_ctx->dfs_cac_block_tx);
+
+		hdd_debug("The value of dfs_cac_block_tx[%d] for ApCtx[%pK]:%d",
+				ap_ctx->dfs_cac_block_tx, ap_ctx,
+				adapter->session_id);
+
+		if (hostapd_state->qdf_status) {
+			hdd_err("startbss event failed!!");
+			/*
+			 * Make sure to set the event before proceeding
+			 * for error handling otherwise caller thread will
+			 * wait till 10 secs and no other connection will
+			 * go through before that.
+			 */
+			hostapd_state->bss_state = BSS_STOP;
+			qdf_event_set(&hostapd_state->qdf_event);
+			goto stopbss;
+		} else {
+			sme_ch_avoid_update_req(mac_handle);
+
+			ap_ctx->broadcast_sta_id =
+				pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
+
+			cdp_hl_fc_set_td_limit(
+				cds_get_context(QDF_MODULE_ID_SOC),
+				adapter->session_id,
+				ap_ctx->operating_channel);
+
+			hdd_register_tx_flow_control(adapter,
+				hdd_softap_tx_resume_timer_expired_handler,
+				hdd_softap_tx_resume_cb,
+				hdd_tx_flow_control_is_pause);
+
+			/* @@@ need wep logic here to set privacy bit */
+			qdf_status =
+				hdd_softap_register_bc_sta(adapter,
+							   ap_ctx->privacy);
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+				hdd_warn("Failed to register BC STA %d",
+				       qdf_status);
+				hdd_stop_bss_link(adapter);
+			}
+		}
+
+		if (ucfg_ipa_is_enabled()) {
+			status = ucfg_ipa_wlan_evt(hdd_ctx->pdev,
+						   adapter->dev,
+						   adapter->device_mode,
+						   ap_ctx->broadcast_sta_id,
+						   adapter->session_id,
+						   WLAN_IPA_AP_CONNECT,
+						   adapter->dev->dev_addr);
+			if (status)
+				hdd_err("WLAN_AP_CONNECT event failed");
+		}
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+		wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
+#endif
+		ap_ctx->operating_channel =
+			pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
+
+		hdd_hostapd_channel_prevent_suspend(adapter,
+						    ap_ctx->operating_channel);
+
+		hostapd_state->bss_state = BSS_START;
+
+		/* Set default key index */
+		hdd_debug("default key index %hu", ap_ctx->wep_def_key_idx);
+
+		sme_roam_set_default_key_index(mac_handle,
+					       adapter->session_id,
+					       ap_ctx->wep_def_key_idx);
+
+		/* Set group key / WEP key every time when BSS is restarted */
+		if (ap_ctx->group_key.keyLength) {
+			status = wlansap_set_key_sta(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+				&ap_ctx->group_key);
+			if (!QDF_IS_STATUS_SUCCESS(status))
+				hdd_err("wlansap_set_key_sta failed");
+		} else {
+			for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
+				if (!ap_ctx->wep_key[i].keyLength)
+					continue;
+
+				status = wlansap_set_key_sta(
+					WLAN_HDD_GET_SAP_CTX_PTR
+						(adapter),
+					&ap_ctx->wep_key[i]);
+				if (!QDF_IS_STATUS_SUCCESS(status))
+					hdd_err("set_key failed idx: %d", i);
+			}
+		}
+
+		/* Fill the params for sending IWEVCUSTOM Event
+		 * with SOFTAP.enabled
+		 */
+		startBssEvent = "SOFTAP.enabled";
+		memset(&we_custom_start_event, '\0',
+		       sizeof(we_custom_start_event));
+		memcpy(&we_custom_start_event, startBssEvent,
+		       strlen(startBssEvent));
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.data.length = strlen(startBssEvent);
+		we_event = IWEVCUSTOM;
+		we_custom_event_generic = we_custom_start_event;
+		hdd_ipa_set_tx_flow_info();
+
+		hdd_debug("check for SAP restart");
+		policy_mgr_check_concurrent_intf_and_restart_sap(
+						hdd_ctx->psoc);
+
+		if (policy_mgr_is_hw_mode_change_after_vdev_up(
+			hdd_ctx->psoc)) {
+			hdd_debug("check for possible hw mode change");
+			status = policy_mgr_set_hw_mode_on_channel_switch(
+				hdd_ctx->psoc, adapter->session_id);
+			if (QDF_IS_STATUS_ERROR(status))
+				hdd_debug("set hw mode change not done");
+			policy_mgr_set_do_hw_mode_change_flag(
+					hdd_ctx->psoc, false);
+		}
+		/*
+		 * set this event at the very end because once this events
+		 * get set, caller thread is waiting to do further processing.
+		 * so once this event gets set, current worker thread might get
+		 * pre-empted by caller thread.
+		 */
+		qdf_status = qdf_event_set(&hostapd_state->qdf_event);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			hdd_err("qdf_event_set failed! status: %d", qdf_status);
+			goto stopbss;
+		}
+		break;          /* Event will be sent after Switch-Case stmt */
+
+	case eSAP_STOP_BSS_EVENT:
+		hdd_debug("BSS stop status = %s",
+		       pSapEvent->sapevt.sapStopBssCompleteEvent.
+		       status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
+
+		hdd_hostapd_channel_allow_suspend(adapter,
+						  ap_ctx->operating_channel);
+
+		/* Invalidate the channel info. */
+		ap_ctx->operating_channel = 0;
+
+		/* reset the dfs_cac_status and dfs_cac_block_tx flag only when
+		 * the last BSS is stopped
+		 */
+		con_sap_adapter = hdd_get_con_sap_adapter(adapter, true);
+		if (!con_sap_adapter) {
+			ap_ctx->dfs_cac_block_tx = true;
+			hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
+		}
+		hdd_debug("bss_stop_reason=%d", ap_ctx->bss_stop_reason);
+		if ((BSS_STOP_DUE_TO_MCC_SCC_SWITCH !=
+			ap_ctx->bss_stop_reason) &&
+		    (BSS_STOP_DUE_TO_VENDOR_CONFIG_CHAN !=
+			ap_ctx->bss_stop_reason)) {
+			/*
+			 * when MCC to SCC switching or vendor subcmd
+			 * setting sap config channel happens, key storage
+			 * should not be cleared due to hostapd will not
+			 * repopulate the original keys
+			 */
+			ap_ctx->group_key.keyLength = 0;
+			for (i = 0; i < CSR_MAX_NUM_KEY; i++)
+				ap_ctx->wep_key[i].keyLength = 0;
+		}
+
+		/* clear the reason code in case BSS is stopped
+		 * in another place
+		 */
+		ap_ctx->bss_stop_reason = BSS_STOP_REASON_INVALID;
+		ap_ctx->ap_active = false;
+		goto stopbss;
+
+	case eSAP_DFS_CAC_START:
+		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+					WLAN_SVC_DFS_CAC_START_IND,
+					    &dfs_info,
+					    sizeof(struct wlan_dfs_info));
+		hdd_ctx->dev_dfs_cac_status = DFS_CAC_IN_PROGRESS;
+		if (QDF_STATUS_SUCCESS !=
+			hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_START,
+				dfs_info, &adapter->wdev)) {
+			hdd_err("Unable to indicate CAC start NL event");
+		} else {
+			hdd_debug("Sent CAC start to user space");
+		}
+
+		qdf_atomic_set(&adapter->dfs_radar_found, 0);
+		break;
+	case eSAP_DFS_CAC_INTERRUPTED:
+		/*
+		 * The CAC timer did not run completely and a radar was detected
+		 * during the CAC time. This new state will keep the tx path
+		 * blocked since we do not want any transmission on the DFS
+		 * channel. CAC end will only be reported here since the user
+		 * space applications are waiting on CAC end for their state
+		 * management.
+		 */
+		if (QDF_STATUS_SUCCESS !=
+			hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_END,
+				dfs_info, &adapter->wdev)) {
+			hdd_err("Unable to indicate CAC end (interrupted) event");
+		} else {
+			hdd_debug("Sent CAC end (interrupted) to user space");
+		}
+		break;
+	case eSAP_DFS_CAC_END:
+		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+					WLAN_SVC_DFS_CAC_END_IND,
+					    &dfs_info,
+					    sizeof(struct wlan_dfs_info));
+		ap_ctx->dfs_cac_block_tx = false;
+		ucfg_ipa_set_dfs_cac_tx(hdd_ctx->pdev,
+					ap_ctx->dfs_cac_block_tx);
+		hdd_ctx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE;
+		if (QDF_STATUS_SUCCESS !=
+			hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_END,
+				dfs_info, &adapter->wdev)) {
+			hdd_err("Unable to indicate CAC end NL event");
+		} else {
+			hdd_debug("Sent CAC end to user space");
+		}
+		break;
+	case eSAP_DFS_RADAR_DETECT:
+	{
+		int i;
+		tsap_config_t *sap_config =
+				&adapter->session.ap.sap_config;
+
+		hdd_dfs_indicate_radar(hdd_ctx);
+		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+					WLAN_SVC_DFS_RADAR_DETECT_IND,
+					    &dfs_info,
+					    sizeof(struct wlan_dfs_info));
+		hdd_ctx->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(hdd_ctx, eSAP_DFS_RADAR_DETECT,
+				dfs_info, &adapter->wdev)) {
+			hdd_err("Unable to indicate Radar detect NL event");
+		} else {
+			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",
+			adapter->session_id);
+		hdd_send_conditional_chan_switch_status(hdd_ctx,
+			&adapter->wdev, false);
+		hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
+		qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
+				wlan_hdd_sap_pre_cac_failure,
+				(void *)adapter);
+		qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
+		break;
+	case eSAP_DFS_PRE_CAC_END:
+		hdd_debug("pre cac end notification received:%d",
+			adapter->session_id);
+		hdd_send_conditional_chan_switch_status(hdd_ctx,
+			&adapter->wdev, true);
+		ap_ctx->dfs_cac_block_tx = false;
+		ucfg_ipa_set_dfs_cac_tx(hdd_ctx->pdev,
+					ap_ctx->dfs_cac_block_tx);
+		hdd_ctx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE;
+
+		qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
+				wlan_hdd_sap_pre_cac_success,
+				(void *)adapter);
+		qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
+		break;
+	case eSAP_DFS_NO_AVAILABLE_CHANNEL:
+		wlan_hdd_send_svc_nlink_msg
+			(hdd_ctx->radio_index,
+			WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND, &dfs_info,
+			sizeof(struct wlan_dfs_info));
+		break;
+
+	case eSAP_STA_SET_KEY_EVENT:
+		/* TODO:
+		 * forward the message to hostapd once implementation
+		 * is done for now just print
+		 */
+		key_complete = &pSapEvent->sapevt.sapStationSetKeyCompleteEvent;
+		hdd_debug("SET Key: configured status = %s",
+			  key_complete->status ?
+			  "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
+
+		if (QDF_IS_STATUS_SUCCESS(key_complete->status)) {
+			hdd_softap_change_sta_state(adapter,
+						    &key_complete->peerMacAddr,
+						    OL_TXRX_PEER_STATE_AUTH);
+		}
+		return QDF_STATUS_SUCCESS;
+	case eSAP_STA_MIC_FAILURE_EVENT:
+	{
+		memset(&msg, '\0', sizeof(msg));
+		msg.src_addr.sa_family = ARPHRD_ETHER;
+		memcpy(msg.src_addr.sa_data,
+		       &pSapEvent->sapevt.sapStationMICFailureEvent.
+		       staMac, QDF_MAC_ADDR_SIZE);
+		hdd_debug("MIC MAC " MAC_ADDRESS_STR,
+		       MAC_ADDR_ARRAY(msg.src_addr.sa_data));
+		if (pSapEvent->sapevt.sapStationMICFailureEvent.
+		    multicast == true)
+			msg.flags = IW_MICFAILURE_GROUP;
+		else
+			msg.flags = IW_MICFAILURE_PAIRWISE;
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.data.length = sizeof(msg);
+		we_event = IWEVMICHAELMICFAILURE;
+		we_custom_event_generic = (uint8_t *) &msg;
+	}
+		/* inform mic failure to nl80211 */
+		cfg80211_michael_mic_failure(dev,
+					     pSapEvent->
+					     sapevt.sapStationMICFailureEvent.
+					     staMac.bytes,
+					     ((pSapEvent->sapevt.
+					       sapStationMICFailureEvent.
+					       multicast ==
+					       true) ?
+					      NL80211_KEYTYPE_GROUP :
+					      NL80211_KEYTYPE_PAIRWISE),
+					     pSapEvent->sapevt.
+					     sapStationMICFailureEvent.keyId,
+					     pSapEvent->sapevt.
+					     sapStationMICFailureEvent.TSC,
+					     GFP_KERNEL);
+		break;
+
+	case eSAP_STA_ASSOC_EVENT:
+	case eSAP_STA_REASSOC_EVENT:
+		event = &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent;
+		if (eSAP_STATUS_FAILURE == event->status) {
+			hdd_info("assoc failure: " MAC_ADDRESS_STR,
+				 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
+			break;
+		}
+
+		wrqu.addr.sa_family = ARPHRD_ETHER;
+		memcpy(wrqu.addr.sa_data,
+		       &event->staMac, QDF_MAC_ADDR_SIZE);
+		hdd_info("associated " MAC_ADDRESS_STR,
+			 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
+		we_event = IWEVREGISTERED;
+
+		if ((eCSR_ENCRYPT_TYPE_NONE == ap_ctx->encryption_type) ||
+		    (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
+		     ap_ctx->encryption_type)
+		    || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
+			ap_ctx->encryption_type)) {
+			bAuthRequired = false;
+		}
+
+		if (bAuthRequired) {
+			qdf_status = hdd_softap_register_sta(
+						adapter,
+						true,
+						ap_ctx->privacy,
+						event->staId,
+						(struct qdf_mac_addr *)
+						wrqu.addr.sa_data,
+						event->wmmEnabled);
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+				hdd_err("Failed to register STA %d "
+					  MAC_ADDRESS_STR "", qdf_status,
+				       MAC_ADDR_ARRAY(wrqu.addr.sa_data));
+		} else {
+			qdf_status = hdd_softap_register_sta(
+						adapter,
+						false,
+						ap_ctx->privacy,
+						event->staId,
+						(struct qdf_mac_addr *)
+						wrqu.addr.sa_data,
+						event->wmmEnabled);
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+				hdd_err("Failed to register STA %d "
+					  MAC_ADDRESS_STR "", qdf_status,
+				       MAC_ADDR_ARRAY(wrqu.addr.sa_data));
+		}
+
+		staId = event->staId;
+		if (QDF_IS_STATUS_SUCCESS(qdf_status))
+			hdd_fill_station_info(adapter, event);
+
+		adapter->sta_info[staId].ecsa_capable = event->ecsa_capable;
+
+		if (ucfg_ipa_is_enabled()) {
+			status = ucfg_ipa_wlan_evt(hdd_ctx->pdev,
+						   adapter->dev,
+						   adapter->device_mode,
+						   event->staId,
+						   adapter->session_id,
+						   WLAN_IPA_CLIENT_CONNECT_EX,
+						   event->staMac.bytes);
+			if (status)
+				hdd_err("WLAN_CLIENT_CONNECT_EX event failed");
+		}
+
+		DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
+			adapter->session_id,
+			QDF_TRACE_DEFAULT_PDEV_ID,
+			QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC));
+
+#ifdef MSM_PLATFORM
+		/* start timer in sap/p2p_go */
+		if (ap_ctx->ap_active == false) {
+			spin_lock_bh(&hdd_ctx->bus_bw_lock);
+			adapter->prev_tx_packets =
+				adapter->stats.tx_packets;
+			adapter->prev_rx_packets =
+				adapter->stats.rx_packets;
+
+			cdp_get_intra_bss_fwd_pkts_count(
+				cds_get_context(QDF_MODULE_ID_SOC),
+				adapter->session_id,
+				&adapter->prev_fwd_tx_packets,
+				&adapter->prev_fwd_rx_packets);
+
+			spin_unlock_bh(&hdd_ctx->bus_bw_lock);
+			hdd_bus_bw_compute_timer_start(hdd_ctx);
+		}
+#endif
+		ap_ctx->ap_active = true;
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+		wlan_hdd_auto_shutdown_enable(hdd_ctx, false);
+#endif
+		cds_host_diag_log_work(&hdd_ctx->sap_wake_lock,
+				       HDD_SAP_WAKE_LOCK_DURATION,
+				       WIFI_POWER_EVENT_WAKELOCK_SAP);
+		qdf_wake_lock_timeout_acquire(&hdd_ctx->sap_wake_lock,
+					      HDD_SAP_WAKE_LOCK_DURATION);
+		{
+			struct station_info *sta_info;
+			uint16_t iesLen = event->iesLen;
+
+			sta_info = qdf_mem_malloc(sizeof(*sta_info));
+			if (!sta_info) {
+				hdd_err("Failed to allocate station info");
+				return QDF_STATUS_E_FAILURE;
+			}
+			if (iesLen <= MAX_ASSOC_IND_IE_LEN) {
+				sta_info->assoc_req_ies =
+					(const u8 *)&event->ies[0];
+				sta_info->assoc_req_ies_len = iesLen;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
+				/*
+				 * After Kernel 4.0, it's no longer need to set
+				 * STATION_INFO_ASSOC_REQ_IES flag, as it
+				 * changed to use assoc_req_ies_len length to
+				 * check the existence of request IE.
+				 */
+				sta_info->filled |= STATION_INFO_ASSOC_REQ_IES;
+#endif
+				cfg80211_new_sta(dev,
+					(const u8 *)&event->staMac.bytes[0],
+					sta_info, GFP_KERNEL);
+			} else {
+				hdd_err("Assoc Ie length is too long");
+			}
+			qdf_mem_free(sta_info);
+		}
+		/* Lets abort scan to ensure smooth authentication for client */
+		if (ucfg_scan_get_vdev_status(adapter->vdev) !=
+				SCAN_NOT_IN_PROGRESS) {
+			wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
+					adapter->session_id, INVALID_SCAN_ID,
+					false);
+		}
+		if (adapter->device_mode == QDF_P2P_GO_MODE) {
+			/* send peer status indication to oem app */
+			hdd_send_peer_status_ind_to_app(
+				&event->staMac,
+				ePeerConnected,
+				event->timingMeasCap,
+				adapter->session_id,
+				&event->chan_info,
+				adapter->device_mode);
+		}
+
+		hdd_green_ap_add_sta(hdd_ctx);
+		break;
+
+	case eSAP_STA_DISASSOC_EVENT:
+		disassoc_comp =
+			&pSapEvent->sapevt.sapStationDisassocCompleteEvent;
+		memcpy(wrqu.addr.sa_data,
+		       &disassoc_comp->staMac, QDF_MAC_ADDR_SIZE);
+
+		cache_stainfo = hdd_get_stainfo(adapter->cache_sta_info,
+						disassoc_comp->staMac);
+		if (cache_stainfo) {
+			/* Cache the disassoc info */
+			cache_stainfo->rssi = disassoc_comp->rssi;
+			cache_stainfo->tx_rate = disassoc_comp->tx_rate;
+			cache_stainfo->rx_rate = disassoc_comp->rx_rate;
+			cache_stainfo->reason_code = disassoc_comp->reason_code;
+			cache_stainfo->disassoc_ts = qdf_system_ticks();
+		}
+		hdd_info(" disassociated " MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(wrqu.addr.sa_data));
+
+		qdf_status = qdf_event_set(&hostapd_state->qdf_sta_disassoc_event);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			hdd_err("Station Deauth event Set failed");
+
+		if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason ==
+		    eSAP_USR_INITATED_DISASSOC)
+			hdd_debug(" User initiated disassociation");
+		else
+			hdd_debug(" MAC initiated disassociation");
+		we_event = IWEVEXPIRED;
+		qdf_status =
+			hdd_softap_get_sta_id(adapter,
+					      &pSapEvent->sapevt.
+					      sapStationDisassocCompleteEvent.staMac,
+					      &staId);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			hdd_err("Failed to find sta id status: %d", qdf_status);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
+			adapter->session_id,
+			QDF_TRACE_DEFAULT_PDEV_ID,
+			QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC));
+
+		stainfo = hdd_get_stainfo(adapter->sta_info,
+					  disassoc_comp->staMac);
+		if (stainfo) {
+			/* Send DHCP STOP indication to FW */
+			stainfo->dhcp_phase = DHCP_PHASE_ACK;
+			if (stainfo->dhcp_nego_status ==
+						DHCP_NEGO_IN_PROGRESS)
+				hdd_post_dhcp_ind(adapter, staId,
+						  WMA_DHCP_STOP_IND);
+			stainfo->dhcp_nego_status = DHCP_NEGO_STOP;
+		}
+		hdd_softap_deregister_sta(adapter, staId);
+
+		ap_ctx->ap_active = false;
+		spin_lock_bh(&adapter->sta_info_lock);
+		for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
+			if (adapter->sta_info[i].in_use
+			    && i !=
+			    (WLAN_HDD_GET_AP_CTX_PTR(adapter))->
+			    broadcast_sta_id) {
+				ap_ctx->ap_active = true;
+				break;
+			}
+		}
+		spin_unlock_bh(&adapter->sta_info_lock);
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+		wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
+#endif
+
+		cds_host_diag_log_work(&hdd_ctx->sap_wake_lock,
+				       HDD_SAP_WAKE_LOCK_DURATION,
+				       WIFI_POWER_EVENT_WAKELOCK_SAP);
+		qdf_wake_lock_timeout_acquire(&hdd_ctx->sap_wake_lock,
+			 HDD_SAP_CLIENT_DISCONNECT_WAKE_LOCK_DURATION);
+		cfg80211_del_sta(dev,
+				 (const u8 *)&pSapEvent->sapevt.
+				 sapStationDisassocCompleteEvent.staMac.
+				 bytes[0], GFP_KERNEL);
+
+		/* Update the beacon Interval if it is P2P GO */
+		qdf_status = policy_mgr_change_mcc_go_beacon_interval(
+			hdd_ctx->psoc, adapter->session_id,
+			adapter->device_mode);
+		if (QDF_STATUS_SUCCESS != qdf_status) {
+			hdd_err("Failed to update Beacon interval status: %d",
+				qdf_status);
+		}
+		if (adapter->device_mode == QDF_P2P_GO_MODE) {
+			/* send peer status indication to oem app */
+			hdd_send_peer_status_ind_to_app(&pSapEvent->sapevt.
+						sapStationDisassocCompleteEvent.
+						staMac, ePeerDisconnected,
+						0,
+						adapter->session_id,
+						NULL,
+						adapter->device_mode);
+		}
+#ifdef MSM_PLATFORM
+		/*stop timer in sap/p2p_go */
+		if (ap_ctx->ap_active == false) {
+			spin_lock_bh(&hdd_ctx->bus_bw_lock);
+			adapter->prev_tx_packets = 0;
+			adapter->prev_rx_packets = 0;
+			adapter->prev_fwd_tx_packets = 0;
+			adapter->prev_fwd_rx_packets = 0;
+			spin_unlock_bh(&hdd_ctx->bus_bw_lock);
+			hdd_bus_bw_compute_timer_try_stop(hdd_ctx);
+		}
+#endif
+		hdd_green_ap_del_sta(hdd_ctx);
+		break;
+
+	case eSAP_WPS_PBC_PROBE_REQ_EVENT:
+		hdd_debug("WPS PBC probe req");
+		return QDF_STATUS_SUCCESS;
+
+	case eSAP_ASSOC_STA_CALLBACK_EVENT:
+		pAssocStasArray =
+			pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
+		if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0) {
+			for (i = 0;
+			     i <
+			     pSapEvent->sapevt.sapAssocStaListEvent.
+			     noOfAssocSta; i++) {
+				hdd_info("Associated Sta Num %d:assocId=%d, staId=%d, staMac="
+					 MAC_ADDRESS_STR, i + 1,
+					 pAssocStasArray->assocId,
+					 pAssocStasArray->staId,
+					 MAC_ADDR_ARRAY(pAssocStasArray->staMac.
+							bytes));
+				pAssocStasArray++;
+			}
+		}
+		qdf_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);
+		pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
+		return QDF_STATUS_SUCCESS;
+	case eSAP_UNKNOWN_STA_JOIN:
+		snprintf(unknownSTAEvent, IW_CUSTOM_MAX,
+			 "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
+			 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
+			 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
+			 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
+			 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
+			 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
+			 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
+		we_event = IWEVCUSTOM;  /* Discovered a new node (AP mode). */
+		wrqu.data.pointer = unknownSTAEvent;
+		wrqu.data.length = strlen(unknownSTAEvent);
+		we_custom_event_generic = (uint8_t *) unknownSTAEvent;
+		hdd_err("%s", unknownSTAEvent);
+		break;
+
+	case eSAP_MAX_ASSOC_EXCEEDED:
+		snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX,
+			 "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
+			 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
+			 " one or more devices to enable the new device connection",
+			 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
+			 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
+			 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
+			 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
+			 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
+			 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.
+			 bytes[5]);
+		we_event = IWEVCUSTOM;  /* Discovered a new node (AP mode). */
+		wrqu.data.pointer = maxAssocExceededEvent;
+		wrqu.data.length = strlen(maxAssocExceededEvent);
+		we_custom_event_generic = (uint8_t *) maxAssocExceededEvent;
+		hdd_debug("%s", maxAssocExceededEvent);
+		break;
+	case eSAP_STA_ASSOC_IND:
+		return QDF_STATUS_SUCCESS;
+
+	case eSAP_DISCONNECT_ALL_P2P_CLIENT:
+		hdd_clear_all_sta(adapter);
+		return QDF_STATUS_SUCCESS;
+
+	case eSAP_MAC_TRIG_STOP_BSS_EVENT:
+		ret = hdd_stop_bss_link(adapter);
+		if (ret)
+			hdd_warn("hdd_stop_bss_link failed %d", ret);
+		return QDF_STATUS_SUCCESS;
+
+	case eSAP_CHANNEL_CHANGE_EVENT:
+		hdd_debug("Received eSAP_CHANNEL_CHANGE_EVENT event");
+		if (hostapd_state->bss_state != BSS_STOP) {
+			/* Prevent suspend for new channel */
+			hdd_hostapd_channel_prevent_suspend(adapter,
+				pSapEvent->sapevt.sap_ch_selected.pri_ch);
+			/* Allow suspend for old channel */
+			hdd_hostapd_channel_allow_suspend(adapter,
+				ap_ctx->operating_channel);
+		}
+		/* SME/PE is already updated for new operation
+		 * channel. So update HDD layer also here. This
+		 * resolves issue in AP-AP mode where AP1 channel is
+		 * changed due to RADAR then CAC is going on and
+		 * START_BSS on new channel has not come to HDD. At
+		 * this case if AP2 is started it needs current
+		 * operation channel for MCC DFS restriction
+		 */
+		ap_ctx->operating_channel =
+			pSapEvent->sapevt.sap_ch_selected.pri_ch;
+		ap_ctx->sap_config.acs_cfg.pri_ch =
+			pSapEvent->sapevt.sap_ch_selected.pri_ch;
+		ap_ctx->sap_config.acs_cfg.ht_sec_ch =
+			pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
+		ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch =
+			pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
+		ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch =
+			pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
+		ap_ctx->sap_config.acs_cfg.ch_width =
+			pSapEvent->sapevt.sap_ch_selected.ch_width;
+
+		sap_ch_param.ch_width =
+			pSapEvent->sapevt.sap_ch_selected.ch_width;
+		sap_ch_param.center_freq_seg0 =
+			pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
+		sap_ch_param.center_freq_seg1 =
+			pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
+		wlan_reg_set_channel_params(hdd_ctx->pdev,
+			pSapEvent->sapevt.sap_ch_selected.pri_ch,
+			pSapEvent->sapevt.sap_ch_selected.ht_sec_ch,
+			&sap_ch_param);
+
+		cdp_hl_fc_set_td_limit(cds_get_context(QDF_MODULE_ID_SOC),
+				       adapter->session_id,
+				       ap_ctx->operating_channel);
+
+		phy_mode = wlan_sap_get_phymode(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter));
+
+		switch (phy_mode) {
+		case eCSR_DOT11_MODE_11n:
+		case eCSR_DOT11_MODE_11n_ONLY:
+		case eCSR_DOT11_MODE_11ac:
+		case eCSR_DOT11_MODE_11ac_ONLY:
+			legacy_phymode = false;
+			break;
+		default:
+			legacy_phymode = true;
+			break;
+		}
+
+		chan_change.chan =
+			pSapEvent->sapevt.sap_ch_selected.pri_ch;
+		chan_change.chan_params.ch_width =
+			pSapEvent->sapevt.sap_ch_selected.ch_width;
+		chan_change.chan_params.sec_ch_offset =
+			sap_ch_param.sec_ch_offset;
+		chan_change.chan_params.center_freq_seg0 =
+			pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
+		chan_change.chan_params.center_freq_seg1 =
+			pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
+
+		return hdd_chan_change_notify(adapter, dev,
+					      chan_change, legacy_phymode);
+	case eSAP_ACS_SCAN_SUCCESS_EVENT:
+		return hdd_handle_acs_scan_event(pSapEvent, adapter);
+
+	case eSAP_ACS_CHANNEL_SELECTED:
+		hdd_debug("ACS Completed for wlan%d",
+					adapter->dev->ifindex);
+		clear_bit(ACS_PENDING, &adapter->event_flags);
+		clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
+		ap_ctx->sap_config.acs_cfg.pri_ch =
+			pSapEvent->sapevt.sap_ch_selected.pri_ch;
+		ap_ctx->sap_config.acs_cfg.ht_sec_ch =
+			pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
+		ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch =
+			pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
+		ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch =
+			pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
+		ap_ctx->sap_config.acs_cfg.ch_width =
+			pSapEvent->sapevt.sap_ch_selected.ch_width;
+		wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
+		qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
+		return QDF_STATUS_SUCCESS;
+	case eSAP_ECSA_CHANGE_CHAN_IND:
+		hdd_debug("Channel change indication from peer for channel %d",
+				pSapEvent->sapevt.sap_chan_cng_ind.new_chan);
+		if (hdd_softap_set_channel_change(dev,
+			 pSapEvent->sapevt.sap_chan_cng_ind.new_chan,
+			 CH_WIDTH_MAX, false))
+			return QDF_STATUS_E_FAILURE;
+		else
+			return QDF_STATUS_SUCCESS;
+
+	case eSAP_DFS_NEXT_CHANNEL_REQ:
+		hdd_debug("Sending next channel query to userspace");
+		hdd_update_acs_timer_reason(adapter,
+				QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS);
+		return QDF_STATUS_SUCCESS;
+
+	case eSAP_STOP_BSS_DUE_TO_NO_CHNL:
+		hdd_debug("Stop sap session[%d]",
+			  adapter->session_id);
+		INIT_WORK(&adapter->sap_stop_bss_work,
+			  hdd_stop_sap_due_to_invalid_channel);
+		schedule_work(&adapter->sap_stop_bss_work);
+		return QDF_STATUS_SUCCESS;
+
+	default:
+		hdd_debug("SAP message is not handled");
+		goto stopbss;
+		return QDF_STATUS_SUCCESS;
+	}
+	wireless_send_event(dev, we_event, &wrqu,
+			    (char *)we_custom_event_generic);
+
+	return QDF_STATUS_SUCCESS;
+
+stopbss:
+	{
+		uint8_t we_custom_event[64];
+		char *stopBssEvent = "STOP-BSS.response";       /* 17 */
+		int event_len = strlen(stopBssEvent);
+
+		hdd_debug("BSS stop status = %s",
+		       pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
+		       "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
+
+		/* Change the BSS state now since, as we are shutting
+		 * things down, we don't want interfaces to become
+		 * re-enabled
+		 */
+		hostapd_state->bss_state = BSS_STOP;
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+		wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
+#endif
+
+		/* Stop the pkts from n/w stack as we are going to free all of
+		 * the TX WMM queues for all STAID's
+		 */
+		hdd_debug("Disabling queues");
+		wlan_hdd_netif_queue_control(adapter,
+					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+					WLAN_CONTROL_PATH);
+
+		/* reclaim all resources allocated to the BSS */
+		qdf_status = hdd_softap_stop_bss(adapter);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			hdd_warn("hdd_softap_stop_bss failed %d",
+			       qdf_status);
+			if (ucfg_ipa_is_enabled()) {
+				ucfg_ipa_uc_disconnect_ap(hdd_ctx->pdev,
+							  adapter->dev);
+				ucfg_ipa_cleanup_dev_iface(hdd_ctx->pdev,
+							   adapter->dev);
+			}
+		}
+
+		/* notify userspace that the BSS has stopped */
+		memset(&we_custom_event, '\0', sizeof(we_custom_event));
+		memcpy(&we_custom_event, stopBssEvent, event_len);
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.data.length = event_len;
+		we_event = IWEVCUSTOM;
+		we_custom_event_generic = we_custom_event;
+		wireless_send_event(dev, we_event, &wrqu,
+				    (char *)we_custom_event_generic);
+
+		/* once the event is set, structure dev/adapter should
+		 * not be touched since they are now subject to being deleted
+		 * by another thread
+		 */
+		if (eSAP_STOP_BSS_EVENT == sapEvent) {
+			qdf_event_set(&hostapd_state->qdf_stop_bss_event);
+			hdd_bus_bw_compute_timer_try_stop(hdd_ctx);
+		}
+
+		hdd_ipa_set_tx_flow_info();
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+static int hdd_softap_unpack_ie(mac_handle_t mac_handle,
+				eCsrEncryptionType *pEncryptType,
+				eCsrEncryptionType *mcEncryptType,
+				eCsrAuthType *pAuthType,
+				bool *pMFPCapable,
+				bool *pMFPRequired,
+				uint16_t gen_ie_len, uint8_t *gen_ie)
+{
+	uint32_t ret;
+	uint8_t *pRsnIe;
+	uint16_t RSNIeLen;
+	tDot11fIERSN dot11RSNIE = {0};
+	tDot11fIEWPA dot11WPAIE = {0};
+
+	if (NULL == mac_handle) {
+		hdd_err("Error haHandle returned NULL");
+		return -EINVAL;
+	}
+	/* Validity checks */
+	if ((gen_ie_len < QDF_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN))
+	    || (gen_ie_len >
+		QDF_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)))
+		return -EINVAL;
+	/* Type check */
+	if (gen_ie[0] == DOT11F_EID_RSN) {
+		/* Validity checks */
+		if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
+		    (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
+			return QDF_STATUS_E_FAILURE;
+		}
+		/* Skip past the EID byte and length byte */
+		pRsnIe = gen_ie + 2;
+		RSNIeLen = gen_ie_len - 2;
+		/* Unpack the RSN IE */
+		memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
+		ret = sme_unpack_rsn_ie(mac_handle, pRsnIe, RSNIeLen,
+					&dot11RSNIE, false);
+		if (DOT11F_FAILED(ret)) {
+			hdd_err("unpack failed, ret: 0x%x", ret);
+			return -EINVAL;
+		}
+		/* Copy out the encryption and authentication types */
+		hdd_debug("pairwise cipher suite count: %d",
+		       dot11RSNIE.pwise_cipher_suite_count);
+		hdd_debug("authentication suite count: %d",
+		       dot11RSNIE.akm_suite_cnt);
+		/*
+		 * Here we have followed the apple base code,
+		 * but probably I suspect we can do something different
+		 * dot11RSNIE.akm_suite_cnt
+		 * Just translate the FIRST one
+		 */
+		*pAuthType =
+		    hdd_translate_rsn_to_csr_auth_type(dot11RSNIE.akm_suite[0]);
+		/* dot11RSNIE.pwise_cipher_suite_count */
+		*pEncryptType =
+			hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
+								 pwise_cipher_suites[0]);
+		/* dot11RSNIE.gp_cipher_suite_count */
+		*mcEncryptType =
+			hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
+								 gp_cipher_suite);
+		/* Set the PMKSA ID Cache for this interface */
+		*pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
+		*pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
+	} else if (gen_ie[0] == DOT11F_EID_WPA) {
+		/* Validity checks */
+		if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
+		    (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
+			return QDF_STATUS_E_FAILURE;
+		}
+		/* Skip past the EID byte and length byte and 4 byte WiFi OUI */
+		pRsnIe = gen_ie + 2 + 4;
+		RSNIeLen = gen_ie_len - (2 + 4);
+		/* Unpack the WPA IE */
+		memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
+		ret = dot11f_unpack_ie_wpa((tpAniSirGlobal) mac_handle,
+				     pRsnIe, RSNIeLen, &dot11WPAIE, false);
+		if (DOT11F_FAILED(ret)) {
+			hdd_err("unpack failed, ret: 0x%x", ret);
+			return -EINVAL;
+		}
+		/* Copy out the encryption and authentication types */
+		hdd_debug("WPA unicast cipher suite count: %d",
+		       dot11WPAIE.unicast_cipher_count);
+		hdd_debug("WPA authentication suite count: %d",
+		       dot11WPAIE.auth_suite_count);
+		/* dot11WPAIE.auth_suite_count */
+		/* Just translate the FIRST one */
+		*pAuthType =
+			hdd_translate_wpa_to_csr_auth_type(dot11WPAIE.auth_suites[0]);
+		/* dot11WPAIE.unicast_cipher_count */
+		*pEncryptType =
+			hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
+								 unicast_ciphers[0]);
+		/* dot11WPAIE.unicast_cipher_count */
+		*mcEncryptType =
+			hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
+								 multicast_cipher);
+		*pMFPCapable = false;
+		*pMFPRequired = false;
+	} else {
+		hdd_err("gen_ie[0]: %d", gen_ie[0]);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_softap_set_channel_change() -
+ * This function to support SAP channel change with CSA IE
+ * set in the beacons.
+ *
+ * @dev: pointer to the net device.
+ * @target_channel: target channel number.
+ * @target_bw: Target bandwidth to move.
+ * If no bandwidth is specified, the value is CH_WIDTH_MAX
+ * @forced: Force to switch channel, ignore SCC/MCC check
+ *
+ * Return: 0 for success, non zero for failure
+ */
+int hdd_softap_set_channel_change(struct net_device *dev, int target_channel,
+				 enum phy_ch_width target_bw, bool forced)
+{
+	QDF_STATUS status;
+	int ret = 0;
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	struct hdd_context *hdd_ctx = NULL;
+	struct hdd_adapter *sta_adapter;
+	struct hdd_station_ctx *sta_ctx;
+	uint8_t conc_rule1 = 0;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	ret = hdd_validate_channel_and_bandwidth(adapter,
+						target_channel, target_bw);
+	if (ret) {
+		hdd_err("Invalid CH and BW combo");
+		return ret;
+	}
+
+	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
+	ucfg_policy_mgr_get_conc_rule1(hdd_ctx->psoc, &conc_rule1);
+	/*
+	 * conc_custom_rule1:
+	 * Force SCC for SAP + STA
+	 * if STA is already connected then we shouldn't allow
+	 * channel switch in SAP interface.
+	 */
+	if (sta_adapter && conc_rule1) {
+		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
+		if (hdd_conn_is_connected(sta_ctx)) {
+			hdd_err("Channel switch not allowed after STA connection with conc_custom_rule1 enabled");
+			return -EBUSY;
+		}
+	}
+
+	/*
+	 * Set the dfs_radar_found flag to mimic channel change
+	 * when a radar is found. This will enable synchronizing
+	 * SAP and HDD states similar to that of radar indication.
+	 * Suspend the netif queues to stop queuing Tx frames
+	 * from upper layers.  netif queues will be resumed
+	 * once the channel change is completed and SAP will
+	 * post eSAP_START_BSS_EVENT success event to HDD.
+	 */
+	if (qdf_atomic_inc_return(&adapter->dfs_radar_found) > 1) {
+		hdd_err("Channel switch in progress!!");
+		return -EBUSY;
+	}
+
+	/*
+	 * Do SAP concurrency check to cover channel switch case as following:
+	 * There is already existing SAP+GO combination but due to upper layer
+	 * notifying LTE-COEX event or sending command to move one connection
+	 * to different channel. Before moving existing connection to new
+	 * channel, check if new channel can co-exist with the other existing
+	 * connection. For example, SAP1 is on channel-6 and SAP2 is on
+	 * channel-36 and lets say they are doing DBS, and upper layer sends
+	 * LTE-COEX to move SAP1 from channel-6 to channel-149. SAP1 and
+	 * SAP2 will end up doing MCC which may not be desirable result. It
+	 * should will be prevented.
+	 */
+	if (!policy_mgr_allow_concurrency_csa(
+				hdd_ctx->psoc,
+				policy_mgr_convert_device_mode_to_qdf_type(
+					adapter->device_mode),
+				target_channel,
+				adapter->session_id)) {
+		hdd_err("Channel switch failed due to concurrency check failure");
+		qdf_atomic_set(&adapter->dfs_radar_found, 0);
+		return -EINVAL;
+	}
+
+	status = policy_mgr_reset_chan_switch_complete_evt(hdd_ctx->psoc);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("clear event failed");
+		qdf_atomic_set(&adapter->dfs_radar_found, 0);
+		return -EINVAL;
+	}
+	/*
+	 * Post the Channel Change request to SAP.
+	 */
+	status = wlansap_set_channel_change_with_csa(
+		WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+		(uint32_t)target_channel,
+		target_bw,
+		forced && !(hdd_ctx->config->sta_sap_scc_on_lte_coex_chan));
+
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("SAP set channel failed for channel: %d, bw: %d",
+		       target_channel, target_bw);
+		/*
+		 * If channel change command fails then clear the
+		 * radar found flag and also restart the netif
+		 * queues.
+		 */
+		qdf_atomic_set(&adapter->dfs_radar_found, 0);
+
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * hdd_sap_restart_with_channel_switch() - SAP channel change with E/CSA
+ * @ap_adapter: HDD adapter
+ * @target_channel: Channel to which switch must happen
+ * @target_bw: Bandwidth of the target channel
+ * @forced: Force to switch channel, ignore SCC/MCC check
+ *
+ * Invokes the necessary API to perform channel switch for the SAP or GO
+ *
+ * Return: None
+ */
+void hdd_sap_restart_with_channel_switch(struct hdd_adapter *ap_adapter,
+					uint32_t target_channel,
+					uint32_t target_bw,
+					bool forced)
+{
+	struct net_device *dev = ap_adapter->dev;
+	int ret;
+
+	hdd_enter();
+
+	if (!dev) {
+		hdd_err("Invalid dev pointer");
+		return;
+	}
+
+	ret = hdd_softap_set_channel_change(dev, target_channel,
+					    target_bw, forced);
+	if (ret) {
+		hdd_err("channel switch failed");
+		return;
+	}
+}
+
+void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id, uint32_t channel,
+				    uint32_t channel_bw,
+				    bool forced)
+{
+	struct hdd_adapter *ap_adapter =
+		wlan_hdd_get_adapter_from_vdev(psoc, vdev_id);
+
+	if (!ap_adapter) {
+		hdd_err("Adapter is NULL");
+		return;
+	}
+	hdd_sap_restart_with_channel_switch(ap_adapter, channel,
+					    channel_bw, forced);
+}
+
+QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id, uint8_t *channel,
+				uint8_t *sec_ch)
+{
+	mac_handle_t mac_handle;
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	uint8_t intf_ch = 0;
+	struct hdd_context *hdd_ctx;
+	struct hdd_station_ctx *hdd_sta_ctx;
+	struct hdd_adapter *sta_adapter;
+	uint8_t mcc_to_scc_switch = 0;
+	struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev(
+					psoc, vdev_id);
+	if (!ap_adapter) {
+		hdd_err("ap_adapter is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* TODO: need work for 3 port case with sta+sta */
+	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
+	if (!sta_adapter) {
+		hdd_err("sta_adapter is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (NULL == channel || NULL == sec_ch) {
+		hdd_err("Null parameters");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
+		hdd_err("SOFTAP_BSS_STARTED not set");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!mac_handle) {
+		hdd_err("mac_handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (policy_mgr_get_connection_count(psoc) == 1) {
+		/*
+		 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
+		 * enabled on DFS channel then move the SAP out of DFS channel
+		 * as soon as STA gets disconnect.
+		 */
+		if (policy_mgr_is_sap_restart_required_after_sta_disconnect(
+			psoc, &intf_ch)) {
+			hdd_debug("Move the sap to user configured channel %u",
+				  intf_ch);
+			goto sap_restart;
+		}
+	}
+	ucfg_policy_mgr_get_mcc_scc_switch(hdd_ctx->psoc,
+					   &mcc_to_scc_switch);
+	/*
+	 * Check if STA's channel is DFS or passive or part of LTE avoided
+	 * channel list. In that case move SAP to other band if DBS is
+	 * supported, return from here if DBS is not supported.
+	 * Need to take care of 3 port cases with 2 STA iface in future.
+	 */
+	intf_ch = wlansap_check_cc_intf(hdd_ap_ctx->sap_context);
+	hdd_info("intf_ch: %d", intf_ch);
+	if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION !=
+		mcc_to_scc_switch) {
+		if (QDF_IS_STATUS_ERROR(
+			policy_mgr_valid_sap_conc_channel_check(
+				hdd_ctx->psoc,
+				&intf_ch,
+				policy_mgr_mode_specific_get_channel(
+					hdd_ctx->psoc, PM_SAP_MODE)))) {
+			hdd_debug("can't move sap to %d",
+				hdd_sta_ctx->conn_info.operationChannel);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+sap_restart:
+	if (intf_ch == 0) {
+		hdd_debug("interface channel is 0");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hdd_info("SAP restart orig chan: %d, new chan: %d",
+		 hdd_ap_ctx->sap_config.channel, intf_ch);
+	hdd_ap_ctx->sap_config.channel = intf_ch;
+	hdd_ap_ctx->sap_config.ch_params.ch_width = CH_WIDTH_MAX;
+	hdd_ap_ctx->bss_stop_reason = BSS_STOP_DUE_TO_MCC_SCC_SWITCH;
+
+	wlan_reg_set_channel_params(hdd_ctx->pdev,
+				    hdd_ap_ctx->sap_config.channel,
+				    hdd_ap_ctx->sap_config.sec_ch,
+				    &hdd_ap_ctx->sap_config.ch_params);
+	*channel = hdd_ap_ctx->sap_config.channel;
+	*sec_ch = hdd_ap_ctx->sap_config.sec_ch;
+
+	hdd_info("SAP channel change with CSA/ECSA");
+	hdd_sap_restart_chan_switch_cb(psoc, vdev_id,
+		hdd_ap_ctx->sap_config.channel,
+		hdd_ap_ctx->sap_config.ch_params.ch_width, false);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+const struct net_device_ops net_ops_struct = {
+	.ndo_open = hdd_hostapd_open,
+	.ndo_stop = hdd_hostapd_stop,
+	.ndo_uninit = hdd_hostapd_uninit,
+	.ndo_start_xmit = hdd_softap_hard_start_xmit,
+	.ndo_tx_timeout = hdd_softap_tx_timeout,
+	.ndo_get_stats = hdd_get_stats,
+	.ndo_set_mac_address = hdd_hostapd_set_mac_address,
+	.ndo_do_ioctl = hdd_ioctl,
+	.ndo_change_mtu = hdd_hostapd_change_mtu,
+	.ndo_select_queue = hdd_hostapd_select_queue,
+};
+
+void hdd_set_ap_ops(struct net_device *dev)
+{
+	dev->netdev_ops = &net_ops_struct;
+}
+
+bool hdd_sap_create_ctx(struct hdd_adapter *adapter)
+{
+	hdd_debug("creating sap context");
+	adapter->session.ap.sap_context = sap_create_ctx();
+	if (adapter->session.ap.sap_context)
+		return true;
+
+	return false;
+}
+
+bool hdd_sap_destroy_ctx(struct hdd_adapter *adapter)
+{
+	hdd_debug("destroying sap context");
+	sap_destroy_ctx(adapter->session.ap.sap_context);
+	adapter->session.ap.sap_context = NULL;
+
+	return true;
+}
+
+QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
+{
+	struct hdd_hostapd_state *phostapdBuf;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct sap_context *sapContext = NULL;
+	int ret;
+	enum dfs_mode acs_dfs_mode;
+
+	hdd_enter();
+
+	hdd_info("SSR in progress: %d", reinit);
+	qdf_atomic_init(&adapter->session.ap.acs_in_progress);
+
+	sapContext = hdd_hostapd_init_sap_session(adapter, reinit);
+	if (!sapContext) {
+		hdd_err("Invalid sap_ctx");
+		goto error_release_vdev;
+	}
+
+	if (!reinit) {
+		adapter->session.ap.sap_config.channel =
+			hdd_ctx->acs_policy.acs_channel;
+		acs_dfs_mode = hdd_ctx->acs_policy.acs_dfs_mode;
+		adapter->session.ap.sap_config.acs_dfs_mode =
+			wlan_hdd_get_dfs_mode(acs_dfs_mode);
+	}
+
+	/* Allocate the Wireless Extensions state structure */
+	phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+
+	sme_set_curr_device_mode(hdd_ctx->mac_handle, adapter->device_mode);
+	/* Zero the memory.  This zeros the profile structure. */
+	memset(phostapdBuf, 0, sizeof(struct hdd_hostapd_state));
+
+	status = qdf_event_create(&phostapdBuf->qdf_event);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Hostapd HDD qdf event init failed!!");
+		goto error_release_sap_session;
+	}
+
+	status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Hostapd HDD stop bss event init failed!!");
+		goto error_release_sap_session;
+	}
+
+	status = qdf_event_create(&phostapdBuf->qdf_sta_disassoc_event);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Hostapd HDD sta disassoc event init failed!!");
+		goto error_release_sap_session;
+	}
+
+	/* Register as a wireless device */
+	hdd_register_hostapd_wext(adapter->dev);
+
+	/* Initialize the data path module */
+	status = hdd_softap_init_tx_rx(adapter);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("hdd_softap_init_tx_rx failed");
+		goto error_release_sap_session;
+	}
+
+	status = hdd_wmm_adapter_init(adapter);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("hdd_wmm_adapter_init() failed code: %08d [x%08x]",
+		       status, status);
+		goto error_release_wmm;
+	}
+
+	set_bit(WMM_INIT_DONE, &adapter->event_flags);
+
+	ret = wma_cli_set_command(adapter->session_id,
+				  WMI_PDEV_PARAM_BURST_ENABLE,
+				  HDD_ENABLE_SIFS_BURST_DEFAULT,
+				  PDEV_CMD);
+
+	if (0 != ret)
+		hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed: %d", ret);
+
+	if (!reinit) {
+		adapter->session.ap.sap_config.acs_cfg.acs_mode = false;
+		wlan_hdd_undo_acs(adapter);
+		qdf_mem_zero(&adapter->session.ap.sap_config.acs_cfg,
+			     sizeof(struct sap_acs_cfg));
+	}
+
+	/* rcpi info initialization */
+	qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
+
+	hdd_exit();
+
+	return status;
+
+error_release_wmm:
+	hdd_softap_deinit_tx_rx(adapter);
+error_release_sap_session:
+	hdd_unregister_wext(adapter->dev);
+	hdd_hostapd_deinit_sap_session(adapter);
+error_release_vdev:
+	QDF_BUG(!hdd_vdev_destroy(adapter));
+
+	hdd_exit();
+	return status;
+}
+
+void hdd_deinit_ap_mode(struct hdd_context *hdd_ctx,
+			struct hdd_adapter *adapter,
+			bool rtnl_held)
+{
+	hdd_enter_dev(adapter->dev);
+
+	if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
+		hdd_wmm_adapter_close(adapter);
+		clear_bit(WMM_INIT_DONE, &adapter->event_flags);
+	}
+	qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
+	wlan_hdd_undo_acs(adapter);
+	hdd_softap_deinit_tx_rx(adapter);
+	/*
+	 * if we are being called during driver unload,
+	 * then the dev has already been invalidated.
+	 * if we are being called at other times, then we can
+	 * detach the wireless device handlers
+	 */
+	if (adapter->dev) {
+		if (rtnl_held) {
+			adapter->dev->wireless_handlers = NULL;
+		} else {
+			rtnl_lock();
+			adapter->dev->wireless_handlers = NULL;
+			rtnl_unlock();
+		}
+	}
+	if (hdd_hostapd_deinit_sap_session(adapter))
+		hdd_err("Failed:hdd_hostapd_deinit_sap_session");
+
+	hdd_exit();
+}
+
+/**
+ * hdd_wlan_create_ap_dev() - create an AP-mode device
+ * @hdd_ctx: Global HDD context
+ * @macAddr: MAC address to assign to the interface
+ * @name_assign_type: the name of assign type of the netdev
+ * @iface_name: User-visible name of the interface
+ *
+ * This function will allocate a Linux net_device and configuration it
+ * for an AP mode of operation.  Note that the device is NOT actually
+ * registered with the kernel at this time.
+ *
+ * Return: A pointer to the private data portion of the net_device if
+ * the allocation and initialization was successful, NULL otherwise.
+ */
+struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx,
+				      tSirMacAddr macAddr,
+				      unsigned char name_assign_type,
+				      uint8_t *iface_name)
+{
+	struct net_device *dev;
+	struct hdd_adapter *adapter;
+	QDF_STATUS qdf_status;
+
+	hdd_debug("iface_name = %s", iface_name);
+
+	dev = alloc_netdev_mq(sizeof(struct hdd_adapter), iface_name,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
+					  name_assign_type,
+#endif
+					  ether_setup, NUM_TX_QUEUES);
+
+	if (!dev)
+		return NULL;
+
+	adapter = netdev_priv(dev);
+
+	/* Init the net_device structure */
+	ether_setup(dev);
+
+	/* Initialize the adapter context to zeros. */
+	qdf_mem_zero(adapter, sizeof(struct hdd_adapter));
+	adapter->dev = dev;
+	adapter->hdd_ctx = hdd_ctx;
+	adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
+	adapter->session_id = HDD_SESSION_ID_INVALID;
+
+	hdd_debug("dev = %pK, adapter = %pK, concurrency_mode=0x%x",
+		dev, adapter,
+		(int)policy_mgr_get_concurrency_mode(hdd_ctx->psoc));
+
+	/* Init the net_device structure */
+	strlcpy(dev->name, (const char *)iface_name, IFNAMSIZ);
+
+	hdd_set_ap_ops(dev);
+
+	dev->watchdog_timeo = HDD_TX_TIMEOUT;
+	dev->mtu = HDD_DEFAULT_MTU;
+	dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
+
+	if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
+			cfg_dp_enable_ip_tcp_udp_checksum_offload))
+		dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+	dev->features |= NETIF_F_RXCSUM;
+
+	qdf_mem_copy(dev->dev_addr, (void *)macAddr,
+		     sizeof(tSirMacAddr));
+	qdf_mem_copy(adapter->mac_addr.bytes,
+		     (void *)macAddr, sizeof(tSirMacAddr));
+
+	adapter->offloads_configured = false;
+	hdd_dev_setup_destructor(dev);
+	dev->ieee80211_ptr = &adapter->wdev;
+	adapter->wdev.wiphy = hdd_ctx->wiphy;
+	adapter->wdev.netdev = dev;
+	hdd_set_tso_flags(hdd_ctx, dev);
+
+	qdf_status = qdf_event_create(
+			&adapter->qdf_session_open_event);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("failed to create session open QDF event!");
+		free_netdev(adapter->dev);
+		return NULL;
+	}
+
+	qdf_status = qdf_event_create(
+			&adapter->qdf_session_close_event);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("failed to create session close QDF event!");
+		free_netdev(adapter->dev);
+		return NULL;
+	}
+
+	SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
+	spin_lock_init(&adapter->pause_map_lock);
+	adapter->start_time = adapter->last_time = qdf_system_ticks();
+
+	qdf_atomic_init(&adapter->dfs_radar_found);
+
+	return adapter;
+}
+
+/**
+ * wlan_hdd_rate_is_11g() - check if rate is 11g rate or not
+ * @rate: Rate to be checked
+ *
+ * Return: true if rate if 11g else false
+ */
+static bool wlan_hdd_rate_is_11g(u8 rate)
+{
+	static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72,
+					 96, 108}; /* actual rate * 2 */
+	u8 i;
+
+	for (i = 0; i < 8; i++) {
+		if (rate == gRateArray[i])
+			return true;
+	}
+	return false;
+}
+
+#ifdef QCA_HT_2040_COEX
+/**
+ * wlan_hdd_get_sap_obss() - Get SAP OBSS enable config based on HT_CAPAB IE
+ * @adapter: Pointer to hostapd adapter
+ *
+ * Return: HT support channel width config value
+ */
+static bool wlan_hdd_get_sap_obss(struct hdd_adapter *adapter)
+{
+	uint32_t ret;
+	const uint8_t *ie = NULL;
+	uint8_t ht_cap_ie[DOT11F_IE_HTCAPS_MAX_LEN];
+	tDot11fIEHTCaps dot11_ht_cap_ie = {0};
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_beacon_data *beacon = adapter->session.ap.beacon;
+	mac_handle_t mac_handle;
+
+	mac_handle = hdd_ctx->mac_handle;
+	ie = wlan_get_ie_ptr_from_eid(WLAN_EID_HT_CAPABILITY,
+					beacon->tail, beacon->tail_len);
+	if (ie && ie[1]) {
+		qdf_mem_copy(ht_cap_ie, &ie[2], DOT11F_IE_HTCAPS_MAX_LEN);
+		ret = dot11f_unpack_ie_ht_caps((tpAniSirGlobal)mac_handle,
+					       ht_cap_ie, ie[1],
+					       &dot11_ht_cap_ie, false);
+		if (DOT11F_FAILED(ret)) {
+			hdd_err("unpack failed, ret: 0x%x", ret);
+			return false;
+		}
+		return dot11_ht_cap_ie.supportedChannelWidthSet;
+	}
+
+	return false;
+}
+#else
+static bool wlan_hdd_get_sap_obss(struct hdd_adapter *adapter)
+{
+	return false;
+}
+#endif
+/**
+ * wlan_hdd_set_channel() - set channel in sap mode
+ * @wiphy: Pointer to wiphy structure
+ * @dev: Pointer to net_device structure
+ * @chandef: Pointer to channel definition structure
+ * @channel_type: Channel type
+ *
+ * Return: 0 for success non-zero for failure
+ */
+int wlan_hdd_set_channel(struct wiphy *wiphy,
+				struct net_device *dev,
+				struct cfg80211_chan_def *chandef,
+				enum nl80211_channel_type channel_type)
+{
+	struct hdd_adapter *adapter = NULL;
+	uint32_t num_ch = 0;
+	int channel = 0;
+	int channel_seg2 = 0;
+	struct hdd_context *hdd_ctx;
+	int status;
+	mac_handle_t mac_handle;
+	tSmeConfigParams *sme_config;
+	tsap_config_t *sap_config;
+
+	hdd_enter();
+
+	if (NULL == dev) {
+		hdd_err("Called with dev = NULL");
+		return -ENODEV;
+	}
+	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_SET_CHANNEL,
+			 adapter->session_id, channel_type));
+
+	hdd_debug("Device_mode %s(%d)  freq = %d",
+		  qdf_opmode_str(adapter->device_mode),
+		  adapter->device_mode, chandef->chan->center_freq);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	/*
+	 * Do freq to chan conversion
+	 * TODO: for 11a
+	 */
+
+	channel = ieee80211_frequency_to_channel(chandef->chan->center_freq);
+
+	if (NL80211_CHAN_WIDTH_80P80 == chandef->width ||
+	    NL80211_CHAN_WIDTH_160 == chandef->width) {
+		if (chandef->center_freq2)
+			channel_seg2 = ieee80211_frequency_to_channel(
+					chandef->center_freq2);
+		else
+			hdd_err("Invalid center_freq2");
+	}
+
+	/* Check freq range */
+	if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
+	    (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel)) {
+		hdd_err("Channel: %d is outside valid range from %d to %d",
+		       channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
+		       WNI_CFG_CURRENT_CHANNEL_STAMAX);
+		return -EINVAL;
+	}
+
+	/* Check freq range */
+
+	if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel_seg2) ||
+	    (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel_seg2)) {
+		hdd_err("Channel: %d is outside valid range from %d to %d",
+		       channel_seg2, WNI_CFG_CURRENT_CHANNEL_STAMIN,
+		       WNI_CFG_CURRENT_CHANNEL_STAMAX);
+		return -EINVAL;
+	}
+
+	num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+
+	if ((QDF_SAP_MODE != adapter->device_mode) &&
+	    (QDF_P2P_GO_MODE != adapter->device_mode)) {
+		if (QDF_STATUS_SUCCESS !=
+		    wlan_hdd_validate_operation_channel(adapter, channel)) {
+			hdd_err("Invalid Channel: %d", channel);
+			return -EINVAL;
+		}
+		hdd_debug("set channel to [%d] for device mode %s(%d)", channel,
+			  qdf_opmode_str(adapter->device_mode),
+			  adapter->device_mode);
+	}
+
+	if ((adapter->device_mode == QDF_STA_MODE) ||
+	    (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
+		struct csr_roam_profile *roam_profile;
+		struct hdd_station_ctx *sta_ctx =
+			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+		if (eConnectionState_IbssConnected ==
+		    sta_ctx->conn_info.connState) {
+			/* Link is up then return cant set channel */
+			hdd_err("IBSS Associated, can't set the channel");
+			return -EINVAL;
+		}
+
+		roam_profile = hdd_roam_profile(adapter);
+		num_ch = roam_profile->ChannelInfo.numOfChannels = 1;
+		sta_ctx->conn_info.operationChannel = channel;
+		roam_profile->ChannelInfo.ChannelList =
+			&sta_ctx->conn_info.operationChannel;
+	} else if ((adapter->device_mode == QDF_SAP_MODE)
+		   || (adapter->device_mode == QDF_P2P_GO_MODE)
+		   ) {
+		sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(adapter))->sap_config);
+		if (QDF_P2P_GO_MODE == adapter->device_mode) {
+			if (QDF_STATUS_SUCCESS !=
+			    wlan_hdd_validate_operation_channel(adapter,
+								channel)) {
+				hdd_err("Invalid Channel: %d", channel);
+				return -EINVAL;
+			}
+			sap_config->channel = channel;
+			sap_config->ch_params.center_freq_seg1 = channel_seg2;
+		} else {
+			/* set channel to what hostapd configured */
+			if (QDF_STATUS_SUCCESS !=
+				wlan_hdd_validate_operation_channel(adapter,
+								channel)) {
+				hdd_err("Invalid Channel: %d", channel);
+				return -EINVAL;
+			}
+
+			sap_config->channel = channel;
+			sap_config->ch_params.center_freq_seg1 = channel_seg2;
+
+			sme_config = qdf_mem_malloc(sizeof(*sme_config));
+
+			if (!sme_config) {
+				hdd_err("Unable to allocate memory for smeconfig!");
+				return -ENOMEM;
+			}
+			sme_get_config_param(mac_handle, sme_config);
+			switch (channel_type) {
+			case NL80211_CHAN_HT20:
+			case NL80211_CHAN_NO_HT:
+				sme_config->csrConfig.obssEnabled = false;
+				sap_config->sec_ch = 0;
+				break;
+			case NL80211_CHAN_HT40MINUS:
+				sap_config->sec_ch = sap_config->channel - 4;
+				break;
+			case NL80211_CHAN_HT40PLUS:
+				sap_config->sec_ch = sap_config->channel + 4;
+				break;
+			default:
+				hdd_err("Error!!! Invalid HT20/40 mode !");
+				qdf_mem_free(sme_config);
+				return -EINVAL;
+			}
+			sme_config->csrConfig.obssEnabled =
+				wlan_hdd_get_sap_obss(adapter);
+
+			sme_update_config(mac_handle, sme_config);
+			qdf_mem_free(sme_config);
+		}
+	} else {
+		hdd_err("Invalid device mode failed to set valid channel");
+		return -EINVAL;
+	}
+	hdd_exit();
+	return status;
+}
+
+/**
+ * wlan_hdd_check_11gmode() - check for 11g mode
+ * @pIe: Pointer to IE
+ * @require_ht: Pointer to require ht
+ * @require_vht: Pointer to require vht
+ * @pCheckRatesfor11g: Pointer to check rates for 11g mode
+ * @pSapHw_mode: SAP HW mode
+ *
+ * Check for 11g rate and set proper 11g only mode
+ *
+ * Return: none
+ */
+static void wlan_hdd_check_11gmode(const u8 *pIe, u8 *require_ht,
+				   u8 *require_vht, u8 *pCheckRatesfor11g,
+				   eCsrPhyMode *pSapHw_mode)
+{
+	u8 i, num_rates = pIe[0];
+
+	pIe += 1;
+	for (i = 0; i < num_rates; i++) {
+		if (*pCheckRatesfor11g
+		    && (true == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK))) {
+			/* If rate set have 11g rate than change the mode
+			 * to 11G
+			 */
+			*pSapHw_mode = eCSR_DOT11_MODE_11g;
+			if (pIe[i] & BASIC_RATE_MASK) {
+				/* If we have 11g rate as  basic rate, it
+				 * means mode is 11g only mode.
+				 */
+				*pSapHw_mode = eCSR_DOT11_MODE_11g_ONLY;
+				*pCheckRatesfor11g = false;
+			}
+		} else {
+			if ((BASIC_RATE_MASK |
+				WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
+				*require_ht = true;
+			else if ((BASIC_RATE_MASK |
+				WLAN_BSS_MEMBERSHIP_SELECTOR_VHT_PHY) == pIe[i])
+				*require_vht = true;
+		}
+	}
+}
+
+#ifdef WLAN_FEATURE_11AX
+/**
+ * wlan_hdd_add_extn_ie() - add extension IE
+ * @adapter: Pointer to hostapd adapter
+ * @genie: Pointer to ie to be added
+ * @total_ielen: Pointer to store total ie length
+ * @oui: Pointer to oui
+ * @oui_size: Size of oui
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int wlan_hdd_add_extn_ie(struct hdd_adapter *adapter, uint8_t *genie,
+			   uint16_t *total_ielen, uint8_t *oui,
+			   uint8_t oui_size)
+{
+	const uint8_t *ie;
+	uint16_t ielen = 0;
+	struct hdd_beacon_data *beacon = adapter->session.ap.beacon;
+
+	ie = wlan_get_ext_ie_ptr_from_ext_id(oui, oui_size,
+					      beacon->tail,
+					      beacon->tail_len);
+	if (ie) {
+		ielen = ie[1] + 2;
+		if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
+			qdf_mem_copy(&genie[*total_ielen], ie, ielen);
+		} else {
+			hdd_err("**Ie Length is too big***");
+			return -EINVAL;
+		}
+		*total_ielen += ielen;
+	}
+	return 0;
+}
+#endif
+
+/**
+ * wlan_hdd_add_hostapd_conf_vsie() - configure Vendor IE in sap mode
+ * @adapter: Pointer to hostapd adapter
+ * @genie: Pointer to Vendor IE
+ * @total_ielen: Pointer to store total ie length
+ *
+ * Return: none
+ */
+static void wlan_hdd_add_hostapd_conf_vsie(struct hdd_adapter *adapter,
+					   uint8_t *genie,
+					   uint16_t *total_ielen)
+{
+	struct hdd_beacon_data *pBeacon = adapter->session.ap.beacon;
+	int left = pBeacon->tail_len;
+	uint8_t *ptr = pBeacon->tail;
+	uint8_t elem_id, elem_len;
+	uint16_t ielen = 0;
+	bool skip_ie;
+
+	if (NULL == ptr || 0 == left)
+		return;
+
+	while (left >= 2) {
+		elem_id = ptr[0];
+		elem_len = ptr[1];
+		left -= 2;
+		if (elem_len > left) {
+			hdd_err("**Invalid IEs eid: %d elem_len: %d left: %d**",
+				elem_id, elem_len, left);
+			return;
+		}
+		if (IE_EID_VENDOR == elem_id) {
+			/*
+			 * skipping the Vendor IE's which we don't want to
+			 * include or it will be included by existing code.
+			 */
+			if (elem_len >= WPS_OUI_TYPE_SIZE &&
+			    (!qdf_mem_cmp(&ptr[2], WHITELIST_OUI_TYPE,
+					  WPA_OUI_TYPE_SIZE) ||
+			     !qdf_mem_cmp(&ptr[2], BLACKLIST_OUI_TYPE,
+					  WPA_OUI_TYPE_SIZE) ||
+			     !qdf_mem_cmp(&ptr[2], "\x00\x50\xf2\x02",
+					  WPA_OUI_TYPE_SIZE) ||
+			     !qdf_mem_cmp(&ptr[2], WPA_OUI_TYPE,
+					  WPA_OUI_TYPE_SIZE)))
+				skip_ie = true;
+			else
+				skip_ie = false;
+
+			if (!skip_ie) {
+				ielen = ptr[1] + 2;
+				if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
+					qdf_mem_copy(&genie[*total_ielen], ptr,
+						     ielen);
+					*total_ielen += ielen;
+				} else {
+					hdd_err("IE Length is too big IEs eid: %d elem_len: %d total_ie_lent: %d",
+					       elem_id, elem_len, *total_ielen);
+				}
+			}
+		}
+
+		left -= elem_len;
+		ptr += (elem_len + 2);
+	}
+}
+
+/**
+ * wlan_hdd_add_extra_ie() - add extra ies in beacon
+ * @adapter: Pointer to hostapd adapter
+ * @genie: Pointer to extra ie
+ * @total_ielen: Pointer to store total ie length
+ * @temp_ie_id: ID of extra ie
+ *
+ * Return: none
+ */
+static void wlan_hdd_add_extra_ie(struct hdd_adapter *adapter,
+				  uint8_t *genie, uint16_t *total_ielen,
+				  uint8_t temp_ie_id)
+{
+	struct hdd_beacon_data *pBeacon = adapter->session.ap.beacon;
+	int left = pBeacon->tail_len;
+	uint8_t *ptr = pBeacon->tail;
+	uint8_t elem_id, elem_len;
+	uint16_t ielen = 0;
+
+	if (NULL == ptr || 0 == left)
+		return;
+
+	while (left >= 2) {
+		elem_id = ptr[0];
+		elem_len = ptr[1];
+		left -= 2;
+		if (elem_len > left) {
+			hdd_err("**Invalid IEs eid: %d elem_len: %d left: %d**",
+			       elem_id, elem_len, left);
+			return;
+		}
+
+		if (temp_ie_id == elem_id) {
+			ielen = ptr[1] + 2;
+			if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
+				qdf_mem_copy(&genie[*total_ielen], ptr, ielen);
+				*total_ielen += ielen;
+			} else {
+				hdd_err("IE Length is too big IEs eid: %d elem_len: %d total_ie_len: %d",
+				       elem_id, elem_len, *total_ielen);
+			}
+		}
+
+		left -= elem_len;
+		ptr += (elem_len + 2);
+	}
+}
+
+/**
+ * wlan_hdd_cfg80211_alloc_new_beacon() - alloc beacon in ap mode
+ * @adapter: Pointer to hostapd adapter
+ * @ppBeacon: Pointer to pointer to beacon data
+ * @params: Pointer to beacon parameters
+ * @dtim_period: DTIM period
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int
+wlan_hdd_cfg80211_alloc_new_beacon(struct hdd_adapter *adapter,
+				   struct hdd_beacon_data **ppBeacon,
+				   struct cfg80211_beacon_data *params,
+				   int dtim_period)
+{
+	int size;
+	struct hdd_beacon_data *beacon = NULL;
+	struct hdd_beacon_data *old = NULL;
+	int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
+	const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
+
+	hdd_enter();
+	if (params->head && !params->head_len) {
+		hdd_err("head_len is NULL");
+		return -EINVAL;
+	}
+
+	old = adapter->session.ap.beacon;
+
+	if (!params->head && !old) {
+		hdd_err("session: %d old and new heads points to NULL",
+		       adapter->session_id);
+		return -EINVAL;
+	}
+
+	if (params->head) {
+		head_len = params->head_len;
+		head = params->head;
+	} else {
+		head_len = old->head_len;
+		head = old->head;
+	}
+
+	if (params->tail || !old) {
+		tail_len = params->tail_len;
+		tail = params->tail;
+	} else {
+		tail_len = old->tail_len;
+		tail = old->tail;
+	}
+
+	if (params->proberesp_ies || !old) {
+		proberesp_ies_len = params->proberesp_ies_len;
+		proberesp_ies = params->proberesp_ies;
+	} else {
+		proberesp_ies_len = old->proberesp_ies_len;
+		proberesp_ies = old->proberesp_ies;
+	}
+
+	if (params->assocresp_ies || !old) {
+		assocresp_ies_len = params->assocresp_ies_len;
+		assocresp_ies = params->assocresp_ies;
+	} else {
+		assocresp_ies_len = old->assocresp_ies_len;
+		assocresp_ies = old->assocresp_ies;
+	}
+
+	size = sizeof(struct hdd_beacon_data) + head_len + tail_len +
+		proberesp_ies_len + assocresp_ies_len;
+
+	beacon = qdf_mem_malloc(size);
+
+	if (beacon == NULL) {
+		hdd_err("Mem allocation for beacon failed");
+		return -ENOMEM;
+	}
+	if (dtim_period)
+		beacon->dtim_period = dtim_period;
+	else if (old)
+		beacon->dtim_period = old->dtim_period;
+	/* -----------------------------------------------
+	 * | head | tail | proberesp_ies | assocresp_ies |
+	 * -----------------------------------------------
+	 */
+	beacon->head = ((u8 *) beacon) + sizeof(struct hdd_beacon_data);
+	beacon->tail = beacon->head + head_len;
+	beacon->proberesp_ies = beacon->tail + tail_len;
+	beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
+
+	beacon->head_len = head_len;
+	beacon->tail_len = tail_len;
+	beacon->proberesp_ies_len = proberesp_ies_len;
+	beacon->assocresp_ies_len = assocresp_ies_len;
+
+	if (head && head_len)
+		memcpy(beacon->head, head, head_len);
+	if (tail && tail_len)
+		memcpy(beacon->tail, tail, tail_len);
+	if (proberesp_ies && proberesp_ies_len)
+		memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
+	if (assocresp_ies && assocresp_ies_len)
+		memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
+
+	*ppBeacon = beacon;
+
+	adapter->session.ap.beacon = NULL;
+	qdf_mem_free(old);
+
+	return 0;
+
+}
+
+#ifdef QCA_HT_2040_COEX
+static void wlan_hdd_add_sap_obss_scan_ie(
+	struct hdd_adapter *hostapd_adapter, uint8_t *ie_buf, uint16_t *ie_len)
+{
+	if (QDF_SAP_MODE == hostapd_adapter->device_mode) {
+		if (wlan_hdd_get_sap_obss(hostapd_adapter))
+			wlan_hdd_add_extra_ie(hostapd_adapter, ie_buf, ie_len,
+					WLAN_EID_OVERLAP_BSS_SCAN_PARAM);
+	}
+}
+#else
+static void wlan_hdd_add_sap_obss_scan_ie(
+	struct hdd_adapter *hostapd_adapter, uint8_t *ie_buf, uint16_t *ie_len)
+{
+}
+#endif
+
+/**
+ * wlan_hdd_cfg80211_update_apies() - update ap mode 11ax ies
+ * @adapter: Pointer to hostapd adapter
+ * @genie: generic IE buffer
+ * @total_ielen: out param to update total ielen
+ *
+ * Return: 0 for success non-zero for failure
+ */
+
+#ifdef WLAN_FEATURE_11AX
+static int hdd_update_11ax_apies(struct hdd_adapter *adapter,
+				 uint8_t *genie, uint16_t *total_ielen)
+{
+	if (wlan_hdd_add_extn_ie(adapter, genie, total_ielen,
+			    HE_CAP_OUI_TYPE, HE_CAP_OUI_SIZE)) {
+		hdd_err("Adding HE Cap ie failed");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_add_extn_ie(adapter, genie, total_ielen,
+			    HE_OP_OUI_TYPE, HE_OP_OUI_SIZE)) {
+		hdd_err("Adding HE Op ie failed");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#else
+static int hdd_update_11ax_apies(struct hdd_adapter *adapter,
+				 uint8_t *genie, uint16_t *total_ielen)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wlan_hdd_cfg80211_update_apies() - update ap mode ies
+ * @adapter: Pointer to hostapd adapter
+ *
+ * Return: 0 for success non-zero for failure
+ */
+int wlan_hdd_cfg80211_update_apies(struct hdd_adapter *adapter)
+{
+	uint8_t *genie;
+	uint16_t total_ielen = 0;
+	int ret = 0;
+	tsap_config_t *pConfig;
+	tSirUpdateIE updateIE;
+	struct hdd_beacon_data *beacon = NULL;
+	uint16_t proberesp_ies_len;
+	uint8_t *proberesp_ies = NULL;
+	mac_handle_t mac_handle;
+
+	pConfig = &adapter->session.ap.sap_config;
+	beacon = adapter->session.ap.beacon;
+	if (!beacon) {
+		hdd_err("Beacon is NULL !");
+		return -EINVAL;
+	}
+
+	genie = qdf_mem_malloc(MAX_GENIE_LEN);
+
+	if (genie == NULL)
+		return -ENOMEM;
+
+	mac_handle = adapter->hdd_ctx->mac_handle;
+
+	wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
+			      WLAN_EID_VHT_TX_POWER_ENVELOPE);
+
+	/* Extract and add the extended capabilities and interworking IE */
+	wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
+			      WLAN_EID_EXT_CAPABILITY);
+
+	wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
+			      WLAN_EID_INTERWORKING);
+
+	if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))
+		wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
+				      WLAN_EID_RSN);
+
+#ifdef FEATURE_WLAN_WAPI
+	if (QDF_SAP_MODE == adapter->device_mode) {
+		wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
+				      WLAN_EID_WAPI);
+	}
+#endif
+
+	wlan_hdd_add_hostapd_conf_vsie(adapter, genie,
+				       &total_ielen);
+
+	ret = hdd_update_11ax_apies(adapter, genie, &total_ielen);
+	if (ret)
+		goto done;
+
+	wlan_hdd_add_sap_obss_scan_ie(adapter, genie, &total_ielen);
+
+	qdf_copy_macaddr(&updateIE.bssid, &adapter->mac_addr);
+	updateIE.smeSessionId = adapter->session_id;
+
+	if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
+		updateIE.ieBufferlength = total_ielen;
+		updateIE.pAdditionIEBuffer = genie;
+		updateIE.append = false;
+		updateIE.notify = true;
+		if (sme_update_add_ie(mac_handle,
+				      &updateIE,
+				      eUPDATE_IE_PROBE_BCN) ==
+		    QDF_STATUS_E_FAILURE) {
+			hdd_err("Could not pass on Add Ie probe beacon data");
+			ret = -EINVAL;
+			goto done;
+		}
+		wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_BCN);
+	} else {
+		wlansap_update_sap_config_add_ie(pConfig,
+						 genie,
+						 total_ielen,
+						 eUPDATE_IE_PROBE_BCN);
+	}
+
+	/* Added for Probe Response IE */
+	proberesp_ies = qdf_mem_malloc(beacon->proberesp_ies_len +
+				      MAX_GENIE_LEN);
+	if (proberesp_ies == NULL) {
+		hdd_err("mem alloc failed for probe resp ies, size: %d",
+			beacon->proberesp_ies_len + MAX_GENIE_LEN);
+		ret = -EINVAL;
+		goto done;
+	}
+	qdf_mem_copy(proberesp_ies, beacon->proberesp_ies,
+		    beacon->proberesp_ies_len);
+	proberesp_ies_len = beacon->proberesp_ies_len;
+
+	wlan_hdd_add_sap_obss_scan_ie(adapter, proberesp_ies,
+				     &proberesp_ies_len);
+
+	if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
+		updateIE.ieBufferlength = proberesp_ies_len;
+		updateIE.pAdditionIEBuffer = proberesp_ies;
+		updateIE.append = false;
+		updateIE.notify = false;
+		if (sme_update_add_ie(mac_handle,
+				      &updateIE,
+				      eUPDATE_IE_PROBE_RESP) ==
+		    QDF_STATUS_E_FAILURE) {
+			hdd_err("Could not pass on PROBE_RESP add Ie data");
+			ret = -EINVAL;
+			goto done;
+		}
+		wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_RESP);
+	} else {
+		wlansap_update_sap_config_add_ie(pConfig,
+						 proberesp_ies,
+						 proberesp_ies_len,
+						 eUPDATE_IE_PROBE_RESP);
+	}
+
+	/* Assoc resp Add ie Data */
+	if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
+		updateIE.ieBufferlength = beacon->assocresp_ies_len;
+		updateIE.pAdditionIEBuffer = (uint8_t *) beacon->assocresp_ies;
+		updateIE.append = false;
+		updateIE.notify = false;
+		if (sme_update_add_ie(mac_handle,
+				      &updateIE,
+				      eUPDATE_IE_ASSOC_RESP) ==
+		    QDF_STATUS_E_FAILURE) {
+			hdd_err("Could not pass on Add Ie Assoc Response data");
+			ret = -EINVAL;
+			goto done;
+		}
+		wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ASSOC_RESP);
+	} else {
+		wlansap_update_sap_config_add_ie(pConfig,
+						 beacon->assocresp_ies,
+						 beacon->assocresp_ies_len,
+						 eUPDATE_IE_ASSOC_RESP);
+	}
+
+done:
+	qdf_mem_free(genie);
+	qdf_mem_free(proberesp_ies);
+	return ret;
+}
+
+/**
+ * wlan_hdd_set_sap_hwmode() - set sap hw mode
+ * @adapter: Pointer to hostapd adapter
+ *
+ * Return: none
+ */
+static void wlan_hdd_set_sap_hwmode(struct hdd_adapter *adapter)
+{
+	tsap_config_t *pConfig = &adapter->session.ap.sap_config;
+	struct hdd_beacon_data *pBeacon = adapter->session.ap.beacon;
+	struct ieee80211_mgmt *pMgmt_frame =
+		(struct ieee80211_mgmt *)pBeacon->head;
+	u8 checkRatesfor11g = true;
+	u8 require_ht = false, require_vht = false;
+	const u8 *pIe = NULL;
+
+	pConfig->SapHw_mode = eCSR_DOT11_MODE_11b;
+
+	pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_SUPP_RATES,
+				       &pMgmt_frame->u.beacon.variable[0],
+				       pBeacon->head_len);
+	if (pIe != NULL) {
+		pIe += 1;
+		wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
+			&checkRatesfor11g, &pConfig->SapHw_mode);
+	}
+
+	pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_EXT_SUPP_RATES,
+					pBeacon->tail, pBeacon->tail_len);
+	if (pIe != NULL) {
+		pIe += 1;
+		wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
+			&checkRatesfor11g, &pConfig->SapHw_mode);
+	}
+
+	if (pConfig->channel > 14)
+		pConfig->SapHw_mode = eCSR_DOT11_MODE_11a;
+
+	pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_HT_CAPABILITY,
+					pBeacon->tail, pBeacon->tail_len);
+	if (pIe) {
+		pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
+		if (require_ht)
+			pConfig->SapHw_mode = eCSR_DOT11_MODE_11n_ONLY;
+	}
+
+	pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_VHT_CAPABILITY,
+					pBeacon->tail, pBeacon->tail_len);
+	if (pIe) {
+		pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac;
+		if (require_vht)
+			pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac_ONLY;
+	}
+
+	wlan_hdd_check_11ax_support(pBeacon, pConfig);
+
+	hdd_info("SAP hw_mode: %d", pConfig->SapHw_mode);
+}
+
+/**
+ * wlan_hdd_config_acs() - config ACS needed parameters
+ * @hdd_ctx: HDD context
+ * @adapter: Adapter pointer
+ *
+ * This function get ACS related INI parameters and populated
+ * sap config and smeConfig for ACS needed configurations.
+ *
+ * Return: The QDF_STATUS code associated with performing the operation.
+ */
+QDF_STATUS wlan_hdd_config_acs(struct hdd_context *hdd_ctx,
+			       struct hdd_adapter *adapter)
+{
+	tsap_config_t *sap_config;
+	struct hdd_config *ini_config;
+	mac_handle_t mac_handle;
+
+	mac_handle = hdd_ctx->mac_handle;
+	sap_config = &adapter->session.ap.sap_config;
+	ini_config = hdd_ctx->config;
+
+	sap_config->enOverLapCh = !!hdd_ctx->config->gEnableOverLapCh;
+
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+	hdd_debug("HDD_ACS_SKIP_STATUS = %d", hdd_ctx->skip_acs_scan_status);
+	if (hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) {
+		struct hdd_adapter *con_sap_adapter;
+		tsap_config_t *con_sap_config = NULL;
+
+		con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
+
+		if (con_sap_adapter)
+			con_sap_config =
+				&con_sap_adapter->session.ap.sap_config;
+
+		sap_config->acs_cfg.skip_scan_status = eSAP_DO_NEW_ACS_SCAN;
+
+		if (con_sap_config &&
+			con_sap_config->acs_cfg.acs_mode == true &&
+			hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN &&
+			con_sap_config->acs_cfg.hw_mode ==
+						sap_config->acs_cfg.hw_mode) {
+			uint8_t con_sap_st_ch, con_sap_end_ch;
+			uint8_t cur_sap_st_ch, cur_sap_end_ch;
+			uint8_t bandStartChannel, bandEndChannel;
+
+			con_sap_st_ch =
+					con_sap_config->acs_cfg.start_ch;
+			con_sap_end_ch =
+					con_sap_config->acs_cfg.end_ch;
+			cur_sap_st_ch = sap_config->acs_cfg.start_ch;
+			cur_sap_end_ch = sap_config->acs_cfg.end_ch;
+
+			wlansap_extend_to_acs_range(mac_handle, &cur_sap_st_ch,
+					&cur_sap_end_ch, &bandStartChannel,
+					&bandEndChannel);
+
+			wlansap_extend_to_acs_range(mac_handle,
+					&con_sap_st_ch, &con_sap_end_ch,
+					&bandStartChannel, &bandEndChannel);
+
+			if (con_sap_st_ch <= cur_sap_st_ch &&
+					con_sap_end_ch >= cur_sap_end_ch) {
+				sap_config->acs_cfg.skip_scan_status =
+							eSAP_SKIP_ACS_SCAN;
+
+			} else if (con_sap_st_ch >= cur_sap_st_ch &&
+					con_sap_end_ch >= cur_sap_end_ch) {
+				sap_config->acs_cfg.skip_scan_status =
+							eSAP_DO_PAR_ACS_SCAN;
+
+				sap_config->acs_cfg.skip_scan_range1_stch =
+							cur_sap_st_ch;
+				sap_config->acs_cfg.skip_scan_range1_endch =
+							con_sap_st_ch - 1;
+				sap_config->acs_cfg.skip_scan_range2_stch =
+							0;
+				sap_config->acs_cfg.skip_scan_range2_endch =
+							0;
+
+			} else if (con_sap_st_ch <= cur_sap_st_ch &&
+				con_sap_end_ch <= cur_sap_end_ch) {
+				sap_config->acs_cfg.skip_scan_status =
+							eSAP_DO_PAR_ACS_SCAN;
+
+				sap_config->acs_cfg.skip_scan_range1_stch =
+							con_sap_end_ch + 1;
+				sap_config->acs_cfg.skip_scan_range1_endch =
+							cur_sap_end_ch;
+				sap_config->acs_cfg.skip_scan_range2_stch =
+							0;
+				sap_config->acs_cfg.skip_scan_range2_endch =
+							0;
+
+			} else if (con_sap_st_ch >= cur_sap_st_ch &&
+				con_sap_end_ch <= cur_sap_end_ch) {
+				sap_config->acs_cfg.skip_scan_status =
+							eSAP_DO_PAR_ACS_SCAN;
+
+				sap_config->acs_cfg.skip_scan_range1_stch =
+							cur_sap_st_ch;
+				sap_config->acs_cfg.skip_scan_range1_endch =
+							con_sap_st_ch - 1;
+				sap_config->acs_cfg.skip_scan_range2_stch =
+							con_sap_end_ch;
+				sap_config->acs_cfg.skip_scan_range2_endch =
+							cur_sap_end_ch + 1;
+
+			} else
+				sap_config->acs_cfg.skip_scan_status =
+							eSAP_DO_NEW_ACS_SCAN;
+
+
+			hdd_debug("SecAP ACS Skip=%d, ACS CH RANGE=%d-%d, %d-%d",
+				  sap_config->acs_cfg.skip_scan_status,
+				  sap_config->acs_cfg.skip_scan_range1_stch,
+				  sap_config->acs_cfg.skip_scan_range1_endch,
+				  sap_config->acs_cfg.skip_scan_range2_stch,
+				  sap_config->acs_cfg.skip_scan_range2_endch);
+		}
+	}
+#endif
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_hdd_sap_p2p_11ac_overrides: API to overwrite 11ac config in case of
+ * SAP or p2p go
+ * @ap_adapter: pointer to adapter
+ *
+ * This function overrides SAP / P2P Go configuration based on driver INI
+ * parameters for 11AC override and ACS. This overrides are done to support
+ * android legacy configuration method.
+ *
+ * NOTE: Non android platform supports concurrency and these overrides shall
+ * not be used. Also future driver based overrides shall be consolidated in this
+ * function only. Avoid random overrides in other location based on ini.
+ *
+ * Return: 0 for Success or Negative error codes.
+ */
+static int wlan_hdd_sap_p2p_11ac_overrides(struct hdd_adapter *ap_adapter)
+{
+	tsap_config_t *sap_cfg = &ap_adapter->session.ap.sap_config;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
+	uint8_t ch_width;
+	uint8_t sub_20_chan_width;
+	QDF_STATUS status;
+
+	/* Fixed channel 11AC override:
+	 * 11AC override in qcacld is introduced for following reasons:
+	 * 1. P2P GO also follows start_bss and since p2p GO could not be
+	 *    configured to setup VHT channel width in wpa_supplicant
+	 * 2. Android UI does not provide advanced configuration options for SAP
+	 *
+	 * Default override enabled (for android). MDM shall disable this in ini
+	 */
+	/*
+	 * sub_20 MHz channel width is incompatible with 11AC rates, hence do
+	 * not allow 11AC rates or more than 20 MHz channel width when
+	 * enable_sub_20_channel_width is non zero
+	 */
+	status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
+						 &sub_20_chan_width);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get sub_20_chan_width config");
+		return -EIO;
+	}
+
+	if (!sub_20_chan_width &&
+	    (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
+	    sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
+	    sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY ||
+	    sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ax ||
+	    sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ax_ONLY) &&
+	    ((ap_adapter->device_mode == QDF_SAP_MODE &&
+	    !hdd_ctx->config->sap_force_11n_for_11ac &&
+	    hdd_ctx->config->sap_11ac_override) ||
+	    (ap_adapter->device_mode == QDF_P2P_GO_MODE &&
+	    !hdd_ctx->config->go_force_11n_for_11ac &&
+	    hdd_ctx->config->go_11ac_override))) {
+		hdd_debug("** Driver force 11AC override for SAP/Go **");
+
+		/* 11n only shall not be overridden since it may be on purpose*/
+		if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n)
+			sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
+
+		if (sap_cfg->channel >= 36) {
+			status =
+			    ucfg_mlme_get_vht_channel_width(hdd_ctx->psoc,
+							    &ch_width);
+			if (!QDF_IS_STATUS_SUCCESS(status))
+				hdd_err("Failed to set channel_width");
+			sap_cfg->ch_width_orig = ch_width;
+		} else {
+			/*
+			 * Allow 40 Mhz in 2.4 Ghz only if indicated by
+			 * supplicant after OBSS scan and if 2.4 Ghz channel
+			 * bonding is set in INI
+			 */
+			if (sap_cfg->ch_width_orig >= eHT_CHANNEL_WIDTH_40MHZ &&
+			   hdd_ctx->config->nChannelBondingMode24GHz)
+				sap_cfg->ch_width_orig =
+					eHT_CHANNEL_WIDTH_40MHZ;
+			else
+				sap_cfg->ch_width_orig =
+					eHT_CHANNEL_WIDTH_20MHZ;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params
+ * @adapter: pointer to adapter struct
+ *
+ * This function overrides SAP / P2P Go configuration based on driver INI
+ * parameters for 11AC override and ACS. These overrides are done to support
+ * android legacy configuration method.
+ *
+ * NOTE: Non android platform supports concurrency and these overrides shall
+ * not be used. Also future driver based overrides shall be consolidated in this
+ * function only. Avoid random overrides in other location based on ini.
+ *
+ * Return: 0 for Success or Negative error codes.
+ */
+static int wlan_hdd_setup_driver_overrides(struct hdd_adapter *ap_adapter)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
+	QDF_STATUS qdf_status;
+	bool is_vendor_acs_support =
+		cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
+
+	qdf_status = ucfg_mlme_get_vendor_acs_support(hdd_ctx->psoc,
+						      &is_vendor_acs_support);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		hdd_err("get_vendor_acs_support failed, set default");
+
+	if (!is_vendor_acs_support)
+		return wlan_hdd_sap_p2p_11ac_overrides(ap_adapter);
+	else
+		return 0;
+}
+
+static void hdd_check_and_disconnect_sta_on_invalid_channel(
+		struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *sta_adapter;
+	uint8_t sta_chan;
+
+	sta_chan = hdd_get_operating_channel(hdd_ctx, QDF_STA_MODE);
+
+	if (!sta_chan) {
+		hdd_err("STA not connected");
+		return;
+	}
+
+	hdd_err("STA connected on chan %d", sta_chan);
+
+	if (sme_is_channel_valid(hdd_ctx->mac_handle, sta_chan)) {
+		hdd_err("STA connected on chan %d and it is valid", sta_chan);
+		return;
+	}
+
+	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
+
+	if (!sta_adapter) {
+		hdd_err("STA adapter does not exist");
+		return;
+	}
+
+	hdd_err("chan %d not valid, issue disconnect", sta_chan);
+	/* Issue Disconnect request */
+	wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
+}
+
+#ifdef DISABLE_CHANNEL_LIST
+/**
+ * wlan_hdd_get_wiphy_channel() - Get wiphy channel
+ * @wiphy: Pointer to wiphy structure
+ * @freq: Frequency of the channel for which the wiphy hw value is required
+ *
+ * Return: wiphy channel for valid frequency else return NULL
+ */
+static struct ieee80211_channel *wlan_hdd_get_wiphy_channel(
+						struct wiphy *wiphy,
+						uint32_t freq)
+{
+	uint32_t band_num, channel_num;
+	struct ieee80211_channel *wiphy_channel = NULL;
+
+	for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
+		for (channel_num = 0; channel_num <
+				wiphy->bands[band_num]->n_channels;
+				channel_num++) {
+			wiphy_channel = &(wiphy->bands[band_num]->
+							channels[channel_num]);
+			if (wiphy_channel->center_freq == freq)
+				return wiphy_channel;
+		}
+	}
+	return wiphy_channel;
+}
+
+int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx,
+			      bool notify_sap_event)
+{
+	struct hdd_cache_channels *cache_chann;
+	struct wiphy *wiphy;
+	int freq, status, rf_channel;
+	int i;
+	struct ieee80211_channel *wiphy_channel = NULL;
+
+	hdd_enter();
+
+	if (!hdd_ctx) {
+		hdd_err("HDD Context is NULL");
+		return -EINVAL;
+	}
+
+	wiphy = hdd_ctx->wiphy;
+	if (!wiphy) {
+		hdd_err("Wiphy is NULL");
+		return -EINVAL;
+	}
+
+	qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
+
+	cache_chann = hdd_ctx->original_channels;
+
+	if (!cache_chann || !cache_chann->num_channels) {
+		qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+		hdd_err("channel list is NULL or num channels are zero");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < cache_chann->num_channels; i++) {
+		freq = reg_chan_to_freq(
+				hdd_ctx->pdev,
+				cache_chann->channel_info[i].channel_num);
+		if (!freq)
+			continue;
+
+		wiphy_channel = wlan_hdd_get_wiphy_channel(wiphy, freq);
+		if (!wiphy_channel)
+			continue;
+		rf_channel = wiphy_channel->hw_value;
+		/*
+		 * Restore the orginal states of the channels
+		 * only if we have cached non zero values
+		 */
+		if (cache_chann->channel_info[i].wiphy_status && wiphy_channel)
+			wiphy_channel->flags =
+				cache_chann->channel_info[i].wiphy_status;
+	}
+
+	qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+	if (notify_sap_event)
+		ucfg_reg_notify_sap_event(hdd_ctx->pdev, false);
+	else
+		ucfg_reg_restore_cached_channels(hdd_ctx->pdev);
+	status = sme_update_channel_list(hdd_ctx->mac_handle);
+	if (status)
+		hdd_err("Can't Restore channel list");
+	hdd_exit();
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_disable_channels() - Cache the channels
+ * and current state of the channels from the channel list
+ * received in the command and disable the channels on the
+ * wiphy and reg table.
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Return: 0 on success, Error code on failure
+ */
+static int wlan_hdd_disable_channels(struct hdd_context *hdd_ctx)
+{
+	struct hdd_cache_channels *cache_chann;
+	struct wiphy *wiphy;
+	int freq, status, rf_channel;
+	int i;
+	struct ieee80211_channel *wiphy_channel = NULL;
+
+	hdd_enter();
+
+	if (!hdd_ctx) {
+		hdd_err("HDD Context is NULL");
+		return -EINVAL;
+	}
+
+	wiphy = hdd_ctx->wiphy;
+	if (!wiphy) {
+		hdd_err("Wiphy is NULL");
+		return -EINVAL;
+	}
+
+	qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
+	cache_chann = hdd_ctx->original_channels;
+
+	if (!cache_chann || !cache_chann->num_channels) {
+		qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+		hdd_err("channel list is NULL or num channels are zero");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < cache_chann->num_channels; i++) {
+		freq = reg_chan_to_freq(hdd_ctx->pdev,
+					cache_chann->
+						channel_info[i].channel_num);
+		if (!freq)
+			continue;
+		wiphy_channel = wlan_hdd_get_wiphy_channel(wiphy, freq);
+		if (!wiphy_channel)
+			continue;
+		rf_channel = wiphy_channel->hw_value;
+		/*
+		 * Cache the current states of
+		 * the channels
+		 */
+		cache_chann->channel_info[i].reg_status =
+					reg_get_channel_state(
+							hdd_ctx->pdev,
+							rf_channel);
+		cache_chann->channel_info[i].wiphy_status =
+							wiphy_channel->flags;
+		hdd_debug("Disable channel %d reg_stat %d wiphy_stat 0x%x",
+			  cache_chann->channel_info[i].channel_num,
+			  cache_chann->channel_info[i].reg_status,
+			  wiphy_channel->flags);
+
+		wiphy_channel->flags |= IEEE80211_CHAN_DISABLED;
+	}
+
+	qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+	status = ucfg_reg_notify_sap_event(hdd_ctx->pdev, true);
+	status = sme_update_channel_list(hdd_ctx->mac_handle);
+
+	hdd_exit();
+	return status;
+}
+#else
+static int wlan_hdd_disable_channels(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+
+int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx,
+			      bool notify_sap_event)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wlan_hdd_is_dhcp_enabled: Enable DHCP offload
+ * @hdd_ctx: HDD context handler
+ * @adapter: Adapter pointer
+ *
+ * Return: None
+ */
+#ifdef DHCP_SERVER_OFFLOAD
+static void wlan_hdd_is_dhcp_enabled(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter)
+{
+	bool enable_dhcp_server_offload;
+	QDF_STATUS status;
+
+	status = ucfg_fwol_get_enable_dhcp_server_offload(
+						hdd_ctx->psoc,
+						&enable_dhcp_server_offload);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+
+	if (enable_dhcp_server_offload)
+		wlan_hdd_set_dhcp_server_offload(adapter);
+}
+#else
+static void wlan_hdd_is_dhcp_enabled(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter)
+{
+}
+#endif
+
+/**
+ * wlan_hdd_cfg80211_start_bss() - start bss
+ * @adapter: Pointer to hostapd adapter
+ * @params: Pointer to start bss beacon parameters
+ * @ssid: Pointer ssid
+ * @ssid_len: Length of ssid
+ * @hidden_ssid: Hidden SSID parameter
+ * @check_for_concurrency: Flag to indicate if check for concurrency is needed
+ *
+ * Return: 0 for success non-zero for failure
+ */
+int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter,
+				       struct cfg80211_beacon_data *params,
+				       const u8 *ssid, size_t ssid_len,
+				       enum nl80211_hidden_ssid hidden_ssid,
+				       bool check_for_concurrency)
+{
+	tsap_config_t *pConfig;
+	struct hdd_beacon_data *pBeacon = NULL;
+	struct ieee80211_mgmt *pMgmt_frame;
+	const uint8_t *pIe = NULL;
+	uint16_t capab_info;
+	eCsrAuthType RSNAuthType;
+	eCsrEncryptionType RSNEncryptType;
+	eCsrEncryptionType mcRSNEncryptType;
+	int status = QDF_STATUS_SUCCESS, ret;
+	int qdf_status = QDF_STATUS_SUCCESS;
+	tpWLAN_SAPEventCB pSapEventCallback;
+	struct hdd_hostapd_state *hostapd_state;
+	mac_handle_t mac_handle;
+	int32_t i;
+	struct hdd_config *iniConfig;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	uint8_t mcc_to_scc_switch = 0, conc_rule1 = 0;
+	tSmeConfigParams *sme_config;
+	bool MFPCapable = false;
+	bool MFPRequired = false;
+	uint16_t prev_rsn_length = 0;
+	enum dfs_mode mode;
+	struct hdd_adapter *sta_adapter;
+	uint8_t ignore_cac = 0;
+	int value;
+	bool val;
+	uint32_t auto_channel_select_weight =
+		cfg_default(CFG_AUTO_CHANNEL_SELECT_WEIGHT);
+	bool bval = false;
+
+	hdd_enter();
+
+	hdd_notify_teardown_tdls_links(adapter->vdev);
+
+	if (policy_mgr_is_hw_mode_change_in_progress(hdd_ctx->psoc)) {
+		status = policy_mgr_wait_for_connection_update(
+			hdd_ctx->psoc);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("qdf wait for event failed!!");
+			return -EINVAL;
+		}
+	}
+
+	/*
+	 * For STA+SAP concurrency support from GUI, first STA connection gets
+	 * triggered and while it is in progress, SAP start also comes up.
+	 * Once STA association is successful, STA connect event is sent to
+	 * kernel which gets queued in kernel workqueue and supplicant won't
+	 * process M1 received from AP and send M2 until this NL80211_CONNECT
+	 * event is received. Workqueue is not scheduled as RTNL lock is already
+	 * taken by hostapd thread which has issued start_bss command to driver.
+	 * Driver cannot complete start_bss as the pending command at the head
+	 * of the SME command pending list is hw_mode_update for STA session
+	 * which cannot be processed as SME is in WAITforKey state for STA
+	 * interface. The start_bss command for SAP interface is queued behind
+	 * the hw_mode_update command and so it cannot be processed until
+	 * hw_mode_update command is processed. This is causing a deadlock so
+	 * disconnect the STA interface first if connection or key exchange is
+	 * in progress and then start SAP interface.
+	 */
+	sta_adapter = hdd_get_sta_connection_in_progress(hdd_ctx);
+	if (sta_adapter) {
+		hdd_debug("Disconnecting STA with session id: %d",
+			  sta_adapter->session_id);
+		wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
+	}
+
+	/*
+	 * Reject start bss if reassoc in progress on any adapter.
+	 * sme_is_any_session_in_middle_of_roaming is for LFR2 and
+	 * hdd_is_roaming_in_progress is for LFR3
+	 */
+	mac_handle = hdd_ctx->mac_handle;
+	if (sme_is_any_session_in_middle_of_roaming(mac_handle) ||
+	    hdd_is_roaming_in_progress(hdd_ctx)) {
+		hdd_info("Reassociation in progress");
+		return -EINVAL;
+	}
+
+	/* Disable Roaming on all adapters before starting bss */
+	wlan_hdd_disable_roaming(adapter);
+
+	sme_config = qdf_mem_malloc(sizeof(*sme_config));
+	if (!sme_config) {
+		hdd_err("failed to allocate memory");
+		ret = -ENOMEM;
+		goto free;
+	}
+
+	iniConfig = hdd_ctx->config;
+	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+
+	clear_bit(ACS_PENDING, &adapter->event_flags);
+	clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
+
+	pConfig = &adapter->session.ap.sap_config;
+	if (!pConfig->channel) {
+		hdd_err("Invalid channel");
+		ret = -EINVAL;
+		goto free;
+	}
+
+	/* Mark the indoor channel (passive) to disable */
+	if (iniConfig->force_ssc_disable_indoor_channel) {
+		hdd_update_indoor_channel(hdd_ctx, true);
+		if (QDF_IS_STATUS_ERROR(
+		    sme_update_channel_list(mac_handle))) {
+			hdd_update_indoor_channel(hdd_ctx, false);
+			hdd_err("Can't start BSS: update channel list failed");
+			ret = -EINVAL;
+			goto free;
+		}
+	}
+	if (adapter->device_mode == QDF_SAP_MODE) {
+		/*
+		 * Disable the channels received in command
+		 * SET_DISABLE_CHANNEL_LIST
+		 */
+		status = wlan_hdd_disable_channels(hdd_ctx);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("Disable channel list fail");
+		else
+			hdd_check_and_disconnect_sta_on_invalid_channel(
+								hdd_ctx);
+	}
+
+	pBeacon = adapter->session.ap.beacon;
+	pMgmt_frame = (struct ieee80211_mgmt *)pBeacon->head;
+
+	pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
+	pConfig->dfs_cac_offload = hdd_ctx->dfs_cac_offload;
+
+	status = ucfg_mlme_get_auto_channel_weight(hdd_ctx->psoc,
+						   &auto_channel_select_weight);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("ucfg_mlme_get_auto_channel_weight failed, set def");
+
+	pConfig->auto_channel_select_weight = auto_channel_select_weight;
+	pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch;
+	ucfg_mlme_get_sap_chn_switch_bcn_count(hdd_ctx->psoc, &value);
+	pConfig->sap_chanswitch_beacon_cnt = value;
+	ucfg_mlme_get_sap_channel_switch_mode(hdd_ctx->psoc, &val);
+	pConfig->sap_chanswitch_mode = val;
+
+	/* channel is already set in the set_channel Call back */
+	/* pConfig->channel = pCommitConfig->channel; */
+
+	/* Protection parameter to enable or disable */
+	pConfig->protEnabled = iniConfig->apProtEnabled;
+
+	ucfg_mlme_get_sap_chan_switch_rate_enabled(hdd_ctx->psoc, &val);
+	pConfig->chan_switch_hostapd_rate_enabled = val;
+
+	if (QDF_STATUS_SUCCESS ==
+	    ucfg_policy_mgr_get_mcc_scc_switch(hdd_ctx->psoc,
+					       &mcc_to_scc_switch)) {
+		if (mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE)
+			pConfig->chan_switch_hostapd_rate_enabled = false;
+	}
+	pConfig->enOverLapCh = iniConfig->gEnableOverLapCh;
+
+	ucfg_mlme_get_sap_reduces_beacon_interval(hdd_ctx->psoc, &value);
+	pConfig->dtim_period = pBeacon->dtim_period;
+	pConfig->dfs_beacon_tx_enhanced = iniConfig->dfs_beacon_tx_enhanced;
+
+	pConfig->reduced_beacon_interval = value;
+	hdd_debug("acs_mode %d", pConfig->acs_cfg.acs_mode);
+
+	if (pConfig->acs_cfg.acs_mode == true) {
+		hdd_debug("acs_channel %d, acs_dfs_mode %d",
+			hdd_ctx->acs_policy.acs_channel,
+			hdd_ctx->acs_policy.acs_dfs_mode);
+
+		if (hdd_ctx->acs_policy.acs_channel)
+			pConfig->channel = hdd_ctx->acs_policy.acs_channel;
+		mode = hdd_ctx->acs_policy.acs_dfs_mode;
+		pConfig->acs_dfs_mode = wlan_hdd_get_dfs_mode(mode);
+	}
+
+	policy_mgr_update_user_config_sap_chan(hdd_ctx->psoc,
+					       pConfig->channel);
+	hdd_debug("pConfig->channel %d, pConfig->acs_dfs_mode %d",
+		pConfig->channel, pConfig->acs_dfs_mode);
+
+	hdd_debug("****pConfig->dtim_period=%d***",
+		pConfig->dtim_period);
+
+	if (adapter->device_mode == QDF_SAP_MODE) {
+		pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_COUNTRY,
+					pBeacon->tail, pBeacon->tail_len);
+		if (pIe) {
+			if (pIe[1] < IEEE80211_COUNTRY_IE_MIN_LEN) {
+				hdd_err("Invalid Country IE len: %d", pIe[1]);
+				ret = -EINVAL;
+				goto error;
+			}
+
+			pConfig->ieee80211d = 1;
+			qdf_mem_copy(pConfig->countryCode, &pIe[2], 3);
+			status = ucfg_reg_set_country(hdd_ctx->pdev,
+						      pConfig->countryCode);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				hdd_err("Failed to set country");
+				pConfig->ieee80211d = 0;
+			}
+		} else {
+			pConfig->countryCode[0] = hdd_ctx->reg.alpha2[0];
+			pConfig->countryCode[1] = hdd_ctx->reg.alpha2[1];
+			pConfig->ieee80211d = 0;
+		}
+
+		ret = wlan_hdd_sap_cfg_dfs_override(adapter);
+		if (ret < 0)
+			goto error;
+
+		if (!ret && wlan_reg_is_dfs_ch(hdd_ctx->pdev, pConfig->channel))
+			hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
+
+		if (QDF_STATUS_SUCCESS !=
+		    wlan_hdd_validate_operation_channel(adapter,
+							pConfig->channel)) {
+			hdd_err("Invalid Channel: %d", pConfig->channel);
+			ret = -EINVAL;
+			goto error;
+		}
+
+		/* reject SAP if DFS channel scan is not allowed */
+		if (!(hdd_ctx->config->enableDFSChnlScan) &&
+		    (CHANNEL_STATE_DFS ==
+		     wlan_reg_get_channel_state(hdd_ctx->pdev,
+						pConfig->channel))) {
+			hdd_err("No SAP start on DFS channel");
+			ret = -EOPNOTSUPP;
+			goto error;
+		}
+
+		if (iniConfig->ignoreCAC ||
+		    ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
+		    iniConfig->sta_sap_scc_on_dfs_chan))
+			ignore_cac = 1;
+
+		wlansap_set_dfs_ignore_cac(mac_handle, ignore_cac);
+		wlansap_set_dfs_restrict_japan_w53(mac_handle,
+			iniConfig->gDisableDfsJapanW53);
+		wlansap_set_dfs_preferred_channel_location(mac_handle,
+			iniConfig->gSapPreferredChanLocation);
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+		wlan_sap_set_channel_avoidance(mac_handle,
+					iniConfig->sap_channel_avoidance);
+#endif
+	} else if (adapter->device_mode == QDF_P2P_GO_MODE) {
+		pConfig->countryCode[0] = hdd_ctx->reg.alpha2[0];
+		pConfig->countryCode[1] = hdd_ctx->reg.alpha2[1];
+		pConfig->ieee80211d = 0;
+	} else {
+		pConfig->ieee80211d = 0;
+	}
+
+	wlansap_set_tx_leakage_threshold(mac_handle,
+		iniConfig->sap_tx_leakage_threshold);
+
+	capab_info = pMgmt_frame->u.beacon.capab_info;
+
+	pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
+			    WLAN_CAPABILITY_PRIVACY) ? true : false;
+
+	(WLAN_HDD_GET_AP_CTX_PTR(adapter))->privacy = pConfig->privacy;
+
+	/*Set wps station to configured */
+	pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
+
+	if (pIe) {
+		/* To acess pIe[15], length needs to be atlest 14 */
+		if (pIe[1] < 14) {
+			hdd_err("**Wps Ie Length(%hhu) is too small***",
+				pIe[1]);
+			ret = -EINVAL;
+			goto error;
+		} else if (memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) ==
+			   0) {
+			hdd_debug("** WPS IE(len %d) ***", (pIe[1] + 2));
+			/* Check 15 bit of WPS IE as it contain information for
+			 * wps state
+			 */
+			if (SAP_WPS_ENABLED_UNCONFIGURED == pIe[15]) {
+				pConfig->wps_state =
+					SAP_WPS_ENABLED_UNCONFIGURED;
+			} else if (SAP_WPS_ENABLED_CONFIGURED == pIe[15]) {
+				pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
+			}
+		}
+	} else {
+		hdd_debug("WPS disabled");
+		pConfig->wps_state = SAP_WPS_DISABLED;
+	}
+	/* Forward WPS PBC probe request frame up */
+	pConfig->fwdWPSPBCProbeReq = 1;
+
+	pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
+	pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
+	(WLAN_HDD_GET_AP_CTX_PTR(adapter))->encryption_type =
+		eCSR_ENCRYPT_TYPE_NONE;
+
+	pConfig->RSNWPAReqIELength = 0;
+	memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
+	pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_RSN, pBeacon->tail,
+				       pBeacon->tail_len);
+	if (pIe && pIe[1]) {
+		pConfig->RSNWPAReqIELength = pIe[1] + 2;
+		if (pConfig->RSNWPAReqIELength < sizeof(pConfig->RSNWPAReqIE))
+			memcpy(&pConfig->RSNWPAReqIE[0], pIe,
+			       pConfig->RSNWPAReqIELength);
+		else
+			hdd_err("RSNWPA IE MAX Length exceeded; length =%d",
+			       pConfig->RSNWPAReqIELength);
+		/* The actual processing may eventually be more extensive than
+		 * this. Right now, just consume any PMKIDs that are sent in
+		 * by the app.
+		 */
+		status =
+			hdd_softap_unpack_ie(cds_get_context
+						     (QDF_MODULE_ID_SME),
+					     &RSNEncryptType, &mcRSNEncryptType,
+					     &RSNAuthType, &MFPCapable,
+					     &MFPRequired,
+					     pConfig->RSNWPAReqIE[1] + 2,
+					     pConfig->RSNWPAReqIE);
+
+		if (QDF_STATUS_SUCCESS == status) {
+			/* Now copy over all the security attributes you have
+			 * parsed out. Use the cipher type in the RSN IE
+			 */
+			pConfig->RSNEncryptType = RSNEncryptType;
+			pConfig->mcRSNEncryptType = mcRSNEncryptType;
+			(WLAN_HDD_GET_AP_CTX_PTR(adapter))->
+			encryption_type = RSNEncryptType;
+			hdd_debug("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d",
+			       RSNAuthType, RSNEncryptType, mcRSNEncryptType);
+		}
+	}
+
+	pIe = wlan_get_vendor_ie_ptr_from_oui(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
+					     pBeacon->tail, pBeacon->tail_len);
+
+	if (pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA)) {
+		if (pConfig->RSNWPAReqIE[0]) {
+			/*Mixed mode WPA/WPA2 */
+			prev_rsn_length = pConfig->RSNWPAReqIELength;
+			pConfig->RSNWPAReqIELength += pIe[1] + 2;
+			if (pConfig->RSNWPAReqIELength <
+			    sizeof(pConfig->RSNWPAReqIE))
+				memcpy(&pConfig->RSNWPAReqIE[0] +
+				       prev_rsn_length, pIe, pIe[1] + 2);
+			else
+				hdd_err("RSNWPA IE MAX Length exceeded; length: %d",
+				       pConfig->RSNWPAReqIELength);
+		} else {
+			pConfig->RSNWPAReqIELength = pIe[1] + 2;
+			if (pConfig->RSNWPAReqIELength <
+			    sizeof(pConfig->RSNWPAReqIE))
+				memcpy(&pConfig->RSNWPAReqIE[0], pIe,
+				       pConfig->RSNWPAReqIELength);
+			else
+				hdd_err("RSNWPA IE MAX Length exceeded; length: %d",
+				       pConfig->RSNWPAReqIELength);
+			status = hdd_softap_unpack_ie
+					(cds_get_context(QDF_MODULE_ID_SME),
+					 &RSNEncryptType,
+					 &mcRSNEncryptType, &RSNAuthType,
+					 &MFPCapable, &MFPRequired,
+					 pConfig->RSNWPAReqIE[1] + 2,
+					 pConfig->RSNWPAReqIE);
+
+			if (QDF_STATUS_SUCCESS == status) {
+				/* Now copy over all the security attributes
+				 * you have parsed out. Use the cipher type
+				 * in the RSN IE
+				 */
+				pConfig->RSNEncryptType = RSNEncryptType;
+				pConfig->mcRSNEncryptType = mcRSNEncryptType;
+				(WLAN_HDD_GET_AP_CTX_PTR(adapter))->
+				encryption_type = RSNEncryptType;
+				hdd_debug("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d",
+				       RSNAuthType, RSNEncryptType,
+				       mcRSNEncryptType);
+			}
+		}
+	}
+
+	if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
+		hdd_err("**RSNWPAReqIELength is too large***");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	pConfig->SSIDinfo.ssidHidden = false;
+
+	if (ssid != NULL) {
+		qdf_mem_copy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
+		pConfig->SSIDinfo.ssid.length = ssid_len;
+
+		switch (hidden_ssid) {
+		case NL80211_HIDDEN_SSID_NOT_IN_USE:
+			hdd_debug("HIDDEN_SSID_NOT_IN_USE");
+			pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE;
+			break;
+		case NL80211_HIDDEN_SSID_ZERO_LEN:
+			hdd_debug("HIDDEN_SSID_ZERO_LEN");
+			pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN;
+			break;
+		case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
+			hdd_debug("HIDDEN_SSID_ZERO_CONTENTS");
+			pConfig->SSIDinfo.ssidHidden =
+				eHIDDEN_SSID_ZERO_CONTENTS;
+			break;
+		default:
+			hdd_err("Wrong hidden_ssid param: %d", hidden_ssid);
+			break;
+		}
+	}
+
+	qdf_mem_copy(pConfig->self_macaddr.bytes,
+		     adapter->mac_addr.bytes,
+		     QDF_MAC_ADDR_SIZE);
+
+	/* default value */
+	pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
+	pConfig->num_accept_mac = 0;
+	pConfig->num_deny_mac = 0;
+	ucfg_policy_mgr_get_conc_rule1(hdd_ctx->psoc, &conc_rule1);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	/*
+	 * We don't want P2PGO to follow STA's channel
+	 * so lets limit the logic for SAP only.
+	 * Later if we decide to make p2pgo follow STA's
+	 * channel then remove this check.
+	 */
+	if ((0 == conc_rule1) ||
+	    (conc_rule1 && (QDF_SAP_MODE == adapter->device_mode)))
+		pConfig->cc_switch_mode = mcc_to_scc_switch;
+#endif
+
+	if (!(ssid && qdf_str_len(PRE_CAC_SSID) == ssid_len &&
+	      (0 == qdf_mem_cmp(ssid, PRE_CAC_SSID, ssid_len)))) {
+		pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_SUPP_RATES,
+					&pMgmt_frame->u.beacon.variable[0],
+					pBeacon->head_len);
+
+		if (pIe != NULL) {
+			pIe++;
+			if (pIe[0] > SIR_MAC_RATESET_EID_MAX) {
+				hdd_err("Invalid supported rates %d",
+					pIe[0]);
+				ret = -EINVAL;
+				goto error;
+			}
+			pConfig->supported_rates.numRates = pIe[0];
+			pIe++;
+			for (i = 0;
+			     i < pConfig->supported_rates.numRates; i++) {
+				if (pIe[i]) {
+					pConfig->supported_rates.rate[i] = pIe[i];
+					hdd_debug("Configured Supported rate is %2x",
+						  pConfig->supported_rates.rate[i]);
+				}
+			}
+		}
+		pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_EXT_SUPP_RATES,
+					       pBeacon->tail,
+					       pBeacon->tail_len);
+		if (pIe != NULL) {
+			pIe++;
+			if (pIe[0] > SIR_MAC_RATESET_EID_MAX) {
+				hdd_err("Invalid supported rates %d",
+					pIe[0]);
+				ret = -EINVAL;
+				goto error;
+			}
+			pConfig->extended_rates.numRates = pIe[0];
+			pIe++;
+			for (i = 0; i < pConfig->extended_rates.numRates; i++) {
+				if (pIe[i]) {
+					pConfig->extended_rates.rate[i] = pIe[i];
+					hdd_debug("Configured ext Supported rate is %2x",
+						  pConfig->extended_rates.rate[i]);
+				}
+			}
+		}
+	}
+
+	if (!cds_is_sub_20_mhz_enabled())
+		wlan_hdd_set_sap_hwmode(adapter);
+
+	status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		hdd_err("Failed to get vht_for_24ghz");
+
+	if (IS_24G_CH(pConfig->channel) && bval &&
+	    (pConfig->SapHw_mode == eCSR_DOT11_MODE_11n ||
+	    pConfig->SapHw_mode == eCSR_DOT11_MODE_11n_ONLY))
+		pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac;
+
+	if (((adapter->device_mode == QDF_SAP_MODE) &&
+	     (hdd_ctx->config->sap_force_11n_for_11ac)) ||
+	     ((adapter->device_mode == QDF_P2P_GO_MODE) &&
+	     (hdd_ctx->config->go_force_11n_for_11ac))) {
+		if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac ||
+		    pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY)
+			pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
+	}
+
+	qdf_mem_zero(sme_config, sizeof(*sme_config));
+	sme_get_config_param(mac_handle, sme_config);
+	/* Override hostapd.conf wmm_enabled only for 11n and 11AC configs (IOT)
+	 * As per spec 11N/AC STA are QOS STA and may not connect or throughput
+	 * may not be good with non QOS 11N AP
+	 * Default: enable QOS for SAP unless WMM IE not present for 11bga
+	 */
+	sme_config->csrConfig.WMMSupportMode = eCsrRoamWmmAuto;
+	pIe = wlan_get_vendor_ie_ptr_from_oui(WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE,
+					pBeacon->tail, pBeacon->tail_len);
+	if (!pIe && (pConfig->SapHw_mode == eCSR_DOT11_MODE_11a ||
+		pConfig->SapHw_mode == eCSR_DOT11_MODE_11g ||
+		pConfig->SapHw_mode == eCSR_DOT11_MODE_11b))
+		sme_config->csrConfig.WMMSupportMode = eCsrRoamWmmNoQos;
+	sme_update_config(mac_handle, sme_config);
+
+	if (!((adapter->device_mode == QDF_SAP_MODE) &&
+	     (hdd_ctx->config->sap_force_11n_for_11ac)) ||
+	     ((adapter->device_mode == QDF_P2P_GO_MODE) &&
+	     (hdd_ctx->config->go_force_11n_for_11ac))) {
+		pConfig->ch_width_orig =
+			hdd_map_nl_chan_width(pConfig->ch_width_orig);
+	} else {
+		if (pConfig->ch_width_orig >= NL80211_CHAN_WIDTH_40)
+			pConfig->ch_width_orig = CH_WIDTH_40MHZ;
+		else
+			pConfig->ch_width_orig = CH_WIDTH_20MHZ;
+	}
+
+	if (wlan_hdd_setup_driver_overrides(adapter)) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	pConfig->ch_params.ch_width = pConfig->ch_width_orig;
+	wlan_reg_set_channel_params(hdd_ctx->pdev, pConfig->channel,
+				    pConfig->sec_ch, &pConfig->ch_params);
+
+	/* ht_capab is not what the name conveys,
+	 * this is used for protection bitmap
+	 */
+	pConfig->ht_capab = iniConfig->apProtection;
+
+	if (0 != wlan_hdd_cfg80211_update_apies(adapter)) {
+		hdd_err("SAP Not able to set AP IEs");
+		ret = -EINVAL;
+		goto error;
+	}
+	/* Uapsd Enabled Bit */
+	pConfig->UapsdEnable = iniConfig->apUapsdEnabled;
+	/* Enable OBSS protection */
+	pConfig->obssProtEnabled = iniConfig->apOBSSProtEnabled;
+
+#ifdef WLAN_FEATURE_11W
+	pConfig->mfpCapable = MFPCapable;
+	pConfig->mfpRequired = MFPRequired;
+	hdd_debug("Soft AP MFP capable %d, MFP required %d",
+	       pConfig->mfpCapable, pConfig->mfpRequired);
+#endif
+
+	hdd_debug("SOftAP macaddress : " MAC_ADDRESS_STR,
+	       MAC_ADDR_ARRAY(adapter->mac_addr.bytes));
+	hdd_debug("ssid =%s, beaconint=%d, channel=%d",
+	       pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
+	       (int)pConfig->channel);
+	hdd_debug("hw_mode=%x, privacy=%d, authType=%d",
+	       pConfig->SapHw_mode, pConfig->privacy, pConfig->authType);
+	hdd_debug("RSN/WPALen=%d, Uapsd = %d",
+	       (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
+	hdd_debug("ProtEnabled = %d, OBSSProtEnabled = %d",
+	       pConfig->protEnabled, pConfig->obssProtEnabled);
+	hdd_debug("ChanSwitchHostapdRateEnabled = %d",
+		pConfig->chan_switch_hostapd_rate_enabled);
+
+	mutex_lock(&hdd_ctx->sap_lock);
+	if (cds_is_driver_unloading()) {
+		mutex_unlock(&hdd_ctx->sap_lock);
+
+		hdd_err("The driver is unloading, ignore the bss starting");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
+		mutex_unlock(&hdd_ctx->sap_lock);
+
+		wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
+		/* Bss already started. just return. */
+		/* TODO Probably it should update some beacon params. */
+		hdd_debug("Bss Already started...Ignore the request");
+		hdd_exit();
+		ret = 0;
+		goto free;
+	}
+
+	if (check_for_concurrency) {
+		if (!policy_mgr_allow_concurrency(hdd_ctx->psoc,
+				policy_mgr_convert_device_mode_to_qdf_type(
+					adapter->device_mode),
+					pConfig->channel, HW_MODE_20_MHZ)) {
+			mutex_unlock(&hdd_ctx->sap_lock);
+
+			hdd_err("This concurrency combination is not allowed");
+			ret = -EINVAL;
+			goto error;
+		}
+	}
+
+	if (!hdd_set_connection_in_progress(true)) {
+		mutex_unlock(&hdd_ctx->sap_lock);
+
+		hdd_err("Can't start BSS: set connection in progress failed");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	pConfig->persona = adapter->device_mode;
+
+	pSapEventCallback = hdd_hostapd_sap_event_cb;
+
+	(WLAN_HDD_GET_AP_CTX_PTR(adapter))->dfs_cac_block_tx = true;
+	set_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
+
+	qdf_event_reset(&hostapd_state->qdf_event);
+	status = wlansap_start_bss(
+		WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+		pSapEventCallback, pConfig, adapter->dev);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		mutex_unlock(&hdd_ctx->sap_lock);
+
+		hdd_set_connection_in_progress(false);
+		hdd_err("SAP Start Bss fail");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	hdd_debug("Waiting for Scan to complete(auto mode) and BSS to start");
+
+	qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
+					SME_CMD_START_STOP_BSS_TIMEOUT);
+
+	wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		mutex_unlock(&hdd_ctx->sap_lock);
+
+		hdd_err("qdf wait for single_event failed!!");
+		hdd_set_connection_in_progress(false);
+		sme_get_command_q_status(mac_handle);
+		wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(adapter));
+		QDF_ASSERT(0);
+		ret = -EINVAL;
+		goto error;
+	}
+	/* Successfully started Bss update the state bit. */
+	set_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
+
+	mutex_unlock(&hdd_ctx->sap_lock);
+
+	/* Initialize WMM configuation */
+	hdd_wmm_init(adapter);
+	if (hostapd_state->bss_state == BSS_START) {
+		policy_mgr_incr_active_session(hdd_ctx->psoc,
+					adapter->device_mode,
+					adapter->session_id);
+		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
+					    true);
+	}
+
+	wlan_hdd_is_dhcp_enabled(hdd_ctx, adapter);
+	ucfg_p2p_status_start_bss(adapter->vdev);
+
+	/* Check and restart SAP if it is on unsafe channel */
+	hdd_unsafe_channel_restart_sap(hdd_ctx);
+
+	hdd_set_connection_in_progress(false);
+
+	ret = 0;
+	goto free;
+
+error:
+	if (adapter->device_mode == QDF_SAP_MODE)
+		wlan_hdd_restore_channels(hdd_ctx, true);
+
+	/* Revert the indoor to passive marking if START BSS fails */
+	if (iniConfig->force_ssc_disable_indoor_channel) {
+		hdd_update_indoor_channel(hdd_ctx, false);
+		sme_update_channel_list(mac_handle);
+	}
+	clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
+	qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
+	wlan_hdd_undo_acs(adapter);
+	wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
+
+free:
+	/* Enable Roaming after start bss in case of failure/success */
+	wlan_hdd_enable_roaming(adapter);
+	qdf_mem_free(sme_config);
+	return ret;
+}
+
+int hdd_destroy_acs_timer(struct hdd_adapter *adapter)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+
+	if (!adapter->session.ap.vendor_acs_timer_initialized)
+		return 0;
+
+	adapter->session.ap.vendor_acs_timer_initialized = false;
+
+	clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
+	if (QDF_TIMER_STATE_RUNNING ==
+			adapter->session.ap.vendor_acs_timer.state) {
+		qdf_status =
+			qdf_mc_timer_stop(&adapter->session.ap.
+					vendor_acs_timer);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			hdd_err("Failed to stop ACS timer");
+	}
+
+	if (adapter->session.ap.vendor_acs_timer.user_data)
+		qdf_mem_free(adapter->session.ap.vendor_acs_timer.user_data);
+
+	qdf_mc_timer_destroy(&adapter->session.ap.vendor_acs_timer);
+
+	return 0;
+}
+
+/**
+ * __wlan_hdd_cfg80211_stop_ap() - stop soft ap
+ * @wiphy: Pointer to wiphy structure
+ * @dev: Pointer to net_device structure
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
+					struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_adapter *sta_adapter;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	tSirUpdateIE updateIE;
+	struct hdd_beacon_data *old;
+	int ret;
+	mac_handle_t mac_handle;
+	uint8_t conc_rule1 = 0;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
+		hdd_err("Driver module is closed; dropping request");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_STOP_AP,
+			 adapter->session_id, adapter->device_mode));
+
+	if (!(adapter->device_mode == QDF_SAP_MODE ||
+	      adapter->device_mode == QDF_P2P_GO_MODE)) {
+		return -EOPNOTSUPP;
+	}
+
+	/* Clear SOFTAP_INIT_DONE flag to mark stop_ap deinit. So that we do
+	 * not restart SAP after SSR as SAP is already stopped from user space.
+	 * This update is moved to start of this function to resolve stop_ap
+	 * call during SSR case. Adapter gets cleaned up as part of SSR.
+	 */
+	clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
+	hdd_debug("Device_mode %s(%d)",
+		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	/*
+	 * If a STA connection is in progress in another adapter, disconnect
+	 * the STA and complete the SAP operation. STA will reconnect
+	 * after SAP stop is done.
+	 */
+	sta_adapter = hdd_get_sta_connection_in_progress(hdd_ctx);
+	if (sta_adapter) {
+		hdd_debug("Disconnecting STA with session id: %d",
+			  sta_adapter->session_id);
+		wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
+	}
+
+	if (adapter->device_mode == QDF_SAP_MODE)
+		wlan_hdd_del_station(adapter);
+
+	cds_flush_work(&adapter->sap_stop_bss_work);
+	ucfg_policy_mgr_get_conc_rule1(hdd_ctx->psoc, &conc_rule1);
+	/*
+	 * When ever stop ap adapter gets called, we need to check
+	 * whether any restart AP work is pending. If any restart is pending
+	 * then lets finish it and go ahead from there.
+	 */
+	if (conc_rule1 && (QDF_SAP_MODE == adapter->device_mode)) {
+		cds_flush_work(&hdd_ctx->sap_start_work);
+		hdd_debug("Canceled the pending restart work");
+		qdf_spin_lock(&hdd_ctx->sap_update_info_lock);
+		hdd_ctx->is_sap_restart_required = false;
+		qdf_spin_unlock(&hdd_ctx->sap_update_info_lock);
+	}
+	adapter->session.ap.sap_config.acs_cfg.acs_mode = false;
+	qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
+	wlan_hdd_undo_acs(adapter);
+	qdf_mem_zero(&adapter->session.ap.sap_config.acs_cfg,
+						sizeof(struct sap_acs_cfg));
+	hdd_debug("Disabling queues");
+	wlan_hdd_netif_queue_control(adapter,
+				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+				     WLAN_CONTROL_PATH);
+
+	old = adapter->session.ap.beacon;
+	if (!old) {
+		hdd_err("Session id: %d beacon data points to NULL",
+		       adapter->session_id);
+		return -EINVAL;
+	}
+	wlan_hdd_cleanup_actionframe(adapter);
+	wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
+	mutex_lock(&hdd_ctx->sap_lock);
+	if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
+		struct hdd_hostapd_state *hostapd_state =
+			WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+
+		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
+		status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(adapter));
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			qdf_status =
+				qdf_wait_for_event_completion(&hostapd_state->
+					qdf_stop_bss_event,
+					SME_CMD_START_STOP_BSS_TIMEOUT);
+
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+				hdd_err("qdf wait for single_event failed!!");
+				QDF_ASSERT(0);
+			}
+		}
+		clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
+		hdd_stop_tsf_sync(adapter);
+
+		/*BSS stopped, clear the active sessions for this device mode*/
+		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
+						adapter->device_mode,
+						adapter->session_id);
+		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
+		adapter->session.ap.beacon = NULL;
+		qdf_mem_free(old);
+	}
+	mutex_unlock(&hdd_ctx->sap_lock);
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (wlan_sap_is_pre_cac_active(mac_handle))
+		hdd_clean_up_pre_cac_interface(hdd_ctx);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Stopping the BSS");
+		return -EINVAL;
+	}
+
+	qdf_copy_macaddr(&updateIE.bssid, &adapter->mac_addr);
+	updateIE.smeSessionId = adapter->session_id;
+	updateIE.ieBufferlength = 0;
+	updateIE.pAdditionIEBuffer = NULL;
+	updateIE.append = true;
+	updateIE.notify = true;
+	if (sme_update_add_ie(mac_handle,
+			      &updateIE,
+			      eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) {
+		hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
+	}
+
+	if (sme_update_add_ie(mac_handle,
+			      &updateIE,
+			      eUPDATE_IE_ASSOC_RESP) == QDF_STATUS_E_FAILURE) {
+		hdd_err("Could not pass on ASSOC_RSP data to PE");
+	}
+	/* Reset WNI_CFG_PROBE_RSP Flags */
+	wlan_hdd_reset_prob_rspies(adapter);
+	hdd_destroy_acs_timer(adapter);
+
+	ucfg_p2p_status_stop_bss(adapter->vdev);
+
+	hdd_exit();
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_get_channel_bw() - get channel bandwidth
+ * @width: input channel width in nl80211_chan_width value
+ *
+ * Return: channel width value defined by driver
+ */
+static enum hw_mode_bandwidth wlan_hdd_get_channel_bw(
+					enum nl80211_chan_width width)
+{
+	enum hw_mode_bandwidth ch_bw = HW_MODE_20_MHZ;
+
+	switch (width) {
+	case NL80211_CHAN_WIDTH_20_NOHT:
+	case NL80211_CHAN_WIDTH_20:
+		ch_bw = HW_MODE_20_MHZ;
+		break;
+	case NL80211_CHAN_WIDTH_40:
+		ch_bw = HW_MODE_40_MHZ;
+		break;
+	case NL80211_CHAN_WIDTH_80:
+		ch_bw = HW_MODE_80_MHZ;
+		break;
+	case NL80211_CHAN_WIDTH_80P80:
+		ch_bw = HW_MODE_80_PLUS_80_MHZ;
+		break;
+	case NL80211_CHAN_WIDTH_160:
+		ch_bw = HW_MODE_160_MHZ;
+		break;
+	default:
+		hdd_err("Invalid width: %d, using default 20MHz", width);
+		break;
+	}
+
+	return ch_bw;
+}
+
+/**
+ * wlan_hdd_cfg80211_stop_ap() - stop sap
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to netdev
+ *
+ * Return: zero for success non-zero for failure
+ */
+int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
+				struct net_device *dev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) || \
+	defined(CFG80211_BEACON_TX_RATE_CUSTOM_BACKPORT)
+/**
+ * hdd_get_data_rate_from_rate_mask() - convert mask to rate
+ * @wiphy: Pointer to wiphy
+ * @band: band
+ * @bit_rate_mask: pointer to bit_rake_mask
+ *
+ * This function takes band and bit_rate_mask as input and
+ * derives the beacon_tx_rate based on the supported rates
+ * published as part of wiphy register.
+ *
+ * Return: data rate for success or zero for failure
+ */
+static uint16_t hdd_get_data_rate_from_rate_mask(struct wiphy *wiphy,
+		enum nl80211_band band,
+		struct cfg80211_bitrate_mask *bit_rate_mask)
+{
+	struct ieee80211_supported_band *sband = wiphy->bands[band];
+	int sband_n_bitrates;
+	struct ieee80211_rate *sband_bitrates;
+	int i;
+
+	if (sband) {
+		sband_bitrates = sband->bitrates;
+		sband_n_bitrates = sband->n_bitrates;
+		for (i = 0; i < sband_n_bitrates; i++) {
+			if (bit_rate_mask->control[band].legacy ==
+			    sband_bitrates[i].hw_value)
+				return sband_bitrates[i].bitrate;
+		}
+	}
+	return 0;
+}
+
+/**
+ * hdd_update_beacon_rate() - Update beacon tx rate
+ * @adapter: Pointer to hdd_adapter_t
+ * @wiphy: Pointer to wiphy
+ * @params: Pointet to cfg80211_ap_settings
+ *
+ * This function updates the beacon tx rate which is provided
+ * as part of cfg80211_ap_settions in to the sap_config
+ * structure
+ *
+ * Return: none
+ */
+static void hdd_update_beacon_rate(struct hdd_adapter *adapter,
+		struct wiphy *wiphy,
+		struct cfg80211_ap_settings *params)
+{
+	struct cfg80211_bitrate_mask *beacon_rate_mask;
+	enum nl80211_band band;
+
+	band = params->chandef.chan->band;
+	beacon_rate_mask = &params->beacon_rate;
+	if (beacon_rate_mask->control[band].legacy) {
+		adapter->session.ap.sap_config.beacon_tx_rate =
+			hdd_get_data_rate_from_rate_mask(wiphy, band,
+					beacon_rate_mask);
+		hdd_debug("beacon mask value %u, rate %hu",
+			  params->beacon_rate.control[0].legacy,
+			  adapter->session.ap.sap_config.beacon_tx_rate);
+	}
+}
+#else
+static void hdd_update_beacon_rate(struct hdd_adapter *adapter,
+		struct wiphy *wiphy,
+		struct cfg80211_ap_settings *params)
+{
+}
+#endif
+
+
+/**
+ * __wlan_hdd_cfg80211_start_ap() - start soft ap mode
+ * @wiphy: Pointer to wiphy structure
+ * @dev: Pointer to net_device structure
+ * @params: Pointer to AP settings parameters
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
+					struct net_device *dev,
+					struct cfg80211_ap_settings *params)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	enum hw_mode_bandwidth channel_width;
+	int status;
+	struct sme_sta_inactivity_timeout  *sta_inactivity_timer;
+	uint8_t channel;
+	bool sta_sap_scc_on_dfs_chan;
+	uint16_t sta_cnt;
+	bool val;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	hdd_enter();
+
+	clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_START_AP, adapter->session_id,
+			 params->beacon_interval));
+	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
+		hdd_err("HDD adapter magic is invalid");
+		return -ENODEV;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return status;
+
+	hdd_debug("adapter = %pK, Device mode %s(%d) sub20 %d",
+		  adapter, qdf_opmode_str(adapter->device_mode),
+		  adapter->device_mode, cds_is_sub_20_mhz_enabled());
+
+	if (policy_mgr_is_hw_mode_change_in_progress(hdd_ctx->psoc)) {
+		status = policy_mgr_wait_for_connection_update(
+			hdd_ctx->psoc);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("qdf wait for event failed!!");
+			return -EINVAL;
+		}
+	}
+
+	channel_width = wlan_hdd_get_channel_bw(params->chandef.width);
+	channel = ieee80211_frequency_to_channel(
+				params->chandef.chan->center_freq);
+	if (!channel) {
+		hdd_err("Invalid channel");
+		return -EINVAL;
+	}
+
+	if (policy_mgr_is_sap_mandatory_chan_list_enabled(hdd_ctx->psoc)) {
+		if (WLAN_REG_IS_5GHZ_CH(channel)) {
+			hdd_debug("channel %hu, sap mandatory chan list enabled",
+			          channel);
+			if (!policy_mgr_get_sap_mandatory_chan_list_len(
+							hdd_ctx->psoc))
+				policy_mgr_init_sap_mandatory_2g_chan(
+							hdd_ctx->psoc);
+
+			policy_mgr_add_sap_mandatory_chan(hdd_ctx->psoc,
+							  channel);
+		} else {
+			policy_mgr_init_sap_mandatory_2g_chan(
+							hdd_ctx->psoc);
+		}
+	}
+
+	adapter->session.ap.sap_config.ch_params.center_freq_seg0 =
+				cds_freq_to_chan(params->chandef.center_freq1);
+	adapter->session.ap.sap_config.ch_params.center_freq_seg1 =
+				cds_freq_to_chan(params->chandef.center_freq2);
+
+	sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
+							hdd_ctx->psoc);
+	sta_cnt =
+		policy_mgr_mode_specific_connection_count(
+					hdd_ctx->psoc, PM_STA_MODE, NULL);
+
+	hdd_debug("sta_sap_scc_on_dfs_chan %u, sta_cnt %u",
+		  sta_sap_scc_on_dfs_chan, sta_cnt);
+
+	/* if sta_sap_scc_on_dfs_chan ini is set, DFS master capability is
+	 * assumed disabled in the driver.
+	 */
+	if ((reg_get_channel_state(hdd_ctx->pdev, channel) ==
+	     CHANNEL_STATE_DFS) && sta_sap_scc_on_dfs_chan && !sta_cnt) {
+		hdd_err("SAP not allowed on DFS channel!!");
+		return -EINVAL;
+	}
+	if (!reg_is_etsi13_srd_chan_allowed_master_mode(hdd_ctx->pdev) &&
+	    reg_is_etsi13_srd_chan(hdd_ctx->pdev, channel)) {
+		hdd_err("SAP not allowed on SRD channel.");
+		return -EINVAL;
+	}
+	if (cds_is_sub_20_mhz_enabled()) {
+		enum channel_state ch_state;
+		enum phy_ch_width sub_20_ch_width = CH_WIDTH_INVALID;
+		tsap_config_t *sap_cfg = &adapter->session.ap.sap_config;
+
+		if (CHANNEL_STATE_DFS == wlan_reg_get_channel_state(
+					hdd_ctx->pdev, channel)) {
+			hdd_err("Can't start SAP-DFS (channel=%d)with sub 20 MHz ch wd",
+				channel);
+			return -EINVAL;
+		}
+		if (channel_width != HW_MODE_20_MHZ) {
+			hdd_err("Hostapd (20+ MHz) conflits with config.ini (sub 20 MHz)");
+			return -EINVAL;
+		}
+		if (cds_is_5_mhz_enabled())
+			sub_20_ch_width = CH_WIDTH_5MHZ;
+		if (cds_is_10_mhz_enabled())
+			sub_20_ch_width = CH_WIDTH_10MHZ;
+		if (WLAN_REG_IS_5GHZ_CH(channel))
+			ch_state = wlan_reg_get_5g_bonded_channel_state(
+					hdd_ctx->pdev, channel,
+					sub_20_ch_width);
+		else
+			ch_state = wlan_reg_get_2g_bonded_channel_state(
+					hdd_ctx->pdev, channel,
+					sub_20_ch_width, 0);
+		if (CHANNEL_STATE_DISABLE == ch_state) {
+			hdd_err("Given ch width not supported by reg domain");
+			return -EINVAL;
+		}
+		sap_cfg->SapHw_mode = eCSR_DOT11_MODE_abg;
+	}
+
+	/* check if concurrency is allowed */
+	if (!policy_mgr_allow_concurrency(hdd_ctx->psoc,
+				policy_mgr_convert_device_mode_to_qdf_type(
+				adapter->device_mode),
+				channel,
+				channel_width)) {
+		hdd_err("Connection failed due to concurrency check failure");
+		return -EINVAL;
+	}
+
+	status = policy_mgr_reset_connection_update(hdd_ctx->psoc);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("ERR: clear event failed");
+
+	/*
+	 * For Start Ap, the driver checks whether the SAP comes up in a
+	 * different or same band( whether we require DBS or Not).
+	 * If we dont require DBS, then the driver does nothing assuming
+	 * the state would be already in non DBS mode, and just continues
+	 * with vdev up on same MAC, by stoping the opportunistic timer,
+	 * which results in a connection of 1x1 if already the state was in
+	 * DBS. So first stop timer, and check the current hw mode.
+	 * If the SAP comes up in band different from STA, DBS mode is already
+	 * set. IF not, then well check for upgrade, and shift the connection
+	 * back to single MAC 2x2 (if initial was 2x2).
+	 */
+
+	policy_mgr_checkn_update_hw_mode_single_mac_mode(hdd_ctx->psoc,
+							 channel);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to stop DBS opportunistic timer");
+		return -EINVAL;
+	}
+
+	status = policy_mgr_current_connections_update(hdd_ctx->psoc,
+			adapter->session_id, channel,
+			POLICY_MGR_UPDATE_REASON_START_AP);
+	if (status == QDF_STATUS_E_FAILURE) {
+		hdd_err("ERROR: connections update failed!!");
+		return -EINVAL;
+	}
+
+	if (QDF_STATUS_SUCCESS == status) {
+		status = policy_mgr_wait_for_connection_update(hdd_ctx->psoc);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("ERROR: qdf wait for event failed!!");
+			return -EINVAL;
+		}
+	}
+
+	if (adapter->device_mode == QDF_P2P_GO_MODE) {
+		struct hdd_adapter  *p2p_adapter;
+
+		p2p_adapter = hdd_get_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE);
+		if (p2p_adapter) {
+			hdd_debug("Cancel active p2p device ROC before GO starting");
+			wlan_hdd_cancel_existing_remain_on_channel(
+				p2p_adapter);
+		}
+	}
+
+	if ((adapter->device_mode == QDF_SAP_MODE)
+	    || (adapter->device_mode == QDF_P2P_GO_MODE)
+	    ) {
+		struct hdd_beacon_data *old, *new;
+		enum nl80211_channel_type channel_type;
+		tsap_config_t *sap_config =
+			&((WLAN_HDD_GET_AP_CTX_PTR(adapter))->sap_config);
+
+		old = adapter->session.ap.beacon;
+
+		if (old)
+			return -EALREADY;
+
+		status =
+			wlan_hdd_cfg80211_alloc_new_beacon(adapter, &new,
+							   &params->beacon,
+							   params->dtim_period);
+
+		if (status != 0) {
+			hdd_err("Error!!! Allocating the new beacon");
+			return -EINVAL;
+		}
+		adapter->session.ap.beacon = new;
+
+		if (params->chandef.width < NL80211_CHAN_WIDTH_80)
+			channel_type = cfg80211_get_chandef_type(
+						&(params->chandef));
+		else
+			channel_type = NL80211_CHAN_HT40PLUS;
+
+
+		wlan_hdd_set_channel(wiphy, dev,
+				     &params->chandef,
+				     channel_type);
+
+		hdd_update_beacon_rate(adapter, wiphy, params);
+
+		/* set authentication type */
+		switch (params->auth_type) {
+		case NL80211_AUTHTYPE_OPEN_SYSTEM:
+			adapter->session.ap.sap_config.authType =
+				eSAP_OPEN_SYSTEM;
+			break;
+		case NL80211_AUTHTYPE_SHARED_KEY:
+			adapter->session.ap.sap_config.authType =
+				eSAP_SHARED_KEY;
+			break;
+		default:
+			adapter->session.ap.sap_config.authType =
+				eSAP_AUTO_SWITCH;
+		}
+		adapter->session.ap.sap_config.ch_width_orig =
+						params->chandef.width;
+
+		status =
+			wlan_hdd_cfg80211_start_bss(adapter,
+				&params->beacon,
+				params->ssid, params->ssid_len,
+				params->hidden_ssid, true);
+
+		if (status != 0) {
+			hdd_err("Error Start bss Failed");
+			goto err_start_bss;
+		}
+
+		hdd_start_tsf_sync(adapter);
+
+		if (wdev->chandef.chan->center_freq !=
+				params->chandef.chan->center_freq)
+			params->chandef = wdev->chandef;
+		/*
+		 * If Do_Not_Break_Stream enabled send avoid channel list
+		 * to application.
+		 */
+		if (policy_mgr_is_dnsc_set(adapter->vdev) &&
+		    sap_config->channel) {
+			wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx,
+							  sap_config->channel);
+		}
+
+		ucfg_mlme_get_sap_inactivity_override(hdd_ctx->psoc, &val);
+		if (val) {
+			sta_inactivity_timer = qdf_mem_malloc(
+					sizeof(*sta_inactivity_timer));
+			if (!sta_inactivity_timer) {
+				hdd_err("Failed to allocate Memory");
+				return QDF_STATUS_E_FAILURE;
+			}
+			sta_inactivity_timer->session_id = adapter->session_id;
+			sta_inactivity_timer->sta_inactivity_timeout =
+				params->inactivity_timeout;
+			sme_update_sta_inactivity_timeout(hdd_ctx->mac_handle,
+							  sta_inactivity_timer);
+			qdf_mem_free(sta_inactivity_timer);
+		}
+	}
+
+	goto success;
+
+err_start_bss:
+	if (adapter->session.ap.beacon)
+		qdf_mem_free(adapter->session.ap.beacon);
+	adapter->session.ap.beacon = NULL;
+
+success:
+	hdd_exit();
+	return status;
+}
+
+/**
+ * wlan_hdd_cfg80211_start_ap() - start sap
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to netdev
+ * @params: Pointer to start ap configuration parameters
+ *
+ * Return: zero for success non-zero for failure
+ */
+int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
+				struct net_device *dev,
+				struct cfg80211_ap_settings *params)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_change_beacon() - change beacon for sofatap/p2p go
+ * @wiphy: Pointer to wiphy structure
+ * @dev: Pointer to net_device structure
+ * @params: Pointer to change beacon parameters
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
+					struct net_device *dev,
+					struct cfg80211_beacon_data *params)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	struct hdd_beacon_data *old, *new;
+	int status;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
+			 adapter->session_id, adapter->device_mode));
+	hdd_debug("Device_mode %s(%d)",
+		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	if (!(adapter->device_mode == QDF_SAP_MODE ||
+	      adapter->device_mode == QDF_P2P_GO_MODE)) {
+		return -EOPNOTSUPP;
+	}
+
+	old = adapter->session.ap.beacon;
+
+	if (!old) {
+		hdd_err("session id: %d beacon data points to NULL",
+		       adapter->session_id);
+		return -EINVAL;
+	}
+
+	status = wlan_hdd_cfg80211_alloc_new_beacon(adapter, &new, params, 0);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("new beacon alloc failed");
+		return -EINVAL;
+	}
+
+	adapter->session.ap.beacon = new;
+	hdd_debug("update beacon for P2P GO/SAP");
+	status = wlan_hdd_cfg80211_start_bss(adapter, params, NULL,
+					0, 0, false);
+
+	hdd_exit();
+	return status;
+}
+
+/**
+ * wlan_hdd_cfg80211_change_beacon() - change beacon content in sap mode
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to netdev
+ * @params: Pointer to change beacon parameters
+ *
+ * Return: zero for success non-zero for failure
+ */
+int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
+				struct net_device *dev,
+				struct cfg80211_beacon_data *params)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_sap_indicate_disconnect_for_sta() - Indicate disconnect indication
+ * to supplicant, if there any clients connected to SAP interface.
+ * @adapter: sap adapter context
+ *
+ * Return:   nothing
+ */
+void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter)
+{
+	tSap_Event sap_event;
+	int sta_id;
+	struct sap_context *sap_ctx;
+
+	hdd_enter();
+
+	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
+	if (!sap_ctx) {
+		hdd_err("invalid sap context");
+		return;
+	}
+
+	for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
+		if (adapter->sta_info[sta_id].in_use) {
+			hdd_debug("sta_id: %d in_use: %d %pK",
+				 sta_id, adapter->sta_info[sta_id].in_use,
+				 adapter);
+
+			if (qdf_is_macaddr_broadcast(
+				&adapter->sta_info[sta_id].sta_mac))
+				continue;
+
+			sap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
+			qdf_mem_copy(
+				&sap_event.sapevt.
+				sapStationDisassocCompleteEvent.staMac,
+				&adapter->sta_info[sta_id].sta_mac,
+				sizeof(struct qdf_mac_addr));
+			sap_event.sapevt.sapStationDisassocCompleteEvent.
+			reason =
+				eSAP_MAC_INITATED_DISASSOC;
+			sap_event.sapevt.sapStationDisassocCompleteEvent.
+			statusCode =
+				QDF_STATUS_E_RESOURCES;
+			hdd_hostapd_sap_event_cb(&sap_event,
+					sap_ctx->pUsrContext);
+		}
+	}
+
+	hdd_exit();
+}
+
+bool hdd_is_peer_associated(struct hdd_adapter *adapter,
+			    struct qdf_mac_addr *mac_addr)
+{
+	uint32_t cnt;
+	struct hdd_station_info *sta_info;
+
+	if (!adapter || !mac_addr) {
+		hdd_err("Invalid adapter or mac_addr");
+		return false;
+	}
+
+	sta_info = adapter->sta_info;
+	spin_lock_bh(&adapter->sta_info_lock);
+	for (cnt = 0; cnt < WLAN_MAX_STA_COUNT; cnt++) {
+		if ((sta_info[cnt].in_use) &&
+		    !qdf_mem_cmp(&(sta_info[cnt].sta_mac), mac_addr,
+		    QDF_MAC_ADDR_SIZE))
+			break;
+	}
+	spin_unlock_bh(&adapter->sta_info_lock);
+	if (cnt != WLAN_MAX_STA_COUNT)
+		return true;
+
+	return false;
+}
diff --git a/core/hdd/src/wlan_hdd_hostapd.h b/core/hdd/src/wlan_hdd_hostapd.h
new file mode 100644
index 0000000..58a1582
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_hostapd.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#if !defined(WLAN_HDD_HOSTAPD_H)
+#define WLAN_HDD_HOSTAPD_H
+
+/**
+ * DOC: wlan_hdd_hostapd.h
+ *
+ * WLAN Host Device driver hostapd header file
+ */
+
+/* Include files */
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <qdf_list.h>
+#include <qdf_types.h>
+#include <wlan_hdd_main.h>
+
+/* Preprocessor definitions and constants */
+
+/* max length of command string in hostapd ioctl */
+#define HOSTAPD_IOCTL_COMMAND_STRLEN_MAX   8192
+
+struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx,
+				      tSirMacAddr macAddr,
+				      unsigned char name_assign_type,
+				      uint8_t *name);
+
+QDF_STATUS hdd_unregister_hostapd(struct hdd_adapter *adapter, bool rtnl_held);
+
+eCsrAuthType
+hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4]);
+
+int hdd_softap_set_channel_change(struct net_device *dev,
+					int target_channel,
+					enum phy_ch_width target_bw,
+					bool forced);
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+void hdd_sap_restart_with_channel_switch(struct hdd_adapter *adapter,
+				uint32_t target_channel,
+				uint32_t target_bw,
+				bool forced);
+/**
+ * hdd_sap_restart_chan_switch_cb() - Function to restart SAP with
+ * a different channel
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @channel: channel to switch
+ * @forced: Force to switch channel, ignore SCC/MCC check
+ *
+ * This function restarts SAP with a different channel
+ *
+ * Return: None
+ *
+ */
+void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id, uint32_t channel,
+				    uint32_t channel_bw,
+				    bool forced);
+/**
+ * wlan_hdd_get_channel_for_sap_restart() - Function to get
+ * suitable channel and restart SAP
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @channel: channel to be returned
+ * @sec_ch: secondary channel to be returned
+ *
+ * This function gets the channel parameters to restart SAP
+ *
+ * Return: None
+ *
+ */
+QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id, uint8_t *channel,
+				uint8_t *sec_ch);
+#endif
+
+eCsrEncryptionType
+hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4]);
+
+eCsrEncryptionType
+hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4]);
+
+eCsrAuthType
+hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4]);
+
+eCsrEncryptionType
+hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4]);
+
+QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
+		struct csr_del_sta_params *pDelStaParams);
+void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
+			     struct csr_del_sta_params *pDelStaParams);
+
+QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
+				    void *context);
+/**
+ * hdd_init_ap_mode() - to init the AP adaptor
+ * @adapter: SAP/GO adapter
+ * @rtnl_held: flag to indicate if RTNL lock needs to be acquired
+ *
+ * This API can be called to open the SAP session as well as
+ * to create and store the vdev object. It also initializes necessary
+ * SAP adapter related params.
+ */
+QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit);
+/**
+ * hdd_deinit_ap_mode() - to deinit the AP adaptor
+ * @hdd_ctx: pointer to hdd_ctx
+ * @adapter: SAP/GO adapter
+ * @rtnl_held: flag to indicate if RTNL lock needs to be acquired
+ *
+ * This API can be called to close the SAP session as well as
+ * release the vdev object completely. It also deinitializes necessary
+ * SAP adapter related params.
+ */
+void hdd_deinit_ap_mode(struct hdd_context *hdd_ctx,
+			struct hdd_adapter *adapter, bool rtnl_held);
+void hdd_set_ap_ops(struct net_device *dev);
+/**
+ * hdd_sap_create_ctx() - Wrapper API to create SAP context
+ * @adapter: pointer to adapter
+ *
+ * This wrapper API can be called to create the sap context. It will
+ * eventually calls SAP API to create the sap context
+ *
+ * Return: true or false based on overall success or failure
+ */
+bool hdd_sap_create_ctx(struct hdd_adapter *adapter);
+/**
+ * hdd_sap_destroy_ctx() - Wrapper API to destroy SAP context
+ * @adapter: pointer to adapter
+ *
+ * This wrapper API can be called to destroy the sap context. It will
+ * eventually calls SAP API to destroy the sap context
+ *
+ * Return: true or false based on overall success or failure
+ */
+bool hdd_sap_destroy_ctx(struct hdd_adapter *adapter);
+int hdd_hostapd_stop(struct net_device *dev);
+int hdd_sap_context_init(struct hdd_context *hdd_ctx);
+void hdd_sap_context_destroy(struct hdd_context *hdd_ctx);
+#ifdef QCA_HT_2040_COEX
+QDF_STATUS hdd_set_sap_ht2040_mode(struct hdd_adapter *adapter,
+				   uint8_t channel_type);
+#endif
+
+int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
+			      struct net_device *dev);
+
+int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
+			       struct net_device *dev,
+			       struct cfg80211_ap_settings *params);
+
+int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
+				    struct net_device *dev,
+				    struct cfg80211_beacon_data *params);
+
+/**
+ * hdd_is_peer_associated - is peer connected to softap
+ * @adapter: pointer to softap adapter
+ * @mac_addr: address to check in peer list
+ *
+ * This function has to be invoked only when bss is started and is used
+ * to check whether station with specified addr is peer or not
+ *
+ * Return: true if peer mac, else false
+ */
+bool hdd_is_peer_associated(struct hdd_adapter *adapter,
+			    struct qdf_mac_addr *mac_addr);
+
+int hdd_destroy_acs_timer(struct hdd_adapter *adapter);
+
+QDF_STATUS wlan_hdd_config_acs(struct hdd_context *hdd_ctx,
+			       struct hdd_adapter *adapter);
+
+void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter);
+#endif /* end #if !defined(WLAN_HDD_HOSTAPD_H) */
diff --git a/core/hdd/src/wlan_hdd_hostapd_wext.c b/core/hdd/src/wlan_hdd_hostapd_wext.c
new file mode 100644
index 0000000..74d9c3f
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_hostapd_wext.c
@@ -0,0 +1,3269 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_hostapd_wext.c
+ *
+ * Linux Wireless Extensions Implementation
+ */
+
+#include <wlan_hdd_hostapd_wext.h>
+#include <wlan_hdd_includes.h>
+#include <qc_sap_ioctl.h>
+#include <wlan_hdd_green_ap.h>
+#include <wlan_hdd_hostapd.h>
+#include <wlan_hdd_ioctl.h>
+#include <wlan_hdd_stats.h>
+#include "wlan_hdd_p2p.h"
+#include "wma.h"
+#ifdef WLAN_DEBUG
+#include "wma_api.h"
+#endif
+#include "wlan_hdd_power.h"
+#include "wlan_policy_mgr_ucfg.h"
+#include <cdp_txrx_stats.h>
+#include "wlan_dfs_utils_api.h"
+#include <wlan_ipa_ucfg_api.h>
+#include <wlan_cfg80211_mc_cp_stats.h>
+#include "wlan_mlme_ucfg_api.h"
+
+#define    IS_UP(_dev) \
+	(((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
+#define    IS_UP_AUTO(_ic) \
+	(IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
+#define WE_WLAN_VERSION     1
+#define WE_GET_STA_INFO_SIZE 30
+/* WEXT limitation: MAX allowed buf len for any *
+ * IW_PRIV_TYPE_CHAR is 2Kbytes *
+ */
+#define WE_SAP_MAX_STA_INFO 0x7FF
+
+#define RC_2_RATE_IDX(_rc)        ((_rc) & 0x7)
+#define HT_RC_2_STREAMS(_rc)    ((((_rc) & 0x78) >> 3) + 1)
+#define RC_2_RATE_IDX_11AC(_rc)        ((_rc) & 0xf)
+#define HT_RC_2_STREAMS_11AC(_rc)    ((((_rc) & 0x30) >> 4) + 1)
+
+#define SAP_24GHZ_CH_COUNT (14)
+
+static int __iw_softap_set_ini_cfg(struct net_device *dev,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu,
+				   char *extra)
+{
+	QDF_STATUS status;
+	int errno;
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	char *value;
+	size_t len;
+
+	hdd_enter_dev(dev);
+
+	adapter = netdev_priv(dev);
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		return errno;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	errno = hdd_check_private_wext_control(hdd_ctx, info);
+	if (errno)
+		return errno;
+
+	/* ensure null termination by copying into a larger, zeroed buffer */
+	len = min_t(size_t, wrqu->data.length, QCSAP_IOCTL_MAX_STR_LEN);
+	value = qdf_mem_malloc(len + 1);
+	if (!value)
+		return -ENOMEM;
+
+	qdf_mem_copy(value, extra, len);
+	hdd_debug("Received data %s", value);
+	status = hdd_execute_global_config_command(hdd_ctx, value);
+	qdf_mem_free(value);
+
+	hdd_exit();
+
+	return qdf_status_to_os_return(status);
+}
+
+int
+static iw_softap_set_ini_cfg(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_set_ini_cfg(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int hdd_sap_get_chan_width(struct hdd_adapter *adapter, int *value)
+{
+	struct sap_context *sap_ctx;
+	struct hdd_hostapd_state *hostapdstate;
+
+	hdd_enter();
+	hostapdstate = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+
+	if (hostapdstate->bss_state != BSS_START) {
+		*value = -EINVAL;
+		return -EINVAL;
+	}
+
+	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
+
+	*value = wlansap_get_chan_width(sap_ctx);
+	hdd_debug("chan_width = %d", *value);
+
+	return 0;
+}
+
+int
+static __iw_softap_get_ini_cfg(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	hdd_debug("Printing CLD global INI Config");
+	hdd_cfg_get_global_config(hdd_ctx, extra, QCSAP_IOCTL_MAX_STR_LEN);
+	wrqu->data.length = strlen(extra) + 1;
+
+	return 0;
+}
+
+int
+static iw_softap_get_ini_cfg(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_get_ini_cfg(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * iw_softap_set_two_ints_getnone() - Generic "set two integer" ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
+					    struct iw_request_info *info,
+					    union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int ret;
+	int *value = (int *)extra;
+	int sub_cmd = value[0];
+	struct hdd_context *hdd_ctx;
+	struct cdp_vdev *vdev = NULL;
+	struct cdp_pdev *pdev = NULL;
+	void *soc = NULL;
+	struct cdp_txrx_stats_req req = {0};
+	uint8_t count = 0;
+	struct hdd_station_info *sta_info;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	switch (sub_cmd) {
+	case QCSAP_PARAM_SET_TXRX_STATS:
+	{
+		ret = cds_get_datapath_handles(&soc, &pdev, &vdev,
+				 adapter->session_id);
+		if (ret != 0) {
+			hdd_err("Invalid Handles");
+			break;
+		}
+		req.stats = value[1];
+		req.mac_id = value[2];
+		hdd_info("QCSAP_PARAM_SET_TXRX_STATS stats_id: %d mac_id: %d",
+			req.stats, req.mac_id);
+		sta_info = adapter->sta_info;
+		if (value[1] == CDP_TXRX_STATS_28) {
+			for (count = 0; count < WLAN_MAX_STA_COUNT; count++) {
+				if (sta_info[count].in_use) {
+					hdd_debug("sta: %d: bss_id: %pM",
+						  sta_info->sta_id,
+						  (void *)&sta_info->sta_mac);
+					req.peer_addr =
+						(char *)&sta_info->sta_mac;
+				}
+			}
+		}
+		ret = cdp_txrx_stats_request(soc, vdev, &req);
+		break;
+	}
+
+	/* Firmware debug log */
+	case QCSAP_IOCTL_SET_FW_CRASH_INJECT:
+		ret = hdd_crash_inject(adapter, value[1], value[2]);
+		break;
+
+	case QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL:
+		hdd_set_dump_dp_trace(value[1], value[2]);
+		break;
+
+	case QCSAP_ENABLE_FW_PROFILE:
+		hdd_debug("QCSAP_ENABLE_FW_PROFILE: %d %d",
+		       value[1], value[2]);
+		ret = wma_cli_set2_command(adapter->session_id,
+				 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
+					value[1], value[2], DBG_CMD);
+		break;
+
+	case QCSAP_SET_FW_PROFILE_HIST_INTVL:
+		hdd_debug("QCSAP_SET_FW_PROFILE_HIST_INTVL: %d %d",
+		       value[1], value[2]);
+		ret = wma_cli_set2_command(adapter->session_id,
+					WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
+					value[1], value[2], DBG_CMD);
+		break;
+
+	case QCSAP_SET_WLAN_SUSPEND:
+		hdd_info("SAP unit-test suspend(%d, %d)", value[1], value[2]);
+		ret = hdd_wlan_fake_apps_suspend(hdd_ctx->wiphy, dev,
+						 value[1], value[2]);
+		break;
+
+	case QCSAP_SET_WLAN_RESUME:
+		ret = hdd_wlan_fake_apps_resume(hdd_ctx->wiphy, dev);
+		break;
+
+	case QCSAP_SET_BA_AGEING_TIMEOUT:
+		hdd_info("QCSAP_SET_BA_AGEING_TIMEOUT: AC[%d] timeout[%d]",
+			 value[1], value[2]);
+		ret = cds_get_datapath_handles(&soc, &pdev, &vdev,
+					       adapter->session_id);
+		if (ret != 0) {
+			hdd_err("Invalid Handles");
+			break;
+		}
+		/*
+		 *  value[1] : suppose to be access class, value between[0-3]
+		 *  value[2]: suppose to be duration in seconds
+		 */
+		cdp_set_ba_timeout(soc, value[1], value[2]);
+		break;
+
+	default:
+		hdd_err("Invalid IOCTL command: %d", sub_cmd);
+		break;
+	}
+
+	return ret;
+}
+
+static int iw_softap_set_two_ints_getnone(struct net_device *dev,
+					  struct iw_request_info *info,
+					  union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_set_two_ints_getnone(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static void print_mac_list(struct qdf_mac_addr *macList, uint8_t size)
+{
+	int i;
+	uint8_t *macArray;
+
+	for (i = 0; i < size; i++) {
+		macArray = (macList + i)->bytes;
+		pr_info("ACL entry %i - %02x:%02x:%02x:%02x:%02x:%02x\n",
+			i, MAC_ADDR_ARRAY(macArray));
+	}
+}
+
+static QDF_STATUS hdd_print_acl(struct hdd_adapter *adapter)
+{
+	eSapMacAddrACL acl_mode;
+	struct qdf_mac_addr maclist[MAX_ACL_MAC_ADDRESS];
+	uint8_t listnum;
+	struct sap_context *sap_ctx;
+
+	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
+	qdf_mem_zero(&maclist[0], sizeof(maclist));
+	if (QDF_STATUS_SUCCESS == wlansap_get_acl_mode(sap_ctx, &acl_mode)) {
+		pr_info("******** ACL MODE *********\n");
+		switch (acl_mode) {
+		case eSAP_ACCEPT_UNLESS_DENIED:
+			pr_info("ACL Mode = ACCEPT_UNLESS_DENIED\n");
+			break;
+		case eSAP_DENY_UNLESS_ACCEPTED:
+			pr_info("ACL Mode = DENY_UNLESS_ACCEPTED\n");
+			break;
+		case eSAP_SUPPORT_ACCEPT_AND_DENY:
+			pr_info("ACL Mode = ACCEPT_AND_DENY\n");
+			break;
+		case eSAP_ALLOW_ALL:
+			pr_info("ACL Mode = ALLOW_ALL\n");
+			break;
+		default:
+			pr_info("Invalid SAP ACL Mode = %d\n", acl_mode);
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (QDF_STATUS_SUCCESS == wlansap_get_acl_accept_list(sap_ctx,
+							      &maclist[0],
+							      &listnum)) {
+		pr_info("******* WHITE LIST ***********\n");
+		if (listnum <= MAX_ACL_MAC_ADDRESS)
+			print_mac_list(&maclist[0], listnum);
+	} else {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (QDF_STATUS_SUCCESS == wlansap_get_acl_deny_list(sap_ctx,
+							    &maclist[0],
+							    &listnum)) {
+		pr_info("******* BLACK LIST ***********\n");
+		if (listnum <= MAX_ACL_MAC_ADDRESS)
+			print_mac_list(&maclist[0], listnum);
+	} else {
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_get_aid_rc() - Get AID and rate code passed from user
+ * @aid: pointer to AID
+ * @rc: pointer to rate code
+ * @set_value: value passed from user
+ *
+ * If target is 11ax capable, set_value will have AID left shifted 16 bits
+ * and 16 bits for rate code. If the target is not 11ax capable, rate code
+ * will only be 8 bits.
+ *
+ * Return: None
+ */
+static void hdd_get_aid_rc(uint8_t *aid, uint16_t *rc, int set_value)
+{
+	uint8_t rc_bits;
+
+	if (sme_is_feature_supported_by_fw(DOT11AX))
+		rc_bits = 16;
+	else
+		rc_bits = 8;
+
+	*aid = set_value >> rc_bits;
+	*rc = set_value & ((1 << (rc_bits + 1)) - 1);
+}
+
+/**
+ * hdd_set_peer_rate() - set peer rate
+ * @adapter: adapter being modified
+ * @set_value: rate code with AID
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int hdd_set_peer_rate(struct hdd_adapter *adapter, int set_value)
+{
+	uint8_t aid, *peer_mac;
+	uint16_t rc;
+	QDF_STATUS status;
+
+	if (adapter->device_mode != QDF_SAP_MODE) {
+		hdd_err("Invalid devicde mode - %d", adapter->device_mode);
+		return -EINVAL;
+	}
+
+	hdd_get_aid_rc(&aid, &rc, set_value);
+
+	if ((adapter->sta_info[aid].in_use) &&
+	    (OL_TXRX_PEER_STATE_CONN == adapter->sta_info[aid].peer_state)) {
+		peer_mac =
+		    (uint8_t *)&(adapter->sta_info[aid].sta_mac.bytes[0]);
+		hdd_info("Peer AID: %d MAC_ADDR: "MAC_ADDRESS_STR,
+			 aid, MAC_ADDR_ARRAY(peer_mac));
+	} else {
+		hdd_err("No matching peer found for AID: %d", aid);
+		return -EINVAL;
+	}
+
+	status = sme_set_peer_param(peer_mac, WMI_PEER_PARAM_FIXED_RATE,
+				    rc, adapter->session_id);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to set peer fixed rate - status: %d", status);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int
+static __iw_softap_setparam(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	mac_handle_t mac_handle;
+	int *value = (int *)extra;
+	int sub_cmd = value[0];
+	int set_value = value[1];
+	QDF_STATUS status;
+	int ret = 0;
+	struct hdd_context *hdd_ctx;
+	bool bval = false;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return -EINVAL;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!mac_handle) {
+		hdd_err("mac handle is null");
+		return -EINVAL;
+	}
+
+	switch (sub_cmd) {
+	case QCASAP_SET_RADAR_DBG:
+		hdd_debug("QCASAP_SET_RADAR_DBG called with: value: %x",
+				set_value);
+		wlan_sap_enable_phy_error_logs(mac_handle, set_value);
+		break;
+
+	case QCSAP_PARAM_CLR_ACL:
+		if (QDF_STATUS_SUCCESS != wlansap_clear_acl(
+		    WLAN_HDD_GET_SAP_CTX_PTR(adapter))) {
+			ret = -EIO;
+		}
+		break;
+
+	case QCSAP_PARAM_ACL_MODE:
+		if ((eSAP_ALLOW_ALL < (eSapMacAddrACL) set_value) ||
+		    (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL) set_value)) {
+			hdd_err("Invalid ACL Mode value: %d", set_value);
+			ret = -EINVAL;
+		} else {
+			wlansap_set_acl_mode(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+				set_value);
+		}
+		break;
+
+	case QCSAP_PARAM_SET_CHANNEL_CHANGE:
+		if ((QDF_SAP_MODE == adapter->device_mode) ||
+		   (QDF_P2P_GO_MODE == adapter->device_mode)) {
+			hdd_debug("SET Channel Change to new channel= %d",
+			       set_value);
+			ret = hdd_softap_set_channel_change(dev, set_value,
+								CH_WIDTH_MAX,
+								false);
+		} else {
+			hdd_err("Channel Change Failed, Device in test mode");
+			ret = -EINVAL;
+		}
+		break;
+
+	case QCSAP_PARAM_CONC_SYSTEM_PREF:
+		hdd_debug("New preference: %d", set_value);
+		ucfg_policy_mgr_set_sys_pref(hdd_ctx->psoc, set_value);
+		break;
+
+	case QCSAP_PARAM_MAX_ASSOC:
+		if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) {
+			hdd_err("Invalid setMaxAssoc value %d",
+			       set_value);
+			ret = -EINVAL;
+		} else {
+			if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value) {
+				hdd_warn("setMaxAssoc %d > max allowed %d.",
+				       set_value,
+				       WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
+				hdd_warn("Setting it to max allowed and continuing");
+				set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
+			}
+			if (ucfg_mlme_set_assoc_sta_limit(hdd_ctx->psoc,
+							  set_value) !=
+			    QDF_STATUS_SUCCESS) {
+				hdd_err("CFG_ASSOC_STA_LIMIT failed");
+				ret = -EIO;
+			}
+
+		}
+		break;
+
+	case QCSAP_PARAM_HIDE_SSID:
+	{
+		QDF_STATUS status;
+
+		status = sme_update_session_param(mac_handle,
+				adapter->session_id,
+				SIR_PARAM_SSID_HIDDEN, set_value);
+		if (QDF_STATUS_SUCCESS != status) {
+			hdd_err("QCSAP_PARAM_HIDE_SSID failed");
+			return -EIO;
+		}
+		break;
+	}
+	case QCSAP_PARAM_SET_MC_RATE:
+	{
+		tSirRateUpdateInd rateUpdate = {0};
+
+		hdd_debug("MC Target rate %d", set_value);
+		qdf_copy_macaddr(&rateUpdate.bssid,
+				 &adapter->mac_addr);
+		status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("unable to get vht_enable2x2");
+			ret = -1;
+		}
+		rateUpdate.nss = (bval == 0) ? 0 : 1;
+
+		rateUpdate.dev_mode = adapter->device_mode;
+		rateUpdate.mcastDataRate24GHz = set_value;
+		rateUpdate.mcastDataRate24GHzTxFlag = 1;
+		rateUpdate.mcastDataRate5GHz = set_value;
+		rateUpdate.bcastDataRate = -1;
+		status = sme_send_rate_update_ind(mac_handle, &rateUpdate);
+		if (QDF_STATUS_SUCCESS != status) {
+			hdd_err("SET_MC_RATE failed");
+			ret = -1;
+		}
+		break;
+	}
+
+	case QCSAP_PARAM_SET_TXRX_FW_STATS:
+	{
+		hdd_debug("QCSAP_PARAM_SET_TXRX_FW_STATS val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
+					  set_value, VDEV_CMD);
+		break;
+	}
+
+	/* Firmware debug log */
+	case QCSAP_DBGLOG_LOG_LEVEL:
+	{
+		hdd_debug("QCSAP_DBGLOG_LOG_LEVEL val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_LOG_LEVEL,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case QCSAP_DBGLOG_VAP_ENABLE:
+	{
+		hdd_debug("QCSAP_DBGLOG_VAP_ENABLE val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_VAP_ENABLE,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case QCSAP_DBGLOG_VAP_DISABLE:
+	{
+		hdd_debug("QCSAP_DBGLOG_VAP_DISABLE val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_VAP_DISABLE,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case QCSAP_DBGLOG_MODULE_ENABLE:
+	{
+		hdd_debug("QCSAP_DBGLOG_MODULE_ENABLE val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_MODULE_ENABLE,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case QCSAP_DBGLOG_MODULE_DISABLE:
+	{
+		hdd_debug("QCSAP_DBGLOG_MODULE_DISABLE val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_MODULE_DISABLE,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case QCSAP_DBGLOG_MOD_LOG_LEVEL:
+	{
+		hdd_debug("QCSAP_DBGLOG_MOD_LOG_LEVEL val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_MOD_LOG_LEVEL,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case QCSAP_DBGLOG_TYPE:
+	{
+		hdd_debug("QCSAP_DBGLOG_TYPE val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_TYPE,
+					  set_value, DBG_CMD);
+		break;
+	}
+	case QCSAP_DBGLOG_REPORT_ENABLE:
+	{
+		hdd_debug("QCSAP_DBGLOG_REPORT_ENABLE val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_REPORT_ENABLE,
+					  set_value, DBG_CMD);
+		break;
+	}
+	case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY:
+	{
+		wlan_hdd_set_mcc_latency(adapter, set_value);
+		break;
+	}
+
+	case QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA:
+	{
+		hdd_debug("iwpriv cmd to set MCC quota value %dms",
+		       set_value);
+		ret = wlan_hdd_go_set_mcc_p2p_quota(adapter,
+						    set_value);
+		break;
+	}
+
+	case QCASAP_TXRX_FWSTATS_RESET:
+	{
+		hdd_debug("WE_TXRX_FWSTATS_RESET val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
+					  set_value, VDEV_CMD);
+		break;
+	}
+
+	case QCSAP_PARAM_RTSCTS:
+	{
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_ENABLE_RTSCTS,
+					  set_value, VDEV_CMD);
+		if (ret) {
+			hdd_err("FAILED TO SET RTSCTS at SAP");
+			ret = -EIO;
+		}
+		break;
+	}
+	case QCASAP_SET_11N_RATE:
+	{
+		uint8_t preamble = 0, nss = 0, rix = 0;
+		tsap_config_t *pConfig =
+			&adapter->session.ap.sap_config;
+
+		hdd_debug("SET_HT_RATE val %d", set_value);
+
+		if (set_value != 0xff) {
+			rix = RC_2_RATE_IDX(set_value);
+			if (set_value & 0x80) {
+				if (pConfig->SapHw_mode ==
+				    eCSR_DOT11_MODE_11b
+				    || pConfig->SapHw_mode ==
+				    eCSR_DOT11_MODE_11b_ONLY
+				    || pConfig->SapHw_mode ==
+				    eCSR_DOT11_MODE_11g
+				    || pConfig->SapHw_mode ==
+				    eCSR_DOT11_MODE_11g_ONLY
+				    || pConfig->SapHw_mode ==
+				    eCSR_DOT11_MODE_abg
+				    || pConfig->SapHw_mode ==
+				    eCSR_DOT11_MODE_11a) {
+					hdd_err("Not valid mode for HT");
+					ret = -EIO;
+					break;
+				}
+				preamble = WMI_RATE_PREAMBLE_HT;
+				nss = HT_RC_2_STREAMS(set_value) - 1;
+			} else if (set_value & 0x10) {
+				if (pConfig->SapHw_mode ==
+				    eCSR_DOT11_MODE_11a) {
+					hdd_err("Not valid for cck");
+					ret = -EIO;
+					break;
+				}
+				preamble = WMI_RATE_PREAMBLE_CCK;
+				/* Enable Short preamble always
+				 * for CCK except 1mbps
+				 */
+				if (rix != 0x3)
+					rix |= 0x4;
+			} else {
+				if (pConfig->SapHw_mode ==
+				    eCSR_DOT11_MODE_11b
+				    || pConfig->SapHw_mode ==
+				    eCSR_DOT11_MODE_11b_ONLY) {
+					hdd_err("Not valid for OFDM");
+					ret = -EIO;
+					break;
+				}
+				preamble = WMI_RATE_PREAMBLE_OFDM;
+			}
+			set_value = hdd_assemble_rate_code(preamble, nss, rix);
+		}
+		hdd_debug("SET_HT_RATE val %d rix %d preamble %x nss %d",
+		       set_value, rix, preamble, nss);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_FIXED_RATE,
+					  set_value, VDEV_CMD);
+		break;
+	}
+
+	case QCASAP_SET_VHT_RATE:
+	{
+		uint8_t preamble = 0, nss = 0, rix = 0;
+		tsap_config_t *pConfig =
+			&adapter->session.ap.sap_config;
+
+		if (pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac &&
+		    pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac_ONLY) {
+			hdd_err("SET_VHT_RATE error: SapHw_mode= 0x%x, ch: %d",
+			       pConfig->SapHw_mode, pConfig->channel);
+			ret = -EIO;
+			break;
+		}
+
+		if (set_value != 0xff) {
+			rix = RC_2_RATE_IDX_11AC(set_value);
+			preamble = WMI_RATE_PREAMBLE_VHT;
+			nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
+
+			set_value = hdd_assemble_rate_code(preamble, nss, rix);
+		}
+		hdd_debug("SET_VHT_RATE val %d rix %d preamble %x nss %d",
+		       set_value, rix, preamble, nss);
+
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_FIXED_RATE,
+					  set_value, VDEV_CMD);
+		break;
+	}
+
+	case QCASAP_SHORT_GI:
+	{
+		hdd_debug("QCASAP_SET_SHORT_GI val %d", set_value);
+		/*
+		 * wma_cli_set_command should be called instead of
+		 * sme_update_ht_config since SGI is used for HT/HE.
+		 * This should be refactored.
+		 *
+		 * SGI is same for 20MHZ and 40MHZ.
+		 */
+		ret = sme_update_ht_config(mac_handle, adapter->session_id,
+					   WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
+					   set_value);
+		if (ret)
+			hdd_err("Failed to set ShortGI value ret: %d", ret);
+		break;
+	}
+
+	case QCSAP_SET_AMPDU:
+	{
+		hdd_debug("QCSAP_SET_AMPDU %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  GEN_VDEV_PARAM_AMPDU,
+					  set_value, GEN_CMD);
+		break;
+	}
+
+	case QCSAP_SET_AMSDU:
+	{
+		hdd_debug("QCSAP_SET_AMSDU %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  GEN_VDEV_PARAM_AMSDU,
+					  set_value, GEN_CMD);
+		break;
+	}
+	case QCSAP_GTX_HT_MCS:
+	{
+		hdd_debug("WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_GTX_HT_MCS,
+					  set_value, GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_VHT_MCS:
+	{
+		hdd_debug("WMI_VDEV_PARAM_GTX_VHT_MCS %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_GTX_VHT_MCS,
+						set_value, GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_USRCFG:
+	{
+		hdd_debug("WMI_VDEV_PARAM_GTX_USR_CFG %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_GTX_USR_CFG,
+					  set_value, GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_THRE:
+	{
+		hdd_debug("WMI_VDEV_PARAM_GTX_THRE %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_GTX_THRE,
+					  set_value, GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_MARGIN:
+	{
+		hdd_debug("WMI_VDEV_PARAM_GTX_MARGIN %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_GTX_MARGIN,
+					  set_value, GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_STEP:
+	{
+		hdd_debug("WMI_VDEV_PARAM_GTX_STEP %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_GTX_STEP,
+					  set_value, GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_MINTPC:
+	{
+		hdd_debug("WMI_VDEV_PARAM_GTX_MINTPC %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_GTX_MINTPC,
+					  set_value, GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_BWMASK:
+	{
+		hdd_debug("WMI_VDEV_PARAM_GTX_BWMASK %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_GTX_BW_MASK,
+					  set_value, GTX_CMD);
+		break;
+	}
+
+	case QCASAP_SET_TM_LEVEL:
+	{
+		hdd_debug("Set Thermal Mitigation Level %d", set_value);
+		(void)sme_set_thermal_level(mac_handle, set_value);
+		break;
+	}
+
+	case QCASAP_SET_DFS_IGNORE_CAC:
+	{
+		hdd_debug("Set Dfs ignore CAC  %d", set_value);
+
+		if (adapter->device_mode != QDF_SAP_MODE)
+			return -EINVAL;
+
+		ret = wlansap_set_dfs_ignore_cac(mac_handle, set_value);
+		break;
+	}
+
+	case QCASAP_SET_DFS_TARGET_CHNL:
+	{
+		hdd_debug("Set Dfs target channel  %d", set_value);
+
+		if (adapter->device_mode != QDF_SAP_MODE)
+			return -EINVAL;
+
+		ret = wlansap_set_dfs_target_chnl(mac_handle, set_value);
+		break;
+	}
+
+	case QCASAP_SET_HE_BSS_COLOR:
+		if (adapter->device_mode != QDF_SAP_MODE)
+			return -EINVAL;
+
+		status = sme_set_he_bss_color(mac_handle, adapter->session_id,
+				set_value);
+		if (QDF_STATUS_SUCCESS != status) {
+			hdd_err("SET_HE_BSS_COLOR failed");
+			return -EIO;
+		}
+		break;
+	case QCASAP_SET_DFS_NOL:
+		wlansap_set_dfs_nol(
+			WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+			(eSapDfsNolType) set_value);
+		break;
+
+	case QCASAP_SET_RADAR_CMD:
+	{
+		struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+		uint8_t ch = ap_ctx->operating_channel;
+		struct wlan_objmgr_pdev *pdev;
+		struct radar_found_info radar;
+
+		hdd_debug("Set QCASAP_SET_RADAR_CMD val %d", set_value);
+
+		pdev = hdd_ctx->pdev;
+		if (!pdev) {
+			hdd_err("null pdev");
+			return -EINVAL;
+		}
+
+		qdf_mem_zero(&radar, sizeof(radar));
+		if (wlan_reg_is_dfs_ch(pdev, ch))
+			tgt_dfs_process_radar_ind(pdev, &radar);
+		else
+			hdd_err("Ignore set radar, op ch(%d) is not dfs", ch);
+
+		break;
+	}
+	case QCASAP_TX_CHAINMASK_CMD:
+	{
+		hdd_debug("QCASAP_TX_CHAINMASK_CMD val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_TX_CHAIN_MASK,
+					  set_value, PDEV_CMD);
+		ret = hdd_set_antenna_mode(adapter, hdd_ctx, set_value);
+		break;
+	}
+
+	case QCASAP_RX_CHAINMASK_CMD:
+	{
+		hdd_debug("QCASAP_RX_CHAINMASK_CMD val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_RX_CHAIN_MASK,
+					  set_value, PDEV_CMD);
+		ret = hdd_set_antenna_mode(adapter, hdd_ctx, set_value);
+		break;
+	}
+
+	case QCASAP_NSS_CMD:
+	{
+		hdd_debug("QCASAP_NSS_CMD val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_NSS,
+					  set_value, VDEV_CMD);
+		break;
+	}
+
+	case QCSAP_IPA_UC_STAT:
+	{
+		/* If input value is non-zero get stats */
+		switch (set_value) {
+		case 1:
+			ucfg_ipa_uc_stat(hdd_ctx->pdev);
+			break;
+		case 2:
+			ucfg_ipa_uc_info(hdd_ctx->pdev);
+			break;
+		case 3:
+			ucfg_ipa_uc_rt_debug_host_dump(hdd_ctx->pdev);
+			break;
+		case 4:
+			ucfg_ipa_dump_info(hdd_ctx->pdev);
+			break;
+		default:
+			/* place holder for stats clean up
+			 * Stats clean not implemented yet on FW and IPA
+			 */
+			break;
+		}
+		return ret;
+	}
+
+	case QCASAP_SET_PHYMODE:
+		ret = wlan_hdd_update_phymode(adapter, set_value);
+		break;
+
+	case QCASAP_DUMP_STATS:
+	{
+		hdd_debug("QCASAP_DUMP_STATS val %d", set_value);
+		ret = hdd_wlan_dump_stats(adapter, set_value);
+		break;
+	}
+	case QCASAP_CLEAR_STATS:
+	{
+		void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+		hdd_debug("QCASAP_CLEAR_STATS val %d", set_value);
+		switch (set_value) {
+		case CDP_HDD_STATS:
+			memset(&adapter->stats, 0,
+						sizeof(adapter->stats));
+			memset(&adapter->hdd_stats, 0,
+					sizeof(adapter->hdd_stats));
+			break;
+		case CDP_TXRX_HIST_STATS:
+			wlan_hdd_clear_tx_rx_histogram(hdd_ctx);
+			break;
+		case CDP_HDD_NETIF_OPER_HISTORY:
+			wlan_hdd_clear_netif_queue_history(hdd_ctx);
+			break;
+		case CDP_HIF_STATS:
+			hdd_clear_hif_stats();
+			break;
+		default:
+			if (soc)
+				cdp_clear_stats(soc, set_value);
+		}
+		break;
+	}
+	case QCSAP_START_FW_PROFILING:
+		hdd_debug("QCSAP_START_FW_PROFILING %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					WMI_WLAN_PROFILE_TRIGGER_CMDID,
+					set_value, DBG_CMD);
+		break;
+	case QCASAP_PARAM_LDPC:
+		ret = hdd_set_ldpc(adapter, set_value);
+		break;
+	case QCASAP_PARAM_TX_STBC:
+		ret = hdd_set_tx_stbc(adapter, set_value);
+		break;
+	case QCASAP_PARAM_RX_STBC:
+		ret = hdd_set_rx_stbc(adapter, set_value);
+		break;
+	case QCASAP_SET_11AX_RATE:
+		ret = hdd_set_11ax_rate(adapter, set_value,
+					&adapter->session.ap.
+					sap_config);
+		break;
+	case QCASAP_SET_PEER_RATE:
+		ret = hdd_set_peer_rate(adapter, set_value);
+		break;
+	case QCASAP_PARAM_DCM:
+		hdd_debug("Set WMI_VDEV_PARAM_HE_DCM: %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_HE_DCM, set_value,
+					  VDEV_CMD);
+		break;
+	case QCASAP_PARAM_RANGE_EXT:
+		hdd_debug("Set WMI_VDEV_PARAM_HE_RANGE_EXT: %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_HE_RANGE_EXT,
+					  set_value, VDEV_CMD);
+		break;
+	case QCSAP_SET_DEFAULT_AMPDU:
+		hdd_debug("QCSAP_SET_DEFAULT_AMPDU val %d", set_value);
+		ret = wma_cli_set_command((int)adapter->session_id,
+				(int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
+				set_value, PDEV_CMD);
+		break;
+	case QCSAP_ENABLE_RTS_BURSTING:
+		hdd_debug("QCSAP_ENABLE_RTS_BURSTING val %d", set_value);
+		ret = wma_cli_set_command((int)adapter->session_id,
+				(int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
+				set_value, PDEV_CMD);
+		break;
+	default:
+		hdd_err("Invalid setparam command %d value %d",
+		       sub_cmd, set_value);
+		ret = -EINVAL;
+		break;
+	}
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * __iw_softap_get_three() - return three value to upper layer.
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/out
+ *
+ * Return: execute result
+ */
+static int __iw_softap_get_three(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *wrqu, char *extra)
+{
+	uint32_t *value = (uint32_t *)extra;
+	uint32_t sub_cmd = value[0];
+	int ret = 0; /* success */
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	switch (sub_cmd) {
+	case QCSAP_GET_TSF:
+		ret = hdd_indicate_tsf(adapter, value, 3);
+		break;
+	default:
+		hdd_err("Invalid getparam command: %d", sub_cmd);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+
+/**
+ * iw_softap_get_three() - return three value to upper layer.
+ *
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/Output
+ *
+ * Return: execute result
+ */
+static int iw_softap_get_three(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_get_three(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int
+static iw_softap_setparam(struct net_device *dev,
+			  struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_setparam(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int
+static __iw_softap_getparam(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	int *value = (int *)extra;
+	int sub_cmd = value[0];
+	int ret;
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	switch (sub_cmd) {
+	case QCSAP_PARAM_MAX_ASSOC:
+		if (ucfg_mlme_set_assoc_sta_limit(hdd_ctx->psoc, *value) !=
+		    QDF_STATUS_SUCCESS) {
+			hdd_err("CFG_ASSOC_STA_LIMIT failed");
+			ret = -EIO;
+		}
+
+		break;
+
+	case QCSAP_PARAM_GET_WLAN_DBG:
+	{
+		qdf_trace_display();
+		*value = 0;
+		break;
+	}
+
+	case QCSAP_PARAM_RTSCTS:
+	{
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_ENABLE_RTSCTS,
+					     VDEV_CMD);
+		break;
+	}
+
+	case QCASAP_SHORT_GI:
+	{
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_SGI,
+					     VDEV_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_HT_MCS:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_HT_MCS");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_HT_MCS,
+					     GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_VHT_MCS:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_VHT_MCS");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_VHT_MCS,
+					     GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_USRCFG:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_USR_CFG");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_USR_CFG,
+					     GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_THRE:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_THRE");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_THRE,
+					     GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_MARGIN:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_MARGIN");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_MARGIN,
+					     GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_STEP:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_STEP");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_STEP,
+					     GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_MINTPC:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_MINTPC");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_MINTPC,
+					     GTX_CMD);
+		break;
+	}
+
+	case QCSAP_GTX_BWMASK:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_BW_MASK");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_BW_MASK,
+					     GTX_CMD);
+		break;
+	}
+
+	case QCASAP_GET_DFS_NOL:
+	{
+		struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+		struct wlan_objmgr_pdev *pdev;
+
+		pdev = hdd_ctx->pdev;
+		if (!pdev) {
+			hdd_err("null pdev");
+			return -EINVAL;
+		}
+
+		utils_dfs_print_nol_channels(pdev);
+	}
+	break;
+
+	case QCSAP_GET_ACL:
+	{
+		hdd_debug("QCSAP_GET_ACL");
+		if (hdd_print_acl(adapter) !=
+		    QDF_STATUS_SUCCESS) {
+			hdd_err("QCSAP_GET_ACL returned Error: not completed");
+		}
+		*value = 0;
+		break;
+	}
+
+	case QCASAP_TX_CHAINMASK_CMD:
+	{
+		hdd_debug("QCASAP_TX_CHAINMASK_CMD");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_TX_CHAIN_MASK,
+					     PDEV_CMD);
+		break;
+	}
+
+	case QCASAP_RX_CHAINMASK_CMD:
+	{
+		hdd_debug("QCASAP_RX_CHAINMASK_CMD");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_RX_CHAIN_MASK,
+					     PDEV_CMD);
+		break;
+	}
+
+	case QCASAP_NSS_CMD:
+	{
+		hdd_debug("QCASAP_NSS_CMD");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_NSS,
+					     VDEV_CMD);
+		break;
+	}
+	case QCSAP_CAP_TSF:
+		ret = hdd_capture_tsf(adapter, (uint32_t *)value, 1);
+		break;
+	case QCASAP_GET_TEMP_CMD:
+	{
+		hdd_debug("QCASAP_GET_TEMP_CMD");
+		ret = wlan_hdd_get_temperature(adapter, value);
+		break;
+	}
+	case QCSAP_GET_FW_PROFILE_DATA:
+		hdd_debug("QCSAP_GET_FW_PROFILE_DATA");
+		ret = wma_cli_set_command(adapter->session_id,
+				WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
+				0, DBG_CMD);
+		break;
+	case QCASAP_PARAM_LDPC:
+	{
+		ret = hdd_get_ldpc(adapter, value);
+		break;
+	}
+	case QCASAP_PARAM_TX_STBC:
+	{
+		ret = hdd_get_tx_stbc(adapter, value);
+		break;
+	}
+	case QCASAP_PARAM_RX_STBC:
+	{
+		ret = hdd_get_rx_stbc(adapter, value);
+		break;
+	}
+	case QCSAP_PARAM_CHAN_WIDTH:
+	{
+		ret = hdd_sap_get_chan_width(adapter, value);
+		break;
+	}
+	case QCASAP_PARAM_DCM:
+	{
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_HE_DCM,
+					     VDEV_CMD);
+		break;
+	}
+	case QCASAP_PARAM_RANGE_EXT:
+	{
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_HE_RANGE_EXT,
+					     VDEV_CMD);
+		break;
+	}
+	default:
+		hdd_err("Invalid getparam command: %d", sub_cmd);
+		ret = -EINVAL;
+		break;
+
+	}
+	hdd_exit();
+	return ret;
+}
+
+int
+static iw_softap_getparam(struct net_device *dev,
+			  struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_getparam(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/* Usage:
+ *  BLACK_LIST  = 0
+ *  WHITE_LIST  = 1
+ *  ADD MAC = 0
+ *  REMOVE MAC  = 1
+ *
+ *  mac addr will be accepted as a 6 octet mac address with each octet
+ *  inputted in hex for e.g. 00:0a:f5:11:22:33 will be represented as
+ *  0x00 0x0a 0xf5 0x11 0x22 0x33 while using this ioctl
+ *
+ *  Syntax:
+ *  iwpriv softap.0 modify_acl
+ *  <6 octet mac addr> <list type> <cmd type>
+ *
+ *  Examples:
+ *  eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
+ *  iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
+ *  eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
+ *  iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
+ */
+static
+int __iw_softap_modify_acl(struct net_device *dev,
+			   struct iw_request_info *info,
+			   union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	uint8_t *value = (uint8_t *) extra;
+	uint8_t pPeerStaMac[QDF_MAC_ADDR_SIZE];
+	int listType, cmd, i;
+	int ret;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	for (i = 0; i < QDF_MAC_ADDR_SIZE; i++)
+		pPeerStaMac[i] = *(value + i);
+
+	listType = (int)(*(value + i));
+	i++;
+	cmd = (int)(*(value + i));
+
+	hdd_debug("Modify ACL mac:" MAC_ADDRESS_STR " type: %d cmd: %d",
+	       MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
+
+	qdf_status = wlansap_modify_acl(
+		WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+		pPeerStaMac, (eSapACLType) listType, (eSapACLCmdType) cmd);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Modify ACL failed");
+		ret = -EIO;
+	}
+	hdd_exit();
+	return ret;
+}
+
+static
+int iw_softap_modify_acl(struct net_device *dev,
+			 struct iw_request_info *info,
+			 union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int
+static __iw_softap_getchannel(struct net_device *dev,
+			      struct iw_request_info *info,
+			      union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	struct hdd_context *hdd_ctx;
+	int *value = (int *)extra;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	*value = 0;
+	if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))
+		*value = (WLAN_HDD_GET_AP_CTX_PTR(
+					adapter))->operating_channel;
+	hdd_exit();
+	return 0;
+}
+
+int
+static iw_softap_getchannel(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_getchannel(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int
+static __iw_softap_set_max_tx_power(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	struct hdd_context *hdd_ctx;
+	int *value = (int *)extra;
+	int set_value;
+	int ret;
+	struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT;
+	struct qdf_mac_addr selfMac = QDF_MAC_ADDR_BCAST_INIT;
+
+	hdd_enter_dev(dev);
+
+	if (NULL == value)
+		return -ENOMEM;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	/* Assign correct self MAC address */
+	qdf_copy_macaddr(&bssid, &adapter->mac_addr);
+	qdf_copy_macaddr(&selfMac, &adapter->mac_addr);
+
+	set_value = value[0];
+	if (QDF_STATUS_SUCCESS !=
+	    sme_set_max_tx_power(hdd_ctx->mac_handle, bssid,
+				 selfMac, set_value)) {
+		hdd_err("Setting maximum tx power failed");
+		return -EIO;
+	}
+	hdd_exit();
+	return 0;
+}
+
+int
+static iw_softap_set_max_tx_power(struct net_device *dev,
+				  struct iw_request_info *info,
+				  union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifndef REMOVE_PKT_LOG
+int
+static __iw_softap_set_pktlog(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = netdev_priv(dev);
+	struct hdd_context *hdd_ctx;
+	int *value = (int *)extra;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	if (wrqu->data.length < 1 || wrqu->data.length > 2) {
+		hdd_err("pktlog: either 1 or 2 parameters are required");
+		return -EINVAL;
+	}
+
+	return hdd_process_pktlog_command(hdd_ctx, value[0], value[1]);
+}
+
+int
+static iw_softap_set_pktlog(struct net_device *dev,
+				  struct iw_request_info *info,
+				  union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_set_pktlog(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#else
+int
+static iw_softap_set_pktlog(struct net_device *dev,
+				  struct iw_request_info *info,
+				  union iwreq_data *wrqu, char *extra)
+{
+	return -EINVAL;
+}
+#endif
+
+int
+static __iw_softap_set_tx_power(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	struct hdd_context *hdd_ctx;
+	int *value = (int *)extra;
+	int set_value;
+	struct qdf_mac_addr bssid;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	qdf_copy_macaddr(&bssid, &adapter->mac_addr);
+
+	set_value = value[0];
+	if (QDF_STATUS_SUCCESS !=
+	    sme_set_tx_power(hdd_ctx->mac_handle, adapter->session_id, bssid,
+			     adapter->device_mode, set_value)) {
+		hdd_err("Setting tx power failed");
+		return -EIO;
+	}
+	hdd_exit();
+	return 0;
+}
+
+int
+static iw_softap_set_tx_power(struct net_device *dev,
+			      struct iw_request_info *info,
+			      union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
+
+int
+static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
+				       struct iw_request_info *info,
+				       union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	struct hdd_station_info *pStaInfo = adapter->sta_info;
+	struct hdd_context *hdd_ctx;
+	char *buf;
+	int cnt = 0;
+	int left;
+	int ret;
+	/* maclist_index must be u32 to match userspace */
+	u32 maclist_index;
+
+	hdd_enter_dev(dev);
+
+	/*
+	 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
+	 * number, and even numbered iocts are supposed to have "set"
+	 * semantics.  Hence the wireless extensions support in the kernel
+	 * won't correctly copy the result to userspace, so the ioctl
+	 * handler itself must copy the data.  Output format is 32-bit
+	 * record length, followed by 0 or more 6-byte STA MAC addresses.
+	 *
+	 * Further note that due to the incorrect semantics, the "iwpriv"
+	 * userspace application is unable to correctly invoke this API,
+	 * hence it is not registered in the hostapd_private_args.  This
+	 * API can only be invoked by directly invoking the ioctl() system
+	 * call.
+	 */
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	/* make sure userspace allocated a reasonable buffer size */
+	if (wrqu->data.length < sizeof(maclist_index)) {
+		hdd_err("invalid userspace buffer");
+		return -EINVAL;
+	}
+
+	/* allocate local buffer to build the response */
+	buf = qdf_mem_malloc(wrqu->data.length);
+	if (!buf)
+		return -ENOMEM;
+
+	/* start indexing beyond where the record count will be written */
+	maclist_index = sizeof(maclist_index);
+	left = wrqu->data.length - maclist_index;
+
+	spin_lock_bh(&adapter->sta_info_lock);
+	while ((cnt < WLAN_MAX_STA_COUNT) && (left >= QDF_MAC_ADDR_SIZE)) {
+		if ((pStaInfo[cnt].in_use) &&
+		    (!IS_BROADCAST_MAC(pStaInfo[cnt].sta_mac.bytes))) {
+			memcpy(&buf[maclist_index], &(pStaInfo[cnt].sta_mac),
+			       QDF_MAC_ADDR_SIZE);
+			maclist_index += QDF_MAC_ADDR_SIZE;
+			left -= QDF_MAC_ADDR_SIZE;
+		}
+		cnt++;
+	}
+	spin_unlock_bh(&adapter->sta_info_lock);
+
+	*((u32 *) buf) = maclist_index;
+	wrqu->data.length = maclist_index;
+	if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
+		hdd_err("failed to copy response to user buffer");
+		ret = -EFAULT;
+	}
+	qdf_mem_free(buf);
+	hdd_exit();
+	return ret;
+}
+
+int
+static iw_softap_getassoc_stamacaddr(struct net_device *dev,
+				     struct iw_request_info *info,
+				     union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/* Usage:
+ *  mac addr will be accepted as a 6 octet mac address with each octet
+ *  inputted in hex for e.g. 00:0a:f5:11:22:33 will be represented as
+ *  0x00 0x0a 0xf5 0x11 0x22 0x33 while using this ioctl
+ *
+ *  Syntax:
+ *  iwpriv softap.0 disassoc_sta <6 octet mac address>
+ *
+ *  e.g.
+ *  disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
+ *  iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
+ */
+
+int
+static __iw_softap_disassoc_sta(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	struct hdd_context *hdd_ctx;
+	uint8_t *peerMacAddr;
+	int ret;
+	struct csr_del_sta_params del_sta_params;
+
+	hdd_enter_dev(dev);
+
+	if (!capable(CAP_NET_ADMIN)) {
+		hdd_err("permission check failed");
+		return -EPERM;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	/* iwpriv tool or framework calls this ioctl with
+	 * data passed in extra (less than 16 octets);
+	 */
+	peerMacAddr = (uint8_t *) (extra);
+
+	hdd_debug("data " MAC_ADDRESS_STR,
+	       MAC_ADDR_ARRAY(peerMacAddr));
+	wlansap_populate_del_sta_params(peerMacAddr,
+			eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
+			(SIR_MAC_MGMT_DISASSOC >> 4),
+			&del_sta_params);
+	hdd_softap_sta_disassoc(adapter, &del_sta_params);
+
+	hdd_exit();
+	return 0;
+}
+
+int
+static iw_softap_disassoc_sta(struct net_device *dev,
+			      struct iw_request_info *info,
+			      union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * iw_get_char_setnone() - Generic "get char" private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_get_char_setnone(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int ret;
+	int sub_cmd = wrqu->data.flags;
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	switch (sub_cmd) {
+	case QCSAP_GET_STATS:
+		hdd_wlan_get_stats(adapter, &(wrqu->data.length),
+					extra, WE_MAX_STR_LEN);
+		break;
+	case QCSAP_LIST_FW_PROFILE:
+		hdd_wlan_list_fw_profile(&(wrqu->data.length),
+					extra, WE_MAX_STR_LEN);
+		break;
+	}
+
+	hdd_exit();
+	return ret;
+}
+
+static int iw_get_char_setnone(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_get_char_setnone(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int __iw_get_channel_list(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *wrqu, char *extra)
+{
+	uint32_t num_channels = 0;
+	uint8_t i = 0;
+	uint8_t band_start_channel = CHAN_ENUM_1;
+	uint8_t band_end_channel = MAX_5GHZ_CHANNEL;
+	struct hdd_adapter *hostapd_adapter = (netdev_priv(dev));
+	struct channel_list_info *channel_list =
+					(struct channel_list_info *) extra;
+	enum band_info cur_band = BAND_ALL;
+	struct hdd_context *hdd_ctx;
+	int ret;
+	bool is_dfs_mode_enabled = false;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	if (QDF_STATUS_SUCCESS != sme_get_freq_band(hdd_ctx->mac_handle,
+						    &cur_band)) {
+		hdd_err("not able get the current frequency band");
+		return -EIO;
+	}
+	wrqu->data.length = sizeof(struct channel_list_info);
+
+	if (BAND_2G == cur_band) {
+		band_start_channel = CHAN_ENUM_1;
+		band_end_channel = CHAN_ENUM_14;
+	} else if (BAND_5G == cur_band) {
+		band_start_channel = CHAN_ENUM_36;
+		band_end_channel = MAX_5GHZ_CHANNEL;
+	}
+
+	if (cur_band != BAND_2G)
+		band_end_channel = MAX_5GHZ_CHANNEL;
+
+	if (hostapd_adapter->device_mode == QDF_STA_MODE &&
+	    hdd_ctx->config->enableDFSChnlScan) {
+		is_dfs_mode_enabled = true;
+	} else if (hostapd_adapter->device_mode == QDF_SAP_MODE) {
+		if (QDF_STATUS_SUCCESS != ucfg_mlme_get_dfs_master_capability(
+				hdd_ctx->psoc, &is_dfs_mode_enabled)) {
+			hdd_err("Fail to get dfs master mode capability");
+			return -EINVAL;
+		}
+	}
+
+	hdd_debug("curBand = %d, StartChannel = %hu, EndChannel = %hu is_dfs_mode_enabled  = %d ",
+			cur_band, band_start_channel, band_end_channel,
+			is_dfs_mode_enabled);
+
+	for (i = band_start_channel; i <= band_end_channel; i++) {
+		if ((CHANNEL_STATE_ENABLE ==
+		     wlan_reg_get_channel_state(hdd_ctx->pdev,
+						WLAN_REG_CH_NUM(i))) ||
+		    (is_dfs_mode_enabled && CHANNEL_STATE_DFS ==
+		     wlan_reg_get_channel_state(hdd_ctx->pdev,
+						WLAN_REG_CH_NUM(i)))) {
+			channel_list->channels[num_channels] =
+						WLAN_REG_CH_NUM(i);
+			num_channels++;
+		}
+	}
+
+	hdd_debug("number of channels %d", num_channels);
+
+	channel_list->num_channels = num_channels;
+	hdd_exit();
+
+	return 0;
+}
+
+int iw_get_channel_list(struct net_device *dev,
+		struct iw_request_info *info,
+		union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_get_channel_list(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static
+int __iw_get_genie(struct net_device *dev,
+		   struct iw_request_info *info,
+		   union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	struct hdd_context *hdd_ctx;
+	int ret;
+	QDF_STATUS status;
+	uint32_t length = DOT11F_IE_RSN_MAX_LEN;
+	uint8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	/*
+	 * Actually retrieve the RSN IE from CSR.
+	 * (We previously sent it down in the CSR Roam Profile.)
+	 */
+	status = wlan_sap_getstation_ie_information(
+		WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+		&length, genIeBytes);
+	if (status == QDF_STATUS_SUCCESS) {
+		wrqu->data.length = length;
+		if (length > DOT11F_IE_RSN_MAX_LEN) {
+			hdd_err("Invalid buffer length: %d", length);
+			return -E2BIG;
+		}
+		qdf_mem_copy(extra, genIeBytes, length);
+		hdd_debug(" RSN IE of %d bytes returned",
+				wrqu->data.length);
+	} else {
+		wrqu->data.length = 0;
+		hdd_debug(" RSN IE failed to populate");
+	}
+
+	hdd_exit();
+	return 0;
+}
+
+static
+int iw_get_genie(struct net_device *dev,
+		 struct iw_request_info *info,
+		 union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_get_genie(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int
+__iw_softap_stopbss(struct net_device *dev,
+		    struct iw_request_info *info,
+		    union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
+		struct hdd_hostapd_state *hostapd_state =
+			WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+
+		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
+		status = wlansap_stop_bss(
+			WLAN_HDD_GET_SAP_CTX_PTR(adapter));
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			status =
+				qdf_wait_for_event_completion(&hostapd_state->
+					qdf_stop_bss_event,
+					SME_CMD_START_STOP_BSS_TIMEOUT);
+
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				hdd_err("wait for single_event failed!!");
+				QDF_ASSERT(0);
+			}
+		}
+		clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
+		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
+					     adapter->device_mode,
+					     adapter->session_id);
+		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
+		ret = qdf_status_to_os_return(status);
+	}
+	hdd_exit();
+	return ret;
+}
+
+static int iw_softap_stopbss(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu,
+			     char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_stopbss(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int
+__iw_softap_version(struct net_device *dev,
+		    struct iw_request_info *info,
+		    union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = netdev_priv(dev);
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	wrqu->data.length = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN,
+						 extra);
+	hdd_exit();
+	return 0;
+}
+
+static int iw_softap_version(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu,
+			     char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_version(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int hdd_softap_get_sta_info(struct hdd_adapter *adapter,
+				   uint8_t *buf,
+				   int size)
+{
+	int i;
+	int written;
+	uint8_t bc_sta_id;
+
+	hdd_enter();
+
+	bc_sta_id = WLAN_HDD_GET_AP_CTX_PTR(adapter)->broadcast_sta_id;
+
+	written = scnprintf(buf, size, "\nstaId staAddress\n");
+	for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
+		struct hdd_station_info *sta = &adapter->sta_info[i];
+
+		if (written >= size - 1)
+			break;
+
+		if (!sta->in_use)
+			continue;
+
+		if (i == bc_sta_id)
+			continue;
+
+		written += scnprintf(buf + written, size - written,
+				     "%5d %02x:%02x:%02x:%02x:%02x:%02x ecsa=%d\n",
+				     sta->sta_id,
+				     sta->sta_mac.bytes[0],
+				     sta->sta_mac.bytes[1],
+				     sta->sta_mac.bytes[2],
+				     sta->sta_mac.bytes[3],
+				     sta->sta_mac.bytes[4],
+				     sta->sta_mac.bytes[5],
+				     sta->ecsa_capable);
+	}
+
+	hdd_exit();
+
+	return 0;
+}
+
+static int __iw_softap_get_sta_info(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *wrqu, char *extra)
+{
+	int errno;
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter_dev(dev);
+
+	adapter = netdev_priv(dev);
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		return errno;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	errno = hdd_check_private_wext_control(hdd_ctx, info);
+	if (errno)
+		return errno;
+
+	errno = hdd_softap_get_sta_info(adapter, extra, WE_SAP_MAX_STA_INFO);
+	if (errno) {
+		hdd_err("Failed to get sta info; errno:%d", errno);
+		return errno;
+	}
+
+	wrqu->data.length = strlen(extra);
+
+	hdd_exit();
+
+	return 0;
+}
+
+static int iw_softap_get_sta_info(struct net_device *dev,
+				  struct iw_request_info *info,
+				  union iwreq_data *wrqu,
+				  char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_get_sta_info(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int __iw_softap_get_ba_timeout(struct net_device *dev,
+				      struct iw_request_info *info,
+				      union iwreq_data *wrqu, char *extra)
+{
+	int errno;
+	uint8_t ac_cat = 4;
+	uint32_t duration[ac_cat], i;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter_dev(dev);
+
+	adapter = netdev_priv(dev);
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		return errno;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	if (!soc) {
+		hdd_err("Invalid handle");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < ac_cat; i++)
+		cdp_get_ba_timeout(soc, i, &duration[i]);
+
+	snprintf(extra, WE_SAP_MAX_STA_INFO,
+		 "\n|------------------------------|\n"
+		 "|AC | BA aging timeout duration |\n"
+		 "|--------------------------------|\n"
+		 "|VO |  %d        |\n"
+		 "|VI |  %d        |\n"
+		 "|BE |  %d        |\n"
+		 "|BK |  %d        |\n"
+		 "|--------------------------------|\n",
+		duration[3], duration[2], duration[1], duration[0]);
+
+	wrqu->data.length = strlen(extra) + 1;
+	hdd_exit();
+
+	return 0;
+}
+
+static int iw_softap_get_ba_timeout(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *wrqu,
+				    char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_softap_get_ba_timeout(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static
+int __iw_get_softap_linkspeed(struct net_device *dev,
+			      struct iw_request_info *info,
+			      union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	struct hdd_context *hdd_ctx;
+	char *pLinkSpeed = (char *)extra;
+	uint32_t link_speed = 0;
+	int len = sizeof(uint32_t) + 1;
+	struct qdf_mac_addr macAddress;
+	char pmacAddress[MAC_ADDRESS_STR_LEN + 1];
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	int rc, ret, i;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	hdd_debug("wrqu->data.length(%d)", wrqu->data.length);
+
+	/* Linkspeed is allowed only for P2P mode */
+	if (adapter->device_mode != QDF_P2P_GO_MODE) {
+		hdd_err("Link Speed is not allowed in Device mode %s(%d)",
+			qdf_opmode_str(adapter->device_mode),
+			adapter->device_mode);
+		return -ENOTSUPP;
+	}
+
+	if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {
+		if (copy_from_user((void *)pmacAddress,
+				   wrqu->data.pointer, MAC_ADDRESS_STR_LEN)) {
+			hdd_err("failed to copy data to user buffer");
+			return -EFAULT;
+		}
+		pmacAddress[MAC_ADDRESS_STR_LEN - 1] = '\0';
+
+		if (!mac_pton(pmacAddress, macAddress.bytes)) {
+			hdd_err("String to Hex conversion Failed");
+			return -EINVAL;
+		}
+	}
+	/* If no mac address is passed and/or its length is less than 17,
+	 * link speed for first connected client will be returned.
+	 */
+	if (wrqu->data.length < 17 || !QDF_IS_STATUS_SUCCESS(status)) {
+		for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
+			if (adapter->sta_info[i].in_use &&
+			    (!qdf_is_macaddr_broadcast
+				  (&adapter->sta_info[i].sta_mac))) {
+				qdf_copy_macaddr(
+					&macAddress,
+					&adapter->sta_info[i].
+					 sta_mac);
+				status = QDF_STATUS_SUCCESS;
+				break;
+			}
+		}
+	}
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Invalid peer macaddress");
+		return -EINVAL;
+	}
+	rc = wlan_hdd_get_linkspeed_for_peermac(adapter, &macAddress,
+						&link_speed);
+	if (rc) {
+		hdd_err("Unable to retrieve SME linkspeed");
+		return rc;
+	}
+
+	/* linkspeed in units of 500 kbps */
+	link_speed = link_speed / 500;
+	wrqu->data.length = len;
+	rc = snprintf(pLinkSpeed, len, "%u", link_speed);
+	if ((rc < 0) || (rc >= len)) {
+		/* encoding or length error? */
+		hdd_err("Unable to encode link speed");
+		return -EIO;
+	}
+	hdd_exit();
+	return 0;
+}
+
+static int
+iw_get_softap_linkspeed(struct net_device *dev,
+			struct iw_request_info *info,
+			union iwreq_data *wrqu,
+			char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __iw_get_peer_rssi() - get station's rssi
+ * @dev: net device
+ * @info: iwpriv request information
+ * @wrqu: iwpriv command parameter
+ * @extra
+ *
+ * This function will call wlan_hdd_get_peer_rssi
+ * to get rssi
+ *
+ * Return: 0 on success, otherwise error value
+ */
+#ifdef QCA_SUPPORT_CP_STATS
+static int
+__iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info,
+		   union iwreq_data *wrqu, char *extra)
+{
+	int ret, i;
+	struct hdd_context *hddctx;
+	struct stats_event *rssi_info;
+	char macaddrarray[MAC_ADDRESS_STR_LEN];
+	struct hdd_adapter *adapter = netdev_priv(dev);
+	struct qdf_mac_addr macaddress = QDF_MAC_ADDR_BCAST_INIT;
+
+	hdd_enter();
+
+	hddctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hddctx);
+	if (ret != 0)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hddctx, info);
+	if (0 != ret)
+		return ret;
+
+	hdd_debug("wrqu->data.length= %d", wrqu->data.length);
+
+	if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {
+		if (copy_from_user(macaddrarray,
+				   wrqu->data.pointer,
+				   MAC_ADDRESS_STR_LEN - 1)) {
+			hdd_info("failed to copy data from user buffer");
+			return -EFAULT;
+		}
+
+		macaddrarray[MAC_ADDRESS_STR_LEN - 1] = '\0';
+		hdd_debug("%s", macaddrarray);
+
+		if (!mac_pton(macaddrarray, macaddress.bytes))
+			hdd_err("String to Hex conversion Failed");
+	}
+
+	rssi_info = wlan_cfg80211_mc_cp_stats_get_peer_rssi(adapter->vdev,
+							    macaddress.bytes,
+							    &ret);
+	if (ret || !rssi_info) {
+		wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
+		return ret;
+	}
+
+	wrqu->data.length = scnprintf(extra, IW_PRIV_SIZE_MASK, "\n");
+	for (i = 0; i < rssi_info->num_peer_stats; i++)
+		wrqu->data.length +=
+			scnprintf(extra + wrqu->data.length,
+				  IW_PRIV_SIZE_MASK - wrqu->data.length,
+				  "[%pM] [%d]\n",
+				  rssi_info->peer_stats[i].peer_macaddr,
+				  rssi_info->peer_stats[i].peer_rssi);
+
+	wrqu->data.length++;
+	wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
+	hdd_exit();
+
+	return 0;
+}
+#else
+static int
+__iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info,
+		   union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = netdev_priv(dev);
+	struct hdd_context *hddctx;
+	char macaddrarray[MAC_ADDRESS_STR_LEN];
+	struct qdf_mac_addr macaddress = QDF_MAC_ADDR_BCAST_INIT;
+	int ret;
+	char *rssi_info_output = extra;
+	struct sir_peer_sta_info peer_sta_info;
+	struct sir_peer_info *rssi_info;
+	int i;
+	int buf;
+	int length;
+
+	hdd_enter();
+
+	hddctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hddctx);
+	if (ret != 0)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hddctx, info);
+	if (0 != ret)
+		return ret;
+
+	hdd_debug("wrqu->data.length= %d", wrqu->data.length);
+
+	if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {
+		if (copy_from_user(macaddrarray,
+				   wrqu->data.pointer,
+				   MAC_ADDRESS_STR_LEN - 1)) {
+			hdd_info("failed to copy data from user buffer");
+			return -EFAULT;
+		}
+
+		macaddrarray[MAC_ADDRESS_STR_LEN - 1] = '\0';
+		hdd_debug("%s", macaddrarray);
+
+		if (!mac_pton(macaddrarray, macaddress.bytes))
+			hdd_err("String to Hex conversion Failed");
+	}
+
+	ret = wlan_hdd_get_peer_rssi(adapter, &macaddress, &peer_sta_info);
+	if (ret) {
+		hdd_err("Unable to retrieve peer rssi: %d", ret);
+		return ret;
+	}
+	/*
+	 * The iwpriv tool default print is before mac addr and rssi.
+	 * Add '\n' before first rssi item to align the first rssi item
+	 * with others
+	 *
+	 * wlan     getRSSI:
+	 * [macaddr1] [rssi1]
+	 * [macaddr2] [rssi2]
+	 * [macaddr3] [rssi3]
+	 */
+	length = scnprintf(rssi_info_output, WE_MAX_STR_LEN, "\n");
+	rssi_info = &peer_sta_info.info[0];
+	for (i = 0; i < peer_sta_info.sta_num; i++) {
+		buf = scnprintf
+			(
+			rssi_info_output + length, WE_MAX_STR_LEN - length,
+			"[%pM] [%d]\n",
+			rssi_info[i].peer_macaddr.bytes,
+			rssi_info[i].rssi
+			);
+		length += buf;
+	}
+	wrqu->data.length = length + 1;
+	hdd_exit();
+
+	return 0;
+}
+#endif
+
+/**
+ * iw_get_peer_rssi() - get station's rssi
+ * @dev: net device
+ * @info: iwpriv request information
+ * @wrqu: iwpriv command parameter
+ * @extra
+ *
+ * This function will call __iw_get_peer_rssi
+ *
+ * Return: 0 on success, otherwise error value
+ */
+static int
+iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info,
+		 union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_get_peer_rssi(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/*
+ * Note that the following ioctls were defined with semantics which
+ * cannot be handled by the "iwpriv" userspace application and hence
+ * they are not included in the hostapd_private_args array
+ *     QCSAP_IOCTL_ASSOC_STA_MACADDR
+ */
+
+static const struct iw_priv_args hostapd_private_args[] = {
+	{
+		QCSAP_IOCTL_SETPARAM,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam"
+	}, {
+		QCSAP_IOCTL_SETPARAM,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""
+	}, {
+		QCSAP_PARAM_MAX_ASSOC,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+		"setMaxAssoc"
+	}, {
+		QCSAP_PARAM_HIDE_SSID,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID"
+	}, {
+		QCSAP_PARAM_SET_MC_RATE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate"
+	}, {
+		QCSAP_PARAM_SET_TXRX_FW_STATS,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+		"txrx_fw_stats"
+	}, {
+		QCSAP_PARAM_SET_TXRX_STATS,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0,
+		"txrx_stats"
+	}, {
+		QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+		"setMccLatency"
+	}, {
+		QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+		"setMccQuota"
+	}, {
+		QCSAP_PARAM_SET_CHANNEL_CHANGE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+		"setChanChange"
+	}, {
+		QCSAP_PARAM_CONC_SYSTEM_PREF,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+		"setConcSysPref"
+	},
+#ifdef FEATURE_FW_LOG_PARSING
+	/* Sub-cmds DBGLOG specific commands */
+	{
+		QCSAP_DBGLOG_LOG_LEVEL,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "dl_loglevel"
+	}, {
+		QCSAP_DBGLOG_VAP_ENABLE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_vapon"
+	}, {
+		QCSAP_DBGLOG_VAP_DISABLE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "dl_vapoff"
+	}, {
+		QCSAP_DBGLOG_MODULE_ENABLE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_modon"
+	}, {
+		QCSAP_DBGLOG_MODULE_DISABLE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "dl_modoff"
+	}, {
+		QCSAP_DBGLOG_MOD_LOG_LEVEL,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "dl_mod_loglevel"
+	}, {
+		QCSAP_DBGLOG_TYPE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_type"
+	}, {
+		QCSAP_DBGLOG_REPORT_ENABLE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "dl_report"
+	},
+#endif /* FEATURE_FW_LOG_PARSING */
+	{
+
+		QCASAP_TXRX_FWSTATS_RESET,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "txrx_fw_st_rst"
+	}, {
+		QCSAP_PARAM_RTSCTS,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "enablertscts"
+	}, {
+		QCASAP_SET_11N_RATE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "set11NRates"
+	}, {
+		QCASAP_SET_VHT_RATE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "set11ACRates"
+	}, {
+		QCASAP_SHORT_GI,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "enable_short_gi"
+	}, {
+		QCSAP_SET_AMPDU,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ampdu"
+	}, {
+		QCSAP_SET_AMSDU,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "amsdu"
+	}, {
+		QCSAP_GTX_HT_MCS,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxHTMcs"
+	}, {
+		QCSAP_GTX_VHT_MCS,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "gtxVHTMcs"
+	}, {
+		QCSAP_GTX_USRCFG,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "gtxUsrCfg"
+	}, {
+		QCSAP_GTX_THRE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxThre"
+	}, {
+		QCSAP_GTX_MARGIN,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "gtxMargin"
+	}, {
+		QCSAP_GTX_STEP,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxStep"
+	}, {
+		QCSAP_GTX_MINTPC,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "gtxMinTpc"
+	}, {
+		QCSAP_GTX_BWMASK,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "gtxBWMask"
+	}, {
+		QCSAP_PARAM_CLR_ACL,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "setClearAcl"
+	}, {
+		QCSAP_PARAM_ACL_MODE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode"
+	},
+	{
+		QCASAP_SET_TM_LEVEL,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "setTmLevel"
+	}, {
+		QCASAP_SET_DFS_IGNORE_CAC,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "setDfsIgnoreCAC"
+	}, {
+		QCASAP_SET_DFS_NOL,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "setdfsnol"
+	}, {
+		QCASAP_SET_DFS_TARGET_CHNL,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "setNextChnl"
+	}, {
+		QCASAP_SET_RADAR_CMD,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setRadar"
+	},
+	{
+		QCSAP_IPA_UC_STAT,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ipaucstat"
+	},
+	{
+		QCASAP_TX_CHAINMASK_CMD,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "set_txchainmask"
+	}, {
+		QCASAP_RX_CHAINMASK_CMD,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "set_rxchainmask"
+	}, {
+		QCASAP_SET_HE_BSS_COLOR,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_he_bss_clr"
+	}, {
+		QCASAP_NSS_CMD,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_nss"
+	}, {
+		QCASAP_SET_PHYMODE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "setphymode"
+	}, {
+		QCASAP_DUMP_STATS,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "dumpStats"
+	}, {
+		QCASAP_CLEAR_STATS,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "clearStats"
+	}, {
+		QCSAP_START_FW_PROFILING,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "startProfile"
+	}, {
+		QCASAP_PARAM_LDPC,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "set_ldpc"
+	}, {
+		QCASAP_PARAM_TX_STBC,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "set_tx_stbc"
+	}, {
+		QCASAP_PARAM_RX_STBC,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "set_rx_stbc"
+	}, {
+		QCSAP_IOCTL_GETPARAM, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam"
+	}, {
+		QCSAP_IOCTL_GETPARAM, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""
+	}, {
+		QCSAP_PARAM_MAX_ASSOC, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc"
+	}, {
+		QCSAP_PARAM_GET_WLAN_DBG, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg"
+	}, {
+		QCSAP_GTX_BWMASK, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_gtxBWMask"
+	}, {
+		QCSAP_GTX_MINTPC, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_gtxMinTpc"
+	}, {
+		QCSAP_GTX_STEP, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_gtxStep"
+	}, {
+		QCSAP_GTX_MARGIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_gtxMargin"
+	}, {
+		QCSAP_GTX_THRE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_gtxThre"
+	}, {
+		QCSAP_GTX_USRCFG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_gtxUsrCfg"
+	}, {
+		QCSAP_GTX_VHT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_gtxVHTMcs"
+	}, {
+		QCSAP_GTX_HT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_gtxHTMcs"
+	}, {
+		QCASAP_SHORT_GI, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_short_gi"
+	}, {
+		QCSAP_PARAM_RTSCTS, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rtscts"
+	}, {
+		QCASAP_GET_DFS_NOL, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdfsnol"
+	}, {
+		QCSAP_GET_ACL, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_acl_list"
+	}, {
+		QCASAP_PARAM_LDPC, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_ldpc"
+	}, {
+		QCASAP_PARAM_TX_STBC, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_tx_stbc"
+	}, {
+		QCASAP_PARAM_RX_STBC, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_rx_stbc"
+	}, {
+		QCSAP_PARAM_CHAN_WIDTH, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_chwidth"
+	}, {
+		QCASAP_TX_CHAINMASK_CMD, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_txchainmask"
+	}, {
+		QCASAP_RX_CHAINMASK_CMD, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_rxchainmask"
+	}, {
+		QCASAP_NSS_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"get_nss"
+	}, {
+		QCSAP_CAP_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"cap_tsf"
+	}, {
+		QCSAP_IOCTL_SET_NONE_GET_THREE, 0, IW_PRIV_TYPE_INT |
+		IW_PRIV_SIZE_FIXED | 3,    ""
+	}, {
+		QCSAP_GET_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+		"get_tsf"
+	}, {
+		QCASAP_GET_TEMP_CMD, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp"
+	}, {
+		QCSAP_GET_FW_PROFILE_DATA, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getProfileData"
+	}, {
+		QCSAP_IOCTL_GET_STAWPAIE,
+		0, IW_PRIV_TYPE_BYTE | DOT11F_IE_RSN_MAX_LEN,
+		"get_staWPAIE"
+	}, {
+		QCSAP_IOCTL_STOPBSS, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0,
+		"stopbss"
+	}, {
+		QCSAP_IOCTL_VERSION, 0, IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+		"version"
+	}, {
+		QCSAP_IOCTL_GET_STA_INFO, 0,
+		IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info"
+	}, {
+		QCSAP_IOCTL_GET_CHANNEL, 0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
+	}, {
+		QCSAP_IOCTL_GET_BA_AGEING_TIMEOUT, 0,
+		IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_ba_timeout"
+	}, {
+		QCSAP_IOCTL_DISASSOC_STA,
+		IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6, 0,
+		"disassoc_sta"
+	}
+	/* handler for main ioctl */
+	, {
+		QCSAP_PRIV_GET_CHAR_SET_NONE, 0,
+		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, ""
+	}
+	/* handler for sub-ioctl */
+	, {
+		QCSAP_GET_STATS, 0,
+		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getStats"
+	}
+	, {
+		QCSAP_LIST_FW_PROFILE, 0,
+		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "listProfile"
+	}
+	, {
+		QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
+		IW_PRIV_TYPE_CHAR | 18,
+		IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
+	}
+	, {
+		QCSAP_IOCTL_PRIV_GET_RSSI,
+		IW_PRIV_TYPE_CHAR | 18,
+		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getRSSI"
+	}
+	, {
+		QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""
+	}
+	,
+	/* handlers for sub-ioctl */
+	{
+		WE_SET_WLAN_DBG,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setwlandbg"
+	}
+	,
+#ifdef CONFIG_DP_TRACE
+	/* handlers for sub-ioctl */
+	{
+		WE_SET_DP_TRACE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_dp_trace"
+	}
+	,
+#endif
+	/* handlers for main ioctl */
+	{
+		QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
+		IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, ""
+	}
+	, {
+		WE_P2P_NOA_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, "SetP2pPs"
+	}
+	, {
+		WE_UNIT_TEST_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0,
+		"setUnitTestCmd"
+	}
+#ifdef WLAN_DEBUG
+	,
+	{
+		WE_SET_CHAN_AVOID,
+		IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+		0,
+		"ch_avoid"
+	}
+#endif
+	,
+	/* handlers for main ioctl */
+	{
+		QCSAP_IOCTL_MODIFY_ACL,
+		IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8, 0, "modify_acl"
+	}
+	,
+	/* handlers for main ioctl */
+	{
+		QCSAP_IOCTL_GET_CHANNEL_LIST,
+		0,
+		IW_PRIV_TYPE_BYTE | sizeof(struct channel_list_info),
+		"getChannelList"
+	}
+	,
+	/* handlers for main ioctl */
+	{
+		QCSAP_IOCTL_SET_TX_POWER,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setTxPower"
+	}
+	,
+	/* handlers for main ioctl */
+	{
+		QCSAP_IOCTL_SET_MAX_TX_POWER,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "setTxMaxPower"
+	}
+	,
+	{
+		QCSAP_IOCTL_SET_PKTLOG,
+		IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+		0, "pktlog"
+	}
+	,
+	/* Set HDD CFG Ini param */
+	{
+		QCSAP_IOCTL_SET_INI_CFG,
+		IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, 0, "setConfig"
+	}
+	,
+	/* Get HDD CFG Ini param */
+	{
+		QCSAP_IOCTL_GET_INI_CFG,
+		0, IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, "getConfig"
+	}
+	,
+	/* handlers for main ioctl */
+	{
+	/* handlers for main ioctl */
+		QCSAP_IOCTL_SET_TWO_INT_GET_NONE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""
+	}
+	,
+	/* handlers for sub-ioctl */
+#ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT
+	{
+		QCSAP_IOCTL_SET_FW_CRASH_INJECT,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+		0, "crash_inject"
+	}
+	,
+#endif
+	{
+		QCASAP_SET_RADAR_DBG,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0,  "setRadarDbg"
+	}
+	,
+#ifdef CONFIG_DP_TRACE
+	/* dump dp trace - descriptor or dp trace records */
+	{
+		QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+		0, "dump_dp_trace"
+	}
+	,
+#endif
+	{
+		QCSAP_ENABLE_FW_PROFILE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+		0, "enableProfile"
+	}
+	,
+	{
+		QCSAP_SET_FW_PROFILE_HIST_INTVL,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+		0, "set_hist_intvl"
+	}
+	,
+#ifdef WLAN_SUSPEND_RESUME_TEST
+	{
+		QCSAP_SET_WLAN_SUSPEND,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+		0, "wlan_suspend"
+	}
+	,
+	{
+		QCSAP_SET_WLAN_RESUME,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+		0, "wlan_resume"
+	}
+	,
+#endif
+	{
+		QCSAP_SET_BA_AGEING_TIMEOUT,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+		0, "set_ba_timeout"
+	}
+	,
+	{
+		QCASAP_SET_11AX_RATE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "set_11ax_rate"
+	}
+	,
+	{
+		QCASAP_SET_PEER_RATE,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "set_peer_rate"
+	}
+	,
+	{
+		QCASAP_PARAM_DCM,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "enable_dcm"
+	}
+	,
+	{
+		QCASAP_PARAM_RANGE_EXT,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "range_ext"
+	}
+	,
+	{	QCSAP_SET_DEFAULT_AMPDU,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "def_ampdu"
+	}
+	,
+	{	QCSAP_ENABLE_RTS_BURSTING,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0, "rts_bursting"
+	}
+	,
+};
+
+static const iw_handler hostapd_private[] = {
+	/* set priv ioctl */
+	[QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam,
+	/* get priv ioctl */
+	[QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam,
+	[QCSAP_IOCTL_SET_NONE_GET_THREE - SIOCIWFIRSTPRIV] =
+							iw_softap_get_three,
+	/* get station genIE */
+	[QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie,
+	/* stop bss */
+	[QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss,
+	/* get driver version */
+	[QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version,
+	[QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] =
+		iw_softap_getchannel,
+	[QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] =
+		iw_softap_getassoc_stamacaddr,
+	[QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] =
+		iw_softap_disassoc_sta,
+	[QCSAP_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] =
+		iw_get_char_setnone,
+	[QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE -
+	 SIOCIWFIRSTPRIV] =
+		iw_set_three_ints_getnone,
+	[QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE -
+	 SIOCIWFIRSTPRIV] =
+		iw_set_var_ints_getnone,
+	[QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] =
+		iw_softap_modify_acl,
+	[QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] =
+		iw_get_channel_list,
+	[QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] =
+		iw_softap_get_sta_info,
+	[QCSAP_IOCTL_GET_BA_AGEING_TIMEOUT - SIOCIWFIRSTPRIV] =
+		iw_softap_get_ba_timeout,
+	[QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED -
+	 SIOCIWFIRSTPRIV] =
+		iw_get_softap_linkspeed,
+	[QCSAP_IOCTL_PRIV_GET_RSSI - SIOCIWFIRSTPRIV] =
+		iw_get_peer_rssi,
+	[QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] =
+		iw_softap_set_tx_power,
+	[QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] =
+		iw_softap_set_max_tx_power,
+	[QCSAP_IOCTL_SET_PKTLOG - SIOCIWFIRSTPRIV] =
+		iw_softap_set_pktlog,
+	[QCSAP_IOCTL_SET_INI_CFG - SIOCIWFIRSTPRIV] =
+		iw_softap_set_ini_cfg,
+	[QCSAP_IOCTL_GET_INI_CFG - SIOCIWFIRSTPRIV] =
+		iw_softap_get_ini_cfg,
+	[QCSAP_IOCTL_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
+		iw_softap_set_two_ints_getnone,
+};
+
+const struct iw_handler_def hostapd_handler_def = {
+	.num_standard = 0,
+	.num_private = QDF_ARRAY_SIZE(hostapd_private),
+	.num_private_args = QDF_ARRAY_SIZE(hostapd_private_args),
+	.standard = NULL,
+	.private = (iw_handler *)hostapd_private,
+	.private_args = hostapd_private_args,
+	.get_wireless_stats = NULL,
+};
+
+/**
+ * hdd_register_wext() - register wext context
+ * @dev: net device handle
+ *
+ * Registers wext interface context for a given net device
+ *
+ * Returns: 0 on success, errno on failure
+ */
+void hdd_register_hostapd_wext(struct net_device *dev)
+{
+	hdd_enter_dev(dev);
+	/* Register as a wireless device */
+	dev->wireless_handlers = (struct iw_handler_def *)&hostapd_handler_def;
+
+	hdd_exit();
+}
+
diff --git a/core/hdd/src/wlan_hdd_hostapd_wext.h b/core/hdd/src/wlan_hdd_hostapd_wext.h
new file mode 100644
index 0000000..d5d48c8
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_hostapd_wext.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef WLAN_HDD_HOSTAPD_WEXT_H
+#define WLAN_HDD_HOSTAPD_WEXT_H
+
+/**
+ * DOC: wlan_hdd_hostapd_wext.h
+ *
+ * WLAN Host Device driver hostapd wext header file
+ */
+
+/* Include files */
+
+#include <linux/netdevice.h>
+
+/* Preprocessor definitions and constants */
+#ifdef WLAN_WEXT_SUPPORT_ENABLE
+void hdd_register_hostapd_wext(struct net_device *dev);
+#else
+static inline void hdd_register_hostapd_wext(struct net_device *dev)
+{
+}
+#endif
+
+#endif /* end #ifndef WLAN_HDD_HOSTAPD_H */
diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c
new file mode 100644
index 0000000..96e976a
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_ioctl.c
@@ -0,0 +1,7737 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/* Include Files */
+
+#include <wlan_hdd_includes.h>
+#include <wlan_hdd_wowl.h>
+#include <wlan_hdd_stats.h>
+#include "cfg_ucfg_api.h"
+#include "wlan_hdd_trace.h"
+#include "wlan_hdd_ioctl.h"
+#include "wlan_hdd_power.h"
+#include "wlan_hdd_regulatory.h"
+#include "wlan_osif_request_manager.h"
+#include "wlan_hdd_driver_ops.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_hdd_hostapd.h"
+#include "scheduler_api.h"
+#include "wlan_reg_ucfg_api.h"
+#include "wlan_hdd_p2p.h"
+#include <linux/ctype.h>
+#include "wma.h"
+#include "wlan_hdd_napi.h"
+#include "wlan_mlme_ucfg_api.h"
+#ifdef FEATURE_WLAN_ESE
+#include <sme_api.h>
+#include <sir_api.h>
+#endif
+#include "hif.h"
+
+#if defined(LINUX_QCMBR)
+#define SIOCIOCTLTX99 (SIOCDEVPRIVATE+13)
+#endif
+
+/*
+ * Size of Driver command strings from upper layer
+ */
+#define SIZE_OF_SETROAMMODE             11      /* size of SETROAMMODE */
+#define SIZE_OF_GETROAMMODE             11      /* size of GETROAMMODE */
+
+/*
+ * Ibss prop IE from command will be of size:
+ * size  = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length)
+ * OUI_DATA should be at least 3 bytes long
+ */
+#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3)
+
+#ifdef FEATURE_WLAN_ESE
+#define TID_MIN_VALUE 0
+#define TID_MAX_VALUE 15
+#endif /* FEATURE_WLAN_ESE */
+
+/*
+ * Maximum buffer size used for returning the data back to user space
+ */
+#define WLAN_MAX_BUF_SIZE 1024
+#define WLAN_PRIV_DATA_MAX_LEN    8192
+
+/*
+ * Driver miracast parameters 0-Disabled
+ * 1-Source, 2-Sink
+ */
+#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
+#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
+
+/*
+ * When ever we need to print IBSSPEERINFOALL for more than 16 STA
+ * we will split the printing.
+ */
+#define NUM_OF_STA_DATA_TO_PRINT 16
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+/**
+ * struct enable_ext_wow_priv - Private data structure for ext wow
+ * @ext_wow_should_suspend: Suspend status of ext wow
+ */
+struct enable_ext_wow_priv {
+	bool ext_wow_should_suspend;
+};
+#endif
+
+/*
+ * Android DRIVER command structures
+ */
+struct android_wifi_reassoc_params {
+	unsigned char bssid[18];
+	int channel;
+};
+
+#define ANDROID_WIFI_ACTION_FRAME_SIZE 1040
+struct android_wifi_af_params {
+	unsigned char bssid[18];
+	int channel;
+	int dwell_time;
+	int len;
+	unsigned char data[ANDROID_WIFI_ACTION_FRAME_SIZE];
+};
+
+/*
+ * Define HDD driver command handling entry, each contains a command
+ * string and the handler.
+ */
+typedef int (*hdd_drv_cmd_handler_t)(struct hdd_adapter *adapter,
+				     struct hdd_context *hdd_ctx,
+				     uint8_t *cmd,
+				     uint8_t cmd_name_len,
+				     struct hdd_priv_data *priv_data);
+
+/**
+ * struct hdd_drv_cmd - Structure to store ioctl command handling info
+ * @cmd: Name of the command
+ * @handler: Command handler to be invoked
+ * @args: Set to true if command expects input parameters
+ */
+struct hdd_drv_cmd {
+	const char *cmd;
+	hdd_drv_cmd_handler_t handler;
+	bool args;
+};
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+#define WLAN_WAIT_TIME_READY_TO_EXTWOW   2000
+#define WLAN_HDD_MAX_TCP_PORT            65535
+#endif
+
+static uint16_t cesium_pid;
+
+/**
+ * drv_cmd_validate() - Validates for space in hdd driver command
+ * @command: pointer to input data (its a NULL terminated string)
+ * @len: length of command name
+ *
+ * This function checks for space after command name and if no space
+ * is found returns error.
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int drv_cmd_validate(uint8_t *command, int len)
+{
+	if (command[len] != ' ')
+		return -EINVAL;
+
+	return 0;
+}
+
+#ifdef FEATURE_WLAN_ESE
+struct tsm_priv {
+	tAniTrafStrmMetrics tsm_metrics;
+};
+
+static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
+				 const uint32_t staId, void *context)
+{
+	struct osif_request *request;
+	struct tsm_priv *priv;
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+	priv = osif_request_priv(request);
+	priv->tsm_metrics = tsm_metrics;
+	osif_request_complete(request);
+	osif_request_put(request);
+	hdd_exit();
+
+}
+
+static int hdd_get_tsm_stats(struct hdd_adapter *adapter,
+			     const uint8_t tid,
+			     tAniTrafStrmMetrics *tsm_metrics)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_station_ctx *hdd_sta_ctx;
+	QDF_STATUS status;
+	int ret;
+	void *cookie;
+	struct osif_request *request;
+	struct tsm_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
+
+	if (NULL == adapter) {
+		hdd_err("adapter is NULL");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	status = sme_get_tsm_stats(hdd_ctx->mac_handle, hdd_get_tsm_stats_cb,
+				   hdd_sta_ctx->conn_info.staId[0],
+				   hdd_sta_ctx->conn_info.bssId,
+				   cookie, tid);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Unable to retrieve tsm statistics");
+		ret = qdf_status_to_os_return(status);
+		goto cleanup;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_err("SME timed out while retrieving tsm statistics");
+		goto cleanup;
+	}
+
+	priv = osif_request_priv(request);
+	*tsm_metrics = priv->tsm_metrics;
+
+ cleanup:
+	osif_request_put(request);
+
+	return ret;
+}
+#endif /*FEATURE_WLAN_ESE */
+
+/**
+ * hdd_get_ibss_peer_info_cb() - IBSS peer Info request callback
+ * @UserData: Adapter private data
+ * @pPeerInfoRsp: Peer info response
+ *
+ * This is an asynchronous callback function from SME when the peer info
+ * is received
+ *
+ * Return: 0 for success non-zero for failure
+ */
+void
+hdd_get_ibss_peer_info_cb(void *pUserData,
+				tSirPeerInfoRspParams *pPeerInfo)
+{
+	struct hdd_adapter *adapter = (struct hdd_adapter *) pUserData;
+	struct hdd_station_ctx *pStaCtx;
+	uint8_t i;
+
+	if ((NULL == adapter) ||
+	    (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		hdd_err("invalid adapter or adapter has invalid magic");
+		return;
+	}
+
+	pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (NULL != pPeerInfo && QDF_STATUS_SUCCESS == pPeerInfo->status) {
+		/* validate number of peers */
+		if (pPeerInfo->numPeers > SIR_MAX_NUM_STA_IN_IBSS) {
+			hdd_warn("Limiting num_peers %u to %u",
+				pPeerInfo->numPeers, SIR_MAX_NUM_STA_IN_IBSS);
+			pPeerInfo->numPeers = SIR_MAX_NUM_STA_IN_IBSS;
+		}
+		pStaCtx->ibss_peer_info.status = pPeerInfo->status;
+		pStaCtx->ibss_peer_info.numPeers = pPeerInfo->numPeers;
+
+		for (i = 0; i < pPeerInfo->numPeers; i++)
+			pStaCtx->ibss_peer_info.peerInfoParams[i] =
+				pPeerInfo->peerInfoParams[i];
+	} else {
+		hdd_debug("peerInfo %s: status %u, numPeers %u",
+			pPeerInfo ? "valid" : "null",
+			pPeerInfo ? pPeerInfo->status : QDF_STATUS_E_FAILURE,
+			pPeerInfo ? pPeerInfo->numPeers : 0);
+		pStaCtx->ibss_peer_info.numPeers = 0;
+		pStaCtx->ibss_peer_info.status = QDF_STATUS_E_FAILURE;
+	}
+
+	complete(&adapter->ibss_peer_info_comp);
+}
+
+/**
+ * hdd_cfg80211_get_ibss_peer_info_all() - get ibss peers' info
+ * @adapter:	Adapter context
+ *
+ * Request function to get IBSS peer info from lower layers
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static
+QDF_STATUS hdd_cfg80211_get_ibss_peer_info_all(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+	unsigned long rc;
+
+	INIT_COMPLETION(adapter->ibss_peer_info_comp);
+
+	status = sme_request_ibss_peer_info(adapter->hdd_ctx->mac_handle,
+					    adapter,
+					    hdd_get_ibss_peer_info_cb,
+					    true, 0xFF);
+
+	if (QDF_STATUS_SUCCESS == status) {
+		rc = wait_for_completion_timeout
+			     (&adapter->ibss_peer_info_comp,
+			     msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
+
+		/* status will be 0 if timed out */
+		if (!rc) {
+			hdd_warn("Warning: IBSS_PEER_INFO_TIMEOUT");
+			status = QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		hdd_warn("Warning: sme_request_ibss_peer_info Request failed");
+	}
+
+	return status;
+}
+
+/**
+ * hdd_cfg80211_get_ibss_peer_info() - get ibss peer info
+ * @adapter:	Adapter context
+ * @staIdx:	Sta index for which the peer info is requested
+ *
+ * Request function to get IBSS peer info from lower layers
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static QDF_STATUS
+hdd_cfg80211_get_ibss_peer_info(struct hdd_adapter *adapter, uint8_t staIdx)
+{
+	unsigned long rc;
+	QDF_STATUS status;
+
+	INIT_COMPLETION(adapter->ibss_peer_info_comp);
+
+	status = sme_request_ibss_peer_info(adapter->hdd_ctx->mac_handle,
+					    adapter,
+					    hdd_get_ibss_peer_info_cb,
+					    false, staIdx);
+
+	if (QDF_STATUS_SUCCESS == status) {
+		rc = wait_for_completion_timeout(
+				&adapter->ibss_peer_info_comp,
+				msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
+
+		/* status = 0 on timeout */
+		if (!rc) {
+			hdd_warn("Warning: IBSS_PEER_INFO_TIMEOUT");
+			status = QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		hdd_warn("Warning: sme_request_ibss_peer_info Request failed");
+	}
+
+	return status;
+}
+
+/* Function header is left blank intentionally */
+static QDF_STATUS
+hdd_parse_get_ibss_peer_info(uint8_t *pValue, struct qdf_mac_addr *pPeerMacAddr)
+{
+	uint8_t *inPtr = pValue;
+	size_t in_ptr_len = strlen(pValue);
+
+	inPtr = strnchr(pValue, in_ptr_len, SPACE_ASCII_VALUE);
+
+	if (NULL == inPtr)
+		return QDF_STATUS_E_FAILURE;
+	else if (SPACE_ASCII_VALUE != *inPtr)
+		return QDF_STATUS_E_FAILURE;
+
+	while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr))
+		inPtr++;
+
+	if ('\0' == *inPtr)
+		return QDF_STATUS_E_FAILURE;
+
+	in_ptr_len -= (inPtr - pValue);
+	if (in_ptr_len < 17)
+		return QDF_STATUS_E_FAILURE;
+
+	if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
+	    inPtr[11] != ':' || inPtr[14] != ':')
+		return QDF_STATUS_E_FAILURE;
+
+	sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
+	       (unsigned int *)&pPeerMacAddr->bytes[0],
+	       (unsigned int *)&pPeerMacAddr->bytes[1],
+	       (unsigned int *)&pPeerMacAddr->bytes[2],
+	       (unsigned int *)&pPeerMacAddr->bytes[3],
+	       (unsigned int *)&pPeerMacAddr->bytes[4],
+	       (unsigned int *)&pPeerMacAddr->bytes[5]);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void hdd_get_band_helper(struct hdd_context *hdd_ctx, int *ui_band)
+{
+	enum band_info band = -1;
+
+	sme_get_freq_band(hdd_ctx->mac_handle, &band);
+	switch (band) {
+	case BAND_ALL:
+		*ui_band = WLAN_HDD_UI_BAND_AUTO;
+		break;
+
+	case BAND_2G:
+		*ui_band = WLAN_HDD_UI_BAND_2_4_GHZ;
+		break;
+
+	case BAND_5G:
+		*ui_band = WLAN_HDD_UI_BAND_5_GHZ;
+		break;
+
+	default:
+		hdd_warn("Invalid Band %d", band);
+		*ui_band = -1;
+		break;
+	}
+}
+
+/**
+ * _hdd_parse_bssid_and_chan() - helper function to parse bssid and channel
+ * @data:            input data
+ * @target_ap_bssid: pointer to bssid (output parameter)
+ * @channel:         pointer to channel (output parameter)
+ *
+ * Return: 0 if parsing is successful; -EINVAL otherwise
+ */
+static int _hdd_parse_bssid_and_chan(const uint8_t **data,
+				     uint8_t *bssid,
+				     uint8_t *channel)
+{
+	const uint8_t *in_ptr;
+	int            v = 0;
+	int            temp_int;
+	uint8_t        temp_buf[32];
+
+	/* 12 hexa decimal digits, 5 ':' and '\0' */
+	uint8_t        mac_addr[18];
+
+	if (!data || !*data)
+		return -EINVAL;
+
+	in_ptr = *data;
+
+	in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE);
+	/* no argument after the command */
+	if (NULL == in_ptr)
+		goto error;
+	/* no space after the command */
+	else if (SPACE_ASCII_VALUE != *in_ptr)
+		goto error;
+
+	/* remove empty spaces */
+	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
+		in_ptr++;
+
+	/* no argument followed by spaces */
+	if ('\0' == *in_ptr)
+		goto error;
+
+	v = sscanf(in_ptr, "%17s", mac_addr);
+	if (!((1 == v) && hdd_is_valid_mac_address(mac_addr))) {
+		hdd_err("Invalid MAC address or All hex inputs are not read (%d)",
+			 v);
+		goto error;
+	}
+
+	bssid[0] = hex_to_bin(mac_addr[0]) << 4 |
+			hex_to_bin(mac_addr[1]);
+	bssid[1] = hex_to_bin(mac_addr[3]) << 4 |
+			hex_to_bin(mac_addr[4]);
+	bssid[2] = hex_to_bin(mac_addr[6]) << 4 |
+			hex_to_bin(mac_addr[7]);
+	bssid[3] = hex_to_bin(mac_addr[9]) << 4 |
+			hex_to_bin(mac_addr[10]);
+	bssid[4] = hex_to_bin(mac_addr[12]) << 4 |
+			hex_to_bin(mac_addr[13]);
+	bssid[5] = hex_to_bin(mac_addr[15]) << 4 |
+			hex_to_bin(mac_addr[16]);
+
+	/* point to the next argument */
+	in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE);
+	/* no argument after the command */
+	if (NULL == in_ptr)
+		goto error;
+
+	/* remove empty spaces */
+	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
+		in_ptr++;
+
+	/* no argument followed by spaces */
+	if ('\0' == *in_ptr)
+		goto error;
+
+	/* get the next argument ie the channel number */
+	v = sscanf(in_ptr, "%31s ", temp_buf);
+	if (1 != v)
+		goto error;
+
+	v = kstrtos32(temp_buf, 10, &temp_int);
+	if ((v < 0) || (temp_int < 0) ||
+	    (temp_int > WNI_CFG_CURRENT_CHANNEL_STAMAX))
+		return -EINVAL;
+
+	*channel = temp_int;
+	*data = in_ptr;
+	return 0;
+error:
+	*data = in_ptr;
+	return -EINVAL;
+}
+
+/**
+ * hdd_parse_send_action_frame_data() - HDD Parse send action frame data
+ * @pValue:         Pointer to input data
+ * @pTargetApBssid: Pointer to target Ap bssid
+ * @pChannel:       Pointer to the Target AP channel
+ * @pDwellTime:     Pointer to the time to stay off-channel
+ *                  after transmitting action frame
+ * @pBuf:           Pointer to data
+ * @pBufLen:        Pointer to data length
+ *
+ * This function parses the send action frame data passed in the format
+ * SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int
+hdd_parse_send_action_frame_v1_data(const uint8_t *pValue,
+				    uint8_t *pTargetApBssid,
+				    uint8_t *pChannel, uint8_t *pDwellTime,
+				    uint8_t **pBuf, uint8_t *pBufLen)
+{
+	const uint8_t *inPtr = pValue;
+	const uint8_t *dataEnd;
+	int tempInt;
+	int j = 0;
+	int i = 0;
+	int v = 0;
+	uint8_t tempBuf[32];
+	uint8_t tempByte = 0;
+
+	if (_hdd_parse_bssid_and_chan(&inPtr, pTargetApBssid, pChannel))
+		return -EINVAL;
+
+	/* point to the next argument */
+	inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
+	/* no argument after the command */
+	if (NULL == inPtr)
+		return -EINVAL;
+	/* removing empty spaces */
+	while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr))
+		inPtr++;
+
+	/* no argument followed by spaces */
+	if ('\0' == *inPtr)
+		return -EINVAL;
+
+	/* getting the next argument ie the dwell time */
+	v = sscanf(inPtr, "%31s ", tempBuf);
+	if (1 != v)
+		return -EINVAL;
+
+	v = kstrtos32(tempBuf, 10, &tempInt);
+	if (v < 0 || tempInt < 0)
+		return -EINVAL;
+
+	*pDwellTime = tempInt;
+
+	/* point to the next argument */
+	inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
+	/* no argument after the command */
+	if (NULL == inPtr)
+		return -EINVAL;
+	/* removing empty spaces */
+	while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr))
+		inPtr++;
+
+	/* no argument followed by spaces */
+	if ('\0' == *inPtr)
+		return -EINVAL;
+
+	/* find the length of data */
+	dataEnd = inPtr;
+	while (('\0' != *dataEnd))
+		dataEnd++;
+
+	*pBufLen = dataEnd - inPtr;
+	if (*pBufLen <= 0)
+		return -EINVAL;
+
+	/*
+	 * Allocate the number of bytes based on the number of input characters
+	 * whether it is even or odd.
+	 * if the number of input characters are even, then we need N/2 byte.
+	 * if the number of input characters are odd, then we need do (N+1)/2
+	 * to compensate rounding off.
+	 * For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
+	 * If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes
+	 */
+	*pBuf = qdf_mem_malloc((*pBufLen + 1) / 2);
+	if (NULL == *pBuf) {
+		hdd_err("qdf_mem_malloc failed");
+		return -ENOMEM;
+	}
+
+	/* the buffer received from the upper layer is character buffer,
+	 * we need to prepare the buffer taking 2 characters in to a U8 hex
+	 * decimal number for example 7f0000f0...form a buffer to contain 7f
+	 * in 0th location, 00 in 1st and f0 in 3rd location
+	 */
+	for (i = 0, j = 0; j < *pBufLen; j += 2) {
+		if (j + 1 == *pBufLen) {
+			tempByte = hex_to_bin(inPtr[j]);
+		} else {
+			tempByte =
+				(hex_to_bin(inPtr[j]) << 4) |
+				(hex_to_bin(inPtr[j + 1]));
+		}
+		(*pBuf)[i++] = tempByte;
+	}
+	*pBufLen = i;
+	return 0;
+}
+
+/**
+ * hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
+ * @pValue:         Pointer to input data (its a NULL terminated string)
+ * @pTargetApBssid: Pointer to target Ap bssid
+ * @pChannel:       Pointer to the Target AP channel
+ *
+ * This function parses the reasoc command data passed in the format
+ * REASSOC<space><bssid><space><channel>
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int hdd_parse_reassoc_command_v1_data(const uint8_t *pValue,
+					     uint8_t *pTargetApBssid,
+					     uint8_t *pChannel)
+{
+	const uint8_t *inPtr = pValue;
+
+	if (_hdd_parse_bssid_and_chan(&inPtr, pTargetApBssid, pChannel))
+		return -EINVAL;
+
+	return 0;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS hdd_wma_send_fastreassoc_cmd(struct hdd_adapter *adapter,
+					const tSirMacAddr bssid,
+					int channel)
+{
+	struct hdd_station_ctx *hdd_sta_ctx =
+			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct csr_roam_profile *roam_profile;
+	tSirMacAddr connected_bssid;
+
+	roam_profile = hdd_roam_profile(adapter);
+	qdf_mem_copy(connected_bssid, hdd_sta_ctx->conn_info.bssId.bytes,
+		     ETH_ALEN);
+	return sme_fast_reassoc(adapter->hdd_ctx->mac_handle,
+				roam_profile, bssid, channel,
+				adapter->session_id, connected_bssid);
+}
+#endif
+
+/**
+ * hdd_reassoc() - perform a userspace-directed reassoc
+ * @adapter:    Adapter upon which the command was received
+ * @bssid:      BSSID with which to reassociate
+ * @channel:    channel upon which to reassociate
+ * @src:        The source for the trigger of this action
+ *
+ * This function performs a userspace-directed reassoc operation
+ *
+ * Return: 0 for success non-zero for failure
+ */
+int hdd_reassoc(struct hdd_adapter *adapter, const uint8_t *bssid,
+		uint8_t channel, const handoff_src src)
+{
+	struct hdd_station_ctx *sta_ctx;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int ret = 0;
+	QDF_STATUS status;
+
+	if (hdd_ctx == NULL) {
+		hdd_err("Invalid hdd ctx");
+		return -EINVAL;
+	}
+
+	if (QDF_STA_MODE != adapter->device_mode) {
+		hdd_warn("Unsupported in mode %s(%d)",
+			 qdf_opmode_str(adapter->device_mode),
+			 adapter->device_mode);
+		return -EINVAL;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	/*
+	 * pHddStaCtx->conn_info.connState is set to disconnected only
+	 * after the disconnect done indication from SME. If the SME is
+	 * in the process of disconnecting, the SME Connection state is
+	 * set to disconnected and the pHddStaCtx->conn_info.connState
+	 * will still be associated till the disconnect is done.
+	 * So check both the HDD state and SME state here.
+	 * If not associated, no need to proceed with reassoc
+	 */
+	if ((eConnectionState_Associated != sta_ctx->conn_info.connState) ||
+	    (!sme_is_conn_state_connected(hdd_ctx->mac_handle,
+	    adapter->session_id))) {
+		hdd_warn("Not associated");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/*
+	 * if the target bssid is same as currently associated AP,
+	 * use the current connections's channel.
+	 */
+	if (!memcmp(bssid, sta_ctx->conn_info.bssId.bytes,
+			QDF_MAC_ADDR_SIZE)) {
+		hdd_warn("Reassoc BSSID is same as currently associated AP bssid");
+		channel = sta_ctx->conn_info.operationChannel;
+	}
+
+	/* Check channel number is a valid channel number */
+	if (QDF_STATUS_SUCCESS !=
+	    wlan_hdd_validate_operation_channel(adapter, channel)) {
+		hdd_err("Invalid Channel: %d", channel);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Proceed with reassoc */
+	if (roaming_offload_enabled(hdd_ctx)) {
+		status = hdd_wma_send_fastreassoc_cmd(adapter,
+						 bssid, (int)channel);
+		if (status != QDF_STATUS_SUCCESS) {
+			hdd_err("Failed to send fast reassoc cmd");
+			ret = -EINVAL;
+		}
+	} else {
+		tCsrHandoffRequest handoff;
+
+		handoff.channel = channel;
+		handoff.src = src;
+		qdf_mem_copy(handoff.bssid.bytes, bssid, QDF_MAC_ADDR_SIZE);
+		sme_handoff_request(hdd_ctx->mac_handle, adapter->session_id,
+				    &handoff);
+	}
+exit:
+	return ret;
+}
+
+/**
+ * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
+ * @adapter:	Adapter upon which the command was received
+ * @command:	ASCII text command that was received
+ *
+ * This function parses the v1 REASSOC command with the format
+ *
+ *    REASSOC xx:xx:xx:xx:xx:xx CH
+ *
+ * Where "xx:xx:xx:xx:xx:xx" is the Hex-ASCII representation of the
+ * BSSID and CH is the ASCII representation of the channel.  For
+ * example
+ *
+ *    REASSOC 00:0a:0b:11:22:33 48
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int hdd_parse_reassoc_v1(struct hdd_adapter *adapter, const char *command)
+{
+	uint8_t channel = 0;
+	tSirMacAddr bssid;
+	int ret;
+
+	ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
+	if (ret)
+		hdd_err("Failed to parse reassoc command data");
+	else
+		ret = hdd_reassoc(adapter, bssid, channel, REASSOC);
+
+	return ret;
+}
+
+/**
+ * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
+ * @adapter:	Adapter upon which the command was received
+ * @command:	Command that was received, ASCII command
+ *		followed by binary data
+ * @total_len:  Total length of the command received
+ *
+ * This function parses the v2 REASSOC command with the format
+ *
+ *    REASSOC <android_wifi_reassoc_params>
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int hdd_parse_reassoc_v2(struct hdd_adapter *adapter,
+				const char *command,
+				int total_len)
+{
+	struct android_wifi_reassoc_params params;
+	tSirMacAddr bssid;
+	int ret;
+
+	if (total_len < sizeof(params) + 8) {
+		hdd_err("Invalid command length");
+		return -EINVAL;
+	}
+
+	/* The params are located after "REASSOC " */
+	memcpy(&params, command + 8, sizeof(params));
+
+	if (!mac_pton(params.bssid, (u8 *) &bssid)) {
+		hdd_err("MAC address parsing failed");
+		ret = -EINVAL;
+	} else {
+		ret = hdd_reassoc(adapter, bssid, params.channel, REASSOC);
+	}
+	return ret;
+}
+
+/**
+ * hdd_parse_reassoc() - parse the REASSOC command
+ * @adapter:	Adapter upon which the command was received
+ * @command:	Command that was received
+ * @total_len:  Total length of the command received
+ *
+ * There are two different versions of the REASSOC command.  Version 1
+ * of the command contains a parameter list that is ASCII characters
+ * whereas version 2 contains a combination of ASCII and binary
+ * payload.  Determine if a version 1 or a version 2 command is being
+ * parsed by examining the parameters, and then dispatch the parser
+ * that is appropriate for the command.
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int hdd_parse_reassoc(struct hdd_adapter *adapter, const char *command,
+			     int total_len)
+{
+	int ret;
+
+	/* both versions start with "REASSOC "
+	 * v1 has a bssid and channel # as an ASCII string
+	 *    REASSOC xx:xx:xx:xx:xx:xx CH
+	 * v2 has a C struct
+	 *    REASSOC <binary c struct>
+	 *
+	 * The first field in the v2 struct is also the bssid in ASCII.
+	 * But in the case of a v2 message the BSSID is NUL-terminated.
+	 * Hence we can peek at that offset to see if this is V1 or V2
+	 * REASSOC xx:xx:xx:xx:xx:xx*
+	 *           1111111111222222
+	 * 01234567890123456789012345
+	 */
+
+	if (total_len < 26) {
+		hdd_err("Invalid command, total_len = %d", total_len);
+		return -EINVAL;
+	}
+
+	if (command[25])
+		ret = hdd_parse_reassoc_v1(adapter, command);
+	else
+		ret = hdd_parse_reassoc_v2(adapter, command, total_len);
+
+	return ret;
+}
+
+/**
+ * hdd_sendactionframe() - send a userspace-supplied action frame
+ * @adapter:	Adapter upon which the command was received
+ * @bssid:	BSSID target of the action frame
+ * @channel:	Channel upon which to send the frame
+ * @dwell_time:	Amount of time to dwell when the frame is sent
+ * @payload_len:Length of the payload
+ * @payload:	Payload of the frame
+ *
+ * This function sends a userspace-supplied action frame
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int
+hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid,
+		    const uint8_t channel, const uint8_t dwell_time,
+		    const int payload_len, const uint8_t *payload)
+{
+	struct ieee80211_channel chan;
+	int frame_len, ret = 0;
+	uint8_t *frame;
+	struct ieee80211_hdr_3addr *hdr;
+	u64 cookie;
+	struct hdd_station_ctx *sta_ctx;
+	struct hdd_context *hdd_ctx;
+	tpSirMacVendorSpecificFrameHdr pVendorSpecific =
+		(tpSirMacVendorSpecificFrameHdr) payload;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+	struct cfg80211_mgmt_tx_params params;
+#endif
+
+	if (QDF_STA_MODE != adapter->device_mode) {
+		hdd_warn("Unsupported in mode %s(%d)",
+			 qdf_opmode_str(adapter->device_mode),
+			 adapter->device_mode);
+		return -EINVAL;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	/* if not associated, no need to send action frame */
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		hdd_warn("Not associated");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/*
+	 * if the target bssid is different from currently associated AP,
+	 * then no need to send action frame
+	 */
+	if (memcmp(bssid, sta_ctx->conn_info.bssId.bytes,
+			QDF_MAC_ADDR_SIZE)) {
+		hdd_warn("STA is not associated to this AP");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	chan.center_freq = sme_chn_to_freq(channel);
+	/* Check if it is specific action frame */
+	if (pVendorSpecific->category ==
+	    SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY) {
+		static const uint8_t Oui[] = { 0x00, 0x00, 0xf0 };
+
+		if (!qdf_mem_cmp(pVendorSpecific->Oui, (void *)Oui, 3)) {
+			/*
+			 * if the channel number is different from operating
+			 * channel then no need to send action frame
+			 */
+			if (channel != 0) {
+				if (channel !=
+				    sta_ctx->conn_info.operationChannel) {
+					hdd_warn("channel(%d) is different from operating channel(%d)",
+						  channel,
+						  sta_ctx->conn_info.
+						  operationChannel);
+					ret = -EINVAL;
+					goto exit;
+				}
+				/*
+				 * If channel number is specified and same
+				 * as home channel, ensure that action frame
+				 * is sent immediately by cancelling
+				 * roaming scans. Otherwise large dwell times
+				 * may cause long delays in sending action
+				 * frames.
+				 */
+				sme_abort_roam_scan(hdd_ctx->mac_handle,
+						    adapter->session_id);
+			} else {
+				/*
+				 * 0 is accepted as current home channel,
+				 * delayed transmission of action frame is ok.
+				 */
+				chan.center_freq =
+					sme_chn_to_freq(sta_ctx->conn_info.
+							operationChannel);
+			}
+		}
+	}
+	if (chan.center_freq == 0) {
+		hdd_err("Invalid channel number: %d", channel);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	frame_len = payload_len + 24;
+	frame = qdf_mem_malloc(frame_len);
+	if (!frame) {
+		hdd_err("memory allocation failed");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	hdr = (struct ieee80211_hdr_3addr *)frame;
+	hdr->frame_control =
+		cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
+	qdf_mem_copy(hdr->addr1, bssid, QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(hdr->addr2, adapter->mac_addr.bytes,
+		     QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(hdr->addr3, bssid, QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(hdr + 1, payload, payload_len);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+	params.chan = &chan;
+	params.offchan = 0;
+	params.wait = dwell_time;
+	params.buf = frame;
+	params.len = frame_len;
+	params.no_cck = 1;
+	params.dont_wait_for_ack = 1;
+	ret = wlan_hdd_mgmt_tx(NULL, &adapter->wdev, &params, &cookie);
+#else
+	ret = wlan_hdd_mgmt_tx(NULL,
+			       &(adapter->wdev),
+			       &chan, 0,
+
+			       dwell_time, frame, frame_len, 1, 1, &cookie);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
+
+	qdf_mem_free(frame);
+exit:
+	return ret;
+}
+
+/**
+ * hdd_parse_sendactionframe_v1() - parse version 1 of the
+ *       SENDACTIONFRAME command
+ * @adapter:	Adapter upon which the command was received
+ * @command:	ASCII text command that was received
+ *
+ * This function parses the v1 SENDACTIONFRAME command with the format
+ *
+ *    SENDACTIONFRAME xx:xx:xx:xx:xx:xx CH DW xxxxxx
+ *
+ * Where "xx:xx:xx:xx:xx:xx" is the Hex-ASCII representation of the
+ * BSSID, CH is the ASCII representation of the channel, DW is the
+ * ASCII representation of the dwell time, and xxxxxx is the Hex-ASCII
+ * payload.  For example
+ *
+ *    SENDACTIONFRAME 00:0a:0b:11:22:33 48 40 aabbccddee
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int
+hdd_parse_sendactionframe_v1(struct hdd_adapter *adapter, const char *command)
+{
+	uint8_t channel = 0;
+	uint8_t dwell_time = 0;
+	uint8_t payload_len = 0;
+	uint8_t *payload = NULL;
+	tSirMacAddr bssid;
+	int ret;
+
+	ret = hdd_parse_send_action_frame_v1_data(command, bssid, &channel,
+						  &dwell_time, &payload,
+						  &payload_len);
+	if (ret) {
+		hdd_err("Failed to parse send action frame data");
+	} else {
+		ret = hdd_sendactionframe(adapter, bssid, channel,
+					  dwell_time, payload_len, payload);
+		qdf_mem_free(payload);
+	}
+
+	return ret;
+}
+
+/**
+ * hdd_parse_sendactionframe_v2() - parse version 2 of the
+ *       SENDACTIONFRAME command
+ * @adapter:	Adapter upon which the command was received
+ * @command:	Command that was received, ASCII command
+ *		followed by binary data
+ *
+ * This function parses the v2 SENDACTIONFRAME command with the format
+ *
+ *    SENDACTIONFRAME <android_wifi_af_params>
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int
+hdd_parse_sendactionframe_v2(struct hdd_adapter *adapter,
+			     const char *command, int total_len)
+{
+	struct android_wifi_af_params *params;
+	tSirMacAddr bssid;
+	int ret;
+	int len_wo_payload = 0;
+
+	/* The params are located after "SENDACTIONFRAME " */
+	total_len -= 16;
+	len_wo_payload = sizeof(*params) - ANDROID_WIFI_ACTION_FRAME_SIZE;
+	if (total_len <= len_wo_payload) {
+		hdd_err("Invalid command len");
+		return -EINVAL;
+	}
+
+	params = (struct android_wifi_af_params *)(command + 16);
+
+	if (params->len <= 0 || params->len > ANDROID_WIFI_ACTION_FRAME_SIZE ||
+		(params->len > (total_len - len_wo_payload))) {
+		hdd_err("Invalid payload length: %d", params->len);
+		return -EINVAL;
+	}
+
+	if (!mac_pton(params->bssid, (u8 *)&bssid)) {
+		hdd_err("MAC address parsing failed");
+		return -EINVAL;
+	}
+
+	if (params->channel < 0 ||
+	    params->channel > WNI_CFG_CURRENT_CHANNEL_STAMAX) {
+		hdd_err("Invalid channel: %d", params->channel);
+		return -EINVAL;
+	}
+
+	if (params->dwell_time < 0) {
+		hdd_err("Invalid dwell_time: %d", params->dwell_time);
+		return -EINVAL;
+	}
+
+	ret = hdd_sendactionframe(adapter, bssid, params->channel,
+				params->dwell_time, params->len, params->data);
+
+	return ret;
+}
+
+/**
+ * hdd_parse_sendactionframe() - parse the SENDACTIONFRAME command
+ * @adapter:	Adapter upon which the command was received
+ * @command:	Command that was received
+ *
+ * There are two different versions of the SENDACTIONFRAME command.
+ * Version 1 of the command contains a parameter list that is ASCII
+ * characters whereas version 2 contains a combination of ASCII and
+ * binary payload.  Determine if a version 1 or a version 2 command is
+ * being parsed by examining the parameters, and then dispatch the
+ * parser that is appropriate for the version of the command.
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int
+hdd_parse_sendactionframe(struct hdd_adapter *adapter, const char *command,
+			  int total_len)
+{
+	int ret;
+
+	/*
+	 * both versions start with "SENDACTIONFRAME "
+	 * v1 has a bssid and other parameters as an ASCII string
+	 *    SENDACTIONFRAME xx:xx:xx:xx:xx:xx CH DWELL LEN FRAME
+	 * v2 has a C struct
+	 *    SENDACTIONFRAME <binary c struct>
+	 *
+	 * The first field in the v2 struct is also the bssid in ASCII.
+	 * But in the case of a v2 message the BSSID is NUL-terminated.
+	 * Hence we can peek at that offset to see if this is V1 or V2
+	 * SENDACTIONFRAME xx:xx:xx:xx:xx:xx*
+	 *           111111111122222222223333
+	 * 0123456789012345678901234567890123
+	 * For both the commands, a valid command must have atleast
+	 * first 34 length of data.
+	 */
+	if (total_len < 34) {
+		hdd_err("Invalid command (total_len=%d)", total_len);
+		return -EINVAL;
+	}
+
+	if (command[33])
+		ret = hdd_parse_sendactionframe_v1(adapter, command);
+	else
+		ret = hdd_parse_sendactionframe_v2(adapter, command, total_len);
+
+	return ret;
+}
+
+/**
+ * hdd_parse_channellist() - HDD Parse channel list
+ * @pValue:		Pointer to input channel list
+ * @ChannelList:	Pointer to local output array to record
+ *			channel list
+ * @pNumChannels:	Pointer to number of roam scan channels
+ *
+ * This function parses the channel list passed in the format
+ * SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>
+ * Channel 2<space>Channel N
+ * if the Number of channels (N) does not match with the actual number
+ * of channels passed then take the minimum of N and count of
+ * (Ch1, Ch2, ...Ch M). For example, if SETROAMSCANCHANNELS 3 36 40 44 48,
+ * only 36, 40 and 44 shall be taken. If SETROAMSCANCHANNELS 5 36 40 44 48,
+ * ignore 5 and take 36, 40, 44 and 48. This function does not take care of
+ * removing duplicate channels from the list
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int
+hdd_parse_channellist(const uint8_t *pValue, uint8_t *pChannelList,
+		      uint8_t *pNumChannels)
+{
+	const uint8_t *inPtr = pValue;
+	int tempInt;
+	int j = 0;
+	int v = 0;
+	char buf[32];
+
+	inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+	/* no argument after the command */
+	if (NULL == inPtr)
+		return -EINVAL;
+	else if (SPACE_ASCII_VALUE != *inPtr) /* no space after the command */
+		return -EINVAL;
+
+	/* remove empty spaces */
+	while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr))
+		inPtr++;
+
+	/* no argument followed by spaces */
+	if ('\0' == *inPtr)
+		return -EINVAL;
+
+	/* get the first argument ie the number of channels */
+	v = sscanf(inPtr, "%31s ", buf);
+	if (1 != v)
+		return -EINVAL;
+
+	v = kstrtos32(buf, 10, &tempInt);
+	if ((v < 0) ||
+	    (tempInt <= 0) || (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
+		return -EINVAL;
+
+	*pNumChannels = tempInt;
+
+	hdd_debug("Number of channels are: %d", *pNumChannels);
+
+	for (j = 0; j < (*pNumChannels); j++) {
+		/*
+		 * inPtr pointing to the beginning of first space after number
+		 * of channels
+		 */
+		inPtr = strpbrk(inPtr, " ");
+		/* no channel list after the number of channels argument */
+		if (NULL == inPtr) {
+			if (0 != j) {
+				*pNumChannels = j;
+				return 0;
+			} else {
+				return -EINVAL;
+			}
+		}
+
+		/* remove empty space */
+		while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr))
+			inPtr++;
+
+		/*
+		 * no channel list after the number of channels
+		 * argument and spaces
+		 */
+		if ('\0' == *inPtr) {
+			if (0 != j) {
+				*pNumChannels = j;
+				return 0;
+			} else {
+				return -EINVAL;
+			}
+		}
+
+		v = sscanf(inPtr, "%31s ", buf);
+		if (1 != v)
+			return -EINVAL;
+
+		v = kstrtos32(buf, 10, &tempInt);
+		if ((v < 0) ||
+		    (tempInt <= 0) ||
+		    (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX)) {
+			return -EINVAL;
+		}
+		pChannelList[j] = tempInt;
+
+		hdd_debug("Channel %d added to preferred channel list",
+			  pChannelList[j]);
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_parse_set_roam_scan_channels_v1() - parse version 1 of the
+ * SETROAMSCANCHANNELS command
+ * @adapter:	Adapter upon which the command was received
+ * @command:	ASCII text command that was received
+ *
+ * This function parses the v1 SETROAMSCANCHANNELS command with the format
+ *
+ *    SETROAMSCANCHANNELS N C1 C2 ... Cn
+ *
+ * Where "N" is the ASCII representation of the number of channels and
+ * C1 thru Cn is the ASCII representation of the channels.  For example
+ *
+ *    SETROAMSCANCHANNELS 4 36 40 44 48
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int
+hdd_parse_set_roam_scan_channels_v1(struct hdd_adapter *adapter,
+				    const char *command)
+{
+	uint8_t channel_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
+	uint8_t num_chan = 0;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int ret;
+	mac_handle_t mac_handle;
+
+	ret = hdd_parse_channellist(command, channel_list, &num_chan);
+	if (ret) {
+		hdd_err("Failed to parse channel list information");
+		goto exit;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
+			 adapter->session_id, num_chan));
+
+	if (num_chan > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		hdd_err("number of channels (%d) supported exceeded max (%d)",
+			 num_chan, WNI_CFG_VALID_CHANNEL_LIST_LEN);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!sme_validate_channel_list(mac_handle, channel_list, num_chan)) {
+		hdd_err("List contains invalid channel(s)");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	status = sme_change_roam_scan_channel_list(mac_handle,
+						   adapter->session_id,
+						   channel_list, num_chan);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Failed to update channel list information");
+		ret = -EINVAL;
+		goto exit;
+	}
+exit:
+	return ret;
+}
+
+/**
+ * hdd_parse_set_roam_scan_channels_v2() - parse version 2 of the
+ * SETROAMSCANCHANNELS command
+ * @adapter:	Adapter upon which the command was received
+ * @command:	Command that was received, ASCII command
+ *		followed by binary data
+ *
+ * This function parses the v2 SETROAMSCANCHANNELS command with the format
+ *
+ *    SETROAMSCANCHANNELS [N][C1][C2][Cn]
+ *
+ * The command begins with SETROAMSCANCHANNELS followed by a space, but
+ * what follows the space is an array of u08 parameters.  For example
+ *
+ *    SETROAMSCANCHANNELS [0x04 0x24 0x28 0x2c 0x30]
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int
+hdd_parse_set_roam_scan_channels_v2(struct hdd_adapter *adapter,
+				    const char *command)
+{
+	const uint8_t *value;
+	uint8_t channel_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
+	uint8_t channel;
+	uint8_t num_chan;
+	int i;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	QDF_STATUS status;
+	int ret = 0;
+	mac_handle_t mac_handle;
+
+	/* array of values begins after "SETROAMSCANCHANNELS " */
+	value = command + 20;
+
+	num_chan = *value++;
+	if (num_chan > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		hdd_err("number of channels (%d) supported exceeded max (%d)",
+			  num_chan, WNI_CFG_VALID_CHANNEL_LIST_LEN);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
+			 adapter->session_id, num_chan));
+
+	for (i = 0; i < num_chan; i++) {
+		channel = *value++;
+		if (!channel) {
+			hdd_err("Channels end at index %d, expected %d",
+				i, num_chan);
+			ret = -EINVAL;
+			goto exit;
+		}
+
+		if (channel > WNI_CFG_CURRENT_CHANNEL_STAMAX) {
+			hdd_err("index %d invalid channel %d",
+				  i, channel);
+			ret = -EINVAL;
+			goto exit;
+		}
+		channel_list[i] = channel;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!sme_validate_channel_list(mac_handle, channel_list, num_chan)) {
+		hdd_err("List contains invalid channel(s)");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	status = sme_change_roam_scan_channel_list(mac_handle,
+						   adapter->session_id,
+						   channel_list, num_chan);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Failed to update channel list information");
+		ret = -EINVAL;
+		goto exit;
+	}
+exit:
+	return ret;
+}
+
+/**
+ * hdd_parse_set_roam_scan_channels() - parse the
+ * SETROAMSCANCHANNELS command
+ * @adapter:	Adapter upon which the command was received
+ * @command:	Command that was received
+ *
+ * There are two different versions of the SETROAMSCANCHANNELS command.
+ * Version 1 of the command contains a parameter list that is ASCII
+ * characters whereas version 2 contains a binary payload.  Determine
+ * if a version 1 or a version 2 command is being parsed by examining
+ * the parameters, and then dispatch the parser that is appropriate for
+ * the command.
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int
+hdd_parse_set_roam_scan_channels(struct hdd_adapter *adapter, const char *command)
+{
+	const char *cursor;
+	char ch;
+	bool v1;
+	int ret;
+
+	/* start after "SETROAMSCANCHANNELS " */
+	cursor = command + 20;
+
+	/* assume we have a version 1 command until proven otherwise */
+	v1 = true;
+
+	/* v1 params will only contain ASCII digits and space */
+	while ((ch = *cursor++) && v1) {
+		if (!(isdigit(ch) || isspace(ch)))
+			v1 = false;
+	}
+
+	if (v1)
+		ret = hdd_parse_set_roam_scan_channels_v1(adapter, command);
+	else
+		ret = hdd_parse_set_roam_scan_channels_v2(adapter, command);
+
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * hdd_parse_plm_cmd() - HDD Parse Plm command
+ * @pValue:	Pointer to input data
+ * @pPlmRequest:Pointer to output struct tpSirPlmReq
+ *
+ * This function parses the plm command passed in the format
+ * CCXPLMREQ<space><enable><space><dialog_token><space>
+ * <meas_token><space><num_of_bursts><space><burst_int><space>
+ * <measu duration><space><burst_len><space><desired_tx_pwr>
+ * <space><multcast_addr><space><number_of_channels>
+ * <space><channel_numbers>
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static QDF_STATUS hdd_parse_plm_cmd(uint8_t *pValue, tSirPlmReq *pPlmRequest)
+{
+	uint8_t *cmdPtr = NULL;
+	int count, content = 0, ret = 0;
+	char buf[32];
+
+	/* move to argument list */
+	cmdPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+	if (NULL == cmdPtr)
+		return QDF_STATUS_E_FAILURE;
+
+	/* no space after the command */
+	if (SPACE_ASCII_VALUE != *cmdPtr)
+		return QDF_STATUS_E_FAILURE;
+
+	/* remove empty spaces */
+	while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr))
+		cmdPtr++;
+
+	/* START/STOP PLM req */
+	ret = sscanf(cmdPtr, "%31s ", buf);
+	if (1 != ret)
+		return QDF_STATUS_E_FAILURE;
+
+	ret = kstrtos32(buf, 10, &content);
+	if (ret < 0)
+		return QDF_STATUS_E_FAILURE;
+
+	pPlmRequest->enable = content;
+	cmdPtr = strpbrk(cmdPtr, " ");
+
+	if (NULL == cmdPtr)
+		return QDF_STATUS_E_FAILURE;
+
+	/* remove empty spaces */
+	while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr))
+		cmdPtr++;
+
+	/* Dialog token of radio meas req containing meas reqIE */
+	ret = sscanf(cmdPtr, "%31s ", buf);
+	if (1 != ret)
+		return QDF_STATUS_E_FAILURE;
+
+	ret = kstrtos32(buf, 10, &content);
+	if (ret < 0)
+		return QDF_STATUS_E_FAILURE;
+
+	pPlmRequest->diag_token = content;
+	hdd_debug("diag token %d", pPlmRequest->diag_token);
+	cmdPtr = strpbrk(cmdPtr, " ");
+
+	if (NULL == cmdPtr)
+		return QDF_STATUS_E_FAILURE;
+
+	/* remove empty spaces */
+	while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr))
+		cmdPtr++;
+
+	/* measurement token of meas req IE */
+	ret = sscanf(cmdPtr, "%31s ", buf);
+	if (1 != ret)
+		return QDF_STATUS_E_FAILURE;
+
+	ret = kstrtos32(buf, 10, &content);
+	if (ret < 0)
+		return QDF_STATUS_E_FAILURE;
+
+	pPlmRequest->meas_token = content;
+	hdd_debug("meas token %d", pPlmRequest->meas_token);
+
+	hdd_debug("PLM req %s", pPlmRequest->enable ? "START" : "STOP");
+	if (pPlmRequest->enable) {
+
+		cmdPtr = strpbrk(cmdPtr, " ");
+
+		if (NULL == cmdPtr)
+			return QDF_STATUS_E_FAILURE;
+
+		/* remove empty spaces */
+		while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr))
+			cmdPtr++;
+
+		/* total number of bursts after which STA stops sending */
+		ret = sscanf(cmdPtr, "%31s ", buf);
+		if (1 != ret)
+			return QDF_STATUS_E_FAILURE;
+
+		ret = kstrtos32(buf, 10, &content);
+		if (ret < 0)
+			return QDF_STATUS_E_FAILURE;
+
+		if (content < 0)
+			return QDF_STATUS_E_FAILURE;
+
+		pPlmRequest->numBursts = content;
+		hdd_debug("num burst %d", pPlmRequest->numBursts);
+		cmdPtr = strpbrk(cmdPtr, " ");
+
+		if (NULL == cmdPtr)
+			return QDF_STATUS_E_FAILURE;
+
+		/* remove empty spaces */
+		while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr))
+			cmdPtr++;
+
+		/* burst interval in seconds */
+		ret = sscanf(cmdPtr, "%31s ", buf);
+		if (1 != ret)
+			return QDF_STATUS_E_FAILURE;
+
+		ret = kstrtos32(buf, 10, &content);
+		if (ret < 0)
+			return QDF_STATUS_E_FAILURE;
+
+		if (content <= 0)
+			return QDF_STATUS_E_FAILURE;
+
+		pPlmRequest->burstInt = content;
+		hdd_debug("burst Int %d", pPlmRequest->burstInt);
+		cmdPtr = strpbrk(cmdPtr, " ");
+
+		if (NULL == cmdPtr)
+			return QDF_STATUS_E_FAILURE;
+
+		/* remove empty spaces */
+		while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr))
+			cmdPtr++;
+
+		/* Meas dur in TU's,STA goes off-ch and transmit PLM bursts */
+		ret = sscanf(cmdPtr, "%31s ", buf);
+		if (1 != ret)
+			return QDF_STATUS_E_FAILURE;
+
+		ret = kstrtos32(buf, 10, &content);
+		if (ret < 0)
+			return QDF_STATUS_E_FAILURE;
+
+		if (content <= 0)
+			return QDF_STATUS_E_FAILURE;
+
+		pPlmRequest->measDuration = content;
+		hdd_debug("measDur %d", pPlmRequest->measDuration);
+		cmdPtr = strpbrk(cmdPtr, " ");
+
+		if (NULL == cmdPtr)
+			return QDF_STATUS_E_FAILURE;
+
+		/* remove empty spaces */
+		while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr))
+			cmdPtr++;
+
+		/* burst length of PLM bursts */
+		ret = sscanf(cmdPtr, "%31s ", buf);
+		if (1 != ret)
+			return QDF_STATUS_E_FAILURE;
+
+		ret = kstrtos32(buf, 10, &content);
+		if (ret < 0)
+			return QDF_STATUS_E_FAILURE;
+
+		if (content <= 0)
+			return QDF_STATUS_E_FAILURE;
+
+		pPlmRequest->burstLen = content;
+		hdd_debug("burstLen %d", pPlmRequest->burstLen);
+		cmdPtr = strpbrk(cmdPtr, " ");
+
+		if (NULL == cmdPtr)
+			return QDF_STATUS_E_FAILURE;
+
+		/* remove empty spaces */
+		while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr))
+			cmdPtr++;
+
+		/* desired tx power for transmission of PLM bursts */
+		ret = sscanf(cmdPtr, "%31s ", buf);
+		if (1 != ret)
+			return QDF_STATUS_E_FAILURE;
+
+		ret = kstrtos32(buf, 10, &content);
+		if (ret < 0)
+			return QDF_STATUS_E_FAILURE;
+
+		if (content <= 0)
+			return QDF_STATUS_E_FAILURE;
+
+		pPlmRequest->desiredTxPwr = content;
+		hdd_debug("desiredTxPwr %d",
+			   pPlmRequest->desiredTxPwr);
+
+		for (count = 0; count < QDF_MAC_ADDR_SIZE; count++) {
+			cmdPtr = strpbrk(cmdPtr, " ");
+
+			if (NULL == cmdPtr)
+				return QDF_STATUS_E_FAILURE;
+
+			/* remove empty spaces */
+			while ((SPACE_ASCII_VALUE == *cmdPtr)
+			       && ('\0' != *cmdPtr))
+				cmdPtr++;
+
+			ret = sscanf(cmdPtr, "%31s ", buf);
+			if (1 != ret)
+				return QDF_STATUS_E_FAILURE;
+
+			ret = kstrtos32(buf, 16, &content);
+			if (ret < 0)
+				return QDF_STATUS_E_FAILURE;
+
+			pPlmRequest->mac_addr.bytes[count] = content;
+		}
+
+		hdd_debug("MC addr " MAC_ADDRESS_STR,
+		       MAC_ADDR_ARRAY(pPlmRequest->mac_addr.bytes));
+
+		cmdPtr = strpbrk(cmdPtr, " ");
+
+		if (NULL == cmdPtr)
+			return QDF_STATUS_E_FAILURE;
+
+		/* remove empty spaces */
+		while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr))
+			cmdPtr++;
+
+		/* number of channels */
+		ret = sscanf(cmdPtr, "%31s ", buf);
+		if (1 != ret)
+			return QDF_STATUS_E_FAILURE;
+
+		ret = kstrtos32(buf, 10, &content);
+		if (ret < 0)
+			return QDF_STATUS_E_FAILURE;
+
+		if (content < 0)
+			return QDF_STATUS_E_FAILURE;
+
+		content = QDF_MIN(content, WNI_CFG_VALID_CHANNEL_LIST_LEN);
+		pPlmRequest->plmNumCh = content;
+		hdd_debug("numch: %d", pPlmRequest->plmNumCh);
+
+		/* Channel numbers */
+		for (count = 0; count < pPlmRequest->plmNumCh; count++) {
+			cmdPtr = strpbrk(cmdPtr, " ");
+
+			if (NULL == cmdPtr)
+				return QDF_STATUS_E_FAILURE;
+
+			/* remove empty spaces */
+			while ((SPACE_ASCII_VALUE == *cmdPtr)
+			       && ('\0' != *cmdPtr))
+				cmdPtr++;
+
+			ret = sscanf(cmdPtr, "%31s ", buf);
+			if (1 != ret)
+				return QDF_STATUS_E_FAILURE;
+
+			ret = kstrtos32(buf, 10, &content);
+			if (ret < 0 || content <= 0 ||
+			    content > WNI_CFG_CURRENT_CHANNEL_STAMAX)
+				return QDF_STATUS_E_FAILURE;
+
+			pPlmRequest->plmChList[count] = content;
+			hdd_debug(" ch- %d", pPlmRequest->plmChList[count]);
+		}
+	}
+	/* If PLM START */
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+/**
+ * wlan_hdd_ready_to_extwow() - Callback function for enable ext wow
+ * @cookie: callback context
+ * @is_success: suspend status of ext wow
+ *
+ * Return: none
+ */
+static void wlan_hdd_ready_to_extwow(void *cookie, bool is_success)
+{
+	struct osif_request *request = NULL;
+	struct enable_ext_wow_priv *priv = NULL;
+
+	request = osif_request_get(cookie);
+	if (!request) {
+		hdd_err("Obselete request");
+		return;
+	}
+	priv = osif_request_priv(request);
+	priv->ext_wow_should_suspend = is_success;
+
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+static int hdd_enable_ext_wow(struct hdd_adapter *adapter,
+			      tpSirExtWoWParams arg_params)
+{
+	tSirExtWoWParams params;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int rc;
+	struct enable_ext_wow_priv *priv = NULL;
+	struct osif_request *request = NULL;
+	void *cookie = NULL;
+	struct osif_request_params hdd_params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_READY_TO_EXTWOW,
+	};
+
+	qdf_mem_copy(&params, arg_params, sizeof(params));
+
+	request = osif_request_alloc(&hdd_params);
+	if (!request) {
+		hdd_err("Request Allocation Failure");
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	status = sme_configure_ext_wow(hdd_ctx->mac_handle, &params,
+				       &wlan_hdd_ready_to_extwow,
+				       cookie);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("sme_configure_ext_wow returned failure %d",
+			 status);
+		rc = -EPERM;
+		goto exit;
+	}
+
+	rc = osif_request_wait_for_response(request);
+	if (rc) {
+		hdd_err("Failed to get ready to extwow");
+		rc = -EPERM;
+		goto exit;
+	}
+
+	priv = osif_request_priv(request);
+	if (!priv->ext_wow_should_suspend) {
+		hdd_err("Received ready to ExtWoW failure");
+		rc = -EPERM;
+		goto exit;
+	}
+
+	if (ucfg_pmo_extwow_is_goto_suspend_enabled(hdd_ctx->psoc)) {
+		hdd_info("Received ready to ExtWoW. Going to suspend");
+
+		rc = wlan_hdd_cfg80211_suspend_wlan(hdd_ctx->wiphy, NULL);
+		if (rc < 0) {
+			hdd_err("wlan_hdd_cfg80211_suspend_wlan failed, error = %d",
+				rc);
+			goto exit;
+		}
+		rc = wlan_hdd_bus_suspend();
+		if (rc) {
+			hdd_err("wlan_hdd_bus_suspend failed, status = %d",
+				rc);
+			wlan_hdd_cfg80211_resume_wlan(hdd_ctx->wiphy);
+			goto exit;
+		}
+	}
+
+exit:
+	osif_request_put(request);
+	return rc;
+}
+
+static int hdd_enable_ext_wow_parser(struct hdd_adapter *adapter, int vdev_id,
+				     int value)
+{
+	tSirExtWoWParams params;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int rc;
+	uint8_t pin1, pin2;
+
+	rc = wlan_hdd_validate_context(hdd_ctx);
+	if (rc)
+		return rc;
+
+	if (value < EXT_WOW_TYPE_APP_TYPE1 ||
+	    value > EXT_WOW_TYPE_APP_TYPE1_2) {
+		hdd_err("Invalid type: %d", value);
+		return -EINVAL;
+	}
+
+	if (value == EXT_WOW_TYPE_APP_TYPE1 &&
+	    hdd_ctx->is_extwow_app_type1_param_set)
+		params.type = value;
+	else if (value == EXT_WOW_TYPE_APP_TYPE2 &&
+		 hdd_ctx->is_extwow_app_type2_param_set)
+		params.type = value;
+	else if (value == EXT_WOW_TYPE_APP_TYPE1_2 &&
+		 hdd_ctx->is_extwow_app_type1_param_set &&
+		 hdd_ctx->is_extwow_app_type2_param_set)
+		params.type = value;
+	else {
+		hdd_err("Set app params before enable it value %d",
+			 value);
+		return -EINVAL;
+	}
+
+	params.vdev_id = vdev_id;
+	pin1 = ucfg_pmo_extwow_app1_wakeup_pin_num(hdd_ctx->psoc);
+	pin2 = ucfg_pmo_extwow_app2_wakeup_pin_num(hdd_ctx->psoc);
+	params.wakeup_pin_num = pin1 | (pin2 << 8);
+
+	return hdd_enable_ext_wow(adapter, &params);
+}
+
+static int hdd_set_app_type1_params(mac_handle_t mac_handle,
+				    tpSirAppType1Params arg_params)
+{
+	tSirAppType1Params params;
+	QDF_STATUS status;
+
+	qdf_mem_copy(&params, arg_params, sizeof(params));
+
+	status = sme_configure_app_type1_params(mac_handle, &params);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("sme_configure_app_type1_params returned failure %d",
+			 status);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int hdd_set_app_type1_parser(struct hdd_adapter *adapter,
+				    char *arg, int len)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	char id[20], password[20];
+	tSirAppType1Params params;
+	int rc;
+
+	rc = wlan_hdd_validate_context(hdd_ctx);
+	if (rc)
+		return rc;
+
+	if (2 != sscanf(arg, "%8s %16s", id, password)) {
+		hdd_err("Invalid Number of arguments");
+		return -EINVAL;
+	}
+
+	memset(&params, 0, sizeof(tSirAppType1Params));
+	params.vdev_id = adapter->session_id;
+	qdf_copy_macaddr(&params.wakee_mac_addr, &adapter->mac_addr);
+
+	params.id_length = strlen(id);
+	qdf_mem_copy(params.identification_id, id, params.id_length);
+	params.pass_length = strlen(password);
+	qdf_mem_copy(params.password, password, params.pass_length);
+
+	hdd_debug("%d %pM %.8s %u %.16s %u",
+		  params.vdev_id, params.wakee_mac_addr.bytes,
+		  params.identification_id, params.id_length,
+		  params.password, params.pass_length);
+
+	return hdd_set_app_type1_params(hdd_ctx->mac_handle, &params);
+}
+
+static int hdd_set_app_type2_params(mac_handle_t mac_handle,
+				    tpSirAppType2Params arg_params)
+{
+	tSirAppType2Params params;
+	QDF_STATUS status;
+
+	qdf_mem_copy(&params, arg_params, sizeof(params));
+
+	status = sme_configure_app_type2_params(mac_handle, &params);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("sme_configure_app_type2_params returned failure %d",
+			 status);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int hdd_set_app_type2_parser(struct hdd_adapter *adapter,
+				    char *arg, int len)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	char mac_addr[20], rc4_key[20];
+	unsigned int gateway_mac[QDF_MAC_ADDR_SIZE];
+	tSirAppType2Params params;
+	int ret;
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	memset(&params, 0, sizeof(tSirAppType2Params));
+
+	ret = sscanf(arg, "%17s %16s %x %x %x %u %u %hu %hu %u %u %u %u %u %u",
+		     mac_addr, rc4_key, (unsigned int *)&params.ip_id,
+		     (unsigned int *)&params.ip_device_ip,
+		     (unsigned int *)&params.ip_server_ip,
+		     (unsigned int *)&params.tcp_seq,
+		     (unsigned int *)&params.tcp_ack_seq,
+		     (uint16_t *)&params.tcp_src_port,
+		     (uint16_t *)&params.tcp_dst_port,
+		     (unsigned int *)&params.keepalive_init,
+		     (unsigned int *)&params.keepalive_min,
+		     (unsigned int *)&params.keepalive_max,
+		     (unsigned int *)&params.keepalive_inc,
+		     (unsigned int *)&params.tcp_tx_timeout_val,
+		     (unsigned int *)&params.tcp_rx_timeout_val);
+
+	if (ret != 15 && ret != 7) {
+		hdd_err("Invalid Number of arguments");
+		return -EINVAL;
+	}
+
+	if (6 != sscanf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x",
+			&gateway_mac[0], &gateway_mac[1], &gateway_mac[2],
+			&gateway_mac[3], &gateway_mac[4], &gateway_mac[5])) {
+		hdd_err("Invalid MacAddress Input %s", mac_addr);
+		return -EINVAL;
+	}
+
+	if (params.tcp_src_port > WLAN_HDD_MAX_TCP_PORT ||
+	    params.tcp_dst_port > WLAN_HDD_MAX_TCP_PORT) {
+		hdd_err("Invalid TCP Port Number");
+		return -EINVAL;
+	}
+
+	qdf_mem_copy(&params.gateway_mac.bytes, (uint8_t *) &gateway_mac,
+			QDF_MAC_ADDR_SIZE);
+
+	params.rc4_key_len = strlen(rc4_key);
+	qdf_mem_copy(params.rc4_key, rc4_key, params.rc4_key_len);
+
+	params.vdev_id = adapter->session_id;
+
+	if (!params.tcp_src_port)
+		params.tcp_src_port =
+		  ucfg_pmo_extwow_app2_tcp_src_port(hdd_ctx->psoc);
+
+	if (!params.tcp_dst_port)
+		params.tcp_dst_port =
+		  ucfg_pmo_extwow_app2_tcp_dst_port(hdd_ctx->psoc);
+
+	if (!params.keepalive_init)
+		params.keepalive_init =
+		  ucfg_pmo_extwow_app2_init_ping_interval(hdd_ctx->psoc);
+
+	if (!params.keepalive_min)
+		params.keepalive_min =
+		  ucfg_pmo_extwow_app2_min_ping_interval(hdd_ctx->psoc);
+
+	if (!params.keepalive_max)
+		params.keepalive_max =
+		  ucfg_pmo_extwow_app2_max_ping_interval(hdd_ctx->psoc);
+
+	if (!params.keepalive_inc)
+		params.keepalive_inc =
+		  ucfg_pmo_extwow_app2_inc_ping_interval(hdd_ctx->psoc);
+
+	if (!params.tcp_tx_timeout_val)
+		params.tcp_tx_timeout_val =
+		  ucfg_pmo_extwow_app2_tcp_tx_timeout(hdd_ctx->psoc);
+
+	if (!params.tcp_rx_timeout_val)
+		params.tcp_rx_timeout_val =
+		  ucfg_pmo_extwow_app2_tcp_rx_timeout(hdd_ctx->psoc);
+
+	hdd_debug("%pM %.16s %u %u %u %u %u %u %u %u %u %u %u %u %u",
+		  gateway_mac, rc4_key, params.ip_id,
+		  params.ip_device_ip, params.ip_server_ip, params.tcp_seq,
+		  params.tcp_ack_seq, params.tcp_src_port, params.tcp_dst_port,
+		  params.keepalive_init, params.keepalive_min,
+		  params.keepalive_max, params.keepalive_inc,
+		  params.tcp_tx_timeout_val, params.tcp_rx_timeout_val);
+
+	return hdd_set_app_type2_params(hdd_ctx->mac_handle, &params);
+}
+#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
+
+/**
+ * hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
+ * @pValue:	Pointer to MAXTXPOWER command
+ * @pDbm:	Pointer to tx power
+ *
+ * This function parses the MAXTXPOWER command passed in the format
+ * MAXTXPOWER<space>X(Tx power in dbm)
+ *
+ * For example input commands:
+ * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
+ * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int hdd_parse_setmaxtxpower_command(uint8_t *pValue, int *pTxPower)
+{
+	uint8_t *inPtr = pValue;
+	int tempInt;
+	int v = 0;
+	*pTxPower = 0;
+
+	inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+	/* no argument after the command */
+	if (NULL == inPtr)
+		return -EINVAL;
+	else if (SPACE_ASCII_VALUE != *inPtr) /* no space after the command */
+		return -EINVAL;
+
+	/* remove empty spaces */
+	while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr))
+		inPtr++;
+
+	/* no argument followed by spaces */
+	if ('\0' == *inPtr)
+		return 0;
+
+	v = kstrtos32(inPtr, 10, &tempInt);
+
+	/* Range checking for passed parameter */
+	if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
+		return -EINVAL;
+
+	*pTxPower = tempInt;
+
+	hdd_debug("SETMAXTXPOWER: %d", *pTxPower);
+
+	return 0;
+} /* End of hdd_parse_setmaxtxpower_command */
+
+static int hdd_get_dwell_time(struct hdd_config *pCfg, uint8_t *command,
+			      char *extra, uint8_t n, uint8_t *len)
+{
+	if (!pCfg || !command || !extra || !len) {
+		hdd_err("argument passed for GETDWELLTIME is incorrect");
+		return -EINVAL;
+	}
+
+	if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0) {
+		*len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
+				 (int)pCfg->nActiveMaxChnTime);
+		return 0;
+	}
+	if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0) {
+		*len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
+				 (int)pCfg->nPassiveMaxChnTime);
+		return 0;
+	}
+	if (strncmp(command, "GETDWELLTIME", 12) == 0) {
+		*len = scnprintf(extra, n, "GETDWELLTIME %u\n",
+				 (int)pCfg->nActiveMaxChnTime);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int hdd_set_dwell_time(struct hdd_adapter *adapter, uint8_t *command)
+{
+	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
+	struct hdd_config *pCfg;
+	uint8_t *value = command;
+	tSmeConfigParams *sme_config;
+	int val = 0, temp = 0;
+	int retval = 0;
+
+	pCfg = (WLAN_HDD_GET_CTX(adapter))->config;
+	if (!pCfg || !mac_handle) {
+		hdd_err("argument passed for SETDWELLTIME is incorrect");
+		return -EINVAL;
+	}
+
+	sme_config = qdf_mem_malloc(sizeof(*sme_config));
+	if (!sme_config) {
+		hdd_err("failed to allocate memory for sme_config");
+		return -ENOMEM;
+	}
+	qdf_mem_zero(sme_config, sizeof(*sme_config));
+	sme_get_config_param(mac_handle, sme_config);
+
+	if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0) {
+		if (drv_cmd_validate(command, 23))
+			return -EINVAL;
+
+		value = value + 24;
+		temp = kstrtou32(value, 10, &val);
+		if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
+		    val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX) {
+			hdd_err("argument passed for SETDWELLTIME ACTIVE MAX is incorrect");
+			retval = -EFAULT;
+			goto free;
+		}
+		pCfg->nActiveMaxChnTime = val;
+		sme_config->csrConfig.nActiveMaxChnTime = val;
+		sme_update_config(mac_handle, sme_config);
+	} else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0) {
+		if (drv_cmd_validate(command, 24))
+			return -EINVAL;
+
+		value = value + 25;
+		temp = kstrtou32(value, 10, &val);
+		if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
+		    val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX) {
+			hdd_err("argument passed for SETDWELLTIME PASSIVE MAX is incorrect");
+			retval = -EFAULT;
+			goto free;
+		}
+		pCfg->nPassiveMaxChnTime = val;
+		sme_config->csrConfig.nPassiveMaxChnTime = val;
+		sme_update_config(mac_handle, sme_config);
+	} else if (strncmp(command, "SETDWELLTIME", 12) == 0) {
+		if (drv_cmd_validate(command, 12))
+			return -EINVAL;
+
+		value = value + 13;
+		temp = kstrtou32(value, 10, &val);
+		if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
+		    val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX) {
+			hdd_err("argument passed for SETDWELLTIME is incorrect");
+			retval = -EFAULT;
+			goto free;
+		}
+		pCfg->nActiveMaxChnTime = val;
+		sme_config->csrConfig.nActiveMaxChnTime = val;
+		sme_update_config(mac_handle, sme_config);
+	} else {
+		retval = -EINVAL;
+		goto free;
+	}
+
+free:
+	qdf_mem_free(sme_config);
+	return retval;
+}
+
+struct link_status_priv {
+	uint8_t link_status;
+};
+
+#ifdef WLAN_AP_STA_CONCURRENCY
+/**
+ * hdd_conc_set_dwell_time() - Set Concurrent dwell time parameters
+ * @adapter: Adapter upon which the command was received
+ * @command: ASCII text command that is received
+ *
+ * Driver commands:
+ * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
+ * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
+ * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value>
+ * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int hdd_conc_set_dwell_time(hdd_context_t *hdd_ctx, uint8_t *command)
+{
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	struct hdd_config *p_cfg;
+	u8 *value = command;
+	tSmeConfigParams *sme_config;
+	int val = 0, temp = 0;
+	int retval = 0;
+
+	p_cfg = hdd_ctx->config;
+	if (!p_cfg || !mac_handle) {
+		hdd_err("Argument passed for CONCSETDWELLTIME is incorrect");
+		return -EINVAL;
+	}
+
+	sme_config = qdf_mem_malloc(sizeof(*sme_config));
+	if (!sme_config) {
+		hdd_err("Failed to allocate memory for sme_config");
+		return -ENOMEM;
+	}
+
+	qdf_mem_zero(sme_config, sizeof(*sme_config));
+	sme_get_config_param(mac_handle, sme_config);
+
+	if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0) {
+		if (drv_cmd_validate(command, 27)) {
+			hdd_err("Invalid driver command");
+			retval = -EINVAL;
+			goto sme_config_free;
+		}
+
+		value = value + 28;
+		temp = kstrtou32(value, 10, &val);
+		if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ||
+		    val > CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX) {
+			hdd_err("Argument passed for CONCSETDWELLTIME ACTIVE MAX is incorrect");
+			retval = -EFAULT;
+			goto sme_config_free;
+		}
+
+		p_cfg->nActiveMaxChnTimeConc = val;
+		sme_config->csrConfig.nActiveMaxChnTimeConc = val;
+		sme_update_config(mac_handle, sme_config);
+	} else if (strncmp(command, "CONCSETDWELLTIME ACTIVE MIN", 27) == 0) {
+		if (drv_cmd_validate(command, 27)) {
+			hdd_err("Invalid driver command");
+			retval = -EINVAL;
+			goto sme_config_free;
+		}
+
+		value = value + 28;
+		temp = kstrtou32(value, 10, &val);
+		if (temp != 0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ||
+		    val > CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX) {
+			hdd_err("argument passed for CONCSETDWELLTIME ACTIVE MIN is incorrect");
+			retval = -EFAULT;
+			goto sme_config_free;
+		}
+
+		p_cfg->nActiveMinChnTimeConc = val;
+		sme_config->csrConfig.nActiveMinChnTimeConc = val;
+		sme_update_config(mac_handle, sme_config);
+	} else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0) {
+		if (drv_cmd_validate(command, 28)) {
+			hdd_err("Invalid driver command");
+			retval = -EINVAL;
+			goto sme_config_free;
+		}
+
+		value = value + 29;
+		temp = kstrtou32(value, 10, &val);
+		if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ||
+		    val > CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX) {
+			hdd_err("Argument passed for CONCSETDWELLTIME PASSIVE MAX is incorrect");
+			retval = -EFAULT;
+			goto sme_config_free;
+		}
+
+		p_cfg->nPassiveMaxChnTimeConc = val;
+		sme_config->csrConfig.nPassiveMaxChnTimeConc = val;
+		sme_update_config(mac_handle, sme_config);
+	} else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MIN", 28) == 0) {
+		if (drv_cmd_validate(command, 28)) {
+			hdd_err("Invalid driver command");
+			retval = -EINVAL;
+			goto sme_config_free;
+		}
+
+		value = value + 29;
+		temp = kstrtou32(value, 10, &val);
+		if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ||
+		    val > CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX) {
+			hdd_err("argument passed for SETDWELLTIME PASSIVE MIN is incorrect");
+			retval = -EFAULT;
+			goto sme_config_free;
+		}
+
+		p_cfg->nPassiveMinChnTimeConc = val;
+		sme_config->csrConfig.nPassiveMinChnTimeConc = val;
+		sme_update_config(mac_handle, sme_config);
+	} else {
+		retval = -EINVAL;
+	}
+
+sme_config_free:
+	qdf_mem_free(sme_config);
+	return retval;
+}
+#endif
+
+static void hdd_get_link_status_cb(uint8_t status, void *context)
+{
+	struct osif_request *request;
+	struct link_status_priv *priv;
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+	priv->link_status = status;
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+/**
+ * wlan_hdd_get_link_status() - get link status
+ * @adapter:     pointer to the adapter
+ *
+ * This function sends a request to query the link status and waits
+ * on a timer to invoke the callback. if the callback is invoked then
+ * latest link status shall be returned or otherwise cached value
+ * will be returned.
+ *
+ * Return: On success, link status shall be returned.
+ *         On error or not associated, link status 0 will be returned.
+ */
+static int wlan_hdd_get_link_status(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx;
+	QDF_STATUS status;
+	int ret;
+	void *cookie;
+	struct osif_request *request;
+	struct link_status_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_LINK_STATUS,
+	};
+
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		hdd_warn("Recovery in Progress. State: 0x%x Ignore!!!",
+			 cds_get_driver_state());
+		return 0;
+	}
+
+	if ((QDF_STA_MODE != adapter->device_mode) &&
+	    (QDF_P2P_CLIENT_MODE != adapter->device_mode)) {
+		hdd_warn("Unsupported in mode %s(%d)",
+			 qdf_opmode_str(adapter->device_mode),
+			 adapter->device_mode);
+		return 0;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		/* If not associated, then expected link status return
+		 * value is 0
+		 */
+		hdd_warn("Not associated!");
+		return 0;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return 0;
+	}
+	cookie = osif_request_cookie(request);
+
+	status = sme_get_link_status(adapter->hdd_ctx->mac_handle,
+				     hdd_get_link_status_cb,
+				     cookie, adapter->session_id);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Unable to retrieve link status");
+		/* return a cached value */
+	} else {
+		/* request is sent -- wait for the response */
+		ret = osif_request_wait_for_response(request);
+		if (ret) {
+			hdd_err("SME timed out while retrieving link status");
+			/* return a cached value */
+		} else {
+			/* update the adapter with the fresh results */
+			priv = osif_request_priv(request);
+			adapter->link_status = priv->link_status;
+		}
+	}
+
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	osif_request_put(request);
+
+	/* either callback updated adapter stats or it has cached data */
+	return adapter->link_status;
+}
+
+static void hdd_tx_fail_ind_callback(uint8_t *MacAddr, uint8_t seqNo)
+{
+	int payload_len;
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	uint8_t *data;
+
+	payload_len = ETH_ALEN;
+
+	if (0 == cesium_pid || cesium_nl_srv_sock == NULL) {
+		hdd_err("cesium process not registered");
+		return;
+	}
+
+	skb = nlmsg_new(payload_len, GFP_ATOMIC);
+	if (skb == NULL) {
+		hdd_err("nlmsg_new() failed for msg size[%d]",
+			 NLMSG_SPACE(payload_len));
+		return;
+	}
+
+	nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
+
+	if (NULL == nlh) {
+		hdd_err("nlmsg_put() failed for msg size[%d]",
+			 NLMSG_SPACE(payload_len));
+
+		kfree_skb(skb);
+		return;
+	}
+
+	data = nlmsg_data(nlh);
+	memcpy(data, MacAddr, ETH_ALEN);
+
+	if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0) {
+		hdd_err("nlmsg_unicast() failed for msg size[%d]",
+			 NLMSG_SPACE(payload_len));
+	}
+}
+
+
+/**
+ * hdd_ParseuserParams - return a pointer to the next argument
+ * @pValue:	Input argument string
+ * @ppArg:	Output pointer to the next argument
+ *
+ * This function parses argument stream and finds the pointer
+ * to the next argument
+ *
+ * Return: 0 if the next argument found; -EINVAL otherwise
+ */
+static int hdd_parse_user_params(uint8_t *pValue, uint8_t **ppArg)
+{
+	uint8_t *pVal;
+
+	pVal = strnchr(pValue, strlen(pValue), ' ');
+
+	if (NULL == pVal) /* no argument remains */
+		return -EINVAL;
+	else if (SPACE_ASCII_VALUE != *pVal)/* no space after the current arg */
+		return -EINVAL;
+
+	pVal++;
+
+	/* remove empty spaces */
+	while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
+		pVal++;
+
+	/* no argument followed by spaces */
+	if ('\0' == *pVal)
+		return -EINVAL;
+
+	*ppArg = pVal;
+
+	return 0;
+}
+
+/**
+ * hdd_parse_ibsstx_fail_event_params - Parse params
+ *                                             for SETIBSSTXFAILEVENT
+ * @pValue:		Input ibss tx fail event argument
+ * @tx_fail_count:	(Output parameter) Tx fail counter
+ * @pid:		(Output parameter) PID
+ *
+ * Return: 0 if the parsing succeeds; -EINVAL otherwise
+ */
+static int hdd_parse_ibsstx_fail_event_params(uint8_t *pValue,
+					      uint8_t *tx_fail_count,
+					      uint16_t *pid)
+{
+	uint8_t *param = NULL;
+	int ret;
+
+	ret = hdd_parse_user_params(pValue, &param);
+
+	if (0 == ret && NULL != param) {
+		if (1 != sscanf(param, "%hhu", tx_fail_count)) {
+			ret = -EINVAL;
+			goto done;
+		}
+	} else {
+		goto done;
+	}
+
+	if (0 == *tx_fail_count) {
+		*pid = 0;
+		goto done;
+	}
+
+	pValue = param;
+	pValue++;
+
+	ret = hdd_parse_user_params(pValue, &param);
+
+	if (0 == ret) {
+		if (1 != sscanf(param, "%hu", pid)) {
+			ret = -EINVAL;
+			goto done;
+		}
+	} else {
+		goto done;
+	}
+
+done:
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * hdd_parse_ese_beacon_req() - Parse ese beacon request
+ * @pValue:	Pointer to data
+ * @pEseBcnReq:	Output pointer to store parsed ie information
+ *
+ * This function parses the ese beacon request passed in the format
+ * CCXBEACONREQ<space><Number of fields><space><Measurement token>
+ * <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
+ * <space>Scan Mode N<space>Meas Duration N
+ *
+ * If the Number of bcn req fields (N) does not match with the
+ * actual number of fields passed then take N.
+ * <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated
+ * as one pair. For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
+ * This function does not take care of removing duplicate channels from the
+ * list
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int hdd_parse_ese_beacon_req(uint8_t *pValue,
+					tCsrEseBeaconReq *pEseBcnReq)
+{
+	uint8_t *inPtr = pValue;
+	uint8_t input = 0;
+	uint32_t tempInt = 0;
+	int j = 0, i = 0, v = 0;
+	char buf[32];
+
+	inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+	if (NULL == inPtr) /* no argument after the command */
+		return -EINVAL;
+	else if (SPACE_ASCII_VALUE != *inPtr) /* no space after the command */
+		return -EINVAL;
+
+	/* remove empty spaces */
+	while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr))
+		inPtr++;
+
+	/* no argument followed by spaces */
+	if ('\0' == *inPtr)
+		return -EINVAL;
+
+	/* Getting the first argument ie Number of IE fields */
+	v = sscanf(inPtr, "%31s ", buf);
+	if (1 != v)
+		return -EINVAL;
+
+	v = kstrtou8(buf, 10, &input);
+	if (v < 0)
+		return -EINVAL;
+
+	input = QDF_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
+	pEseBcnReq->numBcnReqIe = input;
+
+	hdd_debug("Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
+
+	for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++) {
+		for (i = 0; i < 4; i++) {
+			/*
+			 * inPtr pointing to the beginning of 1st space
+			 * after number of ie fields
+			 */
+			inPtr = strpbrk(inPtr, " ");
+			/* no ie data after the number of ie fields argument */
+			if (NULL == inPtr)
+				return -EINVAL;
+
+			/* remove empty space */
+			while ((SPACE_ASCII_VALUE == *inPtr)
+			       && ('\0' != *inPtr))
+				inPtr++;
+
+			/*
+			 * no ie data after the number of ie fields
+			 * argument and spaces
+			 */
+			if ('\0' == *inPtr)
+				return -EINVAL;
+
+			v = sscanf(inPtr, "%31s ", buf);
+			if (1 != v)
+				return -EINVAL;
+
+			v = kstrtou32(buf, 10, &tempInt);
+			if (v < 0)
+				return -EINVAL;
+
+			switch (i) {
+			case 0: /* Measurement token */
+				if (!tempInt) {
+					hdd_err("Invalid Measurement Token: %u",
+						  tempInt);
+					return -EINVAL;
+				}
+				pEseBcnReq->bcnReq[j].measurementToken =
+					tempInt;
+				break;
+
+			case 1: /* Channel number */
+				if (!tempInt ||
+				    (tempInt >
+				     WNI_CFG_CURRENT_CHANNEL_STAMAX)) {
+					hdd_err("Invalid Channel Number: %u",
+						  tempInt);
+					return -EINVAL;
+				}
+				pEseBcnReq->bcnReq[j].channel = tempInt;
+				break;
+
+			case 2: /* Scan mode */
+				if ((tempInt < eSIR_PASSIVE_SCAN)
+				    || (tempInt > eSIR_BEACON_TABLE)) {
+					hdd_err("Invalid Scan Mode: %u Expected{0|1|2}",
+						  tempInt);
+					return -EINVAL;
+				}
+				pEseBcnReq->bcnReq[j].scanMode = tempInt;
+				break;
+
+			case 3: /* Measurement duration */
+				if ((!tempInt
+				     && (pEseBcnReq->bcnReq[j].scanMode !=
+					 eSIR_BEACON_TABLE)) ||
+				    (pEseBcnReq->bcnReq[j].scanMode ==
+						eSIR_BEACON_TABLE)) {
+					hdd_err("Invalid Measurement Duration: %u",
+						  tempInt);
+					return -EINVAL;
+				}
+				pEseBcnReq->bcnReq[j].measurementDuration =
+					tempInt;
+				break;
+			}
+		}
+	}
+
+	for (j = 0; j < pEseBcnReq->numBcnReqIe; j++) {
+		hdd_debug("Index: %d Measurement Token: %u Channel: %u Scan Mode: %u Measurement Duration: %u",
+			  j,
+			  pEseBcnReq->bcnReq[j].measurementToken,
+			  pEseBcnReq->bcnReq[j].channel,
+			  pEseBcnReq->bcnReq[j].scanMode,
+			  pEseBcnReq->bcnReq[j].measurementDuration);
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
+ * @pValue:	Pointer to input data
+ * @pCckmIe:	Pointer to output cckm Ie
+ * @pCckmIeLen:	Pointer to output cckm ie length
+ *
+ * This function parses the SETCCKM IE command
+ * SETCCKMIE<space><ie data>
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int hdd_parse_get_cckm_ie(uint8_t *pValue, uint8_t **pCckmIe,
+				 uint8_t *pCckmIeLen)
+{
+	uint8_t *inPtr = pValue;
+	uint8_t *dataEnd;
+	int j = 0;
+	int i = 0;
+	uint8_t tempByte = 0;
+
+	inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+	/* no argument after the command */
+	if (NULL == inPtr)
+		return -EINVAL;
+	else if (SPACE_ASCII_VALUE != *inPtr) /* no space after the command */
+		return -EINVAL;
+
+	/* remove empty spaces */
+	while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr))
+		inPtr++;
+	/* no argument followed by spaces */
+	if ('\0' == *inPtr)
+		return -EINVAL;
+
+	/* find the length of data */
+	dataEnd = inPtr;
+	while (('\0' != *dataEnd)) {
+		dataEnd++;
+		++(*pCckmIeLen);
+	}
+	if (*pCckmIeLen <= 0)
+		return -EINVAL;
+	/*
+	 * Allocate the number of bytes based on the number of input characters
+	 * whether it is even or odd.
+	 * if the number of input characters are even, then we need N / 2 byte.
+	 * if the number of input characters are odd, then we need do
+	 * (N + 1) / 2 to compensate rounding off.
+	 * For example, if N = 18, then (18 + 1) / 2 = 9 bytes are enough.
+	 * If N = 19, then we need 10 bytes, hence (19 + 1) / 2 = 10 bytes
+	 */
+	*pCckmIe = qdf_mem_malloc((*pCckmIeLen + 1) / 2);
+	if (NULL == *pCckmIe) {
+		hdd_err("qdf_mem_malloc failed");
+		return -ENOMEM;
+	}
+	/*
+	 * the buffer received from the upper layer is character buffer,
+	 * we need to prepare the buffer taking 2 characters in to a U8 hex
+	 * decimal number for example 7f0000f0...form a buffer to contain
+	 * 7f in 0th location, 00 in 1st and f0 in 3rd location
+	 */
+	for (i = 0, j = 0; j < *pCckmIeLen; j += 2) {
+		tempByte = (hex_to_bin(inPtr[j]) << 4) |
+			   (hex_to_bin(inPtr[j + 1]));
+		(*pCckmIe)[i++] = tempByte;
+	}
+	*pCckmIeLen = i;
+	return 0;
+}
+#endif /* FEATURE_WLAN_ESE */
+
+int wlan_hdd_set_mc_rate(struct hdd_adapter *adapter, int targetRate)
+{
+	tSirRateUpdateInd rateUpdate = {0};
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_config *pConfig;
+	bool bval = false;
+
+	if (hdd_ctx == NULL) {
+		hdd_err("HDD context is null");
+		return -EINVAL;
+	}
+	if ((QDF_IBSS_MODE != adapter->device_mode) &&
+	    (QDF_SAP_MODE != adapter->device_mode) &&
+	    (QDF_STA_MODE != adapter->device_mode)) {
+		hdd_err("Received SETMCRATE cmd in invalid mode %s(%d)",
+			qdf_opmode_str(adapter->device_mode),
+			adapter->device_mode);
+		hdd_err("SETMCRATE cmd is allowed only in STA, IBSS or SOFTAP mode");
+		return -EINVAL;
+	}
+	pConfig = hdd_ctx->config;
+
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("unable to get vht_enable2x2");
+		return -EINVAL;
+	}
+	rateUpdate.nss = (bval == 0) ? 0 : 1;
+
+	rateUpdate.dev_mode = adapter->device_mode;
+	rateUpdate.mcastDataRate24GHz = targetRate;
+	rateUpdate.mcastDataRate24GHzTxFlag = 1;
+	rateUpdate.mcastDataRate5GHz = targetRate;
+	rateUpdate.bcastDataRate = -1;
+	qdf_copy_macaddr(&rateUpdate.bssid, &adapter->mac_addr);
+	hdd_debug("MC Target rate %d, mac = %pM, dev_mode %s(%d)",
+		  rateUpdate.mcastDataRate24GHz, rateUpdate.bssid.bytes,
+		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
+	status = sme_send_rate_update_ind(hdd_ctx->mac_handle, &rateUpdate);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("SETMCRATE failed");
+		return -EFAULT;
+	}
+	return 0;
+}
+
+static int drv_cmd_p2p_dev_addr(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	struct qdf_mac_addr *addr = &hdd_ctx->p2p_device_address;
+	size_t user_size = qdf_min(sizeof(addr->bytes),
+				   (size_t)priv_data->total_len);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
+			 adapter->session_id,
+			 (unsigned int)(*(addr->bytes + 2) << 24 |
+				*(addr->bytes + 3) << 16 |
+				*(addr->bytes + 4) << 8 |
+				*(addr->bytes + 5))));
+
+	if (copy_to_user(priv_data->buf, addr->bytes, user_size)) {
+		hdd_err("failed to copy data to user buffer");
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/**
+ * drv_cmd_p2p_set_noa() - Handler for P2P_SET_NOA driver command
+ * @adapter: Adapter on which the command was received
+ * @hdd_ctx: HDD global context
+ * @command: Entire driver command received from userspace
+ * @command_len: Length of @command
+ * @priv_data: Pointer to ioctl private data structure
+ *
+ * This is a trivial command handler function which simply forwards the
+ * command to the actual command processor within the P2P module.
+ *
+ * Return: 0 on success, non-zero on failure
+ */
+static int drv_cmd_p2p_set_noa(struct hdd_adapter *adapter,
+			       struct hdd_context *hdd_ctx,
+			       uint8_t *command,
+			       uint8_t command_len,
+			       struct hdd_priv_data *priv_data)
+{
+	return hdd_set_p2p_noa(adapter->dev, command);
+}
+
+/**
+ * drv_cmd_p2p_set_ps() - Handler for P2P_SET_PS driver command
+ * @adapter: Adapter on which the command was received
+ * @hdd_ctx: HDD global context
+ * @command: Entire driver command received from userspace
+ * @command_len: Length of @command
+ * @priv_data: Pointer to ioctl private data structure
+ *
+ * This is a trivial command handler function which simply forwards the
+ * command to the actual command processor within the P2P module.
+ *
+ * Return: 0 on success, non-zero on failure
+ */
+static int drv_cmd_p2p_set_ps(struct hdd_adapter *adapter,
+			      struct hdd_context *hdd_ctx,
+			      uint8_t *command,
+			      uint8_t command_len,
+			      struct hdd_priv_data *priv_data)
+{
+	return hdd_set_p2p_opps(adapter->dev, command);
+}
+
+static int drv_cmd_set_band(struct hdd_adapter *adapter,
+			    struct hdd_context *hdd_ctx,
+			    uint8_t *command,
+			    uint8_t command_len,
+			    struct hdd_priv_data *priv_data)
+{
+	int err;
+	uint8_t band;
+
+	/*
+	 * Parse the band value passed from userspace. The first 8 bytes
+	 * should be "SETBAND " and the 9th byte should be a UI band value
+	 */
+	err = kstrtou8(command + command_len + 1, 10, &band);
+	if (err) {
+		hdd_err("error %d parsing userspace band parameter", err);
+		return err;
+	}
+
+	return hdd_reg_set_band(adapter->dev, band);
+}
+
+static int drv_cmd_set_wmmps(struct hdd_adapter *adapter,
+			     struct hdd_context *hdd_ctx,
+			     uint8_t *command,
+			     uint8_t command_len,
+			     struct hdd_priv_data *priv_data)
+{
+	return hdd_wmmps_helper(adapter, command);
+}
+
+static inline int drv_cmd_country(struct hdd_adapter *adapter,
+				  struct hdd_context *hdd_ctx,
+				  uint8_t *command,
+				  uint8_t command_len,
+				  struct hdd_priv_data *priv_data)
+{
+	char *country_code;
+
+	country_code = strnchr(command, strlen(command), ' ');
+	/* no argument after the command */
+	if (!country_code)
+		return -EINVAL;
+
+	/* no space after the command */
+	if (*country_code != SPACE_ASCII_VALUE)
+		return -EINVAL;
+
+	country_code++;
+
+	/* removing empty spaces */
+	while ((*country_code == SPACE_ASCII_VALUE) &&
+	       (*country_code != '\0'))
+		country_code++;
+
+	/* no or less than 2  arguments followed by spaces */
+	if (*country_code == '\0' || *(country_code + 1) == '\0')
+		return -EINVAL;
+
+	return hdd_reg_set_country(hdd_ctx, country_code);
+}
+
+static int drv_cmd_set_roam_trigger(struct hdd_adapter *adapter,
+				    struct hdd_context *hdd_ctx,
+				    uint8_t *command,
+				    uint8_t command_len,
+				    struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint8_t *value = command;
+	int8_t rssi = 0;
+	uint8_t lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	/* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtos8(value, 10, &rssi);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed Input value may be out of range[%d - %d]",
+			CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
+			CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	lookUpThreshold = abs(rssi);
+
+	if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
+	    (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX)) {
+		hdd_err("Neighbor lookup threshold value %d is out of range (Min: %d Max: %d)",
+			  lookUpThreshold,
+			  CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
+			  CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
+			 adapter->session_id, lookUpThreshold));
+	hdd_debug("Received Command to Set Roam trigger (Neighbor lookup threshold) = %d",
+		  lookUpThreshold);
+
+	hdd_ctx->config->nNeighborLookupRssiThreshold = lookUpThreshold;
+	status = sme_set_neighbor_lookup_rssi_threshold(hdd_ctx->mac_handle,
+							adapter->session_id,
+							lookUpThreshold);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Failed to set roam trigger, try again");
+		ret = -EPERM;
+		goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_roam_trigger(struct hdd_adapter *adapter,
+				    struct hdd_context *hdd_ctx,
+				    uint8_t *command,
+				    uint8_t command_len,
+				    struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t lookUpThreshold =
+		sme_get_neighbor_lookup_rssi_threshold(hdd_ctx->mac_handle);
+	int rssi = (-1) * lookUpThreshold;
+	char extra[32];
+	uint8_t len = 0;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
+			 adapter->session_id, lookUpThreshold));
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_roam_scan_period(struct hdd_adapter *adapter,
+					struct hdd_context *hdd_ctx,
+					uint8_t *command,
+					uint8_t command_len,
+					struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t roamScanPeriod = 0;
+	uint16_t neighborEmptyScanRefreshPeriod =
+		CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
+
+	/* input refresh period is in terms of seconds */
+
+	/* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &roamScanPeriod);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed Input value may be out of range[%d - %d]",
+			(CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN / 1000),
+			(CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX / 1000));
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN / 1000))
+	    || (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX / 1000))) {
+		hdd_err("Roam scan period value %d is out of range (Min: %d Max: %d)",
+			roamScanPeriod,
+			(CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN / 1000),
+			(CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX / 1000));
+		ret = -EINVAL;
+		goto exit;
+	}
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
+			 adapter->session_id, roamScanPeriod));
+	neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
+
+	hdd_debug("Received Command to Set roam scan period (Empty Scan refresh period) = %d",
+		  roamScanPeriod);
+
+	hdd_ctx->config->nEmptyScanRefreshPeriod =
+		neighborEmptyScanRefreshPeriod;
+	sme_update_empty_scan_refresh_period(hdd_ctx->mac_handle,
+					     adapter->session_id,
+					     neighborEmptyScanRefreshPeriod);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_roam_scan_period(struct hdd_adapter *adapter,
+					struct hdd_context *hdd_ctx,
+					uint8_t *command,
+					uint8_t command_len,
+					struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint16_t nEmptyScanRefreshPeriod =
+		sme_get_empty_scan_refresh_period(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
+			 adapter->session_id,
+			 nEmptyScanRefreshPeriod));
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+			"GETROAMSCANPERIOD",
+			(nEmptyScanRefreshPeriod / 1000));
+	/* Returned value is in units of seconds */
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_roam_scan_refresh_period(struct hdd_adapter *adapter,
+						struct hdd_context *hdd_ctx,
+						uint8_t *command,
+						uint8_t command_len,
+						struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint8_t *value = command;
+	uint8_t roamScanRefreshPeriod = 0;
+	uint16_t neighborScanRefreshPeriod =
+		CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
+
+	/* input refresh period is in terms of seconds */
+	/* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed Input value may be out of range[%d - %d]",
+			CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN / 1000,
+			CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX / 1000);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((roamScanRefreshPeriod <
+		(CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN / 1000)) ||
+	    (roamScanRefreshPeriod >
+		(CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX / 1000))) {
+		hdd_err("Neighbor scan results refresh period value %d is out of range (Min: %d Max: %d)",
+			roamScanRefreshPeriod,
+			(CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN
+			 / 1000),
+			(CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX
+			 / 1000));
+		ret = -EINVAL;
+		goto exit;
+	}
+	neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
+
+	hdd_debug("Received Command to Set roam scan refresh period (Scan refresh period) = %d",
+		  roamScanRefreshPeriod);
+
+	hdd_ctx->config->nNeighborResultsRefreshPeriod =
+				neighborScanRefreshPeriod;
+	sme_set_neighbor_scan_refresh_period(hdd_ctx->mac_handle,
+					     adapter->session_id,
+					     neighborScanRefreshPeriod);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_roam_scan_refresh_period(struct hdd_adapter *adapter,
+						struct hdd_context *hdd_ctx,
+						uint8_t *command,
+						uint8_t command_len,
+						struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint16_t value =
+		sme_get_neighbor_scan_refresh_period(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+			"GETROAMSCANREFRESHPERIOD",
+			(value / 1000));
+	/* Returned value is in units of seconds */
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_roam_mode(struct hdd_adapter *adapter,
+				 struct hdd_context *hdd_ctx,
+				 uint8_t *command,
+				 uint8_t command_len,
+				 struct hdd_priv_data *priv_data)
+{
+	mac_handle_t mac_handle;
+	int ret;
+	uint8_t *value = command;
+	uint8_t roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
+
+	/* Move pointer to ahead of SETROAMMODE<delimiter> */
+	value = value + SIZE_OF_SETROAMMODE + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &roamMode);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			CFG_LFR_FEATURE_ENABLED_MIN,
+			CFG_LFR_FEATURE_ENABLED_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+	if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
+	    (roamMode > CFG_LFR_FEATURE_ENABLED_MAX)) {
+		hdd_err("Roam Mode value %d is out of range (Min: %d Max: %d)",
+			roamMode,
+			CFG_LFR_FEATURE_ENABLED_MIN,
+			CFG_LFR_FEATURE_ENABLED_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to Set Roam Mode = %d",
+		  roamMode);
+	/*
+	 * Note that
+	 *     SETROAMMODE 0 is to enable LFR while
+	 *     SETROAMMODE 1 is to disable LFR, but
+	 *     notify_is_fast_roam_ini_feature_enabled 0/1 is to
+	 *     enable/disable. So, we have to invert the value
+	 *     to call sme_update_is_fast_roam_ini_feature_enabled.
+	 */
+	if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
+		roamMode = CFG_LFR_FEATURE_ENABLED_MAX;  /* Roam enable */
+	else
+		roamMode = CFG_LFR_FEATURE_ENABLED_MIN;  /* Roam disable */
+
+	hdd_ctx->config->isFastRoamIniFeatureEnabled = roamMode;
+	mac_handle = hdd_ctx->mac_handle;
+	if (roamMode) {
+		hdd_ctx->config->isRoamOffloadScanEnabled = roamMode;
+		sme_update_roam_scan_offload_enabled(mac_handle, roamMode);
+		sme_update_is_fast_roam_ini_feature_enabled(mac_handle,
+							    adapter->session_id,
+							    roamMode);
+	} else {
+		sme_update_is_fast_roam_ini_feature_enabled(mac_handle,
+							    adapter->session_id,
+							    roamMode);
+		hdd_ctx->config->isRoamOffloadScanEnabled = roamMode;
+		sme_update_roam_scan_offload_enabled(mac_handle, roamMode);
+	}
+
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_roam_mode(struct hdd_adapter *adapter,
+				 struct hdd_context *hdd_ctx,
+				 uint8_t *command,
+				 uint8_t command_len,
+				 struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	bool roamMode = sme_get_is_lfr_feature_enabled(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len;
+
+	/*
+	 * roamMode value shall be inverted because the sementics is different.
+	 */
+	if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
+		roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
+	else
+		roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_roam_delta(struct hdd_adapter *adapter,
+				  struct hdd_context *hdd_ctx,
+				  uint8_t *command,
+				  uint8_t command_len,
+				  struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint8_t *value = command;
+	uint8_t roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
+
+	/* Move pointer to ahead of SETROAMDELTA<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &roamRssiDiff);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			CFG_ROAM_RSSI_DIFF_MIN,
+			CFG_ROAM_RSSI_DIFF_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
+	    (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX)) {
+		hdd_err("Roam rssi diff value %d is out of range (Min: %d Max: %d)",
+			roamRssiDiff,
+			CFG_ROAM_RSSI_DIFF_MIN,
+			CFG_ROAM_RSSI_DIFF_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to Set roam rssi diff = %d",
+		  roamRssiDiff);
+
+	hdd_ctx->config->RoamRssiDiff = roamRssiDiff;
+	sme_update_roam_rssi_diff(hdd_ctx->mac_handle,
+				  adapter->session_id,
+				  roamRssiDiff);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_roam_delta(struct hdd_adapter *adapter,
+				  struct hdd_context *hdd_ctx,
+				  uint8_t *command,
+				  uint8_t command_len,
+				  struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t roamRssiDiff =
+		sme_get_roam_rssi_diff(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
+			 adapter->session_id, roamRssiDiff));
+
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+			command, roamRssiDiff);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_get_band(struct hdd_adapter *adapter,
+			    struct hdd_context *hdd_ctx,
+			    uint8_t *command,
+			    uint8_t command_len,
+			    struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	int band = -1;
+	char extra[32];
+	uint8_t len = 0;
+
+	hdd_get_band_helper(hdd_ctx, &band);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_GETBAND_IOCTL,
+			 adapter->session_id, band));
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_roam_scan_channels(struct hdd_adapter *adapter,
+					  struct hdd_context *hdd_ctx,
+					  uint8_t *command,
+					  uint8_t command_len,
+					  struct hdd_priv_data *priv_data)
+{
+	return hdd_parse_set_roam_scan_channels(adapter, command);
+}
+
+static int drv_cmd_get_roam_scan_channels(struct hdd_adapter *adapter,
+					  struct hdd_context *hdd_ctx,
+					  uint8_t *command,
+					  uint8_t command_len,
+					  struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
+	uint8_t numChannels = 0;
+	uint8_t j = 0;
+	char extra[128] = { 0 };
+	int len;
+
+	if (QDF_STATUS_SUCCESS !=
+		sme_get_roam_scan_channel_list(hdd_ctx->mac_handle,
+					       ChannelList,
+					       &numChannels,
+					       adapter->session_id)) {
+		hdd_err("failed to get roam scan channel list");
+		ret = -EFAULT;
+		goto exit;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
+			 adapter->session_id, numChannels));
+	/*
+	 * output channel list is of the format
+	 * [Number of roam scan channels][Channel1][Channel2]...
+	 * copy the number of channels in the 0th index
+	 */
+	len = scnprintf(extra, sizeof(extra), "%s %d", command,
+			numChannels);
+	for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
+		len += scnprintf(extra + len, sizeof(extra) - len,
+				 " %d", ChannelList[j]);
+
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+		goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_ccx_mode(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	bool eseMode = sme_get_is_ese_feature_enabled(mac_handle);
+	char extra[32];
+	uint8_t len = 0;
+	struct pmkid_mode_bits pmkid_modes;
+
+	hdd_get_pmkid_modes(hdd_ctx, &pmkid_modes);
+	/*
+	 * Check if the features PMKID/ESE/11R are supported simultaneously,
+	 * then this operation is not permitted (return FAILURE)
+	 */
+	if (eseMode &&
+	    (pmkid_modes.fw_okc || pmkid_modes.fw_pmksa_cache) &&
+	    sme_get_is_ft_feature_enabled(mac_handle)) {
+		hdd_warn("PMKID/ESE/11R are supported simultaneously hence this operation is not permitted!");
+		ret = -EPERM;
+		goto exit;
+	}
+
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+			"GETCCXMODE", eseMode);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+		goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_okc_mode(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	struct pmkid_mode_bits pmkid_modes;
+	char extra[32];
+	uint8_t len = 0;
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+
+	hdd_get_pmkid_modes(hdd_ctx, &pmkid_modes);
+	/*
+	 * Check if the features OKC/ESE/11R are supported simultaneously,
+	 * then this operation is not permitted (return FAILURE)
+	 */
+	if (pmkid_modes.fw_okc &&
+	    sme_get_is_ese_feature_enabled(mac_handle) &&
+	    sme_get_is_ft_feature_enabled(mac_handle)) {
+		hdd_warn("PMKID/ESE/11R are supported simultaneously hence this operation is not permitted!");
+		ret = -EPERM;
+		goto exit;
+	}
+
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+			"GETOKCMODE", pmkid_modes.fw_okc);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+		goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_fast_roam(struct hdd_adapter *adapter,
+				 struct hdd_context *hdd_ctx,
+				 uint8_t *command,
+				 uint8_t command_len,
+				 struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	bool lfrMode = sme_get_is_lfr_feature_enabled(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len = 0;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+			"GETFASTROAM", lfrMode);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_get_fast_transition(struct hdd_adapter *adapter,
+				       struct hdd_context *hdd_ctx,
+				       uint8_t *command,
+				       uint8_t command_len,
+				       struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	bool ft = sme_get_is_ft_feature_enabled(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len = 0;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+					"GETFASTTRANSITION", ft);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_roam_scan_channel_min_time(struct hdd_adapter *adapter,
+						  struct hdd_context *hdd_ctx,
+						  uint8_t *command,
+						  uint8_t command_len,
+						  struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
+
+	/* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &minTime);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
+			CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
+	    (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX)) {
+		hdd_err("scan min channel time value %d is out of range (Min: %d Max: %d)",
+			minTime,
+			CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
+			CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
+			 adapter->session_id, minTime));
+	hdd_debug("Received Command to change channel min time = %d",
+		  minTime);
+
+	hdd_ctx->config->nNeighborScanMinChanTime = minTime;
+	sme_set_neighbor_scan_min_chan_time(hdd_ctx->mac_handle,
+					    minTime,
+					    adapter->session_id);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_send_action_frame(struct hdd_adapter *adapter,
+				     struct hdd_context *hdd_ctx,
+				     uint8_t *command,
+				     uint8_t command_len,
+				     struct hdd_priv_data *priv_data)
+{
+	return hdd_parse_sendactionframe(adapter, command,
+					 priv_data->total_len);
+}
+
+static int drv_cmd_get_roam_scan_channel_min_time(struct hdd_adapter *adapter,
+						  struct hdd_context *hdd_ctx,
+						  uint8_t *command,
+						  uint8_t command_len,
+						  struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint16_t val = sme_get_neighbor_scan_min_chan_time(hdd_ctx->mac_handle,
+							   adapter->session_id);
+	char extra[32];
+	uint8_t len = 0;
+
+	/* value is interms of msec */
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+			"GETROAMSCANCHANNELMINTIME", val);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
+			 adapter->session_id, val));
+
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_scan_channel_time(struct hdd_adapter *adapter,
+					 struct hdd_context *hdd_ctx,
+					 uint8_t *command,
+					 uint8_t command_len,
+					 struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint16_t maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
+
+	/* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou16(value, 10, &maxTime);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou16 failed range [%d - %d]",
+			CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
+			CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
+	    (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX)) {
+		hdd_err("lfr mode value %d is out of range (Min: %d Max: %d)",
+			maxTime,
+			CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
+			CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to change channel max time = %d",
+		  maxTime);
+
+	hdd_ctx->config->nNeighborScanMaxChanTime = maxTime;
+	sme_set_neighbor_scan_max_chan_time(hdd_ctx->mac_handle,
+					    adapter->session_id,
+					    maxTime);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_scan_channel_time(struct hdd_adapter *adapter,
+					 struct hdd_context *hdd_ctx,
+					 uint8_t *command,
+					 uint8_t command_len,
+					 struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint16_t val = sme_get_neighbor_scan_max_chan_time(hdd_ctx->mac_handle,
+							   adapter->session_id);
+	char extra[32];
+	uint8_t len = 0;
+
+	/* value is interms of msec */
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+			"GETSCANCHANNELTIME", val);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_scan_home_time(struct hdd_adapter *adapter,
+				      struct hdd_context *hdd_ctx,
+				      uint8_t *command,
+				      uint8_t command_len,
+				      struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint16_t val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
+
+	/* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou16(value, 10, &val);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou16 failed range [%d - %d]",
+			CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
+			CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
+	    (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX)) {
+		hdd_err("scan home time value %d is out of range (Min: %d Max: %d)",
+			val,
+			CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
+			CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to change scan home time = %d",
+		  val);
+
+	hdd_ctx->config->nNeighborScanPeriod = val;
+	sme_set_neighbor_scan_period(hdd_ctx->mac_handle,
+				     adapter->session_id, val);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_scan_home_time(struct hdd_adapter *adapter,
+				      struct hdd_context *hdd_ctx,
+				      uint8_t *command,
+				      uint8_t command_len,
+				      struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint16_t val = sme_get_neighbor_scan_period(hdd_ctx->mac_handle,
+						    adapter->session_id);
+	char extra[32];
+	uint8_t len = 0;
+
+	/* value is interms of msec */
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+			"GETSCANHOMETIME", val);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_roam_intra_band(struct hdd_adapter *adapter,
+				       struct hdd_context *hdd_ctx,
+				       uint8_t *command,
+				       uint8_t command_len,
+				       struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t val = CFG_ROAM_INTRA_BAND_DEFAULT;
+
+	/* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &val);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			CFG_ROAM_INTRA_BAND_MIN,
+			CFG_ROAM_INTRA_BAND_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
+	    (val > CFG_ROAM_INTRA_BAND_MAX)) {
+		hdd_err("intra band mode value %d is out of range (Min: %d Max: %d)",
+			val,
+			CFG_ROAM_INTRA_BAND_MIN,
+			CFG_ROAM_INTRA_BAND_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+	hdd_debug("Received Command to change intra band = %d",
+		  val);
+
+	hdd_ctx->config->nRoamIntraBand = val;
+	sme_set_roam_intra_band(hdd_ctx->mac_handle, val);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_roam_intra_band(struct hdd_adapter *adapter,
+				       struct hdd_context *hdd_ctx,
+				       uint8_t *command,
+				       uint8_t command_len,
+				       struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint16_t val = sme_get_roam_intra_band(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len = 0;
+
+	/* value is interms of msec */
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+			"GETROAMINTRABAND", val);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_scan_n_probes(struct hdd_adapter *adapter,
+				     struct hdd_context *hdd_ctx,
+				     uint8_t *command,
+				     uint8_t command_len,
+				     struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
+
+	/* Move pointer to ahead of SETSCANNPROBES<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &nProbes);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			CFG_ROAM_SCAN_N_PROBES_MIN,
+			CFG_ROAM_SCAN_N_PROBES_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
+	    (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX)) {
+		hdd_err("NProbes value %d is out of range (Min: %d Max: %d)",
+			nProbes,
+			CFG_ROAM_SCAN_N_PROBES_MIN,
+			CFG_ROAM_SCAN_N_PROBES_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to Set nProbes = %d",
+		  nProbes);
+
+	hdd_ctx->config->nProbes = nProbes;
+	sme_update_roam_scan_n_probes(hdd_ctx->mac_handle,
+				      adapter->session_id, nProbes);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_scan_n_probes(struct hdd_adapter *adapter,
+				     struct hdd_context *hdd_ctx,
+				     uint8_t *command,
+				     uint8_t command_len,
+				     struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t val = sme_get_roam_scan_n_probes(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len = 0;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_scan_home_away_time(struct hdd_adapter *adapter,
+					   struct hdd_context *hdd_ctx,
+					   uint8_t *command,
+					   uint8_t command_len,
+					   struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint16_t homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
+
+	/* input value is in units of msec */
+
+	/* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou16(value, 10, &homeAwayTime);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
+			CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
+	    (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX)) {
+		hdd_err("homeAwayTime value %d is out of range (Min: %d Max: %d)",
+			  homeAwayTime,
+			  CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
+			  CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to Set scan away time = %d",
+		  homeAwayTime);
+
+	if (hdd_ctx->config->nRoamScanHomeAwayTime !=
+	    homeAwayTime) {
+		hdd_ctx->config->nRoamScanHomeAwayTime = homeAwayTime;
+		sme_update_roam_scan_home_away_time(hdd_ctx->mac_handle,
+						    adapter->session_id,
+						    homeAwayTime,
+						    true);
+	}
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_scan_home_away_time(struct hdd_adapter *adapter,
+					   struct hdd_context *hdd_ctx,
+					   uint8_t *command,
+					   uint8_t command_len,
+					   struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint16_t val = sme_get_roam_scan_home_away_time(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len = 0;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_reassoc(struct hdd_adapter *adapter,
+			   struct hdd_context *hdd_ctx,
+			   uint8_t *command,
+			   uint8_t command_len,
+			   struct hdd_priv_data *priv_data)
+{
+	return hdd_parse_reassoc(adapter, command, priv_data->total_len);
+}
+
+static int drv_cmd_set_wes_mode(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
+
+	/* Move pointer to ahead of SETWESMODE<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &wesMode);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			  CFG_ENABLE_WES_MODE_NAME_MIN,
+			  CFG_ENABLE_WES_MODE_NAME_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
+	    (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX)) {
+		hdd_err("WES Mode value %d is out of range (Min: %d Max: %d)",
+			  wesMode,
+			  CFG_ENABLE_WES_MODE_NAME_MIN,
+			  CFG_ENABLE_WES_MODE_NAME_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to Set WES Mode rssi diff = %d",
+		  wesMode);
+
+	hdd_ctx->config->isWESModeEnabled = wesMode;
+	sme_update_wes_mode(hdd_ctx->mac_handle, wesMode, adapter->session_id);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_wes_mode(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	bool wesMode = sme_get_wes_mode(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len = 0;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_opportunistic_rssi_diff(struct hdd_adapter *adapter,
+					       struct hdd_context *hdd_ctx,
+					       uint8_t *command,
+					       uint8_t command_len,
+					       struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t nOpportunisticThresholdDiff =
+		CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_DEFAULT;
+
+	/* Move pointer to ahead of SETOPPORTUNISTICRSSIDIFF<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &nOpportunisticThresholdDiff);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to Set Opportunistic Threshold diff = %d",
+		  nOpportunisticThresholdDiff);
+
+	sme_set_roam_opportunistic_scan_threshold_diff(hdd_ctx->mac_handle,
+				adapter->session_id,
+				nOpportunisticThresholdDiff);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_opportunistic_rssi_diff(struct hdd_adapter *adapter,
+					       struct hdd_context *hdd_ctx,
+					       uint8_t *command,
+					       uint8_t command_len,
+					       struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	int8_t val = sme_get_roam_opportunistic_scan_threshold_diff(mac_handle);
+	char extra[32];
+	uint8_t len = 0;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_roam_rescan_rssi_diff(struct hdd_adapter *adapter,
+					     struct hdd_context *hdd_ctx,
+					     uint8_t *command,
+					     uint8_t command_len,
+					     struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t nRoamRescanRssiDiff = CFG_ROAM_RESCAN_RSSI_DIFF_DEFAULT;
+
+	/* Move pointer to ahead of SETROAMRESCANRSSIDIFF<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &nRoamRescanRssiDiff);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to Set Roam Rescan RSSI Diff = %d",
+		  nRoamRescanRssiDiff);
+
+	sme_set_roam_rescan_rssi_diff(hdd_ctx->mac_handle,
+				      adapter->session_id,
+				      nRoamRescanRssiDiff);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_roam_rescan_rssi_diff(struct hdd_adapter *adapter,
+					     struct hdd_context *hdd_ctx,
+					     uint8_t *command,
+					     uint8_t command_len,
+					     struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t val = sme_get_roam_rescan_rssi_diff(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len = 0;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_set_fast_roam(struct hdd_adapter *adapter,
+				 struct hdd_context *hdd_ctx,
+				 uint8_t *command,
+				 uint8_t command_len,
+				 struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
+
+	/* Move pointer to ahead of SETFASTROAM<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &lfrMode);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			  CFG_LFR_FEATURE_ENABLED_MIN,
+			  CFG_LFR_FEATURE_ENABLED_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
+	    (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX)) {
+		hdd_err("lfr mode value %d is out of range (Min: %d Max: %d)",
+			  lfrMode,
+			  CFG_LFR_FEATURE_ENABLED_MIN,
+			  CFG_LFR_FEATURE_ENABLED_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to change lfr mode = %d",
+		  lfrMode);
+
+	hdd_ctx->config->isFastRoamIniFeatureEnabled = lfrMode;
+	sme_update_is_fast_roam_ini_feature_enabled(hdd_ctx->mac_handle,
+						    adapter->session_id,
+						    lfrMode);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_set_fast_transition(struct hdd_adapter *adapter,
+				       struct hdd_context *hdd_ctx,
+				       uint8_t *command,
+				       uint8_t command_len,
+				       struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
+
+	/* Move pointer to ahead of SETFASTROAM<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &ft);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			  CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
+			  CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
+	    (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX)) {
+		hdd_err("ft mode value %d is out of range (Min: %d Max: %d)",
+			  ft,
+			  CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
+			  CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to change ft mode = %d", ft);
+
+	hdd_ctx->config->isFastTransitionEnabled = ft;
+	sme_update_fast_transition_enabled(hdd_ctx->mac_handle, ft);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_fast_reassoc(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t channel = 0;
+	tSirMacAddr targetApBssid;
+	uint32_t roamId = INVALID_ROAM_ID;
+	tCsrRoamModifyProfileFields modProfileFields;
+	tCsrHandoffRequest handoffInfo;
+	struct hdd_station_ctx *sta_ctx;
+	mac_handle_t mac_handle;
+
+	if (QDF_STA_MODE != adapter->device_mode) {
+		hdd_warn("Unsupported in mode %s(%d)",
+			 qdf_opmode_str(adapter->device_mode),
+			 adapter->device_mode);
+		return -EINVAL;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	/* if not associated, no need to proceed with reassoc */
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		hdd_warn("Not associated!");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid,
+						&channel);
+	if (ret) {
+		hdd_err("Failed to parse reassoc command data");
+		goto exit;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	/*
+	 * if the target bssid is same as currently associated AP,
+	 * issue reassoc to same AP
+	 */
+	if (!qdf_mem_cmp(targetApBssid,
+				    sta_ctx->conn_info.bssId.bytes,
+				    QDF_MAC_ADDR_SIZE)) {
+		hdd_warn("Reassoc BSSID is same as currently associated AP bssid");
+		if (roaming_offload_enabled(hdd_ctx)) {
+			hdd_wma_send_fastreassoc_cmd(adapter,
+				targetApBssid,
+				sta_ctx->conn_info.operationChannel);
+		} else {
+			sme_get_modify_profile_fields(mac_handle,
+				adapter->session_id,
+				&modProfileFields);
+			sme_roam_reassoc(mac_handle, adapter->session_id,
+				NULL, modProfileFields, &roamId, 1);
+		}
+		return 0;
+	}
+
+	/* Check channel number is a valid channel number */
+	if (channel && (QDF_STATUS_SUCCESS !=
+		wlan_hdd_validate_operation_channel(adapter, channel))) {
+		hdd_err("Invalid Channel [%d]", channel);
+		return -EINVAL;
+	}
+
+	if (roaming_offload_enabled(hdd_ctx)) {
+		hdd_wma_send_fastreassoc_cmd(adapter,
+					targetApBssid, (int)channel);
+		goto exit;
+	}
+	/* Proceed with reassoc */
+	handoffInfo.channel = channel;
+	handoffInfo.src = FASTREASSOC;
+	qdf_mem_copy(handoffInfo.bssid.bytes, targetApBssid,
+		     sizeof(tSirMacAddr));
+	sme_handoff_request(mac_handle, adapter->session_id,
+			    &handoffInfo);
+exit:
+	return ret;
+}
+
+static int drv_cmd_set_roam_scan_control(struct hdd_adapter *adapter,
+					 struct hdd_context *hdd_ctx,
+					 uint8_t *command,
+					 uint8_t command_len,
+					 struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t roamScanControl = 0;
+
+	/* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &roamScanControl);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to Set roam scan control = %d",
+		  roamScanControl);
+
+	if (0 != roamScanControl) {
+		ret = 0; /* return success but ignore param value "true" */
+		goto exit;
+	}
+
+	sme_set_roam_scan_control(hdd_ctx->mac_handle,
+				  adapter->session_id,
+				  roamScanControl);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_set_okc_mode(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint32_t okc_mode;
+	struct pmkid_mode_bits pmkid_modes;
+	mac_handle_t mac_handle;
+	uint32_t cur_pmkid_modes;
+	QDF_STATUS status;
+
+	hdd_get_pmkid_modes(hdd_ctx, &pmkid_modes);
+
+	/*
+	 * Check if the features PMKID/ESE/11R are supported simultaneously,
+	 * then this operation is not permitted (return FAILURE)
+	 */
+	mac_handle = hdd_ctx->mac_handle;
+	if (sme_get_is_ese_feature_enabled(mac_handle) &&
+	    pmkid_modes.fw_okc &&
+	    sme_get_is_ft_feature_enabled(mac_handle)) {
+		hdd_warn("PMKID/ESE/11R are supported simultaneously hence this operation is not permitted!");
+		ret = -EPERM;
+		goto exit;
+	}
+
+	/* Move pointer to ahead of SETOKCMODE<delimiter> */
+	value = value + command_len + 1;
+
+	/* get the current configured value */
+	status = ucfg_mlme_get_pmkid_modes(hdd_ctx->psoc,
+					   &cur_pmkid_modes);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_err("get pmkid modes failed");
+
+	okc_mode = cur_pmkid_modes & CFG_PMKID_MODES_OKC;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou32(value, 10, &okc_mode);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("value out of range [0 - 1]");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((okc_mode < 0) ||
+	    (okc_mode > 1)) {
+		hdd_err("Okc mode value %d is out of range (Min: 0 Max: 1)",
+			  okc_mode);
+		ret = -EINVAL;
+		goto exit;
+	}
+	hdd_debug("Received Command to change okc mode = %d",
+		  okc_mode);
+
+	if (okc_mode)
+		cur_pmkid_modes |= CFG_PMKID_MODES_OKC;
+	else
+		cur_pmkid_modes &= ~CFG_PMKID_MODES_OKC;
+	status = ucfg_mlme_set_pmkid_modes(hdd_ctx->psoc,
+					   cur_pmkid_modes);
+	if (status != QDF_STATUS_SUCCESS) {
+		ret = -EPERM;
+		hdd_err("set pmkid modes failed");
+	}
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_roam_scan_control(struct hdd_adapter *adapter,
+					 struct hdd_context *hdd_ctx,
+					 uint8_t *command,
+					 uint8_t command_len,
+					 struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	bool roamScanControl = sme_get_roam_scan_control(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len = 0;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d",
+			command, roamScanControl);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_bt_coex_mode(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	char *bcMode;
+
+	bcMode = command + 11;
+	if ('1' == *bcMode) {
+		hdd_debug("BTCOEXMODE %d", *bcMode);
+		hdd_ctx->bt_coex_mode_set = true;
+		ret = wlan_hdd_scan_abort(adapter);
+		if (ret < 0) {
+			hdd_err("Failed to abort existing scan status: %d",
+				ret);
+		}
+	} else if ('2' == *bcMode) {
+		hdd_debug("BTCOEXMODE %d", *bcMode);
+		hdd_ctx->bt_coex_mode_set = false;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_scan_active(struct hdd_adapter *adapter,
+			       struct hdd_context *hdd_ctx,
+			       uint8_t *command,
+			       uint8_t command_len,
+			       struct hdd_priv_data *priv_data)
+{
+	hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
+	return 0;
+}
+
+static int drv_cmd_scan_passive(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	hdd_ctx->ioctl_scan_mode = eSIR_PASSIVE_SCAN;
+	return 0;
+}
+
+static int drv_cmd_get_dwell_time(struct hdd_adapter *adapter,
+				  struct hdd_context *hdd_ctx,
+				  uint8_t *command,
+				  uint8_t command_len,
+				  struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	struct hdd_config *pCfg =
+		(WLAN_HDD_GET_CTX(adapter))->config;
+	char extra[32];
+	uint8_t len = 0;
+
+	memset(extra, 0, sizeof(extra));
+	ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (ret != 0 || copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+		goto exit;
+	}
+	ret = len;
+exit:
+	return ret;
+}
+
+static int drv_cmd_set_dwell_time(struct hdd_adapter *adapter,
+				  struct hdd_context *hdd_ctx,
+				  uint8_t *command,
+				  uint8_t command_len,
+				  struct hdd_priv_data *priv_data)
+{
+	return hdd_set_dwell_time(adapter, command);
+}
+
+#ifdef WLAN_AP_STA_CONCURRENCY
+static int drv_cmd_conc_set_dwell_time(hdd_adapter_t *adapter,
+				       hdd_context_t *hdd_ctx,
+				       u8 *command,
+				       u8 command_len,
+				       hdd_priv_data_t *priv_data)
+{
+	return hdd_conc_set_dwell_time(hdd_ctx, command);
+}
+#endif
+
+static int drv_cmd_miracast(struct hdd_adapter *adapter,
+			    struct hdd_context *hdd_ctx,
+			    uint8_t *command,
+			    uint8_t command_len,
+			    struct hdd_priv_data *priv_data)
+{
+	QDF_STATUS ret_status;
+	int ret = 0;
+	uint8_t filterType = 0;
+	uint8_t *value;
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	value = command + 9;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &filterType);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range");
+		ret = -EINVAL;
+		goto exit;
+	}
+	if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL)
+	    || (filterType >
+		WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL)) {
+		hdd_err("Accepted Values are 0 to 2. 0-Disabled, 1-Source, 2-Sink");
+		ret = -EINVAL;
+		goto exit;
+	}
+	/* Filtertype value should be either 0-Disabled, 1-Source, 2-sink */
+	hdd_ctx->miracast_value = filterType;
+
+	ret_status = sme_set_miracast(hdd_ctx->mac_handle, filterType);
+	if (QDF_STATUS_SUCCESS != ret_status) {
+		hdd_err("Failed to set miracast");
+		return -EBUSY;
+	}
+	ret_status = ucfg_scan_set_miracast(hdd_ctx->psoc,
+					    filterType ? true : false);
+	if (QDF_IS_STATUS_ERROR(ret_status)) {
+		hdd_err("Failed to set miracastn scan");
+		return -EBUSY;
+	}
+
+	if (policy_mgr_is_mcc_in_24G(hdd_ctx->psoc))
+		return wlan_hdd_set_mas(adapter, filterType);
+
+exit:
+	return ret;
+}
+
+/* Function header is left blank intentionally */
+static int hdd_parse_set_ibss_oui_data_command(uint8_t *command, uint8_t *ie,
+					int32_t *oui_length, int32_t limit)
+{
+	uint8_t len;
+	uint8_t data;
+
+	while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command)) {
+		command++;
+		limit--;
+	}
+
+	len = 2;
+
+	while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
+		(limit > 1)) {
+		sscanf(command, "%02x", (unsigned int *)&data);
+		ie[len++] = data;
+		command += 2;
+		limit -= 2;
+	}
+
+	*oui_length = len - 2;
+
+	while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command)) {
+		command++;
+		limit--;
+	}
+
+	while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
+		(limit > 1)) {
+		sscanf(command, "%02x", (unsigned int *)&data);
+		ie[len++] = data;
+		command += 2;
+		limit -= 2;
+	}
+
+	ie[0] = IE_EID_VENDOR;
+	ie[1] = len - 2;
+
+	return len;
+}
+
+/**
+ * drv_cmd_set_ibss_beacon_oui_data() - set ibss oui data command
+ * @adapter: Pointer to adapter
+ * @hdd_ctx: Pointer to HDD context
+ * @command: Pointer to command string
+ * @command_len : Command length
+ * @priv_data : Pointer to priv data
+ *
+ * Return:
+ *      int status code
+ */
+static int drv_cmd_set_ibss_beacon_oui_data(struct hdd_adapter *adapter,
+					    struct hdd_context *hdd_ctx,
+					    uint8_t *command,
+					    uint8_t command_len,
+					    struct hdd_priv_data *priv_data)
+{
+	int i = 0;
+	int status;
+	int ret = 0;
+	uint8_t *ibss_ie;
+	int32_t oui_length = 0;
+	uint32_t ibss_ie_length;
+	uint8_t *value = command;
+	tSirModifyIE ibssModifyIE;
+	struct csr_roam_profile *roam_profile;
+	mac_handle_t mac_handle;
+
+	if (QDF_IBSS_MODE != adapter->device_mode) {
+		hdd_debug("Device_mode %s(%d) not IBSS",
+			  qdf_opmode_str(adapter->device_mode),
+			  adapter->device_mode);
+		return ret;
+	}
+
+	hdd_debug("received command %s", ((char *)value));
+
+	/* validate argument of command */
+	if (strlen(value) <= command_len) {
+		hdd_err("No arguments in command length %zu",
+			 strlen(value));
+		ret = -EFAULT;
+		goto exit;
+	}
+
+	/* moving to arguments of commands */
+	value = value + command_len;
+	command_len = strlen(value);
+
+	/* oui_data can't be less than 3 bytes */
+	if (command_len < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
+		hdd_err("Invalid SETIBSSBEACONOUIDATA command length %d",
+			 command_len);
+		ret = -EFAULT;
+		goto exit;
+	}
+
+	ibss_ie = qdf_mem_malloc(command_len);
+	if (!ibss_ie) {
+		hdd_err("Could not allocate memory for command length %d",
+			 command_len);
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
+							     &oui_length,
+							     command_len);
+	if (ibss_ie_length <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
+		hdd_err("Could not parse command %s return length %d",
+			 value, ibss_ie_length);
+		ret = -EFAULT;
+		qdf_mem_free(ibss_ie);
+		goto exit;
+	}
+
+	roam_profile = hdd_roam_profile(adapter);
+
+	qdf_copy_macaddr(&ibssModifyIE.bssid,
+		     roam_profile->BSSIDs.bssid);
+
+	ibssModifyIE.smeSessionId = adapter->session_id;
+	ibssModifyIE.notify = true;
+	ibssModifyIE.ieID = IE_EID_VENDOR;
+	ibssModifyIE.ieIDLen = ibss_ie_length;
+	ibssModifyIE.ieBufferlength = ibss_ie_length;
+	ibssModifyIE.pIEBuffer = ibss_ie;
+	ibssModifyIE.oui_length = oui_length;
+
+	hdd_warn("ibss_ie length %d oui_length %d ibss_ie:",
+		 ibss_ie_length, oui_length);
+	while (i < ibssModifyIE.ieBufferlength)
+		hdd_warn("0x%x", ibss_ie[i++]);
+
+	/* Probe Bcn modification */
+	mac_handle = hdd_ctx->mac_handle;
+	sme_modify_add_ie(mac_handle, &ibssModifyIE, eUPDATE_IE_PROBE_BCN);
+
+	/* Populating probe resp frame */
+	sme_modify_add_ie(mac_handle, &ibssModifyIE, eUPDATE_IE_PROBE_RESP);
+
+	qdf_mem_free(ibss_ie);
+
+	status = sme_send_cesium_enable_ind(mac_handle,
+					    adapter->session_id);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Could not send cesium enable indication %d",
+			  status);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_RMC
+/* Function header is left blank intentionally */
+static int hdd_parse_setrmcenable_command(uint8_t *pValue,
+					  uint8_t *pRmcEnable)
+{
+	uint8_t *inPtr = pValue;
+	int tempInt;
+	int v = 0;
+	char buf[32];
+	*pRmcEnable = 0;
+
+	inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+
+	if (NULL == inPtr)
+		return 0;
+	else if (SPACE_ASCII_VALUE != *inPtr)
+		return 0;
+
+	while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr))
+		inPtr++;
+
+	if ('\0' == *inPtr)
+		return 0;
+
+	v = sscanf(inPtr, "%31s ", buf);
+	if (1 != v)
+		return -EINVAL;
+
+	v = kstrtos32(buf, 10, &tempInt);
+	if (v < 0)
+		return -EINVAL;
+
+	*pRmcEnable = tempInt;
+
+	hdd_debug("ucRmcEnable: %d", *pRmcEnable);
+
+	return 0;
+}
+
+/* Function header is left blank intentionally */
+static int hdd_parse_setrmcactionperiod_command(uint8_t *pValue,
+						uint32_t *pActionPeriod)
+{
+	uint8_t *inPtr = pValue;
+	int tempInt;
+	int v = 0;
+	char buf[32];
+	*pActionPeriod = 0;
+
+	inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+
+	if (NULL == inPtr)
+		return -EINVAL;
+	else if (SPACE_ASCII_VALUE != *inPtr)
+		return -EINVAL;
+
+	while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr))
+		inPtr++;
+
+	if ('\0' == *inPtr)
+		return 0;
+
+	v = sscanf(inPtr, "%31s ", buf);
+	if (1 != v)
+		return -EINVAL;
+
+	v = kstrtos32(buf, 10, &tempInt);
+	if (v < 0)
+		return -EINVAL;
+
+	if ((tempInt < cfg_min(CFG_RMC_ACTION_PERIOD_FREQUENCY)) ||
+	    (tempInt > cfg_max(CFG_RMC_ACTION_PERIOD_FREQUENCY)))
+		return -EINVAL;
+
+	*pActionPeriod = tempInt;
+
+	hdd_debug("uActionPeriod: %d", *pActionPeriod);
+
+	return 0;
+}
+
+/* Function header is left blank intentionally */
+static int hdd_parse_setrmcrate_command(uint8_t *pValue,
+					uint32_t *pRate,
+					enum tx_rate_info *pTxFlags)
+{
+	uint8_t *inPtr = pValue;
+	int tempInt;
+	int v = 0;
+	char buf[32];
+	*pRate = 0;
+	*pTxFlags = 0;
+
+	inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
+
+	if (NULL == inPtr)
+		return -EINVAL;
+	else if (SPACE_ASCII_VALUE != *inPtr)
+		return -EINVAL;
+
+	while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr))
+		inPtr++;
+
+	if ('\0' == *inPtr)
+		return 0;
+
+	v = sscanf(inPtr, "%31s ", buf);
+	if (1 != v)
+		return -EINVAL;
+
+	v = kstrtos32(buf, 10, &tempInt);
+	if (v < 0)
+		return -EINVAL;
+
+	switch (tempInt) {
+	default:
+		hdd_warn("Unsupported rate: %d", tempInt);
+		return -EINVAL;
+	case 0:
+	case 6:
+	case 9:
+	case 12:
+	case 18:
+	case 24:
+	case 36:
+	case 48:
+	case 54:
+		*pTxFlags = TX_RATE_LEGACY;
+		*pRate = tempInt * 10;
+		break;
+	case 65:
+		*pTxFlags = TX_RATE_HT20;
+		*pRate = tempInt * 10;
+		break;
+	case 72:
+		*pTxFlags = TX_RATE_HT20 | TX_RATE_SGI;
+		*pRate = 722;
+		break;
+	}
+
+	hdd_debug("Rate: %d", *pRate);
+
+	return 0;
+}
+
+static int drv_cmd_set_rmc_enable(struct hdd_adapter *adapter,
+				  struct hdd_context *hdd_ctx,
+				  uint8_t *command,
+				  uint8_t command_len,
+				  struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t ucRmcEnable = 0;
+	int status;
+	mac_handle_t mac_handle;
+
+	if ((QDF_IBSS_MODE != adapter->device_mode) &&
+	    (QDF_SAP_MODE != adapter->device_mode)) {
+		hdd_err("Received SETRMCENABLE cmd in invalid mode %s(%d)",
+			qdf_opmode_str(adapter->device_mode),
+			adapter->device_mode);
+		hdd_err("SETRMCENABLE cmd is allowed only in IBSS/SOFTAP mode");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
+	if (status) {
+		hdd_err("Invalid SETRMCENABLE command");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("ucRmcEnable %d", ucRmcEnable);
+	mac_handle = hdd_ctx->mac_handle;
+
+	if (true == ucRmcEnable) {
+		status = sme_enable_rmc(mac_handle, adapter->session_id);
+	} else if (false == ucRmcEnable) {
+		status = sme_disable_rmc(mac_handle, adapter->session_id);
+	} else {
+		hdd_err("Invalid SETRMCENABLE command %d", ucRmcEnable);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("SETRMC %d failed status %d", ucRmcEnable, status);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_set_rmc_action_period(struct hdd_adapter *adapter,
+					 struct hdd_context *hdd_ctx,
+					 uint8_t *command,
+					 uint8_t command_len,
+					 struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint32_t uActionPeriod = 0;
+	int status;
+	mac_handle_t mac_handle;
+
+	if ((QDF_IBSS_MODE != adapter->device_mode) &&
+	    (QDF_SAP_MODE != adapter->device_mode)) {
+		hdd_err("Received SETRMC cmd in invalid mode %s(%d)",
+			qdf_opmode_str(adapter->device_mode),
+			adapter->device_mode);
+		hdd_err("SETRMC cmd is allowed only in IBSS/SOFTAP mode");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
+	if (status) {
+		hdd_err("Invalid SETRMCACTIONPERIOD command");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("uActionPeriod %d", uActionPeriod);
+	mac_handle = hdd_ctx->mac_handle;
+
+	if (ucfg_mlme_set_rmc_action_period_freq(hdd_ctx->psoc,
+						 uActionPeriod) !=
+						 QDF_STATUS_SUCCESS) {
+		hdd_err("Could not set SETRMCACTIONPERIOD %d", uActionPeriod);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	status = sme_send_rmc_action_period(mac_handle,
+					    adapter->session_id);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Could not send cesium enable indication %d",
+			  status);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_set_rmc_tx_rate(struct hdd_adapter *adapter,
+				   struct hdd_context *hdd_ctx,
+				   uint8_t *command,
+				   uint8_t command_len,
+				   struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint32_t uRate = 0;
+	enum tx_rate_info txFlags = 0;
+	tSirRateUpdateInd rateUpdateParams = {0};
+	int status;
+	bool bval = false;
+
+	if ((QDF_IBSS_MODE != adapter->device_mode) &&
+	    (QDF_SAP_MODE != adapter->device_mode)) {
+		hdd_err("Received SETRMCTXRATE cmd in invalid mode %s(%d)",
+			qdf_opmode_str(adapter->device_mode),
+			adapter->device_mode);
+		hdd_err("SETRMCTXRATE cmd is allowed only in IBSS/SOFTAP mode");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
+	if (status) {
+		hdd_err("Invalid SETRMCTXRATE command");
+		ret = -EINVAL;
+		goto exit;
+	}
+	hdd_debug("uRate %d", uRate);
+	/* -1 implies ignore this param */
+	rateUpdateParams.ucastDataRate = -1;
+
+	/*
+	 * Fill the user specifieed RMC rate param
+	 * and the derived tx flags.
+	 */
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("unable to get vht_enable2x2");
+		ret = -EINVAL;
+		goto exit;
+	}
+	rateUpdateParams.nss = (bval == 0) ? 0 : 1;
+	rateUpdateParams.reliableMcastDataRate = uRate;
+	rateUpdateParams.reliableMcastDataRateTxFlag = txFlags;
+	rateUpdateParams.dev_mode = adapter->device_mode;
+	rateUpdateParams.bcastDataRate = -1;
+	memcpy(rateUpdateParams.bssid.bytes,
+	       adapter->mac_addr.bytes,
+	       sizeof(rateUpdateParams.bssid));
+	status = sme_send_rate_update_ind(hdd_ctx->mac_handle,
+					  &rateUpdateParams);
+
+exit:
+	return ret;
+}
+#endif /* FEATURE_WLAN_RMC */
+
+static int drv_cmd_get_ibss_peer_info_all(struct hdd_adapter *adapter,
+					  struct hdd_context *hdd_ctx,
+					  uint8_t *command,
+					  uint8_t command_len,
+					  struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	int status = QDF_STATUS_SUCCESS;
+	struct hdd_station_ctx *sta_ctx = NULL;
+	char *extra = NULL;
+	int idx = 0;
+	int length = 0;
+	uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
+	uint32_t numOfBytestoPrint = 0;
+
+	if (QDF_IBSS_MODE != adapter->device_mode) {
+		hdd_warn("Unsupported in mode %s(%d)",
+			 qdf_opmode_str(adapter->device_mode),
+			 adapter->device_mode);
+		return -EINVAL;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	hdd_debug("Received GETIBSSPEERINFOALL Command");
+
+	/* Handle the command */
+	status = hdd_cfg80211_get_ibss_peer_info_all(adapter);
+	if (QDF_STATUS_SUCCESS == status) {
+		size_t user_size = qdf_min(WLAN_MAX_BUF_SIZE,
+					   priv_data->total_len);
+
+		/*
+		 * The variable extra needed to be allocated on the heap since
+		 * amount of memory required to copy the data for 32 devices
+		 * exceeds the size of 1024 bytes of default stack size. On
+		 * 64 bit devices, the default max stack size of 2048 bytes
+		 */
+		extra = qdf_mem_malloc(user_size);
+
+		if (NULL == extra) {
+			hdd_err("memory allocation failed");
+			ret = -ENOMEM;
+			goto exit;
+		}
+
+		/* Copy number of stations */
+		length = scnprintf(extra, user_size, "%d ",
+				   sta_ctx->ibss_peer_info.numPeers);
+		numOfBytestoPrint = length;
+		for (idx = 0; idx < sta_ctx->ibss_peer_info.numPeers;
+								idx++) {
+			int8_t rssi;
+			uint32_t tx_rate;
+
+			qdf_mem_copy(mac_addr,
+				sta_ctx->ibss_peer_info.peerInfoParams[idx].
+				mac_addr, sizeof(mac_addr));
+
+			tx_rate =
+				sta_ctx->ibss_peer_info.peerInfoParams[idx].
+									txRate;
+			/*
+			 * Only lower 3 bytes are rate info. Mask of the MSByte
+			 */
+			tx_rate &= 0x00FFFFFF;
+
+			rssi = sta_ctx->ibss_peer_info.peerInfoParams[idx].
+									rssi;
+
+			length += scnprintf(extra + length,
+				user_size - length,
+				"%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
+				mac_addr[0], mac_addr[1], mac_addr[2],
+				mac_addr[3], mac_addr[4], mac_addr[5],
+				tx_rate, rssi);
+			/*
+			 * cdf_trace_msg has limitation of 512 bytes for the
+			 * print buffer. Hence printing the data in two chunks.
+			 * The first chunk will have the data for 16 devices
+			 * and the second chunk will have the rest.
+			 */
+			if (idx < NUM_OF_STA_DATA_TO_PRINT)
+				numOfBytestoPrint = length;
+		}
+
+		/*
+		 * Copy the data back into buffer, if the data to copy is
+		 * more than 512 bytes than we will split the data and do
+		 * it in two shots
+		 */
+		if (copy_to_user(priv_data->buf, extra, numOfBytestoPrint)) {
+			hdd_err("Copy into user data buffer failed");
+			ret = -EFAULT;
+			goto mem_free;
+		}
+
+		/* This overwrites the last space, which we already copied */
+		extra[numOfBytestoPrint - 1] = '\0';
+		hdd_debug("%s", extra);
+
+		if (length > numOfBytestoPrint) {
+			if (copy_to_user
+				    (priv_data->buf + numOfBytestoPrint,
+				    extra + numOfBytestoPrint,
+				    length - numOfBytestoPrint + 1)) {
+				hdd_err("Copy into user data buffer failed");
+				ret = -EFAULT;
+				goto mem_free;
+			}
+			hdd_debug("%s", &extra[numOfBytestoPrint]);
+		}
+	} else {
+		/* Command failed, log error */
+		hdd_err("GETIBSSPEERINFOALL command failed with status code %d",
+			  status);
+		ret = -EINVAL;
+		goto exit;
+	}
+	ret = 0;
+
+mem_free:
+	qdf_mem_free(extra);
+exit:
+	return ret;
+}
+
+/* Peer Info <Peer Addr> command */
+static int drv_cmd_get_ibss_peer_info(struct hdd_adapter *adapter,
+				      struct hdd_context *hdd_ctx,
+				      uint8_t *command,
+				      uint8_t command_len,
+				      struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	QDF_STATUS status;
+	struct hdd_station_ctx *sta_ctx = NULL;
+	char extra[128] = { 0 };
+	uint32_t length = 0;
+	uint8_t staIdx = 0;
+	struct qdf_mac_addr peerMacAddr;
+
+	if (QDF_IBSS_MODE != adapter->device_mode) {
+		hdd_warn("Unsupported in mode %s(%d)",
+			 qdf_opmode_str(adapter->device_mode),
+			 adapter->device_mode);
+		return -EINVAL;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	hdd_debug("Received GETIBSSPEERINFO Command");
+
+	/* if there are no peers, no need to continue with the command */
+	if (eConnectionState_IbssConnected !=
+	    sta_ctx->conn_info.connState) {
+		hdd_err("No IBSS Peers coalesced");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Parse the incoming command buffer */
+	status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Invalid GETIBSSPEERINFO command");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Get station index for the peer mac address and sanitize it */
+	hdd_get_peer_sta_id(sta_ctx, &peerMacAddr, &staIdx);
+
+	if (staIdx > MAX_PEERS) {
+		hdd_err("Invalid StaIdx %d returned", staIdx);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Handle the command */
+	status = hdd_cfg80211_get_ibss_peer_info(adapter, staIdx);
+	if (QDF_STATUS_SUCCESS == status) {
+		uint32_t txRate =
+			sta_ctx->ibss_peer_info.peerInfoParams[0].txRate;
+		/* Only lower 3 bytes are rate info. Mask of the MSByte */
+		txRate &= 0x00FFFFFF;
+
+		length = scnprintf(extra, sizeof(extra), "%d %d",
+				(int)txRate,
+				(int)sta_ctx->ibss_peer_info.
+				peerInfoParams[0].rssi);
+
+		/* Copy the data back into buffer */
+		if (copy_to_user(priv_data->buf, &extra, length + 1)) {
+			hdd_err("copy data to user buffer failed GETIBSSPEERINFO command");
+			ret = -EFAULT;
+			goto exit;
+		}
+	} else {
+		/* Command failed, log error */
+		hdd_err("GETIBSSPEERINFO command failed with status code %d",
+			  status);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Success ! */
+	hdd_debug("%s", extra);
+	ret = 0;
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_set_ibss_tx_fail_event(struct hdd_adapter *adapter,
+					  struct hdd_context *hdd_ctx,
+					  uint8_t *command,
+					  uint8_t command_len,
+					  struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	char *value;
+	uint8_t tx_fail_count = 0;
+	uint16_t pid = 0;
+	mac_handle_t mac_handle;
+
+	value = command;
+
+	ret = hdd_parse_ibsstx_fail_event_params(value, &tx_fail_count, &pid);
+
+	if (0 != ret) {
+		hdd_err("Failed to parse SETIBSSTXFAILEVENT arguments");
+		goto exit;
+	}
+
+	hdd_debug("tx_fail_cnt=%hhu, pid=%hu", tx_fail_count, pid);
+	mac_handle = hdd_ctx->mac_handle;
+
+	if (0 == tx_fail_count) {
+		/* Disable TX Fail Indication */
+		if (QDF_STATUS_SUCCESS ==
+		    sme_tx_fail_monitor_start_stop_ind(mac_handle,
+						       tx_fail_count,
+						       NULL)) {
+			cesium_pid = 0;
+		} else {
+			hdd_err("failed to disable TX Fail Event");
+			ret = -EINVAL;
+		}
+	} else {
+		if (QDF_STATUS_SUCCESS ==
+		    sme_tx_fail_monitor_start_stop_ind(mac_handle,
+				tx_fail_count,
+				(void *)hdd_tx_fail_ind_callback)) {
+			cesium_pid = pid;
+			hdd_debug("Registered Cesium pid %u",
+				  cesium_pid);
+		} else {
+			hdd_err("Failed to enable TX Fail Monitoring");
+			ret = -EINVAL;
+		}
+	}
+
+exit:
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_ESE
+static int drv_cmd_set_ccx_roam_scan_channels(struct hdd_adapter *adapter,
+					      struct hdd_context *hdd_ctx,
+					      uint8_t *command,
+					      uint8_t command_len,
+					      struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
+	uint8_t numChannels = 0;
+	QDF_STATUS status;
+	mac_handle_t mac_handle;
+
+	ret = hdd_parse_channellist(value, ChannelList, &numChannels);
+	if (ret) {
+		hdd_err("Failed to parse channel list information");
+		goto exit;
+	}
+	if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		hdd_err("number of channels (%d) supported exceeded max (%d)",
+			  numChannels,
+			  WNI_CFG_VALID_CHANNEL_LIST_LEN);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!sme_validate_channel_list(mac_handle, ChannelList, numChannels)) {
+		hdd_err("List contains invalid channel(s)");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	status = sme_set_ese_roam_scan_channel_list(mac_handle,
+						    adapter->session_id,
+						    ChannelList,
+						    numChannels);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Failed to update channel list information");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_tsm_stats(struct hdd_adapter *adapter,
+				 struct hdd_context *hdd_ctx,
+				 uint8_t *command,
+				 uint8_t command_len,
+				 struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	char extra[128] = { 0 };
+	int len = 0;
+	uint8_t tid = 0;
+	struct hdd_station_ctx *sta_ctx;
+	tAniTrafStrmMetrics tsm_metrics = {0};
+
+	if ((QDF_STA_MODE != adapter->device_mode) &&
+	    (QDF_P2P_CLIENT_MODE != adapter->device_mode)) {
+		hdd_warn("Unsupported in mode %s(%d)",
+			 qdf_opmode_str(adapter->device_mode),
+			 adapter->device_mode);
+		return -EINVAL;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	/* if not associated, return error */
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		hdd_err("Not associated!");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Move pointer to ahead of GETTSMSTATS<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &tid);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			  TID_MIN_VALUE,
+			  TID_MAX_VALUE);
+		ret = -EINVAL;
+		goto exit;
+	}
+	if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE)) {
+		hdd_err("tid value %d is out of range (Min: %d Max: %d)",
+			  tid, TID_MIN_VALUE, TID_MAX_VALUE);
+		ret = -EINVAL;
+		goto exit;
+	}
+	hdd_debug("Received Command to get tsm stats tid = %d",
+		 tid);
+	ret = hdd_get_tsm_stats(adapter, tid, &tsm_metrics);
+	if (ret) {
+		hdd_err("failed to get tsm stats");
+		goto exit;
+	}
+	hdd_debug(
+		"UplinkPktQueueDly(%d) UplinkPktQueueDlyHist[0](%d) UplinkPktQueueDlyHist[1](%d) UplinkPktQueueDlyHist[2](%d) UplinkPktQueueDlyHist[3](%d) UplinkPktTxDly(%u) UplinkPktLoss(%d) UplinkPktCount(%d) RoamingCount(%d) RoamingDly(%d)",
+		  tsm_metrics.UplinkPktQueueDly,
+		  tsm_metrics.UplinkPktQueueDlyHist[0],
+		  tsm_metrics.UplinkPktQueueDlyHist[1],
+		  tsm_metrics.UplinkPktQueueDlyHist[2],
+		  tsm_metrics.UplinkPktQueueDlyHist[3],
+		  tsm_metrics.UplinkPktTxDly,
+		  tsm_metrics.UplinkPktLoss,
+		  tsm_metrics.UplinkPktCount,
+		  tsm_metrics.RoamingCount,
+		  tsm_metrics.RoamingDly);
+	/*
+	 * Output TSM stats is of the format
+	 * GETTSMSTATS [PktQueueDly]
+	 * [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
+	 * eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800
+	 */
+	len = scnprintf(extra,
+			sizeof(extra),
+			"%s %d %d:%d:%d:%d %u %d %d %d %d",
+			command,
+			tsm_metrics.UplinkPktQueueDly,
+			tsm_metrics.UplinkPktQueueDlyHist[0],
+			tsm_metrics.UplinkPktQueueDlyHist[1],
+			tsm_metrics.UplinkPktQueueDlyHist[2],
+			tsm_metrics.UplinkPktQueueDlyHist[3],
+			tsm_metrics.UplinkPktTxDly,
+			tsm_metrics.UplinkPktLoss,
+			tsm_metrics.UplinkPktCount,
+			tsm_metrics.RoamingCount,
+			tsm_metrics.RoamingDly);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+		goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_set_cckm_ie(struct hdd_adapter *adapter,
+			       struct hdd_context *hdd_ctx,
+			       uint8_t *command,
+			       uint8_t command_len,
+			       struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint8_t *value = command;
+	uint8_t *cckmIe = NULL;
+	uint8_t cckmIeLen = 0;
+
+	ret = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
+	if (ret) {
+		hdd_err("Failed to parse cckm ie data");
+		goto exit;
+	}
+
+	if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN) {
+		hdd_err("CCKM Ie input length is more than max[%d]",
+			  DOT11F_IE_RSN_MAX_LEN);
+		if (NULL != cckmIe) {
+			qdf_mem_free(cckmIe);
+			cckmIe = NULL;
+		}
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	sme_set_cckm_ie(hdd_ctx->mac_handle, adapter->session_id,
+			cckmIe, cckmIeLen);
+	if (NULL != cckmIe) {
+		qdf_mem_free(cckmIe);
+		cckmIe = NULL;
+	}
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_ccx_beacon_req(struct hdd_adapter *adapter,
+				  struct hdd_context *hdd_ctx,
+				  uint8_t *command,
+				  uint8_t command_len,
+				  struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint8_t *value = command;
+	tCsrEseBeaconReq eseBcnReq = {0};
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (QDF_STA_MODE != adapter->device_mode) {
+		hdd_warn("Unsupported in mode %s(%d)",
+			 qdf_opmode_str(adapter->device_mode),
+			 adapter->device_mode);
+		return -EINVAL;
+	}
+
+	ret = hdd_parse_ese_beacon_req(value, &eseBcnReq);
+	if (ret) {
+		hdd_err("Failed to parse ese beacon req");
+		goto exit;
+	}
+
+	if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
+		hdd_debug("Not associated");
+
+		if (!eseBcnReq.numBcnReqIe)
+			return -EINVAL;
+
+		hdd_indicate_ese_bcn_report_no_results(adapter,
+			eseBcnReq.bcnReq[0].measurementToken,
+			0x02, /* BIT(1) set for measurement done */
+			0);   /* no BSS */
+		goto exit;
+	}
+
+	status = sme_set_ese_beacon_request(hdd_ctx->mac_handle,
+					    adapter->session_id,
+					    &eseBcnReq);
+
+	if (QDF_STATUS_E_RESOURCES == status) {
+		hdd_err("sme_set_ese_beacon_request failed (%d), a request already in progress",
+			  status);
+		ret = -EBUSY;
+		goto exit;
+	} else if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("sme_set_ese_beacon_request failed (%d)",
+			status);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+/**
+ * drv_cmd_ccx_plm_req() - Set ESE PLM request
+ * @adapter:     Pointer to the HDD adapter
+ * @hdd_ctx:     Pointer to the HDD context
+ * @command:     Driver command string
+ * @command_len: Driver command string length
+ * @priv_data:   Private data coming with the driver command. Unused here
+ *
+ * This function handles driver command that sets the ESE PLM request
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+static int drv_cmd_ccx_plm_req(struct hdd_adapter *adapter,
+			       struct hdd_context *hdd_ctx,
+			       uint8_t *command,
+			       uint8_t command_len,
+			       struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpSirPlmReq pPlmRequest = NULL;
+
+	pPlmRequest = qdf_mem_malloc(sizeof(tSirPlmReq));
+	if (NULL == pPlmRequest) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	status = hdd_parse_plm_cmd(value, pPlmRequest);
+	if (QDF_STATUS_SUCCESS != status) {
+		qdf_mem_free(pPlmRequest);
+		pPlmRequest = NULL;
+		ret = -EINVAL;
+		goto exit;
+	}
+	pPlmRequest->sessionId = adapter->session_id;
+
+	status = sme_set_plm_request(hdd_ctx->mac_handle, pPlmRequest);
+	if (QDF_STATUS_SUCCESS != status) {
+		qdf_mem_free(pPlmRequest);
+		pPlmRequest = NULL;
+		ret = -EINVAL;
+		goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+/**
+ * drv_cmd_set_ccx_mode() - Set ESE mode
+ * @adapter:     Pointer to the HDD adapter
+ * @hdd_ctx:     Pointer to the HDD context
+ * @command:     Driver command string
+ * @command_len: Driver command string length
+ * @priv_data:   Private data coming with the driver command. Unused here
+ *
+ * This function handles driver command that sets ESE mode
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+static int drv_cmd_set_ccx_mode(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
+	struct pmkid_mode_bits pmkid_modes;
+	mac_handle_t mac_handle;
+
+	hdd_get_pmkid_modes(hdd_ctx, &pmkid_modes);
+	mac_handle = hdd_ctx->mac_handle;
+	/*
+	 * Check if the features OKC/ESE/11R are supported simultaneously,
+	 * then this operation is not permitted (return FAILURE)
+	 */
+	if (sme_get_is_ese_feature_enabled(mac_handle) &&
+	    pmkid_modes.fw_okc &&
+	    sme_get_is_ft_feature_enabled(mac_handle)) {
+		hdd_warn("OKC/ESE/11R are supported simultaneously hence this operation is not permitted!");
+		ret = -EPERM;
+		goto exit;
+	}
+
+	/* Move pointer to ahead of SETCCXMODE<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &eseMode);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			  CFG_ESE_FEATURE_ENABLED_MIN,
+			  CFG_ESE_FEATURE_ENABLED_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
+	    (eseMode > CFG_ESE_FEATURE_ENABLED_MAX)) {
+		hdd_err("Ese mode value %d is out of range (Min: %d Max: %d)",
+			  eseMode,
+			  CFG_ESE_FEATURE_ENABLED_MIN,
+			  CFG_ESE_FEATURE_ENABLED_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+	hdd_debug("Received Command to change ese mode = %d", eseMode);
+
+	hdd_ctx->config->isEseIniFeatureEnabled = eseMode;
+	sme_update_is_ese_feature_enabled(mac_handle,
+					  adapter->session_id,
+					  eseMode);
+
+exit:
+	return ret;
+}
+#endif /* FEATURE_WLAN_ESE */
+
+static int drv_cmd_set_mc_rate(struct hdd_adapter *adapter,
+			       struct hdd_context *hdd_ctx,
+			       uint8_t *command,
+			       uint8_t command_len,
+			       struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	int target_rate = 0;
+
+	/* input value is in units of hundred kbps */
+
+	/* Move pointer to ahead of SETMCRATE<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer, decimal base */
+	ret = kstrtouint(value, 10, &target_rate);
+
+	ret = wlan_hdd_set_mc_rate(adapter, target_rate);
+	return ret;
+}
+
+static int drv_cmd_max_tx_power(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	int ret;
+	int tx_power;
+	QDF_STATUS status;
+	uint8_t *value = command;
+	struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT;
+	struct qdf_mac_addr selfmac = QDF_MAC_ADDR_BCAST_INIT;
+
+	ret = hdd_parse_setmaxtxpower_command(value, &tx_power);
+	if (ret) {
+		hdd_err("Invalid MAXTXPOWER command");
+		return ret;
+	}
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		/* Assign correct self MAC address */
+		qdf_copy_macaddr(&bssid,
+				 &adapter->mac_addr);
+		qdf_copy_macaddr(&selfmac,
+				 &adapter->mac_addr);
+
+		hdd_debug("Device mode %d max tx power %d selfMac: "
+			  MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR,
+			  adapter->device_mode, tx_power,
+			  MAC_ADDR_ARRAY(selfmac.bytes),
+			  MAC_ADDR_ARRAY(bssid.bytes));
+
+		status = sme_set_max_tx_power(hdd_ctx->mac_handle,
+					      bssid, selfmac, tx_power);
+		if (QDF_STATUS_SUCCESS != status) {
+			hdd_err("Set max tx power failed");
+			ret = -EINVAL;
+			goto exit;
+		}
+		hdd_debug("Set max tx power success");
+	}
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_set_dfs_scan_mode(struct hdd_adapter *adapter,
+				    struct hdd_context *hdd_ctx,
+				    uint8_t *command,
+				    uint8_t command_len,
+				    struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t *value = command;
+	uint8_t dfsScanMode = CFG_ROAMING_DFS_CHANNEL_DEFAULT;
+
+	/* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
+	value = value + command_len + 1;
+
+	/* Convert the value from ascii to integer */
+	ret = kstrtou8(value, 10, &dfsScanMode);
+	if (ret < 0) {
+		/*
+		 * If the input value is greater than max value of datatype,
+		 * then also kstrtou8 fails
+		 */
+		hdd_err("kstrtou8 failed range [%d - %d]",
+			  CFG_ROAMING_DFS_CHANNEL_MIN,
+			  CFG_ROAMING_DFS_CHANNEL_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if ((dfsScanMode < CFG_ROAMING_DFS_CHANNEL_MIN) ||
+	    (dfsScanMode > CFG_ROAMING_DFS_CHANNEL_MAX)) {
+		hdd_err("dfsScanMode value %d is out of range (Min: %d Max: %d)",
+			  dfsScanMode,
+			  CFG_ROAMING_DFS_CHANNEL_MIN,
+			  CFG_ROAMING_DFS_CHANNEL_MAX);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	hdd_debug("Received Command to Set DFS Scan Mode = %d",
+		  dfsScanMode);
+
+	/* When DFS scanning is disabled, the DFS channels need to be
+	 * removed from the operation of device.
+	 */
+	ret = wlan_hdd_enable_dfs_chan_scan(hdd_ctx,
+			dfsScanMode != CFG_ROAMING_DFS_CHANNEL_DISABLED);
+	if (ret < 0) {
+		/* Some conditions prevented it from disabling DFS channels */
+		hdd_err("disable/enable DFS channel request was denied");
+		goto exit;
+	}
+
+	hdd_ctx->config->allowDFSChannelRoam = dfsScanMode;
+	sme_update_dfs_scan_mode(hdd_ctx->mac_handle, adapter->session_id,
+				 dfsScanMode);
+
+exit:
+	return ret;
+}
+
+static int drv_cmd_get_dfs_scan_mode(struct hdd_adapter *adapter,
+				     struct hdd_context *hdd_ctx,
+				     uint8_t *command,
+				     uint8_t command_len,
+				     struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	uint8_t dfsScanMode = sme_get_dfs_scan_mode(hdd_ctx->mac_handle);
+	char extra[32];
+	uint8_t len = 0;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_get_link_status(struct hdd_adapter *adapter,
+				   struct hdd_context *hdd_ctx,
+				   uint8_t *command,
+				   uint8_t command_len,
+				   struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	int value = wlan_hdd_get_link_status(adapter);
+	char extra[32];
+	uint8_t len;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, value);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+static int drv_cmd_enable_ext_wow(struct hdd_adapter *adapter,
+				  struct hdd_context *hdd_ctx,
+				  uint8_t *command,
+				  uint8_t command_len,
+				  struct hdd_priv_data *priv_data)
+{
+	uint8_t *value = command;
+	int set_value;
+
+	/* Move pointer to ahead of ENABLEEXTWOW */
+	value = value + command_len;
+
+	if (!(sscanf(value, "%d", &set_value))) {
+		hdd_info("No input identified");
+		return -EINVAL;
+	}
+
+	return hdd_enable_ext_wow_parser(adapter,
+					 adapter->session_id,
+					 set_value);
+}
+
+static int drv_cmd_set_app1_params(struct hdd_adapter *adapter,
+				   struct hdd_context *hdd_ctx,
+				   uint8_t *command,
+				   uint8_t command_len,
+				   struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint8_t *value = command;
+
+	/* Move pointer to ahead of SETAPP1PARAMS */
+	value = value + command_len;
+
+	ret = hdd_set_app_type1_parser(adapter,
+				       value, strlen(value));
+	if (ret >= 0)
+		hdd_ctx->is_extwow_app_type1_param_set = true;
+
+	return ret;
+}
+
+static int drv_cmd_set_app2_params(struct hdd_adapter *adapter,
+				   struct hdd_context *hdd_ctx,
+				   uint8_t *command,
+				   uint8_t command_len,
+				   struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint8_t *value = command;
+
+	/* Move pointer to ahead of SETAPP2PARAMS */
+	value = value + command_len;
+
+	ret = hdd_set_app_type2_parser(adapter, value, strlen(value));
+	if (ret >= 0)
+		hdd_ctx->is_extwow_app_type2_param_set = true;
+
+	return ret;
+}
+#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
+
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * drv_cmd_tdls_secondary_channel_offset() - secondary tdls off channel offset
+ * @adapter:     Pointer to the HDD adapter
+ * @hdd_ctx:     Pointer to the HDD context
+ * @command:     Driver command string
+ * @command_len: Driver command string length
+ * @priv_data:   Private data coming with the driver command. Unused here
+ *
+ * This function handles driver command that sets the secondary tdls off channel
+ * offset
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+static int drv_cmd_tdls_secondary_channel_offset(struct hdd_adapter *adapter,
+						 struct hdd_context *hdd_ctx,
+						 uint8_t *command,
+						 uint8_t command_len,
+						 struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint8_t *value = command;
+	int set_value;
+
+	/* Move pointer to point the string */
+	value += command_len;
+
+	ret = sscanf(value, "%d", &set_value);
+	if (ret != 1)
+		return -EINVAL;
+
+	hdd_debug("Tdls offchannel offset:%d", set_value);
+
+	ret = hdd_set_tdls_secoffchanneloffset(hdd_ctx, adapter, set_value);
+
+	return ret;
+}
+
+/**
+ * drv_cmd_tdls_off_channel_mode() - set tdls off channel mode
+ * @adapter:     Pointer to the HDD adapter
+ * @hdd_ctx:     Pointer to the HDD context
+ * @command:     Driver command string
+ * @command_len: Driver command string length
+ * @priv_data:   Private data coming with the driver command. Unused here
+ *
+ * This function handles driver command that sets tdls off channel mode
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+static int drv_cmd_tdls_off_channel_mode(struct hdd_adapter *adapter,
+					 struct hdd_context *hdd_ctx,
+					 uint8_t *command,
+					 uint8_t command_len,
+					 struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint8_t *value = command;
+	int set_value;
+
+	/* Move pointer to point the string */
+	value += command_len;
+
+	ret = sscanf(value, "%d", &set_value);
+	if (ret != 1)
+		return -EINVAL;
+
+	hdd_debug("Tdls offchannel mode:%d", set_value);
+
+	ret = hdd_set_tdls_offchannelmode(hdd_ctx, adapter, set_value);
+
+	return ret;
+}
+
+/**
+ * drv_cmd_tdls_off_channel() - set tdls off channel number
+ * @adapter:     Pointer to the HDD adapter
+ * @hdd_ctx:     Pointer to the HDD context
+ * @command:     Driver command string
+ * @command_len: Driver command string length
+ * @priv_data:   Private data coming with the driver command. Unused here
+ *
+ * This function handles driver command that sets tdls off channel number
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+static int drv_cmd_tdls_off_channel(struct hdd_adapter *adapter,
+				    struct hdd_context *hdd_ctx,
+				    uint8_t *command,
+				    uint8_t command_len,
+				    struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint8_t *value = command;
+	int set_value;
+
+	/* Move pointer to point the string */
+	value += command_len;
+
+	ret = sscanf(value, "%d", &set_value);
+	if (ret != 1)
+		return -EINVAL;
+
+	if (wlan_reg_is_dfs_ch(hdd_ctx->pdev, set_value)) {
+		hdd_err("DFS channel %d is passed for hdd_set_tdls_offchannel",
+		    set_value);
+		return -EINVAL;
+	}
+
+	hdd_debug("Tdls offchannel num: %d", set_value);
+
+	ret = hdd_set_tdls_offchannel(hdd_ctx, adapter, set_value);
+
+	return ret;
+}
+
+/**
+ * drv_cmd_tdls_scan() - set tdls scan type
+ * @adapter:     Pointer to the HDD adapter
+ * @hdd_ctx:     Pointer to the HDD context
+ * @command:     Driver command string
+ * @command_len: Driver command string length
+ * @priv_data:   Private data coming with the driver command. Unused here
+ *
+ * This function handles driver command that sets tdls scan type
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+static int drv_cmd_tdls_scan(struct hdd_adapter *adapter,
+				    struct hdd_context *hdd_ctx,
+				    uint8_t *command,
+				    uint8_t command_len,
+				    struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint8_t *value = command;
+	int set_value;
+
+	/* Move pointer to point the string */
+	value += command_len;
+
+	ret = sscanf(value, "%d", &set_value);
+	if (ret != 1)
+		return -EINVAL;
+
+	hdd_debug("Tdls scan type val: %d", set_value);
+
+	ret = hdd_set_tdls_scan_type(hdd_ctx, set_value);
+
+	return ret;
+}
+#endif
+
+static int drv_cmd_get_rssi(struct hdd_adapter *adapter,
+			    struct hdd_context *hdd_ctx,
+			    uint8_t *command,
+			    uint8_t command_len,
+			    struct hdd_priv_data *priv_data)
+{
+	int ret = 0;
+	int8_t rssi = 0;
+	char extra[32];
+
+	uint8_t len = 0;
+
+	wlan_hdd_get_rssi(adapter, &rssi);
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("Failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+static int drv_cmd_get_linkspeed(struct hdd_adapter *adapter,
+				 struct hdd_context *hdd_ctx,
+				 uint8_t *command,
+				 uint8_t command_len,
+				 struct hdd_priv_data *priv_data)
+{
+	int ret;
+	uint32_t link_speed = 0;
+	char extra[32];
+	uint8_t len = 0;
+
+	ret = wlan_hdd_get_link_speed(adapter, &link_speed);
+	if (0 != ret)
+		return ret;
+
+	len = scnprintf(extra, sizeof(extra), "%s %d", command, link_speed);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("Failed to copy data to user buffer");
+		ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+/**
+ * hdd_set_rx_filter() - set RX filter
+ * @adapter: Pointer to adapter
+ * @action: Filter action
+ * @pattern: Address pattern
+ *
+ * Address pattern is most significant byte of address for example
+ * 0x01 for IPV4 multicast address
+ * 0x33 for IPV6 multicast address
+ * 0xFF for broadcast address
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int hdd_set_rx_filter(struct hdd_adapter *adapter, bool action,
+			uint8_t pattern)
+{
+	int ret;
+	uint8_t i, j;
+	tSirRcvFltMcAddrList *filter;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle;
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!mac_handle) {
+		hdd_err("MAC Handle is NULL");
+		return -EINVAL;
+	}
+
+	if (!ucfg_pmo_is_mc_addr_list_enabled(hdd_ctx->psoc)) {
+		hdd_warn("mc addr ini is disabled");
+		return -EINVAL;
+	}
+
+	/*
+	 * If action is false it means start dropping packets
+	 * Set addr_filter_pattern which will be used when sending
+	 * MC/BC address list to target
+	 */
+	if (!action)
+		adapter->addr_filter_pattern = pattern;
+	else
+		adapter->addr_filter_pattern = 0;
+
+	if (((adapter->device_mode == QDF_STA_MODE) ||
+		(adapter->device_mode == QDF_P2P_CLIENT_MODE)) &&
+		adapter->mc_addr_list.mc_cnt &&
+		hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
+
+
+		filter = qdf_mem_malloc(sizeof(*filter));
+		if (NULL == filter) {
+			hdd_err("Could not allocate Memory");
+			return -ENOMEM;
+		}
+		filter->action = action;
+		for (i = 0, j = 0; i < adapter->mc_addr_list.mc_cnt; i++) {
+			if (!memcmp(adapter->mc_addr_list.addr[i],
+				&pattern, 1)) {
+				memcpy(filter->multicastAddr[j].bytes,
+					adapter->mc_addr_list.addr[i],
+					sizeof(adapter->mc_addr_list.addr[i]));
+
+				hdd_debug("%s RX filter : addr ="
+				    MAC_ADDRESS_STR,
+				    action ? "setting" : "clearing",
+				    MAC_ADDR_ARRAY(filter->multicastAddr[j].bytes));
+				j++;
+			}
+			if (j == SIR_MAX_NUM_MULTICAST_ADDRESS)
+				break;
+		}
+		filter->ulMulticastAddrCnt = j;
+		/* Set rx filter */
+		sme_8023_multicast_list(mac_handle, adapter->session_id,
+					filter);
+		qdf_mem_free(filter);
+	} else {
+		hdd_debug("mode %d mc_cnt %d",
+			  adapter->device_mode, adapter->mc_addr_list.mc_cnt);
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_driver_rxfilter_command_handler() - RXFILTER driver command handler
+ * @command: Pointer to input string driver command
+ * @adapter: Pointer to adapter
+ * @action: Action to enable/disable filtering
+ *
+ * If action == false
+ * Start filtering out data packets based on type
+ * RXFILTER-REMOVE 0 -> Start filtering out unicast data packets
+ * RXFILTER-REMOVE 1 -> Start filtering out broadcast data packets
+ * RXFILTER-REMOVE 2 -> Start filtering out IPV4 mcast data packets
+ * RXFILTER-REMOVE 3 -> Start filtering out IPV6 mcast data packets
+ *
+ * if action == true
+ * Stop filtering data packets based on type
+ * RXFILTER-ADD 0 -> Stop filtering unicast data packets
+ * RXFILTER-ADD 1 -> Stop filtering broadcast data packets
+ * RXFILTER-ADD 2 -> Stop filtering IPV4 mcast data packets
+ * RXFILTER-ADD 3 -> Stop filtering IPV6 mcast data packets
+ *
+ * Current implementation only supports IPV4 address filtering by
+ * selectively allowing IPV4 multicast data packest based on
+ * address list received in .ndo_set_rx_mode
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int hdd_driver_rxfilter_command_handler(uint8_t *command,
+						struct hdd_adapter *adapter,
+						bool action)
+{
+	int ret = 0;
+	uint8_t *value;
+	uint8_t type;
+
+	value = command;
+	/* Skip space after RXFILTER-REMOVE OR RXFILTER-ADD based on action */
+	if (!action)
+		value = command + 16;
+	else
+		value = command + 13;
+	ret = kstrtou8(value, 10, &type);
+	if (ret < 0) {
+		hdd_err("kstrtou8 failed invalid input value");
+		return -EINVAL;
+	}
+
+	switch (type) {
+	case 2:
+		/* Set rx filter for IPV4 multicast data packets */
+		ret = hdd_set_rx_filter(adapter, action, 0x01);
+		break;
+	default:
+		hdd_warn("Unsupported RXFILTER type %d", type);
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * drv_cmd_rx_filter_remove() - RXFILTER REMOVE driver command handler
+ * @adapter: Pointer to network adapter
+ * @hdd_ctx: Pointer to hdd context
+ * @command: Pointer to input command
+ * @command_len: Command length
+ * @priv_data: Pointer to private data in command
+ */
+static int drv_cmd_rx_filter_remove(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	return hdd_driver_rxfilter_command_handler(command, adapter, false);
+}
+
+/**
+ * drv_cmd_rx_filter_add() - RXFILTER ADD driver command handler
+ * @adapter: Pointer to network adapter
+ * @hdd_ctx: Pointer to hdd context
+ * @command: Pointer to input command
+ * @command_len: Command length
+ * @priv_data: Pointer to private data in command
+ */
+static int drv_cmd_rx_filter_add(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	return hdd_driver_rxfilter_command_handler(command, adapter, true);
+}
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+
+/**
+ * hdd_parse_setantennamode_command() - HDD Parse SETANTENNAMODE
+ * command
+ * @value: Pointer to SETANTENNAMODE command
+ * @mode: Pointer to antenna mode
+ * @reason: Pointer to reason for set antenna mode
+ *
+ * This function parses the SETANTENNAMODE command passed in the format
+ * SETANTENNAMODE<space>mode
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int hdd_parse_setantennamode_command(const uint8_t *value)
+{
+	const uint8_t *in_ptr = value;
+	int tmp, v;
+	char arg1[32];
+
+	in_ptr = strnchr(value, strlen(value), SPACE_ASCII_VALUE);
+
+	/* no argument after the command */
+	if (NULL == in_ptr) {
+		hdd_err("No argument after the command");
+		return -EINVAL;
+	}
+
+	/* no space after the command */
+	if (SPACE_ASCII_VALUE != *in_ptr) {
+		hdd_err("No space after the command");
+		return -EINVAL;
+	}
+
+	/* remove empty spaces */
+	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
+		in_ptr++;
+
+	/* no argument followed by spaces */
+	if ('\0' == *in_ptr) {
+		hdd_err("No argument followed by spaces");
+		return -EINVAL;
+	}
+
+	/* get the argument i.e. antenna mode */
+	v = sscanf(in_ptr, "%31s ", arg1);
+	if (1 != v) {
+		hdd_err("argument retrieval from cmd string failed");
+		return -EINVAL;
+	}
+
+	v = kstrtos32(arg1, 10, &tmp);
+	if (v < 0) {
+		hdd_err("argument string to int conversion failed");
+		return -EINVAL;
+	}
+
+	return tmp;
+}
+
+/**
+ * hdd_is_supported_chain_mask_2x2() - Verify if supported chain
+ * mask is 2x2 mode
+ * @hdd_ctx: Pointer to hdd contex
+ *
+ * Return: true if supported chain mask 2x2 else false
+ */
+static bool hdd_is_supported_chain_mask_2x2(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	bool bval = false;
+
+/*
+	 * Revisit and the update logic to determine the number
+	 * of TX/RX chains supported in the system when
+	 * antenna sharing per band chain mask support is
+	 * brought in
+	 */
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+
+	return (bval == 0x01) ? true : false;
+}
+
+/**
+ * hdd_is_supported_chain_mask_1x1() - Verify if the supported
+ * chain mask is 1x1
+ * @hdd_ctx: Pointer to hdd contex
+ *
+ * Return: true if supported chain mask 1x1 else false
+ */
+static bool hdd_is_supported_chain_mask_1x1(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	bool bval = false;
+
+	/*
+	 * Revisit and update the logic to determine the number
+	 * of TX/RX chains supported in the system when
+	 * antenna sharing per band chain mask support is
+	 * brought in
+	 */
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+
+	return (!bval) ? true : false;
+}
+
+QDF_STATUS hdd_update_smps_antenna_mode(struct hdd_context *hdd_ctx, int mode)
+{
+	QDF_STATUS status;
+	uint8_t smps_mode;
+	uint8_t smps_enable;
+	mac_handle_t mac_handle;
+
+	/* Update SME SMPS config */
+	if (HDD_ANTENNA_MODE_1X1 == mode) {
+		smps_enable = true;
+		smps_mode = HDD_SMPS_MODE_STATIC;
+	} else {
+		smps_enable = false;
+		smps_mode = HDD_SMPS_MODE_DISABLED;
+	}
+
+	hdd_debug("Update SME SMPS enable: %d mode: %d",
+		 smps_enable, smps_mode);
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_update_mimo_power_save(mac_handle, smps_enable,
+					    smps_mode, false);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Update SMPS config failed enable: %d mode: %d status: %d",
+			smps_enable, smps_mode, status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hdd_ctx->current_antenna_mode = mode;
+	/*
+	 * Update the user requested nss in the mac context.
+	 * This will be used in tdls protocol engine to form tdls
+	 * Management frames.
+	 */
+	sme_update_user_configured_nss(mac_handle,
+				       hdd_ctx->current_antenna_mode);
+
+	hdd_debug("Successfully switched to mode: %d x %d",
+		 hdd_ctx->current_antenna_mode,
+		 hdd_ctx->current_antenna_mode);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_hdd_soc_set_antenna_mode_cb() - Callback for set antenna mode
+ * @status: Status of set antenna mode
+ * @context: callback context
+ *
+ * Callback on setting antenna mode
+ *
+ * Return: None
+ */
+static void
+wlan_hdd_soc_set_antenna_mode_cb(enum set_antenna_mode_status status,
+				 void *context)
+{
+	struct osif_request *request = NULL;
+
+	hdd_debug("Status: %d", status);
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("obselete request");
+		return;
+	}
+
+	/* Signal the completion of set dual mac config */
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+int hdd_set_antenna_mode(struct hdd_adapter *adapter,
+				  struct hdd_context *hdd_ctx, int mode)
+{
+
+	struct sir_antenna_mode_param params;
+	QDF_STATUS status;
+	int ret = 0;
+	struct osif_request *request = NULL;
+	static const struct osif_request_params request_params = {
+		.priv_size = 0,
+		.timeout_ms = WLAN_WAIT_TIME_ANTENNA_MODE_REQ,
+	};
+
+	if (hdd_ctx->current_antenna_mode == mode) {
+		hdd_err("System already in the requested mode");
+		goto exit;
+	}
+
+	if ((HDD_ANTENNA_MODE_2X2 == mode) &&
+	    (!hdd_is_supported_chain_mask_2x2(hdd_ctx))) {
+		hdd_err("System does not support 2x2 mode");
+		ret = -EPERM;
+		goto exit;
+	}
+
+	if ((HDD_ANTENNA_MODE_1X1 == mode) &&
+	    hdd_is_supported_chain_mask_1x1(hdd_ctx)) {
+		hdd_err("System only supports 1x1 mode");
+		goto exit;
+	}
+
+	switch (mode) {
+	case HDD_ANTENNA_MODE_1X1:
+		params.num_rx_chains = 1;
+		params.num_tx_chains = 1;
+		break;
+	case HDD_ANTENNA_MODE_2X2:
+		params.num_rx_chains = 2;
+		params.num_tx_chains = 2;
+		break;
+	default:
+		hdd_err("unsupported antenna mode");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Check TDLS status and update antenna mode */
+	if ((QDF_STA_MODE == adapter->device_mode) &&
+	    policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
+		ret = wlan_hdd_tdls_antenna_switch(hdd_ctx, adapter, mode);
+		if (0 != ret)
+			goto exit;
+	}
+
+	request = osif_request_alloc(&request_params);
+	if (!request) {
+		hdd_err("Request Allocation Failure");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	params.set_antenna_mode_ctx = osif_request_cookie(request);
+	params.set_antenna_mode_resp = (void *)wlan_hdd_soc_set_antenna_mode_cb;
+	hdd_debug("Set antenna mode rx chains: %d tx chains: %d",
+		 params.num_rx_chains,
+		 params.num_tx_chains);
+
+	status = sme_soc_set_antenna_mode(hdd_ctx->mac_handle, &params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("set antenna mode failed status : %d", status);
+		ret = -EFAULT;
+		goto request_put;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_err("send set antenna mode timed out");
+		goto request_put;
+	}
+
+	status = hdd_update_smps_antenna_mode(hdd_ctx, mode);
+	if (QDF_STATUS_SUCCESS != status) {
+		ret = -EFAULT;
+		goto request_put;
+	}
+	ret = 0;
+request_put:
+	osif_request_put(request);
+exit:
+	hdd_debug("Set antenna status: %d current mode: %d",
+		 ret, hdd_ctx->current_antenna_mode);
+
+	return ret;
+}
+/**
+ * drv_cmd_set_antenna_mode() - SET ANTENNA MODE driver command
+ * handler
+ * @adapter: Pointer to network adapter
+ * @hdd_ctx: Pointer to hdd context
+ * @command: Pointer to input command
+ * @command_len: Command length
+ * @priv_data: Pointer to private data in command
+ */
+static int drv_cmd_set_antenna_mode(struct hdd_adapter *adapter,
+				struct hdd_context *hdd_ctx,
+				uint8_t *command,
+				uint8_t command_len,
+				struct hdd_priv_data *priv_data)
+{
+	int mode;
+	uint8_t *value = command;
+
+	mode = hdd_parse_setantennamode_command(value);
+	if (mode < 0) {
+		hdd_err("Invalid SETANTENNA command");
+		return mode;
+	}
+
+	hdd_debug("Processing antenna mode switch to: %d", mode);
+
+	return hdd_set_antenna_mode(adapter, hdd_ctx, mode);
+}
+
+/**
+ * drv_cmd_get_antenna_mode() - GET ANTENNA MODE driver command
+ * handler
+ * @adapter: Pointer to hdd adapter
+ * @hdd_ctx: Pointer to hdd context
+ * @command: Pointer to input command
+ * @command_len: length of the command
+ * @priv_data: private data coming with the driver command
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static inline int drv_cmd_get_antenna_mode(struct hdd_adapter *adapter,
+					   struct hdd_context *hdd_ctx,
+					   uint8_t *command,
+					   uint8_t command_len,
+					   struct hdd_priv_data *priv_data)
+{
+	uint32_t antenna_mode = 0;
+	char extra[32];
+	uint8_t len = 0;
+
+	antenna_mode = hdd_ctx->current_antenna_mode;
+	len = scnprintf(extra, sizeof(extra), "%s %d", command,
+			antenna_mode);
+	len = QDF_MIN(priv_data->total_len, len + 1);
+	if (copy_to_user(priv_data->buf, &extra, len)) {
+		hdd_err("Failed to copy data to user buffer");
+		return -EFAULT;
+	}
+
+	hdd_debug("Get antenna mode: %d", antenna_mode);
+
+	return 0;
+}
+
+/*
+ * dummy (no-op) hdd driver command handler
+ */
+static int drv_cmd_dummy(struct hdd_adapter *adapter,
+			 struct hdd_context *hdd_ctx,
+			 uint8_t *command,
+			 uint8_t command_len,
+			 struct hdd_priv_data *priv_data)
+{
+	hdd_debug("%s: Ignoring driver command \"%s\"",
+		 adapter->dev->name, command);
+	return 0;
+}
+
+/*
+ * handler for any unsupported wlan hdd driver command
+ */
+static int drv_cmd_invalid(struct hdd_adapter *adapter,
+			   struct hdd_context *hdd_ctx,
+			   uint8_t *command,
+			   uint8_t command_len,
+			   struct hdd_priv_data *priv_data)
+{
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
+			 adapter->session_id, 0));
+
+	hdd_warn("%s: Unsupported driver command \"%s\"",
+		 adapter->dev->name, command);
+
+	return -ENOTSUPP;
+}
+
+/**
+ * drv_cmd_set_fcc_channel() - handle fcc constraint request
+ * @adapter: HDD adapter
+ * @hdd_ctx: HDD context
+ * @command: command ptr, SET_FCC_CHANNEL 0/1 is the command
+ * @command_len: command len
+ * @priv_data: private data
+ *
+ * Return: status
+ */
+static int drv_cmd_set_fcc_channel(struct hdd_adapter *adapter,
+				   struct hdd_context *hdd_ctx,
+				   uint8_t *command,
+				   uint8_t command_len,
+				   struct hdd_priv_data *priv_data)
+{
+	QDF_STATUS status;
+	uint8_t fcc_constraint;
+	int err;
+
+	/*
+	 * this command would be called by user-space when it detects WLAN
+	 * ON after airplane mode is set. When APM is set, WLAN turns off.
+	 * But it can be turned back on. Otherwise; when APM is turned back
+	 * off, WLAN would turn back on. So at that point the command is
+	 * expected to come down. 0 means disable, 1 means enable. The
+	 * constraint is removed when parameter 1 is set or different
+	 * country code is set
+	 */
+
+	err = kstrtou8(command + command_len + 1, 10, &fcc_constraint);
+	if (err) {
+		hdd_err("error %d parsing userspace fcc parameter", err);
+		return err;
+	}
+
+	status = ucfg_reg_set_fcc_constraint(hdd_ctx->pdev, fcc_constraint);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to %s tx power for channels 12/13",
+			fcc_constraint ? "reduce" : "restore");
+
+	return qdf_status_to_os_return(status);
+}
+
+/**
+ * hdd_parse_set_channel_switch_command() - Parse and validate CHANNEL_SWITCH
+ * command
+ * @value: Pointer to the command
+ * @chan_number: Pointer to the channel number
+ * @chan_bw: Pointer to the channel bandwidth
+ *
+ * Parses and provides the channel number and channel width from the input
+ * command which is expected to be of the format: CHANNEL_SWITCH <CH> <BW>
+ * <CH> is channel number to move (where 1 = channel 1, 149 = channel 149, ...)
+ * <BW> is bandwidth to move (where 20 = BW 20, 40 = BW 40, 80 = BW 80)
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int hdd_parse_set_channel_switch_command(uint8_t *value,
+					 uint32_t *chan_number,
+					 uint32_t *chan_bw)
+{
+	const uint8_t *in_ptr = value;
+	int ret;
+
+	in_ptr = strnchr(value, strlen(value), SPACE_ASCII_VALUE);
+
+	/* no argument after the command */
+	if (NULL == in_ptr) {
+		hdd_err("No argument after the command");
+		return -EINVAL;
+	}
+
+	/* no space after the command */
+	if (SPACE_ASCII_VALUE != *in_ptr) {
+		hdd_err("No space after the command ");
+		return -EINVAL;
+	}
+
+	/* remove empty spaces and move the next argument */
+	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
+		in_ptr++;
+
+	/* no argument followed by spaces */
+	if ('\0' == *in_ptr) {
+		hdd_err("No argument followed by spaces");
+		return -EINVAL;
+	}
+
+	/* get the two arguments: channel number and bandwidth */
+	ret = sscanf(in_ptr, "%u %u", chan_number, chan_bw);
+	if (ret != 2) {
+		hdd_err("Arguments retrieval from cmd string failed");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * drv_cmd_set_channel_switch() - Switch SAP/P2P-GO operating channel
+ * @adapter: HDD adapter
+ * @hdd_ctx: HDD context
+ * @command: Pointer to the input command CHANNEL_SWITCH
+ * @command_len: Command len
+ * @priv_data: Private data
+ *
+ * Handles private IOCTL CHANNEL_SWITCH command to switch the operating channel
+ * of SAP/P2P-GO
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int drv_cmd_set_channel_switch(struct hdd_adapter *adapter,
+				   struct hdd_context *hdd_ctx,
+				   uint8_t *command,
+				   uint8_t command_len,
+				   struct hdd_priv_data *priv_data)
+{
+	struct net_device *dev = adapter->dev;
+	int status;
+	uint32_t chan_number = 0, chan_bw = 0;
+	uint8_t *value = command;
+	enum phy_ch_width width;
+
+	if ((adapter->device_mode != QDF_P2P_GO_MODE) &&
+		(adapter->device_mode != QDF_SAP_MODE)) {
+		hdd_err("IOCTL CHANNEL_SWITCH not supported for mode %d",
+			adapter->device_mode);
+		return -EINVAL;
+	}
+
+	status = hdd_parse_set_channel_switch_command(value,
+							&chan_number, &chan_bw);
+	if (status) {
+		hdd_err("Invalid CHANNEL_SWITCH command");
+		return status;
+	}
+
+	if ((chan_bw != 20) && (chan_bw != 40) && (chan_bw != 80)) {
+		hdd_err("BW %d is not allowed for CHANNEL_SWITCH", chan_bw);
+		return -EINVAL;
+	}
+
+	if (chan_bw == 80)
+		width = CH_WIDTH_80MHZ;
+	else if (chan_bw == 40)
+		width = CH_WIDTH_40MHZ;
+	else
+		width = CH_WIDTH_20MHZ;
+
+	hdd_debug("CH:%d BW:%d", chan_number, chan_bw);
+
+	status = hdd_softap_set_channel_change(dev, chan_number, width, true);
+	if (status) {
+		hdd_err("Set channel change fail");
+		return status;
+	}
+
+	return 0;
+}
+
+#ifdef DISABLE_CHANNEL_LIST
+void wlan_hdd_free_cache_channels(struct hdd_context *hdd_ctx)
+{
+	hdd_enter();
+
+	if (!hdd_ctx->original_channels)
+		return;
+
+	qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
+	hdd_ctx->original_channels->num_channels = 0;
+	if (hdd_ctx->original_channels->channel_info) {
+		qdf_mem_free(hdd_ctx->original_channels->channel_info);
+		hdd_ctx->original_channels->channel_info = NULL;
+	}
+	qdf_mem_free(hdd_ctx->original_channels);
+	hdd_ctx->original_channels = NULL;
+	qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+
+	hdd_exit();
+}
+
+/**
+ * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
+ * info for the channels received in command SET_DISABLE_CHANNEL_LIST
+ * @hdd_ctx: Pointer to HDD context
+ * @num_chan: Number of channels for which memory needs to
+ * be allocated
+ *
+ * Return: 0 on success and error code on failure
+ */
+static int hdd_alloc_chan_cache(struct hdd_context *hdd_ctx, int num_chan)
+{
+	hdd_ctx->original_channels =
+			qdf_mem_malloc(sizeof(struct hdd_cache_channels));
+	if (!hdd_ctx->original_channels) {
+		hdd_err("QDF_MALLOC_ERR");
+		return -ENOMEM;
+	}
+	hdd_ctx->original_channels->num_channels = num_chan;
+	hdd_ctx->original_channels->channel_info =
+					qdf_mem_malloc(num_chan *
+					sizeof(struct hdd_cache_channel_info));
+	if (!hdd_ctx->original_channels->channel_info) {
+		hdd_err("QDF_MALLOC_ERR");
+		hdd_ctx->original_channels->num_channels = 0;
+		qdf_mem_free(hdd_ctx->original_channels);
+		hdd_ctx->original_channels = NULL;
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+/**
+ * hdd_parse_disable_chan_cmd() - Parse the channel list received
+ * in command.
+ * @adapter: pointer to hdd adapter
+ * @ptr: Pointer to the command string
+ *
+ * This function parses the channel list received in the command.
+ * command should be a string having format
+ * SET_DISABLE_CHANNEL_LIST <num of channels>
+ * <channels separated by spaces>.
+ * If the command comes multiple times than this function will compare
+ * the channels received in the command with the channles cached in the
+ * first command, if the channel list matches with the cached channles,
+ * it returns success otherwise returns failure.
+ *
+ * Return: 0 on success, Error code on failure
+ */
+
+static int hdd_parse_disable_chan_cmd(struct hdd_adapter *adapter, uint8_t *ptr)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	uint8_t *param;
+	int j, i, temp_int, ret = 0, num_channels;
+	uint32_t parsed_channels[MAX_CHANNEL];
+	bool is_command_repeated = false;
+
+	if (NULL == hdd_ctx) {
+		hdd_err("HDD Context is NULL");
+		return -EINVAL;
+	}
+
+	param = strnchr(ptr, strlen(ptr), ' ');
+	/*no argument after the command*/
+	if (NULL == param)
+		return -EINVAL;
+
+	/*no space after the command*/
+	else if (SPACE_ASCII_VALUE != *param)
+		return -EINVAL;
+
+	param++;
+
+	/*removing empty spaces*/
+	while ((SPACE_ASCII_VALUE  == *param) && ('\0' !=  *param))
+		param++;
+
+	/*no argument followed by spaces*/
+	if ('\0' == *param)
+		return -EINVAL;
+
+	/*getting the first argument ie the number of channels*/
+	if (sscanf(param, "%d ", &temp_int) != 1) {
+		hdd_err("Cannot get number of channels from input");
+		return -EINVAL;
+	}
+
+	if (temp_int < 0 || temp_int > MAX_CHANNEL) {
+		hdd_err("Invalid Number of channel received");
+		return -EINVAL;
+	}
+
+	hdd_debug("Number of channel to disable are: %d", temp_int);
+
+	if (!temp_int) {
+		if (!wlan_hdd_restore_channels(hdd_ctx, false)) {
+			/*
+			 * Free the cache channels only when the command is
+			 * received with num channels as 0
+			 */
+			wlan_hdd_free_cache_channels(hdd_ctx);
+		}
+		return 0;
+	}
+
+	qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
+
+	if (!hdd_ctx->original_channels) {
+		if (hdd_alloc_chan_cache(hdd_ctx, temp_int)) {
+			ret = -ENOMEM;
+			goto mem_alloc_failed;
+		}
+	} else if (hdd_ctx->original_channels->num_channels != temp_int) {
+		hdd_err("Invalid Number of channels");
+		ret = -EINVAL;
+		is_command_repeated = true;
+		goto parse_failed;
+	} else {
+		is_command_repeated = true;
+	}
+	num_channels = temp_int;
+	for (j = 0; j < num_channels; j++) {
+		/*
+		 * param pointing to the beginning of first space
+		 * after number of channels
+		 */
+		param = strpbrk(param, " ");
+		/*no channel list after the number of channels argument*/
+		if (NULL == param) {
+			hdd_err("Invalid No of channel provided in the list");
+			ret = -EINVAL;
+			goto parse_failed;
+		}
+
+		param++;
+
+		/*removing empty space*/
+		while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
+			param++;
+
+		if ('\0' == *param) {
+			hdd_err("No channel is provided in the list");
+			ret = -EINVAL;
+			goto parse_failed;
+		}
+
+		if (sscanf(param, "%d ", &temp_int) != 1) {
+			hdd_err("Cannot read channel number");
+			ret = -EINVAL;
+			goto parse_failed;
+		}
+
+		if (!IS_CHANNEL_VALID(temp_int)) {
+			hdd_err("Invalid channel number received");
+			ret = -EINVAL;
+			goto parse_failed;
+		}
+
+		hdd_debug("channel[%d] = %d", j, temp_int);
+		parsed_channels[j] = temp_int;
+	}
+
+	/*extra arguments check*/
+	param = strpbrk(param, " ");
+	if (NULL != param) {
+		while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
+			param++;
+
+		if ('\0' !=  *param) {
+			hdd_err("Invalid argument received");
+			ret = -EINVAL;
+			goto parse_failed;
+		}
+	}
+
+	/*
+	 * If command is received first time, cache the channels to
+	 * be disabled else compare the channels received in the
+	 * command with the cached channels, if channel list matches
+	 * return success otherewise return failure.
+	 */
+	if (!is_command_repeated) {
+		for (j = 0; j < num_channels; j++)
+			hdd_ctx->original_channels->
+					channel_info[j].channel_num =
+							parsed_channels[j];
+
+		/* Cache the channel list in regulatory also */
+		ucfg_reg_cache_channel_state(hdd_ctx->pdev, parsed_channels,
+					     num_channels);
+	} else {
+		for (i = 0; i < num_channels; i++) {
+			for (j = 0; j < num_channels; j++)
+				if (hdd_ctx->original_channels->
+					channel_info[i].channel_num ==
+							parsed_channels[j])
+					break;
+			if (j == num_channels) {
+				ret = -EINVAL;
+				goto parse_failed;
+			}
+		}
+		ret = 0;
+	}
+mem_alloc_failed:
+
+	qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+	hdd_exit();
+
+	return ret;
+
+parse_failed:
+	if (!is_command_repeated)
+		wlan_hdd_free_cache_channels(hdd_ctx);
+	qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+	hdd_exit();
+
+	return ret;
+}
+
+static int drv_cmd_set_disable_chan_list(struct hdd_adapter *adapter,
+					 struct hdd_context *hdd_ctx,
+					 uint8_t *command,
+					 uint8_t command_len,
+					 struct hdd_priv_data *priv_data)
+{
+	return hdd_parse_disable_chan_cmd(adapter, command);
+}
+
+/**
+ * hdd_get_disable_ch_list() - get disable channel list
+ * @hdd_ctx: hdd context
+ * @buf: buffer to hold disable channel list
+ * @buf_len: buffer length
+ *
+ * Return: length of data copied to buf
+ */
+static int hdd_get_disable_ch_list(struct hdd_context *hdd_ctx, uint8_t *buf,
+				   uint32_t buf_len)
+{
+	struct hdd_cache_channel_info *ch_list;
+	unsigned char i, num_ch;
+	int len = 0;
+
+	qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
+	if (hdd_ctx->original_channels &&
+	    hdd_ctx->original_channels->num_channels &&
+	    hdd_ctx->original_channels->channel_info) {
+		num_ch = hdd_ctx->original_channels->num_channels;
+
+		len = scnprintf(buf, buf_len, "%s %hhu",
+				"GET_DISABLE_CHANNEL_LIST", num_ch);
+		ch_list = hdd_ctx->original_channels->channel_info;
+		for (i = 0; (i < num_ch) && (len < buf_len - 1); i++) {
+			len += scnprintf(buf + len, buf_len - len,
+					 " %d", ch_list[i].channel_num);
+		}
+	}
+	qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+
+	return len;
+}
+
+static int drv_cmd_get_disable_chan_list(struct hdd_adapter *adapter,
+					 struct hdd_context *hdd_ctx,
+					 uint8_t *command,
+					 uint8_t command_len,
+					 struct hdd_priv_data *priv_data)
+{
+	char extra[512] = {0};
+	int max_len, copied_length;
+
+	hdd_debug("Received Command to get disable Channels list");
+
+	max_len = QDF_MIN(priv_data->total_len, sizeof(extra));
+	copied_length = hdd_get_disable_ch_list(hdd_ctx, extra, max_len);
+	if (copied_length == 0) {
+		hdd_err("disable channel list is not yet programmed");
+		return -EINVAL;
+	}
+
+	if (copy_to_user(priv_data->buf, &extra, copied_length + 1)) {
+		hdd_err("failed to copy data to user buffer");
+		return -EFAULT;
+	}
+
+	hdd_debug("data:%s", extra);
+	return 0;
+}
+#else
+
+static int drv_cmd_set_disable_chan_list(struct hdd_adapter *adapter,
+					 struct hdd_context *hdd_ctx,
+					 uint8_t *command,
+					 uint8_t command_len,
+					 struct hdd_priv_data *priv_data)
+{
+	return 0;
+}
+
+void wlan_hdd_free_cache_channels(struct hdd_context *hdd_ctx)
+{
+}
+
+static int drv_cmd_get_disable_chan_list(struct hdd_adapter *adapter,
+					 struct hdd_context *hdd_ctx,
+					 uint8_t *command,
+					 uint8_t command_len,
+					 struct hdd_priv_data *priv_data)
+{
+	return 0;
+}
+#endif
+/*
+ * The following table contains all supported WLAN HDD
+ * IOCTL driver commands and the handler for each of them.
+ */
+static const struct hdd_drv_cmd hdd_drv_cmds[] = {
+	{"P2P_DEV_ADDR",              drv_cmd_p2p_dev_addr, false},
+	{"P2P_SET_NOA",               drv_cmd_p2p_set_noa, true},
+	{"P2P_SET_PS",                drv_cmd_p2p_set_ps, true},
+	{"SETBAND",                   drv_cmd_set_band, true},
+	{"SETWMMPS",                  drv_cmd_set_wmmps, true},
+	{"COUNTRY",                   drv_cmd_country, true},
+	{"SETSUSPENDMODE",            drv_cmd_dummy, false},
+	{"SET_AP_WPS_P2P_IE",         drv_cmd_dummy, false},
+	{"SETROAMTRIGGER",            drv_cmd_set_roam_trigger, true},
+	{"GETROAMTRIGGER",            drv_cmd_get_roam_trigger, false},
+	{"SETROAMSCANPERIOD",         drv_cmd_set_roam_scan_period, true},
+	{"GETROAMSCANPERIOD",         drv_cmd_get_roam_scan_period, false},
+	{"SETROAMSCANREFRESHPERIOD",  drv_cmd_set_roam_scan_refresh_period,
+	 true},
+	{"GETROAMSCANREFRESHPERIOD",  drv_cmd_get_roam_scan_refresh_period,
+	 false},
+	{"SETROAMMODE",               drv_cmd_set_roam_mode, true},
+	{"GETROAMMODE",               drv_cmd_get_roam_mode, false},
+	{"SETROAMDELTA",              drv_cmd_set_roam_delta, true},
+	{"GETROAMDELTA",              drv_cmd_get_roam_delta, false},
+	{"GETBAND",                   drv_cmd_get_band, false},
+	{"SETROAMSCANCHANNELS",       drv_cmd_set_roam_scan_channels, true},
+	{"GETROAMSCANCHANNELS",       drv_cmd_get_roam_scan_channels, false},
+	{"GETCCXMODE",                drv_cmd_get_ccx_mode, false},
+	{"GETOKCMODE",                drv_cmd_get_okc_mode, false},
+	{"GETFASTROAM",               drv_cmd_get_fast_roam, false},
+	{"GETFASTTRANSITION",         drv_cmd_get_fast_transition, false},
+	{"SETROAMSCANCHANNELMINTIME", drv_cmd_set_roam_scan_channel_min_time,
+	 true},
+	{"SENDACTIONFRAME",           drv_cmd_send_action_frame, true},
+	{"GETROAMSCANCHANNELMINTIME", drv_cmd_get_roam_scan_channel_min_time,
+	 false},
+	{"SETSCANCHANNELTIME",        drv_cmd_set_scan_channel_time, true},
+	{"GETSCANCHANNELTIME",        drv_cmd_get_scan_channel_time, false},
+	{"SETSCANHOMETIME",           drv_cmd_set_scan_home_time, true},
+	{"GETSCANHOMETIME",           drv_cmd_get_scan_home_time, false},
+	{"SETROAMINTRABAND",          drv_cmd_set_roam_intra_band, true},
+	{"GETROAMINTRABAND",          drv_cmd_get_roam_intra_band, false},
+	{"SETSCANNPROBES",            drv_cmd_set_scan_n_probes, true},
+	{"GETSCANNPROBES",            drv_cmd_get_scan_n_probes, false},
+	{"SETSCANHOMEAWAYTIME",       drv_cmd_set_scan_home_away_time, true},
+	{"GETSCANHOMEAWAYTIME",       drv_cmd_get_scan_home_away_time, false},
+	{"REASSOC",                   drv_cmd_reassoc, true},
+	{"SETWESMODE",                drv_cmd_set_wes_mode, true},
+	{"GETWESMODE",                drv_cmd_get_wes_mode, false},
+	{"SETOPPORTUNISTICRSSIDIFF",  drv_cmd_set_opportunistic_rssi_diff,
+	 true},
+	{"GETOPPORTUNISTICRSSIDIFF",  drv_cmd_get_opportunistic_rssi_diff,
+	 false},
+	{"SETROAMRESCANRSSIDIFF",     drv_cmd_set_roam_rescan_rssi_diff, true},
+	{"GETROAMRESCANRSSIDIFF",     drv_cmd_get_roam_rescan_rssi_diff, false},
+	{"SETFASTROAM",               drv_cmd_set_fast_roam, true},
+	{"SETFASTTRANSITION",         drv_cmd_set_fast_transition, true},
+	{"FASTREASSOC",               drv_cmd_fast_reassoc, true},
+	{"SETROAMSCANCONTROL",        drv_cmd_set_roam_scan_control, true},
+	{"SETOKCMODE",                drv_cmd_set_okc_mode, true},
+	{"GETROAMSCANCONTROL",        drv_cmd_get_roam_scan_control, false},
+	{"BTCOEXMODE",                drv_cmd_bt_coex_mode, true},
+	{"SCAN-ACTIVE",               drv_cmd_scan_active, false},
+	{"SCAN-PASSIVE",              drv_cmd_scan_passive, false},
+#ifdef WLAN_AP_STA_CONCURRENCY
+	{"CONCSETDWELLTIME",          drv_cmd_conc_set_dwell_time, true},
+#endif
+	{"GETDWELLTIME",              drv_cmd_get_dwell_time, false},
+	{"SETDWELLTIME",              drv_cmd_set_dwell_time, true},
+	{"MIRACAST",                  drv_cmd_miracast, true},
+	{"SETIBSSBEACONOUIDATA",      drv_cmd_set_ibss_beacon_oui_data, true},
+#ifdef FEATURE_WLAN_RMC
+	{"SETRMCENABLE",              drv_cmd_set_rmc_enable, true},
+	{"SETRMCACTIONPERIOD",        drv_cmd_set_rmc_action_period, true},
+	{"SETRMCTXRATE",              drv_cmd_set_rmc_tx_rate, true},
+#endif
+	{"GETIBSSPEERINFOALL",        drv_cmd_get_ibss_peer_info_all, false},
+	{"GETIBSSPEERINFO",           drv_cmd_get_ibss_peer_info, true},
+	{"SETIBSSTXFAILEVENT",        drv_cmd_set_ibss_tx_fail_event, true},
+#ifdef FEATURE_WLAN_ESE
+	{"SETCCXROAMSCANCHANNELS",    drv_cmd_set_ccx_roam_scan_channels, true},
+	{"GETTSMSTATS",               drv_cmd_get_tsm_stats, true},
+	{"SETCCKMIE",                 drv_cmd_set_cckm_ie, true},
+	{"CCXBEACONREQ",	      drv_cmd_ccx_beacon_req, true},
+	{"CCXPLMREQ",                 drv_cmd_ccx_plm_req, true},
+	{"SETCCXMODE",                drv_cmd_set_ccx_mode, true},
+#endif /* FEATURE_WLAN_ESE */
+	{"SETMCRATE",                 drv_cmd_set_mc_rate, true},
+	{"MAXTXPOWER",                drv_cmd_max_tx_power, true},
+	{"SETDFSSCANMODE",            drv_cmd_set_dfs_scan_mode, true},
+	{"GETDFSSCANMODE",            drv_cmd_get_dfs_scan_mode, false},
+	{"GETLINKSTATUS",             drv_cmd_get_link_status, false},
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+	{"ENABLEEXTWOW",              drv_cmd_enable_ext_wow, true},
+	{"SETAPP1PARAMS",             drv_cmd_set_app1_params, true},
+	{"SETAPP2PARAMS",             drv_cmd_set_app2_params, true},
+#endif
+#ifdef FEATURE_WLAN_TDLS
+	{"TDLSSECONDARYCHANNELOFFSET", drv_cmd_tdls_secondary_channel_offset,
+	 true},
+	{"TDLSOFFCHANNELMODE",        drv_cmd_tdls_off_channel_mode, true},
+	{"TDLSOFFCHANNEL",            drv_cmd_tdls_off_channel, true},
+	{"TDLSSCAN",                  drv_cmd_tdls_scan, true},
+#endif
+	{"RSSI",                      drv_cmd_get_rssi, false},
+	{"LINKSPEED",                 drv_cmd_get_linkspeed, false},
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+	{"RXFILTER-REMOVE",           drv_cmd_rx_filter_remove, true},
+	{"RXFILTER-ADD",              drv_cmd_rx_filter_add, true},
+#endif
+	{"SET_FCC_CHANNEL",           drv_cmd_set_fcc_channel, true},
+	{"CHANNEL_SWITCH",            drv_cmd_set_channel_switch, true},
+	{"SETANTENNAMODE",            drv_cmd_set_antenna_mode, true},
+	{"GETANTENNAMODE",            drv_cmd_get_antenna_mode, false},
+	{"SET_DISABLE_CHANNEL_LIST",  drv_cmd_set_disable_chan_list, true},
+	{"GET_DISABLE_CHANNEL_LIST",  drv_cmd_get_disable_chan_list, false},
+	{"STOP",                      drv_cmd_dummy, false},
+	/* Deprecated commands */
+	{"RXFILTER-START",            drv_cmd_dummy, false},
+	{"RXFILTER-STOP",             drv_cmd_dummy, false},
+	{"BTCOEXSCAN-START",          drv_cmd_dummy, false},
+	{"BTCOEXSCAN-STOP",           drv_cmd_dummy, false},
+};
+
+/**
+ * hdd_drv_cmd_process() - chooses and runs the proper
+ *                                handler based on the input command
+ * @adapter:	Pointer to the hdd adapter
+ * @cmd:	Pointer to the driver command
+ * @priv_data:	Pointer to the data associated with the command
+ *
+ * This function parses the input hdd driver command and runs
+ * the proper handler
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int hdd_drv_cmd_process(struct hdd_adapter *adapter,
+			       uint8_t *cmd,
+			       struct hdd_priv_data *priv_data)
+{
+	struct hdd_context *hdd_ctx;
+	int i;
+	const int cmd_num_total = ARRAY_SIZE(hdd_drv_cmds);
+	uint8_t *cmd_i = NULL;
+	hdd_drv_cmd_handler_t handler = NULL;
+	int len = 0, cmd_len = 0;
+	uint8_t *ptr;
+	bool args;
+
+	if (!adapter || !cmd || !priv_data) {
+		hdd_err("at least 1 param is NULL");
+		return -EINVAL;
+	}
+
+	/* Calculate length of the first word */
+	ptr = strchrnul(cmd, ' ');
+	cmd_len = ptr - cmd;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	for (i = 0; i < cmd_num_total; i++) {
+
+		cmd_i = (uint8_t *)hdd_drv_cmds[i].cmd;
+		handler = hdd_drv_cmds[i].handler;
+		len = strlen(cmd_i);
+		args = hdd_drv_cmds[i].args;
+
+		if (!handler) {
+			hdd_err("no. %d handler is NULL", i);
+			return -EINVAL;
+		}
+
+		if (len == cmd_len && strncasecmp(cmd, cmd_i, len) == 0) {
+			if (args && drv_cmd_validate(cmd, len))
+				return -EINVAL;
+
+			return handler(adapter, hdd_ctx,
+				       cmd, len, priv_data);
+		}
+	}
+
+	return drv_cmd_invalid(adapter, hdd_ctx, cmd, len, priv_data);
+}
+
+/**
+ * hdd_driver_command() - top level wlan hdd driver command handler
+ * @adapter:	Pointer to the hdd adapter
+ * @priv_data:	Pointer to the raw command data
+ *
+ * This function is the top level wlan hdd driver command handler. It
+ * handles the command with the help of hdd_drv_cmd_process()
+ *
+ * Return: 0 for success non-zero for failure
+ */
+static int hdd_driver_command(struct hdd_adapter *adapter,
+			      struct hdd_priv_data *priv_data)
+{
+	uint8_t *command = NULL;
+	int ret = 0;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
+		hdd_err("Driver module is closed; command can not be processed");
+		return -EINVAL;
+	}
+
+	/*
+	 * Note that valid pointers are provided by caller
+	 */
+
+	/* copy to local struct to avoid numerous changes to legacy code */
+	if (priv_data->total_len <= 0 ||
+	    priv_data->total_len > WLAN_PRIV_DATA_MAX_LEN) {
+		hdd_warn("Invalid priv_data.total_len: %d!!!",
+			  priv_data->total_len);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Allocate +1 for '\0' */
+	command = qdf_mem_malloc(priv_data->total_len + 1);
+	if (!command) {
+		hdd_err("failed to allocate memory");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	if (copy_from_user(command, priv_data->buf, priv_data->total_len)) {
+		ret = -EFAULT;
+		goto exit;
+	}
+
+	/* Make sure the command is NUL-terminated */
+	command[priv_data->total_len] = '\0';
+
+	hdd_debug("%s: %s", adapter->dev->name, command);
+	ret = hdd_drv_cmd_process(adapter, command, priv_data);
+
+exit:
+	if (command)
+		qdf_mem_free(command);
+	hdd_exit();
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static int hdd_driver_compat_ioctl(struct hdd_adapter *adapter, struct ifreq *ifr)
+{
+	struct {
+		compat_uptr_t buf;
+		int used_len;
+		int total_len;
+	} compat_priv_data;
+	struct hdd_priv_data priv_data;
+	int ret = 0;
+
+	/*
+	 * Note that adapter and ifr have already been verified by caller,
+	 * and HDD context has also been validated
+	 */
+	if (copy_from_user(&compat_priv_data, ifr->ifr_data,
+			   sizeof(compat_priv_data))) {
+		ret = -EFAULT;
+		goto exit;
+	}
+	priv_data.buf = compat_ptr(compat_priv_data.buf);
+	priv_data.used_len = compat_priv_data.used_len;
+	priv_data.total_len = compat_priv_data.total_len;
+	ret = hdd_driver_command(adapter, &priv_data);
+exit:
+	return ret;
+}
+#else /* CONFIG_COMPAT */
+static int hdd_driver_compat_ioctl(struct hdd_adapter *adapter, struct ifreq *ifr)
+{
+	/* will never be invoked */
+	return 0;
+}
+#endif /* CONFIG_COMPAT */
+
+static int hdd_driver_ioctl(struct hdd_adapter *adapter, struct ifreq *ifr)
+{
+	struct hdd_priv_data priv_data;
+	int ret = 0;
+
+	/*
+	 * Note that adapter and ifr have already been verified by caller,
+	 * and HDD context has also been validated
+	 */
+	if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data)))
+		ret = -EFAULT;
+	else
+		ret = hdd_driver_command(adapter, &priv_data);
+
+	return ret;
+}
+
+/**
+ * __hdd_ioctl() - ioctl handler for wlan network interfaces
+ * @dev: device upon which the ioctl was received
+ * @ifr: ioctl request information
+ * @cmd: ioctl command
+ *
+ * This function does initial processing of wlan device ioctls.
+ * Currently two flavors of ioctls are supported.  The primary ioctl
+ * that is supported is the (SIOCDEVPRIVATE + 1) ioctl which is used
+ * for Android "DRIVER" commands.  The other ioctl that is
+ * conditionally supported is the SIOCIOCTLTX99 ioctl which is used
+ * for FTM on some platforms.  This function simply verifies that the
+ * driver is in a sane state, and that the ioctl is one of the
+ * supported flavors, in which case flavor-specific handlers are
+ * dispatched.
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	if (dev != adapter->dev) {
+		hdd_err("HDD adapter/dev inconsistency");
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	if ((!ifr) || (!ifr->ifr_data)) {
+		hdd_err("invalid data cmd: %d", cmd);
+		ret = -EINVAL;
+		goto exit;
+	}
+#if  defined(QCA_WIFI_FTM) && defined(LINUX_QCMBR)
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		if (SIOCIOCTLTX99 == cmd) {
+			ret = wlan_hdd_qcmbr_unified_ioctl(adapter, ifr);
+			goto exit;
+		}
+	}
+#endif
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		goto exit;
+
+	switch (cmd) {
+	case (SIOCDEVPRIVATE + 1):
+		if (in_compat_syscall())
+			ret = hdd_driver_compat_ioctl(adapter, ifr);
+		else
+			ret = hdd_driver_ioctl(adapter, ifr);
+		break;
+	default:
+		hdd_warn("unknown ioctl %d", cmd);
+		ret = -EINVAL;
+		break;
+	}
+exit:
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * hdd_ioctl() - ioctl handler (wrapper) for wlan network interfaces
+ * @dev: device upon which the ioctl was received
+ * @ifr: ioctl request information
+ * @cmd: ioctl command
+ *
+ * This function acts as an SSR-protecting wrapper to __hdd_ioctl()
+ * which is where the ioctls are really handled.
+ *
+ * Return: 0 on success, non-zero on error
+ */
+int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_ioctl(dev, ifr, cmd);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
diff --git a/core/hdd/src/wlan_hdd_ioctl.h b/core/hdd/src/wlan_hdd_ioctl.h
new file mode 100644
index 0000000..27708e0
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_ioctl.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012-2014, 2017-2018 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.
+ */
+
+#if !defined(WLAN_HDD_IOCTL_H)
+#define WLAN_HDD_IOCTL_H
+
+#include <linux/netdevice.h>
+#include <uapi/linux/if.h>
+#include "wlan_hdd_main.h"
+
+extern struct sock *cesium_nl_srv_sock;
+
+int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+int wlan_hdd_set_mc_rate(struct hdd_adapter *adapter, int targetRate);
+
+/**
+ * hdd_update_smps_antenna_mode() - set smps and antenna mode
+ * @hdd_ctx: Pointer to hdd context
+ * @mode: antenna mode
+ *
+ * This function will set smps and antenna mode.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS hdd_update_smps_antenna_mode(struct hdd_context *hdd_ctx, int mode);
+
+/**
+ * hdd_set_antenna_mode() - SET ANTENNA MODE command handler
+ * @adapter: Pointer to network adapter
+ * @hdd_ctx: Pointer to hdd context
+ * @mode: new anteena mode
+ */
+int hdd_set_antenna_mode(struct hdd_adapter *adapter,
+			  struct hdd_context *hdd_ctx, int mode);
+
+#endif /* end #if !defined(WLAN_HDD_IOCTL_H) */
+
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
new file mode 100644
index 0000000..76b193c
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 2013-2018 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: wlan_hdd_ipa.c
+ *
+ * WLAN HDD and ipa interface implementation
+ */
+
+/* Include Files */
+#include <wlan_hdd_includes.h>
+#include <wlan_hdd_ipa.h>
+#include "wlan_policy_mgr_api.h"
+#include "wlan_ipa_ucfg_api.h"
+#include <wlan_hdd_softap_tx_rx.h>
+#include <linux/inetdevice.h>
+
+void hdd_ipa_set_tx_flow_info(void)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_station_ctx *sta_ctx;
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	struct hdd_hostapd_state *hostapd_state;
+	struct qdf_mac_addr staBssid = QDF_MAC_ADDR_ZERO_INIT;
+	struct qdf_mac_addr p2pBssid = QDF_MAC_ADDR_ZERO_INIT;
+	struct qdf_mac_addr apBssid = QDF_MAC_ADDR_ZERO_INIT;
+	uint8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
+	const char *p2pMode = "DEV";
+	struct hdd_context *hdd_ctx;
+	struct cds_context *cds_ctx;
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+	uint8_t targetChannel = 0;
+	uint8_t preAdapterChannel = 0;
+	uint8_t channel24;
+	uint8_t channel5;
+	struct hdd_adapter *preAdapterContext = NULL;
+	struct hdd_adapter *adapter2_4 = NULL;
+	struct hdd_adapter *adapter5 = NULL;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+	struct wlan_objmgr_psoc *psoc;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return;
+	}
+
+	cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+	if (!cds_ctx) {
+		hdd_err("Invalid CDS Context");
+		return;
+	}
+
+	psoc = hdd_ctx->psoc;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		switch (adapter->device_mode) {
+		case QDF_STA_MODE:
+			sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+			if (eConnectionState_Associated ==
+			    sta_ctx->conn_info.connState) {
+				staChannel =
+					sta_ctx->conn_info.operationChannel;
+				qdf_copy_macaddr(&staBssid,
+						 &sta_ctx->conn_info.bssId);
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+				targetChannel = staChannel;
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+			}
+			break;
+		case QDF_P2P_CLIENT_MODE:
+			sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+			if (eConnectionState_Associated ==
+			    sta_ctx->conn_info.connState) {
+				p2pChannel =
+					sta_ctx->conn_info.operationChannel;
+				qdf_copy_macaddr(&p2pBssid,
+						&sta_ctx->conn_info.bssId);
+				p2pMode = "CLI";
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+				targetChannel = p2pChannel;
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+			}
+			break;
+		case QDF_P2P_GO_MODE:
+			hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+			hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+			if (hostapd_state->bss_state == BSS_START
+			    && hostapd_state->qdf_status ==
+			    QDF_STATUS_SUCCESS) {
+				p2pChannel = hdd_ap_ctx->operating_channel;
+				qdf_copy_macaddr(&p2pBssid,
+						 &adapter->mac_addr);
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+				targetChannel = p2pChannel;
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+			}
+			p2pMode = "GO";
+			break;
+		case QDF_SAP_MODE:
+			hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+			hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+			if (hostapd_state->bss_state == BSS_START
+			    && hostapd_state->qdf_status ==
+			    QDF_STATUS_SUCCESS) {
+				apChannel = hdd_ap_ctx->operating_channel;
+				qdf_copy_macaddr(&apBssid,
+						&adapter->mac_addr);
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+				targetChannel = apChannel;
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+			}
+			break;
+		case QDF_IBSS_MODE:
+		default:
+			break;
+		}
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+		if (targetChannel) {
+			/*
+			 * This is first adapter detected as active
+			 * set as default for none concurrency case
+			 */
+			if (!preAdapterChannel) {
+				/* If IPA UC data path is enabled,
+				 * target should reserve extra tx descriptors
+				 * for IPA data path.
+				 * Then host data path should allow less TX
+				 * packet pumping in case IPA
+				 * data path enabled
+				 */
+				if (ucfg_ipa_uc_is_enabled() &&
+				    (QDF_SAP_MODE == adapter->device_mode)) {
+					adapter->tx_flow_low_watermark =
+					hdd_ctx->config->tx_flow_low_watermark +
+					WLAN_TFC_IPAUC_TX_DESC_RESERVE;
+				} else {
+					adapter->tx_flow_low_watermark =
+						hdd_ctx->config->
+							tx_flow_low_watermark;
+				}
+				adapter->tx_flow_hi_watermark_offset =
+				   hdd_ctx->config->tx_flow_hi_watermark_offset;
+				cdp_fc_ll_set_tx_pause_q_depth(soc,
+						adapter->session_id,
+						hdd_ctx->config->
+						tx_flow_max_queue_depth);
+				hdd_info("MODE %d,CH %d,LWM %d,HWM %d,TXQDEP %d",
+				    adapter->device_mode,
+				    targetChannel,
+				    adapter->tx_flow_low_watermark,
+				    adapter->tx_flow_low_watermark +
+				    adapter->tx_flow_hi_watermark_offset,
+				    hdd_ctx->config->tx_flow_max_queue_depth);
+				preAdapterChannel = targetChannel;
+				preAdapterContext = adapter;
+			} else {
+				/*
+				 * SCC, disable TX flow control for both
+				 * SCC each adapter cannot reserve dedicated
+				 * channel resource, as a result, if any adapter
+				 * blocked OS Q by flow control,
+				 * blocked adapter will lost chance to recover
+				 */
+				if (preAdapterChannel == targetChannel) {
+					/* Current adapter */
+					adapter->tx_flow_low_watermark = 0;
+					adapter->
+					tx_flow_hi_watermark_offset = 0;
+					cdp_fc_ll_set_tx_pause_q_depth(soc,
+						adapter->session_id,
+						hdd_ctx->config->
+						tx_hbw_flow_max_queue_depth);
+					hdd_info("SCC: MODE %s(%d), CH %d, LWM %d, HWM %d, TXQDEP %d",
+					       qdf_opmode_str(
+							adapter->device_mode),
+					       adapter->device_mode,
+					       targetChannel,
+					       adapter->tx_flow_low_watermark,
+					       adapter->tx_flow_low_watermark +
+					       adapter->
+					       tx_flow_hi_watermark_offset,
+					       hdd_ctx->config->
+					       tx_hbw_flow_max_queue_depth);
+
+					if (!preAdapterContext) {
+						hdd_err("SCC: Previous adapter context NULL");
+						continue;
+					}
+
+					/* Previous adapter */
+					preAdapterContext->
+					tx_flow_low_watermark = 0;
+					preAdapterContext->
+					tx_flow_hi_watermark_offset = 0;
+					cdp_fc_ll_set_tx_pause_q_depth(soc,
+						preAdapterContext->session_id,
+						hdd_ctx->config->
+						tx_hbw_flow_max_queue_depth);
+					hdd_info("SCC: MODE %s(%d), CH %d, LWM %d, HWM %d, TXQDEP %d",
+					       qdf_opmode_str(
+						preAdapterContext->device_mode),
+					       preAdapterContext->device_mode,
+					       targetChannel,
+					       preAdapterContext->
+					       tx_flow_low_watermark,
+					       preAdapterContext->
+					       tx_flow_low_watermark +
+					       preAdapterContext->
+					       tx_flow_hi_watermark_offset,
+					       hdd_ctx->config->
+					       tx_hbw_flow_max_queue_depth);
+				}
+				/*
+				 * MCC, each adapter will have dedicated
+				 * resource
+				 */
+				else {
+					/* current channel is 2.4 */
+					if (targetChannel <=
+				     WLAN_HDD_TX_FLOW_CONTROL_MAX_24BAND_CH) {
+						channel24 = targetChannel;
+						channel5 = preAdapterChannel;
+						adapter2_4 = adapter;
+						adapter5 = preAdapterContext;
+					} else {
+						/* Current channel is 5 */
+						channel24 = preAdapterChannel;
+						channel5 = targetChannel;
+						adapter2_4 = preAdapterContext;
+						adapter5 = adapter;
+					}
+
+					if (!adapter5) {
+						hdd_err("MCC: 5GHz adapter context NULL");
+						continue;
+					}
+					adapter5->tx_flow_low_watermark =
+						hdd_ctx->config->
+						tx_hbw_flow_low_watermark;
+					adapter5->
+					tx_flow_hi_watermark_offset =
+						hdd_ctx->config->
+						tx_hbw_flow_hi_watermark_offset;
+					cdp_fc_ll_set_tx_pause_q_depth(soc,
+						adapter5->session_id,
+						hdd_ctx->config->
+						tx_hbw_flow_max_queue_depth);
+					hdd_info("MCC: MODE %s(%d), CH %d, LWM %d, HWM %d, TXQDEP %d",
+					    qdf_opmode_str(
+						    adapter5->device_mode),
+					    adapter5->device_mode,
+					    channel5,
+					    adapter5->tx_flow_low_watermark,
+					    adapter5->
+					    tx_flow_low_watermark +
+					    adapter5->
+					    tx_flow_hi_watermark_offset,
+					    hdd_ctx->config->
+					    tx_hbw_flow_max_queue_depth);
+
+					if (!adapter2_4) {
+						hdd_err("MCC: 2.4GHz adapter context NULL");
+						continue;
+					}
+					adapter2_4->tx_flow_low_watermark =
+						hdd_ctx->config->
+						tx_lbw_flow_low_watermark;
+					adapter2_4->
+					tx_flow_hi_watermark_offset =
+						hdd_ctx->config->
+						tx_lbw_flow_hi_watermark_offset;
+					cdp_fc_ll_set_tx_pause_q_depth(soc,
+						adapter2_4->session_id,
+						hdd_ctx->config->
+						tx_lbw_flow_max_queue_depth);
+					hdd_info("MCC: MODE %s(%d), CH %d, LWM %d, HWM %d, TXQDEP %d",
+						qdf_opmode_str(
+						    adapter2_4->device_mode),
+						adapter2_4->device_mode,
+						channel24,
+						adapter2_4->
+						tx_flow_low_watermark,
+						adapter2_4->
+						tx_flow_low_watermark +
+						adapter2_4->
+						tx_flow_hi_watermark_offset,
+						hdd_ctx->config->
+						tx_lbw_flow_max_queue_depth);
+
+				}
+			}
+		}
+		targetChannel = 0;
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+	}
+}
+
+#if defined(QCA_CONFIG_SMP) && defined(PF_WAKE_UP_IDLE)
+/**
+ * hdd_ipa_get_wake_up_idle() - Get PF_WAKE_UP_IDLE flag in the task structure
+ *
+ * Get PF_WAKE_UP_IDLE flag in the task structure
+ *
+ * Return: 1 if PF_WAKE_UP_IDLE flag is set, 0 otherwise
+ */
+static uint32_t hdd_ipa_get_wake_up_idle(void)
+{
+	return sched_get_wake_up_idle(current);
+}
+
+/**
+ * hdd_ipa_set_wake_up_idle() - Set PF_WAKE_UP_IDLE flag in the task structure
+ *
+ * Set PF_WAKE_UP_IDLE flag in the task structure
+ * This task and any task woken by this will be waken to idle CPU
+ *
+ * Return: None
+ */
+static void hdd_ipa_set_wake_up_idle(bool wake_up_idle)
+{
+	sched_set_wake_up_idle(current, wake_up_idle);
+}
+#else
+static uint32_t hdd_ipa_get_wake_up_idle(void)
+{
+	return 0;
+}
+
+static void hdd_ipa_set_wake_up_idle(bool wake_up_idle)
+{
+}
+#endif
+
+#ifdef QCA_CONFIG_SMP
+
+/**
+ * hdd_ipa_aggregated_rx_ind() - Submit aggregated packets to the stack
+ * @skb: skb to be submitted to the stack
+ *
+ * For CONFIG_SMP systems, simply call netif_rx_ni.
+ * For non CONFIG_SMP systems call netif_rx till
+ * IPA_WLAN_RX_SOFTIRQ_THRESH. When threshold is reached call netif_rx_ni.
+ * In this manner, UDP/TCP packets are sent in an aggregated way to the stack.
+ * For IP/ICMP packets, simply call netif_rx_ni.
+ *
+ * Return: return value from the netif_rx_ni/netif_rx api.
+ */
+static int hdd_ipa_aggregated_rx_ind(qdf_nbuf_t skb)
+{
+	int ret;
+
+	ret =  netif_rx_ni(skb);
+	return ret;
+}
+#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
+
+void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb, qdf_netdev_t dev)
+{
+	struct hdd_adapter *adapter = (struct hdd_adapter *) netdev_priv(dev);
+	int result;
+	unsigned int cpu_index;
+	uint8_t staid;
+	uint32_t enabled;
+
+	if (hdd_validate_adapter(adapter)) {
+		kfree_skb(skb);
+		return;
+	}
+
+	if (cds_is_driver_unloading()) {
+		kfree_skb(skb);
+		return;
+	}
+
+	if ((adapter->device_mode == QDF_SAP_MODE) &&
+	    (qdf_nbuf_is_ipv4_dhcp_pkt(skb) == true)) {
+		/* Send DHCP Indication to FW */
+		struct qdf_mac_addr *src_mac =
+			(struct qdf_mac_addr *)(skb->data +
+			QDF_NBUF_SRC_MAC_OFFSET);
+		if (QDF_STATUS_SUCCESS ==
+			hdd_softap_get_sta_id(adapter, src_mac, &staid))
+			hdd_inspect_dhcp_packet(adapter, staid, skb, QDF_RX);
+	}
+
+	/*
+	 * Set PF_WAKE_UP_IDLE flag in the task structure
+	 * This task and any task woken by this will be waken to idle CPU
+	 */
+	enabled = hdd_ipa_get_wake_up_idle();
+	if (!enabled)
+		hdd_ipa_set_wake_up_idle(true);
+
+	skb->dev = adapter->dev;
+	skb->protocol = eth_type_trans(skb, skb->dev);
+	skb->ip_summed = CHECKSUM_NONE;
+
+	cpu_index = wlan_hdd_get_cpu();
+
+	++adapter->hdd_stats.tx_rx_stats.rx_packets[cpu_index];
+
+	/*
+	 * Update STA RX exception packet stats.
+	 * For SAP as part of IPA HW stats are updated.
+	 */
+
+	++adapter->stats.rx_packets;
+	adapter->stats.rx_bytes += skb->len;
+	result = hdd_ipa_aggregated_rx_ind(skb);
+	if (result == NET_RX_SUCCESS)
+		++adapter->hdd_stats.tx_rx_stats.rx_delivered[cpu_index];
+	else
+		++adapter->hdd_stats.tx_rx_stats.rx_refused[cpu_index];
+
+	/*
+	 * Restore PF_WAKE_UP_IDLE flag in the task structure
+	 */
+	if (!enabled)
+		hdd_ipa_set_wake_up_idle(false);
+}
+
+void hdd_ipa_set_mcc_mode(bool mcc_mode)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return;
+	}
+
+	ucfg_ipa_set_mcc_mode(hdd_ctx->pdev, mcc_mode);
+}
diff --git a/core/hdd/src/wlan_hdd_lpass.c b/core/hdd/src/wlan_hdd_lpass.c
new file mode 100644
index 0000000..fddb33f
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_lpass.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_lpass.c
+ *
+ *  WLAN Host Device Driver LPASS feature implementation
+ *
+ */
+
+/* Include Files */
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_lpass.h"
+#include "wlan_hdd_oemdata.h"
+#include <cds_utils.h>
+#include "qwlan_version.h"
+
+/**
+ * wlan_hdd_get_channel_info() - Get channel info
+ * @hdd_ctx: HDD context
+ * @chan_info: Pointer to the structure that stores channel info
+ * @chan_id: Channel ID
+ *
+ * Fill in the channel info to chan_info structure.
+ */
+static void wlan_hdd_get_channel_info(struct hdd_context *hdd_ctx,
+				      struct svc_channel_info *chan_info,
+				      uint32_t chan_id)
+{
+	uint32_t reg_info_1;
+	uint32_t reg_info_2;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	status = sme_get_reg_info(hdd_ctx->mac_handle, chan_id,
+				  &reg_info_1, &reg_info_2);
+	if (status != QDF_STATUS_SUCCESS)
+		return;
+
+	chan_info->mhz = cds_chan_to_freq(chan_id);
+	chan_info->band_center_freq1 = chan_info->mhz;
+	chan_info->band_center_freq2 = 0;
+	chan_info->info = 0;
+	if (CHANNEL_STATE_DFS ==
+	    wlan_reg_get_channel_state(hdd_ctx->pdev,
+				       chan_id))
+		WMI_SET_CHANNEL_FLAG(chan_info,
+				     WMI_CHAN_FLAG_DFS);
+	hdd_update_channel_bw_info(hdd_ctx, chan_id,
+				   chan_info);
+	chan_info->reg_info_1 = reg_info_1;
+	chan_info->reg_info_2 = reg_info_2;
+}
+
+/**
+ * wlan_hdd_gen_wlan_status_pack() - Create lpass adapter status package
+ * @data: Status data record to be created
+ * @adapter: Adapter whose status is to being packaged
+ * @sta_ctx: Station-specific context of @adapter
+ * @is_on: Is wlan driver loaded?
+ * @is_connected: Is @adapter connected to an AP?
+ *
+ * Generate a wlan vdev status package. The status info includes wlan
+ * on/off status, vdev ID, vdev mode, supported channels, etc.
+ *
+ * Return: 0 if package was created, otherwise a negative errno
+ */
+static int wlan_hdd_gen_wlan_status_pack(struct wlan_status_data *data,
+					 struct hdd_adapter *adapter,
+					 struct hdd_station_ctx *sta_ctx,
+					 uint8_t is_on, uint8_t is_connected)
+{
+	struct hdd_context *hdd_ctx = NULL;
+	uint8_t buflen = WLAN_SVC_COUNTRY_CODE_LEN;
+	int i;
+	uint32_t chan_id;
+	struct svc_channel_info *chan_info;
+	bool lpass_support;
+	QDF_STATUS status;
+
+	if (!data) {
+		hdd_err("invalid data pointer");
+		return -EINVAL;
+	}
+	if (!adapter) {
+		if (is_on) {
+			/* no active interface */
+			data->lpss_support = 0;
+			data->is_on = is_on;
+			return 0;
+		}
+		hdd_err("invalid adapter pointer");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	status = ucfg_mlme_get_lpass_support(hdd_ctx->psoc, &lpass_support);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get LPASS support config");
+		return -EIO;
+	}
+
+	if (hdd_ctx->lpss_support && lpass_support)
+		data->lpss_support = 1;
+	else
+		data->lpss_support = 0;
+	data->numChannels = WLAN_SVC_MAX_NUM_CHAN;
+	sme_get_cfg_valid_channels(data->channel_list,
+				   &data->numChannels);
+
+	for (i = 0; i < data->numChannels; i++) {
+		chan_info = &data->channel_info[i];
+		chan_id = data->channel_list[i];
+		chan_info->chan_id = chan_id;
+		wlan_hdd_get_channel_info(hdd_ctx, chan_info, chan_id);
+	}
+
+	sme_get_country_code(hdd_ctx->mac_handle, data->country_code, &buflen);
+	data->is_on = is_on;
+	data->vdev_id = adapter->session_id;
+	data->vdev_mode = adapter->device_mode;
+	if (sta_ctx) {
+		data->is_connected = is_connected;
+		data->rssi = adapter->rssi;
+		data->freq =
+			cds_chan_to_freq(sta_ctx->conn_info.operationChannel);
+		if (WLAN_SVC_MAX_SSID_LEN >=
+		    sta_ctx->conn_info.SSID.SSID.length) {
+			data->ssid_len = sta_ctx->conn_info.SSID.SSID.length;
+			memcpy(data->ssid,
+			       sta_ctx->conn_info.SSID.SSID.ssId,
+			       sta_ctx->conn_info.SSID.SSID.length);
+		}
+		if (QDF_MAC_ADDR_SIZE >= sizeof(sta_ctx->conn_info.bssId))
+			memcpy(data->bssid, sta_ctx->conn_info.bssId.bytes,
+			       QDF_MAC_ADDR_SIZE);
+	}
+	return 0;
+}
+
+/**
+ * wlan_hdd_gen_wlan_version_pack() - Create lpass version package
+ * @data: Version data record to be created
+ * @fw_version: Version code from firmware
+ * @chip_id: WLAN chip ID
+ * @chip_name: WLAN chip name
+ *
+ * Generate a wlan software/hw version info package. The version info
+ * includes wlan host driver version, wlan fw driver version, wlan hw
+ * chip id & wlan hw chip name.
+ *
+ * Return: 0 if package was created, otherwise a negative errno
+ */
+static int wlan_hdd_gen_wlan_version_pack(struct wlan_version_data *data,
+					  uint32_t fw_version,
+					  uint32_t chip_id,
+					  const char *chip_name)
+{
+	if (!data) {
+		hdd_err("invalid data pointer");
+		return -EINVAL;
+	}
+
+	data->chip_id = chip_id;
+	strlcpy(data->chip_name, chip_name, WLAN_SVC_MAX_STR_LEN);
+	if (strncmp(chip_name, "Unknown", 7))
+		strlcpy(data->chip_from, "Qualcomm", WLAN_SVC_MAX_STR_LEN);
+	else
+		strlcpy(data->chip_from, "Unknown", WLAN_SVC_MAX_STR_LEN);
+	strlcpy(data->host_version, QWLAN_VERSIONSTR, WLAN_SVC_MAX_STR_LEN);
+	scnprintf(data->fw_version, WLAN_SVC_MAX_STR_LEN, "%d.%d.%d.%d",
+		  (fw_version & 0xf0000000) >> 28,
+		  (fw_version & 0xf000000) >> 24,
+		  (fw_version & 0xf00000) >> 20, (fw_version & 0x7fff));
+	return 0;
+}
+
+/**
+ * wlan_hdd_send_status_pkg() - Send adapter status to lpass
+ * @adapter: Adapter whose status is to be sent to lpass
+ * @sta_ctx: Station-specific context of @adapter
+ * @is_on: Is @adapter enabled
+ * @is_connected: Is @adapter connected
+ *
+ * Generate wlan vdev status package and send it to a user space
+ * daemon through netlink.
+ *
+ * Return: none
+ */
+static void wlan_hdd_send_status_pkg(struct hdd_adapter *adapter,
+				     struct hdd_station_ctx *sta_ctx,
+				     uint8_t is_on, uint8_t is_connected)
+{
+	int ret = 0;
+	struct wlan_status_data *data = NULL;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	if (!hdd_ctx)
+		return;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
+		return;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return;
+
+	if (is_on)
+		ret = wlan_hdd_gen_wlan_status_pack(data, adapter, sta_ctx,
+						    is_on, is_connected);
+
+	if (!ret)
+		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+					    WLAN_SVC_WLAN_STATUS_IND,
+					    data, sizeof(*data));
+	kfree(data);
+}
+
+/**
+ * wlan_hdd_send_version_pkg() - report version information to lpass
+ * @fw_version: Version code from firmware
+ * @chip_id: WLAN chip ID
+ * @chip_name: WLAN chip name
+ *
+ * Generate a wlan sw/hw version info package and send it to a user
+ * space daemon through netlink.
+ *
+ * Return: none
+ */
+static void wlan_hdd_send_version_pkg(uint32_t fw_version,
+				      uint32_t chip_id,
+				      const char *chip_name)
+{
+	int ret = 0;
+	struct wlan_version_data data;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	if (!hdd_ctx)
+		return;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
+		return;
+
+	memset(&data, 0, sizeof(struct wlan_version_data));
+	ret = wlan_hdd_gen_wlan_version_pack(&data, fw_version, chip_id,
+					     chip_name);
+	if (!ret)
+		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+					WLAN_SVC_WLAN_VERSION_IND,
+					    &data, sizeof(data));
+}
+
+/**
+ * wlan_hdd_send_scan_intf_info() - report scan interfaces to lpass
+ * @hdd_ctx: The global HDD context
+ * @adapter: Adapter that supports scanning.
+ *
+ * This function indicates adapter that supports scanning to lpass.
+ *
+ * Return: none
+ */
+static void wlan_hdd_send_scan_intf_info(struct hdd_context *hdd_ctx,
+					 struct hdd_adapter *adapter)
+{
+	if (!hdd_ctx) {
+		hdd_err("NULL pointer for hdd_ctx");
+		return;
+	}
+
+	if (!adapter) {
+		hdd_err("Adapter is Null");
+		return;
+	}
+
+	wlan_hdd_send_status_pkg(adapter, NULL, 1, 0);
+}
+
+/*
+ * hdd_lpass_target_config() - Handle LPASS target configuration
+ * (public function documented in wlan_hdd_lpass.h)
+ */
+void hdd_lpass_target_config(struct hdd_context *hdd_ctx,
+			     struct wma_tgt_cfg *target_config)
+{
+	hdd_ctx->lpss_support = target_config->lpss_support;
+}
+
+/*
+ * hdd_lpass_populate_cds_config() - Populate LPASS configuration
+ * (public function documented in wlan_hdd_lpass.h)
+ */
+void hdd_lpass_populate_cds_config(struct cds_config_info *cds_config,
+				   struct hdd_context *hdd_ctx)
+{
+	bool lpass_support = false;
+	QDF_STATUS status;
+
+	status = ucfg_mlme_get_lpass_support(hdd_ctx->psoc, &lpass_support);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to get LPASS support config");
+
+	cds_config->is_lpass_enabled = lpass_support;
+}
+
+/*
+ * hdd_lpass_populate_pmo_config() - Populate LPASS configuration
+ * (public function documented in wlan_hdd_lpass.h)
+ */
+void hdd_lpass_populate_pmo_config(struct pmo_psoc_cfg *pmo_config,
+				   struct hdd_context *hdd_ctx)
+{
+	bool lpass_support = false;
+	QDF_STATUS status;
+
+	status = ucfg_mlme_get_lpass_support(hdd_ctx->psoc, &lpass_support);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to get LPASS support config");
+
+	pmo_config->lpass_enable = lpass_support;
+}
+
+/*
+ * hdd_lpass_notify_connect() - Notify LPASS of interface connect
+ * (public function documented in wlan_hdd_lpass.h)
+ */
+void hdd_lpass_notify_connect(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx;
+
+	/* only send once per connection */
+	if (adapter->rssi_send)
+		return;
+
+	/* don't send if driver is unloading */
+	if (cds_is_driver_unloading())
+		return;
+
+	adapter->rssi_send = true;
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	wlan_hdd_send_status_pkg(adapter, sta_ctx, 1, 1);
+}
+
+/*
+ * hdd_lpass_notify_disconnect() - Notify LPASS of interface disconnect
+ * (public function documented in wlan_hdd_lpass.h)
+ */
+void hdd_lpass_notify_disconnect(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx;
+
+	adapter->rssi_send = false;
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	wlan_hdd_send_status_pkg(adapter, sta_ctx, 1, 0);
+}
+
+void hdd_lpass_notify_mode_change(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx;
+
+	if (!adapter || adapter->device_mode != QDF_STA_MODE)
+		return;
+
+	hdd_debug("Sending Lpass mode change notification");
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	wlan_hdd_send_scan_intf_info(hdd_ctx, adapter);
+}
+
+/*
+ * hdd_lpass_notify_wlan_version() - Notify LPASS WLAN Host/FW version
+ *
+ * implementation note: Notify LPASS for the WLAN host/firmware version.
+ */
+void hdd_lpass_notify_wlan_version(struct hdd_context *hdd_ctx)
+{
+	hdd_enter();
+
+	wlan_hdd_send_version_pkg(hdd_ctx->target_fw_version,
+				  hdd_ctx->target_hw_version,
+				  hdd_ctx->target_hw_name);
+
+	hdd_exit();
+}
+
+void hdd_lpass_notify_start(struct hdd_context *hdd_ctx,
+			    struct hdd_adapter *adapter)
+{
+	hdd_enter();
+
+	if (!adapter || adapter->device_mode != QDF_STA_MODE)
+		return;
+
+	hdd_debug("Sending Start Lpass notification");
+
+	wlan_hdd_send_scan_intf_info(hdd_ctx, adapter);
+
+	hdd_exit();
+}
+
+void hdd_lpass_notify_stop(struct hdd_context *hdd_ctx)
+{
+	hdd_debug("Sending Lpass stop notifcation");
+	wlan_hdd_send_status_pkg(NULL, NULL, 0, 0);
+}
+
+/*
+ * hdd_lpass_is_supported() - Is lpass feature supported?
+ * (public function documented in wlan_hdd_lpass.h)
+ */
+bool hdd_lpass_is_supported(struct hdd_context *hdd_ctx)
+{
+	bool lpass_support = false;
+	QDF_STATUS status;
+
+	status = ucfg_mlme_get_lpass_support(hdd_ctx->psoc, &lpass_support);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to get LPASS support config");
+
+	return lpass_support;
+}
diff --git a/core/hdd/src/wlan_hdd_lpass.h b/core/hdd/src/wlan_hdd_lpass.h
new file mode 100644
index 0000000..4896242
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_lpass.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#if !defined(WLAN_HDD_LPASS_H)
+#define WLAN_HDD_LPASS_H
+
+struct cds_config_info;
+struct wma_tgt_cfg;
+struct hdd_context;
+struct hdd_adapter;
+
+#ifdef WLAN_FEATURE_LPSS
+/**
+ * hdd_lpass_target_config() - Handle LPASS target configuration
+ * @hdd_ctx: HDD global context where lpass information is stored
+ * @target_config: Target configuration containing lpass info
+ *
+ * This function updates the HDD context with lpass-specific
+ * information provided by the target.
+ *
+ * Return: none
+ */
+void hdd_lpass_target_config(struct hdd_context *hdd_ctx,
+			     struct wma_tgt_cfg *target_config);
+
+/**
+ * hdd_lpass_populate_cds_config() - Populate LPASS configuration
+ * @cds_config: CDS configuration to populate with lpass info
+ * @hdd_ctx: HDD global context which contains lpass information
+ *
+ * This function seeds the CDS configuration structure with
+ * lpass-specific information gleaned from the HDD context.
+ *
+ * Return: none
+ */
+void hdd_lpass_populate_cds_config(struct cds_config_info *cds_config,
+				   struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_lpass_populate_pmo_config() - Populate LPASS configuration
+ * @pmo_config: PMO configuration to populate with lpass info
+ * @hdd_ctx: HDD global context which contains lpass information
+ *
+ * This function seeds the PMO configuration structure with
+ * lpass-specific information gleaned from the HDD context.
+ *
+ * Return: none
+ */
+void hdd_lpass_populate_pmo_config(struct pmo_psoc_cfg *pmo_config,
+				   struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_lpass_notify_connect() - Notify LPASS of interface connect
+ * @adapter: The adapter that connected
+ *
+ * This function is used to notify the LPASS feature that an adapter
+ * has connected.
+ *
+ * Return: none
+ */
+void hdd_lpass_notify_connect(struct hdd_adapter *adapter);
+
+/**
+ * hdd_lpass_notify_disconnect() - Notify LPASS of interface disconnect
+ * @adapter: The adapter that connected
+ *
+ * This function is used to notify the LPASS feature that an adapter
+ * has disconnected.
+ *
+ * Return: none
+ */
+void hdd_lpass_notify_disconnect(struct hdd_adapter *adapter);
+
+/**
+ * hdd_lpass_notify_mode_change() - Notify LPASS of interface mode change
+ * @adapter: The adapter whose mode was changed
+ *
+ * This function is used to notify the LPASS feature that an adapter
+ * had its mode changed.
+ *
+ * Return: none
+ */
+void hdd_lpass_notify_mode_change(struct hdd_adapter *adapter);
+
+/**
+ * hdd_lpass_notify_start() - Notify LPASS of driver start
+ * @hdd_ctx: The global HDD context
+ * @adapter: adapter for which notification is send
+ *
+ * This function is used to notify the LPASS feature that the wlan
+ * driver has (re-)started.
+ *
+ * Return: none
+ */
+void hdd_lpass_notify_start(struct hdd_context *hdd_ctx,
+			    struct hdd_adapter *adapter);
+
+/**
+ * hdd_lpass_notify_stop() - Notify LPASS of driver stop
+ * @hdd_ctx: The global HDD context
+ *
+ * This function is used to notify the LPASS feature that the wlan
+ * driver has stopped.
+ *
+ * Return: none
+ */
+void hdd_lpass_notify_stop(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_lpass_is_supported() - Is lpass feature supported?
+ * @hdd_ctx: The global HDD context
+ *
+ * Return: true if feature is enabled and supported by firmware, false
+ * if the feature is not enabled or not supported by firmware.
+ */
+bool hdd_lpass_is_supported(struct hdd_context *hdd_ctx);
+
+/*
+ * hdd_lpass_notify_wlan_version() - Notify LPASS WLAN Host/FW version
+ * @hdd_ctx: The global HDD context
+ *
+ * Notify LPASS for the WLAN host/firmware and hardware version.
+ *
+ * Return: none
+ */
+void hdd_lpass_notify_wlan_version(struct hdd_context *hdd_ctx);
+#else
+static inline void hdd_lpass_target_config(struct hdd_context *hdd_ctx,
+					   struct wma_tgt_cfg *target_config)
+{
+}
+static inline
+void hdd_lpass_populate_cds_config(struct cds_config_info *cds_config,
+				   struct hdd_context *hdd_ctx)
+{
+}
+
+static inline
+void hdd_lpass_populate_pmo_config(struct pmo_psoc_cfg *pmo_config,
+				   struct hdd_context *hdd_ctx)
+{
+}
+
+static inline void hdd_lpass_notify_connect(struct hdd_adapter *adapter)
+{
+}
+static inline void hdd_lpass_notify_disconnect(struct hdd_adapter *adapter)
+{
+}
+static inline void hdd_lpass_notify_mode_change(struct hdd_adapter *adapter)
+{
+}
+
+static inline void hdd_lpass_notify_start(struct hdd_context *hdd_ctx,
+					  struct hdd_adapter *adapter)
+{
+}
+
+static inline void hdd_lpass_notify_stop(struct hdd_context *hdd_ctx) { }
+static inline bool hdd_lpass_is_supported(struct hdd_context *hdd_ctx)
+{
+	return false;
+}
+
+static inline void hdd_lpass_notify_wlan_version(struct hdd_context *hdd_ctx)
+{
+}
+
+#endif
+
+#endif /* WLAN_HDD_LPASS_H */
diff --git a/core/hdd/src/wlan_hdd_lro.c b/core/hdd/src/wlan_hdd_lro.c
new file mode 100644
index 0000000..f5057f7
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_lro.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2015-2018 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: wlan_hdd_lro.c
+ *
+ * WLAN HDD LRO interface implementation
+ */
+
+#include <wlan_hdd_includes.h>
+#include <qdf_types.h>
+#include <qdf_lro.h>
+#include <wlan_hdd_lro.h>
+#include <wlan_hdd_napi.h>
+#include <wma_api.h>
+
+#include <linux/inet_lro.h>
+#include <linux/list.h>
+#include <linux/random.h>
+#include <net/tcp.h>
+
+#define LRO_VALID_FIELDS \
+	(LRO_DESC | LRO_ELIGIBILITY_CHECKED | LRO_TCP_ACK_NUM | \
+	 LRO_TCP_DATA_CSUM | LRO_TCP_SEQ_NUM | LRO_TCP_WIN)
+
+#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390)
+static qdf_lro_ctx_t wlan_hdd_get_lro_ctx(struct sk_buff *skb)
+{
+	return (qdf_lro_ctx_t)QDF_NBUF_CB_RX_LRO_CTX(skb);
+}
+#else
+static qdf_lro_ctx_t wlan_hdd_get_lro_ctx(struct sk_buff *skb)
+{
+	struct hif_opaque_softc *hif_hdl =
+		(struct hif_opaque_softc *)cds_get_context(QDF_MODULE_ID_HIF);
+	if (hif_hdl == NULL) {
+		hdd_err("hif_hdl is NULL");
+		return NULL;
+	}
+
+	return hif_get_lro_info(QDF_NBUF_CB_RX_CTX_ID(skb), hif_hdl);
+}
+#endif
+
+/**
+ * hdd_lro_rx() - LRO receive function
+ * @adapter: HDD adapter
+ * @skb: network buffer
+ *
+ * Delivers LRO eligible frames to the LRO manager
+ *
+ * Return: QDF_STATUS_SUCCESS - frame delivered to LRO manager
+ * QDF_STATUS_E_FAILURE - frame not delivered
+ */
+QDF_STATUS hdd_lro_rx(struct hdd_adapter *adapter, struct sk_buff *skb)
+{
+	qdf_lro_ctx_t ctx;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct qdf_lro_info info;
+	struct net_lro_desc *lro_desc = NULL;
+
+	if ((adapter->dev->features & NETIF_F_LRO) != NETIF_F_LRO)
+		return QDF_STATUS_E_NOSUPPORT;
+
+	ctx = wlan_hdd_get_lro_ctx(skb);
+	if (!ctx) {
+		hdd_err("LRO mgr is NULL");
+		return status;
+	}
+
+	info.iph = skb->data;
+	info.tcph = skb->data + QDF_NBUF_CB_RX_TCP_OFFSET(skb);
+	ctx->lro_mgr->dev = adapter->dev;
+	if (qdf_lro_get_info(ctx, skb, &info, (void **)&lro_desc)) {
+		struct net_lro_info hdd_lro_info;
+
+		hdd_lro_info.valid_fields = LRO_VALID_FIELDS;
+
+		hdd_lro_info.lro_desc = lro_desc;
+		hdd_lro_info.lro_eligible = 1;
+		hdd_lro_info.tcp_ack_num = QDF_NBUF_CB_RX_TCP_ACK_NUM(skb);
+		hdd_lro_info.tcp_data_csum =
+			 csum_unfold(htons(QDF_NBUF_CB_RX_TCP_CHKSUM(skb)));
+		hdd_lro_info.tcp_seq_num = QDF_NBUF_CB_RX_TCP_SEQ_NUM(skb);
+		hdd_lro_info.tcp_win = QDF_NBUF_CB_RX_TCP_WIN(skb);
+
+		lro_receive_skb_ext(ctx->lro_mgr, skb, (void *)adapter,
+				    &hdd_lro_info);
+
+		if (!hdd_lro_info.lro_desc->active)
+			qdf_lro_desc_free(ctx, lro_desc);
+
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		qdf_lro_flush_pkt(ctx, &info);
+	}
+	return status;
+}
+
+/**
+ * hdd_lro_display_stats() - display LRO statistics
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+void hdd_lro_display_stats(struct hdd_context *hdd_ctx)
+{
+	hdd_debug("LRO stats is broken, will fix it");
+}
+
+QDF_STATUS
+hdd_lro_set_reset(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
+			       uint8_t enable_flag)
+{
+	if ((hdd_ctx->ol_enable != CFG_LRO_ENABLED) ||
+	    (adapter->device_mode != QDF_STA_MODE)) {
+		hdd_debug("LRO is already Disabled");
+		return 0;
+	}
+
+	if (enable_flag) {
+		qdf_atomic_set(&hdd_ctx->vendor_disable_lro_flag, 0);
+		adapter->dev->features |= NETIF_F_LRO;
+	} else {
+		/* Disable LRO, Enable tcpdelack*/
+		qdf_atomic_set(&hdd_ctx->vendor_disable_lro_flag, 1);
+		adapter->dev->features &= ~NETIF_F_LRO;
+		hdd_debug("LRO Disabled");
+
+		if (hdd_ctx->config->enable_tcp_delack) {
+			struct wlan_rx_tp_data rx_tp_data;
+
+			hdd_debug("Enable TCP delack as LRO is disabled");
+			rx_tp_data.rx_tp_flags = TCP_DEL_ACK_IND;
+			rx_tp_data.level = GET_CUR_RX_LVL(hdd_ctx);
+			wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+						WLAN_SVC_WLAN_TP_IND,
+						&rx_tp_data,
+						sizeof(rx_tp_data));
+			hdd_ctx->en_tcp_delack_no_lro = 1;
+		}
+	}
+	return 0;
+}
+
+int hdd_is_lro_enabled(struct hdd_context *hdd_ctx)
+{
+	if (hdd_ctx->ol_enable != CFG_LRO_ENABLED)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
new file mode 100644
index 0000000..91c183e
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -0,0 +1,14710 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_main.c
+ *
+ *  WLAN Host Device Driver implementation
+ *
+ */
+
+/* Include Files */
+#include <wbuff.h>
+#include "cfg_ucfg_api.h"
+#include "wlan_dsc.h"
+#include <wlan_hdd_includes.h>
+#include <cds_api.h>
+#include <cds_sched.h>
+#include <linux/cpu.h>
+#include <linux/etherdevice.h>
+#include <linux/firmware.h>
+#include <wlan_hdd_tx_rx.h>
+#include <wni_api.h>
+#include <wlan_hdd_cfg.h>
+#include <wlan_ptt_sock_svc.h>
+#include <dbglog_host.h>
+#include <wlan_logging_sock_svc.h>
+#include <wlan_roam_debug.h>
+#include <wlan_hdd_wowl.h>
+#include <wlan_hdd_misc.h>
+#include <wlan_hdd_wext.h>
+#include "wlan_hdd_trace.h"
+#include "wlan_hdd_ioctl.h"
+#include "wlan_hdd_ftm.h"
+#include "wlan_hdd_power.h"
+#include "wlan_hdd_stats.h"
+#include "wlan_hdd_scan.h"
+#include "wlan_policy_mgr_ucfg.h"
+#include <wlan_osif_request_manager.h>
+#ifdef CONFIG_LEAK_DETECTION
+#include "qdf_debug_domain.h"
+#endif
+#include "qdf_str.h"
+#include "qdf_trace.h"
+#include "qdf_types.h"
+#include <cdp_txrx_peer_ops.h>
+#include <cdp_txrx_misc.h>
+#include <cdp_txrx_stats.h>
+#include "cdp_txrx_flow_ctrl_legacy.h"
+
+#include <net/addrconf.h>
+#include <linux/wireless.h>
+#include <net/cfg80211.h>
+#include <linux/inetdevice.h>
+#include <net/addrconf.h>
+#include "wlan_hdd_cfg80211.h"
+#include "wlan_hdd_ext_scan.h"
+#include "wlan_hdd_p2p.h"
+#include <linux/rtnetlink.h>
+#include "sap_api.h"
+#include <linux/semaphore.h>
+#include <linux/ctype.h>
+#include <linux/compat.h>
+#include <linux/reboot.h>
+#ifdef MSM_PLATFORM
+#include <soc/qcom/subsystem_restart.h>
+#endif
+#include <wlan_hdd_hostapd.h>
+#include <wlan_hdd_softap_tx_rx.h>
+#include <wlan_hdd_green_ap.h>
+#include "cfg_api.h"
+#include "qwlan_version.h"
+#include "wma_types.h"
+#include "wlan_hdd_tdls.h"
+#ifdef FEATURE_WLAN_CH_AVOID
+#include "cds_regdomain.h"
+#endif /* FEATURE_WLAN_CH_AVOID */
+#include "cdp_txrx_flow_ctrl_v2.h"
+#include "pld_common.h"
+#include "wlan_hdd_ocb.h"
+#include "wlan_hdd_nan.h"
+#include "wlan_hdd_debugfs.h"
+#include "wlan_hdd_debugfs_csr.h"
+#include "wlan_hdd_driver_ops.h"
+#include "epping_main.h"
+#include "wlan_hdd_data_stall_detection.h"
+
+#include <wlan_hdd_ipa.h>
+#include "hif.h"
+#include "wma.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_hdd_tsf.h"
+#include "bmi.h"
+#include <wlan_hdd_regulatory.h>
+#include "wlan_hdd_lpass.h"
+#include "nan_api.h"
+#include <wlan_hdd_napi.h>
+#include "wlan_hdd_disa.h"
+#include <dispatcher_init_deinit.h>
+#include "wlan_hdd_object_manager.h"
+#include "cds_utils.h"
+#include <cdp_txrx_handle.h>
+#include <qca_vendor.h>
+#include "wlan_pmo_ucfg_api.h"
+#include "sir_api.h"
+#include "os_if_wifi_pos.h"
+#include "wifi_pos_api.h"
+#include "wlan_hdd_oemdata.h"
+#include "wlan_hdd_he.h"
+#include "os_if_nan.h"
+#include "nan_public_structs.h"
+#include "wlan_reg_ucfg_api.h"
+#include "wlan_dfs_ucfg_api.h"
+#include "wlan_hdd_rx_monitor.h"
+#include "sme_power_save_api.h"
+#include "enet.h"
+#include <cdp_txrx_cmn_struct.h>
+#include <dp_txrx.h>
+#include "wlan_hdd_sysfs.h"
+#include "wlan_disa_ucfg_api.h"
+#include "wlan_disa_obj_mgmt_api.h"
+#include "wlan_action_oui_ucfg_api.h"
+#include "wlan_ipa_ucfg_api.h"
+#include <target_if.h>
+#include "wlan_hdd_nud_tracking.h"
+#include "wlan_hdd_apf.h"
+#include "wlan_hdd_twt.h"
+#include "qc_sap_ioctl.h"
+#include "wlan_mlme_main.h"
+#include "wlan_p2p_cfg_api.h"
+#include "wlan_tdls_cfg_api.h"
+#include <wlan_hdd_rssi_monitor.h>
+#include "wlan_mlme_ucfg_api.h"
+#include "wlan_fwol_ucfg_api.h"
+#include "wlan_policy_mgr_ucfg.h"
+#ifdef CNSS_GENL
+#include <net/cnss_nl.h>
+#endif
+#include "wlan_reg_ucfg_api.h"
+#include "wlan_ocb_ucfg_api.h"
+#include <wlan_hdd_spectralscan.h>
+#include "wlan_green_ap_ucfg_api.h"
+#include <wlan_p2p_ucfg_api.h>
+
+#ifdef MODULE
+#define WLAN_MODULE_NAME  module_name(THIS_MODULE)
+#else
+#define WLAN_MODULE_NAME  "wlan"
+#endif
+
+#ifdef TIMER_MANAGER
+#define TIMER_MANAGER_STR " +TIMER_MANAGER"
+#else
+#define TIMER_MANAGER_STR ""
+#endif
+
+#ifdef MEMORY_DEBUG
+#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
+#else
+#define MEMORY_DEBUG_STR ""
+#endif
+
+#ifdef PANIC_ON_BUG
+#define PANIC_ON_BUG_STR " +PANIC_ON_BUG"
+#else
+#define PANIC_ON_BUG_STR ""
+#endif
+
+bool g_is_system_reboot_triggered;
+int wlan_start_ret_val;
+static DECLARE_COMPLETION(wlan_start_comp);
+static unsigned int dev_num = 1;
+static struct cdev wlan_hdd_state_cdev;
+static struct class *class;
+static dev_t device;
+#ifndef MODULE
+static struct gwlan_loader *wlan_loader;
+static ssize_t wlan_boot_cb(struct kobject *kobj,
+			    struct kobj_attribute *attr,
+			    const char *buf, size_t count);
+struct gwlan_loader {
+	bool loaded_state;
+	struct kobject *boot_wlan_obj;
+	struct attribute_group *attr_group;
+};
+
+static struct kobj_attribute wlan_boot_attribute =
+	__ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
+
+static struct attribute *attrs[] = {
+	&wlan_boot_attribute.attr,
+	NULL,
+};
+
+#define MODULE_INITIALIZED 1
+
+#ifdef MULTI_IF_NAME
+#define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME
+#else
+#define WLAN_LOADER_NAME "boot_wlan"
+#endif
+#endif
+
+#define HDD_OPS_INACTIVITY_TIMEOUT (120000)
+#define MAX_OPS_NAME_STRING_SIZE 20
+#define RATE_LIMIT_ERROR_LOG (256)
+
+static qdf_timer_t hdd_drv_ops_inactivity_timer;
+static struct task_struct *hdd_drv_ops_task;
+static char drv_ops_string[MAX_OPS_NAME_STRING_SIZE];
+
+/* the Android framework expects this param even though we don't use it */
+#define BUF_LEN 20
+static char fwpath_buffer[BUF_LEN];
+static struct kparam_string fwpath = {
+	.string = fwpath_buffer,
+	.maxlen = BUF_LEN,
+};
+
+static char *country_code;
+static int enable_11d = -1;
+static int enable_dfs_chan_scan = -1;
+
+/*
+ * spinlock for synchronizing asynchronous request/response
+ * (full description of use in wlan_hdd_main.h)
+ */
+DEFINE_SPINLOCK(hdd_context_lock);
+DEFINE_MUTEX(hdd_init_deinit_lock);
+
+#define WLAN_NLINK_CESIUM 30
+
+static qdf_wake_lock_t wlan_wake_lock;
+
+#define WOW_MAX_FILTER_LISTS 1
+#define WOW_MAX_FILTERS_PER_LIST 4
+#define WOW_MIN_PATTERN_SIZE 6
+#define WOW_MAX_PATTERN_SIZE 64
+
+/* max peer can be tdls peers + self peer + bss peer */
+#define HDD_MAX_VDEV_PEER_COUNT  (HDD_MAX_NUM_TDLS_STA + 2)
+#define IS_IDLE_STOP (!cds_is_driver_unloading() && \
+		      !cds_is_driver_recovering() && !cds_is_driver_loading())
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
+static const struct wiphy_wowlan_support wowlan_support_reg_init = {
+	.flags = WIPHY_WOWLAN_ANY |
+		 WIPHY_WOWLAN_MAGIC_PKT |
+		 WIPHY_WOWLAN_DISCONNECT |
+		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+		 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
+		 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
+		 WIPHY_WOWLAN_4WAY_HANDSHAKE |
+		 WIPHY_WOWLAN_RFKILL_RELEASE,
+	.n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
+	.pattern_min_len = WOW_MIN_PATTERN_SIZE,
+	.pattern_max_len = WOW_MAX_PATTERN_SIZE,
+};
+#endif
+
+static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
+	[QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
+	[QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
+	[QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
+	[QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
+	[QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
+	[QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_DP] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL},
+};
+
+struct notifier_block hdd_netdev_notifier;
+struct notifier_block system_reboot_notifier;
+
+struct sock *cesium_nl_srv_sock;
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+static void wlan_hdd_auto_shutdown_cb(void);
+#endif
+
+void hdd_start_complete(int ret)
+{
+	wlan_start_ret_val = ret;
+
+	complete(&wlan_start_comp);
+}
+
+/**
+ * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
+ * @hdd_ctx: pointer to struct hdd_context
+ *
+ * Return: none
+ */
+static void hdd_set_rps_cpu_mask(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter)
+		hdd_send_rps_ind(adapter);
+}
+
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter,
+			   enum netif_action_type action)
+{
+	if (!adapter->tx_flow_timer_initialized)
+		return;
+
+	if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) {
+		qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
+	} else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) {
+		QDF_STATUS status =
+		qdf_mc_timer_start(&adapter->tx_flow_control_timer,
+				   WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
+
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("Failed to start tx_flow_control_timer");
+		else
+			adapter->
+			hdd_stats.tx_rx_stats.txflow_timer_cnt++;
+
+		adapter->hdd_stats.tx_rx_stats.txflow_pause_cnt++;
+		adapter->hdd_stats.tx_rx_stats.is_txflow_paused = true;
+	}
+}
+#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
+
+/**
+ * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
+ * @vdev_id: vdev_id
+ * @action: action type
+ * @reason: reason type
+ *
+ * Return: none
+ */
+void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
+		enum netif_action_type action, enum netif_reason_type reason)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	struct hdd_adapter *adapter;
+
+	if (!hdd_ctx) {
+		hdd_err("hdd ctx is NULL");
+		return;
+	}
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	wlan_hdd_mod_fc_timer(adapter, action);
+	wlan_hdd_netif_queue_control(adapter, action, reason);
+}
+
+/*
+ * Store WLAN driver version and timestamp info in global variables such that
+ * crash debugger can extract them from driver debug symbol and crashdump for
+ * post processing
+ */
+#ifdef BUILD_TAG
+uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR "; " BUILD_TAG;
+#else
+uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR;
+#endif
+
+/**
+ * hdd_get_valid_chan() - return current chan list from regulatory.
+ * @hdd_ctx: HDD context
+ * @chan_list: buf hold returned chan list
+ * @chan_num: input buf size and output returned chan num
+ *
+ * This function helps get current available chan list from regulatory
+ * module. It excludes the "disabled" and "invalid" channels.
+ *
+ * Return: 0 for success.
+ */
+static int hdd_get_valid_chan(struct hdd_context *hdd_ctx,
+			      uint8_t *chan_list,
+			      uint32_t *chan_num)
+{
+	int i = 0, j = 0;
+	struct regulatory_channel *cur_chan_list;
+	struct wlan_objmgr_pdev *pdev;
+
+	if (!hdd_ctx || !hdd_ctx->pdev || !chan_list || !chan_num)
+		return -EINVAL;
+
+	pdev = hdd_ctx->pdev;
+	cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
+			sizeof(struct regulatory_channel));
+	if (!cur_chan_list)
+		return -ENOMEM;
+
+	if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) !=
+					   QDF_STATUS_SUCCESS) {
+		qdf_mem_free(cur_chan_list);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		uint32_t ch = cur_chan_list[i].chan_num;
+		enum channel_state state = wlan_reg_get_channel_state(pdev,
+								      ch);
+
+		if (state != CHANNEL_STATE_DISABLE &&
+		    state != CHANNEL_STATE_INVALID &&
+		    j < *chan_num) {
+			chan_list[j] = (uint8_t)ch;
+			j++;
+		}
+	}
+	*chan_num = j;
+	qdf_mem_free(cur_chan_list);
+	return 0;
+}
+
+/**
+ * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo
+ * @adapter: HDD adapter
+ * @chan_number: Channel number
+ * @chan_bw: Bandwidth
+ *
+ * Checks if the given bandwidth is valid for the given channel number.
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
+		uint32_t chan_number,
+		enum phy_ch_width chan_bw)
+{
+	uint8_t chan[NUM_CHANNELS];
+	uint32_t len = NUM_CHANNELS, i;
+	bool found = false;
+	mac_handle_t mac_handle;
+	int ret;
+
+	mac_handle = hdd_adapter_get_mac_handle(adapter);
+	if (!mac_handle) {
+		hdd_err("Invalid MAC handle");
+		return -EINVAL;
+	}
+
+	ret = hdd_get_valid_chan(adapter->hdd_ctx, chan,
+				 &len);
+	if (ret) {
+		hdd_err("error %d in getting valid channel list", ret);
+		return ret;
+	}
+
+	for (i = 0; i < len; i++) {
+		if (chan[i] == chan_number) {
+			found = true;
+			break;
+		}
+	}
+
+	if (found == false) {
+		hdd_err("Channel not in driver's valid channel list");
+		return -EOPNOTSUPP;
+	}
+
+	if ((!WLAN_REG_IS_24GHZ_CH(chan_number)) &&
+			(!WLAN_REG_IS_5GHZ_CH(chan_number))) {
+		hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number);
+		return -EINVAL;
+	}
+
+	if (WLAN_REG_IS_24GHZ_CH(chan_number)) {
+		if (chan_bw == CH_WIDTH_80MHZ) {
+			hdd_err("BW80 not possible in 2.4GHz band");
+			return -EINVAL;
+		}
+		if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) &&
+				(chan_bw != CH_WIDTH_MAX)) {
+			hdd_err("Only BW20 possible on channel 14");
+			return -EINVAL;
+		}
+	}
+
+	if (WLAN_REG_IS_5GHZ_CH(chan_number)) {
+		if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 165) &&
+				(chan_bw != CH_WIDTH_MAX)) {
+			hdd_err("Only BW20 possible on channel 165");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_wait_for_recovery_completion() - Wait for cds recovery completion
+ *
+ * Block the unloading of the driver (or) interface up until the
+ * cds recovery is completed
+ *
+ * Return: true for recovery completion else false
+ */
+static bool hdd_wait_for_recovery_completion(void)
+{
+	int retry = 0;
+
+	/* Wait for recovery to complete */
+	while (cds_is_driver_recovering()) {
+		if (retry == HDD_MOD_EXIT_SSR_MAX_RETRIES/2)
+			hdd_err("Recovery in progress; wait here!!!");
+
+		if (g_is_system_reboot_triggered) {
+			hdd_info("System Reboot happening ignore unload!!");
+			return false;
+		}
+
+		msleep(1000);
+		if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
+			hdd_err("SSR never completed, error");
+			/*
+			 * Trigger the bug_on in the internal builds, in the
+			 * customer builds self-recovery will be enabled
+			 * in those cases just return error.
+			 */
+			if (cds_is_self_recovery_enabled())
+				return false;
+			QDF_BUG(0);
+		}
+	}
+
+	hdd_info("Recovery completed successfully!");
+	return true;
+}
+
+
+static int __hdd_netdev_notifier_call(struct notifier_block *nb,
+				    unsigned long state, void *data)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
+	struct netdev_notifier_info *dev_notif_info = data;
+	struct net_device *dev = dev_notif_info->dev;
+#else
+	struct net_device *dev = data;
+#endif
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter_dev(dev);
+
+	if (!dev->ieee80211_ptr) {
+		hdd_debug("ieee80211_ptr is null");
+		return NOTIFY_DONE;
+	}
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD Context is Null");
+		return NOTIFY_DONE;
+	}
+
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
+		hdd_debug("%s: Driver module is closed", __func__);
+		return NOTIFY_DONE;
+	}
+
+	/* Make sure that this callback corresponds to our device. */
+	adapter = hdd_get_adapter_by_iface_name(hdd_ctx, dev->name);
+	if (!adapter) {
+		hdd_debug("failed to look up adapter for '%s'", dev->name);
+		return NOTIFY_DONE;
+	}
+
+	if (adapter != WLAN_HDD_GET_PRIV_PTR(dev)) {
+		hdd_err("HDD adapter mismatch!");
+		return NOTIFY_DONE;
+	}
+
+	if (cds_is_driver_recovering()) {
+		hdd_debug("Driver is recovering");
+		return NOTIFY_DONE;
+	}
+
+	if (cds_is_driver_in_bad_state()) {
+		hdd_debug("Driver is in failed recovery state");
+		return NOTIFY_DONE;
+	}
+
+	hdd_debug("%s New Net Device State = %lu", dev->name, state);
+
+	switch (state) {
+	case NETDEV_REGISTER:
+		break;
+
+	case NETDEV_UNREGISTER:
+		break;
+
+	case NETDEV_UP:
+		sme_ch_avoid_update_req(hdd_ctx->mac_handle);
+		break;
+
+	case NETDEV_DOWN:
+		break;
+
+	case NETDEV_CHANGE:
+		if (adapter->is_link_up_service_needed)
+			complete(&adapter->linkup_event_var);
+		break;
+
+	case NETDEV_GOING_DOWN:
+		if (ucfg_scan_get_vdev_status(adapter->vdev) !=
+				SCAN_NOT_IN_PROGRESS) {
+			wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
+					adapter->session_id, INVALID_SCAN_ID,
+					true);
+		}
+		cds_flush_work(&adapter->scan_block_work);
+		/* Need to clean up blocked scan request */
+		wlan_hdd_cfg80211_scan_block_cb(&adapter->scan_block_work);
+		hdd_debug("Scan is not Pending from user");
+		/*
+		 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
+		 * of return status of hdd_stop call, kernel resets the IFF_UP
+		 * flag after which driver does not send the cfg80211_scan_done.
+		 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
+		 */
+		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, dev);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+/**
+ * hdd_netdev_notifier_call() - netdev notifier callback function
+ * @nb: pointer to notifier block
+ * @state: state
+ * @ndev: ndev pointer
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+static int hdd_netdev_notifier_call(struct notifier_block *nb,
+					unsigned long state,
+					void *ndev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_netdev_notifier_call(nb, state, ndev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+struct notifier_block hdd_netdev_notifier = {
+	.notifier_call = hdd_netdev_notifier_call,
+};
+
+static int system_reboot_notifier_call(struct notifier_block *nb,
+				       unsigned long msg_type, void *_unused)
+{
+	switch (msg_type) {
+	case SYS_DOWN:
+	case SYS_HALT:
+	case SYS_POWER_OFF:
+		g_is_system_reboot_triggered = true;
+		hdd_info("reboot, reason: %ld", msg_type);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+struct notifier_block system_reboot_notifier = {
+	.notifier_call = system_reboot_notifier_call,
+};
+
+/* variable to hold the insmod parameters */
+static int con_mode;
+
+static int con_mode_ftm;
+int con_mode_monitor;
+
+/* Variable to hold connection mode including module parameter con_mode */
+static int curr_con_mode;
+
+/**
+ * hdd_map_nl_chan_width() - Map NL channel width to internal representation
+ * @ch_width: NL channel width
+ *
+ * Converts the NL channel width to the driver's internal representation
+ *
+ * Return: Converted channel width. In case of non matching NL channel width,
+ * CH_WIDTH_MAX will be returned.
+ */
+enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
+{
+	uint8_t fw_ch_bw;
+
+	fw_ch_bw = wma_get_vht_ch_width();
+	switch (ch_width) {
+	case NL80211_CHAN_WIDTH_20_NOHT:
+	case NL80211_CHAN_WIDTH_20:
+		return CH_WIDTH_20MHZ;
+	case NL80211_CHAN_WIDTH_40:
+		return CH_WIDTH_40MHZ;
+	case NL80211_CHAN_WIDTH_80:
+		return CH_WIDTH_80MHZ;
+	case NL80211_CHAN_WIDTH_80P80:
+		if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
+			return CH_WIDTH_80P80MHZ;
+		else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
+			return CH_WIDTH_160MHZ;
+		else
+			return CH_WIDTH_80MHZ;
+	case NL80211_CHAN_WIDTH_160:
+		if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
+			return CH_WIDTH_160MHZ;
+		else
+			return CH_WIDTH_80MHZ;
+	case NL80211_CHAN_WIDTH_5:
+		return CH_WIDTH_5MHZ;
+	case NL80211_CHAN_WIDTH_10:
+		return CH_WIDTH_10MHZ;
+	default:
+		hdd_err("Invalid channel width %d, setting to default",
+				ch_width);
+		return CH_WIDTH_INVALID;
+	}
+}
+
+QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,
+				    enum QDF_OPMODE *out_qdf_type)
+{
+	switch (nl_type) {
+	case NL80211_IFTYPE_ADHOC:
+		*out_qdf_type = QDF_IBSS_MODE;
+		break;
+	case NL80211_IFTYPE_AP:
+		*out_qdf_type = QDF_SAP_MODE;
+		break;
+	case NL80211_IFTYPE_MONITOR:
+		*out_qdf_type = QDF_MONITOR_MODE;
+		break;
+	case NL80211_IFTYPE_OCB:
+		*out_qdf_type = QDF_OCB_MODE;
+		break;
+	case NL80211_IFTYPE_P2P_CLIENT:
+		*out_qdf_type = QDF_P2P_CLIENT_MODE;
+		break;
+	case NL80211_IFTYPE_P2P_DEVICE:
+		*out_qdf_type = QDF_P2P_DEVICE_MODE;
+		break;
+	case NL80211_IFTYPE_P2P_GO:
+		*out_qdf_type = QDF_P2P_GO_MODE;
+		break;
+	case NL80211_IFTYPE_STATION:
+		*out_qdf_type = QDF_STA_MODE;
+		break;
+	case NL80211_IFTYPE_WDS:
+		*out_qdf_type = QDF_WDS_MODE;
+		break;
+	default:
+		hdd_err("Invalid nl80211 interface type %d", nl_type);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel,
+			      uint8_t bw_offset)
+{
+	uint8_t opclass = 0;
+
+	sme_get_opclass(mac_handle, channel, bw_offset, &opclass);
+	return opclass;
+}
+
+/**
+ * hdd_qdf_trace_enable() - configure initial QDF Trace enable
+ * @module_id:	Module whose trace level is being configured
+ * @bitmask:	Bitmask of log levels to be enabled
+ *
+ * Called immediately after the cfg.ini is read in order to configure
+ * the desired trace levels.
+ *
+ * Return: None
+ */
+int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
+{
+	QDF_TRACE_LEVEL level;
+	int qdf_print_idx = -1;
+	int status = -1;
+	/*
+	 * if the bitmask is the default value, then a bitmask was not
+	 * specified in cfg.ini, so leave the logging level alone (it
+	 * will remain at the "compiled in" default value)
+	 */
+	if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
+		return 0;
+
+	qdf_print_idx = qdf_get_pidx();
+
+	/* a mask was specified.  start by disabling all logging */
+	status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
+					QDF_TRACE_LEVEL_NONE, 0);
+
+	if (QDF_STATUS_SUCCESS != status)
+		return -EINVAL;
+	/* now cycle through the bitmask until all "set" bits are serviced */
+	level = QDF_TRACE_LEVEL_NONE;
+	while (0 != bitmask) {
+		if (bitmask & 1) {
+			status = qdf_print_set_category_verbose(qdf_print_idx,
+							module_id, level, 1);
+			if (QDF_STATUS_SUCCESS != status)
+				return -EINVAL;
+		}
+
+		level++;
+		bitmask >>= 1;
+	}
+	return 0;
+}
+
+int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func)
+{
+	if (!hdd_ctx) {
+		hdd_err("HDD context is null (via %s)", func);
+		return -ENODEV;
+	}
+
+	if (!hdd_ctx->config) {
+		hdd_err("HDD config is null (via %s)", func);
+		return -ENODEV;
+	}
+
+	if (cds_is_driver_recovering()) {
+		hdd_debug("Recovery in progress (via %s); state:0x%x",
+			  func, cds_get_driver_state());
+		return -EAGAIN;
+	}
+
+	if (cds_is_load_or_unload_in_progress()) {
+		hdd_debug("Load/unload in progress (via %s); state:0x%x",
+			  func, cds_get_driver_state());
+		return -EAGAIN;
+	}
+
+	if (hdd_ctx->start_modules_in_progress) {
+		hdd_debug("Start modules in progress (via %s)", func);
+		return -EAGAIN;
+	}
+
+	if (hdd_ctx->stop_modules_in_progress) {
+		hdd_debug("Stop modules in progress (via %s)", func);
+		return -EAGAIN;
+	}
+
+	if (cds_is_driver_in_bad_state()) {
+		hdd_debug("Driver in bad state (via %s); state:0x%x",
+			  func, cds_get_driver_state());
+		return -EAGAIN;
+	}
+
+	if (cds_is_fw_down()) {
+		hdd_debug("FW is down (via %s); state:0x%x",
+			  func, cds_get_driver_state());
+		return -EAGAIN;
+	}
+
+	if (qdf_atomic_read(&hdd_ctx->con_mode_flag)) {
+		hdd_debug("Driver mode change in progress (via %s)", func);
+		return -EAGAIN;
+	}
+
+	return 0;
+}
+
+int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func)
+{
+	if (!adapter) {
+		hdd_err("adapter is null (via %s)", func);
+		return -EINVAL;
+	}
+
+	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
+		hdd_err("bad adapter magic (via %s)", func);
+		return -EINVAL;
+	}
+
+	if (!adapter->dev) {
+		hdd_err("adapter net_device is null (via %s)", func);
+		return -EINVAL;
+	}
+
+	if (!(adapter->dev->flags & IFF_UP)) {
+		hdd_debug_rl("adapter '%s' is not up (via %s)",
+			     adapter->dev->name, func);
+		return -EAGAIN;
+	}
+
+	return __wlan_hdd_validate_session_id(adapter->session_id, func);
+}
+
+int __wlan_hdd_validate_session_id(uint8_t session_id, const char *func)
+{
+	if (session_id == CSR_SESSION_ID_INVALID) {
+		hdd_debug_rl("adapter is not up (via %s)", func);
+		return -EINVAL;
+	}
+
+	if (session_id >= CSR_ROAM_SESSION_MAX) {
+		hdd_err("bad session Id:%u (via %s)", session_id, func);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr,
+					   const char *func)
+{
+	if (!mac_addr) {
+		hdd_err("Received NULL mac address (via %s)", func);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (qdf_is_macaddr_zero(mac_addr)) {
+		hdd_err("MAC is all zero (via %s)", func);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (qdf_is_macaddr_broadcast(mac_addr)) {
+		hdd_err("MAC is Broadcast (via %s)", func);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) {
+		hdd_err("MAC is Multicast (via %s)", func);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_hdd_validate_modules_state() - Check modules status
+ * @hdd_ctx: HDD context pointer
+ *
+ * Check's the driver module's state and returns true if the
+ * modules are enabled returns false if modules are closed.
+ *
+ * Return: True if modules are enabled or false.
+ */
+bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
+{
+	mutex_lock(&hdd_ctx->iface_change_lock);
+	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+		mutex_unlock(&hdd_ctx->iface_change_lock);
+		hdd_info("Modules not enabled, Present status: %d",
+			 hdd_ctx->driver_status);
+		return false;
+	}
+	mutex_unlock(&hdd_ctx->iface_change_lock);
+	return true;
+}
+
+/**
+ * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA.
+ * @struct hdd_adapter Hdd adapter.
+ *
+ * This function sets the IBSS power save config parameters to WMA
+ * which will send it to firmware if FW supports IBSS power save
+ * before vdev start.
+ *
+ * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
+ *         on failure.
+ */
+QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	if (hdd_ctx == NULL) {
+		hdd_err("HDD context is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = sme_cli_set_command(adapter->session_id,
+				  WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE,
+				  hdd_ctx->config->ibssATIMWinSize,
+				  VDEV_CMD);
+	if (0 != ret) {
+		hdd_err("atim window set failed %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = sme_cli_set_command(adapter->session_id,
+				  WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED,
+				  hdd_ctx->config->isIbssPowerSaveAllowed,
+				  VDEV_CMD);
+	if (0 != ret) {
+		hdd_err("power save allow failed %d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = sme_cli_set_command(adapter->session_id,
+				  WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED,
+				  hdd_ctx->config->
+				  isIbssPowerCollapseAllowed, VDEV_CMD);
+	if (0 != ret) {
+		hdd_err("power collapse allow failed %d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = sme_cli_set_command(adapter->session_id,
+				  WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX,
+				  hdd_ctx->config->isIbssAwakeOnTxRx,
+				  VDEV_CMD);
+	if (0 != ret) {
+		hdd_err("set awake on tx/rx failed %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = sme_cli_set_command(adapter->session_id,
+				  WMA_VDEV_IBSS_SET_INACTIVITY_TIME,
+				  hdd_ctx->config->ibssInactivityCount,
+				  VDEV_CMD);
+	if (0 != ret) {
+		hdd_err("set inactivity time failed %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = sme_cli_set_command(adapter->session_id,
+				  WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME,
+				  hdd_ctx->config->ibssTxSpEndInactivityTime,
+				  VDEV_CMD);
+	if (0 != ret) {
+		hdd_err("set txsp end failed %d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = sme_cli_set_command(adapter->session_id,
+				  WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS,
+				  hdd_ctx->config->ibssPsWarmupTime,
+				  VDEV_CMD);
+	if (0 != ret) {
+		hdd_err("set ps warmup failed %d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = sme_cli_set_command(adapter->session_id,
+				  WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW,
+				  hdd_ctx->config->ibssPs1RxChainInAtimEnable,
+				  VDEV_CMD);
+	if (0 != ret) {
+		hdd_err("set 1rx chain atim failed %d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
+ * @hdd_ctx: HDD context
+ *
+ * Return: None
+ */
+static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
+{
+	struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
+
+	qdf_runtime_lock_init(&ctx->dfs);
+	qdf_runtime_lock_init(&ctx->connect);
+
+	wlan_scan_runtime_pm_init(hdd_ctx->pdev);
+}
+
+/**
+ * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
+ * @hdd_ctx: HDD Context
+ *
+ * Return: None
+ */
+static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
+{
+	struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
+
+	qdf_runtime_lock_deinit(&ctx->dfs);
+	qdf_runtime_lock_deinit(&ctx->connect);
+
+	wlan_scan_runtime_pm_deinit(hdd_ctx->pdev);
+}
+
+#else /* FEATURE_RUNTIME_PM */
+static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
+static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
+#endif /* FEATURE_RUNTIME_PM */
+
+#define INTF_MACADDR_MASK       0x7
+
+/**
+ * hdd_update_macaddr() - update mac address
+ * @config:	hdd configuration
+ * @hw_macaddr:	mac address
+ *
+ * Mac address for multiple virtual interface is found as following
+ * i) The mac address of the first interface is just the actual hw mac address.
+ * ii) MSM 3 or 4 bits of byte5 of the actual mac address are used to
+ *     define the mac address for the remaining interfaces and locally
+ *     admistered bit is set. INTF_MACADDR_MASK is based on the number of
+ *     supported virtual interfaces, right now this is 0x07 (meaning 8
+ *     interface).
+ *     Byte[3] of second interface will be hw_macaddr[3](bit5..7) + 1,
+ *     for third interface it will be hw_macaddr[3](bit5..7) + 2, etc.
+ *
+ * Return: None
+ */
+void hdd_update_macaddr(struct hdd_config *config,
+			struct qdf_mac_addr hw_macaddr)
+{
+	int8_t i;
+	uint8_t macaddr_b3, tmp_br3;
+
+	qdf_mem_copy(config->intfMacAddr[0].bytes, hw_macaddr.bytes,
+		     QDF_MAC_ADDR_SIZE);
+	for (i = 1; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
+		qdf_mem_copy(config->intfMacAddr[i].bytes, hw_macaddr.bytes,
+			     QDF_MAC_ADDR_SIZE);
+		macaddr_b3 = config->intfMacAddr[i].bytes[3];
+		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
+			  INTF_MACADDR_MASK;
+		macaddr_b3 += tmp_br3;
+
+		/* XOR-ing bit-24 of the mac address. This will give enough
+		 * mac address range before collision
+		 */
+		macaddr_b3 ^= (1 << 7);
+
+		/* Set locally administered bit */
+		config->intfMacAddr[i].bytes[0] |= 0x02;
+		config->intfMacAddr[i].bytes[3] = macaddr_b3;
+		hdd_debug("config->intfMacAddr[%d]: "
+		       MAC_ADDRESS_STR, i,
+		       MAC_ADDR_ARRAY(config->intfMacAddr[i].bytes));
+	}
+}
+
+static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
+{
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	struct tdls_start_params tdls_cfg;
+	struct hdd_config *cfg = hdd_ctx->config;
+	QDF_STATUS status;
+
+	cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc,
+				 CFG_TDLS_NSS(cfg->vdev_type_nss_2g));
+	cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc,
+				 CFG_TDLS_NSS(cfg->vdev_type_nss_5g));
+	tdls_cfg.tdls_send_mgmt_req = eWNI_SME_TDLS_SEND_MGMT_REQ;
+	tdls_cfg.tdls_add_sta_req = eWNI_SME_TDLS_ADD_STA_REQ;
+	tdls_cfg.tdls_del_sta_req = eWNI_SME_TDLS_DEL_STA_REQ;
+	tdls_cfg.tdls_update_peer_state = WMA_UPDATE_TDLS_PEER_STATE;
+	tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
+	tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
+	tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
+	tdls_cfg.tdls_evt_cb_data = psoc;
+	tdls_cfg.tdls_peer_context = hdd_ctx;
+	tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer;
+	tdls_cfg.tdls_dereg_peer = hdd_tdls_deregister_peer;
+	tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
+	tdls_cfg.tdls_wmm_cb_data = psoc;
+	tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
+	tdls_cfg.tdls_rx_cb_data = psoc;
+	tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
+
+	status = ucfg_tdls_update_config(psoc, &tdls_cfg);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("failed pmo psoc configuration");
+		return -EINVAL;
+	}
+
+	hdd_ctx->tdls_umac_comp_active = true;
+	/* enable napier specific tdls data path */
+	hdd_ctx->tdls_nap_active = true;
+
+	return 0;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
+				    struct wma_tgt_services *cfg)
+{
+	bool roam_offload_enable;
+
+	ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable);
+	ucfg_mlme_set_roaming_offload(hdd_ctx->psoc,
+				      roam_offload_enable &
+				      cfg->en_roam_offload);
+}
+#else
+static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
+					   struct wma_tgt_services *cfg)
+{
+}
+#endif
+
+static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
+				    struct wma_tgt_services *cfg)
+{
+	struct hdd_config *config = hdd_ctx->config;
+	bool arp_offload_enable;
+#ifdef FEATURE_WLAN_TDLS
+	bool tdls_support;
+	bool tdls_off_channel;
+	bool tdls_buffer_sta;
+	uint32_t tdls_uapsd_mask;
+	bool value;
+#endif
+	/* Set up UAPSD */
+	config->apUapsdEnabled &= cfg->uapsd;
+
+	/* 11AX mode support */
+	if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
+	     config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
+		config->dot11Mode = eHDD_DOT11_MODE_11ac;
+
+	/* 11AC mode support */
+	if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
+	     config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
+		config->dot11Mode = eHDD_DOT11_MODE_AUTO;
+
+	/* ARP offload: override user setting if invalid  */
+	arp_offload_enable =
+			ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc);
+	ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc,
+					 arp_offload_enable & cfg->arp_offload);
+#ifdef FEATURE_WLAN_SCAN_PNO
+	/* PNO offload */
+	hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
+	if (cfg->pno_offload)
+		config->PnoOffload = true;
+#endif
+#ifdef FEATURE_WLAN_TDLS
+	cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support);
+	cfg_tdls_set_support_enable(hdd_ctx->psoc,
+				    tdls_support & cfg->en_tdls);
+
+	cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel);
+	cfg_tdls_set_off_channel_enable(hdd_ctx->psoc,
+					tdls_off_channel &&
+					cfg->en_tdls_offchan);
+
+	cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta);
+	cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc,
+				       tdls_buffer_sta &&
+				       cfg->en_tdls_uapsd_buf_sta);
+
+	cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask);
+	if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta)
+		cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true);
+	else
+		cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false);
+#endif
+	hdd_update_roam_offload(hdd_ctx, cfg);
+
+	if (ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value) ==
+	   QDF_STATUS_SUCCESS)
+		value &= cfg->get_peer_info_enabled;
+
+	config->MAWCEnabled &= cfg->is_fw_mawc_capable;
+	hdd_update_tdls_config(hdd_ctx);
+	sme_update_tgt_services(hdd_ctx->mac_handle, cfg);
+}
+
+/**
+ * hdd_update_vdev_nss() - sets the vdev nss
+ * @hdd_ctx: HDD context
+ *
+ * Sets the Nss per vdev type based on INI
+ *
+ * Return: None
+ */
+static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
+{
+	struct hdd_config *cfg_ini = hdd_ctx->config;
+	uint8_t max_supp_nss = 1;
+	mac_handle_t mac_handle;
+	QDF_STATUS status;
+	bool bval;
+
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+
+	if (bval && !cds_is_sub_20_mhz_enabled())
+		max_supp_nss = 2;
+	hdd_debug("max nss %d vdev_type_nss_2g %x vdev_type_nss_5g %x",
+		  max_supp_nss, cfg_ini->vdev_type_nss_2g,
+		  cfg_ini->vdev_type_nss_5g);
+
+	mac_handle = hdd_ctx->mac_handle;
+	sme_update_vdev_type_nss(mac_handle, max_supp_nss,
+				 cfg_ini->vdev_type_nss_2g, BAND_2G);
+
+	sme_update_vdev_type_nss(mac_handle, max_supp_nss,
+				 cfg_ini->vdev_type_nss_5g, BAND_5G);
+}
+
+/**
+ * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
+ * @hdd_ctx: HDD context
+ *
+ * Updates wiphy vhtcap fields
+ *
+ * Return: None
+ */
+static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
+{
+	struct ieee80211_supported_band *band_5g =
+		hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
+	QDF_STATUS status;
+	uint8_t value = 0, value1 = 0;
+
+	if (!band_5g) {
+		hdd_debug("5GHz band disabled, skipping capability population");
+		return;
+	}
+
+	status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
+							&value);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get tx_bfee_ant_supp");
+
+	band_5g->vht_cap.cap |=
+			(value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
+
+	value1 = NUM_OF_SOUNDING_DIMENSIONS;
+	band_5g->vht_cap.cap |=
+		(value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
+
+	hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
+		  band_5g->vht_cap.cap, value, value1);
+}
+
+/**
+ * hdd_update_hw_dbs_capable() - sets the dbs capability of the device
+ * @hdd_ctx: HDD context
+ *
+ * Sets the DBS capability as per INI and firmware capability
+ *
+ * Return: None
+ */
+static void hdd_update_hw_dbs_capable(struct hdd_context *hdd_ctx)
+{
+	struct hdd_config *cfg_ini = hdd_ctx->config;
+	uint8_t hw_dbs_capable = 0;
+
+	if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) &&
+		((cfg_ini->dual_mac_feature_disable ==
+			ENABLE_DBS_CXN_AND_SCAN) ||
+		(cfg_ini->dual_mac_feature_disable ==
+			ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF) ||
+		(cfg_ini->dual_mac_feature_disable ==
+			ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN)))
+		hw_dbs_capable = 1;
+
+	sme_update_hw_dbs_capable(hdd_ctx->mac_handle, hw_dbs_capable);
+}
+
+static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
+				  struct wma_tgt_ht_cap *cfg)
+{
+	QDF_STATUS status;
+	qdf_size_t value_len;
+	uint32_t value;
+	uint8_t mpdu_density;
+	struct mlme_ht_capabilities_info ht_cap_info;
+	uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
+	bool b_enable1x1;
+
+	/* get the MPDU density */
+	status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("could not get HT MPDU Density");
+		return;
+	}
+
+	/*
+	 * MPDU density:
+	 * override user's setting if value is larger
+	 * than the one supported by target
+	 */
+	if (mpdu_density > cfg->mpdu_density) {
+		status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc,
+						       cfg->mpdu_density);
+		if (QDF_IS_STATUS_ERROR(status))
+			hdd_err("could not set HT capability to CCM");
+	}
+
+	/* get the HT capability info */
+	status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("could not get HT capability info");
+		return;
+	}
+
+	/* check and update RX STBC */
+	if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc)
+		ht_cap_info.rx_stbc = cfg->ht_rx_stbc;
+
+	/* Set the LDPC capability */
+	ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc;
+
+	if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20)
+		ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20;
+
+	if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40)
+		ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40;
+
+	hdd_ctx->num_rf_chains = cfg->num_rf_chains;
+	hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
+
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+
+	b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2);
+
+	status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to set vht_enable2x2");
+
+	if (!b_enable1x1) {
+		ht_cap_info.tx_stbc = 0;
+
+		/* 1x1 */
+		/* Update Rx Highest Long GI data Rate */
+		status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(
+				hdd_ctx->psoc,
+				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("Failed to set rx_supp_data_rate");
+		/* Update Tx Highest Long GI data Rate */
+		status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(
+				hdd_ctx->psoc,
+				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("Failed to set tx_supp_data_rate");
+	}
+	if (!(cfg->ht_tx_stbc && b_enable1x1))
+		ht_cap_info.tx_stbc = 0;
+
+	status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_err("could not set HT capability to CCM");
+#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
+	value_len = SIZE_OF_SUPPORTED_MCS_SET;
+	if (ucfg_mlme_get_supported_mcs_set(
+				hdd_ctx->psoc, mcs_set,
+				&value_len) == QDF_STATUS_SUCCESS) {
+		hdd_debug("Read MCS rate set");
+		if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET)
+			cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET;
+
+		if (b_enable1x1) {
+			for (value = 0; value < cfg->num_rf_chains; value++)
+				mcs_set[value] =
+					WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
+
+			status = ucfg_mlme_set_supported_mcs_set(
+					hdd_ctx->psoc,
+					mcs_set,
+					(qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET);
+			if (QDF_IS_STATUS_ERROR(status))
+				hdd_err("could not set MCS SET to CCM");
+		}
+	}
+#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
+}
+
+static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
+				   struct wma_tgt_vht_cap *cfg)
+{
+	QDF_STATUS status;
+	struct wiphy *wiphy = hdd_ctx->wiphy;
+	struct ieee80211_supported_band *band_5g =
+		wiphy->bands[HDD_NL80211_BAND_5GHZ];
+	uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ;
+	struct wma_caps_per_phy caps_per_phy;
+	uint8_t val = 0;
+
+	if (!band_5g) {
+		hdd_debug("5GHz band disabled, skipping capability population");
+		return;
+	}
+
+	status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("could not update vht capabilities");
+
+	if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
+	else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
+	else
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
+
+
+	if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
+		status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc,
+						    VHT_CAP_160_AND_80P80_SUPP);
+		if (QDF_IS_STATUS_ERROR(status))
+			hdd_err("could not set the VHT CAP 160");
+		band_5g->vht_cap.cap |=
+			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
+		ch_width = eHT_CHANNEL_WIDTH_80P80MHZ;
+	} else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
+		status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc,
+						    VHT_CAP_160_SUPP);
+		if (QDF_IS_STATUS_ERROR(status))
+			hdd_err("could not set the VHT CAP 160");
+		band_5g->vht_cap.cap |=
+			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
+		ch_width = eHT_CHANNEL_WIDTH_160MHZ;
+	}
+
+	status =
+		ucfg_mlme_cfg_get_vht_chan_width(hdd_ctx->psoc, &val);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("could not get channel_width");
+
+	val = QDF_MIN(val, ch_width);
+	status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, val);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("could not set the channel width");
+
+	if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) {
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
+		hdd_debug("VHT RxLDPC capability is set");
+	} else {
+		/*
+		 * Get the RX LDPC capability for the NON DBS
+		 * hardware mode for 5G band
+		 */
+		status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
+					HW_MODE_DBS_NONE, CDS_BAND_5GHZ);
+		if ((QDF_IS_STATUS_SUCCESS(status)) &&
+			(caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) {
+			band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
+			hdd_debug("VHT RX LDPC capability is set");
+		}
+	}
+
+	if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
+	if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
+
+	if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
+
+	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
+	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
+	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
+
+	band_5g->vht_cap.cap |=
+		(cfg->vht_max_ampdu_len_exp <<
+		 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
+
+	if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
+	if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
+	if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
+	if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
+
+	if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
+		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
+
+}
+
+/**
+ * hdd_generate_macaddr_auto() - Auto-generate mac address
+ * @hdd_ctx: Pointer to the HDD context
+ *
+ * Auto-generate mac address using device serial number.
+ * Keep the first 3 bytes of OUI as before and replace
+ * the last 3 bytes with the lower 3 bytes of serial number.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
+{
+	unsigned int serialno = 0;
+	struct qdf_mac_addr mac_addr = {
+		{0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
+	};
+
+	serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
+	if (serialno == 0)
+		return -EINVAL;
+
+	serialno &= 0x00ffffff;
+
+	mac_addr.bytes[3] = (serialno >> 16) & 0xff;
+	mac_addr.bytes[4] = (serialno >> 8) & 0xff;
+	mac_addr.bytes[5] = serialno & 0xff;
+
+	hdd_update_macaddr(hdd_ctx->config, mac_addr);
+	return 0;
+}
+
+/**
+ * hdd_update_ra_rate_limit() - Update RA rate limit from target
+ *  configuration to cfg_ini in HDD
+ * @hdd_ctx: Pointer to hdd_ctx
+ * @cfg: target configuration
+ *
+ * Return: None
+ */
+#ifdef FEATURE_WLAN_RA_FILTERING
+static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
+				     struct wma_tgt_cfg *cfg)
+{
+	ucfg_fwol_set_is_rate_limit_enabled(hdd_ctx->psoc,
+					    cfg->is_ra_rate_limit_enabled);
+}
+#else
+static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
+				     struct wma_tgt_cfg *cfg)
+{
+}
+#endif
+
+static void hdd_sar_target_config(struct hdd_context *hdd_ctx,
+				  struct wma_tgt_cfg *cfg)
+{
+	hdd_ctx->sar_version = cfg->sar_version;
+}
+
+void hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	uint8_t temp_band_cap, band_capability;
+	struct cds_config_info *cds_cfg = cds_get_ini_config();
+	uint8_t antenna_mode;
+	uint8_t sub_20_chan_width;
+	QDF_STATUS status;
+	mac_handle_t mac_handle;
+	bool bval = false;
+	uint8_t value = 0;
+
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return;
+	}
+	ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
+	if (ret) {
+		QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret);
+		return;
+	}
+
+	hdd_debug("New pdev has been created with pdev_id = %u",
+		  hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id);
+
+	status = dispatcher_pdev_open(hdd_ctx->pdev);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d",
+				status);
+		return;
+	}
+
+	status = hdd_component_pdev_open(hdd_ctx->pdev);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d",
+				status);
+		return;
+	}
+	cdp_pdev_set_ctrl_pdev(cds_get_context(QDF_MODULE_ID_SOC),
+			cds_get_context(QDF_MODULE_ID_TXRX),
+			(struct cdp_ctrl_objmgr_pdev *)hdd_ctx->pdev);
+
+	wlan_pdev_set_dp_handle(hdd_ctx->pdev,
+				cds_get_context(QDF_MODULE_ID_TXRX));
+
+	hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count);
+
+	ucfg_ipa_set_dp_handle(hdd_ctx->psoc,
+			       cds_get_context(QDF_MODULE_ID_SOC));
+	ucfg_ipa_set_txrx_handle(hdd_ctx->psoc,
+				 cds_get_context(QDF_MODULE_ID_TXRX));
+	ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev,
+				 hdd_softap_hard_start_xmit);
+	ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev,
+				   hdd_ipa_send_skb_to_network);
+
+	status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
+						 &sub_20_chan_width);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get sub_20_chan_width config");
+		return;
+	}
+
+	if (cds_cfg) {
+		if (sub_20_chan_width !=
+		    WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
+			hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
+			cds_cfg->sub_20_channel_width =
+				WLAN_SUB_20_CH_WIDTH_NONE;
+		} else {
+			cds_cfg->sub_20_channel_width = sub_20_chan_width;
+		}
+	}
+
+	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get MLME band capability");
+		return;
+	}
+
+	/* first store the INI band capability */
+	temp_band_cap = band_capability;
+
+	band_capability = cfg->band_cap;
+	hdd_ctx->is_fils_roaming_supported =
+			cfg->services.is_fils_roaming_supported;
+
+	hdd_ctx->config->is_11k_offload_supported =
+			cfg->services.is_11k_offload_supported;
+
+	/*
+	 * now overwrite the target band capability with INI
+	 * setting if INI setting is a subset
+	 */
+	if ((band_capability == BAND_ALL) &&
+	    (temp_band_cap != BAND_ALL))
+		band_capability = temp_band_cap;
+	else if ((band_capability != BAND_ALL) &&
+		 (temp_band_cap != BAND_ALL) &&
+		 (band_capability != temp_band_cap)) {
+		hdd_warn("ini BandCapability not supported by the target");
+	}
+
+	status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to set MLME Band Capability");
+		return;
+	}
+
+	hdd_ctx->curr_band = band_capability;
+
+	if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		hdd_ctx->reg.reg_domain = cfg->reg_domain;
+		hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
+	}
+
+	/* This can be extended to other configurations like ht, vht cap... */
+
+	if (!qdf_is_macaddr_zero(&cfg->hw_macaddr)) {
+		hdd_update_macaddr(hdd_ctx->config, cfg->hw_macaddr);
+		hdd_ctx->update_mac_addr_to_fw = false;
+	} else {
+		static struct qdf_mac_addr default_mac_addr = {
+			{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}
+		};
+		if (qdf_is_macaddr_equal(&hdd_ctx->config->intfMacAddr[0],
+					 &default_mac_addr)) {
+			if (hdd_generate_macaddr_auto(hdd_ctx) != 0)
+				hdd_err("Fail to auto-generate MAC, using MAC from ini file "
+					MAC_ADDRESS_STR,
+					MAC_ADDR_ARRAY(hdd_ctx->config->
+						       intfMacAddr[0].bytes));
+		} else {
+			hdd_err("Invalid MAC passed from target, using MAC from ini file "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(hdd_ctx->config->
+					       intfMacAddr[0].bytes));
+		}
+		hdd_ctx->update_mac_addr_to_fw = true;
+	}
+
+	hdd_ctx->target_fw_version = cfg->target_fw_version;
+	hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
+
+	hdd_ctx->hw_bd_id = cfg->hw_bd_id;
+	qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info,
+		     sizeof(cfg->hw_bd_info));
+
+	if (cfg->max_intf_count > CSR_ROAM_SESSION_MAX) {
+		hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u",
+			cfg->max_intf_count, CSR_ROAM_SESSION_MAX,
+			CSR_ROAM_SESSION_MAX);
+		hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
+	} else {
+		hdd_ctx->max_intf_count = cfg->max_intf_count;
+	}
+
+	hdd_sar_target_config(hdd_ctx, cfg);
+	hdd_lpass_target_config(hdd_ctx, cfg);
+
+	hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
+	hdd_update_tgt_services(hdd_ctx, &cfg->services);
+
+	hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
+
+	hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
+	if (cfg->services.en_11ax) {
+		hdd_info("11AX: 11ax is enabled - update HDD config");
+		hdd_update_tgt_he_cap(hdd_ctx, cfg);
+	}
+	hdd_update_tgt_twt_cap(hdd_ctx, cfg);
+
+	hdd_update_vdev_nss(hdd_ctx);
+
+	hdd_update_hw_dbs_capable(hdd_ctx);
+
+	hdd_ctx->config->fine_time_meas_cap &= cfg->fine_time_measurement_cap;
+	hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
+	hdd_debug("fine_time_meas_cap: 0x%x",
+		  hdd_ctx->config->fine_time_meas_cap);
+
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+
+	antenna_mode = (bval == 0x01) ?
+			HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
+	hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
+	hdd_debug("Init current antenna mode: %d",
+		  hdd_ctx->current_antenna_mode);
+
+	hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
+	hdd_update_ra_rate_limit(hdd_ctx, cfg);
+
+	status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
+							&value);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		status = false;
+		hdd_err("set tx_bfee_ant_supp failed");
+	}
+
+	if ((value >
+	     WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
+	    !cfg->tx_bfee_8ss_enabled) {
+		status =
+		  ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
+			WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			status = false;
+			hdd_err("set tx_bfee_ant_supp failed");
+		}
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	hdd_debug("txBFCsnValue %d", value);
+
+	/*
+	 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
+	 */
+	hdd_update_wiphy_vhtcap(hdd_ctx);
+
+	hdd_ctx->wmi_max_len = cfg->wmi_max_len;
+
+	/*
+	 * This needs to be done after HDD pdev is created and stored since
+	 * it will access the HDD pdev object lock.
+	 */
+	hdd_runtime_suspend_context_init(hdd_ctx);
+
+	/* Configure NAN datapath features */
+	hdd_nan_datapath_target_config(hdd_ctx, cfg);
+	hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
+	hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
+	hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload;
+	status = sme_cfg_set_int(mac_handle, WNI_CFG_OBSS_DETECTION_OFFLOAD,
+				 cfg->obss_detection_offloaded);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG");
+
+	status = sme_cfg_set_int(mac_handle,
+				 WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD,
+				 cfg->obss_color_collision_offloaded);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD");
+}
+
+bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_ap_ctx *ap_ctx;
+
+	if (!hdd_ctx) {
+		hdd_info("Couldn't get hdd_ctx");
+		return true;
+	}
+
+	if (hdd_ctx->config->disableDFSChSwitch) {
+		hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
+			 hdd_ctx, hdd_ctx->config->disableDFSChSwitch);
+		return true;
+	}
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+
+		if ((QDF_SAP_MODE == adapter->device_mode ||
+		    QDF_P2P_GO_MODE == adapter->device_mode) &&
+		    (wlan_reg_is_passive_or_disable_ch(hdd_ctx->pdev,
+		     ap_ctx->operating_channel))) {
+			WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx =
+				true;
+			hdd_info("tx blocked for session: %d",
+				adapter->session_id);
+			if (adapter->txrx_vdev)
+				cdp_fc_vdev_flush(
+					cds_get_context(QDF_MODULE_ID_SOC),
+					adapter->txrx_vdev);
+		}
+	}
+
+	return true;
+}
+
+/**
+ * hdd_is_valid_mac_address() - validate MAC address
+ * @pMacAddr:	Pointer to the input MAC address
+ *
+ * This function validates whether the given MAC address is valid or not
+ * Expected MAC address is of the format XX:XX:XX:XX:XX:XX
+ * where X is the hexa decimal digit character and separated by ':'
+ * This algorithm works even if MAC address is not separated by ':'
+ *
+ * This code checks given input string mac contains exactly 12 hexadecimal
+ * digits and a separator colon : appears in the input string only after
+ * an even number of hex digits.
+ *
+ * Return: 1 for valid and 0 for invalid
+ */
+bool hdd_is_valid_mac_address(const uint8_t *pMacAddr)
+{
+	int xdigit = 0;
+	int separator = 0;
+
+	while (*pMacAddr) {
+		if (isxdigit(*pMacAddr)) {
+			xdigit++;
+		} else if (':' == *pMacAddr) {
+			if (0 == xdigit || ((xdigit / 2) - 1) != separator)
+				break;
+
+			++separator;
+		} else {
+			/* Invalid MAC found */
+			return 0;
+		}
+		++pMacAddr;
+	}
+	return xdigit == 12 && (separator == 5 || separator == 0);
+}
+
+/**
+ * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
+ * @dev: Handle to struct net_device to be updated.
+ *
+ * Return: None
+ */
+static void hdd_mon_mode_ether_setup(struct net_device *dev)
+{
+	dev->header_ops         = NULL;
+	dev->type               = ARPHRD_IEEE80211_RADIOTAP;
+	dev->hard_header_len    = ETH_HLEN;
+	dev->mtu                = ETH_DATA_LEN;
+	dev->addr_len           = ETH_ALEN;
+	dev->tx_queue_len       = 1000; /* Ethernet wants good queues */
+	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
+	dev->priv_flags        |= IFF_TX_SKB_SHARING;
+
+	memset(dev->broadcast, 0xFF, ETH_ALEN);
+}
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+/**
+ * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device.
+ * @hdd_ctx: Pointer to HDD context.
+ *
+ * Return: None
+ */
+static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx)
+{
+	ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, PS_NOT_SUPPORTED);
+	ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH);
+}
+
+/**
+ * __hdd__mon_open() - HDD Open function
+ * @dev: Pointer to net_device structure
+ *
+ * This is called in response to ifconfig up
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+static int __hdd_mon_open(struct net_device *dev)
+{
+	int ret;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	hdd_mon_mode_ether_setup(dev);
+
+	if (con_mode == QDF_GLOBAL_MONITOR_MODE) {
+		ret = hdd_wlan_start_modules(hdd_ctx, false);
+		if (ret) {
+			hdd_err("Failed to start WLAN modules return");
+			return ret;
+		}
+		hdd_err("hdd_wlan_start_modules() successful !");
+
+		if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
+			ret = hdd_start_adapter(adapter);
+			if (ret) {
+				hdd_err("Failed to start adapter :%d",
+						adapter->device_mode);
+				return ret;
+			}
+			hdd_err("hdd_start_adapters() successful !");
+		}
+		hdd_mon_turn_off_ps_and_wow(hdd_ctx);
+		set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
+	}
+
+	ret = hdd_set_mon_rx_cb(dev);
+
+	if (!ret)
+		ret = hdd_enable_monitor_mode(dev);
+
+	return ret;
+}
+
+/**
+ * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
+ * @dev:	Pointer to net_device structure
+ *
+ * This is called in response to ifconfig up
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+static int hdd_mon_open(struct net_device *dev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_mon_open(dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
+static QDF_STATUS
+wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
+{
+	struct policy_mgr_dual_mac_config cfg = {0};
+	QDF_STATUS status;
+	uint32_t channel_select_logic_conc = 0;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+
+	if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc))
+		return QDF_STATUS_SUCCESS;
+
+	cfg.scan_config = 0;
+	cfg.fw_mode_config = 0;
+	cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
+	ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc,
+					     &channel_select_logic_conc);
+
+	if (hdd_ctx->config->dual_mac_feature_disable !=
+	    DISABLE_DBS_CXN_AND_SCAN) {
+		status = policy_mgr_get_updated_scan_and_fw_mode_config(
+				hdd_ctx->psoc, &cfg.scan_config,
+				&cfg.fw_mode_config,
+				hdd_ctx->config->dual_mac_feature_disable,
+				channel_select_logic_conc);
+
+		if (status != QDF_STATUS_SUCCESS) {
+			hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
+				status);
+			return status;
+		}
+	}
+
+	hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
+		cfg.scan_config, cfg.fw_mode_config);
+
+	status = sme_soc_set_dual_mac_config(cfg);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("sme_soc_set_dual_mac_config failed %d", status);
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_start_adapter() - Wrapper function for device specific adapter
+ * @adapter: pointer to HDD adapter
+ *
+ * This function is called to start the device specific adapter for
+ * the mode passed in the adapter's device_mode.
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+int hdd_start_adapter(struct hdd_adapter *adapter)
+{
+
+	int ret;
+	enum QDF_OPMODE device_mode = adapter->device_mode;
+
+	hdd_enter_dev(adapter->dev);
+	hdd_debug("Start_adapter for mode : %d", adapter->device_mode);
+
+	switch (device_mode) {
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_P2P_DEVICE_MODE:
+	case QDF_OCB_MODE:
+	case QDF_STA_MODE:
+	case QDF_MONITOR_MODE:
+		ret = hdd_start_station_adapter(adapter);
+		if (ret)
+			goto err_start_adapter;
+
+		hdd_nud_ignore_tracking(adapter, false);
+		break;
+	case QDF_P2P_GO_MODE:
+	case QDF_SAP_MODE:
+		ret = hdd_start_ap_adapter(adapter);
+		if (ret)
+			goto err_start_adapter;
+		break;
+	case QDF_IBSS_MODE:
+		/*
+		 * For IBSS interface is initialized as part of
+		 * hdd_init_station_mode()
+		 */
+		goto exit_with_success;
+	case QDF_FTM_MODE:
+		/* vdevs are dynamically managed by firmware in FTM */
+		goto exit_with_success;
+	default:
+		hdd_err("Invalid session type %d", device_mode);
+		QDF_ASSERT(0);
+		goto err_start_adapter;
+	}
+
+	if (hdd_set_fw_params(adapter))
+		hdd_err("Failed to set the FW params for the adapter!");
+
+	if (adapter->session_id != HDD_SESSION_ID_INVALID) {
+		ret = wlan_hdd_cfg80211_register_frames(adapter);
+		if (ret < 0) {
+			hdd_err("Failed to register frames - ret %d", ret);
+			goto err_start_adapter;
+		}
+	}
+
+	wlan_hdd_update_dbs_scan_and_fw_mode_config();
+
+exit_with_success:
+	hdd_exit();
+
+	return 0;
+
+err_start_adapter:
+	return -EINVAL;
+}
+
+/**
+ * hdd_enable_power_management() - API to Enable Power Management
+ *
+ * API invokes Bus Interface Layer power management functionality
+ *
+ * Return: None
+ */
+static void hdd_enable_power_management(void)
+{
+	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+
+	if (!hif_ctx) {
+		hdd_err("Bus Interface Context is Invalid");
+		return;
+	}
+
+	hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
+}
+
+/**
+ * hdd_disable_power_management() - API to disable Power Management
+ *
+ * API disable Bus Interface Layer Power management functionality
+ *
+ * Return: None
+ */
+static void hdd_disable_power_management(void)
+{
+	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+
+	if (!hif_ctx) {
+		hdd_err("Bus Interface Context is Invalid");
+		return;
+	}
+
+	hif_disable_power_management(hif_ctx);
+}
+
+void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
+{
+	void *hif_sc;
+	size_t target_hw_name_len;
+	const char *target_hw_name;
+	uint8_t *buf;
+	uint32_t buf_len;
+
+	hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!hif_sc) {
+		hdd_err("HIF context is NULL");
+		return;
+	}
+
+	hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
+			&hdd_ctx->target_hw_revision,
+			&target_hw_name);
+
+	if (hdd_ctx->target_hw_name)
+		qdf_mem_free(hdd_ctx->target_hw_name);
+
+	target_hw_name_len = strlen(target_hw_name) + 1;
+	hdd_ctx->target_hw_name = qdf_mem_malloc(target_hw_name_len);
+	if (hdd_ctx->target_hw_name)
+		qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
+			     target_hw_name_len);
+
+	buf = qdf_mem_malloc(WE_MAX_STR_LEN);
+	if (buf) {
+		buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf);
+		hdd_info("%s", buf);
+		qdf_mem_free(buf);
+	}
+}
+
+/**
+ * hdd_update_cds_ac_specs_params() - update cds ac_specs params
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Return: none
+ */
+static void
+hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
+{
+	uint8_t num_entries = 0;
+	uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM];
+	uint8_t *tx_sched_wrr_ac;
+	int i;
+	struct cds_context *cds_ctx;
+
+	if (NULL == hdd_ctx)
+		return;
+
+	if (NULL == hdd_ctx->config) {
+		/* Do nothing if hdd_ctx is invalid */
+		hdd_err("%s: Warning: hdd_ctx->cfg_ini is NULL", __func__);
+		return;
+	}
+
+	cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+
+	if (!cds_ctx) {
+		hdd_err("Invalid CDS Context");
+		return;
+	}
+
+	for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
+		switch (i) {
+		case OL_TX_WMM_AC_BE:
+			tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_be;
+			break;
+		case OL_TX_WMM_AC_BK:
+			tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_bk;
+			break;
+		case OL_TX_WMM_AC_VI:
+			tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_vi;
+			break;
+		case OL_TX_WMM_AC_VO:
+			tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_vo;
+			break;
+		default:
+			tx_sched_wrr_ac = NULL;
+			break;
+		}
+
+		hdd_string_to_u8_array(tx_sched_wrr_ac,
+				tx_sched_wrr_param,
+				&num_entries,
+				sizeof(tx_sched_wrr_param));
+
+		if (num_entries == TX_SCHED_WRR_PARAMS_NUM) {
+			cds_ctx->ac_specs[i].wrr_skip_weight =
+						tx_sched_wrr_param[0];
+			cds_ctx->ac_specs[i].credit_threshold =
+						tx_sched_wrr_param[1];
+			cds_ctx->ac_specs[i].send_limit =
+						tx_sched_wrr_param[2];
+			cds_ctx->ac_specs[i].credit_reserve =
+						tx_sched_wrr_param[3];
+			cds_ctx->ac_specs[i].discard_weight =
+						tx_sched_wrr_param[4];
+		}
+
+		num_entries = 0;
+	}
+}
+
+uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx,
+			      const size_t version_len, uint8_t *version)
+{
+	uint32_t size;
+	uint32_t msp_id = 0, mspid = 0, siid = 0, crmid = 0, sub_id = 0;
+
+	if (!hdd_ctx) {
+		hdd_err("Invalid context, HDD context is null");
+		return 0;
+	}
+
+	if (!version || version_len == 0) {
+		hdd_err("Invalid buffer pointr or buffer len\n");
+		return 0;
+	}
+
+	msp_id = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
+	mspid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
+	siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
+	crmid = hdd_ctx->target_fw_version & 0x7fff;
+	sub_id = (hdd_ctx->target_fw_vers_ext & 0xf0000000) >> 28;
+
+	size = scnprintf(version, version_len,
+			 "Host SW:%s, FW:%d.%d.%d.%d.%d, HW:%s, Board ver: %x Ref design id: %x, Customer id: %x, Project id: %x, Board Data Rev: %x",
+			 QWLAN_VERSIONSTR,
+			 msp_id, mspid, siid, crmid, sub_id,
+			 hdd_ctx->target_hw_name,
+			 hdd_ctx->hw_bd_info.bdf_version,
+			 hdd_ctx->hw_bd_info.ref_design_id,
+			 hdd_ctx->hw_bd_info.customer_id,
+			 hdd_ctx->hw_bd_info.project_id,
+			 hdd_ctx->hw_bd_info.board_data_rev);
+
+	return size;
+}
+
+int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value,
+		      struct sap_config *sap_config)
+{
+	uint8_t preamble = 0, nss = 0, rix = 0;
+	int ret;
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+
+	if (!sap_config) {
+		if (!sme_is_feature_supported_by_fw(DOT11AX)) {
+			hdd_err("Target does not support 11ax");
+			return -EIO;
+		}
+	} else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax &&
+		   sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) {
+		hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch = %d",
+			sap_config->SapHw_mode, sap_config->channel);
+		return -EIO;
+	}
+
+	if (set_value != 0xff) {
+		rix = RC_2_RATE_IDX_11AX(set_value);
+		preamble = WMI_RATE_PREAMBLE_HE;
+		nss = HT_RC_2_STREAMS_11AX(set_value);
+
+		set_value = hdd_assemble_rate_code(preamble, nss, rix);
+	} else {
+		ret = sme_set_auto_rate_he_ltf(mac_handle, adapter->session_id,
+					       QCA_WLAN_HE_LTF_AUTO);
+	}
+
+	hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d",
+		 set_value, rix, preamble, nss);
+
+	ret = wma_cli_set_command(adapter->session_id,
+				  WMI_VDEV_PARAM_FIXED_RATE,
+				  set_value, VDEV_CMD);
+
+	return ret;
+}
+
+int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
+{
+	int set_value;
+
+	if (sme_is_feature_supported_by_fw(DOT11AX))
+		set_value = WMI_ASSEMBLE_RATECODE_V1(rate, nss, preamble);
+	else
+		set_value = (preamble << 6) | (nss << 4) | rate;
+
+	return set_value;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+/**
+ * hdd_wapi_security_sta_exist() - return wapi security sta exist or not
+ *
+ * This API returns the wapi security station exist or not
+ *
+ * Return: true - wapi security station exist
+ */
+static bool hdd_wapi_security_sta_exist(void)
+{
+	struct hdd_adapter *adapter = NULL;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if ((adapter->device_mode == QDF_STA_MODE) &&
+		    adapter->wapi_info.wapi_mode &&
+		    (adapter->wapi_info.wapi_auth_mode != WAPI_AUTH_MODE_OPEN))
+			return true;
+	}
+	return false;
+}
+#else
+static bool hdd_wapi_security_sta_exist(void)
+{
+	return false;
+}
+#endif
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
+			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct hdd_adapter *adapter = NULL;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (!adapter) {
+		hdd_err("Adapter is NULL");
+		return PM_MAX_NUM_OF_MODE;
+	}
+
+	return	policy_mgr_convert_device_mode_to_qdf_type(
+			adapter->device_mode);
+}
+
+static void hdd_register_policy_manager_callback(
+			struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_hdd_cbacks hdd_cbacks;
+
+	qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks));
+	hdd_cbacks.sap_restart_chan_switch_cb =
+		hdd_sap_restart_chan_switch_cb;
+	hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
+		wlan_hdd_get_channel_for_sap_restart;
+	hdd_cbacks.get_mode_for_non_connected_vdev =
+		wlan_hdd_get_mode_for_non_connected_vdev;
+	hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
+	hdd_cbacks.hdd_wapi_security_sta_exist =
+		hdd_wapi_security_sta_exist;
+	if (QDF_STATUS_SUCCESS !=
+	    policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
+		hdd_err("HDD callback registration with policy manager failed");
+	}
+}
+#else
+static void hdd_register_policy_manager_callback(
+			struct wlan_objmgr_psoc *psoc)
+{
+}
+#endif
+
+static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
+{
+	struct nan_callbacks cb_obj = {0};
+
+	cb_obj.ndi_open = hdd_ndi_open;
+	cb_obj.ndi_close = hdd_ndi_close;
+	cb_obj.ndi_start = hdd_ndi_start;
+	cb_obj.ndi_delete = hdd_ndi_delete;
+	cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
+	cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
+
+	cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
+	cb_obj.get_peer_idx = hdd_ndp_get_peer_idx;
+	cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
+
+	os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
+}
+
+#ifdef CONFIG_LEAK_DETECTION
+/**
+ * hdd_check_for_leaks() - Perform runtime memory leak checks
+ * @hdd_ctx: the global HDD context
+ * @is_ssr: true if SSR is in progress
+ *
+ * This API triggers runtime memory leak detection. This feature enforces the
+ * policy that any memory allocated at runtime must also be released at runtime.
+ *
+ * Allocating memory at runtime and releasing it at unload is effectively a
+ * memory leak for configurations which never unload (e.g. LONU, statically
+ * compiled driver). Such memory leaks are NOT false positives, and must be
+ * fixed.
+ *
+ * Return: None
+ */
+static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
+{
+	/* DO NOT REMOVE these checks; for false positives, read above first */
+
+	wlan_objmgr_psoc_check_for_peer_leaks(hdd_ctx->psoc);
+	wlan_objmgr_psoc_check_for_vdev_leaks(hdd_ctx->psoc);
+	wlan_objmgr_psoc_check_for_pdev_leaks(hdd_ctx->psoc);
+
+	/* many adapter resources are not freed by design during SSR */
+	if (is_ssr)
+		return;
+
+	qdf_mc_timer_check_for_leaks();
+	qdf_nbuf_map_check_for_leaks();
+	qdf_mem_check_for_leaks();
+}
+
+#define hdd_debug_domain_set(domain) qdf_debug_domain_set(domain)
+#else
+static inline void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
+{ }
+
+#define hdd_debug_domain_set(domain)
+#endif /* CONFIG_LEAK_DETECTION */
+
+/**
+ * hdd_update_country_code - Update country code
+ * @hdd_ctx: HDD context
+ *
+ * Update country code based on module parameter country_code
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int hdd_update_country_code(struct hdd_context *hdd_ctx)
+{
+	if (!country_code)
+		return 0;
+
+	return hdd_reg_set_country(hdd_ctx, country_code);
+}
+
+/**
+ * hdd_wlan_start_modules() - Single driver state machine for starting modules
+ * @hdd_ctx: HDD context
+ * @reinit: flag to indicate from SSR or normal path
+ *
+ * This function maintains the driver state machine it will be invoked from
+ * startup, reinit and change interface. Depending on the driver state shall
+ * perform the opening of the modules.
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
+{
+	int ret = 0;
+	qdf_device_t qdf_dev;
+	QDF_STATUS status;
+	bool unint = false;
+	void *hif_ctx;
+	struct target_psoc_info *tgt_hdl;
+
+	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	if (!qdf_dev) {
+		hdd_err("QDF Device Context is Invalid return");
+		return -EINVAL;
+	}
+
+	hdd_psoc_idle_timer_stop(hdd_ctx);
+
+	mutex_lock(&hdd_ctx->iface_change_lock);
+	if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
+		mutex_unlock(&hdd_ctx->iface_change_lock);
+		hdd_debug("Driver modules already Enabled");
+		hdd_exit();
+		return 0;
+	}
+
+	hdd_ctx->start_modules_in_progress = true;
+
+	switch (hdd_ctx->driver_status) {
+	case DRIVER_MODULES_UNINITIALIZED:
+		hdd_info("Wlan transitioning (UNINITIALIZED -> CLOSED)");
+		unint = true;
+		/* Fall through dont add break here */
+	case DRIVER_MODULES_CLOSED:
+		hdd_info("Wlan transitioning (CLOSED -> ENABLED)");
+
+		hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
+
+		if (!reinit && !unint) {
+			ret = pld_power_on(qdf_dev->dev);
+			if (ret) {
+				hdd_err("Failed to power up device; errno:%d",
+					ret);
+				goto release_lock;
+			}
+		}
+
+		pld_set_fw_log_mode(hdd_ctx->parent_dev,
+				    hdd_ctx->config->enable_fw_log);
+		ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
+				   qdf_dev->bus_type,
+				   (reinit == true) ?  HIF_ENABLE_TYPE_REINIT :
+				   HIF_ENABLE_TYPE_PROBE);
+		if (ret) {
+			hdd_err("Failed to open hif; errno: %d", ret);
+			goto power_down;
+		}
+
+		hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+		if (!hif_ctx) {
+			hdd_err("hif context is null!!");
+			ret = -EINVAL;
+			goto power_down;
+		}
+
+		status = ol_cds_init(qdf_dev, hif_ctx);
+		if (status != QDF_STATUS_SUCCESS) {
+			hdd_err("No Memory to Create BMI Context; status: %d",
+				status);
+			ret = qdf_status_to_os_return(status);
+			goto hif_close;
+		}
+
+		ucfg_ipa_component_config_update(hdd_ctx->psoc);
+
+		hdd_update_cds_ac_specs_params(hdd_ctx);
+
+		status = hdd_component_psoc_open(hdd_ctx->psoc);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Failed to Open legacy components; status: %d",
+				status);
+			ret = qdf_status_to_os_return(status);
+			goto cds_free;
+		}
+
+		ret = hdd_update_config(hdd_ctx);
+		if (ret) {
+			hdd_err("Failed to update configuration; errno: %d",
+				ret);
+			goto cds_free;
+		}
+
+		status = wbuff_module_init();
+		if (QDF_IS_STATUS_ERROR(status))
+			hdd_err("WBUFF init unsuccessful; status: %d", status);
+
+		status = cds_open(hdd_ctx->psoc);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Failed to Open CDS; status: %d", status);
+			ret = qdf_status_to_os_return(status);
+			goto psoc_close;
+		}
+
+		hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
+
+		if (hdd_ctx->config->rx_thread_affinity_mask)
+			cds_set_rx_thread_cpu_mask(
+				hdd_ctx->config->rx_thread_affinity_mask);
+
+		/* initialize components configurations after psoc open */
+		ret = hdd_update_components_config(hdd_ctx);
+		if (ret) {
+			hdd_err("Failed to update component configs; errno: %d",
+				ret);
+			goto close;
+		}
+
+		status = cds_dp_open(hdd_ctx->psoc);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Failed to Open cds post open; status: %d",
+				status);
+			ret = qdf_status_to_os_return(status);
+			goto close;
+		}
+
+		ret = hdd_register_cb(hdd_ctx);
+		if (ret) {
+			hdd_err("Failed to register HDD callbacks!");
+			goto cds_txrx_free;
+		}
+
+		/*
+		 * NAN compoenet requires certian operations like, open adapter,
+		 * close adapter, etc. to be initiated by HDD, for those
+		 * register HDD callbacks with UMAC's NAN componenet.
+		 */
+		hdd_nan_register_callbacks(hdd_ctx);
+
+		status = cds_pre_enable();
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Failed to pre-enable CDS; status: %d", status);
+			ret = qdf_status_to_os_return(status);
+			goto deregister_cb;
+		}
+
+		hdd_register_policy_manager_callback(
+			hdd_ctx->psoc);
+
+		hdd_sysfs_create_driver_root_obj();
+		hdd_sysfs_create_version_interface(hdd_ctx->psoc);
+		hdd_sysfs_create_powerstats_interface();
+		hdd_update_hw_sw_info(hdd_ctx);
+
+		if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+			hdd_err("in ftm mode, no need to configure cds modules");
+			ret = -EINVAL;
+			break;
+		}
+
+		ret = hdd_configure_cds(hdd_ctx);
+		if (ret) {
+			hdd_err("Failed to Enable cds modules; errno: %d", ret);
+			goto destroy_driver_sysfs;
+		}
+
+		hdd_enable_power_management();
+
+		break;
+
+	default:
+		QDF_DEBUG_PANIC("Unknown driver state:%d",
+				hdd_ctx->driver_status);
+		ret = -EINVAL;
+		goto release_lock;
+	}
+
+	hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
+	hdd_info("Wlan transitioned (now ENABLED)");
+
+	hdd_ctx->start_modules_in_progress = false;
+
+	mutex_unlock(&hdd_ctx->iface_change_lock);
+
+	hdd_exit();
+
+	return 0;
+
+destroy_driver_sysfs:
+	hdd_sysfs_destroy_powerstats_interface();
+	hdd_sysfs_destroy_version_interface();
+	hdd_sysfs_destroy_driver_root_obj();
+	cds_post_disable();
+
+deregister_cb:
+	hdd_deregister_cb(hdd_ctx);
+
+cds_txrx_free:
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
+
+	if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl)) {
+		hdd_runtime_suspend_context_deinit(hdd_ctx);
+		dispatcher_pdev_close(hdd_ctx->pdev);
+		hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
+	}
+
+	cds_dp_close(hdd_ctx->psoc);
+
+close:
+	hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
+	hdd_info("Wlan transition aborted (now CLOSED)");
+
+	cds_close(hdd_ctx->psoc);
+
+psoc_close:
+	hdd_component_psoc_close(hdd_ctx->psoc);
+	cds_deinit_ini_config();
+
+cds_free:
+	ol_cds_free();
+
+hif_close:
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	hdd_hif_close(hdd_ctx, hif_ctx);
+power_down:
+	if (!reinit && !unint)
+		pld_power_off(qdf_dev->dev);
+release_lock:
+	hdd_ctx->start_modules_in_progress = false;
+	mutex_unlock(&hdd_ctx->iface_change_lock);
+	if (hdd_ctx->target_hw_name) {
+		qdf_mem_free(hdd_ctx->target_hw_name);
+		hdd_ctx->target_hw_name = NULL;
+	}
+
+	hdd_check_for_leaks(hdd_ctx, reinit);
+	hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
+
+	hdd_exit();
+
+	return ret;
+}
+
+#ifdef WIFI_POS_CONVERGED
+static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
+{
+	int ret = os_if_wifi_pos_register_nl();
+
+	if (ret)
+		hdd_err("os_if_wifi_pos_register_nl failed");
+
+	return ret;
+}
+
+static int hdd_deactivate_wifi_pos(void)
+{
+	int ret = os_if_wifi_pos_deregister_nl();
+
+	if (ret)
+		hdd_err("os_if_wifi_pos_deregister_nl failed");
+
+	return  ret;
+}
+
+/**
+ * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
+ * @hdd_ctx: hdd context
+ *
+ * Return: status of operation
+ */
+static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
+{
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	struct hdd_config *cfg = hdd_ctx->config;
+
+	wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
+	wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
+	wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
+	wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
+	wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
+	wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
+	wifi_pos_set_dwell_time_min(psoc, cfg->nNeighborScanMinChanTime);
+	wifi_pos_set_dwell_time_max(psoc, cfg->nNeighborScanMaxChanTime);
+}
+#else
+static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
+{
+	return oem_activate_service(hdd_ctx);
+}
+
+static int hdd_deactivate_wifi_pos(void)
+{
+	return oem_deactivate_service();
+}
+
+static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
+{
+}
+#endif
+
+/**
+ * __hdd_open() - HDD Open function
+ * @dev:	Pointer to net_device structure
+ *
+ * This is called in response to ifconfig up
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+static int __hdd_open(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int ret;
+
+	hdd_enter_dev(dev);
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
+		adapter->session_id, adapter->device_mode));
+
+	/* Nothing to be done if device is unloading */
+	if (cds_is_driver_unloading()) {
+		hdd_err("Driver is unloading can not open the hdd");
+		return -EBUSY;
+	}
+
+	if (cds_is_driver_recovering()) {
+		hdd_err("WLAN is currently recovering; Please try again.");
+		return -EBUSY;
+	}
+
+	if (qdf_atomic_read(&hdd_ctx->con_mode_flag)) {
+		hdd_err("con_mode_handler is in progress; Please try again.");
+		return -EBUSY;
+	}
+
+	mutex_lock(&hdd_init_deinit_lock);
+	hdd_start_driver_ops_timer(eHDD_DRV_OP_IFF_UP);
+
+	/*
+	 * This scenario can be hit in cases where in the wlan driver after
+	 * registering the netdevices and there is a failure in driver
+	 * initialization. So return error gracefully because the netdevices
+	 * will be de-registered as part of the load failure.
+	 */
+
+	if (!cds_is_driver_loaded()) {
+		hdd_err("Failed to start the wlan driver!!");
+		ret = -EIO;
+		goto err_hdd_hdd_init_deinit_lock;
+	}
+
+
+	ret = hdd_wlan_start_modules(hdd_ctx, false);
+	if (ret) {
+		hdd_err("Failed to start WLAN modules return");
+		goto err_hdd_hdd_init_deinit_lock;
+	}
+
+
+	if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
+		ret = hdd_start_adapter(adapter);
+		if (ret) {
+			hdd_err("Failed to start adapter :%d",
+				adapter->device_mode);
+			goto err_hdd_hdd_init_deinit_lock;
+		}
+	}
+
+	set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
+	if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
+		hdd_debug("Enabling Tx Queues");
+		/* Enable TX queues only when we are connected */
+		wlan_hdd_netif_queue_control(adapter,
+					     WLAN_START_ALL_NETIF_QUEUE,
+					     WLAN_CONTROL_PATH);
+	}
+
+	/* Enable carrier and transmit queues for NDI */
+	if (WLAN_HDD_IS_NDI(adapter)) {
+		hdd_debug("Enabling Tx Queues");
+		wlan_hdd_netif_queue_control(adapter,
+			WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
+			WLAN_CONTROL_PATH);
+	}
+
+	hdd_populate_wifi_pos_cfg(hdd_ctx);
+	hdd_lpass_notify_start(hdd_ctx, adapter);
+
+err_hdd_hdd_init_deinit_lock:
+	hdd_stop_driver_ops_timer();
+	mutex_unlock(&hdd_init_deinit_lock);
+	return ret;
+}
+
+
+/**
+ * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
+ * @dev:	Pointer to net_device structure
+ *
+ * This is called in response to ifconfig up
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+static int hdd_open(struct net_device *dev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_open(dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __hdd_stop() - HDD stop function
+ * @dev:	Pointer to net_device structure
+ *
+ * This is called in response to ifconfig down
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+static int __hdd_stop(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int ret;
+	mac_handle_t mac_handle;
+
+	hdd_enter_dev(dev);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
+			 adapter->session_id, adapter->device_mode));
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret) {
+		set_bit(DOWN_DURING_SSR, &adapter->event_flags);
+		return ret;
+	}
+
+	/* Nothing to be done if the interface is not opened */
+	if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
+		hdd_err("NETDEV Interface is not OPENED");
+		return -ENODEV;
+	}
+
+	/* Make sure the interface is marked as closed */
+	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	hdd_debug("Disabling Auto Power save timer");
+	sme_ps_disable_auto_ps_timer(
+		mac_handle,
+		adapter->session_id);
+
+	/*
+	 * Disable TX on the interface, after this hard_start_xmit() will not
+	 * be called on that interface
+	 */
+	hdd_debug("Disabling queues, adapter device mode: %s(%d)",
+		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
+
+	wlan_hdd_netif_queue_control(adapter,
+				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+				     WLAN_CONTROL_PATH);
+
+	if (adapter->device_mode == QDF_STA_MODE)
+		hdd_lpass_notify_stop(hdd_ctx);
+
+	/*
+	 * NAN data interface is different in some sense. The traffic on NDI is
+	 * bursty in nature and depends on the need to transfer. The service
+	 * layer may down the interface after the usage and up again when
+	 * required. In some sense, the NDI is expected to be available
+	 * (like SAP) iface until NDI delete request is issued by the service
+	 * layer. Skip BSS termination and adapter deletion for NAN Data
+	 * interface (NDI).
+	 */
+	if (WLAN_HDD_IS_NDI(adapter))
+		return 0;
+
+	/*
+	 * The interface is marked as down for outside world (aka kernel)
+	 * But the driver is pretty much alive inside. The driver needs to
+	 * tear down the existing connection on the netdev (session)
+	 * cleanup the data pipes and wait until the control plane is stabilized
+	 * for this interface. The call also needs to wait until the above
+	 * mentioned actions are completed before returning to the caller.
+	 * Notice that hdd_stop_adapter is requested not to close the session
+	 * That is intentional to be able to scan if it is a STA/P2P interface
+	 */
+	hdd_stop_adapter(hdd_ctx, adapter);
+
+	/* DeInit the adapter. This ensures datapath cleanup as well */
+	hdd_deinit_adapter(hdd_ctx, adapter, true);
+
+
+	/*
+	 * Upon wifi turn off, DUT has to flush the scan results so if
+	 * this is the last cli iface, flush the scan database.
+	 */
+	if (!hdd_is_cli_iface_up(hdd_ctx))
+		sme_scan_flush_result(mac_handle);
+
+	if (!hdd_is_any_interface_open(hdd_ctx))
+		hdd_psoc_idle_timer_start(hdd_ctx);
+
+	hdd_exit();
+
+	return 0;
+}
+
+/**
+ * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
+ * @dev: pointer to net_device structure
+ *
+ * This is called in response to ifconfig down
+ *
+ * Return: 0 for success and error number for failure
+ */
+static int hdd_stop(struct net_device *dev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_stop(dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __hdd_uninit() - HDD uninit function
+ * @dev:	Pointer to net_device structure
+ *
+ * This is called during the netdev unregister to uninitialize all data
+ * associated with the device
+ *
+ * Return: None
+ */
+static void __hdd_uninit(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter_dev(dev);
+
+	do {
+		if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
+			hdd_err("Invalid magic");
+			break;
+		}
+
+		hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+		if (!hdd_ctx) {
+			hdd_err("NULL hdd_ctx");
+			break;
+		}
+
+		if (dev != adapter->dev)
+			hdd_err("Invalid device reference");
+
+		hdd_deinit_adapter(hdd_ctx, adapter, true);
+
+		/* after uninit our adapter structure will no longer be valid */
+		adapter->dev = NULL;
+		adapter->magic = 0;
+	} while (0);
+
+	hdd_exit();
+}
+
+/**
+ * hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
+ * @dev: pointer to net_device structure
+ *
+ * This is called during the netdev unregister to uninitialize all data
+ * associated with the device
+ *
+ * Return: none
+ */
+static void hdd_uninit(struct net_device *dev)
+{
+	cds_ssr_protect(__func__);
+	__hdd_uninit(dev);
+	cds_ssr_unprotect(__func__);
+}
+
+static int hdd_open_cesium_nl_sock(void)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
+	struct netlink_kernel_cfg cfg = {
+		.groups = WLAN_NLINK_MCAST_GRP_ID,
+		.input = NULL
+	};
+#endif
+	int ret = 0;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
+	cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
+						   THIS_MODULE,
+#endif
+						   &cfg);
+#else
+	cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
+						   WLAN_NLINK_MCAST_GRP_ID,
+						   NULL, NULL, THIS_MODULE);
+#endif
+
+	if (cesium_nl_srv_sock == NULL) {
+		hdd_err("NLINK:  cesium netlink_kernel_create failed");
+		ret = -ECONNREFUSED;
+	}
+
+	return ret;
+}
+
+static void hdd_close_cesium_nl_sock(void)
+{
+	if (NULL != cesium_nl_srv_sock) {
+		netlink_kernel_release(cesium_nl_srv_sock);
+		cesium_nl_srv_sock = NULL;
+	}
+}
+
+void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx,
+			    struct qdf_mac_addr *curr_mac_addr,
+			    struct qdf_mac_addr *new_mac_addr)
+{
+	uint8_t i;
+
+	hdd_enter();
+
+	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
+		if (!qdf_mem_cmp(curr_mac_addr->bytes,
+				 &hdd_ctx->dynamic_mac_list[i].bytes[0],
+				 sizeof(struct qdf_mac_addr))) {
+			qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i],
+				     new_mac_addr->bytes,
+				     sizeof(struct qdf_mac_addr));
+			break;
+		}
+	}
+
+	hdd_exit();
+}
+
+/**
+ * __hdd_set_mac_address() - set the user specified mac address
+ * @dev:	Pointer to the net device.
+ * @addr:	Pointer to the sockaddr.
+ *
+ * This function sets the user specified mac address using
+ * the command ifconfig wlanX hw ether <mac address>.
+ *
+ * Return: 0 for success, non zero for failure
+ */
+static int __hdd_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_adapter *adapter_temp;
+	struct hdd_context *hdd_ctx;
+	struct sockaddr *psta_mac_addr = addr;
+	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
+	int ret;
+	struct qdf_mac_addr mac_addr;
+
+	hdd_enter_dev(dev);
+
+	if (netif_running(dev)) {
+		hdd_err("On iface up, set mac address change isn't supported");
+		return -EBUSY;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
+	adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
+	if (adapter_temp) {
+		if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
+			return 0;
+		hdd_err("%s adapter exist with same address " MAC_ADDRESS_STR,
+			adapter_temp->dev->name,
+			MAC_ADDR_ARRAY(mac_addr.bytes));
+		return -EINVAL;
+	}
+
+	qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr);
+	if (QDF_IS_STATUS_ERROR(qdf_ret_status))
+		return -EINVAL;
+
+	hdd_info("Changing MAC to " MAC_ADDRESS_STR " of the interface %s ",
+		 MAC_ADDR_ARRAY(mac_addr.bytes), dev->name);
+
+	hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
+	memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
+	memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
+
+	hdd_exit();
+	return qdf_ret_status;
+}
+
+/**
+ * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
+ *			function from SSR
+ * @dev: pointer to net_device structure
+ * @addr: Pointer to the sockaddr
+ *
+ * This function sets the user specified mac address using
+ * the command ifconfig wlanX hw ether <mac address>.
+ *
+ * Return: 0 for success.
+ */
+static int hdd_set_mac_address(struct net_device *dev, void *addr)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_set_mac_address(dev, addr);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx)
+{
+	int i;
+
+	i = qdf_ffz(hdd_ctx->config->intfAddrMask);
+	if (i < 0 || i >= QDF_MAX_CONCURRENCY_PERSONA)
+		return NULL;
+
+	hdd_ctx->config->intfAddrMask |= (1 << i);
+
+	qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].bytes,
+		     &hdd_ctx->config->intfMacAddr[i].bytes,
+		     sizeof(struct qdf_mac_addr));
+	return hdd_ctx->config->intfMacAddr[i].bytes;
+}
+
+void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
+				uint8_t *releaseAddr)
+{
+	int i;
+
+	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
+		if (!memcmp(releaseAddr,
+			    hdd_ctx->dynamic_mac_list[i].bytes,
+			    QDF_MAC_ADDR_SIZE)) {
+			hdd_ctx->config->intfAddrMask &= ~(1 << i);
+			break;
+		}
+	}
+}
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+/**
+ * __hdd_set_multicast_list() - set the multicast address list
+ * @dev:	Pointer to the WLAN device.
+ * @skb:	Pointer to OS packet (sk_buff).
+ *
+ * This funciton sets the multicast address list.
+ *
+ * Return: None
+ */
+static void __hdd_set_multicast_list(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int i = 0, errno;
+	struct netdev_hw_addr *ha;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct pmo_mc_addr_list_params *mc_list_request = NULL;
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	int mc_count = 0;
+
+	hdd_enter_dev(dev);
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
+		goto out;
+
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		goto out;
+
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		goto out;
+
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
+		hdd_err("%s: Driver module is closed", __func__);
+		goto out;
+	}
+
+	mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
+	if (!mc_list_request)
+		goto out;
+
+	/* Delete already configured multicast address list */
+	if (adapter->mc_addr_list.mc_cnt > 0) {
+		hdd_debug("clear previously configured MC address list");
+		hdd_disable_and_flush_mc_addr_list(adapter,
+			pmo_mc_list_change_notify);
+	}
+
+	if (dev->flags & IFF_ALLMULTI) {
+		hdd_debug("allow all multicast frames");
+		hdd_disable_and_flush_mc_addr_list(adapter,
+			pmo_mc_list_change_notify);
+	} else {
+		mc_count = netdev_mc_count(dev);
+		if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) {
+			hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
+				  ucfg_pmo_max_mc_addr_supported(psoc));
+			hdd_disable_and_flush_mc_addr_list(adapter,
+				pmo_mc_list_change_notify);
+			goto free_req;
+		}
+		netdev_for_each_mc_addr(ha, dev) {
+			hdd_debug("ha_addr[%d] "MAC_ADDRESS_STR,
+				i, MAC_ADDR_ARRAY(ha->addr));
+			if (i == mc_count)
+				break;
+			memset(&(mc_list_request->mc_addr[i].bytes),
+				0, ETH_ALEN);
+			memcpy(&(mc_list_request->mc_addr[i].bytes),
+				ha->addr, ETH_ALEN);
+			hdd_debug("mlist[%d] = %pM", i,
+				  mc_list_request->mc_addr[i].bytes);
+			i++;
+		}
+	}
+
+	mc_list_request->psoc = psoc;
+	mc_list_request->vdev_id = adapter->session_id;
+	mc_list_request->count = mc_count;
+
+	errno = hdd_cache_mc_addr_list(mc_list_request);
+	if (errno) {
+		hdd_err("Failed to cache MC address list for vdev %u; errno:%d",
+			adapter->session_id, errno);
+		goto free_req;
+	}
+
+	hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify);
+
+free_req:
+	qdf_mem_free(mc_list_request);
+
+out:
+	hdd_exit();
+}
+
+
+/**
+ * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
+ * @dev: pointer to net_device
+ *
+ * Return: none
+ */
+static void hdd_set_multicast_list(struct net_device *dev)
+{
+	cds_ssr_protect(__func__);
+	__hdd_set_multicast_list(dev);
+	cds_ssr_unprotect(__func__);
+}
+#endif
+
+/**
+ * hdd_select_queue() - used by Linux OS to decide which queue to use first
+ * @dev:	Pointer to the WLAN device.
+ * @skb:	Pointer to OS packet (sk_buff).
+ *
+ * This function is registered with the Linux OS for network
+ * core to decide which queue to use first.
+ *
+ * Return: ac, Queue Index/access category corresponding to UP in IP header
+ */
+static uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
+			  , void *accel_priv
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+			  , select_queue_fallback_t fallback
+#endif
+)
+{
+	return hdd_wmm_select_queue(dev, skb);
+}
+
+static const struct net_device_ops wlan_drv_ops = {
+	.ndo_open = hdd_open,
+	.ndo_stop = hdd_stop,
+	.ndo_uninit = hdd_uninit,
+	.ndo_start_xmit = hdd_hard_start_xmit,
+	.ndo_tx_timeout = hdd_tx_timeout,
+	.ndo_get_stats = hdd_get_stats,
+	.ndo_do_ioctl = hdd_ioctl,
+	.ndo_set_mac_address = hdd_set_mac_address,
+	.ndo_select_queue = hdd_select_queue,
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+	.ndo_set_rx_mode = hdd_set_multicast_list,
+#endif
+};
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
+static const struct net_device_ops wlan_mon_drv_ops = {
+	.ndo_open = hdd_mon_open,
+	.ndo_stop = hdd_stop,
+	.ndo_get_stats = hdd_get_stats,
+};
+
+/**
+ * hdd_set_station_ops() - update net_device ops for monitor mode
+ * @dev: Handle to struct net_device to be updated.
+ * Return: None
+ */
+void hdd_set_station_ops(struct net_device *dev)
+{
+	if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
+		dev->netdev_ops = &wlan_mon_drv_ops;
+	else
+		dev->netdev_ops = &wlan_drv_ops;
+}
+#else
+void hdd_set_station_ops(struct net_device *dev)
+{
+	dev->netdev_ops = &wlan_drv_ops;
+}
+#endif
+
+/**
+ * hdd_alloc_station_adapter() - allocate the station hdd adapter
+ * @hdd_ctx: global hdd context
+ * @mac_addr: mac address to assign to the interface
+ * @name: User-visible name of the interface
+ *
+ * hdd adapter pointer would point to the netdev->priv space, this function
+ * would retrieve the pointer, and setup the hdd adapter configuration.
+ *
+ * Return: the pointer to hdd adapter, otherwise NULL
+ */
+static struct hdd_adapter *
+hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
+			  unsigned char name_assign_type, const char *name)
+{
+	struct net_device *dev;
+	struct hdd_adapter *adapter;
+	struct hdd_station_ctx *sta_ctx;
+	QDF_STATUS qdf_status;
+	void *soc;
+
+	soc = cds_get_context(QDF_MODULE_ID_SOC);
+	/* cfg80211 initialization and registration */
+	dev = alloc_netdev_mq(sizeof(*adapter), name,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
+			      name_assign_type,
+#endif
+			      (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE ?
+			       hdd_mon_mode_ether_setup : ether_setup),
+			      NUM_TX_QUEUES);
+
+	if (!dev) {
+		hdd_err("Failed to allocate new net_device '%s'", name);
+		return NULL;
+	}
+
+	adapter = netdev_priv(dev);
+
+	qdf_mem_zero(adapter, sizeof(*adapter));
+	sta_ctx = &adapter->session.station;
+	qdf_mem_set(sta_ctx->conn_info.staId, sizeof(sta_ctx->conn_info.staId),
+		    HDD_WLAN_INVALID_STA_ID);
+	adapter->dev = dev;
+	adapter->hdd_ctx = hdd_ctx;
+	adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
+	adapter->session_id = HDD_SESSION_ID_INVALID;
+
+	qdf_status = qdf_event_create(&adapter->qdf_session_open_event);
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		goto free_net_dev;
+
+	qdf_status = qdf_event_create(&adapter->qdf_session_close_event);
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		goto free_net_dev;
+
+	adapter->offloads_configured = false;
+	adapter->is_link_up_service_needed = false;
+	adapter->disconnection_in_progress = false;
+	adapter->send_mode_change = true;
+
+	/* Init the net_device structure */
+	strlcpy(dev->name, name, IFNAMSIZ);
+
+	qdf_mem_copy(dev->dev_addr, mac_addr, sizeof(tSirMacAddr));
+	qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr));
+	dev->watchdog_timeo = HDD_TX_TIMEOUT;
+
+	if (cdp_cfg_get(soc,
+			cfg_dp_enable_ip_tcp_udp_checksum_offload))
+		dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+	dev->features |= NETIF_F_RXCSUM;
+
+	hdd_set_tso_flags(hdd_ctx, dev);
+	hdd_set_station_ops(adapter->dev);
+
+	hdd_dev_setup_destructor(dev);
+	dev->ieee80211_ptr = &adapter->wdev;
+	dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
+	adapter->wdev.wiphy = hdd_ctx->wiphy;
+	adapter->wdev.netdev = dev;
+
+	/* set dev's parent to underlying device */
+	SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
+	hdd_wmm_init(adapter);
+	spin_lock_init(&adapter->pause_map_lock);
+	adapter->start_time = qdf_system_ticks();
+	adapter->last_time = adapter->start_time;
+
+	return adapter;
+
+free_net_dev:
+	free_netdev(adapter->dev);
+
+	return NULL;
+}
+
+static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held)
+{
+	struct net_device *dev = adapter->dev;
+	int ret;
+
+	hdd_enter();
+
+	if (rtnl_held) {
+		if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
+
+			ret = dev_alloc_name(dev, dev->name);
+			if (ret < 0) {
+				hdd_err(
+				    "unable to get dev name: %s, err = 0x%x",
+				    dev->name, ret);
+				return QDF_STATUS_E_FAILURE;
+			}
+		}
+
+		ret = register_netdevice(dev);
+		if (ret) {
+			hdd_err("register_netdevice(%s) failed, err = 0x%x",
+				dev->name, ret);
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		ret = register_netdev(dev);
+		if (ret) {
+			hdd_err("register_netdev(%s) failed, err = 0x%x",
+				dev->name, ret);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id,
+					 QDF_STATUS qdf_status)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("Invalid HDD_CTX");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
+	if (NULL == adapter) {
+		hdd_err("NULL adapter for %d", session_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (qdf_status == QDF_STATUS_SUCCESS)
+		set_bit(SME_SESSION_OPENED, &adapter->event_flags);
+
+	qdf_event_set(&adapter->qdf_session_open_event);
+	hdd_debug("session %d opened", adapter->session_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS hdd_sme_close_session_callback(uint8_t session_id)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("Invalid HDD_CTX");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
+	if (NULL == adapter) {
+		hdd_err("NULL adapter");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
+		hdd_err("Invalid magic");
+		return QDF_STATUS_NOT_INITIALIZED;
+	}
+
+	/*
+	 * For NAN Data interface, the close session results in the final
+	 * indication to the userspace
+	 */
+	if (adapter->device_mode == QDF_NDI_MODE)
+		hdd_ndp_session_end_handler(adapter);
+
+	clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
+
+	/*
+	 * We can be blocked while waiting for scheduled work to be
+	 * flushed, and the adapter structure can potentially be freed, in
+	 * which case the magic will have been reset.  So make sure the
+	 * magic is still good, and hence the adapter structure is still
+	 * valid, before signaling completion
+	 */
+	if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
+		qdf_event_set(&adapter->qdf_session_close_event);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+int hdd_vdev_ready(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+
+	status = pmo_vdev_ready(adapter->vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		return qdf_status_to_os_return(status);
+
+	status = ucfg_reg_11d_vdev_created_update(adapter->vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		return qdf_status_to_os_return(status);
+
+	if (wma_capability_enhanced_mcast_filter())
+		status = ucfg_pmo_enhanced_mc_filter_enable(adapter->vdev);
+	else
+		status = ucfg_pmo_enhanced_mc_filter_disable(adapter->vdev);
+
+	return qdf_status_to_os_return(status);
+}
+
+int hdd_vdev_destroy(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+	int errno;
+	struct hdd_context *hdd_ctx;
+	uint8_t vdev_id;
+
+	vdev_id = adapter->session_id;
+	hdd_info("destroying vdev %d", vdev_id);
+
+	/* vdev created sanity check */
+	if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
+		hdd_err("vdev %u does not exist", vdev_id);
+		return -EINVAL;
+	}
+
+	status = ucfg_reg_11d_vdev_delete_update(adapter->vdev);
+	ucfg_scan_set_vdev_del_in_progress(adapter->vdev);
+
+	/* close sme session (destroy vdev in firmware via legacy API) */
+	qdf_event_reset(&adapter->qdf_session_close_event);
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = sme_close_session(hdd_ctx->mac_handle, adapter->session_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("failed to close sme session; status:%d", status);
+		goto release_vdev;
+	}
+
+	/* block on a completion variable until sme session is closed */
+	status = qdf_wait_for_event_completion(
+			&adapter->qdf_session_close_event,
+			SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
+
+		if (adapter->device_mode == QDF_NDI_MODE)
+			hdd_ndp_session_end_handler(adapter);
+
+		if (status == QDF_STATUS_E_TIMEOUT)
+			hdd_err("timed out waiting for sme close session");
+		else if (adapter->qdf_session_close_event.force_set)
+			hdd_info("SSR occurred during sme close session");
+		else
+			hdd_err("failed to wait for sme close session; status:%u",
+				status);
+	}
+
+release_vdev:
+
+	/* do vdev logical destroy via objmgr */
+	errno = hdd_objmgr_release_and_destroy_vdev(adapter);
+	if (errno) {
+		hdd_err("failed to destroy objmgr vdev; errno:%d", errno);
+		return errno;
+	}
+
+	hdd_info("vdev %d destroyed successfully", vdev_id);
+
+	return 0;
+}
+
+static int hdd_set_sme_session_param(struct hdd_adapter *adapter,
+			struct sme_session_params *session_param,
+			csr_roam_complete_cb callback,
+			void *callback_ctx)
+{
+	uint32_t type;
+	uint32_t sub_type;
+	QDF_STATUS status;
+
+	/* determine vdev (sub)type */
+	status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("failed to get vdev type: %d", status);
+		return qdf_status_to_os_return(status);
+	}
+	session_param->sme_session_id = adapter->session_id;
+	session_param->self_mac_addr = (uint8_t *)&adapter->mac_addr;
+	session_param->type_of_persona = type;
+	session_param->subtype_of_persona = sub_type;
+	session_param->session_open_cb = hdd_sme_open_session_callback;
+	session_param->session_close_cb = hdd_sme_close_session_callback;
+	session_param->callback = callback;
+	session_param->callback_ctx = callback_ctx;
+
+	return 0;
+}
+
+int hdd_vdev_create(struct hdd_adapter *adapter,
+		    csr_roam_complete_cb callback, void *ctx)
+{
+	QDF_STATUS status;
+	int errno;
+	struct hdd_context *hdd_ctx;
+	struct sme_session_params sme_session_params = {0};
+
+	hdd_info("creating new vdev");
+
+	/* do vdev create via objmgr */
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	errno = hdd_objmgr_create_and_store_vdev(hdd_ctx->pdev, adapter);
+	if (errno) {
+		hdd_err("failed to create objmgr vdev: %d", errno);
+		return errno;
+	}
+
+	/* Open a SME session (prepare vdev in firmware via legacy API) */
+	status = qdf_event_reset(&adapter->qdf_session_open_event);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("failed to reinit session open event");
+		return -EINVAL;
+	}
+	errno = hdd_set_sme_session_param(adapter, &sme_session_params,
+					  callback, ctx);
+	if (errno) {
+		hdd_err("failed to populating SME params");
+		goto objmgr_vdev_destroy_procedure;
+	}
+
+	status = sme_open_session(hdd_ctx->mac_handle, &sme_session_params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("failed to open sme session: %d", status);
+		errno = qdf_status_to_os_return(status);
+		goto objmgr_vdev_destroy_procedure;
+	}
+
+	/* block on a completion variable until sme session is opened */
+	status = qdf_wait_for_event_completion(&adapter->qdf_session_open_event,
+			SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
+	if (QDF_STATUS_SUCCESS != status) {
+		if (adapter->qdf_session_open_event.force_set) {
+			/*
+			 * SSR/PDR has caused shutdown, which has forcefully
+			 * set the event. Return without the closing session.
+			 */
+			adapter->session_id = HDD_SESSION_ID_INVALID;
+			hdd_err("Session open event forcefully set");
+			return -EINVAL;
+		}
+
+		if (QDF_STATUS_E_TIMEOUT == status)
+			hdd_err("Session failed to open within timeout period");
+		else
+			hdd_err("Failed to wait for session open event(status-%d)",
+				status);
+		errno = -ETIMEDOUT;
+		set_bit(SME_SESSION_OPENED, &adapter->event_flags);
+		goto hdd_vdev_destroy_procedure;
+	}
+
+	if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
+		hdd_err("Session failed to open due to vdev create failure");
+		errno = -EINVAL;
+		goto objmgr_vdev_destroy_procedure;
+	}
+
+	/* firmware ready for component communication, raise vdev_ready event */
+	errno = hdd_vdev_ready(adapter);
+	if (errno) {
+		hdd_err("failed to dispatch vdev ready event: %d", errno);
+		goto hdd_vdev_destroy_procedure;
+	}
+
+	if (adapter->device_mode == QDF_STA_MODE) {
+		hdd_debug("setting RTT mac randomization param: %d",
+			hdd_ctx->config->enable_rtt_mac_randomization);
+		errno = sme_cli_set_command(adapter->session_id,
+			WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC,
+			hdd_ctx->config->enable_rtt_mac_randomization,
+			VDEV_CMD);
+		if (0 != errno)
+			hdd_err("RTT mac randomization param set failed %d",
+				errno);
+	}
+
+	if (adapter->device_mode == QDF_STA_MODE ||
+	    adapter->device_mode == QDF_P2P_CLIENT_MODE)
+		wlan_vdev_set_max_peer_count(adapter->vdev,
+					     HDD_MAX_VDEV_PEER_COUNT);
+
+	hdd_info("vdev %d created successfully", adapter->session_id);
+
+	return 0;
+
+	/*
+	 * Due to legacy constraints, we need to destroy in the same order as
+	 * create. So, split error handling into 2 cases to accommodate.
+	 */
+
+objmgr_vdev_destroy_procedure:
+	QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter));
+
+	return errno;
+
+hdd_vdev_destroy_procedure:
+	QDF_BUG(!hdd_vdev_destroy(adapter));
+
+	return errno;
+}
+
+QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx = &adapter->session.station;
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+	int ret_val;
+	mac_handle_t mac_handle;
+	bool bval = false;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle = hdd_ctx->mac_handle;
+	sme_set_curr_device_mode(mac_handle, adapter->device_mode);
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+	sme_set_pdev_ht_vht_ies(mac_handle, bval);
+
+	sme_set_vdev_ies_per_band(mac_handle, adapter->session_id);
+
+	hdd_roam_profile_init(adapter);
+	hdd_register_wext(adapter->dev);
+
+	hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
+
+	qdf_mem_set(sta_ctx->conn_info.staId,
+		sizeof(sta_ctx->conn_info.staId), HDD_WLAN_INVALID_STA_ID);
+
+	/* set fast roaming capability in sme session */
+	status = sme_config_fast_roaming(mac_handle, adapter->session_id,
+					 true);
+	/* Set the default operation channel */
+	sta_ctx->conn_info.operationChannel =
+		hdd_ctx->config->OperatingChannel;
+
+	/* Make the default Auth Type as OPEN */
+	sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+
+	status = hdd_init_tx_rx(adapter);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("hdd_init_tx_rx() failed, status code %08d [x%08x]",
+		       status, status);
+		goto error_init_txrx;
+	}
+
+	set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
+
+	status = hdd_wmm_adapter_init(adapter);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
+		       status, status);
+		goto error_wmm_init;
+	}
+
+	set_bit(WMM_INIT_DONE, &adapter->event_flags);
+
+	ret_val = sme_cli_set_command(adapter->session_id,
+				      WMI_PDEV_PARAM_BURST_ENABLE,
+				      HDD_ENABLE_SIFS_BURST_DEFAULT,
+				      PDEV_CMD);
+	if (ret_val)
+		hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
+
+	/*
+	 * In case of USB tethering, LRO is disabled. If SSR happened
+	 * during that time, then as part of SSR init, do not enable
+	 * the LRO again. Keep the LRO state same as before SSR.
+	 */
+	if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
+			cfg_dp_lro_enable) &&
+			!(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
+		adapter->dev->features |= NETIF_F_LRO;
+
+	/* rcpi info initialization */
+	qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
+
+	return QDF_STATUS_SUCCESS;
+
+error_wmm_init:
+	clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
+	hdd_deinit_tx_rx(adapter);
+error_init_txrx:
+	hdd_unregister_wext(adapter->dev);
+	QDF_BUG(!hdd_vdev_destroy(adapter));
+
+	return status;
+}
+
+/**
+ * hdd_deinit_station_mode() - De-initialize the station adapter
+ * @hdd_ctx: global hdd context
+ * @adapter: HDD adapter
+ * @rtnl_held: Used to indicate whether or not the caller is holding
+ *             the kernel rtnl_mutex
+ *
+ * This function De-initializes the STA/P2P/OCB adapter.
+ *
+ * Return: None.
+ */
+static void hdd_deinit_station_mode(struct hdd_context *hdd_ctx,
+				       struct hdd_adapter *adapter,
+				       bool rtnl_held)
+{
+	hdd_enter_dev(adapter->dev);
+
+	if (adapter->dev) {
+		if (rtnl_held)
+			adapter->dev->wireless_handlers = NULL;
+		else {
+			rtnl_lock();
+			adapter->dev->wireless_handlers = NULL;
+			rtnl_unlock();
+		}
+	}
+
+	if (test_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
+		hdd_deinit_tx_rx(adapter);
+		clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
+	}
+
+	if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
+		hdd_wmm_adapter_close(adapter);
+		clear_bit(WMM_INIT_DONE, &adapter->event_flags);
+	}
+
+
+	hdd_exit();
+}
+
+void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
+			struct hdd_adapter *adapter,
+			bool rtnl_held)
+{
+	hdd_enter();
+
+	switch (adapter->device_mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_P2P_DEVICE_MODE:
+	case QDF_IBSS_MODE:
+	case QDF_NDI_MODE:
+	{
+		hdd_deinit_station_mode(hdd_ctx, adapter, rtnl_held);
+		break;
+	}
+
+	case QDF_SAP_MODE:
+	case QDF_P2P_GO_MODE:
+	{
+		hdd_deinit_ap_mode(hdd_ctx, adapter, rtnl_held);
+		break;
+	}
+
+	default:
+		break;
+	}
+
+	hdd_exit();
+}
+
+static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
+				bool rtnl_held)
+{
+	struct net_device *dev = NULL;
+
+	if (adapter)
+		dev = adapter->dev;
+	else {
+		hdd_err("adapter is Null");
+		return;
+	}
+
+	hdd_nud_deinit_tracking(adapter);
+	qdf_mutex_destroy(&adapter->disconnection_status_lock);
+	hdd_apf_context_destroy(adapter);
+
+	wlan_hdd_debugfs_csr_deinit(adapter);
+
+	hdd_debugfs_exit(adapter);
+
+	/*
+	 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
+	 * the driver is almost closed and cannot handle either control
+	 * messages or data. However, unregister_netdevice() call above will
+	 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
+	 * to close the active connections(basically excites control path) which
+	 * is not right. Setting this flag helps hdd_stop() to recognize that
+	 * the interface is closed and restricts any operations on that
+	 */
+	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
+
+	if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
+		if (rtnl_held)
+			unregister_netdevice(dev);
+		else
+			unregister_netdev(dev);
+		/*
+		 * Note that the adapter is no longer valid at this point
+		 * since the memory has been reclaimed
+		 */
+	}
+}
+
+static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
+						 tSirMacAddr macAddr)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (!qdf_mem_cmp(adapter->mac_addr.bytes,
+				 macAddr, sizeof(tSirMacAddr))) {
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef CONFIG_FW_LOGS_BASED_ON_INI
+/**
+ * hdd_set_fw_log_params() - Set log parameters to FW
+ * @hdd_ctx: HDD Context
+ * @adapter: HDD Adapter
+ *
+ * This function set the FW Debug log level based on the INI.
+ *
+ * Return: None
+ */
+static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
+				  struct hdd_adapter *adapter)
+{
+	uint8_t count = 0, numentries = 0,
+			moduleloglevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH];
+	uint32_t value = 0;
+	QDF_STATUS status;
+	uint16_t enable_fw_log_level, enable_fw_log_type;
+	int ret;
+
+	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
+	    (!hdd_ctx->config->enable_fw_log)) {
+		hdd_debug("enable_fw_log not enabled in INI or in FTM mode return");
+		return;
+	}
+
+	/* Enable FW logs based on INI configuration */
+	status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc,
+						  &enable_fw_log_type);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+	ret = sme_cli_set_command(adapter->session_id,
+			WMI_DBGLOG_TYPE,
+			enable_fw_log_type,
+			DBG_CMD);
+	if (ret != 0)
+		hdd_err("Failed to enable FW log type ret %d",
+			ret);
+
+	status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc,
+						   &enable_fw_log_level);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+	ret = sme_cli_set_command(adapter->session_id,
+			WMI_DBGLOG_LOG_LEVEL,
+			enable_fw_log_level,
+			DBG_CMD);
+	if (ret != 0)
+		hdd_err("Failed to enable FW log level ret %d",
+			ret);
+
+	hdd_string_to_u8_array(
+		hdd_ctx->config->enableFwModuleLogLevel,
+		moduleloglevel,
+		&numentries,
+		FW_MODULE_LOG_LEVEL_STRING_LENGTH);
+
+	while (count < numentries) {
+		/*
+		 * FW module log level input string looks like
+		 * below:
+		 * gFwDebugModuleLoglevel=<FW Module ID>,
+		 * <Log Level>,...
+		 * For example:
+		 * gFwDebugModuleLoglevel=
+		 * 1,0,2,1,3,2,4,3,5,4,6,5,7,6
+		 * Above input string means :
+		 * For FW module ID 1 enable log level 0
+		 * For FW module ID 2 enable log level 1
+		 * For FW module ID 3 enable log level 2
+		 * For FW module ID 4 enable log level 3
+		 * For FW module ID 5 enable log level 4
+		 * For FW module ID 6 enable log level 5
+		 * For FW module ID 7 enable log level 6
+		 */
+
+		if ((moduleloglevel[count] > WLAN_MODULE_ID_MAX)
+			|| (moduleloglevel[count + 1] > DBGLOG_LVL_MAX)) {
+			hdd_err("Module id %d and dbglog level %d input length is more than max",
+				moduleloglevel[count],
+				moduleloglevel[count + 1]);
+			return;
+		}
+
+		value = moduleloglevel[count] << 16;
+		value |= moduleloglevel[count + 1];
+		ret = sme_cli_set_command(adapter->session_id,
+				WMI_DBGLOG_MOD_LOG_LEVEL,
+				value, DBG_CMD);
+		if (ret != 0)
+			hdd_err("Failed to enable FW module log level %d ret %d",
+				value, ret);
+
+		count += 2;
+	}
+
+}
+#else
+static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
+				  struct hdd_adapter *adapter)
+{
+}
+
+#endif
+
+/**
+ * hdd_configure_chain_mask() - programs chain mask to firmware
+ * @adapter: HDD adapter
+ *
+ * Return: 0 on success or errno on failure
+ */
+static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+	struct wma_caps_per_phy non_dbs_phy_cap;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	bool bval = false;
+
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+
+	hdd_debug("enable2x2: %d, lte_coex: %d, disable_DBS: %d",
+		  bval, hdd_ctx->lte_coex_ant_share,
+		  hdd_ctx->config->dual_mac_feature_disable);
+	hdd_debug("enable_bt_chain_separation %d",
+		  hdd_ctx->config->enable_bt_chain_separation);
+
+	status = wma_get_caps_for_phyidx_hwmode(&non_dbs_phy_cap,
+						HW_MODE_DBS_NONE,
+						CDS_BAND_ALL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("couldn't get phy caps. skip chain mask programming");
+		return qdf_status_to_os_return(status);
+	}
+
+	if (non_dbs_phy_cap.tx_chain_mask_2G < 3 ||
+	    non_dbs_phy_cap.rx_chain_mask_2G < 3 ||
+	    non_dbs_phy_cap.tx_chain_mask_5G < 3 ||
+	    non_dbs_phy_cap.rx_chain_mask_5G < 3) {
+		hdd_debug("firmware not capable. skip chain mask programming");
+		return 0;
+	}
+
+	if (bval && !hdd_ctx->config->enable_bt_chain_separation) {
+		hdd_debug("2x2 enabled. skip chain mask programming");
+		return 0;
+	}
+
+	if (hdd_ctx->config->dual_mac_feature_disable !=
+	    DISABLE_DBS_CXN_AND_SCAN) {
+		hdd_debug("DBS enabled(%d). skip chain mask programming",
+			  hdd_ctx->config->dual_mac_feature_disable);
+		return 0;
+	}
+
+	if (hdd_ctx->lte_coex_ant_share) {
+		hdd_debug("lte ant sharing enabled. skip chainmask programming");
+		return 0;
+	}
+
+	status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc,
+						adapter->session_id);
+	if (status != QDF_STATUS_SUCCESS)
+		goto error;
+
+	return 0;
+
+error:
+	hdd_err("WMI PDEV set param failed");
+	return -EINVAL;
+}
+
+/**
+ * hdd_send_coex_config_params() - Send coex config params to FW
+ * @hdd_ctx: HDD context
+ * @adapter: Primary adapter context
+ *
+ * This function is used to send all coex config related params to FW
+ *
+ * Return: 0 on success and -EINVAL on failure
+ */
+static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx,
+				       struct hdd_adapter *adapter)
+{
+	struct coex_config_params coex_cfg_params = {0};
+	struct wlan_fwol_coex_config config = {0};
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	QDF_STATUS status;
+
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is invalid");
+		goto err;
+	}
+
+	if (!adapter) {
+		hdd_err("adapter is invalid");
+		goto err;
+	}
+
+	if (!psoc) {
+		hdd_err("HDD psoc is invalid");
+		goto err;
+	}
+
+	status = ucfg_fwol_get_coex_config_params(psoc, &config);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Unable to get coex config params");
+		goto err;
+	}
+
+	coex_cfg_params.vdev_id = adapter->session_id;
+	coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER;
+	coex_cfg_params.config_arg1 = config.max_tx_power_for_btc;
+
+	status = sme_send_coex_config_cmd(&coex_cfg_params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to send coex Tx power");
+		goto err;
+	}
+
+	coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI;
+	coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold;
+
+	status = sme_send_coex_config_cmd(&coex_cfg_params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to send coex handover RSSI");
+		goto err;
+	}
+
+	coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE;
+	coex_cfg_params.config_arg1 = config.btc_mode;
+
+	status = sme_send_coex_config_cmd(&coex_cfg_params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to send coex BTC mode");
+		goto err;
+	}
+
+	coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION;
+	coex_cfg_params.config_arg1 = config.antenna_isolation;
+
+	status = sme_send_coex_config_cmd(&coex_cfg_params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to send coex antenna isolation");
+		goto err;
+	}
+
+	coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD;
+	coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold;
+
+	status = sme_send_coex_config_cmd(&coex_cfg_params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to send coex BT low RSSI threshold");
+		goto err;
+	}
+
+	coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL;
+	coex_cfg_params.config_arg1 = config.bt_interference_low_ll;
+	coex_cfg_params.config_arg2 = config.bt_interference_low_ul;
+	coex_cfg_params.config_arg3 = config.bt_interference_medium_ll;
+	coex_cfg_params.config_arg4 = config.bt_interference_medium_ul;
+	coex_cfg_params.config_arg5 = config.bt_interference_high_ll;
+	coex_cfg_params.config_arg6 = config.bt_interference_high_ul;
+
+	status = sme_send_coex_config_cmd(&coex_cfg_params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to send coex BT interference level");
+		goto err;
+	}
+	return 0;
+err:
+	return -EINVAL;
+}
+
+/**
+ * hdd_set_fw_params() - Set parameters to firmware
+ * @adapter: HDD adapter
+ *
+ * This function Sets various parameters to fw once the
+ * adapter is started.
+ *
+ * Return: 0 on success or errno on failure
+ */
+int hdd_set_fw_params(struct hdd_adapter *adapter)
+{
+	int ret;
+	uint16_t upper_brssi_thresh, lower_brssi_thresh, rts_profile;
+	bool enable_dtim_1chrx;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx;
+	bool bval = false;
+	uint8_t max_amsdu_len;
+
+	hdd_enter_dev(adapter->dev);
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx)
+		return -EINVAL;
+
+	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_debug("FTM Mode is active; nothing to do");
+		return 0;
+	}
+
+	ret = sme_cli_set_command(adapter->session_id,
+				WMI_PDEV_PARAM_DTIM_SYNTH,
+				hdd_ctx->config->enable_lprx, PDEV_CMD);
+	if (ret) {
+		hdd_err("Failed to set LPRx");
+		goto error;
+	}
+
+
+	ret = sme_cli_set_command(
+			adapter->session_id,
+			WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION,
+			hdd_ctx->config->enable_dtim_selection_diversity,
+			PDEV_CMD);
+	if (ret) {
+		hdd_err("Failed to set DTIM_OPTIMIZED_CHAIN_SELECTION");
+		goto error;
+	}
+
+	ret = sme_cli_set_command(
+			adapter->session_id,
+			WMI_PDEV_PARAM_TX_SCH_DELAY,
+			hdd_ctx->config->enable_tx_sch_delay,
+			PDEV_CMD);
+	if (ret) {
+		hdd_err("Failed to set WMI_PDEV_PARAM_TX_SCH_DELAY");
+		goto error;
+	}
+
+	ret = sme_cli_set_command(
+			adapter->session_id,
+			WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE,
+			hdd_ctx->config->enable_secondary_rate,
+			PDEV_CMD);
+	if (ret) {
+		hdd_err("Failed to set WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE");
+		goto error;
+	}
+
+	if (adapter->device_mode == QDF_STA_MODE) {
+		status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc,
+						     &upper_brssi_thresh);
+		if (QDF_IS_STATUS_ERROR(status))
+			return -EINVAL;
+
+		sme_set_smps_cfg(adapter->session_id,
+				 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
+				 upper_brssi_thresh);
+
+		status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc,
+						     &lower_brssi_thresh);
+		if (QDF_IS_STATUS_ERROR(status))
+			return -EINVAL;
+
+		sme_set_smps_cfg(adapter->session_id,
+				 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
+				 lower_brssi_thresh);
+
+		status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc,
+						    &enable_dtim_1chrx);
+		if (QDF_IS_STATUS_ERROR(status))
+			return -EINVAL;
+
+		sme_set_smps_cfg(adapter->session_id,
+				 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
+				 enable_dtim_1chrx);
+	}
+
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+
+	if (bval) {
+		hdd_debug("configuring 2x2 mode fw params");
+
+		ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle,
+						  adapter->session_id);
+		if (ret) {
+			hdd_err("WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE set failed %d",
+				ret);
+			goto error;
+		}
+
+		if (hdd_configure_chain_mask(adapter))
+			goto error;
+	} else {
+#define HDD_DTIM_1CHAIN_RX_ID 0x5
+#define HDD_SMPS_PARAM_VALUE_S 29
+		hdd_debug("configuring 1x1 mode fw params");
+
+		/*
+		 * Disable DTIM 1 chain Rx when in 1x1,
+		 * we are passing two value
+		 * as param_id << 29 | param_value.
+		 * Below param_value = 0(disable)
+		 */
+		ret = sme_cli_set_command(adapter->session_id,
+					  WMI_STA_SMPS_PARAM_CMDID,
+					  HDD_DTIM_1CHAIN_RX_ID <<
+					  HDD_SMPS_PARAM_VALUE_S,
+					  VDEV_CMD);
+		if (ret) {
+			hdd_err("DTIM 1 chain set failed %d", ret);
+			goto error;
+		}
+
+#undef HDD_DTIM_1CHAIN_RX_ID
+#undef HDD_SMPS_PARAM_VALUE_S
+
+		if (hdd_configure_chain_mask(adapter))
+			goto error;
+	}
+
+	ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle,
+					    adapter->session_id);
+	if (ret) {
+		hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d", ret);
+		goto error;
+	}
+
+	status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile);
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
+
+	ret = sme_cli_set_command(adapter->session_id,
+				  WMI_VDEV_PARAM_ENABLE_RTSCTS,
+				  rts_profile,
+				  VDEV_CMD);
+	if (ret) {
+		hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
+		goto error;
+	}
+
+	status = ucfg_mlme_get_max_amsdu_num(hdd_ctx->psoc, &max_amsdu_len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get Max AMSDU Num");
+		goto error;
+	}
+
+	hdd_debug("SET AMSDU num %d", max_amsdu_len);
+
+	ret = wma_cli_set_command(adapter->session_id,
+				  GEN_VDEV_PARAM_AMSDU,
+				  max_amsdu_len,
+				  GEN_CMD);
+	if (ret != 0) {
+		hdd_err("GEN_VDEV_PARAM_AMSDU set failed %d", ret);
+		goto error;
+	}
+
+	hdd_set_fw_log_params(hdd_ctx, adapter);
+
+	ret = hdd_send_coex_config_params(hdd_ctx, adapter);
+	if (ret) {
+		hdd_warn("Error initializing coex config params");
+		goto error;
+	}
+
+	hdd_exit();
+
+	return 0;
+
+error:
+	return -EINVAL;
+}
+
+/**
+ * hdd_init_completion() - Initialize Completion Variables
+ * @adapter: HDD adapter
+ *
+ * This function Initialize the completion variables for
+ * a particular adapter
+ *
+ * Return: None
+ */
+static void hdd_init_completion(struct hdd_adapter *adapter)
+{
+	init_completion(&adapter->disconnect_comp_var);
+	init_completion(&adapter->roaming_comp_var);
+	init_completion(&adapter->linkup_event_var);
+	init_completion(&adapter->cancel_rem_on_chan_var);
+	init_completion(&adapter->rem_on_chan_ready_event);
+	init_completion(&adapter->sta_authorized_event);
+	init_completion(&adapter->offchannel_tx_event);
+	init_completion(&adapter->tx_action_cnf_event);
+	init_completion(&adapter->ibss_peer_info_comp);
+	init_completion(&adapter->lfr_fw_status.disable_lfr_event);
+}
+
+/**
+ * hdd_open_adapter() - open and setup the hdd adatper
+ * @hdd_ctx: global hdd context
+ * @session_type: type of the interface to be created
+ * @iface_name: User-visible name of the interface
+ * @macAddr: MAC address to assign to the interface
+ * @name_assign_type: the name of assign type of the netdev
+ * @rtnl_held: the rtnl lock hold flag
+ *
+ * This function open and setup the hdd adpater according to the device
+ * type request, assign the name, the mac address assigned, and then prepared
+ * the hdd related parameters, queue, lock and ready to start.
+ *
+ * Return: the pointer of hdd adapter, otherwise NULL.
+ */
+struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t session_type,
+				const char *iface_name, tSirMacAddr macAddr,
+				unsigned char name_assign_type,
+				bool rtnl_held)
+{
+	struct hdd_adapter *adapter = NULL;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint8_t i;
+
+	if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
+		/*
+		 * Max limit reached on the number of vdevs configured by the
+		 * host. Return error
+		 */
+		hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
+			hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
+		return NULL;
+	}
+
+	status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)macAddr);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		/* Not received valid macAddr */
+		hdd_err("Unable to add virtual intf: Not able to get valid mac address");
+		return NULL;
+	}
+
+	status = hdd_check_for_existing_macaddr(hdd_ctx, macAddr);
+	if (QDF_STATUS_E_FAILURE == status) {
+		hdd_err("Duplicate MAC addr: " MAC_ADDRESS_STR
+				" already exists",
+				MAC_ADDR_ARRAY(macAddr));
+		return NULL;
+	}
+
+	switch (session_type) {
+	case QDF_STA_MODE:
+		/*
+		 * Reset locally administered bit for dynamic_mac_list
+		 * also as while releasing the MAC address for any interface
+		 * mac will be compared with dynamic mac list
+		 */
+		for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
+			if (!qdf_mem_cmp(
+					macAddr,
+					&hdd_ctx->dynamic_mac_list[i].bytes[0],
+					sizeof(struct qdf_mac_addr))) {
+				WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(
+					hdd_ctx->dynamic_mac_list[i].bytes);
+				break;
+			}
+		}
+
+		/* Reset locally administered bit if the device mode is STA */
+		WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macAddr);
+		hdd_debug("locally administered bit reset in sta mode: "
+			  MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
+	/* fall through */
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_P2P_DEVICE_MODE:
+	case QDF_OCB_MODE:
+	case QDF_NDI_MODE:
+	case QDF_MONITOR_MODE:
+		adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
+						    name_assign_type,
+						    iface_name);
+
+		if (NULL == adapter) {
+			hdd_err("failed to allocate adapter for session %d",
+					session_type);
+			return NULL;
+		}
+
+		if (QDF_P2P_CLIENT_MODE == session_type)
+			adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
+		else if (QDF_P2P_DEVICE_MODE == session_type)
+			adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
+		else if (QDF_MONITOR_MODE == session_type)
+			adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
+		else
+			adapter->wdev.iftype = NL80211_IFTYPE_STATION;
+
+		adapter->device_mode = session_type;
+
+
+		/*
+		 * Workqueue which gets scheduled in IPv4 notification
+		 * callback
+		 */
+		INIT_WORK(&adapter->ipv4_notifier_work,
+			  hdd_ipv4_notifier_work_queue);
+
+#ifdef WLAN_NS_OFFLOAD
+		/*
+		 * Workqueue which gets scheduled in IPv6
+		 * notification callback.
+		 */
+		INIT_WORK(&adapter->ipv6_notifier_work,
+			  hdd_ipv6_notifier_work_queue);
+#endif
+		status = hdd_register_interface(adapter, rtnl_held);
+		if (QDF_STATUS_SUCCESS != status)
+			goto err_free_netdev;
+
+		/* Stop the Interface TX queue. */
+		hdd_debug("Disabling queues");
+		wlan_hdd_netif_queue_control(adapter,
+					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+					WLAN_CONTROL_PATH);
+
+		hdd_nud_init_tracking(adapter);
+
+		qdf_mutex_create(&adapter->disconnection_status_lock);
+
+		break;
+
+	case QDF_P2P_GO_MODE:
+	case QDF_SAP_MODE:
+		adapter = hdd_wlan_create_ap_dev(hdd_ctx, macAddr,
+						 name_assign_type,
+						 (uint8_t *) iface_name);
+		if (NULL == adapter) {
+			hdd_err("failed to allocate adapter for session %d",
+					  session_type);
+			return NULL;
+		}
+
+		adapter->wdev.iftype =
+			(session_type ==
+			 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
+			NL80211_IFTYPE_P2P_GO;
+		adapter->device_mode = session_type;
+
+		status = hdd_register_interface(adapter, rtnl_held);
+		if (QDF_STATUS_SUCCESS != status)
+			goto err_free_netdev;
+
+		hdd_debug("Disabling queues");
+		wlan_hdd_netif_queue_control(adapter,
+					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+					WLAN_CONTROL_PATH);
+
+		/*
+		 * Workqueue which gets scheduled in IPv4 notification
+		 * callback
+		 */
+		INIT_WORK(&adapter->ipv4_notifier_work,
+			  hdd_ipv4_notifier_work_queue);
+
+#ifdef WLAN_NS_OFFLOAD
+		/*
+		 * Workqueue which gets scheduled in IPv6
+		 * notification callback.
+		 */
+		INIT_WORK(&adapter->ipv6_notifier_work,
+			  hdd_ipv6_notifier_work_queue);
+#endif
+		break;
+	case QDF_FTM_MODE:
+		adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
+						    name_assign_type,
+						    iface_name);
+		if (NULL == adapter) {
+			hdd_err("Failed to allocate adapter for FTM mode");
+			return NULL;
+		}
+		adapter->wdev.iftype = NL80211_IFTYPE_STATION;
+		adapter->device_mode = session_type;
+		status = hdd_register_interface(adapter, rtnl_held);
+		if (QDF_STATUS_SUCCESS != status)
+			goto err_free_netdev;
+
+		/* Stop the Interface TX queue. */
+		hdd_debug("Disabling queues");
+		wlan_hdd_netif_queue_control(adapter,
+					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+					WLAN_CONTROL_PATH);
+		break;
+	default:
+		hdd_err("Invalid session type %d", session_type);
+		QDF_ASSERT(0);
+		return NULL;
+	}
+
+	hdd_init_completion(adapter);
+	INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
+	qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT);
+	qdf_mutex_create(&adapter->blocked_scan_request_q_lock);
+
+	if (QDF_STATUS_SUCCESS == status) {
+		/* Add it to the hdd's session list. */
+		status = hdd_add_adapter_back(hdd_ctx, adapter);
+	}
+
+	if (QDF_STATUS_SUCCESS != status) {
+		if (NULL != adapter) {
+			hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
+			adapter = NULL;
+		}
+
+		return NULL;
+	}
+	hdd_apf_context_init(adapter);
+
+	if (QDF_STATUS_SUCCESS == status) {
+		policy_mgr_set_concurrency_mode(hdd_ctx->psoc,
+			session_type);
+
+		/* Adapter successfully added. Increment the vdev count */
+		hdd_ctx->current_intf_count++;
+
+		hdd_debug("current_intf_count=%d",
+		       hdd_ctx->current_intf_count);
+
+		hdd_check_and_restart_sap_with_non_dfs_acs();
+	}
+
+	if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
+		hdd_err("Interface %s wow debug_fs init failed",
+			netdev_name(adapter->dev));
+
+	hdd_register_hl_netdev_fc_timer(adapter,
+					hdd_tx_resume_timer_expired_handler);
+
+	hdd_info("%s interface created. iftype: %d", netdev_name(adapter->dev),
+		 session_type);
+
+	if (adapter->device_mode == QDF_STA_MODE)
+		wlan_hdd_debugfs_csr_init(adapter);
+
+	return adapter;
+
+err_free_netdev:
+	wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
+	free_netdev(adapter->dev);
+
+	return NULL;
+}
+
+static void __hdd_close_adapter(struct hdd_context *hdd_ctx,
+				struct hdd_adapter *adapter,
+				bool rtnl_held)
+{
+	qdf_list_destroy(&adapter->blocked_scan_request_q);
+	qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
+	policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
+
+	hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
+
+	if (hdd_ctx->current_intf_count != 0)
+		hdd_ctx->current_intf_count--;
+}
+
+void hdd_close_adapter(struct hdd_context *hdd_ctx,
+		       struct hdd_adapter *adapter,
+		       bool rtnl_held)
+{
+	/*
+	 * Stop the global bus bandwidth timer while touching the adapter list
+	 * to avoid bad memory access by the timer handler.
+	 */
+	hdd_bus_bw_compute_timer_stop(hdd_ctx);
+
+	hdd_remove_adapter(hdd_ctx, adapter);
+	__hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
+
+	/* conditionally restart the bw timer */
+	hdd_bus_bw_compute_timer_try_start(hdd_ctx);
+}
+
+void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_enter();
+
+	while (QDF_IS_STATUS_SUCCESS(hdd_remove_front_adapter(hdd_ctx,
+							      &adapter))) {
+		wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
+		__hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
+	}
+
+	hdd_exit();
+}
+
+void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter)
+{
+	struct qdf_mac_addr *bssid = NULL;
+	tSirUpdateIE updateIE;
+	mac_handle_t mac_handle;
+
+	switch (adapter->device_mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	{
+		struct hdd_station_ctx *sta_ctx =
+			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		bssid = &sta_ctx->conn_info.bssId;
+		break;
+	}
+	case QDF_SAP_MODE:
+	case QDF_P2P_GO_MODE:
+	case QDF_IBSS_MODE:
+	{
+		bssid = &adapter->mac_addr;
+		break;
+	}
+	case QDF_FTM_MODE:
+	case QDF_P2P_DEVICE_MODE:
+	default:
+		/*
+		 * wlan_hdd_reset_prob_rspies should not have been called
+		 * for these kind of devices
+		 */
+		hdd_err("Unexpected request for the current device type %d",
+		       adapter->device_mode);
+		return;
+	}
+
+	qdf_copy_macaddr(&updateIE.bssid, bssid);
+	updateIE.smeSessionId = adapter->session_id;
+	updateIE.ieBufferlength = 0;
+	updateIE.pAdditionIEBuffer = NULL;
+	updateIE.append = true;
+	updateIE.notify = false;
+	mac_handle = hdd_adapter_get_mac_handle(adapter);
+	if (sme_update_add_ie(mac_handle,
+			      &updateIE,
+			      eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
+		hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
+	}
+}
+
+QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
+			    struct hdd_adapter *adapter)
+{
+	return hdd_stop_adapter_ext(hdd_ctx, adapter, 0);
+}
+
+QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx,
+				struct hdd_adapter *adapter,
+				enum hdd_adapter_stop_flag_t flag)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct hdd_station_ctx *sta_ctx;
+	struct csr_roam_profile *roam_profile;
+	union iwreq_data wrqu;
+	tSirUpdateIE updateIE;
+	unsigned long rc;
+	tsap_config_t *sap_config;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+
+	if (adapter->session_id != HDD_SESSION_ID_INVALID)
+		wlan_hdd_cfg80211_deregister_frames(adapter);
+
+	hdd_nud_ignore_tracking(adapter, true);
+	hdd_nud_reset_tracking(adapter);
+	hdd_nud_flush_work(adapter);
+
+	hdd_debug("Disabling queues");
+	wlan_hdd_netif_queue_control(adapter,
+				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+				     WLAN_CONTROL_PATH);
+	/*
+	 * if this is the last active connection check & stop the
+	 * opportunistic timer first
+	 */
+	if ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 1 &&
+	     policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
+		policy_mgr_convert_device_mode_to_qdf_type(
+			adapter->device_mode), NULL) == 1) ||
+	    !policy_mgr_get_connection_count(hdd_ctx->psoc))
+		policy_mgr_check_and_stop_opportunistic_timer(
+			hdd_ctx->psoc, adapter->session_id);
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	switch (adapter->device_mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_IBSS_MODE:
+	case QDF_P2P_DEVICE_MODE:
+	case QDF_NDI_MODE:
+		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+		if (adapter->device_mode == QDF_NDI_MODE ||
+		    hdd_conn_is_connected(sta_ctx) ||
+		    hdd_is_connecting(sta_ctx)) {
+			INIT_COMPLETION(adapter->disconnect_comp_var);
+
+			roam_profile = hdd_roam_profile(adapter);
+			/* For NDI do not use roam_profile */
+			if (adapter->device_mode == QDF_NDI_MODE)
+				status = sme_roam_disconnect(
+					mac_handle,
+					adapter->session_id,
+					eCSR_DISCONNECT_REASON_NDI_DELETE);
+			else if (roam_profile->BSSType ==
+						eCSR_BSS_TYPE_START_IBSS)
+				status = sme_roam_disconnect(
+					mac_handle,
+					adapter->session_id,
+					eCSR_DISCONNECT_REASON_IBSS_LEAVE);
+			else if (adapter->device_mode == QDF_STA_MODE)
+				wlan_hdd_disconnect(adapter,
+					eCSR_DISCONNECT_REASON_DEAUTH);
+			else
+				status = sme_roam_disconnect(
+					mac_handle,
+					adapter->session_id,
+					eCSR_DISCONNECT_REASON_UNSPECIFIED);
+			/* success implies disconnect is queued */
+			if (QDF_IS_STATUS_SUCCESS(status) &&
+			    adapter->device_mode != QDF_STA_MODE) {
+				rc = wait_for_completion_timeout(
+					&adapter->disconnect_comp_var,
+					msecs_to_jiffies
+						(WLAN_WAIT_TIME_DISCONNECT));
+				if (!rc)
+					hdd_warn("disconn_comp_var wait fail");
+			}
+			if (QDF_IS_STATUS_ERROR(status))
+				hdd_warn("failed to post disconnect");
+
+			memset(&wrqu, '\0', sizeof(wrqu));
+			wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+			memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
+			wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
+					    NULL);
+		}
+
+		wlan_hdd_scan_abort(adapter);
+		wlan_hdd_cleanup_actionframe(adapter);
+		wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
+		hdd_clear_fils_connection_info(adapter);
+		hdd_deregister_tx_flow_control(adapter);
+
+#ifdef WLAN_OPEN_SOURCE
+		cancel_work_sync(&adapter->ipv4_notifier_work);
+#ifdef WLAN_NS_OFFLOAD
+		cancel_work_sync(&adapter->ipv6_notifier_work);
+#endif
+#endif
+
+		if (adapter->device_mode == QDF_STA_MODE)
+			wlan_cfg80211_sched_scan_stop(hdd_ctx->pdev,
+						      adapter->dev);
+
+		if (wlan_hdd_try_disconnect(adapter)) {
+			hdd_err("Can't disconnect adapter");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		hdd_vdev_destroy(adapter);
+		break;
+
+	case QDF_MONITOR_MODE:
+		wlan_hdd_scan_abort(adapter);
+		hdd_deregister_tx_flow_control(adapter);
+		hdd_vdev_destroy(adapter);
+		break;
+
+	case QDF_SAP_MODE:
+		if (test_bit(ACS_PENDING, &adapter->event_flags)) {
+			cds_flush_delayed_work(&adapter->acs_pending_work);
+			clear_bit(ACS_PENDING, &adapter->event_flags);
+		}
+
+		wlan_hdd_scan_abort(adapter);
+
+		sap_config = &adapter->session.ap.sap_config;
+		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
+
+		ucfg_ipa_flush(hdd_ctx->pdev);
+
+		if (!(flag & HDD_IN_CAC_WORK_TH_CONTEXT))
+			cds_flush_work(&hdd_ctx->sap_pre_cac_work);
+		/* fallthrough */
+
+	case QDF_P2P_GO_MODE:
+		cds_flush_work(&adapter->sap_stop_bss_work);
+		qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
+		wlan_hdd_undo_acs(adapter);
+
+		if (adapter->device_mode == QDF_P2P_GO_MODE)
+			wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
+
+		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)) {
+			status = wlansap_stop_bss(
+					WLAN_HDD_GET_SAP_CTX_PTR(adapter));
+
+			if (QDF_IS_STATUS_SUCCESS(status)) {
+				struct hdd_hostapd_state *hostapd_state =
+					WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+				qdf_event_reset(&hostapd_state->
+						qdf_stop_bss_event);
+				status = qdf_wait_for_event_completion(
+					&hostapd_state->qdf_stop_bss_event,
+					SME_CMD_START_STOP_BSS_TIMEOUT);
+				if (QDF_IS_STATUS_ERROR(status))
+					hdd_err("failure waiting for wlansap_stop_bss %d",
+						status);
+			} else {
+				hdd_err("failure in wlansap_stop_bss");
+			}
+
+			clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
+			policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
+						adapter->device_mode,
+						adapter->session_id);
+			hdd_green_ap_start_state_mc(hdd_ctx,
+						    adapter->device_mode,
+						    false);
+
+			qdf_copy_macaddr(&updateIE.bssid,
+					 &adapter->mac_addr);
+			updateIE.smeSessionId = adapter->session_id;
+			updateIE.ieBufferlength = 0;
+			updateIE.pAdditionIEBuffer = NULL;
+			updateIE.append = false;
+			updateIE.notify = false;
+
+			/* Probe bcn reset */
+			status = sme_update_add_ie(mac_handle, &updateIE,
+						   eUPDATE_IE_PROBE_BCN);
+			if (status == QDF_STATUS_E_FAILURE)
+				hdd_err("Could not pass PROBE_RSP_BCN to PE");
+
+			/* Assoc resp reset */
+			status = sme_update_add_ie(mac_handle, &updateIE,
+						   eUPDATE_IE_ASSOC_RESP);
+			if (status == QDF_STATUS_E_FAILURE)
+				hdd_err("Could not pass ASSOC_RSP to PE");
+
+			/* Reset WNI_CFG_PROBE_RSP Flags */
+			wlan_hdd_reset_prob_rspies(adapter);
+		}
+		clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
+		qdf_mem_free(adapter->session.ap.beacon);
+		adapter->session.ap.beacon = NULL;
+
+		/*
+		 * If Do_Not_Break_Stream was enabled clear avoid channel list.
+		 */
+		if (policy_mgr_is_dnsc_set(adapter->vdev))
+			wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
+
+#ifdef WLAN_OPEN_SOURCE
+		cancel_work_sync(&adapter->ipv4_notifier_work);
+#ifdef WLAN_NS_OFFLOAD
+		cancel_work_sync(&adapter->ipv6_notifier_work);
+#endif
+#endif
+
+		hdd_vdev_destroy(adapter);
+
+		mutex_unlock(&hdd_ctx->sap_lock);
+		break;
+	case QDF_OCB_MODE:
+		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
+			       cds_get_context(QDF_MODULE_ID_TXRX),
+			       sta_ctx->conn_info.staId[0]);
+		hdd_deregister_tx_flow_control(adapter);
+		hdd_vdev_destroy(adapter);
+		break;
+	default:
+		break;
+	}
+
+	hdd_deregister_hl_netdev_fc_timer(adapter);
+
+	if (adapter->scan_info.default_scan_ies) {
+		qdf_mem_free(adapter->scan_info.default_scan_ies);
+		adapter->scan_info.default_scan_ies = NULL;
+	}
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_deinit_all_adapters - deinit all adapters
+ * @hdd_ctx:   HDD context
+ * @rtnl_held: True if RTNL lock held
+ *
+ */
+void  hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_enter();
+
+	hdd_for_each_adapter(hdd_ctx, adapter)
+		hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
+
+	hdd_exit();
+}
+
+QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_enter();
+
+	cds_flush_work(&hdd_ctx->sap_pre_cac_work);
+
+	hdd_for_each_adapter(hdd_ctx, adapter)
+		hdd_stop_adapter(hdd_ctx, adapter);
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void hdd_reset_scan_operation(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter)
+{
+	switch (adapter->device_mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_IBSS_MODE:
+	case QDF_P2P_DEVICE_MODE:
+	case QDF_NDI_MODE:
+		wlan_hdd_scan_abort(adapter);
+		wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
+		if (adapter->device_mode == QDF_STA_MODE)
+			wlan_cfg80211_sched_scan_stop(hdd_ctx->pdev,
+						      adapter->dev);
+		break;
+	case QDF_P2P_GO_MODE:
+		wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
+		break;
+	case QDF_SAP_MODE:
+		qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
+		wlan_hdd_undo_acs(adapter);
+		break;
+	default:
+		break;
+	}
+}
+
+QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_station_ctx *sta_ctx;
+	struct qdf_mac_addr peerMacAddr;
+	int sta_id;
+	bool value;
+
+	hdd_enter();
+
+	cds_flush_work(&hdd_ctx->sap_pre_cac_work);
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		hdd_info("[SSR] reset adapter with device mode %s(%d)",
+			 qdf_opmode_str(adapter->device_mode),
+			 adapter->device_mode);
+
+		if ((adapter->device_mode == QDF_STA_MODE) ||
+		    (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
+			/* Stop tdls timers */
+			hdd_notify_tdls_reset_adapter(adapter->vdev);
+			adapter->session.station.hdd_reassoc_scenario = false;
+		}
+		ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
+		if (value &&
+		    adapter->device_mode == QDF_SAP_MODE) {
+			wlan_hdd_netif_queue_control(adapter,
+						     WLAN_STOP_ALL_NETIF_QUEUE,
+						     WLAN_CONTROL_PATH);
+			if (test_bit(SOFTAP_BSS_STARTED,
+						&adapter->event_flags))
+				hdd_sap_indicate_disconnect_for_sta(adapter);
+			clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
+		} else {
+			wlan_hdd_netif_queue_control(adapter,
+					   WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+					   WLAN_CONTROL_PATH);
+		}
+		/*
+		 * Clear fc flag if it was set before SSR to avoid TX queues
+		 * permanently stopped after SSR.
+		 * Here WLAN_START_ALL_NETIF_QUEUE will actually not start any
+		 * queue since it's blocked by reason WLAN_CONTROL_PATH.
+		 */
+		if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL))
+			wlan_hdd_netif_queue_control(adapter,
+						     WLAN_START_ALL_NETIF_QUEUE,
+						     WLAN_DATA_FLOW_CONTROL);
+
+		hdd_reset_scan_operation(hdd_ctx, adapter);
+
+		hdd_deinit_tx_rx(adapter);
+		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
+				adapter->device_mode, adapter->session_id);
+		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
+		if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
+			hdd_wmm_adapter_close(adapter);
+			clear_bit(WMM_INIT_DONE, &adapter->event_flags);
+		}
+
+		if (adapter->device_mode == QDF_STA_MODE)
+			hdd_clear_fils_connection_info(adapter);
+
+		if (adapter->device_mode == QDF_SAP_MODE) {
+			wlansap_cleanup_cac_timer(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter));
+			/*
+			 * 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));
+		}
+
+		/* Delete connection peers if any to avoid peer object leaks */
+		if (adapter->device_mode == QDF_STA_MODE ||
+		    adapter->device_mode == QDF_P2P_CLIENT_MODE) {
+			sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+			qdf_copy_macaddr(&peerMacAddr,
+					 &sta_ctx->conn_info.bssId);
+
+		} else if (adapter->device_mode == QDF_P2P_GO_MODE) {
+			clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
+			for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
+				if (adapter->sta_info[sta_id].in_use) {
+					hdd_debug("[SSR] deregister STA with ID %d",
+						  sta_id);
+					hdd_softap_deregister_sta(adapter,
+								  sta_id);
+					adapter->sta_info[sta_id].in_use = 0;
+				}
+			}
+		}
+
+		hdd_nud_ignore_tracking(adapter, true);
+		hdd_nud_reset_tracking(adapter);
+		hdd_nud_flush_work(adapter);
+		hdd_set_disconnect_status(adapter, false);
+
+		hdd_softap_deinit_tx_rx(adapter);
+		hdd_deregister_tx_flow_control(adapter);
+
+		/* Destroy vdev which will be recreated during reinit. */
+		hdd_vdev_destroy(adapter);
+	}
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_info("FTM mode, don't close the module");
+		return true;
+	}
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
+		    test_bit(SME_SESSION_OPENED, &adapter->event_flags))
+			return true;
+	}
+
+	return false;
+}
+
+bool hdd_is_interface_up(struct hdd_adapter *adapter)
+{
+	if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
+		return true;
+	else
+		return false;
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
+	&& !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
+struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
+					  struct ieee80211_channel *channel,
+					  const u8 *bssid, const u8 *ssid,
+					  size_t ssid_len)
+{
+	return cfg80211_get_bss(wiphy, channel, bssid,
+				ssid, ssid_len,
+				WLAN_CAPABILITY_ESS,
+				WLAN_CAPABILITY_ESS);
+}
+#else
+struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
+					  struct ieee80211_channel *channel,
+					  const u8 *bssid, const u8 *ssid,
+					  size_t ssid_len)
+{
+	return cfg80211_get_bss(wiphy, channel, bssid,
+				ssid, ssid_len,
+				IEEE80211_BSS_TYPE_ESS,
+				IEEE80211_PRIVACY_ANY);
+}
+#endif
+
+#if defined CFG80211_CONNECT_BSS || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+#if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+/**
+ * hdd_convert_timeout_reason() - Convert to kernel specific enum
+ * @timeout_reason: reason for connect timeout
+ *
+ * This function is used to convert host timeout
+ * reason enum to kernel specific enum.
+ *
+ * Return: nl timeout enum
+ */
+static enum nl80211_timeout_reason hdd_convert_timeout_reason(
+						tSirResultCodes timeout_reason)
+{
+	switch (timeout_reason) {
+	case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
+		return NL80211_TIMEOUT_SCAN;
+	case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
+		return NL80211_TIMEOUT_AUTH;
+	case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
+		return NL80211_TIMEOUT_ASSOC;
+	default:
+		return NL80211_TIMEOUT_UNSPECIFIED;
+	}
+}
+
+/**
+ * hdd_cfg80211_connect_timeout() - API to send connection timeout reason
+ * @dev: network device
+ * @bssid: bssid to which we want to associate
+ * @timeout_reason: reason for connect timeout
+ *
+ * This API is used to send connection timeout reason to supplicant
+ *
+ * Return: void
+ */
+static void hdd_cfg80211_connect_timeout(struct net_device *dev,
+					 const u8 *bssid,
+					 tSirResultCodes timeout_reason)
+{
+	enum nl80211_timeout_reason nl_timeout_reason;
+
+	nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
+
+	cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL,
+				 nl_timeout_reason);
+}
+
+/**
+ * __hdd_connect_bss() - API to send connection status to supplicant
+ * @dev: network device
+ * @bssid: bssid to which we want to associate
+ * @req_ie: Request Information Element
+ * @req_ie_len: len of the req IE
+ * @resp_ie: Response IE
+ * @resp_ie_len: len of ht response IE
+ * @status: status
+ * @gfp: Kernel Flag
+ * @timeout_reason: reason for connect timeout
+ *
+ * Return: void
+ */
+static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
+			      struct cfg80211_bss *bss, const u8 *req_ie,
+			      size_t req_ie_len, const u8 *resp_ie,
+			      size_t resp_ie_len, int status, gfp_t gfp,
+			      tSirResultCodes timeout_reason)
+{
+	enum nl80211_timeout_reason nl_timeout_reason;
+
+	nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
+
+	cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
+			     resp_ie, resp_ie_len, status, gfp,
+			     nl_timeout_reason);
+}
+#else
+#if defined CFG80211_CONNECT_TIMEOUT || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+static void hdd_cfg80211_connect_timeout(struct net_device *dev,
+					 const u8 *bssid,
+					 tSirResultCodes timeout_reason)
+{
+	cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
+}
+#endif
+
+static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
+			      struct cfg80211_bss *bss, const u8 *req_ie,
+			      size_t req_ie_len, const u8 *resp_ie,
+			      size_t resp_ie_len, int status, gfp_t gfp,
+			      tSirResultCodes timeout_reason)
+{
+	cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
+			     resp_ie, resp_ie_len, status, gfp);
+}
+#endif
+
+/**
+ * hdd_connect_bss() - API to send connection status to supplicant
+ * @dev: network device
+ * @bssid: bssid to which we want to associate
+ * @req_ie: Request Information Element
+ * @req_ie_len: len of the req IE
+ * @resp_ie: Response IE
+ * @resp_ie_len: len of ht response IE
+ * @status: status
+ * @gfp: Kernel Flag
+ * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
+ * @timeout_reason: reason for connect timeout
+ *
+ * The API is a wrapper to send connection status to supplicant
+ *
+ * Return: Void
+ */
+#if defined CFG80211_CONNECT_TIMEOUT || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
+			struct cfg80211_bss *bss, const u8 *req_ie,
+			size_t req_ie_len, const u8 *resp_ie,
+			size_t resp_ie_len, int status, gfp_t gfp,
+			bool connect_timeout,
+			tSirResultCodes timeout_reason)
+{
+	if (connect_timeout)
+		hdd_cfg80211_connect_timeout(dev, bssid, timeout_reason);
+	else
+		__hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
+				  resp_ie_len, status, gfp, timeout_reason);
+}
+#else
+static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
+			struct cfg80211_bss *bss, const u8 *req_ie,
+			size_t req_ie_len, const u8 *resp_ie,
+			size_t resp_ie_len, int status, gfp_t gfp,
+			bool connect_timeout,
+			tSirResultCodes timeout_reason)
+{
+	__hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
+			  resp_ie_len, status, gfp, timeout_reason);
+}
+#endif
+
+#if defined(WLAN_FEATURE_FILS_SK)
+#if defined(CFG80211_CONNECT_DONE) || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
+#if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
+		 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
+/**
+ * hdd_populate_fils_params() - Populate FILS keys to connect response
+ * @fils_params: connect response to supplicant
+ * @fils_kek: FILS kek
+ * @fils_kek_len: FILS kek length
+ * @pmk: FILS PMK
+ * @pmk_len: FILS PMK length
+ * @pmkid: PMKID
+ * @fils_seq_num: FILS Seq number
+ *
+ * Return: None
+ */
+static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
+				     *fils_params, const uint8_t *fils_kek,
+				     size_t fils_kek_len, const uint8_t *pmk,
+				     size_t pmk_len, const uint8_t *pmkid,
+				     uint16_t fils_seq_num)
+{
+	/* Increament seq number to be used for next FILS */
+	fils_params->fils_erp_next_seq_num = fils_seq_num + 1;
+	fils_params->update_erp_next_seq_num = true;
+	fils_params->fils_kek = fils_kek;
+	fils_params->fils_kek_len = fils_kek_len;
+	fils_params->pmk = pmk;
+	fils_params->pmk_len = pmk_len;
+	fils_params->pmkid = pmkid;
+}
+#else
+static inline void hdd_populate_fils_params(struct cfg80211_connect_resp_params
+					    *fils_params, const uint8_t
+					    *fils_kek, size_t fils_kek_len,
+					    const uint8_t *pmk, size_t pmk_len,
+					    const uint8_t *pmkid,
+					    uint16_t fils_seq_num)
+{ }
+#endif
+
+void hdd_update_hlp_info(struct net_device *dev,
+			 struct csr_roam_info *roam_info)
+{
+	struct sk_buff *skb;
+	uint16_t skb_len;
+	struct llc_snap_hdr_t *llc_hdr;
+	QDF_STATUS status;
+	uint8_t *hlp_data;
+	uint16_t hlp_data_len;
+	struct fils_join_rsp_params *roam_fils_params
+				= roam_info->fils_join_rsp;
+	struct hdd_adapter *padapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+	if (!roam_fils_params) {
+		hdd_err("FILS Roam Param NULL");
+		return;
+	}
+
+	if (!roam_fils_params->hlp_data_len) {
+		hdd_err("FILS HLP Data NULL, len %d",
+			roam_fils_params->hlp_data_len);
+		return;
+	}
+
+	hlp_data = roam_fils_params->hlp_data;
+	hlp_data_len = roam_fils_params->hlp_data_len;
+
+	/* Calculate skb length */
+	skb_len = (2 * ETH_ALEN) + hlp_data_len;
+	skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false);
+	if (skb == NULL) {
+		hdd_err("HLP packet nbuf alloc fails");
+		return;
+	}
+
+	qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->dst_mac.bytes,
+				 QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->src_mac.bytes,
+				 QDF_MAC_ADDR_SIZE);
+
+	llc_hdr = (struct llc_snap_hdr_t *) hlp_data;
+	if (IS_SNAP(llc_hdr)) {
+		hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
+		hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
+	}
+
+	qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len);
+
+	/*
+	 * This HLP packet is formed from HLP info encapsulated
+	 * in assoc response frame which is AEAD encrypted.
+	 * Hence, this checksum validation can be set unnecessary.
+	 * i.e. network layer need not worry about checksum.
+	 */
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+	status = hdd_rx_packet_cbk(padapter, skb);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Sending HLP packet fails");
+		return;
+	}
+	hdd_debug("send HLP packet to netif successfully");
+}
+
+/**
+ * hdd_connect_done() - Wrapper API to call cfg80211_connect_done
+ * @dev: network device
+ * @bssid: bssid to which we want to associate
+ * @bss: cfg80211 bss info
+ * @roam_info: information about connected bss
+ * @req_ie: Request Information Element
+ * @req_ie_len: len of the req IE
+ * @resp_ie: Response IE
+ * @resp_ie_len: len of ht response IE
+ * @status: status
+ * @gfp: allocation flags
+ * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
+ * @timeout_reason: reason for connect timeout
+ *
+ * This API is used as wrapper to send FILS key/sequence number
+ * params etc. to supplicant in case of FILS connection
+ *
+ * Return: None
+ */
+static void hdd_connect_done(struct net_device *dev, const u8 *bssid,
+			     struct cfg80211_bss *bss,
+			     struct csr_roam_info *roam_info,
+			     const u8 *req_ie, size_t req_ie_len,
+			     const u8 *resp_ie, size_t resp_ie_len, u16 status,
+			     gfp_t gfp, bool connect_timeout,
+			     tSirResultCodes timeout_reason)
+{
+	struct cfg80211_connect_resp_params fils_params;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct fils_join_rsp_params *roam_fils_params =
+				roam_info->fils_join_rsp;
+
+	qdf_mem_zero(&fils_params, sizeof(fils_params));
+
+	if (!roam_fils_params) {
+		fils_params.status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+	} else {
+		fils_params.status = status;
+		fils_params.bssid = bssid;
+		fils_params.timeout_reason =
+				hdd_convert_timeout_reason(timeout_reason);
+		fils_params.req_ie = req_ie;
+		fils_params.req_ie_len = req_ie_len;
+		fils_params.resp_ie = resp_ie;
+		fils_params.resp_ie_len = resp_ie_len;
+		fils_params.bss = bss;
+		hdd_populate_fils_params(&fils_params, roam_fils_params->kek,
+					 roam_fils_params->kek_len,
+					 roam_fils_params->fils_pmk,
+					 roam_fils_params->fils_pmk_len,
+					 roam_fils_params->fils_pmkid,
+					 roam_info->fils_seq_num);
+		hdd_save_gtk_params(adapter, roam_info, false);
+	}
+	hdd_debug("FILS indicate connect status %d seq no %d",
+		  fils_params.status,
+		  fils_params.fils_erp_next_seq_num);
+
+	cfg80211_connect_done(dev, &fils_params, gfp);
+
+	if (roam_fils_params && roam_fils_params->hlp_data_len)
+		hdd_update_hlp_info(dev, roam_info);
+
+	/* Clear all the FILS key info */
+	if (roam_fils_params && roam_fils_params->fils_pmk)
+		qdf_mem_free(roam_fils_params->fils_pmk);
+	if (roam_fils_params)
+		qdf_mem_free(roam_fils_params);
+	roam_info->fils_join_rsp = NULL;
+}
+#else
+static inline void
+hdd_connect_done(struct net_device *dev, const u8 *bssid,
+		 struct cfg80211_bss *bss, struct csr_roam_info *roam_info,
+		 const u8 *req_ie, size_t req_ie_len,
+		 const u8 *resp_ie, size_t resp_ie_len, u16 status,
+		 gfp_t gfp, bool connect_timeout,
+		 tSirResultCodes timeout_reason)
+{ }
+#endif
+#endif
+
+#if defined(WLAN_FEATURE_FILS_SK) && \
+	(defined(CFG80211_CONNECT_DONE) || \
+		(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)))
+/**
+ * hdd_fils_update_connect_results() - API to send fils connection status to
+ * supplicant.
+ * @dev: network device
+ * @bssid: bssid to which we want to associate
+ * @bss: cfg80211 bss info
+ * @roam_info: information about connected bss
+ * @req_ie: Request Information Element
+ * @req_ie_len: len of the req IE
+ * @resp_ie: Response IE
+ * @resp_ie_len: len of ht response IE
+ * @status: status
+ * @gfp: allocation flags
+ * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
+ * @timeout_reason: reason for connect timeout
+ *
+ * The API is a wrapper to send connection status to supplicant
+ *
+ * Return: 0 if success else failure
+ */
+static int hdd_fils_update_connect_results(struct net_device *dev,
+			const u8 *bssid,
+			struct cfg80211_bss *bss,
+			struct csr_roam_info *roam_info, const u8 *req_ie,
+			size_t req_ie_len, const u8 *resp_ie,
+			size_t resp_ie_len, u16 status, gfp_t gfp,
+			bool connect_timeout,
+			tSirResultCodes timeout_reason)
+{
+	hdd_enter();
+	if (!roam_info || !roam_info->is_fils_connection)
+		return -EINVAL;
+
+	hdd_connect_done(dev, bssid, bss, roam_info, req_ie, req_ie_len,
+			 resp_ie, resp_ie_len, status, gfp, connect_timeout,
+			 timeout_reason);
+	return 0;
+}
+#else
+static inline int hdd_fils_update_connect_results(struct net_device *dev,
+			const u8 *bssid,
+			struct cfg80211_bss *bss,
+			struct csr_roam_info *roam_info, const u8 *req_ie,
+			size_t req_ie_len, const u8 *resp_ie,
+			size_t resp_ie_len, u16 status, gfp_t gfp,
+			bool connect_timeout,
+			tSirResultCodes timeout_reason)
+{
+	return -EINVAL;
+}
+#endif
+
+/**
+ * hdd_connect_result() - API to send connection status to supplicant
+ * @dev: network device
+ * @bssid: bssid to which we want to associate
+ * @roam_info: information about connected bss
+ * @req_ie: Request Information Element
+ * @req_ie_len: len of the req IE
+ * @resp_ie: Response IE
+ * @resp_ie_len: len of ht response IE
+ * @status: status
+ * @gfp: Kernel Flag
+ * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
+ * @timeout_reason: reason for connect timeout
+ *
+ * The API is a wrapper to send connection status to supplicant
+ * and allow runtime suspend
+ *
+ * Return: Void
+ */
+void hdd_connect_result(struct net_device *dev, const u8 *bssid,
+			struct csr_roam_info *roam_info, const u8 *req_ie,
+			size_t req_ie_len, const u8 *resp_ie,
+			size_t resp_ie_len, u16 status, gfp_t gfp,
+			bool connect_timeout,
+			tSirResultCodes timeout_reason)
+{
+	struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
+	struct cfg80211_bss *bss = NULL;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(padapter);
+
+	if (WLAN_STATUS_SUCCESS == status) {
+		struct ieee80211_channel *chan;
+		int freq;
+		int chan_no = roam_info->pBssDesc->channelId;
+
+		if (chan_no <= 14)
+			freq = ieee80211_channel_to_frequency(chan_no,
+				HDD_NL80211_BAND_2GHZ);
+		else
+			freq = ieee80211_channel_to_frequency(chan_no,
+				HDD_NL80211_BAND_5GHZ);
+
+		chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
+		bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,
+			roam_info->u.pConnectedProfile->SSID.ssId,
+			roam_info->u.pConnectedProfile->SSID.length);
+	}
+
+	if (hdd_fils_update_connect_results(dev, bssid, bss,
+			roam_info, req_ie, req_ie_len, resp_ie,
+			resp_ie_len, status, gfp, connect_timeout,
+			timeout_reason) != 0) {
+		hdd_connect_bss(dev, bssid, bss, req_ie,
+			req_ie_len, resp_ie, resp_ie_len,
+			status, gfp, connect_timeout, timeout_reason);
+	}
+
+	qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
+	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
+}
+#else
+void hdd_connect_result(struct net_device *dev, const u8 *bssid,
+			struct csr_roam_info *roam_info, const u8 *req_ie,
+			size_t req_ie_len, const u8 *resp_ie,
+			size_t resp_ie_len, u16 status, gfp_t gfp,
+			bool connect_timeout,
+			tSirResultCodes timeout_reason)
+{
+	struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(padapter);
+
+	cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
+				resp_ie, resp_ie_len, status, gfp);
+
+	qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
+	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
+}
+#endif
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
+				 uint32_t bandwidth)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
+	QDF_STATUS status;
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	struct qdf_mac_addr bssid;
+	struct csr_roam_profile roam_profile;
+	struct ch_params ch_params;
+	eConnectionState connstate;
+
+	if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
+	    adapter->device_mode != QDF_STA_MODE) {
+		hdd_err("Not supported, device is not in monitor mode or sta mission mode");
+		return -EINVAL;
+	}
+	if (adapter->device_mode == QDF_STA_MODE &&
+	    hdd_ctx->config->enable_change_channel_bandwidth) {
+		connstate = sta_ctx->conn_info.connState;
+		if (eConnectionState_Associated == connstate ||
+		    eConnectionState_Connecting == connstate) {
+			return -EINVAL;
+		}
+	}
+
+	/* Validate Channel */
+	if (!WLAN_REG_IS_24GHZ_CH(chan) && !WLAN_REG_IS_5GHZ_CH(chan)) {
+		hdd_err("Channel %d Not supported", chan);
+		return -EINVAL;
+	}
+
+	if (WLAN_REG_IS_24GHZ_CH(chan)) {
+		if (bandwidth == CH_WIDTH_80MHZ) {
+			hdd_err("BW80 not possible in 2.4GHz band");
+			return -EINVAL;
+		}
+		if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 14) &&
+				(bandwidth != CH_WIDTH_MAX)) {
+			hdd_err("Only BW20 possible on channel 14");
+			return -EINVAL;
+		}
+	}
+
+	if (WLAN_REG_IS_5GHZ_CH(chan)) {
+		if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 165) &&
+				(bandwidth != CH_WIDTH_MAX)) {
+			hdd_err("Only BW20 possible on channel 165");
+			return -EINVAL;
+		}
+	}
+
+	hdd_debug("Set monitor mode Channel %d", chan);
+	qdf_mem_zero(&roam_profile, sizeof(roam_profile));
+	roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
+	roam_profile.ChannelInfo.numOfChannels = 1;
+	roam_profile.phyMode = ch_info->phy_mode;
+	roam_profile.ch_params.ch_width = bandwidth;
+	hdd_select_cbmode(adapter, chan, &roam_profile.ch_params);
+	if (hdd_ctx->config->enable_change_channel_bandwidth &&
+	    (!sme_find_session_by_bssid(mac_handle, adapter->mac_addr.bytes))) {
+		status = sme_create_mon_session(mac_handle,
+						adapter->mac_addr.bytes,
+						adapter->session_id);
+		if (status != QDF_STATUS_SUCCESS) {
+			hdd_err("Status: %d Failed to create session.",
+				status);
+			return qdf_status_to_os_return(status);
+		}
+	}
+	qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
+		     QDF_MAC_ADDR_SIZE);
+
+	ch_params.ch_width = bandwidth;
+	wlan_reg_set_channel_params(hdd_ctx->pdev, chan, 0, &ch_params);
+	if (ch_params.ch_width == CH_WIDTH_INVALID) {
+		hdd_err("Invalid capture channel or bandwidth for a country");
+		return -EINVAL;
+	}
+	if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan,
+				POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
+		hdd_err("Failed to change hw mode");
+		return -EINVAL;
+	}
+
+	status = sme_roam_channel_change_req(hdd_ctx->mac_handle,
+					     bssid, &ch_params,
+					     &roam_profile);
+	if (status) {
+		hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
+			status);
+	}
+
+	adapter->mon_chan = chan;
+	adapter->mon_bandwidth = bandwidth;
+	return qdf_status_to_os_return(status);
+}
+#endif
+
+#ifdef MSM_PLATFORM
+/**
+ * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO
+ * @adapter: pointer to adapter
+ *
+ * This function calls cfg80211 API to stop P2P GO
+ *
+ * Return: None
+ */
+static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
+{
+	hdd_debug("[SSR] send stop ap to supplicant");
+	cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
+}
+
+static inline void hdd_delete_sta(struct hdd_adapter *adapter)
+{
+}
+#else
+static inline void hdd_stop_p2p_go(struct hdd_adapter *adapter)
+{
+}
+
+/**
+ * hdd_delete_sta() - call cfg80211 API to delete STA
+ * @adapter: pointer to adapter
+ *
+ * This function calls cfg80211 API to delete STA
+ *
+ * Return: None
+ */
+static void hdd_delete_sta(struct hdd_adapter *adapter)
+{
+	struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
+
+	hdd_debug("[SSR] send restart supplicant");
+	/* event supplicant to restart */
+	cfg80211_del_sta(adapter->dev,
+			 (const u8 *)&bcast_mac.bytes[0],
+			 GFP_KERNEL);
+}
+#endif
+
+QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+	eConnectionState connState;
+	bool value;
+
+	hdd_enter();
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (!hdd_is_interface_up(adapter))
+			continue;
+
+		hdd_debug("[SSR] start adapter with device mode %s(%d)",
+			  qdf_opmode_str(adapter->device_mode),
+			  adapter->device_mode);
+
+		hdd_wmm_init(adapter);
+
+		switch (adapter->device_mode) {
+		case QDF_STA_MODE:
+		case QDF_P2P_CLIENT_MODE:
+		case QDF_P2P_DEVICE_MODE:
+
+			connState = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
+					->conn_info.connState;
+
+			hdd_start_station_adapter(adapter);
+			/* Open the gates for HDD to receive Wext commands */
+			adapter->is_link_up_service_needed = false;
+
+			/* Indicate disconnect event to supplicant
+			 * if associated previously
+			 */
+			if (eConnectionState_Associated == connState ||
+			    eConnectionState_IbssConnected == connState ||
+			    eConnectionState_NotConnected == connState ||
+			    eConnectionState_IbssDisconnected == connState ||
+			    eConnectionState_Disconnecting == connState) {
+				union iwreq_data wrqu;
+
+				memset(&wrqu, '\0', sizeof(wrqu));
+				wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+				memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
+				wireless_send_event(adapter->dev, SIOCGIWAP,
+						    &wrqu, NULL);
+				adapter->session.station.
+				hdd_reassoc_scenario = false;
+
+				/* indicate disconnected event to nl80211 */
+				wlan_hdd_cfg80211_indicate_disconnect(
+						adapter->dev, false,
+						WLAN_REASON_UNSPECIFIED);
+			} else if (eConnectionState_Connecting == connState) {
+				/*
+				 * Indicate connect failure to supplicant if we
+				 * were in the process of connecting
+				 */
+				hdd_connect_result(adapter->dev, NULL, NULL,
+						   NULL, 0, NULL, 0,
+						   WLAN_STATUS_ASSOC_DENIED_UNSPEC,
+						   GFP_KERNEL, false, 0);
+			}
+
+			hdd_register_tx_flow_control(adapter,
+					hdd_tx_resume_timer_expired_handler,
+					hdd_tx_resume_cb,
+					hdd_tx_flow_control_is_pause);
+
+			hdd_lpass_notify_start(hdd_ctx, adapter);
+			hdd_nud_ignore_tracking(adapter, false);
+			break;
+
+		case QDF_SAP_MODE:
+			ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
+							   &value);
+			if (value)
+				hdd_start_ap_adapter(adapter);
+
+			break;
+
+		case QDF_P2P_GO_MODE:
+			hdd_delete_sta(adapter);
+			break;
+		case QDF_MONITOR_MODE:
+			hdd_start_station_adapter(adapter);
+			hdd_set_mon_rx_cb(adapter->dev);
+			wlan_hdd_set_mon_chan(adapter, adapter->mon_chan,
+					      adapter->mon_bandwidth);
+			break;
+		default:
+			break;
+		}
+		/*
+		 * Action frame registered in one adapter which will
+		 * applicable to all interfaces
+		 */
+		wlan_hdd_cfg80211_register_frames(adapter);
+	}
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (!hdd_is_interface_up(adapter))
+			continue;
+
+		if (adapter->device_mode == QDF_P2P_GO_MODE)
+			hdd_stop_p2p_go(adapter);
+	}
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
+				 struct hdd_adapter **out_adapter)
+{
+	QDF_STATUS status;
+	qdf_list_node_t *node;
+
+	*out_adapter = NULL;
+
+	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
+	status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
+	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
+				struct hdd_adapter *current_adapter,
+				struct hdd_adapter **out_adapter)
+{
+	QDF_STATUS status;
+	qdf_list_node_t *node;
+
+	*out_adapter = NULL;
+
+	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
+	status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
+				    &current_adapter->node,
+				    &node);
+	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
+
+	return status;
+}
+
+QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
+			      struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+
+	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
+	status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
+	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
+
+	return status;
+}
+
+QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
+				    struct hdd_adapter **out_adapter)
+{
+	QDF_STATUS status;
+	qdf_list_node_t *node;
+
+	*out_adapter = NULL;
+
+	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
+	status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
+	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
+
+	return status;
+}
+
+QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
+				struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+
+	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
+	status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
+	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
+
+	return status;
+}
+
+QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
+				 struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+
+	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
+	status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
+	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
+
+	return status;
+}
+
+struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
+	struct hdd_context *hdd_ctx, tSirMacAddr mac_addr)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if ((adapter->device_mode == QDF_STA_MODE ||
+		     adapter->device_mode == QDF_P2P_CLIENT_MODE ||
+		     adapter->device_mode == QDF_P2P_DEVICE_MODE) &&
+		    ucfg_p2p_check_random_mac(hdd_ctx->psoc,
+					      adapter->session_id, mac_addr))
+			return adapter;
+	}
+
+	return NULL;
+}
+
+struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
+					  tSirMacAddr macAddr)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (!qdf_mem_cmp(adapter->mac_addr.bytes,
+				 macAddr, sizeof(tSirMacAddr)))
+			return adapter;
+	}
+
+	return NULL;
+}
+
+struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
+				       uint32_t vdev_id)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter->session_id == vdev_id)
+			return adapter;
+	}
+
+	return NULL;
+}
+
+/**
+ * hdd_get_adapter_by_sme_session_id() - Return adapter with
+ * the sessionid
+ * @hdd_ctx: hdd context.
+ * @sme_session_id: sme session is for the adapter to get.
+ *
+ * This function is used to get the adapter with provided session id
+ *
+ * Return: adapter pointer if found
+ *
+ */
+struct hdd_adapter *
+hdd_get_adapter_by_sme_session_id(struct hdd_context *hdd_ctx,
+				  uint32_t sme_session_id)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter->session_id == sme_session_id)
+			return adapter;
+	}
+
+	return NULL;
+}
+
+struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
+					     const char *iface_name)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (!qdf_str_cmp(adapter->dev->name, iface_name))
+			return adapter;
+	}
+
+	return NULL;
+}
+
+/**
+ * hdd_get_adapter() - to get adapter matching the mode
+ * @hdd_ctx: hdd context
+ * @mode: adapter mode
+ *
+ * This routine will return the pointer to adapter matching
+ * with the passed mode.
+ *
+ * Return: pointer to adapter or null
+ */
+struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
+			enum QDF_OPMODE mode)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter->device_mode == mode)
+			return adapter;
+	}
+
+	return NULL;
+}
+
+enum QDF_OPMODE hdd_get_device_mode(uint32_t session_id)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("Invalid HDD context");
+		return QDF_MAX_NO_OF_MODE;
+	}
+
+	adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
+	if (!adapter) {
+		hdd_err("Invalid HDD adapter");
+		return QDF_MAX_NO_OF_MODE;
+	}
+
+	return adapter->device_mode;
+}
+
+/**
+ * hdd_get_operating_channel() - return operating channel of the device mode
+ * @hdd_ctx:	Pointer to the HDD context.
+ * @mode:	Device mode for which operating channel is required.
+ *              Supported modes:
+ *			QDF_STA_MODE,
+ *			QDF_P2P_CLIENT_MODE,
+ *			QDF_SAP_MODE,
+ *			QDF_P2P_GO_MODE.
+ *
+ * This API returns the operating channel of the requested device mode
+ *
+ * Return: channel number. "0" id the requested device is not found OR it is
+ *	   not connected.
+ */
+uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
+			enum QDF_OPMODE mode)
+{
+	struct hdd_adapter *adapter;
+	uint8_t operatingChannel = 0;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (mode == adapter->device_mode) {
+			switch (adapter->device_mode) {
+			case QDF_STA_MODE:
+			case QDF_P2P_CLIENT_MODE:
+				if (hdd_conn_is_connected
+					    (WLAN_HDD_GET_STATION_CTX_PTR
+						(adapter))) {
+					operatingChannel =
+						(WLAN_HDD_GET_STATION_CTX_PTR
+						(adapter))->conn_info.
+							operationChannel;
+				}
+				break;
+			case QDF_SAP_MODE:
+			case QDF_P2P_GO_MODE:
+				/* softap connection info */
+				if (test_bit
+					    (SOFTAP_BSS_STARTED,
+					    &adapter->event_flags))
+					operatingChannel =
+						(WLAN_HDD_GET_AP_CTX_PTR
+						(adapter))->operating_channel;
+				break;
+			default:
+				break;
+			}
+
+			/* Found the device of interest. break the loop */
+			break;
+		}
+	}
+
+	return operatingChannel;
+}
+
+static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
+							  hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_enter();
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter->device_mode == QDF_STA_MODE ||
+		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
+		    adapter->device_mode == QDF_IBSS_MODE ||
+		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
+		    adapter->device_mode == QDF_SAP_MODE ||
+		    adapter->device_mode == QDF_P2P_GO_MODE) {
+			hdd_unregister_wext(adapter->dev);
+		}
+	}
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_enter();
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter->device_mode == QDF_STA_MODE ||
+		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
+		    adapter->device_mode == QDF_IBSS_MODE ||
+		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
+		    adapter->device_mode == QDF_SAP_MODE ||
+		    adapter->device_mode == QDF_P2P_GO_MODE) {
+			wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
+					adapter->session_id, INVALID_SCAN_ID,
+					true);
+		}
+	}
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
+ * adapters
+ * @hdd_ctx: The HDD context containing the adapters to operate on
+ *
+ * return: QDF_STATUS_SUCCESS
+ */
+static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+	int err;
+
+	hdd_enter();
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter->device_mode == QDF_STA_MODE ||
+		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
+		    adapter->device_mode == QDF_IBSS_MODE ||
+		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
+		    adapter->device_mode == QDF_SAP_MODE ||
+		    adapter->device_mode == QDF_P2P_GO_MODE) {
+			err = wlan_hdd_sched_scan_stop(adapter->dev);
+			if (err)
+				hdd_err("Unable to stop scheduled scan");
+		}
+	}
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_NS_OFFLOAD
+/**
+ * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Unregister for IPv6 address change notifications.
+ *
+ * Return: None
+ */
+static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
+{
+	unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
+}
+
+/**
+ * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Register for IPv6 address change notifications.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
+{
+	int ret;
+
+	hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
+	ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
+	if (ret) {
+		hdd_err("Failed to register IPv6 notifier: %d", ret);
+		goto out;
+	}
+
+	hdd_debug("Registered IPv6 notifier");
+out:
+	return ret;
+}
+#else
+/**
+ * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Unregister for IPv6 address change notifications.
+ *
+ * Return: None
+ */
+static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
+{
+}
+
+/**
+ * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Register for IPv6 address change notifications.
+ *
+ * Return: None
+ */
+static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+#endif
+
+void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool status)
+{
+	qdf_mutex_acquire(&adapter->disconnection_status_lock);
+	adapter->disconnection_in_progress = status;
+	qdf_mutex_release(&adapter->disconnection_status_lock);
+	hdd_debug("setting disconnection status: %d", status);
+}
+
+/**
+ * hdd_register_notifiers - Register netdev notifiers.
+ * @hdd_ctx: HDD context
+ *
+ * Register netdev notifiers like IPv4 and IPv6.
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
+{
+	int ret;
+
+	ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
+	if (ret)
+		goto out;
+
+	hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
+	ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
+	if (ret) {
+		hdd_err("Failed to register IPv4 notifier: %d", ret);
+		goto unregister_ip6_notifier;
+	}
+
+	ret = hdd_nud_register_netevent_notifier(hdd_ctx);
+	if (ret) {
+		hdd_err("Failed to register netevent notifier: %d",
+			ret);
+		goto unregister_inetaddr_notifier;
+	}
+	return 0;
+
+unregister_inetaddr_notifier:
+	unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
+unregister_ip6_notifier:
+	hdd_wlan_unregister_ip6_notifier(hdd_ctx);
+out:
+	return ret;
+
+}
+
+/**
+ * hdd_unregister_notifiers - Unregister netdev notifiers.
+ * @hdd_ctx: HDD context
+ *
+ * Unregister netdev notifiers like IPv4 and IPv6.
+ *
+ * Return: None.
+ */
+void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
+{
+	hdd_nud_unregister_netevent_notifier(hdd_ctx);
+	hdd_wlan_unregister_ip6_notifier(hdd_ctx);
+
+	unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
+}
+
+/**
+ * hdd_exit_netlink_services - Exit netlink services
+ * @hdd_ctx: HDD context
+ *
+ * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
+ * nl service.
+ *
+ * Return: None.
+ */
+static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
+{
+	spectral_scan_deactivate_service();
+	cnss_diag_deactivate_service();
+	hdd_close_cesium_nl_sock();
+	ptt_sock_deactivate_svc();
+	hdd_deactivate_wifi_pos();
+
+	nl_srv_exit();
+}
+
+/**
+ * hdd_init_netlink_services- Init netlink services
+ * @hdd_ctx: HDD context
+ *
+ * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
+ * nl service.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
+{
+	int ret;
+
+	ret = wlan_hdd_nl_init(hdd_ctx);
+	if (ret) {
+		hdd_err("nl_srv_init failed: %d", ret);
+		goto out;
+	}
+	cds_set_radio_index(hdd_ctx->radio_index);
+
+	ret = hdd_activate_wifi_pos(hdd_ctx);
+	if (ret) {
+		hdd_err("hdd_activate_wifi_pos failed: %d", ret);
+		goto err_nl_srv;
+	}
+
+	ptt_sock_activate_svc();
+
+	ret = hdd_open_cesium_nl_sock();
+	if (ret)
+		hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
+
+	ret = cnss_diag_activate_service();
+	if (ret) {
+		hdd_err("cnss_diag_activate_service failed: %d", ret);
+		goto err_close_cesium;
+	}
+
+	spectral_scan_activate_service();
+
+	return 0;
+
+err_close_cesium:
+	hdd_close_cesium_nl_sock();
+	ptt_sock_deactivate_svc();
+	hdd_deactivate_wifi_pos();
+err_nl_srv:
+	nl_srv_exit();
+out:
+	return ret;
+}
+
+/**
+ * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
+ * @hdd_ctx:	HDD context.
+ *
+ * Destroy RX wakelock.
+ *
+ * Return: None.
+ */
+static void hdd_rx_wake_lock_destroy(struct hdd_context *hdd_ctx)
+{
+	qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
+}
+
+/**
+ * hdd_rx_wake_lock_create() - Create RX wakelock
+ * @hdd_ctx:	HDD context.
+ *
+ * Create RX wakelock.
+ *
+ * Return: None.
+ */
+static void hdd_rx_wake_lock_create(struct hdd_context *hdd_ctx)
+{
+	qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
+}
+
+/**
+ * hdd_context_deinit() - Deinitialize HDD context
+ * @hdd_ctx:    HDD context.
+ *
+ * Deinitialize HDD context along with all the feature specific contexts but
+ * do not free hdd context itself. Caller of this API is supposed to free
+ * HDD context.
+ *
+ * return: 0 on success and errno on failure.
+ */
+static int hdd_context_deinit(struct hdd_context *hdd_ctx)
+{
+	qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
+
+	wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
+
+	hdd_sap_context_destroy(hdd_ctx);
+
+	hdd_rx_wake_lock_destroy(hdd_ctx);
+
+	hdd_scan_context_destroy(hdd_ctx);
+
+	qdf_list_destroy(&hdd_ctx->hdd_adapters);
+
+	return 0;
+}
+
+/**
+ * hdd_context_destroy() - Destroy HDD context
+ * @hdd_ctx:	HDD context to be destroyed.
+ *
+ * Free config and HDD context as well as destroy all the resources.
+ *
+ * Return: None
+ */
+static void hdd_context_destroy(struct hdd_context *hdd_ctx)
+{
+	cds_set_context(QDF_MODULE_ID_HDD, NULL);
+
+	wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
+
+	hdd_context_deinit(hdd_ctx);
+
+	hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
+
+	qdf_mem_free(hdd_ctx->config);
+	hdd_ctx->config = NULL;
+
+	cfg_release();
+
+	wiphy_free(hdd_ctx->wiphy);
+}
+
+/**
+ * wlan_destroy_bug_report_lock() - Destroy bug report lock
+ *
+ * This function is used to destroy bug report lock
+ *
+ * Return: None
+ */
+static void wlan_destroy_bug_report_lock(void)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		hdd_err("cds context is NULL");
+		return;
+	}
+
+	qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
+}
+
+#ifdef DISABLE_CHANNEL_LIST
+static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
+{
+	qdf_mutex_destroy(&hdd_ctx->cache_channel_lock);
+}
+#else
+static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
+{
+}
+#endif
+
+void hdd_wlan_exit(struct hdd_context *hdd_ctx)
+{
+	struct wiphy *wiphy = hdd_ctx->wiphy;
+	int driver_status;
+
+	hdd_enter();
+
+	hdd_psoc_idle_timer_stop(hdd_ctx);
+
+	hdd_unregister_notifiers(hdd_ctx);
+
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+	if (QDF_TIMER_STATE_RUNNING ==
+	    qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
+		qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
+	}
+
+	if (!QDF_IS_STATUS_SUCCESS
+		    (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
+		hdd_err("Cannot deallocate ACS Skip timer");
+	}
+	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
+	qdf_mem_free(hdd_ctx->last_acs_channel_list);
+	hdd_ctx->last_acs_channel_list = NULL;
+	hdd_ctx->num_of_channels = 0;
+	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
+#endif
+
+	mutex_lock(&hdd_ctx->iface_change_lock);
+	driver_status = hdd_ctx->driver_status;
+	mutex_unlock(&hdd_ctx->iface_change_lock);
+
+	/*
+	 * Powersave Offload Case
+	 * Disable Idle Power Save Mode
+	 */
+	hdd_set_idle_ps_config(hdd_ctx, false);
+	/* clear the scan queue in all the scenarios */
+	wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
+
+	if (driver_status != DRIVER_MODULES_CLOSED) {
+		hdd_unregister_wext_all_adapters(hdd_ctx);
+		/*
+		 * Cancel any outstanding scan requests.  We are about to close
+		 * all of our adapters, but an adapter structure is what SME
+		 * passes back to our callback function.  Hence if there
+		 * are any outstanding scan requests then there is a
+		 * race condition between when the adapter is closed and
+		 * when the callback is invoked.  We try to resolve that
+		 * race condition here by canceling any outstanding scans
+		 * before we close the adapters.
+		 * Note that the scans may be cancelled in an asynchronous
+		 * manner, so ideally there needs to be some kind of
+		 * synchronization.  Rather than introduce a new
+		 * synchronization here, we will utilize the fact that we are
+		 * about to Request Full Power, and since that is synchronized,
+		 * the expectation is that by the time Request Full Power has
+		 * completed, all scans will be cancelled
+		 */
+		hdd_abort_mac_scan_all_adapters(hdd_ctx);
+		hdd_abort_sched_scan_all_adapters(hdd_ctx);
+		hdd_stop_all_adapters(hdd_ctx);
+		hdd_deinit_all_adapters(hdd_ctx, false);
+	}
+
+	unregister_reboot_notifier(&system_reboot_notifier);
+	unregister_netdevice_notifier(&hdd_netdev_notifier);
+
+	qdf_dp_trace_deinit();
+
+	hdd_wlan_stop_modules(hdd_ctx, false);
+
+	hdd_bus_bandwidth_deinit(hdd_ctx);
+	hdd_driver_memdump_deinit();
+
+	qdf_nbuf_deinit_replenish_timer();
+
+	if (QDF_GLOBAL_MONITOR_MODE ==  hdd_get_conparam()) {
+		hdd_info("Release wakelock for monitor mode!");
+		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
+				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
+	}
+
+	qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
+	qdf_spinlock_destroy(&hdd_ctx->sta_update_info_lock);
+	qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
+	wlan_hdd_cache_chann_mutex_destroy(hdd_ctx);
+
+	osif_request_manager_deinit();
+
+	hdd_close_all_adapters(hdd_ctx, false);
+
+	wlansap_global_deinit();
+	/*
+	 * If there is re_init failure wiphy would have already de-registered
+	 * check the wiphy status before un-registering again
+	 */
+	if (wiphy && wiphy->registered) {
+		wiphy_unregister(wiphy);
+		wlan_hdd_cfg80211_deinit(wiphy);
+		hdd_lpass_notify_stop(hdd_ctx);
+	}
+
+	hdd_exit_netlink_services(hdd_ctx);
+	mutex_destroy(&hdd_ctx->iface_change_lock);
+#ifdef FEATURE_WLAN_CH_AVOID
+	mutex_destroy(&hdd_ctx->avoid_freq_lock);
+#endif
+
+	hdd_context_destroy(hdd_ctx);
+}
+
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+/**
+ * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
+ * @data: pointer to struct hdd_context
+ *
+ * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
+ * Then new ACS request will do a fresh scan without reusing the cached
+ * scan information.
+ *
+ * Return: void
+ */
+static void hdd_skip_acs_scan_timer_handler(void *data)
+{
+	struct hdd_context *hdd_ctx = (struct hdd_context *) data;
+	mac_handle_t mac_handle;
+
+	hdd_debug("ACS Scan result expired. Reset ACS scan skip");
+	hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
+	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
+	qdf_mem_free(hdd_ctx->last_acs_channel_list);
+	hdd_ctx->last_acs_channel_list = NULL;
+	hdd_ctx->num_of_channels = 0;
+	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!mac_handle)
+		return;
+	sme_scan_flush_result(mac_handle);
+}
+#endif
+
+#ifdef QCA_HT_2040_COEX
+int hdd_wlan_set_ht2040_mode(struct hdd_adapter *adapter, uint16_t sta_id,
+			     struct qdf_mac_addr sta_mac, int channel_type)
+{
+	int status;
+	QDF_STATUS qdf_status;
+	struct hdd_context *hdd_ctx;
+	mac_handle_t mac_handle;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!mac_handle)
+		return -EINVAL;
+
+	qdf_status = sme_notify_ht2040_mode(mac_handle, sta_id, sta_mac,
+					    adapter->session_id, channel_type);
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		hdd_err("Fail to send notification with ht2040 mode");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif
+
+/**
+ * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
+ * @state: state
+ *
+ * This function notifies FW with modem power status
+ *
+ * Return: 0 if successful, error number otherwise
+ */
+int hdd_wlan_notify_modem_power_state(int state)
+{
+	int status;
+	QDF_STATUS qdf_status;
+	struct hdd_context *hdd_ctx;
+	mac_handle_t mac_handle;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!mac_handle)
+		return -EINVAL;
+
+	qdf_status = sme_notify_modem_power_state(mac_handle, state);
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		hdd_err("Fail to send notification with modem power state %d",
+		       state);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ *
+ * hdd_post_cds_enable_config() - HDD post cds start config helper
+ * @adapter - Pointer to the HDD
+ *
+ * Return: None
+ */
+QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS qdf_ret_status;
+
+	/*
+	 * Send ready indication to the HDD.  This will kick off the MAC
+	 * into a 'running' state and should kick off an initial scan.
+	 */
+	qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
+		hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
+			qdf_ret_status, qdf_ret_status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC)
+			return adapter;
+	}
+
+	return NULL;
+}
+
+/* wake lock APIs for HDD */
+void hdd_prevent_suspend(uint32_t reason)
+{
+	qdf_wake_lock_acquire(&wlan_wake_lock, reason);
+}
+
+void hdd_allow_suspend(uint32_t reason)
+{
+	qdf_wake_lock_release(&wlan_wake_lock, reason);
+}
+
+void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
+{
+	cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
+	qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
+}
+
+/* Initialize channel list in sme based on the country code */
+QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
+{
+	return sme_init_chan_list(hdd_ctx->mac_handle,
+				  hdd_ctx->reg.alpha2,
+				  hdd_ctx->reg.cc_src);
+}
+
+/**
+ * hdd_is_5g_supported() - check if hardware supports 5GHz
+ * @hdd_ctx:	Pointer to the hdd context
+ *
+ * HDD function to know if hardware supports 5GHz
+ *
+ * Return:  true if hardware supports 5GHz
+ */
+bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
+{
+	if (!hdd_ctx)
+		return true;
+
+	if (hdd_ctx->curr_band != BAND_2G)
+		return true;
+	else
+		return false;
+}
+
+static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
+{
+	struct wiphy *wiphy;
+	int ret_val;
+
+	wiphy = hdd_ctx->wiphy;
+
+	/*
+	 * The channel information in
+	 * wiphy needs to be initialized before wiphy registration
+	 */
+	ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
+	if (ret_val) {
+		hdd_err("regulatory init failed");
+		return ret_val;
+	}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
+	wiphy->wowlan = &wowlan_support_reg_init;
+#else
+	wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
+			      WIPHY_WOWLAN_MAGIC_PKT |
+			      WIPHY_WOWLAN_DISCONNECT |
+			      WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+			      WIPHY_WOWLAN_GTK_REKEY_FAILURE |
+			      WIPHY_WOWLAN_EAP_IDENTITY_REQ |
+			      WIPHY_WOWLAN_4WAY_HANDSHAKE |
+			      WIPHY_WOWLAN_RFKILL_RELEASE;
+
+	wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
+				    WOW_MAX_FILTERS_PER_LIST);
+	wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
+	wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
+#endif
+	if (hdd_ctx->obss_scan_offload) {
+		hdd_debug("wmi_service_obss_scan supported");
+	} else if (hdd_ctx->config->nChannelBondingMode24GHz) {
+		hdd_debug("enable wpa_supp obss_scan");
+		wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN;
+	}
+
+	/* registration of wiphy dev with cfg80211 */
+	ret_val = wlan_hdd_cfg80211_register(wiphy);
+	if (0 > ret_val) {
+		hdd_err("wiphy registration failed");
+		return ret_val;
+	}
+
+	/* Check the kernel version for upstream commit aced43ce780dc5 that
+	 * has support for processing user cell_base hints when wiphy is
+	 * self managed or check the backport flag for the same.
+	 */
+#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED ||	\
+		(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
+	hdd_send_wiphy_regd_sync_event(hdd_ctx);
+#endif
+
+	pld_increment_driver_load_cnt(hdd_ctx->parent_dev);
+
+	return ret_val;
+}
+
+#ifdef MSM_PLATFORM
+/**
+ * hdd_display_periodic_stats() - Function to display periodic stats
+ * @hdd_ctx - handle to hdd context
+ * @bool data_in_interval - true, if data detected in bw time interval
+ *
+ * The periodicity is determined by hdd_ctx->config->periodic_stats_disp_time.
+ * Stats show up in wlan driver logs.
+ *
+ * Returns: None
+ */
+static void hdd_display_periodic_stats(struct hdd_context *hdd_ctx,
+				       bool data_in_interval)
+{
+	static uint32_t counter;
+	static bool data_in_time_period;
+	ol_txrx_pdev_handle pdev;
+
+	if (hdd_ctx->config->periodic_stats_disp_time == 0)
+		return;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		hdd_err("pdev is NULL");
+		return;
+	}
+
+	counter++;
+	if (data_in_interval)
+		data_in_time_period = data_in_interval;
+
+	if (counter * hdd_ctx->config->bus_bw_compute_interval >=
+		hdd_ctx->config->periodic_stats_disp_time * 1000) {
+		if (data_in_time_period) {
+			wlan_hdd_display_txrx_stats(hdd_ctx);
+			dp_txrx_dump_stats(cds_get_context(QDF_MODULE_ID_SOC));
+			cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
+					  CDP_RX_RING_STATS,
+					  QDF_STATS_VERBOSITY_LEVEL_LOW);
+			cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
+					  CDP_TXRX_PATH_STATS,
+					  QDF_STATS_VERBOSITY_LEVEL_LOW);
+			wlan_hdd_display_netif_queue_history
+				(hdd_ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
+			qdf_dp_trace_dump_stats();
+		}
+		counter = 0;
+		data_in_time_period = false;
+	}
+}
+
+/**
+ * hdd_clear_rps_cpu_mask - clear RPS CPU mask for interfaces
+ * @hdd_ctx: pointer to struct hdd_context
+ *
+ * Return: none
+ */
+static void hdd_clear_rps_cpu_mask(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter)
+		hdd_send_rps_disable_ind(adapter);
+}
+
+/**
+ * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
+ * @hdd_ctx - handle to hdd context
+ * @tx_packets - transmit packet count
+ * @rx_packets - receive packet count
+ *
+ * The function controls the bus bandwidth and dynamic control of
+ * tcp delayed ack configuration
+ *
+ * Returns: None
+ */
+
+static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
+					  const uint64_t tx_packets,
+					  const uint64_t rx_packets)
+{
+	u64 total_pkts = tx_packets + rx_packets;
+	uint64_t temp_tx = 0, avg_rx = 0;
+	uint64_t no_rx_offload_pkts = 0, avg_no_rx_offload_pkts = 0;
+	uint64_t rx_offload_pkts = 0, avg_rx_offload_pkts = 0;
+	enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_NONE;
+	static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
+	enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
+	uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
+	uint16_t index = 0;
+	bool vote_level_change = false;
+	bool rx_level_change = false;
+	bool tx_level_change = false;
+	bool rxthread_high_tput_req = false;
+	bool dptrace_high_tput_req;
+
+	if (total_pkts > hdd_ctx->config->bus_bw_high_threshold)
+		next_vote_level = PLD_BUS_WIDTH_HIGH;
+	else if (total_pkts > hdd_ctx->config->bus_bw_medium_threshold)
+		next_vote_level = PLD_BUS_WIDTH_MEDIUM;
+	else if (total_pkts > hdd_ctx->config->bus_bw_low_threshold)
+		next_vote_level = PLD_BUS_WIDTH_LOW;
+	else
+		next_vote_level = PLD_BUS_WIDTH_NONE;
+
+	dptrace_high_tput_req =
+			next_vote_level > PLD_BUS_WIDTH_NONE ? true : false;
+
+	if (hdd_ctx->cur_vote_level != next_vote_level) {
+		hdd_debug("trigger level %d, tx_packets: %lld, rx_packets: %lld",
+			 next_vote_level, tx_packets, rx_packets);
+		hdd_ctx->cur_vote_level = next_vote_level;
+		vote_level_change = true;
+		pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level);
+		if ((next_vote_level == PLD_BUS_WIDTH_LOW) ||
+		    (next_vote_level == PLD_BUS_WIDTH_NONE)) {
+			if (hdd_ctx->hbw_requested) {
+				pld_remove_pm_qos(hdd_ctx->parent_dev);
+				hdd_ctx->hbw_requested = false;
+			}
+			if (hdd_ctx->dynamic_rps)
+				hdd_clear_rps_cpu_mask(hdd_ctx);
+		} else {
+			if (!hdd_ctx->hbw_requested) {
+				pld_request_pm_qos(hdd_ctx->parent_dev, 1);
+				hdd_ctx->hbw_requested = true;
+			}
+			if (hdd_ctx->dynamic_rps)
+				hdd_set_rps_cpu_mask(hdd_ctx);
+		}
+
+		if (hdd_ctx->config->napi_cpu_affinity_mask)
+			hdd_napi_apply_throughput_policy(hdd_ctx,
+							 tx_packets,
+							 rx_packets);
+
+		if (rx_packets < hdd_ctx->config->bus_bw_low_threshold)
+			hdd_disable_rx_ol_for_low_tput(hdd_ctx, true);
+		else
+			hdd_disable_rx_ol_for_low_tput(hdd_ctx, false);
+	}
+
+	qdf_dp_trace_apply_tput_policy(dptrace_high_tput_req);
+
+	/*
+	 * Includes tcp+udp, if perf core is required for tcp, then
+	 * perf core is also required for udp.
+	 */
+	no_rx_offload_pkts = hdd_ctx->no_rx_offload_pkt_cnt;
+	hdd_ctx->no_rx_offload_pkt_cnt = 0;
+	rx_offload_pkts = rx_packets - no_rx_offload_pkts;
+
+	avg_no_rx_offload_pkts = (no_rx_offload_pkts +
+				  hdd_ctx->prev_no_rx_offload_pkts) / 2;
+	hdd_ctx->prev_no_rx_offload_pkts = no_rx_offload_pkts;
+
+	avg_rx_offload_pkts = (rx_offload_pkts +
+			       hdd_ctx->prev_rx_offload_pkts) / 2;
+	hdd_ctx->prev_rx_offload_pkts = rx_offload_pkts;
+
+	avg_rx = avg_no_rx_offload_pkts + avg_rx_offload_pkts;
+	/*
+	 * Takes care to set Rx_thread affinity for below case
+	 * 1)LRO/GRO not supported ROME case
+	 * 2)when rx_ol is disabled in cases like concurrency etc
+	 * 3)For UDP cases
+	 */
+	if (avg_no_rx_offload_pkts >
+			hdd_ctx->config->bus_bw_high_threshold)
+		rxthread_high_tput_req = true;
+	else
+		rxthread_high_tput_req = false;
+
+	if (cds_sched_handle_throughput_req(rxthread_high_tput_req))
+		hdd_warn("Rx thread high_tput(%d) affinity request failed",
+			 rxthread_high_tput_req);
+
+	/* fine-tuning parameters for RX Flows */
+	if (avg_rx > hdd_ctx->config->tcp_delack_thres_high) {
+		if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
+		   (++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
+			next_rx_level = WLAN_SVC_TP_HIGH;
+		}
+	} else {
+		hdd_ctx->rx_high_ind_cnt = 0;
+		next_rx_level = WLAN_SVC_TP_LOW;
+	}
+
+	if (hdd_ctx->cur_rx_level != next_rx_level) {
+		struct wlan_rx_tp_data rx_tp_data = {0};
+
+		hdd_debug("TCP DELACK trigger level %d, average_rx: %llu",
+			  next_rx_level, avg_rx);
+		hdd_ctx->cur_rx_level = next_rx_level;
+		rx_level_change = true;
+		/* Send throughput indication only if it is enabled.
+		 * Disabling tcp_del_ack will revert the tcp stack behavior
+		 * to default delayed ack. Note that this will disable the
+		 * dynamic delayed ack mechanism across the system
+		 */
+		if (hdd_ctx->en_tcp_delack_no_lro)
+			rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
+
+		if (hdd_ctx->config->enable_tcp_adv_win_scale)
+			rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
+
+		rx_tp_data.level = next_rx_level;
+		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+				WLAN_SVC_WLAN_TP_IND, &rx_tp_data,
+				sizeof(rx_tp_data));
+	}
+
+	/* fine-tuning parameters for TX Flows */
+	temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
+	hdd_ctx->prev_tx = tx_packets;
+	if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
+		next_tx_level = WLAN_SVC_TP_HIGH;
+	else
+		next_tx_level = WLAN_SVC_TP_LOW;
+
+	if ((hdd_ctx->config->enable_tcp_limit_output) &&
+	    (hdd_ctx->cur_tx_level != next_tx_level)) {
+		hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
+				next_tx_level, temp_tx);
+		hdd_ctx->cur_tx_level = next_tx_level;
+		tx_level_change = true;
+		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+				WLAN_SVC_WLAN_TP_TX_IND,
+				&next_tx_level,
+				sizeof(next_tx_level));
+	}
+
+	index = hdd_ctx->hdd_txrx_hist_idx;
+	if (vote_level_change || tx_level_change || rx_level_change) {
+		hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level;
+		hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level;
+		hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level;
+		hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets;
+		hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets;
+		hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp();
+		hdd_ctx->hdd_txrx_hist_idx++;
+		hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
+	}
+
+	hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false);
+}
+
+#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
+static void __hdd_bus_bw_work_handler(struct work_struct *work)
+{
+	struct hdd_context *hdd_ctx = container_of(work, struct hdd_context,
+					bus_bw_work);
+	struct hdd_adapter *adapter = NULL, *con_sap_adapter = NULL;
+	uint64_t tx_packets = 0, rx_packets = 0;
+	uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
+	uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
+	uint64_t total_tx = 0, total_rx = 0;
+	A_STATUS ret;
+	bool connected = false;
+	uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	if (hdd_ctx->is_wiphy_suspended)
+		goto restart_timer;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		/*
+		 * Validate magic so we don't end up accessing
+		 * an invalid adapter.
+		 */
+		if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
+			continue;
+
+		if ((adapter->device_mode == QDF_STA_MODE ||
+		     adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
+		    WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
+		    != eConnectionState_Associated) {
+
+			continue;
+		}
+
+		if ((adapter->device_mode == QDF_SAP_MODE ||
+		     adapter->device_mode == QDF_P2P_GO_MODE) &&
+		    WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active == false) {
+
+			continue;
+		}
+
+		tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
+					      adapter->prev_tx_packets);
+		rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
+					      adapter->prev_rx_packets);
+
+		if (adapter->device_mode == QDF_SAP_MODE ||
+				adapter->device_mode == QDF_P2P_GO_MODE ||
+				adapter->device_mode == QDF_IBSS_MODE) {
+
+			ret = cdp_get_intra_bss_fwd_pkts_count(
+				cds_get_context(QDF_MODULE_ID_SOC),
+				adapter->session_id,
+				&fwd_tx_packets, &fwd_rx_packets);
+			if (ret == A_OK) {
+				fwd_tx_packets_diff += HDD_BW_GET_DIFF(
+					fwd_tx_packets,
+					adapter->prev_fwd_tx_packets);
+				fwd_rx_packets_diff += HDD_BW_GET_DIFF(
+					fwd_tx_packets,
+					adapter->prev_fwd_rx_packets);
+			}
+		}
+
+		if (adapter->device_mode == QDF_SAP_MODE)
+			con_sap_adapter = adapter;
+
+		total_rx += adapter->stats.rx_packets;
+		total_tx += adapter->stats.tx_packets;
+
+		spin_lock_bh(&hdd_ctx->bus_bw_lock);
+		adapter->prev_tx_packets = adapter->stats.tx_packets;
+		adapter->prev_rx_packets = adapter->stats.rx_packets;
+		adapter->prev_fwd_tx_packets = fwd_tx_packets;
+		adapter->prev_fwd_rx_packets = fwd_rx_packets;
+		spin_unlock_bh(&hdd_ctx->bus_bw_lock);
+		connected = true;
+	}
+
+	if (!connected) {
+		hdd_err("bus bandwidth timer running in disconnected state");
+		return;
+	}
+
+	/* add intra bss forwarded tx and rx packets */
+	tx_packets += fwd_tx_packets_diff;
+	rx_packets += fwd_rx_packets_diff;
+
+	if (ucfg_ipa_is_fw_wdi_activated(hdd_ctx->pdev)) {
+		ucfg_ipa_uc_stat_query(hdd_ctx->pdev, &ipa_tx_packets,
+				       &ipa_rx_packets);
+		tx_packets += (uint64_t)ipa_tx_packets;
+		rx_packets += (uint64_t)ipa_rx_packets;
+
+		if (con_sap_adapter) {
+			con_sap_adapter->stats.tx_packets += ipa_tx_packets;
+			con_sap_adapter->stats.rx_packets += ipa_rx_packets;
+		}
+
+		ucfg_ipa_set_perf_level(hdd_ctx->pdev, tx_packets, rx_packets);
+		ucfg_ipa_uc_stat_request(hdd_ctx->pdev, 2);
+	}
+
+	hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);
+
+restart_timer:
+	/* ensure periodic timer should still be running before restarting it */
+	qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
+	if (hdd_ctx->bus_bw_timer_running)
+		qdf_timer_mod(&hdd_ctx->bus_bw_timer,
+			      hdd_ctx->config->bus_bw_compute_interval);
+	qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
+}
+
+static void hdd_bus_bw_work_handler(struct work_struct *work)
+{
+	cds_ssr_protect(__func__);
+	__hdd_bus_bw_work_handler(work);
+	cds_ssr_unprotect(__func__);
+}
+
+/**
+ * __hdd_bus_bw_cbk() - Bus bandwidth data structure callback.
+ * @arg: Argument of timer function
+ *
+ * Schedule a workqueue in this function where all the processing is done.
+ *
+ * Return: None.
+ */
+static void __hdd_bus_bw_cbk(void *arg)
+{
+	struct hdd_context *hdd_ctx = (struct hdd_context *) arg;
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	schedule_work(&hdd_ctx->bus_bw_work);
+}
+
+/**
+ * hdd_bus_bw_cbk() - Wrapper for bus bw callback for SSR protection.
+ * @arg: Argument of timer function
+ *
+ * Return: None.
+ */
+static void hdd_bus_bw_cbk(void *arg)
+{
+	cds_ssr_protect(__func__);
+	__hdd_bus_bw_cbk(arg);
+	cds_ssr_unprotect(__func__);
+}
+
+int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
+{
+	hdd_enter();
+
+	spin_lock_init(&hdd_ctx->bus_bw_lock);
+	INIT_WORK(&hdd_ctx->bus_bw_work, hdd_bus_bw_work_handler);
+	hdd_ctx->bus_bw_timer_running = false;
+	qdf_spinlock_create(&hdd_ctx->bus_bw_timer_lock);
+	qdf_timer_init(NULL, &hdd_ctx->bus_bw_timer, hdd_bus_bw_cbk,
+		       (void *)hdd_ctx, QDF_TIMER_TYPE_SW);
+
+	hdd_exit();
+
+	return 0;
+}
+
+void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx)
+{
+	hdd_enter();
+
+	QDF_BUG(!hdd_ctx->bus_bw_timer_running);
+
+	qdf_timer_free(&hdd_ctx->bus_bw_timer);
+	qdf_spinlock_destroy(&hdd_ctx->bus_bw_timer_lock);
+
+	hdd_exit();
+}
+
+#endif /* MSM_PLATFORM */
+
+/**
+ * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
+ * @hdd_ctx: hdd context
+ *
+ * Return: 0 for success or error code
+ */
+static int wlan_hdd_init_tx_rx_histogram(struct hdd_context *hdd_ctx)
+{
+	hdd_ctx->hdd_txrx_hist = qdf_mem_malloc(
+		(sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
+	if (!hdd_ctx->hdd_txrx_hist)
+		return -ENOMEM;
+	return 0;
+}
+
+/**
+ * wlan_hdd_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx)
+{
+	if (!hdd_ctx || hdd_ctx->hdd_txrx_hist == NULL)
+		return;
+
+	qdf_mem_free(hdd_ctx->hdd_txrx_hist);
+	hdd_ctx->hdd_txrx_hist = NULL;
+}
+
+static uint8_t *convert_level_to_string(uint32_t level)
+{
+	switch (level) {
+	/* initialize the wlan sub system */
+	case WLAN_SVC_TP_NONE:
+		return "NONE";
+	case WLAN_SVC_TP_LOW:
+		return "LOW";
+	case WLAN_SVC_TP_MEDIUM:
+		return "MED";
+	case WLAN_SVC_TP_HIGH:
+		return "HIGH";
+	default:
+		return "INVAL";
+	}
+}
+
+
+/**
+ * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
+{
+	int i;
+
+#ifdef MSM_PLATFORM
+	hdd_nofl_info("BW compute Interval: %dms",
+		      hdd_ctx->config->bus_bw_compute_interval);
+	hdd_nofl_info("BW High TH: %d BW Med TH: %d BW Low TH: %d",
+		      hdd_ctx->config->bus_bw_high_threshold,
+		      hdd_ctx->config->bus_bw_medium_threshold,
+		      hdd_ctx->config->bus_bw_low_threshold);
+	hdd_nofl_info("Enable TCP DEL ACK: %d",
+		      hdd_ctx->en_tcp_delack_no_lro);
+	hdd_nofl_info("TCP DEL High TH: %d TCP DEL Low TH: %d",
+		      hdd_ctx->config->tcp_delack_thres_high,
+		      hdd_ctx->config->tcp_delack_thres_low);
+	hdd_nofl_info("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_limit)",
+		      hdd_ctx->config->tcp_tx_high_tput_thres);
+#endif
+
+	hdd_nofl_info("Total entries: %d Current index: %d",
+		      NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
+
+	hdd_nofl_info("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level");
+
+	for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
+		/* using hdd_log to avoid printing function name */
+		if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
+			hdd_nofl_info("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s",
+				      i, hdd_ctx->hdd_txrx_hist[i].qtime,
+				      hdd_ctx->hdd_txrx_hist[i].interval_rx,
+				      hdd_ctx->hdd_txrx_hist[i].interval_tx,
+				      convert_level_to_string(
+					hdd_ctx->hdd_txrx_hist[i].
+						next_vote_level),
+				      convert_level_to_string(
+					hdd_ctx->hdd_txrx_hist[i].
+						next_rx_level),
+				      convert_level_to_string(
+					hdd_ctx->hdd_txrx_hist[i].
+						next_tx_level));
+	}
+}
+
+/**
+ * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
+{
+	hdd_ctx->hdd_txrx_hist_idx = 0;
+	qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
+		(sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
+}
+
+/* length of the netif queue log needed per adapter */
+#define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
+
+/**
+ *
+ * hdd_display_netif_queue_history_compact() - display compact netifq history
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+static void
+hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
+{
+	int adapter_num = 0;
+	int i;
+	int bytes_written;
+	u32 tbytes;
+	qdf_time_t total, pause, unpause, curr_time, delta;
+	char temp_str[20 * WLAN_REASON_TYPE_MAX];
+	char *comb_log_str;
+	uint32_t comb_log_str_size;
+	struct hdd_adapter *adapter = NULL;
+
+	comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * CSR_ROAM_SESSION_MAX) + 1;
+	comb_log_str = qdf_mem_malloc(comb_log_str_size);
+	if (!comb_log_str)
+		return;
+
+	bytes_written = 0;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		curr_time = qdf_system_ticks();
+		total = curr_time - adapter->start_time;
+		delta = curr_time - adapter->last_time;
+
+		if (adapter->pause_map) {
+			pause = adapter->total_pause_time + delta;
+			unpause = adapter->total_unpause_time;
+		} else {
+			unpause = adapter->total_unpause_time + delta;
+			pause = adapter->total_pause_time;
+		}
+
+		tbytes = 0;
+		qdf_mem_set(temp_str, 0, sizeof(temp_str));
+		for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
+			if (adapter->queue_oper_stats[i].pause_count == 0)
+				continue;
+			tbytes +=
+				snprintf(
+					&temp_str[tbytes],
+					(tbytes >= sizeof(temp_str) ?
+					0 : sizeof(temp_str) - tbytes),
+					"%d(%d,%d) ",
+					i,
+					adapter->queue_oper_stats[i].
+								pause_count,
+					adapter->queue_oper_stats[i].
+								unpause_count);
+		}
+		if (tbytes >= sizeof(temp_str))
+			hdd_warn("log truncated");
+
+		bytes_written += snprintf(&comb_log_str[bytes_written],
+			bytes_written >= comb_log_str_size ? 0 :
+					comb_log_str_size - bytes_written,
+			"[%d %d] (%d) %u/%ums %s|",
+			adapter->session_id, adapter->device_mode,
+			adapter->pause_map,
+			qdf_system_ticks_to_msecs(pause),
+			qdf_system_ticks_to_msecs(total),
+			temp_str);
+
+		adapter_num++;
+	}
+
+	/* using QDF_TRACE to avoid printing function name */
+	QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
+		  "STATS |%s", comb_log_str);
+
+	if (bytes_written >= comb_log_str_size)
+		hdd_warn("log string truncated");
+
+	qdf_mem_free(comb_log_str);
+}
+
+/**
+ * wlan_hdd_display_netif_queue_history() - display netif queue history
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+void
+wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
+				     enum qdf_stats_verbosity_level verb_lvl)
+{
+
+	struct hdd_adapter *adapter = NULL;
+	int i;
+	qdf_time_t total, pause, unpause, curr_time, delta;
+
+	if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
+		hdd_display_netif_queue_history_compact(hdd_ctx);
+		return;
+	}
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		hdd_nofl_info("Netif queue operation statistics:");
+		hdd_nofl_info("Session_id %d device mode %d",
+			      adapter->session_id, adapter->device_mode);
+		hdd_nofl_info("Current pause_map value %x", adapter->pause_map);
+		curr_time = qdf_system_ticks();
+		total = curr_time - adapter->start_time;
+		delta = curr_time - adapter->last_time;
+		if (adapter->pause_map) {
+			pause = adapter->total_pause_time + delta;
+			unpause = adapter->total_unpause_time;
+		} else {
+			unpause = adapter->total_unpause_time + delta;
+			pause = adapter->total_pause_time;
+		}
+		hdd_nofl_info("Total: %ums Pause: %ums Unpause: %ums",
+			      qdf_system_ticks_to_msecs(total),
+			      qdf_system_ticks_to_msecs(pause),
+			      qdf_system_ticks_to_msecs(unpause));
+		hdd_nofl_info("reason_type: pause_cnt: unpause_cnt: pause_time");
+
+		for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
+			qdf_time_t pause_delta = 0;
+
+			if (adapter->pause_map & (1 << i))
+				pause_delta = delta;
+
+			/* using hdd_log to avoid printing function name */
+			hdd_nofl_info("%s: %d: %d: %ums",
+				      hdd_reason_type_to_string(i),
+				      adapter->queue_oper_stats[i].pause_count,
+				      adapter->queue_oper_stats[i].
+					unpause_count,
+				      qdf_system_ticks_to_msecs(
+				      adapter->queue_oper_stats[i].
+					total_pause_time + pause_delta));
+		}
+
+		hdd_nofl_info("Netif queue operation history:");
+		hdd_nofl_info("Total entries: %d current index %d",
+			      WLAN_HDD_MAX_HISTORY_ENTRY,
+			      adapter->history_index);
+
+		hdd_nofl_info("index: time: action_type: reason_type: pause_map");
+
+		for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
+			/* using hdd_log to avoid printing function name */
+			if (adapter->queue_oper_history[i].time == 0)
+				continue;
+			hdd_nofl_info("%d: %u: %s: %s: %x",
+				      i, qdf_system_ticks_to_msecs(
+					adapter->queue_oper_history[i].time),
+				      hdd_action_type_to_string(
+					adapter->queue_oper_history[i].
+						netif_action),
+				      hdd_reason_type_to_string(
+					adapter->queue_oper_history[i].
+						netif_reason),
+				      adapter->queue_oper_history[i].pause_map);
+		}
+	}
+}
+
+/**
+ * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter = NULL;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		qdf_mem_zero(adapter->queue_oper_stats,
+					sizeof(adapter->queue_oper_stats));
+		qdf_mem_zero(adapter->queue_oper_history,
+					sizeof(adapter->queue_oper_history));
+		adapter->history_index = 0;
+		adapter->start_time = adapter->last_time = qdf_system_ticks();
+		adapter->total_pause_time = 0;
+		adapter->total_unpause_time = 0;
+	}
+}
+
+#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
+/**
+ * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
+ * @hdd_ctx: hdd global context
+ *
+ * Return: none
+ */
+static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
+{
+	uint8_t i;
+
+	mutex_init(&hdd_ctx->op_ctx.op_lock);
+	for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
+		hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
+		hdd_ctx->op_ctx.op_table[i].pattern_id = i;
+	}
+}
+#else
+static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_WOW_PULSE
+/**
+ * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
+ * @phddctx: struct hdd_context structure pointer
+ * @enable: enable or disable this behaviour
+ *
+ * Return: int
+ */
+static int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
+{
+	struct wow_pulse_mode wow_pulse_set_info;
+	QDF_STATUS status;
+
+	hdd_debug("wow pulse enable flag is %d", enable);
+
+	if (!ucfg_pmo_is_wow_pulse_enabled(phddctx->psoc))
+		return 0;
+
+	/* prepare the request to send to SME */
+	if (enable == true) {
+		wow_pulse_set_info.wow_pulse_enable = true;
+		wow_pulse_set_info.wow_pulse_pin =
+			ucfg_pmo_get_wow_pulse_pin(phddctx->psoc);
+
+		wow_pulse_set_info.wow_pulse_interval_high =
+		    ucfg_pmo_get_wow_pulse_interval_high(phddctx->psoc);
+
+		wow_pulse_set_info.wow_pulse_interval_low =
+		    ucfg_pmo_get_wow_pulse_interval_low(phddctx->psoc);
+	} else {
+		wow_pulse_set_info.wow_pulse_enable = false;
+		wow_pulse_set_info.wow_pulse_pin = 0;
+		wow_pulse_set_info.wow_pulse_interval_low = 0;
+		wow_pulse_set_info.wow_pulse_interval_high = 0;
+	}
+	hdd_debug("enable %d pin %d low %d high %d",
+		wow_pulse_set_info.wow_pulse_enable,
+		wow_pulse_set_info.wow_pulse_pin,
+		wow_pulse_set_info.wow_pulse_interval_low,
+		wow_pulse_set_info.wow_pulse_interval_high);
+
+	status = sme_set_wow_pulse(&wow_pulse_set_info);
+	if (QDF_STATUS_E_FAILURE == status) {
+		hdd_debug("sme_set_wow_pulse failure!");
+		return -EIO;
+	}
+	hdd_debug("sme_set_wow_pulse success!");
+	return 0;
+}
+#else
+static inline int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
+{
+	return 0;
+}
+#endif
+
+#ifdef WLAN_FEATURE_FASTPATH
+
+/**
+ * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
+ * @hdd_cfg: hdd config
+ * @context: lower layer context
+ *
+ * Return: none
+ */
+void hdd_enable_fastpath(struct hdd_context *hdd_ctx,
+			 void *context)
+{
+	if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH))
+		hif_enable_fastpath(context);
+}
+#endif
+
+#if defined(FEATURE_WLAN_CH_AVOID)
+/**
+ * hdd_set_thermal_level_cb() - set thermal level callback function
+ * @hdd_handle:	opaque handle for the hdd context
+ * @level:	thermal level
+ *
+ * Change IPA data path to SW path when the thermal throttle level greater
+ * than 0, and restore the original data path when throttle level is 0
+ *
+ * Return: none
+ */
+static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+
+	/* Change IPA to SW path when throttle level greater than 0 */
+	if (level > THROTTLE_LEVEL_0)
+		ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true);
+	else
+		/* restore original concurrency mode */
+		ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode);
+}
+
+/**
+ * hdd_get_safe_channel() - Get safe channel from current regulatory
+ * @hdd_ctx: pointer to hdd context
+ * @adapter: pointer to softap adapter
+ *
+ * This function is used to get safe channel from current regulatory valid
+ * channels to restart SAP if failed to get safe channel from PCL.
+ *
+ * Return: Channel number to restart SAP in case of success. In case of any
+ * failure, the channel number returned is zero.
+ */
+static uint8_t
+hdd_get_safe_channel(struct hdd_context *hdd_ctx,
+		     struct hdd_adapter *adapter)
+{
+	struct sir_pcl_list pcl = {0};
+	uint32_t i, j;
+	bool found = false;
+	int ret;
+
+	/* Try for safe channel from all valid channel */
+	pcl.pcl_len = MAX_NUM_CHAN;
+	ret = hdd_get_valid_chan(hdd_ctx, pcl.pcl_list,
+				 &pcl.pcl_len);
+	if (ret) {
+		hdd_err("error %d in getting valid channel list", ret);
+		return INVALID_CHANNEL_ID;
+	}
+
+	for (i = 0; i < pcl.pcl_len; i++) {
+		hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
+		found = false;
+		for (j = 0; j < hdd_ctx->unsafe_channel_count; j++) {
+			if (pcl.pcl_list[i] ==
+					hdd_ctx->unsafe_channel_list[j]) {
+				hdd_debug("unsafe chan:%d", pcl.pcl_list[i]);
+				found = true;
+				break;
+			}
+		}
+
+		if (found)
+			continue;
+
+		if ((pcl.pcl_list[i] >=
+		   adapter->session.ap.sap_config.acs_cfg.start_ch) &&
+		   (pcl.pcl_list[i] <=
+		   adapter->session.ap.sap_config.acs_cfg.end_ch)) {
+			hdd_debug("found safe chan:%d", pcl.pcl_list[i]);
+			return pcl.pcl_list[i];
+		}
+	}
+
+	return INVALID_CHANNEL_ID;
+}
+
+#else
+/**
+ * hdd_set_thermal_level_cb() - set thermal level callback function
+ * @hdd_handle:	opaque handle for the hdd context
+ * @level:	thermal level
+ *
+ * Change IPA data path to SW path when the thermal throttle level greater
+ * than 0, and restore the original data path when throttle level is 0
+ *
+ * Return: none
+ */
+static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
+{
+}
+
+/**
+ * hdd_get_safe_channel() - Get safe channel from current regulatory
+ * @hdd_ctx: pointer to hdd context
+ * @adapter: pointer to softap adapter
+ *
+ * This function is used to get safe channel from current regulatory valid
+ * channels to restart SAP if failed to get safe channel from PCL.
+ *
+ * Return: Channel number to restart SAP in case of success. In case of any
+ * failure, the channel number returned is zero.
+ */
+static uint8_t
+hdd_get_safe_channel(struct hdd_context *hdd_ctx,
+		     struct hdd_adapter *adapter)
+{
+	return 0;
+}
+#endif
+
+/**
+ * hdd_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP
+ * restart
+ * @adapter: AP adapter, which should be checked for NULL
+ *
+ * Get a safe channel to restart SAP. PCL already takes into account the
+ * unsafe channels. So, the PCL is validated with the ACS range to provide
+ * a safe channel for the SAP to restart.
+ *
+ * Return: Channel number to restart SAP in case of success. In case of any
+ * failure, the channel number returned is zero.
+ */
+static uint8_t
+hdd_get_safe_channel_from_pcl_and_acs_range(struct hdd_adapter *adapter)
+{
+	struct sir_pcl_list pcl;
+	QDF_STATUS status;
+	uint32_t i;
+	mac_handle_t mac_handle;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hdd_ctx) {
+		hdd_err("invalid HDD context");
+		return INVALID_CHANNEL_ID;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!mac_handle) {
+		hdd_err("invalid MAC handle");
+		return INVALID_CHANNEL_ID;
+	}
+
+	status = policy_mgr_get_pcl_for_existing_conn(hdd_ctx->psoc,
+			PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len,
+			pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
+			false);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Get PCL failed");
+		return INVALID_CHANNEL_ID;
+	}
+
+	/*
+	 * In some scenarios, like hw dbs disabled, sap+sap case, if operating
+	 * channel is unsafe channel, the pcl may be empty, instead of return,
+	 * try to choose a safe channel from acs range.
+	 */
+	if (!pcl.pcl_len)
+		hdd_debug("pcl length is zero!");
+
+	hdd_debug("start:%d end:%d",
+		adapter->session.ap.sap_config.acs_cfg.start_ch,
+		adapter->session.ap.sap_config.acs_cfg.end_ch);
+
+	/* PCL already takes unsafe channel into account */
+	for (i = 0; i < pcl.pcl_len; i++) {
+		hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
+		if ((pcl.pcl_list[i] >=
+		   adapter->session.ap.sap_config.acs_cfg.start_ch) &&
+		   (pcl.pcl_list[i] <=
+		   adapter->session.ap.sap_config.acs_cfg.end_ch)) {
+			hdd_debug("found PCL safe chan:%d", pcl.pcl_list[i]);
+			return pcl.pcl_list[i];
+		}
+	}
+
+	hdd_debug("no safe channel from PCL found in ACS range");
+
+	return hdd_get_safe_channel(hdd_ctx, adapter);
+}
+
+/**
+ * hdd_switch_sap_channel() - Move SAP to the given channel
+ * @adapter: AP adapter
+ * @channel: Channel
+ * @forced: Force to switch channel, ignore SCC/MCC check
+ *
+ * Moves the SAP interface by invoking the function which
+ * executes the callback to perform channel switch using (E)CSA.
+ *
+ * Return: None
+ */
+void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel,
+			    bool forced)
+{
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	struct hdd_context *hdd_ctx;
+	mac_handle_t mac_handle;
+
+	if (!adapter) {
+		hdd_err("invalid adapter");
+		return;
+	}
+
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+
+	mac_handle = hdd_adapter_get_mac_handle(adapter);
+	if (!mac_handle) {
+		hdd_err("invalid MAC handle");
+		return;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_ap_ctx->sap_config.channel = channel;
+	hdd_ap_ctx->sap_config.ch_params.ch_width = CH_WIDTH_MAX;
+
+	hdd_debug("chan:%d width:%d",
+		channel, hdd_ap_ctx->sap_config.ch_width_orig);
+
+	wlan_reg_set_channel_params(hdd_ctx->pdev,
+				    hdd_ap_ctx->sap_config.channel,
+				    hdd_ap_ctx->sap_config.sec_ch,
+				    &hdd_ap_ctx->sap_config.ch_params);
+
+	policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc,
+		adapter->session_id, channel,
+		hdd_ap_ctx->sap_config.ch_width_orig, forced);
+}
+
+int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
+{
+	struct hdd_external_acs_timer_context *timer_context;
+	int status;
+	QDF_STATUS qdf_status;
+
+	set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
+
+	if (QDF_TIMER_STATE_RUNNING ==
+	    qdf_mc_timer_get_current_state(&adapter->session.
+					ap.vendor_acs_timer)) {
+		qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer);
+	}
+	timer_context = (struct hdd_external_acs_timer_context *)
+			adapter->session.ap.vendor_acs_timer.user_data;
+	timer_context->reason = reason;
+	qdf_status =
+		qdf_mc_timer_start(&adapter->session.ap.vendor_acs_timer,
+				   WLAN_VENDOR_ACS_WAIT_TIME);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		hdd_err("failed to start external acs timer");
+		return -ENOSPC;
+	}
+	/* Update config to application */
+	status = hdd_cfg80211_update_acs_config(adapter, reason);
+	hdd_info("Updated ACS config to nl with reason %d", reason);
+
+	return status;
+}
+
+#if defined(FEATURE_WLAN_CH_AVOID)
+/**
+ * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
+ * @hdd_ctx: hdd context pointer
+ *
+ * hdd_unsafe_channel_restart_sap check all unsafe channel list
+ * and if ACS is enabled, driver will ask userspace to restart the
+ * sap. User space on LTE coex indication restart driver.
+ *
+ * Return - none
+ */
+void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
+{
+	struct hdd_adapter *adapter;
+	uint32_t i;
+	bool found = false;
+	uint8_t restart_chan;
+	bool value;
+	QDF_STATUS status;
+	bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE);
+	bool is_vendor_acs_support =
+		cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
+
+	hdd_for_each_adapter(hdd_ctxt, adapter) {
+		if (!(adapter->device_mode == QDF_SAP_MODE &&
+		    adapter->session.ap.sap_config.acs_cfg.acs_mode)) {
+			hdd_debug("skip device mode:%d acs:%d",
+				  adapter->device_mode,
+				  adapter->session.ap.sap_config.
+				  acs_cfg.acs_mode);
+			continue;
+		}
+
+		found = false;
+		/*
+		 * If STA+SAP is doing SCC & g_sta_sap_scc_on_lte_coex_chan
+		 * is set, no need to move SAP.
+		 */
+		if (policy_mgr_is_sta_sap_scc(hdd_ctxt->psoc,
+			adapter->session.ap.operating_channel) &&
+			hdd_ctxt->config->sta_sap_scc_on_lte_coex_chan)
+			hdd_debug("SAP is allowed on SCC channel, no need to move SAP");
+		else {
+			for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
+				if (adapter->session.ap.operating_channel ==
+					hdd_ctxt->unsafe_channel_list[i]) {
+					found = true;
+					hdd_debug("operating ch:%d is unsafe",
+					adapter->session.ap.operating_channel);
+					break;
+				}
+			}
+		}
+		if (!found) {
+			hdd_debug("ch:%d is safe. no need to change channel",
+				  adapter->session.ap.operating_channel);
+			continue;
+		}
+
+		status = ucfg_mlme_get_acs_support_for_dfs_ltecoex(
+					hdd_ctxt->psoc,
+					&is_acs_support_for_dfs_ltecoex);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("get_acs_support_for_dfs_ltecoex failed,set def");
+
+		status = ucfg_mlme_get_vendor_acs_support(
+					hdd_ctxt->psoc,
+					&is_vendor_acs_support);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("get_vendor_acs_support failed, set default");
+
+		if (is_vendor_acs_support && is_acs_support_for_dfs_ltecoex) {
+			hdd_update_acs_timer_reason(adapter,
+				QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
+			continue;
+		} else
+			restart_chan =
+				hdd_get_safe_channel_from_pcl_and_acs_range(
+					adapter);
+		if (!restart_chan) {
+			hdd_err("fail to restart SAP");
+		} else {
+			/*
+			 * SAP restart due to unsafe channel. While
+			 * restarting the SAP, make sure to clear
+			 * acs_channel, channel to reset to
+			 * 0. Otherwise these settings will override
+			 * the ACS while restart.
+			 */
+			hdd_ctxt->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
+			hdd_debug("sending coex indication");
+			wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
+					WLAN_SVC_LTE_COEX_IND, NULL, 0);
+			ucfg_mlme_get_sap_internal_restart(hdd_ctxt->psoc,
+							   &value);
+			hdd_debug("driver to start sap: %d", value);
+			if (value)
+				hdd_switch_sap_channel(adapter, restart_chan,
+						       true);
+			else
+				return;
+		}
+	}
+}
+
+/**
+ * hdd_init_channel_avoidance() - Initialize channel avoidance
+ * @hdd_ctx:	HDD global context
+ *
+ * Initialize the channel avoidance logic by retrieving the unsafe
+ * channel list from the platform driver and plumbing the data
+ * down to the lower layers.  Then subscribe to subsequent channel
+ * avoidance events.
+ *
+ * Return: None
+ */
+static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
+{
+	uint16_t unsafe_channel_count;
+	int index;
+
+	pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
+				    hdd_ctx->unsafe_channel_list,
+				     &(hdd_ctx->unsafe_channel_count),
+				     sizeof(uint16_t) * NUM_CHANNELS);
+
+	hdd_debug("num of unsafe channels is %d",
+	       hdd_ctx->unsafe_channel_count);
+
+	unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
+				       (uint16_t)NUM_CHANNELS);
+
+	for (index = 0; index < unsafe_channel_count; index++) {
+		hdd_debug("channel %d is not safe",
+		       hdd_ctx->unsafe_channel_list[index]);
+
+	}
+
+}
+
+static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
+				     struct hdd_context *hdd_ctx)
+{
+	uint8_t restart_chan;
+
+	restart_chan = hdd_get_safe_channel_from_pcl_and_acs_range(adapter);
+	if (!restart_chan) {
+		hdd_alert("fail to restart SAP");
+		return;
+	}
+
+	/* SAP restart due to unsafe channel. While restarting
+	 * the SAP, make sure to clear acs_channel, channel to
+	 * reset to 0. Otherwise these settings will override
+	 * the ACS while restart.
+	 */
+	hdd_ctx->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
+
+	hdd_debug("sending coex indication");
+
+	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+				    WLAN_SVC_LTE_COEX_IND, NULL, 0);
+	hdd_switch_sap_channel(adapter, restart_chan, true);
+}
+
+int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
+	uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
+{
+	uint32_t size;
+	uint16_t *unsafe_list;
+	uint16_t chan_count;
+
+	if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
+		return -EINVAL;
+
+	chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
+			     NUM_CHANNELS);
+	if (chan_count) {
+		size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
+		unsafe_list = qdf_mem_malloc(size);
+		if (!unsafe_list)
+			return -ENOMEM;
+		qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
+	} else {
+		unsafe_list = NULL;
+	}
+
+	*local_unsafe_list = unsafe_list;
+	*local_unsafe_list_count = chan_count;
+
+	return 0;
+}
+
+bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
+	uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count)
+{
+	int i, j;
+
+	if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
+		return true;
+	if (local_unsafe_list_count == 0)
+		return false;
+	for (i = 0; i < local_unsafe_list_count; i++) {
+		for (j = 0; j < local_unsafe_list_count; j++)
+			if (local_unsafe_list[i] ==
+			    hdd_ctx->unsafe_channel_list[j])
+				break;
+		if (j >= local_unsafe_list_count)
+			break;
+	}
+	if (i >= local_unsafe_list_count) {
+		hdd_info("unsafe chan list same");
+		return false;
+	}
+
+	return true;
+}
+#else
+static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
+					    struct hdd_context *hdd_ctx)
+{
+	hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
+}
+#endif /* defined(FEATURE_WLAN_CH_AVOID) */
+
+/**
+ * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
+ * user space
+ * @frame_ind: Management frame data to be informed.
+ *
+ * This function is used to indicate management frame to
+ * user space
+ *
+ * Return: None
+ *
+ */
+void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
+{
+	struct hdd_context *hdd_ctx = NULL;
+	struct hdd_adapter *adapter = NULL;
+	int i;
+	struct ieee80211_mgmt *mgmt =
+		(struct ieee80211_mgmt *)frame_ind->frameBuf;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) {
+		hdd_err(" Invalid frame length");
+		return;
+	}
+
+	if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
+		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+			adapter =
+				hdd_get_adapter_by_sme_session_id(hdd_ctx, i);
+			if (adapter)
+				break;
+		}
+	} else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
+		hdd_for_each_adapter(hdd_ctx, adapter) {
+			if ((NULL != adapter) &&
+			    (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) {
+				__hdd_indicate_mgmt_frame(adapter,
+						frame_ind->frame_len,
+						frame_ind->frameBuf,
+						frame_ind->frameType,
+						frame_ind->rxChan,
+						frame_ind->rxRssi);
+			}
+		}
+		adapter = NULL;
+	} else {
+		adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
+					frame_ind->sessionId);
+	}
+
+	if ((NULL != adapter) &&
+		(WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
+		__hdd_indicate_mgmt_frame(adapter,
+						frame_ind->frame_len,
+						frame_ind->frameBuf,
+						frame_ind->frameType,
+						frame_ind->rxChan,
+						frame_ind->rxRssi);
+}
+
+void hdd_acs_response_timeout_handler(void *context)
+{
+	struct hdd_external_acs_timer_context *timer_context =
+			(struct hdd_external_acs_timer_context *)context;
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	uint8_t reason;
+
+	hdd_enter();
+	if (!timer_context) {
+		hdd_err("invlaid timer context");
+		return;
+	}
+	adapter = timer_context->adapter;
+	reason = timer_context->reason;
+
+
+	if ((!adapter) ||
+	    (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
+		hdd_err("invalid adapter or adapter has invalid magic");
+		return;
+	}
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
+		clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
+	else
+		return;
+
+	hdd_err("ACS timeout happened for %s reason %d",
+				adapter->dev->name, reason);
+
+	switch (reason) {
+	/* SAP init case */
+	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
+		wlan_sap_set_vendor_acs(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+					false);
+		wlan_hdd_cfg80211_start_acs(adapter);
+		break;
+	/* DFS detected on current channel */
+	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
+		wlan_sap_update_next_channel(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter), 0, 0);
+		sme_update_new_channel_event(hdd_ctx->mac_handle,
+					     adapter->session_id);
+		break;
+	/* LTE coex event on current channel */
+	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
+		hdd_lte_coex_restart_sap(adapter, hdd_ctx);
+		break;
+	default:
+		hdd_info("invalid reason for timer invoke");
+
+	}
+}
+
+/**
+ * hdd_override_ini_config - Override INI config
+ * @hdd_ctx: HDD context
+ *
+ * Override INI config based on module parameter.
+ *
+ * Return: None
+ */
+static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
+{
+
+	if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
+		hdd_ctx->config->enableDFSChnlScan = enable_dfs_chan_scan;
+		hdd_debug("Module enable_dfs_chan_scan set to %d",
+			   enable_dfs_chan_scan);
+	}
+	if (0 == enable_11d || 1 == enable_11d) {
+		hdd_ctx->config->Is11dSupportEnabled = enable_11d;
+		hdd_debug("Module enable_11d set to %d", enable_11d);
+	}
+
+	if (hdd_ctx->config->action_oui_enable && !ucfg_action_oui_enabled()) {
+		hdd_ctx->config->action_oui_enable = 0;
+		hdd_err("Ignore ini: %s, since no action_oui component",
+			CFG_ENABLE_ACTION_OUI);
+	}
+}
+
+#ifdef ENABLE_MTRACE_LOG
+static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
+{
+	uint8_t module_id = 0;
+	int qdf_print_idx = -1;
+
+	qdf_print_idx = qdf_get_pidx();
+	for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++)
+		qdf_print_set_category_verbose(
+					qdf_print_idx,
+					module_id, QDF_TRACE_LEVEL_TRACE,
+					hdd_ctx->config->enable_mtrace);
+}
+#else
+static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
+{
+}
+
+#endif
+
+/**
+ * hdd_set_trace_level_for_each - Set trace level for each INI config
+ * @hdd_ctx - HDD context
+ *
+ * Set trace level for each module based on INI config.
+ *
+ * Return: None
+ */
+static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
+{
+	hdd_qdf_trace_enable(QDF_MODULE_ID_WMI,
+			     hdd_ctx->config->qdf_trace_enable_wdi);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_HDD,
+			     hdd_ctx->config->qdf_trace_enable_hdd);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_SME,
+			     hdd_ctx->config->qdf_trace_enable_sme);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_PE,
+			     hdd_ctx->config->qdf_trace_enable_pe);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_WMA,
+			     hdd_ctx->config->qdf_trace_enable_wma);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_SYS,
+			     hdd_ctx->config->qdf_trace_enable_sys);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_QDF,
+			     hdd_ctx->config->qdf_trace_enable_qdf);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_SAP,
+			     hdd_ctx->config->qdf_trace_enable_sap);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SOFTAP,
+			     hdd_ctx->config->qdf_trace_enable_hdd_sap);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_BMI,
+				hdd_ctx->config->qdf_trace_enable_bmi);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_CFG,
+				hdd_ctx->config->qdf_trace_enable_cfg);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_EPPING,
+				hdd_ctx->config->qdf_trace_enable_epping);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_QDF_DEVICE,
+				hdd_ctx->config->qdf_trace_enable_qdf_devices);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_TXRX,
+				hdd_ctx->config->qdf_trace_enable_txrx);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_DP,
+				hdd_ctx->config->qdf_trace_enable_dp);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_HTC,
+				hdd_ctx->config->qdf_trace_enable_htc);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_HIF,
+				hdd_ctx->config->qdf_trace_enable_hif);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SAP_DATA,
+				hdd_ctx->config->qdf_trace_enable_hdd_sap_data);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_DATA,
+				hdd_ctx->config->qdf_trace_enable_hdd_data);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_WIFIPOS,
+				hdd_ctx->config->qdf_trace_enable_wifi_pos);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_NAN,
+				hdd_ctx->config->qdf_trace_enable_nan);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_REGULATORY,
+				hdd_ctx->config->qdf_trace_enable_regulatory);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_CP_STATS,
+				hdd_ctx->config->qdf_trace_enable_cp_stats);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_MLME, 0xffff);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_FWOL, 0xffff);
+
+	hdd_set_mtrace_for_each(hdd_ctx);
+
+	hdd_cfg_print_global_config(hdd_ctx);
+}
+
+/**
+ * hdd_context_init() - Initialize HDD context
+ * @hdd_ctx:	HDD context.
+ *
+ * Initialize HDD context along with all the feature specific contexts.
+ *
+ * return: 0 on success and errno on failure.
+ */
+static int hdd_context_init(struct hdd_context *hdd_ctx)
+{
+	int ret;
+
+	hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
+	hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
+
+	init_completion(&hdd_ctx->mc_sus_event_var);
+	init_completion(&hdd_ctx->ready_to_suspend);
+
+	qdf_spinlock_create(&hdd_ctx->connection_status_lock);
+	qdf_spinlock_create(&hdd_ctx->sta_update_info_lock);
+	qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
+
+	qdf_list_create(&hdd_ctx->hdd_adapters, 0);
+
+	ret = hdd_scan_context_init(hdd_ctx);
+	if (ret)
+		goto list_destroy;
+
+	hdd_rx_wake_lock_create(hdd_ctx);
+
+	ret = hdd_sap_context_init(hdd_ctx);
+	if (ret)
+		goto scan_destroy;
+
+	wlan_hdd_cfg80211_extscan_init(hdd_ctx);
+
+	hdd_init_offloaded_packets_ctx(hdd_ctx);
+
+	ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
+				     hdd_ctx->config);
+	if (ret)
+		goto sap_destroy;
+
+	qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
+			     "monitor_mode_wakelock");
+
+	return 0;
+
+sap_destroy:
+	hdd_sap_context_destroy(hdd_ctx);
+
+scan_destroy:
+	hdd_scan_context_destroy(hdd_ctx);
+	hdd_rx_wake_lock_destroy(hdd_ctx);
+list_destroy:
+	qdf_list_destroy(&hdd_ctx->hdd_adapters);
+
+	return ret;
+}
+
+void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx)
+{
+	uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time;
+	enum wake_lock_reason reason =
+		WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER;
+
+	hdd_debug("Starting psoc idle timer");
+	qdf_sched_delayed_work(&hdd_ctx->psoc_idle_timeout_work, timeout_ms);
+	hdd_prevent_suspend_timeout(timeout_ms, reason);
+}
+
+void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx)
+{
+	qdf_cancel_delayed_work(&hdd_ctx->psoc_idle_timeout_work);
+	hdd_debug("Stopped psoc idle timer");
+}
+
+/**
+ * hdd_iface_change_callback() - Function invoked when stop modules expires
+ * @priv: pointer to hdd context
+ *
+ * This function is invoked when the timer waiting for the interface change
+ * expires, it shall cut-down the power to wlan and stop all the modules.
+ *
+ * Return: void
+ */
+static void hdd_iface_change_callback(void *priv)
+{
+	struct hdd_context *hdd_ctx = (struct hdd_context *) priv;
+	int ret;
+	int status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (status)
+		return;
+
+	hdd_enter();
+	hdd_debug("Interface change timer expired close the modules!");
+	ret = hdd_wlan_stop_modules(hdd_ctx, false);
+	if (ret)
+		hdd_err("Failed to stop modules");
+	hdd_exit();
+}
+
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
+{
+	wlan_logging_set_log_to_console(hdd_ctx->config->
+					wlan_logging_to_console);
+	wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable);
+}
+#else
+static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
+{ }
+#endif
+
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+static void hdd_init_wlan_logging_params(struct hdd_config *config,
+					 struct wlan_objmgr_psoc *psoc)
+{
+	config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT);
+
+	config->wlan_logging_to_console =
+			cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT);
+}
+#else
+static void hdd_init_wlan_logging_params(struct hdd_config *config,
+					 struct wlan_objmgr_psoc *psoc)
+{
+}
+#endif
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
+					struct wlan_objmgr_psoc *psoc)
+{
+	config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN);
+}
+#else
+static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
+					struct wlan_objmgr_psoc *psoc)
+{
+}
+#endif
+
+#ifndef REMOVE_PKT_LOG
+static void hdd_init_packet_log(struct hdd_config *config,
+				struct wlan_objmgr_psoc *psoc)
+{
+	config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG);
+}
+#else
+static void hdd_init_packet_log(struct hdd_config *config,
+				struct wlan_objmgr_psoc *psoc)
+{
+}
+#endif
+
+/**
+ * hdd_cfg_params_init() - Initialize hdd params in hdd_config strucuture
+ * @hdd_ctx - Pointer to HDD context
+ *
+ * Return: None
+ */
+static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
+{
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	struct hdd_config *config = hdd_ctx->config;
+
+	if (!psoc) {
+		hdd_err("Invalid psoc");
+		return;
+	}
+
+	if (!config) {
+		hdd_err("Invalid hdd config");
+		return;
+	}
+
+	config->bug_on_reinit_failure = cfg_get(psoc,
+						CFG_BUG_ON_REINIT_FAILURE);
+
+	config->is_ramdump_enabled = cfg_get(psoc,
+					     CFG_ENABLE_RAMDUMP_COLLECTION);
+
+	config->iface_change_wait_time = cfg_get(psoc,
+						 CFG_INTERFACE_CHANGE_WAIT);
+
+	config->multicast_host_fw_msgs = cfg_get(psoc,
+						 CFG_MULTICAST_HOST_FW_MSGS);
+
+	config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL);
+	config->timer_multiplier = cfg_get(psoc, CFG_TIMER_MULTIPLIER);
+	config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT);
+	config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG);
+
+	hdd_init_wlan_auto_shutdown(config, psoc);
+	hdd_init_wlan_logging_params(config, psoc);
+	hdd_init_packet_log(config, psoc);
+	hdd_dp_cfg_update(psoc, hdd_ctx);
+}
+
+/**
+ * hdd_context_create() - Allocate and inialize HDD context.
+ * @dev:	Device Pointer to the underlying device
+ *
+ * Allocate and initialize HDD context. HDD context is allocated as part of
+ * wiphy allocation and then context is initialized.
+ *
+ * Return: HDD context on success and ERR_PTR on failure
+ */
+static struct hdd_context *hdd_context_create(struct device *dev)
+{
+	QDF_STATUS status;
+	int ret = 0;
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter();
+
+	hdd_ctx = hdd_cfg80211_wiphy_alloc();
+	if (!hdd_ctx) {
+		ret = -ENOMEM;
+		goto err_out;
+	}
+
+	qdf_create_delayed_work(&hdd_ctx->psoc_idle_timeout_work,
+				hdd_iface_change_callback,
+				hdd_ctx);
+
+	mutex_init(&hdd_ctx->iface_change_lock);
+
+	hdd_ctx->parent_dev = dev;
+	hdd_ctx->last_scan_reject_session_id = 0xFF;
+
+	hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
+	if (!hdd_ctx->config) {
+		ret = -ENOMEM;
+		goto err_free_hdd_context;
+	}
+
+	/* Read and parse the qcom_cfg.ini file */
+	status = hdd_parse_config_ini(hdd_ctx);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Error (status: %d) parsing INI file: %s", status,
+			  WLAN_INI_FILE);
+		ret = -EINVAL;
+		goto err_free_config;
+	}
+
+	status = cfg_parse(WLAN_INI_FILE);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to parse cfg %s; status:%d\n",
+			WLAN_INI_FILE, status);
+
+	ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID);
+	if (ret) {
+		QDF_DEBUG_PANIC("Psoc creation fails!");
+		goto err_free_config;
+	}
+
+	hdd_cfg_params_init(hdd_ctx);
+
+	hdd_debug("setting timer multiplier: %u",
+		  hdd_ctx->config->timer_multiplier);
+	qdf_timer_set_multiplier(hdd_ctx->config->timer_multiplier);
+
+	cds_set_fatal_event(cfg_get(hdd_ctx->psoc,
+				    CFG_ENABLE_FATAL_EVENT_TRIGGER));
+
+	hdd_override_ini_config(hdd_ctx);
+
+	ret = hdd_context_init(hdd_ctx);
+
+	if (ret)
+		goto err_hdd_objmgr_destroy;
+
+	/* Uses to enabled logging after SSR */
+	hdd_ctx->fw_log_settings.enable = hdd_ctx->config->enable_fw_log;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
+		goto skip_multicast_logging;
+
+	cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
+
+	ret = wlan_hdd_init_tx_rx_histogram(hdd_ctx);
+	if (ret)
+		goto err_deinit_hdd_context;
+
+	ret = hdd_init_netlink_services(hdd_ctx);
+	if (ret)
+		goto err_deinit_txrx_histogram;
+
+	hdd_set_wlan_logging(hdd_ctx);
+
+skip_multicast_logging:
+	hdd_set_trace_level_for_each(hdd_ctx);
+
+	cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
+
+	hdd_exit();
+
+	return hdd_ctx;
+
+err_deinit_txrx_histogram:
+	wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
+
+err_deinit_hdd_context:
+	hdd_context_deinit(hdd_ctx);
+
+err_hdd_objmgr_destroy:
+	hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
+
+err_free_config:
+	qdf_mem_free(hdd_ctx->config);
+
+err_free_hdd_context:
+	mutex_destroy(&hdd_ctx->iface_change_lock);
+	wiphy_free(hdd_ctx->wiphy);
+
+err_out:
+	return ERR_PTR(ret);
+}
+
+#ifdef WLAN_OPEN_P2P_INTERFACE
+/**
+ * hdd_open_p2p_interface - Open P2P interface
+ * @hdd_ctx: HDD context
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+	bool p2p_dev_addr_admin;
+
+	cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
+
+	if (p2p_dev_addr_admin &&
+	    !(hdd_ctx->config->intfMacAddr[0].bytes[0] & 0x02)) {
+		hdd_ctx->p2p_device_address = hdd_ctx->config->intfMacAddr[0];
+
+		/*
+		 * Generate the P2P Device Address. This consists of
+		 * the device's primary MAC address with the locally
+		 * administered bit set.
+		 */
+		hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
+	} else {
+		uint8_t *p2p_dev_addr;
+
+		p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx);
+		if (!p2p_dev_addr) {
+			hdd_err("Failed to get MAC address for new p2p device");
+			return QDF_STATUS_E_INVAL;
+		}
+
+		qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
+			     p2p_dev_addr, QDF_MAC_ADDR_SIZE);
+	}
+
+	adapter = hdd_open_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE, "p2p%d",
+				   hdd_ctx->p2p_device_address.bytes,
+				   NET_NAME_UNKNOWN, true);
+	if (!adapter) {
+		hdd_err("Failed to open p2p interface");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	adapter = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE, "wlanocb%d",
+				   wlan_hdd_get_intf_addr(hdd_ctx),
+				   NET_NAME_UNKNOWN, true);
+	if (!adapter) {
+		hdd_err("Failed to open 802.11p interface");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	if (qdf_str_eq(hdd_ctx->config->enableConcurrentSTA, ""))
+		return QDF_STATUS_SUCCESS;
+
+	adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE,
+				   hdd_ctx->config->enableConcurrentSTA,
+				   wlan_hdd_get_intf_addr(hdd_ctx),
+				   NET_NAME_UNKNOWN, true);
+	if (!adapter) {
+		hdd_err("Failed to open concurrent station interface");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_start_station_adapter()- Start the Station Adapter
+ * @adapter: HDD adapter
+ *
+ * This function initializes the adapter for the station mode.
+ *
+ * Return: 0 on success or errno on failure.
+ */
+int hdd_start_station_adapter(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+	int ret;
+
+	hdd_enter_dev(adapter->dev);
+	if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
+		hdd_err("session is already opened, %d",
+			adapter->session_id);
+		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
+	}
+
+	ret = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
+	if (ret) {
+		hdd_err("failed to create vdev: %d", ret);
+		return ret;
+	}
+	status = hdd_init_station_mode(adapter);
+
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Error Initializing station mode: %d", status);
+		return qdf_status_to_os_return(status);
+	}
+
+	hdd_register_tx_flow_control(adapter,
+		hdd_tx_resume_timer_expired_handler,
+		hdd_tx_resume_cb,
+		hdd_tx_flow_control_is_pause);
+
+	hdd_exit();
+
+	return 0;
+}
+
+/**
+ * hdd_start_ap_adapter()- Start AP Adapter
+ * @adapter: HDD adapter
+ *
+ * This function initializes the adapter for the AP mode.
+ *
+ * Return: 0 on success errno on failure.
+ */
+int hdd_start_ap_adapter(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+	bool is_ssr = false;
+	int ret;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter();
+
+	if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
+		hdd_err("session is already opened, %d",
+			adapter->session_id);
+		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
+	}
+	/*
+	 * In SSR case no need to create new sap context.
+	 * Otherwise create sap context first and then create
+	 * vdev as while creating the vdev, driver needs to
+	 * register SAP callback and that callback uses sap context
+	 */
+	if (adapter->session.ap.sap_context) {
+		is_ssr = true;
+	} else if (!hdd_sap_create_ctx(adapter)) {
+		hdd_err("sap creation failed");
+		return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
+	}
+
+	ret = hdd_vdev_create(adapter, wlansap_roam_callback,
+			      adapter->session.ap.sap_context);
+	if (ret) {
+		hdd_err("failed to create vdev, status:%d", ret);
+		hdd_sap_destroy_ctx(adapter);
+		return ret;
+	}
+
+	if (adapter->device_mode == QDF_SAP_MODE)
+		sme_cli_set_command(adapter->session_id,
+			WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
+			(bool)(hdd_ctx->config->fine_time_meas_cap &
+							WMI_FW_AP_RTT_RESPR),
+			VDEV_CMD);
+
+	status = hdd_init_ap_mode(adapter, is_ssr);
+
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Error Initializing the AP mode: %d", status);
+		return qdf_status_to_os_return(status);
+	}
+
+	hdd_register_tx_flow_control(adapter,
+		hdd_softap_tx_resume_timer_expired_handler,
+		hdd_softap_tx_resume_cb,
+		hdd_tx_flow_control_is_pause);
+
+	hdd_exit();
+	return 0;
+}
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+/**
+ * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
+ * @cds_cfg: CDS Configuration
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Return: none
+ */
+static inline void hdd_txrx_populate_cds_config(struct cds_config_info
+						*cds_cfg,
+						struct hdd_context *hdd_ctx)
+{
+	cds_cfg->tx_flow_stop_queue_th =
+		hdd_ctx->config->TxFlowStopQueueThreshold;
+	cds_cfg->tx_flow_start_queue_offset =
+		hdd_ctx->config->TxFlowStartQueueOffset;
+	/* configuration for DP RX Threads */
+	cds_cfg->enable_dp_rx_threads = hdd_ctx->enable_dp_rx_threads;
+	cds_cfg->num_dp_rx_threads = hdd_ctx->config->num_dp_rx_threads;
+}
+#else
+static inline void hdd_txrx_populate_cds_config(struct cds_config_info
+						*cds_cfg,
+						struct hdd_context *hdd_ctx)
+{
+}
+#endif
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+/**
+ * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
+ * @cds_cfg: CDS Configuration
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Return: none
+ */
+static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
+			      struct hdd_context *hdd_ctx)
+{
+	bool is_rate_limit_enabled;
+	QDF_STATUS status;
+
+	status = ucfg_fwol_get_is_rate_limit_enabled(hdd_ctx->psoc,
+						     &is_rate_limit_enabled);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+
+	cds_cfg->ra_ratelimit_interval =
+		hdd_ctx->config->RArateLimitInterval;
+	cds_cfg->is_ra_ratelimit_enabled = is_rate_limit_enabled;
+}
+#else
+static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
+			     struct hdd_context *hdd_ctx)
+{
+}
+#endif
+
+/**
+ * hdd_update_cds_config() - API to update cds configuration parameters
+ * @hdd_ctx: HDD Context
+ *
+ * Return: 0 for Success, errno on failure
+ */
+static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
+{
+	struct cds_config_info *cds_cfg;
+	int value;
+	uint8_t band_capability;
+	uint8_t ito_repeat_count;
+	bool crash_inject;
+	bool self_recovery;
+	bool fw_timeout_crash;
+	QDF_STATUS status;
+
+	cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
+	if (!cds_cfg)
+		return -ENOMEM;
+
+	cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
+	cds_cfg->sta_maxlimod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
+
+	/*
+	 * Copy the DFS Phyerr Filtering Offload status.
+	 * This parameter reflects the value of the
+	 * dfs_phyerr_filter_offload flag as set in the ini.
+	 */
+	cds_cfg->dfs_phyerr_filter_offload =
+		hdd_ctx->config->fDfsPhyerrFilterOffload;
+
+	status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get crash inject ini config");
+		goto exit;
+	}
+
+	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get self recovery ini config");
+		goto exit;
+	}
+
+	status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc,
+						&fw_timeout_crash);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get fw timeout crash ini config");
+		goto exit;
+	}
+
+	status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc,
+						&ito_repeat_count);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get ITO repeat count ini config");
+		goto exit;
+	}
+
+	cds_cfg->force_target_assert_enabled = crash_inject;
+
+	ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value);
+	cds_cfg->ap_maxoffload_peers = value;
+	ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc,
+						    &value);
+	cds_cfg->ap_maxoffload_reorderbuffs = value;
+
+	cds_cfg->ap_disable_intrabss_fwd =
+		hdd_ctx->config->apDisableIntraBssFwd;
+
+	cds_cfg->dfs_pri_multiplier =
+		hdd_ctx->config->dfsRadarPriMultiplier;
+	cds_cfg->reorder_offload =
+			hdd_ctx->config->reorderOffloadSupport;
+
+	/* IPA micro controller data path offload resource config item */
+	cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled();
+	cds_cfg->max_scan = hdd_ctx->config->max_scan_count;
+
+	cds_cfg->enable_rxthread = hdd_ctx->enable_rxthread;
+	cds_cfg->self_gen_frm_pwr = hdd_ctx->config->self_gen_frm_pwr;
+	ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
+	cds_cfg->max_station = value;
+	cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
+	cds_cfg->max_msdus_per_rxinorderind =
+		hdd_ctx->config->max_msdus_per_rxinorderind;
+	cds_cfg->self_recovery_enabled = self_recovery;
+	cds_cfg->fw_timeout_crash = fw_timeout_crash;
+	cds_cfg->active_uc_apf_mode = hdd_ctx->config->active_uc_apf_mode;
+	cds_cfg->active_mc_bc_apf_mode = hdd_ctx->config->active_mc_bc_apf_mode;
+
+	cds_cfg->ito_repeat_count = ito_repeat_count;
+
+	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto exit;
+
+	cds_cfg->bandcapability = band_capability;
+	cds_cfg->delay_before_vdev_stop =
+		hdd_ctx->config->delay_before_vdev_stop;
+	cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs;
+
+	hdd_ra_populate_cds_config(cds_cfg, hdd_ctx);
+	hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
+	hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
+	cds_init_ini_config(cds_cfg);
+	return 0;
+
+exit:
+	qdf_mem_free(cds_cfg);
+	return -EINVAL;
+}
+
+/**
+ * hdd_update_user_config() - API to update user configuration
+ * parameters to obj mgr which are used by multiple components
+ * @hdd_ctx: HDD Context
+ *
+ * Return: 0 for Success, errno on failure
+ */
+static int hdd_update_user_config(struct hdd_context *hdd_ctx)
+{
+	struct wlan_objmgr_psoc_user_config *user_config;
+	bool skip_dfs_in_p2p_search = false;
+	uint8_t band_capability;
+	QDF_STATUS status;
+
+	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EIO;
+
+	user_config = qdf_mem_malloc(sizeof(*user_config));
+	if (!user_config)
+		return -ENOMEM;
+
+	user_config->dot11_mode = hdd_ctx->config->dot11Mode;
+	user_config->dual_mac_feature_disable =
+		hdd_ctx->config->dual_mac_feature_disable;
+	user_config->indoor_channel_support =
+		hdd_ctx->config->indoor_channel_support;
+	user_config->is_11d_support_enabled =
+		hdd_ctx->config->Is11dSupportEnabled;
+	user_config->is_11h_support_enabled =
+		hdd_ctx->config->Is11hSupportEnabled;
+	cfg_p2p_get_skip_dfs_channel_p2p_search(hdd_ctx->psoc,
+						&skip_dfs_in_p2p_search);
+	user_config->skip_dfs_chnl_in_p2p_search = skip_dfs_in_p2p_search;
+	user_config->band_capability = band_capability;
+	wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config);
+
+	qdf_mem_free(user_config);
+	return 0;
+}
+
+/**
+ * hdd_init_thermal_info - Initialize thermal level
+ * @hdd_ctx:	HDD context
+ *
+ * Initialize thermal level at SME layer and set the thermal level callback
+ * which would be called when a configured thermal threshold is hit.
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
+{
+	tSmeThermalParams thermal_param;
+	QDF_STATUS status;
+	mac_handle_t mac_handle;
+	struct wlan_fwol_thermal_temp thermal_temp = {0};
+
+	thermal_param.smeThermalMgmtEnabled =
+		hdd_ctx->config->thermalMitigationEnable;
+	thermal_param.smeThrottlePeriod = hdd_ctx->config->throttlePeriod;
+
+	thermal_param.sme_throttle_duty_cycle_tbl[0] =
+		hdd_ctx->config->throttle_dutycycle_level0;
+	thermal_param.sme_throttle_duty_cycle_tbl[1] =
+		hdd_ctx->config->throttle_dutycycle_level1;
+	thermal_param.sme_throttle_duty_cycle_tbl[2] =
+		hdd_ctx->config->throttle_dutycycle_level2;
+	thermal_param.sme_throttle_duty_cycle_tbl[3] =
+		hdd_ctx->config->throttle_dutycycle_level3;
+
+	status = ucfg_fwol_get_thermal_temp(hdd_ctx->psoc, &thermal_temp);
+	if (QDF_IS_STATUS_ERROR(status))
+		return qdf_status_to_os_return(status);
+
+	thermal_param.smeThermalLevels[0].smeMinTempThreshold =
+					thermal_temp.thermal_temp_min_level0;
+	thermal_param.smeThermalLevels[0].smeMaxTempThreshold =
+					thermal_temp.thermal_temp_max_level0;
+	thermal_param.smeThermalLevels[1].smeMinTempThreshold =
+					thermal_temp.thermal_temp_min_level1;
+	thermal_param.smeThermalLevels[1].smeMaxTempThreshold =
+					thermal_temp.thermal_temp_max_level1;
+	thermal_param.smeThermalLevels[2].smeMinTempThreshold =
+					thermal_temp.thermal_temp_min_level2;
+	thermal_param.smeThermalLevels[2].smeMaxTempThreshold =
+					thermal_temp.thermal_temp_max_level2;
+	thermal_param.smeThermalLevels[3].smeMinTempThreshold =
+					thermal_temp.thermal_temp_min_level3;
+	thermal_param.smeThermalLevels[3].smeMaxTempThreshold =
+					thermal_temp.thermal_temp_max_level3;
+
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_init_thermal_info(mac_handle, thermal_param);
+
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return qdf_status_to_os_return(status);
+
+	sme_add_set_thermal_level_callback(mac_handle,
+					   hdd_set_thermal_level_cb);
+
+	return 0;
+
+}
+
+#if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
+/**
+ * hdd_hold_rtnl_lock - Hold RTNL lock
+ *
+ * Hold RTNL lock
+ *
+ * Return: True if held and false otherwise
+ */
+static inline bool hdd_hold_rtnl_lock(void)
+{
+	rtnl_lock();
+	return true;
+}
+
+/**
+ * hdd_release_rtnl_lock - Release RTNL lock
+ *
+ * Release RTNL lock
+ *
+ * Return: None
+ */
+static inline void hdd_release_rtnl_lock(void)
+{
+	rtnl_unlock();
+}
+#else
+static inline bool hdd_hold_rtnl_lock(void) { return false; }
+static inline void hdd_release_rtnl_lock(void) { }
+#endif
+
+#if !defined(REMOVE_PKT_LOG)
+
+/* MAX iwpriv command support */
+#define PKTLOG_SET_BUFF_SIZE	3
+#define PKTLOG_CLEAR_BUFF	4
+#define MAX_PKTLOG_SIZE		16
+
+/**
+ * hdd_pktlog_set_buff_size() - set pktlog buffer size
+ * @hdd_ctx: hdd context
+ * @set_value2: pktlog buffer size value
+ *
+ *
+ * Return: 0 for success or error.
+ */
+static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
+{
+	struct sir_wifi_start_log start_log = { 0 };
+	QDF_STATUS status;
+
+	start_log.ring_id = RING_ID_PER_PACKET_STATS;
+	start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
+	start_log.ini_triggered = cds_is_packet_log_enabled();
+	start_log.user_triggered = 1;
+	start_log.size = set_value2;
+	start_log.is_pktlog_buff_clear = false;
+
+	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
+		hdd_exit();
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_pktlog_clear_buff() - clear pktlog buffer
+ * @hdd_ctx: hdd context
+ *
+ * Return: 0 for success or error.
+ */
+static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
+{
+	struct sir_wifi_start_log start_log;
+	QDF_STATUS status;
+
+	start_log.ring_id = RING_ID_PER_PACKET_STATS;
+	start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
+	start_log.ini_triggered = cds_is_packet_log_enabled();
+	start_log.user_triggered = 1;
+	start_log.size = 0;
+	start_log.is_pktlog_buff_clear = true;
+
+	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
+		hdd_exit();
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+/**
+ * hdd_process_pktlog_command() - process pktlog command
+ * @hdd_ctx: hdd context
+ * @set_value: value set by user
+ * @set_value2: pktlog buffer size value
+ *
+ * This function process pktlog command.
+ * set_value2 only matters when set_value is 3 (set buff size)
+ * otherwise we ignore it.
+ *
+ * Return: 0 for success or error.
+ */
+int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
+			       int set_value2)
+{
+	int ret;
+	bool enable;
+	uint8_t user_triggered = 0;
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
+
+	if (set_value > PKTLOG_CLEAR_BUFF) {
+		hdd_err("invalid pktlog value %d", set_value);
+		return -EINVAL;
+	}
+
+	if (set_value == PKTLOG_SET_BUFF_SIZE) {
+		if (set_value2 <= 0) {
+			hdd_err("invalid pktlog size %d", set_value2);
+			return -EINVAL;
+		} else if (set_value2 > MAX_PKTLOG_SIZE) {
+			hdd_err("Pktlog buff size is too large. max value is 16MB.\n");
+			return -EINVAL;
+		}
+		return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
+	} else if (set_value == PKTLOG_CLEAR_BUFF) {
+		return hdd_pktlog_clear_buff(hdd_ctx);
+	}
+
+	/*
+	 * set_value = 0 then disable packetlog
+	 * set_value = 1 enable packetlog forcefully
+	 * set_vlaue = 2 then disable packetlog if disabled through ini or
+	 *                     enable packetlog with AUTO type.
+	 */
+	enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
+			 true : false;
+
+	if (1 == set_value) {
+		enable = true;
+		user_triggered = 1;
+	}
+
+	return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
+}
+
+/**
+ * hdd_pktlog_enable_disable() - Enable/Disable packet logging
+ * @hdd_ctx: HDD context
+ * @enable: Flag to enable/disable
+ * @user_triggered: triggered through iwpriv
+ * @size: buffer size to be used for packetlog
+ *
+ * Return: 0 on success; error number otherwise
+ */
+int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, bool enable,
+				uint8_t user_triggered, int size)
+{
+	struct sir_wifi_start_log start_log;
+	QDF_STATUS status;
+
+	start_log.ring_id = RING_ID_PER_PACKET_STATS;
+	start_log.verbose_level =
+			enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
+	start_log.ini_triggered = cds_is_packet_log_enabled();
+	start_log.user_triggered = user_triggered;
+	start_log.size = size;
+	start_log.is_pktlog_buff_clear = false;
+	/*
+	 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
+	 * commands. Host uses this flag to decide whether to send pktlog
+	 * disable command to fw without sending pktlog enable command
+	 * previously. For eg, If vendor sends pktlog disable command without
+	 * sending pktlog enable command, then host discards the packet
+	 * but for iwpriv command, host will send it to fw.
+	 */
+	start_log.is_iwpriv_command = 1;
+	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
+		hdd_exit();
+		return -EINVAL;
+	}
+
+	if (enable == true)
+		hdd_ctx->is_pktlog_enabled = 1;
+	else
+		hdd_ctx->is_pktlog_enabled = 0;
+
+	return 0;
+}
+#endif /* REMOVE_PKT_LOG */
+
+/**
+ * hdd_get_platform_wlan_mac_buff() - API to query platform driver
+ *                                    for MAC address
+ * @dev: Device Pointer
+ * @num: Number of Valid Mac address
+ *
+ * Return: Pointer to MAC address buffer
+ */
+static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
+					       uint32_t *num)
+{
+	return pld_get_wlan_mac_address(dev, num);
+}
+
+/**
+ * hdd_populate_random_mac_addr() - API to populate random mac addresses
+ * @hdd_ctx: HDD Context
+ * @num: Number of random mac addresses needed
+ *
+ * Generate random addresses using bit manipulation on the base mac address
+ *
+ * Return: None
+ */
+void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
+{
+	uint32_t start_idx = QDF_MAX_CONCURRENCY_PERSONA - num;
+	uint32_t iter;
+	struct hdd_config *ini = hdd_ctx->config;
+	uint8_t *buf = NULL;
+	uint8_t macaddr_b3, tmp_br3;
+	uint8_t *src = ini->intfMacAddr[0].bytes;
+
+	for (iter = start_idx; iter < QDF_MAX_CONCURRENCY_PERSONA; ++iter) {
+		buf = ini->intfMacAddr[iter].bytes;
+		qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
+		macaddr_b3 = buf[3];
+		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + iter) &
+			INTF_MACADDR_MASK;
+		macaddr_b3 += tmp_br3;
+		macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
+		buf[0] |= 0x02;
+		buf[3] = macaddr_b3;
+		hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
+	}
+}
+
+/**
+ * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
+ * @hdd_ctx: HDD Context
+ *
+ * API to get mac addresses from platform driver and update the driver
+ * structures and configure FW with the base mac address.
+ * Return: int
+ */
+static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
+{
+	uint32_t no_of_mac_addr, iter;
+	uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
+	uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
+	uint8_t *addr, *buf;
+	struct device *dev = hdd_ctx->parent_dev;
+	struct hdd_config *ini = hdd_ctx->config;
+	tSirMacAddr mac_addr;
+	QDF_STATUS status;
+
+	addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
+
+	if (no_of_mac_addr == 0 || !addr)
+		return -EINVAL;
+
+	if (no_of_mac_addr > max_mac_addr)
+		no_of_mac_addr = max_mac_addr;
+
+	qdf_mem_copy(&mac_addr, addr, mac_addr_size);
+
+	for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
+		buf = ini->intfMacAddr[iter].bytes;
+		qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
+		hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
+	}
+
+	status = sme_set_custom_mac_addr(mac_addr);
+
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return -EAGAIN;
+
+	if (no_of_mac_addr < max_mac_addr)
+		hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
+					     no_of_mac_addr);
+	return 0;
+}
+
+/**
+ * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
+ * @hdd_ctx: HDD Context
+ *
+ * Update MAC address to FW. If MAC address passed by FW is invalid, host
+ * will generate its own MAC and update it to FW.
+ *
+ * Return: 0 for success
+ *         Non-zero error code for failure
+ */
+static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
+{
+	tSirMacAddr customMacAddr;
+	QDF_STATUS status;
+
+	qdf_mem_copy(&customMacAddr,
+		     &hdd_ctx->config->intfMacAddr[0].bytes[0],
+		     sizeof(tSirMacAddr));
+	status = sme_set_custom_mac_addr(customMacAddr);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return -EAGAIN;
+	return 0;
+}
+
+/**
+ * hdd_initialize_mac_address() - API to get wlan mac addresses
+ * @hdd_ctx: HDD Context
+ *
+ * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
+ * is provisioned with mac addresses, driver uses it, else it will use
+ * wlan_mac.bin to update HW MAC addresses.
+ *
+ * Return: None
+ */
+static void hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	int ret;
+
+	ret = hdd_platform_wlan_mac(hdd_ctx);
+	if (!ret) {
+		hdd_info("using MAC address from platform driver");
+		return;
+	}
+
+	status = hdd_update_mac_config(hdd_ctx);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_info("using MAC address from wlan_mac.bin");
+		return;
+	}
+
+	hdd_info("using default MAC address");
+
+	if (hdd_ctx->update_mac_addr_to_fw) {
+		ret = hdd_update_mac_addr_to_fw(hdd_ctx);
+		if (ret)
+			hdd_err("MAC address out-of-sync, ret:%d", ret);
+	}
+}
+
+static int hdd_set_smart_chainmask_enabled(struct hdd_context *hdd_ctx)
+{
+	int vdev_id = 0;
+	QDF_STATUS status;
+	bool smart_chainmask_enabled;
+	int param_id = WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME;
+	int vpdev = PDEV_CMD;
+	int ret;
+
+	status = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc,
+						  &smart_chainmask_enabled);
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
+
+	ret = sme_cli_set_command(vdev_id, param_id,
+				  (int)smart_chainmask_enabled, vpdev);
+	if (ret)
+		hdd_err("WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME failed %d", ret);
+
+	return ret;
+}
+
+static int hdd_set_alternative_chainmask_enabled(struct hdd_context *hdd_ctx)
+{
+	int vdev_id = 0;
+	QDF_STATUS status;
+	int param_id = WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME;
+	bool alternative_chainmask_enabled;
+	int vpdev = PDEV_CMD;
+	int ret;
+
+	status = ucfg_get_alternative_chainmask_enabled(
+				hdd_ctx->psoc,
+				&alternative_chainmask_enabled);
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
+
+	ret = sme_cli_set_command(vdev_id, param_id,
+				  (int)alternative_chainmask_enabled, vpdev);
+	if (ret)
+		hdd_err("WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME failed %d",
+			ret);
+
+	return ret;
+}
+
+static int hdd_set_ani_enabled(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	int vdev_id = 0;
+	int param_id = WMI_PDEV_PARAM_ANI_ENABLE;
+	bool value;
+	int vpdev = PDEV_CMD;
+	int ret;
+
+	status = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &value);
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
+
+	ret = sme_cli_set_command(vdev_id, param_id, (int)value, vpdev);
+	if (ret)
+		hdd_err("WMI_PDEV_PARAM_ANI_ENABLE failed %d", ret);
+
+	return ret;
+}
+
+/**
+ * hdd_pre_enable_configure() - Configurations prior to cds_enable
+ * @hdd_ctx:	HDD context
+ *
+ * Pre configurations to be done at lower layer before calling cds enable.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
+{
+	int ret;
+	uint8_t val = 0;
+	QDF_STATUS status;
+	uint32_t arp_ac_category;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
+	/* Register HL netdev flow control callback */
+	cdp_hl_fc_register(soc, wlan_hdd_txrx_pause_cb);
+
+	/*
+	 * Note that the cds_pre_enable() sequence triggers the cfg download.
+	 * The cfg download must occur before we update the SME config
+	 * since the SME config operation must access the cfg database
+	 */
+	status = hdd_set_sme_config(hdd_ctx);
+
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Failed hdd_set_sme_config: %d", status);
+		ret = qdf_status_to_os_return(status);
+		goto out;
+	}
+
+	status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
+		ret = qdf_status_to_os_return(status);
+		goto out;
+	}
+
+	status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Get tx_chainmask_1ss from mlme failed");
+		ret = qdf_status_to_os_return(status);
+		goto out;
+	}
+	ret = sme_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, val,
+				  PDEV_CMD);
+	if (0 != ret) {
+		hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
+		goto out;
+	}
+
+	ret = hdd_set_smart_chainmask_enabled(hdd_ctx);
+	if (ret)
+		goto out;
+
+	ret = hdd_set_alternative_chainmask_enabled(hdd_ctx);
+	if (ret)
+		goto out;
+
+	ret = hdd_set_ani_enabled(hdd_ctx);
+	if (ret)
+		goto out;
+
+	status = ucfg_get_arp_ac_category(hdd_ctx->psoc, &arp_ac_category);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
+
+	ret = sme_cli_set_command(0, WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
+				  arp_ac_category,
+				  PDEV_CMD);
+	if (0 != ret) {
+		hdd_err("WMI_PDEV_PARAM_ARP_AC_OVERRIDE ac: %d ret: %d",
+			arp_ac_category, ret);
+		goto out;
+	}
+
+	status = hdd_set_sme_chan_list(hdd_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to init channel list: %d", status);
+		ret = qdf_status_to_os_return(status);
+		goto out;
+	}
+
+	/* Apply the cfg.ini to cfg.dat */
+	if (!hdd_update_config_cfg(hdd_ctx)) {
+		hdd_err("config update failed");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/*
+	 * Set the MAC Address Currently this is used by HAL to add self sta.
+	 * Remove this once self sta is added as part of session open.
+	 */
+	status = sme_cfg_set_str(hdd_ctx->mac_handle, WNI_CFG_STA_ID,
+				 hdd_ctx->config->intfMacAddr[0].bytes,
+				 sizeof(hdd_ctx->config->intfMacAddr[0]));
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to set MAC Address, status %d", status);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	hdd_init_channel_avoidance(hdd_ctx);
+
+	/* update enable sap mandatory chan list */
+	policy_mgr_enable_disable_sap_mandatory_chan_list(hdd_ctx->psoc,
+			hdd_ctx->config->enable_sap_mandatory_chan_list);
+out:
+	return ret;
+}
+
+#ifdef FEATURE_P2P_LISTEN_OFFLOAD
+/**
+ * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
+ * @context: context registered with sme_register_p2p_lo_event(). HDD
+ *   always registers a hdd context pointer
+ * @evt:event structure pointer
+ *
+ * This is the p2p listen offload stop event handler, it sends vendor
+ * event back to supplicant to notify the stop reason.
+ *
+ * Return: None
+ */
+static void wlan_hdd_p2p_lo_event_callback(void *context,
+					   struct sir_p2p_lo_event *evt)
+{
+	struct hdd_context *hdd_ctx = context;
+	struct sk_buff *vendor_event;
+	struct hdd_adapter *adapter;
+
+	hdd_enter();
+
+	if (hdd_ctx == NULL) {
+		hdd_err("Invalid HDD context pointer");
+		return;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, evt->vdev_id);
+	if (!adapter) {
+		hdd_err("Cannot find adapter by vdev_id = %d",
+				evt->vdev_id);
+		return;
+	}
+
+	vendor_event =
+		cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+			&(adapter->wdev), sizeof(uint32_t) + NLMSG_HDRLEN,
+			QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX,
+			GFP_KERNEL);
+
+	if (!vendor_event) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
+			evt->reason_code)) {
+		hdd_err("nla put failed");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+	hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
+			evt->vdev_id);
+}
+#else
+static void wlan_hdd_p2p_lo_event_callback(void *context,
+					   struct sir_p2p_lo_event *evt)
+{
+}
+#endif
+
+#ifdef FEATURE_WLAN_DYNAMIC_CVM
+static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
+{
+	return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap);
+}
+#else
+static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
+ * @hdd_ctx: HDD context
+ *
+ * This function sends the adaptive dwell time config configuration to the
+ * firmware via WMA
+ *
+ * Return: 0 - success, < 0 - failure
+ */
+static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	struct adaptive_dwelltime_params dwelltime_params;
+
+	dwelltime_params.is_enabled =
+			hdd_ctx->config->adaptive_dwell_mode_enabled;
+	dwelltime_params.dwelltime_mode =
+			hdd_ctx->config->global_adapt_dwelltime_mode;
+	dwelltime_params.lpf_weight =
+			hdd_ctx->config->adapt_dwell_lpf_weight;
+	dwelltime_params.passive_mon_intval =
+			hdd_ctx->config->adapt_dwell_passive_mon_intval;
+	dwelltime_params.wifi_act_threshold =
+			hdd_ctx->config->adapt_dwell_wifi_act_threshold;
+
+	status = sme_set_adaptive_dwelltime_config(hdd_ctx->mac_handle,
+						   &dwelltime_params);
+
+	hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Failed to send Adaptive Dwelltime configuration!");
+		return -EAGAIN;
+	}
+	return 0;
+}
+
+int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	struct wmi_dbs_scan_sel_params dbs_scan_params;
+	uint32_t i = 0;
+	uint8_t count = 0, numentries = 0;
+	uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
+				* CDS_DBS_SCAN_CLIENTS_MAX];
+
+	/* check if DBS is enabled or supported */
+	if ((hdd_ctx->config->dual_mac_feature_disable ==
+	     DISABLE_DBS_CXN_AND_SCAN) ||
+	    (hdd_ctx->config->dual_mac_feature_disable ==
+	     ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN))
+		return -EINVAL;
+
+	hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
+			       dbs_scan_config, &numentries,
+			       (CDS_DBS_SCAN_PARAM_PER_CLIENT
+				* CDS_DBS_SCAN_CLIENTS_MAX));
+
+	if (!numentries) {
+		hdd_debug("Do not send scan_selection_config");
+		return 0;
+	}
+
+	/* hdd_set_fw_log_params */
+	dbs_scan_params.num_clients = 0;
+	while (count < (numentries - 2)) {
+		dbs_scan_params.module_id[i] = dbs_scan_config[count];
+		dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
+		dbs_scan_params.num_non_dbs_scans[i] =
+			dbs_scan_config[count + 2];
+		dbs_scan_params.num_clients++;
+		hdd_debug("module:%d NDS:%d NNDS:%d",
+			  dbs_scan_params.module_id[i],
+			  dbs_scan_params.num_dbs_scans[i],
+			  dbs_scan_params.num_non_dbs_scans[i]);
+		count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
+		i++;
+	}
+
+	dbs_scan_params.pdev_id = 0;
+
+	hdd_debug("clients:%d pdev:%d",
+		  dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
+
+	status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle,
+						   &dbs_scan_params);
+	hdd_debug("Sending DBS Scan Selection Configuration to fw");
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Failed to send DBS Scan selection configuration!");
+		return -EAGAIN;
+	}
+	return 0;
+}
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+/**
+ * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
+ * @hdd_ctx:	HDD context
+ *
+ * Set auto shutdown callback to get indications from firmware to indicate
+ * userspace to shutdown WLAN after a configured amount of inactivity.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+
+	if (!hdd_ctx->config->wlan_auto_shutdown)
+		return 0;
+
+	status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle,
+					  wlan_hdd_auto_shutdown_cb);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_err("Auto shutdown feature could not be enabled: %d",
+			status);
+
+	return qdf_status_to_os_return(status);
+}
+#else
+static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+#endif
+
+#ifdef MWS_COEX
+/**
+ * hdd_set_mws_coex() - Set MWS coex configurations
+ * @hdd_ctx:   HDD context
+ *
+ * This function sends MWS-COEX 4G quick FTDM and
+ * MWS-COEX 5G-NR power limit to FW
+ *
+ * Return: 0 on success and errno on failure.
+ */
+static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
+{
+	int ret = 0;
+
+	ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM,
+				  hdd_ctx->config->mws_coex_4g_quick_tdm,
+				  PDEV_CMD);
+	if (ret) {
+		hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
+		return ret;
+	}
+
+	ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT,
+				  hdd_ctx->config->mws_coex_5g_nr_pwr_limit,
+				  PDEV_CMD);
+	if (ret) {
+		hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
+		return ret;
+	}
+	return ret;
+}
+#else
+static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+#endif
+
+/**
+ * hdd_features_init() - Init features
+ * @hdd_ctx:	HDD context
+ *
+ * Initialize features and their feature context after WLAN firmware is up.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+static int hdd_features_init(struct hdd_context *hdd_ctx)
+{
+	tSirTxPowerLimit hddtxlimit;
+	QDF_STATUS status;
+	int ret;
+	mac_handle_t mac_handle;
+	struct hdd_config *cfg;
+	bool b_cts2self;
+
+	hdd_enter();
+
+	ret = hdd_update_country_code(hdd_ctx);
+	if (ret) {
+		hdd_err("Failed to update country code; errno:%d", ret);
+		return -EINVAL;
+	}
+
+	ret = hdd_init_mws_coex(hdd_ctx);
+	if (ret)
+		hdd_warn("Error initializing mws-coex");
+
+	cfg = hdd_ctx->config;
+	/* FW capabilities received, Set the Dot11 mode */
+	mac_handle = hdd_ctx->mac_handle;
+	sme_setdef_dot11mode(mac_handle);
+	sme_set_etsi13_srd_ch_in_master_mode(mac_handle,
+					     cfg->
+					     etsi13_srd_chan_in_master_mode);
+
+	if (hdd_ctx->config->fIsImpsEnabled)
+		hdd_set_idle_ps_config(hdd_ctx, true);
+	else
+		hdd_set_idle_ps_config(hdd_ctx, false);
+
+	/* Send Enable/Disable data stall detection cmd to FW */
+	sme_cli_set_command(0, WMI_PDEV_PARAM_DATA_STALL_DETECT_ENABLE,
+	cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
+		    cfg_dp_enable_data_stall), PDEV_CMD);
+
+	ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self);
+	if (b_cts2self)
+		sme_set_cts2self_for_p2p_go(mac_handle);
+
+	if (hdd_set_vc_mode_config(hdd_ctx))
+		hdd_warn("Error in setting Voltage Corner mode config to FW");
+
+	if (hdd_rx_ol_init(hdd_ctx))
+		hdd_err("Unable to initialize Rx LRO/GRO in fw");
+
+	if (hdd_adaptive_dwelltime_init(hdd_ctx))
+		hdd_err("Unable to send adaptive dwelltime setting to FW");
+
+	if (hdd_dbs_scan_selection_init(hdd_ctx))
+		hdd_err("Unable to send DBS scan selection setting to FW");
+
+	ret = hdd_init_thermal_info(hdd_ctx);
+	if (ret) {
+		hdd_err("Error while initializing thermal information");
+		return ret;
+	}
+
+	/**
+	 * In case of SSR/PDR, if pktlog was enabled manually before
+	 * SSR/PDR, Then enabled it again automatically after Wlan
+	 * device up.
+	 */
+	if (cds_is_driver_recovering()) {
+		if (hdd_ctx->is_pktlog_enabled)
+			hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
+	} else if (cds_is_packet_log_enabled())
+		hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
+
+	hddtxlimit.txPower2g = hdd_ctx->config->TxPower2g;
+	hddtxlimit.txPower5g = hdd_ctx->config->TxPower5g;
+	status = sme_txpower_limit(mac_handle, &hddtxlimit);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("Error setting txlimit in sme: %d", status);
+
+	wlan_hdd_tsf_init(hdd_ctx);
+
+	status = sme_enable_disable_chanavoidind_event(mac_handle, 0);
+	if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) {
+		hdd_err("Failed to disable Chan Avoidance Indication");
+		return -EINVAL;
+	}
+
+	/* register P2P Listen Offload event callback */
+	if (wma_is_p2p_lo_capable())
+		sme_register_p2p_lo_event(mac_handle, hdd_ctx,
+					  wlan_hdd_p2p_lo_event_callback);
+
+	ret = hdd_set_auto_shutdown_cb(hdd_ctx);
+
+	if (ret)
+		return -EINVAL;
+
+	wlan_hdd_init_chan_info(hdd_ctx);
+	wlan_hdd_twt_init(hdd_ctx);
+
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * hdd_features_deinit() - Deinit features
+ * @hdd_ctx:	HDD context
+ *
+ * De-Initialize features and their feature context.
+ *
+ * Return: none.
+ */
+static void hdd_features_deinit(struct hdd_context *hdd_ctx)
+{
+	wlan_hdd_twt_deinit(hdd_ctx);
+	wlan_hdd_deinit_chan_info(hdd_ctx);
+	wlan_hdd_tsf_deinit(hdd_ctx);
+}
+
+/**
+ * hdd_register_bcn_cb() - register scan beacon callback
+ * @hdd_ctx - Pointer to the HDD context
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+
+	status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
+		wlan_cfg80211_inform_bss_frame,
+		SCAN_CB_TYPE_INFORM_BCN);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("failed with status code %08d [x%08x]",
+			status, status);
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active
+ * @vdev_id: vdev_id, corresponds to flow_pool
+ *
+ * Return: none.
+ */
+static void hdd_v2_flow_pool_map(int vdev_id)
+{
+	QDF_STATUS status;
+
+	status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
+				   cds_get_context(QDF_MODULE_ID_TXRX),
+				   vdev_id);
+	/*
+	 * For Adrastea flow control v2 is based on FW MAP events,
+	 * so this above callback is not implemented.
+	 * Hence this is not actual failure. Dont return failure
+	 */
+	if ((status != QDF_STATUS_SUCCESS) &&
+	    (status != QDF_STATUS_E_INVAL)) {
+		hdd_err("vdev_id: %d, failed to create flow pool status %d",
+			vdev_id, status);
+	}
+}
+
+/**
+ * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active
+ * @vdev_id: vdev_id, corresponds to flow_pool
+ *
+ * Return: none.
+ */
+static void hdd_v2_flow_pool_unmap(int vdev_id)
+{
+	cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
+			    cds_get_context(QDF_MODULE_ID_TXRX), vdev_id);
+}
+
+/**
+ * hdd_action_oui_config() - Configure action_oui strings
+ * @hdd_ctx: pointer to hdd context
+ *
+ * This is a HDD wrapper function which invokes ucfg api
+ * of action_oui component to parse action oui strings.
+ *
+ * Return: None
+ */
+static void hdd_action_oui_config(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	uint32_t id;
+	uint8_t *str;
+
+	if (!hdd_ctx->config->action_oui_enable)
+		return;
+
+	for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
+		str = hdd_ctx->config->action_oui_str[id];
+		if (!qdf_str_len(str))
+			continue;
+
+		status = ucfg_action_oui_parse(hdd_ctx->psoc, str, id);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("Failed to parse action_oui str: %u", id);
+	}
+}
+
+/**
+ * hdd_action_oui_send() - Send action_oui extensions to firmware
+ * @hdd_ctx: pointer to hdd context
+ *
+ * This is a HDD wrapper function which invokes ucfg api
+ * of action_oui component to send action oui extensions to firmware.
+ *
+ * Return: None
+ */
+static void hdd_action_oui_send(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+
+	if (!hdd_ctx->config->action_oui_enable)
+		return;
+
+	status = ucfg_action_oui_send(hdd_ctx->psoc);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("Failed to send one or all action_ouis");
+}
+
+/**
+ * hdd_configure_cds() - Configure cds modules
+ * @hdd_ctx:	HDD context
+ * @adapter:	Primary adapter context
+ *
+ * Enable Cds modules after WLAN firmware is up.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+int hdd_configure_cds(struct hdd_context *hdd_ctx)
+{
+	int ret;
+	QDF_STATUS status;
+	int set_value;
+	mac_handle_t mac_handle;
+	bool enable_rts_sifsbursting;
+	uint8_t enable_phy_reg_retention;
+	uint8_t max_mpdus_inampdu;
+	uint32_t num_abg_tx_chains = 0;
+	uint16_t num_11b_tx_chains = 0;
+	uint16_t num_11ag_tx_chains = 0;
+	struct policy_mgr_dp_cbacks dp_cbs = {0};
+	bool value;
+	enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode;
+	bool bval = false;
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	hdd_action_oui_send(hdd_ctx);
+
+	if (hdd_ctx->config->is_force_1x1)
+		sme_cli_set_command(0, (int)WMI_PDEV_PARAM_SET_IOT_PATTERN,
+				1, PDEV_CMD);
+	/* set chip power save failure detected callback */
+	sme_set_chip_pwr_save_fail_cb(mac_handle,
+				      hdd_chip_pwr_save_fail_detected_cb);
+
+	status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc,
+					    &max_mpdus_inampdu);
+	if (status)
+		return status;
+
+	if (max_mpdus_inampdu) {
+		set_value = max_mpdus_inampdu;
+		sme_cli_set_command(0, (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
+				    set_value, PDEV_CMD);
+	}
+
+	status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc,
+						  &enable_rts_sifsbursting);
+	if (status)
+		return status;
+
+	if (enable_rts_sifsbursting) {
+		set_value = enable_rts_sifsbursting;
+		sme_cli_set_command(0,
+				    (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
+				    set_value, PDEV_CMD);
+	}
+
+	ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
+	if (value) {
+		set_value = value;
+		sme_cli_set_command(0,
+				    (int)WMI_PDEV_PARAM_PEER_STATS_INFO_ENABLE,
+				    set_value, PDEV_CMD);
+	}
+
+	status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc,
+						 &num_11b_tx_chains);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to get num_11b_tx_chains");
+		goto out;
+	}
+
+	status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc,
+						  &num_11ag_tx_chains);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to get num_11ag_tx_chains");
+		goto out;
+	}
+
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+
+	if (!bval) {
+		if (num_11b_tx_chains > 1)
+			num_11b_tx_chains = 1;
+		if (num_11ag_tx_chains > 1)
+			num_11ag_tx_chains = 1;
+	}
+	WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
+					    num_11b_tx_chains);
+	WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
+					     num_11ag_tx_chains);
+	sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
+			    num_abg_tx_chains, PDEV_CMD);
+
+	if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc))
+		ucfg_reg_program_default_cc(hdd_ctx->pdev,
+					    hdd_ctx->reg.reg_domain);
+
+	ret = hdd_pre_enable_configure(hdd_ctx);
+	if (ret) {
+		hdd_err("Failed to pre-configure cds");
+		goto out;
+	}
+
+	/* Always get latest IPA resources allocated from cds_open and configure
+	 * IPA module before configuring them to FW. Sequence required as crash
+	 * observed otherwise.
+	 */
+	if (ucfg_ipa_uc_ol_init(hdd_ctx->pdev,
+				cds_get_context(QDF_MODULE_ID_QDF_DEVICE))) {
+		hdd_err("Failed to setup pipes");
+		goto out;
+	}
+
+	/*
+	 * Start CDS which starts up the SME/MAC/HAL modules and everything
+	 * else
+	 */
+	status = cds_enable(hdd_ctx->psoc);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("cds_enable failed");
+		goto out;
+	}
+
+	status = hdd_post_cds_enable_config(hdd_ctx);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("hdd_post_cds_enable_config failed");
+		goto cds_disable;
+	}
+	status = hdd_register_bcn_cb(hdd_ctx);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("hdd_register_bcn_cb failed");
+		goto cds_disable;
+	}
+
+	ret = hdd_features_init(hdd_ctx);
+	if (ret)
+		goto cds_disable;
+
+	if (hdd_ctx->ol_enable)
+		dp_cbs.hdd_disable_rx_ol_in_concurrency =
+				hdd_disable_rx_ol_in_concurrency;
+	dp_cbs.hdd_set_rx_mode_rps_cb = hdd_set_rx_mode_rps;
+	dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
+	dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
+	dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
+	status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_debug("Failed to register DP cb with Policy Manager");
+		goto cds_disable;
+	}
+	status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc,
+					       wlan_hdd_send_mode_change_event);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_debug("Failed to register mode change cb with Policy Manager");
+		goto cds_disable;
+	}
+
+	if (hdd_green_ap_enable_egap(hdd_ctx))
+		hdd_debug("enhance green ap is not enabled");
+
+	if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
+		hdd_debug("Failed to set wow pulse");
+
+	sme_cli_set_command(0, WMI_PDEV_PARAM_GCMP_SUPPORT_ENABLE,
+			    hdd_ctx->config->gcmp_enabled, PDEV_CMD);
+
+	auto_power_fail_mode =
+		ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc);
+	sme_cli_set_command(0, WMI_PDEV_AUTO_DETECT_POWER_FAILURE,
+			    auto_power_fail_mode, PDEV_CMD);
+
+	status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc,
+						   &enable_phy_reg_retention);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
+
+	if (enable_phy_reg_retention)
+		wma_cli_set_command(0, WMI_PDEV_PARAM_FAST_PWR_TRANSITION,
+			enable_phy_reg_retention, PDEV_CMD);
+
+	return 0;
+
+cds_disable:
+	cds_disable(hdd_ctx->psoc);
+
+out:
+	return -EINVAL;
+}
+
+/**
+ * hdd_deconfigure_cds() -De-Configure cds
+ * @hdd_ctx:	HDD context
+ *
+ * Deconfigure Cds modules before WLAN firmware is down.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS qdf_status;
+	int ret = 0;
+
+	hdd_enter();
+
+	/* De-init features */
+	hdd_features_deinit(hdd_ctx);
+
+	qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		hdd_debug("Failed to deregister mode change cb with Policy Manager");
+
+	qdf_status = cds_disable(hdd_ctx->psoc);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Failed to Disable the CDS Modules! :%d",
+			qdf_status);
+		ret = -EINVAL;
+	}
+
+	if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to disconnect pipes");
+		ret = -EINVAL;
+	}
+
+	hdd_exit();
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+static void hdd_deregister_policy_manager_callback(
+			struct wlan_objmgr_psoc *psoc)
+{
+	if (QDF_STATUS_SUCCESS !=
+	    policy_mgr_deregister_hdd_cb(psoc)) {
+		hdd_err("HDD callback deregister with policy manager failed");
+	}
+}
+#else
+static void hdd_deregister_policy_manager_callback(
+			struct wlan_objmgr_psoc *psoc)
+{
+}
+#endif
+
+/**
+ * hdd_wlan_stop_modules - Single driver state machine for stoping modules
+ * @hdd_ctx: HDD context
+ * @ftm_mode: ftm mode
+ *
+ * This function maintains the driver state machine it will be invoked from
+ * exit, shutdown and con_mode change handler. Depending on the driver state
+ * shall perform the stopping/closing of the modules.
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
+{
+	void *hif_ctx;
+	qdf_device_t qdf_ctx;
+	QDF_STATUS qdf_status;
+	bool is_recovery_stop = cds_is_driver_recovering();
+	int ret = 0;
+	int active_threads;
+	int debugfs_threads;
+	struct target_psoc_info *tgt_hdl;
+
+	hdd_enter();
+
+	hdd_deregister_policy_manager_callback(hdd_ctx->psoc);
+
+	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	if (!qdf_ctx) {
+		hdd_err("QDF device context NULL");
+		return -EINVAL;
+	}
+
+	mutex_lock(&hdd_ctx->iface_change_lock);
+	hdd_ctx->stop_modules_in_progress = true;
+	cds_set_module_stop_in_progress(true);
+
+	active_threads = cds_return_external_threads_count();
+	debugfs_threads = hdd_return_debugfs_threads_count();
+
+	if (active_threads > 0 || debugfs_threads > 0 ||
+	    hdd_ctx->is_wiphy_suspended) {
+		hdd_warn("External threads %d, Debugfs threads %d, wiphy suspend %d",
+			 active_threads, debugfs_threads,
+			 hdd_ctx->is_wiphy_suspended);
+
+		if (active_threads)
+			cds_print_external_threads();
+
+		if (IS_IDLE_STOP && !ftm_mode) {
+			mutex_unlock(&hdd_ctx->iface_change_lock);
+			hdd_psoc_idle_timer_start(hdd_ctx);
+			hdd_ctx->stop_modules_in_progress = false;
+			cds_set_module_stop_in_progress(false);
+
+			return 0;
+		}
+	}
+
+	/* free user wowl patterns */
+	hdd_free_user_wowl_ptrns();
+
+	switch (hdd_ctx->driver_status) {
+	case DRIVER_MODULES_UNINITIALIZED:
+		hdd_debug("Modules not initialized just return");
+		goto done;
+	case DRIVER_MODULES_CLOSED:
+		hdd_debug("Modules already closed");
+		goto done;
+	case DRIVER_MODULES_ENABLED:
+		hdd_info("Wlan transitioning (CLOSED <- ENABLED)");
+
+		if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE)
+			break;
+
+		hdd_disable_power_management();
+		if (hdd_deconfigure_cds(hdd_ctx)) {
+			hdd_err("Failed to de-configure CDS");
+			QDF_ASSERT(0);
+			ret = -EINVAL;
+		}
+		hdd_debug("successfully Disabled the CDS modules!");
+
+		break;
+	default:
+		QDF_DEBUG_PANIC("Unknown driver state:%d",
+				hdd_ctx->driver_status);
+		ret = -EINVAL;
+		goto done;
+	}
+
+	hdd_sysfs_destroy_powerstats_interface();
+	hdd_sysfs_destroy_version_interface();
+	hdd_sysfs_destroy_driver_root_obj();
+	hdd_debug("Closing CDS modules!");
+
+	qdf_status = cds_post_disable();
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Failed to process post CDS disable Modules! :%d",
+			qdf_status);
+		ret = -EINVAL;
+		QDF_ASSERT(0);
+	}
+
+	/* De-register the SME callbacks */
+	hdd_deregister_cb(hdd_ctx);
+
+	hdd_runtime_suspend_context_deinit(hdd_ctx);
+
+	qdf_status = cds_dp_close(hdd_ctx->psoc);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_warn("Failed to stop CDS DP: %d", qdf_status);
+		ret = -EINVAL;
+		QDF_ASSERT(0);
+	}
+
+	qdf_status = cds_close(hdd_ctx->psoc);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_warn("Failed to stop CDS: %d", qdf_status);
+		ret = -EINVAL;
+		QDF_ASSERT(0);
+	}
+
+	qdf_status = wbuff_module_deinit();
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		hdd_err("WBUFF de-init unsuccessful; status: %d", qdf_status);
+
+	hdd_component_pdev_close(hdd_ctx->pdev);
+
+	hdd_component_psoc_close(hdd_ctx->psoc);
+	dispatcher_pdev_close(hdd_ctx->pdev);
+	ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
+	if (ret) {
+		hdd_err("Failed to destroy pdev; errno:%d", ret);
+		QDF_ASSERT(0);
+	}
+
+	/*
+	 * Reset total mac phy during module stop such that during
+	 * next module start same psoc is used to populate new service
+	 * ready data
+	 */
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
+	if (tgt_hdl)
+		target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
+
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!hif_ctx) {
+		hdd_err("Hif context is Null");
+		ret = -EINVAL;
+	}
+
+	if (hdd_ctx->target_hw_name) {
+		qdf_mem_free(hdd_ctx->target_hw_name);
+		hdd_ctx->target_hw_name = NULL;
+	}
+
+	hdd_hif_close(hdd_ctx, hif_ctx);
+
+	ol_cds_free();
+
+	if (IS_IDLE_STOP) {
+		ret = pld_power_off(qdf_ctx->dev);
+		if (ret)
+			hdd_err("Failed to power down device; errno:%d", ret);
+	}
+
+	/* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
+	wlan_hdd_free_cache_channels(hdd_ctx);
+
+	hdd_check_for_leaks(hdd_ctx, is_recovery_stop);
+	hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
+
+	/* Once the firmware sequence is completed reset this flag */
+	hdd_ctx->imps_enabled = false;
+	hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
+	hdd_info("Wlan transitioned (now CLOSED)");
+
+done:
+	hdd_ctx->stop_modules_in_progress = false;
+	cds_set_module_stop_in_progress(false);
+	mutex_unlock(&hdd_ctx->iface_change_lock);
+
+	hdd_exit();
+
+	return ret;
+}
+
+
+#ifdef WLAN_FEATURE_MEMDUMP_ENABLE
+/**
+ * hdd_state_info_dump() - prints state information of hdd layer
+ * @buf: buffer pointer
+ * @size: size of buffer to be filled
+ *
+ * This function is used to dump state information of hdd layer
+ *
+ * Return: None
+ */
+static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_station_ctx *hdd_sta_ctx;
+	struct hdd_adapter *adapter;
+	uint16_t len = 0;
+	char *buf = *buf_ptr;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("Failed to get hdd context ");
+		return;
+	}
+
+	hdd_debug("size of buffer: %d", *size);
+
+	len += scnprintf(buf + len, *size - len,
+		"\n is_wiphy_suspended %d", hdd_ctx->is_wiphy_suspended);
+	len += scnprintf(buf + len, *size - len,
+		"\n is_scheduler_suspended %d",
+		hdd_ctx->is_scheduler_suspended);
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter->dev)
+			len += scnprintf(buf + len, *size - len,
+				"\n device name: %s", adapter->dev->name);
+		len += scnprintf(buf + len, *size - len,
+				"\n device_mode: %d", adapter->device_mode);
+		switch (adapter->device_mode) {
+		case QDF_STA_MODE:
+		case QDF_P2P_CLIENT_MODE:
+			hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+			len += scnprintf(buf + len, *size - len,
+				"\n connState: %d",
+				hdd_sta_ctx->conn_info.connState);
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	*size -= len;
+	*buf_ptr += len;
+}
+
+/**
+ * hdd_register_debug_callback() - registration function for hdd layer
+ * to print hdd state information
+ *
+ * Return: None
+ */
+static void hdd_register_debug_callback(void)
+{
+	qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
+}
+#else /* WLAN_FEATURE_MEMDUMP_ENABLE */
+static void hdd_register_debug_callback(void)
+{
+}
+#endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
+
+/*
+ * wlan_init_bug_report_lock() - Initialize bug report lock
+ *
+ * This function is used to create bug report lock
+ *
+ * Return: None
+ */
+static void wlan_init_bug_report_lock(void)
+{
+	struct cds_context *p_cds_context;
+
+	p_cds_context = cds_get_global_context();
+	if (!p_cds_context) {
+		hdd_err("cds context is NULL");
+		return;
+	}
+
+	qdf_spinlock_create(&p_cds_context->bug_report_lock);
+}
+
+#ifdef CONFIG_DP_TRACE
+void hdd_dp_trace_init(struct hdd_config *config)
+{
+	bool live_mode = DP_TRACE_CONFIG_DEFAULT_LIVE_MODE;
+	uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH;
+	uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT;
+	uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY;
+	uint8_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP;
+	uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS];
+	uint8_t num_entries = 0;
+	uint32_t bw_compute_interval;
+
+	if (!config->enable_dp_trace) {
+		hdd_err("dp trace is disabled from ini");
+		return;
+	}
+
+	hdd_string_to_u8_array(config->dp_trace_config, config_params,
+				&num_entries, sizeof(config_params));
+
+	/* calculating, num bw timer intervals in a second (1000ms) */
+	bw_compute_interval = GET_BW_COMPUTE_INTV(config);
+	if (bw_compute_interval <= 1000 && bw_compute_interval > 0)
+		thresh_time_limit = 1000 / bw_compute_interval;
+	else if (bw_compute_interval > 1000) {
+		hdd_err("busBandwidthComputeInterval > 1000, using 1000");
+		thresh_time_limit = 1;
+	} else
+		hdd_err("busBandwidthComputeInterval is 0, using defaults");
+
+	switch (num_entries) {
+	case 4:
+		proto_bitmap = config_params[3];
+		/* fall through */
+	case 3:
+		verbosity = config_params[2];
+		/* fall through */
+	case 2:
+		thresh = config_params[1];
+		/* fall through */
+	case 1:
+		live_mode = config_params[0];
+		/* fall through */
+	default:
+		hdd_debug("live_mode %u thresh %u time_limit %u verbosity %u bitmap 0x%x",
+			  live_mode, thresh, thresh_time_limit,
+			  verbosity, proto_bitmap);
+	};
+
+	qdf_dp_trace_init(live_mode, thresh, thresh_time_limit,
+			verbosity, proto_bitmap);
+
+}
+#endif
+
+#ifdef DISABLE_CHANNEL_LIST
+static int wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
+{
+	return qdf_mutex_create(&hdd_ctx->cache_channel_lock);
+}
+#else
+static int wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+#endif
+
+static QDF_STATUS
+hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+	enum dot11p_mode dot11p_mode;
+	QDF_STATUS status;
+
+	ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
+
+	/* Create only 802.11p interface? */
+	if (dot11p_mode == CFG_11P_STANDALONE)
+		return hdd_open_ocb_interface(hdd_ctx);
+
+	adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE, "wlan%d",
+				   wlan_hdd_get_intf_addr(hdd_ctx),
+				   NET_NAME_UNKNOWN, true);
+	if (!adapter)
+		return QDF_STATUS_E_INVAL;
+
+	/* opening concurrent STA is best effort, continue on error */
+	hdd_open_concurrent_interface(hdd_ctx);
+
+	status = hdd_open_p2p_interface(hdd_ctx);
+	if (status)
+		goto err_close_adapters;
+
+	/* Open 802.11p Interface */
+	if (dot11p_mode == CFG_11P_CONCURRENT) {
+		status = hdd_open_ocb_interface(hdd_ctx);
+		if (QDF_IS_STATUS_ERROR(status))
+			goto err_close_adapters;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+err_close_adapters:
+	hdd_close_all_adapters(hdd_ctx, true);
+
+	return status;
+}
+
+static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
+				   wlan_hdd_get_intf_addr(hdd_ctx),
+				   NET_NAME_UNKNOWN, true);
+
+	return adapter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
+}
+
+static QDF_STATUS
+hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
+				   wlan_hdd_get_intf_addr(hdd_ctx),
+				   NET_NAME_UNKNOWN, true);
+
+	return adapter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
+}
+
+static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	qdf_device_t qdf_dev;
+
+	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	QDF_BUG(qdf_dev);
+	if (!qdf_dev)
+		return QDF_STATUS_E_INVAL;
+
+	status = epping_open();
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	if (epping_enable(qdf_dev->dev)) {
+		status = QDF_STATUS_E_INVAL;
+		goto epping_close;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+epping_close:
+	epping_close();
+
+	return status;
+}
+
+typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx);
+
+static const hdd_open_mode_handler
+hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = {
+	[QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode,
+	[QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode,
+	[QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode,
+	[QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode,
+};
+
+static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
+					     enum QDF_GLOBAL_MODE driver_mode)
+{
+	QDF_STATUS status;
+
+	if (driver_mode < 0 ||
+	    driver_mode >= QDF_GLOBAL_MAX_MODE ||
+	    !hdd_open_mode_handlers[driver_mode]) {
+		hdd_err("Driver mode %d not supported", driver_mode);
+		return -ENOTSUPP;
+	}
+
+	hdd_hold_rtnl_lock();
+	status = hdd_open_mode_handlers[driver_mode](hdd_ctx);
+	hdd_release_rtnl_lock();
+
+	return status;
+}
+
+int hdd_wlan_startup(struct device *dev, struct hdd_context **out_hdd_ctx)
+{
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx;
+	int ret;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+
+	hdd_ctx = hdd_context_create(dev);
+	if (IS_ERR(hdd_ctx))
+		return PTR_ERR(hdd_ctx);
+
+	hdd_action_oui_config(hdd_ctx);
+
+	qdf_nbuf_init_replenish_timer();
+
+	ret = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
+	if (QDF_IS_STATUS_ERROR(ret))
+		goto err_hdd_free_context;
+
+#ifdef FEATURE_WLAN_CH_AVOID
+	mutex_init(&hdd_ctx->avoid_freq_lock);
+#endif
+
+	osif_request_manager_init();
+	qdf_atomic_init(&hdd_ctx->con_mode_flag);
+	hdd_driver_memdump_init();
+	hdd_bus_bandwidth_init(hdd_ctx);
+
+	ret = hdd_wlan_start_modules(hdd_ctx, false);
+	if (ret) {
+		hdd_err("Failed to start modules: %d", ret);
+		goto err_memdump_deinit;
+	}
+
+	wlan_hdd_update_wiphy(hdd_ctx);
+
+	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
+	hdd_ctx->mac_handle = mac_handle;
+	if (!mac_handle) {
+		hdd_err("Mac Handle is null");
+		goto err_stop_modules;
+	}
+
+	ret = hdd_wiphy_init(hdd_ctx);
+	if (ret) {
+		hdd_err("Failed to initialize wiphy: %d", ret);
+		goto err_stop_modules;
+	}
+
+	hdd_dp_trace_init(hdd_ctx->config);
+
+	hdd_initialize_mac_address(hdd_ctx);
+
+	ret = register_netdevice_notifier(&hdd_netdev_notifier);
+	if (ret) {
+		hdd_err("register_netdevice_notifier failed: %d", ret);
+		goto err_wiphy_unregister;
+	}
+
+	ret = register_reboot_notifier(&system_reboot_notifier);
+	if (ret) {
+		hdd_err("Failed to register reboot notifier: %d", ret);
+		goto err_unregister_netdev;
+	}
+
+	wlan_hdd_update_11n_mode(hdd_ctx->config);
+
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+	status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
+				   QDF_TIMER_TYPE_SW,
+				   hdd_skip_acs_scan_timer_handler,
+				   hdd_ctx);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to init ACS Skip timer");
+
+	qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
+#endif
+
+	hdd_lpass_notify_wlan_version(hdd_ctx);
+
+	ret = hdd_register_notifiers(hdd_ctx);
+	if (ret)
+		goto err_close_adapters;
+
+	status = wlansap_global_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto unregister_notifiers;
+
+	hdd_set_idle_ps_config(hdd_ctx, hdd_ctx->config->fIsImpsEnabled);
+
+	*out_hdd_ctx = hdd_ctx;
+
+	hdd_exit();
+
+	return 0;
+
+unregister_notifiers:
+	hdd_unregister_notifiers(hdd_ctx);
+
+err_close_adapters:
+	hdd_close_all_adapters(hdd_ctx, false);
+
+	unregister_reboot_notifier(&system_reboot_notifier);
+
+err_unregister_netdev:
+	unregister_netdevice_notifier(&hdd_netdev_notifier);
+
+err_wiphy_unregister:
+	qdf_dp_trace_deinit();
+	wiphy_unregister(hdd_ctx->wiphy);
+
+err_stop_modules:
+	hdd_wlan_stop_modules(hdd_ctx, false);
+
+err_memdump_deinit:
+	hdd_bus_bandwidth_deinit(hdd_ctx);
+	hdd_driver_memdump_deinit();
+
+	osif_request_manager_deinit();
+	hdd_exit_netlink_services(hdd_ctx);
+
+err_hdd_free_context:
+	if (cds_is_fw_down())
+		hdd_err("Not setting the complete event as fw is down");
+	else
+		hdd_start_complete(ret);
+
+	qdf_nbuf_deinit_replenish_timer();
+	hdd_context_destroy(hdd_ctx);
+
+	hdd_exit();
+
+	return ret;
+}
+
+QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx)
+{
+	enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam();
+	QDF_STATUS status;
+
+	status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to create vdevs; status:%d", status);
+		return status;
+	}
+
+	if (hdd_ctx->rps)
+		hdd_set_rps_cpu_mask(hdd_ctx);
+
+	if (driver_mode != QDF_GLOBAL_FTM_MODE)
+		hdd_psoc_idle_timer_start(hdd_ctx);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_wlan_update_target_info() - update target type info
+ * @hdd_ctx: HDD context
+ * @context: hif context
+ *
+ * Update target info received from firmware in hdd context
+ * Return:None
+ */
+
+void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
+{
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
+
+	if (!tgt_info) {
+		hdd_err("Target info is Null");
+		return;
+	}
+
+	hdd_ctx->target_type = tgt_info->target_type;
+}
+
+void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp, void *context)
+{
+	struct hdd_context *hdd_ctx = (struct hdd_context *)data;
+	int status;
+	struct hdd_adapter *adapter = NULL;
+	struct osif_request *request = NULL;
+
+	hdd_enter();
+
+	if (!rsp) {
+		hdd_err("data is null");
+		return;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status != 0)
+		return;
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("obselete request");
+		return;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, rsp->vdev_id);
+	if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		hdd_err("Invalid adapter or adapter has invalid magic");
+		osif_request_put(request);
+		return;
+	}
+
+	hdd_debug("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue);
+	hdd_debug("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success);
+	hdd_debug("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure);
+	hdd_debug("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd);
+	hdd_debug("rsp->out_of_order_arp_rsp_drop_cnt :%x",
+		  rsp->out_of_order_arp_rsp_drop_cnt);
+	hdd_debug("rsp->dad_detected :%x", rsp->dad_detected);
+	hdd_debug("rsp->connect_status :%x", rsp->connect_status);
+	hdd_debug("rsp->ba_session_establishment_status :%x",
+		  rsp->ba_session_establishment_status);
+
+	adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd;
+	adapter->dad |= rsp->dad_detected;
+	adapter->con_status = rsp->connect_status;
+
+	/* Flag true indicates connectivity check stats present. */
+	if (rsp->connect_stats_present) {
+		hdd_debug("rsp->tcp_ack_recvd :%x", rsp->tcp_ack_recvd);
+		hdd_debug("rsp->icmpv4_rsp_recvd :%x", rsp->icmpv4_rsp_recvd);
+		adapter->hdd_stats.hdd_tcp_stats.rx_fw_cnt = rsp->tcp_ack_recvd;
+		adapter->hdd_stats.hdd_icmpv4_stats.rx_fw_cnt =
+							rsp->icmpv4_rsp_recvd;
+	}
+
+	osif_request_complete(request);
+	osif_request_put(request);
+
+	hdd_exit();
+}
+
+/**
+ * hdd_register_cb - Register HDD callbacks.
+ * @hdd_ctx: HDD context
+ *
+ * Register the HDD callbacks to CDS/SME.
+ *
+ * Return: 0 for success or Error code for failure
+ */
+int hdd_register_cb(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	int ret = 0;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("in ftm mode, no need to register callbacks");
+		return ret;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	sme_register_oem_data_rsp_callback(mac_handle,
+					   hdd_send_oem_data_rsp_msg);
+
+	sme_register_mgmt_frame_ind_callback(mac_handle,
+					     hdd_indicate_mgmt_frame);
+	sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx);
+	sme_nan_register_callback(mac_handle,
+				  wlan_hdd_cfg80211_nan_callback);
+	sme_stats_ext_register_callback(mac_handle,
+					wlan_hdd_cfg80211_stats_ext_callback);
+
+	sme_ext_scan_register_callback(mac_handle,
+					wlan_hdd_cfg80211_extscan_callback);
+	sme_stats_ext2_register_callback(mac_handle,
+					wlan_hdd_cfg80211_stats_ext2_callback);
+
+	sme_set_rssi_threshold_breached_cb(mac_handle,
+					   hdd_rssi_threshold_breached);
+
+	sme_set_link_layer_stats_ind_cb(mac_handle,
+				wlan_hdd_cfg80211_link_layer_stats_callback);
+
+	sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb);
+
+	sme_set_link_layer_ext_cb(mac_handle,
+			wlan_hdd_cfg80211_link_layer_stats_ext_callback);
+
+	status = sme_set_lost_link_info_cb(mac_handle,
+					   hdd_lost_link_info_cb);
+	/* print error and not block the startup process */
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("set lost link info callback failed");
+
+	ret = hdd_register_data_stall_detect_cb();
+	if (ret) {
+		hdd_err("Register data stall detect detect callback failed.");
+		return ret;
+	}
+
+	wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
+
+	sme_register_set_connection_info_cb(mac_handle,
+					    hdd_set_connection_in_progress,
+					    hdd_is_connection_in_progress);
+
+	status = sme_congestion_register_callback(mac_handle,
+						  hdd_update_cca_info_cb);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("set congestion callback failed");
+
+	status = sme_set_bt_activity_info_cb(mac_handle,
+					     hdd_bt_activity_cb);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("set bt activity info callback failed");
+
+	status = sme_register_tx_queue_cb(mac_handle,
+					  hdd_tx_queue_cb);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("Register tx queue callback failed");
+
+	hdd_exit();
+
+	return ret;
+}
+
+/**
+ * hdd_deregister_cb() - De-Register HDD callbacks.
+ * @hdd_ctx: HDD context
+ *
+ * De-Register the HDD callbacks to CDS/SME.
+ *
+ * Return: void
+ */
+void hdd_deregister_cb(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	int ret;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("in ftm mode, no need to deregister callbacks");
+		return;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	sme_deregister_tx_queue_cb(mac_handle);
+	status = sme_deregister_for_dcc_stats_event(mac_handle);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("De-register of dcc stats callback failed: %d",
+			status);
+
+	sme_reset_link_layer_stats_ind_cb(mac_handle);
+	sme_reset_rssi_threshold_breached_cb(mac_handle);
+
+	sme_stats_ext_register_callback(mac_handle,
+					wlan_hdd_cfg80211_stats_ext_callback);
+
+	sme_nan_deregister_callback(mac_handle);
+	status = sme_reset_tsfcb(mac_handle);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("Failed to de-register tsfcb the callback:%d",
+			status);
+
+	ret = hdd_deregister_data_stall_detect_cb();
+	if (ret)
+		hdd_err("Failed to de-register data stall detect event callback");
+
+	sme_deregister_oem_data_rsp_callback(mac_handle);
+
+	hdd_exit();
+}
+
+/**
+ * hdd_softap_sta_deauth() - handle deauth req from HDD
+ * @adapter:	Pointer to the HDD
+ * @enable:	bool value
+ *
+ * This to take counter measure to handle deauth req from HDD
+ *
+ * Return: None
+ */
+QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
+				 struct csr_del_sta_params *pDelStaParams)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
+
+	hdd_enter();
+
+	/* Ignore request to deauth bcmc station */
+	if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
+		return qdf_status;
+
+	qdf_status =
+		wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+				   pDelStaParams);
+
+	hdd_exit();
+	return qdf_status;
+}
+
+/**
+ * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
+ * @adapter:	Pointer to the HDD
+ * @p_del_sta_params: pointer to station deletion parameters
+ *
+ * This to take counter measure to handle deauth req from HDD
+ *
+ * Return: None
+ */
+void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
+			     struct csr_del_sta_params *pDelStaParams)
+{
+	hdd_enter();
+
+	/* Ignore request to disassoc bcmc station */
+	if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
+		return;
+
+	wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+			     pDelStaParams);
+}
+
+/**
+ * hdd_issta_p2p_clientconnected() - check if sta or p2p client is connected
+ * @hdd_ctx:	HDD Context
+ *
+ * API to find if there is any STA or P2P-Client is connected
+ *
+ * Return: true if connected; false otherwise
+ */
+QDF_STATUS hdd_issta_p2p_clientconnected(struct hdd_context *hdd_ctx)
+{
+	return sme_is_sta_p2p_client_connected(hdd_ctx->mac_handle);
+}
+
+void wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
+	struct hdd_adapter *adapter = NULL;
+	struct csr_roam_profile *roam_profile;
+	struct hdd_station_ctx *sta_ctx;
+
+	if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
+		hdd_debug("No active sta session");
+		return;
+	}
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		roam_profile = hdd_roam_profile(adapter);
+		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+		if (cur_adapter->session_id != adapter->session_id &&
+		    adapter->device_mode == QDF_STA_MODE &&
+		    hdd_conn_is_connected(sta_ctx)) {
+			hdd_debug("%d Disable roaming", adapter->session_id);
+			sme_stop_roaming(hdd_ctx->mac_handle,
+					 adapter->session_id,
+					 ecsr_driver_disabled);
+		}
+	}
+}
+
+void wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
+	struct hdd_adapter *adapter = NULL;
+	struct csr_roam_profile *roam_profile;
+	struct hdd_station_ctx *sta_ctx;
+
+	if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
+		hdd_debug("No active sta session");
+		return;
+	}
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		roam_profile = hdd_roam_profile(adapter);
+		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+		if (cur_adapter->session_id != adapter->session_id &&
+		    adapter->device_mode == QDF_STA_MODE &&
+		    hdd_conn_is_connected(sta_ctx)) {
+			hdd_debug("%d Enable roaming", adapter->session_id);
+			sme_start_roaming(hdd_ctx->mac_handle,
+					  adapter->session_id,
+					  REASON_DRIVER_ENABLED);
+		}
+	}
+}
+
+/**
+ * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
+ * @skb: sk buffer pointer
+ *
+ * Sends the bcast message to SVC multicast group with generic nl socket
+ * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
+ *
+ * Return: None
+ */
+static void nl_srv_bcast_svc(struct sk_buff *skb)
+{
+#ifdef CNSS_GENL
+	nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
+#else
+	nl_srv_bcast(skb);
+#endif
+}
+
+void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
+{
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	tAniMsgHdr *ani_hdr;
+	void *nl_data = NULL;
+	int flags = GFP_KERNEL;
+	struct radio_index_tlv *radio_info;
+	int tlv_len;
+
+	if (in_interrupt() || irqs_disabled() || in_atomic())
+		flags = GFP_ATOMIC;
+
+	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
+
+	if (skb == NULL)
+		return;
+
+	nlh = (struct nlmsghdr *)skb->data;
+	nlh->nlmsg_pid = 0;     /* from kernel */
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_seq = 0;
+	nlh->nlmsg_type = WLAN_NL_MSG_SVC;
+
+	ani_hdr = NLMSG_DATA(nlh);
+	ani_hdr->type = type;
+
+	switch (type) {
+	case WLAN_SVC_FW_CRASHED_IND:
+	case WLAN_SVC_FW_SHUTDOWN_IND:
+	case WLAN_SVC_LTE_COEX_IND:
+	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
+	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
+		ani_hdr->length = 0;
+		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
+		break;
+	case WLAN_SVC_WLAN_STATUS_IND:
+	case WLAN_SVC_WLAN_VERSION_IND:
+	case WLAN_SVC_DFS_CAC_START_IND:
+	case WLAN_SVC_DFS_CAC_END_IND:
+	case WLAN_SVC_DFS_RADAR_DETECT_IND:
+	case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
+	case WLAN_SVC_WLAN_TP_IND:
+	case WLAN_SVC_WLAN_TP_TX_IND:
+	case WLAN_SVC_RPS_ENABLE_IND:
+	case WLAN_SVC_CORE_MINFREQ:
+		ani_hdr->length = len;
+		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
+		nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
+		memcpy(nl_data, data, len);
+		break;
+
+	default:
+		hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
+		       type);
+		kfree_skb(skb);
+		return;
+	}
+
+	/*
+	 * Add radio index at the end of the svc event in TLV format
+	 * to maintain the backward compatibility with userspace
+	 * applications.
+	 */
+
+	tlv_len = 0;
+
+	if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
+		< WLAN_NL_MAX_PAYLOAD) {
+		radio_info  = (struct radio_index_tlv *)((char *) ani_hdr +
+		sizeof(*ani_hdr) + len);
+		radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
+		radio_info->length = (unsigned short) sizeof(radio_info->radio);
+		radio_info->radio = radio;
+		tlv_len = sizeof(*radio_info);
+		hdd_debug("Added radio index tlv - radio index %d",
+			  radio_info->radio);
+	}
+
+	nlh->nlmsg_len += tlv_len;
+	skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
+
+	nl_srv_bcast_svc(skb);
+}
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+void wlan_hdd_auto_shutdown_cb(void)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	if (!hdd_ctx)
+		return;
+
+	hdd_debug("Wlan Idle. Sending Shutdown event..");
+	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+			WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
+}
+
+void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
+{
+	struct hdd_adapter *adapter;
+	bool ap_connected = false, sta_connected = false;
+	mac_handle_t mac_handle;
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!mac_handle)
+		return;
+
+	if (hdd_ctx->config->wlan_auto_shutdown == 0)
+		return;
+
+	if (enable == false) {
+		if (sme_set_auto_shutdown_timer(mac_handle, 0) !=
+							QDF_STATUS_SUCCESS) {
+			hdd_err("Failed to stop wlan auto shutdown timer");
+		}
+		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+			WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
+		return;
+	}
+
+	/* To enable shutdown timer check conncurrency */
+	if (policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) {
+		hdd_for_each_adapter(hdd_ctx, adapter) {
+			if (adapter->device_mode == QDF_STA_MODE) {
+				if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
+				    conn_info.connState ==
+				    eConnectionState_Associated) {
+					sta_connected = true;
+					break;
+				}
+			}
+
+			if (adapter->device_mode == QDF_SAP_MODE) {
+				if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
+				    ap_active == true) {
+					ap_connected = true;
+					break;
+				}
+			}
+		}
+	}
+
+	if (ap_connected == true || sta_connected == true) {
+		hdd_debug("CC Session active. Shutdown timer not enabled");
+		return;
+	}
+
+	if (sme_set_auto_shutdown_timer(mac_handle,
+					hdd_ctx->config->wlan_auto_shutdown)
+	    != QDF_STATUS_SUCCESS)
+		hdd_err("Failed to start wlan auto shutdown timer");
+	else
+		hdd_info("Auto Shutdown timer for %d seconds enabled",
+			 hdd_ctx->config->wlan_auto_shutdown);
+}
+#endif
+
+struct hdd_adapter *
+hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
+			bool check_start_bss)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
+	struct hdd_adapter *adapter, *con_sap_adapter;
+
+	con_sap_adapter = NULL;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
+				(adapter->device_mode == QDF_P2P_GO_MODE)) &&
+						adapter != this_sap_adapter) {
+			if (check_start_bss) {
+				if (test_bit(SOFTAP_BSS_STARTED,
+						&adapter->event_flags)) {
+					con_sap_adapter = adapter;
+					break;
+				}
+			} else {
+				con_sap_adapter = adapter;
+				break;
+			}
+		}
+	}
+
+	return con_sap_adapter;
+}
+
+#ifdef MSM_PLATFORM
+static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
+{
+	return adapter->device_mode == QDF_STA_MODE ||
+		adapter->device_mode == QDF_P2P_CLIENT_MODE;
+}
+
+static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
+{
+	return adapter->device_mode == QDF_SAP_MODE ||
+		adapter->device_mode == QDF_P2P_GO_MODE;
+}
+
+static bool hdd_any_adapter_is_assoc(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (hdd_adapter_is_sta(adapter) &&
+		    WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
+			conn_info.connState == eConnectionState_Associated) {
+			return true;
+		}
+
+		if (hdd_adapter_is_ap(adapter) &&
+		    WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static bool hdd_bus_bw_compute_timer_is_running(struct hdd_context *hdd_ctx)
+{
+	bool is_running;
+
+	qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
+	is_running = hdd_ctx->bus_bw_timer_running;
+	qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
+
+	return is_running;
+}
+
+static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
+{
+	qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
+	hdd_ctx->bus_bw_timer_running = true;
+	qdf_timer_start(&hdd_ctx->bus_bw_timer,
+			hdd_ctx->config->bus_bw_compute_interval);
+	qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
+}
+
+void hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
+{
+	hdd_enter();
+
+	if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
+		hdd_debug("Bandwidth compute timer already started");
+		return;
+	}
+
+	__hdd_bus_bw_compute_timer_start(hdd_ctx);
+
+	hdd_exit();
+}
+
+void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx)
+{
+	hdd_enter();
+
+	if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
+		hdd_debug("Bandwidth compute timer already started");
+		return;
+	}
+
+	if (hdd_any_adapter_is_assoc(hdd_ctx))
+		__hdd_bus_bw_compute_timer_start(hdd_ctx);
+
+	hdd_exit();
+}
+
+static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
+{
+	ucfg_ipa_set_perf_level(hdd_ctx->pdev, 0, 0);
+
+	qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
+	hdd_ctx->bus_bw_timer_running = false;
+	qdf_timer_sync_cancel(&hdd_ctx->bus_bw_timer);
+	qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
+
+	/* work callback is long running; flush outside of lock */
+	cancel_work_sync(&hdd_ctx->bus_bw_work);
+	hdd_reset_tcp_delack(hdd_ctx);
+}
+
+void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
+{
+	hdd_enter();
+
+	if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
+		hdd_debug("Bandwidth compute timer already stopped");
+		return;
+	}
+
+	__hdd_bus_bw_compute_timer_stop(hdd_ctx);
+
+	hdd_exit();
+}
+
+void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx)
+{
+	hdd_enter();
+
+	if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
+		hdd_debug("Bandwidth compute timer already stopped");
+		return;
+	}
+
+	if (!hdd_any_adapter_is_assoc(hdd_ctx))
+		__hdd_bus_bw_compute_timer_stop(hdd_ctx);
+
+	hdd_exit();
+}
+#endif
+
+/**
+ * wlan_hdd_check_custom_con_channel_rules() - This function checks the sap's
+ *                                            and sta's operating channel.
+ * @sta_adapter:  Describe the first argument to foobar.
+ * @ap_adapter:   Describe the second argument to foobar.
+ * @roam_profile: Roam profile of AP to which STA wants to connect.
+ * @concurrent_chnl_same: If both SAP and STA channels are same then
+ *                        set this flag to true else false.
+ *
+ * This function checks the sap's operating channel and sta's operating channel.
+ * if both are same then it will return false else it will restart the sap in
+ * sta's channel and return true.
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
+ */
+QDF_STATUS
+wlan_hdd_check_custom_con_channel_rules(struct hdd_adapter *sta_adapter,
+					struct hdd_adapter *ap_adapter,
+					struct csr_roam_profile *roam_profile,
+					tScanResultHandle *scan_cache,
+					bool *concurrent_chnl_same)
+{
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	uint8_t channel_id;
+	QDF_STATUS status;
+	enum QDF_OPMODE device_mode = ap_adapter->device_mode;
+	*concurrent_chnl_same = true;
+
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
+	status =
+	 sme_get_ap_channel_from_scan_cache(roam_profile,
+					    scan_cache,
+					    &channel_id);
+	if (QDF_STATUS_SUCCESS == status) {
+		if ((QDF_SAP_MODE == device_mode) &&
+			(channel_id < SIR_11A_CHANNEL_BEGIN)) {
+			if (hdd_ap_ctx->operating_channel != channel_id) {
+				*concurrent_chnl_same = false;
+				hdd_debug("channels are different");
+			}
+		} else if ((QDF_P2P_GO_MODE == device_mode) &&
+				(channel_id >= SIR_11A_CHANNEL_BEGIN)) {
+			if (hdd_ap_ctx->operating_channel != channel_id) {
+				*concurrent_chnl_same = false;
+				hdd_debug("channels are different");
+			}
+		}
+	} else {
+		/*
+		 * Lets handle worst case scenario here, Scan cache lookup is
+		 * failed so we have to stop the SAP to avoid any channel
+		 * discrepancy  between SAP's channel and STA's channel.
+		 * Return the status as failure so caller function could know
+		 * that scan look up is failed.
+		 */
+		hdd_err("Finding AP from scan cache failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_hdd_stop_sap() - This function stops bss of SAP.
+ * @ap_adapter: SAP adapter
+ *
+ * This function will process the stopping of sap adapter.
+ *
+ * Return: None
+ */
+void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
+{
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	struct hdd_hostapd_state *hostapd_state;
+	QDF_STATUS qdf_status;
+	struct hdd_context *hdd_ctx;
+
+	if (NULL == ap_adapter) {
+		hdd_err("ap_adapter is NULL here");
+		return;
+	}
+
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
+	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	mutex_lock(&hdd_ctx->sap_lock);
+	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
+		wlan_hdd_del_station(ap_adapter);
+		hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
+		hdd_debug("Now doing SAP STOPBSS");
+		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
+		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
+							sap_context)) {
+			qdf_status = qdf_wait_for_event_completion(&hostapd_state->
+					qdf_stop_bss_event,
+					SME_CMD_START_STOP_BSS_TIMEOUT);
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+				mutex_unlock(&hdd_ctx->sap_lock);
+				hdd_err("SAP Stop Failed");
+				return;
+			}
+		}
+		clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
+		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
+						ap_adapter->device_mode,
+						ap_adapter->session_id);
+		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
+					    false);
+		hdd_debug("SAP Stop Success");
+	} else {
+		hdd_err("Can't stop ap because its not started");
+	}
+	mutex_unlock(&hdd_ctx->sap_lock);
+}
+
+/**
+ * wlan_hdd_start_sap() - this function starts bss of SAP.
+ * @ap_adapter: SAP adapter
+ *
+ * This function will process the starting of sap adapter.
+ *
+ * Return: None
+ */
+void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit)
+{
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	struct hdd_hostapd_state *hostapd_state;
+	QDF_STATUS qdf_status;
+	struct hdd_context *hdd_ctx;
+	tsap_config_t *sap_config;
+
+	if (NULL == ap_adapter) {
+		hdd_err("ap_adapter is NULL here");
+		return;
+	}
+
+	if (QDF_SAP_MODE != ap_adapter->device_mode) {
+		hdd_err("SoftAp role has not been enabled");
+		return;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
+	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
+	sap_config = &ap_adapter->session.ap.sap_config;
+
+	mutex_lock(&hdd_ctx->sap_lock);
+	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
+		goto end;
+
+	if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
+		hdd_err("SAP Not able to set AP IEs");
+		goto end;
+	}
+	wlan_reg_set_channel_params(hdd_ctx->pdev,
+				    hdd_ap_ctx->sap_config.channel, 0,
+				    &hdd_ap_ctx->sap_config.ch_params);
+
+	qdf_event_reset(&hostapd_state->qdf_event);
+	if (wlansap_start_bss(hdd_ap_ctx->sap_context, hdd_hostapd_sap_event_cb,
+			      &hdd_ap_ctx->sap_config,
+			      ap_adapter->dev)
+			      != QDF_STATUS_SUCCESS)
+		goto end;
+
+	hdd_debug("Waiting for SAP to start");
+	qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
+					SME_CMD_START_STOP_BSS_TIMEOUT);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("SAP Start failed");
+		goto end;
+	}
+	hdd_info("SAP Start Success");
+	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
+	set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
+	if (hostapd_state->bss_state == BSS_START) {
+		policy_mgr_incr_active_session(hdd_ctx->psoc,
+					ap_adapter->device_mode,
+					ap_adapter->session_id);
+		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
+					    true);
+	}
+	mutex_unlock(&hdd_ctx->sap_lock);
+
+	return;
+end:
+	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
+	mutex_unlock(&hdd_ctx->sap_lock);
+	/* SAP context and beacon cleanup will happen during driver unload
+	 * in hdd_stop_adapter
+	 */
+	hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
+
+}
+
+/**
+ * hdd_get_fw_version() - Get FW version
+ * @hdd_ctx:     pointer to HDD context.
+ * @major_spid:  FW version - major spid.
+ * @minor_spid:  FW version - minor spid
+ * @ssid:        FW version - ssid
+ * @crmid:       FW version - crmid
+ *
+ * This function is called to get the firmware build version stored
+ * as part of the HDD context
+ *
+ * Return:   None
+ */
+void hdd_get_fw_version(struct hdd_context *hdd_ctx,
+			uint32_t *major_spid, uint32_t *minor_spid,
+			uint32_t *siid, uint32_t *crmid)
+{
+	*major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
+	*minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
+	*siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
+	*crmid = hdd_ctx->target_fw_version & 0x7fff;
+}
+
+#ifdef QCA_CONFIG_SMP
+/**
+ * wlan_hdd_get_cpu() - get cpu_index
+ *
+ * Return: cpu_index
+ */
+int wlan_hdd_get_cpu(void)
+{
+	int cpu_index = get_cpu();
+
+	put_cpu();
+	return cpu_index;
+}
+#endif
+
+/**
+ * hdd_get_fwpath() - get framework path
+ *
+ * This function is used to get the string written by
+ * userspace to start the wlan driver
+ *
+ * Return: string
+ */
+const char *hdd_get_fwpath(void)
+{
+	return fwpath.string;
+}
+
+static inline int hdd_state_query_cb(void)
+{
+	return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD));
+}
+
+/**
+ * hdd_init() - Initialize Driver
+ *
+ * This function initilizes CDS global context with the help of cds_init. This
+ * has to be the first function called after probe to get a valid global
+ * context.
+ *
+ * Return: 0 for success, errno on failure
+ */
+int hdd_init(void)
+{
+	QDF_STATUS status;
+	int ret = 0;
+
+	status = cds_init();
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to allocate CDS context");
+		ret = -ENOMEM;
+		goto err_out;
+	}
+	qdf_register_module_state_query_callback(hdd_state_query_cb);
+
+	wlan_init_bug_report_lock();
+
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+	wlan_logging_sock_init_svc();
+#endif
+
+	qdf_timer_init(NULL, &hdd_drv_ops_inactivity_timer,
+		(void *)hdd_drv_ops_inactivity_handler, NULL,
+		QDF_TIMER_TYPE_SW);
+
+	hdd_trace_init();
+	hdd_register_debug_callback();
+	wlan_roam_debug_init();
+
+err_out:
+	return ret;
+}
+
+/**
+ * hdd_deinit() - Deinitialize Driver
+ *
+ * This function frees CDS global context with the help of cds_deinit. This
+ * has to be the last function call in remove callback to free the global
+ * context.
+ */
+void hdd_deinit(void)
+{
+	wlan_roam_debug_deinit();
+	qdf_timer_free(&hdd_drv_ops_inactivity_timer);
+
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+	wlan_logging_sock_deinit_svc();
+#endif
+
+	wlan_destroy_bug_report_lock();
+	cds_deinit();
+}
+
+#ifdef QCA_WIFI_NAPIER_EMULATION
+#define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
+#else
+#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
+#endif
+
+static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
+					  struct file *file)
+{
+	return 0;
+}
+
+static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
+						const char __user *user_buf,
+						size_t count,
+						loff_t *f_pos)
+{
+	char buf[3];
+	static const char wlan_off_str[] = "OFF";
+	static const char wlan_on_str[] = "ON";
+	int ret;
+	unsigned long rc;
+
+	if (copy_from_user(buf, user_buf, 3)) {
+		pr_err("Failed to read buffer\n");
+		return -EINVAL;
+	}
+
+	if (strncmp(buf, wlan_off_str, strlen(wlan_off_str)) == 0) {
+		pr_debug("Wifi turning off from UI\n");
+		goto exit;
+	}
+
+	if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) == 0)
+		pr_info("Wifi Turning On from UI\n");
+
+	if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) != 0) {
+		pr_err("Invalid value received from framework");
+		goto exit;
+	}
+
+	if (!cds_is_driver_loaded()) {
+		init_completion(&wlan_start_comp);
+		rc = wait_for_completion_timeout(&wlan_start_comp,
+				msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
+		if (!rc) {
+			hdd_alert("Timed-out!!");
+			ret = -EINVAL;
+			return ret;
+		}
+
+		hdd_start_complete(0);
+	}
+
+exit:
+	return count;
+}
+
+
+const struct file_operations wlan_hdd_state_fops = {
+	.owner = THIS_MODULE,
+	.open = wlan_hdd_state_ctrl_param_open,
+	.write = wlan_hdd_state_ctrl_param_write,
+};
+
+static int  wlan_hdd_state_ctrl_param_create(void)
+{
+	unsigned int wlan_hdd_state_major = 0;
+	int ret;
+	struct device *dev;
+
+	device = MKDEV(wlan_hdd_state_major, 0);
+
+	ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
+	if (ret) {
+		pr_err("Failed to register qcwlanstate");
+		goto dev_alloc_err;
+	}
+	wlan_hdd_state_major = MAJOR(device);
+
+	class = class_create(THIS_MODULE, WLAN_MODULE_NAME);
+	if (IS_ERR(class)) {
+		pr_err("wlan_hdd_state class_create error");
+		goto class_err;
+	}
+
+	dev = device_create(class, NULL, device, NULL, WLAN_MODULE_NAME);
+	if (IS_ERR(dev)) {
+		pr_err("wlan_hdd_statedevice_create error");
+		goto err_class_destroy;
+	}
+
+	cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
+	ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
+	if (ret) {
+		pr_err("Failed to add cdev error");
+		goto cdev_add_err;
+	}
+
+	pr_info("wlan_hdd_state %s major(%d) initialized",
+		WLAN_MODULE_NAME, wlan_hdd_state_major);
+
+	return 0;
+
+cdev_add_err:
+	device_destroy(class, device);
+err_class_destroy:
+	class_destroy(class);
+class_err:
+	unregister_chrdev_region(device, dev_num);
+dev_alloc_err:
+	return -ENODEV;
+}
+
+static void wlan_hdd_state_ctrl_param_destroy(void)
+{
+	cdev_del(&wlan_hdd_state_cdev);
+	device_destroy(class, device);
+	class_destroy(class);
+	unregister_chrdev_region(device, dev_num);
+
+	pr_info("Device node unregistered");
+}
+
+/**
+ * hdd_component_init() - Initialize all components
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS hdd_component_init(void)
+{
+	QDF_STATUS status;
+
+	/* initialize converged components */
+	status = dispatcher_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	/* initialize non-converged components */
+	status = ucfg_mlme_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto dispatcher_deinit;
+
+	status = ucfg_fwol_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto mlme_deinit;
+
+	status = disa_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto fwol_deinit;
+
+	status = pmo_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto disa_deinit;
+
+	status = ucfg_ocb_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto pmo_deinit;
+
+	status = ipa_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto ocb_deinit;
+
+	status = ucfg_action_oui_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto ipa_deinit;
+
+	return QDF_STATUS_SUCCESS;
+
+ipa_deinit:
+	ipa_deinit();
+ocb_deinit:
+	ucfg_ocb_deinit();
+pmo_deinit:
+	pmo_deinit();
+disa_deinit:
+	disa_deinit();
+fwol_deinit:
+	ucfg_fwol_deinit();
+mlme_deinit:
+	ucfg_mlme_deinit();
+dispatcher_deinit:
+	dispatcher_deinit();
+
+	return status;
+}
+
+/**
+ * hdd_component_deinit() - Deinitialize all components
+ *
+ * Return: None
+ */
+static void hdd_component_deinit(void)
+{
+	/* deinitialize non-converged components */
+	ucfg_action_oui_deinit();
+	ipa_deinit();
+	ucfg_ocb_deinit();
+	pmo_deinit();
+	disa_deinit();
+	ucfg_fwol_deinit();
+	ucfg_mlme_deinit();
+
+	/* deinitialize converged components */
+	dispatcher_deinit();
+}
+
+QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+
+	status = ucfg_mlme_psoc_open(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	status = ucfg_fwol_psoc_open(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto err_fwol;
+
+	status = ucfg_pmo_psoc_open(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto err_pmo;
+
+	status = ucfg_policy_mgr_psoc_open(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto err_plcy_mgr;
+
+	return status;
+
+err_plcy_mgr:
+	ucfg_pmo_psoc_close(psoc);
+err_pmo:
+	ucfg_fwol_psoc_close(psoc);
+err_fwol:
+	ucfg_mlme_psoc_close(psoc);
+
+	return status;
+}
+
+void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	ucfg_policy_mgr_psoc_close(psoc);
+	ucfg_pmo_psoc_close(psoc);
+	ucfg_fwol_psoc_close(psoc);
+	ucfg_mlme_psoc_close(psoc);
+}
+
+void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	ocb_psoc_enable(psoc);
+	disa_psoc_enable(psoc);
+}
+
+void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	disa_psoc_disable(psoc);
+	ocb_psoc_disable(psoc);
+}
+
+QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev)
+{
+	return ucfg_mlme_pdev_open(pdev);
+}
+
+void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev)
+{
+	ucfg_mlme_pdev_close(pdev);
+}
+
+static struct hdd_driver __hdd_driver;
+
+static QDF_STATUS hdd_driver_ctx_init(struct hdd_driver *hdd_driver)
+{
+	QDF_BUG(hdd_driver);
+	if (!hdd_driver)
+		return QDF_STATUS_E_INVAL;
+
+	hdd_driver->state = driver_state_uninit;
+
+	return dsc_driver_create(&hdd_driver->dsc_driver);
+}
+
+static void hdd_driver_ctx_deinit(struct hdd_driver *hdd_driver)
+{
+	QDF_BUG(hdd_driver);
+	if (!hdd_driver)
+		return;
+
+	dsc_driver_destroy(&hdd_driver->dsc_driver);
+	qdf_mem_zero(hdd_driver, sizeof(*hdd_driver));
+}
+
+struct hdd_driver *hdd_driver_get(void)
+{
+	return &__hdd_driver;
+}
+
+static QDF_STATUS hdd_qdf_print_init(void)
+{
+	QDF_STATUS status;
+	int qdf_print_idx;
+
+	status = qdf_print_setup();
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pr_err("Failed qdf_print_setup; status:%u\n", status);
+		return status;
+	}
+
+	qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
+	if (qdf_print_idx < 0) {
+		pr_err("Failed to register for qdf_print_ctrl\n");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_set_pidx(qdf_print_idx);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void hdd_qdf_print_deinit(void)
+{
+	int qdf_pidx = qdf_get_pidx();
+
+	qdf_set_pidx(-1);
+	qdf_print_ctrl_cleanup(qdf_pidx);
+
+	/* currently, no qdf print 'un-setup'*/
+}
+
+static QDF_STATUS hdd_qdf_init(void)
+{
+	QDF_STATUS status;
+
+	status = hdd_qdf_print_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto exit;
+
+	status = qdf_debugfs_init();
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to init debugfs; status:%u", status);
+		goto print_deinit;
+	}
+
+	qdf_lock_stats_init();
+	qdf_mem_init();
+	qdf_mc_timer_manager_init();
+	qdf_event_list_init();
+
+	status = qdf_cpuhp_init();
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to init cpuhp; status:%u", status);
+		goto event_deinit;
+	}
+
+	status = qdf_trace_spin_lock_init();
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to init spinlock; status:%u", status);
+		goto cpuhp_deinit;
+	}
+
+	qdf_trace_init();
+	qdf_register_debugcb_init();
+
+	return QDF_STATUS_SUCCESS;
+
+cpuhp_deinit:
+	qdf_cpuhp_deinit();
+event_deinit:
+	qdf_event_list_destroy();
+	qdf_mc_timer_manager_exit();
+	qdf_mem_exit();
+	qdf_lock_stats_deinit();
+	qdf_debugfs_exit();
+print_deinit:
+	hdd_qdf_print_deinit();
+
+exit:
+	return status;
+}
+
+static void hdd_qdf_deinit(void)
+{
+	/* currently, no debugcb deinit */
+
+	qdf_trace_deinit();
+
+	/* currently, no trace spinlock deinit */
+
+	qdf_cpuhp_deinit();
+	qdf_event_list_destroy();
+	qdf_mc_timer_manager_exit();
+	qdf_mem_exit();
+	qdf_lock_stats_deinit();
+	qdf_debugfs_exit();
+	hdd_qdf_print_deinit();
+}
+
+/**
+ * hdd_driver_load() - Perform the driver-level load operation
+ *
+ * Note: this is used in both static and DLKM driver builds
+ *
+ * Return: Errno
+ */
+static int hdd_driver_load(void)
+{
+	struct hdd_driver *hdd_driver = hdd_driver_get();
+	QDF_STATUS status;
+	int errno;
+
+	pr_err("%s: Loading driver v%s\n",
+	       WLAN_MODULE_NAME,
+	       g_wlan_driver_version);
+
+	status = hdd_qdf_init();
+	if (QDF_IS_STATUS_ERROR(status)) {
+		errno = qdf_status_to_os_return(status);
+		goto exit;
+	}
+
+	status = hdd_driver_ctx_init(hdd_driver);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to init driver context; status:%u", status);
+		errno = qdf_status_to_os_return(status);
+		goto qdf_deinit;
+	}
+
+	status = dsc_driver_trans_start(hdd_driver->dsc_driver, "load");
+	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+	if (QDF_IS_STATUS_ERROR(status)) {
+		errno = qdf_status_to_os_return(status);
+		goto hdd_driver_deinit;
+	}
+
+	errno = hdd_init();
+	if (errno) {
+		hdd_err("Failed to init HDD; errno:%d", errno);
+		goto trans_stop;
+	}
+
+	status = hdd_component_init();
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to init components; status:%u", status);
+		errno = qdf_status_to_os_return(status);
+		goto hdd_deinit;
+	}
+
+	status = qdf_wake_lock_create(&wlan_wake_lock, "wlan");
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to create wake lock; status:%u", status);
+		errno = qdf_status_to_os_return(status);
+		goto comp_deinit;
+	}
+
+	hdd_set_conparam(con_mode);
+
+	errno = wlan_hdd_state_ctrl_param_create();
+	if (errno) {
+		hdd_err("Failed to create ctrl param; errno:%d", errno);
+		goto wakelock_destroy;
+	}
+
+	errno = pld_init();
+	if (errno) {
+		hdd_err("Failed to init PLD; errno:%d", errno);
+		goto param_destroy;
+	}
+
+	hdd_driver->state = driver_state_loaded;
+	dsc_driver_trans_stop(hdd_driver->dsc_driver);
+
+	/* psoc probe can happen in registration; do after 'load' transition */
+	errno = wlan_hdd_register_driver();
+	if (errno) {
+		hdd_err("Failed to register driver; errno:%d", errno);
+		goto pld_deinit;
+	}
+
+	hdd_debug("%s: driver loaded", WLAN_MODULE_NAME);
+
+	return 0;
+
+pld_deinit:
+	status = dsc_driver_trans_start(hdd_driver->dsc_driver, "unload");
+	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+
+	pld_deinit();
+
+param_destroy:
+	wlan_hdd_state_ctrl_param_destroy();
+wakelock_destroy:
+	qdf_wake_lock_destroy(&wlan_wake_lock);
+comp_deinit:
+	hdd_component_deinit();
+hdd_deinit:
+	hdd_deinit();
+trans_stop:
+	hdd_driver->state = driver_state_deinit;
+	dsc_driver_trans_stop(hdd_driver->dsc_driver);
+hdd_driver_deinit:
+	hdd_driver_ctx_deinit(hdd_driver);
+qdf_deinit:
+	hdd_qdf_deinit();
+
+exit:
+	return errno;
+}
+
+/**
+ * hdd_driver_unload() - Performs the driver-level unload operation
+ *
+ * Note: this is used in both static and DLKM driver builds
+ *
+ * Return: None
+ */
+static void hdd_driver_unload(void)
+{
+	struct hdd_driver *hdd_driver = hdd_driver_get();
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	QDF_STATUS status;
+
+	pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
+		QWLAN_VERSIONSTR);
+
+	status = dsc_driver_trans_start_wait(hdd_driver->dsc_driver, "unload");
+	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Unable to unload wlan; status:%u", status);
+		return;
+	}
+
+	dsc_driver_wait_for_ops(hdd_driver->dsc_driver);
+
+	if (!hdd_wait_for_recovery_completion()) {
+		dsc_driver_trans_stop(hdd_driver->dsc_driver);
+		return;
+	}
+
+	cds_set_driver_loaded(false);
+	cds_set_unload_in_progress(true);
+
+	if (!cds_wait_for_external_threads_completion(__func__))
+		hdd_warn("External threads are still active attempting "
+			 "driver unload anyway");
+
+	if (hdd_ctx)
+		hdd_psoc_idle_timer_stop(hdd_ctx);
+
+	wlan_hdd_unregister_driver();
+	pld_deinit();
+	wlan_hdd_state_ctrl_param_destroy();
+	hdd_set_conparam(0);
+	qdf_wake_lock_destroy(&wlan_wake_lock);
+	hdd_component_deinit();
+	hdd_deinit();
+
+	hdd_driver->state = driver_state_deinit;
+	dsc_driver_trans_stop(hdd_driver->dsc_driver);
+	hdd_driver_ctx_deinit(hdd_driver);
+
+	hdd_qdf_deinit();
+}
+
+#ifndef MODULE
+/**
+ * wlan_boot_cb() - Wlan boot callback
+ * @kobj:      object whose directory we're creating the link in.
+ * @attr:      attribute the user is interacting with
+ * @buff:      the buffer containing the user data
+ * @count:     number of bytes in the buffer
+ *
+ * This callback is invoked when the fs is ready to start the
+ * wlan driver initialization.
+ *
+ * Return: 'count' on success or a negative error code in case of failure
+ */
+static ssize_t wlan_boot_cb(struct kobject *kobj,
+			    struct kobj_attribute *attr,
+			    const char *buf,
+			    size_t count)
+{
+
+	if (wlan_loader->loaded_state) {
+		hdd_err("wlan driver already initialized");
+		return -EALREADY;
+	}
+
+	if (hdd_driver_load())
+		return -EIO;
+
+	wlan_loader->loaded_state = MODULE_INITIALIZED;
+
+	return count;
+}
+
+/**
+ * hdd_sysfs_cleanup() - cleanup sysfs
+ *
+ * Return: None
+ *
+ */
+static void hdd_sysfs_cleanup(void)
+{
+	/* remove from group */
+	if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
+		sysfs_remove_group(wlan_loader->boot_wlan_obj,
+				   wlan_loader->attr_group);
+
+	/* unlink the object from parent */
+	kobject_del(wlan_loader->boot_wlan_obj);
+
+	/* free the object */
+	kobject_put(wlan_loader->boot_wlan_obj);
+
+	kfree(wlan_loader->attr_group);
+	kfree(wlan_loader);
+
+	wlan_loader = NULL;
+}
+
+/**
+ * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
+ * ready
+ *
+ * This is creates the syfs entry boot_wlan. Which shall be invoked
+ * when the filesystem is ready.
+ *
+ * QDF API cannot be used here since this function is called even before
+ * initializing WLAN driver.
+ *
+ * Return: 0 for success, errno on failure
+ */
+static int wlan_init_sysfs(void)
+{
+	int ret = -ENOMEM;
+
+	wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
+	if (!wlan_loader)
+		return -ENOMEM;
+
+	wlan_loader->boot_wlan_obj = NULL;
+	wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
+					  GFP_KERNEL);
+	if (!wlan_loader->attr_group)
+		goto error_return;
+
+	wlan_loader->loaded_state = 0;
+	wlan_loader->attr_group->attrs = attrs;
+
+	wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME,
+							    kernel_kobj);
+	if (!wlan_loader->boot_wlan_obj) {
+		hdd_err("sysfs create and add failed");
+		goto error_return;
+	}
+
+	ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
+				 wlan_loader->attr_group);
+	if (ret) {
+		hdd_err("sysfs create group failed; errno:%d", ret);
+		goto error_return;
+	}
+
+	return 0;
+
+error_return:
+	hdd_sysfs_cleanup();
+
+	return ret;
+}
+
+/**
+ * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
+ *
+ * Return: 0 on success or errno on failure
+ */
+static int wlan_deinit_sysfs(void)
+{
+	if (!wlan_loader) {
+		hdd_err("wlan_loader is null");
+		return -EINVAL;
+	}
+
+	hdd_sysfs_cleanup();
+	return 0;
+}
+
+#endif /* MODULE */
+
+#ifdef MODULE
+/**
+ * hdd_module_init() - Module init helper
+ *
+ * Module init helper function used by both module and static driver.
+ *
+ * Return: 0 for success, errno on failure
+ */
+static int hdd_module_init(void)
+{
+	if (hdd_driver_load())
+		return -EINVAL;
+
+	return 0;
+}
+#else
+static int __init hdd_module_init(void)
+{
+	int ret = -EINVAL;
+
+	ret = wlan_init_sysfs();
+	if (ret)
+		hdd_err("Failed to create sysfs entry");
+
+	return ret;
+}
+#endif
+
+
+#ifdef MODULE
+/**
+ * hdd_module_exit() - Exit function
+ *
+ * This is the driver exit point (invoked when module is unloaded using rmmod)
+ *
+ * Return: None
+ */
+static void __exit hdd_module_exit(void)
+{
+	hdd_driver_unload();
+}
+#else
+static void __exit hdd_module_exit(void)
+{
+	hdd_driver_unload();
+	wlan_deinit_sysfs();
+}
+#endif
+
+static int fwpath_changed_handler(const char *kmessage,
+				  const struct kernel_param *kp)
+{
+	return param_set_copystring(kmessage, kp);
+}
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+static bool is_monitor_mode_supported(void)
+{
+	return true;
+}
+#else
+static bool is_monitor_mode_supported(void)
+{
+	pr_err("Monitor mode not supported!");
+	return false;
+}
+#endif
+
+#ifdef WLAN_FEATURE_EPPING
+static bool is_epping_mode_supported(void)
+{
+	return true;
+}
+#else
+static bool is_epping_mode_supported(void)
+{
+	pr_err("Epping mode not supported!");
+	return false;
+}
+#endif
+
+#ifdef QCA_WIFI_FTM
+static bool is_ftm_mode_supported(void)
+{
+	return true;
+}
+#else
+static bool is_ftm_mode_supported(void)
+{
+	pr_err("FTM mode not supported!");
+	return false;
+}
+#endif
+
+/**
+ * is_con_mode_valid() check con mode is valid or not
+ * @mode: global con mode
+ *
+ * Return: TRUE on success FALSE on failure
+ */
+static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
+{
+	switch (mode) {
+	case QDF_GLOBAL_MONITOR_MODE:
+		return is_monitor_mode_supported();
+	case QDF_GLOBAL_EPPING_MODE:
+		return is_epping_mode_supported();
+	case QDF_GLOBAL_FTM_MODE:
+		return is_ftm_mode_supported();
+	case QDF_GLOBAL_MISSION_MODE:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
+				  enum QDF_GLOBAL_MODE curr_mode)
+{
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
+		return;
+
+	switch (curr_mode) {
+	case QDF_GLOBAL_MONITOR_MODE:
+		hdd_info("Release wakelock for monitor mode!");
+		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
+				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
+		/* fallthrough */
+	case QDF_GLOBAL_MISSION_MODE:
+	case QDF_GLOBAL_FTM_MODE:
+		hdd_abort_mac_scan_all_adapters(hdd_ctx);
+		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
+		hdd_stop_all_adapters(hdd_ctx);
+		hdd_deinit_all_adapters(hdd_ctx, false);
+
+		break;
+	default:
+		break;
+	}
+}
+
+static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
+				    enum QDF_GLOBAL_MODE curr_mode)
+{
+	int driver_status;
+
+	driver_status = hdd_ctx->driver_status;
+
+	switch (curr_mode) {
+	case QDF_GLOBAL_MISSION_MODE:
+	case QDF_GLOBAL_MONITOR_MODE:
+	case QDF_GLOBAL_FTM_MODE:
+		hdd_close_all_adapters(hdd_ctx, false);
+		break;
+	case QDF_GLOBAL_EPPING_MODE:
+		epping_disable();
+		epping_close();
+		break;
+	default:
+		return;
+	}
+}
+
+static int
+hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode)
+{
+	int mode;
+	int errno;
+
+	*out_mode = QDF_GLOBAL_MAX_MODE;
+
+	errno = kstrtoint(mode_str, 0, &mode);
+	if (!errno)
+		*out_mode = (enum QDF_GLOBAL_MODE)mode;
+
+	return errno;
+}
+
+/**
+ * __con_mode_handler() - Handles module param con_mode change
+ * @kmessage: con mode name on which driver to be bring up
+ * @kp: The associated kernel parameter
+ * @hdd_ctx: Pointer to the global HDD context
+ *
+ * This function is invoked when user updates con mode using sys entry,
+ * to initialize and bring-up driver in that specific mode.
+ *
+ * Return: Errno
+ */
+static int __con_mode_handler(const char *kmessage,
+			      const struct kernel_param *kp,
+			      struct hdd_context *hdd_ctx)
+{
+	enum QDF_GLOBAL_MODE curr_mode;
+	enum QDF_GLOBAL_MODE next_mode;
+	int errno;
+
+	hdd_info("Driver mode changing to %s", kmessage);
+
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	errno = hdd_parse_driver_mode(kmessage, &next_mode);
+	if (errno) {
+		hdd_err_rl("Failed to parse driver mode '%s'", kmessage);
+		return errno;
+	}
+
+	if (!is_con_mode_valid(next_mode)) {
+		hdd_err_rl("Requested driver mode is invalid");
+		return -EINVAL;
+	}
+
+	qdf_atomic_set(&hdd_ctx->con_mode_flag, 1);
+	mutex_lock(&hdd_init_deinit_lock);
+
+	curr_mode = hdd_get_conparam();
+	if (curr_mode == next_mode) {
+		hdd_err_rl("Driver is already in the requested mode");
+		errno = 0;
+		goto unlock;
+	}
+
+	/* ensure adapters are stopped */
+	hdd_stop_present_mode(hdd_ctx, curr_mode);
+
+	errno = hdd_wlan_stop_modules(hdd_ctx, true);
+	if (errno) {
+		hdd_err("Stop wlan modules failed");
+		goto unlock;
+	}
+
+	/* Cleanup present mode before switching to new mode */
+	hdd_cleanup_present_mode(hdd_ctx, curr_mode);
+
+	hdd_set_conparam(next_mode);
+
+	errno = hdd_wlan_start_modules(hdd_ctx, false);
+	if (errno) {
+		hdd_err("Start wlan modules failed: %d", errno);
+		goto unlock;
+	}
+
+	errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode);
+	if (errno) {
+		hdd_err("Failed to open adapters");
+		goto unlock;
+	}
+
+	if (next_mode == QDF_GLOBAL_MONITOR_MODE) {
+		struct hdd_adapter *adapter =
+			hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
+
+		QDF_BUG(adapter);
+		if (!adapter) {
+			hdd_err("Failed to get monitor adapter");
+			goto unlock;
+		}
+
+		errno = hdd_start_adapter(adapter);
+		if (errno) {
+			hdd_err("Failed to start monitor adapter");
+			goto unlock;
+		}
+
+		hdd_info("Acquire wakelock for monitor mode");
+		qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
+				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
+	}
+
+	/* con_mode is a global module parameter */
+	con_mode = next_mode;
+	hdd_info("Driver mode successfully changed to %s", kmessage);
+
+	errno = 0;
+
+unlock:
+	mutex_unlock(&hdd_init_deinit_lock);
+	qdf_atomic_set(&hdd_ctx->con_mode_flag, 0);
+
+	return errno;
+}
+
+static int con_mode_handler(const char *kmessage, const struct kernel_param *kp)
+{
+	struct hdd_driver *hdd_driver = hdd_driver_get();
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+	int errno;
+
+	hdd_enter();
+
+	status = dsc_driver_trans_start_wait(hdd_driver->dsc_driver,
+					     "mode change");
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to start 'mode change'; status:%u", status);
+		errno = qdf_status_to_os_return(status);
+		goto exit;
+	}
+
+	dsc_driver_wait_for_ops(hdd_driver->dsc_driver);
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		goto trans_stop;
+
+	if (!cds_wait_for_external_threads_completion(__func__)) {
+		hdd_warn("External threads are still active, can not change mode");
+		errno = -EAGAIN;
+		goto trans_stop;
+	}
+
+	cds_ssr_protect(__func__);
+	errno = __con_mode_handler(kmessage, kp, hdd_ctx);
+	cds_ssr_unprotect(__func__);
+
+trans_stop:
+	dsc_driver_trans_stop(hdd_driver->dsc_driver);
+
+exit:
+	hdd_exit();
+
+	return errno;
+}
+
+static int con_mode_handler_ftm(const char *kmessage,
+				const 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;
+}
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+static int con_mode_handler_monitor(const char *kmessage,
+				    const struct kernel_param *kp)
+{
+	int ret;
+
+	ret = param_set_int(kmessage, kp);
+
+	if (con_mode_monitor != QDF_GLOBAL_MONITOR_MODE) {
+		pr_err("Only Monitor mode supported!");
+		return -ENOTSUPP;
+	}
+
+	hdd_set_conparam(con_mode_monitor);
+	con_mode = con_mode_monitor;
+
+	return ret;
+}
+#endif
+
+/**
+ * hdd_get_conparam() - driver exit point
+ *
+ * This is the driver exit point (invoked when module is unloaded using rmmod)
+ *
+ * Return: enum QDF_GLOBAL_MODE
+ */
+enum QDF_GLOBAL_MODE hdd_get_conparam(void)
+{
+	return (enum QDF_GLOBAL_MODE) curr_con_mode;
+}
+
+void hdd_set_conparam(int32_t con_param)
+{
+	curr_con_mode = con_param;
+}
+
+/**
+ * hdd_clean_up_pre_cac_interface() - Clean up the pre cac interface
+ * @hdd_ctx: HDD context
+ *
+ * Cleans up the pre cac interface, if it exists
+ *
+ * Return: None
+ */
+void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx)
+{
+	uint8_t session_id;
+	QDF_STATUS status;
+	struct hdd_adapter *precac_adapter;
+
+	status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->mac_handle, &session_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("failed to get pre cac vdev id");
+		return;
+	}
+
+	precac_adapter = hdd_get_adapter_by_vdev(hdd_ctx, session_id);
+	if (!precac_adapter) {
+		hdd_err("invalid pre cac adapter");
+		return;
+	}
+
+	qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
+			wlan_hdd_sap_pre_cac_failure,
+			(void *)precac_adapter);
+	qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
+
+}
+
+/**
+ * hdd_update_ol_config - API to update ol configuration parameters
+ * @hdd_ctx: HDD context
+ *
+ * Return: void
+ */
+static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
+{
+	struct ol_config_info cfg;
+	struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
+	bool self_recovery = false;
+	QDF_STATUS status;
+
+	if (!ol_ctx)
+		return;
+
+	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to get self recovery ini config");
+
+	cfg.enable_self_recovery = self_recovery;
+	cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
+	cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
+	cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
+	cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
+
+	ol_init_ini_config(ol_ctx, &cfg);
+}
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * hdd_populate_runtime_cfg() - populate runtime configuration
+ * @hdd_ctx: hdd context
+ * @cfg: pointer to the configuration memory being populated
+ *
+ * Return: void
+ */
+static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
+				     struct hif_config_info *cfg)
+{
+	cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
+	cfg->runtime_pm_delay =
+		ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc);
+}
+#else
+static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
+				     struct hif_config_info *cfg)
+{
+}
+#endif
+
+/**
+ * hdd_update_hif_config - API to update HIF configuration parameters
+ * @hdd_ctx: HDD Context
+ *
+ * Return: void
+ */
+static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
+{
+	struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
+	struct hif_config_info cfg;
+	bool prevent_link_down = false;
+	bool self_recovery = false;
+	QDF_STATUS status;
+
+	if (!scn)
+		return;
+
+	status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc,
+						 &prevent_link_down);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to get prevent_link_down config");
+
+	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to get self recovery ini config");
+
+	cfg.enable_self_recovery = self_recovery;
+	hdd_populate_runtime_cfg(hdd_ctx, &cfg);
+	hif_init_ini_config(scn, &cfg);
+
+	if (prevent_link_down)
+		hif_vote_link_up(scn);
+}
+
+/**
+ * hdd_update_dp_config() - Propagate config parameters to Lithium
+ *                          datapath
+ * @hdd_ctx: HDD Context
+ *
+ * Return: 0 for success/errno for failure
+ */
+static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
+{
+	struct cdp_config_params params;
+	QDF_STATUS status;
+	void *soc;
+
+	soc = cds_get_context(QDF_MODULE_ID_SOC);
+	params.tso_enable = cfg_get(hdd_ctx->psoc, CFG_DP_TSO);
+	params.lro_enable = cfg_get(hdd_ctx->psoc, CFG_DP_LRO);
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+	params.tx_flow_stop_queue_threshold =
+			hdd_ctx->config->TxFlowStopQueueThreshold;
+	params.tx_flow_start_queue_offset =
+			hdd_ctx->config->TxFlowStartQueueOffset;
+#endif
+	params.flow_steering_enable =
+		cfg_get(hdd_ctx->psoc, CFG_DP_FLOW_STEERING_ENABLED);
+	params.napi_enable = hdd_ctx->napi_enable;
+	params.tcp_udp_checksumoffload =
+			cfg_get(hdd_ctx->psoc,
+				CFG_DP_TCP_UDP_CKSUM_OFFLOAD);
+
+	status = cdp_update_config_parameters(soc, &params);
+	if (status) {
+		hdd_err("Failed to attach config parameters");
+		return status;
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_update_config() - Initialize driver per module ini parameters
+ * @hdd_ctx: HDD Context
+ *
+ * API is used to initialize all driver per module configuration parameters
+ * Return: 0 for success, errno for failure
+ */
+int hdd_update_config(struct hdd_context *hdd_ctx)
+{
+	int ret;
+
+	if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc))
+		hdd_ctx->ns_offload_enable = true;
+
+	hdd_update_ol_config(hdd_ctx);
+	hdd_update_hif_config(hdd_ctx);
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
+		ret = hdd_update_cds_config_ftm(hdd_ctx);
+	else
+		ret = hdd_update_cds_config(hdd_ctx);
+	ret = hdd_update_user_config(hdd_ctx);
+
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+/**
+ * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
+ * @psoc_cfg: pmo psoc Configuration
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Return: none
+ */
+static inline void hdd_ra_populate_pmo_config(
+			struct pmo_psoc_cfg *psoc_cfg,
+			struct hdd_context *hdd_ctx)
+{
+	bool is_rate_limit_enabled;
+	QDF_STATUS status;
+
+	status = ucfg_fwol_get_is_rate_limit_enabled(hdd_ctx->psoc,
+						     &is_rate_limit_enabled);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+
+	psoc_cfg->ra_ratelimit_interval =
+		hdd_ctx->config->RArateLimitInterval;
+	psoc_cfg->ra_ratelimit_enable =
+		is_rate_limit_enabled;
+}
+#else
+static inline void hdd_ra_populate_pmo_config(
+			struct cds_config_info *cds_cfg,
+			struct hdd_context *hdd_ctx)
+{
+}
+#endif
+
+/**
+ * hdd_update_pmo_config - API to update pmo configuration parameters
+ * @hdd_ctx: HDD context
+ *
+ * Return: void
+ */
+static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
+{
+	struct pmo_psoc_cfg psoc_cfg;
+	QDF_STATUS status;
+	enum pmo_wow_enable_type wow_enable;
+
+	ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg);
+
+	/*
+	 * Value of hdd_ctx->wowEnable can be,
+	 * 0 - Disable both magic pattern match and pattern byte match.
+	 * 1 - Enable magic pattern match on all interfaces.
+	 * 2 - Enable pattern byte match on all interfaces.
+	 * 3 - Enable both magic patter and pattern byte match on
+	 *     all interfaces.
+	 */
+	wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc);
+	psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false;
+	psoc_cfg.ptrn_match_enable_all_vdev =
+				(wow_enable & 0x02) ? true : false;
+	psoc_cfg.packet_filter_enabled = !hdd_ctx->config->disablePacketFilter;
+	psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
+	psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
+	psoc_cfg.sta_max_li_mod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
+
+	hdd_ra_populate_pmo_config(&psoc_cfg, hdd_ctx);
+	hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
+
+	status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("failed pmo psoc configuration; status:%d", status);
+
+	return qdf_status_to_os_return(status);
+}
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+static inline void hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
+	struct hdd_config *cfg)
+{
+	struct nlo_mawc_params *mawc_cfg = &pno_cfg->mawc_params;
+
+	pno_cfg->channel_prediction = cfg->pno_channel_prediction;
+	pno_cfg->top_k_num_of_channels = cfg->top_k_num_of_channels;
+	pno_cfg->stationary_thresh = cfg->stationary_thresh;
+	pno_cfg->adaptive_dwell_mode = cfg->adaptive_dwell_mode_enabled;
+	pno_cfg->channel_prediction_full_scan =
+		cfg->channel_prediction_full_scan;
+	mawc_cfg->enable = cfg->MAWCEnabled && cfg->mawc_nlo_enabled;
+	mawc_cfg->exp_backoff_ratio = cfg->mawc_nlo_exp_backoff_ratio;
+	mawc_cfg->init_scan_interval = cfg->mawc_nlo_init_scan_interval;
+	mawc_cfg->max_scan_interval = cfg->mawc_nlo_max_scan_interval;
+}
+#else
+static inline void
+hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
+		      struct hdd_config *cfg)
+{
+}
+#endif
+
+void hdd_update_ie_whitelist_attr(struct probe_req_whitelist_attr *ie_whitelist,
+				  struct hdd_context *hdd_ctx)
+{
+	struct wlan_fwol_ie_whitelist whitelist = {0};
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	QDF_STATUS status;
+	bool is_ie_whitelist_enable = false;
+	uint8_t i = 0;
+
+	status = ucfg_fwol_get_ie_whitelist(psoc, &is_ie_whitelist_enable);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Unable to get IE whitelist param");
+		return;
+	}
+
+	ie_whitelist->white_list = is_ie_whitelist_enable;
+	if (!ie_whitelist->white_list)
+		return;
+
+	status = ucfg_fwol_get_all_whitelist_params(psoc, &whitelist);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Unable to get all whitelist params");
+		return;
+	}
+
+	ie_whitelist->ie_bitmap[0] = whitelist.ie_bitmap_0;
+	ie_whitelist->ie_bitmap[1] = whitelist.ie_bitmap_1;
+	ie_whitelist->ie_bitmap[2] = whitelist.ie_bitmap_2;
+	ie_whitelist->ie_bitmap[3] = whitelist.ie_bitmap_3;
+	ie_whitelist->ie_bitmap[4] = whitelist.ie_bitmap_4;
+	ie_whitelist->ie_bitmap[5] = whitelist.ie_bitmap_5;
+	ie_whitelist->ie_bitmap[6] = whitelist.ie_bitmap_6;
+	ie_whitelist->ie_bitmap[7] = whitelist.ie_bitmap_7;
+
+	ie_whitelist->num_vendor_oui = whitelist.no_of_probe_req_ouis;
+	for (i = 0; i < ie_whitelist->num_vendor_oui; i++)
+		ie_whitelist->voui[i] = whitelist.probe_req_voui[i];
+}
+
+uint32_t hdd_limit_max_per_index_score(uint32_t per_index_score)
+{
+	uint8_t i, score;
+
+	for (i = 0; i < MAX_INDEX_PER_INI; i++) {
+		score = WLAN_GET_SCORE_PERCENTAGE(per_index_score, i);
+		if (score > MAX_INDEX_SCORE)
+			WLAN_SET_SCORE_PERCENTAGE(per_index_score,
+				MAX_INDEX_SCORE, i);
+	}
+
+	return per_index_score;
+}
+
+QDF_STATUS hdd_update_score_config(
+	struct scoring_config *score_config, struct hdd_context *hdd_ctx)
+{
+	struct hdd_config *cfg = hdd_ctx->config;
+	QDF_STATUS status;
+	bool bval = false;
+
+	sme_update_score_config(hdd_ctx->mac_handle, score_config);
+
+	score_config->cb_mode_24G = cfg->nChannelBondingMode24GHz;
+	score_config->cb_mode_5G = cfg->nChannelBondingMode5GHz;
+
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+	score_config->vdev_nss_24g =
+		bval ? CFG_STA_NSS(cfg->vdev_type_nss_2g) : 1;
+	score_config->vdev_nss_5g =
+		bval ? CFG_STA_NSS(cfg->vdev_type_nss_5g) : 1;
+
+	if (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO ||
+	    cfg->dot11Mode == eHDD_DOT11_MODE_11ax ||
+	    cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)
+		score_config->he_cap = 1;
+
+	if (score_config->he_cap ||
+	    cfg->dot11Mode == eHDD_DOT11_MODE_11ac ||
+	    cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
+		score_config->vht_cap = 1;
+
+	if (score_config->vht_cap || cfg->dot11Mode == eHDD_DOT11_MODE_11n ||
+	    cfg->dot11Mode == eHDD_DOT11_MODE_11n_ONLY)
+		score_config->ht_cap = 1;
+
+	status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("Failed to get vht_for_24ghz");
+	if (score_config->vht_cap && bval)
+		score_config->vht_24G_cap = 1;
+
+	status = ucfg_mlme_get_vht_enable_tx_bf(hdd_ctx->psoc,
+					&bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable_tx_bf");
+
+	if (bval)
+		score_config->beamformee_cap = 1;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_update_dfs_config() - API to update dfs configuration parameters.
+ * @hdd_ctx: HDD context
+ *
+ * Return: 0 if success else err
+ */
+static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
+{
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	struct hdd_config *cfg = hdd_ctx->config;
+	struct dfs_user_config dfs_cfg;
+	QDF_STATUS status;
+
+	dfs_cfg.dfs_is_phyerr_filter_offload = !!cfg->fDfsPhyerrFilterOffload;
+	status = ucfg_dfs_update_config(psoc, &dfs_cfg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("failed dfs psoc configuration");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_update_scan_config - API to update scan configuration parameters
+ * @hdd_ctx: HDD context
+ *
+ * Return: 0 if success else err
+ */
+static int hdd_update_scan_config(struct hdd_context *hdd_ctx)
+{
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	struct scan_user_cfg scan_cfg;
+	struct hdd_config *cfg = hdd_ctx->config;
+	QDF_STATUS status;
+	uint8_t scan_bucket_thre;
+	uint8_t select_5ghz_margin;
+
+	status = ucfg_mlme_get_select_5ghz_margin(hdd_ctx->psoc,
+						  &select_5ghz_margin);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get select_5ghz_margin");
+		return -EIO;
+	}
+
+	scan_cfg.active_dwell = cfg->nActiveMaxChnTime;
+	scan_cfg.passive_dwell = cfg->nPassiveMaxChnTime;
+	scan_cfg.conc_active_dwell = cfg->nActiveMaxChnTimeConc;
+	scan_cfg.conc_passive_dwell = cfg->nPassiveMaxChnTimeConc;
+	scan_cfg.conc_max_rest_time = cfg->nRestTimeConc;
+	scan_cfg.conc_min_rest_time = cfg->min_rest_time_conc;
+	scan_cfg.conc_idle_time = cfg->idle_time_conc;
+	/* convert to ms */
+	scan_cfg.scan_cache_aging_time =
+		cfg->scanAgingTimeout * 1000;
+	scan_cfg.prefer_5ghz = cfg->nRoamPrefer5GHz;
+	scan_cfg.select_5ghz_margin = select_5ghz_margin;
+	ucfg_mlme_get_first_scan_bucket_threshold(hdd_ctx->psoc,
+						  &scan_bucket_thre);
+	scan_cfg.scan_bucket_threshold = (int32_t)scan_bucket_thre;
+	scan_cfg.rssi_cat_gap = cfg->nRssiCatGap;
+	scan_cfg.scan_dwell_time_mode = cfg->scan_adaptive_dwell_mode;
+	scan_cfg.is_snr_monitoring_enabled = cfg->fEnableSNRMonitoring;
+	scan_cfg.usr_cfg_probe_rpt_time = cfg->scan_probe_repeat_time;
+	scan_cfg.usr_cfg_num_probes = cfg->scan_num_probes;
+	scan_cfg.is_bssid_hint_priority = cfg->is_bssid_hint_priority;
+	scan_cfg.enable_mac_spoofing = cfg->enable_mac_spoofing;
+	scan_cfg.sta_miracast_mcc_rest_time =
+				cfg->sta_miracast_mcc_rest_time_val;
+	hdd_update_pno_config(&scan_cfg.pno_cfg, cfg);
+	hdd_update_ie_whitelist_attr(&scan_cfg.ie_whitelist, hdd_ctx);
+
+	status = hdd_update_score_config(&scan_cfg.score_config, hdd_ctx);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to update scoring config");
+		return -EINVAL;
+	}
+
+	status = ucfg_scan_update_user_config(psoc, &scan_cfg);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("failed pmo psoc configuration");
+		return -EINVAL;
+	}
+	ucfg_scan_set_global_config(
+		psoc, SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH,
+		cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH));
+
+	return 0;
+}
+
+int hdd_update_components_config(struct hdd_context *hdd_ctx)
+{
+	int ret;
+
+	ret = hdd_update_pmo_config(hdd_ctx);
+	if (ret)
+		return ret;
+
+	ret = hdd_update_scan_config(hdd_ctx);
+	if (ret)
+		return ret;
+
+	ret = hdd_update_tdls_config(hdd_ctx);
+	if (ret)
+		return ret;
+
+	ret = hdd_update_dp_config(hdd_ctx);
+	if (ret)
+		return ret;
+
+	ret = hdd_update_dfs_config(hdd_ctx);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_get_dfs_mode() - get ACS DFS mode
+ * @mode : cfg80211 DFS mode
+ *
+ * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
+ */
+enum  sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
+{
+	switch (mode) {
+	case DFS_MODE_ENABLE:
+		return ACS_DFS_MODE_ENABLE;
+	case DFS_MODE_DISABLE:
+		return ACS_DFS_MODE_DISABLE;
+	case DFS_MODE_DEPRIORITIZE:
+		return ACS_DFS_MODE_DEPRIORITIZE;
+	default:
+		hdd_debug("ACS dfs mode is NONE");
+		return ACS_DFS_MODE_NONE;
+	}
+}
+
+/**
+ * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
+ * @hddctx: pointer to hdd context
+ * @set_value: enable/disable
+ *
+ * When Host sends vendor command enable, FW will send *ONE* CA ind to
+ * Host(even though it is duplicate). When Host send vendor command
+ * disable,FW doesn't perform any action. Whenever any change in
+ * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
+ *
+ * return - 0 on success, appropriate error values on failure.
+ */
+int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value)
+{
+	QDF_STATUS status;
+
+	if (0 != wlan_hdd_validate_context(hdd_ctx))
+		return -EAGAIN;
+
+	status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle,
+						       set_value);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Failed to send chan avoid command to SME");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * hdd_set_roaming_in_progress() - to set the roaming in progress flag
+ * @value: value to set
+ *
+ * This function will set the passed value to roaming in progress flag.
+ *
+ * Return: None
+ */
+void hdd_set_roaming_in_progress(bool value)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return;
+	}
+
+	hdd_ctx->roaming_in_progress = value;
+	hdd_debug("Roaming in Progress set to %d", value);
+}
+
+bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx)
+{
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return false;
+	}
+
+	hdd_debug("roaming_in_progress = %d", hdd_ctx->roaming_in_progress);
+
+	return hdd_ctx->roaming_in_progress;
+}
+
+/**
+ * hdd_is_connection_in_progress() - check if connection is in
+ * progress
+ * @session_id: session id
+ * @reason: scan reject reason
+ *
+ * Go through each adapter and check if Connection is in progress
+ *
+ * Return: true if connection is in progress else false
+ */
+bool hdd_is_connection_in_progress(uint8_t *session_id,
+				enum scan_reject_states *reason)
+{
+	struct hdd_station_ctx *hdd_sta_ctx = NULL;
+	struct hdd_adapter *adapter = NULL;
+	uint8_t sta_id = 0;
+	uint8_t *sta_mac = NULL;
+	struct hdd_context *hdd_ctx;
+	mac_handle_t mac_handle;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return false;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		hdd_debug("Adapter with device mode %s(%d) exists",
+			  qdf_opmode_str(adapter->device_mode),
+			  adapter->device_mode);
+		if (((QDF_STA_MODE == adapter->device_mode)
+			|| (QDF_P2P_CLIENT_MODE == adapter->device_mode)
+			|| (QDF_P2P_DEVICE_MODE == adapter->device_mode))
+			&& (eConnectionState_Connecting ==
+				(WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
+					conn_info.connState)) {
+			hdd_debug("%pK(%d) Connection is in progress",
+				WLAN_HDD_GET_STATION_CTX_PTR(adapter),
+				adapter->session_id);
+			if (session_id && reason) {
+				*session_id = adapter->session_id;
+				*reason = CONNECTION_IN_PROGRESS;
+			}
+			return true;
+		}
+		/*
+		 * sme_neighbor_middle_of_roaming is for LFR2
+		 * hdd_is_roaming_in_progress is for LFR3
+		 */
+		if (((QDF_STA_MODE == adapter->device_mode) &&
+		     sme_neighbor_middle_of_roaming(
+			     mac_handle,
+			     adapter->session_id)) ||
+		    hdd_is_roaming_in_progress(hdd_ctx)) {
+			hdd_debug("%pK(%d) Reassociation in progress",
+				WLAN_HDD_GET_STATION_CTX_PTR(adapter),
+				adapter->session_id);
+			if (session_id && reason) {
+				*session_id = adapter->session_id;
+				*reason = REASSOC_IN_PROGRESS;
+			}
+			return true;
+		}
+		if ((QDF_STA_MODE == adapter->device_mode) ||
+			(QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
+			(QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
+			hdd_sta_ctx =
+				WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+			if ((eConnectionState_Associated ==
+			    hdd_sta_ctx->conn_info.connState)
+			    && sme_is_sta_key_exchange_in_progress(
+			    mac_handle, adapter->session_id)) {
+				sta_mac = (uint8_t *)
+					&(adapter->mac_addr.bytes[0]);
+				hdd_debug("client " MAC_ADDRESS_STR
+					" is in middle of WPS/EAPOL exchange.",
+					MAC_ADDR_ARRAY(sta_mac));
+				if (session_id && reason) {
+					*session_id = adapter->session_id;
+					*reason = EAPOL_IN_PROGRESS;
+				}
+				return true;
+			}
+		} else if ((QDF_SAP_MODE == adapter->device_mode) ||
+				(QDF_P2P_GO_MODE == adapter->device_mode)) {
+			for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
+				sta_id++) {
+				if (!((adapter->sta_info[sta_id].in_use)
+				    && (OL_TXRX_PEER_STATE_CONN ==
+				    adapter->sta_info[sta_id].peer_state)))
+					continue;
+
+				sta_mac = (uint8_t *)
+						&(adapter->sta_info[sta_id].
+							sta_mac.bytes[0]);
+				hdd_debug("client " MAC_ADDRESS_STR
+				" of SAP/GO is in middle of WPS/EAPOL exchange",
+				MAC_ADDR_ARRAY(sta_mac));
+				if (session_id && reason) {
+					*session_id = adapter->session_id;
+					*reason = SAP_EAPOL_IN_PROGRESS;
+				}
+				return true;
+			}
+			if (hdd_ctx->connection_in_progress) {
+				hdd_debug("AP/GO: connection is in progress");
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+/**
+ * hdd_restart_sap() - to restart SAP in driver internally
+ * @ap_adapter: Pointer to SAP struct hdd_adapter structure
+ *
+ * Return: None
+ */
+void hdd_restart_sap(struct hdd_adapter *ap_adapter)
+{
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	struct hdd_hostapd_state *hostapd_state;
+	QDF_STATUS qdf_status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
+	tsap_config_t *sap_config;
+	void *sap_ctx;
+
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
+	sap_config = &hdd_ap_ctx->sap_config;
+	sap_ctx = hdd_ap_ctx->sap_context;
+
+	mutex_lock(&hdd_ctx->sap_lock);
+	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
+		wlan_hdd_del_station(ap_adapter);
+		hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
+		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
+		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
+			qdf_status =
+				qdf_wait_for_event_completion(&hostapd_state->
+					qdf_stop_bss_event,
+					SME_CMD_START_STOP_BSS_TIMEOUT);
+
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+				hdd_err("SAP Stop Failed");
+				goto end;
+			}
+		}
+		clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
+		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
+			ap_adapter->device_mode, ap_adapter->session_id);
+		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
+					    false);
+		hdd_err("SAP Stop Success");
+
+		if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
+			hdd_err("SAP Not able to set AP IEs");
+			wlansap_reset_sap_config_add_ie(sap_config,
+					eUPDATE_IE_ALL);
+			goto end;
+		}
+
+		qdf_event_reset(&hostapd_state->qdf_event);
+		if (wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
+				      sap_config,
+				      ap_adapter->dev) != QDF_STATUS_SUCCESS) {
+			hdd_err("SAP Start Bss fail");
+			wlansap_reset_sap_config_add_ie(sap_config,
+					eUPDATE_IE_ALL);
+			goto end;
+		}
+
+		hdd_info("Waiting for SAP to start");
+		qdf_status =
+			qdf_wait_for_event_completion(&hostapd_state->qdf_event,
+					SME_CMD_START_STOP_BSS_TIMEOUT);
+		wlansap_reset_sap_config_add_ie(sap_config,
+				eUPDATE_IE_ALL);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			hdd_err("SAP Start failed");
+			goto end;
+		}
+		hdd_err("SAP Start Success");
+		set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
+		if (hostapd_state->bss_state == BSS_START) {
+			policy_mgr_incr_active_session(hdd_ctx->psoc,
+						ap_adapter->device_mode,
+						ap_adapter->session_id);
+			hdd_green_ap_start_state_mc(hdd_ctx,
+						    ap_adapter->device_mode,
+						    true);
+		}
+	}
+end:
+	mutex_unlock(&hdd_ctx->sap_lock);
+}
+
+/**
+ * hdd_check_and_restart_sap_with_non_dfs_acs() - Restart SAP
+ * with non dfs acs
+ *
+ * Restarts SAP in non-DFS ACS mode when STA-AP mode DFS is not supported
+ *
+ * Return: None
+ */
+void hdd_check_and_restart_sap_with_non_dfs_acs(void)
+{
+	struct hdd_adapter *ap_adapter;
+	struct hdd_context *hdd_ctx;
+	struct cds_context *cds_ctx;
+	uint8_t restart_chan;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return;
+	}
+
+	cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+	if (!cds_ctx) {
+		hdd_err("Invalid CDS Context");
+		return;
+	}
+
+	if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc)
+		!= (QDF_STA_MASK | QDF_SAP_MASK)) {
+		hdd_debug("Concurrency mode is not SAP");
+		return;
+	}
+
+	ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
+	if (ap_adapter &&
+	    test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags) &&
+	    wlan_reg_is_dfs_ch(hdd_ctx->pdev,
+			       ap_adapter->session.ap.operating_channel)) {
+
+		hdd_warn("STA-AP Mode DFS not supported, Switch SAP channel to Non DFS");
+
+		restart_chan =
+			hdd_get_safe_channel_from_pcl_and_acs_range(ap_adapter);
+		if (!restart_chan ||
+		    wlan_reg_is_dfs_ch(hdd_ctx->pdev, restart_chan))
+			restart_chan = SAP_DEFAULT_5GHZ_CHANNEL;
+
+		hdd_switch_sap_channel(ap_adapter, restart_chan, true);
+	}
+}
+
+/**
+ * hdd_set_connection_in_progress() - to set the connection in
+ * progress flag
+ * @value: value to set
+ *
+ * This function will set the passed value to connection in progress flag.
+ * If value is previously being set to true then no need to set it again.
+ *
+ * Return: true if value is being set correctly and false otherwise.
+ */
+bool hdd_set_connection_in_progress(bool value)
+{
+	bool status = true;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return false;
+	}
+
+	qdf_spin_lock(&hdd_ctx->connection_status_lock);
+	/*
+	 * if the value is set to true previously and if someone is
+	 * trying to make it true again then it could be some race
+	 * condition being triggered. Avoid this situation by returning
+	 * false
+	 */
+	if (hdd_ctx->connection_in_progress && value)
+		status = false;
+	else
+		hdd_ctx->connection_in_progress = value;
+	qdf_spin_unlock(&hdd_ctx->connection_status_lock);
+	return status;
+}
+
+int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int set_value)
+{
+	if (!adapter) {
+		hdd_err("Invalid adapter");
+		return -EINVAL;
+	}
+	hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value);
+	sme_cli_set_command(adapter->session_id,
+			    WMA_VDEV_MCC_SET_TIME_QUOTA,
+			    set_value, VDEV_CMD);
+	return 0;
+
+}
+
+int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
+{
+	if (!adapter) {
+		hdd_err("Invalid adapter");
+		return -EINVAL;
+	}
+
+	hdd_info("Send MCC latency WMA: %d", set_value);
+	sme_cli_set_command(adapter->session_id,
+			    WMA_VDEV_MCC_SET_TIME_LATENCY,
+			    set_value, VDEV_CMD);
+	return 0;
+}
+
+struct hdd_adapter *wlan_hdd_get_adapter_from_vdev(struct wlan_objmgr_psoc
+					      *psoc, uint8_t vdev_id)
+{
+	struct hdd_adapter *adapter = NULL;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	/*
+	 * Currently PSOC is not being used. But this logic will
+	 * change once we have the converged implementation of
+	 * HDD context per PSOC in place. This would break if
+	 * multiple vdev objects reuse the vdev id.
+	 */
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (!adapter)
+		hdd_err("Get adapter by vdev id failed");
+
+	return adapter;
+}
+
+int hdd_get_rssi_snr_by_bssid(struct hdd_adapter *adapter, const uint8_t *bssid,
+			      int8_t *rssi, int8_t *snr)
+{
+	QDF_STATUS status;
+	mac_handle_t mac_handle;
+	struct csr_roam_profile *roam_profile;
+
+	roam_profile = hdd_roam_profile(adapter);
+	mac_handle = hdd_adapter_get_mac_handle(adapter);
+	status = sme_get_rssi_snr_by_bssid(mac_handle,
+					   roam_profile, bssid, rssi, snr);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_warn("sme_get_rssi_snr_by_bssid failed");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
+ * @adapter - HDD adapter
+ *
+ * Return: 0 on success and non zero value on failure
+ */
+int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx;
+	int ret;
+	QDF_STATUS status;
+	uint8_t sys_pref = 0;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret < 0)
+		return ret;
+
+	ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc,
+				     &sys_pref);
+	/* set the system preferece to default */
+	policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref);
+
+	/* clear the bitmap */
+	adapter->active_ac = 0;
+
+	hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
+		  adapter->session_id, adapter->active_ac);
+
+	status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
+						   adapter->session_id,
+						   false, 0, 0, false);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("failed to reset limit off chan params");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+/**
+ * hdd_start_driver_ops_timer() - Starts driver ops inactivity timer
+ * @drv_op: Enum indicating driver op
+ *
+ * Return: none
+ */
+void hdd_start_driver_ops_timer(int drv_op)
+{
+	memset(drv_ops_string, 0, MAX_OPS_NAME_STRING_SIZE);
+	switch (drv_op) {
+	case eHDD_DRV_OP_PROBE:
+		memcpy(drv_ops_string, "probe", sizeof("probe"));
+		break;
+	case eHDD_DRV_OP_REMOVE:
+		memcpy(drv_ops_string, "remove", sizeof("remove"));
+		break;
+	case eHDD_DRV_OP_SHUTDOWN:
+		memcpy(drv_ops_string, "shutdown", sizeof("shutdown"));
+		break;
+	case eHDD_DRV_OP_REINIT:
+		memcpy(drv_ops_string, "reinit", sizeof("reinit"));
+		break;
+	case eHDD_DRV_OP_IFF_UP:
+		memcpy(drv_ops_string, "iff_up", sizeof("iff_up"));
+		break;
+	}
+
+	hdd_drv_ops_task = current;
+	qdf_timer_start(&hdd_drv_ops_inactivity_timer,
+		HDD_OPS_INACTIVITY_TIMEOUT * qdf_timer_get_multiplier());
+}
+
+/**
+ * hdd_stop_driver_ops_timer() - Stops driver ops inactivity timer
+ *
+ * Return: none
+ */
+void hdd_stop_driver_ops_timer(void)
+{
+	qdf_timer_sync_cancel(&hdd_drv_ops_inactivity_timer);
+}
+
+/**
+ * hdd_drv_ops_inactivity_handler() - Timeout handler for driver ops
+ * inactivity timer
+ *
+ * Return: None
+ */
+void hdd_drv_ops_inactivity_handler(void)
+{
+	hdd_err("WLAN_BUG_RCA %s: %d Sec timer expired while in .%s",
+		__func__, HDD_OPS_INACTIVITY_TIMEOUT/1000, drv_ops_string);
+
+	if (hdd_drv_ops_task) {
+		printk("Call stack for \"%s\"\n", hdd_drv_ops_task->comm);
+		qdf_print_thread_trace(hdd_drv_ops_task);
+	} else {
+		hdd_err("hdd_drv_ops_task is null");
+	}
+
+	/* Driver shutdown is stuck, no recovery possible at this point */
+	if (0 == qdf_mem_cmp(&drv_ops_string[0], "shutdown",
+		sizeof("shutdown")))
+		QDF_BUG(0);
+
+	if (cds_is_fw_down()) {
+		hdd_err("FW is down");
+		return;
+	}
+
+	cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
+}
+
+/**
+ * hdd_set_rx_mode_rps() - Enable/disable RPS in SAP mode
+ * @struct hdd_context *hdd_ctx
+ * @struct hdd_adapter *padapter
+ * @bool enble
+ *
+ * Return: none
+ */
+void hdd_set_rx_mode_rps(bool enable)
+{
+	struct cds_config_info *cds_cfg = cds_get_ini_config();
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter;
+
+	if (!cds_cfg)
+		return;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx)
+		return;
+
+	adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
+	if (!adapter)
+		return;
+
+	if (!hdd_ctx->rps && cds_cfg->uc_offload_enabled) {
+		if (enable && !cds_cfg->rps_enabled)
+			hdd_send_rps_ind(adapter);
+		else if (!enable && cds_cfg->rps_enabled)
+			hdd_send_rps_disable_ind(adapter);
+	}
+}
+
+bool hdd_is_cli_iface_up(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter = NULL;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if ((adapter->device_mode == QDF_STA_MODE ||
+		     adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
+		    qdf_atomic_test_bit(DEVICE_IFACE_OPENED,
+					&adapter->event_flags)){
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/* Register the module init/exit functions */
+module_init(hdd_module_init);
+module_exit(hdd_module_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Qualcomm Atheros, Inc.");
+MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
+
+static const struct kernel_param_ops con_mode_ops = {
+	.set = con_mode_handler,
+	.get = param_get_int,
+};
+
+static const struct kernel_param_ops con_mode_ftm_ops = {
+	.set = con_mode_handler_ftm,
+	.get = param_get_int,
+};
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+static const struct kernel_param_ops con_mode_monitor_ops = {
+	.set = con_mode_handler_monitor,
+	.get = param_get_int,
+};
+#endif
+
+static const struct kernel_param_ops fwpath_ops = {
+	.set = fwpath_changed_handler,
+	.get = param_get_string,
+};
+
+module_param_cb(con_mode, &con_mode_ops, &con_mode,
+		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
+		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+module_param_cb(con_mode_monitor, &con_mode_monitor_ops, &con_mode_monitor,
+		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+#endif
+
+module_param_cb(fwpath, &fwpath_ops, &fwpath,
+		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
+
+module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
+
+module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);
diff --git a/core/hdd/src/wlan_hdd_memdump.c b/core/hdd/src/wlan_hdd_memdump.c
new file mode 100644
index 0000000..ea01caa
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_memdump.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2016-2018 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 : wlan_hdd_memdump.c
+ *
+ * WLAN Host Device Driver file for dumping firmware memory
+ *
+ */
+
+#include <sme_api.h>
+#include <wlan_hdd_includes.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/proc_fs.h> /* Necessary because we use the proc fs */
+#include <linux/uaccess.h> /* for copy_to_user */
+
+
+#ifdef MULTI_IF_NAME
+#define PROCFS_DRIVER_DUMP_DIR "debugdriver" MULTI_IF_NAME
+#else
+#define PROCFS_DRIVER_DUMP_DIR "debugdriver"
+#endif
+#define PROCFS_DRIVER_DUMP_NAME "driverdump"
+#define PROCFS_DRIVER_DUMP_PERM 0444
+
+static struct proc_dir_entry *proc_file_driver, *proc_dir_driver;
+
+/** memdump_get_file_data() - get data available in proc file
+ *
+ * @file - handle for the proc file.
+ *
+ * This function is used to retrieve the data passed while
+ * creating proc file entry.
+ *
+ * Return: void pointer to hdd_context
+ */
+static void *memdump_get_file_data(struct file *file)
+{
+	void *hdd_ctx;
+
+	hdd_ctx = PDE_DATA(file_inode(file));
+	return hdd_ctx;
+}
+
+/**
+ * hdd_driver_mem_cleanup() - Frees memory allocated for
+ * driver dump
+ *
+ * This function unallocates driver dump memory.
+ *
+ * Return: None
+ */
+static void hdd_driver_mem_cleanup(void)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("Invalid HDD context");
+		return;
+	}
+
+	if (hdd_ctx->driver_dump_mem) {
+		qdf_mem_free(hdd_ctx->driver_dump_mem);
+		hdd_ctx->driver_dump_mem = NULL;
+	}
+}
+
+
+/**
+ * __hdd_driver_memdump_read() - perform read operation in driver
+ * memory dump proc file
+ * @file  - handle for the proc file.
+ * @buf   - pointer to user space buffer.
+ * @count - number of bytes to be read.
+ * @pos   - offset in the from buffer.
+ *
+ * This function performs read operation for the driver memory dump proc file.
+ *
+ * Return: number of bytes read on success
+ *         negative error code in case of failure
+ *         0 in case of no more data
+ */
+static ssize_t __hdd_driver_memdump_read(struct file *file, char __user *buf,
+					 size_t count, loff_t *pos)
+{
+	int status;
+	QDF_STATUS qdf_status;
+	struct hdd_context *hdd_ctx;
+	size_t no_of_bytes_read = 0;
+
+	hdd_ctx = memdump_get_file_data(file);
+
+	hdd_debug("Read req for size:%zu pos:%llu", count, *pos);
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status != 0)
+		return -EINVAL;
+
+	mutex_lock(&hdd_ctx->memdump_lock);
+	if (*pos < 0) {
+		hdd_err("Invalid start offset for memdump read");
+		mutex_unlock(&hdd_ctx->memdump_lock);
+		return -EINVAL;
+	} else if (!count || (hdd_ctx->driver_dump_size &&
+				(*pos >= hdd_ctx->driver_dump_size))) {
+		mutex_unlock(&hdd_ctx->memdump_lock);
+		hdd_debug("No more data to copy");
+		return 0;
+	} else if ((*pos == 0) || (hdd_ctx->driver_dump_mem == NULL)) {
+		/*
+		 * Allocate memory for Driver memory dump.
+		 */
+		if (!hdd_ctx->driver_dump_mem) {
+			hdd_ctx->driver_dump_mem =
+				qdf_mem_malloc(DRIVER_MEM_DUMP_SIZE);
+			if (!hdd_ctx->driver_dump_mem) {
+				hdd_err("qdf_mem_malloc failed");
+				mutex_unlock(&hdd_ctx->memdump_lock);
+				return -ENOMEM;
+			}
+		}
+
+		qdf_status = qdf_state_info_dump_all(hdd_ctx->driver_dump_mem,
+						DRIVER_MEM_DUMP_SIZE,
+						&hdd_ctx->driver_dump_size);
+		/*
+		 * If qdf_status is QDF_STATUS_E_NOMEM, then memory allocated is
+		 * insufficient to dump driver information. This print can give
+		 * information to allocate more memory if more information from
+		 * each layer is added in future.
+		 */
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			hdd_err("Error in dump driver information, status %d",
+				qdf_status);
+		hdd_debug("driver_dump_size: %d",
+					hdd_ctx->driver_dump_size);
+	}
+
+	if (count > hdd_ctx->driver_dump_size - *pos)
+		no_of_bytes_read = hdd_ctx->driver_dump_size - *pos;
+	else
+		no_of_bytes_read = count;
+
+	if (copy_to_user(buf, hdd_ctx->driver_dump_mem + *pos,
+					no_of_bytes_read)) {
+		hdd_err("copy to user space failed");
+		mutex_unlock(&hdd_ctx->memdump_lock);
+		return -EFAULT;
+	}
+
+	/* offset(pos) should be updated here based on the copy done */
+	*pos += no_of_bytes_read;
+
+	/* Entire driver memory dump copy completed */
+	if (*pos >= hdd_ctx->driver_dump_size)
+		hdd_driver_mem_cleanup();
+
+	mutex_unlock(&hdd_ctx->memdump_lock);
+
+	return no_of_bytes_read;
+}
+
+/**
+ * hdd_driver_memdump_read() - perform read operation in driver
+ * memory dump proc file
+ * @file  - handle for the proc file.
+ * @buf   - pointer to user space buffer.
+ * @count - number of bytes to be read.
+ * @pos   - offset in the from buffer.
+ *
+ * This function performs read operation for the driver memory dump proc file.
+ *
+ * Return: number of bytes read on success
+ *         negative error code in case of failure
+ *         0 in case of no more data
+ */
+static ssize_t hdd_driver_memdump_read(struct file *file, char __user *buf,
+				       size_t count, loff_t *pos)
+{
+	ssize_t len;
+
+	cds_ssr_protect(__func__);
+	len = __hdd_driver_memdump_read(file, buf, count, pos);
+	cds_ssr_unprotect(__func__);
+
+	return len;
+}
+
+/**
+ * struct driver_dump_fops - file operations for driver dump feature
+ * @read - read function for driver dump operation.
+ *
+ * This structure initialize the file operation handle for memory
+ * dump feature
+ */
+static const struct file_operations driver_dump_fops = {
+read: hdd_driver_memdump_read
+};
+
+/**
+ * hdd_driver_memdump_procfs_init() - Initialize procfs for driver memory dump
+ * @hdd_ctx Pointer to hdd context
+ *
+ * This function create file under proc file system to be used later for
+ * processing driver memory dump
+ *
+ * Return:   0 on success, error code otherwise.
+ */
+static int hdd_driver_memdump_procfs_init(struct hdd_context *hdd_ctx)
+{
+	proc_dir_driver = proc_mkdir(PROCFS_DRIVER_DUMP_DIR, NULL);
+	if (proc_dir_driver == NULL) {
+		pr_debug("Could not initialize /proc/%s\n",
+			 PROCFS_DRIVER_DUMP_DIR);
+		return -ENOMEM;
+	}
+
+	proc_file_driver = proc_create_data(PROCFS_DRIVER_DUMP_NAME,
+				     PROCFS_DRIVER_DUMP_PERM, proc_dir_driver,
+				     &driver_dump_fops, hdd_ctx);
+	if (proc_file_driver == NULL) {
+		remove_proc_entry(PROCFS_DRIVER_DUMP_NAME, proc_dir_driver);
+		pr_debug("Could not initialize /proc/%s\n",
+			  PROCFS_DRIVER_DUMP_NAME);
+		return -ENOMEM;
+	}
+
+	pr_debug("/proc/%s/%s created\n", PROCFS_DRIVER_DUMP_DIR,
+		 PROCFS_DRIVER_DUMP_NAME);
+	return 0;
+}
+
+/**
+ * hdd_driver_memdump_procfs_remove() - Remove file/dir under procfs
+ * for driver memory dump
+ *
+ * This function removes file/dir under proc file system that was
+ * processing driver memory dump
+ *
+ * Return:  None
+ */
+static void hdd_driver_memdump_procfs_remove(void)
+{
+	remove_proc_entry(PROCFS_DRIVER_DUMP_NAME, proc_dir_driver);
+	pr_debug("/proc/%s/%s removed\n", PROCFS_DRIVER_DUMP_DIR,
+					  PROCFS_DRIVER_DUMP_NAME);
+	remove_proc_entry(PROCFS_DRIVER_DUMP_DIR, NULL);
+	pr_debug("/proc/%s removed\n", PROCFS_DRIVER_DUMP_DIR);
+}
+
+/**
+ * hdd_driver_memdump_init() - Intialization function for driver
+ * memory dump feature
+ *
+ * This function creates proc file for driver memdump feature
+ *
+ * Return - 0 on success, error otherwise
+ */
+int hdd_driver_memdump_init(void)
+{
+	int status;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("Invalid HDD context");
+		return -EINVAL;
+	}
+
+	mutex_init(&hdd_ctx->memdump_lock);
+
+	status = hdd_driver_memdump_procfs_init(hdd_ctx);
+	if (status) {
+		hdd_err("Failed to create proc file");
+		return status;
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_driver_memdump_deinit() - De initialize driver memdump feature
+ *
+ * This function removes proc file created for driver memdump feature.
+ *
+ * Return: None
+ */
+void hdd_driver_memdump_deinit(void)
+{
+	hdd_driver_memdump_procfs_remove();
+
+	hdd_driver_mem_cleanup();
+}
diff --git a/core/hdd/src/wlan_hdd_nan.c b/core/hdd/src/wlan_hdd_nan.c
new file mode 100644
index 0000000..180c4d8
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_nan.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_nan.c
+ *
+ * WLAN Host Device Driver NAN API implementation
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <net/cfg80211.h>
+#include <ani_global.h>
+#include "sme_api.h"
+#include "nan_api.h"
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_nan.h"
+#include <qca_vendor.h>
+#include "cfg_nan_api.h"
+
+/**
+ * __wlan_hdd_cfg80211_nan_request() - cfg80211 NAN request handler
+ * @wiphy: driver's wiphy struct
+ * @wdev: wireless device to which the request is targeted
+ * @data: actual request data (netlink-encapsulated)
+ * @data_len: length of @data
+ *
+ * This is called when userspace needs to send a nan request to
+ * firmware. The wlan host driver simply de-encapsulates the
+ * request from the netlink payload and then forwards it to
+ * firmware via SME.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data,
+					   int data_len)
+{
+	tNanRequestReq nan_req;
+	QDF_STATUS status;
+	int ret_val;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter_dev(wdev->netdev);
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		return ret_val;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err_rl("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (!cfg_nan_get_enable(hdd_ctx->psoc)) {
+		hdd_err("NaN support is not enabled in INI");
+		return -EPERM;
+	}
+
+	nan_req.request_data_len = data_len;
+	nan_req.request_data = data;
+
+	status = sme_nan_request(&nan_req);
+	if (QDF_STATUS_SUCCESS != status)
+		ret_val = -EINVAL;
+
+	return ret_val;
+}
+
+/**
+ * wlan_hdd_cfg80211_nan_request() - handle NAN request
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This function is called by userspace to send a NAN request to
+ * firmware.  This is an SSR-protected wrapper function.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  const void *data,
+				  int data_len)
+
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+void wlan_hdd_cfg80211_nan_callback(hdd_handle_t hdd_handle, tSirNanEvent *msg)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	struct sk_buff *vendor_event;
+	int status;
+
+	if (!msg) {
+		hdd_err("msg received here is null");
+		return;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return;
+
+	vendor_event =
+		cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+					    NULL,
+					    msg->event_data_len + NLMSG_HDRLEN,
+					    QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
+					    GFP_KERNEL);
+
+	if (!vendor_event) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+	if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
+		    msg->event_data_len, msg->event_data)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR_NAN put fail");
+		kfree_skb(vendor_event);
+		return;
+	}
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+}
+
+/**
+ * wlan_hdd_nan_is_supported() - HDD NAN support query function
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * This function is called to determine if NAN is supported by the
+ * driver and by the firmware.
+ *
+ * Return: true if NAN is supported by the driver and firmware
+ */
+bool wlan_hdd_nan_is_supported(struct hdd_context *hdd_ctx)
+{
+	return cfg_nan_get_enable(hdd_ctx->psoc) &&
+		sme_is_feature_supported_by_fw(NAN);
+}
diff --git a/core/hdd/src/wlan_hdd_nan_datapath.c b/core/hdd/src/wlan_hdd_nan_datapath.c
new file mode 100644
index 0000000..306b3b3
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_nan_datapath.c
@@ -0,0 +1,857 @@
+/*
+ * Copyright (c) 2016-2018 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: wlan_hdd_nan_datapath.c
+ *
+ * WLAN Host Device Driver nan datapath API implementation
+ */
+#include <wlan_hdd_includes.h>
+#include <linux/if.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include "wlan_hdd_includes.h"
+#include "wlan_hdd_p2p.h"
+#include "wma_api.h"
+#include "wlan_hdd_assoc.h"
+#include "sme_nan_datapath.h"
+#include "wlan_hdd_object_manager.h"
+#include <qca_vendor.h>
+#include "os_if_nan.h"
+#include "wlan_nan_api.h"
+#include "nan_public_structs.h"
+#include "cfg_nan_api.h"
+#include "wlan_mlme_ucfg_api.h"
+
+/**
+ * hdd_nan_datapath_target_config() - Configure NAN datapath features
+ * @hdd_ctx: Pointer to HDD context
+ * @cfg: Pointer to target device capability information
+ *
+ * NAN datapath functionality is enabled if it is enabled in
+ * .ini file and also supported on target device.
+ *
+ * Return: None
+ */
+void hdd_nan_datapath_target_config(struct hdd_context *hdd_ctx,
+					struct wma_tgt_cfg *tgt_cfg)
+{
+	hdd_ctx->nan_datapath_enabled =
+			cfg_nan_get_datapath_enable(hdd_ctx->psoc) &&
+			tgt_cfg->nan_datapath_enabled;
+	hdd_debug("NAN Datapath Enable: %d (Host: %d FW: %d)",
+		  hdd_ctx->nan_datapath_enabled,
+		  cfg_nan_get_datapath_enable(hdd_ctx->psoc),
+		  tgt_cfg->nan_datapath_enabled);
+}
+
+/**
+ * hdd_close_ndi() - close NAN Data interface
+ * @adapter: adapter context
+ *
+ * Close the adapter if start BSS fails
+ *
+ * Returns: 0 on success, negative error code otherwise
+ */
+static int hdd_close_ndi(struct hdd_adapter *adapter)
+{
+	int errno;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter();
+
+	/* check if the adapter is in NAN Data mode */
+	if (QDF_NDI_MODE != adapter->device_mode) {
+		hdd_err("Interface is not in NDI mode");
+		return -EINVAL;
+	}
+	wlan_hdd_netif_queue_control(adapter,
+				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+				     WLAN_CONTROL_PATH);
+
+#ifdef WLAN_OPEN_SOURCE
+	cancel_work_sync(&adapter->ipv4_notifier_work);
+#endif
+	hdd_deregister_tx_flow_control(adapter);
+
+#ifdef WLAN_NS_OFFLOAD
+#ifdef WLAN_OPEN_SOURCE
+	cancel_work_sync(&adapter->ipv6_notifier_work);
+#endif
+#endif
+	errno = hdd_vdev_destroy(adapter);
+	if (errno)
+		hdd_err("failed to destroy vdev: %d", errno);
+
+	/* We are good to close the adapter */
+	hdd_close_adapter(hdd_ctx, adapter, true);
+
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * hdd_is_ndp_allowed() - Indicates if NDP is allowed
+ * @hdd_ctx: hdd context
+ *
+ * NDP is not allowed with any other role active except STA.
+ *
+ * Return:  true if allowed, false otherwise
+ */
+static bool hdd_is_ndp_allowed(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_station_ctx *sta_ctx;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		switch (adapter->device_mode) {
+		case QDF_P2P_GO_MODE:
+		case QDF_SAP_MODE:
+			if (test_bit(SOFTAP_BSS_STARTED,
+					&adapter->event_flags))
+				return false;
+			break;
+		case QDF_P2P_CLIENT_MODE:
+		case QDF_IBSS_MODE:
+			sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+			if (hdd_conn_is_connected(sta_ctx) ||
+					hdd_is_connecting(sta_ctx))
+				return false;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return true;
+}
+
+/**
+ * hdd_ndi_start_bss() - Start BSS on NAN data interface
+ * @adapter: adapter context
+ * @operating_channel: channel on which the BSS to be started
+ *
+ * Return: 0 on success, error value on failure
+ */
+static int hdd_ndi_start_bss(struct hdd_adapter *adapter,
+				uint8_t operating_channel)
+{
+	QDF_STATUS status;
+	uint32_t roam_id;
+	struct csr_roam_profile *roam_profile;
+	mac_handle_t mac_handle;
+	uint8_t wmm_mode = 0;
+	struct hdd_context *hdd_ctx;
+	uint8_t value = 0;
+
+	hdd_enter();
+
+	roam_profile = hdd_roam_profile(adapter);
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	status = ucfg_mlme_get_wmm_mode(hdd_ctx->psoc, &wmm_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Get wmm_mode failed");
+		return -EINVAL;
+	}
+
+	if (HDD_WMM_USER_MODE_NO_QOS == wmm_mode) {
+		/* QoS not enabled in cfg file*/
+		roam_profile->uapsd_mask = 0;
+	} else {
+		/* QoS enabled, update uapsd mask from cfg file*/
+		status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc, &value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_mask failed");
+			return -EINVAL;
+		}
+		roam_profile->uapsd_mask = value;
+	}
+
+	roam_profile->csrPersona = adapter->device_mode;
+
+	if (!operating_channel)
+		operating_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
+
+	roam_profile->ChannelInfo.numOfChannels = 1;
+	roam_profile->ChannelInfo.ChannelList = &operating_channel;
+
+	roam_profile->SSIDs.numOfSSIDs = 1;
+	roam_profile->SSIDs.SSIDList->SSID.length = 0;
+
+	roam_profile->phyMode = eCSR_DOT11_MODE_11ac;
+	roam_profile->BSSType = eCSR_BSS_TYPE_NDI;
+	roam_profile->BSSIDs.numOfBSSIDs = 1;
+	qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
+		&adapter->mac_addr.bytes[0],
+		QDF_MAC_ADDR_SIZE);
+
+	roam_profile->AuthType.numEntries = 1;
+	roam_profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+	roam_profile->EncryptionType.numEntries = 1;
+	roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
+
+	mac_handle = hdd_adapter_get_mac_handle(adapter);
+	status = sme_roam_connect(mac_handle, adapter->session_id,
+				  roam_profile, &roam_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("NDI sme_RoamConnect session %d failed with status %d -> NotConnected",
+			adapter->session_id, status);
+		/* change back to NotConnected */
+		hdd_conn_set_connection_state(adapter,
+					      eConnectionState_NotConnected);
+	} else {
+		hdd_info("sme_RoamConnect issued successfully for NDI");
+	}
+
+	roam_profile->ChannelInfo.ChannelList = NULL;
+	roam_profile->ChannelInfo.numOfChannels = 0;
+
+	hdd_exit();
+
+	return 0;
+}
+
+/**
+ * hdd_get_random_nan_mac_addr() - generate random non pre-existent mac address
+ * @hdd_ctx: hdd context pointer
+ * @mac_addr: mac address buffer to populate
+ *
+ * Return: status of operation
+ */
+static int hdd_get_random_nan_mac_addr(struct hdd_context *hdd_ctx,
+				       struct qdf_mac_addr *mac_addr)
+{
+	struct hdd_adapter *adapter;
+	uint8_t pos, bit_pos, byte_pos, mask;
+	uint8_t i, attempts, max_attempt = 16;
+
+	for (attempts = 0; attempts < max_attempt; attempts++) {
+		/* if NDI is present next addr is required to be 1 bit apart  */
+		adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
+		if (adapter) {
+			hdd_debug("NDI already exists, deriving next mac");
+			qdf_mem_copy(mac_addr, &adapter->mac_addr,
+				     sizeof(*mac_addr));
+			cds_rand_get_bytes(0, &pos, sizeof(pos));
+			/* skipping byte 0, 5 leaves 8*4=32 positions */
+			pos = pos % 32;
+			bit_pos = pos % 8;
+			byte_pos = pos / 8;
+			mask = 1 << bit_pos;
+			/* flip the required bit */
+			mac_addr->bytes[byte_pos + 1] ^= mask;
+		} else {
+			cds_rand_get_bytes(0, (uint8_t *)mac_addr,
+					   sizeof(*mac_addr));
+			/*
+			 * 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;
+		}
+		for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
+			if (!qdf_mem_cmp(hdd_ctx->config->intfMacAddr[i].bytes,
+					 mac_addr, sizeof(*mac_addr)))
+				continue;
+		}
+
+		adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
+		if (!adapter)
+			return 0;
+	}
+
+	hdd_err("unable to get non-pre-existing mac address in %d attempts",
+		max_attempt);
+
+	return -EINVAL;
+}
+
+void hdd_ndp_event_handler(struct hdd_adapter *adapter,
+			   struct csr_roam_info *roam_info,
+			   uint32_t roam_id, eRoamCmdStatus roam_status,
+			   eCsrRoamResult roam_result)
+{
+	bool success;
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(adapter->vdev);
+
+	if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) {
+		switch (roam_result) {
+		case eCSR_ROAM_RESULT_NDI_CREATE_RSP:
+			success = (roam_info->ndp.ndi_create_params.status ==
+					NAN_DATAPATH_RSP_STATUS_SUCCESS);
+			hdd_debug("posting ndi create status: %d to umac",
+				success);
+			os_if_nan_post_ndi_create_rsp(psoc, adapter->session_id,
+							success);
+			return;
+		case eCSR_ROAM_RESULT_NDI_DELETE_RSP:
+			success = (roam_info->ndp.ndi_create_params.status ==
+					NAN_DATAPATH_RSP_STATUS_SUCCESS);
+			hdd_debug("posting ndi delete status: %d to umac",
+				success);
+			os_if_nan_post_ndi_delete_rsp(psoc, adapter->session_id,
+							success);
+			return;
+		default:
+			hdd_err("in correct roam_result: %d", roam_result);
+			return;
+		}
+	} else {
+		hdd_err("in correct roam_status: %d", roam_status);
+		return;
+	}
+}
+
+/**
+ * __wlan_hdd_cfg80211_process_ndp_cmds() - handle NDP request
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This function is invoked to handle vendor command
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void *data, int data_len)
+{
+	int ret_val;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter();
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		return ret_val;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err_rl("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) {
+		hdd_err("NAN datapath is not enabled");
+		return -EPERM;
+	}
+	/* NAN data path coexists only with STA interface */
+	if (false == hdd_is_ndp_allowed(hdd_ctx)) {
+		hdd_err("Unsupported concurrency for NAN datapath");
+		return -EPERM;
+	}
+
+	/* NAN data path coexists only with STA interface */
+	if (false == hdd_is_ndp_allowed(hdd_ctx)) {
+		hdd_err("Unsupported concurrency for NAN datapath");
+		return -EPERM;
+	}
+
+	return os_if_nan_process_ndp_cmd(hdd_ctx->psoc,
+					 data, data_len);
+}
+
+/**
+ * wlan_hdd_cfg80211_process_ndp_cmd() - handle NDP request
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This function is called to send a NAN request to
+ * firmware. This is an SSR-protected wrapper function.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int update_ndi_state(struct hdd_adapter *adapter, uint32_t state)
+{
+	return os_if_nan_set_ndi_state(adapter->vdev, state);
+}
+
+/**
+ * hdd_init_nan_data_mode() - initialize nan data mode
+ * @adapter: adapter context
+ *
+ * Returns: 0 on success negative error code on error
+ */
+int hdd_init_nan_data_mode(struct hdd_adapter *adapter)
+{
+	struct net_device *wlan_dev = adapter->dev;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	QDF_STATUS status;
+	int32_t ret_val;
+	mac_handle_t mac_handle;
+	bool bval = false;
+
+	ret_val = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
+	if (ret_val) {
+		hdd_err("failed to create vdev: %d", ret_val);
+		return ret_val;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	/* Configure self HT/VHT capabilities */
+	sme_set_curr_device_mode(mac_handle, adapter->device_mode);
+
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+
+	sme_set_pdev_ht_vht_ies(mac_handle, bval);
+	sme_set_vdev_ies_per_band(mac_handle, adapter->session_id);
+
+	hdd_roam_profile_init(adapter);
+	hdd_register_wext(wlan_dev);
+
+	status = hdd_init_tx_rx(adapter);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("hdd_init_tx_rx() init failed, status %d", status);
+		ret_val = -EAGAIN;
+		goto error_init_txrx;
+	}
+
+	set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
+
+	status = hdd_wmm_adapter_init(adapter);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("hdd_wmm_adapter_init() failed, status %d", status);
+		ret_val = -EAGAIN;
+		goto error_wmm_init;
+	}
+
+	set_bit(WMM_INIT_DONE, &adapter->event_flags);
+
+	ret_val = wma_cli_set_command((int)adapter->session_id,
+			(int)WMI_PDEV_PARAM_BURST_ENABLE,
+			(int)HDD_ENABLE_SIFS_BURST_DEFAULT,
+			PDEV_CMD);
+	if (0 != ret_val)
+		hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
+
+
+	update_ndi_state(adapter, NAN_DATA_NDI_CREATING_STATE);
+	return ret_val;
+
+error_wmm_init:
+	clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
+	hdd_deinit_tx_rx(adapter);
+
+error_init_txrx:
+	hdd_unregister_wext(wlan_dev);
+
+	QDF_BUG(!hdd_vdev_destroy(adapter));
+
+	return ret_val;
+}
+
+int hdd_ndi_open(char *iface_name)
+{
+	struct hdd_adapter *adapter;
+	struct qdf_mac_addr random_ndi_mac;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	uint8_t *ndi_mac_addr;
+
+	hdd_enter();
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx null");
+		return -EINVAL;
+	}
+
+	if (cfg_nan_get_ndi_mac_randomize(hdd_ctx->psoc)) {
+		if (hdd_get_random_nan_mac_addr(hdd_ctx, &random_ndi_mac)) {
+			hdd_err("get random mac address failed");
+			return -EFAULT;
+		}
+		ndi_mac_addr = &random_ndi_mac.bytes[0];
+	} else {
+		ndi_mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
+		if (!ndi_mac_addr) {
+			hdd_err("get intf address failed");
+			return -EFAULT;
+		}
+	}
+
+	adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name,
+				   ndi_mac_addr, NET_NAME_UNKNOWN, true);
+	if (!adapter) {
+		hdd_err("hdd_open_adapter failed");
+		return -EINVAL;
+	}
+
+	hdd_exit();
+	return 0;
+}
+
+int hdd_ndi_start(char *iface_name, uint16_t transaction_id)
+{
+	int ret;
+	uint8_t op_channel;
+	QDF_STATUS status;
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	hdd_enter();
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is null");
+		return -EINVAL;
+	}
+
+	op_channel = cfg_nan_get_ndi_channel(hdd_ctx->psoc);
+	adapter = hdd_get_adapter_by_iface_name(hdd_ctx, iface_name);
+	if (!adapter) {
+		hdd_err("adapter is null");
+		return -EINVAL;
+	}
+
+	/* create nan vdev */
+	status = hdd_init_nan_data_mode(adapter);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("failed to init nan data intf, status :%d", status);
+		ret = -EFAULT;
+		goto err_handler;
+	}
+
+	/*
+	 * Create transaction id is required to be saved since the firmware
+	 * does not honor the transaction id for create request
+	 */
+	ucfg_nan_set_ndp_create_transaction_id(adapter->vdev,
+					       transaction_id);
+	ucfg_nan_set_ndi_state(adapter->vdev,
+			       NAN_DATA_NDI_CREATING_STATE);
+
+	/*
+	 * The NAN data interface has been created at this point.
+	 * Unlike traditional device modes, where the higher application
+	 * layer initiates connect / join / start, the NAN data
+	 * interface does not have any such formal requests. The NDI
+	 * create request is responsible for starting the BSS as well.
+	 */
+	if (op_channel != NAN_SOCIAL_CHANNEL_2_4GHZ &&
+	    op_channel != NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND &&
+	    op_channel != NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND) {
+		/* start NDI on the default 2.4 GHz social channel */
+		op_channel = NAN_SOCIAL_CHANNEL_2_4GHZ;
+	}
+
+	if (hdd_ndi_start_bss(adapter, op_channel)) {
+		hdd_err("NDI start bss failed");
+		ret = -EFAULT;
+		goto err_handler;
+	}
+
+	hdd_exit();
+	return 0;
+
+err_handler:
+
+	/* Start BSS failed, delete the interface */
+	hdd_close_ndi(adapter);
+	return ret;
+}
+
+int hdd_ndi_delete(uint8_t vdev_id, char *iface_name, uint16_t transaction_id)
+{
+	int ret;
+	struct hdd_adapter *adapter;
+	struct hdd_station_ctx *sta_ctx;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is null");
+		return -EINVAL;
+	}
+
+	/* check if adapter by vdev_id is valid NDI */
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (!adapter || !WLAN_HDD_IS_NDI(adapter)) {
+		hdd_err("NAN data interface %s is not available", iface_name);
+		return -EINVAL;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (!sta_ctx) {
+		hdd_err("sta_ctx is NULL");
+		return -EINVAL;
+	}
+
+	/* Since, the interface is being deleted, remove the broadcast id. */
+	hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = 0;
+	sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
+
+	os_if_nan_set_ndp_delete_transaction_id(adapter->vdev,
+						transaction_id);
+	os_if_nan_set_ndi_state(adapter->vdev, NAN_DATA_NDI_DELETING_STATE);
+
+	/* Delete the interface */
+	ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
+	if (ret)
+		hdd_err("NDI delete request failed");
+	else
+		hdd_err("NDI delete request successfully issued");
+
+	return ret;
+}
+
+void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id,
+				struct nan_datapath_inf_create_rsp *ndi_rsp)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter;
+	struct hdd_station_ctx *sta_ctx;
+	struct csr_roam_info roam_info = {0};
+	struct bss_description tmp_bss_descp = {0};
+	struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BCAST_INIT;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is null");
+		return;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (!adapter) {
+		hdd_err("adapter is null");
+		return;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (!sta_ctx) {
+		hdd_err("sta_ctx is null");
+		return;
+	}
+
+	if (ndi_rsp->status == QDF_STATUS_SUCCESS) {
+		hdd_alert("NDI interface successfully created");
+		os_if_nan_set_ndp_create_transaction_id(adapter->vdev, 0);
+		os_if_nan_set_ndi_state(adapter->vdev,
+					NAN_DATA_NDI_CREATED_STATE);
+		wlan_hdd_netif_queue_control(adapter,
+					WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
+					WLAN_CONTROL_PATH);
+	} else {
+		hdd_alert("NDI interface creation failed with reason %d",
+			ndi_rsp->reason /* create_reason */);
+	}
+
+	sta_ctx->broadcast_staid = ndi_rsp->sta_id;
+	hdd_save_peer(sta_ctx, sta_ctx->broadcast_staid, &bc_mac_addr);
+	hdd_roam_register_sta(adapter, &roam_info,
+				sta_ctx->broadcast_staid,
+				&bc_mac_addr, &tmp_bss_descp);
+	hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = adapter;
+}
+
+void hdd_ndi_close(uint8_t vdev_id)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is null");
+		return;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (!adapter) {
+		hdd_err("adapter is null");
+		return;
+	}
+
+	hdd_close_ndi(adapter);
+}
+
+void hdd_ndi_drv_ndi_delete_rsp_handler(uint8_t vdev_id)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter;
+	struct hdd_station_ctx *sta_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is null");
+		return;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (!adapter) {
+		hdd_err("adapter is null");
+		return;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (!sta_ctx) {
+		hdd_err("sta_ctx is null");
+		return;
+	}
+
+	hdd_ctx->sta_to_adapter[sta_ctx->broadcast_staid] = NULL;
+	hdd_roam_deregister_sta(adapter, sta_ctx->broadcast_staid);
+	hdd_delete_peer(sta_ctx, sta_ctx->broadcast_staid);
+	sta_ctx->broadcast_staid = HDD_WLAN_INVALID_STA_ID;
+
+	wlan_hdd_netif_queue_control(adapter,
+				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+				     WLAN_CONTROL_PATH);
+
+	complete(&adapter->disconnect_comp_var);
+}
+
+void hdd_ndp_session_end_handler(struct hdd_adapter *adapter)
+{
+	os_if_nan_ndi_session_end(adapter->vdev);
+}
+
+int hdd_ndp_get_peer_idx(uint8_t vdev_id, struct qdf_mac_addr *addr)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	return hdd_get_peer_idx(sta_ctx, addr);
+}
+
+/**
+ * hdd_ndp_new_peer_handler() - NDP new peer indication handler
+ * @adapter: pointer to adapter context
+ * @ind_params: indication parameters
+ *
+ * Return: none
+ */
+int hdd_ndp_new_peer_handler(uint8_t vdev_id, uint16_t sta_id,
+			struct qdf_mac_addr *peer_mac_addr, bool fist_peer)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter;
+	struct hdd_station_ctx *sta_ctx;
+	struct bss_description tmp_bss_descp = {0};
+	struct csr_roam_info roam_info = {0};
+
+	hdd_enter();
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is null");
+		return -EINVAL;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (!adapter) {
+		hdd_err("adapter is null");
+		return -EINVAL;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (!sta_ctx) {
+		hdd_err("sta_ctx is null");
+		return -EINVAL;
+	}
+
+	/* save peer in ndp ctx */
+	if (false == hdd_save_peer(sta_ctx, sta_id, peer_mac_addr)) {
+		hdd_err("Ndp peer table full. cannot save new peer");
+		return -EPERM;
+	}
+
+	/* this function is called for each new peer */
+	hdd_roam_register_sta(adapter, &roam_info, sta_id,
+				peer_mac_addr, &tmp_bss_descp);
+	hdd_ctx->sta_to_adapter[sta_id] = adapter;
+	/* perform following steps for first new peer ind */
+	if (fist_peer) {
+		hdd_info("Set ctx connection state to connected");
+		sta_ctx->conn_info.connState = 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);
+	}
+	hdd_exit();
+	return 0;
+}
+
+
+/**
+ * hdd_ndp_peer_departed_handler() - Handle NDP peer departed indication
+ * @adapter: pointer to adapter context
+ * @ind_params: indication parameters
+ *
+ * Return: none
+ */
+void hdd_ndp_peer_departed_handler(uint8_t vdev_id, uint16_t sta_id,
+			struct qdf_mac_addr *peer_mac_addr, bool last_peer)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter;
+	struct hdd_station_ctx *sta_ctx;
+
+	hdd_enter();
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is null");
+		return;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (!adapter) {
+		hdd_err("adapter is null");
+		return;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (!sta_ctx) {
+		hdd_err("sta_ctx is null");
+		return;
+	}
+
+	hdd_roam_deregister_sta(adapter, sta_id);
+	hdd_delete_peer(sta_ctx, sta_id);
+	hdd_ctx->sta_to_adapter[sta_id] = NULL;
+
+	if (last_peer) {
+		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.");
+		wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
+					     WLAN_CONTROL_PATH);
+	}
+	hdd_exit();
+}
diff --git a/core/hdd/src/wlan_hdd_nan_datapath.h b/core/hdd/src/wlan_hdd_nan_datapath.h
new file mode 100644
index 0000000..8504d8a
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_nan_datapath.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016-2018 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: wlan_hdd_nan_datapath.h
+ *
+ * WLAN Host Device Driver nan datapath API specification
+ */
+#ifndef __WLAN_HDD_NAN_DATAPATH_H
+#define __WLAN_HDD_NAN_DATAPATH_H
+
+struct hdd_context;
+struct hdd_tgt_cfg;
+struct hdd_config;
+struct hdd_adapter;
+struct wireless_dev;
+
+/* NAN Social channels */
+#define NAN_SOCIAL_CHANNEL_2_4GHZ 6
+#define NAN_SOCIAL_CHANNEL_5GHZ_LOWER_BAND 44
+#define NAN_SOCIAL_CHANNEL_5GHZ_UPPER_BAND 149
+
+#define NDP_BROADCAST_STAID           (0)
+
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+#define WLAN_HDD_IS_NDI(adapter) ((adapter)->device_mode == QDF_NDI_MODE)
+
+#define WLAN_HDD_IS_NDI_CONNECTED(adapter) ( \
+	eConnectionState_NdiConnected ==\
+		(adapter)->session.station.conn_info.connState)
+#else
+#define WLAN_HDD_IS_NDI(adapter)	(false)
+#define WLAN_HDD_IS_NDI_CONNECTED(adapter) (false)
+#endif /* WLAN_FEATURE_NAN_DATAPATH */
+
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+void hdd_nan_datapath_target_config(struct hdd_context *hdd_ctx,
+						struct wma_tgt_cfg *cfg);
+void hdd_ndp_event_handler(struct hdd_adapter *adapter,
+			   struct csr_roam_info *roam_info,
+			   uint32_t roam_id, eRoamCmdStatus roam_status,
+			   eCsrRoamResult roam_result);
+int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void *data, int data_len);
+int hdd_init_nan_data_mode(struct hdd_adapter *adapter);
+void hdd_ndp_session_end_handler(struct hdd_adapter *adapter);
+#else
+static inline void hdd_nan_datapath_target_config(struct hdd_context *hdd_ctx,
+						struct wma_tgt_cfg *cfg)
+{
+}
+static inline void hdd_ndp_event_handler(struct hdd_adapter *adapter,
+					 struct csr_roam_info *roam_info,
+					 uint32_t roam_id,
+					 eRoamCmdStatus roam_status,
+					 eCsrRoamResult roam_result)
+{
+}
+static inline int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data, int data_len)
+{
+	return 0;
+}
+static inline int hdd_init_nan_data_mode(struct hdd_adapter *adapter)
+{
+	return 0;
+}
+static inline void hdd_ndp_session_end_handler(struct hdd_adapter *adapter)
+{
+}
+#endif /* WLAN_FEATURE_NAN_DATAPATH */
+
+enum nan_datapath_state;
+struct nan_datapath_inf_create_rsp;
+
+int hdd_ndi_open(char *iface_name);
+int hdd_ndi_start(char *iface_name, uint16_t transaction_id);
+int hdd_ndi_delete(uint8_t vdev_id, char *iface_name, uint16_t transaction_id);
+void hdd_ndi_close(uint8_t vdev_id);
+void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id,
+			       struct nan_datapath_inf_create_rsp *ndi_rsp);
+void hdd_ndi_drv_ndi_delete_rsp_handler(uint8_t vdev_id);
+int hdd_ndp_get_peer_idx(uint8_t vdev_id, struct qdf_mac_addr *addr);
+int hdd_ndp_new_peer_handler(uint8_t vdev_id, uint16_t sta_id,
+			struct qdf_mac_addr *peer_mac_addr, bool fist_peer);
+void hdd_ndp_peer_departed_handler(uint8_t vdev_id, uint16_t sta_id,
+			struct qdf_mac_addr *peer_mac_addr, bool last_peer);
+
+#endif /* __WLAN_HDD_NAN_DATAPATH_H */
diff --git a/core/hdd/src/wlan_hdd_napi.c b/core/hdd/src/wlan_hdd_napi.c
new file mode 100644
index 0000000..7fe535d
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_napi.c
@@ -0,0 +1,558 @@
+/*
+ * Copyright (c) 2015-2018 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: wlan_hdd_napi.c
+ *
+ * WLAN HDD NAPI interface implementation
+ */
+#include <linux/smp.h> /* get_cpu */
+
+#include "wlan_hdd_napi.h"
+#include "cds_api.h"       /* cds_get_context */
+#include "hif.h"           /* hif_map_service...*/
+#include "wlan_hdd_main.h" /* hdd_err/warn... */
+#include "qdf_types.h"     /* QDF_MODULE_ID_... */
+#include "ce_api.h"
+
+/*  guaranteed to be initialized to zero/NULL by the standard */
+static struct qca_napi_data *hdd_napi_ctx;
+
+/**
+ * hdd_napi_get_all() - return the whole NAPI structure from HIF
+ *
+ * Gets to the data structure common to all NAPI instances.
+ *
+ * Return:
+ *  NULL  : probably NAPI not initialized yet.
+ *  <addr>: the address of the whole NAPI structure
+ */
+struct qca_napi_data *hdd_napi_get_all(void)
+{
+	struct qca_napi_data *rp = NULL;
+	struct hif_opaque_softc *hif;
+
+	NAPI_DEBUG("-->");
+
+	hif = cds_get_context(QDF_MODULE_ID_HIF);
+	if (unlikely(NULL == hif))
+		QDF_ASSERT(NULL != hif); /* WARN */
+	else
+		rp = hif_napi_get_all(hif);
+
+	NAPI_DEBUG("<-- [addr=%pK]", rp);
+	return rp;
+}
+
+/**
+ * hdd_napi_get_map() - get a copy of napi pipe map
+ *
+ * Return:
+ *  uint32_t  : copy of pipe map
+ */
+static uint32_t hdd_napi_get_map(void)
+{
+	uint32_t map = 0;
+
+	NAPI_DEBUG("-->");
+	/* cache once, use forever */
+	if (hdd_napi_ctx == NULL)
+		hdd_napi_ctx = hdd_napi_get_all();
+	if (hdd_napi_ctx != NULL)
+		map = hdd_napi_ctx->ce_map;
+
+	NAPI_DEBUG("<-- [map=0x%08x]", map);
+	return map;
+}
+
+/**
+ * hdd_napi_create() - creates the NAPI structures for a given netdev
+ *
+ * Creates NAPI instances. This function is called
+ * unconditionally during initialization. It creates
+ * napi structures through the proper HTC/HIF calls.
+ * The structures are disabled on creation.
+ *
+ * Return:
+ *   single-queue: <0: err, >0=id, 0 (should not happen)
+ *   multi-queue: bitmap of created instances (0: none)
+ */
+int hdd_napi_create(void)
+{
+	struct  hif_opaque_softc *hif_ctx;
+	int     rc = 0;
+	struct hdd_context *hdd_ctx;
+	uint8_t feature_flags = 0;
+	struct qca_napi_data *napid = hdd_napi_get_all();
+
+	NAPI_DEBUG("-->");
+
+	if (NULL == napid) {
+		hdd_err("unable to retrieve napi structure");
+		rc = -EFAULT;
+		goto exit;
+	}
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (unlikely(NULL == hif_ctx)) {
+		QDF_ASSERT(NULL != hif_ctx);
+		rc = -EFAULT;
+		goto exit;
+	}
+
+	feature_flags = QCA_NAPI_FEATURE_CPU_CORRECTION |
+		QCA_NAPI_FEATURE_IRQ_BLACKLISTING |
+		QCA_NAPI_FEATURE_CORE_CTL_BOOST;
+
+	rc = hif_napi_create(hif_ctx, hdd_napi_poll,
+			     QCA_NAPI_BUDGET,
+			     QCA_NAPI_DEF_SCALE,
+			     feature_flags);
+	if (rc < 0) {
+		hdd_err("ERR(%d) creating NAPI instances",
+			rc);
+		goto exit;
+	}
+
+	hdd_debug("napi instances were created. Map=0x%x", rc);
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (unlikely(NULL == hdd_ctx)) {
+		QDF_ASSERT(0);
+		rc = -EFAULT;
+		goto exit;
+	}
+
+	rc = hdd_napi_event(NAPI_EVT_INI_FILE,
+			    (void *)hdd_ctx->napi_enable);
+	napid->user_cpu_affin_mask =
+		hdd_ctx->config->napi_cpu_affinity_mask;
+
+ exit:
+	NAPI_DEBUG("<-- [rc=%d]", rc);
+	return rc;
+}
+
+/**
+ * hdd_napi_destroy() - destroys the NAPI structures for a given netdev
+ * @force: if set, will force-disable the instance before _del'ing
+ *
+ * Destroy NAPI instances. This function is called
+ * unconditionally during module removal. It destroy
+ * napi structures through the proper HTC/HIF calls.
+ *
+ * Return:
+ *    number of NAPI instances destroyed
+ */
+int hdd_napi_destroy(int force)
+{
+	int rc = 0;
+	int i;
+	uint32_t hdd_napi_map = hdd_napi_get_map();
+
+	NAPI_DEBUG("--> (force=%d)", force);
+	if (hdd_napi_map) {
+		struct hif_opaque_softc *hif_ctx;
+
+		hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+		if (unlikely(NULL == hif_ctx))
+			QDF_ASSERT(NULL != hif_ctx);
+		else
+			for (i = 0; i < CE_COUNT_MAX; i++)
+				if (hdd_napi_map & (0x01 << i)) {
+					if (0 <= hif_napi_destroy(
+						    hif_ctx,
+						    NAPI_PIPE2ID(i), force)) {
+						rc++;
+						hdd_napi_map &= ~(0x01 << i);
+					} else
+						hdd_err("cannot destroy napi %d: (pipe:%d), f=%d\n",
+							i,
+							NAPI_PIPE2ID(i), force);
+				}
+	} else {
+		struct hif_opaque_softc *hif_ctx;
+
+		hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+
+		if (unlikely(NULL == hif_ctx))
+			QDF_ASSERT(NULL != hif_ctx);
+		else
+			rc = hif_napi_cpu_deinit(hif_ctx);
+	}
+
+	/* if all instances are removed, it is likely that hif_context has been
+	 * removed as well, so the cached value of the napi context also needs
+	 * to be removed
+	 */
+	if (force)
+		QDF_ASSERT(hdd_napi_map == 0);
+	if (0 == hdd_napi_map)
+		hdd_napi_ctx = NULL;
+
+	NAPI_DEBUG("<-- [rc=%d]", rc);
+	return rc;
+}
+
+/**
+ * hdd_napi_enabled() - checks if NAPI is enabled (for a given id)
+ * @id: the id of the NAPI to check (any= -1)
+ *
+ * Return:
+ *   int: 0  = false (NOT enabled)
+ *        !0 = true  (enabbled)
+ */
+int hdd_napi_enabled(int id)
+{
+	struct hif_opaque_softc *hif;
+	int rc = 0; /* NOT enabled */
+
+	hif = cds_get_context(QDF_MODULE_ID_HIF);
+	if (unlikely(NULL == hif))
+		QDF_ASSERT(hif != NULL); /* WARN_ON; rc = 0 */
+	else if (-1 == id)
+		rc = hif_napi_enabled(hif, id);
+	else
+		rc = hif_napi_enabled(hif, NAPI_ID2PIPE(id));
+	return rc;
+}
+
+/**
+ * hdd_napi_event() - relay the event detected by HDD to HIF NAPI event handler
+ * @event: event code
+ * @data : event-specific auxiliary data
+ *
+ * See function documentation in hif_napi.c::hif_napi_event for list of events
+ * and how each of them is handled.
+ *
+ * Return:
+ *  < 0: error code
+ *  = 0: event handled successfully
+ */
+int hdd_napi_event(enum qca_napi_event event, void *data)
+{
+	int rc = -EFAULT;  /* assume err */
+	struct hif_opaque_softc *hif;
+
+	NAPI_DEBUG("-->(event=%d, aux=%pK)", event, data);
+
+	hif = cds_get_context(QDF_MODULE_ID_HIF);
+	if (unlikely(NULL == hif))
+		QDF_ASSERT(hif != NULL);
+	else
+		rc = hif_napi_event(hif, event, data);
+
+	NAPI_DEBUG("<--[rc=%d]", rc);
+	return rc;
+}
+
+#if defined HELIUMPLUS && defined MSM_PLATFORM
+/**
+ * hdd_napi_perfd_cpufreq() - set/reset min CPU freq for cores
+ * @req_state:  high/low
+ *
+ * Send a message to cnss-daemon through netlink. cnss-daemon,
+ * in turn, sends a message to perf-daemon.
+ * If freq > 0, this is a set request. It sets the min frequency of the
+ * cores of the specified cluster to provided freq value (in KHz).
+ * If freq == 0, then the freq lock is removed (and frequency returns to
+ * system default).
+ *
+ * Semantical Alert:
+ * There can be at most one lock active at a time. Each "set" request must
+ * be followed by a "reset" request. Perfd behaviour is undefined otherwise.
+ *
+ * Return: == 0: netlink message sent to cnss-daemon
+ *         <  0: failure to send the message
+ */
+static int hdd_napi_perfd_cpufreq(enum qca_napi_tput_state req_state)
+{
+	int rc = 0;
+	struct wlan_core_minfreq req;
+	struct hdd_context *hdd_ctx;
+
+	NAPI_DEBUG("-> (%d)", req_state);
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (unlikely(hdd_ctx == NULL)) {
+		hdd_err("cannot get hdd_context");
+		rc = -EFAULT;
+		goto hnpc_ret;
+	}
+
+	switch (req_state) {
+	case QCA_NAPI_TPUT_LO:
+		req.magic    = WLAN_CORE_MINFREQ_MAGIC;
+		req.reserved = 0; /* unused */
+		req.coremask = 0; /* not valid */
+		req.freq     = 0; /* reset */
+		break;
+	case QCA_NAPI_TPUT_HI:
+		req.magic    = WLAN_CORE_MINFREQ_MAGIC;
+		req.reserved = 0; /* unused */
+		req.coremask = 0x0f0; /* perf cluster */
+		req.freq     = 700;   /* KHz */
+		break;
+	default:
+		hdd_err("invalid req_state (%d)", req_state);
+		rc = -EINVAL;
+		goto hnpc_ret;
+	} /* switch */
+
+	NAPI_DEBUG("CPU min freq to %d",
+		   (req.freq == 0)?"Resetting":"Setting", req.freq);
+	/* the following service function returns void */
+	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+				WLAN_SVC_CORE_MINFREQ,
+				&req, sizeof(struct wlan_core_minfreq));
+hnpc_ret:
+	NAPI_DEBUG("<--[rc=%d]", rc);
+	return rc;
+}
+
+/**
+ * hdd_napi_apply_throughput_policy() - implement the throughput action policy
+ * @hddctx:     HDD context
+ * @tx_packets: number of tx packets in the last interval
+ * @rx_packets: number of rx packets in the last interval
+ *
+ * Called by hdd_bus_bw_compute_cb, checks the number of packets in the last
+ * interval, and determines the desired napi throughput state (HI/LO). If
+ * the desired state is different from the current, then it invokes the
+ * event handler to switch to the desired state.
+ *
+ * The policy implementation is limited to this function and
+ * The current policy is: determine the NAPI mode based on the condition:
+ *      (total number of packets > medium threshold)
+ * - tx packets are included because:
+ *   a- tx-completions arrive at one of the rx CEs
+ *   b- in TCP, a lof of TX implies ~(tx/2) rx (ACKs)
+ *   c- so that we can use the same normalized criteria in ini file
+ * - medium-threshold (default: 500 packets / 10 ms), because
+ *   we would like to be more reactive.
+ *
+ * Return: 0 : no action taken, or action return code
+ *         !0: error, or action error code
+ */
+static int napi_tput_policy_delay;
+int hdd_napi_apply_throughput_policy(struct hdd_context *hddctx,
+				     uint64_t tx_packets,
+				     uint64_t rx_packets)
+{
+	int rc = 0;
+	uint64_t packets = tx_packets + rx_packets;
+	enum qca_napi_tput_state req_state;
+	struct qca_napi_data *napid = hdd_napi_get_all();
+	int enabled;
+
+	NAPI_DEBUG("-->%s(tx=%lld, rx=%lld)", __func__, tx_packets, rx_packets);
+
+	if (unlikely(napi_tput_policy_delay < 0))
+		napi_tput_policy_delay = 0;
+	if (napi_tput_policy_delay > 0) {
+		NAPI_DEBUG("%s: delaying policy; delay-count=%d",
+			  __func__, napi_tput_policy_delay);
+		napi_tput_policy_delay--;
+
+		/* make sure the next timer call calls us */
+		hddctx->cur_vote_level = -1;
+
+		return rc;
+	}
+
+	if (!napid) {
+		hdd_err("ERR: napid NULL");
+		return rc;
+	}
+
+	enabled = hdd_napi_enabled(HDD_NAPI_ANY);
+	if (!enabled) {
+		hdd_err("ERR: napi not enabled");
+		return rc;
+	}
+
+	if (packets > hddctx->config->bus_bw_high_threshold)
+		req_state = QCA_NAPI_TPUT_HI;
+	else
+		req_state = QCA_NAPI_TPUT_LO;
+
+	if (req_state != napid->napi_mode) {
+		/* [re]set the floor frequency of high cluster */
+		rc = hdd_napi_perfd_cpufreq(req_state);
+		/* blacklist/boost_mode on/off */
+		rc = hdd_napi_event(NAPI_EVT_TPUT_STATE, (void *)req_state);
+	}
+	return rc;
+}
+
+/**
+ * hdd_napi_serialize() - serialize all NAPI activities
+ * @is_on: 1="serialize" or 0="de-serialize"
+ *
+ * Start/stop "serial-NAPI-mode".
+ * NAPI serial mode describes a state where all NAPI operations are forced to be
+ * run serially. This is achieved by ensuring all NAPI instances are run on the
+ * same CPU, so forced to be serial.
+ * NAPI life-cycle:
+ * - Interrupt is received for a given CE.
+ * - In the ISR, the interrupt is masked and corresponding NAPI instance
+ *   is scheduled, to be run as a bottom-half.
+ * - Bottom-half starts with a poll call (by the net_rx softirq). There may be
+ *   one of more subsequent calls until the work is complete.
+ * - Once the work is complete, the poll handler enables the interrupt and
+ *   the cycle re-starts.
+ *
+ * Return: <0: error-code (operation failed)
+ *         =0: success
+ *         >0: status (not used)
+ */
+int hdd_napi_serialize(int is_on)
+{
+	int rc;
+	struct hdd_context *hdd_ctx;
+#define POLICY_DELAY_FACTOR (1)
+	rc = hif_napi_serialize(cds_get_context(QDF_MODULE_ID_HIF), is_on);
+	if ((rc == 0) && (is_on == 0)) {
+		/* apply throughput policy after one timeout */
+		napi_tput_policy_delay = POLICY_DELAY_FACTOR;
+
+		/* make sure that bus_bandwidth trigger is executed */
+		hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+		if (hdd_ctx != NULL)
+			hdd_ctx->cur_vote_level = -1;
+
+	}
+	return rc;
+}
+#endif /* HELIUMPLUS && MSM_PLATFORM */
+
+/**
+ * hdd_napi_poll() - NAPI poll function
+ * @napi  : pointer to NAPI struct
+ * @budget: the pre-declared budget
+ *
+ * Implementation of poll function. This function is called
+ * by kernel during softirq processing.
+ *
+ * NOTE FOR THE MAINTAINER:
+ *   Make sure this is very close to the ce_tasklet code.
+ *
+ * Return:
+ *   int: the amount of work done ( <= budget )
+ */
+int hdd_napi_poll(struct napi_struct *napi, int budget)
+{
+	return hif_napi_poll(cds_get_context(QDF_MODULE_ID_HIF), napi, budget);
+}
+
+/**
+ * hdd_display_napi_stats() - print NAPI stats
+ *
+ * Return: == 0: success; !=0: failure
+ */
+int hdd_display_napi_stats(void)
+{
+	int i, j, k, n; /* NAPI, CPU, bucket indices, bucket buf write index*/
+	int max;
+	struct qca_napi_data *napid;
+	struct qca_napi_info *napii;
+	struct qca_napi_stat *napis;
+	/*
+	 * Expecting each NAPI bucket item to need at max 5 numerals + space for
+	 * formatting. For example "10000 " Thus the array needs to have
+	 * (5 + 1) * QCA_NAPI_NUM_BUCKETS bytes of space. Leaving one space at
+	 * the end of the "buf" arrary for end of string char.
+	 */
+	char buf[6 * QCA_NAPI_NUM_BUCKETS + 1] = {'\0'};
+
+	napid = hdd_napi_get_all();
+	if (NULL == napid) {
+		hdd_err("%s unable to retrieve napi structure", __func__);
+		return -EFAULT;
+	}
+	hdd_nofl_info("[NAPI %u][BL %d]:  scheds   polls   comps    done t-lim p-lim  corr  max_time napi-buckets(%d)",
+		      napid->napi_mode,
+		      hif_napi_cpu_blacklist(napid, BLACKLIST_QUERY),
+		      QCA_NAPI_NUM_BUCKETS);
+
+	for (i = 0; i < CE_COUNT_MAX; i++)
+		if (napid->ce_map & (0x01 << i)) {
+			napii = napid->napis[i];
+			if (!napii)
+				continue;
+
+			for (j = 0; j < num_possible_cpus(); j++) {
+				napis = &(napii->stats[j]);
+				n = 0;
+				max = sizeof(buf);
+				for (k = 0; k < QCA_NAPI_NUM_BUCKETS; k++) {
+					n += scnprintf(
+						buf + n, max - n,
+						" %d",
+						napis->napi_budget_uses[k]);
+				}
+
+				if (napis->napi_schedules != 0)
+					hdd_nofl_info("NAPI[%2d]CPU[%d]: %7d %7d %7d %7d %5d %5d %5d %9llu %s",
+						      i, j,
+						      napis->napi_schedules,
+						      napis->napi_polls,
+						      napis->napi_completes,
+						      napis->napi_workdone,
+						      napis->time_limit_reached,
+						      napis->
+							rxpkt_thresh_reached,
+						      napis->cpu_corrected,
+						      napis->napi_max_poll_time,
+						      buf);
+			}
+		}
+
+	hif_napi_stats(napid);
+	return 0;
+}
+
+/**
+ * hdd_clear_napi_stats() - clear NAPI stats
+ *
+ * Return: == 0: success; !=0: failure
+ */
+int hdd_clear_napi_stats(void)
+{
+	int i, j;
+	struct qca_napi_data *napid;
+	struct qca_napi_info *napii;
+	struct qca_napi_stat *napis;
+
+	napid = hdd_napi_get_all();
+	if (NULL == napid) {
+		hdd_err("%s unable to retrieve napi structure", __func__);
+		return -EFAULT;
+	}
+
+	for (i = 0; i < CE_COUNT_MAX; i++)
+		if (napid->ce_map & (0x01 << i)) {
+			napii = napid->napis[i];
+			for (j = 0; j < NR_CPUS; j++) {
+				napis = &(napii->stats[j]);
+				qdf_mem_zero(napis,
+					     sizeof(struct qca_napi_stat));
+			}
+		}
+
+	return 0;
+}
diff --git a/core/hdd/src/wlan_hdd_nud_tracking.c b/core/hdd/src/wlan_hdd_nud_tracking.c
new file mode 100644
index 0000000..97d2db3
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_nud_tracking.c
@@ -0,0 +1,472 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: contains nud event tracking main function definitions
+ */
+
+#include "wlan_hdd_main.h"
+
+void hdd_nud_set_gateway_addr(struct hdd_adapter *adapter,
+			      struct qdf_mac_addr gw_mac_addr)
+{
+	qdf_mem_copy(adapter->nud_tracking.gw_mac_addr.bytes,
+		     gw_mac_addr.bytes,
+		     sizeof(struct qdf_mac_addr));
+}
+
+void hdd_nud_incr_gw_rx_pkt_cnt(struct hdd_adapter *adapter,
+				struct qdf_mac_addr *mac_addr)
+{
+	if (!adapter->nud_tracking.is_gw_rx_pkt_track_enabled)
+		return;
+
+	if (qdf_is_macaddr_equal(&adapter->nud_tracking.gw_mac_addr,
+				 mac_addr))
+		qdf_atomic_inc(&adapter
+			       ->nud_tracking.tx_rx_stats.gw_rx_packets);
+}
+
+void hdd_nud_flush_work(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	if (adapter->device_mode == QDF_STA_MODE &&
+	    hdd_ctx->config->enable_nud_tracking) {
+		hdd_debug("Flush the NUD work");
+		qdf_disable_work(&adapter->nud_tracking.nud_event_work);
+	}
+}
+
+void hdd_nud_deinit_tracking(struct hdd_adapter *adapter)
+{
+	hdd_debug("DeInitialize the NUD tracking");
+	qdf_destroy_work(NULL, &adapter->nud_tracking.nud_event_work);
+}
+
+void hdd_nud_ignore_tracking(struct hdd_adapter *adapter, bool ignoring)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	if (adapter->device_mode == QDF_STA_MODE &&
+	    hdd_ctx->config->enable_nud_tracking)
+		adapter->nud_tracking.ignore_nud_tracking = ignoring;
+}
+
+void hdd_nud_reset_tracking(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	if (adapter->device_mode == QDF_STA_MODE &&
+	    hdd_ctx->config->enable_nud_tracking) {
+		hdd_debug("Reset the NUD tracking");
+
+		qdf_zero_macaddr(&adapter->nud_tracking.gw_mac_addr);
+		qdf_mem_zero(&adapter->nud_tracking.tx_rx_stats,
+			     sizeof(struct hdd_nud_tx_rx_stats));
+
+		adapter->nud_tracking.curr_state = NUD_NONE;
+		qdf_atomic_set(&adapter
+			       ->nud_tracking.tx_rx_stats.gw_rx_packets, 0);
+	}
+}
+
+/**
+ * hdd_nud_stats_info() - display wlan NUD stats info
+ * @hdd_adapter: Pointer to hdd adapter
+ *
+ * Return: None
+ */
+static void hdd_nud_stats_info(struct hdd_adapter *adapter)
+{
+	hdd_debug("**** NUD STATS: ****");
+	hdd_debug("NUD Probe Tx  : %d",
+		  adapter->nud_tracking.tx_rx_stats.pre_tx_packets);
+	hdd_debug("NUD Probe Ack : %d",
+		  adapter->nud_tracking.tx_rx_stats.pre_tx_acked);
+	hdd_debug("NUD Probe Rx  : %d",
+		  adapter->nud_tracking.tx_rx_stats.pre_rx_packets);
+	hdd_debug("NUD Failure Tx  : %d",
+		  adapter->nud_tracking.tx_rx_stats.post_tx_packets);
+	hdd_debug("NUD Failure Ack : %d",
+		  adapter->nud_tracking.tx_rx_stats.post_tx_acked);
+	hdd_debug("NUD Failure Rx  : %d",
+		  adapter->nud_tracking.tx_rx_stats.post_rx_packets);
+	hdd_debug("NUD Gateway Rx  : %d",
+		  qdf_atomic_read(&adapter
+				  ->nud_tracking.tx_rx_stats.gw_rx_packets));
+}
+
+/**
+ * hdd_nud_capture_stats() - capture wlan NUD stats
+ * @hdd_adapter: Pointer to hdd adapter
+ * @nud_state: NUD state for which stats to capture
+ *
+ * Return: None
+ */
+static void hdd_nud_capture_stats(struct hdd_adapter *adapter,
+				  uint8_t nud_state)
+{
+	switch (nud_state) {
+	case NUD_INCOMPLETE:
+	case NUD_PROBE:
+		adapter->nud_tracking.tx_rx_stats.pre_tx_packets =
+				adapter->stats.tx_packets;
+		adapter->nud_tracking.tx_rx_stats.pre_rx_packets =
+				adapter->stats.rx_packets;
+		adapter->nud_tracking.tx_rx_stats.pre_tx_acked =
+				hdd_txrx_get_tx_ack_count(adapter);
+		break;
+	case NUD_FAILED:
+		adapter->nud_tracking.tx_rx_stats.post_tx_packets =
+				adapter->stats.tx_packets;
+		adapter->nud_tracking.tx_rx_stats.post_rx_packets =
+				adapter->stats.rx_packets;
+		adapter->nud_tracking.tx_rx_stats.post_tx_acked =
+				hdd_txrx_get_tx_ack_count(adapter);
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ * hdd_nud_honour_failure() - check if nud failure to be honored
+ * @hdd_adapter: Pointer to hdd_adapter
+ *
+ * Return: true if nud failure to be honored, else false.
+ */
+static bool hdd_nud_honour_failure(struct hdd_adapter *adapter)
+{
+	uint32_t tx_transmitted;
+	uint32_t tx_acked;
+	uint32_t gw_rx_pkt;
+
+	tx_transmitted = adapter->nud_tracking.tx_rx_stats.post_tx_packets -
+		adapter->nud_tracking.tx_rx_stats.pre_tx_packets;
+	tx_acked = adapter->nud_tracking.tx_rx_stats.post_tx_acked -
+		adapter->nud_tracking.tx_rx_stats.pre_tx_acked;
+	gw_rx_pkt = qdf_atomic_read(&adapter
+			->nud_tracking.tx_rx_stats.gw_rx_packets);
+
+	if (!tx_transmitted || !tx_acked || !gw_rx_pkt) {
+		hdd_debug("NUD_FAILURE_HONORED");
+		hdd_nud_stats_info(adapter);
+		return true;
+	}
+	hdd_debug("NUD_FAILURE_NOT_HONORED");
+	hdd_nud_stats_info(adapter);
+	return false;
+}
+
+/**
+ * hdd_nud_set_tracking() - set the NUD tracking info
+ * @hdd_adapter: Pointer to hdd_adapter
+ * @nud_state: Current NUD state to set
+ * @capture_enabled: GW Rx packet to be capture or not
+ *
+ * Return: None
+ */
+static void hdd_nud_set_tracking(struct hdd_adapter *adapter,
+				 uint8_t nud_state,
+				 bool capture_enabled)
+{
+	adapter->nud_tracking.curr_state = nud_state;
+	qdf_atomic_set(&adapter->nud_tracking.tx_rx_stats.gw_rx_packets, 0);
+	adapter->nud_tracking.is_gw_rx_pkt_track_enabled = capture_enabled;
+}
+
+/**
+ * __hdd_nud_failure_work() - work for nud event
+ * @data: Pointer to hdd_adapter
+ *
+ * Return: None
+ */
+static void __hdd_nud_failure_work(void *data)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	eConnectionState conn_state;
+	int status;
+
+	hdd_enter();
+
+	if (!data)
+		return;
+
+	adapter = (struct hdd_adapter *)data;
+
+	status = hdd_validate_adapter(adapter);
+	if (status)
+		return;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return;
+
+	conn_state = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
+		      ->conn_info.connState;
+
+	if (eConnectionState_Associated != conn_state) {
+		hdd_debug("Not in Connected State");
+		return;
+	}
+	if (adapter->nud_tracking.curr_state != NUD_FAILED) {
+		hdd_debug("Not in NUD_FAILED state");
+		return;
+	}
+
+	qdf_mutex_acquire(&adapter->disconnection_status_lock);
+	if (adapter->disconnection_in_progress) {
+		qdf_mutex_release(&adapter->disconnection_status_lock);
+		hdd_debug("Disconnect is already in progress");
+		return;
+	}
+	adapter->disconnection_in_progress = true;
+	qdf_mutex_release(&adapter->disconnection_status_lock);
+
+	hdd_debug("Disconnecting STA with session id: %d",
+		  adapter->session_id);
+	/* Issue Disconnect */
+	status = wlan_hdd_disconnect(adapter, eCSR_DISCONNECT_REASON_DEAUTH);
+	if (0 != status) {
+		hdd_err("wlan_hdd_disconnect failed, status: %d", status);
+		hdd_set_disconnect_status(adapter, false);
+	}
+
+	hdd_exit();
+}
+
+/**
+ * hdd_nud_failure_work() - work for nud event
+ * @data: Pointer to hdd_adapter
+ *
+ * Return: None
+ */
+static void hdd_nud_failure_work(void *data)
+{
+	cds_ssr_protect(__func__);
+	__hdd_nud_failure_work(data);
+	cds_ssr_unprotect(__func__);
+}
+
+void hdd_nud_init_tracking(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	if (adapter->device_mode == QDF_STA_MODE &&
+	    hdd_ctx->config->enable_nud_tracking) {
+		hdd_debug("Initialize the NUD tracking");
+
+		qdf_zero_macaddr(&adapter->nud_tracking.gw_mac_addr);
+		qdf_mem_zero(&adapter->nud_tracking.tx_rx_stats,
+			     sizeof(struct hdd_nud_tx_rx_stats));
+
+		adapter->nud_tracking.curr_state = NUD_NONE;
+		adapter->nud_tracking.ignore_nud_tracking = false;
+
+		qdf_atomic_init(&adapter
+				->nud_tracking.tx_rx_stats.gw_rx_packets);
+		qdf_create_work(0, &adapter->nud_tracking.nud_event_work,
+				hdd_nud_failure_work,
+				(void *)adapter);
+	}
+}
+
+/**
+ * hdd_nud_process_failure_event() - processing NUD_FAILED event
+ * @hdd_adapter: Pointer to hdd_adapter
+ *
+ * Return: None
+ */
+static void hdd_nud_process_failure_event(struct hdd_adapter *adapter)
+{
+	uint8_t curr_state;
+
+	curr_state = adapter->nud_tracking.curr_state;
+	if (curr_state == NUD_PROBE || curr_state == NUD_INCOMPLETE) {
+		hdd_nud_capture_stats(adapter, NUD_FAILED);
+		if (hdd_nud_honour_failure(adapter)) {
+			adapter->nud_tracking.curr_state = NUD_FAILED;
+			qdf_sched_work(0, &adapter
+					->nud_tracking.nud_event_work);
+		} else {
+			hdd_nud_set_tracking(adapter, NUD_NONE, false);
+		}
+	} else {
+		hdd_debug("NUD FAILED -> Current State [0x%x]", curr_state);
+	}
+}
+
+/**
+ * hdd_nud_filter_netevent() - filter netevents for STA interface
+ * @neighbour: Pointer to neighbour
+ *
+ * Return: None
+ */
+static void hdd_nud_filter_netevent(struct neighbour *neigh)
+{
+	int status;
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	eConnectionState conn_state;
+	const struct net_device *netdev = neigh->dev;
+
+	hdd_enter();
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return;
+
+	adapter = hdd_get_adapter_by_macaddr(hdd_ctx, netdev->dev_addr);
+
+	if (!adapter)
+		return;
+
+	status = hdd_validate_adapter(adapter);
+	if (status)
+		return;
+
+	if (adapter->device_mode != QDF_STA_MODE)
+		return;
+
+	conn_state = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
+		->conn_info.connState;
+
+	if (eConnectionState_Associated != conn_state) {
+		hdd_debug("Not in Connected State");
+		return;
+	}
+
+	if (adapter->nud_tracking.ignore_nud_tracking) {
+		hdd_debug("NUD Tracking is Disabled");
+		return;
+	}
+
+	if (!qdf_is_macaddr_equal(&adapter->nud_tracking.gw_mac_addr,
+				  (struct qdf_mac_addr *)&neigh->ha[0]))
+		return;
+
+	switch (neigh->nud_state) {
+	case NUD_PROBE:
+	case NUD_INCOMPLETE:
+		hdd_debug("NUD_START [0x%x]", neigh->nud_state);
+		hdd_nud_capture_stats(adapter, neigh->nud_state);
+		hdd_nud_set_tracking(adapter,
+				     neigh->nud_state,
+				     true);
+		break;
+
+	case NUD_REACHABLE:
+		hdd_debug("NUD_REACHABLE [0x%x]", neigh->nud_state);
+		hdd_nud_set_tracking(adapter, NUD_NONE, false);
+		break;
+
+	case NUD_FAILED:
+		hdd_debug("NUD_FAILED [0x%x]", neigh->nud_state);
+		hdd_nud_process_failure_event(adapter);
+		break;
+	default:
+		hdd_debug("NUD Event For Other State [0x%x]",
+			  neigh->nud_state);
+		break;
+	}
+	hdd_exit();
+}
+
+/**
+ * __hdd_nud_netevent_cb() - netevent callback
+ * @nb: Pointer to notifier block
+ * @event: Net Event triggered
+ * @data: Pointer to neighbour struct
+ *
+ * Callback for netevent
+ *
+ * Return: None
+ */
+static void __hdd_nud_netevent_cb(struct notifier_block *nb,
+				  unsigned long event,
+				  void *data)
+{
+	hdd_enter();
+	hdd_nud_filter_netevent(data);
+	hdd_exit();
+}
+
+/**
+ * hdd_nud_netevent_cb() - netevent callback
+ * @nb: Pointer to notifier block
+ * @event: Net Event triggered
+ * @data: Pointer to neighbour struct
+ *
+ * Callback for netevent
+ *
+ * Return: 0 on success
+ */
+static int hdd_nud_netevent_cb(struct notifier_block *nb, unsigned long event,
+			       void *data)
+{
+	switch (event) {
+	case NETEVENT_NEIGH_UPDATE:
+		cds_ssr_protect(__func__);
+		__hdd_nud_netevent_cb(nb, event, data);
+		cds_ssr_unprotect(__func__);
+		break;
+	case NETEVENT_REDIRECT:
+	default:
+		break;
+	}
+	return 0;
+}
+
+static struct notifier_block wlan_netevent_nb = {
+	.notifier_call = hdd_nud_netevent_cb
+};
+
+int hdd_nud_register_netevent_notifier(struct hdd_context *hdd_ctx)
+{
+	int ret = 0;
+
+	if (hdd_ctx->config->enable_nud_tracking) {
+		ret = register_netevent_notifier(&wlan_netevent_nb);
+		if (!ret)
+			hdd_debug("Registered netevent notifier");
+	}
+	return ret;
+}
+
+void hdd_nud_unregister_netevent_notifier(struct hdd_context *hdd_ctx)
+{
+	int ret;
+
+	if (hdd_ctx->config->enable_nud_tracking) {
+		ret = unregister_netevent_notifier(&wlan_netevent_nb);
+		if (!ret)
+			hdd_debug("Unregistered netevent notifier");
+	}
+}
diff --git a/core/hdd/src/wlan_hdd_nud_tracking.h b/core/hdd/src/wlan_hdd_nud_tracking.h
new file mode 100644
index 0000000..584cf9b
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_nud_tracking.h
@@ -0,0 +1,194 @@
+ /*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: contains nud event tracking function declarations
+ */
+
+#ifndef _WLAN_NUD_TRACKING_H_
+#define _WLAN_NUD_TRACKING_H_
+
+#ifdef WLAN_NUD_TRACKING
+
+/**
+ * struct hdd_nud_tx_rx_stats - Capture tx and rx count during NUD tracking
+ * @pre_tx_packets: Number of tx packets at NUD_PROBE event
+ * @pre_tx_acked: Number of tx acked at NUD_PROBE event
+ * @pre_rx_packets: Number of rx packets at NUD_PROBE event
+ * @post_tx_packets: Number of tx packets at NUD_FAILED event
+ * @post_tx_acked: Number of tx acked at NUD_FAILED event
+ * @post_rx_packets: Number of rx packets at NUD_FAILED event
+ * @gw_rx_packets: Number of rx packets from the registered gateway
+ *                 during the period from NUD_PROBE to NUD_FAILED
+ */
+struct hdd_nud_tx_rx_stats {
+	uint32_t pre_tx_packets;
+	uint32_t pre_tx_acked;
+	uint32_t pre_rx_packets;
+	uint32_t post_tx_packets;
+	uint32_t post_tx_acked;
+	uint32_t post_rx_packets;
+	qdf_atomic_t gw_rx_packets;
+};
+
+ /**
+  * struct hdd_nud_tracking_info - structure to keep track for NUD information
+  * @curr_state: current state of NUD machine
+  * @ignore_nud_tracking: true if nud tracking is not required else false
+  * @tx_rx_stats: Number of packets during NUD tracking
+  * @gw_mac_addr: gateway mac address for which NUD events are tracked
+  * @nud_event_work: work to be scheduled during NUD_FAILED
+  * @is_gw_rx_pkt_track_enabled: true if rx pkt capturing is enabled for GW,
+  *                              else false
+  */
+struct hdd_nud_tracking_info {
+	uint8_t curr_state;
+	bool ignore_nud_tracking;
+	struct hdd_nud_tx_rx_stats tx_rx_stats;
+	struct qdf_mac_addr gw_mac_addr;
+	qdf_work_t nud_event_work;
+	bool is_gw_rx_pkt_track_enabled;
+};
+
+/**
+ * hdd_nud_set_gateway_addr() - set gateway mac address
+ * @adapter: Pointer to adapter
+ * @gw_mac_addr: mac address to be set
+ *
+ * Return: none
+ */
+void hdd_nud_set_gateway_addr(struct hdd_adapter *adapter,
+			      struct qdf_mac_addr gw_mac_addr);
+
+/**
+ * hdd_nud_incr_gw_rx_pkt_cnt() - Increment rx count for gateway
+ * @adapter: Pointer to adapter
+ * @mac_addr: Gateway mac address
+ *
+ * Return: None
+ */
+void hdd_nud_incr_gw_rx_pkt_cnt(struct hdd_adapter *adapter,
+				struct qdf_mac_addr *mac_addr);
+
+/**
+ * hdd_nud_init_tracking() - initialize NUD tracking
+ * @hdd_adapter: Pointer to hdd adapter
+ *
+ * Return: None
+ */
+void hdd_nud_init_tracking(struct hdd_adapter *adapter);
+
+/**
+ * hdd_nud_reset_tracking() - reset NUD tracking
+ * @hdd_adapter: Pointer to hdd adapter
+ *
+ * Return: None
+ */
+void hdd_nud_reset_tracking(struct hdd_adapter *adapter);
+
+/**
+ * hdd_nud_deinit_tracking() - deinitialize NUD tracking
+ * @hdd_adapter: Pointer to hdd adapter
+ *
+ * Return: None
+ */
+void hdd_nud_deinit_tracking(struct hdd_adapter *adapter);
+
+/**
+ * hdd_nud_ignore_tracking() - set/reset nud trackig status
+ * @data: Pointer to hdd_adapter
+ * @ignoring: Ignore status to set
+ *
+ * Return: None
+ */
+void hdd_nud_ignore_tracking(struct hdd_adapter *adapter,
+			     bool ignoring);
+
+/**
+ * hdd_nud_register_netevent_notifier - Register netevent notifiers.
+ * @hdd_ctx: HDD context
+ *
+ * Register netevent notifiers.
+ *
+ * Return: 0 on success and errno on failure
+ */
+int hdd_nud_register_netevent_notifier(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_nud_unregister_netevent_notifier - Unregister netevent notifiers.
+ * @hdd_ctx: HDD context
+ *
+ * Unregister netevent notifiers.
+ *
+ * Return: None
+ */
+void hdd_nud_unregister_netevent_notifier(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_nud_flush_work() - flush pending nud work
+ * @adapter: Pointer to hdd adapter
+ *
+ * Return: None
+ */
+void hdd_nud_flush_work(struct hdd_adapter *adapter);
+
+#else
+static inline void hdd_nud_set_gateway_addr(struct hdd_adapter *adapter,
+					    struct qdf_mac_addr gw_mac_addr)
+{
+}
+
+static inline void hdd_nud_incr_gw_rx_pkt_cnt(struct hdd_adapter *adapter,
+					      struct qdf_mac_addr *mac_addr)
+{
+}
+
+static inline void hdd_nud_init_tracking(struct hdd_adapter *adapter)
+{
+}
+
+static inline void hdd_nud_reset_tracking(struct hdd_adapter *adapter)
+{
+}
+
+static inline void hdd_nud_deinit_tracking(struct hdd_adapter *adapter)
+{
+}
+
+static inline void hdd_nud_ignore_tracking(struct hdd_adapter *adapter,
+					   bool status)
+{
+}
+
+static inline int
+hdd_nud_register_netevent_notifier(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
+
+static inline void
+hdd_nud_unregister_netevent_notifier(struct hdd_context *hdd_ctx)
+{
+}
+
+static inline void
+hdd_nud_flush_work(struct hdd_adapter *adapter)
+{
+}
+#endif /* WLAN_NUD_TRACKING */
+#endif /* end  of _WLAN_NUD_TRACKING_H_ */
diff --git a/core/hdd/src/wlan_hdd_object_manager.c b/core/hdd/src/wlan_hdd_object_manager.c
new file mode 100644
index 0000000..6a698eb
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_object_manager.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2017-2018 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: HDD object manager API source file to create/destroy PSOC,
+ *  PDEV, VDEV and PEER objects.
+ */
+
+#include <wlan_hdd_object_manager.h>
+#include <wlan_osif_priv.h>
+#include <wlan_reg_ucfg_api.h>
+#include <target_if.h>
+#include <os_if_spectral_netlink.h>
+
+#define LOW_2GHZ_FREQ 2312
+#define HIGH_2GHZ_FREQ 2732
+#define LOW_5GHZ_FREQ  4912
+#define HIGH_5GHZ_FREQ 6100
+
+static void hdd_init_pdev_os_priv(struct hdd_context *hdd_ctx,
+	struct pdev_osif_priv *os_priv)
+{
+	/* Initialize the OS private structure*/
+	os_priv->wiphy = hdd_ctx->wiphy;
+	os_priv->legacy_osif_priv = hdd_ctx;
+	wlan_cfg80211_scan_priv_init(hdd_ctx->pdev);
+	os_if_spectral_netlink_init(hdd_ctx->pdev);
+}
+
+static void hdd_deinit_pdev_os_priv(struct wlan_objmgr_pdev *pdev)
+{
+	os_if_spectral_netlink_deinit(pdev);
+	wlan_cfg80211_scan_priv_deinit(pdev);
+}
+
+static struct vdev_osif_priv *
+hdd_init_vdev_os_priv(struct hdd_adapter *adapter)
+{
+	struct vdev_osif_priv *os_priv;
+
+	os_priv = qdf_mem_malloc(sizeof(*os_priv));
+	if (!os_priv)
+		return NULL;
+
+	/* Initialize the vdev OS private structure*/
+	os_priv->wdev = adapter->dev->ieee80211_ptr;
+	os_priv->legacy_osif_priv = adapter;
+	wlan_cfg80211_tdls_priv_init(os_priv);
+
+	return os_priv;
+}
+
+static void hdd_deinit_vdev_os_priv(struct vdev_osif_priv *os_priv)
+{
+	if (os_priv) {
+		wlan_cfg80211_tdls_priv_deinit(os_priv);
+		qdf_mem_free(os_priv);
+	}
+}
+
+static void hdd_init_psoc_qdf_ctx(struct wlan_objmgr_psoc *psoc)
+{
+	qdf_device_t qdf_ctx;
+
+	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	if (!qdf_ctx) {
+		hdd_err("qdf ctx is null, can't set to soc object");
+		return;
+	}
+
+	wlan_psoc_set_qdf_dev(psoc, qdf_ctx);
+}
+
+int hdd_objmgr_create_and_store_psoc(struct hdd_context *hdd_ctx,
+				     uint8_t psoc_id)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_objmgr_psoc_obj_create(psoc_id, WLAN_DEV_OL);
+	if (!psoc)
+		return -ENOMEM;
+
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_HDD_ID_OBJ_MGR);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to acquire psoc ref; status:%d", status);
+		QDF_BUG(false);
+		goto psoc_destroy;
+	}
+
+	hdd_init_psoc_qdf_ctx(psoc);
+	hdd_ctx->psoc = psoc;
+
+	return 0;
+
+psoc_destroy:
+	wlan_objmgr_psoc_obj_delete(psoc);
+
+	return qdf_status_to_os_return(status);
+}
+
+int hdd_objmgr_release_and_destroy_psoc(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+
+	hdd_ctx->psoc = NULL;
+
+	QDF_BUG(psoc);
+	if (!psoc)
+		return -EINVAL;
+
+	wlan_objmgr_print_ref_all_objects_per_psoc(psoc);
+
+	status = wlan_objmgr_psoc_obj_delete(psoc);
+	wlan_objmgr_psoc_release_ref(psoc, WLAN_HDD_ID_OBJ_MGR);
+
+	return qdf_status_to_os_return(status);
+}
+
+void hdd_objmgr_update_tgt_max_vdev_psoc(struct hdd_context *hdd_ctx,
+					 uint8_t max_vdev)
+{
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+
+	if (!psoc) {
+		hdd_err("Psoc NULL");
+		return;
+	}
+
+	wlan_psoc_set_max_vdev_count(psoc, max_vdev);
+}
+
+int hdd_objmgr_create_and_store_pdev(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	struct wlan_objmgr_pdev *pdev;
+	struct pdev_osif_priv *priv;
+	struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap_ptr;
+
+	if (!psoc) {
+		hdd_err("Psoc NULL");
+		return -EINVAL;
+	}
+
+	priv = qdf_mem_malloc(sizeof(*priv));
+	if (priv == NULL) {
+		hdd_err("pdev os obj create failed");
+		return -ENOMEM;
+	}
+
+	reg_cap_ptr = ucfg_reg_get_hal_reg_cap(psoc);
+	if (!reg_cap_ptr) {
+		hdd_err("Failed to get reg capability");
+		status = QDF_STATUS_E_INVAL;
+		goto free_priv;
+	}
+	reg_cap_ptr->phy_id = 0;
+	reg_cap_ptr->low_2ghz_chan = LOW_2GHZ_FREQ;
+	reg_cap_ptr->high_2ghz_chan = HIGH_2GHZ_FREQ;
+	reg_cap_ptr->low_5ghz_chan = LOW_5GHZ_FREQ;
+	reg_cap_ptr->high_5ghz_chan = HIGH_5GHZ_FREQ;
+
+	pdev = wlan_objmgr_pdev_obj_create(psoc, priv);
+	if (!pdev) {
+		hdd_err("pdev obj create failed");
+		status = QDF_STATUS_E_NOMEM;
+		goto free_priv;
+	}
+
+	status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_HDD_ID_OBJ_MGR);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to acquire pdev ref; status:%d", status);
+		QDF_BUG(false);
+		goto pdev_destroy;
+	}
+
+	status = target_if_alloc_pdev_tgt_info(pdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("pdev tgt info alloc failed");
+		goto pdev_destroy;
+	}
+
+	hdd_ctx->pdev = pdev;
+	sme_store_pdev(hdd_ctx->mac_handle, hdd_ctx->pdev);
+	hdd_init_pdev_os_priv(hdd_ctx, priv);
+	return 0;
+
+pdev_destroy:
+	wlan_objmgr_pdev_obj_delete(pdev);
+free_priv:
+	qdf_mem_free(priv);
+
+	return qdf_status_to_os_return(status);
+}
+
+int hdd_objmgr_release_and_destroy_pdev(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_pdev *pdev = hdd_ctx->pdev;
+	struct pdev_osif_priv *osif_priv;
+
+	hdd_ctx->pdev = NULL;
+
+	QDF_BUG(pdev);
+	if (!pdev)
+		return -EINVAL;
+
+	target_if_free_pdev_tgt_info(pdev);
+
+	hdd_deinit_pdev_os_priv(pdev);
+	osif_priv = wlan_pdev_get_ospriv(pdev);
+	wlan_pdev_reset_ospriv(pdev);
+	qdf_mem_free(osif_priv);
+
+	status = wlan_objmgr_pdev_obj_delete(pdev);
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_HDD_ID_OBJ_MGR);
+
+	return qdf_status_to_os_return(status);
+}
+
+int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev,
+				     struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+	int errno;
+	struct wlan_objmgr_vdev *vdev;
+	struct vdev_osif_priv *osif_priv;
+	struct wlan_vdev_create_params vdev_params = {0};
+
+	QDF_BUG(pdev);
+	if (!pdev) {
+		hdd_err("pdev is null");
+		return -EINVAL;
+	}
+
+	osif_priv = hdd_init_vdev_os_priv(adapter);
+	if (!osif_priv) {
+		hdd_err("Failed to allocate osif_priv; out of memory");
+		return -ENOMEM;
+	}
+
+	vdev_params.opmode = adapter->device_mode;
+	vdev_params.osifp = osif_priv;
+	qdf_mem_copy(vdev_params.macaddr,
+		     adapter->mac_addr.bytes,
+		     QDF_NET_MAC_ADDR_MAX_LEN);
+
+	vdev = wlan_objmgr_vdev_obj_create(pdev, &vdev_params);
+	if (!vdev) {
+		hdd_err("Failed to create vdev object");
+		errno = -ENOMEM;
+		goto osif_priv_free;
+	}
+
+	/*
+	 * To enable legacy use cases, we need to delay physical vdev destroy
+	 * until after the sme session has been closed. We accomplish this by
+	 * getting a reference here.
+	 */
+	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to acquire vdev ref; status:%d", status);
+		errno = qdf_status_to_os_return(status);
+		goto vdev_destroy;
+	}
+
+	adapter->vdev = vdev;
+	adapter->session_id = wlan_vdev_get_id(vdev);
+
+	return 0;
+
+vdev_destroy:
+	wlan_objmgr_vdev_obj_delete(vdev);
+
+osif_priv_free:
+	hdd_deinit_vdev_os_priv(osif_priv);
+
+	return errno;
+}
+
+int hdd_objmgr_release_and_destroy_vdev(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev = adapter->vdev;
+	struct vdev_osif_priv *osif_priv;
+
+	adapter->vdev = NULL;
+	adapter->session_id = HDD_SESSION_ID_INVALID;
+
+	QDF_BUG(vdev);
+	if (!vdev)
+		return -EINVAL;
+
+	osif_priv = wlan_vdev_get_ospriv(vdev);
+	wlan_vdev_reset_ospriv(vdev);
+
+	QDF_BUG(osif_priv);
+	hdd_deinit_vdev_os_priv(osif_priv);
+
+	status = wlan_objmgr_vdev_obj_delete(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
+
+	return qdf_status_to_os_return(status);
+}
+
+int hdd_objmgr_set_peer_mlme_auth_state(struct wlan_objmgr_vdev *vdev,
+					bool is_authenticated)
+{
+	struct wlan_objmgr_peer *peer;
+	QDF_STATUS status;
+
+	wlan_vdev_obj_lock(vdev);
+	peer = wlan_vdev_get_bsspeer(vdev);
+	wlan_vdev_obj_unlock(vdev);
+
+	if (!peer) {
+		hdd_err("peer is null");
+
+		return -EINVAL;
+	}
+	status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID);
+	if (status != QDF_STATUS_SUCCESS)
+		return -EINVAL;
+
+	wlan_peer_obj_lock(peer);
+	wlan_peer_mlme_set_auth_state(peer, is_authenticated);
+	wlan_peer_obj_unlock(peer);
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID);
+	return 0;
+}
+
+int hdd_objmgr_set_peer_mlme_state(struct wlan_objmgr_vdev *vdev,
+	enum wlan_peer_state peer_state)
+{
+	struct wlan_objmgr_peer *peer;
+
+	wlan_vdev_obj_lock(vdev);
+	peer = wlan_vdev_get_bsspeer(vdev);
+	wlan_vdev_obj_unlock(vdev);
+
+	if (!peer) {
+		hdd_err("peer is null");
+
+		return -EINVAL;
+	}
+
+	wlan_peer_obj_lock(peer);
+	wlan_peer_mlme_set_state(peer, WLAN_ASSOC_STATE);
+	wlan_peer_obj_unlock(peer);
+
+	return 0;
+}
+
diff --git a/core/hdd/src/wlan_hdd_object_manager.h b/core/hdd/src/wlan_hdd_object_manager.h
new file mode 100644
index 0000000..6b2c4cf
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_object_manager.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#if !defined(WLAN_HDD_OBJECT_MANAGER_H)
+#define WLAN_HDD_OBJECT_MANAGER_H
+/**
+ * DOC: HDD object manager API file to create/destroy psoc, pdev, vdev
+ * and peer objects by calling object manager APIs
+ *
+ * Common object model has 1 : N mapping between PSOC and PDEV but for MCL
+ * PSOC and PDEV has 1 : 1 mapping.
+ *
+ * MCL object model view is:
+ *
+ *                          --------
+ *                          | PSOC |
+ *                          --------
+ *                             |
+ *                             |
+ *                 --------------------------
+ *                 |          PDEV          |
+ *                 --------------------------
+ *                 |                        |
+ *                 |                        |
+ *                 |                        |
+ *             ----------             -------------
+ *             | vdev 0 |             |   vdev n  |
+ *             ----------             -------------
+ *             |        |             |           |
+ *        ----------   ----------    ----------  ----------
+ *        | peer 1 |   | peer n |    | peer 1 |  | peer n |
+ *        ----------   ----------    ----------  -----------
+ *
+ */
+#include "wlan_hdd_main.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>
+
+/**
+ * hdd_objmgr_create_and_store_psoc() - Create psoc and store in hdd context
+ * @hdd_ctx: Hdd context
+ * @psoc_id: Psoc Id
+ *
+ * This API creates Psoc object with given @psoc_id and store the psoc reference
+ * to hdd context
+ *
+ * Return: 0 for success, negative error code for failure
+ */
+int hdd_objmgr_create_and_store_psoc(struct hdd_context *hdd_ctx,
+				     uint8_t psoc_id);
+
+/**
+ * hdd_objmgr_release_and_destroy_psoc() - Deletes the psoc object
+ * @hdd_ctx: Hdd context
+ *
+ * This API deletes psoc object and release its reference from hdd context
+ *
+ * Return: 0 for success, negative error code for failure
+ */
+int hdd_objmgr_release_and_destroy_psoc(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_objmgr_update_tgt_max_vdev_psoc() - Update target max vdev number
+ * @hdd_ctx: Hdd context
+ *
+ * This API update target max vdev number to psoc object
+ *
+ * Return: None
+ */
+void hdd_objmgr_update_tgt_max_vdev_psoc(struct hdd_context *hdd_ctx,
+					 uint8_t max_vdev);
+
+/**
+ * hdd_objmgr_create_and_store_pdev() - Create pdev and store in hdd context
+ * @hdd_ctx: Hdd context
+ *
+ * This API creates the pdev object and store the pdev reference to hdd context
+ *
+ * Return: 0 for success, negative error code for failure
+ */
+int hdd_objmgr_create_and_store_pdev(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_objmgr_release_and_destroy_pdev() - Deletes the pdev object
+ * @hdd_ctx: Hdd context
+ *
+ * This API deletes pdev object and release its reference from hdd context
+ *
+ * Return: 0 for success, negative error code for failure
+ */
+int hdd_objmgr_release_and_destroy_pdev(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_objmgr_create_and_store_vdev() - Create vdev and store in hdd adapter
+ * @pdev: pdev pointer
+ * @adapter: hdd adapter
+ *
+ * This API creates the vdev object and store the vdev reference to the
+ * given @adapter. Also, creates a self peer for the vdev.
+ *
+ * Return: 0 for success, negative error code for failure
+ */
+int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev,
+			      struct hdd_adapter *adapter);
+
+/**
+ * hdd_objmgr_release_and_destroy_vdev() - Delete vdev and remove from adapter
+ * @adapter: hdd adapter
+ *
+ * This API deletes vdev object and release its reference from hdd adapter
+ *
+ * Return: 0 for success, negative error code for failure
+ */
+int hdd_objmgr_release_and_destroy_vdev(struct hdd_adapter *adapter);
+
+/**
+ * hdd_objmgr_set_peer_mlme_auth_state() - set the peer mlme auth state
+ * @vdev: vdev pointer
+ * @is_authenticated: Peer mlme auth state true/false
+ *
+ * This API set the peer mlme auth state
+ *
+ * Return: 0 for success, negative error code for failure
+ */
+int hdd_objmgr_set_peer_mlme_auth_state(struct wlan_objmgr_vdev *vdev,
+					bool is_authenticated);
+
+/**
+ * hdd_objmgr_set_peer_mlme_state() - set the peer mlme state
+ * @vdev: vdev pointer
+ * @peer_state: Peer mlme state
+ *
+ * This API set the peer mlme state
+ *
+ * Return: 0 for success, negative error code for failure
+ */
+int hdd_objmgr_set_peer_mlme_state(struct wlan_objmgr_vdev *vdev,
+				   enum wlan_peer_state peer_state);
+
+#endif /* end #if !defined(WLAN_HDD_OBJECT_MANAGER_H) */
diff --git a/core/hdd/src/wlan_hdd_ocb.c b/core/hdd/src/wlan_hdd_ocb.c
new file mode 100644
index 0000000..9bdd0d8
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_ocb.c
@@ -0,0 +1,2036 @@
+/*
+ * Copyright (c) 2011-2018 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: wlan_hdd_ocb.c
+ *
+ * WLAN Host Device Driver 802.11p OCB implementation
+ */
+
+#include "cds_sched.h"
+#include "wlan_hdd_assoc.h"
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_ocb.h"
+#include "wlan_hdd_trace.h"
+#include "wlan_osif_request_manager.h"
+#include "wlan_tgt_def_config.h"
+#include "sch_api.h"
+#include "wma_api.h"
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_peer_ops.h>
+#include <cdp_txrx_handle.h>
+#include "wlan_ocb_public_structs.h"
+#include "wlan_ocb_ucfg_api.h"
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_peer_ops.h>
+#include <cdp_txrx_handle.h>
+#include <cdp_txrx_ocb.h>
+
+/* Structure definitions for WLAN_SET_DOT11P_CHANNEL_SCHED */
+#define AIFSN_MIN		(2)
+#define AIFSN_MAX		(15)
+#define CW_MIN			(1)
+#define CW_MAX			(10)
+
+/* Maximum time(ms) to wait for OCB operations */
+#define WLAN_WAIT_TIME_OCB_CMD 1500
+
+/**
+ * dot11p_validate_qos_params() - Check if QoS parameters are valid
+ * @qos_params:   Array of QoS parameters
+ *
+ * Return: 0 on success. error code on failure.
+ */
+static int dot11p_validate_qos_params(struct ocb_wmm_param qos_params[])
+{
+	int i;
+
+	for (i = 0; i < MAX_NUM_AC; i++) {
+		if ((!qos_params[i].aifsn) && (!qos_params[i].cwmin)
+				&& (!qos_params[i].cwmax))
+			continue;
+
+		/* Validate AIFSN */
+		if ((qos_params[i].aifsn < AIFSN_MIN)
+				|| (qos_params[i].aifsn > AIFSN_MAX)) {
+			hdd_err("Invalid QoS parameter aifsn %d",
+				qos_params[i].aifsn);
+			return -EINVAL;
+		}
+
+		/* Validate CWMin */
+		if ((qos_params[i].cwmin < CW_MIN)
+				|| (qos_params[i].cwmin > CW_MAX)) {
+			hdd_err("Invalid QoS parameter cwmin %d",
+				qos_params[i].cwmin);
+			return -EINVAL;
+		}
+
+		/* Validate CWMax */
+		if ((qos_params[i].cwmax < CW_MIN)
+				|| (qos_params[i].cwmax > CW_MAX)) {
+			hdd_err("Invalid QoS parameter cwmax %d",
+				qos_params[i].cwmax);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * dot11p_validate_channel() - validates a DSRC channel
+ * @center_freq: the channel's center frequency
+ * @bandwidth: the channel's bandwidth
+ * @tx_power: transmit power
+ * @reg_power: (output) the max tx power from the regulatory domain
+ * @antenna_max: (output) the max antenna gain from the regulatory domain
+ *
+ * Return: 0 if the channel is valid, error code otherwise.
+ */
+static int dot11p_validate_channel(struct wiphy *wiphy,
+				   uint32_t channel_freq, uint32_t bandwidth,
+				   uint32_t tx_power, uint8_t *reg_power,
+				   uint8_t *antenna_max)
+{
+	int band_idx, channel_idx;
+	struct ieee80211_supported_band *current_band;
+	struct ieee80211_channel *current_channel;
+
+	for (band_idx = 0; band_idx < HDD_NUM_NL80211_BANDS; band_idx++) {
+		current_band = wiphy->bands[band_idx];
+		if (!current_band)
+			continue;
+
+		for (channel_idx = 0; channel_idx < current_band->n_channels;
+		      channel_idx++) {
+			current_channel = &current_band->channels[channel_idx];
+
+			if (channel_freq == current_channel->center_freq) {
+				if (current_channel->flags &
+				    IEEE80211_CHAN_DISABLED)
+					return -EINVAL;
+
+				if (reg_power)
+					*reg_power =
+						current_channel->max_reg_power;
+				if (antenna_max)
+					*antenna_max =
+						current_channel->
+						max_antenna_gain;
+
+				switch (bandwidth) {
+				case 0:
+					if (current_channel->flags &
+					    IEEE80211_CHAN_NO_10MHZ)
+						bandwidth = 5;
+					else if (current_channel->flags &
+						 IEEE80211_CHAN_NO_20MHZ)
+						bandwidth = 10;
+					else
+						bandwidth = 20;
+					break;
+				case 5:
+					break;
+				case 10:
+					if (current_channel->flags &
+					    IEEE80211_CHAN_NO_10MHZ)
+						return -EINVAL;
+					break;
+				case 20:
+					if (current_channel->flags &
+					    IEEE80211_CHAN_NO_20MHZ)
+						return -EINVAL;
+					break;
+				default:
+					return -EINVAL;
+				}
+
+				if (tx_power > current_channel->max_power)
+					return -EINVAL;
+
+				return 0;
+			}
+		}
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * hdd_ocb_validate_config() - Validates the config data
+ * @config: configuration to be validated
+ *
+ * Return: 0 on success.
+ */
+static int hdd_ocb_validate_config(struct hdd_adapter *adapter,
+				   struct ocb_config *config)
+{
+	int i;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	for (i = 0; i < config->channel_count; i++) {
+		if (dot11p_validate_channel(hdd_ctx->wiphy,
+					    config->channels[i].chan_freq,
+					    config->channels[i].bandwidth,
+					    config->channels[i].max_pwr,
+					    &config->channels[i].reg_pwr,
+					    &config->channels[i].antenna_max)) {
+			hdd_err("Invalid channel frequency %d",
+				config->channels[i].chan_freq);
+			return -EINVAL;
+		}
+		if (dot11p_validate_qos_params(config->channels[i].qos_params))
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_ocb_register_sta() - Register station with Transport Layer
+ * @adapter: Pointer to HDD Adapter
+ *
+ * This function should be invoked in the OCB Set Schedule callback
+ * to enable the data path in the TL by calling RegisterSTAClient
+ *
+ * Return: 0 on success. -1 on failure.
+ */
+static int hdd_ocb_register_sta(struct hdd_adapter *adapter)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	struct ol_txrx_desc_type sta_desc = {0};
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	uint8_t peer_id;
+	struct ol_txrx_ops txrx_ops;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	qdf_status = cdp_peer_register_ocb_peer(soc,
+				adapter->mac_addr.bytes,
+				&peer_id);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Error registering OCB Self Peer!");
+		return -EINVAL;
+	}
+
+	hdd_ctx->sta_to_adapter[peer_id] = adapter;
+
+	sta_desc.sta_id = peer_id;
+	sta_desc.is_qos_enabled = 1;
+
+	/* Register the vdev transmit and receive functions */
+	qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
+	txrx_ops.rx.rx = hdd_rx_packet_cbk;
+	cdp_vdev_register(soc,
+		(struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
+		(struct cdp_pdev *)pdev, adapter->session_id),
+		adapter, (struct cdp_ctrl_objmgr_vdev *)adapter->vdev,
+		&txrx_ops);
+	txrx_ops.rx.stats_rx = hdd_tx_rx_collect_connectivity_stats_info;
+	adapter->tx_fn = txrx_ops.tx.tx;
+
+	qdf_status = cdp_peer_register(soc,
+			(struct cdp_pdev *)pdev, &sta_desc);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Failed to register. Status= %d [0x%08X]",
+		       qdf_status, qdf_status);
+		return -EINVAL;
+	}
+
+	if (sta_ctx->conn_info.staId[0] != HDD_WLAN_INVALID_STA_ID &&
+	     sta_ctx->conn_info.staId[0] != peer_id) {
+		hdd_err("The ID for the OCB station has changed.");
+	}
+
+	sta_ctx->conn_info.staId[0] = peer_id;
+	qdf_copy_macaddr(&sta_ctx->conn_info.peerMacAddress[0],
+			 &adapter->mac_addr);
+
+	return 0;
+}
+
+/**
+ * hdd_ocb_config_new() - Creates a new OCB configuration
+ * @num_channels: the number of channels
+ * @num_schedule: the schedule size
+ * @ndl_chan_list_len: length in bytes of the NDL chan blob
+ * @ndl_active_state_list_len: length in bytes of the active state blob
+ *
+ * Return: A pointer to the OCB configuration struct, NULL on failure.
+ */
+static
+struct ocb_config *hdd_ocb_config_new(uint32_t num_channels,
+				      uint32_t num_schedule,
+				      uint32_t ndl_chan_list_len,
+				      uint32_t ndl_active_state_list_len)
+{
+	struct ocb_config *ret = 0;
+	uint32_t len;
+	void *cursor;
+
+	if (num_channels > CFG_TGT_NUM_OCB_CHANNELS ||
+			num_schedule > CFG_TGT_NUM_OCB_SCHEDULES)
+		return NULL;
+
+	len = sizeof(*ret) +
+		num_channels * sizeof(struct ocb_config_chan) +
+		num_schedule * sizeof(struct ocb_config_schdl) +
+		ndl_chan_list_len +
+		ndl_active_state_list_len;
+
+	cursor = qdf_mem_malloc(len);
+	if (!cursor)
+		goto fail;
+
+	ret = cursor;
+	cursor += sizeof(*ret);
+
+	ret->channel_count = num_channels;
+	ret->channels = cursor;
+	cursor += num_channels * sizeof(*ret->channels);
+
+	ret->schedule_size = num_schedule;
+	ret->schedule = cursor;
+	cursor += num_schedule * sizeof(*ret->schedule);
+
+	ret->dcc_ndl_chan_list = cursor;
+	cursor += ndl_chan_list_len;
+
+	ret->dcc_ndl_active_state_list = cursor;
+	cursor += ndl_active_state_list_len;
+
+	return ret;
+
+fail:
+	qdf_mem_free(ret);
+	return NULL;
+}
+
+struct hdd_ocb_set_config_priv {
+	int status;
+};
+
+
+/**
+ * hdd_ocb_set_config_callback() - OCB set config callback function
+ * @context_ptr: OCB call context
+ * @response_ptr: Pointer to response structure
+ *
+ * This function is registered as a callback with the lower layers
+ * and is used to respond with the status of a OCB set config command.
+ */
+static void hdd_ocb_set_config_callback(void *context_ptr, void *response_ptr)
+{
+	struct osif_request *request;
+	struct hdd_ocb_set_config_priv *priv;
+	struct ocb_set_config_response *response = response_ptr;
+
+	request = osif_request_get(context_ptr);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+	priv = osif_request_priv(request);
+
+	if (response && response->status)
+		hdd_warn("Operation failed: %d", response->status);
+
+	if (response && (response->status == OCB_CHANNEL_CONFIG_SUCCESS))
+		priv->status = 0;
+	else
+		priv->status = -EINVAL;
+
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+/**
+ * hdd_ocb_set_config_req() - Send an OCB set config request
+ * @adapter: a pointer to the adapter
+ * @config: a pointer to the OCB configuration
+ *
+ * Return: 0 on success.
+ */
+static int hdd_ocb_set_config_req(struct hdd_adapter *adapter,
+				  struct ocb_config *config)
+{
+	int rc;
+	QDF_STATUS status;
+	void *cookie;
+	struct osif_request *request;
+	struct hdd_ocb_set_config_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_OCB_CMD,
+	};
+
+	if (hdd_ocb_validate_config(adapter, config)) {
+		hdd_err("The configuration is invalid");
+		return -EINVAL;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	hdd_debug("Disabling queues");
+	wlan_hdd_netif_queue_control(adapter,
+				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
+				     WLAN_CONTROL_PATH);
+
+	status = ucfg_ocb_set_channel_config(adapter->vdev, config,
+					     hdd_ocb_set_config_callback,
+					     cookie);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to set channel config.");
+		rc = qdf_status_to_os_return(status);
+		goto end;
+	}
+
+	/* Wait for the function to complete. */
+	rc = osif_request_wait_for_response(request);
+	if (rc) {
+		hdd_err("Operation timed out");
+		goto end;
+	}
+
+	priv = osif_request_priv(request);
+	rc = priv->status;
+	if (rc) {
+		hdd_err("Operation failed: %d", rc);
+		goto end;
+	}
+
+	/*
+	 * OCB set config command successful.
+	 * Open the TX data path
+	 */
+	if (!hdd_ocb_register_sta(adapter))
+		wlan_hdd_netif_queue_control(adapter,
+					WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
+					WLAN_CONTROL_PATH);
+
+	/* fall through */
+end:
+	osif_request_put(request);
+
+	return rc;
+}
+
+#ifdef WLAN_WEXT_SUPPORT_ENABLE
+/**
+ * __iw_set_dot11p_channel_sched() - Handler for WLAN_SET_DOT11P_CHANNEL_SCHED
+ *				     ioctl
+ * @dev: Pointer to net_device structure
+ * @iw_request_info: IW Request Info
+ * @wrqu: IW Request Userspace Data Pointer
+ * @extra: IW Request Kernel Data Pointer
+ *
+ * Return: 0 on success
+ */
+static int __iw_set_dot11p_channel_sched(struct net_device *dev,
+					 struct iw_request_info *info,
+					 union iwreq_data *wrqu, char *extra)
+{
+	int rc;
+	struct dot11p_channel_sched *sched;
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct ocb_config *config = NULL;
+	uint8_t *mac_addr;
+	int i, j;
+	struct ocb_config_chan *curr_chan;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	rc = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != rc)
+		return rc;
+
+	rc = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != rc)
+		return rc;
+
+	if (adapter->device_mode != QDF_OCB_MODE) {
+		hdd_err("Device not in OCB mode!");
+		return -EINVAL;
+	}
+
+	sched = (struct dot11p_channel_sched *)extra;
+
+	/* Scheduled slots same as num channels for compatibility */
+	config = hdd_ocb_config_new(sched->num_channels, sched->num_channels,
+				    0, 0);
+	if (config == NULL) {
+		hdd_err("Failed to allocate memory!");
+		return -ENOMEM;
+	}
+
+	/* Identify the vdev interface */
+	config->vdev_id = adapter->session_id;
+
+	/* Release all the mac addresses used for OCB */
+	for (i = 0; i < adapter->ocb_mac_addr_count; i++) {
+		wlan_hdd_release_intf_addr(hdd_ctx,
+					   adapter->ocb_mac_address[i].bytes);
+	}
+	adapter->ocb_mac_addr_count = 0;
+
+	config->channel_count = 0;
+	for (i = 0; i < sched->num_channels; i++) {
+		if (0 == sched->channels[i].channel_freq)
+			continue;
+
+		curr_chan = &(config->channels[config->channel_count]);
+
+		curr_chan->chan_freq = sched->channels[i].channel_freq;
+		/*
+		 * tx_power is divided by 2 because ocb_channel.tx_power is
+		 * in half dB increments and ocb_config_channel.max_pwr
+		 * is in 1 dB increments.
+		 */
+		curr_chan->max_pwr = sched->channels[i].tx_power / 2;
+		curr_chan->bandwidth = sched->channels[i].channel_bandwidth;
+		/* assume 10 as default if not provided */
+		if (curr_chan->bandwidth == 0)
+			curr_chan->bandwidth = 10;
+
+		/*
+		 * Setup locally administered mac addresses for each channel.
+		 * First channel uses the adapter's address.
+		 */
+		if (i == 0) {
+			qdf_copy_macaddr(&curr_chan->mac_address,
+				     &adapter->mac_addr);
+		} else {
+			mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
+			if (mac_addr == NULL) {
+				hdd_err("Cannot obtain mac address");
+				rc = -EINVAL;
+				goto fail;
+			}
+			qdf_mem_copy(config->channels[
+				     config->channel_count].mac_address.bytes,
+				     mac_addr, sizeof(tSirMacAddr));
+			/* Save the mac address to release later */
+			qdf_mem_copy(adapter->ocb_mac_address[
+				     adapter->ocb_mac_addr_count].bytes,
+				     mac_addr, QDF_MAC_ADDR_SIZE);
+			adapter->ocb_mac_addr_count++;
+		}
+
+		for (j = 0; j < MAX_NUM_AC; j++) {
+			curr_chan->qos_params[j].aifsn =
+				sched->channels[i].qos_params[j].aifsn;
+			curr_chan->qos_params[j].cwmin =
+				sched->channels[i].qos_params[j].cwmin;
+			curr_chan->qos_params[j].cwmax =
+				sched->channels[i].qos_params[j].cwmax;
+		}
+
+		config->channel_count++;
+	}
+
+	/*
+	 * Scheduled slots same as num channels for compatibility with
+	 * legacy use.
+	 */
+	for (i = 0; i < sched->num_channels; i++) {
+		config->schedule[i].chan_freq = sched->channels[i].channel_freq;
+		config->schedule[i].guard_interval =
+			sched->channels[i].start_guard_interval;
+		config->schedule[i].total_duration =
+			sched->channels[i].duration;
+	}
+
+	rc = hdd_ocb_set_config_req(adapter, config);
+	if (rc) {
+		hdd_err("Error while setting OCB config");
+		goto fail;
+	}
+
+	rc = 0;
+
+fail:
+	qdf_mem_free(config);
+	return rc;
+}
+
+/**
+ * iw_set_dot11p_channel_sched() - IOCTL interface for setting channel schedule
+ * @dev: Pointer to net_device structure
+ * @iw_request_info: IW Request Info
+ * @wrqu: IW Request Userspace Data Pointer
+ * @extra: IW Request Kernel Data Pointer
+ *
+ * Return: 0 on success.
+ */
+int iw_set_dot11p_channel_sched(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_set_dot11p_channel_sched(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif /* WLAN_WEXT_SUPPORT_ENABLE */
+
+static const struct nla_policy qca_wlan_vendor_ocb_set_config_policy[
+		QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_ARRAY] = {
+		.type = NLA_BINARY
+	},
+	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_ARRAY] = {
+		.type = NLA_BINARY
+	},
+	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY] = {
+		.type = NLA_BINARY
+	},
+	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY] = {
+		.type = NLA_BINARY
+	},
+	[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS] = {
+		.type = NLA_U32
+	},
+};
+
+static const struct nla_policy qca_wlan_vendor_ocb_set_utc_time_policy[
+		QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_VALUE] = {
+		.type = NLA_BINARY, .len = SIZE_UTC_TIME
+	},
+	[QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_ERROR] = {
+		.type = NLA_BINARY, .len = SIZE_UTC_TIME_ERROR
+	},
+};
+
+static const struct nla_policy qca_wlan_vendor_ocb_start_timing_advert_policy[
+		QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE] = {
+		.type = NLA_U32
+	},
+};
+
+static const struct nla_policy  qca_wlan_vendor_ocb_stop_timing_advert_policy[
+		QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ] = {
+		.type = NLA_U32
+	},
+};
+
+static const struct nla_policy qca_wlan_vendor_ocb_get_tsf_timer_resp[] = {
+	[QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_HIGH] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_LOW] = {
+		.type = NLA_U32
+	},
+};
+
+static const struct nla_policy qca_wlan_vendor_dcc_get_stats[] = {
+	[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_CHANNEL_COUNT] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY] = {
+		.type = NLA_BINARY
+	},
+};
+
+static const struct nla_policy qca_wlan_vendor_dcc_get_stats_resp[] = {
+	[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_CHANNEL_COUNT] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_STATS_ARRAY] = {
+		.type = NLA_BINARY
+	},
+};
+
+static const struct nla_policy qca_wlan_vendor_dcc_clear_stats[] = {
+	[QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_BITMAP] = {
+		.type = NLA_U32
+	},
+};
+
+static const struct nla_policy qca_wlan_vendor_dcc_update_ndl[
+		QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_COUNT] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_ARRAY] = {
+		.type = NLA_BINARY
+	},
+	[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_ACTIVE_STATE_ARRAY] = {
+		.type = NLA_BINARY
+	},
+};
+
+/**
+ * struct wlan_hdd_ocb_config_channel
+ * @chan_freq: frequency of the channel
+ * @bandwidth: bandwidth of the channel, either 10 or 20 MHz
+ * @mac_address: MAC address assigned to this channel
+ * @qos_params: QoS parameters
+ * @max_pwr: maximum transmit power of the channel (1/2 dBm)
+ * @min_pwr: minimum transmit power of the channel (1/2 dBm)
+ */
+struct wlan_hdd_ocb_config_channel {
+	uint32_t chan_freq;
+	uint32_t bandwidth;
+	uint16_t flags;
+	uint8_t reserved[4];
+	struct sir_qos_params qos_params[MAX_NUM_AC];
+	uint32_t max_pwr;
+	uint32_t min_pwr;
+};
+
+static void wlan_hdd_ocb_config_channel_to_ocb_config_channel(
+	struct ocb_config_chan *dest,
+	struct wlan_hdd_ocb_config_channel *src,
+	uint32_t channel_count)
+{
+	uint32_t i;
+
+	qdf_mem_zero(dest, channel_count * sizeof(*dest));
+
+	for (i = 0; i < channel_count; i++) {
+		dest[i].chan_freq = src[i].chan_freq;
+		dest[i].bandwidth = src[i].bandwidth;
+		qdf_mem_copy(dest[i].qos_params, src[i].qos_params,
+			     sizeof(dest[i].qos_params));
+		/*
+		 *  max_pwr and min_pwr are divided by 2 because
+		 *  ocb_channel_param.max_pwr and min_pwr
+		 *  are in 1/2 dB increments and
+		 *  ocb_config_channel.max_pwr and min_pwr are in
+		 *  1 dB increments.
+		 */
+		dest[i].max_pwr = src[i].max_pwr / 2;
+		dest[i].min_pwr = (src[i].min_pwr + 1) / 2;
+		dest[i].flags = src[i].flags;
+	}
+}
+
+/**
+ * __wlan_hdd_cfg80211_ocb_set_config() - Interface for set config command
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+static int __wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      const void *data,
+					      int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_MAX + 1];
+	struct nlattr *channel_array;
+	struct nlattr *sched_array;
+	struct nlattr *ndl_chan_list;
+	uint32_t ndl_chan_list_len;
+	struct nlattr *ndl_active_state_list;
+	uint32_t ndl_active_state_list_len;
+	uint32_t flags = 0;
+	int i;
+	uint32_t channel_count, schedule_size;
+	struct ocb_config *config;
+	int rc = -EINVAL;
+	uint8_t *mac_addr;
+
+	hdd_enter_dev(dev);
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	if (adapter->device_mode != QDF_OCB_MODE) {
+		hdd_err("Device not in OCB mode!");
+		return -EINVAL;
+	}
+
+	/* Parse the netlink message */
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_MAX,
+				    data, data_len,
+				    qca_wlan_vendor_ocb_set_config_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Get the number of channels in the schedule */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT]) {
+		hdd_err("CHANNEL_COUNT is not present");
+		return -EINVAL;
+	}
+	channel_count = nla_get_u32(
+		tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT]);
+
+	/* Get the size of the channel schedule */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE]) {
+		hdd_err("SCHEDULE_SIZE is not present");
+		return -EINVAL;
+	}
+	schedule_size = nla_get_u32(
+		tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE]);
+
+	/* Get the ndl chan array and the ndl active state array. */
+	ndl_chan_list =
+		tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY];
+	ndl_chan_list_len = (ndl_chan_list ? nla_len(ndl_chan_list) : 0);
+
+	ndl_active_state_list =
+		tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY];
+	ndl_active_state_list_len = (ndl_active_state_list ?
+				    nla_len(ndl_active_state_list) : 0);
+
+	/* Get the flags */
+	if (tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS])
+		flags = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS]);
+
+	config = hdd_ocb_config_new(channel_count, schedule_size,
+				    ndl_chan_list_len,
+				    ndl_active_state_list_len);
+	if (config == NULL) {
+		hdd_err("Failed to allocate memory!");
+		return -ENOMEM;
+	}
+
+	config->channel_count = channel_count;
+	config->schedule_size = schedule_size;
+	config->flags = flags;
+
+	/* Read the channel array */
+	channel_array = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_ARRAY];
+	if (!channel_array) {
+		hdd_err("No channel present");
+		goto fail;
+	}
+	if (nla_len(channel_array) != channel_count *
+	    sizeof(struct wlan_hdd_ocb_config_channel)) {
+		hdd_err("CHANNEL_ARRAY is not the correct size");
+		goto fail;
+	}
+	wlan_hdd_ocb_config_channel_to_ocb_config_channel(
+	    config->channels, nla_data(channel_array), channel_count);
+
+	/* Identify the vdev interface */
+	config->vdev_id = adapter->session_id;
+
+	/* Release all the mac addresses used for OCB */
+	for (i = 0; i < adapter->ocb_mac_addr_count; i++) {
+		wlan_hdd_release_intf_addr(hdd_ctx,
+					   adapter->ocb_mac_address[i].bytes);
+	}
+	adapter->ocb_mac_addr_count = 0;
+
+	/*
+	 * Setup locally administered mac addresses for each channel.
+	 * First channel uses the adapter's address.
+	 */
+	for (i = 0; i < config->channel_count; i++) {
+		if (i == 0) {
+			qdf_copy_macaddr(&config->channels[i].mac_address,
+				&adapter->mac_addr);
+		} else {
+			mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
+			if (mac_addr == NULL) {
+				hdd_err("Cannot obtain mac address");
+				goto fail;
+			}
+			qdf_mem_copy(config->channels[i].mac_address.bytes,
+				mac_addr, QDF_MAC_ADDR_SIZE);
+			/* Save the mac address to release later */
+			qdf_copy_macaddr(&adapter->ocb_mac_address[
+				     adapter->ocb_mac_addr_count],
+				     &config->channels[i].mac_address);
+			adapter->ocb_mac_addr_count++;
+		}
+	}
+
+	/* Read the schedule array */
+	sched_array = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_ARRAY];
+	if (!sched_array) {
+		hdd_err("No channel present");
+		goto fail;
+	}
+	if (nla_len(sched_array) != schedule_size * sizeof(*config->schedule)) {
+		hdd_err("SCHEDULE_ARRAY is not the correct size");
+		goto fail;
+	}
+	qdf_mem_copy(config->schedule, nla_data(sched_array),
+		nla_len(sched_array));
+
+	/* Copy the NDL chan array */
+	if (ndl_chan_list_len) {
+		config->dcc_ndl_chan_list_len = ndl_chan_list_len;
+		qdf_mem_copy(config->dcc_ndl_chan_list, nla_data(ndl_chan_list),
+			nla_len(ndl_chan_list));
+	}
+
+	/* Copy the NDL active state array */
+	if (ndl_active_state_list_len) {
+		config->dcc_ndl_active_state_list_len =
+			ndl_active_state_list_len;
+		qdf_mem_copy(config->dcc_ndl_active_state_list,
+			nla_data(ndl_active_state_list),
+			nla_len(ndl_active_state_list));
+	}
+
+	rc = hdd_ocb_set_config_req(adapter, config);
+	if (rc)
+		hdd_err("Error while setting OCB config: %d", rc);
+
+fail:
+	qdf_mem_free(config);
+	return rc;
+}
+
+/**
+ * wlan_hdd_cfg80211_ocb_set_config() - Interface for set config command
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+int wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     const void *data,
+				     int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_ocb_set_config(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_ocb_set_utc_time() - Interface for set UTC time command
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+static int __wlan_hdd_cfg80211_ocb_set_utc_time(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_MAX + 1];
+	struct nlattr *utc_attr;
+	struct nlattr *time_error_attr;
+	struct ocb_utc_param *utc;
+	int rc = -EINVAL;
+
+	hdd_enter_dev(dev);
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	if (adapter->device_mode != QDF_OCB_MODE) {
+		hdd_err("Device not in OCB mode!");
+		return -EINVAL;
+	}
+
+	if (!wma_is_vdev_up(adapter->session_id)) {
+		hdd_err("The device has not been started");
+		return -EINVAL;
+	}
+
+	/* Parse the netlink message */
+	if (wlan_cfg80211_nla_parse(tb,
+				    QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_MAX,
+				    data, data_len,
+				    qca_wlan_vendor_ocb_set_utc_time_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Read the UTC time */
+	utc_attr = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_VALUE];
+	if (!utc_attr) {
+		hdd_err("UTC_TIME is not present");
+		return -EINVAL;
+	}
+	if (nla_len(utc_attr) != SIZE_UTC_TIME) {
+		hdd_err("UTC_TIME is not the correct size");
+		return -EINVAL;
+	}
+
+	/* Read the time error */
+	time_error_attr = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_ERROR];
+	if (!time_error_attr) {
+		hdd_err("UTC_TIME is not present");
+		return -EINVAL;
+	}
+	if (nla_len(time_error_attr) != SIZE_UTC_TIME_ERROR) {
+		hdd_err("UTC_TIME is not the correct size");
+		return -EINVAL;
+	}
+
+	utc = qdf_mem_malloc(sizeof(*utc));
+	if (!utc) {
+		hdd_err("qdf_mem_malloc failed");
+		return -ENOMEM;
+	}
+	utc->vdev_id = adapter->session_id;
+	qdf_mem_copy(utc->utc_time, nla_data(utc_attr), SIZE_UTC_TIME);
+	qdf_mem_copy(utc->time_error, nla_data(time_error_attr),
+		SIZE_UTC_TIME_ERROR);
+
+	if (ucfg_ocb_set_utc_time(adapter->vdev, utc) !=
+			QDF_STATUS_SUCCESS) {
+		hdd_err("Error while setting UTC time");
+		rc = -EINVAL;
+	} else {
+		rc = 0;
+	}
+
+	qdf_mem_free(utc);
+	return rc;
+}
+
+/**
+ * wlan_hdd_cfg80211_ocb_set_utc_time() - Interface for the set UTC time command
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+int wlan_hdd_cfg80211_ocb_set_utc_time(struct wiphy *wiphy,
+				       struct wireless_dev *wdev,
+				       const void *data,
+				       int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_ocb_set_utc_time(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_ocb_start_timing_advert() - Interface for start TA cmd
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+static int
+__wlan_hdd_cfg80211_ocb_start_timing_advert(struct wiphy *wiphy,
+					    struct wireless_dev *wdev,
+					    const void *data,
+					    int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_MAX + 1];
+	struct ocb_timing_advert_param *timing_advert;
+	int rc = -EINVAL;
+
+	hdd_enter_dev(dev);
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	if (adapter->device_mode != QDF_OCB_MODE) {
+		hdd_err("Device not in OCB mode!");
+		return -EINVAL;
+	}
+
+	if (!wma_is_vdev_up(adapter->session_id)) {
+		hdd_err("The device has not been started");
+		return -EINVAL;
+	}
+
+	timing_advert = qdf_mem_malloc(sizeof(*timing_advert));
+	if (!timing_advert) {
+		hdd_err("qdf_mem_malloc failed");
+		return -ENOMEM;
+	}
+	timing_advert->vdev_id = adapter->session_id;
+
+	/* Parse the netlink message */
+	if (wlan_cfg80211_nla_parse(tb,
+			      QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_MAX,
+			      data, data_len,
+			      qca_wlan_vendor_ocb_start_timing_advert_policy)) {
+		hdd_err("Invalid ATTR");
+		goto fail;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ]) {
+		hdd_err("CHANNEL_FREQ is not present");
+		goto fail;
+	}
+	timing_advert->chan_freq = nla_get_u32(
+		tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ]);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE]) {
+		hdd_err("REPEAT_RATE is not present");
+		goto fail;
+	}
+	timing_advert->repeat_rate = nla_get_u32(
+		tb[QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE]);
+
+	timing_advert->template_length =
+		sme_ocb_gen_timing_advert_frame(hdd_ctx->mac_handle,
+			*(tSirMacAddr *)&adapter->mac_addr.bytes,
+			&timing_advert->template_value,
+			&timing_advert->timestamp_offset,
+			&timing_advert->time_value_offset);
+	if (timing_advert->template_length <= 0) {
+		hdd_err("Error while generating the TA frame");
+		goto fail;
+	}
+
+	if (ucfg_ocb_start_timing_advert(adapter->vdev, timing_advert) !=
+			QDF_STATUS_SUCCESS) {
+		hdd_err("Error while starting timing advert");
+		rc = -EINVAL;
+	} else {
+		rc = 0;
+	}
+
+fail:
+	if (timing_advert->template_value)
+		qdf_mem_free(timing_advert->template_value);
+	qdf_mem_free(timing_advert);
+	return rc;
+}
+
+/**
+ * wlan_hdd_cfg80211_ocb_start_timing_advert() - Interface for the start TA cmd
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+int wlan_hdd_cfg80211_ocb_start_timing_advert(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      const void *data,
+					      int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_ocb_start_timing_advert(wiphy, wdev,
+							  data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_ocb_stop_timing_advert() - Interface for the stop TA cmd
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+static int
+__wlan_hdd_cfg80211_ocb_stop_timing_advert(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data,
+					   int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_MAX + 1];
+	struct ocb_timing_advert_param *timing_advert;
+	int rc = -EINVAL;
+
+	hdd_enter_dev(dev);
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	if (adapter->device_mode != QDF_OCB_MODE) {
+		hdd_err("Device not in OCB mode!");
+		return -EINVAL;
+	}
+
+	if (!wma_is_vdev_up(adapter->session_id)) {
+		hdd_err("The device has not been started");
+		return -EINVAL;
+	}
+
+	timing_advert = qdf_mem_malloc(sizeof(*timing_advert));
+	if (!timing_advert) {
+		hdd_err("qdf_mem_malloc failed");
+		return -ENOMEM;
+	}
+	timing_advert->vdev_id = adapter->session_id;
+
+	/* Parse the netlink message */
+	if (wlan_cfg80211_nla_parse(tb,
+			       QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_MAX,
+			       data, data_len,
+			       qca_wlan_vendor_ocb_stop_timing_advert_policy)) {
+		hdd_err("Invalid ATTR");
+		goto fail;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ]) {
+		hdd_err("CHANNEL_FREQ is not present");
+		goto fail;
+	}
+	timing_advert->chan_freq = nla_get_u32(
+		tb[QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ]);
+
+	if (ucfg_ocb_stop_timing_advert(adapter->vdev, timing_advert) !=
+			QDF_STATUS_SUCCESS) {
+		hdd_err("Error while stopping timing advert");
+		rc = -EINVAL;
+	} else {
+		rc = 0;
+	}
+
+fail:
+	qdf_mem_free(timing_advert);
+	return rc;
+}
+
+/**
+ * wlan_hdd_cfg80211_ocb_stop_timing_advert() - Interface for the stop TA cmd
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+int wlan_hdd_cfg80211_ocb_stop_timing_advert(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data,
+					     int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_ocb_stop_timing_advert(wiphy, wdev,
+							 data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+struct hdd_ocb_get_tsf_timer_priv {
+	struct ocb_get_tsf_timer_response response;
+	int status;
+};
+
+/**
+ * hdd_ocb_get_tsf_timer_callback() - Callback to get TSF command
+ * @context_ptr: request context
+ * @response_ptr: response data
+ */
+static void hdd_ocb_get_tsf_timer_callback(void *context_ptr,
+					   void *response_ptr)
+{
+	struct osif_request *request;
+	struct hdd_ocb_get_tsf_timer_priv *priv;
+	struct ocb_get_tsf_timer_response *response = response_ptr;
+
+	request = osif_request_get(context_ptr);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+	if (response) {
+		priv->response = *response;
+		priv->status = 0;
+	} else {
+		priv->status = -EINVAL;
+	}
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+static int
+hdd_ocb_get_tsf_timer_reply(struct wiphy *wiphy,
+			    struct ocb_get_tsf_timer_response *response)
+{
+	uint32_t nl_buf_len;
+	struct sk_buff *nl_resp;
+	int rc;
+
+	/* Allocate the buffer for the response. */
+	nl_buf_len = NLMSG_HDRLEN;
+	nl_buf_len += 2 * (NLA_HDRLEN + sizeof(uint32_t));
+	nl_resp = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, nl_buf_len);
+	if (!nl_resp) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	/* Populate the response. */
+	rc = nla_put_u32(nl_resp,
+			 QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_HIGH,
+			 response->timer_high);
+	if (rc)
+		goto end;
+	rc = nla_put_u32(nl_resp,
+			 QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_LOW,
+			 response->timer_low);
+	if (rc)
+		goto end;
+
+	/* Send the response. */
+	rc = cfg80211_vendor_cmd_reply(nl_resp);
+	nl_resp = NULL;
+	if (rc) {
+		hdd_err("cfg80211_vendor_cmd_reply failed: %d", rc);
+		goto end;
+	}
+end:
+	if (nl_resp)
+		kfree_skb(nl_resp);
+
+	return rc;
+}
+
+/**
+ * __wlan_hdd_cfg80211_ocb_get_tsf_timer() - Interface for get TSF timer cmd
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+static int
+__wlan_hdd_cfg80211_ocb_get_tsf_timer(struct wiphy *wiphy,
+				      struct wireless_dev *wdev,
+				      const void *data,
+				      int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int rc;
+	struct ocb_get_tsf_timer_param tsf_request = {0};
+	QDF_STATUS status;
+	void *cookie;
+	struct osif_request *request;
+	struct hdd_ocb_get_tsf_timer_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_OCB_CMD,
+	};
+
+	hdd_enter_dev(dev);
+
+	rc = wlan_hdd_validate_context(hdd_ctx);
+	if (rc)
+		return rc;
+
+	if (adapter->device_mode != QDF_OCB_MODE) {
+		hdd_err("Device not in OCB mode!");
+		return -EINVAL;
+	}
+
+	if (!wma_is_vdev_up(adapter->session_id)) {
+		hdd_err("The device has not been started");
+		return -EINVAL;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	tsf_request.vdev_id = adapter->session_id;
+	status = ucfg_ocb_get_tsf_timer(adapter->vdev, &tsf_request,
+					hdd_ocb_get_tsf_timer_callback,
+					cookie);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get tsf timer.");
+		rc = qdf_status_to_os_return(status);
+		goto end;
+	}
+
+	rc = osif_request_wait_for_response(request);
+	if (rc) {
+		hdd_err("Operation timed out");
+		goto end;
+	}
+
+	priv = osif_request_priv(request);
+	rc = priv->status;
+	if (rc) {
+		hdd_err("Operation failed: %d", rc);
+		goto end;
+	}
+
+	hdd_debug("Got TSF timer response, high=%d, low=%d",
+		priv->response.timer_high,
+		priv->response.timer_low);
+
+	/* Send the response. */
+	rc = hdd_ocb_get_tsf_timer_reply(wiphy, &priv->response);
+	if (rc) {
+		hdd_err("hdd_ocb_get_tsf_timer_reply failed: %d", rc);
+		goto end;
+	}
+
+	/* fall through */
+end:
+	osif_request_put(request);
+
+	return rc;
+}
+
+/**
+ * wlan_hdd_cfg80211_ocb_get_tsf_timer() - Interface for get TSF timer cmd
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+int wlan_hdd_cfg80211_ocb_get_tsf_timer(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_ocb_get_tsf_timer(wiphy, wdev,
+						    data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+struct hdd_dcc_stats_priv {
+	struct ocb_dcc_get_stats_response *response;
+	int status;
+};
+
+static void hdd_dcc_get_stats_dealloc(void *context_ptr)
+{
+	struct hdd_dcc_stats_priv *priv = context_ptr;
+
+	qdf_mem_free(priv->response);
+	priv->response = NULL;
+}
+
+/**
+ * hdd_dcc_get_stats_callback() - Callback to get stats command
+ * @context_ptr: request context
+ * @response_ptr: response data
+ */
+static void hdd_dcc_get_stats_callback(void *context_ptr, void *response_ptr)
+{
+	struct osif_request *request;
+	struct hdd_dcc_stats_priv *priv;
+	struct ocb_dcc_get_stats_response *response = response_ptr;
+	struct ocb_dcc_get_stats_response *hdd_resp;
+
+	request = osif_request_get(context_ptr);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+	if (!response) {
+		priv->status = -EINVAL;
+		goto end;
+	}
+
+	priv->response = qdf_mem_malloc(sizeof(*response) +
+					response->channel_stats_array_len);
+	if (!priv->response) {
+		priv->status = -ENOMEM;
+		goto end;
+	}
+
+	hdd_resp = priv->response;
+	*hdd_resp = *response;
+	hdd_resp->channel_stats_array = (void *)hdd_resp + sizeof(*hdd_resp);
+	qdf_mem_copy(hdd_resp->channel_stats_array,
+		     response->channel_stats_array,
+		     response->channel_stats_array_len);
+	priv->status = 0;
+
+end:
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+static int
+hdd_dcc_get_stats_send_reply(struct wiphy *wiphy,
+			     struct ocb_dcc_get_stats_response *response)
+{
+	uint32_t nl_buf_len;
+	struct sk_buff *nl_resp;
+	int rc;
+
+	/* Allocate the buffer for the response. */
+	nl_buf_len = NLMSG_HDRLEN;
+	nl_buf_len += NLA_HDRLEN + sizeof(uint32_t);
+	nl_buf_len += NLA_HDRLEN + response->channel_stats_array_len;
+	nl_resp = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, nl_buf_len);
+	if (!nl_resp) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	/* Populate the response. */
+	rc = nla_put_u32(nl_resp,
+			 QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_CHANNEL_COUNT,
+			 response->num_channels);
+	if (rc)
+		goto end;
+	rc = nla_put(nl_resp,
+		     QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_STATS_ARRAY,
+		     response->channel_stats_array_len,
+		     response->channel_stats_array);
+	if (rc)
+		goto end;
+
+	/* Send the response. */
+	rc = cfg80211_vendor_cmd_reply(nl_resp);
+	nl_resp = NULL;
+	if (rc) {
+		hdd_err("cfg80211_vendor_cmd_reply failed: %d", rc);
+		goto end;
+	}
+end:
+	if (nl_resp)
+		kfree_skb(nl_resp);
+
+	return rc;
+}
+
+/**
+ * __wlan_hdd_cfg80211_dcc_get_stats() - Interface for get dcc stats
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+static int __wlan_hdd_cfg80211_dcc_get_stats(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data,
+					     int data_len)
+{
+	uint32_t channel_count = 0;
+	uint32_t request_array_len = 0;
+	void *request_array = 0;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_MAX + 1];
+	int rc;
+	struct ocb_dcc_get_stats_param dcc_request = {0};
+	QDF_STATUS status;
+	void *cookie;
+	struct osif_request *request;
+	struct hdd_dcc_stats_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_OCB_CMD,
+		.dealloc = hdd_dcc_get_stats_dealloc,
+	};
+
+	hdd_enter_dev(dev);
+
+	rc = wlan_hdd_validate_context(hdd_ctx);
+	if (rc)
+		return rc;
+
+	if (adapter->device_mode != QDF_OCB_MODE) {
+		hdd_err("Device not in OCB mode!");
+		return -EINVAL;
+	}
+
+	if (!wma_is_vdev_up(adapter->session_id)) {
+		hdd_err("The device has not been started");
+		return -EINVAL;
+	}
+
+	/* Parse the netlink message */
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_MAX,
+				    data, data_len,
+				    qca_wlan_vendor_dcc_get_stats)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Validate all the parameters are present */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_CHANNEL_COUNT] ||
+	    !tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY]) {
+		hdd_err("Parameters are not present.");
+		return -EINVAL;
+	}
+
+	channel_count = nla_get_u32(
+		tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_CHANNEL_COUNT]);
+	request_array_len = nla_len(
+		tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY]);
+	request_array = nla_data(
+		tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY]);
+
+	/* Check channel count. Per 11p spec, max 2 channels allowed */
+	if (!channel_count || channel_count > CFG_TGT_NUM_OCB_CHANNELS) {
+		hdd_err("Invalid channel_count %d", channel_count);
+		return -EINVAL;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	dcc_request.vdev_id = adapter->session_id;
+	dcc_request.channel_count = channel_count;
+	dcc_request.request_array_len = request_array_len;
+	dcc_request.request_array = request_array;
+
+	status = ucfg_ocb_dcc_get_stats(adapter->vdev, &dcc_request,
+					hdd_dcc_get_stats_callback,
+					cookie);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get DCC stats.");
+		rc = qdf_status_to_os_return(status);
+		goto end;
+	}
+
+	/* Wait for the function to complete. */
+	rc = osif_request_wait_for_response(request);
+	if (rc) {
+		hdd_err("Operation timed out");
+		goto end;
+	}
+
+	priv = osif_request_priv(request);
+	rc = priv->status;
+	if (rc) {
+		hdd_err("Operation failed: %d", rc);
+		goto end;
+	}
+
+	/* Send the response. */
+	rc = hdd_dcc_get_stats_send_reply(wiphy, priv->response);
+	if (rc) {
+		hdd_err("hdd_dcc_get_stats_send_reply failed: %d", rc);
+		goto end;
+	}
+
+	/* fall through */
+end:
+	osif_request_put(request);
+
+	return rc;
+}
+
+/**
+ * wlan_hdd_cfg80211_dcc_get_stats() - Interface for get dcc stats
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+int wlan_hdd_cfg80211_dcc_get_stats(struct wiphy *wiphy,
+				    struct wireless_dev *wdev,
+				    const void *data,
+				    int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_dcc_get_stats(wiphy, wdev,
+						data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_dcc_clear_stats() - Interface for clear dcc stats cmd
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+static int __wlan_hdd_cfg80211_dcc_clear_stats(struct wiphy *wiphy,
+					       struct wireless_dev *wdev,
+					       const void *data,
+					       int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_MAX + 1];
+
+	hdd_enter_dev(dev);
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	if (adapter->device_mode != QDF_OCB_MODE) {
+		hdd_err("Device not in OCB mode!");
+		return -EINVAL;
+	}
+
+	if (!wma_is_vdev_up(adapter->session_id)) {
+		hdd_err("The device has not been started");
+		return -EINVAL;
+	}
+
+	/* Parse the netlink message */
+	if (wlan_cfg80211_nla_parse(tb,
+				    QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_MAX,
+				    data, data_len,
+				    qca_wlan_vendor_dcc_clear_stats)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Verify that the parameter is present */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_BITMAP]) {
+		hdd_err("Parameters are not present.");
+		return -EINVAL;
+	}
+
+	if (ucfg_ocb_dcc_clear_stats(adapter->vdev, adapter->session_id,
+		nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_BITMAP])) !=
+			QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to clear DCC stats.");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_dcc_clear_stats() - Interface for clear dcc stats cmd
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+int wlan_hdd_cfg80211_dcc_clear_stats(struct wiphy *wiphy,
+				      struct wireless_dev *wdev,
+				      const void *data,
+				      int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_dcc_clear_stats(wiphy, wdev,
+						  data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+struct hdd_dcc_update_ndl_priv {
+	int status;
+};
+
+/**
+ * hdd_dcc_update_ndl_callback() - Callback to update NDL command
+ * @context_ptr: request context
+ * @response_ptr: response data
+ */
+static void hdd_dcc_update_ndl_callback(void *context_ptr, void *response_ptr)
+{
+	struct osif_request *request;
+	struct hdd_dcc_update_ndl_priv *priv;
+	struct ocb_dcc_update_ndl_response *response = response_ptr;
+
+	request = osif_request_get(context_ptr);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+	if (response && (0 == response->status))
+		priv->status = 0;
+	else
+		priv->status = -EINVAL;
+
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+/**
+ * __wlan_hdd_cfg80211_dcc_update_ndl() - Interface for update dcc cmd
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+static int __wlan_hdd_cfg80211_dcc_update_ndl(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      const void *data,
+					      int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_MAX + 1];
+	struct ocb_dcc_update_ndl_param dcc_request;
+	uint32_t channel_count;
+	uint32_t ndl_channel_array_len;
+	void *ndl_channel_array;
+	uint32_t ndl_active_state_array_len;
+	void *ndl_active_state_array;
+	int rc;
+	QDF_STATUS status;
+	void *cookie;
+	struct osif_request *request;
+	struct hdd_dcc_update_ndl_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_OCB_CMD,
+	};
+
+	hdd_enter_dev(dev);
+
+	rc = wlan_hdd_validate_context(hdd_ctx);
+	if (rc)
+		return rc;
+
+	if (adapter->device_mode != QDF_OCB_MODE) {
+		hdd_err("Device not in OCB mode!");
+		return -EINVAL;
+	}
+
+	if (!wma_is_vdev_up(adapter->session_id)) {
+		hdd_err("The device has not been started");
+		return -EINVAL;
+	}
+
+	/* Parse the netlink message */
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_MAX,
+				    data, data_len,
+				    qca_wlan_vendor_dcc_update_ndl)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Verify that the parameter is present */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_COUNT] ||
+	    !tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_ARRAY] ||
+	    !tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_ACTIVE_STATE_ARRAY]) {
+		hdd_err("Parameters are not present.");
+		return -EINVAL;
+	}
+
+	channel_count = nla_get_u32(
+		tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_COUNT]);
+	ndl_channel_array_len = nla_len(
+		tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_ARRAY]);
+	ndl_channel_array = nla_data(
+		tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_ARRAY]);
+	ndl_active_state_array_len = nla_len(
+		tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_ACTIVE_STATE_ARRAY]);
+	ndl_active_state_array = nla_data(
+		tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_ACTIVE_STATE_ARRAY]);
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	/* Copy the parameters to the request structure. */
+	dcc_request.vdev_id = adapter->session_id;
+	dcc_request.channel_count = channel_count;
+	dcc_request.dcc_ndl_chan_list_len = ndl_channel_array_len;
+	dcc_request.dcc_ndl_chan_list = ndl_channel_array;
+	dcc_request.dcc_ndl_active_state_list_len = ndl_active_state_array_len;
+	dcc_request.dcc_ndl_active_state_list = ndl_active_state_array;
+
+	status = ucfg_ocb_dcc_update_ndl(adapter->vdev, &dcc_request,
+					 hdd_dcc_update_ndl_callback,
+					 cookie);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to update NDL.");
+		rc = qdf_status_to_os_return(status);
+		goto end;
+	}
+
+	/* Wait for the function to complete. */
+	rc = osif_request_wait_for_response(request);
+	if (rc) {
+		hdd_err("Operation timed out");
+		goto end;
+	}
+
+	priv = osif_request_priv(request);
+	rc = priv->status;
+	if (rc) {
+		hdd_err("Operation failed: %d", rc);
+		goto end;
+	}
+
+	/* fall through */
+end:
+	osif_request_put(request);
+
+	return rc;
+}
+
+/**
+ * wlan_hdd_cfg80211_dcc_update_ndl() - Interface for update dcc cmd
+ * @wiphy: pointer to the wiphy
+ * @wdev: pointer to the wdev
+ * @data: The netlink data
+ * @data_len: The length of the netlink data in bytes
+ *
+ * Return: 0 on success.
+ */
+int wlan_hdd_cfg80211_dcc_update_ndl(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     const void *data,
+				     int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_dcc_update_ndl(wiphy, wdev,
+						 data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_dcc_stats_event_callback() - Callback to get stats event
+ * @context_ptr: request context
+ * @response_ptr: response data
+ */
+static void wlan_hdd_dcc_stats_event_callback(void *context_ptr,
+					      void *response_ptr)
+{
+	struct hdd_context *hdd_ctx = (struct hdd_context *)context_ptr;
+	struct ocb_dcc_get_stats_response *resp = response_ptr;
+	struct sk_buff *vendor_event;
+
+	hdd_enter();
+
+	vendor_event =
+		cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+			NULL, sizeof(uint32_t) + resp->channel_stats_array_len +
+			NLMSG_HDRLEN,
+			QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT_INDEX,
+			GFP_KERNEL);
+
+	if (!vendor_event) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_CHANNEL_COUNT,
+			resp->num_channels) ||
+		nla_put(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_STATS_ARRAY,
+			resp->channel_stats_array_len,
+			resp->channel_stats_array)) {
+		hdd_err("nla put failed");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+}
+
+/**
+ * wlan_hdd_dcc_register_for_dcc_stats_event() - Register for dcc stats events
+ * @hdd_ctx: hdd context
+ */
+void wlan_hdd_dcc_register_for_dcc_stats_event(struct hdd_context *hdd_ctx)
+{
+	int rc;
+
+	rc = ucfg_ocb_register_for_dcc_stats_event(hdd_ctx->pdev, hdd_ctx,
+				      wlan_hdd_dcc_stats_event_callback);
+	if (rc)
+		hdd_err("Register DCC stats callback failed: %d", rc);
+}
diff --git a/core/hdd/src/wlan_hdd_ocb.h b/core/hdd/src/wlan_hdd_ocb.h
new file mode 100644
index 0000000..2e13a53
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_ocb.h
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2015-2018 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.
+ */
+
+#ifndef __WLAN_HDD_OCB_H
+#define __WLAN_HDD_OCB_H
+
+#include <net/iw_handler.h>
+#include "sir_api.h"
+
+#define WLAN_OCB_CHANNEL_MAX 5
+
+/**
+ * struct ocb_qos_params - QoS Parameters for each AC
+ * @aifsn:  Arbitration Inter-Frame Spacing
+ * @cwmin:  Contention Window (Min)
+ * @cwmax:  Contention Window (Max)
+ */
+struct ocb_qos_params {
+	uint8_t aifsn;
+	uint8_t cwmin;
+	uint8_t cwmax;
+};
+
+/**
+ * struct ocb_channel - Parameters for each OCB channel
+ * @channel_freq:           Channel Center Frequency (MHz)
+ * @duration:               Channel Duration (ms)
+ * @start_guard_interval:   Start Guard Interval (ms)
+ * @channel_bandwidth:      Channel Bandwidth (MHz)
+ * @tx_power:               Transmit Power (1/2 dBm)
+ * @tx_rate:                Transmit Data Rate (mbit)
+ * @qos_params:             Array of QoS Parameters
+ * @per_packet_rx_stats:    Enable per packet RX statistics
+ */
+struct ocb_channel {
+	uint32_t channel_freq;
+	uint32_t duration;
+	uint32_t start_guard_interval;
+	uint32_t channel_bandwidth;
+	uint32_t tx_power;
+	uint32_t tx_rate;
+	struct ocb_qos_params qos_params[MAX_NUM_AC];
+	uint32_t per_packet_rx_stats;
+};
+
+/**
+ * struct dot11p_channel_sched - OCB channel schedule
+ * @num_channels:   Number of channels
+ * @channels:       Array of channel parameters
+ * @off_channel_tx: Enable off channel TX
+ */
+struct dot11p_channel_sched {
+	uint32_t num_channels;
+	struct ocb_channel channels[WLAN_OCB_CHANNEL_MAX];
+	uint32_t off_channel_tx;
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ocb_set_config - vendor subcmd to set ocb config
+ * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT:
+ *	number of channels in the configuration
+ * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE: size of the schedule
+ * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_ARRAY: array of channels
+ * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_ARRAY:
+ *	array of channels to be scheduled
+ * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY:
+ *	array of NDL channel information
+ * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY:
+ *	array of NDL active state configuration
+ * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS:
+ *	flag to set the absolute expiry
+ */
+enum qca_wlan_vendor_attr_ocb_set_config {
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_ARRAY,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_ARRAY,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_MAX =
+		QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ocb_set_utc_time - vendor subcmd to set UTC time
+ * @QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_VALUE:
+ *	the UTC time as an array of 10 bytes
+ * @QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_ERROR:
+ *	the time error as an array of 5 bytes
+ */
+enum qca_wlan_vendor_attr_ocb_set_utc_time {
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_VALUE,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_ERROR,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_MAX =
+		QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ocb_start_timing_advert - vendor subcmd to start
+						       sending timing advert
+						       frames
+ * @QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ:
+ *	channel frequency on which to send the frames
+ * @QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE:
+ *	number of times the frame is sent in 5 seconds
+ */
+enum qca_wlan_vendor_attr_ocb_start_timing_advert {
+	QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ,
+	QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE,
+	QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_MAX =
+		QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ocb_stop_timing_advert - vendor subcmd to stop
+ *						      timing advert
+ * @QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ:
+ *	the channel frequency on which to stop the timing advert
+ */
+enum qca_wlan_vendor_attr_ocb_stop_timing_advert {
+	QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ,
+	QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_MAX =
+		QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_dcc_get_tsf_response - vendor subcmd to get TSF
+ *						    timer value
+ * @QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_HIGH:
+ *      higher 32 bits of the timer
+ * @QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_LOW:
+ *      lower 32 bits of the timer
+ */
+enum qca_wlan_vendor_attr_ocb_get_tsf_resp {
+	QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_HIGH,
+	QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_LOW,
+	QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_MAX =
+		QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_dcc_get_stats - vendor subcmd to get
+ *					     dcc stats
+ * @QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_CHANNEL_COUNT:
+ *      the number of channels in the request array
+ * @QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY
+ *      array of the channel and information being requested
+ */
+enum qca_wlan_vendor_attr_dcc_get_stats {
+	QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_CHANNEL_COUNT,
+	QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY,
+	QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_MAX =
+		QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_dcc_get_stats_resp - response event from get
+ *						  dcc stats
+ * @QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_CHANNEL_COUNT:
+ *      the number of channels in the request array
+ * @QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_STATS_ARRAY
+ *      array of the information being requested
+ */
+enum qca_wlan_vendor_attr_dcc_get_stats_resp {
+	QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_CHANNEL_COUNT,
+	QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_STATS_ARRAY,
+	QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_MAX =
+		QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_RESP_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_dcc_clear_stats - vendor subcmd to clear DCC stats
+ * @QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_BITMAP:
+ *      mask of the type of stats to be cleared
+ */
+enum qca_wlan_vendor_attr_dcc_clear_stats {
+	QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_BITMAP,
+	QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_MAX =
+		QCA_WLAN_VENDOR_ATTR_DCC_CLEAR_STATS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ocb_set_config - vendor subcmd to update dcc
+ * @QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_COUNT:
+ *	number of channels in the configuration
+ * @QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_ARRAY: the array of NDL
+ *  channel info
+ * @QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_ACTIVE_STATE_ARRAY: the array of
+ *  NDL active states
+ */
+enum qca_wlan_vendor_attr_dcc_update_ndl {
+	QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_COUNT,
+	QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_CHANNEL_ARRAY,
+	QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_ACTIVE_STATE_ARRAY,
+	QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_MAX =
+		QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_AFTER_LAST - 1,
+};
+
+struct hdd_context;
+
+#ifdef WLAN_WEXT_SUPPORT_ENABLE
+
+#ifdef WLAN_FEATURE_DSRC
+int iw_set_dot11p_channel_sched(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra);
+#else
+static inline
+int iw_set_dot11p_channel_sched(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	return 0;
+}
+#endif
+#endif
+
+#ifdef WLAN_FEATURE_DSRC
+int wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     const void *data,
+				     int data_len);
+
+int wlan_hdd_cfg80211_ocb_set_utc_time(struct wiphy *wiphy,
+				       struct wireless_dev *wdev,
+				       const void *data,
+				       int data_len);
+
+int wlan_hdd_cfg80211_ocb_start_timing_advert(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      const void *data,
+					      int data_len);
+
+int wlan_hdd_cfg80211_ocb_stop_timing_advert(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data,
+					     int data_len);
+
+int wlan_hdd_cfg80211_ocb_get_tsf_timer(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len);
+
+int wlan_hdd_cfg80211_dcc_get_stats(struct wiphy *wiphy,
+				    struct wireless_dev *wdev,
+				    const void *data,
+				    int data_len);
+
+int wlan_hdd_cfg80211_dcc_clear_stats(struct wiphy *wiphy,
+				      struct wireless_dev *wdev,
+				      const void *data,
+				      int data_len);
+
+int wlan_hdd_cfg80211_dcc_update_ndl(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     const void *data,
+				     int data_len);
+
+void wlan_hdd_dcc_register_for_dcc_stats_event(struct hdd_context *hdd_ctx);
+
+void wlan_hdd_dcc_stats_event(void *context_ptr, void *response_ptr);
+#else
+static inline int wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	return 0;
+}
+
+static inline int wlan_hdd_cfg80211_ocb_set_utc_time(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	return 0;
+}
+
+static inline int wlan_hdd_cfg80211_ocb_start_timing_advert(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	return 0;
+}
+
+static inline int wlan_hdd_cfg80211_ocb_stop_timing_advert(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	return 0;
+}
+
+static inline int wlan_hdd_cfg80211_ocb_get_tsf_timer(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	return 0;
+}
+
+static inline int wlan_hdd_cfg80211_dcc_get_stats(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	return 0;
+}
+
+static inline int wlan_hdd_cfg80211_dcc_clear_stats(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	return 0;
+}
+
+static inline int wlan_hdd_cfg80211_dcc_update_ndl(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	return 0;
+}
+
+static inline void wlan_hdd_dcc_register_for_dcc_stats_event(
+		struct hdd_context *hdd_ctx)
+{
+}
+
+static inline void wlan_hdd_dcc_stats_event(void *context_ptr,
+		void *response_ptr)
+{
+}
+#endif
+
+#endif /* __WLAN_HDD_OCB_H */
diff --git a/core/hdd/src/wlan_hdd_oemdata.c b/core/hdd/src/wlan_hdd_oemdata.c
new file mode 100644
index 0000000..367eab3
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_oemdata.c
@@ -0,0 +1,1137 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
+/**
+ *  DOC: wlan_hdd_oemdata.c
+ *
+ *  Support for generic OEM Data Request handling
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/wireless.h>
+#include <wlan_hdd_includes.h>
+#include <net/arp.h>
+#include "qwlan_version.h"
+#include "cds_utils.h"
+#include "wma.h"
+#include "sme_api.h"
+#include "wlan_nlink_srv.h"
+
+#ifdef CNSS_GENL
+#include <net/cnss_nl.h>
+#endif
+
+static struct hdd_context *p_hdd_ctx;
+
+/**
+ * populate_oem_data_cap() - populate oem capabilities
+ * @adapter: device adapter
+ * @data_cap: pointer to populate the capabilities
+ *
+ * Return: error code
+ */
+static int populate_oem_data_cap(struct hdd_adapter *adapter,
+				 struct oem_data_cap *data_cap)
+{
+	QDF_STATUS status;
+	struct hdd_config *config;
+	uint32_t num_chan;
+	uint8_t *chan_list;
+	uint8_t band_capability;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	config = hdd_ctx->config;
+	if (!config) {
+		hdd_err("HDD configuration is null");
+		return -EINVAL;
+	}
+
+	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get MLME band capability");
+		return -EIO;
+	}
+
+	chan_list = qdf_mem_malloc(sizeof(uint8_t) * OEM_CAP_MAX_NUM_CHANNELS);
+	if (NULL == chan_list) {
+		hdd_err("Memory allocation failed");
+		return -ENOMEM;
+	}
+
+	strlcpy(data_cap->oem_target_signature, OEM_TARGET_SIGNATURE,
+		OEM_TARGET_SIGNATURE_LEN);
+	data_cap->oem_target_type = hdd_ctx->target_type;
+	data_cap->oem_fw_version = hdd_ctx->target_fw_version;
+	data_cap->driver_version.major = QWLAN_VERSION_MAJOR;
+	data_cap->driver_version.minor = QWLAN_VERSION_MINOR;
+	data_cap->driver_version.patch = QWLAN_VERSION_PATCH;
+	data_cap->driver_version.build = QWLAN_VERSION_BUILD;
+	data_cap->allowed_dwell_time_min = config->nNeighborScanMinChanTime;
+	data_cap->allowed_dwell_time_max = config->nNeighborScanMaxChanTime;
+	data_cap->curr_dwell_time_min =
+		sme_get_neighbor_scan_min_chan_time(hdd_ctx->mac_handle,
+						    adapter->session_id);
+	data_cap->curr_dwell_time_max =
+		sme_get_neighbor_scan_max_chan_time(hdd_ctx->mac_handle,
+						    adapter->session_id);
+	data_cap->supported_bands = band_capability;
+
+	/* request for max num of channels */
+	num_chan = OEM_CAP_MAX_NUM_CHANNELS;
+	status = sme_get_cfg_valid_channels(
+					    &chan_list[0], &num_chan);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("failed to get valid channel list, status: %d", status);
+		qdf_mem_free(chan_list);
+		return -EINVAL;
+	}
+
+	/* make sure num channels is not more than chan list array */
+	if (num_chan > OEM_CAP_MAX_NUM_CHANNELS) {
+		hdd_err("Num of channels-%d > length-%d of chan_list",
+			num_chan, OEM_CAP_MAX_NUM_CHANNELS);
+		qdf_mem_free(chan_list);
+		return -ENOMEM;
+	}
+
+	data_cap->num_channels = num_chan;
+	qdf_mem_copy(data_cap->channel_list, chan_list,
+		     sizeof(uint8_t) * num_chan);
+
+	qdf_mem_free(chan_list);
+	return 0;
+}
+
+/**
+ * iw_get_oem_data_cap() - Get OEM Data Capabilities
+ * @dev: net device upon which the request was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl data payload
+ *
+ * This function gets the capability information for OEM Data Request
+ * and Response.
+ *
+ * Return: 0 for success, negative errno value on failure
+ */
+int iw_get_oem_data_cap(struct net_device *dev,
+			struct iw_request_info *info,
+			union iwreq_data *wrqu, char *extra)
+{
+	int status;
+	struct oem_data_cap oemDataCap = { {0} };
+	struct oem_data_cap *pHddOemDataCap;
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	struct hdd_context *pHddContext;
+	int ret;
+
+	hdd_enter();
+
+	pHddContext = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(pHddContext);
+	if (0 != ret)
+		return ret;
+
+	status = populate_oem_data_cap(adapter, &oemDataCap);
+	if (0 != status) {
+		hdd_err("Failed to populate oem data capabilities");
+		return status;
+	}
+
+	pHddOemDataCap = (struct oem_data_cap *) (extra);
+	*pHddOemDataCap = oemDataCap;
+
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * send_oem_reg_rsp_nlink_msg() - send oem registration response
+ *
+ * This function sends oem message to registered application process
+ *
+ * Return:  none
+ */
+static void send_oem_reg_rsp_nlink_msg(void)
+{
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	tAniMsgHdr *aniHdr;
+	uint8_t *buf;
+	uint8_t *numInterfaces;
+	uint8_t *deviceMode;
+	uint8_t *vdevId;
+	struct hdd_adapter *adapter;
+
+	/* OEM msg is always to a specific process & cannot be a broadcast */
+	if (p_hdd_ctx->oem_pid == 0) {
+		hdd_err("invalid dest pid");
+		return;
+	}
+
+	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
+	if (skb == NULL)
+		return;
+
+	nlh = (struct nlmsghdr *)skb->data;
+	nlh->nlmsg_pid = 0;     /* from kernel */
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_seq = 0;
+	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
+	aniHdr = NLMSG_DATA(nlh);
+	aniHdr->type = ANI_MSG_APP_REG_RSP;
+
+	/* Fill message body:
+	 *   First byte will be number of interfaces, followed by
+	 *   two bytes for each interfaces
+	 *     - one byte for device mode
+	 *     - one byte for vdev id
+	 */
+	buf = (char *)((char *)aniHdr + sizeof(tAniMsgHdr));
+	numInterfaces = buf++;
+	*numInterfaces = 0;
+
+	/* Iterate through each adapter and fill device mode and vdev id */
+	hdd_for_each_adapter(p_hdd_ctx, adapter) {
+		deviceMode = buf++;
+		vdevId = buf++;
+		*deviceMode = adapter->device_mode;
+		*vdevId = adapter->session_id;
+		(*numInterfaces)++;
+		hdd_debug("numInterfaces: %d, deviceMode: %d, vdevId: %d",
+			  *numInterfaces, *deviceMode,
+			  *vdevId);
+	}
+
+	aniHdr->length =
+		sizeof(uint8_t) + (*numInterfaces) * 2 * sizeof(uint8_t);
+	nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length));
+
+	skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length)));
+
+	hdd_debug("sending App Reg Response length: %d to pid: %d",
+		   aniHdr->length, p_hdd_ctx->oem_pid);
+
+	(void)nl_srv_ucast_oem(skb, p_hdd_ctx->oem_pid, MSG_DONTWAIT);
+}
+
+/**
+ * send_oem_err_rsp_nlink_msg() - send oem error response
+ * @app_pid: PID of oem application process
+ * @error_code: response error code
+ *
+ * This function sends error response to oem app
+ *
+ * Return: none
+ */
+static void send_oem_err_rsp_nlink_msg(int32_t app_pid, uint8_t error_code)
+{
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	tAniMsgHdr *aniHdr;
+	uint8_t *buf;
+
+	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
+	if (skb == NULL)
+		return;
+
+	nlh = (struct nlmsghdr *)skb->data;
+	nlh->nlmsg_pid = 0;     /* from kernel */
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_seq = 0;
+	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
+	aniHdr = NLMSG_DATA(nlh);
+	aniHdr->type = ANI_MSG_OEM_ERROR;
+	aniHdr->length = sizeof(uint8_t);
+	nlh->nlmsg_len = NLMSG_LENGTH(sizeof(tAniMsgHdr) + aniHdr->length);
+
+	/* message body will contain one byte of error code */
+	buf = (char *)((char *)aniHdr + sizeof(tAniMsgHdr));
+	*buf = error_code;
+
+	skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + aniHdr->length));
+
+	hdd_debug("sending oem error response to pid: %d", app_pid);
+
+	(void)nl_srv_ucast_oem(skb, app_pid, MSG_DONTWAIT);
+}
+
+/**
+ * hdd_send_oem_data_rsp_msg() - send oem data response
+ * @oem_data_rsp: the actual OEM Data Response message
+ *
+ * This function sends an OEM Data Response message to a registered
+ * application process over the netlink socket.
+ *
+ * Return: 0 for success, non zero for failure
+ */
+void hdd_send_oem_data_rsp_msg(struct oem_data_rsp *oem_data_rsp)
+{
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	tAniMsgHdr *ani_hdr;
+	uint8_t *oem_data;
+
+	/*
+	 * OEM message is always to a specific process and cannot be a broadcast
+	 */
+	if (p_hdd_ctx->oem_pid == 0) {
+		hdd_err("invalid dest pid");
+		return;
+	}
+
+	if (oem_data_rsp->rsp_len > OEM_DATA_RSP_SIZE) {
+		hdd_err("invalid length of Oem Data response");
+		return;
+	}
+
+	skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + OEM_DATA_RSP_SIZE),
+			GFP_KERNEL);
+	if (skb == NULL)
+		return;
+
+	nlh = (struct nlmsghdr *)skb->data;
+	nlh->nlmsg_pid = 0;     /* from kernel */
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_seq = 0;
+	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
+	ani_hdr = NLMSG_DATA(nlh);
+	ani_hdr->type = ANI_MSG_OEM_DATA_RSP;
+
+	ani_hdr->length = oem_data_rsp->rsp_len;
+	nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + ani_hdr->length));
+	oem_data = (uint8_t *) ((char *)ani_hdr + sizeof(tAniMsgHdr));
+	qdf_mem_copy(oem_data, oem_data_rsp->data, oem_data_rsp->rsp_len);
+
+	skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + ani_hdr->length)));
+
+	hdd_debug("sending Oem Data Response of len : %d to pid: %d",
+		   oem_data_rsp->rsp_len, p_hdd_ctx->oem_pid);
+
+	(void)nl_srv_ucast_oem(skb, p_hdd_ctx->oem_pid, MSG_DONTWAIT);
+}
+
+/**
+ * oem_process_data_req_msg() - process oem data request
+ * @oem_data_len: Length to OEM Data buffer
+ * @oem_data: Pointer to OEM Data buffer
+ *
+ * This function sends oem message to SME
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS oem_process_data_req_msg(int oem_data_len, char *oem_data)
+{
+	struct oem_data_req oem_data_req;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	/* for now, STA interface only */
+	if (!hdd_get_adapter(p_hdd_ctx, QDF_STA_MODE) &&
+	    !hdd_get_adapter(p_hdd_ctx, QDF_SAP_MODE)) {
+		hdd_err("No adapter for STA or SAP mode");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!oem_data) {
+		hdd_err("oem_data is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_zero(&oem_data_req, sizeof(oem_data_req));
+
+	oem_data_req.data = qdf_mem_malloc(oem_data_len);
+	if (!oem_data_req.data) {
+		hdd_err("malloc failed for data req buffer");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	oem_data_req.data_len = oem_data_len;
+	qdf_mem_copy(oem_data_req.data, oem_data, oem_data_len);
+
+	status = sme_oem_data_req(p_hdd_ctx->mac_handle, &oem_data_req);
+
+	qdf_mem_free(oem_data_req.data);
+	oem_data_req.data = NULL;
+
+	return status;
+}
+
+/**
+ * update_channel_bw_info() - set bandwidth info for the chan
+ * @hdd_ctx: hdd context
+ * @chan: channel for which info are required
+ * @chan_info: struct where the bandwidth info is filled
+ *
+ * This function find the maximum bandwidth allowed, secondary
+ * channel offset and center freq for the channel as per regulatory
+ * domain and using these info calculate the phy mode for the
+ * channel.
+ *
+ * Return: void
+ */
+void hdd_update_channel_bw_info(struct hdd_context *hdd_ctx,
+				uint16_t chan, void *chan_info)
+{
+	struct ch_params ch_params = {0};
+	uint16_t sec_ch_2g = 0;
+	WLAN_PHY_MODE phy_mode;
+	uint32_t wni_dot11_mode;
+	tHddChannelInfo *hdd_chan_info = chan_info;
+
+	wni_dot11_mode = sme_get_wni_dot11_mode(hdd_ctx->mac_handle);
+
+	/* Passing CH_WIDTH_MAX will give the max bandwidth supported */
+	ch_params.ch_width = CH_WIDTH_MAX;
+
+	wlan_reg_set_channel_params(hdd_ctx->pdev, chan, sec_ch_2g, &ch_params);
+	if (ch_params.center_freq_seg0)
+		hdd_chan_info->band_center_freq1 =
+			cds_chan_to_freq(ch_params.center_freq_seg0);
+
+	if (ch_params.ch_width < CH_WIDTH_INVALID)
+		phy_mode = wma_chan_phy_mode(chan, ch_params.ch_width,
+					     wni_dot11_mode);
+	else
+		/*
+		 * If channel width is CH_WIDTH_INVALID, It mean channel is
+		 * invalid and should not have been received in channel info
+		 * req. Set invalid phymode in this case.
+		 */
+		phy_mode = MODE_UNKNOWN;
+
+	hdd_debug("chan %d dot11_mode %d ch_width %d sec offset %d freq_seg0 %d phy_mode %d",
+		chan, wni_dot11_mode, ch_params.ch_width,
+		ch_params.sec_ch_offset,
+		hdd_chan_info->band_center_freq1, phy_mode);
+
+	WMI_SET_CHANNEL_MODE(hdd_chan_info, phy_mode);
+}
+
+/**
+ * oem_process_channel_info_req_msg() - process oem channel_info request
+ * @numOfChannels: number of channels
+ * @chanList: list of channel information
+ *
+ * This function responds with channel info to oem process
+ *
+ * Return: 0 for success, non zero for failure
+ */
+static int oem_process_channel_info_req_msg(int numOfChannels, char *chanList)
+{
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	tAniMsgHdr *aniHdr;
+	struct hdd_channel_info *pHddChanInfo;
+	struct hdd_channel_info hddChanInfo;
+	uint8_t chanId;
+	uint32_t reg_info_1;
+	uint32_t reg_info_2;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	int i;
+	uint8_t *buf;
+
+	/* OEM msg is always to a specific process and cannot be a broadcast */
+	if (p_hdd_ctx->oem_pid == 0) {
+		hdd_err("invalid dest pid");
+		return -EPERM;
+	}
+
+	skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + sizeof(uint8_t) +
+				    numOfChannels * sizeof(*pHddChanInfo)),
+			GFP_KERNEL);
+	if (skb == NULL)
+		return -ENOMEM;
+
+	nlh = (struct nlmsghdr *)skb->data;
+	nlh->nlmsg_pid = 0;     /* from kernel */
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_seq = 0;
+	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
+	aniHdr = NLMSG_DATA(nlh);
+	aniHdr->type = ANI_MSG_CHANNEL_INFO_RSP;
+
+	aniHdr->length =
+		sizeof(uint8_t) + numOfChannels * sizeof(*pHddChanInfo);
+	nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length));
+
+	/* First byte of message body will have num of channels */
+	buf = (char *)((char *)aniHdr + sizeof(tAniMsgHdr));
+	*buf++ = numOfChannels;
+
+	/* Next follows channel info struct for each channel id.
+	 * If chan id is wrong or SME returns failure for a channel
+	 * then fill in 0 in channel info for that particular channel
+	 */
+	for (i = 0; i < numOfChannels; i++) {
+		pHddChanInfo = (struct hdd_channel_info *) ((char *)buf +
+						    i *
+						    sizeof(*pHddChanInfo));
+
+		chanId = chanList[i];
+		status = sme_get_reg_info(p_hdd_ctx->mac_handle, chanId,
+					  &reg_info_1, &reg_info_2);
+		if (QDF_STATUS_SUCCESS == status) {
+			/* copy into hdd chan info struct */
+			hddChanInfo.chan_id = chanId;
+			hddChanInfo.reserved0 = 0;
+			hddChanInfo.mhz = cds_chan_to_freq(chanId);
+			hddChanInfo.band_center_freq1 = hddChanInfo.mhz;
+			hddChanInfo.band_center_freq2 = 0;
+
+			hddChanInfo.info = 0;
+			if (CHANNEL_STATE_DFS ==
+			    wlan_reg_get_channel_state(p_hdd_ctx->pdev, chanId))
+				WMI_SET_CHANNEL_FLAG(&hddChanInfo,
+						     WMI_CHAN_FLAG_DFS);
+
+			hdd_update_channel_bw_info(p_hdd_ctx,
+						chanId, &hddChanInfo);
+			hddChanInfo.reg_info_1 = reg_info_1;
+			hddChanInfo.reg_info_2 = reg_info_2;
+		} else {
+			/* channel info is not returned, fill in zeros in
+			 * channel info struct
+			 */
+			hdd_debug("sme_get_reg_info failed for chan: %d, fill 0s",
+				   chanId);
+			hddChanInfo.chan_id = chanId;
+			hddChanInfo.reserved0 = 0;
+			hddChanInfo.mhz = 0;
+			hddChanInfo.band_center_freq1 = 0;
+			hddChanInfo.band_center_freq2 = 0;
+			hddChanInfo.info = 0;
+			hddChanInfo.reg_info_1 = 0;
+			hddChanInfo.reg_info_2 = 0;
+		}
+		qdf_mem_copy(pHddChanInfo, &hddChanInfo,
+			     sizeof(*pHddChanInfo));
+	}
+
+	skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length)));
+
+	hdd_debug("sending channel info resp for num channels (%d) to pid (%d)",
+		   numOfChannels, p_hdd_ctx->oem_pid);
+
+	(void)nl_srv_ucast_oem(skb, p_hdd_ctx->oem_pid, MSG_DONTWAIT);
+
+	return 0;
+}
+
+/**
+ * oem_process_set_cap_req_msg() - process oem set capability request
+ * @oem_cap_len: Length of OEM capability
+ * @oem_cap: Pointer to OEM capability buffer
+ * @app_pid: process ID, to which rsp message is to be sent
+ *
+ * This function sends oem message to SME
+ *
+ * Return: error code
+ */
+static int oem_process_set_cap_req_msg(int oem_cap_len,
+				       char *oem_cap, int32_t app_pid)
+{
+	QDF_STATUS status;
+	int error_code;
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	tAniMsgHdr *ani_hdr;
+	uint8_t *buf;
+
+	if (!oem_cap) {
+		hdd_err("oem_cap is null");
+		return -EINVAL;
+	}
+
+	status = sme_oem_update_capability(p_hdd_ctx->mac_handle,
+					(struct sme_oem_capability *)oem_cap);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("error updating rm capability, status: %d", status);
+	error_code = qdf_status_to_os_return(status);
+
+	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
+	if (skb == NULL)
+		return -ENOMEM;
+
+	nlh = (struct nlmsghdr *)skb->data;
+	nlh->nlmsg_pid = 0;     /* from kernel */
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_seq = 0;
+	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
+	ani_hdr = NLMSG_DATA(nlh);
+	ani_hdr->type = ANI_MSG_SET_OEM_CAP_RSP;
+	/* 64 bit alignment */
+	ani_hdr->length = sizeof(error_code);
+	nlh->nlmsg_len = NLMSG_LENGTH(sizeof(tAniMsgHdr) + ani_hdr->length);
+
+	/* message body will contain only status code */
+	buf = (char *)((char *)ani_hdr + sizeof(tAniMsgHdr));
+	qdf_mem_copy(buf, &error_code, ani_hdr->length);
+
+	skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + ani_hdr->length));
+
+	hdd_debug("sending oem response to pid %d", app_pid);
+
+	(void)nl_srv_ucast_oem(skb, app_pid, MSG_DONTWAIT);
+
+	return error_code;
+}
+
+/**
+ * oem_process_get_cap_req_msg() - process oem get capability request
+ *
+ * This function process the get capability request from OEM and responds
+ * with the capability.
+ *
+ * Return: error code
+ */
+static int oem_process_get_cap_req_msg(void)
+{
+	int error_code;
+	struct oem_get_capability_rsp *cap_rsp;
+	struct oem_data_cap data_cap = { {0} };
+	struct sme_oem_capability oem_cap;
+	struct hdd_adapter *adapter;
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	tAniMsgHdr *ani_hdr;
+	uint8_t *buf;
+
+	/* for now, STA interface only */
+	adapter = hdd_get_adapter(p_hdd_ctx, QDF_STA_MODE);
+	if (!adapter) {
+		hdd_err("No adapter for STA mode");
+		return -EINVAL;
+	}
+
+	error_code = populate_oem_data_cap(adapter, &data_cap);
+	if (0 != error_code)
+		return error_code;
+
+	skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + sizeof(*cap_rsp)),
+			GFP_KERNEL);
+	if (skb == NULL)
+		return -ENOMEM;
+
+	nlh = (struct nlmsghdr *)skb->data;
+	nlh->nlmsg_pid = 0;     /* from kernel */
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_seq = 0;
+	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
+	ani_hdr = NLMSG_DATA(nlh);
+	ani_hdr->type = ANI_MSG_GET_OEM_CAP_RSP;
+
+	ani_hdr->length = sizeof(*cap_rsp);
+	nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + ani_hdr->length));
+
+	buf = (char *)((char *)ani_hdr + sizeof(tAniMsgHdr));
+	qdf_mem_copy(buf, &data_cap, sizeof(data_cap));
+
+	buf = (char *) buf +  sizeof(data_cap);
+	qdf_mem_zero(&oem_cap, sizeof(oem_cap));
+	sme_oem_get_capability(p_hdd_ctx->mac_handle, &oem_cap);
+	qdf_mem_copy(buf, &oem_cap, sizeof(oem_cap));
+
+	skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + ani_hdr->length)));
+	hdd_info("send rsp to oem-pid:%d for get_capability",
+		 p_hdd_ctx->oem_pid);
+
+	(void)nl_srv_ucast_oem(skb, p_hdd_ctx->oem_pid, MSG_DONTWAIT);
+	return 0;
+}
+
+/**
+ * hdd_send_peer_status_ind_to_oem_app() -
+ * Function to send peer status to a registered application
+ * @peerMac: MAC address of peer
+ * @peerStatus: ePeerConnected or ePeerDisconnected
+ * @peerTimingMeasCap: 0: RTT/RTT2, 1: RTT3. Default is 0
+ * @sessionId: SME session id, i.e. vdev_id
+ * @chan_info: operating channel information
+ * @dev_mode: dev mode for which indication is sent
+ *
+ * Return: none
+ */
+void hdd_send_peer_status_ind_to_oem_app(struct qdf_mac_addr *peerMac,
+					 uint8_t peerStatus,
+					 uint8_t peerTimingMeasCap,
+					 uint8_t sessionId,
+					 tSirSmeChanInfo *chan_info,
+					 enum QDF_OPMODE dev_mode)
+{
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	tAniMsgHdr *aniHdr;
+	struct peer_status_info *pPeerInfo;
+
+	if (!p_hdd_ctx) {
+		hdd_err("HDD Ctx is null");
+		return;
+	}
+
+	/* check if oem app has registered and pid is valid */
+	if ((!p_hdd_ctx->oem_app_registered) || (p_hdd_ctx->oem_pid == 0)) {
+		hdd_info("OEM app is not registered(%d) or pid is invalid(%d)",
+			 p_hdd_ctx->oem_app_registered,
+			 p_hdd_ctx->oem_pid);
+		return;
+	}
+
+	skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) +
+				    sizeof(*pPeerInfo)),
+			GFP_KERNEL);
+	if (skb == NULL)
+		return;
+
+	nlh = (struct nlmsghdr *)skb->data;
+	nlh->nlmsg_pid = 0;     /* from kernel */
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_seq = 0;
+	nlh->nlmsg_type = WLAN_NL_MSG_OEM;
+	aniHdr = NLMSG_DATA(nlh);
+	aniHdr->type = ANI_MSG_PEER_STATUS_IND;
+
+	aniHdr->length = sizeof(*pPeerInfo);
+	nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length));
+
+	pPeerInfo = (struct peer_status_info *) ((char *)aniHdr + sizeof(tAniMsgHdr));
+
+	qdf_mem_copy(pPeerInfo->peer_mac_addr, peerMac->bytes,
+		     sizeof(peerMac->bytes));
+	pPeerInfo->peer_status = peerStatus;
+	pPeerInfo->vdev_id = sessionId;
+	pPeerInfo->peer_capability = peerTimingMeasCap;
+	pPeerInfo->reserved0 = 0;
+	/* Set 0th bit of reserved0 for STA mode */
+	if (QDF_STA_MODE == dev_mode)
+		pPeerInfo->reserved0 |= 0x01;
+
+	if (chan_info) {
+		pPeerInfo->peer_chan_info.chan_id = chan_info->chan_id;
+		pPeerInfo->peer_chan_info.reserved0 = 0;
+		pPeerInfo->peer_chan_info.mhz = chan_info->mhz;
+		pPeerInfo->peer_chan_info.band_center_freq1 =
+			chan_info->band_center_freq1;
+		pPeerInfo->peer_chan_info.band_center_freq2 =
+			chan_info->band_center_freq2;
+		pPeerInfo->peer_chan_info.info = chan_info->info;
+		pPeerInfo->peer_chan_info.reg_info_1 = chan_info->reg_info_1;
+		pPeerInfo->peer_chan_info.reg_info_2 = chan_info->reg_info_2;
+	} else {
+		pPeerInfo->peer_chan_info.chan_id = 0;
+		pPeerInfo->peer_chan_info.reserved0 = 0;
+		pPeerInfo->peer_chan_info.mhz = 0;
+		pPeerInfo->peer_chan_info.band_center_freq1 = 0;
+		pPeerInfo->peer_chan_info.band_center_freq2 = 0;
+		pPeerInfo->peer_chan_info.info = 0;
+		pPeerInfo->peer_chan_info.reg_info_1 = 0;
+		pPeerInfo->peer_chan_info.reg_info_2 = 0;
+	}
+	skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length)));
+
+	hdd_info("sending peer " MAC_ADDRESS_STR
+		  " status(%d), peerTimingMeasCap(%d), vdevId(%d), chanId(%d)"
+		  " to oem app pid(%d), center freq 1 (%d), center freq 2 (%d),"
+		  " info (0x%x), frequency (%d),reg info 1 (0x%x),"
+		  " reg info 2 (0x%x)",
+		  MAC_ADDR_ARRAY(peerMac->bytes),
+		  peerStatus, peerTimingMeasCap,
+		  sessionId, pPeerInfo->peer_chan_info.chan_id,
+		  p_hdd_ctx->oem_pid,
+		  pPeerInfo->peer_chan_info.band_center_freq1,
+		  pPeerInfo->peer_chan_info.band_center_freq2,
+		  pPeerInfo->peer_chan_info.info,
+		  pPeerInfo->peer_chan_info.mhz,
+		  pPeerInfo->peer_chan_info.reg_info_1,
+		  pPeerInfo->peer_chan_info.reg_info_2);
+
+	(void)nl_srv_ucast_oem(skb, p_hdd_ctx->oem_pid, MSG_DONTWAIT);
+}
+
+/**
+ * oem_app_reg_req_handler() - function to handle APP registration request
+ *                             from userspace
+ * @hdd_ctx: handle to HDD context
+ * @msg_hdr: pointer to ANI message header
+ * @pid: Process ID
+ *
+ * Return: 0 if success, error code otherwise
+ */
+static int oem_app_reg_req_handler(struct hdd_context *hdd_ctx,
+				   tAniMsgHdr *msg_hdr, int pid)
+{
+	char *sign_str = NULL;
+
+	/* Registration request is only allowed for Qualcomm Application */
+	hdd_debug("Received App Req Req from App pid: %d len: %d",
+			   pid, msg_hdr->length);
+
+	sign_str = (char *)((char *)msg_hdr + sizeof(tAniMsgHdr));
+	if ((OEM_APP_SIGNATURE_LEN == msg_hdr->length) &&
+			(0 == strncmp(sign_str, OEM_APP_SIGNATURE_STR,
+				      OEM_APP_SIGNATURE_LEN))) {
+		hdd_debug("Valid App Req Req from oem app pid: %d", pid);
+
+		hdd_ctx->oem_app_registered = true;
+		hdd_ctx->oem_pid = pid;
+		send_oem_reg_rsp_nlink_msg();
+	} else {
+		hdd_err("Invalid signature in App Reg Req from pid: %d", pid);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_INVALID_SIGNATURE);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+/**
+ * oem_data_req_handler() - function to handle data_req from userspace
+ * @hdd_ctx: handle to HDD context
+ * @msg_hdr: pointer to ANI message header
+ * @pid: Process ID
+ *
+ * Return: 0 if success, error code otherwise
+ */
+static int oem_data_req_handler(struct hdd_context *hdd_ctx,
+				tAniMsgHdr *msg_hdr, int pid)
+{
+	hdd_debug("Received Oem Data Request length: %d from pid: %d",
+			msg_hdr->length, pid);
+
+	if ((!hdd_ctx->oem_app_registered) ||
+			(pid != hdd_ctx->oem_pid)) {
+		/* either oem app is not registered yet or pid is different */
+		hdd_err("OEM DataReq: app not registered(%d) or incorrect pid(%d)",
+				hdd_ctx->oem_app_registered, pid);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_APP_NOT_REGISTERED);
+		return -EPERM;
+	}
+
+	if ((!msg_hdr->length) || (OEM_DATA_REQ_SIZE < msg_hdr->length)) {
+		hdd_err("Invalid length (%d) in Oem Data Request",
+				msg_hdr->length);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_INVALID_MESSAGE_LENGTH);
+		return -EPERM;
+	}
+
+	oem_process_data_req_msg(msg_hdr->length,
+			(char *) ((char *)msg_hdr +
+				sizeof(tAniMsgHdr)));
+
+	return 0;
+}
+
+/**
+ * oem_chan_info_req_handler() - function to handle chan_info_req from userspace
+ * @hdd_ctx: handle to HDD context
+ * @msg_hdr: pointer to ANI message header
+ * @pid: Process ID
+ *
+ * Return: 0 if success, error code otherwise
+ */
+static int oem_chan_info_req_handler(struct hdd_context *hdd_ctx,
+					tAniMsgHdr *msg_hdr, int pid)
+{
+	hdd_debug("Received channel info request, num channel(%d) from pid: %d",
+			msg_hdr->length, pid);
+
+	if ((!hdd_ctx->oem_app_registered) ||
+			(pid != hdd_ctx->oem_pid)) {
+		/* either oem app is not registered yet or pid is different */
+		hdd_err("Chan InfoReq: app not registered(%d) or incorrect pid(%d)",
+				hdd_ctx->oem_app_registered, pid);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_APP_NOT_REGISTERED);
+		return -EPERM;
+	}
+
+	/* message length contains list of channel ids */
+	if ((!msg_hdr->length) ||
+			(WNI_CFG_VALID_CHANNEL_LIST_LEN < msg_hdr->length)) {
+		hdd_err("Invalid length (%d) in channel info request",
+				msg_hdr->length);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_INVALID_MESSAGE_LENGTH);
+		return -EPERM;
+	}
+	oem_process_channel_info_req_msg(msg_hdr->length,
+			(char *)((char *)msg_hdr + sizeof(tAniMsgHdr)));
+
+	return 0;
+}
+
+/**
+ * oem_set_cap_req_handler() - function to handle set_cap_req from userspace
+ * @hdd_ctx: handle to HDD context
+ * @msg_hdr: pointer to ANI message header
+ * @pid: Process ID
+ *
+ * Return: 0 if success, error code otherwise
+ */
+static int oem_set_cap_req_handler(struct hdd_context *hdd_ctx,
+					tAniMsgHdr *msg_hdr, int pid)
+{
+	hdd_info("Received set oem cap req of length:%d from pid: %d",
+			msg_hdr->length, pid);
+
+	if ((!hdd_ctx->oem_app_registered) ||
+			(pid != hdd_ctx->oem_pid)) {
+		/* oem app is not registered yet or pid is different */
+		hdd_err("set_oem_capability : app not registered(%d) or incorrect pid(%d)",
+				hdd_ctx->oem_app_registered, pid);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_APP_NOT_REGISTERED);
+		return -EPERM;
+	}
+
+	if ((!msg_hdr->length) ||
+			(sizeof(struct sme_oem_capability) < msg_hdr->length)) {
+		hdd_err("Invalid length (%d) in set_oem_capability",
+				msg_hdr->length);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_INVALID_MESSAGE_LENGTH);
+		return -EPERM;
+	}
+
+	oem_process_set_cap_req_msg(msg_hdr->length, (char *)
+			((char *)msg_hdr + sizeof(tAniMsgHdr)),
+			pid);
+	return 0;
+}
+
+/**
+ * oem_get_cap_req_handler() - function to handle get_cap_req from userspace
+ * @hdd_ctx: handle to HDD context
+ * @msg_hdr: pointer to ANI message header
+ * @pid: Process ID
+ *
+ * Return: 0 if success, error code otherwise
+ */
+static int oem_get_cap_req_handler(struct hdd_context *hdd_ctx,
+					tAniMsgHdr *msg_hdr, int pid)
+{
+	hdd_info("Rcvd get oem capability req - length:%d from pid: %d",
+			msg_hdr->length, pid);
+
+	if ((!hdd_ctx->oem_app_registered) ||
+			(pid != hdd_ctx->oem_pid)) {
+		/* oem app is not registered yet or pid is different */
+		hdd_err("get_oem_capability : app not registered(%d) or incorrect pid(%d)",
+				hdd_ctx->oem_app_registered, pid);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_APP_NOT_REGISTERED);
+		return -EPERM;
+	}
+
+	oem_process_get_cap_req_msg();
+	return 0;
+}
+
+/**
+ * oem_request_dispatcher() - OEM command dispatcher API
+ * @msg_hdr: ANI Message Header
+ * @pid: process id
+ *
+ * This API is used to dispatch the command from OEM depending
+ * on the type of the message received.
+ *
+ * Return: None
+ */
+static void oem_request_dispatcher(tAniMsgHdr *msg_hdr, int pid)
+{
+	switch (msg_hdr->type) {
+	case ANI_MSG_APP_REG_REQ:
+		oem_app_reg_req_handler(p_hdd_ctx, msg_hdr, pid);
+		break;
+
+	case ANI_MSG_OEM_DATA_REQ:
+		oem_data_req_handler(p_hdd_ctx, msg_hdr, pid);
+		break;
+
+	case ANI_MSG_CHANNEL_INFO_REQ:
+		oem_chan_info_req_handler(p_hdd_ctx, msg_hdr, pid);
+		break;
+
+	case ANI_MSG_SET_OEM_CAP_REQ:
+		oem_set_cap_req_handler(p_hdd_ctx, msg_hdr, pid);
+		break;
+
+	case ANI_MSG_GET_OEM_CAP_REQ:
+		oem_get_cap_req_handler(p_hdd_ctx, msg_hdr, pid);
+		break;
+
+	default:
+		hdd_err("Received Invalid message type (%d), length (%d)",
+				msg_hdr->type, msg_hdr->length);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_INVALID_MESSAGE_TYPE);
+	}
+}
+
+#ifdef CNSS_GENL
+/**
+ * oem_cmd_handler() - API to handle OEM commands
+ * @data: Pointer to data
+ * @data_len: length of the received data
+ * @ctx: Pointer to the context
+ * @pid: Process id
+ *
+ * This API handles the command from OEM application from user space and
+ * send back event to user space if necessary.
+ *
+ * Return: None
+ */
+static void oem_cmd_handler(const void *data, int data_len, void *ctx, int pid)
+{
+	tAniMsgHdr *msg_hdr;
+	int msg_len;
+	int ret;
+	struct nlattr *tb[CLD80211_ATTR_MAX + 1];
+
+	ret = wlan_hdd_validate_context(p_hdd_ctx);
+	if (ret) {
+		hdd_err("hdd ctx validate fails");
+		return;
+	}
+
+	/*
+	 * audit note: it is ok to pass a NULL policy here since only
+	 * one attribute is parsed and it is explicitly validated
+	 */
+	if (wlan_cfg80211_nla_parse(tb, CLD80211_ATTR_MAX,
+				    data, data_len, NULL)) {
+		hdd_err("Invalid ATTR");
+		return;
+	}
+
+	if (!tb[CLD80211_ATTR_DATA]) {
+		hdd_err("attr ATTR_DATA failed");
+		return;
+	}
+
+	msg_len = nla_len(tb[CLD80211_ATTR_DATA]);
+	if (msg_len < sizeof(*msg_hdr)) {
+		hdd_err("runt ATTR_DATA size %d", msg_len);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_NULL_MESSAGE_HEADER);
+		return;
+	}
+
+	msg_hdr = nla_data(tb[CLD80211_ATTR_DATA]);
+	if (msg_len < (sizeof(*msg_hdr) + msg_hdr->length)) {
+		hdd_err("Invalid nl msg len %d, msg hdr len %d",
+			msg_len, msg_hdr->length);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_INVALID_MESSAGE_LENGTH);
+		return;
+	}
+
+	oem_request_dispatcher(msg_hdr, pid);
+}
+
+int oem_activate_service(struct hdd_context *hdd_ctx)
+{
+	p_hdd_ctx = hdd_ctx;
+	register_cld_cmd_cb(WLAN_NL_MSG_OEM, oem_cmd_handler, NULL);
+	return 0;
+}
+
+int oem_deactivate_service(void)
+{
+	deregister_cld_cmd_cb(WLAN_NL_MSG_OEM);
+	return 0;
+}
+#else
+
+/*
+ * Callback function invoked by Netlink service for all netlink
+ * messages (from user space) addressed to WLAN_NL_MSG_OEM
+ */
+
+/**
+ * oem_msg_callback() - callback invoked by netlink service
+ * @skb:    skb with netlink message
+ *
+ * This function gets invoked by netlink service when a message
+ * is received from user space addressed to WLAN_NL_MSG_OEM
+ *
+ * Return: zero on success
+ *         On error, error number will be returned.
+ */
+static int oem_msg_callback(struct sk_buff *skb)
+{
+	struct nlmsghdr *nlh;
+	tAniMsgHdr *msg_hdr;
+	int ret;
+
+	nlh = (struct nlmsghdr *)skb->data;
+	if (!nlh) {
+		hdd_err("Netlink header null");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(p_hdd_ctx);
+	if (ret)
+		return ret;
+
+	msg_hdr = NLMSG_DATA(nlh);
+
+	if (!msg_hdr) {
+		hdd_err("Message header null");
+		send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
+					   OEM_ERR_NULL_MESSAGE_HEADER);
+		return -EPERM;
+	}
+
+	if (nlh->nlmsg_len <
+	    NLMSG_LENGTH(sizeof(tAniMsgHdr) + msg_hdr->length)) {
+		hdd_err("Invalid nl msg len, nlh->nlmsg_len (%d), msg_hdr->len (%d)",
+			nlh->nlmsg_len, msg_hdr->length);
+		send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid,
+					   OEM_ERR_INVALID_MESSAGE_LENGTH);
+		return -EPERM;
+	}
+
+	oem_request_dispatcher(msg_hdr, nlh->nlmsg_pid);
+	return 0;
+}
+
+static int __oem_msg_callback(struct sk_buff *skb)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = oem_msg_callback(skb);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int oem_activate_service(struct hdd_context *hdd_ctx)
+{
+	p_hdd_ctx = hdd_ctx;
+
+	/* Register the msg handler for msgs addressed to WLAN_NL_MSG_OEM */
+	return nl_srv_register(WLAN_NL_MSG_OEM, __oem_msg_callback);
+}
+
+int oem_deactivate_service(void)
+{
+	/* Deregister the msg handler for msgs addressed to WLAN_NL_MSG_OEM */
+	return nl_srv_unregister(WLAN_NL_MSG_OEM, __oem_msg_callback);
+}
+
+#endif
+#endif
diff --git a/core/hdd/src/wlan_hdd_ota_test.c b/core/hdd/src/wlan_hdd_ota_test.c
new file mode 100644
index 0000000..ef54c99
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_ota_test.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_ota_test.c
+ *
+ * WLAN OTA test functions
+ *
+ */
+
+#include <wlan_hdd_includes.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <sme_power_save_api.h>
+#include <wlan_hdd_ota_test.h>
+
+static const struct
+nla_policy
+qca_wlan_vendor_ota_test_policy
+[QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE] = {.type = NLA_U8 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_set_ota_test() - enable/disable OTA test
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_set_ota_test(struct wiphy *wiphy,
+					    struct wireless_dev *wdev,
+					    const void *data,
+					    int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx  = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX + 1];
+	uint8_t ota_enable = 0;
+	QDF_STATUS status;
+	uint32_t current_roam_state;
+	mac_handle_t mac_handle;
+
+	hdd_enter_dev(dev);
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (wlan_hdd_validate_context(hdd_ctx) != 0)
+		return -EINVAL;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX,
+				    data, data_len,
+				    qca_wlan_vendor_ota_test_policy)) {
+		hdd_err("invalid attr");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE]) {
+		hdd_err("attr ota test failed");
+		return -EINVAL;
+	}
+
+	ota_enable = nla_get_u8(
+		tb[QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE]);
+
+	hdd_debug(" OTA test enable = %d", ota_enable);
+	if (ota_enable != 1) {
+		hdd_err("Invalid value, only enable test mode is supported!");
+		return -EINVAL;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	current_roam_state =
+		sme_get_current_roam_state(mac_handle, adapter->session_id);
+	status = sme_stop_roaming(mac_handle, adapter->session_id,
+				  eCsrHddIssued);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Enable/Disable roaming failed");
+		return -EINVAL;
+	}
+
+	status = sme_ps_enable_disable(mac_handle, adapter->session_id,
+				       SME_PS_DISABLE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Enable/Disable power save failed");
+		/* restore previous roaming setting */
+		if (current_roam_state == eCSR_ROAMING_STATE_JOINING ||
+		    current_roam_state == eCSR_ROAMING_STATE_JOINED)
+			status = sme_start_roaming(mac_handle,
+						   adapter->session_id,
+						   eCsrHddIssued);
+		else if (current_roam_state == eCSR_ROAMING_STATE_STOP ||
+			 current_roam_state == eCSR_ROAMING_STATE_IDLE)
+			status = sme_stop_roaming(mac_handle,
+						  adapter->session_id,
+						  eCsrHddIssued);
+
+		if (status != QDF_STATUS_SUCCESS)
+			hdd_err("Restoring roaming state failed");
+
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int wlan_hdd_cfg80211_set_ota_test(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data,
+				   int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_ota_test(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
diff --git a/core/hdd/src/wlan_hdd_ota_test.h b/core/hdd/src/wlan_hdd_ota_test.h
new file mode 100644
index 0000000..9d950b8
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_ota_test.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __WLAN_HDD_OTA_TEST_H
+#define __WLAN_HDD_OTA_TEST_H
+
+/**
+ * DOC: wlan_hdd_ota_test_h
+ *
+ * WLAN Host Device Driver OTA test API specification
+ */
+
+#ifdef FEATURE_OTA_TEST
+/**
+ * wlan_hdd_cfg80211_set_ota_test () - Enable or disable OTA test
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_set_ota_test(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data,
+				   int data_len);
+
+#define FEATURE_OTA_TEST_VENDOR_COMMANDS			\
+{								\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,		\
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OTA_TEST,	\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |			\
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |		\
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,		\
+	.doit = wlan_hdd_cfg80211_set_ota_test			\
+},
+#else /* FEATURE_OTA_TEST */
+#define FEATURE_OTA_TEST_VENDOR_COMMANDS
+#endif /* FEATURE_OTA_TEST */
+
+#endif /* __WLAN_HDD_OTA_TEST_H */
+
diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c
new file mode 100644
index 0000000..5ffa4b3
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_p2p.c
@@ -0,0 +1,1347 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/**
+ *
+ * @file  wlan_hdd_p2p.c
+ *
+ * @brief WLAN Host Device Driver implementation for P2P commands interface
+ *
+ */
+
+#include <wlan_hdd_includes.h>
+#include <wlan_hdd_hostapd.h>
+#include <net/cfg80211.h>
+#include "sme_api.h"
+#include "sme_qos_api.h"
+#include "wlan_hdd_p2p.h"
+#include "sap_api.h"
+#include "wlan_hdd_main.h"
+#include "qdf_trace.h"
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <net/ieee80211_radiotap.h>
+#include "wlan_hdd_tdls.h"
+#include "wlan_hdd_trace.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "cds_sched.h"
+#include "wlan_policy_mgr_api.h"
+#include "cds_utils.h"
+#include "wlan_p2p_public_struct.h"
+#include "wlan_p2p_ucfg_api.h"
+#include "wlan_cfg80211_p2p.h"
+#include "wlan_p2p_cfg_api.h"
+#include "wlan_policy_mgr_ucfg.h"
+
+/* Ms to Time Unit Micro Sec */
+#define MS_TO_TU_MUS(x)   ((x) * 1024)
+#define MAX_MUS_VAL       (INT_MAX / 1024)
+
+#ifdef WLAN_FEATURE_P2P_DEBUG
+#define MAX_P2P_ACTION_FRAME_TYPE 9
+const char *p2p_action_frame_type[] = { "GO Negotiation Request",
+					"GO Negotiation Response",
+					"GO Negotiation Confirmation",
+					"P2P Invitation Request",
+					"P2P Invitation Response",
+					"Device Discoverability Request",
+					"Device Discoverability Response",
+					"Provision Discovery Request",
+					"Provision Discovery Response"};
+
+#endif
+#define MAX_TDLS_ACTION_FRAME_TYPE 11
+const char *tdls_action_frame_type[] = { "TDLS Setup Request",
+					 "TDLS Setup Response",
+					 "TDLS Setup Confirm",
+					 "TDLS Teardown",
+					 "TDLS Peer Traffic Indication",
+					 "TDLS Channel Switch Request",
+					 "TDLS Channel Switch Response",
+					 "TDLS Peer PSM Request",
+					 "TDLS Peer PSM Response",
+					 "TDLS Peer Traffic Response",
+					 "TDLS Discovery Request"};
+
+void wlan_hdd_cancel_existing_remain_on_channel(struct hdd_adapter *adapter)
+{
+	if (!adapter) {
+		hdd_err("null adapter");
+		return;
+	}
+
+	ucfg_p2p_cleanup_roc_by_vdev(adapter->vdev);
+}
+
+int wlan_hdd_check_remain_on_channel(struct hdd_adapter *adapter)
+{
+	if (QDF_P2P_GO_MODE != adapter->device_mode)
+		wlan_hdd_cancel_existing_remain_on_channel(adapter);
+
+	return 0;
+}
+
+/* Clean up RoC context at hdd_stop_adapter*/
+void wlan_hdd_cleanup_remain_on_channel_ctx(struct hdd_adapter *adapter)
+{
+	if (!adapter) {
+		hdd_err("null adapter");
+		return;
+	}
+
+	ucfg_p2p_cleanup_roc_by_vdev(adapter->vdev);
+}
+
+void wlan_hdd_cleanup_actionframe(struct hdd_adapter *adapter)
+{
+	if (!adapter) {
+		hdd_err("null adapter");
+		return;
+	}
+
+	ucfg_p2p_cleanup_tx_by_vdev(adapter->vdev);
+}
+
+static int __wlan_hdd_cfg80211_remain_on_channel(struct wiphy *wiphy,
+						 struct wireless_dev *wdev,
+						 struct ieee80211_channel *chan,
+						 unsigned int duration,
+						 u64 *cookie)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+	int ret;
+
+	hdd_enter();
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	status = wlan_cfg80211_roc(adapter->vdev, chan, duration, cookie);
+	hdd_debug("remain on channel request, status:%d, cookie:0x%llx",
+		  status, *cookie);
+
+	return qdf_status_to_os_return(status);
+}
+
+int wlan_hdd_cfg80211_remain_on_channel(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					struct ieee80211_channel *chan,
+					unsigned int duration, u64 *cookie)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_remain_on_channel(wiphy,
+						    wdev,
+						    chan,
+						    duration, cookie);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int
+__wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     u64 cookie)
+{
+	QDF_STATUS status;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	status = wlan_cfg80211_cancel_roc(adapter->vdev, cookie);
+	hdd_debug("cancel remain on channel, status:%d", status);
+
+	return 0;
+}
+
+int wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
+					       struct wireless_dev *wdev,
+					       u64 cookie)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy,
+							   wdev,
+							   cookie);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
+			      struct ieee80211_channel *chan, bool offchan,
+			      unsigned int wait,
+			      const u8 *buf, size_t len, bool no_cck,
+			      bool dont_wait_for_ack, u64 *cookie)
+{
+	QDF_STATUS status;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	uint8_t type;
+	uint8_t sub_type;
+	QDF_STATUS qdf_status;
+	int ret;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret) {
+		hdd_err("wlan_hdd_validate_context return:%d", ret);
+		return ret;
+	}
+
+	type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]);
+	sub_type = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]);
+
+	/* When frame to be transmitted is auth mgmt, then trigger
+	 * sme_send_mgmt_tx to send auth frame without need for policy manager.
+	 * Where as wlan_cfg80211_mgmt_tx requires roc and requires approval
+	 * from policy manager.
+	 */
+	if ((adapter->device_mode == QDF_STA_MODE) &&
+	    (type == SIR_MAC_MGMT_FRAME &&
+	    sub_type == SIR_MAC_MGMT_AUTH)) {
+		qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_SME,
+			   TRACE_CODE_HDD_SEND_MGMT_TX,
+			   wlan_vdev_get_id(adapter->vdev), 0);
+
+		qdf_status = sme_send_mgmt_tx(hdd_ctx->mac_handle,
+					      adapter->session_id, buf, len);
+
+		if (QDF_IS_STATUS_SUCCESS(qdf_status))
+			return 0;
+		else
+			return -EINVAL;
+	}
+
+	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_OS_IF,
+		   TRACE_CODE_HDD_SEND_MGMT_TX,
+		   wlan_vdev_get_id(adapter->vdev), 0);
+
+	status = wlan_cfg80211_mgmt_tx(adapter->vdev, chan, offchan, wait, buf,
+				       len, no_cck, dont_wait_for_ack, cookie);
+	hdd_debug("mgmt tx, status:%d, cookie:0x%llx", status, *cookie);
+
+	return 0;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
+		     struct cfg80211_mgmt_tx_params *params, u64 *cookie)
+#else
+int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
+		     struct ieee80211_channel *chan, bool offchan,
+		     unsigned int wait,
+		     const u8 *buf, size_t len, bool no_cck,
+		     bool dont_wait_for_ack, u64 *cookie)
+#endif /* LINUX_VERSION_CODE */
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+	ret = __wlan_hdd_mgmt_tx(wiphy, wdev, params->chan, params->offchan,
+				 params->wait, params->buf, params->len,
+				 params->no_cck, params->dont_wait_for_ack,
+				 cookie);
+#else
+	ret = __wlan_hdd_mgmt_tx(wiphy, wdev, chan, offchan,
+				 wait, buf, len, no_cck,
+				 dont_wait_for_ack, cookie);
+#endif /* LINUX_VERSION_CODE */
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+						   struct wireless_dev *wdev,
+						   u64 cookie)
+{
+	QDF_STATUS status;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	status = wlan_cfg80211_mgmt_tx_cancel(adapter->vdev, cookie);
+	hdd_debug("cancel mgmt tx, status:%d", status);
+
+	return 0;
+}
+
+int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+					  struct wireless_dev *wdev, u64 cookie)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, wdev, cookie);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_set_p2p_noa
+ *
+ ***FUNCTION:
+ * This function is called from hdd_hostapd_ioctl function when Driver
+ * get P2P_SET_NOA command from wpa_supplicant using private ioctl
+ *
+ ***LOGIC:
+ * Fill noa Struct According to P2P Power save Option and Pass it to SME layer
+ *
+ ***ASSUMPTIONS:
+ *
+ *
+ ***NOTE:
+ *
+ * @param dev          Pointer to net device structure
+ * @param command      Pointer to command
+ *
+ * @return Status
+ */
+
+int hdd_set_p2p_noa(struct net_device *dev, uint8_t *command)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct p2p_ps_config noa = {0};
+	int count, duration, interval;
+	char *param;
+	int ret;
+
+	param = strnchr(command, strlen(command), ' ');
+	if (param == NULL) {
+		hdd_err("strnchr failed to find delimeter");
+		return -EINVAL;
+	}
+	param++;
+	ret = sscanf(param, "%d %d %d", &count, &interval, &duration);
+	if (ret != 3) {
+		hdd_err("P2P_SET GO noa: fail to read params, ret=%d",
+			ret);
+		return -EINVAL;
+	}
+	if (count < 0 || interval < 0 || duration < 0 ||
+	    interval > MAX_MUS_VAL || duration > MAX_MUS_VAL) {
+		hdd_err("Invalid NOA parameters");
+		return -EINVAL;
+	}
+	hdd_debug("P2P_SET GO noa: count=%d interval=%d duration=%d",
+		count, interval, duration);
+	duration = MS_TO_TU_MUS(duration);
+	/* PS Selection
+	 * Periodic noa (2)
+	 * Single NOA   (4)
+	 */
+	noa.opp_ps = 0;
+	noa.ct_window = 0;
+	if (count == 1) {
+		noa.duration = 0;
+		noa.single_noa_duration = duration;
+		noa.ps_selection = P2P_POWER_SAVE_TYPE_SINGLE_NOA;
+	} else {
+		noa.duration = duration;
+		noa.single_noa_duration = 0;
+		noa.ps_selection = P2P_POWER_SAVE_TYPE_PERIODIC_NOA;
+	}
+	noa.interval = MS_TO_TU_MUS(interval);
+	noa.count = count;
+	noa.vdev_id = adapter->session_id;
+
+	hdd_debug("P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
+		  "interval %d count %d single noa duration %d "
+		  "PsSelection %x", noa.opp_ps,
+		  noa.ct_window, noa.duration, noa.interval,
+		  noa.count, noa.single_noa_duration, noa.ps_selection);
+
+	return wlan_hdd_set_power_save(adapter, &noa);
+}
+
+/**
+ * hdd_set_p2p_opps
+ *
+ ***FUNCTION:
+ * This function is called from hdd_hostapd_ioctl function when Driver
+ * get P2P_SET_PS command from wpa_supplicant using private ioctl
+ *
+ ***LOGIC:
+ * Fill noa Struct According to P2P Power save Option and Pass it to SME layer
+ *
+ ***ASSUMPTIONS:
+ *
+ *
+ ***NOTE:
+ *
+ * @param  dev         Pointer to net device structure
+ * @param  command     Pointer to command
+ *
+ * @return Status
+ */
+
+int hdd_set_p2p_opps(struct net_device *dev, uint8_t *command)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct p2p_ps_config noa = {0};
+	char *param;
+	int legacy_ps, opp_ps, ctwindow;
+	int ret;
+
+	param = strnchr(command, strlen(command), ' ');
+	if (param == NULL) {
+		hdd_err("strnchr failed to find delimiter");
+		return -EINVAL;
+	}
+	param++;
+	ret = sscanf(param, "%d %d %d", &legacy_ps, &opp_ps, &ctwindow);
+	if (ret != 3) {
+		hdd_err("P2P_SET GO PS: fail to read params, ret=%d", ret);
+		return -EINVAL;
+	}
+
+	if ((opp_ps != -1) && (opp_ps != 0) && (opp_ps != 1)) {
+		hdd_err("Invalid opp_ps value:%d", opp_ps);
+		return -EINVAL;
+	}
+
+	/* P2P spec: 3.3.2 Power Management and discovery:
+	 *     CTWindow should be at least 10 TU.
+	 * P2P spec: Table 27 - CTWindow and OppPS Parameters field format:
+	 *     CTWindow and OppPS Parameters together is 8 bits.
+	 *     CTWindow uses 7 bits (0-6, Bit 7 is for OppPS)
+	 * 0 indicates that there shall be no CTWindow
+	 */
+	if ((ctwindow != -1) && (ctwindow != 0) &&
+	    (!((ctwindow >= 10) && (ctwindow <= 127)))) {
+		hdd_err("Invalid CT window value:%d", ctwindow);
+		return -EINVAL;
+	}
+
+	hdd_debug("P2P_SET GO PS: legacy_ps=%d opp_ps=%d ctwindow=%d",
+		  legacy_ps, opp_ps, ctwindow);
+
+	/* PS Selection
+	 * Opportunistic Power Save (1)
+	 */
+
+	/* From wpa_cli user need to use separate command to set ctWindow and
+	 * Opps when user want to set ctWindow during that time other parameters
+	 * values are coming from wpa_supplicant as -1.
+	 * Example : User want to set ctWindow with 30 then wpa_cli command :
+	 * P2P_SET ctwindow 30
+	 * Command Received at hdd_hostapd_ioctl is as below:
+	 * P2P_SET_PS -1 -1 30 (legacy_ps = -1, opp_ps = -1, ctwindow = 30)
+	 *
+	 * e.g., 1: P2P_SET_PS 1 1 30
+	 * Driver sets the Opps and CTwindow as 30 and send it to FW.
+	 * e.g., 2: P2P_SET_PS 1 -1 15
+	 * Driver caches the CTwindow value but not send the command to FW.
+	 * e.g., 3: P2P_SET_PS 1 1 -1
+	 * Driver sends the command to FW with Opps enabled and CT window as
+	 * 15 (last cached CTWindow value).
+	 * (or) : P2P_SET_PS 1 1 20
+	 * Driver sends the command to FW with opps enabled and CT window
+	 * as 20.
+	 *
+	 * legacy_ps param remains unused until required in the future.
+	 */
+	if (ctwindow != -1)
+		adapter->ctw = ctwindow;
+
+	/* Send command to FW when OppPS is either enabled(1)/disbaled(0) */
+	if (opp_ps != -1) {
+		adapter->ops = opp_ps;
+		noa.opp_ps = adapter->ops;
+		noa.ct_window = adapter->ctw;
+		noa.duration = 0;
+		noa.single_noa_duration = 0;
+		noa.interval = 0;
+		noa.count = 0;
+		noa.ps_selection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
+		noa.vdev_id = adapter->session_id;
+
+		hdd_debug("P2P_PS_ATTR: oppPS %d ctWindow %d duration %d interval %d count %d single noa duration %d PsSelection %x",
+			noa.opp_ps, noa.ct_window,
+			noa.duration, noa.interval, noa.count,
+			noa.single_noa_duration,
+			noa.ps_selection);
+
+		wlan_hdd_set_power_save(adapter, &noa);
+	}
+
+	return 0;
+}
+
+int hdd_set_p2p_ps(struct net_device *dev, void *msgData)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct p2p_ps_config noa = {0};
+	struct p2p_app_set_ps *pappnoa = (struct p2p_app_set_ps *) msgData;
+
+	noa.opp_ps = pappnoa->opp_ps;
+	noa.ct_window = pappnoa->ctWindow;
+	noa.duration = pappnoa->duration;
+	noa.interval = pappnoa->interval;
+	noa.count = pappnoa->count;
+	noa.single_noa_duration = pappnoa->single_noa_duration;
+	noa.ps_selection = pappnoa->psSelection;
+	noa.vdev_id = adapter->session_id;
+
+	return wlan_hdd_set_power_save(adapter, &noa);
+}
+
+/**
+ * wlan_hdd_allow_sap_add() - check to add new sap interface
+ * @hdd_ctx: pointer to hdd context
+ * @name: name of the new interface
+ * @sap_dev: output pointer to hold existing interface
+ *
+ * Return: If able to add interface return true else false
+ */
+static bool
+wlan_hdd_allow_sap_add(struct hdd_context *hdd_ctx, const char *name,
+		       struct wireless_dev **sap_dev)
+{
+	struct hdd_adapter *adapter;
+
+	*sap_dev = NULL;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter->device_mode == QDF_SAP_MODE &&
+		    test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags) &&
+		    adapter->dev &&
+		    !strncmp(adapter->dev->name, name, IFNAMSIZ)) {
+			struct hdd_beacon_data *beacon =
+						adapter->session.ap.beacon;
+
+			hdd_debug("iface already registered");
+			if (beacon) {
+				adapter->session.ap.beacon = NULL;
+				qdf_mem_free(beacon);
+			}
+			if (adapter->dev->ieee80211_ptr) {
+				*sap_dev = adapter->dev->ieee80211_ptr;
+				return false;
+			}
+
+			hdd_err("ieee80211_ptr points to NULL");
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/**
+ * __wlan_hdd_add_virtual_intf() - Add virtual interface
+ * @wiphy: wiphy pointer
+ * @name: User-visible name of the interface
+ * @name_assign_type: the name of assign type of the netdev
+ * @nl80211_iftype: (virtual) interface types
+ * @flags: moniter configuraiton flags (not used)
+ * @vif_params: virtual interface parameters (not used)
+ *
+ * Return: the pointer of wireless dev, otherwise ERR_PTR.
+ */
+static
+struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
+						 const char *name,
+						 unsigned char name_assign_type,
+						 enum nl80211_iftype type,
+						 u32 *flags,
+						 struct vif_params *params)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct hdd_adapter *adapter = NULL;
+	bool p2p_dev_addr_admin = false;
+	enum QDF_OPMODE mode;
+	QDF_STATUS status;
+	int ret;
+
+	hdd_enter();
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return ERR_PTR(-EINVAL);
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ERR_PTR(ret);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_ADD_VIRTUAL_INTF, NO_SESSION, type));
+
+	status = hdd_nl_to_qdf_iface_type(type, &mode);
+	if (QDF_IS_STATUS_ERROR(status))
+		return ERR_PTR(qdf_status_to_os_return(status));
+
+	switch (mode) {
+	case QDF_SAP_MODE:
+	case QDF_P2P_GO_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_STA_MODE:
+		break;
+	default:
+		mode = QDF_STA_MODE;
+		break;
+	}
+
+	adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
+	if (adapter && !wlan_hdd_validate_session_id(adapter->session_id)) {
+		if (ucfg_scan_get_vdev_status(adapter->vdev) !=
+				SCAN_NOT_IN_PROGRESS) {
+			wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
+					adapter->session_id, INVALID_SCAN_ID,
+					false);
+			hdd_debug("Abort Scan while adding virtual interface");
+		}
+	}
+
+	if (mode == QDF_SAP_MODE) {
+		struct wireless_dev *sap_dev;
+		bool allow_add_sap = wlan_hdd_allow_sap_add(hdd_ctx, name,
+							    &sap_dev);
+		if (!allow_add_sap) {
+			if (sap_dev)
+				return sap_dev;
+
+			return ERR_PTR(-EINVAL);
+		}
+	}
+
+	adapter = NULL;
+	cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
+	if (p2p_dev_addr_admin &&
+	    (mode == QDF_P2P_GO_MODE || mode == QDF_P2P_CLIENT_MODE)) {
+		/*
+		 * Generate the P2P Interface Address. this address must be
+		 * different from the P2P Device Address.
+		 */
+		struct qdf_mac_addr p2p_device_address =
+						hdd_ctx->p2p_device_address;
+		p2p_device_address.bytes[4] ^= 0x80;
+		adapter = hdd_open_adapter(hdd_ctx, mode, name,
+					   p2p_device_address.bytes,
+					   name_assign_type, true);
+	} else {
+		adapter = hdd_open_adapter(hdd_ctx, mode, name,
+					   wlan_hdd_get_intf_addr(hdd_ctx),
+					   name_assign_type, true);
+	}
+
+	if (!adapter) {
+		hdd_err("hdd_open_adapter failed");
+		return ERR_PTR(-ENOSPC);
+	}
+
+	/*
+	 * Add interface can be requested from the upper layer at any time
+	 * check the statemachine for modules state and if they are closed
+	 * open the modules.
+	 */
+	ret = hdd_wlan_start_modules(hdd_ctx, false);
+	if (ret) {
+		hdd_err("Failed to start the wlan_modules");
+		goto close_adapter;
+	}
+
+	/*
+	 * Once the support for session creation/deletion from
+	 * hdd_hostapd_open/hdd_host_stop is in place.
+	 * The support for starting adapter from here can be removed.
+	 */
+	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE) {
+		ret = hdd_start_adapter(adapter);
+		if (ret) {
+			hdd_err("Failed to start %s", name);
+			goto stop_modules;
+		}
+	}
+
+	if (hdd_ctx->rps)
+		hdd_send_rps_ind(adapter);
+
+	hdd_exit();
+
+	return adapter->dev->ieee80211_ptr;
+
+stop_modules:
+	if (!hdd_is_any_interface_open(hdd_ctx))
+		hdd_psoc_idle_timer_start(hdd_ctx);
+
+close_adapter:
+	hdd_close_adapter(hdd_ctx, adapter, true);
+
+	return ERR_PTR(-EINVAL);
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
+					       const char *name,
+					       unsigned char name_assign_type,
+					       enum nl80211_iftype type,
+					       struct vif_params *params)
+{
+	struct wireless_dev *wdev;
+
+	cds_ssr_protect(__func__);
+	wdev = __wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
+					   type, &params->flags, params);
+	cds_ssr_unprotect(__func__);
+
+	return wdev;
+}
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) || defined(WITH_BACKPORTS)
+/**
+ * wlan_hdd_add_virtual_intf() - Add virtual interface wrapper
+ * @wiphy: wiphy pointer
+ * @name: User-visible name of the interface
+ * @name_assign_type: the name of assign type of the netdev
+ * @nl80211_iftype: (virtual) interface types
+ * @flags: monitor mode configuration flags (not used)
+ * @vif_params: virtual interface parameters (not used)
+ *
+ * Return: the pointer of wireless dev, otherwise ERR_PTR.
+ */
+struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
+					       const char *name,
+					       unsigned char name_assign_type,
+					       enum nl80211_iftype type,
+					       u32 *flags,
+					       struct vif_params *params)
+{
+	struct wireless_dev *wdev;
+
+	cds_ssr_protect(__func__);
+	wdev = __wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
+					   type, flags, params);
+	cds_ssr_unprotect(__func__);
+	return wdev;
+
+}
+#else
+/**
+ * wlan_hdd_add_virtual_intf() - Add virtual interface wrapper
+ * @wiphy: wiphy pointer
+ * @name: User-visible name of the interface
+ * @nl80211_iftype: (virtual) interface types
+ * @flags: monitor mode configuration flags (not used)
+ * @vif_params: virtual interface parameters (not used)
+ *
+ * Return: the pointer of wireless dev, otherwise ERR_PTR.
+ */
+struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
+					       const char *name,
+					       enum nl80211_iftype type,
+					       u32 *flags,
+					       struct vif_params *params)
+{
+	struct wireless_dev *wdev;
+	unsigned char name_assign_type = 0;
+
+	cds_ssr_protect(__func__);
+	wdev = __wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
+					   type, flags, params);
+	cds_ssr_unprotect(__func__);
+	return wdev;
+
+}
+#endif
+
+int __wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_context *hdd_ctx = (struct hdd_context *) wiphy_priv(wiphy);
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int errno;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	/*
+	 * Clear SOFTAP_INIT_DONE flag to mark SAP unload, so that we do
+	 * not restart SAP after SSR as SAP is already stopped from user space.
+	 */
+	clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_DEL_VIRTUAL_INTF,
+			 adapter->session_id, adapter->device_mode));
+	hdd_debug("Device_mode %s(%d)",
+		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
+
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	/* check state machine state and kickstart modules if they are closed */
+	errno = hdd_wlan_start_modules(hdd_ctx, false);
+	if (errno)
+		return errno;
+
+	if (adapter->device_mode == QDF_SAP_MODE &&
+	    wlan_sap_is_pre_cac_active(hdd_ctx->mac_handle)) {
+		hdd_clean_up_pre_cac_interface(hdd_ctx);
+	} else {
+		wlan_hdd_release_intf_addr(hdd_ctx,
+					   adapter->mac_addr.bytes);
+		hdd_stop_adapter(hdd_ctx, adapter);
+		hdd_deinit_adapter(hdd_ctx, adapter, true);
+		hdd_close_adapter(hdd_ctx, adapter, true);
+	}
+
+	hdd_exit();
+
+	return 0;
+}
+
+int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_del_virtual_intf(wiphy, wdev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_is_qos_action_frame() - check if frame is QOS action frame
+ * @pb_frames: frame pointer
+ * @frame_len: frame length
+ *
+ * Return: true if it is QOS action frame else false.
+ */
+static inline bool
+hdd_is_qos_action_frame(uint8_t *pb_frames, uint32_t frame_len)
+{
+	if (frame_len <= WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + 1) {
+		hdd_debug("Not a QOS frame len: %d", frame_len);
+		return false;
+	}
+
+	return ((pb_frames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] ==
+		 WLAN_HDD_QOS_ACTION_FRAME) &&
+		(pb_frames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + 1] ==
+		 WLAN_HDD_QOS_MAP_CONFIGURE));
+}
+
+void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
+			     uint32_t frm_len,
+			     uint8_t *pb_frames,
+			     uint8_t frameType, uint32_t rxChan, int8_t rxRssi)
+{
+	uint16_t freq;
+	uint8_t type = 0;
+	uint8_t subType = 0;
+	struct hdd_context *hdd_ctx;
+	uint8_t *dest_addr;
+
+	hdd_debug("Frame Type = %d Frame Length = %d",
+		frameType, frm_len);
+
+	if (NULL == adapter) {
+		hdd_err("adapter is NULL");
+		return;
+	}
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	if (!frm_len) {
+		hdd_err("Frame Length is Invalid ZERO");
+		return;
+	}
+
+	if (!pb_frames) {
+		hdd_err("pbFrames is NULL");
+		return;
+	}
+
+	type = WLAN_HDD_GET_TYPE_FRM_FC(pb_frames[0]);
+	subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pb_frames[0]);
+
+	/* Get adapter from Destination mac address of the frame */
+	if ((type == SIR_MAC_MGMT_FRAME) &&
+	    (subType != SIR_MAC_MGMT_PROBE_REQ) &&
+	    !qdf_is_macaddr_broadcast(
+	     (struct qdf_mac_addr *)&pb_frames[WLAN_HDD_80211_FRM_DA_OFFSET])) {
+		dest_addr = &pb_frames[WLAN_HDD_80211_FRM_DA_OFFSET];
+		adapter = hdd_get_adapter_by_macaddr(hdd_ctx, dest_addr);
+		if (!adapter)
+			adapter = hdd_get_adapter_by_rand_macaddr(hdd_ctx,
+								  dest_addr);
+		if (NULL == adapter) {
+			/*
+			 * Under assumtion that we don't receive any action
+			 * frame with BCST as destination,
+			 * we are dropping action frame
+			 */
+			hdd_err("adapter for action frame is NULL Macaddr = "
+				MAC_ADDRESS_STR, MAC_ADDR_ARRAY(dest_addr));
+			hdd_debug("Frame Type = %d Frame Length = %d subType = %d",
+				  frameType, frm_len, subType);
+			/*
+			 * We will receive broadcast management frames
+			 * in OCB mode
+			 */
+			adapter = hdd_get_adapter(hdd_ctx, QDF_OCB_MODE);
+			if (NULL == adapter || !qdf_is_macaddr_broadcast(
+			    (struct qdf_mac_addr *)dest_addr)) {
+				/*
+				 * Under assumtion that we don't
+				 * receive any action frame with BCST
+				 * as destination, we are dropping
+				 * action frame
+				 */
+				return;
+			}
+		}
+	}
+
+	if (NULL == adapter->dev) {
+		hdd_err("adapter->dev is NULL");
+		return;
+	}
+
+	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
+		hdd_err("adapter has invalid magic");
+		return;
+	}
+
+	/* Channel indicated may be wrong. TODO */
+	/* Indicate an action frame. */
+	if (rxChan <= MAX_NO_OF_2_4_CHANNELS)
+		freq = ieee80211_channel_to_frequency(rxChan,
+						      NL80211_BAND_2GHZ);
+	else
+		freq = ieee80211_channel_to_frequency(rxChan,
+						      NL80211_BAND_5GHZ);
+
+	if (hdd_is_qos_action_frame(pb_frames, frm_len))
+		sme_update_dsc_pto_up_mapping(hdd_ctx->mac_handle,
+					      adapter->dscp_to_up_map,
+					      adapter->session_id);
+
+	/* Indicate Frame Over Normal Interface */
+	hdd_debug("Indicate Frame over NL80211 sessionid : %d, idx :%d",
+		   adapter->session_id, adapter->dev->ifindex);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
+	cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr,
+		 freq, rxRssi * 100, pb_frames,
+			 frm_len, NL80211_RXMGMT_FLAG_ANSWERED);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
+	cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr,
+			freq, rxRssi * 100, pb_frames,
+			 frm_len, NL80211_RXMGMT_FLAG_ANSWERED,
+			 GFP_ATOMIC);
+#else
+	cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr, freq,
+			rxRssi * 100,
+			pb_frames, frm_len, GFP_ATOMIC);
+#endif /* LINUX_VERSION_CODE */
+}
+
+int wlan_hdd_set_power_save(struct hdd_adapter *adapter,
+	struct p2p_ps_config *ps_config)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+
+	if (!adapter || !ps_config) {
+		hdd_err("null param, adapter:%pK, ps_config:%pK",
+			adapter, ps_config);
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	psoc = hdd_ctx->psoc;
+	if (!psoc) {
+		hdd_err("psoc is null");
+		return -EINVAL;
+	}
+
+	hdd_debug("opp ps:%d, ct window:%d, duration:%d, interval:%d, count:%d, single noa duration:%d, ps selection:%d, vdev id:%d",
+		ps_config->opp_ps, ps_config->ct_window,
+		ps_config->duration, ps_config->interval,
+		ps_config->count, ps_config->single_noa_duration,
+		ps_config->ps_selection, ps_config->vdev_id);
+
+	status = ucfg_p2p_set_ps(psoc, ps_config);
+	hdd_debug("p2p set power save, status:%d", status);
+
+	return qdf_status_to_os_return(status);
+}
+
+/**
+ * wlan_hdd_update_mcc_adaptive_scheduler() - Function to update
+ * MAS value to FW
+ * @adapter:            adapter object data
+ * @is_enable:          0-Disable, 1-Enable MAS
+ *
+ * This function passes down the value of MAS to UMAC
+ *
+ * Return: 0 for success else non zero
+ *
+ */
+static int32_t wlan_hdd_update_mcc_adaptive_scheduler(
+		struct hdd_adapter *adapter, bool is_enable)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	uint8_t enable_mcc_adaptive_sch = 0;
+
+	if (hdd_ctx == NULL) {
+		hdd_err("HDD context is null");
+		return -EINVAL;
+	}
+
+	hdd_info("enable/disable MAS :%d", is_enable);
+	ucfg_policy_mgr_get_mcc_adaptive_sch(hdd_ctx->psoc,
+					     &enable_mcc_adaptive_sch);
+	if (enable_mcc_adaptive_sch) {
+		/* Todo check where to set the MCC apative SCHED for read */
+
+		if (QDF_STATUS_SUCCESS != sme_set_mas(is_enable)) {
+			hdd_err("Failed to enable/disable MAS");
+			return -EAGAIN;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_update_mcc_p2p_quota() - Function to Update P2P
+ * quota to FW
+ * @adapter:            Pointer to HDD adapter
+ * @is_set:             0-reset, 1-set
+ *
+ * This function passes down the value of MAS to UMAC
+ *
+ * Return: none
+ *
+ */
+static void wlan_hdd_update_mcc_p2p_quota(struct hdd_adapter *adapter,
+					  bool is_set)
+{
+
+	hdd_info("Set/reset P2P quota: %d", is_set);
+	if (is_set) {
+		if (adapter->device_mode == QDF_STA_MODE)
+			wlan_hdd_set_mcc_p2p_quota(adapter,
+				100 - HDD_DEFAULT_MCC_P2P_QUOTA
+			);
+		else if (adapter->device_mode == QDF_P2P_GO_MODE)
+			wlan_hdd_go_set_mcc_p2p_quota(adapter,
+				HDD_DEFAULT_MCC_P2P_QUOTA);
+		else
+			wlan_hdd_set_mcc_p2p_quota(adapter,
+				HDD_DEFAULT_MCC_P2P_QUOTA);
+	} else {
+		if (adapter->device_mode == QDF_P2P_GO_MODE)
+			wlan_hdd_go_set_mcc_p2p_quota(adapter,
+				HDD_RESET_MCC_P2P_QUOTA);
+		else
+			wlan_hdd_set_mcc_p2p_quota(adapter,
+				HDD_RESET_MCC_P2P_QUOTA);
+	}
+}
+
+int32_t wlan_hdd_set_mas(struct hdd_adapter *adapter, uint8_t mas_value)
+{
+	int32_t ret = 0;
+
+	if (!adapter) {
+		hdd_err("Adapter is NULL");
+		return -EINVAL;
+	}
+
+	if (mas_value) {
+		hdd_info("Miracast is ON. Disable MAS and configure P2P quota");
+		ret = wlan_hdd_update_mcc_adaptive_scheduler(
+			adapter, false);
+		if (0 != ret) {
+			hdd_err("Failed to disable MAS");
+			goto done;
+		}
+
+		/* Config p2p quota */
+		wlan_hdd_update_mcc_p2p_quota(adapter, true);
+	} else {
+		hdd_info("Miracast is OFF. Enable MAS and reset P2P quota");
+		wlan_hdd_update_mcc_p2p_quota(adapter, false);
+
+		ret = wlan_hdd_update_mcc_adaptive_scheduler(
+			adapter, true);
+		if (0 != ret) {
+			hdd_err("Failed to enable MAS");
+			goto done;
+		}
+	}
+
+done:
+	return ret;
+}
+
+/**
+ * set_first_connection_operating_channel() - Function to set
+ * first connection oerating channel
+ * @adapter:   adapter data
+ * @set_value: Quota value for the interface
+ * @dev_mode:  Device mode
+ * This function is used to set the first adapter operating
+ * channel
+ *
+ * Return: operating channel updated in set value
+ *
+ */
+static uint32_t set_first_connection_operating_channel(
+		struct hdd_context *hdd_ctx, uint32_t set_value,
+		enum QDF_OPMODE dev_mode)
+{
+	uint8_t operating_channel;
+
+	operating_channel = hdd_get_operating_channel(
+					hdd_ctx, dev_mode);
+	if (!operating_channel) {
+		hdd_err(" First adpter operating channel is invalid");
+		return -EINVAL;
+	}
+
+	hdd_info("First connection channel No.:%d and quota:%dms",
+			operating_channel, set_value);
+	/* Move the time quota for first channel to bits 15-8 */
+	set_value = set_value << 8;
+
+	/*
+	 * Store the channel number of 1st channel at bits 7-0
+	 * of the bit vector
+	 */
+	return set_value | operating_channel;
+}
+
+/**
+ * set_second_connection_operating_channel() - Function to set
+ * second connection oerating channel
+ * @adapter:   adapter data
+ * @set_value: Quota value for the interface
+ * @vdev_id:  vdev id
+ *
+ * This function is used to set the first adapter operating
+ * channel
+ *
+ * Return: operating channel updated in set value
+ *
+ */
+static uint32_t set_second_connection_operating_channel(
+		struct hdd_context *hdd_ctx, uint32_t set_value,
+		uint8_t vdev_id)
+{
+	uint8_t operating_channel;
+
+	operating_channel = policy_mgr_get_mcc_operating_channel(
+		hdd_ctx->psoc, vdev_id);
+
+	if (operating_channel == 0) {
+		hdd_err("Second adapter operating channel is invalid");
+		return -EINVAL;
+	}
+
+	hdd_info("Second connection channel No.:%d and quota:%dms",
+			operating_channel, set_value);
+	/*
+	 * Now move the time quota and channel number of the
+	 * 1st adapter to bits 23-16 and bits 15-8 of the bit
+	 * vector, respectively.
+	 */
+	set_value = set_value << 8;
+
+	/*
+	 * Set the channel number for 2nd MCC vdev at bits
+	 * 7-0 of set_value
+	 */
+	return set_value | operating_channel;
+}
+
+/**
+ * wlan_hdd_set_mcc_p2p_quota() - Function to set quota for P2P
+ * @psoc: PSOC object information
+ * @set_value:          Qouta value for the interface
+ * @operating_channel   First adapter operating channel
+ * @vdev_id             vdev id
+ *
+ * This function is used to set the quota for P2P cases
+ *
+ * Return: Configuration message posting status, SUCCESS or Fail
+ *
+ */
+int wlan_hdd_set_mcc_p2p_quota(struct hdd_adapter *adapter,
+			       uint32_t set_value)
+{
+	int32_t ret = 0;
+	uint32_t concurrent_state;
+	struct hdd_context *hdd_ctx;
+
+	if (!adapter) {
+		hdd_err("Invalid adapter");
+		return -EFAULT;
+	}
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (hdd_ctx == NULL) {
+		hdd_err("HDD context is null");
+		return -EINVAL;
+	}
+
+	concurrent_state = policy_mgr_get_concurrency_mode(
+		hdd_ctx->psoc);
+	/*
+	 * Check if concurrency mode is active.
+	 * Need to modify this code to support MCC modes other than STA/P2P
+	 */
+	if ((concurrent_state ==
+	     (QDF_STA_MASK | QDF_P2P_CLIENT_MASK)) ||
+	    (concurrent_state == (QDF_STA_MASK | QDF_P2P_GO_MASK))) {
+		hdd_info("STA & P2P are both enabled");
+
+		/*
+		 * The channel numbers for both adapters and the time
+		 * quota for the 1st adapter, i.e., one specified in cmd
+		 * are formatted as a bit vector then passed on to WMA
+		 * +***********************************************************+
+		 * |bit 31-24  | bit 23-16  |   bits 15-8   |   bits 7-0       |
+		 * |  Unused   | Quota for  | chan. # for   |   chan. # for    |
+		 * |           | 1st chan.  | 1st chan.     |   2nd chan.      |
+		 * +***********************************************************+
+		 */
+
+		set_value = set_first_connection_operating_channel(
+			hdd_ctx, set_value, adapter->device_mode);
+
+
+		set_value = set_second_connection_operating_channel(
+			hdd_ctx, set_value, adapter->session_id);
+
+
+		ret = wlan_hdd_send_p2p_quota(adapter, set_value);
+	} else {
+		hdd_info("MCC is not active. Exit w/o setting latency");
+	}
+
+	return ret;
+}
+
+int wlan_hdd_go_set_mcc_p2p_quota(struct hdd_adapter *hostapd_adapter,
+				  uint32_t set_value)
+{
+	return wlan_hdd_set_mcc_p2p_quota(hostapd_adapter, set_value);
+}
+
+void wlan_hdd_set_mcc_latency(struct hdd_adapter *adapter, int set_value)
+{
+	uint32_t concurrent_state;
+	struct hdd_context *hdd_ctx;
+
+	if (!adapter) {
+		hdd_err("Invalid adapter");
+		return;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (hdd_ctx == NULL) {
+		hdd_err("HDD context is null");
+		return;
+	}
+
+	concurrent_state = policy_mgr_get_concurrency_mode(
+		hdd_ctx->psoc);
+	/**
+	 * Check if concurrency mode is active.
+	 * Need to modify this code to support MCC modes other than STA/P2P
+	 */
+	if ((concurrent_state ==
+	     (QDF_STA_MASK | QDF_P2P_CLIENT_MASK)) ||
+	    (concurrent_state == (QDF_STA_MASK | QDF_P2P_GO_MASK))) {
+		hdd_info("STA & P2P are both enabled");
+		/*
+		 * The channel number and latency are formatted in
+		 * a bit vector then passed on to WMA layer.
+		 * +**********************************************+
+		 * |bits 31-16 |      bits 15-8    |  bits 7-0    |
+		 * |  Unused   | latency - Chan. 1 |  channel no. |
+		 * +**********************************************+
+		 */
+		set_value = set_first_connection_operating_channel(
+			hdd_ctx, set_value, adapter->device_mode);
+
+		wlan_hdd_send_mcc_latency(adapter, set_value);
+	} else {
+		hdd_info("MCC is not active. Exit w/o setting latency");
+	}
+}
diff --git a/core/hdd/src/wlan_hdd_p2p_listen_offload.c b/core/hdd/src/wlan_hdd_p2p_listen_offload.c
new file mode 100644
index 0000000..a1ff9db
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_p2p_listen_offload.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_vendor_p2p_listen_offload.c
+ *
+ * WLAN p2p listen offload functions
+ *
+ */
+
+#include <wlan_hdd_includes.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <wlan_hdd_p2p.h>
+#include <wlan_p2p_ucfg_api.h>
+#include <wlan_hdd_p2p_listen_offload.h>
+
+/* P2P listen offload device types parameters length in bytes */
+#define P2P_LO_MAX_REQ_DEV_TYPE_COUNT (10)
+#define P2P_LO_WPS_DEV_TYPE_LEN (8)
+#define P2P_LO_DEV_TYPE_MAX_LEN \
+	(P2P_LO_MAX_REQ_DEV_TYPE_COUNT * P2P_LO_WPS_DEV_TYPE_LEN)
+
+static const struct nla_policy
+p2p_listen_offload_policy[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CHANNEL] = { .type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_PERIOD] = { .type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_INTERVAL] = {
+							.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_COUNT] = { .type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_DEVICE_TYPES] = {
+					.type = NLA_BINARY,
+					.len = P2P_LO_DEV_TYPE_MAX_LEN },
+	[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_VENDOR_IE] = {
+					.type = NLA_BINARY,
+					.len = MAX_GENIE_LEN },
+	[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CTRL_FLAG] = {
+					.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CHANNEL] = { .type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON] = {
+						.type = NLA_U8 },
+};
+
+/**
+ * wlan_hdd_listen_offload_start() - hdd set listen offload start
+ * @adapter: adapter context
+ * @params: listen offload parameters
+ *
+ * This function sets listen offload start parameters.
+ *
+ * Return: 0 on success, others on failure
+ */
+static int wlan_hdd_listen_offload_start(struct hdd_adapter *adapter,
+					 struct sir_p2p_lo_start *params)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct p2p_lo_start lo_start;
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+
+	if (!adapter || !params) {
+		hdd_err("null param, adapter:%pK, params:%pK",
+			adapter, params);
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	psoc = hdd_ctx->psoc;
+	if (!psoc) {
+		hdd_err("psoc is null");
+		return -EINVAL;
+	}
+
+	lo_start.vdev_id = params->vdev_id;
+	lo_start.ctl_flags = params->ctl_flags;
+	lo_start.freq = params->freq;
+	lo_start.period = params->period;
+	lo_start.interval = params->interval;
+	lo_start.count = params->count;
+	lo_start.device_types = params->device_types;
+	lo_start.dev_types_len = params->dev_types_len;
+	lo_start.probe_resp_tmplt = params->probe_resp_tmplt;
+	lo_start.probe_resp_len = params->probe_resp_len;
+
+	status = ucfg_p2p_lo_start(psoc, &lo_start);
+	hdd_debug("p2p listen offload start, status:%d", status);
+
+	return qdf_status_to_os_return(status);
+}
+
+/**
+ * __wlan_hdd_cfg80211_p2p_lo_start () - start P2P Listen Offload
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * This function is to process the p2p listen offload start vendor
+ * command. It parses the input parameters and invoke WMA API to
+ * send the command to firmware.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_p2p_lo_start(struct wiphy *wiphy,
+					    struct wireless_dev *wdev,
+					    const void *data,
+					    int data_len)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX + 1];
+	struct sir_p2p_lo_start params;
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	if ((adapter->device_mode != QDF_P2P_DEVICE_MODE) &&
+	    (adapter->device_mode != QDF_P2P_CLIENT_MODE) &&
+	    (adapter->device_mode != QDF_P2P_GO_MODE)) {
+		hdd_err("Invalid device mode %d", adapter->device_mode);
+		return -EINVAL;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb,
+				    QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX,
+				    data, data_len,
+				    p2p_listen_offload_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	memset(&params, 0, sizeof(params));
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CTRL_FLAG])
+		params.ctl_flags = 1;  /* set to default value */
+	else
+		params.ctl_flags = nla_get_u32(tb
+			[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CTRL_FLAG]);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CHANNEL] ||
+	    !tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_PERIOD] ||
+	    !tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_INTERVAL] ||
+	    !tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_COUNT] ||
+	    !tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_DEVICE_TYPES] ||
+	    !tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_VENDOR_IE]) {
+		hdd_err("Attribute parsing failed");
+		return -EINVAL;
+	}
+
+	params.vdev_id = adapter->session_id;
+	params.freq = nla_get_u32(tb
+		[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CHANNEL]);
+	if ((params.freq != 2412) && (params.freq != 2437) &&
+	    (params.freq != 2462)) {
+		hdd_err("Invalid listening channel: %d", params.freq);
+		return -EINVAL;
+	}
+
+	params.period = nla_get_u32(tb
+		[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_PERIOD]);
+	if (!((params.period > 0) && (params.period < UINT_MAX))) {
+		hdd_err("Invalid period: %d", params.period);
+		return -EINVAL;
+	}
+
+	params.interval = nla_get_u32(tb
+		[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_INTERVAL]);
+	if (!((params.interval > 0) && (params.interval < UINT_MAX))) {
+		hdd_err("Invalid interval: %d", params.interval);
+		return -EINVAL;
+	}
+
+	params.count = nla_get_u32(tb
+		[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_COUNT]);
+	if (!((params.count >= 0) && (params.count < UINT_MAX))) {
+		hdd_err("Invalid count: %d", params.count);
+		return -EINVAL;
+	}
+
+	params.device_types = nla_data(tb
+		[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_DEVICE_TYPES]);
+	if (!params.device_types) {
+		hdd_err("Invalid device types");
+		return -EINVAL;
+	}
+
+	params.dev_types_len = nla_len(tb
+		[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_DEVICE_TYPES]);
+	/* device type length has to be multiple of P2P_LO_WPS_DEV_TYPE_LEN */
+	if (0 != (params.dev_types_len % P2P_LO_WPS_DEV_TYPE_LEN)) {
+		hdd_err("Invalid device type length: %d", params.dev_types_len);
+		return -EINVAL;
+	}
+
+	params.probe_resp_tmplt = nla_data(tb
+		[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_VENDOR_IE]);
+	if (!params.probe_resp_tmplt) {
+		hdd_err("Invalid probe response template");
+		return -EINVAL;
+	}
+
+	/*
+	 * IEs minimum length should be 2 bytes: 1 byte for element id
+	 * and 1 byte for element id length.
+	 */
+	params.probe_resp_len = nla_len(tb
+		[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_VENDOR_IE]);
+	if (params.probe_resp_len < MIN_GENIE_LEN) {
+		hdd_err("Invalid probe resp template length: %d",
+			params.probe_resp_len);
+		return -EINVAL;
+	}
+
+	hdd_debug("P2P LO params: freq=%d, period=%d, interval=%d, count=%d",
+		  params.freq, params.period, params.interval, params.count);
+
+	return wlan_hdd_listen_offload_start(adapter, &params);
+}
+
+int wlan_hdd_cfg80211_p2p_lo_start(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data,
+				   int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_p2p_lo_start(wiphy, wdev,
+					       data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_listen_offload_stop() - hdd set listen offload stop
+ * @adapter: adapter context
+ *
+ * This function sets listen offload stop parameters.
+ *
+ * Return: 0 on success, others on failure
+ */
+static int wlan_hdd_listen_offload_stop(struct hdd_adapter *adapter)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct hdd_context *hdd_ctx;
+	uint32_t vdev_id;
+	QDF_STATUS status;
+
+	if (!adapter) {
+		hdd_err("adapter is null, adapter:%pK", adapter);
+		return -EINVAL;
+	}
+
+	vdev_id = (uint32_t)adapter->session_id;
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	psoc = hdd_ctx->psoc;
+	if (!psoc) {
+		hdd_err("psoc is null");
+		return -EINVAL;
+	}
+
+	status = ucfg_p2p_lo_stop(psoc, vdev_id);
+	hdd_debug("p2p listen offload stop, status:%d", status);
+
+	return qdf_status_to_os_return(status);
+}
+
+/**
+ * __wlan_hdd_cfg80211_p2p_lo_stop () - stop P2P Listen Offload
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * This function is to process the p2p listen offload stop vendor
+ * command. It invokes WMA API to send command to firmware.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_p2p_lo_stop(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data,
+					   int data_len)
+{
+	struct hdd_adapter *adapter;
+	struct net_device *dev = wdev->netdev;
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	if ((adapter->device_mode != QDF_P2P_DEVICE_MODE) &&
+	    (adapter->device_mode != QDF_P2P_CLIENT_MODE) &&
+	    (adapter->device_mode != QDF_P2P_GO_MODE)) {
+		hdd_err("Invalid device mode");
+		return -EINVAL;
+	}
+
+	return wlan_hdd_listen_offload_stop(adapter);
+}
+
+int wlan_hdd_cfg80211_p2p_lo_stop(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  const void *data,
+				  int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_p2p_lo_stop(wiphy, wdev,
+					      data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
diff --git a/core/hdd/src/wlan_hdd_p2p_listen_offload.h b/core/hdd/src/wlan_hdd_p2p_listen_offload.h
new file mode 100644
index 0000000..f039aca
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_p2p_listen_offload.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __WLAN_HDD_P2P_LISTEN_OFFLOAD_H
+#define __WLAN_HDD_P2P_LISTEN_OFFLOAD_H
+
+/**
+ * DOC: wlan_hdd_p2p_listen_offload_h
+ *
+ * WLAN Host Device Driver p2p listen offload API specification
+ */
+
+#ifdef FEATURE_P2P_LISTEN_OFFLOAD
+/**
+ * __wlan_hdd_cfg80211_p2p_lo_start() - start P2P Listen Offload
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * This function is to process the p2p listen offload start vendor
+ * command. It parses the input parameters and invoke WMA API to
+ * send the command to firmware.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_p2p_lo_start(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data,
+				   int data_len);
+
+/**
+ * wlan_hdd_cfg80211_p2p_lo_stop() - stop P2P Listen Offload
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * This function inovkes internal __wlan_hdd_cfg80211_p2p_lo_stop()
+ * to process p2p listen offload stop vendor command.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_p2p_lo_stop(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  const void *data,
+				  int data_len);
+
+#define FEATURE_P2P_LISTEN_OFFLOAD_VENDOR_COMMANDS			\
+{									\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,			\
+	.info.subcmd =							\
+		QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_START,	\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |				\
+			WIPHY_VENDOR_CMD_NEED_NETDEV |			\
+			WIPHY_VENDOR_CMD_NEED_RUNNING,			\
+	.doit = wlan_hdd_cfg80211_p2p_lo_start				\
+},									\
+{									\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,			\
+	.info.subcmd =							\
+		QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP,	\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |				\
+			WIPHY_VENDOR_CMD_NEED_NETDEV |			\
+			WIPHY_VENDOR_CMD_NEED_RUNNING,			\
+	.doit = wlan_hdd_cfg80211_p2p_lo_stop				\
+},
+#else /* FEATURE_P2P_LISTEN_OFFLOAD */
+#define FEATURE_P2P_LISTEN_OFFLOAD_VENDOR_COMMANDS
+#endif /* FEATURE_P2P_LISTEN_OFFLOAD */
+
+#endif /* __WLAN_HDD_P2P_LISTEN_OFFLOAD_H */
+
diff --git a/core/hdd/src/wlan_hdd_packet_filter.c b/core/hdd/src/wlan_hdd_packet_filter.c
new file mode 100644
index 0000000..c1d728d
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_packet_filter.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2017-2018 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: wlan_hdd_packet_filter.c
+ *
+ *  WLAN Host Device Driver implementation
+ *
+ */
+
+/* Include Files */
+#include "wlan_hdd_packet_filter_api.h"
+#include "wlan_hdd_packet_filter_rules.h"
+
+int hdd_enable_default_pkt_filters(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx;
+	uint8_t filters = 0, i = 0, filter_id = 1;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (hdd_ctx == NULL) {
+		hdd_err("HDD context is Null!!!");
+		return -EINVAL;
+	}
+	if (hdd_ctx->user_configured_pkt_filter_rules) {
+		hdd_info("user has defined pkt filter run hence skipping default packet filter rule");
+		return 0;
+	}
+
+	filters = ucfg_pmo_get_pkt_filter_bitmap(hdd_ctx->psoc);
+
+	while (filters != 0) {
+		if (filters & 0x1) {
+			hdd_err("setting filter[%d], of id = %d",
+				i+1, filter_id);
+			packet_filter_default_rules[i].filter_id = filter_id;
+			wlan_hdd_set_filter(hdd_ctx,
+					    &packet_filter_default_rules[i],
+					    adapter->session_id);
+			filter_id++;
+		}
+		filters = filters >> 1;
+		i++;
+	}
+
+	return 0;
+}
+
+int hdd_disable_default_pkt_filters(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx;
+	uint8_t filters = 0, i = 0, filter_id = 1;
+
+	struct pkt_filter_cfg packet_filter_default_rules = {0};
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (hdd_ctx == NULL) {
+		hdd_err("HDD context is Null!!!");
+		return -EINVAL;
+	}
+
+	if (hdd_ctx->user_configured_pkt_filter_rules) {
+		hdd_info("user has defined pkt filter run hence skipping default packet filter rule");
+		return 0;
+	}
+
+	filters = ucfg_pmo_get_pkt_filter_bitmap(hdd_ctx->psoc);
+
+	while (filters != 0) {
+		if (filters & 0x1) {
+			hdd_err("Clearing filter[%d], of id = %d",
+				i+1, filter_id);
+			packet_filter_default_rules.filter_action =
+						HDD_RCV_FILTER_CLEAR;
+			packet_filter_default_rules.filter_id = filter_id;
+			wlan_hdd_set_filter(hdd_ctx,
+					    &packet_filter_default_rules,
+					    adapter->session_id);
+			filter_id++;
+		}
+		filters = filters >> 1;
+		i++;
+	}
+
+	return 0;
+}
+
+int wlan_hdd_set_filter(struct hdd_context *hdd_ctx,
+				struct pkt_filter_cfg *request,
+				uint8_t sessionId)
+{
+	struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req = NULL;
+	struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param = NULL;
+	int i = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (hdd_ctx->config->disablePacketFilter) {
+		hdd_warn("Packet filtering disabled in ini");
+		return 0;
+	}
+
+	/* Debug display of request components. */
+	hdd_debug("Packet Filter Request : FA %d params %d",
+		request->filter_action, request->num_params);
+
+	switch (request->filter_action) {
+	case HDD_RCV_FILTER_SET:
+		hdd_debug("Set Packet Filter Request for Id: %d",
+			request->filter_id);
+
+		pmo_set_pkt_fltr_req =
+			qdf_mem_malloc(sizeof(*pmo_set_pkt_fltr_req));
+		if (!pmo_set_pkt_fltr_req) {
+			hdd_err("unable to allocate pmo_set_pkt_fltr_req");
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		pmo_set_pkt_fltr_req->filter_id = request->filter_id;
+		if (request->num_params >= HDD_MAX_CMP_PER_PACKET_FILTER) {
+			hdd_err("Number of Params exceed Max limit %d",
+				request->num_params);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		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 = 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;
+			pmo_set_pkt_fltr_req->params_data[i].compare_flag =
+				request->params_data[i].compare_flag;
+			pmo_set_pkt_fltr_req->params_data[i].data_offset =
+				request->params_data[i].data_offset;
+			pmo_set_pkt_fltr_req->params_data[i].data_length =
+				request->params_data[i].data_length;
+			pmo_set_pkt_fltr_req->params_data[i].reserved = 0;
+
+			if (request->params_data[i].data_offset >
+			    SIR_MAX_FILTER_TEST_DATA_OFFSET) {
+				hdd_err("Invalid data offset %u for param %d (max = %d)",
+					request->params_data[i].data_offset,
+					i,
+					SIR_MAX_FILTER_TEST_DATA_OFFSET);
+				status = QDF_STATUS_E_INVAL;
+				goto out;
+			}
+
+			if (request->params_data[i].data_length >
+				SIR_MAX_FILTER_TEST_DATA_LEN) {
+				hdd_err("Error invalid data length %d",
+					request->params_data[i].data_length);
+				status = QDF_STATUS_E_INVAL;
+				goto out;
+			}
+
+			hdd_debug("Proto %d Comp Flag %d Filter Type %d",
+				request->params_data[i].protocol_layer,
+				request->params_data[i].compare_flag,
+				pmo_set_pkt_fltr_req->filter_type);
+
+			hdd_debug("Data Offset %d Data Len %d",
+				request->params_data[i].data_offset,
+				request->params_data[i].data_length);
+
+			if (sizeof(
+			    pmo_set_pkt_fltr_req->params_data[i].compare_data)
+				< (request->params_data[i].data_length)) {
+				hdd_err("Error invalid data length %d",
+					request->params_data[i].data_length);
+				status = QDF_STATUS_E_INVAL;
+				goto out;
+			}
+
+			memcpy(
+			    &pmo_set_pkt_fltr_req->params_data[i].compare_data,
+			       request->params_data[i].compare_data,
+			       request->params_data[i].data_length);
+			memcpy(&pmo_set_pkt_fltr_req->params_data[i].data_mask,
+			       request->params_data[i].data_mask,
+			       request->params_data[i].data_length);
+
+			hdd_debug("CData %d CData %d CData %d CData %d CData %d CData %d",
+				request->params_data[i].compare_data[0],
+				request->params_data[i].compare_data[1],
+				request->params_data[i].compare_data[2],
+				request->params_data[i].compare_data[3],
+				request->params_data[i].compare_data[4],
+				request->params_data[i].compare_data[5]);
+
+			hdd_debug("MData %d MData %d MData %d MData %d MData %d MData %d",
+				request->params_data[i].data_mask[0],
+				request->params_data[i].data_mask[1],
+				request->params_data[i].data_mask[2],
+				request->params_data[i].data_mask[3],
+				request->params_data[i].data_mask[4],
+				request->params_data[i].data_mask[5]);
+		}
+
+
+		status= ucfg_pmo_set_pkt_filter(hdd_ctx->psoc,
+						pmo_set_pkt_fltr_req,
+						sessionId);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Failure to execute Set Filter");
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+
+		break;
+
+	case HDD_RCV_FILTER_CLEAR:
+		hdd_debug("Clear Packet Filter Request for Id: %d",
+			request->filter_id);
+
+		pmo_clr_pkt_fltr_param = qdf_mem_malloc(
+					sizeof(*pmo_clr_pkt_fltr_param));
+		if (!pmo_clr_pkt_fltr_param) {
+			hdd_err("unable to allocate pmo_clr_pkt_fltr_param");
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		pmo_clr_pkt_fltr_param->filter_id = request->filter_id;
+		status = ucfg_pmo_clear_pkt_filter(hdd_ctx->psoc,
+						   pmo_clr_pkt_fltr_param,
+						   sessionId);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Failure to execute Clear Filter");
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		break;
+
+	default:
+		hdd_err("Packet Filter Request: Invalid %d",
+		       request->filter_action);
+		return -EINVAL;
+	}
+
+out:
+	if (pmo_set_pkt_fltr_req)
+		qdf_mem_free(pmo_set_pkt_fltr_req);
+	if (pmo_clr_pkt_fltr_param)
+		qdf_mem_free(pmo_clr_pkt_fltr_param);
+
+	return status;
+}
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
new file mode 100644
index 0000000..6bdbd08
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -0,0 +1,2422 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_power.c
+ *
+ * WLAN power management functions
+ *
+ */
+
+/* Include files */
+
+#include <linux/pm.h>
+#include <linux/wait.h>
+#include <linux/cpu.h>
+#include <wlan_hdd_includes.h>
+#if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK)
+#include <linux/wakelock.h>
+#endif
+#include "qdf_types.h"
+#include "sme_api.h"
+#include <cds_api.h>
+#include <cds_sched.h>
+#include <mac_init_api.h>
+#include <wlan_qct_sys.h>
+#include <wlan_hdd_main.h>
+#include <wlan_hdd_assoc.h>
+#include <wlan_nlink_srv.h>
+#include <wlan_hdd_misc.h>
+#include <wlan_hdd_power.h>
+#include <wlan_hdd_host_offload.h>
+#include <dbglog_host.h>
+#include <wlan_hdd_trace.h>
+#include <wlan_hdd_p2p.h>
+
+#include <linux/semaphore.h>
+#include <wlan_hdd_hostapd.h>
+#include "cfg_api.h"
+
+#include <linux/inetdevice.h>
+#include <wlan_hdd_cfg.h>
+#include <wlan_hdd_scan.h>
+#include <wlan_hdd_stats.h>
+#include <wlan_hdd_cfg80211.h>
+#include <net/addrconf.h>
+#include <wlan_hdd_lpass.h>
+
+#include <wma_types.h>
+#include <ol_txrx_osif_api.h>
+#include "hif.h"
+#include "hif_unit_test_suspend.h"
+#include "sme_power_save_api.h"
+#include "wlan_policy_mgr_api.h"
+#include "cdp_txrx_flow_ctrl_v2.h"
+#include "pld_common.h"
+#include "wlan_hdd_driver_ops.h"
+#include <wlan_logging_sock_svc.h>
+#include "scheduler_api.h"
+#include "cds_utils.h"
+#include "wlan_hdd_packet_filter_api.h"
+#include "wlan_cfg80211_scan.h"
+#include <dp_txrx.h>
+#include "wlan_ipa_ucfg_api.h"
+#include <wlan_cfg80211_mc_cp_stats.h>
+#include "wlan_p2p_ucfg_api.h"
+#include "wlan_mlme_ucfg_api.h"
+
+/* Preprocessor definitions and constants */
+#ifdef QCA_WIFI_NAPIER_EMULATION
+#define HDD_SSR_BRING_UP_TIME 3000000
+#else
+#define HDD_SSR_BRING_UP_TIME 30000
+#endif
+
+/* Type declarations */
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void hdd_wlan_suspend_resume_event(uint8_t state)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(suspend_state, struct host_event_suspend);
+	qdf_mem_zero(&suspend_state, sizeof(suspend_state));
+
+	suspend_state.state = state;
+	WLAN_HOST_DIAG_EVENT_REPORT(&suspend_state, EVENT_WLAN_SUSPEND_RESUME);
+}
+
+/**
+ * hdd_wlan_offload_event()- send offloads event
+ * @type: offload type
+ * @state: enabled or disabled
+ *
+ * This Function send offloads enable/disable diag event
+ *
+ * Return: void.
+ */
+
+void hdd_wlan_offload_event(uint8_t type, uint8_t state)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(host_offload, struct host_event_offload_req);
+	qdf_mem_zero(&host_offload, sizeof(host_offload));
+
+	host_offload.offload_type = type;
+	host_offload.state = state;
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&host_offload, EVENT_WLAN_OFFLOAD_REQ);
+}
+#endif
+
+#ifdef QCA_CONFIG_SMP
+
+/* timeout in msec to wait for RX_THREAD to suspend */
+#define HDD_RXTHREAD_SUSPEND_TIMEOUT 200
+
+void wlan_hdd_rx_thread_resume(struct hdd_context *hdd_ctx)
+{
+	if (hdd_ctx->is_ol_rx_thread_suspended) {
+		cds_resume_rx_thread();
+		hdd_ctx->is_ol_rx_thread_suspended = false;
+	}
+}
+
+int wlan_hdd_rx_thread_suspend(struct hdd_context *hdd_ctx)
+{
+	p_cds_sched_context cds_sched_context = get_cds_sched_ctxt();
+	int rc;
+
+	if (!cds_sched_context)
+		return 0;
+
+	/* Suspend tlshim rx thread */
+	set_bit(RX_SUSPEND_EVENT, &cds_sched_context->ol_rx_event_flag);
+	wake_up_interruptible(&cds_sched_context->ol_rx_wait_queue);
+	rc = wait_for_completion_timeout(&cds_sched_context->
+					 ol_suspend_rx_event,
+					 msecs_to_jiffies
+					 (HDD_RXTHREAD_SUSPEND_TIMEOUT)
+					);
+	if (!rc) {
+		clear_bit(RX_SUSPEND_EVENT,
+			  &cds_sched_context->ol_rx_event_flag);
+		hdd_err("Failed to stop tl_shim rx thread");
+		return -EINVAL;
+	}
+	hdd_ctx->is_ol_rx_thread_suspended = true;
+
+	return 0;
+}
+#endif /* QCA_CONFIG_SMP */
+
+/**
+ * hdd_enable_gtk_offload() - enable GTK offload
+ * @adapter: pointer to the adapter
+ *
+ * Central function to enable GTK offload.
+ *
+ * Return: nothing
+ */
+static void hdd_enable_gtk_offload(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+
+	status = ucfg_pmo_enable_gtk_offload_in_fwr(adapter->vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_info("Failed to enable gtk offload");
+}
+
+/**
+ * hdd_disable_gtk_offload() - disable GTK offload
+ * @adapter:   pointer to the adapter
+ *
+ * Central function to disable GTK offload.
+ *
+ * Return: nothing
+ */
+static void hdd_disable_gtk_offload(struct hdd_adapter *adapter)
+{
+	struct pmo_gtk_rsp_req gtk_rsp_request;
+	QDF_STATUS status;
+
+	/* ensure to get gtk rsp first before disable it*/
+	gtk_rsp_request.callback = wlan_hdd_cfg80211_update_replay_counter_cb;
+
+	/* Passing as void* as PMO does not know legacy HDD adapter type */
+	gtk_rsp_request.callback_context = (void *)adapter;
+
+	status = ucfg_pmo_get_gtk_rsp(adapter->vdev, &gtk_rsp_request);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to send get gtk rsp status:%d", status);
+		return;
+	}
+
+	hdd_debug("send get_gtk_rsp successful");
+	status = ucfg_pmo_disable_gtk_offload_in_fwr(adapter->vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_info("Failed to disable gtk offload");
+}
+
+#ifdef WLAN_NS_OFFLOAD
+/**
+ * __wlan_hdd_ipv6_changed() - IPv6 notifier callback function
+ * @nb: notifier block that was registered with the kernel
+ * @data: (unused) generic data that was registered with the kernel
+ * @arg: (unused) generic argument that was registered with the kernel
+ *
+ * This is a callback function that is registered with the kernel via
+ * register_inet6addr_notifier() which allows the driver to be
+ * notified when there is an IPv6 address change.
+ *
+ * Return: NOTIFY_DONE to indicate we don't care what happens with
+ *	other callbacks
+ */
+static int __wlan_hdd_ipv6_changed(struct notifier_block *nb,
+				   unsigned long data, void *arg)
+{
+	struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
+	struct net_device *ndev = ifa->idev->dev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	struct hdd_context *hdd_ctx;
+	int errno;
+
+	hdd_enter_dev(ndev);
+
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		goto exit;
+
+	if (adapter->dev == ndev &&
+	    (adapter->device_mode == QDF_STA_MODE ||
+	     adapter->device_mode == QDF_P2P_CLIENT_MODE ||
+	     adapter->device_mode == QDF_NDI_MODE)) {
+		hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+		errno = wlan_hdd_validate_context(hdd_ctx);
+		if (errno)
+			goto exit;
+
+		/* Ignore if the interface is down */
+		if (!(ndev->flags & IFF_UP)) {
+			hdd_err("Rcvd change addr request on %s(flags 0x%X)",
+				ndev->name, ndev->flags);
+			hdd_err("NETDEV Interface is down, ignoring...");
+			goto exit;
+		}
+
+		hdd_debug("invoking sme_dhcp_done_ind");
+		sme_dhcp_done_ind(hdd_ctx->mac_handle, adapter->session_id);
+		schedule_work(&adapter->ipv6_notifier_work);
+	}
+
+exit:
+	hdd_exit();
+
+	return NOTIFY_DONE;
+}
+
+int wlan_hdd_ipv6_changed(struct notifier_block *nb,
+				unsigned long data, void *arg)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_ipv6_changed(nb, data, arg);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_fill_ipv6_uc_addr() - fill IPv6 unicast addresses
+ * @idev: pointer to net device
+ * @ipv6addr: destination array to fill IPv6 addresses
+ * @ipv6addr_type: IPv6 Address type
+ * @scope_array: scope of ipv6 addr
+ * @count: number of IPv6 addresses
+ *
+ * This is the IPv6 utility function to populate unicast addresses.
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+static int hdd_fill_ipv6_uc_addr(struct inet6_dev *idev,
+				uint8_t ipv6_uc_addr[][SIR_MAC_IPV6_ADDR_LEN],
+				uint8_t *ipv6addr_type,
+				enum pmo_ns_addr_scope *scope_array,
+				uint32_t *count)
+{
+	struct inet6_ifaddr *ifa;
+	struct list_head *p;
+	uint32_t scope;
+
+	read_lock_bh(&idev->lock);
+	list_for_each(p, &idev->addr_list) {
+		if (*count >= PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) {
+			read_unlock_bh(&idev->lock);
+			return -EINVAL;
+		}
+		ifa = list_entry(p, struct inet6_ifaddr, if_list);
+		if (ifa->flags & IFA_F_DADFAILED)
+			continue;
+		scope = ipv6_addr_src_scope(&ifa->addr);
+		switch (scope) {
+		case IPV6_ADDR_SCOPE_GLOBAL:
+		case IPV6_ADDR_SCOPE_LINKLOCAL:
+			qdf_mem_copy(ipv6_uc_addr[*count], &ifa->addr.s6_addr,
+				sizeof(ifa->addr.s6_addr));
+			ipv6addr_type[*count] = PMO_IPV6_ADDR_UC_TYPE;
+			scope_array[*count] = ucfg_pmo_ns_addr_scope(scope);
+			hdd_debug("Index %d scope = %s UC-Address: %pI6",
+				*count, (scope == IPV6_ADDR_SCOPE_LINKLOCAL) ?
+				"LINK LOCAL" : "GLOBAL", ipv6_uc_addr[*count]);
+			*count += 1;
+			break;
+		default:
+			hdd_warn("The Scope %d is not supported", scope);
+		}
+	}
+
+	read_unlock_bh(&idev->lock);
+	return 0;
+}
+
+/**
+ * hdd_fill_ipv6_ac_addr() - fill IPv6 anycast addresses
+ * @idev: pointer to net device
+ * @ipv6addr: destination array to fill IPv6 addresses
+ * @ipv6addr_type: IPv6 Address type
+ * @scope_array: scope of ipv6 addr
+ * @count: number of IPv6 addresses
+ *
+ * This is the IPv6 utility function to populate anycast addresses.
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+static int hdd_fill_ipv6_ac_addr(struct inet6_dev *idev,
+				uint8_t ipv6_ac_addr[][SIR_MAC_IPV6_ADDR_LEN],
+				uint8_t *ipv6addr_type,
+				enum pmo_ns_addr_scope *scope_array,
+				uint32_t *count)
+{
+	struct ifacaddr6 *ifaca;
+	uint32_t scope;
+
+	read_lock_bh(&idev->lock);
+	for (ifaca = idev->ac_list; ifaca; ifaca = ifaca->aca_next) {
+		if (*count >= PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) {
+			read_unlock_bh(&idev->lock);
+			return -EINVAL;
+		}
+		/* For anycast addr no DAD */
+		scope = ipv6_addr_src_scope(&ifaca->aca_addr);
+		switch (scope) {
+		case IPV6_ADDR_SCOPE_GLOBAL:
+		case IPV6_ADDR_SCOPE_LINKLOCAL:
+			qdf_mem_copy(ipv6_ac_addr[*count], &ifaca->aca_addr,
+				sizeof(ifaca->aca_addr));
+			ipv6addr_type[*count] = PMO_IPV6_ADDR_AC_TYPE;
+			scope_array[*count] = ucfg_pmo_ns_addr_scope(scope);
+			hdd_debug("Index %d scope = %s AC-Address: %pI6",
+				*count, (scope == IPV6_ADDR_SCOPE_LINKLOCAL) ?
+				"LINK LOCAL" : "GLOBAL", ipv6_ac_addr[*count]);
+			*count += 1;
+			break;
+		default:
+			hdd_warn("The Scope %d is not supported", scope);
+		}
+	}
+
+	read_unlock_bh(&idev->lock);
+	return 0;
+}
+
+void hdd_enable_ns_offload(struct hdd_adapter *adapter,
+			   enum pmo_offload_trigger trigger)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	struct inet6_dev *in6_dev;
+	struct pmo_ns_req *ns_req;
+	QDF_STATUS status;
+	int errno;
+
+	hdd_enter();
+
+	if (!psoc) {
+		hdd_err("psoc is NULL");
+		goto out;
+	}
+
+	in6_dev = __in6_dev_get(adapter->dev);
+	if (NULL == in6_dev) {
+		hdd_err("IPv6 dev does not exist. Failed to request NSOffload");
+		goto out;
+	}
+
+	ns_req = qdf_mem_malloc(sizeof(*ns_req));
+	if (!ns_req)
+		goto out;
+
+	ns_req->psoc = psoc;
+	ns_req->vdev_id = adapter->session_id;
+	ns_req->trigger = trigger;
+	ns_req->count = 0;
+
+	/* Unicast Addresses */
+	errno = hdd_fill_ipv6_uc_addr(in6_dev, ns_req->ipv6_addr,
+				      ns_req->ipv6_addr_type, ns_req->scope,
+				      &ns_req->count);
+	if (errno) {
+		hdd_disable_ns_offload(adapter, trigger);
+		hdd_debug("Max supported addresses: disabling NS offload");
+		goto free_req;
+	}
+
+	/* Anycast Addresses */
+	errno = hdd_fill_ipv6_ac_addr(in6_dev, ns_req->ipv6_addr,
+				      ns_req->ipv6_addr_type, ns_req->scope,
+				      &ns_req->count);
+	if (errno) {
+		hdd_disable_ns_offload(adapter, trigger);
+		hdd_debug("Max supported addresses: disabling NS offload");
+		goto free_req;
+	}
+
+	/* cache ns request */
+	status = ucfg_pmo_cache_ns_offload_req(ns_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to cache ns request; status:%d", status);
+		goto free_req;
+	}
+
+	/* enable ns request */
+	status = ucfg_pmo_enable_ns_offload_in_fwr(adapter->vdev, trigger);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to enable ns offload; status:%d", status);
+		goto free_req;
+	}
+
+	hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD, SIR_OFFLOAD_ENABLE);
+
+free_req:
+	qdf_mem_free(ns_req);
+
+out:
+	hdd_exit();
+}
+
+void hdd_disable_ns_offload(struct hdd_adapter *adapter,
+		enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status;
+
+	hdd_enter();
+	status = ucfg_pmo_flush_ns_offload_req(adapter->vdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to flush NS Offload");
+		goto out;
+	}
+
+	status = ucfg_pmo_disable_ns_offload_in_fwr(adapter->vdev, trigger);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_err("Failed to disable NS Offload");
+	else
+		hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
+			SIR_OFFLOAD_DISABLE);
+out:
+	hdd_exit();
+
+}
+
+/**
+ * __hdd_ipv6_notifier_work_queue() - IPv6 notification work function
+ * @work: registered work item
+ *
+ * This function performs the work initially trigged by a callback
+ * from the IPv6 netdev notifier.  Since this means there has been a
+ * change in IPv6 state for the interface, the NS offload is
+ * reconfigured.
+ *
+ * Return: None
+ */
+static void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter;
+	int errno;
+
+	hdd_enter();
+
+	adapter = container_of(work, struct hdd_adapter, ipv6_notifier_work);
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		goto exit;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		goto exit;
+
+	hdd_enable_ns_offload(adapter, pmo_ipv6_change_notify);
+
+exit:
+	hdd_exit();
+}
+
+void hdd_ipv6_notifier_work_queue(struct work_struct *work)
+{
+	cds_ssr_protect(__func__);
+	__hdd_ipv6_notifier_work_queue(work);
+	cds_ssr_unprotect(__func__);
+}
+#endif /* WLAN_NS_OFFLOAD */
+
+static void hdd_enable_hw_filter(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	status = ucfg_pmo_enable_hw_filter_in_fwr(adapter->vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_info("Failed to enable hardware filter");
+
+	hdd_exit();
+}
+
+static void hdd_disable_hw_filter(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	status = ucfg_pmo_disable_hw_filter_in_fwr(adapter->vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_info("Failed to disable hardware filter");
+
+	hdd_exit();
+}
+
+void hdd_enable_host_offloads(struct hdd_adapter *adapter,
+	enum pmo_offload_trigger trigger)
+{
+	hdd_enter();
+
+	if (!ucfg_pmo_is_vdev_supports_offload(adapter->vdev)) {
+		hdd_debug("offload is not supported on vdev opmode %d",
+			  adapter->device_mode);
+		goto out;
+	}
+
+	if (!ucfg_pmo_is_vdev_connected(adapter->vdev)) {
+		hdd_debug("offload is not supported on disconnected vdevs");
+		goto out;
+	}
+
+	hdd_debug("enable offloads");
+	hdd_enable_gtk_offload(adapter);
+	hdd_enable_arp_offload(adapter, trigger);
+	hdd_enable_ns_offload(adapter, trigger);
+	hdd_enable_mc_addr_filtering(adapter, trigger);
+	hdd_enable_hw_filter(adapter);
+out:
+	hdd_exit();
+
+}
+
+void hdd_disable_host_offloads(struct hdd_adapter *adapter,
+	enum pmo_offload_trigger trigger)
+{
+	hdd_enter();
+
+	if (!ucfg_pmo_is_vdev_supports_offload(adapter->vdev)) {
+		hdd_info("offload is not supported on this vdev opmode: %d",
+				adapter->device_mode);
+			goto out;
+	}
+
+	if (!ucfg_pmo_is_vdev_connected(adapter->vdev)) {
+		hdd_info("vdev is not connected");
+		goto out;
+	}
+
+	hdd_debug("disable offloads");
+	hdd_disable_gtk_offload(adapter);
+	hdd_disable_arp_offload(adapter, trigger);
+	hdd_disable_ns_offload(adapter, trigger);
+	hdd_disable_mc_addr_filtering(adapter, trigger);
+	hdd_disable_hw_filter(adapter);
+out:
+	hdd_exit();
+
+}
+
+/**
+ * hdd_lookup_ifaddr() - Lookup interface address data by name
+ * @adapter: the adapter whose name should be searched for
+ *
+ * return in_ifaddr pointer on success, NULL for failure
+ */
+static struct in_ifaddr *hdd_lookup_ifaddr(struct hdd_adapter *adapter)
+{
+	struct in_ifaddr *ifa;
+	struct in_device *in_dev;
+
+	if (!adapter) {
+		hdd_err("adapter is null");
+		return NULL;
+	}
+
+	in_dev = __in_dev_get_rtnl(adapter->dev);
+	if (!in_dev) {
+		hdd_err("Failed to get in_device");
+		return NULL;
+	}
+
+	/* lookup address data by interface name */
+	for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
+		if (!strcmp(adapter->dev->name, ifa->ifa_label))
+			return ifa;
+	}
+
+	return NULL;
+}
+
+/**
+ * hdd_populate_ipv4_addr() - Populates the adapter's IPv4 address
+ * @adapter: the adapter whose IPv4 address is desired
+ * @ipv4_addr: the address of the array to copy the IPv4 address into
+ *
+ * return: zero for success; non-zero for failure
+ */
+static int hdd_populate_ipv4_addr(struct hdd_adapter *adapter,
+				  uint8_t *ipv4_addr)
+{
+	struct in_ifaddr *ifa;
+	int i;
+
+	if (!adapter) {
+		hdd_err("adapter is null");
+		return -EINVAL;
+	}
+
+	if (!ipv4_addr) {
+		hdd_err("ipv4_addr is null");
+		return -EINVAL;
+	}
+
+	ifa = hdd_lookup_ifaddr(adapter);
+	if (!ifa || !ifa->ifa_local) {
+		hdd_err("ipv4 address not found");
+		return -EINVAL;
+	}
+
+	/* convert u32 to byte array */
+	for (i = 0; i < 4; i++)
+		ipv4_addr[i] = (ifa->ifa_local >> i * 8) & 0xff;
+
+	return 0;
+}
+
+/**
+ * hdd_set_grat_arp_keepalive() - Enable grat APR keepalive
+ * @adapter: the HDD adapter to configure
+ *
+ * This configures gratuitous APR keepalive based on the adapter's current
+ * connection information, specifically IPv4 address and BSSID
+ *
+ * return: zero for success, non-zero for failure
+ */
+static int hdd_set_grat_arp_keepalive(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+	int exit_code;
+	struct hdd_context *hdd_ctx;
+	struct hdd_station_ctx *sta_ctx;
+	tSirKeepAliveReq req = {
+		.packetType = SIR_KEEP_ALIVE_UNSOLICIT_ARP_RSP,
+		.dest_macaddr = QDF_MAC_ADDR_BCAST_INIT,
+	};
+
+	if (!adapter) {
+		hdd_err("adapter is null");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is null");
+		return -EINVAL;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (!sta_ctx) {
+		hdd_err("sta_ctx is null");
+		return -EINVAL;
+	}
+
+	exit_code = hdd_populate_ipv4_addr(adapter, req.hostIpv4Addr);
+	if (exit_code) {
+		hdd_err("Failed to populate ipv4 address");
+		return exit_code;
+	}
+
+	/* according to RFC5227, sender/target ip address should be the same */
+	qdf_mem_copy(&req.destIpv4Addr, &req.hostIpv4Addr,
+		     sizeof(req.destIpv4Addr));
+
+	qdf_copy_macaddr(&req.bssid, &sta_ctx->conn_info.bssId);
+	ucfg_mlme_get_sta_keep_alive_period(hdd_ctx->psoc, &req.timePeriod);
+	req.sessionId = adapter->session_id;
+
+	hdd_debug("Setting gratuitous ARP keepalive; ipv4_addr:%u.%u.%u.%u",
+		 req.hostIpv4Addr[0], req.hostIpv4Addr[1],
+		 req.hostIpv4Addr[2], req.hostIpv4Addr[3]);
+
+	status = sme_set_keep_alive(hdd_ctx->mac_handle, req.sessionId, &req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to set keepalive");
+		return qdf_status_to_os_return(status);
+	}
+
+	return 0;
+}
+
+/**
+ * __hdd_ipv4_notifier_work_queue() - IPv4 notification work function
+ * @work: registered work item
+ *
+ * This function performs the work initially trigged by a callback
+ * from the IPv4 netdev notifier.  Since this means there has been a
+ * change in IPv4 state for the interface, the ARP offload is
+ * reconfigured. Also, Updates the HLP IE info with IP address info
+ * to fw if LFR3 is enabled
+ *
+ * Return: None
+ */
+static void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter;
+	int errno;
+	struct csr_roam_profile *roam_profile;
+	struct in_ifaddr *ifa;
+
+	hdd_enter();
+
+	adapter = container_of(work, struct hdd_adapter, ipv4_notifier_work);
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		goto exit;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		goto exit;
+
+	hdd_enable_arp_offload(adapter, pmo_ipv4_change_notify);
+
+	if (hdd_ctx->config->sta_keepalive_method == HDD_STA_KEEPALIVE_GRAT_ARP)
+		hdd_set_grat_arp_keepalive(adapter);
+
+	hdd_debug("FILS Roaming support: %d",
+		  hdd_ctx->is_fils_roaming_supported);
+	roam_profile = hdd_roam_profile(adapter);
+
+	ifa = hdd_lookup_ifaddr(adapter);
+	if (ifa && hdd_ctx->is_fils_roaming_supported)
+		sme_send_hlp_ie_info(hdd_ctx->mac_handle, adapter->session_id,
+				     roam_profile, ifa->ifa_local);
+exit:
+	hdd_exit();
+}
+
+void hdd_ipv4_notifier_work_queue(struct work_struct *work)
+{
+	cds_ssr_protect(__func__);
+	__hdd_ipv4_notifier_work_queue(work);
+	cds_ssr_unprotect(__func__);
+}
+
+/**
+ * __wlan_hdd_ipv4_changed() - IPv4 notifier callback function
+ * @nb: notifier block that was registered with the kernel
+ * @data: (unused) generic data that was registered with the kernel
+ * @arg: (unused) generic argument that was registered with the kernel
+ *
+ * This is a callback function that is registered with the kernel via
+ * register_inetaddr_notifier() which allows the driver to be
+ * notified when there is an IPv4 address change.
+ *
+ * Return: NOTIFY_DONE to indicate we don't care what happens with
+ *	other callbacks
+ */
+static int __wlan_hdd_ipv4_changed(struct notifier_block *nb,
+				 unsigned long data, void *arg)
+{
+	struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
+	struct net_device *ndev = ifa->ifa_dev->dev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	struct hdd_context *hdd_ctx;
+	int errno;
+
+	hdd_enter_dev(ndev);
+
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		goto exit;
+
+	if (adapter->dev == ndev &&
+	    (adapter->device_mode == QDF_STA_MODE ||
+	     adapter->device_mode == QDF_P2P_CLIENT_MODE ||
+	     adapter->device_mode == QDF_NDI_MODE)) {
+
+		hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+		errno = wlan_hdd_validate_context(hdd_ctx);
+		if (errno)
+			goto exit;
+
+		/* Ignore if the interface is down */
+		if (!(ndev->flags & IFF_UP)) {
+			hdd_err("Rcvd change addr request on %s(flags 0x%X)",
+				ndev->name, ndev->flags);
+			hdd_err("NETDEV Interface is down, ignoring...");
+			goto exit;
+		}
+		hdd_debug("invoking sme_dhcp_done_ind");
+		sme_dhcp_done_ind(hdd_ctx->mac_handle, adapter->session_id);
+
+		if (!ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc)) {
+			hdd_debug("Offload not enabled");
+			goto exit;
+		}
+
+		ifa = hdd_lookup_ifaddr(adapter);
+		if (ifa && ifa->ifa_local)
+			schedule_work(&adapter->ipv4_notifier_work);
+	}
+
+exit:
+	hdd_exit();
+
+	return NOTIFY_DONE;
+}
+
+int wlan_hdd_ipv4_changed(struct notifier_block *nb,
+			unsigned long data, void *arg)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_ipv4_changed(nb, data, arg);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_get_ipv4_local_interface() - get ipv4 local interafce from iface list
+ * @adapter: Adapter context for which ARP offload is to be configured
+ *
+ * Return:
+ *	ifa - on successful operation,
+ *	NULL - on failure of operation
+ */
+static struct in_ifaddr *hdd_get_ipv4_local_interface(
+				struct hdd_adapter *adapter)
+{
+	struct in_ifaddr **ifap = NULL;
+	struct in_ifaddr *ifa = NULL;
+	struct in_device *in_dev;
+
+	in_dev = __in_dev_get_rtnl(adapter->dev);
+	if (in_dev) {
+		for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
+			     ifap = &ifa->ifa_next) {
+			if (!strcmp(adapter->dev->name, ifa->ifa_label)) {
+				/* if match break */
+				return ifa;
+			}
+		}
+	}
+	ifa = NULL;
+
+	return ifa;
+}
+
+void hdd_enable_arp_offload(struct hdd_adapter *adapter,
+			    enum pmo_offload_trigger trigger)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+	QDF_STATUS status;
+	struct pmo_arp_req *arp_req;
+	struct in_ifaddr *ifa;
+
+	hdd_enter();
+
+	arp_req = qdf_mem_malloc(sizeof(*arp_req));
+	if (!arp_req)
+		goto out;
+
+	arp_req->psoc = psoc;
+	arp_req->vdev_id = adapter->session_id;
+	arp_req->trigger = trigger;
+
+	ifa = hdd_get_ipv4_local_interface(adapter);
+	if (!ifa || !ifa->ifa_local) {
+		hdd_info("IP Address is not assigned");
+		status = QDF_STATUS_NOT_INITIALIZED;
+		goto free_req;
+	}
+
+	arp_req->ipv4_addr = (uint32_t)ifa->ifa_local;
+
+	status = ucfg_pmo_cache_arp_offload_req(arp_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("failed to cache arp offload req; status:%d", status);
+		goto free_req;
+	}
+
+	status = ucfg_pmo_enable_arp_offload_in_fwr(adapter->vdev, trigger);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("failed arp offload config in fw; status:%d", status);
+		goto free_req;
+	}
+
+	hdd_wlan_offload_event(PMO_IPV4_ARP_REPLY_OFFLOAD, PMO_OFFLOAD_ENABLE);
+
+free_req:
+	qdf_mem_free(arp_req);
+
+out:
+	hdd_exit();
+}
+
+void hdd_disable_arp_offload(struct hdd_adapter *adapter,
+		enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status;
+
+	hdd_enter();
+	status = ucfg_pmo_flush_arp_offload_req(adapter->vdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to flush arp Offload");
+		goto out;
+	}
+
+	status = ucfg_pmo_disable_arp_offload_in_fwr(adapter->vdev,
+						     trigger);
+	if (status == QDF_STATUS_SUCCESS)
+		hdd_wlan_offload_event(PMO_IPV4_ARP_REPLY_OFFLOAD,
+			PMO_OFFLOAD_DISABLE);
+	else
+		hdd_info("fail to disable arp offload");
+out:
+	hdd_exit();
+}
+
+void hdd_enable_mc_addr_filtering(struct hdd_adapter *adapter,
+				  enum pmo_offload_trigger trigger)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		goto out;
+
+	if (!hdd_adapter_is_connected_sta(adapter))
+		goto out;
+
+	status = ucfg_pmo_enable_mc_addr_filtering_in_fwr(hdd_ctx->psoc,
+							  adapter->session_id,
+							  trigger);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("failed to enable mc list; status:%d", status);
+
+out:
+	hdd_exit();
+}
+
+void hdd_disable_mc_addr_filtering(struct hdd_adapter *adapter,
+				   enum pmo_offload_trigger trigger)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		goto out;
+
+	if (!hdd_adapter_is_connected_sta(adapter))
+		goto out;
+
+	status = ucfg_pmo_disable_mc_addr_filtering_in_fwr(hdd_ctx->psoc,
+							   adapter->session_id,
+							   trigger);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("failed to disable mc list; status:%d", status);
+
+out:
+	hdd_exit();
+}
+
+int hdd_cache_mc_addr_list(struct pmo_mc_addr_list_params *mc_list_config)
+{
+	QDF_STATUS status;
+
+	hdd_enter();
+	status = ucfg_pmo_cache_mc_addr_list(mc_list_config);
+	hdd_exit();
+
+	return qdf_status_to_os_return(status);
+}
+
+void hdd_disable_and_flush_mc_addr_list(struct hdd_adapter *adapter,
+					enum pmo_offload_trigger trigger)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	if (!hdd_adapter_is_connected_sta(adapter))
+		goto flush_mc_list;
+
+	/* disable mc list first because the mc list is cached in PMO */
+	status = ucfg_pmo_disable_mc_addr_filtering_in_fwr(hdd_ctx->psoc,
+							   adapter->session_id,
+							   trigger);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("failed to disable mc list; status:%d", status);
+
+flush_mc_list:
+	status = ucfg_pmo_flush_mc_addr_list(hdd_ctx->psoc,
+					     adapter->session_id);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("failed to flush mc list; status:%d", status);
+
+	hdd_exit();
+}
+
+/**
+ * hdd_update_conn_state_mask(): record info needed by wma_suspend_req
+ * @adapter: adapter to get info from
+ * @conn_state_mask: mask of connection info
+ *
+ * currently only need to send connection info.
+ */
+static void hdd_update_conn_state_mask(struct hdd_adapter *adapter,
+				       uint32_t *conn_state_mask)
+{
+
+	eConnectionState connState;
+	struct hdd_station_ctx *sta_ctx;
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	connState = sta_ctx->conn_info.connState;
+
+	if (connState == eConnectionState_Associated ||
+			connState == eConnectionState_IbssConnected)
+		*conn_state_mask |= (1 << adapter->session_id);
+}
+
+/**
+ * hdd_suspend_wlan() - Driver suspend function
+ * @callback: Callback function to invoke when driver is ready to suspend
+ * @callbackContext: Context to pass back to @callback function
+ *
+ * Return: 0 on success else error code.
+ */
+static int
+hdd_suspend_wlan(void)
+{
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+	struct hdd_adapter *adapter = NULL;
+	uint32_t conn_state_mask = 0;
+
+	hdd_info("WLAN being suspended by OS");
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is Null");
+		return -EINVAL;
+	}
+
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		hdd_info("Recovery in Progress. State: 0x%x Ignore suspend!!!",
+			 cds_get_driver_state());
+		return -EINVAL;
+	}
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (wlan_hdd_validate_session_id(adapter->session_id))
+			continue;
+
+		/* stop all TX queues before suspend */
+		hdd_debug("Disabling queues for dev mode %s",
+			  qdf_opmode_str(adapter->device_mode));
+		wlan_hdd_netif_queue_control(adapter,
+					     WLAN_STOP_ALL_NETIF_QUEUE,
+					     WLAN_CONTROL_PATH);
+
+		if (adapter->device_mode == QDF_STA_MODE)
+			status = hdd_enable_default_pkt_filters(adapter);
+
+		/* Configure supported OffLoads */
+		hdd_enable_host_offloads(adapter, pmo_apps_suspend);
+		hdd_update_conn_state_mask(adapter, &conn_state_mask);
+	}
+
+	status = ucfg_pmo_psoc_user_space_suspend_req(hdd_ctx->psoc,
+						      QDF_SYSTEM_SUSPEND);
+	if (status != QDF_STATUS_SUCCESS)
+		return -EAGAIN;
+
+	hdd_ctx->hdd_wlan_suspended = true;
+	hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND);
+
+	return 0;
+}
+
+/**
+ * hdd_resume_wlan() - Driver resume function
+ *
+ * Return: 0 on success else error code.
+ */
+static int hdd_resume_wlan(void)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_adapter *adapter;
+	QDF_STATUS status;
+
+	hdd_info("WLAN being resumed by OS");
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is Null");
+		return -EINVAL;
+	}
+
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		hdd_info("Recovery in Progress. State: 0x%x Ignore resume!!!",
+			 cds_get_driver_state());
+		return -EINVAL;
+	}
+
+	hdd_ctx->hdd_wlan_suspended = false;
+	hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
+
+	/*loop through all adapters. Concurrency */
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (wlan_hdd_validate_session_id(adapter->session_id))
+			continue;
+
+		/* Disable supported OffLoads */
+		hdd_disable_host_offloads(adapter, pmo_apps_resume);
+
+		/* wake the tx queues */
+		hdd_debug("Enabling queues for dev mode %s",
+			  qdf_opmode_str(adapter->device_mode));
+		wlan_hdd_netif_queue_control(adapter,
+					WLAN_WAKE_ALL_NETIF_QUEUE,
+					WLAN_CONTROL_PATH);
+
+		if (adapter->device_mode == QDF_STA_MODE)
+			status = hdd_disable_default_pkt_filters(adapter);
+	}
+
+	ucfg_ipa_resume(hdd_ctx->pdev);
+	status = ucfg_pmo_psoc_user_space_resume_req(hdd_ctx->psoc,
+						     QDF_SYSTEM_SUSPEND);
+	if (QDF_IS_STATUS_ERROR(status))
+		return qdf_status_to_os_return(status);
+
+	return 0;
+}
+
+void hdd_svc_fw_shutdown_ind(struct device *dev)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+					      WLAN_SVC_FW_SHUTDOWN_IND,
+					      NULL, 0) : 0;
+}
+
+/**
+ * hdd_ssr_restart_sap() - restart sap on SSR
+ * @hdd_ctx:   hdd context
+ *
+ * Return:     nothing
+ */
+static void hdd_ssr_restart_sap(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_enter();
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (adapter->device_mode == QDF_SAP_MODE) {
+			if (test_bit(SOFTAP_INIT_DONE, &adapter->event_flags)) {
+				hdd_debug("Restart prev SAP session");
+				wlan_hdd_start_sap(adapter, true);
+			}
+		}
+	}
+
+	hdd_exit();
+}
+
+QDF_STATUS hdd_wlan_shutdown(void)
+{
+	struct hdd_context *hdd_ctx;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	hdd_info("WLAN driver shutting down!");
+
+	/* Get the HDD context. */
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is Null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hdd_bus_bw_compute_timer_stop(hdd_ctx);
+	policy_mgr_clear_concurrent_session_count(hdd_ctx->psoc);
+
+	hdd_debug("Invoking packetdump deregistration API");
+	wlan_deregister_txrx_packetdump();
+
+	/* resume wlan threads before adapter reset which does vdev destroy */
+	if (hdd_ctx->is_scheduler_suspended) {
+		scheduler_resume();
+		hdd_ctx->is_scheduler_suspended = false;
+		hdd_ctx->is_wiphy_suspended = false;
+	}
+
+	wlan_hdd_rx_thread_resume(hdd_ctx);
+
+	/*
+	 * After SSR, FW clear its txrx stats. In host,
+	 * as adapter is intact so those counts are still
+	 * available. Now if agains Set stats command comes,
+	 * then host will increment its counts start from its
+	 * last saved value, i.e., count before SSR, and FW will
+	 * increment its count from 0. This will finally sends a
+	 * mismatch of packet counts b/w host and FW to framework
+	 * that will create ambiquity. Therfore, Resetting the host
+	 * counts here so that after SSR both FW and host start
+	 * increment their counts from 0.
+	 */
+	hdd_reset_all_adapters_connectivity_stats(hdd_ctx);
+
+	hdd_reset_all_adapters(hdd_ctx);
+
+	ucfg_ipa_uc_ssr_cleanup(hdd_ctx->pdev);
+
+	/* Flush cached rx frame queue */
+	if (soc)
+		cdp_flush_cache_rx_queue(soc);
+
+	/* De-register the HDD callbacks */
+	hdd_deregister_cb(hdd_ctx);
+
+	hdd_wlan_stop_modules(hdd_ctx, false);
+
+	hdd_bus_bandwidth_deinit(hdd_ctx);
+	hdd_lpass_notify_stop(hdd_ctx);
+
+	hdd_info("WLAN driver shutdown complete");
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * hdd_wlan_ssr_reinit_event()- send ssr reinit state
+ *
+ * This Function send send ssr reinit state diag event
+ *
+ * Return: void.
+ */
+static void hdd_wlan_ssr_reinit_event(void)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(ssr_reinit, struct host_event_wlan_ssr_reinit);
+	qdf_mem_zero(&ssr_reinit, sizeof(ssr_reinit));
+	ssr_reinit.status = SSR_SUB_SYSTEM_REINIT;
+	WLAN_HOST_DIAG_EVENT_REPORT(&ssr_reinit,
+					EVENT_WLAN_SSR_REINIT_SUBSYSTEM);
+}
+#else
+static inline void hdd_wlan_ssr_reinit_event(void)
+{
+
+}
+#endif
+
+/**
+ * hdd_send_default_scan_ies - send default scan ies to fw
+ *
+ * This function is used to send default scan ies to fw
+ * in case of wlan re-init
+ *
+ * Return: void
+ */
+static void hdd_send_default_scan_ies(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (hdd_is_interface_up(adapter) &&
+		    (adapter->device_mode == QDF_STA_MODE ||
+		    adapter->device_mode == QDF_P2P_DEVICE_MODE) &&
+		    adapter->scan_info.default_scan_ies) {
+			sme_set_default_scan_ie(hdd_ctx->mac_handle,
+				      adapter->session_id,
+				      adapter->scan_info.default_scan_ies,
+				      adapter->scan_info.default_scan_ies_len);
+		}
+	}
+}
+
+/**
+ * hdd_is_interface_down_during_ssr - Check if the interface went down during
+ * SSR
+ * @hdd_ctx: HDD context
+ *
+ * Check if any of the interface went down while the device is recovering.
+ * If the interface went down close the session.
+ */
+static void hdd_is_interface_down_during_ssr(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter = NULL, *pnext = NULL;
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	status = hdd_get_front_adapter(hdd_ctx, &adapter);
+	while (adapter && status == QDF_STATUS_SUCCESS) {
+		if (test_bit(DOWN_DURING_SSR, &adapter->event_flags)) {
+			clear_bit(DOWN_DURING_SSR, &adapter->event_flags);
+			hdd_stop_adapter(hdd_ctx, adapter);
+			hdd_deinit_adapter(hdd_ctx, adapter, true);
+			clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
+		}
+		status = hdd_get_next_adapter(hdd_ctx, adapter, &pnext);
+		adapter = pnext;
+	}
+
+	hdd_exit();
+}
+
+QDF_STATUS hdd_wlan_re_init(void)
+{
+	struct hdd_context *hdd_ctx = NULL;
+	struct hdd_adapter *adapter;
+	int ret;
+	bool bug_on_reinit_failure = CFG_BUG_ON_REINIT_FAILURE_DEFAULT;
+	bool value;
+
+	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
+
+	/* Get the HDD context */
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is Null");
+		goto err_ctx_null;
+	}
+	bug_on_reinit_failure = hdd_ctx->config->bug_on_reinit_failure;
+
+	adapter = hdd_get_first_valid_adapter(hdd_ctx);
+	if (!adapter)
+		hdd_err("Failed to get adapter");
+
+	hdd_dp_trace_init(hdd_ctx->config);
+	hdd_bus_bandwidth_init(hdd_ctx);
+
+	ret = hdd_wlan_start_modules(hdd_ctx, true);
+	if (ret) {
+		hdd_err("Failed to start wlan after error");
+		goto err_re_init;
+	}
+
+	hdd_update_hw_sw_info(hdd_ctx);
+
+	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+				WLAN_SVC_FW_CRASHED_IND, NULL, 0);
+
+	/* Restart all adapters */
+	hdd_start_all_adapters(hdd_ctx);
+
+	hdd_init_scan_reject_params(hdd_ctx);
+
+	hdd_set_roaming_in_progress(false);
+	complete(&adapter->roaming_comp_var);
+	hdd_ctx->bt_coex_mode_set = false;
+
+	/* Allow the phone to go to sleep */
+	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
+	/* set chip power save failure detected callback */
+	sme_set_chip_pwr_save_fail_cb(hdd_ctx->mac_handle,
+				      hdd_chip_pwr_save_fail_detected_cb);
+
+	hdd_send_default_scan_ies(hdd_ctx);
+	hdd_info("WLAN host driver reinitiation completed!");
+
+	ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
+	if (value)
+		hdd_ssr_restart_sap(hdd_ctx);
+	hdd_is_interface_down_during_ssr(hdd_ctx);
+	hdd_wlan_ssr_reinit_event();
+	return QDF_STATUS_SUCCESS;
+
+err_re_init:
+	hdd_bus_bandwidth_deinit(hdd_ctx);
+	qdf_dp_trace_deinit();
+
+err_ctx_null:
+	/* Allow the phone to go to sleep */
+	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
+	if (bug_on_reinit_failure)
+		QDF_BUG(0);
+	return -EPERM;
+}
+
+int wlan_hdd_set_powersave(struct hdd_adapter *adapter,
+	bool allow_power_save, uint32_t timeout)
+{
+	mac_handle_t mac_handle;
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (NULL == adapter) {
+		hdd_err("Adapter NULL");
+		return -ENODEV;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hdd_ctx) {
+		hdd_err("hdd context is NULL");
+		return -EINVAL;
+	}
+
+	hdd_debug("Allow power save: %d", allow_power_save);
+	mac_handle = hdd_ctx->mac_handle;
+
+	/*
+	 * This is a workaround for defective AP's that send a disassoc
+	 * immediately after WPS connection completes. Defer powersave by a
+	 * small amount if the affected AP is detected.
+	 */
+	if (allow_power_save &&
+	    adapter->device_mode == QDF_STA_MODE &&
+	    !adapter->session.station.ap_supports_immediate_power_save) {
+		timeout = AUTO_PS_DEFER_TIMEOUT_MS;
+		hdd_debug("Defer power-save due to AP spec non-conformance");
+	}
+
+	if (allow_power_save) {
+		if (QDF_STA_MODE == adapter->device_mode ||
+		    QDF_P2P_CLIENT_MODE == adapter->device_mode) {
+			hdd_debug("Disabling Auto Power save timer");
+			status = sme_ps_disable_auto_ps_timer(mac_handle,
+						adapter->session_id);
+			if (status != QDF_STATUS_SUCCESS)
+				goto end;
+		}
+
+		if (hdd_ctx->config && hdd_ctx->config->is_ps_enabled) {
+			hdd_debug("Wlan driver Entering Power save");
+
+			/*
+			 * Enter Power Save command received from GUI
+			 * this means DHCP is completed
+			 */
+			if (timeout) {
+				status = sme_ps_enable_auto_ps_timer(mac_handle,
+							    adapter->session_id,
+							    timeout);
+				if (status != QDF_STATUS_SUCCESS)
+					goto end;
+			} else {
+				status = sme_ps_enable_disable(mac_handle,
+						adapter->session_id,
+						SME_PS_ENABLE);
+				if (status != QDF_STATUS_SUCCESS)
+					goto end;
+			}
+		} else {
+			hdd_debug("Power Save is not enabled in the cfg");
+		}
+	} else {
+		hdd_debug("Wlan driver Entering Full Power");
+
+		/*
+		 * Enter Full power command received from GUI
+		 * this means we are disconnected
+		 */
+		status = sme_ps_disable_auto_ps_timer(mac_handle,
+					adapter->session_id);
+		if (status != QDF_STATUS_SUCCESS)
+			goto end;
+		status = sme_ps_enable_disable(mac_handle, adapter->session_id,
+					       SME_PS_DISABLE);
+	}
+
+end:
+	return qdf_status_to_os_return(status);
+}
+
+static void wlan_hdd_print_suspend_fail_stats(struct hdd_context *hdd_ctx)
+{
+	struct suspend_resume_stats *stats = &hdd_ctx->suspend_resume_stats;
+
+	hdd_err("ipa:%d, radar:%d, roam:%d, scan:%d, initial_wakeup:%d",
+		stats->suspend_fail[SUSPEND_FAIL_IPA],
+		stats->suspend_fail[SUSPEND_FAIL_RADAR],
+		stats->suspend_fail[SUSPEND_FAIL_ROAM],
+		stats->suspend_fail[SUSPEND_FAIL_SCAN],
+		stats->suspend_fail[SUSPEND_FAIL_INITIAL_WAKEUP]);
+}
+
+void wlan_hdd_inc_suspend_stats(struct hdd_context *hdd_ctx,
+				enum suspend_fail_reason reason)
+{
+	wlan_hdd_print_suspend_fail_stats(hdd_ctx);
+	hdd_ctx->suspend_resume_stats.suspend_fail[reason]++;
+	wlan_hdd_print_suspend_fail_stats(hdd_ctx);
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
+static inline void
+hdd_sched_scan_results(struct wiphy *wiphy, uint64_t reqid)
+{
+	cfg80211_sched_scan_results(wiphy);
+}
+#else
+static inline void
+hdd_sched_scan_results(struct wiphy *wiphy, uint64_t reqid)
+{
+	cfg80211_sched_scan_results(wiphy, reqid);
+}
+#endif
+
+/**
+ * __wlan_hdd_cfg80211_resume_wlan() - cfg80211 resume callback
+ * @wiphy: Pointer to wiphy
+ *
+ * This API is called when cfg80211 driver resumes driver updates
+ * latest sched_scan scan result(if any) to cfg80211 database
+ *
+ * Return: integer status
+ */
+static int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	int exit_code;
+
+	hdd_enter();
+
+	if (cds_is_driver_recovering()) {
+		hdd_debug("Driver is recovering; Skipping resume");
+		exit_code = 0;
+		goto exit_with_code;
+	}
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		exit_code = -EINVAL;
+		goto exit_with_code;
+	}
+
+	exit_code = wlan_hdd_validate_context(hdd_ctx);
+	if (exit_code) {
+		hdd_err("Invalid HDD context");
+		goto exit_with_code;
+	}
+
+	mutex_lock(&hdd_ctx->iface_change_lock);
+	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+		mutex_unlock(&hdd_ctx->iface_change_lock);
+		hdd_debug("Driver is not enabled; Skipping resume");
+		exit_code = 0;
+		goto exit_with_code;
+	}
+	mutex_unlock(&hdd_ctx->iface_change_lock);
+
+	pld_request_bus_bandwidth(hdd_ctx->parent_dev, PLD_BUS_WIDTH_MEDIUM);
+
+	status = hdd_resume_wlan();
+	if (status != QDF_STATUS_SUCCESS) {
+		exit_code = 0;
+		goto exit_with_code;
+	}
+	/* Resume control path scheduler */
+	if (hdd_ctx->is_scheduler_suspended) {
+		scheduler_resume();
+		hdd_ctx->is_scheduler_suspended = false;
+	}
+
+	/* Resume tlshim Rx thread */
+	if (hdd_ctx->enable_rxthread)
+		wlan_hdd_rx_thread_resume(hdd_ctx);
+
+	if (hdd_ctx->enable_dp_rx_threads)
+		dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC));
+
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
+			 NO_SESSION, hdd_ctx->is_wiphy_suspended));
+	hdd_ctx->is_wiphy_suspended = false;
+
+	hdd_ctx->suspend_resume_stats.resumes++;
+	exit_code = 0;
+
+exit_with_code:
+	hdd_exit();
+	return exit_code;
+}
+
+int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static void hdd_suspend_cb(void)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return;
+	}
+
+	complete(&hdd_ctx->mc_sus_event_var);
+}
+
+/**
+ * __wlan_hdd_cfg80211_suspend_wlan() - cfg80211 suspend callback
+ * @wiphy: Pointer to wiphy
+ * @wow: Pointer to wow
+ *
+ * This API is called when cfg80211 driver suspends
+ *
+ * Return: integer status
+ */
+static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
+				     struct cfg80211_wowlan *wow)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct hdd_adapter *adapter;
+	struct hdd_scan_info *scan_info;
+	mac_handle_t mac_handle;
+	int rc;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	rc = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != rc)
+		return rc;
+
+	mutex_lock(&hdd_ctx->iface_change_lock);
+
+	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+		mutex_unlock(&hdd_ctx->iface_change_lock);
+		hdd_debug("Driver Modules not Enabled ");
+		return 0;
+	}
+	mutex_unlock(&hdd_ctx->iface_change_lock);
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	/* If RADAR detection is in progress (HDD), prevent suspend. The flag
+	 * "dfs_cac_block_tx" is set to true when RADAR is found and stay true
+	 * until CAC is done for a SoftAP which is in started state.
+	 */
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (wlan_hdd_validate_session_id(adapter->session_id))
+			continue;
+
+		if (QDF_SAP_MODE == adapter->device_mode) {
+			if (BSS_START ==
+			    WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter)->bss_state &&
+			    true ==
+			    WLAN_HDD_GET_AP_CTX_PTR(adapter)->
+			    dfs_cac_block_tx) {
+				hdd_err("RADAR detection in progress, do not allow suspend");
+				wlan_hdd_inc_suspend_stats(hdd_ctx,
+							   SUSPEND_FAIL_RADAR);
+				return -EAGAIN;
+			} else if (!hdd_ctx->config->enable_sap_suspend) {
+				/* return -EOPNOTSUPP if SAP does not support
+				 * suspend
+				 */
+				hdd_err("SAP does not support suspend!!");
+				return -EOPNOTSUPP;
+			}
+		} else if (QDF_P2P_GO_MODE == adapter->device_mode) {
+			if (!hdd_ctx->config->enable_sap_suspend) {
+				/* return -EOPNOTSUPP if GO does not support
+				 * suspend
+				 */
+				hdd_err("GO does not support suspend!!");
+				return -EOPNOTSUPP;
+			}
+		}
+	}
+	/* p2p cleanup task based on scheduler */
+	ucfg_p2p_cleanup_tx_by_psoc(hdd_ctx->psoc);
+	ucfg_p2p_cleanup_roc_by_psoc(hdd_ctx->psoc);
+
+	/* Stop ongoing scan on each interface */
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		scan_info = &adapter->scan_info;
+
+		if (sme_neighbor_middle_of_roaming(mac_handle,
+		    adapter->session_id) ||
+		    hdd_is_roaming_in_progress(hdd_ctx)) {
+			hdd_err("Roaming in progress, do not allow suspend");
+			wlan_hdd_inc_suspend_stats(hdd_ctx,
+						   SUSPEND_FAIL_ROAM);
+			return -EAGAIN;
+		}
+
+		wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
+				adapter->session_id, INVALID_SCAN_ID, false);
+	}
+
+	/* flush any pending powersave timers */
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		if (wlan_hdd_validate_session_id(adapter->session_id))
+			continue;
+
+		sme_ps_timer_flush_sync(mac_handle, adapter->session_id);
+	}
+
+	/*
+	 * Suspend IPA early before proceeding to suspend other entities like
+	 * firmware to avoid any race conditions.
+	 */
+	if (ucfg_ipa_suspend(hdd_ctx->pdev)) {
+		hdd_err("IPA not ready to suspend!");
+		wlan_hdd_inc_suspend_stats(hdd_ctx, SUSPEND_FAIL_IPA);
+		return -EAGAIN;
+	}
+
+	/* Suspend control path scheduler */
+	scheduler_register_hdd_suspend_callback(hdd_suspend_cb);
+	scheduler_set_event_mask(MC_SUSPEND_EVENT);
+	scheduler_wake_up_controller_thread();
+
+	/* Wait for suspend confirmation from scheduler */
+	rc = wait_for_completion_timeout(&hdd_ctx->mc_sus_event_var,
+		msecs_to_jiffies(WLAN_WAIT_TIME_MCTHREAD_SUSPEND));
+	if (!rc) {
+		scheduler_clear_event_mask(MC_SUSPEND_EVENT);
+		hdd_err("Failed to stop mc thread");
+		goto resume_tx;
+	}
+	hdd_ctx->is_scheduler_suspended = true;
+
+	if (hdd_ctx->enable_rxthread) {
+		if (wlan_hdd_rx_thread_suspend(hdd_ctx))
+			goto resume_ol_rx;
+	}
+
+	if (hdd_ctx->enable_dp_rx_threads)
+		dp_txrx_suspend(cds_get_context(QDF_MODULE_ID_SOC));
+
+	if (hdd_suspend_wlan() < 0) {
+		hdd_err("Failed to suspend WLAN");
+		goto resume_dp_thread;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
+			 NO_SESSION, hdd_ctx->is_wiphy_suspended));
+	hdd_ctx->is_wiphy_suspended = true;
+
+	pld_request_bus_bandwidth(hdd_ctx->parent_dev, PLD_BUS_WIDTH_NONE);
+
+	hdd_exit();
+	return 0;
+
+resume_dp_thread:
+	if (hdd_ctx->enable_dp_rx_threads)
+		dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC));
+
+resume_ol_rx:
+	/* Resume tlshim Rx thread */
+	wlan_hdd_rx_thread_resume(hdd_ctx);
+	scheduler_resume();
+	hdd_ctx->is_scheduler_suspended = false;
+resume_tx:
+	hdd_resume_wlan();
+	return -ETIME;
+
+}
+
+int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
+				   struct cfg80211_wowlan *wow)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_stop_dhcp_ind() - API to stop DHCP sequence
+ * @adapter: Adapter on which DHCP needs to be stopped
+ *
+ * Release the wakelock held for DHCP process and allow
+ * the runtime pm to continue
+ *
+ * Return: None
+ */
+static void hdd_stop_dhcp_ind(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_debug("DHCP stop indicated through power save");
+	sme_dhcp_stop_ind(hdd_ctx->mac_handle, adapter->device_mode,
+			  adapter->mac_addr.bytes,
+			  adapter->session_id);
+	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DHCP);
+	qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
+}
+
+/**
+ * hdd_start_dhcp_ind() - API to start DHCP sequence
+ * @adapter: Adapter on which DHCP needs to be stopped
+ *
+ * Prevent APPS suspend and the runtime suspend during
+ * DHCP sequence
+ *
+ * Return: None
+ */
+static void hdd_start_dhcp_ind(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_debug("DHCP start indicated through power save");
+	qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.connect);
+	hdd_prevent_suspend_timeout(HDD_WAKELOCK_TIMEOUT_CONNECT,
+				    WIFI_POWER_EVENT_WAKELOCK_DHCP);
+	sme_dhcp_start_ind(hdd_ctx->mac_handle, adapter->device_mode,
+			   adapter->mac_addr.bytes,
+			   adapter->session_id);
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_power_mgmt() - set cfg80211 power management config
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @allow_power_save: is wlan allowed to go into power save mode
+ * @timeout: Timeout value in ms
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+					      struct net_device *dev,
+					      bool allow_power_save,
+					      int timeout)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	int status;
+
+	hdd_enter();
+
+	if (timeout < 0) {
+		hdd_debug("User space timeout: %d; Enter full power or power save",
+			  timeout);
+		timeout = 0;
+	}
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
+			 adapter->session_id, timeout));
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	mutex_lock(&hdd_ctx->iface_change_lock);
+	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+		mutex_unlock(&hdd_ctx->iface_change_lock);
+		hdd_debug("Driver Module not enabled return success");
+		return 0;
+	}
+	mutex_unlock(&hdd_ctx->iface_change_lock);
+
+	status = wlan_hdd_set_powersave(adapter, allow_power_save, timeout);
+
+	allow_power_save ? hdd_stop_dhcp_ind(adapter) :
+		hdd_start_dhcp_ind(adapter);
+
+	hdd_exit();
+	return status;
+}
+
+int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+				     struct net_device *dev,
+				     bool allow_power_save,
+				     int timeout)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev,
+		allow_power_save, timeout);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_txpower() - set TX power
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to network device
+ * @type: TX power setting type
+ * @mbm: TX power in mBm
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   enum nl80211_tx_power_setting type,
+					   int mbm)
+{
+	struct hdd_context *hdd_ctx = (struct hdd_context *) wiphy_priv(wiphy);
+	mac_handle_t mac_handle;
+	struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT;
+	struct qdf_mac_addr selfMac = QDF_MAC_ADDR_BCAST_INIT;
+	QDF_STATUS status;
+	int errno;
+	int dbm;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
+			 NO_SESSION, type));
+
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	dbm = MBM_TO_DBM(mbm);
+
+	/*
+	 * the original implementation of this function expected power
+	 * values in dBm instead of mBm. If the conversion from mBm to
+	 * dBm is zero, then assume dBm was passed.
+	 */
+	if (!dbm)
+		dbm = mbm;
+
+	status = sme_cfg_set_int(mac_handle, WNI_CFG_CURRENT_TX_POWER_LEVEL,
+				 dbm);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("sme_cfg_set_int failed for tx power %hu, %d",
+			dbm, status);
+		return -EIO;
+	}
+
+	hdd_debug("Set tx power level %d dbm", dbm);
+
+	switch (type) {
+	/* Automatically determine transmit power */
+	case NL80211_TX_POWER_AUTOMATIC:
+	/* Fall through */
+	case NL80211_TX_POWER_LIMITED:
+	/* Limit TX power by the mBm parameter */
+		status = sme_set_max_tx_power(mac_handle, bssid, selfMac, dbm);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Setting maximum tx power failed, %d", status);
+			return -EIO;
+		}
+		break;
+
+	case NL80211_TX_POWER_FIXED:    /* Fix TX power to the mBm parameter */
+		hdd_err("NL80211_TX_POWER_FIXED not supported");
+		return -EOPNOTSUPP;
+
+	default:
+		hdd_err("Invalid power setting type %d", type);
+		return -EIO;
+	}
+
+	hdd_exit();
+	return 0;
+}
+
+int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  enum nl80211_tx_power_setting type,
+				  int mbm)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
+					      wdev,
+					      type, mbm);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef QCA_SUPPORT_CP_STATS
+static void wlan_hdd_get_tx_power(struct hdd_adapter *adapter, int *dbm)
+{
+	wlan_cfg80211_mc_cp_stats_get_tx_power(adapter->vdev, dbm);
+}
+#else
+static void wlan_hdd_get_tx_power(struct hdd_adapter *adapter, int *dbm)
+{
+	wlan_hdd_get_class_astats(adapter);
+	*dbm = adapter->hdd_stats.class_a_stat.max_pwr;
+}
+#endif
+/**
+ * __wlan_hdd_cfg80211_get_txpower() - get TX power
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to network device
+ * @dbm: Pointer to TX power in dbm
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  int *dbm)
+{
+
+	struct hdd_context *hdd_ctx = (struct hdd_context *) wiphy_priv(wiphy);
+	struct net_device *ndev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	int status;
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	hdd_enter_dev(ndev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	*dbm = 0;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	/* Validate adapter sessionId */
+	status = wlan_hdd_validate_session_id(adapter->session_id);
+	if (status)
+		return status;
+
+	if (sta_ctx->hdd_reassoc_scenario) {
+		hdd_debug("Roaming is in progress, rej this req");
+		return -EINVAL;
+	}
+
+	mutex_lock(&hdd_ctx->iface_change_lock);
+	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
+		mutex_unlock(&hdd_ctx->iface_change_lock);
+		hdd_debug("Driver Module not enabled return success");
+		/* Send cached data to upperlayer*/
+		*dbm = adapter->hdd_stats.class_a_stat.max_pwr;
+		return 0;
+	}
+	mutex_unlock(&hdd_ctx->iface_change_lock);
+
+	if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
+		hdd_debug("Not associated");
+		return 0;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
+			 adapter->session_id, adapter->device_mode));
+
+	wlan_hdd_get_tx_power(adapter, dbm);
+	hdd_debug("power: %d", *dbm);
+
+	return 0;
+}
+
+int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 int *dbm)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_txpower(wiphy, wdev, dbm);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int hdd_set_qpower_config(struct hdd_context *hddctx,
+			  struct hdd_adapter *adapter,
+			  u8 qpower)
+{
+	QDF_STATUS status;
+
+	if (!ucfg_pmo_get_power_save_mode(hddctx->psoc)) {
+		hdd_err("qpower is disabled in configuration");
+		return -EINVAL;
+	}
+	if (adapter->device_mode != QDF_STA_MODE &&
+	    adapter->device_mode != QDF_P2P_CLIENT_MODE) {
+		hdd_info("QPOWER only allowed in STA/P2P-Client modes:%d",
+			 adapter->device_mode);
+		return -EINVAL;
+	}
+
+	if (qpower > PS_DUTY_CYCLING_QPOWER ||
+	    qpower < PS_LEGACY_NODEEPSLEEP) {
+		hdd_err("invalid qpower value: %d", qpower);
+		return -EINVAL;
+	}
+
+	if (ucfg_pmo_get_max_ps_poll(hddctx->psoc)) {
+		if ((qpower == PS_QPOWER_NODEEPSLEEP) ||
+				(qpower == PS_LEGACY_NODEEPSLEEP))
+			qpower = PS_LEGACY_NODEEPSLEEP;
+		else
+			qpower = PS_LEGACY_DEEPSLEEP;
+		hdd_info("Qpower disabled, %d", qpower);
+	}
+	status = wma_set_qpower_config(adapter->session_id, qpower);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("failed to configure qpower: %d", status);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+#ifdef WLAN_SUSPEND_RESUME_TEST
+static struct net_device *g_dev;
+static struct wiphy *g_wiphy;
+static enum wow_resume_trigger g_resume_trigger;
+
+#define HDD_FA_SUSPENDED_BIT (0)
+static unsigned long fake_apps_state;
+
+/**
+ * __hdd_wlan_fake_apps_resume() - The core logic for
+ *	hdd_wlan_fake_apps_resume() skipping the call to hif_fake_apps_resume(),
+ *	which is only need for non-irq resume
+ * @wiphy: the kernel wiphy struct for the device being resumed
+ * @dev: the kernel net_device struct for the device being resumed
+ *
+ * Return: none, calls QDF_BUG() on failure
+ */
+static void __hdd_wlan_fake_apps_resume(struct wiphy *wiphy,
+					struct net_device *dev)
+{
+	struct hif_opaque_softc *hif_ctx;
+	qdf_device_t qdf_dev;
+
+	hdd_info("Unit-test resume WLAN");
+
+	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	if (!qdf_dev) {
+		hdd_err("Failed to get QDF device context");
+		QDF_BUG(0);
+		return;
+	}
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!hif_ctx) {
+		hdd_err("Failed to get HIF context");
+		return;
+	}
+
+	if (!test_and_clear_bit(HDD_FA_SUSPENDED_BIT, &fake_apps_state)) {
+		hdd_alert("Not unit-test suspended; Nothing to do");
+		return;
+	}
+
+	/* simulate kernel disable irqs */
+	QDF_BUG(!hif_apps_wake_irq_disable(hif_ctx));
+
+	QDF_BUG(!wlan_hdd_bus_resume_noirq());
+
+	/* simulate kernel enable irqs */
+	QDF_BUG(!hif_apps_irqs_enable(hif_ctx));
+
+	QDF_BUG(!wlan_hdd_bus_resume());
+
+	QDF_BUG(!wlan_hdd_cfg80211_resume_wlan(wiphy));
+
+	if (g_resume_trigger == WOW_RESUME_TRIGGER_HTC_WAKEUP)
+		hif_vote_link_down(hif_ctx);
+
+	dev->watchdog_timeo = HDD_TX_TIMEOUT;
+
+	hdd_alert("Unit-test resume succeeded");
+}
+
+/**
+ * hdd_wlan_fake_apps_resume_irq_callback() - Irq callback function for resuming
+ *	from unit-test initiated suspend from irq wakeup signal
+ *
+ * Resume wlan after getting very 1st CE interrupt from target
+ *
+ * Return: none
+ */
+static void hdd_wlan_fake_apps_resume_irq_callback(void)
+{
+	hdd_info("Trigger unit-test resume WLAN");
+
+	QDF_BUG(g_wiphy);
+	QDF_BUG(g_dev);
+	__hdd_wlan_fake_apps_resume(g_wiphy, g_dev);
+	g_wiphy = NULL;
+	g_dev = NULL;
+}
+
+int hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev,
+			       enum wow_interface_pause pause_setting,
+			       enum wow_resume_trigger resume_setting)
+{
+	int errno;
+	qdf_device_t qdf_dev;
+	struct hif_opaque_softc *hif_ctx;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	struct wow_enable_params wow_params = {
+		.is_unit_test = true,
+		.interface_pause = pause_setting,
+		.resume_trigger = resume_setting
+	};
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	if (!hdd_ctx->config->is_unit_test_framework_enabled) {
+		hdd_warn_rl("UT framework is disabled");
+		return -EINVAL;
+	}
+
+	hdd_info("Unit-test suspend WLAN");
+
+	if (pause_setting < WOW_INTERFACE_PAUSE_DEFAULT ||
+	    pause_setting >= WOW_INTERFACE_PAUSE_COUNT) {
+		hdd_err("Invalid interface pause %d (expected range [0, 2])",
+			pause_setting);
+		return -EINVAL;
+	}
+
+	if (resume_setting < WOW_RESUME_TRIGGER_DEFAULT ||
+	    resume_setting >= WOW_RESUME_TRIGGER_COUNT) {
+		hdd_err("Invalid resume trigger %d (expected range [0, 2])",
+			resume_setting);
+		return -EINVAL;
+	}
+
+	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	if (!qdf_dev) {
+		hdd_err("Failed to get QDF device context");
+		return -EINVAL;
+	}
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!hif_ctx) {
+		hdd_err("Failed to get HIF context");
+		return -EINVAL;
+	}
+
+	if (test_and_set_bit(HDD_FA_SUSPENDED_BIT, &fake_apps_state)) {
+		hdd_alert("Already unit-test suspended; Nothing to do");
+		return 0;
+	}
+
+	/* pci link is needed to wakeup from HTC wakeup trigger */
+	if (resume_setting == WOW_RESUME_TRIGGER_HTC_WAKEUP)
+		hif_vote_link_up(hif_ctx);
+
+	errno = wlan_hdd_cfg80211_suspend_wlan(wiphy, NULL);
+	if (errno)
+		goto link_down;
+
+	errno = wlan_hdd_unit_test_bus_suspend(wow_params);
+	if (errno)
+		goto cfg80211_resume;
+
+	/* simulate kernel disabling irqs */
+	errno = hif_apps_irqs_disable(hif_ctx);
+	if (errno)
+		goto bus_resume;
+
+	errno = wlan_hdd_bus_suspend_noirq();
+	if (errno)
+		goto enable_irqs;
+
+	/* pass wiphy/dev to callback via global variables */
+	g_wiphy = wiphy;
+	g_dev = dev;
+	g_resume_trigger = resume_setting;
+	hif_ut_apps_suspend(hif_ctx, hdd_wlan_fake_apps_resume_irq_callback);
+
+	/* re-enable wake irq */
+	errno = hif_apps_wake_irq_enable(hif_ctx);
+	if (errno)
+		goto fake_apps_resume;
+
+	/*
+	 * Tell the kernel not to worry if TX queues aren't moving. This is
+	 * expected since we are suspending the wifi hardware, but not APPS
+	 */
+	dev->watchdog_timeo = INT_MAX;
+
+	hdd_alert("Unit-test suspend succeeded");
+
+	return 0;
+
+fake_apps_resume:
+	hif_ut_apps_resume(hif_ctx);
+
+enable_irqs:
+	QDF_BUG(!hif_apps_irqs_enable(hif_ctx));
+
+bus_resume:
+	QDF_BUG(!wlan_hdd_bus_resume());
+
+cfg80211_resume:
+	QDF_BUG(!wlan_hdd_cfg80211_resume_wlan(wiphy));
+
+link_down:
+	hif_vote_link_down(hif_ctx);
+
+	clear_bit(HDD_FA_SUSPENDED_BIT, &fake_apps_state);
+	hdd_err("Unit-test suspend failed: %d", errno);
+
+	return errno;
+}
+
+int hdd_wlan_fake_apps_resume(struct wiphy *wiphy, struct net_device *dev)
+{
+	struct hif_opaque_softc *hif_ctx;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	if (!hdd_ctx->config->is_unit_test_framework_enabled) {
+		hdd_warn_rl("UT framework is disabled");
+		return -EINVAL;
+	}
+
+	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	if (!hif_ctx) {
+		hdd_err("Failed to get HIF context");
+		return -EINVAL;
+	}
+
+	hif_ut_apps_resume(hif_ctx);
+	__hdd_wlan_fake_apps_resume(wiphy, dev);
+
+	return 0;
+}
+#endif
diff --git a/core/hdd/src/wlan_hdd_regulatory.c b/core/hdd/src/wlan_hdd_regulatory.c
new file mode 100644
index 0000000..7578839
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_regulatory.c
@@ -0,0 +1,1424 @@
+/*
+ * Copyright (c) 2014-2018 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: wlan_hdd_regulatory.c
+ *
+ * hdd regulatory implementation
+ */
+
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "wlan_hdd_main.h"
+#include <wlan_osif_priv.h>
+#include "wlan_hdd_regulatory.h"
+#include <wlan_reg_ucfg_api.h>
+#include "cds_regdomain.h"
+#include "cds_utils.h"
+#include "pld_common.h"
+#include <net/cfg80211.h>
+
+#define REG_RULE_2412_2462    REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
+
+#define REG_RULE_2467_2472    REG_RULE(2467-10, 2472+10, 40, 0, 20, \
+		NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+
+#define REG_RULE_2484         REG_RULE(2484-10, 2484+10, 20, 0, 20, \
+		NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | \
+				       NL80211_RRF_NO_OFDM)
+
+#define REG_RULE_5180_5320    REG_RULE(5180-10, 5320+10, 160, 0, 20, \
+		NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+
+#define REG_RULE_5500_5720    REG_RULE(5500-10, 5720+10, 160, 0, 20, \
+		NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+
+#define REG_RULE_5745_5925    REG_RULE(5745-10, 5925+10, 80, 0, 20, \
+		NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+
+static bool init_by_driver;
+static bool init_by_reg_core;
+
+struct regulatory_channel reg_channels[NUM_CHANNELS];
+
+static const struct ieee80211_regdomain
+hdd_world_regrules_60_61_62 = {
+	.n_reg_rules = 6,
+	.alpha2 =  "00",
+	.reg_rules = {
+		REG_RULE_2412_2462,
+		REG_RULE_2467_2472,
+		REG_RULE_2484,
+		REG_RULE_5180_5320,
+		REG_RULE_5500_5720,
+		REG_RULE_5745_5925,
+	}
+};
+
+static const struct ieee80211_regdomain
+hdd_world_regrules_63_65 = {
+	.n_reg_rules = 4,
+	.alpha2 =  "00",
+	.reg_rules = {
+		REG_RULE_2412_2462,
+		REG_RULE_2467_2472,
+		REG_RULE_5180_5320,
+		REG_RULE_5745_5925,
+	}
+};
+
+static const struct ieee80211_regdomain
+hdd_world_regrules_64 = {
+	.n_reg_rules = 3,
+	.alpha2 =  "00",
+	.reg_rules = {
+		REG_RULE_2412_2462,
+		REG_RULE_5180_5320,
+		REG_RULE_5745_5925,
+	}
+};
+
+static const struct ieee80211_regdomain
+hdd_world_regrules_66_69 = {
+	.n_reg_rules = 4,
+	.alpha2 =  "00",
+	.reg_rules = {
+		REG_RULE_2412_2462,
+		REG_RULE_5180_5320,
+		REG_RULE_5500_5720,
+		REG_RULE_5745_5925,
+	}
+};
+
+static const struct ieee80211_regdomain
+hdd_world_regrules_67_68_6A_6C = {
+	.n_reg_rules = 5,
+	.alpha2 =  "00",
+	.reg_rules = {
+		REG_RULE_2412_2462,
+		REG_RULE_2467_2472,
+		REG_RULE_5180_5320,
+		REG_RULE_5500_5720,
+		REG_RULE_5745_5925,
+	}
+};
+
+/**
+ * hdd_get_world_regrules() - get the appropriate world regrules
+ * @reg: regulatory data
+ *
+ * Return: regulatory rules ptr
+ */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0))
+static const struct ieee80211_regdomain *hdd_get_world_regrules(
+	struct regulatory *reg)
+{
+	struct reg_dmn_pair *regpair =
+		(struct reg_dmn_pair *)reg->regpair;
+
+	switch (regpair->reg_dmn_pair) {
+	case 0x60:
+	case 0x61:
+	case 0x62:
+		return &hdd_world_regrules_60_61_62;
+	case 0x63:
+	case 0x65:
+		return &hdd_world_regrules_63_65;
+	case 0x64:
+		return &hdd_world_regrules_64;
+	case 0x66:
+	case 0x69:
+		return &hdd_world_regrules_66_69;
+	case 0x67:
+	case 0x68:
+	case 0x6A:
+	case 0x6C:
+		return &hdd_world_regrules_67_68_6A_6C;
+	default:
+		hdd_warn("invalid world mode in BDF");
+		return &hdd_world_regrules_60_61_62;
+	}
+}
+
+/**
+ * hdd_is_world_regdomain() - whether world regdomain
+ * @reg_domain: integer regulatory domain
+ *
+ * Return: bool
+ */
+static bool hdd_is_world_regdomain(uint32_t reg_domain)
+{
+	uint32_t temp_regd = reg_domain & ~WORLD_ROAMING_FLAG;
+
+	return ((temp_regd & CTRY_FLAG) != CTRY_FLAG) &&
+		((temp_regd & WORLD_ROAMING_MASK) ==
+		 WORLD_ROAMING_PREFIX);
+}
+
+/**
+ * hdd_update_regulatory_info() - update regulatory info
+ * @hdd_ctx: hdd context
+ *
+ * Return: Error Code
+ */
+static int hdd_update_regulatory_info(struct hdd_context *hdd_ctx)
+{
+	uint32_t country_code;
+
+	country_code = cds_get_country_from_alpha2(hdd_ctx->reg.alpha2);
+
+	hdd_ctx->reg.reg_domain = CTRY_FLAG;
+	hdd_ctx->reg.reg_domain |= country_code;
+
+	return cds_fill_some_regulatory_info(&hdd_ctx->reg);
+
+}
+#endif
+
+/**
+ * hdd_reset_global_reg_params - Reset global static reg params
+ *
+ * This function is helpful in static driver to reset
+ * the global params.
+ *
+ * Return: void
+ */
+void hdd_reset_global_reg_params(void)
+{
+	init_by_driver = false;
+	init_by_reg_core = false;
+}
+
+static void reg_program_config_vars(struct hdd_context *hdd_ctx,
+				    struct reg_config_vars *config_vars)
+{
+	uint8_t band_capability = 0;
+	QDF_STATUS status;
+
+	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to get MLME band cap, defaulting to BAND_ALL");
+
+	config_vars->enable_11d_support = hdd_ctx->config->Is11dSupportEnabled;
+	config_vars->scan_11d_interval = hdd_ctx->config->scan_11d_interval;
+	config_vars->userspace_ctry_priority =
+		hdd_ctx->config->fSupplicantCountryCodeHasPriority;
+	config_vars->dfs_enabled = hdd_ctx->config->enableDFSChnlScan;
+	config_vars->indoor_chan_enabled =
+		hdd_ctx->config->indoor_channel_support;
+	config_vars->force_ssc_disable_indoor_channel =
+		hdd_ctx->config->force_ssc_disable_indoor_channel;
+	config_vars->band_capability = band_capability;
+	config_vars->restart_beaconing = hdd_ctx->config->
+		restart_beaconing_on_chan_avoid_event;
+	config_vars->enable_srd_chan_in_master_mode =
+		hdd_ctx->config->etsi13_srd_chan_in_master_mode;
+	config_vars->enable_11d_in_world_mode =
+		hdd_ctx->config->enable_11d_in_world_mode;
+}
+
+
+/**
+ * hdd_regulatory_wiphy_init() - regulatory wiphy init
+ * @hdd_ctx: hdd context
+ * @reg: regulatory data
+ * @wiphy: wiphy structure
+ *
+ * Return: void
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(WITH_BACKPORTS)
+static void hdd_regulatory_wiphy_init(struct hdd_context *hdd_ctx,
+				     struct regulatory *reg,
+				     struct wiphy *wiphy)
+{
+	const struct ieee80211_regdomain *reg_rules;
+	int chan_num;
+	struct ieee80211_channel *chan;
+
+	if (hdd_is_world_regdomain(reg->reg_domain)) {
+		reg_rules = hdd_get_world_regrules(reg);
+		wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
+	} else if (hdd_ctx->config->fRegChangeDefCountry) {
+		wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
+		reg_rules = &hdd_world_regrules_60_61_62;
+	} else {
+		wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
+		reg_rules = &hdd_world_regrules_60_61_62;
+	}
+
+	/*
+	 * save the original driver regulatory flags
+	 */
+	hdd_ctx->reg.reg_flags = wiphy->regulatory_flags;
+	wiphy_apply_custom_regulatory(wiphy, reg_rules);
+
+	/*
+	 * disable 2.4 Ghz channels that dont have 20 mhz bw
+	 */
+	for (chan_num = 0;
+	     chan_num < wiphy->bands[HDD_NL80211_BAND_2GHZ]->n_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;
+	}
+
+	/*
+	 * restore the driver regulatory flags since
+	 * wiphy_apply_custom_regulatory may have
+	 * changed them
+	 */
+	wiphy->regulatory_flags = hdd_ctx->reg.reg_flags;
+
+}
+#else
+static void hdd_regulatory_wiphy_init(struct hdd_context *hdd_ctx,
+				     struct regulatory *reg,
+				     struct wiphy *wiphy)
+{
+	const struct ieee80211_regdomain *reg_rules;
+
+	if (hdd_is_world_regdomain(reg->reg_domain)) {
+		reg_rules = hdd_get_world_regrules(reg);
+		wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+	} else if (hdd_ctx->config->fRegChangeDefCountry) {
+		wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+		reg_rules = &hdd_world_regrules_60_61_62;
+	} else {
+		wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
+		reg_rules = &hdd_world_regrules_60_61_62;
+	}
+
+	/*
+	 * save the original driver regulatory flags
+	 */
+	hdd_ctx->reg.reg_flags = wiphy->flags;
+	wiphy_apply_custom_regulatory(wiphy, reg_rules);
+
+	/*
+	 * restore the driver regulatory flags since
+	 * wiphy_apply_custom_regulatory may have
+	 * changed them
+	 */
+	wiphy->flags = hdd_ctx->reg.reg_flags;
+
+}
+#endif
+
+/**
+ * is_wiphy_custom_regulatory() - is custom regulatory defined
+ * @wiphy: wiphy
+ *
+ * Return: int
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(WITH_BACKPORTS)
+static int is_wiphy_custom_regulatory(struct wiphy *wiphy)
+{
+
+	return wiphy->regulatory_flags & REGULATORY_CUSTOM_REG;
+}
+#else
+static int is_wiphy_custom_regulatory(struct wiphy *wiphy)
+{
+	return wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY;
+}
+#endif
+
+/**
+ * hdd_modify_wiphy() - modify wiphy
+ * @wiphy: wiphy
+ * @chan: channel structure
+ *
+ * Return: void
+ */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0))
+static void hdd_modify_wiphy(struct wiphy  *wiphy,
+			     struct ieee80211_channel *chan)
+{
+	const struct ieee80211_reg_rule *reg_rule;
+
+	if (is_wiphy_custom_regulatory(wiphy)) {
+		reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
+		if (!IS_ERR(reg_rule)) {
+			chan->flags &= ~IEEE80211_CHAN_DISABLED;
+
+			if (!(reg_rule->flags & NL80211_RRF_DFS)) {
+				hdd_debug("Remove dfs restriction for %u",
+					chan->center_freq);
+				chan->flags &= ~IEEE80211_CHAN_RADAR;
+			}
+
+			if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) {
+				hdd_debug("Remove passive restriction for %u",
+					chan->center_freq);
+				chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+			}
+
+			if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) {
+				hdd_debug("Remove no ibss restriction for %u",
+					chan->center_freq);
+				chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
+			}
+
+			chan->max_power =
+				MBM_TO_DBM(reg_rule->power_rule.max_eirp);
+		}
+	}
+}
+#endif
+
+/**
+ * hdd_set_dfs_region() - set the dfs_region
+ * @dfs_region: the dfs_region to set
+ *
+ * Return: void
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(WITH_BACKPORTS)
+static void hdd_set_dfs_region(struct hdd_context *hdd_ctx,
+			       enum dfs_reg dfs_reg)
+{
+	wlan_reg_set_dfs_region(hdd_ctx->pdev, dfs_reg);
+}
+#endif
+
+/**
+ * hdd_process_regulatory_data() - process regulatory data
+ * @hdd_ctx: hdd context
+ * @wiphy: wiphy
+ * @reset: whether to reset channel data
+ *
+ * Return: void
+ */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0))
+static void hdd_process_regulatory_data(struct hdd_context *hdd_ctx,
+					struct wiphy *wiphy,
+					bool reset)
+{
+	int band_num;
+	int chan_num;
+	enum channel_enum chan_enum = CHAN_ENUM_1;
+	struct ieee80211_channel *wiphy_chan, *wiphy_chan_144 = NULL;
+	struct regulatory_channel *cds_chan;
+	uint8_t band_capability;
+
+	band_capability = hdd_ctx->curr_band;
+
+	for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
+
+		if (wiphy->bands[band_num] == NULL)
+			continue;
+
+		for (chan_num = 0;
+		     chan_num < wiphy->bands[band_num]->n_channels &&
+		     chan_enum < NUM_CHANNELS;
+		     chan_num++) {
+			wiphy_chan =
+				&(wiphy->bands[band_num]->channels[chan_num]);
+			cds_chan = &(reg_channels[chan_enum]);
+			cds_chan->chan_flags = 0;
+			if (CHAN_ENUM_144 == chan_enum)
+				wiphy_chan_144 = wiphy_chan;
+
+			chan_enum++;
+
+			if (!reset)
+				hdd_modify_wiphy(wiphy, wiphy_chan);
+
+			if (hdd_ctx->config->force_ssc_disable_indoor_channel &&
+			     (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY))
+				cds_chan->chan_flags |=
+					REGULATORY_CHAN_INDOOR_ONLY;
+
+			if (wiphy_chan->flags & IEEE80211_CHAN_DISABLED) {
+				cds_chan->state = CHANNEL_STATE_DISABLE;
+				cds_chan->chan_flags |=
+					REGULATORY_CHAN_DISABLED;
+			} else if (wiphy_chan->flags &
+				    (IEEE80211_CHAN_RADAR |
+				     IEEE80211_CHAN_PASSIVE_SCAN)) {
+				cds_chan->state = CHANNEL_STATE_DFS;
+				if (wiphy_chan->flags & IEEE80211_CHAN_RADAR)
+					cds_chan->chan_flags |=
+						REGULATORY_CHAN_RADAR;
+				if (wiphy_chan->flags &
+				    IEEE80211_CHAN_PASSIVE_SCAN)
+					cds_chan->chan_flags |=
+						REGULATORY_CHAN_NO_IR;
+			} else if (wiphy_chan->flags &
+				     IEEE80211_CHAN_INDOOR_ONLY) {
+				cds_chan->chan_flags |=
+						REGULATORY_CHAN_INDOOR_ONLY;
+				if (hdd_ctx->config->indoor_channel_support
+				    == false) {
+					cds_chan->state = CHANNEL_STATE_DFS;
+					wiphy_chan->flags |=
+						IEEE80211_CHAN_PASSIVE_SCAN;
+					cds_chan->chan_flags |=
+						REGULATORY_CHAN_NO_IR;
+				} else
+					cds_chan->state = CHANNEL_STATE_ENABLE;
+			} else
+				cds_chan->state = CHANNEL_STATE_ENABLE;
+			cds_chan->tx_power = wiphy_chan->max_power;
+			if (wiphy_chan->flags & IEEE80211_CHAN_NO_10MHZ)
+				cds_chan->max_bw = 5;
+			else if (wiphy_chan->flags & IEEE80211_CHAN_NO_20MHZ)
+				cds_chan->max_bw = 10;
+			/*
+			 * IEEE80211_CHAN_NO_HT40  is defined as 0x30 in kernel
+			 * 4th BIT representing IEEE80211_CHAN_NO_HT40PLUS
+			 * 5th BIT representing IEEE80211_CHAN_NO_HT40MINUS
+			 *
+			 * In order to claim no 40Mhz support value of
+			 * wiphy_chan->flags needs to be 0x30.
+			 * 0x20 and 0x10 values shows that either HT40+ or
+			 * HT40- is not supported based on BIT set but they
+			 * can support 40Mhz Operation.
+			 */
+			else if ((wiphy_chan->flags & IEEE80211_CHAN_NO_HT40) ==
+					IEEE80211_CHAN_NO_HT40)
+				cds_chan->max_bw = 20;
+			else if (wiphy_chan->flags & IEEE80211_CHAN_NO_80MHZ)
+				cds_chan->max_bw = 40;
+			else if (wiphy_chan->flags & IEEE80211_CHAN_NO_160MHZ)
+				cds_chan->max_bw = 80;
+			else
+				cds_chan->max_bw = 160;
+		}
+	}
+
+	if (0 == (hdd_ctx->reg.eeprom_rd_ext &
+		  (1 << WMI_REG_EXT_FCC_CH_144))) {
+		cds_chan = &(reg_channels[CHAN_ENUM_144]);
+		cds_chan->state = CHANNEL_STATE_DISABLE;
+		if (NULL != wiphy_chan_144)
+			wiphy_chan_144->flags |= IEEE80211_CHAN_DISABLED;
+	}
+
+	wlan_hdd_cfg80211_update_band(hdd_ctx, wiphy, band_capability);
+}
+
+/**
+ * hdd_regulatory_init_no_offload() - regulatory init
+ * @hdd_ctx: hdd context
+ * @wiphy: wiphy
+ *
+ * Return: int
+ */
+static int hdd_regulatory_init_no_offload(struct hdd_context *hdd_ctx,
+					  struct wiphy *wiphy)
+{
+	int ret_val;
+	struct regulatory *reg_info;
+	enum dfs_reg dfs_reg;
+	struct reg_config_vars config_vars;
+
+	reg_info = &hdd_ctx->reg;
+
+	ret_val = cds_fill_some_regulatory_info(reg_info);
+	if (ret_val) {
+		hdd_err("incorrect BDF regulatory data");
+		return ret_val;
+	}
+
+	hdd_set_dfs_region(hdd_ctx, DFS_FCC_REGION);
+
+	hdd_regulatory_wiphy_init(hdd_ctx, reg_info, wiphy);
+
+	hdd_process_regulatory_data(hdd_ctx, wiphy, true);
+
+	reg_info->cc_src = SOURCE_DRIVER;
+
+	ucfg_reg_set_default_country(hdd_ctx->psoc, reg_info->alpha2);
+
+	cds_fill_and_send_ctl_to_fw(reg_info);
+
+	wlan_reg_get_dfs_region(hdd_ctx->pdev, &dfs_reg);
+
+	reg_program_config_vars(hdd_ctx, &config_vars);
+	ucfg_reg_set_config_vars(hdd_ctx->psoc, config_vars);
+	ucfg_reg_program_mas_chan_list(hdd_ctx->psoc,
+				       reg_channels,
+				       hdd_ctx->reg.alpha2,
+				       dfs_reg);
+
+	return 0;
+}
+#endif
+
+/**
+ * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
+ * @wiphy_chan: wiphy channel number
+ * @cds_chan: cds channel structure
+ * @disable: Disable/enable the flags
+ *
+ * Modify wiphy flags and cds state if channel is indoor.
+ *
+ * Return: void
+ */
+void hdd_modify_indoor_channel_state_flags(
+	struct hdd_context *hdd_ctx,
+	struct ieee80211_channel *wiphy_chan,
+	struct regulatory_channel *cds_chan,
+	enum channel_enum chan_enum, int chan_num, bool disable)
+{
+	bool indoor_support = hdd_ctx->config->indoor_channel_support;
+
+	/* Mark indoor channel to disable in wiphy and cds */
+	if (disable) {
+		if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
+			wiphy_chan->flags |=
+				IEEE80211_CHAN_DISABLED;
+			hdd_info("Mark indoor channel %d as disable",
+				cds_chan->center_freq);
+			cds_chan->state =
+				CHANNEL_STATE_DISABLE;
+		}
+	} else {
+		if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
+			wiphy_chan->flags &=
+					~IEEE80211_CHAN_DISABLED;
+			 /*
+			  * Indoor channels may be marked as dfs / enable
+			  * during regulatory processing
+			  */
+			if ((wiphy_chan->flags &
+				(IEEE80211_CHAN_RADAR |
+				IEEE80211_CHAN_PASSIVE_SCAN)) ||
+			     ((indoor_support == false) &&
+				(wiphy_chan->flags &
+				IEEE80211_CHAN_INDOOR_ONLY)))
+				cds_chan->state =
+					CHANNEL_STATE_DFS;
+			else
+				cds_chan->state =
+					CHANNEL_STATE_ENABLE;
+			hdd_debug("Mark indoor channel %d as cds_chan state %d",
+					cds_chan->chan_num, cds_chan->state);
+		}
+	}
+
+}
+
+void hdd_update_indoor_channel(struct hdd_context *hdd_ctx,
+					bool disable)
+{
+	int band_num;
+	int chan_num;
+	enum channel_enum chan_enum = CHAN_ENUM_1;
+	struct ieee80211_channel *wiphy_chan, *wiphy_chan_144 = NULL;
+	struct regulatory_channel *cds_chan;
+	uint8_t band_capability;
+	struct wiphy *wiphy = hdd_ctx->wiphy;
+
+	hdd_enter();
+	hdd_debug("mark indoor channel disable: %d", disable);
+
+	band_capability = hdd_ctx->curr_band;
+	for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
+
+		if (wiphy->bands[band_num] == NULL)
+			continue;
+
+		for (chan_num = 0;
+		     chan_num < wiphy->bands[band_num]->n_channels &&
+		     chan_enum < NUM_CHANNELS;
+		     chan_num++) {
+
+			wiphy_chan =
+				&(wiphy->bands[band_num]->channels[chan_num]);
+			cds_chan = &(reg_channels[chan_enum]);
+			if (chan_enum == CHAN_ENUM_144)
+				wiphy_chan_144 = wiphy_chan;
+
+			chan_enum++;
+			hdd_modify_indoor_channel_state_flags(hdd_ctx,
+				wiphy_chan, cds_chan,
+				chan_enum, chan_num, disable);
+		}
+	}
+
+	/* Notify the regulatory domain to update the channel list */
+	if (QDF_IS_STATUS_ERROR(ucfg_reg_notify_sap_event(hdd_ctx->pdev,
+							  disable))) {
+		hdd_err("Failed to notify sap event");
+	}
+	hdd_exit();
+
+}
+
+/**
+ * hdd_program_country_code() - process channel information from country code
+ * @hdd_ctx: hddc context
+ *
+ * Return: void
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+void hdd_program_country_code(struct hdd_context *hdd_ctx)
+{
+}
+#else
+void hdd_program_country_code(struct hdd_context *hdd_ctx)
+{
+	struct wiphy *wiphy = hdd_ctx->wiphy;
+	uint8_t *country_alpha2 = hdd_ctx->reg.alpha2;
+
+	if (!init_by_reg_core && !init_by_driver) {
+		init_by_driver = true;
+		if (('0' != country_alpha2[0]) ||
+		    ('0' != country_alpha2[1]))
+			regulatory_hint(wiphy, country_alpha2);
+	}
+}
+#endif
+
+int hdd_reg_set_country(struct hdd_context *hdd_ctx, char *country_code)
+{
+	QDF_STATUS status;
+
+	if (!country_code) {
+		hdd_err("country_code is null");
+		return -EINVAL;
+	}
+
+	status = ucfg_reg_set_country(hdd_ctx->pdev, country_code);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to set country");
+
+	return qdf_status_to_os_return(status);
+}
+
+int hdd_reg_set_band(struct net_device *dev, u8 ui_band)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	mac_handle_t mac_handle;
+	enum band_info band;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx;
+	enum band_info currBand;
+	enum band_info connectedBand;
+	long lrc;
+	uint8_t band_capability;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	switch (ui_band) {
+	case WLAN_HDD_UI_BAND_AUTO:
+		band = BAND_ALL;
+		break;
+	case WLAN_HDD_UI_BAND_5_GHZ:
+		band = BAND_5G;
+		break;
+	case WLAN_HDD_UI_BAND_2_4_GHZ:
+		band = BAND_2G;
+		break;
+	default:
+		hdd_err("Invalid band value %u", ui_band);
+		return -EINVAL;
+	}
+
+	hdd_debug("change band to %u", band);
+
+	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EIO;
+
+	if ((band == BAND_2G && band_capability == 2) ||
+	    (band == BAND_5G && band_capability == 1) ||
+	    (band == BAND_ALL && band_capability != 0)) {
+		hdd_err("band value %u violate INI settings %u",
+			  band, band_capability);
+		return -EIO;
+	}
+
+	if (band == BAND_ALL) {
+		hdd_debug("Auto band received. Setting band same as ini value %d",
+			band_capability);
+		band = band_capability;
+	}
+
+	if (ucfg_reg_get_curr_band(hdd_ctx->pdev, &currBand) !=
+	    QDF_STATUS_SUCCESS) {
+		hdd_debug("Failed to get current band config");
+		return -EIO;
+	}
+
+	if (currBand == band)
+		return 0;
+
+	hdd_ctx->curr_band = band;
+
+	/* Change band request received.
+	 * Abort pending scan requests, flush the existing scan results,
+	 * and change the band capability
+	 */
+	hdd_debug("Current band value = %u, new setting %u ",
+			currBand, band);
+
+	mac_handle = hdd_ctx->mac_handle;
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
+				adapter->session_id, INVALID_SCAN_ID, false);
+		connectedBand = hdd_conn_get_connected_band(
+				WLAN_HDD_GET_STATION_CTX_PTR(adapter));
+
+		/* Handling is done only for STA and P2P */
+		if (band != BAND_ALL &&
+		    ((adapter->device_mode == QDF_STA_MODE) ||
+		     (adapter->device_mode == QDF_P2P_CLIENT_MODE)) &&
+		    (hdd_conn_is_connected(
+				WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
+			&& (connectedBand != band)) {
+			status = QDF_STATUS_SUCCESS;
+
+			/* STA already connected on current
+			 * band, So issue disconnect first,
+			 * then change the band
+			 */
+
+			hdd_debug("STA (Device mode %s(%d)) connected in band %u, Changing band to %u, Issuing Disconnect",
+				  qdf_opmode_str(adapter->device_mode),
+				  adapter->device_mode, currBand, band);
+			INIT_COMPLETION(adapter->disconnect_comp_var);
+
+			status = sme_roam_disconnect(
+					mac_handle,
+					adapter->session_id,
+					eCSR_DISCONNECT_REASON_UNSPECIFIED);
+
+			if (QDF_STATUS_SUCCESS != status) {
+				hdd_err("sme_roam_disconnect failure, status: %d",
+						(int)status);
+				return -EINVAL;
+			}
+
+			lrc = wait_for_completion_timeout(
+					&adapter->disconnect_comp_var,
+					msecs_to_jiffies(
+						WLAN_WAIT_TIME_DISCONNECT));
+
+			if (lrc == 0) {
+				hdd_err("Timeout while waiting for csr_roam_disconnect");
+				return -ETIMEDOUT;
+			}
+		}
+
+		sme_scan_flush_result(mac_handle);
+	}
+
+	if (QDF_IS_STATUS_ERROR(ucfg_reg_set_band(hdd_ctx->pdev, band))) {
+		hdd_err("Failed to set the band value to %u", band);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_restore_custom_reg_settings() - restore custom reg settings
+ * @wiphy: wiphy structure
+ * @country_alpha2: alpha2 of the country
+ * @reset: whether wiphy is reset
+ *
+ * Return: void
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0)) || defined(WITH_BACKPORTS)
+static void hdd_restore_custom_reg_settings(struct wiphy *wiphy,
+					    uint8_t *country_alpha2,
+					    bool *reset)
+{
+}
+#else
+static void hdd_restore_custom_reg_settings(struct wiphy *wiphy,
+					    uint8_t *country_alpha2,
+					    bool *reset)
+{
+	struct ieee80211_supported_band *sband;
+	enum nl80211_band band;
+	struct ieee80211_channel *chan;
+	int i;
+
+	if ((country_alpha2[0] == '0') &&
+	    (country_alpha2[1] == '0') &&
+	    (wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)) {
+
+		for (band = 0; band < HDD_NUM_NL80211_BANDS; band++) {
+			sband = wiphy->bands[band];
+			if (!sband)
+				continue;
+			for (i = 0; i < sband->n_channels; i++) {
+				chan = &sband->channels[i];
+				chan->flags = chan->orig_flags;
+				chan->max_antenna_gain = chan->orig_mag;
+				chan->max_power = chan->orig_mpwr;
+			}
+		}
+		*reset = true;
+	}
+}
+#endif
+
+/**
+ * hdd_restore_reg_flags() - restore regulatory flags
+ * @flags: regulatory flags
+ *
+ * Return: void
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(WITH_BACKPORTS)
+static void hdd_restore_reg_flags(struct wiphy *wiphy, uint32_t flags)
+{
+	wiphy->regulatory_flags = flags;
+}
+#else
+static void hdd_restore_reg_flags(struct wiphy *wiphy, uint32_t flags)
+{
+	wiphy->flags = flags;
+}
+#endif
+
+/**
+ * hdd_reg_notifier() - regulatory notifier
+ * @wiphy: wiphy
+ * @request: regulatory request
+ *
+ * Return: void
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+void hdd_reg_notifier(struct wiphy *wiphy,
+		      struct regulatory_request *request)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	char country[REG_ALPHA2_LEN + 1] = {0};
+
+	hdd_debug("country: %c%c, initiator %d, dfs_region: %d",
+		  request->alpha2[0],
+		  request->alpha2[1],
+		  request->initiator,
+		  request->dfs_region);
+
+	switch (request->initiator) {
+	case NL80211_REGDOM_SET_BY_USER:
+		qdf_mem_copy(country, request->alpha2, QDF_MIN(
+			     sizeof(request->alpha2), sizeof(country)));
+		status = ucfg_reg_set_country(hdd_ctx->pdev, country);
+		break;
+	case NL80211_REGDOM_SET_BY_CORE:
+	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+	case NL80211_REGDOM_SET_BY_DRIVER:
+	default:
+		break;
+	}
+
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to set country");
+}
+#else
+void hdd_reg_notifier(struct wiphy *wiphy,
+		      struct regulatory_request *request)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	bool reset = false;
+	enum dfs_reg dfs_reg;
+	struct reg_config_vars config_vars;
+	int ret_val;
+
+	hdd_debug("country: %c%c, initiator %d, dfs_region: %d",
+		  request->alpha2[0],
+		  request->alpha2[1],
+		  request->initiator,
+		  request->dfs_region);
+
+	if (NULL == hdd_ctx) {
+		hdd_err("invalid hdd_ctx pointer");
+		return;
+	}
+
+	if (cds_is_driver_unloading() || cds_is_driver_recovering() ||
+	    cds_is_driver_in_bad_state()) {
+		hdd_err("%s: unloading or ssr in progress, ignore",
+			__func__);
+		return;
+	}
+
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
+		hdd_err("Driver module is closed; dropping request");
+		return;
+	}
+
+	if (hdd_ctx->is_wiphy_suspended == true) {
+		hdd_err("%s: system/cfg80211 is already suspend", __func__);
+		return;
+	}
+
+	if (('K' == request->alpha2[0]) &&
+	    ('R' == request->alpha2[1]))
+		request->dfs_region = (enum nl80211_dfs_regions)DFS_KR_REGION;
+
+	if (('C' == request->alpha2[0]) &&
+	    ('N' == request->alpha2[1]))
+		request->dfs_region = (enum nl80211_dfs_regions)DFS_CN_REGION;
+
+	/* first check if this callback is in response to the driver callback */
+	switch (request->initiator) {
+	case NL80211_REGDOM_SET_BY_DRIVER:
+	case NL80211_REGDOM_SET_BY_CORE:
+	case NL80211_REGDOM_SET_BY_USER:
+
+		if ((false == init_by_driver) &&
+		    (false == init_by_reg_core)) {
+
+			if (NL80211_REGDOM_SET_BY_CORE == request->initiator)
+				return;
+			init_by_reg_core = true;
+		}
+
+		if ((NL80211_REGDOM_SET_BY_DRIVER == request->initiator) &&
+		    (true == init_by_driver)) {
+
+			/*
+			 * restore the driver regulatory flags since
+			 * regulatory_hint may have
+			 * changed them
+			 */
+			hdd_restore_reg_flags(wiphy, hdd_ctx->reg.reg_flags);
+		}
+
+		if (NL80211_REGDOM_SET_BY_CORE == request->initiator) {
+			hdd_ctx->reg.cc_src = SOURCE_CORE;
+			if (is_wiphy_custom_regulatory(wiphy))
+				reset = true;
+		} else if (NL80211_REGDOM_SET_BY_DRIVER == request->initiator) {
+			hdd_ctx->reg.cc_src = SOURCE_DRIVER;
+			sme_set_cc_src(hdd_ctx->mac_handle, SOURCE_DRIVER);
+		} else {
+			hdd_ctx->reg.cc_src = SOURCE_USERSPACE;
+			hdd_restore_custom_reg_settings(wiphy,
+							request->alpha2,
+							&reset);
+		}
+
+		hdd_ctx->reg.alpha2[0] = request->alpha2[0];
+		hdd_ctx->reg.alpha2[1] = request->alpha2[1];
+
+		ret_val = hdd_update_regulatory_info(hdd_ctx);
+		if (ret_val) {
+			hdd_err("invalid reg info, do not process");
+			return;
+		}
+
+		hdd_process_regulatory_data(hdd_ctx, wiphy, reset);
+
+		sme_generic_change_country_code(hdd_ctx->mac_handle,
+						hdd_ctx->reg.alpha2);
+
+		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->pdev, &dfs_reg);
+
+		reg_program_config_vars(hdd_ctx, &config_vars);
+		ucfg_reg_set_config_vars(hdd_ctx->psoc, config_vars);
+		ucfg_reg_program_mas_chan_list(hdd_ctx->psoc,
+					       reg_channels,
+					       hdd_ctx->reg.alpha2,
+					       dfs_reg);
+		break;
+
+	default:
+		break;
+	}
+}
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+static void fill_wiphy_channel(struct ieee80211_channel *wiphy_chan,
+			       struct regulatory_channel *cur_chan)
+{
+
+	wiphy_chan->flags = 0;
+	wiphy_chan->max_power = cur_chan->tx_power;
+
+	if (cur_chan->chan_flags & REGULATORY_CHAN_DISABLED)
+		wiphy_chan->flags  |= IEEE80211_CHAN_DISABLED;
+	if (cur_chan->chan_flags & REGULATORY_CHAN_NO_IR)
+		wiphy_chan->flags  |= IEEE80211_CHAN_NO_IR;
+	if (cur_chan->chan_flags & REGULATORY_CHAN_RADAR)
+		wiphy_chan->flags  |= IEEE80211_CHAN_RADAR;
+	if (cur_chan->chan_flags & REGULATORY_CHAN_NO_OFDM)
+		wiphy_chan->flags  |= IEEE80211_CHAN_NO_OFDM;
+	if (cur_chan->chan_flags & REGULATORY_CHAN_INDOOR_ONLY)
+		wiphy_chan->flags  |= IEEE80211_CHAN_INDOOR_ONLY;
+
+	if (cur_chan->max_bw < 10)
+		wiphy_chan->flags |= IEEE80211_CHAN_NO_10MHZ;
+	if (cur_chan->max_bw < 20)
+		wiphy_chan->flags |= IEEE80211_CHAN_NO_20MHZ;
+	if (cur_chan->max_bw < 40)
+		wiphy_chan->flags |= IEEE80211_CHAN_NO_HT40;
+	if (cur_chan->max_bw < 80)
+		wiphy_chan->flags |= IEEE80211_CHAN_NO_80MHZ;
+	if (cur_chan->max_bw < 160)
+		wiphy_chan->flags |= IEEE80211_CHAN_NO_160MHZ;
+
+	wiphy_chan->orig_flags = wiphy_chan->flags;
+}
+
+static void fill_wiphy_band_channels(struct wiphy *wiphy,
+				     struct regulatory_channel *cur_chan_list,
+				     uint8_t band_id)
+{
+	uint32_t wiphy_num_chan, wiphy_index;
+	uint32_t chan_cnt;
+	struct ieee80211_channel *wiphy_chan;
+
+	if (wiphy->bands[band_id] == NULL)
+		return;
+
+	wiphy_num_chan = wiphy->bands[band_id]->n_channels;
+	wiphy_chan = wiphy->bands[band_id]->channels;
+
+	for (wiphy_index = 0; wiphy_index < wiphy_num_chan; wiphy_index++) {
+		for (chan_cnt = 0; chan_cnt < NUM_CHANNELS; chan_cnt++) {
+			if (wiphy_chan[wiphy_index].center_freq ==
+			    cur_chan_list[chan_cnt].center_freq) {
+				fill_wiphy_channel(&(wiphy_chan[wiphy_index]),
+						   &(cur_chan_list[chan_cnt]));
+				break;
+			}
+		}
+	}
+}
+
+#ifdef FEATURE_WLAN_CH_AVOID
+/**
+ * hdd_ch_avoid_ind() - Avoid notified channels from FW handler
+ * @adapter:	HDD adapter pointer
+ * @indParam:	Channel avoid notification parameter
+ *
+ * Avoid channel notification from FW handler.
+ * FW will send un-safe channel list to avoid over wrapping.
+ * hostapd should not use notified channel
+ *
+ * Return: None
+ */
+void hdd_ch_avoid_ind(struct hdd_context *hdd_ctxt,
+		struct unsafe_ch_list *unsafe_chan_list,
+		struct ch_avoid_ind_type *avoid_freq_list)
+{
+	uint16_t *local_unsafe_list;
+	uint16_t local_unsafe_list_count;
+
+	/* Basic sanity */
+	if (!hdd_ctxt) {
+		hdd_err("Invalid arguments");
+		return;
+	}
+
+	mutex_lock(&hdd_ctxt->avoid_freq_lock);
+	qdf_mem_copy(&hdd_ctxt->coex_avoid_freq_list, avoid_freq_list,
+			sizeof(struct ch_avoid_ind_type));
+	mutex_unlock(&hdd_ctxt->avoid_freq_lock);
+
+	if (hdd_clone_local_unsafe_chan(hdd_ctxt,
+					&local_unsafe_list,
+					&local_unsafe_list_count) != 0) {
+		hdd_err("failed to clone cur unsafe chan list");
+		return;
+	}
+
+	/* clear existing unsafe channel cache */
+	hdd_ctxt->unsafe_channel_count = 0;
+	qdf_mem_zero(hdd_ctxt->unsafe_channel_list,
+					sizeof(hdd_ctxt->unsafe_channel_list));
+
+	hdd_ctxt->unsafe_channel_count = unsafe_chan_list->ch_cnt;
+
+	qdf_mem_copy(hdd_ctxt->unsafe_channel_list, unsafe_chan_list->ch_list,
+					sizeof(hdd_ctxt->unsafe_channel_list));
+	hdd_debug("number of unsafe channels is %d ",
+	       hdd_ctxt->unsafe_channel_count);
+
+	if (pld_set_wlan_unsafe_channel(hdd_ctxt->parent_dev,
+					hdd_ctxt->unsafe_channel_list,
+				hdd_ctxt->unsafe_channel_count)) {
+		hdd_err("Failed to set unsafe channel");
+
+		/* clear existing unsafe channel cache */
+		hdd_ctxt->unsafe_channel_count = 0;
+		qdf_mem_zero(hdd_ctxt->unsafe_channel_list,
+			sizeof(hdd_ctxt->unsafe_channel_list));
+		qdf_mem_free(local_unsafe_list);
+		return;
+	}
+
+	mutex_lock(&hdd_ctxt->avoid_freq_lock);
+	if (hdd_ctxt->dnbs_avoid_freq_list.ch_avoid_range_cnt)
+		if (wlan_hdd_merge_avoid_freqs(avoid_freq_list,
+					&hdd_ctxt->dnbs_avoid_freq_list)) {
+			mutex_unlock(&hdd_ctxt->avoid_freq_lock);
+			hdd_debug("unable to merge avoid freqs");
+			qdf_mem_free(local_unsafe_list);
+			return;
+	}
+	mutex_unlock(&hdd_ctxt->avoid_freq_lock);
+	/*
+	 * first update the unsafe channel list to the platform driver and
+	 * send the avoid freq event to the application
+	 */
+	wlan_hdd_send_avoid_freq_event(hdd_ctxt, avoid_freq_list);
+
+	if (!hdd_ctxt->unsafe_channel_count) {
+		hdd_debug("no unsafe channels - not restarting SAP");
+		qdf_mem_free(local_unsafe_list);
+		return;
+	}
+	if (hdd_local_unsafe_channel_updated(hdd_ctxt,
+					    local_unsafe_list,
+					    local_unsafe_list_count))
+		hdd_unsafe_channel_restart_sap(hdd_ctxt);
+	qdf_mem_free(local_unsafe_list);
+
+}
+#endif
+
+#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
+	    (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
+static void map_nl_reg_rule_flags(uint16_t drv_reg_rule_flag,
+				  uint32_t *regd_rule_flag)
+{
+	if (drv_reg_rule_flag & REGULATORY_CHAN_NO_IR)
+		*regd_rule_flag |= NL80211_RRF_NO_IR;
+	if (drv_reg_rule_flag & REGULATORY_CHAN_RADAR)
+		*regd_rule_flag |= NL80211_RRF_DFS;
+	if (drv_reg_rule_flag & REGULATORY_CHAN_INDOOR_ONLY)
+		*regd_rule_flag |= NL80211_RRF_NO_OUTDOOR;
+	if (drv_reg_rule_flag & REGULATORY_CHAN_NO_OFDM)
+		*regd_rule_flag |= NL80211_RRF_NO_OFDM;
+}
+
+/**
+ * dfs_reg_to_nl80211_dfs_regions() - convert dfs_reg to nl80211_dfs_regions
+ * @dfs_region: DFS region
+ *
+ * Return: nl80211_dfs_regions
+ */
+static enum nl80211_dfs_regions dfs_reg_to_nl80211_dfs_regions(
+					enum dfs_reg dfs_region)
+{
+	switch (dfs_region) {
+	case DFS_UNINIT_REGION:
+		return NL80211_DFS_UNSET;
+	case DFS_FCC_REGION:
+		return NL80211_DFS_FCC;
+	case DFS_ETSI_REGION:
+		return NL80211_DFS_ETSI;
+	case DFS_MKK_REGION:
+		return NL80211_DFS_JP;
+	default:
+		return NL80211_DFS_UNSET;
+	}
+}
+
+void hdd_send_wiphy_regd_sync_event(struct hdd_context *hdd_ctx)
+{
+	struct ieee80211_regdomain *regd;
+	struct ieee80211_reg_rule *regd_rules;
+	struct reg_rule_info reg_rules_struct;
+	struct reg_rule_info *reg_rules;
+	QDF_STATUS  status;
+	uint8_t i;
+
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is NULL");
+		return;
+	}
+
+	status = ucfg_reg_get_regd_rules(hdd_ctx->pdev, &reg_rules_struct);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("could not get reg rules");
+		return;
+	}
+
+	reg_rules = &reg_rules_struct;
+	if (!reg_rules->num_of_reg_rules) {
+		hdd_err("no reg rules %d", reg_rules->num_of_reg_rules);
+		return;
+	}
+
+	regd = qdf_mem_malloc((reg_rules->num_of_reg_rules *
+				sizeof(*regd_rules) + sizeof(*regd)));
+	if (!regd) {
+		hdd_err("mem alloc failed for reg rules");
+		return;
+	}
+
+	regd->n_reg_rules = reg_rules->num_of_reg_rules;
+	qdf_mem_copy(regd->alpha2, reg_rules->alpha2, REG_ALPHA2_LEN + 1);
+	regd->dfs_region =
+		dfs_reg_to_nl80211_dfs_regions(reg_rules->dfs_region);
+	regd_rules = regd->reg_rules;
+	hdd_debug("Regulatory Domain %s", regd->alpha2);
+	hdd_debug("start freq\tend freq\t@ max_bw\tant_gain\tpwr\tflags");
+	for (i = 0; i < reg_rules->num_of_reg_rules; i++) {
+		regd_rules[i].freq_range.start_freq_khz =
+			reg_rules->reg_rules[i].start_freq * 1000;
+		regd_rules[i].freq_range.end_freq_khz =
+			reg_rules->reg_rules[i].end_freq * 1000;
+		regd_rules[i].freq_range.max_bandwidth_khz =
+			reg_rules->reg_rules[i].max_bw * 1000;
+		regd_rules[i].power_rule.max_antenna_gain =
+			reg_rules->reg_rules[i].ant_gain * 100;
+		regd_rules[i].power_rule.max_eirp =
+			reg_rules->reg_rules[i].reg_power * 100;
+		map_nl_reg_rule_flags(reg_rules->reg_rules[i].flags,
+				      &regd_rules[i].flags);
+		hdd_debug("%d KHz\t%d KHz\t@ %d KHz\t%d\t\t%d\t%d",
+			  regd_rules[i].freq_range.start_freq_khz,
+			  regd_rules[i].freq_range.end_freq_khz,
+			  regd_rules[i].freq_range.max_bandwidth_khz,
+			  regd_rules[i].power_rule.max_antenna_gain,
+			  regd_rules[i].power_rule.max_eirp,
+			  regd_rules[i].flags);
+	}
+
+	regulatory_set_wiphy_regd(hdd_ctx->wiphy, regd);
+
+	hdd_debug("regd sync event sent with reg rules info");
+	qdf_mem_free(regd);
+}
+#endif
+
+static void hdd_regulatory_dyn_cbk(struct wlan_objmgr_psoc *psoc,
+				   struct wlan_objmgr_pdev *pdev,
+				   struct regulatory_channel *chan_list,
+				   struct avoid_freq_ind_data *avoid_freq_ind,
+				   void *arg)
+{
+	struct wiphy *wiphy;
+	struct pdev_osif_priv *pdev_priv;
+	struct hdd_context *hdd_ctx;
+	enum country_src cc_src;
+	uint8_t alpha2[REG_ALPHA2_LEN + 1];
+
+	pdev_priv = wlan_pdev_get_ospriv(pdev);
+	wiphy = pdev_priv->wiphy;
+	hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_debug("process channel list update from regulatory");
+
+	fill_wiphy_band_channels(wiphy, chan_list, NL80211_BAND_2GHZ);
+	fill_wiphy_band_channels(wiphy, chan_list, NL80211_BAND_5GHZ);
+
+	cc_src = ucfg_reg_get_cc_and_src(hdd_ctx->psoc, alpha2);
+	qdf_mem_copy(hdd_ctx->reg.alpha2, alpha2, REG_ALPHA2_LEN + 1);
+	sme_set_cc_src(hdd_ctx->mac_handle, cc_src);
+
+	/* Check the kernel version for upstream commit aced43ce780dc5 that
+	 * has support for processing user cell_base hints when wiphy is
+	 * self managed or check the backport flag for the same.
+	 */
+#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
+	    (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
+	if (wiphy->registered)
+		hdd_send_wiphy_regd_sync_event(hdd_ctx);
+#endif
+
+	if (avoid_freq_ind)
+		hdd_ch_avoid_ind(hdd_ctx, &avoid_freq_ind->chan_list,
+				&avoid_freq_ind->freq_list);
+	else
+		sme_generic_change_country_code(hdd_ctx->mac_handle,
+				hdd_ctx->reg.alpha2);
+}
+
+int hdd_regulatory_init(struct hdd_context *hdd_ctx, struct wiphy *wiphy)
+{
+	bool offload_enabled;
+	struct reg_config_vars config_vars;
+	struct regulatory_channel cur_chan_list[NUM_CHANNELS];
+	enum country_src cc_src;
+	uint8_t alpha2[REG_ALPHA2_LEN + 1];
+
+	reg_program_config_vars(hdd_ctx, &config_vars);
+	ucfg_reg_register_chan_change_callback(hdd_ctx->psoc,
+					       hdd_regulatory_dyn_cbk,
+					       NULL);
+
+	ucfg_reg_set_config_vars(hdd_ctx->psoc, config_vars);
+
+	wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
+	/* Check the kernel version for upstream commit aced43ce780dc5 that
+	 * has support for processing user cell_base hints when wiphy is
+	 * self managed or check the backport flag for the same.
+	 */
+#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
+	    (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
+	wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
+#endif
+	wiphy->reg_notifier = hdd_reg_notifier;
+	offload_enabled = ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc);
+	hdd_debug("regulatory offload_enabled %d", offload_enabled);
+	if (offload_enabled) {
+		hdd_ctx->reg_offload = true;
+		ucfg_reg_get_current_chan_list(hdd_ctx->pdev,
+					       cur_chan_list);
+		fill_wiphy_band_channels(wiphy, cur_chan_list,
+					 NL80211_BAND_2GHZ);
+		fill_wiphy_band_channels(wiphy, cur_chan_list,
+					 NL80211_BAND_5GHZ);
+
+		cc_src = ucfg_reg_get_cc_and_src(hdd_ctx->psoc, alpha2);
+		qdf_mem_copy(hdd_ctx->reg.alpha2, alpha2, REG_ALPHA2_LEN + 1);
+		sme_set_cc_src(hdd_ctx->mac_handle, cc_src);
+	} else {
+		hdd_ctx->reg_offload = false;
+	}
+
+	return 0;
+}
+
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+int hdd_regulatory_init(struct hdd_context *hdd_ctx, struct wiphy *wiphy)
+{
+	hdd_ctx->reg_offload = false;
+	wiphy->reg_notifier = hdd_reg_notifier;
+	wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
+	wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
+	hdd_regulatory_init_no_offload(hdd_ctx, wiphy);
+
+	return 0;
+}
+
+#else
+int hdd_regulatory_init(struct hdd_context *hdd_ctx, struct wiphy *wiphy)
+{
+	hdd_ctx->reg_offload = false;
+	wiphy->reg_notifier = hdd_reg_notifier;
+	wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
+	wiphy->country_ie_pref |= NL80211_COUNTRY_IE_IGNORE_CORE;
+	hdd_regulatory_init_no_offload(hdd_ctx, wiphy);
+
+	return 0;
+}
+#endif
diff --git a/core/hdd/src/wlan_hdd_rssi_monitor.c b/core/hdd/src/wlan_hdd_rssi_monitor.c
new file mode 100644
index 0000000..b78116f
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_rssi_monitor.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_rssi_monitor.c
+ *
+ * WLAN rssi monitoring functions
+ *
+ */
+
+#include <wlan_hdd_includes.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <wlan_hdd_ext_scan.h>
+#include <wlan_hdd_rssi_monitor.h>
+
+/*
+ * define short names for the global vendor params
+ * used by __wlan_hdd_cfg80211_monitor_rssi()
+ */
+#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
+#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
+#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
+#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
+#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
+
+/**
+ * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
+				 struct wireless_dev *wdev,
+				 const void *data,
+				 int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[PARAM_MAX + 1];
+	struct rssi_monitor_req req;
+	QDF_STATUS status;
+	int ret;
+	uint32_t control;
+	mac_handle_t mac_handle;
+	static const struct nla_policy policy[PARAM_MAX + 1] = {
+			[PARAM_REQUEST_ID] = { .type = NLA_U32 },
+			[PARAM_CONTROL] = { .type = NLA_U32 },
+			[PARAM_MIN_RSSI] = { .type = NLA_S8 },
+			[PARAM_MAX_RSSI] = { .type = NLA_S8 },
+	};
+
+	hdd_enter_dev(dev);
+
+	if (wlan_hdd_validate_session_id(adapter->session_id)) {
+		hdd_err("invalid session id: %d", adapter->session_id);
+		return -EINVAL;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
+		hdd_err("Not in Connected state!");
+		return -ENOTSUPP;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (!tb[PARAM_REQUEST_ID]) {
+		hdd_err("attr request id failed");
+		return -EINVAL;
+	}
+
+	if (!tb[PARAM_CONTROL]) {
+		hdd_err("attr control failed");
+		return -EINVAL;
+	}
+
+	req.request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
+	req.session_id = adapter->session_id;
+	control = nla_get_u32(tb[PARAM_CONTROL]);
+
+	if (control == QCA_WLAN_RSSI_MONITORING_START) {
+		req.control = true;
+		if (!tb[PARAM_MIN_RSSI]) {
+			hdd_err("attr min rssi failed");
+			return -EINVAL;
+		}
+
+		if (!tb[PARAM_MAX_RSSI]) {
+			hdd_err("attr max rssi failed");
+			return -EINVAL;
+		}
+
+		req.min_rssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
+		req.max_rssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
+
+		if (!(req.min_rssi < req.max_rssi)) {
+			hdd_warn("min_rssi: %d must be less than max_rssi: %d",
+				 req.min_rssi, req.max_rssi);
+			return -EINVAL;
+		}
+		hdd_debug("Min_rssi: %d Max_rssi: %d",
+			  req.min_rssi, req.max_rssi);
+
+	} else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
+		req.control = false;
+	} else {
+		hdd_err("Invalid control cmd: %d", control);
+		return -EINVAL;
+	}
+	hdd_debug("Request Id: %u Session_id: %d Control: %d",
+		  req.request_id, req.session_id, req.control);
+
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_set_rssi_monitoring(mac_handle, &req);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_set_rssi_monitoring failed(err=%d)", status);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * done with short names for the global vendor params
+ * used by __wlan_hdd_cfg80211_monitor_rssi()
+ */
+#undef PARAM_MAX
+#undef PARAM_CONTROL
+#undef PARAM_REQUEST_ID
+#undef PARAM_MAX_RSSI
+#undef PARAM_MIN_RSSI
+
+int
+wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
+			       const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+void hdd_rssi_threshold_breached(hdd_handle_t hdd_handle,
+				 struct rssi_breach_event *data)
+{
+	struct hdd_context *hdd_ctx  = hdd_handle_to_context(hdd_handle);
+	struct sk_buff *skb;
+
+	hdd_enter();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+	if (!data) {
+		hdd_err("data is null");
+		return;
+	}
+
+	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+				  NULL,
+				  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
+				  QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
+				  GFP_KERNEL);
+
+	if (!skb) {
+		hdd_err("mem alloc failed");
+		return;
+	}
+
+	hdd_debug("Req Id: %u Current rssi: %d",
+		  data->request_id, data->curr_rssi);
+	hdd_debug("Current BSSID: "MAC_ADDRESS_STR,
+		  MAC_ADDR_ARRAY(data->curr_bssid.bytes));
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
+			data->request_id) ||
+	    nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
+		    sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
+	    nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
+		       data->curr_rssi)) {
+		hdd_err("nla put fail");
+		goto fail;
+	}
+
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+	return;
+
+fail:
+	kfree_skb(skb);
+}
+
diff --git a/core/hdd/src/wlan_hdd_rssi_monitor.h b/core/hdd/src/wlan_hdd_rssi_monitor.h
new file mode 100644
index 0000000..ac621c4
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_rssi_monitor.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __WLAN_HDD_RSSI_MONITOR_H
+#define __WLAN_HDD_RSSI_MONITOR_H
+
+/**
+ * DOC: wlan_hdd_rssi_monitor_h
+ *
+ * WLAN Host Device Driver RSSI monitoring API specification
+ */
+
+#ifdef FEATURE_RSSI_MONITOR
+/**
+ * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success; errno on failure
+ */
+int
+wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
+			       const void *data, int data_len);
+
+/**
+ * hdd_rssi_threshold_breached() - rssi breached NL event
+ * @hdd_handle: HDD handle
+ * @data: rssi breached event data
+ *
+ * This function reads the rssi breached event %data and fill in the skb with
+ * NL attributes and send up the NL event.
+ *
+ * Return: none
+ */
+void hdd_rssi_threshold_breached(hdd_handle_t hdd_handle,
+				 struct rssi_breach_event *data);
+
+#define FEATURE_RSSI_MONITOR_VENDOR_EVENTS			\
+[QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {		\
+	.vendor_id = QCA_NL80211_VENDOR_ID,			\
+	.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI	\
+},
+
+#define FEATURE_RSSI_MONITOR_VENDOR_COMMANDS			\
+{								\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,		\
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,	\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |			\
+		WIPHY_VENDOR_CMD_NEED_NETDEV |			\
+		WIPHY_VENDOR_CMD_NEED_RUNNING,			\
+	.doit = wlan_hdd_cfg80211_monitor_rssi			\
+},
+
+#else /* FEATURE_RSSI_MONITOR */
+static inline
+void hdd_rssi_threshold_breached(hdd_handle_t hdd_handle,
+				 struct rssi_breach_event *data)
+{
+}
+
+#define FEATURE_RSSI_MONITOR_VENDOR_EVENTS
+#define FEATURE_RSSI_MONITOR_VENDOR_COMMANDS
+#endif /* FEATURE_RSSI_MONITOR */
+
+#endif /* __WLAN_HDD_RSSI_MONITOR_H */
+
diff --git a/core/hdd/src/wlan_hdd_rx_monitor.c b/core/hdd/src/wlan_hdd_rx_monitor.c
new file mode 100644
index 0000000..ff88f7a
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_rx_monitor.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include "wlan_hdd_includes.h"
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <cds_sched.h>
+#include <cds_utils.h>
+#include "wlan_hdd_rx_monitor.h"
+
+/**
+ * hdd_rx_monitor_callback(): Callback function for receive monitor mode
+ * @vdev: Handle to vdev object
+ * @mpdu: pointer to mpdu to be delivered to os
+ * @rx_status: receive status
+ *
+ * Returns: None
+ */
+void hdd_rx_monitor_callback(ol_osif_vdev_handle context,
+				qdf_nbuf_t rxbuf,
+				void *rx_status)
+{
+	struct hdd_adapter *adapter;
+	int rxstat;
+	struct sk_buff *skb;
+	struct sk_buff *skb_next;
+	unsigned int cpu_index;
+
+	qdf_assert(context);
+	qdf_assert(rxbuf);
+
+	adapter = (struct hdd_adapter *)context;
+	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			"invalid adapter %pK", adapter);
+		return;
+	}
+
+	cpu_index = wlan_hdd_get_cpu();
+
+	/* walk the chain until all are processed */
+	skb = (struct sk_buff *)rxbuf;
+	while (NULL != skb) {
+		skb_next = skb->next;
+		skb->dev = adapter->dev;
+
+		++adapter->hdd_stats.tx_rx_stats.rx_packets[cpu_index];
+		++adapter->stats.rx_packets;
+		adapter->stats.rx_bytes += skb->len;
+
+		/* Remove SKB from internal tracking table before submitting
+		 * it to stack
+		 */
+		qdf_net_buf_debug_release_skb(skb);
+
+		/*
+		 * If this is not a last packet on the chain
+		 * Just put packet into backlog queue, not scheduling RX sirq
+		 */
+		if (skb->next) {
+			rxstat = netif_rx(skb);
+		} else {
+			/*
+			 * This is the last packet on the chain
+			 * Scheduling rx sirq
+			 */
+			rxstat = netif_rx_ni(skb);
+		}
+
+		if (NET_RX_SUCCESS == rxstat)
+			++adapter->
+				hdd_stats.tx_rx_stats.rx_delivered[cpu_index];
+		else
+			++adapter->hdd_stats.tx_rx_stats.rx_refused[cpu_index];
+
+		skb = skb_next;
+	}
+}
+
+/**
+ * hdd_monitor_set_rx_monitor_cb(): Set rx monitor mode callback function
+ * @txrx: pointer to txrx ops
+ * @rx_monitor_cb: pointer to callback function
+ *
+ * Returns: None
+ */
+void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
+				ol_txrx_rx_mon_fp rx_monitor_cb)
+{
+	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);
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+	hdd_enter_dev(dev);
+
+	return cdp_set_monitor_mode(soc,
+			(struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
+			(struct cdp_pdev *)pdev, adapter->session_id), false);
+}
diff --git a/core/hdd/src/wlan_hdd_rx_monitor.h b/core/hdd/src/wlan_hdd_rx_monitor.h
new file mode 100644
index 0000000..61f8ed2
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_rx_monitor.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#ifndef __WLAN_HDD_RX_MONITOR_H
+#define __WLAN_HDD_RX_MONITOR_H
+
+struct ol_txrx_ops;
+
+#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390)
+void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
+				ol_txrx_rx_mon_fp rx_monitor_cb);
+
+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 inline void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
+					ol_txrx_rx_mon_fp rx_monitor_cb){ }
+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 0;
+}
+#endif /* CONFIG_LITHIUM */
+
+#endif /* __WLAN_HDD_RX_MONITOR_H */
+
diff --git a/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c
new file mode 100644
index 0000000..1dcd953
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_sap_cond_chan_switch.c
+ *
+ * WLAN SAP conditional channel switch functions
+ *
+ */
+
+#include <wlan_hdd_includes.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <cds_utils.h>
+#include <qdf_str.h>
+#include <wlan_hdd_sap_cond_chan_switch.h>
+
+/**
+ * wlan_hdd_set_pre_cac_status() - Set the pre cac status
+ * @pre_cac_adapter: AP adapter used for pre cac
+ * @status: Status (true or false)
+ *
+ * Sets the status of pre cac i.e., whether the pre cac is active or not
+ *
+ * Return: Zero on success, non-zero on failure
+ */
+static int wlan_hdd_set_pre_cac_status(struct hdd_adapter *pre_cac_adapter,
+				       bool status)
+{
+	QDF_STATUS ret;
+
+	ret = wlan_sap_set_pre_cac_status(
+		WLAN_HDD_GET_SAP_CTX_PTR(pre_cac_adapter), status);
+	if (QDF_IS_STATUS_ERROR(ret))
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_set_chan_before_pre_cac() - Save the channel before pre cac
+ * @ap_adapter: AP adapter
+ * @chan_before_pre_cac: Channel
+ *
+ * Saves the channel which the AP was beaconing on before moving to the pre
+ * cac channel. If radar is detected on the pre cac channel, this saved
+ * channel will be used for AP operations.
+ *
+ * Return: Zero on success, non-zero on failure
+ */
+static int wlan_hdd_set_chan_before_pre_cac(struct hdd_adapter *ap_adapter,
+					    uint8_t chan_before_pre_cac)
+{
+	QDF_STATUS ret;
+
+	ret = wlan_sap_set_chan_before_pre_cac(
+		WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter), chan_before_pre_cac);
+	if (QDF_IS_STATUS_ERROR(ret))
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_validate_and_get_pre_cac_ch() - Validate and get pre cac channel
+ * @hdd_ctx: HDD context
+ * @ap_adapter: AP adapter
+ * @channel: Channel requested by userspace
+ * @pre_cac_chan: Pointer to the pre CAC channel
+ *
+ * Validates the channel provided by userspace. If user provided channel 0,
+ * a valid outdoor channel must be selected from the regulatory channel.
+ *
+ * Return: Zero on success and non zero value on error
+ */
+static int wlan_hdd_validate_and_get_pre_cac_ch(struct hdd_context *hdd_ctx,
+						struct hdd_adapter *ap_adapter,
+						uint8_t channel,
+						uint8_t *pre_cac_chan)
+{
+	uint32_t i;
+	QDF_STATUS status;
+	uint32_t weight_len = 0;
+	uint32_t len = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+	uint8_t channel_list[QDF_MAX_NUM_CHAN] = {0};
+	uint8_t pcl_weights[QDF_MAX_NUM_CHAN] = {0};
+	mac_handle_t mac_handle;
+
+	if (channel == 0) {
+		/* Channel is not obtained from PCL because PCL may not have
+		 * the entire channel list. For example: if SAP is up on
+		 * channel 6 and PCL is queried for the next SAP interface,
+		 * if SCC is preferred, the PCL will contain only the channel
+		 * 6. But, we are in need of a DFS channel. So, going with the
+		 * first channel from the valid channel list.
+		 */
+		status = policy_mgr_get_valid_chans(hdd_ctx->psoc,
+						    channel_list, &len);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Failed to get channel list");
+			return -EINVAL;
+		}
+		policy_mgr_update_with_safe_channel_list(hdd_ctx->psoc,
+							 channel_list, &len,
+							 pcl_weights,
+							 weight_len);
+		for (i = 0; i < len; i++) {
+			if (wlan_reg_is_dfs_ch(hdd_ctx->pdev,
+					       channel_list[i])) {
+				*pre_cac_chan = channel_list[i];
+				break;
+			}
+		}
+		if (*pre_cac_chan == 0) {
+			hdd_err("unable to find outdoor channel");
+			return -EINVAL;
+		}
+	} else {
+		/* Only when driver selects a channel, check is done for
+		 * unnsafe and NOL channels. When user provides a fixed channel
+		 * the user is expected to take care of this.
+		 */
+		mac_handle = hdd_ctx->mac_handle;
+		if (!sme_is_channel_valid(mac_handle, channel) ||
+		    !wlan_reg_is_dfs_ch(hdd_ctx->pdev, channel)) {
+			hdd_err("Invalid channel for pre cac:%d", channel);
+			return -EINVAL;
+		}
+		*pre_cac_chan = channel;
+	}
+	hdd_debug("selected pre cac channel:%d", *pre_cac_chan);
+	return 0;
+}
+
+/**
+ * wlan_hdd_request_pre_cac() - Start pre CAC in the driver
+ * @channel: Channel option provided by userspace
+ *
+ * Sets the driver to the required hardware mode and start an adapter for
+ * pre CAC which will mimic an AP.
+ *
+ * Return: Zero on success, non-zero value on error
+ */
+int wlan_hdd_request_pre_cac(uint8_t channel)
+{
+	uint8_t pre_cac_chan = 0, *mac_addr;
+	struct hdd_context *hdd_ctx;
+	int ret;
+	struct hdd_adapter *ap_adapter, *pre_cac_adapter;
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	QDF_STATUS status;
+	struct wiphy *wiphy;
+	struct net_device *dev;
+	struct cfg80211_chan_def chandef;
+	enum nl80211_channel_type channel_type;
+	uint32_t freq;
+	struct ieee80211_channel *chan;
+	mac_handle_t mac_handle;
+	bool val;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (wlan_hdd_validate_context(hdd_ctx) != 0)
+		return -EINVAL;
+
+	if (policy_mgr_get_connection_count(hdd_ctx->psoc) > 1) {
+		hdd_err("pre cac not allowed in concurrency");
+		return -EINVAL;
+	}
+
+	ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
+	if (!ap_adapter) {
+		hdd_err("unable to get SAP adapter");
+		return -EINVAL;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	val = wlan_sap_is_pre_cac_active(mac_handle);
+	if (val) {
+		hdd_err("pre cac is already in progress");
+		return -EINVAL;
+	}
+
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
+	if (!hdd_ap_ctx) {
+		hdd_err("SAP context is NULL");
+		return -EINVAL;
+	}
+
+	if (wlan_reg_is_dfs_ch(hdd_ctx->pdev,
+			       hdd_ap_ctx->operating_channel)) {
+		hdd_err("SAP is already on DFS channel:%d",
+			hdd_ap_ctx->operating_channel);
+		return -EINVAL;
+	}
+
+	if (!WLAN_REG_IS_24GHZ_CH(hdd_ap_ctx->operating_channel)) {
+		hdd_err("pre CAC alllowed only when SAP is in 2.4GHz:%d",
+			hdd_ap_ctx->operating_channel);
+		return -EINVAL;
+	}
+
+	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx);
+	if (!mac_addr) {
+		hdd_err("can't add virtual intf: Not getting valid mac addr");
+		return -EINVAL;
+	}
+
+	hdd_debug("channel:%d", channel);
+
+	ret = wlan_hdd_validate_and_get_pre_cac_ch(hdd_ctx, ap_adapter, channel,
+						   &pre_cac_chan);
+	if (ret != 0) {
+		hdd_err("can't validate pre-cac channel");
+		goto release_intf_addr_and_return_failure;
+	}
+
+	hdd_debug("starting pre cac SAP  adapter");
+
+	/* Starting a SAP adapter:
+	 * Instead of opening an adapter, we could just do a SME open session
+	 * for AP type. But, start BSS would still need an adapter.
+	 * So, this option is not taken.
+	 *
+	 * hdd open adapter is going to register this precac interface with
+	 * user space. This interface though exposed to user space will be in
+	 * DOWN state. Consideration was done to avoid this registration to the
+	 * user space. But, as part of SAP operations multiple events are sent
+	 * to user space. Some of these events received from unregistered
+	 * interface was causing crashes. So, retaining the registration.
+	 *
+	 * So, this interface would remain registered and will remain in DOWN
+	 * state for the CAC duration. We will add notes in the feature
+	 * announcement to not use this temporary interface for any activity
+	 * from user space.
+	 */
+	pre_cac_adapter = hdd_open_adapter(hdd_ctx, QDF_SAP_MODE, "precac%d",
+					   mac_addr, NET_NAME_UNKNOWN, true);
+	if (!pre_cac_adapter) {
+		hdd_err("error opening the pre cac adapter");
+		goto release_intf_addr_and_return_failure;
+	}
+
+	/*
+	 * This interface is internally created by the driver. So, no interface
+	 * up comes for this interface from user space and hence starting
+	 * the adapter internally.
+	 */
+	if (hdd_start_adapter(pre_cac_adapter)) {
+		hdd_err("error starting the pre cac adapter");
+		goto close_pre_cac_adapter;
+	}
+
+	hdd_debug("preparing for start ap/bss on the pre cac adapter");
+
+	wiphy = hdd_ctx->wiphy;
+	dev = pre_cac_adapter->dev;
+
+	/* Since this is only a dummy interface lets us use the IEs from the
+	 * other active SAP interface. In regular scenarios, these IEs would
+	 * come from the user space entity
+	 */
+	pre_cac_adapter->session.ap.beacon = qdf_mem_malloc(
+			sizeof(*ap_adapter->session.ap.beacon));
+	if (!pre_cac_adapter->session.ap.beacon) {
+		hdd_err("failed to alloc mem for beacon");
+		goto stop_close_pre_cac_adapter;
+	}
+	qdf_mem_copy(pre_cac_adapter->session.ap.beacon,
+		     ap_adapter->session.ap.beacon,
+		     sizeof(*pre_cac_adapter->session.ap.beacon));
+	pre_cac_adapter->session.ap.sap_config.ch_width_orig =
+			ap_adapter->session.ap.sap_config.ch_width_orig;
+	pre_cac_adapter->session.ap.sap_config.authType =
+			ap_adapter->session.ap.sap_config.authType;
+
+	/* Premise is that on moving from 2.4GHz to 5GHz, the SAP will continue
+	 * to operate on the same bandwidth as that of the 2.4GHz operations.
+	 * Only bandwidths 20MHz/40MHz are possible on 2.4GHz band.
+	 */
+	switch (ap_adapter->session.ap.sap_config.ch_width_orig) {
+	case CH_WIDTH_20MHZ:
+		channel_type = NL80211_CHAN_HT20;
+		break;
+	case CH_WIDTH_40MHZ:
+		if (ap_adapter->session.ap.sap_config.sec_ch >
+				ap_adapter->session.ap.sap_config.channel)
+			channel_type = NL80211_CHAN_HT40PLUS;
+		else
+			channel_type = NL80211_CHAN_HT40MINUS;
+		break;
+	default:
+		channel_type = NL80211_CHAN_NO_HT;
+		break;
+	}
+
+	freq = cds_chan_to_freq(pre_cac_chan);
+	chan = ieee80211_get_channel(wiphy, freq);
+	if (!chan) {
+		hdd_err("channel converion failed");
+		goto stop_close_pre_cac_adapter;
+	}
+
+	cfg80211_chandef_create(&chandef, chan, channel_type);
+
+	hdd_debug("orig width:%d channel_type:%d freq:%d",
+		  ap_adapter->session.ap.sap_config.ch_width_orig,
+		  channel_type, freq);
+	/*
+	 * Doing update after opening and starting pre-cac adapter will make
+	 * sure that driver won't do hardware mode change if there are any
+	 * initial hick-ups or issues in pre-cac adapter's configuration.
+	 * Since current SAP is in 2.4GHz and pre CAC channel is in 5GHz, this
+	 * connection update should result in DBS mode
+	 */
+	status = policy_mgr_update_and_wait_for_connection_update(
+					hdd_ctx->psoc,
+					ap_adapter->session_id,
+					pre_cac_chan,
+					POLICY_MGR_UPDATE_REASON_PRE_CAC);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("error in moving to DBS mode");
+		goto stop_close_pre_cac_adapter;
+	}
+
+	ret = wlan_hdd_set_channel(wiphy, dev, &chandef, channel_type);
+	if (ret != 0) {
+		hdd_err("failed to set channel");
+		goto stop_close_pre_cac_adapter;
+	}
+
+	status = wlan_hdd_cfg80211_start_bss(pre_cac_adapter, NULL,
+			PRE_CAC_SSID, qdf_str_len(PRE_CAC_SSID),
+			NL80211_HIDDEN_SSID_NOT_IN_USE, false);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("start bss failed");
+		goto stop_close_pre_cac_adapter;
+	}
+
+	/*
+	 * The pre cac status is set here. But, it would not be reset explicitly
+	 * anywhere, since after the pre cac success/failure, the pre cac
+	 * adapter itself would be removed.
+	 */
+	ret = wlan_hdd_set_pre_cac_status(pre_cac_adapter, true);
+	if (ret != 0) {
+		hdd_err("failed to set pre cac status");
+		goto stop_close_pre_cac_adapter;
+	}
+
+	ret = wlan_hdd_set_chan_before_pre_cac(ap_adapter,
+					       hdd_ap_ctx->operating_channel);
+	if (ret != 0) {
+		hdd_err("failed to set channel before pre cac");
+		goto stop_close_pre_cac_adapter;
+	}
+
+	ap_adapter->pre_cac_chan = pre_cac_chan;
+
+	return 0;
+
+stop_close_pre_cac_adapter:
+	hdd_stop_adapter(hdd_ctx, pre_cac_adapter);
+	qdf_mem_free(pre_cac_adapter->session.ap.beacon);
+	pre_cac_adapter->session.ap.beacon = NULL;
+close_pre_cac_adapter:
+	hdd_close_adapter(hdd_ctx, pre_cac_adapter, false);
+release_intf_addr_and_return_failure:
+	/*
+	 * Release the interface address as the adapter
+	 * failed to start, if you don't release then next
+	 * adapter which is trying to come wouldn't get valid
+	 * mac address. Remember we have limited pool of mac addresses
+	 */
+	wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
+	return -EINVAL;
+}
+
+/**
+ * __wlan_hdd_cfg80211_conditional_chan_switch() - Conditional channel switch
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Processes the conditional channel switch request and invokes the helper
+ * APIs to process the channel switch request.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_conditional_chan_switch(struct wiphy *wiphy,
+					    struct wireless_dev *wdev,
+					    const void *data,
+					    int data_len)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter;
+	struct nlattr
+		*tb[QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_MAX + 1];
+	uint32_t freq_len, i;
+	uint32_t *freq;
+	uint8_t chans[QDF_MAX_NUM_CHAN] = {0};
+	bool is_dfs_mode_enabled = false;
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (QDF_STATUS_SUCCESS != ucfg_mlme_get_dfs_master_capability(
+				hdd_ctx->psoc, &is_dfs_mode_enabled)) {
+		hdd_err("Failed to get dfs master capability");
+		return -EINVAL;
+	}
+
+	if (!is_dfs_mode_enabled) {
+		hdd_err("DFS master capability is not present in the driver");
+		return -EINVAL;
+	}
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	if (adapter->device_mode != QDF_SAP_MODE) {
+		hdd_err("Invalid device mode %d", adapter->device_mode);
+		return -EINVAL;
+	}
+
+	/*
+	 * audit note: it is ok to pass a NULL policy here since only
+	 * one attribute is parsed which is array of frequencies and
+	 * it is explicitly validated for both under read and over read
+	 */
+	if (wlan_cfg80211_nla_parse(tb,
+			   QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_MAX,
+			   data, data_len, NULL)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST]) {
+		hdd_err("Frequency list is missing");
+		return -EINVAL;
+	}
+
+	freq_len = nla_len(
+		tb[QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST])/
+		sizeof(uint32_t);
+
+	if (freq_len > QDF_MAX_NUM_CHAN) {
+		hdd_err("insufficient space to hold channels");
+		return -ENOMEM;
+	}
+
+	hdd_debug("freq_len=%d", freq_len);
+
+	freq = nla_data(
+		tb[QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST]);
+
+	for (i = 0; i < freq_len; i++) {
+		if (freq[i] == 0)
+			chans[i] = 0;
+		else
+			chans[i] = ieee80211_frequency_to_channel(freq[i]);
+
+		hdd_debug("freq[%d]=%d", i, freq[i]);
+	}
+
+	/*
+	 * The input frequency list from user space is designed to be a
+	 * priority based frequency list. This is only to accommodate any
+	 * future request. But, current requirement is only to perform CAC
+	 * on a single channel. So, the first entry from the list is picked.
+	 *
+	 * If channel is zero, any channel in the available outdoor regulatory
+	 * domain will be selected.
+	 */
+	ret = wlan_hdd_request_pre_cac(chans[0]);
+	if (ret) {
+		hdd_err("pre cac request failed with reason:%d", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int wlan_hdd_cfg80211_conditional_chan_switch(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      const void *data,
+					      int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_conditional_chan_switch(wiphy, wdev,
+							  data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
diff --git a/core/hdd/src/wlan_hdd_sap_cond_chan_switch.h b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.h
new file mode 100644
index 0000000..1ea89eb
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __WLAN_HDD_SAP_COND_CHAN_SWITCH_H
+#define __WLAN_HDD_SAP_COND_CHAN_SWITCH_H
+
+/**
+ * DOC: wlan_hdd_sap_cond_chan_switch_h
+ *
+ * WLAN Host Device Driver SAP conditional channel switch API specification
+ */
+
+#ifdef FEATURE_SAP_COND_CHAN_SWITCH
+/**
+ * wlan_hdd_cfg80211_conditional_chan_switch() - SAP conditional channel switch
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Invokes internal API __wlan_hdd_cfg80211_conditional_chan_switch()
+ * to process the conditional channel switch request.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_conditional_chan_switch(struct wiphy *wiphy,
+					      struct wireless_dev *wdev,
+					      const void *data,
+					      int data_len);
+
+#define FEATURE_SAP_COND_CHAN_SWITCH_VENDOR_COMMANDS			\
+{									\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,			\
+	.info.subcmd =							\
+		QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH,	\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |				\
+			WIPHY_VENDOR_CMD_NEED_NETDEV |			\
+			WIPHY_VENDOR_CMD_NEED_RUNNING,			\
+	.doit = wlan_hdd_cfg80211_conditional_chan_switch		\
+},
+#else /* FEATURE_SAP_COND_CHAN_SWITCH */
+#define FEATURE_SAP_COND_CHAN_SWITCH_VENDOR_COMMANDS
+#endif /* FEATURE_SAP_COND_CHAN_SWITCH */
+
+#endif /* __WLAN_HDD_SAP_COND_CHAN_SWITCH_H */
+
diff --git a/core/hdd/src/wlan_hdd_sar_limits.c b/core/hdd/src/wlan_hdd_sar_limits.c
new file mode 100644
index 0000000..c500ddc
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_sar_limits.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_vendor_sar_limits.c
+ *
+ * WLAN SAR limits functions
+ *
+ */
+
+#include <wlan_hdd_includes.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <wlan_osif_request_manager.h>
+#include <wlan_hdd_sar_limits.h>
+
+#define WLAN_WAIT_TIME_SAR 5000
+/**
+ * hdd_sar_context - hdd sar context
+ * @event: sar limit event
+ */
+struct hdd_sar_context {
+	struct sar_limit_event event;
+};
+
+static u32 hdd_sar_wmi_to_nl_enable(uint32_t wmi_value)
+{
+	switch (wmi_value) {
+	default:
+	case WMI_SAR_FEATURE_OFF:
+		return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE;
+	case WMI_SAR_FEATURE_ON_SET_0:
+		return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0;
+	case WMI_SAR_FEATURE_ON_SET_1:
+		return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1;
+	case WMI_SAR_FEATURE_ON_SET_2:
+		return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2;
+	case WMI_SAR_FEATURE_ON_SET_3:
+		return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3;
+	case WMI_SAR_FEATURE_ON_SET_4:
+		return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4;
+	case WMI_SAR_FEATURE_ON_USER_DEFINED:
+		return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER;
+	case WMI_SAR_FEATURE_ON_SAR_V2_0:
+		return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0;
+	}
+}
+
+static u32 hdd_sar_wmi_to_nl_band(uint32_t wmi_value)
+{
+	switch (wmi_value) {
+	default:
+	case WMI_SAR_2G_ID:
+		return HDD_NL80211_BAND_2GHZ;
+	case WMI_SAR_5G_ID:
+		return HDD_NL80211_BAND_5GHZ;
+	}
+}
+
+static u32 hdd_sar_wmi_to_nl_modulation(uint32_t wmi_value)
+{
+	switch (wmi_value) {
+	default:
+	case WMI_SAR_MOD_CCK:
+		return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_CCK;
+	case WMI_SAR_MOD_OFDM:
+		return QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_OFDM;
+	}
+}
+
+/**
+ * hdd_sar_cb () - sar response message handler
+ * @cookie: hdd request cookie
+ * @event: sar response event
+ *
+ * Return: none
+ */
+static void hdd_sar_cb(void *cookie,
+		       struct sar_limit_event *event)
+{
+	struct osif_request *request;
+	struct hdd_sar_context *context;
+
+	hdd_enter();
+
+	if (!event) {
+		hdd_err("response is NULL");
+		return;
+	}
+
+	request = osif_request_get(cookie);
+	if (!request) {
+		hdd_debug("Obsolete request");
+		return;
+	}
+
+	context = osif_request_priv(request);
+	context->event = *event;
+	osif_request_complete(request);
+	osif_request_put(request);
+
+	hdd_exit();
+}
+
+static uint32_t hdd_sar_get_response_len(const struct sar_limit_event *event)
+{
+	uint32_t len;
+	uint32_t row_len;
+
+	len = NLMSG_HDRLEN;
+	/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE */
+	len += NLA_HDRLEN + sizeof(u32);
+	/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS */
+	len += NLA_HDRLEN + sizeof(u32);
+
+	/* nest */
+	row_len = NLA_HDRLEN;
+	/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND */
+	row_len += NLA_HDRLEN + sizeof(u32);
+	/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN */
+	row_len += NLA_HDRLEN + sizeof(u32);
+	/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION */
+	row_len += NLA_HDRLEN + sizeof(u32);
+	/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT */
+	row_len += NLA_HDRLEN + sizeof(u32);
+
+	/* QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC */
+	len += NLA_HDRLEN + (row_len * event->num_limit_rows);
+
+	return len;
+}
+
+static int hdd_sar_fill_response(struct sk_buff *skb,
+				 const struct sar_limit_event *event)
+{
+	int errno;
+	u32 value;
+	u32 attr;
+	struct nlattr *nla_spec_attr;
+	struct nlattr *nla_row_attr;
+	uint32_t row;
+	const struct sar_limit_event_row *event_row;
+
+	attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE;
+	value = hdd_sar_wmi_to_nl_enable(event->sar_enable);
+	errno = nla_put_u32(skb, attr, value);
+	if (errno)
+		return errno;
+
+	attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS;
+	value = event->num_limit_rows;
+	errno = nla_put_u32(skb, attr, value);
+	if (errno)
+		return errno;
+
+	attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC;
+	nla_spec_attr = nla_nest_start(skb, attr);
+	if (!nla_spec_attr)
+		return -EINVAL;
+
+	for (row = 0, event_row = event->sar_limit_row;
+	     row < event->num_limit_rows;
+	     row++, event_row++) {
+		nla_row_attr = nla_nest_start(skb, attr);
+		if (!nla_row_attr)
+			return -EINVAL;
+
+		attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND;
+		value = hdd_sar_wmi_to_nl_band(event_row->band_id);
+		errno = nla_put_u32(skb, attr, value);
+		if (errno)
+			return errno;
+
+		attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN;
+		value = event_row->chain_id;
+		errno = nla_put_u32(skb, attr, value);
+		if (errno)
+			return errno;
+
+		attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION;
+		value = hdd_sar_wmi_to_nl_modulation(event_row->mod_id);
+		errno = nla_put_u32(skb, attr, value);
+		if (errno)
+			return errno;
+
+		attr = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT;
+		value = event_row->limit_value;
+		errno = nla_put_u32(skb, attr, value);
+		if (errno)
+			return errno;
+
+		nla_nest_end(skb, nla_row_attr);
+	}
+	nla_nest_end(skb, nla_spec_attr);
+
+	return 0;
+}
+
+static int hdd_sar_send_response(struct wiphy *wiphy,
+				 const struct sar_limit_event *event)
+{
+	uint32_t len;
+	struct sk_buff *skb;
+	int errno;
+
+	len = hdd_sar_get_response_len(event);
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	errno = hdd_sar_fill_response(skb, event);
+	if (errno) {
+		kfree_skb(skb);
+		return errno;
+	}
+
+	return cfg80211_vendor_cmd_reply(skb);
+}
+
+/**
+ * __wlan_hdd_get_sar_power_limits() - Get SAR power limits
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * This function is used to retrieve Specific Absorption Rate limit specs.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_get_sar_power_limits(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data, int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct osif_request *request;
+	struct hdd_sar_context *context;
+	mac_handle_t mac_handle;
+	void *cookie;
+	QDF_STATUS status;
+	int ret;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*context),
+		.timeout_ms = WLAN_WAIT_TIME_SAR,
+	};
+
+	hdd_enter();
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+
+	cookie = osif_request_cookie(request);
+
+	mac_handle = hdd_ctx->mac_handle;
+	status = sme_get_sar_power_limits(mac_handle, hdd_sar_cb, cookie);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Unable to post sar message");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_err("Target response timed out");
+		goto cleanup;
+	}
+
+	context = osif_request_priv(request);
+	ret = hdd_sar_send_response(wiphy, &context->event);
+
+cleanup:
+	osif_request_put(request);
+
+	return ret;
+}
+
+int wlan_hdd_cfg80211_get_sar_power_limits(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data,
+					   int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_get_sar_power_limits(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
diff --git a/core/hdd/src/wlan_hdd_sar_limits.h b/core/hdd/src/wlan_hdd_sar_limits.h
new file mode 100644
index 0000000..2a49a46
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_sar_limits.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __WLAN_HDD_SAR_LIMITS_H
+#define __WLAN_HDD_SAR_LIMITS_H
+
+/**
+ * DOC: wlan_hdd_sar_limits_h
+ *
+ * WLAN Host Device Driver SAR limits API specification
+ */
+
+#ifdef FEATURE_SAR_LIMITS
+/**
+ * wlan_hdd_cfg80211_get_sar_power_limits() - Get SAR power limits
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Wrapper function of __wlan_hdd_cfg80211_get_sar_power_limits()
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_get_sar_power_limits(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data,
+					   int data_len);
+
+#define FEATURE_SAR_LIMITS_VENDOR_COMMANDS				\
+{									\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,			\
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS,	\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |				\
+		 WIPHY_VENDOR_CMD_NEED_RUNNING,				\
+	.doit = wlan_hdd_cfg80211_get_sar_power_limits			\
+},
+#else /* FEATURE_SAR_LIMITS */
+#define FEATURE_SAR_LIMITS_VENDOR_COMMANDS
+#endif /* FEATURE_SAR_LIMITS */
+
+#endif /* __WLAN_HDD_SAR_LIMITS_H */
+
diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c
new file mode 100644
index 0000000..8e0c74c
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_scan.c
@@ -0,0 +1,1544 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_scan.c
+ *
+ * WLAN Host Device Driver scan implementation
+ */
+
+#include <linux/wireless.h>
+#include <net/cfg80211.h>
+
+#include "wlan_hdd_includes.h"
+#include "cds_api.h"
+#include "cds_api.h"
+#include "ani_global.h"
+#include "dot11f.h"
+#include "cds_sched.h"
+#include "wlan_hdd_p2p.h"
+#include "wlan_hdd_trace.h"
+#include "wlan_hdd_scan.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_hdd_power.h"
+#include "wma_api.h"
+#include "cds_utils.h"
+#include "wlan_p2p_ucfg_api.h"
+
+#ifdef WLAN_UMAC_CONVERGENCE
+#include "wlan_cfg80211.h"
+#endif
+#include <qca_vendor.h>
+#include <wlan_cfg80211_scan.h>
+#include "wlan_utility.h"
+
+#define MAX_RATES                       12
+#define HDD_WAKE_LOCK_SCAN_DURATION (5 * 1000) /* in msec */
+
+#define SCAN_DONE_EVENT_BUF_SIZE 4096
+#define RATE_MASK 0x7f
+
+/**
+ * enum essid_bcast_type - SSID broadcast type
+ * @eBCAST_UNKNOWN: Broadcast unknown
+ * @eBCAST_NORMAL: Broadcast normal
+ * @eBCAST_HIDDEN: Broadcast hidden
+ */
+enum essid_bcast_type {
+	eBCAST_UNKNOWN = 0,
+	eBCAST_NORMAL = 1,
+	eBCAST_HIDDEN = 2,
+};
+
+/**
+ * hdd_vendor_scan_callback() - Scan completed callback event
+ * @hddctx: HDD context
+ * @req : Scan request
+ * @aborted : true scan aborted false scan success
+ *
+ * This function sends scan completed callback event to NL.
+ *
+ * Return: none
+ */
+static void hdd_vendor_scan_callback(struct hdd_adapter *adapter,
+					struct cfg80211_scan_request *req,
+					bool aborted)
+{
+	struct hdd_context *hddctx = WLAN_HDD_GET_CTX(adapter);
+	struct sk_buff *skb;
+	struct nlattr *attr;
+	int i;
+	uint8_t scan_status;
+	uint64_t cookie;
+
+	hdd_enter();
+
+	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
+		hdd_err("Invalid adapter magic");
+		qdf_mem_free(req);
+		return;
+	}
+	skb = cfg80211_vendor_event_alloc(hddctx->wiphy, &(adapter->wdev),
+			SCAN_DONE_EVENT_BUF_SIZE + 4 + NLMSG_HDRLEN,
+			QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX,
+			GFP_KERNEL);
+
+	if (!skb) {
+		hdd_err("skb alloc failed");
+		qdf_mem_free(req);
+		return;
+	}
+
+	cookie = (uintptr_t)req;
+	attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS);
+	if (!attr)
+		goto nla_put_failure;
+	for (i = 0; i < req->n_ssids; i++) {
+		if (nla_put(skb, i, req->ssids[i].ssid_len,
+			req->ssids[i].ssid)) {
+			hdd_err("Failed to add ssid");
+			goto nla_put_failure;
+		}
+	}
+	nla_nest_end(skb, attr);
+	attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES);
+	if (!attr)
+		goto nla_put_failure;
+	for (i = 0; i < req->n_channels; i++) {
+		if (nla_put_u32(skb, i, req->channels[i]->center_freq)) {
+			hdd_err("Failed to add channel");
+			goto nla_put_failure;
+		}
+	}
+	nla_nest_end(skb, attr);
+
+	if (req->ie &&
+		nla_put(skb, QCA_WLAN_VENDOR_ATTR_SCAN_IE, req->ie_len,
+			req->ie)) {
+		hdd_err("Failed to add scan ie");
+		goto nla_put_failure;
+	}
+	if (req->flags &&
+		nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS, req->flags)) {
+		hdd_err("Failed to add scan flags");
+		goto nla_put_failure;
+	}
+	if (hdd_wlan_nla_put_u64(skb,
+				  QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
+				  cookie)) {
+		hdd_err("Failed to add scan cookie");
+		goto nla_put_failure;
+	}
+	scan_status = (aborted == true) ? VENDOR_SCAN_STATUS_ABORTED :
+		VENDOR_SCAN_STATUS_NEW_RESULTS;
+	if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_SCAN_STATUS, scan_status)) {
+		hdd_err("Failed to add scan staus");
+		goto nla_put_failure;
+	}
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+	hdd_info("scan complete event sent to NL");
+	qdf_mem_free(req);
+	return;
+
+nla_put_failure:
+	kfree_skb(skb);
+	qdf_mem_free(req);
+}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+/**
+ * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
+ * @adapter: Pointer to the adapter
+ * @req : Scan request
+ * @aborted : true scan aborted false scan success
+ *
+ * This function notifies scan done to cfg80211
+ *
+ * Return: none
+ */
+static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
+				   struct cfg80211_scan_request *req,
+				   bool aborted)
+{
+	struct cfg80211_scan_info info = {
+		.aborted = aborted
+	};
+
+	if (adapter->dev->flags & IFF_UP)
+		cfg80211_scan_done(req, &info);
+}
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+/**
+ * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
+ * @adapter: Pointer to the adapter
+ * @req : Scan request
+ * @aborted : true scan aborted false scan success
+ *
+ * This function notifies scan done to cfg80211
+ *
+ * Return: none
+ */
+static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
+				   struct cfg80211_scan_request *req,
+				   bool aborted)
+{
+	if (adapter->dev->flags & IFF_UP)
+		cfg80211_scan_done(req, aborted);
+}
+#else
+/**
+ * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
+ * @adapter: Pointer to the adapter
+ * @req : Scan request
+ * @aborted : true scan aborted false scan success
+ *
+ * This function notifies scan done to cfg80211
+ *
+ * Return: none
+ */
+static void hdd_cfg80211_scan_done(struct hdd_adapter *adapter,
+				   struct cfg80211_scan_request *req,
+				   bool aborted)
+{
+	cfg80211_scan_done(req, aborted);
+}
+#endif
+
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+/**
+ * wlan_hdd_sap_skip_scan_check() - The function will check OBSS
+ *         scan skip or not for SAP.
+ * @hdd_ctx: pointer to hdd context.
+ * @request: pointer to scan request.
+ *
+ * This function will check the scan request's chan list against the
+ * previous ACS scan chan list. If all the chan are covered by
+ * previous ACS scan, we can skip the scan and return scan complete
+ * to save the SAP starting time.
+ *
+ * Return: true to skip the scan,
+ *            false to continue the scan
+ */
+static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx,
+	struct cfg80211_scan_request *request)
+{
+	int i, j;
+	bool skip;
+
+	hdd_debug("HDD_ACS_SKIP_STATUS = %d",
+		hdd_ctx->skip_acs_scan_status);
+	if (hdd_ctx->skip_acs_scan_status != eSAP_SKIP_ACS_SCAN)
+		return false;
+	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
+	if (hdd_ctx->last_acs_channel_list == NULL ||
+	   hdd_ctx->num_of_channels == 0 ||
+	   request->n_channels == 0) {
+		qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
+		return false;
+	}
+	skip = true;
+	for (i = 0; i < request->n_channels ; i++) {
+		bool find = false;
+
+		for (j = 0; j < hdd_ctx->num_of_channels; j++) {
+			if (hdd_ctx->last_acs_channel_list[j] ==
+			   request->channels[i]->hw_value) {
+				find = true;
+				break;
+			}
+		}
+		if (!find) {
+			skip = false;
+			hdd_debug("Chan %d isn't in ACS chan list",
+				request->channels[i]->hw_value);
+			break;
+		}
+	}
+	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
+	return skip;
+}
+#else
+static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx,
+	struct cfg80211_scan_request *request)
+{
+	return false;
+}
+#endif
+
+static void __wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
+{
+	struct hdd_adapter *adapter;
+	struct cfg80211_scan_request *request;
+	struct scan_req *blocked_scan_req;
+	qdf_list_node_t *node = NULL;
+
+	adapter = container_of(work, struct hdd_adapter, scan_block_work);
+	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
+		hdd_err("HDD adapter context is invalid");
+		return;
+	}
+
+	qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock);
+
+	while (!qdf_list_empty(&adapter->blocked_scan_request_q)) {
+		qdf_list_remove_front(&adapter->blocked_scan_request_q,
+				      &node);
+		blocked_scan_req = qdf_container_of(node, struct scan_req,
+						    node);
+		request = blocked_scan_req->scan_request;
+		request->n_ssids = 0;
+		request->n_channels = 0;
+		if (blocked_scan_req->source == NL_SCAN) {
+			hdd_err("Scan aborted. Null result sent");
+			hdd_cfg80211_scan_done(adapter, request, true);
+		} else {
+			hdd_err("Vendor scan aborted. Null result sent");
+			hdd_vendor_scan_callback(adapter, request, true);
+		}
+		qdf_mem_free(blocked_scan_req);
+	}
+
+	qdf_mutex_release(&adapter->blocked_scan_request_q_lock);
+}
+
+void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
+{
+	cds_ssr_protect(__func__);
+	__wlan_hdd_cfg80211_scan_block_cb(work);
+	cds_ssr_unprotect(__func__);
+}
+
+void hdd_init_scan_reject_params(struct hdd_context *hdd_ctx)
+{
+	if (hdd_ctx) {
+		hdd_ctx->last_scan_reject_timestamp = 0;
+		hdd_ctx->last_scan_reject_session_id = 0xFF;
+		hdd_ctx->last_scan_reject_reason = 0;
+		hdd_ctx->scan_reject_cnt = 0;
+	}
+}
+
+void hdd_reset_scan_reject_params(struct hdd_context *hdd_ctx,
+				  eRoamCmdStatus roam_status,
+				  eCsrRoamResult roam_result)
+{
+	if ((roam_status == eCSR_ROAM_ASSOCIATION_FAILURE) ||
+	    (roam_status == eCSR_ROAM_CANCELLED) ||
+	    (roam_result == eCSR_ROAM_RESULT_ASSOCIATED)) {
+		hdd_debug("Reset scan reject params");
+		hdd_init_scan_reject_params(hdd_ctx);
+	}
+}
+
+/*
+ * wlan_hdd_update_scan_ies() - API to update the scan IEs of scan request
+ * with already stored default scan IEs
+ *
+ * @adapter: Pointer to HDD adapter
+ * @scan_info: Pointer to scan info in HDD adapter
+ * @scan_ie: Pointer to scan IE in scan request
+ * @scan_ie_len: Pointer to scan IE length in scan request
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int wlan_hdd_update_scan_ies(struct hdd_adapter *adapter,
+			struct hdd_scan_info *scan_info, uint8_t *scan_ie,
+			uint16_t *scan_ie_len)
+{
+	uint16_t rem_len = scan_info->default_scan_ies_len;
+	uint8_t *temp_ie = scan_info->default_scan_ies;
+	uint8_t *current_ie;
+	uint8_t elem_id;
+	uint16_t elem_len;
+	bool add_ie = false;
+
+	if (!scan_info->default_scan_ies_len || !scan_info->default_scan_ies)
+		return 0;
+
+	while (rem_len >= 2) {
+		current_ie = temp_ie;
+		elem_id = *temp_ie++;
+		elem_len = *temp_ie++;
+		rem_len -= 2;
+
+		switch (elem_id) {
+		case DOT11F_EID_EXTCAP:
+			if (!wlan_get_ie_ptr_from_eid(DOT11F_EID_EXTCAP,
+						      scan_ie, *scan_ie_len))
+				add_ie = true;
+			break;
+		case IE_EID_VENDOR:
+			if ((0 != qdf_mem_cmp(&temp_ie[0], MBO_OUI_TYPE,
+							MBO_OUI_TYPE_SIZE)) ||
+				(0 == qdf_mem_cmp(&temp_ie[0], QCN_OUI_TYPE,
+							QCN_OUI_TYPE_SIZE)))
+				add_ie = true;
+			break;
+		}
+
+		if (add_ie && (((*scan_ie_len) + elem_len) >
+					SIR_MAC_MAX_ADD_IE_LENGTH)){
+			hdd_err("Not enough buffer to save default scan IE's");
+			return 0;
+		}
+
+		if (add_ie) {
+			qdf_mem_copy(scan_ie + (*scan_ie_len),
+						current_ie, elem_len + 2);
+			(*scan_ie_len) += (elem_len + 2);
+			add_ie = false;
+		}
+
+		temp_ie += elem_len;
+		rem_len -= elem_len;
+	}
+	return 0;
+}
+
+static int
+wlan_hdd_enqueue_blocked_scan_request(struct net_device *dev,
+				      struct cfg80211_scan_request *request,
+				      uint8_t source)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct scan_req *blocked_scan_req =
+		qdf_mem_malloc(sizeof(*blocked_scan_req));
+	int ret = 0;
+
+	if (!blocked_scan_req)
+		return -EINVAL;
+
+	blocked_scan_req->dev = dev;
+	blocked_scan_req->scan_request = request;
+	blocked_scan_req->source = source;
+	blocked_scan_req->scan_id = 0;
+
+	qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock);
+	if (qdf_list_size(&adapter->blocked_scan_request_q) <
+		WLAN_MAX_SCAN_COUNT)
+		qdf_list_insert_back(&adapter->blocked_scan_request_q,
+				     &blocked_scan_req->node);
+	else
+		ret = -EINVAL;
+	qdf_mutex_release(&adapter->blocked_scan_request_q_lock);
+
+	if (ret) {
+		hdd_err("Maximum number of block scan request reached!");
+		qdf_mem_free(blocked_scan_req);
+	}
+
+	return ret;
+}
+
+/* Define short name to use in cds_trigger_recovery */
+#define SCAN_FAILURE QDF_SCAN_ATTEMPT_FAILURES
+
+/**
+ * __wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to net device
+ * @request: Pointer to scan request
+ * @source: scan request source(NL/Vendor scan)
+ *
+ * This API responds to scan trigger and update cfg80211 scan database
+ * later, scan dump command can be used to receive scan results
+ *
+ * Return: 0 for success, non zero for failure
+ */
+static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
+				    struct cfg80211_scan_request *request,
+				    uint8_t source)
+{
+	struct net_device *dev = request->wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_config *cfg_param = NULL;
+	int status;
+	struct hdd_scan_info *scan_info = NULL;
+	struct hdd_adapter *con_sap_adapter;
+	uint16_t con_dfs_ch;
+	uint8_t curr_session_id;
+	enum scan_reject_states curr_reason;
+	static uint32_t scan_ebusy_cnt;
+	struct scan_params params = {0};
+	bool self_recovery;
+	QDF_STATUS qdf_status;
+
+	hdd_enter();
+
+	if (cds_is_fw_down()) {
+		hdd_err("firmware is down, scan cmd cannot be processed");
+		return -EINVAL;
+	}
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return status;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_SCAN,
+			 adapter->session_id, request->n_channels));
+
+	if (!sme_is_session_id_valid(hdd_ctx->mac_handle, adapter->session_id))
+		return -EINVAL;
+
+	qdf_status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		hdd_err("Failed to get self recovery ini config");
+		return -EIO;
+	}
+
+	if ((eConnectionState_Associated ==
+			WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
+						conn_info.connState) &&
+	    (!hdd_ctx->config->enable_connected_scan)) {
+		hdd_info("enable_connected_scan is false, Aborting scan");
+		if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source))
+			return -EAGAIN;
+		schedule_work(&adapter->scan_block_work);
+		return 0;
+	}
+
+	hdd_debug("Device_mode %s(%d)",
+		  qdf_opmode_str(adapter->device_mode),
+		  adapter->device_mode);
+
+	/*
+	 * IBSS vdev does not need to scan to establish
+	 * IBSS connection. If IBSS vdev need to support scan,
+	 * Firmware need to make the change to add self peer
+	 * per mac for IBSS vdev.
+	 * NDI does not need scan from userspace to establish connection
+	 * and it does not support scan request either.
+	 */
+	if (QDF_IBSS_MODE == adapter->device_mode ||
+	    QDF_NDI_MODE == adapter->device_mode) {
+		hdd_err("Scan not supported for %s",
+			qdf_opmode_str(adapter->device_mode));
+		return -EINVAL;
+	}
+
+	cfg_param = hdd_ctx->config;
+	scan_info = &adapter->scan_info;
+
+	/* Block All Scan during DFS operation and send null scan result */
+	con_sap_adapter = hdd_get_con_sap_adapter(adapter, true);
+	if (con_sap_adapter) {
+		con_dfs_ch = con_sap_adapter->session.ap.sap_config.channel;
+		if (con_dfs_ch == AUTO_CHANNEL_SELECT)
+			con_dfs_ch =
+				con_sap_adapter->session.ap.operating_channel;
+
+		if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) &&
+			wlan_reg_is_dfs_ch(hdd_ctx->pdev, con_dfs_ch) &&
+			!policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
+			hdd_ctx->psoc)) {
+			/* Provide empty scan result during DFS operation since
+			 * scanning not supported during DFS. Reason is
+			 * following case:
+			 * DFS is supported only in SCC for MBSSID Mode.
+			 * We shall not return EBUSY or ENOTSUPP as when Primary
+			 * AP is operating in DFS channel and secondary AP is
+			 * started. Though we force SCC in driver, the hostapd
+			 * issues obss scan before starting secAP. This results
+			 * in MCC in DFS mode. Thus we return null scan result.
+			 * If we return scan failure hostapd fails secondary AP
+			 * startup.
+			 */
+			hdd_err("##In DFS Master mode. Scan aborted");
+			if (wlan_hdd_enqueue_blocked_scan_request(dev, request,
+								  source))
+				return -EAGAIN;
+			schedule_work(&adapter->scan_block_work);
+			return 0;
+		}
+	}
+
+	/* Check if scan is allowed at this point of time */
+	if (hdd_is_connection_in_progress(&curr_session_id, &curr_reason)) {
+		scan_ebusy_cnt++;
+		hdd_err_rl("Scan not allowed. scan_ebusy_cnt: %d Session %d Reason %d",
+			   scan_ebusy_cnt, curr_session_id, curr_reason);
+		if (hdd_ctx->last_scan_reject_session_id != curr_session_id ||
+		    hdd_ctx->last_scan_reject_reason != curr_reason ||
+		    !hdd_ctx->last_scan_reject_timestamp) {
+			hdd_ctx->last_scan_reject_session_id = curr_session_id;
+			hdd_ctx->last_scan_reject_reason = curr_reason;
+			hdd_ctx->last_scan_reject_timestamp = jiffies +
+				msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
+			hdd_ctx->scan_reject_cnt = 0;
+		} else {
+			hdd_ctx->scan_reject_cnt++;
+			if ((hdd_ctx->scan_reject_cnt >=
+			   SCAN_REJECT_THRESHOLD) &&
+			   qdf_system_time_after(jiffies,
+			   hdd_ctx->last_scan_reject_timestamp)) {
+				hdd_err("scan reject threshold reached Session %d Reason %d count %d reject timestamp %lu jiffies %lu",
+					curr_session_id, curr_reason,
+					hdd_ctx->scan_reject_cnt,
+					hdd_ctx->last_scan_reject_timestamp,
+					jiffies);
+				hdd_ctx->last_scan_reject_timestamp = 0;
+				hdd_ctx->scan_reject_cnt = 0;
+				if (cds_is_fatal_event_enabled()) {
+					cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+					   WLAN_LOG_INDICATOR_HOST_DRIVER,
+					   WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
+					   false,
+					   self_recovery);
+				} else {
+					hdd_err("Triggering SSR due to scan stuck");
+					cds_trigger_recovery(SCAN_FAILURE);
+				}
+			}
+		}
+		return -EBUSY;
+	}
+
+	hdd_init_scan_reject_params(hdd_ctx);
+
+	/* Check whether SAP scan can be skipped or not */
+	if (adapter->device_mode == QDF_SAP_MODE &&
+	   wlan_hdd_sap_skip_scan_check(hdd_ctx, request)) {
+		hdd_debug("sap scan skipped");
+		if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source))
+			return -EAGAIN;
+		schedule_work(&adapter->scan_block_work);
+		return 0;
+	}
+
+	params.source = source;
+	params.default_ie.len = 0;
+	/* Store the Scan IE's in Adapter*/
+	if (request->ie_len) {
+		if (request->ie_len > SIR_MAC_MAX_ADD_IE_LENGTH) {
+			hdd_debug("Invalid ie_len: %zu", request->ie_len);
+			return -EINVAL;
+		}
+
+		/* save this for future association (join requires this) */
+		memset(&scan_info->scan_add_ie, 0, sizeof(scan_info->scan_add_ie));
+		memcpy(scan_info->scan_add_ie.addIEdata, request->ie,
+		       request->ie_len);
+		scan_info->scan_add_ie.length = request->ie_len;
+
+		wlan_hdd_update_scan_ies(adapter, scan_info,
+				scan_info->scan_add_ie.addIEdata,
+				&scan_info->scan_add_ie.length);
+	} else {
+		if (scan_info->default_scan_ies &&
+		    scan_info->default_scan_ies_len) {
+			qdf_mem_copy(scan_info->scan_add_ie.addIEdata,
+				     scan_info->default_scan_ies,
+				     scan_info->default_scan_ies_len);
+			scan_info->scan_add_ie.length =
+				scan_info->default_scan_ies_len;
+			params.default_ie.ptr =
+				qdf_mem_malloc(scan_info->default_scan_ies_len);
+			if (params.default_ie.ptr != NULL) {
+				qdf_mem_copy(params.default_ie.ptr,
+					     scan_info->default_scan_ies,
+					     scan_info->default_scan_ies_len);
+				params.default_ie.len =
+						scan_info->default_scan_ies_len;
+			}
+		}
+	}
+
+	if ((QDF_STA_MODE == adapter->device_mode) ||
+	    (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
+	    (QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
+		struct csr_roam_profile *roam_profile =
+			hdd_roam_profile(adapter);
+
+		roam_profile->pAddIEScan =
+			scan_info->scan_add_ie.addIEdata;
+		roam_profile->nAddIEScanLength =
+			scan_info->scan_add_ie.length;
+	}
+
+	if ((request->n_ssids == 1) && (request->ssids != NULL) &&
+	    (request->ssids[0].ssid_len > 7) &&
+	     !qdf_mem_cmp(&request->ssids[0], "DIRECT-", 7))
+		ucfg_p2p_status_scan(adapter->vdev);
+
+	status = wlan_cfg80211_scan(hdd_ctx->pdev, request, &params);
+	if (params.default_ie.ptr)
+		qdf_mem_free(params.default_ie.ptr);
+	hdd_exit();
+	return status;
+}
+
+#undef SCAN_FAILURE
+
+/**
+ * wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to net device
+ * @request: Pointer to scan request
+ *
+ * This API responds to scan trigger and update cfg80211 scan database
+ * later, scan dump command can be used to receive scan results
+ *
+ * Return: 0 for success, non zero for failure
+ */
+int wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
+			   struct cfg80211_scan_request *request)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_scan(wiphy,
+				request, NL_SCAN);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_tdls_scan() - API to process cfg80211 scan request
+ * @wiphy: Pointer to wiphy
+ * @request: Pointer to scan request
+ * @source: scan request source(NL/Vendor scan)
+ *
+ * This API responds to scan trigger and update cfg80211 scan database
+ * later, scan dump command can be used to receive scan results. This
+ * function gets called when tdls module queues the scan request.
+ *
+ * Return: 0 for success, non zero for failure.
+ */
+int wlan_hdd_cfg80211_tdls_scan(struct wiphy *wiphy,
+				struct cfg80211_scan_request *request,
+				uint8_t source)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_scan(wiphy,
+				request, source);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
+
+/**
+ * wlan_hdd_get_rates() -API to get the rates from scan request
+ * @wiphy: Pointer to wiphy
+ * @band: Band
+ * @rates: array of rates
+ * @rate_count: number of rates
+ *
+ * Return: o for failure, rate bitmap for success
+ */
+static uint32_t wlan_hdd_get_rates(struct wiphy *wiphy,
+	enum nl80211_band band,
+	const u8 *rates, unsigned int rate_count)
+{
+	uint32_t j, count, rate_bitmap = 0;
+	uint32_t rate;
+	bool found;
+
+	for (count = 0; count < rate_count; count++) {
+		rate = ((rates[count]) & RATE_MASK) * 5;
+		found = false;
+		for (j = 0; j < wiphy->bands[band]->n_bitrates; j++) {
+			if (wiphy->bands[band]->bitrates[j].bitrate == rate) {
+				found = true;
+				rate_bitmap |= (1 << j);
+				break;
+			}
+		}
+		if (!found)
+			return 0;
+	}
+	return rate_bitmap;
+}
+
+/**
+ * wlan_hdd_send_scan_start_event() -API to send the scan start event
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to net device
+ * @cookie: scan identifier
+ *
+ * Return: return 0 on success and negative error code on failure
+ */
+static int wlan_hdd_send_scan_start_event(struct wiphy *wiphy,
+		struct wireless_dev *wdev, uint64_t cookie)
+{
+	struct sk_buff *skb;
+	int ret;
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u64) +
+			NLA_HDRLEN + NLMSG_HDRLEN);
+	if (!skb) {
+		hdd_err(" reply skb alloc failed");
+		return -ENOMEM;
+	}
+
+	if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
+				 cookie)) {
+		hdd_err("nla put fail");
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+
+	ret = cfg80211_vendor_cmd_reply(skb);
+
+	/* Send a scan started event to supplicant */
+	skb = cfg80211_vendor_event_alloc(wiphy, wdev,
+		sizeof(u64) + 4 + NLMSG_HDRLEN,
+		QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX, GFP_KERNEL);
+	if (!skb) {
+		hdd_err("skb alloc failed");
+		return -ENOMEM;
+	}
+
+	if (hdd_wlan_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
+				 cookie)) {
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_copy_bssid() - API to copy the bssid to vendor Scan request
+ * @request: Pointer to vendor scan request
+ * @bssid: Pointer to BSSID
+ *
+ * This API copies the specific BSSID received from Supplicant and copies it to
+ * the vendor Scan request
+ *
+ * Return: None
+ */
+#if defined(CFG80211_SCAN_BSSID) || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request,
+					uint8_t *bssid)
+{
+	qdf_mem_copy(request->bssid, bssid, QDF_MAC_ADDR_SIZE);
+}
+#else
+static inline void wlan_hdd_copy_bssid(struct cfg80211_scan_request *request,
+					uint8_t *bssid)
+{
+}
+#endif
+
+static void hdd_process_vendor_acs_response(struct hdd_adapter *adapter)
+{
+	if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags)) {
+		if (QDF_TIMER_STATE_RUNNING ==
+		    qdf_mc_timer_get_current_state(&adapter->session.
+					ap.vendor_acs_timer)) {
+			qdf_mc_timer_stop(&adapter->session.
+					ap.vendor_acs_timer);
+		}
+	}
+}
+
+#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+/**
+ * wlan_hdd_vendor_scan_random_attr() - check and fill scan randomization attrs
+ * @wiphy: Pointer to wiphy
+ * @request: Pointer to scan request
+ * @wdev: Pointer to wireless device
+ * @tb: Pointer to nl attributes
+ *
+ * This function is invoked to check whether vendor scan needs
+ * probe req source addr, if so populates mac_addr and mac_addr_mask
+ * in scan request with nl attrs.
+ *
+ * Return: 0 - on success, negative value on failure
+ */
+static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy,
+					struct cfg80211_scan_request *request,
+					struct wireless_dev *wdev,
+					struct nlattr **tb)
+{
+	uint32_t i;
+	int32_t len = QDF_MAC_ADDR_SIZE;
+
+	if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
+		return 0;
+
+	if (!(wiphy->features & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR) ||
+	    (wdev->current_bss)) {
+		hdd_err("SCAN RANDOMIZATION not supported");
+		return -EOPNOTSUPP;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] &&
+	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) {
+		qdf_mem_zero(request->mac_addr, len);
+		qdf_mem_zero(request->mac_addr_mask, len);
+		request->mac_addr[0] = 0x2;
+		request->mac_addr_mask[0] = 0x3;
+
+		return 0;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] ||
+	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK])
+		return -EINVAL;
+
+	if ((nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]) != len) ||
+	    (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) != len))
+		return -EINVAL;
+
+	qdf_mem_copy(request->mac_addr,
+		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]), len);
+
+	qdf_mem_copy(request->mac_addr_mask,
+		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]), len);
+
+	/* avoid configure on multicast address */
+	if (!cds_is_group_addr(request->mac_addr_mask) ||
+	    cds_is_group_addr(request->mac_addr))
+		return -EINVAL;
+
+	for (i = 0; i < ETH_ALEN; i++)
+		request->mac_addr[i] &= request->mac_addr_mask[i];
+
+	return 0;
+}
+#else
+static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy,
+					struct cfg80211_scan_request *request,
+					struct wireless_dev *wdev,
+					struct nlattr **tb)
+{
+	return 0;
+}
+#endif
+
+static const
+struct nla_policy scan_policy[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE] = {.type = NLA_FLAG},
+	[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE] = {.type = NLA_U64},
+	[QCA_WLAN_VENDOR_ATTR_SCAN_IE] = {.type = NLA_BINARY,
+					  .len = MAX_DEFAULT_SCAN_IE_LEN},
+	[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] = {.type = NLA_UNSPEC,
+					   .len = QDF_MAC_ADDR_SIZE},
+	[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK] = {.type = NLA_UNSPEC,
+						.len = QDF_MAC_ADDR_SIZE},
+};
+
+/**
+ * __wlan_hdd_cfg80211_vendor_scan() - API to process venor scan request
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to net device
+ * @data : Pointer to the data
+ * @data_len : length of the data
+ *
+ * API to process venor scan request.
+ *
+ * Return: return 0 on success and negative error code on failure
+ */
+static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data,
+		int data_len)
+{
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
+	struct cfg80211_scan_request *request = NULL;
+	struct nlattr *attr;
+	enum nl80211_band band;
+	uint32_t n_channels = 0, n_ssid = 0;
+	uint32_t tmp, count, j;
+	size_t len, ie_len = 0;
+	struct ieee80211_channel *chan;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
+	int ret;
+
+	hdd_enter_dev(wdev->netdev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
+				    data, data_len, scan_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
+		nla_for_each_nested(attr,
+			tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES], tmp)
+			n_channels++;
+	} else {
+		for (band = 0; band < HDD_NUM_NL80211_BANDS; band++)
+			if (wiphy->bands[band])
+				n_channels += wiphy->bands[band]->n_channels;
+	}
+
+	if (MAX_CHANNEL < n_channels) {
+		hdd_err("Exceed max number of channels: %d", n_channels);
+		return -EINVAL;
+	}
+	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS])
+		nla_for_each_nested(attr,
+			tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], tmp)
+			n_ssid++;
+
+	if (MAX_SCAN_SSID < n_ssid) {
+		hdd_err("Exceed max number of SSID: %d", n_ssid);
+		return -EINVAL;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE])
+		ie_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]);
+
+	len = sizeof(*request) + (sizeof(*request->ssids) * n_ssid) +
+			(sizeof(*request->channels) * n_channels) + ie_len;
+
+	request = qdf_mem_malloc(len);
+	if (!request)
+		goto error;
+	if (n_ssid)
+		request->ssids = (void *)&request->channels[n_channels];
+	request->n_ssids = n_ssid;
+	if (ie_len) {
+		if (request->ssids)
+			request->ie = (void *)(request->ssids + n_ssid);
+		else
+			request->ie = (void *)(request->channels + n_channels);
+	}
+
+	request->ie_len = ie_len;
+	count = 0;
+	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
+		nla_for_each_nested(attr,
+				    tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES],
+				    tmp) {
+			if (nla_len(attr) != sizeof(uint32_t)) {
+				hdd_err("len is not correct for frequency %d",
+					count);
+				goto error;
+			}
+			chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
+			if (!chan)
+				goto error;
+			if (chan->flags & IEEE80211_CHAN_DISABLED)
+				continue;
+			request->channels[count] = chan;
+			count++;
+		}
+	} else {
+		for (band = 0; band < HDD_NUM_NL80211_BANDS; band++) {
+			if (!wiphy->bands[band])
+				continue;
+			for (j = 0; j < wiphy->bands[band]->n_channels;
+				j++) {
+				chan = &wiphy->bands[band]->channels[j];
+				if (chan->flags & IEEE80211_CHAN_DISABLED)
+					continue;
+				request->channels[count] = chan;
+				count++;
+			}
+		}
+	}
+
+	if (!count)
+		goto error;
+
+	request->n_channels = count;
+	count = 0;
+	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) {
+		int ssid_length;
+
+		nla_for_each_nested(attr, tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS],
+				tmp) {
+			ssid_length = nla_len(attr);
+			if ((ssid_length > SIR_MAC_MAX_SSID_LENGTH) ||
+			    (ssid_length < 0)) {
+				hdd_err("SSID Len %d is not correct for network %d",
+					 ssid_length, count);
+				goto error;
+			}
+
+			request->ssids[count].ssid_len = ssid_length;
+			memcpy(request->ssids[count].ssid, nla_data(attr),
+					ssid_length);
+			count++;
+		}
+	}
+
+	if (ie_len)
+		nla_memcpy((void *)request->ie,
+			   tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE], ie_len);
+
+	for (count = 0; count < HDD_NUM_NL80211_BANDS; count++)
+		if (wiphy->bands[count])
+			request->rates[count] =
+				(1 << wiphy->bands[count]->n_bitrates) - 1;
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES]) {
+		nla_for_each_nested(attr,
+				    tb[QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES],
+				    tmp) {
+			band = nla_type(attr);
+			if (band >= HDD_NUM_NL80211_BANDS)
+				continue;
+			if (!wiphy->bands[band])
+				continue;
+			request->rates[band] =
+				wlan_hdd_get_rates(wiphy,
+						   band, nla_data(attr),
+						   nla_len(attr));
+		}
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]) {
+		request->flags =
+			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS]);
+		if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
+		    !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
+			hdd_err("LOW PRIORITY SCAN not supported");
+			goto error;
+		}
+
+		if (wlan_hdd_vendor_scan_random_attr(wiphy, request, wdev, tb))
+			goto error;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) {
+		if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) <
+		    QDF_MAC_ADDR_SIZE) {
+			hdd_err("invalid bssid length");
+			goto error;
+		}
+		wlan_hdd_copy_bssid(request,
+			nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]));
+	}
+
+	/* Check if external acs was requested on this adapter */
+	hdd_process_vendor_acs_response(adapter);
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE])
+		request->no_cck =
+		   nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE]);
+	request->wdev = wdev;
+	request->wiphy = wiphy;
+	request->scan_start = jiffies;
+
+	ret = __wlan_hdd_cfg80211_scan(wiphy, request, VENDOR_SCAN);
+	if (0 != ret) {
+		hdd_err("Scan Failed. Ret = %d", ret);
+		qdf_mem_free(request);
+		return ret;
+	}
+	ret = wlan_hdd_send_scan_start_event(wiphy, wdev, (uintptr_t)request);
+
+	return ret;
+error:
+	hdd_err("Scan Request Failed");
+	qdf_mem_free(request);
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_vendor_scan() -API to process venor scan request
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to net device
+ * @data : Pointer to the data
+ * @data_len : length of the data
+ *
+ * This is called from userspace to request scan.
+ *
+ * Return: Return the Success or Failure code.
+ */
+int wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data,
+		int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_vendor_scan(wiphy, wdev,
+					      data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_vendor_abort_scan() - API to process vendor command for
+ * abort scan
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to net device
+ * @data : Pointer to the data
+ * @data_len : length of the data
+ *
+ * API to process vendor abort scan
+ *
+ * Return: zero for success and non zero for failure
+ */
+static int __wlan_hdd_vendor_abort_scan(
+		struct wiphy *wiphy, const void *data,
+		int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	wlan_vendor_abort_scan(hdd_ctx->pdev, data, data_len);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_vendor_abort_scan() - API to process vendor command for
+ * abort scan
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to net device
+ * @data : Pointer to the data
+ * @data_len : length of the data
+ *
+ * This is called from supplicant to abort scan
+ *
+ * Return: zero for success and non zero for failure
+ */
+int wlan_hdd_vendor_abort_scan(
+	struct wiphy *wiphy, struct wireless_dev *wdev,
+	const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_vendor_abort_scan(wiphy,
+					   data,
+					   data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_scan_abort() - abort ongoing scan
+ * @adapter: Pointer to interface adapter
+ *
+ * Return: 0 for success, non zero for failure
+ */
+int wlan_hdd_scan_abort(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
+			adapter->session_id, INVALID_SCAN_ID, true);
+
+	return 0;
+}
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+/**
+ * __wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer network device
+ * @request: Pointer to cfg80211 scheduled scan start request
+ *
+ * Return: 0 for success, non zero for failure
+ */
+static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
+						struct net_device *dev,
+						struct
+						cfg80211_sched_scan_request
+						*request)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	if (adapter->device_mode != QDF_STA_MODE) {
+		hdd_info("Sched scans only supported on STA ifaces");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (!hdd_ctx->config->PnoOffload) {
+		hdd_debug("PnoOffload is not enabled!!!");
+		return -EINVAL;
+	}
+
+	if ((eConnectionState_Associated ==
+				WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
+							conn_info.connState) &&
+	    (!hdd_ctx->config->enable_connected_scan)) {
+		hdd_info("enable_connected_scan is false, Aborting scan");
+		return -EBUSY;
+	}
+
+	return wlan_cfg80211_sched_scan_start(hdd_ctx->pdev, dev, request,
+				      hdd_ctx->config->scan_backoff_multiplier);
+}
+
+/**
+ * wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer network device
+ * @request: Pointer to cfg80211 scheduled scan start request
+ *
+ * Return: 0 for success, non zero for failure
+ */
+int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
+				       struct net_device *dev,
+				       struct cfg80211_sched_scan_request
+				       *request)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int wlan_hdd_sched_scan_stop(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (NULL == hdd_ctx) {
+		hdd_err("HDD context is Null");
+		return -EINVAL;
+	}
+	if (!hdd_ctx->config->PnoOffload) {
+		hdd_debug("PnoOffload is not enabled!!!");
+		return -EINVAL;
+	}
+
+	return wlan_cfg80211_sched_scan_stop(hdd_ctx->pdev, dev);
+}
+
+/**
+ * __wlan_hdd_cfg80211_sched_scan_stop() - stop cfg80211 scheduled scan(pno)
+ * @dev: Pointer network device
+ *
+ * This is a wrapper around wlan_hdd_sched_scan_stop() that returns success
+ * in the event that the driver is currently recovering or unloading. This
+ * prevents a race condition where we get a scan stop from kernel during
+ * a driver unload from PLD.
+ *
+ * Return: 0 for success, non zero for failure
+ */
+static int __wlan_hdd_cfg80211_sched_scan_stop(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int errno;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err_rl("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+
+	/* The return 0 is intentional when Recovery and Load/Unload in
+	 * progress. We did observe a crash due to a return of
+	 * failure in sched_scan_stop , especially for a case where the unload
+	 * of the happens at the same time. The function
+	 * __cfg80211_stop_sched_scan was clearing rdev->sched_scan_req only
+	 * when the sched_scan_stop returns success. If it returns a failure ,
+	 * then its next invocation due to the clean up of the second interface
+	 * will have the dev pointer corresponding to the first one leading to
+	 * a crash.
+	 */
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		hdd_info("Recovery in Progress. State: 0x%x Ignore!!!",
+			 cds_get_driver_state());
+		return 0;
+	}
+
+	if (cds_is_load_or_unload_in_progress()) {
+		hdd_info("Unload/Load in Progress, state: 0x%x.  Ignore!!!",
+			cds_get_driver_state());
+		return 0;
+	}
+
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		return errno;
+
+	if (adapter->device_mode != QDF_STA_MODE) {
+		hdd_info("Sched scans only supported on STA ifaces");
+		return -EINVAL;
+	}
+
+	errno = wlan_hdd_validate_context(WLAN_HDD_GET_CTX(adapter));
+	if (errno)
+		return errno;
+
+	errno = wlan_hdd_sched_scan_stop(dev);
+
+	hdd_exit();
+
+	return errno;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
+int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
+				      struct net_device *dev)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_sched_scan_stop(dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#else
+int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
+				      struct net_device *dev,
+				      uint64_t reqid)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_sched_scan_stop(dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif /* KERNEL_VERSION(4, 12, 0) */
+#endif /*FEATURE_WLAN_SCAN_PNO */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \
+	defined(CFG80211_ABORT_SCAN)
+/**
+ * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wireless device structure
+ *
+ * This function is used to abort an ongoing scan
+ *
+ * Return: None
+ */
+static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
+					   struct wireless_dev *wdev)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return;
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return;
+
+	wlan_cfg80211_abort_scan(hdd_ctx->pdev);
+
+	hdd_exit();
+}
+
+/**
+ * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wireless device structure
+ *
+ * Wrapper to __wlan_hdd_cfg80211_abort_scan() -
+ * function is used to abort an ongoing scan
+ *
+ * Return: None
+ */
+void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
+				  struct wireless_dev *wdev)
+{
+	cds_ssr_protect(__func__);
+	__wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
+	cds_ssr_unprotect(__func__);
+}
+#endif
+
+/**
+ * hdd_scan_context_destroy() - Destroy scan context
+ * @hdd_ctx:	HDD context.
+ *
+ * Destroy scan context.
+ *
+ * Return: None.
+ */
+void hdd_scan_context_destroy(struct hdd_context *hdd_ctx)
+{
+}
+
+/**
+ * hdd_scan_context_init() - Initialize scan context
+ * @hdd_ctx:	HDD context.
+ *
+ * Initialize scan related resources like spin lock and lists.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+int hdd_scan_context_init(struct hdd_context *hdd_ctx)
+{
+	return 0;
+}
diff --git a/core/hdd/src/wlan_hdd_scan.h b/core/hdd/src/wlan_hdd_scan.h
new file mode 100644
index 0000000..bcc874b
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_scan.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2012-2018 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 : wlan_hdd_scan.h
+ *
+ * WLAN Host Device Driver scan related implementation
+ *
+ */
+
+#if !defined(WLAN_HDD_SCAN_H)
+#define WLAN_HDD_SCAN_H
+
+#include "wlan_hdd_main.h"
+#include "csr_inside_api.h"
+#include <wlan_cfg80211_scan.h>
+
+#define MAX_PENDING_LOG 5
+
+/* (30 Mins) */
+#define MIN_TIME_REQUIRED_FOR_NEXT_BUG_REPORT (30 * 60 * 1000)
+
+/* HDD Scan inactivity timeout set to double
+ * of the CSR CMD Timeout.
+ */
+#define HDD_SCAN_INACTIVITY_TIMEOUT \
+	(CSR_ACTIVE_SCAN_LIST_CMD_TIMEOUT * 2)
+
+int hdd_scan_context_init(struct hdd_context *hdd_ctx);
+void hdd_scan_context_destroy(struct hdd_context *hdd_ctx);
+
+int wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
+			   struct cfg80211_scan_request *request);
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
+				       struct net_device *dev,
+				       struct cfg80211_sched_scan_request
+				       *request);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
+/**
+ * wlan_hdd_cfg80211_sched_scan_stop() - stop cfg80211 scheduled (PNO) scan
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer network device
+ *
+ * Note, this returns success if the driver is recovering or unloading to
+ * prevent race conditions between PLD initiating an unload and kernel
+ * initiating a scheduled scan stop via cfg80211. Unload is expected to stop
+ * any pending scheduled scans in this case.
+ *
+ * Return: 0 for success, non zero for failure
+ */
+int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
+				      struct net_device *dev);
+#else
+int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
+				      struct net_device *dev,
+				      uint64_t reqid);
+
+#endif /* KERNEL_VERSION(4, 12, 0) */
+
+/**
+ * wlan_hdd_sched_scan_stop() - stop scheduled (PNO) scans
+ * @dev: Pointer network device
+ *
+ * Return: 0 for success, non zero for failure
+ */
+int wlan_hdd_sched_scan_stop(struct net_device *dev);
+#else
+static inline int wlan_hdd_sched_scan_stop(struct net_device *dev)
+{
+	return 0;
+}
+#endif /* End of FEATURE_WLAN_SCAN_PNO */
+
+int wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data,
+		int data_len);
+
+/**
+ * wlan_hdd_vendor_abort_scan() - API to process vendor command for
+ * abort scan
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to net device
+ * @data : Pointer to the data
+ * @data_len : length of the data
+ *
+ * This is called from supplicant to abort scan
+ *
+ * Return: zero for success and non zero for failure.
+ */
+int wlan_hdd_vendor_abort_scan(
+	struct wiphy *wiphy, struct wireless_dev *wdev,
+	const void *data, int data_len);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \
+	defined(CFG80211_ABORT_SCAN)
+void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
+				  struct wireless_dev *wdev);
+#endif
+
+/**
+ * hdd_init_scan_reject_params() - init scan reject params
+ * @hdd_ctx: hdd contxt
+ *
+ * Return: None
+ */
+void hdd_init_scan_reject_params(struct hdd_context *hdd_ctx);
+
+/**
+ * hdd_reset_scan_reject_params() - reset scan reject params per roam stats
+ * @hdd_ctx: hdd contxt
+ * @roam_status: roam status
+ * @roam_result: roam result
+ *
+ * Return: None
+ */
+void hdd_reset_scan_reject_params(struct hdd_context *hdd_ctx,
+				  eRoamCmdStatus roam_status,
+				  eCsrRoamResult roam_result);
+
+/**
+ * wlan_hdd_cfg80211_scan_block_cb() - scan block work handler
+ * @work: Pointer to work
+ *
+ * This function is used to do scan block work handler
+ *
+ * Return: none
+ */
+void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work);
+#endif /* end #if !defined(WLAN_HDD_SCAN_H) */
+
diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c
new file mode 100644
index 0000000..24a9649
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c
@@ -0,0 +1,1251 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/* denote that this file does not allow legacy hddLog */
+#define HDD_DISALLOW_LEGACY_HDDLOG 1
+
+/* Include files */
+#include <linux/semaphore.h>
+#include <wlan_hdd_tx_rx.h>
+#include <wlan_hdd_softap_tx_rx.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <qdf_types.h>
+#include <ani_global.h>
+#include <qdf_types.h>
+#include <net/ieee80211_radiotap.h>
+#include <cds_sched.h>
+#include <wlan_hdd_napi.h>
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_peer_ops.h>
+#include <cds_utils.h>
+#include <cdp_txrx_flow_ctrl_v2.h>
+#include <cdp_txrx_misc.h>
+#include <wlan_hdd_object_manager.h>
+#include "wlan_p2p_ucfg_api.h"
+#include <wlan_hdd_regulatory.h>
+#include "wlan_ipa_ucfg_api.h"
+#include <wma_types.h>
+
+/* Preprocessor definitions and constants */
+#undef QCA_HDD_SAP_DUMP_SK_BUFF
+
+/* Type declarations */
+
+/* Function definitions and documenation */
+#ifdef QCA_HDD_SAP_DUMP_SK_BUFF
+/**
+ * hdd_softap_dump_sk_buff() - Dump an skb
+ * @skb: skb to dump
+ *
+ * Return: None
+ */
+static void hdd_softap_dump_sk_buff(struct sk_buff *skb)
+{
+	QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
+		  "%s: head = %pK ", __func__, skb->head);
+	QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
+		  "%s: tail = %pK ", __func__, skb->tail);
+	QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
+		  "%s: end = %pK ", __func__, skb->end);
+	QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
+		  "%s: len = %d ", __func__, skb->len);
+	QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
+		  "%s: data_len = %d ", __func__, skb->data_len);
+	QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
+		  "%s: mac_len = %d", __func__, skb->mac_len);
+
+	QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
+		  "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x ", skb->data[0],
+		  skb->data[1], skb->data[2], skb->data[3], skb->data[4],
+		  skb->data[5], skb->data[6], skb->data[7]);
+	QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
+		  "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", skb->data[8],
+		  skb->data[9], skb->data[10], skb->data[11], skb->data[12],
+		  skb->data[13], skb->data[14], skb->data[15]);
+}
+#else
+static void hdd_softap_dump_sk_buff(struct sk_buff *skb)
+{
+}
+#endif
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+void hdd_softap_tx_resume_timer_expired_handler(void *adapter_context)
+{
+	struct hdd_adapter *adapter = (struct hdd_adapter *) adapter_context;
+
+	if (!adapter) {
+		hdd_err("NULL adapter");
+		return;
+	}
+
+	hdd_debug("Enabling queues");
+	wlan_hdd_netif_queue_control(adapter, WLAN_WAKE_ALL_NETIF_QUEUE,
+				     WLAN_CONTROL_PATH);
+}
+
+#if defined(CONFIG_PER_VDEV_TX_DESC_POOL)
+
+/**
+ * hdd_softap_tx_resume_false() - Resume OS TX Q false leads to queue disabling
+ * @adapter: pointer to hdd adapter
+ * @tx_resume: TX Q resume trigger
+ *
+ *
+ * Return: None
+ */
+static void
+hdd_softap_tx_resume_false(struct hdd_adapter *adapter, bool tx_resume)
+{
+	if (true == tx_resume)
+		return;
+
+	hdd_debug("Disabling queues");
+	wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
+				     WLAN_DATA_FLOW_CONTROL);
+
+	if (QDF_TIMER_STATE_STOPPED ==
+			qdf_mc_timer_get_current_state(&adapter->
+						       tx_flow_control_timer)) {
+		QDF_STATUS status;
+
+		status = qdf_mc_timer_start(&adapter->tx_flow_control_timer,
+				WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
+
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("Failed to start tx_flow_control_timer");
+		else
+			adapter->hdd_stats.tx_rx_stats.txflow_timer_cnt++;
+	}
+}
+#else
+
+static inline void
+hdd_softap_tx_resume_false(struct hdd_adapter *adapter, bool tx_resume)
+{
+}
+#endif
+
+void hdd_softap_tx_resume_cb(void *adapter_context, bool tx_resume)
+{
+	struct hdd_adapter *adapter = (struct hdd_adapter *) adapter_context;
+
+	if (!adapter) {
+		hdd_err("NULL adapter");
+		return;
+	}
+
+	/* Resume TX  */
+	if (true == tx_resume) {
+		if (QDF_TIMER_STATE_STOPPED !=
+		    qdf_mc_timer_get_current_state(&adapter->
+						   tx_flow_control_timer)) {
+			qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
+		}
+
+		hdd_debug("Enabling queues");
+		wlan_hdd_netif_queue_control(adapter,
+					WLAN_WAKE_ALL_NETIF_QUEUE,
+					WLAN_DATA_FLOW_CONTROL);
+	}
+	hdd_softap_tx_resume_false(adapter, tx_resume);
+}
+
+static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter,
+		struct sk_buff *skb)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int need_orphan = 0;
+
+	if (adapter->tx_flow_low_watermark > 0) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
+		/*
+		 * The TCP TX throttling logic is changed a little after
+		 * 3.19-rc1 kernel, the TCP sending limit will be smaller,
+		 * which will throttle the TCP packets to the host driver.
+		 * The TCP UP LINK throughput will drop heavily. In order to
+		 * fix this issue, need to orphan the socket buffer asap, which
+		 * will call skb's destructor to notify the TCP stack that the
+		 * SKB buffer is unowned. And then the TCP stack will pump more
+		 * packets to host driver.
+		 *
+		 * The TX packets might be dropped for UDP case in the iperf
+		 * testing. So need to be protected by follow control.
+		 */
+		need_orphan = 1;
+#else
+		if (hdd_ctx->config->tx_orphan_enable)
+			need_orphan = 1;
+#endif
+	} else if (hdd_ctx->config->tx_orphan_enable) {
+		if (qdf_nbuf_is_ipv4_tcp_pkt(skb) ||
+		    qdf_nbuf_is_ipv6_tcp_pkt(skb))
+			need_orphan = 1;
+	}
+
+	if (need_orphan) {
+		skb_orphan(skb);
+		++adapter->hdd_stats.tx_rx_stats.tx_orphaned;
+	} else
+		skb = skb_unshare(skb, GFP_ATOMIC);
+
+	return skb;
+}
+
+#else
+/**
+ * hdd_skb_orphan() - skb_unshare a cloned packed else skb_orphan
+ * @adapter: pointer to HDD adapter
+ * @skb: pointer to skb data packet
+ *
+ * Return: pointer to skb structure
+ */
+static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter,
+		struct sk_buff *skb) {
+
+	struct sk_buff *nskb;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+#endif
+
+	hdd_skb_fill_gso_size(adapter->dev, skb);
+
+	nskb = skb_unshare(skb, GFP_ATOMIC);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
+	if (unlikely(hdd_ctx->config->tx_orphan_enable) && (nskb == skb)) {
+		/*
+		 * For UDP packets we want to orphan the packet to allow the app
+		 * to send more packets. The flow would ultimately be controlled
+		 * by the limited number of tx descriptors for the vdev.
+		 */
+		++adapter->hdd_stats.tx_rx_stats.tx_orphaned;
+		skb_orphan(skb);
+	}
+#endif
+	return nskb;
+}
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+
+/**
+ * hdd_post_dhcp_ind() - Send DHCP START/STOP indication to FW
+ * @adapter: pointer to hdd adapter
+ * @sta_id: peer station ID
+ * @type: WMA message type
+ *
+ * Return: error number
+ */
+int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
+			     uint8_t sta_id, uint16_t type)
+{
+	tAniDHCPInd pmsg;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	hdd_debug("Post DHCP indication,sta_id=%d,  type=%d", sta_id, type);
+
+	if (!adapter) {
+		hdd_err("NULL adapter");
+		return -EINVAL;
+	}
+
+	pmsg.msgType = type;
+	pmsg.msgLen = (uint16_t) sizeof(tAniDHCPInd);
+	pmsg.device_mode = adapter->device_mode;
+	qdf_mem_copy(pmsg.adapterMacAddr.bytes,
+		     adapter->mac_addr.bytes,
+		     QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(pmsg.peerMacAddr.bytes,
+		     adapter->sta_info[sta_id].sta_mac.bytes,
+		     QDF_MAC_ADDR_SIZE);
+
+	status = wma_process_dhcp_ind(cds_get_context(QDF_MODULE_ID_WMA),
+				      &pmsg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Post DHCP Ind MSG fail", __func__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/**
+ * hdd_softap_notify_dhcp_ind() - Notify SAP for DHCP indication for tx desc
+ * @context: pointer to HDD context
+ * @netbuf: pointer to OS packet (sk_buff)
+ *
+ * Return: None
+ */
+static void hdd_softap_notify_dhcp_ind(void *context, struct sk_buff *netbuf)
+{
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	struct qdf_mac_addr *dest_mac_addr;
+	uint8_t sta_id;
+	struct hdd_adapter *adapter = context;
+
+	if (hdd_validate_adapter(adapter))
+		return;
+
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+	if (!hdd_ap_ctx) {
+		hdd_err("HDD sap context is NULL");
+		return;
+	}
+
+	dest_mac_addr = (struct qdf_mac_addr *)netbuf->data;
+
+	if (QDF_NBUF_CB_GET_IS_BCAST(netbuf) ||
+	    QDF_NBUF_CB_GET_IS_MCAST(netbuf)) {
+		/* The BC/MC station ID is assigned during BSS
+		 * starting phase.  SAP will return the station ID
+		 * used for BC/MC traffic.
+		 */
+		sta_id = hdd_ap_ctx->broadcast_sta_id;
+	} else {
+		if (QDF_STATUS_SUCCESS !=
+		    hdd_softap_get_sta_id(adapter,
+					  dest_mac_addr, &sta_id)) {
+			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s: Failed to find right station", __func__);
+			return;
+		}
+	}
+	hdd_post_dhcp_ind(adapter, sta_id, WMA_DHCP_STOP_IND);
+}
+
+/**
+ * hdd_inspect_dhcp_packet() - Inspect DHCP packet
+ * @adapter: pointer to hdd adapter
+ * @sta_id: peer station ID
+ * @skb: pointer to OS packet (sk_buff)
+ * @dir: direction
+ *
+ * Inspect the Tx/Rx frame, and send DHCP START/STOP notification to the FW
+ * through WMI message, during DHCP based IP address acquisition phase.
+ *
+ * - Send DHCP_START notification to FW when SAP gets DHCP Discovery
+ * - Send DHCP_STOP notification to FW when SAP sends DHCP ACK/NAK
+ *
+ * DHCP subtypes are determined by a status octet in the DHCP Message type
+ * option (option code 53 (0x35)).
+ *
+ * Each peer will be in one of 4 DHCP phases, starts from QDF_DHCP_PHASE_ACK,
+ * and transitioned per DHCP message type as it arrives.
+ *
+ * - QDF_DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase
+ * - QDF_DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase
+ * - QDF_DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase
+ *	or ACK phase (Renewal process)
+ * - QDF_DHCP_PHASE_ACK : upon receiving DHCP_ACK/NAK message in REQUEST phase
+ *	or DHCP_DELINE message in OFFER phase
+ *
+ * Return: error number
+ */
+int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
+			    uint8_t sta_id,
+			    struct sk_buff *skb,
+			    enum qdf_proto_dir dir)
+{
+	enum qdf_proto_subtype subtype = QDF_PROTO_INVALID;
+	struct hdd_station_info *hdd_sta_info;
+	int errno = 0;
+
+	if (sta_id >= WLAN_MAX_STA_COUNT) {
+		hdd_err("Invalid sta id: %d", sta_id);
+		return -EINVAL;
+	}
+
+	if (((adapter->device_mode == QDF_SAP_MODE) ||
+	     (adapter->device_mode == QDF_P2P_GO_MODE)) &&
+	    ((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_DHCP ==
+				QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
+	     (dir == QDF_RX && qdf_nbuf_is_ipv4_dhcp_pkt(skb) == true))) {
+
+		subtype = qdf_nbuf_get_dhcp_subtype(skb);
+		hdd_sta_info = &adapter->sta_info[sta_id];
+
+		hdd_debug("ENTER: type=%d, phase=%d, nego_status=%d",
+			  subtype,
+			  hdd_sta_info->dhcp_phase,
+			  hdd_sta_info->dhcp_nego_status);
+
+		switch (subtype) {
+		case QDF_PROTO_DHCP_DISCOVER:
+			if (dir != QDF_RX)
+				break;
+			if (hdd_sta_info->dhcp_nego_status == DHCP_NEGO_STOP)
+				errno = hdd_post_dhcp_ind(adapter, sta_id,
+							   WMA_DHCP_START_IND);
+			hdd_sta_info->dhcp_phase = DHCP_PHASE_DISCOVER;
+			hdd_sta_info->dhcp_nego_status = DHCP_NEGO_IN_PROGRESS;
+			break;
+		case QDF_PROTO_DHCP_OFFER:
+			hdd_sta_info->dhcp_phase = DHCP_PHASE_OFFER;
+			break;
+		case QDF_PROTO_DHCP_REQUEST:
+			if (dir != QDF_RX)
+				break;
+			if (hdd_sta_info->dhcp_nego_status == DHCP_NEGO_STOP)
+				errno = hdd_post_dhcp_ind(adapter, sta_id,
+							   WMA_DHCP_START_IND);
+			hdd_sta_info->dhcp_nego_status = DHCP_NEGO_IN_PROGRESS;
+		case QDF_PROTO_DHCP_DECLINE:
+			if (dir == QDF_RX)
+				hdd_sta_info->dhcp_phase = DHCP_PHASE_REQUEST;
+			break;
+		case QDF_PROTO_DHCP_ACK:
+		case QDF_PROTO_DHCP_NACK:
+			hdd_sta_info->dhcp_phase = DHCP_PHASE_ACK;
+			if (hdd_sta_info->dhcp_nego_status ==
+				DHCP_NEGO_IN_PROGRESS) {
+				hdd_debug("Setting NOTIFY_COMP Flag");
+				QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(skb)
+									= 1;
+			}
+			hdd_sta_info->dhcp_nego_status = DHCP_NEGO_STOP;
+			break;
+		default:
+			break;
+		}
+
+		hdd_debug("EXIT: phase=%d, nego_status=%d",
+			  hdd_sta_info->dhcp_phase,
+			  hdd_sta_info->dhcp_nego_status);
+	}
+
+	return errno;
+}
+
+/**
+ * __hdd_softap_hard_start_xmit() - Transmit a frame
+ * @skb: pointer to OS packet (sk_buff)
+ * @dev: pointer to network device
+ *
+ * Function registered with the Linux OS for transmitting
+ * packets. This version of the function directly passes
+ * the packet to Transport Layer.
+ * In case of any packet drop or error, log the error with
+ * INFO HIGH/LOW/MEDIUM to avoid excessive logging in kmsg.
+ *
+ * Return: Always returns NETDEV_TX_OK
+ */
+static netdev_tx_t __hdd_softap_hard_start_xmit(struct sk_buff *skb,
+						struct net_device *dev)
+{
+	sme_ac_enum_type ac = SME_AC_BE;
+	struct hdd_adapter *adapter = (struct hdd_adapter *) netdev_priv(dev);
+	struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+	struct qdf_mac_addr *dest_mac_addr;
+	uint8_t sta_id;
+	uint32_t num_seg;
+
+	++adapter->hdd_stats.tx_rx_stats.tx_called;
+	adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0;
+
+	/* Prevent this function from being called during SSR since TL
+	 * context may not be reinitialized at this time which may
+	 * lead to a crash.
+	 */
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state() ||
+	    cds_is_load_or_unload_in_progress()) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: Recovery/(Un)load in Progress. Ignore!!!",
+			  __func__);
+		goto drop_pkt;
+	}
+
+	/*
+	 * If the device is operating on a DFS Channel
+	 * then check if SAP is in CAC WAIT state and
+	 * drop the packets. In CAC WAIT state device
+	 * is expected not to transmit any frames.
+	 * SAP starts Tx only after the BSS START is
+	 * done.
+	 */
+	if (ap_ctx->dfs_cac_block_tx)
+		goto drop_pkt;
+
+	/*
+	 * If a transmit function is not registered, drop packet
+	 */
+	if (!adapter->tx_fn) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+			 "%s: TX function not registered by the data path",
+			 __func__);
+		goto drop_pkt;
+	}
+
+	wlan_hdd_classify_pkt(skb);
+
+	dest_mac_addr = (struct qdf_mac_addr *)skb->data;
+
+	if (QDF_NBUF_CB_GET_IS_BCAST(skb) ||
+	    QDF_NBUF_CB_GET_IS_MCAST(skb)) {
+		/* The BC/MC station ID is assigned during BSS
+		 * starting phase.  SAP will return the station ID
+		 * used for BC/MC traffic.
+		 */
+		sta_id = ap_ctx->broadcast_sta_id;
+	} else {
+		if (QDF_STATUS_SUCCESS !=
+			 hdd_softap_get_sta_id(adapter,
+				 dest_mac_addr, &sta_id)) {
+			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s: Failed to find right station", __func__);
+			goto drop_pkt;
+		}
+
+		if (sta_id >= WLAN_MAX_STA_COUNT) {
+			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s: Failed to find right station", __func__);
+			goto drop_pkt;
+		} else if (!adapter->sta_info[sta_id].in_use) {
+			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s: STA %d is unregistered", __func__,
+				  sta_id);
+			goto drop_pkt;
+		} else if (adapter->sta_info[sta_id].
+							is_deauth_in_progress) {
+			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s: STA %d deauth in progress", __func__,
+				  sta_id);
+			goto drop_pkt;
+		}
+
+		if ((OL_TXRX_PEER_STATE_CONN !=
+		     adapter->sta_info[sta_id].peer_state)
+		    && (OL_TXRX_PEER_STATE_AUTH !=
+			adapter->sta_info[sta_id].peer_state)) {
+			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s: Station not connected yet", __func__);
+			goto drop_pkt;
+		} else if (OL_TXRX_PEER_STATE_CONN ==
+			   adapter->sta_info[sta_id].peer_state) {
+			if (ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X) {
+				QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
+					  QDF_TRACE_LEVEL_INFO_HIGH,
+					  "%s: NON-EAPOL packet in non-Authenticated state",
+					  __func__);
+				goto drop_pkt;
+			}
+		}
+	}
+
+	hdd_get_tx_resource(adapter, sta_id,
+			    WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
+
+	/* Get TL AC corresponding to Qdisc queue index/AC. */
+	ac = hdd_qdisc_ac_to_tl_ac[skb->queue_mapping];
+	++adapter->hdd_stats.tx_rx_stats.tx_classified_ac[ac];
+
+#if defined(IPA_OFFLOAD)
+	if (!qdf_nbuf_ipa_owned_get(skb)) {
+#endif
+
+		skb = hdd_skb_orphan(adapter, skb);
+		if (!skb)
+			goto drop_pkt_accounting;
+
+#if defined(IPA_OFFLOAD)
+	} else {
+		/*
+		 * Clear the IPA ownership after check it to avoid ipa_free_skb
+		 * is called when Tx completed for intra-BSS Tx packets
+		 */
+		qdf_nbuf_ipa_owned_clear(skb);
+	}
+#endif
+
+	/*
+	 * Add SKB to internal tracking table before further processing
+	 * in WLAN driver.
+	 */
+	qdf_net_buf_debug_acquire_skb(skb, __FILE__, __LINE__);
+
+	adapter->stats.tx_bytes += skb->len;
+	adapter->sta_info[sta_id].tx_bytes += skb->len;
+
+	if (qdf_nbuf_is_tso(skb)) {
+		num_seg = qdf_nbuf_get_tso_num_seg(skb);
+		adapter->stats.tx_packets += num_seg;
+		adapter->sta_info[sta_id].tx_packets += num_seg;
+	} else {
+		++adapter->stats.tx_packets;
+		adapter->sta_info[sta_id].tx_packets++;
+	}
+	adapter->sta_info[sta_id].last_tx_rx_ts = qdf_system_ticks();
+
+	QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(skb) = 0;
+
+	if (sta_id != ap_ctx->broadcast_sta_id)
+		hdd_inspect_dhcp_packet(adapter, sta_id, skb, QDF_TX);
+
+	hdd_event_eapol_log(skb, QDF_TX);
+	QDF_NBUF_CB_TX_PACKET_TRACK(skb) = QDF_NBUF_TX_PKT_DATA_TRACK;
+	QDF_NBUF_UPDATE_TX_PKT_COUNT(skb, QDF_NBUF_TX_PKT_HDD);
+	qdf_dp_trace_set_track(skb, QDF_TX);
+	DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD,
+			QDF_TRACE_DEFAULT_PDEV_ID, qdf_nbuf_data_addr(skb),
+			sizeof(qdf_nbuf_data(skb)),
+			QDF_TX));
+
+	/* check whether need to linearize skb, like non-linear udp data */
+	if (hdd_skb_nontso_linearize(skb) != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+			  QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: skb %pK linearize failed. drop the pkt",
+			  __func__, skb);
+		++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
+		goto drop_pkt_and_release_skb;
+	}
+
+	if (adapter->tx_fn(adapter->txrx_vdev,
+		 (qdf_nbuf_t)skb) != NULL) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: Failed to send packet to txrx for staid:%d",
+			  __func__, sta_id);
+		++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
+		goto drop_pkt_and_release_skb;
+	}
+	netif_trans_update(dev);
+
+	return NETDEV_TX_OK;
+
+drop_pkt_and_release_skb:
+	qdf_net_buf_debug_release_skb(skb);
+drop_pkt:
+
+	qdf_dp_trace_data_pkt(skb, QDF_TRACE_DEFAULT_PDEV_ID,
+			      QDF_DP_TRACE_DROP_PACKET_RECORD, 0,
+			      QDF_TX);
+	kfree_skb(skb);
+
+drop_pkt_accounting:
+	++adapter->stats.tx_dropped;
+	++adapter->hdd_stats.tx_rx_stats.tx_dropped;
+
+	return NETDEV_TX_OK;
+}
+
+netdev_tx_t hdd_softap_hard_start_xmit(struct sk_buff *skb,
+				       struct net_device *dev)
+{
+	netdev_tx_t ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_softap_hard_start_xmit(skb, dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static void __hdd_softap_tx_timeout(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	struct netdev_queue *txq;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	int i;
+
+	DPTRACE(qdf_dp_trace(NULL, QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT,
+			QDF_TRACE_DEFAULT_PDEV_ID,
+			NULL, 0, QDF_TX));
+	/* Getting here implies we disabled the TX queues for too
+	 * long. Queues are disabled either because of disassociation
+	 * or low resource scenarios. In case of disassociation it is
+	 * ok to ignore this. But if associated, we have do possible
+	 * recovery here
+	 */
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
+			 "%s: Recovery in Progress. Ignore!!!", __func__);
+		return;
+	}
+
+	TX_TIMEOUT_TRACE(dev, QDF_MODULE_ID_HDD_SAP_DATA);
+
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		txq = netdev_get_tx_queue(dev, i);
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+			  QDF_TRACE_LEVEL_DEBUG,
+			  "Queue: %d status: %d txq->trans_start: %lu",
+			  i, netif_tx_queue_stopped(txq), txq->trans_start);
+	}
+
+	wlan_hdd_display_netif_queue_history(hdd_ctx,
+					     QDF_STATS_VERBOSITY_LEVEL_HIGH);
+	cdp_dump_flow_pool_info(cds_get_context(QDF_MODULE_ID_SOC));
+	QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+			"carrier state: %d", netif_carrier_ok(dev));
+
+	++adapter->hdd_stats.tx_rx_stats.tx_timeout_cnt;
+	++adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt;
+
+	if (adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt >
+	    HDD_TX_STALL_THRESHOLD) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "Detected data stall due to continuous TX timeouts");
+		adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0;
+		if (cdp_cfg_get(soc, cfg_dp_enable_data_stall))
+			cdp_post_data_stall_event(soc,
+					  DATA_STALL_LOG_INDICATOR_HOST_DRIVER,
+					  DATA_STALL_LOG_HOST_SOFTAP_TX_TIMEOUT,
+					  0xFF, 0xFF,
+					  DATA_STALL_LOG_RECOVERY_TRIGGER_PDR);
+	}
+}
+
+void hdd_softap_tx_timeout(struct net_device *dev)
+{
+	cds_ssr_protect(__func__);
+	__hdd_softap_tx_timeout(dev);
+	cds_ssr_unprotect(__func__);
+}
+
+QDF_STATUS hdd_softap_init_tx_rx(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	uint8_t STAId = 0;
+
+	qdf_mem_zero(&adapter->stats, sizeof(struct net_device_stats));
+
+	spin_lock_init(&adapter->sta_info_lock);
+
+	for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) {
+		qdf_mem_zero(&adapter->sta_info[STAId],
+			     sizeof(struct hdd_station_info));
+	}
+
+	return status;
+}
+
+QDF_STATUS hdd_softap_deinit_tx_rx(struct hdd_adapter *adapter)
+{
+	QDF_BUG(adapter);
+	if (!adapter)
+		return QDF_STATUS_E_FAILURE;
+
+	adapter->txrx_vdev = NULL;
+	adapter->tx_fn = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS hdd_softap_init_tx_rx_sta(struct hdd_adapter *adapter,
+				     uint8_t sta_id,
+				     struct qdf_mac_addr *sta_mac)
+{
+	spin_lock_bh(&adapter->sta_info_lock);
+	if (adapter->sta_info[sta_id].in_use) {
+		spin_unlock_bh(&adapter->sta_info_lock);
+		hdd_err("Reinit of in use station %d", sta_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_zero(&adapter->sta_info[sta_id],
+		     sizeof(struct hdd_station_info));
+
+	adapter->sta_info[sta_id].in_use = true;
+	adapter->sta_info[sta_id].is_deauth_in_progress = false;
+	qdf_copy_macaddr(&adapter->sta_info[sta_id].sta_mac, sta_mac);
+
+	spin_unlock_bh(&adapter->sta_info_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS hdd_softap_deinit_tx_rx_sta(struct hdd_adapter *adapter,
+				       uint8_t sta_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct hdd_hostapd_state *hostapd_state;
+
+	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+
+	spin_lock_bh(&adapter->sta_info_lock);
+
+	if (false == adapter->sta_info[sta_id].in_use) {
+		spin_unlock_bh(&adapter->sta_info_lock);
+		hdd_err("Deinit station not inited %d", sta_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	adapter->sta_info[sta_id].in_use = false;
+	adapter->sta_info[sta_id].is_deauth_in_progress = false;
+
+	spin_unlock_bh(&adapter->sta_info_lock);
+	return status;
+}
+
+/**
+ * hdd_softap_notify_tx_compl_cbk() - callback to notify tx completion
+ * @skb: pointer to skb data
+ * @adapter: pointer to vdev apdapter
+ *
+ * Return: None
+ */
+static void hdd_softap_notify_tx_compl_cbk(struct sk_buff *skb,
+					   void *context)
+{
+	int errno;
+	struct hdd_adapter *adapter = context;
+
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		return;
+
+	if (QDF_NBUF_CB_PACKET_TYPE_DHCP == QDF_NBUF_CB_GET_PACKET_TYPE(skb)) {
+		hdd_debug("sending DHCP indication");
+		hdd_softap_notify_dhcp_ind(context, skb);
+	}
+}
+
+QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf)
+{
+	struct hdd_adapter *adapter = NULL;
+	int rxstat;
+	unsigned int cpu_index;
+	struct sk_buff *skb = NULL;
+	struct sk_buff *next = NULL;
+	struct hdd_context *hdd_ctx = NULL;
+	struct qdf_mac_addr *src_mac;
+	uint8_t staid;
+
+	/* Sanity check on inputs */
+	if (unlikely((!adapter_context) || (!rx_buf))) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Null params being passed", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	adapter = (struct hdd_adapter *)adapter_context;
+	if (unlikely(WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "Magic cookie(%x) for adapter sanity verification is invalid",
+			  adapter->magic);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (unlikely(NULL == hdd_ctx)) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "%s: HDD context is Null", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* walk the chain until all are processed */
+	next = (struct sk_buff *)rx_buf;
+
+	while (next) {
+		skb = next;
+		next = skb->next;
+		skb->next = NULL;
+
+/* Debug code, remove later */
+#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390)
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+			 "%s: skb %pK skb->len %d\n", __func__, skb, skb->len);
+#endif
+
+		hdd_softap_dump_sk_buff(skb);
+
+		skb->dev = adapter->dev;
+
+		if (unlikely(skb->dev == NULL)) {
+			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
+				  QDF_TRACE_LEVEL_ERROR,
+				  "%s: ERROR!!Invalid netdevice", __func__);
+			continue;
+		}
+		cpu_index = wlan_hdd_get_cpu();
+		++adapter->hdd_stats.tx_rx_stats.rx_packets[cpu_index];
+		++adapter->stats.rx_packets;
+		adapter->stats.rx_bytes += skb->len;
+
+		/* Send DHCP Indication to FW */
+		src_mac = (struct qdf_mac_addr *)(skb->data +
+						  QDF_NBUF_SRC_MAC_OFFSET);
+		if (QDF_STATUS_SUCCESS ==
+			hdd_softap_get_sta_id(adapter, src_mac, &staid)) {
+			if (staid < WLAN_MAX_STA_COUNT) {
+				adapter->sta_info[staid].rx_packets++;
+				adapter->sta_info[staid].rx_bytes += skb->len;
+				adapter->sta_info[staid].last_tx_rx_ts =
+					qdf_system_ticks();
+				hdd_inspect_dhcp_packet(adapter, staid,
+							skb, QDF_RX);
+			}
+		}
+
+		hdd_event_eapol_log(skb, QDF_RX);
+		qdf_dp_trace_log_pkt(adapter->session_id,
+				     skb, QDF_RX, QDF_TRACE_DEFAULT_PDEV_ID);
+		DPTRACE(qdf_dp_trace(skb,
+			QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD,
+			QDF_TRACE_DEFAULT_PDEV_ID,
+			qdf_nbuf_data_addr(skb),
+			sizeof(qdf_nbuf_data(skb)), QDF_RX));
+		DPTRACE(qdf_dp_trace_data_pkt(skb, QDF_TRACE_DEFAULT_PDEV_ID,
+				QDF_DP_TRACE_RX_PACKET_RECORD, 0, QDF_RX));
+
+		skb->protocol = eth_type_trans(skb, skb->dev);
+
+		/* hold configurable wakelock for unicast traffic */
+		if (hdd_ctx->config->rx_wakelock_timeout &&
+			skb->pkt_type != PACKET_BROADCAST &&
+			skb->pkt_type != PACKET_MULTICAST) {
+			cds_host_diag_log_work(&hdd_ctx->rx_wake_lock,
+						   hdd_ctx->config->rx_wakelock_timeout,
+						   WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
+			qdf_wake_lock_timeout_acquire(&hdd_ctx->rx_wake_lock,
+							  hdd_ctx->config->
+								  rx_wakelock_timeout);
+		}
+
+		/* Remove SKB from internal tracking table before submitting
+		 * it to stack
+		 */
+		qdf_net_buf_debug_release_skb(skb);
+		if (hdd_napi_enabled(HDD_NAPI_ANY) &&
+			!hdd_ctx->enable_rxthread)
+			rxstat = netif_receive_skb(skb);
+		else
+			rxstat = netif_rx_ni(skb);
+
+		hdd_ctx->no_rx_offload_pkt_cnt++;
+
+		if (NET_RX_SUCCESS == rxstat)
+			++adapter->hdd_stats.tx_rx_stats.rx_delivered[cpu_index];
+		else
+			++adapter->hdd_stats.tx_rx_stats.rx_refused[cpu_index];
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS hdd_softap_deregister_sta(struct hdd_adapter *adapter,
+				     uint8_t sta_id)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct hdd_context *hdd_ctx;
+
+	if (NULL == adapter) {
+		hdd_err("NULL adapter");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
+		hdd_err("Invalid adapter magic");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	/* Clear station in TL and then update HDD data
+	 * structures. This helps to block RX frames from other
+	 * station to this station.
+	 */
+	qdf_status = cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
+			(struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX),
+			sta_id);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("cdp_clear_peer failed for staID %d, Status=%d [0x%08X]",
+			sta_id, qdf_status, qdf_status);
+	}
+
+	if (adapter->sta_info[sta_id].in_use) {
+		if (ucfg_ipa_is_enabled()) {
+			if (ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev,
+					  adapter->device_mode,
+					  adapter->sta_info[sta_id].sta_id,
+					  adapter->session_id,
+					  WLAN_IPA_CLIENT_DISCONNECT,
+					  adapter->sta_info[sta_id].sta_mac.
+					  bytes) != QDF_STATUS_SUCCESS)
+				hdd_err("WLAN_CLIENT_DISCONNECT event failed");
+		}
+		spin_lock_bh(&adapter->sta_info_lock);
+		qdf_mem_zero(&adapter->sta_info[sta_id],
+			     sizeof(struct hdd_station_info));
+		spin_unlock_bh(&adapter->sta_info_lock);
+	}
+
+	hdd_ctx->sta_to_adapter[sta_id] = NULL;
+
+	return qdf_status;
+}
+
+QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter,
+				   bool auth_required,
+				   bool privacy_required,
+				   uint8_t sta_id,
+				   struct qdf_mac_addr *sta_mac,
+				   bool wmm_enabled)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	struct ol_txrx_desc_type staDesc = { 0 };
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct ol_txrx_ops txrx_ops;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	hdd_info("STA:%u, Auth:%u, Priv:%u, WMM:%u",
+		 sta_id, auth_required, privacy_required, wmm_enabled);
+
+	/*
+	 * Clean up old entry if it is not cleaned up properly
+	 */
+	if (adapter->sta_info[sta_id].in_use) {
+		hdd_info("clean up old entry for STA %d", sta_id);
+		hdd_softap_deregister_sta(adapter, sta_id);
+	}
+
+	/* Get the Station ID from the one saved during the association. */
+	staDesc.sta_id = sta_id;
+
+	/* Save the adapter Pointer for this sta_id */
+	hdd_ctx->sta_to_adapter[sta_id] = adapter;
+
+	qdf_status = hdd_softap_init_tx_rx_sta(adapter, sta_id, sta_mac);
+
+	staDesc.is_qos_enabled = wmm_enabled;
+
+	/* Register the vdev transmit and receive functions */
+	qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
+
+	txrx_ops.tx.tx_comp = hdd_softap_notify_tx_compl_cbk;
+
+	if (adapter->hdd_ctx->enable_dp_rx_threads) {
+		txrx_ops.rx.rx = hdd_rx_pkt_thread_enqueue_cbk;
+		txrx_ops.rx.rx_stack = hdd_softap_rx_packet_cbk;
+	} else {
+		txrx_ops.rx.rx = hdd_softap_rx_packet_cbk;
+		txrx_ops.rx.rx_stack = NULL;
+	}
+
+	cdp_vdev_register(soc,
+		(struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
+		(struct cdp_pdev *)pdev, adapter->session_id),
+		adapter, (struct cdp_ctrl_objmgr_vdev *)adapter->vdev,
+		&txrx_ops);
+	adapter->txrx_vdev = (void *)cdp_get_vdev_from_vdev_id(soc,
+					(struct cdp_pdev *)pdev,
+					adapter->session_id);
+	adapter->tx_fn = txrx_ops.tx.tx;
+
+	qdf_status = cdp_peer_register(soc,
+			(struct cdp_pdev *)pdev, &staDesc);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("cdp_peer_register() failed to register.  Status = %d [0x%08X]",
+			qdf_status, qdf_status);
+		return qdf_status;
+	}
+
+	/* if ( WPA ), tell TL to go to 'connected' and after keys come to the
+	 * driver then go to 'authenticated'.  For all other authentication
+	 * types (those that do not require upper layer authentication) we can
+	 * put TL directly into 'authenticated' state
+	 */
+
+	adapter->sta_info[sta_id].sta_id = sta_id;
+	adapter->sta_info[sta_id].is_qos_enabled = wmm_enabled;
+
+	if (!auth_required) {
+		hdd_info("open/shared auth StaId= %d.  Changing TL state to AUTHENTICATED at Join time",
+			 adapter->sta_info[sta_id].sta_id);
+
+		/* Connections that do not need Upper layer auth,
+		 * transition TL directly to 'Authenticated' state.
+		 */
+		qdf_status = hdd_change_peer_state(adapter, staDesc.sta_id,
+						OL_TXRX_PEER_STATE_AUTH, false);
+
+		adapter->sta_info[sta_id].peer_state = OL_TXRX_PEER_STATE_AUTH;
+	} else {
+
+		hdd_info("ULA auth StaId= %d.  Changing TL state to CONNECTED at Join time",
+			 adapter->sta_info[sta_id].sta_id);
+
+		qdf_status = hdd_change_peer_state(adapter, staDesc.sta_id,
+						OL_TXRX_PEER_STATE_CONN, false);
+		adapter->sta_info[sta_id].peer_state = OL_TXRX_PEER_STATE_CONN;
+	}
+
+	hdd_debug("Enabling queues");
+	wlan_hdd_netif_queue_control(adapter,
+				   WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
+				   WLAN_CONTROL_PATH);
+
+	return qdf_status;
+}
+
+/**
+ * hdd_softap_register_bc_sta() - Register the SoftAP broadcast STA
+ * @adapter: pointer to adapter context
+ * @privacy_required: should 802.11 privacy bit be set?
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS hdd_softap_register_bc_sta(struct hdd_adapter *adapter,
+				      bool privacy_required)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct qdf_mac_addr broadcastMacAddr = QDF_MAC_ADDR_BCAST_INIT;
+	struct hdd_ap_ctx *ap_ctx;
+
+	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+
+	hdd_ctx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = adapter;
+	hdd_ctx->sta_to_adapter[ap_ctx->broadcast_sta_id] = adapter;
+	qdf_status =
+		hdd_softap_register_sta(adapter, false, privacy_required,
+					ap_ctx->broadcast_sta_id,
+					&broadcastMacAddr, 0);
+
+	return qdf_status;
+}
+
+/**
+ * hdd_softap_deregister_bc_sta() - Deregister the SoftAP broadcast STA
+ * @adapter: pointer to adapter context
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+static QDF_STATUS hdd_softap_deregister_bc_sta(struct hdd_adapter *adapter)
+{
+	struct hdd_ap_ctx *ap_ctx;
+
+	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+	return hdd_softap_deregister_sta(adapter, ap_ctx->broadcast_sta_id);
+}
+
+QDF_STATUS hdd_softap_stop_bss(struct hdd_adapter *adapter)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	uint8_t sta_id = 0;
+	struct hdd_context *hdd_ctx;
+	struct hdd_ap_ctx *ap_ctx;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+
+	/* This is stop bss callback running in scheduler thread so do not
+	 * driver unload in progress check otherwise it can lead to peer
+	 * object leak
+	 */
+	qdf_status = hdd_softap_deregister_bc_sta(adapter);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		hdd_err("Failed to deregister BC sta Id %d",
+			ap_ctx->broadcast_sta_id);
+
+	for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
+		/* This excludes BC sta as it is already deregistered */
+		if (adapter->sta_info[sta_id].in_use) {
+			qdf_status = hdd_softap_deregister_sta(adapter, sta_id);
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+				hdd_err("Failed to deregister sta Id %d",
+					sta_id);
+			}
+		}
+	}
+	if (adapter->device_mode == QDF_SAP_MODE)
+		wlan_hdd_restore_channels(hdd_ctx, true);
+
+	/*  Mark the indoor channel (passive) to enable  */
+	if (hdd_ctx->config->force_ssc_disable_indoor_channel) {
+		hdd_update_indoor_channel(hdd_ctx, false);
+		sme_update_channel_list(hdd_ctx->mac_handle);
+	}
+
+	if (ucfg_ipa_is_enabled()) {
+		if (ucfg_ipa_wlan_evt(hdd_ctx->pdev,
+				      adapter->dev,
+				      adapter->device_mode,
+				      ap_ctx->broadcast_sta_id,
+				      adapter->session_id,
+				      WLAN_IPA_AP_DISCONNECT,
+				      adapter->dev->dev_addr) !=
+		    QDF_STATUS_SUCCESS)
+			hdd_err("WLAN_AP_DISCONNECT event failed");
+	}
+
+	return qdf_status;
+}
+
+QDF_STATUS hdd_softap_change_sta_state(struct hdd_adapter *adapter,
+				       struct qdf_mac_addr *sta_mac,
+				       enum ol_txrx_peer_state state)
+{
+	uint8_t sta_id = WLAN_MAX_STA_COUNT;
+	QDF_STATUS qdf_status;
+
+	hdd_enter_dev(adapter->dev);
+
+	qdf_status = hdd_softap_get_sta_id(adapter, sta_mac, &sta_id);
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		hdd_err("Failed to find right station");
+		return qdf_status;
+	}
+
+	if (false ==
+	    qdf_is_macaddr_equal(&adapter->sta_info[sta_id].sta_mac,
+				 sta_mac)) {
+		hdd_err("Station %u MAC address not matching", sta_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_status =
+		hdd_change_peer_state(adapter, sta_id, state, false);
+	hdd_info("Station %u changed to state %d", sta_id, state);
+
+	if (QDF_STATUS_SUCCESS == qdf_status) {
+		adapter->sta_info[sta_id].peer_state =
+			OL_TXRX_PEER_STATE_AUTH;
+		p2p_peer_authorized(adapter->vdev, sta_mac->bytes);
+	}
+
+	hdd_exit();
+	return qdf_status;
+}
+
+QDF_STATUS hdd_softap_get_sta_id(struct hdd_adapter *adapter,
+				 struct qdf_mac_addr *sta_mac,
+				 uint8_t *sta_id)
+{
+	uint8_t i;
+
+	for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
+		if (!qdf_mem_cmp
+			(&adapter->sta_info[i].sta_mac, sta_mac,
+			QDF_MAC_ADDR_SIZE) && adapter->sta_info[i].in_use) {
+			*sta_id = i;
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	return QDF_STATUS_E_FAILURE;
+}
diff --git a/core/hdd/src/wlan_hdd_spectralscan.c b/core/hdd/src/wlan_hdd_spectralscan.c
new file mode 100644
index 0000000..b5198f4
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_spectralscan.c
@@ -0,0 +1,482 @@
+/*
+ * Copyright (c) 2017, 2018 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: wlan_hdd_spectral_scan.c
+ *
+ * WLAN Host Device Driver Spectral Scan Implementation
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <net/cfg80211.h>
+#include "wlan_hdd_includes.h"
+#include "cds_api.h"
+#include "ani_global.h"
+#include "wlan_cfg80211_spectral.h"
+#include "wlan_hdd_spectralscan.h"
+#include <wlan_spectral_ucfg_api.h>
+#ifdef CNSS_GENL
+#include <net/cnss_nl.h>
+#endif
+
+/**
+ * __wlan_hdd_cfg80211_spectral_scan_start() - start spectral scan
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function starts spectral scan
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int __wlan_hdd_cfg80211_spectral_scan_start(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter;
+
+	hdd_enter();
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	ret = wlan_cfg80211_spectral_scan_config_and_start(wiphy,
+					hdd_ctx->pdev,
+					data, data_len);
+	hdd_exit();
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_spectral_scan_stop() - stop spectral scan
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function stops spectral scan
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int __wlan_hdd_cfg80211_spectral_scan_stop(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter();
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_cfg80211_spectral_scan_stop(wiphy, hdd_ctx->pdev,
+					       data, data_len);
+	hdd_exit();
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_spectral_scan_get_config() - spectral scan get config
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function to get the spectral scan configuration
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int __wlan_hdd_cfg80211_spectral_scan_get_config(
+						struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter();
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_cfg80211_spectral_scan_get_config(wiphy, hdd_ctx->pdev,
+						     data, data_len);
+	hdd_exit();
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_spectral_scan_get_diag_stats() - get diag stats
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function gets the spectral scan diag stats
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int __wlan_hdd_cfg80211_spectral_scan_get_diag_stats(
+						struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter();
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_cfg80211_spectral_scan_get_diag_stats(wiphy,
+					hdd_ctx->pdev,
+					data, data_len);
+	hdd_exit();
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_spectral_scan_get_cap_info() - get spectral caps
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function gets spectral scan configured capabilities
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int __wlan_hdd_cfg80211_spectral_scan_get_cap_info(
+						struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter();
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_cfg80211_spectral_scan_get_cap(wiphy, hdd_ctx->pdev,
+						  data, data_len);
+	hdd_exit();
+
+	return ret;
+}
+
+/*
+ * __wlan_hdd_cfg80211_spectral_scan_get_status() - get spectral scan
+ * status
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function gets current status of spectral scan
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int __wlan_hdd_cfg80211_spectral_scan_get_status(
+						struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter();
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_cfg80211_spectral_scan_get_status(wiphy, hdd_ctx->pdev,
+						     data, data_len);
+	hdd_exit();
+
+	return ret;
+}
+
+int wlan_hdd_cfg80211_spectral_scan_start(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_spectral_scan_start(
+				wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int wlan_hdd_cfg80211_spectral_scan_stop(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_spectral_scan_stop(
+				wiphy, wdev, data, data_len);
+
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int wlan_hdd_cfg80211_spectral_scam_get_config(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_spectral_scan_get_config(
+				wiphy, wdev, data, data_len);
+
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int wlan_hdd_cfg80211_spectral_scan_get_diag_stats(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_spectral_scan_get_diag_stats(
+				wiphy, wdev, data, data_len);
+
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int wlan_hdd_cfg80211_spectral_scan_get_cap_info(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_spectral_scan_get_cap_info(
+				wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int wlan_hdd_cfg80211_spectral_scan_get_status(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_spectral_scan_get_status(
+				wiphy, wdev, data, data_len);
+
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#if defined(CNSS_GENL) && defined(WLAN_CONV_SPECTRAL_ENABLE)
+static void send_spectral_scan_reg_rsp_msg(struct hdd_context *hdd_ctx)
+{
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	struct spectral_scan_msg *rsp_msg;
+	int err;
+
+	skb = alloc_skb(NLMSG_SPACE(sizeof(struct spectral_scan_msg)),
+				GFP_KERNEL);
+	if (skb == NULL) {
+		hdd_err("Skb allocation failed");
+		return;
+	}
+
+	nlh = (struct nlmsghdr *)skb->data;
+	nlh->nlmsg_pid = 0;
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_seq = 0;
+	nlh->nlmsg_type = WLAN_NL_MSG_SPECTRAL_SCAN;
+
+	rsp_msg = NLMSG_DATA(nlh);
+	rsp_msg->msg_type = SPECTRAL_SCAN_REGISTER_RSP;
+	rsp_msg->pid = hdd_ctx->sscan_pid;
+
+	nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct spectral_scan_msg));
+	skb_put(skb, NLMSG_SPACE(sizeof(struct spectral_scan_msg)));
+
+	hdd_info("sending App Reg Response to process pid %d",
+			hdd_ctx->sscan_pid);
+
+	err = nl_srv_ucast(skb, hdd_ctx->sscan_pid, MSG_DONTWAIT,
+			WLAN_NL_MSG_SPECTRAL_SCAN, CLD80211_MCGRP_OEM_MSGS);
+
+	if (err < 0)
+		hdd_err("SPECTRAL: failed to send to spectral scan reg"
+			" response");
+}
+
+/**
+ * __spectral_scan_msg_handler() - API to handle spectral scan
+ * command
+ * @data: Data received
+ * @data_len: length of the data received
+ * @ctx: Pointer to stored context
+ * @pid: Process ID
+ *
+ * API to handle spectral scan commands from user space
+ *
+ * Return: None
+ */
+static void __spectral_scan_msg_handler(const void *data, int data_len,
+					void *ctx, int pid)
+{
+	struct spectral_scan_msg *ss_msg = NULL;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_ctx = (struct hdd_context *)cds_get_context(QDF_MODULE_ID_HDD);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return;
+
+	if (wlan_cfg80211_nla_parse(tb, CLD80211_ATTR_MAX, data,
+				    data_len, NULL)) {
+		hdd_err("nla parse fails");
+		return;
+	}
+
+	if (!tb[CLD80211_ATTR_DATA]) {
+		hdd_err("attr VENDOR_DATA fails");
+		return;
+	}
+	ss_msg = (struct spectral_scan_msg *)nla_data(tb[CLD80211_ATTR_DATA]);
+
+	if (!ss_msg) {
+		hdd_err("data NULL");
+		return;
+	}
+
+	switch (ss_msg->msg_type) {
+	case SPECTRAL_SCAN_REGISTER_REQ:
+		hdd_ctx->sscan_pid = ss_msg->pid;
+		hdd_debug("spectral scan application registered, pid=%d",
+				 hdd_ctx->sscan_pid);
+		send_spectral_scan_reg_rsp_msg(hdd_ctx);
+		ucfg_spectral_scan_set_ppid(hdd_ctx->pdev,
+					    hdd_ctx->sscan_pid);
+		break;
+	default:
+		hdd_warn("invalid message type %d", ss_msg->msg_type);
+		break;
+	}
+}
+
+static void spectral_scan_msg_handler(const void *data, int data_len,
+					void *ctx, int pid)
+{
+	cds_ssr_protect(__func__);
+	__spectral_scan_msg_handler(data, data_len, ctx, pid);
+	cds_ssr_unprotect(__func__);
+}
+
+void spectral_scan_activate_service(void)
+{
+	register_cld_cmd_cb(WLAN_NL_MSG_SPECTRAL_SCAN,
+			    spectral_scan_msg_handler, NULL);
+}
+
+void spectral_scan_deactivate_service(void)
+{
+	deregister_cld_cmd_cb(WLAN_NL_MSG_SPECTRAL_SCAN);
+}
+#endif
diff --git a/core/hdd/src/wlan_hdd_station_info.c b/core/hdd/src/wlan_hdd_station_info.c
new file mode 100644
index 0000000..7b39cc2
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_station_info.c
@@ -0,0 +1,1228 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_station_info.c
+ *
+ * WLAN station info functions
+ *
+ */
+
+#include <wlan_hdd_includes.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <wlan_cp_stats_mc_ucfg_api.h>
+#include <wlan_hdd_stats.h>
+#include <wlan_hdd_hostapd.h>
+#include <wlan_hdd_station_info.h>
+#include "wlan_mlme_ucfg_api.h"
+
+/*
+ * define short names for the global vendor params
+ * used by __wlan_hdd_cfg80211_get_station_cmd()
+ */
+#define STATION_INVALID \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
+#define STATION_INFO \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
+#define STATION_ASSOC_FAIL_REASON \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
+#define STATION_REMOTE \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
+#define STATION_MAX \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
+
+/* define short names for get station info attributes */
+#define LINK_INFO_STANDARD_NL80211_ATTR \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR
+#define AP_INFO_STANDARD_NL80211_ATTR \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR
+#define INFO_ROAM_COUNT \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT
+#define INFO_AKM \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM
+#define WLAN802_11_MODE \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE
+#define AP_INFO_HS20_INDICATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION
+#define HT_OPERATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION
+#define VHT_OPERATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION
+#define INFO_ASSOC_FAIL_REASON \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON
+#define REMOTE_MAX_PHY_RATE \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_MAX_PHY_RATE
+#define REMOTE_TX_PACKETS \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_PACKETS
+#define REMOTE_TX_BYTES \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_BYTES
+#define REMOTE_RX_PACKETS \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_PACKETS
+#define REMOTE_RX_BYTES \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BYTES
+#define REMOTE_LAST_TX_RATE \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_TX_RATE
+#define REMOTE_LAST_RX_RATE \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_RX_RATE
+#define REMOTE_WMM \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_WMM
+#define REMOTE_SUPPORTED_MODE \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SUPPORTED_MODE
+#define REMOTE_AMPDU \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_AMPDU
+#define REMOTE_TX_STBC \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_STBC
+#define REMOTE_RX_STBC \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_STBC
+#define REMOTE_CH_WIDTH\
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH
+#define REMOTE_SGI_ENABLE\
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SGI_ENABLE
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+	#define REMOTE_PAD\
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD
+#endif
+
+static const struct nla_policy
+hdd_get_station_policy[STATION_MAX + 1] = {
+	[STATION_INFO] = {.type = NLA_FLAG},
+	[STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
+	[STATION_REMOTE] = {.type = NLA_BINARY, .len = QDF_MAC_ADDR_SIZE},
+};
+
+#ifdef QCA_SUPPORT_CP_STATS
+static int hdd_get_sta_congestion(struct hdd_adapter *adapter,
+				  uint32_t *congestion)
+{
+	QDF_STATUS status;
+	struct cca_stats cca_stats;
+
+	status = ucfg_mc_cp_stats_cca_stats_get(adapter->vdev, &cca_stats);
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
+
+	*congestion = cca_stats.congestion;
+	return 0;
+}
+#else
+static int hdd_get_sta_congestion(struct hdd_adapter *adapter,
+				  uint32_t *congestion)
+{
+	struct hdd_station_ctx *hdd_sta_ctx;
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	*congestion = hdd_sta_ctx->conn_info.cca;
+	return 0;
+}
+#endif
+
+/**
+ * hdd_get_station_assoc_fail() - Handle get station assoc fail
+ * @hdd_ctx: HDD context within host driver
+ * @wdev: wireless device
+ *
+ * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
+ * Validate cmd attributes and send the station info to upper layers.
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int hdd_get_station_assoc_fail(struct hdd_context *hdd_ctx,
+				      struct hdd_adapter *adapter)
+{
+	struct sk_buff *skb = NULL;
+	uint32_t nl_buf_len;
+	struct hdd_station_ctx *hdd_sta_ctx;
+	uint32_t congestion;
+
+	nl_buf_len = NLMSG_HDRLEN;
+	nl_buf_len += sizeof(uint32_t);
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
+			hdd_sta_ctx->conn_info.assoc_status_code)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+
+	if (hdd_get_sta_congestion(adapter, &congestion))
+		congestion = 0;
+
+	hdd_info("congestion:%d", congestion);
+	if (nla_put_u32(skb, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
+			congestion)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+
+	return cfg80211_vendor_cmd_reply(skb);
+fail:
+	if (skb)
+		kfree_skb(skb);
+	return -EINVAL;
+}
+
+/**
+ * hdd_map_auth_type() - transform auth type specific to
+ * vendor command
+ * @auth_type: csr auth type
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int hdd_convert_auth_type(uint32_t auth_type)
+{
+	uint32_t ret_val;
+
+	switch (auth_type) {
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
+		break;
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
+		break;
+	case eCSR_AUTH_TYPE_WPA:
+		ret_val = QCA_WLAN_AUTH_TYPE_WPA;
+		break;
+	case eCSR_AUTH_TYPE_WPA_PSK:
+		ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
+		break;
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+		ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
+		break;
+	case eCSR_AUTH_TYPE_WPA_NONE:
+		ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
+		break;
+	case eCSR_AUTH_TYPE_RSN:
+		ret_val = QCA_WLAN_AUTH_TYPE_RSN;
+		break;
+	case eCSR_AUTH_TYPE_RSN_PSK:
+		ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
+		break;
+	case eCSR_AUTH_TYPE_FT_RSN:
+		ret_val = QCA_WLAN_AUTH_TYPE_FT;
+		break;
+	case eCSR_AUTH_TYPE_FT_RSN_PSK:
+		ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
+		break;
+	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
+		ret_val = QCA_WLAN_AUTH_TYPE_WAI;
+		break;
+	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
+		ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
+		break;
+	case eCSR_AUTH_TYPE_CCKM_WPA:
+		ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
+		break;
+	case eCSR_AUTH_TYPE_CCKM_RSN:
+		ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
+		break;
+	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+		ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
+		break;
+	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
+		ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
+		break;
+	case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
+	case eCSR_AUTH_TYPE_FAILED:
+	case eCSR_AUTH_TYPE_NONE:
+	default:
+		ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
+		break;
+	}
+	return ret_val;
+}
+
+/**
+ * hdd_map_dot_11_mode() - transform dot11mode type specific to
+ * vendor command
+ * @dot11mode: dot11mode
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int hdd_convert_dot11mode(uint32_t dot11mode)
+{
+	uint32_t ret_val;
+
+	switch (dot11mode) {
+	case eCSR_CFG_DOT11_MODE_11A:
+		ret_val = QCA_WLAN_802_11_MODE_11A;
+		break;
+	case eCSR_CFG_DOT11_MODE_11B:
+		ret_val = QCA_WLAN_802_11_MODE_11B;
+		break;
+	case eCSR_CFG_DOT11_MODE_11G:
+		ret_val = QCA_WLAN_802_11_MODE_11G;
+		break;
+	case eCSR_CFG_DOT11_MODE_11N:
+		ret_val = QCA_WLAN_802_11_MODE_11N;
+		break;
+	case eCSR_CFG_DOT11_MODE_11AC:
+		ret_val = QCA_WLAN_802_11_MODE_11AC;
+		break;
+	case eCSR_CFG_DOT11_MODE_AUTO:
+	case eCSR_CFG_DOT11_MODE_ABG:
+	default:
+		ret_val = QCA_WLAN_802_11_MODE_INVALID;
+	}
+	return ret_val;
+}
+
+/**
+ * hdd_add_tx_bitrate() - add tx bitrate attribute
+ * @skb: pointer to sk buff
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
+				  struct hdd_station_ctx *hdd_sta_ctx,
+				  int idx)
+{
+	struct nlattr *nla_attr;
+	uint32_t bitrate, bitrate_compat;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr) {
+		hdd_err("nla_nest_start failed");
+		goto fail;
+	}
+
+	/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
+	bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->
+						cache_conn_info.txrate);
+
+	/* report 16-bit bitrate only if we can */
+	bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
+
+	if (bitrate > 0) {
+		if (nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
+			hdd_err("put fail bitrate: %u", bitrate);
+			goto fail;
+		}
+	} else {
+		hdd_err("Invalid bitrate: %u", bitrate);
+	}
+
+	if (bitrate_compat > 0) {
+		if (nla_put_u16(skb, NL80211_RATE_INFO_BITRATE,
+				bitrate_compat)) {
+			hdd_err("put fail bitrate_compat: %u", bitrate_compat);
+			goto fail;
+		}
+	} else {
+		hdd_err("Invalid bitrate_compat: %u", bitrate_compat);
+	}
+
+	if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
+		       hdd_sta_ctx->cache_conn_info.txrate.nss)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_add_sta_info() - add station info attribute
+ * @skb: pointer to sk buff
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t hdd_add_sta_info(struct sk_buff *skb,
+				struct hdd_station_ctx *hdd_sta_ctx,
+				int idx)
+{
+	struct nlattr *nla_attr;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr) {
+		hdd_err("nla_nest_start failed");
+		goto fail;
+	}
+
+	if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
+		       (hdd_sta_ctx->cache_conn_info.signal + 100))) {
+		hdd_err("put fail");
+		goto fail;
+	}
+	if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE)) {
+		hdd_err("hdd_add_tx_bitrate failed");
+		goto fail;
+	}
+
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_add_survey_info() - add survey info attribute
+ * @skb: pointer to sk buff
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t hdd_add_survey_info(struct sk_buff *skb,
+				   struct hdd_station_ctx *hdd_sta_ctx,
+				   int idx)
+{
+	struct nlattr *nla_attr;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr)
+		goto fail;
+	if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
+			hdd_sta_ctx->cache_conn_info.freq) ||
+	    nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
+		       (hdd_sta_ctx->cache_conn_info.noise + 100))) {
+		hdd_err("put fail");
+		goto fail;
+	}
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_add_link_standard_info() - add link info attribute
+ * @skb: pointer to sk buff
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t
+hdd_add_link_standard_info(struct sk_buff *skb,
+			   struct hdd_station_ctx *hdd_sta_ctx, int idx)
+{
+	struct nlattr *nla_attr;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr) {
+		hdd_err("nla_nest_start failed");
+		goto fail;
+	}
+
+	if (nla_put(skb,
+		    NL80211_ATTR_SSID,
+		    hdd_sta_ctx->cache_conn_info.last_ssid.SSID.length,
+		    hdd_sta_ctx->cache_conn_info.last_ssid.SSID.ssId)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+	if (nla_put(skb, NL80211_ATTR_MAC, QDF_MAC_ADDR_SIZE,
+		    hdd_sta_ctx->cache_conn_info.bssId.bytes)) {
+		hdd_err("put bssid failed");
+		goto fail;
+	}
+	if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO)) {
+		hdd_err("hdd_add_survey_info failed");
+		goto fail;
+	}
+
+	if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO)) {
+		hdd_err("hdd_add_sta_info failed");
+		goto fail;
+	}
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_add_ap_standard_info() - add ap info attribute
+ * @skb: pointer to sk buff
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @idx: attribute index
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int32_t
+hdd_add_ap_standard_info(struct sk_buff *skb,
+			 struct hdd_station_ctx *hdd_sta_ctx, int idx)
+{
+	struct nlattr *nla_attr;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr)
+		goto fail;
+	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
+		if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
+			    sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
+			    &hdd_sta_ctx->cache_conn_info.vht_caps)) {
+			hdd_err("put fail");
+			goto fail;
+		}
+	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
+		if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
+			    sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
+			    &hdd_sta_ctx->cache_conn_info.ht_caps)) {
+			hdd_err("put fail");
+			goto fail;
+		}
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_get_station_info() - send BSS information to supplicant
+ * @hdd_ctx: pointer to hdd context
+ * @adapter: pointer to adapter
+ *
+ * Return: 0 if success else error status
+ */
+static int hdd_get_station_info(struct hdd_context *hdd_ctx,
+				struct hdd_adapter *adapter)
+{
+	struct sk_buff *skb = NULL;
+	uint8_t *tmp_hs20 = NULL;
+	uint32_t nl_buf_len;
+	struct hdd_station_ctx *hdd_sta_ctx;
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	nl_buf_len = NLMSG_HDRLEN;
+	nl_buf_len += sizeof(hdd_sta_ctx->
+				cache_conn_info.last_ssid.SSID.length) +
+		      QDF_MAC_ADDR_SIZE +
+		      sizeof(hdd_sta_ctx->cache_conn_info.freq) +
+		      sizeof(hdd_sta_ctx->cache_conn_info.noise) +
+		      sizeof(hdd_sta_ctx->cache_conn_info.signal) +
+		      (sizeof(uint32_t) * 2) +
+		      sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
+		      sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
+		      sizeof(hdd_sta_ctx->cache_conn_info.last_auth_type) +
+		      sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
+	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
+		nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
+	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
+		nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
+	if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
+		tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
+						cache_conn_info.hs20vendor_ie);
+		nl_buf_len += (sizeof(hdd_sta_ctx->
+					cache_conn_info.hs20vendor_ie) - 1);
+	}
+	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
+		nl_buf_len += sizeof(hdd_sta_ctx->
+						cache_conn_info.ht_operation);
+	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
+		nl_buf_len += sizeof(hdd_sta_ctx->
+						cache_conn_info.vht_operation);
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
+				       LINK_INFO_STANDARD_NL80211_ATTR)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+	if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
+				     AP_INFO_STANDARD_NL80211_ATTR)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+	if (nla_put_u32(skb, INFO_ROAM_COUNT,
+			hdd_sta_ctx->cache_conn_info.roam_count) ||
+	    nla_put_u32(skb, INFO_AKM,
+			hdd_convert_auth_type(
+			hdd_sta_ctx->cache_conn_info.last_auth_type)) ||
+	    nla_put_u32(skb, WLAN802_11_MODE,
+			hdd_convert_dot11mode(
+			hdd_sta_ctx->cache_conn_info.dot11Mode))) {
+		hdd_err("put fail");
+		goto fail;
+	}
+	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
+		if (nla_put(skb, HT_OPERATION,
+			    (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
+			    &hdd_sta_ctx->cache_conn_info.ht_operation)) {
+			hdd_err("put fail");
+			goto fail;
+		}
+	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
+		if (nla_put(skb, VHT_OPERATION,
+			    (sizeof(hdd_sta_ctx->
+					cache_conn_info.vht_operation)),
+			    &hdd_sta_ctx->cache_conn_info.vht_operation)) {
+			hdd_err("put fail");
+			goto fail;
+		}
+	if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
+		if (nla_put(skb, AP_INFO_HS20_INDICATION,
+			    (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
+			     - 1),
+			    tmp_hs20 + 1)) {
+			hdd_err("put fail");
+			goto fail;
+		}
+
+	return cfg80211_vendor_cmd_reply(skb);
+fail:
+	if (skb)
+		kfree_skb(skb);
+	return -EINVAL;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+static inline int32_t remote_station_put_u64(struct sk_buff *skb,
+					     int32_t attrtype,
+					     uint64_t value)
+{
+	return nla_put_u64_64bit(skb, attrtype, value, REMOTE_PAD);
+}
+#else
+static inline int32_t remote_station_put_u64(struct sk_buff *skb,
+					     int32_t attrtype,
+					     uint64_t value)
+{
+	return nla_put_u64(skb, attrtype, value);
+}
+#endif
+
+/**
+ * hdd_add_survey_info_sap_get_len - get data length used in
+ * hdd_add_survey_info_sap()
+ *
+ * This function calculates the data length used in hdd_add_survey_info_sap()
+ *
+ * Return: total data length used in hdd_add_survey_info_sap()
+ */
+static uint32_t hdd_add_survey_info_sap_get_len(void)
+{
+	return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
+}
+
+/**
+ * hdd_add_survey_info - add survey info attribute
+ * @skb: pointer to response skb buffer
+ * @stainfo: station information
+ * @idx: attribute type index for nla_next_start()
+ *
+ * This function adds survey info attribute to response skb buffer
+ *
+ * Return : 0 on success and errno on failure
+ */
+static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
+				       struct hdd_station_info *stainfo,
+				       int idx)
+{
+	struct nlattr *nla_attr;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr)
+		goto fail;
+	if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
+			stainfo->freq)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_add_tx_bitrate_sap_get_len - get data length used in
+ * hdd_add_tx_bitrate_sap()
+ *
+ * This function calculates the data length used in hdd_add_tx_bitrate_sap()
+ *
+ * Return: total data length used in hdd_add_tx_bitrate_sap()
+ */
+static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
+{
+	return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
+}
+
+/**
+ * hdd_add_tx_bitrate_sap - add vhs nss info attribute
+ * @skb: pointer to response skb buffer
+ * @stainfo: station information
+ * @idx: attribute type index for nla_next_start()
+ *
+ * This function adds vht nss attribute to response skb buffer
+ *
+ * Return : 0 on success and errno on failure
+ */
+static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
+				  struct hdd_station_info *stainfo,
+				  int idx)
+{
+	struct nlattr *nla_attr;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr)
+		goto fail;
+
+	if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
+		       stainfo->nss)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_add_sta_info_sap_get_len - get data length used in
+ * hdd_add_sta_info_sap()
+ *
+ * This function calculates the data length used in hdd_add_sta_info_sap()
+ *
+ * Return: total data length used in hdd_add_sta_info_sap()
+ */
+static uint32_t hdd_add_sta_info_sap_get_len(void)
+{
+	return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
+		hdd_add_tx_bitrate_sap_get_len());
+}
+
+/**
+ * hdd_add_sta_info_sap - add sta signal info attribute
+ * @skb: pointer to response skb buffer
+ * @stainfo: station information
+ * @idx: attribute type index for nla_next_start()
+ *
+ * This function adds sta signal attribute to response skb buffer
+ *
+ * Return : 0 on success and errno on failure
+ */
+static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
+				    struct hdd_station_info *stainfo, int idx)
+{
+	struct nlattr *nla_attr;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr)
+		goto fail;
+
+	if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, rssi)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+	if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE))
+		goto fail;
+
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_add_link_standard_info_sap_get_len - get data length used in
+ * hdd_add_link_standard_info_sap()
+ *
+ * This function calculates the data length used in
+ * hdd_add_link_standard_info_sap()
+ *
+ * Return: total data length used in hdd_add_link_standard_info_sap()
+ */
+static uint32_t hdd_add_link_standard_info_sap_get_len(void)
+{
+	return ((NLA_HDRLEN) +
+		hdd_add_survey_info_sap_get_len() +
+		hdd_add_sta_info_sap_get_len() +
+		(sizeof(uint32_t) + NLA_HDRLEN));
+}
+
+/**
+ * hdd_add_link_standard_info_sap - add add link info attribut
+ * @skb: pointer to response skb buffer
+ * @stainfo: station information
+ * @idx: attribute type index for nla_next_start()
+ *
+ * This function adds link info attribut to response skb buffer
+ *
+ * Return : 0 on success and errno on failure
+ */
+static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
+					  struct hdd_station_info *stainfo,
+					  int idx)
+{
+	struct nlattr *nla_attr;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr)
+		goto fail;
+	if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
+		goto fail;
+	if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
+		goto fail;
+
+	if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
+		hdd_err("Reason code put fail");
+		goto fail;
+	}
+
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_add_ap_standard_info_sap_get_len - get data length used in
+ * hdd_add_ap_standard_info_sap()
+ * @stainfo: station information
+ *
+ * This function calculates the data length used in
+ * hdd_add_ap_standard_info_sap()
+ *
+ * Return: total data length used in hdd_add_ap_standard_info_sap()
+ */
+static uint32_t hdd_add_ap_standard_info_sap_get_len(
+				struct hdd_station_info *stainfo)
+{
+	uint32_t len;
+
+	len = NLA_HDRLEN;
+	if (stainfo->vht_present)
+		len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
+	if (stainfo->ht_present)
+		len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
+
+	return len;
+}
+
+/**
+ * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
+ * @skb: pointer to response skb buffer
+ * @stainfo: station information
+ * @idx: attribute type index for nla_next_start()
+ *
+ * This function adds HT and VHT info attributes to response skb buffer
+ *
+ * Return : 0 on success and errno on failure
+ */
+static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
+					struct hdd_station_info *stainfo,
+					int idx)
+{
+	struct nlattr *nla_attr;
+
+	nla_attr = nla_nest_start(skb, idx);
+	if (!nla_attr)
+		goto fail;
+
+	if (stainfo->vht_present) {
+		if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
+			    sizeof(stainfo->vht_caps),
+			    &stainfo->vht_caps)) {
+			hdd_err("put fail");
+			goto fail;
+		}
+	}
+	if (stainfo->ht_present) {
+		if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
+			    sizeof(stainfo->ht_caps),
+			    &stainfo->ht_caps)) {
+			hdd_err("put fail");
+			goto fail;
+		}
+	}
+	nla_nest_end(skb, nla_attr);
+	return 0;
+fail:
+	return -EINVAL;
+}
+
+/**
+ * hdd_decode_ch_width - decode channel band width based
+ * @ch_width: encoded enum value holding channel band width
+ *
+ * This function decodes channel band width from the given encoded enum value.
+ *
+ * Returns: decoded channel band width.
+ */
+static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
+{
+	switch (ch_width) {
+	case 0:
+		return 20;
+	case 1:
+		return 40;
+	case 2:
+		return 80;
+	case 3:
+	case 4:
+		return 160;
+	default:
+		hdd_debug("invalid enum: %d", ch_width);
+		return 20;
+	}
+}
+
+/**
+ * hdd_get_cached_station_remote() - get cached(deleted) peer's info
+ * @hdd_ctx: hdd context
+ * @adapter: hostapd interface
+ * @mac_addr: mac address of requested peer
+ *
+ * This function collect and indicate the cached(deleted) peer's info
+ *
+ * Return: 0 on success, otherwise error value
+ */
+
+static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx,
+					 struct hdd_adapter *adapter,
+					 struct qdf_mac_addr mac_addr)
+{
+	struct hdd_station_info *stainfo = hdd_get_stainfo(
+						adapter->cache_sta_info,
+						mac_addr);
+	struct sk_buff *skb = NULL;
+	uint32_t nl_buf_len = NLMSG_HDRLEN;
+	uint8_t channel_width;
+
+	if (!stainfo) {
+		hdd_err("peer " MAC_ADDRESS_STR " not found",
+			MAC_ADDR_ARRAY(mac_addr.bytes));
+		return -EINVAL;
+	}
+
+	nl_buf_len += hdd_add_link_standard_info_sap_get_len() +
+			hdd_add_ap_standard_info_sap_get_len(stainfo) +
+			(sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
+			(sizeof(stainfo->ch_width) + NLA_HDRLEN) +
+			(sizeof(stainfo->tx_rate) + NLA_HDRLEN) +
+			(sizeof(stainfo->rx_rate) + NLA_HDRLEN);
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
+					   LINK_INFO_STANDARD_NL80211_ATTR)) {
+		hdd_err("link standard put fail");
+		goto fail;
+	}
+
+	if (hdd_add_ap_standard_info_sap(skb, stainfo,
+					 AP_INFO_STANDARD_NL80211_ATTR)) {
+		hdd_err("ap standard put fail");
+		goto fail;
+	}
+
+	/* upper layer expects decoded channel BW */
+	channel_width = hdd_decode_ch_width(stainfo->ch_width);
+
+	if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE,
+			hdd_convert_dot11mode(
+			stainfo->mode)) ||
+	    nla_put_u8(skb, REMOTE_CH_WIDTH, channel_width)) {
+		hdd_err("remote ch put fail");
+		goto fail;
+	}
+	if (nla_put_u32(skb, REMOTE_LAST_TX_RATE, stainfo->tx_rate)) {
+		hdd_err("tx rate put fail");
+		goto fail;
+	}
+	if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, stainfo->rx_rate)) {
+		hdd_err("rx rate put fail");
+		goto fail;
+	}
+
+	qdf_mem_zero(stainfo, sizeof(*stainfo));
+
+	return cfg80211_vendor_cmd_reply(skb);
+fail:
+	if (skb)
+		kfree_skb(skb);
+
+	return -EINVAL;
+}
+
+/**
+ * hdd_get_cached_station_remote() - get connected peer's info
+ * @hdd_ctx: hdd context
+ * @adapter: hostapd interface
+ * @mac_addr: mac address of requested peer
+ *
+ * This function collect and indicate the connected peer's info
+ *
+ * Return: 0 on success, otherwise error value
+ */
+static int hdd_get_connected_station_info(struct hdd_context *hdd_ctx,
+					  struct hdd_adapter *adapter,
+					  struct qdf_mac_addr mac_addr,
+					  struct hdd_station_info *stainfo)
+{
+	struct sk_buff *skb = NULL;
+	uint32_t nl_buf_len;
+	struct sir_peer_info_ext peer_info;
+	bool txrx_rate = true;
+	bool value;
+	QDF_STATUS status;
+
+	nl_buf_len = NLMSG_HDRLEN;
+	nl_buf_len += (sizeof(stainfo->max_phy_rate) + NLA_HDRLEN) +
+		(sizeof(stainfo->tx_packets) + NLA_HDRLEN) +
+		(sizeof(stainfo->tx_bytes) + NLA_HDRLEN) +
+		(sizeof(stainfo->rx_packets) + NLA_HDRLEN) +
+		(sizeof(stainfo->rx_bytes) + NLA_HDRLEN) +
+		(sizeof(stainfo->is_qos_enabled) + NLA_HDRLEN) +
+		(sizeof(stainfo->mode) + NLA_HDRLEN);
+
+	status = ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_err("Unable to fetch sap ger peer info");
+	if (!value ||
+	    wlan_hdd_get_peer_info(adapter, mac_addr, &peer_info)) {
+		hdd_err("fail to get tx/rx rate");
+		txrx_rate = false;
+	} else {
+		stainfo->tx_rate = peer_info.tx_rate;
+		stainfo->rx_rate = peer_info.rx_rate;
+		nl_buf_len += (sizeof(stainfo->tx_rate) + NLA_HDRLEN) +
+			(sizeof(stainfo->rx_rate) + NLA_HDRLEN);
+	}
+
+	/* below info is only valid for HT/VHT mode */
+	if (stainfo->mode > SIR_SME_PHY_MODE_LEGACY)
+		nl_buf_len += (sizeof(stainfo->ampdu) + NLA_HDRLEN) +
+			(sizeof(stainfo->tx_stbc) + NLA_HDRLEN) +
+			(sizeof(stainfo->rx_stbc) + NLA_HDRLEN) +
+			(sizeof(stainfo->ch_width) + NLA_HDRLEN) +
+			(sizeof(stainfo->sgi_enable) + NLA_HDRLEN);
+
+	hdd_info("buflen %d hdrlen %d", nl_buf_len, NLMSG_HDRLEN);
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
+						  nl_buf_len);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		goto fail;
+	}
+
+	hdd_info("stainfo");
+	hdd_info("maxrate %x tx_pkts %x tx_bytes %llx",
+		 stainfo->max_phy_rate, stainfo->tx_packets,
+		 stainfo->tx_bytes);
+	hdd_info("rx_pkts %x rx_bytes %llx mode %x",
+		 stainfo->rx_packets, stainfo->rx_bytes,
+		 stainfo->mode);
+	if (stainfo->mode > SIR_SME_PHY_MODE_LEGACY) {
+		hdd_info("ampdu %d tx_stbc %d rx_stbc %d",
+			 stainfo->ampdu, stainfo->tx_stbc,
+			 stainfo->rx_stbc);
+		hdd_info("wmm %d chwidth %d sgi %d",
+			 stainfo->is_qos_enabled,
+			 stainfo->ch_width,
+			 stainfo->sgi_enable);
+	}
+
+	if (nla_put_u32(skb, REMOTE_MAX_PHY_RATE, stainfo->max_phy_rate) ||
+	    nla_put_u32(skb, REMOTE_TX_PACKETS, stainfo->tx_packets) ||
+	    remote_station_put_u64(skb, REMOTE_TX_BYTES, stainfo->tx_bytes) ||
+	    nla_put_u32(skb, REMOTE_RX_PACKETS, stainfo->rx_packets) ||
+	    remote_station_put_u64(skb, REMOTE_RX_BYTES, stainfo->rx_bytes) ||
+	    nla_put_u8(skb, REMOTE_WMM, stainfo->is_qos_enabled) ||
+	    nla_put_u8(skb, REMOTE_SUPPORTED_MODE, stainfo->mode)) {
+		hdd_err("put fail");
+		goto fail;
+	}
+
+	if (txrx_rate) {
+		if (nla_put_u32(skb, REMOTE_LAST_TX_RATE, stainfo->tx_rate) ||
+		    nla_put_u32(skb, REMOTE_LAST_RX_RATE, stainfo->rx_rate)) {
+			hdd_err("put fail");
+			goto fail;
+		} else {
+			hdd_info("tx_rate %x rx_rate %x",
+				 stainfo->tx_rate, stainfo->rx_rate);
+		}
+	}
+
+	if (stainfo->mode > SIR_SME_PHY_MODE_LEGACY) {
+		if (nla_put_u8(skb, REMOTE_AMPDU, stainfo->ampdu) ||
+		    nla_put_u8(skb, REMOTE_TX_STBC, stainfo->tx_stbc) ||
+		    nla_put_u8(skb, REMOTE_RX_STBC, stainfo->rx_stbc) ||
+		    nla_put_u8(skb, REMOTE_CH_WIDTH, stainfo->ch_width) ||
+		    nla_put_u8(skb, REMOTE_SGI_ENABLE, stainfo->sgi_enable)) {
+			hdd_err("put fail");
+			goto fail;
+		}
+	}
+
+	return cfg80211_vendor_cmd_reply(skb);
+
+fail:
+	if (skb)
+		kfree_skb(skb);
+
+	return -EINVAL;
+}
+
+/**
+ * hdd_get_station_remote() - get remote peer's info
+ * @hdd_ctx: hdd context
+ * @adapter: hostapd interface
+ * @mac_addr: mac address of requested peer
+ *
+ * This function collect and indicate the remote peer's info
+ *
+ * Return: 0 on success, otherwise error value
+ */
+static int hdd_get_station_remote(struct hdd_context *hdd_ctx,
+				  struct hdd_adapter *adapter,
+				  struct qdf_mac_addr mac_addr)
+{
+	struct hdd_station_info *stainfo = hdd_get_stainfo(adapter->sta_info,
+							   mac_addr);
+	int status = 0;
+	bool is_associated = false;
+
+	if (!stainfo) {
+		status = hdd_get_cached_station_remote(hdd_ctx, adapter,
+						       mac_addr);
+		return status;
+	}
+
+	is_associated = hdd_is_peer_associated(adapter, &mac_addr);
+	if (!is_associated) {
+		status = hdd_get_cached_station_remote(hdd_ctx, adapter,
+						       mac_addr);
+		return status;
+	}
+
+	status = hdd_get_connected_station_info(hdd_ctx, adapter,
+						mac_addr, stainfo);
+	return status;
+}
+
+/**
+ * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
+ * @wiphy: corestack handler
+ * @wdev: wireless device
+ * @data: data
+ * @data_len: data length
+ *
+ * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
+ * Validate cmd attributes and send the station info to upper layers.
+ *
+ * Return: Success(0) or reason code for failure
+ */
+static int
+__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
+			       struct wireless_dev *wdev,
+			       const void *data,
+			       int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
+	int32_t status;
+
+	hdd_enter_dev(dev);
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		status = -EPERM;
+		goto out;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status != 0)
+		goto out;
+
+	status = wlan_cfg80211_nla_parse(tb,
+					 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
+					 data, data_len,
+					 hdd_get_station_policy);
+	if (status) {
+		hdd_err("Invalid ATTR");
+		goto out;
+	}
+
+	/* Parse and fetch Command Type*/
+	if (tb[STATION_INFO]) {
+		status = hdd_get_station_info(hdd_ctx, adapter);
+	} else if (tb[STATION_ASSOC_FAIL_REASON]) {
+		status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
+	} else if (tb[STATION_REMOTE]) {
+		struct qdf_mac_addr mac_addr;
+
+		if (adapter->device_mode != QDF_SAP_MODE &&
+		    adapter->device_mode != QDF_P2P_GO_MODE) {
+			hdd_err("invalid device_mode:%d", adapter->device_mode);
+			status = -EINVAL;
+			goto out;
+		}
+
+		nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
+			   QDF_MAC_ADDR_SIZE);
+
+		hdd_debug("STATION_REMOTE " MAC_ADDRESS_STR,
+			  MAC_ADDR_ARRAY(mac_addr.bytes));
+
+		status = hdd_get_station_remote(hdd_ctx, adapter, mac_addr);
+	} else {
+		hdd_err("get station info cmd type failed");
+		status = -EINVAL;
+		goto out;
+	}
+	hdd_exit();
+out:
+	return status;
+}
+
+int32_t hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     const void *data,
+				     int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
diff --git a/core/hdd/src/wlan_hdd_station_info.h b/core/hdd/src/wlan_hdd_station_info.h
new file mode 100644
index 0000000..84e2c86
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_station_info.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __WLAN_HDD_STATION_INFO_H
+#define __WLAN_HDD_STATION_INFO_H
+
+/**
+ * DOC: wlan_hdd_station_info_h
+ *
+ * WLAN Host Device Driver STATION info API specification
+ */
+
+#ifdef FEATURE_STATION_INFO
+/**
+ * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
+ * @wiphy: corestack handler
+ * @wdev: wireless device
+ * @data: data
+ * @data_len: data length
+ *
+ * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
+ * Validate cmd attributes and send the station info to upper layers.
+ *
+ * Return: Success(0) or reason code for failure
+ */
+int32_t hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     const void *data,
+				     int data_len);
+
+#define FEATURE_STATION_INFO_VENDOR_COMMANDS				\
+{									\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,			\
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,		\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |				\
+		WIPHY_VENDOR_CMD_NEED_NETDEV |				\
+		WIPHY_VENDOR_CMD_NEED_RUNNING,				\
+	.doit = hdd_cfg80211_get_station_cmd				\
+},
+#else /* FEATURE_STATION_INFO */
+#define FEATURE_STATION_INFO_VENDOR_COMMANDS
+#endif /* FEATURE_STATION_INFO */
+
+#endif /* __WLAN_HDD_STATION_INFO_H */
+
diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c
new file mode 100644
index 0000000..daba6c6
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_stats.c
@@ -0,0 +1,6167 @@
+/*
+ * Copyright (c) 2012-2018 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 : wlan_hdd_stats.c
+ *
+ * WLAN Host Device Driver statistics related implementation
+ *
+ */
+
+#include "wlan_hdd_stats.h"
+#include "sme_api.h"
+#include "cds_sched.h"
+#include "wlan_hdd_trace.h"
+#include "wlan_hdd_lpass.h"
+#include "hif.h"
+#include <qca_vendor.h>
+#include "wma_api.h"
+#include "wlan_hdd_hostapd.h"
+#include "wlan_osif_request_manager.h"
+#include "wlan_hdd_debugfs_llstat.h"
+#include "wlan_reg_services_api.h"
+#include <wlan_cfg80211_mc_cp_stats.h>
+#include "wlan_mlme_ucfg_api.h"
+#include "wlan_mlme_ucfg_api.h"
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
+#define HDD_INFO_SIGNAL                 STATION_INFO_SIGNAL
+#define HDD_INFO_SIGNAL_AVG             STATION_INFO_SIGNAL_AVG
+#define HDD_INFO_TX_PACKETS             STATION_INFO_TX_PACKETS
+#define HDD_INFO_TX_RETRIES             STATION_INFO_TX_RETRIES
+#define HDD_INFO_TX_FAILED              STATION_INFO_TX_FAILED
+#define HDD_INFO_TX_BITRATE             STATION_INFO_TX_BITRATE
+#define HDD_INFO_RX_BITRATE             STATION_INFO_RX_BITRATE
+#define HDD_INFO_TX_BYTES               STATION_INFO_TX_BYTES
+#define HDD_INFO_CHAIN_SIGNAL_AVG       STATION_INFO_CHAIN_SIGNAL_AVG
+#define HDD_INFO_RX_BYTES               STATION_INFO_RX_BYTES
+#define HDD_INFO_RX_PACKETS             STATION_INFO_RX_PACKETS
+#define HDD_INFO_TX_BYTES64             0
+#define HDD_INFO_RX_BYTES64             0
+#define HDD_INFO_INACTIVE_TIME          0
+#define HDD_INFO_CONNECTED_TIME         0
+#else
+#define HDD_INFO_SIGNAL                 BIT(NL80211_STA_INFO_SIGNAL)
+#define HDD_INFO_SIGNAL_AVG             BIT(NL80211_STA_INFO_SIGNAL_AVG)
+#define HDD_INFO_TX_PACKETS             BIT(NL80211_STA_INFO_TX_PACKETS)
+#define HDD_INFO_TX_RETRIES             BIT(NL80211_STA_INFO_TX_RETRIES)
+#define HDD_INFO_TX_FAILED              BIT(NL80211_STA_INFO_TX_FAILED)
+#define HDD_INFO_TX_BITRATE             BIT(NL80211_STA_INFO_TX_BITRATE)
+#define HDD_INFO_RX_BITRATE             BIT(NL80211_STA_INFO_RX_BITRATE)
+#define HDD_INFO_TX_BYTES               BIT(NL80211_STA_INFO_TX_BYTES)
+#define HDD_INFO_CHAIN_SIGNAL_AVG       BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)
+#define HDD_INFO_RX_BYTES               BIT(NL80211_STA_INFO_RX_BYTES)
+#define HDD_INFO_RX_PACKETS             BIT(NL80211_STA_INFO_RX_PACKETS)
+#define HDD_INFO_TX_BYTES64             BIT(NL80211_STA_INFO_TX_BYTES64)
+#define HDD_INFO_RX_BYTES64             BIT(NL80211_STA_INFO_RX_BYTES64)
+#define HDD_INFO_INACTIVE_TIME          BIT(NL80211_STA_INFO_INACTIVE_TIME)
+#define HDD_INFO_CONNECTED_TIME         BIT(NL80211_STA_INFO_CONNECTED_TIME)
+#endif /* kernel version less than 4.0.0 && no_backport */
+
+/* 11B, 11G Rate table include Basic rate and Extended rate
+ * The IDX field is the rate index
+ * The HI field is the rate when RSSI is strong or being ignored
+ *  (in this case we report actual rate)
+ * The MID field is the rate when RSSI is moderate
+ * (in this case we cap 11b rates at 5.5 and 11g rates at 24)
+ * The LO field is the rate when RSSI is low
+ *  (in this case we don't report rates, actual current rate used)
+ */
+static const struct index_data_rate_type supported_data_rate[] = {
+	/* IDX     HI  HM  LM LO (RSSI-based index */
+	{2,   { 10,  10, 10, 0} },
+	{4,   { 20,  20, 10, 0} },
+	{11,  { 55,  20, 10, 0} },
+	{12,  { 60,  55, 20, 0} },
+	{18,  { 90,  55, 20, 0} },
+	{22,  {110,  55, 20, 0} },
+	{24,  {120,  90, 60, 0} },
+	{36,  {180, 120, 60, 0} },
+	{44,  {220, 180, 60, 0} },
+	{48,  {240, 180, 90, 0} },
+	{66,  {330, 180, 90, 0} },
+	{72,  {360, 240, 90, 0} },
+	{96,  {480, 240, 120, 0} },
+	{108, {540, 240, 120, 0} }
+};
+/* MCS Based rate table HT MCS parameters with Nss = 1 */
+static struct index_data_rate_type supported_mcs_rate_nss1[] = {
+/* MCS  L20   L40   S20  S40 */
+	{0, {65, 135, 72, 150} },
+	{1, {130, 270, 144, 300} },
+	{2, {195, 405, 217, 450} },
+	{3, {260, 540, 289, 600} },
+	{4, {390, 810, 433, 900} },
+	{5, {520, 1080, 578, 1200} },
+	{6, {585, 1215, 650, 1350} },
+	{7, {650, 1350, 722, 1500} }
+};
+
+/* HT MCS parameters with Nss = 2 */
+static struct index_data_rate_type supported_mcs_rate_nss2[] = {
+/* MCS  L20    L40   S20   S40 */
+	{0, {130, 270, 144, 300} },
+	{1, {260, 540, 289, 600} },
+	{2, {390, 810, 433, 900} },
+	{3, {520, 1080, 578, 1200} },
+	{4, {780, 1620, 867, 1800} },
+	{5, {1040, 2160, 1156, 2400} },
+	{6, {1170, 2430, 1300, 2700} },
+	{7, {1300, 2700, 1444, 3000} }
+};
+
+/* MCS Based VHT rate table MCS parameters with Nss = 1*/
+static struct index_vht_data_rate_type supported_vht_mcs_rate_nss1[] = {
+/* MCS  L80    S80     L40   S40    L20   S40*/
+	{0, {293, 325}, {135, 150}, {65, 72} },
+	{1, {585, 650}, {270, 300}, {130, 144} },
+	{2, {878, 975}, {405, 450}, {195, 217} },
+	{3, {1170, 1300}, {540, 600}, {260, 289} },
+	{4, {1755, 1950}, {810, 900}, {390, 433} },
+	{5, {2340, 2600}, {1080, 1200}, {520, 578} },
+	{6, {2633, 2925}, {1215, 1350}, {585, 650} },
+	{7, {2925, 3250}, {1350, 1500}, {650, 722} },
+	{8, {3510, 3900}, {1620, 1800}, {780, 867} },
+	{9, {3900, 4333}, {1800, 2000}, {780, 867} }
+};
+
+/*MCS parameters with Nss = 2*/
+static struct index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = {
+/* MCS  L80    S80     L40   S40    L20   S40*/
+	{0, {585, 650}, {270, 300}, {130, 144} },
+	{1, {1170, 1300}, {540, 600}, {260, 289} },
+	{2, {1755, 1950}, {810, 900}, {390, 433} },
+	{3, {2340, 2600}, {1080, 1200}, {520, 578} },
+	{4, {3510, 3900}, {1620, 1800}, {780, 867} },
+	{5, {4680, 5200}, {2160, 2400}, {1040, 1156} },
+	{6, {5265, 5850}, {2430, 2700}, {1170, 1300} },
+	{7, {5850, 6500}, {2700, 3000}, {1300, 1444} },
+	{8, {7020, 7800}, {3240, 3600}, {1560, 1733} },
+	{9, {7800, 8667}, {3600, 4000}, {1560, 1733} }
+};
+
+/*array index ponints to MCS and array value points respective rssi*/
+static int rssi_mcs_tbl[][10] = {
+/*MCS 0   1     2   3    4    5    6    7    8    9*/
+	{-82, -79, -77, -74, -70, -66, -65, -64, -59, -57},     /* 20 */
+	{-79, -76, -74, -71, -67, -63, -62, -61, -56, -54},     /* 40 */
+	{-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} /* 80 */
+};
+
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+
+/**
+ * struct hdd_ll_stats_priv - hdd link layer stats private
+ * @request_id: userspace-assigned link layer stats request id
+ * @request_bitmap: userspace-assigned link layer stats request bitmap
+ */
+struct hdd_ll_stats_priv {
+	uint32_t request_id;
+	uint32_t request_bitmap;
+};
+
+/*
+ * Used to allocate the size of 4096 for the link layer stats.
+ * The size of 4096 is considered assuming that all data per
+ * respective event fit with in the limit.Please take a call
+ * on the limit based on the data requirements on link layer
+ * statistics.
+ */
+#define LL_STATS_EVENT_BUF_SIZE 4096
+
+/**
+ * put_wifi_rate_stat() - put wifi rate stats
+ * @stats: Pointer to stats context
+ * @vendor_event: Pointer to vendor event
+ *
+ * Return: bool
+ */
+static bool put_wifi_rate_stat(tpSirWifiRateStat stats,
+			       struct sk_buff *vendor_event)
+{
+	if (nla_put_u8(vendor_event,
+		       QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
+		       stats->rate.preamble) ||
+	    nla_put_u8(vendor_event,
+		       QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
+		       stats->rate.nss) ||
+	    nla_put_u8(vendor_event,
+		       QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
+		       stats->rate.bw) ||
+	    nla_put_u8(vendor_event,
+		       QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
+		       stats->rate.rateMcsIdx) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
+			stats->rate.bitrate) ||
+	    nla_put_u32(vendor_event,
+			   QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
+			   stats->txMpdu) ||
+	    nla_put_u32(vendor_event,
+			   QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
+			   stats->rxMpdu) ||
+	    nla_put_u32(vendor_event,
+			   QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
+			   stats->mpduLost) ||
+	    nla_put_u32(vendor_event,
+			   QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
+			   stats->retries) ||
+	    nla_put_u32(vendor_event,
+			   QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
+			   stats->retriesShort) ||
+	    nla_put_u32(vendor_event,
+			   QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
+			   stats->retriesLong)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * put_wifi_peer_info() - put wifi peer info
+ * @stats: Pointer to stats context
+ * @vendor_event: Pointer to vendor event
+ *
+ * Return: bool
+ */
+static bool put_wifi_peer_info(tpSirWifiPeerInfo stats,
+			       struct sk_buff *vendor_event)
+{
+	u32 i = 0;
+	tpSirWifiRateStat pRateStats;
+
+	if (nla_put_u32
+		    (vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
+		    wmi_to_sir_peer_type(stats->type)) ||
+	    nla_put(vendor_event,
+		       QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
+		       QDF_MAC_ADDR_SIZE, &stats->peerMacAddress.bytes[0]) ||
+	    nla_put_u32(vendor_event,
+			   QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
+			   stats->capabilities) ||
+	    nla_put_u32(vendor_event,
+			   QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
+			   stats->numRate)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+		goto error;
+	}
+
+	if (stats->numRate) {
+		struct nlattr *rateInfo;
+		struct nlattr *rates;
+
+		rateInfo = nla_nest_start(vendor_event,
+					  QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
+		if (rateInfo == NULL)
+			goto error;
+
+		for (i = 0; i < stats->numRate; i++) {
+			pRateStats = (tpSirWifiRateStat) ((uint8_t *)
+							  stats->rateStats +
+							  (i *
+							   sizeof
+							   (tSirWifiRateStat)));
+			rates = nla_nest_start(vendor_event, i);
+			if (rates == NULL)
+				goto error;
+
+			if (false ==
+			    put_wifi_rate_stat(pRateStats, vendor_event)) {
+				hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+				return false;
+			}
+			nla_nest_end(vendor_event, rates);
+		}
+		nla_nest_end(vendor_event, rateInfo);
+	}
+
+	return true;
+error:
+	return false;
+}
+
+/**
+ * put_wifi_wmm_ac_stat() - put wifi wmm ac stats
+ * @stats: Pointer to stats context
+ * @vendor_event: Pointer to vendor event
+ *
+ * Return: bool
+ */
+static bool put_wifi_wmm_ac_stat(wmi_wmm_ac_stats *stats,
+				 struct sk_buff *vendor_event)
+{
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
+			stats->ac_type) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
+			stats->tx_mpdu) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
+			stats->rx_mpdu) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
+			stats->tx_mcast) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
+			stats->rx_mcast) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
+			stats->rx_ampdu) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
+			stats->tx_ampdu) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
+			stats->mpdu_lost) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
+			stats->retries) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
+			stats->retries_short) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
+			stats->retries_long) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
+			stats->contention_time_min) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
+			stats->contention_time_max) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
+			stats->contention_time_avg) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
+			stats->contention_num_samples)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * put_wifi_interface_info() - put wifi interface info
+ * @stats: Pointer to stats context
+ * @vendor_event: Pointer to vendor event
+ *
+ * Return: bool
+ */
+static bool put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
+				    struct sk_buff *vendor_event)
+{
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE,
+			stats->mode) ||
+	    nla_put(vendor_event,
+		    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
+		    QDF_MAC_ADDR_SIZE, stats->macAddr.bytes) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
+			stats->state) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
+			stats->roaming) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
+			stats->capabilities) ||
+	    nla_put(vendor_event,
+		    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
+		    strlen(stats->ssid), stats->ssid) ||
+	    nla_put(vendor_event,
+		    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
+		    QDF_MAC_ADDR_SIZE, stats->bssid.bytes) ||
+	    nla_put(vendor_event,
+		    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
+		    WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
+	    nla_put(vendor_event,
+		    QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
+		    WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * put_wifi_iface_stats() - put wifi interface stats
+ * @pWifiIfaceStat: Pointer to interface stats context
+ * @num_peer: Number of peers
+ * @vendor_event: Pointer to vendor event
+ *
+ * Return: bool
+ */
+static bool put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
+				 u32 num_peers, struct sk_buff *vendor_event)
+{
+	int i = 0;
+	struct nlattr *wmmInfo;
+	struct nlattr *wmmStats;
+	u64 average_tsf_offset;
+	wmi_iface_link_stats *link_stats = &pWifiIfaceStat->link_stats;
+
+	if (false == put_wifi_interface_info(&pWifiIfaceStat->info,
+					     vendor_event)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+		return false;
+
+	}
+
+	average_tsf_offset =  link_stats->avg_bcn_spread_offset_high;
+	average_tsf_offset =  (average_tsf_offset << 32) |
+		link_stats->avg_bcn_spread_offset_low;
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
+			num_peers) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
+			link_stats->beacon_rx) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
+			link_stats->mgmt_rx) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
+			link_stats->mgmt_action_rx) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
+			link_stats->mgmt_action_tx) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
+			link_stats->rssi_mgmt) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
+			link_stats->rssi_data) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
+			link_stats->rssi_ack) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
+			link_stats->is_leaky_ap) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
+			link_stats->avg_rx_frms_leaked) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
+			link_stats->rx_leak_window) ||
+	    hdd_wlan_nla_put_u64(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
+			average_tsf_offset) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RTS_SUCC_CNT,
+			pWifiIfaceStat->rts_succ_cnt) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RTS_FAIL_CNT,
+			pWifiIfaceStat->rts_fail_cnt) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_SUCC_CNT,
+			pWifiIfaceStat->ppdu_succ_cnt) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_FAIL_CNT,
+			pWifiIfaceStat->ppdu_fail_cnt)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+		return false;
+	}
+
+	wmmInfo = nla_nest_start(vendor_event,
+				 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
+	if (wmmInfo == NULL)
+		return false;
+
+	for (i = 0; i < WIFI_AC_MAX; i++) {
+		wmmStats = nla_nest_start(vendor_event, i);
+		if (wmmStats == NULL)
+			return false;
+
+		if (false ==
+		    put_wifi_wmm_ac_stat(&pWifiIfaceStat->ac_stats[i],
+					 vendor_event)) {
+			hdd_err("put_wifi_wmm_ac_stat Fail");
+			return false;
+		}
+
+		nla_nest_end(vendor_event, wmmStats);
+	}
+	nla_nest_end(vendor_event, wmmInfo);
+	return true;
+}
+
+/**
+ * hdd_map_device_to_ll_iface_mode() - map device to link layer interface mode
+ * @deviceMode: Device mode
+ *
+ * Return: interface mode
+ */
+static tSirWifiInterfaceMode hdd_map_device_to_ll_iface_mode(int deviceMode)
+{
+	switch (deviceMode) {
+	case QDF_STA_MODE:
+		return WIFI_INTERFACE_STA;
+	case QDF_SAP_MODE:
+		return WIFI_INTERFACE_SOFTAP;
+	case QDF_P2P_CLIENT_MODE:
+		return WIFI_INTERFACE_P2P_CLIENT;
+	case QDF_P2P_GO_MODE:
+		return WIFI_INTERFACE_P2P_GO;
+	case QDF_IBSS_MODE:
+		return WIFI_INTERFACE_IBSS;
+	default:
+		/* Return Interface Mode as STA for all the unsupported modes */
+		return WIFI_INTERFACE_STA;
+	}
+}
+
+bool hdd_get_interface_info(struct hdd_adapter *adapter,
+			    tpSirWifiInterfaceInfo pInfo)
+{
+	uint8_t *staMac = NULL;
+	struct hdd_station_ctx *sta_ctx;
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+	/* pre-existing layering violation */
+	tpAniSirGlobal pMac = MAC_CONTEXT(mac_handle);
+
+	pInfo->mode = hdd_map_device_to_ll_iface_mode(adapter->device_mode);
+
+	qdf_copy_macaddr(&pInfo->macAddr, &adapter->mac_addr);
+
+	if (((QDF_STA_MODE == adapter->device_mode) ||
+	     (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
+	     (QDF_P2P_DEVICE_MODE == adapter->device_mode))) {
+		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		if (eConnectionState_NotConnected ==
+		    sta_ctx->conn_info.connState) {
+			pInfo->state = WIFI_DISCONNECTED;
+		}
+		if (eConnectionState_Connecting ==
+		    sta_ctx->conn_info.connState) {
+			hdd_err("Session ID %d, Connection is in progress",
+				adapter->session_id);
+			pInfo->state = WIFI_ASSOCIATING;
+		}
+		if ((eConnectionState_Associated ==
+		     sta_ctx->conn_info.connState)
+		    && (false == sta_ctx->conn_info.uIsAuthenticated)) {
+			staMac =
+				(uint8_t *) &(adapter->mac_addr.
+					      bytes[0]);
+			hdd_err("client " MAC_ADDRESS_STR
+				" is in the middle of WPS/EAPOL exchange.",
+				MAC_ADDR_ARRAY(staMac));
+			pInfo->state = WIFI_AUTHENTICATING;
+		}
+		if (eConnectionState_Associated ==
+		    sta_ctx->conn_info.connState) {
+			pInfo->state = WIFI_ASSOCIATED;
+			qdf_copy_macaddr(&pInfo->bssid,
+					 &sta_ctx->conn_info.bssId);
+			qdf_mem_copy(pInfo->ssid,
+				     sta_ctx->conn_info.SSID.SSID.ssId,
+				     sta_ctx->conn_info.SSID.SSID.length);
+			/*
+			 * NULL Terminate the string
+			 */
+			pInfo->ssid[sta_ctx->conn_info.SSID.SSID.length] = 0;
+		}
+	}
+
+	qdf_mem_copy(pInfo->countryStr,
+		     pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
+
+	qdf_mem_copy(pInfo->apCountryStr,
+		     pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
+
+	return true;
+}
+
+/**
+ * hdd_link_layer_process_peer_stats() - This function is called after
+ * @adapter: Pointer to device adapter
+ * @more_data: More data
+ * @pData: Pointer to stats data
+ *
+ * Receiving Link Layer Peer statistics from FW.This function converts
+ * the firmware data to the NL data and sends the same to the kernel/upper
+ * layers.
+ *
+ * Return: None
+ */
+static void hdd_link_layer_process_peer_stats(struct hdd_adapter *adapter,
+					      u32 more_data,
+					      tpSirWifiPeerStat pData)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	tpSirWifiPeerStat pWifiPeerStat;
+	tpSirWifiPeerInfo pWifiPeerInfo;
+	struct sk_buff *vendor_event;
+	int status, i;
+	struct nlattr *peers;
+	int numRate;
+
+	hdd_enter();
+
+	pWifiPeerStat = pData;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return;
+
+	hdd_debug("LL_STATS_PEER_ALL : numPeers %u, more data = %u",
+		   pWifiPeerStat->numPeers, more_data);
+
+	/*
+	 * Allocate a size of 4096 for the peer stats comprising
+	 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
+	 * sizeof (tSirWifiRateStat).Each field is put with an
+	 * NL attribute.The size of 4096 is considered assuming
+	 * that number of rates shall not exceed beyond 50 with
+	 * the sizeof (tSirWifiRateStat) being 32.
+	 */
+	vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
+				LL_STATS_EVENT_BUF_SIZE);
+
+	if (!vendor_event) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return;
+	}
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_MORE_DATA,
+			more_data) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
+			pWifiPeerStat->numPeers)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8_t *)
+					     pWifiPeerStat->peerInfo);
+
+	if (pWifiPeerStat->numPeers) {
+		struct nlattr *peerInfo;
+
+		peerInfo = nla_nest_start(vendor_event,
+					  QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
+		if (peerInfo == NULL) {
+			hdd_err("nla_nest_start failed");
+			kfree_skb(vendor_event);
+			return;
+		}
+
+		for (i = 1; i <= pWifiPeerStat->numPeers; i++) {
+			peers = nla_nest_start(vendor_event, i);
+			if (peers == NULL) {
+				hdd_err("nla_nest_start failed");
+				kfree_skb(vendor_event);
+				return;
+			}
+
+			numRate = pWifiPeerInfo->numRate;
+
+			if (false ==
+			    put_wifi_peer_info(pWifiPeerInfo, vendor_event)) {
+				hdd_err("put_wifi_peer_info fail");
+				kfree_skb(vendor_event);
+				return;
+			}
+
+			pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8_t *)
+							     pWifiPeerStat->
+							     peerInfo +
+							     (i *
+							      sizeof
+							      (tSirWifiPeerInfo))
+							     +
+							     (numRate *
+							      sizeof
+							      (tSirWifiRateStat)));
+			nla_nest_end(vendor_event, peers);
+		}
+		nla_nest_end(vendor_event, peerInfo);
+	}
+
+	cfg80211_vendor_cmd_reply(vendor_event);
+	hdd_exit();
+}
+
+/**
+ * hdd_link_layer_process_iface_stats() - This function is called after
+ * @adapter: Pointer to device adapter
+ * @pData: Pointer to stats data
+ * @num_peers: Number of peers
+ *
+ * Receiving Link Layer Interface statistics from FW.This function converts
+ * the firmware data to the NL data and sends the same to the kernel/upper
+ * layers.
+ *
+ * Return: None
+ */
+static void hdd_link_layer_process_iface_stats(struct hdd_adapter *adapter,
+					       tpSirWifiIfaceStat pData,
+					       u32 num_peers)
+{
+	tpSirWifiIfaceStat pWifiIfaceStat;
+	struct sk_buff *vendor_event;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int status;
+
+	hdd_enter();
+
+	pWifiIfaceStat = pData;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return;
+
+	/*
+	 * Allocate a size of 4096 for the interface stats comprising
+	 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
+	 * assuming that all these fit with in the limit.Please take
+	 * a call on the limit based on the data requirements on
+	 * interface statistics.
+	 */
+	vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
+				LL_STATS_EVENT_BUF_SIZE);
+
+	if (!vendor_event) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return;
+	}
+
+	hdd_debug("WMI_LINK_STATS_IFACE Data");
+
+	if (false == hdd_get_interface_info(adapter, &pWifiIfaceStat->info)) {
+		hdd_err("hdd_get_interface_info get fail");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	if (false ==
+	    put_wifi_iface_stats(pWifiIfaceStat, num_peers, vendor_event)) {
+		hdd_err("put_wifi_iface_stats fail");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	cfg80211_vendor_cmd_reply(vendor_event);
+	hdd_exit();
+}
+
+/**
+ * hdd_llstats_radio_fill_channels() - radio stats fill channels
+ * @adapter: Pointer to device adapter
+ * @radiostat: Pointer to stats data
+ * @vendor_event: vendor event
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int hdd_llstats_radio_fill_channels(struct hdd_adapter *adapter,
+					   tSirWifiRadioStat *radiostat,
+					   struct sk_buff *vendor_event)
+{
+	tSirWifiChannelStats *channel_stats;
+	struct nlattr *chlist;
+	struct nlattr *chinfo;
+	int i;
+
+	chlist = nla_nest_start(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
+	if (chlist == NULL) {
+		hdd_err("nla_nest_start failed");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < radiostat->numChannels; i++) {
+		channel_stats = (tSirWifiChannelStats *) ((uint8_t *)
+				     radiostat->channels +
+				     (i * sizeof(tSirWifiChannelStats)));
+
+		chinfo = nla_nest_start(vendor_event, i);
+		if (chinfo == NULL) {
+			hdd_err("nla_nest_start failed");
+			return -EINVAL;
+		}
+
+		if (nla_put_u32(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
+				channel_stats->channel.width) ||
+		    nla_put_u32(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
+				channel_stats->channel.centerFreq) ||
+		    nla_put_u32(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
+				channel_stats->channel.centerFreq0) ||
+		    nla_put_u32(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
+				channel_stats->channel.centerFreq1) ||
+		    nla_put_u32(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
+				channel_stats->onTime) ||
+		    nla_put_u32(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
+				channel_stats->ccaBusyTime)) {
+			hdd_err("nla_put failed");
+			return -EINVAL;
+		}
+		nla_nest_end(vendor_event, chinfo);
+	}
+	nla_nest_end(vendor_event, chlist);
+
+	return 0;
+}
+
+/**
+ * hdd_llstats_post_radio_stats() - post radio stats
+ * @adapter: Pointer to device adapter
+ * @more_data: More data
+ * @radiostat: Pointer to stats data
+ * @num_radio: Number of radios
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int hdd_llstats_post_radio_stats(struct hdd_adapter *adapter,
+					u32 more_data,
+					tSirWifiRadioStat *radiostat,
+					u32 num_radio)
+{
+	struct sk_buff *vendor_event;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int ret;
+
+	/*
+	 * Allocate a size of 4096 for the Radio stats comprising
+	 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
+	 * (tSirWifiChannelStats).Each channel data is put with an
+	 * NL attribute.The size of 4096 is considered assuming that
+	 * number of channels shall not exceed beyond  60 with the
+	 * sizeof (tSirWifiChannelStats) being 24 bytes.
+	 */
+
+	vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(
+					hdd_ctx->wiphy,
+					LL_STATS_EVENT_BUF_SIZE);
+
+	if (!vendor_event) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_MORE_DATA,
+			more_data) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
+			num_radio) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
+			radiostat->radio) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
+			radiostat->onTime) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
+			radiostat->txTime) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
+			radiostat->rxTime) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
+			radiostat->onTimeScan) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
+			radiostat->onTimeNbd) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN,
+			radiostat->onTimeGscan) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
+			radiostat->onTimeRoamScan) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
+			radiostat->onTimePnoScan) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
+			radiostat->onTimeHs20) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_TX_LEVELS,
+			radiostat->total_num_tx_power_levels)    ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
+			radiostat->numChannels)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+		goto failure;
+	}
+
+	if (radiostat->total_num_tx_power_levels) {
+		if (nla_put(vendor_event,
+			    QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL,
+			    sizeof(u32) *
+			    radiostat->total_num_tx_power_levels,
+			    radiostat->tx_time_per_power_level)) {
+			hdd_err("nla_put fail");
+			goto failure;
+		}
+	}
+
+	if (radiostat->numChannels) {
+		ret = hdd_llstats_radio_fill_channels(adapter, radiostat,
+						      vendor_event);
+		if (ret)
+			goto failure;
+	}
+
+	cfg80211_vendor_cmd_reply(vendor_event);
+	return 0;
+
+failure:
+	kfree_skb(vendor_event);
+	return -EINVAL;
+}
+
+/**
+ * hdd_link_layer_process_radio_stats() - This function is called after
+ * @adapter: Pointer to device adapter
+ * @more_data: More data
+ * @pData: Pointer to stats data
+ * @num_radios: Number of radios
+ *
+ * Receiving Link Layer Radio statistics from FW.This function converts
+ * the firmware data to the NL data and sends the same to the kernel/upper
+ * layers.
+ *
+ * Return: None
+ */
+static void hdd_link_layer_process_radio_stats(struct hdd_adapter *adapter,
+					       u32 more_data,
+					       tpSirWifiRadioStat pData,
+					       u32 num_radio)
+{
+	int status, i, nr, ret;
+	tSirWifiRadioStat *pWifiRadioStat = pData;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter();
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return;
+
+	hdd_debug("LL_STATS_RADIO: number of radios: %u", num_radio);
+
+	for (i = 0; i < num_radio; i++) {
+		hdd_debug("LL_STATS_RADIO"
+		       " radio: %u onTime: %u txTime: %u rxTime: %u"
+		       " onTimeScan: %u onTimeNbd: %u"
+		       " onTimeGscan: %u onTimeRoamScan: %u"
+		       " onTimePnoScan: %u  onTimeHs20: %u"
+		       " numChannels: %u total_num_tx_pwr_levels: %u"
+		       " on_time_host_scan: %u, on_time_lpi_scan: %u",
+		       pWifiRadioStat->radio, pWifiRadioStat->onTime,
+		       pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
+		       pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
+		       pWifiRadioStat->onTimeGscan,
+		       pWifiRadioStat->onTimeRoamScan,
+		       pWifiRadioStat->onTimePnoScan,
+		       pWifiRadioStat->onTimeHs20, pWifiRadioStat->numChannels,
+		       pWifiRadioStat->total_num_tx_power_levels,
+		       pWifiRadioStat->on_time_host_scan,
+		       pWifiRadioStat->on_time_lpi_scan);
+		pWifiRadioStat++;
+	}
+
+	pWifiRadioStat = pData;
+	for (nr = 0; nr < num_radio; nr++) {
+		ret = hdd_llstats_post_radio_stats(adapter, more_data,
+						   pWifiRadioStat, num_radio);
+		if (ret)
+			return;
+
+		pWifiRadioStat++;
+	}
+
+	hdd_exit();
+}
+
+/**
+ * hdd_ll_process_radio_stats() - Wrapper function for cfg80211/debugfs
+ * @adapter: Pointer to device adapter
+ * @more_data: More data
+ * @data: Pointer to stats data
+ * @num_radios: Number of radios
+ * @resp_id: Response ID from FW
+ *
+ * Receiving Link Layer Radio statistics from FW. This function is a wrapper
+ * function which calls cfg80211/debugfs functions based on the response ID.
+ *
+ * Return: None
+ */
+static void hdd_ll_process_radio_stats(struct hdd_adapter *adapter,
+		uint32_t more_data, void *data, uint32_t num_radio,
+		uint32_t resp_id)
+{
+	if (DEBUGFS_LLSTATS_REQID == resp_id)
+		hdd_debugfs_process_radio_stats(adapter, more_data,
+			(tpSirWifiRadioStat)data, num_radio);
+	else
+		hdd_link_layer_process_radio_stats(adapter, more_data,
+			(tpSirWifiRadioStat)data, num_radio);
+}
+
+/**
+ * hdd_ll_process_iface_stats() - Wrapper function for cfg80211/debugfs
+ * @adapter: Pointer to device adapter
+ * @data: Pointer to stats data
+ * @num_peers: Number of peers
+ * @resp_id: Response ID from FW
+ *
+ * Receiving Link Layer Radio statistics from FW. This function is a wrapper
+ * function which calls cfg80211/debugfs functions based on the response ID.
+ *
+ * Return: None
+ */
+static void hdd_ll_process_iface_stats(struct hdd_adapter *adapter,
+			void *data, uint32_t num_peers, uint32_t resp_id)
+{
+	if (DEBUGFS_LLSTATS_REQID == resp_id)
+		hdd_debugfs_process_iface_stats(adapter,
+				(tpSirWifiIfaceStat) data, num_peers);
+	else
+		hdd_link_layer_process_iface_stats(adapter,
+				(tpSirWifiIfaceStat) data, num_peers);
+}
+
+/**
+ * hdd_ll_process_peer_stats() - Wrapper function for cfg80211/debugfs
+ * @adapter: Pointer to device adapter
+ * @more_data: More data
+ * @data: Pointer to stats data
+ * @resp_id: Response ID from FW
+ *
+ * Receiving Link Layer Radio statistics from FW. This function is a wrapper
+ * function which calls cfg80211/debugfs functions based on the response ID.
+ *
+ * Return: None
+ */
+static void hdd_ll_process_peer_stats(struct hdd_adapter *adapter,
+		uint32_t more_data, void *data, uint32_t resp_id)
+{
+	if (DEBUGFS_LLSTATS_REQID == resp_id)
+		hdd_debugfs_process_peer_stats(adapter, data);
+	else
+		hdd_link_layer_process_peer_stats(adapter, more_data,
+						  (tpSirWifiPeerStat) data);
+}
+
+void wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle,
+						 int indication_type,
+						 tSirLLStatsResults *results,
+						 void *cookie)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	struct hdd_ll_stats_priv *priv;
+	struct hdd_adapter *adapter = NULL;
+	int status;
+	struct osif_request *request;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return;
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx,
+					   results->ifaceId);
+
+	if (!adapter) {
+		hdd_err("vdev_id %d does not exist with host",
+			results->ifaceId);
+		return;
+	}
+
+	hdd_debug("Link Layer Indication Type: %d", indication_type);
+
+	switch (indication_type) {
+	case SIR_HAL_LL_STATS_RESULTS_RSP:
+	{
+		hdd_debug("LL_STATS RESP paramID = 0x%x, ifaceId = %u, respId= %u , moreResultToFollow = %u, num radio = %u result = %pK",
+			results->paramId,
+			results->ifaceId,
+			results->rspId,
+			results->moreResultToFollow,
+			results->num_radio,
+			results->results);
+
+		request = osif_request_get(cookie);
+		if (!request) {
+			hdd_err("Obsolete request");
+			return;
+		}
+
+		priv = osif_request_priv(request);
+
+		/* validate response received from target */
+		if ((priv->request_id != results->rspId) ||
+		    !(priv->request_bitmap & results->paramId)) {
+			hdd_err("Request id %d response id %d request bitmap 0x%x response bitmap 0x%x",
+				priv->request_id, results->rspId,
+				priv->request_bitmap, results->paramId);
+			osif_request_put(request);
+			return;
+		}
+
+		if (results->paramId & WMI_LINK_STATS_RADIO) {
+			hdd_ll_process_radio_stats(adapter,
+				results->moreResultToFollow,
+				results->results,
+				results->num_radio,
+				results->rspId);
+
+			if (!results->moreResultToFollow)
+				priv->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
+
+		} else if (results->paramId &
+				WMI_LINK_STATS_IFACE) {
+			hdd_ll_process_iface_stats(adapter,
+				results->results,
+				results->num_peers,
+				results->rspId);
+
+			/* Firmware doesn't send peerstats event if no peers are
+			 * connected. HDD should not wait for any peerstats in
+			 * this case and return the status to middleware after
+			 * receiving iface stats
+			 */
+			if (!results->num_peers)
+				priv->request_bitmap &=
+					~(WMI_LINK_STATS_ALL_PEER);
+			priv->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
+
+		} else if (results->
+			   paramId & WMI_LINK_STATS_ALL_PEER) {
+			hdd_ll_process_peer_stats(adapter,
+				results->moreResultToFollow,
+				results->results,
+				results->rspId);
+
+			if (!results->moreResultToFollow)
+				priv->request_bitmap &=
+						~(WMI_LINK_STATS_ALL_PEER);
+
+		} else {
+			hdd_err("INVALID LL_STATS_NOTIFY RESPONSE");
+		}
+
+		/* complete response event if all requests are completed */
+		if (!priv->request_bitmap)
+			osif_request_complete(request);
+
+		osif_request_put(request);
+		break;
+	}
+	default:
+		hdd_warn("invalid event type %d", indication_type);
+		break;
+	}
+}
+
+void hdd_lost_link_info_cb(hdd_handle_t hdd_handle,
+			   struct sir_lost_link_info *lost_link_info)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	int status;
+	struct hdd_adapter *adapter;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return;
+
+	if (!lost_link_info) {
+		hdd_err("lost_link_info is NULL");
+		return;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, lost_link_info->vdev_id);
+	if (!adapter) {
+		hdd_err("invalid adapter");
+		return;
+	}
+
+	adapter->rssi_on_disconnect = lost_link_info->rssi;
+	hdd_debug("rssi on disconnect %d", adapter->rssi_on_disconnect);
+}
+
+const struct
+nla_policy
+	qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] = {
+						.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] = {
+						.type = NLA_U32},
+};
+
+/**
+ * __wlan_hdd_cfg80211_ll_stats_set() - set link layer stats
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: int
+ */
+static int
+__wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data,
+				   int data_len)
+{
+	int status;
+	struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
+	tSirLLStatsSetReq LinkLayerStatsSetReq;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return -EINVAL;
+
+	if (hdd_validate_adapter(adapter))
+		return -EINVAL;
+
+	if (adapter->device_mode != QDF_STA_MODE) {
+		hdd_debug("Cannot set LL_STATS for device mode %d",
+			  adapter->device_mode);
+		return -EINVAL;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb_vendor,
+				    QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
+				    (struct nlattr *)data, data_len,
+				    qca_wlan_vendor_ll_set_policy)) {
+		hdd_err("maximum attribute not present");
+		return -EINVAL;
+	}
+
+	if (!tb_vendor
+	    [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]) {
+		hdd_err("MPDU size Not present");
+		return -EINVAL;
+	}
+
+	if (!tb_vendor
+	    [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]) {
+		hdd_err("Stats Gathering Not Present");
+		return -EINVAL;
+	}
+
+	/* Shall take the request Id if the Upper layers pass. 1 For now. */
+	LinkLayerStatsSetReq.reqId = 1;
+
+	LinkLayerStatsSetReq.mpduSizeThreshold =
+		nla_get_u32(tb_vendor
+			    [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
+
+	LinkLayerStatsSetReq.aggressiveStatisticsGathering =
+		nla_get_u32(tb_vendor
+			    [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
+
+	LinkLayerStatsSetReq.staId = adapter->session_id;
+
+	hdd_debug("LL_STATS_SET reqId = %d, staId = %d, mpduSizeThreshold = %d, Statistics Gathering = %d",
+		LinkLayerStatsSetReq.reqId, LinkLayerStatsSetReq.staId,
+		LinkLayerStatsSetReq.mpduSizeThreshold,
+		LinkLayerStatsSetReq.aggressiveStatisticsGathering);
+
+	if (QDF_STATUS_SUCCESS != sme_ll_stats_set_req(hdd_ctx->mac_handle,
+						       &LinkLayerStatsSetReq)) {
+		hdd_err("sme_ll_stats_set_req Failed");
+		return -EINVAL;
+	}
+
+	adapter->is_link_layer_stats_set = true;
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_ll_stats_set() - set ll stats
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 if success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+const struct
+nla_policy
+	qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1] = {
+	/* Unsigned 32bit value provided by the caller issuing the GET stats
+	 * command. When reporting
+	 * the stats results, the driver uses the same value to indicate
+	 * which GET request the results
+	 * correspond to.
+	 */
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = {.type = NLA_U32},
+
+	/* Unsigned 32bit value . bit mask to identify what statistics are
+	 * requested for retrieval
+	 */
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = {.type = NLA_U32}
+};
+
+static int wlan_hdd_send_ll_stats_req(struct hdd_context *hdd_ctx,
+				      tSirLLStatsGetReq *req)
+{
+	int ret;
+	struct hdd_ll_stats_priv *priv;
+	struct osif_request *request;
+	void *cookie;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_LL_STATS,
+	};
+
+	hdd_enter();
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request Allocation Failure");
+		return -ENOMEM;
+	}
+
+	cookie = osif_request_cookie(request);
+
+	priv = osif_request_priv(request);
+
+	priv->request_id = req->reqId;
+	priv->request_bitmap = req->paramIdMask;
+
+	if (QDF_STATUS_SUCCESS !=
+			sme_ll_stats_get_req(hdd_ctx->mac_handle, req,
+					     cookie)) {
+		hdd_err("sme_ll_stats_get_req Failed");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_err("Target response timed out request id %d request bitmap 0x%x",
+			priv->request_id, priv->request_bitmap);
+		ret = -ETIMEDOUT;
+		goto exit;
+	}
+	hdd_exit();
+
+exit:
+	osif_request_put(request);
+	return ret;
+}
+
+int wlan_hdd_ll_stats_get(struct hdd_adapter *adapter, uint32_t req_id,
+			  uint32_t req_mask)
+{
+	int errno;
+	tSirLLStatsGetReq get_req;
+	struct hdd_station_ctx *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_warn("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (hddstactx->hdd_reassoc_scenario) {
+		hdd_err("Roaming in progress, cannot process the request");
+		return -EBUSY;
+	}
+
+	if (!adapter->is_link_layer_stats_set) {
+		hdd_info("LL_STATs not set");
+		return -EINVAL;
+	}
+
+	get_req.reqId = req_id;
+	get_req.paramIdMask = req_mask;
+	get_req.staId = adapter->session_id;
+
+	rtnl_lock();
+	errno = wlan_hdd_send_ll_stats_req(hdd_ctx, &get_req);
+	rtnl_unlock();
+	if (errno)
+		hdd_err("Send LL stats req failed, id:%u, mask:%d, session:%d",
+			req_id, req_mask, adapter->session_id);
+
+	hdd_exit();
+
+	return errno;
+}
+
+/**
+ * __wlan_hdd_cfg80211_ll_stats_get() - get link layer stats
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: int
+ */
+static int
+__wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data,
+				   int data_len)
+{
+	int ret;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
+	tSirLLStatsGetReq LinkLayerStatsGetReq;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_station_ctx *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	/* ENTER() intentionally not used in a frequently invoked API */
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return -EINVAL;
+
+	if (!adapter->is_link_layer_stats_set) {
+		hdd_warn("is_link_layer_stats_set: %d",
+			 adapter->is_link_layer_stats_set);
+		return -EINVAL;
+	}
+
+	if (hddstactx->hdd_reassoc_scenario) {
+		hdd_err("Roaming in progress, cannot process the request");
+		return -EBUSY;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb_vendor,
+				    QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
+				    (struct nlattr *)data, data_len,
+				    qca_wlan_vendor_ll_get_policy)) {
+		hdd_err("max attribute not present");
+		return -EINVAL;
+	}
+
+	if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]) {
+		hdd_err("Request Id Not present");
+		return -EINVAL;
+	}
+
+	if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]) {
+		hdd_err("Req Mask Not present");
+		return -EINVAL;
+	}
+
+	LinkLayerStatsGetReq.reqId =
+		nla_get_u32(tb_vendor
+			    [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
+	LinkLayerStatsGetReq.paramIdMask =
+		nla_get_u32(tb_vendor
+			    [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
+
+	LinkLayerStatsGetReq.staId = adapter->session_id;
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	ret = wlan_hdd_send_ll_stats_req(hdd_ctx, &LinkLayerStatsGetReq);
+	if (0 != ret) {
+		hdd_err("Failed to send LL stats request (id:%u)",
+			LinkLayerStatsGetReq.reqId);
+		return ret;
+	}
+
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_ll_stats_get() - get ll stats
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 if success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
+				struct wireless_dev *wdev,
+				const void *data,
+				int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+const struct
+nla_policy
+	qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8},
+};
+
+/**
+ * __wlan_hdd_cfg80211_ll_stats_clear() - clear link layer stats
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: int
+ */
+static int
+__wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
+				    struct wireless_dev *wdev,
+				    const void *data,
+				    int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
+	tSirLLStatsClearReq LinkLayerStatsClearReq;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	u32 statsClearReqMask;
+	u8 stopReq;
+	int errno;
+	QDF_STATUS status;
+	struct sk_buff *skb;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return -EINVAL;
+
+	if (!adapter->is_link_layer_stats_set) {
+		hdd_warn("is_link_layer_stats_set : %d",
+			  adapter->is_link_layer_stats_set);
+		return -EINVAL;
+	}
+
+	if (wlan_cfg80211_nla_parse(tb_vendor,
+				    QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
+				    (struct nlattr *)data, data_len,
+				    qca_wlan_vendor_ll_clr_policy)) {
+		hdd_err("STATS_CLR_MAX is not present");
+		return -EINVAL;
+	}
+
+	if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
+	    !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]) {
+		hdd_err("Error in LL_STATS CLR CONFIG PARA");
+		return -EINVAL;
+	}
+
+	statsClearReqMask = LinkLayerStatsClearReq.statsClearReqMask =
+				    nla_get_u32(tb_vendor
+						[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
+
+	stopReq = LinkLayerStatsClearReq.stopReq =
+			  nla_get_u8(tb_vendor
+				     [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
+
+	/*
+	 * Shall take the request Id if the Upper layers pass. 1 For now.
+	 */
+	LinkLayerStatsClearReq.reqId = 1;
+
+	LinkLayerStatsClearReq.staId = adapter->session_id;
+
+	hdd_debug("LL_STATS_CLEAR reqId = %d, staId = %d, statsClearReqMask = 0x%X, stopReq = %d",
+		LinkLayerStatsClearReq.reqId,
+		LinkLayerStatsClearReq.staId,
+		LinkLayerStatsClearReq.statsClearReqMask,
+		LinkLayerStatsClearReq.stopReq);
+
+	status = sme_ll_stats_clear_req(hdd_ctx->mac_handle,
+					&LinkLayerStatsClearReq);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("stats clear request failed, %d", status);
+		return -EINVAL;
+	}
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
+						  2 * sizeof(u32) +
+						  2 * NLMSG_HDRLEN);
+	if (!skb) {
+		hdd_err("skb allocation failed");
+		return -ENOMEM;
+	}
+
+	if (nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
+			statsClearReqMask) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
+			stopReq)) {
+		hdd_err("LL_STATS_CLR put fail");
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+
+	/* If the ask is to stop the stats collection
+	 * as part of clear (stopReq = 1), ensure
+	 * that no further requests of get go to the
+	 * firmware by having is_link_layer_stats_set set
+	 * to 0.  However it the stopReq as part of
+	 * the clear request is 0, the request to get
+	 * the statistics are honoured as in this case
+	 * the firmware is just asked to clear the
+	 * statistics.
+	 */
+	if (stopReq == 1)
+		adapter->is_link_layer_stats_set = false;
+
+	hdd_exit();
+
+	return cfg80211_vendor_cmd_reply(skb);
+}
+
+/**
+ * wlan_hdd_cfg80211_ll_stats_clear() - clear ll stats
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 if success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_clear_link_layer_stats() - clear link layer stats
+ * @adapter: pointer to adapter
+ *
+ * Wrapper function to clear link layer stats.
+ * return - void
+ */
+void wlan_hdd_clear_link_layer_stats(struct hdd_adapter *adapter)
+{
+	tSirLLStatsClearReq link_layer_stats_clear_req;
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+
+	link_layer_stats_clear_req.statsClearReqMask = WIFI_STATS_IFACE_AC |
+		WIFI_STATS_IFACE_ALL_PEER;
+	link_layer_stats_clear_req.stopReq = 0;
+	link_layer_stats_clear_req.reqId = 1;
+	link_layer_stats_clear_req.staId = adapter->session_id;
+	sme_ll_stats_clear_req(mac_handle, &link_layer_stats_clear_req);
+}
+
+/**
+ * hdd_populate_per_peer_ps_info() - populate per peer sta's PS info
+ * @wifi_peer_info: peer information
+ * @vendor_event: buffer for vendor event
+ *
+ * Return: 0 success
+ */
+static inline int
+hdd_populate_per_peer_ps_info(tSirWifiPeerInfo *wifi_peer_info,
+			      struct sk_buff *vendor_event)
+{
+	if (!wifi_peer_info) {
+		hdd_err("Invalid pointer to peer info.");
+		return -EINVAL;
+	}
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_STATE,
+			wifi_peer_info->power_saving) ||
+	    nla_put(vendor_event,
+		    QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_MAC_ADDRESS,
+		    QDF_MAC_ADDR_SIZE, &wifi_peer_info->peerMacAddress)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail.");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * hdd_populate_wifi_peer_ps_info() - populate peer sta's power state
+ * @data: stats for peer STA
+ * @vendor_event: buffer for vendor event
+ *
+ * Return: 0 success
+ */
+static int hdd_populate_wifi_peer_ps_info(tSirWifiPeerStat *data,
+					  struct sk_buff *vendor_event)
+{
+	uint32_t peer_num, i;
+	tSirWifiPeerInfo *wifi_peer_info;
+	struct nlattr *peer_info, *peers;
+
+	if (!data) {
+		hdd_err("Invalid pointer to Wifi peer stat.");
+		return -EINVAL;
+	}
+
+	peer_num = data->numPeers;
+	if (peer_num == 0) {
+		hdd_err("Peer number is zero.");
+		return -EINVAL;
+	}
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_NUM,
+			peer_num)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+		return -EINVAL;
+	}
+
+	peer_info = nla_nest_start(vendor_event,
+			       QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_CHG);
+	if (peer_info == NULL) {
+		hdd_err("nla_nest_start failed");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < peer_num; i++) {
+		wifi_peer_info = &data->peerInfo[i];
+		peers = nla_nest_start(vendor_event, i);
+
+		if (peers == NULL) {
+			hdd_err("nla_nest_start failed");
+			return -EINVAL;
+		}
+
+		if (hdd_populate_per_peer_ps_info(wifi_peer_info, vendor_event))
+			return -EINVAL;
+
+		nla_nest_end(vendor_event, peers);
+	}
+	nla_nest_end(vendor_event, peer_info);
+
+	return 0;
+}
+
+/**
+ * hdd_populate_tx_failure_info() - populate TX failure info
+ * @tx_fail: TX failure info
+ * @skb: buffer for vendor event
+ *
+ * Return: 0 Success
+ */
+static inline int
+hdd_populate_tx_failure_info(struct sir_wifi_iface_tx_fail *tx_fail,
+			     struct sk_buff *skb)
+{
+	int status = 0;
+
+	if (tx_fail == NULL || skb == NULL)
+		return -EINVAL;
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TID,
+			tx_fail->tid) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NUM_MSDU,
+			tx_fail->msdu_num) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_STATUS,
+			tx_fail->status)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+		status = -EINVAL;
+	}
+
+	return status;
+}
+
+/**
+ * hdd_populate_wifi_channel_cca_info() - put channel cca info to vendor event
+ * @info: cca info array for all channels
+ * @vendor_event: vendor event buffer
+ *
+ * Return: 0 Success, EINVAL failure
+ */
+static int
+hdd_populate_wifi_channel_cca_info(struct sir_wifi_chan_cca_stats *cca,
+				   struct sk_buff *vendor_event)
+{
+	/* There might be no CCA info for a channel */
+	if (!cca)
+		return 0;
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME,
+			cca->idle_time) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME,
+			cca->tx_time) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME,
+			cca->rx_in_bss_time) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME,
+			cca->rx_out_bss_time) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY,
+			cca->rx_busy_time) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD,
+			cca->rx_in_bad_cond_time) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD,
+			cca->tx_in_bad_cond_time) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL,
+			cca->wlan_not_avail_time) ||
+	    nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_ID,
+			cca->vdev_id)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * hdd_populate_wifi_signal_info - put chain signal info
+ * @info: RF chain signal info
+ * @skb: vendor event buffer
+ *
+ * Return: 0 Success, EINVAL failure
+ */
+static int
+hdd_populate_wifi_signal_info(struct sir_wifi_peer_signal_stats *peer_signal,
+			      struct sk_buff *skb)
+{
+	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,
+			chain_count)) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+		return -EINVAL;
+	}
+
+	att = nla_nest_start(skb,
+			     QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_SIGNAL);
+	if (!att) {
+		hdd_err("nla_nest_start failed");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < chain_count; i++) {
+		chains = nla_nest_start(skb, i);
+
+		if (!chains) {
+			hdd_err("nla_nest_start failed");
+			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]) ||
+		    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;
+		}
+		nla_nest_end(skb, chains);
+	}
+	nla_nest_end(skb, att);
+
+	return 0;
+}
+
+/**
+ * hdd_populate_wifi_wmm_ac_tx_info() - put AC TX info
+ * @info: tx info
+ * @skb: vendor event buffer
+ *
+ * Return: 0 Success, EINVAL failure
+ */
+static int
+hdd_populate_wifi_wmm_ac_tx_info(struct sir_wifi_tx *tx_stats,
+				 struct sk_buff *skb)
+{
+	uint32_t *agg_size, *succ_mcs, *fail_mcs, *delay;
+
+	/* There might be no TX info for a peer */
+	if (!tx_stats)
+		return 0;
+
+	agg_size = tx_stats->mpdu_aggr_size;
+	succ_mcs = tx_stats->success_mcs;
+	fail_mcs = tx_stats->fail_mcs;
+	delay = tx_stats->delay;
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU,
+			tx_stats->msdus) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU,
+			tx_stats->mpdus) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU,
+			tx_stats->ppdus) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES,
+			tx_stats->bytes) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP,
+			tx_stats->drops) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES,
+			tx_stats->drop_bytes) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY,
+			tx_stats->retries) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK,
+			tx_stats->failed) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR_NUM,
+			tx_stats->aggr_len) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS_NUM,
+			tx_stats->success_mcs_len) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS_NUM,
+			tx_stats->fail_mcs_len) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_DELAY_ARRAY_SIZE,
+			tx_stats->delay_len))
+		goto put_attr_fail;
+
+	if (agg_size) {
+		if (nla_put(skb,
+			    QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR,
+			    tx_stats->aggr_len, agg_size))
+			goto put_attr_fail;
+	}
+
+	if (succ_mcs) {
+		if (nla_put(skb,
+			    QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS,
+			    tx_stats->success_mcs_len, succ_mcs))
+			goto put_attr_fail;
+	}
+
+	if (fail_mcs) {
+		if (nla_put(skb,
+			    QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS,
+			    tx_stats->fail_mcs_len, fail_mcs))
+			goto put_attr_fail;
+	}
+
+	if (delay) {
+		if (nla_put(skb,
+			    QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY,
+			    tx_stats->delay_len, delay))
+			goto put_attr_fail;
+	}
+	return 0;
+
+put_attr_fail:
+	hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+	return -EINVAL;
+}
+
+/**
+ * hdd_populate_wifi_wmm_ac_rx_info() - put AC RX info
+ * @info: rx info
+ * @skb: vendor event buffer
+ *
+ * Return: 0 Success, EINVAL failure
+ */
+static int
+hdd_populate_wifi_wmm_ac_rx_info(struct sir_wifi_rx *rx_stats,
+				 struct sk_buff *skb)
+{
+	uint32_t *mcs, *aggr;
+
+	/* There might be no RX info for a peer */
+	if (!rx_stats)
+		return 0;
+
+	aggr = rx_stats->mpdu_aggr;
+	mcs = rx_stats->mcs;
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU,
+			rx_stats->mpdus) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES,
+			rx_stats->bytes) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU,
+			rx_stats->ppdus) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES,
+			rx_stats->ppdu_bytes) ||
+	    nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST,
+			rx_stats->mpdu_lost) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY,
+			rx_stats->mpdu_retry) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP,
+			rx_stats->mpdu_dup) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD,
+			rx_stats->mpdu_discard) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR_NUM,
+			rx_stats->aggr_len) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS_NUM,
+			rx_stats->mcs_len))
+		goto put_attr_fail;
+
+	if (aggr) {
+		if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR,
+			    rx_stats->aggr_len, aggr))
+			goto put_attr_fail;
+	}
+
+	if (mcs) {
+		if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS,
+			    rx_stats->mcs_len, mcs))
+			goto put_attr_fail;
+	}
+
+	return 0;
+
+put_attr_fail:
+	hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+	return -EINVAL;
+}
+
+/**
+ * hdd_populate_wifi_wmm_ac_info() - put WMM AC info
+ * @info: per AC stats
+ * @skb: vendor event buffer
+ *
+ * Return: 0 Success, EINVAL failure
+ */
+static int
+hdd_populate_wifi_wmm_ac_info(struct sir_wifi_ll_ext_wmm_ac_stats *ac_stats,
+			      struct sk_buff *skb)
+{
+	struct nlattr *wmm;
+
+	wmm = nla_nest_start(skb, ac_stats->type);
+	if (!wmm)
+		goto nest_start_fail;
+
+	if (hdd_populate_wifi_wmm_ac_tx_info(ac_stats->tx_stats, skb) ||
+	    hdd_populate_wifi_wmm_ac_rx_info(ac_stats->rx_stats, skb))
+		goto put_attr_fail;
+
+	nla_nest_end(skb, wmm);
+	return 0;
+
+nest_start_fail:
+	hdd_err("nla_nest_start failed");
+	return -EINVAL;
+
+put_attr_fail:
+	hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+	return -EINVAL;
+}
+
+/**
+ * hdd_populate_wifi_ll_ext_peer_info() - put per peer info
+ * @info: peer stats
+ * @skb: vendor event buffer
+ *
+ * Return: 0 Success, EINVAL failure
+ */
+static int
+hdd_populate_wifi_ll_ext_peer_info(struct sir_wifi_ll_ext_peer_stats *peers,
+				   struct sk_buff *skb)
+{
+	uint32_t i;
+	struct nlattr *wmm_ac;
+
+	if (nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ID,
+			peers->peer_id) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_ID,
+			peers->vdev_id) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES,
+			peers->sta_ps_inds) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION,
+			peers->sta_ps_durs) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ,
+			peers->rx_probe_reqs) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT,
+			peers->rx_oth_mgmts) ||
+	    nla_put(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_MAC_ADDRESS,
+		    QDF_MAC_ADDR_SIZE, peers->mac_address) ||
+	    hdd_populate_wifi_signal_info(&peers->peer_signal_stats, skb)) {
+		hdd_err("put peer signal attr failed");
+		return -EINVAL;
+	}
+
+	wmm_ac = nla_nest_start(skb,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_STATUS);
+	if (!wmm_ac) {
+		hdd_err("nla_nest_start failed");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < WLAN_MAX_AC; i++) {
+		if (hdd_populate_wifi_wmm_ac_info(&peers->ac_stats[i], skb)) {
+			hdd_err("put WMM AC attr failed");
+			return -EINVAL;
+		}
+	}
+
+	nla_nest_end(skb, wmm_ac);
+	return 0;
+}
+
+/**
+ * hdd_populate_wifi_ll_ext_stats() - put link layer extension stats
+ * @info: link layer stats
+ * @skb: vendor event buffer
+ *
+ * Return: 0 Success, EINVAL failure
+ */
+static int
+hdd_populate_wifi_ll_ext_stats(struct sir_wifi_ll_ext_stats *stats,
+			       struct sk_buff *skb)
+{
+	uint32_t i;
+	struct nlattr *peer, *peer_info, *channels, *channel_info;
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_EVENT_MODE,
+			stats->trigger_cond_id) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP,
+			stats->cca_chgd_bitmap) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP,
+			stats->sig_chgd_bitmap) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP,
+			stats->tx_chgd_bitmap) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP,
+			stats->rx_chgd_bitmap) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CHANNEL_NUM,
+			stats->channel_num) ||
+	    nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_NUM,
+			stats->peer_num)) {
+		goto put_attr_fail;
+	}
+
+	channels = nla_nest_start(skb,
+				  QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS);
+	if (!channels) {
+		hdd_err("nla_nest_start failed");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < stats->channel_num; i++) {
+		channel_info = nla_nest_start(skb, i);
+		if (!channel_info) {
+			hdd_err("nla_nest_start failed");
+			return -EINVAL;
+		}
+
+		if (hdd_populate_wifi_channel_cca_info(&stats->cca[i], skb))
+			goto put_attr_fail;
+		nla_nest_end(skb, channel_info);
+	}
+	nla_nest_end(skb, channels);
+
+	peer_info = nla_nest_start(skb,
+				   QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER);
+	if (!peer_info) {
+		hdd_err("nla_nest_start failed");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < stats->peer_num; i++) {
+		peer = nla_nest_start(skb, i);
+		if (!peer) {
+			hdd_err("nla_nest_start failed");
+			return -EINVAL;
+		}
+
+		if (hdd_populate_wifi_ll_ext_peer_info(&stats->peer_stats[i],
+						       skb))
+			goto put_attr_fail;
+		nla_nest_end(skb, peer);
+	}
+
+	nla_nest_end(skb, peer_info);
+	return 0;
+
+put_attr_fail:
+	hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_link_layer_stats_ext_callback() - Callback for LL ext
+ * @ctx: HDD context
+ * @rsp: msg from FW
+ *
+ * This function is an extension of
+ * wlan_hdd_cfg80211_link_layer_stats_callback. It converts
+ * monitoring parameters offloaded to NL data and send the same to the
+ * kernel/upper layers.
+ *
+ * Return: None
+ */
+void wlan_hdd_cfg80211_link_layer_stats_ext_callback(hdd_handle_t ctx,
+						     tSirLLStatsResults *rsp)
+{
+	struct hdd_context *hdd_ctx;
+	struct sk_buff *skb = NULL;
+	uint32_t param_id, index;
+	struct hdd_adapter *adapter = NULL;
+	tSirLLStatsResults *linkLayer_stats_results;
+	tSirWifiPeerStat *peer_stats;
+	uint8_t *results;
+	int status;
+
+	hdd_enter();
+
+	if (!rsp) {
+		hdd_err("Invalid result.");
+		return;
+	}
+
+	hdd_ctx = hdd_handle_to_context(ctx);
+	linkLayer_stats_results = rsp;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return;
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx,
+					  linkLayer_stats_results->ifaceId);
+
+	if (!adapter) {
+		hdd_err("vdev_id %d does not exist with host.",
+			linkLayer_stats_results->ifaceId);
+		return;
+	}
+
+	index = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT_INDEX;
+	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+			NULL, LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
+			index, GFP_KERNEL);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_event_alloc failed.");
+		return;
+	}
+
+	results = linkLayer_stats_results->results;
+	param_id = linkLayer_stats_results->paramId;
+	hdd_info("LL_STATS RESP paramID = 0x%x, ifaceId = %u, result = %pK",
+		 linkLayer_stats_results->paramId,
+		 linkLayer_stats_results->ifaceId,
+		 linkLayer_stats_results->results);
+	if (param_id & WMI_LL_STATS_EXT_PS_CHG) {
+		peer_stats = (tSirWifiPeerStat *)results;
+		status = hdd_populate_wifi_peer_ps_info(peer_stats, skb);
+	} else if (param_id & WMI_LL_STATS_EXT_TX_FAIL) {
+		struct sir_wifi_iface_tx_fail *tx_fail;
+
+		tx_fail = (struct sir_wifi_iface_tx_fail *)results;
+		status = hdd_populate_tx_failure_info(tx_fail, skb);
+	} else if (param_id & WMI_LL_STATS_EXT_MAC_COUNTER) {
+		hdd_info("MAC counters stats");
+		status = hdd_populate_wifi_ll_ext_stats(
+				(struct sir_wifi_ll_ext_stats *)
+				rsp->results, skb);
+	} else {
+		hdd_info("Unknown link layer stats");
+		status = -EINVAL;
+	}
+
+	if (status == 0)
+		cfg80211_vendor_event(skb, GFP_KERNEL);
+	else
+		kfree_skb(skb);
+	hdd_exit();
+}
+
+static const struct nla_policy
+qca_wlan_vendor_ll_ext_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_GLOBAL] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_BACK] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR] = {
+		.type = NLA_U32
+	},
+	[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF] = {
+		.type = NLA_U32
+	},
+};
+
+/**
+ * __wlan_hdd_cfg80211_ll_stats_ext_set_param - config monitor parameters
+ * @wiphy: wiphy handle
+ * @wdev: wdev handle
+ * @data: user layer input
+ * @data_len: length of user layer input
+ *
+ * this function is called in ssr protected environment.
+ *
+ * return: 0 success, none zero for failure
+ */
+static int __wlan_hdd_cfg80211_ll_stats_ext_set_param(struct wiphy *wiphy,
+						      struct wireless_dev *wdev,
+						      const void *data,
+						      int data_len)
+{
+	QDF_STATUS status;
+	int errno;
+	uint32_t period;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct sir_ll_ext_stats_threshold thresh = {0,};
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MAX + 1];
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_warn("command not allowed in ftm mode");
+		return -EPERM;
+	}
+
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return -EPERM;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MAX,
+				    (struct nlattr *)data, data_len,
+				    qca_wlan_vendor_ll_ext_policy)) {
+		hdd_err("maximum attribute not present");
+		return -EPERM;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD]) {
+		period = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD]);
+
+		if (period != 0 && period < LL_STATS_MIN_PERIOD)
+			period = LL_STATS_MIN_PERIOD;
+
+		/*
+		 * Only enable/disbale counters.
+		 * Keep the last threshold settings.
+		 */
+		goto set_period;
+	}
+
+	/* global thresh is not enabled */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD]) {
+		thresh.global = false;
+		hdd_warn("global thresh is not set");
+	} else {
+		thresh.global_threshold = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD]);
+		thresh.global = true;
+		hdd_debug("globle thresh is %d", thresh.global_threshold);
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_GLOBAL]) {
+		thresh.global = false;
+		hdd_warn("global thresh is not enabled");
+	} else {
+		thresh.global = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_GLOBAL]);
+		hdd_debug("global is %d", thresh.global);
+	}
+
+	thresh.enable_bitmap = false;
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP]) {
+		thresh.tx_bitmap = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP]);
+		thresh.enable_bitmap = true;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP]) {
+		thresh.rx_bitmap = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP]);
+		thresh.enable_bitmap = true;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP]) {
+		thresh.cca_bitmap = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP]);
+		thresh.enable_bitmap = true;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP]) {
+		thresh.signal_bitmap = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP]);
+		thresh.enable_bitmap = true;
+	}
+
+	if (!thresh.global && !thresh.enable_bitmap) {
+		hdd_warn("threshold will be disabled.");
+		thresh.enable = false;
+
+		/* Just disable threshold */
+		goto set_thresh;
+	} else {
+		thresh.enable = true;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU]) {
+		thresh.tx.msdu = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU]) {
+		thresh.tx.mpdu = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU]) {
+		thresh.tx.ppdu = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES]) {
+		thresh.tx.bytes = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP]) {
+		thresh.tx.msdu_drop = nla_get_u32(
+			tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES]) {
+		thresh.tx.byte_drop = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY]) {
+		thresh.tx.mpdu_retry = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK]) {
+		thresh.tx.mpdu_fail = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_BACK]) {
+		thresh.tx.ppdu_fail = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_BACK]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR]) {
+		thresh.tx.aggregation = nla_get_u32(tb[
+				  QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS]) {
+		thresh.tx.succ_mcs = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS]) {
+		thresh.tx.fail_mcs = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY]) {
+		thresh.tx.delay = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU]) {
+		thresh.rx.mpdu = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES]) {
+		thresh.rx.bytes = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU]) {
+		thresh.rx.ppdu = nla_get_u32(tb[
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES]) {
+		thresh.rx.ppdu_bytes = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST]) {
+		thresh.rx.mpdu_lost = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY]) {
+		thresh.rx.mpdu_retry = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP]) {
+		thresh.rx.mpdu_dup = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD]) {
+		thresh.rx.mpdu_discard = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR]) {
+		thresh.rx.aggregation = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS]) {
+		thresh.rx.mcs = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES]) {
+		thresh.rx.ps_inds = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION]) {
+		thresh.rx.ps_durs = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ]) {
+		thresh.rx.probe_reqs = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT]) {
+		thresh.rx.other_mgmt = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME]) {
+		thresh.cca.idle_time = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME]) {
+		thresh.cca.tx_time = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME]) {
+		thresh.cca.rx_in_bss_time = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME]) {
+		thresh.cca.rx_out_bss_time = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY]) {
+		thresh.cca.rx_busy_time = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD]) {
+		thresh.cca.rx_in_bad_cond_time = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD]) {
+		thresh.cca.tx_in_bad_cond_time = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL]) {
+		thresh.cca.wlan_not_avail_time = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR]) {
+		thresh.signal.snr = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF]) {
+		thresh.signal.nf = nla_get_u32(tb[
+			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF]);
+	}
+
+set_thresh:
+	hdd_info("send thresh settings to target");
+	status = sme_ll_stats_set_thresh(hdd_ctx->mac_handle, &thresh);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("sme_ll_stats_set_thresh failed.");
+		return -EINVAL;
+	}
+	return 0;
+
+set_period:
+	hdd_info("send period to target");
+	errno = wma_cli_set_command(adapter->session_id,
+				    WMI_PDEV_PARAM_STATS_OBSERVATION_PERIOD,
+				    period, PDEV_CMD);
+	if (errno) {
+		hdd_err("wma_cli_set_command set_period failed.");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_ll_stats_ext_set_param - config monitor parameters
+ * @wiphy: wiphy handle
+ * @wdev: wdev handle
+ * @data: user layer input
+ * @data_len: length of user layer input
+ *
+ * return: 0 success, einval failure
+ */
+int wlan_hdd_cfg80211_ll_stats_ext_set_param(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data,
+					     int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_ll_stats_ext_set_param(wiphy, wdev,
+							 data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+#ifdef WLAN_FEATURE_STATS_EXT
+/**
+ * __wlan_hdd_cfg80211_stats_ext_request() - ext stats request
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: int
+ */
+static int __wlan_hdd_cfg80211_stats_ext_request(struct wiphy *wiphy,
+						 struct wireless_dev *wdev,
+						 const void *data,
+						 int data_len)
+{
+	tStatsExtRequestReq stats_ext_req;
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int ret_val;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+
+	hdd_enter_dev(dev);
+
+	ret_val = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_val)
+		return ret_val;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	stats_ext_req.request_data_len = data_len;
+	stats_ext_req.request_data = (void *)data;
+
+	status = sme_stats_ext_request(adapter->session_id, &stats_ext_req);
+
+	if (QDF_STATUS_SUCCESS != status)
+		ret_val = -EINVAL;
+
+	return ret_val;
+}
+
+/**
+ * wlan_hdd_cfg80211_stats_ext_request() - ext stats request
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: int
+ */
+int wlan_hdd_cfg80211_stats_ext_request(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_stats_ext_request(wiphy, wdev,
+						    data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+void wlan_hdd_cfg80211_stats_ext_callback(hdd_handle_t hdd_handle,
+					  struct stats_ext_event *data)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	struct sk_buff *vendor_event;
+	int status;
+	int ret_val;
+	struct hdd_adapter *adapter;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return;
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, data->vdev_id);
+	if (!adapter) {
+		hdd_err("vdev_id %d does not exist with host", data->vdev_id);
+		return;
+	}
+
+	vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+						   NULL,
+						   data->event_data_len +
+						   sizeof(uint32_t) +
+						   NLMSG_HDRLEN + NLMSG_HDRLEN,
+						   QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX,
+						   GFP_KERNEL);
+
+	if (!vendor_event) {
+		hdd_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	ret_val = nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_IFINDEX,
+			      adapter->dev->ifindex);
+	if (ret_val) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR_IFINDEX put fail");
+		kfree_skb(vendor_event);
+
+		return;
+	}
+
+	ret_val = nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_STATS_EXT,
+			  data->event_data_len, data->event_data);
+
+	if (ret_val) {
+		hdd_err("QCA_WLAN_VENDOR_ATTR_STATS_EXT put fail");
+		kfree_skb(vendor_event);
+
+		return;
+	}
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+
+}
+
+void
+wlan_hdd_cfg80211_stats_ext2_callback(hdd_handle_t hdd_handle,
+				      struct sir_sme_rx_aggr_hole_ind *pmsg)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	int status;
+	uint32_t data_size, hole_info_size;
+	struct sk_buff *vendor_event;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return;
+
+	if (NULL == pmsg) {
+		hdd_err("msg received here is null");
+		return;
+	}
+
+	hole_info_size = (pmsg->hole_cnt)*sizeof(pmsg->hole_info_array[0]);
+	data_size = sizeof(struct sir_sme_rx_aggr_hole_ind) + hole_info_size;
+
+	vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+			NULL,
+			data_size + NLMSG_HDRLEN + NLMSG_HDRLEN,
+			QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX,
+			GFP_KERNEL);
+
+	if (!vendor_event) {
+		hdd_err("vendor_event_alloc failed for STATS_EXT2");
+		return;
+	}
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_NUM,
+			pmsg->hole_cnt)) {
+		hdd_err("%s put fail",
+			"QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_NUM");
+		kfree_skb(vendor_event);
+		return;
+	}
+	if (nla_put(vendor_event,
+		    QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_INFO,
+		    hole_info_size,
+		    (void *)(pmsg->hole_info_array))) {
+		hdd_err("%s put fail",
+			"QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_INFO");
+		kfree_skb(vendor_event);
+		return;
+	}
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+}
+
+#endif /* End of WLAN_FEATURE_STATS_EXT */
+
+#ifdef LINKSPEED_DEBUG_ENABLED
+#define linkspeed_dbg(format, args...) pr_info(format, ## args)
+#else
+#define linkspeed_dbg(format, args...)
+#endif /* LINKSPEED_DEBUG_ENABLED */
+
+/**
+ * wlan_hdd_fill_summary_stats() - populate station_info summary stats
+ * @stats: summary stats to use as a source
+ * @info: kernel station_info struct to use as a destination
+ *
+ * Return: None
+ */
+static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
+					struct station_info *info)
+{
+	int i;
+
+	info->rx_packets = stats->rx_frm_cnt;
+	info->tx_packets = 0;
+	info->tx_retries = 0;
+	info->tx_failed = 0;
+
+	for (i = 0; i < WIFI_MAX_AC; ++i) {
+		info->tx_packets += stats->tx_frm_cnt[i];
+		info->tx_retries += stats->multiple_retry_cnt[i];
+		info->tx_failed += stats->fail_cnt[i];
+	}
+
+	info->filled |= HDD_INFO_TX_PACKETS |
+			HDD_INFO_TX_RETRIES |
+			HDD_INFO_TX_FAILED  |
+			HDD_INFO_RX_PACKETS;
+}
+
+/**
+ * wlan_hdd_get_sap_stats() - get aggregate SAP stats
+ * @adapter: sap adapter to get stats for
+ * @info: kernel station_info struct to populate
+ *
+ * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
+ * support "station dump" and "station get" for SAP vdevs, even though they
+ * aren't technically stations.
+ *
+ * Return: errno
+ */
+static int
+wlan_hdd_get_sap_stats(struct hdd_adapter *adapter, struct station_info *info)
+{
+	int ret;
+
+	ret = wlan_hdd_get_station_stats(adapter);
+	if (ret) {
+		hdd_err("Failed to get SAP stats; status:%d", ret);
+		return ret;
+	}
+
+	wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
+
+	return 0;
+}
+
+/**
+ * hdd_get_max_rate_legacy() - get max rate for legacy mode
+ * @stainfo: stainfo pointer
+ * @rssidx: rssi index
+ *
+ * This function will get max rate for legacy mode
+ *
+ * Return: max rate on success, otherwise 0
+ */
+static uint32_t hdd_get_max_rate_legacy(struct hdd_station_info *stainfo,
+					uint8_t rssidx)
+{
+	uint32_t maxrate = 0;
+	/*Minimum max rate, 6Mbps*/
+	int maxidx = 12;
+	int i;
+
+	/* check supported rates */
+	if (stainfo->max_supp_idx != 0xff &&
+	    maxidx < stainfo->max_supp_idx)
+		maxidx = stainfo->max_supp_idx;
+
+	/* check extended rates */
+	if (stainfo->max_ext_idx != 0xff &&
+	    maxidx < stainfo->max_ext_idx)
+		maxidx = stainfo->max_ext_idx;
+
+	for (i = 0; QDF_ARRAY_SIZE(supported_data_rate); i++) {
+		if (supported_data_rate[i].beacon_rate_index == maxidx)
+			maxrate =
+				supported_data_rate[i].supported_rate[rssidx];
+	}
+
+	hdd_debug("maxrate %d", maxrate);
+
+	return maxrate;
+}
+
+/**
+ * hdd_get_max_rate_ht() - get max rate for ht mode
+ * @stainfo: stainfo pointer
+ * @stats: fw txrx status pointer
+ * @rate_flags: rate flags
+ * @nss: number of streams
+ * @maxrate: returned max rate buffer pointer
+ * @max_mcs_idx: max mcs idx
+ * @report_max: report max rate or actual rate
+ *
+ * This function will get max rate for ht mode
+ *
+ * Return: None
+ */
+static void hdd_get_max_rate_ht(struct hdd_station_info *stainfo,
+				struct hdd_fw_txrx_stats *stats,
+				uint32_t rate_flags,
+				uint8_t nss,
+				uint32_t *maxrate,
+				uint8_t *max_mcs_idx,
+				bool report_max)
+{
+	struct index_data_rate_type *supported_mcs_rate;
+	uint32_t tmprate;
+	uint8_t flag = 0, mcsidx;
+	int8_t rssi = stats->rssi;
+	int mode;
+	int i;
+
+	if (rate_flags & TX_RATE_HT40)
+		mode = 1;
+	else
+		mode = 0;
+
+	if (rate_flags & TX_RATE_HT40)
+		flag |= 1;
+	if (rate_flags & TX_RATE_SGI)
+		flag |= 2;
+
+	supported_mcs_rate = (struct index_data_rate_type *)
+		((nss == 1) ? &supported_mcs_rate_nss1 :
+		 &supported_mcs_rate_nss2);
+
+	if (stainfo->max_mcs_idx == 0xff) {
+		hdd_err("invalid max_mcs_idx");
+		/* report real mcs idx */
+		mcsidx = stats->tx_rate.mcs;
+	} else {
+		mcsidx = stainfo->max_mcs_idx;
+	}
+
+	if (!report_max) {
+		for (i = 0; i < mcsidx; i++) {
+			if (rssi <= rssi_mcs_tbl[mode][i]) {
+				mcsidx = i;
+				break;
+			}
+		}
+		if (mcsidx < stats->tx_rate.mcs)
+			mcsidx = stats->tx_rate.mcs;
+	}
+
+	tmprate = supported_mcs_rate[mcsidx].supported_rate[flag];
+
+	hdd_debug("tmprate %d mcsidx %d", tmprate, mcsidx);
+
+	*maxrate = tmprate;
+	*max_mcs_idx = mcsidx;
+}
+
+/**
+ * hdd_get_max_rate_vht() - get max rate for vht mode
+ * @stainfo: stainfo pointer
+ * @stats: fw txrx status pointer
+ * @rate_flags: rate flags
+ * @nss: number of streams
+ * @maxrate: returned max rate buffer pointer
+ * @max_mcs_idx: max mcs idx
+ * @report_max: report max rate or actual rate
+ *
+ * This function will get max rate for vht mode
+ *
+ * Return: None
+ */
+static void hdd_get_max_rate_vht(struct hdd_station_info *stainfo,
+				 struct hdd_fw_txrx_stats *stats,
+				 uint32_t rate_flags,
+				 uint8_t nss,
+				 uint32_t *maxrate,
+				 uint8_t *max_mcs_idx,
+				 bool report_max)
+{
+	struct index_vht_data_rate_type *supported_vht_mcs_rate;
+	uint32_t tmprate = 0;
+	uint32_t vht_max_mcs;
+	uint8_t flag = 0, mcsidx = INVALID_MCS_IDX;
+	int8_t rssi = stats->rssi;
+	int mode;
+	int i;
+
+	supported_vht_mcs_rate = (struct index_vht_data_rate_type *)
+		((nss == 1) ?
+		 &supported_vht_mcs_rate_nss1 :
+		 &supported_vht_mcs_rate_nss2);
+
+	if (rate_flags & TX_RATE_VHT80)
+		mode = 2;
+	else if (rate_flags & TX_RATE_VHT40)
+		mode = 1;
+	else
+		mode = 0;
+
+	if (rate_flags &
+	    (TX_RATE_VHT20 | TX_RATE_VHT40 | TX_RATE_VHT80)) {
+		vht_max_mcs =
+			(enum data_rate_11ac_max_mcs)
+			(stainfo->tx_mcs_map & DATA_RATE_11AC_MCS_MASK);
+		if (rate_flags & TX_RATE_SGI)
+			flag |= 1;
+
+		if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_7) {
+			mcsidx = 7;
+		} else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_8) {
+			mcsidx = 8;
+		} else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_9) {
+			/*
+			 * 'IEEE_P802.11ac_2013.pdf' page 325, 326
+			 * - MCS9 is valid for VHT20 when Nss = 3 or Nss = 6
+			 * - MCS9 is not valid for VHT20 when Nss = 1,2,4,5,7,8
+			 */
+			if ((rate_flags & TX_RATE_VHT20) &&
+			    (nss != 3 && nss != 6))
+				mcsidx = 8;
+			else
+				mcsidx = 9;
+		} else {
+			hdd_err("invalid vht_max_mcs");
+			/* report real mcs idx */
+			mcsidx = stats->tx_rate.mcs;
+		}
+
+		if (!report_max) {
+			for (i = 0; i <= mcsidx; i++) {
+				if (rssi <= rssi_mcs_tbl[mode][i]) {
+					mcsidx = i;
+					break;
+				}
+			}
+			if (mcsidx < stats->tx_rate.mcs)
+				mcsidx = stats->tx_rate.mcs;
+		}
+
+		if (rate_flags & TX_RATE_VHT80)
+			tmprate =
+		    supported_vht_mcs_rate[mcsidx].supported_VHT80_rate[flag];
+		else if (rate_flags & TX_RATE_VHT40)
+			tmprate =
+		    supported_vht_mcs_rate[mcsidx].supported_VHT40_rate[flag];
+		else if (rate_flags & TX_RATE_VHT20)
+			tmprate =
+		    supported_vht_mcs_rate[mcsidx].supported_VHT20_rate[flag];
+	}
+
+	hdd_debug("tmprate %d mcsidx %d", tmprate, mcsidx);
+
+	*maxrate = tmprate;
+	*max_mcs_idx = mcsidx;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+/**
+ * hdd_fill_bw_mcs() - fill ch width and mcs flags
+ * @stainfo: stainfo pointer
+ * @rate_flags: HDD rate flags
+ * @mcsidx: mcs index
+ * @nss: number of streams
+ * @vht: vht mode or not
+ *
+ * This function will fill ch width and mcs flags
+ *
+ * Return: None
+ */
+static void hdd_fill_bw_mcs(struct station_info *sinfo,
+			    uint8_t rate_flags,
+			    uint8_t mcsidx,
+			    uint8_t nss,
+			    bool vht)
+{
+	if (vht) {
+		sinfo->txrate.nss = nss;
+		sinfo->txrate.mcs = mcsidx;
+		sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
+		if (rate_flags & TX_RATE_VHT80)
+			sinfo->txrate.bw = RATE_INFO_BW_80;
+		else if (rate_flags & TX_RATE_VHT40)
+			sinfo->txrate.bw = RATE_INFO_BW_40;
+		else if (rate_flags & TX_RATE_VHT20)
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
+	} else {
+		sinfo->txrate.mcs = (nss - 1) << 3;
+		sinfo->txrate.mcs |= mcsidx;
+		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+		if (rate_flags & TX_RATE_HT40)
+			sinfo->txrate.bw = RATE_INFO_BW_40;
+	}
+}
+#else
+/**
+ * hdd_fill_bw_mcs() - fill ch width and mcs flags
+ * @stainfo: stainfo pointer
+ * @rate_flags: HDD rate flags
+ * @mcsidx: mcs index
+ * @nss: number of streams
+ * @vht: vht mode or not
+ *
+ * This function will fill ch width and mcs flags
+ *
+ * Return: None
+ */
+static void hdd_fill_bw_mcs(struct station_info *sinfo,
+			    uint8_t rate_flags,
+			    uint8_t mcsidx,
+			    uint8_t nss,
+			    bool vht)
+{
+	if (vht) {
+		sinfo->txrate.nss = nss;
+		sinfo->txrate.mcs = mcsidx;
+		sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
+		if (rate_flags & TX_RATE_VHT80)
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
+		else if (rate_flags & TX_RATE_VHT40)
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+		else if (rate_flags & TX_RATE_VHT20)
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
+	} else {
+		sinfo->txrate.mcs = (nss - 1) << 3;
+		sinfo->txrate.mcs |= mcsidx;
+		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+		if (rate_flags & TX_RATE_HT40)
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+	}
+}
+#endif
+
+/**
+ * hdd_fill_bw_mcs_vht() - fill ch width and mcs flags for VHT mode
+ * @stainfo: stainfo pointer
+ * @rate_flags: HDD rate flags
+ * @mcsidx: mcs index
+ * @nss: number of streams
+ *
+ * This function will fill ch width and mcs flags for VHT mode
+ *
+ * Return: None
+ */
+static void hdd_fill_bw_mcs_vht(struct station_info *sinfo,
+				uint8_t rate_flags,
+				uint8_t mcsidx,
+				uint8_t nss)
+{
+	hdd_fill_bw_mcs(sinfo, rate_flags, mcsidx, nss, true);
+}
+
+/**
+ * hdd_fill_sinfo_rate_info() - fill rate info of sinfo struct
+ * @sinfo: station_info struct pointer
+ * @rate_flags: HDD rate flags
+ * @mcsidx: mcs index
+ * @nss: number of streams
+ * @maxrate: data rate (kbps)
+ *
+ * This function will fill rate info of sinfo struct
+ *
+ * Return: None
+ */
+static void hdd_fill_sinfo_rate_info(struct station_info *sinfo,
+				     uint32_t rate_flags,
+				     uint8_t mcsidx,
+				     uint8_t nss,
+				     uint32_t maxrate)
+{
+	if (rate_flags & TX_RATE_LEGACY) {
+		/* provide to the UI in units of 100kbps */
+		sinfo->txrate.legacy = maxrate;
+	} else {
+		/* must be MCS */
+		if (rate_flags &
+				(TX_RATE_VHT80 |
+				 TX_RATE_VHT40 |
+				 TX_RATE_VHT20))
+			hdd_fill_bw_mcs_vht(sinfo, rate_flags, mcsidx, nss);
+
+		if (rate_flags & (TX_RATE_HT20 | TX_RATE_HT40))
+			hdd_fill_bw_mcs(sinfo, rate_flags, mcsidx, nss, false);
+
+		if (rate_flags & TX_RATE_SGI) {
+			if (!(sinfo->txrate.flags & RATE_INFO_FLAGS_VHT_MCS))
+				sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+		}
+	}
+
+	hdd_info("flag %x mcs %d legacy %d nss %d",
+		 sinfo->txrate.flags,
+		 sinfo->txrate.mcs,
+		 sinfo->txrate.legacy,
+		 sinfo->txrate.nss);
+}
+
+/**
+ * hdd_fill_station_info_flags() - fill flags of sinfo struct
+ * @sinfo: station_info struct pointer
+ *
+ * This function will fill flags of sinfo struct
+ *
+ * Return: None
+ */
+static void hdd_fill_station_info_flags(struct station_info *sinfo)
+{
+	sinfo->filled |= HDD_INFO_SIGNAL        |
+			 HDD_INFO_TX_BYTES      |
+			 HDD_INFO_TX_BYTES64    |
+			 HDD_INFO_TX_BITRATE    |
+			 HDD_INFO_TX_PACKETS    |
+			 HDD_INFO_TX_RETRIES    |
+			 HDD_INFO_TX_FAILED     |
+			 HDD_INFO_RX_BYTES      |
+			 HDD_INFO_RX_BYTES64    |
+			 HDD_INFO_RX_PACKETS    |
+			 HDD_INFO_INACTIVE_TIME |
+			 HDD_INFO_CONNECTED_TIME;
+}
+
+/**
+ * hdd_fill_rate_info() - fill rate info of sinfo
+ * @sinfo: station_info struct pointer
+ * @stainfo: stainfo pointer
+ * @stats: fw txrx status pointer
+ * @cfg: hdd config pointer
+ *
+ * This function will fill rate info of sinfo
+ *
+ * Return: None
+ */
+static void hdd_fill_rate_info(struct station_info *sinfo,
+			       struct hdd_station_info *stainfo,
+			       struct hdd_fw_txrx_stats *stats,
+			       struct hdd_config *cfg)
+{
+	uint8_t rate_flags;
+	uint8_t mcsidx = 0xff;
+	uint32_t myrate, maxrate, tmprate;
+	int rssidx;
+	int nss = 1;
+
+	hdd_info("reportMaxLinkSpeed %d", cfg->reportMaxLinkSpeed);
+
+	/* convert to 100kbps expected in rate table */
+	myrate = stats->tx_rate.rate / 100;
+	rate_flags = stainfo->rate_flags;
+	if (!(rate_flags & TX_RATE_LEGACY)) {
+		nss = stainfo->nss;
+		if (eHDD_LINK_SPEED_REPORT_ACTUAL == cfg->reportMaxLinkSpeed) {
+			/* Get current rate flags if report actual */
+			if (stats->tx_rate.rate_flags)
+				rate_flags =
+					stats->tx_rate.rate_flags;
+			nss = stats->tx_rate.nss;
+		}
+
+		if (stats->tx_rate.mcs == INVALID_MCS_IDX)
+			rate_flags = TX_RATE_LEGACY;
+	}
+
+	if (eHDD_LINK_SPEED_REPORT_ACTUAL != cfg->reportMaxLinkSpeed) {
+		/* we do not want to necessarily report the current speed */
+		if (eHDD_LINK_SPEED_REPORT_MAX == cfg->reportMaxLinkSpeed) {
+			/* report the max possible speed */
+			rssidx = 0;
+		} else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED ==
+				cfg->reportMaxLinkSpeed) {
+			/* report the max possible speed with RSSI scaling */
+			if (stats->rssi >= cfg->linkSpeedRssiHigh) {
+				/* report the max possible speed */
+				rssidx = 0;
+			} else if (stats->rssi >=
+					cfg->linkSpeedRssiMid) {
+				/* report middle speed */
+				rssidx = 1;
+			} else if (stats->rssi >=
+					cfg->linkSpeedRssiLow) {
+				/* report middle speed */
+				rssidx = 2;
+			} else {
+				/* report actual speed */
+				rssidx = 3;
+			}
+		} else {
+			/* unknown, treat as eHDD_LINK_SPEED_REPORT_MAX */
+			hdd_err("Invalid value for reportMaxLinkSpeed: %u",
+				cfg->reportMaxLinkSpeed);
+			rssidx = 0;
+		}
+
+		maxrate = hdd_get_max_rate_legacy(stainfo, rssidx);
+
+		/*
+		 * Get MCS Rate Set --
+		 * Only if we are connected in non legacy mode and not
+		 * reporting actual speed
+		 */
+		if ((rssidx != 3) &&
+		    !(rate_flags & TX_RATE_LEGACY)) {
+			hdd_get_max_rate_vht(stainfo,
+					     stats,
+					     rate_flags,
+					     nss,
+					     &tmprate,
+					     &mcsidx,
+					     rssidx == 0);
+
+			if (maxrate < tmprate &&
+			    mcsidx != INVALID_MCS_IDX)
+				maxrate = tmprate;
+
+			if (mcsidx == INVALID_MCS_IDX)
+				hdd_get_max_rate_ht(stainfo,
+						    stats,
+						    rate_flags,
+						    nss,
+						    &tmprate,
+						    &mcsidx,
+						    rssidx == 0);
+
+			if (maxrate < tmprate &&
+			    mcsidx != INVALID_MCS_IDX)
+				maxrate = tmprate;
+		} else if (!(rate_flags & TX_RATE_LEGACY)) {
+			maxrate = myrate;
+			mcsidx = stats->tx_rate.mcs;
+		}
+
+		/*
+		 * make sure we report a value at least as big as our
+		 * current rate
+		 */
+		if ((maxrate < myrate) || (maxrate == 0)) {
+			maxrate = myrate;
+			if (!(rate_flags & TX_RATE_LEGACY)) {
+				mcsidx = stats->tx_rate.mcs;
+				/*
+				 * 'IEEE_P802.11ac_2013.pdf' page 325, 326
+				 * - MCS9 is valid for VHT20 when Nss = 3 or
+				 *   Nss = 6
+				 * - MCS9 is not valid for VHT20 when
+				 *   Nss = 1,2,4,5,7,8
+				 */
+				if ((rate_flags & TX_RATE_VHT20) &&
+				    (mcsidx > 8) &&
+				    (nss != 3 && nss != 6))
+					mcsidx = 8;
+			}
+		}
+	} else {
+		/* report current rate instead of max rate */
+		maxrate = myrate;
+		if (!(rate_flags & TX_RATE_LEGACY))
+			mcsidx = stats->tx_rate.mcs;
+	}
+
+	hdd_fill_sinfo_rate_info(sinfo,
+				 rate_flags,
+				 mcsidx,
+				 nss,
+				 maxrate);
+}
+
+/**
+ * wlan_hdd_fill_station_info() - fill station_info struct
+ * @sinfo: station_info struct pointer
+ * @stainfo: stainfo pointer
+ * @stats: fw txrx status pointer
+ * @cfg: hdd config pointer
+ *
+ * This function will fill station_info struct
+ *
+ * Return: None
+ */
+static void wlan_hdd_fill_station_info(struct station_info *sinfo,
+				       struct hdd_station_info *stainfo,
+				       struct hdd_fw_txrx_stats *stats,
+				       struct hdd_config *cfg)
+{
+	qdf_time_t curr_time, dur;
+
+	curr_time = qdf_system_ticks();
+	dur = curr_time - stainfo->assoc_ts;
+	sinfo->connected_time = qdf_system_ticks_to_msecs(dur) / 1000;
+	dur = curr_time - stainfo->last_tx_rx_ts;
+	sinfo->inactive_time = qdf_system_ticks_to_msecs(dur);
+	sinfo->signal = stats->rssi;
+	sinfo->tx_bytes = stats->tx_bytes;
+	sinfo->tx_packets = stats->tx_packets;
+	sinfo->rx_bytes = stats->rx_bytes;
+	sinfo->rx_packets = stats->rx_packets;
+	sinfo->tx_failed = stats->tx_failed;
+	sinfo->tx_retries = stats->tx_retries;
+
+	/* tx rate info */
+	hdd_fill_rate_info(sinfo, stainfo, stats, cfg);
+
+	hdd_fill_station_info_flags(sinfo);
+
+	/* dump sta info*/
+	hdd_info("dump stainfo");
+	hdd_info("con_time %d inact_time %d tx_pkts %d rx_pkts %d",
+		 sinfo->connected_time, sinfo->inactive_time,
+		 sinfo->tx_packets, sinfo->rx_packets);
+	hdd_info("failed %d retries %d tx_bytes %lld rx_bytes %lld",
+		 sinfo->tx_failed, sinfo->tx_retries,
+		 sinfo->tx_bytes, sinfo->rx_bytes);
+	hdd_info("rssi %d mcs %d legacy %d nss %d flags %x",
+		 sinfo->signal, sinfo->txrate.mcs,
+		 sinfo->txrate.legacy, sinfo->txrate.nss,
+		 sinfo->txrate.flags);
+}
+
+/**
+ * hdd_get_rate_flags_ht() - get HT rate flags based on rate, nss and mcs
+ * @rate: Data rate (100 kbps)
+ * @nss: Number of streams
+ * @mcs: HT mcs index
+ *
+ * This function is used to construct HT rate flag with rate, nss and mcs
+ *
+ * Return: rate flags for success, 0 on failure.
+ */
+static uint8_t hdd_get_rate_flags_ht(uint32_t rate,
+				     uint8_t nss,
+				     uint8_t mcs)
+{
+	struct index_data_rate_type *mcs_rate;
+	uint8_t flags = 0;
+
+	mcs_rate = (struct index_data_rate_type *)
+		((nss == 1) ? &supported_mcs_rate_nss1 :
+		 &supported_mcs_rate_nss2);
+
+	if (rate == mcs_rate[mcs].supported_rate[0]) {
+		flags |= TX_RATE_HT20;
+	} else if (rate == mcs_rate[mcs].supported_rate[1]) {
+		flags |= TX_RATE_HT40;
+	} else if (rate == mcs_rate[mcs].supported_rate[2]) {
+		flags |= TX_RATE_HT20;
+		flags |= TX_RATE_SGI;
+	} else if (rate == mcs_rate[mcs].supported_rate[3]) {
+		flags |= TX_RATE_HT40;
+		flags |= TX_RATE_SGI;
+	} else {
+		hdd_err("invalid params rate %d nss %d mcs %d",
+			rate, nss, mcs);
+	}
+
+	return flags;
+}
+
+/**
+ * hdd_get_rate_flags_vht() - get VHT rate flags based on rate, nss and mcs
+ * @rate: Data rate (100 kbps)
+ * @nss: Number of streams
+ * @mcs: VHT mcs index
+ *
+ * This function is used to construct VHT rate flag with rate, nss and mcs
+ *
+ * Return: rate flags for success, 0 on failure.
+ */
+static uint8_t hdd_get_rate_flags_vht(uint32_t rate,
+				      uint8_t nss,
+				      uint8_t mcs)
+{
+	struct index_vht_data_rate_type *mcs_rate;
+	uint8_t flags = 0;
+
+	mcs_rate = (struct index_vht_data_rate_type *)
+		((nss == 1) ?
+		 &supported_vht_mcs_rate_nss1 :
+		 &supported_vht_mcs_rate_nss2);
+
+	if (rate == mcs_rate[mcs].supported_VHT80_rate[0]) {
+		flags |= TX_RATE_VHT80;
+	} else if (rate == mcs_rate[mcs].supported_VHT80_rate[1]) {
+		flags |= TX_RATE_VHT80;
+		flags |= TX_RATE_SGI;
+	} else if (rate == mcs_rate[mcs].supported_VHT40_rate[0]) {
+		flags |= TX_RATE_VHT40;
+	} else if (rate == mcs_rate[mcs].supported_VHT40_rate[1]) {
+		flags |= TX_RATE_VHT40;
+		flags |= TX_RATE_SGI;
+	} else if (rate == mcs_rate[mcs].supported_VHT20_rate[0]) {
+		flags |= TX_RATE_VHT20;
+	} else if (rate == mcs_rate[mcs].supported_VHT20_rate[1]) {
+		flags |= TX_RATE_VHT20;
+		flags |= TX_RATE_SGI;
+	} else {
+		hdd_err("invalid params rate %d nss %d mcs %d",
+			rate, nss, mcs);
+	}
+
+	return flags;
+}
+
+/**
+ * hdd_get_rate_flags() - get HT/VHT rate flags based on rate, nss and mcs
+ * @rate: Data rate (100 kbps)
+ * @mode: Tx/Rx mode
+ * @nss: Number of streams
+ * @mcs: Mcs index
+ *
+ * This function is used to construct rate flag with rate, nss and mcs
+ *
+ * Return: rate flags for success, 0 on failure.
+ */
+static uint8_t hdd_get_rate_flags(uint32_t rate,
+				  uint8_t mode,
+				  uint8_t nss,
+				  uint8_t mcs)
+{
+	uint8_t flags = 0;
+
+	if (mode == SIR_SME_PHY_MODE_HT)
+		flags = hdd_get_rate_flags_ht(rate, nss, mcs);
+	else if (mode == SIR_SME_PHY_MODE_VHT)
+		flags = hdd_get_rate_flags_vht(rate, nss, mcs);
+	else
+		hdd_err("invalid mode param %d", mode);
+
+	return flags;
+}
+
+/**
+ * wlan_hdd_fill_rate_info() - fill HDD rate info from SIR peer info
+ * @ap_ctx: AP Context
+ * @peer_info: SIR peer info pointer
+ *
+ * This function is used to fill HDD rate info rom SIR peer info
+ *
+ * Return: None
+ */
+static void wlan_hdd_fill_rate_info(struct hdd_ap_ctx *ap_ctx,
+				    struct sir_peer_info_ext *peer_info)
+{
+	uint8_t flags;
+	uint32_t rate_code;
+
+	/* tx rate info */
+	ap_ctx->txrx_stats.tx_rate.rate = peer_info->tx_rate;
+	rate_code = peer_info->tx_rate_code;
+
+	if ((WMI_GET_HW_RATECODE_PREAM_V1(rate_code)) ==
+			WMI_RATE_PREAMBLE_HT)
+		ap_ctx->txrx_stats.tx_rate.mode = SIR_SME_PHY_MODE_HT;
+	else if ((WMI_GET_HW_RATECODE_PREAM_V1(rate_code)) ==
+			WMI_RATE_PREAMBLE_VHT)
+		ap_ctx->txrx_stats.tx_rate.mode = SIR_SME_PHY_MODE_VHT;
+	else
+		ap_ctx->txrx_stats.tx_rate.mode = SIR_SME_PHY_MODE_LEGACY;
+
+	ap_ctx->txrx_stats.tx_rate.nss =
+		WMI_GET_HW_RATECODE_NSS_V1(rate_code) + 1;
+	ap_ctx->txrx_stats.tx_rate.mcs =
+		WMI_GET_HW_RATECODE_RATE_V1(rate_code);
+
+	flags = hdd_get_rate_flags(ap_ctx->txrx_stats.tx_rate.rate / 100,
+				   ap_ctx->txrx_stats.tx_rate.mode,
+				   ap_ctx->txrx_stats.tx_rate.nss,
+				   ap_ctx->txrx_stats.tx_rate.mcs);
+
+	ap_ctx->txrx_stats.tx_rate.rate_flags = flags;
+
+	hdd_debug("tx: mode %d nss %d mcs %d rate_flags %x flags %x",
+		  ap_ctx->txrx_stats.tx_rate.mode,
+		  ap_ctx->txrx_stats.tx_rate.nss,
+		  ap_ctx->txrx_stats.tx_rate.mcs,
+		  ap_ctx->txrx_stats.tx_rate.rate_flags,
+		  flags);
+
+	/* rx rate info */
+	ap_ctx->txrx_stats.rx_rate.rate = peer_info->rx_rate;
+	rate_code = peer_info->rx_rate_code;
+
+	if ((WMI_GET_HW_RATECODE_PREAM_V1(rate_code)) ==
+			WMI_RATE_PREAMBLE_HT)
+		ap_ctx->txrx_stats.rx_rate.mode = SIR_SME_PHY_MODE_HT;
+	else if ((WMI_GET_HW_RATECODE_PREAM_V1(rate_code)) ==
+			WMI_RATE_PREAMBLE_VHT)
+		ap_ctx->txrx_stats.rx_rate.mode = SIR_SME_PHY_MODE_VHT;
+	else
+		ap_ctx->txrx_stats.rx_rate.mode = SIR_SME_PHY_MODE_LEGACY;
+
+	ap_ctx->txrx_stats.rx_rate.nss =
+		WMI_GET_HW_RATECODE_NSS_V1(rate_code) + 1;
+	ap_ctx->txrx_stats.rx_rate.mcs =
+		WMI_GET_HW_RATECODE_RATE_V1(rate_code);
+
+	flags = hdd_get_rate_flags(ap_ctx->txrx_stats.rx_rate.rate / 100,
+				   ap_ctx->txrx_stats.rx_rate.mode,
+				   ap_ctx->txrx_stats.rx_rate.nss,
+				   ap_ctx->txrx_stats.rx_rate.mcs);
+
+	ap_ctx->txrx_stats.rx_rate.rate_flags = flags;
+
+	hdd_info("rx: mode %d nss %d mcs %d rate_flags %x flags %x",
+		 ap_ctx->txrx_stats.rx_rate.mode,
+		 ap_ctx->txrx_stats.rx_rate.nss,
+		 ap_ctx->txrx_stats.rx_rate.mcs,
+		 ap_ctx->txrx_stats.rx_rate.rate_flags,
+		 flags);
+}
+
+int wlan_hdd_get_station_remote(struct wiphy *wiphy,
+				struct net_device *dev,
+				const u8 *mac,
+				struct station_info *sinfo);
+
+/**
+ * wlan_hdd_get_station_remote() - NL80211_CMD_GET_STATION handler for SoftAP
+ * @wiphy: pointer to wiphy
+ * @dev: pointer to net_device structure
+ * @mac: request peer mac address
+ * @sinfo: pointer to station_info struct
+ *
+ * This function will get remote peer info from fw and fill sinfo struct
+ *
+ * Return: 0 on success, otherwise error value
+ */
+int wlan_hdd_get_station_remote(struct wiphy *wiphy,
+				struct net_device *dev,
+				const u8 *mac,
+				struct station_info *sinfo)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hddctx = wiphy_priv(wiphy);
+	struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+	struct hdd_station_info *stainfo = NULL;
+	struct hdd_config *cfg;
+	struct qdf_mac_addr macaddr;
+	struct sir_peer_info_ext peer_info;
+	int status;
+	int i;
+
+	status = wlan_hdd_validate_context(hddctx);
+	if (status != 0)
+		return status;
+
+	cfg = hddctx->config;
+
+	hdd_debug("get peer %pM info", mac);
+
+	for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
+		if (!qdf_mem_cmp(adapter->sta_info[i].sta_mac.bytes,
+				 mac,
+				 QDF_MAC_ADDR_SIZE)) {
+			stainfo = &adapter->sta_info[i];
+			break;
+		}
+	}
+
+	if (!stainfo) {
+		hdd_err("peer %pM not found", mac);
+		return -EINVAL;
+	}
+
+	qdf_mem_copy(macaddr.bytes, mac, QDF_MAC_ADDR_SIZE);
+	status = wlan_hdd_get_peer_info(adapter, macaddr, &peer_info);
+	if (status) {
+		hdd_err("fail to get peer info from fw");
+		return -EPERM;
+	}
+
+	qdf_mem_zero(&ap_ctx->txrx_stats, sizeof(ap_ctx->txrx_stats));
+	ap_ctx->txrx_stats.tx_packets = peer_info.tx_packets;
+	ap_ctx->txrx_stats.tx_bytes = peer_info.tx_bytes;
+	ap_ctx->txrx_stats.rx_packets = peer_info.rx_packets;
+	ap_ctx->txrx_stats.rx_bytes = peer_info.rx_bytes;
+	ap_ctx->txrx_stats.tx_retries = peer_info.tx_retries;
+	ap_ctx->txrx_stats.tx_failed = peer_info.tx_failed;
+	ap_ctx->txrx_stats.rssi =
+		peer_info.rssi + WLAN_HDD_TGT_NOISE_FLOOR_DBM;
+	wlan_hdd_fill_rate_info(ap_ctx, &peer_info);
+
+	wlan_hdd_fill_station_info(sinfo, stainfo, &ap_ctx->txrx_stats, cfg);
+
+	return status;
+}
+
+/**
+ * hdd_report_max_rate() - Fill the max rate stats in the station info structure
+ * to be sent to the userspace.
+ *
+ * @mac_handle: The mac handle
+ * @config: The HDD config structure
+ * @sinfo: The station_info struct to be filled
+ * @tx_rate_flags: The TX rate flags computed from tx rate
+ * @tx_mcs_index; The TX mcs index computed from tx rate
+ * @my_tx_rate: The tx_rate from fw stats
+ * @tx_nss: The TX NSS from fw stats
+ *
+ * Return: 0 for success
+ */
+static int hdd_report_max_rate(mac_handle_t mac_handle,
+			       struct hdd_config *config,
+			       struct station_info *sinfo,
+			       uint8_t tx_rate_flags,
+			       uint8_t tx_mcs_index,
+			       uint16_t my_tx_rate, uint8_t tx_nss)
+{
+	uint8_t i, j, rssidx;
+	uint16_t max_rate = 0;
+	uint32_t vht_mcs_map;
+	uint16_t current_rate = 0;
+	qdf_size_t or_leng = CSR_DOT11_SUPPORTED_RATES_MAX;
+	uint8_t operational_rates[CSR_DOT11_SUPPORTED_RATES_MAX];
+	uint8_t extended_rates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
+	qdf_size_t er_leng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
+	uint8_t mcs_rates[SIZE_OF_BASIC_MCS_SET];
+	qdf_size_t mcs_leng = SIZE_OF_BASIC_MCS_SET;
+	struct index_vht_data_rate_type *supported_vht_mcs_rate;
+	struct index_data_rate_type *supported_mcs_rate;
+	enum data_rate_11ac_max_mcs vht_max_mcs;
+	uint8_t max_speed_mcs = 0;
+	uint8_t max_mcs_idx = 0;
+	uint8_t rate_flag = 1;
+	int mode = 0, max_ht_idx;
+	QDF_STATUS stat = QDF_STATUS_E_FAILURE;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* we do not want to necessarily report the current speed */
+	if (eHDD_LINK_SPEED_REPORT_MAX == config->reportMaxLinkSpeed) {
+		/* report the max possible speed */
+		rssidx = 0;
+	} else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED ==
+		   config->reportMaxLinkSpeed) {
+		/* report the max possible speed with RSSI scaling */
+		if (sinfo->signal >= config->linkSpeedRssiHigh) {
+			/* report the max possible speed */
+			rssidx = 0;
+		} else if (sinfo->signal >= config->linkSpeedRssiMid) {
+			/* report middle speed */
+			rssidx = 1;
+		} else if (sinfo->signal >= config->linkSpeedRssiLow) {
+			/* report middle speed */
+			rssidx = 2;
+		} else {
+			/* report actual speed */
+			rssidx = 3;
+		}
+	} else {
+		/* unknown, treat as eHDD_LINK_SPEED_REPORT_MAX */
+		hdd_err("Invalid value for reportMaxLinkSpeed: %u",
+			config->reportMaxLinkSpeed);
+		rssidx = 0;
+	}
+
+	max_rate = 0;
+
+	/* Get Basic Rate Set */
+	if (0 != ucfg_mlme_get_opr_rate_set(hdd_ctx->psoc,
+					    operational_rates, &or_leng)) {
+		hdd_err("cfg get returned failure");
+		/*To keep GUI happy */
+		return 0;
+	}
+
+	for (i = 0; i < or_leng; i++) {
+		for (j = 0;
+			 j < ARRAY_SIZE(supported_data_rate); j++) {
+			/* Validate Rate Set */
+			if (supported_data_rate[j].beacon_rate_index ==
+				(operational_rates[i] & 0x7F)) {
+				current_rate =
+					supported_data_rate[j].
+					supported_rate[rssidx];
+				break;
+			}
+		}
+		/* Update MAX rate */
+		max_rate = (current_rate > max_rate) ? current_rate : max_rate;
+	}
+
+	/* Get Extended Rate Set */
+	if (0 != ucfg_mlme_get_ext_opr_rate_set(hdd_ctx->psoc,
+						extended_rates,
+						&er_leng)) {
+		hdd_err("cfg get returned failure");
+		/*To keep GUI happy */
+		return 0;
+	}
+
+	for (i = 0; i < er_leng; i++) {
+		for (j = 0; j < ARRAY_SIZE(supported_data_rate); j++) {
+			if (supported_data_rate[j].beacon_rate_index ==
+			    (extended_rates[i] & 0x7F)) {
+				current_rate = supported_data_rate[j].
+					       supported_rate[rssidx];
+				break;
+			}
+		}
+		/* Update MAX rate */
+		max_rate = (current_rate > max_rate) ? current_rate : max_rate;
+	}
+	/* Get MCS Rate Set --
+	 * Only if we are connected in non legacy mode and not reporting
+	 * actual speed
+	 */
+	if ((3 != rssidx) && !(tx_rate_flags & TX_RATE_LEGACY)) {
+		if (0 != ucfg_mlme_get_current_mcs_set(hdd_ctx->psoc,
+						       mcs_rates,
+						       &mcs_leng)) {
+			hdd_err("cfg get returned failure");
+			/*To keep GUI happy */
+			return 0;
+		}
+		rate_flag = 0;
+		supported_vht_mcs_rate = (struct index_vht_data_rate_type *)
+					  ((tx_nss == 1) ?
+					  &supported_vht_mcs_rate_nss1 :
+					  &supported_vht_mcs_rate_nss2);
+
+		if (tx_rate_flags & TX_RATE_VHT80)
+			mode = 2;
+		else if ((tx_rate_flags & TX_RATE_VHT40) ||
+			 (tx_rate_flags & TX_RATE_HT40))
+			mode = 1;
+		else
+			mode = 0;
+
+		/* VHT80 rate has separate rate table */
+		if (tx_rate_flags & (TX_RATE_VHT20 | TX_RATE_VHT40 |
+		    TX_RATE_VHT80)) {
+			stat = ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc,
+								&vht_mcs_map);
+			if (QDF_IS_STATUS_ERROR(stat))
+				hdd_err("failed to get tx_mcs_map");
+			vht_max_mcs = (enum data_rate_11ac_max_mcs)
+				(vht_mcs_map & DATA_RATE_11AC_MCS_MASK);
+			if (tx_rate_flags & TX_RATE_SGI)
+				rate_flag |= 1;
+
+			if (DATA_RATE_11AC_MAX_MCS_7 == vht_max_mcs) {
+				max_mcs_idx = 7;
+			} else if (DATA_RATE_11AC_MAX_MCS_8 == vht_max_mcs) {
+				max_mcs_idx = 8;
+			} else if (DATA_RATE_11AC_MAX_MCS_9 == vht_max_mcs) {
+				max_mcs_idx = 9;
+			}
+
+			if (rssidx != 0) {
+				for (i = 0; i <= max_mcs_idx; i++) {
+					if (sinfo->signal <=
+						rssi_mcs_tbl[mode][i]) {
+						max_mcs_idx = i;
+						break;
+					}
+				}
+			}
+
+			if (tx_rate_flags & TX_RATE_VHT80) {
+				current_rate =
+				  supported_vht_mcs_rate[tx_mcs_index].
+				  supported_VHT80_rate[rate_flag];
+				max_rate =
+				  supported_vht_mcs_rate[max_mcs_idx].
+					supported_VHT80_rate[rate_flag];
+			} else if (tx_rate_flags & TX_RATE_VHT40) {
+				current_rate =
+				  supported_vht_mcs_rate[tx_mcs_index].
+				  supported_VHT40_rate[rate_flag];
+				max_rate =
+				  supported_vht_mcs_rate[max_mcs_idx].
+					supported_VHT40_rate[rate_flag];
+			} else if (tx_rate_flags & TX_RATE_VHT20) {
+				current_rate =
+				  supported_vht_mcs_rate[tx_mcs_index].
+				  supported_VHT20_rate[rate_flag];
+				max_rate =
+				  supported_vht_mcs_rate[max_mcs_idx].
+				  supported_VHT20_rate[rate_flag];
+			}
+
+			max_speed_mcs = 1;
+			if (current_rate > max_rate)
+				max_rate = current_rate;
+
+		} else {
+			if (tx_rate_flags & TX_RATE_HT40)
+				rate_flag |= 1;
+			if (tx_rate_flags & TX_RATE_SGI)
+				rate_flag |= 2;
+
+			supported_mcs_rate =
+				(struct index_data_rate_type *)
+				((tx_nss ==
+				  1) ? &supported_mcs_rate_nss1 :
+				 &supported_mcs_rate_nss2);
+
+			max_ht_idx = MAX_HT_MCS_IDX;
+			if (rssidx != 0) {
+				for (i = 0; i < MAX_HT_MCS_IDX; i++) {
+					if (sinfo->signal <=
+						rssi_mcs_tbl[mode][i]) {
+						max_ht_idx = i + 1;
+						break;
+					}
+				}
+			}
+
+			for (i = 0; i < mcs_leng; i++) {
+				for (j = 0; j < max_ht_idx; j++) {
+					if (supported_mcs_rate[j].
+						beacon_rate_index ==
+						mcs_rates[i]) {
+						current_rate =
+						  supported_mcs_rate[j].
+						  supported_rate
+						  [rate_flag];
+						max_mcs_idx =
+						  supported_mcs_rate[j].
+						  beacon_rate_index;
+						break;
+					}
+				}
+
+				if ((j < MAX_HT_MCS_IDX) &&
+				    (current_rate > max_rate)) {
+					max_rate = current_rate;
+				}
+				max_speed_mcs = 1;
+			}
+			if (tx_nss == 2)
+				max_mcs_idx += MAX_HT_MCS_IDX;
+		}
+	}
+
+	else if (!(tx_rate_flags & TX_RATE_LEGACY)) {
+		max_rate = my_tx_rate;
+		max_speed_mcs = 1;
+		max_mcs_idx = tx_mcs_index;
+	}
+	/* report a value at least as big as current rate */
+	if ((max_rate < my_tx_rate) || (0 == max_rate)) {
+		max_rate = my_tx_rate;
+		if (tx_rate_flags & TX_RATE_LEGACY) {
+			max_speed_mcs = 0;
+		} else {
+			max_speed_mcs = 1;
+			max_mcs_idx = tx_mcs_index;
+			}
+	}
+
+	if (tx_rate_flags & TX_RATE_LEGACY) {
+		sinfo->txrate.legacy = max_rate;
+
+		hdd_info("Reporting legacy rate %d",
+			 sinfo->txrate.legacy);
+	} else {
+		sinfo->txrate.mcs = max_mcs_idx;
+		sinfo->txrate.nss = tx_nss;
+		if (tx_rate_flags & TX_RATE_VHT80)
+			hdd_set_rate_bw(&sinfo->txrate, HDD_RATE_BW_80);
+		else if (tx_rate_flags & TX_RATE_VHT40)
+			hdd_set_rate_bw(&sinfo->txrate, HDD_RATE_BW_40);
+		else if (tx_rate_flags & TX_RATE_VHT20)
+			hdd_set_rate_bw(&sinfo->txrate, HDD_RATE_BW_20);
+
+		if (tx_rate_flags &
+		    (TX_RATE_HT20 | TX_RATE_HT40)) {
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+			if (tx_rate_flags & TX_RATE_HT40)
+				hdd_set_rate_bw(&sinfo->txrate,
+						HDD_RATE_BW_40);
+			else if (tx_rate_flags & TX_RATE_HT20)
+				hdd_set_rate_bw(&sinfo->txrate,
+						HDD_RATE_BW_20);
+		} else {
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
+		}
+
+		if (tx_rate_flags & TX_RATE_SGI) {
+			if (!
+			    (sinfo->txrate.
+			     flags & RATE_INFO_FLAGS_VHT_MCS))
+				sinfo->txrate.flags |=
+					RATE_INFO_FLAGS_MCS;
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+		}
+		linkspeed_dbg("Reporting MCS rate %d flags %x\n",
+			      sinfo->txrate.mcs, sinfo->txrate.flags);
+	}
+	return 1;
+}
+
+/**
+ * hdd_report_actual_rate() - Fill the actual rate stats.
+ *
+ * @rate_flags: The rate flags computed from rate
+ * @my_rate: The rate from fw stats
+ * @rate: The station_info struct member strust rate_info to be filled
+ * @mcs_index; The mcs index computed from rate
+ * @nss: The NSS from fw stats
+ *
+ * Return: None
+ */
+static void hdd_report_actual_rate(uint8_t rate_flags, uint16_t my_rate,
+				   struct rate_info *rate, uint8_t mcs_index,
+				   uint8_t nss)
+{
+	/* report current rate instead of max rate */
+
+	if (rate_flags & TX_RATE_LEGACY) {
+		/* provide to the UI in units of 100kbps */
+		rate->legacy = my_rate;
+		linkspeed_dbg("Reporting actual legacy rate %d",
+			      rate->legacy);
+	} else {
+		/* must be MCS */
+		rate->mcs = mcs_index;
+		rate->nss = nss;
+
+		if (rate_flags & TX_RATE_VHT80)
+			hdd_set_rate_bw(rate, HDD_RATE_BW_80);
+		else if (rate_flags & TX_RATE_VHT40)
+			hdd_set_rate_bw(rate, HDD_RATE_BW_40);
+
+		if (rate_flags &
+			(TX_RATE_HT20 | TX_RATE_HT40)) {
+			rate->flags |= RATE_INFO_FLAGS_MCS;
+			if (rate_flags & TX_RATE_HT40)
+				hdd_set_rate_bw(rate, HDD_RATE_BW_40);
+		} else {
+			rate->flags |= RATE_INFO_FLAGS_VHT_MCS;
+		}
+
+		if (rate_flags & TX_RATE_SGI) {
+			rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
+		}
+
+		linkspeed_dbg("Reporting actual MCS rate %d flags %x\n",
+			      rate->mcs, rate->flags);
+	}
+}
+
+/**
+ * hdd_wlan_fill_per_chain_rssi_stats() - Fill per chain rssi stats
+ *
+ * @sinfo: The station_info structure to be filled.
+ * @adapter: The HDD adapter structure
+ *
+ * Return: None
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+static inline
+void hdd_wlan_fill_per_chain_rssi_stats(struct station_info *sinfo,
+					struct hdd_adapter *adapter)
+{
+	bool rssi_stats_valid = false;
+	uint8_t i;
+
+	sinfo->signal_avg = WLAN_HDD_TGT_NOISE_FLOOR_DBM;
+	for (i = 0; i < NUM_CHAINS_MAX; i++) {
+		sinfo->chain_signal_avg[i] =
+			   adapter->hdd_stats.per_chain_rssi_stats.rssi[i];
+		sinfo->chains |= 1 << i;
+		if (sinfo->chain_signal_avg[i] > sinfo->signal_avg &&
+		    sinfo->chain_signal_avg[i] != 0)
+			sinfo->signal_avg = sinfo->chain_signal_avg[i];
+
+		hdd_debug("RSSI for chain %d, vdev_id %d is %d",
+			  i, adapter->session_id, sinfo->chain_signal_avg[i]);
+
+		if (!rssi_stats_valid && sinfo->chain_signal_avg[i])
+			rssi_stats_valid = true;
+	}
+
+	if (rssi_stats_valid) {
+		sinfo->filled |= HDD_INFO_CHAIN_SIGNAL_AVG;
+		sinfo->filled |= HDD_INFO_SIGNAL_AVG;
+	}
+}
+
+#else
+
+static inline
+void hdd_wlan_fill_per_chain_rssi_stats(struct station_info *sinfo,
+					struct hdd_adapter *adapter)
+{
+}
+
+#endif
+
+/**
+ * wlan_hdd_get_sta_stats() - get aggregate STA stats
+ * @wiphy: wireless phy
+ * @adapter: STA adapter to get stats for
+ * @mac: mac address of sta
+ * @sinfo: kernel station_info struct to populate
+ *
+ * Fetch the vdev-level aggregate stats for the given STA adapter. This is to
+ * support "station dump" and "station get" for STA vdevs
+ *
+ * Return: errno
+ */
+static int wlan_hdd_get_sta_stats(struct wiphy *wiphy,
+				  struct hdd_adapter *adapter,
+				  const uint8_t *mac,
+				  struct station_info *sinfo)
+{
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	uint8_t rate_flags, tx_rate_flags, rx_rate_flags;
+	uint8_t tx_mcs_index, rx_mcs_index;
+	struct hdd_context *hdd_ctx = (struct hdd_context *) wiphy_priv(wiphy);
+	struct hdd_config *pCfg = hdd_ctx->config;
+	mac_handle_t mac_handle;
+	uint16_t maxRate = 0;
+	int8_t snr = 0;
+	uint16_t my_tx_rate, my_rx_rate;
+	uint8_t tx_nss = 1, rx_nss = 1;
+	int32_t rcpi_value;
+
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		hdd_debug("Not associated");
+		/*To keep GUI happy */
+		return 0;
+	}
+
+	if (sta_ctx->hdd_reassoc_scenario) {
+		hdd_debug("Roaming is in progress, cannot continue with this request");
+		/*
+		 * supplicant reports very low rssi to upper layer
+		 * and handover happens to cellular.
+		 * send the cached rssi when get_station
+		 */
+		sinfo->signal = adapter->rssi;
+		sinfo->filled |= HDD_INFO_SIGNAL;
+		return 0;
+	}
+
+	if (hdd_ctx->rcpi_enabled)
+		wlan_hdd_get_rcpi(adapter, (uint8_t *)mac, &rcpi_value,
+				  RCPI_MEASUREMENT_TYPE_AVG_MGMT);
+
+	wlan_hdd_get_station_stats(adapter);
+
+	adapter->rssi = adapter->hdd_stats.summary_stat.rssi;
+	snr = adapter->hdd_stats.summary_stat.snr;
+
+	/* for new connection there might be no valid previous RSSI */
+	if (!adapter->rssi) {
+		hdd_get_rssi_snr_by_bssid(adapter,
+				sta_ctx->conn_info.bssId.bytes,
+				&adapter->rssi, &snr);
+	}
+
+	sinfo->signal = adapter->rssi;
+	hdd_debug("snr: %d, rssi: %d",
+		adapter->hdd_stats.summary_stat.snr,
+		adapter->hdd_stats.summary_stat.rssi);
+	sta_ctx->conn_info.signal = sinfo->signal;
+	sta_ctx->conn_info.noise =
+		sta_ctx->conn_info.signal - snr;
+	sta_ctx->cache_conn_info.signal = sinfo->signal;
+	sta_ctx->cache_conn_info.noise = sta_ctx->conn_info.noise;
+	sinfo->filled |= HDD_INFO_SIGNAL;
+
+	/*
+	 * we notify connect to lpass here instead of during actual
+	 * connect processing because rssi info is not accurate during
+	 * actual connection.  lpass will ensure the notification is
+	 * only processed once per association.
+	 */
+	hdd_lpass_notify_connect(adapter);
+
+	rate_flags = adapter->hdd_stats.class_a_stat.tx_rx_rate_flags;
+	tx_rate_flags = rx_rate_flags = rate_flags;
+
+	tx_mcs_index = adapter->hdd_stats.class_a_stat.tx_mcs_index;
+	rx_mcs_index = adapter->hdd_stats.class_a_stat.rx_mcs_index;
+	mac_handle = hdd_ctx->mac_handle;
+
+	/* convert to the UI units of 100kbps */
+	my_tx_rate = adapter->hdd_stats.class_a_stat.tx_rate * 5;
+	my_rx_rate = adapter->hdd_stats.class_a_stat.rx_rate * 5;
+
+	if (!(rate_flags & TX_RATE_LEGACY)) {
+		tx_nss = adapter->hdd_stats.class_a_stat.tx_nss;
+		rx_nss = adapter->hdd_stats.class_a_stat.rx_nss;
+
+		if ((tx_nss > 1) &&
+		    policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc) &&
+		    !policy_mgr_is_hw_dbs_2x2_capable(hdd_ctx->psoc)) {
+			hdd_debug("Hw mode is DBS, Reduce nss(%d) to 1",
+				  tx_nss);
+			tx_nss--;
+		}
+
+		if ((rx_nss > 1) &&
+		    policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc) &&
+		    !policy_mgr_is_hw_dbs_2x2_capable(hdd_ctx->psoc)) {
+			hdd_debug("Hw mode is DBS, Reduce nss(%d) to 1",
+				  rx_nss);
+			rx_nss--;
+		}
+
+		if (eHDD_LINK_SPEED_REPORT_ACTUAL == pCfg->reportMaxLinkSpeed) {
+			/* Get current rate flags if report actual */
+			/* WMA fails to find mcs_index for legacy tx rates */
+			if (tx_mcs_index == INVALID_MCS_IDX && my_tx_rate)
+				tx_rate_flags = TX_RATE_LEGACY;
+			else
+				tx_rate_flags =
+			      adapter->hdd_stats.class_a_stat.tx_mcs_rate_flags;
+
+			if (rx_mcs_index == INVALID_MCS_IDX && my_rx_rate)
+				rx_rate_flags = TX_RATE_LEGACY;
+			else
+				rx_rate_flags =
+			      adapter->hdd_stats.class_a_stat.rx_mcs_rate_flags;
+		}
+
+		if (tx_mcs_index == INVALID_MCS_IDX)
+			tx_mcs_index = 0;
+		if (rx_mcs_index == INVALID_MCS_IDX)
+			rx_mcs_index = 0;
+	}
+
+	hdd_debug("RSSI %d, RLMS %u, rssi high %d, rssi mid %d, rssi low %d",
+		  sinfo->signal, pCfg->reportMaxLinkSpeed,
+		  (int)pCfg->linkSpeedRssiHigh, (int)pCfg->linkSpeedRssiMid,
+		  (int)pCfg->linkSpeedRssiLow);
+	hdd_debug("Rate info: TX: %d, RX: %d", my_tx_rate, my_rx_rate);
+	hdd_debug("Rate flags: TX: 0x%x, RX: 0x%x", (int)tx_rate_flags,
+		  (int)rx_rate_flags);
+	hdd_debug("MCS Index: TX: %d, RX: %d", (int)tx_mcs_index,
+		  (int)rx_mcs_index);
+	hdd_debug("NSS: TX: %d, RX: %d", (int)tx_nss, (int)rx_nss);
+
+	/* assume basic BW. anything else will override this later */
+	hdd_set_rate_bw(&sinfo->txrate, HDD_RATE_BW_20);
+
+	if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed) {
+		if (!hdd_report_max_rate(mac_handle, pCfg, sinfo,
+					 tx_rate_flags, tx_mcs_index,
+					 my_tx_rate, tx_nss)) {
+			/* Keep GUI happy */
+			return 0;
+		}
+	} else {
+
+		/* Fill TX stats */
+		hdd_report_actual_rate(tx_rate_flags, my_tx_rate,
+				       &sinfo->txrate, tx_mcs_index, tx_nss);
+
+		/* Fill RX stats */
+		hdd_report_actual_rate(rx_rate_flags, my_rx_rate,
+				       &sinfo->rxrate, rx_mcs_index, rx_nss);
+	}
+
+	wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, sinfo);
+	sinfo->tx_bytes = adapter->stats.tx_bytes;
+	sinfo->rx_bytes = adapter->stats.rx_bytes;
+	sinfo->rx_packets = adapter->stats.rx_packets;
+
+	qdf_mem_copy(&sta_ctx->conn_info.txrate,
+		     &sinfo->txrate, sizeof(sinfo->txrate));
+	qdf_mem_copy(&sta_ctx->cache_conn_info.txrate,
+		     &sinfo->txrate, sizeof(sinfo->txrate));
+
+	sinfo->filled |= HDD_INFO_TX_BITRATE |
+			 HDD_INFO_RX_BITRATE |
+			 HDD_INFO_TX_BYTES   |
+			 HDD_INFO_RX_BYTES   |
+			 HDD_INFO_RX_PACKETS;
+
+	if (tx_rate_flags & TX_RATE_LEGACY)
+		hdd_debug("Reporting legacy rate %d pkt cnt tx %d rx %d",
+			sinfo->txrate.legacy, sinfo->tx_packets,
+			sinfo->rx_packets);
+	else
+		hdd_debug("Reporting MCS rate %d flags 0x%x pkt cnt tx %d rx %d",
+			sinfo->txrate.mcs, sinfo->txrate.flags,
+			sinfo->tx_packets, sinfo->rx_packets);
+
+	hdd_wlan_fill_per_chain_rssi_stats(sinfo, adapter);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_GET_STA,
+			 adapter->session_id, maxRate));
+
+	hdd_exit();
+
+	return 0;
+}
+
+/**
+ * __wlan_hdd_cfg80211_get_station() - get station statistics
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @mac: Pointer to mac
+ * @sinfo: Pointer to station info
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
+					   struct net_device *dev,
+					   const uint8_t *mac,
+					   struct station_info *sinfo)
+{
+	int status;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = (struct hdd_context *) wiphy_priv(wiphy);
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return status;
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	if (adapter->device_mode == QDF_SAP_MODE)
+		return wlan_hdd_get_sap_stats(adapter, sinfo);
+	else
+		return wlan_hdd_get_sta_stats(wiphy, adapter, mac, sinfo);
+}
+
+/**
+ * wlan_hdd_cfg80211_get_station() - get station statistics
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @mac: Pointer to mac
+ * @sinfo: Pointer to station info
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
+				  struct net_device *dev, const uint8_t *mac,
+				  struct station_info *sinfo)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_dump_station() - dump station statistics
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @idx: variable to determine whether to get stats or not
+ * @mac: Pointer to mac
+ * @sinfo: Pointer to station info
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_dump_station(struct wiphy *wiphy,
+				struct net_device *dev,
+				int idx, u8 *mac,
+				struct station_info *sinfo)
+{
+	struct hdd_context *hdd_ctx = (struct hdd_context *) wiphy_priv(wiphy);
+
+	hdd_debug("%s: idx %d", __func__, idx);
+	if (idx != 0)
+		return -ENOENT;
+	qdf_mem_copy(mac, hdd_ctx->config->intfMacAddr[0].bytes,
+				QDF_MAC_ADDR_SIZE);
+	return __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
+}
+
+/**
+ * wlan_hdd_cfg80211_dump_station() - dump station statistics
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @idx: variable to determine whether to get stats or not
+ * @mac: Pointer to mac
+ * @sinfo: Pointer to station info
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_dump_station(struct wiphy *wiphy,
+				struct net_device *dev,
+				int idx, u8 *mac,
+				struct station_info *sinfo)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_dump_station(wiphy, dev, idx, mac, sinfo);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
+
+/**
+ * hdd_get_stats() - Function to retrieve interface statistics
+ * @dev: pointer to network device
+ *
+ * This function is the ndo_get_stats method for all netdevs
+ * registered with the kernel
+ *
+ * Return: pointer to net_device_stats structure
+ */
+struct net_device_stats *hdd_get_stats(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+	hdd_enter_dev(dev);
+	return &adapter->stats;
+}
+
+
+/*
+ * time = cycle_count * cycle
+ * cycle = 1 / clock_freq
+ * Since the unit of clock_freq reported from
+ * FW is MHZ, and we want to calculate time in
+ * ms level, the result is
+ * time = cycle / (clock_freq * 1000)
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+static bool wlan_fill_survey_result(struct survey_info *survey, int opfreq,
+				    struct scan_chan_info *chan_info,
+				    struct ieee80211_channel *channels)
+{
+	uint64_t clock_freq = chan_info->clock_freq * 1000;
+
+	if (channels->center_freq != (uint16_t)chan_info->freq)
+		return false;
+
+	survey->channel = channels;
+	survey->noise = chan_info->noise_floor;
+	survey->filled = SURVEY_INFO_NOISE_DBM;
+
+	if (opfreq == chan_info->freq)
+		survey->filled |= SURVEY_INFO_IN_USE;
+
+	if (clock_freq == 0)
+		return true;
+
+	survey->time = qdf_do_div(chan_info->cycle_count, clock_freq);
+
+	survey->time_busy = qdf_do_div(chan_info->rx_clear_count, clock_freq);
+
+	survey->time_tx = qdf_do_div(chan_info->tx_frame_count, clock_freq);
+
+	survey->filled |= SURVEY_INFO_TIME |
+			  SURVEY_INFO_TIME_BUSY |
+			  SURVEY_INFO_TIME_TX;
+	return true;
+}
+#else
+static bool wlan_fill_survey_result(struct survey_info *survey, int opfreq,
+				    struct scan_chan_info *chan_info,
+				    struct ieee80211_channel *channels)
+{
+	uint64_t clock_freq = chan_info->clock_freq * 1000;
+
+	if (channels->center_freq != (uint16_t)chan_info->freq)
+		return false;
+
+	survey->channel = channels;
+	survey->noise = chan_info->noise_floor;
+	survey->filled = SURVEY_INFO_NOISE_DBM;
+
+	if (opfreq == chan_info->freq)
+		survey->filled |= SURVEY_INFO_IN_USE;
+
+	if (clock_freq == 0)
+		return true;
+
+	survey->channel_time = qdf_do_div(chan_info->cycle_count, clock_freq);
+
+	survey->channel_time_busy = qdf_do_div(chan_info->rx_clear_count,
+							 clock_freq);
+
+	survey->channel_time_tx = qdf_do_div(chan_info->tx_frame_count,
+							 clock_freq);
+
+	survey->filled |= SURVEY_INFO_CHANNEL_TIME |
+			  SURVEY_INFO_CHANNEL_TIME_BUSY |
+			  SURVEY_INFO_CHANNEL_TIME_TX;
+	return true;
+}
+#endif
+
+static bool wlan_hdd_update_survey_info(struct wiphy *wiphy,
+					struct hdd_adapter *adapter,
+					struct survey_info *survey, int idx)
+{
+	bool filled = false;
+	int i, j = 0;
+	uint32_t channel = 0, opfreq; /* Initialization Required */
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	sme_get_operation_channel(hdd_ctx->mac_handle, &channel,
+				  adapter->session_id);
+	opfreq = wlan_reg_chan_to_freq(hdd_ctx->pdev, channel);
+
+	mutex_lock(&hdd_ctx->chan_info_lock);
+
+	for (i = 0; i < HDD_NUM_NL80211_BANDS && !filled; i++) {
+		if (wiphy->bands[i] == NULL)
+			continue;
+
+		for (j = 0; j < wiphy->bands[i]->n_channels && !filled; j++) {
+			struct ieee80211_supported_band *band = wiphy->bands[i];
+
+			filled = wlan_fill_survey_result(survey, opfreq,
+				&hdd_ctx->chan_info[idx],
+				&band->channels[j]);
+		}
+	}
+	mutex_unlock(&hdd_ctx->chan_info_lock);
+
+	return filled;
+}
+
+/**
+ * __wlan_hdd_cfg80211_dump_survey() - get survey related info
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @idx: Index
+ * @survey: Pointer to survey info
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
+					   struct net_device *dev,
+					   int idx, struct survey_info *survey)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	struct hdd_station_ctx *sta_ctx;
+	int status;
+	bool filled = false;
+
+	hdd_enter_dev(dev);
+
+	hdd_debug("dump survey index: %d", idx);
+	if (idx > QDF_MAX_NUM_CHAN - 1)
+		return -EINVAL;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return status;
+
+	if (hdd_ctx->chan_info == NULL) {
+		hdd_debug("chan_info is NULL");
+		return -EINVAL;
+	}
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	if (hdd_ctx->config->fEnableSNRMonitoring == 0)
+		return -ENONET;
+
+	if (sta_ctx->hdd_reassoc_scenario) {
+		hdd_info("Roaming in progress, hence return");
+		return -ENONET;
+	}
+
+	filled = wlan_hdd_update_survey_info(wiphy, adapter, survey, idx);
+
+	if (!filled)
+		return -ENONET;
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_dump_survey() - get survey related info
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @idx: Index
+ * @survey: Pointer to survey info
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
+				  struct net_device *dev,
+				  int idx, struct survey_info *survey)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_display_hif_stats() - display hif stats
+ *
+ * Return: none
+ *
+ */
+void hdd_display_hif_stats(void)
+{
+	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+
+	if (!hif_ctx)
+		return;
+
+	hif_display_stats(hif_ctx);
+}
+
+/**
+ * hdd_clear_hif_stats() - clear hif stats
+ *
+ * Return: none
+ */
+void hdd_clear_hif_stats(void)
+{
+	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+
+	if (!hif_ctx)
+		return;
+	hif_clear_stats(hif_ctx);
+}
+
+/**
+ * hdd_is_rcpi_applicable() - validates RCPI request
+ * @adapter: adapter upon which the measurement is requested
+ * @mac_addr: peer addr for which measurement is requested
+ * @rcpi_value: pointer to where the RCPI should be returned
+ * @reassoc: used to return cached RCPI during reassoc
+ *
+ * Return: true for success, false for failure
+ */
+
+static bool hdd_is_rcpi_applicable(struct hdd_adapter *adapter,
+				   struct qdf_mac_addr *mac_addr,
+				   int32_t *rcpi_value,
+				   bool *reassoc)
+{
+	struct hdd_station_ctx *hdd_sta_ctx;
+
+	if (adapter->device_mode == QDF_STA_MODE ||
+	    adapter->device_mode == QDF_P2P_CLIENT_MODE) {
+		hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		if (hdd_sta_ctx->conn_info.connState !=
+		    eConnectionState_Associated)
+			return false;
+
+		if (hdd_sta_ctx->hdd_reassoc_scenario) {
+			/* return the cached rcpi, if mac addr matches */
+			hdd_debug("Roaming in progress, return cached RCPI");
+			if (!qdf_mem_cmp(&adapter->rcpi.mac_addr,
+					 mac_addr, sizeof(*mac_addr))) {
+				*rcpi_value = adapter->rcpi.rcpi;
+				*reassoc = true;
+				return true;
+			}
+			return false;
+		}
+
+		if (qdf_mem_cmp(mac_addr, &hdd_sta_ctx->conn_info.bssId,
+				sizeof(*mac_addr))) {
+			hdd_err("mac addr is different from bssid connected");
+			return false;
+		}
+	} else if (adapter->device_mode == QDF_SAP_MODE ||
+		   adapter->device_mode == QDF_P2P_GO_MODE) {
+		if (!test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
+			hdd_err("Invalid rcpi request, softap not started");
+			return false;
+		}
+
+		/* check if peer mac addr is associated to softap */
+		if (!hdd_is_peer_associated(adapter, mac_addr)) {
+			hdd_err("invalid peer mac-addr: not associated");
+			return false;
+		}
+	} else {
+		hdd_err("Invalid rcpi request");
+		return false;
+	}
+
+	*reassoc = false;
+	return true;
+}
+
+/**
+ * wlan_hdd_get_rcpi_cb() - callback function for rcpi response
+ * @context: Pointer to rcpi context
+ * @rcpi_req: Pointer to rcpi response
+ *
+ * Return: None
+ */
+static void wlan_hdd_get_rcpi_cb(void *context, struct qdf_mac_addr mac_addr,
+				 int32_t rcpi, QDF_STATUS status)
+{
+	struct osif_request *request;
+	struct rcpi_info *priv;
+
+	if (!context) {
+		hdd_err("No rcpi context");
+		return;
+	}
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete RCPI request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+	priv->mac_addr = mac_addr;
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		priv->rcpi = 0;
+		hdd_err("Error in computing RCPI");
+	} else {
+		priv->rcpi = rcpi;
+	}
+
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+/**
+ * __wlan_hdd_get_rcpi() - local function to get RCPI
+ * @adapter: adapter upon which the measurement is requested
+ * @mac: peer addr for which measurement is requested
+ * @rcpi_value: pointer to where the RCPI should be returned
+ * @measurement_type: type of rcpi measurement
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int __wlan_hdd_get_rcpi(struct hdd_adapter *adapter,
+			       uint8_t *mac,
+			       int32_t *rcpi_value,
+			       enum rcpi_measurement_type measurement_type)
+{
+	struct hdd_context *hdd_ctx;
+	int status = 0, ret = 0;
+	struct qdf_mac_addr mac_addr;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct sme_rcpi_req *rcpi_req;
+	void *cookie;
+	struct rcpi_info *priv;
+	struct osif_request *request;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_RCPI,
+	};
+	bool reassoc;
+
+	hdd_enter();
+
+	/* initialize the rcpi value to zero, useful in error cases */
+	*rcpi_value = 0;
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (!adapter) {
+		hdd_warn("adapter context is NULL");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status)
+		return -EINVAL;
+
+	if (!hdd_ctx->rcpi_enabled) {
+		hdd_debug("RCPI not supported");
+		return -EINVAL;
+	}
+
+	if (!mac) {
+		hdd_warn("RCPI peer mac-addr is NULL");
+		return -EINVAL;
+	}
+
+	qdf_mem_copy(&mac_addr, mac, QDF_MAC_ADDR_SIZE);
+
+	if (!hdd_is_rcpi_applicable(adapter, &mac_addr, rcpi_value, &reassoc))
+		return -EINVAL;
+	if (reassoc)
+		return 0;
+
+	rcpi_req = qdf_mem_malloc(sizeof(*rcpi_req));
+	if (!rcpi_req)
+		return -EINVAL;
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		qdf_mem_free(rcpi_req);
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	rcpi_req->mac_addr = mac_addr;
+	rcpi_req->session_id = adapter->session_id;
+	rcpi_req->measurement_type = measurement_type;
+	rcpi_req->rcpi_callback = wlan_hdd_get_rcpi_cb;
+	rcpi_req->rcpi_context = cookie;
+
+	qdf_status = sme_get_rcpi(hdd_ctx->mac_handle, rcpi_req);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Unable to retrieve RCPI");
+		status = qdf_status_to_os_return(qdf_status);
+		goto out;
+	}
+
+	/* request was sent -- wait for the response */
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_err("SME timed out while retrieving RCPI");
+		status = -EINVAL;
+		goto out;
+	}
+
+	/* update the adapter with the fresh results */
+	priv = osif_request_priv(request);
+	adapter->rcpi.mac_addr = priv->mac_addr;
+	adapter->rcpi.rcpi = priv->rcpi;
+	if (qdf_mem_cmp(&mac_addr, &priv->mac_addr, sizeof(mac_addr))) {
+		hdd_err("mis match of mac addr from call-back");
+		status = -EINVAL;
+		goto out;
+	}
+
+	*rcpi_value = adapter->rcpi.rcpi;
+	hdd_debug("RCPI = %d", *rcpi_value);
+out:
+	qdf_mem_free(rcpi_req);
+	osif_request_put(request);
+
+	hdd_exit();
+	return status;
+}
+
+int wlan_hdd_get_rcpi(struct hdd_adapter *adapter, uint8_t *mac,
+		      int32_t *rcpi_value,
+		      enum rcpi_measurement_type measurement_type)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_get_rcpi(adapter, mac, rcpi_value, measurement_type);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef QCA_SUPPORT_CP_STATS
+QDF_STATUS wlan_hdd_get_rssi(struct hdd_adapter *adapter, int8_t *rssi_value)
+{
+	int ret = 0, i;
+	struct hdd_station_ctx *sta_ctx;
+	struct stats_event *rssi_info;
+
+	if (NULL == adapter) {
+		hdd_err("Invalid context, adapter");
+		return QDF_STATUS_E_FAULT;
+	}
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
+			cds_get_driver_state());
+		/* return a cached value */
+		*rssi_value = adapter->rssi;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		hdd_debug("Not associated!, rssi on disconnect %d",
+			  adapter->rssi_on_disconnect);
+		*rssi_value = adapter->rssi_on_disconnect;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (sta_ctx->hdd_reassoc_scenario) {
+		hdd_debug("Roaming in progress, return cached RSSI");
+		*rssi_value = adapter->rssi;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	rssi_info = wlan_cfg80211_mc_cp_stats_get_peer_rssi(
+			adapter->vdev,
+			sta_ctx->conn_info.bssId.bytes,
+			&ret);
+	if (ret || !rssi_info) {
+		wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
+		return ret;
+	}
+
+	for (i = 0; i < rssi_info->num_peer_stats; i++) {
+		if (!qdf_mem_cmp(rssi_info->peer_stats[i].peer_macaddr,
+				 sta_ctx->conn_info.bssId.bytes,
+				 WLAN_MACADDR_LEN)) {
+			*rssi_value = rssi_info->peer_stats[i].peer_rssi;
+			hdd_debug("RSSI = %d", *rssi_value);
+			wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
+	hdd_err("bss peer not present in returned result");
+	return QDF_STATUS_E_FAULT;
+}
+#else /* QCA_SUPPORT_CP_STATS */
+struct rssi_priv {
+	int8_t rssi;
+};
+
+/**
+ * hdd_get_rssi_cb() - "Get RSSI" callback function
+ * @rssi: Current RSSI of the station
+ * @sta_id: ID of the station
+ * @context: opaque context originally passed to SME.  HDD always passes
+ *	a cookie for the request context
+ *
+ * Return: None
+ */
+static void hdd_get_rssi_cb(int8_t rssi, uint32_t sta_id, void *context)
+{
+	struct osif_request *request;
+	struct rssi_priv *priv;
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+	priv->rssi = rssi;
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+QDF_STATUS wlan_hdd_get_rssi(struct hdd_adapter *adapter, int8_t *rssi_value)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_station_ctx *sta_ctx;
+	QDF_STATUS status;
+	int ret;
+	void *cookie;
+	struct osif_request *request;
+	struct rssi_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
+
+	if (NULL == adapter) {
+		hdd_err("Invalid context, adapter");
+		return QDF_STATUS_E_FAULT;
+	}
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
+			cds_get_driver_state());
+		/* return a cached value */
+		*rssi_value = adapter->rssi;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		hdd_debug("Not associated!, rssi on disconnect %d",
+			adapter->rssi_on_disconnect);
+		*rssi_value = adapter->rssi_on_disconnect;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (sta_ctx->hdd_reassoc_scenario) {
+		hdd_debug("Roaming in progress, return cached RSSI");
+		*rssi_value = adapter->rssi;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure, return cached RSSI");
+		*rssi_value = adapter->rssi;
+		return QDF_STATUS_SUCCESS;
+	}
+	cookie = osif_request_cookie(request);
+
+	status = sme_get_rssi(hdd_ctx->mac_handle, hdd_get_rssi_cb,
+			      sta_ctx->conn_info.staId[0],
+			      sta_ctx->conn_info.bssId, adapter->rssi,
+			      cookie);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Unable to retrieve RSSI");
+		/* we'll returned a cached value below */
+	} else {
+		/* request was sent -- wait for the response */
+		ret = osif_request_wait_for_response(request);
+		if (ret) {
+			hdd_warn("SME timed out while retrieving RSSI");
+			/* we'll returned a cached value below */
+		} else {
+			/* update the adapter with the fresh results */
+			priv = osif_request_priv(request);
+
+			adapter->rssi = priv->rssi;
+
+			/*
+			 * for new connection there might be no valid previous
+			 * RSSI.
+			 */
+			if (!adapter->rssi) {
+				hdd_get_rssi_snr_by_bssid(adapter,
+					sta_ctx->conn_info.bssId.bytes,
+					&adapter->rssi, NULL);
+			}
+		}
+	}
+
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	osif_request_put(request);
+
+	*rssi_value = adapter->rssi;
+	hdd_debug("RSSI = %d", *rssi_value);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+struct snr_priv {
+	int8_t snr;
+};
+
+/**
+ * hdd_get_snr_cb() - "Get SNR" callback function
+ * @snr: Current SNR of the station
+ * @sta_id: ID of the station
+ * @context: opaque context originally passed to SME.  HDD always passes
+ *	a cookie for the request context
+ *
+ * Return: None
+ */
+static void hdd_get_snr_cb(int8_t snr, uint32_t sta_id, void *context)
+{
+	struct osif_request *request;
+	struct snr_priv *priv;
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	/* propagate response back to requesting thread */
+	priv = osif_request_priv(request);
+	priv->snr = snr;
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+QDF_STATUS wlan_hdd_get_snr(struct hdd_adapter *adapter, int8_t *snr)
+{
+	struct hdd_context *hdd_ctx;
+	struct hdd_station_ctx *sta_ctx;
+	QDF_STATUS status;
+	int ret;
+	void *cookie;
+	struct osif_request *request;
+	struct snr_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
+
+	hdd_enter();
+
+	if (NULL == adapter) {
+		hdd_err("Invalid context, adapter");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return QDF_STATUS_E_FAULT;
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return QDF_STATUS_E_FAULT;
+	}
+	cookie = osif_request_cookie(request);
+
+	status = sme_get_snr(hdd_ctx->mac_handle, hdd_get_snr_cb,
+			     sta_ctx->conn_info.staId[0],
+			     sta_ctx->conn_info.bssId, cookie);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Unable to retrieve RSSI");
+		/* we'll returned a cached value below */
+	} else {
+		/* request was sent -- wait for the response */
+		ret = osif_request_wait_for_response(request);
+		if (ret) {
+			hdd_err("SME timed out while retrieving SNR");
+			/* we'll now returned a cached value below */
+		} else {
+			/* update the adapter with the fresh results */
+			priv = osif_request_priv(request);
+			adapter->snr = priv->snr;
+		}
+	}
+
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	osif_request_put(request);
+
+	*snr = adapter->snr;
+	hdd_exit();
+	return QDF_STATUS_SUCCESS;
+}
+
+struct linkspeed_priv {
+	tSirLinkSpeedInfo linkspeed_info;
+};
+
+static void
+hdd_get_link_speed_cb(tSirLinkSpeedInfo *linkspeed_info, void *context)
+{
+	struct osif_request *request;
+	struct linkspeed_priv *priv;
+
+	if (!linkspeed_info) {
+		hdd_err("NULL linkspeed");
+		return;
+	}
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+	priv->linkspeed_info = *linkspeed_info;
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+int wlan_hdd_get_linkspeed_for_peermac(struct hdd_adapter *adapter,
+				       struct qdf_mac_addr *mac_address,
+				       uint32_t *linkspeed)
+{
+	int ret;
+	QDF_STATUS status;
+	void *cookie;
+	tSirLinkSpeedInfo *linkspeed_info;
+	struct osif_request *request;
+	struct linkspeed_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
+
+	if ((!adapter) || (!linkspeed)) {
+		hdd_err("NULL argument");
+		return -EINVAL;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		ret = -ENOMEM;
+		goto return_cached_value;
+	}
+
+	cookie = osif_request_cookie(request);
+	priv = osif_request_priv(request);
+
+	linkspeed_info = &priv->linkspeed_info;
+	qdf_copy_macaddr(&linkspeed_info->peer_macaddr, mac_address);
+	status = sme_get_link_speed(adapter->hdd_ctx->mac_handle,
+				    linkspeed_info,
+				    cookie, hdd_get_link_speed_cb);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Unable to retrieve statistics for link speed");
+		ret = qdf_status_to_os_return(status);
+		goto cleanup;
+	}
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_err("SME timed out while retrieving link speed");
+		goto cleanup;
+	}
+	adapter->estimated_linkspeed = linkspeed_info->estLinkSpeed;
+
+cleanup:
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	osif_request_put(request);
+
+return_cached_value:
+	*linkspeed = adapter->estimated_linkspeed;
+
+	return ret;
+}
+
+int wlan_hdd_get_link_speed(struct hdd_adapter *adapter, uint32_t *link_speed)
+{
+	struct hdd_context *hddctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_station_ctx *hdd_stactx =
+				WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	int ret;
+
+	ret = wlan_hdd_validate_context(hddctx);
+	if (ret)
+		return ret;
+
+	/* Linkspeed is allowed only for P2P mode */
+	if (adapter->device_mode != QDF_P2P_CLIENT_MODE) {
+		hdd_err("Link Speed is not allowed in Device mode %s(%d)",
+			qdf_opmode_str(adapter->device_mode),
+			adapter->device_mode);
+		return -ENOTSUPP;
+	}
+
+	if (eConnectionState_Associated != hdd_stactx->conn_info.connState) {
+		/* we are not connected so we don't have a classAstats */
+		*link_speed = 0;
+	} else {
+		struct qdf_mac_addr bssid;
+
+		qdf_copy_macaddr(&bssid, &hdd_stactx->conn_info.bssId);
+
+		ret = wlan_hdd_get_linkspeed_for_peermac(adapter, &bssid,
+							 link_speed);
+		if (ret) {
+			hdd_err("Unable to retrieve SME linkspeed");
+			return ret;
+		}
+		/* linkspeed in units of 500 kbps */
+		*link_speed = (*link_speed) / 500;
+	}
+	return 0;
+}
+
+struct peer_rssi_priv {
+	struct sir_peer_sta_info peer_sta_info;
+};
+
+/**
+ * hdd_get_peer_rssi_cb() - get peer station's rssi callback
+ * @sta_rssi: pointer of peer information
+ * @context: get rssi callback context
+ *
+ * This function will fill rssi information to rssi priv
+ * adapter
+ *
+ */
+static void hdd_get_peer_rssi_cb(struct sir_peer_info_resp *sta_rssi,
+				 void *context)
+{
+	struct osif_request *request;
+	struct peer_rssi_priv *priv;
+	struct sir_peer_info *rssi_info;
+	uint8_t peer_num;
+
+	if ((!sta_rssi)) {
+		hdd_err("Bad param, sta_rssi [%pK]", sta_rssi);
+		return;
+	}
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+
+	peer_num = sta_rssi->count;
+	rssi_info = sta_rssi->info;
+
+	hdd_debug("%d peers", peer_num);
+
+	if (peer_num > MAX_PEER_STA) {
+		hdd_warn("Exceed max peer sta to handle one time %d", peer_num);
+		peer_num = MAX_PEER_STA;
+	}
+
+	qdf_mem_copy(priv->peer_sta_info.info, rssi_info,
+		     peer_num * sizeof(*rssi_info));
+	priv->peer_sta_info.sta_num = peer_num;
+
+	osif_request_complete(request);
+	osif_request_put(request);
+
+}
+
+int wlan_hdd_get_peer_rssi(struct hdd_adapter *adapter,
+			   struct qdf_mac_addr *macaddress,
+			   struct sir_peer_sta_info *peer_sta_info)
+{
+	QDF_STATUS status;
+	void *cookie;
+	int ret;
+	struct sir_peer_info_req rssi_req;
+	struct osif_request *request;
+	struct peer_rssi_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
+
+	if (!adapter || !macaddress || !peer_sta_info) {
+		hdd_err("adapter [%pK], macaddress [%pK], peer_sta_info[%pK]",
+			adapter, macaddress, peer_sta_info);
+		return -EFAULT;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+
+	cookie = osif_request_cookie(request);
+	priv = osif_request_priv(request);
+
+	qdf_mem_copy(&rssi_req.peer_macaddr, macaddress,
+		     QDF_MAC_ADDR_SIZE);
+	rssi_req.sessionid = adapter->session_id;
+	status = sme_get_peer_info(adapter->hdd_ctx->mac_handle,
+				   rssi_req,
+				   cookie,
+				   hdd_get_peer_rssi_cb);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Unable to retrieve statistics for rssi");
+		ret = -EFAULT;
+	} else {
+		ret = osif_request_wait_for_response(request);
+		if (ret) {
+			hdd_err("SME timed out while retrieving rssi");
+			ret = -EFAULT;
+		} else {
+			*peer_sta_info = priv->peer_sta_info;
+			ret = 0;
+		}
+	}
+
+	osif_request_put(request);
+
+	return ret;
+}
+
+struct peer_info_priv {
+	struct sir_peer_sta_ext_info peer_sta_ext_info;
+};
+
+/**
+ * wlan_hdd_get_peer_info_cb() - get peer info callback
+ * @sta_info: pointer of peer information
+ * @context: get peer info callback context
+ *
+ * This function will fill stats info to peer info priv
+ *
+ */
+static void wlan_hdd_get_peer_info_cb(struct sir_peer_info_ext_resp *sta_info,
+				      void *context)
+{
+	struct osif_request *request;
+	struct peer_info_priv *priv;
+	uint8_t sta_num;
+
+	if ((!sta_info) || (!context)) {
+		hdd_err("Bad param, sta_info [%pK] context [%pK]",
+			sta_info, context);
+		return;
+	}
+
+	if (!sta_info->count) {
+		hdd_err("Fail to get remote peer info");
+		return;
+	}
+
+	if (sta_info->count > MAX_PEER_STA) {
+		hdd_warn("Exceed max peer number %d", sta_info->count);
+		sta_num = MAX_PEER_STA;
+	} else {
+		sta_num = sta_info->count;
+	}
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+
+	priv->peer_sta_ext_info.sta_num = sta_num;
+	qdf_mem_copy(&priv->peer_sta_ext_info.info,
+		     sta_info->info,
+		     sta_num * sizeof(sta_info->info[0]));
+
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+int wlan_hdd_get_peer_info(struct hdd_adapter *adapter,
+			   struct qdf_mac_addr macaddress,
+			   struct sir_peer_info_ext *peer_info_ext)
+{
+	QDF_STATUS status;
+	void *cookie;
+	int ret;
+	struct sir_peer_info_ext_req peer_info_req;
+	struct osif_request *request;
+	struct peer_info_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
+
+	if (!adapter) {
+		hdd_err("adapter is NULL");
+		return -EFAULT;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+
+	cookie = osif_request_cookie(request);
+	priv = osif_request_priv(request);
+
+	qdf_mem_copy(&peer_info_req.peer_macaddr, &macaddress,
+		     QDF_MAC_ADDR_SIZE);
+	peer_info_req.sessionid = adapter->session_id;
+	peer_info_req.reset_after_request = 0;
+	status = sme_get_peer_info_ext(adapter->hdd_ctx->mac_handle,
+				       &peer_info_req,
+				       cookie,
+				       wlan_hdd_get_peer_info_cb);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Unable to retrieve statistics for peer info");
+		ret = -EFAULT;
+	} else {
+		ret = osif_request_wait_for_response(request);
+		if (ret) {
+			hdd_err("SME timed out while retrieving peer info");
+			ret = -EFAULT;
+		} else {
+			/* only support one peer by now */
+			*peer_info_ext = priv->peer_sta_ext_info.info[0];
+			ret = 0;
+		}
+	}
+
+	osif_request_put(request);
+
+	return ret;
+}
+
+#ifndef QCA_SUPPORT_CP_STATS
+struct class_a_stats {
+	tCsrGlobalClassAStatsInfo class_a_stats;
+};
+
+/**
+ * hdd_get_class_a_statistics_cb() - Get Class A stats callback function
+ * @stats: pointer to Class A stats
+ * @context: user context originally registered with SME (always the
+ *	cookie from the request context)
+ *
+ * Return: None
+ */
+static void hdd_get_class_a_statistics_cb(void *stats, void *context)
+{
+	struct osif_request *request;
+	struct class_a_stats *priv;
+	tCsrGlobalClassAStatsInfo *returned_stats;
+
+	hdd_enter();
+	if (NULL == stats) {
+		hdd_err("Bad param, stats");
+		return;
+	}
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	returned_stats = stats;
+	priv = osif_request_priv(request);
+	priv->class_a_stats = *returned_stats;
+	osif_request_complete(request);
+	osif_request_put(request);
+	hdd_exit();
+}
+
+QDF_STATUS wlan_hdd_get_class_astats(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	QDF_STATUS status;
+	int ret;
+	void *cookie;
+	struct osif_request *request;
+	struct class_a_stats *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
+
+	if (NULL == adapter) {
+		hdd_err("adapter is NULL");
+		return QDF_STATUS_E_FAULT;
+	}
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
+		hdd_debug("Recovery in Progress. State: 0x%x Ignore!!!",
+			 cds_get_driver_state());
+		return QDF_STATUS_SUCCESS;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return QDF_STATUS_E_NOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	/* query only for Class A statistics (which include link speed) */
+	status = sme_get_statistics(adapter->hdd_ctx->mac_handle,
+				    eCSR_HDD, SME_GLOBAL_CLASSA_STATS,
+				    hdd_get_class_a_statistics_cb,
+				    sta_ctx->conn_info.staId[0],
+				    cookie, adapter->session_id);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_warn("Unable to retrieve Class A statistics");
+		goto return_cached_results;
+	}
+
+	/* request was sent -- wait for the response */
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_warn("SME timed out while retrieving Class A statistics");
+		goto return_cached_results;
+	}
+
+	/* update the adapter with the fresh results */
+	priv = osif_request_priv(request);
+	adapter->hdd_stats.class_a_stat = priv->class_a_stats;
+
+return_cached_results:
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	osif_request_put(request);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef QCA_SUPPORT_CP_STATS
+int wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
+{
+	int ret = 0;
+	uint8_t mcs_rate_flags;
+	struct stats_event *stats;
+
+	stats = wlan_cfg80211_mc_cp_stats_get_station_stats(adapter->vdev,
+							    &ret);
+	if (ret || !stats) {
+		wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
+		return ret;
+	}
+
+	/* save summary stats to legacy location */
+	qdf_mem_copy(adapter->hdd_stats.summary_stat.retry_cnt,
+		stats->vdev_summary_stats[0].stats.retry_cnt,
+		sizeof(adapter->hdd_stats.summary_stat.retry_cnt));
+	qdf_mem_copy(adapter->hdd_stats.summary_stat.multiple_retry_cnt,
+		stats->vdev_summary_stats[0].stats.multiple_retry_cnt,
+		sizeof(adapter->hdd_stats.summary_stat.multiple_retry_cnt));
+	qdf_mem_copy(adapter->hdd_stats.summary_stat.tx_frm_cnt,
+		stats->vdev_summary_stats[0].stats.tx_frm_cnt,
+		sizeof(adapter->hdd_stats.summary_stat.tx_frm_cnt));
+	qdf_mem_copy(adapter->hdd_stats.summary_stat.fail_cnt,
+		stats->vdev_summary_stats[0].stats.fail_cnt,
+		sizeof(adapter->hdd_stats.summary_stat.fail_cnt));
+	adapter->hdd_stats.summary_stat.snr =
+		stats->vdev_summary_stats[0].stats.snr;
+	adapter->hdd_stats.summary_stat.rssi =
+		stats->vdev_summary_stats[0].stats.rssi;
+	adapter->hdd_stats.summary_stat.rx_frm_cnt =
+		stats->vdev_summary_stats[0].stats.rx_frm_cnt;
+	adapter->hdd_stats.summary_stat.frm_dup_cnt =
+		stats->vdev_summary_stats[0].stats.frm_dup_cnt;
+	adapter->hdd_stats.summary_stat.rts_fail_cnt =
+		stats->vdev_summary_stats[0].stats.rts_fail_cnt;
+	adapter->hdd_stats.summary_stat.ack_fail_cnt =
+		stats->vdev_summary_stats[0].stats.ack_fail_cnt;
+	adapter->hdd_stats.summary_stat.rts_succ_cnt =
+		stats->vdev_summary_stats[0].stats.rts_succ_cnt;
+	adapter->hdd_stats.summary_stat.rx_discard_cnt =
+		stats->vdev_summary_stats[0].stats.rx_discard_cnt;
+	adapter->hdd_stats.summary_stat.rx_error_cnt =
+		stats->vdev_summary_stats[0].stats.rx_error_cnt;
+
+	/* save class a stats to legacy location */
+	adapter->hdd_stats.class_a_stat.tx_nss =
+		wlan_vdev_mlme_get_nss(adapter->vdev);
+	adapter->hdd_stats.class_a_stat.tx_rate = stats->tx_rate;
+	adapter->hdd_stats.class_a_stat.rx_rate = stats->rx_rate;
+	adapter->hdd_stats.class_a_stat.tx_rx_rate_flags = stats->tx_rate_flags;
+	adapter->hdd_stats.class_a_stat.tx_mcs_index =
+		sme_get_mcs_idx(stats->tx_rate * 5, stats->tx_rate_flags,
+				&adapter->hdd_stats.class_a_stat.tx_nss,
+				&mcs_rate_flags);
+	adapter->hdd_stats.class_a_stat.tx_mcs_rate_flags = mcs_rate_flags;
+	adapter->hdd_stats.class_a_stat.rx_mcs_index =
+		sme_get_mcs_idx(stats->rx_rate * 5, stats->tx_rate_flags,
+				&adapter->hdd_stats.class_a_stat.rx_nss,
+				&mcs_rate_flags);
+	adapter->hdd_stats.class_a_stat.rx_mcs_rate_flags = mcs_rate_flags;
+
+	/* save per chain rssi to legacy location */
+	qdf_mem_copy(adapter->hdd_stats.per_chain_rssi_stats.rssi,
+		     stats->vdev_chain_rssi[0].chain_rssi,
+		     sizeof(stats->vdev_chain_rssi[0].chain_rssi));
+	wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
+
+	return 0;
+}
+#else /* QCA_SUPPORT_CP_STATS */
+struct station_stats {
+	tCsrSummaryStatsInfo summary_stats;
+	tCsrGlobalClassAStatsInfo class_a_stats;
+	struct csr_per_chain_rssi_stats_info per_chain_rssi_stats;
+};
+
+/**
+ * hdd_get_station_statistics_cb() - Get stats callback function
+ * @stats: pointer to combined station stats
+ * @context: user context originally registered with SME (always the
+ *	cookie from the request context)
+ *
+ * Return: None
+ */
+static void hdd_get_station_statistics_cb(void *stats, void *context)
+{
+	struct osif_request *request;
+	struct station_stats *priv;
+	tCsrSummaryStatsInfo *summary_stats;
+	tCsrGlobalClassAStatsInfo *class_a_stats;
+	struct csr_per_chain_rssi_stats_info *per_chain_rssi_stats;
+
+	if ((NULL == stats) || (NULL == context)) {
+		hdd_err("Bad param, pStats [%pK] pContext [%pK]",
+			stats, context);
+		return;
+	}
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	summary_stats = (tCsrSummaryStatsInfo *) stats;
+	class_a_stats = (tCsrGlobalClassAStatsInfo *) (summary_stats + 1);
+	per_chain_rssi_stats = (struct csr_per_chain_rssi_stats_info *)
+				(class_a_stats + 1);
+	priv = osif_request_priv(request);
+
+	/* copy over the stats. do so as a struct copy */
+	priv->summary_stats = *summary_stats;
+	priv->class_a_stats = *class_a_stats;
+	priv->per_chain_rssi_stats = *per_chain_rssi_stats;
+
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+int wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	QDF_STATUS status;
+	int errno;
+	void *cookie;
+	struct osif_request *request;
+	struct station_stats *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
+
+	if (NULL == adapter) {
+		hdd_err("adapter is NULL");
+		return 0;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	/* query only for Summary & Class A statistics */
+	status = sme_get_statistics(adapter->hdd_ctx->mac_handle,
+				    eCSR_HDD,
+				    SME_SUMMARY_STATS |
+					    SME_GLOBAL_CLASSA_STATS |
+					    SME_PER_CHAIN_RSSI_STATS,
+				    hdd_get_station_statistics_cb,
+				    sta_ctx->conn_info.staId[0],
+				    cookie,
+				    adapter->session_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to retrieve statistics, status %d", status);
+		goto put_request;
+	}
+
+	/* request was sent -- wait for the response */
+	errno = osif_request_wait_for_response(request);
+	if (errno) {
+		hdd_err("Failed to wait for statistics, errno %d", errno);
+		goto put_request;
+	}
+
+	/* update the adapter with the fresh results */
+	priv = osif_request_priv(request);
+	adapter->hdd_stats.summary_stat = priv->summary_stats;
+	adapter->hdd_stats.class_a_stat = priv->class_a_stats;
+	adapter->hdd_stats.per_chain_rssi_stats = priv->per_chain_rssi_stats;
+
+put_request:
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	osif_request_put(request);
+
+	/* either callback updated adapter stats or it has cached data */
+	return 0;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+struct temperature_priv {
+	int temperature;
+};
+
+/**
+ * hdd_get_temperature_cb() - "Get Temperature" callback function
+ * @temperature: measured temperature
+ * @context: callback context
+ *
+ * This function is passed to sme_get_temperature() as the callback
+ * function to be invoked when the temperature measurement is
+ * available.
+ *
+ * Return: None
+ */
+static void hdd_get_temperature_cb(int temperature, void *context)
+{
+	struct osif_request *request;
+	struct temperature_priv *priv;
+
+	hdd_enter();
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+	priv->temperature = temperature;
+	osif_request_complete(request);
+	osif_request_put(request);
+	hdd_exit();
+}
+
+int wlan_hdd_get_temperature(struct hdd_adapter *adapter, int *temperature)
+{
+	QDF_STATUS status;
+	int ret;
+	void *cookie;
+	struct osif_request *request;
+	struct temperature_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
+
+	hdd_enter();
+	if (NULL == adapter) {
+		hdd_err("adapter is NULL");
+		return -EPERM;
+	}
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+	status = sme_get_temperature(adapter->hdd_ctx->mac_handle, cookie,
+				     hdd_get_temperature_cb);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Unable to retrieve temperature");
+	} else {
+		ret = osif_request_wait_for_response(request);
+		if (ret) {
+			hdd_err("SME timed out while retrieving temperature");
+		} else {
+			/* update the adapter with the fresh results */
+			priv = osif_request_priv(request);
+			if (priv->temperature)
+				adapter->temperature = priv->temperature;
+		}
+	}
+
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	osif_request_put(request);
+
+	*temperature = adapter->temperature;
+	hdd_exit();
+	return 0;
+}
+
+void wlan_hdd_display_txrx_stats(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter = NULL;
+	struct hdd_tx_rx_stats *stats;
+	int i = 0;
+	uint32_t total_rx_pkt, total_rx_dropped,
+		 total_rx_delv, total_rx_refused;
+
+	hdd_for_each_adapter(hdd_ctx, adapter) {
+		total_rx_pkt = 0;
+		total_rx_dropped = 0;
+		total_rx_delv = 0;
+		total_rx_refused = 0;
+		stats = &adapter->hdd_stats.tx_rx_stats;
+		hdd_debug("adapter: %u", adapter->session_id);
+		for (; i < NUM_CPUS; i++) {
+			total_rx_pkt += stats->rx_packets[i];
+			total_rx_dropped += stats->rx_dropped[i];
+			total_rx_delv += stats->rx_delivered[i];
+			total_rx_refused += stats->rx_refused[i];
+		}
+
+		hdd_debug("Total Transmit - called %u, dropped %u orphan %u",
+			  stats->tx_called, stats->tx_dropped,
+			  stats->tx_orphaned);
+
+		for (i = 0; i < NUM_CPUS; i++) {
+			if (stats->rx_packets[i] == 0)
+				continue;
+			hdd_debug("Rx CPU[%d]: packets %u, dropped %u, delivered %u, refused %u",
+				  i, stats->rx_packets[i], stats->rx_dropped[i],
+				  stats->rx_delivered[i], stats->rx_refused[i]);
+		}
+		hdd_debug("Total Receive - packets %u, dropped %u, delivered %u, refused %u",
+			  total_rx_pkt, total_rx_dropped, total_rx_delv,
+			  total_rx_refused);
+	}
+}
diff --git a/core/hdd/src/wlan_hdd_stats.h b/core/hdd/src/wlan_hdd_stats.h
new file mode 100644
index 0000000..4fc80c9
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_stats.h
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2012-2018 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 : wlan_hdd_stats.h
+ *
+ * WLAN Host Device Driver statistics related implementation
+ *
+ */
+
+#if !defined(WLAN_HDD_STATS_H)
+#define WLAN_HDD_STATS_H
+
+#include "wlan_hdd_main.h"
+
+#define INVALID_MCS_IDX 255
+#define MAX_HT_MCS_IDX 8
+#define MAX_VHT_MCS_IDX 10
+
+#define DATA_RATE_11AC_MCS_MASK    0x03
+
+/* LL stats get request time out value */
+#define WLAN_WAIT_TIME_LL_STATS 800
+
+#define WLAN_HDD_TGT_NOISE_FLOOR_DBM     (-96)
+
+/**
+ * struct index_vht_data_rate_type - vht data rate type
+ * @beacon_rate_index: Beacon rate index
+ * @supported_VHT80_rate: VHT80 rate
+ * @supported_VHT40_rate: VHT40 rate
+ * @supported_VHT20_rate: VHT20 rate
+ */
+struct index_vht_data_rate_type {
+	uint8_t beacon_rate_index;
+	uint16_t supported_VHT80_rate[2];
+	uint16_t supported_VHT40_rate[2];
+	uint16_t supported_VHT20_rate[2];
+};
+
+/**
+ * enum - data_rate_11ac_max_mcs
+ * @DATA_RATE_11AC_MAX_MCS_7: MCS7 rate
+ * @DATA_RATE_11AC_MAX_MCS_8: MCS8 rate
+ * @DATA_RATE_11AC_MAX_MCS_9: MCS9 rate
+ * @DATA_RATE_11AC_MAX_MCS_NA:i Not applicable
+ */
+enum data_rate_11ac_max_mcs {
+	DATA_RATE_11AC_MAX_MCS_7,
+	DATA_RATE_11AC_MAX_MCS_8,
+	DATA_RATE_11AC_MAX_MCS_9,
+	DATA_RATE_11AC_MAX_MCS_NA
+};
+
+/**
+ * struct index_data_rate_type - non vht data rate type
+ * @beacon_rate_index: Beacon rate index
+ * @supported_rate: Supported rate table
+ */
+struct index_data_rate_type {
+	uint8_t beacon_rate_index;
+	uint16_t supported_rate[4];
+};
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+
+/**
+ * wlan_hdd_cfg80211_ll_stats_set() - set link layer stats
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: int
+ */
+int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data,
+				   int data_len);
+
+/**
+ * wlan_hdd_cfg80211_ll_stats_get() - get link layer stats
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: int
+ */
+int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
+				   struct wireless_dev *wdev,
+				   const void *data,
+				   int data_len);
+
+
+/**
+ * wlan_hdd_cfg80211_ll_stats_clear() - clear link layer stats
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: int
+ */
+int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     const void *data,
+				     int data_len);
+
+void wlan_hdd_clear_link_layer_stats(struct hdd_adapter *adapter);
+
+static inline bool hdd_link_layer_stats_supported(void)
+{
+	return true;
+}
+
+/**
+ * __wlan_hdd_cfg80211_ll_stats_ext_set_param - config monitor parameters
+ * @wiphy: wiphy handle
+ * @wdev: wdev handle
+ * @data: user layer input
+ * @data_len: length of user layer input
+ *
+ * return: 0 success, einval failure
+ */
+int wlan_hdd_cfg80211_ll_stats_ext_set_param(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data,
+					     int data_len);
+/**
+ * hdd_get_interface_info() - get interface info
+ * @adapter: Pointer to device adapter
+ * @info: Pointer to interface info
+ *
+ * Return: bool
+ */
+bool hdd_get_interface_info(struct hdd_adapter *adapter,
+			    tpSirWifiInterfaceInfo info);
+
+/**
+ * wlan_hdd_ll_stats_get() - Get Link Layer statistics from FW
+ * @adapter: Pointer to device adapter
+ * @req_id: request id
+ * @req_mask: bitmask used by FW for the request
+ *
+ * Return: 0 on success and error code otherwise
+ */
+int wlan_hdd_ll_stats_get(struct hdd_adapter *adapter, uint32_t req_id,
+			  uint32_t req_mask);
+
+/**
+ * wlan_hdd_cfg80211_link_layer_stats_callback() - This function is called
+ * @hdd_handle: Handle to HDD context
+ * @indication_type: Indication type
+ * @results: Pointer to results
+ * @cookie: Callback context
+ *
+ * After receiving Link Layer indications from FW.This callback converts the
+ * firmware data to the NL data and send the same to the kernel/upper layers.
+ *
+ * Return: None
+ */
+void wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle,
+						 int indication_type,
+						 tSirLLStatsResults *results,
+						 void *cookie);
+
+/**
+ * wlan_hdd_cfg80211_link_layer_stats_ext_callback() - Callback for LL ext
+ * @ctx: HDD context
+ * @rsp: msg from FW
+ *
+ * This function is an extension of
+ * wlan_hdd_cfg80211_link_layer_stats_callback. It converts
+ * monitoring parameters offloaded to NL data and send the same to the
+ * kernel/upper layers.
+ *
+ * Return: None.
+ */
+void wlan_hdd_cfg80211_link_layer_stats_ext_callback(hdd_handle_t ctx,
+						     tSirLLStatsResults *rsp);
+
+/**
+ * hdd_lost_link_info_cb() - callback function to get lost link information
+ * @hdd_handle: Opaque handle for the HDD context
+ * @lost_link_info: lost link information
+ *
+ * Return: none
+ */
+void hdd_lost_link_info_cb(hdd_handle_t hdd_handle,
+			   struct sir_lost_link_info *lost_link_info);
+
+#else /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+static inline bool hdd_link_layer_stats_supported(void)
+{
+	return false;
+}
+
+static inline int
+wlan_hdd_cfg80211_ll_stats_ext_set_param(struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 const void *data,
+					 int data_len)
+{
+	return -EINVAL;
+}
+
+static inline int
+wlan_hdd_ll_stats_get(struct hdd_adapter *adapter, uint32_t req_id,
+		      uint32_t req_mask)
+{
+	return -EINVAL;
+}
+
+static inline void
+wlan_hdd_clear_link_layer_stats(struct hdd_adapter *adapter)
+{
+}
+
+static inline void
+wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle,
+					    int indication_type,
+					    tSirLLStatsResults *results,
+					    void *cookie)
+{
+}
+
+static inline void
+wlan_hdd_cfg80211_link_layer_stats_ext_callback(hdd_handle_t ctx,
+						tSirLLStatsResults *rsp)
+{
+}
+
+static inline void
+hdd_lost_link_info_cb(hdd_handle_t hdd_handle,
+		      struct sir_lost_link_info *lost_link_info)
+{
+}
+
+#endif /* End of WLAN_FEATURE_LINK_LAYER_STATS */
+
+#ifdef WLAN_FEATURE_STATS_EXT
+/**
+ * wlan_hdd_cfg80211_stats_ext_request() - ext stats request
+ * @wiphy: Pointer to wiphy
+ * @wdev: Pointer to wdev
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: int
+ */
+int wlan_hdd_cfg80211_stats_ext_request(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len);
+
+#endif /* End of WLAN_FEATURE_STATS_EXT */
+
+/**
+ * wlan_hdd_cfg80211_get_station() - get station statistics
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @mac: Pointer to mac
+ * @sinfo: Pointer to station info
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
+				  struct net_device *dev, const uint8_t *mac,
+				  struct station_info *sinfo);
+#else
+int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
+				  struct net_device *dev, uint8_t *mac,
+				  struct station_info *sinfo);
+#endif
+
+/**
+ * wlan_hdd_cfg80211_dump_station() - dump station statistics
+ * @wiphy: Pointer to wiphy
+ * @dev: Pointer to network device
+ * @idx: variable to determine whether to get stats or not
+ * @mac: Pointer to mac
+ * @sinfo: Pointer to station info
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_cfg80211_dump_station(struct wiphy *wiphy,
+				struct net_device *dev,
+				int idx, u8 *mac,
+				struct station_info *sinfo);
+
+struct net_device_stats *hdd_get_stats(struct net_device *dev);
+
+int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
+				  struct net_device *dev,
+				  int idx, struct survey_info *survey);
+
+void hdd_display_hif_stats(void);
+void hdd_clear_hif_stats(void);
+
+/**
+ * wlan_hdd_cfg80211_stats_ext_callback() - ext stats callback
+ * @hdd_handle: Opaque handle to HDD context
+ * @data: ext stats payload
+ *
+ * Return: nothing
+ */
+void wlan_hdd_cfg80211_stats_ext_callback(hdd_handle_t hdd_handle,
+					  struct stats_ext_event *data);
+
+/**
+ * wlan_hdd_cfg80211_stats_ext2_callback() - stats_ext2_callback
+ * @hdd_handle: opaque handle to the hdd context
+ * @pmsg: sir_sme_rx_aggr_hole_ind
+ *
+ * Return: void
+ */
+void
+wlan_hdd_cfg80211_stats_ext2_callback(hdd_handle_t hdd_handle,
+				      struct sir_sme_rx_aggr_hole_ind *pmsg);
+
+/**
+ * wlan_hdd_get_rcpi() - Wrapper to get current RCPI
+ * @adapter: adapter upon which the measurement is requested
+ * @mac: peer addr for which measurement is requested
+ * @rcpi_value: pointer to where the RCPI should be returned
+ * @measurement_type: type of rcpi measurement
+ *
+ * This is a wrapper function for getting RCPI, invoke this function only
+ * when rcpi support is enabled in firmware
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+int wlan_hdd_get_rcpi(struct hdd_adapter *adapter, uint8_t *mac,
+		      int32_t *rcpi_value,
+		      enum rcpi_measurement_type measurement_type);
+
+/**
+ * wlan_hdd_get_rssi() - Get the current RSSI
+ * @adapter: adapter upon which the measurement is requested
+ * @rssi_value: pointer to where the RSSI should be returned
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wlan_hdd_get_rssi(struct hdd_adapter *adapter, int8_t *rssi_value);
+
+/**
+ * wlan_hdd_get_snr() - Get the current SNR
+ * @adapter: adapter upon which the measurement is requested
+ * @snr: pointer to where the SNR should be returned
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wlan_hdd_get_snr(struct hdd_adapter *adapter, int8_t *snr);
+
+/**
+ * wlan_hdd_get_linkspeed_for_peermac() - Get link speed for a peer
+ * @adapter: adapter upon which the peer is active
+ * @mac_address: MAC address of the peer
+ * @linkspeed: pointer to memory where returned link speed is to be placed
+ *
+ * This function will send a query to SME for the linkspeed of the
+ * given peer, and then wait for the callback to be invoked.
+ *
+ * Return: 0 if linkspeed data is available, negative errno otherwise
+ */
+int wlan_hdd_get_linkspeed_for_peermac(struct hdd_adapter *adapter,
+				       struct qdf_mac_addr *mac_address,
+				       uint32_t *linkspeed);
+
+/**
+ * wlan_hdd_get_link_speed() - get link speed
+ * @adapter:     pointer to the adapter
+ * @link_speed:   pointer to link speed
+ *
+ * This function fetches per bssid link speed.
+ *
+ * Return: if associated, link speed shall be returned.
+ *         if not associated, link speed of 0 is returned.
+ *         On error, error number will be returned.
+ */
+int wlan_hdd_get_link_speed(struct hdd_adapter *adapter, uint32_t *link_speed);
+
+/**
+ * wlan_hdd_get_peer_rssi() - get station's rssi
+ * @adapter: hostapd interface
+ * @macaddress: peer sta mac address or ff:ff:ff:ff:ff:ff to query all peer
+ * @peer_sta_info: output pointer which will fill by peer sta info
+ *
+ * This function will call sme_get_peer_info to get rssi
+ *
+ * Return: 0 on success, otherwise error value
+ */
+int wlan_hdd_get_peer_rssi(struct hdd_adapter *adapter,
+			   struct qdf_mac_addr *macaddress,
+			   struct sir_peer_sta_info *peer_sta_info);
+
+/**
+ * wlan_hdd_get_peer_info() - get peer info
+ * @adapter: hostapd interface
+ * @macaddress: request peer mac address
+ * @peer_info_ext: one peer extended info retrieved
+ *
+ * This function will call sme_get_peer_info_ext to get peer info
+ *
+ * Return: 0 on success, otherwise error value
+ */
+int wlan_hdd_get_peer_info(struct hdd_adapter *adapter,
+			   struct qdf_mac_addr macaddress,
+			   struct sir_peer_info_ext *peer_info_ext);
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * wlan_hdd_get_class_astats() - Get Class A statistics
+ * @adapter: adapter for which statistics are desired
+ *
+ * Return: QDF_STATUS_SUCCESS if adapter's Class A statistics were updated
+ */
+QDF_STATUS wlan_hdd_get_class_astats(struct hdd_adapter *adapter);
+#endif
+
+/**
+ * wlan_hdd_get_station_stats() - Get station statistics
+ * @adapter: adapter for which statistics are desired
+ *
+ * Return: status of operation
+ */
+int wlan_hdd_get_station_stats(struct hdd_adapter *adapter);
+
+/**
+ * wlan_hdd_get_temperature() - get current device temperature
+ * @adapter: device upon which the request was made
+ * @temperature: pointer to where the temperature is to be returned
+ *
+ * Return: 0 if a temperature value (either current or cached) was
+ * returned, otherwise a negative errno is returned.
+ *
+ */
+int wlan_hdd_get_temperature(struct hdd_adapter *adapter, int *temperature);
+
+/**
+ * wlan_hdd_request_station_stats() - Get station statistics
+ * @adapter: adapter for which statistics are desired
+ *
+ * Return: QDF_STATUS_SUCCESS if adapter's statistics were updated
+ */
+int wlan_hdd_request_station_stats(struct hdd_adapter *adapter);
+
+/**
+ * wlan_hdd_display_txrx_stats() - display HDD txrx stats summary
+ * @hdd_ctx: hdd context
+ *
+ * Display TXRX Stats for all adapters
+ *
+ * Return: none
+ */
+void wlan_hdd_display_txrx_stats(struct hdd_context *hdd_ctx);
+#endif /* end #if !defined(WLAN_HDD_STATS_H) */
diff --git a/core/hdd/src/wlan_hdd_subnet_detect.c b/core/hdd/src/wlan_hdd_subnet_detect.c
new file mode 100644
index 0000000..ae2d2b8
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_subnet_detect.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2015-2018 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: wlan_hdd_subnet_detect.c
+ *
+ * WLAN Host Device Driver subnet detect API implementation
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <net/cfg80211.h>
+#include <ani_global.h>
+#include "sme_api.h"
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_subnet_detect.h"
+#include <qca_vendor.h>
+
+/*
+ * define short names for the global vendor params
+ * used by __wlan_hdd_cfg80211_set_gateway_params()
+ */
+#define PARAM_MAC_ADDR QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_GW_MAC_ADDR
+#define PARAM_IPV4_ADDR QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV4_ADDR
+#define PARAM_IPV6_ADDR QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV6_ADDR
+
+static const struct nla_policy
+	policy[QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_MAX + 1] = {
+		[PARAM_MAC_ADDR] = {
+				.type = NLA_UNSPEC,
+				.len = QDF_MAC_ADDR_SIZE
+		},
+		[PARAM_IPV4_ADDR] = {
+				.type = NLA_UNSPEC,
+				.len = QDF_IPV4_ADDR_SIZE
+		},
+		[PARAM_IPV6_ADDR] = {
+				.type = NLA_UNSPEC,
+				.len = QDF_IPV6_ADDR_SIZE
+		}
+};
+
+/**
+ * __wlan_hdd_cfg80211_set_gateway_params() - set gateway params
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_set_gateway_params(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_MAX + 1];
+	struct gateway_param_update_req req = { 0 };
+	int ret;
+	QDF_STATUS status;
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	/* user may have disabled the feature in INI */
+	if (!hdd_ctx->config->enable_lfr_subnet_detection) {
+		hdd_info("LFR Subnet Detection disabled in INI");
+		return -ENOTSUPP;
+	}
+
+	/* The gateway parameters are only valid in the STA persona
+	 * and only in the connected state.
+	 */
+	if (QDF_STA_MODE != adapter->device_mode) {
+		hdd_err("Received GW param update for non-STA mode adapter");
+		return -ENOTSUPP;
+	}
+
+	if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
+		hdd_err("Received GW param update in disconnected state!");
+		return -ENOTSUPP;
+	}
+
+	/* Extract NL parameters
+	 * mac_addr:  6 bytes
+	 * ipv4 addr: 4 bytes
+	 * ipv6 addr: 16 bytes
+	 */
+	if (wlan_cfg80211_nla_parse(tb,
+				    QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_MAX,
+				    data, data_len, policy)) {
+		hdd_err("Invalid ATTR list");
+		return -EINVAL;
+	}
+
+	if (!tb[PARAM_MAC_ADDR]) {
+		hdd_err("request mac addr failed");
+		return -EINVAL;
+	}
+	nla_memcpy(req.gw_mac_addr.bytes, tb[PARAM_MAC_ADDR],
+			QDF_MAC_ADDR_SIZE);
+
+	/* req ipv4_addr_type and ipv6_addr_type are initially false due
+	 * to zeroing the struct
+	 */
+	if (tb[PARAM_IPV4_ADDR]) {
+		nla_memcpy(req.ipv4_addr, tb[PARAM_IPV4_ADDR],
+			QDF_IPV4_ADDR_SIZE);
+		req.ipv4_addr_type = true;
+	}
+
+	if (tb[PARAM_IPV6_ADDR]) {
+		nla_memcpy(&req.ipv6_addr, tb[PARAM_IPV6_ADDR],
+			QDF_IPV6_ADDR_SIZE);
+		req.ipv6_addr_type = true;
+	}
+
+	if (!req.ipv4_addr_type && !req.ipv6_addr_type) {
+		hdd_err("invalid ipv4 or ipv6 gateway address");
+		return -EINVAL;
+	}
+
+	req.max_retries = 3;
+	req.timeout = 100;   /* in milliseconds */
+	req.session_id = adapter->session_id;
+
+	hdd_debug("Configuring gateway for session %d", req.session_id);
+	hdd_debug("mac:%pM, ipv4:%pI4 (type %d), ipv6:%pI6c (type %d)",
+		  req.gw_mac_addr.bytes,
+		  req.ipv4_addr, req.ipv4_addr_type,
+		  req.ipv6_addr, req.ipv6_addr_type);
+
+	hdd_nud_set_gateway_addr(adapter, req.gw_mac_addr);
+
+	status = sme_gateway_param_update(hdd_ctx->mac_handle, &req);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_gateway_param_update failed(err=%d)", status);
+		ret = -EINVAL;
+	}
+
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_gateway_params() - set gateway parameters
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * The API is invoked by the user space to set the gateway parameters
+ * such as mac address and the IP address which is used for detecting
+ * the IP subnet change
+ *
+ * Return: 0 on success; errno on failure
+ */
+int wlan_hdd_cfg80211_set_gateway_params(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+
+	ret = __wlan_hdd_cfg80211_set_gateway_params(
+				wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
+#undef PARAM_MAC_ADDR
+#undef PARAM_IPV4_ADDR
+#undef PARAM_IPV6_ADDR
diff --git a/core/hdd/src/wlan_hdd_subnet_detect.h b/core/hdd/src/wlan_hdd_subnet_detect.h
new file mode 100644
index 0000000..2d83200
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_subnet_detect.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015 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.
+ */
+
+#ifndef __WLAN_HDD_SUBNET_DETECT_H
+#define __WLAN_HDD_SUBNET_DETECT_H
+
+/**
+ * DOC: wlan_hdd_subnet_detect.h
+ *
+ * WLAN Host Device Driver subnet detect API specification
+ */
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+struct wiphy;
+struct wireless_dev;
+
+int wlan_hdd_cfg80211_set_gateway_params(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void *data, int data_len);
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+#endif /* __WLAN_HDD_SUBNET_DETECT_H */
diff --git a/core/hdd/src/wlan_hdd_sysfs.c b/core/hdd/src/wlan_hdd_sysfs.c
new file mode 100644
index 0000000..35b09bf
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_sysfs.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 2017-2018 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: wlan_hdd_sysfs.c
+ *
+ *  WLAN Host Device Driver implementation
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kobject.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include "wlan_hdd_includes.h"
+#include "wlan_hdd_sysfs.h"
+#include "qwlan_version.h"
+#include "cds_api.h"
+#include <wlan_osif_request_manager.h>
+#include <qdf_mem.h>
+#include <sir_api.h>
+
+#define MAX_PSOC_ID_SIZE 10
+
+#ifdef MULTI_IF_NAME
+#define DRIVER_NAME MULTI_IF_NAME
+#else
+#define DRIVER_NAME "wifi"
+#endif
+
+static struct kobject *wlan_kobject;
+static struct kobject *driver_kobject;
+static struct kobject *fw_kobject;
+static struct kobject *psoc_kobject;
+
+static ssize_t __show_driver_version(struct kobject *kobj,
+				     struct kobj_attribute *attr,
+				     char *buf)
+{
+	return scnprintf(buf, PAGE_SIZE, QWLAN_VERSIONSTR);
+}
+
+static ssize_t show_driver_version(struct kobject *kobj,
+				   struct kobj_attribute *attr,
+				   char *buf)
+{
+	ssize_t ret_val;
+
+	cds_ssr_protect(__func__);
+	ret_val = __show_driver_version(kobj, attr, buf);
+	cds_ssr_unprotect(__func__);
+
+	return ret_val;
+}
+
+static ssize_t __show_fw_version(struct kobject *kobj,
+				 struct kobj_attribute *attr,
+				 char *buf)
+{
+	uint32_t major_spid = 0, minor_spid = 0, siid = 0, crmid = 0;
+	uint32_t sub_id = 0;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	int ret;
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret) {
+		hdd_err("hdd ctx is invalid");
+		return ret;
+	}
+
+	hdd_debug("Rcvd req for FW version");
+	hdd_get_fw_version(hdd_ctx, &major_spid, &minor_spid, &siid,
+			   &crmid);
+	sub_id = (hdd_ctx->target_fw_vers_ext & 0xf0000000) >> 28;
+
+	return scnprintf(buf, PAGE_SIZE,
+			 "FW:%d.%d.%d.%d.%d HW:%s Board version: %x Ref design id: %x Customer id: %x Project id: %x Board Data Rev: %x\n",
+			 major_spid, minor_spid, siid, crmid, sub_id,
+			 hdd_ctx->target_hw_name,
+			 hdd_ctx->hw_bd_info.bdf_version,
+			 hdd_ctx->hw_bd_info.ref_design_id,
+			 hdd_ctx->hw_bd_info.customer_id,
+			 hdd_ctx->hw_bd_info.project_id,
+			 hdd_ctx->hw_bd_info.board_data_rev);
+}
+
+static ssize_t show_fw_version(struct kobject *kobj,
+			       struct kobj_attribute *attr,
+			       char *buf)
+{
+	ssize_t ret_val;
+
+	cds_ssr_protect(__func__);
+	ret_val = __show_fw_version(kobj, attr, buf);
+	cds_ssr_unprotect(__func__);
+
+	return ret_val;
+};
+
+struct power_stats_priv {
+	struct power_stats_response power_stats;
+};
+
+static void hdd_power_debugstats_dealloc(void *priv)
+{
+	struct power_stats_priv *stats = priv;
+
+	qdf_mem_free(stats->power_stats.debug_registers);
+	stats->power_stats.debug_registers = NULL;
+}
+
+static void hdd_power_debugstats_cb(struct power_stats_response *response,
+				    void *context)
+{
+	struct osif_request *request;
+	struct power_stats_priv *priv;
+	uint32_t *debug_registers;
+	uint32_t debug_registers_len;
+
+	hdd_enter();
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+
+	/* copy fixed-sized data */
+	priv->power_stats = *response;
+
+	/* copy variable-size data */
+	if (response->num_debug_register) {
+		debug_registers_len = (sizeof(response->debug_registers[0]) *
+				       response->num_debug_register);
+		debug_registers = qdf_mem_malloc(debug_registers_len);
+		priv->power_stats.debug_registers = debug_registers;
+		if (debug_registers) {
+			qdf_mem_copy(debug_registers,
+				     response->debug_registers,
+				     debug_registers_len);
+		} else {
+			hdd_err("Power stats memory alloc fails!");
+			priv->power_stats.num_debug_register = 0;
+		}
+	}
+	osif_request_complete(request);
+	osif_request_put(request);
+	hdd_exit();
+}
+
+static ssize_t __show_device_power_stats(struct kobject *kobj,
+					 struct kobj_attribute *attr,
+					 char *buf)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	QDF_STATUS status;
+	struct power_stats_response *chip_power_stats;
+	ssize_t ret_cnt = 0;
+	int j;
+	void *cookie;
+	struct osif_request *request;
+	struct power_stats_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+		.dealloc = hdd_power_debugstats_dealloc,
+	};
+
+	hdd_enter();
+
+	ret_cnt = wlan_hdd_validate_context(hdd_ctx);
+	if (ret_cnt)
+		return ret_cnt;
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	status = sme_power_debug_stats_req(hdd_ctx->mac_handle,
+					   hdd_power_debugstats_cb,
+					   cookie);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("chip power stats request failed");
+		ret_cnt = -EINVAL;
+		goto cleanup;
+	}
+
+	ret_cnt = osif_request_wait_for_response(request);
+	if (ret_cnt) {
+		hdd_err("Target response timed out Power stats");
+		ret_cnt = -ETIMEDOUT;
+		goto cleanup;
+	}
+	priv = osif_request_priv(request);
+	chip_power_stats = &priv->power_stats;
+
+	ret_cnt += scnprintf(buf, PAGE_SIZE,
+			"POWER DEBUG STATS\n=================\n"
+			"cumulative_sleep_time_ms: %d\n"
+			"cumulative_total_on_time_ms: %d\n"
+			"deep_sleep_enter_counter: %d\n"
+			"last_deep_sleep_enter_tstamp_ms: %d\n"
+			"debug_register_fmt: %d\n"
+			"num_debug_register: %d\n",
+			chip_power_stats->cumulative_sleep_time_ms,
+			chip_power_stats->cumulative_total_on_time_ms,
+			chip_power_stats->deep_sleep_enter_counter,
+			chip_power_stats->last_deep_sleep_enter_tstamp_ms,
+			chip_power_stats->debug_register_fmt,
+			chip_power_stats->num_debug_register);
+
+	for (j = 0; j < chip_power_stats->num_debug_register; j++) {
+		if ((PAGE_SIZE - ret_cnt) > 0)
+			ret_cnt += scnprintf(buf + ret_cnt,
+					PAGE_SIZE - ret_cnt,
+					"debug_registers[%d]: 0x%x\n", j,
+					chip_power_stats->debug_registers[j]);
+		else
+			j = chip_power_stats->num_debug_register;
+	}
+
+cleanup:
+	osif_request_put(request);
+	hdd_exit();
+	return ret_cnt;
+}
+
+static ssize_t show_device_power_stats(struct kobject *kobj,
+				       struct kobj_attribute *attr,
+				       char *buf)
+{
+	ssize_t ret_val;
+
+	cds_ssr_protect(__func__);
+	ret_val = __show_device_power_stats(kobj, attr, buf);
+	cds_ssr_unprotect(__func__);
+
+	return ret_val;
+}
+
+static struct kobj_attribute dr_ver_attribute =
+	__ATTR(driver_version, 0440, show_driver_version, NULL);
+static struct kobj_attribute fw_ver_attribute =
+	__ATTR(version, 0440, show_fw_version, NULL);
+static struct kobj_attribute power_stats_attribute =
+	__ATTR(power_stats, 0440, show_device_power_stats, NULL);
+
+void hdd_sysfs_create_version_interface(struct wlan_objmgr_psoc *psoc)
+{
+	int error = 0;
+	uint32_t psoc_id;
+	char buf[MAX_PSOC_ID_SIZE];
+
+	if (!driver_kobject || !wlan_kobject) {
+		hdd_err("could not get driver kobject!");
+		return;
+	}
+
+	error = sysfs_create_file(wlan_kobject, &dr_ver_attribute.attr);
+	if (error) {
+		hdd_err("could not create wlan sysfs file");
+		return;
+	}
+
+	fw_kobject = kobject_create_and_add("fw", wlan_kobject);
+	if (!fw_kobject) {
+		hdd_err("could not allocate fw kobject");
+		goto free_fw_kobj;
+	}
+
+	psoc_id = wlan_psoc_get_nif_phy_version(psoc);
+	scnprintf(buf, PAGE_SIZE, "%d", psoc_id);
+
+	psoc_kobject = kobject_create_and_add(buf, fw_kobject);
+	if (!psoc_kobject) {
+		hdd_err("could not allocate psoc kobject");
+		goto free_fw_kobj;
+	}
+
+	error = sysfs_create_file(psoc_kobject, &fw_ver_attribute.attr);
+	if (error) {
+		hdd_err("could not create fw sysfs file");
+		goto free_psoc_kobj;
+	}
+
+	return;
+
+free_psoc_kobj:
+	kobject_put(psoc_kobject);
+	psoc_kobject = NULL;
+
+free_fw_kobj:
+	kobject_put(fw_kobject);
+	fw_kobject = NULL;
+}
+
+void hdd_sysfs_destroy_version_interface(void)
+{
+	if (psoc_kobject) {
+		kobject_put(psoc_kobject);
+		psoc_kobject = NULL;
+		kobject_put(fw_kobject);
+		fw_kobject = NULL;
+	}
+}
+
+void hdd_sysfs_create_powerstats_interface(void)
+{
+	int error;
+
+	if (!driver_kobject) {
+		hdd_err("could not get driver kobject!");
+		return;
+	}
+
+	error = sysfs_create_file(driver_kobject, &power_stats_attribute.attr);
+	if (error)
+		hdd_err("could not create power_stats sysfs file");
+}
+
+void hdd_sysfs_destroy_powerstats_interface(void)
+{
+	if (!driver_kobject) {
+		hdd_err("could not get driver kobject!");
+		return;
+	}
+	sysfs_remove_file(driver_kobject, &power_stats_attribute.attr);
+}
+
+void hdd_sysfs_create_driver_root_obj(void)
+{
+	driver_kobject = kobject_create_and_add(DRIVER_NAME, kernel_kobj);
+	if (!driver_kobject) {
+		hdd_err("could not allocate driver kobject");
+		return;
+	}
+
+	wlan_kobject = kobject_create_and_add("wlan", driver_kobject);
+	if (!wlan_kobject) {
+		hdd_err("could not allocate wlan kobject");
+		kobject_put(driver_kobject);
+		driver_kobject = NULL;
+	}
+}
+
+void hdd_sysfs_destroy_driver_root_obj(void)
+{
+	if (wlan_kobject) {
+		kobject_put(wlan_kobject);
+		wlan_kobject = NULL;
+	}
+
+	if (driver_kobject) {
+		kobject_put(driver_kobject);
+		driver_kobject = NULL;
+	}
+}
diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c
new file mode 100644
index 0000000..45e38c9
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_tdls.c
@@ -0,0 +1,866 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_tdls.c
+ *
+ * WLAN Host Device Driver implementation for TDLS
+ */
+
+#include <wlan_hdd_includes.h>
+#include <ani_global.h>
+#include <wlan_hdd_hostapd.h>
+#include <wlan_hdd_trace.h>
+#include <net/cfg80211.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/list.h>
+#include <linux/etherdevice.h>
+#include <net/ieee80211_radiotap.h>
+#include "wlan_hdd_tdls.h"
+#include "wlan_hdd_cfg80211.h"
+#include "wlan_hdd_assoc.h"
+#include "sme_api.h"
+#include "cds_sched.h"
+#include "wma_types.h"
+#include "wlan_policy_mgr_api.h"
+#include <qca_vendor.h>
+#include "wlan_tdls_cfg_api.h"
+
+/**
+ * enum qca_wlan_vendor_tdls_trigger_mode_hdd_map: Maps the user space TDLS
+ *	trigger mode in the host driver.
+ * @WLAN_HDD_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT: TDLS Connection and
+ *	disconnection handled by user space.
+ * @WLAN_HDD_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT: TDLS connection and
+ *	disconnection controlled by host driver based on data traffic.
+ * @WLAN_HDD_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL: TDLS connection and
+ *	disconnection jointly controlled by user space and host driver.
+ */
+enum qca_wlan_vendor_tdls_trigger_mode_hdd_map {
+	WLAN_HDD_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT =
+		QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT,
+	WLAN_HDD_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT =
+		QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT,
+	WLAN_HDD_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL =
+		((QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT |
+		  QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT) << 1),
+};
+
+/**
+ * wlan_hdd_tdls_get_all_peers() - dump all TDLS peer info into output string
+ * @adapter: HDD adapter
+ * @buf: output string buffer to hold the peer info
+ * @buflen: the size of output string buffer
+ *
+ * Return: The size (in bytes) of the valid peer info in the output buffer
+ */
+int wlan_hdd_tdls_get_all_peers(struct hdd_adapter *adapter,
+				char *buf, int buflen)
+{
+	int len;
+	struct hdd_context *hdd_ctx;
+
+	hdd_enter();
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (0 != (wlan_hdd_validate_context(hdd_ctx))) {
+		len = scnprintf(buf, buflen,
+				"\nHDD context is not valid\n");
+		return len;
+	}
+
+	if ((QDF_STA_MODE != adapter->device_mode) &&
+	    (QDF_P2P_CLIENT_MODE != adapter->device_mode)) {
+		len = scnprintf(buf, buflen,
+				"\nNo TDLS support for this adapter\n");
+		return len;
+	}
+
+	return wlan_cfg80211_tdls_get_all_peers(adapter->vdev,
+						buf, buflen);
+}
+
+static const struct nla_policy
+	wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +
+					   1] = {
+	[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
+		.type = NLA_UNSPEC,
+		.len = QDF_MAC_ADDR_SIZE},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] = {.type =
+								NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type =
+								NLA_U32},
+};
+static const struct nla_policy
+	wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +
+					    1] = {
+	[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
+		.type = NLA_UNSPEC,
+		.len = QDF_MAC_ADDR_SIZE},
+};
+static const struct nla_policy
+	wlan_hdd_tdls_config_state_change_policy[QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX
+						 + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
+		.type = NLA_UNSPEC,
+		.len = QDF_MAC_ADDR_SIZE},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] = {.type =
+								NLA_U32},
+};
+static const struct nla_policy
+	wlan_hdd_tdls_config_get_status_policy
+[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
+		.type = NLA_UNSPEC,
+		.len = QDF_MAC_ADDR_SIZE},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_U32},
+	[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS] = {
+							.type = NLA_U32},
+};
+
+static const struct nla_policy
+	wlan_hdd_tdls_mode_configuration_policy
+	[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX + 1] = {
+		[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE] = {
+						.type = NLA_U32},
+		[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_STATS_PERIOD] = {
+						.type = NLA_U32},
+		[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_THRESHOLD] = {
+						.type = NLA_U32},
+		[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_DISCOVERY_PERIOD] = {
+						.type = NLA_U32},
+		[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX_DISCOVERY_ATTEMPT] = {
+						.type = NLA_U32},
+		[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_TIMEOUT] = {
+						.type = NLA_U32},
+		[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_PACKET_THRESHOLD] = {
+						.type = NLA_U32},
+		[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_SETUP_RSSI_THRESHOLD] = {
+						.type = NLA_S32},
+		[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TEARDOWN_RSSI_THRESHOLD] = {
+						.type = NLA_S32},
+};
+
+/**
+ * __wlan_hdd_cfg80211_exttdls_get_status() - handle get status cfg80211 command
+ * @wiphy: wiphy
+ * @wdev: wireless dev
+ * @data: netlink buffer with the mac address of the peer to get the status for
+ * @data_len: length of data in bytes
+ */
+static int
+__wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 const void *data,
+					 int data_len)
+{
+	/* TODO */
+	return 0;
+}
+
+/**
+ * __wlan_hdd_cfg80211_configure_tdls_mode() - configure the tdls mode
+ * @wiphy: wiphy
+ * @wdev: wireless dev
+ * @data: netlink buffer
+ * @data_len: length of data in bytes
+ *
+ * Return 0 for success and error code for failure
+ */
+static int
+__wlan_hdd_cfg80211_configure_tdls_mode(struct wiphy *wiphy,
+					 struct wireless_dev *wdev,
+					 const void *data,
+					 int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX + 1];
+	int ret;
+	uint32_t trigger_mode;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return -EINVAL;
+
+	if (NULL == adapter)
+		return -EINVAL;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX,
+				    data, data_len,
+				    wlan_hdd_tdls_mode_configuration_policy)) {
+		hdd_err("Invalid attribute");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE]) {
+		hdd_err("attr tdls trigger mode failed");
+		return -EINVAL;
+	}
+	trigger_mode = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE]);
+	hdd_debug("TDLS trigger mode %d", trigger_mode);
+
+	if (hdd_ctx->tdls_umac_comp_active) {
+		ret = wlan_cfg80211_tdls_configure_mode(adapter->vdev,
+							trigger_mode);
+		return ret;
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_configure_tdls_mode() - configure tdls mode
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Return:   Return the Success or Failure code.
+ */
+int wlan_hdd_cfg80211_configure_tdls_mode(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_configure_tdls_mode(wiphy, wdev, data,
+							data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_exttdls_get_status() - get ext tdls status
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Return:   Return the Success or Failure code.
+ */
+int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data,
+							data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_exttdls_enable() - enable an externally controllable
+ *                                      TDLS peer and set parameters
+ * wiphy: wiphy
+ * @wdev: wireless dev pointer
+ * @data: netlink buffer with peer MAC address and configuration parameters
+ * @data_len: size of data in bytes
+ *
+ * This function sets channel, operation class, maximum latency and minimal
+ * bandwidth parameters on a TDLS peer that's externally controllable.
+ *
+ * Return: 0 for success; negative errno otherwise
+ */
+static int
+__wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
+				     struct wireless_dev *wdev,
+				     const void *data,
+				     int data_len)
+{
+	/* TODO */
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_exttdls_enable() - enable ext tdls
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Return:   Return the Success or Failure code.
+ */
+int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_cfg80211_exttdls_disable() - disable an externally controllable
+ *                                       TDLS peer
+ * wiphy: wiphy
+ * @wdev: wireless dev pointer
+ * @data: netlink buffer with peer MAC address
+ * @data_len: size of data in bytes
+ *
+ * This function disables an externally controllable TDLS peer
+ *
+ * Return: 0 for success; negative errno otherwise
+ */
+static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
+				      struct wireless_dev *wdev,
+				      const void *data,
+				      int data_len)
+{
+	/* TODO */
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_exttdls_disable() - disable ext tdls
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Return:   Return the Success or Failure code.
+ */
+int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#if TDLS_MGMT_VERSION2
+/**
+ * __wlan_hdd_cfg80211_tdls_mgmt() - handle management actions on a given peer
+ * @wiphy: wiphy
+ * @dev: net device
+ * @peer: MAC address of the TDLS peer
+ * @action_code: action code
+ * @dialog_token: dialog token
+ * @status_code: status code
+ * @peer_capability: peer capability
+ * @buf: additional IE to include
+ * @len: length of buf in bytes
+ *
+ * Return: 0 if success; negative errno otherwise
+ */
+static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+				struct net_device *dev, u8 *peer,
+				u8 action_code, u8 dialog_token,
+				u16 status_code, u32 peer_capability,
+				const u8 *buf, size_t len)
+#else
+/**
+ * __wlan_hdd_cfg80211_tdls_mgmt() - handle management actions on a given peer
+ * @wiphy: wiphy
+ * @dev: net device
+ * @peer: MAC address of the TDLS peer
+ * @action_code: action code
+ * @dialog_token: dialog token
+ * @status_code: status code
+ * @buf: additional IE to include
+ * @len: length of buf in bytes
+ *
+ * Return: 0 if success; negative errno otherwise
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
+static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+				struct net_device *dev, const uint8_t *peer,
+				uint8_t action_code, uint8_t dialog_token,
+				uint16_t status_code, uint32_t peer_capability,
+				bool initiator, const uint8_t *buf,
+				size_t len)
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+				struct net_device *dev, const uint8_t *peer,
+				uint8_t action_code, uint8_t dialog_token,
+				uint16_t status_code, uint32_t peer_capability,
+				const uint8_t *buf, size_t len)
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
+static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+				struct net_device *dev, uint8_t *peer,
+				uint8_t action_code, uint8_t dialog_token,
+				uint16_t status_code, uint32_t peer_capability,
+				const uint8_t *buf, size_t len)
+#else
+static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+				struct net_device *dev, uint8_t *peer,
+				uint8_t action_code, uint8_t dialog_token,
+				uint16_t status_code, const uint8_t *buf,
+				size_t len)
+#endif
+#endif
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	bool tdls_support;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
+#if !(TDLS_MGMT_VERSION2)
+	u32 peer_capability;
+
+	peer_capability = 0;
+#endif
+#endif
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
+			 adapter->session_id, action_code));
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support);
+	if (!tdls_support) {
+		hdd_debug("TDLS Disabled in INI OR not enabled in FW. "
+			"Cannot process TDLS commands");
+		return -ENOTSUPP;
+	}
+
+	if (hdd_ctx->tdls_umac_comp_active)
+		return wlan_cfg80211_tdls_mgmt(hdd_ctx->pdev, dev,
+					       peer,
+					       action_code, dialog_token,
+					       status_code, peer_capability,
+					       buf, len);
+
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_tdls_mgmt() - cfg80211 tdls mgmt handler function
+ * @wiphy: Pointer to wiphy structure.
+ * @dev: Pointer to net_device structure.
+ * @peer: peer address
+ * @action_code: action code
+ * @dialog_token: dialog token
+ * @status_code: status code
+ * @peer_capability: peer capability
+ * @buf: buffer
+ * @len: Length of @buf
+ *
+ * This is the cfg80211 tdls mgmt handler function which invokes
+ * the internal function @__wlan_hdd_cfg80211_tdls_mgmt with
+ * SSR protection.
+ *
+ * Return: 0 for success, error number on failure.
+ */
+#if TDLS_MGMT_VERSION2
+int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+					struct net_device *dev,
+					u8 *peer, u8 action_code,
+					u8 dialog_token,
+					u16 status_code, u32 peer_capability,
+					const u8 *buf, size_t len)
+#else /* TDLS_MGMT_VERSION2 */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
+int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+					struct net_device *dev,
+					const u8 *peer, u8 action_code,
+					u8 dialog_token, u16 status_code,
+					u32 peer_capability, bool initiator,
+					const u8 *buf, size_t len)
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+					struct net_device *dev,
+					const u8 *peer, u8 action_code,
+					u8 dialog_token, u16 status_code,
+					u32 peer_capability, const u8 *buf,
+					size_t len)
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
+int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+					struct net_device *dev,
+					u8 *peer, u8 action_code,
+					u8 dialog_token,
+					u16 status_code, u32 peer_capability,
+					const u8 *buf, size_t len)
+#else
+int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
+					struct net_device *dev,
+					u8 *peer, u8 action_code,
+					u8 dialog_token,
+					u16 status_code, const u8 *buf,
+					size_t len)
+#endif
+#endif
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+#if TDLS_MGMT_VERSION2
+	ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
+						dialog_token, status_code,
+						peer_capability, buf, len);
+#else /* TDLS_MGMT_VERSION2 */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
+	ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
+					dialog_token, status_code,
+					peer_capability, initiator,
+					buf, len);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+	ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
+					dialog_token, status_code,
+					peer_capability, buf, len);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
+	ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
+					dialog_token, status_code,
+					peer_capability, buf, len);
+#else
+	ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
+					dialog_token, status_code, buf, len);
+#endif
+#endif
+
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_tdls_extctrl_config_peer() - configure an externally controllable
+ *                                       TDLS peer
+ * @adapter: HDD adapter
+ * @peer: MAC address of the TDLS peer
+ * @callback: Callback to set on the peer
+ * @chan: Channel
+ * @max_latency: Maximum latency
+ * @op_class: Operation class
+ * @min_bandwidth: Minimal bandwidth
+ *
+ * Return: 0 on success; negative otherwise
+ */
+int wlan_hdd_tdls_extctrl_config_peer(struct hdd_adapter *adapter,
+				      const uint8_t *peer,
+				      cfg80211_exttdls_callback callback,
+				      u32 chan,
+				      u32 max_latency,
+				      u32 op_class, u32 min_bandwidth)
+{
+	/* TODO */
+	return 0;
+}
+
+/**
+ * wlan_hdd_tdls_extctrl_deconfig_peer() - de-configure an externally
+ *                                         controllable TDLS peer
+ * @adapter: HDD adapter
+ * @peer: MAC address of the tdls peer
+ *
+ * Return: 0 if success; negative errno otherwisw
+ */
+int wlan_hdd_tdls_extctrl_deconfig_peer(struct hdd_adapter *adapter,
+					const uint8_t *peer)
+{
+	/* TODO */
+	return 0;
+}
+
+/**
+ * __wlan_hdd_cfg80211_tdls_oper() - helper function to handle cfg80211 operation
+ *                                   on an TDLS peer
+ * @wiphy: wiphy
+ * @dev: net device
+ * @peer: MAC address of the TDLS peer
+ * @oper: cfg80211 TDLS operation
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
+					 struct net_device *dev,
+					 const uint8_t *peer,
+					 enum nl80211_tdls_operation oper)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	int status;
+	bool tdls_support;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support);
+	if (!tdls_support) {
+		hdd_debug("TDLS Disabled in INI OR not enabled in FW. "
+			"Cannot process TDLS commands");
+		return -ENOTSUPP;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
+			 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
+			 adapter->session_id, oper));
+	if (NULL == peer) {
+		hdd_err("Invalid arguments");
+		return -EINVAL;
+	}
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		return status;
+
+	if (hdd_ctx->tdls_umac_comp_active) {
+		status = wlan_cfg80211_tdls_oper(hdd_ctx->pdev,
+						 dev, peer, oper);
+		hdd_exit();
+		return status;
+	}
+
+	hdd_exit();
+	return -EINVAL;
+}
+
+/**
+ * wlan_hdd_cfg80211_tdls_oper() - handle cfg80211 operation on an TDLS peer
+ * @wiphy: wiphy
+ * @dev: net device
+ * @peer: MAC address of the TDLS peer
+ * @oper: cfg80211 TDLS operation
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
+				struct net_device *dev,
+				const uint8_t *peer,
+				enum nl80211_tdls_operation oper)
+#else
+int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
+				struct net_device *dev,
+				uint8_t *peer,
+				enum nl80211_tdls_operation oper)
+#endif
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_send_tdls_discover_req() - send out TDLS discovery for
+ *                                              a TDLS peer
+ * @wiphy: wiphy
+ * @dev: net device
+ * @peer: MAC address of the peer
+ *
+ * Return: 0 if success; negative errno otherwise
+ */
+int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
+					     struct net_device *dev, u8 *peer)
+{
+	hdd_debug("tdls send discover req: " MAC_ADDRESS_STR,
+		   MAC_ADDR_ARRAY(peer));
+#if TDLS_MGMT_VERSION2
+	return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
+					   WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0,
+					   NULL, 0);
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
+	return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
+					   WLAN_TDLS_DISCOVERY_REQUEST, 1, 0,
+					   0, 0, NULL, 0);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
+	return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
+					   WLAN_TDLS_DISCOVERY_REQUEST, 1, 0,
+					   0, NULL, 0);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
+	return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
+					   WLAN_TDLS_DISCOVERY_REQUEST, 1, 0,
+					   0, NULL, 0);
+#else
+	return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
+					   WLAN_TDLS_DISCOVERY_REQUEST, 1, 0,
+					   NULL, 0);
+#endif
+#endif
+}
+
+
+int hdd_set_tdls_offchannel(struct hdd_context *hdd_ctx,
+			    struct hdd_adapter *adapter,
+			    int offchannel)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (hdd_ctx->tdls_umac_comp_active)
+		status = ucfg_set_tdls_offchannel(adapter->vdev,
+						  offchannel);
+	return qdf_status_to_os_return(status);
+}
+
+int hdd_set_tdls_secoffchanneloffset(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter,
+				     int offchanoffset)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (hdd_ctx->tdls_umac_comp_active)
+		status = ucfg_set_tdls_secoffchanneloffset(adapter->vdev,
+							   offchanoffset);
+	return qdf_status_to_os_return(status);
+}
+
+int hdd_set_tdls_offchannelmode(struct hdd_context *hdd_ctx,
+				struct hdd_adapter *adapter,
+				int offchanmode)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (hdd_ctx->tdls_umac_comp_active)
+		status = ucfg_set_tdls_offchan_mode(adapter->vdev,
+						    offchanmode);
+	return qdf_status_to_os_return(status);
+}
+
+/**
+ * hdd_set_tdls_scan_type - set scan during active tdls session
+ * @hdd_ctx: ptr to hdd context.
+ * @val: scan type value: 0 or 1.
+ *
+ * Set scan type during tdls session. If set to 1, that means driver
+ * shall maintain tdls link and allow scan regardless if tdls peer is
+ * buffer sta capable or not and/or if device is sleep sta capable or
+ * not. If tdls peer is not buffer sta capable then during scan there
+ * will be loss of Rx packets and Tx would stop when device moves away
+ * from tdls channel. If set to 0, then driver shall teardown tdls link
+ * before initiating scan if peer is not buffer sta capable and device
+ * is not sleep sta capable. By default, scan type is set to 0.
+ *
+ * Return: success (0) or failure (errno value)
+ */
+int hdd_set_tdls_scan_type(struct hdd_context *hdd_ctx, int val)
+{
+	if ((val != 0) && (val != 1)) {
+		hdd_err("Incorrect value of tdls scan type: %d", val);
+		return -EINVAL;
+	}
+
+	cfg_tdls_set_scan_enable(hdd_ctx->psoc, (bool)val);
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_tdls_antenna_switch() - Dynamic TDLS antenna  switch 1x1 <-> 2x2
+ * antenna mode in standalone station
+ * @hdd_ctx: Pointer to hdd contex
+ * @adapter: Pointer to hdd adapter
+ *
+ * Return: 0 if success else non zero
+ */
+int wlan_hdd_tdls_antenna_switch(struct hdd_context *hdd_ctx,
+				 struct hdd_adapter *adapter,
+				 uint32_t mode)
+{
+	if (hdd_ctx->tdls_umac_comp_active)
+		return wlan_tdls_antenna_switch(adapter->vdev, mode);
+
+	return 0;
+}
+
+QDF_STATUS hdd_tdls_register_peer(void *userdata, uint32_t vdev_id,
+				  const uint8_t *mac, uint16_t sta_id,
+				  uint8_t qos)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hddctx;
+
+	hddctx = userdata;
+	if (!hddctx) {
+		hdd_err("Invalid hddctx");
+		return QDF_STATUS_E_INVAL;
+	}
+	adapter = hdd_get_adapter_by_vdev(hddctx, vdev_id);
+	if (!adapter) {
+		hdd_err("Invalid adapter");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return hdd_roam_register_tdlssta(adapter, mac, sta_id, qos);
+}
+
+QDF_STATUS hdd_tdls_deregister_peer(void *userdata, uint32_t vdev_id,
+				    uint8_t sta_id)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hddctx;
+
+	hddctx = userdata;
+	if (!hddctx) {
+		hdd_err("Invalid hddctx");
+		return QDF_STATUS_E_INVAL;
+	}
+	adapter = hdd_get_adapter_by_vdev(hddctx, vdev_id);
+	if (!adapter) {
+		hdd_err("Invalid adapter");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return hdd_roam_deregister_tdlssta(adapter, sta_id);
+}
diff --git a/core/hdd/src/wlan_hdd_trace.c b/core/hdd/src/wlan_hdd_trace.c
new file mode 100644
index 0000000..22a2438
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_trace.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014-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.
+ */
+
+#ifdef HDD_TRACE_RECORD
+
+/**
+ * DOC: wlan_hdd_trace.c
+ *
+ * WLAN Host Device Driver trace implementation
+ *
+ */
+
+#include "qdf_trace.h"
+#include "qdf_types.h"
+#include "wlan_hdd_trace.h"
+#include "wlan_hdd_main.h"
+
+/**
+ * hdd_trace_dump() - Dump an HDD-specific trace record
+ * @mac: (unused) global MAC handle
+ * @record: trace record that was previously recorded
+ * @index: index of the trace record
+ *
+ * Return: none
+ */
+static void
+hdd_trace_dump(void *mac, tp_qdf_trace_record record, uint16_t index)
+{
+	if (TRACE_CODE_HDD_RX_SME_MSG == record->code)
+		hdd_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)",
+			index, record->qtime, record->time, record->session,
+			"RX SME MSG:",
+			get_e_roam_cmd_status_str(record->data), record->data);
+	else
+		hdd_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)",
+			index, record->qtime, record->time, record->session,
+			"HDD Event:",
+			hdd_trace_event_string(record->code), record->data);
+}
+
+/**
+ * hdd_trace_init() - HDD trace subsystem initialization
+ *
+ * Registers HDD with the debug trace subsystem
+ *
+ * Return: none
+ */
+void hdd_trace_init(void)
+{
+	qdf_trace_register(QDF_MODULE_ID_HDD, hdd_trace_dump);
+}
+
+#endif /* ifdef HDD_TRACE_RECORD */
diff --git a/core/hdd/src/wlan_hdd_tsf.c b/core/hdd/src/wlan_hdd_tsf.c
new file mode 100644
index 0000000..cf138ed
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_tsf.c
@@ -0,0 +1,1568 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+/**
+ * wlan_hdd_tsf.c - WLAN Host Device Driver tsf related implementation
+ */
+
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_tsf.h"
+#include "wma_api.h"
+#include "wlan_fwol_ucfg_api.h"
+#include <qca_vendor.h>
+#include <linux/errqueue.h>
+#include "ol_txrx_api.h"
+static struct completion tsf_sync_get_completion_evt;
+#define WLAN_TSF_SYNC_GET_TIMEOUT 2000
+#define WLAN_HDD_CAPTURE_TSF_REQ_TIMEOUT_MS 500
+#define WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS 100
+#define WLAN_HDD_SOFTAP_INTERVEL_TIMES 100
+
+/**
+ * enum hdd_tsf_op_result - result of tsf operation
+ *
+ * HDD_TSF_OP_SUCC:  succeed
+ * HDD_TSF_OP_FAIL:  fail
+ */
+enum hdd_tsf_op_result {
+	HDD_TSF_OP_SUCC,
+	HDD_TSF_OP_FAIL
+};
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+#define WLAN_HDD_CAPTURE_TSF_RESYNC_INTERVAL 9
+
+static inline void hdd_set_th_sync_status(struct hdd_adapter *adapter,
+					  bool initialized)
+{
+	qdf_atomic_set(&adapter->tsf_sync_ready_flag,
+		       (initialized ? 1 : 0));
+}
+
+static inline bool hdd_get_th_sync_status(struct hdd_adapter *adapter)
+{
+	return qdf_atomic_read(&adapter->tsf_sync_ready_flag) != 0;
+}
+
+#else
+static inline bool hdd_get_th_sync_status(struct hdd_adapter *adapter)
+{
+	return true;
+}
+#endif
+
+static
+enum hdd_tsf_get_state hdd_tsf_check_conn_state(struct hdd_adapter *adapter)
+{
+	enum hdd_tsf_get_state ret = TSF_RETURN;
+	struct hdd_station_ctx *hdd_sta_ctx;
+
+	if (adapter->device_mode == QDF_STA_MODE ||
+			adapter->device_mode == QDF_P2P_CLIENT_MODE) {
+		hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		if (hdd_sta_ctx->conn_info.connState !=
+				eConnectionState_Associated) {
+			hdd_err("failed to cap tsf, not connect with ap");
+			ret = TSF_STA_NOT_CONNECTED_NO_TSF;
+		}
+	} else if ((adapter->device_mode == QDF_SAP_MODE ||
+				adapter->device_mode == QDF_P2P_GO_MODE) &&
+			!(test_bit(SOFTAP_BSS_STARTED,
+					&adapter->event_flags))) {
+		hdd_err("Soft AP / P2p GO not beaconing");
+		ret = TSF_SAP_NOT_STARTED_NO_TSF;
+	}
+	return ret;
+}
+
+static bool hdd_tsf_is_initialized(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hddctx;
+
+	if (!adapter) {
+		hdd_err("invalid adapter");
+		return false;
+	}
+
+	hddctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hddctx) {
+		hdd_err("invalid hdd context");
+		return false;
+	}
+
+	if (!qdf_atomic_read(&hddctx->tsf_ready_flag) ||
+	    !hdd_get_th_sync_status(adapter)) {
+		hdd_err("TSF is not initialized");
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * hdd_tsf_reset_gpio() - Reset TSF GPIO used for host timer sync
+ * @adapter: pointer to adapter
+ *
+ * This function send WMI command to reset GPIO configured in FW after
+ * TSF get operation.
+ *
+ * Return: TSF_RETURN on Success, TSF_RESET_GPIO_FAIL on failure
+ */
+#if defined(WLAN_FEATURE_TSF_PLUS_NOIRQ) && defined(WLAN_FEATURE_TSF_PLUS)
+static int hdd_tsf_reset_gpio(struct hdd_adapter *adapter)
+{
+	/* No GPIO Host timer sync for integrated WIFI Device */
+	return TSF_RETURN;
+}
+
+/**
+ * hdd_tsf_set_gpio() - Set TSF GPIO used for host timer sync
+ * @hdd_ctx: pointer to hdd context
+ *
+ * This function is a dummy function for adrastea arch
+ *
+ * Return: QDF_STATUS_SUCCESS on Success
+ */
+
+static QDF_STATUS hdd_tsf_set_gpio(struct hdd_context *hdd_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd)
+{
+	return (hdd && (hdd->config) &&
+		(hdd->config->tsf_ptp_options));
+}
+
+bool hdd_tsf_is_tx_set(struct hdd_context *hdd)
+{
+	return (hdd && (hdd->config) &&
+		((hdd->config->tsf_ptp_options)
+		& CFG_SET_TSF_PTP_OPT_TX));
+}
+
+bool hdd_tsf_is_rx_set(struct hdd_context *hdd)
+{
+	return (hdd && (hdd->config) &&
+		((hdd->config->tsf_ptp_options)
+		& CFG_SET_TSF_PTP_OPT_RX));
+}
+
+bool hdd_tsf_is_raw_set(struct hdd_context *hdd)
+{
+	return (hdd && (hdd->config) &&
+		((hdd->config->tsf_ptp_options)
+		& CFG_SET_TSF_PTP_OPT_RAW));
+}
+
+bool hdd_tsf_is_dbg_fs_set(struct hdd_context *hdd)
+{
+	return (hdd && (hdd->config) &&
+		((hdd->config->tsf_ptp_options)
+		& CFG_SET_TSF_DBG_FS));
+}
+
+#else
+static int hdd_tsf_reset_gpio(struct hdd_adapter *adapter)
+{
+	int ret;
+
+	ret = wma_cli_set_command((int)adapter->session_id,
+			(int)GEN_PARAM_RESET_TSF_GPIO, adapter->session_id,
+			GEN_CMD);
+
+	if (ret != 0) {
+		hdd_err("tsf reset GPIO fail ");
+		ret = TSF_RESET_GPIO_FAIL;
+	} else {
+		ret = TSF_RETURN;
+	}
+	return ret;
+}
+
+/**
+ * hdd_tsf_set_gpio() - Set TSF GPIO used for host timer sync
+ * @hdd_ctx: pointer to hdd context
+ *
+ * This function check GPIO and set GPIO as IRQ to FW side on
+ * none Adrastea arch
+ *
+ * Return: QDF_STATUS_SUCCESS on Success, others on Failure.
+ */
+static QDF_STATUS hdd_tsf_set_gpio(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	uint32_t tsf_gpio_pin = TSF_GPIO_PIN_INVALID;
+
+	status = ucfg_fwol_get_tsf_gpio_pin(hdd_ctx->psoc, &tsf_gpio_pin);
+	if (QDF_IS_STATUS_ERROR(status))
+		return QDF_STATUS_E_INVAL;
+
+	if (tsf_gpio_pin == TSF_GPIO_PIN_INVALID)
+		return QDF_STATUS_E_INVAL;
+
+	status = sme_set_tsf_gpio(hdd_ctx->mac_handle,
+				  tsf_gpio_pin);
+
+	return status;
+}
+#endif
+
+static enum hdd_tsf_op_result hdd_capture_tsf_internal(
+	struct hdd_adapter *adapter, uint32_t *buf, int len)
+{
+	int ret;
+	struct hdd_context *hddctx;
+	qdf_mc_timer_t *cap_timer;
+
+	if (adapter == NULL || buf == NULL) {
+		hdd_err("invalid pointer");
+		return HDD_TSF_OP_FAIL;
+	}
+
+	if (len != 1)
+		return HDD_TSF_OP_FAIL;
+
+	hddctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hddctx) {
+		hdd_err("invalid hdd context");
+		return HDD_TSF_OP_FAIL;
+	}
+
+	if (!hdd_tsf_is_initialized(adapter)) {
+		buf[0] = TSF_NOT_READY;
+		return HDD_TSF_OP_SUCC;
+	}
+
+	buf[0] = hdd_tsf_check_conn_state(adapter);
+	if (buf[0] != TSF_RETURN)
+		return HDD_TSF_OP_SUCC;
+
+	if (qdf_atomic_inc_return(&hddctx->cap_tsf_flag) > 1) {
+		hdd_err("current in capture state");
+		buf[0] = TSF_CURRENT_IN_CAP_STATE;
+		return HDD_TSF_OP_SUCC;
+	}
+
+	/* record adapter for cap_tsf_irq_handler  */
+	hddctx->cap_tsf_context = adapter;
+
+	hdd_info("+ioctl issue cap tsf cmd");
+	cap_timer = &adapter->host_capture_req_timer;
+	qdf_mc_timer_init(cap_timer, QDF_TIMER_TYPE_SW,
+			  hdd_capture_req_timer_expired_handler,
+			  (void *)adapter);
+	qdf_mc_timer_start(cap_timer, WLAN_HDD_CAPTURE_TSF_REQ_TIMEOUT_MS);
+
+	/* Reset TSF value for new capture */
+	adapter->cur_target_time = 0;
+
+	buf[0] = TSF_RETURN;
+	init_completion(&tsf_sync_get_completion_evt);
+	ret = wma_cli_set_command((int)adapter->session_id,
+				  (int)GEN_PARAM_CAPTURE_TSF,
+				  adapter->session_id, GEN_CMD);
+	if (QDF_STATUS_SUCCESS != ret) {
+		hdd_err("cap tsf fail");
+		buf[0] = TSF_CAPTURE_FAIL;
+		hddctx->cap_tsf_context = NULL;
+		qdf_atomic_set(&hddctx->cap_tsf_flag, 0);
+		qdf_mc_timer_stop(&adapter->host_capture_req_timer);
+		qdf_mc_timer_destroy(&adapter->host_capture_req_timer);
+
+		return HDD_TSF_OP_SUCC;
+	}
+	hdd_info("-ioctl return cap tsf cmd");
+	return HDD_TSF_OP_SUCC;
+}
+
+static enum hdd_tsf_op_result hdd_indicate_tsf_internal(
+	struct hdd_adapter *adapter, uint32_t *buf, int len)
+{
+	int ret;
+	struct hdd_context *hddctx;
+
+	if (!adapter || !buf) {
+		hdd_err("invalid pointer");
+		return HDD_TSF_OP_FAIL;
+	}
+
+	if (len != 3)
+		return HDD_TSF_OP_FAIL;
+
+	hddctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hddctx) {
+		hdd_err("invalid hdd context");
+		return HDD_TSF_OP_FAIL;
+	}
+
+	buf[1] = 0;
+	buf[2] = 0;
+
+	if (!hdd_tsf_is_initialized(adapter)) {
+		buf[0] = TSF_NOT_READY;
+		return HDD_TSF_OP_SUCC;
+	}
+
+	buf[0] = hdd_tsf_check_conn_state(adapter);
+	if (buf[0] != TSF_RETURN)
+		return HDD_TSF_OP_SUCC;
+
+	if (adapter->cur_target_time == 0) {
+		hdd_info("TSF value not received");
+		buf[0] = TSF_NOT_RETURNED_BY_FW;
+		return HDD_TSF_OP_SUCC;
+	}
+
+	buf[0] = TSF_RETURN;
+	buf[1] = (uint32_t)(adapter->cur_target_time & 0xffffffff);
+	buf[2] = (uint32_t)((adapter->cur_target_time >> 32) &
+				0xffffffff);
+
+	if (!qdf_atomic_read(&hddctx->cap_tsf_flag)) {
+		hdd_info("old: status=%u, tsf_low=%u, tsf_high=%u",
+			 buf[0], buf[1], buf[2]);
+		return HDD_TSF_OP_SUCC;
+	}
+
+	ret = hdd_tsf_reset_gpio(adapter);
+	if (0 != ret) {
+		hdd_err("reset tsf gpio fail");
+		buf[0] = TSF_RESET_GPIO_FAIL;
+		return HDD_TSF_OP_SUCC;
+	}
+	hddctx->cap_tsf_context = NULL;
+	qdf_atomic_set(&hddctx->cap_tsf_flag, 0);
+	hdd_info("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u",
+		 buf[0], buf[1], buf[2]);
+
+	return HDD_TSF_OP_SUCC;
+}
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+/* unit for target time: us;  host time: ns */
+#define HOST_TO_TARGET_TIME_RATIO NSEC_PER_USEC
+#define MAX_ALLOWED_DEVIATION_NS (100 * NSEC_PER_USEC)
+#define MAX_CONTINUOUS_ERROR_CNT 3
+
+/* to distinguish 32-bit overflow case, this inverval should:
+ * equal or less than (1/2 * OVERFLOW_INDICATOR32 us)
+ */
+#define WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC 10
+#define OVERFLOW_INDICATOR32 (((int64_t)0x1) << 32)
+#define CAP_TSF_TIMER_FIX_SEC 1
+
+/**
+ * TS_STATUS - timestamp status
+ *
+ * HDD_TS_STATUS_WAITING:  one of the stamp-pair
+ *    is not updated
+ * HDD_TS_STATUS_READY:  valid tstamp-pair
+ * HDD_TS_STATUS_INVALID: invalid tstamp-pair
+ */
+enum hdd_ts_status {
+	HDD_TS_STATUS_WAITING,
+	HDD_TS_STATUS_READY,
+	HDD_TS_STATUS_INVALID
+};
+
+static
+enum hdd_tsf_op_result __hdd_start_tsf_sync(struct hdd_adapter *adapter)
+{
+	QDF_STATUS ret;
+
+	if (!hdd_get_th_sync_status(adapter)) {
+		hdd_err("Host Target sync has not initialized");
+		return HDD_TSF_OP_FAIL;
+	}
+
+	ret = qdf_mc_timer_start(&adapter->host_target_sync_timer,
+				 WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS);
+	if (ret != QDF_STATUS_SUCCESS && ret != QDF_STATUS_E_ALREADY) {
+		hdd_err("Failed to start timer, ret: %d", ret);
+		return HDD_TSF_OP_FAIL;
+	}
+	return HDD_TSF_OP_SUCC;
+}
+
+static
+enum hdd_tsf_op_result __hdd_stop_tsf_sync(struct hdd_adapter *adapter)
+{
+	QDF_STATUS ret;
+
+	if (!hdd_get_th_sync_status(adapter)) {
+		hdd_err("Host Target sync has not initialized");
+		return HDD_TSF_OP_SUCC;
+	}
+
+	ret = qdf_mc_timer_stop(&adapter->host_target_sync_timer);
+	if (ret != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to stop timer, ret: %d", ret);
+		return HDD_TSF_OP_FAIL;
+	}
+	return HDD_TSF_OP_SUCC;
+}
+
+static inline void hdd_reset_timestamps(struct hdd_adapter *adapter)
+{
+	qdf_spin_lock_bh(&adapter->host_target_sync_lock);
+	adapter->cur_host_time = 0;
+	adapter->cur_target_time = 0;
+	adapter->last_host_time = 0;
+	adapter->last_target_time = 0;
+	qdf_spin_unlock_bh(&adapter->host_target_sync_lock);
+}
+
+/**
+ * hdd_check_timestamp_status() - return the tstamp status
+ *
+ * @last_target_time: the last saved target time
+ * @last_host_time: the last saved host time
+ * @cur_target_time : new target time
+ * @cur_host_time : new host time
+ *
+ * This function check the new timstamp-pair(cur_host_time/cur_target_time)
+ *
+ * Return:
+ * HDD_TS_STATUS_WAITING: cur_host_time or cur_host_time is 0
+ * HDD_TS_STATUS_READY: cur_target_time/cur_host_time is a valid pair,
+ *    and can be saved
+ * HDD_TS_STATUS_INVALID: cur_target_time/cur_host_time is a invalid pair,
+ *    should be discard
+ */
+static
+enum hdd_ts_status hdd_check_timestamp_status(
+		uint64_t last_target_time,
+		uint64_t last_host_time,
+		uint64_t cur_target_time,
+		uint64_t cur_host_time)
+{
+	uint64_t delta_ns, delta_target_time, delta_host_time;
+
+	/* one or more are not updated, need to wait */
+	if (cur_target_time == 0 || cur_host_time == 0)
+		return HDD_TS_STATUS_WAITING;
+
+	/* init value, it's the first time to update the pair */
+	if (last_target_time == 0 && last_host_time == 0)
+		return HDD_TS_STATUS_READY;
+
+	/* the new values should be greater than the saved values */
+	if ((cur_target_time <= last_target_time) ||
+	    (cur_host_time <= last_host_time)) {
+		hdd_err("Invalid timestamps!last_target_time: %llu;"
+			"last_host_time: %llu; cur_target_time: %llu;"
+			"cur_host_time: %llu",
+			last_target_time, last_host_time,
+			cur_target_time, cur_host_time);
+		return HDD_TS_STATUS_INVALID;
+	}
+
+	delta_target_time = (cur_target_time - last_target_time) *
+		HOST_TO_TARGET_TIME_RATIO;
+	delta_host_time = cur_host_time - last_host_time;
+
+	/*
+	 * DO NOT use abs64() , a big uint64 value might be turned to
+	 * a small int64 value
+	 */
+	delta_ns = ((delta_target_time > delta_host_time) ?
+			(delta_target_time - delta_host_time) :
+			(delta_host_time - delta_target_time));
+
+	/* the deviation should be smaller than a threshold */
+	if (delta_ns > MAX_ALLOWED_DEVIATION_NS) {
+		hdd_warn("Invalid timestamps - delta: %llu ns", delta_ns);
+		return HDD_TS_STATUS_INVALID;
+	}
+	return HDD_TS_STATUS_READY;
+}
+
+static void hdd_update_timestamp(struct hdd_adapter *adapter,
+				 uint64_t target_time, uint64_t host_time)
+{
+	int interval = 0;
+	enum hdd_ts_status sync_status;
+
+	if (!adapter)
+		return;
+
+	/* host time is updated in IRQ context, it's always before target time,
+	 * and so no need to try update last_host_time at present;
+	 * since the interval of capturing TSF
+	 * (WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC) is long enough, host and target
+	 * time are updated in pairs, and one by one, we can return here to
+	 * avoid requiring spin lock, and to speed up the IRQ processing.
+	 */
+	if (host_time > 0) {
+	/* on ADREASTEA ach, Qtime is used to sync host and tsf time as a
+	 * intermedia there is no IRQ to sync up TSF-HOST, so host time in ns
+	 * and target in us will be updated at the same time in WMI command
+	 * callback
+	 */
+		adapter->cur_host_time = host_time;
+
+		if (0 == target_time)
+			return;
+	}
+
+	qdf_spin_lock_bh(&adapter->host_target_sync_lock);
+	if (target_time > 0)
+		adapter->cur_target_time = target_time;
+
+	sync_status = hdd_check_timestamp_status(adapter->last_target_time,
+						 adapter->last_host_time,
+						 adapter->cur_target_time,
+						 adapter->cur_host_time);
+	hdd_info("sync_status %d", sync_status);
+	switch (sync_status) {
+	case HDD_TS_STATUS_INVALID:
+		if (++adapter->continuous_error_count <
+		    MAX_CONTINUOUS_ERROR_CNT) {
+			interval =
+				WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS;
+			adapter->last_target_time = adapter->cur_target_time;
+			adapter->last_host_time = adapter->cur_host_time;
+			adapter->cur_target_time = 0;
+			adapter->cur_host_time = 0;
+			break;
+		}
+		hdd_warn("Reach the max continuous error count");
+		/*
+		 * fall through:
+		 * If reach MAX_CONTINUOUS_ERROR_CNT, treat it as a
+		 * valid pair
+		 */
+	case HDD_TS_STATUS_READY:
+		adapter->last_target_time = adapter->cur_target_time;
+		adapter->last_host_time = adapter->cur_host_time;
+		adapter->cur_target_time = 0;
+		adapter->cur_host_time = 0;
+		hdd_info("ts-pair updated: target: %llu; host: %llu",
+			 adapter->last_target_time,
+			 adapter->last_host_time);
+
+		/*
+		 * TSF-HOST need to be updated in at most
+		 * WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC, it couldn't be achieved
+		 * if the timer interval is also
+		 * WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC, due to processing or
+		 * schedule delay. So deduct several seconds from
+		 * WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC.
+		 * Without this change, hdd_get_hosttime_from_targettime() will
+		 * get wrong host time when it's longer than
+		 * WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC from last
+		 * TSF-HOST update.
+		 */
+		interval = (WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC -
+			    CAP_TSF_TIMER_FIX_SEC) * MSEC_PER_SEC;
+		if (adapter->device_mode == QDF_SAP_MODE ||
+		    adapter->device_mode == QDF_P2P_GO_MODE) {
+			interval *= WLAN_HDD_SOFTAP_INTERVEL_TIMES;
+		}
+
+		adapter->continuous_error_count = 0;
+		hdd_debug("ts-pair updated: interval: %d",
+			  interval);
+		break;
+	case HDD_TS_STATUS_WAITING:
+		interval = 0;
+		hdd_warn("TS status is waiting due to one or more pair not updated");
+		break;
+	}
+	qdf_spin_unlock_bh(&adapter->host_target_sync_lock);
+
+	if (interval > 0)
+		qdf_mc_timer_start(&adapter->host_target_sync_timer, interval);
+}
+
+static inline bool hdd_tsf_is_in_cap(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hddctx;
+
+	hddctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hddctx)
+		return false;
+
+	return qdf_atomic_read(&hddctx->cap_tsf_flag) > 0;
+}
+
+/* define 64bit plus/minus to deal with overflow */
+static inline int hdd_64bit_plus(uint64_t x, int64_t y, uint64_t *ret)
+{
+	if ((y < 0 && (-y) > x) ||
+	    (y > 0 && (y > U64_MAX - x))) {
+		*ret = 0;
+		return -EINVAL;
+	}
+
+	*ret = x + y;
+	return 0;
+}
+
+static inline int hdd_uint64_plus(uint64_t x, uint64_t y, uint64_t *ret)
+{
+	if (!ret)
+		return -EINVAL;
+
+	if (x > (U64_MAX - y)) {
+		*ret = 0;
+		return -EINVAL;
+	}
+
+	*ret = x + y;
+	return 0;
+}
+
+static inline int hdd_uint64_minus(uint64_t x, uint64_t y, uint64_t *ret)
+{
+	if (!ret)
+		return -EINVAL;
+
+	if (x < y) {
+		*ret = 0;
+		return -EINVAL;
+	}
+
+	*ret = x - y;
+	return 0;
+}
+
+static inline int32_t hdd_get_hosttime_from_targettime(
+	struct hdd_adapter *adapter, uint64_t target_time,
+	uint64_t *host_time)
+{
+	int32_t ret = -EINVAL;
+	int64_t delta32_target;
+	bool in_cap_state;
+	int64_t normal_interval_target;
+
+	in_cap_state = hdd_tsf_is_in_cap(adapter);
+
+	/*
+	 * To avoid check the lock when it's not capturing tsf
+	 * (the tstamp-pair won't be changed)
+	 */
+	if (in_cap_state)
+		qdf_spin_lock_bh(&adapter->host_target_sync_lock);
+
+	/* at present, target_time is only 32bit in fact */
+	delta32_target = (int64_t)((target_time & U32_MAX) -
+			(adapter->last_target_time & U32_MAX));
+
+	normal_interval_target =
+		qdf_do_div(WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC *
+			   NSEC_PER_SEC, HOST_TO_TARGET_TIME_RATIO);
+
+	if (delta32_target <
+			(normal_interval_target - OVERFLOW_INDICATOR32))
+		delta32_target += OVERFLOW_INDICATOR32;
+	else if (delta32_target >
+			(OVERFLOW_INDICATOR32 - normal_interval_target))
+		delta32_target -= OVERFLOW_INDICATOR32;
+
+	ret = hdd_64bit_plus(adapter->last_host_time,
+			     HOST_TO_TARGET_TIME_RATIO * delta32_target,
+			     host_time);
+
+	if (in_cap_state)
+		qdf_spin_unlock_bh(&adapter->host_target_sync_lock);
+
+	return ret;
+}
+
+static inline int32_t hdd_get_targettime_from_hosttime(
+	struct hdd_adapter *adapter, uint64_t host_time,
+	uint64_t *target_time)
+{
+	int32_t ret = -EINVAL;
+	bool in_cap_state;
+
+	if (!adapter || host_time == 0)
+		return ret;
+
+	in_cap_state = hdd_tsf_is_in_cap(adapter);
+	if (in_cap_state)
+		qdf_spin_lock_bh(&adapter->host_target_sync_lock);
+
+	if (host_time < adapter->last_host_time)
+		ret = hdd_uint64_minus(adapter->last_target_time,
+				       qdf_do_div(adapter->last_host_time -
+						  host_time,
+						  HOST_TO_TARGET_TIME_RATIO),
+				       target_time);
+	else
+		ret = hdd_uint64_plus(adapter->last_target_time,
+				      qdf_do_div(host_time -
+						 adapter->last_host_time,
+						 HOST_TO_TARGET_TIME_RATIO),
+				      target_time);
+
+	if (in_cap_state)
+		qdf_spin_unlock_bh(&adapter->host_target_sync_lock);
+
+	return ret;
+}
+
+static inline
+uint64_t hdd_get_monotonic_host_time(struct hdd_context *hdd_ctx)
+{
+	return hdd_tsf_is_raw_set(hdd_ctx) ?
+		ktime_get_ns() : ktime_get_real_ns();
+}
+
+static ssize_t __hdd_wlan_tsf_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct hdd_station_ctx *hdd_sta_ctx;
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	ssize_t size;
+	uint64_t host_time, target_time;
+
+	struct net_device *net_dev = container_of(dev, struct net_device, dev);
+
+	adapter = (struct hdd_adapter *)(netdev_priv(net_dev));
+	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
+		return scnprintf(buf, PAGE_SIZE, "Invalid device\n");
+
+	if (!hdd_get_th_sync_status(adapter))
+		return scnprintf(buf, PAGE_SIZE,
+				 "TSF sync is not initialized\n");
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (eConnectionState_Associated != hdd_sta_ctx->conn_info.connState &&
+	    (adapter->device_mode == QDF_STA_MODE ||
+	    adapter->device_mode == QDF_P2P_CLIENT_MODE))
+		return scnprintf(buf, PAGE_SIZE, "NOT connected\n");
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hdd_ctx)
+		return scnprintf(buf, PAGE_SIZE, "Invalid HDD context\n");
+
+	host_time = hdd_get_monotonic_host_time(hdd_ctx);
+
+	if (hdd_get_targettime_from_hosttime(adapter, host_time,
+					     &target_time)) {
+		size = scnprintf(buf, PAGE_SIZE, "Invalid timestamp\n");
+	} else {
+		if (adapter->device_mode == QDF_STA_MODE ||
+		    adapter->device_mode == QDF_P2P_CLIENT_MODE) {
+			size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n",
+					 buf, target_time, host_time,
+					 hdd_sta_ctx->conn_info.bssId.bytes);
+		} else {
+			size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n",
+					 buf, target_time, host_time,
+					 adapter->mac_addr.bytes);
+		}
+	}
+
+	return size;
+}
+
+static ssize_t hdd_wlan_tsf_show(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	ssize_t ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_wlan_tsf_show(dev, attr, buf);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static DEVICE_ATTR(tsf, 0400, hdd_wlan_tsf_show, NULL);
+
+static void hdd_capture_tsf_timer_expired_handler(void *arg)
+{
+	uint32_t tsf_op_resp;
+	struct hdd_adapter *adapter;
+
+	if (!arg)
+		return;
+
+	adapter = (struct hdd_adapter *)arg;
+	hdd_capture_tsf_internal(adapter, &tsf_op_resp, 1);
+}
+
+#ifndef WLAN_FEATURE_TSF_PLUS_NOIRQ
+static irqreturn_t hdd_tsf_captured_irq_handler(int irq, void *arg)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	uint64_t host_time;
+	char *name = NULL;
+
+	if (!arg)
+		return IRQ_NONE;
+
+	hdd_ctx = (struct hdd_context *)arg;
+	host_time = hdd_get_monotonic_host_time(hdd_ctx);
+
+	adapter = hdd_ctx->cap_tsf_context;
+	if (!adapter)
+		return IRQ_HANDLED;
+
+	if (!hdd_tsf_is_initialized(adapter)) {
+		hdd_err("tsf is not init, ignore irq");
+		return IRQ_HANDLED;
+	}
+
+	hdd_update_timestamp(adapter, 0, host_time);
+	if (adapter->dev)
+		name = adapter->dev->name;
+
+	hdd_info("irq: %d - iface: %s - host_time: %llu",
+		 irq, (!name ? "none" : name), host_time);
+
+	return IRQ_HANDLED;
+}
+#endif
+
+void hdd_capture_req_timer_expired_handler(void *arg)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	QDF_TIMER_STATE capture_req_timer_status;
+	qdf_mc_timer_t *sync_timer;
+	int interval;
+	int ret;
+
+	if (!arg)
+		return;
+	adapter = (struct hdd_adapter *)arg;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hdd_ctx) {
+		hdd_warn("invalid hdd context");
+		return;
+	}
+
+	if (!hdd_tsf_is_initialized(adapter)) {
+		qdf_mc_timer_destroy(&adapter->host_capture_req_timer);
+		hdd_warn("tsf not init");
+		return;
+	}
+
+	qdf_spin_lock_bh(&adapter->host_target_sync_lock);
+	adapter->cur_host_time = 0;
+	adapter->cur_target_time = 0;
+	qdf_spin_unlock_bh(&adapter->host_target_sync_lock);
+
+	ret = hdd_tsf_reset_gpio(adapter);
+	if (0 != ret)
+		hdd_info("reset tsf gpio fail");
+
+	hdd_ctx->cap_tsf_context = NULL;
+	qdf_atomic_set(&hdd_ctx->cap_tsf_flag, 0);
+	qdf_mc_timer_destroy(&adapter->host_capture_req_timer);
+
+	sync_timer = &adapter->host_target_sync_timer;
+	capture_req_timer_status =
+		qdf_mc_timer_get_current_state(sync_timer);
+
+	if (capture_req_timer_status == QDF_TIMER_STATE_UNUSED) {
+		hdd_warn("invalid timer status");
+		return;
+	}
+
+	interval = WLAN_HDD_CAPTURE_TSF_RESYNC_INTERVAL * MSEC_PER_SEC;
+	qdf_mc_timer_start(sync_timer, interval);
+}
+
+static enum hdd_tsf_op_result hdd_tsf_sync_init(struct hdd_adapter *adapter)
+{
+	QDF_STATUS ret;
+	struct hdd_context *hddctx;
+	struct net_device *net_dev;
+
+	if (!adapter)
+		return HDD_TSF_OP_FAIL;
+
+	hddctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hddctx) {
+		hdd_err("invalid hdd context");
+		return HDD_TSF_OP_FAIL;
+	}
+
+	if (!qdf_atomic_read(&hddctx->tsf_ready_flag)) {
+		hdd_err("TSF feature has NOT been initialized");
+		return HDD_TSF_OP_FAIL;
+	}
+
+	if (hdd_get_th_sync_status(adapter)) {
+		hdd_err("Host Target sync has been initialized!!");
+		return HDD_TSF_OP_SUCC;
+	}
+
+	qdf_spinlock_create(&adapter->host_target_sync_lock);
+
+	hdd_reset_timestamps(adapter);
+
+	ret = qdf_mc_timer_init(&adapter->host_target_sync_timer,
+				QDF_TIMER_TYPE_SW,
+				hdd_capture_tsf_timer_expired_handler,
+				(void *)adapter);
+	if (ret != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to init timer, ret: %d", ret);
+		goto fail;
+	}
+
+	net_dev = adapter->dev;
+	if (net_dev && hdd_tsf_is_dbg_fs_set(hddctx))
+		device_create_file(&net_dev->dev, &dev_attr_tsf);
+	hdd_set_th_sync_status(adapter, true);
+
+	return HDD_TSF_OP_SUCC;
+fail:
+	hdd_set_th_sync_status(adapter, false);
+	return HDD_TSF_OP_FAIL;
+}
+
+static enum hdd_tsf_op_result hdd_tsf_sync_deinit(struct hdd_adapter *adapter)
+{
+	QDF_STATUS ret;
+	struct hdd_context *hddctx;
+	struct net_device *net_dev;
+
+	if (!adapter)
+		return HDD_TSF_OP_FAIL;
+
+	if (!hdd_get_th_sync_status(adapter)) {
+		hdd_err("Host Target sync has not been initialized!!");
+		return HDD_TSF_OP_SUCC;
+	}
+
+	hdd_set_th_sync_status(adapter, false);
+	ret = qdf_mc_timer_destroy(&adapter->host_target_sync_timer);
+	if (ret != QDF_STATUS_SUCCESS)
+		hdd_err("Failed to destroy timer, ret: %d", ret);
+
+	hddctx = WLAN_HDD_GET_CTX(adapter);
+
+	/* reset the cap_tsf flag and gpio if needed */
+	if (hddctx && qdf_atomic_read(&hddctx->cap_tsf_flag) &&
+	    hddctx->cap_tsf_context == adapter) {
+		int reset_ret = hdd_tsf_reset_gpio(adapter);
+
+		if (reset_ret)
+			hdd_err("Failed to reset tsf gpio, ret:%d",
+				reset_ret);
+		hddctx->cap_tsf_context = NULL;
+		qdf_atomic_set(&hddctx->cap_tsf_flag, 0);
+	}
+
+	hdd_reset_timestamps(adapter);
+
+	net_dev = adapter->dev;
+	if (net_dev && hdd_tsf_is_dbg_fs_set(hddctx)) {
+		struct device *dev = &net_dev->dev;
+
+		device_remove_file(dev, &dev_attr_tsf);
+	}
+	return HDD_TSF_OP_SUCC;
+}
+
+#ifdef WLAN_FEATURE_TSF_PLUS_NOIRQ
+static inline void hdd_update_tsf(struct hdd_adapter *adapter, uint64_t tsf)
+{
+	uint32_t tsf_op_resp[3];
+	struct hdd_context *hddctx;
+	uint64_t host_time;
+
+	hddctx = WLAN_HDD_GET_CTX(adapter);
+	host_time = hdd_get_monotonic_host_time(hddctx);
+	hdd_indicate_tsf_internal(adapter, tsf_op_resp, 3);
+	host_time -= qdf_log_timestamp_to_usecs(qdf_get_log_timestamp()
+			- adapter->tsf_sync_soc_timer) * NSEC_PER_USEC;
+	adapter->cur_host_time = host_time;
+	hdd_update_timestamp(adapter, tsf, host_time);
+}
+#else
+static inline void hdd_update_tsf(struct hdd_adapter *adapter, uint64_t tsf)
+{
+	uint32_t tsf_op_resp[3];
+
+	hdd_indicate_tsf_internal(adapter, tsf_op_resp, 3);
+	hdd_update_timestamp(adapter, tsf, 0);
+}
+#endif
+
+static inline
+enum hdd_tsf_op_result hdd_netbuf_timestamp(qdf_nbuf_t netbuf,
+					    uint64_t target_time)
+{
+	struct hdd_adapter *adapter;
+	struct net_device *net_dev = netbuf->dev;
+
+	if (!net_dev)
+		return HDD_TSF_OP_FAIL;
+
+	adapter = (struct hdd_adapter *)(netdev_priv(net_dev));
+	if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC &&
+	    hdd_get_th_sync_status(adapter)) {
+		uint64_t host_time;
+		int32_t ret = hdd_get_hosttime_from_targettime(adapter,
+				target_time, &host_time);
+		if (!ret) {
+			netbuf->tstamp = ns_to_ktime(host_time);
+			return HDD_TSF_OP_SUCC;
+		}
+	}
+
+	return HDD_TSF_OP_FAIL;
+}
+
+int hdd_start_tsf_sync(struct hdd_adapter *adapter)
+{
+	enum hdd_tsf_op_result ret;
+
+	if (!adapter)
+		return -EINVAL;
+
+	ret = hdd_tsf_sync_init(adapter);
+	if (ret != HDD_TSF_OP_SUCC) {
+		hdd_err("Failed to init tsf sync, ret: %d", ret);
+		return -EINVAL;
+	}
+
+	return (__hdd_start_tsf_sync(adapter) ==
+		HDD_TSF_OP_SUCC) ? 0 : -EINVAL;
+}
+
+int hdd_stop_tsf_sync(struct hdd_adapter *adapter)
+{
+	enum hdd_tsf_op_result ret;
+
+	if (!adapter)
+		return -EINVAL;
+
+	ret = __hdd_stop_tsf_sync(adapter);
+	if (ret != HDD_TSF_OP_SUCC)
+		return -EINVAL;
+
+	ret = hdd_tsf_sync_deinit(adapter);
+	if (ret != HDD_TSF_OP_SUCC) {
+		hdd_err("Failed to deinit tsf sync, ret: %d", ret);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int hdd_tx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time)
+{
+	struct sock *sk = netbuf->sk;
+
+	if (!sk)
+		return -EINVAL;
+
+	if ((skb_shinfo(netbuf)->tx_flags & SKBTX_SW_TSTAMP) &&
+	    !(skb_shinfo(netbuf)->tx_flags & SKBTX_IN_PROGRESS)) {
+		struct sock_exterr_skb *serr;
+		qdf_nbuf_t new_netbuf;
+		int err;
+
+		if (hdd_netbuf_timestamp(netbuf, target_time) !=
+		    HDD_TSF_OP_SUCC)
+			return -EINVAL;
+
+		new_netbuf = qdf_nbuf_clone(netbuf);
+		if (!new_netbuf)
+			return -ENOMEM;
+
+		serr = SKB_EXT_ERR(new_netbuf);
+		memset(serr, 0, sizeof(*serr));
+		serr->ee.ee_errno = ENOMSG;
+		serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
+
+		err = sock_queue_err_skb(sk, new_netbuf);
+		if (err) {
+			qdf_nbuf_free(new_netbuf);
+			return err;
+		}
+
+		return 0;
+	}
+	return -EINVAL;
+}
+
+int hdd_rx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time)
+{
+	if (hdd_netbuf_timestamp(netbuf, target_time) ==
+		HDD_TSF_OP_SUCC)
+		return 0;
+
+	/* reset tstamp when failed */
+	netbuf->tstamp = ns_to_ktime(0);
+	return -EINVAL;
+}
+
+static inline int __hdd_capture_tsf(struct hdd_adapter *adapter,
+				    uint32_t *buf, int len)
+{
+	if (!adapter || !buf) {
+		hdd_err("invalid pointer");
+		return -EINVAL;
+	}
+
+	if (len != 1)
+		return -EINVAL;
+
+	buf[0] = TSF_DISABLED_BY_TSFPLUS;
+
+	return 0;
+}
+
+static inline int __hdd_indicate_tsf(struct hdd_adapter *adapter,
+				     uint32_t *buf, int len)
+{
+	if (!adapter || !buf) {
+		hdd_err("invalid pointer");
+		return -EINVAL;
+	}
+
+	if (len != 3)
+		return -EINVAL;
+
+	buf[0] = TSF_DISABLED_BY_TSFPLUS;
+	buf[1] = 0;
+	buf[2] = 0;
+
+	return 0;
+}
+
+#ifdef WLAN_FEATURE_TSF_PLUS_NOIRQ
+static inline
+enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx)
+{
+	if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) {
+		hdd_info("To enable TSF_PLUS, set gtsf_ptp_options in ini");
+		return HDD_TSF_OP_FAIL;
+	}
+
+	if (hdd_tsf_is_tx_set(hdd_ctx))
+		ol_register_timestamp_callback(hdd_tx_timestamp);
+	return HDD_TSF_OP_SUCC;
+}
+
+static inline
+enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	QDF_TIMER_STATE capture_req_timer_status;
+	qdf_mc_timer_t *cap_timer;
+	struct hdd_adapter *adapter, *adapternode_ptr, *next_ptr;
+
+	if (!hdd_tsf_is_ptp_enabled(hdd_ctx))
+		return HDD_TSF_OP_SUCC;
+
+	if (hdd_tsf_is_tx_set(hdd_ctx))
+		ol_deregister_timestamp_callback();
+
+	status = hdd_get_front_adapter(hdd_ctx, &adapternode_ptr);
+
+	while (NULL != adapternode_ptr && QDF_STATUS_SUCCESS == status) {
+		adapter = adapternode_ptr;
+		status =
+		    hdd_get_next_adapter(hdd_ctx, adapternode_ptr, &next_ptr);
+		adapternode_ptr = next_ptr;
+		if (adapter->host_capture_req_timer.state == 0)
+			continue;
+		cap_timer = &adapter->host_capture_req_timer;
+		capture_req_timer_status =
+			qdf_mc_timer_get_current_state(cap_timer);
+
+		if (capture_req_timer_status != QDF_TIMER_STATE_UNUSED) {
+			qdf_mc_timer_stop(cap_timer);
+			status =
+				qdf_mc_timer_destroy(cap_timer);
+			if (status != QDF_STATUS_SUCCESS)
+				hdd_err("remove timer failed: %d", status);
+		}
+	}
+
+	return HDD_TSF_OP_SUCC;
+}
+#else
+static inline
+enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx)
+{
+	int ret;
+
+	if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) {
+		hdd_info("To enable TSF_PLUS, set gtsf_ptp_options in ini");
+		return HDD_TSF_OP_FAIL;
+	}
+
+	ret = cnss_common_register_tsf_captured_handler(
+			hdd_ctx->parent_dev,
+			hdd_tsf_captured_irq_handler,
+			(void *)hdd_ctx);
+	if (ret != 0) {
+		hdd_err("Failed to register irq handler: %d", ret);
+		return HDD_TSF_OP_FAIL;
+	}
+
+	if (hdd_tsf_is_tx_set(hdd_ctx))
+		ol_register_timestamp_callback(hdd_tx_timestamp);
+	return HDD_TSF_OP_SUCC;
+}
+
+static inline
+enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx)
+{
+	int ret;
+
+	if (!hdd_tsf_is_ptp_enabled(hdd_ctx))
+		return HDD_TSF_OP_SUCC;
+
+	if (hdd_tsf_is_tx_set(hdd_ctx))
+		ol_deregister_timestamp_callback();
+
+	ret = cnss_common_unregister_tsf_captured_handler(
+				hdd_ctx->parent_dev,
+				(void *)hdd_ctx);
+	if (ret != 0) {
+		hdd_err("Failed to unregister irq handler, ret:%d",
+			ret);
+		ret = HDD_TSF_OP_FAIL;
+	}
+
+	return HDD_TSF_OP_SUCC;
+}
+#endif
+
+void hdd_tsf_notify_wlan_state_change(struct hdd_adapter *adapter,
+				      eConnectionState old_state,
+				      eConnectionState new_state)
+{
+	if (!adapter)
+		return;
+
+	if (old_state != eConnectionState_Associated &&
+	    new_state == eConnectionState_Associated)
+		hdd_start_tsf_sync(adapter);
+	else if (old_state == eConnectionState_Associated &&
+		 new_state != eConnectionState_Associated)
+		hdd_stop_tsf_sync(adapter);
+}
+#else
+static inline void hdd_update_tsf(struct hdd_adapter *adapter, uint64_t tsf)
+{
+}
+
+static inline int __hdd_indicate_tsf(struct hdd_adapter *adapter,
+				     uint32_t *buf, int len)
+{
+	return (hdd_indicate_tsf_internal(adapter, buf, len) ==
+		HDD_TSF_OP_SUCC) ? 0 : -EINVAL;
+}
+
+static inline int __hdd_capture_tsf(struct hdd_adapter *adapter,
+				    uint32_t *buf, int len)
+{
+	return (hdd_capture_tsf_internal(adapter, buf, len) ==
+		HDD_TSF_OP_SUCC) ? 0 : -EINVAL;
+}
+
+static inline
+enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx)
+{
+	return HDD_TSF_OP_SUCC;
+}
+
+static inline
+enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx)
+{
+	return HDD_TSF_OP_SUCC;
+}
+#endif /* WLAN_FEATURE_TSF_PLUS */
+
+int hdd_capture_tsf(struct hdd_adapter *adapter, uint32_t *buf, int len)
+{
+	return __hdd_capture_tsf(adapter, buf, len);
+}
+
+int hdd_indicate_tsf(struct hdd_adapter *adapter, uint32_t *buf, int len)
+{
+	return __hdd_indicate_tsf(adapter, buf, len);
+}
+
+/**
+ * hdd_get_tsf_cb() - handle tsf callback
+ * @pcb_cxt: pointer to the hdd_contex
+ * @ptsf: pointer to struct stsf
+ *
+ * This function handle the event that reported by firmware at first.
+ * The event contains the vdev_id, current tsf value of this vdev,
+ * tsf value is 64bits, discripted in two varaible tsf_low and tsf_high.
+ * These two values each is uint32.
+ *
+ * Return: 0 for success or non-zero negative failure code
+ */
+int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf)
+{
+	struct hdd_context *hddctx;
+	struct hdd_adapter *adapter;
+	int ret;
+	QDF_STATUS status;
+	QDF_TIMER_STATE capture_req_timer_status;
+	qdf_mc_timer_t *capture_timer;
+
+	if (pcb_cxt == NULL || ptsf == NULL) {
+		hdd_err("HDD context is not valid");
+			return -EINVAL;
+	}
+
+	hddctx = (struct hdd_context *)pcb_cxt;
+	ret = wlan_hdd_validate_context(hddctx);
+	if (0 != ret)
+		return -EINVAL;
+
+	adapter = hdd_get_adapter_by_vdev(hddctx, ptsf->vdev_id);
+
+	if (NULL == adapter) {
+		hdd_err("failed to find adapter");
+		return -EINVAL;
+	}
+
+	if (!hdd_tsf_is_initialized(adapter)) {
+		hdd_err("tsf is not init, ignore tsf event");
+		return -EINVAL;
+	}
+
+	hdd_info("tsf cb handle event, device_mode is %d",
+		adapter->device_mode);
+
+	capture_timer = &adapter->host_capture_req_timer;
+	capture_req_timer_status =
+		qdf_mc_timer_get_current_state(capture_timer);
+	if (capture_req_timer_status == QDF_TIMER_STATE_UNUSED) {
+		hdd_warn("invalid timer status");
+		return -EINVAL;
+	}
+
+	qdf_mc_timer_stop(capture_timer);
+	status = qdf_mc_timer_destroy(capture_timer);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_warn("destroy cap req timer fail, ret: %d", status);
+
+	adapter->cur_target_time = ((uint64_t)ptsf->tsf_high << 32 |
+			 ptsf->tsf_low);
+	adapter->tsf_sync_soc_timer = ((uint64_t) ptsf->soc_timer_high << 32 |
+						  ptsf->soc_timer_low);
+
+	complete(&tsf_sync_get_completion_evt);
+	hdd_update_tsf(adapter, adapter->cur_target_time);
+	hdd_info("Vdev=%u, tsf_low=%u, tsf_high=%u soc_timer=%llu",
+		ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high,
+		adapter->tsf_sync_soc_timer);
+	return 0;
+}
+
+static const struct nla_policy tsf_policy[QCA_WLAN_VENDOR_ATTR_TSF_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_TSF_CMD] = {.type = NLA_U32},
+};
+
+/**
+ * __wlan_hdd_cfg80211_handle_tsf_cmd(): Setup TSF operations
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Handle TSF SET / GET operation from userspace
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_TSF_MAX + 1];
+	int status, ret;
+	struct sk_buff *reply_skb;
+	uint32_t tsf_op_resp[3], tsf_cmd;
+
+	hdd_enter_dev(wdev->netdev);
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return -EINVAL;
+
+	if (wlan_cfg80211_nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TSF_MAX,
+				    data, data_len, tsf_policy)) {
+		hdd_err("Invalid TSF cmd");
+		return -EINVAL;
+	}
+
+	if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TSF_CMD]) {
+		hdd_err("Invalid TSF cmd");
+		return -EINVAL;
+	}
+	tsf_cmd = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TSF_CMD]);
+
+	if (tsf_cmd == QCA_TSF_CAPTURE || tsf_cmd == QCA_TSF_SYNC_GET) {
+		hdd_capture_tsf(adapter, tsf_op_resp, 1);
+		switch (tsf_op_resp[0]) {
+		case TSF_RETURN:
+			status = 0;
+			break;
+		case TSF_CURRENT_IN_CAP_STATE:
+			status = -EALREADY;
+			break;
+		case TSF_STA_NOT_CONNECTED_NO_TSF:
+		case TSF_SAP_NOT_STARTED_NO_TSF:
+			status = -EPERM;
+			break;
+		default:
+		case TSF_CAPTURE_FAIL:
+			status = -EINVAL;
+			break;
+		}
+	}
+	if (status < 0)
+		goto end;
+
+	if (tsf_cmd == QCA_TSF_SYNC_GET) {
+		ret = wait_for_completion_timeout(&tsf_sync_get_completion_evt,
+			msecs_to_jiffies(WLAN_TSF_SYNC_GET_TIMEOUT));
+		if (ret == 0) {
+			status = -ETIMEDOUT;
+			goto end;
+		}
+	}
+
+	if (tsf_cmd == QCA_TSF_GET || tsf_cmd == QCA_TSF_SYNC_GET) {
+		hdd_indicate_tsf(adapter, tsf_op_resp, 3);
+		switch (tsf_op_resp[0]) {
+		case TSF_RETURN:
+			status = 0;
+			break;
+		case TSF_NOT_RETURNED_BY_FW:
+			status = -EINPROGRESS;
+			break;
+		case TSF_STA_NOT_CONNECTED_NO_TSF:
+		case TSF_SAP_NOT_STARTED_NO_TSF:
+			status = -EPERM;
+			break;
+		default:
+			status = -EINVAL;
+			break;
+		}
+		if (status != 0)
+			goto end;
+
+		reply_skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
+					sizeof(uint64_t) * 2 + NLMSG_HDRLEN,
+					QCA_NL80211_VENDOR_SUBCMD_TSF_INDEX,
+					GFP_KERNEL);
+		if (!reply_skb) {
+			hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+			status = -ENOMEM;
+			goto end;
+		}
+		if (hdd_wlan_nla_put_u64(reply_skb,
+				QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE,
+				adapter->cur_target_time) ||
+		    hdd_wlan_nla_put_u64(reply_skb,
+				QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE,
+				adapter->tsf_sync_soc_timer)) {
+			hdd_err("nla put fail");
+			kfree_skb(reply_skb);
+			status = -EINVAL;
+			goto end;
+		}
+		status = cfg80211_vendor_cmd_reply(reply_skb);
+	}
+
+end:
+	hdd_info("TSF operation %d status: %d", tsf_cmd, status);
+	return status;
+}
+
+int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_handle_tsf_cmd(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * wlan_hdd_tsf_init() - set callback to handle tsf value.
+ * @hdd_ctx: pointer to the struct hdd_context
+ *
+ * This function set the callback to sme module, the callback will be
+ * called when a tsf event is reported by firmware
+ *
+ * Return: none
+ */
+void wlan_hdd_tsf_init(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+
+	if (!hdd_ctx)
+		return;
+
+	if (qdf_atomic_inc_return(&hdd_ctx->tsf_ready_flag) > 1)
+		return;
+
+	qdf_atomic_init(&hdd_ctx->cap_tsf_flag);
+
+	status = hdd_tsf_set_gpio(hdd_ctx);
+
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("set tsf GPIO failed, status: %d", status);
+		goto fail;
+	}
+
+	if (wlan_hdd_tsf_plus_init(hdd_ctx) != HDD_TSF_OP_SUCC)
+		goto fail;
+
+	return;
+
+fail:
+	qdf_atomic_set(&hdd_ctx->tsf_ready_flag, 0);
+}
+
+void wlan_hdd_tsf_deinit(struct hdd_context *hdd_ctx)
+{
+	if (!hdd_ctx)
+		return;
+
+	if (!qdf_atomic_read(&hdd_ctx->tsf_ready_flag))
+		return;
+
+	wlan_hdd_tsf_plus_deinit(hdd_ctx);
+	qdf_atomic_set(&hdd_ctx->tsf_ready_flag, 0);
+	qdf_atomic_set(&hdd_ctx->cap_tsf_flag, 0);
+}
diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c
new file mode 100644
index 0000000..2f4ac71
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_twt.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2018 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 : wlan_hdd_twt.c
+ *
+ * WLAN Host Device Driver file for TWT (Target Wake Time) support.
+ *
+ */
+
+#include "wlan_hdd_twt.h"
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_cfg.h"
+#include "cfg_api.h"
+#include "sme_api.h"
+#include "wma_twt.h"
+
+void hdd_update_tgt_twt_cap(struct hdd_context *hdd_ctx,
+			    struct wma_tgt_cfg *cfg)
+{
+	struct wma_tgt_services *services = &cfg->services;
+
+	hdd_debug("TWT: enable_twt=%d, tgt Req=%d, Res=%d",
+		  hdd_ctx->config->enable_twt, services->twt_requestor,
+		  services->twt_responder);
+
+	sme_cfg_set_int(hdd_ctx->mac_handle, WNI_CFG_TWT_REQUESTOR,
+			QDF_MIN(services->twt_requestor,
+				hdd_ctx->config->enable_twt));
+
+	sme_cfg_set_int(hdd_ctx->mac_handle, WNI_CFG_TWT_RESPONDER,
+			QDF_MIN(services->twt_responder,
+				hdd_ctx->config->enable_twt));
+
+	/*
+	 * Currently broadcast TWT is not supported
+	 */
+	sme_cfg_set_int(hdd_ctx->mac_handle, WNI_CFG_BCAST_TWT,
+			QDF_MIN(0, hdd_ctx->config->enable_twt));
+}
+
+void hdd_send_twt_enable_cmd(struct hdd_context *hdd_ctx)
+{
+	uint8_t pdev_id = hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id;
+	uint32_t req_val = 0, resp_val = 0, bcast_val = 0;
+	uint32_t congestion_timeout = hdd_ctx->config->twt_congestion_timeout;
+
+	sme_cfg_get_int(hdd_ctx->mac_handle, WNI_CFG_TWT_REQUESTOR, &req_val);
+	sme_cfg_get_int(hdd_ctx->mac_handle, WNI_CFG_TWT_RESPONDER, &resp_val);
+	sme_cfg_get_int(hdd_ctx->mac_handle, WNI_CFG_BCAST_TWT, &bcast_val);
+
+	hdd_debug("TWT cfg req:%d, responder:%d, bcast:%d, pdev:%d, cong:%d",
+		  req_val, resp_val, bcast_val, pdev_id, congestion_timeout);
+
+	if (req_val || resp_val || bcast_val)
+		wma_send_twt_enable_cmd(pdev_id, congestion_timeout);
+}
+
+/**
+ * hdd_twt_enable_comp_cb() - TWT enable complete event callback
+ * @hdd_handle: opaque handle for the global HDD Context
+ * @twt_event: TWT event data received from the target
+ *
+ * Return: None
+ */
+static void
+hdd_twt_enable_comp_cb(hdd_handle_t hdd_handle,
+		       struct wmi_twt_enable_complete_event_param *params)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	enum twt_status prev_state;
+
+	if (!hdd_ctx) {
+		hdd_err("TWT: Invalid HDD Context");
+		return;
+	}
+	prev_state = hdd_ctx->twt_state;
+	if (params->status == WMI_HOST_ENABLE_TWT_STATUS_OK ||
+	    params->status == WMI_HOST_ENABLE_TWT_STATUS_ALREADY_ENABLED) {
+		switch (prev_state) {
+		case TWT_FW_TRIGGER_ENABLE_REQUESTED:
+			hdd_ctx->twt_state = TWT_FW_TRIGGER_ENABLED;
+			break;
+		case TWT_HOST_TRIGGER_ENABLE_REQUESTED:
+			hdd_ctx->twt_state = TWT_HOST_TRIGGER_ENABLED;
+			break;
+		default:
+			break;
+		}
+	}
+	if (params->status == WMI_HOST_ENABLE_TWT_INVALID_PARAM ||
+	    params->status == WMI_HOST_ENABLE_TWT_STATUS_UNKNOWN_ERROR)
+		hdd_ctx->twt_state = TWT_INIT;
+
+	hdd_debug("TWT: pdev ID:%d, status:%d State transitioned from %d to %d",
+		  params->pdev_id, params->status,
+		  prev_state, hdd_ctx->twt_state);
+}
+
+/**
+ * hdd_twt_disable_comp_cb() - TWT disable complete event callback
+ * @hdd_handle: opaque handle for the global HDD Context
+ *
+ * Return: None
+ */
+static void
+hdd_twt_disable_comp_cb(hdd_handle_t hdd_handle)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	enum twt_status prev_state;
+
+	if (!hdd_ctx) {
+		hdd_err("TWT: Invalid HDD Context");
+		return;
+	}
+	prev_state = hdd_ctx->twt_state;
+	hdd_ctx->twt_state = TWT_DISABLED;
+
+	hdd_debug("TWT: State transitioned from %d to %d",
+		  prev_state, hdd_ctx->twt_state);
+}
+
+void wlan_hdd_twt_init(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+
+	hdd_ctx->twt_state = TWT_INIT;
+	status = sme_register_twt_enable_complete_cb(hdd_ctx->mac_handle,
+						     hdd_twt_enable_comp_cb);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Register twt enable complete failed");
+		return;
+	}
+
+	status = sme_register_twt_disable_complete_cb(hdd_ctx->mac_handle,
+						      hdd_twt_disable_comp_cb);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Register twt disable complete failed");
+		goto twt_init_fail;
+	}
+	hdd_send_twt_enable_cmd(hdd_ctx);
+	return;
+
+twt_init_fail:
+
+	sme_deregister_twt_enable_complete_cb(hdd_ctx->mac_handle);
+}
+
+void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+
+	status  = sme_deregister_twt_disable_complete_cb(hdd_ctx->mac_handle);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("De-register of twt disable cb failed: %d", status);
+	status  = sme_deregister_twt_enable_complete_cb(hdd_ctx->mac_handle);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("De-register of twt enable cb failed: %d", status);
+
+	hdd_ctx->twt_state = TWT_CLOSED;
+}
diff --git a/core/hdd/src/wlan_hdd_tx_power.c b/core/hdd/src/wlan_hdd_tx_power.c
new file mode 100644
index 0000000..5ed261a
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_tx_power.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_tx_power.c
+ *
+ * WLAN tx power setting functions
+ *
+ */
+
+#include <wlan_hdd_includes.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <wma_api.h>
+#include <wlan_hdd_tx_power.h>
+
+#define MAX_TXPOWER_SCALE 4
+
+static const struct nla_policy
+txpower_scale_policy[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE] = { .type = NLA_U8 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_txpower_scale () - txpower scaling
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_txpower_scale(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data,
+					     int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter;
+	int ret;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX + 1];
+	uint8_t scale_value;
+	QDF_STATUS status;
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX,
+				    data, data_len, txpower_scale_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE]) {
+		hdd_err("attr tx power scale failed");
+		return -EINVAL;
+	}
+
+	scale_value = nla_get_u8(tb
+		    [QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE]);
+
+	if (scale_value > MAX_TXPOWER_SCALE) {
+		hdd_err("Invalid tx power scale level");
+		return -EINVAL;
+	}
+
+	status = wma_set_tx_power_scale(adapter->session_id, scale_value);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Set tx power scale failed");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int wlan_hdd_cfg80211_txpower_scale(struct wiphy *wiphy,
+				    struct wireless_dev *wdev,
+				    const void *data,
+				    int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_txpower_scale(wiphy, wdev,
+						data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static const struct nla_policy txpower_scale_decr_db_policy
+[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB] = { .type = NLA_U8 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_txpower_scale_decr_db () - txpower scaling
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_txpower_scale_decr_db(struct wiphy *wiphy,
+					  struct wireless_dev *wdev,
+					  const void *data,
+					  int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter;
+	int ret;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_MAX + 1];
+	uint8_t scale_value;
+	QDF_STATUS status;
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+	if (wlan_cfg80211_nla_parse(tb,
+				QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_MAX,
+				data, data_len,
+				txpower_scale_decr_db_policy)) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB]) {
+		hdd_err("attr tx power decrease db value failed");
+		return -EINVAL;
+	}
+
+	scale_value = nla_get_u8(tb
+		    [QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB]);
+
+	status = wma_set_tx_power_scale_decr_db(adapter->session_id,
+						scale_value);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Set tx power decrease db failed");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int wlan_hdd_cfg80211_txpower_scale_decr_db(struct wiphy *wiphy,
+					    struct wireless_dev *wdev,
+					    const void *data,
+					    int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_txpower_scale_decr_db(wiphy, wdev,
+							data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
diff --git a/core/hdd/src/wlan_hdd_tx_power.h b/core/hdd/src/wlan_hdd_tx_power.h
new file mode 100644
index 0000000..3ba2792
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_tx_power.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef __WLAN_HDD_TX_POWER_H
+#define __WLAN_HDD_TX_POWER_H
+
+/**
+ * DOC: wlan_hdd_tx_power_h
+ *
+ * WLAN Host Device Driver TX power setting API specification
+ */
+
+#ifdef FEATURE_TX_POWER
+/**
+ * wlan_hdd_cfg80211_txpower_scale () - txpower scaling
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_txpower_scale(struct wiphy *wiphy,
+				    struct wireless_dev *wdev,
+				    const void *data,
+				    int data_len);
+
+/**
+ * wlan_hdd_cfg80211_txpower_scale_decr_db () - txpower scaling
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_txpower_scale_decr_db(struct wiphy *wiphy,
+					    struct wireless_dev *wdev,
+					    const void *data,
+					    int data_len);
+
+#define FEATURE_TX_POWER_VENDOR_COMMANDS				\
+{									\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,			\
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE,	\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |				\
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |			\
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,			\
+	.doit = wlan_hdd_cfg80211_txpower_scale				\
+},									\
+{									\
+	.info.vendor_id = QCA_NL80211_VENDOR_ID,			\
+	.info.subcmd =							\
+		QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE_DECR_DB,	\
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |				\
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |			\
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,			\
+	.doit = wlan_hdd_cfg80211_txpower_scale_decr_db			\
+},
+#else /* FEATURE_TX_POWER */
+#define FEATURE_TX_POWER_VENDOR_COMMANDS
+#endif /* FEATURE_TX_POWER */
+
+#endif /* __WLAN_HDD_TX_POWER_H */
+
diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c
new file mode 100644
index 0000000..182d5e5
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_tx_rx.c
@@ -0,0 +1,2815 @@
+/*
+ * Copyright (c) 2012-2018 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: wlan_hdd_tx_rx.c
+ *
+ * Linux HDD Tx/RX APIs
+ */
+
+/* denote that this file does not allow legacy hddLog */
+#define HDD_DISALLOW_LEGACY_HDDLOG 1
+
+#include <wlan_hdd_tx_rx.h>
+#include <wlan_hdd_softap_tx_rx.h>
+#include <wlan_hdd_napi.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <linux/inetdevice.h>
+#include <cds_sched.h>
+#include <cds_utils.h>
+
+#include <wlan_hdd_p2p.h>
+#include <linux/wireless.h>
+#include <net/cfg80211.h>
+#include <net/ieee80211_radiotap.h>
+#include "sap_api.h"
+#include "wlan_hdd_wmm.h"
+#include "wlan_hdd_tdls.h"
+#include "wlan_hdd_ocb.h"
+#include "wlan_hdd_lro.h"
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_peer_ops.h>
+#include <cdp_txrx_flow_ctrl_v2.h>
+#include "wlan_hdd_nan_datapath.h"
+#include "pld_common.h"
+#include <cdp_txrx_misc.h>
+#include "wlan_hdd_rx_monitor.h"
+#include "wlan_hdd_power.h"
+#include "wlan_hdd_cfg80211.h"
+#include <wlan_hdd_tsf.h>
+#include <net/tcp.h>
+#include "wma_api.h"
+
+#include "wlan_hdd_nud_tracking.h"
+#include "dp_txrx.h"
+#include "cfg_ucfg_api.h"
+
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+/*
+ * Mapping Linux AC interpretation to SME AC.
+ * Host has 5 tx queues, 4 flow-controlled queues for regular traffic and
+ * one non-flow-controlled queue for high priority control traffic(EOPOL, DHCP).
+ * The fifth queue is mapped to AC_VO to allow for proper prioritization.
+ */
+const uint8_t hdd_qdisc_ac_to_tl_ac[] = {
+	SME_AC_VO,
+	SME_AC_VI,
+	SME_AC_BE,
+	SME_AC_BK,
+	SME_AC_VO,
+};
+
+#else
+const uint8_t hdd_qdisc_ac_to_tl_ac[] = {
+	SME_AC_VO,
+	SME_AC_VI,
+	SME_AC_BE,
+	SME_AC_BK,
+};
+
+#endif
+
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+void hdd_register_hl_netdev_fc_timer(struct hdd_adapter *adapter,
+				     qdf_mc_timer_callback_t timer_callback)
+{
+	if (!adapter->tx_flow_timer_initialized) {
+		qdf_mc_timer_init(&adapter->tx_flow_control_timer,
+				  QDF_TIMER_TYPE_SW, timer_callback, adapter);
+		adapter->tx_flow_timer_initialized = true;
+	}
+}
+
+/**
+ * hdd_deregister_hl_netdev_fc_timer() - Deregister HL Flow Control Timer
+ * @adapter: adapter handle
+ *
+ * Return: none
+ */
+void hdd_deregister_hl_netdev_fc_timer(struct hdd_adapter *adapter)
+{
+	if (adapter->tx_flow_timer_initialized) {
+		qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
+		qdf_mc_timer_destroy(&adapter->tx_flow_control_timer);
+		adapter->tx_flow_timer_initialized = false;
+	}
+}
+
+/**
+ * hdd_tx_resume_timer_expired_handler() - TX Q resume timer handler
+ * @adapter_context: pointer to vdev adapter
+ *
+ * Return: None
+ */
+void hdd_tx_resume_timer_expired_handler(void *adapter_context)
+{
+	struct hdd_adapter *adapter = (struct hdd_adapter *)adapter_context;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	u32 p_qpaused;
+	u32 np_qpaused;
+
+	if (!adapter) {
+		hdd_err("invalid adapter context");
+		return;
+	}
+
+	hdd_debug("Enabling queues");
+	spin_lock_bh(&adapter->pause_map_lock);
+	p_qpaused = adapter->pause_map & BIT(WLAN_DATA_FLOW_CONTROL_PRIORITY);
+	np_qpaused = adapter->pause_map & BIT(WLAN_DATA_FLOW_CONTROL);
+	spin_unlock_bh(&adapter->pause_map_lock);
+
+	if (p_qpaused) {
+		wlan_hdd_netif_queue_control(adapter,
+					     WLAN_NETIF_PRIORITY_QUEUE_ON,
+					     WLAN_DATA_FLOW_CONTROL_PRIORITY);
+		cdp_hl_fc_set_os_queue_status(soc,
+					      adapter->session_id,
+					      WLAN_NETIF_PRIORITY_QUEUE_ON);
+	}
+	if (np_qpaused) {
+		wlan_hdd_netif_queue_control(adapter,
+					     WLAN_WAKE_NON_PRIORITY_QUEUE,
+					     WLAN_DATA_FLOW_CONTROL);
+		cdp_hl_fc_set_os_queue_status(soc,
+					      adapter->session_id,
+					      WLAN_WAKE_NON_PRIORITY_QUEUE);
+	}
+}
+
+#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+/**
+ * hdd_tx_resume_timer_expired_handler() - TX Q resume timer handler
+ * @adapter_context: pointer to vdev adapter
+ *
+ * If Blocked OS Q is not resumed during timeout period, to prevent
+ * permanent stall, resume OS Q forcefully.
+ *
+ * Return: None
+ */
+void hdd_tx_resume_timer_expired_handler(void *adapter_context)
+{
+	struct hdd_adapter *adapter = (struct hdd_adapter *) adapter_context;
+
+	if (!adapter) {
+		/* INVALID ARG */
+		return;
+	}
+
+	hdd_debug("Enabling queues");
+	wlan_hdd_netif_queue_control(adapter, WLAN_WAKE_ALL_NETIF_QUEUE,
+				     WLAN_CONTROL_PATH);
+}
+#if defined(CONFIG_PER_VDEV_TX_DESC_POOL)
+
+/**
+ * hdd_tx_resume_false() - Resume OS TX Q false leads to queue disabling
+ * @adapter: pointer to hdd adapter
+ * @tx_resume: TX Q resume trigger
+ *
+ *
+ * Return: None
+ */
+static void
+hdd_tx_resume_false(struct hdd_adapter *adapter, bool tx_resume)
+{
+	if (true == tx_resume)
+		return;
+
+	/* Pause TX  */
+	hdd_debug("Disabling queues");
+	wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
+				     WLAN_DATA_FLOW_CONTROL);
+
+	if (QDF_TIMER_STATE_STOPPED ==
+			qdf_mc_timer_get_current_state(&adapter->
+						       tx_flow_control_timer)) {
+		QDF_STATUS status;
+
+		status = qdf_mc_timer_start(&adapter->tx_flow_control_timer,
+				WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
+
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("Failed to start tx_flow_control_timer");
+		else
+			adapter->hdd_stats.tx_rx_stats.txflow_timer_cnt++;
+	}
+
+	adapter->hdd_stats.tx_rx_stats.txflow_pause_cnt++;
+	adapter->hdd_stats.tx_rx_stats.is_txflow_paused = true;
+}
+#else
+
+static inline void
+hdd_tx_resume_false(struct hdd_adapter *adapter, bool tx_resume)
+{
+}
+#endif
+
+static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter,
+		struct sk_buff *skb)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int need_orphan = 0;
+
+	if (adapter->tx_flow_low_watermark > 0) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
+		/*
+		 * The TCP TX throttling logic is changed a little after
+		 * 3.19-rc1 kernel, the TCP sending limit will be smaller,
+		 * which will throttle the TCP packets to the host driver.
+		 * The TCP UP LINK throughput will drop heavily. In order to
+		 * fix this issue, need to orphan the socket buffer asap, which
+		 * will call skb's destructor to notify the TCP stack that the
+		 * SKB buffer is unowned. And then the TCP stack will pump more
+		 * packets to host driver.
+		 *
+		 * The TX packets might be dropped for UDP case in the iperf
+		 * testing. So need to be protected by follow control.
+		 */
+		need_orphan = 1;
+#else
+		if (hdd_ctx->config->tx_orphan_enable)
+			need_orphan = 1;
+#endif
+	} else if (hdd_ctx->config->tx_orphan_enable) {
+		if (qdf_nbuf_is_ipv4_tcp_pkt(skb) ||
+		    qdf_nbuf_is_ipv6_tcp_pkt(skb))
+			need_orphan = 1;
+	}
+
+	if (need_orphan) {
+		skb_orphan(skb);
+		++adapter->hdd_stats.tx_rx_stats.tx_orphaned;
+	} else
+		skb = skb_unshare(skb, GFP_ATOMIC);
+
+	return skb;
+}
+
+/**
+ * hdd_tx_resume_cb() - Resume OS TX Q.
+ * @adapter_context: pointer to vdev apdapter
+ * @tx_resume: TX Q resume trigger
+ *
+ * Q was stopped due to WLAN TX path low resource condition
+ *
+ * Return: None
+ */
+void hdd_tx_resume_cb(void *adapter_context, bool tx_resume)
+{
+	struct hdd_adapter *adapter = (struct hdd_adapter *) adapter_context;
+	struct hdd_station_ctx *hdd_sta_ctx = NULL;
+
+	if (!adapter) {
+		/* INVALID ARG */
+		return;
+	}
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	/* Resume TX  */
+	if (true == tx_resume) {
+		if (QDF_TIMER_STATE_STOPPED !=
+		    qdf_mc_timer_get_current_state(&adapter->
+						   tx_flow_control_timer)) {
+			qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
+		}
+		hdd_debug("Enabling queues");
+		wlan_hdd_netif_queue_control(adapter,
+					     WLAN_WAKE_ALL_NETIF_QUEUE,
+					     WLAN_DATA_FLOW_CONTROL);
+	}
+	hdd_tx_resume_false(adapter, tx_resume);
+}
+
+bool hdd_tx_flow_control_is_pause(void *adapter_context)
+{
+	struct hdd_adapter *adapter = (struct hdd_adapter *) adapter_context;
+
+	if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		/* INVALID ARG */
+		hdd_err("invalid adapter %pK", adapter);
+		return false;
+	}
+
+	return adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL);
+}
+
+void hdd_register_tx_flow_control(struct hdd_adapter *adapter,
+		qdf_mc_timer_callback_t timer_callback,
+		ol_txrx_tx_flow_control_fp flow_control_fp,
+		ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause_fp)
+{
+	if (adapter->tx_flow_timer_initialized == false) {
+		qdf_mc_timer_init(&adapter->tx_flow_control_timer,
+			  QDF_TIMER_TYPE_SW,
+			  timer_callback,
+			  adapter);
+		adapter->tx_flow_timer_initialized = true;
+	}
+	cdp_fc_register(cds_get_context(QDF_MODULE_ID_SOC),
+		adapter->session_id, flow_control_fp, adapter,
+		flow_control_is_pause_fp);
+}
+
+/**
+ * hdd_deregister_tx_flow_control() - Deregister TX Flow control
+ * @adapter: adapter handle
+ *
+ * Return: none
+ */
+void hdd_deregister_tx_flow_control(struct hdd_adapter *adapter)
+{
+	cdp_fc_deregister(cds_get_context(QDF_MODULE_ID_SOC),
+			adapter->session_id);
+	if (adapter->tx_flow_timer_initialized == true) {
+		qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
+		qdf_mc_timer_destroy(&adapter->tx_flow_control_timer);
+		adapter->tx_flow_timer_initialized = false;
+	}
+}
+
+/**
+ * hdd_get_tx_resource() - check tx resources and take action
+ * @adapter: adapter handle
+ * @STAId: station id
+ * @timer_value: timer value
+ *
+ * Return: none
+ */
+void hdd_get_tx_resource(struct hdd_adapter *adapter,
+			uint8_t STAId, uint16_t timer_value)
+{
+	if (false ==
+	    cdp_fc_get_tx_resource(cds_get_context(QDF_MODULE_ID_SOC), STAId,
+				   adapter->tx_flow_low_watermark,
+				   adapter->tx_flow_hi_watermark_offset)) {
+		hdd_debug("Disabling queues lwm %d hwm offset %d",
+			 adapter->tx_flow_low_watermark,
+			 adapter->tx_flow_hi_watermark_offset);
+		wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
+					     WLAN_DATA_FLOW_CONTROL);
+		if ((adapter->tx_flow_timer_initialized == true) &&
+		    (QDF_TIMER_STATE_STOPPED ==
+		    qdf_mc_timer_get_current_state(&adapter->
+						    tx_flow_control_timer))) {
+			qdf_mc_timer_start(&adapter->tx_flow_control_timer,
+					   timer_value);
+			adapter->hdd_stats.tx_rx_stats.txflow_timer_cnt++;
+			adapter->hdd_stats.tx_rx_stats.txflow_pause_cnt++;
+			adapter->hdd_stats.tx_rx_stats.is_txflow_paused = true;
+		}
+	}
+}
+
+#else
+/**
+ * hdd_skb_orphan() - skb_unshare a cloned packed else skb_orphan
+ * @adapter: pointer to HDD adapter
+ * @skb: pointer to skb data packet
+ *
+ * Return: pointer to skb structure
+ */
+static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter,
+		struct sk_buff *skb) {
+
+	struct sk_buff *nskb;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+#endif
+
+	hdd_skb_fill_gso_size(adapter->dev, skb);
+
+	nskb = skb_unshare(skb, GFP_ATOMIC);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
+	if (unlikely(hdd_ctx->config->tx_orphan_enable) && (nskb == skb)) {
+		/*
+		 * For UDP packets we want to orphan the packet to allow the app
+		 * to send more packets. The flow would ultimately be controlled
+		 * by the limited number of tx descriptors for the vdev.
+		 */
+		++adapter->hdd_stats.tx_rx_stats.tx_orphaned;
+		skb_orphan(skb);
+	}
+#endif
+	return nskb;
+}
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+
+uint32_t hdd_txrx_get_tx_ack_count(struct hdd_adapter *adapter)
+{
+	return cdp_get_tx_ack_stats(cds_get_context(QDF_MODULE_ID_SOC),
+				    adapter->session_id);
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * qdf_event_eapol_log() - send event to wlan diag
+ * @skb: skb ptr
+ * @dir: direction
+ * @eapol_key_info: eapol key info
+ *
+ * Return: None
+ */
+void hdd_event_eapol_log(struct sk_buff *skb, enum qdf_proto_dir dir)
+{
+	int16_t eapol_key_info;
+
+	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct host_event_wlan_eapol);
+
+	if ((dir == QDF_TX &&
+		(QDF_NBUF_CB_PACKET_TYPE_EAPOL !=
+		 QDF_NBUF_CB_GET_PACKET_TYPE(skb))))
+		return;
+	else if (!qdf_nbuf_is_ipv4_eapol_pkt(skb))
+		return;
+
+	eapol_key_info = (uint16_t)(*(uint16_t *)
+				(skb->data + EAPOL_KEY_INFO_OFFSET));
+
+	wlan_diag_event.event_sub_type =
+		(dir == QDF_TX ?
+		 WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED :
+		 WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
+	wlan_diag_event.eapol_packet_type = (uint8_t)(*(uint8_t *)
+				(skb->data + EAPOL_PACKET_TYPE_OFFSET));
+	wlan_diag_event.eapol_key_info = eapol_key_info;
+	wlan_diag_event.eapol_rate = 0;
+	qdf_mem_copy(wlan_diag_event.dest_addr,
+			(skb->data + QDF_NBUF_DEST_MAC_OFFSET),
+			sizeof(wlan_diag_event.dest_addr));
+	qdf_mem_copy(wlan_diag_event.src_addr,
+			(skb->data + QDF_NBUF_SRC_MAC_OFFSET),
+			sizeof(wlan_diag_event.src_addr));
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_EAPOL);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+/**
+ * wlan_hdd_classify_pkt() - classify packet
+ * @skb - sk buff
+ *
+ * Return: none
+ */
+void wlan_hdd_classify_pkt(struct sk_buff *skb)
+{
+	struct ethhdr *eh = (struct ethhdr *)skb->data;
+
+	qdf_mem_set(skb->cb, sizeof(skb->cb), 0);
+
+	/* check destination mac address is broadcast/multicast */
+	if (is_broadcast_ether_addr((uint8_t *)eh))
+		QDF_NBUF_CB_GET_IS_BCAST(skb) = true;
+	else if (is_multicast_ether_addr((uint8_t *)eh))
+		QDF_NBUF_CB_GET_IS_MCAST(skb) = true;
+
+	if (qdf_nbuf_is_ipv4_arp_pkt(skb))
+		QDF_NBUF_CB_GET_PACKET_TYPE(skb) =
+			QDF_NBUF_CB_PACKET_TYPE_ARP;
+	else if (qdf_nbuf_is_ipv4_dhcp_pkt(skb))
+		QDF_NBUF_CB_GET_PACKET_TYPE(skb) =
+			QDF_NBUF_CB_PACKET_TYPE_DHCP;
+	else if (qdf_nbuf_is_ipv4_eapol_pkt(skb))
+		QDF_NBUF_CB_GET_PACKET_TYPE(skb) =
+			QDF_NBUF_CB_PACKET_TYPE_EAPOL;
+	else if (qdf_nbuf_is_ipv4_wapi_pkt(skb))
+		QDF_NBUF_CB_GET_PACKET_TYPE(skb) =
+			QDF_NBUF_CB_PACKET_TYPE_WAPI;
+	else if (qdf_nbuf_is_icmp_pkt(skb))
+		QDF_NBUF_CB_GET_PACKET_TYPE(skb) =
+			QDF_NBUF_CB_PACKET_TYPE_ICMP;
+	else if (qdf_nbuf_is_icmpv6_pkt(skb))
+		QDF_NBUF_CB_GET_PACKET_TYPE(skb) =
+			QDF_NBUF_CB_PACKET_TYPE_ICMPv6;
+}
+
+/**
+ * hdd_get_transmit_sta_id() - function to retrieve station id to be used for
+ * sending traffic towards a particular destination address. The destination
+ * address can be unicast, multicast or broadcast
+ *
+ * @adapter: Handle to adapter context
+ * @dst_addr: Destination address
+ * @station_id: station id
+ *
+ * Returns: None
+ */
+static void hdd_get_transmit_sta_id(struct hdd_adapter *adapter,
+			struct sk_buff *skb, uint8_t *station_id)
+{
+	bool mcbc_addr = false;
+	QDF_STATUS status;
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct qdf_mac_addr *dst_addr = NULL;
+
+	dst_addr = (struct qdf_mac_addr *)skb->data;
+	status = hdd_get_peer_sta_id(sta_ctx, dst_addr, station_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		if (QDF_NBUF_CB_GET_IS_BCAST(skb) ||
+				QDF_NBUF_CB_GET_IS_MCAST(skb)) {
+			hdd_debug("Received MC/BC packet for transmission");
+			mcbc_addr = true;
+		}
+	}
+
+	if (adapter->device_mode == QDF_IBSS_MODE ||
+		adapter->device_mode == QDF_NDI_MODE) {
+		/*
+		 * This check is necessary to make sure station id is not
+		 * overwritten for UC traffic in IBSS or NDI mode
+		 */
+		if (mcbc_addr)
+			*station_id = sta_ctx->broadcast_staid;
+	} else {
+		/* For the rest, traffic is directed to AP/P2P GO */
+		if (eConnectionState_Associated == sta_ctx->conn_info.connState)
+			*station_id = sta_ctx->conn_info.staId[0];
+	}
+}
+
+/**
+ * hdd_clear_tx_rx_connectivity_stats() - clear connectivity stats
+ * @hdd_ctx: pointer to HDD Station Context
+ *
+ * Return: None
+ */
+static void hdd_clear_tx_rx_connectivity_stats(struct hdd_adapter *adapter)
+{
+	hdd_info("Clear txrx connectivity stats");
+	qdf_mem_zero(&adapter->hdd_stats.hdd_arp_stats,
+		     sizeof(adapter->hdd_stats.hdd_arp_stats));
+	qdf_mem_zero(&adapter->hdd_stats.hdd_dns_stats,
+		     sizeof(adapter->hdd_stats.hdd_dns_stats));
+	qdf_mem_zero(&adapter->hdd_stats.hdd_tcp_stats,
+		     sizeof(adapter->hdd_stats.hdd_tcp_stats));
+	qdf_mem_zero(&adapter->hdd_stats.hdd_icmpv4_stats,
+		     sizeof(adapter->hdd_stats.hdd_icmpv4_stats));
+	adapter->pkt_type_bitmap = 0;
+	adapter->track_arp_ip = 0;
+	qdf_mem_zero(adapter->dns_payload, adapter->track_dns_domain_len);
+	adapter->track_dns_domain_len = 0;
+	adapter->track_src_port = 0;
+	adapter->track_dest_port = 0;
+	adapter->track_dest_ipv4 = 0;
+}
+
+void hdd_reset_all_adapters_connectivity_stats(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter = NULL, *pNext = NULL;
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	status = hdd_get_front_adapter(hdd_ctx, &adapter);
+
+	while (NULL != adapter && QDF_STATUS_SUCCESS == status) {
+		hdd_clear_tx_rx_connectivity_stats(adapter);
+		status = hdd_get_next_adapter(hdd_ctx, adapter, &pNext);
+		adapter = pNext;
+	}
+
+	hdd_exit();
+}
+
+/**
+ * hdd_is_tx_allowed() - check if Tx is allowed based on current peer state
+ * @skb: pointer to OS packet (sk_buff)
+ * @peer_id: Peer STA ID in peer table
+ *
+ * This function gets the peer state from DP and check if it is either
+ * in OL_TXRX_PEER_STATE_CONN or OL_TXRX_PEER_STATE_AUTH. Only EAP packets
+ * are allowed when peer_state is OL_TXRX_PEER_STATE_CONN. All packets
+ * allowed when peer_state is OL_TXRX_PEER_STATE_AUTH.
+ *
+ * Return: true if Tx is allowed and false otherwise.
+ */
+static inline bool hdd_is_tx_allowed(struct sk_buff *skb, uint8_t peer_id)
+{
+	enum ol_txrx_peer_state peer_state;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	void *peer;
+
+	QDF_BUG(soc);
+	QDF_BUG(pdev);
+
+	peer = cdp_peer_find_by_local_id(soc, pdev, peer_id);
+
+	if (peer == NULL) {
+		hdd_err_rl("Unable to find peer entry for staid: %d", peer_id);
+		return false;
+	}
+
+	peer_state = cdp_peer_state_get(soc, peer);
+	if (likely(OL_TXRX_PEER_STATE_AUTH == peer_state))
+		return true;
+	if (OL_TXRX_PEER_STATE_CONN == peer_state &&
+		(ntohs(skb->protocol) == HDD_ETHERTYPE_802_1_X
+		|| IS_HDD_ETHERTYPE_WAI(skb)))
+		return true;
+	QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("Invalid peer state for Tx: %d"), peer_state);
+	return false;
+}
+
+/**
+ * hdd_tx_rx_is_dns_domain_name_match() - function to check whether dns
+ * domain name in the received skb matches with the tracking dns domain
+ * name or not
+ *
+ * @skb: pointer to skb
+ * @adapter: pointer to adapter
+ *
+ * Returns: true if matches else false
+ */
+static bool hdd_tx_rx_is_dns_domain_name_match(struct sk_buff *skb,
+					       struct hdd_adapter *adapter)
+{
+	uint8_t *domain_name;
+
+	if (adapter->track_dns_domain_len == 0)
+		return false;
+
+	domain_name = qdf_nbuf_get_dns_domain_name(skb,
+						adapter->track_dns_domain_len);
+	if (strncmp(domain_name, adapter->dns_payload,
+		    adapter->track_dns_domain_len) == 0)
+		return true;
+	else
+		return false;
+}
+
+void hdd_tx_rx_collect_connectivity_stats_info(struct sk_buff *skb,
+			void *context,
+			enum connectivity_stats_pkt_status action,
+			uint8_t *pkt_type)
+{
+	uint32_t pkt_type_bitmap;
+	struct hdd_adapter *adapter = NULL;
+
+	adapter = (struct hdd_adapter *)context;
+	if (unlikely(adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "Magic cookie(%x) for adapter sanity verification is invalid",
+			  adapter->magic);
+		return;
+	}
+
+	/* ARP tracking is done already. */
+	pkt_type_bitmap = adapter->pkt_type_bitmap;
+	pkt_type_bitmap &= ~CONNECTIVITY_CHECK_SET_ARP;
+
+	if (!pkt_type_bitmap)
+		return;
+
+	switch (action) {
+	case PKT_TYPE_REQ:
+	case PKT_TYPE_TX_HOST_FW_SENT:
+		if (qdf_nbuf_is_icmp_pkt(skb)) {
+			if (qdf_nbuf_data_is_icmpv4_req(skb) &&
+			    (adapter->track_dest_ipv4 ==
+					qdf_nbuf_get_icmpv4_tgt_ip(skb))) {
+				*pkt_type = CONNECTIVITY_CHECK_SET_ICMPV4;
+				if (action == PKT_TYPE_REQ) {
+					++adapter->hdd_stats.hdd_icmpv4_stats.
+							tx_icmpv4_req_count;
+					QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+						  QDF_TRACE_LEVEL_INFO_HIGH,
+						  "%s : ICMPv4 Req packet",
+						  __func__);
+				} else
+					/* host receives tx completion */
+					++adapter->hdd_stats.hdd_icmpv4_stats.
+								tx_host_fw_sent;
+			}
+		} else if (qdf_nbuf_is_ipv4_tcp_pkt(skb)) {
+			if (qdf_nbuf_data_is_tcp_syn(skb) &&
+			    (adapter->track_dest_port ==
+					qdf_nbuf_data_get_tcp_dst_port(skb))) {
+				*pkt_type = CONNECTIVITY_CHECK_SET_TCP_SYN;
+				if (action == PKT_TYPE_REQ) {
+					++adapter->hdd_stats.hdd_tcp_stats.
+							tx_tcp_syn_count;
+					QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+						  QDF_TRACE_LEVEL_INFO_HIGH,
+						  "%s : TCP Syn packet",
+						  __func__);
+				} else
+					/* host receives tx completion */
+					++adapter->hdd_stats.hdd_tcp_stats.
+							tx_tcp_syn_host_fw_sent;
+			} else if ((adapter->hdd_stats.hdd_tcp_stats.
+				    is_tcp_syn_ack_rcv || adapter->hdd_stats.
+					hdd_tcp_stats.is_tcp_ack_sent) &&
+				   qdf_nbuf_data_is_tcp_ack(skb) &&
+				   (adapter->track_dest_port ==
+				    qdf_nbuf_data_get_tcp_dst_port(skb))) {
+				*pkt_type = CONNECTIVITY_CHECK_SET_TCP_ACK;
+				if (action == PKT_TYPE_REQ &&
+					adapter->hdd_stats.hdd_tcp_stats.
+							is_tcp_syn_ack_rcv) {
+					++adapter->hdd_stats.hdd_tcp_stats.
+							tx_tcp_ack_count;
+					adapter->hdd_stats.hdd_tcp_stats.
+						is_tcp_syn_ack_rcv = false;
+					adapter->hdd_stats.hdd_tcp_stats.
+						is_tcp_ack_sent = true;
+					QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+						  QDF_TRACE_LEVEL_INFO_HIGH,
+						  "%s : TCP Ack packet",
+						  __func__);
+				} else if (action == PKT_TYPE_TX_HOST_FW_SENT &&
+					adapter->hdd_stats.hdd_tcp_stats.
+							is_tcp_ack_sent) {
+					/* host receives tx completion */
+					++adapter->hdd_stats.hdd_tcp_stats.
+							tx_tcp_ack_host_fw_sent;
+					adapter->hdd_stats.hdd_tcp_stats.
+							is_tcp_ack_sent = false;
+				}
+			}
+		} else if (qdf_nbuf_is_ipv4_udp_pkt(skb)) {
+			if (qdf_nbuf_data_is_dns_query(skb) &&
+			    hdd_tx_rx_is_dns_domain_name_match(skb, adapter)) {
+				*pkt_type = CONNECTIVITY_CHECK_SET_DNS;
+				if (action == PKT_TYPE_REQ) {
+					++adapter->hdd_stats.hdd_dns_stats.
+							tx_dns_req_count;
+					QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+						  QDF_TRACE_LEVEL_INFO_HIGH,
+						  "%s : DNS query packet",
+						  __func__);
+				} else
+					/* host receives tx completion */
+					++adapter->hdd_stats.hdd_dns_stats.
+								tx_host_fw_sent;
+			}
+		}
+		break;
+
+	case PKT_TYPE_RSP:
+		if (qdf_nbuf_is_icmp_pkt(skb)) {
+			if (qdf_nbuf_data_is_icmpv4_rsp(skb) &&
+			    (adapter->track_dest_ipv4 ==
+					qdf_nbuf_get_icmpv4_src_ip(skb))) {
+				++adapter->hdd_stats.hdd_icmpv4_stats.
+							rx_icmpv4_rsp_count;
+				*pkt_type =
+				CONNECTIVITY_CHECK_SET_ICMPV4;
+				QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+					  QDF_TRACE_LEVEL_INFO_HIGH,
+					  "%s : ICMPv4 Res packet", __func__);
+			}
+		} else if (qdf_nbuf_is_ipv4_tcp_pkt(skb)) {
+			if (qdf_nbuf_data_is_tcp_syn_ack(skb) &&
+			    (adapter->track_dest_port ==
+					qdf_nbuf_data_get_tcp_src_port(skb))) {
+				++adapter->hdd_stats.hdd_tcp_stats.
+							rx_tcp_syn_ack_count;
+				adapter->hdd_stats.hdd_tcp_stats.
+					is_tcp_syn_ack_rcv = true;
+				*pkt_type =
+				CONNECTIVITY_CHECK_SET_TCP_SYN_ACK;
+				QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+					  QDF_TRACE_LEVEL_INFO_HIGH,
+					  "%s : TCP Syn ack packet", __func__);
+			}
+		} else if (qdf_nbuf_is_ipv4_udp_pkt(skb)) {
+			if (qdf_nbuf_data_is_dns_response(skb) &&
+			    hdd_tx_rx_is_dns_domain_name_match(skb, adapter)) {
+				++adapter->hdd_stats.hdd_dns_stats.
+							rx_dns_rsp_count;
+				*pkt_type = CONNECTIVITY_CHECK_SET_DNS;
+				QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+					  QDF_TRACE_LEVEL_INFO_HIGH,
+					  "%s : DNS response packet", __func__);
+			}
+		}
+		break;
+
+	case PKT_TYPE_TX_DROPPED:
+		switch (*pkt_type) {
+		case CONNECTIVITY_CHECK_SET_ICMPV4:
+			++adapter->hdd_stats.hdd_icmpv4_stats.tx_dropped;
+			QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s : ICMPv4 Req packet dropped", __func__);
+			break;
+		case CONNECTIVITY_CHECK_SET_TCP_SYN:
+			++adapter->hdd_stats.hdd_tcp_stats.tx_tcp_syn_dropped;
+			QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s : TCP syn packet dropped", __func__);
+			break;
+		case CONNECTIVITY_CHECK_SET_TCP_ACK:
+			++adapter->hdd_stats.hdd_tcp_stats.tx_tcp_ack_dropped;
+			QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s : TCP ack packet dropped", __func__);
+			break;
+		case CONNECTIVITY_CHECK_SET_DNS:
+			++adapter->hdd_stats.hdd_dns_stats.tx_dropped;
+			QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s : DNS query packet dropped", __func__);
+			break;
+		default:
+			break;
+		}
+		break;
+	case PKT_TYPE_RX_DELIVERED:
+		switch (*pkt_type) {
+		case CONNECTIVITY_CHECK_SET_ICMPV4:
+			++adapter->hdd_stats.hdd_icmpv4_stats.rx_delivered;
+			break;
+		case CONNECTIVITY_CHECK_SET_TCP_SYN_ACK:
+			++adapter->hdd_stats.hdd_tcp_stats.rx_delivered;
+			break;
+		case CONNECTIVITY_CHECK_SET_DNS:
+			++adapter->hdd_stats.hdd_dns_stats.rx_delivered;
+			break;
+		default:
+			break;
+		}
+		break;
+	case PKT_TYPE_RX_REFUSED:
+		switch (*pkt_type) {
+		case CONNECTIVITY_CHECK_SET_ICMPV4:
+			++adapter->hdd_stats.hdd_icmpv4_stats.rx_refused;
+			break;
+		case CONNECTIVITY_CHECK_SET_TCP_SYN_ACK:
+			++adapter->hdd_stats.hdd_tcp_stats.rx_refused;
+			break;
+		case CONNECTIVITY_CHECK_SET_DNS:
+			++adapter->hdd_stats.hdd_dns_stats.rx_refused;
+			break;
+		default:
+			break;
+		}
+		break;
+	case PKT_TYPE_TX_ACK_CNT:
+		switch (*pkt_type) {
+		case CONNECTIVITY_CHECK_SET_ICMPV4:
+			++adapter->hdd_stats.hdd_icmpv4_stats.tx_ack_cnt;
+			break;
+		case CONNECTIVITY_CHECK_SET_TCP_SYN:
+			++adapter->hdd_stats.hdd_tcp_stats.tx_tcp_syn_ack_cnt;
+			break;
+		case CONNECTIVITY_CHECK_SET_TCP_ACK:
+			++adapter->hdd_stats.hdd_tcp_stats.tx_tcp_ack_ack_cnt;
+			break;
+		case CONNECTIVITY_CHECK_SET_DNS:
+			++adapter->hdd_stats.hdd_dns_stats.tx_ack_cnt;
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ * __hdd_hard_start_xmit() - Transmit a frame
+ * @skb: pointer to OS packet (sk_buff)
+ * @dev: pointer to network device
+ *
+ * Function registered with the Linux OS for transmitting
+ * packets. This version of the function directly passes
+ * the packet to Transport Layer.
+ * In case of any packet drop or error, log the error with
+ * INFO HIGH/LOW/MEDIUM to avoid excessive logging in kmsg.
+ *
+ * Return: Always returns NETDEV_TX_OK
+ */
+static netdev_tx_t __hdd_hard_start_xmit(struct sk_buff *skb,
+					 struct net_device *dev)
+{
+	QDF_STATUS status;
+	sme_ac_enum_type ac;
+	enum sme_qos_wmmuptype up;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	bool granted;
+	uint8_t STAId;
+	struct hdd_station_ctx *sta_ctx = &adapter->session.station;
+	struct qdf_mac_addr *mac_addr;
+	uint8_t pkt_type = 0;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	bool is_arp = false;
+
+#ifdef QCA_WIFI_FTM
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		kfree_skb(skb);
+		return NETDEV_TX_OK;
+	}
+#endif
+
+	++adapter->hdd_stats.tx_rx_stats.tx_called;
+	adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0;
+
+	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state() ||
+	    cds_is_load_or_unload_in_progress()) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "Recovery/(Un)load in progress, dropping the packet");
+		goto drop_pkt;
+	}
+
+	wlan_hdd_classify_pkt(skb);
+	if (QDF_NBUF_CB_GET_PACKET_TYPE(skb) == QDF_NBUF_CB_PACKET_TYPE_ARP) {
+		is_arp = true;
+		if (qdf_nbuf_data_is_arp_req(skb) &&
+		    (hdd_ctx->track_arp_ip == qdf_nbuf_get_arp_tgt_ip(skb))) {
+			++adapter->hdd_stats.hdd_arp_stats.tx_arp_req_count;
+			QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+					"%s : ARP packet", __func__);
+		}
+	}
+	/* track connectivity stats */
+	if (adapter->pkt_type_bitmap)
+		hdd_tx_rx_collect_connectivity_stats_info(skb, adapter,
+						PKT_TYPE_REQ, &pkt_type);
+
+	if (cds_is_driver_recovering()) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_WARN,
+			"Recovery in progress, dropping the packet");
+		goto drop_pkt;
+	}
+
+	STAId = HDD_WLAN_INVALID_STA_ID;
+
+	hdd_get_transmit_sta_id(adapter, skb, &STAId);
+	if (STAId >= WLAN_MAX_STA_COUNT) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "Invalid station id, transmit operation suspended");
+		goto drop_pkt;
+	}
+
+	hdd_get_tx_resource(adapter, STAId,
+				WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
+
+	/* Get TL AC corresponding to Qdisc queue index/AC. */
+	ac = hdd_qdisc_ac_to_tl_ac[skb->queue_mapping];
+
+	if (!qdf_nbuf_ipa_owned_get(skb)) {
+		skb = hdd_skb_orphan(adapter, skb);
+		if (!skb)
+			goto drop_pkt_accounting;
+	}
+
+	/*
+	 * Add SKB to internal tracking table before further processing
+	 * in WLAN driver.
+	 */
+	qdf_net_buf_debug_acquire_skb(skb, __FILE__, __LINE__);
+
+	/*
+	 * user priority from IP header, which is already extracted and set from
+	 * select_queue call back function
+	 */
+	up = skb->priority;
+
+	++adapter->hdd_stats.tx_rx_stats.tx_classified_ac[ac];
+#ifdef HDD_WMM_DEBUG
+	QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Classified as ac %d up %d", __func__, ac, up);
+#endif /* HDD_WMM_DEBUG */
+
+	if (HDD_PSB_CHANGED == adapter->psb_changed) {
+		/*
+		 * Function which will determine acquire admittance for a
+		 * WMM AC is required or not based on psb configuration done
+		 * in the framework
+		 */
+		hdd_wmm_acquire_access_required(adapter, ac);
+	}
+	/*
+	 * Make sure we already have access to this access category
+	 * or it is EAPOL or WAPI frame during initial authentication which
+	 * can have artifically boosted higher qos priority.
+	 */
+
+	if (((adapter->psb_changed & (1 << ac)) &&
+		likely(adapter->hdd_wmm_status.wmmAcStatus[ac].
+			wmmAcAccessAllowed)) ||
+		((sta_ctx->conn_info.uIsAuthenticated == false) &&
+		 (QDF_NBUF_CB_PACKET_TYPE_EAPOL ==
+			QDF_NBUF_CB_GET_PACKET_TYPE(skb) ||
+		  QDF_NBUF_CB_PACKET_TYPE_WAPI ==
+			QDF_NBUF_CB_GET_PACKET_TYPE(skb)))) {
+		granted = true;
+	} else {
+		status = hdd_wmm_acquire_access(adapter, ac, &granted);
+		adapter->psb_changed |= (1 << ac);
+	}
+
+	if (!granted) {
+		bool isDefaultAc = false;
+		/*
+		 * ADDTS request for this AC is sent, for now
+		 * send this packet through next available lower
+		 * Access category until ADDTS negotiation completes.
+		 */
+		while (!likely
+			       (adapter->hdd_wmm_status.wmmAcStatus[ac].
+			       wmmAcAccessAllowed)) {
+			switch (ac) {
+			case SME_AC_VO:
+				ac = SME_AC_VI;
+				up = SME_QOS_WMM_UP_VI;
+				break;
+			case SME_AC_VI:
+				ac = SME_AC_BE;
+				up = SME_QOS_WMM_UP_BE;
+				break;
+			case SME_AC_BE:
+				ac = SME_AC_BK;
+				up = SME_QOS_WMM_UP_BK;
+				break;
+			default:
+				ac = SME_AC_BK;
+				up = SME_QOS_WMM_UP_BK;
+				isDefaultAc = true;
+				break;
+			}
+			if (isDefaultAc)
+				break;
+		}
+		skb->priority = up;
+		skb->queue_mapping = hdd_linux_up_to_ac_map[up];
+	}
+
+	adapter->stats.tx_bytes += skb->len;
+
+	mac_addr = (struct qdf_mac_addr *)skb->data;
+
+	ucfg_tdls_update_tx_pkt_cnt(adapter->vdev, mac_addr);
+
+	if (qdf_nbuf_is_tso(skb))
+		adapter->stats.tx_packets += qdf_nbuf_get_tso_num_seg(skb);
+	else
+		++adapter->stats.tx_packets;
+
+	hdd_event_eapol_log(skb, QDF_TX);
+	QDF_NBUF_CB_TX_PACKET_TRACK(skb) = QDF_NBUF_TX_PKT_DATA_TRACK;
+	QDF_NBUF_UPDATE_TX_PKT_COUNT(skb, QDF_NBUF_TX_PKT_HDD);
+
+	qdf_dp_trace_set_track(skb, QDF_TX);
+
+	DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD,
+			QDF_TRACE_DEFAULT_PDEV_ID, qdf_nbuf_data_addr(skb),
+			sizeof(qdf_nbuf_data(skb)),
+			QDF_TX));
+
+	if (!hdd_is_tx_allowed(skb, STAId)) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("Tx not allowed for sta_id: %d"), STAId);
+		++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
+		goto drop_pkt_and_release_skb;
+	}
+
+	/* check whether need to linearize skb, like non-linear udp data */
+	if (hdd_skb_nontso_linearize(skb) != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+			  QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: skb %pK linearize failed. drop the pkt",
+			  __func__, skb);
+		++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
+		goto drop_pkt_and_release_skb;
+	}
+
+	/*
+	 * If a transmit function is not registered, drop packet
+	 */
+	if (!adapter->tx_fn) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+			 "%s: TX function not registered by the data path",
+			 __func__);
+		++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
+		goto drop_pkt_and_release_skb;
+	}
+
+	if (adapter->tx_fn(adapter->txrx_vdev,
+		 (qdf_nbuf_t)skb) != NULL) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: Failed to send packet to txrx for staid: %d",
+			  __func__, STAId);
+		++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
+		goto drop_pkt_and_release_skb;
+	}
+
+	netif_trans_update(dev);
+
+	return NETDEV_TX_OK;
+
+drop_pkt_and_release_skb:
+	qdf_net_buf_debug_release_skb(skb);
+drop_pkt:
+
+	/* track connectivity stats */
+	if (adapter->pkt_type_bitmap)
+		hdd_tx_rx_collect_connectivity_stats_info(skb, adapter,
+							  PKT_TYPE_TX_DROPPED,
+							  &pkt_type);
+	qdf_dp_trace_data_pkt(skb, QDF_TRACE_DEFAULT_PDEV_ID,
+			      QDF_DP_TRACE_DROP_PACKET_RECORD, 0,
+			      QDF_TX);
+	kfree_skb(skb);
+
+drop_pkt_accounting:
+
+	++adapter->stats.tx_dropped;
+	++adapter->hdd_stats.tx_rx_stats.tx_dropped;
+	if (is_arp) {
+		++adapter->hdd_stats.hdd_arp_stats.tx_dropped;
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+			"%s : ARP packet dropped", __func__);
+	}
+
+	return NETDEV_TX_OK;
+}
+
+/**
+ * hdd_hard_start_xmit() - Wrapper function to protect
+ * __hdd_hard_start_xmit from SSR
+ * @skb: pointer to OS packet
+ * @dev: pointer to net_device structure
+ *
+ * Function called by OS if any packet needs to transmit.
+ *
+ * Return: Always returns NETDEV_TX_OK
+ */
+netdev_tx_t hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	netdev_tx_t ret;
+
+	cds_ssr_protect(__func__);
+	ret = __hdd_hard_start_xmit(skb, dev);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_get_peer_sta_id() - Get the StationID using the Peer Mac address
+ * @sta_ctx: pointer to HDD Station Context
+ * @pMacAddress: pointer to Peer Mac address
+ * @staID: pointer to returned Station Index
+ *
+ * Return: QDF_STATUS_SUCCESS/QDF_STATUS_E_FAILURE
+ */
+
+QDF_STATUS hdd_get_peer_sta_id(struct hdd_station_ctx *sta_ctx,
+			       struct qdf_mac_addr *pMacAddress, uint8_t *staId)
+{
+	uint8_t idx;
+
+	for (idx = 0; idx < MAX_PEERS; idx++) {
+		if (!qdf_mem_cmp(&sta_ctx->conn_info.peerMacAddress[idx],
+				    pMacAddress, QDF_MAC_ADDR_SIZE)) {
+			*staId = sta_ctx->conn_info.staId[idx];
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * __hdd_tx_timeout() - TX timeout handler
+ * @dev: pointer to network device
+ *
+ * This function is registered as a netdev ndo_tx_timeout method, and
+ * is invoked by the kernel if the driver takes too long to transmit a
+ * frame.
+ *
+ * Return: None
+ */
+static void __hdd_tx_timeout(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	struct netdev_queue *txq;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	u64 diff_jiffies;
+	int i = 0;
+
+	TX_TIMEOUT_TRACE(dev, QDF_MODULE_ID_HDD_DATA);
+	DPTRACE(qdf_dp_trace(NULL, QDF_DP_TRACE_HDD_TX_TIMEOUT,
+				QDF_TRACE_DEFAULT_PDEV_ID,
+				NULL, 0, QDF_TX));
+
+	/* Getting here implies we disabled the TX queues for too
+	 * long. Queues are disabled either because of disassociation
+	 * or low resource scenarios. In case of disassociation it is
+	 * ok to ignore this. But if associated, we have do possible
+	 * recovery here
+	 */
+
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		txq = netdev_get_tx_queue(dev, i);
+		hdd_info("Queue: %d status: %d txq->trans_start: %lu",
+			 i, netif_tx_queue_stopped(txq), txq->trans_start);
+	}
+
+	hdd_info("carrier state: %d", netif_carrier_ok(dev));
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	wlan_hdd_display_netif_queue_history(hdd_ctx,
+					     QDF_STATS_VERBOSITY_LEVEL_HIGH);
+	cdp_dump_flow_pool_info(cds_get_context(QDF_MODULE_ID_SOC));
+
+	++adapter->hdd_stats.tx_rx_stats.tx_timeout_cnt;
+	++adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt;
+
+	diff_jiffies = jiffies -
+		       adapter->hdd_stats.tx_rx_stats.jiffies_last_txtimeout;
+
+	if ((adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt > 1) &&
+	    (diff_jiffies > (HDD_TX_TIMEOUT * 2))) {
+		/*
+		 * In case when there is no traffic is running, it may
+		 * possible tx time-out may once happen and later system
+		 * recovered then continuous tx timeout count has to be
+		 * reset as it is gets modified only when traffic is running.
+		 * If over a period of time if this count reaches to threshold
+		 * then host triggers a false subsystem restart. In genuine
+		 * time out case kernel will call the tx time-out back to back
+		 * at interval of HDD_TX_TIMEOUT. Here now check if previous
+		 * TX TIME out has occurred more than twice of HDD_TX_TIMEOUT
+		 * back then host may recovered here from data stall.
+		 */
+		adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0;
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+			  "Reset continuous tx timeout stat");
+	}
+
+	adapter->hdd_stats.tx_rx_stats.jiffies_last_txtimeout = jiffies;
+
+	if (adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt >
+	    HDD_TX_STALL_THRESHOLD) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "Data stall due to continuous TX timeouts");
+		adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0;
+		if (cdp_cfg_get(soc, cfg_dp_enable_data_stall))
+			cdp_post_data_stall_event(soc,
+					  DATA_STALL_LOG_INDICATOR_HOST_DRIVER,
+					  DATA_STALL_LOG_HOST_STA_TX_TIMEOUT,
+					  0xFF, 0xFF,
+					  DATA_STALL_LOG_RECOVERY_TRIGGER_PDR);
+	}
+}
+
+/**
+ * hdd_tx_timeout() - Wrapper function to protect __hdd_tx_timeout from SSR
+ * @dev: pointer to net_device structure
+ *
+ * Function called by OS if there is any timeout during transmission.
+ * Since HDD simply enqueues packet and returns control to OS right away,
+ * this would never be invoked
+ *
+ * Return: none
+ */
+void hdd_tx_timeout(struct net_device *dev)
+{
+	cds_ssr_protect(__func__);
+	__hdd_tx_timeout(dev);
+	cds_ssr_unprotect(__func__);
+}
+
+/**
+ * @hdd_init_tx_rx() - Initialize Tx/RX module
+ * @adapter: pointer to adapter context
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS hdd_init_tx_rx(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (NULL == adapter) {
+		hdd_err("adapter is NULL");
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+/**
+ * @hdd_deinit_tx_rx() - Deinitialize Tx/RX module
+ * @adapter: pointer to adapter context
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered,
+ *	   QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS hdd_deinit_tx_rx(struct hdd_adapter *adapter)
+{
+	QDF_BUG(adapter);
+	if (!adapter)
+		return QDF_STATUS_E_FAILURE;
+
+	adapter->txrx_vdev = NULL;
+	adapter->tx_fn = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+/**
+ * hdd_mon_rx_packet_cbk() - Receive callback registered with OL layer.
+ * @context: [in] pointer to qdf context
+ * @rxBuf:      [in] pointer to rx qdf_nbuf
+ *
+ * TL will call this to notify the HDD when one or more packets were
+ * received for a registered STA.
+ *
+ * Return: QDF_STATUS_E_FAILURE if any errors encountered, QDF_STATUS_SUCCESS
+ * otherwise
+ */
+static QDF_STATUS hdd_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf)
+{
+	struct hdd_adapter *adapter;
+	int rxstat;
+	struct sk_buff *skb;
+	struct sk_buff *skb_next;
+	unsigned int cpu_index;
+
+	/* Sanity check on inputs */
+	if ((NULL == context) || (NULL == rxbuf)) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Null params being passed", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	adapter = (struct hdd_adapter *)context;
+	if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "invalid adapter %pK", adapter);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cpu_index = wlan_hdd_get_cpu();
+
+	/* walk the chain until all are processed */
+	skb = (struct sk_buff *) rxbuf;
+	while (NULL != skb) {
+		skb_next = skb->next;
+		skb->dev = adapter->dev;
+
+		++adapter->hdd_stats.tx_rx_stats.rx_packets[cpu_index];
+		++adapter->stats.rx_packets;
+		adapter->stats.rx_bytes += skb->len;
+
+		/* Remove SKB from internal tracking table before submitting
+		 * it to stack
+		 */
+		qdf_net_buf_debug_release_skb(skb);
+
+		/*
+		 * If this is not a last packet on the chain
+		 * Just put packet into backlog queue, not scheduling RX sirq
+		 */
+		if (skb->next) {
+			rxstat = netif_rx(skb);
+		} else {
+			/*
+			 * This is the last packet on the chain
+			 * Scheduling rx sirq
+			 */
+			rxstat = netif_rx_ni(skb);
+		}
+
+		if (NET_RX_SUCCESS == rxstat)
+			++adapter->
+				hdd_stats.tx_rx_stats.rx_delivered[cpu_index];
+		else
+			++adapter->hdd_stats.tx_rx_stats.rx_refused[cpu_index];
+
+		skb = skb_next;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * hdd_get_peer_idx() - Get the idx for given address in peer table
+ * @sta_ctx: pointer to HDD Station Context
+ * @addr: pointer to Peer Mac address
+ *
+ * Return: index when success else INVALID_PEER_IDX
+ */
+int hdd_get_peer_idx(struct hdd_station_ctx *sta_ctx,
+		     struct qdf_mac_addr *addr)
+{
+	uint8_t idx;
+
+	for (idx = 0; idx < MAX_PEERS; idx++) {
+		if (sta_ctx->conn_info.staId[idx] == HDD_WLAN_INVALID_STA_ID)
+			continue;
+		if (qdf_mem_cmp(&sta_ctx->conn_info.peerMacAddress[idx],
+				addr, sizeof(struct qdf_mac_addr)))
+			continue;
+		return idx;
+	}
+
+	return INVALID_PEER_IDX;
+}
+
+/*
+ * hdd_is_mcast_replay() - checks if pkt is multicast replay
+ * @skb: packet skb
+ *
+ * Return: true if replayed multicast pkt, false otherwise
+ */
+static bool hdd_is_mcast_replay(struct sk_buff *skb)
+{
+	struct ethhdr *eth;
+
+	eth = eth_hdr(skb);
+	if (unlikely(skb->pkt_type == PACKET_MULTICAST)) {
+		if (unlikely(ether_addr_equal(eth->h_source,
+				skb->dev->dev_addr)))
+			return true;
+	}
+	return false;
+}
+
+/**
+ * hdd_is_arp_local() - check if local or non local arp
+ * @skb: pointer to sk_buff
+ *
+ * Return: true if local arp or false otherwise.
+ */
+static bool hdd_is_arp_local(struct sk_buff *skb)
+{
+	struct arphdr *arp;
+	struct in_ifaddr **ifap = NULL;
+	struct in_ifaddr *ifa = NULL;
+	struct in_device *in_dev;
+	unsigned char *arp_ptr;
+	__be32 tip;
+
+	arp = (struct arphdr *)skb->data;
+	if (arp->ar_op == htons(ARPOP_REQUEST)) {
+		in_dev = __in_dev_get_rtnl(skb->dev);
+		if (in_dev) {
+			for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
+				ifap = &ifa->ifa_next) {
+				if (!strcmp(skb->dev->name, ifa->ifa_label))
+					break;
+			}
+		}
+
+		if (ifa && ifa->ifa_local) {
+			arp_ptr = (unsigned char *)(arp + 1);
+			arp_ptr += (skb->dev->addr_len + 4 +
+					skb->dev->addr_len);
+			memcpy(&tip, arp_ptr, 4);
+			hdd_debug("ARP packet: local IP: %x dest IP: %x",
+				ifa->ifa_local, tip);
+			if (ifa->ifa_local == tip)
+				return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * hdd_is_rx_wake_lock_needed() - check if wake lock is needed
+ * @skb: pointer to sk_buff
+ *
+ * RX wake lock is needed for:
+ * 1) Unicast data packet OR
+ * 2) Local ARP data packet
+ *
+ * Return: true if wake lock is needed or false otherwise.
+ */
+static bool hdd_is_rx_wake_lock_needed(struct sk_buff *skb)
+{
+	if ((skb->pkt_type != PACKET_BROADCAST &&
+	     skb->pkt_type != PACKET_MULTICAST) || hdd_is_arp_local(skb))
+		return true;
+
+	return false;
+}
+
+#ifdef RECEIVE_OFFLOAD
+/**
+ * hdd_resolve_rx_ol_mode() - Resolve Rx offload method, LRO or GRO
+ * @hdd_ctx: pointer to HDD Station Context
+ *
+ * Return: None
+ */
+static void hdd_resolve_rx_ol_mode(struct hdd_context *hdd_ctx)
+{
+	void *soc;
+
+	soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!(cdp_cfg_get(soc, cfg_dp_lro_enable) ^
+	    cdp_cfg_get(soc, cfg_dp_gro_enable))) {
+		cdp_cfg_get(soc, cfg_dp_lro_enable) &&
+			cdp_cfg_get(soc, cfg_dp_gro_enable) ?
+		hdd_err("Can't enable both LRO and GRO, disabling Rx offload") :
+		hdd_debug("LRO and GRO both are disabled");
+		hdd_ctx->ol_enable = 0;
+	} else if (cdp_cfg_get(soc, cfg_dp_lro_enable)) {
+		hdd_debug("Rx offload LRO is enabled");
+		hdd_ctx->ol_enable = CFG_LRO_ENABLED;
+	} else {
+		hdd_debug("Rx offload GRO is enabled");
+		hdd_ctx->ol_enable = CFG_GRO_ENABLED;
+	}
+}
+
+/**
+ * hdd_gro_rx() - Handle Rx procesing via GRO
+ * @adapter: pointer to adapter context
+ * @skb: pointer to sk_buff
+ *
+ * Return: QDF_STATUS_SUCCESS if processed via GRO or non zero return code
+ */
+static QDF_STATUS hdd_gro_rx(struct hdd_adapter *adapter, struct sk_buff *skb)
+{
+	struct qca_napi_info *qca_napii;
+	struct qca_napi_data *napid;
+	struct napi_struct *napi_to_use;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	/* Only enabling it for STA mode like LRO today */
+	if (QDF_STA_MODE != adapter->device_mode)
+		return QDF_STATUS_E_NOSUPPORT;
+
+	napid = hdd_napi_get_all();
+	if (unlikely(napid == NULL))
+		goto out;
+
+	qca_napii = hif_get_napi(QDF_NBUF_CB_RX_CTX_ID(skb), napid);
+	if (unlikely(qca_napii == NULL))
+		goto out;
+
+	skb_set_hash(skb, QDF_NBUF_CB_RX_FLOW_ID(skb), PKT_HASH_TYPE_L4);
+	/*
+	 * As we are breaking context in Rxthread mode, there is rx_thread NAPI
+	 * corresponds each hif_napi.
+	 */
+	if (adapter->hdd_ctx->enable_rxthread)
+		napi_to_use =  &qca_napii->rx_thread_napi;
+	else
+		napi_to_use = &qca_napii->napi;
+
+	local_bh_disable();
+	napi_gro_receive(napi_to_use, skb);
+	local_bh_enable();
+
+	status = QDF_STATUS_SUCCESS;
+out:
+
+	return status;
+}
+
+/**
+ * hdd_rxthread_napi_gro_flush() - GRO flush callback for NAPI+Rx_Thread Rx mode
+ * @data: hif NAPI context
+ *
+ * Return: none
+ */
+static void hdd_rxthread_napi_gro_flush(void *data)
+{
+	struct qca_napi_info *qca_napii = (struct qca_napi_info *)data;
+
+	local_bh_disable();
+	/*
+	 * As we are breaking context in Rxthread mode, there is rx_thread NAPI
+	 * corresponds each hif_napi.
+	 */
+	napi_gro_flush(&qca_napii->rx_thread_napi, false);
+	local_bh_enable();
+}
+
+/**
+ * hdd_hif_napi_gro_flush() - GRO flush callback for NAPI Rx mode
+ * @data: hif NAPI context
+ *
+ * Return: none
+ */
+static void hdd_hif_napi_gro_flush(void *data)
+{
+	struct qca_napi_info *qca_napii = (struct qca_napi_info *)data;
+
+	local_bh_disable();
+	napi_gro_flush(&qca_napii->napi, false);
+	local_bh_enable();
+}
+
+#ifdef FEATURE_LRO
+/**
+ * hdd_qdf_lro_flush() - LRO flush wrapper
+ * @data: hif NAPI context
+ *
+ * Return: none
+ */
+static void hdd_qdf_lro_flush(void *data)
+{
+	struct qca_napi_info *qca_napii = (struct qca_napi_info *)data;
+	qdf_lro_ctx_t qdf_lro_ctx = qca_napii->lro_ctx;
+
+	qdf_lro_flush(qdf_lro_ctx);
+}
+#else
+static void hdd_qdf_lro_flush(void *data)
+{
+}
+#endif
+
+/**
+ * hdd_register_rx_ol() - Register LRO/GRO rx processing callbacks
+ *
+ * Return: none
+ */
+static void hdd_register_rx_ol(void)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if  (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return;
+	}
+
+	hdd_ctx->en_tcp_delack_no_lro = 0;
+
+	if (!hdd_is_lro_enabled(hdd_ctx)) {
+		cdp_register_rx_offld_flush_cb(soc, hdd_qdf_lro_flush);
+		hdd_ctx->receive_offload_cb = hdd_lro_rx;
+		hdd_debug("LRO is enabled");
+	} else if (hdd_ctx->ol_enable == CFG_GRO_ENABLED) {
+		if (hdd_ctx->enable_rxthread)
+			cdp_register_rx_offld_flush_cb(soc,
+						hdd_rxthread_napi_gro_flush);
+		else
+			cdp_register_rx_offld_flush_cb(soc,
+						       hdd_hif_napi_gro_flush);
+		hdd_ctx->receive_offload_cb = hdd_gro_rx;
+		hdd_debug("GRO is enabled");
+	} else if (HDD_MSM_CFG(hdd_ctx->config->enable_tcp_delack)) {
+		hdd_ctx->en_tcp_delack_no_lro = 1;
+	}
+}
+
+int hdd_rx_ol_init(struct hdd_context *hdd_ctx)
+{
+	struct cdp_lro_hash_config lro_config = {0};
+
+	hdd_resolve_rx_ol_mode(hdd_ctx);
+
+	hdd_register_rx_ol();
+
+	/*
+	 * This will enable flow steering and Toeplitz hash
+	 * So enable it for LRO or GRO processing.
+	 */
+	if (hdd_napi_enabled(HDD_NAPI_ANY) == 0) {
+		hdd_warn("NAPI is disabled");
+		return 0;
+	}
+
+	lro_config.lro_enable = 1;
+	lro_config.tcp_flag = TCPHDR_ACK;
+	lro_config.tcp_flag_mask = TCPHDR_FIN | TCPHDR_SYN | TCPHDR_RST |
+		TCPHDR_ACK | TCPHDR_URG | TCPHDR_ECE | TCPHDR_CWR;
+
+	get_random_bytes(lro_config.toeplitz_hash_ipv4,
+			 (sizeof(lro_config.toeplitz_hash_ipv4[0]) *
+			  LRO_IPV4_SEED_ARR_SZ));
+
+	get_random_bytes(lro_config.toeplitz_hash_ipv6,
+			 (sizeof(lro_config.toeplitz_hash_ipv6[0]) *
+			  LRO_IPV6_SEED_ARR_SZ));
+
+	if (0 != wma_lro_init(&lro_config)) {
+		hdd_err("Failed to send LRO/GRO configuration!");
+		hdd_ctx->ol_enable = 0;
+		return -EAGAIN;
+	}
+
+	return 0;
+}
+
+void hdd_disable_rx_ol_in_concurrency(bool disable)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is NULL");
+		return;
+	}
+
+	if (disable) {
+		if (HDD_MSM_CFG(hdd_ctx->config->enable_tcp_delack)) {
+			struct wlan_rx_tp_data rx_tp_data;
+
+			hdd_info("Enable TCP delack as LRO disabled in concurrency");
+			rx_tp_data.rx_tp_flags = TCP_DEL_ACK_IND;
+			rx_tp_data.level = GET_CUR_RX_LVL(hdd_ctx);
+			wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
+						    WLAN_SVC_WLAN_TP_IND,
+						    &rx_tp_data,
+						    sizeof(rx_tp_data));
+			hdd_ctx->en_tcp_delack_no_lro = 1;
+		}
+		qdf_atomic_set(&hdd_ctx->disable_lro_in_concurrency, 1);
+	} else {
+		if (HDD_MSM_CFG(hdd_ctx->config->enable_tcp_delack)) {
+			hdd_info("Disable TCP delack as LRO is enabled");
+			hdd_ctx->en_tcp_delack_no_lro = 0;
+			hdd_reset_tcp_delack(hdd_ctx);
+		}
+		qdf_atomic_set(&hdd_ctx->disable_lro_in_concurrency, 0);
+	}
+}
+
+void hdd_disable_rx_ol_for_low_tput(struct hdd_context *hdd_ctx, bool disable)
+{
+	if (disable)
+		qdf_atomic_set(&hdd_ctx->disable_lro_in_low_tput, 1);
+	else
+		qdf_atomic_set(&hdd_ctx->disable_lro_in_low_tput, 0);
+}
+
+/**
+ * hdd_can_handle_receive_offload() - Check for dynamic disablement
+ * @hdd_ctx: hdd context
+ * @skb: pointer to sk_buff which will be processed by Rx OL
+ *
+ * Check for dynamic disablement of Rx offload
+ *
+ * Return: false if we cannot process otherwise true
+ */
+static bool hdd_can_handle_receive_offload(struct hdd_context *hdd_ctx,
+					   struct sk_buff *skb)
+{
+	if (!hdd_ctx->receive_offload_cb)
+		return false;
+
+	if (!QDF_NBUF_CB_RX_TCP_PROTO(skb) ||
+	    qdf_atomic_read(&hdd_ctx->disable_lro_in_concurrency) ||
+	    QDF_NBUF_CB_RX_PEER_CACHED_FRM(skb) ||
+	    qdf_atomic_read(&hdd_ctx->disable_lro_in_low_tput))
+		return false;
+	else
+		return true;
+}
+#else /* RECEIVE_OFFLOAD */
+static bool hdd_can_handle_receive_offload(struct hdd_context *hdd_ctx,
+					   struct sk_buff *skb)
+{
+	return false;
+}
+
+int hdd_rx_ol_init(struct hdd_context *hdd_ctx)
+{
+	hdd_err("Rx_OL, LRO/GRO not supported");
+	return -EPERM;
+}
+
+void hdd_disable_rx_ol_in_concurrency(bool disable)
+{
+}
+
+void hdd_disable_rx_ol_for_low_tput(struct hdd_context *hdd_ctx, bool disable)
+{
+}
+#endif /* RECEIVE_OFFLOAD */
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+static inline void hdd_tsf_timestamp_rx(struct hdd_context *hdd_ctx,
+					qdf_nbuf_t netbuf,
+					uint64_t target_time)
+{
+	if (!hdd_tsf_is_rx_set(hdd_ctx))
+		return;
+
+	hdd_rx_timestamp(netbuf, target_time);
+}
+#else
+static inline void hdd_tsf_timestamp_rx(struct hdd_context *hdd_ctx,
+					qdf_nbuf_t netbuf,
+					uint64_t target_time)
+{
+}
+#endif
+
+QDF_STATUS hdd_rx_pkt_thread_enqueue_cbk(void *adapter,
+					 qdf_nbuf_t nbuf_list)
+{
+	if (unlikely((!adapter) || (!nbuf_list))) {
+		hdd_err("Null params being passed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	return dp_rx_enqueue_pkt(cds_get_context(QDF_MODULE_ID_SOC), nbuf_list);
+}
+
+QDF_STATUS hdd_rx_packet_cbk(void *adapter_context,
+			     qdf_nbuf_t rxBuf)
+{
+	struct hdd_adapter *adapter = NULL;
+	struct hdd_context *hdd_ctx = NULL;
+	int rxstat = 0;
+	QDF_STATUS rx_ol_status = QDF_STATUS_E_FAILURE;
+	struct sk_buff *skb = NULL;
+	struct sk_buff *next = NULL;
+	struct hdd_station_ctx *sta_ctx = NULL;
+	unsigned int cpu_index;
+	struct qdf_mac_addr *mac_addr;
+	bool wake_lock = false;
+	uint8_t pkt_type = 0;
+	bool track_arp = false;
+
+	/* Sanity check on inputs */
+	if (unlikely((!adapter_context) || (!rxBuf))) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Null params being passed", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	adapter = (struct hdd_adapter *)adapter_context;
+	if (unlikely(WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "Magic cookie(%x) for adapter sanity verification is invalid",
+			  adapter->magic);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (unlikely(NULL == hdd_ctx)) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "%s: HDD context is Null", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cpu_index = wlan_hdd_get_cpu();
+
+	next = (struct sk_buff *)rxBuf;
+
+	while (next) {
+		skb = next;
+		next = skb->next;
+		skb->next = NULL;
+
+/* Debug code, remove later */
+#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390)
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+			 "%s: skb %pK skb->len %d\n", __func__, skb, skb->len);
+#endif
+		if (QDF_NBUF_CB_PACKET_TYPE_ARP ==
+		    QDF_NBUF_CB_GET_PACKET_TYPE(skb)) {
+			if (qdf_nbuf_data_is_arp_rsp(skb) &&
+				(hdd_ctx->track_arp_ip ==
+			     qdf_nbuf_get_arp_src_ip(skb))) {
+				++adapter->hdd_stats.hdd_arp_stats.
+							rx_arp_rsp_count;
+				QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+						QDF_TRACE_LEVEL_INFO,
+						"%s: ARP packet received",
+						__func__);
+				track_arp = true;
+			}
+		}
+		/* track connectivity stats */
+		if (adapter->pkt_type_bitmap)
+			hdd_tx_rx_collect_connectivity_stats_info(skb, adapter,
+						PKT_TYPE_RSP, &pkt_type);
+
+		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		if ((sta_ctx->conn_info.proxyARPService) &&
+			cfg80211_is_gratuitous_arp_unsolicited_na(skb)) {
+			uint32_t rx_dropped;
+
+			rx_dropped = ++adapter->hdd_stats.tx_rx_stats.
+							rx_dropped[cpu_index];
+			/* rate limit error messages to 1/8th */
+			if ((rx_dropped & 0x07) == 0)
+				QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+					  QDF_TRACE_LEVEL_INFO,
+					  "%s: Dropping HS 2.0 Gratuitous ARP or Unsolicited NA count=%u",
+					  __func__, rx_dropped);
+			/* Remove SKB from internal tracking table before submitting
+			 * it to stack
+			 */
+			qdf_nbuf_free(skb);
+			continue;
+		}
+
+		hdd_event_eapol_log(skb, QDF_RX);
+		qdf_dp_trace_log_pkt(adapter->session_id, skb, QDF_RX,
+				     QDF_TRACE_DEFAULT_PDEV_ID);
+
+		DPTRACE(qdf_dp_trace(skb,
+			QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD,
+			QDF_TRACE_DEFAULT_PDEV_ID,
+			qdf_nbuf_data_addr(skb),
+			sizeof(qdf_nbuf_data(skb)), QDF_RX));
+
+		DPTRACE(qdf_dp_trace_data_pkt(skb, QDF_TRACE_DEFAULT_PDEV_ID,
+			QDF_DP_TRACE_RX_PACKET_RECORD,
+			0, QDF_RX));
+
+		mac_addr = (struct qdf_mac_addr *)(skb->data+QDF_MAC_ADDR_SIZE);
+
+		ucfg_tdls_update_rx_pkt_cnt(adapter->vdev, mac_addr);
+
+		skb->dev = adapter->dev;
+		skb->protocol = eth_type_trans(skb, skb->dev);
+		++adapter->hdd_stats.tx_rx_stats.rx_packets[cpu_index];
+		++adapter->stats.rx_packets;
+		adapter->stats.rx_bytes += skb->len;
+
+		/* Incr GW Rx count for NUD tracking based on GW mac addr */
+		hdd_nud_incr_gw_rx_pkt_cnt(adapter, mac_addr);
+
+		/* Check & drop replayed mcast packets (for IPV6) */
+		if (hdd_ctx->config->multicast_replay_filter &&
+				hdd_is_mcast_replay(skb)) {
+			++adapter->hdd_stats.tx_rx_stats.rx_dropped[cpu_index];
+			QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+				"%s: Dropping multicast replay pkt", __func__);
+			qdf_nbuf_free(skb);
+			continue;
+		}
+
+		/* hold configurable wakelock for unicast traffic */
+		if (hdd_ctx->config->rx_wakelock_timeout &&
+				sta_ctx->conn_info.uIsAuthenticated)
+			wake_lock = hdd_is_rx_wake_lock_needed(skb);
+
+		if (wake_lock) {
+			cds_host_diag_log_work(&hdd_ctx->rx_wake_lock,
+						   hdd_ctx->config->rx_wakelock_timeout,
+						   WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
+			qdf_wake_lock_timeout_acquire(&hdd_ctx->rx_wake_lock,
+							  hdd_ctx->config->
+								  rx_wakelock_timeout);
+		}
+
+		/* Remove SKB from internal tracking table before submitting
+		 * it to stack
+		 */
+		qdf_net_buf_debug_release_skb(skb);
+
+		hdd_tsf_timestamp_rx(hdd_ctx, skb, ktime_to_us(skb->tstamp));
+
+		if (hdd_can_handle_receive_offload(hdd_ctx, skb))
+			rx_ol_status = hdd_ctx->receive_offload_cb(adapter,
+								   skb);
+
+		if (rx_ol_status != QDF_STATUS_SUCCESS) {
+			/* we should optimize this per packet check, unlikely */
+			/* Account for GRO/LRO ineligible packets, mostly UDP */
+			hdd_ctx->no_rx_offload_pkt_cnt++;
+			if (hdd_napi_enabled(HDD_NAPI_ANY) &&
+			    !hdd_ctx->enable_rxthread &&
+			    !QDF_NBUF_CB_RX_PEER_CACHED_FRM(skb)) {
+				rxstat = netif_receive_skb(skb);
+			} else {
+				local_bh_disable();
+				rxstat = netif_receive_skb(skb);
+				local_bh_enable();
+			}
+		}
+
+		if (!rxstat) {
+			++adapter->hdd_stats.tx_rx_stats.
+						rx_delivered[cpu_index];
+			if (track_arp)
+				++adapter->hdd_stats.hdd_arp_stats.
+							rx_delivered;
+			/* track connectivity stats */
+			if (adapter->pkt_type_bitmap)
+				hdd_tx_rx_collect_connectivity_stats_info(
+					skb, adapter,
+					PKT_TYPE_RX_DELIVERED, &pkt_type);
+		} else {
+			++adapter->hdd_stats.tx_rx_stats.rx_refused[cpu_index];
+			if (track_arp)
+				++adapter->hdd_stats.hdd_arp_stats.rx_refused;
+
+			/* track connectivity stats */
+			if (adapter->pkt_type_bitmap)
+				hdd_tx_rx_collect_connectivity_stats_info(
+					skb, adapter,
+					PKT_TYPE_RX_REFUSED, &pkt_type);
+
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_reason_type_to_string() - return string conversion of reason type
+ * @reason: reason type
+ *
+ * This utility function helps log string conversion of reason type.
+ *
+ * Return: string conversion of device mode, if match found;
+ *        "Unknown" otherwise.
+ */
+const char *hdd_reason_type_to_string(enum netif_reason_type reason)
+{
+	switch (reason) {
+	CASE_RETURN_STRING(WLAN_CONTROL_PATH);
+	CASE_RETURN_STRING(WLAN_DATA_FLOW_CONTROL);
+	CASE_RETURN_STRING(WLAN_FW_PAUSE);
+	CASE_RETURN_STRING(WLAN_TX_ABORT);
+	CASE_RETURN_STRING(WLAN_VDEV_STOP);
+	CASE_RETURN_STRING(WLAN_PEER_UNAUTHORISED);
+	CASE_RETURN_STRING(WLAN_THERMAL_MITIGATION);
+	CASE_RETURN_STRING(WLAN_DATA_FLOW_CONTROL_PRIORITY);
+	default:
+		return "Invalid";
+	}
+}
+
+/**
+ * hdd_action_type_to_string() - return string conversion of action type
+ * @action: action type
+ *
+ * This utility function helps log string conversion of action_type.
+ *
+ * Return: string conversion of device mode, if match found;
+ *        "Unknown" otherwise.
+ */
+const char *hdd_action_type_to_string(enum netif_action_type action)
+{
+
+	switch (action) {
+	CASE_RETURN_STRING(WLAN_STOP_ALL_NETIF_QUEUE);
+	CASE_RETURN_STRING(WLAN_START_ALL_NETIF_QUEUE);
+	CASE_RETURN_STRING(WLAN_WAKE_ALL_NETIF_QUEUE);
+	CASE_RETURN_STRING(WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER);
+	CASE_RETURN_STRING(WLAN_START_ALL_NETIF_QUEUE_N_CARRIER);
+	CASE_RETURN_STRING(WLAN_NETIF_TX_DISABLE);
+	CASE_RETURN_STRING(WLAN_NETIF_TX_DISABLE_N_CARRIER);
+	CASE_RETURN_STRING(WLAN_NETIF_CARRIER_ON);
+	CASE_RETURN_STRING(WLAN_NETIF_CARRIER_OFF);
+	CASE_RETURN_STRING(WLAN_NETIF_PRIORITY_QUEUE_ON);
+	CASE_RETURN_STRING(WLAN_NETIF_PRIORITY_QUEUE_OFF);
+	CASE_RETURN_STRING(WLAN_NETIF_VO_QUEUE_ON);
+	CASE_RETURN_STRING(WLAN_NETIF_VO_QUEUE_OFF);
+	CASE_RETURN_STRING(WLAN_NETIF_VI_QUEUE_ON);
+	CASE_RETURN_STRING(WLAN_NETIF_VI_QUEUE_OFF);
+	CASE_RETURN_STRING(WLAN_NETIF_BE_BK_QUEUE_OFF);
+	CASE_RETURN_STRING(WLAN_WAKE_NON_PRIORITY_QUEUE);
+	CASE_RETURN_STRING(WLAN_STOP_NON_PRIORITY_QUEUE);
+	default:
+		return "Invalid";
+	}
+}
+
+/**
+ * wlan_hdd_update_queue_oper_stats - update queue operation statistics
+ * @adapter: adapter handle
+ * @action: action type
+ * @reason: reason type
+ */
+static void wlan_hdd_update_queue_oper_stats(struct hdd_adapter *adapter,
+	enum netif_action_type action, enum netif_reason_type reason)
+{
+	switch (action) {
+	case WLAN_STOP_ALL_NETIF_QUEUE:
+	case WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER:
+	case WLAN_NETIF_BE_BK_QUEUE_OFF:
+	case WLAN_NETIF_VI_QUEUE_OFF:
+	case WLAN_NETIF_VO_QUEUE_OFF:
+	case WLAN_NETIF_PRIORITY_QUEUE_OFF:
+	case WLAN_STOP_NON_PRIORITY_QUEUE:
+		adapter->queue_oper_stats[reason].pause_count++;
+		break;
+	case WLAN_START_ALL_NETIF_QUEUE:
+	case WLAN_WAKE_ALL_NETIF_QUEUE:
+	case WLAN_START_ALL_NETIF_QUEUE_N_CARRIER:
+	case WLAN_NETIF_VI_QUEUE_ON:
+	case WLAN_NETIF_VO_QUEUE_ON:
+	case WLAN_NETIF_PRIORITY_QUEUE_ON:
+	case WLAN_WAKE_NON_PRIORITY_QUEUE:
+		adapter->queue_oper_stats[reason].unpause_count++;
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ * hdd_netdev_queue_is_locked()
+ * @txq: net device tx queue
+ *
+ * For SMP system, always return false and we could safely rely on
+ * __netif_tx_trylock().
+ *
+ * Return: true locked; false not locked
+ */
+#ifdef QCA_CONFIG_SMP
+static inline bool hdd_netdev_queue_is_locked(struct netdev_queue *txq)
+{
+	return false;
+}
+#else
+static inline bool hdd_netdev_queue_is_locked(struct netdev_queue *txq)
+{
+	return txq->xmit_lock_owner != -1;
+}
+#endif
+
+/**
+ * wlan_hdd_update_txq_timestamp() - update txq timestamp
+ * @dev: net device
+ *
+ * Return: none
+ */
+static void wlan_hdd_update_txq_timestamp(struct net_device *dev)
+{
+	struct netdev_queue *txq;
+	int i;
+
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		txq = netdev_get_tx_queue(dev, i);
+
+		/*
+		 * On UP system, kernel will trigger watchdog bite if spinlock
+		 * recursion is detected. Unfortunately recursion is possible
+		 * when it is called in dev_queue_xmit() context, where stack
+		 * grabs the lock before calling driver's ndo_start_xmit
+		 * callback.
+		 */
+		if (!hdd_netdev_queue_is_locked(txq)) {
+			if (__netif_tx_trylock(txq)) {
+				txq_trans_update(txq);
+				__netif_tx_unlock(txq);
+			}
+		}
+	}
+}
+
+/**
+ * wlan_hdd_update_unpause_time() - update unpause time
+ * @adapter: adapter handle
+ *
+ * Return: none
+ */
+static void wlan_hdd_update_unpause_time(struct hdd_adapter *adapter)
+{
+	qdf_time_t curr_time = qdf_system_ticks();
+
+	adapter->total_unpause_time += curr_time - adapter->last_time;
+	adapter->last_time = curr_time;
+}
+
+/**
+ * wlan_hdd_update_pause_time() - update pause time
+ * @adapter: adapter handle
+ *
+ * Return: none
+ */
+static void wlan_hdd_update_pause_time(struct hdd_adapter *adapter,
+	 uint32_t temp_map)
+{
+	qdf_time_t curr_time = qdf_system_ticks();
+	uint8_t i;
+	qdf_time_t pause_time;
+
+	pause_time = curr_time - adapter->last_time;
+	adapter->total_pause_time += pause_time;
+	adapter->last_time = curr_time;
+
+	for (i = 0; i < WLAN_REASON_TYPE_MAX; i++) {
+		if (temp_map & (1 << i)) {
+			adapter->queue_oper_stats[i].total_pause_time +=
+								 pause_time;
+			break;
+		}
+	}
+
+}
+
+/**
+ * wlan_hdd_stop_non_priority_queue() - stop non prority queues
+ * @adapter: adapter handle
+ *
+ * Return: None
+ */
+static inline void wlan_hdd_stop_non_priority_queue(struct hdd_adapter *adapter)
+{
+	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VO);
+	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VI);
+	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BE);
+	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BK);
+}
+
+/**
+ * wlan_hdd_wake_non_priority_queue() - wake non prority queues
+ * @adapter: adapter handle
+ *
+ * Return: None
+ */
+static inline void wlan_hdd_wake_non_priority_queue(struct hdd_adapter *adapter)
+{
+	netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VO);
+	netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VI);
+	netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_BE);
+	netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_BK);
+}
+
+/**
+ * wlan_hdd_netif_queue_control() - Use for netif_queue related actions
+ * @adapter: adapter handle
+ * @action: action type
+ * @reason: reason type
+ *
+ * This is single function which is used for netif_queue related
+ * actions like start/stop of network queues and on/off carrier
+ * option.
+ *
+ * Return: None
+ */
+void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter,
+	enum netif_action_type action, enum netif_reason_type reason)
+{
+	uint32_t temp_map;
+
+	if ((!adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) ||
+		 (!adapter->dev)) {
+		hdd_err("adapter is invalid");
+		return;
+	}
+
+	switch (action) {
+
+	case WLAN_NETIF_CARRIER_ON:
+		netif_carrier_on(adapter->dev);
+		break;
+
+	case WLAN_NETIF_CARRIER_OFF:
+		netif_carrier_off(adapter->dev);
+		break;
+
+	case WLAN_STOP_ALL_NETIF_QUEUE:
+		spin_lock_bh(&adapter->pause_map_lock);
+		if (!adapter->pause_map) {
+			netif_tx_stop_all_queues(adapter->dev);
+			wlan_hdd_update_txq_timestamp(adapter->dev);
+			wlan_hdd_update_unpause_time(adapter);
+		}
+		adapter->pause_map |= (1 << reason);
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_STOP_NON_PRIORITY_QUEUE:
+		spin_lock_bh(&adapter->pause_map_lock);
+		if (!adapter->pause_map) {
+			wlan_hdd_stop_non_priority_queue(adapter);
+			wlan_hdd_update_txq_timestamp(adapter->dev);
+			wlan_hdd_update_unpause_time(adapter);
+		}
+		adapter->pause_map |= (1 << reason);
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_NETIF_PRIORITY_QUEUE_ON:
+		spin_lock_bh(&adapter->pause_map_lock);
+		temp_map = adapter->pause_map;
+		adapter->pause_map &= ~(1 << reason);
+		netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO);
+		wlan_hdd_update_pause_time(adapter, temp_map);
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_NETIF_PRIORITY_QUEUE_OFF:
+		spin_lock_bh(&adapter->pause_map_lock);
+		netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO);
+		wlan_hdd_update_txq_timestamp(adapter->dev);
+		wlan_hdd_update_unpause_time(adapter);
+		adapter->pause_map |= (1 << reason);
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_NETIF_BE_BK_QUEUE_OFF:
+		spin_lock_bh(&adapter->pause_map_lock);
+		netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BK);
+		netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BE);
+		wlan_hdd_update_txq_timestamp(adapter->dev);
+		wlan_hdd_update_unpause_time(adapter);
+		adapter->pause_map |= (1 << reason);
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_NETIF_VI_QUEUE_OFF:
+		spin_lock_bh(&adapter->pause_map_lock);
+		netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VI);
+		wlan_hdd_update_txq_timestamp(adapter->dev);
+		wlan_hdd_update_unpause_time(adapter);
+		adapter->pause_map |= (1 << reason);
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_NETIF_VI_QUEUE_ON:
+		spin_lock_bh(&adapter->pause_map_lock);
+		temp_map = adapter->pause_map;
+		adapter->pause_map &= ~(1 << reason);
+		netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VI);
+		wlan_hdd_update_pause_time(adapter, temp_map);
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_NETIF_VO_QUEUE_OFF:
+		spin_lock_bh(&adapter->pause_map_lock);
+		netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VO);
+		wlan_hdd_update_txq_timestamp(adapter->dev);
+		wlan_hdd_update_unpause_time(adapter);
+		adapter->pause_map |= (1 << reason);
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_NETIF_VO_QUEUE_ON:
+		spin_lock_bh(&adapter->pause_map_lock);
+		temp_map = adapter->pause_map;
+		adapter->pause_map &= ~(1 << reason);
+		netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VO);
+		wlan_hdd_update_pause_time(adapter, temp_map);
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_START_ALL_NETIF_QUEUE:
+		spin_lock_bh(&adapter->pause_map_lock);
+		temp_map = adapter->pause_map;
+		adapter->pause_map &= ~(1 << reason);
+		if (!adapter->pause_map) {
+			netif_tx_start_all_queues(adapter->dev);
+			wlan_hdd_update_pause_time(adapter, temp_map);
+		}
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_WAKE_ALL_NETIF_QUEUE:
+		spin_lock_bh(&adapter->pause_map_lock);
+		temp_map = adapter->pause_map;
+		adapter->pause_map &= ~(1 << reason);
+		if (!adapter->pause_map) {
+			netif_tx_wake_all_queues(adapter->dev);
+			wlan_hdd_update_pause_time(adapter, temp_map);
+		}
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_WAKE_NON_PRIORITY_QUEUE:
+		spin_lock_bh(&adapter->pause_map_lock);
+		temp_map = adapter->pause_map;
+		adapter->pause_map &= ~(1 << reason);
+		if (!adapter->pause_map) {
+			wlan_hdd_wake_non_priority_queue(adapter);
+			wlan_hdd_update_pause_time(adapter, temp_map);
+		}
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER:
+		spin_lock_bh(&adapter->pause_map_lock);
+		if (!adapter->pause_map) {
+			netif_tx_stop_all_queues(adapter->dev);
+			wlan_hdd_update_txq_timestamp(adapter->dev);
+			wlan_hdd_update_unpause_time(adapter);
+		}
+		adapter->pause_map |= (1 << reason);
+		netif_carrier_off(adapter->dev);
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	case WLAN_START_ALL_NETIF_QUEUE_N_CARRIER:
+		spin_lock_bh(&adapter->pause_map_lock);
+		netif_carrier_on(adapter->dev);
+		temp_map = adapter->pause_map;
+		adapter->pause_map &= ~(1 << reason);
+		if (!adapter->pause_map) {
+			netif_tx_start_all_queues(adapter->dev);
+			wlan_hdd_update_pause_time(adapter, temp_map);
+		}
+		spin_unlock_bh(&adapter->pause_map_lock);
+		break;
+
+	default:
+		hdd_err("unsupported action %d", action);
+	}
+
+	spin_lock_bh(&adapter->pause_map_lock);
+	if (adapter->pause_map & (1 << WLAN_PEER_UNAUTHORISED))
+		wlan_hdd_process_peer_unauthorised_pause(adapter);
+	spin_unlock_bh(&adapter->pause_map_lock);
+
+	wlan_hdd_update_queue_oper_stats(adapter, action, reason);
+
+	adapter->queue_oper_history[adapter->history_index].time =
+							qdf_system_ticks();
+	adapter->queue_oper_history[adapter->history_index].netif_action =
+									action;
+	adapter->queue_oper_history[adapter->history_index].netif_reason =
+									reason;
+	adapter->queue_oper_history[adapter->history_index].pause_map =
+							adapter->pause_map;
+	if (++adapter->history_index == WLAN_HDD_MAX_HISTORY_ENTRY)
+		adapter->history_index = 0;
+}
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+/**
+ * hdd_set_mon_rx_cb() - Set Monitor mode Rx callback
+ * @dev:        Pointer to net_device structure
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+int hdd_set_mon_rx_cb(struct net_device *dev)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx =  WLAN_HDD_GET_CTX(adapter);
+	int ret;
+	QDF_STATUS qdf_status;
+	struct ol_txrx_desc_type sta_desc = {0};
+	struct ol_txrx_ops txrx_ops;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
+	txrx_ops.rx.rx = hdd_mon_rx_packet_cbk;
+	hdd_monitor_set_rx_monitor_cb(&txrx_ops, hdd_rx_monitor_callback);
+	cdp_vdev_register(soc,
+		(struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
+		(struct cdp_pdev *)pdev, adapter->session_id),
+		adapter, (struct cdp_ctrl_objmgr_vdev *)adapter->vdev,
+		&txrx_ops);
+	/* peer is created wma_vdev_attach->wma_create_peer */
+	qdf_status = cdp_peer_register(soc,
+			(struct cdp_pdev *)pdev, &sta_desc);
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		hdd_err("cdp_peer_register() failed to register. Status= %d [0x%08X]",
+			qdf_status, qdf_status);
+		goto exit;
+	}
+
+	qdf_status = sme_create_mon_session(hdd_ctx->mac_handle,
+					    adapter->mac_addr.bytes,
+					    adapter->session_id);
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		hdd_err("sme_create_mon_session() failed to register. Status= %d [0x%08X]",
+			qdf_status, qdf_status);
+	}
+exit:
+	ret = qdf_status_to_os_return(qdf_status);
+	return ret;
+}
+#endif
+
+/**
+ * hdd_send_rps_ind() - send rps indication to daemon
+ * @adapter: adapter context
+ *
+ * If RPS feature enabled by INI, send RPS enable indication to daemon
+ * Indication contents is the name of interface to find correct sysfs node
+ * Should send all available interfaces
+ *
+ * Return: none
+ */
+void hdd_send_rps_ind(struct hdd_adapter *adapter)
+{
+	int i;
+	uint8_t cpu_map_list_len = 0;
+	struct hdd_context *hdd_ctxt = NULL;
+	struct wlan_rps_data rps_data;
+	struct cds_config_info *cds_cfg;
+
+	cds_cfg = cds_get_ini_config();
+
+	if (!adapter) {
+		hdd_err("adapter is NULL");
+		return;
+	}
+
+	if (!cds_cfg) {
+		hdd_err("cds_cfg is NULL");
+		return;
+	}
+
+	hdd_ctxt = WLAN_HDD_GET_CTX(adapter);
+	rps_data.num_queues = NUM_TX_QUEUES;
+
+	hdd_info("cpu_map_list '%s'", hdd_ctxt->config->cpu_map_list);
+
+	/* in case no cpu map list is provided, simply return */
+	if (!strlen(hdd_ctxt->config->cpu_map_list)) {
+		hdd_err("no cpu map list found");
+		goto err;
+	}
+
+	if (QDF_STATUS_SUCCESS !=
+		hdd_hex_string_to_u16_array(hdd_ctxt->config->cpu_map_list,
+				rps_data.cpu_map_list,
+				&cpu_map_list_len,
+				WLAN_SVC_IFACE_NUM_QUEUES)) {
+		hdd_err("invalid cpu map list");
+		goto err;
+	}
+
+	rps_data.num_queues =
+		(cpu_map_list_len < rps_data.num_queues) ?
+				cpu_map_list_len : rps_data.num_queues;
+
+	for (i = 0; i < rps_data.num_queues; i++) {
+		hdd_info("cpu_map_list[%d] = 0x%x",
+			i, rps_data.cpu_map_list[i]);
+	}
+
+	strlcpy(rps_data.ifname, adapter->dev->name,
+			sizeof(rps_data.ifname));
+	wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
+				WLAN_SVC_RPS_ENABLE_IND,
+				&rps_data, sizeof(rps_data));
+
+	cds_cfg->rps_enabled = true;
+
+	return;
+
+err:
+	hdd_err("Wrong RPS configuration. enabling rx_thread");
+	cds_cfg->rps_enabled = false;
+}
+
+/**
+ * hdd_send_rps_disable_ind() - send rps disable indication to daemon
+ * @adapter: adapter context
+ *
+ * Return: none
+ */
+void hdd_send_rps_disable_ind(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctxt = NULL;
+	struct wlan_rps_data rps_data;
+	struct cds_config_info *cds_cfg;
+
+	cds_cfg = cds_get_ini_config();
+
+	if (!adapter) {
+		hdd_err("adapter is NULL");
+		return;
+	}
+
+	if (!cds_cfg) {
+		hdd_err("cds_cfg is NULL");
+		return;
+	}
+
+	hdd_ctxt = WLAN_HDD_GET_CTX(adapter);
+	rps_data.num_queues = NUM_TX_QUEUES;
+
+	hdd_info("Set cpu_map_list 0");
+
+	qdf_mem_zero(&rps_data.cpu_map_list, sizeof(rps_data.cpu_map_list));
+
+	strlcpy(rps_data.ifname, adapter->dev->name, sizeof(rps_data.ifname));
+	wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
+				    WLAN_SVC_RPS_ENABLE_IND,
+				    &rps_data, sizeof(rps_data));
+
+	cds_cfg->rps_enabled = false;
+}
+
+void hdd_tx_queue_cb(hdd_handle_t hdd_handle, uint32_t vdev_id,
+		     enum netif_action_type action,
+		     enum netif_reason_type reason)
+{
+	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+	struct hdd_adapter *adapter;
+
+	/*
+	 * Validating the context is not required here.
+	 * if there is a driver unload/SSR in progress happening in a
+	 * different context and it has been scheduled to run and
+	 * driver got a firmware event of sta kick out, then it is
+	 * good to disable the Tx Queue to stop the influx of traffic.
+	 */
+	if (!hdd_ctx) {
+		hdd_err("Invalid context passed");
+		return;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (!adapter) {
+		hdd_err("vdev_id %d does not exist with host", vdev_id);
+		return;
+	}
+	hdd_debug("Tx Queue action %d on vdev %d", action, vdev_id);
+
+	wlan_hdd_netif_queue_control(adapter, action, reason);
+}
+
+#ifdef MSM_PLATFORM
+/**
+ * hdd_reset_tcp_delack() - Reset tcp delack value to default
+ * @hdd_ctx: Handle to hdd context
+ *
+ * Function used to reset TCP delack value to its default value
+ *
+ * Return: None
+ */
+void hdd_reset_tcp_delack(struct hdd_context *hdd_ctx)
+{
+	enum wlan_tp_level next_level = WLAN_SVC_TP_LOW;
+	struct wlan_rx_tp_data rx_tp_data = {0};
+
+	rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
+	rx_tp_data.level = next_level;
+	hdd_ctx->rx_high_ind_cnt = 0;
+	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, WLAN_SVC_WLAN_TP_IND,
+				    &rx_tp_data, sizeof(rx_tp_data));
+}
+#endif /* MSM_PLATFORM */
+
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+/**
+ * hdd_ini_tx_flow_control() - Initialize INIs concerned about tx flow control
+ * @config: pointer to hdd config
+ * @psoc: pointer to psoc obj
+ *
+ * Return: none
+ */
+static void hdd_ini_tx_flow_control(struct hdd_config *config,
+				    struct wlan_objmgr_psoc *psoc)
+{
+	config->tx_flow_low_watermark =
+		cfg_get(psoc, CFG_DP_LL_TX_FLOW_LWM);
+	config->tx_flow_hi_watermark_offset =
+		cfg_get(psoc, CFG_DP_LL_TX_FLOW_HWM_OFFSET);
+	config->tx_flow_max_queue_depth =
+		cfg_get(psoc, CFG_DP_LL_TX_FLOW_MAX_Q_DEPTH);
+	config->tx_lbw_flow_low_watermark =
+		cfg_get(psoc, CFG_DP_LL_TX_LBW_FLOW_LWM);
+	config->tx_lbw_flow_hi_watermark_offset =
+		cfg_get(psoc, CFG_DP_LL_TX_LBW_FLOW_HWM_OFFSET);
+	config->tx_lbw_flow_max_queue_depth =
+		cfg_get(psoc, CFG_DP_LL_TX_LBW_FLOW_MAX_Q_DEPTH);
+	config->tx_hbw_flow_low_watermark =
+		cfg_get(psoc, CFG_DP_LL_TX_HBW_FLOW_LWM);
+	config->tx_hbw_flow_hi_watermark_offset =
+		cfg_get(psoc, CFG_DP_LL_TX_HBW_FLOW_HWM_OFFSET);
+	config->tx_hbw_flow_max_queue_depth =
+		cfg_get(psoc, CFG_DP_LL_TX_HBW_FLOW_MAX_Q_DEPTH);
+}
+#else
+static void hdd_ini_tx_flow_control(struct hdd_config *config,
+				    struct wlan_objmgr_psoc *psoc)
+{
+}
+#endif
+
+#ifdef MSM_PLATFORM
+/**
+ * hdd_ini_tx_flow_control() - Initialize INIs concerned about bus bandwidth
+ * @config: pointer to hdd config
+ * @psoc: pointer to psoc obj
+ *
+ * Return: none
+ */
+static void hdd_ini_bus_bandwidth(struct hdd_config *config,
+				  struct wlan_objmgr_psoc *psoc)
+{
+	config->bus_bw_high_threshold =
+		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_HIGH_THRESHOLD);
+	config->bus_bw_medium_threshold =
+		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_MEDIUM_THRESHOLD);
+	config->bus_bw_low_threshold =
+		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_LOW_THRESHOLD);
+	config->bus_bw_compute_interval =
+		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_COMPUTE_INTERVAL);
+}
+
+/**
+ * hdd_ini_tx_flow_control() - Initialize INIs concerned about tcp settings
+ * @config: pointer to hdd config
+ * @psoc: pointer to psoc obj
+ *
+ * Return: none
+ */
+static void hdd_ini_tcp_settings(struct hdd_config *config,
+				 struct wlan_objmgr_psoc *psoc)
+{
+	config->enable_tcp_limit_output =
+		cfg_get(psoc, CFG_DP_ENABLE_TCP_LIMIT_OUTPUT);
+	config->enable_tcp_adv_win_scale =
+		cfg_get(psoc, CFG_DP_ENABLE_TCP_ADV_WIN_SCALE);
+	config->enable_tcp_delack =
+		cfg_get(psoc, CFG_DP_ENABLE_TCP_DELACK);
+	config->tcp_delack_thres_high =
+		cfg_get(psoc, CFG_DP_TCP_DELACK_THRESHOLD_HIGH);
+	config->tcp_delack_thres_low =
+		cfg_get(psoc, CFG_DP_TCP_DELACK_THRESHOLD_LOW);
+	config->tcp_delack_timer_count =
+		cfg_get(psoc, CFG_DP_TCP_DELACK_TIMER_COUNT);
+	config->tcp_tx_high_tput_thres =
+		cfg_get(psoc, CFG_DP_TCP_TX_HIGH_TPUT_THRESHOLD);
+}
+#else
+static void hdd_ini_bus_bandwidth(struct hdd_config *config,
+				  struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static void hdd_ini_tcp_settings(struct hdd_config *config,
+				 struct wlan_objmgr_psoc *psoc)
+{
+}
+#endif
+
+/**
+ * hdd_set_rx_mode_value() - set rx_mode values
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+static void hdd_set_rx_mode_value(struct hdd_context *hdd_ctx)
+{
+	uint32_t rx_mode = hdd_ctx->config->rx_mode;
+
+	/* RPS has higher priority than dynamic RPS when both bits are set */
+	if (rx_mode & CFG_ENABLE_RPS && rx_mode & CFG_ENABLE_DYNAMIC_RPS)
+		rx_mode &= ~CFG_ENABLE_DYNAMIC_RPS;
+
+	if (rx_mode & CFG_ENABLE_RX_THREAD && rx_mode & CFG_ENABLE_RPS) {
+		hdd_warn("rx_mode wrong configuration. Make it default");
+		rx_mode = CFG_RX_MODE_DEFAULT;
+	}
+
+	if (rx_mode & CFG_ENABLE_RX_THREAD)
+		hdd_ctx->enable_rxthread = true;
+	else if (rx_mode & CFG_ENABLE_DP_RX_THREADS)
+		hdd_ctx->enable_dp_rx_threads = true;
+
+	if (rx_mode & CFG_ENABLE_RPS)
+		hdd_ctx->rps = true;
+
+	if (rx_mode & CFG_ENABLE_NAPI)
+		hdd_ctx->napi_enable = true;
+
+	if (rx_mode & CFG_ENABLE_DYNAMIC_RPS)
+		hdd_ctx->dynamic_rps = true;
+
+	hdd_debug("rx_mode:%u dp_rx_threads:%u rx_thread:%u napi:%u rps:%u dynamic rps %u",
+		  rx_mode, hdd_ctx->enable_dp_rx_threads,
+		  hdd_ctx->enable_rxthread, hdd_ctx->napi_enable,
+		  hdd_ctx->rps, hdd_ctx->dynamic_rps);
+}
+
+void hdd_dp_cfg_update(struct wlan_objmgr_psoc *psoc,
+		       struct hdd_context *hdd_ctx)
+{
+	struct hdd_config *config;
+	qdf_size_t cpu_map_list_len;
+
+	config = hdd_ctx->config;
+	hdd_ini_tx_flow_control(config, psoc);
+	hdd_ini_bus_bandwidth(config, psoc);
+	hdd_ini_tcp_settings(config, psoc);
+	config->napi_cpu_affinity_mask =
+		cfg_get(psoc, CFG_DP_NAPI_CE_CPU_MASK);
+	config->rx_thread_affinity_mask =
+		cfg_get(psoc, CFG_DP_RX_THREAD_CPU_MASK);
+	qdf_uint8_array_parse(cfg_get(psoc, CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST),
+			      config->cpu_map_list,
+			      sizeof(config->cpu_map_list), &cpu_map_list_len);
+	config->tx_orphan_enable = cfg_get(psoc, CFG_DP_TX_ORPHAN_ENABLE);
+	config->rx_mode = cfg_get(psoc, CFG_DP_RX_MODE);
+	hdd_set_rx_mode_value(hdd_ctx);
+}
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
new file mode 100644
index 0000000..9ac489d
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -0,0 +1,10514 @@
+/*
+ * Copyright (c) 2011-2018 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: wlan_hdd_wext.c
+ *
+ * Linux Wireless Extensions Implementation
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/wireless.h>
+#include <mac_trace.h>
+#include <wlan_hdd_includes.h>
+#include <cds_api.h>
+#include "scheduler_api.h"
+#include <net/arp.h>
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_stats.h>
+#include "sir_params.h"
+#include "csr_api.h"
+#include "csr_inside_api.h"
+#include "sme_rrm_internal.h"
+#include <ani_global.h>
+#include "dot11f.h"
+#include <wlan_hdd_wowl.h>
+#include <wlan_hdd_cfg.h>
+#include <wlan_hdd_wmm.h>
+#include "utils_api.h"
+#include "wlan_hdd_p2p.h"
+#ifdef FEATURE_WLAN_TDLS
+#include "wlan_hdd_tdls.h"
+#endif
+
+#include "cds_ieee80211_common.h"
+#include "ol_if_athvar.h"
+#include "dbglog_host.h"
+#include "wma.h"
+
+#include "wlan_hdd_power.h"
+#include "qwlan_version.h"
+#include "wlan_hdd_host_offload.h"
+
+#include <linux/wireless.h>
+#include <net/cfg80211.h>
+
+#include "wlan_hdd_misc.h"
+
+#include "qc_sap_ioctl.h"
+#include "sme_api.h"
+#include "wma_types.h"
+#include "qdf_str.h"
+#include "qdf_trace.h"
+#include "wlan_hdd_assoc.h"
+#include "wlan_hdd_ioctl.h"
+#include "wlan_hdd_scan.h"
+#include "sme_power_save_api.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_hdd_conc_ut.h"
+#include "wlan_hdd_fips.h"
+#include "wlan_hdd_tsf.h"
+#include "wlan_hdd_ocb.h"
+#include "wlan_hdd_napi.h"
+#include "cdp_txrx_flow_ctrl_legacy.h"
+#include "wlan_hdd_nan_datapath.h"
+#include "wlan_hdd_stats.h"
+#ifdef WLAN_SUSPEND_RESUME_TEST
+#include "wlan_hdd_driver_ops.h"
+#include "hif.h"
+#include "pld_common.h"
+#endif
+#include "wlan_hdd_lro.h"
+#include "cds_utils.h"
+#include "wlan_osif_request_manager.h"
+#include "os_if_wifi_pos.h"
+#include <cdp_txrx_stats.h>
+#include <cds_api.h>
+#include "wlan_dsc_test.h"
+#include <wlan_osif_priv.h>
+#include "wlan_hdd_regulatory.h"
+#include "wlan_reg_ucfg_api.h"
+#include "wlan_hdd_packet_filter_api.h"
+#include "wlan_cp_stats_mc_ucfg_api.h"
+#include "wlan_mlme_ucfg_api.h"
+#include "cfg_mlme_sta.h"
+#include "wlan_mlme_public_struct.h"
+#include "cfg_ucfg_api.h"
+#include "wlan_policy_mgr_ucfg.h"
+#include "wlan_mlme_public_struct.h"
+#include "cfg_ucfg_api.h"
+#include "cfg_mlme_threshold.h"
+#include "wlan_pmo_cfg.h"
+#include "wlan_pmo_ucfg_api.h"
+
+#define HDD_FINISH_ULA_TIME_OUT         800
+#define HDD_SET_MCBC_FILTERS_TO_FW      1
+#define HDD_DELETE_MCBC_FILTERS_FROM_FW 0
+
+/* Private ioctls and their sub-ioctls */
+#define WLAN_PRIV_SET_INT_GET_NONE    (SIOCIWFIRSTPRIV + 0)
+#define WE_SET_11D_STATE     1
+#define WE_WOWL              2
+#define WE_SET_POWER         3
+/*
+ * <ioctl>
+ * setMaxAssoc - Sets the maximum number of associated stations
+ *
+ * @INPUT: 1 to 32
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL sets the maximum number of associated stations
+ *
+ * @E.g: iwpriv wlan0 setMaxAssoc <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_MAX_ASSOC     4
+/*
+ * <ioctl>
+ * scan_disable - Disable scan
+ *
+ * @INPUT: set_value
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to set disable scan
+ *
+ * @E.g: iwpriv wlan0 scan_disable 1
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_SCAN_DISABLE  5
+/*
+ * <ioctl>
+ * inactivityTO - sets the timeout value for inactivity data while
+ * in power save mode
+ *
+ * @INPUT: int1…..int255
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL set the timeout value for inactivity data in power save mode
+ *
+ * @E.g: iwpriv wlan0 inactivityTO 20
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_DATA_INACTIVITY_TO  6
+/*
+ * <ioctl>
+ * setMaxTxPower - Dynamically sets the maximum transmission power
+ *
+ * @INPUT: Transmission power in dBm
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL dynamically sets the maximum transmission power
+ * This setting does not persist over reboots
+ *
+ * @E.g: iwpriv wlan0 setMaxTxPower <value in db)
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_MAX_TX_POWER  7
+/* 8 is unused */
+#define WE_SET_TM_LEVEL      9
+/*
+ * <ioctl>
+ * setphymode - Set the phymode dynamically
+ *
+ * @INPUT: 0 IEEE80211_MODE_AUTO to 22 IEEE80211_MODE_11AGN
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the phymode dynamically
+ *
+ * @E.g: iwpriv wlan0 setphymode 10
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_PHYMODE       10
+/*
+ * <ioctl>
+ * nss - Set the number of spatial streams
+ *
+ * @INPUT: int1…..int3
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the number of spatial streams. Supported values are 1 and 2
+ *
+ * @E.g: iwpriv wlan0 nss 2
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_NSS           11
+/*
+ * <ioctl>
+ * ldpc - Enables or disables LDPC
+ *
+ * @INPUT: 0 – Disable, 1 - Enable
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL enables or disables LDPC
+ *
+ * @E.g: iwpriv wlan0 ldpc 1
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_LDPC          12
+/*
+ * <ioctl>
+ * tx_stbc - Enables or disables tx_stbc
+ *
+ * @INPUT: Int 0 – Disable, 1 - Enable
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to enables or disables tx_stbc
+ *
+ * @E.g: iwpriv wlan0 tx_stbc <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_TX_STBC       13
+/*
+ * <ioctl>
+ * rx_stbc - Set the rx_stbc parameter
+ *
+ * @INPUT: Int 0 – Disable, 1 - Enable
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to set rx_stbc parameter
+ *
+ * @E.g: iwpriv wlan0 rx_stbc <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_RX_STBC       14
+/*
+ * <ioctl>
+ * shortgi  - Sets the short-guard interval
+ *
+ * @INPUT: Fixed Rate: 0 - 400ns, 1 - 800ns, 2 - 1600ns, 3 - 3200us
+ * Auto Rate: 8 - 400ns, 9 - 800ns, 10 - 1600ns, 11 - 3200us
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the short-guard interval.
+ *
+ * @E.g: iwpriv wlan0 shortgi <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_SHORT_GI      15
+/*
+ * <ioctl>
+ * enablertscts - enables or disables rts/cts.
+ *
+ * @INPUT: 1-Enable , 0-Disable
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL enables or disables rts/cts.
+ *
+ * @E.g: iwpriv wlan0 enablertscts <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_RTSCTS        16
+/*
+ * <ioctl>
+ * chwidth - Set the channel bandwidth
+ *
+ * @INPUT: 0-20mhz to 3-160mhz
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to set the channel bandwidth
+ *
+ * @E.g: iwpriv wlan0 chwidth 1
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_CHWIDTH       17
+#define WE_SET_ANI_EN_DIS    18
+#define WE_SET_ANI_POLL_PERIOD    19
+#define WE_SET_ANI_LISTEN_PERIOD  20
+#define WE_SET_ANI_OFDM_LEVEL     21
+#define WE_SET_ANI_CCK_LEVEL      22
+/*
+ * <ioctl>
+ * cwmenable - Enables or disables the dynamic channel bandwidth
+ *
+ * @INPUT: 0-Disable, 1-Enable
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to enables or disables the dynamic channel bandwidth
+ *
+ * @E.g: iwpriv wlan0 cwmenable <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_DYNAMIC_BW         23
+/*
+ * <ioctl>
+ * txchainmask - This IOCTL sets the current Tx chain mask
+ *
+ * @INPUT: Mask Value
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the current Tx chain mask
+ *
+ * @E.g: iwpriv wlan0 txchainmask 1
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_TX_CHAINMASK  24
+/*
+ * <ioctl>
+ * rxchainmask - Sets the current Rx chain mask
+ *
+ * @INPUT: Mask Value
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the current Rx chain mask. This command is the
+ * equivalent to setting in gSetRxChainmask1x1 in WCNSS_qcom_cfg.ini.
+ *
+ * @E.g: iwpriv wlan0 rxchainmask <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_RX_CHAINMASK  25
+/*
+ * <ioctl>
+ * set11NRates - Fixes the Tx data rate of the 11N mode.
+ *
+ * @INPUT: 0x1b to 0x8f
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL fixes the Tx data rate of the 11N mode.
+ *
+ * @E.g: iwpriv wlan0 set11NRates 0x85
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_11N_RATE      26
+/*
+ * <ioctl>
+ * ampdu  - Set the the maximum subframe of ampdu
+ *
+ * @INPUT: int 1 to int 63
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the maximum subframe of ampdu.
+ *
+ * @E.g: iwpriv wlan0 ampdu 9
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_AMPDU         27
+/*
+ * <ioctl>
+ * amsdu - Sets the maximum subframe of amsdu.
+ *
+ * @INPUT: int 1 to int 31
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the maximum subframe of amsdu.
+ *
+ * @E.g: iwpriv wlan0 amsdu 9
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_AMSDU         28
+/*
+ * <ioctl>
+ * txpow2g - current 2 GHz Tx power setting
+ *
+ * @INPUT: Tx power in dBm
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL  used to set 2 ghz tx power
+ *
+ * @E.g: iwpriv wlan0 txpow2g
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_TXPOW_2G      29
+/*
+ * <ioctl>
+ * txpow5g - Current 5 GHz tx power setting
+ *
+ * @INPUT: Tx power in dBm
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to set the 5 ghz txpower
+ *
+ * @E.g: iwpriv wlan0 txpow5g
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_TXPOW_5G      30
+/* Private ioctl for firmware debug log */
+#define WE_DBGLOG_LOG_LEVEL             31
+#define WE_DBGLOG_VAP_ENABLE            32
+#define WE_DBGLOG_VAP_DISABLE           33
+#define WE_DBGLOG_MODULE_ENABLE         34
+#define WE_DBGLOG_MODULE_DISABLE        35
+#define WE_DBGLOG_MOD_LOG_LEVEL         36
+#define WE_DBGLOG_TYPE                  37
+#define WE_SET_TXRX_FWSTATS             38
+/*
+ * <ioctl>
+ * set11ACRates  - Fixes the Tx data rate of 11AC
+ *
+ * @INPUT: 0x1 to 0x9
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL fixes the Tx data rate of 11AC.
+ *
+ * @E.g: iwpriv wlan0 set11ACRates 0x9
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_VHT_RATE                 39
+#define WE_DBGLOG_REPORT_ENABLE         40
+#define WE_TXRX_FWSTATS_RESET           41
+/*
+ * <ioctl>
+ * setTxMaxPower2G - Set the maximum transmit power for the 2.4-GHz band
+ *
+ * @INPUT: Transmission power in dBm
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the maximum transmit power for the 2.4-GHz band
+ * This setting does not persist over reboots
+ *
+ * @E.g: iwpriv wlan0 setTxMaxPower2G 10
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_MAX_TX_POWER_2_4   42
+/*
+ * <ioctl>
+ * setTxMaxPower5G - Set the maximum transmit power for the 5-GHz band
+ *
+ * @INPUT: Transmission power in dBm
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the maximum transmit power for the 5-GHz band
+ * This setting does not persist over reboots
+ *
+ * @E.g: iwpriv wlan0 setTxMaxPower5G 10
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_MAX_TX_POWER_5_0   43
+#define WE_SET_PKTLOG                   44
+/* Private ioctl for packet power save */
+#define  WE_PPS_PAID_MATCH              45
+#define  WE_PPS_GID_MATCH               46
+#define  WE_PPS_EARLY_TIM_CLEAR         47
+#define  WE_PPS_EARLY_DTIM_CLEAR        48
+#define  WE_PPS_EOF_PAD_DELIM           49
+#define  WE_PPS_MACADDR_MISMATCH        50
+#define  WE_PPS_DELIM_CRC_FAIL          51
+#define  WE_PPS_GID_NSTS_ZERO           52
+/*
+ * <ioctl>
+ * rssi_chk - Check the rssi
+ *
+ * @INPUT: One argument as input
+ *
+ * @OUTPUT: rssi
+ *  wlan0	rssi_chk:56
+ *
+ * This IOTCL used to chek rssi
+ *
+ * @E.g: iwpriv wlan0 rssi_chk <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define  WE_PPS_RSSI_CHECK              53
+/*
+ * <ioctl>
+ * htsmps - Sets the htsmps
+ *
+ * @INPUT: Atleast one int argument
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to set htsmps
+ *
+ * @E.g: iwpriv wlan0 htsmps <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_HTSMPS                   55
+/* Private ioctl for QPower */
+#define WE_SET_QPOWER_MAX_PSPOLL_COUNT            56
+#define WE_SET_QPOWER_MAX_TX_BEFORE_WAKE          57
+#define WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL   58
+#define WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 59
+/* GTX Commands */
+/*
+ * <ioctl>
+ * gtxHTMcs - Set the tx HTM value
+ *
+ * @INPUT: Atleast one int orgument
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL sets htm tx value
+ *
+ * @E.g: iwpriv wlan0 gtxHTMcs <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_GTX_HT_MCS               62
+/*
+ * <ioctl>
+ * gtxVHTMcs - Set gtxVHTMcs value
+ *
+ * @INPUT: Atleast one int argument
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to set gtxVHTMcs value
+ *
+ * @E.g: iwpriv wlan0 gtxVHTMcs <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_GTX_VHT_MCS              63
+/*
+ * <ioctl>
+ * gtxUsrCfg - Host request for GTX mask
+ *
+ * @INPUT: Atleast one int orgument
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used send the host request for GTX mask
+ *
+ * @E.g: iwpriv wlan0 gtxUsrCfg <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_GTX_USRCFG               64
+/*
+ * <ioctl>
+ * gtxThre - Set the tx threshold
+ *
+ * @INPUT: Atleast one int argument
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to set tx threshold
+ *
+ * @E.g: iwpriv wlan0 gtxThre <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_GTX_THRE                 65
+/*
+ * <ioctl>
+ * gtxMargin  - Set the gtxMargin
+ *
+ * @INPUT: 1 to 32
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL use dto set gtxMargin
+ *
+ * @E.g: iwpriv wlan0 gtxMargini <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_GTX_MARGIN               66
+/*
+ * <ioctl>
+ * gtxStep - Set the gtxStep
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to sets gtxStep
+ *
+ * @E.g: iwpriv wlan0 gtxStep <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_GTX_STEP                 67
+/*
+ * <ioctl>
+ * gtxMinTpc - Sets the gtxMinTpc
+ *
+ * @INPUT: Atleast one int argument
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL sets the tx MinTpc
+ *
+ * @E.g: iwpriv wlan0 gtxMinTpc <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_GTX_MINTPC               68
+/*
+ * <ioctl>
+ * gtxBWMask - Sets the BW mask (20/40/80/160 Mhz)
+ *
+ * @INPUT: Mask value
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to set gtxBWMask
+ *
+ * @E.g: iwpriv wlan0 gtxBWMask <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+
+#define WE_SET_GTX_BWMASK               69
+/*
+ * <ioctl>
+ * setMccLatency - Sets the MCC latency value during STA-P2P concurrency
+ *
+ * @INPUT: set_value
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to set the MCC latency value in milliseconds
+ * during STA-P2P concurrency.
+ *
+ * If 0ms latency is provided, then FW will set to a default.
+ * Otherwise, latency must be at least 30ms.
+ *
+ * @E.g: iwpriv wlan0 setMccLatency 40
+ *
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_MCC_CONFIG_LATENCY           70
+
+/*
+ * <ioctl>
+ * setMccQuota- Set the quota for P2P cases
+ *
+ * @INPUT: set_value [0,100]
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to set the quota in milliseconds for P2P_GO/STA.
+ *
+ * Currently used to set time quota for 2 MCC vdevs/adapters using
+ * (operating channel, quota) for each mode.
+ * The info is provided run time using iwpriv command:
+ * iwpriv <wlan0 | p2p0> setMccQuota <quota in ms>.
+ * Note: the quota provided in command is for the same mode in cmd.
+ * HDD checks if MCC mode is active, gets the second mode and its
+ * operating chan.
+ * Quota for the 2nd role is calculated as 100 - quota of first mode.
+ *
+ * @E.g: iwpriv wlan0 setMccQuota 50
+ *       iwpriv p2p0 setMccQuota 50
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_MCC_CONFIG_QUOTA             71
+/* Private IOCTL for debug connection issues */
+#define WE_SET_DEBUG_LOG                72
+#ifdef WE_SET_TX_POWER
+#undef WE_SET_TX_POWER
+#endif
+
+/*
+ * <ioctl>
+ * setTxPower - Set the current transmit power
+ *
+ * @INPUT: Transmission power in dBm
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the current transmit power.
+ * This setting does not persist over reboots.
+ *
+ * @E.g: iwpriv wlan0 setTxPower 10
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_TX_POWER                 74
+/* Private ioctl for earlyrx power save feature */
+#define WE_SET_EARLY_RX_ADJUST_ENABLE         75
+#define WE_SET_EARLY_RX_TGT_BMISS_NUM         76
+#define WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE    77
+#define WE_SET_EARLY_RX_SLOP_STEP             78
+#define WE_SET_EARLY_RX_INIT_SLOP             79
+#define WE_SET_EARLY_RX_ADJUST_PAUSE          80
+/*
+ * <ioctl>
+ * setMcRate  - Set the data rate for multicast data
+ *
+ * @INPUT: 1 to 32
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the data rate for multicast data. Note that this command
+ * is allowed only in STA, IBSS, or QCMobileAP mode
+ *
+ * @E.g: iwpriv wlan0 setMcRate <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_MC_RATE                        81
+#define WE_SET_EARLY_RX_DRIFT_SAMPLE          82
+/* Private ioctl for packet power save */
+/*
+ * <ioctl>
+ * 5g_ebt - Sets the 5g_ebt
+ *
+ * @INPUT: <value>
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to set 5g_ebt
+ *
+ * @E.g: iwpriv wlan0 5g_ebt <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_PPS_5G_EBT                         83
+/*
+ * <ioctl>
+ * cts_cbw  - Set CTS channel BW for dynamic BW adjustment
+ *
+ * @INPUT: 20 t0 160
+ *
+ * @OUTPUT: None
+ *
+ * This IOTCL used to set CTS channel BW for dynamic BW adjustment
+ *
+ * @E.g: iwpriv wlan0 cts_cbw <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_CTS_CBW                        84
+#define WE_DUMP_STATS                         85
+#define WE_CLEAR_STATS                        86
+/* Private sub ioctl for starting/stopping the profiling */
+#define WE_START_FW_PROFILE                      87
+
+/*
+ * <ioctl>
+ * setChanChange - Initiate channel change
+ *
+ * @INPUT: channel number to switch to.
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to initiate a channel change.
+ * If called on STA/CLI interface it will send the
+ * ECSA action frame to the connected SAP/GO asking to
+ * initiate the ECSA, if supported.
+ * If called on SAP/GO interface it will initiate
+ * ECSA and ask connected peers to move to new channel.
+ *
+ * @E.g: iwpriv wlan0 setChanChange <channel>
+ * iwpriv wlan0 setChanChange 1
+ *
+ * Supported Feature: ECSA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_CHANNEL                        88
+#define WE_SET_CONC_SYSTEM_PREF               89
+
+/*
+ * <ioctl>
+ * set_11ax_rate - set 11ax rates to FW
+ *
+ * @INPUT: rate code
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL fixes the Tx data rate of 11AX.
+ *
+ * @E.g: iwpriv wlan0 set_11ax_rate <rate code>
+ *
+ * Supported Feature: STA/SAP
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_SET_11AX_RATE                      91
+
+/*
+ * <ioctl>
+ * enable_dcm - enable Dual Carrier Modulation(DCM)
+ *
+ * @INPUT: 0/1
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL enables/disables DCM.
+ *
+ * @E.g: iwpriv wlan0 enable_dcm <0/1>
+ *
+ * Supported Feature: STA/SAP
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_SET_DCM                            92
+
+/*
+ * <ioctl>
+ * range_ext - enable Range extension
+ *
+ * @INPUT: 0/1
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL enables/disables Range extension.
+ *
+ * @E.g: iwpriv wlan0 range_ext <1/0>
+ *
+ * Supported Feature: STA/SAP
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_SET_RANGE_EXT                      93
+
+/*
+ * <ioctl>
+ * wow_ito - sets the timeout value for inactivity data while
+ * in power save mode during wow
+ *
+ * @INPUT: int
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL set the timeout value for inactivity data in power save mode
+ *
+ * @E.g: iwpriv wlan0 wow_ito 20
+ *
+ * Supported Feature: STA
+ *
+ * Usage: External
+ *
+ * </ioctl>
+ */
+#define WE_SET_WOW_DATA_INACTIVITY_TO    94
+
+/*
+ * <ioctl>
+ * pdev_reset - reset the pdev
+ *
+ * @INPUT: Reset command to initiate:
+ *    TX_FLUSH = 1
+ *    WARM_RESET = 2
+ *    COLD_RESET = 3
+ *    WARM_RESET_RESTORE_CAL = 4
+ *    COLD_RESET_RESTORE_CAL = 5
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to reset the pdev. The primary use is
+ * for internal testing. It is not expected that this will
+ * be used on a production device.
+ *
+ * @E.g: iwpriv wlan0 pdev_reset <command>
+ * iwpriv wlan0 pdev_reset 1
+ *
+ * Supported Feature: None
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_SET_PDEV_RESET    95
+
+/*
+ * setModDTIM - Change Modulated DTIM
+ *
+ * @INPUT: set_value.
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to change modulated DTIM
+ * value without WIFI OFF/ON.
+ *
+ * @E.g: iwpriv wlan0 setModDTIM <value>
+ * iwpriv wlan0 setModDTIM 2
+ *
+ * Supported Feature: N/A
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_MODULATED_DTIM                 96
+
+/* Private ioctls and their sub-ioctls */
+#define WLAN_PRIV_SET_NONE_GET_INT    (SIOCIWFIRSTPRIV + 1)
+#define WE_GET_11D_STATE     1
+#define WE_GET_WLAN_DBG      4
+#define WE_GET_MAX_ASSOC     6
+/* 7 is unused */
+#define WE_GET_SAP_AUTO_CHANNEL_SELECTION 8
+
+/*
+ * <ioctl>
+ * getconcurrency - Get concurrency mode
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: It shows concurrency value
+ * Bit 0:STA   1:SAP     2:P2P_Client  3:P2P_GO
+ *     4:FTM   5:IBSS    6:Monitor     7:P2P_Device
+ *     8:OCB   9:EPPING  10:QVIT       11:NDI
+ *
+ * This IOCTL is used to retrieve concurrency mode.
+ *
+ * @E.g: iwpriv wlan0 getconcurrency
+ * wlan0     getconcurrency:5
+ * Above value shows STA+P2P_Client
+ *
+ * Supported Feature: Concurrency
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_CONCURRENCY_MODE 9
+/*
+ * <ioctl>
+ * get_nss - Get the number of spatial STBC streams (NSS)
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: NSS
+ *  wlan0     get_nss:2
+ *
+ * This IOTCL used to get the number of spatial STBC streams
+ *
+ * @E.g: iwpriv wlan0 get_nss
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_NSS           11
+/*
+ * <ioctl>
+ * get_ldpc - This IOCTL gets the low density parity check (LDPC)
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: ldpc
+ *  wlan0     get_ldpc:1
+ *
+ * This IOTCL used to gets the low density parity check (LDPC)
+ *
+ * @E.g: iwpriv wlan0 get_ldpc
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_LDPC          12
+/*
+ * <ioctl>
+ * get_tx_stbc - Get the value of the current Tx space time block code (STBC)
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: TXSTBC
+ *  wlan0     get_tx_stbc:1
+ *
+ * This IOTCL get the value of the current Tx space time block code (STBC)
+ *
+ * @E.g: iwpriv wlan0 get_tx_stbc
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_TX_STBC       13
+/*
+ * <ioctl>
+ * get_rx_stbc - Gets the value of the current Rx STBC
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Rx STBC
+ *  wlan0     get_rx_stbc:1
+ *
+ * This IOTCL used to get the value of the current Rx STBC
+ *
+ * @E.g: iwpriv wlan0 get_rx_stbc
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_RX_STBC       14
+/*
+ * <ioctl>
+ * get_shortgi - Get the value of the current short GI setting
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Enable/disable of shortgi
+ *  wlan0     get_shortgi:1
+ *
+ * This IOCTL gets the value of the current short GI setting
+ *
+ * @E.g: iwpriv wlan0 get_shortgi
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_SHORT_GI      15
+/*
+ * <ioctl>
+ * get_rtscts - Get the value of the current RTS/CTS setting.
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Enable/disable of RTS/CTS
+ *  wlan0     get_rtscts:33
+ *
+ * This IOTCL get the value of the current RTS/CTS setting.
+ *
+ * @E.g: iwpriv wlan0 get_rtscts
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_RTSCTS        16
+/*
+ * <ioctl>
+ * get_chwidth - Get the current channel width setting
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: channel width
+ *  wlan0     get_chwidth:0
+ *
+ * This IOTCL get the current channel width setting.
+ *
+ * @E.g: iwpriv wlan0 get_chwidth
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_CHWIDTH       17
+/*
+ * <ioctl>
+ * get_anienable - Get the anienable
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT:
+ *  wlan0     get_anienable:0
+ *
+ * This IOTCL get the anienable
+ *
+ * @E.g: iwpriv wlan0 get_anienable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_ANI_EN_DIS    18
+/*
+ * <ioctl>
+ * get_aniplen  - Get the aniplen
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT:
+ *  wlan0     get_aniplen:0
+ *
+ * This IOTCL get the aniplen
+ *
+ * @E.g: iwpriv wlan0 get_aniplen
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_ANI_POLL_PERIOD    19
+/*
+ * <ioctl>
+ * get_anilislen- Get the anilislen
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT:
+ *  wlan0     get_anilislen:0
+ *
+ * This IOTCL used to get anilislen
+ *
+ * @E.g: iwpriv wlan0 get_anilislen
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_ANI_LISTEN_PERIOD  20
+/*
+ * <ioctl>
+ * get_aniofdmlvl - Get the OFDM level
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: OFDM
+ *  wlan0     get_aniofdmlvl:0
+ *
+ * This IOTCL used to get ofdm level
+ *
+ * @E.g: iwpriv wlan0 get_aniofdmlvl
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_ANI_OFDM_LEVEL     21
+/*
+ * <ioctl>
+ * get_aniccklvl - Get the cck level
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT:
+ *  wlan0     get_aniccklvl:0
+ *
+ * This IOTCL used to get cck level
+ *
+ * @E.g: iwpriv wlan0 get_aniccklvl
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_ANI_CCK_LEVEL      22
+/*
+ * <ioctl>
+ * get_cwmenable - Get the value of the dynamic channel bandwidth setting
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Enable/disable dynamic channel bandwidth
+ *  wlan0     get_cwmenable:0
+ *
+ * This IOTCL get the value of the dynamic channel bandwidth setting
+ *
+ * @E.g: iwpriv wlan0 get_cwmenable
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_DYNAMIC_BW         23
+/*
+ * <ioctl>
+ * get_txchainmask - Get the txchainmask that was set
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: txchainmask
+ *  wlan0     get_txchainmask:1
+ *
+ * This IOCTL gets the txchainmask that was set
+ * This command is useful if it was previously set
+ *
+ * @E.g: iwpriv wlan0 get_txchainmask
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_TX_CHAINMASK  24
+/*
+ * <ioctl>
+ * get_rxchainmask - Get the rxchainmask that was set
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: rxchainmask
+ *  wlan0     get_rxchainmask:1
+ *
+ * This IOCTL gets the rxchainmask that was set
+ * This command is useful only if it was previously set.
+ *
+ * @E.g: iwpriv wlan0 get_rxchainmask
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_RX_CHAINMASK  25
+/*
+ * <ioctl>
+ * get_11nrate - Get the fixed Tx data rate
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Using this command does not return the same value as set
+ *  wlan0     get_11nrate:0
+ *
+ * This IOCTL gets the fixed Tx data rate
+ * This command is useful only if setting the fixed Tx rate.
+ *
+ * @E.g: iwpriv wlan0 get_11nrate
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_11N_RATE      26
+/*
+ * <ioctl>
+ * get_ampdu - Get the maximum subframe of ampdu
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Maximum subframe of ampdu
+ *  wlan0     get_ampdu:1
+ *
+ * This IOCTL gets the maximum subframe of ampdu
+ * This command is useful only if setting ampdu.
+ *
+ * @E.g: iwpriv wlan0 get_ampdu
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_AMPDU         27
+/*
+ * <ioctl>
+ * get_amsdu - Get the maximum subframe of amsdu
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Maximum subframe of amsdu
+ *  wlan0     get_amsdu:1
+ *
+ * This IOCTL gets the maximum subframe of amsdu.
+ * This command is useful only if setting amsdu
+ *
+ * @E.g: iwpriv wlan0 get_amsdu
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_AMSDU         28
+/*
+ * <ioctl>
+ * get_txpow2g - Get the current 2 GHz Tx power setting
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Tx Power in dbm
+ * wlan0     get_txpow2g:0
+ *
+ * This IOCTL gets the current 2 GHz Tx power setting
+ * This command is useful if setting Tx power
+ *
+ * @E.g: iwpriv wlan0 get_txpow2g
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_TXPOW_2G      29
+/*
+ * <ioctl>
+ * get_txpow5g - Get the current 5 GHz Tx power setting
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Tx Power in dbm
+ * wlan0     get_txpow5g:0
+ *
+ * This IOCTL gets the current 5 GHz Tx power setting
+ * This command is useful if setting Tx power
+ *
+ * @E.g: iwpriv wlan0 get_txpow5g
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_TXPOW_5G      30
+/* 31 is unused */
+#define WE_GET_PPS_PAID_MATCH           32
+#define WE_GET_PPS_GID_MATCH            33
+#define WE_GET_PPS_EARLY_TIM_CLEAR      34
+#define WE_GET_PPS_EARLY_DTIM_CLEAR     35
+#define WE_GET_PPS_EOF_PAD_DELIM        36
+#define WE_GET_PPS_MACADDR_MISMATCH     37
+#define WE_GET_PPS_DELIM_CRC_FAIL       38
+#define WE_GET_PPS_GID_NSTS_ZERO        39
+#define WE_GET_PPS_RSSI_CHECK           40
+/* Private ioctl for QPower */
+#define WE_GET_QPOWER_MAX_PSPOLL_COUNT            41
+#define WE_GET_QPOWER_MAX_TX_BEFORE_WAKE          42
+#define WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL   43
+#define WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 44
+/* GTX Commands */
+/*
+ * <ioctl>
+ * get_gtxHTMcs - Get the tx HTM
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: HTM
+ *  wlan0     get_gtxHTMcs:32896
+ *
+ * This IOTCL used to get HTM
+ *
+ * @E.g: iwpriv wlan0 get_gtxHTMcs
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_GTX_HT_MCS               47
+/*
+ * <ioctl>
+ * get_gtxVHTMcs - Get the VHTM
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: VHTM
+ *  wlan0     get_gtxVHTMcs:524800
+ *
+ * This IOTCL used to get the VHTM
+ *
+ * @E.g: iwpriv wlan0 get_gtxVHTMcs
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_GTX_VHT_MCS              48
+/*
+ * <ioctl>
+ * get_gtxUsrCfg - Get the tx cfg
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: TXCFG
+ *  wlan0     get_gtxUsrCfg:32
+ *
+ * This IOTCL used to get the tx cfg
+ *
+ * @E.g: iwpriv wlan0 get_gtxUsrCfg
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_GTX_USRCFG               49
+/*
+ * <ioctl>
+ * get_gtxThre - Get the tx threshold
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Threshold
+ *  wlan0     get_gtxThre:3
+ *
+ * This IOCTL is used to get tx threshold
+ *
+ * @E.g: iwpriv wlan0 get_gtxThre
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_GTX_THRE                 50
+/*
+ * <ioctl>
+ * get_gtxMargin - Get the tx margin
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: GTXMARGIN
+ *  wlan0     get_gtxMargin:2
+ *
+ * This IOCTL is used to set tx margin
+ *
+ * @E.g: iwpriv wlan0 get_gtxMargin
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_GTX_MARGIN               51
+/*
+ * <ioctl>
+ * get_gtxStep - Get the tx step
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: GTXSTEP
+ * wlan0     get_gtxStep:0
+ *
+ * This IOCTL is used to get the gtx step
+ *
+ * @E.g: iwpriv wlan0 get_gtxStep
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_GTX_STEP                 52
+/*
+ * <ioctl>
+ * get_gtxMinTpc - Get the tx miminum tpc
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: TPC
+ * wlan0     get_gtxMinTpc:0
+ *
+ * This IOCTL is used to get tx miminum tpc
+ *
+ * @E.g: iwpriv wlan0 get_gtxMinTpc
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_GTX_MINTPC               53
+/*
+ * <ioctl>
+ * get_gtxBWMask - Get the tx BW MASK
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: MASK
+ * wlan0     get_gtxBWMask:15
+ *
+ * This IOCTL is used get gtx bw mask
+ *
+ * @E.g: iwpriv wlan0 get_gtxBWMask
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_GTX_BWMASK               54
+#define WE_GET_TEMPERATURE              56
+#define WE_CAP_TSF                      58
+#define WE_GET_ROAM_SYNCH_DELAY         59
+
+/*
+ * <ioctl>
+ * get_dcm - Get dcm enablement value
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: 0/1
+ * wlan0     get_dcm
+ *
+ * This IOCTL is used get dcm value
+ *
+ * Supported Feature: STA/SAP
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_GET_DCM                      60
+
+/*
+ * <ioctl>
+ * get_dcm - Get range extension enablement value
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: 0/1
+ * wlan0     get_range_ext
+ *
+ * This IOCTL is used get range_extension value
+ *
+ * Supported Feature: STA/SAP
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_GET_RANGE_EXT                61
+
+/* Private ioctls and their sub-ioctls */
+#define WLAN_PRIV_SET_INT_GET_INT     (SIOCIWFIRSTPRIV + 2)
+
+/* Private ioctls and their sub-ioctls */
+#define WLAN_PRIV_SET_CHAR_GET_NONE   (SIOCIWFIRSTPRIV + 3)
+#define WE_WOWL_ADD_PTRN     1
+#define WE_WOWL_DEL_PTRN     2
+/*
+ * <ioctl>
+ * neighbor - Send neighbor report request
+ *
+ * @INPUT: string
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL create a Neighbor report request and send it to peer
+ *
+ * @E.g: iwpriv wlan0 neighbor "SSID"
+ *
+ * Supported Feature: 11k
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_NEIGHBOR_REPORT_REQUEST 3
+/*
+ * <ioctl>
+ * set_ap_wps_ie - Set the P2P IE of the probe response
+ *
+ * @INPUT: string
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the P2P IE of the probe response
+ *
+ * @E.g: iwpriv wlan0 set_ap_wps_ie abcd
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_AP_WPS_IE     4
+#define WE_SET_CONFIG        5
+
+/*
+ * <ioctl>
+ * unit_test - execute component-level unit tests
+ *
+ * @INPUT: string - the name of the component to test.
+ *	All tests are executed if unspecified
+ * @OUTPUT: None
+ *
+ * Usage: Internal only
+ * </ioctl>
+ */
+#define WE_UNIT_TEST         6
+
+/* Private ioctls and their sub-ioctls */
+#define WLAN_PRIV_SET_THREE_INT_GET_NONE   (SIOCIWFIRSTPRIV + 4)
+#define WE_SET_WLAN_DBG      1
+#define WE_SET_DP_TRACE      2
+#define WE_SET_FW_TEST       4
+
+/* Private ioctls and their sub-ioctls */
+#define WLAN_PRIV_GET_CHAR_SET_NONE   (SIOCIWFIRSTPRIV + 5)
+#define WE_WLAN_VERSION      1
+#define WE_GET_STATS         2
+/*
+ * <ioctl>
+ * getConfig - gets the values of all configurations listed in WCNSS
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Current configuration to the sys log
+ *  wlan0	getConfig: WLAN configuration written to system log
+ *
+ * This IOCTL gets the values of all configurations listed in WCNSS
+ *
+ * @E.g: iwpriv wlan0 getConfig
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_CFG           3
+#define WE_GET_WMM_STATUS    4
+/*
+ * <ioctl>
+ * getChannelList - Get the available channel list while in QCMobileAP
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Channel list
+ * wlan0     getChannelList:36 US 1..165
+ *
+ * This IOCTL gets the available channel list while in QCMobileAP
+ *
+ * @E.g: iwpriv wlan0 getChannelList
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_CHANNEL_LIST  5
+/*
+ * <ioctl>
+ * getRSSI - Get the Received Signal Strength Indicator
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: RSSI
+ * wlan0     getRSSI:rsssi=-32
+ *
+ * This IOCTL gets the Received Signal Strength Indicator (RSSI)
+ *
+ * @E.g: iwpriv wlan0 getRSSI
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_RSSI          6
+
+/*
+ * <ioctl>
+ * getSuspendStats - Get suspend/resume stats
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: character string containing formatted suspend/resume stats
+ *
+ * This ioctl is used to get suspend/resume stats formatted for display.
+ * Currently it includes suspend/resume counts, wow wake up reasons, and
+ * suspend fail reasons.
+ *
+ * @E.g: iwpriv wlan0 getSuspendStats
+ * iwpriv wlan0 getSuspendStats
+ *
+ * Supported Feature: suspend/resume
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_GET_SUSPEND_RESUME_STATS 7
+#ifdef FEATURE_WLAN_TDLS
+/*
+ * <ioctl>
+ * getTdlsPeers - Get all TDLS peers.
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Returns the MAC address of all the TDLS peers
+ * wlan0     getTdlsPeers:
+ * MAC               Id cap up RSSI
+ * ---------------------------------
+ * 00:0a:f5:0e:bd:18  2   Y  Y  -44
+ * 00:0a:f5:bf:0e:12  0   N  N    0
+ *
+ * This IOCTL is used to get all TDLS peers.
+ *
+ * @E.g: iwpriv wlan0 getTdlsPeers
+ *
+ * Supported Feature: TDLS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_TDLS_PEERS    8
+#endif
+#ifdef WLAN_FEATURE_11W
+/*
+ * <ioctl>
+ * getPMFInfo - get the PMF info of the connected session
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT:
+ *  wlan0     getPMFInfo:
+ *  BSSID E4:F4:C6:0A:E0:36, Is PMF Assoc? 0
+ *  Number of Unprotected Disassocs 0
+ *  Number of Unprotected Deauths 0
+ *
+ * This IOCTL is used to get the PMF stats/status of the current
+ * connection.
+ *
+ * @e.g:iwpriv wlan0 getPMFInfo
+ *
+ * Supported Feature: PMF
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_11W_INFO      9
+#endif
+#define WE_GET_STATES        10
+/*
+ * <ioctl>
+ * getIbssSTAs - get ibss sta info
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Give the MAC of the IBSS STA
+ *  wlan0     getIbssSTAs:
+ *  1 .8c:fd:f0:01:9c:bf
+ *
+ * This IOCTL is used to get ibss sta info
+ *
+ * @E.g: iwpriv wlan0 getIbssSTAs
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_IBSS_STA_INFO 11
+/*
+ * <ioctl>
+ * getphymode - Get the current phymode.
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: In phymode
+ *  wlan0     getphymode:AUTO MODE
+ *
+ * This IOCTL used to gets the current phymode.
+ *
+ * @E.g: iwpriv wlan0 getphymode
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_PHYMODE       12
+
+/*
+ * <ioctl>
+ * getOemDataCap - Get the oem data caps.
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: oem data capability
+ *
+ * This IOCTL used to gets the current oem data cap.
+ *
+ * @E.g: iwpriv wlan0 getOemDataCap
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_GET_OEM_DATA_CAP  13
+
+/*
+ * <ioctl>
+ * getSNR - Enable SNR Monitoring
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: Signal strength/ratio
+ *  wlan0     getSNR:1
+ *
+ * This IOCTL is used to get ibss sta info
+ *
+ * @E.g: iwpriv wlan0 getSNR
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+
+#define WE_GET_SNR           14
+#define WE_LIST_FW_PROFILE      15
+
+/*
+ * <ioctl>
+ *
+ * get_ba_timeout - to get timeout for each AC
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: displays timeout value for each access class
+ *
+ * @E.g.: iwpriv wlan0 get_ba_timeout
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_GET_BA_AGEING_TIMEOUT 16
+
+/* Private ioctls and their sub-ioctls */
+#define WLAN_PRIV_SET_NONE_GET_NONE   (SIOCIWFIRSTPRIV + 6)
+
+/*
+ * <ioctl>
+ * reassoc - Trigger STA re-association to the connected AP
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to trigger STA reassociation to the connected AP.
+ *
+ * @E.g: iwpriv wlan0 reassoc
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_SET_REASSOC_TRIGGER     8
+/*
+ * <ioctl>
+ * ibssPeerInfoAll - Print the ibss peers's MAC, rate and RSSI
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: print ibss peer in info logs
+ *  pPeerInfo->numIBSSPeers = 1
+ *  PEER ADDR : 8c:fd:f0:01:9c:bf TxRate: 1 Mbps RSSI: -35
+ *
+ * This IOCTL is used to rint the ibss peers's MAC, rate and RSSI
+ * in info logs
+ *
+ * @E.g: iwpriv wlan0 ibssPeerInfoAll
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_IBSS_GET_PEER_INFO_ALL 10
+/* Sub ioctls 11 to 16 are not used */
+#define WE_GET_RECOVERY_STAT       17
+#define WE_GET_FW_PROFILE_DATA     18
+/*
+ * <ioctl>
+ * stop_obss_scan - Stop obss scan
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to stop obss scan
+ *
+ * @E.g: iwpriv wlan0 stop_obss_scan
+ *
+ * Supported Feature: Scan
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_STOP_OBSS_SCAN          19
+
+/* Private ioctls and their sub-ioctls */
+#define WLAN_PRIV_SET_VAR_INT_GET_NONE   (SIOCIWFIRSTPRIV + 7)
+
+#define WE_P2P_NOA_CMD       2
+/* subcommands 3 is unused */
+
+#define WE_MAC_PWR_DEBUG_CMD 4
+
+/* subcommand 5 is unused */
+
+/*
+ * <ioctl>
+ * ibssPeerInfo - Print the ibss peers's MAC, rate and RSSI
+ *
+ * @INPUT: staid
+ *
+ * @OUTPUT: print ibss peer corresponding to staid in info logs
+ *  PEER ADDR : 8c:fd:f0:01:9c:bf TxRate: 1 Mbps RSSI: -35
+ *
+ * This IOCTL is used to print the specific ibss peers's MAC,
+ * rate and RSSI in info logs
+ *
+ * @E.g: iwpriv wlan0 ibssPeerInfo <sta_id>
+ *  iwpriv wlan0 ibssPeerInfo 0
+ *
+ * Supported Feature: IBSS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_IBSS_GET_PEER_INFO   6
+#define WE_UNIT_TEST_CMD   7
+
+#define WE_MTRACE_DUMP_CMD    8
+#define WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD    9
+
+
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+#define WE_LED_FLASHING_PARAM    10
+#endif
+
+/*
+ * <ioctl>
+ * pm_clist - Increments the index value of the concurrent connection list
+ * and update with the input parameters provided.
+ *
+ * @INPUT: Following 8 arguments:
+ * @vdev_id: vdev id
+ * @tx_streams: TX streams
+ * @rx_streams: RX streams
+ * @chain_mask: Chain mask
+ * @type: vdev_type
+ *    AP:1    STA:2    IBSS:3    Monitor:4    NAN:5    OCB:6    NDI:7
+ * @sub_type: vdev_subtype
+ *    P2P_Device:1    P2P_Client:2     P2P_GO:3
+ *    Proxy_STA:4     Mesh:5           Mesh_11s:6
+ * @channel: Channel
+ * @mac: Mac id
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to increments the index value of the concurrent connection
+ * list and update with the input parameters provided.
+ *
+ * @E.g: iwpriv wlan0 pm_clist vdev_id tx_streams rx_streams chain_mask type
+ *                    sub_type channel mac
+ * iwpriv wlan0 pm_clist 1 2 2 1 2 3 10 1
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_POLICY_MANAGER_CLIST_CMD    11
+
+/*
+ * <ioctl>
+ * pm_dlist - Delete the index from the concurrent connection list that is
+ * present in the given vdev_id.
+ *
+ * @INPUT: delete_all, vdev_id
+ * @delete_all: delete all indices
+ * @vdev_id: vdev id
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to delete the index from the concurrent connection list
+ * that is present in the given vdev_id.
+ *
+ * @E.g: iwpriv wlan0 pm_dlist delete_all vdev_id
+ * iwpriv wlan0 pm_dlist 0 1
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_POLICY_MANAGER_DLIST_CMD    12
+
+/*
+ * <ioctl>
+ * pm_dbs - Set dbs capability and system preference
+ *
+ * @INPUT: dbs, system_pref
+ * @dbs: Value of DBS capability to be set
+ * @system_pref: System preference
+ *     0:PM_THROUGHPUT 1: PM_POWERSAVE 2: PM_LATENCY
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to set dbs capability and system preference.
+ *
+ * @E.g: iwpriv wlan0 pm_dbs dbs system_pref
+ * iwpriv wlan0 pm_dbs 1 0
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_POLICY_MANAGER_DBS_CMD      13
+
+/*
+ * <ioctl>
+ * pm_pcl - Set pcl for concurrency mode.
+ *
+ * @INPUT: policy_mgr_con_mode
+ * @policy_mgr_con_mode: concurrency mode for PCL table
+ *     0:STA  1:SAP  2:P2P_Client  3:P2P_GO  4:IBSS
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to set pcl for concurrency mode.
+ *
+ * @E.g: iwpriv wlan0 pm_pcl policy_mgr_con_mode
+ * iwpriv wlan0 pm_pcl 0
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_POLICY_MANAGER_PCL_CMD      14
+
+/*
+ * <ioctl>
+ * pm_cinfo - Shows the concurrent connection list.
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to show the concurrent connection list.
+ *
+ * @E.g: iwpriv wlan0 pm_cinfo
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_POLICY_MANAGER_CINFO_CMD    15
+
+/*
+ * <ioctl>
+ * pm_ulist - Updates the index value of the concurrent connection list
+ * with the input parameters provided.
+ *
+ * @INPUT: Following 8 arguments:
+ * @vdev_id: vdev id
+ * @tx_streams: TX streams
+ * @rx_streams: RX streams
+ * @chain_mask: Chain mask
+ * @type: vdev_type
+ *    AP:1    STA:2    IBSS:3    Monitor:4    NAN:5    OCB:6    NDI:7
+ * @sub_type: vdev_subtype
+ *    P2P_Device:1    P2P_Client:2     P2P_GO:3
+ *    Proxy_STA:4     Mesh:5           Mesh_11s:6
+ * @channel: Channel
+ * @mac: Mac id
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to updates the index value of the concurrent
+ * connection list with the input parameters provided.
+ *
+ * @E.g: iwpriv wlan0 pm_ulist vdev_id tx_streams rx_streams chain_mask type
+ *                    sub_type channel mac
+ * iwpriv wlan0 pm_ulist 1 2 2 1 2 3 10 1
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_POLICY_MANAGER_ULIST_CMD    16
+
+/*
+ * <ioctl>
+ * pm_query_action - Initiate actions needed on current connections as
+ * per the channel provided.
+ *
+ * @INPUT: channel
+ * @channel: Channel on which new connection will be.
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to initiate actions needed on current connections
+ * as per the channel provided.
+ *
+ * @E.g: iwpriv wlan0 pm_query_action channel
+ * iwpriv wlan0 pm_query_action 6
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_POLICY_MANAGER_QUERY_ACTION_CMD    17
+
+/*
+ * <ioctl>
+ * pm_query_allow - Checks for allowed concurrency combination
+ *
+ * @INPUT: mode, channel, bandwidth
+ * @mode:	new connection mode
+ *     0:STA  1:SAP  2:P2P_Client  3:P2P_GO  4:IBSS
+ * @channel: channel on which new connection is coming up
+ * @bandwidth: Bandwidth requested by the connection
+ *     0:None    1:5MHz    2:10MHz      3:20MHz
+ *     4:40MHz   5:80MHz   6:80+80MHz   7:160MHz
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to checks for allowed concurrency combination.
+ *
+ * @E.g: iwpriv wlan0 pm_query_allow mode channel bandwidth
+ * iwpriv wlan0 pm_query_allow 0 6 4
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_POLICY_MANAGER_QUERY_ALLOW_CMD    18
+
+/*
+ * <ioctl>
+ * pm_run_scenario - Create scenario with number of connections provided.
+ *
+ * @INPUT: num_of_conn
+ * @num_of_conn: the number of connections (values: 1~3)
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to create scenario with the number of connections
+ * provided.
+ *
+ * @E.g: iwpriv wlan0 pm_run_scenario num_of_conn
+ * iwpriv wlan0 pm_run_scenario 1
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_POLICY_MANAGER_SCENARIO_CMD 19
+
+/*
+ * <ioctl>
+ * pm_set_hw_mode - Set hardware for single/dual mac.
+ *
+ * @INPUT: hw_mode
+ *     0:single mac     1:dual mac
+ *     2: 2x2 5g + 1x1 2g dbs mode
+ *     3: 2x2 2g + 1x1 5g dbs mode
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to set hardware for single/dual mac.
+ *
+ * @E.g: iwpriv wlan0 pm_set_hw_mode hw_mode
+ * iwpriv wlan0 pm_set_hw_mode 1
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_POLICY_SET_HW_MODE_CMD 20
+
+/*
+ * <ioctl>
+ * ch_avoid - unit test SAP channel avoidance
+ *
+ * @INPUT: chan avoid ranges
+ *
+ * @OUTPUT: none
+ *
+ * This IOCTL is used to fake a channel avoidance event.
+ * To test SAP/GO chan switch during chan avoid event process.
+ *
+ * @E.g: iwpriv wlan0 ch_avoid 2452 2462
+ *
+ * Supported Feature: SAP chan avoidance.
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_SET_CHAN_AVOID 21
+
+/*
+ * <ioctl>
+ * set_scan_cfg - Set dual MAC scan config parameters.
+ *
+ * @INPUT: dbs, dbs_plus_agile_scan, single_mac_scan_with_dbs
+ * @dbs: Value of DBS bit
+ * @dbs_plus_agile_scan: Value of DBS plus agile scan bit
+ * @single_mac_scan_with_dbs: Value of Single MAC scan with DBS
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to set the dual MAC scan config.
+ *
+ * @E.g: iwpriv wlan0 set_scan_cfg dbs dbs_plus_agile_scan
+ *                    single_mac_scan_with_dbs
+ * iwpriv wlan0 set_scan_cfg 1 0 1
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_DUAL_MAC_SCAN_CONFIG    21
+
+/*
+ * <ioctl>
+ * set_fw_mode_cfg - Sets the dual mac FW mode config
+ *
+ * @INPUT: dbs, dfs
+ * @dbs: DBS bit
+ * @dfs: Agile DFS bit
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL is used to set the dual mac FW mode config.
+ *
+ * @E.g: iwpriv wlan0 set_fw_mode_cfg dbs dfs
+ * iwpriv wlan0 set_fw_mode_cfg 1 1
+ *
+ * Supported Feature: DBS
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_SET_DUAL_MAC_FW_MODE_CONFIG 22
+#define WE_SET_MON_MODE_CHAN 23
+/*
+ * <ioctl>
+ * txrx_stats - TXRX statistics query
+ *
+ * @INPUT: query category, mac id (default mac id is 0)
+ *
+ * @OUTPUT: TXRX statistics result
+ *
+ * This IOCTL is used to get TXRX statistics counters.
+ *
+ * @E.g: iwpriv wlan0 txrx_stats 21 0
+ * iwpriv wlan0 txrx_stats 21 1
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_SET_TXRX_STATS    24
+
+
+#ifdef FEATURE_WLAN_TDLS
+#undef  MAX_VAR_ARGS
+#define MAX_VAR_ARGS         11
+#else
+#undef  MAX_VAR_ARGS
+#define MAX_VAR_ARGS         9
+#endif
+
+/*
+ * <ioctl>
+ * fips_test - Perform a FIPS test
+ *
+ * @INPUT: Binary representation of the following packed structure
+ *
+ * @OUTPUT: Binary representation of the following packed structure
+ *
+ * This IOCTL is used to perform FIPS certification testing
+ *
+ * @E.g: iwpriv wlan0 fips_test <test vector>
+ *
+ * iwpriv wlan0 fips_test <tbd>
+ *
+ * Supported Feature: FIPS
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WLAN_PRIV_FIPS_TEST (SIOCIWFIRSTPRIV +  8)
+
+/* Private ioctls (with no sub-ioctls) */
+/* note that they must be odd so that they have "get" semantics */
+/*
+ * <ioctl>
+ * addTspec - Add TSPEC for each AC
+ *
+ * @INPUT: 19 TSPEC params
+ *     @[arg0]: handle
+ *     @[arg1]: tid
+ *     @[arg2]: dir
+ *     @[arg3]: psb
+ *     @[arg4]: up
+ *     @[arg5]: nomMsduSize
+ *     @[arg6]: maxMsduSize
+ *     @[arg7]: minDataRate
+ *     @[arg8]: meanDataRate
+ *     @[arg9]: peakDataRate
+ *     @[arg10]: maxBurstSize
+ *     @[arg11]: minPhyRate
+ *     @[arg12]: sba
+ *     @[arg13]: minServiceIntv
+ *     @[arg14]: suspendIntv
+ *     @[arg15]: burstSizeDefn
+ *     @[arg16]: ackPolicy
+ *     @[arg17]: inactivityPeriod
+ *     @[arg18]: maxServiceIntv
+ *
+ * @OUTPUT: Success/Failure
+ *
+ * This IOCTL is used to add TSPEC for each AC.
+ *
+ * @E.g: iwpriv wlan0 addTspec <handle> <tid> <dir> <psb> <up> <nomMsduSize>
+ *                             <maxMsduSize> <minDataRate> <meanDataRate>
+ *                             <peakDataRate> <maxBurstSize> <minPhyRate>
+ *                             <sba> <minServiceIntv> <suspendIntv>
+ *                             <burstSizeDefn> <ackPolicy> <inactivityPeriod>
+ *                             <maxServiceIntv>
+ * iwpriv wlan0 addTspec 7001 6 2 1 6 0x80D0 0x80D0 0x14500 0x14500 0x14500
+ *                      0 0x5B8D80 0x2001 20 2000 0 0 0 2000
+ * wlan0     addTspec:3
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WLAN_PRIV_ADD_TSPEC (SIOCIWFIRSTPRIV +  9)
+/*
+ * <ioctl>
+ * delTspec - Delete TSPEC entry for each AC
+ *
+ * @INPUT: 1 TSPEC param
+ *     @[arg0]: handle
+ *
+ * @OUTPUT: Success/Failure
+ *
+ * This IOCTL is used to delete TSPEC entry for each AC.
+ *
+ * @E.g: iwpriv wlan0 delTspec <handle>
+ * iwpriv wlan0 delTspec 7001
+ * wlan0     delTspec:16
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WLAN_PRIV_DEL_TSPEC (SIOCIWFIRSTPRIV + 11)
+/*
+ * <ioctl>
+ * getTspec - Get TSPEC entry for each AC
+ *
+ * @INPUT: 1 TSPEC param
+ *     @[arg0]: handle
+ *
+ * @OUTPUT: Success/Failure
+ *
+ * This IOCTL is used to get TSPEC entry for each AC.
+ *
+ * @E.g: iwpriv wlan0 getTspec <handle>
+ * iwpriv wlan0 getTspec 7001
+ * wlan0     delTspec:18
+ *
+ * Supported Feature: WMM
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WLAN_PRIV_GET_TSPEC (SIOCIWFIRSTPRIV + 13)
+
+/* (SIOCIWFIRSTPRIV + 10) is currently unused */
+/* (SIOCIWFIRSTPRIV + 12) is currently unused */
+/* (SIOCIWFIRSTPRIV + 14) is currently unused */
+#define WLAN_PRIV_SET_NONE_GET_THREE_INT   (SIOCIWFIRSTPRIV + 15)
+#define WE_GET_TSF      1
+/* (SIOCIWFIRSTPRIV + 16) is currently unused */
+/* (SIOCIWFIRSTPRIV + 17) is currently unused */
+/* (SIOCIWFIRSTPRIV + 19) is currently unused */
+
+#define WLAN_PRIV_SET_FTIES             (SIOCIWFIRSTPRIV + 20)
+
+/* Private ioctl for setting the host offload feature */
+#define WLAN_PRIV_SET_HOST_OFFLOAD (SIOCIWFIRSTPRIV + 18)
+
+/* Private ioctl to get the statistics */
+#define WLAN_GET_WLAN_STATISTICS (SIOCIWFIRSTPRIV + 21)
+
+/* Private ioctl to set the Keep Alive Params */
+/*
+ * <ioctl>
+ * setKeepAlive - Set the keep alive feature
+ *
+ * @INPUT: 28 bytes of information in the order of packet type, time period
+ * host IPv4 address, destination IPv4 address, destination MAC address, bssID
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL sets the keep alive feature to send either NULL
+ * or unsolicited ARP response packets
+ *
+ * @E.g: iwpriv wlan0 setKeepAlive
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WLAN_SET_KEEPALIVE_PARAMS (SIOCIWFIRSTPRIV + 22)
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+/* Private ioctl to set the packet filtering params */
+#define WLAN_SET_PACKET_FILTER_PARAMS (SIOCIWFIRSTPRIV + 23)
+#endif
+
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+/* Private ioctl to get the statistics */
+#define WLAN_SET_PNO (SIOCIWFIRSTPRIV + 24)
+#endif
+/*
+ * <ioctl>
+ * SETBAND - Set the operational band
+ *
+ * @INPUT: 0 to Auto, 1 to 5 GHz and 2 to 2.4 GHz
+ *
+ * @OUTPUT: None
+ *
+ * This IOCTL Set the operational band If the new band is different from the
+ * current operational band, it aborts the pending scan requests, flushes
+ * the existing scan results, and then change * the band capability
+ *
+ * @E.g: iwpriv wlan0 SETBAND <value>
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WLAN_SET_BAND_CONFIG  (SIOCIWFIRSTPRIV + 25)
+
+#define WLAN_PRIV_SET_MCBC_FILTER   (SIOCIWFIRSTPRIV + 26)
+/* (SIOCIWFIRSTPRIV + 27) is currently unused */
+
+/* Private ioctls and their sub-ioctls */
+#define WLAN_PRIV_SET_TWO_INT_GET_NONE   (SIOCIWFIRSTPRIV + 28)
+#define WE_SET_SMPS_PARAM    1
+#define WE_SET_FW_CRASH_INJECT    2
+#define WE_DUMP_DP_TRACE_LEVEL    3
+/* Private sub ioctl for enabling and setting histogram interval of profiling */
+#define WE_ENABLE_FW_PROFILE    4
+#define WE_SET_FW_PROFILE_HIST_INTVL    5
+
+/* Private sub-ioctl for initiating WoW suspend without Apps suspend */
+#define WE_SET_WLAN_SUSPEND    6
+#define WE_SET_WLAN_RESUME    7
+
+/*
+ * <ioctl>
+ * log_buffer - prints host/target related communication logs via dmesg
+ *
+ * @INPUT: Log Id, Count
+ *
+ * Log Id:
+ *	0) HTC_CREDIT_HISTORY_LOG
+ *	1) COMMAND_LOG,
+ *	2) COMMAND_TX_CMP_LOG,
+ *	3) MGMT_COMMAND_LOG,
+ *	4) MGMT_COMMAND_TX_CMP_LOG,
+ *	5) EVENT_LOG,
+ *	6) RX_EVENT_LOG,
+ *	7) MGMT_EVENT_LOG
+ *
+ * @OUTPUT: None
+ *
+ * @E.g:
+ * # print up to 10 of the most recent records from HTC Credit History
+ *	iwpriv wlan0 log_buffer 0 10
+ * # print up to 3 of the most recent records from Event Log
+ *	iwpriv wlan0 log_buffer 5 3
+ *
+ * Supported Feature: WLAN Trace
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WE_LOG_BUFFER			8
+
+/*
+ * <ioctl>
+ * set_ba_timeout - sets Block ACK aging timeout value for each Access class
+ *
+ * @INPUT: Access Class [0:BK, 1:BE, 2:VI, 3:VO], Timeout value
+ *
+ * @OUTPUT: None
+ *
+ * @E.g.:
+ * # to set duration of 2 seconds for BE
+ *	iwpriv wlan0 set_ba_timeout 1 2
+ * # to set duration of 3 seconds for VO
+ *	iwpriv wlan0 set_ba_timeout 3 3
+ *
+ * Usage: Internal
+ *
+ * </ioctl>
+ */
+#define WE_SET_BA_AGEING_TIMEOUT		9
+
+enum host_target_comm_log {
+	HTC_CREDIT_HISTORY_LOG = 0,
+	COMMAND_LOG,
+	COMMAND_TX_CMP_LOG,
+	MGMT_COMMAND_LOG,
+	MGMT_COMMAND_TX_CMP_LOG,
+	EVENT_LOG,
+	RX_EVENT_LOG,
+	MGMT_EVENT_LOG
+};
+
+/* (SIOCIWFIRSTPRIV + 29) is currently unused */
+
+/* 802.11p IOCTL */
+#define WLAN_SET_DOT11P_CHANNEL_SCHED    (SIOCIWFIRSTPRIV + 30)
+
+/*
+ * <ioctl>
+ * getLinkSpeed - Gets the current link speed in Mbps
+ *
+ * @INPUT: None
+ *
+ * @OUTPUT: linkspeed in mbps
+ *  wlan0     getLinkSpeed:7
+ *
+ * This IOCTL is used get the current link speed in Mbps
+ *
+ * @E.g: iwpriv wlan0 getLinkSpeed
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal/External
+ *
+ * </ioctl>
+ */
+#define WLAN_GET_LINK_SPEED          (SIOCIWFIRSTPRIV + 31)
+
+#define WLAN_STATS_INVALID            0
+#define WLAN_STATS_RETRY_CNT          1
+#define WLAN_STATS_MUL_RETRY_CNT      2
+#define WLAN_STATS_TX_FRM_CNT         3
+#define WLAN_STATS_RX_FRM_CNT         4
+#define WLAN_STATS_FRM_DUP_CNT        5
+#define WLAN_STATS_FAIL_CNT           6
+#define WLAN_STATS_RTS_FAIL_CNT       7
+#define WLAN_STATS_ACK_FAIL_CNT       8
+#define WLAN_STATS_RTS_SUC_CNT        9
+#define WLAN_STATS_RX_DISCARD_CNT     10
+#define WLAN_STATS_RX_ERROR_CNT       11
+#define WLAN_STATS_TX_BYTE_CNT        12
+
+#define WLAN_STATS_RX_BYTE_CNT        13
+#define WLAN_STATS_RX_RATE            14
+#define WLAN_STATS_TX_RATE            15
+
+#define WLAN_STATS_RX_UC_BYTE_CNT     16
+#define WLAN_STATS_RX_MC_BYTE_CNT     17
+#define WLAN_STATS_RX_BC_BYTE_CNT     18
+#define WLAN_STATS_TX_UC_BYTE_CNT     19
+#define WLAN_STATS_TX_MC_BYTE_CNT     20
+#define WLAN_STATS_TX_BC_BYTE_CNT     21
+
+#define FILL_TLV(__p, __type, __size, __val, __tlen) do {		\
+		if ((__tlen + __size + 2) < WE_MAX_STR_LEN) {		\
+			*__p++ = __type;				\
+			*__p++ = __size;				\
+			memcpy(__p, __val, __size);			\
+			__p += __size;					\
+			__tlen += __size + 2;				\
+		} else {						\
+			hdd_err("FILL_TLV Failed!!!");  \
+		}							\
+	} while (0)
+
+#define VERSION_VALUE_MAX_LEN 32
+
+#define TX_PER_TRACKING_DEFAULT_RATIO             5
+#define TX_PER_TRACKING_MAX_RATIO                10
+#define TX_PER_TRACKING_DEFAULT_WATERMARK         5
+
+#define WLAN_ADAPTER 0
+#define P2P_ADAPTER  1
+
+/**
+ * mem_alloc_copy_from_user_helper - copy from user helper
+ * @wrqu_data: wireless extensions request data
+ * @len: length of @wrqu_data
+ *
+ * Helper function to allocate buffer and copy user data.
+ *
+ * Return: On success return a pointer to a kernel buffer containing a
+ * copy of the userspace data (with an additional NUL character
+ * appended for safety). On failure return %NULL.
+ */
+void *mem_alloc_copy_from_user_helper(const __user void *wrqu_data, size_t len)
+{
+	u8 *ptr = NULL;
+
+	/* in order to protect the code, an extra byte is post
+	 * appended to the buffer and the null termination is added.
+	 * However, when allocating (len+1) byte of memory, we need to
+	 * make sure that there is no uint overflow when doing
+	 * addition. In theory check len < UINT_MAX protects the uint
+	 * overflow. For wlan private ioctl, the buffer size is much
+	 * less than UINT_MAX, as a good guess, now, it is assumed
+	 * that the private command buffer size is no greater than 4K
+	 * (4096 bytes). So we use 4096 as the upper boundary for now.
+	 */
+	if (len > MAX_USER_COMMAND_SIZE) {
+		hdd_err("Invalid length: %zu max: %u",
+			 len, MAX_USER_COMMAND_SIZE);
+		return NULL;
+	}
+
+	ptr = qdf_mem_malloc(len + 1);
+	if (NULL == ptr) {
+		hdd_err("unable to allocate memory");
+		return NULL;
+	}
+
+	if (copy_from_user(ptr, wrqu_data, len)) {
+		hdd_err("failed to copy data to user buffer");
+		qdf_mem_free(ptr);
+		return NULL;
+	}
+	ptr[len] = '\0';
+	return ptr;
+}
+
+/**
+ * hdd_priv_get_data() - Get pointer to ioctl private data
+ * @p_priv_data: pointer to iw_point struct to be filled
+ * @wrqu: Pointer to IOCTL Data received from userspace
+ *
+ * Helper function to get compatible struct iw_point passed to ioctl
+ *
+ * Return - 0 if p_priv_data successfully filled, error otherwise
+ */
+int hdd_priv_get_data(struct iw_point *p_priv_data, union iwreq_data *wrqu)
+{
+	if ((NULL == p_priv_data) || (NULL == wrqu))
+		return -EINVAL;
+
+#ifdef CONFIG_COMPAT
+	if (in_compat_syscall()) {
+		struct compat_iw_point *p_compat_priv_data;
+
+		/* Compat task:
+		 * typecast to compat structure and copy the members.
+		 */
+		p_compat_priv_data = (struct compat_iw_point *)&wrqu->data;
+
+		p_priv_data->pointer = compat_ptr(p_compat_priv_data->pointer);
+		p_priv_data->length = p_compat_priv_data->length;
+		p_priv_data->flags = p_compat_priv_data->flags;
+	} else {
+#endif /* #ifdef CONFIG_COMPAT */
+
+		/* Non compat task: directly copy the structure. */
+		memcpy(p_priv_data, &wrqu->data, sizeof(struct iw_point));
+
+#ifdef CONFIG_COMPAT
+	}
+#endif /* #ifdef CONFIG_COMPAT */
+
+	return 0;
+}
+
+static int hdd_check_wext_control(enum hdd_wext_control wext_control,
+				  struct iw_request_info *info)
+{
+	switch (wext_control) {
+	default:
+	case hdd_wext_disabled:
+		hdd_err_rl("Rejecting disabled ioctl %x", info->cmd);
+		return -ENOTSUPP;
+	case hdd_wext_deprecated:
+		hdd_warn_rl("Using deprecated ioctl %x", info->cmd);
+		return 0;
+	case hdd_wext_enabled:
+		return 0;
+	}
+}
+
+int hdd_check_private_wext_control(struct hdd_context *hdd_ctx,
+				   struct iw_request_info *info)
+{
+	return hdd_check_wext_control(hdd_ctx->config->private_wext_control,
+				      info);
+}
+
+/**
+ * hdd_wlan_get_stats() - Get txrx stats in SAP mode
+ * @adapter: Pointer to the hdd adapter.
+ * @length:   Size of the data copied
+ * @buffer:   Pointer to char buffer.
+ * @buf_len:  Length of the char buffer.
+ *
+ * This function called when the "iwpriv wlan0 get_stats" command is given.
+ * It used to collect the txrx stats when the device is configured in SAP mode.
+ *
+ * Return - none
+ */
+void hdd_wlan_get_stats(struct hdd_adapter *adapter, uint16_t *length,
+			char *buffer, uint16_t buf_len)
+{
+	struct hdd_tx_rx_stats *stats = &adapter->hdd_stats.tx_rx_stats;
+	uint32_t len = 0;
+	uint32_t total_rx_pkt = 0, total_rx_dropped = 0;
+	uint32_t total_rx_delv = 0, total_rx_refused = 0;
+	int i = 0;
+
+	for (; i < NUM_CPUS; i++) {
+		total_rx_pkt += stats->rx_packets[i];
+		total_rx_dropped += stats->rx_dropped[i];
+		total_rx_delv += stats->rx_delivered[i];
+		total_rx_refused += stats->rx_refused[i];
+	}
+
+	len = scnprintf(buffer, buf_len,
+		"\nTransmit[%lu] - "
+		"called %u, dropped %u orphan %u,"
+		"\n[dropped]    BK %u, BE %u, VI %u, VO %u"
+		"\n[classified] BK %u, BE %u, VI %u, VO %u"
+		"\n\nReceive[%lu] - "
+		"packets %u, dropped %u, delivered %u, refused %u"
+		"\n",
+		qdf_system_ticks(),
+		stats->tx_called,
+		stats->tx_dropped,
+		stats->tx_orphaned,
+
+		stats->tx_dropped_ac[SME_AC_BK],
+		stats->tx_dropped_ac[SME_AC_BE],
+		stats->tx_dropped_ac[SME_AC_VI],
+		stats->tx_dropped_ac[SME_AC_VO],
+
+		stats->tx_classified_ac[SME_AC_BK],
+		stats->tx_classified_ac[SME_AC_BE],
+		stats->tx_classified_ac[SME_AC_VI],
+		stats->tx_classified_ac[SME_AC_VO],
+		qdf_system_ticks(),
+		total_rx_pkt, total_rx_dropped, total_rx_delv, total_rx_refused
+		);
+
+	for (i = 0; i < NUM_CPUS; i++) {
+		if (stats->rx_packets[i] == 0)
+			continue;
+		len += scnprintf(buffer + len, buf_len - len,
+			"Rx CPU[%d]:"
+			"packets %u, dropped %u, delivered %u, refused %u\n",
+			i, stats->rx_packets[i], stats->rx_dropped[i],
+			stats->rx_delivered[i], stats->rx_refused[i]);
+	}
+
+	len += scnprintf(buffer + len, buf_len - len,
+		"\nTX_FLOW"
+		"\nCurrent status: %s"
+		"\ntx-flow timer start count %u"
+		"\npause count %u, unpause count %u",
+		(stats->is_txflow_paused == true ? "PAUSED" : "UNPAUSED"),
+		stats->txflow_timer_cnt,
+		stats->txflow_pause_cnt,
+		stats->txflow_unpause_cnt);
+
+	len += cdp_stats(cds_get_context(QDF_MODULE_ID_SOC),
+		adapter->session_id, &buffer[len], (buf_len - len));
+	*length = len + 1;
+}
+
+/**
+ * wlan_hdd_write_suspend_resume_stats() - Writes suspend/resume stats to buffer
+ * @hdd_ctx: The Hdd context owning the stats to be written
+ * @buffer: The char buffer to write to
+ * @max_len: The maximum number of chars to write
+ *
+ * This assumes hdd_ctx has already been validated, and buffer is not NULL.
+ *
+ * Return - length of written content, negative number on error
+ */
+#ifdef QCA_SUPPORT_CP_STATS
+static int wlan_hdd_write_suspend_resume_stats(struct hdd_context *hdd_ctx,
+					       char *buffer, uint16_t max_len)
+{
+	int ret;
+	QDF_STATUS status;
+	struct suspend_resume_stats *sr_stats;
+
+	sr_stats = &hdd_ctx->suspend_resume_stats;
+	ret = scnprintf(buffer, max_len,
+			"\n"
+			"Suspends: %u\n"
+			"Resumes: %u\n"
+			"\n"
+			"Suspend Fail Reasons\n"
+			"\tIPA: %u\n"
+			"\tRadar: %u\n"
+			"\tRoam: %u\n"
+			"\tScan: %u\n"
+			"\tInitial Wakeup: %u\n"
+			"\n",
+			sr_stats->suspends, sr_stats->resumes,
+			sr_stats->suspend_fail[SUSPEND_FAIL_IPA],
+			sr_stats->suspend_fail[SUSPEND_FAIL_RADAR],
+			sr_stats->suspend_fail[SUSPEND_FAIL_ROAM],
+			sr_stats->suspend_fail[SUSPEND_FAIL_SCAN],
+			sr_stats->suspend_fail[SUSPEND_FAIL_INITIAL_WAKEUP]);
+
+	status = ucfg_mc_cp_stats_write_wow_stats(hdd_ctx->psoc,
+						  &buffer[ret], max_len - ret,
+						  &ret);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get WoW stats");
+		return qdf_status_to_os_return(status);
+	}
+
+	return ret;
+}
+#else
+static int wlan_hdd_write_suspend_resume_stats(struct hdd_context *hdd_ctx,
+					       char *buffer, uint16_t max_len)
+{
+	QDF_STATUS status;
+	struct suspend_resume_stats *sr_stats;
+	struct sir_wake_lock_stats wow_stats;
+
+	sr_stats = &hdd_ctx->suspend_resume_stats;
+
+	status = wma_get_wakelock_stats(&wow_stats);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get WoW stats");
+		return qdf_status_to_os_return(status);
+	}
+
+	return scnprintf(buffer, max_len,
+			"\n"
+			"Suspends: %u\n"
+			"Resumes: %u\n"
+			"\n"
+			"Suspend Fail Reasons\n"
+			"\tIPA: %u\n"
+			"\tRadar: %u\n"
+			"\tRoam: %u\n"
+			"\tScan: %u\n"
+			"\tInitial Wakeup: %u\n"
+			"\n"
+			"WoW Wake Reasons\n"
+			"\tunicast: %u\n"
+			"\tbroadcast: %u\n"
+			"\tIPv4 multicast: %u\n"
+			"\tIPv6 multicast: %u\n"
+			"\tIPv6 multicast RA: %u\n"
+			"\tIPv6 multicast NS: %u\n"
+			"\tIPv6 multicast NA: %u\n"
+			"\tICMPv4: %u\n"
+			"\tICMPv6: %u\n"
+			"\tRSSI Breach: %u\n"
+			"\tLow RSSI: %u\n"
+			"\tG-Scan: %u\n"
+			"\tPNO Complete: %u\n"
+			"\tPNO Match: %u\n",
+			sr_stats->suspends,
+			sr_stats->resumes,
+			sr_stats->suspend_fail[SUSPEND_FAIL_IPA],
+			sr_stats->suspend_fail[SUSPEND_FAIL_RADAR],
+			sr_stats->suspend_fail[SUSPEND_FAIL_ROAM],
+			sr_stats->suspend_fail[SUSPEND_FAIL_SCAN],
+			sr_stats->suspend_fail[SUSPEND_FAIL_INITIAL_WAKEUP],
+			wow_stats.wow_ucast_wake_up_count,
+			wow_stats.wow_bcast_wake_up_count,
+			wow_stats.wow_ipv4_mcast_wake_up_count,
+			wow_stats.wow_ipv6_mcast_wake_up_count,
+			wow_stats.wow_ipv6_mcast_ra_stats,
+			wow_stats.wow_ipv6_mcast_ns_stats,
+			wow_stats.wow_ipv6_mcast_na_stats,
+			wow_stats.wow_icmpv4_count,
+			wow_stats.wow_icmpv6_count,
+			wow_stats.wow_rssi_breach_wake_up_count,
+			wow_stats.wow_low_rssi_wake_up_count,
+			wow_stats.wow_gscan_wake_up_count,
+			wow_stats.wow_pno_complete_wake_up_count,
+			wow_stats.wow_pno_match_wake_up_count);
+}
+#endif
+/**
+ * hdd_wlan_list_fw_profile() - Get fw profiling points
+ * @length:   Size of the data copied
+ * @buffer:   Pointer to char buffer.
+ * @buf_len:  Length of the char buffer.
+ *
+ * This function called when the "iwpriv wlan0 listProfile" command is given.
+ * It is used to get the supported profiling points in FW.
+ *
+ * Return - none
+ */
+void hdd_wlan_list_fw_profile(uint16_t *length,
+			char *buffer, uint16_t buf_len)
+{
+	uint32_t len = 0;
+
+	len = scnprintf(buffer, buf_len,
+		    "PROF_CPU_IDLE: %u\n"
+		    "PROF_PPDU_PROC: %u\n"
+		    "PROF_PPDU_POST: %u\n"
+		    "PROF_HTT_TX_INPUT: %u\n"
+		    "PROF_MSDU_ENQ: %u\n"
+		    "PROF_PPDU_POST_HAL: %u\n"
+		    "PROF_COMPUTE_TX_TIME: %u\n",
+		    PROF_CPU_IDLE,
+		    PROF_PPDU_PROC,
+		    PROF_PPDU_POST,
+		    PROF_HTT_TX_INPUT,
+		    PROF_MSDU_ENQ,
+		    PROF_PPDU_POST_HAL,
+		    PROF_COMPUTE_TX_TIME);
+
+	*length = len + 1;
+}
+/**
+ * hdd_display_stats_help() - print statistics help
+ *
+ * Return: none
+ */
+static void hdd_display_stats_help(void)
+{
+	hdd_nofl_info("iwpriv wlan0 dumpStats [option] - dump statistics");
+	hdd_nofl_info("iwpriv wlan0 clearStats [option] - clear statistics");
+	hdd_nofl_info("options:");
+	hdd_nofl_info("  1 -- TXRX PATH statistics");
+	hdd_nofl_info("  2 -- TXRX HIST statistics");
+	hdd_nofl_info("  3 -- TSO statistics");
+	hdd_nofl_info("  4 -- Network queue statistics");
+	hdd_nofl_info("  5 -- Flow control statistics");
+	hdd_nofl_info("  6 -- Per Layer statistics");
+	hdd_nofl_info("  7 -- Copy engine interrupt statistics");
+	hdd_nofl_info("  9 -- NAPI statistics");
+}
+
+/**
+ * hdd_wlan_dump_stats() - display dump Stats
+ * @adapter: adapter handle
+ * @value: value from user
+ *
+ * Return: 0 => success, error code on failure
+ */
+int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int value)
+{
+	int ret = 0;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	switch (value) {
+	case CDP_TXRX_HIST_STATS:
+		wlan_hdd_display_tx_rx_histogram(hdd_ctx);
+		break;
+
+	case CDP_HDD_NETIF_OPER_HISTORY:
+		wlan_hdd_display_netif_queue_history
+					(hdd_ctx,
+					 QDF_STATS_VERBOSITY_LEVEL_HIGH);
+		break;
+
+	case CDP_HIF_STATS:
+		hdd_display_hif_stats();
+		break;
+
+	case CDP_LRO_STATS:
+		hdd_lro_display_stats(hdd_ctx);
+		break;
+
+	case CDP_NAPI_STATS:
+		if (hdd_display_napi_stats()) {
+			hdd_err("error displaying napi stats");
+			ret = EFAULT;
+		}
+		break;
+
+	case CDP_DISCONNECT_STATS:
+		sme_display_disconnect_stats(hdd_ctx->mac_handle,
+					     adapter->session_id);
+		break;
+
+	default:
+		status = cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
+					   value,
+					   QDF_STATS_VERBOSITY_LEVEL_HIGH);
+		if (status == QDF_STATUS_E_INVAL) {
+			hdd_display_stats_help();
+			ret = EINVAL;
+		}
+		break;
+	}
+	return ret;
+}
+
+/**
+ * hdd_wlan_get_ibss_peer_info() - Print IBSS peer information
+ * @adapter: Adapter upon which the IBSS client is active
+ * @staIdx: Station index of the IBSS peer
+ *
+ * Return: QDF_STATUS_STATUS if the peer was found and displayed,
+ * otherwise an appropriate QDF_STATUS_E_* failure code.
+ */
+static QDF_STATUS hdd_wlan_get_ibss_peer_info(struct hdd_adapter *adapter,
+					      uint8_t staIdx)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+	struct hdd_station_ctx *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	tSirPeerInfoRspParams *pPeerInfo = &pStaCtx->ibss_peer_info;
+
+	INIT_COMPLETION(adapter->ibss_peer_info_comp);
+	status = sme_request_ibss_peer_info(mac_handle, adapter,
+					    hdd_get_ibss_peer_info_cb,
+					    false, staIdx);
+
+	if (QDF_STATUS_SUCCESS == status) {
+		unsigned long rc;
+
+		rc = wait_for_completion_timeout
+			     (&adapter->ibss_peer_info_comp,
+			     msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
+		if (!rc) {
+			hdd_err("failed wait on ibss_peer_info_comp");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		/** Print the peer info */
+		hdd_debug("pPeerInfo->numIBSSPeers = %d ", pPeerInfo->numPeers);
+		{
+			uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
+			uint32_t tx_rate = pPeerInfo->peerInfoParams[0].txRate;
+
+			qdf_mem_copy(mac_addr, pPeerInfo->peerInfoParams[0].
+					mac_addr, sizeof(mac_addr));
+			hdd_debug("PEER ADDR : %pM TxRate: %d Mbps  RSSI: %d",
+				mac_addr, (int)tx_rate,
+				(int)pPeerInfo->peerInfoParams[0].rssi);
+		}
+	} else {
+		hdd_warn("Warning: sme_request_ibss_peer_info Request failed");
+	}
+
+	return status;
+}
+
+/**
+ * hdd_wlan_get_ibss_peer_info_all() - Print all IBSS peers
+ * @adapter: Adapter upon which the IBSS clients are active
+ *
+ * Return: QDF_STATUS_STATUS if the peer information was retrieved and
+ * displayed, otherwise an appropriate QDF_STATUS_E_* failure code.
+ */
+static QDF_STATUS hdd_wlan_get_ibss_peer_info_all(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+	struct hdd_station_ctx *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	tSirPeerInfoRspParams *pPeerInfo = &pStaCtx->ibss_peer_info;
+	int i;
+
+	INIT_COMPLETION(adapter->ibss_peer_info_comp);
+	status = sme_request_ibss_peer_info(mac_handle, adapter,
+					    hdd_get_ibss_peer_info_cb,
+					    true, 0xFF);
+
+	if (QDF_STATUS_SUCCESS == status) {
+		unsigned long rc;
+
+		rc = wait_for_completion_timeout
+			     (&adapter->ibss_peer_info_comp,
+			     msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
+		if (!rc) {
+			hdd_err("failed wait on ibss_peer_info_comp");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		/** Print the peer info */
+		hdd_debug("pPeerInfo->numIBSSPeers = %d ",
+			(int)pPeerInfo->numPeers);
+		for (i = 0; i < pPeerInfo->numPeers; i++) {
+			uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
+			uint32_t tx_rate;
+
+			tx_rate = pPeerInfo->peerInfoParams[i].txRate;
+			qdf_mem_copy(mac_addr,
+				pPeerInfo->peerInfoParams[i].mac_addr,
+				sizeof(mac_addr));
+
+			hdd_debug(" PEER ADDR : %pM TxRate: %d Mbps RSSI: %d",
+				mac_addr, (int)tx_rate,
+				(int)pPeerInfo->peerInfoParams[i].rssi);
+		}
+	} else {
+		hdd_warn("Warning: sme_request_ibss_peer_info Request failed");
+	}
+
+	return status;
+}
+
+/**
+ * hdd_get_ldpc() - Get adapter LDPC
+ * @adapter: adapter being queried
+ * @value: where to store the value
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int hdd_get_ldpc(struct hdd_adapter *adapter, int *value)
+{
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+	int ret;
+
+	hdd_enter();
+	ret = sme_get_ht_config(mac_handle, adapter->session_id,
+				WNI_CFG_HT_CAP_INFO_ADVANCE_CODING);
+	if (ret < 0) {
+		hdd_err("Failed to get LDPC value");
+	} else {
+		*value = ret;
+		ret = 0;
+	}
+	return ret;
+}
+
+int hdd_set_ldpc(struct hdd_adapter *adapter, int value)
+{
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+	int ret;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_config *config = hdd_ctx->config;
+	struct mlme_ht_capabilities_info ht_cap_info;
+
+	hdd_debug("%d", value);
+
+	if (!mac_handle) {
+		hdd_err("NULL Mac handle");
+		return -EINVAL;
+	}
+
+	if (value) {
+		/* make sure HT capabilities allow this */
+		if (!config->enable_rx_ldpc) {
+			hdd_err("LDCP not supported");
+			return -EINVAL;
+		}
+	} else if (!config->enable_rx_ldpc) {
+		hdd_err("LDCP is already disabled");
+		return 0;
+	}
+	status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Failed to get HT capability info");
+		return -EIO;
+	}
+
+	ht_cap_info.adv_coding_cap = value;
+	status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Failed to set HT capability info");
+		return -EIO;
+	}
+	status =
+		ucfg_mlme_cfg_set_vht_ldpc_coding_cap(hdd_ctx->psoc, value);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to set VHT LDPC capability info");
+		return -EIO;
+	}
+	ret = sme_update_ht_config(mac_handle, adapter->session_id,
+				   WNI_CFG_HT_CAP_INFO_ADVANCE_CODING,
+				   value);
+	if (ret)
+		hdd_err("Failed to set LDPC value");
+	ret = sme_update_he_ldpc_supp(mac_handle, adapter->session_id, value);
+	if (ret)
+		hdd_err("Failed to set HE LDPC value");
+
+	return ret;
+}
+
+/**
+ * hdd_get_tx_stbc() - Get adapter TX STBC
+ * @adapter: adapter being queried
+ * @value: where to store the value
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int hdd_get_tx_stbc(struct hdd_adapter *adapter, int *value)
+{
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+	int ret;
+
+	hdd_enter();
+	ret = sme_get_ht_config(mac_handle, adapter->session_id,
+				WNI_CFG_HT_CAP_INFO_TX_STBC);
+	if (ret < 0) {
+		hdd_err("Failed to get TX STBC value");
+	} else {
+		*value = ret;
+		ret = 0;
+	}
+
+	return ret;
+}
+
+int hdd_set_tx_stbc(struct hdd_adapter *adapter, int value)
+{
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int ret;
+	QDF_STATUS status;
+	struct mlme_ht_capabilities_info ht_cap_info;
+
+	hdd_debug("%d", value);
+
+	if (!mac_handle) {
+		hdd_err("NULL Mac handle");
+		return -EINVAL;
+	}
+
+	if (value) {
+		/* make sure HT capabilities allow this */
+		status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc,
+						   &ht_cap_info);
+		if (QDF_STATUS_SUCCESS != status) {
+			hdd_err("Failed to get HT capability info");
+			return -EIO;
+		}
+		if (!ht_cap_info.tx_stbc) {
+			hdd_err("TX STBC not supported");
+			return -EINVAL;
+		}
+	}
+	ret = sme_update_ht_config(mac_handle, adapter->session_id,
+				   WNI_CFG_HT_CAP_INFO_TX_STBC,
+				   value);
+	if (ret)
+		hdd_err("Failed to set TX STBC value");
+	ret = sme_update_he_tx_stbc_cap(mac_handle, adapter->session_id, value);
+	if (ret)
+		hdd_err("Failed to set HE TX STBC value");
+
+	return ret;
+}
+
+/**
+ * hdd_get_rx_stbc() - Get adapter RX STBC
+ * @adapter: adapter being queried
+ * @value: where to store the value
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int hdd_get_rx_stbc(struct hdd_adapter *adapter, int *value)
+{
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+	int ret;
+
+	hdd_enter();
+	ret = sme_get_ht_config(mac_handle, adapter->session_id,
+				WNI_CFG_HT_CAP_INFO_RX_STBC);
+	if (ret < 0) {
+		hdd_err("Failed to get RX STBC value");
+	} else {
+		*value = ret;
+		ret = 0;
+	}
+
+	return ret;
+}
+
+int hdd_set_rx_stbc(struct hdd_adapter *adapter, int value)
+{
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int ret;
+	QDF_STATUS status;
+	struct mlme_ht_capabilities_info ht_cap_info;
+
+	hdd_debug("%d", value);
+
+	if (!mac_handle) {
+		hdd_err("NULL Mac handle");
+		return -EINVAL;
+	}
+
+	if (value) {
+		/* make sure HT capabilities allow this */
+		status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc,
+						   &ht_cap_info);
+		if (QDF_STATUS_SUCCESS != status) {
+			hdd_err("Failed to get HT capability info");
+			return -EIO;
+		}
+		if (!ht_cap_info.rx_stbc) {
+			hdd_warn("RX STBC not supported");
+			return -EINVAL;
+		}
+	}
+	ret = sme_update_ht_config(mac_handle, adapter->session_id,
+				   WNI_CFG_HT_CAP_INFO_RX_STBC,
+				   value);
+	if (ret)
+		hdd_err("Failed to set RX STBC value");
+
+	ret = sme_update_he_rx_stbc_cap(mac_handle, adapter->session_id, value);
+	if (ret)
+		hdd_err("Failed to set HE RX STBC value");
+
+	return ret;
+}
+
+/**
+ * iw_get_linkspeed() - Get current link speed ioctl
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: extra ioctl buffer
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_get_linkspeed(struct net_device *dev,
+			      struct iw_request_info *info,
+			      union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	char *pLinkSpeed = (char *)extra;
+	int len = sizeof(uint32_t) + 1;
+	uint32_t link_speed = 0;
+	struct hdd_context *hdd_ctx;
+	int ret;
+	int rc;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	ret = wlan_hdd_get_link_speed(adapter, &link_speed);
+	if (0 != ret)
+		return ret;
+
+	wrqu->data.length = len;
+	/* return the linkspeed as a string */
+	rc = snprintf(pLinkSpeed, len, "%u", link_speed);
+	if ((rc < 0) || (rc >= len)) {
+		/* encoding or length error? */
+		hdd_err("Unable to encode link speed");
+		return -EIO;
+	}
+
+	hdd_exit();
+	/* a value is being successfully returned */
+	return 0;
+}
+
+static int iw_get_linkspeed(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_get_linkspeed(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+int wlan_hdd_update_phymode(struct hdd_adapter *adapter, int new_phymode)
+{
+	struct net_device *net = adapter->dev;
+	struct hdd_context *phddctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle = phddctx->mac_handle;
+	bool band_24 = false, band_5g = false;
+	bool ch_bond24 = false, ch_bond5g = false;
+	tSmeConfigParams *sme_config;
+	uint32_t chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+	uint8_t vhtchanwidth;
+	eCsrPhyMode phymode = -EIO, old_phymode;
+	enum hdd_dot11_mode hdd_dot11mode = phddctx->config->dot11Mode;
+	enum band_info curr_band = BAND_ALL;
+	int retval = 0;
+	uint8_t band_capability;
+	QDF_STATUS status;
+
+	if (!mac_handle)
+		return -EINVAL;
+
+	old_phymode = sme_get_phy_mode(mac_handle);
+
+	if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
+	    sme_get_cb_phy_state_from_cb_ini_value(phddctx->config->
+						   nChannelBondingMode24GHz))
+		ch_bond24 = true;
+
+	if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
+	    sme_get_cb_phy_state_from_cb_ini_value(phddctx->config->
+						   nChannelBondingMode5GHz))
+		ch_bond5g = true;
+
+	status = wlan_mlme_get_band_capability(phddctx->psoc, &band_capability);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get MLME Band capability");
+		return -EIO;
+	}
+
+	if (band_capability == BAND_ALL)
+		band_24 = band_5g = true;
+	else if (band_capability == BAND_2G)
+		band_24 = true;
+	else if (band_capability == BAND_5G)
+		band_5g = true;
+
+	status = ucfg_mlme_get_vht_channel_width(phddctx->psoc, &vhtchanwidth);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("Failed to get channel_width");
+
+	hdd_debug("ch_bond24=%d ch_bond5g=%d band_24=%d band_5g=%d VHT_ch_width=%u",
+		ch_bond24, ch_bond5g, band_24, band_5g, vhtchanwidth);
+
+	switch (new_phymode) {
+	case IEEE80211_MODE_AUTO:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_AUTO);
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0) {
+			phymode = eCSR_DOT11_MODE_AUTO;
+			hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
+			chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
+			curr_band = BAND_ALL;
+			vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	case IEEE80211_MODE_11A:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11a);
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0) {
+			phymode = eCSR_DOT11_MODE_11a;
+			hdd_dot11mode = eHDD_DOT11_MODE_11a;
+			chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+			curr_band = BAND_5G;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	case IEEE80211_MODE_11B:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11b);
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0) {
+			phymode = eCSR_DOT11_MODE_11b;
+			hdd_dot11mode = eHDD_DOT11_MODE_11b;
+			chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+			curr_band = BAND_2G;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	case IEEE80211_MODE_11G:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11g);
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0) {
+			phymode = eCSR_DOT11_MODE_11g;
+			hdd_dot11mode = eHDD_DOT11_MODE_11g;
+			chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+			curr_band = BAND_2G;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	/* UMAC doesn't have option to set MODE_11NA/MODE_11NG as phymode
+	 * so setting phymode as eCSR_DOT11_MODE_11n and updating the band
+	 * and channel bonding in configuration to reflect MODE_11NA/MODE_11NG
+	 */
+	case IEEE80211_MODE_11NA_HT20:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11n);
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0) {
+			phymode = eCSR_DOT11_MODE_11n;
+			hdd_dot11mode = eHDD_DOT11_MODE_11n;
+			chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+			curr_band = BAND_5G;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	case IEEE80211_MODE_11NA_HT40:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11n);
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0) {
+			phymode = eCSR_DOT11_MODE_11n;
+			hdd_dot11mode = eHDD_DOT11_MODE_11n;
+			chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
+			curr_band = BAND_5G;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	case IEEE80211_MODE_11NG_HT20:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11n);
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0) {
+			phymode = eCSR_DOT11_MODE_11n;
+			hdd_dot11mode = eHDD_DOT11_MODE_11n;
+			chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+			curr_band = BAND_2G;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	case IEEE80211_MODE_11NG_HT40:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11n);
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0) {
+			phymode = eCSR_DOT11_MODE_11n;
+			hdd_dot11mode = eHDD_DOT11_MODE_11n;
+			chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
+			curr_band = BAND_2G;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	case IEEE80211_MODE_11AC_VHT20:
+	case IEEE80211_MODE_11AC_VHT40:
+	case IEEE80211_MODE_11AC_VHT80:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11ac);
+		phymode = eCSR_DOT11_MODE_11ac;
+		hdd_dot11mode = eHDD_DOT11_MODE_11ac;
+		chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
+		if (band_5g && band_24) {
+			curr_band = BAND_ALL;
+			break;
+		} else if (band_5g) {
+			curr_band = BAND_5G;
+			break;
+		} else if (new_phymode != IEEE80211_MODE_11AC_VHT80) {
+			curr_band = BAND_2G;
+			break;
+		}
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0) {
+			curr_band = BAND_ALL;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	case IEEE80211_MODE_2G_AUTO:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_AUTO);
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0) {
+			phymode = eCSR_DOT11_MODE_AUTO;
+			hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
+			chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
+			curr_band = BAND_2G;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	case IEEE80211_MODE_5G_AUTO:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_AUTO);
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0) {
+			phymode = eCSR_DOT11_MODE_AUTO;
+			hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
+			chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
+			vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
+			curr_band = BAND_5G;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	case IEEE80211_MODE_11AGN:
+		sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11n);
+		if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0) {
+			phymode = eCSR_DOT11_MODE_11n;
+			hdd_dot11mode = eHDD_DOT11_MODE_11n;
+			chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
+			curr_band = BAND_ALL;
+		} else {
+			sme_set_phy_mode(mac_handle, old_phymode);
+			return -EIO;
+		}
+		break;
+	default:
+		return -EIO;
+	}
+
+	switch (new_phymode) {
+	case IEEE80211_MODE_11AC_VHT20:
+		chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+		vhtchanwidth = eHT_CHANNEL_WIDTH_20MHZ;
+		break;
+	case IEEE80211_MODE_11AC_VHT40:
+		vhtchanwidth = eHT_CHANNEL_WIDTH_40MHZ;
+		break;
+	case IEEE80211_MODE_11AC_VHT80:
+		vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
+		break;
+	default:
+		status = ucfg_mlme_get_vht_channel_width(phddctx->psoc,
+							 &vhtchanwidth);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("Failed to get channel_width");
+		break;
+	}
+
+	if (phymode != -EIO) {
+		sme_config = qdf_mem_malloc(sizeof(*sme_config));
+		if (!sme_config) {
+			hdd_err("Failed to allocate memory for sme_config");
+			return -ENOMEM;
+		}
+		qdf_mem_zero(sme_config, sizeof(*sme_config));
+		sme_get_config_param(mac_handle, sme_config);
+		sme_config->csrConfig.phyMode = phymode;
+#ifdef QCA_HT_2040_COEX
+		if (phymode == eCSR_DOT11_MODE_11n &&
+		    chwidth == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) {
+			sme_config->csrConfig.obssEnabled = false;
+			status = sme_set_ht2040_mode(mac_handle,
+						     adapter->session_id,
+						     eHT_CHAN_HT20, false);
+			if (status == QDF_STATUS_E_FAILURE) {
+				hdd_err("Failed to disable OBSS");
+				retval = -EIO;
+				goto free;
+			}
+		} else if (phymode == eCSR_DOT11_MODE_11n &&
+			   chwidth == WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) {
+			sme_config->csrConfig.obssEnabled = true;
+			status = sme_set_ht2040_mode(mac_handle,
+						     adapter->session_id,
+						     eHT_CHAN_HT20, true);
+			if (status == QDF_STATUS_E_FAILURE) {
+				hdd_err("Failed to enable OBSS");
+				retval = -EIO;
+				goto free;
+			}
+		}
+#endif
+		status = ucfg_mlme_set_band_capability(phddctx->psoc,
+						       curr_band);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("failed to set MLME band capability");
+			goto free;
+		}
+
+		if (curr_band == BAND_2G)
+			sme_config->csrConfig.Is11hSupportEnabled = 0;
+		else
+			sme_config->csrConfig.Is11hSupportEnabled =
+				phddctx->config->Is11hSupportEnabled;
+		if (curr_band == BAND_2G)
+			sme_config->csrConfig.channelBondingMode24GHz = chwidth;
+		else if (curr_band == BAND_5G)
+			sme_config->csrConfig.channelBondingMode5GHz = chwidth;
+		else {
+			sme_config->csrConfig.channelBondingMode24GHz = chwidth;
+			sme_config->csrConfig.channelBondingMode5GHz = chwidth;
+		}
+		sme_update_config(mac_handle, sme_config);
+
+		phddctx->config->dot11Mode = hdd_dot11mode;
+		phddctx->config->nChannelBondingMode24GHz =
+			sme_config->csrConfig.channelBondingMode24GHz;
+		phddctx->config->nChannelBondingMode5GHz =
+			sme_config->csrConfig.channelBondingMode5GHz;
+		if (hdd_update_config_cfg(phddctx) == false) {
+			hdd_err("could not update config_dat");
+			retval = -EIO;
+			goto free;
+		}
+
+		if (band_5g) {
+			struct ieee80211_supported_band *band;
+
+			band = phddctx->wiphy->bands[HDD_NL80211_BAND_5GHZ];
+			if (phddctx->config->nChannelBondingMode5GHz)
+				band->ht_cap.cap |=
+					IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+			else
+				band->ht_cap.cap &=
+					~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+		}
+
+		hdd_debug("New_Phymode= %d ch_bonding=%d band=%d VHT_ch_width=%u",
+			phymode, chwidth, curr_band, vhtchanwidth);
+	}
+
+free:
+	if (sme_config)
+		qdf_mem_free(sme_config);
+	return retval;
+}
+
+static int hdd_validate_pdev_reset(int value)
+{
+	if ((value < 1) || (value > 5)) {
+		hdd_warn(" Invalid value %d: Use any one of the below values\n"
+			 "    TX_FLUSH = 1\n"
+			 "    WARM_RESET = 2\n"
+			 "    COLD_RESET = 3\n"
+			 "    WARM_RESET_RESTORE_CAL = 4\n"
+			 "    COLD_RESET_RESTORE_CAL = 5", value);
+
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int hdd_handle_pdev_reset(struct hdd_adapter *adapter, int value)
+{
+	int ret;
+
+	hdd_debug("%d", value);
+
+	ret = hdd_validate_pdev_reset(value);
+	if (ret)
+		return ret;
+
+	ret = wma_cli_set_command(adapter->session_id,
+				  WMI_PDEV_PARAM_PDEV_RESET,
+				  value, PDEV_CMD);
+
+	return ret;
+}
+
+static int hdd_we_set_ch_width(struct hdd_adapter *adapter, int ch_width)
+{
+	int errno;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ePhyChanBondState bonding_state;
+	uint32_t bonding_mode;
+	tSmeConfigParams *sme_config;
+	mac_handle_t mac_handle;
+
+	mac_handle = hdd_ctx->mac_handle;
+	if (!mac_handle)
+		return -EINVAL;
+
+	/* updating channel bonding only on 5Ghz */
+	hdd_debug("WMI_VDEV_PARAM_CHWIDTH val %d", ch_width);
+
+	switch (ch_width) {
+	case eHT_CHANNEL_WIDTH_20MHZ:
+		bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+		break;
+
+	case eHT_CHANNEL_WIDTH_40MHZ:
+	case eHT_CHANNEL_WIDTH_80MHZ:
+		bonding_state = csr_convert_cb_ini_value_to_phy_cb_state(
+			hdd_ctx->config->nChannelBondingMode5GHz);
+
+		if (bonding_state == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE)
+			return -EINVAL;
+
+		bonding_mode = hdd_ctx->config->nChannelBondingMode5GHz;
+		break;
+
+	default:
+		hdd_err("Invalid channel width 0->20 1->40 2->80");
+		return -EINVAL;
+	}
+
+	sme_config = qdf_mem_malloc(sizeof(*sme_config));
+	if (!sme_config) {
+		hdd_err("failed to allocate memory for sme_config");
+		return -ENOMEM;
+	}
+
+	errno = wma_cli_set_command(adapter->session_id, WMI_VDEV_PARAM_CHWIDTH,
+				    ch_width, VDEV_CMD);
+	if (errno)
+		goto free_config;
+
+	sme_get_config_param(mac_handle, sme_config);
+	sme_config->csrConfig.channelBondingMode5GHz = bonding_mode;
+	sme_update_config(mac_handle, sme_config);
+
+free_config:
+	qdf_mem_free(sme_config);
+
+	return errno;
+}
+
+static int hdd_we_set_11d_state(struct hdd_context *hdd_ctx, int state_11d)
+{
+	tSmeConfigParams *sme_config;
+	bool enable_11d;
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+
+	if (!mac_handle)
+		return -EINVAL;
+
+	switch (state_11d) {
+	case ENABLE_11D:
+		enable_11d = true;
+		break;
+	case DISABLE_11D:
+		enable_11d = false;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sme_config = qdf_mem_malloc(sizeof(*sme_config));
+	if (!sme_config) {
+		hdd_err("failed to allocate memory for sme_config");
+		return -ENOMEM;
+	}
+
+	sme_get_config_param(mac_handle, sme_config);
+	sme_config->csrConfig.Is11dSupportEnabled = enable_11d;
+	sme_update_config(mac_handle, sme_config);
+
+	qdf_mem_free(sme_config);
+
+	hdd_debug("11D state=%d", enable_11d);
+
+	return 0;
+}
+
+static int hdd_we_set_power(struct hdd_adapter *adapter, int value)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+
+	if (!mac_handle)
+		return -EINVAL;
+
+	switch (value) {
+	case 1:
+		/* Enable PowerSave */
+		sme_ps_enable_disable(mac_handle, adapter->session_id,
+				      SME_PS_ENABLE);
+		return 0;
+	case 2:
+		/* Disable PowerSave */
+		sme_ps_enable_disable(mac_handle, adapter->session_id,
+				      SME_PS_DISABLE);
+		return 0;
+	case 3:
+		/* Enable UASPD */
+		sme_ps_uapsd_enable(mac_handle, adapter->session_id);
+		return 0;
+	case 4:
+		/* Disable UASPD */
+		sme_ps_uapsd_disable(mac_handle, adapter->session_id);
+		return 0;
+	default:
+		hdd_err("Invalid value %d", value);
+		return -EINVAL;
+	}
+}
+
+static int hdd_we_set_max_assoc(struct hdd_adapter *adapter, int value)
+{
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	status = ucfg_mlme_set_assoc_sta_limit(hdd_ctx->psoc, value);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("cfg set failed, value %d status %d", value, status);
+
+	return qdf_status_to_os_return(status);
+}
+
+static int hdd_we_set_data_inactivity_timeout(struct hdd_adapter *adapter,
+					      int value)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	tpAniSirGlobal mac_ctx;
+
+	if (!mac_handle)
+		return -EINVAL;
+
+	if (!cfg_in_range(CFG_PS_DATA_INACTIVITY_TIMEOUT, value)) {
+		hdd_err_rl("Invalid value %d", value);
+		return -EINVAL;
+	}
+
+	mac_ctx = PMAC_STRUCT(mac_handle);
+	mac_ctx->mlme_cfg->timeouts.ps_data_inactivity_timeout = value;
+
+	return 0;
+}
+
+static int hdd_we_set_wow_data_inactivity_timeout(struct hdd_adapter *adapter,
+						  int value)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	QDF_STATUS status;
+
+	if (!mac_handle)
+		return -EINVAL;
+
+	if ((value < CFG_WOW_DATA_INACTIVITY_TIMEOUT_MIN) ||
+	    (value > CFG_WOW_DATA_INACTIVITY_TIMEOUT_MAX)) {
+		hdd_err_rl("Invalid value %d", value);
+		return -EINVAL;
+	}
+
+	status = sme_cfg_set_int(mac_handle,
+				 WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT,
+				 value);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("cfg set failed, value %d status %d", value, status);
+
+	return qdf_status_to_os_return(status);
+}
+
+static int hdd_we_set_tx_power(struct hdd_adapter *adapter, int value)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	QDF_STATUS status;
+
+	if (!mac_handle)
+		return -EINVAL;
+
+	status = sme_set_tx_power(mac_handle, adapter->session_id,
+				  sta_ctx->conn_info.bssId,
+				  adapter->device_mode, value);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("cfg set failed, value %d status %d", value, status);
+
+	return qdf_status_to_os_return(status);
+}
+
+static int hdd_we_set_max_tx_power(struct hdd_adapter *adapter, int value)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	QDF_STATUS status;
+
+	if (!mac_handle)
+		return -EINVAL;
+
+	status = sme_set_max_tx_power(mac_handle,
+				      sta_ctx->conn_info.bssId,
+				      sta_ctx->conn_info.bssId,
+				      value);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("cfg set failed, value %d status %d", value, status);
+
+	return qdf_status_to_os_return(status);
+}
+
+static int hdd_we_set_max_tx_power_2_4(struct hdd_adapter *adapter, int power)
+{
+	QDF_STATUS status;
+
+	hdd_debug("power %d dBm", power);
+	status = sme_set_max_tx_power_per_band(BAND_2G, power);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("cfg set failed, value %d status %d", power, status);
+
+	return qdf_status_to_os_return(status);
+}
+
+static int hdd_we_set_max_tx_power_5_0(struct hdd_adapter *adapter, int power)
+{
+	QDF_STATUS status;
+
+	hdd_debug("power %d dBm", power);
+	status = sme_set_max_tx_power_per_band(BAND_5G, power);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("cfg set failed, value %d status %d", power, status);
+
+	return qdf_status_to_os_return(status);
+}
+
+static int hdd_we_set_tm_level(struct hdd_adapter *adapter, int level)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	QDF_STATUS status;
+
+	if (!mac_handle)
+		return -EINVAL;
+
+	hdd_debug("Thermal Mitigation Level %d", level);
+	status = sme_set_thermal_level(mac_handle, level);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("cfg set failed, value %d status %d", level, status);
+
+	return qdf_status_to_os_return(status);
+}
+
+static int hdd_we_set_nss(struct hdd_adapter *adapter, int nss)
+{
+	QDF_STATUS status;
+
+	hdd_debug("NSS %d", nss);
+
+	if ((nss > 2) || (nss <= 0)) {
+		hdd_err("Invalid NSS: %d", nss);
+		return -EINVAL;
+	}
+
+	status = hdd_update_nss(adapter, nss);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("cfg set failed, value %d status %d", nss, status);
+
+	return qdf_status_to_os_return(status);
+}
+
+static int hdd_we_set_short_gi(struct hdd_adapter *adapter, int sgi)
+{
+	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
+	int errno;
+
+	hdd_debug("Short GI %d", sgi);
+
+	if (!mac_handle) {
+		hdd_err("NULL Mac handle");
+		return -EINVAL;
+	}
+
+	if (sgi & HDD_AUTO_RATE_SGI)
+		errno = sme_set_auto_rate_he_sgi(mac_handle,
+						 adapter->session_id,
+						 sgi);
+	else
+		errno = sme_update_ht_config(mac_handle,
+					     adapter->session_id,
+					     WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
+					     sgi);
+	if (errno)
+		hdd_err("cfg set failed, value %d status %d", sgi, errno);
+
+	return errno;
+}
+
+static int hdd_we_set_rtscts(struct hdd_adapter *adapter, int rtscts)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	uint32_t value;
+	uint32_t rts_threshold_val;
+	QDF_STATUS status;
+	int errno;
+
+	hdd_debug("RTSCTS %d", rtscts);
+
+	if (!mac_handle) {
+		hdd_err("NULL Mac handle");
+		return -EINVAL;
+	}
+
+	status = ucfg_mlme_get_rts_threshold(hdd_ctx->psoc,
+					     &rts_threshold_val);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Get rts threshold failed, status %d", status);
+		return -EINVAL;
+	}
+
+	if ((rtscts & HDD_RTSCTS_EN_MASK) == HDD_RTSCTS_ENABLE) {
+		value = rts_threshold_val;
+	} else if (((rtscts & HDD_RTSCTS_EN_MASK) == 0) ||
+		   ((rtscts & HDD_RTSCTS_EN_MASK) == HDD_CTS_ENABLE)) {
+		value = cfg_max(CFG_RTS_THRESHOLD);
+	} else {
+		hdd_err_rl("Invalid value %d", rtscts);
+		return -EINVAL;
+	}
+
+	errno = wma_cli_set_command(adapter->session_id,
+				    WMI_VDEV_PARAM_ENABLE_RTSCTS,
+				    rtscts, VDEV_CMD);
+	if (errno) {
+		hdd_err("Failed to set firmware, errno %d", errno);
+		return errno;
+	}
+
+	status = ucfg_mlme_set_rts_threshold(hdd_ctx->psoc, value);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Set rts threshold failed, status %d", status);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int hdd_we_set_11n_rate(struct hdd_adapter *adapter, int rate_code)
+{
+	uint8_t preamble = 0, nss = 0, rix = 0;
+	int errno;
+
+	hdd_debug("Rate code %d", rate_code);
+
+	if (rate_code != 0xff) {
+		rix = RC_2_RATE_IDX(rate_code);
+		if (rate_code & 0x80) {
+			preamble = WMI_RATE_PREAMBLE_HT;
+			nss = HT_RC_2_STREAMS(rate_code) - 1;
+		} else {
+			nss = 0;
+			rix = RC_2_RATE_IDX(rate_code);
+			if (rate_code & 0x10) {
+				preamble = WMI_RATE_PREAMBLE_CCK;
+				if (rix != 0x3)
+					/* Enable Short preamble
+					 * always for CCK except 1mbps
+					 */
+					rix |= 0x4;
+			} else {
+				preamble = WMI_RATE_PREAMBLE_OFDM;
+			}
+		}
+		rate_code = hdd_assemble_rate_code(preamble, nss, rix);
+	}
+
+	hdd_debug("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
+		  rate_code, rix, preamble, nss);
+
+	errno = wma_cli_set_command(adapter->session_id,
+				    WMI_VDEV_PARAM_FIXED_RATE,
+				    rate_code, VDEV_CMD);
+	if (errno)
+		hdd_err("Failed to set firmware, errno %d", errno);
+
+	return errno;
+}
+
+static int hdd_we_set_vht_rate(struct hdd_adapter *adapter, int rate_code)
+{
+	uint8_t preamble = 0, nss = 0, rix = 0;
+	int errno;
+
+	hdd_debug("Rate code %d", rate_code);
+
+	if (rate_code != 0xff) {
+		rix = RC_2_RATE_IDX_11AC(rate_code);
+		preamble = WMI_RATE_PREAMBLE_VHT;
+		nss = HT_RC_2_STREAMS_11AC(rate_code) - 1;
+		rate_code = hdd_assemble_rate_code(preamble, nss, rix);
+	}
+
+	hdd_debug("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
+		  rate_code, rix, preamble, nss);
+
+	errno = wma_cli_set_command(adapter->session_id,
+				    WMI_VDEV_PARAM_FIXED_RATE,
+				    rate_code, VDEV_CMD);
+	if (errno)
+		hdd_err("Failed to set firmware, errno %d", errno);
+
+	return errno;
+}
+
+static int hdd_we_set_amsdu(struct hdd_adapter *adapter, int amsdu)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle_t mac_handle = hdd_ctx->mac_handle;
+	int errno;
+	QDF_STATUS status;
+
+	hdd_debug("AMSDU %d", amsdu);
+
+	if (!mac_handle) {
+		hdd_err("NULL Mac handle");
+		return -EINVAL;
+	}
+
+	if (amsdu > 1)
+		sme_set_amsdu(mac_handle, true);
+	else
+		sme_set_amsdu(mac_handle, false);
+
+	errno = wma_cli_set_command(adapter->session_id,
+				    GEN_VDEV_PARAM_AMSDU,
+				    amsdu, GEN_CMD);
+	if (errno) {
+		hdd_err("Failed to set firmware, errno %d", errno);
+		return errno;
+	}
+
+	status = ucfg_mlme_set_max_amsdu_num(hdd_ctx->psoc,
+					     amsdu);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to set Max AMSDU Num to cfg");
+
+	return 0;
+}
+
+static int hdd_we_clear_stats(struct hdd_adapter *adapter, int option)
+{
+	hdd_debug("option %d", option);
+
+	switch (option) {
+	case CDP_HDD_STATS:
+		memset(&adapter->stats, 0, sizeof(adapter->stats));
+		memset(&adapter->hdd_stats, 0, sizeof(adapter->hdd_stats));
+		break;
+	case CDP_TXRX_HIST_STATS:
+		wlan_hdd_clear_tx_rx_histogram(adapter->hdd_ctx);
+		break;
+	case CDP_HDD_NETIF_OPER_HISTORY:
+		wlan_hdd_clear_netif_queue_history(adapter->hdd_ctx);
+		break;
+	case CDP_HIF_STATS:
+		hdd_clear_hif_stats();
+		break;
+	case CDP_NAPI_STATS:
+		hdd_clear_napi_stats();
+		break;
+	default:
+		cdp_clear_stats(cds_get_context(QDF_MODULE_ID_SOC),
+				option);
+	}
+
+	return 0;
+}
+
+static int hdd_we_set_green_tx_param(struct hdd_adapter *adapter,
+				     green_tx_param id,
+				     const char *id_string,
+				     int value)
+{
+	int errno;
+
+	hdd_debug("%s %d", id_string, value);
+	errno = wma_cli_set_command(adapter->session_id, id, value, GTX_CMD);
+	if (errno)
+		hdd_err("Failed to set firmware, errno %d", errno);
+
+	return errno;
+}
+
+#define hdd_we_set_green_tx_param(adapter, id, value) \
+			hdd_we_set_green_tx_param(adapter, id, #id, value)
+
+static int hdd_we_set_gtx_ht_mcs(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_set_green_tx_param(adapter,
+					 WMI_VDEV_PARAM_GTX_HT_MCS,
+					 value);
+}
+
+static int hdd_we_set_gtx_vht_mcs(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_set_green_tx_param(adapter,
+					 WMI_VDEV_PARAM_GTX_VHT_MCS,
+					 value);
+}
+
+static int hdd_we_set_gtx_usrcfg(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_set_green_tx_param(adapter,
+					 WMI_VDEV_PARAM_GTX_USR_CFG,
+					 value);
+}
+
+static int hdd_we_set_gtx_thre(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_set_green_tx_param(adapter,
+					 WMI_VDEV_PARAM_GTX_THRE,
+					 value);
+}
+
+static int hdd_we_set_gtx_margin(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_set_green_tx_param(adapter,
+					 WMI_VDEV_PARAM_GTX_MARGIN,
+					 value);
+}
+
+static int hdd_we_set_gtx_step(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_set_green_tx_param(adapter,
+					 WMI_VDEV_PARAM_GTX_STEP,
+					 value);
+}
+
+static int hdd_we_set_gtx_mintpc(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_set_green_tx_param(adapter,
+					 WMI_VDEV_PARAM_GTX_MINTPC,
+					 value);
+}
+
+static int hdd_we_set_gtx_bwmask(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_set_green_tx_param(adapter,
+					 WMI_VDEV_PARAM_GTX_BW_MASK,
+					 value);
+}
+
+static int hdd_we_packet_power_save(struct hdd_adapter *adapter,
+				    packet_power_save id,
+				    const char *id_string,
+				    int value)
+{
+	int errno;
+
+	if (adapter->device_mode != QDF_STA_MODE) {
+		hdd_err_rl("Not supported in mode %d", adapter->device_mode);
+		return -EINVAL;
+	}
+
+	hdd_debug("%s %d", id_string, value);
+	errno = wma_cli_set_command(adapter->session_id, id, value, PPS_CMD);
+	if (errno)
+		hdd_err("Failed to set firmware, errno %d", errno);
+
+	return errno;
+}
+
+#define hdd_we_packet_power_save(adapter, id, value) \
+			hdd_we_packet_power_save(adapter, id, #id, value)
+
+static int hdd_we_pps_paid_match(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_packet_power_save(adapter,
+					WMI_VDEV_PPS_PAID_MATCH,
+					value);
+}
+
+static int hdd_we_pps_gid_match(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_packet_power_save(adapter,
+					WMI_VDEV_PPS_GID_MATCH,
+					value);
+}
+
+static int hdd_we_pps_early_tim_clear(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_packet_power_save(adapter,
+					WMI_VDEV_PPS_EARLY_TIM_CLEAR,
+					value);
+}
+
+static int hdd_we_pps_early_dtim_clear(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_packet_power_save(adapter,
+					WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
+					value);
+}
+
+static int hdd_we_pps_eof_pad_delim(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_packet_power_save(adapter,
+					WMI_VDEV_PPS_EOF_PAD_DELIM,
+					value);
+}
+
+static int hdd_we_pps_macaddr_mismatch(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_packet_power_save(adapter,
+					WMI_VDEV_PPS_MACADDR_MISMATCH,
+					value);
+}
+
+static int hdd_we_pps_delim_crc_fail(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_packet_power_save(adapter,
+					WMI_VDEV_PPS_DELIM_CRC_FAIL,
+					value);
+}
+
+static int hdd_we_pps_gid_nsts_zero(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_packet_power_save(adapter,
+					WMI_VDEV_PPS_GID_NSTS_ZERO,
+					value);
+}
+
+static int hdd_we_pps_rssi_check(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_packet_power_save(adapter,
+					WMI_VDEV_PPS_RSSI_CHECK,
+					value);
+}
+
+static int hdd_we_pps_5g_ebt(struct hdd_adapter *adapter, int value)
+{
+	return hdd_we_packet_power_save(adapter,
+					WMI_VDEV_PPS_5G_EBT,
+					value);
+}
+
+static int hdd_we_set_qpower(struct hdd_adapter *adapter,
+			     enum wmi_sta_powersave_param id,
+			     const char *id_string,
+			     int value)
+{
+	int errno;
+
+	hdd_debug("%s %d", id_string, value);
+	errno = wma_cli_set_command(adapter->session_id, id, value, QPOWER_CMD);
+	if (errno)
+		hdd_err("Failed to set firmware, errno %d", errno);
+
+	return errno;
+}
+
+#define hdd_we_set_qpower(adapter, id, value) \
+			hdd_we_set_qpower(adapter, id, #id, value)
+
+static int
+hdd_we_set_qpower_max_pspoll_count(struct hdd_adapter *adapter, int value)
+{
+	enum wmi_sta_powersave_param id =
+		WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT;
+
+	return hdd_we_set_qpower(adapter, id, value);
+}
+
+static int
+hdd_we_set_qpower_max_tx_before_wake(struct hdd_adapter *adapter, int value)
+{
+	enum wmi_sta_powersave_param id =
+		WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE;
+
+	return hdd_we_set_qpower(adapter, id, value);
+}
+
+static int
+hdd_we_set_qpower_spec_pspoll_wake_interval(struct hdd_adapter *adapter,
+					    int value)
+{
+	enum wmi_sta_powersave_param id =
+		WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL;
+
+	return hdd_we_set_qpower(adapter, id, value);
+}
+
+static int
+hdd_we_set_qpower_spec_max_spec_nodata_pspoll(struct hdd_adapter *adapter,
+					      int value)
+{
+	enum wmi_sta_powersave_param id =
+		WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL;
+
+	return hdd_we_set_qpower(adapter, id, value);
+}
+
+/**
+ * iw_setint_getnone() - Generic "set integer" private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_setint_getnone(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	mac_handle_t mac_handle;
+	struct hdd_context *hdd_ctx;
+	int *value = (int *)extra;
+	int sub_cmd = value[0];
+	int set_value = value[1];
+	int ret;
+	QDF_STATUS status;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (ret)
+		return ret;
+
+	mac_handle = hdd_ctx->mac_handle;
+	switch (sub_cmd) {
+	case WE_SET_11D_STATE:
+		ret = hdd_we_set_11d_state(hdd_ctx, set_value);
+		break;
+
+	case WE_SET_POWER:
+		ret = hdd_we_set_power(adapter, set_value);
+		break;
+
+	case WE_SET_MAX_ASSOC:
+		ret = hdd_we_set_max_assoc(adapter, set_value);
+		break;
+
+	case WE_SET_DATA_INACTIVITY_TO:
+		ret = hdd_we_set_data_inactivity_timeout(adapter, set_value);
+		break;
+
+	case WE_SET_WOW_DATA_INACTIVITY_TO:
+		ret = hdd_we_set_wow_data_inactivity_timeout(adapter,
+							     set_value);
+		break;
+
+	case WE_SET_MC_RATE:
+		ret = wlan_hdd_set_mc_rate(adapter, set_value);
+		break;
+
+	case WE_SET_TX_POWER:
+		ret = hdd_we_set_tx_power(adapter, set_value);
+		break;
+
+	case WE_SET_MAX_TX_POWER:
+		ret = hdd_we_set_max_tx_power(adapter, set_value);
+		break;
+
+	case WE_SET_MAX_TX_POWER_2_4:
+		ret = hdd_we_set_max_tx_power_2_4(adapter, set_value);
+		break;
+
+	case WE_SET_MAX_TX_POWER_5_0:
+		ret = hdd_we_set_max_tx_power_5_0(adapter, set_value);
+		break;
+
+	case WE_SET_TM_LEVEL:
+		ret = hdd_we_set_tm_level(adapter, set_value);
+		break;
+
+	case WE_SET_PHYMODE:
+		ret = wlan_hdd_update_phymode(adapter, set_value);
+		break;
+
+	case WE_SET_NSS:
+		ret = hdd_we_set_nss(adapter, set_value);
+		break;
+
+	case WE_SET_GTX_HT_MCS:
+		ret = hdd_we_set_gtx_ht_mcs(adapter, set_value);
+		break;
+
+	case WE_SET_GTX_VHT_MCS:
+		ret = hdd_we_set_gtx_vht_mcs(adapter, set_value);
+		break;
+
+	case WE_SET_GTX_USRCFG:
+		ret = hdd_we_set_gtx_usrcfg(adapter, set_value);
+		break;
+
+	case WE_SET_GTX_THRE:
+		ret = hdd_we_set_gtx_thre(adapter, set_value);
+		break;
+
+	case WE_SET_GTX_MARGIN:
+		ret = hdd_we_set_gtx_margin(adapter, set_value);
+		break;
+
+	case WE_SET_GTX_STEP:
+		ret = hdd_we_set_gtx_step(adapter, set_value);
+		break;
+
+	case WE_SET_GTX_MINTPC:
+		ret = hdd_we_set_gtx_mintpc(adapter, set_value);
+		break;
+
+	case WE_SET_GTX_BWMASK:
+		ret = hdd_we_set_gtx_bwmask(adapter, set_value);
+		break;
+
+	case WE_SET_LDPC:
+		ret = hdd_set_ldpc(adapter, set_value);
+		break;
+
+	case WE_SET_TX_STBC:
+		ret = hdd_set_tx_stbc(adapter, set_value);
+		break;
+
+	case WE_SET_RX_STBC:
+		ret = hdd_set_rx_stbc(adapter, set_value);
+		break;
+
+	case WE_SET_SHORT_GI:
+		ret = hdd_we_set_short_gi(adapter, set_value);
+		break;
+
+	case WE_SET_RTSCTS:
+		ret = hdd_we_set_rtscts(adapter, set_value);
+		break;
+
+	case WE_SET_CHWIDTH:
+		ret = hdd_we_set_ch_width(adapter, set_value);
+		break;
+
+	case WE_SET_ANI_EN_DIS:
+	{
+		hdd_debug("WMI_PDEV_PARAM_ANI_ENABLE val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_ANI_ENABLE,
+					  set_value, PDEV_CMD);
+		break;
+	}
+
+	case WE_SET_ANI_POLL_PERIOD:
+	{
+		hdd_debug("WMI_PDEV_PARAM_ANI_POLL_PERIOD val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_ANI_POLL_PERIOD,
+					  set_value, PDEV_CMD);
+		break;
+	}
+
+	case WE_SET_ANI_LISTEN_PERIOD:
+	{
+		hdd_debug("WMI_PDEV_PARAM_ANI_LISTEN_PERIOD val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
+					  set_value, PDEV_CMD);
+		break;
+	}
+
+	case WE_SET_ANI_OFDM_LEVEL:
+	{
+		hdd_debug("WMI_PDEV_PARAM_ANI_OFDM_LEVEL val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
+					  set_value, PDEV_CMD);
+		break;
+	}
+
+	case WE_SET_ANI_CCK_LEVEL:
+	{
+		hdd_debug("WMI_PDEV_PARAM_ANI_CCK_LEVEL val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_ANI_CCK_LEVEL,
+					  set_value, PDEV_CMD);
+		break;
+	}
+
+	case WE_SET_DYNAMIC_BW:
+	{
+		hdd_debug("WMI_PDEV_PARAM_DYNAMIC_BW val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_DYNAMIC_BW,
+					  set_value, PDEV_CMD);
+		break;
+	}
+
+	case WE_SET_CTS_CBW:
+	{
+		hdd_debug("WE_SET_CTS_CBW val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_CTS_CBW,
+					  set_value, PDEV_CMD);
+		break;
+	}
+
+	case WE_SET_11N_RATE:
+		ret = hdd_we_set_11n_rate(adapter, set_value);
+		break;
+
+	case WE_SET_VHT_RATE:
+		ret = hdd_we_set_vht_rate(adapter, set_value);
+		break;
+
+	case WE_SET_AMPDU:
+	{
+		hdd_debug("SET AMPDU val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  GEN_VDEV_PARAM_AMPDU,
+					  set_value, GEN_CMD);
+		break;
+	}
+
+	case WE_SET_AMSDU:
+		ret = hdd_we_set_amsdu(adapter, set_value);
+		break;
+
+	case WE_SET_TX_CHAINMASK:
+	{
+		hdd_debug("WMI_PDEV_PARAM_TX_CHAIN_MASK val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_TX_CHAIN_MASK,
+					  set_value, PDEV_CMD);
+		ret = hdd_set_antenna_mode(adapter, hdd_ctx, set_value);
+		break;
+	}
+
+	case WE_SET_RX_CHAINMASK:
+	{
+		hdd_debug("WMI_PDEV_PARAM_RX_CHAIN_MASK val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_RX_CHAIN_MASK,
+					  set_value, PDEV_CMD);
+		ret = hdd_set_antenna_mode(adapter, hdd_ctx, set_value);
+		break;
+	}
+
+	case WE_SET_TXPOW_2G:
+	{
+		hdd_debug("WMI_PDEV_PARAM_TXPOWER_LIMIT2G val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
+					  set_value, PDEV_CMD);
+		break;
+	}
+
+	case WE_SET_TXPOW_5G:
+	{
+		hdd_debug("WMI_PDEV_PARAM_TXPOWER_LIMIT5G val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
+					  set_value, PDEV_CMD);
+		break;
+	}
+
+	/* Firmware debug log */
+	case WE_DBGLOG_LOG_LEVEL:
+	{
+		hdd_debug("WE_DBGLOG_LOG_LEVEL val %d", set_value);
+		hdd_ctx->fw_log_settings.dl_loglevel = set_value;
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_LOG_LEVEL,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case WE_DBGLOG_VAP_ENABLE:
+	{
+		hdd_debug("WE_DBGLOG_VAP_ENABLE val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_VAP_ENABLE,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case WE_DBGLOG_VAP_DISABLE:
+	{
+		hdd_debug("WE_DBGLOG_VAP_DISABLE val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_VAP_DISABLE,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case WE_DBGLOG_MODULE_ENABLE:
+	{
+		hdd_debug("WE_DBGLOG_MODULE_ENABLE val %d",
+		       set_value);
+		hdd_ctx->fw_log_settings.enable = set_value;
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_MODULE_ENABLE,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case WE_DBGLOG_MODULE_DISABLE:
+	{
+		hdd_debug("WE_DBGLOG_MODULE_DISABLE val %d",
+		       set_value);
+		hdd_ctx->fw_log_settings.enable = set_value;
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_MODULE_DISABLE,
+					  set_value, DBG_CMD);
+		break;
+	}
+	case WE_DBGLOG_MOD_LOG_LEVEL:
+	{
+		hdd_debug("WE_DBGLOG_MOD_LOG_LEVEL val %d",
+		       set_value);
+
+		if (hdd_ctx->fw_log_settings.index >= MAX_MOD_LOGLEVEL)
+			hdd_ctx->fw_log_settings.index = 0;
+
+		hdd_ctx->fw_log_settings.
+		dl_mod_loglevel[hdd_ctx->fw_log_settings.index] =
+			set_value;
+		hdd_ctx->fw_log_settings.index++;
+
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_MOD_LOG_LEVEL,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case WE_DBGLOG_TYPE:
+	{
+		hdd_debug("WE_DBGLOG_TYPE val %d", set_value);
+		hdd_ctx->fw_log_settings.dl_type = set_value;
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_TYPE,
+					  set_value, DBG_CMD);
+		break;
+	}
+	case WE_DBGLOG_REPORT_ENABLE:
+	{
+		hdd_debug("WE_DBGLOG_REPORT_ENABLE val %d",
+		       set_value);
+		hdd_ctx->fw_log_settings.dl_report = set_value;
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_DBGLOG_REPORT_ENABLE,
+					  set_value, DBG_CMD);
+		break;
+	}
+
+	case WE_SET_TXRX_FWSTATS:
+	{
+		hdd_debug("WE_SET_TXRX_FWSTATS val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
+					  set_value, VDEV_CMD);
+		break;
+	}
+
+	case WE_TXRX_FWSTATS_RESET:
+	{
+		hdd_debug("WE_TXRX_FWSTATS_RESET val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
+					  set_value, VDEV_CMD);
+		break;
+	}
+
+	case WE_DUMP_STATS:
+	{
+		hdd_debug("WE_DUMP_STATS val %d", set_value);
+		ret = hdd_wlan_dump_stats(adapter, set_value);
+		break;
+	}
+
+	case WE_CLEAR_STATS:
+		ret = hdd_we_clear_stats(adapter, set_value);
+		break;
+
+	case WE_PPS_PAID_MATCH:
+		ret = hdd_we_pps_paid_match(adapter, set_value);
+		break;
+
+	case WE_PPS_GID_MATCH:
+		ret = hdd_we_pps_gid_match(adapter, set_value);
+		break;
+
+	case WE_PPS_EARLY_TIM_CLEAR:
+		ret = hdd_we_pps_early_tim_clear(adapter, set_value);
+		break;
+
+	case WE_PPS_EARLY_DTIM_CLEAR:
+		ret = hdd_we_pps_early_dtim_clear(adapter, set_value);
+		break;
+
+	case WE_PPS_EOF_PAD_DELIM:
+		ret = hdd_we_pps_eof_pad_delim(adapter, set_value);
+		break;
+
+	case WE_PPS_MACADDR_MISMATCH:
+		ret = hdd_we_pps_macaddr_mismatch(adapter, set_value);
+		break;
+
+	case WE_PPS_DELIM_CRC_FAIL:
+		ret = hdd_we_pps_delim_crc_fail(adapter, set_value);
+		break;
+
+	case WE_PPS_GID_NSTS_ZERO:
+		ret = hdd_we_pps_gid_nsts_zero(adapter, set_value);
+		break;
+
+	case WE_PPS_RSSI_CHECK:
+		ret = hdd_we_pps_rssi_check(adapter, set_value);
+		break;
+
+	case WE_PPS_5G_EBT:
+		ret = hdd_we_pps_5g_ebt(adapter, set_value);
+		break;
+
+	case WE_SET_HTSMPS:
+	{
+		hdd_debug("WE_SET_HTSMPS val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_STA_SMPS_FORCE_MODE_CMDID,
+					  set_value, VDEV_CMD);
+		break;
+	}
+
+	case WE_SET_QPOWER_MAX_PSPOLL_COUNT:
+		ret = hdd_we_set_qpower_max_pspoll_count(adapter, set_value);
+		break;
+
+	case WE_SET_QPOWER_MAX_TX_BEFORE_WAKE:
+		ret = hdd_we_set_qpower_max_tx_before_wake(adapter, set_value);
+		break;
+
+	case WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
+		ret = hdd_we_set_qpower_spec_pspoll_wake_interval(adapter,
+								  set_value);
+		break;
+
+	case WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
+		ret = hdd_we_set_qpower_spec_max_spec_nodata_pspoll(adapter,
+								    set_value);
+		break;
+
+	case WE_MCC_CONFIG_LATENCY:
+	{
+		wlan_hdd_set_mcc_latency(adapter, set_value);
+		break;
+	}
+
+	case WE_MCC_CONFIG_QUOTA:
+	{
+		hdd_debug("iwpriv cmd to set MCC quota with val %dms",
+				set_value);
+		ret = wlan_hdd_set_mcc_p2p_quota(adapter,
+			set_value);
+		break;
+	}
+	case WE_SET_DEBUG_LOG:
+	{
+		if (!mac_handle)
+			return -EINVAL;
+
+		sme_update_connect_debug(mac_handle, set_value);
+		break;
+	}
+	case WE_SET_EARLY_RX_ADJUST_ENABLE:
+	{
+		hdd_debug("SET early_rx enable val %d", set_value);
+		if ((set_value == 0) || (set_value == 1))
+			ret = wma_cli_set_command(
+					adapter->session_id,
+					WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE,
+					set_value, VDEV_CMD);
+		else
+			ret = -EINVAL;
+		break;
+	}
+	case WE_SET_EARLY_RX_TGT_BMISS_NUM:
+	{
+		hdd_debug("SET early_rx bmiss val %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM,
+					  set_value, VDEV_CMD);
+		break;
+	}
+	case WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE:
+	{
+		hdd_debug("SET early_rx bmiss sample cycle %d",
+		       set_value);
+		ret = wma_cli_set_command(
+				adapter->session_id,
+				WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE,
+				set_value, VDEV_CMD);
+		break;
+	}
+	case WE_SET_EARLY_RX_SLOP_STEP:
+	{
+		hdd_debug("SET early_rx bmiss slop step val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP,
+					  set_value, VDEV_CMD);
+		break;
+	}
+	case WE_SET_EARLY_RX_INIT_SLOP:
+	{
+		hdd_debug("SET early_rx init slop step val %d",
+		       set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP,
+					  set_value, VDEV_CMD);
+		break;
+	}
+	case WE_SET_EARLY_RX_ADJUST_PAUSE:
+	{
+		hdd_debug("SET early_rx adjust pause %d", set_value);
+		if ((set_value == 0) || (set_value == 1))
+			ret = wma_cli_set_command(
+					adapter->session_id,
+					WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE,
+					set_value, VDEV_CMD);
+		else
+			ret = -EINVAL;
+		break;
+	}
+	case WE_SET_EARLY_RX_DRIFT_SAMPLE:
+	{
+		hdd_debug("SET early_rx drift sample %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE,
+					  set_value, VDEV_CMD);
+		break;
+	}
+	case WE_SET_SCAN_DISABLE:
+	{
+		if (!mac_handle)
+			return -EINVAL;
+
+		hdd_debug("SET SCAN DISABLE %d", set_value);
+		sme_set_scan_disable(mac_handle, set_value);
+		break;
+	}
+	case WE_START_FW_PROFILE:
+	{
+		hdd_debug("WE_START_FW_PROFILE %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					WMI_WLAN_PROFILE_TRIGGER_CMDID,
+					set_value, DBG_CMD);
+		break;
+	}
+	case WE_SET_CHANNEL:
+	{
+		hdd_debug("Set Channel %d Session ID %d mode %d", set_value,
+				  adapter->session_id, adapter->device_mode);
+		if (!mac_handle)
+			return -EINVAL;
+
+
+		if ((QDF_STA_MODE == adapter->device_mode) ||
+		    (QDF_P2P_CLIENT_MODE == adapter->device_mode)) {
+
+			status = sme_ext_change_channel(mac_handle,
+							set_value,
+							adapter->session_id);
+			if (status != QDF_STATUS_SUCCESS) {
+				hdd_err("Error in change channel status %d",
+					status);
+				ret = -EINVAL;
+			}
+		} else {
+			hdd_err("change channel not supported for device mode %d",
+				adapter->device_mode);
+			ret = -EINVAL;
+		}
+		break;
+	}
+	case WE_SET_CONC_SYSTEM_PREF:
+		hdd_debug("New preference: %d", set_value);
+		ucfg_policy_mgr_set_sys_pref(hdd_ctx->psoc, set_value);
+		break;
+	case WE_SET_11AX_RATE:
+		ret = hdd_set_11ax_rate(adapter, set_value, NULL);
+		break;
+	case WE_SET_DCM:
+		hdd_debug("Set WMI_VDEV_PARAM_HE_DCM: %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_HE_DCM, set_value,
+					  VDEV_CMD);
+		break;
+	case WE_SET_RANGE_EXT:
+		hdd_debug("Set WMI_VDEV_PARAM_HE_RANGE_EXT: %d", set_value);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_VDEV_PARAM_HE_RANGE_EXT,
+					  set_value, VDEV_CMD);
+		break;
+	case WE_SET_PDEV_RESET:
+		ret = hdd_handle_pdev_reset(adapter, set_value);
+		break;
+	case WE_SET_MODULATED_DTIM:
+		if ((set_value < cfg_max(CFG_PMO_ENABLE_MODULATED_DTIM)) ||
+		    (set_value > cfg_max(CFG_PMO_ENABLE_MODULATED_DTIM))) {
+			hdd_err("Invalid gEnableModuleDTIM value %d",
+				set_value);
+			return -EINVAL;
+		}
+
+		ucfg_pmo_set_sta_mod_dtim(hdd_ctx->psoc, set_value);
+		break;
+	default:
+		hdd_debug("Invalid sub command %d", sub_cmd);
+		ret = -EINVAL;
+		break;
+	}
+
+	hdd_exit();
+
+	return ret;
+}
+
+static int iw_setint_getnone(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu,
+			     char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_setint_getnone(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __iw_setnone_get_threeint() - return three value to up layer.
+ *
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/Output
+ *
+ * Return: execute result
+ */
+static int __iw_setnone_get_threeint(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *wrqu, char *extra)
+{
+	int ret = 0; /* success */
+	uint32_t *value = (int *)extra;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter_dev(dev);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	hdd_debug("param = %d", value[0]);
+	switch (value[0]) {
+	case WE_GET_TSF:
+		ret = hdd_indicate_tsf(adapter, value, 3);
+		break;
+	default:
+		hdd_err("Invalid IOCTL get_value command %d", value[0]);
+		break;
+	}
+	return ret;
+}
+
+/**
+ * iw_setnone_get_threeint() - return three value to up layer.
+ *
+ * @dev: pointer of net_device of this wireless card
+ * @info: meta data about Request sent
+ * @wrqu: include request info
+ * @extra: buf used for in/Output
+ *
+ * Return: execute result
+ */
+static int iw_setnone_get_threeint(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_setnone_get_threeint(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef WLAN_UNIT_TEST
+static int hdd_we_unit_test(struct hdd_context *hdd_ctx, const char *component)
+{
+	uint32_t errors = 0;
+	bool all = !component || !component[0];
+
+	if (all)
+		hdd_info("Starting unit tests for all components");
+	else
+		hdd_info("Starting unit tests for component '%s'", component);
+
+	if (all || qdf_str_eq(component, "dsc"))
+		errors += dsc_unit_test();
+
+	/* add future tests here */
+
+	if (errors) {
+		hdd_err("Unit tests failed with %u errors", errors);
+		return -EPERM;
+	}
+
+	hdd_info("Unit tests passed successfully");
+
+	return 0;
+}
+#else
+static int hdd_we_unit_test(struct hdd_context *hdd_ctx, const char *component)
+{
+	return -EOPNOTSUPP;
+}
+#endif /* WLAN_UNIT_TEST */
+
+/**
+ * iw_setchar_getnone() - Generic "set string" private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_setchar_getnone(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	QDF_STATUS status;
+	int sub_cmd;
+	int ret;
+	char *str_arg = NULL;
+	struct hdd_adapter *adapter = (netdev_priv(dev));
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_config *pConfig = hdd_ctx->config;
+	struct iw_point s_priv_data;
+
+	hdd_enter_dev(dev);
+
+	if (!capable(CAP_NET_ADMIN)) {
+		hdd_err("permission check failed");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	/* helper function to get iwreq_data with compat handling. */
+	if (hdd_priv_get_data(&s_priv_data, wrqu))
+		return -EINVAL;
+
+	/* make sure all params are correctly passed to function */
+	if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length))
+		return -EINVAL;
+
+	sub_cmd = s_priv_data.flags;
+
+	/* ODD number is used for set, copy data using copy_from_user */
+	str_arg = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
+						  s_priv_data.length);
+	if (!str_arg) {
+		hdd_err("mem_alloc_copy_from_user_helper fail");
+		return -ENOMEM;
+	}
+
+	hdd_debug("Received length: %d data: %s",
+			s_priv_data.length, str_arg);
+
+	switch (sub_cmd) {
+	case WE_WOWL_ADD_PTRN:
+		hdd_debug("ADD_PTRN");
+		hdd_add_wowl_ptrn(adapter, str_arg);
+		break;
+	case WE_WOWL_DEL_PTRN:
+		hdd_debug("DEL_PTRN");
+		hdd_del_wowl_ptrn(adapter, str_arg);
+		break;
+	case WE_NEIGHBOR_REPORT_REQUEST:
+	{
+		tRrmNeighborReq neighborReq;
+		tRrmNeighborRspCallbackInfo callbackInfo;
+
+		if (pConfig->fRrmEnable) {
+			neighborReq.neighbor_report_offload = false;
+			neighborReq.no_ssid =
+				(s_priv_data.length - 1) ? false : true;
+			hdd_debug("Neighbor Request ssid present %d",
+				  neighborReq.no_ssid);
+			if (!neighborReq.no_ssid) {
+				neighborReq.ssid.length =
+					(s_priv_data.length - 1) >
+					32 ? 32 : (s_priv_data.length - 1);
+				qdf_mem_copy(neighborReq.ssid.ssId,
+					     str_arg,
+					     neighborReq.ssid.length);
+			}
+
+			/*
+			 * If 11k offload is supported by FW and enabled
+			 * in the ini, set the offload to true
+			 */
+			if (hdd_ctx->config->is_11k_offload_supported &&
+			    (hdd_ctx->config->offload_11k_enable_bitmask &
+			    OFFLOAD_11K_BITMASK_NEIGHBOR_REPORT_REQUEST)) {
+				hdd_debug("Neighbor report offloaded to FW");
+				neighborReq.neighbor_report_offload = true;
+			}
+
+			callbackInfo.neighborRspCallback = NULL;
+			callbackInfo.neighborRspCallbackContext = NULL;
+			callbackInfo.timeout = 5000; /* 5 seconds */
+			sme_neighbor_report_request(
+					hdd_ctx->mac_handle,
+					adapter->session_id,
+					&neighborReq,
+					&callbackInfo);
+		} else {
+			hdd_err("Ignoring neighbor request as RRM not enabled");
+			ret = -EINVAL;
+		}
+	}
+	break;
+	case WE_SET_AP_WPS_IE:
+		hdd_debug("Received WE_SET_AP_WPS_IE, won't process");
+		break;
+	case WE_SET_CONFIG:
+		status = hdd_execute_global_config_command(hdd_ctx, str_arg);
+		if (QDF_IS_STATUS_ERROR(status))
+			ret = -EINVAL;
+
+		break;
+	case WE_UNIT_TEST:
+		ret = hdd_we_unit_test(hdd_ctx, str_arg);
+		break;
+	default:
+	{
+		hdd_err("Invalid sub command %d", sub_cmd);
+		ret = -EINVAL;
+		break;
+	}
+	}
+
+	qdf_mem_free(str_arg);
+	hdd_exit();
+
+	return ret;
+}
+
+static int iw_setchar_getnone(struct net_device *dev,
+			      struct iw_request_info *info,
+			      union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_setchar_getnone(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * iw_setnone_getint() - Generic "get integer" private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_setnone_getint(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	mac_handle_t mac_handle;
+	int *value = (int *)extra;
+	int ret;
+	tSmeConfigParams *sme_config;
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+	bool bval = false;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	sme_config = qdf_mem_malloc(sizeof(*sme_config));
+	if (!sme_config) {
+		hdd_err("failed to allocate memory for sme_config");
+		return -ENOMEM;
+	}
+
+	mac_handle = hdd_ctx->mac_handle;
+	switch (value[0]) {
+	case WE_GET_11D_STATE:
+	{
+		sme_get_config_param(mac_handle, sme_config);
+
+		*value = sme_config->csrConfig.Is11dSupportEnabled;
+
+		hdd_debug("11D state=%d!!", *value);
+
+		break;
+	}
+
+	case WE_GET_WLAN_DBG:
+	{
+		qdf_trace_display();
+		*value = 0;
+		break;
+	}
+	case WE_GET_MAX_ASSOC:
+	{
+		if (ucfg_mlme_set_assoc_sta_limit(hdd_ctx->psoc, *value) !=
+		    QDF_STATUS_SUCCESS) {
+			hdd_err("CFG_ASSOC_STA_LIMIT failed");
+			ret = -EIO;
+		}
+
+		break;
+	}
+
+	case WE_GET_CONCURRENCY_MODE:
+	{
+		*value = policy_mgr_get_concurrency_mode(hdd_ctx->psoc);
+
+		hdd_debug("concurrency mode=%d", *value);
+		break;
+	}
+
+	case WE_GET_NSS:
+	{
+		sme_get_config_param(mac_handle, sme_config);
+		status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("unable to get vht_enable2x2");
+		*value = (bval == 0) ? 1 : 2;
+		if (policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc))
+			*value = *value - 1;
+		hdd_debug("GET_NSS: Current NSS:%d", *value);
+		break;
+	}
+
+	case WE_GET_GTX_HT_MCS:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_HT_MCS");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_HT_MCS,
+					     GTX_CMD);
+		break;
+	}
+
+	case WE_GET_GTX_VHT_MCS:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_VHT_MCS");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_VHT_MCS,
+					     GTX_CMD);
+		break;
+	}
+
+	case WE_GET_GTX_USRCFG:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_USR_CFG");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_USR_CFG,
+					     GTX_CMD);
+		break;
+	}
+
+	case WE_GET_GTX_THRE:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_THRE");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_THRE,
+					     GTX_CMD);
+		break;
+	}
+
+	case WE_GET_GTX_MARGIN:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_MARGIN");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_MARGIN,
+					     GTX_CMD);
+		break;
+	}
+
+	case WE_GET_GTX_STEP:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_STEP");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_STEP,
+					     GTX_CMD);
+		break;
+	}
+
+	case WE_GET_GTX_MINTPC:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_MINTPC");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_MINTPC,
+					     GTX_CMD);
+		break;
+	}
+
+	case WE_GET_GTX_BWMASK:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_GTX_BW_MASK");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_GTX_BW_MASK,
+					     GTX_CMD);
+		break;
+	}
+
+	case WE_GET_LDPC:
+	{
+		ret = hdd_get_ldpc(adapter, value);
+		break;
+	}
+
+	case WE_GET_TX_STBC:
+	{
+		ret = hdd_get_tx_stbc(adapter, value);
+		break;
+	}
+
+	case WE_GET_RX_STBC:
+	{
+		ret = hdd_get_rx_stbc(adapter, value);
+		break;
+	}
+
+	case WE_GET_SHORT_GI:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_SGI");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_SGI,
+					     VDEV_CMD);
+		break;
+	}
+
+	case WE_GET_RTSCTS:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_ENABLE_RTSCTS");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_ENABLE_RTSCTS,
+					     VDEV_CMD);
+		break;
+	}
+
+	case WE_GET_CHWIDTH:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_CHWIDTH");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_CHWIDTH,
+					     VDEV_CMD);
+		break;
+	}
+
+	case WE_GET_ANI_EN_DIS:
+	{
+		hdd_debug("GET WMI_PDEV_PARAM_ANI_ENABLE");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_ANI_ENABLE,
+					     PDEV_CMD);
+		break;
+	}
+
+	case WE_GET_ANI_POLL_PERIOD:
+	{
+		hdd_debug("GET WMI_PDEV_PARAM_ANI_POLL_PERIOD");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_ANI_POLL_PERIOD,
+					     PDEV_CMD);
+		break;
+	}
+
+	case WE_GET_ANI_LISTEN_PERIOD:
+	{
+		hdd_debug("GET WMI_PDEV_PARAM_ANI_LISTEN_PERIOD");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
+					     PDEV_CMD);
+		break;
+	}
+
+	case WE_GET_ANI_OFDM_LEVEL:
+	{
+		hdd_debug("GET WMI_PDEV_PARAM_ANI_OFDM_LEVEL");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
+					     PDEV_CMD);
+		break;
+	}
+
+	case WE_GET_ANI_CCK_LEVEL:
+	{
+		hdd_debug("GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_ANI_CCK_LEVEL,
+					     PDEV_CMD);
+		break;
+	}
+
+	case WE_GET_DYNAMIC_BW:
+	{
+		hdd_debug("GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_DYNAMIC_BW,
+					     PDEV_CMD);
+		break;
+	}
+
+	case WE_GET_11N_RATE:
+	{
+		hdd_debug("GET WMI_VDEV_PARAM_FIXED_RATE");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_FIXED_RATE,
+					     VDEV_CMD);
+		break;
+	}
+
+	case WE_GET_AMPDU:
+	{
+		hdd_debug("GET AMPDU");
+		*value = wma_cli_get_command(adapter->session_id,
+					     GEN_VDEV_PARAM_AMPDU,
+					     GEN_CMD);
+		break;
+	}
+
+	case WE_GET_AMSDU:
+	{
+		hdd_debug("GET AMSDU");
+		*value = wma_cli_get_command(adapter->session_id,
+					     GEN_VDEV_PARAM_AMSDU,
+					     GEN_CMD);
+		break;
+	}
+
+	case WE_GET_ROAM_SYNCH_DELAY:
+	{
+		hdd_debug("GET ROAM SYNCH DELAY");
+		*value = wma_cli_get_command(adapter->session_id,
+					     GEN_VDEV_ROAM_SYNCH_DELAY,
+					     GEN_CMD);
+		break;
+	}
+
+	case WE_GET_TX_CHAINMASK:
+	{
+		hdd_debug("GET WMI_PDEV_PARAM_TX_CHAIN_MASK");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_TX_CHAIN_MASK,
+					     PDEV_CMD);
+		break;
+	}
+
+	case WE_GET_RX_CHAINMASK:
+	{
+		hdd_debug("GET WMI_PDEV_PARAM_RX_CHAIN_MASK");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_RX_CHAIN_MASK,
+					     PDEV_CMD);
+		break;
+	}
+
+	case WE_GET_TXPOW_2G:
+	{
+		uint32_t txpow2g = 0;
+
+		hdd_debug("GET WMI_PDEV_PARAM_TXPOWER_LIMIT2G");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
+					     PDEV_CMD);
+		if (QDF_STATUS_SUCCESS !=
+		    sme_cfg_get_int(mac_handle, WNI_CFG_CURRENT_TX_POWER_LEVEL,
+				    &txpow2g)) {
+			return -EIO;
+		}
+		hdd_debug("2G tx_power %d", txpow2g);
+		break;
+	}
+
+	case WE_GET_TXPOW_5G:
+	{
+		uint32_t txpow5g = 0;
+
+		hdd_debug("GET WMI_PDEV_PARAM_TXPOWER_LIMIT5G");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
+					     PDEV_CMD);
+		if (QDF_STATUS_SUCCESS !=
+		    sme_cfg_get_int(mac_handle, WNI_CFG_CURRENT_TX_POWER_LEVEL,
+				    &txpow5g)) {
+			return -EIO;
+		}
+		hdd_debug("5G tx_power %d", txpow5g);
+		break;
+	}
+
+	case WE_GET_PPS_PAID_MATCH:
+	{
+		hdd_debug("GET WMI_VDEV_PPS_PAID_MATCH");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PPS_PAID_MATCH,
+					     PPS_CMD);
+		break;
+	}
+
+	case WE_GET_PPS_GID_MATCH:
+	{
+		hdd_debug("GET WMI_VDEV_PPS_GID_MATCH");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PPS_GID_MATCH,
+					     PPS_CMD);
+		break;
+	}
+
+	case WE_GET_PPS_EARLY_TIM_CLEAR:
+	{
+		hdd_debug("GET WMI_VDEV_PPS_EARLY_TIM_CLEAR");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PPS_EARLY_TIM_CLEAR,
+					     PPS_CMD);
+		break;
+	}
+
+	case WE_GET_PPS_EARLY_DTIM_CLEAR:
+	{
+		hdd_debug("GET WMI_VDEV_PPS_EARLY_DTIM_CLEAR");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
+					     PPS_CMD);
+		break;
+	}
+
+	case WE_GET_PPS_EOF_PAD_DELIM:
+	{
+		hdd_debug("GET WMI_VDEV_PPS_EOF_PAD_DELIM");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PPS_EOF_PAD_DELIM,
+					     PPS_CMD);
+		break;
+	}
+
+	case WE_GET_PPS_MACADDR_MISMATCH:
+	{
+		hdd_debug("GET WMI_VDEV_PPS_MACADDR_MISMATCH");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PPS_MACADDR_MISMATCH,
+					     PPS_CMD);
+		break;
+	}
+
+	case WE_GET_PPS_DELIM_CRC_FAIL:
+	{
+		hdd_debug("GET WMI_VDEV_PPS_DELIM_CRC_FAIL");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PPS_DELIM_CRC_FAIL,
+					     PPS_CMD);
+		break;
+	}
+
+	case WE_GET_PPS_GID_NSTS_ZERO:
+	{
+		hdd_debug("GET WMI_VDEV_PPS_GID_NSTS_ZERO");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PPS_GID_NSTS_ZERO,
+					     PPS_CMD);
+		break;
+	}
+
+	case WE_GET_PPS_RSSI_CHECK:
+	{
+
+		hdd_debug("GET WMI_VDEV_PPS_RSSI_CHECK");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PPS_RSSI_CHECK,
+					     PPS_CMD);
+		break;
+	}
+
+	case WE_GET_QPOWER_MAX_PSPOLL_COUNT:
+	{
+		hdd_debug("WE_GET_QPOWER_MAX_PSPOLL_COUNT");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
+					     QPOWER_CMD);
+		break;
+	}
+
+	case WE_GET_QPOWER_MAX_TX_BEFORE_WAKE:
+	{
+		hdd_debug("WE_GET_QPOWER_MAX_TX_BEFORE_WAKE");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
+					     QPOWER_CMD);
+		break;
+	}
+
+	case WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
+	{
+		hdd_debug("WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
+					     QPOWER_CMD);
+		break;
+	}
+
+	case WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
+	{
+		hdd_debug("WE_GET_QPOWER_MAX_PSPOLL_COUNT");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
+					     QPOWER_CMD);
+		break;
+	}
+	case WE_CAP_TSF:
+		ret = hdd_capture_tsf(adapter, (uint32_t *)value, 1);
+		break;
+	case WE_GET_TEMPERATURE:
+	{
+		hdd_debug("WE_GET_TEMPERATURE");
+		ret = wlan_hdd_get_temperature(adapter, value);
+		break;
+	}
+	case WE_GET_DCM:
+		hdd_debug("GET WMI_VDEV_PARAM_HE_DCM");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_HE_DCM,
+					     VDEV_CMD);
+		break;
+	case WE_GET_RANGE_EXT:
+		hdd_debug("GET WMI_VDEV_PARAM_HE_RANGE_EXT");
+		*value = wma_cli_get_command(adapter->session_id,
+					     WMI_VDEV_PARAM_HE_RANGE_EXT,
+					     VDEV_CMD);
+		break;
+	default:
+	{
+		hdd_err("Invalid IOCTL get_value command %d",
+		       value[0]);
+		break;
+	}
+	}
+	hdd_exit();
+	qdf_mem_free(sme_config);
+	return ret;
+}
+
+static int iw_setnone_getint(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_setnone_getint(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int hdd_set_fwtest(int argc, int cmd, int value)
+{
+	struct set_fwtest_params *fw_test;
+
+	/* check for max number of arguments */
+	if (argc > (WMA_MAX_NUM_ARGS) ||
+	    argc != HDD_FWTEST_PARAMS) {
+		hdd_err("Too Many args %d", argc);
+		return -EINVAL;
+	}
+	/*
+	 * check if number of arguments are 3 then, check
+	 * then set the default value for sounding interval.
+	 */
+	if (HDD_FWTEST_PARAMS == argc) {
+		if (HDD_FWTEST_SU_PARAM_ID == cmd && 0 == value)
+			value = HDD_FWTEST_SU_DEFAULT_VALUE;
+		if (HDD_FWTEST_MU_PARAM_ID == cmd && 0 == value)
+			value = HDD_FWTEST_MU_DEFAULT_VALUE;
+	}
+	/* check sounding interval value should not exceed to max */
+	if (value > HDD_FWTEST_MAX_VALUE) {
+		hdd_err("Invalid arguments value should not exceed max: %d",
+			value);
+		return -EINVAL;
+	}
+	fw_test = qdf_mem_malloc(sizeof(*fw_test));
+	if (NULL == fw_test) {
+		hdd_err("qdf_mem_malloc failed for fw_test");
+		return -ENOMEM;
+	}
+	fw_test->arg = cmd;
+	fw_test->value = value;
+	if (QDF_STATUS_SUCCESS != sme_set_fw_test(fw_test)) {
+		qdf_mem_free(fw_test);
+		hdd_err("Not able to post FW_TEST_CMD message to WMA");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * iw_set_three_ints_getnone() - Generic "set 3 params" private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_set_three_ints_getnone(struct net_device *dev,
+				       struct iw_request_info *info,
+				       union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int *value = (int *)extra;
+	int sub_cmd = value[0];
+	int ret;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter_dev(dev);
+
+	if (!capable(CAP_NET_ADMIN)) {
+		hdd_err("permission check failed");
+		return -EPERM;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	switch (sub_cmd) {
+
+	case WE_SET_WLAN_DBG:
+		qdf_print_set_category_verbose(qdf_get_pidx(), value[1],
+					       value[2], value[3]);
+		break;
+	case WE_SET_DP_TRACE:
+		qdf_dp_trace_set_value(value[1], value[2], value[3]);
+		break;
+
+	case WE_SET_DUAL_MAC_SCAN_CONFIG:
+		hdd_debug("Ioctl to set dual mac scan config");
+		if (hdd_ctx->config->dual_mac_feature_disable ==
+				DISABLE_DBS_CXN_AND_SCAN) {
+			hdd_err("Dual mac feature is disabled from INI");
+			return -EPERM;
+		}
+		hdd_debug("%d %d %d", value[1], value[2], value[3]);
+		policy_mgr_set_dual_mac_scan_config(hdd_ctx->psoc,
+			value[1], value[2], value[3]);
+		break;
+	case WE_SET_FW_TEST:
+	{
+		ret = hdd_set_fwtest(value[1], value[2], value[3]);
+		if (ret) {
+			hdd_err("Not able to set fwtest %d", ret);
+			return ret;
+		}
+	}
+	break;
+	default:
+		hdd_err("Invalid IOCTL command %d", sub_cmd);
+		break;
+
+	}
+	hdd_exit();
+	return ret;
+}
+
+int iw_set_three_ints_getnone(struct net_device *dev,
+			      struct iw_request_info *info,
+			      union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_set_three_ints_getnone(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * hdd_connection_state_string() - Get connection state string
+ * @connection_state: enum to be converted to a string
+ *
+ * Return: the string equivalent of @connection_state
+ */
+static const char *
+hdd_connection_state_string(eConnectionState connection_state)
+{
+	switch (connection_state) {
+		CASE_RETURN_STRING(eConnectionState_NotConnected);
+		CASE_RETURN_STRING(eConnectionState_Connecting);
+		CASE_RETURN_STRING(eConnectionState_Associated);
+		CASE_RETURN_STRING(eConnectionState_IbssDisconnected);
+		CASE_RETURN_STRING(eConnectionState_IbssConnected);
+		CASE_RETURN_STRING(eConnectionState_Disconnecting);
+	default:
+		return "UNKNOWN";
+	}
+}
+
+#if defined(FEATURE_OEM_DATA_SUPPORT)
+/**
+ * iw_get_oem_data_cap_wrapper() - wrapper function to call legacy or new
+ * wifi_pos api to get oem data caps
+ * @dev: net device upon which the request was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl data payload
+ *
+ * Return: 0 for success, negative errno value on failure
+ */
+static inline int iw_get_oem_data_cap_wrapper(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *wrqu, char *extra)
+{
+	return iw_get_oem_data_cap(dev, info, wrqu, extra);
+}
+#elif defined(WIFI_POS_CONVERGED)
+static inline int iw_get_oem_data_cap_wrapper(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	return os_if_wifi_pos_populate_caps(hdd_ctx->psoc,
+					(struct wifi_pos_driver_caps *)extra);
+}
+#else
+static inline int iw_get_oem_data_cap_wrapper(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *wrqu, char *extra)
+{
+	return -ENOTSUPP;
+}
+#endif
+
+/**
+ * iw_get_char_setnone() - Generic "get string" private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_get_char_setnone(struct net_device *dev,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int sub_cmd = wrqu->data.flags;
+	struct hdd_context *hdd_ctx;
+	mac_handle_t mac_handle;
+	int ret;
+	QDF_STATUS status;
+	uint8_t value;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	mac_handle = hdd_ctx->mac_handle;
+	switch (sub_cmd) {
+	case WE_WLAN_VERSION:
+	{
+		wrqu->data.length = hdd_wlan_get_version(hdd_ctx,
+							 WE_MAX_STR_LEN, extra);
+		break;
+	}
+
+	case WE_GET_STATS:
+	{
+		hdd_wlan_get_stats(adapter, &(wrqu->data.length),
+				   extra, WE_MAX_STR_LEN);
+		break;
+	}
+
+	case WE_GET_SUSPEND_RESUME_STATS:
+	{
+		ret = wlan_hdd_write_suspend_resume_stats(hdd_ctx, extra,
+							  WE_MAX_STR_LEN);
+		if (ret >= 0) {
+			wrqu->data.length = ret;
+			ret = 0;
+		}
+
+		break;
+	}
+
+	case WE_LIST_FW_PROFILE:
+		hdd_wlan_list_fw_profile(&(wrqu->data.length),
+					extra, WE_MAX_STR_LEN);
+		break;
+
+	/* The case prints the current state of the HDD, SME, CSR, PE,
+	 * TL it can be extended for WDI Global State as well.  And
+	 * currently it only checks P2P_CLIENT adapter.  P2P_DEVICE
+	 * and P2P_GO have not been added as of now.
+	 */
+	case WE_GET_STATES:
+	{
+		int buf = 0, len = 0;
+		int adapter_num = 0;
+		int count = 0, check = 1;
+
+		struct hdd_station_ctx *sta_ctx = NULL;
+
+		struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+		struct hdd_adapter *useAdapter = NULL;
+
+		/* Print wlan0 or p2p0 states based on the adapter_num
+		 * by using the correct adapter
+		 */
+		while (adapter_num < 2) {
+			if (WLAN_ADAPTER == adapter_num) {
+				useAdapter = adapter;
+				buf =
+					scnprintf(extra + len,
+						  WE_MAX_STR_LEN - len,
+						  "\n\n wlan0 States:-");
+				len += buf;
+			} else if (P2P_ADAPTER == adapter_num) {
+				buf =
+					scnprintf(extra + len,
+						  WE_MAX_STR_LEN - len,
+						  "\n\n p2p0 States:-");
+				len += buf;
+
+				if (!hdd_ctx) {
+					buf =
+						scnprintf(extra + len,
+							  WE_MAX_STR_LEN -
+							  len,
+							  "\n hdd_ctx is NULL");
+					len += buf;
+					break;
+				}
+
+				/* Printing p2p0 states only in the
+				 * case when the device is configured
+				 * as a p2p_client
+				 */
+				useAdapter =
+					hdd_get_adapter(hdd_ctx,
+							QDF_P2P_CLIENT_MODE);
+				if (!useAdapter) {
+					buf =
+						scnprintf(extra + len,
+							  WE_MAX_STR_LEN -
+							  len,
+							  "\n Device not configured as P2P_CLIENT.");
+					len += buf;
+					break;
+				}
+			}
+
+			if (!mac_handle) {
+				buf = scnprintf(extra + len,
+						WE_MAX_STR_LEN - len,
+						"\n mac_handle is NULL");
+				len += buf;
+				break;
+			}
+			sta_ctx =
+				WLAN_HDD_GET_STATION_CTX_PTR(useAdapter);
+
+
+			buf =
+				scnprintf(extra + len, WE_MAX_STR_LEN - len,
+					  "\n HDD Conn State - %s "
+					  "\n\n SME State:"
+					  "\n Neighbour Roam State - %s"
+					  "\n CSR State - %s"
+					  "\n CSR Substate - %s",
+					  hdd_connection_state_string
+						  (sta_ctx->conn_info.connState),
+					  mac_trace_get_neighbour_roam_state
+						  (sme_get_neighbor_roam_state
+							  (mac_handle, useAdapter->session_id)),
+					  mac_trace_getcsr_roam_state
+						  (sme_get_current_roam_state
+							  (mac_handle, useAdapter->session_id)),
+					  mac_trace_getcsr_roam_sub_state
+						  (sme_get_current_roam_sub_state
+							  (mac_handle, useAdapter->session_id))
+					  );
+			len += buf;
+			adapter_num++;
+		}
+
+		if (mac_handle) {
+			/* Printing Lim State starting with global lim states */
+			buf =
+				scnprintf(extra + len, WE_MAX_STR_LEN - len,
+					  "\n\n LIM STATES:-"
+					  "\n Global Sme State - %s "
+					  "\n Global mlm State - %s " "\n",
+					  mac_trace_get_lim_sme_state
+						  (sme_get_lim_sme_state(mac_handle)),
+					  mac_trace_get_lim_mlm_state
+						  (sme_get_lim_sme_state(mac_handle))
+					  );
+			len += buf;
+
+			while (check < 3 && count < 255) {
+				if (sme_is_lim_session_valid(mac_handle, count)) {
+					buf =
+						scnprintf(extra + len,
+							  WE_MAX_STR_LEN -
+							  len,
+							  "\n Lim Valid Session %d:-"
+							  "\n PE Sme State - %s "
+							  "\n PE Mlm State - %s "
+							  "\n", check,
+							  mac_trace_get_lim_sme_state
+								  (sme_get_lim_sme_session_state
+									  (mac_handle, count)),
+							  mac_trace_get_lim_mlm_state
+								  (sme_get_lim_mlm_session_state
+									  (mac_handle, count))
+							  );
+
+					len += buf;
+					check++;
+				}
+				count++;
+			}
+		}
+
+		wrqu->data.length = strlen(extra) + 1;
+		break;
+	}
+
+	case WE_GET_CFG:
+	{
+		hdd_debug("Printing CLD global INI Config");
+		hdd_cfg_get_global_config(WLAN_HDD_GET_CTX(adapter),
+					  extra,
+					  QCSAP_IOCTL_MAX_STR_LEN);
+		wrqu->data.length = strlen(extra) + 1;
+		break;
+	}
+	case WE_GET_RSSI:
+	{
+		int8_t s7Rssi = 0;
+
+		wlan_hdd_get_rssi(adapter, &s7Rssi);
+		snprintf(extra, WE_MAX_STR_LEN, "rssi=%d", s7Rssi);
+		wrqu->data.length = strlen(extra) + 1;
+		break;
+	}
+
+	case WE_GET_WMM_STATUS:
+	{
+		snprintf(extra, WE_MAX_STR_LEN,
+			 "\nDir: 0=up, 1=down, 3=both\n"
+			 "|------------------------|\n"
+			 "|AC | ACM |Admitted| Dir |\n"
+			 "|------------------------|\n"
+			 "|VO |  %d  |  %3s   |  %d  |\n"
+			 "|VI |  %d  |  %3s   |  %d  |\n"
+			 "|BE |  %d  |  %3s   |  %d  |\n"
+			 "|BK |  %d  |  %3s   |  %d  |\n"
+			 "|------------------------|\n",
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_VO].wmmAcAccessRequired,
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_VO].
+			 wmmAcAccessAllowed ? "YES" : "NO",
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_VO].wmmAcTspecInfo.
+			 ts_info.direction,
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_VI].wmmAcAccessRequired,
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_VI].
+			 wmmAcAccessAllowed ? "YES" : "NO",
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_VI].wmmAcTspecInfo.
+			 ts_info.direction,
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_BE].wmmAcAccessRequired,
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_BE].
+			 wmmAcAccessAllowed ? "YES" : "NO",
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_BE].wmmAcTspecInfo.
+			 ts_info.direction,
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_BK].wmmAcAccessRequired,
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_BK].
+			 wmmAcAccessAllowed ? "YES" : "NO",
+			 adapter->hdd_wmm_status.
+			 wmmAcStatus[SME_AC_BK].wmmAcTspecInfo.
+			 ts_info.direction);
+
+		wrqu->data.length = strlen(extra) + 1;
+		break;
+	}
+
+	case WE_GET_BA_AGEING_TIMEOUT:
+	{
+		uint8_t ac_cat = 4;
+		uint32_t duration[ac_cat], i;
+		void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+		if (!soc) {
+			hdd_err("Invalid SOC handle");
+			break;
+		}
+
+		for (i = 0; i < ac_cat; i++)
+			cdp_get_ba_timeout(soc, i, &duration[i]);
+
+		snprintf(extra, WE_MAX_STR_LEN,
+			 "\n|------------------------------|\n"
+			 "|AC | BA aging timeout duration |\n"
+			 "|--------------------------------|\n"
+			 "|VO |  %d        |\n"
+			 "|VI |  %d        |\n"
+			 "|BE |  %d        |\n"
+			 "|BK |  %d        |\n"
+			 "|--------------------------------|\n",
+			duration[3], duration[2], duration[1], duration[0]);
+
+		wrqu->data.length = strlen(extra) + 1;
+		break;
+	}
+
+	case WE_GET_CHANNEL_LIST:
+	{
+		QDF_STATUS status;
+		uint8_t i, len;
+		char *buf;
+		uint8_t ubuf[WNI_CFG_COUNTRY_CODE_LEN];
+		uint8_t ubuf_len = WNI_CFG_COUNTRY_CODE_LEN;
+		struct channel_list_info channel_list;
+
+		memset(&channel_list, 0, sizeof(channel_list));
+		status = iw_get_channel_list(dev, info, wrqu,
+						   (char *)&channel_list);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("GetChannelList Failed!!!");
+			return -EINVAL;
+		}
+		buf = extra;
+		/*
+		 * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN.
+		 * Maximum buffer needed = 5 * number of channels.
+		 * Check ifsufficient buffer is available and then
+		 * proceed to fill the buffer.
+		 */
+		if (WE_MAX_STR_LEN <
+		    (5 * WNI_CFG_VALID_CHANNEL_LIST_LEN)) {
+			hdd_err("Insufficient Buffer to populate channel list");
+			return -EINVAL;
+		}
+		len = scnprintf(buf, WE_MAX_STR_LEN, "%u ",
+				channel_list.num_channels);
+		if (QDF_STATUS_SUCCESS == sme_get_country_code(mac_handle,
+							       ubuf,
+							       &ubuf_len)) {
+			/* Printing Country code in getChannelList */
+			for (i = 0; i < (ubuf_len - 1); i++)
+				len += scnprintf(buf + len,
+						WE_MAX_STR_LEN - len,
+						"%c", ubuf[i]);
+		}
+		for (i = 0; i < channel_list.num_channels; i++) {
+			len +=
+				scnprintf(buf + len, WE_MAX_STR_LEN - len,
+					  " %u", channel_list.channels[i]);
+		}
+		wrqu->data.length = strlen(extra) + 1;
+
+		break;
+	}
+#ifdef FEATURE_WLAN_TDLS
+	case WE_GET_TDLS_PEERS:
+	{
+		wrqu->data.length =
+			wlan_hdd_tdls_get_all_peers(adapter, extra,
+						    WE_MAX_STR_LEN) + 1;
+		break;
+	}
+#endif
+#ifdef WLAN_FEATURE_11W
+	case WE_GET_11W_INFO:
+	{
+		struct csr_roam_profile *roam_profile =
+			hdd_roam_profile(adapter);
+
+		hdd_debug("WE_GET_11W_ENABLED = %d",
+		       roam_profile->MFPEnabled);
+
+		snprintf(extra, WE_MAX_STR_LEN,
+			 "\n BSSID %02X:%02X:%02X:%02X:%02X:%02X, Is PMF Assoc? %d"
+			 "\n Number of Unprotected Disassocs %d"
+			 "\n Number of Unprotected Deauths %d",
+			 roam_profile->BSSIDs.bssid->bytes[0],
+			 roam_profile->BSSIDs.bssid->bytes[1],
+			 roam_profile->BSSIDs.bssid->bytes[2],
+			 roam_profile->BSSIDs.bssid->bytes[3],
+			 roam_profile->BSSIDs.bssid->bytes[4],
+			 roam_profile->BSSIDs.bssid->bytes[5],
+			 roam_profile->MFPEnabled,
+			 adapter->hdd_stats.hdd_pmf_stats.
+			 num_unprot_disassoc_rx,
+			 adapter->hdd_stats.hdd_pmf_stats.
+			 num_unprot_deauth_rx);
+
+		wrqu->data.length = strlen(extra) + 1;
+		break;
+	}
+#endif
+	case WE_GET_IBSS_STA_INFO:
+	{
+		struct hdd_station_ctx *sta_ctx =
+			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		int idx = 0;
+		int length = 0, buf = 0;
+
+		for (idx = 0; idx < MAX_PEERS; idx++) {
+			if (HDD_WLAN_INVALID_STA_ID !=
+					sta_ctx->conn_info.staId[idx]) {
+				buf = snprintf
+					      ((extra + length),
+					      WE_MAX_STR_LEN - length,
+					      "\n%d .%02x:%02x:%02x:%02x:%02x:%02x\n",
+					      sta_ctx->conn_info.staId[idx],
+					      sta_ctx->conn_info.
+					      peerMacAddress[idx].bytes[0],
+					      sta_ctx->conn_info.
+					      peerMacAddress[idx].bytes[1],
+					      sta_ctx->conn_info.
+					      peerMacAddress[idx].bytes[2],
+					      sta_ctx->conn_info.
+					      peerMacAddress[idx].bytes[3],
+					      sta_ctx->conn_info.
+					      peerMacAddress[idx].bytes[4],
+					      sta_ctx->conn_info.
+					      peerMacAddress[idx].bytes[5]
+					      );
+				length += buf;
+			}
+		}
+		wrqu->data.length = strlen(extra) + 1;
+		break;
+	}
+	case WE_GET_PHYMODE:
+	{
+		bool ch_bond24 = false, ch_bond5g = false;
+		struct hdd_context *hddctx = WLAN_HDD_GET_CTX(adapter);
+		eCsrPhyMode phymode;
+		enum band_info currBand;
+		tSmeConfigParams *sme_config;
+
+		sme_config = qdf_mem_malloc(sizeof(*sme_config));
+		if (!sme_config) {
+			hdd_err("Out of memory");
+			ret = -ENOMEM;
+			break;
+		}
+
+		sme_get_config_param(mac_handle, sme_config);
+		if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
+		    sme_config->csrConfig.channelBondingMode24GHz)
+			ch_bond24 = true;
+
+		if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
+		    sme_config->csrConfig.channelBondingMode5GHz)
+			ch_bond5g = true;
+
+		qdf_mem_free(sme_config);
+
+		phymode = sme_get_phy_mode(mac_handle);
+		if ((QDF_STATUS_SUCCESS !=
+		     sme_get_freq_band(mac_handle, &currBand))) {
+			hdd_err("Failed to get current band config");
+			return -EIO;
+		}
+
+		switch (phymode) {
+		case eCSR_DOT11_MODE_AUTO:
+			snprintf(extra, WE_MAX_STR_LEN, "AUTO MODE");
+			break;
+		case eCSR_DOT11_MODE_11n:
+		case eCSR_DOT11_MODE_11n_ONLY:
+			if (currBand == BAND_2G) {
+				if (ch_bond24)
+					snprintf(extra, WE_MAX_STR_LEN,
+						 "11NGHT40");
+				else
+					snprintf(extra, WE_MAX_STR_LEN,
+						 "11NGHT20");
+			} else if (currBand == BAND_5G) {
+				if (ch_bond5g)
+					snprintf(extra, WE_MAX_STR_LEN,
+						 "11NAHT40");
+				else
+					snprintf(extra, WE_MAX_STR_LEN,
+						 "11NAHT20");
+			} else {
+				snprintf(extra, WE_MAX_STR_LEN, "11N");
+			}
+			break;
+		case eCSR_DOT11_MODE_abg:
+			snprintf(extra, WE_MAX_STR_LEN, "11ABG");
+			break;
+		case eCSR_DOT11_MODE_11a:
+			snprintf(extra, WE_MAX_STR_LEN, "11A");
+			break;
+		case eCSR_DOT11_MODE_11b:
+		case eCSR_DOT11_MODE_11b_ONLY:
+			snprintf(extra, WE_MAX_STR_LEN, "11B");
+			break;
+		case eCSR_DOT11_MODE_11g:
+		case eCSR_DOT11_MODE_11g_ONLY:
+			snprintf(extra, WE_MAX_STR_LEN, "11G");
+			break;
+		case eCSR_DOT11_MODE_11ac:
+		case eCSR_DOT11_MODE_11ac_ONLY:
+			status =
+			   ucfg_mlme_get_vht_channel_width(hddctx->psoc,
+							   &value);
+			if (!QDF_IS_STATUS_SUCCESS(status))
+				hdd_err("Failed to set channel_width");
+			if (value == eHT_CHANNEL_WIDTH_20MHZ)
+				snprintf(extra, WE_MAX_STR_LEN,
+					 "11ACVHT20");
+			else if (value == eHT_CHANNEL_WIDTH_40MHZ)
+				snprintf(extra, WE_MAX_STR_LEN,
+					 "11ACVHT40");
+			else if (value == eHT_CHANNEL_WIDTH_80MHZ)
+				snprintf(extra, WE_MAX_STR_LEN,
+					 "11ACVHT80");
+			else if (value == eHT_CHANNEL_WIDTH_160MHZ)
+				snprintf(extra, WE_MAX_STR_LEN,
+					 "11ACVHT160");
+			break;
+		case eCSR_DOT11_MODE_11ax:
+		case eCSR_DOT11_MODE_11ax_ONLY:
+			status =
+			ucfg_mlme_get_vht_channel_width(hddctx->psoc,
+							&value);
+			if (!QDF_IS_STATUS_SUCCESS(status))
+				hdd_err("Failed to set channel_width");
+
+			/* currently using vhtChannelWidth */
+			if (value == eHT_CHANNEL_WIDTH_20MHZ)
+				snprintf(extra, WE_MAX_STR_LEN,
+					 "11AX_HE_20");
+			else if (value == eHT_CHANNEL_WIDTH_40MHZ)
+				snprintf(extra, WE_MAX_STR_LEN,
+					 "11AX_HE_40");
+			else if (value == eHT_CHANNEL_WIDTH_80MHZ)
+				snprintf(extra, WE_MAX_STR_LEN,
+					 "11AX_HE_80");
+			else if (value == eHT_CHANNEL_WIDTH_160MHZ)
+				snprintf(extra, WE_MAX_STR_LEN,
+					 "11AX_HE_160");
+			break;
+		}
+
+		wrqu->data.length = strlen(extra) + 1;
+		break;
+	}
+
+	case WE_GET_OEM_DATA_CAP:
+		return iw_get_oem_data_cap_wrapper(dev, info, wrqu, extra);
+	case WE_GET_SNR:
+	{
+		int8_t s7snr = 0;
+		int status = 0;
+		struct hdd_context *hdd_ctx;
+		struct hdd_station_ctx *sta_ctx;
+
+		hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+		status = wlan_hdd_validate_context(hdd_ctx);
+		if (status)
+			return status;
+
+		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+		if (0 == hdd_ctx->config->fEnableSNRMonitoring ||
+		    eConnectionState_Associated !=
+		    sta_ctx->conn_info.connState) {
+			hdd_err("getSNR failed: Enable SNR Monitoring-%d, ConnectionState-%d",
+			       hdd_ctx->config->fEnableSNRMonitoring,
+			       sta_ctx->conn_info.connState);
+			return -ENONET;
+		}
+		wlan_hdd_get_snr(adapter, &s7snr);
+		snprintf(extra, WE_MAX_STR_LEN, "snr=%d", s7snr);
+		wrqu->data.length = strlen(extra) + 1;
+		break;
+	}
+
+	default:
+		hdd_err("Invalid IOCTL command %d", sub_cmd);
+		break;
+	}
+
+	hdd_exit();
+	return ret;
+}
+
+static int iw_get_char_setnone(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_get_char_setnone(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * iw_setnone_getnone() - Generic "action" private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_setnone_getnone(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	mac_handle_t mac_handle;
+	int ret;
+	int sub_cmd;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+#ifdef CONFIG_COMPAT
+	/* this ioctl is a special case where a sub-ioctl is used and both
+	 * the number of get and set args is 0.  in this specific case the
+	 * logic in iwpriv places the sub_cmd in the data.flags portion of
+	 * the iwreq.  unfortunately the location of this field will be
+	 * different between 32-bit and 64-bit userspace, and the standard
+	 * compat support in the kernel does not handle this case.  so we
+	 * need to explicitly handle it here.
+	 */
+	if (in_compat_syscall()) {
+		struct compat_iw_point *compat_iw_point =
+			(struct compat_iw_point *)&wrqu->data;
+		sub_cmd = compat_iw_point->flags;
+	} else {
+		sub_cmd = wrqu->data.flags;
+	}
+#else
+	sub_cmd = wrqu->data.flags;
+#endif
+
+	mac_handle = hdd_ctx->mac_handle;
+	switch (sub_cmd) {
+
+	case WE_GET_RECOVERY_STAT:
+		sme_get_recovery_stats(mac_handle);
+		break;
+
+	case WE_GET_FW_PROFILE_DATA:
+		ret = wma_cli_set_command(adapter->session_id,
+				WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
+				0, DBG_CMD);
+		break;
+
+	case WE_IBSS_GET_PEER_INFO_ALL:
+		hdd_wlan_get_ibss_peer_info_all(adapter);
+		break;
+
+	case WE_SET_REASSOC_TRIGGER:
+	{
+		struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+		tSirMacAddr bssid;
+		uint32_t roamId = INVALID_ROAM_ID;
+		uint8_t operating_ch =
+			adapter->session.station.conn_info.operationChannel;
+		tCsrRoamModifyProfileFields modProfileFields;
+
+		sme_get_modify_profile_fields(mac_handle, adapter->session_id,
+					      &modProfileFields);
+		if (roaming_offload_enabled(hdd_ctx)) {
+			qdf_mem_copy(bssid,
+				&adapter->session.station.conn_info.bssId,
+				sizeof(bssid));
+			hdd_wma_send_fastreassoc_cmd(adapter,
+						     bssid, operating_ch);
+		} else {
+			sme_roam_reassoc(mac_handle, adapter->session_id,
+					 NULL, modProfileFields, &roamId, 1);
+		}
+		return 0;
+	}
+
+	case WE_STOP_OBSS_SCAN:
+		/*
+		 * 1.OBSS Scan is mandatory while operating in 2.4GHz
+		 * 2.OBSS scan is stopped by Firmware during the disassociation
+		 * 3.OBSS stop comamnd is added for debugging purpose
+		 */
+		if (!mac_handle) {
+			hdd_err("mac_handle context is NULL");
+			return -EINVAL;
+		}
+		sme_ht40_stop_obss_scan(mac_handle, adapter->session_id);
+		break;
+
+	default:
+		hdd_err("unknown ioctl %d", sub_cmd);
+		break;
+	}
+	hdd_exit();
+	return ret;
+}
+
+static int iw_setnone_getnone(struct net_device *dev,
+			      struct iw_request_info *info,
+			      union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_setnone_getnone(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef MPC_UT_FRAMEWORK
+static void
+hdd_policy_mgr_set_hw_mode_ut(struct hdd_context *hdd_ctx,
+			      struct hdd_adapter *adapter, int cmd)
+{
+	enum hw_mode_ss_config mac0_ss;
+	enum hw_mode_bandwidth mac0_bw;
+	enum hw_mode_ss_config mac1_ss;
+	enum hw_mode_bandwidth mac1_bw;
+	enum hw_mode_mac_band_cap mac0_band_cap;
+	enum hw_mode_dbs_capab dbs;
+
+	switch (cmd) {
+	case 0:
+		hdd_debug("set hw mode for single mac");
+		mac0_ss = HW_MODE_SS_2x2;
+		mac0_bw = HW_MODE_80_MHZ;
+		mac1_ss = HW_MODE_SS_0x0;
+		mac1_bw = HW_MODE_BW_NONE;
+		mac0_band_cap = HW_MODE_MAC_BAND_NONE;
+		dbs = HW_MODE_DBS_NONE;
+		break;
+	case 1:
+		hdd_debug("set hw mode for dual mac");
+		mac0_ss = HW_MODE_SS_1x1;
+		mac0_bw = HW_MODE_80_MHZ;
+		mac1_ss = HW_MODE_SS_1x1;
+		mac1_bw = HW_MODE_40_MHZ;
+		mac0_band_cap = HW_MODE_MAC_BAND_NONE;
+		dbs = HW_MODE_DBS;
+		break;
+	case 2:
+		hdd_debug("set hw mode for 2x2 5g + 1x1 2g");
+		mac0_ss = HW_MODE_SS_2x2;
+		mac0_bw = HW_MODE_80_MHZ;
+		mac1_ss = HW_MODE_SS_1x1;
+		mac1_bw = HW_MODE_40_MHZ;
+		mac0_band_cap = HW_MODE_MAC_BAND_5G;
+		dbs = HW_MODE_DBS;
+		break;
+	case 3:
+		hdd_debug("set hw mode for 2x2 2g + 1x1 5g");
+		mac0_ss = HW_MODE_SS_2x2;
+		mac0_bw = HW_MODE_40_MHZ;
+		mac1_ss = HW_MODE_SS_1x1;
+		mac1_bw = HW_MODE_40_MHZ;
+		mac0_band_cap = HW_MODE_MAC_BAND_2G;
+		dbs = HW_MODE_DBS;
+		break;
+	default:
+		hdd_err("unknown cmd %d", cmd);
+		return;
+	}
+	policy_mgr_pdev_set_hw_mode(hdd_ctx->psoc, adapter->session_id,
+				    mac0_ss, mac0_bw, mac1_ss, mac1_bw,
+				    mac0_band_cap, dbs, HW_MODE_AGILE_DFS_NONE,
+				    HW_MODE_SBS_NONE,
+				    POLICY_MGR_UPDATE_REASON_UT, PM_NOP);
+}
+
+static int iw_get_policy_manager_ut_ops(struct hdd_context *hdd_ctx,
+			struct hdd_adapter *adapter, int sub_cmd, int *apps_args)
+{
+	switch (sub_cmd) {
+	case WE_POLICY_MANAGER_CLIST_CMD:
+	{
+		hdd_debug("<iwpriv wlan0 pm_clist> is called");
+		if ((apps_args[0] < 0) || (apps_args[1] < 0) ||
+		    (apps_args[2] < 0) || (apps_args[3] < 0) ||
+		    (apps_args[4] < 0) || (apps_args[5] < 0) ||
+		    (apps_args[6] < 0) || (apps_args[7] < 0)) {
+			hdd_err("Invalid input params received for the IOCTL");
+			return 0;
+		}
+		policy_mgr_incr_connection_count_utfw(hdd_ctx->psoc,
+			apps_args[0], apps_args[1], apps_args[2], apps_args[3],
+			apps_args[4], apps_args[5], apps_args[6], apps_args[7]);
+	}
+	break;
+
+	case WE_POLICY_MANAGER_DLIST_CMD:
+	{
+		hdd_debug("<iwpriv wlan0 pm_dlist> is called");
+		if ((apps_args[0] < 0) || (apps_args[1] < 0)) {
+			hdd_err("Invalid input params received for the IOCTL");
+			return 0;
+		}
+		policy_mgr_decr_connection_count_utfw(hdd_ctx->psoc,
+			apps_args[0], apps_args[1]);
+	}
+	break;
+
+	case WE_POLICY_MANAGER_ULIST_CMD:
+	{
+		hdd_debug("<iwpriv wlan0 pm_ulist> is called");
+		if ((apps_args[0] < 0) || (apps_args[1] < 0) ||
+		    (apps_args[2] < 0) || (apps_args[3] < 0) ||
+		    (apps_args[4] < 0) || (apps_args[5] < 0) ||
+		    (apps_args[6] < 0) || (apps_args[7] < 0)) {
+			hdd_err("Invalid input params received for the IOCTL");
+			return 0;
+		}
+		policy_mgr_update_connection_info_utfw(hdd_ctx->psoc,
+			apps_args[0], apps_args[1], apps_args[2], apps_args[3],
+			apps_args[4], apps_args[5], apps_args[6], apps_args[7]);
+	}
+	break;
+
+	case WE_POLICY_MANAGER_DBS_CMD:
+	{
+		hdd_debug("<iwpriv wlan0 pm_dbs> is called");
+		if (apps_args[0] == 0)
+			wma_set_dbs_capability_ut(0);
+		else
+			wma_set_dbs_capability_ut(1);
+
+		if (apps_args[1] >= PM_THROUGHPUT &&
+			apps_args[1] <= PM_LATENCY) {
+			hdd_debug("setting system pref to [%d]\n",
+				  apps_args[1]);
+			ucfg_policy_mgr_set_sys_pref(hdd_ctx->psoc,
+						     apps_args[1]);
+		}
+	}
+	break;
+
+	case WE_POLICY_MANAGER_PCL_CMD:
+	{
+		uint8_t pcl[QDF_MAX_NUM_CHAN] = {0};
+		uint8_t weight_list[QDF_MAX_NUM_CHAN] = {0};
+		uint32_t pcl_len = 0, i = 0;
+
+		hdd_debug("<iwpriv wlan0 pm_pcl> is called");
+
+		if (apps_args[0] < 0) {
+			hdd_err("Invalid input param received for the IOCTL");
+			return 0;
+		}
+		policy_mgr_get_pcl(hdd_ctx->psoc, apps_args[0],
+				pcl, &pcl_len,
+				weight_list, QDF_ARRAY_SIZE(weight_list));
+		hdd_debug("PCL list for role[%d] is {", apps_args[0]);
+		for (i = 0 ; i < pcl_len; i++)
+			hdd_debug(" %d, ", pcl[i]);
+		hdd_debug("}--------->\n");
+	}
+	break;
+
+	case WE_POLICY_SET_HW_MODE_CMD:
+	{
+		hdd_debug("pm_set_hw_mode cmd %d", apps_args[0]);
+		hdd_policy_mgr_set_hw_mode_ut(hdd_ctx, adapter, apps_args[0]);
+	}
+	break;
+
+	case WE_POLICY_MANAGER_QUERY_ACTION_CMD:
+	{
+		hdd_debug("<iwpriv wlan0 pm_query_action> is called");
+		if (apps_args[0] < 0) {
+			hdd_err("Invalid input params received for the IOCTL");
+			return 0;
+		}
+		policy_mgr_current_connections_update(
+			hdd_ctx->psoc,
+			adapter->session_id, apps_args[0],
+			POLICY_MGR_UPDATE_REASON_UT);
+	}
+	break;
+
+	case WE_POLICY_MANAGER_QUERY_ALLOW_CMD:
+	{
+		bool allow;
+
+		hdd_debug("<iwpriv wlan0 pm_query_allow> is called");
+		if ((apps_args[0] < 0) || (apps_args[1] < 0) ||
+		    (apps_args[2] < 0)) {
+			hdd_err("Invalid input params received for the IOCTL");
+			return 0;
+		}
+		allow = policy_mgr_allow_concurrency(hdd_ctx->psoc,
+				apps_args[0], apps_args[1], apps_args[2]);
+		hdd_debug("allow %d {0 = don't allow, 1 = allow}", allow);
+	}
+	break;
+
+	case WE_POLICY_MANAGER_SCENARIO_CMD:
+	{
+		clean_report(hdd_ctx);
+		if (apps_args[0] == 1) {
+			wlan_hdd_one_connection_scenario(hdd_ctx);
+		} else if (apps_args[0] == 2) {
+			wlan_hdd_two_connections_scenario(hdd_ctx,
+				6, POLICY_MGR_TWO_TWO);
+			wlan_hdd_two_connections_scenario(hdd_ctx,
+				36, POLICY_MGR_TWO_TWO);
+			wlan_hdd_two_connections_scenario(hdd_ctx,
+				6, POLICY_MGR_ONE_ONE);
+			wlan_hdd_two_connections_scenario(hdd_ctx,
+				36, POLICY_MGR_ONE_ONE);
+		} else if (apps_args[0] == 3) {
+			/* MCC on same band with 2x2 same mac*/
+			wlan_hdd_three_connections_scenario(hdd_ctx,
+				6, 11, POLICY_MGR_TWO_TWO, 0);
+			/* MCC on diff band with 2x2 same mac*/
+			wlan_hdd_three_connections_scenario(hdd_ctx,
+				6, 36, POLICY_MGR_TWO_TWO, 0);
+			/* MCC on diff band with 1x1 diff mac */
+			wlan_hdd_three_connections_scenario(hdd_ctx,
+				36, 6, POLICY_MGR_ONE_ONE, 0);
+			/* MCC on diff band with 1x1 same mac */
+			wlan_hdd_three_connections_scenario(hdd_ctx,
+				36, 6, POLICY_MGR_ONE_ONE, 1);
+			/* SCC on same band with 2x2 same mac */
+			wlan_hdd_three_connections_scenario(hdd_ctx,
+				36, 36, POLICY_MGR_TWO_TWO, 0);
+			/* SCC on same band with 1x1 same mac */
+			wlan_hdd_three_connections_scenario(hdd_ctx,
+				36, 36, POLICY_MGR_ONE_ONE, 1);
+			/* MCC on same band with 2x2 same mac */
+			wlan_hdd_three_connections_scenario(hdd_ctx,
+				36, 149, POLICY_MGR_TWO_TWO, 0);
+			/* MCC on same band with 1x1 same mac */
+			wlan_hdd_three_connections_scenario(hdd_ctx,
+				36, 149, POLICY_MGR_ONE_ONE, 1);
+		}
+		print_report(hdd_ctx);
+	}
+	break;
+	}
+	return 0;
+}
+#else
+static int iw_get_policy_manager_ut_ops(struct hdd_context *hdd_ctx,
+			struct hdd_adapter *adapter, int sub_cmd, int *apps_args)
+{
+	return 0;
+}
+#endif
+
+/**
+ * hdd_ch_avoid_unit_cmd - unit test ch avoidance
+ * @hdd_ctx: hdd_context
+ * @num_args: input args number
+ * @apps_args: args data ptr
+ *
+ * This is to inject a ch avoid event to do unit test SAP chan avoidance.
+ *
+ * Return: void
+ */
+#if WLAN_DEBUG
+static void hdd_ch_avoid_unit_cmd(struct hdd_context *hdd_ctx,
+				  int num_args, int *apps_args)
+{
+	struct ch_avoid_ind_type ch_avoid;
+	int cnt = 0, i;
+
+	if (num_args < 2 || num_args > CH_AVOID_MAX_RANGE * 2 ||
+	    num_args % 2 != 0)
+		return;
+	hdd_info("simulate ch avoid num_args %d", num_args);
+	for (i = 0; i < num_args && i < CH_AVOID_MAX_RANGE * 2; i++) {
+		ch_avoid.avoid_freq_range[cnt].start_freq =
+			apps_args[i];
+		ch_avoid.avoid_freq_range[cnt].end_freq =
+			apps_args[++i];
+
+		hdd_info("simulate ch avoid [%d %d]",
+			 ch_avoid.avoid_freq_range[cnt].start_freq,
+			 ch_avoid.avoid_freq_range[cnt].end_freq);
+		cnt++;
+	}
+	ch_avoid.ch_avoid_range_cnt = cnt;
+	ucfg_reg_unit_simulate_ch_avoid(hdd_ctx->psoc, &ch_avoid);
+}
+#else
+static void hdd_ch_avoid_unit_cmd(struct hdd_context *hdd_ctx,
+				  int num_args, int *apps_args)
+{
+}
+#endif
+/**
+ * __iw_set_var_ints_getnone - Generic "set many" private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * This is an SSR-protected generic handler for private ioctls which
+ * take multiple arguments.  Note that this implementation is also
+ * somewhat unique in that it is shared by both STA-mode and SAP-mode
+ * interfaces.
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_set_var_ints_getnone(struct net_device *dev,
+				     struct iw_request_info *info,
+				     union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	mac_handle_t mac_handle;
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	int sub_cmd;
+	int *apps_args = (int *) extra;
+	struct hdd_context *hdd_ctx;
+	int ret, num_args;
+	void *soc = NULL;
+	struct cdp_pdev *pdev = NULL;
+	struct cdp_vdev *vdev = NULL;
+	struct cdp_txrx_stats_req req = {0};
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	mac_handle = hdd_ctx->mac_handle;
+	sub_cmd = wrqu->data.flags;
+	num_args = wrqu->data.length;
+
+	hdd_debug("Received length %d", wrqu->data.length);
+
+	switch (sub_cmd) {
+	case WE_IBSS_GET_PEER_INFO:
+	{
+		pr_info("Station ID = %d\n", apps_args[0]);
+		hdd_wlan_get_ibss_peer_info(adapter, apps_args[0]);
+	}
+	break;
+
+	case WE_P2P_NOA_CMD:
+	{
+		struct p2p_app_set_ps p2pNoA;
+
+		if (adapter->device_mode != QDF_P2P_GO_MODE) {
+			hdd_err("Setting NoA is not allowed in Device mode %s(%d)",
+				qdf_opmode_str(adapter->device_mode),
+				adapter->device_mode);
+			return -EINVAL;
+		}
+
+		p2pNoA.opp_ps = apps_args[0];
+		p2pNoA.ctWindow = apps_args[1];
+		p2pNoA.duration = apps_args[2];
+		p2pNoA.interval = apps_args[3];
+		p2pNoA.count = apps_args[4];
+		p2pNoA.single_noa_duration = apps_args[5];
+		p2pNoA.psSelection = apps_args[6];
+
+		hdd_debug("P2P_NOA_ATTR:oppPS %d ctWindow %d duration %d interval %d count %d single noa duration %d PsSelection %x",
+			   apps_args[0], apps_args[1], apps_args[2],
+			   apps_args[3], apps_args[4],
+			   apps_args[5], apps_args[6]);
+
+		hdd_set_p2p_ps(dev, &p2pNoA);
+
+	}
+	break;
+
+	case WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD:
+	{
+		hdd_debug("SELECTIVE_MODULE_LOG %d arg1 %d arg2",
+			   apps_args[0], apps_args[1]);
+		qdf_trace_enable(apps_args[0], apps_args[1]);
+	}
+	break;
+
+	case WE_MTRACE_DUMP_CMD:
+	{
+		hdd_debug("MTRACE_DUMP code %d session %d count %d bitmask_of_module %d ",
+			   apps_args[0], apps_args[1],
+			   apps_args[2], apps_args[3]);
+		qdf_trace_dump_all((void *)mac_handle, apps_args[0],
+				   apps_args[1], apps_args[2],
+				   apps_args[3]);
+
+	}
+	break;
+
+	case WE_POLICY_MANAGER_CINFO_CMD:
+	{
+		struct policy_mgr_conc_connection_info *conn_info;
+		uint32_t i = 0, len = 0;
+
+		hdd_info("<iwpriv wlan0 pm_cinfo> is called");
+		conn_info = policy_mgr_get_conn_info(&len);
+		pr_info("+--------------------------+\n");
+		for (i = 0; i < len; i++) {
+			pr_info("|table_index[%d]\t\t\n", i);
+			pr_info("|\t|vdev_id - %-10d|\n", conn_info->vdev_id);
+			pr_info("|\t|chan    - %-10d|\n", conn_info->chan);
+			pr_info("|\t|bw      - %-10d|\n", conn_info->bw);
+			pr_info("|\t|mode    - %-10d|\n", conn_info->mode);
+			pr_info("|\t|mac     - %-10d|\n", conn_info->mac);
+			pr_info("|\t|in_use  - %-10d|\n", conn_info->in_use);
+			pr_info("+--------------------------+\n");
+			conn_info++;
+		}
+	}
+	break;
+
+	case WE_UNIT_TEST_CMD:
+	{
+		QDF_STATUS status;
+
+		if ((apps_args[0] < WLAN_MODULE_ID_MIN) ||
+		    (apps_args[0] >= WLAN_MODULE_ID_MAX)) {
+			hdd_err("Invalid MODULE ID %d", apps_args[0]);
+			return -EINVAL;
+		}
+		if ((apps_args[1] >= (WMA_MAX_NUM_ARGS)) ||
+		    (apps_args[1] < 0)) {
+			hdd_err("Too Many/Few args %d", apps_args[1]);
+			return -EINVAL;
+		}
+		status = sme_send_unit_test_cmd(adapter->session_id,
+						apps_args[0],
+						apps_args[1],
+						&apps_args[2]);
+		if (QDF_STATUS_SUCCESS != status) {
+			hdd_err("sme_send_unit_test_cmd returned %d", status);
+			return -EINVAL;
+		}
+	}
+	break;
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+	case WE_LED_FLASHING_PARAM:
+	{
+		int i;
+
+		if (num_args != 4) {
+			hdd_err("gpio_control: 4 parameters are required");
+			return -EINVAL;
+		}
+		for (i = 0; i < num_args; i++) {
+			if (apps_args[i] >= 0x7fffffff) {
+				hdd_err("gpio_control: parameter should be less than 0x7fffffff");
+				return -EINVAL;
+			}
+		}
+		sme_set_led_flashing(mac_handle,
+				     0, apps_args[0], apps_args[1]);
+		sme_set_led_flashing(mac_handle,
+				     1, apps_args[2], apps_args[3]);
+	}
+	break;
+#endif
+	case WE_SET_PKTLOG:
+	{
+		int ret;
+
+		if (num_args < 1 || num_args > 2) {
+			hdd_err("pktlog: either 1 or 2 parameters are required");
+			return -EINVAL;
+		}
+
+		ret = hdd_process_pktlog_command(hdd_ctx, apps_args[0],
+						   apps_args[1]);
+		if (ret)
+			return ret;
+		break;
+	}
+	case WE_MAC_PWR_DEBUG_CMD:
+	{
+		struct sir_mac_pwr_dbg_cmd mac_pwr_dbg_args;
+		int i, j;
+
+		if (num_args < 3) {
+			hdd_err("number of arguments can't be null %d",
+				num_args);
+			return -EINVAL;
+		}
+		if (num_args - 3 != apps_args[2]) {
+			hdd_err("arg list of size %d doesn't match num_args %d",
+				num_args-3, apps_args[2]);
+			return -EINVAL;
+		}
+		if ((apps_args[1] < WLAN_MODULE_ID_MIN) ||
+		    (apps_args[1] >= WLAN_MODULE_ID_MAX)) {
+			hdd_err("Invalid MODULE ID %d", apps_args[1]);
+			return -EINVAL;
+		}
+		if (apps_args[2] > (MAX_POWER_DBG_ARGS_SUPPORTED)) {
+			hdd_err("Too Many args %d", apps_args[2]);
+			return -EINVAL;
+		}
+		mac_pwr_dbg_args.pdev_id = apps_args[0];
+		mac_pwr_dbg_args.module_id = apps_args[1];
+		mac_pwr_dbg_args.num_args = apps_args[2];
+
+		for (i = 0, j = 3; i < mac_pwr_dbg_args.num_args; i++, j++)
+			mac_pwr_dbg_args.args[i] = apps_args[j];
+
+		if (QDF_STATUS_SUCCESS !=
+			sme_process_mac_pwr_dbg_cmd(mac_handle,
+						    adapter->session_id,
+						    &mac_pwr_dbg_args)) {
+			return -EINVAL;
+		}
+	}
+	break;
+	case WE_POLICY_MANAGER_CLIST_CMD:
+	case WE_POLICY_MANAGER_DLIST_CMD:
+	case WE_POLICY_MANAGER_ULIST_CMD:
+	case WE_POLICY_MANAGER_DBS_CMD:
+	case WE_POLICY_MANAGER_PCL_CMD:
+	case WE_POLICY_SET_HW_MODE_CMD:
+	case WE_POLICY_MANAGER_QUERY_ACTION_CMD:
+	case WE_POLICY_MANAGER_QUERY_ALLOW_CMD:
+	case WE_POLICY_MANAGER_SCENARIO_CMD:
+	{
+		if (!hdd_ctx->config->is_unit_test_framework_enabled) {
+			hdd_warn_rl("UT framework is disabled");
+			return -EINVAL;
+		}
+		iw_get_policy_manager_ut_ops(hdd_ctx, adapter,
+				sub_cmd, apps_args);
+	}
+	break;
+	case WE_SET_CHAN_AVOID:
+	{
+		hdd_ch_avoid_unit_cmd(hdd_ctx, num_args, apps_args);
+	}
+	break;
+	case WE_SET_TXRX_STATS:
+	{
+		ret = cds_get_datapath_handles(&soc, &pdev, &vdev,
+					       adapter->session_id);
+
+		if (ret != 0) {
+			hdd_err("Invalid handles");
+			break;
+		}
+
+		req.stats = apps_args[0];
+		/* default value of secondary parameter is 0(mac_id) */
+		req.mac_id = apps_args[1];
+
+		hdd_debug("WE_SET_TXRX_STATS stats cmd: %d mac_id: %d",
+			  req.stats, req.mac_id);
+		if (apps_args[0] == CDP_TXRX_STATS_28) {
+			if (sta_ctx->conn_info.uIsAuthenticated) {
+				hdd_debug("ap mac addr: %pM",
+					  (void *)&sta_ctx->conn_info.bssId);
+				req.peer_addr =
+					(char *)&sta_ctx->conn_info.bssId;
+			}
+		}
+		ret = cdp_txrx_stats_request(soc, vdev, &req);
+		break;
+	}
+	default:
+	{
+		hdd_err("Invalid IOCTL command %d", sub_cmd);
+	}
+	break;
+	}
+	hdd_exit();
+	return 0;
+}
+
+/**
+ * iw_hdd_set_var_ints_getnone() - set var ints getnone callback
+ * @dev: pointer to net_device structure
+ * @info: pointer to iw_request_info structure
+ * @wrqu: pointer to iwreq_data
+ * @extra; extra
+ *
+ * Return: 0 on success, error number otherwise
+ *
+ */
+static int iw_hdd_set_var_ints_getnone(struct net_device *dev,
+				       struct iw_request_info *info,
+				       union iwreq_data *wrqu, char *extra)
+{
+	union iwreq_data u_priv_wrqu;
+	int apps_args[MAX_VAR_ARGS] = {0};
+	int ret, num_args;
+
+	if (!capable(CAP_NET_ADMIN)) {
+		hdd_err("permission check failed");
+		return -EPERM;
+	}
+
+	/* Helper function to get iwreq_data with compat handling. */
+	if (hdd_priv_get_data(&u_priv_wrqu.data, wrqu))
+		return -EINVAL;
+
+	if (NULL == u_priv_wrqu.data.pointer) {
+		hdd_err("NULL data pointer");
+		return -EINVAL;
+	}
+
+	num_args = u_priv_wrqu.data.length;
+	if (num_args > MAX_VAR_ARGS)
+		num_args = MAX_VAR_ARGS;
+
+	if (copy_from_user(apps_args, u_priv_wrqu.data.pointer,
+			  (sizeof(int)) * num_args)) {
+		hdd_err("failed to copy data from user buffer");
+		return -EFAULT;
+	}
+
+	cds_ssr_protect(__func__);
+	ret = __iw_set_var_ints_getnone(dev, info, &u_priv_wrqu,
+					(char *)&apps_args);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
+
+/**
+ * iw_set_var_ints_getnone - Generic "set many" private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * This is a generic handler for private ioctls which take multiple
+ * arguments.  Note that this implementation is also somewhat unique
+ * in that it is shared by both STA-mode and SAP-mode interfaces.
+ *
+ * Return: 0 on success, non-zero on error
+ */
+int iw_set_var_ints_getnone(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_set_var_ints_getnone(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
+
+/**
+ * iw_add_tspec - Add TSpec private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_add_tspec(struct net_device *dev, struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
+	int params[HDD_WLAN_WMM_PARAM_COUNT];
+	struct sme_qos_wmmtspecinfo tSpec;
+	uint32_t handle;
+	struct iw_point s_priv_data;
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	/* make sure the application is sufficiently priviledged */
+	/* note that the kernel will do this for "set" ioctls, but since */
+	/* this ioctl wants to return status to user space it must be */
+	/* defined as a "get" ioctl */
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	/* we must be associated in order to add a tspec */
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		*pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+		return 0;
+	}
+	/* since we are defined to be a "get" ioctl, and since the number */
+	/* of params exceeds the number of params that wireless extensions */
+	/* will pass down in the iwreq_data, we must copy the "set" params. */
+	/* We must handle the compat for iwreq_data in 32U/64K environment. */
+
+	/* helper function to get iwreq_data with compat handling. */
+	if (hdd_priv_get_data(&s_priv_data, wrqu)) {
+		*pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+		return 0;
+	}
+	/* make sure all params are correctly passed to function */
+	if ((NULL == s_priv_data.pointer) ||
+	    (HDD_WLAN_WMM_PARAM_COUNT != s_priv_data.length)) {
+		*pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+		return 0;
+	}
+	/* from user space ourselves */
+	if (copy_from_user(&params, s_priv_data.pointer, sizeof(params))) {
+		/* hmmm, can't get them */
+		return -EIO;
+	}
+	/* clear the tspec */
+	memset(&tSpec, 0, sizeof(tSpec));
+
+	/* validate the handle */
+	handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
+	if (HDD_WMM_HANDLE_IMPLICIT == handle) {
+		/* that one is reserved */
+		*pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+		return 0;
+	}
+	/* validate the TID */
+	if (params[HDD_WLAN_WMM_PARAM_TID] > 7) {
+		/* out of range */
+		*pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+		return 0;
+	}
+	tSpec.ts_info.tid = params[HDD_WLAN_WMM_PARAM_TID];
+
+	/* validate the direction */
+	switch (params[HDD_WLAN_WMM_PARAM_DIRECTION]) {
+	case HDD_WLAN_WMM_DIRECTION_UPSTREAM:
+		tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_UPLINK;
+		break;
+
+	case HDD_WLAN_WMM_DIRECTION_DOWNSTREAM:
+		tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_DOWNLINK;
+		break;
+
+	case HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL:
+		tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH;
+		break;
+
+	default:
+		/* unknown */
+		*pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+		return 0;
+	}
+
+	tSpec.ts_info.psb = params[HDD_WLAN_WMM_PARAM_APSD];
+
+	/* validate the user priority */
+	if (params[HDD_WLAN_WMM_PARAM_USER_PRIORITY] >= SME_QOS_WMM_UP_MAX) {
+		/* out of range */
+		*pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+		return 0;
+	}
+	tSpec.ts_info.up = params[HDD_WLAN_WMM_PARAM_USER_PRIORITY];
+	if (0 > tSpec.ts_info.up || SME_QOS_WMM_UP_MAX < tSpec.ts_info.up) {
+		hdd_err("***ts_info.up out of bounds***");
+		return 0;
+	}
+
+	hdd_debug("TS_INFO PSB %d UP %d !!!",
+		  tSpec.ts_info.psb, tSpec.ts_info.up);
+
+	tSpec.nominal_msdu_size = params[HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE];
+	tSpec.maximum_msdu_size = params[HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE];
+	tSpec.min_data_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE];
+	tSpec.mean_data_rate = params[HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE];
+	tSpec.peak_data_rate = params[HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE];
+	tSpec.max_burst_size = params[HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE];
+	tSpec.min_phy_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE];
+	tSpec.surplus_bw_allowance =
+		params[HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE];
+	tSpec.min_service_interval =
+		params[HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL];
+	tSpec.max_service_interval =
+		params[HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL];
+	tSpec.suspension_interval =
+		params[HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL];
+	tSpec.inactivity_interval =
+		params[HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL];
+
+	tSpec.ts_info.burst_size_defn =
+		params[HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN];
+
+	/* validate the ts info ack policy */
+	switch (params[HDD_WLAN_WMM_PARAM_ACK_POLICY]) {
+	case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
+		tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
+		break;
+
+	case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
+		tSpec.ts_info.ack_policy =
+			SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
+		break;
+
+	default:
+		/* unknown */
+		*pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+		return 0;
+	}
+
+	*pStatus = hdd_wmm_addts(adapter, handle, &tSpec);
+	hdd_exit();
+	return 0;
+}
+
+static int iw_add_tspec(struct net_device *dev,
+			struct iw_request_info *info,
+			union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_add_tspec(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * iw_del_tspec - Delete TSpec private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_del_tspec(struct net_device *dev, struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	int *params = (int *)extra;
+	hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
+	uint32_t handle;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	/* make sure the application is sufficiently priviledged */
+	/* note that the kernel will do this for "set" ioctls, but since */
+	/* this ioctl wants to return status to user space it must be */
+	/* defined as a "get" ioctl */
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	/* although we are defined to be a "get" ioctl, the params we require */
+	/* will fit in the iwreq_data, therefore unlike iw_add_tspec() there */
+	/* is no need to copy the params from user space */
+
+	/* validate the handle */
+	handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
+	if (HDD_WMM_HANDLE_IMPLICIT == handle) {
+		/* that one is reserved */
+		*pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+		return 0;
+	}
+
+	*pStatus = hdd_wmm_delts(adapter, handle);
+	hdd_exit();
+	return 0;
+}
+
+static int iw_del_tspec(struct net_device *dev,
+			struct iw_request_info *info,
+			union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_del_tspec(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * iw_get_tspec - Get TSpec private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_get_tspec(struct net_device *dev, struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	int *params = (int *)extra;
+	hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
+	uint32_t handle;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	/* although we are defined to be a "get" ioctl, the params we require */
+	/* will fit in the iwreq_data, therefore unlike iw_add_tspec() there */
+	/* is no need to copy the params from user space */
+
+	/* validate the handle */
+	handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
+	if (HDD_WMM_HANDLE_IMPLICIT == handle) {
+		/* that one is reserved */
+		*pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+		return 0;
+	}
+
+	*pStatus = hdd_wmm_checkts(adapter, handle);
+	hdd_exit();
+	return 0;
+}
+
+static int iw_get_tspec(struct net_device *dev,
+			struct iw_request_info *info,
+			union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_get_tspec(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * iw_set_fties - Set FT IEs private ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Each time the supplicant has the auth_request or reassoc request
+ * IEs ready they are pushed to the driver. The driver will in turn
+ * use it to send out the auth req and reassoc req for 11r FT Assoc.
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_set_fties(struct net_device *dev, struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	if (!wrqu->data.length) {
+		hdd_err("called with 0 length IEs");
+		return -EINVAL;
+	}
+	if (wrqu->data.pointer == NULL) {
+		hdd_err("called with NULL IE");
+		return -EINVAL;
+	}
+	/* Added for debug on reception of Re-assoc Req. */
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		hdd_debug("Called with Ie of length = %d when not associated",
+		       wrqu->data.length);
+		hdd_debug("Should be Re-assoc Req IEs");
+	}
+	hdd_debug("called with Ie of length = %d", wrqu->data.length);
+
+	/* Pass the received FT IEs to SME */
+	sme_set_ft_ies(hdd_ctx->mac_handle, adapter->session_id,
+		       extra, wrqu->data.length);
+	hdd_exit();
+	return 0;
+}
+
+static int iw_set_fties(struct net_device *dev,
+			struct iw_request_info *info,
+			union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_set_fties(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * iw_set_dynamic_mcbc_filter() - Set Dynamic MCBC Filter ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * This IOCTL is OBSOLETE as of Jan 30, 2017. We are leaving it here for the
+ * time being to provide guidance in migrating to standard APIs.
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int iw_set_dynamic_mcbc_filter(struct net_device *dev,
+				      struct iw_request_info *info,
+				      union iwreq_data *wrqu,
+				      char *extra)
+{
+	hdd_err("\n"
+		"setMCBCFilter is obsolete. Use the following instead:\n"
+		"Configure multicast filtering via the ‘ip’ command.\n"
+		"\tip maddr add 11:22:33:44:55:66 dev wlan0 # allow traffic to address\n"
+		"\tip maddr del 11:22:33:44:55:66 dev wlan0 # undo allow\n"
+		"Configure broadcast filtering via ini item, 'g_enable_non_arp_bc_hw_filter.'\n"
+		"\tg_enable_non_arp_bc_hw_filter=1 # drop all non-ARP broadcast traffic\n"
+		"\tg_enable_non_arp_bc_hw_filter=0 # allow all broadcast traffic");
+	return -EINVAL;
+}
+
+/**
+ * iw_set_host_offload - Set host offload ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_set_host_offload(struct net_device *dev,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct host_offload_req *pRequest = (struct host_offload_req *) extra;
+	tSirHostOffloadReq offloadRequest;
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
+		hdd_err("dev is not in CONNECTED state, ignore!!!");
+		return -EINVAL;
+	}
+
+	/* Debug display of request components. */
+	switch (pRequest->offloadType) {
+	case WLAN_IPV4_ARP_REPLY_OFFLOAD:
+		hdd_debug("Host offload request: ARP reply");
+		switch (pRequest->enableOrDisable) {
+		case WLAN_OFFLOAD_DISABLE:
+			hdd_debug("   disable");
+			break;
+		case WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE:
+			hdd_debug("   BC Filtering enable");
+			/* fallthrough */
+		case WLAN_OFFLOAD_ENABLE:
+			hdd_debug("   ARP offload enable");
+			hdd_debug("   IP address: %d.%d.%d.%d",
+			       pRequest->params.hostIpv4Addr[0],
+			       pRequest->params.hostIpv4Addr[1],
+			       pRequest->params.hostIpv4Addr[2],
+			       pRequest->params.hostIpv4Addr[3]);
+		}
+		break;
+
+	case WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD:
+		hdd_debug("Host offload request: neighbor discovery");
+		switch (pRequest->enableOrDisable) {
+		case WLAN_OFFLOAD_DISABLE:
+			hdd_debug("   disable");
+			break;
+		case WLAN_OFFLOAD_ENABLE:
+			hdd_debug("   enable");
+			hdd_debug("   IP address: %x:%x:%x:%x:%x:%x:%x:%x",
+			       *(uint16_t *) (pRequest->params.hostIpv6Addr),
+			       *(uint16_t *) (pRequest->params.hostIpv6Addr +
+					      2),
+			       *(uint16_t *) (pRequest->params.hostIpv6Addr +
+					      4),
+			       *(uint16_t *) (pRequest->params.hostIpv6Addr +
+					      6),
+			       *(uint16_t *) (pRequest->params.hostIpv6Addr +
+					      8),
+			       *(uint16_t *) (pRequest->params.hostIpv6Addr +
+					      10),
+			       *(uint16_t *) (pRequest->params.hostIpv6Addr +
+					      12),
+			       *(uint16_t *) (pRequest->params.hostIpv6Addr +
+					      14));
+		}
+	}
+
+	qdf_mem_zero(&offloadRequest, sizeof(offloadRequest));
+	offloadRequest.offloadType = pRequest->offloadType;
+	offloadRequest.enableOrDisable = pRequest->enableOrDisable;
+	qdf_mem_copy(&offloadRequest.params, &pRequest->params,
+		     sizeof(pRequest->params));
+	qdf_mem_copy(&offloadRequest.bssid, &pRequest->bssId.bytes,
+		     QDF_MAC_ADDR_SIZE);
+
+	if (QDF_STATUS_SUCCESS !=
+	    sme_set_host_offload(hdd_ctx->mac_handle,
+				 adapter->session_id, &offloadRequest)) {
+		hdd_err("Failure to execute host offload request");
+		return -EINVAL;
+	}
+	hdd_exit();
+	return 0;
+}
+
+static int iw_set_host_offload(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_set_host_offload(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * iw_set_keepalive_params - Set keepalive params ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_set_keepalive_params(struct net_device *dev,
+				     struct iw_request_info *info,
+				     union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	tpSirKeepAliveReq request = (tpSirKeepAliveReq) extra;
+	struct hdd_context *hdd_ctx;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	if (wrqu->data.length != sizeof(*request)) {
+		hdd_err("Invalid length %d", wrqu->data.length);
+		return -EINVAL;
+	}
+
+	if (request->timePeriod > cfg_max(CFG_INFRA_STA_KEEP_ALIVE_PERIOD)) {
+		hdd_err("Value of timePeriod %d exceed Max limit %d",
+			request->timePeriod,
+			cfg_max(CFG_INFRA_STA_KEEP_ALIVE_PERIOD));
+		return -EINVAL;
+	}
+
+	/* Debug display of request components. */
+	hdd_debug("Set Keep Alive Request : TimePeriod %d size %zu",
+		request->timePeriod, sizeof(tSirKeepAliveReq));
+
+	switch (request->packetType) {
+	case WLAN_KEEP_ALIVE_NULL_PKT:
+		hdd_debug("Keep Alive Request: Tx NULL");
+		break;
+
+	case WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP:
+		hdd_debug("Keep Alive Request: Tx UnSolicited ARP RSP");
+
+		hdd_debug("Host IP address: %d.%d.%d.%d",
+		       request->hostIpv4Addr[0], request->hostIpv4Addr[1],
+		       request->hostIpv4Addr[2], request->hostIpv4Addr[3]);
+
+		hdd_debug("Dest IP address: %d.%d.%d.%d",
+		       request->destIpv4Addr[0], request->destIpv4Addr[1],
+		       request->destIpv4Addr[2], request->destIpv4Addr[3]);
+
+		hdd_debug("Dest MAC address: "MAC_ADDRESS_STR,
+		       MAC_ADDR_ARRAY(request->dest_macaddr.bytes));
+		break;
+	}
+
+	hdd_debug("Keep alive period  %d", request->timePeriod);
+
+	if (QDF_STATUS_SUCCESS !=
+	    sme_set_keep_alive(hdd_ctx->mac_handle,
+			       adapter->session_id, request)) {
+		hdd_err("Failure to execute Keep Alive");
+		return -EINVAL;
+	}
+	hdd_exit();
+	return 0;
+}
+
+static int iw_set_keepalive_params(struct net_device *dev,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu,
+				   char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_set_keepalive_params(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+/**
+ * validate_packet_filter_params_size() - Validate the size of the params rcvd
+ * @priv_data: Pointer to the priv data from user space
+ * @request: Pointer to the struct containing the copied data from user space
+ *
+ * Return: False on invalid length, true otherwise
+ */
+static bool validate_packet_filter_params_size(struct pkt_filter_cfg *request,
+					       uint16_t length)
+{
+	int max_params_size, rcvd_params_size;
+
+	max_params_size = HDD_MAX_CMP_PER_PACKET_FILTER *
+					sizeof(struct pkt_filter_param_cfg);
+
+	if (length < sizeof(struct pkt_filter_cfg) - max_params_size) {
+		hdd_err("Less than minimum number of arguments needed");
+		return false;
+	}
+
+	rcvd_params_size = request->num_params *
+					sizeof(struct pkt_filter_param_cfg);
+
+	if (length != sizeof(struct pkt_filter_cfg) -
+					max_params_size + rcvd_params_size) {
+		hdd_err("Arguments do not match the number of params provided");
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * __iw_set_packet_filter_params() - set packet filter parameters in target
+ * @dev: Pointer to netdev
+ * @info: Pointer to iw request info
+ * @wrqu: Pointer to data
+ * @extra: Pointer to extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int __iw_set_packet_filter_params(struct net_device *dev,
+				       struct iw_request_info *info,
+				       union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+	struct hdd_context *hdd_ctx;
+	struct iw_point priv_data;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct pkt_filter_cfg *request = NULL;
+
+	if (!capable(CAP_NET_ADMIN)) {
+		hdd_err("permission check failed");
+		return -EPERM;
+	}
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	if (hdd_priv_get_data(&priv_data, wrqu)) {
+		hdd_err("failed to get priv data");
+		return -EINVAL;
+	}
+
+	if ((NULL == priv_data.pointer) || (0 == priv_data.length)) {
+		hdd_err("invalid priv data %pK or invalid priv data length %d",
+			priv_data.pointer, priv_data.length);
+		return -EINVAL;
+	}
+
+	if (adapter->device_mode != QDF_STA_MODE) {
+		hdd_err("Packet filter not supported for this mode :%d",
+			adapter->device_mode);
+		return -ENOTSUPP;
+	}
+
+	if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
+		hdd_err("Packet filter not supported in disconnected state");
+		return -ENOTSUPP;
+	}
+
+	/* copy data using copy_from_user */
+	request = mem_alloc_copy_from_user_helper(priv_data.pointer,
+						   priv_data.length);
+
+	if (NULL == request) {
+		hdd_err("mem_alloc_copy_from_user_helper fail");
+		return -ENOMEM;
+	}
+
+	if (!validate_packet_filter_params_size(request, priv_data.length)) {
+		hdd_err("Invalid priv data length %d", priv_data.length);
+		qdf_mem_free(request);
+		return -EINVAL;
+	}
+
+	if (request->filter_action == HDD_RCV_FILTER_SET)
+		hdd_ctx->user_configured_pkt_filter_rules |=
+					1 << request->filter_id;
+	else if (request->filter_action == HDD_RCV_FILTER_CLEAR)
+		hdd_ctx->user_configured_pkt_filter_rules &=
+					~(1 << request->filter_id);
+
+	ret = wlan_hdd_set_filter(hdd_ctx, request, adapter->session_id);
+
+	qdf_mem_free(request);
+	hdd_exit();
+	return ret;
+}
+
+/**
+ * iw_set_packet_filter_params() - set packet filter parameters in target
+ * @dev: Pointer to netdev
+ * @info: Pointer to iw request info
+ * @wrqu: Pointer to data
+ * @extra: Pointer to extra data
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int iw_set_packet_filter_params(struct net_device *dev,
+				       struct iw_request_info *info,
+				       union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_set_packet_filter_params(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
+#ifdef QCA_SUPPORT_CP_STATS
+static int hdd_get_wlan_stats(struct hdd_adapter *adapter)
+{
+	return wlan_hdd_get_station_stats(adapter);
+}
+#else /* QCA_SUPPORT_CP_STATS */
+struct hdd_statistics_priv {
+	tCsrSummaryStatsInfo summary_stats;
+	tCsrGlobalClassAStatsInfo class_a_stats;
+	tCsrGlobalClassDStatsInfo class_d_stats;
+};
+
+/**
+ * hdd_statistics_cb() - "Get statistics" callback function
+ * @stats: statistics payload
+ * @context: opaque context originally passed to SME.  HDD always passes
+ *	a cookie for the request context
+ *
+ * Return: None
+ */
+static void hdd_statistics_cb(void *stats, void *context)
+{
+	struct osif_request *request;
+	struct hdd_statistics_priv *priv;
+	tCsrSummaryStatsInfo *summary_stats;
+	tCsrGlobalClassAStatsInfo *class_a_stats;
+	tCsrGlobalClassDStatsInfo *class_d_stats;
+
+	request = osif_request_get(context);
+	if (!request) {
+		hdd_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+
+	summary_stats = (tCsrSummaryStatsInfo *)stats;
+	priv->summary_stats = *summary_stats;
+
+	class_a_stats = (tCsrGlobalClassAStatsInfo *)(summary_stats + 1);
+	priv->class_a_stats = *class_a_stats;
+
+	class_d_stats = (tCsrGlobalClassDStatsInfo *)(class_a_stats + 1);
+	priv->class_d_stats = *class_d_stats;
+
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+static int hdd_get_wlan_stats(struct hdd_adapter *adapter)
+{
+	int ret = 0;
+	void *cookie;
+	QDF_STATUS status;
+	struct osif_request *request;
+	struct hdd_station_ctx *sta_ctx;
+	struct hdd_statistics_priv *priv;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_STATS,
+	};
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	request = osif_request_alloc(&params);
+	if (!request) {
+		hdd_warn("request allocation failed");
+		return -EINVAL;
+	}
+
+	cookie = osif_request_cookie(request);
+	status = sme_get_statistics(hdd_ctx->mac_handle, eCSR_HDD,
+				    SME_SUMMARY_STATS |
+				    SME_GLOBAL_CLASSA_STATS |
+				    SME_GLOBAL_CLASSD_STATS,
+				    hdd_statistics_cb,
+				    sta_ctx->conn_info.staId[0],
+				    cookie, adapter->session_id);
+
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_warn("Unable to retrieve SME statistics");
+		goto put_request;
+	}
+
+	/* request was sent -- wait for the response */
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		hdd_err("Failed to wait for statistics, errno %d", ret);
+		goto put_request;
+	}
+
+	/* update the adapter cache with the fresh results */
+	priv = osif_request_priv(request);
+	adapter->hdd_stats.summary_stat = priv->summary_stats;
+	adapter->hdd_stats.class_a_stat = priv->class_a_stats;
+	adapter->hdd_stats.class_d_stat = priv->class_d_stats;
+
+put_request:
+	/*
+	 * either we never sent a request, we sent a request and
+	 * received a response or we sent a request and timed out.
+	 * regardless we are done with the request.
+	 */
+	osif_request_put(request);
+	return ret;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+static int __iw_get_statistics(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+	char *p;
+	int tlen;
+	struct hdd_station_ctx *sta_ctx;
+	tCsrSummaryStatsInfo *summary_stats;
+	tCsrGlobalClassAStatsInfo *class_a_stats;
+	tCsrGlobalClassDStatsInfo *class_d_stats;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		wrqu->data.length = 0;
+		return 0;
+	}
+
+	hdd_get_wlan_stats(adapter);
+
+	summary_stats = &(adapter->hdd_stats.summary_stat);
+	class_a_stats = &(adapter->hdd_stats.class_a_stat);
+	class_d_stats = &(adapter->hdd_stats.class_d_stat);
+
+	p = extra;
+	tlen = 0;
+
+	FILL_TLV(p, WLAN_STATS_RETRY_CNT,
+		 sizeof(summary_stats->retry_cnt),
+		 &(summary_stats->retry_cnt[0]), tlen);
+
+	FILL_TLV(p, WLAN_STATS_MUL_RETRY_CNT,
+		 sizeof(summary_stats->multiple_retry_cnt),
+		 &(summary_stats->multiple_retry_cnt[0]), tlen);
+
+	FILL_TLV(p, WLAN_STATS_TX_FRM_CNT,
+		 sizeof(summary_stats->tx_frm_cnt),
+		 &(summary_stats->tx_frm_cnt[0]), tlen);
+
+	FILL_TLV(p, WLAN_STATS_RX_FRM_CNT,
+		 sizeof(summary_stats->rx_frm_cnt),
+		 &(summary_stats->rx_frm_cnt), tlen);
+
+	FILL_TLV(p, WLAN_STATS_FRM_DUP_CNT,
+		 sizeof(summary_stats->frm_dup_cnt),
+		 &(summary_stats->frm_dup_cnt), tlen);
+
+	FILL_TLV(p, WLAN_STATS_FAIL_CNT,
+		 sizeof(summary_stats->fail_cnt),
+		 &(summary_stats->fail_cnt[0]), tlen);
+
+	FILL_TLV(p, WLAN_STATS_RTS_FAIL_CNT,
+		 sizeof(summary_stats->rts_fail_cnt),
+		 &(summary_stats->rts_fail_cnt), tlen);
+
+	FILL_TLV(p, WLAN_STATS_ACK_FAIL_CNT,
+		 sizeof(summary_stats->ack_fail_cnt),
+		 &(summary_stats->ack_fail_cnt), tlen);
+
+	FILL_TLV(p, WLAN_STATS_RTS_SUC_CNT,
+		 sizeof(summary_stats->rts_succ_cnt),
+		 &(summary_stats->rts_succ_cnt), tlen);
+
+	FILL_TLV(p, WLAN_STATS_RX_DISCARD_CNT,
+		 sizeof(summary_stats->rx_discard_cnt),
+		 &(summary_stats->rx_discard_cnt), tlen);
+
+	FILL_TLV(p, WLAN_STATS_RX_ERROR_CNT,
+		 sizeof(summary_stats->rx_error_cnt),
+		 &(summary_stats->rx_error_cnt), tlen);
+
+	FILL_TLV(p, WLAN_STATS_TX_BYTE_CNT,
+		 sizeof(class_d_stats->tx_uc_byte_cnt[0]),
+		 &(class_d_stats->tx_uc_byte_cnt[0]), tlen);
+
+	FILL_TLV(p, WLAN_STATS_RX_BYTE_CNT,
+		 sizeof(class_d_stats->rx_byte_cnt),
+		 &(class_d_stats->rx_byte_cnt), tlen);
+
+	FILL_TLV(p, WLAN_STATS_RX_RATE,
+		 sizeof(class_d_stats->rx_rate),
+		 &(class_d_stats->rx_rate), tlen);
+
+	/* Transmit rate, in units of 500 kbit/sec */
+	FILL_TLV(p, WLAN_STATS_TX_RATE,
+		 sizeof(class_a_stats->tx_rate),
+		 &(class_a_stats->tx_rate), tlen);
+
+	FILL_TLV(p, WLAN_STATS_RX_UC_BYTE_CNT,
+		 sizeof(class_d_stats->rx_uc_byte_cnt[0]),
+		 &(class_d_stats->rx_uc_byte_cnt[0]), tlen);
+	FILL_TLV(p, WLAN_STATS_RX_MC_BYTE_CNT,
+		 sizeof(class_d_stats->rx_mc_byte_cnt),
+		 &(class_d_stats->rx_mc_byte_cnt), tlen);
+	FILL_TLV(p, WLAN_STATS_RX_BC_BYTE_CNT,
+		 sizeof(class_d_stats->rx_bc_byte_cnt),
+		 &(class_d_stats->rx_bc_byte_cnt), tlen);
+	FILL_TLV(p, WLAN_STATS_TX_UC_BYTE_CNT,
+		 sizeof(class_d_stats->tx_uc_byte_cnt[0]),
+		 &(class_d_stats->tx_uc_byte_cnt[0]), tlen);
+	FILL_TLV(p, WLAN_STATS_TX_MC_BYTE_CNT,
+		 sizeof(class_d_stats->tx_mc_byte_cnt),
+		 &(class_d_stats->tx_mc_byte_cnt), tlen);
+	FILL_TLV(p, WLAN_STATS_TX_BC_BYTE_CNT,
+		 sizeof(class_d_stats->tx_bc_byte_cnt),
+		 &(class_d_stats->tx_bc_byte_cnt), tlen);
+
+	wrqu->data.length = tlen;
+
+	hdd_exit();
+
+	return 0;
+}
+
+static int iw_get_statistics(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_get_statistics(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+/*Max Len for PNO notification*/
+#define MAX_PNO_NOTIFY_LEN 100
+static void found_pref_network_cb(struct wlan_objmgr_vdev *vdev,
+	struct scan_event *event, void *args)
+{
+	struct vdev_osif_priv *osif_priv;
+	struct wireless_dev *wdev;
+	union iwreq_data wrqu;
+	char buf[MAX_PNO_NOTIFY_LEN + 1];
+
+	wlan_vdev_obj_lock(vdev);
+	osif_priv = wlan_vdev_get_ospriv(vdev);
+	wlan_vdev_obj_unlock(vdev);
+	if (!osif_priv) {
+		hdd_err("osif_priv is null");
+		return;
+	}
+
+	wdev = osif_priv->wdev;
+	if (!wdev) {
+		hdd_err("wdev is null");
+		return;
+	}
+
+	hdd_debug("A preferred network was found");
+
+	/* create the event */
+	qdf_mem_zero(&wrqu, sizeof(wrqu));
+	qdf_mem_zero(buf, sizeof(buf));
+
+	snprintf(buf, MAX_PNO_NOTIFY_LEN,
+		 "QCOM: Found preferred network:");
+
+	wrqu.data.pointer = buf;
+	wrqu.data.length = strlen(buf);
+
+	/* send the event */
+
+	wireless_send_event(wdev->netdev, IWEVCUSTOM, &wrqu, buf);
+}
+
+/**
+ * __iw_set_pno() - Preferred Network Offload ioctl handler
+ * @dev: device upon which the ioctl was received
+ * @info: ioctl request information
+ * @wrqu: ioctl request data
+ * @extra: ioctl extra data
+ *
+ * This function parses a Preferred Network Offload command
+ * Input is string based and expected to be of the form:
+ *
+ * <enable(1) | disable(0)>
+ * when enabling:
+ * <number of networks>
+ * for each network:
+ *    <ssid_len> <ssid> <authentication> <encryption>
+ *    <ch_num> <channel_list optional> <bcast_type> <rssi_threshold>
+ * <scan_time (seconds)>
+ * <scan_repeat_count (0 means indefinite)>
+ * <suspend mode>
+ *
+ * e.g:
+ * 1 2 4 test 0 0 3 1 6 11 2 40 5 test2 4 4 6 1 2 3 4 5 6 1 0 5 2 1
+ *
+ * this translates into:
+ * -----------------------------
+ * enable PNO
+ * 2 networks
+ * Network 1:
+ *   test - with authentication type 0 and encryption type 0,
+ *   search on 3 channels: 1 6 and 11,
+ *   SSID bcast type is unknown (directed probe will be sent if
+ *   AP not found) and must meet -40dBm RSSI
+ * Network 2:
+ *   test2 - with authentication type 4 and encryption type 4,
+ *   search on 6 channels 1, 2, 3, 4, 5 and 6
+ *   bcast type is non-bcast (directed probe will be sent)
+ *   and must not meet any RSSI threshold
+ *   scan every 5 seconds 2 times
+ *   enable on suspend
+ */
+static int __iw_set_pno(struct net_device *dev,
+			struct iw_request_info *info,
+			union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	uint8_t value;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_psoc *psoc;
+	int ret = 0;
+	int offset;
+	char *ptr, *data;
+	uint8_t i, j, params;
+	QDF_STATUS status;
+	size_t len;
+
+	/* request is a large struct, so we make it static to avoid
+	 * stack overflow.  This API is only invoked via ioctl, so it
+	 * is serialized by the kernel rtnl_lock and hence does not
+	 * need to be reentrant
+	 */
+	static struct pno_scan_req_params req;
+
+	hdd_enter_dev(dev);
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(hdd_ctx->pdev,
+							 dev->dev_addr,
+							 WLAN_LEGACY_MAC_ID);
+	if (!vdev) {
+		hdd_err("vdev object is NULL");
+		return -EIO;
+	}
+
+	/* making sure argument string ends with '\0' */
+	len = (wrqu->data.length + 1);
+	data = qdf_mem_malloc(len);
+	if (!data) {
+		hdd_err("fail to allocate memory %zu", len);
+		return -EINVAL;
+	}
+	qdf_mem_copy(data, extra, (len-1));
+	ptr = data;
+
+	hdd_debug("PNO data len %d data %s", wrqu->data.length, data);
+
+	if (1 != sscanf(ptr, " %hhu %n", &value, &offset)) {
+		hdd_err("PNO enable input is not valid %s", ptr);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if (!value) {
+		status = ucfg_scan_pno_stop(vdev);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Failed to disabled PNO");
+			ret = -EINVAL;
+		} else {
+			hdd_debug("PNO scan disabled");
+		}
+		goto exit;
+	}
+
+	if (ucfg_scan_get_pno_in_progress(vdev)) {
+		hdd_debug("pno is already in progress");
+		ret = -EBUSY;
+		goto exit;
+	}
+
+	ptr += offset;
+
+	if (1 != sscanf(ptr, " %hhu %n", &value, &offset)) {
+		hdd_err("PNO count input not valid %s", ptr);
+		ret = -EINVAL;
+		goto exit;
+	}
+	req.networks_cnt = value;
+
+	hdd_debug("PNO enable networks count %d offset %d",
+		 req.networks_cnt, offset);
+
+	if ((0 == req.networks_cnt) ||
+	    (req.networks_cnt > SCAN_PNO_MAX_SUPP_NETWORKS)) {
+		hdd_err("Network count %d invalid",
+			req.networks_cnt);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	ptr += offset;
+
+	for (i = 0; i < req.networks_cnt; i++) {
+
+		req.networks_list[i].ssid.length = 0;
+
+		params = sscanf(ptr, " %hhu %n",
+				  &(req.networks_list[i].ssid.length),
+				  &offset);
+
+		if (1 != params) {
+			hdd_err("PNO ssid length input is not valid %s", ptr);
+			ret = -EINVAL;
+			goto exit;
+		}
+
+		if ((0 == req.networks_list[i].ssid.length) ||
+		    (req.networks_list[i].ssid.length > 32)) {
+			hdd_err("SSID Len %d is not correct for network %d",
+				  req.networks_list[i].ssid.length, i);
+			ret = -EINVAL;
+			goto exit;
+		}
+
+		/* Advance to SSID */
+		ptr += offset;
+
+		memcpy(req.networks_list[i].ssid.ssid, ptr,
+		       req.networks_list[i].ssid.length);
+		ptr += req.networks_list[i].ssid.length;
+
+		params = sscanf(ptr, " %u %u %hhu %n",
+				  &(req.networks_list[i].authentication),
+				  &(req.networks_list[i].encryption),
+				  &(req.networks_list[i].channel_cnt),
+				  &offset);
+
+		if (3 != params) {
+			hdd_err("Incorrect cmd %s", ptr);
+			ret = -EINVAL;
+			goto exit;
+		}
+
+		hdd_debug("PNO len %d ssid %.*s auth %d encry %d channel count %d offset %d",
+			  req.networks_list[i].ssid.length,
+			  req.networks_list[i].ssid.length,
+			  req.networks_list[i].ssid.ssid,
+			  req.networks_list[i].authentication,
+			  req.networks_list[i].encryption,
+			  req.networks_list[i].channel_cnt, offset);
+
+		/* Advance to channel list */
+		ptr += offset;
+
+		if (SCAN_PNO_MAX_NETW_CHANNELS_EX <
+		    req.networks_list[i].channel_cnt) {
+			hdd_err("Incorrect number of channels");
+			ret = -EINVAL;
+			goto exit;
+		}
+
+		if (0 != req.networks_list[i].channel_cnt) {
+			for (j = 0; j < req.networks_list[i].channel_cnt;
+			     j++) {
+				if (1 != sscanf(ptr, " %hhu %n", &value,
+				   &offset)) {
+					hdd_err("PNO network channel is not valid %s",
+						  ptr);
+					ret = -EINVAL;
+					goto exit;
+				}
+				if (!IS_CHANNEL_VALID(value)) {
+					hdd_err("invalid channel: %hhu", value);
+					ret = -EINVAL;
+					goto exit;
+				}
+				req.networks_list[i].channels[j] =
+					cds_chan_to_freq(value);
+				/* Advance to next channel number */
+				ptr += offset;
+			}
+		}
+
+		if (1 != sscanf(ptr, " %u %n",
+				&(req.networks_list[i].bc_new_type),
+				&offset)) {
+			hdd_err("PNO broadcast network type is not valid %s",
+				  ptr);
+			ret = -EINVAL;
+			goto exit;
+		}
+		if (req.networks_list[i].bc_new_type > 2) {
+			hdd_err("invalid bcast nw type: %u",
+				req.networks_list[i].bc_new_type);
+			ret = -EINVAL;
+			goto exit;
+		}
+
+		hdd_debug("PNO bcastNetwType %d offset %d",
+			  req.networks_list[i].bc_new_type, offset);
+
+		/* Advance to rssi Threshold */
+		ptr += offset;
+		if (1 != sscanf(ptr, " %d %n",
+				&(req.networks_list[i].rssi_thresh),
+				&offset)) {
+			hdd_err("PNO rssi threshold input is not valid %s",
+				  ptr);
+			ret = -EINVAL;
+			goto exit;
+		}
+		hdd_debug("PNO rssi %d offset %d",
+			  req.networks_list[i].rssi_thresh, offset);
+		/* Advance to next network */
+		ptr += offset;
+	} /* For ucNetworkCount */
+
+	req.fast_scan_period = 0;
+	if (sscanf(ptr, " %u %n", &(req.fast_scan_period), &offset) > 0) {
+		req.fast_scan_period *= MSEC_PER_SEC;
+		ptr += offset;
+	}
+	if (req.fast_scan_period == 0) {
+		hdd_err("invalid fast scan period %u",
+			req.fast_scan_period);
+			ret = -EINVAL;
+			goto exit;
+	}
+
+	req.fast_scan_max_cycles = 0;
+	if (sscanf(ptr, " %hhu %n", &value,
+		   &offset) > 0)
+		ptr += offset;
+	req.fast_scan_max_cycles = value;
+
+	wlan_pdev_obj_lock(hdd_ctx->pdev);
+	psoc = wlan_pdev_get_psoc(hdd_ctx->pdev);
+	wlan_pdev_obj_unlock(hdd_ctx->pdev);
+	ucfg_scan_register_pno_cb(psoc,
+		found_pref_network_cb, NULL);
+
+	ucfg_scan_get_pno_def_params(vdev, &req);
+	status = ucfg_scan_pno_start(vdev, &req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to enable PNO");
+		ret = -EINVAL;
+	}
+
+exit:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
+
+	qdf_mem_free(data);
+	return ret;
+}
+
+static int iw_set_pno(struct net_device *dev,
+		      struct iw_request_info *info,
+		      union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_set_pno(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif /* FEATURE_WLAN_SCAN_PNO */
+
+static int __iw_set_band_config(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx;
+	int ret;
+	int *value = (int *)extra;
+
+	hdd_enter_dev(dev);
+
+	if (!capable(CAP_NET_ADMIN)) {
+		hdd_err("permission check failed");
+		return -EPERM;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	return hdd_reg_set_band(dev, value[0]);
+}
+
+static int iw_set_band_config(struct net_device *dev,
+			      struct iw_request_info *info,
+			      union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_set_band_config(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+static int printk_adapter(void *priv, const char *fmt, ...)
+{
+	int ret;
+	va_list args;
+
+	va_start(args, fmt);
+	ret = vprintk(fmt, args);
+	ret += printk("\n");
+	va_end(args);
+
+	return ret;
+}
+
+static void hdd_ioctl_log_buffer(int log_id, uint32_t count)
+{
+	qdf_abstract_print *print = &printk_adapter;
+
+	switch (log_id) {
+	case HTC_CREDIT_HISTORY_LOG:
+		cds_print_htc_credit_history(count, print, NULL);
+		break;
+	case COMMAND_LOG:
+		wma_print_wmi_cmd_log(count, print, NULL);
+		break;
+	case COMMAND_TX_CMP_LOG:
+		wma_print_wmi_cmd_tx_cmp_log(count, print, NULL);
+		break;
+	case MGMT_COMMAND_LOG:
+		wma_print_wmi_mgmt_cmd_log(count, print, NULL);
+		break;
+	case MGMT_COMMAND_TX_CMP_LOG:
+		wma_print_wmi_mgmt_cmd_tx_cmp_log(count, print, NULL);
+		break;
+	case EVENT_LOG:
+		wma_print_wmi_event_log(count, print, NULL);
+		break;
+	case RX_EVENT_LOG:
+		wma_print_wmi_rx_event_log(count, print, NULL);
+		break;
+	case MGMT_EVENT_LOG:
+		wma_print_wmi_mgmt_event_log(count, print, NULL);
+		break;
+	default:
+		print(NULL, "Invalid Log Id %d", log_id);
+		break;
+	}
+}
+
+#ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT
+int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2)
+{
+	struct hdd_context *hdd_ctx;
+	int ret;
+	bool crash_inject;
+	QDF_STATUS status;
+
+	hdd_debug("WE_SET_FW_CRASH_INJECT: %d %d",
+		  v1, v2);
+	pr_err("SSR is triggered by iwpriv CRASH_INJECT: %d %d\n",
+	       v1, v2);
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get crash inject ini config");
+		return 0;
+	}
+
+	if (!crash_inject) {
+		hdd_err("Crash Inject ini disabled, Ignore Crash Inject");
+		return 0;
+	}
+
+	if (v1 == 3) {
+		cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
+		return 0;
+	}
+	ret = wma_cli_set2_command(adapter->session_id,
+				   GEN_PARAM_CRASH_INJECT,
+				   v1, v2, GEN_CMD);
+	return ret;
+}
+#endif
+
+#ifdef CONFIG_DP_TRACE
+void hdd_set_dump_dp_trace(uint16_t cmd_type, uint16_t count)
+{
+	hdd_debug("WE_DUMP_DP_TRACE_LEVEL: %d %d",
+		  cmd_type, count);
+	if (cmd_type == DUMP_DP_TRACE)
+		qdf_dp_trace_dump_all(count, QDF_TRACE_DEFAULT_PDEV_ID);
+	else if (cmd_type == ENABLE_DP_TRACE_LIVE_MODE)
+		qdf_dp_trace_enable_live_mode();
+	else if (cmd_type == CLEAR_DP_TRACE_BUFFER)
+		qdf_dp_trace_clear_buffer();
+	else if (cmd_type == DISABLE_DP_TRACE_LIVE_MODE)
+		qdf_dp_trace_disable_live_mode();
+}
+#endif
+
+static int __iw_set_two_ints_getnone(struct net_device *dev,
+				     struct iw_request_info *info,
+				     union iwreq_data *wrqu, char *extra)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	int *value = (int *)extra;
+	int sub_cmd = value[0];
+	int ret;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	switch (sub_cmd) {
+	case WE_SET_SMPS_PARAM:
+		hdd_debug("WE_SET_SMPS_PARAM val %d %d", value[1], value[2]);
+		ret = wma_cli_set_command(adapter->session_id,
+					  WMI_STA_SMPS_PARAM_CMDID,
+					  value[1] << WMA_SMPS_PARAM_VALUE_S
+					      | value[2],
+					  VDEV_CMD);
+		break;
+	case WE_SET_FW_CRASH_INJECT:
+		ret = hdd_crash_inject(adapter, value[1], value[2]);
+		break;
+	case WE_ENABLE_FW_PROFILE:
+		hdd_err("WE_ENABLE_FW_PROFILE: %d %d",
+		       value[1], value[2]);
+		ret = wma_cli_set2_command(adapter->session_id,
+				 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
+					value[1], value[2], DBG_CMD);
+		break;
+	case WE_SET_FW_PROFILE_HIST_INTVL:
+		hdd_err("WE_SET_FW_PROFILE_HIST_INTVL: %d %d",
+		       value[1], value[2]);
+		ret = wma_cli_set2_command(adapter->session_id,
+					WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
+					value[1], value[2], DBG_CMD);
+		break;
+	case WE_SET_DUAL_MAC_FW_MODE_CONFIG:
+		hdd_debug("Ioctl to set dual fw mode config");
+		if (hdd_ctx->config->dual_mac_feature_disable ==
+				DISABLE_DBS_CXN_AND_SCAN) {
+			hdd_err("Dual mac feature is disabled from INI");
+			return -EPERM;
+		}
+		hdd_debug("%d %d", value[1], value[2]);
+		policy_mgr_set_dual_mac_fw_mode_config(hdd_ctx->psoc,
+			value[1], value[2]);
+		break;
+	case WE_DUMP_DP_TRACE_LEVEL:
+		hdd_set_dump_dp_trace(value[1], value[2]);
+		break;
+	case WE_SET_MON_MODE_CHAN:
+		ret = wlan_hdd_set_mon_chan(adapter, value[1], value[2]);
+		break;
+	case WE_SET_WLAN_SUSPEND:
+		ret = hdd_wlan_fake_apps_suspend(hdd_ctx->wiphy, dev,
+						 value[1], value[2]);
+		break;
+	case WE_SET_WLAN_RESUME:
+		ret = hdd_wlan_fake_apps_resume(hdd_ctx->wiphy, dev);
+		break;
+	case WE_LOG_BUFFER: {
+		int log_id = value[1];
+		uint32_t count = value[2] < 0 ? 0 : value[2];
+
+		hdd_ioctl_log_buffer(log_id, count);
+
+		break;
+	}
+	case WE_SET_BA_AGEING_TIMEOUT:
+	{
+		void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+		if (!soc) {
+			hdd_err("Invalid handles");
+			break;
+		}
+		cdp_set_ba_timeout(soc, value[1], value[2]);
+		break;
+	}
+	default:
+		hdd_err("Invalid IOCTL command %d", sub_cmd);
+		break;
+	}
+
+	return ret;
+}
+
+static int iw_set_two_ints_getnone(struct net_device *dev,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __iw_set_two_ints_getnone(dev, info, wrqu, extra);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/* Define the Wireless Extensions to the Linux Network Device structure */
+
+static const iw_handler we_private[] = {
+
+	[WLAN_PRIV_SET_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_setint_getnone,
+	[WLAN_PRIV_SET_NONE_GET_INT - SIOCIWFIRSTPRIV] = iw_setnone_getint,
+	[WLAN_PRIV_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] = iw_setchar_getnone,
+	[WLAN_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] =
+		iw_set_three_ints_getnone,
+	[WLAN_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = iw_get_char_setnone,
+	[WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone,
+	[WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] =
+		iw_hdd_set_var_ints_getnone,
+	[WLAN_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV] =
+							iw_setnone_get_threeint,
+#ifdef WLAN_FEATURE_FIPS
+	[WLAN_PRIV_FIPS_TEST - SIOCIWFIRSTPRIV] = hdd_fips_test,
+#endif
+	[WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec,
+	[WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec,
+	[WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec,
+	[WLAN_PRIV_SET_FTIES - SIOCIWFIRSTPRIV] = iw_set_fties,
+	[WLAN_PRIV_SET_HOST_OFFLOAD - SIOCIWFIRSTPRIV] = iw_set_host_offload,
+	[WLAN_GET_WLAN_STATISTICS - SIOCIWFIRSTPRIV] = iw_get_statistics,
+	[WLAN_SET_KEEPALIVE_PARAMS - SIOCIWFIRSTPRIV] =
+		iw_set_keepalive_params,
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+	[WLAN_SET_PACKET_FILTER_PARAMS - SIOCIWFIRSTPRIV] =
+		iw_set_packet_filter_params,
+#endif
+#ifdef FEATURE_WLAN_SCAN_PNO
+	[WLAN_SET_PNO - SIOCIWFIRSTPRIV] = iw_set_pno,
+#endif
+	[WLAN_SET_BAND_CONFIG - SIOCIWFIRSTPRIV] = iw_set_band_config,
+	[WLAN_PRIV_SET_MCBC_FILTER - SIOCIWFIRSTPRIV] =
+		iw_set_dynamic_mcbc_filter,
+	[WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed,
+	[WLAN_PRIV_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
+		iw_set_two_ints_getnone,
+	[WLAN_SET_DOT11P_CHANNEL_SCHED - SIOCIWFIRSTPRIV] =
+		iw_set_dot11p_channel_sched,
+};
+
+/*Maximum command length can be only 15 */
+static const struct iw_priv_args we_private_args[] = {
+
+	/* handlers for main ioctl */
+	{WLAN_PRIV_SET_INT_GET_NONE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 ""},
+
+	/* handlers for sub-ioctl */
+	{WE_SET_11D_STATE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "set11Dstate"},
+
+	{WE_WOWL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "wowl"},
+
+	{WE_SET_POWER,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "setPower"},
+
+	{WE_SET_MAX_ASSOC,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "setMaxAssoc"},
+
+	{WE_SET_SCAN_DISABLE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "scan_disable"},
+
+	{WE_SET_DATA_INACTIVITY_TO,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "inactivityTO"},
+
+	{WE_SET_WOW_DATA_INACTIVITY_TO,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "wow_ito"},
+
+	{WE_SET_MAX_TX_POWER,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "setMaxTxPower"},
+
+	{WE_SET_TX_POWER,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "setTxPower"},
+
+	{WE_SET_MC_RATE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "setMcRate"},
+
+	{WE_SET_MAX_TX_POWER_2_4,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "setTxMaxPower2G"},
+
+	{WE_SET_MAX_TX_POWER_5_0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "setTxMaxPower5G"},
+
+#ifndef REMOVE_PKT_LOG
+	{WE_SET_PKTLOG,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "pktlog"},
+#endif
+
+	/* SAP has TxMax whereas STA has MaxTx, adding TxMax for STA
+	 * as well to keep same syntax as in SAP. Now onwards, STA
+	 * will support both
+	 */
+	{WE_SET_MAX_TX_POWER,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "setTxMaxPower"},
+
+	{WE_SET_TM_LEVEL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "setTmLevel"},
+
+	{WE_SET_PHYMODE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "setphymode"},
+
+	{WE_SET_NSS,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "nss"},
+
+	{WE_SET_LDPC,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "ldpc"},
+
+	{WE_SET_TX_STBC,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "tx_stbc"},
+
+	{WE_SET_RX_STBC,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "rx_stbc"},
+
+	{WE_SET_SHORT_GI,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "shortgi"},
+
+	{WE_SET_RTSCTS,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "enablertscts"},
+
+	{WE_SET_CHWIDTH,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "chwidth"},
+
+	{WE_SET_ANI_EN_DIS,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "anienable"},
+
+	{WE_SET_ANI_POLL_PERIOD,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "aniplen"},
+
+	{WE_SET_ANI_LISTEN_PERIOD,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "anilislen"},
+
+	{WE_SET_ANI_OFDM_LEVEL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "aniofdmlvl"},
+
+	{WE_SET_ANI_CCK_LEVEL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "aniccklvl"},
+
+	{WE_SET_DYNAMIC_BW,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "cwmenable"},
+
+	{WE_SET_CTS_CBW,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "cts_cbw" },
+
+	{WE_SET_GTX_HT_MCS,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "gtxHTMcs"},
+
+	{WE_SET_GTX_VHT_MCS,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "gtxVHTMcs"},
+
+	{WE_SET_GTX_USRCFG,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "gtxUsrCfg"},
+
+	{WE_SET_GTX_THRE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "gtxThre"},
+
+	{WE_SET_GTX_MARGIN,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "gtxMargin"},
+
+	{WE_SET_GTX_STEP,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "gtxStep"},
+
+	{WE_SET_GTX_MINTPC,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "gtxMinTpc"},
+
+	{WE_SET_GTX_BWMASK,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "gtxBWMask"},
+
+	{WE_SET_TX_CHAINMASK,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "txchainmask"},
+
+	{WE_SET_RX_CHAINMASK,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "rxchainmask"},
+
+	{WE_SET_11N_RATE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "set11NRates"},
+
+	{WE_SET_VHT_RATE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "set11ACRates"},
+
+	{WE_SET_AMPDU,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "ampdu"},
+
+	{WE_SET_AMSDU,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "amsdu"},
+
+	{WE_SET_TXPOW_2G,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "txpow2g"},
+
+	{WE_SET_TXPOW_5G,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "txpow5g"},
+
+#ifdef FEATURE_FW_LOG_PARSING
+	/* Sub-cmds DBGLOG specific commands */
+	{WE_DBGLOG_LOG_LEVEL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "dl_loglevel"},
+
+	{WE_DBGLOG_VAP_ENABLE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "dl_vapon"},
+
+	{WE_DBGLOG_VAP_DISABLE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "dl_vapoff"},
+
+	{WE_DBGLOG_MODULE_ENABLE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "dl_modon"},
+
+	{WE_DBGLOG_MODULE_DISABLE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "dl_modoff"},
+
+	{WE_DBGLOG_MOD_LOG_LEVEL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "dl_mod_loglevel"},
+
+	{WE_DBGLOG_TYPE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "dl_type"},
+	{WE_DBGLOG_REPORT_ENABLE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "dl_report"},
+#endif /* FEATURE_FW_LOG_PARSING */
+
+	{WE_SET_TXRX_FWSTATS,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "txrx_fw_stats"},
+
+	{WE_SET_TXRX_STATS,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "txrx_stats"},
+
+	{WE_TXRX_FWSTATS_RESET,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "txrx_fw_st_rst"},
+
+	{WE_PPS_PAID_MATCH,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "paid_match"},
+
+	{WE_PPS_GID_MATCH,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "gid_match"},
+
+	{WE_PPS_EARLY_TIM_CLEAR,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "tim_clear"},
+
+	{WE_PPS_EARLY_DTIM_CLEAR,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "dtim_clear"},
+
+	{WE_PPS_EOF_PAD_DELIM,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "eof_delim"},
+
+	{WE_PPS_MACADDR_MISMATCH,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "mac_match"},
+
+	{WE_PPS_DELIM_CRC_FAIL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "delim_fail"},
+
+	{WE_PPS_GID_NSTS_ZERO,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "nsts_zero"},
+
+	{WE_PPS_RSSI_CHECK,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "rssi_chk"},
+
+	{WE_PPS_5G_EBT,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "5g_ebt"},
+
+	{WE_SET_HTSMPS,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "htsmps"},
+
+	{WE_SET_QPOWER_MAX_PSPOLL_COUNT,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "set_qpspollcnt"},
+
+	{WE_SET_QPOWER_MAX_TX_BEFORE_WAKE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "set_qtxwake"},
+
+	{WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "set_qwakeintv"},
+
+	{WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "set_qnodatapoll"},
+
+	/* handlers for MCC time quota and latency sub ioctls */
+	{WE_MCC_CONFIG_LATENCY,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "setMccLatency"},
+
+	{WE_MCC_CONFIG_QUOTA,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "setMccQuota"},
+
+	{WE_SET_DEBUG_LOG,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "setDbgLvl"},
+
+	/* handlers for early_rx power save */
+	{WE_SET_EARLY_RX_ADJUST_ENABLE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "erx_enable"},
+
+	{WE_SET_EARLY_RX_TGT_BMISS_NUM,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "erx_bmiss_val"},
+
+	{WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "erx_bmiss_smpl"},
+
+	{WE_SET_EARLY_RX_SLOP_STEP,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "erx_slop_step"},
+
+	{WE_SET_EARLY_RX_INIT_SLOP,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "erx_init_slop"},
+
+	{WE_SET_EARLY_RX_ADJUST_PAUSE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "erx_adj_pause"},
+
+	{WE_SET_EARLY_RX_DRIFT_SAMPLE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "erx_dri_sample"},
+
+	{WE_DUMP_STATS,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "dumpStats"},
+
+	{WE_CLEAR_STATS,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "clearStats"},
+
+	{WE_START_FW_PROFILE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "startProfile"},
+
+	{WE_SET_CHANNEL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "setChanChange" },
+
+	{WE_SET_CONC_SYSTEM_PREF,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "setConcSysPref" },
+
+	{WE_SET_PDEV_RESET,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0, "pdev_reset" },
+
+	{WE_SET_MODULATED_DTIM,
+	IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	0, "setModDTIM" },
+
+	{WLAN_PRIV_SET_NONE_GET_INT,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 ""},
+
+	/* handlers for sub-ioctl */
+	{WE_GET_11D_STATE,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get11Dstate"},
+
+	{WE_GET_WLAN_DBG,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "getwlandbg"},
+
+	{WE_GET_MAX_ASSOC,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "getMaxAssoc"},
+
+	{WE_GET_SAP_AUTO_CHANNEL_SELECTION,
+		0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		"getAutoChannel" },
+
+	{WE_GET_CONCURRENCY_MODE,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "getconcurrency"},
+
+	{WE_GET_NSS,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_nss"},
+
+	{WE_GET_LDPC,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_ldpc"},
+
+	{WE_GET_TX_STBC,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_tx_stbc"},
+
+	{WE_GET_RX_STBC,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_rx_stbc"},
+
+	{WE_GET_SHORT_GI,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_shortgi"},
+
+	{WE_GET_RTSCTS,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_rtscts"},
+
+	{WE_GET_CHWIDTH,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_chwidth"},
+
+	{WE_GET_ANI_EN_DIS,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_anienable"},
+
+	{WE_GET_ANI_POLL_PERIOD,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_aniplen"},
+
+	{WE_GET_ANI_LISTEN_PERIOD,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_anilislen"},
+
+	{WE_GET_ANI_OFDM_LEVEL,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_aniofdmlvl"},
+
+	{WE_GET_ANI_CCK_LEVEL,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_aniccklvl"},
+
+	{WE_GET_DYNAMIC_BW,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_cwmenable"},
+
+	{WE_GET_GTX_HT_MCS,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_gtxHTMcs"},
+
+	{WE_GET_GTX_VHT_MCS,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_gtxVHTMcs"},
+
+	{WE_GET_GTX_USRCFG,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_gtxUsrCfg"},
+
+	{WE_GET_GTX_THRE,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_gtxThre"},
+
+	{WE_GET_GTX_MARGIN,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_gtxMargin"},
+
+	{WE_GET_GTX_STEP,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_gtxStep"},
+
+	{WE_GET_GTX_MINTPC,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_gtxMinTpc"},
+
+	{WE_GET_GTX_BWMASK,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_gtxBWMask"},
+
+	{WE_GET_TX_CHAINMASK,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_txchainmask"},
+
+	{WE_GET_RX_CHAINMASK,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_rxchainmask"},
+
+	{WE_GET_11N_RATE,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_11nrate"},
+
+	{WE_GET_AMPDU,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_ampdu"},
+
+	{WE_GET_AMSDU,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_amsdu"},
+
+	{WE_GET_TXPOW_2G,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_txpow2g"},
+
+	{WE_GET_TXPOW_5G,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_txpow5g"},
+
+	{WE_GET_PPS_PAID_MATCH,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_paid_match"},
+
+	{WE_GET_PPS_GID_MATCH,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_gid_match"},
+
+	{WE_GET_PPS_EARLY_TIM_CLEAR,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_tim_clear"},
+
+	{WE_GET_PPS_EARLY_DTIM_CLEAR,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_dtim_clear"},
+
+	{WE_GET_PPS_EOF_PAD_DELIM,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_eof_delim"},
+
+	{WE_GET_PPS_MACADDR_MISMATCH,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_mac_match"},
+
+	{WE_GET_PPS_DELIM_CRC_FAIL,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_delim_fail"},
+
+	{WE_GET_PPS_GID_NSTS_ZERO,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_nsts_zero"},
+
+	{WE_GET_PPS_RSSI_CHECK,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_rssi_chk"},
+
+	{WE_GET_QPOWER_MAX_PSPOLL_COUNT,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_qpspollcnt"},
+
+	{WE_GET_QPOWER_MAX_TX_BEFORE_WAKE,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_qtxwake"},
+
+	{WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_qwakeintv"},
+
+	{WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_qnodatapoll"},
+
+	{WE_CAP_TSF,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "cap_tsf"},
+
+	{WE_GET_TEMPERATURE,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_temp"},
+	{WE_GET_DCM,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_dcm"},
+	{WE_GET_RANGE_EXT,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "get_range_ext"},
+	/* handlers for main ioctl */
+	{WLAN_PRIV_SET_CHAR_GET_NONE,
+	 IW_PRIV_TYPE_CHAR | 512,
+	 0,
+	 ""},
+
+	/* handlers for sub-ioctl */
+	{WE_WOWL_ADD_PTRN,
+	 IW_PRIV_TYPE_CHAR | 512,
+	 0,
+	 "wowlAddPtrn"},
+
+	{WE_WOWL_DEL_PTRN,
+	 IW_PRIV_TYPE_CHAR | 512,
+	 0,
+	 "wowlDelPtrn"},
+
+	/* handlers for sub-ioctl */
+	{WE_NEIGHBOR_REPORT_REQUEST,
+	 IW_PRIV_TYPE_CHAR | 512,
+	 0,
+	 "neighbor"},
+
+	{WE_SET_AP_WPS_IE,
+	 IW_PRIV_TYPE_CHAR | 512,
+	 0,
+	 "set_ap_wps_ie"},
+
+	{WE_SET_CONFIG,
+	 IW_PRIV_TYPE_CHAR | 512,
+	 0,
+	 "setConfig"},
+
+#ifdef WLAN_UNIT_TEST
+	{WE_UNIT_TEST,
+	 IW_PRIV_TYPE_CHAR | 512,
+	 0,
+	 "unit_test"},
+#endif
+
+	/* handlers for main ioctl */
+	{WLAN_PRIV_SET_THREE_INT_GET_NONE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+	 0,
+	 ""},
+
+	/* handlers for sub-ioctl */
+	{WE_SET_WLAN_DBG,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+	 0,
+	 "setwlandbg"},
+
+#ifdef CONFIG_DP_TRACE
+	/* handlers for sub-ioctl */
+	{WE_SET_DP_TRACE,
+	IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+	0,
+	"set_dp_trace"},
+#endif
+
+	{WE_SET_FW_TEST,
+	IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+	0, "fw_test"},
+
+	/* handlers for main ioctl */
+	{WLAN_PRIV_SET_NONE_GET_THREE_INT,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+	 "" },
+	{WE_GET_TSF,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+	 "get_tsf" },
+
+	{WE_SET_DUAL_MAC_SCAN_CONFIG,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+	 0,
+	 "set_scan_cfg"},
+
+	/* handlers for main ioctl */
+	{WLAN_PRIV_GET_CHAR_SET_NONE,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 ""},
+
+	/* handlers for sub-ioctl */
+	{WE_WLAN_VERSION,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "version"},
+	{WE_GET_STATS,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "getStats"},
+	{WE_GET_SUSPEND_RESUME_STATS,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "getSuspendStats"},
+	{WE_LIST_FW_PROFILE,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "listProfile"},
+	{WE_GET_STATES,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "getHostStates"},
+	{WE_GET_CFG,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "getConfig"},
+	{WE_GET_RSSI,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "getRSSI"},
+	{WE_GET_WMM_STATUS,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "getWmmStatus"},
+	{
+		WE_GET_CHANNEL_LIST,
+		0,
+		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+		"getChannelList"
+	},
+#ifdef FEATURE_WLAN_TDLS
+	{
+		WE_GET_TDLS_PEERS,
+		0,
+		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+		"getTdlsPeers"
+	},
+#endif
+#ifdef WLAN_FEATURE_11W
+	{
+		WE_GET_11W_INFO,
+		0,
+		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+		"getPMFInfo"
+	},
+#endif
+	{
+		WE_GET_IBSS_STA_INFO,
+		0,
+		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+		"getIbssSTAs"
+	},
+	{WE_GET_PHYMODE,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "getphymode"},
+#if defined(FEATURE_OEM_DATA_SUPPORT) || defined(WIFI_POS_CONVERGED)
+	{WE_GET_OEM_DATA_CAP,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "getOemDataCap"},
+#endif
+	{WE_GET_SNR,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "getSNR"},
+
+	{WE_GET_BA_AGEING_TIMEOUT,
+	 0,
+	 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+	 "get_ba_timeout"},
+
+	/* handlers for main ioctl */
+	{WLAN_PRIV_SET_NONE_GET_NONE,
+	 0,
+	 0,
+	 ""},
+
+	/* handlers for sub-ioctl */
+	{
+		WE_IBSS_GET_PEER_INFO_ALL,
+		0,
+		0,
+		"ibssPeerInfoAll"
+	},
+	{WE_GET_RECOVERY_STAT,
+	 0,
+	 0,
+	 "getRecoverStat"},
+
+	{WE_GET_FW_PROFILE_DATA,
+	 0,
+	 0,
+	 "getProfileData"},
+
+	{WE_SET_REASSOC_TRIGGER,
+	0,
+	0,
+	"reassoc"},
+
+	{WE_STOP_OBSS_SCAN,
+	 0,
+	 0,
+	 "stop_obss_scan"},
+	/* handlers for main ioctl */
+	{WLAN_PRIV_SET_VAR_INT_GET_NONE,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 ""},
+
+	/* handlers for sub-ioctl */
+	{WE_IBSS_GET_PEER_INFO,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "ibssPeerInfo"},
+
+#ifdef TRACE_RECORD
+	/* handlers for sub-ioctl */
+	{WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "setdumplog"},
+
+	{WE_MTRACE_DUMP_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "dumplog"},
+#endif
+
+	{WE_POLICY_MANAGER_CINFO_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "pm_cinfo"},
+
+#ifdef MPC_UT_FRAMEWORK
+	{WE_POLICY_MANAGER_CLIST_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "pm_clist"},
+
+	{WE_POLICY_MANAGER_DLIST_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "pm_dlist"},
+
+	{WE_POLICY_MANAGER_DBS_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "pm_dbs"},
+
+	{WE_POLICY_MANAGER_PCL_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "pm_pcl"},
+
+	{WE_POLICY_MANAGER_ULIST_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "pm_ulist"},
+
+	{WE_POLICY_MANAGER_QUERY_ACTION_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "pm_query_action"},
+
+	{WE_POLICY_MANAGER_QUERY_ALLOW_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "pm_query_allow"},
+
+	{WE_POLICY_MANAGER_SCENARIO_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "pm_run_scenario"},
+
+	{WE_POLICY_SET_HW_MODE_CMD,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "pm_set_hw_mode"},
+#endif
+	{
+		WE_UNIT_TEST_CMD,
+		IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+		0,
+		"setUnitTestCmd"
+	},
+	{
+		WE_MAC_PWR_DEBUG_CMD,
+		IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+		0,
+		"halPwrDebug"
+	},
+
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+	{WE_LED_FLASHING_PARAM,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "gpio_control"},
+#endif
+#ifdef WLAN_DEBUG
+	{WE_SET_CHAN_AVOID,
+	 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
+	 0,
+	 "ch_avoid"},
+#endif
+	/* handlers for main ioctl */
+	{WLAN_PRIV_FIPS_TEST,
+	 IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN,
+	 IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN,
+	 "fips_test"},
+
+	/* handlers for main ioctl */
+	{WLAN_PRIV_ADD_TSPEC,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | HDD_WLAN_WMM_PARAM_COUNT,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "addTspec"},
+
+	/* handlers for main ioctl */
+	{WLAN_PRIV_DEL_TSPEC,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "delTspec"},
+
+	/* handlers for main ioctl */
+	{WLAN_PRIV_GET_TSPEC,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "getTspec"},
+
+	/* handlers for main ioctl - host offload */
+	{
+		WLAN_PRIV_SET_HOST_OFFLOAD,
+		IW_PRIV_TYPE_BYTE | sizeof(struct host_offload_req),
+		0,
+		"setHostOffload"
+	}
+	,
+
+	{
+		WLAN_GET_WLAN_STATISTICS,
+		0,
+		IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN,
+		"getWlanStats"
+	}
+	,
+
+	{
+		WLAN_SET_KEEPALIVE_PARAMS,
+		IW_PRIV_TYPE_BYTE | sizeof(tSirKeepAliveReq) |
+		IW_PRIV_SIZE_FIXED,
+		0,
+		"setKeepAlive"
+	}
+	,
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+	{
+		WLAN_SET_PACKET_FILTER_PARAMS,
+		IW_PRIV_TYPE_BYTE |
+		sizeof(struct pkt_filter_cfg),
+		0,
+		"setPktFilter"
+	}
+	,
+#endif
+#ifdef FEATURE_WLAN_SCAN_PNO
+	{
+		WLAN_SET_PNO,
+		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
+		0,
+		"setpno"
+	}
+	,
+#endif
+	{
+		WLAN_SET_BAND_CONFIG,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		0,
+		"SETBAND"
+	}
+	,
+	{
+		WLAN_PRIV_SET_MCBC_FILTER,
+		0,
+		0,
+		"setMCBCFilter"
+	}
+	,
+
+	{
+		WLAN_GET_LINK_SPEED,
+		IW_PRIV_TYPE_CHAR | 18,
+		IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
+	}
+	,
+
+	/* handlers for main ioctl */
+	{WLAN_PRIV_SET_TWO_INT_GET_NONE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0,
+	 ""}
+	,
+	{WE_SET_SMPS_PARAM,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0, "set_smps_param"}
+	,
+	{WLAN_SET_DOT11P_CHANNEL_SCHED,
+	 IW_PRIV_TYPE_BYTE | sizeof(struct dot11p_channel_sched),
+	 0, "set_dot11p" }
+	,
+#ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT
+	{WE_SET_FW_CRASH_INJECT,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0, "crash_inject"}
+	,
+#endif
+#if defined(WMI_INTERFACE_EVENT_LOGGING) || defined(FEATURE_HTC_CREDIT_HISTORY)
+	{WE_LOG_BUFFER,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0, "log_buffer"}
+	,
+#endif
+	{WE_SET_BA_AGEING_TIMEOUT,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0, "set_ba_timeout"}
+	,
+#ifdef WLAN_SUSPEND_RESUME_TEST
+	{WE_SET_WLAN_SUSPEND,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0, "wlan_suspend"}
+	,
+	{WE_SET_WLAN_RESUME,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0, "wlan_resume"}
+	,
+#endif
+	{WE_ENABLE_FW_PROFILE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0, "enableProfile"}
+	,
+	{WE_SET_FW_PROFILE_HIST_INTVL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0, "set_hist_intvl"}
+	,
+	{WE_SET_DUAL_MAC_FW_MODE_CONFIG,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0, "set_fw_mode_cfg"}
+	,
+#ifdef CONFIG_DP_TRACE
+	{WE_DUMP_DP_TRACE_LEVEL,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0, "dump_dp_trace"}
+	,
+#endif
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+	{WE_SET_MON_MODE_CHAN,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+	 0, "setMonChan"}
+	,
+#endif
+	{WE_GET_ROAM_SYNCH_DELAY,
+	 0,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 "hostroamdelay"}
+	,
+	{WE_SET_11AX_RATE,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "set_11ax_rate"}
+	,
+	{WE_SET_DCM,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "enable_dcm"}
+	,
+	{WE_SET_RANGE_EXT,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	 0,
+	 "range_ext"}
+	,
+
+	{WLAN_PRIV_SET_FTIES,
+	 IW_PRIV_TYPE_CHAR | MAX_FTIE_SIZE,
+	 0,
+	 "set_ft_ies"},
+};
+
+const struct iw_handler_def we_handler_def = {
+	.num_standard = 0,
+	.num_private = QDF_ARRAY_SIZE(we_private),
+	.num_private_args = QDF_ARRAY_SIZE(we_private_args),
+
+	.standard = NULL,
+	.private = (iw_handler *) we_private,
+	.private_args = we_private_args,
+	.get_wireless_stats = NULL,
+};
+
+void hdd_register_wext(struct net_device *dev)
+{
+	hdd_enter_dev(dev);
+
+	dev->wireless_handlers = &we_handler_def;
+
+	hdd_exit();
+}
+
+void hdd_unregister_wext(struct net_device *dev)
+{
+	hdd_enter_dev(dev);
+
+	rtnl_lock();
+	dev->wireless_handlers = NULL;
+	rtnl_unlock();
+
+	hdd_exit();
+}
diff --git a/core/hdd/src/wlan_hdd_wmm.c b/core/hdd/src/wlan_hdd_wmm.c
new file mode 100644
index 0000000..0628d32
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_wmm.c
@@ -0,0 +1,2697 @@
+/*
+ * Copyright (c) 2013-2018 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: HDD WMM
+ *
+ * This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation)
+ * houses all the logic for WMM in HDD.
+ *
+ * On the control path, it has the logic to setup QoS, modify QoS and delete
+ * QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an
+ * explicit application invoked and an internal HDD invoked.  The implicit QoS
+ * is for applications that do NOT call the custom QCT WLAN OIDs for QoS but
+ * which DO mark their traffic for priortization. It also has logic to start,
+ * update and stop the U-APSD trigger frame generation. It also has logic to
+ * read WMM related config parameters from the registry.
+ *
+ * On the data path, it has the logic to figure out the WMM AC of an egress
+ * packet and when to signal TL to serve a particular AC queue. It also has the
+ * logic to retrieve a packet based on WMM priority in response to a fetch from
+ * TL.
+ *
+ * The remaining functions are utility functions for information hiding.
+ */
+
+/* Include files */
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/ip.h>
+#include <linux/semaphore.h>
+#include <linux/ipv6.h>
+#include <wlan_hdd_tx_rx.h>
+#include <wlan_hdd_wmm.h>
+#include <wlan_hdd_ether.h>
+#include <wlan_hdd_hostapd.h>
+#include <wlan_hdd_softap_tx_rx.h>
+#include <cds_sched.h>
+#include "sme_api.h"
+#include "wlan_mlme_ucfg_api.h"
+
+#define WLAN_HDD_MAX_DSCP 0x3f
+
+#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
+
+const uint8_t hdd_wmm_up_to_ac_map[] = {
+	SME_AC_BE,
+	SME_AC_BK,
+	SME_AC_BK,
+	SME_AC_BE,
+	SME_AC_VI,
+	SME_AC_VI,
+	SME_AC_VO,
+	SME_AC_VO
+};
+
+/**
+ * enum hdd_wmm_linuxac: AC/Queue Index values for Linux Qdisc to
+ * operate on different traffic.
+ */
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+void wlan_hdd_process_peer_unauthorised_pause(struct hdd_adapter *adapter)
+{
+	/* Enable HI_PRIO queue */
+	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VO);
+	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VI);
+	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BE);
+	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BK);
+	netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO);
+
+}
+#else
+void wlan_hdd_process_peer_unauthorised_pause(struct hdd_adapter *adapter)
+{
+}
+#endif
+
+/* Linux based UP -> AC Mapping */
+const uint8_t hdd_linux_up_to_ac_map[HDD_WMM_UP_TO_AC_MAP_SIZE] = {
+	HDD_LINUX_AC_BE,
+	HDD_LINUX_AC_BK,
+	HDD_LINUX_AC_BK,
+	HDD_LINUX_AC_BE,
+	HDD_LINUX_AC_VI,
+	HDD_LINUX_AC_VI,
+	HDD_LINUX_AC_VO,
+	HDD_LINUX_AC_VO
+};
+
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+/**
+ * hdd_wmm_enable_tl_uapsd() - function which decides whether and
+ * how to update UAPSD parameters in TL
+ *
+ * @pQosContext: [in] the pointer the QoS instance control block
+ *
+ * Return: None
+ */
+static void hdd_wmm_enable_tl_uapsd(struct hdd_wmm_qos_context *pQosContext)
+{
+	struct hdd_adapter *adapter = pQosContext->adapter;
+	sme_ac_enum_type acType = pQosContext->acType;
+	struct hdd_wmm_ac_status *pAc = &adapter->hdd_wmm_status.wmmAcStatus[acType];
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	QDF_STATUS status;
+	uint32_t service_interval;
+	uint32_t suspension_interval;
+	enum sme_qos_wmm_dir_type direction;
+	bool psb;
+
+	/* The TSPEC must be valid */
+	if (pAc->wmmAcTspecValid == false) {
+		hdd_err("Invoked with invalid TSPEC");
+		return;
+	}
+	/* determine the service interval */
+	if (pAc->wmmAcTspecInfo.min_service_interval) {
+		service_interval = pAc->wmmAcTspecInfo.min_service_interval;
+	} else if (pAc->wmmAcTspecInfo.max_service_interval) {
+		service_interval = pAc->wmmAcTspecInfo.max_service_interval;
+	} else {
+		/* no service interval is present in the TSPEC */
+		/* this is OK, there just won't be U-APSD */
+		hdd_debug("No service interval supplied");
+		service_interval = 0;
+	}
+
+	/* determine the suspension interval & direction */
+	suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
+	direction = pAc->wmmAcTspecInfo.ts_info.direction;
+	psb = pAc->wmmAcTspecInfo.ts_info.psb;
+
+	/* if we have previously enabled U-APSD, have any params changed? */
+	if ((pAc->wmmAcUapsdInfoValid) &&
+	    (pAc->wmmAcUapsdServiceInterval == service_interval) &&
+	    (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
+	    (pAc->wmmAcUapsdDirection == direction) &&
+	    (pAc->wmmAcIsUapsdEnabled == psb)) {
+		hdd_debug("No change in U-APSD parameters");
+		return;
+	}
+	/* everything is in place to notify TL */
+	status =
+		sme_enable_uapsd_for_ac((WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
+					   conn_info.staId[0], acType,
+					   pAc->wmmAcTspecInfo.ts_info.tid,
+					   pAc->wmmAcTspecInfo.ts_info.up,
+					   service_interval, suspension_interval,
+					   direction, psb, adapter->session_id,
+					   hdd_ctx->config->DelayedTriggerFrmInt);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Failed to enable U-APSD for AC=%d", acType);
+		return;
+	}
+	/* stash away the parameters that were used */
+	pAc->wmmAcUapsdInfoValid = true;
+	pAc->wmmAcUapsdServiceInterval = service_interval;
+	pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
+	pAc->wmmAcUapsdDirection = direction;
+	pAc->wmmAcIsUapsdEnabled = psb;
+
+	hdd_debug("Enabled UAPSD in TL srv_int=%d susp_int=%d dir=%d AC=%d",
+		   service_interval, suspension_interval, direction, acType);
+
+}
+
+/**
+ * hdd_wmm_disable_tl_uapsd() - function which decides whether
+ * to disable UAPSD parameters in TL
+ *
+ * @pQosContext: [in] the pointer the QoS instance control block
+ *
+ * Return: None
+ */
+static void hdd_wmm_disable_tl_uapsd(struct hdd_wmm_qos_context *pQosContext)
+{
+	struct hdd_adapter *adapter = pQosContext->adapter;
+	sme_ac_enum_type acType = pQosContext->acType;
+	struct hdd_wmm_ac_status *pAc = &adapter->hdd_wmm_status.wmmAcStatus[acType];
+	QDF_STATUS status;
+
+	/* have we previously enabled UAPSD? */
+	if (pAc->wmmAcUapsdInfoValid == true) {
+		status =
+			sme_disable_uapsd_for_ac((WLAN_HDD_GET_STATION_CTX_PTR
+							     (adapter))->conn_info.staId[0],
+						    acType, adapter->session_id);
+
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Failed to disable U-APSD for AC=%d", acType);
+		} else {
+			/* TL no longer has valid UAPSD info */
+			pAc->wmmAcUapsdInfoValid = false;
+			hdd_debug("Disabled UAPSD in TL for AC=%d", acType);
+		}
+	}
+}
+
+#endif
+
+/**
+ * hdd_wmm_free_context() - function which frees a QoS context
+ *
+ * @pQosContext: [in] the pointer the QoS instance control block
+ *
+ * Return: None
+ */
+static void hdd_wmm_free_context(struct hdd_wmm_qos_context *pQosContext)
+{
+	struct hdd_adapter *adapter;
+
+	hdd_debug("Entered, context %pK", pQosContext);
+
+	if (unlikely((NULL == pQosContext) ||
+		     (HDD_WMM_CTX_MAGIC != pQosContext->magic))) {
+		/* must have been freed in another thread */
+		return;
+	}
+	/* get pointer to the adapter context */
+	adapter = pQosContext->adapter;
+
+	/* take the wmmLock since we're manipulating the context list */
+	mutex_lock(&adapter->hdd_wmm_status.wmmLock);
+
+	/* make sure nobody thinks this is a valid context */
+	pQosContext->magic = 0;
+
+	/* unlink the context */
+	list_del(&pQosContext->node);
+
+	/* done manipulating the list */
+	mutex_unlock(&adapter->hdd_wmm_status.wmmLock);
+
+	/* reclaim memory */
+	qdf_mem_free(pQosContext);
+
+}
+
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+/**
+ * hdd_wmm_notify_app() - function which notifies an application
+ *			  of changes in state of it flow
+ *
+ * @pQosContext: [in] the pointer the QoS instance control block
+ *
+ * Return: None
+ */
+#define MAX_NOTIFY_LEN 50
+static void hdd_wmm_notify_app(struct hdd_wmm_qos_context *pQosContext)
+{
+	struct hdd_adapter *adapter;
+	union iwreq_data wrqu;
+	char buf[MAX_NOTIFY_LEN + 1];
+
+	hdd_debug("Entered, context %pK", pQosContext);
+
+	if (unlikely((NULL == pQosContext) ||
+		     (HDD_WMM_CTX_MAGIC != pQosContext->magic))) {
+		hdd_err("Invalid QoS Context");
+		return;
+	}
+
+	/* create the event */
+	memset(&wrqu, 0, sizeof(wrqu));
+	memset(buf, 0, sizeof(buf));
+
+	snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
+		 (unsigned int)pQosContext->handle,
+		 (unsigned int)pQosContext->lastStatus);
+
+	wrqu.data.pointer = buf;
+	wrqu.data.length = strlen(buf);
+
+	/* get pointer to the adapter */
+	adapter = pQosContext->adapter;
+
+	/* send the event */
+	hdd_debug("Sending [%s]", buf);
+	wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buf);
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * hdd_wmm_inactivity_timer_cb() - inactivity timer callback function
+ *
+ * @user_data: opaque user data registered with the timer.  In the
+ * case of this timer, the associated wmm QoS context is registered.
+ *
+ * This timer handler function is called for every inactivity interval
+ * per AC. This function gets the current transmitted packets on the
+ * given AC, and checks if there was any TX activity from the previous
+ * interval. If there was no traffic then it would delete the TS that
+ * was negotiated on that AC.
+ *
+ * Return: None
+ */
+static void hdd_wmm_inactivity_timer_cb(void *user_data)
+{
+	struct hdd_wmm_qos_context *pQosContext = user_data;
+	struct hdd_adapter *adapter;
+	struct hdd_wmm_ac_status *pAc;
+	hdd_wlan_wmm_status_e status;
+	QDF_STATUS qdf_status;
+	uint32_t currentTrafficCnt = 0;
+	sme_ac_enum_type acType;
+
+	if (!pQosContext) {
+		hdd_err("invalid user data");
+		return;
+	}
+	acType = pQosContext->acType;
+
+	adapter = pQosContext->adapter;
+	if ((NULL == adapter) ||
+	    (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
+		hdd_err("invalid adapter: %pK", adapter);
+		return;
+	}
+
+	pAc = &adapter->hdd_wmm_status.wmmAcStatus[acType];
+
+	/* Get the Tx stats for this AC. */
+	currentTrafficCnt =
+		adapter->hdd_stats.tx_rx_stats.tx_classified_ac[pQosContext->
+								    acType];
+
+	hdd_warn("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d",
+		 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
+	if (pAc->wmmPrevTrafficCnt == currentTrafficCnt) {
+		/* there is no traffic activity, delete the TSPEC for this AC */
+		status = hdd_wmm_delts(adapter, pQosContext->handle);
+		hdd_warn("Deleted TS on AC %d, due to inactivity with status = %d!!!",
+			 acType, status);
+	} else {
+		pAc->wmmPrevTrafficCnt = currentTrafficCnt;
+		if (pAc->wmmInactivityTimer.state == QDF_TIMER_STATE_STOPPED) {
+			/* Restart the timer */
+			qdf_status =
+				qdf_mc_timer_start(&pAc->wmmInactivityTimer,
+						   pAc->wmmInactivityTime);
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+				hdd_err("Restarting inactivity timer failed on AC %d",
+					acType);
+			}
+		} else {
+			QDF_ASSERT(qdf_mc_timer_get_current_state
+					   (&pAc->wmmInactivityTimer) ==
+				   QDF_TIMER_STATE_STOPPED);
+		}
+	}
+}
+
+/**
+ * hdd_wmm_enable_inactivity_timer() -
+ *	function to enable the traffic inactivity timer for the given AC
+ *
+ * @pQosContext: [in] pointer to pQosContext
+ * @inactivityTime: [in] value of the inactivity interval in millisecs
+ *
+ * When a QoS-Tspec is successfully setup, if the inactivity interval
+ * time specified in the AddTS parameters is non-zero, this function
+ * is invoked to start a traffic inactivity timer for the given AC.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS
+hdd_wmm_enable_inactivity_timer(struct hdd_wmm_qos_context *pQosContext,
+				uint32_t inactivityTime)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	struct hdd_adapter *adapter = pQosContext->adapter;
+	sme_ac_enum_type acType = pQosContext->acType;
+	struct hdd_wmm_ac_status *pAc;
+
+	adapter = pQosContext->adapter;
+	pAc = &adapter->hdd_wmm_status.wmmAcStatus[acType];
+
+	qdf_status = qdf_mc_timer_init(&pAc->wmmInactivityTimer,
+				       QDF_TIMER_TYPE_SW,
+				       hdd_wmm_inactivity_timer_cb,
+				       pQosContext);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Initializing inactivity timer failed on AC %d",
+			  acType);
+		return qdf_status;
+	}
+	/* Start the inactivity timer */
+	qdf_status = qdf_mc_timer_start(&pAc->wmmInactivityTimer,
+					inactivityTime);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Starting inactivity timer failed on AC %d",
+			  acType);
+		qdf_status = qdf_mc_timer_destroy(&pAc->wmmInactivityTimer);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			hdd_err("Failed to destroy inactivity timer");
+
+		return qdf_status;
+	}
+	pAc->wmmInactivityTime = inactivityTime;
+	/* Initialize the current tx traffic count on this AC */
+	pAc->wmmPrevTrafficCnt =
+		adapter->hdd_stats.tx_rx_stats.tx_classified_ac[pQosContext->
+								    acType];
+	pQosContext->is_inactivity_timer_running = true;
+	return qdf_status;
+}
+
+/**
+ * hdd_wmm_disable_inactivity_timer() -
+ *	function to disable the traffic inactivity timer for the given AC.
+ *
+ * @pQosContext: [in] pointer to pQosContext
+ *
+ * This function is invoked to disable the traffic inactivity timer
+ * for the given AC.  This is normally done when the TS is deleted.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS
+hdd_wmm_disable_inactivity_timer(struct hdd_wmm_qos_context *pQosContext)
+{
+	struct hdd_adapter *adapter = pQosContext->adapter;
+	sme_ac_enum_type acType = pQosContext->acType;
+	struct hdd_wmm_ac_status *pAc = &adapter->hdd_wmm_status.wmmAcStatus[acType];
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+
+	/* Clear the timer and the counter */
+	pAc->wmmInactivityTime = 0;
+	pAc->wmmPrevTrafficCnt = 0;
+
+	if (pQosContext->is_inactivity_timer_running == true) {
+		pQosContext->is_inactivity_timer_running = false;
+		qdf_status = qdf_mc_timer_stop(&pAc->wmmInactivityTimer);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			hdd_err("Failed to stop inactivity timer");
+			return qdf_status;
+		}
+		qdf_status = qdf_mc_timer_destroy(&pAc->wmmInactivityTimer);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			hdd_err("Failed to destroy inactivity timer:Timer started");
+	}
+
+	return qdf_status;
+}
+#else
+
+static QDF_STATUS
+hdd_wmm_disable_inactivity_timer(struct hdd_wmm_qos_context *pQosContext)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_ESE */
+
+/**
+ * hdd_wmm_sme_callback() - callback for QoS notifications
+ *
+ * @mac_handle: [in] the MAC handle
+ * @context : [in] the HDD callback context
+ * @pCurrentQosInfo : [in] the TSPEC params
+ * @smeStatus : [in] the QoS related SME status
+ * @qosFlowId: [in] the unique identifier of the flow
+ *
+ * This callback is registered by HDD with SME for receiving QoS
+ * notifications. Even though this function has a static scope it
+ * gets called externally through some function pointer magic (so
+ * there is a need for rigorous parameter checking).
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS hdd_wmm_sme_callback(mac_handle_t mac_handle,
+			void *context,
+			struct sme_qos_wmmtspecinfo *pCurrentQosInfo,
+			enum sme_qos_statustype smeStatus,
+			uint32_t qosFlowId)
+{
+	struct hdd_wmm_qos_context *pQosContext = context;
+	struct hdd_adapter *adapter;
+	sme_ac_enum_type acType;
+	struct hdd_wmm_ac_status *pAc;
+
+	hdd_debug("Entered, context %pK", pQosContext);
+
+	if (unlikely((NULL == pQosContext) ||
+		     (HDD_WMM_CTX_MAGIC != pQosContext->magic))) {
+		hdd_err("Invalid QoS Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	adapter = pQosContext->adapter;
+	acType = pQosContext->acType;
+	pAc = &adapter->hdd_wmm_status.wmmAcStatus[acType];
+
+	hdd_debug("status %d flowid %d info %pK",
+		 smeStatus, qosFlowId, pCurrentQosInfo);
+
+	switch (smeStatus) {
+
+	case SME_QOS_STATUS_SETUP_SUCCESS_IND:
+		hdd_debug("Setup is complete");
+
+		/* there will always be a TSPEC returned with this
+		 * status, even if a TSPEC is not exchanged OTA
+		 */
+		if (pCurrentQosInfo) {
+			pAc->wmmAcTspecValid = true;
+			memcpy(&pAc->wmmAcTspecInfo,
+			       pCurrentQosInfo, sizeof(pAc->wmmAcTspecInfo));
+		}
+		pAc->wmmAcAccessAllowed = true;
+		pAc->wmmAcAccessGranted = true;
+		pAc->wmmAcAccessPending = false;
+		pAc->wmmAcAccessFailed = false;
+
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+
+			hdd_debug("Explicit Qos, notifying user space");
+
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
+			hdd_wmm_notify_app(pQosContext);
+		}
+
+#ifdef FEATURE_WLAN_ESE
+		/* Check if the inactivity interval is specified */
+		if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
+			hdd_debug("Inactivity timer value = %d for AC=%d",
+				  pCurrentQosInfo->inactivity_interval, acType);
+			hdd_wmm_enable_inactivity_timer(pQosContext,
+							pCurrentQosInfo->
+							inactivity_interval);
+		}
+#endif /* FEATURE_WLAN_ESE */
+
+		/* notify TL to enable trigger frames if necessary */
+		hdd_wmm_enable_tl_uapsd(pQosContext);
+
+		break;
+
+	case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
+		hdd_debug("Setup is complete (U-APSD set previously)");
+
+		pAc->wmmAcAccessAllowed = true;
+		pAc->wmmAcAccessGranted = true;
+		pAc->wmmAcAccessPending = false;
+
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+
+			hdd_debug("Explicit Qos, notifying user space");
+
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
+			hdd_wmm_notify_app(pQosContext);
+		}
+
+		break;
+
+	case SME_QOS_STATUS_SETUP_FAILURE_RSP:
+		hdd_err("Setup failed");
+		/* QoS setup failed */
+
+		pAc->wmmAcAccessPending = false;
+		pAc->wmmAcAccessFailed = true;
+		pAc->wmmAcAccessAllowed = false;
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+
+			hdd_debug("Explicit Qos, notifying user space");
+
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_SETUP_FAILED;
+
+			hdd_wmm_notify_app(pQosContext);
+		}
+
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+
+		/* Setting up QoS Failed, QoS context can be released.
+		 * SME is releasing this flow information and if HDD
+		 * doesn't release this context, next time if
+		 * application uses the same handle to set-up QoS, HDD
+		 * (as it has QoS context for this handle) will issue
+		 * Modify QoS request to SME but SME will reject as now
+		 * it has no information for this flow.
+		 */
+		hdd_wmm_free_context(pQosContext);
+		break;
+
+	case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
+		hdd_err("Setup Invalid Params, notify TL");
+		/* QoS setup failed */
+		pAc->wmmAcAccessAllowed = false;
+
+		if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) {
+
+			/* we note the failure, but we also mark
+			 * access as allowed so that the packets will
+			 * flow.  Note that the MAC will "do the right
+			 * thing"
+			 */
+			pAc->wmmAcAccessPending = false;
+			pAc->wmmAcAccessFailed = true;
+			pAc->wmmAcAccessAllowed = true;
+
+		} else {
+			hdd_debug("Explicit Qos, notifying user space");
+
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+			hdd_wmm_notify_app(pQosContext);
+		}
+		break;
+
+	case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
+		hdd_err("Setup failed, not a QoS AP");
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+			hdd_info("Explicit Qos, notifying user space");
+
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
+			hdd_wmm_notify_app(pQosContext);
+		}
+		break;
+
+	case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
+		hdd_debug("Setup pending");
+		/* not a callback status -- ignore if we get it */
+		break;
+
+	case SME_QOS_STATUS_SETUP_MODIFIED_IND:
+		hdd_debug("Setup modified");
+		if (pCurrentQosInfo) {
+			/* update the TSPEC */
+			pAc->wmmAcTspecValid = true;
+			memcpy(&pAc->wmmAcTspecInfo,
+			       pCurrentQosInfo, sizeof(pAc->wmmAcTspecInfo));
+
+			if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+				hdd_debug("Explicit Qos, notifying user space");
+
+				/* this was triggered by an application */
+				pQosContext->lastStatus =
+					HDD_WLAN_WMM_STATUS_MODIFIED;
+				hdd_wmm_notify_app(pQosContext);
+			}
+			/* need to tell TL to update its UAPSD handling */
+			hdd_wmm_enable_tl_uapsd(pQosContext);
+		}
+		break;
+
+	case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
+		if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) {
+
+			/* this was triggered by implicit QoS so we
+			 * know packets are pending
+			 */
+			pAc->wmmAcAccessPending = false;
+			pAc->wmmAcAccessGranted = true;
+			pAc->wmmAcAccessAllowed = true;
+
+		} else {
+			hdd_debug("Explicit Qos, notifying user space");
+
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
+			hdd_wmm_notify_app(pQosContext);
+		}
+		break;
+
+	case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
+		/* nothing to do for now */
+		break;
+
+	case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
+		hdd_err("Setup successful but U-APSD failed");
+
+		if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) {
+
+			/* QoS setup was successful but setting U=APSD
+			 * failed.  Since the OTA part of the request
+			 * was successful, we don't mark this as a
+			 * failure.  the packets will flow.  Note that
+			 * the MAC will "do the right thing"
+			 */
+			pAc->wmmAcAccessGranted = true;
+			pAc->wmmAcAccessAllowed = true;
+			pAc->wmmAcAccessFailed = false;
+			pAc->wmmAcAccessPending = false;
+
+		} else {
+			hdd_info("Explicit Qos, notifying user space");
+
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
+			hdd_wmm_notify_app(pQosContext);
+		}
+
+		/* Since U-APSD portion failed disabled trigger frame
+		 * generation
+		 */
+		hdd_wmm_disable_tl_uapsd(pQosContext);
+
+		break;
+
+	case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
+		hdd_debug("Release is complete");
+
+		if (pCurrentQosInfo) {
+			hdd_debug("flows still active");
+
+			/* there is still at least one flow active for
+			 * this AC so update the AC state
+			 */
+			memcpy(&pAc->wmmAcTspecInfo,
+			       pCurrentQosInfo, sizeof(pAc->wmmAcTspecInfo));
+
+			/* need to tell TL to update its UAPSD handling */
+			hdd_wmm_enable_tl_uapsd(pQosContext);
+		} else {
+			hdd_debug("last flow");
+
+			/* this is the last flow active for this AC so
+			 * update the AC state
+			 */
+			pAc->wmmAcTspecValid = false;
+
+			/* DELTS is successful, do not allow */
+			pAc->wmmAcAccessAllowed = false;
+
+			/* need to tell TL to update its UAPSD handling */
+			hdd_wmm_disable_tl_uapsd(pQosContext);
+		}
+
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+			hdd_debug("Explicit Qos, notifying user space");
+
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
+			hdd_wmm_notify_app(pQosContext);
+		}
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+
+		/* we are done with this flow */
+		hdd_wmm_free_context(pQosContext);
+		break;
+
+	case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
+		hdd_debug("Release failure");
+
+		/* we don't need to update our state or TL since
+		 * nothing has changed
+		 */
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+			hdd_debug("Explicit Qos, notifying user space");
+
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
+			hdd_wmm_notify_app(pQosContext);
+		}
+
+		break;
+
+	case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
+		hdd_debug("QOS Lost indication received");
+
+		/* current TSPEC is no longer valid */
+		pAc->wmmAcTspecValid = false;
+		/* AP has sent DELTS, do not allow */
+		pAc->wmmAcAccessAllowed = false;
+
+		/* need to tell TL to update its UAPSD handling */
+		hdd_wmm_disable_tl_uapsd(pQosContext);
+
+		if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) {
+			/* we no longer have implicit access granted */
+			pAc->wmmAcAccessGranted = false;
+			pAc->wmmAcAccessFailed = false;
+		} else {
+			hdd_debug("Explicit Qos, notifying user space");
+
+			/* this was triggered by an application */
+			pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
+			hdd_wmm_notify_app(pQosContext);
+		}
+
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+
+		/* we are done with this flow */
+		hdd_wmm_free_context(pQosContext);
+		break;
+
+	case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
+		hdd_debug("Release pending");
+		/* not a callback status -- ignore if we get it */
+		break;
+
+	case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
+		hdd_err("Release Invalid Params");
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
+			hdd_wmm_notify_app(pQosContext);
+		}
+		break;
+
+	case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
+		hdd_debug("Modification is complete, notify TL");
+
+		/* there will always be a TSPEC returned with this
+		 * status, even if a TSPEC is not exchanged OTA
+		 */
+		if (pCurrentQosInfo) {
+			pAc->wmmAcTspecValid = true;
+			memcpy(&pAc->wmmAcTspecInfo,
+			       pCurrentQosInfo, sizeof(pAc->wmmAcTspecInfo));
+		}
+
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
+			hdd_wmm_notify_app(pQosContext);
+		}
+		/* notify TL to enable trigger frames if necessary */
+		hdd_wmm_enable_tl_uapsd(pQosContext);
+
+		break;
+
+	case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
+			hdd_wmm_notify_app(pQosContext);
+		}
+		break;
+
+	case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
+		/* the flow modification failed so we'll leave in
+		 * place whatever existed beforehand
+		 */
+
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
+			hdd_wmm_notify_app(pQosContext);
+		}
+		break;
+
+	case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
+		hdd_debug("modification pending");
+		/* not a callback status -- ignore if we get it */
+		break;
+
+	case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
+		/* the flow modification was successful but no QoS
+		 * changes required
+		 */
+
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
+			hdd_wmm_notify_app(pQosContext);
+		}
+		break;
+
+	case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
+		/* invalid params -- notify the application */
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
+			hdd_wmm_notify_app(pQosContext);
+		}
+		break;
+
+	case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
+		/* nothing to do for now.  when APSD is established we'll have work to do */
+		break;
+
+	case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
+		hdd_err("Modify successful but U-APSD failed");
+
+		/* QoS modification was successful but setting U=APSD
+		 * failed.  This will always be an explicit QoS
+		 * instance, so all we can do is notify the
+		 * application and let it clean up.
+		 */
+		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
+			/* this was triggered by an application */
+			pQosContext->lastStatus =
+				HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
+			hdd_wmm_notify_app(pQosContext);
+		}
+		/* Since U-APSD portion failed disabled trigger frame
+		 * generation
+		 */
+		hdd_wmm_disable_tl_uapsd(pQosContext);
+
+		break;
+
+	case SME_QOS_STATUS_HANDING_OFF:
+		/* no roaming so we won't see this */
+		break;
+
+	case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
+		/* need to tell TL to stop trigger frame generation */
+		hdd_wmm_disable_tl_uapsd(pQosContext);
+		break;
+
+	case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
+		/* need to tell TL to start sending trigger frames again */
+		hdd_wmm_enable_tl_uapsd(pQosContext);
+		break;
+
+	default:
+		hdd_err("unexpected SME Status=%d", smeStatus);
+		QDF_ASSERT(0);
+	}
+
+	/* if Tspec only allows downstream traffic then access is not
+	 * allowed
+	 */
+	if (pAc->wmmAcTspecValid &&
+	    (pAc->wmmAcTspecInfo.ts_info.direction ==
+	     SME_QOS_WMM_TS_DIR_DOWNLINK)) {
+		pAc->wmmAcAccessAllowed = false;
+	}
+	/* if we have valid Tpsec or if ACM bit is not set, allow access */
+	if ((pAc->wmmAcTspecValid &&
+	     (pAc->wmmAcTspecInfo.ts_info.direction !=
+	      SME_QOS_WMM_TS_DIR_DOWNLINK)) || !pAc->wmmAcAccessRequired) {
+		pAc->wmmAcAccessAllowed = true;
+	}
+
+	hdd_debug("complete, access for TL AC %d is%sallowed",
+		   acType, pAc->wmmAcAccessAllowed ? " " : " not ");
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * hdd_wmmps_helper() - Function to set uapsd psb dynamically
+ *
+ * @adapter: [in] pointer to adapter structure
+ * @ptr: [in] pointer to command buffer
+ *
+ * Return: Zero on success, appropriate error on failure.
+ */
+int hdd_wmmps_helper(struct hdd_adapter *adapter, uint8_t *ptr)
+{
+	if (NULL == adapter) {
+		hdd_err("adapter is NULL");
+		return -EINVAL;
+	}
+	if (NULL == ptr) {
+		hdd_err("ptr is NULL");
+		return -EINVAL;
+	}
+	/* convert ASCII to integer */
+	adapter->configured_psb = ptr[9] - '0';
+	adapter->psb_changed = HDD_PSB_CHANGED;
+
+	return 0;
+}
+
+/**
+ * __hdd_wmm_do_implicit_qos() - Function which will attempt to setup
+ *				QoS for any AC requiring it.
+ * @work: [in] pointer to work structure.
+ *
+ * Return: none
+ */
+static void __hdd_wmm_do_implicit_qos(struct work_struct *work)
+{
+	struct hdd_wmm_qos_context *pQosContext =
+		container_of(work, struct hdd_wmm_qos_context,
+			     wmmAcSetupImplicitQos);
+	struct hdd_adapter *adapter;
+	sme_ac_enum_type acType;
+	struct hdd_wmm_ac_status *pAc;
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	enum sme_qos_statustype smeStatus;
+#endif
+	struct sme_qos_wmmtspecinfo qosInfo;
+	struct hdd_context *hdd_ctx;
+	mac_handle_t mac_handle;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t dir_ac, mask = 0;
+	uint16_t nom_msdu_size_ac = 0;
+	uint32_t rate_ac = 0;
+	uint16_t sba_ac = 0;
+	uint32_t uapsd_value = 0;
+
+	hdd_debug("Entered, context %pK", pQosContext);
+
+	if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic)) {
+		hdd_err("Invalid QoS Context");
+		return;
+	}
+
+	adapter = pQosContext->adapter;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	mac_handle = hdd_ctx->mac_handle;
+
+	acType = pQosContext->acType;
+	pAc = &adapter->hdd_wmm_status.wmmAcStatus[acType];
+
+	hdd_debug("adapter %pK acType %d", adapter, acType);
+
+	if (!pAc->wmmAcAccessNeeded) {
+		hdd_err("AC %d doesn't need service", acType);
+		pQosContext->magic = 0;
+		qdf_mem_free(pQosContext);
+		return;
+	}
+
+	pAc->wmmAcAccessPending = true;
+	pAc->wmmAcAccessNeeded = false;
+
+	memset(&qosInfo, 0, sizeof(qosInfo));
+
+	qosInfo.ts_info.psb = adapter->configured_psb;
+
+	switch (acType) {
+	case SME_AC_VO:
+		qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
+		/* Check if there is any valid configuration from framework */
+		if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
+			status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
+							      &mask);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				hdd_err("Get uapsd_mask failed");
+				return;
+			}
+			qosInfo.ts_info.psb = (mask & SME_QOS_UAPSD_VO) ? 1 : 0;
+		}
+		status = ucfg_mlme_get_wmm_dir_ac_vo(hdd_ctx->psoc,
+						     &dir_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get infra_dir_ac_vo failed");
+			return;
+		}
+		qosInfo.ts_info.direction = dir_ac;
+
+		qosInfo.ts_info.tid = 255;
+
+		status = ucfg_mlme_get_wmm_uapsd_vo_srv_intv(hdd_ctx->psoc,
+							     &uapsd_value);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Get uapsd_srv_intv failed");
+			return;
+		}
+		qosInfo.min_service_interval = uapsd_value;
+
+		status = ucfg_mlme_get_wmm_uapsd_vo_sus_intv(hdd_ctx->psoc,
+							     &uapsd_value);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Get uapsd_vo_sus_intv failed");
+			return;
+		}
+		qosInfo.suspension_interval = uapsd_value;
+
+		status = ucfg_mlme_get_wmm_mean_data_rate_ac_vo(hdd_ctx->psoc,
+								&rate_ac);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Get mean_data_rate_ac_vo failed");
+			return;
+		}
+		qosInfo.mean_data_rate = rate_ac;
+
+		status = ucfg_mlme_get_wmm_min_phy_rate_ac_vo(hdd_ctx->psoc,
+							      &rate_ac);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Get min_phy_rate_ac_vo failed");
+			return;
+		}
+		qosInfo.min_phy_rate = rate_ac;
+
+		status = ucfg_mlme_get_wmm_nom_msdu_size_ac_vo(hdd_ctx->psoc,
+							     &nom_msdu_size_ac);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Get nom_msdu_size_ac_vo failed");
+			return;
+		}
+		qosInfo.nominal_msdu_size = nom_msdu_size_ac;
+
+		status = ucfg_mlme_get_wmm_sba_ac_vo(hdd_ctx->psoc,
+						     &sba_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get sba_ac_vo failed");
+			return;
+		}
+		qosInfo.surplus_bw_allowance = sba_ac;
+
+		break;
+	case SME_AC_VI:
+		qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
+		/* Check if there is any valid configuration from framework */
+		if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
+			status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
+							      &mask);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				hdd_err("Get uapsd_mask failed");
+				return;
+			}
+			qosInfo.ts_info.psb = (mask & SME_QOS_UAPSD_VI) ? 1 : 0;
+		}
+		status = ucfg_mlme_get_wmm_dir_ac_vi(
+			hdd_ctx->psoc, &dir_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get infra_dir_ac_vi failed");
+			return;
+		}
+		qosInfo.ts_info.direction = dir_ac;
+
+		qosInfo.ts_info.tid = 255;
+		status = ucfg_mlme_get_wmm_uapsd_vi_srv_intv(
+			hdd_ctx->psoc, &uapsd_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_vi_srv_intv failed");
+			return;
+		}
+		qosInfo.min_service_interval = uapsd_value;
+
+		status = ucfg_mlme_get_wmm_uapsd_vi_sus_intv(
+			hdd_ctx->psoc, &uapsd_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_vi_sus_intv failed");
+			return;
+		}
+		qosInfo.suspension_interval = uapsd_value;
+
+		status = ucfg_mlme_get_wmm_mean_data_rate_ac_vi(
+			hdd_ctx->psoc, &rate_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get mean_data_rate_ac_vi failed");
+			return;
+		}
+		qosInfo.mean_data_rate = rate_ac;
+
+		status = ucfg_mlme_get_wmm_min_phy_rate_ac_vi(
+			hdd_ctx->psoc, &rate_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get min_phy_rate_ac_vi failed");
+			return;
+		}
+		qosInfo.min_phy_rate = rate_ac;
+
+		status = ucfg_mlme_get_wmm_nom_msdu_size_ac_vi(
+			hdd_ctx->psoc, &nom_msdu_size_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get nom_msdu_size_ac_vi failed");
+			return;
+		}
+		qosInfo.nominal_msdu_size = nom_msdu_size_ac;
+
+		status = ucfg_mlme_get_wmm_sba_ac_vi(
+			hdd_ctx->psoc, &sba_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get sba_ac_vi failed");
+			return;
+		}
+		qosInfo.surplus_bw_allowance = sba_ac;
+
+		break;
+	default:
+	case SME_AC_BE:
+		qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
+		/* Check if there is any valid configuration from framework */
+		if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
+			status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
+							      &mask);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				hdd_err("Get uapsd_mask failed");
+				return;
+			}
+			qosInfo.ts_info.psb = (mask & SME_QOS_UAPSD_BE) ? 1 : 0;
+		}
+		status = ucfg_mlme_get_wmm_dir_ac_be(hdd_ctx->psoc, &dir_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get infra_dir_ac_be failed");
+			return;
+		}
+		qosInfo.ts_info.direction = dir_ac;
+
+		qosInfo.ts_info.tid = 255;
+		status = ucfg_mlme_get_wmm_uapsd_be_srv_intv(hdd_ctx->psoc,
+							     &uapsd_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_vi_srv_intv failed");
+			return;
+		}
+		qosInfo.min_service_interval = uapsd_value;
+
+		status = ucfg_mlme_get_wmm_uapsd_be_sus_intv(hdd_ctx->psoc,
+							     &uapsd_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_vi_sus_intv failed");
+			return;
+		}
+		qosInfo.suspension_interval = uapsd_value;
+
+		status = ucfg_mlme_get_wmm_mean_data_rate_ac_be(hdd_ctx->psoc,
+								&rate_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get mean_data_rate_ac_be failed");
+			return;
+		}
+		qosInfo.mean_data_rate = rate_ac;
+
+		status = ucfg_mlme_get_wmm_min_phy_rate_ac_be(hdd_ctx->psoc,
+							      &rate_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get min_phy_rate_ac_be failed");
+			return;
+		}
+		qosInfo.min_phy_rate = rate_ac;
+
+		status = ucfg_mlme_get_wmm_nom_msdu_size_ac_be(hdd_ctx->psoc,
+							    &nom_msdu_size_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get nom_msdu_size_ac_be failed");
+			return;
+		}
+		qosInfo.nominal_msdu_size = nom_msdu_size_ac;
+
+		status = ucfg_mlme_get_wmm_sba_ac_be(hdd_ctx->psoc, &sba_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get sba_ac_be failed");
+			return;
+		}
+		qosInfo.surplus_bw_allowance = sba_ac;
+
+		break;
+	case SME_AC_BK:
+		qosInfo.ts_info.up = SME_QOS_WMM_UP_BK;
+		/* Check if there is any valid configuration from framework */
+		if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
+			status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
+							      &mask);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				hdd_err("Get uapsd_mask failed");
+				return;
+			}
+			qosInfo.ts_info.psb = (mask & SME_QOS_UAPSD_BK) ? 1 : 0;
+		}
+
+		status = ucfg_mlme_get_wmm_dir_ac_bk(hdd_ctx->psoc, &dir_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get infra_dir_ac_bk failed");
+			return;
+		}
+		qosInfo.ts_info.direction = dir_ac;
+
+		qosInfo.ts_info.tid = 255;
+		status = ucfg_mlme_get_wmm_uapsd_bk_srv_intv(hdd_ctx->psoc,
+							     &uapsd_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_bk_srv_intv failed");
+			return;
+		}
+		qosInfo.min_service_interval = uapsd_value;
+
+		status = ucfg_mlme_get_wmm_uapsd_bk_sus_intv(hdd_ctx->psoc,
+							     &uapsd_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_bk_sus_intv failed");
+			return;
+		}
+		qosInfo.suspension_interval = uapsd_value;
+
+		status = ucfg_mlme_get_wmm_mean_data_rate_ac_bk(hdd_ctx->psoc,
+								&rate_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get mean_data_rate_ac_bk failed");
+			return;
+		}
+		qosInfo.mean_data_rate = rate_ac;
+
+		status = ucfg_mlme_get_wmm_min_phy_rate_ac_bk(hdd_ctx->psoc,
+							      &rate_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get min_phy_rate_ac_bk failed");
+			return;
+		}
+		qosInfo.min_phy_rate = rate_ac;
+
+		status =
+		  ucfg_mlme_get_wmm_nom_msdu_size_ac_bk(hdd_ctx->psoc,
+							&nom_msdu_size_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get nom_msdu_size_ac_bk failed");
+			return;
+		}
+		qosInfo.nominal_msdu_size = nom_msdu_size_ac;
+
+		status = ucfg_mlme_get_wmm_sba_ac_bk(hdd_ctx->psoc, &sba_ac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get sba_ac_bk failed");
+			return;
+		}
+		qosInfo.surplus_bw_allowance = sba_ac;
+
+		break;
+	}
+#ifdef FEATURE_WLAN_ESE
+	qosInfo.inactivity_interval =
+		(WLAN_HDD_GET_CTX(adapter))->config->InfraInactivityInterval;
+#endif
+	qosInfo.ts_info.burst_size_defn =
+		(WLAN_HDD_GET_CTX(adapter))->config->burstSizeDefinition;
+
+	switch ((WLAN_HDD_GET_CTX(adapter))->config->tsInfoAckPolicy) {
+	case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
+		qosInfo.ts_info.ack_policy =
+			SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
+		break;
+
+	case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
+		qosInfo.ts_info.ack_policy =
+			SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
+		break;
+
+	default:
+		/* unknown */
+		qosInfo.ts_info.ack_policy =
+			SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
+	}
+
+	if (qosInfo.ts_info.ack_policy ==
+	    SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK) {
+		if (!sme_qos_is_ts_info_ack_policy_valid(mac_handle, &qosInfo,
+							 adapter->session_id)) {
+			qosInfo.ts_info.ack_policy =
+				SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
+		}
+	}
+
+	mutex_lock(&adapter->hdd_wmm_status.wmmLock);
+	list_add(&pQosContext->node, &adapter->hdd_wmm_status.wmmContextList);
+	mutex_unlock(&adapter->hdd_wmm_status.wmmLock);
+
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	smeStatus = sme_qos_setup_req(mac_handle,
+				      adapter->session_id,
+				      &qosInfo,
+				      hdd_wmm_sme_callback,
+				      pQosContext,
+				      qosInfo.ts_info.up,
+				      &pQosContext->qosFlowId);
+
+	hdd_debug("sme_qos_setup_req returned %d flowid %d",
+		   smeStatus, pQosContext->qosFlowId);
+
+	/* need to check the return values and act appropriately */
+	switch (smeStatus) {
+	case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
+	case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
+		/* setup is pending, so no more work to do now.  all
+		 * further work will be done in hdd_wmm_sme_callback()
+		 */
+		hdd_debug("Setup is pending, no further work");
+
+		break;
+
+	case SME_QOS_STATUS_SETUP_FAILURE_RSP:
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+
+		/* we can't tell the difference between when a request
+		 * fails because AP rejected it versus when SME
+		 * encountered an internal error.  in either case SME
+		 * won't ever reference this context so free the
+		 * record
+		 */
+		hdd_wmm_free_context(pQosContext);
+
+		/* fall through and start packets flowing */
+	case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
+		/* no ACM in effect, no need to setup U-APSD */
+	case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
+		/* no ACM in effect, U-APSD is desired but was already setup */
+
+		/* for these cases everything is already setup so we
+		 * can signal TL that it has work to do
+		 */
+		hdd_debug("Setup is complete, notify TL");
+
+		pAc->wmmAcAccessAllowed = true;
+		pAc->wmmAcAccessGranted = true;
+		pAc->wmmAcAccessPending = false;
+
+		break;
+
+	default:
+		hdd_err("unexpected SME Status=%d", smeStatus);
+		QDF_ASSERT(0);
+	}
+#endif
+
+}
+
+/**
+ * hdd_wmm_do_implicit_qos() - SSR wraper function for hdd_wmm_do_implicit_qos
+ * @work: pointer to work_struct
+ *
+ * Return: none
+ */
+static void hdd_wmm_do_implicit_qos(struct work_struct *work)
+{
+	cds_ssr_protect(__func__);
+	__hdd_wmm_do_implicit_qos(work);
+	cds_ssr_unprotect(__func__);
+}
+
+/**
+ * hdd_wmm_init() - initialize the WMM DSCP configuation
+ * @adapter : [in]  pointer to Adapter context
+ *
+ * This function will initialize the WMM DSCP configuation of an
+ * adapter to an initial state.  The configuration can later be
+ * overwritten via application APIs or via QoS Map sent OTA.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_init(struct hdd_adapter *adapter)
+{
+	enum sme_qos_wmmuptype *dscp_to_up_map = adapter->dscp_to_up_map;
+	uint8_t dscp;
+
+	hdd_enter();
+
+	/* DSCP to User Priority Lookup Table
+	 * By default use the 3 Precedence bits of DSCP as the User Priority
+	 */
+	for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
+		dscp_to_up_map[dscp] = dscp >> 3;
+
+	/* Special case for Expedited Forwarding (DSCP 46) */
+	dscp_to_up_map[46] = SME_QOS_WMM_UP_VO;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_wmm_adapter_init() - initialize the WMM configuration of an adapter
+ * @adapter: [in]  pointer to Adapter context
+ *
+ * This function will initialize the WMM configuation and status of an
+ * adapter to an initial state.  The configuration can later be
+ * overwritten via application APIs
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_adapter_init(struct hdd_adapter *adapter)
+{
+	struct hdd_wmm_ac_status *pAcStatus;
+	sme_ac_enum_type acType;
+
+	hdd_enter();
+
+	adapter->hdd_wmm_status.wmmQap = false;
+	INIT_LIST_HEAD(&adapter->hdd_wmm_status.wmmContextList);
+	mutex_init(&adapter->hdd_wmm_status.wmmLock);
+
+	for (acType = 0; acType < WLAN_MAX_AC; acType++) {
+		pAcStatus = &adapter->hdd_wmm_status.wmmAcStatus[acType];
+		pAcStatus->wmmAcAccessRequired = false;
+		pAcStatus->wmmAcAccessNeeded = false;
+		pAcStatus->wmmAcAccessPending = false;
+		pAcStatus->wmmAcAccessFailed = false;
+		pAcStatus->wmmAcAccessGranted = false;
+		pAcStatus->wmmAcAccessAllowed = false;
+		pAcStatus->wmmAcTspecValid = false;
+		pAcStatus->wmmAcUapsdInfoValid = false;
+	}
+	/* Invalid value(0xff) to indicate psb not configured through
+	 * framework initially.
+	 */
+	adapter->configured_psb = HDD_PSB_CFG_INVALID;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_wmm_adapter_clear() - Function which will clear the WMM status
+ * for all the ACs
+ *
+ * @adapter: [in]  pointer to Adapter context
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_adapter_clear(struct hdd_adapter *adapter)
+{
+	struct hdd_wmm_ac_status *pAcStatus;
+	sme_ac_enum_type acType;
+
+	hdd_enter();
+	for (acType = 0; acType < WLAN_MAX_AC; acType++) {
+		pAcStatus = &adapter->hdd_wmm_status.wmmAcStatus[acType];
+		pAcStatus->wmmAcAccessRequired = false;
+		pAcStatus->wmmAcAccessNeeded = false;
+		pAcStatus->wmmAcAccessPending = false;
+		pAcStatus->wmmAcAccessFailed = false;
+		pAcStatus->wmmAcAccessGranted = false;
+		pAcStatus->wmmAcAccessAllowed = false;
+		pAcStatus->wmmAcTspecValid = false;
+		pAcStatus->wmmAcUapsdInfoValid = false;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_wmm_close() - WMM close function
+ * @adapter: [in]  pointer to adapter context
+ *
+ * Function which will perform any necessary work to to clean up the
+ * WMM functionality prior to the kernel module unload.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_adapter_close(struct hdd_adapter *adapter)
+{
+	struct hdd_wmm_qos_context *pQosContext;
+
+	hdd_enter();
+
+	/* free any context records that we still have linked */
+	while (!list_empty(&adapter->hdd_wmm_status.wmmContextList)) {
+		pQosContext =
+			list_first_entry(&adapter->hdd_wmm_status.wmmContextList,
+					 struct hdd_wmm_qos_context, node);
+
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+
+		if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT
+			&& pQosContext->magic == HDD_WMM_CTX_MAGIC)
+			cds_flush_work(&pQosContext->wmmAcSetupImplicitQos);
+
+		hdd_wmm_free_context(pQosContext);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_wmm_classify_pkt() - Function which will classify an OS packet
+ * into a WMM AC based on DSCP
+ *
+ * @adapter: adapter upon which the packet is being transmitted
+ * @skb: pointer to network buffer
+ * @user_pri: user priority of the OS packet
+ * @is_eapol: eapol packet flag
+ *
+ * Return: None
+ */
+static
+void hdd_wmm_classify_pkt(struct hdd_adapter *adapter,
+			  struct sk_buff *skb,
+			  enum sme_qos_wmmuptype *user_pri,
+			  bool *is_eapol)
+{
+	unsigned char dscp;
+	unsigned char tos;
+	union generic_ethhdr *eth_hdr;
+	struct iphdr *ip_hdr;
+	struct ipv6hdr *ipv6hdr;
+	unsigned char *pkt;
+
+	/* this code is executed for every packet therefore
+	 * all debug code is kept conditional
+	 */
+
+#ifdef HDD_WMM_DEBUG
+	hdd_enter();
+#endif /* HDD_WMM_DEBUG */
+
+	pkt = skb->data;
+	eth_hdr = (union generic_ethhdr *)pkt;
+
+#ifdef HDD_WMM_DEBUG
+	hdd_debug("proto is 0x%04x", skb->protocol);
+#endif /* HDD_WMM_DEBUG */
+
+	if (eth_hdr->eth_II.h_proto == htons(ETH_P_IP)) {
+		/* case 1: Ethernet II IP packet */
+		ip_hdr = (struct iphdr *)&pkt[sizeof(eth_hdr->eth_II)];
+		tos = ip_hdr->tos;
+#ifdef HDD_WMM_DEBUG
+		hdd_debug("Ethernet II IP Packet, tos is %d", tos);
+#endif /* HDD_WMM_DEBUG */
+
+	} else if (eth_hdr->eth_II.h_proto == htons(ETH_P_IPV6)) {
+		ipv6hdr = ipv6_hdr(skb);
+		tos = ntohs(*(const __be16 *)ipv6hdr) >> 4;
+#ifdef HDD_WMM_DEBUG
+		hdd_debug("Ethernet II IPv6 Packet, tos is %d", tos);
+#endif /* HDD_WMM_DEBUG */
+	} else if ((ntohs(eth_hdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
+		  (eth_hdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
+		  (eth_hdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
+		  (eth_hdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
+		  (eth_hdr->eth_8023.h_proto == htons(ETH_P_IP))) {
+		/* case 2: 802.3 LLC/SNAP IP packet */
+		ip_hdr = (struct iphdr *)&pkt[sizeof(eth_hdr->eth_8023)];
+		tos = ip_hdr->tos;
+#ifdef HDD_WMM_DEBUG
+		hdd_debug("802.3 LLC/SNAP IP Packet, tos is %d", tos);
+#endif /* HDD_WMM_DEBUG */
+	} else if (eth_hdr->eth_II.h_proto == htons(ETH_P_8021Q)) {
+		/* VLAN tagged */
+
+		if (eth_hdr->eth_IIv.h_vlan_encapsulated_proto ==
+			htons(ETH_P_IP)) {
+			/* case 3: Ethernet II vlan-tagged IP packet */
+			ip_hdr =
+				(struct iphdr *)
+				&pkt[sizeof(eth_hdr->eth_IIv)];
+			tos = ip_hdr->tos;
+#ifdef HDD_WMM_DEBUG
+			hdd_debug("Ether II VLAN tagged IP Packet, tos is %d",
+				 tos);
+#endif /* HDD_WMM_DEBUG */
+		} else if ((ntohs(eth_hdr->eth_IIv.h_vlan_encapsulated_proto)
+			< WLAN_MIN_PROTO) &&
+			(eth_hdr->eth_8023v.h_snap.dsap ==
+			WLAN_SNAP_DSAP)
+			&& (eth_hdr->eth_8023v.h_snap.ssap ==
+			WLAN_SNAP_SSAP)
+			&& (eth_hdr->eth_8023v.h_snap.ctrl ==
+			WLAN_SNAP_CTRL)
+			&& (eth_hdr->eth_8023v.h_proto ==
+			htons(ETH_P_IP))) {
+			/* case 4: 802.3 LLC/SNAP vlan-tagged IP packet */
+			ip_hdr =
+				(struct iphdr *)
+				&pkt[sizeof(eth_hdr->eth_8023v)];
+			tos = ip_hdr->tos;
+#ifdef HDD_WMM_DEBUG
+			hdd_debug("802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
+				 tos);
+#endif /* HDD_WMM_DEBUG */
+		} else {
+			/* default */
+#ifdef HDD_WMM_DEBUG
+			hdd_warn("VLAN tagged Unhandled Protocol, using default tos");
+#endif /* HDD_WMM_DEBUG */
+			tos = 0;
+		}
+	} else {
+		/* default */
+#ifdef HDD_WMM_DEBUG
+		hdd_warn("Unhandled Protocol, using default tos");
+#endif /* HDD_WMM_DEBUG */
+		/* Give the highest priority to 802.1x packet */
+		if (eth_hdr->eth_II.h_proto ==
+			htons(HDD_ETHERTYPE_802_1_X)) {
+			tos = 0xC0;
+			*is_eapol = true;
+		} else
+			tos = 0;
+	}
+
+	dscp = (tos >> 2) & 0x3f;
+	*user_pri = adapter->dscp_to_up_map[dscp];
+
+#ifdef HDD_WMM_DEBUG
+	hdd_debug("tos is %d, dscp is %d, up is %d", tos, dscp, *user_pri);
+#endif /* HDD_WMM_DEBUG */
+}
+
+/**
+ * __hdd_get_queue_index() - get queue index
+ * @up: user priority
+ *
+ * Return: queue_index
+ */
+static uint16_t __hdd_get_queue_index(uint16_t up)
+{
+	if (qdf_unlikely(up >= ARRAY_SIZE(hdd_linux_up_to_ac_map)))
+		return HDD_LINUX_AC_BE;
+	return hdd_linux_up_to_ac_map[up];
+}
+
+#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_HL_NETDEV_FLOW_CONTROL)
+/**
+ * hdd_get_queue_index() - get queue index
+ * @up: user priority
+ * @is_eapol: is_eapol flag
+ *
+ * Return: queue_index
+ */
+static
+uint16_t hdd_get_queue_index(uint16_t up, bool is_eapol)
+{
+	if (qdf_unlikely(is_eapol == true))
+		return HDD_LINUX_AC_HI_PRIO;
+	return __hdd_get_queue_index(up);
+}
+#else
+static
+uint16_t hdd_get_queue_index(uint16_t up, bool is_eapol)
+{
+	return __hdd_get_queue_index(up);
+}
+#endif
+
+
+/**
+ * hdd_hostapd_select_queue() - Function which will classify the packet
+ *       according to linux qdisc expectation.
+ *
+ * @dev: [in] pointer to net_device structure
+ * @skb: [in] pointer to os packet
+ *
+ * Return: Qdisc queue index
+ */
+uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
+				  , void *accel_priv
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+				  , select_queue_fallback_t fallback
+#endif
+
+)
+{
+	enum sme_qos_wmmuptype up = SME_QOS_WMM_UP_BE;
+	uint16_t queueIndex;
+	struct hdd_adapter *adapter = (struct hdd_adapter *) netdev_priv(dev);
+	struct hdd_context *hddctx = WLAN_HDD_GET_CTX(adapter);
+	bool is_eapol = false;
+	int status = 0;
+
+	status = wlan_hdd_validate_context(hddctx);
+
+	if (status != 0) {
+		skb->priority = SME_QOS_WMM_UP_BE;
+		return HDD_LINUX_AC_BE;
+	}
+
+	/* Get the user priority from IP header */
+	hdd_wmm_classify_pkt(adapter, skb, &up, &is_eapol);
+	skb->priority = up;
+	queueIndex = hdd_get_queue_index(skb->priority, is_eapol);
+
+	return queueIndex;
+}
+
+/**
+ * hdd_wmm_select_queue() - Function which will classify the packet
+ *       according to linux qdisc expectation.
+ *
+ * @dev: [in] pointer to net_device structure
+ * @skb: [in] pointer to os packet
+ *
+ * Return: Qdisc queue index
+ */
+uint16_t hdd_wmm_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+	enum sme_qos_wmmuptype up = SME_QOS_WMM_UP_BE;
+	uint16_t queueIndex;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	bool is_crtical = false;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	int status;
+	enum qdf_proto_subtype proto_subtype;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status != 0) {
+		skb->priority = SME_QOS_WMM_UP_BE;
+		return HDD_LINUX_AC_BE;
+	}
+
+	/* Get the user priority from IP header */
+	hdd_wmm_classify_pkt(adapter, skb, &up, &is_crtical);
+	spin_lock_bh(&adapter->pause_map_lock);
+	if ((adapter->pause_map & (1 <<  WLAN_DATA_FLOW_CONTROL)) &&
+	   !(adapter->pause_map & (1 <<  WLAN_DATA_FLOW_CONTROL_PRIORITY))) {
+		if (qdf_nbuf_is_ipv4_arp_pkt(skb))
+			is_crtical = true;
+		else if (qdf_nbuf_is_icmpv6_pkt(skb)) {
+			proto_subtype = qdf_nbuf_get_icmpv6_subtype(skb);
+			switch (proto_subtype) {
+			case QDF_PROTO_ICMPV6_NA:
+			case QDF_PROTO_ICMPV6_NS:
+				is_crtical = true;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+	spin_unlock_bh(&adapter->pause_map_lock);
+	skb->priority = up;
+	queueIndex = hdd_get_queue_index(skb->priority, is_crtical);
+
+	return queueIndex;
+}
+
+/**
+ * hdd_wmm_acquire_access_required() - Function which will determine
+ * acquire admittance for a WMM AC is required or not based on psb configuration
+ * done in framework
+ *
+ * @adapter: [in] pointer to adapter structure
+ * @acType: [in] WMM AC type of OS packet
+ *
+ * Return: void
+ */
+void hdd_wmm_acquire_access_required(struct hdd_adapter *adapter,
+				     sme_ac_enum_type acType)
+{
+	/* Each bit in the LSB nibble indicates 1 AC.
+	 * Clearing the particular bit in LSB nibble to indicate
+	 * access required
+	 */
+	switch (acType) {
+	case SME_AC_BK:
+		/* clear first bit */
+		adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK;
+		break;
+	case SME_AC_BE:
+		/* clear second bit */
+		adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK;
+		break;
+	case SME_AC_VI:
+		/* clear third bit */
+		adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK;
+		break;
+	case SME_AC_VO:
+		/* clear fourth bit */
+		adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK;
+		break;
+	default:
+		hdd_err("Invalid AC Type");
+		break;
+	}
+}
+
+/**
+ * hdd_wmm_acquire_access() - Function which will attempt to acquire
+ * admittance for a WMM AC
+ *
+ * @adapter: [in]  pointer to adapter context
+ * @acType: [in]  WMM AC type of OS packet
+ * @pGranted: [out] pointer to bool flag when indicates if access
+ *	      has been granted or not
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_acquire_access(struct hdd_adapter *adapter,
+				  sme_ac_enum_type acType, bool *pGranted)
+{
+	struct hdd_wmm_qos_context *pQosContext;
+	struct hdd_context *hdd_ctx;
+	bool enable;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Entered for AC %d", __func__, acType);
+
+	status = ucfg_mlme_get_implicit_qos_is_enabled(hdd_ctx->psoc, &enable);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get implicit_qos_is_enabled failed");
+		}
+	if (!hdd_wmm_is_active(adapter) || !(enable) ||
+	    !adapter->hdd_wmm_status.wmmAcStatus[acType].wmmAcAccessRequired) {
+		/* either we don't want QoS or the AP doesn't support
+		 * QoS or we don't want to do implicit QoS
+		 */
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: QoS not configured on both ends ", __func__);
+
+		*pGranted =
+			adapter->hdd_wmm_status.wmmAcStatus[acType].
+			wmmAcAccessAllowed;
+
+		return QDF_STATUS_SUCCESS;
+	}
+	/* do we already have an implicit QoS request pending for this AC? */
+	if ((adapter->hdd_wmm_status.wmmAcStatus[acType].wmmAcAccessNeeded) ||
+	    (adapter->hdd_wmm_status.wmmAcStatus[acType].wmmAcAccessPending)) {
+		/* request already pending so we need to wait for that
+		 * response
+		 */
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: Implicit QoS for TL AC %d already scheduled",
+			  __func__, acType);
+
+		*pGranted = false;
+		return QDF_STATUS_SUCCESS;
+	}
+	/* did we already fail to establish implicit QoS for this AC?
+	 * (if so, access should have been granted when the failure
+	 * was handled)
+	 */
+	if (adapter->hdd_wmm_status.wmmAcStatus[acType].wmmAcAccessFailed) {
+		/* request previously failed
+		 * allow access, but we'll be downgraded
+		 */
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: Implicit QoS for TL AC %d previously failed",
+			  __func__, acType);
+
+		if (!adapter->hdd_wmm_status.wmmAcStatus[acType].
+		    wmmAcAccessRequired) {
+			adapter->hdd_wmm_status.wmmAcStatus[acType].
+			wmmAcAccessAllowed = true;
+			*pGranted = true;
+		} else {
+			adapter->hdd_wmm_status.wmmAcStatus[acType].
+			wmmAcAccessAllowed = false;
+			*pGranted = false;
+		}
+
+		return QDF_STATUS_SUCCESS;
+	}
+	/* we need to establish implicit QoS */
+	QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Need to schedule implicit QoS for TL AC %d, adapter is %pK",
+		  __func__, acType, adapter);
+
+	adapter->hdd_wmm_status.wmmAcStatus[acType].wmmAcAccessNeeded = true;
+
+	pQosContext = qdf_mem_malloc(sizeof(*pQosContext));
+	if (NULL == pQosContext) {
+		/* no memory for QoS context.  Nothing we can do but
+		 * let data flow
+		 */
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Unable to allocate context", __func__);
+		adapter->hdd_wmm_status.wmmAcStatus[acType].wmmAcAccessAllowed =
+			true;
+		*pGranted = true;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	pQosContext->acType = acType;
+	pQosContext->adapter = adapter;
+	pQosContext->qosFlowId = 0;
+	pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
+	pQosContext->magic = HDD_WMM_CTX_MAGIC;
+	pQosContext->is_inactivity_timer_running = false;
+
+	INIT_WORK(&pQosContext->wmmAcSetupImplicitQos, hdd_wmm_do_implicit_qos);
+
+	QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Scheduling work for AC %d, context %pK",
+		  __func__, acType, pQosContext);
+
+	schedule_work(&pQosContext->wmmAcSetupImplicitQos);
+
+	/* caller will need to wait until the work takes place and
+	 * TSPEC negotiation completes
+	 */
+	*pGranted = false;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_wmm_assoc() - Function which will handle the housekeeping
+ * required by WMM when association takes place
+ *
+ * @adapter: [in]  pointer to adapter context
+ * @roam_info: [in]  pointer to roam information
+ * @eBssType: [in]  type of BSS
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_assoc(struct hdd_adapter *adapter,
+			 struct csr_roam_info *roam_info,
+			 eCsrRoamBssType eBssType)
+{
+	uint8_t uapsdMask;
+	QDF_STATUS status;
+	uint32_t srv_value = 0;
+	uint32_t sus_value = 0;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	/* when we associate we need to notify TL if it needs to
+	 * enable UAPSD for any access categories
+	 */
+
+	hdd_enter();
+
+	if (roam_info->fReassocReq) {
+		/* when we reassociate we should continue to use
+		 * whatever parameters were previously established.
+		 * if we are reassociating due to a U-APSD change for
+		 * a particular Access Category, then the change will
+		 * be communicated to HDD via the QoS callback
+		 * associated with the given flow, and U-APSD
+		 * parameters will be updated there
+		 */
+
+		hdd_debug("Reassoc so no work, Exiting");
+
+		return QDF_STATUS_SUCCESS;
+	}
+	/* get the negotiated UAPSD Mask */
+	uapsdMask =
+		roam_info->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
+
+	hdd_debug("U-APSD mask is 0x%02x", (int)uapsdMask);
+
+	if (uapsdMask & HDD_AC_VO) {
+		status = ucfg_mlme_get_wmm_uapsd_vo_srv_intv(hdd_ctx->psoc,
+							     &srv_value);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Get uapsd_srv_intv failed");
+			return QDF_STATUS_SUCCESS;
+		}
+		status = ucfg_mlme_get_wmm_uapsd_vo_sus_intv(hdd_ctx->psoc,
+							     &sus_value);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Get uapsd_vo_sus_intv failed");
+			return QDF_STATUS_SUCCESS;
+		}
+
+		status = sme_enable_uapsd_for_ac(
+				(WLAN_HDD_GET_STATION_CTX_PTR(
+				adapter))->conn_info.staId[0],
+				SME_AC_VO, 7, 7, srv_value, sus_value,
+				SME_QOS_WMM_TS_DIR_BOTH, 1,
+				adapter->session_id,
+				hdd_ctx->config->DelayedTriggerFrmInt);
+
+		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
+	}
+
+	if (uapsdMask & HDD_AC_VI) {
+		status = ucfg_mlme_get_wmm_uapsd_vi_srv_intv(
+			hdd_ctx->psoc, &srv_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_vi_srv_intv failed");
+			return QDF_STATUS_SUCCESS;
+		}
+		status = ucfg_mlme_get_wmm_uapsd_vi_sus_intv(
+			hdd_ctx->psoc, &sus_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_vi_sus_intv failed");
+			return QDF_STATUS_SUCCESS;
+		}
+
+		status = sme_enable_uapsd_for_ac(
+				(WLAN_HDD_GET_STATION_CTX_PTR(
+				adapter))->conn_info.staId[0],
+				SME_AC_VI, 5, 5, srv_value, sus_value,
+				SME_QOS_WMM_TS_DIR_BOTH, 1,
+				adapter->session_id,
+				hdd_ctx->config->DelayedTriggerFrmInt);
+
+		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
+	}
+
+	if (uapsdMask & HDD_AC_BK) {
+		status = ucfg_mlme_get_wmm_uapsd_bk_srv_intv(hdd_ctx->psoc,
+							     &srv_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_bk_srv_intv failed");
+			return QDF_STATUS_SUCCESS;
+		}
+		status = ucfg_mlme_get_wmm_uapsd_bk_sus_intv(hdd_ctx->psoc,
+							     &sus_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_bk_sus_intv failed");
+			return QDF_STATUS_SUCCESS;
+		}
+
+		status = sme_enable_uapsd_for_ac(
+				(WLAN_HDD_GET_STATION_CTX_PTR(
+				adapter))->conn_info.staId[0],
+				SME_AC_BK, 2, 2, srv_value, sus_value,
+				SME_QOS_WMM_TS_DIR_BOTH, 1,
+				adapter->session_id,
+				hdd_ctx->config->DelayedTriggerFrmInt);
+
+		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
+	}
+
+	if (uapsdMask & HDD_AC_BE) {
+		status = ucfg_mlme_get_wmm_uapsd_be_srv_intv(hdd_ctx->psoc,
+							     &srv_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_be_srv_intv failed");
+			return QDF_STATUS_SUCCESS;
+		}
+		status = ucfg_mlme_get_wmm_uapsd_be_sus_intv(hdd_ctx->psoc,
+							     &sus_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_be_sus_intv failed");
+			return QDF_STATUS_SUCCESS;
+		}
+
+		status = sme_enable_uapsd_for_ac(
+				(WLAN_HDD_GET_STATION_CTX_PTR(
+				adapter))->conn_info.staId[0],
+				SME_AC_BE, 3, 3, srv_value, sus_value,
+				SME_QOS_WMM_TS_DIR_BOTH, 1,
+				adapter->session_id,
+				hdd_ctx->config->DelayedTriggerFrmInt);
+
+		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
+	}
+
+	status = sme_update_dsc_pto_up_mapping(hdd_ctx->mac_handle,
+					       adapter->dscp_to_up_map,
+					       adapter->session_id);
+
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_wmm_init(adapter);
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static const uint8_t acm_mask_bit[WLAN_MAX_AC] = {
+	0x4,                    /* SME_AC_BK */
+	0x8,                    /* SME_AC_BE */
+	0x2,                    /* SME_AC_VI */
+	0x1                     /* SME_AC_VO */
+};
+
+/**
+ * hdd_wmm_connect() - Function which will handle the housekeeping
+ * required by WMM when a connection is established
+ *
+ * @adapter : [in]  pointer to adapter context
+ * @roam_info: [in]  pointer to roam information
+ * @eBssType : [in]  type of BSS
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_connect(struct hdd_adapter *adapter,
+			   struct csr_roam_info *roam_info,
+			   eCsrRoamBssType eBssType)
+{
+	int ac;
+	bool qap;
+	bool qosConnection;
+	uint8_t acmMask;
+	mac_handle_t mac_handle;
+
+	hdd_enter();
+
+	if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
+	    roam_info && roam_info->u.pConnectedProfile) {
+		qap = roam_info->u.pConnectedProfile->qap;
+		qosConnection = roam_info->u.pConnectedProfile->qosConnection;
+		acmMask = roam_info->u.pConnectedProfile->acm_mask;
+	} else {
+		qap = true;
+		qosConnection = true;
+		acmMask = 0x0;
+	}
+
+	hdd_debug("qap is %d, qosConnection is %d, acmMask is 0x%x",
+		 qap, qosConnection, acmMask);
+
+	adapter->hdd_wmm_status.wmmQap = qap;
+	adapter->hdd_wmm_status.wmmQosConnection = qosConnection;
+	mac_handle = hdd_adapter_get_mac_handle(adapter);
+
+	for (ac = 0; ac < WLAN_MAX_AC; ac++) {
+		if (qap && qosConnection && (acmMask & acm_mask_bit[ac])) {
+			hdd_debug("ac %d on", ac);
+
+			/* admission is required */
+			adapter->hdd_wmm_status.wmmAcStatus[ac].
+			wmmAcAccessRequired = true;
+			adapter->hdd_wmm_status.wmmAcStatus[ac].
+			wmmAcAccessAllowed = false;
+			adapter->hdd_wmm_status.wmmAcStatus[ac].
+			wmmAcAccessGranted = false;
+			/* after reassoc if we have valid tspec, allow access */
+			if (adapter->hdd_wmm_status.wmmAcStatus[ac].
+			    wmmAcTspecValid
+			    && (adapter->hdd_wmm_status.wmmAcStatus[ac].
+				wmmAcTspecInfo.ts_info.direction !=
+				SME_QOS_WMM_TS_DIR_DOWNLINK)) {
+				adapter->hdd_wmm_status.wmmAcStatus[ac].
+				wmmAcAccessAllowed = true;
+			}
+			if (!roam_info->fReassocReq &&
+			    !sme_neighbor_roam_is11r_assoc(
+						mac_handle,
+						adapter->session_id) &&
+			    !sme_roam_is_ese_assoc(roam_info)) {
+				adapter->hdd_wmm_status.wmmAcStatus[ac].
+					wmmAcTspecValid = false;
+				adapter->hdd_wmm_status.wmmAcStatus[ac].
+					wmmAcAccessAllowed = false;
+			}
+		} else {
+			hdd_debug("ac %d off", ac);
+			/* admission is not required so access is allowed */
+			adapter->hdd_wmm_status.wmmAcStatus[ac].
+			wmmAcAccessRequired = false;
+			adapter->hdd_wmm_status.wmmAcStatus[ac].
+			wmmAcAccessAllowed = true;
+		}
+
+	}
+
+	hdd_exit();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_wmm_get_uapsd_mask() - Function which will calculate the
+ * initial value of the UAPSD mask based upon the device configuration
+ *
+ * @adapter  : [in]  pointer to adapter context
+ * @pUapsdMask: [out] pointer to where the UAPSD Mask is to be stored
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_wmm_get_uapsd_mask(struct hdd_adapter *adapter,
+				  uint8_t *pUapsdMask)
+{
+	uint8_t uapsdMask;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	uint32_t uapsd_value = 0;
+	uint8_t wmm_mode = 0;
+
+	status = ucfg_mlme_get_wmm_mode(hdd_ctx->psoc, &wmm_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Get wmm_mode failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (HDD_WMM_USER_MODE_NO_QOS == wmm_mode) {
+		/* no QOS then no UAPSD */
+		uapsdMask = 0;
+	} else {
+		/* start with the default mask */
+		status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
+						      &uapsdMask);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_mask failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		/* disable UAPSD for any ACs with a 0 Service Interval */
+		status = ucfg_mlme_get_wmm_uapsd_vo_srv_intv(hdd_ctx->psoc,
+							     &uapsd_value);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			hdd_err("Get uapsd_srv_intv failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (uapsd_value == 0)
+			uapsdMask &= ~HDD_AC_VO;
+
+		status = ucfg_mlme_get_wmm_uapsd_vi_srv_intv(
+			hdd_ctx->psoc, &uapsd_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_vi_srv_intv failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+		if (uapsd_value == 0) {
+			uapsdMask &= ~HDD_AC_VI;
+		}
+
+		status = ucfg_mlme_get_wmm_uapsd_bk_srv_intv(hdd_ctx->psoc,
+							     &uapsd_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_bk_srv_intv failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+		if (uapsd_value == 0)
+			uapsdMask &= ~HDD_AC_BK;
+
+		status = ucfg_mlme_get_wmm_uapsd_be_srv_intv(hdd_ctx->psoc,
+							     &uapsd_value);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			hdd_err("Get uapsd_be_srv_intv failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+		if (uapsd_value == 0) {
+			uapsdMask &= ~HDD_AC_BE;
+		}
+	}
+
+	/* return calculated mask */
+	*pUapsdMask = uapsdMask;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_wmm_is_active() - Function which will determine if WMM is
+ * active on the current connection
+ *
+ * @adapter: [in]  pointer to adapter context
+ *
+ * Return: true if WMM is enabled, false if WMM is not enabled
+ */
+bool hdd_wmm_is_active(struct hdd_adapter *adapter)
+{
+	if ((!adapter->hdd_wmm_status.wmmQosConnection) ||
+	    (!adapter->hdd_wmm_status.wmmQap)) {
+		return false;
+	} else {
+		return true;
+	}
+}
+
+bool hdd_wmm_is_acm_allowed(uint8_t vdev_id)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_wmm_ac_status *wmm_ac_status;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("Unable to fetch the hdd context");
+		return false;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (hdd_validate_adapter(adapter)) {
+		hdd_err("Invalid adapter");
+		return false;
+	}
+
+	wmm_ac_status = adapter->hdd_wmm_status.wmmAcStatus;
+
+	if (hdd_wmm_is_active(adapter) &&
+	    !(wmm_ac_status[OL_TX_WMM_AC_VI].wmmAcAccessAllowed))
+		return false;
+	return true;
+}
+
+/**
+ * hdd_wmm_addts() - Function which will add a traffic spec at the
+ * request of an application
+ *
+ * @adapter  : [in]  pointer to adapter context
+ * @handle    : [in]  handle to uniquely identify a TS
+ * @pTspec    : [in]  pointer to the traffic spec
+ *
+ * Return: HDD_WLAN_WMM_STATUS_*
+ */
+hdd_wlan_wmm_status_e hdd_wmm_addts(struct hdd_adapter *adapter,
+				    uint32_t handle,
+				    struct sme_qos_wmmtspecinfo *pTspec)
+{
+	struct hdd_wmm_qos_context *pQosContext;
+	hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	enum sme_qos_statustype smeStatus;
+#endif
+	bool found = false;
+	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
+
+	hdd_debug("Entered with handle 0x%x", handle);
+
+	/* see if a context already exists with the given handle */
+	mutex_lock(&adapter->hdd_wmm_status.wmmLock);
+	list_for_each_entry(pQosContext,
+			    &adapter->hdd_wmm_status.wmmContextList, node) {
+		if (pQosContext->handle == handle) {
+			found = true;
+			break;
+		}
+	}
+	mutex_unlock(&adapter->hdd_wmm_status.wmmLock);
+	if (found) {
+		/* record with that handle already exists */
+		hdd_err("Record already exists with handle 0x%x", handle);
+
+		/* Application is trying to modify some of the Tspec
+		 * params. Allow it
+		 */
+		smeStatus = sme_qos_modify_req(mac_handle,
+					       pTspec, pQosContext->qosFlowId);
+
+		/* need to check the return value and act appropriately */
+		switch (smeStatus) {
+		case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
+			status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
+			break;
+		case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
+			status =
+				HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
+			break;
+		case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
+			status =
+				HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
+			break;
+		case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
+			status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
+			break;
+		case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
+			status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
+			break;
+		case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
+			status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
+			break;
+		default:
+			/* we didn't get back one of the
+			 * SME_QOS_STATUS_MODIFY_* status codes
+			 */
+			hdd_err("unexpected SME Status=%d",
+				  smeStatus);
+			QDF_ASSERT(0);
+			return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
+		}
+
+		/* we were successful, save the status */
+		mutex_lock(&adapter->hdd_wmm_status.wmmLock);
+		if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
+			pQosContext->lastStatus = status;
+		mutex_unlock(&adapter->hdd_wmm_status.wmmLock);
+
+		return status;
+	}
+
+	pQosContext = qdf_mem_malloc(sizeof(*pQosContext));
+	if (NULL == pQosContext) {
+		/* no memory for QoS context.  Nothing we can do */
+		hdd_err("Unable to allocate QoS context");
+		return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
+	}
+	/* we assume the tspec has already been validated by the caller */
+
+	pQosContext->handle = handle;
+	if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
+		pQosContext->acType = hdd_wmm_up_to_ac_map[pTspec->ts_info.up];
+	else {
+		hdd_err("ts_info.up (%d) larger than max value (%d), use default acType (%d)",
+			pTspec->ts_info.up,
+			HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hdd_wmm_up_to_ac_map[0]);
+		pQosContext->acType = hdd_wmm_up_to_ac_map[0];
+	}
+	pQosContext->adapter = adapter;
+	pQosContext->qosFlowId = 0;
+	pQosContext->magic = HDD_WMM_CTX_MAGIC;
+	pQosContext->is_inactivity_timer_running = false;
+
+	hdd_debug("Setting up QoS, context %pK", pQosContext);
+
+	mutex_lock(&adapter->hdd_wmm_status.wmmLock);
+	list_add(&pQosContext->node, &adapter->hdd_wmm_status.wmmContextList);
+	mutex_unlock(&adapter->hdd_wmm_status.wmmLock);
+
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	smeStatus = sme_qos_setup_req(mac_handle,
+				      adapter->session_id,
+				      pTspec,
+				      hdd_wmm_sme_callback,
+				      pQosContext,
+				      pTspec->ts_info.up,
+				      &pQosContext->qosFlowId);
+
+	hdd_debug("sme_qos_setup_req returned %d flowid %d",
+		   smeStatus, pQosContext->qosFlowId);
+
+	/* need to check the return value and act appropriately */
+	switch (smeStatus) {
+	case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
+		status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
+		break;
+	case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
+		status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
+		break;
+	case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
+		status =
+			HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
+		break;
+	case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
+		status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
+		break;
+	case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+		hdd_wmm_free_context(pQosContext);
+		return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
+	case SME_QOS_STATUS_SETUP_FAILURE_RSP:
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+		/* we can't tell the difference between when a request
+		 * fails because AP rejected it versus when SME
+		 * encounterd an internal error
+		 */
+		hdd_wmm_free_context(pQosContext);
+		return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
+	case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+		hdd_wmm_free_context(pQosContext);
+		return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
+	default:
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+		/* we didn't get back one of the
+		 * SME_QOS_STATUS_SETUP_* status codes
+		 */
+		hdd_wmm_free_context(pQosContext);
+		hdd_err("unexpected SME Status=%d", smeStatus);
+		QDF_ASSERT(0);
+		return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
+	}
+#endif
+
+	/* we were successful, save the status */
+	mutex_lock(&adapter->hdd_wmm_status.wmmLock);
+	if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
+		pQosContext->lastStatus = status;
+	mutex_unlock(&adapter->hdd_wmm_status.wmmLock);
+
+	return status;
+}
+
+/**
+ * hdd_wmm_delts() - Function which will delete a traffic spec at the
+ * request of an application
+ *
+ * @adapter: [in]  pointer to adapter context
+ * @handle: [in]  handle to uniquely identify a TS
+ *
+ * Return: HDD_WLAN_WMM_STATUS_*
+ */
+hdd_wlan_wmm_status_e hdd_wmm_delts(struct hdd_adapter *adapter,
+				    uint32_t handle)
+{
+	struct hdd_wmm_qos_context *pQosContext;
+	bool found = false;
+	sme_ac_enum_type acType = 0;
+	uint32_t qosFlowId = 0;
+	hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	enum sme_qos_statustype smeStatus;
+	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
+#endif
+
+	hdd_debug("Entered with handle 0x%x", handle);
+
+	/* locate the context with the given handle */
+	mutex_lock(&adapter->hdd_wmm_status.wmmLock);
+	list_for_each_entry(pQosContext,
+			    &adapter->hdd_wmm_status.wmmContextList, node) {
+		if (pQosContext->handle == handle) {
+			found = true;
+			acType = pQosContext->acType;
+			qosFlowId = pQosContext->qosFlowId;
+			break;
+		}
+	}
+	mutex_unlock(&adapter->hdd_wmm_status.wmmLock);
+
+	if (false == found) {
+		/* we didn't find the handle */
+		hdd_info("handle 0x%x not found", handle);
+		return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
+	}
+
+	hdd_debug("found handle 0x%x, flow %d, AC %d, context %pK",
+		 handle, qosFlowId, acType, pQosContext);
+
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	smeStatus = sme_qos_release_req(mac_handle, adapter->session_id,
+					qosFlowId);
+
+	hdd_debug("SME flow %d released, SME status %d", qosFlowId, smeStatus);
+
+	switch (smeStatus) {
+	case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
+		/* this flow is the only one on that AC, so go ahead
+		 * and update our TSPEC state for the AC
+		 */
+		adapter->hdd_wmm_status.wmmAcStatus[acType].wmmAcTspecValid =
+			false;
+		adapter->hdd_wmm_status.wmmAcStatus[acType].wmmAcAccessAllowed =
+			false;
+
+		/* need to tell TL to stop trigger timer, etc */
+		hdd_wmm_disable_tl_uapsd(pQosContext);
+
+		/* disable the inactivity timer */
+		hdd_wmm_disable_inactivity_timer(pQosContext);
+
+		/* we are done with this context */
+		hdd_wmm_free_context(pQosContext);
+
+		/* SME must not fire any more callbacks for this flow
+		 * since the context is no longer valid
+		 */
+
+		return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
+
+	case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
+		/* do nothing as we will get a response from SME */
+		status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
+		break;
+
+	case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
+		/* nothing we can do with the existing flow except leave it */
+		status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
+		break;
+
+	case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
+		/* nothing we can do with the existing flow except leave it */
+		status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
+		break;
+
+	default:
+		/* we didn't get back one of the
+		 * SME_QOS_STATUS_RELEASE_* status codes
+		 */
+		hdd_err("unexpected SME Status=%d", smeStatus);
+		QDF_ASSERT(0);
+		status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
+	}
+
+#endif
+	mutex_lock(&adapter->hdd_wmm_status.wmmLock);
+	if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
+		pQosContext->lastStatus = status;
+	mutex_unlock(&adapter->hdd_wmm_status.wmmLock);
+
+	return status;
+}
+
+/**
+ * hdd_wmm_checkts() - Function which will return the status of a traffic
+ * spec at the request of an application
+ *
+ * @adapter: [in]  pointer to adapter context
+ * @handle: [in]  handle to uniquely identify a TS
+ *
+ * Return: HDD_WLAN_WMM_STATUS_*
+ */
+hdd_wlan_wmm_status_e hdd_wmm_checkts(struct hdd_adapter *adapter, uint32_t handle)
+{
+	struct hdd_wmm_qos_context *pQosContext;
+	hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
+
+	hdd_debug("Entered with handle 0x%x", handle);
+
+	/* locate the context with the given handle */
+	mutex_lock(&adapter->hdd_wmm_status.wmmLock);
+	list_for_each_entry(pQosContext,
+			    &adapter->hdd_wmm_status.wmmContextList, node) {
+		if (pQosContext->handle == handle) {
+			hdd_debug("found handle 0x%x, context %pK",
+				 handle, pQosContext);
+
+			status = pQosContext->lastStatus;
+			break;
+		}
+	}
+	mutex_unlock(&adapter->hdd_wmm_status.wmmLock);
+	return status;
+}
diff --git a/core/hdd/src/wlan_hdd_wowl.c b/core/hdd/src/wlan_hdd_wowl.c
new file mode 100644
index 0000000..379e0e9
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_wowl.c
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/**
+ * @file wlan_hdd_wowl.c
+ *
+ * @brief wake up on WLAN API file
+ */
+
+/* Include Files */
+
+#include "qdf_str.h"
+#include <wlan_hdd_includes.h>
+#include <wlan_hdd_wowl.h>
+#include <wlan_pmo_wow_public_struct.h>
+
+/* Preprocessor Definitions and Constants */
+#define WOWL_INTER_PTRN_TOKENIZER   ';'
+#define WOWL_INTRA_PTRN_TOKENIZER   ':'
+
+/* Type Declarations */
+
+static char *g_hdd_wowl_ptrns[WOWL_MAX_PTRNS_ALLOWED];
+static bool g_hdd_wowl_ptrns_debugfs[WOWL_MAX_PTRNS_ALLOWED] = { 0 };
+
+static uint8_t g_hdd_wowl_ptrns_count;
+
+static inline int find_ptrn_len(const char *ptrn)
+{
+	int len = 0;
+
+	while (*ptrn != '\0' && *ptrn != WOWL_INTER_PTRN_TOKENIZER) {
+		len++;
+		ptrn++;
+	}
+	return len;
+}
+
+/**
+ * dump_hdd_wowl_ptrn() - log wow patterns
+ * @ptrn: pointer to wow pattern
+ *
+ * Return: none
+ */
+static void dump_hdd_wowl_ptrn(struct pmo_wow_add_pattern *ptrn)
+{
+	int i;
+
+	hdd_info("Pattern Id = 0x%x", ptrn->pattern_id);
+	hdd_info("Pattern Byte Offset = 0x%x", ptrn->pattern_byte_offset);
+	hdd_info("Pattern_size = 0x%x", ptrn->pattern_size);
+	hdd_info("Pattern_mask_size = 0x%x", ptrn->pattern_mask_size);
+	hdd_info("Pattern: ");
+	for (i = 0; i < ptrn->pattern_size; i++)
+		hdd_info(" %02X", ptrn->pattern[i]);
+	hdd_info("pattern_mask: ");
+	for (i = 0; i < ptrn->pattern_mask_size; i++)
+		hdd_info("%02X", ptrn->pattern_mask[i]);
+}
+
+static QDF_STATUS
+hdd_get_num_wow_filters(struct hdd_context *hdd_ctx, uint8_t *num_filters)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
+
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_HDD_ID_OBJ_MGR);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	*num_filters = ucfg_pmo_get_num_wow_filters(hdd_ctx->psoc);
+
+	wlan_objmgr_psoc_release_ref(psoc, WLAN_HDD_ID_OBJ_MGR);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_add_wowl_ptrn() - Function which will add the WoWL pattern to be
+ *			 used when PBM filtering is enabled
+ * @adapter: pointer to the adapter
+ * @ptrn: pointer to the pattern string to be added
+ *
+ * Return: false if any errors encountered, true otherwise
+ */
+bool hdd_add_wowl_ptrn(struct hdd_adapter *adapter, const char *ptrn)
+{
+	struct pmo_wow_add_pattern localPattern;
+	int i, empty_slot, len, offset;
+	QDF_STATUS status;
+	const char *temp;
+	uint8_t sessionId = adapter->session_id;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	uint8_t num_filters;
+
+	status = hdd_get_num_wow_filters(hdd_ctx, &num_filters);
+	if (QDF_IS_STATUS_ERROR(status))
+		return false;
+
+	/* There has to have at least 1 byte for each field (pattern
+	 * size, mask size, pattern, mask) e.g. PP:QQ:RR:SS ==> 11
+	 * chars
+	 */
+	len = find_ptrn_len(ptrn);
+	while (len >= 11) {
+		empty_slot = -1;
+
+		/* check if pattern is already configured */
+		for (i = num_filters - 1; i >= 0; i--) {
+			if (g_hdd_wowl_ptrns[i] == NULL) {
+				empty_slot = i;
+				continue;
+			}
+
+			if (!memcmp(ptrn, g_hdd_wowl_ptrns[i], len)) {
+				hdd_err("WoWL pattern '%s' already configured",
+					g_hdd_wowl_ptrns[i]);
+				ptrn += len;
+				goto next_ptrn;
+			}
+		}
+
+		/* Maximum number of patterns have been configured already */
+		if (empty_slot == -1) {
+			hdd_err("Max WoW patterns (%u) reached", num_filters);
+			return false;
+		}
+
+		/* Validate the pattern */
+		if (ptrn[2] != WOWL_INTRA_PTRN_TOKENIZER ||
+		    ptrn[5] != WOWL_INTRA_PTRN_TOKENIZER) {
+			hdd_err("Malformed pattern string. Skip!");
+			ptrn += len;
+			goto next_ptrn;
+		}
+
+		/* Extract the pattern size */
+		localPattern.pattern_size =
+			(hex_to_bin(ptrn[0]) * 0x10) + hex_to_bin(ptrn[1]);
+
+		/* Extract the pattern mask size */
+		localPattern.pattern_mask_size =
+			(hex_to_bin(ptrn[3]) * 0x10) + hex_to_bin(ptrn[4]);
+
+		if (localPattern.pattern_size > PMO_WOWL_BCAST_PATTERN_MAX_SIZE
+		    || localPattern.pattern_mask_size >
+		    WOWL_PTRN_MASK_MAX_SIZE) {
+			hdd_err("Invalid length specified. Skip!");
+			ptrn += len;
+			goto next_ptrn;
+		}
+
+		/* compute the offset of tokenizer after the pattern */
+		offset = 5 + 2 * localPattern.pattern_size + 1;
+		if ((offset >= len) ||
+		    (ptrn[offset] != WOWL_INTRA_PTRN_TOKENIZER)) {
+			hdd_err("Malformed pattern string..skip!");
+			ptrn += len;
+			goto next_ptrn;
+		}
+
+		/* compute the end of pattern sring */
+		offset = offset + 2 * localPattern.pattern_mask_size;
+		if (offset + 1 != len) {
+			/* offset begins with 0 */
+			hdd_err("Malformed pattern string...skip!");
+			ptrn += len;
+			goto next_ptrn;
+		}
+
+		temp = ptrn;
+
+		/* Now advance to where pattern begins */
+		ptrn += 6;
+
+		/* Extract the pattern */
+		for (i = 0; i < localPattern.pattern_size; i++) {
+			localPattern.pattern[i] =
+				(hex_to_bin(ptrn[0]) * 0x10) +
+				hex_to_bin(ptrn[1]);
+			ptrn += 2;      /* skip to next byte */
+		}
+
+		/* Skip over the ':' separator after the pattern */
+		ptrn++;
+
+		/* Extract the pattern Mask */
+		for (i = 0; i < localPattern.pattern_mask_size; i++) {
+			localPattern.pattern_mask[i] =
+				(hex_to_bin(ptrn[0]) * 0x10) +
+				hex_to_bin(ptrn[1]);
+			ptrn += 2;      /* skip to next byte */
+		}
+
+		/* All is good. Store the pattern locally */
+		g_hdd_wowl_ptrns[empty_slot] = qdf_mem_malloc(len + 1);
+		if (g_hdd_wowl_ptrns[empty_slot] == NULL) {
+			hdd_err("memory allocation failure");
+			return false;
+		}
+
+		memcpy(g_hdd_wowl_ptrns[empty_slot], temp, len);
+		g_hdd_wowl_ptrns[empty_slot][len] = '\0';
+		localPattern.pattern_id = empty_slot;
+		localPattern.pattern_byte_offset = 0;
+		localPattern.session_id = sessionId;
+
+		/* Register the pattern downstream */
+		status = ucfg_pmo_add_wow_user_pattern(
+					adapter->vdev, &localPattern);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			/* Add failed, so invalidate the local storage */
+			hdd_err("sme_wowl_add_bcast_pattern failed with error code (%d)",
+				status);
+			qdf_mem_free(g_hdd_wowl_ptrns[empty_slot]);
+			g_hdd_wowl_ptrns[empty_slot] = NULL;
+		}
+
+		dump_hdd_wowl_ptrn(&localPattern);
+
+next_ptrn:
+		if (*ptrn == WOWL_INTER_PTRN_TOKENIZER) {
+			/* move past the tokenizer */
+			ptrn += 1;
+			len = find_ptrn_len(ptrn);
+			continue;
+		} else {
+			break;
+		}
+	}
+
+	return true;
+}
+
+/**
+ * hdd_del_wowl_ptrn() - Function which will remove a WoWL pattern
+ * @adapter: pointer to the adapter
+ * @ptrn: pointer to the pattern string to be removed
+ *
+ * Return: false if any errors encountered, true otherwise
+ */
+bool hdd_del_wowl_ptrn(struct hdd_adapter *adapter, const char *ptrn)
+{
+	uint8_t id;
+	bool patternFound = false;
+	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	uint8_t num_filters;
+
+	status = hdd_get_num_wow_filters(hdd_ctx, &num_filters);
+	if (QDF_IS_STATUS_ERROR(status))
+		return false;
+
+	/* lookup pattern */
+	for (id = 0; id < num_filters; id++) {
+		if (!g_hdd_wowl_ptrns[id])
+			continue;
+
+		if (qdf_str_eq(ptrn, g_hdd_wowl_ptrns[id])) {
+			patternFound = true;
+			break;
+		}
+	}
+
+	/* If pattern present, remove it from downstream */
+	if (!patternFound)
+		return false;
+
+	status = ucfg_pmo_del_wow_user_pattern(adapter->vdev, id);
+	if (QDF_IS_STATUS_ERROR(status))
+		return false;
+
+	/* Remove from local storage as well */
+	hdd_err("Deleted pattern with id %d [%s]", id, g_hdd_wowl_ptrns[id]);
+
+	qdf_mem_free(g_hdd_wowl_ptrns[id]);
+	g_hdd_wowl_ptrns[id] = NULL;
+
+	return true;
+}
+
+/**
+ * hdd_add_wowl_ptrn_debugfs() - Function which will add a WoW pattern
+ *				 sent from debugfs interface
+ * @adapter: pointer to the adapter
+ * @pattern_idx: index of the pattern to be added
+ * @pattern_offset: offset of the pattern in the frame payload
+ * @pattern_buf: pointer to the pattern hex string to be added
+ * @pattern_mask: pointer to the pattern mask hex string
+ *
+ * Return: false if any errors encountered, true otherwise
+ */
+bool hdd_add_wowl_ptrn_debugfs(struct hdd_adapter *adapter, uint8_t pattern_idx,
+			       uint8_t pattern_offset, char *pattern_buf,
+			       char *pattern_mask)
+{
+	struct pmo_wow_add_pattern localPattern;
+	QDF_STATUS qdf_ret_status;
+	uint8_t session_id = adapter->session_id;
+	uint16_t pattern_len, mask_len, i;
+
+	if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1)) {
+		hdd_err("WoW pattern index %d is out of range (0 ~ %d)",
+			pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1);
+
+		return false;
+	}
+
+	pattern_len = strlen(pattern_buf);
+
+	/* Since the pattern is a hex string, 2 characters represent 1 byte. */
+	if (pattern_len % 2) {
+		hdd_err("Malformed WoW pattern!");
+
+		return false;
+	}
+
+	pattern_len >>= 1;
+	if (!pattern_len || pattern_len > WOWL_PTRN_MAX_SIZE) {
+		hdd_err("WoW pattern length %d is out of range (1 ~ %d).",
+			pattern_len, WOWL_PTRN_MAX_SIZE);
+
+		return false;
+	}
+
+	localPattern.pattern_id = pattern_idx;
+	localPattern.pattern_byte_offset = pattern_offset;
+	localPattern.pattern_size = pattern_len;
+	localPattern.session_id = session_id;
+
+	if (localPattern.pattern_size > PMO_WOWL_BCAST_PATTERN_MAX_SIZE) {
+		hdd_err("WoW pattern size (%d) greater than max (%d)",
+			localPattern.pattern_size,
+			PMO_WOWL_BCAST_PATTERN_MAX_SIZE);
+		return false;
+	}
+	/* Extract the pattern */
+	for (i = 0; i < localPattern.pattern_size; i++) {
+		localPattern.pattern[i] =
+			(hex_to_bin(pattern_buf[0]) << 4) +
+			hex_to_bin(pattern_buf[1]);
+
+		/* Skip to next byte */
+		pattern_buf += 2;
+	}
+
+	/* Get pattern mask size by pattern length */
+	localPattern.pattern_mask_size = pattern_len >> 3;
+	if (pattern_len % 8)
+		localPattern.pattern_mask_size += 1;
+
+	mask_len = strlen(pattern_mask);
+	if ((mask_len % 2)
+	    || (localPattern.pattern_mask_size != (mask_len >> 1))) {
+		hdd_err("Malformed WoW pattern mask!");
+
+		return false;
+	}
+	if (localPattern.pattern_mask_size > WOWL_PTRN_MASK_MAX_SIZE) {
+		hdd_err("WoW pattern mask size (%d) greater than max (%d)",
+			localPattern.pattern_mask_size,
+			WOWL_PTRN_MASK_MAX_SIZE);
+		return false;
+	}
+	/* Extract the pattern mask */
+	for (i = 0; i < localPattern.pattern_mask_size; i++) {
+		localPattern.pattern_mask[i] =
+			(hex_to_bin(pattern_mask[0]) << 4) +
+			hex_to_bin(pattern_mask[1]);
+
+		/* Skip to next byte */
+		pattern_mask += 2;
+	}
+
+	/* Register the pattern downstream */
+	qdf_ret_status = ucfg_pmo_add_wow_user_pattern(
+				adapter->vdev, &localPattern);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
+		hdd_err("pmo_wow_user_pattern failed with error code (%d).",
+			  qdf_ret_status);
+
+		return false;
+	}
+
+	/* All is good. */
+	if (!g_hdd_wowl_ptrns_debugfs[pattern_idx]) {
+		g_hdd_wowl_ptrns_debugfs[pattern_idx] = 1;
+		g_hdd_wowl_ptrns_count++;
+	}
+
+	dump_hdd_wowl_ptrn(&localPattern);
+
+	return true;
+}
+
+/**
+ * hdd_del_wowl_ptrn_debugfs() - Function which will remove a WoW pattern
+ *				 sent from debugfs interface
+ * @adapter: pointer to the adapter
+ * @pattern_idx: index of the pattern to be removed
+ *
+ * Return: false if any errors encountered, true otherwise
+ */
+bool hdd_del_wowl_ptrn_debugfs(struct hdd_adapter *adapter,
+			       uint8_t pattern_idx)
+{
+	QDF_STATUS qdf_ret_status;
+
+	if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1)) {
+		hdd_err("WoW pattern index %d is not in the range (0 ~ %d).",
+			pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1);
+
+		return false;
+	}
+
+	if (!g_hdd_wowl_ptrns_debugfs[pattern_idx]) {
+		hdd_err("WoW pattern %d is not in the table.",
+			pattern_idx);
+
+		return false;
+	}
+
+	qdf_ret_status = ucfg_pmo_del_wow_user_pattern(
+				adapter->vdev, pattern_idx);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
+		hdd_err("sme_wowl_del_bcast_pattern failed with error code (%d).",
+			 qdf_ret_status);
+
+		return false;
+	}
+
+	g_hdd_wowl_ptrns_debugfs[pattern_idx] = 0;
+	g_hdd_wowl_ptrns_count--;
+
+	return true;
+}
+
+void hdd_free_user_wowl_ptrns(void)
+{
+	int i;
+
+	for (i = 0; i < WOWL_MAX_PTRNS_ALLOWED; ++i) {
+		if (g_hdd_wowl_ptrns[i]) {
+			qdf_mem_free(g_hdd_wowl_ptrns[i]);
+			g_hdd_wowl_ptrns[i] = NULL;
+		}
+	}
+}
diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h
new file mode 100644
index 0000000..0a8d9f3
--- /dev/null
+++ b/core/mac/inc/ani_global.h
@@ -0,0 +1,933 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef _ANIGLOBAL_H
+#define _ANIGLOBAL_H
+
+#include "qdf_types.h"
+#include "sir_common.h"
+#include "ani_system_defs.h"
+#include "sys_def.h"
+#include "dph_global.h"
+#include "lim_global.h"
+#include "sch_global.h"
+#include "sys_global.h"
+#include "cfg_global.h"
+#include "sir_api.h"
+
+#include "csr_api.h"
+#include "sme_ft_api.h"
+#include "csr_support.h"
+#include "sme_internal.h"
+#include "sap_api.h"
+#include "csr_internal.h"
+
+#include "sme_rrm_internal.h"
+#include "rrm_global.h"
+
+#include <lim_ft_defs.h>
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_mlme_public_struct.h"
+
+/**
+ * MAC_CONTEXT() - Convert an opaque mac handle into a mac context
+ * @handle: MAC handle to be converted
+ *
+ * Given an opaque mac handle this function will return the mac
+ * context that is associated with that handle.
+ *
+ * This is the inverse function of MAC_HANDLE()
+ *
+ * Return: mac context for @handle
+ */
+static inline tpAniSirGlobal MAC_CONTEXT(mac_handle_t handle)
+{
+	return (tpAniSirGlobal)handle;
+}
+
+/* legacy definition */
+#define PMAC_STRUCT(handle)  MAC_CONTEXT(handle)
+
+/**
+ * MAC_HANDLE() - Convert a mac context into an opaque mac handle
+ * @mac: MAC context to be converted
+ *
+ * Given a mac context this function will return the opaque mac handle
+ * that is associated with that handle.
+ *
+ * This is the inverse function of PMAC_STRUCT()
+ *
+ * Return: opaque handle for @mac
+ */
+static inline mac_handle_t MAC_HANDLE(tpAniSirGlobal mac)
+{
+	return (mac_handle_t)mac;
+}
+
+#define ANI_DRIVER_TYPE(pMac)     (((tpAniSirGlobal)(pMac))->gDriverType)
+
+/* ------------------------------------------------------------------- */
+/* Bss Qos Caps bit map definition */
+#define LIM_BSS_CAPS_OFFSET_HCF 0
+#define LIM_BSS_CAPS_OFFSET_WME 1
+#define LIM_BSS_CAPS_OFFSET_WSM 2
+
+#define LIM_BSS_CAPS_HCF (1 << LIM_BSS_CAPS_OFFSET_HCF)
+#define LIM_BSS_CAPS_WME (1 << LIM_BSS_CAPS_OFFSET_WME)
+#define LIM_BSS_CAPS_WSM (1 << LIM_BSS_CAPS_OFFSET_WSM)
+
+/* cap should be one of HCF/WME/WSM */
+#define LIM_BSS_CAPS_GET(cap, val) (((val) & (LIM_BSS_CAPS_ ## cap)) >> LIM_BSS_CAPS_OFFSET_ ## cap)
+#define LIM_BSS_CAPS_SET(cap, val) ((val) |= (LIM_BSS_CAPS_ ## cap))
+#define LIM_BSS_CAPS_CLR(cap, val) ((val) &= (~(LIM_BSS_CAPS_ ## cap)))
+
+/* 40 beacons per heart beat interval is the default + 1 to count the rest */
+#define MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL 41
+
+/* max number of legacy bssid we can store during scan on one channel */
+#define MAX_NUM_LEGACY_BSSID_PER_CHANNEL    10
+
+#ifdef WLAN_FEATURE_CONCURRENT_P2P
+#define MAX_NO_OF_P2P_SESSIONS  5
+#endif /* WLAN_FEATURE_CONCURRENT_P2P */
+
+#define SPACE_ASCII_VALUE  32
+
+#define WLAN_HOST_SEQ_NUM_MIN                           2048
+#define WLAN_HOST_SEQ_NUM_MAX                           4095
+#define LOW_SEQ_NUM_MASK                                0x000F
+#define HIGH_SEQ_NUM_MASK                               0x0FF0
+#define HIGH_SEQ_NUM_OFFSET                             4
+#define DEF_HE_AUTO_SGI_LTF                             0x0F07
+
+/* vendor element ID */
+#define IE_EID_VENDOR        (221) /* 0xDD */
+#define IE_LEN_SIZE          (1)
+#define IE_EID_SIZE          (1)
+/* Minimum size of vendor IE = 3 bytes of oui_data + 1 byte of data */
+#define IE_VENDOR_OUI_SIZE   (4)
+
+/*
+ * NSS cfg bit definition.
+ * STA          BIT[0:1]
+ * SAP          BIT[2:3]
+ * P2P_GO       BIT[4:5]
+ * P2P_CLIENT   BIT[6:7]
+ * IBSS         BIT[8:9]
+ * TDLS         BIT[10:11]
+ * P2P_DEVICE   BIT[12:13]
+ * OCB          BIT[14:15]
+ */
+
+#define CFG_STA_NSS(_x)     ((((_x) >> 0) & 0x3) ? (((_x) >> 0) & 0x3) : 1)
+#define CFG_SAP_NSS(_x)     ((((_x) >> 2) & 0x3) ? (((_x) >> 2) & 0x3) : 1)
+#define CFG_P2P_GO_NSS(_x)  ((((_x) >> 4) & 0x3) ? (((_x) >> 4) & 0x3) : 1)
+#define CFG_P2P_CLI_NSS(_x) ((((_x) >> 6) & 0x3) ? (((_x) >> 6) & 0x3) : 1)
+#define CFG_IBSS_NSS(_x)    ((((_x) >> 8) & 0x3) ? (((_x) >> 8) & 0x3) : 1)
+#define CFG_TDLS_NSS(_x)    ((((_x) >> 10) & 0x3) ? (((_x) >> 10) & 0x3) : 1)
+#define CFG_P2P_DEV_NSS(_x) ((((_x) >> 12) & 0x3) ? (((_x) >> 12) & 0x3) : 1)
+#define CFG_OCB_NSS(_x)     ((((_x) >> 14) & 0x3) ? (((_x) >> 14) & 0x3) : 1)
+
+/**
+ * enum log_event_type - Type of event initiating bug report
+ * @WLAN_LOG_TYPE_NON_FATAL: Non fatal event
+ * @WLAN_LOG_TYPE_FATAL: Fatal event
+ *
+ * Enum indicating the type of event that is initiating the bug report
+ */
+enum log_event_type {
+	WLAN_LOG_TYPE_NON_FATAL,
+	WLAN_LOG_TYPE_FATAL,
+};
+
+/**
+ * enum log_event_indicator - Module triggering bug report
+ * @WLAN_LOG_INDICATOR_UNUSED: Unused
+ * @WLAN_LOG_INDICATOR_FRAMEWORK: Framework triggers bug report
+ * @WLAN_LOG_INDICATOR_HOST_DRIVER: Host driver triggers bug report
+ * @WLAN_LOG_INDICATOR_FIRMWARE: FW initiates bug report
+ * @WLAN_LOG_INDICATOR_HOST_ONLY: Host triggers fatal event bug report
+ *
+ * Enum indicating the module that triggered the bug report
+ */
+enum log_event_indicator {
+	WLAN_LOG_INDICATOR_UNUSED,
+	WLAN_LOG_INDICATOR_FRAMEWORK,
+	WLAN_LOG_INDICATOR_HOST_DRIVER,
+	WLAN_LOG_INDICATOR_FIRMWARE,
+	WLAN_LOG_INDICATOR_HOST_ONLY,
+};
+
+/**
+ * enum log_event_host_reason_code - Reason code for bug report
+ * @WLAN_LOG_REASON_CODE_UNUSED: Unused
+ * @WLAN_LOG_REASON_ROAM_FAIL: Driver initiated roam has failed
+ * @WLAN_LOG_REASON_DATA_STALL: Unable to send/receive data due to low resource
+ * scenario for a prolonged period
+ * @WLAN_LOG_REASON_SME_COMMAND_STUCK: SME command is stuck in SME active queue
+ * @WLAN_LOG_REASON_QUEUE_FULL: Defer queue becomes full for a prolonged period
+ * @WLAN_LOG_REASON_POWER_COLLAPSE_FAIL: Unable to allow apps power collapse
+ * for a prolonged period
+ * @WLAN_LOG_REASON_MALLOC_FAIL: Memory allocation Fails
+ * @WLAN_LOG_REASON_VOS_MSG_UNDER_RUN: VOS Core runs out of message wrapper
+ * @WLAN_LOG_REASON_HDD_TIME_OUT: Wait for event Timeout in HDD layer
+   @WLAN_LOG_REASON_SME_OUT_OF_CMD_BUFL sme out of cmd buffer
+ * @WLAN_LOG_REASON_NO_SCAN_RESULTS: no scan results to report from HDD
+ * This enum contains the different reason codes for bug report
+ * @WLAN_LOG_REASON_SCAN_NOT_ALLOWED: scan not allowed due to connection states
+ * @WLAN_LOG_REASON_HB_FAILURE: station triggered heart beat failure with AP
+ * @WLAN_LOG_REASON_ROAM_HO_FAILURE: Handover failed during LFR3 roaming
+ * @WLAN_LOG_REASON_DISCONNECT: Disconnect because of some failure
+ */
+enum log_event_host_reason_code {
+	WLAN_LOG_REASON_CODE_UNUSED,
+	WLAN_LOG_REASON_ROAM_FAIL,
+	WLAN_LOG_REASON_DATA_STALL,
+	WLAN_LOG_REASON_SME_COMMAND_STUCK,
+	WLAN_LOG_REASON_QUEUE_FULL,
+	WLAN_LOG_REASON_POWER_COLLAPSE_FAIL,
+	WLAN_LOG_REASON_MALLOC_FAIL,
+	WLAN_LOG_REASON_VOS_MSG_UNDER_RUN,
+	WLAN_LOG_REASON_HDD_TIME_OUT,
+	WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF,
+	WLAN_LOG_REASON_NO_SCAN_RESULTS,
+	WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
+	WLAN_LOG_REASON_HB_FAILURE,
+	WLAN_LOG_REASON_ROAM_HO_FAILURE,
+	WLAN_LOG_REASON_DISCONNECT
+};
+
+
+/**
+ * enum userspace_log_level - Log level at userspace
+ * @LOG_LEVEL_NO_COLLECTION: verbose_level 0 corresponds to no collection
+ * @LOG_LEVEL_NORMAL_COLLECT: verbose_level 1 correspond to normal log level,
+ * with minimal user impact. this is the default value
+ * @LOG_LEVEL_ISSUE_REPRO: verbose_level 2 are enabled when user is lazily
+ * trying to reproduce a problem, wifi performances and power can be impacted
+ * but device should not otherwise be significantly impacted
+ * @LOG_LEVEL_ACTIVE: verbose_level 3+ are used when trying to
+ * actively debug a problem
+ *
+ * Various log levels defined in the userspace for logging applications
+ */
+enum userspace_log_level {
+	LOG_LEVEL_NO_COLLECTION,
+	LOG_LEVEL_NORMAL_COLLECT,
+	LOG_LEVEL_ISSUE_REPRO,
+	LOG_LEVEL_ACTIVE,
+};
+
+/**
+ * enum wifi_driver_log_level - Log level defined in the driver for logging
+ * @WLAN_LOG_LEVEL_OFF: No logging
+ * @WLAN_LOG_LEVEL_NORMAL: Default logging
+ * @WLAN_LOG_LEVEL_REPRO: Normal debug level
+ * @WLAN_LOG_LEVEL_ACTIVE: Active debug level
+ *
+ * Log levels defined for logging by the wifi driver
+ */
+enum wifi_driver_log_level {
+	WLAN_LOG_LEVEL_OFF,
+	WLAN_LOG_LEVEL_NORMAL,
+	WLAN_LOG_LEVEL_REPRO,
+	WLAN_LOG_LEVEL_ACTIVE,
+};
+
+/**
+ * enum wifi_logging_ring_id - Ring id of logging entities
+ * @RING_ID_WAKELOCK:         Power events ring id
+ * @RING_ID_CONNECTIVITY:     Connectivity event ring id
+ * @RING_ID_PER_PACKET_STATS: Per packet statistic ring id
+ * @RING_ID_DRIVER_DEBUG:     Driver debug messages ring id
+ * @RING_ID_FIRMWARE_DEBUG:   Firmware debug messages ring id
+ *
+ * This enum has the ring id values of logging rings
+ */
+enum wifi_logging_ring_id {
+	RING_ID_WAKELOCK,
+	RING_ID_CONNECTIVITY,
+	RING_ID_PER_PACKET_STATS,
+	RING_ID_DRIVER_DEBUG,
+	RING_ID_FIRMWARE_DEBUG,
+};
+
+/* ------------------------------------------------------------------- */
+/* Change channel generic scheme */
+typedef void (*CHANGE_CHANNEL_CALLBACK)(tpAniSirGlobal pMac, QDF_STATUS status,
+					uint32_t *data,
+					tpPESession psessionEntry);
+
+/* / LIM global definitions */
+typedef struct sAniSirLimIbss {
+	void *pHdr;
+	void *pBeacon;
+} tAniSirLimIbss;
+
+typedef struct sDialogueToken {
+	/* bytes 0-3 */
+	uint16_t assocId;
+	uint8_t token;
+	uint8_t rsvd1;
+	/* Bytes 4-7 */
+	uint16_t tid;
+	uint8_t rsvd2[2];
+
+	struct sDialogueToken *next;
+} tDialogueToken, *tpDialogueToken;
+
+typedef struct sLimTimers {
+	/* TIMERS IN LIM ARE NOT SUPPOSED TO BE ZEROED OUT DURING RESET. */
+	/* DURING lim_initialize DONOT ZERO THEM OUT. */
+
+/* STA SPECIFIC TIMERS */
+
+	TX_TIMER gLimPreAuthClnupTimer;
+
+	/* Association related timers */
+	TX_TIMER gLimAssocFailureTimer;
+	TX_TIMER gLimReassocFailureTimer;
+
+	/* / Wait for Probe after Heartbeat failure timer on STA */
+	TX_TIMER gLimProbeAfterHBTimer;
+
+	/* Authentication related timers */
+	TX_TIMER gLimAuthFailureTimer;
+
+	/* Join Failure timeout on STA */
+	TX_TIMER gLimJoinFailureTimer;
+
+	/* CNF_WAIT timer */
+	TX_TIMER *gpLimCnfWaitTimer;
+
+	TX_TIMER gLimAddtsRspTimer;     /* max wait for a response */
+
+	/* Update OLBC Cache Timer */
+	TX_TIMER gLimUpdateOlbcCacheTimer;
+
+	TX_TIMER gLimChannelSwitchTimer;
+	/* This TIMER is started on the STA, as indicated by the */
+	/* AP in its Quiet BSS IE, for the specified interval */
+	TX_TIMER gLimQuietTimer;
+	/* This TIMER is started on the AP, prior to the AP going */
+	/* into LEARN mode */
+	/* This TIMER is started on the STA, for the specified */
+	/* quiet duration */
+	TX_TIMER gLimQuietBssTimer;
+
+	TX_TIMER gLimFTPreAuthRspTimer;
+
+#ifdef FEATURE_WLAN_ESE
+	TX_TIMER gLimEseTsmTimer;
+#endif
+	TX_TIMER gLimPeriodicJoinProbeReqTimer;
+	TX_TIMER gLimDisassocAckTimer;
+	TX_TIMER gLimDeauthAckTimer;
+	/* This timer is used to convert active channel to
+	 * passive channel when there is no beacon
+	 * for a period of time on a particular DFS channel
+	 */
+	TX_TIMER gLimActiveToPassiveChannelTimer;
+	TX_TIMER g_lim_periodic_auth_retry_timer;
+
+	/* SAE authentication related timer */
+	TX_TIMER sae_auth_timer;
+
+/* ********************TIMER SECTION ENDS************************************************** */
+/* ALL THE FIELDS BELOW THIS CAN BE ZEROED OUT in lim_initialize */
+/* **************************************************************************************** */
+
+} tLimTimers;
+
+typedef struct {
+	void *pMlmDisassocReq;
+	void *pMlmDeauthReq;
+} tLimDisassocDeauthCnfReq;
+
+typedef struct sAniSirLim {
+	/* ////////////////////////////////////     TIMER RELATED START /////////////////////////////////////////// */
+
+	tLimTimers limTimers;
+	/* / Flag to track if LIM timers are created or not */
+	uint32_t gLimTimersCreated;
+
+	/* ////////////////////////////////////     TIMER RELATED END /////////////////////////////////////////// */
+
+	struct lim_scan_channel_status scan_channel_status;
+
+	uint8_t gLimCurrentBssUapsd;
+
+	/* */
+	/* Store the BSS Index returned by HAL during */
+	/* WMA_ADD_BSS_RSP here. */
+	/* */
+
+	/* For now: */
+	/* This will be used during WMA_SET_BSSKEY_REQ in */
+	/* order to set the GTK */
+	/* Later: */
+	/* There could be other interfaces needing this info */
+	/* */
+
+	/* */
+	/* Due to the asynchronous nature of the interface */
+	/* between PE <-> HAL, some transient information */
+	/* like this needs to be cached. */
+	/* This is cached upon receipt of eWNI_SME_SETCONTEXT_REQ. */
+	/* This is released while posting LIM_MLM_SETKEYS_CNF */
+	/* */
+	void *gpLimMlmSetKeysReq;
+
+	/* ////////////////////////////////////////     BSS RELATED END /////////////////////////////////////////// */
+
+	/* ////////////////////////////////////////     IBSS RELATED START /////////////////////////////////////////// */
+	/* This indicates whether this STA coalesced and adapter to peer's capabilities or not. */
+	uint8_t gLimIbssCoalescingHappened;
+
+	/* / Definition for storing IBSS peers BSS description */
+	tLimIbssPeerNode *gLimIbssPeerList;
+	uint32_t gLimNumIbssPeers;
+	uint32_t ibss_retry_cnt;
+
+	/* ibss info - params for which ibss to join while coalescing */
+	tAniSirLimIbss ibssInfo;
+
+	/* ////////////////////////////////////////     IBSS RELATED END /////////////////////////////////////////// */
+
+	/* ////////////////////////////////////////     STATS/COUNTER RELATED START /////////////////////////////////////////// */
+
+	uint16_t maxStation;
+	uint16_t maxBssId;
+
+	uint32_t gLimNumBeaconsRcvd;
+	uint32_t gLimNumBeaconsIgnored;
+
+	uint32_t gLimNumDeferredMsgs;
+
+	/* / Variable to keep track of number of currently associated STAs */
+	uint16_t gLimNumOfAniSTAs;      /* count of ANI peers */
+
+	/* Heart-Beat interval value */
+	uint32_t gLimHeartBeatCount;
+	tSirMacAddr gLimHeartBeatApMac[2];
+	uint8_t gLimHeartBeatApMacIndex;
+
+	/* Statistics to keep track of no. beacons rcvd in heart beat interval */
+	uint16_t
+		gLimHeartBeatBeaconStats[MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL];
+
+#ifdef WLAN_DEBUG
+	/* Debug counters */
+	uint32_t numTot, numBbt, numProtErr, numLearn, numLearnIgnore;
+	uint32_t numSme, numMAC[4][16];
+
+	/* Debug counter to track number of Assoc Req frame drops */
+	/* when received in pStaDs->mlmState other than LINK_ESTABLISED */
+	uint32_t gLimNumAssocReqDropInvldState;
+	/* counters to track rejection of Assoc Req due to Admission Control */
+	uint32_t gLimNumAssocReqDropACRejectTS;
+	uint32_t gLimNumAssocReqDropACRejectSta;
+	/* Debug counter to track number of Reassoc Req frame drops */
+	/* when received in pStaDs->mlmState other than LINK_ESTABLISED */
+	uint32_t gLimNumReassocReqDropInvldState;
+	/* Debug counter to track number of Hash Miss event that */
+	/* will not cause a sending of de-auth/de-associate frame */
+	uint32_t gLimNumHashMissIgnored;
+
+	/* Debug counter to track number of Beacon frames */
+	/* received in unexpected state */
+	uint32_t gLimUnexpBcnCnt;
+
+	/* Debug counter to track number of Beacon frames */
+	/* received in wt-join-state that do have SSID mismatch */
+	uint32_t gLimBcnSSIDMismatchCnt;
+
+	/* Debug counter to track number of Link establishments on STA/BP */
+	uint32_t gLimNumLinkEsts;
+
+	/* Debug counter to track number of Rx cleanup */
+	uint32_t gLimNumRxCleanup;
+
+	/* Debug counter to track different parse problem */
+	uint32_t gLim11bStaAssocRejectCount;
+
+#endif
+
+	/* ////////////////////////////////////////     STATS/COUNTER RELATED END /////////////////////////////////////////// */
+
+	/* ////////////////////////////////////////     STATES RELATED START /////////////////////////////////////////// */
+	/* Counts Heartbeat failures */
+	uint8_t gLimHBfailureCntInLinkEstState;
+	uint8_t gLimProbeFailureAfterHBfailedCnt;
+	uint8_t gLimHBfailureCntInOtherStates;
+
+	/**
+	 * This variable indicates whether LIM module need to
+	 * send response to host. Used to identify whether a request
+	 * is generated internally within LIM module or by host
+	 */
+	uint8_t gLimRspReqd;
+
+	/* / Previous SME State */
+	tLimSmeStates gLimPrevSmeState;
+
+	/* / MLM State visible across all Sirius modules */
+	tLimMlmStates gLimMlmState;
+
+	/* / Previous MLM State */
+	tLimMlmStates gLimPrevMlmState;
+
+	/* Can be set to invalid channel. If it is invalid, HAL */
+	/* should move to previous valid channel or stay in the */
+	/* current channel. CB state goes along with channel to resume to */
+	uint16_t gResumeChannel;
+	ePhyChanBondState gResumePhyCbState;
+
+	/* Change channel generic scheme */
+	CHANGE_CHANNEL_CALLBACK gpchangeChannelCallback;
+	uint32_t *gpchangeChannelData;
+
+	/* / SME State visible across all Sirius modules */
+	tLimSmeStates gLimSmeState;
+	/* / This indicates whether we're an AP, STA in BSS/IBSS */
+	tLimSystemRole gLimSystemRole;
+
+	/* Number of STAs that do not support short preamble */
+	tLimNoShortParams gLimNoShortParams;
+
+	/* Number of STAs that do not support short slot time */
+	tLimNoShortSlotParams gLimNoShortSlotParams;
+
+	/* */
+	/* ---------------- DPH ----------------------- */
+	/* these used to live in DPH but are now moved here (where they belong) */
+	uint32_t gLimPhyMode;
+
+	uint8_t gLimQosEnabled:1;       /* 11E */
+	uint8_t gLimWmeEnabled:1;       /* WME */
+	uint8_t gLimWsmEnabled:1;       /* WSM */
+	uint8_t gLimHcfEnabled:1;
+	uint8_t gLim11dEnabled:1;
+	uint8_t gLimProbeRespDisableFlag:1;    /* control over probe response */
+	/* ---------------- DPH ----------------------- */
+
+	/* ////////////////////////////////////////     STATES RELATED END /////////////////////////////////////////// */
+
+	/* ////////////////////////////////////////     MISC RELATED START /////////////////////////////////////////// */
+
+	/* Deferred Queue Parameters */
+	tLimDeferredMsgQParams gLimDeferredMsgQ;
+
+	/* addts request if any - only one can be outstanding at any time */
+	tSirAddtsReq gLimAddtsReq;
+	uint8_t gLimAddtsSent;
+	uint8_t gLimAddtsRspTimerCount;
+
+	/* protection related config cache */
+	tCfgProtection cfgProtection;
+
+	uint8_t gLimProtectionControl;
+	/* This flag will remain to be set except while LIM is waiting for specific response messages */
+	/* from HAL. e.g when LIM issues ADD_STA req it will clear this flag and when it will receive */
+	/* the response the flag will be set. */
+	uint8_t gLimProcessDefdMsgs;
+
+	/* UAPSD flag used on AP */
+	uint8_t gUapsdEnable;
+
+	/* Used on STA for AC downgrade. This is a dynamic mask
+	 * setting which keep tracks of ACs being admitted.
+	 * If bit is set to 0: That partiular AC is not admitted
+	 * If bit is set to 1: That particular AC is admitted
+	 */
+	uint8_t gAcAdmitMask[SIR_MAC_DIRECTION_DIRECT];
+
+	/* dialogue token List head/tail for Action frames request sent. */
+	tpDialogueToken pDialogueTokenHead;
+	tpDialogueToken pDialogueTokenTail;
+
+	tLimTspecInfo tspecInfo[LIM_NUM_TSPEC_MAX];
+
+	/* admission control policy information */
+	tLimAdmitPolicyInfo admitPolicyInfo;
+	qdf_mutex_t lkPeGlobalLock;
+	uint8_t disableLDPCWithTxbfAP;
+#ifdef FEATURE_WLAN_TDLS
+	uint8_t gLimTDLSBufStaEnabled;
+	uint8_t gLimTDLSUapsdMask;
+	uint8_t gLimTDLSOffChannelEnabled;
+	uint8_t gLimTDLSWmmMode;
+#endif
+	/* ////////////////////////////////////////     MISC RELATED END /////////////////////////////////////////// */
+
+	/* ////////////////////////////////////////     ASSOC RELATED START /////////////////////////////////////////// */
+	/* Place holder for JoinReq message */
+	/* received by SME state machine */
+	/* tpSirSmeJoinReq       gpLimJoinReq; */
+
+	/* Place holder for ReassocReq message */
+	/* received by SME state machine */
+	/* tpSirSmeReassocReq    gpLimReassocReq;  sep23 review */
+
+	/* Current Authentication type used at STA */
+	/* tAniAuthType        gLimCurrentAuthType; */
+
+	/* Place holder for current authentication request */
+	/* being handled */
+	tLimMlmAuthReq *gpLimMlmAuthReq;
+
+	/* Reason code to determine the channel change context while sending */
+	/* WMA_CHNL_SWITCH_REQ message to HAL */
+	uint32_t channelChangeReasonCode;
+
+	/* / MAC level Pre-authentication related globals */
+	tSirMacChanNum gLimPreAuthChannelNumber;
+	tAniAuthType gLimPreAuthType;
+	tSirMacAddr gLimPreAuthPeerAddr;
+	uint32_t gLimNumPreAuthContexts;
+	tLimPreAuthTable gLimPreAuthTimerTable;
+
+	/* Placed holder to deauth reason */
+	uint16_t gLimDeauthReasonCode;
+
+	/* Place holder for Pre-authentication node list */
+	struct tLimPreAuthNode *pLimPreAuthList;
+
+	/* Assoc or ReAssoc Response Data/Frame */
+	void *gLimAssocResponseData;
+
+	/* One cache for each overlap and associated case. */
+	tCacheParams protStaOverlapCache[LIM_PROT_STA_OVERLAP_CACHE_SIZE];
+	tCacheParams protStaCache[LIM_PROT_STA_CACHE_SIZE];
+
+	/* ////////////////////////////////////////     ASSOC RELATED END /////////////////////////////////////////// */
+
+	/* //////////////////////////////  HT RELATED           ////////////////////////////////////////// */
+	/* */
+	/* The following global LIM variables maintain/manage */
+	/* the runtime configurations related to 802.11n */
+
+	/* 802.11n Station detected HT capability in Beacon Frame */
+	uint8_t htCapabilityPresentInBeacon;
+
+	/* 802.11 HT capability: Enabled or Disabled */
+	uint8_t htCapability;
+
+	uint8_t gHTGreenfield;
+
+	uint8_t gHTShortGI40Mhz;
+	uint8_t gHTShortGI20Mhz;
+
+	/* Set to 0 for 3839 octets */
+	/* Set to 1 for 7935 octets */
+	uint8_t gHTMaxAmsduLength;
+
+	/* DSSS/CCK at 40 MHz: Enabled 1 or Disabled */
+	uint8_t gHTDsssCckRate40MHzSupport;
+
+	/* PSMP Support: Enabled 1 or Disabled 0 */
+	uint8_t gHTPSMPSupport;
+
+	/* L-SIG TXOP Protection used only if peer support available */
+	uint8_t gHTLsigTXOPProtection;
+
+	/* MIMO Power Save */
+	tSirMacHTMIMOPowerSaveState gHTMIMOPSState;
+
+	/* */
+	/* A-MPDU Density */
+	/* 000 - No restriction */
+	/* 001 - 1/8 usec */
+	/* 010 - 1/4 usec */
+	/* 011 - 1/2 usec */
+	/* 100 - 1 usec */
+	/* 101 - 2 usec */
+	/* 110 - 4 usec */
+	/* 111 - 8 usec */
+	/* */
+	uint8_t gHTAMpduDensity;
+
+	bool gMaxAmsduSizeEnabled;
+	/* Maximum Tx/Rx A-MPDU factor */
+	uint8_t gHTMaxRxAMpduFactor;
+
+	/* */
+	/* Scheduled PSMP related - Service Interval Granularity */
+	/* 000 - 5 ms */
+	/* 001 - 10 ms */
+	/* 010 - 15 ms */
+	/* 011 - 20 ms */
+	/* 100 - 25 ms */
+	/* 101 - 30 ms */
+	/* 110 - 35 ms */
+	/* 111 - 40 ms */
+	/* */
+	uint8_t gHTServiceIntervalGranularity;
+
+	/* Indicates whether an AP wants to associate PSMP enabled Stations */
+	uint8_t gHTControlledAccessOnly;
+
+	/* RIFS Mode. Set if no APSD legacy devices associated */
+	uint8_t gHTRifsMode;
+	/* OBss Mode . set when we have Non HT STA is associated or with in overlap bss */
+	uint8_t gHTObssMode;
+
+	/* Identifies the current Operating Mode */
+	tSirMacHTOperatingMode gHTOperMode;
+
+	/* Indicates if PCO is activated in the BSS */
+	uint8_t gHTPCOActive;
+
+	/* */
+	/* If PCO is active, indicates which PCO phase to use */
+	/* 0 - switch to 20 MHz phase */
+	/* 1 - switch to 40 MHz phase */
+	/* */
+	uint8_t gHTPCOPhase;
+
+	/* */
+	/* Used only in beacons. For PR, this is set to 0 */
+	/* 0 - Primary beacon */
+	/* 1 - Secondary beacon */
+	/* */
+	uint8_t gHTSecondaryBeacon;
+
+	/* */
+	/* Dual CTS Protection */
+	/* 0 - Use RTS/CTS */
+	/* 1 - Dual CTS Protection is used */
+	/* */
+	uint8_t gHTDualCTSProtection;
+
+	/* */
+	/* Identifies a single STBC MCS that shall ne used for */
+	/* STBC control frames and STBC beacons */
+	/* */
+	uint8_t gHTSTBCBasicMCS;
+
+	uint8_t gHTNonGFDevicesPresent;
+
+	/* //////////////////////////////  HT RELATED           ////////////////////////////////////////// */
+
+#ifdef FEATURE_WLAN_TDLS
+	uint8_t gLimTdlsLinkMode;
+	/* //////////////////////////////  TDLS RELATED         ////////////////////////////////////////// */
+#endif
+
+	/* wsc info required to form the wsc IE */
+	tLimWscIeInfo wscIeInfo;
+	tpPESession gpSession;  /* Pointer to  session table */
+	/*
+	 * sessionID and transactionID from SME is stored here for those messages, for which
+	 * there is no session context in PE, e.g. Scan related messages.
+	 **/
+	uint8_t gSmeSessionId;
+
+	tSirRemainOnChnReq *gpLimRemainOnChanReq;       /* hold remain on chan request in this buf */
+	qdf_mutex_t lim_frame_register_lock;
+	qdf_list_t gLimMgmtFrameRegistratinQueue;
+	uint32_t mgmtFrameSessionId;
+	uint32_t tdls_frm_session_id;
+
+	tpPESession pSessionEntry;
+	uint8_t reAssocRetryAttempt;
+	tLimDisassocDeauthCnfReq limDisassocDeauthCnfReq;
+	uint8_t deferredMsgCnt;
+	tSirDFSChannelList dfschannelList;
+	uint8_t deauthMsgCnt;
+	uint8_t disassocMsgCnt;
+	uint8_t gLimIbssStaLimit;
+
+	/* Number of channel switch IEs sent so far */
+	uint8_t gLimDfsChanSwTxCount;
+	uint8_t gLimDfsTargetChanNum;
+	QDF_STATUS(*sme_msg_callback)
+		(tpAniSirGlobal mac, struct scheduler_msg *msg);
+	QDF_STATUS(*stop_roaming_callback)
+		(tpAniSirGlobal mac, uint8_t session_id, uint8_t reason);
+	uint8_t retry_packet_cnt;
+	uint8_t beacon_probe_rsp_cnt_per_scan;
+	wlan_scan_requester req_id;
+	bool global_obss_offload_enabled;
+	bool global_obss_color_collision_det_offload;
+} tAniSirLim, *tpAniSirLim;
+
+struct mgmt_frm_reg_info {
+	qdf_list_node_t node;   /* MUST be first element */
+	uint16_t frameType;
+	uint16_t matchLen;
+	uint16_t sessionId;
+	uint8_t matchData[1];
+};
+
+typedef struct sRrmContext {
+	tRrmSMEContext rrmSmeContext;
+	tRrmPEContext rrmPEContext;
+} tRrmContext, *tpRrmContext;
+
+/**
+ * enum auth_tx_ack_status - Indicate TX status of AUTH
+ * @LIM_AUTH_ACK_NOT_RCD : Default status while waiting for ack status.
+ * @LIM_AUTH_ACK_RCD_SUCCESS : Ack is received.
+ * @LIM_AUTH_ACK_RCD_FAILURE : No Ack received.
+ *
+ * Indicate if driver is waiting for ACK status of auth or ACK received for AUTH
+ * OR NO ACK is received for the auth sent.
+ */
+enum auth_tx_ack_status {
+	LIM_AUTH_ACK_NOT_RCD,
+	LIM_AUTH_ACK_RCD_SUCCESS,
+	LIM_AUTH_ACK_RCD_FAILURE,
+};
+/**
+ * struct vdev_type_nss - vdev type nss structure
+ * @sta: STA Nss value.
+ * @sap: SAP Nss value.
+ * @p2p_go: P2P GO Nss value.
+ * @p2p_cli: P2P CLI Nss value.
+ * @p2p_dev: P2P device Nss value.
+ * @ibss: IBSS Nss value.
+ * @tdls: TDLS Nss value.
+ * @ocb: OCB Nss value.
+ *
+ * Holds the Nss values of different vdev types.
+ */
+struct vdev_type_nss {
+	uint8_t sta;
+	uint8_t sap;
+	uint8_t p2p_go;
+	uint8_t p2p_cli;
+	uint8_t p2p_dev;
+	uint8_t ibss;
+	uint8_t tdls;
+	uint8_t ocb;
+};
+
+/**
+ * struct mgmt_beacon_probe_filter
+ * @bcn_filter_lock: Spinlock for the filter structure
+ * @num_sta_sessions: Number of active PE STA sessions
+ * @sta_bssid: Array of PE STA session's peer BSSIDs
+ * @num_ibss_sessions: Number of active PE IBSS sessions
+ * @ibss_ssid: Array of PE IBSS session's SSID
+ * @num_sap_session: Number of active PE SAP sessions
+ * @sap_channel: Array of PE SAP session's channels
+ *
+ * Used to filter the STA/IBSS/SAP beacons/probes required in PE and
+ * drop other unwanted beacon/probe response frames
+ */
+struct mgmt_beacon_probe_filter {
+	uint8_t num_sta_sessions;
+	tSirMacAddr sta_bssid[SIR_MAX_SUPPORTED_BSS];
+	uint8_t num_ibss_sessions;
+	tSirMacSSid ibss_ssid[SIR_MAX_SUPPORTED_BSS];
+	uint8_t num_sap_sessions;
+	uint8_t sap_channel[SIR_MAX_SUPPORTED_BSS];
+};
+
+/**
+ * struct mac_context - Global MAC context
+ */
+struct mac_context {
+	enum qdf_driver_type gDriverType;
+
+	tAniSirCfg cfg;
+	struct wlan_mlme_cfg *mlme_cfg;
+	tAniSirLim lim;
+	tAniSirSch sch;
+	tAniSirSys sys;
+
+	/* PAL/HDD handle */
+	hdd_handle_t hdd_handle;
+
+	tSmeStruct sme;
+	tSapStruct sap;
+	struct csr_scanstruct scan;
+	struct csr_roamstruct roam;
+	tRrmContext rrm;
+	csr_readyToSuspendCallback readyToSuspendCallback;
+	void *readyToSuspendContext;
+	uint8_t isCoalesingInIBSSAllowed;
+	uint8_t lteCoexAntShare;
+	uint8_t beacon_offload;
+	bool pmf_offload;
+	bool is_fils_roaming_supported;
+	uint8_t f_prefer_non_dfs_on_radar;
+	uint32_t f_sta_miracast_mcc_rest_time_val;
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+	csr_readyToExtWoWCallback readyToExtWoWCallback;
+	void *readyToExtWoWContext;
+#endif
+	struct vdev_type_nss vdev_type_nss_2g;
+	struct vdev_type_nss vdev_type_nss_5g;
+
+	uint16_t mgmtSeqNum;
+	/* DBS capability based on INI and FW capability */
+	uint8_t hw_dbs_capable;
+	uint32_t sta_sap_scc_on_dfs_chan;
+	sir_mgmt_frame_ind_callback mgmt_frame_ind_cb;
+	qdf_atomic_t global_cmd_id;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	void (*chan_info_cb)(struct scan_chan_info *chan_info);
+	/* Based on INI parameter */
+	uint32_t dual_mac_feature_disable;
+
+	enum  country_src reg_hint_src;
+	uint32_t rx_packet_drop_counter;
+	enum auth_tx_ack_status auth_ack_status;
+	uint8_t user_configured_nss;
+	bool snr_monitor_enabled;
+	bool ignore_assoc_disallowed;
+	uint32_t peer_rssi;
+	uint32_t peer_txrate;
+	uint32_t peer_rxrate;
+	/* 11k Offload Support */
+	bool is_11k_offload_supported;
+	uint8_t reject_addba_req;
+	uint16_t usr_cfg_ba_buff_size;
+	bool is_usr_cfg_amsdu_enabled;
+	uint8_t no_ack_policy_cfg[MAX_NUM_AC];
+	uint32_t he_sgi_ltf_cfg_bit_mask;
+	uint8_t usr_cfg_tx_bfee_nsts;
+	struct mgmt_beacon_probe_filter bcn_filter;
+	tSirMacEdcaParamRecord usr_mu_edca_params[MAX_NUM_AC];
+	bool usr_cfg_mu_edca_params;
+	bool he_om_ctrl_cfg_bw_set;
+	uint8_t he_om_ctrl_cfg_bw;
+	bool he_om_ctrl_cfg_nss_set;
+	uint8_t he_om_ctrl_cfg_nss;
+#ifdef WLAN_FEATURE_11AX
+	tDot11fIEhe_cap he_cap_2g;
+	tDot11fIEhe_cap he_cap_5g;
+#endif
+	bool obss_scan_offload;
+};
+
+#ifdef FEATURE_WLAN_TDLS
+
+#define RFC1042_HDR_LENGTH      (6)
+#define GET_BE16(x)             ((uint16_t) (((x)[0] << 8) | (x)[1]))
+#define ETH_TYPE_89_0d          (0x890d)
+#define ETH_TYPE_LEN            (2)
+#define PAYLOAD_TYPE_TDLS_SIZE  (1)
+#define PAYLOAD_TYPE_TDLS       (2)
+
+#endif
+
+#endif /* _ANIGLOBAL_H */
diff --git a/core/mac/inc/ani_system_defs.h b/core/mac/inc/ani_system_defs.h
new file mode 100644
index 0000000..7efebd2
--- /dev/null
+++ b/core/mac/inc/ani_system_defs.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file ani_system_defs.h contains definitions used by
+ * various ANI entities
+ * Author:    Chandra Modumudi
+ * Date:      09/18/2002
+ * History:-
+ * Date       Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#ifndef __ANI_SYSTEM_DEFS_H
+#define __ANI_SYSTEM_DEFS_H
+
+#include "sir_types.h"
+#include "sir_mac_prot_def.h"
+
+#define ANI_OUI  0x000AF5
+
+/* / Max WDS info length. */
+#define ANI_WDS_INFO_MAX_LENGTH        64
+
+/* This is to force compiler to use the maximum of an int for enum */
+#define SIR_MAX_ENUM_SIZE    0x7FFFFFFF
+
+/* Max key size  including the WAPI and TKIP */
+#define WLAN_MAX_KEY_RSC_LEN         16
+#define WLAN_WAPI_KEY_RSC_LEN        16
+
+#ifndef false
+#undef false
+#define false   0
+#endif
+#ifndef true
+#undef true
+#define true    1
+#endif
+
+/* / Authentication type enum used with peer */
+typedef enum eAniAuthType {
+	eSIR_OPEN_SYSTEM,
+	eSIR_SHARED_KEY,
+	eSIR_FT_AUTH,
+	eSIR_AUTH_TYPE_SAE = 3,
+#if defined FEATURE_WLAN_ESE
+	eSIR_LEAP_AUTH = 0x80,
+#endif
+	SIR_FILS_SK_WITHOUT_PFS = 4,
+	SIR_FILS_SK_WITH_PFS = 5,
+	SIR_FILS_PK_AUTH = 6,
+	eSIR_AUTH_TYPE_OWE,
+	eSIR_AUTO_SWITCH,
+	eSIR_DONOT_USE_AUTH_TYPE = SIR_MAX_ENUM_SIZE
+} tAniAuthType;
+
+/* / Encryption type enum used with peer */
+typedef enum eAniEdType {
+	eSIR_ED_NONE,
+	eSIR_ED_WEP40,
+	eSIR_ED_WEP104,
+	eSIR_ED_TKIP,
+	eSIR_ED_CCMP,
+#if defined(FEATURE_WLAN_WAPI)
+	eSIR_ED_WPI,
+#endif
+	/*DPU HW treats encryption mode 4 plus RMF bit set in TX BD as BIP.
+	   Thus while setting BIP encryption mode in corresponding DPU Desc
+	   eSIR_ED_AES_128_CMAC should be set to eSIR_ED_CCMP */
+	eSIR_ED_AES_128_CMAC,
+	/* Firmware uses key length to find GCMP 128 or 256 */
+	eSIR_ED_GCMP,
+	eSIR_ED_GCMP_256,
+	eSIR_ED_AES_GMAC_128,
+	eSIR_ED_AES_GMAC_256,
+	eSIR_ED_NOT_IMPLEMENTED = SIR_MAX_ENUM_SIZE
+} tAniEdType;
+
+typedef enum eAniWepType {
+	eSIR_WEP_STATIC,
+	eSIR_WEP_DYNAMIC,
+} tAniWepType;
+
+/* / Enum to specify whether key is used */
+/* / for TX only, RX only or both */
+typedef enum eAniKeyDirection {
+	eSIR_TX_ONLY,
+	eSIR_RX_ONLY,
+	eSIR_TX_RX,
+	eSIR_TX_DEFAULT,
+	eSIR_DONOT_USE_KEY_DIRECTION = SIR_MAX_ENUM_SIZE
+} tAniKeyDirection;
+
+typedef struct sAniSSID {
+	uint8_t length;
+	uint8_t ssId[SIR_MAC_MAX_SSID_LENGTH];
+} tAniSSID, *tpAniSSID;
+
+typedef struct sAniApName {
+	uint8_t length;
+	uint8_t name[SIR_MAC_MAX_SSID_LENGTH];
+} tAniApName, *tpAniApName;
+
+/* / RSN IE information */
+typedef struct sSirRSNie {
+	uint16_t length;
+	uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH + 2];
+} tSirRSNie, *tpSirRSNie;
+
+typedef struct sSirWAPIie {
+	uint16_t length;
+	uint8_t wapiIEdata[SIR_MAC_MAX_IE_LENGTH + 2];
+} tSirWAPIie, *tpSirWAPIie;
+/* / Additional IE information : */
+/* / This can include WSC IE, P2P IE, and/or FTIE from upper layer. */
+/* / MAC layer transparently convey these IE info between peer STA and upper layer, */
+/* / but never requires to parse it. */
+typedef struct sSirAddie {
+	uint16_t length;
+	uint8_t addIEdata[SIR_MAC_MAX_ADD_IE_LENGTH + 2];
+} tSirAddie, *tpSirAddie;
+
+#ifdef FEATURE_WLAN_ESE
+
+/* The CCKM IE needs to be in the */
+/* Join and Reassoc Req. */
+typedef struct sSirCCKMie {
+	uint16_t length;
+	uint8_t cckmIEdata[SIR_MAC_MAX_IE_LENGTH + 2];
+} tSirCCKMie, *tpSirCCKMie;
+
+#endif
+
+/* / Definition for Encryption Keys */
+typedef struct sSirKeys {
+	uint8_t keyId;
+	uint8_t unicast;        /* 0 for multicast */
+	tAniKeyDirection keyDirection;
+	uint8_t keyRsc[WLAN_MAX_KEY_RSC_LEN];   /* Usage is unknown */
+	uint8_t paeRole;        /* =1 for authenticator, */
+	/* =0 for supplicant */
+	uint16_t keyLength;
+	uint8_t key[SIR_MAC_MAX_KEY_LENGTH];
+} tSirKeys, *tpSirKeys;
+
+/* / Definition for Keying material */
+typedef struct sSirKeyMaterial {
+	uint16_t length;        /* This is the length of all */
+	/* data that follows */
+	tAniEdType edType;      /* Encryption/Decryption type */
+	uint8_t numKeys;
+	tSirKeys key[1];
+} tSirKeyMaterial, *tpSirKeyMaterial;
+
+#define SIR_CIPHER_SEQ_CTR_SIZE 6
+/* / Definition for MIC failure indication */
+typedef struct sSirMicFailureInfo {
+	tSirMacAddr srcMacAddr; /* address used to compute MIC */
+	tSirMacAddr taMacAddr;  /* transmitter address */
+	tSirMacAddr dstMacAddr;
+	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 */
+	tSirMacAddr rxMacAddr;  /* receive address */
+
+} tSirMicFailureInfo, *tpSirMicFailureInfo;
+
+typedef struct sTrafStrmMetrics {
+	uint16_t UplinkPktQueueDly;
+	uint16_t UplinkPktQueueDlyHist[4];
+	uint32_t UplinkPktTxDly;
+	uint16_t UplinkPktLoss;
+	uint16_t UplinkPktCount;
+	uint8_t RoamingCount;
+	uint16_t RoamingDly;
+} qdf_packed tTrafStrmMetrics, *tpTrafStrmMetrics;
+
+typedef struct sBcnReportFields {
+	uint8_t ChanNum;
+	uint8_t Spare;
+	uint16_t MeasDuration;
+	uint8_t PhyType;
+	uint8_t RecvSigPower;
+	tSirMacAddr Bssid;
+	uint32_t ParentTsf;
+	uint32_t TargetTsf[2];
+	uint16_t BcnInterval;
+	uint16_t CapabilityInfo;
+} qdf_packed tBcnReportFields, *tpBcnReportFields;
+
+#endif /* __ANI_SYSTEM_DEFS_H */
diff --git a/core/mac/inc/mac_init_api.h b/core/mac/inc/mac_init_api.h
new file mode 100644
index 0000000..e4f5f7f
--- /dev/null
+++ b/core/mac/inc/mac_init_api.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * mac_init_api.c - Header file for mac level init functions
+ * Author:    Dinesh Upadhyay
+ * Date:      04/23/2007
+ * History:-
+ * Date       Modified by            Modification Information
+ * --------------------------------------------------------------------------
+ *
+ */
+#ifndef __MAC_INIT_API_H
+#define __MAC_INIT_API_H
+
+#include "ani_global.h"
+#include "sir_types.h"
+
+/**
+ * struct mac_start_params - parameters needed when starting the MAC
+ * @driver_type: Operating mode of the driver
+ */
+struct mac_start_params {
+	enum qdf_driver_type driver_type;
+};
+
+/**
+ * mac_start() - Start all MAC modules
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: Parameters needed to start the MAC
+ *
+ * This function is called to start MAC. This function will start all
+ * the mac modules.
+ *
+ * Return: QDF_STATUS_SUCCESS if the MAC was successfully started. Any
+ *         other value means that there was an issue with starting the
+ *         MAC and the MAC should not be considered operational.
+ */
+QDF_STATUS mac_start(mac_handle_t mac_handle,
+		     struct mac_start_params *params);
+
+/**
+ * mac_stop() - Stop all MAC modules
+ * @mac_handle: Opaque handle to the MAC context
+ *
+ * This function is called to stop MAC. This function will stop all
+ * the mac modules.
+ *
+ * Return: QDF_STATUS_SUCCESS if the MAC was successfully stopped. Any
+ *         other value means that there was an issue with stopping the
+ *         MAC, but the caller should still consider the MAC to be
+ *         stopped.
+ */
+QDF_STATUS mac_stop(mac_handle_t mac_handle);
+
+/**
+ * mac_open() - Open the MAC
+ * @psoc: SOC global object
+ * @mac_handle: Pointer to where the MAC handle is to be stored
+ * @hdd_handle: Opaque handle to the HDD context
+ * @cds_cfg: Initial configuration
+ *
+ * This function will be called during init. This function is suppose
+ * to allocate all the memory with the global context will be
+ * allocated here.
+ *
+ * Return: QDF_STATUS_SUCCESS if the MAC was successfully opened and a
+ *         MAC handle was returned to the caller. Any other value
+ *         means the MAC was not opened.
+ */
+QDF_STATUS mac_open(struct wlan_objmgr_psoc *psoc, mac_handle_t *mac_handle,
+		    hdd_handle_t hdd_handle, struct cds_config_info *cds_cfg);
+
+/**
+ * mac_close() - close the MAC
+ * @mac_handle: Opaque handle to the MAC context returned by mac_open()
+ *
+ * This function will be called in shutdown sequence from HDD. All the
+ * allocated memory with global context will be freed here.
+ *
+ * Return: QDF_STATUS_SUCCESS if the MAC was successfully closed. Any
+ *         other value means that there was an issue with closing the
+ *         MAC, but the caller should still consider the MAC to be
+ *         closed.
+ */
+QDF_STATUS mac_close(mac_handle_t mac_handle);
+
+#endif /* __MAC_INIT_API_H */
diff --git a/core/mac/inc/mac_trace.h b/core/mac/inc/mac_trace.h
new file mode 100644
index 0000000..9398a3c
--- /dev/null
+++ b/core/mac/inc/mac_trace.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013-2016, 2018 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.
+ */
+
+/**=========================================================================
+
+ *  \file  mac_trace.h
+
+ *  \brief definition for trace related APIs
+
+   \author Sunit Bhatia
+
+   ========================================================================*/
+
+#ifndef __MAC_TRACE_H
+#define __MAC_TRACE_H
+
+#include "ani_global.h"
+
+#define MAC_TRACE_GET_MODULE_ID(data) ((data >> 8) & 0xff)
+#define MAC_TRACE_GET_MSG_ID(data)       (data & 0xffff)
+
+#ifdef TRACE_RECORD
+
+#define eLOG_NODROP_MISSED_BEACON_SCENARIO 0
+#define eLOG_PROC_DEAUTH_FRAME_SCENARIO 1
+
+void mac_trace(tpAniSirGlobal pMac, uint8_t code, uint16_t session,
+	       uint32_t data);
+void mac_trace_new(tpAniSirGlobal pMac, uint8_t module, uint8_t code,
+		   uint16_t session, uint32_t data);
+uint8_t *mac_trace_get_cfg_msg_string(uint16_t cfgMsg);
+uint8_t *mac_trace_get_lim_msg_string(uint16_t limMsg);
+uint8_t *mac_trace_get_sme_msg_string(uint16_t smeMsg);
+uint8_t *mac_trace_get_info_log_string(uint16_t infoLog);
+
+#endif
+uint8_t *mac_trace_get_wma_msg_string(uint16_t wmaMsg);
+QDF_STATUS pe_acquire_global_lock(tAniSirLim *psPe);
+QDF_STATUS pe_release_global_lock(tAniSirLim *psPe);
+uint8_t *mac_trace_get_neighbour_roam_state(uint16_t neighbourRoamState);
+uint8_t *mac_trace_getcsr_roam_state(uint16_t csr_roamState);
+uint8_t *mac_trace_getcsr_roam_sub_state(uint16_t csr_roamSubState);
+uint8_t *mac_trace_get_lim_sme_state(uint16_t limState);
+uint8_t *mac_trace_get_lim_mlm_state(uint16_t mlmState);
+
+#endif
diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h
new file mode 100644
index 0000000..5657d6a
--- /dev/null
+++ b/core/mac/inc/qwlan_version.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef QWLAN_VERSION_H
+#define QWLAN_VERSION_H
+/*===========================================================================
+
+   FILE:
+   qwlan_version.h
+
+   BRIEF DESCRIPTION:
+   WLAN Host Version file.
+   Build number automatically updated by build scripts.
+
+   ===========================================================================*/
+
+#define QWLAN_VERSION_MAJOR            5
+#define QWLAN_VERSION_MINOR            2
+#define QWLAN_VERSION_PATCH            0
+#define QWLAN_VERSION_EXTRA            "V"
+#define QWLAN_VERSION_BUILD            105
+
+#define QWLAN_VERSIONSTR               "5.2.0.105V"
+
+#endif /* QWLAN_VERSION_H */
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
new file mode 100644
index 0000000..aaf7727
--- /dev/null
+++ b/core/mac/inc/sir_api.h
@@ -0,0 +1,6975 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file sir_api.h contains definitions exported by
+ * Sirius software.
+ * Author:        Chandra Modumudi
+ * Date:          04/16/2002
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#ifndef __SIR_API_H
+#define __SIR_API_H
+
+/* legacy definition */
+typedef struct mac_context *tpAniSirGlobal;
+
+#include "qdf_types.h"
+#include "cds_regdomain.h"
+#include "sir_types.h"
+#include "sir_mac_prot_def.h"
+#include "ani_system_defs.h"
+#include "sir_params.h"
+#include "cds_regdomain.h"
+#include "wmi_unified.h"
+#include "wmi_unified_param.h"
+#include "ol_txrx_htt_api.h"
+#include "wlan_reg_services_api.h"
+#include <dot11f.h>
+#include "wlan_policy_mgr_api.h"
+
+#ifndef SIR_MAX_SUPPORTED_BSS
+#define SIR_MAX_SUPPORTED_BSS 5
+#endif
+
+#define OFFSET_OF(structType, fldName)   (&((structType *)0)->fldName)
+
+/* / Max supported channel list */
+#define SIR_MAX_SUPPORTED_CHANNEL_LIST      96
+
+#define SIR_MDIE_ELEMENT_ID         54
+#define SIR_MDIE_SIZE               3   /* MD ID(2 bytes), Capability(1 byte) */
+
+#define SIR_MAX_ELEMENT_ID         255
+
+/* Max number of channels are 165, but to access 165th element of array,
+   *array of 166 is required.
+ */
+#define SIR_MAX_24G_5G_CHANNEL_RANGE      166
+#define SIR_BCN_REPORT_MAX_BSS_DESC       4
+
+#define SIR_NUM_11B_RATES 4     /* 1,2,5.5,11 */
+#define SIR_NUM_11A_RATES 8     /* 6,9,12,18,24,36,48,54 */
+
+#define SIR_PM_SLEEP_MODE   0
+#define SIR_PM_ACTIVE_MODE        1
+
+/* hidden SSID options */
+#define SIR_SCAN_NO_HIDDEN_SSID                      0
+#define SIR_SCAN_HIDDEN_SSID_PE_DECISION             1
+
+#define SIR_IPV4_ADDR_LEN       4
+
+typedef uint8_t tSirIpv4Addr[SIR_IPV4_ADDR_LEN];
+
+#define SIR_VERSION_STRING_LEN 64
+typedef uint8_t tSirVersionString[SIR_VERSION_STRING_LEN];
+
+/* Periodic Tx pattern offload feature */
+#define PERIODIC_TX_PTRN_MAX_SIZE 1536
+#define MAXNUM_PERIODIC_TX_PTRNS 6
+#define WIFI_SCANNING_MAC_OUI_LENGTH 3
+
+/* This should not be greater than MAX_NUMBER_OF_CONC_CONNECTIONS */
+#define MAX_VDEV_SUPPORTED                        4
+
+#define MAX_POWER_DBG_ARGS_SUPPORTED 8
+#define QOS_MAP_MAX_EX  21
+#define QOS_MAP_LEN_MIN 16
+#define QOS_MAP_LEN_MAX \
+	(QOS_MAP_LEN_MIN + 2 * QOS_MAP_MAX_EX)
+#define NUM_CHAINS_MAX  2
+
+#define MAX_RSSI_AVOID_BSSID_LIST    10
+
+/* Maximum number of realms present in fils indication element */
+#define SIR_MAX_REALM_COUNT 7
+/* Realm length */
+#define SIR_REALM_LEN 2
+/* Cache ID length */
+#define CACHE_ID_LEN 2
+
+/* Maximum peer station number query one time */
+#define MAX_PEER_STA 12
+
+/* Maximum number of peers for SAP */
+#ifndef SIR_SAP_MAX_NUM_PEERS
+#define SIR_SAP_MAX_NUM_PEERS 32
+#endif
+
+#define SIR_KRK_KEY_LEN 16
+#define SIR_BTK_KEY_LEN 32
+#define SIR_KCK_KEY_LEN 16
+#define SIR_KEK_KEY_LEN 16
+#define SIR_KEK_KEY_LEN_FILS 64
+#define SIR_REPLAY_CTR_LEN 8
+#define SIR_PMK_LEN  48
+#define SIR_PMKID_LEN 16
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+#define SIR_UAPSD_BITOFFSET_ACVO     0
+#define SIR_UAPSD_BITOFFSET_ACVI     1
+#define SIR_UAPSD_BITOFFSET_ACBK     2
+#define SIR_UAPSD_BITOFFSET_ACBE     3
+
+#define SIR_UAPSD_FLAG_ACVO     (1 << SIR_UAPSD_BITOFFSET_ACVO)
+#define SIR_UAPSD_FLAG_ACVI     (1 << SIR_UAPSD_BITOFFSET_ACVI)
+#define SIR_UAPSD_FLAG_ACBK     (1 << SIR_UAPSD_BITOFFSET_ACBK)
+#define SIR_UAPSD_FLAG_ACBE     (1 << SIR_UAPSD_BITOFFSET_ACBE)
+#define SIR_UAPSD_GET(ac, mask)      (((mask) & (SIR_UAPSD_FLAG_ ## ac)) >> SIR_UAPSD_BITOFFSET_ ## ac)
+
+#endif
+
+/**
+ * enum sir_roam_op_code - Operation to be done by the callback.
+ * @SIR_ROAM_SYNCH_PROPAGATION: Propagate the new BSS info after roaming.
+ * @SIR_ROAMING_DEREGISTER_STA: Deregister the old STA after roaming.
+ * @SIR_ROAMING_START: Firmware started roaming operation
+ * @SIR_ROAMING_ABORT: Firmware aborted roaming operation, still connected.
+ * @SIR_ROAM_SYNCH_COMPLETE: Roam sync propagation is complete.
+ * @SIR_ROAMING_INVOKE_FAIL: Firmware roaming failed.
+ */
+enum sir_roam_op_code {
+	SIR_ROAM_SYNCH_PROPAGATION = 1,
+	SIR_ROAMING_DEREGISTER_STA,
+	SIR_ROAMING_START,
+	SIR_ROAMING_ABORT,
+	SIR_ROAM_SYNCH_COMPLETE,
+	SIR_ROAM_SYNCH_NAPI_OFF,
+	SIR_ROAMING_INVOKE_FAIL,
+};
+/**
+ * Module ID definitions.
+ */
+enum {
+	SIR_BOOT_MODULE_ID = 1,
+	SIR_HAL_MODULE_ID = 0x10,
+	SIR_CFG_MODULE_ID = 0x12,
+	SIR_LIM_MODULE_ID,
+	SIR_ARQ_MODULE_ID,
+	SIR_SCH_MODULE_ID,
+	SIR_PMM_MODULE_ID,
+	SIR_MNT_MODULE_ID,
+	SIR_DBG_MODULE_ID,
+	SIR_DPH_MODULE_ID,
+	SIR_SYS_MODULE_ID,
+	SIR_SMS_MODULE_ID,
+};
+
+#define SIR_WMA_MODULE_ID SIR_HAL_MODULE_ID
+
+/**
+ * First and last module definition for logging utility
+ *
+ * NOTE:  The following definitions need to be updated if
+ *        the above list is changed.
+ */
+#define SIR_FIRST_MODULE_ID     SIR_HAL_MODULE_ID
+#define SIR_LAST_MODULE_ID      SIR_SMS_MODULE_ID
+
+/* Type declarations used by Firmware and Host software */
+
+/* Scan type enum used in scan request */
+typedef enum eSirScanType {
+	eSIR_PASSIVE_SCAN,
+	eSIR_ACTIVE_SCAN,
+	eSIR_BEACON_TABLE,
+} tSirScanType;
+
+/* Rsn Capabilities structure */
+struct rsn_caps {
+	uint16_t PreAuthSupported:1;
+	uint16_t NoPairwise:1;
+	uint16_t PTKSAReplayCounter:2;
+	uint16_t GTKSAReplayCounter:2;
+	uint16_t MFPRequired:1;
+	uint16_t MFPCapable:1;
+	uint16_t Reserved:8;
+};
+
+/* / Result codes Firmware return to Host SW */
+typedef enum eSirResultCodes {
+	eSIR_SME_SUCCESS,
+	eSIR_LOGE_EXCEPTION,
+	eSIR_SME_INVALID_PARAMETERS = 500,
+	eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,
+	eSIR_SME_RESOURCES_UNAVAILABLE,
+	/* Unable to find a BssDescription */
+	eSIR_SME_SCAN_FAILED,
+	/* matching requested scan criteria */
+	eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED,
+	eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE,
+	eSIR_SME_REFUSED,
+	eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA,
+	eSIR_SME_JOIN_TIMEOUT_RESULT_CODE,
+	eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,
+	eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE,
+	eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE,
+	eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED,
+	eSIR_SME_AUTH_REFUSED,
+	eSIR_SME_INVALID_WEP_DEFAULT_KEY,
+	eSIR_SME_NO_KEY_MAPPING_KEY_FOR_PEER,
+	eSIR_SME_ASSOC_REFUSED,
+	eSIR_SME_REASSOC_REFUSED,
+	/* Recvd Deauth while join/pre-auth */
+	eSIR_SME_DEAUTH_WHILE_JOIN,
+	eSIR_SME_STA_NOT_AUTHENTICATED,
+	eSIR_SME_STA_NOT_ASSOCIATED,
+	eSIR_SME_ALREADY_JOINED_A_BSS,
+	/* Given in SME_SCAN_RSP msg */
+	eSIR_SME_MORE_SCAN_RESULTS_FOLLOW,
+	/* that more SME_SCAN_RSP */
+	/* messages are following. */
+	/* SME_SCAN_RSP message with */
+	/* eSIR_SME_SUCCESS status */
+	/* code is the last one. */
+	/* Sent in SME_JOIN/REASSOC_RSP */
+	eSIR_SME_INVALID_ASSOC_RSP_RXED,
+	/* messages upon receiving */
+	/* invalid Re/Assoc Rsp frame. */
+	/* STOP BSS triggered by MIC failures: MAC software to
+	 * disassoc all stations
+	 */
+	eSIR_SME_MIC_COUNTER_MEASURES,
+	/* with MIC_FAILURE reason code and perform the stop bss operation */
+	/* didn't get rsp from peer within timeout interval */
+	eSIR_SME_ADDTS_RSP_TIMEOUT,
+	/* didn't get success rsp from HAL */
+	eSIR_SME_ADDTS_RSP_FAILED,
+	/* failed to send ch switch act frm */
+	eSIR_SME_CHANNEL_SWITCH_FAIL,
+	eSIR_SME_INVALID_STATE,
+	/* SIR_HAL_SIR_HAL_INIT_SCAN_RSP returned failed status */
+	eSIR_SME_HAL_SCAN_INIT_FAILED,
+	/* SIR_HAL_END_SCAN_RSP returned failed status */
+	eSIR_SME_HAL_SCAN_END_FAILED,
+	/* SIR_HAL_FINISH_SCAN_RSP returned failed status */
+	eSIR_SME_HAL_SCAN_FINISH_FAILED,
+	/* Failed to send a message to HAL */
+	eSIR_SME_HAL_SEND_MESSAGE_FAIL,
+	/* Failed to stop the bss */
+	eSIR_SME_STOP_BSS_FAILURE,
+	eSIR_SME_WOWL_ENTER_REQ_FAILED,
+	eSIR_SME_WOWL_EXIT_REQ_FAILED,
+	eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE,
+	eSIR_SME_FT_REASSOC_FAILURE,
+	eSIR_SME_SEND_ACTION_FAIL,
+	eSIR_SME_DEAUTH_STATUS,
+	eSIR_PNO_SCAN_SUCCESS,
+	eSIR_SME_INVALID_SESSION,
+	eSIR_SME_PEER_CREATE_FAILED,
+	eSIR_DONOT_USE_RESULT_CODE = SIR_MAX_ENUM_SIZE
+} tSirResultCodes;
+
+#ifdef WLAN_FEATURE_FILS_SK
+struct fils_join_rsp_params {
+	uint8_t *fils_pmk;
+	uint8_t fils_pmk_len;
+	uint8_t fils_pmkid[PMKID_LEN];
+	uint8_t kek[MAX_KEK_LEN];
+	uint8_t kek_len;
+	uint8_t tk[MAX_TK_LEN];
+	uint8_t tk_len;
+	uint8_t gtk_len;
+	uint8_t gtk[MAX_GTK_LEN];
+	struct qdf_mac_addr dst_mac;
+	struct qdf_mac_addr src_mac;
+	uint16_t hlp_data_len;
+	uint8_t hlp_data[FILS_MAX_HLP_DATA_LEN];
+};
+#endif
+
+#define RMENABLEDCAP_MAX_LEN 5
+
+struct rrm_config_param {
+	uint8_t rrm_enabled;
+	uint8_t max_randn_interval;
+	uint8_t rm_capability[RMENABLEDCAP_MAX_LEN];
+};
+
+/*
+ * although in tSirSupportedRates each IE is 16bit but PE only passes IEs in 8
+ * bits with MSB=1 for basic rates. change the mask for bit0-7 only so HAL gets
+ * correct basic rates for setting response rates.
+ */
+#define IERATE_BASICRATE_MASK     0x80
+#define IERATE_RATE_MASK          0x7f
+#define IERATE_IS_BASICRATE(x)   ((x) & IERATE_BASICRATE_MASK)
+
+const char *lim_bss_type_to_string(const uint16_t bss_type);
+/**
+ * struct sSirSupportedRates - stores rates/MCS supported
+ * @llbRates: 11b rates in unit of 500kbps
+ * @llaRates: 11a rates in unit of 500kbps
+ * @supportedMCSSet: supported basic MCS, 0-76 bits used, remaining reserved
+ *                    bits 0-15 and 32 should be set.
+ * @rxHighestDataRate: RX Highest Supported Data Rate defines the highest data
+ *                      rate that the STA is able to receive, in unites of 1Mbps
+ *                      This value is derived from "Supported MCS Set field"
+ *                      inside the HT capability element.
+ * @vhtRxMCSMap: Indicates the Maximum MCS(VHT) that can be received for each
+ *                number of spacial streams
+ * @vhtRxHighestDataRate: Indicate the highest VHT data rate that the STA is
+ *                         able to receive
+ * @vhtTxMCSMap: Indicates the Maximum MCS(VHT) that can be transmitted for
+ *                each number of spacial streams
+ * @vhtTxHighestDataRate: Indicate the highest VHT data rate that the STA is
+ *                         able to transmit
+ * @he_rx_mcs: Indicates the Maximum MCS(HE) that can be received for each
+ *              number of spacial streams
+ * @he_tx_mcs: Indicates the Maximum MCS(HE) that can be transmitted for each
+ *              number of spacial streams
+ */
+typedef struct sSirSupportedRates {
+	uint16_t llbRates[SIR_NUM_11B_RATES];
+	uint16_t llaRates[SIR_NUM_11A_RATES];
+	uint8_t supportedMCSSet[SIR_MAC_MAX_SUPPORTED_MCS_SET];
+	uint16_t rxHighestDataRate;
+	uint16_t vhtRxMCSMap;
+	uint16_t vhtRxHighestDataRate;
+	uint16_t vhtTxMCSMap;
+	uint16_t vhtTxHighestDataRate;
+#ifdef WLAN_FEATURE_11AX
+	uint16_t rx_he_mcs_map_lt_80;
+	uint16_t tx_he_mcs_map_lt_80;
+	uint16_t rx_he_mcs_map_160;
+	uint16_t tx_he_mcs_map_160;
+	uint16_t rx_he_mcs_map_80_80;
+	uint16_t tx_he_mcs_map_80_80;
+#endif
+} tSirSupportedRates, *tpSirSupportedRates;
+
+typedef struct sSirRemainOnChnReq {
+	uint16_t messageType;
+	uint16_t length;
+	uint8_t sessionId;
+	struct qdf_mac_addr selfMacAddr;
+	uint8_t chnNum;
+	uint8_t phyMode;
+	uint32_t duration;
+	uint8_t isProbeRequestAllowed;
+	uint32_t scan_id;
+	uint8_t probeRspIe[1];
+} tSirRemainOnChnReq, *tpSirRemainOnChnReq;
+
+/**
+ * struct sir_roc_rsp - Structure to store the remain on channel response
+ * @message_type: Message Type
+ * @length: Message Length
+ * @session_id: SME session Id
+ * @scan_id : scan identifier
+ * @status: result status
+ */
+struct sir_roc_rsp {
+	uint16_t message_type;
+	uint16_t length;
+	uint8_t session_id;
+	uint32_t scan_id;
+	tSirResultCodes status;
+};
+
+typedef struct sSirRegisterMgmtFrame {
+	uint16_t messageType;
+	uint16_t length;
+	uint8_t sessionId;
+	bool registerFrame;
+	uint16_t frameType;
+	uint16_t matchLen;
+	uint8_t matchData[1];
+} tSirRegisterMgmtFrame, *tpSirRegisterMgmtFrame;
+
+/* / Generic type for sending a response message */
+/* / with result code to host software */
+typedef struct sSirSmeRsp {
+	uint16_t messageType;   /* eWNI_SME_*_RSP */
+	uint16_t length;
+	uint8_t sessionId;      /* To support BT-AMP */
+	uint16_t transactionId; /* To support BT-AMP */
+	tSirResultCodes statusCode;
+	struct wlan_objmgr_psoc *psoc;
+} tSirSmeRsp, *tpSirSmeRsp;
+
+/* / Definition for indicating all modules ready on STA */
+typedef struct sSirSmeReadyReq {
+	uint16_t messageType;   /* eWNI_SME_SYS_READY_IND */
+	uint16_t length;
+	uint16_t transactionId;
+	void *csr_roam_synch_cb;
+	void *pe_roam_synch_cb;
+	void *stop_roaming_cb;
+	QDF_STATUS (*sme_msg_cb)(tpAniSirGlobal mac,
+				 struct scheduler_msg *msg);
+} tSirSmeReadyReq, *tpSirSmeReadyReq;
+
+/**
+ * struct s_sir_set_hw_mode - Set HW mode request
+ * @messageType: Message type
+ * @length: Length of the message
+ * @set_hw: Params containing the HW mode index and callback
+ */
+struct s_sir_set_hw_mode {
+	uint16_t messageType;
+	uint16_t length;
+	struct policy_mgr_hw_mode set_hw;
+};
+
+/**
+ * struct sir_set_dual_mac_cfg - Set Dual mac config request
+ * @message_type: Message type
+ * @length: Length of the message
+ * @set_dual_mac: Params containing the dual mac config and callback
+ */
+struct sir_set_dual_mac_cfg {
+	uint16_t message_type;
+	uint16_t length;
+	struct policy_mgr_dual_mac_config set_dual_mac;
+};
+
+/**
+ * struct sir_antenna_mode_param - antenna mode param
+ * @num_tx_chains: Number of TX chains
+ * @num_rx_chains: Number of RX chains
+ * @set_antenna_mode_resp: callback to set antenna mode command
+ * @set_antenna_mode_ctx: callback context to set antenna mode command
+ */
+struct sir_antenna_mode_param {
+	uint32_t num_tx_chains;
+	uint32_t num_rx_chains;
+	void *set_antenna_mode_resp;
+	void *set_antenna_mode_ctx;
+};
+
+/**
+ * struct sir_set_antenna_mode - Set antenna mode request
+ * @message_type: Message type
+ * @length: Length of the message
+ * @set_antenna_mode: Params containing antenna mode params
+ */
+struct sir_set_antenna_mode {
+	uint16_t message_type;
+	uint16_t length;
+	struct sir_antenna_mode_param set_antenna_mode;
+};
+
+/**
+ * enum tSirBssType - Enum for BSS type used in scanning/joining etc.
+ *
+ * @eSIR_INFRASTRUCTURE_MODE: Infrastructure station
+ * @eSIR_INFRA_AP_MODE: softAP mode
+ * @eSIR_IBSS_MODE: IBSS mode
+ * @eSIR_AUTO_MODE: Auto role
+ * @eSIR_MONITOR_MODE: Monitor mode
+ * @eSIR_NDI_MODE: NAN datapath mode
+ */
+typedef enum eSirBssType {
+	eSIR_INFRASTRUCTURE_MODE,
+	eSIR_INFRA_AP_MODE,
+	eSIR_IBSS_MODE,
+	eSIR_AUTO_MODE,
+	eSIR_MONITOR_MODE,
+	eSIR_NDI_MODE,
+	eSIR_DONOT_USE_BSS_TYPE = SIR_MAX_ENUM_SIZE
+} tSirBssType;
+
+/* / Power Capability info used in 11H */
+typedef struct sSirMacPowerCapInfo {
+	uint8_t minTxPower;
+	uint8_t maxTxPower;
+} tSirMacPowerCapInfo, *tpSirMacPowerCapInfo;
+
+/* / Supported Channel info used in 11H */
+typedef struct sSirSupChnl {
+	uint8_t numChnl;
+	uint8_t channelList[SIR_MAX_SUPPORTED_CHANNEL_LIST];
+} tSirSupChnl, *tpSirSupChnl;
+
+typedef enum eSirNwType {
+	eSIR_11A_NW_TYPE,
+	eSIR_11B_NW_TYPE,
+	eSIR_11G_NW_TYPE,
+	eSIR_11N_NW_TYPE,
+	eSIR_11AC_NW_TYPE,
+	eSIR_11AX_NW_TYPE,
+	eSIR_DONOT_USE_NW_TYPE = SIR_MAX_ENUM_SIZE
+} tSirNwType;
+
+/* / Definition for new iBss peer info */
+typedef struct sSirNewIbssPeerInfo {
+	struct qdf_mac_addr peerAddr;
+	uint16_t aid;
+} tSirNewIbssPeerInfo, *tpSirNewIbssPeerInfo;
+
+/* HT configuration values */
+typedef struct sSirHtConfig {
+	/* Enable/Disable receiving LDPC coded packets */
+	uint32_t ht_rx_ldpc:1;
+	/* Enable/Disable TX STBC */
+	uint32_t ht_tx_stbc:1;
+	/* Enable/Disable RX STBC */
+	uint32_t ht_rx_stbc:2;
+	/* Enable/Disable SGI */
+	uint32_t ht_sgi20:1;
+	uint32_t ht_sgi40:1;
+	uint32_t unused:27;
+} qdf_packed tSirHTConfig, *tpSirHTConfig;
+
+/**
+ * struct sir_vht_config - VHT capabilities
+ * @max_mpdu_len: MPDU length
+ * @supported_channel_widthset: channel width set
+ * @ldpc_coding: LDPC coding capability
+ * @shortgi80: short GI 80 support
+ * @shortgi160and80plus80: short Gi 160 & 80+80 support
+ * @tx_stbc; Tx STBC cap
+ * @tx_stbc: Rx STBC cap
+ * @su_beam_former: SU beam former cap
+ * @su_beam_formee: SU beam formee cap
+ * @csnof_beamformer_antSup: Antenna support for beamforming
+ * @num_soundingdim: Sound dimensions
+ * @mu_beam_former: MU beam former cap
+ * @mu_beam_formee: MU beam formee cap
+ * @vht_txops: TXOP power save
+ * @htc_vhtcap: HTC VHT capability
+ * @max_ampdu_lenexp: AMPDU length
+ * @vht_link_adapt: VHT link adapatation capable
+ * @rx_antpattern: Rx Antenna pattern
+ * @tx_antpattern: Tx Antenna pattern
+ */
+struct sir_vht_config {
+	uint32_t           max_mpdu_len:2;
+	uint32_t supported_channel_widthset:2;
+	uint32_t        ldpc_coding:1;
+	uint32_t         shortgi80:1;
+	uint32_t shortgi160and80plus80:1;
+	uint32_t               tx_stbc:1;
+	uint32_t               rx_stbc:3;
+	uint32_t      su_beam_former:1;
+	uint32_t      su_beam_formee:1;
+	uint32_t csnof_beamformer_antSup:3;
+	uint32_t       num_soundingdim:3;
+	uint32_t      mu_beam_former:1;
+	uint32_t      mu_beam_formee:1;
+	uint32_t            vht_txops:1;
+	uint32_t            htc_vhtcap:1;
+	uint32_t       max_ampdu_lenexp:3;
+	uint32_t        vht_link_adapt:2;
+	uint32_t         rx_antpattern:1;
+	uint32_t         tx_antpattern:1;
+	uint32_t            unused:2;
+};
+
+
+typedef struct sSirAddIeParams {
+	uint16_t probeRespDataLen;
+	uint8_t *probeRespData_buff;
+	uint16_t assocRespDataLen;
+	uint8_t *assocRespData_buff;
+	uint16_t probeRespBCNDataLen;
+	uint8_t *probeRespBCNData_buff;
+} tSirAddIeParams, *tpSirAddIeParams;
+
+/* / Definition for kick starting BSS */
+/* / ---> MAC */
+/**
+ * Usage of ssId, numSSID & ssIdList:
+ * ---------------------------------
+ * 1. ssId.length of zero indicates that Broadcast/Suppress SSID
+ *    feature is enabled.
+ * 2. If ssId.length is zero, MAC SW will advertise NULL SSID
+ *    and interpret the SSID list from numSSID & ssIdList.
+ * 3. If ssId.length is non-zero, MAC SW will advertise the SSID
+ *    specified in the ssId field and it is expected that
+ *    application will set numSSID to one (only one SSID present
+ *    in the list) and SSID in the list is same as ssId field.
+ * 4. Application will always set numSSID >= 1.
+ */
+/* ***** NOTE: Please make sure all codes are updated if inserting field into
+ * this structure..********** */
+typedef struct sSirSmeStartBssReq {
+	uint16_t messageType;   /* eWNI_SME_START_BSS_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Added for BT-AMP Support */
+	uint16_t transactionId; /* Added for BT-AMP Support */
+	struct qdf_mac_addr bssid;      /* Added for BT-AMP Support */
+	struct qdf_mac_addr self_macaddr;        /* Added for BT-AMP Support */
+	uint16_t beaconInterval;        /* Added for BT-AMP Support */
+	uint8_t dot11mode;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	uint8_t cc_switch_mode;
+#endif
+	tSirBssType bssType;
+	tSirMacSSid ssId;
+	uint8_t channelId;
+	ePhyChanBondState cbMode;
+	uint8_t vht_channel_width;
+	uint8_t center_freq_seg0;
+	uint8_t center_freq_seg1;
+	uint8_t sec_ch_offset;
+
+	uint8_t privacy;
+	uint8_t apUapsdEnable;
+	uint8_t ssidHidden;
+	bool fwdWPSPBCProbeReq;
+	bool protEnabled;
+	bool obssProtEnabled;
+	uint16_t ht_capab;
+	tAniAuthType authType;
+	uint32_t dtimPeriod;
+	uint8_t wps_state;
+	uint8_t isCoalesingInIBSSAllowed;       /* Coalesing on/off knob */
+	enum QDF_OPMODE bssPersona;
+
+	uint8_t txLdpcIniFeatureEnabled;
+
+	tSirRSNie rsnIE;        /* RSN IE to be sent in */
+	/* Beacon and Probe */
+	/* Response frames */
+	tSirNwType nwType;      /* Indicates 11a/b/g */
+	tSirMacRateSet operationalRateSet;      /* Has 11a or 11b rates */
+	tSirMacRateSet extendedRateSet; /* Has 11g rates */
+	tSirHTConfig htConfig;
+	struct sir_vht_config vht_config;
+#ifdef WLAN_FEATURE_11AX
+	tDot11fIEhe_cap he_config;
+#endif
+#ifdef WLAN_FEATURE_11W
+	bool pmfCapable;
+	bool pmfRequired;
+#endif
+
+	tSirAddIeParams addIeParams;
+
+	bool obssEnabled;
+	uint8_t sap_dot11mc;
+	uint16_t beacon_tx_rate;
+	bool vendor_vht_sap;
+	uint32_t cac_duration_ms;
+	uint32_t dfs_regdomain;
+
+} tSirSmeStartBssReq, *tpSirSmeStartBssReq;
+
+#define GET_IE_LEN_IN_BSS(lenInBss) (lenInBss + sizeof(lenInBss) - \
+				    ((uintptr_t)OFFSET_OF(tSirBssDescription,\
+							  ieFields)))
+
+#define WSCIE_PROBE_RSP_LEN (317 + 2)
+
+#ifdef WLAN_FEATURE_FILS_SK
+/* struct fils_ind_elements: elements parsed from fils indication present
+ * in beacon/probe resp
+ * @realm_cnt: number of realm present
+ * @realm: realms
+ * @is_fils_sk_supported: if FILS SK supported
+ * @is_cache_id_present: if cache id present
+ * @cache_id: cache id
+ */
+struct fils_ind_elements {
+	uint16_t realm_cnt;
+	uint8_t realm[SIR_MAX_REALM_COUNT][SIR_REALM_LEN];
+	bool is_fils_sk_supported;
+	bool is_cache_id_present;
+	uint8_t cache_id[CACHE_ID_LEN];
+};
+#endif
+
+struct bss_description {
+	/* offset of the ieFields from bssId. */
+	uint16_t length;
+	tSirMacAddr bssId;
+	unsigned long scansystimensec;
+	uint32_t timeStamp[2];
+	uint16_t beaconInterval;
+	uint16_t capabilityInfo;
+	tSirNwType nwType;      /* Indicates 11a/b/g */
+	int8_t rssi;
+	int8_t rssi_raw;
+	int8_t sinr;
+	/* channelId what peer sent in beacon/probersp. */
+	uint8_t channelId;
+	/* channelId on which we are parked at. */
+	/* used only in scan case. */
+	uint8_t channelIdSelf;
+	uint8_t sSirBssDescriptionRsvd[3];
+	/* Based on system time, not a relative time. */
+	uint64_t received_time;
+	uint32_t parentTSF;
+	uint32_t startTSF[2];
+	uint8_t mdiePresent;
+	/* MDIE for 11r, picked from the beacons */
+	uint8_t mdie[SIR_MDIE_SIZE];
+#ifdef FEATURE_WLAN_ESE
+	uint16_t QBSSLoad_present;
+	uint16_t QBSSLoad_avail;
+	/* To achieve 8-byte alignment with ESE enabled */
+	uint32_t reservedPadding5;
+#endif
+	/* whether it is from a probe rsp */
+	uint8_t fProbeRsp;
+	/* Actual channel the beacon/probe response was received on */
+	uint8_t rx_channel;
+	tSirMacSeqCtl seq_ctrl;
+	uint32_t WscIeLen;
+	uint8_t WscIeProbeRsp[WSCIE_PROBE_RSP_LEN];
+	uint8_t reservedPadding4;
+	uint32_t tsf_delta;
+#ifdef WLAN_FEATURE_FILS_SK
+	struct fils_ind_elements fils_info_element;
+#endif
+	/* Please keep the structure 4 bytes aligned above the ieFields */
+	uint32_t ieFields[1];
+};
+typedef struct bss_description tSirBssDescription, *tpSirBssDescription;
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+typedef struct sSirSmeHTProfile {
+	uint8_t dot11mode;
+	uint8_t htCapability;
+	uint8_t htSupportedChannelWidthSet;
+	uint8_t htRecommendedTxWidthSet;
+	ePhyChanBondState htSecondaryChannelOffset;
+	uint8_t vhtCapability;
+	uint8_t apCenterChan;
+	uint8_t apChanWidth;
+} tSirSmeHTProfile;
+#endif
+/* / Definition for response message to previously */
+/* / issued start BSS request */
+/* / MAC ---> */
+typedef struct sSirSmeStartBssRsp {
+	uint16_t messageType;   /* eWNI_SME_START_BSS_RSP */
+	uint16_t length;
+	uint8_t sessionId;
+	uint16_t transactionId; /* transaction ID for cmd */
+	tSirResultCodes statusCode;
+	tSirBssType bssType;    /* Add new type for WDS mode */
+	uint16_t beaconInterval;        /* Beacon Interval for both type */
+	uint32_t staId;         /* Station ID for Self */
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	tSirSmeHTProfile HTProfile;
+#endif
+	tSirBssDescription bssDescription;      /* Peer BSS description */
+} tSirSmeStartBssRsp, *tpSirSmeStartBssRsp;
+
+typedef struct sSirChannelList {
+	uint8_t numChannels;
+	uint8_t channelNumber[SIR_ESE_MAX_MEAS_IE_REQS];
+} tSirChannelList, *tpSirChannelList;
+
+typedef struct sSirDFSChannelList {
+	uint32_t timeStamp[SIR_MAX_24G_5G_CHANNEL_RANGE];
+
+} tSirDFSChannelList, *tpSirDFSChannelList;
+
+/* / Two Background Scan mode */
+typedef enum eSirBackgroundScanMode {
+	eSIR_ROAMING_SCAN = 2,
+} tSirBackgroundScanMode;
+
+/* / Two types of traffic check */
+typedef enum eSirLinkTrafficCheck {
+	eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN = 0,
+	eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN = 1,
+	eSIR_CHECK_ROAMING_SCAN = 2,
+} tSirLinkTrafficCheck;
+
+#define SIR_BG_SCAN_RETURN_CACHED_RESULTS              0x0
+#define SIR_BG_SCAN_PURGE_RESUTLS                      0x80
+#define SIR_BG_SCAN_RETURN_FRESH_RESULTS               0x01
+#define SIR_SCAN_MAX_NUM_SSID                          0x0A
+#define SIR_BG_SCAN_RETURN_LFR_CACHED_RESULTS          0x02
+#define SIR_BG_SCAN_PURGE_LFR_RESULTS                  0x40
+
+typedef struct sSirSmeScanAbortReq {
+	uint16_t type;
+	uint16_t msgLen;
+	uint8_t sessionId;
+	uint32_t scan_id;
+} tSirSmeScanAbortReq, *tpSirSmeScanAbortReq;
+
+typedef struct sSirSmeScanChanReq {
+	uint16_t type;
+	uint16_t msgLen;
+	uint8_t sessionId;
+	uint16_t transcationId;
+} tSirSmeGetScanChanReq, *tpSirSmeGetScanChanReq;
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+struct oem_data_req {
+	uint32_t data_len;
+	uint8_t *data;
+};
+
+struct oem_data_rsp {
+	uint32_t rsp_len;
+	uint8_t *data;
+};
+#endif /* FEATURE_OEM_DATA_SUPPORT */
+
+#ifdef FEATURE_WLAN_ESE
+typedef struct ese_wmm_tspec_ie {
+	uint16_t         traffic_type:1;
+	uint16_t                 tsid:4;
+	uint16_t            direction:2;
+	uint16_t        access_policy:2;
+	uint16_t          aggregation:1;
+	uint16_t                  psb:1;
+	uint16_t        user_priority:3;
+	uint16_t       tsinfo_ack_pol:2;
+	uint8_t          tsinfo_rsvd:7;
+	uint8_t      burst_size_defn:1;
+	uint16_t                 size:15;
+	uint16_t                fixed:1;
+	uint16_t            max_msdu_size;
+	uint32_t            min_service_int;
+	uint32_t            max_service_int;
+	uint32_t            inactivity_int;
+	uint32_t            suspension_int;
+	uint32_t            service_start_time;
+	uint32_t            min_data_rate;
+	uint32_t            mean_data_rate;
+	uint32_t            peak_data_rate;
+	uint32_t            burst_size;
+	uint32_t            delay_bound;
+	uint32_t            min_phy_rate;
+	uint16_t            surplus_bw_allowance;
+	uint16_t            medium_time;
+} qdf_packed ese_wmm_tspec_ie;
+
+typedef struct sTspecInfo {
+	uint8_t valid;
+	tSirMacTspecIE tspec;
+} tTspecInfo;
+
+#define SIR_ESE_MAX_TSPEC_IES   4
+typedef struct sESETspecTspecInfo {
+	uint8_t numTspecs;
+	tTspecInfo tspec[SIR_ESE_MAX_TSPEC_IES];
+} tESETspecInfo;
+
+typedef struct sSirTsmIE {
+	uint8_t tsid;
+	uint8_t state;
+	uint16_t msmt_interval;
+} tSirTsmIE, *tpSirTsmIE;
+typedef struct sSirSmeTsmIEInd {
+	tSirTsmIE tsmIe;
+	uint8_t sessionId;
+} tSirSmeTsmIEInd, *tpSirSmeTsmIEInd;
+typedef struct sAniTrafStrmMetrics {
+	uint16_t UplinkPktQueueDly;
+	uint16_t UplinkPktQueueDlyHist[4];
+	uint32_t UplinkPktTxDly;
+	uint16_t UplinkPktLoss;
+	uint16_t UplinkPktCount;
+	uint8_t RoamingCount;
+	uint16_t RoamingDly;
+} tAniTrafStrmMetrics, *tpAniTrafStrmMetrics;
+
+typedef struct sAniGetTsmStatsReq {
+	/* Common for all types are requests */
+	uint16_t msgType;       /* message type is same as the request type */
+	uint16_t msgLen;        /* length of the entire request */
+	uint8_t staId;
+	uint8_t tid;            /* traffic id */
+	struct qdf_mac_addr bssId;
+	void *tsmStatsCallback;
+	void *pDevContext;      /* device context */
+} tAniGetTsmStatsReq, *tpAniGetTsmStatsReq;
+
+typedef struct sAniGetTsmStatsRsp {
+	/* Common for all types are responses */
+	uint16_t msgType;       /*
+				 * message type is same as
+				 * the request type
+				 */
+	uint16_t msgLen;        /*
+				 * length of the entire request,
+				 * includes the pStatsBuf length too
+				 */
+	uint8_t sessionId;
+	uint32_t rc;            /* success/failure */
+	uint32_t staId;         /*
+				 * Per STA stats request must
+				 * contain valid
+				 */
+	tAniTrafStrmMetrics tsmMetrics;
+	void *tsmStatsReq;      /* tsm stats request backup */
+} tAniGetTsmStatsRsp, *tpAniGetTsmStatsRsp;
+
+typedef struct sSirEseBcnReportBssInfo {
+	tBcnReportFields bcnReportFields;
+	uint8_t ieLen;
+	uint8_t *pBuf;
+} tSirEseBcnReportBssInfo, *tpSirEseBcnReportBssInfo;
+
+typedef struct sSirEseBcnReportRsp {
+	uint16_t measurementToken;
+	uint8_t flag;        /* Flag to report measurement done and more data */
+	uint8_t numBss;
+	tSirEseBcnReportBssInfo bcnRepBssInfo[SIR_BCN_REPORT_MAX_BSS_DESC];
+} tSirEseBcnReportRsp, *tpSirEseBcnReportRsp;
+
+#define TSRS_11AG_RATE_6MBPS   0xC
+#define TSRS_11B_RATE_5_5MBPS  0xB
+typedef struct sSirMacESETSRSIE {
+	uint8_t tsid;
+	uint8_t rates[8];
+} tSirMacESETSRSIE;
+typedef struct sSirMacESETSMIE {
+	uint8_t tsid;
+	uint8_t state;
+	uint16_t msmt_interval;
+} tSirMacESETSMIE;
+typedef struct sTSMStats {
+	uint8_t tid;
+	struct qdf_mac_addr bssid;
+	tTrafStrmMetrics tsmMetrics;
+} tTSMStats, *tpTSMStats;
+typedef struct sEseTSMContext {
+	uint8_t tid;
+	tSirMacESETSMIE tsmInfo;
+	tTrafStrmMetrics tsmMetrics;
+} tEseTSMContext, *tpEseTSMContext;
+typedef struct sEsePEContext {
+	tEseTSMContext tsm;
+} tEsePEContext, *tpEsePEContext;
+
+typedef struct sSirPlmReq {
+	uint16_t diag_token;    /* Dialog token */
+	uint16_t meas_token;    /* measurement token */
+	uint16_t numBursts;     /* total number of bursts */
+	uint16_t burstInt;      /* burst interval in seconds */
+	uint16_t measDuration;  /* in TU's,STA goes off-ch */
+	/* no of times the STA should cycle through PLM ch list */
+	uint8_t burstLen;
+	int8_t  desiredTxPwr; /* desired tx power */
+	struct qdf_mac_addr mac_addr;    /* MC dest addr */
+	/* no of channels */
+	uint8_t plmNumCh;
+	/* channel numbers */
+	uint8_t plmChList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	uint8_t sessionId;
+	bool enable;
+} tSirPlmReq, *tpSirPlmReq;
+
+#endif /* FEATURE_WLAN_ESE */
+
+/* / Definition for response message to previously issued scan request */
+typedef struct sSirSmeScanRsp {
+	uint16_t messageType;   /* eWNI_SME_SCAN_RSP */
+	uint16_t length;
+	uint8_t sessionId;
+	tSirResultCodes statusCode;
+	uint16_t transcationId;
+	uint32_t scan_id;
+} tSirSmeScanRsp, *tpSirSmeScanRsp;
+
+/* / Definition for join request */
+/* / ---> MAC */
+/* / WARNING! If you add a field in JOIN REQ. */
+/* /         Make sure to add it in REASSOC REQ */
+/* / The Serdes function is the same and its */
+/* / shared with REASSOC. So if we add a field */
+/*  here and dont add it in REASSOC REQ. It will BREAK!!! REASSOC. */
+typedef struct sSirSmeJoinReq {
+	uint16_t messageType;   /* eWNI_SME_JOIN_REQ */
+	uint16_t length;
+	uint8_t sessionId;
+	uint16_t transactionId;
+	tSirMacSSid ssId;
+	tSirMacAddr selfMacAddr;        /* self Mac address */
+	tSirBssType bsstype;    /* add new type for BT-AMP STA and AP Modules */
+	uint8_t dot11mode;      /* to support BT-AMP */
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	uint8_t cc_switch_mode;
+#endif
+	enum QDF_OPMODE staPersona;       /* Persona */
+	bool wps_registration;
+	ePhyChanBondState cbMode;       /* Pass CB mode value in Join. */
+
+	/*This contains the UAPSD Flag for all 4 AC
+	 * B0: AC_VO UAPSD FLAG
+	 * B1: AC_VI UAPSD FLAG
+	 * B2: AC_BK UAPSD FLAG
+	 * B3: AC_BE UASPD FLAG
+	 */
+	uint8_t uapsdPerAcBitmask;
+
+	tSirMacRateSet operationalRateSet;      /* Has 11a or 11b rates */
+	tSirMacRateSet extendedRateSet; /* Has 11g rates */
+	tSirRSNie rsnIE;        /* RSN IE to be sent in */
+	/* (Re) Association Request */
+#ifdef FEATURE_WLAN_ESE
+	/* CCMK IE to be included as handler for join and reassoc is */
+	tSirCCKMie cckmIE;
+	/* the same. The join will never carry cckm, but will be set to */
+	/* 0. */
+#endif
+
+	tSirAddie addIEScan;    /* Additional IE to be sent in */
+	/* (unicast) Probe Request at the time of join */
+
+	tSirAddie addIEAssoc;   /* Additional IE to be sent in */
+	/* (Re) Association Request */
+
+	tAniEdType UCEncryptionType;
+
+	tAniEdType MCEncryptionType;
+
+#ifdef WLAN_FEATURE_11W
+	tAniEdType MgmtEncryptionType;
+#endif
+
+	bool is11Rconnection;
+#ifdef FEATURE_WLAN_ESE
+	bool isESEFeatureIniEnabled;
+	bool isESEconnection;
+	tESETspecInfo eseTspecInfo;
+#endif
+
+	bool isFastTransitionEnabled;
+	bool isFastRoamIniFeatureEnabled;
+
+	uint8_t txLdpcIniFeatureEnabled;
+	tSirHTConfig htConfig;
+	struct sir_vht_config vht_config;
+#ifdef WLAN_FEATURE_11AX
+	tDot11fIEhe_cap he_config;
+#endif
+	uint8_t enableVhtpAid;
+	uint8_t enableVhtGid;
+	uint8_t enableAmpduPs;
+	uint8_t enableHtSmps;
+	uint8_t htSmps;
+	bool send_smps_action;
+	bool he_with_wep_tkip;
+	uint8_t max_amsdu_num;
+	bool isWMEenabled;
+	bool isQosEnabled;
+	bool isOSENConnection;
+	struct rrm_config_param rrm_config;
+	bool spectrumMgtIndicator;
+	tSirMacPowerCapInfo powerCap;
+	tSirSupChnl supportedChannels;
+	bool enable_bcast_probe_rsp;
+#ifdef WLAN_FEATURE_FILS_SK
+	struct cds_fils_connection_info fils_con_info;
+#endif
+	bool sae_pmk_cached;
+	/* Pls make this as last variable in struct */
+	bool force_24ghz_in_ht20;
+	bool force_rsne_override;
+	bool supported_nss_1x1;
+	uint8_t vdev_nss;
+	uint8_t nss;
+	bool nss_forced_1x1;
+	bool enable_session_twt_support;
+	tSirBssDescription bssDescription;
+	/*
+	 * WARNING: Pls make bssDescription as last variable in struct
+	 * tSirSmeJoinReq as it has ieFields followed after this bss
+	 * description. Adding a variable after this corrupts the ieFields
+	 */
+} tSirSmeJoinReq, *tpSirSmeJoinReq;
+
+/* / Definition for response message to previously issued join request */
+/* / MAC ---> */
+typedef struct sSirSmeJoinRsp {
+	uint16_t messageType;   /* eWNI_SME_JOIN_RSP */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	tSirResultCodes statusCode;
+	tAniAuthType authType;
+	uint32_t vht_channel_width;
+	/* It holds reasonCode when join fails due to deauth/disassoc frame.
+	 * Otherwise it holds status code.
+	 */
+	uint16_t protStatusCode;
+	uint16_t aid;
+	uint32_t beaconLength;
+	uint32_t assocReqLength;
+	uint32_t assocRspLength;
+	uint32_t parsedRicRspLen;
+#ifdef FEATURE_WLAN_ESE
+	uint32_t tspecIeLen;
+#endif
+	uint32_t staId;         /* Station ID for peer */
+
+	/*Timing measurement capability */
+	uint8_t timingMeasCap;
+
+#ifdef FEATURE_WLAN_TDLS
+	/* TDLS prohibited and TDLS channel switch prohibited are set as
+	 * per ExtCap IE in received assoc/re-assoc response from AP
+	 */
+	bool tdls_prohibited;
+	bool tdls_chan_swit_prohibited;
+#endif
+	uint8_t nss;
+	uint32_t max_rate_flags;
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	tSirSmeHTProfile HTProfile;
+#endif
+	bool supported_nss_1x1;
+	tDot11fIEHTCaps ht_caps;
+	tDot11fIEVHTCaps vht_caps;
+	tDot11fIEHTInfo ht_operation;
+	tDot11fIEVHTOperation vht_operation;
+	tDot11fIEhs20vendor_ie hs20vendor_ie;
+	bool is_fils_connection;
+	uint16_t fils_seq_num;
+#ifdef WLAN_FEATURE_FILS_SK
+	struct fils_join_rsp_params *fils_join_rsp;
+#endif
+	uint8_t frames[1];
+} tSirSmeJoinRsp, *tpSirSmeJoinRsp;
+
+/* / probereq from peer, when wsc is enabled */
+typedef struct sSirSmeProbereq {
+	uint16_t messageType;
+	uint16_t length;
+	uint8_t sessionId;
+	struct qdf_mac_addr peer_macaddr;
+	uint16_t devicePasswdId;
+} tSirSmeProbeReq, *tpSirSmeProbeReq;
+
+typedef struct sSirSmeChanInfo {
+	uint8_t chan_id;
+	uint32_t mhz;
+	uint32_t band_center_freq1;
+	uint32_t band_center_freq2;
+	uint32_t info;
+	uint32_t reg_info_1;
+	uint32_t reg_info_2;
+	uint8_t nss;
+	uint32_t rate_flags;
+	uint8_t sec_ch_offset;
+	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 {
+	uint16_t messageType;   /* eWNI_SME_ASSOC_IND */
+	uint16_t length;
+	uint8_t sessionId;
+	tSirMacAddr peerMacAddr;
+	uint16_t aid;
+	tSirMacAddr bssId;      /* Self BSSID */
+	uint16_t staId;         /* Station ID for peer */
+	tAniAuthType authType;
+	tAniSSID ssId;          /* SSID used by STA to associate */
+	tSirWAPIie wapiIE;      /* WAPI IE received from peer */
+	tSirRSNie rsnIE;        /* RSN IE received from peer */
+	/* Additional IE received from peer, which possibly include
+	 * WSC IE and/or P2P IE
+	 */
+	tSirAddie addIE;
+
+	/* powerCap & supportedChannels are present only when */
+	/* spectrumMgtIndicator flag is set */
+	bool spectrumMgtIndicator;
+	tSirMacPowerCapInfo powerCap;
+	tSirSupChnl supportedChannels;
+	bool wmmEnabledSta; /* if present - STA is WMM enabled */
+	bool reassocReq;
+	/* Required for indicating the frames to upper layer */
+	uint32_t beaconLength;
+	uint8_t *beaconPtr;
+	uint32_t assocReqLength;
+	uint8_t *assocReqPtr;
+
+	/* 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;
+	/* Extended CSA capability of station */
+	uint8_t ecsa_capable;
+	tDot11fIEHTCaps HTCaps;
+	tDot11fIEVHTCaps VHTCaps;
+} tSirSmeAssocInd, *tpSirSmeAssocInd;
+
+/* / Definition for Association confirm */
+/* / ---> MAC */
+typedef struct sSirSmeAssocCnf {
+	uint16_t messageType;   /* eWNI_SME_ASSOC_CNF */
+	uint16_t length;
+	tSirResultCodes statusCode;
+	struct qdf_mac_addr bssid;      /* Self BSSID */
+	struct qdf_mac_addr peer_macaddr;
+	uint16_t aid;
+	struct qdf_mac_addr alternate_bssid;
+	uint8_t alternateChannelId;
+} tSirSmeAssocCnf, *tpSirSmeAssocCnf;
+
+/* / Enum definition for  Wireless medium status change codes */
+typedef enum eSirSmeStatusChangeCode {
+	eSIR_SME_DEAUTH_FROM_PEER,
+	eSIR_SME_DISASSOC_FROM_PEER,
+	eSIR_SME_LOST_LINK_WITH_PEER,
+	eSIR_SME_CHANNEL_SWITCH,
+	eSIR_SME_JOINED_NEW_BSS,
+	eSIR_SME_LEAVING_BSS,
+	eSIR_SME_IBSS_ACTIVE,
+	eSIR_SME_IBSS_INACTIVE,
+	eSIR_SME_IBSS_PEER_DEPARTED,
+	eSIR_SME_RADAR_DETECTED,
+	eSIR_SME_IBSS_NEW_PEER,
+	eSIR_SME_AP_CAPS_CHANGED,
+} tSirSmeStatusChangeCode;
+
+typedef struct sSirSmeNewBssInfo {
+	struct qdf_mac_addr bssId;
+	uint8_t channelNumber;
+	uint8_t reserved;
+	tSirMacSSid ssId;
+} tSirSmeNewBssInfo, *tpSirSmeNewBssInfo;
+
+typedef struct sSirSmeApNewCaps {
+	uint16_t capabilityInfo;
+	struct qdf_mac_addr bssId;
+	uint8_t channelId;
+	uint8_t reserved[3];
+	tSirMacSSid ssId;
+} tSirSmeApNewCaps, *tpSirSmeApNewCaps;
+
+/**
+ * Table below indicates what information is passed for each of
+ * the Wireless Media status change notifications:
+ *
+ * Status Change code           Status change info
+ * ----------------------------------------------------------------------
+ * eSIR_SME_DEAUTH_FROM_PEER        Reason code received in DEAUTH frame
+ * eSIR_SME_DISASSOC_FROM_PEER      Reason code received in DISASSOC frame
+ * eSIR_SME_LOST_LINK_WITH_PEER     None
+ * eSIR_SME_CHANNEL_SWITCH          New channel number
+ * eSIR_SME_JOINED_NEW_BSS          BSSID, SSID and channel number
+ * eSIR_SME_LEAVING_BSS             None
+ * eSIR_SME_IBSS_ACTIVE             Indicates that another STA joined
+ *                                  IBSS apart from this STA that
+ *                                  started IBSS
+ * eSIR_SME_IBSS_INACTIVE           Indicates that only this STA is left
+ *                                  in IBSS
+ * eSIR_SME_RADAR_DETECTED          Indicates that radar is detected
+ * eSIR_SME_IBSS_NEW_PEER           Indicates that a new peer is detected
+ * eSIR_SME_AP_CAPS_CHANGED         Indicates that capabilities of the AP
+ *                                  that STA is currently associated with
+ *                                  have changed.
+ */
+
+/* / Definition for Wireless medium status change notification */
+typedef struct sSirSmeWmStatusChangeNtf {
+	uint16_t messageType;   /* eWNI_SME_WM_STATUS_CHANGE_NTF */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	tSirSmeStatusChangeCode statusChangeCode;
+	struct qdf_mac_addr bssid;      /* Self BSSID */
+	union {
+		uint16_t deAuthReasonCode;      /* eSIR_SME_DEAUTH_FROM_PEER */
+		/* eSIR_SME_DISASSOC_FROM_PEER */
+		uint16_t disassocReasonCode;
+		/* none for eSIR_SME_LOST_LINK_WITH_PEER */
+		uint8_t newChannelId;   /* eSIR_SME_CHANNEL_SWITCH */
+		tSirSmeNewBssInfo newBssInfo;   /* eSIR_SME_JOINED_NEW_BSS */
+		/* none for eSIR_SME_LEAVING_BSS */
+		/* none for eSIR_SME_IBSS_ACTIVE */
+		/* none for eSIR_SME_IBSS_INACTIVE */
+		/* eSIR_SME_IBSS_NEW_PEER */
+		tSirNewIbssPeerInfo newIbssPeerInfo;
+		tSirSmeApNewCaps apNewCaps;     /* eSIR_SME_AP_CAPS_CHANGED */
+	} statusChangeInfo;
+} tSirSmeWmStatusChangeNtf, *tpSirSmeWmStatusChangeNtf;
+
+/* Definition for Disassociation request */
+typedef struct sSirSmeDisassocReq {
+	uint16_t messageType;   /* eWNI_SME_DISASSOC_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	struct qdf_mac_addr bssid;      /* Peer BSSID */
+	struct qdf_mac_addr peer_macaddr;
+	uint16_t reasonCode;
+	/* This flag tells LIM whether to send the disassoc OTA or not */
+	/* This will be set in while handing off from one AP to other */
+	uint8_t doNotSendOverTheAir;
+	bool process_ho_fail;
+} qdf_packed tSirSmeDisassocReq, *tpSirSmeDisassocReq;
+
+/* / Definition for Tkip countermeasures request */
+typedef struct sSirSmeTkipCntrMeasReq {
+	uint16_t messageType;   /* eWNI_SME_DISASSOC_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	struct qdf_mac_addr bssId; /* Peer BSSID */
+	bool bEnable;           /* Start/stop countermeasures */
+} qdf_packed tSirSmeTkipCntrMeasReq, *tpSirSmeTkipCntrMeasReq;
+
+typedef struct sAni64BitCounters {
+	uint32_t Hi;
+	uint32_t Lo;
+} tAni64BitCounters, *tpAni64BitCounters;
+
+typedef struct sAniSecurityStat {
+	tAni64BitCounters txBlks;
+	tAni64BitCounters rxBlks;
+	tAni64BitCounters formatErrorCnt;
+	tAni64BitCounters decryptErr;
+	tAni64BitCounters protExclCnt;
+	tAni64BitCounters unDecryptableCnt;
+	tAni64BitCounters decryptOkCnt;
+
+} tAniSecurityStat, *tpAniSecurityStat;
+
+typedef struct sAniTxRxStats {
+	tAni64BitCounters txFrames;
+	tAni64BitCounters rxFrames;
+	tAni64BitCounters nRcvBytes;
+	tAni64BitCounters nXmitBytes;
+
+} tAniTxRxStats, *tpAniTxRxStats;
+
+typedef struct sAniSecStats {
+	tAniSecurityStat aes;
+	tAni64BitCounters aesReplays;
+	tAniSecurityStat tkip;
+	tAni64BitCounters tkipReplays;
+	tAni64BitCounters tkipMicError;
+
+	tAniSecurityStat wep;
+#if defined(FEATURE_WLAN_WAPI) && !defined(LIBRA_WAPI_SUPPORT)
+	tAniSecurityStat wpi;
+	tAni64BitCounters wpiReplays;
+	tAni64BitCounters wpiMicError;
+#endif
+} tAniSecStats, *tpAniSecStats;
+
+#define SIR_MAX_RX_CHAINS 3
+
+typedef struct sAniStaStatStruct {
+	/* following statistic elements till expandPktRxCntLo are not filled
+	 * with valid data. These are kept as it is, since WSM is using this
+	 * structure. These elements can be removed whenever WSM is updated.
+	 * Phystats is used to hold phystats from BD.
+	 */
+	uint32_t sentAesBlksUcastHi;
+	uint32_t sentAesBlksUcastLo;
+	uint32_t recvAesBlksUcastHi;
+	uint32_t recvAesBlksUcastLo;
+	uint32_t aesFormatErrorUcastCnts;
+	uint32_t aesReplaysUcast;
+	uint32_t aesDecryptErrUcast;
+	uint32_t singleRetryPkts;
+	uint32_t failedTxPkts;
+	uint32_t ackTimeouts;
+	uint32_t multiRetryPkts;
+	uint32_t fragTxCntsHi;
+	uint32_t fragTxCntsLo;
+	uint32_t transmittedPktsHi;
+	uint32_t transmittedPktsLo;
+	uint32_t phyStatHi;     /* These are used to fill in the phystats. */
+	uint32_t phyStatLo;     /* This is only for private use. */
+
+	uint32_t uplinkRssi;
+	uint32_t uplinkSinr;
+	uint32_t uplinkRate;
+	uint32_t downlinkRssi;
+	uint32_t downlinkSinr;
+	uint32_t downlinkRate;
+	uint32_t nRcvBytes;
+	uint32_t nXmitBytes;
+
+	/*
+	 * Following elements are valid and filled in correctly. They have
+	 * valid values.
+	 */
+
+	/* Unicast frames and bytes. */
+	tAniTxRxStats ucStats;
+
+	/* Broadcast frames and bytes. */
+	tAniTxRxStats bcStats;
+
+	/* Multicast frames and bytes. */
+	tAniTxRxStats mcStats;
+
+	uint32_t currentTxRate;
+	uint32_t currentRxRate; /* Rate in 100Kbps */
+
+	uint32_t maxTxRate;
+	uint32_t maxRxRate;
+
+	int8_t rssi[SIR_MAX_RX_CHAINS];
+
+	tAniSecStats securityStats;
+
+	uint8_t currentRxRateIdx;       /* This the softmac rate Index. */
+	uint8_t currentTxRateIdx;
+
+} tAniStaStatStruct, *tpAniStaStatStruct;
+
+typedef enum sPacketType {
+	ePACKET_TYPE_UNKNOWN,
+	ePACKET_TYPE_11A,
+	ePACKET_TYPE_11G,
+	ePACKET_TYPE_11B,
+	ePACKET_TYPE_11N
+} tPacketType, *tpPacketType;
+
+/* / Definition for Disassociation response */
+typedef struct sSirSmeDisassocRsp {
+	uint16_t messageType;   /* eWNI_SME_DISASSOC_RSP */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	tSirResultCodes statusCode;
+	struct qdf_mac_addr peer_macaddr;
+	tAniStaStatStruct perStaStats;  /* STA stats */
+	uint16_t staId;
+} tSirSmeDisassocRsp, *tpSirSmeDisassocRsp;
+
+/* / Definition for Disassociation indication from peer */
+typedef struct sSirSmeDisassocInd {
+	uint16_t messageType;   /* eWNI_SME_DISASSOC_IND */
+	uint16_t length;
+	uint8_t sessionId;      /* Session Identifier */
+	uint16_t transactionId; /* Transaction Identifier with PE */
+	tSirResultCodes statusCode;
+	struct qdf_mac_addr bssid;
+	struct qdf_mac_addr peer_macaddr;
+	tAniStaStatStruct perStaStats;  /* STA stats */
+	uint16_t staId;
+	uint32_t reasonCode;
+} tSirSmeDisassocInd, *tpSirSmeDisassocInd;
+
+/* / Definition for Disassociation confirm */
+/* / MAC ---> */
+typedef struct sSirSmeDisassocCnf {
+	uint16_t messageType;   /* eWNI_SME_DISASSOC_CNF */
+	uint16_t length;
+	uint8_t sme_session_id;
+	tSirResultCodes statusCode;
+	struct qdf_mac_addr bssid;
+	struct qdf_mac_addr peer_macaddr;
+} tSirSmeDisassocCnf, *tpSirSmeDisassocCnf,
+	tSirSmeDeauthCnf, *tpSirSmeDeauthCnf;
+
+/**
+ * struct sir_sme_discon_done_ind  - disconnect done indiaction
+ * @message_type: msg type
+ * @length: length of msg
+ * @session_id: session id of the indication
+ * @reason_code: reason for disconnect indication
+ * @peer_mac: peer mac
+ */
+struct sir_sme_discon_done_ind {
+	uint16_t           message_type;
+	uint16_t           length;
+	uint8_t            session_id;
+	tSirResultCodes    reason_code;
+	tSirMacAddr        peer_mac;
+};
+
+
+/* / Definition for Deauthetication request */
+typedef struct sSirSmeDeauthReq {
+	uint16_t messageType;   /* eWNI_SME_DEAUTH_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	struct qdf_mac_addr bssid;      /* AP BSSID */
+	struct qdf_mac_addr peer_macaddr;
+	uint16_t reasonCode;
+} tSirSmeDeauthReq, *tpSirSmeDeauthReq;
+
+/* / Definition for Deauthetication response */
+typedef struct sSirSmeDeauthRsp {
+	uint16_t messageType;   /* eWNI_SME_DEAUTH_RSP */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	tSirResultCodes statusCode;
+	struct qdf_mac_addr peer_macaddr;
+} tSirSmeDeauthRsp, *tpSirSmeDeauthRsp;
+
+/* / Definition for Deauthetication indication from peer */
+typedef struct sSirSmeDeauthInd {
+	uint16_t messageType;   /* eWNI_SME_DEAUTH_IND */
+	uint16_t length;
+	uint8_t sessionId;      /* Added for BT-AMP */
+	uint16_t transactionId; /* Added for BT-AMP */
+	tSirResultCodes statusCode;
+	struct qdf_mac_addr bssid;      /* AP BSSID */
+	struct qdf_mac_addr peer_macaddr;
+
+	uint16_t staId;
+	uint32_t reasonCode;
+	int8_t rssi;
+} tSirSmeDeauthInd, *tpSirSmeDeauthInd;
+
+/* / Definition for stop BSS request message */
+typedef struct sSirSmeStopBssReq {
+	uint16_t messageType;   /* eWNI_SME_STOP_BSS_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* tranSaction ID for cmd */
+	tSirResultCodes reasonCode;
+	struct qdf_mac_addr bssid;      /* Self BSSID */
+} tSirSmeStopBssReq, *tpSirSmeStopBssReq;
+
+/* / Definition for stop BSS response message */
+typedef struct sSirSmeStopBssRsp {
+	uint16_t messageType;   /* eWNI_SME_STOP_BSS_RSP */
+	uint16_t length;
+	tSirResultCodes statusCode;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+} tSirSmeStopBssRsp, *tpSirSmeStopBssRsp;
+
+/* / Definition for Channel Switch indication for station */
+/* / MAC ---> */
+typedef struct sSirSmeSwitchChannelInd {
+	uint16_t messageType;   /* eWNI_SME_SWITCH_CHL_IND */
+	uint16_t length;
+	uint8_t sessionId;
+	uint16_t newChannelId;
+	struct ch_params chan_params;
+	struct qdf_mac_addr bssid;      /* BSSID */
+} tSirSmeSwitchChannelInd, *tpSirSmeSwitchChannelInd;
+
+/* / Definition for MIC failure indication */
+/* / MAC ---> */
+/* / MAC reports this each time a MIC failure occures on Rx TKIP packet */
+typedef struct sSirSmeMicFailureInd {
+	uint16_t messageType;   /* eWNI_SME_MIC_FAILURE_IND */
+	uint16_t length;
+	uint8_t sessionId;
+	struct qdf_mac_addr bssId;
+	tSirMicFailureInfo info;
+} tSirSmeMicFailureInd, *tpSirSmeMicFailureInd;
+
+typedef struct sSirSmeMissedBeaconInd {
+	uint16_t messageType;   /* eWNI_SME_MISSED_BEACON_IND */
+	uint16_t length;
+	uint8_t bssIdx;
+} tSirSmeMissedBeaconInd, *tpSirSmeMissedBeaconInd;
+
+/* / Definition for Set Context request */
+/* / ---> MAC */
+typedef struct sSirSmeSetContextReq {
+	uint16_t messageType;   /* eWNI_SME_SET_CONTEXT_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	struct qdf_mac_addr peer_macaddr;
+	struct qdf_mac_addr bssid;      /* BSSID */
+	tSirKeyMaterial keyMaterial;
+} tSirSmeSetContextReq, *tpSirSmeSetContextReq;
+
+/* / Definition for Set Context response */
+/* / MAC ---> */
+typedef struct sSirSmeSetContextRsp {
+	uint16_t messageType;   /* eWNI_SME_SET_CONTEXT_RSP */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	tSirResultCodes statusCode;
+	struct qdf_mac_addr peer_macaddr;
+} tSirSmeSetContextRsp, *tpSirSmeSetContextRsp;
+
+/* / Statistic definitions */
+/* ============================================================= */
+/* Per STA statistic structure; This same struct will be used for Aggregate */
+/* STA stats as well. */
+
+/* Clear radio stats and clear per sta stats */
+typedef enum {
+	eANI_CLEAR_ALL_STATS,   /* Clears all stats */
+	eANI_CLEAR_RX_STATS,    /* Clears RX stats of the radio interface */
+	eANI_CLEAR_TX_STATS,    /* Clears TX stats of the radio interface */
+	eANI_CLEAR_RADIO_STATS, /* Clears all the radio stats */
+	eANI_CLEAR_PER_STA_STATS,       /* Clears Per STA stats */
+	eANI_CLEAR_AGGR_PER_STA_STATS,  /* Clears aggregate stats */
+
+	/* Used to distinguish between per sta to security stats. */
+	/* Used only by AP, FW just returns the same param as it received. */
+	eANI_LINK_STATS,        /* Get Per STA stats */
+	eANI_SECURITY_STATS,    /* Get Per STA security stats */
+
+	eANI_CLEAR_STAT_TYPES_END
+} tAniStatSubTypes;
+
+typedef struct sAniTxCtrs {
+	/* add the rate counters here */
+	uint32_t tx1Mbps;
+	uint32_t tx2Mbps;
+	uint32_t tx5_5Mbps;
+	uint32_t tx6Mbps;
+	uint32_t tx9Mbps;
+	uint32_t tx11Mbps;
+	uint32_t tx12Mbps;
+	uint32_t tx18Mbps;
+	uint32_t tx24Mbps;
+	uint32_t tx36Mbps;
+	uint32_t tx48Mbps;
+	uint32_t tx54Mbps;
+	uint32_t tx72Mbps;
+	uint32_t tx96Mbps;
+	uint32_t tx108Mbps;
+
+	/* tx path radio counts */
+	uint32_t txFragHi;
+	uint32_t txFragLo;
+	uint32_t txFrameHi;
+	uint32_t txFrameLo;
+	uint32_t txMulticastFrameHi;
+	uint32_t txMulticastFrameLo;
+	uint32_t txFailedHi;
+	uint32_t txFailedLo;
+	uint32_t multipleRetryHi;
+	uint32_t multipleRetryLo;
+	uint32_t singleRetryHi;
+	uint32_t singleRetryLo;
+	uint32_t ackFailureHi;
+	uint32_t ackFailureLo;
+	uint32_t xmitBeacons;
+} tAniTxCtrs, *tpAniTxCtrs;
+
+typedef struct sAniRxCtrs {
+	/* receive frame rate counters */
+	uint32_t rx1Mbps;
+	uint32_t rx2Mbps;
+	uint32_t rx5_5Mbps;
+	uint32_t rx6Mbps;
+	uint32_t rx9Mbps;
+	uint32_t rx11Mbps;
+	uint32_t rx12Mbps;
+	uint32_t rx18Mbps;
+	uint32_t rx24Mbps;
+	uint32_t rx36Mbps;
+	uint32_t rx48Mbps;
+	uint32_t rx54Mbps;
+	uint32_t rx72Mbps;
+	uint32_t rx96Mbps;
+	uint32_t rx108Mbps;
+
+	/* receive size counters; 'Lte' = Less than or equal to */
+	uint32_t rxLte64;
+	uint32_t rxLte128Gt64;
+	uint32_t rxLte256Gt128;
+	uint32_t rxLte512Gt256;
+	uint32_t rxLte1kGt512;
+	uint32_t rxLte1518Gt1k;
+	uint32_t rxLte2kGt1518;
+	uint32_t rxLte4kGt2k;
+
+	/* rx radio stats */
+	uint32_t rxFrag;
+	uint32_t rxFrame;
+	uint32_t fcsError;
+	uint32_t rxMulticast;
+	uint32_t duplicate;
+	uint32_t rtsSuccess;
+	uint32_t rtsFailed;
+	uint32_t wepUndecryptables;
+	uint32_t drops;
+	uint32_t aesFormatErrorUcastCnts;
+	uint32_t aesReplaysUcast;
+	uint32_t aesDecryptErrUcast;
+} tAniRxCtrs, *tpAniRxCtrs;
+
+/* *************************************************************** */
+
+/*******************PE Statistics*************************/
+
+/*
+ * tpAniGetPEStatsReq is tied to
+ * for SME ==> PE eWNI_SME_GET_STATISTICS_REQ msgId  and
+ * for PE ==> HAL SIR_HAL_GET_STATISTICS_REQ msgId
+ */
+typedef struct sAniGetPEStatsReq {
+	/* Common for all types are requests */
+	uint16_t msgType;       /* message type is same as the request type */
+	uint16_t msgLen;        /* length of the entire request */
+	uint32_t staId;         /* Per STA stats request must contain valid */
+	/* categories of stats requested. look at ePEStatsMask */
+	uint32_t statsMask;
+	uint8_t sessionId;
+} tAniGetPEStatsReq, *tpAniGetPEStatsReq;
+
+/*
+ * tpAniGetPEStatsRsp is tied to
+ * for PE ==> SME eWNI_SME_GET_STATISTICS_RSP msgId  and
+ * for HAL ==> PE SIR_HAL_GET_STATISTICS_RSP msgId
+ */
+typedef struct sAniGetPEStatsRsp {
+	/* Common for all types are responses */
+	uint16_t msgType;       /* message type is same as the request type */
+	/* length of the entire request, includes the pStatsBuf length too */
+	uint16_t msgLen;
+	uint8_t sessionId;
+	uint32_t rc;            /* success/failure */
+	uint32_t staId;         /* Per STA stats request must contain valid */
+	/* categories of stats requested. look at ePEStatsMask */
+	uint32_t statsMask;
+	/* void                  *pStatsBuf; */
+	/*
+	 * The Stats buffer starts here and can be an aggregate of more than one
+	 * statistics structure depending on statsMask. The void pointer
+	 * "pStatsBuf" is commented out intentionally and the src code that uses
+	 * this structure should take that into account.
+	 */
+} tAniGetPEStatsRsp, *tpAniGetPEStatsRsp;
+
+typedef struct sAniGetRssiReq {
+	/* Common for all types are requests */
+	uint16_t msgType;       /* message type is same as the request type */
+	uint16_t msgLen;        /* length of the entire request */
+	uint8_t sessionId;
+	uint8_t staId;
+	int8_t lastRSSI;        /* in case of error, return last RSSI */
+	void *rssiCallback;
+	void *pDevContext;      /* device context */
+} tAniGetRssiReq, *tpAniGetRssiReq;
+
+typedef struct sAniGetSnrReq {
+	/* Common for all types are requests */
+	uint16_t msgType;       /* message type is same as the request type */
+	uint16_t msgLen;        /* length of the entire request */
+	uint8_t sessionId;
+	uint8_t staId;
+	void *snrCallback;
+	void *pDevContext;      /* device context */
+	int8_t snr;
+} tAniGetSnrReq, *tpAniGetSnrReq;
+
+/**
+ * struct ani_roc_req - Remain on channel request
+ * @msg_type: Message type
+ * @msg_len: Message Length
+ * @session_id: SME session Id
+ * @channel: channel number
+ * @callback: call back function for scan result
+ * @duration: Roc duration
+ * @is_p2pprobe_allowed : flag for p2p probe request
+ * @ctx: Global context
+ * @scan_id: Scan Identifier
+ *
+ * Remain on channel request message structure
+ */
+struct ani_roc_req {
+	/* message type is same as the request type */
+	uint16_t msg_type;
+	/* length of the entire request */
+	uint16_t msg_len;
+	uint16_t session_id;
+	uint8_t channel;
+	uint32_t duration;
+	uint8_t is_p2pprobe_allowed;
+	void *callback;
+	void *ctx;
+	uint32_t scan_id;
+};
+
+/* generic country code change request MSG structure */
+typedef struct sAniGenericChangeCountryCodeReq {
+	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 */
+} tAniGenericChangeCountryCodeReq, *tpAniGenericChangeCountryCodeReq;
+
+/**
+ * struct sAniDHCPStopInd - DHCP Stop indication message
+ * @msgType: message type is same as the request type
+ * @msgLen: length of the entire request
+ * @device_mode: Mode of the device(ex:STA, AP)
+ * @adapterMacAddr: MAC address of the adapter
+ * @peerMacAddr: MAC address of the connected peer
+ */
+typedef struct sAniDHCPStopInd {
+	uint16_t msgType;
+	uint16_t msgLen;
+	uint8_t device_mode;
+	struct qdf_mac_addr adapterMacAddr;
+	struct qdf_mac_addr peerMacAddr;
+} tAniDHCPInd, *tpAniDHCPInd;
+
+typedef struct sAniTXFailMonitorInd {
+	uint16_t msgType;       /* message type is same as the request type */
+	uint16_t msgLen;        /* length of the entire request */
+	uint8_t tx_fail_count;
+	void *txFailIndCallback;
+} tAniTXFailMonitorInd, *tpAniTXFailMonitorInd;
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * enum tx_rate_info - tx_rate flags
+ * @TX_RATE_LEGACY: Legacy rates
+ * @TX_RATE_HT20: HT20 rates
+ * @TX_RATE_HT40: HT40 rates
+ * @TX_RATE_SGI: Rate with Short guard interval
+ * @TX_RATE_LGI: Rate with Long guard interval
+ * @TX_RATE_VHT20: VHT 20 rates
+ * @TX_RATE_VHT40: VHT 40 rates
+ * @TX_RATE_VHT80: VHT 80 rates
+ */
+enum tx_rate_info {
+	TX_RATE_LEGACY = 0x1,
+	TX_RATE_HT20 = 0x2,
+	TX_RATE_HT40 = 0x4,
+	TX_RATE_SGI = 0x8,
+	TX_RATE_LGI = 0x10,
+	TX_RATE_VHT20 = 0x20,
+	TX_RATE_VHT40 = 0x40,
+	TX_RATE_VHT80 = 0x80
+};
+#endif
+/**********************PE Statistics end*************************/
+
+typedef struct sSirP2PNoaStart {
+	uint32_t status;
+	uint32_t bssIdx;
+} tSirP2PNoaStart, *tpSirP2PNoaStart;
+
+typedef struct sSirTdlsInd {
+	uint16_t status;
+	uint16_t assocId;
+	uint16_t staIdx;
+	uint16_t reasonCode;
+} tSirTdlsInd, *tpSirTdlsInd;
+
+typedef struct sSirP2PNoaAttr {
+#ifdef ANI_BIG_BYTE_ENDIAN
+	uint32_t index:8;
+	uint32_t oppPsFlag:1;
+	uint32_t ctWin:7;
+	uint32_t rsvd1:16;
+#else
+	uint32_t rsvd1:16;
+	uint32_t ctWin:7;
+	uint32_t oppPsFlag:1;
+	uint32_t index:8;
+#endif
+
+#ifdef ANI_BIG_BYTE_ENDIAN
+	uint32_t uNoa1IntervalCnt:8;
+	uint32_t rsvd2:24;
+#else
+	uint32_t rsvd2:24;
+	uint32_t uNoa1IntervalCnt:8;
+#endif
+	uint32_t uNoa1Duration;
+	uint32_t uNoa1Interval;
+	uint32_t uNoa1StartTime;
+
+#ifdef ANI_BIG_BYTE_ENDIAN
+	uint32_t uNoa2IntervalCnt:8;
+	uint32_t rsvd3:24;
+#else
+	uint32_t rsvd3:24;
+	uint32_t uNoa2IntervalCnt:8;
+#endif
+	uint32_t uNoa2Duration;
+	uint32_t uNoa2Interval;
+	uint32_t uNoa2StartTime;
+} tSirP2PNoaAttr, *tpSirP2PNoaAttr;
+
+typedef struct sSirTclasInfo {
+	tSirMacTclasIE tclas;
+	uint8_t version;        /* applies only for classifier type ip */
+	union {
+		tSirMacTclasParamEthernet eth;
+		tSirMacTclasParamIPv4 ipv4;
+		tSirMacTclasParamIPv6 ipv6;
+		tSirMacTclasParam8021dq t8021dq;
+	} qdf_packed tclasParams;
+} qdf_packed tSirTclasInfo;
+
+typedef struct sSirAddtsReqInfo {
+	uint8_t dialogToken;
+	tSirMacTspecIE tspec;
+
+	uint8_t numTclas;       /* number of Tclas elements */
+	tSirTclasInfo tclasInfo[SIR_MAC_TCLASIE_MAXNUM];
+	uint8_t tclasProc;
+#if defined(FEATURE_WLAN_ESE)
+	tSirMacESETSRSIE tsrsIE;
+	uint8_t tsrsPresent:1;
+#endif
+	uint8_t wmeTspecPresent:1;
+	uint8_t wsmTspecPresent:1;
+	uint8_t lleTspecPresent:1;
+	uint8_t tclasProcPresent:1;
+} tSirAddtsReqInfo, *tpSirAddtsReqInfo;
+
+typedef struct sSirAddtsRspInfo {
+	uint8_t dialogToken;
+	tSirMacStatusCodes status;
+	tSirMacTsDelayIE delay;
+
+	tSirMacTspecIE tspec;
+	uint8_t numTclas;       /* number of Tclas elements */
+	tSirTclasInfo tclasInfo[SIR_MAC_TCLASIE_MAXNUM];
+	uint8_t tclasProc;
+	tSirMacScheduleIE schedule;
+#ifdef FEATURE_WLAN_ESE
+	tSirMacESETSMIE tsmIE;
+	uint8_t tsmPresent:1;
+#endif
+	uint8_t wmeTspecPresent:1;
+	uint8_t wsmTspecPresent:1;
+	uint8_t lleTspecPresent:1;
+	uint8_t tclasProcPresent:1;
+	uint8_t schedulePresent:1;
+} tSirAddtsRspInfo, *tpSirAddtsRspInfo;
+
+typedef struct sSirDeltsReqInfo {
+	tSirMacTSInfo tsinfo;
+	tSirMacTspecIE tspec;
+	uint8_t wmeTspecPresent:1;
+	uint8_t wsmTspecPresent:1;
+	uint8_t lleTspecPresent:1;
+} tSirDeltsReqInfo, *tpSirDeltsReqInfo;
+
+/* / Add a tspec as defined */
+typedef struct sSirAddtsReq {
+	uint16_t messageType;   /* eWNI_SME_ADDTS_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId;
+	struct qdf_mac_addr bssid;      /* BSSID */
+	uint32_t timeout;       /* in ms */
+	uint8_t rspReqd;
+	tSirAddtsReqInfo req;
+} tSirAddtsReq, *tpSirAddtsReq;
+
+typedef struct sSirAddtsRsp {
+	uint16_t messageType;   /* eWNI_SME_ADDTS_RSP */
+	uint16_t length;
+	uint8_t sessionId;      /* sme sessionId  Added for BT-AMP support */
+	uint16_t transactionId; /* sme transaction Id - for BT-AMP Support */
+	uint32_t rc;            /* return code */
+	tSirAddtsRspInfo rsp;
+} tSirAddtsRsp, *tpSirAddtsRsp;
+
+typedef struct sSirDeltsReq {
+	uint16_t messageType;   /* eWNI_SME_DELTS_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId;
+	struct qdf_mac_addr bssid;      /* BSSID */
+	uint16_t aid;           /* use 0 if macAddr is being specified */
+	struct qdf_mac_addr macaddr;    /* only on AP to specify the STA */
+	uint8_t rspReqd;
+	tSirDeltsReqInfo req;
+} tSirDeltsReq, *tpSirDeltsReq;
+
+typedef struct sSirDeltsRsp {
+	uint16_t messageType;   /* eWNI_SME_DELTS_RSP */
+	uint16_t length;
+	uint8_t sessionId;      /* sme sessionId  Added for BT-AMP support */
+	uint16_t transactionId; /* sme transaction Id - for BT-AMP Support */
+	uint32_t rc;
+	uint16_t aid;           /* use 0 if macAddr is being specified */
+	struct qdf_mac_addr macaddr;    /* only on AP to specify the STA */
+	tSirDeltsReqInfo rsp;
+} tSirDeltsRsp, *tpSirDeltsRsp;
+
+#define SIR_QOS_NUM_AC_MAX 4
+
+typedef struct sSirAggrQosReqInfo {
+	uint16_t tspecIdx;
+	tSirAddtsReqInfo aggrAddTsInfo[SIR_QOS_NUM_AC_MAX];
+} tSirAggrQosReqInfo, *tpSirAggrQosReqInfo;
+
+typedef struct sSirAggrQosReq {
+	uint16_t messageType;   /* eWNI_SME_ADDTS_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId;
+	struct qdf_mac_addr bssid;      /* BSSID */
+	uint32_t timeout;       /* in ms */
+	uint8_t rspReqd;
+	tSirAggrQosReqInfo aggrInfo;
+} tSirAggrQosReq, *tpSirAggrQosReq;
+
+typedef struct sSirAggrQosRspInfo {
+	uint16_t tspecIdx;
+	tSirAddtsRspInfo aggrRsp[SIR_QOS_NUM_AC_MAX];
+} tSirAggrQosRspInfo, *tpSirAggrQosRspInfo;
+
+typedef struct sSirAggrQosRsp {
+	uint16_t messageType;
+	uint16_t length;
+	uint8_t sessionId;
+	tSirAggrQosRspInfo aggrInfo;
+} tSirAggrQosRsp, *tpSirAggrQosRsp;
+
+
+typedef struct sSirQosMapSet {
+	uint8_t present;
+	uint8_t num_dscp_exceptions;
+	uint8_t dscp_exceptions[21][2];
+	uint8_t dscp_range[8][2];
+} tSirQosMapSet, *tpSirQosMapSet;
+
+typedef struct sSmeIbssPeerInd {
+	uint16_t mesgType;
+	uint16_t mesgLen;
+	uint8_t sessionId;
+
+	struct qdf_mac_addr peer_addr;
+	uint16_t staId;
+
+	/* Beacon will be appended for new Peer indication. */
+} tSmeIbssPeerInd, *tpSmeIbssPeerInd;
+
+typedef struct sSirIbssPeerInactivityInd {
+	uint8_t bssIdx;
+	uint8_t staIdx;
+	struct qdf_mac_addr peer_addr;
+} tSirIbssPeerInactivityInd, *tpSirIbssPeerInactivityInd;
+
+typedef struct sLimScanChn {
+	uint16_t numTimeScan;   /* how many time this channel is scan */
+	uint8_t channelId;
+} tLimScanChn;
+
+/**
+ * struct lim_channel_status
+ * @channelfreq: Channel freq
+ * @noise_floor: Noise Floor value
+ * @rx_clear_count: rx clear count
+ * @cycle_count: cycle count
+ * @chan_tx_pwr_range: channel tx power per range in 0.5dBm steps
+ * @chan_tx_pwr_throughput: channel tx power per throughput
+ * @rx_frame_count: rx frame count (cumulative)
+ * @bss_rx_cycle_count: BSS rx cycle count
+ * @rx_11b_mode_data_duration: b-mode data rx time (units are microseconds)
+ * @tx_frame_count: BSS tx cycle count
+ * @mac_clk_mhz: sample frequency
+ * @channel_id: channel index
+ * @cmd_flags: indicate which stat event is this status coming from
+ */
+struct lim_channel_status {
+	uint32_t    channelfreq;
+	uint32_t    noise_floor;
+	uint32_t    rx_clear_count;
+	uint32_t    cycle_count;
+	uint32_t    chan_tx_pwr_range;
+	uint32_t    chan_tx_pwr_throughput;
+	uint32_t    rx_frame_count;
+	uint32_t    bss_rx_cycle_count;
+	uint32_t    rx_11b_mode_data_duration;
+	uint32_t    tx_frame_count;
+	uint32_t    mac_clk_mhz;
+	uint32_t    channel_id;
+	uint32_t    cmd_flags;
+};
+
+/**
+ * struct lim_scan_channel_status
+ * @total_channel: total number of be scanned channel
+ * @channel_status_list: channel status info store in this array
+ */
+struct lim_scan_channel_status {
+	uint8_t total_channel;
+	struct lim_channel_status
+		 channel_status_list[SIR_MAX_SUPPORTED_CHANNEL_LIST];
+};
+
+typedef struct sSmeGetScanChnRsp {
+	/* Message Type */
+	uint16_t mesgType;
+	/* Message Length */
+	uint16_t mesgLen;
+	uint8_t sessionId;
+	uint8_t numChn;
+	tLimScanChn scanChn[1];
+} tSmeGetScanChnRsp, *tpSmeGetScanChnRsp;
+
+typedef struct sSirSmeGetAssocSTAsReq {
+	uint16_t messageType;   /* eWNI_SME_GET_ASSOC_STAS_REQ */
+	uint16_t length;
+	struct qdf_mac_addr bssid;      /* BSSID */
+	uint16_t modId;
+	void *pUsrContext;
+	void *pSapEventCallback;
+	/* Pointer to allocated mem passed in wlansap_get_assoc_stations API */
+	void *pAssocStasArray;
+} tSirSmeGetAssocSTAsReq, *tpSirSmeGetAssocSTAsReq;
+
+typedef struct sSmeMaxAssocInd {
+	uint16_t mesgType;      /* eWNI_SME_MAX_ASSOC_EXCEEDED */
+	uint16_t mesgLen;
+	uint8_t sessionId;
+	/* the new peer that got rejected max assoc limit reached */
+	struct qdf_mac_addr peer_mac;
+} tSmeMaxAssocInd, *tpSmeMaxAssocInd;
+
+typedef struct sSmeCsaOffloadInd {
+	uint16_t mesgType;      /* eWNI_SME_CSA_OFFLOAD_EVENT */
+	uint16_t mesgLen;
+	struct qdf_mac_addr bssid;      /* BSSID */
+} tSmeCsaOffloadInd, *tpSmeCsaOffloadInd;
+
+#define SIR_MAX_NAME_SIZE 64
+#define SIR_MAX_TEXT_SIZE 32
+
+typedef struct sSirName {
+	uint8_t num_name;
+	uint8_t name[SIR_MAX_NAME_SIZE];
+} tSirName;
+
+typedef struct sSirText {
+	uint8_t num_text;
+	uint8_t text[SIR_MAX_TEXT_SIZE];
+} tSirText;
+
+#define SIR_WPS_PROBRSP_VER_PRESENT    0x00000001
+#define SIR_WPS_PROBRSP_STATE_PRESENT    0x00000002
+#define SIR_WPS_PROBRSP_APSETUPLOCK_PRESENT    0x00000004
+#define SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT    0x00000008
+#define SIR_WPS_PROBRSP_DEVICEPASSWORDID_PRESENT    0x00000010
+#define SIR_WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT    0x00000020
+#define SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT    0x00000040
+#define SIR_WPS_PROBRSP_UUIDE_PRESENT    0x00000080
+#define SIR_WPS_PROBRSP_MANUFACTURE_PRESENT    0x00000100
+#define SIR_WPS_PROBRSP_MODELNAME_PRESENT    0x00000200
+#define SIR_WPS_PROBRSP_MODELNUMBER_PRESENT    0x00000400
+#define SIR_WPS_PROBRSP_SERIALNUMBER_PRESENT    0x00000800
+#define SIR_WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT    0x00001000
+#define SIR_WPS_PROBRSP_DEVICENAME_PRESENT    0x00002000
+#define SIR_WPS_PROBRSP_CONFIGMETHODS_PRESENT    0x00004000
+#define SIR_WPS_PROBRSP_RF_BANDS_PRESENT    0x00008000
+
+typedef struct sSirWPSProbeRspIE {
+	uint32_t FieldPresent;
+	uint32_t Version;       /* Version. 0x10 = version 1.0, 0x11 = etc. */
+	uint32_t wpsState;      /* 1 = unconfigured, 2 = configured. */
+	bool APSetupLocked;     /* Must be included if value is true */
+	/*
+	 * BOOL:  indicates if the user has recently activated a Registrar to
+	 * add an Enrollee.
+	 */
+	bool SelectedRegistra;
+	uint16_t DevicePasswordID;      /* Device Password ID */
+	/* Selected Registrar config method */
+	uint16_t SelectedRegistraCfgMethod;
+	uint8_t ResponseType;   /* Response type */
+	uint8_t UUID_E[16];     /* Unique identifier of the AP. */
+	tSirName Manufacture;
+	tSirText ModelName;
+	tSirText ModelNumber;
+	tSirText SerialNumber;
+	/* Device Category ID: 1Computer, 2Input Device, ... */
+	uint32_t PrimaryDeviceCategory;
+	/* Vendor specific OUI for Device Sub Category */
+	uint8_t PrimaryDeviceOUI[4];
+	/*
+	   Device Sub Category ID: 1-PC, 2-Server if Device Category ID
+	 * is computer
+	 */
+	uint32_t DeviceSubCategory;
+	tSirText DeviceName;
+	uint16_t ConfigMethod;  /* Configuaration method */
+	uint8_t RFBand;         /* RF bands available on the AP */
+} tSirWPSProbeRspIE;
+
+#define SIR_WPS_BEACON_VER_PRESENT    0x00000001
+#define SIR_WPS_BEACON_STATE_PRESENT    0x00000002
+#define SIR_WPS_BEACON_APSETUPLOCK_PRESENT    0x00000004
+#define SIR_WPS_BEACON_SELECTEDREGISTRA_PRESENT    0x00000008
+#define SIR_WPS_BEACON_DEVICEPASSWORDID_PRESENT    0x00000010
+#define SIR_WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT    0x00000020
+#define SIR_WPS_BEACON_UUIDE_PRESENT    0x00000080
+#define SIR_WPS_BEACON_RF_BANDS_PRESENT    0x00000100
+#define SIR_WPS_UUID_LEN 16
+
+typedef struct sSirWPSBeaconIE {
+	uint32_t FieldPresent;
+	uint32_t Version;       /* Version. 0x10 = version 1.0, 0x11 = etc. */
+	uint32_t wpsState;      /* 1 = unconfigured, 2 = configured. */
+	bool APSetupLocked;     /* Must be included if value is true */
+	/*
+	 * BOOL:  indicates if the user has recently activated a Registrar to
+	 * add an Enrollee.
+	 */
+	bool SelectedRegistra;
+	uint16_t DevicePasswordID;      /* Device Password ID */
+	/* Selected Registrar config method */
+	uint16_t SelectedRegistraCfgMethod;
+	uint8_t UUID_E[SIR_WPS_UUID_LEN];     /* Unique identifier of the AP. */
+	uint8_t RFBand;         /* RF bands available on the AP */
+} tSirWPSBeaconIE;
+
+#define SIR_WPS_ASSOCRSP_VER_PRESENT    0x00000001
+#define SIR_WPS_ASSOCRSP_RESPONSETYPE_PRESENT    0x00000002
+
+typedef struct sSirWPSAssocRspIE {
+	uint32_t FieldPresent;
+	uint32_t Version;
+	uint8_t ResposeType;
+} tSirWPSAssocRspIE;
+
+typedef struct sSirAPWPSIEs {
+	tSirWPSProbeRspIE SirWPSProbeRspIE;     /*WPS Set Probe Respose IE */
+	tSirWPSBeaconIE SirWPSBeaconIE; /*WPS Set Beacon IE */
+	tSirWPSAssocRspIE SirWPSAssocRspIE;     /*WPS Set Assoc Response IE */
+} tSirAPWPSIEs, *tpSiriAPWPSIEs;
+
+typedef struct sSirUpdateAPWPSIEsReq {
+	uint16_t messageType;   /* eWNI_SME_UPDATE_APWPSIE_REQ */
+	uint16_t length;
+	uint16_t transactionId; /* Transaction ID for cmd */
+	struct qdf_mac_addr bssid;      /* BSSID */
+	uint8_t sessionId;      /* Session ID */
+	tSirAPWPSIEs APWPSIEs;
+} tSirUpdateAPWPSIEsReq, *tpSirUpdateAPWPSIEsReq;
+
+struct update_config {
+	uint16_t messageType;   /* eWNI_SME_UPDATE_CONFIG */
+	uint16_t length;
+	uint8_t sme_session_id;
+	uint16_t capab;
+	uint32_t value;
+};
+
+/*
+ * enum sir_update_session_param_type - session param type
+ * @SIR_PARAM_SSID_HIDDEN: ssidHidden parameter
+ * @SIR_PARAM_IGNORE_ASSOC_DISALLOWED: ignore_assoc_disallowed parameter
+ */
+enum sir_update_session_param_type {
+	SIR_PARAM_SSID_HIDDEN,
+	SIR_PARAM_IGNORE_ASSOC_DISALLOWED,
+};
+
+/*
+ * struct sir_update_session_param
+ * @message_type: SME message type
+ * @length: size of struct sir_update_session_param
+ * @session_id: Session ID
+ * @param_type: parameter to be updated
+ * @param_val: Parameter value to update
+ */
+struct sir_update_session_param {
+	uint16_t message_type;
+	uint16_t length;
+	uint8_t session_id;
+	uint32_t param_type;
+	uint32_t param_val;
+};
+
+/**
+ * struct sir_set_he_bss_color
+ * @message_type: SME message type
+ * @length: size of struct sir_set_he_bss_color
+ * @session_id: Session ID
+ * @bss_color: bss color value
+ */
+struct sir_set_he_bss_color {
+	uint16_t message_type;
+	uint16_t length;
+	uint8_t session_id;
+	uint8_t bss_color;
+};
+
+/**
+ * struct sir_create_session - Used for creating session in monitor mode
+ * @type: SME host message type.
+ * @msg_len: Length of the message.
+ * @bss_id: bss_id for creating the session.
+ */
+struct sir_create_session {
+	uint16_t type;
+	uint16_t msg_len;
+	uint8_t vdev_id;
+	struct qdf_mac_addr bss_id;
+};
+
+/* Beacon Interval */
+typedef struct sSirChangeBIParams {
+	uint16_t messageType;
+	uint16_t length;
+	uint16_t beaconInterval;        /* Beacon Interval */
+	struct qdf_mac_addr bssid;
+	uint8_t sessionId;      /* Session ID */
+} tSirChangeBIParams, *tpSirChangeBIParams;
+
+#ifdef QCA_HT_2040_COEX
+typedef struct sSirSetHT2040Mode {
+	uint16_t messageType;
+	uint16_t length;
+	uint8_t cbMode;
+	bool obssEnabled;
+	struct qdf_mac_addr bssid;
+	uint8_t sessionId;      /* Session ID */
+} tSirSetHT2040Mode, *tpSirSetHT2040Mode;
+#endif
+
+#define SIR_WPS_PBC_WALK_TIME   120     /* 120 Second */
+
+typedef struct sSirWPSPBCSession {
+	struct sSirWPSPBCSession *next;
+	struct qdf_mac_addr addr;
+	uint8_t uuid_e[SIR_WPS_UUID_LEN];
+	uint32_t timestamp;
+} tSirWPSPBCSession;
+
+typedef struct sSirSmeGetWPSPBCSessionsReq {
+	uint16_t messageType;   /* eWNI_SME_GET_WPSPBC_SESSION_REQ */
+	uint16_t length;
+	void *pUsrContext;
+	void *pSapEventCallback;
+	struct qdf_mac_addr bssid;      /* BSSID */
+	/* MAC Address of STA in WPS Session to be removed */
+	struct qdf_mac_addr remove_mac;
+} tSirSmeGetWPSPBCSessionsReq, *tpSirSmeGetWPSPBCSessionsReq;
+
+typedef struct sSirWPSPBCProbeReq {
+	struct qdf_mac_addr peer_macaddr;
+	uint16_t probeReqIELen;
+	uint8_t probeReqIE[512];
+} tSirWPSPBCProbeReq, *tpSirWPSPBCProbeReq;
+
+/* probereq from peer, when wsc is enabled */
+typedef struct sSirSmeProbeReqInd {
+	uint16_t messageType;   /*  eWNI_SME_WPS_PBC_PROBE_REQ_IND */
+	uint16_t length;
+	uint8_t sessionId;
+	struct qdf_mac_addr bssid;
+	tSirWPSPBCProbeReq WPSPBCProbeReq;
+} tSirSmeProbeReqInd, *tpSirSmeProbeReqInd;
+
+typedef struct sSirUpdateAPWPARSNIEsReq {
+	uint16_t messageType;   /* eWNI_SME_SET_APWPARSNIEs_REQ */
+	uint16_t length;
+	uint16_t transactionId; /* Transaction ID for cmd */
+	struct qdf_mac_addr bssid;      /* BSSID */
+	uint8_t sessionId;      /* Session ID */
+	tSirRSNie APWPARSNIEs;
+} tSirUpdateAPWPARSNIEsReq, *tpSirUpdateAPWPARSNIEsReq;
+
+#define SIR_ROAM_MAX_CHANNELS            80
+#define SIR_ROAM_SCAN_MAX_PB_REQ_SIZE    450
+/* Occupied channel list remains static */
+#define CHANNEL_LIST_STATIC                   1
+/* Occupied channel list can be dynamic */
+#define CHANNEL_LIST_DYNAMIC                  2
+#define SIR_ROAM_SCAN_24G_DEFAULT_CH     1
+#define SIR_ROAM_SCAN_5G_DEFAULT_CH      36
+#define SIR_ROAM_SCAN_RESERVED_BYTES     61
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+#define SIR_ROAM_SCAN_PSK_SIZE    32
+#define SIR_ROAM_R0KH_ID_MAX_LEN  48
+#endif
+/* SME -> HAL - This is the host offload request. */
+#define SIR_IPV4_ARP_REPLY_OFFLOAD                  0
+#define SIR_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD         1
+#define SIR_IPV6_NS_OFFLOAD                         2
+#define SIR_OFFLOAD_DISABLE                         0
+#define SIR_OFFLOAD_ENABLE                          1
+
+#ifdef WLAN_NS_OFFLOAD
+typedef struct sSirNsOffloadReq {
+	uint8_t srcIPv6Addr[SIR_MAC_IPV6_ADDR_LEN];
+	uint8_t selfIPv6Addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA][SIR_MAC_IPV6_ADDR_LEN];
+	uint8_t targetIPv6Addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA][SIR_MAC_IPV6_ADDR_LEN];
+	struct qdf_mac_addr self_macaddr;
+	uint8_t srcIPv6AddrValid;
+	uint8_t targetIPv6AddrValid[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA];
+	uint8_t target_ipv6_addr_ac_type[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA];
+	uint8_t slotIdx;
+} tSirNsOffloadReq, *tpSirNsOffloadReq;
+#endif /* WLAN_NS_OFFLOAD */
+
+typedef struct sSirHostOffloadReq {
+	uint8_t offloadType;
+	uint8_t enableOrDisable;
+	uint32_t num_ns_offload_count;
+	union {
+		uint8_t hostIpv4Addr[SIR_IPV4_ADDR_LEN];
+		uint8_t hostIpv6Addr[SIR_MAC_IPV6_ADDR_LEN];
+	} params;
+#ifdef WLAN_NS_OFFLOAD
+	tSirNsOffloadReq nsOffloadInfo;
+#endif /* WLAN_NS_OFFLOAD */
+	struct qdf_mac_addr bssid;
+} tSirHostOffloadReq, *tpSirHostOffloadReq;
+
+/* Packet Types. */
+#define SIR_KEEP_ALIVE_NULL_PKT              1
+#define SIR_KEEP_ALIVE_UNSOLICIT_ARP_RSP     2
+
+/* Keep Alive request. */
+typedef struct sSirKeepAliveReq {
+	uint8_t packetType;
+	uint32_t timePeriod;
+	tSirIpv4Addr hostIpv4Addr;
+	tSirIpv4Addr destIpv4Addr;
+	struct qdf_mac_addr dest_macaddr;
+	struct qdf_mac_addr bssid;
+	uint8_t sessionId;
+} tSirKeepAliveReq, *tpSirKeepAliveReq;
+
+typedef struct sSirSmeMgmtFrameInd {
+	uint16_t frame_len;
+	uint32_t rxChan;
+	uint8_t sessionId;
+	uint8_t frameType;
+	int8_t rxRssi;
+	uint8_t frameBuf[1];    /* variable */
+} tSirSmeMgmtFrameInd, *tpSirSmeMgmtFrameInd;
+
+typedef void (*sir_mgmt_frame_ind_callback)(tSirSmeMgmtFrameInd *frame_ind);
+/**
+ * struct sir_sme_mgmt_frame_cb_req - Register a
+ * management frame callback req
+ *
+ * @message_type: message id
+ * @length: msg length
+ * @callback: callback for management frame indication
+ */
+struct sir_sme_mgmt_frame_cb_req {
+	uint16_t message_type;
+	uint16_t length;
+	sir_mgmt_frame_ind_callback callback;
+};
+
+#ifdef WLAN_FEATURE_11W
+typedef struct sSirSmeUnprotMgmtFrameInd {
+	uint8_t sessionId;
+	uint8_t frameType;
+	uint8_t frameLen;
+	uint8_t frameBuf[1];    /* variable */
+} tSirSmeUnprotMgmtFrameInd, *tpSirSmeUnprotMgmtFrameInd;
+#endif
+
+#define SIR_IS_FULL_POWER_REASON_DISCONNECTED(eReason) \
+	((eSME_LINK_DISCONNECTED_BY_HDD == (eReason)) || \
+	 (eSME_LINK_DISCONNECTED_BY_OTHER == (eReason)))
+#define SIR_IS_FULL_POWER_NEEDED_BY_HDD(eReason) \
+	((eSME_LINK_DISCONNECTED_BY_HDD == (eReason)) || \
+	 (eSME_FULL_PWR_NEEDED_BY_HDD == (eReason)))
+
+/* P2P Power Save Related */
+typedef struct sSirNoAParam {
+	uint8_t ctWindow:7;
+	uint8_t OppPS:1;
+	uint8_t count;
+	uint32_t duration;
+	uint32_t interval;
+	uint32_t singleNoADuration;
+	uint8_t psSelection;
+} tSirNoAParam, *tpSirNoAParam;
+
+typedef struct sSirWlanResumeParam {
+	uint8_t configuredMcstBcstFilterSetting;
+} tSirWlanResumeParam, *tpSirWlanResumeParam;
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+
+typedef enum ext_wow_type {
+	EXT_WOW_TYPE_APP_TYPE1, /* wow type: only enable wakeup for app type1 */
+	EXT_WOW_TYPE_APP_TYPE2, /* wow type: only enable wakeup for app type2 */
+	EXT_WOW_TYPE_APP_TYPE1_2,  /* wow type: enable wakeup for app type1&2 */
+} EXT_WOW_TYPE;
+
+typedef struct {
+	uint8_t vdev_id;
+	EXT_WOW_TYPE type;
+	uint32_t wakeup_pin_num;
+} tSirExtWoWParams, *tpSirExtWoWParams;
+
+typedef struct {
+	uint8_t vdev_id;
+	struct qdf_mac_addr wakee_mac_addr;
+	uint8_t identification_id[8];
+	uint8_t password[16];
+	uint32_t id_length;
+	uint32_t pass_length;
+} tSirAppType1Params, *tpSirAppType1Params;
+
+typedef struct {
+	uint8_t vdev_id;
+
+	uint8_t rc4_key[16];
+	uint32_t rc4_key_len;
+
+	/** ip header parameter */
+	uint32_t ip_id;         /* NC id */
+	uint32_t ip_device_ip;  /* NC IP address */
+	uint32_t ip_server_ip;  /* Push server IP address */
+
+	/** tcp header parameter */
+	uint16_t tcp_src_port;  /* NC TCP port */
+	uint16_t tcp_dst_port;  /* Push server TCP port */
+	uint32_t tcp_seq;
+	uint32_t tcp_ack_seq;
+
+	uint32_t keepalive_init;        /* Initial ping interval */
+	uint32_t keepalive_min; /* Minimum ping interval */
+	uint32_t keepalive_max; /* Maximum ping interval */
+	uint32_t keepalive_inc; /* Increment of ping interval */
+
+	struct qdf_mac_addr gateway_mac;
+	uint32_t tcp_tx_timeout_val;
+	uint32_t tcp_rx_timeout_val;
+} tSirAppType2Params, *tpSirAppType2Params;
+#endif
+
+#define ANI_MAX_IBSS_ROUTE_TABLE_ENTRY   100
+
+typedef struct sAniDestIpNextHopMacPair {
+	uint8_t destIpv4Addr[QDF_IPV4_ADDR_SIZE];
+	uint8_t nextHopMacAddr[QDF_MAC_ADDR_SIZE];
+} tAniDestIpNextHopMacPair;
+
+typedef struct sAniIbssRouteTable {
+	uint8_t sessionId;
+	uint16_t numEntries;
+	tAniDestIpNextHopMacPair destIpNextHopPair[1];
+} tAniIbssRouteTable;
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+typedef struct {
+	uint8_t acvo_uapsd:1;
+	uint8_t acvi_uapsd:1;
+	uint8_t acbk_uapsd:1;
+	uint8_t acbe_uapsd:1;
+	uint8_t reserved:4;
+} tSirAcUapsd, *tpSirAcUapsd;
+#endif
+
+typedef struct {
+	tSirMacSSid ssId;
+	uint8_t currAPbssid[QDF_MAC_ADDR_SIZE];
+	uint32_t authentication;
+	uint8_t encryption;
+	uint8_t mcencryption;
+	uint8_t ChannelCount;
+	uint8_t ChannelCache[SIR_ROAM_MAX_CHANNELS];
+#ifdef WLAN_FEATURE_11W
+	bool mfp_enabled;
+#endif
+
+} tSirRoamNetworkType;
+
+typedef struct SirMobilityDomainInfo {
+	uint8_t mdiePresent;
+	uint16_t mobilityDomain;
+} tSirMobilityDomainInfo;
+
+typedef enum {
+	SIR_ROAMING_DFS_CHANNEL_DISABLED = 0,
+	SIR_ROAMING_DFS_CHANNEL_ENABLED_NORMAL = 1,
+	SIR_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE = 2
+} eSirDFSRoamScanMode;
+#define MAX_SSID_ALLOWED_LIST 4
+#define MAX_BSSID_AVOID_LIST  16
+#define MAX_BSSID_FAVORED     16
+/**
+ * struct roam_ext_params - Structure holding roaming parameters
+ * @num_bssid_avoid_list:       The number of BSSID's that we should
+ *                              avoid connecting to. It is like a
+ *                              blacklist of BSSID's.
+ * @num_ssid_allowed_list:      The number of SSID profiles that are
+ *                              in the Whitelist. When roaming, we
+ *                              consider the BSSID's with this SSID
+ *                              also for roaming apart from the connected one's
+ * @num_bssid_favored:          Number of BSSID's which have a preference over
+ *                              others
+ * @ssid_allowed_list:          Whitelist SSID's
+ * @bssid_avoid_list:           Blacklist SSID's
+ * @bssid_favored:              Favorable BSSID's
+ * @bssid_favored_factor:       RSSI to be added to this BSSID to prefer it
+ * @raise_rssi_thresh_5g:       The RSSI threshold below which the
+ *                              raise_factor_5g (boost factor) should be
+ *                              applied.
+ * @drop_rssi_thresh_5g:        The RSSI threshold beyond which the
+ *                              drop_factor_5g (penalty factor) should be
+ *                              applied
+ * @raise_rssi_type_5g:         Algorithm to apply the boost factor
+ * @raise_factor_5g:            Boost factor
+ * @drop_rssi_type_5g:          Algorithm to apply the penalty factor
+ * @drop_factor_5g:             Penalty factor
+ * @max_raise_rssi_5g:          Maximum amount of Boost that can added
+ * @max_drop_rssi_5g:           Maximum amount of penalty that can be subtracted
+ * @good_rssi_threshold:        The Lookup UP threshold beyond which roaming
+ *                              scan should be performed.
+ * @rssi_diff:                  RSSI difference for the AP to be better over the
+ *                              current AP to avoid ping pong effects
+ * @good_rssi_roam:             Lazy Roam
+ * @bg_scan_bad_rssi_thresh:    Bad RSSI threshold to perform bg scan.
+ * @bad_rssi_thresh_offset_2g:  Offset from Bad RSSI threshold for 2G to 5G Roam
+ * @bg_scan_client_bitmap:      Bitmap to identify the client scans to snoop.
+ *
+ * This structure holds all the key parameters related to
+ * initial connection and also roaming connections.
+ * */
+struct roam_ext_params {
+	uint8_t num_bssid_avoid_list;
+	uint8_t num_ssid_allowed_list;
+	uint8_t num_bssid_favored;
+	tSirMacSSid ssid_allowed_list[MAX_SSID_ALLOWED_LIST];
+	struct qdf_mac_addr bssid_avoid_list[MAX_BSSID_AVOID_LIST];
+	struct qdf_mac_addr bssid_favored[MAX_BSSID_FAVORED];
+	uint8_t bssid_favored_factor[MAX_BSSID_FAVORED];
+	int raise_rssi_thresh_5g;
+	int drop_rssi_thresh_5g;
+	uint8_t raise_rssi_type_5g;
+	uint8_t raise_factor_5g;
+	uint8_t drop_rssi_type_5g;
+	uint8_t drop_factor_5g;
+	int max_raise_rssi_5g;
+	int max_drop_rssi_5g;
+	int alert_rssi_threshold;
+	int rssi_diff;
+	int good_rssi_roam;
+	int dense_rssi_thresh_offset;
+	int dense_min_aps_cnt;
+	int initial_dense_status;
+	int traffic_threshold;
+	uint8_t num_rssi_rejection_ap;
+	struct rssi_disallow_bssid rssi_rejection_ap[MAX_RSSI_AVOID_BSSID_LIST];
+	int8_t bg_scan_bad_rssi_thresh;
+	uint8_t roam_bad_rssi_thresh_offset_2g;
+	uint32_t bg_scan_client_bitmap;
+};
+
+/**
+ * struct pmkid_mode_bits - Bit flags for PMKID usage in RSN IE
+ * @fw_okc: Opportunistic key caching enable in firmware
+ * @fw_pmksa_cache: PMKSA caching enable in firmware, remember previously
+ *                  visited BSSID/PMK pairs
+ */
+struct pmkid_mode_bits {
+	uint32_t fw_okc:1;
+	uint32_t fw_pmksa_cache:1;
+	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;
+};
+
+/**
+ * struct mawc_params - Motion Aided Wireless Connectivity configuration
+ * @mawc_enabled: Global configuration for MAWC (Roaming/PNO/ExtScan)
+ * @mawc_roam_enabled: MAWC roaming enable/disable
+ * @mawc_roam_traffic_threshold: Traffic threshold in kBps for MAWC roaming
+ * @mawc_roam_ap_rssi_threshold: AP RSSI threshold for MAWC roaming
+ * @mawc_roam_rssi_high_adjust: High Adjustment value for suppressing scan
+ * @mawc_roam_rssi_low_adjust: Low Adjustment value for suppressing scan
+ */
+struct mawc_params {
+	bool mawc_enabled;
+	bool mawc_roam_enabled;
+	uint32_t mawc_roam_traffic_threshold;
+	int8_t mawc_roam_ap_rssi_threshold;
+	uint8_t mawc_roam_rssi_high_adjust;
+	uint8_t mawc_roam_rssi_low_adjust;
+};
+
+typedef struct sSirRoamOffloadScanReq {
+	uint16_t message_type;
+	uint16_t length;
+	bool RoamScanOffloadEnabled;
+	struct mawc_params mawc_roam_params;
+	int8_t LookupThreshold;
+	int8_t rssi_thresh_offset_5g;
+	uint8_t delay_before_vdev_stop;
+	uint8_t OpportunisticScanThresholdDiff;
+	uint8_t RoamRescanRssiDiff;
+	uint8_t RoamRssiDiff;
+	struct rsn_caps rsn_caps;
+	int32_t rssi_abs_thresh;
+	uint8_t ChannelCacheType;
+	uint8_t Command;
+	uint8_t reason;
+	uint16_t NeighborScanTimerPeriod;
+	uint16_t neighbor_scan_min_timer_period;
+	uint16_t NeighborRoamScanRefreshPeriod;
+	uint16_t NeighborScanChannelMinTime;
+	uint16_t NeighborScanChannelMaxTime;
+	uint16_t EmptyRefreshScanPeriod;
+	uint8_t ValidChannelCount;
+	uint8_t ValidChannelList[SIR_ROAM_MAX_CHANNELS];
+	bool IsESEAssoc;
+	bool is_11r_assoc;
+	uint8_t nProbes;
+	uint16_t HomeAwayTime;
+	tSirRoamNetworkType ConnectedNetwork;
+	tSirMobilityDomainInfo MDID;
+	uint8_t sessionId;
+	uint8_t RoamBmissFirstBcnt;
+	uint8_t RoamBmissFinalBcnt;
+	uint8_t RoamBeaconRssiWeight;
+	eSirDFSRoamScanMode allowDFSChannelRoam;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	uint8_t RoamOffloadEnabled;
+	uint8_t PSK_PMK[SIR_ROAM_SCAN_PSK_SIZE];
+	uint32_t pmk_len;
+	uint8_t Prefer5GHz;
+	uint8_t RoamRssiCatGap;
+	uint8_t Select5GHzMargin;
+	uint8_t KRK[SIR_KRK_KEY_LEN];
+	uint8_t BTK[SIR_BTK_KEY_LEN];
+	uint32_t ReassocFailureTimeout;
+	tSirAcUapsd AcUapsd;
+	uint8_t R0KH_ID[SIR_ROAM_R0KH_ID_MAX_LEN];
+	uint32_t R0KH_ID_Length;
+	uint8_t RoamKeyMgmtOffloadEnabled;
+	struct pmkid_mode_bits pmkid_modes;
+#endif
+	struct roam_ext_params roam_params;
+	uint8_t  middle_of_roaming;
+	uint32_t hi_rssi_scan_max_count;
+	uint32_t hi_rssi_scan_rssi_delta;
+	uint32_t hi_rssi_scan_delay;
+	int32_t hi_rssi_scan_rssi_ub;
+	uint8_t early_stop_scan_enable;
+	int8_t early_stop_scan_min_threshold;
+	int8_t early_stop_scan_max_threshold;
+	enum scan_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode;
+	tSirAddie assoc_ie;
+	struct lca_disallow_config_params lca_config_params;
+	struct scoring_param score_params;
+#ifdef WLAN_FEATURE_FILS_SK
+	bool is_fils_connection;
+	struct roam_fils_params roam_fils_params;
+#endif
+	uint32_t btm_offload_config;
+	uint32_t btm_solicited_timeout;
+	uint32_t btm_max_attempt_cnt;
+	uint32_t btm_sticky_time;
+	struct wmi_11k_offload_params offload_11k_params;
+	uint32_t ho_delay_for_rx;
+	uint32_t roam_preauth_retry_count;
+	uint32_t roam_preauth_no_ack_timeout;
+	uint32_t min_delay_btw_roam_scans;
+	uint32_t roam_trigger_reason_bitmask;
+	bool roam_force_rssi_trigger;
+} tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq;
+
+typedef struct sSirRoamOffloadScanRsp {
+	uint8_t sessionId;
+	uint32_t reason;
+} tSirRoamOffloadScanRsp, *tpSirRoamOffloadScanRsp;
+
+/*---------------------------------------------------------------------------
+   Packet Filtering Parameters
+   ---------------------------------------------------------------------------*/
+#define    SIR_MAX_FILTER_TEST_DATA_LEN       8
+#define    SIR_MAX_FILTER_TEST_DATA_OFFSET  200
+#define    SIR_MAX_NUM_MULTICAST_ADDRESS    240
+#define    SIR_MAX_NUM_FILTERS               20
+#define    SIR_MAX_NUM_TESTS_PER_FILTER      10
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+/* */
+/* Filter Packet Match Count Parameters */
+/* */
+typedef struct sSirRcvFltPktMatchCnt {
+	uint8_t filterId;
+	uint32_t matchCnt;
+} tSirRcvFltPktMatchCnt, tpSirRcvFltPktMatchCnt;
+
+typedef struct sSirRcvFltPktMatchRsp {
+	uint16_t mesgType;
+	uint16_t mesgLen;
+
+	/* Success or Failure */
+	uint32_t status;
+	tSirRcvFltPktMatchCnt filterMatchCnt[SIR_MAX_NUM_FILTERS];
+	struct qdf_mac_addr bssid;
+} tSirRcvFltPktMatchRsp, *tpSirRcvFltPktMatchRsp;
+
+/* */
+/* Receive Filter Clear Parameters */
+/* */
+typedef struct sSirRcvFltPktClearParam {
+	uint32_t status;        /* only valid for response message */
+	uint8_t filterId;
+	struct qdf_mac_addr self_macaddr;
+	struct qdf_mac_addr bssid;
+} tSirRcvFltPktClearParam, *tpSirRcvFltPktClearParam;
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+
+/* */
+/* Multicast Address List Parameters */
+/* */
+typedef struct sSirRcvFltMcAddrList {
+	uint32_t ulMulticastAddrCnt;
+	struct qdf_mac_addr multicastAddr[SIR_MAX_NUM_MULTICAST_ADDRESS];
+	struct qdf_mac_addr self_macaddr;
+	struct qdf_mac_addr bssid;
+	uint8_t action;
+} tSirRcvFltMcAddrList, *tpSirRcvFltMcAddrList;
+
+/* */
+/* Generic version information */
+/* */
+typedef struct {
+	uint8_t revision;
+	uint8_t version;
+	uint8_t minor;
+	uint8_t major;
+} tSirVersionType;
+
+/**
+ * struct sir_wifi_start_log - Structure to store the params sent to start/
+ * stop logging
+ * @name:          Attribute which indicates the type of logging like per packet
+ *                 statistics, connectivity etc.
+ * @verbose_level: Verbose level which can be 0,1,2,3
+ * @is_iwpriv_command: Set 1 for iwpriv command
+ * @ini_triggered: triggered using ini
+ * @user_triggered: triggered by user
+ * @size: pktlog buffer size
+ * @is_pktlog_buff_clear: clear the pktlog buffer
+ */
+struct sir_wifi_start_log {
+	uint32_t ring_id;
+	uint32_t verbose_level;
+	uint32_t is_iwpriv_command;
+	bool ini_triggered;
+	uint8_t user_triggered;
+	int size;
+	bool is_pktlog_buff_clear;
+};
+
+
+/**
+ * struct sir_pcl_list - Format of PCL
+ * @pcl_list: List of preferred channels
+ * @weight_list: Weights of the PCL
+ * @pcl_len: Number of channels in the PCL
+ */
+struct sir_pcl_list {
+	uint32_t pcl_len;
+	uint8_t pcl_list[128];
+	uint8_t weight_list[128];
+};
+
+/**
+ * struct sir_pcl_chan_weights - Params to get the valid weighed list
+ * @pcl_list: Preferred channel list already sorted in the order of preference
+ * @pcl_len: Length of the PCL
+ * @saved_chan_list: Valid channel list updated as part of
+ * WMA_UPDATE_CHAN_LIST_REQ
+ * @saved_num_chan: Length of the valid channel list
+ * @weighed_valid_list: Weights of the valid channel list. This will have one
+ * to one mapping with valid_chan_list. FW expects channel order and size to be
+ * as per the list provided in WMI_SCAN_CHAN_LIST_CMDID.
+ * @weight_list: Weights assigned by policy manager
+ */
+struct sir_pcl_chan_weights {
+	uint8_t pcl_list[128];
+	uint32_t pcl_len;
+	uint8_t saved_chan_list[128];
+	uint32_t saved_num_chan;
+	uint8_t weighed_valid_list[128];
+	uint8_t weight_list[128];
+};
+
+/**
+ * struct sir_hw_mode_params - HW mode params
+ * @mac0_tx_ss: MAC0 Tx spatial stream
+ * @mac0_rx_ss: MAC0 Rx spatial stream
+ * @mac1_tx_ss: MAC1 Tx spatial stream
+ * @mac1_rx_ss: MAC1 Rx spatial stream
+ * @mac0_bw: MAC0 bandwidth
+ * @mac1_bw: MAC1 bandwidth
+ * @dbs_cap: DBS capabality
+ * @agile_dfs_cap: Agile DFS capabality
+ */
+struct sir_hw_mode_params {
+	uint8_t mac0_tx_ss;
+	uint8_t mac0_rx_ss;
+	uint8_t mac1_tx_ss;
+	uint8_t mac1_rx_ss;
+	uint8_t mac0_bw;
+	uint8_t mac1_bw;
+	uint8_t dbs_cap;
+	uint8_t agile_dfs_cap;
+	uint8_t sbs_cap;
+};
+
+/**
+ * struct sir_set_hw_mode_resp - HW mode response
+ * @status: Status
+ * @cfgd_hw_mode_index: Configured HW mode index
+ * @num_vdev_mac_entries: Number of vdev-mac id entries
+ * @vdev_mac_map: vdev id-mac id map
+ */
+struct sir_set_hw_mode_resp {
+	uint32_t status;
+	uint32_t cfgd_hw_mode_index;
+	uint32_t num_vdev_mac_entries;
+	struct policy_mgr_vdev_mac_map vdev_mac_map[MAX_VDEV_SUPPORTED];
+};
+
+/**
+ * struct sir_hw_mode_trans_ind - HW mode transition indication
+ * @old_hw_mode_index: Index of old HW mode
+ * @new_hw_mode_index: Index of new HW mode
+ * @num_vdev_mac_entries: Number of vdev-mac id entries
+ * @vdev_mac_map: vdev id-mac id map
+ */
+struct sir_hw_mode_trans_ind {
+	uint32_t old_hw_mode_index;
+	uint32_t new_hw_mode_index;
+	uint32_t num_vdev_mac_entries;
+	struct policy_mgr_vdev_mac_map vdev_mac_map[MAX_VDEV_SUPPORTED];
+};
+
+/**
+ * struct sir_dual_mac_config_resp - Dual MAC config response
+ * @status: Status of setting the dual mac configuration
+ */
+struct sir_dual_mac_config_resp {
+	uint32_t status;
+};
+
+/**
+ * enum set_antenna_mode_status - Status of set antenna mode
+ * command
+ * @SET_ANTENNA_MODE_STATUS_OK: command successful
+ * @SET_ANTENNA_MODE_STATUS_EINVAL: invalid antenna mode
+ * @SET_ANTENNA_MODE_STATUS_ECANCELED: mode change cancelled
+ * @SET_ANTENNA_MODE_STATUS_ENOTSUP: mode not supported
+ */
+enum set_antenna_mode_status {
+	SET_ANTENNA_MODE_STATUS_OK,
+	SET_ANTENNA_MODE_STATUS_EINVAL,
+	SET_ANTENNA_MODE_STATUS_ECANCELED,
+	SET_ANTENNA_MODE_STATUS_ENOTSUP,
+};
+
+/**
+ * struct sir_antenna_mode_resp - set antenna mode response
+ * @status: Status of setting the antenna mode
+ */
+struct sir_antenna_mode_resp {
+	enum set_antenna_mode_status status;
+};
+
+/*---------------------------------------------------------------------------
+   sAniSetTmLevelReq
+   ---------------------------------------------------------------------------*/
+typedef struct sAniSetTmLevelReq {
+	uint16_t tmMode;
+	uint16_t newTmLevel;
+} tAniSetTmLevelReq, *tpAniSetTmLevelReq;
+
+#ifdef FEATURE_WLAN_TDLS
+/* TDLS Request struct SME-->PE */
+typedef struct sSirTdlsSendMgmtReq {
+	uint16_t messageType;   /* eWNI_SME_TDLS_DISCOVERY_START_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	uint8_t reqType;
+	uint8_t dialog;
+	uint16_t statusCode;
+	uint8_t responder;
+	uint32_t peerCapability;
+	/* For multi-session, for PE to locate peSession ID */
+	struct qdf_mac_addr bssid;
+	struct qdf_mac_addr peer_mac;
+	enum wifi_traffic_ac ac;
+	/* Variable length. Dont add any field after this. */
+	uint8_t addIe[1];
+} tSirTdlsSendMgmtReq, *tpSirSmeTdlsSendMgmtReq;
+
+typedef enum TdlsAddOper {
+	TDLS_OPER_NONE,
+	TDLS_OPER_ADD,
+	TDLS_OPER_UPDATE
+} eTdlsAddOper;
+
+/* TDLS Request struct SME-->PE */
+typedef struct sSirTdlsAddStaReq {
+	uint16_t messageType;   /* eWNI_SME_TDLS_DISCOVERY_START_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	/* For multi-session, for PE to locate peSession ID */
+	struct qdf_mac_addr bssid;
+	eTdlsAddOper tdlsAddOper;
+	struct qdf_mac_addr peermac;
+	uint16_t capability;
+	uint8_t extn_capability[SIR_MAC_MAX_EXTN_CAP];
+	uint8_t supported_rates_length;
+	uint8_t supported_rates[SIR_MAC_MAX_SUPP_RATES];
+	uint8_t htcap_present;
+	tSirHTCap htCap;
+	uint8_t vhtcap_present;
+	tSirVHTCap vhtCap;
+	uint8_t uapsd_queues;
+	uint8_t max_sp;
+} tSirTdlsAddStaReq, *tpSirSmeTdlsAddStaReq;
+
+/* TDLS Response struct PE-->SME */
+typedef struct sSirTdlsAddStaRsp {
+	uint16_t messageType;
+	uint16_t length;
+	tSirResultCodes statusCode;
+	struct qdf_mac_addr peermac;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t staId;
+	uint16_t staType;
+	eTdlsAddOper tdlsAddOper;
+	struct wlan_objmgr_psoc *psoc;
+} tSirTdlsAddStaRsp;
+
+/* TDLS Request struct SME-->PE */
+typedef struct {
+	uint16_t messageType;   /* eWNI_SME_TDLS_LINK_ESTABLISH_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	uint8_t uapsdQueues;    /* Peer's uapsd Queues Information */
+	uint8_t maxSp;          /* Peer's Supported Maximum Service Period */
+	uint8_t isBufSta;       /* Does Peer Support as Buffer Station. */
+	/* Does Peer Support as TDLS Off Channel. */
+	uint8_t isOffChannelSupported;
+	uint8_t isResponder;    /* Is Peer a responder. */
+	/* For multi-session, for PE to locate peSession ID */
+	struct qdf_mac_addr bssid;
+	struct qdf_mac_addr peermac;
+	uint8_t supportedChannelsLen;
+	uint8_t supportedChannels[SIR_MAC_MAX_SUPP_CHANNELS];
+	uint8_t supportedOperClassesLen;
+	uint8_t supportedOperClasses[REG_MAX_SUPP_OPER_CLASSES];
+} tSirTdlsLinkEstablishReq, *tpSirTdlsLinkEstablishReq;
+
+/* TDLS Request struct SME-->PE */
+typedef struct {
+	uint16_t messageType;   /* eWNI_SME_TDLS_LINK_ESTABLISH_RSP */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	tSirResultCodes statusCode;
+	struct qdf_mac_addr peermac;
+} tSirTdlsLinkEstablishReqRsp, *tpSirTdlsLinkEstablishReqRsp;
+
+/* TDLS Request struct SME-->PE */
+typedef struct sSirTdlsDelStaReq {
+	uint16_t messageType;   /* eWNI_SME_TDLS_DISCOVERY_START_REQ */
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint16_t transactionId; /* Transaction ID for cmd */
+	/* For multi-session, for PE to locate peSession ID */
+	struct qdf_mac_addr bssid;
+	struct qdf_mac_addr peermac;
+} tSirTdlsDelStaReq, *tpSirSmeTdlsDelStaReq;
+/* TDLS Response struct PE-->SME */
+typedef struct sSirTdlsDelStaRsp {
+	uint16_t messageType;
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	tSirResultCodes statusCode;
+	struct qdf_mac_addr peermac;
+	uint16_t staId;
+	struct wlan_objmgr_psoc *psoc;
+} tSirTdlsDelStaRsp, *tpSirTdlsDelStaRsp;
+/* TDLS Delete Indication struct PE-->SME */
+typedef struct sSirTdlsDelStaInd {
+	uint16_t messageType;
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	struct qdf_mac_addr peermac;
+	uint16_t staId;
+	uint16_t reasonCode;
+} tSirTdlsDelStaInd, *tpSirTdlsDelStaInd;
+typedef struct sSirTdlsDelAllPeerInd {
+	uint16_t messageType;
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+} tSirTdlsDelAllPeerInd, *tpSirTdlsDelAllPeerInd;
+typedef struct sSirMgmtTxCompletionInd {
+	uint16_t messageType;
+	uint16_t length;
+	uint8_t sessionId;      /* Session ID */
+	uint32_t txCompleteStatus;
+	struct wlan_objmgr_psoc *psoc;
+} tSirMgmtTxCompletionInd, *tpSirMgmtTxCompletionInd;
+
+typedef struct sSirTdlsEventnotify {
+	uint8_t sessionId;
+	struct qdf_mac_addr peermac;
+	uint16_t messageType;
+	uint32_t peer_reason;
+} tSirTdlsEventnotify;
+#endif /* FEATURE_WLAN_TDLS */
+
+/* Reset AP Caps Changed */
+typedef struct sSirResetAPCapsChange {
+	uint16_t messageType;
+	uint16_t length;
+	struct qdf_mac_addr bssId;
+} tSirResetAPCapsChange, *tpSirResetAPCapsChange;
+
+/* / Definition for Candidate found indication from FW */
+typedef struct sSirSmeCandidateFoundInd {
+	uint16_t messageType;   /* eWNI_SME_CANDIDATE_FOUND_IND */
+	uint16_t length;
+	uint8_t sessionId;      /* Session Identifier */
+} tSirSmeCandidateFoundInd, *tpSirSmeCandidateFoundInd;
+
+#ifdef WLAN_FEATURE_11W
+typedef struct sSirWlanExcludeUnencryptParam {
+	bool excludeUnencrypt;
+	struct qdf_mac_addr bssid;
+} tSirWlanExcludeUnencryptParam, *tpSirWlanExcludeUnencryptParam;
+#endif
+
+typedef enum {
+	P2P_SCAN_TYPE_SEARCH = 1,       /* P2P Search */
+	P2P_SCAN_TYPE_LISTEN    /* P2P Listen */
+} tSirP2pScanType;
+
+typedef struct sAniHandoffReq {
+	/* Common for all types are requests */
+	uint16_t msgType;       /* message type is same as the request type */
+	uint16_t msgLen;        /* length of the entire request */
+	uint8_t sessionId;
+	uint8_t bssid[QDF_MAC_ADDR_SIZE];
+	uint8_t channel;
+	uint8_t handoff_src;
+} tAniHandoffReq, *tpAniHandoffReq;
+
+/**
+ * sir_scan_event_type - scan event types used in LIM
+ * @SIR_SCAN_EVENT_STARTED - scan command accepted by FW
+ * @SIR_SCAN_EVENT_COMPLETED - scan has been completed by FW
+ * @SIR_SCAN_EVENT_BSS_CHANNEL - FW is going to move to HOME channel
+ * @SIR_SCAN_EVENT_FOREIGN_CHANNEL - FW is going to move to FORIEGN channel
+ * @SIR_SCAN_EVENT_DEQUEUED - scan request got dequeued
+ * @SIR_SCAN_EVENT_PREEMPTED - preempted by other high priority scan
+ * @SIR_SCAN_EVENT_START_FAILED - scan start failed
+ * @SIR_SCAN_EVENT_RESTARTED - scan restarted
+ * @SIR_SCAN_EVENT_MAX - max value for event type
+*/
+enum sir_scan_event_type {
+	SIR_SCAN_EVENT_STARTED = 0x1,
+	SIR_SCAN_EVENT_COMPLETED = 0x2,
+	SIR_SCAN_EVENT_BSS_CHANNEL = 0x4,
+	SIR_SCAN_EVENT_FOREIGN_CHANNEL = 0x8,
+	SIR_SCAN_EVENT_DEQUEUED = 0x10,
+	SIR_SCAN_EVENT_PREEMPTED = 0x20,
+	SIR_SCAN_EVENT_START_FAILED = 0x40,
+	SIR_SCAN_EVENT_RESTARTED = 0x80,
+	SIR_SCAN_EVENT_MAX = 0x8000
+};
+
+typedef struct sSirScanOffloadEvent {
+	enum sir_scan_event_type event;
+	tSirResultCodes reasonCode;
+	uint32_t chanFreq;
+	uint32_t requestor;
+	uint32_t scanId;
+	tSirP2pScanType p2pScanType;
+	uint8_t sessionId;
+} tSirScanOffloadEvent, *tpSirScanOffloadEvent;
+
+/**
+ * struct sSirUpdateChanParam - channel parameters
+ * @chanId: ID of the channel
+ * @pwr: power level
+ * @dfsSet: is dfs supported or not
+ * @half_rate: is the channel operating at 10MHz
+ * @quarter_rate: is the channel operating at 5MHz
+ */
+typedef struct sSirUpdateChanParam {
+	uint8_t chanId;
+	uint8_t pwr;
+	bool dfsSet;
+	bool half_rate;
+	bool quarter_rate;
+} tSirUpdateChanParam, *tpSirUpdateChanParam;
+
+typedef struct sSirUpdateChan {
+	uint8_t numChan;
+	uint8_t ht_en;
+	uint8_t vht_en;
+	uint8_t vht_24_en;
+	tSirUpdateChanParam chanParam[1];
+} tSirUpdateChanList, *tpSirUpdateChanList;
+
+typedef enum eSirAddonPsReq {
+	eSIR_ADDON_NOTHING,
+	eSIR_ADDON_ENABLE_UAPSD,
+	eSIR_ADDON_DISABLE_UAPSD
+} tSirAddonPsReq;
+
+#ifdef FEATURE_WLAN_CH_AVOID
+typedef struct sSirChAvoidUpdateReq {
+	uint32_t reserved_param;
+} tSirChAvoidUpdateReq;
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+typedef struct sSirLinkSpeedInfo {
+	/* MAC Address for the peer */
+	struct qdf_mac_addr peer_macaddr;
+	uint32_t estLinkSpeed;  /* Linkspeed from firmware */
+} tSirLinkSpeedInfo, *tpSirLinkSpeedInfo;
+
+/**
+ * struct sir_peer_info_req - peer info request struct
+ * @peer_macaddr: MAC address
+ * @sessionid: vdev id
+ *
+ * peer info request message's struct
+ */
+struct sir_peer_info_req {
+	struct qdf_mac_addr peer_macaddr;
+	uint8_t sessionid;
+};
+
+/**
+ * struct sir_peer_info - peer information struct
+ * @peer_macaddr: MAC address
+ * @rssi: rssi
+ * @tx_rate: last tx rate
+ * @rx_rate: last rx rate
+ *
+ * a station's information
+ */
+struct sir_peer_info {
+	struct qdf_mac_addr peer_macaddr;
+	int8_t rssi;
+	uint32_t tx_rate;
+	uint32_t rx_rate;
+};
+
+/**
+ * struct sir_peer_info_resp - all peers information struct
+ * @count: peer's number
+ * @info: peer information
+ *
+ * all station's information
+ */
+struct sir_peer_info_resp {
+	uint8_t count;
+	struct sir_peer_info info[0];
+};
+
+/**
+ * struct sir_peer_info_ext_req - peer info request struct
+ * @peer_macaddr: MAC address
+ * @sessionid: vdev id
+ * @reset_after_request: fw reset statistics after query
+ *
+ * peer info request message's struct
+ */
+struct sir_peer_info_ext_req {
+	struct qdf_mac_addr peer_macaddr;
+	uint8_t sessionid;
+	uint8_t reset_after_request;
+};
+
+/**
+ * struct sir_peer_info_ext - peer info information struct
+ *                            (refer to station_info struct in Kernel)
+ * @peer_macaddr: MAC address
+ * @tx_packets: packets transmitted to this station
+ * @tx_bytes: bytes transmitted to this station
+ * @rx_packets: packets received from this station
+ * @rx_bytes: bytes received from this station
+ * @rx_retries: cumulative retry counts
+ * @tx_failed: number of failed transmissions
+ * @rssi: The signal strength
+ * @tx_rate: last used tx bitrate (kbps)
+ * @tx_rate_code: last tx rate code (last_tx_rate_code of wmi_peer_stats_info)
+ * @rx_rate: last used rx bitrate (kbps)
+ * @rx_rate_code: last rx rate code (last_rx_rate_code of wmi_peer_stats_info)
+ *
+ * a station's information
+ */
+struct sir_peer_info_ext {
+	struct qdf_mac_addr peer_macaddr;
+	uint32_t tx_packets;
+	uint64_t tx_bytes;
+	uint32_t rx_packets;
+	uint64_t rx_bytes;
+	uint32_t tx_retries;
+	uint32_t tx_failed;
+	int32_t rssi;
+	uint32_t tx_rate;
+	uint32_t tx_rate_code;
+	uint32_t rx_rate;
+	uint32_t rx_rate_code;
+};
+
+/**
+ * struct sir_peer_info_ext_resp - all peers' information struct
+ * @count: peer's number
+ * @info: peer information
+ *
+ * all station's information
+ */
+struct sir_peer_info_ext_resp {
+	uint8_t count;
+	struct sir_peer_info_ext info[0];
+};
+
+/**
+ * @sta_num: number of peer station which has valid info
+ * @info: peer information
+ *
+ * all SAP peer station's information retrieved
+ */
+struct sir_peer_sta_info {
+	uint8_t sta_num;
+	struct sir_peer_info info[MAX_PEER_STA];
+};
+
+/**
+ * @sta_num: number of peer station which has valid info
+ * @info: peer extended information
+ *
+ * all SAP peer station's extended information retrieved
+ */
+struct sir_peer_sta_ext_info {
+	uint8_t sta_num;
+	struct sir_peer_info_ext info[MAX_PEER_STA];
+};
+
+typedef struct sSirAddPeriodicTxPtrn {
+	/* MAC Address for the adapter */
+	struct qdf_mac_addr mac_address;
+	uint8_t ucPtrnId;       /* Pattern ID */
+	uint16_t ucPtrnSize;    /* Pattern size */
+	uint32_t usPtrnIntervalMs;      /* In msec */
+	uint8_t ucPattern[PERIODIC_TX_PTRN_MAX_SIZE];   /* Pattern buffer */
+} tSirAddPeriodicTxPtrn, *tpSirAddPeriodicTxPtrn;
+
+typedef struct sSirDelPeriodicTxPtrn {
+	/* MAC Address for the adapter */
+	struct qdf_mac_addr mac_address;
+	/* Bitmap of pattern IDs that need to be deleted */
+	uint32_t ucPatternIdBitmap;
+	uint8_t ucPtrnId;       /* Pattern ID */
+} tSirDelPeriodicTxPtrn, *tpSirDelPeriodicTxPtrn;
+
+/*---------------------------------------------------------------------------
+* tSirIbssGetPeerInfoReqParams
+*--------------------------------------------------------------------------*/
+typedef struct {
+	bool allPeerInfoReqd;   /* If set, all IBSS peers stats are reported */
+	uint8_t staIdx;         /* If allPeerInfoReqd is not set, only stats */
+	/* of peer with staIdx is reported */
+} tSirIbssGetPeerInfoReqParams, *tpSirIbssGetPeerInfoReqParams;
+
+/**
+ * typedef struct - tSirIbssGetPeerInfoParams
+ * @mac_addr: mac address received from target
+ * @txRate: TX rate
+ * @mcsIndex: MCS index
+ * @txRateFlags: TX rate flags
+ * @rssi: RSSI
+ */
+typedef struct {
+	uint8_t  mac_addr[QDF_MAC_ADDR_SIZE];
+	uint32_t txRate;
+	uint32_t mcsIndex;
+	uint32_t txRateFlags;
+	int8_t  rssi;
+} tSirIbssPeerInfoParams;
+
+typedef struct {
+	uint32_t status;
+	uint8_t numPeers;
+	tSirIbssPeerInfoParams peerInfoParams[32];
+} tSirPeerInfoRspParams, *tpSirIbssPeerInfoRspParams;
+
+/*---------------------------------------------------------------------------
+* tSirIbssGetPeerInfoRspParams
+*--------------------------------------------------------------------------*/
+typedef struct {
+	uint16_t mesgType;
+	uint16_t mesgLen;
+	tSirPeerInfoRspParams ibssPeerInfoRspParams;
+} tSirIbssGetPeerInfoRspParams, *tpSirIbssGetPeerInfoRspParams;
+
+typedef struct {
+	uint16_t mesgType;
+	uint16_t mesgLen;
+	bool suspended;
+} tSirReadyToSuspendInd, *tpSirReadyToSuspendInd;
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+typedef struct {
+	uint16_t mesgType;
+	uint16_t mesgLen;
+	bool status;
+} tSirReadyToExtWoWInd, *tpSirReadyToExtWoWInd;
+#endif
+typedef struct sSirRateUpdateInd {
+	uint8_t nss;            /* 0: 1x1, 1: 2x2 */
+	struct qdf_mac_addr bssid;
+	enum QDF_OPMODE dev_mode;
+	int32_t bcastDataRate;  /* bcast rate unit Mbpsx10, -1:not used */
+	/*
+	 * 0 implies RA, positive value implies fixed rate, -1 implies ignore
+	 * this param.
+	 */
+	int32_t ucastDataRate;
+
+	/* TX flag to differentiate between HT20, HT40 etc */
+	enum tx_rate_info ucastDataRateTxFlag;
+
+	/*
+	 * 0 implies MCAST RA, positive value implies fixed rate,
+	 * -1 implies ignore this param
+	 */
+	int32_t reliableMcastDataRate;  /* unit Mbpsx10 */
+
+	/* TX flag to differentiate between HT20, HT40 etc */
+	enum tx_rate_info reliableMcastDataRateTxFlag;
+
+	/*
+	 * MCAST(or BCAST) fixed data rate in 2.4 GHz, unit Mbpsx10,
+	 * 0 implies ignore
+	 */
+	uint32_t mcastDataRate24GHz;
+
+	/* TX flag to differentiate between HT20, HT40 etc */
+	enum tx_rate_info mcastDataRate24GHzTxFlag;
+
+	/*
+	 * MCAST(or BCAST) fixed data rate in 5 GHz,
+	 * unit Mbpsx10, 0 implies ignore
+	 */
+	uint32_t mcastDataRate5GHz;
+
+	/* TX flag to differentiate between HT20, HT40 etc */
+	enum tx_rate_info mcastDataRate5GHzTxFlag;
+
+} tSirRateUpdateInd, *tpSirRateUpdateInd;
+
+#if defined(FEATURE_WLAN_CH_AVOID) || defined(FEATURE_WLAN_FORCE_SAP_SCC)
+#define SIR_CH_AVOID_MAX_RANGE   4
+
+typedef struct sSirChAvoidFreqType {
+	uint32_t start_freq;
+	uint32_t end_freq;
+} tSirChAvoidFreqType;
+
+typedef struct sSirChAvoidIndType {
+	uint32_t avoid_range_count;
+	tSirChAvoidFreqType avoid_freq_range[SIR_CH_AVOID_MAX_RANGE];
+} tSirChAvoidIndType;
+#endif /* FEATURE_WLAN_CH_AVOID || FEATURE_WLAN_FORCE_SAP_SCC */
+
+#define SIR_DFS_MAX_20M_SUB_CH 8
+#define SIR_80MHZ_START_CENTER_CH_DIFF 6
+
+typedef struct sSirSmeDfsChannelList {
+	uint32_t nchannels;
+	/* Ch num including bonded channels on which the RADAR is present */
+	uint8_t channels[SIR_DFS_MAX_20M_SUB_CH];
+} tSirSmeDfsChannelList, *tpSirSmeDfsChannelList;
+
+typedef struct sSirSmeDfsEventInd {
+	uint32_t sessionId;
+	tSirSmeDfsChannelList chan_list;
+	uint32_t dfs_radar_status;
+	int use_nol;
+} tSirSmeDfsEventInd, *tpSirSmeDfsEventInd;
+
+typedef struct sSirChanChangeRequest {
+	uint16_t messageType;
+	uint16_t messageLen;
+	uint8_t targetChannel;
+	uint8_t sec_ch_offset;
+	enum phy_ch_width ch_width;
+	uint8_t center_freq_seg_0;
+	uint8_t center_freq_seg_1;
+	uint8_t bssid[QDF_MAC_ADDR_SIZE];
+	uint32_t dot11mode;
+	tSirNwType nw_type;
+	tSirMacRateSet operational_rateset;
+	tSirMacRateSet extended_rateset;
+	uint32_t cac_duration_ms;
+	uint32_t dfs_regdomain;
+} tSirChanChangeRequest, *tpSirChanChangeRequest;
+
+typedef struct sSirChanChangeResponse {
+	uint8_t sessionId;
+	uint8_t newChannelNumber;
+	uint8_t channelChangeStatus;
+} tSirChanChangeResponse, *tpSirChanChangeResponse;
+
+typedef struct sSirStartBeaconIndication {
+	uint16_t messageType;
+	uint16_t messageLen;
+	uint8_t beaconStartStatus;
+	uint8_t bssid[QDF_MAC_ADDR_SIZE];
+} tSirStartBeaconIndication, *tpSirStartBeaconIndication;
+
+/* additional IE type */
+typedef enum tUpdateIEsType {
+	eUPDATE_IE_NONE,
+	eUPDATE_IE_PROBE_BCN,
+	eUPDATE_IE_PROBE_RESP,
+	eUPDATE_IE_ASSOC_RESP,
+
+	/* Add type above this line */
+	/* this is used to reset all buffer */
+	eUPDATE_IE_ALL,
+	eUPDATE_IE_MAX
+} eUpdateIEsType;
+
+/* Modify particular IE in addition IE for prob resp Bcn */
+typedef struct sSirModifyIE {
+	struct qdf_mac_addr bssid;
+	uint16_t smeSessionId;
+	bool notify;
+	uint8_t ieID;
+	uint8_t ieIDLen;        /*ie length as per spec */
+	uint16_t ieBufferlength;
+	uint8_t *pIEBuffer;
+	int32_t oui_length;
+
+} tSirModifyIE, *tpSirModifyIE;
+
+struct send_add_ba_req {
+	uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
+	struct addba_send_params param;
+};
+
+/* Message format for Update IE message sent to PE  */
+typedef struct sSirModifyIEsInd {
+	uint16_t msgType;
+	uint16_t msgLen;
+	tSirModifyIE modifyIE;
+	eUpdateIEsType updateType;
+} tSirModifyIEsInd, *tpSirModifyIEsInd;
+
+/* Message format for Update IE message sent to PE  */
+typedef struct sSirUpdateIE {
+	struct qdf_mac_addr bssid;
+	uint16_t smeSessionId;
+	bool append;
+	bool notify;
+	uint16_t ieBufferlength;
+	uint8_t *pAdditionIEBuffer;
+} tSirUpdateIE, *tpSirUpdateIE;
+
+/* Message format for Update IE message sent to PE  */
+typedef struct sSirUpdateIEsInd {
+	uint16_t msgType;
+	uint16_t msgLen;
+	tSirUpdateIE updateIE;
+	eUpdateIEsType updateType;
+} tSirUpdateIEsInd, *tpSirUpdateIEsInd;
+
+/* Message format for requesting channel switch announcement to lower layers */
+typedef struct sSirDfsCsaIeRequest {
+	uint16_t msgType;
+	uint16_t msgLen;
+	uint8_t targetChannel;
+	uint8_t csaIeRequired;
+	uint8_t bssid[QDF_MAC_ADDR_SIZE];
+	struct ch_params ch_params;
+	uint8_t  ch_switch_beacon_cnt;
+	uint8_t  ch_switch_mode;
+	uint8_t  dfs_ch_switch_disable;
+} tSirDfsCsaIeRequest, *tpSirDfsCsaIeRequest;
+
+/* Indication from lower layer indicating the completion of first beacon send
+ * after the beacon template update
+ */
+typedef struct sSirFirstBeaconTxCompleteInd {
+	uint16_t messageType;   /* eWNI_SME_MISSED_BEACON_IND */
+	uint16_t length;
+	uint8_t bssIdx;
+} tSirFirstBeaconTxCompleteInd, *tpSirFirstBeaconTxCompleteInd;
+
+typedef struct sSirSmeCSAIeTxCompleteRsp {
+	uint8_t sessionId;
+	uint8_t chanSwIeTxStatus;
+} tSirSmeCSAIeTxCompleteRsp, *tpSirSmeCSAIeTxCompleteRsp;
+
+/* Thermal Mitigation*/
+
+typedef struct {
+	uint16_t minTempThreshold;
+	uint16_t maxTempThreshold;
+} t_thermal_level_info, *tp_thermal_level_info;
+
+typedef enum {
+	WLAN_WMA_THERMAL_LEVEL_0,
+	WLAN_WMA_THERMAL_LEVEL_1,
+	WLAN_WMA_THERMAL_LEVEL_2,
+	WLAN_WMA_THERMAL_LEVEL_3,
+	WLAN_WMA_MAX_THERMAL_LEVELS
+} t_thermal_level;
+
+#define WLAN_THROTTLE_DUTY_CYCLE_LEVEL_MAX (4)
+
+typedef struct {
+	/* Array of thermal levels */
+	t_thermal_level_info thermalLevels[WLAN_WMA_MAX_THERMAL_LEVELS];
+	uint8_t thermalCurrLevel;
+	uint8_t thermalMgmtEnabled;
+	uint32_t throttlePeriod;
+	uint8_t throttle_duty_cycle_tbl[WLAN_THROTTLE_DUTY_CYCLE_LEVEL_MAX];
+} t_thermal_mgmt, *tp_thermal_mgmt;
+
+typedef struct sSirTxPowerLimit {
+	/* Thermal limits for 2g and 5g */
+	uint32_t txPower2g;
+	uint32_t txPower5g;
+} tSirTxPowerLimit;
+
+enum bad_peer_thresh_levels {
+	WLAN_WMA_IEEE80211_B_LEVEL = 0,
+	WLAN_WMA_IEEE80211_AG_LEVEL,
+	WLAN_WMA_IEEE80211_N_LEVEL,
+	WLAN_WMA_IEEE80211_AC_LEVEL,
+	WLAN_WMA_IEEE80211_AX_LEVEL,
+	WLAN_WMA_IEEE80211_MAX_LEVEL,
+};
+
+#define NUM_OF_RATE_THRESH_MAX    (4)
+struct t_bad_peer_info {
+	uint32_t cond;
+	uint32_t delta;
+	uint32_t percentage;
+	uint32_t thresh[NUM_OF_RATE_THRESH_MAX];
+	uint32_t txlimit;
+};
+
+struct t_bad_peer_txtcl_config {
+	/* Array of thermal levels */
+	struct t_bad_peer_info threshold[WLAN_WMA_IEEE80211_MAX_LEVEL];
+	uint32_t enable;
+	uint32_t period;
+	uint32_t txq_limit;
+	uint32_t tgt_backoff;
+	uint32_t tgt_report_prd;
+};
+
+/* notify MODEM power state to FW */
+typedef struct {
+	uint32_t param;
+} tSirModemPowerStateInd, *tpSirModemPowerStateInd;
+
+#ifdef WLAN_FEATURE_STATS_EXT
+typedef struct {
+	uint32_t vdev_id;
+	uint32_t event_data_len;
+	uint8_t event_data[];
+} tSirStatsExtEvent, *tpSirStatsExtEvent;
+#endif
+
+typedef struct {
+	uint32_t event_data_len;
+	uint8_t event_data[];
+} tSirNanEvent, *tpSirNanEvent;
+
+typedef struct sSirSmeRoamOffloadSynchInd {
+	uint16_t messageType;   /*eWNI_SME_ROAM_OFFLOAD_SYNCH_IND */
+	uint16_t length;
+	uint16_t beaconProbeRespOffset;
+	uint16_t beaconProbeRespLength;
+	uint16_t reassocRespOffset;
+	uint16_t reassocRespLength;
+	uint16_t reassoc_req_offset;
+	uint16_t reassoc_req_length;
+	uint8_t isBeacon;
+	uint8_t roamedVdevId;
+	struct qdf_mac_addr bssid;
+	struct qdf_mac_addr self_mac;
+	int8_t txMgmtPower;
+	uint32_t authStatus;
+	uint8_t rssi;
+	uint8_t roamReason;
+	uint32_t chan_freq;
+	uint8_t kck[SIR_KCK_KEY_LEN];
+	uint32_t kek_len;
+	uint8_t kek[SIR_KEK_KEY_LEN_FILS];
+	uint32_t   pmk_len;
+	uint8_t    pmk[SIR_PMK_LEN];
+	uint8_t    pmkid[SIR_PMKID_LEN];
+	bool update_erp_next_seq_num;
+	uint16_t next_erp_seq_num;
+	uint8_t replay_ctr[SIR_REPLAY_CTR_LEN];
+	void *add_bss_params;
+	tpSirSmeJoinRsp join_rsp;
+	uint16_t aid;
+	struct sir_hw_mode_trans_ind hw_mode_trans_ind;
+	uint8_t nss;
+	struct qdf_mac_addr dst_mac;
+	struct qdf_mac_addr src_mac;
+	uint16_t hlp_data_len;
+	uint8_t hlp_data[FILS_MAX_HLP_DATA_LEN];
+} roam_offload_synch_ind;
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+typedef struct sSirSmeRoamOffloadSynchCnf {
+	uint8_t sessionId;
+} tSirSmeRoamOffloadSynchCnf, *tpSirSmeRoamOffloadSynchCnf;
+
+typedef struct sSirSmeHOFailureInd {
+	uint8_t sessionId;
+} tSirSmeHOFailureInd, *tpSirSmeHOFailureInd;
+
+struct roam_offload_synch_fail {
+	uint8_t session_id;
+};
+
+#endif
+
+/**
+ * struct sir_wisa_params - WISA Mode Parameters
+ * @mode: WISA mode
+ * @session_id: Session ID of vdev
+ */
+struct sir_wisa_params {
+	bool mode;
+	uint8_t vdev_id;
+};
+
+#ifdef FEATURE_WLAN_EXTSCAN
+
+#define WLAN_EXTSCAN_MAX_CHANNELS                 36
+#define WLAN_EXTSCAN_MAX_BUCKETS                  16
+#define WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS   64
+
+typedef enum {
+	eSIR_EXTSCAN_INVALID,
+	eSIR_EXTSCAN_START_RSP,
+	eSIR_EXTSCAN_STOP_RSP,
+	eSIR_EXTSCAN_CACHED_RESULTS_RSP,
+	eSIR_EXTSCAN_SET_BSSID_HOTLIST_RSP,
+	eSIR_EXTSCAN_RESET_BSSID_HOTLIST_RSP,
+	eSIR_EXTSCAN_SET_SIGNIFICANT_WIFI_CHANGE_RSP,
+	eSIR_EXTSCAN_RESET_SIGNIFICANT_WIFI_CHANGE_RSP,
+
+	eSIR_EXTSCAN_GET_CAPABILITIES_IND,
+	eSIR_EXTSCAN_HOTLIST_MATCH_IND,
+	eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND,
+	eSIR_EXTSCAN_CACHED_RESULTS_IND,
+	eSIR_EXTSCAN_SCAN_RES_AVAILABLE_IND,
+	eSIR_EXTSCAN_SCAN_PROGRESS_EVENT_IND,
+	eSIR_EXTSCAN_FULL_SCAN_RESULT_IND,
+	eSIR_EPNO_NETWORK_FOUND_IND,
+	eSIR_PASSPOINT_NETWORK_FOUND_IND,
+	eSIR_EXTSCAN_SET_SSID_HOTLIST_RSP,
+	eSIR_EXTSCAN_RESET_SSID_HOTLIST_RSP,
+
+	/* Keep this last */
+	eSIR_EXTSCAN_CALLBACK_TYPE_MAX,
+} tSirExtScanCallbackType;
+
+/**
+ * typedef enum wifi_scan_flags - wifi scan flags
+ * @WIFI_SCAN_FLAG_INTERRUPTED: Indicates that scan results are not complete
+ *				because probes were not sent on some channels
+ */
+typedef enum {
+	WIFI_SCAN_FLAG_INTERRUPTED = 1,
+} wifi_scan_flags;
+
+typedef enum {
+	WIFI_BAND_UNSPECIFIED,
+	WIFI_BAND_BG = 1,       /* 2.4 GHz */
+	WIFI_BAND_A = 2,        /* 5 GHz without DFS */
+	WIFI_BAND_ABG = 3,      /* 2.4 GHz + 5 GHz; no DFS */
+	WIFI_BAND_A_DFS_ONLY = 4,       /* 5 GHz DFS only */
+	/* 5 is reserved */
+	WIFI_BAND_A_WITH_DFS = 6,       /* 5 GHz with DFS */
+	WIFI_BAND_ABG_WITH_DFS = 7,     /* 2.4 GHz + 5 GHz with DFS */
+
+	/* Keep it last */
+	WIFI_BAND_MAX
+} tWifiBand;
+
+/**
+ * enum wifi_extscan_event_type - extscan event type
+ * @WIFI_EXTSCAN_RESULTS_AVAILABLE: reported when REPORT_EVENTS_EACH_SCAN is set
+ *		and a scan cycle completes. WIFI_SCAN_THRESHOLD_NUM_SCANS or
+ *		WIFI_SCAN_THRESHOLD_PERCENT can be reported instead if the
+ *		reason for the event is available; however, at most one of
+ *		these events should be reported per scan.
+ * @WIFI_EXTSCAN_THRESHOLD_NUM_SCANS: can be reported when
+ *		REPORT_EVENTS_EACH_SCAN is not set and
+ *		report_threshold_num_scans is reached.
+ * @WIFI_EXTSCAN_THRESHOLD_PERCENT: can be reported when REPORT_EVENTS_EACH_SCAN
+ *		is not set and report_threshold_percent is reached.
+ * @WIFI_SCAN_DISABLED: reported when currently executing gscans are disabled
+ *		start_gscan will need to be called again in order to continue
+ *		scanning.
+ * @WIFI_EXTSCAN_BUCKET_STARTED_EVENT: Bucket started event
+ *		This event is consumed in driver only.
+ * @WIFI_EXTSCAN_CYCLE_STARTED_EVENT: Cycle started event.
+ *		This event is consumed in driver only.
+ * @WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT: Cycle complete event. This event
+ *		triggers @WIFI_EXTSCAN_RESULTS_AVAILABLE to the user space.
+ */
+enum wifi_extscan_event_type {
+	WIFI_EXTSCAN_RESULTS_AVAILABLE,
+	WIFI_EXTSCAN_THRESHOLD_NUM_SCANS,
+	WIFI_EXTSCAN_THRESHOLD_PERCENT,
+	WIFI_SCAN_DISABLED,
+
+	WIFI_EXTSCAN_BUCKET_STARTED_EVENT = 0x10,
+	WIFI_EXTSCAN_CYCLE_STARTED_EVENT,
+	WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT,
+};
+
+/**
+ * enum extscan_configuration_flags - extscan config flags
+ * @EXTSCAN_LP_EXTENDED_BATCHING: extended batching
+ */
+enum extscan_configuration_flags {
+	EXTSCAN_LP_EXTENDED_BATCHING = 0x00000001,
+};
+
+/**
+ * struct ext_scan_capabilities_response - extscan capabilities response data
+ * @requestId: request identifier
+ * @status:    status
+ * @max_scan_cache_size: total space allocated for scan (in bytes)
+ * @max_scan_buckets: maximum number of channel buckets
+ * @max_ap_cache_per_scan: maximum number of APs that can be stored per scan
+ * @max_rssi_sample_size: number of RSSI samples used for averaging RSSI
+ * @ax_scan_reporting_threshold: max possible report_threshold
+ * @max_hotlist_bssids: maximum number of entries for hotlist APs
+ * @max_significant_wifi_change_aps: maximum number of entries for
+ *				significant wifi change APs
+ * @max_bssid_history_entries: number of BSSID/RSSI entries that device can hold
+ * @max_hotlist_ssids: maximum number of entries for hotlist SSIDs
+ * @max_number_epno_networks: max number of epno entries
+ * @max_number_epno_networks_by_ssid: max number of epno entries
+ *			if ssid is specified, that is, epno entries for
+ *			which an exact match is required,
+ *			or entries corresponding to hidden ssids
+ * @max_number_of_white_listed_ssid: max number of white listed SSIDs
+ * @max_number_of_black_listed_bssid: max number of black listed BSSIDs
+ */
+struct ext_scan_capabilities_response {
+	uint32_t requestId;
+	uint32_t status;
+
+	uint32_t max_scan_cache_size;
+	uint32_t max_scan_buckets;
+	uint32_t max_ap_cache_per_scan;
+	uint32_t max_rssi_sample_size;
+	uint32_t max_scan_reporting_threshold;
+
+	uint32_t max_hotlist_bssids;
+	uint32_t max_significant_wifi_change_aps;
+
+	uint32_t max_bssid_history_entries;
+	uint32_t max_hotlist_ssids;
+	uint32_t max_number_epno_networks;
+	uint32_t max_number_epno_networks_by_ssid;
+	uint32_t max_number_of_white_listed_ssid;
+	uint32_t max_number_of_black_listed_bssid;
+};
+
+typedef struct {
+	uint32_t requestId;
+	uint32_t status;
+} tSirExtScanGetCachedResultsRspParams, *tpSirExtScanGetCachedResultsRspParams;
+
+typedef struct {
+	/* Time of discovery */
+	uint64_t ts;
+
+	/* Null terminated SSID */
+	uint8_t ssid[SIR_MAC_MAX_SSID_LENGTH + 1];
+
+	struct qdf_mac_addr bssid;
+
+	/* Frequency in MHz */
+	uint32_t channel;
+
+	/* RSSI in dBm */
+	int32_t rssi;
+
+	/* RTT in nanoseconds */
+	uint32_t rtt;
+
+	/* Standard deviation in rtt */
+	uint32_t rtt_sd;
+
+	/* Period advertised in the beacon */
+	uint16_t beaconPeriod;
+
+	/* Capabilities advertised in the beacon */
+	uint16_t capability;
+
+	uint16_t ieLength;
+
+	uint8_t ieData[];
+} tSirWifiScanResult, *tpSirWifiScanResult;
+
+/**
+ * struct extscan_hotlist_match - extscan hotlist match
+ * @requestId: request identifier
+ * @numOfAps: number of bssids retrieved by the scan
+ * @moreData: 0 - for last fragment
+ *	      1 - still more fragment(s) coming
+ * @ap: wifi scan result
+ */
+struct extscan_hotlist_match {
+	uint32_t    requestId;
+	bool        moreData;
+	bool        ap_found;
+	uint32_t    numOfAps;
+	tSirWifiScanResult   ap[];
+};
+
+/**
+ * struct extscan_cached_scan_result - extscan cached scan result
+ * @scan_id: a unique identifier for the scan unit
+ * @flags: a bitmask with additional information about scan
+ * @num_results: number of bssids retrieved by the scan
+ * @buckets_scanned: bitmask of buckets scanned in current extscan cycle
+ * @ap: wifi scan bssid results info
+ */
+struct extscan_cached_scan_result {
+	uint32_t    scan_id;
+	uint32_t    flags;
+	uint32_t    num_results;
+	uint32_t    buckets_scanned;
+	tSirWifiScanResult *ap;
+};
+
+/**
+ * struct tSirWifiScanResultEvent - wifi scan result event
+ * @requestId: request identifier
+ * @ap_found: flag to indicate ap found or not
+ *		true: AP was found
+ *		false: AP was lost
+ * @numOfAps: number of aps
+ * @moreData: more data
+ * @ap: bssid information
+ *
+ */
+typedef struct {
+	uint32_t     requestId;
+	bool         ap_found;
+	uint32_t     numOfAps;
+	bool         moreData;
+	tSirWifiScanResult   ap[];
+} tSirWifiScanResultEvent, *tpSirWifiScanResultEvent;
+
+/**
+ * struct extscan_cached_scan_results - extscan cached scan results
+ * @request_id: request identifier
+ * @more_data: 0 - for last fragment
+ *	       1 - still more fragment(s) coming
+ * @num_scan_ids: number of scan ids
+ * @result: wifi scan result
+ */
+struct extscan_cached_scan_results {
+	uint32_t    request_id;
+	bool        more_data;
+	uint32_t    num_scan_ids;
+	struct extscan_cached_scan_result  *result;
+};
+
+
+/**
+ * struct tSirWifiFullScanResultEvent - extscan full scan event
+ * @request_id: request identifier
+ * @moreData: 0 - for last fragment
+ *             1 - still more fragment(s) coming
+ * @ap: bssid info
+ *
+ * Reported when each probe response is received, if report_events
+ * enabled in struct wifi_scan_cmd_req_params
+ */
+typedef struct {
+	uint32_t            requestId;
+	bool                moreData;
+	tSirWifiScanResult  ap;
+} tSirWifiFullScanResultEvent, *tpSirWifiFullScanResultEvent;
+
+/**
+ * struct pno_match_found - epno match found
+ * @request_id: request identifier
+ * @moreData: 0 - for last fragment
+     * 1 - still more fragment(s) coming
+ * @num_results: number of bssids, driver sends this event to upper layer
+ *		 for every beacon, hence %num_results is always set to 1.
+ * @ap: bssid info
+ *
+ * Reported when each beacon probe response is received with
+ * epno match found tag.
+     */
+struct pno_match_found {
+	uint32_t            request_id;
+	bool                more_data;
+	uint32_t            num_results;
+	tSirWifiScanResult  ap[];
+};
+
+/**
+ * struct sir_extscan_generic_response -
+ *	Generic ExtScan Response structure
+ * @request_id: ID of the request
+ * @status: operation status returned by firmware
+ */
+struct sir_extscan_generic_response {
+	uint32_t request_id;
+	uint32_t status;
+};
+
+typedef struct {
+	struct qdf_mac_addr bssid;
+	uint32_t channel;
+	uint32_t numOfRssi;
+
+	/* Rssi history in db */
+	int32_t rssi[];
+} tSirWifiSignificantChange, *tpSirWifiSignificantChange;
+
+typedef struct {
+	uint32_t requestId;
+
+	bool moreData;
+	uint32_t numResults;
+	tSirWifiSignificantChange ap[];
+} tSirWifiSignificantChangeEvent, *tpSirWifiSignificantChangeEvent;
+
+typedef struct {
+	uint32_t requestId;
+	uint32_t numResultsAvailable;
+} tSirExtScanResultsAvailableIndParams, *tpSirExtScanResultsAvailableIndParams;
+
+typedef struct {
+	uint32_t requestId;
+	uint32_t status;
+	uint8_t scanEventType;
+	uint32_t   buckets_scanned;
+} tSirExtScanOnScanEventIndParams, *tpSirExtScanOnScanEventIndParams;
+
+#define MAX_EPNO_NETWORKS 64
+
+#define SIR_PASSPOINT_LIST_MAX_NETWORKS 8
+
+/**
+ * struct wifi_passpoint_match - wifi passpoint network match
+ * @id: network block identifier for the matched network
+ * @anqp_len: length of ANQP blob
+ * @ap: scan result, with channel and beacon information
+ * @anqp: ANQP data, in the information_element format
+ */
+struct wifi_passpoint_match {
+	uint32_t  request_id;
+	uint32_t  id;
+	uint32_t  anqp_len;
+	tSirWifiScanResult ap;
+	uint8_t   anqp[];
+};
+#endif /* FEATURE_WLAN_EXTSCAN */
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+typedef struct {
+	uint32_t timer_val;
+} tSirAutoShutdownCmdParams;
+
+typedef struct {
+	uint32_t shutdown_reason;
+} tSirAutoShutdownEvtParams;
+#endif
+
+#ifdef WLAN_POWER_DEBUGFS
+/**
+ * struct power_stats_response - Power stats response
+ * @cumulative_sleep_time_ms: cumulative sleep time in ms
+ * @cumulative_total_on_time_ms: total awake time in ms
+ * @deep_sleep_enter_counter: deep sleep enter counter
+ * @last_deep_sleep_enter_tstamp_ms: last deep sleep enter timestamp
+ * @debug_register_fmt: debug registers format
+ * @num_debug_register: number of debug registers
+ * @debug_registers: Pointer to the debug registers buffer
+ */
+struct power_stats_response {
+	uint32_t cumulative_sleep_time_ms;
+	uint32_t cumulative_total_on_time_ms;
+	uint32_t deep_sleep_enter_counter;
+	uint32_t last_deep_sleep_enter_tstamp_ms;
+	uint32_t debug_register_fmt;
+	uint32_t num_debug_register;
+	uint32_t *debug_registers;
+};
+#endif
+
+/**
+ * struct lfr_firmware_status - LFR status in firmware
+ * @is_disabled: Is LFR disabled in FW
+ * @disable_lfr_event: Disable attempt done in FW
+ */
+struct lfr_firmware_status {
+	uint32_t is_disabled;
+	struct completion disable_lfr_event;
+};
+
+/**
+ * struct rso_cmd_status - RSO Command status
+ * @vdev_id: Vdev ID for which RSO command sent
+ * @status: Status of RSO command sent to FW
+ */
+struct rso_cmd_status {
+	uint32_t vdev_id;
+	bool status;
+};
+
+typedef struct {
+	uint8_t oui[WIFI_SCANNING_MAC_OUI_LENGTH];
+	uint32_t vdev_id;
+	bool enb_probe_req_sno_randomization;
+	struct probe_req_whitelist_attr ie_whitelist;
+} tSirScanMacOui, *tpSirScanMacOui;
+
+enum {
+	SIR_AP_RX_DATA_OFFLOAD             = 0x00,
+	SIR_STA_RX_DATA_OFFLOAD            = 0x01,
+};
+
+/**
+ * struct sir_set_vdev_ies_per_band
+ * @msg_type: message type
+ * @len: message length
+ * @vdev_id: vdev id
+ *
+ * Message wrapper structure for eWNI_SME_SET_VDEV_IES_PER_BAND.
+ */
+struct sir_set_vdev_ies_per_band {
+	uint16_t msg_type;
+	uint16_t len;
+	uint32_t vdev_id;
+};
+
+/**
+ * struct sir_set_ht_vht_cfg - ht, vht IE config
+ * @msg_type: message type
+ * @len: message length
+ * @pdev_id: pdev id
+ * @nss: Nss value
+ * @dot11mode: Dot11 mode.
+ *
+ * Message wrapper structure for set HT/VHT IE req.
+ */
+struct sir_set_ht_vht_cfg {
+	uint16_t msg_type;
+	uint16_t len;
+	uint32_t pdev_id;
+	uint32_t nss;
+	uint32_t dot11mode;
+};
+
+#define WIFI_INVALID_PEER_ID            (-1)
+#define WIFI_INVALID_VDEV_ID            (-1)
+#define WIFI_MAX_AC                     (4)
+
+typedef struct {
+	uint32_t paramId;
+	uint8_t ifaceId;
+	uint32_t rspId;
+	uint32_t moreResultToFollow;
+	uint32_t nr_received;
+	union {
+		uint32_t num_peers;
+		uint32_t num_radio;
+	};
+
+	uint32_t peer_event_number;
+	/* Variable  length field - Do not add anything after this */
+	uint8_t results[0];
+} tSirLLStatsResults, *tpSirLLStatsResults;
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+/*---------------------------------------------------------------------------
+   WLAN_HAL_LL_NOTIFY_STATS
+   ---------------------------------------------------------------------------*/
+
+/******************************LINK LAYER Statistics**********************/
+
+typedef int tSirWifiRadio;
+typedef int tSirWifiChannel;
+typedef int tSirwifiTxRate;
+
+typedef struct {
+	uint32_t reqId;
+	uint8_t staId;
+	uint32_t mpduSizeThreshold;
+	uint32_t aggressiveStatisticsGathering;
+} tSirLLStatsSetReq, *tpSirLLStatsSetReq;
+
+typedef struct {
+	uint32_t reqId;
+	uint8_t staId;
+	uint32_t paramIdMask;
+} tSirLLStatsGetReq, *tpSirLLStatsGetReq;
+
+typedef struct {
+	uint32_t reqId;
+	uint8_t staId;
+	uint32_t statsClearReqMask;
+	uint8_t stopReq;
+} tSirLLStatsClearReq, *tpSirLLStatsClearReq;
+
+/* channel operating width */
+typedef enum {
+	WIFI_CHAN_WIDTH_20 = 0,
+	WIFI_CHAN_WIDTH_40 = 1,
+	WIFI_CHAN_WIDTH_80 = 2,
+	WIFI_CHAN_WIDTH_160 = 3,
+	WIFI_CHAN_WIDTH_80P80 = 4,
+	WIFI_CHAN_WIDTH_5 = 5,
+	WIFI_CHAN_WIDTH_10 = 6,
+} tSirWifiChannelWidth;
+
+typedef enum {
+	WIFI_DISCONNECTED = 0,
+	WIFI_AUTHENTICATING = 1,
+	WIFI_ASSOCIATING = 2,
+	WIFI_ASSOCIATED = 3,
+	WIFI_EAPOL_STARTED = 4, /* if done by firmware/driver */
+	WIFI_EAPOL_COMPLETED = 5,       /* if done by firmware/driver */
+} tSirWifiConnectionState;
+
+typedef enum {
+	WIFI_ROAMING_IDLE = 0,
+	WIFI_ROAMING_ACTIVE = 1,
+} tSirWifiRoamState;
+
+typedef enum {
+	WIFI_INTERFACE_STA = 0,
+	WIFI_INTERFACE_SOFTAP = 1,
+	WIFI_INTERFACE_IBSS = 2,
+	WIFI_INTERFACE_P2P_CLIENT = 3,
+	WIFI_INTERFACE_P2P_GO = 4,
+	WIFI_INTERFACE_NAN = 5,
+	WIFI_INTERFACE_MESH = 6,
+	WIFI_INTERFACE_NDI = 7,
+} tSirWifiInterfaceMode;
+
+/* set for QOS association */
+#define WIFI_CAPABILITY_QOS          0x00000001
+/* set for protected assoc (802.11 beacon frame control protected bit set) */
+#define WIFI_CAPABILITY_PROTECTED    0x00000002
+/* set if 802.11 Extended Capabilities element interworking bit is set */
+#define WIFI_CAPABILITY_INTERWORKING 0x00000004
+/* set for HS20 association */
+#define WIFI_CAPABILITY_HS20         0x00000008
+/* set is 802.11 Extended Capabilities element UTF-8 SSID bit is set */
+#define WIFI_CAPABILITY_SSID_UTF8    0x00000010
+/* set is 802.11 Country Element is present */
+#define WIFI_CAPABILITY_COUNTRY      0x00000020
+
+typedef struct {
+	/* tSirWifiInterfaceMode */
+	/* interface mode */
+	uint8_t mode;
+	/* interface mac address (self) */
+	struct qdf_mac_addr macAddr;
+	/* tSirWifiConnectionState */
+	/* connection state (valid for STA, CLI only) */
+	uint8_t state;
+	/* tSirWifiRoamState */
+	/* roaming state */
+	uint32_t roaming;
+	/* WIFI_CAPABILITY_XXX (self) */
+	uint32_t capabilities;
+	/* null terminated SSID */
+	uint8_t ssid[33];
+	/* bssid */
+	struct qdf_mac_addr bssid;
+	/* country string advertised by AP */
+	uint8_t apCountryStr[WNI_CFG_COUNTRY_CODE_LEN];
+	/* country string for this association */
+	uint8_t countryStr[WNI_CFG_COUNTRY_CODE_LEN];
+} tSirWifiInterfaceInfo, *tpSirWifiInterfaceInfo;
+
+/* channel information */
+typedef struct {
+	/* channel width (20, 40, 80, 80+80, 160) */
+	tSirWifiChannelWidth width;
+	/* primary 20 MHz channel */
+	tSirWifiChannel centerFreq;
+	/* center frequency (MHz) first segment */
+	tSirWifiChannel centerFreq0;
+	/* center frequency (MHz) second segment */
+	tSirWifiChannel centerFreq1;
+} tSirWifiChannelInfo, *tpSirWifiChannelInfo;
+
+/* wifi rate info */
+typedef struct {
+	/* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */
+	uint32_t preamble:3;
+	/* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */
+	uint32_t nss:2;
+	/* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */
+	uint32_t bw:3;
+	/* OFDM/CCK rate code would be as per ieee std in units of 0.5mbps */
+	/* HT/VHT it would be mcs index */
+	uint32_t rateMcsIdx:8;
+	/* reserved */
+	uint32_t reserved:16;
+	/* units of 100 Kbps */
+	uint32_t bitrate;
+} tSirWifiRate, *tpSirWifiRate;
+
+/* channel statistics */
+typedef struct {
+	/* channel */
+	tSirWifiChannelInfo channel;
+	/* msecs the radio is awake (32 bits number accruing over time) */
+	uint32_t onTime;
+	/* msecs the CCA register is busy (32 bits number accruing over time) */
+	uint32_t ccaBusyTime;
+} tSirWifiChannelStats, *tpSirWifiChannelStats;
+
+#define MAX_TPC_LEVELS 64
+/* radio statistics */
+typedef struct {
+	/* wifi radio (if multiple radio supported) */
+	tSirWifiRadio radio;
+	/* msecs the radio is awake (32 bits number accruing over time) */
+	uint32_t onTime;
+	/* msecs the radio is transmitting
+	 * (32 bits number accruing over time)
+	 */
+	uint32_t txTime;
+	/* msecs the radio is in active receive
+	   *(32 bits number accruing over time)
+	 */
+	uint32_t rxTime;
+	/* msecs the radio is awake due to all scan
+	 * (32 bits number accruing over time)
+	 */
+	uint32_t onTimeScan;
+	/* msecs the radio is awake due to NAN
+	 * (32 bits number accruing over time)
+	 */
+	uint32_t onTimeNbd;
+	/* msecs the radio is awake due to Gscan
+	 * (32 bits number accruing over time)
+	 */
+	uint32_t onTimeGscan;
+	/* msecs the radio is awake due to roam?scan
+	 * (32 bits number accruing over time)
+	 */
+	uint32_t onTimeRoamScan;
+	/* msecs the radio is awake due to PNO scan
+	 * (32 bits number accruing over time)
+	 */
+	uint32_t onTimePnoScan;
+	/* msecs the radio is awake due to HS2.0 scans and GAS exchange
+	 * (32 bits number accruing over time)
+	 */
+	uint32_t onTimeHs20;
+
+	/* tx time (in milliseconds) per TPC level (0.5 dBm) */
+	uint32_t total_num_tx_power_levels;
+	uint32_t *tx_time_per_power_level;
+
+	/* number of channels */
+	uint32_t numChannels;
+
+	/* tx time (in milliseconds) per TPC level (0.5 dBm) */
+	uint32_t tx_time_per_tpc[MAX_TPC_LEVELS];
+
+	uint32_t on_time_host_scan;
+	uint32_t on_time_lpi_scan;
+
+	/* channel statistics tSirWifiChannelStats */
+	tSirWifiChannelStats *channels;
+} tSirWifiRadioStat, *tpSirWifiRadioStat;
+
+/* per rate statistics */
+typedef struct {
+	/* rate information */
+	tSirWifiRate rate;
+	/* number of successfully transmitted data pkts (ACK rcvd) */
+	uint32_t txMpdu;
+	/* number of received data pkts */
+	uint32_t rxMpdu;
+	/* number of data packet losses (no ACK) */
+	uint32_t mpduLost;
+	/* total number of data pkt retries * */
+	uint32_t retries;
+	/* number of short data pkt retries */
+	uint32_t retriesShort;
+	/* number of long data pkt retries */
+	uint32_t retriesLong;
+} tSirWifiRateStat, *tpSirWifiRateStat;
+
+/* wifi peer type */
+typedef enum {
+	WIFI_PEER_STA,
+	WIFI_PEER_AP,
+	WIFI_PEER_P2P_GO,
+	WIFI_PEER_P2P_CLIENT,
+	WIFI_PEER_NAN,
+	WIFI_PEER_TDLS,
+	WIFI_PEER_INVALID,
+} tSirWifiPeerType;
+
+/* per peer statistics */
+typedef struct {
+	/* peer type (AP, TDLS, GO etc.) */
+	enum wmi_peer_type type;
+	/* mac address */
+	struct qdf_mac_addr peerMacAddress;
+	/* peer WIFI_CAPABILITY_XXX */
+	uint32_t capabilities;
+	union {
+		/* peer power saving mode */
+		uint32_t power_saving;
+		/* number of rates */
+		uint32_t numRate;
+	};
+	/* per rate statistics, number of entries  = num_rate */
+	tSirWifiRateStat rateStats[0];
+} tSirWifiPeerInfo, *tpSirWifiPeerInfo;
+
+/* Interface statistics - corresponding to 2nd most
+ * LSB in wifi statistics bitmap  for getting statistics
+ */
+typedef struct {
+	/* current state of the interface */
+	tSirWifiInterfaceInfo info;
+
+	uint32_t rts_succ_cnt;
+	uint32_t rts_fail_cnt;
+	uint32_t ppdu_succ_cnt;
+	uint32_t ppdu_fail_cnt;
+
+	/* link statistics */
+	wmi_iface_link_stats link_stats;
+
+	/* per ac data packet statistics */
+	wmi_wmm_ac_stats ac_stats[WIFI_AC_MAX];
+
+	uint32_t num_offload_stats;
+	wmi_iface_offload_stats offload_stats[WMI_OFFLOAD_STATS_TYPE_MAX];
+} tSirWifiIfaceStat, *tpSirWifiIfaceStat;
+
+/* Peer statistics - corresponding to 3rd most LSB in
+ * wifi statistics bitmap  for getting statistics
+ */
+typedef struct {
+	/* number of peers */
+	uint32_t numPeers;
+	/* per peer statistics */
+	tSirWifiPeerInfo peerInfo[0];
+} tSirWifiPeerStat, *tpSirWifiPeerStat;
+
+/* wifi statistics bitmap  for getting statistics */
+#define WMI_LINK_STATS_RADIO          0x00000001
+#define WMI_LINK_STATS_IFACE          0x00000002
+#define WMI_LINK_STATS_ALL_PEER       0x00000004
+#define WMI_LINK_STATS_PER_PEER       0x00000008
+
+/* wifi statistics bitmap  for clearing statistics */
+/* all radio statistics */
+#define WIFI_STATS_RADIO              0x00000001
+/* cca_busy_time (within radio statistics) */
+#define WIFI_STATS_RADIO_CCA          0x00000002
+/* all channel statistics (within radio statistics) */
+#define WIFI_STATS_RADIO_CHANNELS     0x00000004
+/* all scan statistics (within radio statistics) */
+#define WIFI_STATS_RADIO_SCAN         0x00000008
+/* all interface statistics */
+#define WIFI_STATS_IFACE              0x00000010
+/* all tx rate statistics (within interface statistics) */
+#define WIFI_STATS_IFACE_TXRATE       0x00000020
+/* all ac statistics (within interface statistics) */
+#define WIFI_STATS_IFACE_AC           0x00000040
+/* all contention (min, max, avg) statistics (within ac statistics) */
+#define WIFI_STATS_IFACE_CONTENTION   0x00000080
+/* All peer stats on this interface */
+#define WIFI_STATS_IFACE_ALL_PEER      0x00000100
+/* Clear particular peer stats depending on the peer_mac */
+#define WIFI_STATS_IFACE_PER_PEER      0x00000200
+
+/**
+ * struct sir_wifi_iface_tx_fail - TX failure event
+ * @tid: TX TID
+ * @msdu_num: TX MSDU failed counter
+ * @status: TX status from HTT message.
+ *          Only failure status will be involved.
+ */
+struct sir_wifi_iface_tx_fail {
+	uint8_t  tid;
+	uint16_t msdu_num;
+	enum htt_tx_status status;
+};
+
+/**
+ * struct sir_wifi_chan_cca_stats - channal CCA stats
+ * @vdev_id: vdev ID
+ * @idle_time: percentage of idle time, no TX, no RX, no interference
+ * @tx_time: percentage of time transmitting packets
+ * @rx_in_bss_time: percentage of time receiving packets in current BSS
+ * @rx_out_bss_time: percentage of time receiving packets not in current BSS
+ * @rx_busy_time: percentage of time interference detected
+ * @rx_in_bad_cond_time: percentage of time receiving packets with errors
+ *	or packets flagged as retransmission or seqnum discontinued.
+ * @tx_in_bad_cond_time: percentage of time the device transmitted packets
+ *	that haven't been ACKed.
+ * @wlan_not_avail_time: percentage of time the chip is unable to
+ *	work in normal conditions.
+ */
+struct sir_wifi_chan_cca_stats {
+	uint32_t vdev_id;
+	uint32_t idle_time;
+	uint32_t tx_time;
+	uint32_t rx_in_bss_time;
+	uint32_t rx_out_bss_time;
+	uint32_t rx_busy_time;
+	uint32_t rx_in_bad_cond_time;
+	uint32_t tx_in_bad_cond_time;
+	uint32_t wlan_not_avail_time;
+};
+
+#define WIFI_MAX_CHAINS                 8
+
+/**
+ * struct sir_wifi_peer_signal_stats - peer signal stats
+ * @vdev_id: vdev ID
+ * @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;
+	uint32_t peer_id;
+
+	/* per antenna SNR in current bss */
+	int32_t per_ant_snr[WIFI_MAX_CHAINS];
+
+	/* 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
+#define WFIF_MCS_NUM            10
+#define WIFI_AGGR_NUM           8
+#define WIFI_DELAY_SIZE         11
+
+/**
+ * struct sir_wifi_tx - per AC tx stats
+ * @msdus: number of totoal MSDUs on MAC layer in the period
+ * @mpdus: number of totoal MPDUs on MAC layer in the period
+ * @ppdus: number of totoal PPDUs on PHY layer in the period
+ * @bytes: bytes of tx data on MAC layer in the period
+ * @drops: number of TX packets cancelled due to any reason in the period,
+ *	such as WMM limitation/bandwidth limitation/radio congestion
+ * @drop_bytes: bytes of dropped TX packets in the period
+ * @retries: number of unacked transmissions of MPDUs
+ * @failed: number of packets have not been ACKed despite retried
+ * @aggr_len: length of the MPDU aggregation size buffer
+ * @mpdu_aggr_size: histogram of MPDU aggregation size
+ * @success_mcs_len: length of success mcs buffer
+ * @success_mcs: histogram of successed received MPDUs encoding rate
+ * @fail_mcs_len: length of failed mcs buffer
+ * @fail_mcs: histogram of failed received MPDUs encoding rate
+ * @delay_len: length of the delay histofram buffer
+ * @delay: histogram of delays on MAC layer
+ */
+struct sir_wifi_tx {
+	uint32_t msdus;
+	uint32_t mpdus;
+	uint32_t ppdus;
+	uint32_t bytes;
+	uint32_t drops;
+	uint32_t drop_bytes;
+	uint32_t retries;
+	uint32_t failed;
+	uint32_t aggr_len;
+	uint32_t *mpdu_aggr_size;
+	uint32_t success_mcs_len;
+	uint32_t *success_mcs;
+	uint32_t fail_mcs_len;
+	uint32_t *fail_mcs;
+	uint32_t delay_len;
+	uint32_t *delay;
+};
+
+/**
+ * struct sir_wifi_rx - per AC rx stats
+ * @mpdus: number of RX packets on MAC layer
+ * @bytes: bytes of RX packets on MAC layer
+ * @ppdus: number of RX packets on PHY layer
+ * @ppdu_bytes: bytes of RX packets on PHY layer
+ * @mpdu_lost: number of discontinuity in seqnum
+ * @mpdu_retry: number of RX packets flagged as retransmissions
+ * @mpdu_dup: number of RX packets identified as duplicates
+ * @mpdu_discard: number of RX packets discarded
+ * @aggr_len: length of MPDU aggregation histogram buffer
+ * @mpdu_aggr: histogram of MPDU aggregation size
+ * @mcs_len: length of mcs histogram buffer
+ * @mcs: histogram of encoding rate.
+ */
+struct sir_wifi_rx {
+	uint32_t mpdus;
+	uint32_t bytes;
+	uint32_t ppdus;
+	uint32_t ppdu_bytes;
+	uint32_t mpdu_lost;
+	uint32_t mpdu_retry;
+	uint32_t mpdu_dup;
+	uint32_t mpdu_discard;
+	uint32_t aggr_len;
+	uint32_t *mpdu_aggr;
+	uint32_t mcs_len;
+	uint32_t *mcs;
+};
+
+/**
+ * struct sir_wifi_ll_ext_wmm_ac_stats - stats for WMM AC
+ * @type: WMM AC type
+ * @tx_stats: pointer to TX stats
+ * @rx_stats: pointer to RX stats
+ */
+struct sir_wifi_ll_ext_wmm_ac_stats {
+	uint32_t type;
+	struct sir_wifi_tx *tx_stats;
+	struct sir_wifi_rx *rx_stats;
+};
+
+/**
+ * struct sir_wifi_ll_ext_peer_stats - per peer stats
+ * @peer_id: peer ID
+ * @vdev_id: VDEV ID
+ * mac_address: MAC address
+ * @sta_ps_inds: how many times STAs go to sleep
+ * @sta_ps_durs: total sleep time of STAs (units in ms)
+ * @rx_probe_reqs: number of probe requests received
+ * @rx_oth_mgmts: number of other management frames received,
+ *		  not including probe requests
+ * @peer_signal_stat: signal stats
+ * @ac_stats: WMM BE/BK/VI/VO stats
+ */
+struct sir_wifi_ll_ext_peer_stats {
+	uint32_t peer_id;
+	uint32_t vdev_id;
+	tSirMacAddr mac_address;
+	uint32_t sta_ps_inds;
+	uint32_t sta_ps_durs;
+	uint32_t rx_probe_reqs;
+	uint32_t rx_oth_mgmts;
+	struct sir_wifi_peer_signal_stats peer_signal_stats;
+	struct sir_wifi_ll_ext_wmm_ac_stats ac_stats[WIFI_MAX_AC];
+};
+
+/**
+ * struct sir_wifi_ll_ext_stats - link layer stats report
+ * @trigger_cond_id:  Indicate what triggered this event.
+ *	1: timeout. 2: threshold
+ * @cca_chgd_bitmap: Bitmap to indicate changed channel CCA stats
+ *	which exceeded the thresholds
+ * @sig_chgd_bitmap: Bitmap to indicate changed peer signal stats
+ *	which exceeded the thresholds
+ * @tx_chgd_bitmap: Bitmap to indicate changed TX counters
+ *	which exceeded the thresholds
+ * @rx_chgd_bitmap: Bitmap to indicate changed RX counters
+ *	which exceeded the thresholds
+ * @chan_cca_stats: channel CCA stats
+ * @peer_signal_stats: peer signal stats
+ * @tx_mpdu_aggr_array_len: length of TX MPDU aggregation buffer
+ * @tx_succ_mcs_array_len: length of mcs buffer for ACKed MPDUs
+ * @tx_fail_mcs_array_len: length of mcs buffer for no-ACKed MPDUs
+ * @tx_delay_array_len: length of delay stats buffer
+ * @rx_mpdu_aggr_array_len: length of RX MPDU aggregation buffer
+ * @rx_mcs_array_len: length of RX mcs stats buffer
+ * @peer_stats: peer stats
+ * @cca: physical channel CCA stats
+ * @stats: pointer to stats data buffer.
+ *
+ * Structure of the whole statictics is like this:
+ *     ---------------------------------
+ *     |      trigger_cond_i           |
+ *     +-------------------------------+
+ *     |      cca_chgd_bitmap          |
+ *     +-------------------------------+
+ *     |      sig_chgd_bitmap          |
+ *     +-------------------------------+
+ *     |      tx_chgd_bitmap           |
+ *     +-------------------------------+
+ *     |      rx_chgd_bitmap           |
+ *     +-------------------------------+
+ *     |      peer_num                 |
+ *     +-------------------------------+
+ *     |      channel_num              |
+ *     +-------------------------------+
+ *     |      tx_mpdu_aggr_array_len   |
+ *     +-------------------------------+
+ *     |      tx_succ_mcs_array_len    |
+ *     +-------------------------------+
+ *     |      tx_fail_mcs_array_len    |
+ *     +-------------------------------+
+ *     |      tx_delay_array_len       |
+ *     +-------------------------------+
+ *     |      rx_mpdu_aggr_array_len   |
+ *     +-------------------------------+
+ *     |      rx_mcs_array_len         |
+ *     +-------------------------------+
+ *     |      pointer to CCA stats     |
+ *     +-------------------------------+
+ *     |      pointer to peer stats    |
+ *     +-------------------------------+
+ *     |      CCA stats                |
+ *     +-------------------------------+
+ *     |      peer_stats               |----+
+ *     +-------------------------------+    |
+ *     |      per peer signals stats   |<---+
+ *     |        peer0 ~ peern          |    |
+ *     +-------------------------------+    |
+ *     | TX aggr/mcs parameters array  |    |
+ *     | Length of this buffer is      |    |
+ *     | configurable for user layer.  |<-+ |
+ *     +-------------------------------+  | |
+ *     |      per peer tx stats        |--+ |
+ *     |         BE                    | <--+
+ *     |         BK                    |    |
+ *     |         VI                    |    |
+ *     |         VO                    |    |
+ *     +-------------------------------+    |
+ *     | TX aggr/mcs parameters array  |    |
+ *     | Length of this buffer is      |    |
+ *     | configurable for user layer.  |<-+ |
+ *     +-------------------------------+  | |
+ *     |      peer peer rx stats       |--+ |
+ *     |         BE                    | <--+
+ *     |         BE                    |
+ *     |         BK                    |
+ *     |         VI                    |
+ *     |         VO                    |
+ *     ---------------------------------
+ */
+struct sir_wifi_ll_ext_stats {
+	uint32_t trigger_cond_id;
+	uint32_t cca_chgd_bitmap;
+	uint32_t sig_chgd_bitmap;
+	uint32_t tx_chgd_bitmap;
+	uint32_t rx_chgd_bitmap;
+	uint8_t peer_num;
+	uint8_t channel_num;
+	uint32_t tx_mpdu_aggr_array_len;
+	uint32_t tx_succ_mcs_array_len;
+	uint32_t tx_fail_mcs_array_len;
+	uint32_t tx_delay_array_len;
+	uint32_t rx_mpdu_aggr_array_len;
+	uint32_t rx_mcs_array_len;
+	struct sir_wifi_ll_ext_peer_stats *peer_stats;
+	struct sir_wifi_chan_cca_stats *cca;
+	uint8_t stats[];
+};
+
+/**
+ * struct sir_channel_cca_threshold - threshold for channel CCA
+ * @idle_time: idle time, no TX, no RX, no interference
+ * @tx_time: time transmitting packets
+ * @rx_in_bss_time: time receiving packets in current BSSs
+ * @rx_out_bss_time: time receiving packets not in current BSSs
+ * @rx_busy_time: time interference detected
+ * @rx_in_bad_cond_time: receiving packets with errors
+ * @tx_in_bad_cond_time: time transmitted packets not been ACKed
+ * @wlan_not_avail_time: wlan card cannot work
+ */
+struct sir_channel_cca_threshold {
+	uint32_t idle_time;
+	uint32_t tx_time;
+	uint32_t rx_in_bss_time;
+	uint32_t rx_out_bss_time;
+	uint32_t rx_busy_time;
+	uint32_t rx_in_bad_cond_time;
+	uint32_t tx_in_bad_cond_time;
+	uint32_t wlan_not_avail_time;
+};
+
+/**
+ * struct sir_signal_threshold - threshold for per peer sigbal
+ * @snr: signal to noise rate
+ * @nf: noise floor
+ */
+struct sir_signal_threshold {
+	uint32_t snr;
+	uint32_t nf;
+};
+
+/**
+ * struct sir_tx_threshold - threshold for TX
+ * @msdu: TX MSDUs on MAC layer
+ * @mpdu: TX MPDUs on MAC layer
+ * @ppdu: TX PPDUs on MAC layer
+ * @bytes: TX bytes on MAC layer
+ * @msdu_drop: drooped MSDUs
+ * @byte_drop: dropped Bytes
+ * @mpdu_retry: MPDU not acked
+ * @ppdu_fail: PPDUs which received no block ack
+ * @aggregation: aggregation size
+ * @succ_mcs: histogram of encoding rate for acked PPDUs
+ * @fail_mcs: histogram of encoding rate for no-acked PPDUs
+ */
+struct sir_tx_threshold {
+	uint32_t msdu;
+	uint32_t mpdu;
+	uint32_t ppdu;
+	uint32_t bytes;
+	uint32_t msdu_drop;
+	uint32_t byte_drop;
+	uint32_t mpdu_retry;
+	uint32_t mpdu_fail;
+	uint32_t ppdu_fail;
+	uint32_t aggregation;
+	uint32_t succ_mcs;
+	uint32_t fail_mcs;
+	uint32_t delay;
+};
+
+/**
+ * struct sir_rx_threshold - threshold for RX
+ * @mpdu: RX MPDUs on MAC layer
+ * @bytes: RX bytes on MAC layer
+ * @ppdu: RX PPDU on PHY layer
+ * @ppdu_bytes: RX bytes on PHY layer
+ * @disorder: discontinuity in seqnum
+ * @mpdu_retry: MPDUs flagged as retry
+ * @mpdu_dup: MPDUs identified as duplicated
+ * @aggregation: aggregation size
+ * @mcs: histogram of encoding rate for PPDUs
+ * @ps_inds: power save indication
+ * @ps_durs: total time in power save
+ * @probe_reqs: probe request received
+ * @other_mgmt: other MGMT frames received
+ */
+struct sir_rx_threshold {
+	uint32_t mpdu;
+	uint32_t bytes;
+	uint32_t ppdu;
+	uint32_t ppdu_bytes;
+	uint32_t disorder;
+	uint32_t mpdu_lost;
+	uint32_t mpdu_retry;
+	uint32_t mpdu_dup;
+	uint32_t mpdu_discard;
+	uint32_t aggregation;
+	uint32_t mcs;
+	uint32_t ps_inds;
+	uint32_t ps_durs;
+	uint32_t probe_reqs;
+	uint32_t other_mgmt;
+};
+
+/**
+ * struct sir_wifi_ll_ext_stats_threshold - Threshold for stats update
+ * @period: MAC counter indication period (unit in ms)
+ * @enable: if threshold mechnism is enabled or disabled
+ * @enable_bitmap: whether dedicated threshold is enabed.
+ *     Every MAC counter has a dedicated threshold. If the dedicated
+ *     threshold is not set in the bitmap, global threshold will take
+ *     effect.
+ * @global: whether clobal threshold is enabled.
+ *     When both global and dedicated threshold are disabled, MAC counter
+ *     will indicate stats periodically.
+ * @global_threshold: global threshold value
+ * @cca_bitmap: bitmap for CCA.
+ *     Bit0: idle time
+ *     Bit1: tx time
+ *     Bit2: RX in BSS
+ *     Bit3: RX out of BSS
+ *     Bit4: medium busy
+ *     Bit5: RX bad
+ *     Bit6: TX bad
+ *     Bit7: WLAN card not available
+ * @signal_bitmap:
+ *     Bit0: Per channel SNR counter
+ *     Bit1: Per channel noise floor counter
+ * @tx_bitmap:  bitmap for TX counters
+ *     Bit0: TX counter unit in MSDU
+ *     Bit1: TX counter unit in MPDU
+ *     Bit2: TX counter unit in PPDU
+ *     Bit3: TX counter unit in byte
+ *     Bit4: Dropped MSDUs
+ *     Bit5: Dropped Bytes
+ *     Bit6: MPDU retry counter
+ *     Bit7: MPDU failure counter
+ *     Bit8: PPDU failure counter
+ *     Bit9: MPDU aggregation counter
+ *     Bit10: MCS counter for ACKed MPDUs
+ *     Bit11: MCS counter for Failed MPDUs
+ *     Bit12: TX Delay counter
+ * @rx_bitmap:bitmap for RX counters
+ *     Bit0: MAC RX counter unit in MPDU
+ *     Bit1: MAC RX counter unit in byte
+ *     Bit2: PHY RX counter unit in PPDU
+ *     Bit3: PHY RX counter unit in byte
+ *     Bit4: Disorder counter
+ *     Bit5: Retry counter
+ *     Bit6: Duplication counter
+ *     Bit7: Discard counter
+ *     Bit8: MPDU aggregation size counter
+ *     Bit9: MCS counter
+ *     Bit10: Peer STA power state change (wake to sleep) counter
+ *     Bit11: Peer STA power save counter, total time in PS mode
+ *     Bit12: Probe request counter
+ *     Bit13: Other management frames counter
+ * @cca_thresh: CCA threshold
+ * @signal_thresh: signal threshold
+ * @tx_thresh: TX threshold
+ * @rx_thresh: RX threshold
+ *
+ * Generally, Link layer statistics is reported periodically. But if the
+ * variation of one stats of compared to the pervious notification exceeds
+ * a threshold, FW will report the new stats immediately.
+ * This structure contains threshold for different counters.
+ */
+struct sir_ll_ext_stats_threshold {
+	uint32_t period;
+	uint32_t enable;
+	uint32_t enable_bitmap;
+	uint32_t global;
+	uint32_t global_threshold;
+	uint32_t cca_bitmap;
+	uint32_t signal_bitmap;
+	uint32_t tx_bitmap;
+	uint32_t rx_bitmap;
+	struct sir_channel_cca_threshold cca;
+	struct sir_signal_threshold signal;
+	struct sir_tx_threshold tx;
+	struct sir_rx_threshold rx;
+};
+
+#define LL_STATS_MIN_PERIOD          10
+#define LL_STATS_INVALID_PERIOD      0xFFFFFFFF
+
+/* Result ID for LL stats extension */
+#define WMI_LL_STATS_EXT_PS_CHG             0x00000100
+#define WMI_LL_STATS_EXT_TX_FAIL            0x00000200
+#define WMI_LL_STATS_EXT_MAC_COUNTER        0x00000400
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+typedef struct sAniGetLinkStatus {
+	uint16_t msgType;       /* message type is same as the request type */
+	uint16_t msgLen;        /* length of the entire request */
+	uint8_t linkStatus;
+	uint8_t sessionId;
+} tAniGetLinkStatus, *tpAniGetLinkStatus;
+
+#ifdef DHCP_SERVER_OFFLOAD
+typedef struct {
+	uint32_t vdev_id;
+	uint32_t dhcpSrvOffloadEnabled;
+	uint32_t dhcpClientNum;
+	uint32_t dhcpSrvIP;
+} tSirDhcpSrvOffloadInfo, *tpSirDhcpSrvOffloadInfo;
+#endif /* DHCP_SERVER_OFFLOAD */
+
+/**
+ * struct sir_lost_link_info - lost link information structure.
+ *
+ * @vdev_id: vdev_id from WMA. some modules call sessionId.
+ * @rssi: rssi at disconnection time.
+ *
+ * driver uses this structure to communicate information collected at
+ * disconnection time.
+ */
+struct sir_lost_link_info {
+	uint32_t vdev_id;
+	int32_t rssi;
+};
+
+/* find the size of given member within a structure */
+#ifndef member_size
+#define member_size(type, member) (sizeof(((type *)0)->member))
+#endif
+
+#define RTT_INVALID                     0x00
+#define RTT_TIMING_MEAS_CAPABILITY      0x01
+#define RTT_FINE_TIME_MEAS_INITIATOR_CAPABILITY 0x02
+#define RTT_FINE_TIME_MEAS_RESPONDER_CAPABILITY 0x03
+
+/**
+ * enum fine_time_meas_mask - bit mask to identify device's
+ *                            fine timing measurement capability
+ * @FINE_TIME_MEAS_STA_INITIATOR - STA role, Initiator capability is supported
+ * @FINE_TIME_MEAS_STA_RESPONDER - STA role, Responder capability is supported
+ * @FINE_TIME_MEAS_P2PCLI_INITIATOR - P2P-CLI supports initiator capability
+ * @FINE_TIME_MEAS_P2PCLI_RESPONDER - P2P-CLI supports responder capability
+ * @FINE_TIME_MEAS_P2PGO_INITIATOR - P2P-GO supports initiator capability
+ * @FINE_TIME_MEAS_P2PGO_RESPONDER - P2P-GO supports responder capability
+ * @FINE_TIME_MEAS_SAP_INITIATOR - SAP role, Initiator capability is supported
+ * @FINE_TIME_MEAS_SAP_RESPONDER - SAP role, Responder capability is supported
+ */
+enum fine_time_meas_mask {
+	FINE_TIME_MEAS_STA_INITIATOR    = (1 << (0)),
+	FINE_TIME_MEAS_STA_RESPONDER    = (1 << (1)),
+	FINE_TIME_MEAS_P2PCLI_INITIATOR = (1 << (2)),
+	FINE_TIME_MEAS_P2PCLI_RESPONDER = (1 << (3)),
+	FINE_TIME_MEAS_P2PGO_INITIATOR  = (1 << (4)),
+	FINE_TIME_MEAS_P2PGO_RESPONDER  = (1 << (5)),
+	FINE_TIME_MEAS_SAP_INITIATOR    = (1 << (6)),
+	FINE_TIME_MEAS_SAP_RESPONDER    = (1 << (7)),
+};
+
+/* number of neighbor reports that we can handle in Neighbor Report Response */
+#define MAX_SUPPORTED_NEIGHBOR_RPT 15
+
+/**
+ * struct sir_stats_avg_factor
+ * @vdev_id: session id
+ * @stats_avg_factor: average factor
+ */
+struct sir_stats_avg_factor {
+	uint8_t vdev_id;
+	uint16_t stats_avg_factor;
+};
+
+/**
+ * struct sir_guard_time_request
+ * @vdev_id: session id
+ * @guard_time: guard time
+ */
+struct sir_guard_time_request {
+	uint8_t vdev_id;
+	uint32_t guard_time;
+};
+
+/* Max number of rates allowed in Supported Rates IE */
+#define MAX_NUM_SUPPORTED_RATES (8)
+
+/*
+ * struct rssi_monitor_req - rssi monitoring
+ * @request_id: request id
+ * @session_id: session id
+ * @min_rssi: minimum rssi
+ * @max_rssi: maximum rssi
+ * @control: flag to indicate start or stop
+ */
+struct rssi_monitor_req {
+	uint32_t request_id;
+	uint32_t session_id;
+	int8_t   min_rssi;
+	int8_t   max_rssi;
+	bool     control;
+};
+
+/**
+ * struct rssi_breach_event - rssi breached event structure
+ * @request_id: request id
+ * @session_id: session id
+ * @curr_rssi: current rssi
+ * @curr_bssid: current bssid
+ */
+struct rssi_breach_event {
+	uint32_t     request_id;
+	uint32_t     session_id;
+	int8_t       curr_rssi;
+	struct qdf_mac_addr  curr_bssid;
+};
+
+/**
+ * struct chip_pwr_save_fail_detected_params - chip power save failure detected
+ * event params
+ * @failure_reason_code:failure reason code
+ * @wake_lock_bitmap:bitmap for modules voting against sleep for long duration.
+ */
+struct chip_pwr_save_fail_detected_params {
+	uint32_t     failure_reason_code;
+	uint32_t     wake_lock_bitmap[4];
+};
+
+#define MAX_NUM_FW_SEGMENTS 4
+
+/**
+ * DEFAULT_SCAN_IE_ID - Identifier for the collection of IE's added
+ * by default to the probe request
+ */
+#define DEFAULT_SCAN_IE_ID 256
+
+ /* MAX_DEFAULT_SCAN_IE_LEN - Maxmimum length of Default Scan IE's */
+#define MAX_DEFAULT_SCAN_IE_LEN 2048
+
+ /* Extended Capabilities IE header(IE Id + IE Length) length */
+#define EXT_CAP_IE_HDR_LEN 2
+
+/**
+ * struct hdd_default_scan_ie - HDD default scan IE structure
+ * @message_type: message type to be set with eWNI_SME_DEFAULT_SCAN_IE
+ * @length: length of the struct hdd_default_scan_ie
+ * @session_id: Session Id
+ * @ie_len: Default scan IE length
+ * @ie_data: Pointer to default scan IE data
+ */
+struct hdd_default_scan_ie {
+	uint16_t message_type;
+	uint16_t length;
+	uint16_t session_id;
+	uint16_t ie_len;
+	uint8_t ie_data[MAX_DEFAULT_SCAN_IE_LEN];
+};
+
+/**
+ * struct vdev_ie_info - IE info
+ * @vdev_id - vdev for which the IE is being sent
+ * @ie_id - ID of the IE
+ * @length - length of the IE data
+ * @band - indicates IE is intended for which band
+ * @data - IE data
+ *
+ * This structure is used to store the IE information.
+ */
+struct vdev_ie_info {
+	uint32_t vdev_id;
+	uint32_t ie_id;
+	uint32_t length;
+	uint32_t band;
+	uint8_t *data;
+};
+
+/**
+ * struct send_extcap_ie - used to pass send_extcap_ie msg from SME to PE
+ * @type - MSG type
+ * @length - length of the message
+ * @seesion_id - session_id for which the message is intended for
+ *
+ * This structure is used to pass send_extcap_ie msg from SME to PE
+ */
+struct send_extcap_ie {
+	uint16_t msg_type; /* eWNI_SME_SET_IE_REQ */
+	uint16_t length;
+	uint8_t session_id;
+};
+
+typedef void (*hw_mode_transition_cb)(uint32_t old_hw_mode_index,
+		uint32_t new_hw_mode_index,
+		uint32_t num_vdev_mac_entries,
+		struct policy_mgr_vdev_mac_map *vdev_mac_map);
+typedef void (*antenna_mode_cb)(uint32_t status, void *context);
+
+/**
+ * struct sir_nss_update_request
+ * @msgType: nss update msg type
+ * @msgLen: length of the msg
+ * @new_nss: new spatial stream value
+ * @vdev_id: session id
+ */
+struct sir_nss_update_request {
+	uint16_t msgType;
+	uint16_t msgLen;
+	uint8_t  new_nss;
+	uint32_t vdev_id;
+};
+
+/**
+ * enum sir_bcn_update_reason: bcn update reason
+ * @REASON_DEFAULT: reason default
+ * @REASON_NSS_UPDATE: If NSS is updated
+ * @REASON_CONFIG_UPDATE: Config update
+ * @REASON_SET_HT2040: HT2040 update
+ * @REASON_COLOR_CHANGE: Color change
+ * @REASON_CHANNEL_SWITCH: channel switch
+ */
+enum sir_bcn_update_reason {
+	REASON_DEFAULT = 0,
+	REASON_NSS_UPDATE = 1,
+	REASON_CONFIG_UPDATE = 2,
+	REASON_SET_HT2040 = 3,
+	REASON_COLOR_CHANGE = 4,
+	REASON_CHANNEL_SWITCH = 5,
+};
+
+/**
+ * struct sir_bcn_update_rsp
+ *
+ * @vdev_id: session for which bcn was updated
+ * @reason: bcn update reason
+ * @status: status of the beacon sent to FW
+ */
+struct sir_bcn_update_rsp {
+	uint8_t vdev_id;
+	enum sir_bcn_update_reason reason;
+	QDF_STATUS status;
+};
+
+/**
+ * OCB structures
+ */
+
+#define NUM_AC			(4)
+#define OCB_CHANNEL_MAX	(5)
+
+struct sir_qos_params {
+	uint8_t aifsn;
+	uint8_t cwmin;
+	uint8_t cwmax;
+};
+
+/**
+ * struct sir_ocb_set_config_response
+ * @status: response status
+ */
+struct sir_ocb_set_config_response {
+	uint8_t status;
+};
+
+/** Callback for the dcc_stats_event */
+typedef void (*dcc_stats_event_callback_t)(void *hdd_ctx, uint32_t vdev_id,
+	uint32_t num_channels, uint32_t stats_per_channel_array_len,
+	const void *stats_per_channel_array);
+
+/**
+ * struct sir_ocb_config_channel
+ * @chan_freq: frequency of the channel
+ * @bandwidth: bandwidth of the channel, either 10 or 20 MHz
+ * @mac_address: MAC address assigned to this channel
+ * @qos_params: QoS parameters
+ * @max_pwr: maximum transmit power of the channel (dBm)
+ * @min_pwr: minimum transmit power of the channel (dBm)
+ * @reg_pwr: maximum transmit power specified by the regulatory domain (dBm)
+ * @antenna_max: maximum antenna gain specified by the regulatory domain (dB)
+ */
+struct sir_ocb_config_channel {
+	uint32_t chan_freq;
+	uint32_t bandwidth;
+	struct qdf_mac_addr mac_address;
+	struct sir_qos_params qos_params[MAX_NUM_AC];
+	uint32_t max_pwr;
+	uint32_t min_pwr;
+	uint8_t reg_pwr;
+	uint8_t antenna_max;
+	uint16_t flags;
+};
+
+/**
+ * OCB_CHANNEL_FLAG_NO_RX_HDR - Don't add the RX stats header to packets
+ *      received on this channel.
+ */
+#define OCB_CHANNEL_FLAG_DISABLE_RX_STATS_HDR	(1 << 0)
+
+/**
+ * struct sir_ocb_config_sched
+ * @chan_freq: frequency of the channel
+ * @total_duration: duration of the schedule
+ * @guard_interval: guard interval on the start of the schedule
+ */
+struct sir_ocb_config_sched {
+	uint32_t chan_freq;
+	uint32_t total_duration;
+	uint32_t guard_interval;
+};
+
+/**
+ * struct sir_ocb_config
+ * @session_id: session id
+ * @channel_count: number of channels
+ * @schedule_size: size of the channel schedule
+ * @flags: reserved
+ * @channels: array of OCB channels
+ * @schedule: array of OCB schedule elements
+ * @dcc_ndl_chan_list_len: size of the ndl_chan array
+ * @dcc_ndl_chan_list: array of dcc channel info
+ * @dcc_ndl_active_state_list_len: size of the active state array
+ * @dcc_ndl_active_state_list: array of active states
+ * @adapter: the OCB adapter
+ * @dcc_stats_callback: callback for the response event
+ */
+struct sir_ocb_config {
+	uint8_t session_id;
+	uint32_t channel_count;
+	uint32_t schedule_size;
+	uint32_t flags;
+	struct sir_ocb_config_channel *channels;
+	struct sir_ocb_config_sched *schedule;
+	uint32_t dcc_ndl_chan_list_len;
+	void *dcc_ndl_chan_list;
+	uint32_t dcc_ndl_active_state_list_len;
+	void *dcc_ndl_active_state_list;
+};
+
+/* The size of the utc time in bytes. */
+#define SIZE_UTC_TIME (10)
+/* The size of the utc time error in bytes. */
+#define SIZE_UTC_TIME_ERROR (5)
+
+/**
+ * struct sir_ocb_utc
+ * @vdev_id: session id
+ * @utc_time: number of nanoseconds from Jan 1st 1958
+ * @time_error: the error in the UTC time. All 1's for unknown
+ */
+struct sir_ocb_utc {
+	uint32_t vdev_id;
+	uint8_t utc_time[SIZE_UTC_TIME];
+	uint8_t time_error[SIZE_UTC_TIME_ERROR];
+};
+
+/**
+ * struct sir_ocb_timing_advert
+ * @vdev_id: session id
+ * @chan_freq: frequency on which to advertise
+ * @repeat_rate: the number of times it will send TA in 5 seconds
+ * @timestamp_offset: offset of the timestamp field in the TA frame
+ * @time_value_offset: offset of the time_value field in the TA frame
+ * @template_length: size in bytes of the TA frame
+ * @template_value: the TA frame
+ */
+struct sir_ocb_timing_advert {
+	uint32_t vdev_id;
+	uint32_t chan_freq;
+	uint32_t repeat_rate;
+	uint32_t timestamp_offset;
+	uint32_t time_value_offset;
+	uint32_t template_length;
+	uint8_t *template_value;
+};
+
+/**
+ * struct sir_ocb_get_tsf_timer_response
+ * @vdev_id: session id
+ * @timer_high: higher 32-bits of the timer
+ * @timer_low: lower 32-bits of the timer
+ */
+struct sir_ocb_get_tsf_timer_response {
+	uint32_t vdev_id;
+	uint32_t timer_high;
+	uint32_t timer_low;
+};
+
+/**
+ * struct sir_ocb_get_tsf_timer
+ * @vdev_id: session id
+ */
+struct sir_ocb_get_tsf_timer {
+	uint32_t vdev_id;
+};
+
+/**
+ * struct sir_dcc_get_stats_response
+ * @vdev_id: session id
+ * @num_channels: number of dcc channels
+ * @channel_stats_array_len: size in bytes of the stats array
+ * @channel_stats_array: the stats array
+ */
+struct sir_dcc_get_stats_response {
+	uint32_t vdev_id;
+	uint32_t num_channels;
+	uint32_t channel_stats_array_len;
+	void *channel_stats_array;
+};
+
+/**
+ * struct sir_dcc_get_stats
+ * @vdev_id: session id
+ * @channel_count: number of dcc channels
+ * @request_array_len: size in bytes of the request array
+ * @request_array: the request array
+ */
+struct sir_dcc_get_stats {
+	uint32_t vdev_id;
+	uint32_t channel_count;
+	uint32_t request_array_len;
+	void *request_array;
+};
+
+/**
+ * struct sir_dcc_clear_stats
+ * @vdev_id: session id
+ * @dcc_stats_bitmap: bitmap of clear option
+ */
+struct sir_dcc_clear_stats {
+	uint32_t vdev_id;
+	uint32_t dcc_stats_bitmap;
+};
+
+/**
+ * struct sir_dcc_update_ndl_response
+ * @vdev_id: session id
+ * @status: response status
+ */
+struct sir_dcc_update_ndl_response {
+	uint32_t vdev_id;
+	uint32_t status;
+};
+
+/**
+ * struct sir_dcc_update_ndl
+ * @vdev_id: session id
+ * @channel_count: number of channels to be updated
+ * @dcc_ndl_chan_list_len: size in bytes of the ndl_chan array
+ * @dcc_ndl_chan_list: the ndl_chan array
+ * @dcc_ndl_active_state_list_len: size in bytes of the active_state array
+ * @dcc_ndl_active_state_list: the active state array
+ */
+struct sir_dcc_update_ndl {
+	uint32_t vdev_id;
+	uint32_t channel_count;
+	uint32_t dcc_ndl_chan_list_len;
+	void *dcc_ndl_chan_list;
+	uint32_t dcc_ndl_active_state_list_len;
+	void *dcc_ndl_active_state_list;
+};
+
+/**
+ * enum powersave_qpower_mode: QPOWER modes
+ * @QPOWER_DISABLED: Qpower is disabled
+ * @QPOWER_ENABLED: Qpower is enabled
+ * @QPOWER_DUTY_CYCLING: Qpower is enabled with duty cycling
+ */
+enum powersave_qpower_mode {
+	QPOWER_DISABLED = 0,
+	QPOWER_ENABLED = 1,
+	QPOWER_DUTY_CYCLING = 2
+};
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+/**
+ * struct gateway_param_update_req - gateway parameter update request
+ * @request_id: request id
+ * @session_id: session id
+ * @max_retries: Max ARP/NS retry attempts
+ * @timeout: Retry interval
+ * @ipv4_addr_type: on ipv4 network
+ * @ipv6_addr_type: on ipv6 network
+ * @gw_mac_addr: gateway mac addr
+ * @ipv4_addr: ipv4 addr
+ * @ipv6_addr: ipv6 addr
+ */
+struct gateway_param_update_req {
+	uint32_t     request_id;
+	uint32_t     session_id;
+	uint32_t     max_retries;
+	uint32_t     timeout;
+	uint32_t     ipv4_addr_type;
+	uint32_t     ipv6_addr_type;
+	struct qdf_mac_addr  gw_mac_addr;
+	uint8_t      ipv4_addr[QDF_IPV4_ADDR_SIZE];
+	uint8_t      ipv6_addr[QDF_IPV6_ADDR_SIZE];
+};
+#else
+struct gateway_param_update_req;
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+
+/**
+ * struct sir_sme_ext_change_chan_req - channel change request
+ * @message_type: message id
+ * @length: msg length
+ * @new_channel: new channel
+ * @session_id: session id
+ */
+struct sir_sme_ext_cng_chan_req {
+	uint16_t  message_type; /* eWNI_SME_EXT_CHANGE_CHANNEL */
+	uint16_t  length;
+	uint32_t  new_channel;
+	uint8_t   session_id;
+};
+
+/**
+ * struct sir_sme_ext_change_chan_ind.
+ * @session_id: session id
+ * @new_channel: new channel to change
+ */
+struct sir_sme_ext_cng_chan_ind {
+	uint8_t  session_id;
+	uint8_t  new_channel;
+};
+
+/**
+ * struct stsf - the basic stsf structure
+ *
+ * @vdev_id: vdev id
+ * @tsf_low: low 32bits of tsf
+ * @tsf_high: high 32bits of tsf
+ * @soc_timer_low: low 32bits of synced SOC timer value
+ * @soc_timer_high: high 32bits of synced SOC timer value
+ *
+ * driver use this struct to store the tsf info
+ */
+struct stsf {
+	uint32_t vdev_id;
+	uint32_t tsf_low;
+	uint32_t tsf_high;
+	uint32_t soc_timer_low;
+	uint32_t soc_timer_high;
+};
+
+#define SIR_BCN_FLT_MAX_ELEMS_IE_LIST 8
+/**
+ * struct beacon_filter_param - parameters for beacon filtering
+ * @vdev_id: vdev id
+ * @ie_map: bitwise map of IEs that needs to be filtered
+ *
+ */
+struct beacon_filter_param {
+	uint32_t   vdev_id;
+	uint32_t   ie_map[SIR_BCN_FLT_MAX_ELEMS_IE_LIST];
+};
+
+/**
+ * struct adaptive_dwelltime_params - the adaptive dwelltime params
+ * @vdev_id: vdev id
+ * @is_enabled: Adaptive dwell time is enabled/disabled
+ * @dwelltime_mode: global default adaptive dwell mode
+ * @lpf_weight: weight to calculate the average low pass
+ * filter for channel congestion
+ * @passive_mon_intval: intval to monitor wifi activity in passive scan in msec
+ * @wifi_act_threshold: % of wifi activity used in passive scan 0-100
+ *
+ */
+struct adaptive_dwelltime_params {
+	uint32_t  vdev_id;
+	bool      is_enabled;
+	uint8_t   dwelltime_mode;
+	uint8_t   lpf_weight;
+	uint8_t   passive_mon_intval;
+	uint8_t   wifi_act_threshold;
+};
+
+/**
+ * struct csa_offload_params - CSA offload request parameters
+ * @channel: channel
+ * @switch_mode: switch mode
+ * @sec_chan_offset: second channel offset
+ * @new_ch_width: new channel width
+ * @new_ch_freq_seg1: channel center freq 1
+ * @new_ch_freq_seg2: channel center freq 2
+ * @ies_present_flag: IE present flag
+ */
+struct csa_offload_params {
+	uint8_t channel;
+	uint8_t switch_mode;
+	uint8_t sec_chan_offset;
+	uint8_t new_ch_width;
+	uint8_t new_op_class;
+	uint8_t new_ch_freq_seg1;
+	uint8_t new_ch_freq_seg2;
+	uint32_t ies_present_flag;
+	tSirMacAddr bssId;
+};
+
+/**
+ * enum obss_ht40_scancmd_type - obss scan command type
+ * @HT40_OBSS_SCAN_PARAM_START: OBSS scan start
+ * @HT40_OBSS_SCAN_PARAM_UPDATE: OBSS scan param update
+ */
+enum obss_ht40_scancmd_type {
+	HT40_OBSS_SCAN_PARAM_START,
+	HT40_OBSS_SCAN_PARAM_UPDATE
+};
+
+/**
+ * struct sme_obss_ht40_scanind_msg - sme obss scan params
+ * @msg_type: message type
+ * @length: message length
+ * @mac_addr: mac address
+ */
+struct sme_obss_ht40_scanind_msg {
+	uint16_t               msg_type;
+	uint16_t               length;
+	struct qdf_mac_addr    mac_addr;
+};
+
+/**
+ * struct obss_ht40_scanind - ht40 obss scan request
+ * @cmd: message type
+ * @scan_type: message length
+ * @obss_passive_dwelltime: obss passive dwelltime
+ * @obss_active_dwelltime: obss active dwelltime
+ * @obss_width_trigger_interval: scan interval
+ * @obss_passive_total_per_channel: total passive scan time per channel
+ * @obss_active_total_per_channel: total active scan time per channel
+ * @bsswidth_ch_trans_delay: OBSS transition delay time
+ * @obss_activity_threshold: OBSS activity threshold
+ * @self_sta_id: self sta identification
+ * @bss_id: BSS index
+ * @fortymhz_intolerent: Ht40mhz intolerance
+ * @channel_count: channel count
+ * @channels: channel information
+ * @current_operatingclass: operating class
+ * @iefield_len: ie's length
+ * @iefiled: ie's information
+ */
+struct obss_ht40_scanind {
+	enum obss_ht40_scancmd_type cmd;
+	enum eSirScanType scan_type;
+	/* In TUs */
+	uint16_t obss_passive_dwelltime;
+	uint16_t obss_active_dwelltime;
+	/* In seconds */
+	uint16_t obss_width_trigger_interval;
+	/* In TU's */
+	uint16_t obss_passive_total_per_channel;
+	uint16_t obss_active_total_per_channel;
+	uint16_t bsswidth_ch_trans_delay;
+	uint16_t obss_activity_threshold;
+	uint8_t  self_sta_idx;
+	uint8_t bss_id;
+	uint8_t fortymhz_intolerent;
+	uint8_t channel_count;
+	uint8_t channels[SIR_ROAM_MAX_CHANNELS];
+	uint8_t current_operatingclass;
+	uint16_t iefield_len;
+	uint8_t  iefield[SIR_ROAM_SCAN_MAX_PB_REQ_SIZE];
+};
+
+/**
+ * struct obss_scanparam - OBSS scan parameters
+ * @obss_passive_dwelltime: message type
+ * @obss_active_dwelltime: message length
+ * @obss_width_trigger_interval: obss passive dwelltime
+ * @obss_passive_total_per_channel: obss passive total scan time
+ * @obss_active_total_per_channel: obss active total scan time
+ * @bsswidth_ch_trans_delay: OBSS transition delay time
+ * @obss_activity_threshold: OBSS activity threshold
+ */
+struct obss_scanparam {
+	uint16_t obss_passive_dwelltime;
+	uint16_t obss_active_dwelltime;
+	uint16_t obss_width_trigger_interval;
+	uint16_t obss_passive_total_per_channel;
+	uint16_t obss_active_total_per_channel;
+	uint16_t bsswidth_ch_trans_delay;
+	uint16_t obss_activity_threshold;
+};
+
+/**
+ * struct sir_apf_set_offload - set apf filter instructions
+ * @session_id: session identifier
+ * @version: host apf version
+ * @filter_id: Filter ID for APF filter
+ * @total_length: The total length of the full instruction
+ *                total_length equal to 0 means reset
+ * @current_offset: current offset, 0 means start a new setting
+ * @current_length: Length of current @program
+ * @program: APF instructions
+ */
+struct sir_apf_set_offload {
+	uint8_t  session_id;
+	uint32_t version;
+	uint32_t filter_id;
+	uint32_t total_length;
+	uint32_t current_offset;
+	uint32_t current_length;
+	uint8_t  *program;
+};
+
+/**
+ * struct sir_apf_offload_capabilities - get apf Capabilities
+ * @apf_version: fw's implement version
+ * @max_apf_filters: max filters that fw supports
+ * @max_bytes_for_apf_inst: the max bytes that can be used as apf instructions
+ * @remaining_bytes_for_apf_inst: remaining bytes for apf instructions
+ *
+ */
+struct sir_apf_get_offload {
+	uint32_t apf_version;
+	uint32_t max_apf_filters;
+	uint32_t max_bytes_for_apf_inst;
+	uint32_t remaining_bytes_for_apf_inst;
+};
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * struct sir_wake_lock_stats - wake lock stats structure
+ * @wow_unspecified_wake_up_count: number of non-wow related wake ups
+ * @wow_ucast_wake_up_count: Unicast wakeup count
+ * @wow_bcast_wake_up_count: Broadcast wakeup count
+ * @wow_ipv4_mcast_wake_up_count: ipv4 multicast wakeup count
+ * @wow_ipv6_mcast_wake_up_count: ipv6 multicast wakeup count
+ * @wow_ipv6_mcast_ra_stats: ipv6 multicast ra stats
+ * @wow_ipv6_mcast_ns_stats: ipv6 multicast ns stats
+ * @wow_ipv6_mcast_na_stats: ipv6 multicast na stats
+ * @wow_icmpv4_count: ipv4 icmp packet count
+ * @wow_icmpv6_count: ipv6 icmp packet count
+ * @wow_rssi_breach_wake_up_count: rssi breach wakeup count
+ * @wow_low_rssi_wake_up_count: low rssi wakeup count
+ * @wow_gscan_wake_up_count: gscan wakeup count
+ * @wow_pno_complete_wake_up_count: pno complete wakeup count
+ * @wow_pno_match_wake_up_count: pno match wakeup count
+ * @wow_oem_response_wake_up_count: oem response wakeup count
+ * @pwr_save_fail_detected: pwr save fail detected wakeup count
+ */
+struct sir_wake_lock_stats {
+	uint32_t wow_unspecified_wake_up_count;
+	uint32_t wow_ucast_wake_up_count;
+	uint32_t wow_bcast_wake_up_count;
+	uint32_t wow_ipv4_mcast_wake_up_count;
+	uint32_t wow_ipv6_mcast_wake_up_count;
+	uint32_t wow_ipv6_mcast_ra_stats;
+	uint32_t wow_ipv6_mcast_ns_stats;
+	uint32_t wow_ipv6_mcast_na_stats;
+	uint32_t wow_icmpv4_count;
+	uint32_t wow_icmpv6_count;
+	uint32_t wow_rssi_breach_wake_up_count;
+	uint32_t wow_low_rssi_wake_up_count;
+	uint32_t wow_gscan_wake_up_count;
+	uint32_t wow_pno_complete_wake_up_count;
+	uint32_t wow_pno_match_wake_up_count;
+	uint32_t wow_oem_response_wake_up_count;
+	uint32_t pwr_save_fail_detected;
+};
+
+/**
+ * struct sir_vdev_wow_stats - container for per vdev wow related stat counters
+ * @ucast: Unicast wakeup count
+ * @bcast: Broadcast wakeup count
+ * @ipv4_mcast: ipv4 multicast wakeup count
+ * @ipv6_mcast: ipv6 multicast wakeup count
+ * @ipv6_mcast_ra: ipv6 multicast ra stats
+ * @ipv6_mcast_ns: ipv6 multicast ns stats
+ * @ipv6_mcast_na: ipv6 multicast na stats
+ * @icmpv4: ipv4 icmp packet count
+ * @icmpv6: ipv6 icmp packet count
+ * @rssi_breach: rssi breach wakeup count
+ * @low_rssi: low rssi wakeup count
+ * @gscan: gscan wakeup count
+ * @pno_complete: pno complete wakeup count
+ * @pno_match: pno match wakeup count
+ * @oem_response: oem response wakeup coun
+ * @scan_11d: 11d scan wakeup count
+ */
+struct sir_vdev_wow_stats {
+	uint32_t ucast;
+	uint32_t bcast;
+	uint32_t ipv4_mcast;
+	uint32_t ipv6_mcast;
+	uint32_t ipv6_mcast_ra;
+	uint32_t ipv6_mcast_ns;
+	uint32_t ipv6_mcast_na;
+	uint32_t icmpv4;
+	uint32_t icmpv6;
+	uint32_t rssi_breach;
+	uint32_t low_rssi;
+	uint32_t gscan;
+	uint32_t pno_complete;
+	uint32_t pno_match;
+	uint32_t oem_response;
+	uint32_t pwr_save_fail_detected;
+	uint32_t scan_11d;
+};
+#endif
+
+/**
+ * enum ht_capability_fields - HT Capabilities bit fields
+ * @HT_CAPS_LDPC: ldpc coding capability bit field
+ * @HT_CAPS_SUPPORTED_CHANNEL_SET: channel width set bit field
+ * @HT_CAPS_SM_PWR_SAVE: SM power save bit field
+ * @HT_CAPS_GREENFIELD: greenfield capability bit field
+ * @HT_CAPS_SHORT_GI20: short GI 20 bit field
+ * @HT_CAPS_SHORT_GI40: short GI 40 bit field
+ * @HT_CAPS_TX_STBC: Tx STBC bit field
+ * @HT_CAPS_RX_STBC: Rx STBC bit fields
+ */
+enum ht_capability_fields {
+	HT_CAPS_LDPC = 0x0001,
+	HT_CAPS_SUPPORTED_CHANNEL_SET = 0x0002,
+	HT_CAPS_SM_PWR_SAVE = 0x000c,
+	HT_CAPS_GREENFIELD = 0x0010,
+	HT_CAPS_SHORT_GI20 = 0x0020,
+	HT_CAPS_SHORT_GI40 = 0x0040,
+	HT_CAPS_TX_STBC = 0x0080,
+	HT_CAPS_RX_STBC = 0x0300
+};
+
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+
+#define IFACE_NAME_SIZE 64
+
+/**
+ * enum ndp_accept_policy - nan data path accept policy
+ * @NDP_ACCEPT_POLICY_NONE: the framework will decide the policy
+ * @NDP_ACCEPT_POLICY_ALL: accept policy offloaded to fw
+ *
+ */
+enum ndp_accept_policy {
+	NDP_ACCEPT_POLICY_NONE = 0,
+	NDP_ACCEPT_POLICY_ALL = 1,
+};
+
+/**
+ * enum ndp_self_role - nan data path role
+ * @NDP_ROLE_INITIATOR: initiator of nan data path request
+ * @NDP_ROLE_RESPONDER: responder to nan data path request
+ *
+ */
+enum ndp_self_role {
+	NDP_ROLE_INITIATOR = 0,
+	NDP_ROLE_RESPONDER = 1,
+};
+
+/**
+ * enum ndp_response_code - responder's response code to nan data path request
+ * @NDP_RESPONSE_ACCEPT: ndp request accepted
+ * @NDP_RESPONSE_REJECT: ndp request rejected
+ * @NDP_RESPONSE_DEFER: ndp request deferred until later (response to follow
+ * any time later)
+ *
+ */
+enum ndp_response_code {
+	NDP_RESPONSE_ACCEPT = 0,
+	NDP_RESPONSE_REJECT = 1,
+	NDP_RESPONSE_DEFER = 2,
+};
+
+/**
+ * enum ndp_end_type - NDP end type
+ * @NDP_END_TYPE_UNSPECIFIED: type is unspecified
+ * @NDP_END_TYPE_PEER_UNAVAILABLE: type is peer unavailable
+ * @NDP_END_TYPE_OTA_FRAME: NDP end frame received from peer
+ *
+ */
+enum ndp_end_type {
+	NDP_END_TYPE_UNSPECIFIED = 0x00,
+	NDP_END_TYPE_PEER_UNAVAILABLE = 0x01,
+	NDP_END_TYPE_OTA_FRAME = 0x02,
+};
+
+/**
+ * enum ndp_end_reason_code - NDP end reason code
+ * @NDP_END_REASON_UNSPECIFIED: reason is unspecified
+ * @NDP_END_REASON_INACTIVITY: reason is peer inactivity
+ * @NDP_END_REASON_PEER_DATA_END: data end indication received from peer
+ *
+ */
+enum ndp_end_reason_code {
+	NDP_END_REASON_UNSPECIFIED = 0x00,
+	NDP_END_REASON_INACTIVITY = 0x01,
+	NDP_END_REASON_PEER_DATA_END = 0x02,
+};
+
+/**
+ * enum nan_status_type - NDP status type
+ * @NDP_RSP_STATUS_SUCCESS: request was successful
+ * @NDP_RSP_STATUS_ERROR: request failed
+ */
+enum nan_status_type {
+	NDP_RSP_STATUS_SUCCESS = 0x00,
+	NDP_RSP_STATUS_ERROR = 0x01,
+};
+
+/**
+ * enum nan_reason_code - NDP command rsp reason code value
+ * @NDP_UNSUPPORTED_CONCURRENCY: Will be used in unsupported concurrency cases
+ * @NDP_NAN_DATA_IFACE_CREATE_FAILED: ndi create failed
+ * @NDP_NAN_DATA_IFACE_DELETE_FAILED: ndi delete failed
+ * @NDP_DATA_INITIATOR_REQ_FAILED: data initiator request failed
+ * @NDP_DATA_RESPONDER_REQ_FAILED: data responder request failed
+ * @NDP_INVALID_SERVICE_INSTANCE_ID: invalid service instance id
+ * @NDP_INVALID_NDP_INSTANCE_ID: invalid ndp instance id
+ * @NDP_INVALID_RSP_CODE: invalid response code in ndp responder request
+ * @NDP_INVALID_APP_INFO_LEN: invalid app info length
+ * @NDP_NMF_REQ_FAIL: OTA nan mgmt frame failure for data request
+ * @NDP_NMF_RSP_FAIL: OTA nan mgmt frame failure for data response
+ * @NDP_NMF_CNF_FAIL: OTA nan mgmt frame failure for confirm
+ * @NDP_END_FAILED: ndp end failed
+ * @NDP_NMF_END_REQ_FAIL: OTA nan mgmt frame failure for data end
+ * @NDP_VENDOR_SPECIFIC_ERROR: other vendor specific failures
+ */
+enum nan_reason_code {
+	NDP_UNSUPPORTED_CONCURRENCY = 9000,
+	NDP_NAN_DATA_IFACE_CREATE_FAILED = 9001,
+	NDP_NAN_DATA_IFACE_DELETE_FAILED = 9002,
+	NDP_DATA_INITIATOR_REQ_FAILED = 9003,
+	NDP_DATA_RESPONDER_REQ_FAILED = 9004,
+	NDP_INVALID_SERVICE_INSTANCE_ID = 9005,
+	NDP_INVALID_NDP_INSTANCE_ID = 9006,
+	NDP_INVALID_RSP_CODE = 9007,
+	NDP_INVALID_APP_INFO_LEN = 9008,
+	NDP_NMF_REQ_FAIL = 9009,
+	NDP_NMF_RSP_FAIL = 9010,
+	NDP_NMF_CNF_FAIL = 9011,
+	NDP_END_FAILED = 9012,
+	NDP_NMF_END_REQ_FAIL = 9013,
+	/* 9500 onwards vendor specific error codes */
+	NDP_VENDOR_SPECIFIC_ERROR = 9500,
+};
+
+/**
+ * struct ndp_cfg - ndp configuration
+ * @tag: unique identifier
+ * @ndp_cfg_len: ndp configuration length
+ * @ndp_cfg: variable length ndp configuration
+ *
+ */
+struct ndp_cfg {
+	uint32_t tag;
+	uint32_t ndp_cfg_len;
+	uint8_t *ndp_cfg;
+};
+
+/**
+ * struct ndp_qos_cfg - ndp qos configuration
+ * @tag: unique identifier
+ * @ndp_qos_cfg_len: ndp qos configuration length
+ * @ndp_qos_cfg: variable length ndp qos configuration
+ *
+ */
+struct ndp_qos_cfg {
+	uint32_t tag;
+	uint32_t ndp_qos_cfg_len;
+	uint8_t ndp_qos_cfg[];
+};
+
+/**
+ * struct ndp_app_info - application info shared during ndp setup
+ * @tag: unique identifier
+ * @ndp_app_info_len: ndp app info length
+ * @ndp_app_info: variable length application information
+ *
+ */
+struct ndp_app_info {
+	uint32_t tag;
+	uint32_t ndp_app_info_len;
+	uint8_t *ndp_app_info;
+};
+
+/**
+ * struct ndp_scid - structure to hold sceurity context identifier
+ * @scid_len: length of scid
+ * @scid: scid
+ *
+ */
+struct ndp_scid {
+	uint32_t scid_len;
+	uint8_t *scid;
+};
+
+/**
+ * struct ndp_pmk - structure to hold pairwise master key
+ * @pmk_len: length of pairwise master key
+ * @pmk: buffer containing pairwise master key
+ *
+ */
+struct ndp_pmk {
+	uint32_t pmk_len;
+	uint8_t *pmk;
+};
+
+/**
+ * struct ndi_create_req - ndi create request params
+ * @transaction_id: unique identifier
+ * @iface_name: interface name
+ *
+ */
+struct ndi_create_req {
+	uint32_t transaction_id;
+	char  iface_name[IFACE_NAME_SIZE];
+};
+
+/**
+ * struct ndi_create_rsp - ndi create response params
+ * @status: request status
+ * @reason: reason if any
+ *
+ */
+struct ndi_create_rsp {
+	uint32_t status;
+	uint32_t reason;
+	uint8_t sta_id;
+};
+
+/**
+ * struct ndi_delete_rsp - ndi delete response params
+ * @status: request status
+ * @reason: reason if any
+ *
+ */
+struct ndi_delete_rsp {
+	uint32_t status;
+	uint32_t reason;
+};
+
+/**
+ * struct ndp_initiator_req - ndp initiator request params
+ * @transaction_id: unique identifier
+ * @vdev_id: session id of the interface over which ndp is being created
+ * @channel: suggested channel for ndp creation
+ * @channel_cfg: channel config, 0=no channel, 1=optional, 2=mandatory
+ * @service_instance_id: Service identifier
+ * @peer_discovery_mac_addr: Peer's discovery mac address
+ * @self_ndi_mac_addr: self NDI mac address
+ * @ndp_config: ndp configuration params
+ * @ndp_info: ndp application info
+ * @ncs_sk_type: indicates NCS_SK_128 or NCS_SK_256
+ * @pmk: pairwise master key
+ *
+ */
+struct ndp_initiator_req {
+	uint32_t transaction_id;
+	uint32_t vdev_id;
+	uint32_t channel;
+	uint32_t channel_cfg;
+	uint32_t service_instance_id;
+	struct qdf_mac_addr peer_discovery_mac_addr;
+	struct qdf_mac_addr self_ndi_mac_addr;
+	struct ndp_cfg ndp_config;
+	struct ndp_app_info ndp_info;
+	uint32_t ncs_sk_type;
+	struct ndp_pmk pmk;
+};
+
+/**
+ * struct ndp_initiator_rsp - response event from FW
+ * @transaction_id: unique identifier
+ * @vdev_id: session id of the interface over which ndp is being created
+ * @ndp_instance_id: locally created NDP instance ID
+ * @status: status of the ndp request
+ * @reason: reason for failure if any
+ *
+ */
+struct ndp_initiator_rsp {
+	uint32_t transaction_id;
+	uint32_t vdev_id;
+	uint32_t ndp_instance_id;
+	uint32_t status;
+	uint32_t reason;
+};
+
+/**
+ * struct ndp_indication_event - create ndp indication on the responder
+ * @vdev_id: session id of the interface over which ndp is being created
+ * @service_instance_id: Service identifier
+ * @peer_discovery_mac_addr: Peer's discovery mac address
+ * @peer_mac_addr: Peer's NDI mac address
+ * @ndp_initiator_mac_addr: NDI mac address of the peer initiating NDP
+ * @ndp_instance_id: locally created NDP instance ID
+ * @role: self role for NDP
+ * @ndp_accept_policy: accept policy configured by the upper layer
+ * @ndp_config: ndp configuration params
+ * @ndp_info: ndp application info
+ * @ncs_sk_type: indicates NCS_SK_128 or NCS_SK_256
+ * @scid: security context identifier
+ *
+ */
+struct ndp_indication_event {
+	uint32_t vdev_id;
+	uint32_t service_instance_id;
+	struct qdf_mac_addr peer_discovery_mac_addr;
+	struct qdf_mac_addr peer_mac_addr;
+	uint32_t ndp_instance_id;
+	enum ndp_self_role role;
+	enum ndp_accept_policy policy;
+	struct ndp_cfg ndp_config;
+	struct ndp_app_info ndp_info;
+	uint32_t ncs_sk_type;
+	struct ndp_scid scid;
+};
+
+/**
+ * struct ndp_responder_req - responder's response to ndp create request
+ * @transaction_id: unique identifier
+ * @vdev_id: session id of the interface over which ndp is being created
+ * @ndp_instance_id: locally created NDP instance ID
+ * @ndp_rsp: response to the ndp create request
+ * @ndp_config: ndp configuration params
+ * @ndp_info: ndp application info
+ * @pmk: pairwise master key
+ * @ncs_sk_type: indicates NCS_SK_128 or NCS_SK_256
+ *
+ */
+struct ndp_responder_req {
+	uint32_t transaction_id;
+	uint32_t vdev_id;
+	uint32_t ndp_instance_id;
+	enum ndp_response_code ndp_rsp;
+	struct ndp_cfg ndp_config;
+	struct ndp_app_info ndp_info;
+	struct ndp_pmk pmk;
+	uint32_t ncs_sk_type;
+};
+
+/**
+ * struct ndp_responder_rsp_event - response to responder's request
+ * @transaction_id: unique identifier
+ * @vdev_id: session id of the interface over which ndp is being created
+ * @status: command status
+ * @reason: reason for failure if any
+ * @peer_mac_addr: Peer's mac address
+ * @create_peer: Flag to indicate to create peer
+ */
+struct ndp_responder_rsp_event {
+	uint32_t transaction_id;
+	uint32_t vdev_id;
+	uint32_t status;
+	uint32_t reason;
+	struct qdf_mac_addr peer_mac_addr;
+	bool create_peer;
+};
+
+/**
+ * struct ndp_confirm_event - ndp confirmation event from FW
+ * @vdev_id: session id of the interface over which ndp is being created
+ * @ndp_instance_id: ndp instance id for which confirm is being generated
+ * @reason_code : reason code(opaque to driver)
+ * @num_active_ndps_on_peer: number of ndp instances on peer
+ * @peer_ndi_mac_addr: peer NDI mac address
+ * @rsp_code: ndp response code
+ * @ndp_info: ndp application info
+ *
+ */
+struct ndp_confirm_event {
+	uint32_t vdev_id;
+	uint32_t ndp_instance_id;
+	uint32_t reason_code;
+	uint32_t num_active_ndps_on_peer;
+	struct qdf_mac_addr peer_ndi_mac_addr;
+	enum ndp_response_code rsp_code;
+	struct ndp_app_info ndp_info;
+};
+
+/**
+ * struct ndp_end_req - ndp end request
+ * @transaction_id: unique transaction identifier
+ * @num_ndp_instances: number of ndp instances to be terminated
+ * @ndp_ids: pointer to array of ndp_instance_id to be terminated
+ *
+ */
+struct ndp_end_req {
+	uint32_t transaction_id;
+	uint32_t num_ndp_instances;
+	uint32_t *ndp_ids;
+};
+
+/**
+ * struct peer_ndp_map  - mapping of NDP instances to peer to VDEV
+ * @vdev_id: session id of the interface over which ndp is being created
+ * @peer_ndi_mac_addr: peer NDI mac address
+ * @num_active_ndp_sessions: number of active NDP sessions on the peer
+ * @type: NDP end indication type
+ * @reason_code: NDP end indication reason code
+ * @ndp_instance_id: NDP instance ID
+ *
+ */
+struct peer_ndp_map {
+	uint32_t vdev_id;
+	struct qdf_mac_addr peer_ndi_mac_addr;
+	uint32_t num_active_ndp_sessions;
+	enum ndp_end_type type;
+	enum ndp_end_reason_code reason_code;
+	uint32_t ndp_instance_id;
+};
+
+/**
+ * struct ndp_end_rsp_event  - firmware response to ndp end request
+ * @transaction_id: unique identifier for the request
+ * @status: status of operation
+ * @reason: reason(opaque to host driver)
+ *
+ */
+struct ndp_end_rsp_event {
+	uint32_t transaction_id;
+	uint32_t status;
+	uint32_t reason;
+};
+
+/**
+ * struct ndp_end_indication_event - ndp termination notification from FW
+ * @num_ndp_ids: number of NDP ids
+ * @ndp_map: mapping of NDP instances to peer and vdev
+ *
+ */
+struct ndp_end_indication_event {
+	uint32_t num_ndp_ids;
+	struct peer_ndp_map ndp_map[];
+};
+
+/**
+ * struct ndp_schedule_update_req - ndp schedule update request
+ * @transaction_id: unique identifier
+ * @vdev_id: session id of the interface over which ndp is being created
+ * @ndp_instance_id: ndp instance id for which schedule update is requested
+ * @ndp_qos: new set of qos parameters
+ *
+ */
+struct ndp_schedule_update_req {
+	uint32_t transaction_id;
+	uint32_t vdev_id;
+	uint32_t ndp_instance_id;
+	struct ndp_qos_cfg ndp_qos;
+};
+
+/**
+ * struct ndp_schedule_update_rsp - ndp schedule update response
+ * @transaction_id: unique identifier
+ * @vdev_id: session id of the interface over which ndp is being created
+ * @status: status of the request
+ * @reason: reason code for failure if any
+ *
+ */
+struct ndp_schedule_update_rsp {
+	uint32_t transaction_id;
+	uint32_t vdev_id;
+	uint32_t status;
+	uint32_t reason;
+};
+
+/**
+ * struct sme_ndp_peer_ind - ndp peer indication
+ * @msg_type: message id
+ * @msg_len: message length
+ * @session_id: session id
+ * @peer_mac_addr: peer mac address
+ * @sta_id: station id
+ *
+ */
+struct sme_ndp_peer_ind {
+	uint16_t msg_type;
+	uint16_t msg_len;
+	uint8_t session_id;
+	struct qdf_mac_addr peer_mac_addr;
+	uint16_t sta_id;
+};
+
+#endif /* WLAN_FEATURE_NAN_DATAPATH */
+
+/**
+ * struct sir_set_tx_rx_aggregation_size - sets tx rx aggregation size
+ * @vdev_id: vdev id of the session
+ * @aggr_type: TX Aggregation Type (0=A-MPDU, 1=A-MSDU)
+ * @tx_aggregation_size: Tx aggregation size
+ * @tx_aggregation_size_be: Tx aggregation size for be queue
+ * @tx_aggregation_size_bk: Tx aggregation size for bk queue
+ * @tx_aggregation_size_vi: Tx aggregation size for vi queue
+ * @tx_aggregation_size_vo: Tx aggregation size for vo queue
+ * @rx_aggregation_size: Rx aggregation size
+ */
+struct sir_set_tx_rx_aggregation_size {
+	uint8_t vdev_id;
+	wmi_vdev_custom_aggr_type_t aggr_type;
+	uint32_t tx_aggregation_size;
+	uint32_t tx_aggregation_size_be;
+	uint32_t tx_aggregation_size_bk;
+	uint32_t tx_aggregation_size_vi;
+	uint32_t tx_aggregation_size_vo;
+	uint32_t rx_aggregation_size;
+};
+
+/**
+ * struct sir_set_tx_sw_retry_threshold - set sw retry threshold
+ * @vdev_id: vdev id of the session
+ * @tx_aggr_sw_retry_threshold_be: aggr sw retry threshold for BE
+ * @tx_aggr_sw_retry_threshold_bk: aggr sw retry threshold for BK
+ * @tx_aggr_sw_retry_threshold_vi: aggr sw retry threshold for VI
+ * @tx_aggr_sw_retry_threshold_vo: aggr sw retry threshold for VO
+ * @tx_non_aggr_sw_retry_threshold_be: non aggr sw retry threshold for BE
+ * @tx_non_aggr_sw_retry_threshold_bk: non aggr sw retry threshold for BK
+ * @tx_non_aggr_sw_retry_threshold_vi: non aggr sw retry threshold for VI
+ * @tx_non_aggr_sw_retry_threshold_vo: non aggr sw retry threshold for VO
+ */
+struct sir_set_tx_sw_retry_threshold {
+	uint8_t vdev_id;
+	uint32_t tx_aggr_sw_retry_threshold_be;
+	uint32_t tx_aggr_sw_retry_threshold_bk;
+	uint32_t tx_aggr_sw_retry_threshold_vi;
+	uint32_t tx_aggr_sw_retry_threshold_vo;
+	uint32_t tx_non_aggr_sw_retry_threshold_be;
+	uint32_t tx_non_aggr_sw_retry_threshold_bk;
+	uint32_t tx_non_aggr_sw_retry_threshold_vi;
+	uint32_t tx_non_aggr_sw_retry_threshold_vo;
+};
+
+/**
+ * struct sir_p2p_lo_start - p2p listen offload start
+ * @vdev_id: vdev identifier
+ * @ctl_flags: control flag
+ * @freq: p2p listen frequency
+ * @period: listen offload period
+ * @interval: listen offload interval
+ * @count: number listen offload intervals
+ * @device_types: device types
+ * @dev_types_len: device types length
+ * @probe_resp_tmplt: probe response template
+ * @probe_resp_len: probe response template length
+ */
+struct sir_p2p_lo_start {
+	uint32_t vdev_id;
+	uint32_t ctl_flags;
+	uint32_t freq;
+	uint32_t period;
+	uint32_t interval;
+	uint32_t count;
+	uint8_t  *device_types;
+	uint32_t dev_types_len;
+	uint8_t  *probe_resp_tmplt;
+	uint32_t probe_resp_len;
+};
+
+/**
+ * struct sir_p2p_lo_event - P2P listen offload stop event
+ * @vdev_id: vdev identifier
+ * @reason_code: P2P listen offload stop reason
+ */
+struct sir_p2p_lo_event {
+	uint32_t vdev_id;
+	uint32_t reason_code;
+};
+
+/**
+ * struct sir_hal_pwr_dbg_cmd - unit test command parameters
+ * @pdev_id: pdev id
+ * @module_id: module id
+ * @num_args: number of arguments
+ * @args: arguments
+ */
+struct sir_mac_pwr_dbg_cmd {
+	uint32_t pdev_id;
+	uint32_t module_id;
+	uint32_t num_args;
+	uint32_t args[MAX_POWER_DBG_ARGS_SUPPORTED];
+};
+
+/**
+ * struct sme_send_disassoc_frm_req - send disassoc request frame
+ * @msg_type: message type
+ * @length: length of message
+ * @session_id: session id
+ * @trans_id: transaction id
+ * @peer_mac: peer mac address
+ * @reason: reason for disassoc
+ * @wait_for_ack: wait for acknowledgment
+ **/
+ struct sme_send_disassoc_frm_req {
+	uint16_t msg_type;
+	uint16_t length;
+	uint8_t session_id;
+	uint16_t trans_id;
+	uint8_t peer_mac[6];
+	uint16_t reason;
+	uint8_t wait_for_ack;
+ };
+
+/**
+ * struct sme_update_access_policy_vendor_ie - update vendor ie and access
+ * policy
+ * @msg_type: message id
+ * @msg_len: message length
+ * @sme_session_id: sme session id
+ * @ie: vendor ie
+ * @access_policy: access policy for vendor ie
+ */
+struct sme_update_access_policy_vendor_ie {
+	uint16_t msg_type;
+	uint16_t length;
+	uint32_t sme_session_id;
+	uint8_t ie[SIR_MAC_MAX_IE_LENGTH];
+	uint8_t access_policy;
+};
+
+/**
+ * struct sir_encrypt_decrypt_rsp_params - encrypt/decrypt rsp params
+ * @vdev_id: vdev id
+ * @status: status
+ * @data_length: data length
+ * @data: data pointer
+ */
+struct sir_encrypt_decrypt_rsp_params {
+	uint32_t vdev_id;
+	int32_t status;
+	uint32_t data_length;
+	uint8_t *data;
+};
+
+/**
+ * struct sme_tx_fail_cnt_threshold - tx failure count for disconnect to fw
+ * @session_id: Session id
+ * @tx_fail_cnt_threshold: Tx failure count to do disconnect
+ */
+struct sme_tx_fail_cnt_threshold {
+	uint8_t session_id;
+	uint32_t tx_fail_cnt_threshold;
+};
+
+/**
+ * struct sme_short_retry_limit - transmission retry limit for short frames.
+ * @session_id: Session id
+ * @short_retry_limit: tranmission retry limit for short frame.
+ *
+ */
+struct sme_short_retry_limit {
+	uint8_t session_id;
+	uint32_t short_retry_limit;
+};
+
+/**
+ * struct sme_long_retry_limit - tranmission retry limit for long frames
+ * @session_id: Session id
+ * @short_retry_limit: tranmission retry limit for long frames.
+ *
+ */
+struct sme_long_retry_limit {
+	uint8_t session_id;
+	uint32_t long_retry_limit;
+};
+
+/**
+ * struct sme_addba_accept - Allow/reject the addba request frame
+ * @session_id: Session id
+ * @addba_accept: Allow/reject the addba request frame
+ */
+struct sme_addba_accept {
+	uint8_t session_id;
+	uint8_t addba_accept;
+};
+
+/**
+ * struct sme_sta_inactivity_timeout - set sta_inactivity_timeout
+ * @session_id: session Id.
+ * @sta_inactivity_timeout: Timeout to disconnect STA after there
+ * is no activity.
+ */
+struct sme_sta_inactivity_timeout {
+	uint8_t session_id;
+	uint32_t sta_inactivity_timeout;
+};
+
+/*
+ * struct wow_pulse_mode - WoW Pulse set cmd struct
+ * @wow_pulse_enable: enable or disable this feature
+ * @wow_pulse_pin: GPIO PIN for Pulse
+ * @wow_pulse_interval_low: Pulse interval low
+ * @wow_pulse_interval_high: Pulse interval high
+ *
+ * SME uses this structure to configure wow pulse info
+ * and send it to WMA
+ */
+struct wow_pulse_mode {
+	bool                       wow_pulse_enable;
+	uint8_t                    wow_pulse_pin;
+	uint16_t                   wow_pulse_interval_high;
+	uint16_t                   wow_pulse_interval_low;
+};
+
+
+/**
+ * umac_send_mb_message_to_mac(): post message to umac
+ * @msg: opaque message pointer
+ *
+ * Return: QDF status
+ */
+QDF_STATUS umac_send_mb_message_to_mac(void *msg);
+
+/**
+ * struct scan_chan_info - channel info
+ * @freq: radio frequence
+ * @cmd flag: cmd flag
+ * @noise_floor: noise floor
+ * @cycle_count: cycle count
+ * @rx_clear_count: rx clear count
+ * @tx_frame_count: TX frame count
+ * @clock_freq: clock frequence MHZ
+ */
+struct scan_chan_info {
+	uint32_t freq;
+	uint32_t cmd_flag;
+	uint32_t noise_floor;
+	uint32_t cycle_count;
+	uint32_t rx_clear_count;
+	uint32_t tx_frame_count;
+	uint32_t clock_freq;
+};
+
+/**
+ * enum wow_resume_trigger - resume trigger override setting values
+ * @WOW_RESUME_TRIGGER_DEFAULT: fw to use platform default resume trigger
+ * @WOW_RESUME_TRIGGER_HTC_WAKEUP: force fw to use HTC Wakeup to resume
+ * @WOW_RESUME_TRIGGER_GPIO: force fw to use GPIO to resume
+ * @WOW_RESUME_TRIGGER_COUNT: number of resume trigger options
+ */
+enum wow_resume_trigger {
+	/* always first */
+	WOW_RESUME_TRIGGER_DEFAULT = 0,
+	WOW_RESUME_TRIGGER_HTC_WAKEUP,
+	WOW_RESUME_TRIGGER_GPIO,
+	/* always last */
+	WOW_RESUME_TRIGGER_COUNT
+};
+
+/**
+ * enum wow_interface_pause - interface pause override setting values
+ * @WOW_INTERFACE_PAUSE_DEFAULT: use platform default interface pause setting
+ * @WOW_INTERFACE_PAUSE_ENABLE: force interface pause setting to enabled
+ * @WOW_INTERFACE_PAUSE_DISABLE: force interface pause setting to disabled
+ * @WOW_INTERFACE_PAUSE_COUNT: number of interface pause options
+ */
+enum wow_interface_pause {
+	/* always first */
+	WOW_INTERFACE_PAUSE_DEFAULT = 0,
+	WOW_INTERFACE_PAUSE_ENABLE,
+	WOW_INTERFACE_PAUSE_DISABLE,
+	/* always last */
+	WOW_INTERFACE_PAUSE_COUNT
+};
+
+/**
+ * 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 wow_enable_params {
+	bool is_unit_test;
+	enum wow_interface_pause interface_pause;
+	enum wow_resume_trigger resume_trigger;
+};
+
+#define HE_LTF_1X	0
+#define HE_LTF_2X	1
+#define HE_LTF_4X	2
+
+#define HE_LTF_ALL	0x7
+#define HE_SGI_MASK	0xFF00
+
+#define AUTO_RATE_GI_400NS	8
+#define AUTO_RATE_GI_800NS	9
+#define AUTO_RATE_GI_1600NS	10
+#define AUTO_RATE_GI_3200NS	11
+
+#define SET_AUTO_RATE_SGI_VAL(set_val, bit_mask) \
+	(set_val = (set_val & HE_LTF_ALL) | bit_mask)
+
+#define SET_AUTO_RATE_HE_LTF_VAL(set_val, bit_mask) \
+	(set_val = (set_val & HE_SGI_MASK) | bit_mask)
+
+#ifdef WLAN_FEATURE_11AX
+#define HE_CAP_OUI_TYPE "\x23"
+#define HE_CAP_OUI_SIZE 1
+#define HE_OP_OUI_TYPE "\x24"
+#define HE_OP_OUI_SIZE 1
+
+#define HE_RU_ALLOC_INDX0_MASK (0x01 << 0)
+#define HE_RU_ALLOC_INDX1_MASK (0x01 << 1)
+#define HE_RU_ALLOC_INDX2_MASK (0x01 << 2)
+#define HE_RU_ALLOC_INDX3_MASK (0x01 << 3)
+
+/* 3 bits for NSS and 4 bits for RU Index */
+#define HE_PPET_NSS_LEN 3
+#define HE_PEPT_RU_IDX_LEN 4
+#define HE_PPET_NSS_RU_LEN (HE_PPET_NSS_LEN + HE_PEPT_RU_IDX_LEN)
+#define HE_PPET_SIZE 3
+#define HE_BYTE_SIZE 8
+
+struct ppet_hdr {
+	uint8_t nss:3;
+	uint8_t ru_idx_mask:4;
+	uint8_t remaining:1;
+};
+
+/* MAX PPET size = 7 bits + (max_nss X max_ru_number X 6) = 25 bytes */
+#define HE_MAX_PPET_SIZE WNI_CFG_HE_PPET_LEN
+
+#define HE_MAX_PHY_CAP_SIZE 3
+
+#define HE_CH_WIDTH_GET_BIT(ch_wd, bit)      (((ch_wd) >> (bit)) & 1)
+#define HE_CH_WIDTH_COMBINE(b0, b1, b2, b3, b4, b5, b6)             \
+	((uint8_t)(b0) | ((b1) << 1) | ((b2) << 2) |  ((b3) << 3) | \
+	((b4) << 4) | ((b5) << 5) | ((b6) << 6))
+
+/*
+ * MCS values are interpreted as in IEEE 11ax-D1.4 spec onwards
+ * +-----------------------------------------------------+
+ * |  SS8  |  SS7  |  SS6  | SS5 | SS4 | SS3 | SS2 | SS1 |
+ * +-----------------------------------------------------+
+ * | 15-14 | 13-12 | 11-10 | 9-8 | 7-6 | 5-4 | 3-2 | 1-0 |
+ * +-----------------------------------------------------+
+ */
+#define HE_MCS_NSS_SHIFT(nss)                 (((nss) - 1) << 1)
+#define HE_MCS_MSK_4_NSS(nss)                 (3 << HE_MCS_NSS_SHIFT(nss))
+#define HE_MCS_INV_MSK_4_NSS(nss)             (~HE_MCS_MSK_4_NSS(nss))
+#define HE_GET_MCS_4_NSS(mcs_set, nss)             \
+	(((mcs_set) >> HE_MCS_NSS_SHIFT(nss)) & 3)
+#define HE_SET_MCS_4_NSS(mcs_set, mcs, nss)        \
+	(((mcs_set) & HE_MCS_INV_MSK_4_NSS(nss)) | \
+	((mcs) << HE_MCS_NSS_SHIFT(nss)))
+#define HE_MCS_IS_NSS_ENABLED(mcs_set, nss)        \
+	((HE_MCS_MSK_4_NSS(nss) & (mcs_set)) != HE_MCS_MSK_4_NSS(nss))
+
+#define HE_MCS_ALL_DISABLED                   0xFFFF
+
+#define HE_MCS_0_7     0x0
+#define HE_MCS_0_9     0x1
+#define HE_MCS_0_11    0x2
+#define HE_MCS_DISABLE 0x3
+
+/*
+ * Following formuala has been arrived at using karnaugh map and unit tested
+ * with sample code. Take MCS for each NSS as 2 bit value first and solve for
+ * 2 bit intersection of NSS. Use following table/Matrix as guide for solving
+ * K-Maps
+ * MCS 1\MCS 2    00         01         10         11
+ *    00          00         00         00         11
+ *    01          00         01         01         11
+ *    10          00         01         10         11
+ *    11          11         11         11         11
+ * if output MCS is o1o0, then as per K-map reduction:
+ * o0 = m1.m0 | n1.n0 | (~m1).m0.(n1^n0) | (~n1).n0.(m1^m0)
+ * o1 = m1.m0 | n1.n0 | m1.(~m0).n1.(~n0)
+ *
+ * Please note: Calculating MCS intersection is 80211 protocol specific and
+ * should be implemented in PE. WMA can use this macro rather than calling any
+ * lim API to do the intersection.
+ */
+#define HE_INTERSECT_MCS_BITS_PER_NSS(m1, m0, n1, n0)                \
+	(((m1 & m0) | (n1 & n0) | (((~m1) & m0) & (n1 ^ n0))  |      \
+	(((~n1) & n0) & (m1 ^ m0))) | (((m1 & m0) | (n1 & n0) |      \
+	(m1 & ~m0 & n1 & ~n0)) << 1))
+
+/* following takes MCS as 2 bits */
+#define HE_INTERSECT_MCS_PER_NSS(mcs_1, mcs_2)                       \
+	HE_INTERSECT_MCS_BITS_PER_NSS((mcs_1 >> 1), (mcs_1 & 1),     \
+				      (mcs_2 >> 1), (mcs_2 & 1))
+
+/* following takes MCS as 16 bits */
+#define HE_INTERSECT_MCS(mcs_1, mcs_2)                             ( \
+	HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 1),         \
+		HE_GET_MCS_4_NSS(mcs_2, 1)) << HE_MCS_NSS_SHIFT(1) | \
+	HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 2),         \
+		HE_GET_MCS_4_NSS(mcs_2, 2)) << HE_MCS_NSS_SHIFT(2) | \
+	HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 3),         \
+		HE_GET_MCS_4_NSS(mcs_2, 3)) << HE_MCS_NSS_SHIFT(3) | \
+	HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 4),         \
+		HE_GET_MCS_4_NSS(mcs_2, 4)) << HE_MCS_NSS_SHIFT(4) | \
+	HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 5),         \
+		HE_GET_MCS_4_NSS(mcs_2, 5)) << HE_MCS_NSS_SHIFT(5) | \
+	HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 6),         \
+		HE_GET_MCS_4_NSS(mcs_2, 6)) << HE_MCS_NSS_SHIFT(6) | \
+	HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 7),         \
+		HE_GET_MCS_4_NSS(mcs_2, 7)) << HE_MCS_NSS_SHIFT(7) | \
+	HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 8),         \
+		HE_GET_MCS_4_NSS(mcs_2, 8)) << HE_MCS_NSS_SHIFT(8))
+
+/**
+ * struct he_capability - to store 11ax HE capabilities
+ * @phy_cap: HE PHY capabilities
+ * @mac_cap: HE MAC capabilities
+ * @mcs: HE MCS
+ * @ppet: HE PPE threshold
+ */
+struct he_capability {
+	uint32_t phy_cap[HE_MAX_PHY_CAP_SIZE];
+	uint32_t mac_cap;
+	uint32_t mcs;
+	struct wlan_psoc_host_ppe_threshold ppet;
+};
+#endif
+
+#define HE_GET_NSS(mcs, nss)                                         \
+	do {                                                         \
+		(nss) = 0;                                           \
+		while ((((mcs) >> ((nss)*2)) & 3) != 3 && nss < 8)   \
+			(nss)++;                                     \
+	} while (0)
+
+/**
+ * struct sir_del_all_tdls_peers - delete all tdls peers
+ * @msg_type: type of message
+ * @msg_len: length of message
+ * @bssid: bssid of peer device
+ */
+struct sir_del_all_tdls_peers {
+	uint16_t msg_type;
+	uint16_t msg_len;
+	struct qdf_mac_addr bssid;
+};
+
+/**
+ * struct rsp_stats - arp packet stats
+ * @arp_req_enqueue: fw tx count
+ * @arp_req_tx_success: tx ack count
+ * @arp_req_tx_failure: tx ack fail count
+ * @arp_rsp_recvd: rx fw count
+ * @out_of_order_arp_rsp_drop_cnt: out of order count
+ * @dad_detected: dad detected
+ * @connect_status: connection status
+ * @ba_session_establishment_status: BA session status
+ * @connect_stats_present: connectivity stats present or not
+ * @tcp_ack_recvd: tcp syn ack's count
+ * @icmpv4_rsp_recvd: icmpv4 responses count
+ */
+struct rsp_stats {
+	uint32_t vdev_id;
+	uint32_t arp_req_enqueue;
+	uint32_t arp_req_tx_success;
+	uint32_t arp_req_tx_failure;
+	uint32_t arp_rsp_recvd;
+	uint32_t out_of_order_arp_rsp_drop_cnt;
+	uint32_t dad_detected;
+	uint32_t connect_status;
+	uint32_t ba_session_establishment_status;
+	bool connect_stats_present;
+	uint32_t tcp_ack_recvd;
+	uint32_t icmpv4_rsp_recvd;
+};
+
+/**
+ * struct set_arp_stats_params - set/reset arp stats
+ * @vdev_id: session id
+ * @flag: enable/disable stats
+ * @pkt_type: type of packet(1 - arp)
+ * @ip_addr: subnet ipv4 address in case of encrypted packets
+ * @pkt_type_bitmap: pkt bitmap
+ * @tcp_src_port: tcp src port for pkt tracking
+ * @tcp_dst_port: tcp dst port for pkt tracking
+ * @icmp_ipv4: target ipv4 address to track ping packets
+ * @reserved: reserved
+ */
+struct set_arp_stats_params {
+	uint32_t vdev_id;
+	uint8_t flag;
+	uint8_t pkt_type;
+	uint32_t ip_addr;
+	uint32_t pkt_type_bitmap;
+	uint32_t tcp_src_port;
+	uint32_t tcp_dst_port;
+	uint32_t icmp_ipv4;
+	uint32_t reserved;
+};
+
+/**
+ * struct get_arp_stats_params - get arp stats from firmware
+ * @pkt_type: packet type(1 - ARP)
+ * @vdev_id: session id
+ */
+struct get_arp_stats_params {
+	uint8_t pkt_type;
+	uint32_t vdev_id;
+};
+
+typedef void (*sme_rcpi_callback)(void *context, struct qdf_mac_addr mac_addr,
+				  int32_t rcpi, QDF_STATUS status);
+/**
+ * struct sme_rcpi_req - structure for querying rcpi info
+ * @session_id: session for which rcpi is required
+ * @measurement_type: type of measurement from enum rcpi_measurement_type
+ * @rcpi_callback: callback function to be invoked for rcpi response
+ * @rcpi_context: context info for rcpi callback
+ * @mac_addr: peer addr for which rcpi is required
+ */
+struct sme_rcpi_req {
+	uint32_t session_id;
+	enum rcpi_measurement_type measurement_type;
+	sme_rcpi_callback rcpi_callback;
+	void *rcpi_context;
+	struct qdf_mac_addr mac_addr;
+};
+
+/*
+ * @SCAN_REJECT_DEFAULT: default value
+ * @CONNECTION_IN_PROGRESS: connection is in progress
+ * @REASSOC_IN_PROGRESS: reassociation is in progress
+ * @EAPOL_IN_PROGRESS: STA/P2P-CLI is in middle of EAPOL/WPS exchange
+ * @SAP_EAPOL_IN_PROGRESS: SAP/P2P-GO is in middle of EAPOL/WPS exchange
+ */
+enum scan_reject_states {
+	SCAN_REJECT_DEFAULT = 0,
+	CONNECTION_IN_PROGRESS,
+	REASSOC_IN_PROGRESS,
+	EAPOL_IN_PROGRESS,
+	SAP_EAPOL_IN_PROGRESS,
+};
+
+/**
+ * sir_sme_rx_aggr_hole_ind - sme rx aggr hole indication
+ * @hole_cnt: num of holes detected
+ * @hole_info_array: hole info
+ */
+struct sir_sme_rx_aggr_hole_ind {
+	uint32_t hole_cnt;
+	uint32_t hole_info_array[];
+};
+
+/**
+ * struct sir_set_rx_reorder_timeout_val - rx reorder timeout
+ * @rx_timeout_pri: reorder timeout for AC
+ *                  rx_timeout_pri[0] : AC_VO
+ *                  rx_timeout_pri[1] : AC_VI
+ *                  rx_timeout_pri[2] : AC_BE
+ *                  rx_timeout_pri[3] : AC_BK
+ */
+struct sir_set_rx_reorder_timeout_val {
+	uint32_t rx_timeout_pri[4];
+};
+
+/**
+ * struct sir_peer_set_rx_blocksize - set rx blocksize
+ * @vdev_id: vdev id
+ * @peer_macaddr: peer mac address
+ * @rx_block_ack_win_limit: windows size limitation
+ */
+struct sir_peer_set_rx_blocksize {
+	uint32_t vdev_id;
+	struct qdf_mac_addr peer_macaddr;
+	uint32_t rx_block_ack_win_limit;
+};
+
+/**
+ * struct sir_rssi_disallow_lst - Structure holding Rssi based avoid candidate
+ * list
+ * @node: Node pointer
+ * @bssid: BSSID of the AP
+ * @retry_delay: Retry delay received during last rejection in ms
+ * @ expected_rssi: RSSI at which STA can initate
+ * @time_during_rejection: Timestamp during last rejection in millisec
+ */
+struct sir_rssi_disallow_lst {
+	qdf_list_node_t node;
+	struct qdf_mac_addr bssid;
+	uint32_t retry_delay;
+	int8_t expected_rssi;
+	qdf_time_t time_during_rejection;
+};
+
+/**
+ * struct chain_rssi_result - chain rssi result
+ * num_chains_valid: valid chain num
+ * @chain_rssi: chain rssi result as dBm unit
+ * @ant_id: antenna id
+ */
+#define CHAIN_MAX_NUM 8
+struct chain_rssi_result {
+	uint32_t num_chains_valid;
+	uint32_t chain_rssi[CHAIN_MAX_NUM];
+	uint32_t ant_id[CHAIN_MAX_NUM];
+};
+
+/**
+ * struct get_chain_rssi_req_params - get chain rssi req params
+ * @peer_macaddr: specific peer mac address
+ * @session_id: session id
+ */
+struct get_chain_rssi_req_params {
+	struct qdf_mac_addr peer_macaddr;
+	uint8_t session_id;
+};
+
+/*
+ * struct sir_limit_off_chan - limit off-channel command parameters
+ * @vdev_id: vdev id
+ * @is_tos_active: status of the traffic (active/inactive)
+ * @max_off_chan_time: max allowed off channel time
+ * @rest_time: home channel time
+ * @skip_dfs_chans: skip dfs channels during scan
+ */
+struct sir_limit_off_chan {
+	uint8_t vdev_id;
+	bool is_tos_active;
+	uint32_t max_off_chan_time;
+	uint32_t rest_time;
+	bool skip_dfs_chans;
+};
+
+typedef void (*roam_scan_stats_cb)(void *context,
+				   struct wmi_roam_scan_stats_res *res);
+
+/**
+ * struct sir_roam_scan_stats - Stores roam scan context
+ * @vdev_id: vdev id
+ * @cb: callback to be invoked for roam scan stats response
+ * @context: context of callback
+ */
+struct sir_roam_scan_stats {
+	uint32_t vdev_id;
+	roam_scan_stats_cb cb;
+	void *context;
+};
+
+/**
+ * struct sae_info - SAE info used for commit/confirm messages
+ * @msg_type: Message type
+ * @msg_len: length of message
+ * @vdev_id: vdev id
+ * @peer_mac_addr: peer MAC address
+ * @ssid: SSID
+ */
+struct sir_sae_info {
+	uint16_t msg_type;
+	uint16_t msg_len;
+	uint32_t vdev_id;
+	struct qdf_mac_addr peer_mac_addr;
+	tSirMacSSid ssid;
+};
+
+/**
+ * struct sir_sae_msg - SAE msg used for message posting
+ * @message_type: message type
+ * @length: message length
+ * @session_id: SME session id
+ * @sae_status: SAE status, 0: Success, Non-zero: Failure.
+ */
+struct sir_sae_msg {
+	uint16_t message_type;
+	uint16_t length;
+	uint16_t session_id;
+	uint8_t sae_status;
+};
+
+/**
+ * struct set_pcl_req - Request message to set the PCL
+ * @chan_weights: PCL channel weights
+ * @band: Supported band
+ */
+struct set_pcl_req {
+	struct wmi_pcl_chan_weights chan_weights;
+	enum band_info band;
+};
+
+#endif /* __SIR_API_H */
diff --git a/core/mac/inc/sir_mac_prop_exts.h b/core/mac/inc/sir_mac_prop_exts.h
new file mode 100644
index 0000000..4e0a374
--- /dev/null
+++ b/core/mac/inc/sir_mac_prop_exts.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2011-2015, 2017-2018 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.
+ */
+
+/*
+ *
+ * This file sir_mac_prop_exts.h contains the MAC protocol
+ * extensions to support ANI feature set.
+ * Author:        Chandra Modumudi
+ * Date:          11/27/02
+ */
+#ifndef __MAC_PROP_EXTS_H
+#define __MAC_PROP_EXTS_H
+
+#include "sir_types.h"
+#include "sir_api.h"
+#include "ani_system_defs.h"
+
+/* / EID (Element ID) definitions */
+
+#define PROP_CAPABILITY_GET(bitname, value) \
+	(((value) >> SIR_MAC_PROP_CAPABILITY_ ## bitname) & 1)
+
+#define IS_DOT11_MODE_HT(dot11Mode) \
+	(((dot11Mode == WNI_CFG_DOT11_MODE_11N) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_11N_ONLY) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_11AC) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_11AC_ONLY) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_11AX) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_11AX_ONLY) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_ALL)) ? true:false)
+
+#define IS_DOT11_MODE_VHT(dot11Mode) \
+	(((dot11Mode == WNI_CFG_DOT11_MODE_11AC) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_11AC_ONLY) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_11AX) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_11AX_ONLY) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_ALL)) ? true:false)
+
+#define IS_DOT11_MODE_HE(dot11Mode) \
+	(((dot11Mode == WNI_CFG_DOT11_MODE_11AX) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_11AX_ONLY) || \
+	  (dot11Mode ==  WNI_CFG_DOT11_MODE_ALL)) ? true:false)
+
+#define IS_DOT11_MODE_11B(dot11Mode)  \
+	((dot11Mode == WNI_CFG_DOT11_MODE_11B) ? true:false)
+
+#define IS_BSS_VHT_CAPABLE(vhtCaps) \
+	((vhtCaps).present && \
+	 ((vhtCaps).rxMCSMap != 0xFFFF) && \
+	 ((vhtCaps).txMCSMap != 0xFFFF))
+
+#define WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ		0
+#define WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ		1
+#define WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ		2
+#define WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ	3
+
+/* / Proprietary IE definition */
+typedef struct sSirMacPropIE {
+	uint8_t elementID;      /* SIR_MAC_ANI_PROP_IE_EID */
+	uint8_t length;
+	uint8_t oui[3];         /* ANI_OUI for Airgo products */
+	uint8_t info[1];
+} tSirMacPropIE, *tpSirMacPropIE;
+
+typedef struct sSirMacPropRateSet {
+	uint8_t numPropRates;
+	uint8_t propRate[8];
+} tSirMacPropRateSet, *tpSirMacPropRateSet;
+
+#define SIR_PROP_VERSION_STR_MAX 20
+typedef struct sSirMacPropVersion {
+	uint32_t chip_rev;      /* board, chipset info */
+	uint8_t card_type;      /* Type of Card */
+	/* build version string */
+	uint8_t build_version[SIR_PROP_VERSION_STR_MAX];
+} tSirMacPropVersion, *tpSirMacPropVersion;
+
+/* generic proprietary IE structure definition */
+typedef struct sSirPropIEStruct {
+	uint8_t propRatesPresent:1;
+	uint8_t apNamePresent:1;
+	uint8_t loadBalanceInfoPresent:1;
+	uint8_t versionPresent:1;
+	uint8_t edcaParamPresent:1;
+	uint8_t capabilityPresent:1;
+	uint8_t propChannelSwitchPresent:1;
+	uint8_t triggerStaScanPresent:1;
+	uint8_t rsvd:8;
+
+	tSirMacPropRateSet propRates;
+	tAniApName apName;      /* used in beacon/probe only */
+	uint16_t capability;    /* capability bit map */
+	tSirMacPropVersion version;
+	tSirMacEdcaParamSetIE edca;
+	uint8_t triggerStaScanEnable;
+
+} tSirPropIEStruct, *tpSirPropIEStruct;
+
+#endif /* __MAC_PROP_EXTS_H */
diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h
new file mode 100644
index 0000000..5307a60
--- /dev/null
+++ b/core/mac/inc/sir_mac_prot_def.h
@@ -0,0 +1,2489 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * This file sir_mac_prot_def.h contains the MAC/PHY protocol
+ * definitions used across various projects.
+ */
+
+#ifndef __MAC_PROT_DEFS_H
+#define __MAC_PROT_DEFS_H
+
+#include <linux/if_ether.h>
+
+#include "cds_api.h"
+#include "sir_types.h"
+#include "wni_cfg.h"
+#include <lim_fils_defs.h>
+
+/* /Capability information related */
+#define CAPABILITY_INFO_DELAYED_BA_BIT 14
+#define CAPABILITY_INFO_IMMEDIATE_BA_BIT 15
+
+/* / 11h MAC defaults */
+#define SIR_11A_CHANNEL_BEGIN           34
+#define SIR_11A_CHANNEL_END             165
+#define SIR_11B_CHANNEL_BEGIN           1
+#define SIR_11B_CHANNEL_END             14
+#define SIR_11A_FREQUENCY_OFFSET        4
+#define SIR_11B_FREQUENCY_OFFSET        1
+#define SIR_11P_CHANNEL_BEGIN           170
+#define SIR_11P_CHANNEL_END             184
+
+/* / Current version of 802.11 */
+#define SIR_MAC_PROTOCOL_VERSION 0
+
+/* Frame Type definitions */
+
+#define SIR_MAC_MGMT_FRAME    0x0
+#define SIR_MAC_CTRL_FRAME    0x1
+#define SIR_MAC_DATA_FRAME    0x2
+
+#define SIR_MAC_FRAME_TYPE_START   0x0
+#define SIR_MAC_FRAME_TYPE_END     0x3
+
+/* Control frame subtype definitions */
+
+#define SIR_MAC_CTRL_RR         4
+#define SIR_MAC_CTRL_BAR        8
+#define SIR_MAC_CTRL_BA         9
+#define SIR_MAC_CTRL_PS_POLL    10
+#define SIR_MAC_CTRL_RTS        11
+#define SIR_MAC_CTRL_CTS        12
+#define SIR_MAC_CTRL_ACK        13
+#define SIR_MAC_CTRL_CF_END     14
+#define SIR_MAC_CTRL_CF_END_ACK 15
+
+#define SIR_MAC_MAX_DURATION_MICRO_SECONDS       32767
+
+/* Data frame subtype definitions */
+#define SIR_MAC_DATA_DATA                 0
+#define SIR_MAC_DATA_DATA_ACK             1
+#define SIR_MAC_DATA_DATA_POLL            2
+#define SIR_MAC_DATA_DATA_ACK_POLL        3
+#define SIR_MAC_DATA_NULL                 4
+#define SIR_MAC_DATA_NULL_ACK             5
+#define SIR_MAC_DATA_NULL_POLL            6
+#define SIR_MAC_DATA_NULL_ACK_POLL        7
+#define SIR_MAC_DATA_QOS_DATA             8
+#define SIR_MAC_DATA_QOS_DATA_ACK         9
+#define SIR_MAC_DATA_QOS_DATA_POLL        10
+#define SIR_MAC_DATA_QOS_DATA_ACK_POLL    11
+#define SIR_MAC_DATA_QOS_NULL             12
+#define SIR_MAC_DATA_QOS_NULL_ACK         13
+#define SIR_MAC_DATA_QOS_NULL_POLL        14
+#define SIR_MAC_DATA_QOS_NULL_ACK_POLL    15
+
+#define SIR_MAC_FRAME_SUBTYPE_START       0
+#define SIR_MAC_FRAME_SUBTYPE_END         16
+
+#define SIR_MAC_DATA_QOS_MASK             8
+#define SIR_MAC_DATA_NULL_MASK            4
+#define SIR_MAC_DATA_POLL_MASK            2
+#define SIR_MAC_DATA_ACK_MASK             1
+
+/* Management frame subtype definitions */
+
+#define SIR_MAC_MGMT_ASSOC_REQ    0x0
+#define SIR_MAC_MGMT_ASSOC_RSP    0x1
+#define SIR_MAC_MGMT_REASSOC_REQ  0x2
+#define SIR_MAC_MGMT_REASSOC_RSP  0x3
+#define SIR_MAC_MGMT_PROBE_REQ    0x4
+#define SIR_MAC_MGMT_PROBE_RSP    0x5
+#define SIR_MAC_MGMT_TIME_ADVERT  0x6
+#define SIR_MAC_MGMT_BEACON       0x8
+#define SIR_MAC_MGMT_ATIM         0x9
+#define SIR_MAC_MGMT_DISASSOC     0xA
+#define SIR_MAC_MGMT_AUTH         0xB
+#define SIR_MAC_MGMT_DEAUTH       0xC
+#define SIR_MAC_MGMT_ACTION       0xD
+#define SIR_MAC_MGMT_RESERVED15   0xF
+
+/* Action frame categories */
+
+#define SIR_MAC_ACTION_SPECTRUM_MGMT   0
+#define SIR_MAC_ACTION_QOS_MGMT        1
+#define SIR_MAC_ACTION_DLP             2
+#define SIR_MAC_ACTION_BLKACK          3
+#define SIR_MAC_ACTION_PUBLIC_USAGE    4
+#define SIR_MAC_ACTION_RRM             5
+#define SIR_MAC_ACTION_FAST_BSS_TRNST  6
+#define SIR_MAC_ACTION_HT              7
+#define SIR_MAC_ACTION_SA_QUERY        8
+#define SIR_MAC_ACTION_PROT_DUAL_PUB   9
+#define SIR_MAC_ACTION_WNM            10
+#define SIR_MAC_ACTION_UNPROT_WNM     11
+#define SIR_MAC_ACTION_TDLS           12
+#define SIR_MAC_ACITON_MESH           13
+#define SIR_MAC_ACTION_MHF            14
+#define SIR_MAC_SELF_PROTECTED        15
+#define SIR_MAC_ACTION_WME            17
+#define SIR_MAC_ACTION_FST            18
+#define SIR_MAC_ACTION_VHT            21
+#define SIR_MAC_ACTION_MAX            256
+
+#define SIR_MAC_ACTION_TX             1
+#define SIR_MAC_ACTION_RX             2
+
+/* QoS management action codes */
+
+#define SIR_MAC_QOS_ADD_TS_REQ      0
+#define SIR_MAC_QOS_ADD_TS_RSP      1
+#define SIR_MAC_QOS_DEL_TS_REQ      2
+#define SIR_MAC_QOS_SCHEDULE        3
+#define SIR_MAC_QOS_MAP_CONFIGURE   4
+/* and these are proprietary */
+#define SIR_MAC_QOS_DEF_BA_REQ      4
+#define SIR_MAC_QOS_DEF_BA_RSP      5
+
+#define SIR_MAC_ADDBA_REQ     0
+#define SIR_MAC_ADDBA_RSP     1
+#define SIR_MAC_DELBA_REQ     2
+
+#define SIR_MAC_BA_POLICY_DELAYED       0
+#define SIR_MAC_BA_POLICY_IMMEDIATE     1
+#define SIR_MAC_BA_AMSDU_SUPPORTED      1
+#define SIR_MAC_BA_DEFAULT_BUFF_SIZE    64
+
+#define MAX_BA_BUFF_SIZE    80
+
+#ifdef ANI_SUPPORT_11H
+#define SIR_MAC_ACTION_MEASURE_REQUEST_ID      0
+#define SIR_MAC_ACTION_MEASURE_REPORT_ID       1
+#define SIR_MAC_ACTION_TPC_REQUEST_ID          2
+#define SIR_MAC_ACTION_TPC_REPORT_ID           3
+#endif /* ANI_SUPPORT_11H */
+#define SIR_MAC_ACTION_CHANNEL_SWITCH_ID       4
+
+#ifdef ANI_SUPPORT_11H
+#define SIR_MAC_BASIC_MEASUREMENT_TYPE         0
+#define SIR_MAC_CCA_MEASUREMENT_TYPE           1
+#define SIR_MAC_RPI_MEASUREMENT_TYPE           2
+#endif /* ANI_SUPPORT_11H */
+
+/* RRM related. */
+/* Refer IEEE Std 802.11k-2008, Section 7.3.2.21, table 7.29 */
+
+#define SIR_MAC_RRM_CHANNEL_LOAD_TYPE          3
+#define SIR_MAC_RRM_NOISE_HISTOGRAM_BEACON     4
+#define SIR_MAC_RRM_BEACON_TYPE                5
+#define SIR_MAC_RRM_FRAME_TYPE                 6
+#define SIR_MAC_RRM_STA_STATISTICS_TYPE        7
+#define SIR_MAC_RRM_LCI_TYPE                   8
+#define SIR_MAC_RRM_TSM_TYPE                   9
+#define SIR_MAC_RRM_LOCATION_CIVIC_TYPE        11
+#define SIR_MAC_RRM_FINE_TIME_MEAS_TYPE        16
+
+/* RRM action codes */
+#define SIR_MAC_RRM_RADIO_MEASURE_REQ          0
+#define SIR_MAC_RRM_RADIO_MEASURE_RPT          1
+#define SIR_MAC_RRM_LINK_MEASUREMENT_REQ       2
+#define SIR_MAC_RRM_LINK_MEASUREMENT_RPT       3
+#define SIR_MAC_RRM_NEIGHBOR_REQ               4
+#define SIR_MAC_RRM_NEIGHBOR_RPT               5
+
+/* VHT Action Field */
+#define SIR_MAC_VHT_GID_NOTIFICATION           1
+#define SIR_MAC_VHT_OPMODE_NOTIFICATION        2
+
+#define SIR_MAC_VHT_OPMODE_SIZE                3
+
+#define NUM_OF_SOUNDING_DIMENSIONS	1 /*Nss - 1, (Nss = 2 for 2x2)*/
+/* HT Action Field Codes */
+#define SIR_MAC_SM_POWER_SAVE       1
+
+/* DLP action frame types */
+#define SIR_MAC_DLP_REQ             0
+#define SIR_MAC_DLP_RSP             1
+#define SIR_MAC_DLP_TEARDOWN        2
+
+/* block acknowledgment action frame types */
+#define SIR_MAC_ACTION_VENDOR_SPECIFIC 9
+#define SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY     0x7F
+#define SIR_MAC_ACTION_P2P_SUBTYPE_PRESENCE_RSP     2
+
+/* Public Action for 20/40 BSS Coexistence */
+#define SIR_MAC_ACTION_2040_BSS_COEXISTENCE     0
+#define SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID    4
+
+/* Public Action frames for GAS */
+#define SIR_MAC_ACTION_GAS_INITIAL_REQUEST      0x0A
+#define SIR_MAC_ACTION_GAS_INITIAL_RESPONSE     0x0B
+#define SIR_MAC_ACTION_GAS_COMEBACK_REQUEST     0x0C
+#define SIR_MAC_ACTION_GAS_COMEBACK_RESPONSE    0x0D
+
+#ifdef WLAN_FEATURE_11W
+/* 11w SA query request/response action frame category code */
+#define SIR_MAC_SA_QUERY_REQ             0
+#define SIR_MAC_SA_QUERY_RSP             1
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+#define SIR_MAC_TDLS_SETUP_REQ           0
+#define SIR_MAC_TDLS_SETUP_RSP           1
+#define SIR_MAC_TDLS_SETUP_CNF           2
+#define SIR_MAC_TDLS_TEARDOWN            3
+#define SIR_MAC_TDLS_PEER_TRAFFIC_IND    4
+#define SIR_MAC_TDLS_CH_SWITCH_REQ       5
+#define SIR_MAC_TDLS_CH_SWITCH_RSP       6
+#define SIR_MAC_TDLS_PEER_TRAFFIC_RSP    9
+#define SIR_MAC_TDLS_DIS_REQ             10
+#define SIR_MAC_TDLS_DIS_RSP             14
+#endif
+
+/* WNM Action field values; IEEE Std 802.11-2012, 8.5.14.1, Table 8-250 */
+#define SIR_MAC_WNM_BSS_TM_QUERY         6
+#define SIR_MAC_WNM_BSS_TM_REQUEST       7
+#define SIR_MAC_WNM_BSS_TM_RESPONSE      8
+#define SIR_MAC_WNM_NOTIF_REQUEST        26
+#define SIR_MAC_WNM_NOTIF_RESPONSE       27
+
+/* Protected Dual of Public Action(PDPA) frames Action field */
+#define SIR_MAC_PDPA_GAS_INIT_REQ      10
+#define SIR_MAC_PDPA_GAS_INIT_RSP      11
+#define SIR_MAC_PDPA_GAS_COMEBACK_REQ  12
+#define SIR_MAC_PDPA_GAS_COMEBACK_RSP  13
+
+#define SIR_MAC_MAX_RANDOM_LENGTH   2306
+
+/* ----------------------------------------------------------------------------- */
+/* EID (Element ID) definitions */
+/* and their min/max lengths */
+/* ----------------------------------------------------------------------------- */
+
+#define SIR_MAC_SSID_EID               0
+#define SIR_MAC_SSID_EID_MIN               0
+#define SIR_MAC_SSID_EID_MAX               32
+#define SIR_MAC_RATESET_EID            1
+#define SIR_MAC_RATESET_EID_MIN            1
+#define SIR_MAC_RATESET_EID_MAX            12
+#define SIR_MAC_FH_PARAM_SET_EID       2
+#define SIR_MAC_FH_PARAM_SET_EID_MIN       5
+#define SIR_MAC_FH_PARAM_SET_EID_MAX       5
+#define SIR_MAC_DS_PARAM_SET_EID       3
+#define SIR_MAC_DS_PARAM_SET_EID_MIN       1
+#define SIR_MAC_DS_PARAM_SET_EID_MAX       1
+#define SIR_MAC_CF_PARAM_SET_EID       4
+#define SIR_MAC_CF_PARAM_SET_EID_MIN       6
+#define SIR_MAC_CF_PARAM_SET_EID_MAX       6
+#define SIR_MAC_TIM_EID                5
+#define SIR_MAC_TIM_EID_MIN                3
+#define SIR_MAC_TIM_EID_MAX                254
+#define SIR_MAC_IBSS_PARAM_SET_EID     6
+#define SIR_MAC_IBSS_PARAM_SET_EID_MIN     2
+#define SIR_MAC_IBSS_PARAM_SET_EID_MAX     2
+#define SIR_MAC_COUNTRY_EID            7
+#define SIR_MAC_COUNTRY_EID_MIN            6
+#define SIR_MAC_COUNTRY_EID_MAX            254
+#define SIR_MAC_FH_PARAMS_EID          8
+#define SIR_MAC_FH_PARAMS_EID_MIN          4
+#define SIR_MAC_FH_PARAMS_EID_MAX          4
+#define SIR_MAC_FH_PATTERN_EID         9
+#define SIR_MAC_FH_PATTERN_EID_MIN         4
+#define SIR_MAC_FH_PATTERN_EID_MAX         254
+#define SIR_MAC_REQUEST_EID            10
+#define SIR_MAC_REQUEST_EID_MIN            1
+#define SIR_MAC_REQUEST_EID_MAX            255
+#define SIR_MAC_QBSS_LOAD_EID          11
+#define SIR_MAC_QBSS_LOAD_EID_MIN          5
+#define SIR_MAC_QBSS_LOAD_EID_MAX          5
+#define SIR_MAC_EDCA_PARAM_SET_EID     12       /* EDCA parameter set */
+#define SIR_MAC_EDCA_PARAM_SET_EID_MIN     18
+#define SIR_MAC_EDCA_PARAM_SET_EID_MAX     20   /* TBD temp - change backto 18 */
+#define SIR_MAC_TSPEC_EID              13
+#define SIR_MAC_TSPEC_EID_MIN              55
+#define SIR_MAC_TSPEC_EID_MAX              55
+#define SIR_MAC_TCLAS_EID              14
+#define SIR_MAC_TCLAS_EID_MIN              4
+#define SIR_MAC_TCLAS_EID_MAX              255
+#define SIR_MAC_QOS_SCHEDULE_EID       15
+#define SIR_MAC_QOS_SCHEDULE_EID_MIN       14
+#define SIR_MAC_QOS_SCHEDULE_EID_MAX       14
+#define SIR_MAC_CHALLENGE_TEXT_EID     16
+#define SIR_MAC_CHALLENGE_TEXT_EID_MIN     1
+#define SIR_MAC_CHALLENGE_TEXT_EID_MAX     253
+/* reserved       17-31 */
+#define SIR_MAC_PWR_CONSTRAINT_EID     32
+#define SIR_MAC_PWR_CONSTRAINT_EID_MIN     1
+#define SIR_MAC_PWR_CONSTRAINT_EID_MAX     1
+#define SIR_MAC_PWR_CAPABILITY_EID     33
+#define SIR_MAC_PWR_CAPABILITY_EID_MIN     2
+#define SIR_MAC_PWR_CAPABILITY_EID_MAX     2
+#define SIR_MAC_TPC_REQ_EID            34
+#define SIR_MAC_TPC_REQ_EID_MIN            0
+#define SIR_MAC_TPC_REQ_EID_MAX            255
+/* SIR_MAC_EXTENDED_CAP_EID    35 */
+#define SIR_MAC_TPC_RPT_EID            35
+#define SIR_MAC_TPC_RPT_EID_MIN            2
+#define SIR_MAC_TPC_RPT_EID_MAX            2
+#define SIR_MAC_SPRTD_CHNLS_EID        36
+#define SIR_MAC_SPRTD_CHNLS_EID_MIN        2
+#define SIR_MAC_SPRTD_CHNLS_EID_MAX        254
+#define SIR_MAC_CHNL_SWITCH_ANN_EID    37
+#define SIR_MAC_CHNL_SWITCH_ANN_EID_MIN    3
+#define SIR_MAC_CHNL_SWITCH_ANN_EID_MAX    3
+#define SIR_MAC_MEAS_REQ_EID           38
+#define SIR_MAC_MEAS_REQ_EID_MIN           3
+#define SIR_MAC_MEAS_REQ_EID_MAX           255
+#define SIR_MAC_MEAS_RPT_EID           39
+#define SIR_MAC_MEAS_RPT_EID_MIN           3
+#define SIR_MAC_MEAS_RPT_EID_MAX           255
+#define SIR_MAC_QUIET_EID              40
+#define SIR_MAC_QUIET_EID_MIN              6
+#define SIR_MAC_QUIET_EID_MAX              6
+#define SIR_MAC_IBSS_DFS_EID           41
+#define SIR_MAC_IBSS_DFS_EID_MIN           7
+#define SIR_MAC_IBSS_DFS_EID_MAX           255
+#define SIR_MAC_ERP_INFO_EID           42
+#define SIR_MAC_ERP_INFO_EID_MIN           0
+#define SIR_MAC_ERP_INFO_EID_MAX           255
+#define SIR_MAC_TS_DELAY_EID           43
+#define SIR_MAC_TS_DELAY_EID_MIN           4
+#define SIR_MAC_TS_DELAY_EID_MAX           4
+#define SIR_MAC_TCLAS_PROC_EID         44
+#define SIR_MAC_TCLAS_PROC_EID_MIN         1
+#define SIR_MAC_TCLAS_PROC_EID_MAX         1
+#define SIR_MAC_QOS_CAPABILITY_EID     46
+#define SIR_MAC_QOS_CAPABILITY_EID_MIN     1
+#define SIR_MAC_QOS_CAPABILITY_EID_MAX     1
+#define SIR_MAC_RSN_EID                48
+#define SIR_MAC_RSN_EID_MIN                4
+#define SIR_MAC_RSN_EID_MAX                254
+
+/* using reserved EID for Qos Action IE for now, */
+/* need to check 11e spec for the actual EID */
+#define SIR_MAC_QOS_ACTION_EID         49
+#define SIR_MAC_QOS_ACTION_EID_MIN         4
+#define SIR_MAC_QOS_ACTION_EID_MAX         255
+#define SIR_MAC_EXTENDED_RATE_EID      50
+#define SIR_MAC_EXTENDED_RATE_EID_MIN      0
+#define SIR_MAC_EXTENDED_RATE_EID_MAX      255
+#define SIR_MAC_CHNL_EXTENDED_SWITCH_ANN_EID 60
+#define SIR_MAC_CHNL_EXTENDED_SWITCH_ANN_EID_MIN    0
+#define SIR_MAC_CHNL_EXTENDED_SWITCH_ANN_EID_MAX    255
+
+#define SIR_MAC_OPERATING_CLASS_EID    59
+#define SIR_MAC_OPERATING_CLASS_EID_MIN    2
+#define SIR_MAC_OPERATING_CLASS_EID_MAX    253
+/* reserved       51-69 */
+#define SIR_MAC_RM_ENABLED_CAPABILITY_EID      70
+#define SIR_MAC_RM_ENABLED_CAPABILITY_EID_MIN  5
+#define SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX  5
+/* reserved       71-220 */
+#define SIR_MAC_WPA_EID                221
+#define SIR_MAC_WPA_EID_MIN                0
+#define SIR_MAC_WPA_EID_MAX                255
+
+#define SIR_MAC_EID_VENDOR                221
+
+#define SIR_MAC_WAPI_EID                68
+/* reserved                            222-254 */
+#define SIR_MAC_HT_CAPABILITIES_EID    45
+#define SIR_MAC_HT_CAPABILITIES_EID_MIN    0
+#define SIR_MAC_HT_CAPABILITIES_EID_MAX    255
+#define SIR_MAC_HT_INFO_EID      61
+#define SIR_MAC_HT_INFO_EID_MIN    0
+#define SIR_MAC_HT_INFO_EID_MAX    255
+
+#define SIR_MAC_VHT_CAPABILITIES_EID   191
+#define SIR_MAC_VHT_OPERATION_EID      192
+#define SIR_MAC_VHT_EXT_BSS_LOAD_EID   193
+#define SIR_MAC_VHT_OPMODE_EID         199
+#define SIR_MAC_MAX_SUPPORTED_MCS_SET    16
+
+#define VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1       390
+#define VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1       390
+#define VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2       780
+#define VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2       780
+
+#define VHT_CAP_160_SUPP 1
+#define VHT_CAP_160_AND_80P80_SUPP 2
+
+#define VHT_MCS_1x1 0xFFFC
+#define VHT_MCS_2x2 0xFFF3
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+#define SIR_MAC_QCOM_VENDOR_EID      200
+#define SIR_MAC_QCOM_VENDOR_OUI      "\x00\xA0\xC6"
+#define SIR_MAC_QCOM_VENDOR_SIZE     3
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+/* / Workaround IE to change beacon length when it is 4*n+1 */
+#define SIR_MAC_ANI_WORKAROUND_EID     255
+#define SIR_MAC_ANI_WORKAROUND_EID_MIN     0
+#define SIR_MAC_ANI_WORKAROUND_EID_MAX     255
+
+#define SIR_MAC_MAX_ADD_IE_LENGTH       2048
+
+/* / Maximum length of each IE */
+#define SIR_MAC_MAX_IE_LENGTH       255
+
+/* / Maximum length of each IE */
+#define SIR_MAC_RSN_IE_MAX_LENGTH   255
+/* / Minimum length of each IE */
+#define SIR_MAC_RSN_IE_MIN_LENGTH   2
+#define SIR_MAC_WPA_IE_MIN_LENGTH   6
+
+#ifdef FEATURE_WLAN_ESE
+#define ESE_VERSION_4               4
+#define ESE_VERSION_SUPPORTED       ESE_VERSION_4
+
+/* When station sends Radio Management Cap. */
+/* State should be normal=1 */
+/* Mbssid Mask should be 0 */
+#define RM_STATE_NORMAL             1
+#endif
+
+#define SIR_MAC_OUI_VERSION_1         1
+
+/* OWE DH Parameter element https://tools.ietf.org/html/rfc8110 */
+#define SIR_DH_PARAMETER_ELEMENT_EXT_EID 32
+
+/* OUI and type definition for WPA IE in network byte order */
+#define SIR_MAC_WPA_OUI             0x01F25000
+#define SIR_MAC_WME_OUI             0x02F25000
+#define SIR_MAC_WSM_OUI             SIR_MAC_WME_OUI
+#define SIR_MAC_WSC_OUI             "\x00\x50\xf2\x04"
+#define SIR_MAC_WSC_OUI_SIZE        4
+#define SIR_MAC_P2P_OUI             "\x50\x6f\x9a\x09"
+#define SIR_MAC_P2P_OUI_SIZE        4
+#define SIR_P2P_NOA_ATTR            12
+#define SIR_MAX_NOA_ATTR_LEN        31
+#define SIR_MAX_NOA_DESCR           2
+#define SIR_P2P_IE_HEADER_LEN       6
+
+#define SIR_MAC_CISCO_OUI "\x00\x40\x96"
+#define SIR_MAC_CISCO_OUI_SIZE 3
+
+#define SIR_MAC_QCN_OUI_TYPE   "\x8c\xfd\xf0\x01"
+#define SIR_MAC_QCN_OUI_TYPE_SIZE  4
+
+/* MBO OUI definitions */
+#define SIR_MAC_MBO_OUI "\x50\x6f\x9a\x16"
+#define SIR_MAC_MBO_OUI_SIZE 4
+
+/* min size of wme oui header: oui(3) + type + subtype + version */
+#define SIR_MAC_OUI_WME_HDR_MIN       6
+
+/* OUI subtype and their lengths */
+#define SIR_MAC_OUI_SUBTYPE_WME_INFO  0
+#define SIR_MAC_OUI_WME_INFO_MIN      7
+#define SIR_MAC_OUI_WME_INFO_MAX      7
+
+#define SIR_MAC_OUI_SUBTYPE_WME_PARAM 1
+#define SIR_MAC_OUI_WME_PARAM_MIN     24
+#define SIR_MAC_OUI_WME_PARAM_MAX     24
+
+#define SIR_MAC_OUI_SUBTYPE_WME_TSPEC 2
+#define SIR_MAC_OUI_WME_TSPEC_MIN     61
+#define SIR_MAC_OUI_WME_TSPEC_MAX     61
+
+#define SIR_MAC_OUI_SUBTYPE_WSM_TSPEC 2 /* same as WME TSPEC */
+#define SIR_MAC_OUI_WSM_TSPEC_MIN     61
+#define SIR_MAC_OUI_WSM_TSPEC_MAX     61
+
+/* reserved subtypes                        3-4 */
+/* WSM capability */
+#define SIR_MAC_OUI_SUBTYPE_WSM_CAPABLE     5
+#define SIR_MAC_OUI_WSM_CAPABLE_MIN         7
+#define SIR_MAC_OUI_WSM_CAPABLE_MAX         7
+/* WSM classifier */
+#define SIR_MAC_OUI_SUBTYPE_WSM_TCLAS       6
+#define SIR_MAC_OUI_WSM_TCLAS_MIN           10
+#define SIR_MAC_OUI_WSM_TCLAS_MAX           255
+/* classifier processing element */
+#define SIR_MAC_OUI_SUBTYPE_WSM_TCLASPROC   7
+#define SIR_MAC_OUI_WSM_TCLASPROC_MIN       7
+#define SIR_MAC_OUI_WSM_TCLASPROC_MAX       7
+/* tspec delay element */
+#define SIR_MAC_OUI_SUBTYPE_WSM_TSDELAY     8
+#define SIR_MAC_OUI_WSM_TSDELAY_MIN         10
+#define SIR_MAC_OUI_WSM_TSDELAY_MAX         10
+/* schedule element */
+#define SIR_MAC_OUI_SUBTYPE_WSM_SCHEDULE    9
+#define SIR_MAC_OUI_WSM_SCHEDULE_MIN        20
+#define SIR_MAC_OUI_WSM_SCHEDULE_MAX        20
+
+#define SIR_MAC_NS_OFFLOAD_SIZE             1   /* support only one IPv6 offload */
+/* Number of target IP V6 addresses for NS offload */
+#define SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA   16
+#define SIR_MAC_IPV6_ADDR_LEN               16
+#define SIR_IPV6_ADDR_VALID                 1
+#define SIR_IPV6_ADDR_UC_TYPE               0
+#define SIR_IPV6_ADDR_AC_TYPE               1
+
+/* ----------------------------------------------------------------------------- */
+
+/* OFFSET definitions for fixed fields in Management frames */
+
+/* Beacon/Probe Response offsets */
+#define SIR_MAC_TS_OFFSET                    0
+#define SIR_MAC_BEACON_INT_OFFSET            8  /* Beacon Interval offset */
+#define SIR_MAC_B_PR_CAPAB_OFFSET            10
+#define SIR_MAC_B_PR_SSID_OFFSET             12
+
+/* Association/Reassociation offsets */
+#define SIR_MAC_ASSOC_CAPAB_OFFSET           0
+#define SIR_MAC_LISTEN_INT_OFFSET            2  /* Listen Interval offset */
+#define SIR_MAC_ASSOC_SSID_OFFSET            4
+#define SIR_MAC_CURRENT_AP_OFFSET            4
+#define SIR_MAC_REASSOC_SSID_OFFSET          10
+#define SIR_MAC_ASSOC_STATUS_CODE_OFFSET     2
+#define SIR_MAC_ASSOC_AID_OFFSET             4
+#define SIR_MAC_ASSOC_RSP_RATE_OFFSET        6
+
+/* Disassociation/Deauthentication offsets */
+#define SIR_MAC_REASON_CODE_OFFSET           0
+
+/* Probe Request offset */
+#define SIR_MAC_PROBE_REQ_SSID_OFFSET        0
+
+/* Authentication offsets */
+#define SIR_MAC_AUTH_ALGO_OFFSET             0
+#define SIR_MAC_AUTH_XACT_SEQNUM_OFFSET      2
+#define SIR_MAC_AUTH_STATUS_CODE_OFFSET      4
+
+/* / Transaction sequence number definitions (used in Authentication frames) */
+#define    SIR_MAC_AUTH_FRAME_1        1
+#define    SIR_MAC_AUTH_FRAME_2        2
+#define    SIR_MAC_AUTH_FRAME_3        3
+#define    SIR_MAC_AUTH_FRAME_4        4
+
+/* / Protocol defined MAX definitions */
+#define SIR_MAC_MAX_SSID_LENGTH              32
+#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        253
+#define SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH    128
+#define SIR_MAC_WEP_IV_LENGTH                4
+#define SIR_MAC_WEP_ICV_LENGTH               4
+#define SIR_MAC_CHALLENGE_ID_LEN             2
+
+/* 2 bytes each for auth algo number, transaction number and status code */
+#define SIR_MAC_AUTH_FRAME_INFO_LEN          6
+/* 2 bytes for ID and length + SIR_MAC_AUTH_CHALLENGE_LENGTH */
+#define SIR_MAC_AUTH_CHALLENGE_BODY_LEN    (SIR_MAC_CHALLENGE_ID_LEN + \
+					    SIR_MAC_AUTH_CHALLENGE_LENGTH)
+
+/* / MAX key length when ULA is used */
+#define SIR_MAC_MAX_KEY_LENGTH               32
+#define SIR_MAC_MAX_KEY_RSC_LEN              16
+
+/* / Macro definitions for get/set on FC fields */
+#define SIR_MAC_GET_PROT_VERSION(x)      ((((uint16_t) x) & 0x0300) >> 8)
+#define SIR_MAC_GET_FRAME_TYPE(x)        ((((uint16_t) x) & 0x0C00) >> 8)
+#define SIR_MAC_GET_FRAME_SUB_TYPE(x)    ((((uint16_t) x) & 0xF000) >> 12)
+#define SIR_MAC_GET_WEP_BIT_IN_FC(x)     (((uint16_t) x) & 0x0040)
+#define SIR_MAC_SET_PROT_VERSION(x)      ((uint16_t) x)
+#define SIR_MAC_SET_FRAME_TYPE(x)        (((uint16_t) x) << 2)
+#define SIR_MAC_SET_FRAME_SUB_TYPE(x)    (((uint16_t) x) << 4)
+#define SIR_MAC_SET_WEP_BIT_IN_FC(x)     (((uint16_t) x) << 14)
+
+/* / Macro definitions for get/set on capabilityInfo bits */
+#define SIR_MAC_GET_ESS(x)               (((uint16_t) x) & 0x0001)
+#define SIR_MAC_GET_IBSS(x)              ((((uint16_t) x) & 0x0002) >> 1)
+#define SIR_MAC_GET_CF_POLLABLE(x)       ((((uint16_t) x) & 0x0004) >> 2)
+#define SIR_MAC_GET_CF_POLL_REQ(x)       ((((uint16_t) x) & 0x0008) >> 3)
+#define SIR_MAC_GET_PRIVACY(x)           ((((uint16_t) x) & 0x0010) >> 4)
+#define SIR_MAC_GET_SHORT_PREAMBLE(x)    ((((uint16_t) x) & 0x0020) >> 5)
+#define SIR_MAC_GET_SPECTRUM_MGMT(x)     ((((uint16_t) x) & 0x0100) >> 8)
+#define SIR_MAC_GET_QOS(x)               ((((uint16_t) x) & 0x0200) >> 9)
+#define SIR_MAC_GET_SHORT_SLOT_TIME(x)   ((((uint16_t) x) & 0x0400) >> 10)
+#define SIR_MAC_GET_APSD(x)              ((((uint16_t) x) & 0x0800) >> 11)
+#define SIR_MAC_GET_RRM(x)               ((((uint16_t) x) & 0x1000) >> 12)
+#define SIR_MAC_GET_BLOCK_ACK(x)         ((((uint16_t) x) & 0xc000) >> CAPABILITY_INFO_DELAYED_BA_BIT)
+#define SIR_MAC_SET_ESS(x)               (((uint16_t) x) | 0x0001)
+#define SIR_MAC_SET_IBSS(x)              (((uint16_t) x) | 0x0002)
+#define SIR_MAC_SET_CF_POLLABLE(x)       (((uint16_t) x) | 0x0004)
+#define SIR_MAC_SET_CF_POLL_REQ(x)       (((uint16_t) x) | 0x0008)
+#define SIR_MAC_SET_PRIVACY(x)           (((uint16_t) x) | 0x0010)
+#define SIR_MAC_SET_SHORT_PREAMBLE(x)    (((uint16_t) x) | 0x0020)
+#define SIR_MAC_SET_SPECTRUM_MGMT(x)     (((uint16_t) x) | 0x0100)
+#define SIR_MAC_SET_QOS(x)               (((uint16_t) x) | 0x0200)
+#define SIR_MAC_SET_SHORT_SLOT_TIME(x)   (((uint16_t) x) | 0x0400)
+#define SIR_MAC_SET_APSD(x)              (((uint16_t) x) | 0x0800)
+#define SIR_MAC_SET_RRM(x)               (((uint16_t) x) | 0x1000)
+#define SIR_MAC_SET_GROUP_ACK(x)         (((uint16_t) x) | 0x4000)
+
+#define SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(x) ((((uint32_t) x) & 0x03800000) >> 23)
+
+/* bitname must be one of the above, eg ESS, CF_POLLABLE, etc. */
+#define SIR_MAC_CLEAR_CAPABILITY(u16value, bitname) \
+	((u16value) &= (~(SIR_MAC_SET_ ## bitname(0))))
+
+#define IS_WES_MODE_ENABLED(x) \
+	((x)->roam.configParam.isWESModeEnabled)
+
+#define BA_RECIPIENT       1
+#define BA_INITIATOR       2
+#define BA_BOTH_DIRECTIONS 3
+
+#define SIR_MAC_VENDOR_AP_1_OUI             "\x00\x0C\x43"
+#define SIR_MAC_VENDOR_AP_1_OUI_LEN         3
+
+#define SIR_MAC_VENDOR_AP_3_OUI             "\x00\x03\x7F"
+#define SIR_MAC_VENDOR_AP_3_OUI_LEN         3
+
+#define SIR_MAC_VENDOR_AP_4_OUI             "\x8C\xFD\xF0"
+#define SIR_MAC_VENDOR_AP_4_OUI_LEN         3
+
+/* Maximum allowable size of a beacon and probe rsp frame */
+#define SIR_MAX_BEACON_SIZE    512
+#define SIR_MAX_PROBE_RESP_SIZE 512
+
+/* / Status Code (present in Management response frames) enum */
+
+typedef enum eSirMacStatusCodes {
+	eSIR_MAC_SUCCESS_STATUS = 0,    /* Reserved */
+	eSIR_MAC_UNSPEC_FAILURE_STATUS = 1,     /* Unspecified reason */
+	/* 802.11 reserved                              2-9 */
+	/*
+	   WMM status codes(standard 1.1 table 9)
+	   Table 9 ADDTS Response Status Codes
+	   Value Operation
+	   0 Admission accepted
+	   1 Invalid parameters
+	   2 Reserved
+	   3 Refused
+	   4-255 Reserved
+	 */
+	eSIR_MAC_WME_INVALID_PARAMS_STATUS = 1, /* ?? */
+	eSIR_MAC_WME_REFUSED_STATUS = 3,        /* ?? */
+	eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS = 10,        /* Cannot support all requested capabilities in the Capability Information field */
+	eSIR_MAC_INABLITY_TO_CONFIRM_ASSOC_STATUS = 11, /* Reassociation denied due to inability to confirm that association exists */
+	eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS = 12,     /* Association denied due to reason outside the scope of this standard */
+	eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS = 13,   /* Responding station does not support the specified authentication algorithm */
+	eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS = 14,     /* Received an Authentication frame with authentication transaction sequence number */
+	/* out of expected sequence */
+	eSIR_MAC_CHALLENGE_FAILURE_STATUS = 15, /* Authentication rejected because of challenge failure */
+	eSIR_MAC_AUTH_RSP_TIMEOUT_STATUS = 16,  /* Authentication rejected due to timeout waiting for next frame in sequence */
+	eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS = 17,     /* Association denied because AP is unable to handle additional associated stations */
+	eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS = 18, /* Association denied due to requesting station not supporting all of the data rates in the */
+	/* BSSBasicRateSet parameter */
+	eSIR_MAC_SHORT_PREAMBLE_NOT_SUPPORTED_STATUS = 19,      /* Association denied due to requesting station not supporting the short preamble */
+	/* option */
+	eSIR_MAC_PBCC_NOT_SUPPORTED_STATUS = 20,        /* Association denied due to requesting station not supporting the PBCC modulation */
+	/* option */
+	eSIR_MAC_CHANNEL_AGILITY_NOT_SUPPORTED_STATUS = 21,     /* Association denied due to requesting station not supporting the Channel Agility */
+	/* option */
+	eSIR_MAC_SPECTRUM_MGMT_REQD_STATUS = 22,        /* Association request rejected because Spectrum Management capability is required */
+	eSIR_MAC_PWR_CAPABILITY_BAD_STATUS = 23,        /* Association request rejected because the information in the Power Capability */
+	/* element is unacceptable */
+	eSIR_MAC_SPRTD_CHANNELS_BAD_STATUS = 24,        /* Association request rejected because the information in the Supported Channels */
+	/* element is unacceptable */
+	eSIR_MAC_SHORT_SLOT_NOT_SUPPORTED_STATUS = 25,   /* Association denied due to requesting station not supporting the Short Slot Time */
+	/* option */
+	eSIR_MAC_DSSS_OFDM_NOT_SUPPORTED_STATUS = 26,   /* Association denied due to requesting station not supporting the DSSS-OFDM option */
+	/* reserved                                     27-29 */
+	eSIR_MAC_TRY_AGAIN_LATER = 30,  /* Association request rejected temporarily, try again later */
+	/* reserved                                     31 */
+	eSIR_MAC_QOS_UNSPECIFIED_FAILURE_STATUS = 32,   /* Unspecified, QoS-related failure */
+	eSIR_MAC_QAP_NO_BANDWIDTH_STATUS = 33,  /* Association denied because QoS AP has insufficient bandwidth to handle another */
+	/* QoS STA */
+	/*
+	 * Association denied due to excessive frame loss rates
+	 * and/or poor conditions/RSSI on cur channel
+	 */
+	eSIR_MAC_XS_FRAME_LOSS_POOR_CHANNEL_RSSI_STATUS = 34,
+	/* rent operating channel */
+	eSIR_MAC_STA_QOS_NOT_SUPPORTED_STATUS = 35,     /* Association (with QoS BSS) denied because the requesting STA does not support the */
+	/* QoS facility */
+	eSIR_MAC_STA_BLK_ACK_NOT_SUPPORTED_STATUS = 36, /* Reserved */
+	eSIR_MAC_REQ_DECLINED_STATUS = 37,      /* The request has been declined */
+	eSIR_MAC_INVALID_PARAM_STATUS = 38,     /* The request has not been successful as one or more parameters have invalid values */
+	eSIR_MAC_TS_NOT_HONOURED_STATUS = 39,   /* The TS has not been created because the request cannot be honored; however, a suggested */
+	/* TSPEC is provided so that the initiating STA may attempt to set another TS */
+	/* with the suggested changes to the TSPEC */
+	eSIR_MAC_INVALID_IE_STATUS = 40,       /* Invalid information element, i.e., an information element defined in this standard for */
+	/* which the content does not meet the specifications in Clause 7 */
+	eSIR_MAC_INVALID_GROUP_CIPHER_STATUS = 41,      /* Invalid group cipher */
+	eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS = 42,   /* Invalid pairwise cipher */
+	eSIR_MAC_INVALID_AKMP_STATUS = 43,      /* Invalid AKMP */
+	eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS = 44,        /* Unsupported RSN information element version */
+	eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS = 45,       /* Invalid RSN information element capabilities */
+	eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS = 46,     /* Cipher suite rejected because of security policy */
+	eSIR_MAC_TS_NOT_CREATED_STATUS = 47,    /* The TS has not been created; however, the HC may be capable of creating a TS, in */
+	/* response to a request, after the time indicated in the TS Delay element */
+	eSIR_MAC_DL_NOT_ALLOWED_STATUS = 48,    /* Direct link is not allowed in the BSS by policy */
+	eSIR_MAC_DEST_STA_NOT_KNOWN_STATUS = 49,        /* The Destination STA is not present within this BSS */
+	eSIR_MAC_DEST_STA_NOT_QSTA_STATUS = 50, /* The Destination STA is not a QoS STA */
+	eSIR_MAC_INVALID_LISTEN_INTERVAL_STATUS = 51,   /* Association denied because the ListenInterval is too large */
+
+	eSIR_MAC_DSSS_CCK_RATE_MUST_SUPPORT_STATUS = 52,        /* FIXME: */
+	eSIR_MAC_DSSS_CCK_RATE_NOT_SUPPORT_STATUS = 53,
+	eSIR_MAC_PSMP_CONTROLLED_ACCESS_ONLY_STATUS = 54,
+#ifdef FEATURE_WLAN_ESE
+	eSIR_MAC_ESE_UNSPECIFIED_QOS_FAILURE_STATUS = 200,      /* ESE-Unspecified, QoS related failure in (Re)Assoc response frames */
+	eSIR_MAC_ESE_TSPEC_REQ_REFUSED_STATUS = 201,    /* ESE-TSPEC request refused due to AP's policy configuration in AddTs Rsp, (Re)Assoc Rsp. */
+	eSIR_MAC_ESE_ASSOC_DENIED_INSUFF_BW_STATUS = 202,       /* ESE-Assoc denied due to insufficient bandwidth to handle new TS in (Re)Assoc Rsp. */
+	eSIR_MAC_ESE_INVALID_PARAMETERS_STATUS = 203,   /* ESE-Invalid parameters. (Re)Assoc request had one or more TSPEC parameters with */
+	/* invalid values. */
+#endif
+
+} tSirMacStatusCodes;
+
+/**
+ * Reason Code (present in Deauthentication/Disassociation
+ * Management frames) enum
+ */
+typedef enum eSirMacReasonCodes {
+	eSIR_MAC_UNSPEC_FAILURE_REASON = 1,     /* Unspecified reason */
+	eSIR_MAC_PREV_AUTH_NOT_VALID_REASON = 2,        /* Previous authentication no longer valid */
+	eSIR_MAC_DEAUTH_LEAVING_BSS_REASON = 3, /* Deauthenticated because sending station is leaving (or has left) IBSS or ESS */
+	eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON = 4, /* Disassociated due to inactivity */
+	eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON = 5, /* Disassociated because AP is unable to handle all currently associated stations */
+	eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON = 6,     /* Class 2 frame received from nonauthenticated station */
+	eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON = 7,    /* Class 3 frame received from nonassociated station */
+	eSIR_MAC_DISASSOC_LEAVING_BSS_REASON = 8,       /* Disassociated because sending station is leaving (or has left) BSS */
+	eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON = 9,  /* Station requesting (re)association is not authenticated with responding station */
+	eSIR_MAC_PWR_CAPABILITY_BAD_REASON = 10,        /* Disassociated because the information in the Power Capability element is unacceptable */
+	eSIR_MAC_SPRTD_CHANNELS_BAD_REASON = 11,        /* Disassociated because the information in the Supported Channels element is unacceptable */
+	/* reserved                                        12 */
+	eSIR_MAC_INVALID_IE_REASON = 13,        /* Invalid information element, i.e., an information element defined in this standard for */
+	/* which the content does not meet the specifications in Clause 7 */
+	eSIR_MAC_MIC_FAILURE_REASON = 14,       /* Message integrity code (MIC) failure */
+	eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON = 15,    /* 4-Way Handshake timeout */
+	eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON = 16,     /* Group Key Handshake timeout */
+	eSIR_MAC_RSN_IE_MISMATCH_REASON = 17,   /* Information element in 4-Way Handshake different from (Re)Association Request/Probe */
+	/* Response/Beacon frame */
+	eSIR_MAC_INVALID_MC_CIPHER_REASON = 18, /* Invalid group cipher */
+	eSIR_MAC_INVALID_UC_CIPHER_REASON = 19, /* Invalid pairwise cipher */
+	eSIR_MAC_INVALID_AKMP_REASON = 20,      /* Invalid AKMP */
+	eSIR_MAC_UNSUPPORTED_RSN_IE_VER_REASON = 21,    /* Unsupported RSN information element version */
+	eSIR_MAC_INVALID_RSN_CAPABILITIES_REASON = 22,  /* Invalid RSN information element capabilities */
+	eSIR_MAC_1X_AUTH_FAILURE_REASON = 23,   /* IEEE 802.1X authentication failed */
+	eSIR_MAC_CIPHER_SUITE_REJECTED_REASON = 24,     /* Cipher suite rejected because of the security policy */
+#ifdef FEATURE_WLAN_TDLS
+	eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE = 25,   /* TDLS direct link teardown due to TDLS peer STA unreachable via the TDLS direct link */
+	eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON = 26,      /* TDLS direct link teardown for unspecified reason */
+#endif
+	/* reserved                                        27 - 30 */
+#ifdef WLAN_FEATURE_11W
+	eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION = 31,      /* Robust management frames policy violation */
+#endif
+	eSIR_MAC_QOS_UNSPECIFIED_REASON = 32,   /* Disassociated for unspecified, QoS-related reason */
+	eSIR_MAC_QAP_NO_BANDWIDTH_REASON = 33,  /* Disassociated because QoS AP lacks sufficient bandwidth for this QoS STA */
+	eSIR_MAC_XS_UNACKED_FRAMES_REASON = 34, /* Disassociated because excessive number of frames need to be acknowledged, but are not */
+	/* acknowledged due to AP transmissions and/or poor channel conditions */
+	eSIR_MAC_BAD_TXOP_USE_REASON = 35,      /* Disassociated because STA is transmitting outside the limits of its TXOPs */
+	eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON = 36,  /* Requested from peer STA as the STA is leaving the BSS (or resetting) */
+	eSIR_MAC_PEER_REJECT_MECHANISIM_REASON = 37,    /* Requested from peer STA as it does not want to use the mechanism */
+	eSIR_MAC_MECHANISM_NOT_SETUP_REASON = 38,       /* Requested from peer STA as the STA received frames using the mechanism for which a */
+	/* setup is required */
+	eSIR_MAC_PEER_TIMEDOUT_REASON = 39,     /* Requested from peer STA due to timeout */
+	eSIR_MAC_CIPHER_NOT_SUPPORTED_REASON = 45,      /* Peer STA does not support the requested cipher suite */
+	eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON = 46, /* FT reason */
+	/* reserved                                         47 - 65535. */
+	eSIR_BEACON_MISSED = 65534,     /* We invented this to tell beacon missed case */
+} tSirMacReasonCodes;
+
+/* BA Initiator v/s Recipient */
+typedef enum eBADirection {
+	eBA_RECIPIENT,
+	eBA_INITIATOR
+} tBADirection;
+
+/* A-MPDU/BA Enable/Disable in Tx/Rx direction */
+typedef enum eBAEnable {
+	eBA_DISABLE,
+	eBA_ENABLE
+} tBAEnable;
+
+/* A-MPDU/BA Policy */
+typedef enum eBAPolicy {
+	eBA_UNCOMPRESSED,
+	eBA_COMPRESSED
+} tBAPolicy;
+
+/* A-MPDU/BA Policy */
+typedef enum eBAPolicyType {
+	eBA_POLICY_DELAYED,
+	eBA_POLICY_IMMEDIATE
+} tBAPolicyType;
+
+/* / Frame control field format (2 bytes) */
+typedef struct sSirMacFrameCtl {
+
+#ifndef ANI_LITTLE_BIT_ENDIAN
+
+	uint8_t subType:4;
+	uint8_t type:2;
+	uint8_t protVer:2;
+
+	uint8_t order:1;
+	uint8_t wep:1;
+	uint8_t moreData:1;
+	uint8_t powerMgmt:1;
+	uint8_t retry:1;
+	uint8_t moreFrag:1;
+	uint8_t fromDS:1;
+	uint8_t toDS:1;
+
+#else
+
+	uint8_t protVer:2;
+	uint8_t type:2;
+	uint8_t subType:4;
+
+	uint8_t toDS:1;
+	uint8_t fromDS:1;
+	uint8_t moreFrag:1;
+	uint8_t retry:1;
+	uint8_t powerMgmt:1;
+	uint8_t moreData:1;
+	uint8_t wep:1;
+	uint8_t order:1;
+
+#endif
+
+} qdf_packed tSirMacFrameCtl, *tpSirMacFrameCtl;
+
+/* / Sequence control field */
+typedef struct sSirMacSeqCtl {
+
+#ifndef ANI_LITTLE_BIT_ENDIAN
+
+	uint8_t seqNumLo:4;
+	uint8_t fragNum:4;
+
+	uint8_t seqNumHi:8;
+
+#else
+
+	uint8_t fragNum:4;
+	uint8_t seqNumLo:4;
+	uint8_t seqNumHi:8;
+
+#endif
+} qdf_packed tSirMacSeqCtl, *tpSirMacSeqCtl;
+
+/* / QoS control field */
+typedef struct sSirMacQosCtl {
+
+#ifndef ANI_LITTLE_BIT_ENDIAN
+
+	uint8_t rsvd:1;
+	uint8_t ackPolicy:2;
+	uint8_t esop_txopUnit:1;
+	uint8_t tid:4;
+
+	uint8_t txop:8;
+
+#else
+
+	uint8_t tid:4;
+	uint8_t esop_txopUnit:1;
+	uint8_t ackPolicy:2;
+	uint8_t rsvd:1;
+
+	uint8_t txop:8;
+
+#endif
+} qdf_packed tSirMacQosCtl, *tpSirMacQosCtl;
+
+/* / Length (in bytes) of MAC header in 3 address format */
+#define SIR_MAC_HDR_LEN_3A    24
+
+typedef uint8_t tSirMacAddr[ETH_ALEN];
+
+/* / 3 address MAC data header format (24/26 bytes) */
+typedef struct sSirMacDot3Hdr {
+	tSirMacAddr da;
+	tSirMacAddr sa;
+	uint16_t length;
+} qdf_packed tSirMacDot3Hdr, *tpSirMacDot3Hdr;
+
+/* / 3 address MAC data header format (24/26 bytes) */
+typedef struct sSirMacDataHdr3a {
+	tSirMacFrameCtl fc;
+	uint8_t durationLo;
+	uint8_t durationHi;
+	tSirMacAddr addr1;
+	tSirMacAddr addr2;
+	tSirMacAddr addr3;
+	tSirMacSeqCtl seqControl;
+	tSirMacQosCtl qosControl;
+} qdf_packed tSirMacDataHdr3a, *tpSirMacDataHdr3a;
+
+/* / Management header format */
+typedef struct sSirMacMgmtHdr {
+	tSirMacFrameCtl fc;
+	uint8_t durationLo;
+	uint8_t durationHi;
+	tSirMacAddr da;
+	tSirMacAddr sa;
+	tSirMacAddr bssId;
+	tSirMacSeqCtl seqControl;
+} qdf_packed tSirMacMgmtHdr, *tpSirMacMgmtHdr;
+
+/* / ERP information field */
+typedef struct sSirMacErpInfo {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint8_t reserved:5;
+	uint8_t barkerPreambleMode:1;
+	uint8_t useProtection:1;
+	uint8_t nonErpPresent:1;
+#else
+	uint8_t nonErpPresent:1;
+	uint8_t useProtection:1;
+	uint8_t barkerPreambleMode:1;
+	uint8_t reserved:5;
+#endif
+} qdf_packed tSirMacErpInfo, *tpSirMacErpInfo;
+
+/* / Capability information field */
+typedef struct sSirMacCapabilityInfo {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint16_t immediateBA:1;
+	uint16_t delayedBA:1;
+	uint16_t dsssOfdm:1;
+	uint16_t rrm:1;
+	uint16_t apsd:1;
+	uint16_t shortSlotTime:1;
+	uint16_t qos:1;
+	uint16_t spectrumMgt:1;
+	uint16_t channelAgility:1;
+	uint16_t pbcc:1;
+	uint16_t shortPreamble:1;
+	uint16_t privacy:1;
+	uint16_t cfPollReq:1;
+	uint16_t cfPollable:1;
+	uint16_t ibss:1;
+	uint16_t ess:1;
+#else
+	uint16_t ess:1;
+	uint16_t ibss:1;
+	uint16_t cfPollable:1;
+	uint16_t cfPollReq:1;
+	uint16_t privacy:1;
+	uint16_t shortPreamble:1;
+	uint16_t pbcc:1;
+	uint16_t channelAgility:1;
+	uint16_t spectrumMgt:1;
+	uint16_t qos:1;
+	uint16_t shortSlotTime:1;
+	uint16_t apsd:1;
+	uint16_t rrm:1;
+	uint16_t dsssOfdm:1;
+	uint16_t delayedBA:1;
+	uint16_t immediateBA:1;
+#endif
+} qdf_packed tSirMacCapabilityInfo, *tpSirMacCapabilityInfo;
+
+typedef struct sSirMacCfParamSet {
+	uint8_t cfpCount;
+	uint8_t cfpPeriod;
+	uint16_t cfpMaxDuration;
+	uint16_t cfpDurRemaining;
+} qdf_packed tSirMacCfParamSet;
+
+typedef struct sSirMacTim {
+	uint8_t dtimCount;
+	uint8_t dtimPeriod;
+	uint8_t bitmapControl;
+	uint8_t bitmapLength;
+	uint8_t bitmap[251];
+} qdf_packed tSirMacTim;
+
+/* 12 Bytes long because this structure can be used to represent rate */
+/* and extended rate set IEs */
+/* The parser assume this to be at least 12 */
+typedef struct sSirMacRateSet {
+	uint8_t numRates;
+	uint8_t rate[SIR_MAC_RATESET_EID_MAX];
+} qdf_packed tSirMacRateSet;
+
+/** struct merged_mac_rate_set - merged mac rate set
+ * @num_rates: num of rates
+ * @rate: rate list
+ */
+struct merged_mac_rate_set {
+	uint8_t num_rates;
+	uint8_t rate[2 * SIR_MAC_RATESET_EID_MAX];
+};
+
+/* Reserve 1 byte for NULL character in the SSID name field to print in %s */
+typedef struct sSirMacSSid {
+	uint8_t length;
+	uint8_t ssId[SIR_MAC_MAX_SSID_LENGTH +1];
+} qdf_packed tSirMacSSid;
+
+typedef struct sSirMacWpaInfo {
+	uint8_t length;
+	uint8_t info[SIR_MAC_MAX_IE_LENGTH];
+} qdf_packed tSirMacWpaInfo, *tpSirMacWpaInfo,
+tSirMacRsnInfo, *tpSirMacRsnInfo;
+
+typedef struct sSirMacWapiInfo {
+	uint8_t length;
+	uint8_t info[SIR_MAC_MAX_IE_LENGTH];
+} qdf_packed tSirMacWapiInfo, *tpSirMacWapiInfo;
+
+typedef struct sSirMacFHParamSet {
+	uint16_t dwellTime;
+	uint8_t hopSet;
+	uint8_t hopPattern;
+	uint8_t hopIndex;
+} tSirMacFHParamSet, *tpSirMacFHParamSet;
+
+typedef struct sSirMacIBSSParams {
+	uint16_t atim;
+} tSirMacIBSSParams, *tpSirMacIBSSParams;
+
+typedef struct sSirMacRRMEnabledCap {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint8_t reserved:6;
+	uint8_t AntennaInformation:1;
+	uint8_t BSSAvailAdmission:1;
+	uint8_t BssAvgAccessDelay:1;
+	uint8_t RSNIMeasurement:1;
+	uint8_t RCPIMeasurement:1;
+	uint8_t NeighborTSFOffset:1;
+	uint8_t MeasurementPilotEnabled:1;
+	uint8_t MeasurementPilot:3;
+	uint8_t nonOperatinChanMax:3;
+	uint8_t operatingChanMax:3;
+	uint8_t RRMMIBEnabled:1;
+	uint8_t APChanReport:1;
+	uint8_t triggeredTCM:1;
+	uint8_t TCMCapability:1;
+	uint8_t LCIAzimuth:1;
+	uint8_t LCIMeasurement:1;
+	uint8_t statistics:1;
+	uint8_t NoiseHistogram:1;
+	uint8_t ChannelLoad:1;
+	uint8_t FrameMeasurement:1;
+	uint8_t BeaconRepCond:1;
+	uint8_t BeaconTable:1;
+	uint8_t BeaconActive:1;
+	uint8_t BeaconPassive:1;
+	uint8_t repeated:1;
+	uint8_t parallel:1;
+	uint8_t NeighborRpt:1;
+	uint8_t LinkMeasurement:1;
+	uint8_t present;
+#else
+	uint8_t present;
+	uint8_t LinkMeasurement:1;
+	uint8_t NeighborRpt:1;
+	uint8_t parallel:1;
+	uint8_t repeated:1;
+	uint8_t BeaconPassive:1;
+	uint8_t BeaconActive:1;
+	uint8_t BeaconTable:1;
+	uint8_t BeaconRepCond:1;
+	uint8_t FrameMeasurement:1;
+	uint8_t ChannelLoad:1;
+	uint8_t NoiseHistogram:1;
+	uint8_t statistics:1;
+	uint8_t LCIMeasurement:1;
+	uint8_t LCIAzimuth:1;
+	uint8_t TCMCapability:1;
+	uint8_t triggeredTCM:1;
+	uint8_t APChanReport:1;
+	uint8_t RRMMIBEnabled:1;
+	uint8_t operatingChanMax:3;
+	uint8_t nonOperatinChanMax:3;
+	uint8_t MeasurementPilot:3;
+	uint8_t MeasurementPilotEnabled:1;
+	uint8_t NeighborTSFOffset:1;
+	uint8_t RCPIMeasurement:1;
+	uint8_t RSNIMeasurement:1;
+	uint8_t BssAvgAccessDelay:1;
+	uint8_t BSSAvailAdmission:1;
+	uint8_t AntennaInformation:1;
+	uint8_t reserved:6;
+#endif
+} tSirMacRRMEnabledCap, *tpSirMacRRMEnabledCap;
+
+/* ----------------
+ *  EDCA Profiles
+ * ---------------
+ */
+
+#define EDCA_AC_BE 0
+#define EDCA_AC_BK 1
+#define EDCA_AC_VI 2
+#define EDCA_AC_VO 3
+#define AC_MGMT_LO 4
+#define AC_MGMT_HI 5
+#define MAX_NUM_AC 4
+
+/* access categories */
+#define SIR_MAC_EDCAACI_BESTEFFORT  (EDCA_AC_BE)
+#define SIR_MAC_EDCAACI_BACKGROUND  (EDCA_AC_BK)
+#define SIR_MAC_EDCAACI_VIDEO       (EDCA_AC_VI)
+#define SIR_MAC_EDCAACI_VOICE       (EDCA_AC_VO)
+
+#define MU_EDCA_DEF_AIFSN     0
+#define MU_EDCA_DEF_CW_MAX    15
+#define MU_EDCA_DEF_CW_MIN    15
+#define MU_EDCA_DEF_TIMER     255
+/* access category record */
+typedef struct sSirMacAciAifsn {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint8_t rsvd:1;
+	uint8_t aci:2;
+	uint8_t acm:1;
+	uint8_t aifsn:4;
+#else
+	uint8_t aifsn:4;
+	uint8_t acm:1;
+	uint8_t aci:2;
+	uint8_t rsvd:1;
+#endif
+} qdf_packed tSirMacAciAifsn;
+
+/* contention window size */
+typedef struct sSirMacCW {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint8_t max:4;
+	uint8_t min:4;
+#else
+	uint8_t min:4;
+	uint8_t max:4;
+#endif
+} qdf_packed tSirMacCW;
+
+typedef struct sSirMacEdcaParamRecord {
+	tSirMacAciAifsn aci;
+	tSirMacCW cw;
+	union {
+		uint16_t txoplimit;
+		uint16_t mu_edca_timer;
+	};
+	uint8_t no_ack;
+} qdf_packed tSirMacEdcaParamRecord;
+
+typedef struct sSirMacQosInfo {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint8_t uapsd:1;
+	uint8_t txopreq:1;
+	uint8_t qreq:1;
+	uint8_t qack:1;
+	uint8_t count:4;
+#else
+	uint8_t count:4;
+	uint8_t qack:1;
+	uint8_t qreq:1;
+	uint8_t txopreq:1;
+	uint8_t uapsd:1;
+#endif
+} qdf_packed tSirMacQosInfo;
+
+typedef struct sSirMacQosInfoStation {
+#ifdef ANI_LITTLE_BIT_ENDIAN
+	uint8_t acvo_uapsd:1;
+	uint8_t acvi_uapsd:1;
+	uint8_t acbk_uapsd:1;
+	uint8_t acbe_uapsd:1;
+	uint8_t qack:1;
+	uint8_t maxSpLen:2;
+	uint8_t moreDataAck:1;
+#else
+	uint8_t moreDataAck:1;
+	uint8_t maxSpLen:2;
+	uint8_t qack:1;
+	uint8_t acbe_uapsd:1;
+	uint8_t acbk_uapsd:1;
+	uint8_t acvi_uapsd:1;
+	uint8_t acvo_uapsd:1;
+#endif
+} qdf_packed tSirMacQosInfoStation, *tpSirMacQosInfoStation;
+
+typedef struct sSirMacEdcaParamSetIE {
+	uint8_t type;
+	uint8_t length;
+	tSirMacQosInfo qosInfo;
+	uint8_t rsvd;
+	tSirMacEdcaParamRecord acbe;    /* best effort */
+	tSirMacEdcaParamRecord acbk;    /* background */
+	tSirMacEdcaParamRecord acvi;    /* video */
+	tSirMacEdcaParamRecord acvo;    /* voice */
+} qdf_packed tSirMacEdcaParamSetIE;
+
+typedef struct sSirMacQoSParams {
+	uint8_t count;
+	uint16_t limit;
+	uint8_t CWmin[8];
+	uint8_t AIFS[8];
+} qdf_packed tSirMacQoSParams;
+
+/* ts info direction field can take any of these values */
+#define SIR_MAC_DIRECTION_UPLINK    0
+#define SIR_MAC_DIRECTION_DNLINK    1
+#define SIR_MAC_DIRECTION_DIRECT    2
+#define SIR_MAC_DIRECTION_BIDIR     3
+
+/* access policy */
+/* reserved                         0 */
+#define SIR_MAC_ACCESSPOLICY_EDCA   1
+#define SIR_MAC_ACCESSPOLICY_HCCA   2
+#define SIR_MAC_ACCESSPOLICY_BOTH   3
+
+typedef struct sSirMacTSInfoTfc {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint8_t burstSizeDefn:1;
+	uint8_t reserved:7;
+#else
+	uint8_t reserved:7;
+	uint8_t burstSizeDefn:1;
+#endif
+
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint16_t ackPolicy:2;
+	uint16_t userPrio:3;
+	uint16_t psb:1;
+	uint16_t aggregation:1;
+	uint16_t accessPolicy:2;
+	uint16_t direction:2;
+	uint16_t tsid:4;
+	uint16_t trafficType:1;
+#else
+	uint16_t trafficType:1;
+	uint16_t tsid:4;
+	uint16_t direction:2;
+	uint16_t accessPolicy:2;
+	uint16_t aggregation:1;
+	uint16_t psb:1;
+	uint16_t userPrio:3;
+	uint16_t ackPolicy:2;
+#endif
+} qdf_packed tSirMacTSInfoTfc;
+
+typedef struct sSirMacTSInfoSch {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint8_t rsvd:7;
+	uint8_t schedule:1;
+#else
+	uint8_t schedule:1;
+	uint8_t rsvd:7;
+#endif
+} qdf_packed tSirMacTSInfoSch;
+
+typedef struct sSirMacTSInfo {
+	tSirMacTSInfoTfc traffic;
+	tSirMacTSInfoSch schedule;
+} qdf_packed tSirMacTSInfo;
+
+typedef struct sSirMacTspecIE {
+	uint8_t type;
+	uint8_t length;
+	tSirMacTSInfo tsinfo;
+	uint16_t nomMsduSz;
+	uint16_t maxMsduSz;
+	uint32_t minSvcInterval;
+	uint32_t maxSvcInterval;
+	uint32_t inactInterval;
+	uint32_t suspendInterval;
+	uint32_t svcStartTime;
+	uint32_t minDataRate;
+	uint32_t meanDataRate;
+	uint32_t peakDataRate;
+	uint32_t maxBurstSz;
+	uint32_t delayBound;
+	uint32_t minPhyRate;
+	uint16_t surplusBw;
+	uint16_t mediumTime;
+} qdf_packed tSirMacTspecIE;
+
+/* frame classifier types */
+#define SIR_MAC_TCLASTYPE_ETHERNET 0
+#define SIR_MAC_TCLASTYPE_TCPUDPIP 1
+#define SIR_MAC_TCLASTYPE_8021DQ   2
+/* reserved                        3-255 */
+
+typedef struct sSirMacTclasParamEthernet {
+	tSirMacAddr srcAddr;
+	tSirMacAddr dstAddr;
+	uint16_t type;
+} qdf_packed tSirMacTclasParamEthernet;
+
+typedef struct sSirMacTclasParamIPv4 {
+	uint8_t version;
+	uint8_t srcIpAddr[4];
+	uint8_t dstIpAddr[4];
+	uint16_t srcPort;
+	uint16_t dstPort;
+	uint8_t dscp;
+	uint8_t protocol;
+	uint8_t rsvd;
+} qdf_packed tSirMacTclasParamIPv4;
+
+#define SIR_MAC_TCLAS_IPV4  4
+#define SIR_MAC_TCLAS_IPV6  6
+
+typedef struct sSirMacTclasParamIPv6 {
+	uint8_t version;
+	uint8_t srcIpAddr[16];
+	uint8_t dstIpAddr[16];
+	uint16_t srcPort;
+	uint16_t dstPort;
+	uint8_t flowLabel[3];
+} qdf_packed tSirMacTclasParamIPv6;
+
+typedef struct sSirMacTclasParam8021dq {
+	uint16_t tag;
+} qdf_packed tSirMacTclasParam8021dq;
+
+typedef struct sSirMacTclasIE {
+	uint8_t type;
+	uint8_t length;
+	uint8_t userPrio;
+	uint8_t classifierType;
+	uint8_t classifierMask;
+} qdf_packed tSirMacTclasIE;
+
+typedef struct sSirMacTsDelayIE {
+	uint8_t type;
+	uint8_t length;
+	uint32_t delay;
+} qdf_packed tSirMacTsDelayIE;
+
+typedef struct sSirMacScheduleInfo {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint16_t rsvd:9;
+	uint16_t direction:2;
+	uint16_t tsid:4;
+	uint16_t aggregation:1;
+#else
+	uint16_t aggregation:1;
+	uint16_t tsid:4;
+	uint16_t direction:2;
+	uint16_t rsvd:9;
+#endif
+} qdf_packed tSirMacScheduleInfo;
+
+typedef struct sSirMacScheduleIE {
+	uint8_t type;
+	uint8_t length;
+	tSirMacScheduleInfo info;
+	uint32_t svcStartTime;
+	uint32_t svcInterval;
+	uint16_t maxSvcDuration;
+	uint16_t specInterval;
+} qdf_packed tSirMacScheduleIE;
+
+typedef struct sSirMacQosCapabilityIE {
+	uint8_t type;
+	uint8_t length;
+	tSirMacQosInfo qosInfo;
+} qdf_packed tSirMacQosCapabilityIE;
+
+typedef struct sSirMacQosCapabilityStaIE {
+	uint8_t type;
+	uint8_t length;
+	tSirMacQosInfoStation qosInfo;
+} qdf_packed tSirMacQosCapabilityStaIE;
+
+typedef uint32_t tSirMacTimeStamp[2];
+
+typedef uint16_t tSirMacBeaconInterval;
+
+typedef uint16_t tSirMacListenInterval;
+
+typedef uint8_t tSirMacChanNum;
+
+/* IE definitions */
+typedef struct sSirMacSSidIE {
+	uint8_t type;
+	tSirMacSSid ssId;
+} qdf_packed tSirMacSSidIE;
+
+typedef struct sSirMacRateSetIE {
+	uint8_t type;
+	tSirMacRateSet supportedRateSet;
+} qdf_packed tSirMacRateSetIE;
+
+typedef struct sSirMacDsParamSetIE {
+	uint8_t type;
+	uint8_t length;
+	tSirMacChanNum channelNumber;
+} qdf_packed tSirMacDsParamSetIE;
+
+typedef struct sSirMacCfParamSetIE {
+	uint8_t type;
+	uint8_t length;
+	tSirMacCfParamSet cfParams;
+} qdf_packed tSirMacCfParamSetIE;
+
+typedef struct sSirMacChanInfo {
+	tSirMacChanNum firstChanNum;
+	uint8_t numChannels;
+	int8_t maxTxPower;
+} qdf_packed tSirMacChanInfo;
+
+typedef struct sSirMacNonErpPresentIE {
+	uint8_t type;
+	uint8_t length;
+	uint8_t erp;
+} qdf_packed tSirMacNonErpPresentIE;
+
+typedef struct sSirMacPowerCapabilityIE {
+	uint8_t type;
+	uint8_t length;
+	uint8_t minTxPower;
+	uint8_t maxTxPower;
+} tSirMacPowerCapabilityIE;
+
+typedef struct sSirMacSupportedChannelIE {
+	uint8_t type;
+	uint8_t length;
+	uint8_t supportedChannels[96];
+} tSirMacSupportedChannelIE;
+
+typedef struct sSirMacMeasReqField {
+	uint8_t channelNumber;
+	uint8_t measStartTime[8];
+	uint16_t measDuration;
+} tSirMacMeasReqField, *tpSirMacMeasReqField;
+
+typedef struct sSirMacMeasReqIE {
+	uint8_t type;
+	uint8_t length;
+	uint8_t measToken;
+	uint8_t measReqMode;
+	uint8_t measType;
+	tSirMacMeasReqField measReqField;
+} tSirMacMeasReqIE, *tpSirMacMeasReqIE;
+
+#define SIR_MAC_MAX_SUPP_RATES            32
+
+#define SIR_MAC_MAX_SUPP_CHANNELS            100
+#define SIR_MAC_MAX_EXTN_CAP               8
+
+/* VHT Capabilities Info */
+typedef struct sSirMacVHTCapabilityInfo {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint32_t reserved1:2;
+	uint32_t txAntPattern:1;
+	uint32_t rxAntPattern:1;
+	uint32_t vhtLinkAdaptCap:2;
+	uint32_t maxAMPDULenExp:3;
+	uint32_t htcVHTCap:1;
+	uint32_t vhtTXOPPS:1;
+	uint32_t muBeamformeeCap:1;
+	uint32_t muBeamformerCap:1;
+	uint32_t numSoundingDim:3;
+	uint32_t csnofBeamformerAntSup:3;
+	uint32_t suBeamformeeCap:1;
+	uint32_t suBeamFormerCap:1;
+	uint32_t rxSTBC:3;
+	uint32_t txSTBC:1;
+	uint32_t shortGI160and80plus80MHz:1;
+	uint32_t shortGI80MHz:1;
+	uint32_t ldpcCodingCap:1;
+	uint32_t supportedChannelWidthSet:2;
+	uint32_t maxMPDULen:2;
+#else
+	uint32_t maxMPDULen:2;
+	uint32_t supportedChannelWidthSet:2;
+	uint32_t ldpcCodingCap:1;
+	uint32_t shortGI80MHz:1;
+	uint32_t shortGI160and80plus80MHz:1;
+	uint32_t txSTBC:1;
+	uint32_t rxSTBC:3;
+	uint32_t suBeamFormerCap:1;
+	uint32_t suBeamformeeCap:1;
+	uint32_t csnofBeamformerAntSup:3;
+	uint32_t numSoundingDim:3;
+	uint32_t muBeamformerCap:1;
+	uint32_t muBeamformeeCap:1;
+	uint32_t vhtTXOPPS:1;
+	uint32_t htcVHTCap:1;
+	uint32_t maxAMPDULenExp:3;
+	uint32_t vhtLinkAdaptCap:2;
+	uint32_t rxAntPattern:1;
+	uint32_t txAntPattern:1;
+	uint32_t reserved1:2;
+#endif
+} qdf_packed tSirMacVHTCapabilityInfo;
+
+typedef struct sSirMacVHTTxSupDataRateInfo {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint16_t reserved:3;
+	uint16_t txSupDataRate:13;
+#else
+	uint16_t txSupDataRate:13;
+	uint16_t reserved:3;
+#endif
+} qdf_packed tSirMacVHTTxSupDataRateInfo;
+
+typedef struct sSirMacVHTRxSupDataRateInfo {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint16_t reserved:3;
+	uint16_t rxSupDataRate:13;
+#else
+	uint16_t rxSupDataRate:13;
+	uint16_t reserved:3;
+#endif
+} qdf_packed tSirMacVHTRxSupDataRateInfo;
+
+/**
+ * struct sSirVhtMcsInfo - VHT MCS information
+ * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams
+ * @rx_highest: Indicates highest long GI VHT PPDU data rate
+ *      STA can receive. Rate expressed in units of 1 Mbps.
+ *      If this field is 0 this value should not be used to
+ *      consider the highest RX data rate supported.
+ * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams
+ * @tx_highest: Indicates highest long GI VHT PPDU data rate
+ *      STA can transmit. Rate expressed in units of 1 Mbps.
+ *      If this field is 0 this value should not be used to
+ *      consider the highest TX data rate supported.
+ */
+typedef struct sSirVhtMcsInfo {
+	uint16_t rxMcsMap;
+	uint16_t rxHighest;
+	uint16_t txMcsMap;
+	uint16_t txHighest;
+} tSirVhtMcsInfo;
+
+/**
+ * struct sSirVHtCap - VHT capabilities
+ *
+ * This structure is the "VHT capabilities element" as
+ * described in 802.11ac D3.0 8.4.2.160
+ * @vht_cap_info: VHT capability info
+ * @supp_mcs: VHT MCS supported rates
+ */
+typedef struct sSirVHtCap {
+	uint32_t vhtCapInfo;
+	tSirVhtMcsInfo suppMcs;
+} tSirVHTCap;
+
+/**
+ * struct sSirHtCap - HT capabilities
+ *
+ * This structure refers to "HT capabilities element" as
+ * described in 802.11n draft section 7.3.2.52
+ */
+
+typedef struct sSirHtCap {
+	uint16_t capInfo;
+	uint8_t ampduParamsInfo;
+	uint8_t suppMcsSet[16];
+	uint16_t extendedHtCapInfo;
+	uint32_t txBFCapInfo;
+	uint8_t antennaSelectionInfo;
+} tSirHTCap;
+
+/* HT Cap and HT IE Size defines */
+#define HT_CAPABILITY_IE_SIZE                       28
+#define HT_INFO_IE_SIZE                                          24
+
+/* */
+/* Determines the current operating mode of the 802.11n STA */
+/* */
+
+typedef enum eSirMacHTOperatingMode {
+	eSIR_HT_OP_MODE_PURE,   /* No Protection */
+	eSIR_HT_OP_MODE_OVERLAP_LEGACY, /* Overlap Legacy device present, protection is optional */
+	eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT,     /* No legacy device, but 20 MHz HT present */
+	eSIR_HT_OP_MODE_MIXED   /* Protetion is required */
+} tSirMacHTOperatingMode;
+
+/* Spatial Multiplexing(SM) Power Save mode */
+typedef enum eSirMacHTMIMOPowerSaveState {
+	eSIR_HT_MIMO_PS_STATIC = 0,     /* Static SM Power Save mode */
+	eSIR_HT_MIMO_PS_DYNAMIC = 1,    /* Dynamic SM Power Save mode */
+	eSIR_HT_MIMO_PS_NA = 2, /* reserved */
+	eSIR_HT_MIMO_PS_NO_LIMIT = 3    /* SM Power Save disabled */
+} tSirMacHTMIMOPowerSaveState;
+
+typedef enum eSirMacHTChannelWidth {
+	eHT_CHANNEL_WIDTH_20MHZ = 0,
+	eHT_CHANNEL_WIDTH_40MHZ = 1,
+	eHT_CHANNEL_WIDTH_80MHZ = 2,
+	eHT_CHANNEL_WIDTH_160MHZ = 3,
+	eHT_CHANNEL_WIDTH_80P80MHZ = 4,
+	eHT_MAX_CHANNEL_WIDTH
+} tSirMacHTChannelWidth;
+
+typedef enum eSirMacHTChannelType {
+	eHT_CHAN_NO_HT = 0,
+	eHT_CHAN_HT20 = 1,
+	eHT_CHAN_HT40MINUS = 2,
+	eHT_CHAN_HT40PLUS = 3
+} tSirMacHTChannelType;
+
+/* Packet struct for HT capability */
+typedef struct sHtCaps {
+	uint16_t advCodingCap:1;
+	uint16_t supportedChannelWidthSet:1;
+	uint16_t mimoPowerSave:2;
+	uint16_t greenField:1;
+	uint16_t shortGI20MHz:1;
+	uint16_t shortGI40MHz:1;
+	uint16_t txSTBC:1;
+	uint16_t rxSTBC:2;
+	uint16_t delayedBA:1;
+	uint16_t maximalAMSDUsize:1;
+	uint16_t dsssCckMode40MHz:1;
+	uint16_t psmp:1;
+	uint16_t stbcControlFrame:1;
+	uint16_t lsigTXOPProtection:1;
+	uint8_t maxRxAMPDUFactor:2;
+	uint8_t mpduDensity:3;
+	uint8_t reserved1:3;
+	uint8_t supportedMCSSet[16];
+	uint16_t pco:1;
+	uint16_t transitionTime:2;
+	uint16_t reserved2:5;
+	uint16_t mcsFeedback:2;
+	uint16_t reserved3:6;
+	uint32_t txBF:1;
+	uint32_t rxStaggeredSounding:1;
+	uint32_t txStaggeredSounding:1;
+	uint32_t rxZLF:1;
+	uint32_t txZLF:1;
+	uint32_t implicitTxBF:1;
+	uint32_t calibration:2;
+	uint32_t explicitCSITxBF:1;
+	uint32_t explicitUncompressedSteeringMatrix:1;
+	uint32_t explicitBFCSIFeedback:3;
+	uint32_t explicitUncompressedSteeringMatrixFeedback:3;
+	uint32_t explicitCompressedSteeringMatrixFeedback:3;
+	uint32_t csiNumBFAntennae:2;
+	uint32_t uncompressedSteeringMatrixBFAntennae:2;
+	uint32_t compressedSteeringMatrixBFAntennae:2;
+	uint32_t reserved4:7;
+	uint8_t antennaSelection:1;
+	uint8_t explicitCSIFeedbackTx:1;
+	uint8_t antennaIndicesFeedbackTx:1;
+	uint8_t explicitCSIFeedback:1;
+	uint8_t antennaIndicesFeedback:1;
+	uint8_t rxAS:1;
+	uint8_t txSoundingPPDUs:1;
+	uint8_t reserved5:1;
+
+} qdf_packed tHtCaps;
+
+/* During 11h channel switch, the AP can indicate if the
+ * STA needs to stop the transmission or continue until the
+ * channel-switch.
+ * eSIR_CHANSW_MODE_NORMAL - STA can continue transmission
+ * eSIR_CHANSW_MODE_SILENT - STA should stop transmission
+ */
+typedef enum eSirMacChanSwMode {
+	eSIR_CHANSW_MODE_NORMAL = 0,
+	eSIR_CHANSW_MODE_SILENT = 1
+} tSirMacChanSwitchMode;
+
+typedef struct _BarControl {
+
+#ifndef ANI_BIG_BYTE_ENDIAN
+
+	uint16_t barAckPolicy:1;
+	uint16_t multiTID:1;
+	uint16_t bitMap:1;
+	uint16_t rsvd:9;
+	uint16_t numTID:4;
+
+#else
+	uint16_t numTID:4;
+	uint16_t rsvd:9;
+	uint16_t bitMap:1;
+	uint16_t multiTID:1;
+	uint16_t barAckPolicy:1;
+
+#endif
+
+} qdf_packed barCtrlType;
+
+typedef struct _BARFrmStruct {
+	tSirMacFrameCtl fc;
+	uint16_t duration;
+	tSirMacAddr rxAddr;
+	tSirMacAddr txAddr;
+	barCtrlType barControl;
+	tSirMacSeqCtl ssnCtrl;
+} qdf_packed BARFrmType;
+
+/* Supported MCS set */
+#define SIZE_OF_SUPPORTED_MCS_SET                          16
+#define SIZE_OF_BASIC_MCS_SET                              16
+#define VALID_MCS_SIZE                                     77   /* 0-76 */
+#define MCS_RX_HIGHEST_SUPPORTED_RATE_BYTE_OFFSET          10
+#define VALID_MAX_MCS_INDEX                                8
+
+/* */
+/* The following enums will be used to get the "current" HT Capabilities of */
+/* the local STA in a generic fashion. In other words, the following enums */
+/* identify the HT capabilities that can be queried or set. */
+/* */
+typedef enum eHTCapability {
+	eHT_LSIG_TXOP_PROTECTION,
+	eHT_STBC_CONTROL_FRAME,
+	eHT_PSMP,
+	eHT_DSSS_CCK_MODE_40MHZ,
+	eHT_MAX_AMSDU_LENGTH,
+	eHT_MAX_AMSDU_NUM,
+	eHT_RX_STBC,
+	eHT_TX_STBC,
+	eHT_SHORT_GI_40MHZ,
+	eHT_SHORT_GI_20MHZ,
+	eHT_GREENFIELD,
+	eHT_MIMO_POWER_SAVE,
+	eHT_SUPPORTED_CHANNEL_WIDTH_SET,
+	eHT_ADVANCED_CODING,
+	eHT_MAX_RX_AMPDU_FACTOR,
+	eHT_MPDU_DENSITY,
+	eHT_PCO,
+	eHT_TRANSITION_TIME,
+	eHT_MCS_FEEDBACK,
+	eHT_TX_BEAMFORMING,
+	eHT_ANTENNA_SELECTION,
+	/* The following come under Additional HT Capabilities */
+	eHT_SI_GRANULARITY,
+	eHT_CONTROLLED_ACCESS,
+	eHT_RIFS_MODE,
+	eHT_RECOMMENDED_TX_WIDTH_SET,
+	eHT_EXTENSION_CHANNEL_OFFSET,
+	eHT_OP_MODE,
+	eHT_BASIC_STBC_MCS,
+	eHT_DUAL_CTS_PROTECTION,
+	eHT_LSIG_TXOP_PROTECTION_FULL_SUPPORT,
+	eHT_PCO_ACTIVE,
+	eHT_PCO_PHASE
+} tHTCapability;
+
+/* HT Parameters Info */
+typedef struct sSirMacHTParametersInfo {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint8_t reserved:3;
+	uint8_t mpduDensity:3;  /* Dynamic state */
+	uint8_t maxRxAMPDUFactor:2;     /* Dynamic state */
+#else
+	uint8_t maxRxAMPDUFactor:2;
+	uint8_t mpduDensity:3;
+	uint8_t reserved:3;
+#endif
+} qdf_packed tSirMacHTParametersInfo;
+
+/* Extended HT Capabilities Info */
+typedef struct sSirMacExtendedHTCapabilityInfo {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint16_t reserved2:6;
+	uint16_t mcsFeedback:2; /* Static via CFG */
+	uint16_t reserved1:5;
+	uint16_t transitionTime:2;      /* Static via CFG */
+	uint16_t pco:1;         /* Static via CFG */
+#else
+	uint16_t pco:1;
+	uint16_t transitionTime:2;
+	uint16_t reserved1:5;
+	uint16_t mcsFeedback:2;
+	uint16_t reserved2:6;
+#endif
+} qdf_packed tSirMacExtendedHTCapabilityInfo;
+
+/* IEEE 802.11n/D7.0 - 7.3.2.57.4 */
+/* Part of the "supported MCS set field" */
+typedef struct sSirMacRxHighestSupportRate {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint16_t reserved:6;
+	uint16_t rate:10;
+#else
+	uint16_t rate:10;
+	uint16_t reserved:6;
+#endif
+} qdf_packed tSirMacRxHighestSupportRate, *tpSirMacRxHighestSupportRate;
+
+/* Transmit Beam Forming Capabilities Info */
+typedef struct sSirMacTxBFCapabilityInfo {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint32_t reserved:7;
+	uint32_t compressedSteeringMatrixBFAntennae:2;  /* Static via CFG */
+	/* Static via CFG */
+	uint32_t uncompressedSteeringMatrixBFAntennae:2;
+	uint32_t csiNumBFAntennae:2;    /* Static via CFG */
+	/* Static via CFG */
+	uint32_t explicitCompressedSteeringMatrixFeedback:3;
+	/* Static via CFG */
+	uint32_t explicitUncompressedSteeringMatrixFeedback:3;
+	uint32_t explicitBFCSIFeedback:3;       /* Static via CFG */
+	uint32_t explicitUncompressedSteeringMatrix:1;  /* Static via CFG */
+	uint32_t explicitCSITxBF:1;     /* Static via CFG */
+	uint32_t calibration:2; /* Static via CFG */
+	uint32_t implicitTxBF:1;        /* Static via CFG */
+	uint32_t txZLF:1;       /* Static via CFG */
+	uint32_t rxZLF:1;       /* Static via CFG */
+	uint32_t txStaggeredSounding:1; /* Static via CFG */
+	uint32_t rxStaggeredSounding:1; /* Static via CFG */
+	uint32_t txBF:1;        /* Static via CFG */
+#else
+	uint32_t txBF:1;
+	uint32_t rxStaggeredSounding:1;
+	uint32_t txStaggeredSounding:1;
+	uint32_t rxZLF:1;
+	uint32_t txZLF:1;
+	uint32_t implicitTxBF:1;
+	uint32_t calibration:2;
+	uint32_t explicitCSITxBF:1;
+	uint32_t explicitUncompressedSteeringMatrix:1;
+	uint32_t explicitBFCSIFeedback:3;
+	uint32_t explicitUncompressedSteeringMatrixFeedback:3;
+	uint32_t explicitCompressedSteeringMatrixFeedback:3;
+	uint32_t csiNumBFAntennae:2;
+	uint32_t uncompressedSteeringMatrixBFAntennae:2;
+	uint32_t compressedSteeringMatrixBFAntennae:2;
+	uint32_t reserved:7;
+#endif
+} qdf_packed tSirMacTxBFCapabilityInfo;
+
+/* Antenna Selection Capability Info */
+typedef struct sSirMacASCapabilityInfo {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint8_t reserved2:1;
+	uint8_t txSoundingPPDUs:1;      /* Static via CFG */
+	uint8_t rxAS:1;         /* Static via CFG */
+	uint8_t antennaIndicesFeedback:1;       /* Static via CFG */
+	uint8_t explicitCSIFeedback:1;  /* Static via CFG */
+	uint8_t antennaIndicesFeedbackTx:1;     /* Static via CFG */
+	uint8_t explicitCSIFeedbackTx:1;        /* Static via CFG */
+	uint8_t antennaSelection:1;     /* Static via CFG */
+#else
+	uint8_t antennaSelection:1;
+	uint8_t explicitCSIFeedbackTx:1;
+	uint8_t antennaIndicesFeedbackTx:1;
+	uint8_t explicitCSIFeedback:1;
+	uint8_t antennaIndicesFeedback:1;
+	uint8_t rxAS:1;
+	uint8_t txSoundingPPDUs:1;
+	uint8_t reserved2:1;
+#endif
+} qdf_packed tSirMacASCapabilityInfo;
+
+typedef struct sSirMacProbeReqFrame {
+	tSirMacSSidIE ssIdIE;
+	tSirMacRateSetIE rateSetIE;
+	tSirMacRateSetIE extendedRateSetIE;
+} qdf_packed tSirMacProbeReqFrame, *tpSirMacProbeReqFrame;
+
+typedef struct sSirMacProbeRspFrame {
+	tSirMacTimeStamp ts;
+	tSirMacBeaconInterval beaconInterval;
+	tSirMacCapabilityInfo capabilityInfo;
+	tSirMacSSidIE ssIdIE;
+	tSirMacRateSetIE rateSetIE;
+	tSirMacRateSetIE extendedRateSetIE;
+	tSirMacNonErpPresentIE nonErpPresent;
+	tSirMacDsParamSetIE dsParamsIE;
+	tSirMacCfParamSetIE cfParamsIE;
+} qdf_packed tSirMacProbeRspFrame, *tpSirMacProbeRspFrame;
+
+typedef struct sSirMacAuthFrameBody {
+	uint16_t authAlgoNumber;
+	uint16_t authTransactionSeqNumber;
+	uint16_t authStatusCode;
+	uint8_t type;           /* = SIR_MAC_CHALLENGE_TEXT_EID */
+	uint8_t length;         /* = SIR_MAC_AUTH_CHALLENGE_LENGTH */
+	uint8_t challengeText[SIR_MAC_AUTH_CHALLENGE_LENGTH];
+#ifdef WLAN_FEATURE_FILS_SK
+	tSirMacRsnInfo rsn_ie;
+	uint8_t assoc_delay_info;
+	uint8_t session[SIR_FILS_SESSION_LENGTH];
+	uint8_t wrapped_data_len;
+	uint8_t wrapped_data[SIR_FILS_WRAPPED_DATA_MAX_SIZE];
+	uint8_t nonce[SIR_FILS_NONCE_LENGTH];
+#endif
+} qdf_packed tSirMacAuthFrameBody, *tpSirMacAuthFrameBody;
+
+typedef struct sSirMacAuthenticationFrame {
+	tSirMacAuthFrameBody authFrameBody;
+} qdf_packed tSirMacAuthFrame, *tpSirMacAuthFrame;
+
+typedef struct sSirMacAssocReqFrame {
+	tSirMacCapabilityInfo capabilityInfo;
+	uint16_t listenInterval;
+	tSirMacSSidIE ssIdIE;
+	tSirMacRateSetIE rateSetIE;
+	tSirMacRateSetIE extendedRateSetIE;
+} qdf_packed tSirMacAssocReqFrame, *tpSirMacAssocReqFrame;
+
+typedef struct sSirMacAssocRspFrame {
+	tSirMacCapabilityInfo capabilityInfo;
+	uint16_t statusCode;
+	uint16_t aid;
+	tSirMacRateSetIE supportedRates;
+	tSirMacRateSetIE extendedRateSetIE;
+} qdf_packed tSirMacAssocRspFrame, *tpSirMacAssocRspFrame;
+
+typedef struct sSirMacDisassocFrame {
+	uint16_t reasonCode;
+} qdf_packed tSirMacDisassocFrame, *tpSirMacDisassocFrame;
+
+typedef struct sDSirMacDeauthFrame {
+	uint16_t reasonCode;
+} qdf_packed tSirMacDeauthFrame, *tpSirMacDeauthFrame;
+
+/* / Common header for all action frames */
+typedef struct sSirMacActionFrameHdr {
+	uint8_t category;
+	uint8_t actionID;
+} qdf_packed tSirMacActionFrameHdr, *tpSirMacActionFrameHdr;
+
+typedef struct sSirMacVendorSpecificFrameHdr {
+	uint8_t category;
+	uint8_t Oui[4];
+} qdf_packed tSirMacVendorSpecificFrameHdr,
+*tpSirMacVendorSpecificFrameHdr;
+
+typedef struct sSirMacVendorSpecificPublicActionFrameHdr {
+	uint8_t category;
+	uint8_t actionID;
+	uint8_t Oui[4];
+	uint8_t OuiSubType;
+	uint8_t dialogToken;
+} qdf_packed tSirMacVendorSpecificPublicActionFrameHdr,
+*tpSirMacVendorSpecificPublicActionFrameHdr;
+
+typedef struct sSirMacP2PActionFrameHdr {
+	uint8_t category;
+	uint8_t Oui[4];
+	uint8_t OuiSubType;
+	uint8_t dialogToken;
+} qdf_packed tSirMacP2PActionFrameHdr, *tpSirMacP2PActionFrameHdr;
+
+typedef struct sSirMacMeasActionFrameHdr {
+	uint8_t category;
+	uint8_t actionID;
+	uint8_t dialogToken;
+} tSirMacMeasActionFrameHdr, *tpSirMacMeasActionFrameHdr;
+
+#ifdef ANI_SUPPORT_11H
+typedef struct sSirMacTpcReqActionFrame {
+	tSirMacMeasActionFrameHdr actionHeader;
+	uint8_t type;
+	uint8_t length;
+} tSirMacTpcReqActionFrame, *tpSirMacTpcReqActionFrame;
+typedef struct sSirMacMeasReqActionFrame {
+	tSirMacMeasActionFrameHdr actionHeader;
+	tSirMacMeasReqIE measReqIE;
+} tSirMacMeasReqActionFrame, *tpSirMacMeasReqActionFrame;
+#endif
+
+typedef struct sSirMacNeighborReportReq {
+	uint8_t dialogToken;
+	uint8_t ssid_present;
+	tSirMacSSid ssid;
+} tSirMacNeighborReportReq, *tpSirMacNeighborReportReq;
+
+typedef struct sSirMacLinkReport {
+	uint8_t dialogToken;
+	uint8_t txPower;
+	uint8_t rxAntenna;
+	uint8_t txAntenna;
+	uint8_t rcpi;
+	uint8_t rsni;
+} tSirMacLinkReport, *tpSirMacLinkReport;
+
+#define BEACON_REPORT_MAX_IES 224       /* Refer IEEE 802.11k-2008, Table 7-31d */
+typedef struct sSirMacBeaconReport {
+	uint8_t regClass;
+	uint8_t channel;
+	uint8_t measStartTime[8];
+	uint8_t measDuration;
+	uint8_t phyType;
+	uint8_t bcnProbeRsp;
+	uint8_t rsni;
+	uint8_t rcpi;
+	tSirMacAddr bssid;
+	uint8_t antennaId;
+	uint32_t parentTSF;
+	uint8_t numIes;
+	uint8_t Ies[BEACON_REPORT_MAX_IES];
+
+} tSirMacBeaconReport, *tpSirMacBeaconReport;
+
+#define RADIO_REPORTS_MAX_IN_A_FRAME 4
+typedef struct sSirMacRadioMeasureReport {
+	uint8_t token;
+	uint8_t refused;
+	uint8_t incapable;
+	uint8_t type;
+	union {
+		tSirMacBeaconReport beaconReport;
+	} report;
+
+} tSirMacRadioMeasureReport, *tpSirMacRadioMeasureReport;
+
+#ifdef WLAN_FEATURE_11AX
+struct he_cap_network_endian {
+	uint32_t htc_he:1;
+	uint32_t twt_request:1;
+	uint32_t twt_responder:1;
+	uint32_t fragmentation:2;
+	uint32_t max_num_frag_msdu_amsdu_exp:3;
+	uint32_t min_frag_size:2;
+	uint32_t trigger_frm_mac_pad:2;
+	uint32_t multi_tid_aggr_rx_supp:3;
+	uint32_t he_link_adaptation:2;
+	uint32_t all_ack:1;
+	uint32_t trigd_rsp_sched:1;
+	uint32_t a_bsr:1;
+	uint32_t broadcast_twt:1;
+	uint32_t ba_32bit_bitmap:1;
+	uint32_t mu_cascade:1;
+	uint32_t ack_enabled_multitid:1;
+	uint32_t reserved:1;
+	uint32_t omi_a_ctrl:1;
+	uint32_t ofdma_ra:1;
+	uint32_t max_ampdu_len_exp_ext:2;
+	uint32_t amsdu_frag:1;
+	uint32_t flex_twt_sched:1;
+	uint32_t rx_ctrl_frame:1;
+
+	uint16_t bsrp_ampdu_aggr:1;
+	uint16_t qtp:1;
+	uint16_t a_bqr:1;
+	uint16_t spatial_reuse_param_rspder:1;
+	uint16_t ndp_feedback_supp:1;
+	uint16_t ops_supp:1;
+	uint16_t amsdu_in_ampdu:1;
+	uint16_t multi_tid_aggr_tx_supp:3;
+	uint16_t he_sub_ch_sel_tx_supp:1;
+	uint16_t ul_2x996_tone_ru_supp:1;
+	uint16_t om_ctrl_ul_mu_data_dis_rx:1;
+	uint16_t reserved1:3;
+
+	uint32_t reserved2:1;
+	uint32_t chan_width:7;
+	uint32_t rx_pream_puncturing:4;
+	uint32_t device_class:1;
+	uint32_t ldpc_coding:1;
+	uint32_t he_1x_ltf_800_gi_ppdu:1;
+	uint32_t midamble_tx_rx_max_nsts:2;
+	uint32_t he_4x_ltf_3200_gi_ndp:1;
+	uint32_t tx_stbc_lt_80mhz:1;
+	uint32_t rx_stbc_lt_80mhz:1;
+	uint32_t doppler:2;
+	uint32_t ul_mu:2;
+	uint32_t dcm_enc_tx:3;
+	uint32_t dcm_enc_rx:3;
+	uint32_t ul_he_mu:1;
+	uint32_t su_beamformer:1;
+
+	uint32_t su_beamformee:1;
+	uint32_t mu_beamformer:1;
+	uint32_t bfee_sts_lt_80:3;
+	uint32_t bfee_sts_gt_80:3;
+	uint32_t num_sounding_lt_80:3;
+	uint32_t num_sounding_gt_80:3;
+	uint32_t su_feedback_tone16:1;
+	uint32_t mu_feedback_tone16:1;
+	uint32_t codebook_su:1;
+	uint32_t codebook_mu:1;
+	uint32_t beamforming_feedback:3;
+	uint32_t he_er_su_ppdu:1;
+	uint32_t dl_mu_mimo_part_bw:1;
+	uint32_t ppet_present:1;
+	uint32_t srp:1;
+	uint32_t power_boost:1;
+	uint32_t he_ltf_800_gi_4x:1;
+	uint32_t max_nc:3;
+	uint32_t tx_stbc_gt_80mhz:1;
+	uint32_t rx_stbc_gt_80mhz:1;
+
+	uint16_t er_he_ltf_800_gi_4x:1;
+	uint16_t he_ppdu_20_in_40Mhz_2G:1;
+	uint16_t he_ppdu_20_in_160_80p80Mhz:1;
+	uint16_t he_ppdu_80_in_160_80p80Mhz:1;
+	uint16_t er_1x_he_ltf_gi:1;
+	uint16_t midamble_tx_rx_1x_he_ltf:1;
+	uint16_t dcm_max_bw:2;
+	uint16_t longer_than_16_he_sigb_ofdm_sym:1;
+	uint16_t non_trig_cqi_feedback:1;
+	uint16_t tx_1024_qam_lt_242_tone_ru:1;
+	uint16_t rx_1024_qam_lt_242_tone_ru:1;
+	uint16_t rx_full_bw_su_he_mu_compress_sigb:1;
+	uint16_t rx_full_bw_su_he_mu_non_cmpr_sigb:1;
+	uint16_t reserved3:2;
+
+	uint8_t  reserved4;
+
+	uint16_t rx_he_mcs_map_lt_80;
+	uint16_t tx_he_mcs_map_lt_80;
+	uint16_t rx_he_mcs_map_160;
+	uint16_t tx_he_mcs_map_160;
+	uint16_t rx_he_mcs_map_80_80;
+	uint16_t tx_he_mcs_map_80_80;
+} qdf_packed;
+
+struct he_ops_network_endian {
+	uint32_t            bss_color:6;
+	uint32_t           default_pe:3;
+	uint32_t         twt_required:1;
+	uint32_t        txop_rts_threshold:10;
+	uint32_t      partial_bss_col:1;
+	uint32_t     vht_oper_present:1;
+	uint32_t            reserved1:6;
+	uint32_t            co_located_bss:1;
+	uint32_t     bss_col_disabled:1;
+	uint32_t            reserved2:1;
+	uint8_t             basic_mcs_nss[2];
+	union {
+		struct {
+			uint8_t chan_width;
+			uint8_t center_freq_seg0;
+			uint8_t center_freq_seg1;
+		} info; /* vht_oper_present = 1 */
+	} vht_oper;
+	union {
+		struct {
+			uint8_t data;
+		} info; /* co_located_bss = 1 */
+	} maxbssid_ind;
+} qdf_packed;
+
+/* HE Capabilities Info */
+struct he_capability_info {
+#ifndef ANI_LITTLE_BIT_ENDIAN
+	uint32_t rx_ctrl_frame:1;
+	uint32_t flex_twt_sched:1;
+	uint32_t amsdu_frag:1;
+	uint32_t max_ampdu_len_exp_ext:2;
+	uint32_t ofdma_ra:1;
+	uint32_t omi_a_ctrl:1;
+	uint32_t reserved:1;
+	uint32_t ack_enabled_multitid:1;
+	uint32_t mu_cascade:1;
+	uint32_t ba_32bit_bitmap:1;
+	uint32_t broadcast_twt:1;
+	uint32_t a_bsr:1;
+	uint32_t trigd_rsp_sched:1;
+	uint32_t all_ack:1;
+	uint32_t he_link_adaptation:2;
+	uint32_t multi_tid_aggr_rx_supp:3;
+	uint32_t trigger_frm_mac_pad:2;
+	uint32_t min_frag_size:2;
+	uint32_t max_num_frag_msdu_amsdu_exp:3;
+	uint32_t fragmentation:2;
+	uint32_t twt_responder:1;
+	uint32_t twt_request:1;
+	uint32_t htc_he:1;
+
+	uint16_t reserved1:3;
+	uint16_t om_ctrl_ul_mu_data_dis_rx:1;
+	uint16_t ul_2x996_tone_ru_supp:1;
+	uint16_t he_sub_ch_sel_tx_supp:1;
+	uint16_t multi_tid_aggr_tx_supp:3;
+	uint16_t amsdu_in_ampdu:1;
+	uint16_t ops_supp:1;
+	uint16_t ndp_feedback_supp:1;
+	uint16_t spatial_reuse_param_rspder:1;
+	uint16_t a_bqr:1;
+	uint16_t qtp:1;
+	uint16_t bsrp_ampdu_aggr:1;
+
+	uint32_t su_beamformer:1;
+	uint32_t ul_he_mu:1;
+	uint32_t dcm_enc_rx:3;
+	uint32_t dcm_enc_tx:3;
+	uint32_t ul_mu:2;
+	uint32_t doppler:2;
+	uint32_t rx_stbc_lt_80mhz:1;
+	uint32_t tx_stbc_lt_80mhz:1;
+	uint32_t he_4x_ltf_3200_gi_ndp:1;
+	uint32_t midamble_tx_rx_max_nsts:2;
+	uint32_t he_1x_ltf_800_gi_ppdu:1;
+	uint32_t ldpc_coding:1;
+	uint32_t device_class:1;
+	uint32_t rx_pream_puncturing:4;
+	uint32_t chan_width:7;
+	uint32_t reserved2:1;
+
+	uint32_t rx_stbc_gt_80mhz:1;
+	uint32_t tx_stbc_gt_80mhz:1;
+	uint32_t max_nc:3;
+	uint32_t he_ltf_800_gi_4x:1;
+	uint32_t power_boost:1;
+	uint32_t srp:1;
+	uint32_t ppet_present:1;
+	uint32_t dl_mu_mimo_part_bw:1;
+	uint32_t he_er_su_ppdu:1;
+	uint32_t beamforming_feedback:3;
+	uint32_t codebook_mu:1;
+	uint32_t codebook_su:1;
+	uint32_t mu_feedback_tone16:1;
+	uint32_t su_feedback_tone16:1;
+	uint32_t num_sounding_gt_80:3;
+	uint32_t num_sounding_lt_80:3;
+	uint32_t bfee_sts_gt_80:3;
+	uint32_t bfee_sts_lt_80:3;
+	uint32_t mu_beamformer:1;
+	uint32_t su_beamformee:1;
+
+	uint16_t reserved3:2;
+	uint16_t rx_full_bw_su_he_mu_non_cmpr_sigb:1;
+	uint16_t rx_full_bw_su_he_mu_compress_sigb:1;
+	uint16_t rx_1024_qam_lt_242_tone_ru:1;
+	uint16_t tx_1024_qam_lt_242_tone_ru:1;
+	uint16_t non_trig_cqi_feedback:1;
+	uint16_t longer_than_16_he_sigb_ofdm_sym:1;
+	uint16_t dcm_max_bw:2;
+	uint16_t midamble_tx_rx_1x_he_ltf:1;
+	uint16_t er_1x_he_ltf_gi:1;
+	uint16_t he_ppdu_80_in_160_80p80Mhz:1;
+	uint16_t he_ppdu_20_in_160_80p80Mhz:1;
+	uint16_t he_ppdu_20_in_40Mhz_2G:1;
+	uint16_t er_he_ltf_800_gi_4x:1;
+
+	uint8_t reserved4;
+
+	uint16_t tx_he_mcs_map_80_80;
+	uint16_t rx_he_mcs_map_80_80;
+	uint16_t tx_he_mcs_map_160;
+	uint16_t rx_he_mcs_map_160;
+	uint16_t tx_he_mcs_map_lt_80;
+	uint16_t rx_he_mcs_map_lt_80;
+#else
+	uint32_t htc_he:1;
+	uint32_t twt_request:1;
+	uint32_t twt_responder:1;
+	uint32_t fragmentation:2;
+	uint32_t max_num_frag_msdu_amsdu_exp:3;
+	uint32_t min_frag_size:2;
+	uint32_t trigger_frm_mac_pad:2;
+	uint32_t multi_tid_aggr_rx_supp:3;
+	uint32_t he_link_adaptation:2;
+	uint32_t all_ack:1;
+	uint32_t trigd_rsp_sched:1;
+	uint32_t a_bsr:1;
+	uint32_t broadcast_twt:1;
+	uint32_t ba_32bit_bitmap:1;
+	uint32_t mu_cascade:1;
+	uint32_t ack_enabled_multitid:1;
+	uint32_t reserved:1;
+	uint32_t omi_a_ctrl:1;
+	uint32_t ofdma_ra:1;
+	uint32_t max_ampdu_len_exp_ext:2;
+	uint32_t amsdu_frag:1;
+	uint32_t flex_twt_sched:1;
+	uint32_t rx_ctrl_frame:1;
+
+	uint16_t bsrp_ampdu_aggr:1;
+	uint16_t qtp:1;
+	uint16_t a_bqr:1;
+	uint16_t spatial_reuse_param_rspder:1;
+	uint16_t ndp_feedback_supp:1;
+	uint16_t ops_supp:1;
+	uint16_t amsdu_in_ampdu:1;
+	uint16_t multi_tid_aggr_tx_supp:3;
+	uint16_t he_sub_ch_sel_tx_supp:1;
+	uint16_t ul_2x996_tone_ru_supp:1;
+	uint16_t om_ctrl_ul_mu_data_dis_rx:1;
+	uint16_t reserved1:3;
+
+	uint32_t reserved2:1;
+	uint32_t chan_width:7;
+	uint32_t rx_pream_puncturing:4;
+	uint32_t device_class:1;
+	uint32_t ldpc_coding:1;
+	uint32_t he_1x_ltf_800_gi_ppdu:1;
+	uint32_t midamble_tx_rx_max_nsts:2;
+	uint32_t he_4x_ltf_3200_gi_ndp:1;
+	uint32_t tx_stbc_lt_80mhz:1;
+	uint32_t rx_stbc_lt_80mhz:1;
+	uint32_t doppler:2;
+	uint32_t ul_mu:2;
+	uint32_t dcm_enc_tx:3;
+	uint32_t dcm_enc_rx:3;
+	uint32_t ul_he_mu:1;
+	uint32_t su_beamformer:1;
+
+	uint32_t su_beamformee:1;
+	uint32_t mu_beamformer:1;
+	uint32_t bfee_sts_lt_80:3;
+	uint32_t bfee_sts_gt_80:3;
+	uint32_t num_sounding_lt_80:3;
+	uint32_t num_sounding_gt_80:3;
+	uint32_t su_feedback_tone16:1;
+	uint32_t mu_feedback_tone16:1;
+	uint32_t codebook_su:1;
+	uint32_t codebook_mu:1;
+	uint32_t beamforming_feedback:3;
+	uint32_t he_er_su_ppdu:1;
+	uint32_t dl_mu_mimo_part_bw:1;
+	uint32_t ppet_present:1;
+	uint32_t srp:1;
+	uint32_t power_boost:1;
+	uint32_t he_ltf_800_gi_4x:1;
+	uint32_t max_nc:3;
+	uint32_t tx_stbc_gt_80mhz:1;
+	uint32_t rx_stbc_gt_80mhz:1;
+
+	uint16_t er_he_ltf_800_gi_4x:1;
+	uint16_t he_ppdu_20_in_40Mhz_2G:1;
+	uint16_t he_ppdu_20_in_160_80p80Mhz:1;
+	uint16_t he_ppdu_80_in_160_80p80Mhz:1;
+	uint16_t er_1x_he_ltf_gi:1;
+	uint16_t midamble_tx_rx_1x_he_ltf:1;
+	uint16_t dcm_max_bw:2;
+	uint16_t longer_than_16_he_sigb_ofdm_sym:1;
+	uint16_t non_trig_cqi_feedback:1;
+	uint16_t tx_1024_qam_lt_242_tone_ru:1;
+	uint16_t rx_1024_qam_lt_242_tone_ru:1;
+	uint16_t rx_full_bw_su_he_mu_compress_sigb:1;
+	uint16_t rx_full_bw_su_he_mu_non_cmpr_sigb:1;
+	uint16_t reserved3:2;
+
+	uint8_t  reserved4;
+
+	uint16_t rx_he_mcs_map_lt_80;
+	uint16_t tx_he_mcs_map_lt_80;
+	uint16_t rx_he_mcs_map_160;
+	uint16_t tx_he_mcs_map_160;
+	uint16_t rx_he_mcs_map_80_80;
+	uint16_t tx_he_mcs_map_80_80;
+#endif
+} qdf_packed;
+#endif
+
+/*
+ * frame parser does not include optional 160 and 80+80 mcs set for MIN IE len
+ */
+#define SIR_MAC_HE_CAP_MIN_LEN       (DOT11F_IE_HE_CAP_MIN_LEN + 8)
+
+/* QOS action frame definitions */
+
+/* max number of possible tclas elements in any frame */
+#define SIR_MAC_TCLASIE_MAXNUM  2
+
+/* 11b rate encoding in MAC format */
+
+#define SIR_MAC_RATE_1   0x02
+#define SIR_MAC_RATE_2   0x04
+#define SIR_MAC_RATE_5_5 0x0B
+#define SIR_MAC_RATE_11  0x16
+
+/* 11a/g rate encoding in MAC format */
+
+#define SIR_MAC_RATE_6   0x0C
+#define SIR_MAC_RATE_9   0x12
+#define SIR_MAC_RATE_12  0x18
+#define SIR_MAC_RATE_18  0x24
+#define SIR_MAC_RATE_24  0x30
+#define SIR_MAC_RATE_36  0x48
+#define SIR_MAC_RATE_48  0x60
+#define SIR_MAC_RATE_54  0x6C
+
+/* ANI legacy supported rates */
+#define SIR_MAC_RATE_72  0x01
+#define SIR_MAC_RATE_96  0x03
+#define SIR_MAC_RATE_108 0x05
+
+/* ANI enhanced rates */
+#define SIR_MAC_RATE_42  1000
+#define SIR_MAC_RATE_84  1001
+#define SIR_MAC_RATE_126 1002
+#define SIR_MAC_RATE_144 1003
+#define SIR_MAC_RATE_168 1004
+#define SIR_MAC_RATE_192 1005
+#define SIR_MAC_RATE_216 1006
+#define SIR_MAC_RATE_240 1007
+
+#define SIR_MAC_RATE_1_BITMAP    (1<<0)
+#define SIR_MAC_RATE_2_BITMAP    (1<<1)
+#define SIR_MAC_RATE_5_5_BITMAP  (1<<2)
+#define SIR_MAC_RATE_11_BITMAP   (1<<3)
+#define SIR_MAC_RATE_6_BITMAP    (1<<4)
+#define SIR_MAC_RATE_9_BITMAP    (1<<5)
+#define SIR_MAC_RATE_12_BITMAP   (1<<6)
+#define SIR_MAC_RATE_18_BITMAP   (1<<7)
+#define SIR_MAC_RATE_24_BITMAP   (1<<8)
+#define SIR_MAC_RATE_36_BITMAP   (1<<9)
+#define SIR_MAC_RATE_48_BITMAP   (1<<10)
+#define SIR_MAC_RATE_54_BITMAP   (1<<11)
+
+#define sirIsArate(x) ((((uint8_t)x) == SIR_MAC_RATE_6)  || \
+		       (((uint8_t)x) == SIR_MAC_RATE_9)  || \
+		       (((uint8_t)x) == SIR_MAC_RATE_12) || \
+		       (((uint8_t)x) == SIR_MAC_RATE_18) || \
+		       (((uint8_t)x) == SIR_MAC_RATE_24) || \
+		       (((uint8_t)x) == SIR_MAC_RATE_36) || \
+		       (((uint8_t)x) == SIR_MAC_RATE_48) || \
+		       (((uint8_t)x) == SIR_MAC_RATE_54))
+
+#define sirIsBrate(x) ((((uint8_t)x) == SIR_MAC_RATE_1)   || \
+		       (((uint8_t)x) == SIR_MAC_RATE_2)   || \
+		       (((uint8_t)x) == SIR_MAC_RATE_5_5) || \
+		       (((uint8_t)x) == SIR_MAC_RATE_11))
+
+#define sirIsGrate(x) ((((uint8_t)x) == SIR_MAC_RATE_1)   || \
+		       (((uint8_t)x) == SIR_MAC_RATE_2)   || \
+		       (((uint8_t)x) == SIR_MAC_RATE_5_5) || \
+		       (((uint8_t)x) == SIR_MAC_RATE_11)  || \
+		       (((uint8_t)x) == SIR_MAC_RATE_6)   || \
+		       (((uint8_t)x) == SIR_MAC_RATE_9)   || \
+		       (((uint8_t)x) == SIR_MAC_RATE_12)  || \
+		       (((uint8_t)x) == SIR_MAC_RATE_18)  || \
+		       (((uint8_t)x) == SIR_MAC_RATE_24)  || \
+		       (((uint8_t)x) == SIR_MAC_RATE_36)  || \
+		       (((uint8_t)x) == SIR_MAC_RATE_48)  || \
+		       (((uint8_t)x) == SIR_MAC_RATE_54))
+
+#define SIR_MAC_MIN_IE_LEN 2    /* Minimum IE length for IE validation */
+
+#define SIR_MAC_TI_TYPE_REASSOC_DEADLINE        1
+#define SIR_MAC_TI_TYPE_KEY_LIFETIME            2
+#define SIR_MAC_TI_TYPE_ASSOC_COMEBACK          3
+
+#define SIR_MAC_VHT_CAP_MAX_MPDU_LEN              0
+#define SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET         2
+#define SIR_MAC_VHT_CAP_LDPC_CODING_CAP           4
+#define SIR_MAC_VHT_CAP_SHORTGI_80MHZ             5
+#define SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ      6
+#define SIR_MAC_VHT_CAP_TXSTBC                    7
+#define SIR_MAC_VHT_CAP_RXSTBC                    8
+#define SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP         11
+#define SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP         12
+#define SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP     13
+#define SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM          16
+#define SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP       19
+#define SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP       20
+#define SIR_MAC_VHT_CAP_TXOPPS                    21
+#define SIR_MAC_VHT_CAP_HTC_CAP                   22
+#define SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO         23
+#define SIR_MAC_VHT_CAP_LINK_ADAPT_CAP            26
+#define SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN        28
+#define SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN        29
+#define SIR_MAC_VHT_CAP_RESERVED2                 30
+
+#define SIR_MAC_HT_CAP_ADVCODING_S                 0
+#define SIR_MAC_HT_CAP_CHWIDTH40_S                 1
+#define SIR_MAC_HT_CAP_SMPOWERSAVE_DYNAMIC_S       2
+#define SIR_MAC_HT_CAP_SM_RESERVED_S               3
+#define SIR_MAC_HT_CAP_GREENFIELD_S                4
+#define SIR_MAC_HT_CAP_SHORTGI20MHZ_S              5
+#define SIR_MAC_HT_CAP_SHORTGI40MHZ_S              6
+#define SIR_MAC_HT_CAP_TXSTBC_S                    7
+#define SIR_MAC_HT_CAP_RXSTBC_S                    8
+#define SIR_MAC_HT_CAP_DELAYEDBLKACK_S            10
+#define SIR_MAC_HT_CAP_MAXAMSDUSIZE_S             11
+#define SIR_MAC_HT_CAP_DSSSCCK40_S                12
+#define SIR_MAC_HT_CAP_PSMP_S                     13
+#define SIR_MAC_HT_CAP_INTOLERANT40_S             14
+#define SIR_MAC_HT_CAP_LSIGTXOPPROT_S             15
+
+#define SIR_MAC_TXSTBC                             1
+#define SIR_MAC_RXSTBC                             1
+
+#endif /* __MAC_PROT_DEFS_H */
diff --git a/core/mac/inc/sir_types.h b/core/mac/inc/sir_types.h
new file mode 100644
index 0000000..1e3b73d
--- /dev/null
+++ b/core/mac/inc/sir_types.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011-2016,2018 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.
+ */
+
+/*
+ *
+ * This file sir_types.h contains the common types
+ *
+ * Author:    V. K. Kandarpa
+ * Date:      04/12/2002
+ */
+
+#ifndef __SIR_TYPES_H
+#define __SIR_TYPES_H
+
+#include <qdf_status.h>
+#include <qdf_types.h>
+
+/**
+ * typedef mac_handle_t - MAC Handle
+ *
+ * Handle to the MAC.  The MAC handle is returned to the HDD from the
+ * UMAC on Open.  The MAC handle is an input to all UMAC function
+ * calls and represents an opaque handle to the UMAC instance that is
+ * tied to the HDD instance
+ *
+ * The UMAC must be able to derive it's internal instance structure
+ * pointer through this handle.
+ */
+/*
+ * NOTE WELL: struct opaque_mac_handle is not defined anywhere. This
+ * reference is used to help ensure that a mac_handle_t is never used
+ * where a different handle type is expected
+ */
+struct opaque_mac_handle;
+typedef struct opaque_mac_handle *mac_handle_t;
+
+/* retain legacy name until all instances have been replaced */
+typedef mac_handle_t tHalHandle;
+
+/**
+ * typedef hdd_handle_t - HDD Handle
+ *
+ * Handle to the HDD.  The HDD handle is given to the UMAC from the
+ * HDD on Open.  The HDD handle is an input to all HDD/PAL function
+ * calls and represents an opaque handle to the HDD instance that is
+ * tied to the UMAC instance
+ *
+ * The HDD must be able to derive it's internal instance structure
+ * pointer through this handle.
+ */
+/*
+ * NOTE WELL: struct opaque_hdd_handle is not defined anywhere. This
+ * reference is used to help ensure that a hdd_handle_t is never used
+ * where a different handle type is expected
+ */
+struct opaque_hdd_handle;
+typedef struct opaque_hdd_handle *hdd_handle_t;
+
+#define HAL_NUM_ASSOC_STA           32
+#define HAL_NUM_STA                 41
+
+#define STACFG_MAX_TC               8
+
+#endif /* __SIR_TYPES_H */
diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h
new file mode 100644
index 0000000..2381a3b
--- /dev/null
+++ b/core/mac/inc/wni_api.h
@@ -0,0 +1,540 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file wni_api.h contains message definitions exported by
+ * Sirius software modules.
+ * NOTE: See projects/sirius/include/sir_api.h for structure
+ * definitions of the host/FW messages.
+ *
+ * Author:        Chandra Modumudi
+ * Date:          04/11/2002
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#ifndef __WNI_API_H
+#define __WNI_API_H
+
+#define SIR_SME_MODULE_ID 0x16
+
+/* / Start of Sirius/Host message types */
+#define WNI_HOST_MSG_START             0x1500
+
+enum eWniMsgTypes {
+	/* / CFG message types */
+	eWNI_CFG_MSG_TYPES_BEGIN = WNI_HOST_MSG_START,
+	eWNI_CFG_MSG_TYPES_END = eWNI_CFG_MSG_TYPES_BEGIN + 0xFF,
+
+	/* / SME message types */
+	eWNI_SME_MSG_TYPES_BEGIN = eWNI_CFG_MSG_TYPES_END,
+	eWNI_SME_SYS_READY_IND,
+	eWNI_SME_SCAN_REQ,
+	eWNI_SME_SCAN_ABORT_IND,
+	eWNI_SME_SCAN_RSP,
+	eWNI_SME_JOIN_REQ,
+	eWNI_SME_JOIN_RSP,
+	eWNI_SME_SETCONTEXT_REQ,
+	eWNI_SME_SETCONTEXT_RSP,
+	eWNI_SME_REASSOC_REQ,
+	eWNI_SME_REASSOC_RSP,
+	eWNI_SME_DISASSOC_REQ,
+	eWNI_SME_DISASSOC_RSP,
+	eWNI_SME_DISASSOC_IND,
+	eWNI_SME_DISASSOC_CNF,
+	eWNI_SME_DEAUTH_REQ,
+	eWNI_SME_DEAUTH_RSP,
+	eWNI_SME_DEAUTH_IND,
+	eWNI_SME_DISCONNECT_DONE_IND,
+	eWNI_SME_WM_STATUS_CHANGE_NTF,
+	eWNI_SME_IBSS_NEW_PEER_IND,
+	eWNI_SME_IBSS_PEER_DEPARTED_IND,
+	eWNI_SME_START_BSS_REQ,
+	eWNI_SME_START_BSS_RSP,
+	eWNI_SME_ASSOC_IND,
+	eWNI_SME_ASSOC_CNF,
+	eWNI_SME_SWITCH_CHL_IND,
+	eWNI_SME_STOP_BSS_REQ,
+	eWNI_SME_STOP_BSS_RSP,
+	eWNI_SME_DEAUTH_CNF,
+	eWNI_SME_MIC_FAILURE_IND,
+	eWNI_SME_ADDTS_REQ,
+	eWNI_SME_ADDTS_RSP,
+	eWNI_SME_DELTS_REQ,
+	eWNI_SME_DELTS_RSP,
+	eWNI_SME_DELTS_IND,
+	eWNI_SME_GET_STATISTICS_REQ,
+	eWNI_SME_GET_STATISTICS_RSP,
+	eWNI_SME_GET_RSSI_REQ,
+	eWNI_SME_GET_ASSOC_STAS_REQ,
+	eWNI_SME_WPS_PBC_PROBE_REQ_IND,
+	eWNI_SME_UPPER_LAYER_ASSOC_CNF,
+	eWNI_SME_SESSION_UPDATE_PARAM,
+	eWNI_SME_CHNG_MCC_BEACON_INTERVAL,
+	eWNI_SME_CLEAR_DFS_CHANNEL_LIST,
+	eWNI_SME_GET_SNR_REQ,
+
+	eWNI_SME_RRM_MSG_TYPE_BEGIN,
+
+	eWNI_SME_NEIGHBOR_REPORT_REQ_IND,
+	eWNI_SME_NEIGHBOR_REPORT_IND,
+	eWNI_SME_BEACON_REPORT_REQ_IND,
+	eWNI_SME_BEACON_REPORT_RESP_XMIT_IND,
+
+	eWNI_SME_ADD_STA_SELF_RSP,
+	eWNI_SME_DEL_STA_SELF_RSP,
+
+	eWNI_SME_FT_PRE_AUTH_REQ,
+	eWNI_SME_FT_PRE_AUTH_RSP,
+	eWNI_SME_FT_UPDATE_KEY,
+	eWNI_SME_FT_AGGR_QOS_REQ,
+	eWNI_SME_FT_AGGR_QOS_RSP,
+
+#if defined FEATURE_WLAN_ESE
+	eWNI_SME_ESE_ADJACENT_AP_REPORT,
+#endif
+
+	eWNI_SME_REGISTER_MGMT_FRAME_REQ,
+	eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE,
+	eWNI_SME_MAX_ASSOC_EXCEEDED,
+#ifdef FEATURE_WLAN_TDLS
+	eWNI_SME_TDLS_SEND_MGMT_REQ,
+	eWNI_SME_TDLS_SEND_MGMT_RSP,
+	eWNI_SME_TDLS_ADD_STA_REQ,
+	eWNI_SME_TDLS_ADD_STA_RSP,
+	eWNI_SME_TDLS_DEL_STA_REQ,
+	eWNI_SME_TDLS_DEL_STA_RSP,
+	eWNI_SME_TDLS_DEL_STA_IND,
+	eWNI_SME_TDLS_DEL_ALL_PEER_IND,
+	eWNI_SME_MGMT_FRM_TX_COMPLETION_IND,
+	eWNI_SME_TDLS_LINK_ESTABLISH_REQ,
+	eWNI_SME_TDLS_LINK_ESTABLISH_RSP,
+	eWNI_SME_TDLS_SHOULD_DISCOVER,
+	eWNI_SME_TDLS_SHOULD_TEARDOWN,
+	eWNI_SME_TDLS_PEER_DISCONNECTED,
+	eWNI_SME_TDLS_CONNECTION_TRACKER_NOTIFICATION,
+#endif
+	/* NOTE: If you are planning to add more mesages, please make sure that */
+	/* SIR_LIM_ITC_MSG_TYPES_BEGIN is moved appropriately. It is set as */
+	/* SIR_LIM_MSG_TYPES_BEGIN+0xB0 = 12B0 (which means max of 176 messages and */
+	/* eWNI_SME_TDLS_DEL_STA_RSP = 175. */
+	/* Should fix above issue to enable TDLS_INTERNAL */
+	eWNI_SME_RESET_AP_CAPS_CHANGED,
+#ifdef WLAN_FEATURE_11W
+	eWNI_SME_UNPROT_MGMT_FRM_IND,
+#endif
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+	eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP,
+#endif /* WLAN_FEATURE_GTK_OFFLOAD */
+	eWNI_SME_CANDIDATE_FOUND_IND,   /*ROAM candidate indication from FW */
+	eWNI_SME_HANDOFF_REQ,   /*upper layer requested handoff to driver in STA mode */
+	eWNI_SME_ROAM_SCAN_OFFLOAD_RSP, /*Fwd the LFR scan offload rsp from FW to SME */
+	eWNI_SME_IBSS_PEER_INFO_RSP,
+	eWNI_SME_GET_TSM_STATS_REQ,
+	eWNI_SME_GET_TSM_STATS_RSP,
+	eWNI_SME_TSM_IE_IND,
+
+	eWNI_SME_READY_TO_SUSPEND_IND,
+	/* DFS EVENTS */
+	eWNI_SME_DFS_RADAR_FOUND,       /* RADAR found indication from DFS */
+	eWNI_SME_CHANNEL_CHANGE_REQ,    /* Channel Change Request from SAP */
+	eWNI_SME_CHANNEL_CHANGE_RSP,    /* Channel Change Response from WMA */
+	eWNI_SME_START_BEACON_REQ,      /* Start Beacon Transmission. */
+	eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ,     /* Transmit CSA IE in beacons */
+	eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND,     /* To indicate completion of CSA IE */
+	/* update in beacons/probe rsp */
+	eWNI_SME_STATS_EXT_EVENT,
+	eWNI_SME_GET_PEER_INFO_IND,
+	eWNI_SME_GET_PEER_INFO_EXT_IND,
+	eWNI_SME_CSA_OFFLOAD_EVENT,
+	eWNI_SME_UPDATE_ADDITIONAL_IES, /* indicates Additional IE from hdd to PE */
+	eWNI_SME_MODIFY_ADDITIONAL_IES, /* To indicate IE modify from hdd to PE */
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+	eWNI_SME_AUTO_SHUTDOWN_IND,
+#endif
+#ifdef QCA_HT_2040_COEX
+	eWNI_SME_SET_HT_2040_MODE,
+#endif
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	eWNI_SME_HO_FAIL_IND,   /* Hand Off Failure Ind from WMA to SME */
+#endif
+#ifdef WLAN_FEATURE_NAN
+	eWNI_SME_NAN_EVENT,
+#endif
+	eWNI_SME_LINK_STATUS_IND,
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+	eWNI_SME_READY_TO_EXTWOW_IND,
+#endif
+	eWNI_SME_MSG_GET_TEMPERATURE_IND,
+	eWNI_SME_SNR_IND,
+#ifdef FEATURE_WLAN_EXTSCAN
+	eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND,
+	eWNI_SME_EPNO_NETWORK_FOUND_IND,
+#endif
+	eWNI_SME_SET_HW_MODE_REQ,
+	eWNI_SME_SET_HW_MODE_RESP,
+	eWNI_SME_HW_MODE_TRANS_IND,
+	eWNI_SME_NSS_UPDATE_REQ,
+	eWNI_SME_NSS_UPDATE_RSP,
+	eWNI_SME_OCB_SET_CONFIG_RSP,
+	eWNI_SME_OCB_GET_TSF_TIMER_RSP,
+	eWNI_SME_DCC_GET_STATS_RSP,
+	eWNI_SME_DCC_UPDATE_NDL_RSP,
+	eWNI_SME_DCC_STATS_EVENT,
+	eWNI_SME_SET_DUAL_MAC_CFG_REQ,
+	eWNI_SME_SET_DUAL_MAC_CFG_RESP,
+	eWNI_SME_SET_THERMAL_LEVEL_IND,
+	eWNI_SME_SET_IE_REQ,
+	eWNI_SME_EXT_CHANGE_CHANNEL,
+	eWNI_SME_EXT_CHANGE_CHANNEL_IND,
+	eWNI_SME_REGISTER_MGMT_FRAME_CB,
+	eWNI_SME_HT40_OBSS_SCAN_IND, /* START and UPDATE OBSS SCAN Indication*/
+	eWNI_SME_SET_ANTENNA_MODE_REQ,
+	eWNI_SME_SET_ANTENNA_MODE_RESP,
+	eWNI_SME_TSF_EVENT,
+	eWNI_SME_MON_INIT_SESSION,
+	eWNI_SME_PDEV_SET_HT_VHT_IE,
+	eWNI_SME_SET_VDEV_IES_PER_BAND,
+	eWNI_SME_SEND_DISASSOC_FRAME,
+	eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE,
+	eWNI_SME_DEFAULT_SCAN_IE,
+	eWNI_SME_ROAM_INVOKE,
+	eWNI_SME_ROAM_SCAN_OFFLOAD_REQ,
+	eWNI_SME_LOST_LINK_INFO_IND,
+	eWNI_SME_DEL_ALL_TDLS_PEERS,
+	eWNI_SME_RSO_CMD_STATUS_IND,
+	eWMI_SME_LL_STATS_IND,
+	eWNI_SME_DFS_CAC_COMPLETE,
+	eWNI_SME_UPDATE_CONFIG,
+	eWNI_SME_BT_ACTIVITY_INFO_IND,
+	eWNI_SME_SET_HE_BSS_COLOR,
+	eWNI_SME_TRIGGER_SAE,
+	eWNI_SME_SEND_MGMT_FRAME_TX,
+	eWNI_SME_SEND_SAE_MSG,
+	eWNI_SME_SET_ADDBA_ACCEPT,
+	eWNI_SME_UPDATE_EDCA_PROFILE,
+	WNI_SME_UPDATE_MU_EDCA_PARAMS,
+	eWNI_SME_CSA_RESTART_REQ,
+	eWNI_SME_CSA_RESTART_RSP,
+	eWNI_SME_MSG_TYPES_END
+};
+
+typedef enum {
+	eWNI_TDLS_TEARDOWN_REASON_TX,
+	eWNI_TDLS_TEARDOWN_REASON_RSSI,
+	eWNI_TDLS_TEARDOWN_REASON_SCAN,
+	eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE,
+	eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT,
+	eWNI_TDLS_TEARDOWN_REASON_BAD_PTR,
+	eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE,
+} eWniTdlsTeardownReason;
+
+/**
+ * enum ewni_tdls_connection_tracker_notification - connection tracker events
+ * @eWNI_TDLS_PEER_ENTER_BUF_STA: TDLS peer enters buff sta
+ * @eWNI_TDLS_PEER_EXIT_BUF_STA: TDLS peer exit buff sta
+ * @eWNI_TDLS_ENTER_BT_BUSY_MODE: Enter BT busy event
+ * @eWNI_TDLS_EXIT_BT_BUSY_MODE: Exit BT busy event
+ * @eWMI_TDLS_SCAN_STARTED_EVENT: offload scan start event
+ * @eWMI_TDLS_SCAN_COMPLETED_EVENT: offload scan end event
+ */
+enum ewni_tdls_connection_tracker_notification {
+	eWNI_TDLS_PEER_ENTER_BUF_STA,
+	eWNI_TDLS_PEER_EXIT_BUF_STA,
+	eWNI_TDLS_ENTER_BT_BUSY_MODE,
+	eWNI_TDLS_EXIT_BT_BUSY_MODE,
+	eWMI_TDLS_SCAN_STARTED_EVENT,
+	eWMI_TDLS_SCAN_COMPLETED_EVENT,
+};
+
+#define WNI_CFG_MSG_TYPES_BEGIN        0x1200
+
+/*---------------------------------------------------------------------*/
+/* CFG Module Definitions                                              */
+/*---------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------*/
+/* CFG message definitions                                             */
+/*---------------------------------------------------------------------*/
+#define WNI_CFG_MSG_HDR_MASK    0xffff0000
+#define WNI_CFG_MSG_LEN_MASK    0x0000ffff
+#define WNI_CFG_MB_HDR_LEN      4
+#define WNI_CFG_MAX_PARAM_NUM   32
+
+/*---------------------------------------------------------------------*/
+/* CFG to HDD message types                                            */
+/*---------------------------------------------------------------------*/
+#define WNI_CFG_PARAM_UPDATE_IND       (WNI_CFG_MSG_TYPES_BEGIN | 0x00)
+#define WNI_CFG_DNLD_REQ               (WNI_CFG_MSG_TYPES_BEGIN | 0x01)
+#define WNI_CFG_DNLD_CNF               (WNI_CFG_MSG_TYPES_BEGIN | 0x02)
+#define WNI_CFG_GET_RSP                (WNI_CFG_MSG_TYPES_BEGIN | 0x03)
+#define WNI_CFG_SET_CNF                (WNI_CFG_MSG_TYPES_BEGIN | 0x04)
+#define WNI_CFG_GET_ATTRIB_RSP         (WNI_CFG_MSG_TYPES_BEGIN | 0x05)
+#define WNI_CFG_ADD_GRP_ADDR_CNF       (WNI_CFG_MSG_TYPES_BEGIN | 0x06)
+#define WNI_CFG_DEL_GRP_ADDR_CNF       (WNI_CFG_MSG_TYPES_BEGIN | 0x07)
+
+#define ANI_CFG_GET_RADIO_STAT_RSP     (WNI_CFG_MSG_TYPES_BEGIN | 0x08)
+#define ANI_CFG_GET_PER_STA_STAT_RSP   (WNI_CFG_MSG_TYPES_BEGIN | 0x09)
+#define ANI_CFG_GET_AGG_STA_STAT_RSP   (WNI_CFG_MSG_TYPES_BEGIN | 0x0a)
+#define ANI_CFG_CLEAR_STAT_RSP         (WNI_CFG_MSG_TYPES_BEGIN | 0x0b)
+
+/*---------------------------------------------------------------------*/
+/* CFG to HDD message parameter indices                                 */
+
+/*   The followings are word indices starting from the message body    */
+
+/*   WNI_CFG_xxxx_xxxx_xxxx:         index of parameter                */
+/*   WNI_CFG_xxxx_xxxx_NUM:          number of parameters in message   */
+
+/*   WNI_CFG_xxxx_xxxx_LEN:          byte length of message including  */
+/*                                   MB header                         */
+/*                                                                     */
+/*   WNI_CFG_xxxx_xxxx_PARTIAL_LEN:  byte length of message including  */
+/*                                   parameters and MB header but      */
+/*                                   excluding variable data length    */
+/*---------------------------------------------------------------------*/
+
+/* Parameter update indication */
+#define WNI_CFG_PARAM_UPDATE_IND_PID   0
+
+#define WNI_CFG_PARAM_UPDATE_IND_NUM   1
+#define WNI_CFG_PARAM_UPDATE_IND_LEN   (WNI_CFG_MB_HDR_LEN + \
+					(WNI_CFG_PARAM_UPDATE_IND_NUM << 2))
+
+/* Configuration download request */
+#define WNI_CFG_DNLD_REQ_NUM           0
+#define WNI_CFG_DNLD_REQ_LEN           WNI_CFG_MB_HDR_LEN
+
+/* Configuration download confirm */
+#define WNI_CFG_DNLD_CNF_RES           0
+
+#define WNI_CFG_DNLD_CNF_NUM           1
+#define WNI_CFG_DNLD_CNF_LEN           (WNI_CFG_MB_HDR_LEN + \
+					(WNI_CFG_DNLD_CNF_NUM << 2))
+/* Get response */
+#define WNI_CFG_GET_RSP_RES            0
+#define WNI_CFG_GET_RSP_PID            1
+#define WNI_CFG_GET_RSP_PLEN           2
+
+#define WNI_CFG_GET_RSP_NUM            3
+#define WNI_CFG_GET_RSP_PARTIAL_LEN    (WNI_CFG_MB_HDR_LEN + \
+					(WNI_CFG_GET_RSP_NUM << 2))
+/* Set confirm */
+#define WNI_CFG_SET_CNF_RES            0
+#define WNI_CFG_SET_CNF_PID            1
+
+#define WNI_CFG_SET_CNF_NUM            2
+#define WNI_CFG_SET_CNF_LEN            (WNI_CFG_MB_HDR_LEN + \
+					(WNI_CFG_SET_CNF_NUM << 2))
+/* Get attribute response */
+#define WNI_CFG_GET_ATTRIB_RSP_RES     0
+#define WNI_CFG_GET_ATTRIB_RSP_PID     1
+#define WNI_CFG_GET_ATTRIB_RSP_TYPE    2
+#define WNI_CFG_GET_ATTRIB_RSP_PLEN    3
+#define WNI_CFG_GET_ATTRIB_RSP_RW      4
+
+#define WNI_CFG_GET_ATTRIB_RSP_NUM     5
+#define WNI_CFG_GET_ATTRIB_RSP_LEN     (WNI_CFG_MB_HDR_LEN + \
+					(WNI_CFG_GET_ATTRIB_RSP_NUM << 2))
+
+/* Add group address confirm */
+#define WNI_CFG_ADD_GRP_ADDR_CNF_RES   0
+
+#define WNI_CFG_ADD_GRP_ADDR_CNF_NUM   1
+#define WNI_CFG_ADD_GRP_ADDR_CNF_LEN   (WNI_CFG_MB_HDR_LEN + \
+					(WNI_CFG_ADD_GRP_ADDR_CNF_NUM << 2))
+
+/* Delete group address confirm */
+#define WNI_CFG_DEL_GRP_ADDR_CNF_RES   0
+
+#define WNI_CFG_DEL_GRP_ADDR_CNF_NUM   1
+#define WNI_CFG_DEL_GRP_ADDR_CNF_LEN   (WNI_CFG_MB_HDR_LEN + \
+					(WNI_CFG_DEL_GRP_ADDR_CNF_NUM << 2))
+
+#define IS_CFG_MSG(msg) ((msg & 0xff00) == WNI_CFG_MSG_TYPES_BEGIN)
+
+/* Clear stats types. */
+#define ANI_CLEAR_ALL_STATS          0
+#define ANI_CLEAR_RX_STATS           1
+#define ANI_CLEAR_TX_STATS           2
+#define ANI_CLEAR_PER_STA_STATS      3
+#define ANI_CLEAR_AGGR_PER_STA_STATS 4
+#define ANI_CLEAR_STAT_TYPES_END     5
+
+/*---------------------------------------------------------------------*/
+/* HDD to CFG message types                                            */
+/*---------------------------------------------------------------------*/
+#define WNI_CFG_DNLD_RSP               (WNI_CFG_MSG_TYPES_BEGIN | 0x80)
+#define WNI_CFG_GET_REQ                (WNI_CFG_MSG_TYPES_BEGIN | 0x81)
+
+/* Shall be removed after stats integration */
+
+/*---------------------------------------------------------------------*/
+/* HDD to CFG message parameter indices                                 */
+/*                                                                     */
+/*   The followings are word indices starting from the message body    */
+/*                                                                     */
+/*   WNI_CFG_xxxx_xxxx_xxxx:         index of parameter                */
+/*                                                                     */
+/*   WNI_CFG_xxxx_xxxx_NUM:          number of parameters in message   */
+/*                                                                     */
+/*   WNI_CFG_xxxx_xxxx_LEN:          byte length of message including  */
+/*                                   MB header                         */
+/*                                                                     */
+/*   WNI_CFG_xxxx_xxxx_PARTIAL_LEN:  byte length of message including  */
+/*                                   parameters and MB header but      */
+/*                                   excluding variable data length    */
+/*---------------------------------------------------------------------*/
+
+/* Download response */
+#define WNI_CFG_DNLD_RSP_BIN_LEN       0
+
+#define WNI_CFG_DNLD_RSP_NUM           1
+#define WNI_CFG_DNLD_RSP_PARTIAL_LEN   (WNI_CFG_MB_HDR_LEN + \
+					(WNI_CFG_DNLD_RSP_NUM << 2))
+
+/* Set parameter request */
+#define WNI_CFG_SET_REQ_PID            0
+#define WNI_CFG_SET_REQ_PLEN           1
+
+/*---------------------------------------------------------------------*/
+/* CFG return values                                                   */
+/*---------------------------------------------------------------------*/
+#define WNI_CFG_SUCCESS             1
+#define WNI_CFG_NOT_READY           2
+#define WNI_CFG_INVALID_PID         3
+#define WNI_CFG_INVALID_LEN         4
+#define WNI_CFG_RO_PARAM            5
+#define WNI_CFG_WO_PARAM            6
+#define WNI_CFG_INVALID_STAID       7
+#define WNI_CFG_OTHER_ERROR         8
+#define WNI_CFG_NEED_RESTART        9
+#define WNI_CFG_NEED_RELOAD        10
+
+/*---------------------------------------------------------------------*/
+/* CFG definitions                                                     */
+/*---------------------------------------------------------------------*/
+
+/* Shall be removed after integration of stats. */
+/* Get statistic response */
+#define WNI_CFG_GET_STAT_RSP_RES       0
+#define WNI_CFG_GET_STAT_RSP_PARAMID   1
+#define WNI_CFG_GET_STAT_RSP_VALUE     2
+
+#define WNI_CFG_GET_STAT_RSP_NUM       3
+#define WNI_CFG_GET_STAT_RSP_LEN       (WNI_CFG_MB_HDR_LEN + \
+					(WNI_CFG_GET_STAT_RSP_NUM << 2))
+/* Get per station statistic response */
+#define WNI_CFG_GET_PER_STA_STAT_RSP_RES                        0
+#define WNI_CFG_GET_PER_STA_STAT_RSP_STAID                      1
+#define WNI_CFG_GET_PER_STA_STAT_RSP_FIRST_PARAM                2
+
+/* Per STA statistic structure */
+typedef struct sAniCfgPerStaStatStruct {
+	unsigned long sentAesBlksUcastHi;
+	unsigned long sentAesBlksUcastLo;
+
+	unsigned long recvAesBlksUcastHi;
+	unsigned long recvAesBlksUcastLo;
+
+	unsigned long aesFormatErrorUcastCnts;
+
+	unsigned long aesReplaysUcast;
+
+	unsigned long aesDecryptErrUcast;
+
+	unsigned long singleRetryPkts;
+
+	unsigned long failedTxPkts;
+
+	unsigned long ackTimeouts;
+
+	unsigned long multiRetryPkts;
+
+	unsigned long fragTxCntsHi;
+	unsigned long fragTxCntsLo;
+
+	unsigned long transmittedPktsHi;
+	unsigned long transmittedPktsLo;
+
+	unsigned long phyStatHi;
+	unsigned long phyStatLo;
+} tCfgPerStaStatStruct, *tpAniCfgPerStaStatStruct;
+
+#define WNI_CFG_GET_PER_STA_STAT_RSP_NUM                       23
+#define WNI_CFG_GET_PER_STA_STAT_RSP_LEN    (WNI_CFG_MB_HDR_LEN + \
+					     (WNI_CFG_GET_PER_STA_STAT_RSP_NUM << 2))
+
+/* Shall be removed after integrating stats. */
+#define WNI_CFG_GET_STAT_RSP           (WNI_CFG_MSG_TYPES_BEGIN | 0x08)
+#define WNI_CFG_GET_PER_STA_STAT_RSP   (WNI_CFG_MSG_TYPES_BEGIN | 0x09)
+#define WNI_CFG_GET_AGG_STA_STAT_RSP   (WNI_CFG_MSG_TYPES_BEGIN | 0x0a)
+#define WNI_CFG_GET_TX_RATE_CTR_RSP    (WNI_CFG_MSG_TYPES_BEGIN | 0x0b)
+
+#define WNI_CFG_GET_AGG_STA_STAT_RSP_NUM    21
+#define WNI_CFG_GET_AGG_STA_STAT_RSP_LEN    (WNI_CFG_MB_HDR_LEN + \
+					     (WNI_CFG_GET_AGG_STA_STAT_RSP_NUM << 2))
+#define WNI_CFG_GET_AGG_STA_STAT_RSP_RES 0
+
+/* Get TX rate based stats */
+#define WNI_CFG_GET_TX_RATE_CTR_RSP_RES                        0
+
+typedef struct sAniCfgTxRateCtrs {
+/* add the rate counters here */
+	unsigned long TxFrames_1Mbps;
+	unsigned long TxFrames_2Mbps;
+	unsigned long TxFrames_5_5Mbps;
+	unsigned long TxFrames_6Mbps;
+	unsigned long TxFrames_9Mbps;
+	unsigned long TxFrames_11Mbps;
+	unsigned long TxFrames_12Mbps;
+	unsigned long TxFrames_18Mbps;
+	unsigned long TxFrames_24Mbps;
+	unsigned long TxFrames_36Mbps;
+	unsigned long TxFrames_48Mbps;
+	unsigned long TxFrames_54Mbps;
+	unsigned long TxFrames_72Mbps;
+	unsigned long TxFrames_96Mbps;
+	unsigned long TxFrames_108Mbps;
+
+} tAniCfgTxRateCtrs, *tpAniCfgTxRateCtrs;
+
+#define WNI_CFG_GET_STAT_REQ           (WNI_CFG_MSG_TYPES_BEGIN | 0x86)
+#define WNI_CFG_GET_PER_STA_STAT_REQ   (WNI_CFG_MSG_TYPES_BEGIN | 0x87)
+#define WNI_CFG_GET_AGG_STA_STAT_REQ   (WNI_CFG_MSG_TYPES_BEGIN | 0x88)
+#define WNI_CFG_GET_TX_RATE_CTR_REQ    (WNI_CFG_MSG_TYPES_BEGIN | 0x89)
+
+/* Get statistic request */
+#define WNI_CFG_GET_STAT_REQ_PARAMID   0
+
+#define WNI_CFG_GET_STAT_REQ_NUM       1
+#define WNI_CFG_GET_STAT_REQ_LEN       (WNI_CFG_MB_HDR_LEN + \
+					(WNI_CFG_GET_STAT_REQ_NUM << 2))
+
+/* Get per station statistic request */
+#define WNI_CFG_GET_PER_STA_STAT_REQ_STAID 0
+
+#define WNI_CFG_GET_PER_STA_STAT_REQ_NUM   1
+#define WNI_CFG_GET_PER_STA_STAT_REQ_LEN   (WNI_CFG_MB_HDR_LEN + \
+					    (WNI_CFG_GET_PER_STA_STAT_REQ_NUM << 2))
+
+#define DYNAMIC_CFG_TYPE_SELECTED_REGISTRAR   (0)
+#define DYNAMIC_CFG_TYPE_WPS_STATE            (1)
+
+#endif /* __WNI_API_H */
diff --git a/core/mac/inc/wni_cfg.h b/core/mac/inc/wni_cfg.h
new file mode 100644
index 0000000..8be6dd0
--- /dev/null
+++ b/core/mac/inc/wni_cfg.h
@@ -0,0 +1,955 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#ifndef __WNICFG_H
+#define __WNICFG_H
+
+/*
+ * Configuration Parameter ID for STA
+ */
+
+enum {
+	WNI_CFG_STA_ID,
+	WNI_CFG_SSID,
+	WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
+	WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
+	WNI_CFG_DOT11_MODE,
+	WNI_CFG_VALID_CHANNEL_LIST,
+	WNI_CFG_APSD_ENABLED,
+	WNI_CFG_11D_ENABLED,
+	WNI_CFG_MAX_TX_POWER_2_4,
+	WNI_CFG_MAX_TX_POWER_5,
+	WNI_CFG_CURRENT_TX_POWER_LEVEL,
+	WNI_CFG_COUNTRY_CODE,
+	WNI_CFG_11H_ENABLED,
+	WNI_CFG_LOCAL_POWER_CONSTRAINT,
+	WNI_CFG_SCAN_CONTROL_LIST,
+	WNI_CFG_TX_BF_CAP,
+	WNI_CFG_AS_CAP,
+	WNI_CFG_SCAN_IN_POWERSAVE,
+	WNI_CFG_IBSS_AUTO_BSSID,
+	WNI_CFG_WPS_UUID,
+	WNI_CFG_TELE_BCN_WAKEUP_EN,
+	WNI_CFG_TELE_BCN_MAX_LI,
+	WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED,
+	WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP,
+	WNI_CFG_IBSS_ATIM_WIN_SIZE,
+	WNI_CFG_HE_CONTROL,
+	WNI_CFG_HE_TWT_REQUESTOR,
+	WNI_CFG_HE_TWT_RESPONDER,
+	WNI_CFG_HE_FRAGMENTATION,
+	WNI_CFG_HE_MAX_FRAG_MSDU,
+	WNI_CFG_HE_MIN_FRAG_SIZE,
+	WNI_CFG_HE_TRIG_PAD,
+	WNI_CFG_HE_MTID_AGGR_RX,
+	WNI_CFG_HE_LINK_ADAPTATION,
+	WNI_CFG_HE_ALL_ACK,
+	WNI_CFG_HE_TRIGD_RSP_SCHEDULING,
+	WNI_CFG_HE_BUFFER_STATUS_RPT,
+	WNI_CFG_HE_BCAST_TWT,
+	WNI_CFG_HE_BA_32BIT,
+	WNI_CFG_HE_MU_CASCADING,
+	WNI_CFG_HE_MULTI_TID,
+	WNI_CFG_HE_DL_MU_BA,
+	WNI_CFG_HE_OMI,
+	WNI_CFG_HE_OFDMA_RA,
+	WNI_CFG_HE_MAX_AMPDU_LEN,
+	WNI_CFG_HE_AMSDU_FRAG,
+	WNI_CFG_HE_FLEX_TWT_SCHED,
+	WNI_CFG_HE_RX_CTRL,
+	WNI_CFG_HE_BSRP_AMPDU_AGGR,
+	WNI_CFG_HE_QTP,
+	WNI_CFG_HE_A_BQR,
+	WNI_CFG_HE_SR_RESPONDER,
+	WNI_CFG_HE_NDP_FEEDBACK_SUPP,
+	WNI_CFG_HE_OPS_SUPP,
+	WNI_CFG_HE_AMSDU_IN_AMPDU,
+	WNI_CFG_HE_MTID_AGGR_TX,
+	WNI_CFG_HE_SUB_CH_SEL_TX,
+	WNI_CFG_HE_UL_2X996_RU,
+	WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX,
+	WNI_CFG_HE_CHAN_WIDTH,
+	WNI_CFG_HE_RX_PREAM_PUNC,
+	WNI_CFG_HE_CLASS_OF_DEVICE,
+	WNI_CFG_HE_LDPC,
+	WNI_CFG_HE_LTF_PPDU,
+	WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS,
+	WNI_CFG_HE_LTF_NDP,
+	WNI_CFG_HE_TX_STBC_LT80,
+	WNI_CFG_HE_RX_STBC_LT80,
+	WNI_CFG_HE_DOPPLER,
+	WNI_CFG_HE_UL_MUMIMO,
+	WNI_CFG_HE_DCM_TX,
+	WNI_CFG_HE_DCM_RX,
+	WNI_CFG_HE_MU_PPDU,
+	WNI_CFG_HE_SU_BEAMFORMER,
+	WNI_CFG_HE_SU_BEAMFORMEE,
+	WNI_CFG_HE_MU_BEAMFORMER,
+	WNI_CFG_HE_BFEE_STS_LT80,
+	WNI_CFG_HE_BFEE_STS_GT80,
+	WNI_CFG_HE_NUM_SOUND_LT80,
+	WNI_CFG_HE_NUM_SOUND_GT80,
+	WNI_CFG_HE_SU_FEED_TONE16,
+	WNI_CFG_HE_MU_FEED_TONE16,
+	WNI_CFG_HE_CODEBOOK_SU,
+	WNI_CFG_HE_CODEBOOK_MU,
+	WNI_CFG_HE_BFRM_FEED,
+	WNI_CFG_HE_ER_SU_PPDU,
+	WNI_CFG_HE_DL_PART_BW,
+	WNI_CFG_HE_PPET_PRESENT,
+	WNI_CFG_HE_SRP,
+	WNI_CFG_HE_POWER_BOOST,
+	WNI_CFG_HE_4x_LTF_GI,
+	WNI_CFG_HE_MAX_NC,
+	WNI_CFG_HE_TX_STBC_GT80,
+	WNI_CFG_HE_RX_STBC_GT80,
+	WNI_CFG_HE_ER_4x_LTF_GI,
+	WNI_CFG_HE_PPDU_20_IN_40MHZ_2G,
+	WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ,
+	WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ,
+	WNI_CFG_HE_ER_1X_HE_LTF_GI,
+	WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF,
+	WNI_CFG_HE_DCM_MAX_BW,
+	WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM,
+	WNI_CFG_HE_NON_TRIG_CQI_FEEDBACK,
+	WNI_CFG_HE_TX_1024_QAM_LT_242_RU,
+	WNI_CFG_HE_RX_1024_QAM_LT_242_RU,
+	WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB,
+	WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB,
+	WNI_CFG_HE_RX_MCS_MAP_LT_80,
+	WNI_CFG_HE_TX_MCS_MAP_LT_80,
+	WNI_CFG_HE_RX_MCS_MAP_160,
+	WNI_CFG_HE_TX_MCS_MAP_160,
+	WNI_CFG_HE_RX_MCS_MAP_80_80,
+	WNI_CFG_HE_TX_MCS_MAP_80_80,
+	WNI_CFG_HE_PPET_2G,
+	WNI_CFG_HE_PPET_5G,
+	WNI_CFG_HE_OPS_BSS_COLOR,
+	WNI_CFG_HE_OPS_DEFAULT_PE,
+	WNI_CFG_HE_OPS_TWT_REQUIRED,
+	WNI_CFG_HE_OPS_RTS_THRESHOLD,
+	WNI_CFG_HE_OPS_PARTIAL_BSS_COL,
+	WNI_CFG_HE_OPS_VHT_OPER_PRESENT,
+	WNI_CFG_HE_OPS_MBSSID_AP,
+	WNI_CFG_HE_OPS_TX_BSSID_IND,
+	WNI_CFG_HE_OPS_BSS_COL_DISABLED,
+	WNI_CFG_HE_OPS_BASIC_MCS_NSS,
+	WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT,
+	WNI_CFG_HE_STA_OBSSPD,
+	WNI_CFG_OBSS_DETECTION_OFFLOAD,
+	WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD,
+	WNI_CFG_TWT_REQUESTOR,
+	WNI_CFG_TWT_RESPONDER,
+	WNI_CFG_BCAST_TWT,
+	/* Any new items to be added should be above this strictly */
+	CFG_PARAM_MAX_NUM
+};
+/*
+ * String parameter lengths
+ */
+
+#define WNI_CFG_STA_ID_LEN    6
+#define WNI_CFG_SSID_LEN    32
+#define WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET_LEN    4
+#define WNI_CFG_VALID_CHANNEL_LIST_LEN    100
+#define WNI_CFG_MAX_TX_POWER_2_4_LEN    128
+#define WNI_CFG_MAX_TX_POWER_5_LEN    128
+#define WNI_CFG_COUNTRY_CODE_LEN    3
+#define WNI_CFG_SCAN_CONTROL_LIST_LEN    128
+#define WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN    255
+#define WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN    255
+#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN    255
+#define WNI_CFG_WPS_UUID_LEN    16
+#define WNI_CFG_HE_PPET_LEN     25
+
+/*
+ * Integer parameter min/max/default values
+ */
+#define WNI_CFG_EXCLUDE_UNENCRYPTED_STAMIN    0
+#define WNI_CFG_EXCLUDE_UNENCRYPTED_STAMAX    1
+#define WNI_CFG_EXCLUDE_UNENCRYPTED_STADEF    0
+
+#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMIN    0
+#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMAX    65535
+#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STADEF    40
+
+#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMIN    0
+#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMAX    65535
+#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STADEF    60
+
+#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMIN    0
+#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMAX    65535
+#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STADEF    110
+
+#define WNI_CFG_PS_ENABLE_BCN_FILTER_STAMIN    0
+#define WNI_CFG_PS_ENABLE_BCN_FILTER_STAMAX    1
+#define WNI_CFG_PS_ENABLE_BCN_FILTER_STADEF    1
+
+#define WNI_CFG_PS_ENABLE_HEART_BEAT_STAMIN    0
+#define WNI_CFG_PS_ENABLE_HEART_BEAT_STAMAX    1
+#define WNI_CFG_PS_ENABLE_HEART_BEAT_STADEF    1
+
+#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMIN    0
+#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMAX    1
+#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STADEF    0
+
+#define WNI_CFG_RF_SETTLING_TIME_CLK_STAMIN    0
+#define WNI_CFG_RF_SETTLING_TIME_CLK_STAMAX    60000
+#define WNI_CFG_RF_SETTLING_TIME_CLK_STADEF    1500
+
+#define WNI_CFG_PHY_MODE_STAMIN    0
+#define WNI_CFG_PHY_MODE_STAMAX    3
+#define WNI_CFG_PHY_MODE_STADEF    0
+
+#define WNI_CFG_PHY_MODE_11A    0
+#define WNI_CFG_PHY_MODE_11B    1
+#define WNI_CFG_PHY_MODE_11G    2
+#define WNI_CFG_PHY_MODE_NONE    3
+
+#define WNI_CFG_DOT11_MODE_STAMIN    0
+#define WNI_CFG_DOT11_MODE_STAMAX    10
+#define WNI_CFG_DOT11_MODE_STADEF    0
+
+#define WNI_CFG_DOT11_MODE_ALL    0
+#define WNI_CFG_DOT11_MODE_11A    1
+#define WNI_CFG_DOT11_MODE_11B    2
+#define WNI_CFG_DOT11_MODE_11G    3
+#define WNI_CFG_DOT11_MODE_11N    4
+#define WNI_CFG_DOT11_MODE_11G_ONLY    5
+#define WNI_CFG_DOT11_MODE_11N_ONLY    6
+#define WNI_CFG_DOT11_MODE_11AC    7
+#define WNI_CFG_DOT11_MODE_11AC_ONLY    8
+#define WNI_CFG_DOT11_MODE_11AX    9
+#define WNI_CFG_DOT11_MODE_11AX_ONLY    10
+
+#define WNI_CFG_CURRENT_CHANNEL_STAMIN    0
+#define WNI_CFG_CURRENT_CHANNEL_STAMAX    173
+#define WNI_CFG_CURRENT_CHANNEL_STADEF    1
+
+#define WNI_CFG_RATE_ADAPTATION_TYPE_FIXED    0
+#define WNI_CFG_RATE_ADAPTATION_TYPE_AUTO    1
+#define WNI_CFG_RATE_ADAPTATION_TYPE_SNR_BASED    2
+
+#define WNI_CFG_FIXED_RATE_STAMIN    0
+#define WNI_CFG_FIXED_RATE_STAMAX    44
+#define WNI_CFG_FIXED_RATE_STADEF    0
+
+#define WNI_CFG_FIXED_RATE_AUTO    0
+#define WNI_CFG_FIXED_RATE_1MBPS    1
+#define WNI_CFG_FIXED_RATE_2MBPS    2
+#define WNI_CFG_FIXED_RATE_5_5MBPS    3
+#define WNI_CFG_FIXED_RATE_11MBPS    4
+#define WNI_CFG_FIXED_RATE_6MBPS    5
+#define WNI_CFG_FIXED_RATE_9MBPS    6
+#define WNI_CFG_FIXED_RATE_12MBPS    7
+#define WNI_CFG_FIXED_RATE_18MBPS    8
+#define WNI_CFG_FIXED_RATE_24MBPS    9
+#define WNI_CFG_FIXED_RATE_36MBPS    10
+#define WNI_CFG_FIXED_RATE_48MBPS    11
+#define WNI_CFG_FIXED_RATE_54MBPS    12
+#define WNI_CFG_FIXED_RATE_6_5MBPS_MCS0_20MHZ_SIMO    13
+#define WNI_CFG_FIXED_RATE_13MBPS_MCS1_20MHZ_SIMO    14
+#define WNI_CFG_FIXED_RATE_19_5MBPS_MCS2_20MHZ_SIMO    15
+#define WNI_CFG_FIXED_RATE_26MBPS_MCS3_20MHZ_SIMO    16
+#define WNI_CFG_FIXED_RATE_39MBPS_MCS4_20MHZ_SIMO    17
+#define WNI_CFG_FIXED_RATE_52MBPS_MCS5_20MHZ_SIMO    18
+#define WNI_CFG_FIXED_RATE_58_5MBPS_MCS6_20MHZ_SIMO    19
+#define WNI_CFG_FIXED_RATE_65MBPS_MCS7_20MHZ_SIMO    20
+#define WNI_CFG_FIXED_RATE_7_2MBPS_MCS0_20MHZ_SIMO_SGI    21
+#define WNI_CFG_FIXED_RATE_14_4MBPS_MCS1_20MHZ_SIMO_SGI    22
+#define WNI_CFG_FIXED_RATE_21_7MBPS_MCS2_20MHZ_SIMO_SGI    23
+#define WNI_CFG_FIXED_RATE_28_9MBPS_MCS3_20MHZ_SIMO_SGI    24
+#define WNI_CFG_FIXED_RATE_43_3MBPS_MCS4_20MHZ_SIMO_SGI    25
+#define WNI_CFG_FIXED_RATE_57_8MBPS_MCS5_20MHZ_SIMO_SGI    26
+#define WNI_CFG_FIXED_RATE_65MBPS_MCS6_20MHZ_SIMO_SGI    27
+#define WNI_CFG_FIXED_RATE_72_2MBPS_MCS7_20MHZ_SIMO_SGI    28
+#define WNI_CFG_FIXED_RATE_0_25MBPS_SLR_20MHZ_SIMO    29
+#define WNI_CFG_FIXED_RATE_0_5MBPS_SLR_20MHZ_SIMO    30
+#define WNI_CFG_FIXED_RATE_68_25MBPS_QC_PROP_20MHZ_SIMO    31
+#define WNI_CFG_FIXED_RATE_54MBPS_MCS3_40MHZ_SIMO    32
+#define WNI_CFG_FIXED_RATE_81MBPS_MCS4_40MHZ_SIMO    33
+#define WNI_CFG_FIXED_RATE_108MBPS_MCS5_40MHZ_SIMO    34
+#define WNI_CFG_FIXED_RATE_121_5MBPS_MCS6_40MHZ_SIMO    35
+#define WNI_CFG_FIXED_RATE_135MBPS_MCS7_40MHZ_SIMO    36
+#define WNI_CFG_FIXED_RATE_15MBPS_MCS0_40MHZ_SIMO_SGI    37
+#define WNI_CFG_FIXED_RATE_30MBPS_MCS1_40MHZ_SIMO_SGI    38
+#define WNI_CFG_FIXED_RATE_45MBPS_MCS2_40MHZ_SIMO_SGI    39
+#define WNI_CFG_FIXED_RATE_60MBPS_MCS3_40MHZ_SIMO_SGI    40
+#define WNI_CFG_FIXED_RATE_90MBPS_MCS4_40MHZ_SIMO_SGI    41
+#define WNI_CFG_FIXED_RATE_120MBPS_MCS5_40MHZ_SIMO_SGI    42
+#define WNI_CFG_FIXED_RATE_135MBPS_MCS6_40MHZ_SIMO_SGI    43
+#define WNI_CFG_FIXED_RATE_150MBPS_MCS7_40MHZ_SIMO_SGI    44
+
+#define WNI_CFG_RETRYRATE_POLICY_MIN_SUPPORTED    0
+#define WNI_CFG_RETRYRATE_POLICY_PRIMARY    1
+#define WNI_CFG_RETRYRATE_POLICY_RESERVED    2
+#define WNI_CFG_RETRYRATE_POLICY_CLOSEST    3
+#define WNI_CFG_RETRYRATE_POLICY_AUTOSELECT    4
+#define WNI_CFG_RETRYRATE_POLICY_MAX    5
+
+#define WNI_CFG_APSD_ENABLED_STAMIN    0
+#define WNI_CFG_APSD_ENABLED_STAMAX    1
+#define WNI_CFG_APSD_ENABLED_STADEF    0
+
+#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMIN    0
+#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMAX    1
+#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STADEF    1
+
+#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMIN    0
+#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMAX    1
+#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STADEF    1
+
+#define WNI_CFG_AUTHENTICATION_TYPE_STAMIN    0
+#define WNI_CFG_AUTHENTICATION_TYPE_STAMAX    65535
+#define WNI_CFG_AUTHENTICATION_TYPE_STADEF    0
+
+#define WNI_CFG_PRIVACY_ENABLED_STAMIN    0
+#define WNI_CFG_PRIVACY_ENABLED_STAMAX    1
+#define WNI_CFG_PRIVACY_ENABLED_STADEF    0
+
+#define WNI_CFG_SHORT_PREAMBLE_STAMIN    0
+#define WNI_CFG_SHORT_PREAMBLE_STAMAX    1
+#define WNI_CFG_SHORT_PREAMBLE_STADEF    1
+
+#define WNI_CFG_SHORT_SLOT_TIME_STAMIN    0
+#define WNI_CFG_SHORT_SLOT_TIME_STAMAX    1
+#define WNI_CFG_SHORT_SLOT_TIME_STADEF    1
+
+#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMIN    0
+#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMAX    1
+#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STADEF    0
+
+#define WNI_CFG_QOS_ENABLED_STAMIN    0
+#define WNI_CFG_QOS_ENABLED_STAMAX    1
+#define WNI_CFG_QOS_ENABLED_STADEF    0
+
+#define WNI_CFG_HCF_ENABLED_STAMIN    0
+#define WNI_CFG_HCF_ENABLED_STAMAX    1
+#define WNI_CFG_HCF_ENABLED_STADEF    0
+
+#define WNI_CFG_RSN_ENABLED_STAMIN    0
+#define WNI_CFG_RSN_ENABLED_STAMAX    1
+#define WNI_CFG_RSN_ENABLED_STADEF    0
+
+#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STAMIN    0
+#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STAMAX    180000
+#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STADEF    5000
+
+#define WNI_CFG_11D_ENABLED_STAMIN    0
+#define WNI_CFG_11D_ENABLED_STAMAX    1
+#define WNI_CFG_11D_ENABLED_STADEF    1
+
+#define WNI_CFG_NETWORK_DENSITY_LOW    0
+#define WNI_CFG_NETWORK_DENSITY_MEDIUM    1
+#define WNI_CFG_NETWORK_DENSITY_HIGH    2
+#define WNI_CFG_NETWORK_DENSITY_ADAPTIVE    3
+
+#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_CARRIER    1
+#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_CORRELATION    2
+
+#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMIN    0
+#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX    128
+#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STADEF    27
+
+#define WNI_CFG_11H_ENABLED_STAMIN    0
+#define WNI_CFG_11H_ENABLED_STAMAX    1
+#define WNI_CFG_11H_ENABLED_STADEF    1
+
+#define WNI_CFG_WME_ENABLED_STAMIN    0
+#define WNI_CFG_WME_ENABLED_STAMAX    1
+#define WNI_CFG_WME_ENABLED_STADEF    1
+
+#define WNI_CFG_MAX_SP_LENGTH_STAMIN    0
+#define WNI_CFG_MAX_SP_LENGTH_STAMAX    3
+#define WNI_CFG_MAX_SP_LENGTH_STADEF    0
+
+#define WNI_CFG_WSM_ENABLED_STAMIN    0
+#define WNI_CFG_WSM_ENABLED_STAMAX    1
+#define WNI_CFG_WSM_ENABLED_STADEF    0
+
+#define WNI_CFG_EDCA_PROFILE_STAMIN    0
+#define WNI_CFG_EDCA_PROFILE_STAMAX    255
+#define WNI_CFG_EDCA_PROFILE_STADEF    1
+
+#define WNI_CFG_EDCA_PROFILE_ANI    0
+#define WNI_CFG_EDCA_PROFILE_WMM    1
+#define WNI_CFG_EDCA_PROFILE_TIT_DEMO    2
+#define WNI_CFG_EDCA_PROFILE_ETSI_EUROPE   3
+#define WNI_CFG_EDCA_PROFILE_MAX    4
+
+#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMIN    0
+#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMAX    255
+#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STADEF    0
+
+#define WNI_CFG_ADMIT_POLICY_ADMIT_ALL    0
+#define WNI_CFG_ADMIT_POLICY_REJECT_ALL    1
+#define WNI_CFG_ADMIT_POLICY_BW_FACTOR    2
+
+#define WNI_CFG_CHANNEL_BONDING_MODE_STAMIN    0
+#define WNI_CFG_CHANNEL_BONDING_MODE_STAMAX    10
+#define WNI_CFG_CHANNEL_BONDING_MODE_STADEF    0
+
+#define WNI_CFG_CHANNEL_BONDING_MODE_DISABLE    0
+#define WNI_CFG_CHANNEL_BONDING_MODE_ENABLE    1
+#define WNI_CFG_CHANNEL_BONDING_MODE_IF_NO_LEGACY_BSS    2
+#define WNI_CFG_CHANNEL_BONDING_MODE_IF_NO_LEGACY_ALL    3
+#define WNI_CFG_CHANNEL_BONDING_MODE_INTELLIGENT    4
+
+#define WNI_CFG_BLOCK_ACK_ENABLED_STAMIN    0
+#define WNI_CFG_BLOCK_ACK_ENABLED_STAMAX    3
+#define WNI_CFG_BLOCK_ACK_ENABLED_STADEF    0
+
+#define WNI_CFG_BLOCK_ACK_ENABLED_DELAYED    0
+#define WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE    1
+
+#define WNI_CFG_HT_CAP_INFO_ADVANCE_CODING    0
+#define WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET    1
+#define WNI_CFG_HT_CAP_INFO_SM_POWER_SAVE    2
+#define WNI_CFG_HT_CAP_INFO_GREEN_FIELD    4
+#define WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ    5
+#define WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ    6
+#define WNI_CFG_HT_CAP_INFO_TX_STBC    7
+#define WNI_CFG_HT_CAP_INFO_RX_STBC    8
+#define WNI_CFG_HT_CAP_INFO_DELAYED_BA    10
+#define WNI_CFG_HT_CAP_INFO_MAX_AMSDU_SIZE    11
+#define WNI_CFG_HT_CAP_INFO_DSSS_CCK_MODE_40MHZ    12
+#define WNI_CFG_HT_CAP_INFO_PSMP    13
+#define WNI_CFG_HT_CAP_INFO_STBC_CONTROL_FRAME    14
+#define WNI_CFG_HT_CAP_INFO_LSIG_TXOP_PROTECTION    15
+
+#define WNI_CFG_TX_BF_CAP_STAMIN    0
+#define WNI_CFG_TX_BF_CAP_STAMAX    4294967295
+#define WNI_CFG_TX_BF_CAP_STADEF    0
+
+#define WNI_CFG_AS_CAP_STAMIN    0
+#define WNI_CFG_AS_CAP_STAMAX    255
+#define WNI_CFG_AS_CAP_STADEF    0
+
+#define WNI_CFG_AS_CAP_ANTENNA_SELECTION    0
+#define WNI_CFG_AS_CAP_EXPLICIT_CSI_FEEDBACK_TX    1
+#define WNI_CFG_AS_CAP_ANTENNA_INDICES_FEEDBACK_TX    2
+#define WNI_CFG_AS_CAP_EXPLICIT_CSI_FEEDBACK    3
+#define WNI_CFG_AS_CAP_ANTENNA_INDICES_FEEDBACK    4
+#define WNI_CFG_AS_CAP_RX_AS    5
+#define WNI_CFG_AS_CAP_TX_SOUNDING_PPDUS    6
+#define WNI_CFG_AS_CAP_RESERVED    7
+
+#define WNI_CFG_GREENFIELD_CAPABILITY_STAMIN    0
+#define WNI_CFG_GREENFIELD_CAPABILITY_STAMAX    1
+#define WNI_CFG_GREENFIELD_CAPABILITY_STADEF    0
+
+#define WNI_CFG_GREENFIELD_CAPABILITY_ENABLE    1
+#define WNI_CFG_GREENFIELD_CAPABILITY_DISABLE    0
+
+/*
+ * WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF + 1 is
+ * assumed to be the default fw supported BF antennas, if fw
+ * says it supports 8 antennas in rx ready event and if
+ * gTxBFCsnValue INI value is configured above 3, set
+ * the same to WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED.
+ * Otherwise, fall back and set fw default value[3].
+ */
+#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF    3
+
+
+#define WNI_CFG_MAX_AMSDU_LENGTH_SHORT_3839_BYTES    0
+#define WNI_CFG_MAX_AMSDU_LENGTH_LONG_7935__BYTES    1
+
+#define WNI_CFG_MPDU_DENSITY_STAMIN    0
+#define WNI_CFG_MPDU_DENSITY_STAMAX    7
+#define WNI_CFG_MPDU_DENSITY_STADEF    7
+
+#define WNI_CFG_NUM_BUFF_ADVERT_STAMIN    0
+#define WNI_CFG_NUM_BUFF_ADVERT_STAMAX    128
+#define WNI_CFG_NUM_BUFF_ADVERT_STADEF    64
+
+#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMIN    0
+#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMAX    3
+#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STADEF    3
+
+#define WNI_CFG_SHORT_GI_20MHZ_STAMIN    0
+#define WNI_CFG_SHORT_GI_20MHZ_STAMAX    1
+#define WNI_CFG_SHORT_GI_20MHZ_STADEF    1
+
+#define WNI_CFG_SHORT_GI_20MHZ_ENABLE    1
+#define WNI_CFG_SHORT_GI_20MHZ_DISABLE    0
+
+#define WNI_CFG_SHORT_GI_40MHZ_STAMIN    0
+#define WNI_CFG_SHORT_GI_40MHZ_STAMAX    1
+#define WNI_CFG_SHORT_GI_40MHZ_STADEF    0
+
+#define WNI_CFG_SHORT_GI_40MHZ_ENABLE    1
+#define WNI_CFG_SHORT_GI_40MHZ_DISABLE    0
+
+#define WNI_CFG_SCAN_IN_POWERSAVE_STAMIN    0
+#define WNI_CFG_SCAN_IN_POWERSAVE_STAMAX    1
+#define WNI_CFG_SCAN_IN_POWERSAVE_STADEF    1
+
+#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMIN    0
+#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMAX    1
+#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STADEF    1
+
+#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMIN    0
+#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMAX    1
+#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STADEF    1
+
+#define WNI_CFG_IBSS_AUTO_BSSID_STAMIN    0
+#define WNI_CFG_IBSS_AUTO_BSSID_STAMAX    1
+#define WNI_CFG_IBSS_AUTO_BSSID_STADEF    1
+
+#define WNI_CFG_WPS_ENABLE_AP    1
+
+#define WNI_CFG_TELE_BCN_WAKEUP_EN_STAMIN    0
+#define WNI_CFG_TELE_BCN_WAKEUP_EN_STAMAX    1
+#define WNI_CFG_TELE_BCN_WAKEUP_EN_STADEF    0
+
+#define WNI_CFG_TELE_BCN_MAX_LI_STAMIN    0
+#define WNI_CFG_TELE_BCN_MAX_LI_STAMAX    7
+#define WNI_CFG_TELE_BCN_MAX_LI_STADEF    5
+
+#define WNI_CFG_ASSOC_STA_LIMIT_STAMIN    1
+#define WNI_CFG_ASSOC_STA_LIMIT_STAMAX    32
+#define WNI_CFG_ASSOC_STA_LIMIT_STADEF    10
+
+#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMIN    0
+#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX    1
+#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STADEF    0
+
+#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMIN    0
+#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMAX    1
+#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STADEF    0
+
+#define WNI_CFG_IBSS_ATIM_WIN_SIZE_STAMIN    0
+#define WNI_CFG_IBSS_ATIM_WIN_SIZE_STAMAX    100
+#define WNI_CFG_IBSS_ATIM_WIN_SIZE_STADEF    0
+
+#define WNI_CFG_HE_CONTROL_STAMIN 0
+#define WNI_CFG_HE_CONTROL_STAMAX 1
+#define WNI_CFG_HE_CONTROL_STADEF 0
+
+#define WNI_CFG_HE_TWT_REQUESTOR_STAMIN 0
+#define WNI_CFG_HE_TWT_REQUESTOR_STAMAX 1
+#define WNI_CFG_HE_TWT_REQUESTOR_STADEF 0
+
+#define WNI_CFG_HE_TWT_RESPONDER_STAMIN 0
+#define WNI_CFG_HE_TWT_RESPONDER_STAMAX 1
+#define WNI_CFG_HE_TWT_RESPONDER_STADEF 0
+
+#define WNI_CFG_HE_FRAGMENTATION_STAMIN 0
+#define WNI_CFG_HE_FRAGMENTATION_STAMAX 0x3
+#define WNI_CFG_HE_FRAGMENTATION_STADEF 0
+
+#define WNI_CFG_HE_MAX_FRAG_MSDU_STAMIN 0
+#define WNI_CFG_HE_MAX_FRAG_MSDU_STAMAX 0x7
+#define WNI_CFG_HE_MAX_FRAG_MSDU_STADEF 0
+
+#define WNI_CFG_HE_MIN_FRAG_SIZE_STAMIN 0
+#define WNI_CFG_HE_MIN_FRAG_SIZE_STAMAX 0x3
+#define WNI_CFG_HE_MIN_FRAG_SIZE_STADEF 0
+
+#define WNI_CFG_HE_TRIG_PAD_STAMIN 0
+#define WNI_CFG_HE_TRIG_PAD_STAMAX 2
+#define WNI_CFG_HE_TRIG_PAD_STADEF 0
+
+#define WNI_CFG_HE_MTID_AGGR_RX_STAMIN 0
+#define WNI_CFG_HE_MTID_AGGR_RX_STAMAX 0x7
+#define WNI_CFG_HE_MTID_AGGR_RX_STADEF 0
+
+#define WNI_CFG_HE_LINK_ADAPTATION_STAMIN 0
+#define WNI_CFG_HE_LINK_ADAPTATION_STAMAX 0x3
+#define WNI_CFG_HE_LINK_ADAPTATION_STADEF 0
+
+#define WNI_CFG_HE_ALL_ACK_STAMIN 0
+#define WNI_CFG_HE_ALL_ACK_STAMAX 1
+#define WNI_CFG_HE_ALL_ACK_STADEF 0
+
+#define WNI_CFG_HE_TRIGD_RSP_SCHEDULING_STAMIN 0
+#define WNI_CFG_HE_TRIGD_RSP_SCHEDULING_STAMAX 1
+#define WNI_CFG_HE_TRIGD_RSP_SCHEDULING_STADEF 0
+
+#define WNI_CFG_HE_BUFFER_STATUS_RPT_STAMIN 0
+#define WNI_CFG_HE_BUFFER_STATUS_RPT_STAMAX 1
+#define WNI_CFG_HE_BUFFER_STATUS_RPT_STADEF 0
+
+#define WNI_CFG_HE_BCAST_TWT_STAMIN 0
+#define WNI_CFG_HE_BCAST_TWT_STAMAX 1
+#define WNI_CFG_HE_BCAST_TWT_STADEF 0
+
+#define WNI_CFG_HE_BA_32BIT_STAMIN 0
+#define WNI_CFG_HE_BA_32BIT_STAMAX 1
+#define WNI_CFG_HE_BA_32BIT_STADEF 0
+
+#define WNI_CFG_HE_MU_CASCADING_STAMIN 0
+#define WNI_CFG_HE_MU_CASCADING_STAMAX 1
+#define WNI_CFG_HE_MU_CASCADING_STADEF 0
+
+#define WNI_CFG_HE_MULTI_TID_STAMIN 0
+#define WNI_CFG_HE_MULTI_TID_STAMAX 1
+#define WNI_CFG_HE_MULTI_TID_STADEF 0
+
+#define WNI_CFG_HE_DL_MU_BA_STAMIN 0
+#define WNI_CFG_HE_DL_MU_BA_STAMAX 1
+#define WNI_CFG_HE_DL_MU_BA_STADEF 0
+
+#define WNI_CFG_HE_OMI_STAMIN 0
+#define WNI_CFG_HE_OMI_STAMAX 1
+#define WNI_CFG_HE_OMI_STADEF 0
+
+#define WNI_CFG_HE_OFDMA_RA_STAMIN 0
+#define WNI_CFG_HE_OFDMA_RA_STAMAX 1
+#define WNI_CFG_HE_OFDMA_RA_STADEF 0
+
+#define WNI_CFG_HE_MAX_AMPDU_LEN_STAMIN 0
+#define WNI_CFG_HE_MAX_AMPDU_LEN_STAMAX 0x3
+#define WNI_CFG_HE_MAX_AMPDU_LEN_STADEF 0
+
+#define WNI_CFG_HE_AMSDU_FRAG_STAMIN 0
+#define WNI_CFG_HE_AMSDU_FRAG_STAMAX 1
+#define WNI_CFG_HE_AMSDU_FRAG_STADEF 0
+
+#define WNI_CFG_HE_FLEX_TWT_SCHED_STAMIN 0
+#define WNI_CFG_HE_FLEX_TWT_SCHED_STAMAX 1
+#define WNI_CFG_HE_FLEX_TWT_SCHED_STADEF 0
+
+#define WNI_CFG_HE_RX_CTRL_STAMIN 0
+#define WNI_CFG_HE_RX_CTRL_STAMAX 1
+#define WNI_CFG_HE_RX_CTRL_STADEF 0
+
+#define WNI_CFG_HE_BSRP_AMPDU_AGGR_STAMIN 0
+#define WNI_CFG_HE_BSRP_AMPDU_AGGR_STAMAX 1
+#define WNI_CFG_HE_BSRP_AMPDU_AGGR_STADEF 0
+
+#define WNI_CFG_HE_QTP_STAMIN 0
+#define WNI_CFG_HE_QTP_STAMAX 1
+#define WNI_CFG_HE_QTP_STADEF 0
+
+#define WNI_CFG_HE_A_BQR_STAMIN 0
+#define WNI_CFG_HE_A_BQR_STAMAX 1
+#define WNI_CFG_HE_A_BQR_STADEF 0
+
+#define WNI_CFG_HE_SR_RESPONDER_STAMIN 0
+#define WNI_CFG_HE_SR_RESPONDER_STAMAX 1
+#define WNI_CFG_HE_SR_RESPONDER_STADEF 0
+
+#define WNI_CFG_HE_NDP_FEEDBACK_SUPP_STAMIN 0
+#define WNI_CFG_HE_NDP_FEEDBACK_SUPP_STAMAX 1
+#define WNI_CFG_HE_NDP_FEEDBACK_SUPP_STADEF 0
+
+#define WNI_CFG_HE_OPS_SUPP_STAMIN 0
+#define WNI_CFG_HE_OPS_SUPP_STAMAX 1
+#define WNI_CFG_HE_OPS_SUPP_STADEF 0
+
+#define WNI_CFG_HE_AMSDU_IN_AMPDU_MIN 0
+#define WNI_CFG_HE_AMSDU_IN_AMPDU_MAX 1
+#define WNI_CFG_HE_AMSDU_IN_AMPDU_DEF 0
+
+#define WNI_CFG_HE_MTID_AGGR_TX_MIN 0
+#define WNI_CFG_HE_MTID_AGGR_TX_MAX 0x7
+#define WNI_CFG_HE_MTID_AGGR_TX_DEF 0
+
+#define WNI_CFG_HE_SUB_CH_SEL_TX_MIN 0
+#define WNI_CFG_HE_SUB_CH_SEL_TX_MAX 1
+#define WNI_CFG_HE_SUB_CH_SEL_TX_DEF 0
+
+#define WNI_CFG_HE_UL_2X996_RU_MIN 0
+#define WNI_CFG_HE_UL_2X996_RU_MAX 1
+#define WNI_CFG_HE_UL_2X996_RU_DEF 0
+
+#define WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX_MIN 0
+#define WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX_MAX 1
+#define WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX_DEF 0
+
+#define WNI_CFG_HE_CHAN_WIDTH_STAMIN 0
+#define WNI_CFG_HE_CHAN_WIDTH_STAMAX 0x3F
+#define WNI_CFG_HE_CHAN_WIDTH_STADEF 0
+
+#define WNI_CFG_HE_RX_PREAM_PUNC_STAMIN 0
+#define WNI_CFG_HE_RX_PREAM_PUNC_STAMAX 0xF
+#define WNI_CFG_HE_RX_PREAM_PUNC_STADEF 0
+
+#define WNI_CFG_HE_CLASS_OF_DEVICE_STAMIN 0
+#define WNI_CFG_HE_CLASS_OF_DEVICE_STAMAX 1
+#define WNI_CFG_HE_CLASS_OF_DEVICE_STADEF 0
+
+#define WNI_CFG_HE_LDPC_STAMIN 0
+#define WNI_CFG_HE_LDPC_STAMAX 1
+#define WNI_CFG_HE_LDPC_STADEF 0
+
+#define WNI_CFG_HE_LTF_PPDU_STAMIN 0
+#define WNI_CFG_HE_LTF_PPDU_STAMAX 0x3
+#define WNI_CFG_HE_LTF_PPDU_STADEF 0
+
+#define WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS_MIN 0
+#define WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS_MAX 0x3
+#define WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS_DEF 0
+
+#define WNI_CFG_HE_LTF_NDP_STAMIN 0
+#define WNI_CFG_HE_LTF_NDP_STAMAX 0x3
+#define WNI_CFG_HE_LTF_NDP_STADEF 0
+
+#define WNI_CFG_HE_TX_STBC_LT80_STAMIN 0
+#define WNI_CFG_HE_TX_STBC_LT80_STAMAX 1
+#define WNI_CFG_HE_TX_STBC_LT80_STADEF 0
+
+#define WNI_CFG_HE_RX_STBC_LT80_STAMIN 0
+#define WNI_CFG_HE_RX_STBC_LT80_STAMAX 1
+#define WNI_CFG_HE_RX_STBC_LT80_STADEF 0
+
+#define WNI_CFG_HE_DOPPLER_STAMIN 0
+#define WNI_CFG_HE_DOPPLER_STAMAX 0x3
+#define WNI_CFG_HE_DOPPLER_STADEF 0
+
+#define WNI_CFG_HE_UL_MUMIMO_STAMIN 0
+#define WNI_CFG_HE_UL_MUMIMO_STAMAX 0x3
+#define WNI_CFG_HE_UL_MUMIMO_STADEF 0
+
+#define WNI_CFG_HE_DCM_TX_STAMIN 0
+#define WNI_CFG_HE_DCM_TX_STAMAX 0x7
+#define WNI_CFG_HE_DCM_TX_STADEF 0
+
+#define WNI_CFG_HE_DCM_RX_STAMIN 0
+#define WNI_CFG_HE_DCM_RX_STAMAX 0x7
+#define WNI_CFG_HE_DCM_RX_STADEF 0
+
+#define WNI_CFG_HE_MU_PPDU_STAMIN 0
+#define WNI_CFG_HE_MU_PPDU_STAMAX 1
+#define WNI_CFG_HE_MU_PPDU_STADEF 0
+
+#define WNI_CFG_HE_SU_BEAMFORMER_STAMIN 0
+#define WNI_CFG_HE_SU_BEAMFORMER_STAMAX 1
+#define WNI_CFG_HE_SU_BEAMFORMER_STADEF 0
+
+#define WNI_CFG_HE_SU_BEAMFORMEE_STAMIN 0
+#define WNI_CFG_HE_SU_BEAMFORMEE_STAMAX 1
+#define WNI_CFG_HE_SU_BEAMFORMEE_STADEF 0
+
+#define WNI_CFG_HE_MU_BEAMFORMER_STAMIN 0
+#define WNI_CFG_HE_MU_BEAMFORMER_STAMAX 1
+#define WNI_CFG_HE_MU_BEAMFORMER_STADEF 0
+
+#define WNI_CFG_HE_BFEE_STS_LT80_STAMIN 0
+#define WNI_CFG_HE_BFEE_STS_LT80_STAMAX 0x7
+#define WNI_CFG_HE_BFEE_STS_LT80_STADEF 0
+
+#define WNI_CFG_HE_BFEE_STS_GT80_STAMIN 0
+#define WNI_CFG_HE_BFEE_STS_GT80_STAMAX 0x7
+#define WNI_CFG_HE_BFEE_STS_GT80_STADEF 0
+
+#define WNI_CFG_HE_NUM_SOUND_LT80_STAMIN 0
+#define WNI_CFG_HE_NUM_SOUND_LT80_STAMAX 0x7
+#define WNI_CFG_HE_NUM_SOUND_LT80_STADEF 0
+
+#define WNI_CFG_HE_NUM_SOUND_GT80_STAMIN 0
+#define WNI_CFG_HE_NUM_SOUND_GT80_STAMAX 0x7
+#define WNI_CFG_HE_NUM_SOUND_GT80_STADEF 0
+
+#define WNI_CFG_HE_SU_FEED_TONE16_STAMIN 0
+#define WNI_CFG_HE_SU_FEED_TONE16_STAMAX 1
+#define WNI_CFG_HE_SU_FEED_TONE16_STADEF 0
+
+#define WNI_CFG_HE_MU_FEED_TONE16_STAMIN 0
+#define WNI_CFG_HE_MU_FEED_TONE16_STAMAX 1
+#define WNI_CFG_HE_MU_FEED_TONE16_STADEF 0
+
+#define WNI_CFG_HE_CODEBOOK_SU_STAMIN 0
+#define WNI_CFG_HE_CODEBOOK_SU_STAMAX 1
+#define WNI_CFG_HE_CODEBOOK_SU_STADEF 0
+
+#define WNI_CFG_HE_CODEBOOK_MU_STAMIN 0
+#define WNI_CFG_HE_CODEBOOK_MU_STAMAX 1
+#define WNI_CFG_HE_CODEBOOK_MU_STADEF 0
+
+#define WNI_CFG_HE_BFRM_FEED_STAMIN 0
+#define WNI_CFG_HE_BFRM_FEED_STAMAX 0x7
+#define WNI_CFG_HE_BFRM_FEED_STADEF 0
+
+#define WNI_CFG_HE_ER_SU_PPDU_STAMIN 0
+#define WNI_CFG_HE_ER_SU_PPDU_STAMAX 1
+#define WNI_CFG_HE_ER_SU_PPDU_STADEF 0
+
+#define WNI_CFG_HE_DL_PART_BW_STAMIN 0
+#define WNI_CFG_HE_DL_PART_BW_STAMAX 1
+#define WNI_CFG_HE_DL_PART_BW_STADEF 0
+
+#define WNI_CFG_HE_PPET_PRESENT_STAMIN 0
+#define WNI_CFG_HE_PPET_PRESENT_STAMAX 1
+#define WNI_CFG_HE_PPET_PRESENT_STADEF 0
+
+#define WNI_CFG_HE_SRP_STAMIN 0
+#define WNI_CFG_HE_SRP_STAMAX 1
+#define WNI_CFG_HE_SRP_STADEF 0
+
+#define WNI_CFG_HE_POWER_BOOST_STAMIN 0
+#define WNI_CFG_HE_POWER_BOOST_STAMAX 1
+#define WNI_CFG_HE_POWER_BOOST_STADEF 0
+
+#define WNI_CFG_HE_4x_LTF_GI_STAMIN 0
+#define WNI_CFG_HE_4x_LTF_GI_STAMAX 1
+#define WNI_CFG_HE_4x_LTF_GI_STADEF 0
+
+#define WNI_CFG_HE_MAX_NC_STAMIN 0
+#define WNI_CFG_HE_MAX_NC_STAMAX 0x7
+#define WNI_CFG_HE_MAX_NC_STADEF 0
+
+#define WNI_CFG_HE_TX_STBC_GT80_STAMIN 0
+#define WNI_CFG_HE_TX_STBC_GT80_STAMAX 1
+#define WNI_CFG_HE_TX_STBC_GT80_STADEF 0
+
+#define WNI_CFG_HE_RX_STBC_GT80_STAMIN 0
+#define WNI_CFG_HE_RX_STBC_GT80_STAMAX 1
+#define WNI_CFG_HE_RX_STBC_GT80_STADEF 0
+
+#define WNI_CFG_HE_ER_4x_LTF_GI_STAMIN 0
+#define WNI_CFG_HE_ER_4x_LTF_GI_STAMAX 1
+#define WNI_CFG_HE_ER_4x_LTF_GI_STADEF 0
+
+#define WNI_CFG_HE_PPDU_20_IN_40MHZ_2G_MIN 0
+#define WNI_CFG_HE_PPDU_20_IN_40MHZ_2G_MAX 1
+#define WNI_CFG_HE_PPDU_20_IN_40MHZ_2G_DEF 0
+
+#define WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ_MIN 0
+#define WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ_MAX 1
+#define WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ_DEF 0
+
+#define WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ_MIN 0
+#define WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ_MAX 1
+#define WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ_DEF 0
+
+#define WNI_CFG_HE_ER_1X_HE_LTF_GI_MIN 0
+#define WNI_CFG_HE_ER_1X_HE_LTF_GI_MAX 1
+#define WNI_CFG_HE_ER_1X_HE_LTF_GI_DEF 0
+
+#define WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF_MIN 0
+#define WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF_MAX 1
+#define WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF_DEF 0
+
+#define WNI_CFG_HE_DCM_MAX_BW_MIN 0
+#define WNI_CFG_HE_DCM_MAX_BW_MAX 3
+#define WNI_CFG_HE_DCM_MAX_BW_DEF 0
+
+#define WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM_MIN 0
+#define WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM_MAX 1
+#define WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM_DEF 0
+
+#define WNI_CFG_HE_TX_1024_QAM_LT_242_RU_MIN 0
+#define WNI_CFG_HE_TX_1024_QAM_LT_242_RU_MAX 1
+#define WNI_CFG_HE_TX_1024_QAM_LT_242_RU_DEF 0
+
+#define WNI_CFG_HE_RX_1024_QAM_LT_242_RU_MIN 0
+#define WNI_CFG_HE_RX_1024_QAM_LT_242_RU_MAX 1
+#define WNI_CFG_HE_RX_1024_QAM_LT_242_RU_DEF 0
+
+#define WNI_CFG_HE_NON_TRIG_CQI_FEEDBACK_MIN 0
+#define WNI_CFG_HE_NON_TRIG_CQI_FEEDBACK_MAX 1
+#define WNI_CFG_HE_NON_TRIG_CQI_FEEDBACK_DEF 0
+
+#define WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB_MIN 0
+#define WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB_MAX 1
+#define WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB_DEF 0
+
+#define WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB_MIN 0
+#define WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB_MAX 1
+#define WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB_DEF 0
+
+#define WNI_CFG_HE_RX_MCS_MAP_LT_80_MIN 0x0000
+#define WNI_CFG_HE_RX_MCS_MAP_LT_80_MAX 0xFFFF
+#define WNI_CFG_HE_RX_MCS_MAP_LT_80_DEF 0xFFF0
+
+#define WNI_CFG_HE_TX_MCS_MAP_LT_80_MIN 0x0000
+#define WNI_CFG_HE_TX_MCS_MAP_LT_80_MAX 0xFFFF
+#define WNI_CFG_HE_TX_MCS_MAP_LT_80_DEF 0xFFF0
+
+#define WNI_CFG_HE_RX_MCS_MAP_160_MIN 0x0000
+#define WNI_CFG_HE_RX_MCS_MAP_160_MAX 0xFFFF
+#define WNI_CFG_HE_RX_MCS_MAP_160_DEF 0xFFF0
+
+#define WNI_CFG_HE_TX_MCS_MAP_160_MIN 0x0000
+#define WNI_CFG_HE_TX_MCS_MAP_160_MAX 0xFFFF
+#define WNI_CFG_HE_TX_MCS_MAP_160_DEF 0xFFF0
+
+#define WNI_CFG_HE_RX_MCS_MAP_80_80_MIN 0x0000
+#define WNI_CFG_HE_RX_MCS_MAP_80_80_MAX 0xFFFF
+#define WNI_CFG_HE_RX_MCS_MAP_80_80_DEF 0xFFF0
+
+#define WNI_CFG_HE_TX_MCS_MAP_80_80_MIN 0x0000
+#define WNI_CFG_HE_TX_MCS_MAP_80_80_MAX 0xFFFF
+#define WNI_CFG_HE_TX_MCS_MAP_80_80_DEF 0xFFF0
+
+#define WNI_CFG_HE_OPS_BSS_COLOR_MIN 0x01
+#define WNI_CFG_HE_OPS_BSS_COLOR_MAX 0x3F
+#define WNI_CFG_HE_OPS_BSS_COLOR_DEF 0x01
+
+#define WNI_CFG_HE_OPS_DEFAULT_PE_MIN 0x0
+#define WNI_CFG_HE_OPS_DEFAULT_PE_MAX 0x7
+#define WNI_CFG_HE_OPS_DEFAULT_PE_DEF 0x0
+
+#define WNI_CFG_HE_OPS_TWT_REQUIRED_MIN 0
+#define WNI_CFG_HE_OPS_TWT_REQUIRED_MAX 1
+#define WNI_CFG_HE_OPS_TWT_REQUIRED_DEF 0
+
+#define WNI_CFG_HE_OPS_RTS_THRESHOLD_MIN 0x000
+#define WNI_CFG_HE_OPS_RTS_THRESHOLD_MAX 0x3FF
+#define WNI_CFG_HE_OPS_RTS_THRESHOLD_DEF 0x000
+
+#define WNI_CFG_HE_OPS_PARTIAL_BSS_COL_MIN 0
+#define WNI_CFG_HE_OPS_PARTIAL_BSS_COL_MAX 1
+#define WNI_CFG_HE_OPS_PARTIAL_BSS_COL_DEF 0
+
+#define WNI_CFG_HE_OPS_VHT_OPER_PRESENT_MIN 0
+#define WNI_CFG_HE_OPS_VHT_OPER_PRESENT_MAX 1
+#define WNI_CFG_HE_OPS_VHT_OPER_PRESENT_DEF 0
+
+#define WNI_CFG_HE_OPS_MBSSID_AP_MIN 0
+#define WNI_CFG_HE_OPS_MBSSID_AP_MAX 1
+#define WNI_CFG_HE_OPS_MBSSID_AP_DEF 0
+
+#define WNI_CFG_HE_OPS_TX_BSSID_IND_MIN 0
+#define WNI_CFG_HE_OPS_TX_BSSID_IND_MAX 1
+#define WNI_CFG_HE_OPS_TX_BSSID_IND_DEF 0
+
+#define WNI_CFG_HE_OPS_BSS_COL_DISABLED_MIN 0
+#define WNI_CFG_HE_OPS_BSS_COL_DISABLED_MAX 1
+#define WNI_CFG_HE_OPS_BSS_COL_DISABLED_DEF 0
+
+#define WNI_CFG_HE_OPS_BASIC_MCS_NSS_MIN 0x0000
+#define WNI_CFG_HE_OPS_BASIC_MCS_NSS_MAX 0xFFFF
+#define WNI_CFG_HE_OPS_BASIC_MCS_NSS_DEF 0xFFFC
+
+#define WNI_CFG_HE_STA_OBSSPD_STAMIN 0
+#define WNI_CFG_HE_STA_OBSSPD_STAMAX 0xffffffff
+#define WNI_CFG_HE_STA_OBSSPD_STADEF 0x15b8c2ae
+
+#define WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT_STAMIN    1
+#define WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT_STAMAX    255
+#define WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT_STADEF    50
+
+#define WNI_CFG_TWT_REQUESTOR_STAMIN 0
+#define WNI_CFG_TWT_REQUESTOR_STAMAX 1
+#define WNI_CFG_TWT_REQUESTOR_STADEF 0
+
+#define WNI_CFG_TWT_RESPONDER_STAMIN 0
+#define WNI_CFG_TWT_RESPONDER_STAMAX 1
+#define WNI_CFG_TWT_RESPONDER_STADEF 0
+
+#define WNI_CFG_BCAST_TWT_STAMIN 0
+#define WNI_CFG_BCAST_TWT_STAMAX 1
+#define WNI_CFG_BCAST_TWT_STADEF 0
+
+#define CFG_STA_MAGIC_DWORD    0xbeefbeef
+
+#endif
diff --git a/core/mac/src/cfg/cfgUtil/dot11f.frms b/core/mac/src/cfg/cfgUtil/dot11f.frms
new file mode 100644
index 0000000..a0bebf0
--- /dev/null
+++ b/core/mac/src/cfg/cfgUtil/dot11f.frms
@@ -0,0 +1,4335 @@
+/*
+ * Copyright (c) 2006-2007, 2014-2018 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.
+ */
+
+/**
+ * \file dot11f.frms
+ *
+ * \brief Primary 'frames' file for the MAC parser
+ *
+ *
+ * This  file defines  several  802.11 frames  (along  with their  associated
+ * constituents) in a little language  called "frames".  When run through the
+ * 'framesc' program, it will generate  C code for working with these frames:
+ * C  structs  representing the  802.11  frame  together  with functions  for
+ * packing & unpacking them.
+ *
+ * For more information on the "frames" language, run 'framesc --help'...
+ *
+ *
+ */
+
+
+// Tell framesc what types to use for...
+%8-bit-type   uint8_t  // 8,
+%16-bit-type  uint16_t // 16,
+%32-bit-type  uint32_t // & 32-bit unsigned integral types.  These can also
+                       // be specified on the command line.
+
+// Define some mnemonic constants; these are just for our use with the frames
+// files we're compiling.  IOW, they won't result in any C code being
+// emitted.
+
+const EID_SSID                       =   0;
+const EID_SUPP_RATES                 =   1;
+const EID_FH_PARAM_SET               =   2;
+const EID_DS_PARAM_SET               =   3;
+const EID_CF_PARAM_SET               =   4;
+const EID_TIM                        =   5;
+const EID_IBSS_PARAM_SET             =   6;
+const EID_COUNTRY                    =   7;
+const EID_FH_PATTERN                 =   8;
+const EID_FH_PATT_TABLE              =   9;
+const EID_REQUEST                    =  10;
+const EID_QBSS_LOAD                  =  11;
+const EID_EDCA_PARAM_SET             =  12;
+const EID_TSPEC                      =  13;
+const EID_TCLAS                      =  14;
+const EID_SCHEDULE                   =  15;
+const EID_CHALLENGE_TEXT             =  16;
+const EID_POWER_CONSTRAINTS          =  32;
+const EID_POWER_CAPABILITY           =  33;
+const EID_TPC_REQUEST                =  34;
+const EID_TPC_REPORT                 =  35;
+const EID_SUPPORTED_CHANNELS         =  36;
+const EID_CHANNEL_SWITCH_ANN         =  37;
+const EID_MEAS_REQUEST               =  38;
+const EID_MEAS_REPORT                =  39;
+const EID_QUIET                      =  40;
+const EID_ERP_INFO                   =  42;
+const EID_TS_DELAY                   =  43;
+const EID_TCLASS_PROC                =  44;
+const EID_HT_CAPABILITIES            =  45;
+const EID_QOS_CAPABILITY             =  46;
+const EID_RSN                        =  48;
+const EID_EXT_SUPP_RATES             =  50;
+const EID_AP_CHAN_REPORT             =  51;
+const EID_NEIGHBOR_REPORT            =  52;
+const EID_RCPI                       =  53;
+const EID_FT_MOBILITY_DOMAIN         =  54;
+const EID_FT_INFO                    =  55;
+const EID_TIMEOUT_INTERVAL           =  56;
+const EID_FT_RIC_DATA                =  57;
+const EID_SUPPORTED_OPER_CLASSES     =  59;
+const EID_EXT_CHAN_SWITCH            =  60;
+const EID_HT_INFO                    =  61;
+const EID_SEC_CHAN_OFFSET            =  62;
+const EID_RSNI                       =  65;
+const EID_RRM_MEAS_PILOT_TX_INFO     =  66;
+const EID_WAPI                       =  68;
+const EID_TIME_ADVERTISEMENT         =  69;
+const EID_RRM_ENABLED_CAPS           =  70;
+const EID_MULTIPLE_BSSID             =  71;
+const EID_20_40_BSS_COEXISTENCE      =  72;
+const EID_20_40_BSS_INTOLERANT_REPORT=  73;
+const EID_OBSS_SCAN_PARAMETERS       =  74;
+const EID_FT_RIC_DESCRIPTOR          =  75;
+const EID_LINK_IDENTIFIER            = 101;
+const EID_PTI_CONTROL                = 105;
+const EID_PU_BUFFER_STATUS           = 106;
+const EID_QOS_MAP_SET                = 110;
+const EID_ESE_SPECIFIC               = 150;
+const EID_ESE_CCKM_SPECIFIC          = 156;
+const EID_ADDBA_EXTN_ELEMENT         = 159;
+const EID_VHT_CAPABILITIES           =  191;
+const EID_VHT_OPERATION_ELEMENT      =  192;
+const EID_VHT_EXT_BSS_LOAD           =  193;
+const EID_AID                        =  197;
+const EID_EXT_CAP           	     =  127;
+const EID_OPERATING_MODE             =  199;
+const EID_WIDER_BW_CHANNEL_SWITCH_ANN=  194;
+const VHT_TRANSMIT_POWER_ENVELOPE    = 195;
+const EID_CHANNEL_SWITCH_WRAPPER     = 196;
+const EID_VENDOR_SPECIFIC            = 221;
+const EID_FILS_INDICATION            = 240;
+const EID_FRAGMENT_IE                = 242;
+/**
+ * Extended Element ID
+ *
+ * As part of IEEE-802.11-2016 spec, extended element ID is introduced(9.4.2.1)
+ * Elements are defined to have a common general format consisting of a 1 octet
+ * Element ID field, a 1 octet Length field, an optional 1 octet Element ID
+ * Extension field, and a variable-length element-specific Information field.
+ * Each element is identified by the contents of the Element ID and, when
+ * present, Element ID Extension fields as defined in this standard. An Extended
+ * Element ID is a combination of an Element ID and an Element ID Extension for
+ * those elements that have a defined Element ID Extension. The Length field
+ * specifies the number of octets following the Length field. The presence of
+ * the Element ID Extension field is determined by the Element ID field having
+ * value of 255
+ */
+const EID_EXTN_ID_ELEMENT            = 255;
+
+const SIR_MAC_PROP_EXT_RATES_TYPE    =   0;
+const SIR_MAC_PROP_AP_NAME_TYPE      =   1;
+const SIR_MAC_PROP_HCF_TYPE          =   2;
+const SIR_MAC_PROP_WDS_TYPE          =   3;
+const SIR_MAC_PROP_BP_IND_TYPE       =   4;
+const SIR_MAC_PROP_NEIGHBOR_BSS_TYPE =   5;
+const SIR_MAC_PROP_LOAD_INFO_TYPE    =   6;
+const SIR_MAC_PROP_ASSOC_TYPE        =   7;
+const SIR_MAC_PROP_LOAD_BALANCE_TYPE =   8;
+const SIR_MAC_PROP_LL_ATTR_TYPE      =   9;
+const SIR_MAC_PROP_CAPABILITY        =  10;
+const SIR_MAC_PROP_VERSION           =  11;
+const SIR_MAC_PROP_EDCAPARAMS        =  12;
+const SIR_MAC_PROP_CHANNEL_SWITCH    =  15;
+const SIR_MAC_PROP_QUIET_BSS         =  16;
+const SIR_MAC_PROP_TRIG_STA_BK_SCAN	 =  17;
+
+const ANI_WDS_INFO_MAX_LENGTH        =  64;
+const SIR_MAC_MAX_NUMBER_OF_RATES    =  12;
+const HT_MAX_SUPPORTED_MCS_SET       =  16;
+const MAX_SUPPORTED_NEIGHBOR_RPT     =  15;
+
+/////////////////////////////////////////////////////////////////////////////
+//                  Wi-Fi Protected Setup TLV Identifiers                  //
+//                  WSC Version 2.0.0 Table 28                             //
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//                  Wi-Fi Simple Configuration TLV Identifiers             //
+// WFA Vendor Extension Subelements                                        //
+/////////////////////////////////////////////////////////////////////////////
+const TLV_VERSION2                          = 0;
+const TLV_AUTHORIZED_MAC                    = 1;
+const TLV_NETWORK_KEY_SHAREABLE             = 2;
+const TLV_REQUEST_TO_ENROLL                 = 3;
+const TLV_SETTINGS_DELAY_TIME               = 4;
+
+const TLV_VERSION                           = 0x104A;
+const TLV_WI_FI_SIMPLE_CONFIG_STATE         = 0x1044;
+const TLV_AP_SETUP_LOCKED                   = 0x1057;
+const TLV_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053;
+const TLV_DEVICE_PASSWORD_ID                = 0x1012;
+const TLV_UUID_E                            = 0x1047;
+const TLV_UUID_R                            = 0x1048;
+const TLV_RF_BANDS                          = 0x103C;
+const TLV_REQUEST_TYPE                      = 0x103A;
+const TLV_RESPONSE_TYPE                     = 0x103B;
+const TLV_CONFIG_METHODS                    = 0x1008;
+const TLV_PRIMARY_DEVICE_TYPE               = 0x1054;
+const TLV_ASSOCIATION_STATE                 = 0x1002;
+const TLV_CONFIGURATION_ERROR               = 0x1009;
+const TLV_MANUFACTURER                      = 0x1021;
+const TLV_MODEL_NAME                        = 0x1023;
+const TLV_MODEL_NUMBER                      = 0x1024;
+const TLV_SERIAL_NUMBER                     = 0x1042;
+const TLV_DEVICE_NAME                       = 0x1011;
+const TLV_SELECTED_REGISTRAR                = 0x1041;
+const TLV_VENDOR_EXTENSION                  = 0x1049;
+const TLV_REQUESTED_DEVICE_TYPE             = 0x106A;
+
+/////////////////////////////////////////////////////////////////////////////
+//                  Wi-Fi Direct/P2P TLV Identifiers                       //
+/////////////////////////////////////////////////////////////////////////////
+const TLV_P2P_STATUS                         =   0;
+const TLV_MINOR_REASON_CODE                  =   1;
+const TLV_P2P_CAPABILITY                     =   2;
+const TLV_P2P_DEVICE_ID                      =   3;
+const TLV_P2P_GROUP_OWNER_INTENT             =   4;
+const TLV_CONFIGURATION_TIMEOUT              =   5;
+const TLV_LISTEN_CHANNEL                     =   6;
+const TLV_P2P_GROUP_BSSID                    =   7;
+const TLV_EXTENDED_LISTEN_TIMING             =   8;
+const TLV_INTENDED_P2P_INTERFACE_ADDRESS     =   9;
+const TLV_P2P_MANAGEABILITY                  =  10;
+const TLV_CHANNEL_LIST                       =  11;
+const TLV_NOTICE_OF_ABSENCE                  =  12;
+const TLV_P2P_DEVICE_INFO                    =  13;
+const TLV_P2P_GROUP_INFO                     =  14;
+const TLV_P2P_GROUP_ID                       =  15;
+const TLV_P2P_INTERFACE                      =  16;
+const TLV_OPERATING_CHANNEL                  =  17;
+const TLV_INVITATION_FLAGS                   =  18;
+const TLV_P2P_VENDOR_SPECIFIC                = 221;
+
+
+/////////////////////////////////////////////////////////////////////////////
+//                  MBO-OCE Attributes (0, 151-255: Reserved)              //
+/////////////////////////////////////////////////////////////////////////////
+const TLV_MBO_AP_CAP_ATTR                    =   1;
+const TLV_NON_PREFERRED_CHAN_REPORT_ATTR     =   2;
+const TLV_CELLULAR_DATA_CAP_ATTR             =   3;
+const TLV_ASSOC_DISSALLOWED_ATTR             =   4;
+const TLV_CELLULAR_DATA_CON_PREF_ATTR        =   5;
+const TLV_TRANSITION_REASON_CODE_ATTR        =   6;
+const TLV_TRANSITION_REJECT_REASON_CODE_ATTR =   7;
+const TLV_ASSOC_RETRY_DELAY_ATTR             =   8;
+
+// 9-100 : Reserved for MBO //
+
+// OCE ATTRIBUTES //
+const TLV_OCE_CAP_IND_ATTR                   =   101;
+const TLV_RSSI_ASSOC_REJ_ATTR                =   102;
+const TLV_REDUCED_WAN_METRICS_ATTR           =   103;
+// 104-150 : Reserved for OCE
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Fixed Fields
+
+FF AuthAlgo (2)                           // C.f. Sec. 7.3.1.1
+{
+    algo, 2;
+}
+
+FF AuthSeqNo (2)                          // 7.3.1.2
+{
+    no, 2;
+}
+
+FF BeaconInterval (2)                     // 7.3.1.3
+{
+    interval, 2;
+}
+
+FF Capabilities (2)                       // 7.3.1.4
+{
+    {
+        ess:            1;
+        ibss:           1;
+        cfPollable:     1;
+        cfPollReq:      1;
+        privacy:        1;
+        shortPreamble:  1;
+        pbcc:           1;
+        channelAgility: 1;
+        spectrumMgt:    1;
+        qos:            1;
+        shortSlotTime:  1;
+        apsd:           1;
+        rrm:            1;
+        dsssOfdm:       1;
+        delayedBA:      1;
+        immediateBA:    1;
+    }
+}
+
+FF CurrentAPAddress(6)                    // 7.3.1.5
+{
+    mac[6];
+}
+
+FF ListenInterval (2)                     // 7.3.1.6
+{
+    interval, 2;
+}
+
+FF Reason (2)                             // 7.3.1.7
+{
+    code, 2;
+}
+
+FF AID (2)                                // 7.3.1.8
+{
+    associd, 2;
+}
+
+FF Status (2)                             // 7.3.1.9
+{
+    status, 2;
+}
+
+FF TimeStamp (8)                          // 7.3.1.10
+{
+    timestamp, 8;
+}
+
+FF Category (1)                           // 7.3.1.11
+{
+    category, 1;
+}
+
+FF Action (1)                             // 7.3.1.11
+{
+    action, 1;
+}
+
+FF TransactionId (2)                      // 7.3.1.11
+{
+    transId[2];
+}
+
+FF DialogToken (1)                        // 7.3.1.12
+{
+    token, 1;
+}
+
+FF StatusCode (1)                         // WMM Spec 2.2.10
+{
+    statusCode, 1;
+}
+
+FF p2p_action_oui (4)
+{
+    oui_data[4];
+}
+
+FF p2p_action_subtype (1)
+{
+    subtype, 1;
+}
+
+FF OperatingMode (1)
+{
+   {
+    //Operating Mode field
+    chanWidth:    2;
+    reserved:     2;
+    rxNSS:        3;
+    rxNSSType:    1;
+    }
+}
+
+FF SMPowerModeSet (1)				//7.3.1.25
+{
+    {
+        PowerSave_En: 1;
+        Mode: 1;
+        reserved: 6;
+     }
+}
+
+FF TSInfo (3)                             // 7.3.2.30
+{
+    {
+        traffic_type:    1;
+        tsid:            4;
+        direction:       2;
+        access_policy:   2;
+        aggregation:     1;
+        psb:             1;
+        user_priority:   3;
+        tsinfo_ack_pol:  2;
+        schedule:        1;
+        unused:         15;
+    }
+}
+
+FF NumOfRepetitions (2)
+{
+     repetitions, 2;
+}
+
+FF TxPower (1)
+{
+     txPower, 1;
+}
+
+FF MaxTxPower (1)
+{
+     maxTxPower, 1;
+}
+FF TPCEleID (1)
+{
+     TPCId, 1;
+}
+FF TPCEleLen (1)
+{
+     TPCLen, 1;
+}
+FF LinkMargin (1)
+{
+     linkMargin, 1;
+}
+FF RxAntennaId (1)
+{
+     antennaId, 1;
+}
+FF TxAntennaId (1)
+{
+     antennaId, 1;
+}
+FF RCPI (1)
+{
+     rcpi, 1;
+}
+FF RSNI (1)
+{
+     rsni, 1;
+}
+
+FF VhtMembershipStatusArray(8)                    // 8.4.1.51
+{
+    membershipStatusArray[8];
+}
+
+FF VhtUserPositionArray(16)                    // 8.4.1.52
+{
+    userPositionArray[16];
+}
+
+FF ext_chan_switch_ann_action(4)
+{
+   {
+     switch_mode: 8;
+     op_class: 8;
+     new_channel: 8;
+     switch_count: 8;
+   }
+}
+
+FF addba_param_set(2)
+{
+   {
+     amsdu_supp: 1;
+     policy: 1;
+     tid: 4;
+     buff_size: 10;
+   }
+}
+
+FF ba_timeout(2)
+{
+    timeout, 2;
+}
+
+FF ba_start_seq_ctrl(2)
+{
+    {
+      frag_number: 4;
+      ssn: 12;
+    }
+}
+
+IE addba_extn_element(EID_ADDBA_EXTN_ELEMENT)
+{
+    {
+      no_fragmentation: 1;
+      he_frag_operation: 2;
+      reserved: 5;
+    }
+}
+
+FF delba_param_set(2)
+{
+    {
+      reserved: 11;
+      initiator: 1;
+      tid: 4;
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//                                  TLVs                                   //
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * \brief Version
+ *
+ * WPS 1.0h
+ * Version specifies  the Easy  Setup version. The  one-byte field  is broken
+ * into a  four-bit major  part using  the top MSBs  and four-bit  minor part
+ * using the LSBs. As an example, version 3.2 would be 0x32.
+ *
+ * WSC 2.0.0
+ * Deprecated Version mechanism. This attribute is always set to value 0x10
+ * (version 1.0) for backwards compatibility. Version 1.0h of the specification
+ * did not fully describe the version negotiation mechanism and version 2.0
+ * introduced a new subelement (Version2) for indicating the version number
+ * to avoid potential interoperability issues with deployed 1.0h-based devices.
+ *
+ */
+
+TLV Version( TLV_VERSION ) ( 2 : 2 ) MSB
+{
+  {
+      minor: 4;
+      major: 4;
+  }
+}
+
+/// Wi-Fi Protected Setup State
+TLV WPSState( TLV_WI_FI_SIMPLE_CONFIG_STATE ) ( 2 : 2 ) MSB
+{
+  state, 1;
+}
+
+/**
+ * \brief AP Setup Locked
+ *
+ *
+ * This variable indicates that the AP has entered a state in which it will
+ * refuse to allow an external Registrar to attempt to run the Registration
+ * Protocol using the AP?s PIN (with the AP acting as Enrollee). The AP
+ * should enter this state if it believes a brute force attack is underway
+ * against the AP?s PIN.
+ *
+ * When the AP is in this state, it MUST continue to allow other Enrollees to
+ * connect and run the Registration  Protocol with any external Registrars or
+ * the AP's built-in  Registrar (if any). It  is only the use of  the AP' PIN
+ * for adding external Registrars that is disabled in this state.
+ *
+ * The AP Setup Locked state can be reset to FALSE through an authenticated
+ * call to SetAPSettings. APs may provide other implementation-specific
+ * methods of resetting the AP Setup Locked state as well.
+ *
+ *
+ */
+
+TLV APSetupLocked( TLV_AP_SETUP_LOCKED ) ( 2 : 2 ) MSB
+{
+    fLocked, 1;
+}
+
+/**
+ * \brief Selected Registrar Config Methods
+ *
+ *
+ * This attribute has the same values that Config Methods have. It is used in
+ * Probe Response messages to convey the Config Methods of the selected
+ * Registrar.
+ *
+ *
+ */
+
+TLV SelectedRegistrarConfigMethods ( TLV_SELECTED_REGISTRAR_CONFIG_METHODS ) ( 2 : 2 ) MSB
+{
+    methods, 2;
+}
+
+/**
+ * \brief UUID-E
+ *
+ *
+ * The  universally  unique  identifier  (UUID)  element  is  a  unique  GUID
+ * generated by  the Enrollee. It  uniquely identifies an  operational device
+ * and  should survive reboots  and resets.  The UUID  is provided  in binary
+ * format. If the device also supports UPnP, then the UUID corresponds to the
+ * UPnP UUID.
+ *
+ *
+ */
+
+TLV UUID_E ( TLV_UUID_E ) ( 2 : 2 ) MSB
+{
+    uuid[ 16 ];
+}
+
+/**
+ * \brief UUID-R
+ *
+ *
+ * The  universally  unique  identifier  (UUID)  element  is  a  unique  GUID
+ * generated by  the Registrar. It uniquely identifies  an operational device
+ * and  should survive reboots  and resets.  The UUID  is provided  in binary
+ * format. If the device also supports UPnP, then the UUID corresponds to the
+ * UPnP UUID.
+ *
+ *
+ */
+
+TLV UUID_R ( TLV_UUID_R ) ( 2 : 2 ) MSB
+{
+    uuid[ 16 ];
+}
+
+/**
+ * \brief RF Bands
+ *
+ *
+ \code
+
+  0x01 2.4GHz
+  0x02 5.0GHz
+
+ \endcode
+ *
+ *
+ */
+
+TLV RFBands ( TLV_RF_BANDS ) ( 2 : 2 ) MSB
+{
+    bands, 1;
+}
+
+
+/**
+ * \brief Selected Registrar
+ *
+ *
+ * This field indicates that a Registrar has been selected by a user and that
+ * an Enrollee  should proceed  with setting up  an 802.1X  uncontrolled data
+ * port with the Registrar.
+ *
+ *
+ */
+
+TLV SelectedRegistrar ( TLV_SELECTED_REGISTRAR ) ( 2 : 2 ) MSB
+{
+    selected, 1;
+}
+
+/**
+ * \brief Config Methods
+ *
+ *
+ * The  Config Methods  Data component  lists the  configuration  methods the
+ * Enrollee or Registrar  supports.  The list is a bitwise  OR of values from
+ * the table below. In addition to  Config Methods, APs and STAs that support
+ * the UPnP  Management Interface must  support the Permitted  Config Methods
+ * attribute, which is used to control the Config Methods that are enabled on
+ * that AP.
+ *
+ \code
+
+   Value   Hardware Interface
+   0x0001  USBA (Flash Drive)
+   0x0002  Ethernet
+   0x0004  Label
+   0x0008  Display
+   0x0010  External NFC Token
+   0x0020  Integrated NFC Token
+   0x0040  NFC Interface
+   0x0080  PushButton
+   0x0100  Keypad
+
+ \endcode
+ *
+ *
+ */
+
+TLV ConfigMethods ( TLV_CONFIG_METHODS ) ( 2 : 2 ) MSB
+{
+    methods, 2;
+}
+
+/**
+ * \brief Association State
+ *
+ *
+ * The  Association  State component  shows  the  configuration and  previous
+ * association  state  of  the  wireless  station when  sending  a  Discovery
+ * request.
+ *
+ \code
+
+  Association State    Description
+  0                    Not Associated
+  1                    Connection Success
+  2                    Configuration Failure
+  3                    Association Failure
+  4                    IP Failure
+
+ \endcode
+ *
+ *
+ */
+
+TLV AssociationState ( TLV_ASSOCIATION_STATE ) ( 2 : 2 ) MSB
+{
+    state, 2;
+}
+
+/**
+ * \brief Configuration Error
+ *
+ *
+ * The  Configuration  Error  component   shows  the  result  of  the  device
+ * attempting to configure itself and to associate with the WLAN.
+ *
+ \code
+
+   Configuration Error  Description
+    0                   No Error
+    1                   OOB Interface Read Error
+    2                   Decryption CRC Failure
+    3                   2.4 channel not supported
+    4                   5.0 channel not supported
+    5                   Signal too weak
+    6                   Network auth failure
+    7                   Network association failure
+    8                   No DHCP response
+    9                   Failed DHCP config
+   10                   IP address conflict
+   11                   Couldn't connect to Registrar
+   12                   Multiple PBC sessions detected
+   13                   Rogue activity suspected
+   14                   Device busy
+   15                   Setup locked
+   16                   Message Timeout
+   17                   Registration Session Timeout
+   18                   Device Password Auth Failure
+
+ \endcode
+ *
+ * The  Device busy  error is  returned if  the sending  device is  unable to
+ * respond  to  the  request  due  to  some  internal  conflict  or  resource
+ * contention issue. For example, if a device is only capable of performing a
+ * single instance of the Registration Protocol at a time, it may return this
+ * error in response  to attempts to start another instance  in the middle of
+ * an active session.
+ *
+ *
+ */
+
+TLV ConfigurationError ( TLV_CONFIGURATION_ERROR ) ( 2 : 2 ) MSB
+{
+    error, 2;
+}
+
+TLV Manufacturer ( TLV_MANUFACTURER ) ( 2 : 2 ) MSB
+{
+    name[ 0..64 ];
+}
+
+TLV ModelName ( TLV_MODEL_NAME ) ( 2 : 2 ) MSB
+{
+    text[ 0..32 ];
+}
+
+TLV ModelNumber ( TLV_MODEL_NUMBER ) ( 2 : 2 ) MSB
+{
+    text[ 0..32 ];
+}
+
+TLV SerialNumber ( TLV_SERIAL_NUMBER ) ( 2 : 2 ) MSB
+{
+    text[ 0..32 ];
+}
+
+TLV DeviceName ( TLV_DEVICE_NAME ) ( 2 : 2 ) MSB
+{
+    text[ 0..32 ];
+}
+
+/**
+ * \brief Device Password ID
+ *
+ *
+ * This  attribute is  used  to identify  a  device password.  There are  six
+ * predefined values  and ten reserved values.  If the Device  Password ID is
+ * Default,  the Enrollee  should use  its PIN  password (from  the  label or
+ * display).  This  password may  correspond  to  the  label, display,  or  a
+ * user-defined  password that has  been configured  to replace  the original
+ * device password.
+ *
+ * User-specified indicates that the user  has overridden the password with a
+ * manually  selected value.  Machine-specified  indicates that  the original
+ * PIN  password has  been overridden  by a  strong,  machinegenerated device
+ * password  value.  The Rekey  value  indicates  that  the device's  256-bit
+ * rekeying password  will be used.  The PushButton value indicates  that the
+ * PIN  is  the all-zero  value  reserved  for  the PushButton  Configuration
+ * method.
+ *
+ * The Registrar-specified value indicates a  PIN that has been obtained from
+ * the Registrar (via a display  or other out-of-band method). This value may
+ * be further  augmented with the  optional 'Identity' attribute in  M1. This
+ * augmentation is useful when multiple predefined UserID/PIN pairs have been
+ * established  by a  Registrar such  as  an authenticator  used for  Hotspot
+ * access. If the  Device Password ID in  M1 is not one of  the predefined or
+ * reserved values, it corresponds to a password given to the Registrar as an
+ * OOB Device Password.
+ *
+ \code
+
+   Value            Description
+
+   0x0000           Default (PIN)
+   0x0001           User-specified
+   0x0002           Machine-specified
+   0x0003           Rekey
+   0x0004           PushButton
+   0x0005           Registrar-specified
+   0x0006 - 0x000F  Reserved
+
+ \endcode
+ *
+ *
+ */
+
+TLV DevicePasswordID ( TLV_DEVICE_PASSWORD_ID ) ( 2 : 2 ) MSB
+{
+    id, 2;
+}
+
+
+/**
+ * \brief Primary Device Type
+ *
+ *
+ * This attribute contains the primary type of the device. Its format
+ * follows:
+ *
+ \code
+
+   0 1 2 3
+   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | Attribute ID                   | Length                       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | Category ID                    | OUI (1-2)                    |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | OUI (3-4)                      | Sub Category ID              |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ \endcode
+ *
+ * Vendor-specific sub-categories  are designated by  setting the OUI  to the
+ * value associated with  that vendor.  Note that a  four-byte subdivided OUI
+ * is used. For the predefined values, the  Wi-Fi Alliance OUI of 00 50 F2 04
+ * is used.  The predefined values  for Category ID  and Sub Category  ID are
+ * provided in the next table. There  is no way to indicate a vendor-specific
+ * main device  category. The OUI applies  only to the  interpretation of the
+ * Sub Category. If  a vendor does not use sub categories  for their OUI, the
+ * three-byte OUI  occupies the first  three bytes of  the OUI field  and the
+ * fourth byte is set to zero.
+ *
+ *
+ \code
+
+   Category              ID Value  Sub Category             ID Value
+   Computer              1         PC                       1
+                                   Server                   2
+                                   Media Center             3
+   Input Device          2
+   Printers, Scanners,             Printer                  1
+   Faxes and Copiers     3         Scanner                  2
+   Camera                4         Digital Still Camera     1
+   Storage               5         NAS                      1
+   Network                         AP                       1
+   Infrastructure        6         Router                   2
+                                   Switch                   3
+   Displays              7         Television               1
+                                   Electronic Picture Frame 2
+                                   Projector                3
+   Multimedia Devices    8         DAR                      1
+                                   PVR                      2
+                                   MCX                      3
+   Gaming Devices        9         Xbox                     1
+                                   Xbox360                  2
+                                   Playstation              3
+   Telephone             10        Windows Mobile           1
+
+ \endcode
+ *
+ *
+ */
+
+TLV PrimaryDeviceType ( TLV_PRIMARY_DEVICE_TYPE ) ( 2 : 2 ) MSB
+{
+    primary_category, 2;
+    oui[ 4 ];
+    sub_category, 2;
+}
+
+
+/**
+ * \brief Request Type
+ *
+ *
+ * The Request  Type component  specifies the mode  in which the  device will
+ * operate in for  this setup exchange. If the device is  an Enrollee, it may
+ * send only  discovery messages  or it may  also request that  the Registrar
+ * proceed with opening a data  connection. This protocol allows Enrollees to
+ * more efficiently discover devices on the network.
+
+ * If  the device  indicates that  it  intends to  engage setup  either as  a
+ * Registrar or an  Enrollee, the Access Point continues  to indicate that it
+ * will  operate as  an AP  in the  response. The  Request Type  attribute is
+ * carried  throughout the  802.1X data  channel setup  process in  the Wi-Fi
+ * Protected Setup IE.   There are two sub-types of  Registrars: WLAN Manager
+ * Registrar indicates  that this Registrar intends  to manage the  AP or STA
+ * settings using UPnP.  It will derive a UPnP AP or  STA Management key. The
+ * ordinary Registrar type  indicates that this Registrar does  not intend to
+ * subsequently  manage  the Enrollee's  settings.  APs  must  not derive  AP
+ * Management Keys for an ordinary  Registrar. If a Registrar does not intend
+ * to  be  a WLAN  Manager  Registrar,  it should  set  the  Request Type  to
+ * Registrar. Doing so avoids needlessly consuming resources on the AP.
+
+ \code
+
+ Request Type Value        Description
+ 0x00                      Enrollee, Info only
+ 0x01                      Enrollee, open 802.1X
+ 0x02                      Registrar
+ 0x03                      WLAN Manager Registrar
+
+ \endcode
+ *
+ *
+ */
+
+TLV RequestType ( TLV_REQUEST_TYPE ) ( 2 : 2 ) MSB
+{
+    reqType, 1;
+}
+
+/**
+ * \brief Response Type
+ *
+ *
+ * The Response Type component specifies the operational mode of the
+ * device for this setup exchange. The Response Type IE is carried
+ * throughout the 802.1X data channel setup process.
+
+ \code
+
+ Response Type Value       Description
+ 0x00                      Enrollee, Info only
+ 0x01                      Enrollee, open 802.1X
+ 0x02                      Registrar
+ 0x03                      AP
+
+\endcode
+ *
+ *
+ */
+
+TLV ResponseType ( TLV_RESPONSE_TYPE  ) ( 2 : 2 ) MSB
+{
+    resType, 1;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//                       WiFi Direct/P2P TLVs                            //
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ * \brief P2P Status Attribute
+ */
+
+TLV P2PStatus ( TLV_P2P_STATUS ) ( 1 : 2 ) LSB
+{
+    status, 1;
+}
+
+
+/**
+ * \brief Minor Reason Code Attribute
+ */
+
+TLV MinorReasonCode ( TLV_MINOR_REASON_CODE ) ( 1 : 2 ) LSB
+{
+    minorReasonCode, 1;
+}
+
+
+/**
+ * \brief P2P Capability Attribute
+ */
+
+TLV P2PCapability ( TLV_P2P_CAPABILITY ) ( 1 : 2 ) LSB
+{
+    deviceCapability, 1;
+    groupCapability, 1;
+}
+
+
+/**
+ * \brief P2P Device Id Attribute
+ */
+
+TLV P2PDeviceId ( TLV_P2P_DEVICE_ID ) ( 1 : 2 ) LSB
+{
+    P2PDeviceAddress[6];
+}
+
+/**
+ * \brief Listen Channel Attribute
+ */
+
+TLV ListenChannel ( TLV_LISTEN_CHANNEL ) ( 1 : 2 ) LSB
+{
+    countryString[3];
+    regulatoryClass, 1;
+    channel,         1;
+}
+
+/**
+ * \brief Extended Listen Attribute
+ */
+
+TLV ExtendedListenTiming ( TLV_EXTENDED_LISTEN_TIMING ) ( 1 : 2 ) LSB
+{
+    availibilityPeriod, 2;
+    availibilityInterval, 2;
+}
+
+
+/**
+ * \brief P2P Manageability Attribute
+ */
+
+TLV P2PManageability ( TLV_P2P_MANAGEABILITY ) ( 1 : 2 ) LSB
+{
+    manageability, 1;
+}
+
+
+/**
+ * \brief Notice of Absence
+ */
+
+TLV NoticeOfAbsence ( TLV_NOTICE_OF_ABSENCE ) ( 1 : 2 ) LSB
+{
+    index, 1;
+    CTSWindowOppPS, 1;
+    NoADesc[0..36];
+}
+
+/**
+ * \brief P2P Device Info Attribute
+ */
+
+TLV P2PDeviceInfo ( TLV_P2P_DEVICE_INFO ) ( 1 : 2 ) LSB
+{
+    P2PDeviceAddress[6];
+    configMethod, 2 , FLIPBYTEORDER;
+    primaryDeviceType[8];
+    MANDATORYTLV DeviceName;
+}
+
+
+/**
+ * \brief P2P Group Info Attribute
+ */
+
+TLV P2PGroupInfo ( TLV_P2P_GROUP_INFO ) ( 1 : 2 ) LSB
+{
+    P2PClientInfoDesc[0..1024];
+}
+
+
+/**
+ * \brief P2P Interface Attribute
+ */
+
+TLV P2PInterface ( TLV_P2P_INTERFACE ) ( 1 : 2 ) LSB
+{
+    P2PDeviceAddress[6];
+}
+
+
+/**
+ * \brief Operating Channel Attribute
+ */
+
+TLV OperatingChannel ( TLV_OPERATING_CHANNEL ) ( 1 : 2 ) LSB
+{
+    countryString[3];
+    regulatoryClass, 1;
+    channel,         1;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//                       MBO-OCE ATTR TLVs                            //
+///////////////////////////////////////////////////////////////////////////
+
+TLV mbo_ap_cap ( TLV_MBO_AP_CAP_ATTR ) ( 1 : 1 ) LSB
+{
+    mbo_cap_ind, 1;
+}
+
+TLV non_prefferd_chan_rep ( TLV_NON_PREFERRED_CHAN_REPORT_ATTR ) ( 1 : 1 ) LSB
+{
+    oper_class, 1;
+    channel_report[3..254];
+}
+
+TLV cellular_data_cap ( TLV_CELLULAR_DATA_CAP_ATTR ) ( 1 : 1 ) LSB
+{
+    cellular_connectivity, 1;
+}
+
+TLV assoc_disallowed ( TLV_ASSOC_DISSALLOWED_ATTR ) ( 1 : 1 ) LSB
+{
+    reason_code, 1;
+}
+
+TLV cellular_data_con_pref ( TLV_CELLULAR_DATA_CON_PREF_ATTR ) ( 1 : 1 ) LSB
+{
+    cellular_preference, 1;
+}
+
+TLV transition_reason ( TLV_TRANSITION_REASON_CODE_ATTR ) ( 1 : 1 ) LSB
+{
+    transition_reason_code, 1;
+}
+
+TLV transition_reject_reason ( TLV_TRANSITION_REJECT_REASON_CODE_ATTR ) ( 1 : 1 ) LSB
+{
+    transition_reject_code, 1;
+}
+
+TLV assoc_retry_delay ( TLV_ASSOC_RETRY_DELAY_ATTR ) ( 1 : 1 ) LSB
+{
+    delay, 2;
+}
+
+// OCE Attributes //
+
+TLV oce_cap ( TLV_OCE_CAP_IND_ATTR ) ( 1 : 1 ) LSB
+{
+    {
+     oce_release: 3;
+     is_sta_cfon : 1;
+     non_oce_ap_present : 1;
+     reserved: 3;
+    }
+}
+
+TLV rssi_assoc_rej ( TLV_RSSI_ASSOC_REJ_ATTR ) ( 1 : 1 ) LSB
+{
+    delta_rssi, 1;
+    retry_delay, 1;
+}
+
+TLV reduced_wan_metrics ( TLV_REDUCED_WAN_METRICS_ATTR ) ( 1 : 1 ) LSB
+{
+    {
+     downlink_av_cap: 4;
+     uplink_av_cap : 4;
+    }
+}
+
+/**
+ * \brief Vendor Extension
+ *
+ * This variable permits vendor extensions in the Wi-Fi Simple
+ * Configuration TLV framework. The Vendor Extension figure
+ * illustrates the implementation of vendor extensions. Vendor
+ * ID is the SMI network management private enterprise code
+ *
+ * +-----------+----------------------+
+ * | Vendor ID |   Vendor Data        |
+ * +-----------+----------------------+
+ * |<--- 3 --->|<----- 1 - 1021 ----->|
+ *
+ */
+
+TLV VendorExtension ( TLV_VENDOR_EXTENSION ) ( 2 : 2 ) MSB
+{
+    /*
+     * vendorId is the SMI network management private enterprise code.
+     * WFA Vendor ID 0x00372A
+     *
+     */
+    vendorId[ 3 ];
+
+    /**
+     * \breif Version2
+     *
+     * The Version2 field specifies the version Wi-Fi Simple
+     * Configuration implemented by the device sending this attribute.
+     * The one-byte field is broken into a four-bit major part using
+     * the top MSBs and four-bit minor part using the LSBs. As an example,
+     * version 3.2 would be 0x32. This subelement was added in the
+     * specification version 2.0 and if the subelement is not included
+     * in a message, the transmitter of the message is assumed to
+     * use version 1.0.
+     *
+     */
+    OPTIONALTLV TLV Version2 ( TLV_VERSION2 )  ( 1 : 1 ) MSB
+    {
+      {
+          minor: 4;
+          major: 4;
+      }
+    }
+    /**
+     * \brief AuthorizedMACs
+     *
+     * This subelement contains a list of Enrollee MAC addresses (each
+     * being six bytes in length) that have been registered to start WSC.
+     * The AP includes this field in Beacon and Probe Response frames so
+     * Enrollees can tell if they have been registered to start WSC. There
+     * may be multiple Enrollees active on the network, but not all of them have
+     * been registered to start WSC. This element allows an Enrollee to detect
+     * if they should start WSC with the AP. The AuthorizedMACs field augments
+     * the use of the Selected Registrar.
+    *
+     */
+    OPTIONALTLV TLV AuthorizedMACs ( TLV_AUTHORIZED_MAC ) ( 1 : 1 ) MSB
+    {
+        mac[6];
+    }
+
+    /**
+     * \brief Request to Enroll
+     *
+     * This optional subelement in the WSC IE in Probe Request or M1 indicates
+     * the desire to enroll in the network by setting its value to TRUE. If the
+     * Registrar gets this subelement it can use this as a trigger that a device
+     * wants to enroll (maybe an indication can be shown to the user). The device
+     * must set it to FALSE after the registration protocol completion.
+     *
+     */
+    OPTIONALTLV TLV RequestToEnroll( TLV_REQUEST_TO_ENROLL ) ( 1 : 1 ) MSB
+    {
+        req, 1;
+    }
+}
+
+/**
+ * \brief Requested Device Type
+ *
+ * This attribute contains the requested device type of a Wi-Fi
+ * Direct device.
+ *
+ * This attribute allows a device to specify the Primary Device Type
+ * or the Secondary Device Type of other devices it is interested in.
+ * Only a device that receives a Probe Request containing a WSC IE with
+ * this attribute and with a Primary Device Type or Secondary Device Type
+ * that matches the Requested Device Type will respond with a Probe Response.
+ *
+ * Its format and contents is identical to the 'Primary Device Type'.
+ *
+ * Both the Category ID and Sub Category ID can be used as a filter. If only
+ * looking for devices with a certain Category ID, the OUI and Sub Category ID
+ * fields will have to be set to zero.
+ *
+ */
+TLV RequestDeviceType ( TLV_REQUESTED_DEVICE_TYPE ) ( 2 : 2 ) MSB
+{
+    primary_category, 2;
+    oui[ 4 ];
+    sub_category, 2;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Information Elements
+
+IE SSID (EID_SSID)                        // C.f. Sec. 7.3.2.1
+{
+    ssid[0..32];
+}
+
+IE SuppRates (EID_SUPP_RATES)             // 7.3.2.2
+{
+    rates[0..SIR_MAC_MAX_NUMBER_OF_RATES];
+}
+
+IE FHParamSet (EID_FH_PARAM_SET)          // 7.3.2.3
+{
+    dwell_time,  2;
+    hop_set,     1;
+    hop_pattern, 1;
+    hop_index,   1;
+}
+
+IE DSParams (EID_DS_PARAM_SET)            // 7.3.2.4
+{
+    curr_channel, 1;
+}
+
+IE CFParams (EID_CF_PARAM_SET)            // 7.3.2.5
+{
+    cfp_count,        1;
+    cfp_period,       1;
+    cfp_maxduration,  2;
+    cfp_durremaining, 2;
+}
+
+IE TIM (EID_TIM)                          // 7.3.2.6
+{
+    dtim_count,    1;
+    dtim_period,   1;
+    bmpctl,        1;
+    vbmp[1..251];
+}
+
+IE IBSSParams (EID_IBSS_PARAM_SET)        // 7.3.2.7
+{
+    atim, 2;
+}
+
+IE ChallengeText (EID_CHALLENGE_TEXT)     // 7.3.2.8
+{
+    text[1..253];
+}
+
+IE RequestedInfo (EID_REQUEST)            // 7.3.2.12
+{
+    requested_eids[0..255];
+}
+
+IE Country (EID_COUNTRY)                  // 7.3.2.9
+{
+    country[3];
+    OPTIONAL triplets[3][0..84];
+}
+
+IE FHParams (EID_FH_PATTERN)              // 7.3.2.10
+{
+    radix, 1;
+    nchannels, 1;
+}
+
+IE FHPattTable (EID_FH_PATT_TABLE)        // 7.3.2.11
+{
+    flag,    1;
+    nsets,   1;
+    modulus, 1;
+    offset,  1;
+    randtable[0..251];
+}
+
+IE ERPInfo (EID_ERP_INFO)                 // 7.3.2.13
+{
+    {
+        non_erp_present : 1;
+        use_prot:         1;
+        barker_preamble:  1;
+        unused:           5;
+    }
+}
+
+IE ExtSuppRates (EID_EXT_SUPP_RATES)      // 7.3.2.14
+{
+    rates[1..SIR_MAC_MAX_NUMBER_OF_RATES];
+}
+
+IE PowerConstraints (EID_POWER_CONSTRAINTS) // 7.3.2.15
+{
+    localPowerConstraints, 1;
+}
+
+IE PowerCaps (EID_POWER_CAPABILITY)       // 7.3.2.16
+{
+    minTxPower, 1;
+    maxTxPower, 1;
+}
+
+IE TPCRequest (EID_TPC_REQUEST)           // 7.3.2.17
+{ }
+
+IE TPCReport (EID_TPC_REPORT)             // 7.3.2.18
+{
+    tx_power,    1;
+    link_margin, 1;
+}
+
+IE SuppChannels (EID_SUPPORTED_CHANNELS)  // 7.2.3.19
+{
+    bands[2][0..48];
+}
+
+IE SuppOperatingClasses (EID_SUPPORTED_OPER_CLASSES)
+{
+    classes[1..32];
+}
+
+IE ChanSwitchAnn (EID_CHANNEL_SWITCH_ANN) // 7.3.2.20
+{
+    switchMode,  1;
+    newChannel,  1;
+    switchCount, 1;
+}
+
+IE ext_chan_switch_ann (EID_EXT_CHAN_SWITCH) // 8.4.2.55
+{
+    switch_mode,   1;
+    new_reg_class, 1;
+    new_channel,   1;
+    switch_count,  1;
+}
+
+IE sec_chan_offset_ele (EID_SEC_CHAN_OFFSET) // 7.3.2.20a
+{
+	secondaryChannelOffset, 1;
+}
+
+IE Quiet (EID_QUIET)                      // 7.3.2.23
+{
+    count,    1;
+    period,   1;
+    duration, 2;
+    offset,   2;
+}
+
+IE RSN (EID_RSN)                          // 7.3.2.25
+{
+    // The version is 2 octets, and we only support version 1.
+    version, 2 MUSTBE 1;
+    // The next four octets will be the Optional Group Cipher Suite
+    OPTIONAL gp_cipher_suite[4];
+    // The IE *may* stop here; if there's any more, we should see two more
+    // octets giving the number of Pairwise Cipher Suites
+    OPTIONAL pwise_cipher_suite_count, 2;
+    // I don't see anything in the Standard limiting the number of Pairwise
+    // Cypher Suites, other than the maximum length of an IE, which limits us
+    // to 61.  However, that seems needlessly wasteful of space.
+    pwise_cipher_suites[4][0..6] COUNTIS pwise_cipher_suite_count;
+    // Optional count of AKM suite selectors
+    OPTIONAL akm_suite_cnt, 2;
+    // Again, I see nothing in the Standard explicitly limiting the number of
+    // AKM suite selectors other than the maximum size of an IE.
+    akm_suite[4][0..6] COUNTIS akm_suite_cnt;
+    OPTIONAL RSN_Cap[2];
+    // Finally, the IE may contain zero or more PMKIDs:
+    OPTIONAL pmkid_count, 2;
+    pmkid[16][0..4] COUNTIS pmkid_count;
+    OPTIONAL gp_mgmt_cipher_suite[4];
+}
+
+IE RSNOpaque (EID_RSN)                    // 7.3.2.25
+{
+    data[ 0..253 ];
+}
+
+IE WAPI (EID_WAPI)                          // 7.3.2.25
+{
+    // The version is 2 octets, and we only support version 1.
+    version, 2 MUSTBE 1;
+    // count of AKM suite selectors
+    akm_suite_count, 2;
+    // Again, I see nothing in the Standard explicitly limiting the number of
+    // AKM suite selectors other than the maximum size of an IE.
+    akm_suites[4][0..4] COUNTIS akm_suite_count;
+    // we should see two more
+    // octets giving the number of Unicast Cipher Suites
+    unicast_cipher_suite_count, 2;
+    // I don't see anything in the Standard limiting the number of Pairwise
+    // Cypher Suites, other than the maximum length of an IE, which limits us
+    // to 61.  However, that seems needlessly wasteful of space.
+    unicast_cipher_suites[4][0..4] COUNTIS unicast_cipher_suite_count;
+    // The next four octets will be the Multicast Cipher Suite
+    multicast_cipher_suite[4];
+    // WAPI capabilities
+    {
+        preauth:               1;
+        reserved:             15;
+    }
+    // Finally, the IE may contain zero or more BKIDs:
+    OPTIONAL bkid_count, 2;
+    bkid[16][0..4] COUNTIS bkid_count;
+}
+
+IE WAPIOpaque (EID_WAPI)                    // 7.3.2.25
+{
+    data[ 6..253 ];
+}
+
+IE QBSSLoad (EID_QBSS_LOAD)               // 7.3.2.28
+{
+    stacount, 2;
+    chautil,  1;
+    avail,    2;
+}
+
+IE EDCAParamSet (EID_EDCA_PARAM_SET)      // 7.3.2.29
+{
+    qos, 1;                     // ToDo: This is a bitfield whose format
+                                // depends on whether this is from an AP
+                                // or a STA, information which I'm not
+                                // sure we have at parse time...
+    reserved, 1;
+    {
+        acbe_aifsn: 4;
+        acbe_acm:   1;
+        acbe_aci:   2;
+        unused1:    1;
+    }
+    {
+        acbe_acwmin: 4;
+        acbe_acwmax: 4;
+    }
+    acbe_txoplimit, 2;
+    {
+        acbk_aifsn: 4;
+        acbk_acm:   1;
+        acbk_aci:   2;
+        unused2:    1;
+    }
+    {
+        acbk_acwmin: 4;
+        acbk_acwmax: 4;
+    }
+    acbk_txoplimit, 2;
+    {
+        acvi_aifsn: 4;
+        acvi_acm:   1;
+        acvi_aci:   2;
+        unused3:    1;
+    }
+    {
+        acvi_acwmin: 4;
+        acvi_acwmax: 4;
+    }
+    acvi_txoplimit, 2;
+    {
+        acvo_aifsn: 4;
+        acvo_acm:   1;
+        acvo_aci:   2;
+        unused4:    1;
+    }
+    {
+        acvo_acwmin: 4;
+        acvo_acwmax: 4;
+    }
+    acvo_txoplimit, 2;
+}
+
+IE TSPEC (EID_TSPEC)                             // 7.3.2.30
+{
+
+    // TS Info
+    {
+        traffic_type:    1;
+        tsid:            4;
+        direction:       2;
+        access_policy:   2;
+        aggregation:     1;
+        psb:             1;
+        user_priority:   3;
+        tsinfo_ack_pol:  2;
+    }
+    {
+        schedule:        1;
+        unused:          7;
+    }
+
+    // Nominal MSDU Size
+    {
+        size:  15;
+        fixed: 1;
+    }
+
+    max_msdu_size,        2;
+    min_service_int,      4;
+    max_service_int,      4;
+    inactivity_int,       4;
+    suspension_int,       4;
+    service_start_time,   4;
+    min_data_rate,        4;
+    mean_data_rate,       4;
+    peak_data_rate,       4;
+    burst_size,           4;
+    delay_bound,          4;
+    min_phy_rate,         4;
+    surplus_bw_allowance, 2;
+    medium_time,          2;
+
+} // End IE TSPEC.
+
+IE TCLAS (EID_TCLAS)                             // 7.3.2.31
+{
+    user_priority, 1;
+    classifier_type, 1;
+    classifier_mask, 1;
+    UNION info (DISCRIMINATOR classifier_type)
+    {
+        EthParams (classifier_type IS 0)
+        {
+            source[6];
+            dest[6];
+            type, 2;
+        }
+        IpParams (classifier_type IS 1)
+        {
+            version, 1;
+            UNION params (DISCRIMINATOR version)
+            {
+                IpV4Params (version IS 4)
+                {
+                    source[4];
+                    dest[4];
+                    src_port, 2;
+                    dest_port, 2;
+                    DSCP, 1;
+                    proto, 1;
+                    reserved, 1;
+                }
+                IpV6Params (version IS 6)
+                {
+                    source[16];
+                    dest[16];
+                    src_port, 2;
+                    dest_port, 2;
+                    flow_label[3];
+                }
+            };
+        }
+        Params8021dq (classifier_type IS 2)
+        {
+            tag_type, 2;
+        }
+    };
+} // End IE TCLASS
+
+const EID_BCN_REPORT_FRAME_BODY    = 1;
+IE BeaconReportFrmBody (EID_BCN_REPORT_FRAME_BODY)
+{
+     reportedFields[0..224];
+}
+
+const EID_BCN_REPORT_FRAME_BODY_FRAGMENT_ID = 2;
+IE beacon_report_frm_body_fragment_id (EID_BCN_REPORT_FRAME_BODY_FRAGMENT_ID)
+{
+    // Data
+    {
+        beacon_report_id:    8;
+        fragment_id_number:  7;
+        more_fragments:      1;
+    }
+}
+
+const EID_BCN_REPORT_LAST_BEACON_REPORT_INDICATION = 164;
+IE last_beacon_report_indication (EID_BCN_REPORT_LAST_BEACON_REPORT_INDICATION)
+{
+    last_fragment, 1;
+}
+
+IE MeasurementReport (EID_MEAS_REPORT)    // 7.3.2.22
+{
+    token, 1;
+    // Measurement Report Mode
+    {
+        late:      1;
+        incapable: 1;
+        refused:   1;
+        unused:    5;
+    }
+    type, 1;
+    OPTIONAL UNION report (DISCRIMINATOR type)
+    {
+        Basic (type IS 0)                 // 7.3.2.22.1
+        {
+            channel,         1;
+            meas_start_time, 8;
+            meas_duration,   2;
+            // Map
+            {
+                bss:           1;
+                ofdm_preamble: 1;
+                unid_signal:   1;
+                rader:         1;
+                unmeasured:    1;
+                unused:        3;
+            }
+        }
+        CCA (type IS 1)
+        {
+            channel,           1;
+            meas_start_time,   8;
+            meas_duration,     2;
+            cca_busy_fraction, 1;
+        }
+        RPIHistogram (type IS 2)
+        {
+            channel,         1;
+            meas_start_time, 8;
+            meas_duration,   2;
+            rpi0_density,    1;
+            rpi1_density,    1;
+            rpi2_density,    1;
+            rpi3_density,    1;
+            rpi4_density,    1;
+            rpi5_density,    1;
+            rpi6_density,    1;
+            rpi7_density,    1;
+        }
+       Beacon (type IS 5)
+       {
+           regClass,               1;
+           channel,                1;
+           meas_start_time,        8;
+           meas_duration,          2;
+           // reported_frame_info,
+           {
+              condensed_PHY:        7;
+              reported_frame_type: 1;
+           }
+           RCPI,                   1;
+           RSNI,                   1;
+           BSSID[6];
+           antenna_id,               1;
+           parent_TSF,              4;
+           OPTIE BeaconReportFrmBody;
+           OPTIE beacon_report_frm_body_fragment_id;
+           OPTIE last_beacon_report_indication;
+           //IE vendor_specific
+     }
+    };
+}
+
+IE TSDelay (EID_TS_DELAY)                 // 7.3.2.32
+{
+    delay, 4;
+}
+
+IE TCLASSPROC (EID_TCLASS_PROC)           // 7.3.2.33
+{
+    processing, 1;
+}
+
+IE Schedule (EID_SCHEDULE)                // 7.3.2.34
+{
+    {
+        aggregation: 1;
+        tsid:        4;
+        direction:   2;
+        reserved:    9;
+    }
+    service_start_time, 4;
+    service_interval,   4;
+    max_service_dur,    2;
+    spec_interval,      2;
+}
+
+IE QOSCapsAp (EID_QOS_CAPABILITY)           // 7.3.2.35
+{
+    {
+        count:   4;
+        qack:    1;
+        qreq:    1;
+        txopreq: 1;
+        reserved: 1;
+    }
+}
+
+IE QOSCapsStation (EID_QOS_CAPABILITY)           // 7.3.2.35
+{
+    {
+        acvo_uapsd:    1;
+        acvi_uapsd:    1;
+        acbk_uapsd:    1;
+        acbe_uapsd:    1;
+        qack:          1;
+        max_sp_length: 2;
+        more_data_ack: 1;
+    }
+}
+
+IE LinkIdentifier (EID_LINK_IDENTIFIER)          // 7.3.2.62
+{
+    bssid[6];
+    InitStaAddr[6];
+    RespStaAddr[6];
+}
+
+IE WPA (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x01)
+{
+    // This IE's first two octets should be interpreted as a version number;
+    // we only support version 1.
+    version, 2 MUSTBE 1;
+    // A four-octet Multicast Cipher may or may not appear next (hence the
+    // OPTIONAL keyword)
+    OPTIONAL multicast_cipher[4];
+    // Optional Unicast Cipher count
+    OPTIONAL unicast_cipher_count, 2;
+    // Next comes an array of four-octet Cipher Suite selectors; the COUNTIS
+    // clause indicates that the actual number of selectors seen is in the
+    // member 'unicast_cipher_count'.
+    unicast_ciphers[4][0..4] COUNTIS unicast_cipher_count;
+    // (Optional) Authentication suites:
+    OPTIONAL auth_suite_count, 2;
+    auth_suites[4][0..4] COUNTIS auth_suite_count;
+    // This field is declared optional as per bugs 15234, 14755, & 14991.
+    OPTIONAL caps, 2;
+}
+
+IE WPAOpaque (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x01)
+{
+    data[ 2..249 ];
+}
+
+IE WMMInfoStation (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x00)
+{
+    // This IE contains the QoS Info field when sent from WMM Station
+    version, 1;
+    {
+        acvo_uapsd:    1;
+        acvi_uapsd:    1;
+        acbk_uapsd:    1;
+        acbe_uapsd:    1;
+        reserved1:     1;
+        max_sp_length: 2;
+        reserved2:     1;
+    }
+}
+
+IE WMMInfoAp (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x00)
+{
+    // This IE contains the QoS Info field when sent from WMM AP
+    version, 1;
+    {
+        param_set_count: 4;
+        reserved:        3;
+        uapsd:           1;
+    }
+}
+
+
+IE WMMParams (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x01)
+{
+    version, 1 MUSTBE 1;
+    qosInfo, 1;                           // ToDo: This is actually a
+                                          // bitfield, but it's format
+                                          // varies depending on whether
+                                          // the sender is a STA or AP...
+    reserved2, 1;
+    {
+        acbe_aifsn: 4;
+        acbe_acm: 1;
+        acbe_aci: 2;
+        unused1: 1;
+    }
+    {
+        acbe_acwmin: 4;
+        acbe_acwmax: 4;
+    }
+    acbe_txoplimit, 2;
+    {
+        acbk_aifsn: 4;
+        acbk_acm: 1;
+        acbk_aci: 2;
+        unused2: 1;
+    }
+    {
+        acbk_acwmin: 4;
+        acbk_acwmax: 4;
+    }
+    acbk_txoplimit, 2;
+    {
+        acvi_aifsn: 4;
+        acvi_acm: 1;
+        acvi_aci: 2;
+        unused3: 1;
+    }
+    {
+        acvi_acwmin: 4;
+        acvi_acwmax: 4;
+    }
+    acvi_txoplimit, 2;
+    {
+        acvo_aifsn: 4;
+        acvo_acm: 1;
+        acvo_aci: 2;
+        unused4: 1;
+    }
+    {
+        acvo_acwmin: 4;
+        acvo_acwmax: 4;
+    }
+    acvo_txoplimit, 2;
+}
+
+IE WMMTSPEC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xf2, 0x02, 0x02)
+{
+    version, 1 MUSTBE 1;
+
+    // TS Info
+    {
+        traffic_type:    1;
+        tsid:            4;
+        direction:       2;
+        access_policy:   2;
+        aggregation:     1;
+        psb:             1;
+        user_priority:   3;
+        tsinfo_ack_pol:  2;
+    }
+    {
+       tsinfo_rsvd:      7;
+       burst_size_defn:  1;
+    }
+
+    // Nominal MSDU Size
+    {
+        size:  15;
+        fixed: 1;
+    }
+
+    max_msdu_size,        2;
+    min_service_int,      4;
+    max_service_int,      4;
+    inactivity_int,       4;
+    suspension_int,       4;
+    service_start_time,   4;
+    min_data_rate,        4;
+    mean_data_rate,       4;
+    peak_data_rate,       4;
+    burst_size,           4;
+    delay_bound,          4;
+    min_phy_rate,         4;
+    surplus_bw_allowance, 2;
+    medium_time,          2;
+
+} // End IE WMMTSpec.
+
+IE WMMCaps (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x05)
+{
+    version, 1 MUSTBE 1;
+    {
+        reserved:      4;
+        qack:          1;
+        queue_request: 1;
+        txop_request:  1;
+        more_ack:      1;
+    }
+}
+
+IE WMMTCLAS (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x06)
+{
+    version, 1 MUSTBE 1;
+
+    user_priority, 1;
+    classifier_type, 1;
+    classifier_mask, 1;
+    UNION info (DISCRIMINATOR classifier_type)
+    {
+        EthParams (classifier_type IS 0)
+        {
+            source[6];
+            dest[6];
+            type, 2;
+        }
+        IpParams (classifier_type IS 1)
+        {
+            version, 1;
+            UNION params (DISCRIMINATOR version)
+            {
+                IpV4Params (version IS 4)
+                {
+                    source[4];
+                    dest[4];
+                    src_port, 2;
+                    dest_port, 2;
+                    DSCP, 1;
+                    proto, 1;
+                    reserved, 1;
+                }
+                IpV6Params (version IS 6)
+                {
+                    source[16];
+                    dest[16];
+                    src_port, 2;
+                    dest_port, 2;
+                    flow_label[3];
+                }
+            };
+        }
+        Params8021dq (classifier_type IS 2)
+        {
+            tag_type, 2;
+        }
+    };
+
+}
+
+IE WMMTCLASPROC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x07)
+{
+    version, 1 MUSTBE 1;
+    processing, 1;
+}
+
+IE WMMTSDelay (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x08)
+{
+    version, 1 MUSTBE 1;
+    delay, 4;
+}
+
+IE WMMSchedule (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x09)
+{
+    version, 1 MUSTBE 1;
+
+    {
+        aggregation: 1;
+        tsid:        4;
+        direction:   2;
+        reserved:    9;
+    }
+
+    service_start_time, 4;
+    service_interval,   4;
+    max_service_dur,    2;
+    spec_interval,      2;
+}
+
+IE ESERadMgmtCap (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x01)
+{
+
+    mgmt_state,  1;
+
+    {
+        mbssid_mask:    3;
+        reserved:       5;
+    }
+
+}
+
+IE Vendor1IE (EID_VENDOR_SPECIFIC) OUI (0x00, 0x10, 0x18)
+{
+}
+
+IE Vendor3IE (EID_VENDOR_SPECIFIC) OUI (0x00, 0x16, 0x32)
+{
+}
+
+IE hs20vendor_ie (EID_VENDOR_SPECIFIC) OUI (0x50, 0x6F, 0x9A, 0x10)
+{
+    /* hotspot_configurations */
+    {
+        dgaf_dis:               1;
+        hs_id_present:          2;
+        reserved:               1;
+        release_num:            4;
+    }
+    OPTIONAL UNION hs_id (DISCRIMINATOR hs_id_present)
+    {
+        pps_mo (hs_id_present IS 1)
+        {
+            pps_mo_id,          2;
+        }
+        anqp_domain (hs_id_present IS 2)
+        {
+            anqp_domain_id,     2;
+        }
+    };
+}
+
+IE osen_ie (EID_VENDOR_SPECIFIC) OUI (0x50, 0x6F, 0x9A, 0x12)
+{
+    data[0..255];
+}
+
+IE QComVendorIE (EID_VENDOR_SPECIFIC) OUI (0x00, 0xA0, 0xC6)
+{
+    type,      1;
+    channel,   1;
+}
+
+IE ESETrafStrmMet (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x07)
+{
+    tsid,           1;
+    state,          1;
+    msmt_interval,  2;
+}
+
+IE ESETrafStrmRateSet (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x08)
+{
+    tsid,         1;
+    tsrates[0..8];
+}
+
+IE ESEVersion (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x03)
+{
+    version,           1;
+}
+
+IE ESETxmitPower (EID_ESE_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x00)
+{
+    power_limit,    1;
+    reserved,       1;
+}
+
+IE ESECckmOpaque (EID_ESE_CCKM_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x00)
+{
+    data[ 6..20 ];
+}
+
+IE RRMEnabledCap (EID_RRM_ENABLED_CAPS)
+{
+     //Capability bitmap
+     {
+          LinkMeasurement:         1;
+          NeighborRpt:             1;
+          parallel:                1;
+          repeated:                1;
+          BeaconPassive:           1;
+          BeaconActive:            1;
+          BeaconTable:             1;
+          BeaconRepCond:           1;
+     }
+     {
+          FrameMeasurement:        1;
+          ChannelLoad:             1;
+          NoiseHistogram:          1;
+          statistics:              1;
+          LCIMeasurement:          1;
+          LCIAzimuth:              1;
+          TCMCapability:           1;
+          triggeredTCM:            1;
+     }
+     {
+          APChanReport:            1;
+          RRMMIBEnabled:           1;
+          operatingChanMax:        3;
+          nonOperatinChanMax:      3;
+     }
+     {
+          MeasurementPilot:        3;
+          MeasurementPilotEnabled: 1;
+          NeighborTSFOffset:       1;
+          RCPIMeasurement:         1;
+          RSNIMeasurement:         1;
+          BssAvgAccessDelay:       1;
+     }
+     {
+          BSSAvailAdmission:       1;
+          AntennaInformation:      1;
+          fine_time_meas_rpt:      1;
+          lci_capability:          1;
+          reserved:                4;
+     }
+}
+
+IE MeasurementPilot (EID_RRM_MEAS_PILOT_TX_INFO)
+{
+     measurementPilot, 1;
+     vendorSpecific[0..255]; //Should be an IE. But currently only one level of nesting allowed. Can ignore for now.
+}
+
+IE MultiBssid (EID_MULTIPLE_BSSID)
+{
+     maxBSSIDIndicator, 1;
+     vendorSpecific[0..255];
+}
+
+IE OBSSScanParameters (EID_OBSS_SCAN_PARAMETERS)
+{
+    obssScanPassiveDwell, 2;
+	obssScanActiveDwell, 2;
+	bssChannelWidthTriggerScanInterval, 2;
+	obssScanPassiveTotalPerChannel, 2;
+	obssScanActiveTotalPerChannel, 2;
+	bssWidthChannelTransitionDelayFactor, 2;
+    obssScanActivityThreshold, 2;
+}
+
+IE ht2040_bss_coexistence (EID_20_40_BSS_COEXISTENCE)
+{
+     // 20/40 BSS Coexistence Information
+    {
+        info_request:               1;
+        forty_mhz_intolerant:       1;
+        twenty_mhz_bsswidth_req:    1;
+        obss_scan_exemption_req:    1;
+        obss_scan_exemption_grant:  1;
+        unused:                     3;
+    }
+}
+
+IE ht2040_bss_intolerant_report (EID_20_40_BSS_INTOLERANT_REPORT)
+{
+     operating_class, 1;
+     channel_list[0..50];
+}
+
+const EID_RRM_NBR_RPT_TSF              =    1;
+const EID_RRM_NBR_CD_COUNTRY           =    2;
+
+IE TSFInfo (EID_RRM_NBR_RPT_TSF)
+{
+     TsfOffset, 2;
+     BeaconIntvl, 2;
+}
+IE CondensedCountryStr (EID_RRM_NBR_CD_COUNTRY)
+{
+     countryStr[2];
+}
+
+IE NeighborReport (EID_NEIGHBOR_REPORT)
+{
+     bssid[6];
+     //Bssid Info
+     {
+          APReachability: 2;
+          Security:       1;
+          KeyScope:       1;
+          //Capabilities
+          SpecMgmtCap:    1;
+          QosCap:         1;
+          apsd:           1;
+          rrm:            1;
+     }
+     //Capabilities contd.
+     {
+          DelayedBA:      1;
+          ImmBA:          1;
+     //Capabilities end.
+          MobilityDomain: 1;
+          reserved:       5;
+     }
+
+          reserved1,      2; //part of BSSID Info.
+
+     regulatoryClass, 1;
+     channel,         1;
+     PhyType,         1;
+     OPTIE IE TSFInfo;
+     OPTIE IE CondensedCountryStr;
+     OPTIE IE MeasurementPilot;
+     OPTIE IE RRMEnabledCap;
+     OPTIE IE MultiBssid;
+     //Ignoring vendor specific.
+}
+
+IE RCPIIE (EID_RCPI)
+{
+     rcpi, 1;
+}
+
+IE RSNIIE (EID_RSNI)
+{
+     rsni, 1;
+}
+
+IE WFATPC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x08, 0x00)
+{
+     txPower, 1;
+     linkMargin, 1;
+}
+
+IE MobilityDomain (EID_FT_MOBILITY_DOMAIN)
+{
+   MDID, 2;
+   //FT Capability and policy
+   {
+      overDSCap:         1;
+      resourceReqCap:    1;
+      reserved:          6;
+   }
+}
+const SUB_EID_FT_R1KH_ID = 1;
+const SUB_EID_FT_GTK     = 2;
+const SUB_EID_FT_R0KH_ID = 3;
+const SUB_EID_FT_IGTK    = 4;
+IE FTInfo (EID_FT_INFO)
+{
+   // MicControl, 2;
+   {
+      reserved: 8;
+      IECount:  8;
+   }
+   MIC[16];
+   Anonce[32];
+   Snonce[32];
+
+   OPTIE IE R1KH_ID (SUB_EID_FT_R1KH_ID)
+   {
+      PMK_R1_ID[6];
+   }
+
+   OPTIE IE GTK (SUB_EID_FT_GTK)
+   {
+      //Key Info
+      {
+         keyId: 2;
+         reserved: 14;
+      }
+      keyLength, 1;
+      RSC[8];
+      key[5..32];
+   }
+
+   OPTIE IE R0KH_ID (SUB_EID_FT_R0KH_ID)
+   {
+      PMK_R0_ID[1..48];
+   }
+
+   OPTIE IE IGTK (SUB_EID_FT_IGTK)
+   {
+      //Key Info
+      keyID[2];
+      IPN[6];
+      keyLength, 1;
+      key[24];
+   }
+}
+
+IE TimeoutInterval (EID_TIMEOUT_INTERVAL)
+{
+   timeoutType, 1;
+   timeoutValue, 4;
+}
+
+//TODO: need to define this properly.
+IE RICData (EID_FT_RIC_DATA)
+{
+   Identifier, 1;
+   resourceDescCount, 1;
+   statusCode, 2;
+}
+
+IE RICDescriptor (EID_FT_RIC_DESCRIPTOR)
+{
+   resourceType, 1;
+   variableData[0..255]; //Block ack param set...TODO:
+}
+
+IE WscIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x00, 0x50, 0xF2, 0x04 )
+{
+    data[ 2..249 ];
+}
+
+IE P2PIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x50, 0x6F, 0x9A, 0x09 )
+{
+    data[ 2..249 ];
+}
+
+IE WFDIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x50, 0x6F, 0x9A, 0x0A )
+{
+    data[ 2..249 ];
+}
+
+IE PTIControl (EID_PTI_CONTROL)                 // 7.3.2.65
+{
+    tid,                  1;
+    sequence_control,     2;
+}
+
+IE PUBufferStatus (EID_PU_BUFFER_STATUS)        // 7.3.2.66
+{
+    {
+        ac_bk_traffic_aval:          1;
+        ac_be_traffic_aval:          1;
+        ac_vi_traffic_aval:          1;
+        ac_vo_traffic_aval:          1;
+        reserved:    4;
+    }
+}
+
+
+
+IE VHTCaps (EID_VHT_CAPABILITIES)
+{
+    //VHT Capability Info
+    {
+        maxMPDULen:               2;
+        supportedChannelWidthSet: 2;
+        ldpcCodingCap:            1;
+        shortGI80MHz:             1;
+        shortGI160and80plus80MHz: 1;
+        txSTBC:                   1;
+        rxSTBC:                   3;
+        suBeamFormerCap:          1;
+        suBeamformeeCap:          1;
+        csnofBeamformerAntSup:    3;
+        numSoundingDim:           3;
+        muBeamformerCap:          1;
+        muBeamformeeCap:          1;
+        vhtTXOPPS:                1;
+        htcVHTCap:                1;
+        maxAMPDULenExp:           3;
+        vhtLinkAdaptCap:          2;
+        rxAntPattern:             1;
+        txAntPattern:             1;
+        reserved1:                2;
+    }
+    rxMCSMap,                     2;
+    {
+         rxHighSupDataRate:       13;
+         reserved2:               3;
+    }
+    txMCSMap,                     2;
+    {
+        txSupDataRate:            13;
+        reserved3:                3;
+    }
+}
+
+IE VHTOperation (EID_VHT_OPERATION_ELEMENT)
+{
+    chanWidth,           1;
+    chanCenterFreqSeg1,  1;
+    chanCenterFreqSeg2,  1;
+    basicMCSSet,         2;
+}
+
+IE VHTExtBssLoad (EID_VHT_EXT_BSS_LOAD)
+{
+    muMIMOCapStaCount,    1;
+    ssUnderUtil,          1;
+    FortyMHzUtil,         1;
+    EightyMHzUtil,        1;
+    OneSixtyMHzUtil,      1;
+}
+
+IE AID (EID_AID)
+{
+    assocId,              2;
+}
+
+IE WiderBWChanSwitchAnn (EID_WIDER_BW_CHANNEL_SWITCH_ANN)
+{
+   newChanWidth,          1;
+   newCenterChanFreq0,    1;
+   newCenterChanFreq1,    1;
+}
+
+IE vht_transmit_power_env (VHT_TRANSMIT_POWER_ENVELOPE)
+{
+    bytes[2..5];
+}
+
+IE ChannelSwitchWrapper (EID_CHANNEL_SWITCH_WRAPPER)
+{
+    OPTIE IE  WiderBWChanSwitchAnn;
+    OPTIE IE  vht_transmit_power_env;
+}
+IE ExtCap (EID_EXT_CAP)
+{
+    bytes[1..15];
+}
+
+IE HTCaps (EID_HT_CAPABILITIES)
+{
+    // HT Capability Info
+    {
+        advCodingCap:             1;
+        supportedChannelWidthSet: 1;
+        mimoPowerSave:            2;
+        greenField:               1;
+        shortGI20MHz:             1;
+        shortGI40MHz:             1;
+        txSTBC:                   1;
+        rxSTBC:                   2;
+        delayedBA:                1;
+        maximalAMSDUsize:         1;
+        dsssCckMode40MHz:         1;
+        psmp:                     1;
+        stbcControlFrame:         1;
+        lsigTXOPProtection:       1;
+    }
+    // HT Parameters Info;
+    {
+        maxRxAMPDUFactor: 2;
+        mpduDensity:      3;
+        reserved1:        3;
+    }
+
+    supportedMCSSet[ HT_MAX_SUPPORTED_MCS_SET ];
+
+    // Extended HT Capability Info
+    {
+        pco:            1;
+        transitionTime: 2;
+        reserved2:      5;
+        mcsFeedback:    2;
+        reserved3:      6;
+    }
+    // TXBF Capability Info
+    {
+        txBF:                                       1;
+        rxStaggeredSounding:                        1;
+        txStaggeredSounding:                        1;
+        rxZLF:                                      1;
+        txZLF:                                      1;
+        implicitTxBF:                               1;
+        calibration:                                2;
+        explicitCSITxBF:                            1;
+        explicitUncompressedSteeringMatrix:         1;
+        explicitBFCSIFeedback:                      3;
+        explicitUncompressedSteeringMatrixFeedback: 3;
+        explicitCompressedSteeringMatrixFeedback:   3;
+        csiNumBFAntennae:                           2;
+        uncompressedSteeringMatrixBFAntennae:       2;
+        compressedSteeringMatrixBFAntennae:         2;
+        reserved4:           7;
+    }
+    // AS Capability Info
+    {
+        antennaSelection:         1;
+        explicitCSIFeedbackTx:    1;
+        antennaIndicesFeedbackTx: 1;
+        explicitCSIFeedback:      1;
+        antennaIndicesFeedback:   1;
+        rxAS:                     1;
+        txSoundingPPDUs:          1;
+        reserved5:                1;
+    }
+    //TODO: take it out when generic fix to remove extra bytes in IE is available.
+    //This is required to interop with Dlink AP which is sending 2 bytes extra in HTInfo IE.
+    rsvd[0..32];
+
+} // End IE HTCaps.
+
+IE HTInfo (EID_HT_INFO)
+{
+    primaryChannel, 1;
+
+    // ahtInfoField1
+    {
+        secondaryChannelOffset:     2;
+        recommendedTxWidthSet:      1;
+        rifsMode:                   1;
+        controlledAccessOnly:       1;
+        serviceIntervalGranularity: 3;
+    }
+
+    // ahtInfoField2
+
+
+    // ahtInfoField2
+    {
+        opMode:              2;
+        nonGFDevicesPresent: 1;
+        transmitBurstLimit: 1;
+        obssNonHTStaPresent:1;
+        reserved:           11;
+    }
+
+
+    // ahtInfoField3
+    {
+        basicSTBCMCS:                  7;
+        dualCTSProtection:             1;
+        secondaryBeacon:               1;
+        lsigTXOPProtectionFullSupport: 1;
+        pcoActive:                     1;
+        pcoPhase:                      1;
+        reserved2:                     4;
+    }
+
+    basicMCSSet[ HT_MAX_SUPPORTED_MCS_SET ];
+
+    //TODO: take it out when generic fix to remove extra bytes in IE is available.
+    //This is required to interop with Dlink AP which is sending 2 bytes extra in HTInfo IE.
+    rsvd[0..32];
+
+} // End IE HTInfo.
+
+
+IE OperatingMode (EID_OPERATING_MODE)
+{
+    { //Operating Mode field
+        chanWidth:    2;
+        reserved:     2;
+        rxNSS:        3;
+        rxNSSType:    1;
+    }
+}
+
+IE QosMapSet (EID_QOS_MAP_SET)
+{
+    dscp_exceptions[0..60];
+}
+
+CONTAINERIE RICDataDesc
+{
+  MANDIE RICData;
+  OPTIE  RICDescriptor;
+  OPTIE  TSPEC;
+  OPTIE  TCLAS[0..2];
+  OPTIE  TCLASSPROC;
+  OPTIE  TSDelay;
+  OPTIE  Schedule;
+  OPTIE  WMMTSPEC;
+  OPTIE  WMMTCLAS[0..2];
+  OPTIE  WMMTCLASPROC;
+  OPTIE  WMMTSDelay;
+  OPTIE  WMMSchedule;
+}
+
+IE TimeAdvertisement (EID_TIME_ADVERTISEMENT)   // 8.4.2.63
+{
+    timing_capabilities, 1;
+    time_value[10];
+    time_error[5];
+}
+
+IE QCN_IE (EID_VENDOR_SPECIFIC) OUI ( 0x8C, 0xFD, 0xF0, 0x01 )
+{
+    version[4];
+}
+
+IE esp_information (EID_EXTN_ID_ELEMENT) OUI ( 0x0B )
+{
+    data[0..96];
+}
+IE fils_indication (EID_FILS_INDICATION)
+{
+   // FILS Information element
+   {
+       public_key_identifiers_cnt     : 3;
+       realm_identifiers_cnt          : 3;
+       is_ip_config_supported         : 1;
+       is_cache_id_present            : 1;
+       is_hessid_present              : 1;
+       is_fils_sk_auth_supported      : 1;
+       is_fils_sk_auth_pfs_supported  : 1;
+       is_pk_auth_supported           : 1;
+       reserved                       : 4;
+   }
+   // other FILS elements
+   variable_data[2..255];
+}
+
+IE fils_assoc_delay_info (EID_EXTN_ID_ELEMENT) OUI ( 0x01 )
+{
+    assoc_delay_info, 1;
+}
+
+IE fils_key_confirmation (EID_EXTN_ID_ELEMENT) OUI ( 0x03 )
+{
+    key_auth[0..255];
+}
+
+IE fils_session (EID_EXTN_ID_ELEMENT) OUI ( 0x04 )
+{
+    session[8];
+}
+
+IE fils_hlp_container (EID_EXTN_ID_ELEMENT) OUI ( 0x05 )
+{
+    dest_mac[6];
+    src_mac[6];
+    hlp_packet[0..255];
+}
+
+IE fils_kde (EID_EXTN_ID_ELEMENT) OUI ( 0x07 )
+{
+    key_rsc[8];
+    kde_list[0..255];
+}
+
+IE fils_wrapped_data (EID_EXTN_ID_ELEMENT) OUI ( 0x08 )
+{
+    wrapped_data[0..255];
+}
+
+IE fils_public_key (EID_EXTN_ID_ELEMENT) OUI ( 0x0C )
+{
+    key_type, 1;
+    public_key[0..255];
+}
+
+IE fils_nonce (EID_EXTN_ID_ELEMENT) OUI ( 0x0D )
+{
+    nonce[16];
+}
+
+IE fragment_ie (EID_FRAGMENT_IE)
+{
+    data[0..255];
+}
+
+IE dh_parameter_element (EID_EXTN_ID_ELEMENT) OUI ( 0x20 )
+{
+    group[2];
+    public_key[0..255];
+}
+
+const EID_RRM_BEACON_REPORTING     = 1;
+const EID_RRM_BCN_REPORTING_DETAIL = 2;
+
+const SUB_EID_AZIMUTH_REQ = 1;
+const SUB_EID_REQ_MAC_ADDR = 2;
+const SUB_EID_TGT_MAC_ADDR = 3;
+const SUB_EID_MAX_AGE = 4;
+const SUB_EID_NEIGHBOR_RPT = 52;
+
+IE BeaconReporting (EID_RRM_BEACON_REPORTING)
+{
+     reportingCondition, 1;
+     threshold,          1;
+}
+
+IE BcnReportingDetail (EID_RRM_BCN_REPORTING_DETAIL)
+{
+     reportingDetail, 1;
+}
+
+IE APChannelReport (EID_AP_CHAN_REPORT)
+{
+     regulatoryClass, 1;
+     channelList[0..50];
+}
+
+IE azimuth_req (SUB_EID_AZIMUTH_REQ)
+{
+    request,    1;
+}
+
+IE req_mac_addr (SUB_EID_REQ_MAC_ADDR)
+{
+    addr[6];
+}
+
+IE tgt_mac_addr (SUB_EID_TGT_MAC_ADDR)
+{
+    addr[6];
+}
+
+IE max_age (SUB_EID_MAX_AGE)
+{
+    max_age,     2;
+}
+
+IE neighbor_rpt (SUB_EID_NEIGHBOR_RPT)
+{
+    bssid[6];
+    //Bssid Info
+    {
+         APReachability: 2;
+         Security:       1;
+         KeyScope:       1;
+         //Capabilities
+         SpecMgmtCap:    1;
+         QosCap:         1;
+         apsd:           1;
+         rrm:            1;
+    }
+    //Capabilities contd.
+    {
+         DelayedBA:      1;
+         ImmBA:          1;
+    //Capabilities end.
+         MobilityDomain: 1;
+         reserved:       5;
+    }
+         reserved1,      2; //part of BSSID Info.
+    regulatoryClass, 1;
+    channel,         1;
+    PhyType,         1;
+    OPTIE IE TSFInfo;
+    OPTIE IE CondensedCountryStr;
+    OPTIE IE MeasurementPilot;
+    OPTIE IE RRMEnabledCap;
+    OPTIE IE MultiBssid;
+}
+
+IE MeasurementRequest (EID_MEAS_REQUEST)  // 7.3.2.21
+{
+    measurement_token, 1;
+
+    // Measurement Request Mode
+    {
+        parallel:          1;
+        enable:            1;
+        request:           1;
+        report:            1;
+        durationMandatory: 1;
+        unused:            3;
+    }
+
+    measurement_type, 1;
+    UNION measurement_request (DISCRIMINATOR measurement_type)
+    {
+       Basic (measurement_type IS 0)
+       {
+           channel_no,       1;
+           meas_start_time[8];
+           meas_duration,    2;
+       }
+       CCA (measurement_type IS 1)
+       {
+           channel_no,       1;
+           meas_start_time[8];
+           meas_duration,    2;
+       }
+       RPIHistogram (measurement_type IS 2)
+       {
+           channel_no,       1;
+           meas_start_time[8];
+           meas_duration,    2;
+       }
+       Beacon (measurement_type IS 5)
+       {
+          regClass,          1;
+          channel,           1;
+          randomization,     2;
+          meas_duration,     2;
+          meas_mode,         1;
+          BSSID[6];
+          OPTIE SSID;
+          OPTIE BeaconReporting;
+          OPTIE BcnReportingDetail;
+          OPTIE RequestedInfo;
+          OPTIE APChannelReport[0..2];
+          OPTIE last_beacon_report_indication;
+          //OPTIONAL vendor_specific[1..239];
+       }
+       lci (measurement_type IS 8)
+       {
+          loc_subject,       1;
+          OPTIE azimuth_req;
+          OPTIE req_mac_addr;
+          OPTIE tgt_mac_addr;
+          OPTIE max_age;
+       }
+       ftmrr (measurement_type IS 16)
+       {
+          random_interval,   2;
+          min_ap_count,      1;
+
+          OPTIE neighbor_rpt;
+          OPTIE max_age;
+       }
+
+    };
+}
+
+IE he_cap (EID_EXTN_ID_ELEMENT) OUI (0x23)
+{
+    {
+      htc_he:1;
+      twt_request:1;
+      twt_responder:1;
+      fragmentation:2;
+      max_num_frag_msdu_amsdu_exp:3;
+      min_frag_size:2;
+      trigger_frm_mac_pad:2;
+      multi_tid_aggr_rx_supp:3;
+      he_link_adaptation:2;
+      all_ack:1;
+      trigd_rsp_sched:1;
+      a_bsr:1;
+      broadcast_twt:1;
+      ba_32bit_bitmap:1;
+      mu_cascade:1;
+      ack_enabled_multitid:1;
+      reserved:1;
+      omi_a_ctrl:1;
+      ofdma_ra:1;
+      max_ampdu_len_exp_ext:2;
+      amsdu_frag:1;
+      flex_twt_sched:1;
+      rx_ctrl_frame:1;
+    }
+    {
+      bsrp_ampdu_aggr:1;
+      qtp:1;
+      a_bqr:1;
+      spatial_reuse_param_rspder:1;
+      ndp_feedback_supp:1;
+      ops_supp:1;
+      amsdu_in_ampdu:1;
+      multi_tid_aggr_tx_supp:3;
+      he_sub_ch_sel_tx_supp:1;
+      ul_2x996_tone_ru_supp:1;
+      om_ctrl_ul_mu_data_dis_rx:1;
+      reserved1:3;
+    }
+    {
+      reserved2:1;
+      chan_width_0:1;
+      chan_width_1:1;
+      chan_width_2:1;
+      chan_width_3:1;
+      chan_width_4:1;
+      chan_width_5:1;
+      chan_width_6:1;
+      rx_pream_puncturing:4;
+      device_class:1;
+      ldpc_coding:1;
+      he_1x_ltf_800_gi_ppdu:1;
+      midamble_tx_rx_max_nsts:2;
+      he_4x_ltf_3200_gi_ndp:1;
+      tx_stbc_lt_80mhz:1;
+      rx_stbc_lt_80mhz:1;
+      doppler:2;
+      ul_mu:2;
+      dcm_enc_tx:3;
+      dcm_enc_rx:3;
+      ul_he_mu:1;
+      su_beamformer:1;
+    }
+    {
+      su_beamformee:1;
+      mu_beamformer:1;
+      bfee_sts_lt_80:3;
+      bfee_sts_gt_80:3;
+      num_sounding_lt_80:3;
+      num_sounding_gt_80:3;
+      su_feedback_tone16:1;
+      mu_feedback_tone16:1;
+      codebook_su:1;
+      codebook_mu:1;
+      beamforming_feedback:3;
+      he_er_su_ppdu:1;
+      dl_mu_mimo_part_bw:1;
+      ppet_present:1;
+      srp:1;
+      power_boost:1;
+      he_ltf_800_gi_4x:1;
+      max_nc:3;
+      tx_stbc_gt_80mhz:1;
+      rx_stbc_gt_80mhz:1;
+    }
+    {
+      er_he_ltf_800_gi_4x:1;
+      he_ppdu_20_in_40Mhz_2G:1;
+      he_ppdu_20_in_160_80p80Mhz:1;
+      he_ppdu_80_in_160_80p80Mhz:1;
+      er_1x_he_ltf_gi:1;
+      midamble_tx_rx_1x_he_ltf:1;
+      dcm_max_bw:2;
+      longer_than_16_he_sigb_ofdm_sym:1;
+      non_trig_cqi_feedback:1;
+      tx_1024_qam_lt_242_tone_ru:1;
+      rx_1024_qam_lt_242_tone_ru:1;
+      rx_full_bw_su_he_mu_compress_sigb:1;
+      rx_full_bw_su_he_mu_non_cmpr_sigb:1;
+      reserved3:2;
+    }
+    reserved4, 1;
+    rx_he_mcs_map_lt_80, 2;
+    tx_he_mcs_map_lt_80, 2;
+    rx_he_mcs_map_160[2][0..1] COUNTIS chan_width_2;
+    tx_he_mcs_map_160[2][0..1] COUNTIS chan_width_2;
+    rx_he_mcs_map_80_80[2][0..1] COUNTIS chan_width_3;
+    tx_he_mcs_map_80_80[2][0..1] COUNTIS chan_width_3;
+    OPTIONAL UNION ppet (DISCRIMINATOR ppet_present)
+    {
+        ppe_threshold (ppet_present IS 1)
+        {
+            ppe_th[1..25];
+        }
+    };
+}
+
+IE he_op (EID_EXTN_ID_ELEMENT) OUI (0x24)
+{
+    {
+        default_pe: 3;
+        twt_required: 1;
+        txop_rts_threshold: 10;
+        vht_oper_present: 1;
+        co_located_bss: 1;
+    }
+    {
+        er_su_disable: 1;
+        reserved2: 7;
+    }
+    {
+        bss_color:6;
+        partial_bss_col:1;
+        bss_col_disabled:1;
+    }
+    basic_mcs_nss[2];
+    OPTIONAL UNION vht_oper (DISCRIMINATOR vht_oper_present)
+    {
+        info (vht_oper_present IS 1)
+        {
+            chan_width, 1;
+            center_freq_seg0, 1;
+            center_freq_seg1, 1;
+        }
+    };
+    OPTIONAL UNION maxbssid_ind (DISCRIMINATOR co_located_bss)
+    {
+        info (co_located_bss IS 1)
+        {
+            data, 1;
+        }
+    };
+}
+
+IE mu_edca_param_set (EID_EXTN_ID_ELEMENT) OUI (0x26)
+{
+    qos, 1;
+    {
+        acbe_aifsn: 4;
+        acbe_acm:   1;
+        acbe_aci:   2;
+        unused1:    1;
+    }
+    {
+        acbe_acwmin: 4;
+        acbe_acwmax: 4;
+    }
+    acbe_muedca_timer, 1;
+    {
+        acbk_aifsn: 4;
+        acbk_acm:   1;
+        acbk_aci:   2;
+        unused2:    1;
+    }
+    {
+        acbk_acwmin: 4;
+        acbk_acwmax: 4;
+    }
+    acbk_muedca_timer, 1;
+    {
+        acvi_aifsn: 4;
+        acvi_acm:   1;
+        acvi_aci:   2;
+        unused3:    1;
+    }
+    {
+        acvi_acwmin: 4;
+        acvi_acwmax: 4;
+    }
+    acvi_muedca_timer, 1;
+    {
+        acvo_aifsn: 4;
+        acvo_acm:   1;
+        acvo_aci:   2;
+        unused4:    1;
+    }
+    {
+        acvo_acwmin: 4;
+        acvo_acwmax: 4;
+    }
+    acvo_muedca_timer, 1;
+}
+
+IE bss_color_change (EID_EXTN_ID_ELEMENT) OUI (0x2A)
+{
+    countdown, 1;
+    {
+        new_color: 6;
+        reserved: 2;
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//                                MULTIIEs                                 //
+/////////////////////////////////////////////////////////////////////////////
+
+MULTIIE WSC ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+    MANDATORYTLV Version;                               // Must be 0x10
+    OPTIONALTLV  WPSState;
+    OPTIONALTLV  APSetupLocked;
+    OPTIONALTLV  SelectedRegistrarConfigMethods;
+    OPTIONALTLV  UUID_E;
+    OPTIONALTLV  UUID_R;
+    OPTIONALTLV  RFBands;
+    OPTIONALTLV  SelectedRegistrar;
+    OPTIONALTLV  ConfigMethods;
+    OPTIONALTLV  AssociationState;
+    OPTIONALTLV  ConfigurationError;
+    OPTIONALTLV  Manufacturer;
+    OPTIONALTLV  ModelName;
+    OPTIONALTLV  ModelNumber;
+    OPTIONALTLV  SerialNumber;
+    OPTIONALTLV  DeviceName;
+    OPTIONALTLV  DevicePasswordID;
+    OPTIONALTLV  PrimaryDeviceType;
+    OPTIONALTLV  RequestType;
+    OPTIONALTLV  ResponseType;
+    OPTIONALTLV  VendorExtension;
+    OPTIONALTLV  RequestDeviceType;
+}
+
+MULTIIE WscBeacon ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+    MANDATORYTLV Version;                        // 0x10 = version 1.0, 0x11
+                                                 // = version 1.1, etc.
+    MANDATORYTLV WPSState;                       // 1 = unconfigured, 2 =
+                                                 // configured
+    OPTIONALTLV  APSetupLocked;                  // Must be included if value
+                                                 // is TRUE
+    OPTIONALTLV  SelectedRegistrar;              // BOOL: indicates if the
+                                                 // user has recently
+                                                 // activated a Registrar to
+                                                 // add an Enrollee.
+    OPTIONALTLV  DevicePasswordID;               // Device Password ID
+                                                 // indicates the method or
+                                                 // identifies the specific
+                                                 // password that the
+                                                 // selected Registrar
+                                                 // intends to use.
+    OPTIONALTLV  SelectedRegistrarConfigMethods; // This attribute contains
+                                                 // the config methods active
+                                                 // on the selected
+                                                 // Registrar.
+    OPTIONALTLV  UUID_E;                         // The AP's UUID is provided
+                                                 // only when the AP is a
+                                                 // dual-band AP in push
+                                                 // button mode and
+                                                 // indicating push button
+                                                 // mode on both radios
+    OPTIONALTLV  RFBands;                        // Indicates all RF bands
+                                                 // available on the AP. A
+                                                 // dual-band AP must provide
+                                                 // this attribute.
+    // WSC 2.0
+    OPTIONALTLV  VendorExtension;                // Version2 and AuthorizedMACs
+
+} // End Multi-IE WscBeacon.
+
+MULTIIE WscAssocReq ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+    MANDATORYTLV Version;                        // 0x10 = version 1.0, 0x11
+                                                 // = version 1.1, etc.
+    MANDATORYTLV RequestType;                    //
+                                                 //
+    // WSC 2.0
+    OPTIONALTLV  VendorExtension;                // Version2
+
+} // End Multi-IE WscAssocReq.
+
+
+MULTIIE WscAssocRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+    MANDATORYTLV Version;                        // 0x10 = version 1.0, 0x11
+                                                 // = version 1.1, etc.
+    MANDATORYTLV ResponseType;                   //
+                                                 //
+    // WSC 2.0
+    OPTIONALTLV  VendorExtension;                // Version2
+
+} // End Multi-IE WscAssocRes.
+
+MULTIIE WscReassocRes ( 221 ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+    MANDATORYTLV Version;                        // 0x10 = version 1.0, 0x11
+                                                 // = version 1.1, etc.
+    MANDATORYTLV ResponseType;                   //
+                                                 //
+    // WSC 2.0
+    OPTIONALTLV  VendorExtension;                // Version2
+
+} // End Multi-IE WscReassocRes
+
+MULTIIE WscProbeReq ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+    MANDATORYTLV Version;                        // 0x10 = version 1.0, 0x11
+                                                 // = version 1.1, etc.
+    MANDATORYTLV RequestType;                    //
+                                                 //
+    MANDATORYTLV ConfigMethods;                  // Configuration methods the
+                                                 // Enrollee or Registrar
+                                                 // supports
+    MANDATORYTLV UUID_E;                         // unique GUID generated by
+                                                 // the Enrollee.
+    MANDATORYTLV PrimaryDeviceType;
+    MANDATORYTLV RFBands;                        // Specific RF bands used
+                                                 // for this message
+    MANDATORYTLV AssociationState;               // Configuration and previous
+                                                 // association state
+    MANDATORYTLV ConfigurationError;
+    MANDATORYTLV DevicePasswordID;
+
+    // WSC 2.0
+    OPTIONALTLV  Manufacturer;                   // Must be included in ver 2.0
+                                                 // or higher.
+    OPTIONALTLV  ModelName;                      // Must be included in ver 2.0
+                                                 // or higher.
+    OPTIONALTLV  ModelNumber;                    // Must be included in ver 2.0
+                                                 // or higher.
+    OPTIONALTLV  DeviceName;                     // Must be included in ver 2.0
+                                                 // or higher.
+    OPTIONALTLV  VendorExtension;                // Version2 and RequestToEntroll
+
+    OPTIONALTLV  RequestDeviceType;              // When a device receives a Probe
+                                                 // Request containing this type,
+                                                 // It will only reponse if Primary
+                                                 // or Secondary Device Type matches.
+
+} // End Multi-IE WscProbeReq.
+
+MULTIIE WscProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+    MANDATORYTLV Version;                        // 0x10 = version 1.0, 0x11
+                                                 // = version 1.1, etc.
+    MANDATORYTLV WPSState;                       // 1 = unconfigured, 2 =
+                                                 // configured
+    OPTIONALTLV  APSetupLocked;                  // Must be included if value
+                                                 // is TRUE
+    OPTIONALTLV  SelectedRegistrar;              // BOOL: indicates if the
+                                                 // user has recently
+                                                 // activated a Registrar to
+                                                 // add an Enrollee.
+    OPTIONALTLV  DevicePasswordID;               // Device Password ID
+                                                 // indicates the method or
+                                                 // identifies the specific
+                                                 // password that the
+                                                 // selected Registrar
+                                                 // intends to use.
+    OPTIONALTLV  SelectedRegistrarConfigMethods; // This attribute contains
+                                                 // the config methods active
+                                                 // on the selected
+                                                 // Registrar.
+    MANDATORYTLV ResponseType;
+    MANDATORYTLV UUID_E;                         // unique identifier of AP
+    MANDATORYTLV Manufacturer;
+    MANDATORYTLV ModelName;
+    MANDATORYTLV ModelNumber;
+    MANDATORYTLV SerialNumber;
+    MANDATORYTLV PrimaryDeviceType;
+    MANDATORYTLV DeviceName;                     // User-friendly description
+                                                 // of device
+    MANDATORYTLV ConfigMethods;                  // Config Methods corresponds
+                                                 // to the methods the AP
+                                                 // supports as an Enrollee
+                                                 // for adding external
+                                                 // Registrars.
+    OPTIONALTLV RFBands;                         // Indicates all RF bands
+                                                 // available on the AP. A
+                                                 // dual-band AP must provide
+                                                 // this attribute.
+    // WSC 2.0
+    OPTIONALTLV  VendorExtension;                // Version2 and AuthorizedMACs
+
+} // WscProbeRes.
+
+// This MULTIIE combines the fields from the WSC IEs as they appear in
+// Beacons *and* in Probe Responses, with the difference that they're all
+// optional.  In our device drivers, we combine Probe Responses and Beacons
+// into one list, and parse their IEs later (c.f. frame BeaconIEs).  Because
+// the WSC IE differs in those two frames, we'd often see warning messages
+// about either unexpected fields showing up (if we thought we were parsing a
+// Beacon, and we in fact had data from a Probe Response) or mandatory fields
+// missing (if we thought we were parsing a Probe Response, and in fact had
+// data from a Beacon).
+
+// I created this MULTIIE to stuff into the BeaconIEs frames to avoid this.
+// It's intended to be used on unpack only, and to do so in a very forgiving
+// way.
+
+MULTIIE WscBeaconProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+    OPTIONALTLV Version;                        // 0x10 = version 1.0, 0x11
+                                                 // = version 1.1, etc.
+    OPTIONALTLV WPSState;                       // 1 = unconfigured, 2 =
+                                                 // configured
+    OPTIONALTLV  APSetupLocked;                  // Must be included if value
+                                                 // is TRUE
+    OPTIONALTLV  SelectedRegistrar;              // BOOL: indicates if the
+                                                 // user has recently
+                                                 // activated a Registrar to
+                                                 // add an Enrollee.
+    OPTIONALTLV  DevicePasswordID;               // Device Password ID
+                                                 // indicates the method or
+                                                 // identifies the specific
+                                                 // password that the
+                                                 // selected Registrar
+                                                 // intends to use.
+    OPTIONALTLV  SelectedRegistrarConfigMethods; // This attribute contains
+                                                 // the config methods active
+                                                 // on the selected
+                                                 // Registrar.
+    OPTIONALTLV ResponseType;
+    OPTIONALTLV UUID_E;                         // unique identifier of AP
+    OPTIONALTLV Manufacturer;
+    OPTIONALTLV ModelName;
+    OPTIONALTLV ModelNumber;
+    OPTIONALTLV SerialNumber;
+    OPTIONALTLV PrimaryDeviceType;
+    OPTIONALTLV DeviceName;                     // User-friendly description
+                                                 // of device
+    OPTIONALTLV ConfigMethods;                  // Config Methods corresponds
+                                                 // to the methods the AP
+                                                 // supports as an Enrollee
+                                                 // for adding external
+                                                 // Registrars.
+    OPTIONALTLV RFBands;                         // Indicates all RF bands
+                                                 // available on the AP. A
+                                                 // dual-band AP must provide
+                                                 // this attribute.
+    // WSC 2.0
+    OPTIONALTLV  VendorExtension;                // Version2 and AuthorizedMACs
+
+} // WscProbeRes.
+/////////////////////////////////////////////////////////////////////////////
+//                                MULTIIEs                                 //
+/////////////////////////////////////////////////////////////////////////////
+
+MULTIIE P2PBeacon ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+    MANDATORYTLV P2PCapability;                  // Contains P2P Device
+                                                 // and P2P Group Capability
+    MANDATORYTLV P2PDeviceId;                    // Contains P2P Device
+                                                 // Address
+    OPTIONALTLV  NoticeOfAbsence;                // Indicates Notice of
+                                                 // Absence schedule and
+                                                 // CT Window
+
+} // End P2PBeacon
+
+
+MULTIIE P2PAssocReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+    MANDATORYTLV P2PCapability;                  // Contains P2P Device
+                                                 // and P2P Group Capability
+    OPTIONALTLV  ExtendedListenTiming;
+    MANDATORYTLV P2PDeviceInfo;
+
+} // End P2PAssocReq
+
+
+MULTIIE P2PAssocRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+    MANDATORYTLV P2PStatus;
+    OPTIONALTLV  ExtendedListenTiming;
+
+} // End P2PAssocRes
+
+
+MULTIIE P2PProbeReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+    MANDATORYTLV P2PCapability;
+    OPTIONALTLV  P2PDeviceId;
+    MANDATORYTLV ListenChannel;
+    OPTIONALTLV  ExtendedListenTiming;
+    OPTIONALTLV  OperatingChannel;
+} // End P2PProbeReq
+
+
+MULTIIE P2PProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+    MANDATORYTLV P2PCapability;
+    OPTIONALTLV  ExtendedListenTiming;
+    OPTIONALTLV  NoticeOfAbsence;
+    MANDATORYTLV P2PDeviceInfo;
+    OPTIONALTLV  P2PGroupInfo;
+
+} // End P2PProbeRes
+
+
+MULTIIE P2PBeaconProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+    OPTIONALTLV P2PCapability;
+    OPTIONALTLV P2PDeviceId;
+    OPTIONALTLV ExtendedListenTiming;
+    OPTIONALTLV NoticeOfAbsence;
+    OPTIONALTLV P2PDeviceInfo;
+    OPTIONALTLV P2PGroupInfo;
+
+} // End P2PBeaconProbeRes
+
+
+MULTIIE P2PDeAuth ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+   MANDATORYTLV MinorReasonCode;
+}
+
+
+MULTIIE P2PDisAssoc ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+   MANDATORYTLV MinorReasonCode;
+}
+
+MULTIIE MBO_IE (EID_VENDOR_SPECIFIC) OUI ( 0x50, 0x6F, 0x9A, 0x16 )
+{
+   OPTIONALTLV mbo_ap_cap;
+   OPTIONALTLV non_prefferd_chan_rep;
+   OPTIONALTLV cellular_data_cap ;
+   OPTIONALTLV assoc_disallowed;
+   OPTIONALTLV cellular_data_con_pref;
+   OPTIONALTLV transition_reason;
+   OPTIONALTLV transition_reject_reason;
+   OPTIONALTLV assoc_retry_delay;
+   OPTIONALTLV oce_cap;
+   OPTIONALTLV rssi_assoc_rej;
+   OPTIONALTLV reduced_wan_metrics;
+}
+
+IE vendor_vht_ie (EID_VENDOR_SPECIFIC) OUI (0x00, 0x90, 0x4c, 0x04)
+{
+   sub_type, 1;
+   OPTIE IE VHTCaps;
+   OPTIE IE VHTOperation;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Frames
+
+FRAME Beacon                              // C.f. Sec. 7.2.3.1
+{
+    FF     TimeStamp;
+    FF     BeaconInterval;
+    FF     Capabilities;
+    MANDIE SSID;
+    MANDIE SuppRates;
+    OPTIE  FHParamSet;
+    OPTIE  DSParams;
+    OPTIE  CFParams;
+    OPTIE  IBSSParams;
+    OPTIE  TIM;
+    OPTIE  Country;
+    OPTIE  FHParams;
+    OPTIE  FHPattTable;
+    OPTIE  PowerConstraints;
+    OPTIE  ChanSwitchAnn;
+    OPTIE  ext_chan_switch_ann;
+    OPTIE  SuppOperatingClasses;
+    OPTIE  Quiet;
+    OPTIE  TPCReport;
+    OPTIE  ERPInfo;
+    OPTIE  ExtSuppRates;
+    OPTIE  RSN;
+    OPTIE  QBSSLoad;
+    OPTIE  EDCAParamSet;
+    OPTIE  QOSCapsAp;
+    OPTIE  APChannelReport;
+    OPTIE  RRMEnabledCap;
+    OPTIE  MobilityDomain;
+    OPTIE  WPA;
+    OPTIE  HTCaps;
+    OPTIE  HTInfo;
+    OPTIE  sec_chan_offset_ele;
+    OPTIE  WMMInfoAp;
+    OPTIE  WMMParams;
+    OPTIE  WMMCaps;
+    OPTIE  WAPI;
+    OPTIE  ESERadMgmtCap;
+    OPTIE  ESETrafStrmMet;
+    OPTIE  ESETxmitPower;
+
+    OPTIE  WscBeacon;
+    OPTIE  P2PBeacon;
+    OPTIE  VHTCaps;
+    OPTIE  VHTOperation;
+    OPTIE  VHTExtBssLoad;
+    OPTIE  ExtCap;
+    OPTIE  OperatingMode;
+    OPTIE  WiderBWChanSwitchAnn;
+    OPTIE  OBSSScanParameters;
+    OPTIE  fils_indication;
+    OPTIE  Vendor1IE;
+    OPTIE  vendor_vht_ie;
+    OPTIE  Vendor3IE;
+    OPTIE  hs20vendor_ie;
+    OPTIE  ChannelSwitchWrapper;
+    OPTIE  QComVendorIE;
+    OPTIE  ESEVersion;
+    OPTIE  MBO_IE;
+    OPTIE  QCN_IE;
+    OPTIE  he_cap;
+    OPTIE  he_op;
+    OPTIE  bss_color_change;
+    OPTIE  mu_edca_param_set;
+    OPTIE  esp_information;
+} // End frame Beacon.
+
+// Ok, here's  the story on  Beacon1 & Beacon2.   We presumably beacon  a lot
+// more than we  change configuration.  So it makes sense  to keep the beacon
+// we plan to send next in  serialized format.  We do this in struct schMisc.
+// Whenever our  config changes in  a way that  would affect our  beacons, we
+// just  update  our internal  datastructures  &  re-generate the  serialized
+// beacon.
+
+// The problem  is that there  are *some* fields  that need to be  updated at
+// send time,  specifically the CF Param  Set & the  TIM.  So, what we  do is
+// this: whenever  our config changes,  call schSetFixedBeaconFields.  There,
+// we serialize the following  Beacon fields into gSchBeaconFrameBegin (after
+// the power template & MAC header): TimeStamp, BeaconInterval, Capabilities,
+// SSID, SuppRates, DSParams, & IBSSParams.  It sets gSchBeaconOffsetBegin to
+// the length of this buffer (incl. power template & MAC header).
+
+// Next, it serializes the following fields into gSchBeaconFrameEnd: Country,
+// EDCAParamSet,   PowerConstraints,   TPCReport,  ChannelSwitchAnn,   Quiet,
+// ERPInfo,      HTCaps,      HTInfo,      ExtSuppRates, WPA, RSN,  WMMInfo,
+// WMMParams, WMMCaps.
+// The length of *this* buffer is kept in gSchBeaconOffsetEnd.
+
+// Then, in 'schBeaconInterruptHandler',  we write CFParams & TIM  at the end
+// of gSchBeaconFrameBegin, keeping track of the (new) size of this buffer in
+// the local 'beaconSize'.
+
+// After  that,  we  call  'specialBeaconProcessing'.   Note  that  this  may
+// actually call  schSetFixedBeaconFields repeatedly!  The  comments say they
+// try to avoid this, but...
+
+// Finally, we call writeBeaconToTFP, where the first thing we do is copy the
+// gSchBeaconFrameEnd buffer after the end of gSchBeaconFrameBegin.
+
+FRAME Beacon1
+{
+    FF     TimeStamp;
+    FF     BeaconInterval;
+    FF     Capabilities;
+    MANDIE SSID;
+    MANDIE SuppRates;
+    OPTIE  DSParams;
+    OPTIE  IBSSParams;
+}
+
+FRAME Beacon2
+{
+    OPTIE  Country;
+    OPTIE  PowerConstraints;
+    OPTIE  ChanSwitchAnn;
+    OPTIE  ext_chan_switch_ann;
+    OPTIE  SuppOperatingClasses;
+    OPTIE  Quiet;
+    OPTIE  TPCReport;
+    OPTIE  ERPInfo;
+    OPTIE  ExtSuppRates;
+    OPTIE  RSNOpaque;
+    OPTIE  EDCAParamSet;
+    OPTIE  APChannelReport;
+    OPTIE  RRMEnabledCap;
+    OPTIE  MobilityDomain;
+    OPTIE  WPA;
+    OPTIE  HTCaps;
+    OPTIE  HTInfo;
+    OPTIE  sec_chan_offset_ele;
+    OPTIE  WMMInfoAp;
+    OPTIE  WMMParams;
+    OPTIE  WMMCaps;
+    OPTIE  WscBeacon;
+    OPTIE  WAPI;
+    OPTIE  ESERadMgmtCap;
+    OPTIE  ESETrafStrmMet;
+    OPTIE  ESETxmitPower;
+    OPTIE  P2PBeacon;
+    OPTIE  VHTCaps;
+    OPTIE  VHTOperation;
+    OPTIE  VHTExtBssLoad;
+    OPTIE  ExtCap;
+    OPTIE  OperatingMode;
+    OPTIE  WiderBWChanSwitchAnn;
+    OPTIE  OBSSScanParameters;
+    OPTIE  fils_indication;
+    OPTIE  Vendor1IE;
+    OPTIE  vendor_vht_ie;
+    OPTIE  Vendor3IE;
+    OPTIE  hs20vendor_ie;
+    OPTIE  ChannelSwitchWrapper;
+    OPTIE  QComVendorIE;
+    OPTIE  ESEVersion;
+    OPTIE  QCN_IE;
+    OPTIE  he_cap;
+    OPTIE  he_op;
+    OPTIE  bss_color_change;
+    OPTIE  mu_edca_param_set;
+    OPTIE  esp_information;
+}
+
+// This frame is just Beacon with its Fixed Fields stripped out.  It's handy
+// for use with struct 'tSirBssDescription', which has members corresponding
+// to some fixed fields, but keeps its IEs in un-parsed format.
+
+// Note that it also includes the IE 'WscBeaconProbeRes'.
+
+FRAME BeaconIEs
+{
+
+    MANDIE SSID;
+    MANDIE SuppRates;
+    OPTIE  FHParamSet;
+    OPTIE  DSParams;
+    OPTIE  CFParams;
+    OPTIE  IBSSParams;
+    OPTIE  TIM;
+    OPTIE  Country;
+    OPTIE  FHParams;
+    OPTIE  FHPattTable;
+    OPTIE  PowerConstraints;
+    OPTIE  ChanSwitchAnn;
+    OPTIE  ext_chan_switch_ann;
+    OPTIE  SuppOperatingClasses;
+    OPTIE  Quiet;
+    OPTIE  TPCReport;
+    OPTIE  ERPInfo;
+    OPTIE  ExtSuppRates;
+    OPTIE  RSN;
+    OPTIE  QBSSLoad;
+    OPTIE  EDCAParamSet;
+    OPTIE  QOSCapsAp;
+    OPTIE  APChannelReport;
+    OPTIE  RRMEnabledCap;
+    OPTIE  MobilityDomain;
+    OPTIE  WPA;
+    OPTIE  HTCaps;
+    OPTIE  HTInfo;
+    OPTIE  sec_chan_offset_ele;
+    OPTIE  WMMInfoAp;
+    OPTIE  WMMParams;
+    OPTIE  WMMCaps;
+    OPTIE  WAPI;
+    OPTIE  ESEVersion;
+    OPTIE  ESERadMgmtCap;
+    OPTIE  ESETrafStrmMet;
+    OPTIE  ESETxmitPower;
+
+    OPTIE  WscBeaconProbeRes;
+    OPTIE  P2PBeaconProbeRes;
+    OPTIE  VHTCaps;
+    OPTIE  VHTOperation;
+    OPTIE  VHTExtBssLoad;
+    OPTIE  ExtCap;
+    OPTIE  OperatingMode;
+    OPTIE  WiderBWChanSwitchAnn;
+    OPTIE  OBSSScanParameters;
+    OPTIE  fils_indication;
+    OPTIE  Vendor1IE;
+    OPTIE  vendor_vht_ie;
+    OPTIE  Vendor3IE;
+    OPTIE  hs20vendor_ie;
+    OPTIE  ChannelSwitchWrapper;
+    OPTIE  QComVendorIE;
+    OPTIE  MBO_IE;
+    OPTIE  QCN_IE;
+    OPTIE  he_cap;
+    OPTIE  he_op;
+    OPTIE  bss_color_change;
+    OPTIE  mu_edca_param_set;
+    OPTIE  esp_information;
+} // End frame BeaconIEs.
+
+FRAME Disassociation                      // 7.3.3.3
+{
+    FF    Reason;
+    OPTIE P2PDisAssoc;
+}
+
+FRAME AssocRequest                        // 7.2.3.4
+{
+    FF     Capabilities;
+    FF     ListenInterval;
+    MANDIE SSID;
+    MANDIE SuppRates;
+    OPTIE  OperatingMode;
+    OPTIE  PowerCaps;
+    OPTIE  SuppChannels;
+    OPTIE  HTCaps;
+    OPTIE  QOSCapsStation;
+    OPTIE  RSNOpaque;
+    OPTIE  ExtSuppRates;
+    OPTIE  MobilityDomain;
+    OPTIE  SuppOperatingClasses;
+    OPTIE  WAPIOpaque;
+    OPTIE  WAPI;
+    OPTIE  RRMEnabledCap;
+    OPTIE  QosMapSet;
+    OPTIE  ExtCap;
+    OPTIE  VHTCaps;
+    OPTIE  fils_session;
+    OPTIE  fils_public_key;
+    OPTIE  fils_key_confirmation;
+    OPTIE  fils_hlp_container;
+    OPTIE  fragment_ie;
+    OPTIE  dh_parameter_element;
+    OPTIE  WPAOpaque;
+    OPTIE  WMMCaps;
+    OPTIE  WMMInfoStation;
+    OPTIE  WscIEOpaque;
+    OPTIE  ESERadMgmtCap;
+    OPTIE  ESEVersion;
+    OPTIE  P2PIEOpaque;
+    OPTIE  WFDIEOpaque;
+    OPTIE  vendor_vht_ie;
+    OPTIE  hs20vendor_ie;
+    OPTIE  QCN_IE;
+    OPTIE  he_cap;
+    OPTIE  osen_ie;
+} // End frame AssocRequest.
+
+FRAME AssocResponse                       // 7.2.3.5
+{
+    FF     Capabilities;
+    FF     Status;
+    FF     AID;
+    MANDIE SuppRates;
+    OPTIE  ExtSuppRates;
+    OPTIE  EDCAParamSet;
+    OPTIE  RCPIIE;
+    OPTIE  RSNIIE;
+    OPTIE  RRMEnabledCap;
+    OPTIE  MobilityDomain;
+    OPTIE  FTInfo;
+    OPTIE  RICDataDesc[2];
+    OPTIE  WPA;
+    OPTIE  TimeoutInterval;
+    OPTIE  HTCaps;
+    OPTIE  HTInfo;
+    OPTIE  WMMParams;
+    OPTIE  WMMCaps;
+    OPTIE  ESERadMgmtCap;
+    OPTIE  ESETrafStrmMet;
+    OPTIE  ESETxmitPower;
+    OPTIE  WMMTSPEC[0..4];
+    OPTIE  WscAssocRes;
+    OPTIE  P2PAssocRes;
+    OPTIE  VHTCaps;
+    OPTIE  VHTOperation;
+    OPTIE  ExtCap;
+    OPTIE  OBSSScanParameters;
+    OPTIE  QosMapSet;
+    OPTIE  fils_session;
+    OPTIE  fils_public_key;
+    OPTIE  fils_key_confirmation;
+    OPTIE  fils_hlp_container;
+    OPTIE  fragment_ie;
+    OPTIE  fils_kde;
+    OPTIE  vendor_vht_ie;
+    OPTIE  QCN_IE;
+    OPTIE  he_cap;
+    OPTIE  he_op;
+    OPTIE  bss_color_change;
+    OPTIE  mu_edca_param_set;
+    OPTIE  MBO_IE;
+} // End frame AssocResponse.
+
+FRAME ReAssocRequest                      // 7.2.3.6
+{
+    FF     Capabilities;
+    FF     ListenInterval;
+    FF     CurrentAPAddress;
+    MANDIE SSID;
+    MANDIE SuppRates;
+    OPTIE  ExtSuppRates;
+    OPTIE  PowerCaps;
+    OPTIE  SuppChannels;
+    OPTIE  RSNOpaque;
+    OPTIE  QOSCapsStation;
+    OPTIE  RRMEnabledCap;
+    OPTIE  MobilityDomain;
+    OPTIE  FTInfo;
+    OPTIE  RICDataDesc[2];
+    OPTIE  WPAOpaque;
+    OPTIE  HTCaps;
+    OPTIE  WMMCaps;
+    OPTIE  WMMInfoStation;
+    OPTIE  WscIEOpaque;
+    OPTIE  WAPIOpaque;
+    OPTIE  WAPI;
+    OPTIE  ESERadMgmtCap;
+    OPTIE  ESEVersion;
+    OPTIE  ESECckmOpaque;
+    OPTIE  WMMTSPEC[0..4];
+    OPTIE  ESETrafStrmRateSet;
+    OPTIE  P2PIEOpaque;
+    OPTIE  WFDIEOpaque;
+    OPTIE  VHTCaps;
+    OPTIE  ExtCap;
+    OPTIE  OperatingMode;
+    OPTIE  QosMapSet;
+    OPTIE  vendor_vht_ie;
+    OPTIE  hs20vendor_ie;
+    OPTIE  he_cap;
+} // End frame ReAssocRequest.
+
+FRAME ReAssocResponse                     // 7.2.3.7
+{
+    FF     Capabilities;
+    FF     Status;
+    FF     AID;
+    MANDIE SuppRates;
+    OPTIE  ExtSuppRates;
+    OPTIE  EDCAParamSet;
+    OPTIE  RCPIIE;
+    OPTIE  RSNIIE;
+    OPTIE  RRMEnabledCap;
+    OPTIE  RSNOpaque;
+    OPTIE  MobilityDomain;
+    OPTIE  FTInfo;
+    OPTIE  RICDataDesc[2];
+    OPTIE  WPA;
+    OPTIE  TimeoutInterval;
+    OPTIE  HTCaps;
+    OPTIE  HTInfo;
+    OPTIE  WMMParams;
+    OPTIE  ESERadMgmtCap;
+    OPTIE  ESETrafStrmMet;
+    OPTIE  ESETxmitPower;
+    OPTIE  WMMTSPEC[0..4];
+    OPTIE  ESETrafStrmRateSet;
+    OPTIE  WscReassocRes;
+    OPTIE  P2PAssocRes;
+    OPTIE  VHTCaps;
+    OPTIE  VHTOperation;
+    OPTIE  ExtCap;
+    OPTIE  OBSSScanParameters;
+    OPTIE  QosMapSet;
+    OPTIE  vendor_vht_ie;
+    OPTIE  he_cap;
+    OPTIE  he_op;
+    OPTIE  bss_color_change;
+    OPTIE  mu_edca_param_set;
+    OPTIE  MBO_IE;
+} // End frame ReAssocResponse.
+
+FRAME ProbeRequest                        // 7.2.3.8
+{
+    MANDIE SSID;
+    MANDIE SuppRates;
+    OPTIE  RequestedInfo;
+    OPTIE  ExtSuppRates;
+    OPTIE  DSParams;
+    OPTIE  HTCaps;
+    OPTIE  WscProbeReq;
+    OPTIE  WFATPC;
+    OPTIE  P2PProbeReq;
+    OPTIE  VHTCaps;
+    OPTIE  ExtCap;
+    OPTIE  QCN_IE;
+    OPTIE  he_cap;
+} // End frame ProbeRequest.
+
+FRAME ProbeResponse                       // 7.2.3.9
+{
+    FF     TimeStamp;
+    FF     BeaconInterval;
+    FF     Capabilities;
+    MANDIE SSID;
+    MANDIE SuppRates;
+    OPTIE  FHParamSet;
+    OPTIE  DSParams;
+    OPTIE  CFParams;
+    OPTIE  IBSSParams;
+    OPTIE  Country;
+    OPTIE  FHParams;
+    OPTIE  FHPattTable;
+    OPTIE  PowerConstraints;
+    OPTIE  ChanSwitchAnn;
+    OPTIE  ext_chan_switch_ann;
+    OPTIE  SuppOperatingClasses;
+    OPTIE  Quiet;
+    OPTIE  TPCReport;
+    OPTIE  ERPInfo;
+    OPTIE  ExtSuppRates;
+    OPTIE  RSNOpaque;
+    OPTIE  QBSSLoad;
+    OPTIE  EDCAParamSet;
+    OPTIE  RRMEnabledCap;
+    OPTIE  APChannelReport;
+    OPTIE  MobilityDomain;
+    OPTIE  WPA;
+    OPTIE  HTCaps;
+    OPTIE  HTInfo;
+    OPTIE  sec_chan_offset_ele;
+    OPTIE  WMMInfoAp;
+    OPTIE  WMMParams;
+    OPTIE  WMMCaps;
+    OPTIE  WAPI;
+    OPTIE  ESERadMgmtCap;
+    OPTIE  ESETrafStrmMet;
+    OPTIE  ESETxmitPower;
+
+    OPTIE  WscProbeRes;
+    OPTIE  P2PProbeRes;
+
+    OPTIE  VHTCaps;
+    OPTIE  VHTOperation;
+    OPTIE  VHTExtBssLoad;
+    OPTIE  ExtCap;
+    OPTIE  OBSSScanParameters;
+    OPTIE  fils_indication;
+    OPTIE  Vendor1IE;
+    OPTIE  vendor_vht_ie;
+    OPTIE  Vendor3IE;
+    OPTIE  hs20vendor_ie;
+    OPTIE  ChannelSwitchWrapper;
+    OPTIE  QComVendorIE;
+    OPTIE  ESEVersion;
+    OPTIE  MBO_IE;
+    OPTIE  QCN_IE;
+    OPTIE  he_cap;
+    OPTIE  he_op;
+    OPTIE  bss_color_change;
+    OPTIE  mu_edca_param_set;
+    OPTIE  esp_information;
+} // End frame ProbeResponse.
+
+FRAME Authentication                      // 7.2.3.10
+{
+    FF    AuthAlgo;
+    FF    AuthSeqNo;
+    FF    Status;
+    OPTIE ChallengeText;
+    OPTIE  RSNOpaque;
+    OPTIE  MobilityDomain;
+    OPTIE  FTInfo;
+    OPTIE  TimeoutInterval;
+    OPTIE  RICDataDesc[2];
+    OPTIE  fils_nonce;
+    OPTIE  fils_session;
+    OPTIE  fils_wrapped_data;
+    OPTIE  fils_assoc_delay_info;
+} // End frame Auth.
+
+FRAME DeAuth                              // 7.2.3.11
+{
+    FF    Reason;
+    OPTIE P2PDeAuth;
+}
+
+FRAME AddTSRequest                        // 7.4.2.1
+{
+
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    MANDIE TSPEC;
+    OPTIE  TCLAS[0..2];
+    OPTIE  TCLASSPROC;
+
+    // These IEs aren't in the spec, but our extant code *will* parse them if
+    // they're present.  I included them to preserve that capability
+
+    OPTIE  WMMTSPEC;
+    OPTIE  WMMTCLAS[0..2];
+    OPTIE  WMMTCLASPROC;
+    OPTIE  ESETrafStrmRateSet;
+
+} // End frame AddTSRequest.
+
+FRAME WMMAddTSRequest
+{
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    FF     StatusCode;
+    MANDIE WMMTSPEC;
+    OPTIE  ESETrafStrmRateSet;
+} // End Frame WMMAddTSRequest
+
+FRAME AddTSResponse                       // 7.4.2.2
+{
+
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    FF     Status;
+    MANDIE TSDelay;
+    MANDIE TSPEC;
+    OPTIE  TCLAS[0..2];
+    OPTIE  TCLASSPROC;
+    OPTIE  Schedule;
+
+    // These IEs aren't in the spec, but our extant code *will* parse them if
+    // they're present.  I included them to preserve that capability
+    OPTIE  WMMTSDelay;
+    OPTIE  WMMSchedule;
+    OPTIE  WMMTSPEC;
+    OPTIE  WMMTCLAS[0..2];
+    OPTIE  WMMTCLASPROC;
+    OPTIE  ESETrafStrmMet;
+
+} // End frame AddTSResponse.
+
+FRAME WMMAddTSResponse
+{
+
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    FF     StatusCode;
+    OPTIE  WMMTSPEC;
+    OPTIE  ESETrafStrmMet;
+
+} // End frame WMMAddTSResponse.
+
+FRAME DelTS                               // 7.4.2.3
+{
+    FF     Category;
+    FF     Action;
+    FF     TSInfo;
+    FF     Reason;
+}
+
+FRAME WMMDelTS
+{
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    FF     StatusCode;
+    MANDIE WMMTSPEC;
+}
+
+FRAME TPCRequest
+{
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    MANDIE TPCRequest;
+}
+
+FRAME TPCReport
+{
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    MANDIE TPCReport;
+}
+
+FRAME ChannelSwitch
+{
+    FF     Category;
+    FF     Action;
+    MANDIE ChanSwitchAnn;
+    OPTIE  sec_chan_offset_ele;
+    OPTIE  WiderBWChanSwitchAnn;
+}
+
+FRAME MeasurementRequest
+{
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    MANDIE MeasurementRequest[1..4];
+}
+
+FRAME MeasurementReport
+{
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    MANDIE MeasurementReport;
+}
+
+FRAME SMPowerSave
+{
+    FF    Category;
+    FF    Action;
+    FF    SMPowerModeSet;
+}
+
+FRAME RadioMeasurementRequest
+{
+   FF    Category;
+   FF    Action;
+   FF    DialogToken;
+   FF    NumOfRepetitions;
+   //Measurement Request IE.
+   MANDIE MeasurementRequest[1..2];
+}
+
+FRAME RadioMeasurementReport
+{
+   FF   Category;
+   FF   Action;
+   FF   DialogToken;
+   //Measurement Report elements.
+   MANDIE MeasurementReport[1..4];
+}
+
+FRAME LinkMeasurementRequest
+{
+   FF   Category;
+   FF   Action;
+   FF   DialogToken;
+   FF   TxPower;
+   FF   MaxTxPower;
+   //Optional Sub Ies
+}
+
+FRAME LinkMeasurementReport
+{
+   FF   Category;
+   FF   Action;
+   FF   DialogToken;
+   FF   TPCEleID;
+   FF   TPCEleLen;
+   FF   TxPower;
+   FF   LinkMargin;
+   FF   RxAntennaId;
+   FF   TxAntennaId;
+   FF   RCPI;
+   FF   RSNI;
+   //Optional Vendor specific IEs ... ignoring
+}
+
+FRAME NeighborReportRequest
+{
+   FF     Category;
+   FF     Action;
+   FF     DialogToken;
+   OPTIE  SSID;
+   //Optional vendor specific IE...ignoring.
+}
+
+FRAME NeighborReportResponse
+{
+   FF     Category;
+   FF     Action;
+   FF     DialogToken;
+   OPTIE  NeighborReport[1..MAX_SUPPORTED_NEIGHBOR_RPT];
+}
+
+FRAME OperatingMode
+{
+    FF        Category;
+    FF        Action;
+    //Operating Mode field
+    FF        OperatingMode;
+}
+
+FRAME TDLSDisReq
+{
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    MANDIE LinkIdentifier;
+}
+
+FRAME TDLSDisRsp
+{
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    FF     Capabilities;
+    MANDIE SuppRates;
+    OPTIE  ExtSuppRates;
+    OPTIE  SuppChannels;
+    OPTIE  SuppOperatingClasses;
+    OPTIE  RSN;
+    OPTIE  ExtCap;
+    OPTIE  FTInfo;
+    OPTIE  TimeoutInterval;
+    OPTIE  RICData;
+    OPTIE  HTCaps;
+    OPTIE  ht2040_bss_coexistence;
+    MANDIE LinkIdentifier;
+    OPTIE  VHTCaps;
+}
+
+FRAME TDLSSetupReq
+{
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    FF     Capabilities;
+    MANDIE SuppRates;
+    OPTIE  Country;
+    OPTIE  ExtSuppRates;
+    OPTIE  SuppChannels;
+    OPTIE  RSN;
+    OPTIE  ExtCap;
+    OPTIE  SuppOperatingClasses;
+    OPTIE  QOSCapsStation;
+    OPTIE  FTInfo;
+    OPTIE  TimeoutInterval;
+    OPTIE  RICData;
+    OPTIE  HTCaps;
+    OPTIE  ht2040_bss_coexistence;
+    MANDIE LinkIdentifier;
+    OPTIE  WMMInfoStation;
+    OPTIE  AID;
+    OPTIE  VHTCaps;
+}
+
+FRAME TDLSSetupRsp
+{
+    FF     Category;
+    FF     Action;
+    FF     Status;
+    FF     DialogToken;
+    FF     Capabilities ;
+    OPTIE  SuppRates;
+    OPTIE  Country;
+    OPTIE  ExtSuppRates;
+    OPTIE  SuppChannels;
+    OPTIE  RSN;
+    OPTIE  ExtCap;
+    OPTIE  SuppOperatingClasses;
+    OPTIE  QOSCapsStation;
+    OPTIE  FTInfo;
+    OPTIE  TimeoutInterval;
+    OPTIE  RICData;
+    OPTIE  HTCaps;
+    OPTIE  ht2040_bss_coexistence;
+    OPTIE  LinkIdentifier;
+    OPTIE  WMMInfoStation;
+    OPTIE  AID;
+    OPTIE  VHTCaps;
+    OPTIE  OperatingMode;
+}
+
+FRAME TDLSSetupCnf
+{
+    FF     Category;
+    FF     Action;
+    FF     Status;
+    FF     DialogToken;
+    OPTIE  RSN;
+    OPTIE  EDCAParamSet;
+    OPTIE  FTInfo;
+    OPTIE  TimeoutInterval;
+    OPTIE  HTInfo;
+    OPTIE  LinkIdentifier;
+    OPTIE  WMMParams;
+    OPTIE  VHTOperation;
+    OPTIE  OperatingMode;
+}
+FRAME TDLSTeardown
+{
+    FF     Category;
+    FF     Action;
+    FF     Reason;
+    OPTIE  FTInfo;
+    MANDIE LinkIdentifier;
+}
+
+FRAME TDLSPeerTrafficInd
+{
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    MANDIE LinkIdentifier;
+    OPTIE  PTIControl;
+    MANDIE PUBufferStatus;
+}
+
+FRAME TDLSPeerTrafficRsp
+{
+    FF     Category;
+    FF     Action;
+    FF     DialogToken;
+    MANDIE LinkIdentifier;
+}
+
+FRAME SaQueryReq
+{
+    FF     Category;
+    FF     Action;
+    FF     TransactionId;
+}
+
+FRAME SaQueryRsp
+{
+    FF     Category;
+    FF     Action;
+    FF     TransactionId;
+}
+
+FRAME QosMapConfigure
+{
+    FF     Category;
+    FF     Action;
+    MANDIE  QosMapSet;
+}
+
+FRAME VHTGidManagementActionFrame
+{
+    FF     Category;
+    FF     Action;
+    FF     VhtMembershipStatusArray;
+    FF     VhtUserPositionArray;
+}
+
+FRAME ht2040_bss_coexistence_mgmt_action_frame
+{
+    FF     Category;
+    FF     Action;
+    MANDIE ht2040_bss_coexistence;
+    MANDIE ht2040_bss_intolerant_report;
+}
+
+FRAME TimingAdvertisementFrame            // 8.3.3.15
+{
+    FF     TimeStamp;
+    FF     Capabilities;
+    OPTIE  Country;
+    OPTIE  PowerConstraints;
+    OPTIE  TimeAdvertisement;
+    OPTIE  ExtCap;
+    OPTIE  Vendor1IE;
+    OPTIE  Vendor3IE;
+}
+
+FRAME ext_channel_switch_action_frame
+{
+    FF     Category;
+    FF     Action;
+    FF     ext_chan_switch_ann_action;
+    OPTIE  WiderBWChanSwitchAnn;
+}
+
+FRAME p2p_oper_chan_change_confirm
+{
+    FF Category;
+    FF p2p_action_oui;
+    FF p2p_action_subtype;
+    FF DialogToken;
+    OPTIE HTCaps;
+    OPTIE VHTCaps;
+    OPTIE OperatingMode;
+}
+
+FRAME addba_req
+{
+    FF    Category;
+    FF    Action;
+    FF    DialogToken;
+    FF    addba_param_set;
+    FF    ba_timeout;
+    FF    ba_start_seq_ctrl;
+    OPTIE addba_extn_element;
+}
+
+FRAME addba_rsp
+{
+    FF    Category;
+    FF    Action;
+    FF    DialogToken;
+    FF    Status;
+    FF    addba_param_set;
+    FF    ba_timeout;
+    OPTIE addba_extn_element;
+}
+
+FRAME delba_req
+{
+    FF    Category;
+    FF    Action;
+    FF    delba_param_set;
+    FF    Reason;
+}
+
+// Local Variables:
+// mode: c++
+// fill-column: 77
+// comment-column: 42
+// indent-tabs-mode: nil
+// show-trailing-whitespace: t
+// End:
+
+// parser.frms ends here.
diff --git a/core/mac/src/cfg/cfg_api.c b/core/mac/src/cfg/cfg_api.c
new file mode 100644
index 0000000..78db2a8
--- /dev/null
+++ b/core/mac/src/cfg/cfg_api.c
@@ -0,0 +1,879 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file contains the source code for CFG API functions.
+ *
+ * Author:      Kevin Nguyen
+ * Date:        04/09/02
+ * History:-
+ * 04/09/02        Created.
+ * --------------------------------------------------------------------
+ */
+
+#include "cds_api.h"
+#include "cfg_priv.h"
+#include "wma_types.h"
+#include "cfg_api.h"
+
+/* --------------------------------------------------------------------- */
+/* Static Variables */
+/* ---------------------------------------------------------------------- */
+static tCfgCtl __g_cfg_entry[CFG_PARAM_MAX_NUM];
+static uint8_t __g_s_buffer[CFG_MAX_STR_LEN];
+static uint32_t __g_param_list[WNI_CFG_MAX_PARAM_NUM +
+			     WNI_CFG_GET_PER_STA_STAT_RSP_NUM];
+
+static void notify(tpAniSirGlobal, uint16_t, uint32_t);
+
+typedef enum {
+	eRF_BAND_UNKNOWN = 0,
+	eRF_BAND_2_4_GHZ = 1,
+	eRF_BAND_5_GHZ = 2
+} eRfBandMode;
+
+extern cfgstatic_string cfg_static_string[CFG_MAX_STATIC_STRING];
+extern cgstatic cfg_static[CFG_PARAM_MAX_NUM];
+
+/* --------------------------------------------------------------------- */
+uint32_t cfg_need_restart(tpAniSirGlobal pMac, uint16_t cfgId)
+{
+	if (!pMac->cfg.gCfgEntry) {
+		pe_err("gCfgEntry is NULL");
+		return 0;
+	}
+	return !!(pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_RESTART);
+}
+
+static void cfg_get_strindex(tpAniSirGlobal pMac, uint16_t cfgId)
+{
+	uint16_t i = 0;
+
+	for (i = 0; i < CFG_MAX_STATIC_STRING; i++) {
+		if (cfgId == cfg_static_string[i].cfgId)
+			break;
+	}
+	if (i == CFG_MAX_STATIC_STRING) {
+		pe_warn("Entry not found for cfg id: %d", cfgId);
+		cfg_static[cfgId].pStrData = NULL;
+		return;
+	}
+	cfg_static[cfgId].pStrData = &cfg_static_string[i];
+}
+/* --------------------------------------------------------------------- */
+uint32_t cfg_need_reload(tpAniSirGlobal pMac, uint16_t cfgId)
+{
+	if (!pMac->cfg.gCfgEntry) {
+		pe_err("gCfgEntry is NULL");
+		return 0;
+	}
+	return !!(pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_RELOAD);
+}
+
+/* --------------------------------------------------------------------- */
+QDF_STATUS cfg_init(tpAniSirGlobal pMac)
+{
+	uint16_t i = 0;
+	uint16_t combined_buff_size = 0;
+	uint32_t    max_i_count = 0;
+	uint32_t    max_s_count = 0;
+	cfgstatic_string *str_cfg;
+
+	pMac->cfg.gSBuffer = __g_s_buffer;
+	pMac->cfg.gCfgEntry = __g_cfg_entry;
+	pMac->cfg.gParamList = __g_param_list;
+
+	for (i = 0; i < CFG_PARAM_MAX_NUM; i++) {
+		if (!(cfg_static[i].control & CFG_CTL_INT)) {
+			cfg_get_strindex(pMac, i);
+		} else {
+			cfg_static[i].pStrData = NULL;
+		}
+	}
+
+	for (i = 0; i < CFG_PARAM_MAX_NUM ; i++) {
+		if (cfg_static[i].control & CFG_CTL_INT) {
+			max_i_count++;
+		} else {
+			str_cfg = (cfgstatic_string *)cfg_static[i].pStrData;
+			if (str_cfg == NULL) {
+				pe_warn("pStrCfg is NULL for CfigID: %d", i);
+				continue;
+			}
+			/* + 2 to include len field and max len field */
+			max_s_count += str_cfg->maxLen + 2;
+		}
+	}
+
+	pMac->cfg.gCfgMaxIBufSize = max_i_count;
+	pMac->cfg.gCfgMaxSBufSize = max_s_count;
+
+	/* Allocate a combined memory */
+	combined_buff_size = max_s_count + (3 * sizeof(uint32_t) * max_i_count);
+
+	pe_debug("Size of cfg I buffer: %d  S buffer: %d",
+		max_i_count, max_s_count);
+
+	pe_debug("Allocation for cfg buffers: %d bytes", combined_buff_size);
+
+	if (combined_buff_size > 4 * PAGE_SIZE) {
+		pe_err("Mem alloc request too big");
+		return QDF_STATUS_E_NOMEM;
+	}
+	/* at this point pMac->cfg.gCfgSBuf starts */
+	pMac->cfg.gCfgSBuf = qdf_mem_malloc(combined_buff_size);
+	if (!pMac->cfg.gCfgSBuf)
+		return QDF_STATUS_E_NOMEM;
+
+	/* at offset max_s_count, pMac->cfg.gCfgIBuf starts */
+	pMac->cfg.gCfgIBuf = (uint32_t *)&pMac->cfg.gCfgSBuf[max_s_count];
+	/* after max_i_count integers, pMac->cfg.gCfgIBufMin starts */
+	pMac->cfg.gCfgIBufMin = &pMac->cfg.gCfgIBuf[max_i_count];
+	/* after max_i_count integers, pMac->cfg.gCfgIBufMax starts */
+	pMac->cfg.gCfgIBufMax = &pMac->cfg.gCfgIBufMin[max_i_count];
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/* ---------------------------------------------------------------------- */
+void cfg_de_init(tpAniSirGlobal pMac)
+{
+	qdf_mem_free(pMac->cfg.gCfgSBuf);
+	pMac->cfg.gCfgIBufMin = NULL;
+	pMac->cfg.gCfgIBufMax = NULL;
+	pMac->cfg.gCfgIBuf = NULL;
+	pMac->cfg.gCfgSBuf = NULL;
+	pMac->cfg.gSBuffer = NULL;
+	pMac->cfg.gCfgEntry = NULL;
+	pMac->cfg.gParamList = NULL;
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_check_valid()
+ *
+ * FUNCTION:
+ * This function is called to check if a parameter is valid
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param cfgId:  16-bit CFG parameter ID
+ *
+ * @return QDF_STATUS_SUCCESS:  request completed successfully
+ * @return QDF_STATUS_E_INVAL:  invalid CFG parameter ID
+ */
+QDF_STATUS cfg_check_valid(tpAniSirGlobal pMac, uint16_t cfgId,
+			   uint32_t *index)
+{
+	uint32_t control;
+
+	if (cfgId >= CFG_PARAM_MAX_NUM) {
+		pe_warn("Invalid cfg id: %d", cfgId);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!pMac->cfg.gCfgEntry) {
+		pe_warn("gCfgEntry is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	control = pMac->cfg.gCfgEntry[cfgId].control;
+
+	/* Check if parameter is valid */
+	if ((control & CFG_CTL_VALID) == 0) {
+		pe_warn("Not valid cfg id: %d", cfgId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*index = control & CFG_BUF_INDX_MASK;
+
+	if (*index >= pMac->cfg.gCfgMaxSBufSize) {
+		pe_warn("cfg index out of bounds: %d", *index);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /*** end cfg_check_valid() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_set_int()
+ *
+ * FUNCTION:
+ * This function is called to update an integer parameter.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * - Range checking is performed by the calling function.  In case this
+ *   function call is being triggered by a request from host, then host
+ *   is responsible for performing range checking before sending the
+ *   request.
+ *
+ * - Host RW permission checking should already be done prior to calling
+ *   this function by the message processing function.
+ *
+ * NOTE:
+ *
+ * @param cfgId:     16-bit CFG parameter ID
+ * @param value:     32-bit unsigned value
+ *
+ * @return QDF_STATUS_SUCCESS:  request completed successfully
+ * @return QDF_STATUS_E_INVAL:  invalid CFG parameter ID
+ */
+
+QDF_STATUS cfg_set_int(tpAniSirGlobal pMac, uint16_t cfgId, uint32_t value)
+{
+	uint32_t index;
+	uint32_t control;
+	uint32_t mask;
+	QDF_STATUS status;
+
+	status = cfg_check_valid(pMac, cfgId, &index);
+
+	if (QDF_STATUS_SUCCESS != status)
+		return status;
+
+	if ((pMac->cfg.gCfgIBufMin[index] > value) ||
+			(pMac->cfg.gCfgIBufMax[index] < value)) {
+		pe_warn("Value: %d out of range: [%d,%d] cfg id: %d, %s",
+				value, pMac->cfg.gCfgIBufMin[index],
+				pMac->cfg.gCfgIBufMax[index], cfgId,
+				cfg_get_string(cfgId));
+		return QDF_STATUS_E_INVAL;
+	} else {
+		/* Write integer value */
+		pMac->cfg.gCfgIBuf[index] = value;
+
+		control = pMac->cfg.gCfgEntry[cfgId].control;
+		/* Update hardware if necessary */
+		mask = control & CFG_CTL_NTF_MASK;
+		if ((mask & CFG_CTL_NTF_HW) != 0)
+			pe_debug("CFG notify HW not supported!!!");
+			/* notify other modules if necessary */
+			if ((mask & CFG_CTL_NTF_MASK) != 0)
+				notify(pMac, cfgId, mask);
+	}
+	return status;
+} /*** end cfg_set_int ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * wlan_cfg_get_int()
+ *
+ * FUNCTION:
+ * This function is called to read an integer parameter.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param cfgId:  16-bit CFG parameter ID
+ * @param pVal:   address where parameter value will be written
+ *
+ * @return QDF_STATUS_SUCCESS:  request completed successfully
+ * @return QDF_STATUS_E_INVAL:  invalid CFG parameter ID
+ */
+
+QDF_STATUS wlan_cfg_get_int(tpAniSirGlobal pMac, uint16_t cfgId,
+			    uint32_t *pValue)
+{
+	uint32_t index;
+	QDF_STATUS status;
+
+	status = cfg_check_valid(pMac, cfgId, &index);
+
+	if (QDF_STATUS_SUCCESS != status)
+		return status;
+
+	/* Get integer value */
+	*pValue = pMac->cfg.gCfgIBuf[index];
+
+	return QDF_STATUS_SUCCESS;
+} /*** end wlan_cfg_get_int() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_set_str()
+ *
+ * FUNCTION:
+ * This function is called to set a string parameter.
+ *
+ * LOGIC:
+ * This function invokes the cfg_set_str_notify function passing the notify
+ * bool value set to true. This basically means that HAL needs to be
+ * notified. This is true in the case of non-integrated SOC's or Libra/Volans.
+ * In the case of Prima the cfg_set_str_notify is invoked with the bool value
+ * set to false.
+ *
+ * ASSUMPTIONS:
+ * - always notify has to be called
+ *
+ * NOTE:
+ *
+ * @param cfgId:     16-bit CFG parameter ID
+ * @param pStr:      address of string data
+ * @param len:       string length
+ *
+ * @return QDF_STATUS_SUCCESS:  request completed successfully
+ * @return QDF_STATUS_E_INVAL:  invalid CFG parameter ID
+ * @return QDF_STATUS_E_INVAL:  invalid CFG parameter length
+ *
+ */
+
+QDF_STATUS cfg_set_str(tpAniSirGlobal pMac, uint16_t cfgId, uint8_t *pStr,
+		       uint32_t length)
+{
+	return cfg_set_str_notify(pMac, cfgId, pStr, length, true);
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_set_str_notify()
+ *
+ * FUNCTION:
+ * This function is called to set a string parameter.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * - No length checking will be performed.  Should be done by calling
+ *   module.
+ * - Host RW permission should be checked prior to calling this
+ *   function.
+ *
+ * NOTE:
+ *
+ * @param cfgId:     16-bit CFG parameter ID
+ * @param pStr:      address of string data
+ * @param len:       string length
+ * @param notifyMod. notify respective Module
+ *
+ * @return QDF_STATUS_SUCCESS:  request completed successfully
+ * @return QDF_STATUS_E_INVAL:  invalid CFG parameter ID
+ * @return QDF_STATUS_E_INVAL:  invalid CFG parameter length
+ *
+ */
+
+QDF_STATUS cfg_set_str_notify(tpAniSirGlobal pMac, uint16_t cfgId,
+			      uint8_t *pStr, uint32_t length,
+			      int notifyMod)
+{
+	uint8_t *pDst, *pDstEnd;
+	uint32_t index, paramLen, mask;
+	uint32_t control;
+	QDF_STATUS status;
+
+	status = cfg_check_valid(pMac, cfgId, &index);
+
+	if (QDF_STATUS_SUCCESS != status)
+		return status;
+
+	pDst = &pMac->cfg.gCfgSBuf[index];
+	paramLen = *pDst++;
+	control = pMac->cfg.gCfgEntry[cfgId].control;
+	if (length > paramLen) {
+		pe_warn("Invalid length: %d (>%d) cfg id: %d",
+			length, paramLen, cfgId);
+			return QDF_STATUS_E_INVAL;
+	} else {
+		*pDst++ = (uint8_t) length;
+		pDstEnd = pDst + length;
+		while (pDst < pDstEnd) {
+			*pDst++ = *pStr++;
+		}
+		if (notifyMod) {
+			/* Update hardware if necessary */
+			mask = control & CFG_CTL_NTF_MASK;
+			if ((mask & CFG_CTL_NTF_HW) != 0) {
+				pe_debug("CFG notify HW not supported!");
+			}
+			/* notify other modules if necessary */
+			if ((mask & CFG_CTL_NTF_MASK) != 0) {
+				notify(pMac, cfgId, mask);
+			}
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+} /*** end cfg_set_str_notify() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * wlan_cfg_get_str()
+ *
+ * FUNCTION:
+ * This function is called to get a string parameter.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * - Host RW permission should be checked prior to calling this
+ *   function.
+ *
+ * NOTE:
+ *
+ * @param cfgId:     16-bit CFG parameter ID
+ * @param pBuf:      address of string buffer
+ * @param pLen:      address of max buffer length
+ *                   actual length will be returned at this address
+ *
+ * @return QDF_STATUS_SUCCESS:  request completed successfully
+ * @return QDF_STATUS_E_INVAL:  invalid CFG parameter ID
+ * @return QDF_STATUS_E_INVAL:  invalid CFG parameter length
+ *
+ */
+
+QDF_STATUS wlan_cfg_get_str(tpAniSirGlobal pMac, uint16_t cfgId,
+			    uint8_t *pBuf, uint32_t *pLength)
+{
+	uint8_t *pSrc, *pSrcEnd;
+	uint32_t index;
+	QDF_STATUS status;
+
+	status = cfg_check_valid(pMac, cfgId, &index);
+
+	if (QDF_STATUS_SUCCESS != status)
+		return status;
+
+	/* Get string */
+	pSrc = &pMac->cfg.gCfgSBuf[index];
+	pSrc++;         /* skip over max length */
+	if (*pLength < *pSrc) {
+		pe_warn("Invalid length: %d (<%d) cfg id: %d",
+			*pLength, *pSrc, cfgId);
+			return QDF_STATUS_E_INVAL;
+	} else {
+		*pLength = *pSrc++;     /* save parameter length */
+		pSrcEnd = pSrc + *pLength;
+		while (pSrc < pSrcEnd)
+			*pBuf++ = *pSrc++;
+	}
+	return QDF_STATUS_SUCCESS;
+} /*** end wlan_cfg_get_str() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * wlan_cfg_get_str_max_len()
+ *
+ * FUNCTION:
+ * This function is called to get a string maximum length.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * - Host RW permission should be checked prior to calling this
+ *   function.
+ *
+ * NOTE:
+ *
+ * @param cfgId:     16-bit CFG parameter ID
+ * @param pLen:      maximum length will be returned at this address
+ *
+ * @return QDF_STATUS_SUCCESS:  request completed successfully
+ * @return QDF_STATUS_E_INVAL:  invalid CFG parameter ID
+ *
+ */
+
+QDF_STATUS wlan_cfg_get_str_max_len(tpAniSirGlobal pMac, uint16_t cfgId,
+				    uint32_t *pLength)
+{
+	uint32_t index;
+	QDF_STATUS status;
+
+	status = cfg_check_valid(pMac, cfgId, &index);
+
+	if (QDF_STATUS_SUCCESS != status)
+		return status;
+
+	*pLength = pMac->cfg.gCfgSBuf[index];
+
+	return status;
+} /*** end wlan_cfg_get_str_max_len() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * wlan_cfg_get_str_len()
+ *
+ * FUNCTION:
+ * This function is called to get a string length.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * - Host RW permission should be checked prior to calling this
+ *   function.
+ *
+ * NOTE:
+ *
+ * @param cfgId:     16-bit CFG parameter ID
+ * @param pLen:      current length will be returned at this address
+ *
+ * @return QDF_STATUS_SUCCESS:         request completed successfully
+ * @return QDF_STATUS_E_INVAL:  invalid CFG parameter ID
+ *
+ */
+
+QDF_STATUS wlan_cfg_get_str_len(tpAniSirGlobal pMac, uint16_t cfgId,
+				uint32_t *pLength)
+{
+	uint32_t index;
+	QDF_STATUS status;
+
+	status = cfg_check_valid(pMac, cfgId, &index);
+
+	if (QDF_STATUS_SUCCESS != status)
+		return status;
+
+	*pLength = pMac->cfg.gCfgSBuf[index + 1];
+
+	return status;
+
+} /*** end wlan_cfg_get_str_len() ***/
+
+/**
+ * cfg_get_dot11d_transmit_power() - regulatory max transmit power
+ * @pMac: pointer to mac data
+ * @cfgId: configuration ID
+ * @cfgLength: configuration length
+ * @channel: channel number
+ *
+ * Return:  int8_t - power
+ */
+static int8_t
+cfg_get_dot11d_transmit_power(tpAniSirGlobal pMac, uint16_t cfgId,
+			      uint32_t cfgLength, uint8_t channel)
+{
+	uint8_t *pCountryInfo = NULL;
+	uint8_t count = 0;
+	int8_t maxTxPwr = WMA_MAX_TXPOWER_INVALID;
+
+	/* At least one element is present */
+	if (cfgLength < sizeof(tSirMacChanInfo)) {
+		pe_err("Invalid CFGLENGTH: %d while getting 11d txpower",
+			       cfgLength);
+		goto error;
+	}
+
+	pCountryInfo = qdf_mem_malloc(cfgLength);
+	if (!pCountryInfo)
+		goto error;
+
+	/* The CSR will always update this CFG. The contents will be from country IE if regulatory domain
+	 * is enabled on AP else will contain EEPROM contents
+	 */
+	if (wlan_cfg_get_str(pMac, cfgId, pCountryInfo, &cfgLength) !=
+							QDF_STATUS_SUCCESS) {
+		qdf_mem_free(pCountryInfo);
+		pCountryInfo = NULL;
+
+		pe_warn("Failed to retrieve 11d configuration parameters while retrieving 11d tuples");
+		goto error;
+	}
+	/* Identify the channel and maxtxpower */
+	while (count <= (cfgLength - (sizeof(tSirMacChanInfo)))) {
+		uint8_t firstChannel, maxChannels;
+
+		firstChannel = pCountryInfo[count++];
+		maxChannels = pCountryInfo[count++];
+		maxTxPwr = pCountryInfo[count++];
+
+		if ((channel >= firstChannel) &&
+		    (channel < (firstChannel + maxChannels))) {
+			break;
+		}
+	}
+
+error:
+	if (NULL != pCountryInfo)
+		qdf_mem_free(pCountryInfo);
+
+	return maxTxPwr;
+}
+
+/**----------------------------------------------------------------------
+   \fn     cfg_get_regulatory_max_transmit_power
+
+   \brief  Gets regulatory tx power on the current channel.
+
+   \param  pMac
+   \param  channel
+   \param  rfBand
+   -----------------------------------------------------------------------*/
+int8_t cfg_get_regulatory_max_transmit_power(tpAniSirGlobal pMac,
+					     uint8_t channel)
+{
+	uint32_t cfgLength = 0;
+	uint16_t cfgId = 0;
+	int8_t maxTxPwr;
+	eRfBandMode rfBand = eRF_BAND_UNKNOWN;
+
+	if ((channel >= SIR_11A_CHANNEL_BEGIN) &&
+	    (channel <= SIR_11A_CHANNEL_END))
+		rfBand = eRF_BAND_5_GHZ;
+	else
+		rfBand = eRF_BAND_2_4_GHZ;
+
+	/* Get the max transmit power for current channel for the current regulatory domain */
+	switch (rfBand) {
+	case eRF_BAND_2_4_GHZ:
+		cfgId = WNI_CFG_MAX_TX_POWER_2_4;
+		cfgLength = WNI_CFG_MAX_TX_POWER_2_4_LEN;
+		pe_debug("HAL: Reading CFG for 2.4 GHz channels to get regulatory max tx power");
+		break;
+
+	case eRF_BAND_5_GHZ:
+		cfgId = WNI_CFG_MAX_TX_POWER_5;
+		cfgLength = WNI_CFG_MAX_TX_POWER_5_LEN;
+		pe_debug("HAL: Reading CFG for 5.0 GHz channels to get regulatory max tx power");
+		break;
+
+	case eRF_BAND_UNKNOWN:
+	default:
+		pe_warn("HAL: Invalid current working band for the device");
+		return WMA_MAX_TXPOWER_INVALID;         /* Its return, not break. */
+	}
+
+	maxTxPwr = cfg_get_dot11d_transmit_power(pMac, cfgId, cfgLength, channel);
+
+	return maxTxPwr;
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_get_capability_info
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+QDF_STATUS cfg_get_capability_info(tpAniSirGlobal pMac, uint16_t *pCap,
+				   tpPESession sessionEntry)
+{
+	uint32_t val = 0;
+	tpSirMacCapabilityInfo pCapInfo;
+
+	*pCap = 0;
+	pCapInfo = (tpSirMacCapabilityInfo) pCap;
+
+	if (LIM_IS_IBSS_ROLE(sessionEntry))
+		pCapInfo->ibss = 1;     /* IBSS bit */
+	else if (LIM_IS_AP_ROLE(sessionEntry) ||
+		LIM_IS_STA_ROLE(sessionEntry))
+		pCapInfo->ess = 1;      /* ESS bit */
+	else if (LIM_IS_P2P_DEVICE_ROLE(sessionEntry) ||
+		LIM_IS_NDI_ROLE(sessionEntry)) {
+		pCapInfo->ess = 0;
+		pCapInfo->ibss = 0;
+	} else
+		pe_warn("can't get capability, role is UNKNOWN!!");
+
+	if (LIM_IS_AP_ROLE(sessionEntry)) {
+		val = sessionEntry->privacy;
+	} else {
+		/* PRIVACY bit */
+		val = pMac->mlme_cfg->wep_params.is_privacy_enabled;
+	}
+	if (val)
+		pCapInfo->privacy = 1;
+
+	/* Short preamble bit */
+	if (pMac->mlme_cfg->ht_caps.short_preamble)
+		pCapInfo->shortPreamble =
+			pMac->mlme_cfg->ht_caps.short_preamble;
+
+	/* PBCC bit */
+	pCapInfo->pbcc = 0;
+
+	/* Channel agility bit */
+	pCapInfo->channelAgility = 0;
+	/* If STA/AP operating in 11B mode, don't set rest of the
+	 * capability info bits.
+	 */
+	if (sessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11B)
+		return QDF_STATUS_SUCCESS;
+
+	/* Short slot time bit */
+	if (LIM_IS_AP_ROLE(sessionEntry)) {
+		pCapInfo->shortSlotTime = sessionEntry->shortSlotTimeSupported;
+	} else {
+		/* When in STA mode, we need to check if short slot is
+		 * enabled as well as check if the current operating
+		 * mode is short slot time and then decide whether to
+		 * enable short slot or not. It is safe to check both
+		 * cfg values to determine short slot value in this
+		 * funcn since this funcn is always used after assoc
+		 * when these cfg values are already set based on
+		 * peer's capability. Even in case of IBSS, its value
+		 * is set to correct value either in delBSS as part of
+		 * deleting the previous IBSS or in start BSS as part
+		 * of coalescing
+		 */
+		if (pMac->mlme_cfg->feature_flags.enable_short_slot_time_11g) {
+			pCapInfo->shortSlotTime =
+				sessionEntry->shortSlotTimeSupported;
+		}
+	}
+
+	/* Spectrum Management bit */
+	if (!LIM_IS_IBSS_ROLE(sessionEntry) && sessionEntry->lim11hEnable) {
+		if (wlan_cfg_get_int(pMac, WNI_CFG_11H_ENABLED, &val) !=
+		    QDF_STATUS_SUCCESS) {
+			pe_err("cfg get WNI_CFG_11H_ENABLED failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+		if (val)
+			pCapInfo->spectrumMgt = 1;
+	}
+	/* QoS bit */
+	if (pMac->mlme_cfg->wmm_params.qos_enabled)
+		pCapInfo->qos = 1;
+
+	/* APSD bit */
+	if (wlan_cfg_get_int(pMac, WNI_CFG_APSD_ENABLED, &val) !=
+							QDF_STATUS_SUCCESS) {
+		pe_err("cfg get WNI_CFG_APSD_ENABLED failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (val)
+		pCapInfo->apsd = 1;
+
+	pCapInfo->rrm = pMac->rrm.rrmSmeContext.rrmConfig.rrm_enabled;
+	pe_debug("RRM: %d", pCapInfo->rrm);
+	/* DSSS-OFDM */
+	/* FIXME : no config defined yet. */
+
+	/* Block ack bit */
+	val = pMac->mlme_cfg->feature_flags.enable_block_ack;
+	pCapInfo->delayedBA =
+		(uint16_t) ((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1);
+	pCapInfo->immediateBA =
+		(uint16_t) ((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * cfg_set_capability_info
+ *
+ * FUNCTION:
+ * This function is called on BP based on the capabilities
+ * received in SME_JOIN/REASSOC_REQ message.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE: 1. ESS/IBSS capabilities are based on system role.
+ *       2. Since PBCC, Channel agility and Extended capabilities
+ *          are not supported, they're not set at CFG
+ *
+ * @param  pMac   Pointer to global MAC structure
+ * @param  caps   16-bit Capability Info field
+ * @return None
+ */
+
+void cfg_set_capability_info(tpAniSirGlobal pMac, uint16_t caps)
+{
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_cleanup()
+ *
+ * FUNCTION:
+ * CFG cleanup function.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ * This function must be called during system shutdown.
+ *
+ * @param None
+ *
+ * @return None.
+ *
+ */
+
+void cfg_cleanup(tpAniSirGlobal pMac)
+{
+	/* Set status to not-ready */
+	pMac->cfg.gCfgStatus = CFG_INCOMPLETE;
+
+} /*** end CfgCleanup() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * notify()
+ *
+ * FUNCTION:
+ * This function is called to notify other modules of parameter update.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param cfgId:    configuration parameter ID
+ * @param mask:     notification mask
+ *
+ * @return None.
+ *
+ */
+
+static void notify(tpAniSirGlobal pMac, uint16_t cfgId, uint32_t ntfMask)
+{
+
+	struct scheduler_msg mmhMsg = {0};
+
+	mmhMsg.type = SIR_CFG_PARAM_UPDATE_IND;
+	mmhMsg.bodyval = (uint32_t) cfgId;
+	mmhMsg.bodyptr = NULL;
+
+	if ((ntfMask & CFG_CTL_NTF_SCH) != 0)
+		sch_post_message(pMac, &mmhMsg);
+
+	if ((ntfMask & CFG_CTL_NTF_LIM) != 0)
+		lim_post_msg_api(pMac, &mmhMsg);
+
+	if ((ntfMask & CFG_CTL_NTF_TARGET) != 0)
+		wma_post_ctrl_msg(pMac, &mmhMsg);
+
+	/* notify ARQ */
+
+} /*** end notify() ***/
+
diff --git a/core/mac/src/cfg/cfg_def.h b/core/mac/src/cfg/cfg_def.h
new file mode 100644
index 0000000..e521c6b
--- /dev/null
+++ b/core/mac/src/cfg/cfg_def.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011-2012, 2014, 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.
+ */
+
+/*
+ *
+ * This is the private header file for CFG module.
+ *
+ * Author:        Kevin Nguyen
+ * Date:        03/20/02
+ * History:-
+ * 03/20/02        Created.
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __CFGDEF_H
+#define __CFGDEF_H
+
+/*
+ * CFG Control Flag definitions
+ */
+#define CFG_CTL_VALID         0x00010000
+#define CFG_CTL_RE            0x00020000
+#define CFG_CTL_WE            0x00040000
+#define CFG_CTL_INT           0x00080000
+#define CFG_CTL_SAVE          0x00100000
+#define CFG_CTL_RESTART       0x00200000
+#define CFG_CTL_RELOAD        0x00400000
+#define CFG_CTL_NTF_PHY       0x00800000
+#define CFG_CTL_NTF_MAC       0x01000000
+#define CFG_CTL_NTF_LOG       0x02000000
+#define CFG_CTL_NTF_TARGET    0x04000000
+#define CFG_CTL_NTF_DPH       0x08000000
+#define CFG_CTL_NTF_ARQ       0x10000000
+#define CFG_CTL_NTF_SCH       0x20000000
+#define CFG_CTL_NTF_LIM       0x40000000
+#define CFG_CTL_NTF_HDD       0x80000000
+#define CFG_CTL_NTF_MASK      0xFFE00000
+
+#define CFG_CTL_NTF_TFP       CFG_CTL_NTF_MAC
+#define CFG_CTL_NTF_RHP       CFG_CTL_NTF_MAC
+#define CFG_CTL_NTF_RFP       CFG_CTL_NTF_MAC
+#define CFG_CTL_NTF_SP        CFG_CTL_NTF_MAC
+#define CFG_CTL_NTF_HW        (CFG_CTL_NTF_MAC | CFG_CTL_NTF_PHY)
+
+#define CFG_BUF_INDX_MASK     0x00000fff
+
+#endif /* __CFGDEF_H */
diff --git a/core/mac/src/cfg/cfg_param_name.c b/core/mac/src/cfg/cfg_param_name.c
new file mode 100644
index 0000000..0a90da1
--- /dev/null
+++ b/core/mac/src/cfg/cfg_param_name.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * DO NOT EDIT - This file is generated automatically
+ */
+
+/*
+ * IMPORTANT:  This file is for system that supports STA mode ONLY.
+ */
+#include "cfg_priv.h"
+
+/**
+ * cfg_get_string() - return string conversion of HE WNI CFG
+ * @cfg_id: Config ID.
+ *
+ * This utility function helps log string conversion of WNI config ID.
+ *
+ * Return: string conversion of the HE WNI config ID, if match found;
+ *	"Invalid" otherwise.
+ */
+const char *cfg_get_string(uint16_t cfg_id)
+{
+	switch (cfg_id) {
+	default:
+		break;
+	CASE_RETURN_STRING(WNI_CFG_STA_ID);
+	CASE_RETURN_STRING(WNI_CFG_SSID);
+	CASE_RETURN_STRING(WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME);
+	CASE_RETURN_STRING(WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME);
+	CASE_RETURN_STRING(WNI_CFG_DOT11_MODE);
+	CASE_RETURN_STRING(WNI_CFG_VALID_CHANNEL_LIST);
+	CASE_RETURN_STRING(WNI_CFG_APSD_ENABLED);
+	CASE_RETURN_STRING(WNI_CFG_11D_ENABLED);
+	CASE_RETURN_STRING(WNI_CFG_MAX_TX_POWER_2_4);
+	CASE_RETURN_STRING(WNI_CFG_MAX_TX_POWER_5);
+	CASE_RETURN_STRING(WNI_CFG_CURRENT_TX_POWER_LEVEL);
+	CASE_RETURN_STRING(WNI_CFG_COUNTRY_CODE);
+	CASE_RETURN_STRING(WNI_CFG_11H_ENABLED);
+	CASE_RETURN_STRING(WNI_CFG_LOCAL_POWER_CONSTRAINT);
+	CASE_RETURN_STRING(WNI_CFG_SCAN_CONTROL_LIST);
+	CASE_RETURN_STRING(WNI_CFG_TX_BF_CAP);
+	CASE_RETURN_STRING(WNI_CFG_AS_CAP);
+	CASE_RETURN_STRING(WNI_CFG_IBSS_AUTO_BSSID);
+	CASE_RETURN_STRING(WNI_CFG_WPS_UUID);
+	CASE_RETURN_STRING(WNI_CFG_TELE_BCN_WAKEUP_EN);
+	CASE_RETURN_STRING(WNI_CFG_TELE_BCN_MAX_LI);
+	CASE_RETURN_STRING(WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED);
+	CASE_RETURN_STRING(WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP);
+	CASE_RETURN_STRING(WNI_CFG_IBSS_ATIM_WIN_SIZE);
+	CASE_RETURN_STRING(WNI_CFG_HE_CONTROL);
+	CASE_RETURN_STRING(WNI_CFG_HE_TWT_REQUESTOR);
+	CASE_RETURN_STRING(WNI_CFG_HE_TWT_RESPONDER);
+	CASE_RETURN_STRING(WNI_CFG_HE_FRAGMENTATION);
+	CASE_RETURN_STRING(WNI_CFG_HE_MAX_FRAG_MSDU);
+	CASE_RETURN_STRING(WNI_CFG_HE_MIN_FRAG_SIZE);
+	CASE_RETURN_STRING(WNI_CFG_HE_TRIG_PAD);
+	CASE_RETURN_STRING(WNI_CFG_HE_MTID_AGGR_RX);
+	CASE_RETURN_STRING(WNI_CFG_HE_MTID_AGGR_TX);
+	CASE_RETURN_STRING(WNI_CFG_HE_LINK_ADAPTATION);
+	CASE_RETURN_STRING(WNI_CFG_HE_ALL_ACK);
+	CASE_RETURN_STRING(WNI_CFG_HE_TRIGD_RSP_SCHEDULING);
+	CASE_RETURN_STRING(WNI_CFG_HE_BUFFER_STATUS_RPT);
+	CASE_RETURN_STRING(WNI_CFG_HE_BCAST_TWT);
+	CASE_RETURN_STRING(WNI_CFG_HE_BA_32BIT);
+	CASE_RETURN_STRING(WNI_CFG_HE_MU_CASCADING);
+	CASE_RETURN_STRING(WNI_CFG_HE_MULTI_TID);
+	CASE_RETURN_STRING(WNI_CFG_HE_DL_MU_BA);
+	CASE_RETURN_STRING(WNI_CFG_HE_OMI);
+	CASE_RETURN_STRING(WNI_CFG_HE_OFDMA_RA);
+	CASE_RETURN_STRING(WNI_CFG_HE_MAX_AMPDU_LEN);
+	CASE_RETURN_STRING(WNI_CFG_HE_AMSDU_FRAG);
+	CASE_RETURN_STRING(WNI_CFG_HE_FLEX_TWT_SCHED);
+	CASE_RETURN_STRING(WNI_CFG_HE_RX_CTRL);
+	CASE_RETURN_STRING(WNI_CFG_HE_BSRP_AMPDU_AGGR);
+	CASE_RETURN_STRING(WNI_CFG_HE_QTP);
+	CASE_RETURN_STRING(WNI_CFG_HE_A_BQR);
+	CASE_RETURN_STRING(WNI_CFG_HE_SR_RESPONDER);
+	CASE_RETURN_STRING(WNI_CFG_HE_NDP_FEEDBACK_SUPP);
+	CASE_RETURN_STRING(WNI_CFG_HE_OPS_SUPP);
+	CASE_RETURN_STRING(WNI_CFG_HE_SUB_CH_SEL_TX);
+	CASE_RETURN_STRING(WNI_CFG_HE_UL_2X996_RU);
+	CASE_RETURN_STRING(WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX);
+	CASE_RETURN_STRING(WNI_CFG_HE_CHAN_WIDTH);
+	CASE_RETURN_STRING(WNI_CFG_HE_RX_PREAM_PUNC);
+	CASE_RETURN_STRING(WNI_CFG_HE_CLASS_OF_DEVICE);
+	CASE_RETURN_STRING(WNI_CFG_HE_LDPC);
+	CASE_RETURN_STRING(WNI_CFG_HE_LTF_PPDU);
+	CASE_RETURN_STRING(WNI_CFG_HE_LTF_NDP);
+	CASE_RETURN_STRING(WNI_CFG_HE_TX_STBC_LT80);
+	CASE_RETURN_STRING(WNI_CFG_HE_RX_STBC_LT80);
+	CASE_RETURN_STRING(WNI_CFG_HE_DOPPLER);
+	CASE_RETURN_STRING(WNI_CFG_HE_UL_MUMIMO);
+	CASE_RETURN_STRING(WNI_CFG_HE_DCM_TX);
+	CASE_RETURN_STRING(WNI_CFG_HE_DCM_RX);
+	CASE_RETURN_STRING(WNI_CFG_HE_MU_PPDU);
+	CASE_RETURN_STRING(WNI_CFG_HE_SU_BEAMFORMER);
+	CASE_RETURN_STRING(WNI_CFG_HE_SU_BEAMFORMEE);
+	CASE_RETURN_STRING(WNI_CFG_HE_MU_BEAMFORMER);
+	CASE_RETURN_STRING(WNI_CFG_HE_BFEE_STS_LT80);
+	CASE_RETURN_STRING(WNI_CFG_HE_BFEE_STS_GT80);
+	CASE_RETURN_STRING(WNI_CFG_HE_NUM_SOUND_LT80);
+	CASE_RETURN_STRING(WNI_CFG_HE_NUM_SOUND_GT80);
+	CASE_RETURN_STRING(WNI_CFG_HE_SU_FEED_TONE16);
+	CASE_RETURN_STRING(WNI_CFG_HE_MU_FEED_TONE16);
+	CASE_RETURN_STRING(WNI_CFG_HE_CODEBOOK_SU);
+	CASE_RETURN_STRING(WNI_CFG_HE_CODEBOOK_MU);
+	CASE_RETURN_STRING(WNI_CFG_HE_BFRM_FEED);
+	CASE_RETURN_STRING(WNI_CFG_HE_ER_SU_PPDU);
+	CASE_RETURN_STRING(WNI_CFG_HE_DL_PART_BW);
+	CASE_RETURN_STRING(WNI_CFG_HE_PPET_PRESENT);
+	CASE_RETURN_STRING(WNI_CFG_HE_SRP);
+	CASE_RETURN_STRING(WNI_CFG_HE_POWER_BOOST);
+	CASE_RETURN_STRING(WNI_CFG_HE_4x_LTF_GI);
+	CASE_RETURN_STRING(WNI_CFG_HE_MAX_NC);
+	CASE_RETURN_STRING(WNI_CFG_HE_TX_STBC_GT80);
+	CASE_RETURN_STRING(WNI_CFG_HE_RX_STBC_GT80);
+	CASE_RETURN_STRING(WNI_CFG_HE_ER_4x_LTF_GI);
+	CASE_RETURN_STRING(WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF);
+	CASE_RETURN_STRING(WNI_CFG_HE_DCM_MAX_BW);
+	CASE_RETURN_STRING(WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM);
+	CASE_RETURN_STRING(WNI_CFG_HE_TX_1024_QAM_LT_242_RU);
+	CASE_RETURN_STRING(WNI_CFG_HE_RX_1024_QAM_LT_242_RU);
+	CASE_RETURN_STRING(WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB);
+	CASE_RETURN_STRING(WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB);
+	CASE_RETURN_STRING(WNI_CFG_HE_RX_MCS_MAP_LT_80);
+	CASE_RETURN_STRING(WNI_CFG_HE_TX_MCS_MAP_LT_80);
+	CASE_RETURN_STRING(WNI_CFG_HE_RX_MCS_MAP_160);
+	CASE_RETURN_STRING(WNI_CFG_HE_TX_MCS_MAP_160);
+	CASE_RETURN_STRING(WNI_CFG_HE_RX_MCS_MAP_80_80);
+	CASE_RETURN_STRING(WNI_CFG_HE_TX_MCS_MAP_80_80);
+	CASE_RETURN_STRING(WNI_CFG_HE_PPET_2G);
+	CASE_RETURN_STRING(WNI_CFG_HE_PPET_5G);
+	CASE_RETURN_STRING(WNI_CFG_HE_OPS_BSS_COLOR);
+	CASE_RETURN_STRING(WNI_CFG_HE_OPS_DEFAULT_PE);
+	CASE_RETURN_STRING(WNI_CFG_HE_OPS_TWT_REQUIRED);
+	CASE_RETURN_STRING(WNI_CFG_HE_OPS_RTS_THRESHOLD);
+	CASE_RETURN_STRING(WNI_CFG_HE_OPS_PARTIAL_BSS_COL);
+	CASE_RETURN_STRING(WNI_CFG_HE_OPS_VHT_OPER_PRESENT);
+	CASE_RETURN_STRING(WNI_CFG_HE_OPS_MBSSID_AP);
+	CASE_RETURN_STRING(WNI_CFG_HE_OPS_TX_BSSID_IND);
+	CASE_RETURN_STRING(WNI_CFG_HE_OPS_BSS_COL_DISABLED);
+	CASE_RETURN_STRING(WNI_CFG_HE_OPS_BASIC_MCS_NSS);
+	CASE_RETURN_STRING(WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT);
+	CASE_RETURN_STRING(WNI_CFG_HE_STA_OBSSPD);
+	CASE_RETURN_STRING(WNI_CFG_OBSS_DETECTION_OFFLOAD);
+	CASE_RETURN_STRING(WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD);
+	CASE_RETURN_STRING(WNI_CFG_TWT_REQUESTOR);
+	CASE_RETURN_STRING(WNI_CFG_TWT_RESPONDER);
+	CASE_RETURN_STRING(WNI_CFG_BCAST_TWT);
+	}
+
+	return "invalid";
+}
diff --git a/core/mac/src/cfg/cfg_priv.h b/core/mac/src/cfg/cfg_priv.h
new file mode 100644
index 0000000..79fc0d7
--- /dev/null
+++ b/core/mac/src/cfg/cfg_priv.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011-2015 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.
+ */
+
+/*
+ *
+ * This is the private header file for CFG module.
+ *
+ * Author:        Kevin Nguyen
+ * Date:        03/20/02
+ * History:-
+ * 03/20/02        Created.
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __CFGPRIV_H
+#define __CFGPRIV_H
+
+#include <sir_common.h>
+#include <sir_types.h>
+#include <sir_debug.h>
+#include <utils_api.h>
+#include <lim_api.h>
+#include <sch_api.h>
+#include <cfg_api.h>
+#include "cfg_def.h"
+
+#include <wni_cfg.h>
+
+/*--------------------------------------------------------------------*/
+/* CFG miscellaneous definition                                       */
+/*--------------------------------------------------------------------*/
+
+/* Function index bit mask */
+#define CFG_FUNC_INDX_MASK   0x7f
+#define CFG_GET_FUNC_INDX(val) (val & CFG_FUNC_INDX_MASK)
+
+/* Macro to convert return code to debug string index */
+#define CFG_GET_DBG_INDX(val) (val - eCFG_SUCCESS - 1)
+
+/*--------------------------------------------------------------------*/
+/* Binary header structure                                            */
+/*--------------------------------------------------------------------*/
+typedef struct sCfgBinHdr {
+	uint32_t hdrInfo;
+	uint32_t controlSize;
+	uint32_t iBufSize;
+	uint32_t sBufSize;
+} tCfgBinHdr, *tpCfgBinHdr;
+
+/*--------------------------------------------------------------------*/
+/* Polaris HW counter access structure                                */
+/*--------------------------------------------------------------------*/
+
+#define CFG_STAT_CNT_LO_MASK       0x0000ffff
+#define CFG_STAT_CNT_HI_MASK       0xffff0000
+#define CFG_STAT_CNT_HI_INCR       0x00010000
+
+/*--------------------------------------------------------------------*/
+/* CFG function prototypes                                            */
+/*--------------------------------------------------------------------*/
+
+extern void cfg_send_host_msg(tpAniSirGlobal, uint16_t, uint32_t, uint32_t,
+			      uint32_t *, uint32_t, uint32_t *);
+
+#endif /* __CFGPRIV_H */
diff --git a/core/mac/src/cfg/cfg_proc_msg.c b/core/mac/src/cfg/cfg_proc_msg.c
new file mode 100644
index 0000000..21564bf
--- /dev/null
+++ b/core/mac/src/cfg/cfg_proc_msg.c
@@ -0,0 +1,1209 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * This file contains CFG functions for processing host messages.
+ */
+#include "cds_api.h"
+#include "ani_global.h"
+#include "cfg_priv.h"
+#include "wma_types.h"
+#include "lim_trace.h"
+
+cgstatic cfg_static[CFG_PARAM_MAX_NUM] = {
+	{WNI_CFG_STA_ID,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RELOAD,
+	0, 255, 1},
+	{WNI_CFG_SSID,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+	0, 255, 6},
+	{WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMIN,
+	WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMAX,
+	WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STADEF},
+	{WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMIN,
+	WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMAX,
+	WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STADEF},
+	{WNI_CFG_DOT11_MODE,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART |
+	CFG_CTL_NTF_LIM,
+	WNI_CFG_DOT11_MODE_STAMIN,
+	WNI_CFG_DOT11_MODE_STAMAX,
+	WNI_CFG_DOT11_MODE_STADEF},
+	{WNI_CFG_VALID_CHANNEL_LIST,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART |
+	CFG_CTL_NTF_LIM,
+	0, 1, 1},
+	{WNI_CFG_APSD_ENABLED,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_APSD_ENABLED_STAMIN,
+	WNI_CFG_APSD_ENABLED_STAMAX,
+	WNI_CFG_APSD_ENABLED_STADEF},
+	{WNI_CFG_11D_ENABLED,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+	CFG_CTL_RESTART,
+	WNI_CFG_11D_ENABLED_STAMIN,
+	WNI_CFG_11D_ENABLED_STAMAX,
+	WNI_CFG_11D_ENABLED_STADEF},
+	{WNI_CFG_MAX_TX_POWER_2_4,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+	0, 0, 0},
+	{WNI_CFG_MAX_TX_POWER_5,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+	0, 0, 0},
+	{WNI_CFG_CURRENT_TX_POWER_LEVEL,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMIN,
+	WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX,
+	WNI_CFG_CURRENT_TX_POWER_LEVEL_STADEF},
+	{WNI_CFG_COUNTRY_CODE,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_NTF_SCH,
+	0, 0, 0},
+	{WNI_CFG_11H_ENABLED,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+	CFG_CTL_RESTART,
+	WNI_CFG_11H_ENABLED_STAMIN,
+	WNI_CFG_11H_ENABLED_STAMAX,
+	WNI_CFG_11H_ENABLED_STADEF},
+	{WNI_CFG_LOCAL_POWER_CONSTRAINT,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+	CFG_CTL_RESTART,
+	WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMIN,
+	WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMAX,
+	WNI_CFG_LOCAL_POWER_CONSTRAINT_STADEF},
+	{WNI_CFG_SCAN_CONTROL_LIST,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART |
+	CFG_CTL_NTF_LIM,
+	0, 0, 0},
+	{WNI_CFG_TX_BF_CAP,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT | CFG_CTL_RESTART |
+	CFG_CTL_NTF_LIM,
+	WNI_CFG_TX_BF_CAP_STAMIN,
+	4294967295u,
+	WNI_CFG_TX_BF_CAP_STADEF},
+	{WNI_CFG_AS_CAP,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_SAVE |
+	CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+	WNI_CFG_AS_CAP_STAMIN,
+	WNI_CFG_AS_CAP_STAMAX,
+	WNI_CFG_AS_CAP_STADEF},
+	{WNI_CFG_SCAN_IN_POWERSAVE,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+	CFG_CTL_NTF_LIM,
+	WNI_CFG_SCAN_IN_POWERSAVE_STAMIN,
+	WNI_CFG_SCAN_IN_POWERSAVE_STAMAX,
+	WNI_CFG_SCAN_IN_POWERSAVE_STADEF},
+	{WNI_CFG_IBSS_AUTO_BSSID,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_IBSS_AUTO_BSSID_STAMIN,
+	WNI_CFG_IBSS_AUTO_BSSID_STAMAX,
+	WNI_CFG_IBSS_AUTO_BSSID_STADEF},
+	{WNI_CFG_WPS_UUID,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_NTF_LIM,
+	0, 0, 0},
+	{WNI_CFG_TELE_BCN_WAKEUP_EN,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_TELE_BCN_WAKEUP_EN_STAMIN,
+	WNI_CFG_TELE_BCN_WAKEUP_EN_STAMAX,
+	WNI_CFG_TELE_BCN_WAKEUP_EN_STADEF},
+	{WNI_CFG_TELE_BCN_MAX_LI,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_TELE_BCN_MAX_LI_STAMIN,
+	WNI_CFG_TELE_BCN_MAX_LI_STAMAX,
+	WNI_CFG_TELE_BCN_MAX_LI_STADEF},
+	{WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMIN,
+	WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX,
+	WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STADEF},
+	{WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMIN,
+	WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMAX,
+	WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STADEF},
+	{WNI_CFG_IBSS_ATIM_WIN_SIZE,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_IBSS_ATIM_WIN_SIZE_STAMIN,
+	WNI_CFG_IBSS_ATIM_WIN_SIZE_STAMAX,
+	WNI_CFG_IBSS_ATIM_WIN_SIZE_STADEF},
+	{WNI_CFG_HE_CONTROL,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_CONTROL_STAMIN, WNI_CFG_HE_CONTROL_STAMAX,
+	WNI_CFG_HE_CONTROL_STADEF},
+	{WNI_CFG_HE_TWT_REQUESTOR,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_TWT_REQUESTOR_STAMIN, WNI_CFG_HE_TWT_REQUESTOR_STAMAX,
+	WNI_CFG_HE_TWT_REQUESTOR_STADEF},
+	{WNI_CFG_HE_TWT_RESPONDER,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_TWT_RESPONDER_STAMIN, WNI_CFG_HE_TWT_RESPONDER_STAMAX,
+	WNI_CFG_HE_TWT_RESPONDER_STADEF},
+	{WNI_CFG_HE_FRAGMENTATION,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_FRAGMENTATION_STAMIN, WNI_CFG_HE_FRAGMENTATION_STAMAX,
+	WNI_CFG_HE_FRAGMENTATION_STADEF},
+	{WNI_CFG_HE_MAX_FRAG_MSDU,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MAX_FRAG_MSDU_STAMIN, WNI_CFG_HE_MAX_FRAG_MSDU_STAMAX,
+	WNI_CFG_HE_MAX_FRAG_MSDU_STADEF},
+	{WNI_CFG_HE_MIN_FRAG_SIZE,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MIN_FRAG_SIZE_STAMIN, WNI_CFG_HE_MIN_FRAG_SIZE_STAMAX,
+	WNI_CFG_HE_MIN_FRAG_SIZE_STADEF},
+	{WNI_CFG_HE_TRIG_PAD,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_TRIG_PAD_STAMIN, WNI_CFG_HE_TRIG_PAD_STAMAX,
+	WNI_CFG_HE_TRIG_PAD_STADEF},
+	{WNI_CFG_HE_MTID_AGGR_RX,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MTID_AGGR_RX_STAMIN, WNI_CFG_HE_MTID_AGGR_RX_STAMAX,
+	WNI_CFG_HE_MTID_AGGR_RX_STADEF},
+	{WNI_CFG_HE_LINK_ADAPTATION,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_LINK_ADAPTATION_STAMIN, WNI_CFG_HE_LINK_ADAPTATION_STAMAX,
+	WNI_CFG_HE_LINK_ADAPTATION_STADEF},
+	{WNI_CFG_HE_ALL_ACK,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_ALL_ACK_STAMIN, WNI_CFG_HE_ALL_ACK_STAMAX,
+	WNI_CFG_HE_ALL_ACK_STADEF},
+	{WNI_CFG_HE_TRIGD_RSP_SCHEDULING,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_TRIGD_RSP_SCHEDULING_STAMIN,
+	WNI_CFG_HE_TRIGD_RSP_SCHEDULING_STAMAX,
+	WNI_CFG_HE_TRIGD_RSP_SCHEDULING_STADEF},
+	{WNI_CFG_HE_BUFFER_STATUS_RPT,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_BUFFER_STATUS_RPT_STAMIN,
+	WNI_CFG_HE_BUFFER_STATUS_RPT_STAMAX,
+	WNI_CFG_HE_BUFFER_STATUS_RPT_STADEF},
+	{WNI_CFG_HE_BCAST_TWT,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_BCAST_TWT_STAMIN, WNI_CFG_HE_BCAST_TWT_STAMAX,
+	WNI_CFG_HE_BCAST_TWT_STADEF},
+	{WNI_CFG_HE_BA_32BIT,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_BA_32BIT_STAMIN, WNI_CFG_HE_BA_32BIT_STAMAX,
+	WNI_CFG_HE_BA_32BIT_STADEF},
+	{WNI_CFG_HE_MU_CASCADING,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MU_CASCADING_STAMIN, WNI_CFG_HE_MU_CASCADING_STAMAX,
+	WNI_CFG_HE_MU_CASCADING_STADEF},
+	{WNI_CFG_HE_MULTI_TID,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MULTI_TID_STAMIN, WNI_CFG_HE_MULTI_TID_STAMAX,
+	WNI_CFG_HE_MULTI_TID_STADEF},
+	{WNI_CFG_HE_DL_MU_BA,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_DL_MU_BA_STAMIN, WNI_CFG_HE_DL_MU_BA_STAMAX,
+	WNI_CFG_HE_DL_MU_BA_STADEF},
+	{WNI_CFG_HE_OMI,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OMI_STAMIN, WNI_CFG_HE_OMI_STAMAX,
+	WNI_CFG_HE_OMI_STADEF},
+	{WNI_CFG_HE_OFDMA_RA,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OFDMA_RA_STAMIN, WNI_CFG_HE_OFDMA_RA_STAMAX,
+	WNI_CFG_HE_OFDMA_RA_STADEF},
+	{WNI_CFG_HE_MAX_AMPDU_LEN,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MAX_AMPDU_LEN_STAMIN, WNI_CFG_HE_MAX_AMPDU_LEN_STAMAX,
+	WNI_CFG_HE_MAX_AMPDU_LEN_STADEF},
+	{WNI_CFG_HE_AMSDU_FRAG,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_AMSDU_FRAG_STAMIN, WNI_CFG_HE_AMSDU_FRAG_STAMAX,
+	WNI_CFG_HE_AMSDU_FRAG_STADEF},
+	{WNI_CFG_HE_FLEX_TWT_SCHED,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_FLEX_TWT_SCHED_STAMIN, WNI_CFG_HE_FLEX_TWT_SCHED_STAMAX,
+	WNI_CFG_HE_FLEX_TWT_SCHED_STADEF},
+	{WNI_CFG_HE_RX_CTRL,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_RX_CTRL_STAMIN, WNI_CFG_HE_RX_CTRL_STAMAX,
+	WNI_CFG_HE_RX_CTRL_STADEF},
+	{WNI_CFG_HE_BSRP_AMPDU_AGGR,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_BSRP_AMPDU_AGGR_STAMIN, WNI_CFG_HE_BSRP_AMPDU_AGGR_STAMAX,
+	WNI_CFG_HE_BSRP_AMPDU_AGGR_STADEF},
+	{WNI_CFG_HE_QTP,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_QTP_STAMIN, WNI_CFG_HE_QTP_STAMAX,
+	WNI_CFG_HE_QTP_STADEF},
+	{WNI_CFG_HE_A_BQR,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_A_BQR_STAMIN, WNI_CFG_HE_A_BQR_STAMAX,
+	WNI_CFG_HE_A_BQR_STADEF},
+	{WNI_CFG_HE_SR_RESPONDER,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_SR_RESPONDER_STAMIN, WNI_CFG_HE_SR_RESPONDER_STAMAX,
+	WNI_CFG_HE_SR_RESPONDER_STADEF},
+	{WNI_CFG_HE_NDP_FEEDBACK_SUPP,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_NDP_FEEDBACK_SUPP_STAMIN,
+	WNI_CFG_HE_NDP_FEEDBACK_SUPP_STAMAX,
+	WNI_CFG_HE_NDP_FEEDBACK_SUPP_STADEF},
+	{WNI_CFG_HE_AMSDU_IN_AMPDU,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_AMSDU_IN_AMPDU_MIN,
+	WNI_CFG_HE_AMSDU_IN_AMPDU_MAX,
+	WNI_CFG_HE_AMSDU_IN_AMPDU_DEF},
+	{WNI_CFG_HE_MTID_AGGR_TX,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MTID_AGGR_TX_MIN,
+	WNI_CFG_HE_MTID_AGGR_TX_MAX,
+	WNI_CFG_HE_MTID_AGGR_TX_DEF},
+	{WNI_CFG_HE_SUB_CH_SEL_TX,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_SUB_CH_SEL_TX_MIN,
+	WNI_CFG_HE_SUB_CH_SEL_TX_MAX,
+	WNI_CFG_HE_SUB_CH_SEL_TX_DEF},
+	{WNI_CFG_HE_UL_2X996_RU,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_UL_2X996_RU_MIN,
+	WNI_CFG_HE_UL_2X996_RU_MAX,
+	WNI_CFG_HE_UL_2X996_RU_DEF},
+	{WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX_MIN,
+	WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX_MAX,
+	WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX_DEF},
+	{WNI_CFG_HE_A_BQR,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_A_BQR_STAMIN, WNI_CFG_HE_A_BQR_STAMAX,
+	WNI_CFG_HE_A_BQR_STADEF},
+	{WNI_CFG_HE_CHAN_WIDTH,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_CHAN_WIDTH_STAMIN, WNI_CFG_HE_CHAN_WIDTH_STAMAX,
+	WNI_CFG_HE_CHAN_WIDTH_STADEF},
+	{WNI_CFG_HE_RX_PREAM_PUNC,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_RX_PREAM_PUNC_STAMIN, WNI_CFG_HE_RX_PREAM_PUNC_STAMAX,
+	WNI_CFG_HE_RX_PREAM_PUNC_STADEF},
+	{WNI_CFG_HE_CLASS_OF_DEVICE,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_CLASS_OF_DEVICE_STAMIN, WNI_CFG_HE_CLASS_OF_DEVICE_STAMAX,
+	WNI_CFG_HE_CLASS_OF_DEVICE_STADEF},
+	{WNI_CFG_HE_LDPC,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_LDPC_STAMIN, WNI_CFG_HE_LDPC_STAMAX,
+	WNI_CFG_HE_LDPC_STADEF},
+	{WNI_CFG_HE_LTF_PPDU,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_LTF_PPDU_STAMIN, WNI_CFG_HE_LTF_PPDU_STAMAX,
+	WNI_CFG_HE_LTF_PPDU_STADEF},
+	{WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS_MIN,
+	WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS_MAX,
+	WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS_DEF},
+	{WNI_CFG_HE_LTF_NDP,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_LTF_NDP_STAMIN, WNI_CFG_HE_LTF_NDP_STAMAX,
+	WNI_CFG_HE_LTF_NDP_STADEF},
+	{WNI_CFG_HE_TX_STBC_LT80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_TX_STBC_LT80_STAMIN, WNI_CFG_HE_TX_STBC_LT80_STAMAX,
+	WNI_CFG_HE_TX_STBC_LT80_STADEF},
+	{WNI_CFG_HE_RX_STBC_LT80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_RX_STBC_LT80_STAMIN, WNI_CFG_HE_RX_STBC_LT80_STAMAX,
+	WNI_CFG_HE_RX_STBC_LT80_STADEF},
+	{WNI_CFG_HE_DOPPLER,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_DOPPLER_STAMIN, WNI_CFG_HE_DOPPLER_STAMAX,
+	WNI_CFG_HE_DOPPLER_STADEF},
+	{WNI_CFG_HE_UL_MUMIMO,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_UL_MUMIMO_STAMIN, WNI_CFG_HE_UL_MUMIMO_STAMAX,
+	WNI_CFG_HE_UL_MUMIMO_STADEF},
+	{WNI_CFG_HE_DCM_TX,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_DCM_TX_STAMIN, WNI_CFG_HE_DCM_TX_STAMAX,
+	WNI_CFG_HE_DCM_TX_STADEF},
+	{WNI_CFG_HE_DCM_RX,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_DCM_RX_STAMIN, WNI_CFG_HE_DCM_RX_STAMAX,
+	WNI_CFG_HE_DCM_RX_STADEF},
+	{WNI_CFG_HE_MU_PPDU,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MU_PPDU_STAMIN, WNI_CFG_HE_MU_PPDU_STAMAX,
+	WNI_CFG_HE_MU_PPDU_STADEF},
+	{WNI_CFG_HE_SU_BEAMFORMER,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_SU_BEAMFORMER_STAMIN, WNI_CFG_HE_SU_BEAMFORMER_STAMAX,
+	WNI_CFG_HE_SU_BEAMFORMER_STADEF},
+	{WNI_CFG_HE_SU_BEAMFORMEE,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_SU_BEAMFORMEE_STAMIN, WNI_CFG_HE_SU_BEAMFORMEE_STAMAX,
+	WNI_CFG_HE_SU_BEAMFORMEE_STADEF},
+	{WNI_CFG_HE_MU_BEAMFORMER,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MU_BEAMFORMER_STAMIN, WNI_CFG_HE_MU_BEAMFORMER_STAMAX,
+	WNI_CFG_HE_MU_BEAMFORMER_STADEF},
+	{WNI_CFG_HE_BFEE_STS_LT80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_BFEE_STS_LT80_STAMIN, WNI_CFG_HE_BFEE_STS_LT80_STAMAX,
+	WNI_CFG_HE_BFEE_STS_LT80_STADEF},
+	{WNI_CFG_HE_BFEE_STS_GT80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_BFEE_STS_GT80_STAMIN, WNI_CFG_HE_BFEE_STS_GT80_STAMAX,
+	WNI_CFG_HE_BFEE_STS_GT80_STADEF},
+	{WNI_CFG_HE_NUM_SOUND_LT80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_NUM_SOUND_LT80_STAMIN, WNI_CFG_HE_NUM_SOUND_LT80_STAMAX,
+	WNI_CFG_HE_NUM_SOUND_LT80_STADEF},
+	{WNI_CFG_HE_NUM_SOUND_GT80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_NUM_SOUND_GT80_STAMIN, WNI_CFG_HE_NUM_SOUND_GT80_STAMAX,
+	WNI_CFG_HE_NUM_SOUND_GT80_STADEF},
+	{WNI_CFG_HE_SU_FEED_TONE16,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_SU_FEED_TONE16_STAMIN, WNI_CFG_HE_SU_FEED_TONE16_STAMAX,
+	WNI_CFG_HE_SU_FEED_TONE16_STADEF},
+	{WNI_CFG_HE_MU_FEED_TONE16,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MU_FEED_TONE16_STAMIN, WNI_CFG_HE_MU_FEED_TONE16_STAMAX,
+	WNI_CFG_HE_MU_FEED_TONE16_STADEF},
+	{WNI_CFG_HE_CODEBOOK_SU,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_CODEBOOK_SU_STAMIN, WNI_CFG_HE_CODEBOOK_SU_STAMAX,
+	WNI_CFG_HE_CODEBOOK_SU_STADEF},
+	{WNI_CFG_HE_CODEBOOK_MU,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_CODEBOOK_MU_STAMIN, WNI_CFG_HE_CODEBOOK_MU_STAMAX,
+	WNI_CFG_HE_CODEBOOK_MU_STADEF},
+	{WNI_CFG_HE_BFRM_FEED,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_BFRM_FEED_STAMIN, WNI_CFG_HE_BFRM_FEED_STAMAX,
+	WNI_CFG_HE_BFRM_FEED_STADEF},
+	{WNI_CFG_HE_ER_SU_PPDU,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_ER_SU_PPDU_STAMIN, WNI_CFG_HE_ER_SU_PPDU_STAMAX,
+	WNI_CFG_HE_ER_SU_PPDU_STADEF},
+	{WNI_CFG_HE_DL_PART_BW,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_DL_PART_BW_STAMIN, WNI_CFG_HE_DL_PART_BW_STAMAX,
+	WNI_CFG_HE_DL_PART_BW_STADEF},
+	{WNI_CFG_HE_PPET_PRESENT,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_PPET_PRESENT_STAMIN, WNI_CFG_HE_PPET_PRESENT_STAMAX,
+	WNI_CFG_HE_PPET_PRESENT_STADEF},
+	{WNI_CFG_HE_SRP,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_SRP_STAMIN, WNI_CFG_HE_SRP_STAMAX,
+	WNI_CFG_HE_SRP_STADEF},
+	{WNI_CFG_HE_POWER_BOOST,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_POWER_BOOST_STAMIN, WNI_CFG_HE_POWER_BOOST_STAMAX,
+	WNI_CFG_HE_POWER_BOOST_STADEF},
+	{WNI_CFG_HE_4x_LTF_GI,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_4x_LTF_GI_STAMIN, WNI_CFG_HE_4x_LTF_GI_STAMAX,
+	WNI_CFG_HE_4x_LTF_GI_STADEF},
+	{WNI_CFG_HE_MAX_NC,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MAX_NC_STAMIN, WNI_CFG_HE_MAX_NC_STAMAX,
+	WNI_CFG_HE_MAX_NC_STADEF},
+	{WNI_CFG_HE_TX_STBC_GT80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_TX_STBC_GT80_STAMIN, WNI_CFG_HE_TX_STBC_GT80_STAMAX,
+	WNI_CFG_HE_TX_STBC_GT80_STADEF},
+	{WNI_CFG_HE_RX_STBC_GT80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_RX_STBC_GT80_STAMIN, WNI_CFG_HE_RX_STBC_GT80_STAMAX,
+	WNI_CFG_HE_RX_STBC_GT80_STADEF},
+	{WNI_CFG_HE_ER_4x_LTF_GI,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_ER_4x_LTF_GI_STAMIN, WNI_CFG_HE_ER_4x_LTF_GI_STAMAX,
+	WNI_CFG_HE_ER_4x_LTF_GI_STADEF},
+
+	{WNI_CFG_HE_PPDU_20_IN_40MHZ_2G,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_PPDU_20_IN_40MHZ_2G_MIN, WNI_CFG_HE_PPDU_20_IN_40MHZ_2G_MAX,
+	WNI_CFG_HE_PPDU_20_IN_40MHZ_2G_DEF},
+	{WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ_MIN,
+	WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ_MAX,
+	WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ_DEF},
+	{WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ_MIN,
+	WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ_MAX,
+	WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ_DEF},
+	{WNI_CFG_HE_ER_1X_HE_LTF_GI,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_ER_1X_HE_LTF_GI_MIN, WNI_CFG_HE_ER_1X_HE_LTF_GI_MAX,
+	WNI_CFG_HE_ER_1X_HE_LTF_GI_DEF},
+	{WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF_MIN,
+	WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF_MAX,
+	WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF_DEF},
+	{WNI_CFG_HE_DCM_MAX_BW,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_DCM_MAX_BW_MIN,
+	WNI_CFG_HE_DCM_MAX_BW_MAX,
+	WNI_CFG_HE_DCM_MAX_BW_DEF},
+	{WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM_MIN,
+	WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM_MAX,
+	WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM_DEF},
+	{WNI_CFG_HE_TX_1024_QAM_LT_242_RU,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_TX_1024_QAM_LT_242_RU_MIN,
+	WNI_CFG_HE_TX_1024_QAM_LT_242_RU_MAX,
+	WNI_CFG_HE_TX_1024_QAM_LT_242_RU_DEF},
+	{WNI_CFG_HE_RX_1024_QAM_LT_242_RU,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_RX_1024_QAM_LT_242_RU_MIN,
+	WNI_CFG_HE_RX_1024_QAM_LT_242_RU_MAX,
+	WNI_CFG_HE_RX_1024_QAM_LT_242_RU_DEF},
+	{WNI_CFG_HE_NON_TRIG_CQI_FEEDBACK,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_NON_TRIG_CQI_FEEDBACK_MIN,
+	WNI_CFG_HE_NON_TRIG_CQI_FEEDBACK_MAX,
+	WNI_CFG_HE_NON_TRIG_CQI_FEEDBACK_DEF},
+	{WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB_MIN,
+	WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB_MAX,
+	WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB_DEF},
+	{WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB_MIN,
+	WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB_MAX,
+	WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB_DEF},
+
+	{WNI_CFG_HE_RX_MCS_MAP_LT_80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_RX_MCS_MAP_LT_80_MIN, WNI_CFG_HE_RX_MCS_MAP_LT_80_MAX,
+	WNI_CFG_HE_RX_MCS_MAP_LT_80_DEF},
+
+	{WNI_CFG_HE_TX_MCS_MAP_LT_80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_TX_MCS_MAP_LT_80_MIN, WNI_CFG_HE_TX_MCS_MAP_LT_80_MAX,
+	WNI_CFG_HE_TX_MCS_MAP_LT_80_DEF},
+
+	{WNI_CFG_HE_RX_MCS_MAP_160,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_RX_MCS_MAP_160_MIN, WNI_CFG_HE_RX_MCS_MAP_160_MAX,
+	WNI_CFG_HE_RX_MCS_MAP_160_DEF},
+
+	{WNI_CFG_HE_TX_MCS_MAP_160,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_TX_MCS_MAP_160_MIN, WNI_CFG_HE_TX_MCS_MAP_160_MAX,
+	WNI_CFG_HE_TX_MCS_MAP_160_DEF},
+
+	{WNI_CFG_HE_RX_MCS_MAP_80_80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_RX_MCS_MAP_80_80_MIN, WNI_CFG_HE_RX_MCS_MAP_80_80_MAX,
+	WNI_CFG_HE_RX_MCS_MAP_80_80_DEF},
+
+	{WNI_CFG_HE_TX_MCS_MAP_80_80,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_TX_MCS_MAP_80_80_MIN, WNI_CFG_HE_TX_MCS_MAP_80_80_MAX,
+	WNI_CFG_HE_TX_MCS_MAP_80_80_DEF},
+
+	{WNI_CFG_HE_PPET_2G,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+	0, 0, 0},
+	{WNI_CFG_HE_PPET_5G,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+	0, 0, 0},
+
+	{WNI_CFG_HE_OPS_BSS_COLOR,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OPS_BSS_COLOR_MIN, WNI_CFG_HE_OPS_BSS_COLOR_MAX,
+	WNI_CFG_HE_OPS_BSS_COLOR_DEF},
+
+	{WNI_CFG_HE_OPS_DEFAULT_PE,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OPS_DEFAULT_PE_MIN, WNI_CFG_HE_OPS_DEFAULT_PE_MAX,
+	WNI_CFG_HE_OPS_DEFAULT_PE_DEF},
+
+	{WNI_CFG_HE_OPS_TWT_REQUIRED,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OPS_TWT_REQUIRED_MIN, WNI_CFG_HE_OPS_TWT_REQUIRED_MAX,
+	WNI_CFG_HE_OPS_TWT_REQUIRED_DEF},
+
+	{WNI_CFG_HE_OPS_RTS_THRESHOLD,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OPS_RTS_THRESHOLD_MIN, WNI_CFG_HE_OPS_RTS_THRESHOLD_MAX,
+	WNI_CFG_HE_OPS_RTS_THRESHOLD_DEF},
+
+	{WNI_CFG_HE_OPS_PARTIAL_BSS_COL,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OPS_PARTIAL_BSS_COL_MIN, WNI_CFG_HE_OPS_PARTIAL_BSS_COL_MAX,
+	WNI_CFG_HE_OPS_PARTIAL_BSS_COL_DEF},
+
+	{WNI_CFG_HE_OPS_VHT_OPER_PRESENT,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OPS_VHT_OPER_PRESENT_MIN,
+	WNI_CFG_HE_OPS_VHT_OPER_PRESENT_MAX,
+	WNI_CFG_HE_OPS_VHT_OPER_PRESENT_DEF},
+
+	{WNI_CFG_HE_OPS_MBSSID_AP,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OPS_MBSSID_AP_MIN, WNI_CFG_HE_OPS_MBSSID_AP_MAX,
+	WNI_CFG_HE_OPS_MBSSID_AP_DEF},
+
+	{WNI_CFG_HE_OPS_TX_BSSID_IND,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OPS_TX_BSSID_IND_MIN, WNI_CFG_HE_OPS_TX_BSSID_IND_MAX,
+	WNI_CFG_HE_OPS_TX_BSSID_IND_DEF},
+
+	{WNI_CFG_HE_OPS_BSS_COL_DISABLED,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OPS_BSS_COL_DISABLED_MIN,
+	WNI_CFG_HE_OPS_BSS_COL_DISABLED_MAX,
+	WNI_CFG_HE_OPS_BSS_COL_DISABLED_DEF},
+
+	{WNI_CFG_HE_OPS_BASIC_MCS_NSS,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_OPS_BASIC_MCS_NSS_MIN, WNI_CFG_HE_OPS_BASIC_MCS_NSS_MAX,
+	WNI_CFG_HE_OPS_BASIC_MCS_NSS_DEF},
+
+	{WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT_STAMIN,
+	WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT_STAMAX,
+	WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT_STADEF},
+	{WNI_CFG_HE_STA_OBSSPD,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_HE_STA_OBSSPD_STAMIN, WNI_CFG_HE_STA_OBSSPD_STAMAX,
+	WNI_CFG_HE_STA_OBSSPD_STADEF},
+	{WNI_CFG_OBSS_DETECTION_OFFLOAD,
+	 CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	 0, 1, 0},
+	{WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD,
+	 CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	 0, 1, 0},
+	{WNI_CFG_TWT_REQUESTOR,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_TWT_REQUESTOR_STAMIN, WNI_CFG_TWT_REQUESTOR_STAMAX,
+	WNI_CFG_TWT_REQUESTOR_STADEF},
+	{WNI_CFG_TWT_RESPONDER,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_TWT_RESPONDER_STAMIN, WNI_CFG_TWT_RESPONDER_STAMAX,
+	WNI_CFG_TWT_RESPONDER_STADEF},
+	{WNI_CFG_BCAST_TWT,
+	CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+	WNI_CFG_BCAST_TWT_STAMIN, WNI_CFG_BCAST_TWT_STAMAX,
+	WNI_CFG_BCAST_TWT_STADEF},
+};
+
+
+cfgstatic_string cfg_static_string[CFG_MAX_STATIC_STRING] = {
+
+	{WNI_CFG_STA_ID,
+	WNI_CFG_STA_ID_LEN,
+	6,
+	{0x22, 0x22, 0x44, 0x44, 0x33, 0x33} },
+	{WNI_CFG_SSID,
+	WNI_CFG_SSID_LEN,
+	10,
+	{1, 2, 3, 4, 5, 6, 7, 8, 9, 0} },
+	{WNI_CFG_VALID_CHANNEL_LIST,
+	WNI_CFG_VALID_CHANNEL_LIST_LEN,
+	55,
+	{36, 40, 44, 48, 52, 56, 60, 64, 1, 6, 11, 34, 38, 42, 46, 2, 3, 4,
+	 5, 7, 8, 9, 10, 12, 13, 14, 100, 104, 108, 112, 116, 120, 124, 128,
+	 132, 136, 140, 149, 151, 153, 155, 157, 159, 161, 50, 54, 58, 62, 240,
+	 242, 244, 246, 248, 250, 252} },
+	{WNI_CFG_MAX_TX_POWER_2_4,
+	WNI_CFG_MAX_TX_POWER_2_4_LEN,
+	3,
+	{0x1, 0xe, 0x14} },
+	{WNI_CFG_MAX_TX_POWER_5,
+	WNI_CFG_MAX_TX_POWER_5_LEN,
+	3,
+	{0x24, 0x7e, 0x14} },
+	{WNI_CFG_COUNTRY_CODE,
+	WNI_CFG_COUNTRY_CODE_LEN,
+	0,
+	{0} },
+	{WNI_CFG_SCAN_CONTROL_LIST,
+	WNI_CFG_SCAN_CONTROL_LIST_LEN,
+	114,
+	{0x1, 0x1, 0x2, 0x1, 0x3, 0x1, 0x4, 0x1, 0x5, 0x1, 0x6, 0x1, 0x7, 0x1,
+	 0x8, 0x1, 0x9, 0x1, 0xa, 0x1, 0xb, 0x1, 0xc, 0x1, 0xd, 0x1, 0xe, 0x1,
+	 0x22, 0x1, 0x24, 0x1, 0x26, 0x1, 0x28, 0x1, 0x2a, 0x1, 0x2c, 0x1, 0x2e,
+	 0x1, 0x30, 0x1, 0x32, 0x1, 0x34, 0x0, 0x36, 0x0, 0x38, 0x0, 0x3a, 0x0,
+	 0x3c, 0x0, 0x3e, 0x0, 0x40, 0x0, 0x64, 0x0, 0x68, 0x0, 0x6c, 0x0, 0x70,
+	 0x0, 0x74, 0x0, 0x78, 0x0, 0x7c, 0x0, 0x80, 0x0, 0x84, 0x0, 0x88, 0x0,
+	 0x8c, 0x0, 0x90, 0x0, 0x95, 0x1, 0x97, 0x1, 0x99, 0x1, 0x9b, 0x1, 0x9d,
+	 0x1, 0x9f, 0x1, 0xa1, 0x1, 0xa5, 0x1, 0xf0, 0x1, 0xf2, 0x1, 0xf4, 0x1,
+	 0xf6, 0x1, 0xf8, 0x1, 0xfa, 0x1, 0xfc, 0x1} },
+	{WNI_CFG_WPS_UUID,
+	WNI_CFG_WPS_UUID_LEN,
+	6,
+	{0xa, 0xb, 0xc, 0xd, 0xe, 0xf} },
+	{WNI_CFG_HE_PPET_2G,
+	WNI_CFG_HE_PPET_LEN,
+	WNI_CFG_HE_PPET_LEN,
+	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+	 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} },
+	{WNI_CFG_HE_PPET_5G,
+	WNI_CFG_HE_PPET_LEN,
+	WNI_CFG_HE_PPET_LEN,
+	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+	 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} },
+};
+
+/*--------------------------------------------------------------------*/
+/* Static function prototypes                                         */
+/*--------------------------------------------------------------------*/
+static void proc_dnld_rsp(tpAniSirGlobal, uint16_t, uint32_t *);
+static void proc_get_req(tpAniSirGlobal, uint16_t, uint32_t *);
+
+static uint8_t check_param(tpAniSirGlobal, uint16_t, uint32_t, uint32_t,
+			   uint32_t *);
+/*--------------------------------------------------------------------*/
+/* Module global variables                                            */
+/*--------------------------------------------------------------------*/
+
+/* CFG function table */
+void (*g_cfg_func[])(tpAniSirGlobal, uint16_t, uint32_t *) = {
+	proc_dnld_rsp, proc_get_req
+};
+
+/**---------------------------------------------------------------------
+ * cfg_process_mb_msg()
+ *
+ ***FUNCTION:
+ * CFG mailbox message processing function.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * None.
+ *
+ ***NOTE:
+ *
+ * @param pMsg    Message pointer
+ *
+ * @return None.
+ *
+ */
+void cfg_process_mb_msg(tpAniSirGlobal pMac, tSirMbMsg *pMsg)
+{
+	uint16_t index;
+	uint16_t len;
+	uint32_t *pParam;
+
+	/* Use type[7:0] as index to function table */
+	index = CFG_GET_FUNC_INDX(pMsg->type);
+
+	if (index >= QDF_ARRAY_SIZE(g_cfg_func)) {
+		qdf_mem_free(pMsg);
+		return;
+	}
+	len = pMsg->msgLen - WNI_CFG_MB_HDR_LEN;
+	pParam = ((uint32_t *) pMsg) + 1;
+
+	/* Call processing function */
+	g_cfg_func[index] (pMac, len, pParam);
+
+	/* Free up buffer */
+	qdf_mem_free(pMsg);
+
+} /*** end cfg_process_mb_msg() ***/
+
+/**---------------------------------------------------------------------
+ * proc_dnld_rsp()
+ *
+ * FUNCTION:
+ * This function processes CFG_DNLD_RSP message from host.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param length:  message length
+ * @param pParam:  parameter list pointer
+ *
+ * @return None
+ *
+ */
+static void proc_dnld_rsp(tpAniSirGlobal pMac, uint16_t length, uint32_t *pParam)
+{
+	int32_t i;
+
+	uint32_t expLen, retVal, bufStart, bufEnd;
+	uint32_t *pSrc, *pDst, *pDstEnd;
+	uint32_t strSize, j;
+	uint8_t pStr[CFG_MAX_STR_LEN];
+	tpCfgBinHdr pHdr;
+	struct scheduler_msg mmhMsg = {0};
+
+	/* First Dword must contain the AP or STA magic dword */
+	pe_debug("CFG size: %d bytes MAGIC dword is: 0x%x",
+		       length, sir_read_u32_n((uint8_t *) pParam));
+
+	/* if the string is not correct, return failure */
+	if (*pParam == CFG_STA_MAGIC_DWORD) {
+	}
+
+	else {
+		pe_warn("Invalid magic dword: 0x%x",
+			       sir_read_u32_n((uint8_t *) pParam));
+		retVal = WNI_CFG_INVALID_LEN;
+		goto end;
+	}
+
+	pParam++;
+	length -= 4;
+
+	/* Parse the Cfg header */
+	pHdr = (tpCfgBinHdr) pParam;
+	pParam += (sizeof(tCfgBinHdr) >> 2);
+	pe_debug("CFG hdr totParams: %d intParams: %d strBufSize: %d/%d",
+		       pHdr->controlSize, pHdr->iBufSize, pHdr->sBufSize,
+		       pMac->cfg.gCfgMaxSBufSize);
+
+	if (pHdr->sBufSize > (UINT_MAX -
+		(((CFG_PARAM_MAX_NUM + 3 * pMac->cfg.gCfgMaxIBufSize) << 2) +
+		sizeof(tCfgBinHdr)))) {
+		pe_warn("Invalid sBufSize coming from fw: %d", pHdr->sBufSize);
+		retVal = WNI_CFG_INVALID_LEN;
+		goto end;
+	}
+	expLen =
+		((CFG_PARAM_MAX_NUM + 3 * pMac->cfg.gCfgMaxIBufSize) << 2) +
+		pHdr->sBufSize + sizeof(tCfgBinHdr);
+
+	if (length != expLen) {
+		pe_warn("<CFG> DNLD_RSP invalid length: %d (exp: %d)", length,
+			       expLen);
+		retVal = WNI_CFG_INVALID_LEN;
+		goto end;
+	}
+
+	if (pHdr->controlSize != CFG_PARAM_MAX_NUM) {
+		pe_warn("<CFG> Total parameter count mismatch");
+		retVal = WNI_CFG_INVALID_LEN;
+		goto end;
+	}
+
+	if (pHdr->iBufSize != pMac->cfg.gCfgMaxIBufSize) {
+		pe_warn("<CFG> Integer parameter count mismatch");
+		retVal = WNI_CFG_INVALID_LEN;
+		goto end;
+	}
+	/* Copy control array */
+	pDst = (uint32_t *) pMac->cfg.gCfgEntry;
+	pDstEnd = pDst + CFG_PARAM_MAX_NUM;
+	pSrc = pParam;
+	while (pDst < pDstEnd) {
+		*pDst++ = *pSrc++;
+	}
+	/* Copy default values */
+	pDst = pMac->cfg.gCfgIBuf;
+	pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize;
+	while (pDst < pDstEnd) {
+		*pDst++ = *pSrc++;
+	}
+
+	/* Copy min values */
+	pDst = pMac->cfg.gCfgIBufMin;
+	pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize;
+	while (pDst < pDstEnd) {
+		*pDst++ = *pSrc++;
+	}
+
+	/* Copy max values */
+	pDst = pMac->cfg.gCfgIBufMax;
+	pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize;
+	while (pDst < pDstEnd) {
+		*pDst++ = *pSrc++;
+	}
+
+	for (i = 0; i < pMac->cfg.gCfgMaxIBufSize; i++)
+		if (pMac->cfg.gCfgIBuf[i] < pMac->cfg.gCfgIBufMin[i] ||
+		    pMac->cfg.gCfgIBuf[i] > pMac->cfg.gCfgIBufMax[i]) {
+			pe_debug("cfg id: %d Invalid def value: %d min: %d max: %d",
+					i, pMac->cfg.gCfgIBuf[i],
+				       pMac->cfg.gCfgIBufMin[i],
+				       pMac->cfg.gCfgIBufMax[i]);
+		}
+	/* Calculate max string buffer lengths for all string parameters */
+	bufEnd = pMac->cfg.gCfgMaxSBufSize;
+	for (i = CFG_PARAM_MAX_NUM - 1; i >= 0; i--) {
+		if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_INT) != 0)
+			continue;
+
+		if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0)
+			continue;
+
+		bufStart = pMac->cfg.gCfgEntry[i].control & CFG_BUF_INDX_MASK;
+		pMac->cfg.gCfgSBuf[bufStart] =
+			(uint8_t) (bufEnd - bufStart - 2);
+
+		pe_debug("id: %d max: %d bufStart: %d bufEnd: %d", i,
+			       pMac->cfg.gCfgSBuf[bufStart], bufStart, bufEnd);
+		bufEnd = bufStart;
+	}
+
+	/* Initialize string defaults */
+	strSize = pHdr->sBufSize;
+	while (strSize) {
+		uint32_t paramId, paramLen, paramLenCeil4;
+
+		if (strSize < 4) {
+			pe_warn("parsing str defaults, rem: %d bytes",
+				       strSize);
+			retVal = WNI_CFG_INVALID_LEN;
+			goto end;
+		}
+		paramId = *pSrc >> 16;
+		paramLen = *pSrc & 0xff;
+		pSrc++;
+		strSize -= 4;
+
+		paramLenCeil4 = ((paramLen + 3) >> 2);
+		if (strSize < paramLenCeil4 << 2) {
+			pe_warn("parsing str defaults, rem: %d bytes",
+				       strSize);
+			pe_warn("param id: %d len: %d bytes",
+					paramId, paramLen);
+			retVal = WNI_CFG_INVALID_LEN;
+			goto end;
+		}
+		for (j = 0; j < paramLenCeil4; j++) {
+			pStr[4 * j] = (uint8_t) (*pSrc >> 24) & 0xff;
+			pStr[4 * j + 1] = (uint8_t) (*pSrc >> 16) & 0xff;
+			pStr[4 * j + 2] = (uint8_t) (*pSrc >> 8) & 0xff;
+			pStr[4 * j + 3] = (uint8_t) (*pSrc) & 0xff;
+
+			pSrc++;
+			strSize -= 4;
+		}
+
+		pe_debug("set str id: %d len: %d", paramId, paramLen);
+
+		if (cfg_set_str(pMac, (uint16_t) paramId, pStr, paramLen) !=
+		    QDF_STATUS_SUCCESS) {
+			pe_warn("setting str default param %d len %d",
+				       paramId, paramLen);
+			retVal = WNI_CFG_INVALID_LEN;
+			goto end;
+		}
+	}
+
+	/* Set status to READY */
+	pMac->cfg.gCfgStatus = CFG_SUCCESS;
+	retVal = WNI_CFG_SUCCESS;
+	pe_debug("<CFG> Completed successfully");
+
+end:
+
+	if (retVal != WNI_CFG_SUCCESS)
+		pMac->cfg.gCfgStatus = CFG_FAILURE;
+
+	/* Send response message to host */
+	pMac->cfg.gParamList[WNI_CFG_DNLD_CNF_RES] = retVal;
+	cfg_send_host_msg(pMac, WNI_CFG_DNLD_CNF, WNI_CFG_DNLD_CNF_LEN,
+			  WNI_CFG_DNLD_CNF_NUM, pMac->cfg.gParamList, 0, 0);
+
+	/* notify WMA that the config has downloaded */
+	mmhMsg.type = SIR_CFG_DOWNLOAD_COMPLETE_IND;
+	mmhMsg.bodyptr = NULL;
+	mmhMsg.bodyval = 0;
+
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+	if (wma_post_ctrl_msg(pMac, &mmhMsg) != QDF_STATUS_SUCCESS) {
+		pe_err("WMAPostMsgApi failed!");
+	}
+
+} /*** end procDnldRsp() ***/
+
+/**---------------------------------------------------------------------
+ * proc_get_req()
+ *
+ * FUNCTION:
+ * This function processes CFG_GET_REQ message from host.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ * For every parameter ID specified on the list, CFG will send a separate
+ * CFG_GET_RSP back to host.
+ *
+ * @param length:  message length
+ * @param pParam:  parameter list pointer
+ *
+ * @return None
+ *
+ */
+static void proc_get_req(tpAniSirGlobal pMac, uint16_t length, uint32_t *pParam)
+{
+	uint16_t cfgId, i;
+	uint32_t value, valueLen, result;
+	uint32_t *pValue;
+
+	pe_debug("Rcvd cfg get request %d bytes", length);
+	for (i = 0; i < length / 4; i++)
+		pe_debug("[%2d] 0x%08x", i, pParam[i]);
+
+		if (!pMac->cfg.gCfgStatus) {
+			cfgId = (uint16_t) sir_read_u32_n((uint8_t *) pParam);
+			pe_debug("CFG not ready, param %d", cfgId);
+			pMac->cfg.gParamList[WNI_CFG_GET_RSP_RES] =
+				WNI_CFG_NOT_READY;
+			pMac->cfg.gParamList[WNI_CFG_GET_RSP_PID] = cfgId;
+			pMac->cfg.gParamList[WNI_CFG_GET_RSP_PLEN] = 0;
+			cfg_send_host_msg(pMac, WNI_CFG_GET_RSP,
+					  WNI_CFG_GET_RSP_PARTIAL_LEN, WNI_CFG_GET_RSP_NUM,
+					  pMac->cfg.gParamList, 0, 0);
+		} else {
+			/* Process all parameter ID's on the list */
+			while (length >= sizeof(uint32_t)) {
+				cfgId = (uint16_t) *pParam++;
+				pValue = 0;
+				valueLen = 0;
+
+				pe_debug("Cfg get param %d", cfgId);
+				/* Check for valid parameter ID, etc... */
+				if (check_param
+					    (pMac, cfgId, CFG_CTL_RE, WNI_CFG_WO_PARAM,
+					    &result)) {
+					if ((pMac->cfg.gCfgEntry[cfgId].
+					     control & CFG_CTL_INT) != 0) {
+						/* Get integer parameter */
+						result =
+							(wlan_cfg_get_int(pMac, cfgId, &value)
+							 ==
+							 QDF_STATUS_SUCCESS ? WNI_CFG_SUCCESS :
+							 WNI_CFG_OTHER_ERROR);
+						pValue = &value;
+						valueLen = sizeof(uint32_t);
+					} else {
+						/* Get string parameter */
+						valueLen = sizeof(pMac->cfg.gSBuffer);
+						result =
+							(wlan_cfg_get_str
+								 (pMac, cfgId, pMac->cfg.gSBuffer,
+								 &valueLen)
+							 == QDF_STATUS_SUCCESS ? WNI_CFG_SUCCESS :
+							 WNI_CFG_OTHER_ERROR);
+						pValue =
+							(uint32_t *) pMac->cfg.gSBuffer;
+					}
+				} else {
+					pe_warn("Check param failed, param %d",
+						       cfgId);
+					result = WNI_CFG_INVALID_LEN;
+				}
+
+				/* Send response message to host */
+				pMac->cfg.gParamList[WNI_CFG_GET_RSP_RES] = result;
+				pMac->cfg.gParamList[WNI_CFG_GET_RSP_PID] = cfgId;
+				pMac->cfg.gParamList[WNI_CFG_GET_RSP_PLEN] = valueLen;
+
+				/* We need to round up buffer length to word-increment */
+				valueLen = (((valueLen + 3) >> 2) << 2);
+				cfg_send_host_msg(pMac, WNI_CFG_GET_RSP,
+						  WNI_CFG_GET_RSP_PARTIAL_LEN + valueLen,
+						  WNI_CFG_GET_RSP_NUM,
+						  pMac->cfg.gParamList, valueLen, pValue);
+
+				/* Decrement length */
+				length -= sizeof(uint32_t);
+			}
+		}
+
+} /*** end procGetReq() ***/
+
+/**---------------------------------------------------------------------
+ * check_param()
+ *
+ * FUNCTION:
+ * This function is called to perform various check on a parameter.
+ *
+ * LOGIC:
+ * -  If cfgId is out of bound or parameter is not valid, result
+ *    WNI_CFG_INVALID_PID is returned at address specified in pResult.
+ *
+ * -  If specified 'flag' is not set in the parameter control entry,
+ *    'failedResult' is returned at address specified in pResult.
+ *
+ * ASSUMPTIONS:
+ * Since this function is used internally, 'pResult' is always valid.
+ *
+ * NOTE:
+ *
+ * @param None
+ *
+ * @return true:   Parameter is valid and matches checked condition \n
+ * @return false:  Parameter either is not valid or does not match
+ *                 checked condition.
+ *
+ */
+static uint8_t
+check_param(tpAniSirGlobal pMac, uint16_t cfgId, uint32_t flag,
+	    uint32_t failedResult, uint32_t *pResult)
+{
+	/* Check if parameter ID is out of bound */
+	if (cfgId >= CFG_PARAM_MAX_NUM) {
+		pe_warn("Invalid param id: %d", cfgId);
+		*pResult = WNI_CFG_INVALID_PID;
+	} else {
+		/* Check if parameter is valid */
+		if ((pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_VALID) == 0) {
+			pe_warn("Param id: %d not valid", cfgId);
+			*pResult = WNI_CFG_INVALID_PID;
+		} else {
+			/* Check control field against flag */
+			if ((pMac->cfg.gCfgEntry[cfgId].control & flag) == 0) {
+				pe_debug("Param id: %d wrong permissions: %x",
+					       cfgId,
+					       pMac->cfg.gCfgEntry[cfgId].control);
+				*pResult = failedResult;
+			} else
+				return true;
+		}
+	}
+	return false;
+
+} /*** cfgParamCheck() ***/
+
+/**---------------------------------------------------------------------
+ * process_cfg_download_req()
+ *
+ * FUNCTION: This function does the Cfg Download and is invoked
+ *           only in the case of Prima or the Integrated SOC
+ *           solutions. Not applicable to Volans or Libra
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pMac: Pointer to Mac Structure
+ *
+ * @return None
+ *
+ */
+
+void
+process_cfg_download_req(tpAniSirGlobal pMac)
+{
+	int32_t i;
+	uint32_t    index;
+	uint8_t    *pDstTest, *pSrcTest;
+	uint8_t     len;
+	cfgstatic_string * pStrCfg;
+	uint32_t    bufStart, bufEnd;
+	uint32_t    retVal;
+	uint32_t    iCount = 0;
+	uint32_t    sCount = 0;
+
+	for (i = 0; i < CFG_PARAM_MAX_NUM ; i++) {
+		if ((cfg_static[i].control & CFG_CTL_VALID) != 0) {
+			if (!(cfg_static[i].control & CFG_CTL_INT)) {
+				pStrCfg = (cfgstatic_string*)cfg_static[i].
+								pStrData;
+				if (pStrCfg == NULL) {
+					pe_err("pStrCfg is NULL for CfigID : %d",
+					  i);
+					continue;
+				}
+				index = sCount & CFG_BUF_INDX_MASK;
+				sCount += pStrCfg->maxLen + 1 + 1;
+			} else {
+				index = iCount & CFG_BUF_INDX_MASK;
+				iCount++;
+			}
+		} else {
+			index = 0;
+		}
+		pMac->cfg.gCfgEntry[i].control = cfg_static[i].control | index;
+	}
+
+	/*Fill the SBUF wih maxLength*/
+	bufEnd = pMac->cfg.gCfgMaxSBufSize;
+	for (i = CFG_PARAM_MAX_NUM - 1; i >= 0; i--) {
+		if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_INT) != 0)
+			continue;
+
+		if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0)
+			continue;
+
+		bufStart = pMac->cfg.gCfgEntry[i].control & CFG_BUF_INDX_MASK;
+		pMac->cfg.gCfgSBuf[bufStart] = (uint8_t)(bufEnd - bufStart - 2);
+
+		pe_debug("id: %d max: %d bufStart: %d bufEnd: %d",
+					i, pMac->cfg.gCfgSBuf[bufStart],
+						bufStart, bufEnd);
+			bufEnd = bufStart;
+	}
+
+	for (i = 0; i < CFG_PARAM_MAX_NUM ; i++) {
+		index = pMac->cfg.gCfgEntry[i].control & CFG_BUF_INDX_MASK;
+
+		if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_INT) != 0) {
+			pMac->cfg.gCfgIBufMin[index] = cfg_static[i].cfgIMin;
+			pMac->cfg.gCfgIBufMax[index] = cfg_static[i].cfgIMax;
+			pMac->cfg.gCfgIBuf[index]    = cfg_static[i].cfgIVal;
+		} else {
+			uint8_t maxSavedLen;
+
+			if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0)
+				continue;
+			if (index >= pMac->cfg.gCfgMaxSBufSize) {
+				pe_debug("No space id:%d BufSize:%d index:%d",
+					 i, pMac->cfg.gCfgMaxSBufSize, index);
+				continue;
+			}
+
+			pDstTest = &pMac->cfg.gCfgSBuf[index];
+			pStrCfg = (cfgstatic_string*)cfg_static[i].pStrData;
+			pSrcTest = pStrCfg->data;
+			if ((pDstTest == NULL) || (pStrCfg == NULL) ||
+							(pSrcTest == NULL))
+				continue;
+			maxSavedLen = *pDstTest;
+			len = pStrCfg->length;
+			if (len > maxSavedLen)
+				continue;
+			*pDstTest++ = pStrCfg->maxLen;
+			*pDstTest++ = len;
+			while (len) {
+				*pDstTest++ = *pSrcTest++;
+				len--;
+			}
+		}
+	}
+
+	/* Set status to READY */
+	pMac->cfg.gCfgStatus = CFG_SUCCESS;
+	retVal = WNI_CFG_SUCCESS;
+	pe_debug("<CFG> Completed successfully");
+
+	pMac->cfg.gParamList[WNI_CFG_DNLD_CNF_RES] = retVal;
+
+} /*** end ProcessDownloadReq() ***/
diff --git a/core/mac/src/cfg/cfg_send_msg.c b/core/mac/src/cfg/cfg_send_msg.c
new file mode 100644
index 0000000..cd95399
--- /dev/null
+++ b/core/mac/src/cfg/cfg_send_msg.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012, 2014-2018 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.
+ */
+
+/*
+ * This file contains the source code for composing and sending messages
+ * to host.
+ *
+ * Author:      Kevin Nguyen
+ * Date:        04/09/02
+ * History:-
+ * 04/09/02     Created.
+ * --------------------------------------------------------------------
+ */
+#include "cds_api.h"
+#include "cfg_priv.h"
+#include "lim_trace.h"
+
+/*--------------------------------------------------------------------*/
+/* ATTENTION:  The functions contained in this module are to be used  */
+/*             by CFG module ONLY.                                    */
+/*--------------------------------------------------------------------*/
+
+/**---------------------------------------------------------------------
+ * cfg_send_host_msg()
+ *
+ * FUNCTION:
+ * Send CNF/RSP to host.
+ *
+ * LOGIC:
+ * Please see Configuration & Statistic Collection Micro-Architecture
+ * specification for details.
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param msgType:     message type
+ * @param msgLen:      message length
+ * @param paramNum:    number of parameters
+ * @param pParamList:  pointer to parameter list
+ * @param dataLen:     data length
+ * @param pData:       pointer to additional data
+ *
+ * @return None.
+ *
+ */
+void
+cfg_send_host_msg(tpAniSirGlobal pMac, uint16_t msgType, uint32_t msgLen,
+		  uint32_t paramNum, uint32_t *pParamList, uint32_t dataLen,
+		  uint32_t *pData)
+{
+	uint32_t *pMsg, *pEnd;
+	struct scheduler_msg mmhMsg = {0};
+
+	if ((paramNum > 0) && (NULL == pParamList)) {
+		pe_err("pParamList NULL when paramNum greater than 0!");
+		return;
+	}
+	if ((dataLen > 0) && (NULL == pData)) {
+		pe_err("pData NULL when dataLen greater than 0!");
+		return;
+	}
+	pMsg = qdf_mem_malloc(msgLen);
+	if (!pMsg)
+		return;
+
+	/* Fill in message details */
+	mmhMsg.type = msgType;
+	mmhMsg.bodyptr = pMsg;
+	mmhMsg.bodyval = 0;
+	((tSirMbMsg *) pMsg)->type = msgType;
+	((tSirMbMsg *) pMsg)->msgLen = (uint16_t) msgLen;
+
+	switch (msgType) {
+	case WNI_CFG_GET_RSP:
+	case WNI_CFG_PARAM_UPDATE_IND:
+	case WNI_CFG_DNLD_REQ:
+	case WNI_CFG_DNLD_CNF:
+	case WNI_CFG_SET_CNF:
+		/* Fill in parameters */
+		pMsg++;
+		if (NULL != pParamList) {
+			pEnd = pMsg + paramNum;
+			while (pMsg < pEnd) {
+				*pMsg++ = *pParamList++;
+			}
+		}
+		/* Copy data if there is any */
+		if (NULL != pData) {
+			pEnd = pMsg + (dataLen >> 2);
+			while (pMsg < pEnd) {
+				*pMsg++ = *pData++;
+			}
+		}
+		break;
+
+	default:
+		pe_warn("Unknown msg: %d!", (int)msgType);
+		qdf_mem_free(pMsg);
+		return;
+	}
+
+	/* Ship it */
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+	sys_process_mmh_msg(pMac, &mmhMsg);
+
+} /*** end cfg_send_host_msg() ***/
diff --git a/core/mac/src/dph/dph_hash_table.c b/core/mac/src/dph/dph_hash_table.c
new file mode 100644
index 0000000..d88e58f
--- /dev/null
+++ b/core/mac/src/dph/dph_hash_table.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ *
+ * This file dph_hash_table.cc implements the member functions of
+ * DPH hash table class.
+ *
+ * Author:      Sandesh Goel
+ * Date:        02/25/02
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "cfg_api.h"
+#include "sch_api.h"
+#include "dph_global.h"
+#include "lim_api.h"
+#include "wma_if.h"
+#include "wlan_mlme_api.h"
+
+/* --------------------------------------------------------------------- */
+/**
+ * dphHashTableClass()
+ *
+ * FUNCTION:
+ * Constructor function
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+void dph_hash_table_class_init(tpAniSirGlobal pMac,
+			       dphHashTableClass *pDphHashTable)
+{
+	uint16_t i;
+
+	for (i = 0; i < pDphHashTable->size; i++) {
+		pDphHashTable->pHashTable[i] = 0;
+	}
+
+	for (i = 0; i < pDphHashTable->size; i++) {
+		pDphHashTable->pDphNodeArray[i].valid = 0;
+		pDphHashTable->pDphNodeArray[i].added = 0;
+		pDphHashTable->pDphNodeArray[i].assocId = i;
+	}
+
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * hash_function
+ *
+ * FUNCTION:
+ * Hashing function
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param staAddr MAC address of the station
+ * @return None
+ */
+
+static uint16_t hash_function(tpAniSirGlobal pMac, uint8_t staAddr[],
+			      uint16_t numSta)
+{
+	int i;
+	uint16_t sum = 0;
+
+	for (i = 0; i < 6; i++)
+		sum += staAddr[i];
+
+	return sum % numSta;
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * dph_lookup_hash_entry
+ *
+ * FUNCTION:
+ * Look up an entry in hash table
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param staAddr MAC address of the station
+ * @param pStaId pointer to the Station ID assigned to the station
+ * @return pointer to STA hash entry if lookup was a success \n
+ *         NULL if lookup was a failure
+ */
+
+tpDphHashNode dph_lookup_hash_entry(tpAniSirGlobal pMac, uint8_t staAddr[],
+				    uint16_t *pAssocId,
+				    dphHashTableClass *pDphHashTable)
+{
+	tpDphHashNode ptr = NULL;
+	uint16_t index = hash_function(pMac, staAddr, pDphHashTable->size);
+
+	if (!pDphHashTable->pHashTable) {
+		pe_err("pHashTable is NULL");
+		return ptr;
+	}
+
+	for (ptr = pDphHashTable->pHashTable[index]; ptr; ptr = ptr->next) {
+		if (dph_compare_mac_addr(staAddr, ptr->staAddr)) {
+			*pAssocId = ptr->assocId;
+			break;
+		}
+	}
+	return ptr;
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * dph_get_hash_entry
+ *
+ * FUNCTION:
+ * Get a pointer to the hash node
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param staId Station ID
+ * @return pointer to STA hash entry if lookup was a success \n
+ *         NULL if lookup was a failure
+ */
+
+tpDphHashNode dph_get_hash_entry(tpAniSirGlobal pMac, uint16_t peerIdx,
+				 dphHashTableClass *pDphHashTable)
+{
+	if (peerIdx < pDphHashTable->size) {
+		if (pDphHashTable->pDphNodeArray[peerIdx].added)
+			return &pDphHashTable->pDphNodeArray[peerIdx];
+		else
+			return NULL;
+	} else
+		return NULL;
+
+}
+
+static inline tpDphHashNode get_node(tpAniSirGlobal pMac, uint8_t assocId,
+				     dphHashTableClass *pDphHashTable)
+{
+	return &pDphHashTable->pDphNodeArray[assocId];
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * dph_lookup_assoc_id
+ *
+ * FUNCTION:
+ * This function looks up assocID given the station Id. It traverses the complete table to do this.
+ * Need to find an efficient way to do this.
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pMac pointer to global Mac structure.
+ * @param staIdx station ID
+ * @param *assocId pointer to associd to be returned by this function.
+ * @return pointer to the dph node.
+ */
+tpDphHashNode dph_lookup_assoc_id(tpAniSirGlobal pMac, uint16_t staIdx,
+				  uint16_t *assocId,
+				  dphHashTableClass *pDphHashTable)
+{
+	uint8_t i;
+
+	for (i = 0; i < pDphHashTable->size; i++) {
+		if ((pDphHashTable->pDphNodeArray[i].added) &&
+		    (pDphHashTable->pDphNodeArray[i].staIndex == staIdx)) {
+			*assocId = i;
+			break;
+		}
+
+	}
+	if (i == pDphHashTable->size)
+		return NULL;
+	return &pDphHashTable->pDphNodeArray[i];
+
+}
+
+/** -------------------------------------------------------------
+   \fn dph_init_sta_state
+   \brief Initialize STA state. this function saves the staId from the current entry in the DPH table with given assocId
+ \ if validStaIdx flag is set. Otherwise it sets the staId to invalid.
+   \param  tpAniSirGlobal    pMac
+   \param  tSirMacAddr staAddr
+   \param  uint16_t assocId
+   \param  uint8_t validStaIdx -   true ==> the staId in the DPH entry with given assocId is valid and restore it back.
+ \                                              false ==> set the staId to invalid.
+   \return tpDphHashNode - DPH hash node if found.
+   -------------------------------------------------------------*/
+
+tpDphHashNode dph_init_sta_state(tpAniSirGlobal pMac, tSirMacAddr staAddr,
+				 uint16_t assocId, uint8_t validStaIdx,
+				 dphHashTableClass *pDphHashTable)
+{
+	uint32_t val;
+
+	tpDphHashNode pStaDs, pnext;
+	uint16_t staIdx = STA_INVALID_IDX;
+
+	if (assocId >= pDphHashTable->size) {
+		pe_err("Invalid Assoc Id %d", assocId);
+		return NULL;
+	}
+
+	pStaDs = get_node(pMac, (uint8_t) assocId, pDphHashTable);
+	staIdx = pStaDs->staIndex;
+	pnext = pStaDs->next;
+
+	/* 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;
+	if (true == validStaIdx)
+		pStaDs->staIndex = staIdx;
+	else
+		pStaDs->staIndex = STA_INVALID_IDX;
+
+	/* Initialize STA mac address */
+	qdf_mem_copy(pStaDs->staAddr, staAddr, sizeof(tSirMacAddr));
+
+	/* Initialize fragmentation threshold */
+	if (wlan_mlme_get_frag_threshold(pMac->psoc, &val) !=
+					 QDF_STATUS_SUCCESS)
+		pe_warn("could not retrieve fragmentation threshold");
+	else
+		pStaDs->fragSize = (uint16_t) val;
+
+	pStaDs->added = 1;
+	pStaDs->encPolicy = ENC_POLICY_NULL;
+	pStaDs->is_disassoc_deauth_in_progress = 0;
+	pStaDs->last_assoc_received_time = 0;
+	pStaDs->last_disassoc_deauth_received_time = 0;
+	pStaDs->sta_deletion_in_progress = false;
+	pStaDs->valid = 1;
+	return pStaDs;
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * dph_add_hash_entry
+ *
+ * FUNCTION:
+ * Add entry to hash table
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param staAddr MAC address of the station
+ * @param staId Station ID assigned to the station
+ * @return Pointer to STA hash entry
+ */
+
+tpDphHashNode dph_add_hash_entry(tpAniSirGlobal pMac, tSirMacAddr staAddr,
+				 uint16_t assocId,
+				 dphHashTableClass *pDphHashTable)
+{
+	tpDphHashNode ptr, node;
+	uint16_t index = hash_function(pMac, staAddr, pDphHashTable->size);
+
+	pe_debug("assocId %d index %d STA addr",
+		       assocId, index);
+	pe_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(staAddr));
+
+	if (assocId >= pDphHashTable->size) {
+		pe_err("invalid STA id %d", assocId);
+		return NULL;
+	}
+
+	if (pDphHashTable->pDphNodeArray[assocId].added) {
+		pe_err("already added STA %d", assocId);
+		return NULL;
+	}
+
+	for (ptr = pDphHashTable->pHashTable[index]; ptr; ptr = ptr->next) {
+		if (ptr == ptr->next) {
+			pe_err("Infinite Loop");
+			return NULL;
+		}
+
+		if (dph_compare_mac_addr(staAddr, ptr->staAddr)
+		    || ptr->assocId == assocId)
+			break;
+	}
+
+	if (ptr) {
+		/* Duplicate entry */
+		pe_err("assocId %d hashIndex %d entry exists",
+			assocId, index);
+		return NULL;
+	} else {
+		if (dph_init_sta_state
+			    (pMac, staAddr, assocId, false, pDphHashTable) == NULL) {
+			pe_err("could not Init STA id: %d", assocId);
+			return NULL;
+		}
+		/* Add the node to the link list */
+		pDphHashTable->pDphNodeArray[assocId].next =
+			pDphHashTable->pHashTable[index];
+		pDphHashTable->pHashTable[index] =
+			&pDphHashTable->pDphNodeArray[assocId];
+
+		node = pDphHashTable->pHashTable[index];
+		return node;
+	}
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * dph_delete_hash_entry
+ *
+ * FUNCTION:
+ * Delete entry from hash table
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param staAddr MAC address of the station
+ * @param staId Station ID assigned to the station
+ * @return QDF_STATUS_SUCCESS if successful,
+ *         QDF_STATUS_E_FAILURE otherwise
+ */
+
+QDF_STATUS dph_delete_hash_entry(tpAniSirGlobal pMac, tSirMacAddr staAddr,
+				 uint16_t assocId,
+				 dphHashTableClass *pDphHashTable)
+{
+	tpDphHashNode ptr, prev;
+	uint16_t index = hash_function(pMac, staAddr, pDphHashTable->size);
+
+	pe_debug("assocId %d index %d STA addr", assocId, index);
+	pe_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(staAddr));
+
+	if (assocId >= pDphHashTable->size) {
+		pe_err("invalid STA id %d", assocId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pDphHashTable->pDphNodeArray[assocId].added == 0) {
+		pe_err("STA %d never added", assocId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (prev = 0, ptr = pDphHashTable->pHashTable[index];
+	     ptr; prev = ptr, ptr = ptr->next) {
+		if (dph_compare_mac_addr(staAddr, ptr->staAddr))
+			break;
+		if (prev == ptr) {
+			pe_err("Infinite Loop");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	if (ptr) {
+		/* / Delete the entry after invalidating it */
+		ptr->valid = 0;
+		memset(ptr->staAddr, 0, sizeof(ptr->staAddr));
+		if (prev == 0)
+			pDphHashTable->pHashTable[index] = ptr->next;
+		else
+			prev->next = ptr->next;
+		ptr->added = 0;
+		ptr->is_disassoc_deauth_in_progress = 0;
+		ptr->last_assoc_received_time = 0;
+		ptr->last_disassoc_deauth_received_time = 0;
+		ptr->sta_deletion_in_progress = false;
+		ptr->next = 0;
+	} else {
+		pe_err("Entry not present STA addr");
+		pe_err(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(staAddr));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
diff --git a/core/mac/src/dph/dph_hash_table.h b/core/mac/src/dph/dph_hash_table.h
new file mode 100644
index 0000000..83c6d49
--- /dev/null
+++ b/core/mac/src/dph/dph_hash_table.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2011-2015, 2017-2018 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.
+ */
+
+/*
+ *
+ * This file dph_hash_table.h contains the definition of the scheduler class.
+ *
+ * Author:      Sandesh Goel
+ * Date:        02/25/02
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __DPH_HASH_TABLE_H__
+#define __DPH_HASH_TABLE_H__
+
+#include "ani_global.h"
+/* Compare MAC addresses, return true if same */
+static inline uint8_t dph_compare_mac_addr(uint8_t addr1[], uint8_t addr2[])
+{
+	return (addr1[0] == addr2[0]) &&
+		(addr1[1] == addr2[1]) &&
+		(addr1[2] == addr2[2]) &&
+		(addr1[3] == addr2[3]) &&
+		(addr1[4] == addr2[4]) && (addr1[5] == addr2[5]);
+}
+
+/* Hash table class */
+typedef struct {
+
+	/* The hash table itself */
+	tpDphHashNode *pHashTable;
+
+	/* The state array */
+	tDphHashNode *pDphNodeArray;
+	uint16_t size;
+} dphHashTableClass;
+
+/* The hash table object */
+extern dphHashTableClass dphHashTable;
+
+tpDphHashNode dph_lookup_hash_entry(tpAniSirGlobal pMac, uint8_t staAddr[],
+				    uint16_t *pStaId,
+				    dphHashTableClass *pDphHashTable);
+tpDphHashNode dph_lookup_assoc_id(tpAniSirGlobal pMac, uint16_t staIdx,
+				  uint16_t *assocId,
+				  dphHashTableClass *pDphHashTable);
+
+/* Get a pointer to the hash node */
+extern tpDphHashNode dph_get_hash_entry(tpAniSirGlobal pMac, uint16_t staId,
+					dphHashTableClass *pDphHashTable);
+
+/* Add an entry to the hash table */
+extern tpDphHashNode dph_add_hash_entry(tpAniSirGlobal pMac,
+					tSirMacAddr staAddr,
+					uint16_t staId,
+					dphHashTableClass *pDphHashTable);
+
+/* Delete an entry from the hash table */
+QDF_STATUS dph_delete_hash_entry(tpAniSirGlobal pMac,
+				 tSirMacAddr staAddr, uint16_t staId,
+				 dphHashTableClass *pDphHashTable);
+
+void dph_hash_table_class_init(tpAniSirGlobal pMac,
+			       dphHashTableClass *pDphHashTable);
+/* Initialize STA state */
+extern tpDphHashNode dph_init_sta_state(tpAniSirGlobal pMac,
+					tSirMacAddr staAddr,
+					uint16_t staId, uint8_t validStaIdx,
+					dphHashTableClass *pDphHashTable);
+
+#endif
diff --git a/core/mac/src/include/cfg_api.h b/core/mac/src/include/cfg_api.h
new file mode 100644
index 0000000..ee5b7aa
--- /dev/null
+++ b/core/mac/src/include/cfg_api.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2011-2012, 2015-2018 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.
+ */
+
+/*
+ *
+ * Author:      Kevin Nguyen
+ * Date:        04/09/02
+ * History:-
+ * 04/09/02        Created.
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __CFGAPI_H
+#define __CFGAPI_H
+
+#include <sir_common.h>
+#include <sir_params.h>
+#include <sir_mac_prot_def.h>
+#include <wni_api.h>
+#include <ani_global.h>
+
+/*---------------------------------------------------------------------*/
+/* CFG definitions                                                     */
+/*---------------------------------------------------------------------*/
+
+/* CFG status */
+typedef enum eCfgStatusTypes {
+	CFG_INCOMPLETE,
+	CFG_SUCCESS,
+	CFG_FAILURE
+} tCfgStatusTypes;
+
+/* WEP key mapping table row structure */
+typedef struct {
+	uint8_t keyMappingAddr[QDF_MAC_ADDR_SIZE];
+	uint32_t wepOn;
+	uint8_t key[SIR_MAC_KEY_LENGTH];
+	uint32_t status;
+} tCfgWepKeyEntry;
+
+/*---------------------------------------------------------------------*/
+/* CFG function prototypes                                             */
+/*---------------------------------------------------------------------*/
+
+uint32_t cfg_need_restart(tpAniSirGlobal pMac, uint16_t cfgId);
+uint32_t cfg_need_reload(tpAniSirGlobal pMac, uint16_t cfgId);
+
+/* / Process host message */
+void cfg_process_mb_msg(tpAniSirGlobal, tSirMbMsg *);
+
+/* / Set integer parameter value */
+QDF_STATUS cfg_set_int(tpAniSirGlobal, uint16_t, uint32_t);
+
+/* / Check if the parameter is valid */
+QDF_STATUS cfg_check_valid(tpAniSirGlobal, uint16_t, uint32_t *);
+
+/* / Get integer parameter value */
+QDF_STATUS wlan_cfg_get_int(tpAniSirGlobal, uint16_t, uint32_t *);
+
+/* / Set string parameter value */
+QDF_STATUS cfg_set_str(tpAniSirGlobal, uint16_t, uint8_t *, uint32_t);
+
+QDF_STATUS cfg_set_str_notify(tpAniSirGlobal, uint16_t, uint8_t *, uint32_t,
+			      int);
+
+/* Cfg Download function for Prima or Integrated solutions. */
+void process_cfg_download_req(tpAniSirGlobal);
+
+/* / Get string parameter value */
+QDF_STATUS wlan_cfg_get_str(tpAniSirGlobal, uint16_t, uint8_t *, uint32_t *);
+
+/* / Get string parameter maximum length */
+QDF_STATUS wlan_cfg_get_str_max_len(tpAniSirGlobal, uint16_t, uint32_t *);
+
+/* / Get string parameter maximum length */
+QDF_STATUS wlan_cfg_get_str_len(tpAniSirGlobal, uint16_t, uint32_t *);
+
+/* / Get the regulatory tx power on given channel */
+int8_t cfg_get_regulatory_max_transmit_power(tpAniSirGlobal pMac,
+					     uint8_t channel);
+
+/* / Get capability info */
+QDF_STATUS cfg_get_capability_info(tpAniSirGlobal pMac, uint16_t *pCap,
+				   tpPESession psessionEntry);
+
+/* / Set capability info */
+void cfg_set_capability_info(tpAniSirGlobal, uint16_t);
+
+/* / Cleanup CFG module */
+void cfg_cleanup(tpAniSirGlobal pMac);
+
+const char *cfg_get_string(uint16_t cfg_id);
+
+#endif /* __CFGAPI_H */
diff --git a/core/mac/src/include/cfg_global.h b/core/mac/src/include/cfg_global.h
new file mode 100644
index 0000000..ebc4f17
--- /dev/null
+++ b/core/mac/src/include/cfg_global.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * Author:      Sandesh Goel
+ * Date:        02/09/03
+ * History:-
+ * 04/09/02        Created.
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __CFGGLOBAL_H
+#define __CFGGLOBAL_H
+
+#include "sir_common.h"
+#include "sir_types.h"
+#include "wni_cfg.h"
+
+#define CFG_MAX_NUM_STA      SIR_MAX_NUM_STA_IN_IBSS
+
+#define CFG_MAX_STATIC_STRING   70
+/* as the number of channels grows, 128 is not big enough */
+#define CFG_MAX_STR_LEN       256
+
+/*--------------------------------------------------------------------*/
+/* Configuration Control Structure                                    */
+/*--------------------------------------------------------------------*/
+typedef struct {
+	uint32_t control;
+} tCfgCtl;
+
+
+typedef struct sAniSirCfgStaticString {
+	uint16_t cfgId;
+	uint8_t  maxLen;
+	uint8_t  length;
+	uint8_t  data[255];
+} cfgstatic_string;
+
+typedef struct sAniSirCfgStatic {
+	uint16_t cfgId;
+	uint32_t control;
+	uint32_t cfgIMin;
+	uint32_t cfgIMax;
+	uint32_t cfgIVal;
+	void     *pStrData;
+} cgstatic;
+
+typedef struct sAniSirCfg {
+	/* CFG module status */
+	uint8_t gCfgStatus;
+	uint16_t gCfgMaxIBufSize;
+	uint16_t gCfgMaxSBufSize;
+
+	tCfgCtl *gCfgEntry;
+
+	uint8_t *gCfgSBuf;
+	uint32_t *gCfgIBuf;
+	uint32_t *gCfgIBufMin;
+	uint32_t *gCfgIBufMax;
+
+	/* Static buffer for string parameter (must be word-aligned) */
+	uint8_t *gSBuffer;
+
+	/* Message param list buffer (enough for largest possible response) */
+	uint32_t *gParamList;
+} tAniSirCfg, *tpAniSirCfg;
+
+#endif
diff --git a/core/mac/src/include/dot11f.h b/core/mac/src/include/dot11f.h
new file mode 100644
index 0000000..5964660
--- /dev/null
+++ b/core/mac/src/include/dot11f.h
@@ -0,0 +1,11187 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef DOT11F_H
+#define DOT11F_H
+/*
+ * \file dot11f.h
+ *
+ * \brief Structures, function prototypes & definitions
+ * for working with 802.11 Frames
+ *
+ *
+ * This file was automatically generated by 'framesc'
+ * Tue Sep 18 11:47:29 2018 from the following file(s):
+ *
+ * dot11f.frms
+ *
+ * PLEASE DON'T EDIT THIS FILE BY HAND!
+ *
+ * Instead, please update the input files & re-run
+ * 'framesc'  For more information on 'framesc' & the
+ * frames language,  run 'framesc --help'.
+ *
+ */
+
+typedef uint32_t tDOT11F_U64[2];
+
+#if defined (_MSC_VER)
+#pragma warning (disable:4214)	/* nonstandard extension used */
+#endif /* Microsoft C/C++             bit field types other than int */
+
+#if !defined __must_check
+#define __must_check
+#endif
+
+#if !defined unlikely
+#define unlikely(x)    (x)
+#endif
+
+/*
+ * Frames Return Codes:
+ *
+ * Success is indicated by a return value of zero.  Failure is indicated
+ * by the presence of the high bit.  Warnings encountered in the course
+ * of a successful parse are indicated by various bits in the lower 31
+ * being turned on.
+ *
+ * For instance, a return value of 0x0000000a would indicate that the
+ * parse succeeded, but that a mandatory IE wasn't present, and some IE
+ * was found to be corrupt.
+ *
+ *
+ */
+
+#define DOT11F_PARSE_SUCCESS         (0x00000000)
+#define DOT11F_UNKNOWN_IES           (0x00000001)
+#define DOT11F_MANDATORY_IE_MISSING  (0x00000002)
+#define DOT11F_INCOMPLETE_IE         (0x00000004)
+#define DOT11F_SKIPPED_BAD_IE        (0x00000008)
+#define DOT11F_LAST_IE_TOO_LONG      (0x00000010)
+#define DOT11F_DUPLICATE_IE          (0x00000020)
+#define DOT11F_BAD_FIXED_VALUE       (0x00000040)
+#define DOT11F_INCOMPLETE_TLV        (0x00000080)
+#define DOT11F_INVALID_TLV_LENGTH    (0x00000100)
+#define DOT11F_SKIPPED_BAD_TLV       (0x00000200)
+#define DOT11F_UNKNOWN_TLVS          (0x00000400)
+#define DOT11F_LAST_TLV_TOO_LONG     (0x00000800)
+#define DOT11F_MANDATORY_TLV_MISSING (0x00001000)
+#define DOT11F_INTERNAL_ERROR        (0x10000001)
+#define DOT11F_MISSING_FIXED_FIELD   (0x10000002)
+#define DOT11F_BAD_INPUT_BUFFER      (0x10000003)
+#define DOT11F_BAD_OUTPUT_BUFFER     (0x10000004)
+#define DOT11F_BUFFER_OVERFLOW       (0x10000005)
+#define DOT11F_FAILED(code)          ((code) & 0x10000000)
+#define DOT11F_SUCCEEDED(code)       ((code) == 0)
+#define DOT11F_WARNED(code)          (!DOT11F_SUCCEEDED(code) && !DOT11F_FAILED(code))
+
+/*********************************************************************
+ * Fixed Fields                                                      *
+ ********************************************************************/
+
+typedef struct sDot11fFfAID {
+	uint16_t associd;
+} tDot11fFfAID;
+
+#define DOT11F_FF_AID_LEN (2)
+
+void dot11f_unpack_ff_AID(tpAniSirGlobal, uint8_t *, tDot11fFfAID *);
+
+void dot11f_pack_ff_aid(tpAniSirGlobal, tDot11fFfAID *, uint8_t *);
+
+typedef struct sDot11fFfAction {
+	uint8_t action;
+} tDot11fFfAction;
+
+#define DOT11F_FF_ACTION_LEN (1)
+
+void dot11f_unpack_ff_action(tpAniSirGlobal, uint8_t *, tDot11fFfAction *);
+
+void dot11f_pack_ff_action(tpAniSirGlobal, tDot11fFfAction *, uint8_t *);
+
+typedef struct sDot11fFfAuthAlgo {
+	uint16_t algo;
+} tDot11fFfAuthAlgo;
+
+#define DOT11F_FF_AUTHALGO_LEN (2)
+
+void dot11f_unpack_ff_AuthAlgo(tpAniSirGlobal, uint8_t *,
+			       tDot11fFfAuthAlgo *);
+
+void dot11f_pack_ff_auth_algo(tpAniSirGlobal, tDot11fFfAuthAlgo *, uint8_t *);
+
+typedef struct sDot11fFfAuthSeqNo {
+	uint16_t no;
+} tDot11fFfAuthSeqNo;
+
+#define DOT11F_FF_AUTHSEQNO_LEN (2)
+
+void dot11f_unpack_ff_AuthSeqNo(tpAniSirGlobal, uint8_t *,
+				tDot11fFfAuthSeqNo *);
+
+void dot11f_pack_ff_auth_seq_no(tpAniSirGlobal, tDot11fFfAuthSeqNo *,
+			      uint8_t *);
+
+typedef struct sDot11fFfBeaconInterval {
+	uint16_t interval;
+} tDot11fFfBeaconInterval;
+
+#define DOT11F_FF_BEACONINTERVAL_LEN (2)
+
+void dot11f_unpack_ff_BeaconInterval(tpAniSirGlobal, uint8_t *,
+				     tDot11fFfBeaconInterval *);
+
+void dot11f_pack_ff_beacon_interval(tpAniSirGlobal, tDot11fFfBeaconInterval *,
+				   uint8_t *);
+
+typedef struct sDot11fFfCapabilities {
+	uint16_t             ess:1;
+	uint16_t            ibss:1;
+	uint16_t      cfPollable:1;
+	uint16_t       cfPollReq:1;
+	uint16_t         privacy:1;
+	uint16_t   shortPreamble:1;
+	uint16_t            pbcc:1;
+	uint16_t  channelAgility:1;
+	uint16_t     spectrumMgt:1;
+	uint16_t             qos:1;
+	uint16_t   shortSlotTime:1;
+	uint16_t            apsd:1;
+	uint16_t             rrm:1;
+	uint16_t        dsssOfdm:1;
+	uint16_t       delayedBA:1;
+	uint16_t     immediateBA:1;
+} tDot11fFfCapabilities;
+
+#define DOT11F_FF_CAPABILITIES_LEN (2)
+
+void dot11f_unpack_ff_capabilities(tpAniSirGlobal, uint8_t *,
+				   tDot11fFfCapabilities *);
+
+void dot11f_pack_ff_capabilities(tpAniSirGlobal, tDot11fFfCapabilities *,
+				 uint8_t *);
+
+#define CAPABILITIES_ESS_OFFSET            0
+#define CAPABILITIES_ESS_WIDTH             1
+#define CAPABILITIES_IBSS_OFFSET           1
+#define CAPABILITIES_IBSS_WIDTH            1
+#define CAPABILITIES_CFPOLLABLE_OFFSET     2
+#define CAPABILITIES_CFPOLLABLE_WIDTH      1
+#define CAPABILITIES_CFPOLLREQ_OFFSET      3
+#define CAPABILITIES_CFPOLLREQ_WIDTH       1
+#define CAPABILITIES_PRIVACY_OFFSET        4
+#define CAPABILITIES_PRIVACY_WIDTH         1
+#define CAPABILITIES_SHORTPREAMBLE_OFFSET  5
+#define CAPABILITIES_SHORTPREAMBLE_WIDTH   1
+#define CAPABILITIES_PBCC_OFFSET           6
+#define CAPABILITIES_PBCC_WIDTH            1
+#define CAPABILITIES_CHANNELAGILITY_OFFSET 7
+#define CAPABILITIES_CHANNELAGILITY_WIDTH  1
+#define CAPABILITIES_SPECTRUMMGT_OFFSET    8
+#define CAPABILITIES_SPECTRUMMGT_WIDTH     1
+#define CAPABILITIES_QOS_OFFSET            9
+#define CAPABILITIES_QOS_WIDTH             1
+#define CAPABILITIES_SHORTSLOTTIME_OFFSET  10
+#define CAPABILITIES_SHORTSLOTTIME_WIDTH   1
+#define CAPABILITIES_APSD_OFFSET           11
+#define CAPABILITIES_APSD_WIDTH            1
+#define CAPABILITIES_RRM_OFFSET            12
+#define CAPABILITIES_RRM_WIDTH             1
+#define CAPABILITIES_DSSSOFDM_OFFSET       13
+#define CAPABILITIES_DSSSOFDM_WIDTH        1
+#define CAPABILITIES_DELAYEDBA_OFFSET      14
+#define CAPABILITIES_DELAYEDBA_WIDTH       1
+#define CAPABILITIES_IMMEDIATEBA_OFFSET    15
+#define CAPABILITIES_IMMEDIATEBA_WIDTH     1
+
+typedef struct sDot11fFfCategory {
+	uint8_t category;
+} tDot11fFfCategory;
+
+#define DOT11F_FF_CATEGORY_LEN (1)
+
+void dot11f_unpack_ff_category(tpAniSirGlobal, uint8_t *,
+			       tDot11fFfCategory *);
+
+void dot11f_pack_ff_category(tpAniSirGlobal, tDot11fFfCategory *, uint8_t *);
+
+typedef struct sDot11fFfCurrentAPAddress {
+	uint8_t mac[6];
+} tDot11fFfCurrentAPAddress;
+
+#define DOT11F_FF_CURRENTAPADDRESS_LEN (6)
+
+void dot11f_unpack_ff_current_ap_address(tpAniSirGlobal, uint8_t *,
+				       tDot11fFfCurrentAPAddress *);
+
+void dot11f_pack_ff_current_ap_address(tpAniSirGlobal,
+				     tDot11fFfCurrentAPAddress *,
+				     uint8_t *);
+
+
+typedef struct sDot11fFfDialogToken {
+	uint8_t token;
+} tDot11fFfDialogToken;
+
+#define DOT11F_FF_DIALOGTOKEN_LEN (1)
+
+void dot11f_unpack_ff_dialog_token(tpAniSirGlobal, uint8_t *,
+				  tDot11fFfDialogToken *);
+
+void dot11f_pack_ff_dialog_token(tpAniSirGlobal, tDot11fFfDialogToken *,
+				uint8_t *);
+
+typedef struct sDot11fFfLinkMargin {
+	uint8_t linkMargin;
+} tDot11fFfLinkMargin;
+
+#define DOT11F_FF_LINKMARGIN_LEN (1)
+
+void dot11f_unpack_ff_link_margin(tpAniSirGlobal, uint8_t *,
+				 tDot11fFfLinkMargin *);
+
+void dot11f_pack_ff_link_margin(tpAniSirGlobal, tDot11fFfLinkMargin *,
+			       uint8_t *);
+
+typedef struct sDot11fFfListenInterval {
+	uint16_t interval;
+} tDot11fFfListenInterval;
+
+#define DOT11F_FF_LISTENINTERVAL_LEN (2)
+
+void dot11f_unpack_ff_ListenInterval(tpAniSirGlobal, uint8_t *,
+				     tDot11fFfListenInterval *);
+
+void dot11f_pack_ff_listen_interval(tpAniSirGlobal, tDot11fFfListenInterval *,
+				   uint8_t *);
+
+typedef struct sDot11fFfMaxTxPower {
+	uint8_t maxTxPower;
+} tDot11fFfMaxTxPower;
+
+#define DOT11F_FF_MAXTXPOWER_LEN (1)
+
+void dot11f_unpack_ff_max_tx_power(tpAniSirGlobal, uint8_t *,
+				 tDot11fFfMaxTxPower *);
+
+void dot11f_pack_ff_max_tx_power(tpAniSirGlobal, tDot11fFfMaxTxPower *,
+			       uint8_t *);
+
+typedef struct sDot11fFfNumOfRepetitions {
+	uint16_t repetitions;
+} tDot11fFfNumOfRepetitions;
+
+#define DOT11F_FF_NUMOFREPETITIONS_LEN (2)
+
+void dot11f_unpack_ff_num_of_repetitions(tpAniSirGlobal, uint8_t *,
+				       tDot11fFfNumOfRepetitions *);
+
+void dot11f_pack_ff_num_of_repetitions(tpAniSirGlobal,
+				     tDot11fFfNumOfRepetitions *,
+				     uint8_t *);
+
+
+typedef struct sDot11fFfOperatingMode {
+	uint8_t  chanWidth:2;
+	uint8_t   reserved:2;
+	uint8_t      rxNSS:3;
+	uint8_t  rxNSSType:1;
+} tDot11fFfOperatingMode;
+
+#define DOT11F_FF_OPERATINGMODE_LEN (1)
+
+void dot11f_unpack_ff_operating_mode(tpAniSirGlobal, uint8_t *,
+				    tDot11fFfOperatingMode *);
+
+void dot11f_pack_ff_operating_mode(tpAniSirGlobal, tDot11fFfOperatingMode *,
+				  uint8_t *);
+
+#define OPERATINGMODE_CHANWIDTH_OFFSET 0
+#define OPERATINGMODE_CHANWIDTH_WIDTH  2
+#define OPERATINGMODE_RESERVED_OFFSET  2
+#define OPERATINGMODE_RESERVED_WIDTH   2
+#define OPERATINGMODE_RXNSS_OFFSET     4
+#define OPERATINGMODE_RXNSS_WIDTH      3
+#define OPERATINGMODE_RXNSSTYPE_OFFSET 7
+#define OPERATINGMODE_RXNSSTYPE_WIDTH  1
+
+typedef struct sDot11fFfRCPI {
+	uint8_t rcpi;
+} tDot11fFfRCPI;
+
+#define DOT11F_FF_RCPI_LEN (1)
+
+void dot11f_unpack_ff_rcpi(tpAniSirGlobal, uint8_t *, tDot11fFfRCPI *);
+
+void dot11f_pack_ff_rcpi(tpAniSirGlobal, tDot11fFfRCPI *, uint8_t *);
+
+typedef struct sDot11fFfRSNI {
+	uint8_t rsni;
+} tDot11fFfRSNI;
+
+#define DOT11F_FF_RSNI_LEN (1)
+
+void dot11f_unpack_ff_rsni(tpAniSirGlobal, uint8_t *, tDot11fFfRSNI *);
+
+void dot11f_pack_ff_rsni(tpAniSirGlobal, tDot11fFfRSNI *, uint8_t *);
+
+typedef struct sDot11fFfReason {
+	uint16_t code;
+} tDot11fFfReason;
+
+#define DOT11F_FF_REASON_LEN (2)
+
+void dot11f_unpack_ff_Reason(tpAniSirGlobal, uint8_t *, tDot11fFfReason *);
+
+void dot11f_pack_ff_reason(tpAniSirGlobal, tDot11fFfReason *, uint8_t *);
+
+typedef struct sDot11fFfRxAntennaId {
+	uint8_t antennaId;
+} tDot11fFfRxAntennaId;
+
+#define DOT11F_FF_RXANTENNAID_LEN (1)
+
+void dot11f_unpack_ff_rx_antenna_id(tpAniSirGlobal, uint8_t *,
+				  tDot11fFfRxAntennaId *);
+
+void dot11f_pack_ff_rx_antenna_id(tpAniSirGlobal, tDot11fFfRxAntennaId *,
+				uint8_t *);
+
+typedef struct sDot11fFfSMPowerModeSet {
+	uint8_t  PowerSave_En:1;
+	uint8_t          Mode:1;
+	uint8_t      reserved:6;
+} tDot11fFfSMPowerModeSet;
+
+#define DOT11F_FF_SMPOWERMODESET_LEN (1)
+
+void dot11f_unpack_ff_sm_power_mode_set(tpAniSirGlobal, uint8_t *,
+				     tDot11fFfSMPowerModeSet *);
+
+void dot11f_pack_ff_sm_power_mode_set(tpAniSirGlobal, tDot11fFfSMPowerModeSet *,
+				   uint8_t *);
+
+#define SMPOWERMODESET_POWERSAVE_EN_OFFSET 0
+#define SMPOWERMODESET_POWERSAVE_EN_WIDTH  1
+#define SMPOWERMODESET_MODE_OFFSET         1
+#define SMPOWERMODESET_MODE_WIDTH          1
+#define SMPOWERMODESET_RESERVED_OFFSET     2
+#define SMPOWERMODESET_RESERVED_WIDTH      6
+
+typedef struct sDot11fFfStatus {
+	uint16_t status;
+} tDot11fFfStatus;
+
+#define DOT11F_FF_STATUS_LEN (2)
+
+void dot11f_unpack_ff_Status(tpAniSirGlobal, uint8_t *, tDot11fFfStatus *);
+
+void dot11f_pack_ff_status(tpAniSirGlobal, tDot11fFfStatus *, uint8_t *);
+
+typedef struct sDot11fFfStatusCode {
+	uint8_t statusCode;
+} tDot11fFfStatusCode;
+
+#define DOT11F_FF_STATUSCODE_LEN (1)
+
+void dot11f_unpack_ff_status_code(tpAniSirGlobal, uint8_t *,
+				 tDot11fFfStatusCode *);
+
+void dot11f_pack_ff_status_code(tpAniSirGlobal, tDot11fFfStatusCode *,
+			       uint8_t *);
+
+typedef struct sDot11fFfTPCEleID {
+	uint8_t TPCId;
+} tDot11fFfTPCEleID;
+
+#define DOT11F_FF_TPCELEID_LEN (1)
+
+void dot11f_unpack_ff_tpc_ele_id(tpAniSirGlobal, uint8_t *,
+			       tDot11fFfTPCEleID *);
+
+void dot11f_pack_ff_tpc_ele_id(tpAniSirGlobal, tDot11fFfTPCEleID *, uint8_t *);
+
+typedef struct sDot11fFfTPCEleLen {
+	uint8_t TPCLen;
+} tDot11fFfTPCEleLen;
+
+#define DOT11F_FF_TPCELELEN_LEN (1)
+
+void dot11f_unpack_ff_tpc_ele_len(tpAniSirGlobal, uint8_t *,
+				tDot11fFfTPCEleLen *);
+
+void dot11f_pack_ff_tpc_ele_len(tpAniSirGlobal, tDot11fFfTPCEleLen *,
+			      uint8_t *);
+
+typedef struct sDot11fFfTSInfo {
+	uint32_t    traffic_type:1;
+	uint32_t            tsid:4;
+	uint32_t       direction:2;
+	uint32_t   access_policy:2;
+	uint32_t     aggregation:1;
+	uint32_t             psb:1;
+	uint32_t   user_priority:3;
+	uint32_t  tsinfo_ack_pol:2;
+	uint32_t        schedule:1;
+	uint32_t          unused:15;
+} tDot11fFfTSInfo;
+
+#define DOT11F_FF_TSINFO_LEN (3)
+
+void dot11f_unpack_ff_ts_info(tpAniSirGlobal, uint8_t *, tDot11fFfTSInfo *);
+
+void dot11f_pack_ff_ts_info(tpAniSirGlobal, tDot11fFfTSInfo *, uint8_t *);
+
+#define TSINFO_TRAFFIC_TYPE_OFFSET   0
+#define TSINFO_TRAFFIC_TYPE_WIDTH    1
+#define TSINFO_TSID_OFFSET           1
+#define TSINFO_TSID_WIDTH            4
+#define TSINFO_DIRECTION_OFFSET      5
+#define TSINFO_DIRECTION_WIDTH       2
+#define TSINFO_ACCESS_POLICY_OFFSET  7
+#define TSINFO_ACCESS_POLICY_WIDTH   2
+#define TSINFO_AGGREGATION_OFFSET    9
+#define TSINFO_AGGREGATION_WIDTH     1
+#define TSINFO_PSB_OFFSET            10
+#define TSINFO_PSB_WIDTH             1
+#define TSINFO_USER_PRIORITY_OFFSET  11
+#define TSINFO_USER_PRIORITY_WIDTH   3
+#define TSINFO_TSINFO_ACK_POL_OFFSET 14
+#define TSINFO_TSINFO_ACK_POL_WIDTH  2
+#define TSINFO_SCHEDULE_OFFSET       16
+#define TSINFO_SCHEDULE_WIDTH        1
+#define TSINFO_UNUSED_OFFSET         17
+#define TSINFO_UNUSED_WIDTH          15
+
+typedef struct sDot11fFfTimeStamp {
+	tDOT11F_U64 timestamp;
+} tDot11fFfTimeStamp;
+
+#define DOT11F_FF_TIMESTAMP_LEN (8)
+
+void dot11f_unpack_ff_time_stamp(tpAniSirGlobal, uint8_t *,
+				tDot11fFfTimeStamp *);
+
+void dot11f_pack_ff_time_stamp(tpAniSirGlobal, tDot11fFfTimeStamp *,
+			      uint8_t *);
+
+typedef struct sDot11fFfTransactionId {
+	uint8_t transId[2];
+} tDot11fFfTransactionId;
+
+#define DOT11F_FF_TRANSACTIONID_LEN (2)
+
+void dot11f_unpack_ff_transaction_id(tpAniSirGlobal, uint8_t *,
+				    tDot11fFfTransactionId *);
+
+void dot11f_pack_ff_transaction_id(tpAniSirGlobal, tDot11fFfTransactionId *,
+				  uint8_t *);
+
+typedef struct sDot11fFfTxAntennaId {
+	uint8_t antennaId;
+} tDot11fFfTxAntennaId;
+
+#define DOT11F_FF_TXANTENNAID_LEN (1)
+
+void dot11f_unpack_ff_tx_antenna_id(tpAniSirGlobal, uint8_t *,
+				  tDot11fFfTxAntennaId *);
+
+void dot11f_pack_ff_tx_antenna_id(tpAniSirGlobal, tDot11fFfTxAntennaId *,
+				uint8_t *);
+
+typedef struct sDot11fFfTxPower {
+	uint8_t txPower;
+} tDot11fFfTxPower;
+
+#define DOT11F_FF_TXPOWER_LEN (1)
+
+void dot11f_unpack_ff_tx_power(tpAniSirGlobal, uint8_t *,
+			      tDot11fFfTxPower *);
+
+void dot11f_pack_ff_tx_power(tpAniSirGlobal, tDot11fFfTxPower *, uint8_t *);
+
+typedef struct sDot11fFfVhtMembershipStatusArray {
+	uint8_t membershipStatusArray[8];
+} tDot11fFfVhtMembershipStatusArray;
+
+#define DOT11F_FF_VHTMEMBERSHIPSTATUSARRAY_LEN (8)
+
+void dot11f_unpack_ff_vht_membership_status_array(tpAniSirGlobal, uint8_t *,
+					       tDot11fFfVhtMembershipStatusArray *);
+
+void dot11f_pack_ff_vht_membership_status_array(tpAniSirGlobal,
+					     tDot11fFfVhtMembershipStatusArray *,
+					     uint8_t *);
+
+
+typedef struct sDot11fFfVhtUserPositionArray {
+	uint8_t userPositionArray[16];
+} tDot11fFfVhtUserPositionArray;
+
+#define DOT11F_FF_VHTUSERPOSITIONARRAY_LEN (16)
+
+void dot11f_unpack_ff_vht_user_position_array(tpAniSirGlobal, uint8_t *,
+					   tDot11fFfVhtUserPositionArray *);
+
+void dot11f_pack_ff_vht_user_position_array(tpAniSirGlobal,
+					 tDot11fFfVhtUserPositionArray *,
+					 uint8_t *);
+
+
+typedef struct sDot11fFfaddba_param_set {
+	uint16_t  amsdu_supp:1;
+	uint16_t      policy:1;
+	uint16_t         tid:4;
+	uint16_t   buff_size:10;
+} tDot11fFfaddba_param_set;
+
+#define DOT11F_FF_ADDBA_PARAM_SET_LEN (2)
+
+void dot11f_unpack_ff_addba_param_set(tpAniSirGlobal, uint8_t *,
+				      tDot11fFfaddba_param_set *);
+
+void dot11f_pack_ff_addba_param_set(tpAniSirGlobal, tDot11fFfaddba_param_set *,
+				    uint8_t *);
+
+#define ADDBA_PARAM_SET_AMSDU_SUPP_OFFSET 0
+#define ADDBA_PARAM_SET_AMSDU_SUPP_WIDTH  1
+#define ADDBA_PARAM_SET_POLICY_OFFSET     1
+#define ADDBA_PARAM_SET_POLICY_WIDTH      1
+#define ADDBA_PARAM_SET_TID_OFFSET        2
+#define ADDBA_PARAM_SET_TID_WIDTH         4
+#define ADDBA_PARAM_SET_BUFF_SIZE_OFFSET  6
+#define ADDBA_PARAM_SET_BUFF_SIZE_WIDTH   10
+
+typedef struct sDot11fFfba_start_seq_ctrl {
+	uint16_t  frag_number:4;
+	uint16_t          ssn:12;
+} tDot11fFfba_start_seq_ctrl;
+
+#define DOT11F_FF_BA_START_SEQ_CTRL_LEN (2)
+
+void dot11f_unpack_ff_ba_start_seq_ctrl(tpAniSirGlobal, uint8_t *,
+					tDot11fFfba_start_seq_ctrl *);
+
+void dot11f_pack_ff_ba_start_seq_ctrl(tpAniSirGlobal,
+				      tDot11fFfba_start_seq_ctrl *,
+				      uint8_t *);
+
+
+#define BA_START_SEQ_CTRL_FRAG_NUMBER_OFFSET 0
+#define BA_START_SEQ_CTRL_FRAG_NUMBER_WIDTH  4
+#define BA_START_SEQ_CTRL_SSN_OFFSET         4
+#define BA_START_SEQ_CTRL_SSN_WIDTH          12
+
+typedef struct sDot11fFfba_timeout {
+	uint16_t timeout;
+} tDot11fFfba_timeout;
+
+#define DOT11F_FF_BA_TIMEOUT_LEN (2)
+
+void dot11f_unpack_ff_ba_timeout(tpAniSirGlobal, uint8_t *,
+				 tDot11fFfba_timeout *);
+
+void dot11f_pack_ff_ba_timeout(tpAniSirGlobal, tDot11fFfba_timeout *,
+			       uint8_t *);
+
+typedef struct sDot11fFfdelba_param_set {
+	uint16_t   reserved:11;
+	uint16_t  initiator:1;
+	uint16_t        tid:4;
+} tDot11fFfdelba_param_set;
+
+#define DOT11F_FF_DELBA_PARAM_SET_LEN (2)
+
+void dot11f_unpack_ff_delba_param_set(tpAniSirGlobal, uint8_t *,
+				      tDot11fFfdelba_param_set *);
+
+void dot11f_pack_ff_delba_param_set(tpAniSirGlobal, tDot11fFfdelba_param_set *,
+				    uint8_t *);
+
+#define DELBA_PARAM_SET_RESERVED_OFFSET  0
+#define DELBA_PARAM_SET_RESERVED_WIDTH   11
+#define DELBA_PARAM_SET_INITIATOR_OFFSET 11
+#define DELBA_PARAM_SET_INITIATOR_WIDTH  1
+#define DELBA_PARAM_SET_TID_OFFSET       12
+#define DELBA_PARAM_SET_TID_WIDTH        4
+
+typedef struct sDot11fFfext_chan_switch_ann_action {
+	uint32_t   switch_mode:8;
+	uint32_t      op_class:8;
+	uint32_t   new_channel:8;
+	uint32_t  switch_count:8;
+} tDot11fFfext_chan_switch_ann_action;
+
+#define DOT11F_FF_EXT_CHAN_SWITCH_ANN_ACTION_LEN (4)
+
+void dot11f_unpack_ff_ext_chan_switch_ann_action(tpAniSirGlobal, uint8_t *,
+						 tDot11fFfext_chan_switch_ann_action *);
+
+void dot11f_pack_ff_ext_chan_switch_ann_action(tpAniSirGlobal,
+					       tDot11fFfext_chan_switch_ann_action *,
+					       uint8_t *);
+
+
+#define EXT_CHAN_SWITCH_ANN_ACTION_SWITCH_MODE_OFFSET  0
+#define EXT_CHAN_SWITCH_ANN_ACTION_SWITCH_MODE_WIDTH   8
+#define EXT_CHAN_SWITCH_ANN_ACTION_OP_CLASS_OFFSET     8
+#define EXT_CHAN_SWITCH_ANN_ACTION_OP_CLASS_WIDTH      8
+#define EXT_CHAN_SWITCH_ANN_ACTION_NEW_CHANNEL_OFFSET  16
+#define EXT_CHAN_SWITCH_ANN_ACTION_NEW_CHANNEL_WIDTH   8
+#define EXT_CHAN_SWITCH_ANN_ACTION_SWITCH_COUNT_OFFSET 24
+#define EXT_CHAN_SWITCH_ANN_ACTION_SWITCH_COUNT_WIDTH  8
+
+typedef struct sDot11fFfp2p_action_oui {
+	uint8_t oui_data[4];
+} tDot11fFfp2p_action_oui;
+
+#define DOT11F_FF_P2P_ACTION_OUI_LEN (4)
+
+void dot11f_unpack_ff_p2p_action_oui(tpAniSirGlobal, uint8_t *,
+				     tDot11fFfp2p_action_oui *);
+
+void dot11f_pack_ff_p2p_action_oui(tpAniSirGlobal, tDot11fFfp2p_action_oui *,
+				   uint8_t *);
+
+typedef struct sDot11fFfp2p_action_subtype {
+	uint8_t subtype;
+} tDot11fFfp2p_action_subtype;
+
+#define DOT11F_FF_P2P_ACTION_SUBTYPE_LEN (1)
+
+void dot11f_unpack_ff_p2p_action_subtype(tpAniSirGlobal, uint8_t *,
+					 tDot11fFfp2p_action_subtype *);
+
+void dot11f_pack_ff_p2p_action_subtype(tpAniSirGlobal,
+				       tDot11fFfp2p_action_subtype *,
+				       uint8_t *);
+
+
+/*********************************************************************
+ * TLVs                                                              *
+ ********************************************************************/
+
+
+/* ID 1 (0x0001) */
+typedef struct sDot11fTLVAuthorizedMACs {
+	uint8_t             present;
+	uint8_t             mac[6];
+} tDot11fTLVAuthorizedMACs;
+
+#define DOT11F_TLV_AUTHORIZEDMACS (1)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_AUTHORIZEDMACS_MIN_LEN (6)
+
+#define DOT11F_TLV_AUTHORIZEDMACS_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_authorized_ma_cs(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVAuthorizedMACs*);
+
+uint32_t dot11f_pack_tlv_authorized_ma_cs(
+	tpAniSirGlobal,
+	tDot11fTLVAuthorizedMACs *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_AuthorizedMACs(
+	tpAniSirGlobal,
+	tDot11fTLVAuthorizedMACs *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 3 (0x0003) */
+typedef struct sDot11fTLVRequestToEnroll {
+	uint8_t             present;
+	uint8_t             req;
+} tDot11fTLVRequestToEnroll;
+
+#define DOT11F_TLV_REQUESTTOENROLL (3)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_REQUESTTOENROLL_MIN_LEN (1)
+
+#define DOT11F_TLV_REQUESTTOENROLL_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_RequestToEnroll(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVRequestToEnroll*);
+
+uint32_t dot11f_pack_tlv_request_to_enroll(
+	tpAniSirGlobal,
+	tDot11fTLVRequestToEnroll *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_RequestToEnroll(
+	tpAniSirGlobal,
+	tDot11fTLVRequestToEnroll *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 0 (0x0000) */
+typedef struct sDot11fTLVVersion2 {
+	uint8_t             present;
+	uint8_t                minor:4;
+	uint8_t                major:4;
+} tDot11fTLVVersion2;
+
+#define DOT11F_TLV_VERSION2 (0)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_VERSION2_MIN_LEN (1)
+
+#define DOT11F_TLV_VERSION2_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_version2(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVVersion2*);
+
+uint32_t dot11f_pack_tlv_version2(
+	tpAniSirGlobal,
+	tDot11fTLVVersion2 *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_Version2(
+	tpAniSirGlobal,
+	tDot11fTLVVersion2 *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4183 (0x1057) */
+typedef struct sDot11fTLVAPSetupLocked {
+	uint8_t             present;
+	uint8_t             fLocked;
+} tDot11fTLVAPSetupLocked;
+
+#define DOT11F_TLV_APSETUPLOCKED (4183)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_APSETUPLOCKED_MIN_LEN (3)
+
+#define DOT11F_TLV_APSETUPLOCKED_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_APSetupLocked(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVAPSetupLocked*);
+
+uint32_t dot11f_pack_tlv_ap_setup_locked(
+	tpAniSirGlobal,
+	tDot11fTLVAPSetupLocked *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_APSetupLocked(
+	tpAniSirGlobal,
+	tDot11fTLVAPSetupLocked *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4098 (0x1002) */
+typedef struct sDot11fTLVAssociationState {
+	uint8_t             present;
+	uint16_t            state;
+} tDot11fTLVAssociationState;
+
+#define DOT11F_TLV_ASSOCIATIONSTATE (4098)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_ASSOCIATIONSTATE_MIN_LEN (4)
+
+#define DOT11F_TLV_ASSOCIATIONSTATE_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_AssociationState(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVAssociationState*);
+
+uint32_t dot11f_pack_tlv_association_state(
+	tpAniSirGlobal,
+	tDot11fTLVAssociationState *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_AssociationState(
+	tpAniSirGlobal,
+	tDot11fTLVAssociationState *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4104 (0x1008) */
+typedef struct sDot11fTLVConfigMethods {
+	uint8_t             present;
+	uint16_t            methods;
+} tDot11fTLVConfigMethods;
+
+#define DOT11F_TLV_CONFIGMETHODS (4104)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_CONFIGMETHODS_MIN_LEN (4)
+
+#define DOT11F_TLV_CONFIGMETHODS_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_ConfigMethods(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVConfigMethods*);
+
+uint32_t dot11f_pack_tlv_config_methods(
+	tpAniSirGlobal,
+	tDot11fTLVConfigMethods *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ConfigMethods(
+	tpAniSirGlobal,
+	tDot11fTLVConfigMethods *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4105 (0x1009) */
+typedef struct sDot11fTLVConfigurationError {
+	uint8_t             present;
+	uint16_t            error;
+} tDot11fTLVConfigurationError;
+
+#define DOT11F_TLV_CONFIGURATIONERROR (4105)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_CONFIGURATIONERROR_MIN_LEN (4)
+
+#define DOT11F_TLV_CONFIGURATIONERROR_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_ConfigurationError(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVConfigurationError*);
+
+uint32_t dot11f_pack_tlv_configuration_error(
+	tpAniSirGlobal,
+	tDot11fTLVConfigurationError *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ConfigurationError(
+	tpAniSirGlobal,
+	tDot11fTLVConfigurationError *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4113 (0x1011) */
+typedef struct sDot11fTLVDeviceName {
+	uint8_t             present;
+	uint8_t             num_text;
+	uint8_t             text[32];
+} tDot11fTLVDeviceName;
+
+#define DOT11F_TLV_DEVICENAME (4113)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_DEVICENAME_MIN_LEN (2)
+
+#define DOT11F_TLV_DEVICENAME_MAX_LEN (34)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_device_name(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVDeviceName*);
+
+uint32_t dot11f_pack_tlv_device_name(
+	tpAniSirGlobal,
+	tDot11fTLVDeviceName *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_DeviceName(
+	tpAniSirGlobal,
+	tDot11fTLVDeviceName *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4114 (0x1012) */
+typedef struct sDot11fTLVDevicePasswordID {
+	uint8_t             present;
+	uint16_t            id;
+} tDot11fTLVDevicePasswordID;
+
+#define DOT11F_TLV_DEVICEPASSWORDID (4114)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_DEVICEPASSWORDID_MIN_LEN (4)
+
+#define DOT11F_TLV_DEVICEPASSWORDID_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_DevicePasswordID(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVDevicePasswordID*);
+
+uint32_t dot11f_pack_tlv_device_password_id(
+	tpAniSirGlobal,
+	tDot11fTLVDevicePasswordID *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_DevicePasswordID(
+	tpAniSirGlobal,
+	tDot11fTLVDevicePasswordID *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 8 (0x0008) */
+typedef struct sDot11fTLVExtendedListenTiming {
+	uint8_t             present;
+	uint16_t            availibilityPeriod;
+	uint16_t            availibilityInterval;
+} tDot11fTLVExtendedListenTiming;
+
+#define DOT11F_TLV_EXTENDEDLISTENTIMING (8)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_EXTENDEDLISTENTIMING_MIN_LEN (5)
+
+#define DOT11F_TLV_EXTENDEDLISTENTIMING_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_extended_listen_timing(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVExtendedListenTiming*);
+
+uint32_t dot11f_pack_tlv_extended_listen_timing(
+	tpAniSirGlobal,
+	tDot11fTLVExtendedListenTiming *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ExtendedListenTiming(
+	tpAniSirGlobal,
+	tDot11fTLVExtendedListenTiming *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 6 (0x0006) */
+typedef struct sDot11fTLVListenChannel {
+	uint8_t             present;
+	uint8_t             countryString[3];
+	uint8_t             regulatoryClass;
+	uint8_t             channel;
+} tDot11fTLVListenChannel;
+
+#define DOT11F_TLV_LISTENCHANNEL (6)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_LISTENCHANNEL_MIN_LEN (6)
+
+#define DOT11F_TLV_LISTENCHANNEL_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_listen_channel(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVListenChannel*);
+
+uint32_t dot11f_pack_tlv_listen_channel(
+	tpAniSirGlobal,
+	tDot11fTLVListenChannel *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ListenChannel(
+	tpAniSirGlobal,
+	tDot11fTLVListenChannel *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4129 (0x1021) */
+typedef struct sDot11fTLVManufacturer {
+	uint8_t             present;
+	uint8_t             num_name;
+	uint8_t             name[64];
+} tDot11fTLVManufacturer;
+
+#define DOT11F_TLV_MANUFACTURER (4129)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_MANUFACTURER_MIN_LEN (2)
+
+#define DOT11F_TLV_MANUFACTURER_MAX_LEN (66)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_manufacturer(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVManufacturer*);
+
+uint32_t dot11f_pack_tlv_manufacturer(
+	tpAniSirGlobal,
+	tDot11fTLVManufacturer *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_Manufacturer(
+	tpAniSirGlobal,
+	tDot11fTLVManufacturer *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 1 (0x0001) */
+typedef struct sDot11fTLVMinorReasonCode {
+	uint8_t             present;
+	uint8_t             minorReasonCode;
+} tDot11fTLVMinorReasonCode;
+
+#define DOT11F_TLV_MINORREASONCODE (1)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_MINORREASONCODE_MIN_LEN (2)
+
+#define DOT11F_TLV_MINORREASONCODE_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_MinorReasonCode(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVMinorReasonCode*);
+
+uint32_t dot11f_pack_tlv_minor_reason_code(
+	tpAniSirGlobal,
+	tDot11fTLVMinorReasonCode *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_MinorReasonCode(
+	tpAniSirGlobal,
+	tDot11fTLVMinorReasonCode *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4131 (0x1023) */
+typedef struct sDot11fTLVModelName {
+	uint8_t             present;
+	uint8_t             num_text;
+	uint8_t             text[32];
+} tDot11fTLVModelName;
+
+#define DOT11F_TLV_MODELNAME (4131)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_MODELNAME_MIN_LEN (2)
+
+#define DOT11F_TLV_MODELNAME_MAX_LEN (34)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_model_name(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVModelName*);
+
+uint32_t dot11f_pack_tlv_model_name(
+	tpAniSirGlobal,
+	tDot11fTLVModelName *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ModelName(
+	tpAniSirGlobal,
+	tDot11fTLVModelName *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4132 (0x1024) */
+typedef struct sDot11fTLVModelNumber {
+	uint8_t             present;
+	uint8_t             num_text;
+	uint8_t             text[32];
+} tDot11fTLVModelNumber;
+
+#define DOT11F_TLV_MODELNUMBER (4132)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_MODELNUMBER_MIN_LEN (2)
+
+#define DOT11F_TLV_MODELNUMBER_MAX_LEN (34)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_model_number(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVModelNumber*);
+
+uint32_t dot11f_pack_tlv_model_number(
+	tpAniSirGlobal,
+	tDot11fTLVModelNumber *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ModelNumber(
+	tpAniSirGlobal,
+	tDot11fTLVModelNumber *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 12 (0x000c) */
+typedef struct sDot11fTLVNoticeOfAbsence {
+	uint8_t             present;
+	uint8_t             index;
+	uint8_t             CTSWindowOppPS;
+	uint8_t             num_NoADesc;
+	uint8_t             NoADesc[36];
+} tDot11fTLVNoticeOfAbsence;
+
+#define DOT11F_TLV_NOTICEOFABSENCE (12)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_NOTICEOFABSENCE_MIN_LEN (3)
+
+#define DOT11F_TLV_NOTICEOFABSENCE_MAX_LEN (39)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_notice_of_absence(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVNoticeOfAbsence*);
+
+uint32_t dot11f_pack_tlv_notice_of_absence(
+	tpAniSirGlobal,
+	tDot11fTLVNoticeOfAbsence *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_NoticeOfAbsence(
+	tpAniSirGlobal,
+	tDot11fTLVNoticeOfAbsence *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 17 (0x0011) */
+typedef struct sDot11fTLVOperatingChannel {
+	uint8_t             present;
+	uint8_t             countryString[3];
+	uint8_t             regulatoryClass;
+	uint8_t             channel;
+} tDot11fTLVOperatingChannel;
+
+#define DOT11F_TLV_OPERATINGCHANNEL (17)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_OPERATINGCHANNEL_MIN_LEN (6)
+
+#define DOT11F_TLV_OPERATINGCHANNEL_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_operating_channel(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVOperatingChannel*);
+
+uint32_t dot11f_pack_tlv_operating_channel(
+	tpAniSirGlobal,
+	tDot11fTLVOperatingChannel *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_OperatingChannel(
+	tpAniSirGlobal,
+	tDot11fTLVOperatingChannel *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 2 (0x0002) */
+typedef struct sDot11fTLVP2PCapability {
+	uint8_t             present;
+	uint8_t             deviceCapability;
+	uint8_t             groupCapability;
+} tDot11fTLVP2PCapability;
+
+#define DOT11F_TLV_P2PCAPABILITY (2)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PCAPABILITY_MIN_LEN (3)
+
+#define DOT11F_TLV_P2PCAPABILITY_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_p2_p_capability(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVP2PCapability*);
+
+uint32_t dot11f_pack_tlv_p2_p_capability(
+	tpAniSirGlobal,
+	tDot11fTLVP2PCapability *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PCapability(
+	tpAniSirGlobal,
+	tDot11fTLVP2PCapability *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 3 (0x0003) */
+typedef struct sDot11fTLVP2PDeviceId {
+	uint8_t             present;
+	uint8_t             P2PDeviceAddress[6];
+} tDot11fTLVP2PDeviceId;
+
+#define DOT11F_TLV_P2PDEVICEID (3)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PDEVICEID_MIN_LEN (7)
+
+#define DOT11F_TLV_P2PDEVICEID_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_p2_p_device_id(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVP2PDeviceId*);
+
+uint32_t dot11f_pack_tlv_p2_p_device_id(
+	tpAniSirGlobal,
+	tDot11fTLVP2PDeviceId *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PDeviceId(
+	tpAniSirGlobal,
+	tDot11fTLVP2PDeviceId *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 13 (0x000d) */
+typedef struct sDot11fTLVP2PDeviceInfo {
+	uint8_t                     present;
+	uint8_t                     P2PDeviceAddress[6];
+	uint16_t                    configMethod;
+	uint8_t                     primaryDeviceType[8];
+	tDot11fTLVDeviceName        DeviceName;
+} tDot11fTLVP2PDeviceInfo;
+
+#define DOT11F_TLV_P2PDEVICEINFO (13)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PDEVICEINFO_MIN_LEN (17)
+
+#define DOT11F_TLV_P2PDEVICEINFO_MAX_LEN (53)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_p2_p_device_info(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVP2PDeviceInfo*);
+
+uint32_t dot11f_pack_tlv_p2_p_device_info(
+	tpAniSirGlobal,
+	tDot11fTLVP2PDeviceInfo *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PDeviceInfo(
+	tpAniSirGlobal,
+	tDot11fTLVP2PDeviceInfo *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 14 (0x000e) */
+typedef struct sDot11fTLVP2PGroupInfo {
+	uint8_t             present;
+	uint8_t             num_P2PClientInfoDesc;
+	uint8_t             P2PClientInfoDesc[1024];
+} tDot11fTLVP2PGroupInfo;
+
+#define DOT11F_TLV_P2PGROUPINFO (14)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PGROUPINFO_MIN_LEN (1)
+
+#define DOT11F_TLV_P2PGROUPINFO_MAX_LEN (1025)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_p2_p_group_info(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVP2PGroupInfo*);
+
+uint32_t dot11f_pack_tlv_p2_p_group_info(
+	tpAniSirGlobal,
+	tDot11fTLVP2PGroupInfo *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PGroupInfo(
+	tpAniSirGlobal,
+	tDot11fTLVP2PGroupInfo *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 0 (0x0000) */
+typedef struct sDot11fTLVP2PStatus {
+	uint8_t             present;
+	uint8_t             status;
+} tDot11fTLVP2PStatus;
+
+#define DOT11F_TLV_P2PSTATUS (0)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PSTATUS_MIN_LEN (2)
+
+#define DOT11F_TLV_P2PSTATUS_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_P2PStatus(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVP2PStatus*);
+
+uint32_t dot11f_pack_tlv_p2_p_status(
+	tpAniSirGlobal,
+	tDot11fTLVP2PStatus *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PStatus(
+	tpAniSirGlobal,
+	tDot11fTLVP2PStatus *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4180 (0x1054) */
+typedef struct sDot11fTLVPrimaryDeviceType {
+	uint8_t             present;
+	uint16_t            primary_category;
+	uint8_t             oui[4];
+	uint16_t            sub_category;
+} tDot11fTLVPrimaryDeviceType;
+
+#define DOT11F_TLV_PRIMARYDEVICETYPE (4180)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_PRIMARYDEVICETYPE_MIN_LEN (10)
+
+#define DOT11F_TLV_PRIMARYDEVICETYPE_MAX_LEN (10)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_primary_device_type(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVPrimaryDeviceType*);
+
+uint32_t dot11f_pack_tlv_primary_device_type(
+	tpAniSirGlobal,
+	tDot11fTLVPrimaryDeviceType *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_PrimaryDeviceType(
+	tpAniSirGlobal,
+	tDot11fTLVPrimaryDeviceType *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4156 (0x103c) */
+typedef struct sDot11fTLVRFBands {
+	uint8_t             present;
+	uint8_t             bands;
+} tDot11fTLVRFBands;
+
+#define DOT11F_TLV_RFBANDS (4156)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_RFBANDS_MIN_LEN (3)
+
+#define DOT11F_TLV_RFBANDS_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_RFBands(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVRFBands*);
+
+uint32_t dot11f_pack_tlv_rf_bands(
+	tpAniSirGlobal,
+	tDot11fTLVRFBands *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_RFBands(
+	tpAniSirGlobal,
+	tDot11fTLVRFBands *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4202 (0x106a) */
+typedef struct sDot11fTLVRequestDeviceType {
+	uint8_t             present;
+	uint16_t            primary_category;
+	uint8_t             oui[4];
+	uint16_t            sub_category;
+} tDot11fTLVRequestDeviceType;
+
+#define DOT11F_TLV_REQUESTDEVICETYPE (4202)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_REQUESTDEVICETYPE_MIN_LEN (10)
+
+#define DOT11F_TLV_REQUESTDEVICETYPE_MAX_LEN (10)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_request_device_type(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVRequestDeviceType*);
+
+uint32_t dot11f_pack_tlv_request_device_type(
+	tpAniSirGlobal,
+	tDot11fTLVRequestDeviceType *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_RequestDeviceType(
+	tpAniSirGlobal,
+	tDot11fTLVRequestDeviceType *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4154 (0x103a) */
+typedef struct sDot11fTLVRequestType {
+	uint8_t             present;
+	uint8_t             reqType;
+} tDot11fTLVRequestType;
+
+#define DOT11F_TLV_REQUESTTYPE (4154)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_REQUESTTYPE_MIN_LEN (3)
+
+#define DOT11F_TLV_REQUESTTYPE_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_RequestType(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVRequestType*);
+
+uint32_t dot11f_pack_tlv_request_type(
+	tpAniSirGlobal,
+	tDot11fTLVRequestType *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_RequestType(
+	tpAniSirGlobal,
+	tDot11fTLVRequestType *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4155 (0x103b) */
+typedef struct sDot11fTLVResponseType {
+	uint8_t             present;
+	uint8_t             resType;
+} tDot11fTLVResponseType;
+
+#define DOT11F_TLV_RESPONSETYPE (4155)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_RESPONSETYPE_MIN_LEN (3)
+
+#define DOT11F_TLV_RESPONSETYPE_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_ResponseType(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVResponseType*);
+
+uint32_t dot11f_pack_tlv_response_type(
+	tpAniSirGlobal,
+	tDot11fTLVResponseType *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ResponseType(
+	tpAniSirGlobal,
+	tDot11fTLVResponseType *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4161 (0x1041) */
+typedef struct sDot11fTLVSelectedRegistrar {
+	uint8_t             present;
+	uint8_t             selected;
+} tDot11fTLVSelectedRegistrar;
+
+#define DOT11F_TLV_SELECTEDREGISTRAR (4161)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_SELECTEDREGISTRAR_MIN_LEN (3)
+
+#define DOT11F_TLV_SELECTEDREGISTRAR_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_SelectedRegistrar(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVSelectedRegistrar*);
+
+uint32_t dot11f_pack_tlv_selected_registrar(
+	tpAniSirGlobal,
+	tDot11fTLVSelectedRegistrar *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_SelectedRegistrar(
+	tpAniSirGlobal,
+	tDot11fTLVSelectedRegistrar *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4179 (0x1053) */
+typedef struct sDot11fTLVSelectedRegistrarConfigMethods {
+	uint8_t             present;
+	uint16_t            methods;
+} tDot11fTLVSelectedRegistrarConfigMethods;
+
+#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS (4179)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS_MIN_LEN (4)
+
+#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_SelectedRegistrarConfigMethods(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVSelectedRegistrarConfigMethods*);
+
+uint32_t dot11f_pack_tlv_selected_registrar_config_methods(
+	tpAniSirGlobal,
+	tDot11fTLVSelectedRegistrarConfigMethods *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_SelectedRegistrarConfigMethods(
+	tpAniSirGlobal,
+	tDot11fTLVSelectedRegistrarConfigMethods *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4162 (0x1042) */
+typedef struct sDot11fTLVSerialNumber {
+	uint8_t             present;
+	uint8_t             num_text;
+	uint8_t             text[32];
+} tDot11fTLVSerialNumber;
+
+#define DOT11F_TLV_SERIALNUMBER (4162)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_SERIALNUMBER_MIN_LEN (2)
+
+#define DOT11F_TLV_SERIALNUMBER_MAX_LEN (34)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_serial_number(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVSerialNumber*);
+
+uint32_t dot11f_pack_tlv_serial_number(
+	tpAniSirGlobal,
+	tDot11fTLVSerialNumber *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_SerialNumber(
+	tpAniSirGlobal,
+	tDot11fTLVSerialNumber *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4167 (0x1047) */
+typedef struct sDot11fTLVUUID_E {
+	uint8_t             present;
+	uint8_t             uuid[16];
+} tDot11fTLVUUID_E;
+
+#define DOT11F_TLV_UUID_E (4167)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_UUID_E_MIN_LEN (18)
+
+#define DOT11F_TLV_UUID_E_MAX_LEN (18)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_uuid_e(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVUUID_E*);
+
+uint32_t dot11f_pack_tlv_uuid_e(
+	tpAniSirGlobal,
+	tDot11fTLVUUID_E *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_UUID_E(
+	tpAniSirGlobal,
+	tDot11fTLVUUID_E *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4168 (0x1048) */
+typedef struct sDot11fTLVUUID_R {
+	uint8_t             present;
+	uint8_t             uuid[16];
+} tDot11fTLVUUID_R;
+
+#define DOT11F_TLV_UUID_R (4168)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_UUID_R_MIN_LEN (18)
+
+#define DOT11F_TLV_UUID_R_MAX_LEN (18)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_uuid_r(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVUUID_R*);
+
+uint32_t dot11f_pack_tlv_uuid_r(
+	tpAniSirGlobal,
+	tDot11fTLVUUID_R *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_UUID_R(
+	tpAniSirGlobal,
+	tDot11fTLVUUID_R *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4169 (0x1049) */
+typedef struct sDot11fTLVVendorExtension {
+	uint8_t                          present;
+	uint8_t                          vendorId[3];
+	tDot11fTLVVersion2               Version2;
+	tDot11fTLVAuthorizedMACs         AuthorizedMACs;
+	tDot11fTLVRequestToEnroll        RequestToEnroll;
+} tDot11fTLVVendorExtension;
+
+#define DOT11F_TLV_VENDOREXTENSION (4169)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_VENDOREXTENSION_MIN_LEN (5)
+
+#define DOT11F_TLV_VENDOREXTENSION_MAX_LEN (19)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_vendor_extension(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVVendorExtension*);
+
+uint32_t dot11f_pack_tlv_vendor_extension(
+	tpAniSirGlobal,
+	tDot11fTLVVendorExtension *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_VendorExtension(
+	tpAniSirGlobal,
+	tDot11fTLVVendorExtension *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4170 (0x104a) */
+typedef struct sDot11fTLVVersion {
+	uint8_t             present;
+	uint8_t                minor:4;
+	uint8_t                major:4;
+} tDot11fTLVVersion;
+
+#define DOT11F_TLV_VERSION (4170)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_VERSION_MIN_LEN (3)
+
+#define DOT11F_TLV_VERSION_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_version(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVVersion*);
+
+uint32_t dot11f_pack_tlv_version(
+	tpAniSirGlobal,
+	tDot11fTLVVersion *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_Version(
+	tpAniSirGlobal,
+	tDot11fTLVVersion *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4164 (0x1044) */
+typedef struct sDot11fTLVWPSState {
+	uint8_t             present;
+	uint8_t             state;
+} tDot11fTLVWPSState;
+
+#define DOT11F_TLV_WPSSTATE (4164)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_WPSSTATE_MIN_LEN (3)
+
+#define DOT11F_TLV_WPSSTATE_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_WPSState(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVWPSState*);
+
+uint32_t dot11f_pack_tlv_wps_state(
+	tpAniSirGlobal,
+	tDot11fTLVWPSState *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_WPSState(
+	tpAniSirGlobal,
+	tDot11fTLVWPSState *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4 (0x0004) */
+typedef struct sDot11fTLVassoc_disallowed {
+	uint8_t             present;
+	uint8_t             reason_code;
+} tDot11fTLVassoc_disallowed;
+
+#define DOT11F_TLV_ASSOC_DISALLOWED (4)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_ASSOC_DISALLOWED_MIN_LEN (1)
+
+#define DOT11F_TLV_ASSOC_DISALLOWED_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_assoc_disallowed(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVassoc_disallowed*);
+
+uint32_t dot11f_pack_tlv_assoc_disallowed(
+	tpAniSirGlobal,
+	tDot11fTLVassoc_disallowed *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_assoc_disallowed(
+	tpAniSirGlobal,
+	tDot11fTLVassoc_disallowed *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 8 (0x0008) */
+typedef struct sDot11fTLVassoc_retry_delay {
+	uint8_t             present;
+	uint16_t            delay;
+} tDot11fTLVassoc_retry_delay;
+
+#define DOT11F_TLV_ASSOC_RETRY_DELAY (8)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_ASSOC_RETRY_DELAY_MIN_LEN (2)
+
+#define DOT11F_TLV_ASSOC_RETRY_DELAY_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_assoc_retry_delay(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVassoc_retry_delay*);
+
+uint32_t dot11f_pack_tlv_assoc_retry_delay(
+	tpAniSirGlobal,
+	tDot11fTLVassoc_retry_delay *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_assoc_retry_delay(
+	tpAniSirGlobal,
+	tDot11fTLVassoc_retry_delay *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 3 (0x0003) */
+typedef struct sDot11fTLVcellular_data_cap {
+	uint8_t             present;
+	uint8_t             cellular_connectivity;
+} tDot11fTLVcellular_data_cap;
+
+#define DOT11F_TLV_CELLULAR_DATA_CAP (3)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_CELLULAR_DATA_CAP_MIN_LEN (1)
+
+#define DOT11F_TLV_CELLULAR_DATA_CAP_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_cellular_data_cap(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVcellular_data_cap*);
+
+uint32_t dot11f_pack_tlv_cellular_data_cap(
+	tpAniSirGlobal,
+	tDot11fTLVcellular_data_cap *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_cellular_data_cap(
+	tpAniSirGlobal,
+	tDot11fTLVcellular_data_cap *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 5 (0x0005) */
+typedef struct sDot11fTLVcellular_data_con_pref {
+	uint8_t             present;
+	uint8_t             cellular_preference;
+} tDot11fTLVcellular_data_con_pref;
+
+#define DOT11F_TLV_CELLULAR_DATA_CON_PREF (5)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_CELLULAR_DATA_CON_PREF_MIN_LEN (1)
+
+#define DOT11F_TLV_CELLULAR_DATA_CON_PREF_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_cellular_data_con_pref(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVcellular_data_con_pref*);
+
+uint32_t dot11f_pack_tlv_cellular_data_con_pref(
+	tpAniSirGlobal,
+	tDot11fTLVcellular_data_con_pref *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_cellular_data_con_pref(
+	tpAniSirGlobal,
+	tDot11fTLVcellular_data_con_pref *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 1 (0x0001) */
+typedef struct sDot11fTLVmbo_ap_cap {
+	uint8_t             present;
+	uint8_t             mbo_cap_ind;
+} tDot11fTLVmbo_ap_cap;
+
+#define DOT11F_TLV_MBO_AP_CAP (1)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_MBO_AP_CAP_MIN_LEN (1)
+
+#define DOT11F_TLV_MBO_AP_CAP_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_mbo_ap_cap(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVmbo_ap_cap*);
+
+uint32_t dot11f_pack_tlv_mbo_ap_cap(
+	tpAniSirGlobal,
+	tDot11fTLVmbo_ap_cap *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_mbo_ap_cap(
+	tpAniSirGlobal,
+	tDot11fTLVmbo_ap_cap *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 2 (0x0002) */
+typedef struct sDot11fTLVnon_prefferd_chan_rep {
+	uint8_t             present;
+	uint8_t             oper_class;
+	uint8_t             num_channel_report;
+	uint8_t             channel_report[254];
+} tDot11fTLVnon_prefferd_chan_rep;
+
+#define DOT11F_TLV_NON_PREFFERD_CHAN_REP (2)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_NON_PREFFERD_CHAN_REP_MIN_LEN (4)
+
+#define DOT11F_TLV_NON_PREFFERD_CHAN_REP_MAX_LEN (255)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_non_prefferd_chan_rep(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVnon_prefferd_chan_rep*);
+
+uint32_t dot11f_pack_tlv_non_prefferd_chan_rep(
+	tpAniSirGlobal,
+	tDot11fTLVnon_prefferd_chan_rep *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_non_prefferd_chan_rep(
+	tpAniSirGlobal,
+	tDot11fTLVnon_prefferd_chan_rep *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 101 (0x0065) */
+typedef struct sDot11fTLVoce_cap {
+	uint8_t             present;
+	uint8_t          oce_release:3;
+	uint8_t          is_sta_cfon:1;
+	uint8_t   non_oce_ap_present:1;
+	uint8_t             reserved:3;
+} tDot11fTLVoce_cap;
+
+#define DOT11F_TLV_OCE_CAP (101)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_OCE_CAP_MIN_LEN (1)
+
+#define DOT11F_TLV_OCE_CAP_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_oce_cap(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVoce_cap*);
+
+uint32_t dot11f_pack_tlv_oce_cap(
+	tpAniSirGlobal,
+	tDot11fTLVoce_cap *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_oce_cap(
+	tpAniSirGlobal,
+	tDot11fTLVoce_cap *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 103 (0x0067) */
+typedef struct sDot11fTLVreduced_wan_metrics {
+	uint8_t             present;
+	uint8_t      downlink_av_cap:4;
+	uint8_t        uplink_av_cap:4;
+} tDot11fTLVreduced_wan_metrics;
+
+#define DOT11F_TLV_REDUCED_WAN_METRICS (103)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_REDUCED_WAN_METRICS_MIN_LEN (1)
+
+#define DOT11F_TLV_REDUCED_WAN_METRICS_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_reduced_wan_metrics(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVreduced_wan_metrics*);
+
+uint32_t dot11f_pack_tlv_reduced_wan_metrics(
+	tpAniSirGlobal,
+	tDot11fTLVreduced_wan_metrics *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_reduced_wan_metrics(
+	tpAniSirGlobal,
+	tDot11fTLVreduced_wan_metrics *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 102 (0x0066) */
+typedef struct sDot11fTLVrssi_assoc_rej {
+	uint8_t             present;
+	uint8_t             delta_rssi;
+	uint8_t             retry_delay;
+} tDot11fTLVrssi_assoc_rej;
+
+#define DOT11F_TLV_RSSI_ASSOC_REJ (102)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_RSSI_ASSOC_REJ_MIN_LEN (2)
+
+#define DOT11F_TLV_RSSI_ASSOC_REJ_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_rssi_assoc_rej(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVrssi_assoc_rej*);
+
+uint32_t dot11f_pack_tlv_rssi_assoc_rej(
+	tpAniSirGlobal,
+	tDot11fTLVrssi_assoc_rej *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_rssi_assoc_rej(
+	tpAniSirGlobal,
+	tDot11fTLVrssi_assoc_rej *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 6 (0x0006) */
+typedef struct sDot11fTLVtransition_reason {
+	uint8_t             present;
+	uint8_t             transition_reason_code;
+} tDot11fTLVtransition_reason;
+
+#define DOT11F_TLV_TRANSITION_REASON (6)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_TRANSITION_REASON_MIN_LEN (1)
+
+#define DOT11F_TLV_TRANSITION_REASON_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_transition_reason(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVtransition_reason*);
+
+uint32_t dot11f_pack_tlv_transition_reason(
+	tpAniSirGlobal,
+	tDot11fTLVtransition_reason *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_transition_reason(
+	tpAniSirGlobal,
+	tDot11fTLVtransition_reason *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 7 (0x0007) */
+typedef struct sDot11fTLVtransition_reject_reason {
+	uint8_t             present;
+	uint8_t             transition_reject_code;
+} tDot11fTLVtransition_reject_reason;
+
+#define DOT11F_TLV_TRANSITION_REJECT_REASON (7)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_TRANSITION_REJECT_REASON_MIN_LEN (1)
+
+#define DOT11F_TLV_TRANSITION_REJECT_REASON_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_transition_reject_reason(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVtransition_reject_reason*);
+
+uint32_t dot11f_pack_tlv_transition_reject_reason(
+	tpAniSirGlobal,
+	tDot11fTLVtransition_reject_reason *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_transition_reject_reason(
+	tpAniSirGlobal,
+	tDot11fTLVtransition_reject_reason *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 16 (0x0010) */
+typedef struct sDot11fTLVP2PInterface {
+	uint8_t             present;
+	uint8_t             P2PDeviceAddress[6];
+} tDot11fTLVP2PInterface;
+
+#define DOT11F_TLV_P2PINTERFACE (16)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PINTERFACE_MIN_LEN (7)
+
+#define DOT11F_TLV_P2PINTERFACE_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_p2_p_interface(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVP2PInterface*);
+
+uint32_t dot11f_pack_tlv_p2_p_interface(
+	tpAniSirGlobal,
+	tDot11fTLVP2PInterface *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PInterface(
+	tpAniSirGlobal,
+	tDot11fTLVP2PInterface *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 10 (0x000a) */
+typedef struct sDot11fTLVP2PManageability {
+	uint8_t             present;
+	uint8_t             manageability;
+} tDot11fTLVP2PManageability;
+
+#define DOT11F_TLV_P2PMANAGEABILITY (10)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PMANAGEABILITY_MIN_LEN (2)
+
+#define DOT11F_TLV_P2PMANAGEABILITY_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_P2PManageability(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint16_t,
+	tDot11fTLVP2PManageability*);
+
+uint32_t dot11f_pack_tlv_p2_p_manageability(
+	tpAniSirGlobal,
+	tDot11fTLVP2PManageability *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PManageability(
+	tpAniSirGlobal,
+	tDot11fTLVP2PManageability *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+/*********************************************************************
+ * Information Elements                                              *
+ ********************************************************************/
+
+
+/* EID 2 (0x02) */
+typedef struct sDot11fIEGTK {
+	uint8_t             present;
+	uint16_t                keyId:2;
+	uint16_t             reserved:14;
+	uint8_t             keyLength;
+	uint8_t             RSC[8];
+	uint8_t             num_key;
+	uint8_t             key[32];
+} tDot11fIEGTK;
+
+#define DOT11F_EID_GTK (2)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_GTK_MIN_LEN (16)
+
+#define DOT11F_IE_GTK_MAX_LEN (43)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_gtk(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEGTK*,
+	bool);
+
+uint32_t dot11f_pack_ie_gtk(
+	tpAniSirGlobal,
+	tDot11fIEGTK *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_GTK(
+	tpAniSirGlobal,
+	tDot11fIEGTK *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 4 (0x04) */
+typedef struct sDot11fIEIGTK {
+	uint8_t             present;
+	uint8_t             keyID[2];
+	uint8_t             IPN[6];
+	uint8_t             keyLength;
+	uint8_t             key[24];
+} tDot11fIEIGTK;
+
+#define DOT11F_EID_IGTK (4)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_IGTK_MIN_LEN (33)
+
+#define DOT11F_IE_IGTK_MAX_LEN (33)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_igtk(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEIGTK*,
+	bool);
+
+uint32_t dot11f_pack_ie_igtk(
+	tpAniSirGlobal,
+	tDot11fIEIGTK *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_IGTK(
+	tpAniSirGlobal,
+	tDot11fIEIGTK *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 3 (0x03) */
+typedef struct sDot11fIER0KH_ID {
+	uint8_t             present;
+	uint8_t             num_PMK_R0_ID;
+	uint8_t             PMK_R0_ID[48];
+} tDot11fIER0KH_ID;
+
+#define DOT11F_EID_R0KH_ID (3)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_R0KH_ID_MIN_LEN (1)
+
+#define DOT11F_IE_R0KH_ID_MAX_LEN (48)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_r0_kh_id(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIER0KH_ID*,
+	bool);
+
+uint32_t dot11f_pack_ie_r0_kh_id(
+	tpAniSirGlobal,
+	tDot11fIER0KH_ID *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_R0KH_ID(
+	tpAniSirGlobal,
+	tDot11fIER0KH_ID *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 1 (0x01) */
+typedef struct sDot11fIER1KH_ID {
+	uint8_t             present;
+	uint8_t             PMK_R1_ID[6];
+} tDot11fIER1KH_ID;
+
+#define DOT11F_EID_R1KH_ID (1)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_R1KH_ID_MIN_LEN (6)
+
+#define DOT11F_IE_R1KH_ID_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_r1_kh_id(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIER1KH_ID*,
+	bool);
+
+uint32_t dot11f_pack_ie_r1_kh_id(
+	tpAniSirGlobal,
+	tDot11fIER1KH_ID *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_R1KH_ID(
+	tpAniSirGlobal,
+	tDot11fIER1KH_ID *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 51 (0x33) */
+typedef struct sDot11fIEAPChannelReport {
+	uint8_t             present;
+	uint8_t             regulatoryClass;
+	uint8_t             num_channelList;
+	uint8_t             channelList[50];
+} tDot11fIEAPChannelReport;
+
+#define DOT11F_EID_APCHANNELREPORT (51)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_APCHANNELREPORT_MIN_LEN (1)
+
+#define DOT11F_IE_APCHANNELREPORT_MAX_LEN (51)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ap_channel_report(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEAPChannelReport*,
+	bool);
+
+uint32_t dot11f_pack_ie_ap_channel_report(
+	tpAniSirGlobal,
+	tDot11fIEAPChannelReport *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_APChannelReport(
+	tpAniSirGlobal,
+	tDot11fIEAPChannelReport *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 2 (0x02) */
+typedef struct sDot11fIEBcnReportingDetail {
+	uint8_t             present;
+	uint8_t             reportingDetail;
+} tDot11fIEBcnReportingDetail;
+
+#define DOT11F_EID_BCNREPORTINGDETAIL (2)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_BCNREPORTINGDETAIL_MIN_LEN (1)
+
+#define DOT11F_IE_BCNREPORTINGDETAIL_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_bcn_reporting_detail(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEBcnReportingDetail*,
+	bool);
+
+uint32_t dot11f_pack_ie_bcn_reporting_detail(
+	tpAniSirGlobal,
+	tDot11fIEBcnReportingDetail *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_BcnReportingDetail(
+	tpAniSirGlobal,
+	tDot11fIEBcnReportingDetail *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 1 (0x01) */
+typedef struct sDot11fIEBeaconReportFrmBody {
+	uint8_t             present;
+	uint8_t             num_reportedFields;
+	uint8_t             reportedFields[224];
+} tDot11fIEBeaconReportFrmBody;
+
+#define DOT11F_EID_BEACONREPORTFRMBODY (1)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_BEACONREPORTFRMBODY_MIN_LEN (0)
+
+#define DOT11F_IE_BEACONREPORTFRMBODY_MAX_LEN (224)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_beacon_report_frm_body(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEBeaconReportFrmBody*,
+	bool);
+
+uint32_t dot11f_pack_ie_beacon_report_frm_body(
+	tpAniSirGlobal,
+	tDot11fIEBeaconReportFrmBody *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_BeaconReportFrmBody(
+	tpAniSirGlobal,
+	tDot11fIEBeaconReportFrmBody *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 1 (0x01) */
+typedef struct sDot11fIEBeaconReporting {
+	uint8_t             present;
+	uint8_t             reportingCondition;
+	uint8_t             threshold;
+} tDot11fIEBeaconReporting;
+
+#define DOT11F_EID_BEACONREPORTING (1)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_BEACONREPORTING_MIN_LEN (2)
+
+#define DOT11F_IE_BEACONREPORTING_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_beacon_reporting(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEBeaconReporting*,
+	bool);
+
+uint32_t dot11f_pack_ie_beacon_reporting(
+	tpAniSirGlobal,
+	tDot11fIEBeaconReporting *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_BeaconReporting(
+	tpAniSirGlobal,
+	tDot11fIEBeaconReporting *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 2 (0x02) */
+typedef struct sDot11fIECondensedCountryStr {
+	uint8_t             present;
+	uint8_t             countryStr[2];
+} tDot11fIECondensedCountryStr;
+
+#define DOT11F_EID_CONDENSEDCOUNTRYSTR (2)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_CONDENSEDCOUNTRYSTR_MIN_LEN (2)
+
+#define DOT11F_IE_CONDENSEDCOUNTRYSTR_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_condensed_country_str(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIECondensedCountryStr*,
+	bool);
+
+uint32_t dot11f_pack_ie_condensed_country_str(
+	tpAniSirGlobal,
+	tDot11fIECondensedCountryStr *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_CondensedCountryStr(
+	tpAniSirGlobal,
+	tDot11fIECondensedCountryStr *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 66 (0x42) */
+typedef struct sDot11fIEMeasurementPilot {
+	uint8_t             present;
+	uint8_t             measurementPilot;
+	uint8_t             num_vendorSpecific;
+	uint8_t             vendorSpecific[255];
+} tDot11fIEMeasurementPilot;
+
+#define DOT11F_EID_MEASUREMENTPILOT (66)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MEASUREMENTPILOT_MIN_LEN (1)
+
+#define DOT11F_IE_MEASUREMENTPILOT_MAX_LEN (256)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_measurement_pilot(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEMeasurementPilot*,
+	bool);
+
+uint32_t dot11f_pack_ie_measurement_pilot(
+	tpAniSirGlobal,
+	tDot11fIEMeasurementPilot *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_MeasurementPilot(
+	tpAniSirGlobal,
+	tDot11fIEMeasurementPilot *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 71 (0x47) */
+typedef struct sDot11fIEMultiBssid {
+	uint8_t             present;
+	uint8_t             maxBSSIDIndicator;
+	uint8_t             num_vendorSpecific;
+	uint8_t             vendorSpecific[255];
+} tDot11fIEMultiBssid;
+
+#define DOT11F_EID_MULTIBSSID (71)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MULTIBSSID_MIN_LEN (1)
+
+#define DOT11F_IE_MULTIBSSID_MAX_LEN (256)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_multi_bssid(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEMultiBssid*,
+	bool);
+
+uint32_t dot11f_pack_ie_multi_bssid(
+	tpAniSirGlobal,
+	tDot11fIEMultiBssid *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_MultiBssid(
+	tpAniSirGlobal,
+	tDot11fIEMultiBssid *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 57 (0x39) */
+typedef struct sDot11fIERICData {
+	uint8_t             present;
+	uint8_t             Identifier;
+	uint8_t             resourceDescCount;
+	uint16_t            statusCode;
+} tDot11fIERICData;
+
+#define DOT11F_EID_RICDATA (57)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RICDATA_MIN_LEN (4)
+
+#define DOT11F_IE_RICDATA_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ric_data(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIERICData*,
+	bool);
+
+uint32_t dot11f_pack_ie_ric_data(
+	tpAniSirGlobal,
+	tDot11fIERICData *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_RICData(
+	tpAniSirGlobal,
+	tDot11fIERICData *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 75 (0x4b) */
+typedef struct sDot11fIERICDescriptor {
+	uint8_t             present;
+	uint8_t             resourceType;
+	uint8_t             num_variableData;
+	uint8_t             variableData[255];
+} tDot11fIERICDescriptor;
+
+#define DOT11F_EID_RICDESCRIPTOR (75)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RICDESCRIPTOR_MIN_LEN (1)
+
+#define DOT11F_IE_RICDESCRIPTOR_MAX_LEN (256)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ric_descriptor(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIERICDescriptor*,
+	bool);
+
+uint32_t dot11f_pack_ie_ric_descriptor(
+	tpAniSirGlobal,
+	tDot11fIERICDescriptor *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_RICDescriptor(
+	tpAniSirGlobal,
+	tDot11fIERICDescriptor *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 70 (0x46) */
+typedef struct sDot11fIERRMEnabledCap {
+	uint8_t             present;
+	uint8_t      LinkMeasurement:1;
+	uint8_t          NeighborRpt:1;
+	uint8_t             parallel:1;
+	uint8_t             repeated:1;
+	uint8_t        BeaconPassive:1;
+	uint8_t         BeaconActive:1;
+	uint8_t          BeaconTable:1;
+	uint8_t        BeaconRepCond:1;
+	uint8_t     FrameMeasurement:1;
+	uint8_t          ChannelLoad:1;
+	uint8_t       NoiseHistogram:1;
+	uint8_t           statistics:1;
+	uint8_t       LCIMeasurement:1;
+	uint8_t           LCIAzimuth:1;
+	uint8_t        TCMCapability:1;
+	uint8_t         triggeredTCM:1;
+	uint8_t         APChanReport:1;
+	uint8_t        RRMMIBEnabled:1;
+	uint8_t     operatingChanMax:3;
+	uint8_t   nonOperatinChanMax:3;
+	uint8_t     MeasurementPilot:3;
+	uint8_t MeasurementPilotEnabled:1;
+	uint8_t    NeighborTSFOffset:1;
+	uint8_t      RCPIMeasurement:1;
+	uint8_t      RSNIMeasurement:1;
+	uint8_t    BssAvgAccessDelay:1;
+	uint8_t    BSSAvailAdmission:1;
+	uint8_t   AntennaInformation:1;
+	uint8_t   fine_time_meas_rpt:1;
+	uint8_t       lci_capability:1;
+	uint8_t             reserved:4;
+} tDot11fIERRMEnabledCap;
+
+#define DOT11F_EID_RRMENABLEDCAP (70)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RRMENABLEDCAP_MIN_LEN (5)
+
+#define DOT11F_IE_RRMENABLEDCAP_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_rrm_enabled_cap(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIERRMEnabledCap*,
+	bool);
+
+uint32_t dot11f_pack_ie_rrm_enabled_cap(
+	tpAniSirGlobal,
+	tDot11fIERRMEnabledCap *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_RRMEnabledCap(
+	tpAniSirGlobal,
+	tDot11fIERRMEnabledCap *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 10 (0x0a) */
+typedef struct sDot11fIERequestedInfo {
+	uint8_t             present;
+	uint8_t             num_requested_eids;
+	uint8_t             requested_eids[255];
+} tDot11fIERequestedInfo;
+
+#define DOT11F_EID_REQUESTEDINFO (10)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_REQUESTEDINFO_MIN_LEN (0)
+
+#define DOT11F_IE_REQUESTEDINFO_MAX_LEN (255)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_requested_info(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIERequestedInfo*,
+	bool);
+
+uint32_t dot11f_pack_ie_requested_info(
+	tpAniSirGlobal,
+	tDot11fIERequestedInfo *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_RequestedInfo(
+	tpAniSirGlobal,
+	tDot11fIERequestedInfo *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 0 (0x00) */
+typedef struct sDot11fIESSID {
+	uint8_t             present;
+	uint8_t             num_ssid;
+	uint8_t             ssid[32];
+} tDot11fIESSID;
+
+#define DOT11F_EID_SSID (0)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SSID_MIN_LEN (0)
+
+#define DOT11F_IE_SSID_MAX_LEN (32)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ssid(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIESSID*,
+	bool);
+
+uint32_t dot11f_pack_ie_ssid(
+	tpAniSirGlobal,
+	tDot11fIESSID *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_SSID(
+	tpAniSirGlobal,
+	tDot11fIESSID *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 15 (0x0f) */
+typedef struct sDot11fIESchedule {
+	uint8_t             present;
+	uint16_t          aggregation:1;
+	uint16_t                 tsid:4;
+	uint16_t            direction:2;
+	uint16_t             reserved:9;
+	uint32_t            service_start_time;
+	uint32_t            service_interval;
+	uint16_t            max_service_dur;
+	uint16_t            spec_interval;
+} tDot11fIESchedule;
+
+#define DOT11F_EID_SCHEDULE (15)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SCHEDULE_MIN_LEN (14)
+
+#define DOT11F_IE_SCHEDULE_MAX_LEN (14)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_schedule(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIESchedule*,
+	bool);
+
+uint32_t dot11f_pack_ie_schedule(
+	tpAniSirGlobal,
+	tDot11fIESchedule *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_Schedule(
+	tpAniSirGlobal,
+	tDot11fIESchedule *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 14 (0x0e) */
+typedef struct sDot11fIETCLAS {
+	uint8_t             present;
+	uint8_t             user_priority;
+	uint8_t             classifier_type;
+	uint8_t             classifier_mask;
+	union {
+		struct {
+			uint8_t source[6];
+			uint8_t dest[6];
+			uint16_t type;
+		} EthParams; /* classifier_type = 0 */
+		struct {
+			uint8_t version;
+			union {
+				struct {
+					uint8_t source[4];
+					uint8_t dest[4];
+					uint16_t src_port;
+					uint16_t dest_port;
+					uint8_t DSCP;
+					uint8_t proto;
+					uint8_t reserved;
+				} IpV4Params; /* version = 4 */
+				struct {
+					uint8_t source[16];
+					uint8_t dest[16];
+					uint16_t src_port;
+					uint16_t dest_port;
+					uint8_t flow_label[3];
+				} IpV6Params; /* version = 6 */
+			} params;
+		} IpParams; /* classifier_type = 1 */
+		struct {
+			uint16_t tag_type;
+		} Params8021dq; /* classifier_type = 2 */
+	} info;
+} tDot11fIETCLAS;
+
+#define DOT11F_EID_TCLAS (14)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TCLAS_MIN_LEN (5)
+
+#define DOT11F_IE_TCLAS_MAX_LEN (43)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_tclas(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIETCLAS*,
+	bool);
+
+uint32_t dot11f_pack_ie_tclas(
+	tpAniSirGlobal,
+	tDot11fIETCLAS *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ietclas(
+	tpAniSirGlobal,
+	tDot11fIETCLAS *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 44 (0x2c) */
+typedef struct sDot11fIETCLASSPROC {
+	uint8_t             present;
+	uint8_t             processing;
+} tDot11fIETCLASSPROC;
+
+#define DOT11F_EID_TCLASSPROC (44)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TCLASSPROC_MIN_LEN (1)
+
+#define DOT11F_IE_TCLASSPROC_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_tclasSPROC(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIETCLASSPROC*,
+	bool);
+
+uint32_t dot11f_pack_ie_tclassproc(
+	tpAniSirGlobal,
+	tDot11fIETCLASSPROC *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ietclasSPROC(
+	tpAniSirGlobal,
+	tDot11fIETCLASSPROC *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 43 (0x2b) */
+typedef struct sDot11fIETSDelay {
+	uint8_t             present;
+	uint32_t            delay;
+} tDot11fIETSDelay;
+
+#define DOT11F_EID_TSDELAY (43)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TSDELAY_MIN_LEN (4)
+
+#define DOT11F_IE_TSDELAY_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ts_delay(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIETSDelay*,
+	bool);
+
+uint32_t dot11f_pack_ie_ts_delay(
+	tpAniSirGlobal,
+	tDot11fIETSDelay *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TSDelay(
+	tpAniSirGlobal,
+	tDot11fIETSDelay *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 1 (0x01) */
+typedef struct sDot11fIETSFInfo {
+	uint8_t             present;
+	uint16_t            TsfOffset;
+	uint16_t            BeaconIntvl;
+} tDot11fIETSFInfo;
+
+#define DOT11F_EID_TSFINFO (1)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TSFINFO_MIN_LEN (4)
+
+#define DOT11F_IE_TSFINFO_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_tsf_info(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIETSFInfo*,
+	bool);
+
+uint32_t dot11f_pack_ie_tsf_info(
+	tpAniSirGlobal,
+	tDot11fIETSFInfo *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TSFInfo(
+	tpAniSirGlobal,
+	tDot11fIETSFInfo *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 13 (0x0d) */
+typedef struct sDot11fIETSPEC {
+	uint8_t             present;
+	uint16_t         traffic_type:1;
+	uint16_t                 tsid:4;
+	uint16_t            direction:2;
+	uint16_t        access_policy:2;
+	uint16_t          aggregation:1;
+	uint16_t                  psb:1;
+	uint16_t        user_priority:3;
+	uint16_t       tsinfo_ack_pol:2;
+	uint8_t             schedule:1;
+	uint8_t               unused:7;
+	uint16_t                 size:15;
+	uint16_t                fixed:1;
+	uint16_t            max_msdu_size;
+	uint32_t            min_service_int;
+	uint32_t            max_service_int;
+	uint32_t            inactivity_int;
+	uint32_t            suspension_int;
+	uint32_t            service_start_time;
+	uint32_t            min_data_rate;
+	uint32_t            mean_data_rate;
+	uint32_t            peak_data_rate;
+	uint32_t            burst_size;
+	uint32_t            delay_bound;
+	uint32_t            min_phy_rate;
+	uint16_t            surplus_bw_allowance;
+	uint16_t            medium_time;
+} tDot11fIETSPEC;
+
+#define DOT11F_EID_TSPEC (13)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TSPEC_MIN_LEN (55)
+
+#define DOT11F_IE_TSPEC_MAX_LEN (55)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_tspec(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIETSPEC*,
+	bool);
+
+uint32_t dot11f_pack_ie_tspec(
+	tpAniSirGlobal,
+	tDot11fIETSPEC *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TSPEC(
+	tpAniSirGlobal,
+	tDot11fIETSPEC *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 191 (0xbf) */
+typedef struct sDot11fIEVHTCaps {
+	uint8_t             present;
+	uint32_t           maxMPDULen:2;
+	uint32_t supportedChannelWidthSet:2;
+	uint32_t        ldpcCodingCap:1;
+	uint32_t         shortGI80MHz:1;
+	uint32_t shortGI160and80plus80MHz:1;
+	uint32_t               txSTBC:1;
+	uint32_t               rxSTBC:3;
+	uint32_t      suBeamFormerCap:1;
+	uint32_t      suBeamformeeCap:1;
+	uint32_t csnofBeamformerAntSup:3;
+	uint32_t       numSoundingDim:3;
+	uint32_t      muBeamformerCap:1;
+	uint32_t      muBeamformeeCap:1;
+	uint32_t            vhtTXOPPS:1;
+	uint32_t            htcVHTCap:1;
+	uint32_t       maxAMPDULenExp:3;
+	uint32_t      vhtLinkAdaptCap:2;
+	uint32_t         rxAntPattern:1;
+	uint32_t         txAntPattern:1;
+	uint32_t            reserved1:2;
+	uint16_t            rxMCSMap;
+	uint16_t    rxHighSupDataRate:13;
+	uint16_t            reserved2:3;
+	uint16_t            txMCSMap;
+	uint16_t        txSupDataRate:13;
+	uint16_t            reserved3:3;
+} tDot11fIEVHTCaps;
+
+#define DOT11F_EID_VHTCAPS (191)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VHTCAPS_MIN_LEN (12)
+
+#define DOT11F_IE_VHTCAPS_MAX_LEN (12)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_vht_caps(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEVHTCaps*,
+	bool);
+
+uint32_t dot11f_pack_ie_vht_caps(
+	tpAniSirGlobal,
+	tDot11fIEVHTCaps *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_VHTCaps(
+	tpAniSirGlobal,
+	tDot11fIEVHTCaps *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 192 (0xc0) */
+typedef struct sDot11fIEVHTOperation {
+	uint8_t             present;
+	uint8_t             chanWidth;
+	uint8_t             chanCenterFreqSeg1;
+	uint8_t             chanCenterFreqSeg2;
+	uint16_t            basicMCSSet;
+} tDot11fIEVHTOperation;
+
+#define DOT11F_EID_VHTOPERATION (192)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VHTOPERATION_MIN_LEN (5)
+
+#define DOT11F_IE_VHTOPERATION_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_vht_operation(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEVHTOperation*,
+	bool);
+
+uint32_t dot11f_pack_ie_vht_operation(
+	tpAniSirGlobal,
+	tDot11fIEVHTOperation *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_VHTOperation(
+	tpAniSirGlobal,
+	tDot11fIEVHTOperation *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x09} */
+typedef struct sDot11fIEWMMSchedule {
+	uint8_t             present;
+	uint8_t             version /* Must be 1! */;
+	uint16_t          aggregation:1;
+	uint16_t                 tsid:4;
+	uint16_t            direction:2;
+	uint16_t             reserved:9;
+	uint32_t            service_start_time;
+	uint32_t            service_interval;
+	uint16_t            max_service_dur;
+	uint16_t            spec_interval;
+} tDot11fIEWMMSchedule;
+
+#define DOT11F_EID_WMMSCHEDULE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMSCHEDULE_MIN_LEN (20)
+
+#define DOT11F_IE_WMMSCHEDULE_MAX_LEN (20)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wmm_schedule(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWMMSchedule*,
+	bool);
+
+uint32_t dot11f_pack_ie_wmm_schedule(
+	tpAniSirGlobal,
+	tDot11fIEWMMSchedule *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMSchedule(
+	tpAniSirGlobal,
+	tDot11fIEWMMSchedule *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x06} */
+typedef struct sDot11fIEWMMTCLAS {
+	uint8_t             present;
+	uint8_t             version /* Must be 1! */;
+	uint8_t             user_priority;
+	uint8_t             classifier_type;
+	uint8_t             classifier_mask;
+	union {
+		struct {
+			uint8_t source[6];
+			uint8_t dest[6];
+			uint16_t type;
+		} EthParams; /* classifier_type = 0 */
+		struct {
+			uint8_t version;
+			union {
+				struct {
+					uint8_t source[4];
+					uint8_t dest[4];
+					uint16_t src_port;
+					uint16_t dest_port;
+					uint8_t DSCP;
+					uint8_t proto;
+					uint8_t reserved;
+				} IpV4Params; /* version = 4 */
+				struct {
+					uint8_t source[16];
+					uint8_t dest[16];
+					uint16_t src_port;
+					uint16_t dest_port;
+					uint8_t flow_label[3];
+				} IpV6Params; /* version = 6 */
+			} params;
+		} IpParams; /* classifier_type = 1 */
+		struct {
+			uint16_t tag_type;
+		} Params8021dq; /* classifier_type = 2 */
+	} info;
+} tDot11fIEWMMTCLAS;
+
+#define DOT11F_EID_WMMTCLAS (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMTCLAS_MIN_LEN (11)
+
+#define DOT11F_IE_WMMTCLAS_MAX_LEN (49)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wmmtclas(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWMMTCLAS*,
+	bool);
+
+uint32_t dot11f_pack_ie_wmmtclas(
+	tpAniSirGlobal,
+	tDot11fIEWMMTCLAS *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iewmmtclas(
+	tpAniSirGlobal,
+	tDot11fIEWMMTCLAS *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x07} */
+typedef struct sDot11fIEWMMTCLASPROC {
+	uint8_t             present;
+	uint8_t             version /* Must be 1! */;
+	uint8_t             processing;
+} tDot11fIEWMMTCLASPROC;
+
+#define DOT11F_EID_WMMTCLASPROC (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMTCLASPROC_MIN_LEN (7)
+
+#define DOT11F_IE_WMMTCLASPROC_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wmmtclasproc(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWMMTCLASPROC*,
+	bool);
+
+uint32_t dot11f_pack_ie_wmmtclasproc(
+	tpAniSirGlobal,
+	tDot11fIEWMMTCLASPROC *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iewmmtclasPROC(
+	tpAniSirGlobal,
+	tDot11fIEWMMTCLASPROC *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x08} */
+typedef struct sDot11fIEWMMTSDelay {
+	uint8_t             present;
+	uint8_t             version /* Must be 1! */;
+	uint32_t            delay;
+} tDot11fIEWMMTSDelay;
+
+#define DOT11F_EID_WMMTSDELAY (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMTSDELAY_MIN_LEN (10)
+
+#define DOT11F_IE_WMMTSDELAY_MAX_LEN (10)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wmmts_delay(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWMMTSDelay*,
+	bool);
+
+uint32_t dot11f_pack_ie_wmmts_delay(
+	tpAniSirGlobal,
+	tDot11fIEWMMTSDelay *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMTSDelay(
+	tpAniSirGlobal,
+	tDot11fIEWMMTSDelay *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x02} */
+typedef struct sDot11fIEWMMTSPEC {
+	uint8_t             present;
+	uint8_t             version /* Must be 1! */;
+	uint16_t         traffic_type:1;
+	uint16_t                 tsid:4;
+	uint16_t            direction:2;
+	uint16_t        access_policy:2;
+	uint16_t          aggregation:1;
+	uint16_t                  psb:1;
+	uint16_t        user_priority:3;
+	uint16_t       tsinfo_ack_pol:2;
+	uint8_t          tsinfo_rsvd:7;
+	uint8_t      burst_size_defn:1;
+	uint16_t                 size:15;
+	uint16_t                fixed:1;
+	uint16_t            max_msdu_size;
+	uint32_t            min_service_int;
+	uint32_t            max_service_int;
+	uint32_t            inactivity_int;
+	uint32_t            suspension_int;
+	uint32_t            service_start_time;
+	uint32_t            min_data_rate;
+	uint32_t            mean_data_rate;
+	uint32_t            peak_data_rate;
+	uint32_t            burst_size;
+	uint32_t            delay_bound;
+	uint32_t            min_phy_rate;
+	uint16_t            surplus_bw_allowance;
+	uint16_t            medium_time;
+} tDot11fIEWMMTSPEC;
+
+#define DOT11F_EID_WMMTSPEC (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMTSPEC_MIN_LEN (61)
+
+#define DOT11F_IE_WMMTSPEC_MAX_LEN (61)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wmmtspec(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWMMTSPEC*,
+	bool);
+
+uint32_t dot11f_pack_ie_wmmtspec(
+	tpAniSirGlobal,
+	tDot11fIEWMMTSPEC *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMTSPEC(
+	tpAniSirGlobal,
+	tDot11fIEWMMTSPEC *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 194 (0xc2) */
+typedef struct sDot11fIEWiderBWChanSwitchAnn {
+	uint8_t             present;
+	uint8_t             newChanWidth;
+	uint8_t             newCenterChanFreq0;
+	uint8_t             newCenterChanFreq1;
+} tDot11fIEWiderBWChanSwitchAnn;
+
+#define DOT11F_EID_WIDERBWCHANSWITCHANN (194)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WIDERBWCHANSWITCHANN_MIN_LEN (3)
+
+#define DOT11F_IE_WIDERBWCHANSWITCHANN_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wider_bw_chan_switch_ann(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWiderBWChanSwitchAnn*,
+	bool);
+
+uint32_t dot11f_pack_ie_wider_bw_chan_switch_ann(
+	tpAniSirGlobal,
+	tDot11fIEWiderBWChanSwitchAnn *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WiderBWChanSwitchAnn(
+	tpAniSirGlobal,
+	tDot11fIEWiderBWChanSwitchAnn *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 1 (0x01) */
+typedef struct sDot11fIEazimuth_req {
+	uint8_t             present;
+	uint8_t             request;
+} tDot11fIEazimuth_req;
+
+#define DOT11F_EID_AZIMUTH_REQ (1)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_AZIMUTH_REQ_MIN_LEN (1)
+
+#define DOT11F_IE_AZIMUTH_REQ_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_azimuth_req(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEazimuth_req*,
+	bool);
+
+uint32_t dot11f_pack_ie_azimuth_req(
+	tpAniSirGlobal,
+	tDot11fIEazimuth_req *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_azimuth_req(
+	tpAniSirGlobal,
+	tDot11fIEazimuth_req *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 2 (0x02) */
+typedef struct sDot11fIEbeacon_report_frm_body_fragment_id {
+	uint8_t             present;
+	uint16_t     beacon_report_id:8;
+	uint16_t   fragment_id_number:7;
+	uint16_t       more_fragments:1;
+} tDot11fIEbeacon_report_frm_body_fragment_id;
+
+#define DOT11F_EID_BEACON_REPORT_FRM_BODY_FRAGMENT_ID (2)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_BEACON_REPORT_FRM_BODY_FRAGMENT_ID_MIN_LEN (2)
+
+#define DOT11F_IE_BEACON_REPORT_FRM_BODY_FRAGMENT_ID_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_beacon_report_frm_body_fragment_id(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEbeacon_report_frm_body_fragment_id*,
+	bool);
+
+uint32_t dot11f_pack_ie_beacon_report_frm_body_fragment_id(
+	tpAniSirGlobal,
+	tDot11fIEbeacon_report_frm_body_fragment_id *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_beacon_report_frm_body_fragment_id(
+	tpAniSirGlobal,
+	tDot11fIEbeacon_report_frm_body_fragment_id *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 164 (0xa4) */
+typedef struct sDot11fIElast_beacon_report_indication {
+	uint8_t             present;
+	uint8_t             last_fragment;
+} tDot11fIElast_beacon_report_indication;
+
+#define DOT11F_EID_LAST_BEACON_REPORT_INDICATION (164)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_LAST_BEACON_REPORT_INDICATION_MIN_LEN (1)
+
+#define DOT11F_IE_LAST_BEACON_REPORT_INDICATION_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_last_beacon_report_indication(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIElast_beacon_report_indication*,
+	bool);
+
+uint32_t dot11f_pack_ie_last_beacon_report_indication(
+	tpAniSirGlobal,
+	tDot11fIElast_beacon_report_indication *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_last_beacon_report_indication(
+	tpAniSirGlobal,
+	tDot11fIElast_beacon_report_indication *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 4 (0x04) */
+typedef struct sDot11fIEmax_age {
+	uint8_t             present;
+	uint16_t            max_age;
+} tDot11fIEmax_age;
+
+#define DOT11F_EID_MAX_AGE (4)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MAX_AGE_MIN_LEN (2)
+
+#define DOT11F_IE_MAX_AGE_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_max_age(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEmax_age*,
+	bool);
+
+uint32_t dot11f_pack_ie_max_age(
+	tpAniSirGlobal,
+	tDot11fIEmax_age *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_max_age(
+	tpAniSirGlobal,
+	tDot11fIEmax_age *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 52 (0x34) */
+typedef struct sDot11fIEneighbor_rpt {
+	uint8_t                             present;
+	uint8_t                             bssid[6];
+	uint8_t                       APReachability:2;
+	uint8_t                             Security:1;
+	uint8_t                             KeyScope:1;
+	uint8_t                          SpecMgmtCap:1;
+	uint8_t                               QosCap:1;
+	uint8_t                                 apsd:1;
+	uint8_t                                  rrm:1;
+	uint8_t                            DelayedBA:1;
+	uint8_t                                ImmBA:1;
+	uint8_t                       MobilityDomain:1;
+	uint8_t                             reserved:5;
+	uint16_t                            reserved1;
+	uint8_t                             regulatoryClass;
+	uint8_t                             channel;
+	uint8_t                             PhyType;
+	tDot11fIETSFInfo                    TSFInfo;
+	tDot11fIECondensedCountryStr        CondensedCountryStr;
+	tDot11fIEMeasurementPilot           MeasurementPilot;
+	tDot11fIERRMEnabledCap              RRMEnabledCap;
+	tDot11fIEMultiBssid                 MultiBssid;
+} tDot11fIEneighbor_rpt;
+
+#define DOT11F_EID_NEIGHBOR_RPT (52)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_NEIGHBOR_RPT_MIN_LEN (13)
+
+#define DOT11F_IE_NEIGHBOR_RPT_MAX_LEN (546)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_neighbor_rpt(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEneighbor_rpt*,
+	bool);
+
+uint32_t dot11f_pack_ie_neighbor_rpt(
+	tpAniSirGlobal,
+	tDot11fIEneighbor_rpt *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_neighbor_rpt(
+	tpAniSirGlobal,
+	tDot11fIEneighbor_rpt *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 2 (0x02) */
+typedef struct sDot11fIEreq_mac_addr {
+	uint8_t             present;
+	uint8_t             addr[6];
+} tDot11fIEreq_mac_addr;
+
+#define DOT11F_EID_REQ_MAC_ADDR (2)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_REQ_MAC_ADDR_MIN_LEN (6)
+
+#define DOT11F_IE_REQ_MAC_ADDR_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_req_mac_addr(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEreq_mac_addr*,
+	bool);
+
+uint32_t dot11f_pack_ie_req_mac_addr(
+	tpAniSirGlobal,
+	tDot11fIEreq_mac_addr *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_req_mac_addr(
+	tpAniSirGlobal,
+	tDot11fIEreq_mac_addr *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 3 (0x03) */
+typedef struct sDot11fIEtgt_mac_addr {
+	uint8_t             present;
+	uint8_t             addr[6];
+} tDot11fIEtgt_mac_addr;
+
+#define DOT11F_EID_TGT_MAC_ADDR (3)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TGT_MAC_ADDR_MIN_LEN (6)
+
+#define DOT11F_IE_TGT_MAC_ADDR_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_tgt_mac_addr(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEtgt_mac_addr*,
+	bool);
+
+uint32_t dot11f_pack_ie_tgt_mac_addr(
+	tpAniSirGlobal,
+	tDot11fIEtgt_mac_addr *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_tgt_mac_addr(
+	tpAniSirGlobal,
+	tDot11fIEtgt_mac_addr *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 195 (0xc3) */
+typedef struct sDot11fIEvht_transmit_power_env {
+	uint8_t             present;
+	uint8_t             num_bytes;
+	uint8_t             bytes[5];
+} tDot11fIEvht_transmit_power_env;
+
+#define DOT11F_EID_VHT_TRANSMIT_POWER_ENV (195)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VHT_TRANSMIT_POWER_ENV_MIN_LEN (2)
+
+#define DOT11F_IE_VHT_TRANSMIT_POWER_ENV_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_vht_transmit_power_env(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEvht_transmit_power_env*,
+	bool);
+
+uint32_t dot11f_pack_ie_vht_transmit_power_env(
+	tpAniSirGlobal,
+	tDot11fIEvht_transmit_power_env *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_vht_transmit_power_env(
+	tpAniSirGlobal,
+	tDot11fIEvht_transmit_power_env *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 197 (0xc5) */
+typedef struct sDot11fIEAID {
+	uint8_t             present;
+	uint16_t            assocId;
+} tDot11fIEAID;
+
+#define DOT11F_EID_AID (197)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_AID_MIN_LEN (2)
+
+#define DOT11F_IE_AID_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_aid(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEAID*,
+	bool);
+
+uint32_t dot11f_pack_ie_aid(
+	tpAniSirGlobal,
+	tDot11fIEAID *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_AID(
+	tpAniSirGlobal,
+	tDot11fIEAID *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 4 (0x04) */
+typedef struct sDot11fIECFParams {
+	uint8_t             present;
+	uint8_t             cfp_count;
+	uint8_t             cfp_period;
+	uint16_t            cfp_maxduration;
+	uint16_t            cfp_durremaining;
+} tDot11fIECFParams;
+
+#define DOT11F_EID_CFPARAMS (4)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_CFPARAMS_MIN_LEN (6)
+
+#define DOT11F_IE_CFPARAMS_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_cf_params(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIECFParams*,
+	bool);
+
+uint32_t dot11f_pack_ie_cf_params(
+	tpAniSirGlobal,
+	tDot11fIECFParams *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_CFParams(
+	tpAniSirGlobal,
+	tDot11fIECFParams *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 16 (0x10) */
+typedef struct sDot11fIEChallengeText {
+	uint8_t             present;
+	uint8_t             num_text;
+	uint8_t             text[253];
+} tDot11fIEChallengeText;
+
+#define DOT11F_EID_CHALLENGETEXT (16)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_CHALLENGETEXT_MIN_LEN (1)
+
+#define DOT11F_IE_CHALLENGETEXT_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_challenge_text(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEChallengeText*,
+	bool);
+
+uint32_t dot11f_pack_ie_challenge_text(
+	tpAniSirGlobal,
+	tDot11fIEChallengeText *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ChallengeText(
+	tpAniSirGlobal,
+	tDot11fIEChallengeText *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 37 (0x25) */
+typedef struct sDot11fIEChanSwitchAnn {
+	uint8_t             present;
+	uint8_t             switchMode;
+	uint8_t             newChannel;
+	uint8_t             switchCount;
+} tDot11fIEChanSwitchAnn;
+
+#define DOT11F_EID_CHANSWITCHANN (37)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_CHANSWITCHANN_MIN_LEN (3)
+
+#define DOT11F_IE_CHANSWITCHANN_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_chan_switch_ann(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEChanSwitchAnn*,
+	bool);
+
+uint32_t dot11f_pack_ie_chan_switch_ann(
+	tpAniSirGlobal,
+	tDot11fIEChanSwitchAnn *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ChanSwitchAnn(
+	tpAniSirGlobal,
+	tDot11fIEChanSwitchAnn *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 196 (0xc4) */
+typedef struct sDot11fIEChannelSwitchWrapper {
+	uint8_t                                present;
+	tDot11fIEWiderBWChanSwitchAnn          WiderBWChanSwitchAnn;
+	tDot11fIEvht_transmit_power_env        vht_transmit_power_env;
+} tDot11fIEChannelSwitchWrapper;
+
+#define DOT11F_EID_CHANNELSWITCHWRAPPER (196)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_CHANNELSWITCHWRAPPER_MIN_LEN (0)
+
+#define DOT11F_IE_CHANNELSWITCHWRAPPER_MAX_LEN (12)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_channel_switch_wrapper(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEChannelSwitchWrapper*,
+	bool);
+
+uint32_t dot11f_pack_ie_channel_switch_wrapper(
+	tpAniSirGlobal,
+	tDot11fIEChannelSwitchWrapper *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_channel_switch_wrapper(
+	tpAniSirGlobal,
+	tDot11fIEChannelSwitchWrapper *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 7 (0x07) */
+typedef struct sDot11fIECountry {
+	uint8_t             present;
+	uint8_t             country[3];
+	uint8_t             num_triplets;
+	uint8_t             triplets[84][3];
+} tDot11fIECountry;
+
+#define DOT11F_EID_COUNTRY (7)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_COUNTRY_MIN_LEN (3)
+
+#define DOT11F_IE_COUNTRY_MAX_LEN (255)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_country(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIECountry*,
+	bool);
+
+uint32_t dot11f_pack_ie_country(
+	tpAniSirGlobal,
+	tDot11fIECountry *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_country(
+	tpAniSirGlobal,
+	tDot11fIECountry *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 3 (0x03) */
+typedef struct sDot11fIEDSParams {
+	uint8_t             present;
+	uint8_t             curr_channel;
+} tDot11fIEDSParams;
+
+#define DOT11F_EID_DSPARAMS (3)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_DSPARAMS_MIN_LEN (1)
+
+#define DOT11F_IE_DSPARAMS_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_DSParams(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEDSParams*,
+	bool);
+
+uint32_t dot11f_pack_ie_ds_params(
+	tpAniSirGlobal,
+	tDot11fIEDSParams *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_DSParams(
+	tpAniSirGlobal,
+	tDot11fIEDSParams *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 12 (0x0c) */
+typedef struct sDot11fIEEDCAParamSet {
+	uint8_t             present;
+	uint8_t             qos;
+	uint8_t             reserved;
+	uint8_t           acbe_aifsn:4;
+	uint8_t             acbe_acm:1;
+	uint8_t             acbe_aci:2;
+	uint8_t              unused1:1;
+	uint8_t          acbe_acwmin:4;
+	uint8_t          acbe_acwmax:4;
+	uint16_t            acbe_txoplimit;
+	uint8_t           acbk_aifsn:4;
+	uint8_t             acbk_acm:1;
+	uint8_t             acbk_aci:2;
+	uint8_t              unused2:1;
+	uint8_t          acbk_acwmin:4;
+	uint8_t          acbk_acwmax:4;
+	uint16_t            acbk_txoplimit;
+	uint8_t           acvi_aifsn:4;
+	uint8_t             acvi_acm:1;
+	uint8_t             acvi_aci:2;
+	uint8_t              unused3:1;
+	uint8_t          acvi_acwmin:4;
+	uint8_t          acvi_acwmax:4;
+	uint16_t            acvi_txoplimit;
+	uint8_t           acvo_aifsn:4;
+	uint8_t             acvo_acm:1;
+	uint8_t             acvo_aci:2;
+	uint8_t              unused4:1;
+	uint8_t          acvo_acwmin:4;
+	uint8_t          acvo_acwmax:4;
+	uint16_t            acvo_txoplimit;
+} tDot11fIEEDCAParamSet;
+
+#define DOT11F_EID_EDCAPARAMSET (12)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_EDCAPARAMSET_MIN_LEN (18)
+
+#define DOT11F_IE_EDCAPARAMSET_MAX_LEN (18)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_edca_param_set(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEEDCAParamSet*,
+	bool);
+
+uint32_t dot11f_pack_ie_edca_param_set(
+	tpAniSirGlobal,
+	tDot11fIEEDCAParamSet *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_EDCAParamSet(
+	tpAniSirGlobal,
+	tDot11fIEEDCAParamSet *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 42 (0x2a) */
+typedef struct sDot11fIEERPInfo {
+	uint8_t             present;
+	uint8_t      non_erp_present:1;
+	uint8_t             use_prot:1;
+	uint8_t      barker_preamble:1;
+	uint8_t               unused:5;
+} tDot11fIEERPInfo;
+
+#define DOT11F_EID_ERPINFO (42)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ERPINFO_MIN_LEN (1)
+
+#define DOT11F_IE_ERPINFO_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_erp_info(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEERPInfo*,
+	bool);
+
+uint32_t dot11f_pack_ie_erp_info(
+	tpAniSirGlobal,
+	tDot11fIEERPInfo *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ERPInfo(
+	tpAniSirGlobal,
+	tDot11fIEERPInfo *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 156 (0x9c) {OUI 0x00, 0x40, 0x96, 0x00} */
+typedef struct sDot11fIEESECckmOpaque {
+	uint8_t             present;
+	uint8_t             num_data;
+	uint8_t             data[20];
+} tDot11fIEESECckmOpaque;
+
+#define DOT11F_EID_ESECCKMOPAQUE (156)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESECCKMOPAQUE_MIN_LEN (10)
+
+#define DOT11F_IE_ESECCKMOPAQUE_MAX_LEN (24)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ese_cckm_opaque(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEESECckmOpaque*,
+	bool);
+
+uint32_t dot11f_pack_ie_ese_cckm_opaque(
+	tpAniSirGlobal,
+	tDot11fIEESECckmOpaque *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESECckmOpaque(
+	tpAniSirGlobal,
+	tDot11fIEESECckmOpaque *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x01} */
+typedef struct sDot11fIEESERadMgmtCap {
+	uint8_t             present;
+	uint8_t             mgmt_state;
+	uint8_t          mbssid_mask:3;
+	uint8_t             reserved:5;
+} tDot11fIEESERadMgmtCap;
+
+#define DOT11F_EID_ESERADMGMTCAP (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESERADMGMTCAP_MIN_LEN (6)
+
+#define DOT11F_IE_ESERADMGMTCAP_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ese_rad_mgmt_cap(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEESERadMgmtCap*,
+	bool);
+
+uint32_t dot11f_pack_ie_ese_rad_mgmt_cap(
+	tpAniSirGlobal,
+	tDot11fIEESERadMgmtCap *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESERadMgmtCap(
+	tpAniSirGlobal,
+	tDot11fIEESERadMgmtCap *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x07} */
+typedef struct sDot11fIEESETrafStrmMet {
+	uint8_t             present;
+	uint8_t             tsid;
+	uint8_t             state;
+	uint16_t            msmt_interval;
+} tDot11fIEESETrafStrmMet;
+
+#define DOT11F_EID_ESETRAFSTRMMET (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESETRAFSTRMMET_MIN_LEN (8)
+
+#define DOT11F_IE_ESETRAFSTRMMET_MAX_LEN (8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ese_traf_strm_met(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEESETrafStrmMet*,
+	bool);
+
+uint32_t dot11f_pack_ie_ese_traf_strm_met(
+	tpAniSirGlobal,
+	tDot11fIEESETrafStrmMet *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESETrafStrmMet(
+	tpAniSirGlobal,
+	tDot11fIEESETrafStrmMet *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x08} */
+typedef struct sDot11fIEESETrafStrmRateSet {
+	uint8_t             present;
+	uint8_t             tsid;
+	uint8_t             num_tsrates;
+	uint8_t             tsrates[8];
+} tDot11fIEESETrafStrmRateSet;
+
+#define DOT11F_EID_ESETRAFSTRMRATESET (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESETRAFSTRMRATESET_MIN_LEN (5)
+
+#define DOT11F_IE_ESETRAFSTRMRATESET_MAX_LEN (13)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ese_traf_strm_rate_set(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEESETrafStrmRateSet*,
+	bool);
+
+uint32_t dot11f_pack_ie_ese_traf_strm_rate_set(
+	tpAniSirGlobal,
+	tDot11fIEESETrafStrmRateSet *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESETrafStrmRateSet(
+	tpAniSirGlobal,
+	tDot11fIEESETrafStrmRateSet *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 150 (0x96) {OUI 0x00, 0x40, 0x96, 0x00} */
+typedef struct sDot11fIEESETxmitPower {
+	uint8_t             present;
+	uint8_t             power_limit;
+	uint8_t             reserved;
+} tDot11fIEESETxmitPower;
+
+#define DOT11F_EID_ESETXMITPOWER (150)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESETXMITPOWER_MIN_LEN (6)
+
+#define DOT11F_IE_ESETXMITPOWER_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ese_txmit_power(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEESETxmitPower*,
+	bool);
+
+uint32_t dot11f_pack_ie_ese_txmit_power(
+	tpAniSirGlobal,
+	tDot11fIEESETxmitPower *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESETxmitPower(
+	tpAniSirGlobal,
+	tDot11fIEESETxmitPower *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x03} */
+typedef struct sDot11fIEESEVersion {
+	uint8_t             present;
+	uint8_t             version;
+} tDot11fIEESEVersion;
+
+#define DOT11F_EID_ESEVERSION (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESEVERSION_MIN_LEN (5)
+
+#define DOT11F_IE_ESEVERSION_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ese_version(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEESEVersion*,
+	bool);
+
+uint32_t dot11f_pack_ie_ese_version(
+	tpAniSirGlobal,
+	tDot11fIEESEVersion *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESEVersion(
+	tpAniSirGlobal,
+	tDot11fIEESEVersion *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 127 (0x7f) */
+typedef struct sDot11fIEExtCap {
+	uint8_t             present;
+	uint8_t             num_bytes;
+	uint8_t             bytes[15];
+} tDot11fIEExtCap;
+
+#define DOT11F_EID_EXTCAP (127)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_EXTCAP_MIN_LEN (1)
+
+#define DOT11F_IE_EXTCAP_MAX_LEN (15)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ext_cap(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEExtCap*,
+	bool);
+
+uint32_t dot11f_pack_ie_ext_cap(
+	tpAniSirGlobal,
+	tDot11fIEExtCap *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ExtCap(
+	tpAniSirGlobal,
+	tDot11fIEExtCap *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 50 (0x32) */
+typedef struct sDot11fIEExtSuppRates {
+	uint8_t             present;
+	uint8_t             num_rates;
+	uint8_t             rates[12];
+} tDot11fIEExtSuppRates;
+
+#define DOT11F_EID_EXTSUPPRATES (50)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_EXTSUPPRATES_MIN_LEN (1)
+
+#define DOT11F_IE_EXTSUPPRATES_MAX_LEN (12)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ext_supp_rates(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEExtSuppRates*,
+	bool);
+
+uint32_t dot11f_pack_ie_ext_supp_rates(
+	tpAniSirGlobal,
+	tDot11fIEExtSuppRates *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ExtSuppRates(
+	tpAniSirGlobal,
+	tDot11fIEExtSuppRates *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 2 (0x02) */
+typedef struct sDot11fIEFHParamSet {
+	uint8_t             present;
+	uint16_t            dwell_time;
+	uint8_t             hop_set;
+	uint8_t             hop_pattern;
+	uint8_t             hop_index;
+} tDot11fIEFHParamSet;
+
+#define DOT11F_EID_FHPARAMSET (2)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FHPARAMSET_MIN_LEN (5)
+
+#define DOT11F_IE_FHPARAMSET_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fh_param_set(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEFHParamSet*,
+	bool);
+
+uint32_t dot11f_pack_ie_fh_param_set(
+	tpAniSirGlobal,
+	tDot11fIEFHParamSet *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_FHParamSet(
+	tpAniSirGlobal,
+	tDot11fIEFHParamSet *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 8 (0x08) */
+typedef struct sDot11fIEFHParams {
+	uint8_t             present;
+	uint8_t             radix;
+	uint8_t             nchannels;
+} tDot11fIEFHParams;
+
+#define DOT11F_EID_FHPARAMS (8)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FHPARAMS_MIN_LEN (2)
+
+#define DOT11F_IE_FHPARAMS_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fh_params(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEFHParams*,
+	bool);
+
+uint32_t dot11f_pack_ie_fh_params(
+	tpAniSirGlobal,
+	tDot11fIEFHParams *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_FHParams(
+	tpAniSirGlobal,
+	tDot11fIEFHParams *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 9 (0x09) */
+typedef struct sDot11fIEFHPattTable {
+	uint8_t             present;
+	uint8_t             flag;
+	uint8_t             nsets;
+	uint8_t             modulus;
+	uint8_t             offset;
+	uint8_t             num_randtable;
+	uint8_t             randtable[251];
+} tDot11fIEFHPattTable;
+
+#define DOT11F_EID_FHPATTTABLE (9)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FHPATTTABLE_MIN_LEN (4)
+
+#define DOT11F_IE_FHPATTTABLE_MAX_LEN (255)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fh_patt_table(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEFHPattTable*,
+	bool);
+
+uint32_t dot11f_pack_ie_fh_patt_table(
+	tpAniSirGlobal,
+	tDot11fIEFHPattTable *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_FHPattTable(
+	tpAniSirGlobal,
+	tDot11fIEFHPattTable *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 55 (0x37) */
+typedef struct sDot11fIEFTInfo {
+	uint8_t                 present;
+	uint16_t                 reserved:8;
+	uint16_t                  IECount:8;
+	uint8_t                 MIC[16];
+	uint8_t                 Anonce[32];
+	uint8_t                 Snonce[32];
+	tDot11fIER1KH_ID        R1KH_ID;
+	tDot11fIEGTK            GTK;
+	tDot11fIER0KH_ID        R0KH_ID;
+	tDot11fIEIGTK           IGTK;
+} tDot11fIEFTInfo;
+
+#define DOT11F_EID_FTINFO (55)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FTINFO_MIN_LEN (82)
+
+#define DOT11F_IE_FTINFO_MAX_LEN (220)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ft_info(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEFTInfo*,
+	bool);
+
+uint32_t dot11f_pack_ie_ft_info(
+	tpAniSirGlobal,
+	tDot11fIEFTInfo *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ieft_info(
+	tpAniSirGlobal,
+	tDot11fIEFTInfo *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 45 (0x2d) */
+typedef struct sDot11fIEHTCaps {
+	uint8_t             present;
+	uint16_t         advCodingCap:1;
+	uint16_t supportedChannelWidthSet:1;
+	uint16_t        mimoPowerSave:2;
+	uint16_t           greenField:1;
+	uint16_t         shortGI20MHz:1;
+	uint16_t         shortGI40MHz:1;
+	uint16_t               txSTBC:1;
+	uint16_t               rxSTBC:2;
+	uint16_t            delayedBA:1;
+	uint16_t     maximalAMSDUsize:1;
+	uint16_t     dsssCckMode40MHz:1;
+	uint16_t                 psmp:1;
+	uint16_t     stbcControlFrame:1;
+	uint16_t   lsigTXOPProtection:1;
+	uint8_t     maxRxAMPDUFactor:2;
+	uint8_t          mpduDensity:3;
+	uint8_t            reserved1:3;
+	uint8_t             supportedMCSSet[16];
+	uint16_t                  pco:1;
+	uint16_t       transitionTime:2;
+	uint16_t            reserved2:5;
+	uint16_t          mcsFeedback:2;
+	uint16_t            reserved3:6;
+	uint32_t                 txBF:1;
+	uint32_t  rxStaggeredSounding:1;
+	uint32_t  txStaggeredSounding:1;
+	uint32_t                rxZLF:1;
+	uint32_t                txZLF:1;
+	uint32_t         implicitTxBF:1;
+	uint32_t          calibration:2;
+	uint32_t      explicitCSITxBF:1;
+	uint32_t explicitUncompressedSteeringMatrix:1;
+	uint32_t explicitBFCSIFeedback:3;
+	uint32_t explicitUncompressedSteeringMatrixFeedback:3;
+	uint32_t explicitCompressedSteeringMatrixFeedback:3;
+	uint32_t     csiNumBFAntennae:2;
+	uint32_t uncompressedSteeringMatrixBFAntennae:2;
+	uint32_t compressedSteeringMatrixBFAntennae:2;
+	uint32_t            reserved4:7;
+	uint8_t     antennaSelection:1;
+	uint8_t explicitCSIFeedbackTx:1;
+	uint8_t antennaIndicesFeedbackTx:1;
+	uint8_t  explicitCSIFeedback:1;
+	uint8_t antennaIndicesFeedback:1;
+	uint8_t                 rxAS:1;
+	uint8_t      txSoundingPPDUs:1;
+	uint8_t            reserved5:1;
+	uint8_t             num_rsvd;
+	uint8_t             rsvd[32];
+} tDot11fIEHTCaps;
+
+#define DOT11F_EID_HTCAPS (45)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HTCAPS_MIN_LEN (26)
+
+#define DOT11F_IE_HTCAPS_MAX_LEN (58)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ht_caps(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEHTCaps*,
+	bool);
+
+uint32_t dot11f_pack_ie_ht_caps(
+	tpAniSirGlobal,
+	tDot11fIEHTCaps *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_HTCaps(
+	tpAniSirGlobal,
+	tDot11fIEHTCaps *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 61 (0x3d) */
+typedef struct sDot11fIEHTInfo {
+	uint8_t             present;
+	uint8_t             primaryChannel;
+	uint8_t secondaryChannelOffset:2;
+	uint8_t recommendedTxWidthSet:1;
+	uint8_t             rifsMode:1;
+	uint8_t controlledAccessOnly:1;
+	uint8_t serviceIntervalGranularity:3;
+	uint16_t               opMode:2;
+	uint16_t  nonGFDevicesPresent:1;
+	uint16_t   transmitBurstLimit:1;
+	uint16_t  obssNonHTStaPresent:1;
+	uint16_t             reserved:11;
+	uint16_t         basicSTBCMCS:7;
+	uint16_t    dualCTSProtection:1;
+	uint16_t      secondaryBeacon:1;
+	uint16_t lsigTXOPProtectionFullSupport:1;
+	uint16_t            pcoActive:1;
+	uint16_t             pcoPhase:1;
+	uint16_t            reserved2:4;
+	uint8_t             basicMCSSet[16];
+	uint8_t             num_rsvd;
+	uint8_t             rsvd[32];
+} tDot11fIEHTInfo;
+
+#define DOT11F_EID_HTINFO (61)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HTINFO_MIN_LEN (22)
+
+#define DOT11F_IE_HTINFO_MAX_LEN (54)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ht_info(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEHTInfo*,
+	bool);
+
+uint32_t dot11f_pack_ie_ht_info(
+	tpAniSirGlobal,
+	tDot11fIEHTInfo *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_HTInfo(
+	tpAniSirGlobal,
+	tDot11fIEHTInfo *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 6 (0x06) */
+typedef struct sDot11fIEIBSSParams {
+	uint8_t             present;
+	uint16_t            atim;
+} tDot11fIEIBSSParams;
+
+#define DOT11F_EID_IBSSPARAMS (6)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_IBSSPARAMS_MIN_LEN (2)
+
+#define DOT11F_IE_IBSSPARAMS_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ibss_params(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEIBSSParams*,
+	bool);
+
+uint32_t dot11f_pack_ie_ibss_params(
+	tpAniSirGlobal,
+	tDot11fIEIBSSParams *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_IBSSParams(
+	tpAniSirGlobal,
+	tDot11fIEIBSSParams *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 101 (0x65) */
+typedef struct sDot11fIELinkIdentifier {
+	uint8_t             present;
+	uint8_t             bssid[6];
+	uint8_t             InitStaAddr[6];
+	uint8_t             RespStaAddr[6];
+} tDot11fIELinkIdentifier;
+
+#define DOT11F_EID_LINKIDENTIFIER (101)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_LINKIDENTIFIER_MIN_LEN (18)
+
+#define DOT11F_IE_LINKIDENTIFIER_MAX_LEN (18)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_link_identifier(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIELinkIdentifier*,
+	bool);
+
+uint32_t dot11f_pack_ie_link_identifier(
+	tpAniSirGlobal,
+	tDot11fIELinkIdentifier *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_LinkIdentifier(
+	tpAniSirGlobal,
+	tDot11fIELinkIdentifier *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x16} (Multi-IE) */
+typedef struct sDot11fIEMBO_IE {
+	uint8_t             present;
+	tDot11fTLVmbo_ap_cap mbo_ap_cap;
+	tDot11fTLVnon_prefferd_chan_rep non_prefferd_chan_rep;
+	tDot11fTLVcellular_data_cap cellular_data_cap;
+	tDot11fTLVassoc_disallowed assoc_disallowed;
+	tDot11fTLVcellular_data_con_pref cellular_data_con_pref;
+	tDot11fTLVtransition_reason transition_reason;
+	tDot11fTLVtransition_reject_reason transition_reject_reason;
+	tDot11fTLVassoc_retry_delay assoc_retry_delay;
+	tDot11fTLVoce_cap   oce_cap;
+	tDot11fTLVrssi_assoc_rej rssi_assoc_rej;
+	tDot11fTLVreduced_wan_metrics reduced_wan_metrics;
+} tDot11fIEMBO_IE;
+
+#define DOT11F_EID_MBO_IE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MBO_IE_MIN_LEN (4)
+
+#define DOT11F_IE_MBO_IE_MAX_LEN (293)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_MBO_IE(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEMBO_IE*,
+	bool);
+
+uint32_t dot11f_pack_ie_MBO_IE(
+	tpAniSirGlobal,
+	tDot11fIEMBO_IE *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_MBO_IE(
+	tpAniSirGlobal,
+	tDot11fIEMBO_IE *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 39 (0x27) */
+typedef struct sDot11fIEMeasurementReport {
+	uint8_t             present;
+	uint8_t             token;
+	uint8_t                 late:1;
+	uint8_t            incapable:1;
+	uint8_t              refused:1;
+	uint8_t               unused:5;
+	uint8_t             type;
+	union {
+		struct {
+			uint8_t channel;
+			tDOT11F_U64 meas_start_time;
+			uint16_t meas_duration;
+			uint8_t            bss:1;
+			uint8_t  ofdm_preamble:1;
+			uint8_t    unid_signal:1;
+			uint8_t          rader:1;
+			uint8_t     unmeasured:1;
+			uint8_t         unused:3;
+		} Basic; /* type = 0 */
+		struct {
+			uint8_t channel;
+			tDOT11F_U64 meas_start_time;
+			uint16_t meas_duration;
+			uint8_t cca_busy_fraction;
+		} CCA; /* type = 1 */
+		struct {
+			uint8_t channel;
+			tDOT11F_U64 meas_start_time;
+			uint16_t meas_duration;
+			uint8_t rpi0_density;
+			uint8_t rpi1_density;
+			uint8_t rpi2_density;
+			uint8_t rpi3_density;
+			uint8_t rpi4_density;
+			uint8_t rpi5_density;
+			uint8_t rpi6_density;
+			uint8_t rpi7_density;
+		} RPIHistogram; /* type = 2 */
+		struct {
+			uint8_t regClass;
+			uint8_t channel;
+			tDOT11F_U64 meas_start_time;
+			uint16_t meas_duration;
+			uint8_t        condensed_PHY:7;
+			uint8_t  reported_frame_type:1;
+			uint8_t RCPI;
+			uint8_t RSNI;
+			uint8_t BSSID[6];
+			uint8_t antenna_id;
+			uint32_t parent_TSF;
+	tDot11fIEBeaconReportFrmBody BeaconReportFrmBody;
+	tDot11fIEbeacon_report_frm_body_fragment_id beacon_report_frm_body_fragment_id;
+	tDot11fIElast_beacon_report_indication last_beacon_report_indication;
+		} Beacon; /* type = 5 */
+	} report;
+} tDot11fIEMeasurementReport;
+
+#define DOT11F_EID_MEASUREMENTREPORT (39)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MEASUREMENTREPORT_MIN_LEN (3)
+
+#define DOT11F_IE_MEASUREMENTREPORT_MAX_LEN (29)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_measurement_report(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEMeasurementReport*,
+	bool);
+
+uint32_t dot11f_pack_ie_measurement_report(
+	tpAniSirGlobal,
+	tDot11fIEMeasurementReport *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_measurement_report(
+	tpAniSirGlobal,
+	tDot11fIEMeasurementReport *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 38 (0x26) */
+typedef struct sDot11fIEMeasurementRequest {
+	uint8_t             present;
+	uint8_t             measurement_token;
+	uint8_t             parallel:1;
+	uint8_t               enable:1;
+	uint8_t              request:1;
+	uint8_t               report:1;
+	uint8_t    durationMandatory:1;
+	uint8_t               unused:3;
+	uint8_t             measurement_type;
+	union {
+		struct {
+			uint8_t channel_no;
+			uint8_t meas_start_time[8];
+			uint16_t meas_duration;
+		} Basic; /* measurement_type = 0 */
+		struct {
+			uint8_t channel_no;
+			uint8_t meas_start_time[8];
+			uint16_t meas_duration;
+		} CCA; /* measurement_type = 1 */
+		struct {
+			uint8_t channel_no;
+			uint8_t meas_start_time[8];
+			uint16_t meas_duration;
+		} RPIHistogram; /* measurement_type = 2 */
+		struct {
+			uint8_t regClass;
+			uint8_t channel;
+			uint16_t randomization;
+			uint16_t meas_duration;
+			uint8_t meas_mode;
+			uint8_t BSSID[6];
+	tDot11fIESSID SSID;
+	tDot11fIEBeaconReporting BeaconReporting;
+	tDot11fIEBcnReportingDetail BcnReportingDetail;
+	tDot11fIERequestedInfo RequestedInfo;
+	uint16_t num_APChannelReport;
+	tDot11fIEAPChannelReport APChannelReport[2];
+	tDot11fIElast_beacon_report_indication last_beacon_report_indication;
+		} Beacon; /* measurement_type = 5 */
+		struct {
+			uint8_t loc_subject;
+	tDot11fIEazimuth_req azimuth_req;
+	tDot11fIEreq_mac_addr req_mac_addr;
+	tDot11fIEtgt_mac_addr tgt_mac_addr;
+	tDot11fIEmax_age max_age;
+		} lci; /* measurement_type = 8 */
+		struct {
+			uint16_t random_interval;
+			uint8_t min_ap_count;
+	tDot11fIEneighbor_rpt neighbor_rpt;
+	tDot11fIEmax_age max_age;
+		} ftmrr; /* measurement_type = 16 */
+	} measurement_request;
+} tDot11fIEMeasurementRequest;
+
+#define DOT11F_EID_MEASUREMENTREQUEST (38)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MEASUREMENTREQUEST_MIN_LEN (4)
+
+#define DOT11F_IE_MEASUREMENTREQUEST_MAX_LEN (16)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_measurement_request(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEMeasurementRequest*,
+	bool);
+
+uint32_t dot11f_pack_ie_measurement_request(
+	tpAniSirGlobal,
+	tDot11fIEMeasurementRequest *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_measurement_request(
+	tpAniSirGlobal,
+	tDot11fIEMeasurementRequest *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 54 (0x36) */
+typedef struct sDot11fIEMobilityDomain {
+	uint8_t             present;
+	uint16_t            MDID;
+	uint8_t            overDSCap:1;
+	uint8_t       resourceReqCap:1;
+	uint8_t             reserved:6;
+} tDot11fIEMobilityDomain;
+
+#define DOT11F_EID_MOBILITYDOMAIN (54)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MOBILITYDOMAIN_MIN_LEN (3)
+
+#define DOT11F_IE_MOBILITYDOMAIN_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_mobility_domain(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEMobilityDomain*,
+	bool);
+
+uint32_t dot11f_pack_ie_mobility_domain(
+	tpAniSirGlobal,
+	tDot11fIEMobilityDomain *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_MobilityDomain(
+	tpAniSirGlobal,
+	tDot11fIEMobilityDomain *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 52 (0x34) */
+typedef struct sDot11fIENeighborReport {
+	uint8_t                             present;
+	uint8_t                             bssid[6];
+	uint8_t                       APReachability:2;
+	uint8_t                             Security:1;
+	uint8_t                             KeyScope:1;
+	uint8_t                          SpecMgmtCap:1;
+	uint8_t                               QosCap:1;
+	uint8_t                                 apsd:1;
+	uint8_t                                  rrm:1;
+	uint8_t                            DelayedBA:1;
+	uint8_t                                ImmBA:1;
+	uint8_t                       MobilityDomain:1;
+	uint8_t                             reserved:5;
+	uint16_t                            reserved1;
+	uint8_t                             regulatoryClass;
+	uint8_t                             channel;
+	uint8_t                             PhyType;
+	tDot11fIETSFInfo                    TSFInfo;
+	tDot11fIECondensedCountryStr        CondensedCountryStr;
+	tDot11fIEMeasurementPilot           MeasurementPilot;
+	tDot11fIERRMEnabledCap              RRMEnabledCap;
+	tDot11fIEMultiBssid                 MultiBssid;
+} tDot11fIENeighborReport;
+
+#define DOT11F_EID_NEIGHBORREPORT (52)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_NEIGHBORREPORT_MIN_LEN (13)
+
+#define DOT11F_IE_NEIGHBORREPORT_MAX_LEN (546)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_neighbor_report(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIENeighborReport*,
+	bool);
+
+uint32_t dot11f_pack_ie_neighbor_report(
+	tpAniSirGlobal,
+	tDot11fIENeighborReport *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_neighbor_report(
+	tpAniSirGlobal,
+	tDot11fIENeighborReport *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 74 (0x4a) */
+typedef struct sDot11fIEOBSSScanParameters {
+	uint8_t             present;
+	uint16_t            obssScanPassiveDwell;
+	uint16_t            obssScanActiveDwell;
+	uint16_t            bssChannelWidthTriggerScanInterval;
+	uint16_t            obssScanPassiveTotalPerChannel;
+	uint16_t            obssScanActiveTotalPerChannel;
+	uint16_t            bssWidthChannelTransitionDelayFactor;
+	uint16_t            obssScanActivityThreshold;
+} tDot11fIEOBSSScanParameters;
+
+#define DOT11F_EID_OBSSSCANPARAMETERS (74)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_OBSSSCANPARAMETERS_MIN_LEN (14)
+
+#define DOT11F_IE_OBSSSCANPARAMETERS_MAX_LEN (14)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_obss_scan_parameters(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEOBSSScanParameters*,
+	bool);
+
+uint32_t dot11f_pack_ie_obss_scan_parameters(
+	tpAniSirGlobal,
+	tDot11fIEOBSSScanParameters *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_OBSSScanParameters(
+	tpAniSirGlobal,
+	tDot11fIEOBSSScanParameters *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 199 (0xc7) */
+typedef struct sDot11fIEOperatingMode {
+	uint8_t             present;
+	uint8_t            chanWidth:2;
+	uint8_t             reserved:2;
+	uint8_t                rxNSS:3;
+	uint8_t            rxNSSType:1;
+} tDot11fIEOperatingMode;
+
+#define DOT11F_EID_OPERATINGMODE (199)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_OPERATINGMODE_MIN_LEN (1)
+
+#define DOT11F_IE_OPERATINGMODE_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_operating_mode(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEOperatingMode*,
+	bool);
+
+uint32_t dot11f_pack_ie_operating_mode(
+	tpAniSirGlobal,
+	tDot11fIEOperatingMode *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_OperatingMode(
+	tpAniSirGlobal,
+	tDot11fIEOperatingMode *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PAssocReq {
+	uint8_t             present;
+	tDot11fTLVP2PCapability P2PCapability;
+	tDot11fTLVExtendedListenTiming ExtendedListenTiming;
+	tDot11fTLVP2PDeviceInfo P2PDeviceInfo;
+} tDot11fIEP2PAssocReq;
+
+#define DOT11F_EID_P2PASSOCREQ (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PASSOCREQ_MIN_LEN (4)
+
+#define DOT11F_IE_P2PASSOCREQ_MAX_LEN (71)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_p2_p_assoc_req(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEP2PAssocReq*,
+	bool);
+
+uint32_t dot11f_pack_ie_p2_p_assoc_req(
+	tpAniSirGlobal,
+	tDot11fIEP2PAssocReq *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_assoc_req(
+	tpAniSirGlobal,
+	tDot11fIEP2PAssocReq *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PAssocRes {
+	uint8_t             present;
+	tDot11fTLVP2PStatus P2PStatus;
+	tDot11fTLVExtendedListenTiming ExtendedListenTiming;
+} tDot11fIEP2PAssocRes;
+
+#define DOT11F_EID_P2PASSOCRES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PASSOCRES_MIN_LEN (4)
+
+#define DOT11F_IE_P2PASSOCRES_MAX_LEN (15)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_p2_p_assoc_res(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEP2PAssocRes*,
+	bool);
+
+uint32_t dot11f_pack_ie_p2_p_assoc_res(
+	tpAniSirGlobal,
+	tDot11fIEP2PAssocRes *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_assoc_res(
+	tpAniSirGlobal,
+	tDot11fIEP2PAssocRes *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PBeacon {
+	uint8_t             present;
+	tDot11fTLVP2PCapability P2PCapability;
+	tDot11fTLVP2PDeviceId P2PDeviceId;
+	tDot11fTLVNoticeOfAbsence NoticeOfAbsence;
+} tDot11fIEP2PBeacon;
+
+#define DOT11F_EID_P2PBEACON (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PBEACON_MIN_LEN (4)
+
+#define DOT11F_IE_P2PBEACON_MAX_LEN (59)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_p2_p_beacon(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEP2PBeacon*,
+	bool);
+
+uint32_t dot11f_pack_ie_p2_p_beacon(
+	tpAniSirGlobal,
+	tDot11fIEP2PBeacon *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_beacon(
+	tpAniSirGlobal,
+	tDot11fIEP2PBeacon *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PBeaconProbeRes {
+	uint8_t             present;
+	tDot11fTLVP2PCapability P2PCapability;
+	tDot11fTLVP2PDeviceId P2PDeviceId;
+	tDot11fTLVExtendedListenTiming ExtendedListenTiming;
+	tDot11fTLVNoticeOfAbsence NoticeOfAbsence;
+	tDot11fTLVP2PDeviceInfo P2PDeviceInfo;
+	tDot11fTLVP2PGroupInfo P2PGroupInfo;
+} tDot11fIEP2PBeaconProbeRes;
+
+#define DOT11F_EID_P2PBEACONPROBERES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PBEACONPROBERES_MIN_LEN (4)
+
+#define DOT11F_IE_P2PBEACONPROBERES_MAX_LEN (1148)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_p2_p_beacon_probe_res(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEP2PBeaconProbeRes*,
+	bool);
+
+uint32_t dot11f_pack_ie_p2_p_beacon_probe_res(
+	tpAniSirGlobal,
+	tDot11fIEP2PBeaconProbeRes *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_beacon_probe_res(
+	tpAniSirGlobal,
+	tDot11fIEP2PBeaconProbeRes *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PDeAuth {
+	uint8_t             present;
+	tDot11fTLVMinorReasonCode MinorReasonCode;
+} tDot11fIEP2PDeAuth;
+
+#define DOT11F_EID_P2PDEAUTH (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PDEAUTH_MIN_LEN (4)
+
+#define DOT11F_IE_P2PDEAUTH_MAX_LEN (8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_p2_p_de_auth(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEP2PDeAuth*,
+	bool);
+
+uint32_t dot11f_pack_ie_p2_p_de_auth(
+	tpAniSirGlobal,
+	tDot11fIEP2PDeAuth *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_de_auth(
+	tpAniSirGlobal,
+	tDot11fIEP2PDeAuth *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PDisAssoc {
+	uint8_t             present;
+	tDot11fTLVMinorReasonCode MinorReasonCode;
+} tDot11fIEP2PDisAssoc;
+
+#define DOT11F_EID_P2PDISASSOC (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PDISASSOC_MIN_LEN (4)
+
+#define DOT11F_IE_P2PDISASSOC_MAX_LEN (8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_p2_p_dis_assoc(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEP2PDisAssoc*,
+	bool);
+
+uint32_t dot11f_pack_ie_p2_p_dis_assoc(
+	tpAniSirGlobal,
+	tDot11fIEP2PDisAssoc *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_dis_assoc(
+	tpAniSirGlobal,
+	tDot11fIEP2PDisAssoc *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} */
+typedef struct sDot11fIEP2PIEOpaque {
+	uint8_t             present;
+	uint8_t             num_data;
+	uint8_t             data[249];
+} tDot11fIEP2PIEOpaque;
+
+#define DOT11F_EID_P2PIEOPAQUE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PIEOPAQUE_MIN_LEN (6)
+
+#define DOT11F_IE_P2PIEOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_p2_pie_opaque(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEP2PIEOpaque*,
+	bool);
+
+uint32_t dot11f_pack_ie_p2_pie_opaque(
+	tpAniSirGlobal,
+	tDot11fIEP2PIEOpaque *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_P2PIEOpaque(
+	tpAniSirGlobal,
+	tDot11fIEP2PIEOpaque *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PProbeReq {
+	uint8_t             present;
+	tDot11fTLVP2PCapability P2PCapability;
+	tDot11fTLVP2PDeviceId P2PDeviceId;
+	tDot11fTLVListenChannel ListenChannel;
+	tDot11fTLVExtendedListenTiming ExtendedListenTiming;
+	tDot11fTLVOperatingChannel OperatingChannel;
+} tDot11fIEP2PProbeReq;
+
+#define DOT11F_EID_P2PPROBEREQ (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PPROBEREQ_MIN_LEN (4)
+
+#define DOT11F_IE_P2PPROBEREQ_MAX_LEN (41)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_p2_p_probe_req(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEP2PProbeReq*,
+	bool);
+
+uint32_t dot11f_pack_ie_p2_p_probe_req(
+	tpAniSirGlobal,
+	tDot11fIEP2PProbeReq *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_probe_req(
+	tpAniSirGlobal,
+	tDot11fIEP2PProbeReq *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PProbeRes {
+	uint8_t             present;
+	tDot11fTLVP2PCapability P2PCapability;
+	tDot11fTLVExtendedListenTiming ExtendedListenTiming;
+	tDot11fTLVNoticeOfAbsence NoticeOfAbsence;
+	tDot11fTLVP2PDeviceInfo P2PDeviceInfo;
+	tDot11fTLVP2PGroupInfo P2PGroupInfo;
+} tDot11fIEP2PProbeRes;
+
+#define DOT11F_EID_P2PPROBERES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PPROBERES_MIN_LEN (4)
+
+#define DOT11F_IE_P2PPROBERES_MAX_LEN (1139)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_p2_p_probe_res(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEP2PProbeRes*,
+	bool);
+
+uint32_t dot11f_pack_ie_p2_p_probe_res(
+	tpAniSirGlobal,
+	tDot11fIEP2PProbeRes *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_probe_res(
+	tpAniSirGlobal,
+	tDot11fIEP2PProbeRes *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 105 (0x69) */
+typedef struct sDot11fIEPTIControl {
+	uint8_t             present;
+	uint8_t             tid;
+	uint16_t            sequence_control;
+} tDot11fIEPTIControl;
+
+#define DOT11F_EID_PTICONTROL (105)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_PTICONTROL_MIN_LEN (3)
+
+#define DOT11F_IE_PTICONTROL_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_pti_control(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEPTIControl*,
+	bool);
+
+uint32_t dot11f_pack_ie_pti_control(
+	tpAniSirGlobal,
+	tDot11fIEPTIControl *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_PTIControl(
+	tpAniSirGlobal,
+	tDot11fIEPTIControl *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 106 (0x6a) */
+typedef struct sDot11fIEPUBufferStatus {
+	uint8_t             present;
+	uint8_t   ac_bk_traffic_aval:1;
+	uint8_t   ac_be_traffic_aval:1;
+	uint8_t   ac_vi_traffic_aval:1;
+	uint8_t   ac_vo_traffic_aval:1;
+	uint8_t             reserved:4;
+} tDot11fIEPUBufferStatus;
+
+#define DOT11F_EID_PUBUFFERSTATUS (106)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_PUBUFFERSTATUS_MIN_LEN (1)
+
+#define DOT11F_IE_PUBUFFERSTATUS_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_pu_buffer_status(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEPUBufferStatus*,
+	bool);
+
+uint32_t dot11f_pack_ie_pu_buffer_status(
+	tpAniSirGlobal,
+	tDot11fIEPUBufferStatus *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_PUBufferStatus(
+	tpAniSirGlobal,
+	tDot11fIEPUBufferStatus *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 33 (0x21) */
+typedef struct sDot11fIEPowerCaps {
+	uint8_t             present;
+	uint8_t             minTxPower;
+	uint8_t             maxTxPower;
+} tDot11fIEPowerCaps;
+
+#define DOT11F_EID_POWERCAPS (33)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_POWERCAPS_MIN_LEN (2)
+
+#define DOT11F_IE_POWERCAPS_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_power_caps(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEPowerCaps*,
+	bool);
+
+uint32_t dot11f_pack_ie_power_caps(
+	tpAniSirGlobal,
+	tDot11fIEPowerCaps *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_PowerCaps(
+	tpAniSirGlobal,
+	tDot11fIEPowerCaps *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 32 (0x20) */
+typedef struct sDot11fIEPowerConstraints {
+	uint8_t             present;
+	uint8_t             localPowerConstraints;
+} tDot11fIEPowerConstraints;
+
+#define DOT11F_EID_POWERCONSTRAINTS (32)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_POWERCONSTRAINTS_MIN_LEN (1)
+
+#define DOT11F_IE_POWERCONSTRAINTS_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_power_constraints(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEPowerConstraints*,
+	bool);
+
+uint32_t dot11f_pack_ie_power_constraints(
+	tpAniSirGlobal,
+	tDot11fIEPowerConstraints *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_PowerConstraints(
+	tpAniSirGlobal,
+	tDot11fIEPowerConstraints *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 11 (0x0b) */
+typedef struct sDot11fIEQBSSLoad {
+	uint8_t             present;
+	uint16_t            stacount;
+	uint8_t             chautil;
+	uint16_t            avail;
+} tDot11fIEQBSSLoad;
+
+#define DOT11F_EID_QBSSLOAD (11)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QBSSLOAD_MIN_LEN (5)
+
+#define DOT11F_IE_QBSSLOAD_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_qbss_load(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEQBSSLoad*,
+	bool);
+
+uint32_t dot11f_pack_ie_qbss_load(
+	tpAniSirGlobal,
+	tDot11fIEQBSSLoad *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_QBSSLoad(
+	tpAniSirGlobal,
+	tDot11fIEQBSSLoad *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x8c, 0xfd, 0xf0, 0x01} */
+typedef struct sDot11fIEQCN_IE {
+	uint8_t             present;
+	uint8_t             version[4];
+} tDot11fIEQCN_IE;
+
+#define DOT11F_EID_QCN_IE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QCN_IE_MIN_LEN (8)
+
+#define DOT11F_IE_QCN_IE_MAX_LEN (8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_QCN_IE(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEQCN_IE*,
+	bool);
+
+uint32_t dot11f_pack_ie_QCN_IE(
+	tpAniSirGlobal,
+	tDot11fIEQCN_IE *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_QCN_IE(
+	tpAniSirGlobal,
+	tDot11fIEQCN_IE *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0xa0, 0xc6} */
+typedef struct sDot11fIEQComVendorIE {
+	uint8_t             present;
+	uint8_t             type;
+	uint8_t             channel;
+} tDot11fIEQComVendorIE;
+
+#define DOT11F_EID_QCOMVENDORIE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QCOMVENDORIE_MIN_LEN (5)
+
+#define DOT11F_IE_QCOMVENDORIE_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_QComVendorIE(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEQComVendorIE*,
+	bool);
+
+uint32_t dot11f_pack_ie_QComVendorIE(
+	tpAniSirGlobal,
+	tDot11fIEQComVendorIE *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_QComVendorIE(
+	tpAniSirGlobal,
+	tDot11fIEQComVendorIE *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 46 (0x2e) */
+typedef struct sDot11fIEQOSCapsAp {
+	uint8_t             present;
+	uint8_t                count:4;
+	uint8_t                 qack:1;
+	uint8_t                 qreq:1;
+	uint8_t              txopreq:1;
+	uint8_t             reserved:1;
+} tDot11fIEQOSCapsAp;
+
+#define DOT11F_EID_QOSCAPSAP (46)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QOSCAPSAP_MIN_LEN (1)
+
+#define DOT11F_IE_QOSCAPSAP_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_qos_caps_ap(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEQOSCapsAp*,
+	bool);
+
+uint32_t dot11f_pack_ie_qos_caps_ap(
+	tpAniSirGlobal,
+	tDot11fIEQOSCapsAp *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_QOSCapsAp(
+	tpAniSirGlobal,
+	tDot11fIEQOSCapsAp *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 46 (0x2e) */
+typedef struct sDot11fIEQOSCapsStation {
+	uint8_t             present;
+	uint8_t           acvo_uapsd:1;
+	uint8_t           acvi_uapsd:1;
+	uint8_t           acbk_uapsd:1;
+	uint8_t           acbe_uapsd:1;
+	uint8_t                 qack:1;
+	uint8_t        max_sp_length:2;
+	uint8_t        more_data_ack:1;
+} tDot11fIEQOSCapsStation;
+
+#define DOT11F_EID_QOSCAPSSTATION (46)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QOSCAPSSTATION_MIN_LEN (1)
+
+#define DOT11F_IE_QOSCAPSSTATION_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_qos_caps_station(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEQOSCapsStation*,
+	bool);
+
+uint32_t dot11f_pack_ie_qos_caps_station(
+	tpAniSirGlobal,
+	tDot11fIEQOSCapsStation *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_QOSCapsStation(
+	tpAniSirGlobal,
+	tDot11fIEQOSCapsStation *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 110 (0x6e) */
+typedef struct sDot11fIEQosMapSet {
+	uint8_t             present;
+	uint8_t             num_dscp_exceptions;
+	uint8_t             dscp_exceptions[60];
+} tDot11fIEQosMapSet;
+
+#define DOT11F_EID_QOSMAPSET (110)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QOSMAPSET_MIN_LEN (0)
+
+#define DOT11F_IE_QOSMAPSET_MAX_LEN (60)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_qos_map_set(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEQosMapSet*,
+	bool);
+
+uint32_t dot11f_pack_ie_qos_map_set(
+	tpAniSirGlobal,
+	tDot11fIEQosMapSet *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_QosMapSet(
+	tpAniSirGlobal,
+	tDot11fIEQosMapSet *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 40 (0x28) */
+typedef struct sDot11fIEQuiet {
+	uint8_t             present;
+	uint8_t             count;
+	uint8_t             period;
+	uint16_t            duration;
+	uint16_t            offset;
+} tDot11fIEQuiet;
+
+#define DOT11F_EID_QUIET (40)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QUIET_MIN_LEN (6)
+
+#define DOT11F_IE_QUIET_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_quiet(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEQuiet*,
+	bool);
+
+uint32_t dot11f_pack_ie_quiet(
+	tpAniSirGlobal,
+	tDot11fIEQuiet *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_Quiet(
+	tpAniSirGlobal,
+	tDot11fIEQuiet *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 53 (0x35) */
+typedef struct sDot11fIERCPIIE {
+	uint8_t             present;
+	uint8_t             rcpi;
+} tDot11fIERCPIIE;
+
+#define DOT11F_EID_RCPIIE (53)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RCPIIE_MIN_LEN (1)
+
+#define DOT11F_IE_RCPIIE_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_rcpiie(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIERCPIIE*,
+	bool);
+
+uint32_t dot11f_pack_ie_rcpiie(
+	tpAniSirGlobal,
+	tDot11fIERCPIIE *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_RCPIIE(
+	tpAniSirGlobal,
+	tDot11fIERCPIIE *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 57 (0x39) */
+typedef struct sDot11fIERICDataDesc {
+	uint8_t                       present;
+	tDot11fIERICData              RICData;
+	tDot11fIERICDescriptor        RICDescriptor;
+	tDot11fIETSPEC                TSPEC;
+	uint16_t                      num_TCLAS;
+	tDot11fIETCLAS                TCLAS[2];
+	tDot11fIETCLASSPROC           TCLASSPROC;
+	tDot11fIETSDelay              TSDelay;
+	tDot11fIESchedule             Schedule;
+	tDot11fIEWMMTSPEC             WMMTSPEC;
+	uint16_t                      num_WMMTCLAS;
+	tDot11fIEWMMTCLAS             WMMTCLAS[2];
+	tDot11fIEWMMTCLASPROC         WMMTCLASPROC;
+	tDot11fIEWMMTSDelay           WMMTSDelay;
+	tDot11fIEWMMSchedule          WMMSchedule;
+} tDot11fIERICDataDesc;
+
+#define DOT11F_EID_RICDATADESC (57)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RICDATADESC_MIN_LEN (0)
+
+#define DOT11F_IE_RICDATADESC_MAX_LEN (548)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ric_data_desc(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIERICDataDesc*,
+	bool);
+
+uint32_t dot11f_pack_ie_ric_data_desc(
+	tpAniSirGlobal,
+	tDot11fIERICDataDesc *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ieric_data_desc(
+	tpAniSirGlobal,
+	tDot11fIERICDataDesc *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 48 (0x30) */
+typedef struct sDot11fIERSN {
+	uint8_t             present;
+	uint16_t            version /* Must be 1! */;
+	uint8_t             gp_cipher_suite_present;
+	uint8_t             gp_cipher_suite[4];
+	uint16_t            pwise_cipher_suite_count;
+	uint8_t             pwise_cipher_suites[6][4];
+	uint16_t            akm_suite_cnt;
+	uint8_t             akm_suite[6][4];
+	uint8_t             RSN_Cap_present;
+	uint8_t             RSN_Cap[2];
+	uint16_t            pmkid_count;
+	uint8_t             pmkid[4][16];
+	uint8_t             gp_mgmt_cipher_suite_present;
+	uint8_t             gp_mgmt_cipher_suite[4];
+} tDot11fIERSN;
+
+#define DOT11F_EID_RSN (48)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RSN_MIN_LEN (2)
+
+#define DOT11F_IE_RSN_MAX_LEN (130)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_rsn(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIERSN*,
+	bool);
+
+uint32_t dot11f_pack_ie_rsn(
+	tpAniSirGlobal,
+	tDot11fIERSN *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iersn(
+	tpAniSirGlobal,
+	tDot11fIERSN *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 65 (0x41) */
+typedef struct sDot11fIERSNIIE {
+	uint8_t             present;
+	uint8_t             rsni;
+} tDot11fIERSNIIE;
+
+#define DOT11F_EID_RSNIIE (65)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RSNIIE_MIN_LEN (1)
+
+#define DOT11F_IE_RSNIIE_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_rsniie(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIERSNIIE*,
+	bool);
+
+uint32_t dot11f_pack_ie_rsniie(
+	tpAniSirGlobal,
+	tDot11fIERSNIIE *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iersnIIE(
+	tpAniSirGlobal,
+	tDot11fIERSNIIE *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 48 (0x30) */
+typedef struct sDot11fIERSNOpaque {
+	uint8_t             present;
+	uint8_t             num_data;
+	uint8_t             data[253];
+} tDot11fIERSNOpaque;
+
+#define DOT11F_EID_RSNOPAQUE (48)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RSNOPAQUE_MIN_LEN (0)
+
+#define DOT11F_IE_RSNOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_rsn_opaque(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIERSNOpaque*,
+	bool);
+
+uint32_t dot11f_pack_ie_rsn_opaque(
+	tpAniSirGlobal,
+	tDot11fIERSNOpaque *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iersnOpaque(
+	tpAniSirGlobal,
+	tDot11fIERSNOpaque *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 36 (0x24) */
+typedef struct sDot11fIESuppChannels {
+	uint8_t             present;
+	uint8_t             num_bands;
+	uint8_t             bands[48][2];
+} tDot11fIESuppChannels;
+
+#define DOT11F_EID_SUPPCHANNELS (36)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SUPPCHANNELS_MIN_LEN (0)
+
+#define DOT11F_IE_SUPPCHANNELS_MAX_LEN (96)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_supp_channels(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIESuppChannels*,
+	bool);
+
+uint32_t dot11f_pack_ie_supp_channels(
+	tpAniSirGlobal,
+	tDot11fIESuppChannels *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_SuppChannels(
+	tpAniSirGlobal,
+	tDot11fIESuppChannels *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 59 (0x3b) */
+typedef struct sDot11fIESuppOperatingClasses {
+	uint8_t             present;
+	uint8_t             num_classes;
+	uint8_t             classes[32];
+} tDot11fIESuppOperatingClasses;
+
+#define DOT11F_EID_SUPPOPERATINGCLASSES (59)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SUPPOPERATINGCLASSES_MIN_LEN (1)
+
+#define DOT11F_IE_SUPPOPERATINGCLASSES_MAX_LEN (32)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_supp_operating_classes(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIESuppOperatingClasses*,
+	bool);
+
+uint32_t dot11f_pack_ie_supp_operating_classes(
+	tpAniSirGlobal,
+	tDot11fIESuppOperatingClasses *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_SuppOperatingClasses(
+	tpAniSirGlobal,
+	tDot11fIESuppOperatingClasses *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 1 (0x01) */
+typedef struct sDot11fIESuppRates {
+	uint8_t             present;
+	uint8_t             num_rates;
+	uint8_t             rates[12];
+} tDot11fIESuppRates;
+
+#define DOT11F_EID_SUPPRATES (1)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SUPPRATES_MIN_LEN (0)
+
+#define DOT11F_IE_SUPPRATES_MAX_LEN (12)
+
+#define DOT11F_IS_BG_RATE(_x)  (((_x) == 02) || \
+				((_x) == 04) || \
+				((_x) == 11) || \
+				((_x) == 22) || \
+				((_x) == 12) || \
+				((_x) == 18) || \
+				((_x) == 24) || \
+				((_x) == 36) || \
+				((_x) == 48) || \
+				((_x) == 72) || \
+				((_x) == 96) || \
+				((_x) == 108))
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_supp_rates(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIESuppRates*,
+	bool);
+
+uint32_t dot11f_pack_ie_supp_rates(
+	tpAniSirGlobal,
+	tDot11fIESuppRates *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_SuppRates(
+	tpAniSirGlobal,
+	tDot11fIESuppRates *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 5 (0x05) */
+typedef struct sDot11fIETIM {
+	uint8_t             present;
+	uint8_t             dtim_count;
+	uint8_t             dtim_period;
+	uint8_t             bmpctl;
+	uint8_t             num_vbmp;
+	uint8_t             vbmp[251];
+} tDot11fIETIM;
+
+#define DOT11F_EID_TIM (5)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TIM_MIN_LEN (4)
+
+#define DOT11F_IE_TIM_MAX_LEN (254)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_tim(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIETIM*,
+	bool);
+
+uint32_t dot11f_pack_ie_tim(
+	tpAniSirGlobal,
+	tDot11fIETIM *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TIM(
+	tpAniSirGlobal,
+	tDot11fIETIM *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 35 (0x23) */
+typedef struct sDot11fIETPCReport {
+	uint8_t             present;
+	uint8_t             tx_power;
+	uint8_t             link_margin;
+} tDot11fIETPCReport;
+
+#define DOT11F_EID_TPCREPORT (35)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TPCREPORT_MIN_LEN (2)
+
+#define DOT11F_IE_TPCREPORT_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_tpc_report(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIETPCReport*,
+	bool);
+
+uint32_t dot11f_pack_ie_tpc_report(
+	tpAniSirGlobal,
+	tDot11fIETPCReport *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TPCReport(
+	tpAniSirGlobal,
+	tDot11fIETPCReport *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 34 (0x22) */
+typedef struct sDot11fIETPCRequest {
+	uint8_t             present;
+} tDot11fIETPCRequest;
+
+#define DOT11F_EID_TPCREQUEST (34)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TPCREQUEST_MIN_LEN (0)
+
+#define DOT11F_IE_TPCREQUEST_MAX_LEN (0)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_tpc_request(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIETPCRequest*,
+	bool);
+
+uint32_t dot11f_pack_ie_tpc_request(
+	tpAniSirGlobal,
+	tDot11fIETPCRequest *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TPCRequest(
+	tpAniSirGlobal,
+	tDot11fIETPCRequest *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 69 (0x45) */
+typedef struct sDot11fIETimeAdvertisement {
+	uint8_t             present;
+	uint8_t             timing_capabilities;
+	uint8_t             time_value[10];
+	uint8_t             time_error[5];
+} tDot11fIETimeAdvertisement;
+
+#define DOT11F_EID_TIMEADVERTISEMENT (69)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TIMEADVERTISEMENT_MIN_LEN (16)
+
+#define DOT11F_IE_TIMEADVERTISEMENT_MAX_LEN (16)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_time_advertisement(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIETimeAdvertisement*,
+	bool);
+
+uint32_t dot11f_pack_ie_time_advertisement(
+	tpAniSirGlobal,
+	tDot11fIETimeAdvertisement *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_time_advertisement(
+	tpAniSirGlobal,
+	tDot11fIETimeAdvertisement *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 56 (0x38) */
+typedef struct sDot11fIETimeoutInterval {
+	uint8_t             present;
+	uint8_t             timeoutType;
+	uint32_t            timeoutValue;
+} tDot11fIETimeoutInterval;
+
+#define DOT11F_EID_TIMEOUTINTERVAL (56)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TIMEOUTINTERVAL_MIN_LEN (5)
+
+#define DOT11F_IE_TIMEOUTINTERVAL_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_timeout_interval(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIETimeoutInterval*,
+	bool);
+
+uint32_t dot11f_pack_ie_timeout_interval(
+	tpAniSirGlobal,
+	tDot11fIETimeoutInterval *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TimeoutInterval(
+	tpAniSirGlobal,
+	tDot11fIETimeoutInterval *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 193 (0xc1) */
+typedef struct sDot11fIEVHTExtBssLoad {
+	uint8_t             present;
+	uint8_t             muMIMOCapStaCount;
+	uint8_t             ssUnderUtil;
+	uint8_t             FortyMHzUtil;
+	uint8_t             EightyMHzUtil;
+	uint8_t             OneSixtyMHzUtil;
+} tDot11fIEVHTExtBssLoad;
+
+#define DOT11F_EID_VHTEXTBSSLOAD (193)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VHTEXTBSSLOAD_MIN_LEN (5)
+
+#define DOT11F_IE_VHTEXTBSSLOAD_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_vht_ext_bss_load(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEVHTExtBssLoad*,
+	bool);
+
+uint32_t dot11f_pack_ie_vht_ext_bss_load(
+	tpAniSirGlobal,
+	tDot11fIEVHTExtBssLoad *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_VHTExtBssLoad(
+	tpAniSirGlobal,
+	tDot11fIEVHTExtBssLoad *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x10, 0x18} */
+typedef struct sDot11fIEVendor1IE {
+	uint8_t             present;
+} tDot11fIEVendor1IE;
+
+#define DOT11F_EID_VENDOR1IE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VENDOR1IE_MIN_LEN (3)
+
+#define DOT11F_IE_VENDOR1IE_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_vendor1_ie(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEVendor1IE*,
+	bool);
+
+uint32_t dot11f_pack_ie_vendor1_ie(
+	tpAniSirGlobal,
+	tDot11fIEVendor1IE *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_Vendor1IE(
+	tpAniSirGlobal,
+	tDot11fIEVendor1IE *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x16, 0x32} */
+typedef struct sDot11fIEVendor3IE {
+	uint8_t             present;
+} tDot11fIEVendor3IE;
+
+#define DOT11F_EID_VENDOR3IE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VENDOR3IE_MIN_LEN (3)
+
+#define DOT11F_IE_VENDOR3IE_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_vendor3_ie(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEVendor3IE*,
+	bool);
+
+uint32_t dot11f_pack_ie_vendor3_ie(
+	tpAniSirGlobal,
+	tDot11fIEVendor3IE *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_Vendor3IE(
+	tpAniSirGlobal,
+	tDot11fIEVendor3IE *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 68 (0x44) */
+typedef struct sDot11fIEWAPI {
+	uint8_t             present;
+	uint16_t            version /* Must be 1! */;
+	uint16_t            akm_suite_count;
+	uint8_t             akm_suites[4][4];
+	uint16_t            unicast_cipher_suite_count;
+	uint8_t             unicast_cipher_suites[4][4];
+	uint8_t             multicast_cipher_suite[4];
+	uint16_t              preauth:1;
+	uint16_t             reserved:15;
+	uint16_t            bkid_count;
+	uint8_t             bkid[4][16];
+} tDot11fIEWAPI;
+
+#define DOT11F_EID_WAPI (68)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WAPI_MIN_LEN (12)
+
+#define DOT11F_IE_WAPI_MAX_LEN (110)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wapi(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWAPI*,
+	bool);
+
+uint32_t dot11f_pack_ie_wapi(
+	tpAniSirGlobal,
+	tDot11fIEWAPI *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iewapi(
+	tpAniSirGlobal,
+	tDot11fIEWAPI *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 68 (0x44) */
+typedef struct sDot11fIEWAPIOpaque {
+	uint8_t             present;
+	uint8_t             num_data;
+	uint8_t             data[253];
+} tDot11fIEWAPIOpaque;
+
+#define DOT11F_EID_WAPIOPAQUE (68)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WAPIOPAQUE_MIN_LEN (6)
+
+#define DOT11F_IE_WAPIOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wapi_opaque(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWAPIOpaque*,
+	bool);
+
+uint32_t dot11f_pack_ie_wapi_opaque(
+	tpAniSirGlobal,
+	tDot11fIEWAPIOpaque *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iewapiOpaque(
+	tpAniSirGlobal,
+	tDot11fIEWAPIOpaque *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x08, 0x00} */
+typedef struct sDot11fIEWFATPC {
+	uint8_t             present;
+	uint8_t             txPower;
+	uint8_t             linkMargin;
+} tDot11fIEWFATPC;
+
+#define DOT11F_EID_WFATPC (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WFATPC_MIN_LEN (7)
+
+#define DOT11F_IE_WFATPC_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wfatpc(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWFATPC*,
+	bool);
+
+uint32_t dot11f_pack_ie_wfatpc(
+	tpAniSirGlobal,
+	tDot11fIEWFATPC *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WFATPC(
+	tpAniSirGlobal,
+	tDot11fIEWFATPC *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x0a} */
+typedef struct sDot11fIEWFDIEOpaque {
+	uint8_t             present;
+	uint8_t             num_data;
+	uint8_t             data[249];
+} tDot11fIEWFDIEOpaque;
+
+#define DOT11F_EID_WFDIEOPAQUE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WFDIEOPAQUE_MIN_LEN (6)
+
+#define DOT11F_IE_WFDIEOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wfdie_opaque(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWFDIEOpaque*,
+	bool);
+
+uint32_t dot11f_pack_ie_wfdie_opaque(
+	tpAniSirGlobal,
+	tDot11fIEWFDIEOpaque *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WFDIEOpaque(
+	tpAniSirGlobal,
+	tDot11fIEWFDIEOpaque *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x05} */
+typedef struct sDot11fIEWMMCaps {
+	uint8_t             present;
+	uint8_t             version /* Must be 1! */;
+	uint8_t             reserved:4;
+	uint8_t                 qack:1;
+	uint8_t        queue_request:1;
+	uint8_t         txop_request:1;
+	uint8_t             more_ack:1;
+} tDot11fIEWMMCaps;
+
+#define DOT11F_EID_WMMCAPS (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMCAPS_MIN_LEN (7)
+
+#define DOT11F_IE_WMMCAPS_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wmm_caps(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWMMCaps*,
+	bool);
+
+uint32_t dot11f_pack_ie_wmm_caps(
+	tpAniSirGlobal,
+	tDot11fIEWMMCaps *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMCaps(
+	tpAniSirGlobal,
+	tDot11fIEWMMCaps *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x00} */
+typedef struct sDot11fIEWMMInfoAp {
+	uint8_t             present;
+	uint8_t             version;
+	uint8_t      param_set_count:4;
+	uint8_t             reserved:3;
+	uint8_t                uapsd:1;
+} tDot11fIEWMMInfoAp;
+
+#define DOT11F_EID_WMMINFOAP (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMINFOAP_MIN_LEN (7)
+
+#define DOT11F_IE_WMMINFOAP_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wmm_info_ap(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWMMInfoAp*,
+	bool);
+
+uint32_t dot11f_pack_ie_wmm_info_ap(
+	tpAniSirGlobal,
+	tDot11fIEWMMInfoAp *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMInfoAp(
+	tpAniSirGlobal,
+	tDot11fIEWMMInfoAp *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x00} */
+typedef struct sDot11fIEWMMInfoStation {
+	uint8_t             present;
+	uint8_t             version;
+	uint8_t           acvo_uapsd:1;
+	uint8_t           acvi_uapsd:1;
+	uint8_t           acbk_uapsd:1;
+	uint8_t           acbe_uapsd:1;
+	uint8_t            reserved1:1;
+	uint8_t        max_sp_length:2;
+	uint8_t            reserved2:1;
+} tDot11fIEWMMInfoStation;
+
+#define DOT11F_EID_WMMINFOSTATION (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMINFOSTATION_MIN_LEN (7)
+
+#define DOT11F_IE_WMMINFOSTATION_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wmm_info_station(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWMMInfoStation*,
+	bool);
+
+uint32_t dot11f_pack_ie_wmm_info_station(
+	tpAniSirGlobal,
+	tDot11fIEWMMInfoStation *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMInfoStation(
+	tpAniSirGlobal,
+	tDot11fIEWMMInfoStation *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x01} */
+typedef struct sDot11fIEWMMParams {
+	uint8_t             present;
+	uint8_t             version /* Must be 1! */;
+	uint8_t             qosInfo;
+	uint8_t             reserved2;
+	uint8_t           acbe_aifsn:4;
+	uint8_t             acbe_acm:1;
+	uint8_t             acbe_aci:2;
+	uint8_t              unused1:1;
+	uint8_t          acbe_acwmin:4;
+	uint8_t          acbe_acwmax:4;
+	uint16_t            acbe_txoplimit;
+	uint8_t           acbk_aifsn:4;
+	uint8_t             acbk_acm:1;
+	uint8_t             acbk_aci:2;
+	uint8_t              unused2:1;
+	uint8_t          acbk_acwmin:4;
+	uint8_t          acbk_acwmax:4;
+	uint16_t            acbk_txoplimit;
+	uint8_t           acvi_aifsn:4;
+	uint8_t             acvi_acm:1;
+	uint8_t             acvi_aci:2;
+	uint8_t              unused3:1;
+	uint8_t          acvi_acwmin:4;
+	uint8_t          acvi_acwmax:4;
+	uint16_t            acvi_txoplimit;
+	uint8_t           acvo_aifsn:4;
+	uint8_t             acvo_acm:1;
+	uint8_t             acvo_aci:2;
+	uint8_t              unused4:1;
+	uint8_t          acvo_acwmin:4;
+	uint8_t          acvo_acwmax:4;
+	uint16_t            acvo_txoplimit;
+} tDot11fIEWMMParams;
+
+#define DOT11F_EID_WMMPARAMS (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMPARAMS_MIN_LEN (24)
+
+#define DOT11F_IE_WMMPARAMS_MAX_LEN (24)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wmm_params(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWMMParams*,
+	bool);
+
+uint32_t dot11f_pack_ie_wmm_params(
+	tpAniSirGlobal,
+	tDot11fIEWMMParams *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMParams(
+	tpAniSirGlobal,
+	tDot11fIEWMMParams *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x01} */
+typedef struct sDot11fIEWPA {
+	uint8_t             present;
+	uint16_t            version /* Must be 1! */;
+	/* field added to fix the bug in dot11fPackIEWPA */
+	uint8_t             multicast_cipher_present;
+	uint8_t             multicast_cipher[4];
+	uint16_t            unicast_cipher_count;
+	uint8_t             unicast_ciphers[4][4];
+	uint16_t            auth_suite_count;
+	uint8_t             auth_suites[4][4];
+	uint16_t            caps;
+} tDot11fIEWPA;
+
+#define DOT11F_EID_WPA (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WPA_MIN_LEN (6)
+
+#define DOT11F_IE_WPA_MAX_LEN (48)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wpa(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWPA*,
+	bool);
+
+uint32_t dot11f_pack_ie_wpa(
+	tpAniSirGlobal,
+	tDot11fIEWPA *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iewpa(
+	tpAniSirGlobal,
+	tDot11fIEWPA *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x01} */
+typedef struct sDot11fIEWPAOpaque {
+	uint8_t             present;
+	uint8_t             num_data;
+	uint8_t             data[249];
+} tDot11fIEWPAOpaque;
+
+#define DOT11F_EID_WPAOPAQUE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WPAOPAQUE_MIN_LEN (6)
+
+#define DOT11F_IE_WPAOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wpa_opaque(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWPAOpaque*,
+	bool);
+
+uint32_t dot11f_pack_ie_wpa_opaque(
+	tpAniSirGlobal,
+	tDot11fIEWPAOpaque *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iewpaOpaque(
+	tpAniSirGlobal,
+	tDot11fIEWPAOpaque *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWSC {
+	uint8_t             present;
+	tDot11fTLVVersion   Version;
+	tDot11fTLVWPSState  WPSState;
+	tDot11fTLVAPSetupLocked APSetupLocked;
+	tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods;
+	tDot11fTLVUUID_E    UUID_E;
+	tDot11fTLVUUID_R    UUID_R;
+	tDot11fTLVRFBands   RFBands;
+	tDot11fTLVSelectedRegistrar SelectedRegistrar;
+	tDot11fTLVConfigMethods ConfigMethods;
+	tDot11fTLVAssociationState AssociationState;
+	tDot11fTLVConfigurationError ConfigurationError;
+	tDot11fTLVManufacturer Manufacturer;
+	tDot11fTLVModelName ModelName;
+	tDot11fTLVModelNumber ModelNumber;
+	tDot11fTLVSerialNumber SerialNumber;
+	tDot11fTLVDeviceName DeviceName;
+	tDot11fTLVDevicePasswordID DevicePasswordID;
+	tDot11fTLVPrimaryDeviceType PrimaryDeviceType;
+	tDot11fTLVRequestType RequestType;
+	tDot11fTLVResponseType ResponseType;
+	tDot11fTLVVendorExtension VendorExtension;
+	tDot11fTLVRequestDeviceType RequestDeviceType;
+} tDot11fIEWSC;
+
+#define DOT11F_EID_WSC (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSC_MIN_LEN (4)
+
+#define DOT11F_IE_WSC_MAX_LEN (366)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wsc(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWSC*,
+	bool);
+
+uint32_t dot11f_pack_ie_wsc(
+	tpAniSirGlobal,
+	tDot11fIEWSC *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_iewsc(
+	tpAniSirGlobal,
+	tDot11fIEWSC *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscAssocReq {
+	uint8_t             present;
+	tDot11fTLVVersion   Version;
+	tDot11fTLVRequestType RequestType;
+	tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscAssocReq;
+
+#define DOT11F_EID_WSCASSOCREQ (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCASSOCREQ_MIN_LEN (4)
+
+#define DOT11F_IE_WSCASSOCREQ_MAX_LEN (35)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wsc_assoc_req(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWscAssocReq*,
+	bool);
+
+uint32_t dot11f_pack_ie_wsc_assoc_req(
+	tpAniSirGlobal,
+	tDot11fIEWscAssocReq *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_assoc_req(
+	tpAniSirGlobal,
+	tDot11fIEWscAssocReq *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscAssocRes {
+	uint8_t             present;
+	tDot11fTLVVersion   Version;
+	tDot11fTLVResponseType ResponseType;
+	tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscAssocRes;
+
+#define DOT11F_EID_WSCASSOCRES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCASSOCRES_MIN_LEN (4)
+
+#define DOT11F_IE_WSCASSOCRES_MAX_LEN (35)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wsc_assoc_res(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWscAssocRes*,
+	bool);
+
+uint32_t dot11f_pack_ie_wsc_assoc_res(
+	tpAniSirGlobal,
+	tDot11fIEWscAssocRes *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_assoc_res(
+	tpAniSirGlobal,
+	tDot11fIEWscAssocRes *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscBeacon {
+	uint8_t             present;
+	tDot11fTLVVersion   Version;
+	tDot11fTLVWPSState  WPSState;
+	tDot11fTLVAPSetupLocked APSetupLocked;
+	tDot11fTLVSelectedRegistrar SelectedRegistrar;
+	tDot11fTLVDevicePasswordID DevicePasswordID;
+	tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods;
+	tDot11fTLVUUID_E    UUID_E;
+	tDot11fTLVRFBands   RFBands;
+	tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscBeacon;
+
+#define DOT11F_EID_WSCBEACON (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCBEACON_MIN_LEN (4)
+
+#define DOT11F_IE_WSCBEACON_MAX_LEN (82)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wsc_beacon(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWscBeacon*,
+	bool);
+
+uint32_t dot11f_pack_ie_wsc_beacon(
+	tpAniSirGlobal,
+	tDot11fIEWscBeacon *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_beacon(
+	tpAniSirGlobal,
+	tDot11fIEWscBeacon *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscBeaconProbeRes {
+	uint8_t             present;
+	tDot11fTLVVersion   Version;
+	tDot11fTLVWPSState  WPSState;
+	tDot11fTLVAPSetupLocked APSetupLocked;
+	tDot11fTLVSelectedRegistrar SelectedRegistrar;
+	tDot11fTLVDevicePasswordID DevicePasswordID;
+	tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods;
+	tDot11fTLVResponseType ResponseType;
+	tDot11fTLVUUID_E    UUID_E;
+	tDot11fTLVManufacturer Manufacturer;
+	tDot11fTLVModelName ModelName;
+	tDot11fTLVModelNumber ModelNumber;
+	tDot11fTLVSerialNumber SerialNumber;
+	tDot11fTLVPrimaryDeviceType PrimaryDeviceType;
+	tDot11fTLVDeviceName DeviceName;
+	tDot11fTLVConfigMethods ConfigMethods;
+	tDot11fTLVRFBands   RFBands;
+	tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscBeaconProbeRes;
+
+#define DOT11F_EID_WSCBEACONPROBERES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCBEACONPROBERES_MIN_LEN (4)
+
+#define DOT11F_IE_WSCBEACONPROBERES_MAX_LEN (317)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wsc_beacon_probe_res(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWscBeaconProbeRes*,
+	bool);
+
+uint32_t dot11f_pack_ie_wsc_beacon_probe_res(
+	tpAniSirGlobal,
+	tDot11fIEWscBeaconProbeRes *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_beacon_probe_res(
+	tpAniSirGlobal,
+	tDot11fIEWscBeaconProbeRes *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} */
+typedef struct sDot11fIEWscIEOpaque {
+	uint8_t             present;
+	uint8_t             num_data;
+	uint8_t             data[249];
+} tDot11fIEWscIEOpaque;
+
+#define DOT11F_EID_WSCIEOPAQUE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCIEOPAQUE_MIN_LEN (6)
+
+#define DOT11F_IE_WSCIEOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wsc_ie_opaque(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWscIEOpaque*,
+	bool);
+
+uint32_t dot11f_pack_ie_wsc_ie_opaque(
+	tpAniSirGlobal,
+	tDot11fIEWscIEOpaque *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WscIEOpaque(
+	tpAniSirGlobal,
+	tDot11fIEWscIEOpaque *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscProbeReq {
+	uint8_t             present;
+	tDot11fTLVVersion   Version;
+	tDot11fTLVRequestType RequestType;
+	tDot11fTLVConfigMethods ConfigMethods;
+	tDot11fTLVUUID_E    UUID_E;
+	tDot11fTLVPrimaryDeviceType PrimaryDeviceType;
+	tDot11fTLVRFBands   RFBands;
+	tDot11fTLVAssociationState AssociationState;
+	tDot11fTLVConfigurationError ConfigurationError;
+	tDot11fTLVDevicePasswordID DevicePasswordID;
+	tDot11fTLVManufacturer Manufacturer;
+	tDot11fTLVModelName ModelName;
+	tDot11fTLVModelNumber ModelNumber;
+	tDot11fTLVDeviceName DeviceName;
+	tDot11fTLVVendorExtension VendorExtension;
+	tDot11fTLVRequestDeviceType RequestDeviceType;
+} tDot11fIEWscProbeReq;
+
+#define DOT11F_EID_WSCPROBEREQ (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCPROBEREQ_MIN_LEN (4)
+
+#define DOT11F_IE_WSCPROBEREQ_MAX_LEN (284)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wsc_probe_req(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWscProbeReq*,
+	bool);
+
+uint32_t dot11f_pack_ie_wsc_probe_req(
+	tpAniSirGlobal,
+	tDot11fIEWscProbeReq *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_probe_req(
+	tpAniSirGlobal,
+	tDot11fIEWscProbeReq *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscProbeRes {
+	uint8_t             present;
+	tDot11fTLVVersion   Version;
+	tDot11fTLVWPSState  WPSState;
+	tDot11fTLVAPSetupLocked APSetupLocked;
+	tDot11fTLVSelectedRegistrar SelectedRegistrar;
+	tDot11fTLVDevicePasswordID DevicePasswordID;
+	tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods;
+	tDot11fTLVResponseType ResponseType;
+	tDot11fTLVUUID_E    UUID_E;
+	tDot11fTLVManufacturer Manufacturer;
+	tDot11fTLVModelName ModelName;
+	tDot11fTLVModelNumber ModelNumber;
+	tDot11fTLVSerialNumber SerialNumber;
+	tDot11fTLVPrimaryDeviceType PrimaryDeviceType;
+	tDot11fTLVDeviceName DeviceName;
+	tDot11fTLVConfigMethods ConfigMethods;
+	tDot11fTLVRFBands   RFBands;
+	tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscProbeRes;
+
+#define DOT11F_EID_WSCPROBERES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCPROBERES_MIN_LEN (4)
+
+#define DOT11F_IE_WSCPROBERES_MAX_LEN (317)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wsc_probe_res(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWscProbeRes*,
+	bool);
+
+uint32_t dot11f_pack_ie_wsc_probe_res(
+	tpAniSirGlobal,
+	tDot11fIEWscProbeRes *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_probe_res(
+	tpAniSirGlobal,
+	tDot11fIEWscProbeRes *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscReassocRes {
+	uint8_t             present;
+	tDot11fTLVVersion   Version;
+	tDot11fTLVResponseType ResponseType;
+	tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscReassocRes;
+
+#define DOT11F_EID_WSCREASSOCRES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCREASSOCRES_MIN_LEN (4)
+
+#define DOT11F_IE_WSCREASSOCRES_MAX_LEN (35)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_wsc_reassoc_res(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEWscReassocRes*,
+	bool);
+
+uint32_t dot11f_pack_ie_wsc_reassoc_res(
+	tpAniSirGlobal,
+	tDot11fIEWscReassocRes *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_reassoc_res(
+	tpAniSirGlobal,
+	tDot11fIEWscReassocRes *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 159 (0x9f) */
+typedef struct sDot11fIEaddba_extn_element {
+	uint8_t             present;
+	uint8_t     no_fragmentation:1;
+	uint8_t    he_frag_operation:2;
+	uint8_t             reserved:5;
+} tDot11fIEaddba_extn_element;
+
+#define DOT11F_EID_ADDBA_EXTN_ELEMENT (159)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ADDBA_EXTN_ELEMENT_MIN_LEN (1)
+
+#define DOT11F_IE_ADDBA_EXTN_ELEMENT_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_addba_extn_element(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEaddba_extn_element*,
+	bool);
+
+uint32_t dot11f_pack_ie_addba_extn_element(
+	tpAniSirGlobal,
+	tDot11fIEaddba_extn_element *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_addba_extn_element(
+	tpAniSirGlobal,
+	tDot11fIEaddba_extn_element *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 42 (0x2a) */
+typedef struct sDot11fIEbss_color_change {
+	uint8_t             present;
+	uint8_t             countdown;
+	uint8_t            new_color:6;
+	uint8_t             reserved:2;
+} tDot11fIEbss_color_change;
+
+#define DOT11F_EID_BSS_COLOR_CHANGE (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_BSS_COLOR_CHANGE_MIN_LEN (2)
+
+#define DOT11F_IE_BSS_COLOR_CHANGE_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_bss_color_change(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEbss_color_change*,
+	bool);
+
+uint32_t dot11f_pack_ie_bss_color_change(
+	tpAniSirGlobal,
+	tDot11fIEbss_color_change *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_bss_color_change(
+	tpAniSirGlobal,
+	tDot11fIEbss_color_change *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 32 (0x20) */
+typedef struct sDot11fIEdh_parameter_element {
+	uint8_t             present;
+	uint8_t             group[2];
+	uint8_t             num_public_key;
+	uint8_t             public_key[255];
+} tDot11fIEdh_parameter_element;
+
+#define DOT11F_EID_DH_PARAMETER_ELEMENT (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_DH_PARAMETER_ELEMENT_MIN_LEN (2)
+
+#define DOT11F_IE_DH_PARAMETER_ELEMENT_MAX_LEN (257)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_dh_parameter_element(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEdh_parameter_element*,
+	bool);
+
+uint32_t dot11f_pack_ie_dh_parameter_element(
+	tpAniSirGlobal,
+	tDot11fIEdh_parameter_element *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_dh_parameter_element(
+	tpAniSirGlobal,
+	tDot11fIEdh_parameter_element *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 11 (0x0b) */
+typedef struct sDot11fIEesp_information {
+	uint8_t             present;
+	uint8_t             num_data;
+	uint8_t             data[96];
+} tDot11fIEesp_information;
+
+#define DOT11F_EID_ESP_INFORMATION (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESP_INFORMATION_MIN_LEN (0)
+
+#define DOT11F_IE_ESP_INFORMATION_MAX_LEN (96)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_esp_information(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEesp_information*,
+	bool);
+
+uint32_t dot11f_pack_ie_esp_information(
+	tpAniSirGlobal,
+	tDot11fIEesp_information *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_esp_information(
+	tpAniSirGlobal,
+	tDot11fIEesp_information *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 60 (0x3c) */
+typedef struct sDot11fIEext_chan_switch_ann {
+	uint8_t             present;
+	uint8_t             switch_mode;
+	uint8_t             new_reg_class;
+	uint8_t             new_channel;
+	uint8_t             switch_count;
+} tDot11fIEext_chan_switch_ann;
+
+#define DOT11F_EID_EXT_CHAN_SWITCH_ANN (60)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_EXT_CHAN_SWITCH_ANN_MIN_LEN (4)
+
+#define DOT11F_IE_EXT_CHAN_SWITCH_ANN_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ext_chan_switch_ann(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEext_chan_switch_ann*,
+	bool);
+
+uint32_t dot11f_pack_ie_ext_chan_switch_ann(
+	tpAniSirGlobal,
+	tDot11fIEext_chan_switch_ann *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ext_chan_switch_ann(
+	tpAniSirGlobal,
+	tDot11fIEext_chan_switch_ann *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 1 (0x01) */
+typedef struct sDot11fIEfils_assoc_delay_info {
+	uint8_t             present;
+	uint8_t             assoc_delay_info;
+} tDot11fIEfils_assoc_delay_info;
+
+#define DOT11F_EID_FILS_ASSOC_DELAY_INFO (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FILS_ASSOC_DELAY_INFO_MIN_LEN (1)
+
+#define DOT11F_IE_FILS_ASSOC_DELAY_INFO_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fils_assoc_delay_info(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEfils_assoc_delay_info*,
+	bool);
+
+uint32_t dot11f_pack_ie_fils_assoc_delay_info(
+	tpAniSirGlobal,
+	tDot11fIEfils_assoc_delay_info *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_fils_assoc_delay_info(
+	tpAniSirGlobal,
+	tDot11fIEfils_assoc_delay_info *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 5 (0x05) */
+typedef struct sDot11fIEfils_hlp_container {
+	uint8_t             present;
+	uint8_t             dest_mac[6];
+	uint8_t             src_mac[6];
+	uint8_t             num_hlp_packet;
+	uint8_t             hlp_packet[255];
+} tDot11fIEfils_hlp_container;
+
+#define DOT11F_EID_FILS_HLP_CONTAINER (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FILS_HLP_CONTAINER_MIN_LEN (12)
+
+#define DOT11F_IE_FILS_HLP_CONTAINER_MAX_LEN (267)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fils_hlp_container(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEfils_hlp_container*,
+	bool);
+
+uint32_t dot11f_pack_ie_fils_hlp_container(
+	tpAniSirGlobal,
+	tDot11fIEfils_hlp_container *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_fils_hlp_container(
+	tpAniSirGlobal,
+	tDot11fIEfils_hlp_container *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 240 (0xf0) */
+typedef struct sDot11fIEfils_indication {
+	uint8_t             present;
+	uint16_t public_key_identifiers_cnt:3;
+	uint16_t realm_identifiers_cnt:3;
+	uint16_t is_ip_config_supported:1;
+	uint16_t  is_cache_id_present:1;
+	uint16_t    is_hessid_present:1;
+	uint16_t is_fils_sk_auth_supported:1;
+	uint16_t is_fils_sk_auth_pfs_supported:1;
+	uint16_t is_pk_auth_supported:1;
+	uint16_t             reserved:4;
+	uint8_t             num_variable_data;
+	uint8_t             variable_data[255];
+} tDot11fIEfils_indication;
+
+#define DOT11F_EID_FILS_INDICATION (240)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FILS_INDICATION_MIN_LEN (4)
+
+#define DOT11F_IE_FILS_INDICATION_MAX_LEN (257)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fils_indication(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEfils_indication*,
+	bool);
+
+uint32_t dot11f_pack_ie_fils_indication(
+	tpAniSirGlobal,
+	tDot11fIEfils_indication *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_fils_indication(
+	tpAniSirGlobal,
+	tDot11fIEfils_indication *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 7 (0x07) */
+typedef struct sDot11fIEfils_kde {
+	uint8_t             present;
+	uint8_t             key_rsc[8];
+	uint8_t             num_kde_list;
+	uint8_t             kde_list[255];
+} tDot11fIEfils_kde;
+
+#define DOT11F_EID_FILS_KDE (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FILS_KDE_MIN_LEN (8)
+
+#define DOT11F_IE_FILS_KDE_MAX_LEN (263)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fils_kde(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEfils_kde*,
+	bool);
+
+uint32_t dot11f_pack_ie_fils_kde(
+	tpAniSirGlobal,
+	tDot11fIEfils_kde *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_fils_kde(
+	tpAniSirGlobal,
+	tDot11fIEfils_kde *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 3 (0x03) */
+typedef struct sDot11fIEfils_key_confirmation {
+	uint8_t             present;
+	uint8_t             num_key_auth;
+	uint8_t             key_auth[255];
+} tDot11fIEfils_key_confirmation;
+
+#define DOT11F_EID_FILS_KEY_CONFIRMATION (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FILS_KEY_CONFIRMATION_MIN_LEN (0)
+
+#define DOT11F_IE_FILS_KEY_CONFIRMATION_MAX_LEN (255)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fils_key_confirmation(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEfils_key_confirmation*,
+	bool);
+
+uint32_t dot11f_pack_ie_fils_key_confirmation(
+	tpAniSirGlobal,
+	tDot11fIEfils_key_confirmation *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_fils_key_confirmation(
+	tpAniSirGlobal,
+	tDot11fIEfils_key_confirmation *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 13 (0x0d) */
+typedef struct sDot11fIEfils_nonce {
+	uint8_t             present;
+	uint8_t             nonce[16];
+} tDot11fIEfils_nonce;
+
+#define DOT11F_EID_FILS_NONCE (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FILS_NONCE_MIN_LEN (16)
+
+#define DOT11F_IE_FILS_NONCE_MAX_LEN (16)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fils_nonce(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEfils_nonce*,
+	bool);
+
+uint32_t dot11f_pack_ie_fils_nonce(
+	tpAniSirGlobal,
+	tDot11fIEfils_nonce *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_fils_nonce(
+	tpAniSirGlobal,
+	tDot11fIEfils_nonce *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 12 (0x0c) */
+typedef struct sDot11fIEfils_public_key {
+	uint8_t             present;
+	uint8_t             key_type;
+	uint8_t             num_public_key;
+	uint8_t             public_key[255];
+} tDot11fIEfils_public_key;
+
+#define DOT11F_EID_FILS_PUBLIC_KEY (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FILS_PUBLIC_KEY_MIN_LEN (1)
+
+#define DOT11F_IE_FILS_PUBLIC_KEY_MAX_LEN (256)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fils_public_key(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEfils_public_key*,
+	bool);
+
+uint32_t dot11f_pack_ie_fils_public_key(
+	tpAniSirGlobal,
+	tDot11fIEfils_public_key *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_fils_public_key(
+	tpAniSirGlobal,
+	tDot11fIEfils_public_key *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 4 (0x04) */
+typedef struct sDot11fIEfils_session {
+	uint8_t             present;
+	uint8_t             session[8];
+} tDot11fIEfils_session;
+
+#define DOT11F_EID_FILS_SESSION (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FILS_SESSION_MIN_LEN (8)
+
+#define DOT11F_IE_FILS_SESSION_MAX_LEN (8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fils_session(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEfils_session*,
+	bool);
+
+uint32_t dot11f_pack_ie_fils_session(
+	tpAniSirGlobal,
+	tDot11fIEfils_session *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_fils_session(
+	tpAniSirGlobal,
+	tDot11fIEfils_session *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 8 (0x08) */
+typedef struct sDot11fIEfils_wrapped_data {
+	uint8_t             present;
+	uint8_t             num_wrapped_data;
+	uint8_t             wrapped_data[255];
+} tDot11fIEfils_wrapped_data;
+
+#define DOT11F_EID_FILS_WRAPPED_DATA (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FILS_WRAPPED_DATA_MIN_LEN (0)
+
+#define DOT11F_IE_FILS_WRAPPED_DATA_MAX_LEN (255)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fils_wrapped_data(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEfils_wrapped_data*,
+	bool);
+
+uint32_t dot11f_pack_ie_fils_wrapped_data(
+	tpAniSirGlobal,
+	tDot11fIEfils_wrapped_data *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_fils_wrapped_data(
+	tpAniSirGlobal,
+	tDot11fIEfils_wrapped_data *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 242 (0xf2) */
+typedef struct sDot11fIEfragment_ie {
+	uint8_t             present;
+	uint8_t             num_data;
+	uint8_t             data[255];
+} tDot11fIEfragment_ie;
+
+#define DOT11F_EID_FRAGMENT_IE (242)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FRAGMENT_IE_MIN_LEN (0)
+
+#define DOT11F_IE_FRAGMENT_IE_MAX_LEN (255)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_fragment_ie(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEfragment_ie*,
+	bool);
+
+uint32_t dot11f_pack_ie_fragment_ie(
+	tpAniSirGlobal,
+	tDot11fIEfragment_ie *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_fragment_ie(
+	tpAniSirGlobal,
+	tDot11fIEfragment_ie *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 35 (0x23) */
+typedef struct sDot11fIEhe_cap {
+	uint8_t             present;
+	uint32_t               htc_he:1;
+	uint32_t          twt_request:1;
+	uint32_t        twt_responder:1;
+	uint32_t        fragmentation:2;
+	uint32_t max_num_frag_msdu_amsdu_exp:3;
+	uint32_t        min_frag_size:2;
+	uint32_t  trigger_frm_mac_pad:2;
+	uint32_t multi_tid_aggr_rx_supp:3;
+	uint32_t   he_link_adaptation:2;
+	uint32_t              all_ack:1;
+	uint32_t      trigd_rsp_sched:1;
+	uint32_t                a_bsr:1;
+	uint32_t        broadcast_twt:1;
+	uint32_t      ba_32bit_bitmap:1;
+	uint32_t           mu_cascade:1;
+	uint32_t ack_enabled_multitid:1;
+	uint32_t             reserved:1;
+	uint32_t           omi_a_ctrl:1;
+	uint32_t             ofdma_ra:1;
+	uint32_t max_ampdu_len_exp_ext:2;
+	uint32_t           amsdu_frag:1;
+	uint32_t       flex_twt_sched:1;
+	uint32_t        rx_ctrl_frame:1;
+	uint16_t      bsrp_ampdu_aggr:1;
+	uint16_t                  qtp:1;
+	uint16_t                a_bqr:1;
+	uint16_t spatial_reuse_param_rspder:1;
+	uint16_t    ndp_feedback_supp:1;
+	uint16_t             ops_supp:1;
+	uint16_t       amsdu_in_ampdu:1;
+	uint16_t multi_tid_aggr_tx_supp:3;
+	uint16_t he_sub_ch_sel_tx_supp:1;
+	uint16_t ul_2x996_tone_ru_supp:1;
+	uint16_t om_ctrl_ul_mu_data_dis_rx:1;
+	uint16_t            reserved1:3;
+	uint32_t            reserved2:1;
+	uint32_t         chan_width_0:1;
+	uint32_t         chan_width_1:1;
+	uint32_t         chan_width_2:1;
+	uint32_t         chan_width_3:1;
+	uint32_t         chan_width_4:1;
+	uint32_t         chan_width_5:1;
+	uint32_t         chan_width_6:1;
+	uint32_t  rx_pream_puncturing:4;
+	uint32_t         device_class:1;
+	uint32_t          ldpc_coding:1;
+	uint32_t he_1x_ltf_800_gi_ppdu:1;
+	uint32_t midamble_tx_rx_max_nsts:2;
+	uint32_t he_4x_ltf_3200_gi_ndp:1;
+	uint32_t     tx_stbc_lt_80mhz:1;
+	uint32_t     rx_stbc_lt_80mhz:1;
+	uint32_t              doppler:2;
+	uint32_t                ul_mu:2;
+	uint32_t           dcm_enc_tx:3;
+	uint32_t           dcm_enc_rx:3;
+	uint32_t             ul_he_mu:1;
+	uint32_t        su_beamformer:1;
+	uint32_t        su_beamformee:1;
+	uint32_t        mu_beamformer:1;
+	uint32_t       bfee_sts_lt_80:3;
+	uint32_t       bfee_sts_gt_80:3;
+	uint32_t   num_sounding_lt_80:3;
+	uint32_t   num_sounding_gt_80:3;
+	uint32_t   su_feedback_tone16:1;
+	uint32_t   mu_feedback_tone16:1;
+	uint32_t          codebook_su:1;
+	uint32_t          codebook_mu:1;
+	uint32_t beamforming_feedback:3;
+	uint32_t        he_er_su_ppdu:1;
+	uint32_t   dl_mu_mimo_part_bw:1;
+	uint32_t         ppet_present:1;
+	uint32_t                  srp:1;
+	uint32_t          power_boost:1;
+	uint32_t     he_ltf_800_gi_4x:1;
+	uint32_t               max_nc:3;
+	uint32_t     tx_stbc_gt_80mhz:1;
+	uint32_t     rx_stbc_gt_80mhz:1;
+	uint16_t  er_he_ltf_800_gi_4x:1;
+	uint16_t he_ppdu_20_in_40Mhz_2G:1;
+	uint16_t he_ppdu_20_in_160_80p80Mhz:1;
+	uint16_t he_ppdu_80_in_160_80p80Mhz:1;
+	uint16_t      er_1x_he_ltf_gi:1;
+	uint16_t midamble_tx_rx_1x_he_ltf:1;
+	uint16_t           dcm_max_bw:2;
+	uint16_t longer_than_16_he_sigb_ofdm_sym:1;
+	uint16_t non_trig_cqi_feedback:1;
+	uint16_t tx_1024_qam_lt_242_tone_ru:1;
+	uint16_t rx_1024_qam_lt_242_tone_ru:1;
+	uint16_t rx_full_bw_su_he_mu_compress_sigb:1;
+	uint16_t rx_full_bw_su_he_mu_non_cmpr_sigb:1;
+	uint16_t            reserved3:2;
+	uint8_t             reserved4;
+	uint16_t            rx_he_mcs_map_lt_80;
+	uint16_t            tx_he_mcs_map_lt_80;
+	uint8_t             rx_he_mcs_map_160[1][2];
+	uint8_t             tx_he_mcs_map_160[1][2];
+	uint8_t             rx_he_mcs_map_80_80[1][2];
+	uint8_t             tx_he_mcs_map_80_80[1][2];
+	union {
+		struct {
+			uint8_t num_ppe_th;
+			uint8_t ppe_th[25];
+		} ppe_threshold; /* ppet_present = 1 */
+	} ppet;
+} tDot11fIEhe_cap;
+
+#define DOT11F_EID_HE_CAP (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HE_CAP_MIN_LEN (21)
+
+#define DOT11F_IE_HE_CAP_MAX_LEN (54)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_he_cap(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEhe_cap*,
+	bool);
+
+uint32_t dot11f_pack_ie_he_cap(
+	tpAniSirGlobal,
+	tDot11fIEhe_cap *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_he_cap(
+	tpAniSirGlobal,
+	tDot11fIEhe_cap *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 36 (0x24) */
+typedef struct sDot11fIEhe_op {
+	uint8_t             present;
+	uint16_t           default_pe:3;
+	uint16_t         twt_required:1;
+	uint16_t   txop_rts_threshold:10;
+	uint16_t     vht_oper_present:1;
+	uint16_t       co_located_bss:1;
+	uint8_t        er_su_disable:1;
+	uint8_t            reserved2:7;
+	uint8_t            bss_color:6;
+	uint8_t      partial_bss_col:1;
+	uint8_t     bss_col_disabled:1;
+	uint8_t             basic_mcs_nss[2];
+	union {
+		struct {
+			uint8_t chan_width;
+			uint8_t center_freq_seg0;
+			uint8_t center_freq_seg1;
+		} info; /* vht_oper_present = 1 */
+	} vht_oper;
+	union {
+		struct {
+			uint8_t data;
+		} info; /* co_located_bss = 1 */
+	} maxbssid_ind;
+} tDot11fIEhe_op;
+
+#define DOT11F_EID_HE_OP (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HE_OP_MIN_LEN (6)
+
+#define DOT11F_IE_HE_OP_MAX_LEN (10)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_he_op(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEhe_op*,
+	bool);
+
+uint32_t dot11f_pack_ie_he_op(
+	tpAniSirGlobal,
+	tDot11fIEhe_op *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_he_op(
+	tpAniSirGlobal,
+	tDot11fIEhe_op *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x10} */
+typedef struct sDot11fIEhs20vendor_ie {
+	uint8_t             present;
+	uint8_t             dgaf_dis:1;
+	uint8_t        hs_id_present:2;
+	uint8_t             reserved:1;
+	uint8_t          release_num:4;
+	union {
+		struct {
+			uint16_t pps_mo_id;
+		} pps_mo; /* hs_id_present = 1 */
+		struct {
+			uint16_t anqp_domain_id;
+		} anqp_domain; /* hs_id_present = 2 */
+	} hs_id;
+} tDot11fIEhs20vendor_ie;
+
+#define DOT11F_EID_HS20VENDOR_IE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HS20VENDOR_IE_MIN_LEN (5)
+
+#define DOT11F_IE_HS20VENDOR_IE_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_hs20vendor_ie(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEhs20vendor_ie*,
+	bool);
+
+uint32_t dot11f_pack_ie_hs20vendor_ie(
+	tpAniSirGlobal,
+	tDot11fIEhs20vendor_ie *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_hs20vendor_ie(
+	tpAniSirGlobal,
+	tDot11fIEhs20vendor_ie *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 72 (0x48) */
+typedef struct sDot11fIEht2040_bss_coexistence {
+	uint8_t             present;
+	uint8_t         info_request:1;
+	uint8_t forty_mhz_intolerant:1;
+	uint8_t twenty_mhz_bsswidth_req:1;
+	uint8_t obss_scan_exemption_req:1;
+	uint8_t obss_scan_exemption_grant:1;
+	uint8_t               unused:3;
+} tDot11fIEht2040_bss_coexistence;
+
+#define DOT11F_EID_HT2040_BSS_COEXISTENCE (72)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HT2040_BSS_COEXISTENCE_MIN_LEN (1)
+
+#define DOT11F_IE_HT2040_BSS_COEXISTENCE_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ht2040_bss_coexistence(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEht2040_bss_coexistence*,
+	bool);
+
+uint32_t dot11f_pack_ie_ht2040_bss_coexistence(
+	tpAniSirGlobal,
+	tDot11fIEht2040_bss_coexistence *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ht2040_bss_coexistence(
+	tpAniSirGlobal,
+	tDot11fIEht2040_bss_coexistence *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 73 (0x49) */
+typedef struct sDot11fIEht2040_bss_intolerant_report {
+	uint8_t             present;
+	uint8_t             operating_class;
+	uint8_t             num_channel_list;
+	uint8_t             channel_list[50];
+} tDot11fIEht2040_bss_intolerant_report;
+
+#define DOT11F_EID_HT2040_BSS_INTOLERANT_REPORT (73)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HT2040_BSS_INTOLERANT_REPORT_MIN_LEN (1)
+
+#define DOT11F_IE_HT2040_BSS_INTOLERANT_REPORT_MAX_LEN (51)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_ht2040_bss_intolerant_report(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEht2040_bss_intolerant_report*,
+	bool);
+
+uint32_t dot11f_pack_ie_ht2040_bss_intolerant_report(
+	tpAniSirGlobal,
+	tDot11fIEht2040_bss_intolerant_report *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ht2040_bss_intolerant_report(
+	tpAniSirGlobal,
+	tDot11fIEht2040_bss_intolerant_report *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 255 (0xff) Extended EID 38 (0x26) */
+typedef struct sDot11fIEmu_edca_param_set {
+	uint8_t             present;
+	uint8_t             qos;
+	uint8_t           acbe_aifsn:4;
+	uint8_t             acbe_acm:1;
+	uint8_t             acbe_aci:2;
+	uint8_t              unused1:1;
+	uint8_t          acbe_acwmin:4;
+	uint8_t          acbe_acwmax:4;
+	uint8_t             acbe_muedca_timer;
+	uint8_t           acbk_aifsn:4;
+	uint8_t             acbk_acm:1;
+	uint8_t             acbk_aci:2;
+	uint8_t              unused2:1;
+	uint8_t          acbk_acwmin:4;
+	uint8_t          acbk_acwmax:4;
+	uint8_t             acbk_muedca_timer;
+	uint8_t           acvi_aifsn:4;
+	uint8_t             acvi_acm:1;
+	uint8_t             acvi_aci:2;
+	uint8_t              unused3:1;
+	uint8_t          acvi_acwmin:4;
+	uint8_t          acvi_acwmax:4;
+	uint8_t             acvi_muedca_timer;
+	uint8_t           acvo_aifsn:4;
+	uint8_t             acvo_acm:1;
+	uint8_t             acvo_aci:2;
+	uint8_t              unused4:1;
+	uint8_t          acvo_acwmin:4;
+	uint8_t          acvo_acwmax:4;
+	uint8_t             acvo_muedca_timer;
+} tDot11fIEmu_edca_param_set;
+
+#define DOT11F_EID_MU_EDCA_PARAM_SET (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MU_EDCA_PARAM_SET_MIN_LEN (13)
+
+#define DOT11F_IE_MU_EDCA_PARAM_SET_MAX_LEN (13)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_mu_edca_param_set(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEmu_edca_param_set*,
+	bool);
+
+uint32_t dot11f_pack_ie_mu_edca_param_set(
+	tpAniSirGlobal,
+	tDot11fIEmu_edca_param_set *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_mu_edca_param_set(
+	tpAniSirGlobal,
+	tDot11fIEmu_edca_param_set *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x12} */
+typedef struct sDot11fIEosen_ie {
+	uint8_t             present;
+	uint8_t             num_data;
+	uint8_t             data[255];
+} tDot11fIEosen_ie;
+
+#define DOT11F_EID_OSEN_IE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_OSEN_IE_MIN_LEN (4)
+
+#define DOT11F_IE_OSEN_IE_MAX_LEN (259)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_osen_ie(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEosen_ie*,
+	bool);
+
+uint32_t dot11f_pack_ie_osen_ie(
+	tpAniSirGlobal,
+	tDot11fIEosen_ie *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_osen_ie(
+	tpAniSirGlobal,
+	tDot11fIEosen_ie *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 62 (0x3e) */
+typedef struct sDot11fIEsec_chan_offset_ele {
+	uint8_t             present;
+	uint8_t             secondaryChannelOffset;
+} tDot11fIEsec_chan_offset_ele;
+
+#define DOT11F_EID_SEC_CHAN_OFFSET_ELE (62)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SEC_CHAN_OFFSET_ELE_MIN_LEN (1)
+
+#define DOT11F_IE_SEC_CHAN_OFFSET_ELE_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_sec_chan_offset_ele(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEsec_chan_offset_ele*,
+	bool);
+
+uint32_t dot11f_pack_ie_sec_chan_offset_ele(
+	tpAniSirGlobal,
+	tDot11fIEsec_chan_offset_ele *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_sec_chan_offset_ele(
+	tpAniSirGlobal,
+	tDot11fIEsec_chan_offset_ele *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x90, 0x4c, 0x04} */
+typedef struct sDot11fIEvendor_vht_ie {
+	uint8_t                      present;
+	uint8_t                      sub_type;
+	tDot11fIEVHTCaps             VHTCaps;
+	tDot11fIEVHTOperation        VHTOperation;
+} tDot11fIEvendor_vht_ie;
+
+#define DOT11F_EID_VENDOR_VHT_IE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VENDOR_VHT_IE_MIN_LEN (5)
+
+#define DOT11F_IE_VENDOR_VHT_IE_MAX_LEN (26)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_vendor_vht_ie(
+	tpAniSirGlobal,
+	uint8_t *,
+	uint8_t,
+	tDot11fIEvendor_vht_ie*,
+	bool);
+
+uint32_t dot11f_pack_ie_vendor_vht_ie(
+	tpAniSirGlobal,
+	tDot11fIEvendor_vht_ie *,
+	uint8_t *,
+	uint32_t,
+	uint32_t*);
+
+uint32_t dot11f_get_packed_ie_vendor_vht_ie(
+	tpAniSirGlobal,
+	tDot11fIEvendor_vht_ie *,
+	uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+/************************************************************************
+ * Frames
+ **********************************************************************/
+
+typedef struct sDot11fAddTSRequest{
+	tDot11fFfCategory                  Category;
+	tDot11fFfAction                    Action;
+	tDot11fFfDialogToken               DialogToken;
+	tDot11fIETSPEC                     TSPEC;
+	uint16_t                           num_TCLAS;
+	tDot11fIETCLAS                     TCLAS[2];
+	tDot11fIETCLASSPROC                TCLASSPROC;
+	tDot11fIEWMMTSPEC                  WMMTSPEC;
+	uint16_t                           num_WMMTCLAS;
+	tDot11fIEWMMTCLAS                  WMMTCLAS[2];
+	tDot11fIEWMMTCLASPROC              WMMTCLASPROC;
+	tDot11fIEESETrafStrmRateSet        ESETrafStrmRateSet;
+} tDot11fAddTSRequest;
+
+#define DOT11F_ADDTSREQUEST (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_add_ts_request(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fAddTSRequest * pFrm, bool append_ie);
+uint32_t dot11f_pack_add_ts_request(tpAniSirGlobal pCtx,
+	tDot11fAddTSRequest *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_add_ts_request_size(tpAniSirGlobal pCtx,
+	tDot11fAddTSRequest *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fAddTSResponse{
+	tDot11fFfCategory              Category;
+	tDot11fFfAction                Action;
+	tDot11fFfDialogToken           DialogToken;
+	tDot11fFfStatus                Status;
+	tDot11fIETSDelay               TSDelay;
+	tDot11fIETSPEC                 TSPEC;
+	uint16_t                       num_TCLAS;
+	tDot11fIETCLAS                 TCLAS[2];
+	tDot11fIETCLASSPROC            TCLASSPROC;
+	tDot11fIESchedule              Schedule;
+	tDot11fIEWMMTSDelay            WMMTSDelay;
+	tDot11fIEWMMSchedule           WMMSchedule;
+	tDot11fIEWMMTSPEC              WMMTSPEC;
+	uint16_t                       num_WMMTCLAS;
+	tDot11fIEWMMTCLAS              WMMTCLAS[2];
+	tDot11fIEWMMTCLASPROC          WMMTCLASPROC;
+	tDot11fIEESETrafStrmMet        ESETrafStrmMet;
+} tDot11fAddTSResponse;
+
+#define DOT11F_ADDTSRESPONSE (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_add_ts_response(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fAddTSResponse * pFrm, bool append_ie);
+uint32_t dot11f_pack_add_ts_response(tpAniSirGlobal pCtx,
+	tDot11fAddTSResponse *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_add_ts_response_size(tpAniSirGlobal pCtx,
+	tDot11fAddTSResponse *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fAssocRequest{
+	tDot11fFfCapabilities                 Capabilities;
+	tDot11fFfListenInterval               ListenInterval;
+	tDot11fIESSID                         SSID;
+	tDot11fIESuppRates                    SuppRates;
+	tDot11fIEOperatingMode                OperatingMode;
+	tDot11fIEPowerCaps                    PowerCaps;
+	tDot11fIESuppChannels                 SuppChannels;
+	tDot11fIEHTCaps                       HTCaps;
+	tDot11fIEQOSCapsStation               QOSCapsStation;
+	tDot11fIERSNOpaque                    RSNOpaque;
+	tDot11fIEExtSuppRates                 ExtSuppRates;
+	tDot11fIEMobilityDomain               MobilityDomain;
+	tDot11fIESuppOperatingClasses         SuppOperatingClasses;
+	tDot11fIEWAPIOpaque                   WAPIOpaque;
+	tDot11fIEWAPI                         WAPI;
+	tDot11fIERRMEnabledCap                RRMEnabledCap;
+	tDot11fIEQosMapSet                    QosMapSet;
+	tDot11fIEExtCap                       ExtCap;
+	tDot11fIEVHTCaps                      VHTCaps;
+	tDot11fIEfils_session                 fils_session;
+	tDot11fIEfils_public_key              fils_public_key;
+	tDot11fIEfils_key_confirmation        fils_key_confirmation;
+	tDot11fIEfils_hlp_container           fils_hlp_container;
+	tDot11fIEfragment_ie                  fragment_ie;
+	tDot11fIEdh_parameter_element         dh_parameter_element;
+	tDot11fIEWPAOpaque                    WPAOpaque;
+	tDot11fIEWMMCaps                      WMMCaps;
+	tDot11fIEWMMInfoStation               WMMInfoStation;
+	tDot11fIEWscIEOpaque                  WscIEOpaque;
+	tDot11fIEESERadMgmtCap                ESERadMgmtCap;
+	tDot11fIEESEVersion                   ESEVersion;
+	tDot11fIEP2PIEOpaque                  P2PIEOpaque;
+	tDot11fIEWFDIEOpaque                  WFDIEOpaque;
+	tDot11fIEvendor_vht_ie                vendor_vht_ie;
+	tDot11fIEhs20vendor_ie                hs20vendor_ie;
+	tDot11fIEQCN_IE                       QCN_IE;
+	tDot11fIEhe_cap                       he_cap;
+	tDot11fIEosen_ie                      osen_ie;
+} tDot11fAssocRequest;
+
+#define DOT11F_ASSOCREQUEST (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_assoc_request(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fAssocRequest * pFrm, bool append_ie);
+uint32_t dot11f_pack_assoc_request(tpAniSirGlobal pCtx,
+	tDot11fAssocRequest *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_assoc_request_size(tpAniSirGlobal pCtx,
+	tDot11fAssocRequest *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fAssocResponse{
+	tDot11fFfCapabilities                 Capabilities;
+	tDot11fFfStatus                       Status;
+	tDot11fFfAID                          AID;
+	tDot11fIESuppRates                    SuppRates;
+	tDot11fIEExtSuppRates                 ExtSuppRates;
+	tDot11fIEEDCAParamSet                 EDCAParamSet;
+	tDot11fIERCPIIE                       RCPIIE;
+	tDot11fIERSNIIE                       RSNIIE;
+	tDot11fIERRMEnabledCap                RRMEnabledCap;
+	tDot11fIEMobilityDomain               MobilityDomain;
+	tDot11fIEFTInfo                       FTInfo;
+	uint16_t                              num_RICDataDesc;
+	tDot11fIERICDataDesc                  RICDataDesc[2];
+	tDot11fIEWPA                          WPA;
+	tDot11fIETimeoutInterval              TimeoutInterval;
+	tDot11fIEHTCaps                       HTCaps;
+	tDot11fIEHTInfo                       HTInfo;
+	tDot11fIEWMMParams                    WMMParams;
+	tDot11fIEWMMCaps                      WMMCaps;
+	tDot11fIEESERadMgmtCap                ESERadMgmtCap;
+	tDot11fIEESETrafStrmMet               ESETrafStrmMet;
+	tDot11fIEESETxmitPower                ESETxmitPower;
+	uint16_t                              num_WMMTSPEC;
+	tDot11fIEWMMTSPEC                     WMMTSPEC[4];
+	tDot11fIEWscAssocRes                  WscAssocRes;
+	tDot11fIEP2PAssocRes                  P2PAssocRes;
+	tDot11fIEVHTCaps                      VHTCaps;
+	tDot11fIEVHTOperation                 VHTOperation;
+	tDot11fIEExtCap                       ExtCap;
+	tDot11fIEOBSSScanParameters           OBSSScanParameters;
+	tDot11fIEQosMapSet                    QosMapSet;
+	tDot11fIEfils_session                 fils_session;
+	tDot11fIEfils_public_key              fils_public_key;
+	tDot11fIEfils_key_confirmation        fils_key_confirmation;
+	tDot11fIEfils_hlp_container           fils_hlp_container;
+	tDot11fIEfragment_ie                  fragment_ie;
+	tDot11fIEfils_kde                     fils_kde;
+	tDot11fIEvendor_vht_ie                vendor_vht_ie;
+	tDot11fIEQCN_IE                       QCN_IE;
+	tDot11fIEhe_cap                       he_cap;
+	tDot11fIEhe_op                        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)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_assoc_response(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fAssocResponse * pFrm, bool append_ie);
+uint32_t dot11f_pack_assoc_response(tpAniSirGlobal pCtx,
+	tDot11fAssocResponse *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_assoc_response_size(tpAniSirGlobal pCtx,
+	tDot11fAssocResponse *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fAuthentication{
+	tDot11fFfAuthAlgo                     AuthAlgo;
+	tDot11fFfAuthSeqNo                    AuthSeqNo;
+	tDot11fFfStatus                       Status;
+	tDot11fIEChallengeText                ChallengeText;
+	tDot11fIERSNOpaque                    RSNOpaque;
+	tDot11fIEMobilityDomain               MobilityDomain;
+	tDot11fIEFTInfo                       FTInfo;
+	tDot11fIETimeoutInterval              TimeoutInterval;
+	uint16_t                              num_RICDataDesc;
+	tDot11fIERICDataDesc                  RICDataDesc[2];
+	tDot11fIEfils_nonce                   fils_nonce;
+	tDot11fIEfils_session                 fils_session;
+	tDot11fIEfils_wrapped_data            fils_wrapped_data;
+	tDot11fIEfils_assoc_delay_info        fils_assoc_delay_info;
+} tDot11fAuthentication;
+
+#define DOT11F_AUTHENTICATION (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_authentication(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fAuthentication * pFrm, bool append_ie);
+uint32_t dot11f_pack_authentication(tpAniSirGlobal pCtx,
+	tDot11fAuthentication *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_authentication_size(tpAniSirGlobal pCtx,
+	tDot11fAuthentication *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fBeacon{
+	tDot11fFfTimeStamp                   TimeStamp;
+	tDot11fFfBeaconInterval              BeaconInterval;
+	tDot11fFfCapabilities                Capabilities;
+	tDot11fIESSID                        SSID;
+	tDot11fIESuppRates                   SuppRates;
+	tDot11fIEFHParamSet                  FHParamSet;
+	tDot11fIEDSParams                    DSParams;
+	tDot11fIECFParams                    CFParams;
+	tDot11fIEIBSSParams                  IBSSParams;
+	tDot11fIETIM                         TIM;
+	tDot11fIECountry                     Country;
+	tDot11fIEFHParams                    FHParams;
+	tDot11fIEFHPattTable                 FHPattTable;
+	tDot11fIEPowerConstraints            PowerConstraints;
+	tDot11fIEChanSwitchAnn               ChanSwitchAnn;
+	tDot11fIEext_chan_switch_ann         ext_chan_switch_ann;
+	tDot11fIESuppOperatingClasses        SuppOperatingClasses;
+	tDot11fIEQuiet                       Quiet;
+	tDot11fIETPCReport                   TPCReport;
+	tDot11fIEERPInfo                     ERPInfo;
+	tDot11fIEExtSuppRates                ExtSuppRates;
+	tDot11fIERSN                         RSN;
+	tDot11fIEQBSSLoad                    QBSSLoad;
+	tDot11fIEEDCAParamSet                EDCAParamSet;
+	tDot11fIEQOSCapsAp                   QOSCapsAp;
+	tDot11fIEAPChannelReport             APChannelReport;
+	tDot11fIERRMEnabledCap               RRMEnabledCap;
+	tDot11fIEMobilityDomain              MobilityDomain;
+	tDot11fIEWPA                         WPA;
+	tDot11fIEHTCaps                      HTCaps;
+	tDot11fIEHTInfo                      HTInfo;
+	tDot11fIEsec_chan_offset_ele         sec_chan_offset_ele;
+	tDot11fIEWMMInfoAp                   WMMInfoAp;
+	tDot11fIEWMMParams                   WMMParams;
+	tDot11fIEWMMCaps                     WMMCaps;
+	tDot11fIEWAPI                        WAPI;
+	tDot11fIEESERadMgmtCap               ESERadMgmtCap;
+	tDot11fIEESETrafStrmMet              ESETrafStrmMet;
+	tDot11fIEESETxmitPower               ESETxmitPower;
+	tDot11fIEWscBeacon                   WscBeacon;
+	tDot11fIEP2PBeacon                   P2PBeacon;
+	tDot11fIEVHTCaps                     VHTCaps;
+	tDot11fIEVHTOperation                VHTOperation;
+	tDot11fIEVHTExtBssLoad               VHTExtBssLoad;
+	tDot11fIEExtCap                      ExtCap;
+	tDot11fIEOperatingMode               OperatingMode;
+	tDot11fIEWiderBWChanSwitchAnn        WiderBWChanSwitchAnn;
+	tDot11fIEOBSSScanParameters          OBSSScanParameters;
+	tDot11fIEfils_indication             fils_indication;
+	tDot11fIEVendor1IE                   Vendor1IE;
+	tDot11fIEvendor_vht_ie               vendor_vht_ie;
+	tDot11fIEVendor3IE                   Vendor3IE;
+	tDot11fIEhs20vendor_ie               hs20vendor_ie;
+	tDot11fIEChannelSwitchWrapper        ChannelSwitchWrapper;
+	tDot11fIEQComVendorIE                QComVendorIE;
+	tDot11fIEESEVersion                  ESEVersion;
+	tDot11fIEMBO_IE                      MBO_IE;
+	tDot11fIEQCN_IE                      QCN_IE;
+	tDot11fIEhe_cap                      he_cap;
+	tDot11fIEhe_op                       he_op;
+	tDot11fIEbss_color_change            bss_color_change;
+	tDot11fIEmu_edca_param_set           mu_edca_param_set;
+	tDot11fIEesp_information             esp_information;
+} tDot11fBeacon;
+
+#define DOT11F_BEACON (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_beacon(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fBeacon * pFrm, bool append_ie);
+uint32_t dot11f_pack_beacon(tpAniSirGlobal pCtx,
+	tDot11fBeacon *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_beacon_size(tpAniSirGlobal pCtx,
+	tDot11fBeacon *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fBeacon1{
+	tDot11fFfTimeStamp             TimeStamp;
+	tDot11fFfBeaconInterval        BeaconInterval;
+	tDot11fFfCapabilities          Capabilities;
+	tDot11fIESSID                  SSID;
+	tDot11fIESuppRates             SuppRates;
+	tDot11fIEDSParams              DSParams;
+	tDot11fIEIBSSParams            IBSSParams;
+} tDot11fBeacon1;
+
+#define DOT11F_BEACON1 (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_beacon1(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fBeacon1 * pFrm, bool append_ie);
+uint32_t dot11f_pack_beacon1(tpAniSirGlobal pCtx,
+	tDot11fBeacon1 *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_beacon1_size(tpAniSirGlobal pCtx,
+	tDot11fBeacon1 *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fBeacon2{
+	tDot11fIECountry                     Country;
+	tDot11fIEPowerConstraints            PowerConstraints;
+	tDot11fIEChanSwitchAnn               ChanSwitchAnn;
+	tDot11fIEext_chan_switch_ann         ext_chan_switch_ann;
+	tDot11fIESuppOperatingClasses        SuppOperatingClasses;
+	tDot11fIEQuiet                       Quiet;
+	tDot11fIETPCReport                   TPCReport;
+	tDot11fIEERPInfo                     ERPInfo;
+	tDot11fIEExtSuppRates                ExtSuppRates;
+	tDot11fIERSNOpaque                   RSNOpaque;
+	tDot11fIEEDCAParamSet                EDCAParamSet;
+	tDot11fIEAPChannelReport             APChannelReport;
+	tDot11fIERRMEnabledCap               RRMEnabledCap;
+	tDot11fIEMobilityDomain              MobilityDomain;
+	tDot11fIEWPA                         WPA;
+	tDot11fIEHTCaps                      HTCaps;
+	tDot11fIEHTInfo                      HTInfo;
+	tDot11fIEsec_chan_offset_ele         sec_chan_offset_ele;
+	tDot11fIEWMMInfoAp                   WMMInfoAp;
+	tDot11fIEWMMParams                   WMMParams;
+	tDot11fIEWMMCaps                     WMMCaps;
+	tDot11fIEWscBeacon                   WscBeacon;
+	tDot11fIEWAPI                        WAPI;
+	tDot11fIEESERadMgmtCap               ESERadMgmtCap;
+	tDot11fIEESETrafStrmMet              ESETrafStrmMet;
+	tDot11fIEESETxmitPower               ESETxmitPower;
+	tDot11fIEP2PBeacon                   P2PBeacon;
+	tDot11fIEVHTCaps                     VHTCaps;
+	tDot11fIEVHTOperation                VHTOperation;
+	tDot11fIEVHTExtBssLoad               VHTExtBssLoad;
+	tDot11fIEExtCap                      ExtCap;
+	tDot11fIEOperatingMode               OperatingMode;
+	tDot11fIEWiderBWChanSwitchAnn        WiderBWChanSwitchAnn;
+	tDot11fIEOBSSScanParameters          OBSSScanParameters;
+	tDot11fIEfils_indication             fils_indication;
+	tDot11fIEVendor1IE                   Vendor1IE;
+	tDot11fIEvendor_vht_ie               vendor_vht_ie;
+	tDot11fIEVendor3IE                   Vendor3IE;
+	tDot11fIEhs20vendor_ie               hs20vendor_ie;
+	tDot11fIEChannelSwitchWrapper        ChannelSwitchWrapper;
+	tDot11fIEQComVendorIE                QComVendorIE;
+	tDot11fIEESEVersion                  ESEVersion;
+	tDot11fIEQCN_IE                      QCN_IE;
+	tDot11fIEhe_cap                      he_cap;
+	tDot11fIEhe_op                       he_op;
+	tDot11fIEbss_color_change            bss_color_change;
+	tDot11fIEmu_edca_param_set           mu_edca_param_set;
+	tDot11fIEesp_information             esp_information;
+} tDot11fBeacon2;
+
+#define DOT11F_BEACON2 (8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_beacon2(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fBeacon2 * pFrm, bool append_ie);
+uint32_t dot11f_pack_beacon2(tpAniSirGlobal pCtx,
+	tDot11fBeacon2 *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_beacon2_size(tpAniSirGlobal pCtx,
+	tDot11fBeacon2 *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fBeaconIEs{
+	tDot11fIESSID                        SSID;
+	tDot11fIESuppRates                   SuppRates;
+	tDot11fIEFHParamSet                  FHParamSet;
+	tDot11fIEDSParams                    DSParams;
+	tDot11fIECFParams                    CFParams;
+	tDot11fIEIBSSParams                  IBSSParams;
+	tDot11fIETIM                         TIM;
+	tDot11fIECountry                     Country;
+	tDot11fIEFHParams                    FHParams;
+	tDot11fIEFHPattTable                 FHPattTable;
+	tDot11fIEPowerConstraints            PowerConstraints;
+	tDot11fIEChanSwitchAnn               ChanSwitchAnn;
+	tDot11fIEext_chan_switch_ann         ext_chan_switch_ann;
+	tDot11fIESuppOperatingClasses        SuppOperatingClasses;
+	tDot11fIEQuiet                       Quiet;
+	tDot11fIETPCReport                   TPCReport;
+	tDot11fIEERPInfo                     ERPInfo;
+	tDot11fIEExtSuppRates                ExtSuppRates;
+	tDot11fIERSN                         RSN;
+	tDot11fIEQBSSLoad                    QBSSLoad;
+	tDot11fIEEDCAParamSet                EDCAParamSet;
+	tDot11fIEQOSCapsAp                   QOSCapsAp;
+	tDot11fIEAPChannelReport             APChannelReport;
+	tDot11fIERRMEnabledCap               RRMEnabledCap;
+	tDot11fIEMobilityDomain              MobilityDomain;
+	tDot11fIEWPA                         WPA;
+	tDot11fIEHTCaps                      HTCaps;
+	tDot11fIEHTInfo                      HTInfo;
+	tDot11fIEsec_chan_offset_ele         sec_chan_offset_ele;
+	tDot11fIEWMMInfoAp                   WMMInfoAp;
+	tDot11fIEWMMParams                   WMMParams;
+	tDot11fIEWMMCaps                     WMMCaps;
+	tDot11fIEWAPI                        WAPI;
+	tDot11fIEESEVersion                  ESEVersion;
+	tDot11fIEESERadMgmtCap               ESERadMgmtCap;
+	tDot11fIEESETrafStrmMet              ESETrafStrmMet;
+	tDot11fIEESETxmitPower               ESETxmitPower;
+	tDot11fIEWscBeaconProbeRes           WscBeaconProbeRes;
+	tDot11fIEP2PBeaconProbeRes           P2PBeaconProbeRes;
+	tDot11fIEVHTCaps                     VHTCaps;
+	tDot11fIEVHTOperation                VHTOperation;
+	tDot11fIEVHTExtBssLoad               VHTExtBssLoad;
+	tDot11fIEExtCap                      ExtCap;
+	tDot11fIEOperatingMode               OperatingMode;
+	tDot11fIEWiderBWChanSwitchAnn        WiderBWChanSwitchAnn;
+	tDot11fIEOBSSScanParameters          OBSSScanParameters;
+	tDot11fIEfils_indication             fils_indication;
+	tDot11fIEVendor1IE                   Vendor1IE;
+	tDot11fIEvendor_vht_ie               vendor_vht_ie;
+	tDot11fIEVendor3IE                   Vendor3IE;
+	tDot11fIEhs20vendor_ie               hs20vendor_ie;
+	tDot11fIEChannelSwitchWrapper        ChannelSwitchWrapper;
+	tDot11fIEQComVendorIE                QComVendorIE;
+	tDot11fIEMBO_IE                      MBO_IE;
+	tDot11fIEQCN_IE                      QCN_IE;
+	tDot11fIEhe_cap                      he_cap;
+	tDot11fIEhe_op                       he_op;
+	tDot11fIEbss_color_change            bss_color_change;
+	tDot11fIEmu_edca_param_set           mu_edca_param_set;
+	tDot11fIEesp_information             esp_information;
+} tDot11fBeaconIEs;
+
+#define DOT11F_BEACONIES (9)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_beacon_i_es(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fBeaconIEs * pFrm, bool append_ie);
+uint32_t dot11f_pack_beacon_i_es(tpAniSirGlobal pCtx,
+	tDot11fBeaconIEs *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_beacon_i_es_size(tpAniSirGlobal pCtx,
+	tDot11fBeaconIEs *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fChannelSwitch{
+	tDot11fFfCategory                    Category;
+	tDot11fFfAction                      Action;
+	tDot11fIEChanSwitchAnn               ChanSwitchAnn;
+	tDot11fIEsec_chan_offset_ele         sec_chan_offset_ele;
+	tDot11fIEWiderBWChanSwitchAnn        WiderBWChanSwitchAnn;
+} tDot11fChannelSwitch;
+
+#define DOT11F_CHANNELSWITCH (10)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_channel_switch(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fChannelSwitch * pFrm, bool append_ie);
+uint32_t dot11f_pack_channel_switch(tpAniSirGlobal pCtx,
+	tDot11fChannelSwitch *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_channel_switch_size(tpAniSirGlobal pCtx,
+	tDot11fChannelSwitch *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fDeAuth{
+	tDot11fFfReason           Reason;
+	tDot11fIEP2PDeAuth        P2PDeAuth;
+} tDot11fDeAuth;
+
+#define DOT11F_DEAUTH (11)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_de_auth(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fDeAuth * pFrm, bool append_ie);
+uint32_t dot11f_pack_de_auth(tpAniSirGlobal pCtx,
+	tDot11fDeAuth *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_de_auth_size(tpAniSirGlobal pCtx,
+	tDot11fDeAuth *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fDelTS{
+	tDot11fFfCategory        Category;
+	tDot11fFfAction          Action;
+	tDot11fFfTSInfo          TSInfo;
+	tDot11fFfReason          Reason;
+} tDot11fDelTS;
+
+#define DOT11F_DELTS (12)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_del_ts(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fDelTS * pFrm, bool append_ie);
+uint32_t dot11f_pack_del_ts(tpAniSirGlobal pCtx,
+	tDot11fDelTS *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_del_ts_size(tpAniSirGlobal pCtx,
+	tDot11fDelTS *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fDisassociation{
+	tDot11fFfReason             Reason;
+	tDot11fIEP2PDisAssoc        P2PDisAssoc;
+} tDot11fDisassociation;
+
+#define DOT11F_DISASSOCIATION (13)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_disassociation(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fDisassociation * pFrm, bool append_ie);
+uint32_t dot11f_pack_disassociation(tpAniSirGlobal pCtx,
+	tDot11fDisassociation *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_disassociation_size(tpAniSirGlobal pCtx,
+	tDot11fDisassociation *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fLinkMeasurementReport{
+	tDot11fFfCategory           Category;
+	tDot11fFfAction             Action;
+	tDot11fFfDialogToken        DialogToken;
+	tDot11fFfTPCEleID           TPCEleID;
+	tDot11fFfTPCEleLen          TPCEleLen;
+	tDot11fFfTxPower            TxPower;
+	tDot11fFfLinkMargin         LinkMargin;
+	tDot11fFfRxAntennaId        RxAntennaId;
+	tDot11fFfTxAntennaId        TxAntennaId;
+	tDot11fFfRCPI               RCPI;
+	tDot11fFfRSNI               RSNI;
+} tDot11fLinkMeasurementReport;
+
+#define DOT11F_LINKMEASUREMENTREPORT (14)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_link_measurement_report(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fLinkMeasurementReport * pFrm, bool append_ie);
+uint32_t dot11f_pack_link_measurement_report(tpAniSirGlobal pCtx,
+	tDot11fLinkMeasurementReport *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_link_measurement_report_size(tpAniSirGlobal pCtx,
+	tDot11fLinkMeasurementReport *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fLinkMeasurementRequest{
+	tDot11fFfCategory           Category;
+	tDot11fFfAction             Action;
+	tDot11fFfDialogToken        DialogToken;
+	tDot11fFfTxPower            TxPower;
+	tDot11fFfMaxTxPower         MaxTxPower;
+} tDot11fLinkMeasurementRequest;
+
+#define DOT11F_LINKMEASUREMENTREQUEST (15)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_link_measurement_request(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fLinkMeasurementRequest * pFrm, bool append_ie);
+uint32_t dot11f_pack_link_measurement_request(tpAniSirGlobal pCtx,
+	tDot11fLinkMeasurementRequest *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_link_measurement_request_size(tpAniSirGlobal pCtx,
+	tDot11fLinkMeasurementRequest *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fMeasurementReport{
+	tDot11fFfCategory                 Category;
+	tDot11fFfAction                   Action;
+	tDot11fFfDialogToken              DialogToken;
+	tDot11fIEMeasurementReport        MeasurementReport;
+} tDot11fMeasurementReport;
+
+#define DOT11F_MEASUREMENTREPORT (16)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_measurement_report(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fMeasurementReport * pFrm, bool append_ie);
+uint32_t dot11f_pack_measurement_report(tpAniSirGlobal pCtx,
+	tDot11fMeasurementReport *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_measurement_report_size(tpAniSirGlobal pCtx,
+	tDot11fMeasurementReport *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fMeasurementRequest{
+	tDot11fFfCategory                  Category;
+	tDot11fFfAction                    Action;
+	tDot11fFfDialogToken               DialogToken;
+	uint16_t                           num_MeasurementRequest;
+	tDot11fIEMeasurementRequest        MeasurementRequest[4];
+} tDot11fMeasurementRequest;
+
+#define DOT11F_MEASUREMENTREQUEST (17)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_measurement_request(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fMeasurementRequest * pFrm, bool append_ie);
+uint32_t dot11f_pack_measurement_request(tpAniSirGlobal pCtx,
+	tDot11fMeasurementRequest *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_measurement_request_size(tpAniSirGlobal pCtx,
+	tDot11fMeasurementRequest *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fNeighborReportRequest{
+	tDot11fFfCategory           Category;
+	tDot11fFfAction             Action;
+	tDot11fFfDialogToken        DialogToken;
+	tDot11fIESSID               SSID;
+} tDot11fNeighborReportRequest;
+
+#define DOT11F_NEIGHBORREPORTREQUEST (18)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_neighbor_report_request(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fNeighborReportRequest * pFrm, bool append_ie);
+uint32_t dot11f_pack_neighbor_report_request(tpAniSirGlobal pCtx,
+	tDot11fNeighborReportRequest *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_neighbor_report_request_size(tpAniSirGlobal pCtx,
+	tDot11fNeighborReportRequest *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fNeighborReportResponse{
+	tDot11fFfCategory              Category;
+	tDot11fFfAction                Action;
+	tDot11fFfDialogToken           DialogToken;
+	uint16_t                       num_NeighborReport;
+	tDot11fIENeighborReport        NeighborReport[15];
+} tDot11fNeighborReportResponse;
+
+#define DOT11F_NEIGHBORREPORTRESPONSE (19)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_neighbor_report_response(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fNeighborReportResponse * pFrm, bool append_ie);
+uint32_t dot11f_pack_neighbor_report_response(tpAniSirGlobal pCtx,
+	tDot11fNeighborReportResponse *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_neighbor_report_response_size(tpAniSirGlobal pCtx,
+	tDot11fNeighborReportResponse *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fOperatingMode{
+	tDot11fFfCategory             Category;
+	tDot11fFfAction               Action;
+	tDot11fFfOperatingMode        OperatingMode;
+} tDot11fOperatingMode;
+
+#define DOT11F_OPERATINGMODE (20)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_operating_mode(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fOperatingMode * pFrm, bool append_ie);
+uint32_t dot11f_pack_operating_mode(tpAniSirGlobal pCtx,
+	tDot11fOperatingMode *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_operating_mode_size(tpAniSirGlobal pCtx,
+	tDot11fOperatingMode *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fProbeRequest{
+	tDot11fIESSID                 SSID;
+	tDot11fIESuppRates            SuppRates;
+	tDot11fIERequestedInfo        RequestedInfo;
+	tDot11fIEExtSuppRates         ExtSuppRates;
+	tDot11fIEDSParams             DSParams;
+	tDot11fIEHTCaps               HTCaps;
+	tDot11fIEWscProbeReq          WscProbeReq;
+	tDot11fIEWFATPC               WFATPC;
+	tDot11fIEP2PProbeReq          P2PProbeReq;
+	tDot11fIEVHTCaps              VHTCaps;
+	tDot11fIEExtCap               ExtCap;
+	tDot11fIEQCN_IE               QCN_IE;
+	tDot11fIEhe_cap               he_cap;
+} tDot11fProbeRequest;
+
+#define DOT11F_PROBEREQUEST (21)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_probe_request(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fProbeRequest * pFrm, bool append_ie);
+uint32_t dot11f_pack_probe_request(tpAniSirGlobal pCtx,
+	tDot11fProbeRequest *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_probe_request_size(tpAniSirGlobal pCtx,
+	tDot11fProbeRequest *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fProbeResponse{
+	tDot11fFfTimeStamp                   TimeStamp;
+	tDot11fFfBeaconInterval              BeaconInterval;
+	tDot11fFfCapabilities                Capabilities;
+	tDot11fIESSID                        SSID;
+	tDot11fIESuppRates                   SuppRates;
+	tDot11fIEFHParamSet                  FHParamSet;
+	tDot11fIEDSParams                    DSParams;
+	tDot11fIECFParams                    CFParams;
+	tDot11fIEIBSSParams                  IBSSParams;
+	tDot11fIECountry                     Country;
+	tDot11fIEFHParams                    FHParams;
+	tDot11fIEFHPattTable                 FHPattTable;
+	tDot11fIEPowerConstraints            PowerConstraints;
+	tDot11fIEChanSwitchAnn               ChanSwitchAnn;
+	tDot11fIEext_chan_switch_ann         ext_chan_switch_ann;
+	tDot11fIESuppOperatingClasses        SuppOperatingClasses;
+	tDot11fIEQuiet                       Quiet;
+	tDot11fIETPCReport                   TPCReport;
+	tDot11fIEERPInfo                     ERPInfo;
+	tDot11fIEExtSuppRates                ExtSuppRates;
+	tDot11fIERSNOpaque                   RSNOpaque;
+	tDot11fIEQBSSLoad                    QBSSLoad;
+	tDot11fIEEDCAParamSet                EDCAParamSet;
+	tDot11fIERRMEnabledCap               RRMEnabledCap;
+	tDot11fIEAPChannelReport             APChannelReport;
+	tDot11fIEMobilityDomain              MobilityDomain;
+	tDot11fIEWPA                         WPA;
+	tDot11fIEHTCaps                      HTCaps;
+	tDot11fIEHTInfo                      HTInfo;
+	tDot11fIEsec_chan_offset_ele         sec_chan_offset_ele;
+	tDot11fIEWMMInfoAp                   WMMInfoAp;
+	tDot11fIEWMMParams                   WMMParams;
+	tDot11fIEWMMCaps                     WMMCaps;
+	tDot11fIEWAPI                        WAPI;
+	tDot11fIEESERadMgmtCap               ESERadMgmtCap;
+	tDot11fIEESETrafStrmMet              ESETrafStrmMet;
+	tDot11fIEESETxmitPower               ESETxmitPower;
+	tDot11fIEWscProbeRes                 WscProbeRes;
+	tDot11fIEP2PProbeRes                 P2PProbeRes;
+	tDot11fIEVHTCaps                     VHTCaps;
+	tDot11fIEVHTOperation                VHTOperation;
+	tDot11fIEVHTExtBssLoad               VHTExtBssLoad;
+	tDot11fIEExtCap                      ExtCap;
+	tDot11fIEOBSSScanParameters          OBSSScanParameters;
+	tDot11fIEfils_indication             fils_indication;
+	tDot11fIEVendor1IE                   Vendor1IE;
+	tDot11fIEvendor_vht_ie               vendor_vht_ie;
+	tDot11fIEVendor3IE                   Vendor3IE;
+	tDot11fIEhs20vendor_ie               hs20vendor_ie;
+	tDot11fIEChannelSwitchWrapper        ChannelSwitchWrapper;
+	tDot11fIEQComVendorIE                QComVendorIE;
+	tDot11fIEESEVersion                  ESEVersion;
+	tDot11fIEMBO_IE                      MBO_IE;
+	tDot11fIEQCN_IE                      QCN_IE;
+	tDot11fIEhe_cap                      he_cap;
+	tDot11fIEhe_op                       he_op;
+	tDot11fIEbss_color_change            bss_color_change;
+	tDot11fIEmu_edca_param_set           mu_edca_param_set;
+	tDot11fIEesp_information             esp_information;
+} tDot11fProbeResponse;
+
+#define DOT11F_PROBERESPONSE (22)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_probe_response(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fProbeResponse * pFrm, bool append_ie);
+uint32_t dot11f_pack_probe_response(tpAniSirGlobal pCtx,
+	tDot11fProbeResponse *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_probe_response_size(tpAniSirGlobal pCtx,
+	tDot11fProbeResponse *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fQosMapConfigure{
+	tDot11fFfCategory         Category;
+	tDot11fFfAction           Action;
+	tDot11fIEQosMapSet        QosMapSet;
+} tDot11fQosMapConfigure;
+
+#define DOT11F_QOSMAPCONFIGURE (23)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_qos_map_configure(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fQosMapConfigure * pFrm, bool append_ie);
+uint32_t dot11f_pack_qos_map_configure(tpAniSirGlobal pCtx,
+	tDot11fQosMapConfigure *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_qos_map_configure_size(tpAniSirGlobal pCtx,
+	tDot11fQosMapConfigure *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fRadioMeasurementReport{
+	tDot11fFfCategory                 Category;
+	tDot11fFfAction                   Action;
+	tDot11fFfDialogToken              DialogToken;
+	uint16_t                          num_MeasurementReport;
+	tDot11fIEMeasurementReport        MeasurementReport[4];
+} tDot11fRadioMeasurementReport;
+
+#define DOT11F_RADIOMEASUREMENTREPORT (24)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_radio_measurement_report(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fRadioMeasurementReport * pFrm, bool append_ie);
+uint32_t dot11f_pack_radio_measurement_report(tpAniSirGlobal pCtx,
+	tDot11fRadioMeasurementReport *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_radio_measurement_report_size(tpAniSirGlobal pCtx,
+	tDot11fRadioMeasurementReport *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fRadioMeasurementRequest{
+	tDot11fFfCategory                  Category;
+	tDot11fFfAction                    Action;
+	tDot11fFfDialogToken               DialogToken;
+	tDot11fFfNumOfRepetitions          NumOfRepetitions;
+	uint16_t                           num_MeasurementRequest;
+	tDot11fIEMeasurementRequest        MeasurementRequest[2];
+} tDot11fRadioMeasurementRequest;
+
+#define DOT11F_RADIOMEASUREMENTREQUEST (25)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_radio_measurement_request(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fRadioMeasurementRequest * pFrm, bool append_ie);
+uint32_t dot11f_pack_radio_measurement_request(tpAniSirGlobal pCtx,
+	tDot11fRadioMeasurementRequest *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_radio_measurement_request_size(tpAniSirGlobal pCtx,
+	tDot11fRadioMeasurementRequest *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fReAssocRequest{
+	tDot11fFfCapabilities              Capabilities;
+	tDot11fFfListenInterval            ListenInterval;
+	tDot11fFfCurrentAPAddress          CurrentAPAddress;
+	tDot11fIESSID                      SSID;
+	tDot11fIESuppRates                 SuppRates;
+	tDot11fIEExtSuppRates              ExtSuppRates;
+	tDot11fIEPowerCaps                 PowerCaps;
+	tDot11fIESuppChannels              SuppChannels;
+	tDot11fIERSNOpaque                 RSNOpaque;
+	tDot11fIEQOSCapsStation            QOSCapsStation;
+	tDot11fIERRMEnabledCap             RRMEnabledCap;
+	tDot11fIEMobilityDomain            MobilityDomain;
+	tDot11fIEFTInfo                    FTInfo;
+	uint16_t                           num_RICDataDesc;
+	tDot11fIERICDataDesc               RICDataDesc[2];
+	tDot11fIEWPAOpaque                 WPAOpaque;
+	tDot11fIEHTCaps                    HTCaps;
+	tDot11fIEWMMCaps                   WMMCaps;
+	tDot11fIEWMMInfoStation            WMMInfoStation;
+	tDot11fIEWscIEOpaque               WscIEOpaque;
+	tDot11fIEWAPIOpaque                WAPIOpaque;
+	tDot11fIEWAPI                      WAPI;
+	tDot11fIEESERadMgmtCap             ESERadMgmtCap;
+	tDot11fIEESEVersion                ESEVersion;
+	tDot11fIEESECckmOpaque             ESECckmOpaque;
+	uint16_t                           num_WMMTSPEC;
+	tDot11fIEWMMTSPEC                  WMMTSPEC[4];
+	tDot11fIEESETrafStrmRateSet        ESETrafStrmRateSet;
+	tDot11fIEP2PIEOpaque               P2PIEOpaque;
+	tDot11fIEWFDIEOpaque               WFDIEOpaque;
+	tDot11fIEVHTCaps                   VHTCaps;
+	tDot11fIEExtCap                    ExtCap;
+	tDot11fIEOperatingMode             OperatingMode;
+	tDot11fIEQosMapSet                 QosMapSet;
+	tDot11fIEvendor_vht_ie             vendor_vht_ie;
+	tDot11fIEhs20vendor_ie             hs20vendor_ie;
+	tDot11fIEhe_cap                    he_cap;
+} tDot11fReAssocRequest;
+
+#define DOT11F_REASSOCREQUEST (26)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_re_assoc_request(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fReAssocRequest * pFrm, bool append_ie);
+uint32_t dot11f_pack_re_assoc_request(tpAniSirGlobal pCtx,
+	tDot11fReAssocRequest *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_re_assoc_request_size(tpAniSirGlobal pCtx,
+	tDot11fReAssocRequest *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fReAssocResponse{
+	tDot11fFfCapabilities              Capabilities;
+	tDot11fFfStatus                    Status;
+	tDot11fFfAID                       AID;
+	tDot11fIESuppRates                 SuppRates;
+	tDot11fIEExtSuppRates              ExtSuppRates;
+	tDot11fIEEDCAParamSet              EDCAParamSet;
+	tDot11fIERCPIIE                    RCPIIE;
+	tDot11fIERSNIIE                    RSNIIE;
+	tDot11fIERRMEnabledCap             RRMEnabledCap;
+	tDot11fIERSNOpaque                 RSNOpaque;
+	tDot11fIEMobilityDomain            MobilityDomain;
+	tDot11fIEFTInfo                    FTInfo;
+	uint16_t                           num_RICDataDesc;
+	tDot11fIERICDataDesc               RICDataDesc[2];
+	tDot11fIEWPA                       WPA;
+	tDot11fIETimeoutInterval           TimeoutInterval;
+	tDot11fIEHTCaps                    HTCaps;
+	tDot11fIEHTInfo                    HTInfo;
+	tDot11fIEWMMParams                 WMMParams;
+	tDot11fIEESERadMgmtCap             ESERadMgmtCap;
+	tDot11fIEESETrafStrmMet            ESETrafStrmMet;
+	tDot11fIEESETxmitPower             ESETxmitPower;
+	uint16_t                           num_WMMTSPEC;
+	tDot11fIEWMMTSPEC                  WMMTSPEC[4];
+	tDot11fIEESETrafStrmRateSet        ESETrafStrmRateSet;
+	tDot11fIEWscReassocRes             WscReassocRes;
+	tDot11fIEP2PAssocRes               P2PAssocRes;
+	tDot11fIEVHTCaps                   VHTCaps;
+	tDot11fIEVHTOperation              VHTOperation;
+	tDot11fIEExtCap                    ExtCap;
+	tDot11fIEOBSSScanParameters        OBSSScanParameters;
+	tDot11fIEQosMapSet                 QosMapSet;
+	tDot11fIEvendor_vht_ie             vendor_vht_ie;
+	tDot11fIEhe_cap                    he_cap;
+	tDot11fIEhe_op                     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)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_re_assoc_response(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fReAssocResponse * pFrm, bool append_ie);
+uint32_t dot11f_pack_re_assoc_response(tpAniSirGlobal pCtx,
+	tDot11fReAssocResponse *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_re_assoc_response_size(tpAniSirGlobal pCtx,
+	tDot11fReAssocResponse *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fSMPowerSave{
+	tDot11fFfCategory              Category;
+	tDot11fFfAction                Action;
+	tDot11fFfSMPowerModeSet        SMPowerModeSet;
+} tDot11fSMPowerSave;
+
+#define DOT11F_SMPOWERSAVE (28)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_sm_power_save(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fSMPowerSave * pFrm, bool append_ie);
+uint32_t dot11f_pack_sm_power_save(tpAniSirGlobal pCtx,
+	tDot11fSMPowerSave *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_sm_power_save_size(tpAniSirGlobal pCtx,
+	tDot11fSMPowerSave *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fSaQueryReq{
+	tDot11fFfCategory             Category;
+	tDot11fFfAction               Action;
+	tDot11fFfTransactionId        TransactionId;
+} tDot11fSaQueryReq;
+
+#define DOT11F_SAQUERYREQ (29)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_sa_query_req(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fSaQueryReq * pFrm, bool append_ie);
+uint32_t dot11f_pack_sa_query_req(tpAniSirGlobal pCtx,
+	tDot11fSaQueryReq *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_sa_query_req_size(tpAniSirGlobal pCtx,
+	tDot11fSaQueryReq *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fSaQueryRsp{
+	tDot11fFfCategory             Category;
+	tDot11fFfAction               Action;
+	tDot11fFfTransactionId        TransactionId;
+} tDot11fSaQueryRsp;
+
+#define DOT11F_SAQUERYRSP (30)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_sa_query_rsp(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fSaQueryRsp * pFrm, bool append_ie);
+uint32_t dot11f_pack_sa_query_rsp(tpAniSirGlobal pCtx,
+	tDot11fSaQueryRsp *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_sa_query_rsp_size(tpAniSirGlobal pCtx,
+	tDot11fSaQueryRsp *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSDisReq{
+	tDot11fFfCategory              Category;
+	tDot11fFfAction                Action;
+	tDot11fFfDialogToken           DialogToken;
+	tDot11fIELinkIdentifier        LinkIdentifier;
+} tDot11fTDLSDisReq;
+
+#define DOT11F_TDLSDISREQ (31)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_dis_req(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fTDLSDisReq * pFrm, bool append_ie);
+uint32_t dot11f_pack_tdls_dis_req(tpAniSirGlobal pCtx,
+	tDot11fTDLSDisReq *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_dis_req_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSDisReq *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSDisRsp{
+	tDot11fFfCategory                      Category;
+	tDot11fFfAction                        Action;
+	tDot11fFfDialogToken                   DialogToken;
+	tDot11fFfCapabilities                  Capabilities;
+	tDot11fIESuppRates                     SuppRates;
+	tDot11fIEExtSuppRates                  ExtSuppRates;
+	tDot11fIESuppChannels                  SuppChannels;
+	tDot11fIESuppOperatingClasses          SuppOperatingClasses;
+	tDot11fIERSN                           RSN;
+	tDot11fIEExtCap                        ExtCap;
+	tDot11fIEFTInfo                        FTInfo;
+	tDot11fIETimeoutInterval               TimeoutInterval;
+	tDot11fIERICData                       RICData;
+	tDot11fIEHTCaps                        HTCaps;
+	tDot11fIEht2040_bss_coexistence        ht2040_bss_coexistence;
+	tDot11fIELinkIdentifier                LinkIdentifier;
+	tDot11fIEVHTCaps                       VHTCaps;
+} tDot11fTDLSDisRsp;
+
+#define DOT11F_TDLSDISRSP (32)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_dis_rsp(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fTDLSDisRsp * pFrm, bool append_ie);
+uint32_t dot11f_pack_tdls_dis_rsp(tpAniSirGlobal pCtx,
+	tDot11fTDLSDisRsp *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_dis_rsp_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSDisRsp *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSPeerTrafficInd{
+	tDot11fFfCategory              Category;
+	tDot11fFfAction                Action;
+	tDot11fFfDialogToken           DialogToken;
+	tDot11fIELinkIdentifier        LinkIdentifier;
+	tDot11fIEPTIControl            PTIControl;
+	tDot11fIEPUBufferStatus        PUBufferStatus;
+} tDot11fTDLSPeerTrafficInd;
+
+#define DOT11F_TDLSPEERTRAFFICIND (33)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_peer_traffic_ind(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fTDLSPeerTrafficInd * pFrm, bool append_ie);
+uint32_t dot11f_pack_tdls_peer_traffic_ind(tpAniSirGlobal pCtx,
+	tDot11fTDLSPeerTrafficInd *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_peer_traffic_ind_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSPeerTrafficInd *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSPeerTrafficRsp{
+	tDot11fFfCategory              Category;
+	tDot11fFfAction                Action;
+	tDot11fFfDialogToken           DialogToken;
+	tDot11fIELinkIdentifier        LinkIdentifier;
+} tDot11fTDLSPeerTrafficRsp;
+
+#define DOT11F_TDLSPEERTRAFFICRSP (34)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_peer_traffic_rsp(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fTDLSPeerTrafficRsp * pFrm, bool append_ie);
+uint32_t dot11f_pack_tdls_peer_traffic_rsp(tpAniSirGlobal pCtx,
+	tDot11fTDLSPeerTrafficRsp *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_peer_traffic_rsp_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSPeerTrafficRsp *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSSetupCnf{
+	tDot11fFfCategory               Category;
+	tDot11fFfAction                 Action;
+	tDot11fFfStatus                 Status;
+	tDot11fFfDialogToken            DialogToken;
+	tDot11fIERSN                    RSN;
+	tDot11fIEEDCAParamSet           EDCAParamSet;
+	tDot11fIEFTInfo                 FTInfo;
+	tDot11fIETimeoutInterval        TimeoutInterval;
+	tDot11fIEHTInfo                 HTInfo;
+	tDot11fIELinkIdentifier         LinkIdentifier;
+	tDot11fIEWMMParams              WMMParams;
+	tDot11fIEVHTOperation           VHTOperation;
+	tDot11fIEOperatingMode          OperatingMode;
+} tDot11fTDLSSetupCnf;
+
+#define DOT11F_TDLSSETUPCNF (35)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_setup_cnf(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fTDLSSetupCnf * pFrm, bool append_ie);
+uint32_t dot11f_pack_tdls_setup_cnf(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupCnf *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_setup_cnf_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupCnf *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSSetupReq{
+	tDot11fFfCategory                      Category;
+	tDot11fFfAction                        Action;
+	tDot11fFfDialogToken                   DialogToken;
+	tDot11fFfCapabilities                  Capabilities;
+	tDot11fIESuppRates                     SuppRates;
+	tDot11fIECountry                       Country;
+	tDot11fIEExtSuppRates                  ExtSuppRates;
+	tDot11fIESuppChannels                  SuppChannels;
+	tDot11fIERSN                           RSN;
+	tDot11fIEExtCap                        ExtCap;
+	tDot11fIESuppOperatingClasses          SuppOperatingClasses;
+	tDot11fIEQOSCapsStation                QOSCapsStation;
+	tDot11fIEFTInfo                        FTInfo;
+	tDot11fIETimeoutInterval               TimeoutInterval;
+	tDot11fIERICData                       RICData;
+	tDot11fIEHTCaps                        HTCaps;
+	tDot11fIEht2040_bss_coexistence        ht2040_bss_coexistence;
+	tDot11fIELinkIdentifier                LinkIdentifier;
+	tDot11fIEWMMInfoStation                WMMInfoStation;
+	tDot11fIEAID                           AID;
+	tDot11fIEVHTCaps                       VHTCaps;
+} tDot11fTDLSSetupReq;
+
+#define DOT11F_TDLSSETUPREQ (36)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_setup_req(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fTDLSSetupReq * pFrm, bool append_ie);
+uint32_t dot11f_pack_tdls_setup_req(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupReq *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_setup_req_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupReq *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSSetupRsp{
+	tDot11fFfCategory                      Category;
+	tDot11fFfAction                        Action;
+	tDot11fFfStatus                        Status;
+	tDot11fFfDialogToken                   DialogToken;
+	tDot11fFfCapabilities                  Capabilities;
+	tDot11fIESuppRates                     SuppRates;
+	tDot11fIECountry                       Country;
+	tDot11fIEExtSuppRates                  ExtSuppRates;
+	tDot11fIESuppChannels                  SuppChannels;
+	tDot11fIERSN                           RSN;
+	tDot11fIEExtCap                        ExtCap;
+	tDot11fIESuppOperatingClasses          SuppOperatingClasses;
+	tDot11fIEQOSCapsStation                QOSCapsStation;
+	tDot11fIEFTInfo                        FTInfo;
+	tDot11fIETimeoutInterval               TimeoutInterval;
+	tDot11fIERICData                       RICData;
+	tDot11fIEHTCaps                        HTCaps;
+	tDot11fIEht2040_bss_coexistence        ht2040_bss_coexistence;
+	tDot11fIELinkIdentifier                LinkIdentifier;
+	tDot11fIEWMMInfoStation                WMMInfoStation;
+	tDot11fIEAID                           AID;
+	tDot11fIEVHTCaps                       VHTCaps;
+	tDot11fIEOperatingMode                 OperatingMode;
+} tDot11fTDLSSetupRsp;
+
+#define DOT11F_TDLSSETUPRSP (37)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_setup_rsp(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fTDLSSetupRsp * pFrm, bool append_ie);
+uint32_t dot11f_pack_tdls_setup_rsp(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupRsp *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_setup_rsp_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupRsp *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSTeardown{
+	tDot11fFfCategory              Category;
+	tDot11fFfAction                Action;
+	tDot11fFfReason                Reason;
+	tDot11fIEFTInfo                FTInfo;
+	tDot11fIELinkIdentifier        LinkIdentifier;
+} tDot11fTDLSTeardown;
+
+#define DOT11F_TDLSTEARDOWN (38)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_teardown(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fTDLSTeardown * pFrm, bool append_ie);
+uint32_t dot11f_pack_tdls_teardown(tpAniSirGlobal pCtx,
+	tDot11fTDLSTeardown *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_teardown_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSTeardown *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTPCReport{
+	tDot11fFfCategory           Category;
+	tDot11fFfAction             Action;
+	tDot11fFfDialogToken        DialogToken;
+	tDot11fIETPCReport          TPCReport;
+} tDot11fTPCReport;
+
+#define DOT11F_TPCREPORT (39)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tpc_report(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fTPCReport * pFrm, bool append_ie);
+uint32_t dot11f_pack_tpc_report(tpAniSirGlobal pCtx,
+	tDot11fTPCReport *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tpc_report_size(tpAniSirGlobal pCtx,
+	tDot11fTPCReport *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTPCRequest{
+	tDot11fFfCategory           Category;
+	tDot11fFfAction             Action;
+	tDot11fFfDialogToken        DialogToken;
+	tDot11fIETPCRequest         TPCRequest;
+} tDot11fTPCRequest;
+
+#define DOT11F_TPCREQUEST (40)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tpc_request(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fTPCRequest * pFrm, bool append_ie);
+uint32_t dot11f_pack_tpc_request(tpAniSirGlobal pCtx,
+	tDot11fTPCRequest *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tpc_request_size(tpAniSirGlobal pCtx,
+	tDot11fTPCRequest *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTimingAdvertisementFrame{
+	tDot11fFfTimeStamp                TimeStamp;
+	tDot11fFfCapabilities             Capabilities;
+	tDot11fIECountry                  Country;
+	tDot11fIEPowerConstraints         PowerConstraints;
+	tDot11fIETimeAdvertisement        TimeAdvertisement;
+	tDot11fIEExtCap                   ExtCap;
+	tDot11fIEVendor1IE                Vendor1IE;
+	tDot11fIEVendor3IE                Vendor3IE;
+} tDot11fTimingAdvertisementFrame;
+
+#define DOT11F_TIMINGADVERTISEMENTFRAME (41)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_timing_advertisement_frame(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fTimingAdvertisementFrame * pFrm, bool append_ie);
+uint32_t dot11f_pack_timing_advertisement_frame(tpAniSirGlobal pCtx,
+	tDot11fTimingAdvertisementFrame *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_timing_advertisement_frame_size(tpAniSirGlobal pCtx,
+	tDot11fTimingAdvertisementFrame *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fVHTGidManagementActionFrame{
+	tDot11fFfCategory                        Category;
+	tDot11fFfAction                          Action;
+	tDot11fFfVhtMembershipStatusArray        VhtMembershipStatusArray;
+	tDot11fFfVhtUserPositionArray            VhtUserPositionArray;
+} tDot11fVHTGidManagementActionFrame;
+
+#define DOT11F_VHTGIDMANAGEMENTACTIONFRAME (42)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_vht_gid_management_action_frame(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fVHTGidManagementActionFrame * pFrm, bool append_ie);
+uint32_t dot11f_pack_vht_gid_management_action_frame(tpAniSirGlobal pCtx,
+	tDot11fVHTGidManagementActionFrame *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_vht_gid_management_action_frame_size(tpAniSirGlobal pCtx,
+	tDot11fVHTGidManagementActionFrame *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fWMMAddTSRequest{
+	tDot11fFfCategory                  Category;
+	tDot11fFfAction                    Action;
+	tDot11fFfDialogToken               DialogToken;
+	tDot11fFfStatusCode                StatusCode;
+	tDot11fIEWMMTSPEC                  WMMTSPEC;
+	tDot11fIEESETrafStrmRateSet        ESETrafStrmRateSet;
+} tDot11fWMMAddTSRequest;
+
+#define DOT11F_WMMADDTSREQUEST (43)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_wmm_add_ts_request(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fWMMAddTSRequest * pFrm, bool append_ie);
+uint32_t dot11f_pack_wmm_add_ts_request(tpAniSirGlobal pCtx,
+	tDot11fWMMAddTSRequest *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_wmm_add_ts_request_size(tpAniSirGlobal pCtx,
+	tDot11fWMMAddTSRequest *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fWMMAddTSResponse{
+	tDot11fFfCategory              Category;
+	tDot11fFfAction                Action;
+	tDot11fFfDialogToken           DialogToken;
+	tDot11fFfStatusCode            StatusCode;
+	tDot11fIEWMMTSPEC              WMMTSPEC;
+	tDot11fIEESETrafStrmMet        ESETrafStrmMet;
+} tDot11fWMMAddTSResponse;
+
+#define DOT11F_WMMADDTSRESPONSE (44)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_wmm_add_ts_response(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fWMMAddTSResponse * pFrm, bool append_ie);
+uint32_t dot11f_pack_wmm_add_ts_response(tpAniSirGlobal pCtx,
+	tDot11fWMMAddTSResponse *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_wmm_add_ts_response_size(tpAniSirGlobal pCtx,
+	tDot11fWMMAddTSResponse *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fWMMDelTS{
+	tDot11fFfCategory           Category;
+	tDot11fFfAction             Action;
+	tDot11fFfDialogToken        DialogToken;
+	tDot11fFfStatusCode         StatusCode;
+	tDot11fIEWMMTSPEC           WMMTSPEC;
+} tDot11fWMMDelTS;
+
+#define DOT11F_WMMDELTS (45)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_wmm_del_ts(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fWMMDelTS * pFrm, bool append_ie);
+uint32_t dot11f_pack_wmm_del_ts(tpAniSirGlobal pCtx,
+	tDot11fWMMDelTS *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_wmm_del_ts_size(tpAniSirGlobal pCtx,
+	tDot11fWMMDelTS *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11faddba_req{
+	tDot11fFfCategory                  Category;
+	tDot11fFfAction                    Action;
+	tDot11fFfDialogToken               DialogToken;
+	tDot11fFfaddba_param_set           addba_param_set;
+	tDot11fFfba_timeout                ba_timeout;
+	tDot11fFfba_start_seq_ctrl         ba_start_seq_ctrl;
+	tDot11fIEaddba_extn_element        addba_extn_element;
+} tDot11faddba_req;
+
+#define DOT11F_ADDBA_REQ (46)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_addba_req(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11faddba_req * pFrm, bool append_ie);
+uint32_t dot11f_pack_addba_req(tpAniSirGlobal pCtx,
+	tDot11faddba_req *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_addba_req_size(tpAniSirGlobal pCtx,
+	tDot11faddba_req *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11faddba_rsp{
+	tDot11fFfCategory                  Category;
+	tDot11fFfAction                    Action;
+	tDot11fFfDialogToken               DialogToken;
+	tDot11fFfStatus                    Status;
+	tDot11fFfaddba_param_set           addba_param_set;
+	tDot11fFfba_timeout                ba_timeout;
+	tDot11fIEaddba_extn_element        addba_extn_element;
+} tDot11faddba_rsp;
+
+#define DOT11F_ADDBA_RSP (47)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_addba_rsp(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11faddba_rsp * pFrm, bool append_ie);
+uint32_t dot11f_pack_addba_rsp(tpAniSirGlobal pCtx,
+	tDot11faddba_rsp *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_addba_rsp_size(tpAniSirGlobal pCtx,
+	tDot11faddba_rsp *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fdelba_req{
+	tDot11fFfCategory               Category;
+	tDot11fFfAction                 Action;
+	tDot11fFfdelba_param_set        delba_param_set;
+	tDot11fFfReason                 Reason;
+} tDot11fdelba_req;
+
+#define DOT11F_DELBA_REQ (48)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_delba_req(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fdelba_req * pFrm, bool append_ie);
+uint32_t dot11f_pack_delba_req(tpAniSirGlobal pCtx,
+	tDot11fdelba_req *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_delba_req_size(tpAniSirGlobal pCtx,
+	tDot11fdelba_req *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fext_channel_switch_action_frame{
+	tDot11fFfCategory                          Category;
+	tDot11fFfAction                            Action;
+	tDot11fFfext_chan_switch_ann_action        ext_chan_switch_ann_action;
+	tDot11fIEWiderBWChanSwitchAnn              WiderBWChanSwitchAnn;
+} tDot11fext_channel_switch_action_frame;
+
+#define DOT11F_EXT_CHANNEL_SWITCH_ACTION_FRAME (49)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_ext_channel_switch_action_frame(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fext_channel_switch_action_frame * pFrm, bool append_ie);
+uint32_t dot11f_pack_ext_channel_switch_action_frame(tpAniSirGlobal pCtx,
+	tDot11fext_channel_switch_action_frame *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_ext_channel_switch_action_frame_size(tpAniSirGlobal pCtx,
+	tDot11fext_channel_switch_action_frame *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fht2040_bss_coexistence_mgmt_action_frame{
+	tDot11fFfCategory                            Category;
+	tDot11fFfAction                              Action;
+	tDot11fIEht2040_bss_coexistence              ht2040_bss_coexistence;
+	tDot11fIEht2040_bss_intolerant_report        ht2040_bss_intolerant_report;
+} tDot11fht2040_bss_coexistence_mgmt_action_frame;
+
+#define DOT11F_HT2040_BSS_COEXISTENCE_MGMT_ACTION_FRAME (50)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_ht2040_bss_coexistence_mgmt_action_frame(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fht2040_bss_coexistence_mgmt_action_frame * pFrm, bool append_ie);
+uint32_t dot11f_pack_ht2040_bss_coexistence_mgmt_action_frame(tpAniSirGlobal pCtx,
+	tDot11fht2040_bss_coexistence_mgmt_action_frame *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_ht2040_bss_coexistence_mgmt_action_frameSize(tpAniSirGlobal pCtx,
+	tDot11fht2040_bss_coexistence_mgmt_action_frame *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fp2p_oper_chan_change_confirm{
+	tDot11fFfCategory                  Category;
+	tDot11fFfp2p_action_oui            p2p_action_oui;
+	tDot11fFfp2p_action_subtype        p2p_action_subtype;
+	tDot11fFfDialogToken               DialogToken;
+	tDot11fIEHTCaps                    HTCaps;
+	tDot11fIEVHTCaps                   VHTCaps;
+	tDot11fIEOperatingMode             OperatingMode;
+} tDot11fp2p_oper_chan_change_confirm;
+
+#define DOT11F_P2P_OPER_CHAN_CHANGE_CONFIRM (51)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_p2p_oper_chan_change_confirm(tpAniSirGlobal pCtx,
+	uint8_t *pBuf, uint32_t nBuf,
+	tDot11fp2p_oper_chan_change_confirm * pFrm, bool append_ie);
+uint32_t dot11f_pack_p2p_oper_chan_change_confirm(tpAniSirGlobal pCtx,
+	tDot11fp2p_oper_chan_change_confirm *pFrm, uint8_t *pBuf,
+	uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_p2p_oper_chan_change_confirmSize(tpAniSirGlobal pCtx,
+	tDot11fp2p_oper_chan_change_confirm *pFrm,
+	uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+#endif /* DOT11F_H */
diff --git a/core/mac/src/include/dph_global.h b/core/mac/src/include/dph_global.h
new file mode 100644
index 0000000..ea1ed1c
--- /dev/null
+++ b/core/mac/src/include/dph_global.h
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+
+ *
+
+ * Author:      Sandesh Goel
+
+ * Date:        02/25/02
+
+ * History:-
+
+ * Date            Modified by    Modification Information
+
+ * --------------------------------------------------------------------
+
+ *
+
+ */
+
+#ifndef __DPH_GLOBAL_H__
+#define __DPH_GLOBAL_H__
+
+#include "lim_global.h"
+#include "sir_mac_prot_def.h"
+#include "sir_mac_prop_exts.h"
+#include "sir_api.h"
+
+/* Following determines whether statistics are maintained or not */
+#define DPH_STATS
+
+/* STAID for Management frames */
+#define DPH_USE_MGMT_STAID  -1
+
+/* Keep Alive frames */
+#define DPH_NON_KEEPALIVE_FRAME  0
+#define DPH_KEEPALIVE_FRAME      1
+
+/* DPH Hash Index for BSS(STA's Peer) on station. */
+#define DPH_STA_HASH_INDEX_PEER   1
+
+#ifdef WLAN_FEATURE_11W
+/* DPH PMF SA Query state for station */
+#define DPH_SA_QUERY_NOT_IN_PROGRESS      1
+#define DPH_SA_QUERY_IN_PROGRESS          2
+#define DPH_SA_QUERY_TIMED_OUT            3
+#endif
+
+typedef struct sDphRateBasedCtr {
+	uint32_t hi;
+	uint32_t lo;
+} tDphRateBasedCtr;
+
+typedef struct sDphPhyRates {
+	uint8_t dataRateX2;
+	uint8_t ackRateX2;
+	uint8_t rtsRateX2;
+} tDphPhyRates;
+
+typedef struct sDphIFSValues {
+	uint8_t sifs;
+	uint8_t pifs;
+	uint8_t difs;
+	uint8_t preamble;
+} tDphIFSValues;
+
+typedef struct sDphQosParams {
+	uint8_t addtsPresent;
+	tSirAddtsReqInfo addts;
+	tSirMacQosCapabilityStaIE capability;
+} tDphQosParams;
+
+/* Queue attribute structure */
+typedef struct sDphQueueAttr {
+	uint16_t valid:1;
+	uint16_t seqNum:12;
+	uint16_t ackPolicy:2;
+	uint16_t rsvd:1;
+} tDphQueueAttr, *tpDphQueueAttr;
+
+/**
+ * struct parsed_ies: Parsed IE's of BSS capability
+ * @ht_caps: HT caps IE
+ * @vht_caps: VHT caps IE
+ * @ht_operation: HT operation IE
+ * @vht_operation: VHT operation IE
+ * @hs20vendor_ie: HS2.0 vendor IE
+ *
+ * This structure holds the parsed IE of connected BSS
+ * and this is not the intersection of BSS and STA
+ * capability. For example, if BSS supports 80 MHz
+ * and STA connects to BSS in 20 MHz, this structure
+ * holds 80 MHz as peer capability.
+ */
+struct parsed_ies {
+	tDot11fIEHTCaps ht_caps;
+	tDot11fIEVHTCaps vht_caps;
+	tDot11fIEHTInfo ht_operation;
+	tDot11fIEVHTOperation vht_operation;
+	tDot11fIEhs20vendor_ie hs20vendor_ie;
+};
+
+/* STA state node */
+typedef struct sDphHashNode {
+	/*
+	 * BYTE 0
+	 * HASH ENTRY FIELDS NOT NEEDED IN HAL.
+	 * This STA valid or not
+	 */
+	uint8_t valid:1;
+	uint8_t encPolicy:3;
+	uint8_t defaultKey:1;
+	uint8_t defaultKeyId:2;
+	uint8_t qosMode:1;
+	/* BYTE 1 */
+	uint8_t erpEnabled:1;
+	/* This has been added to the dph hash table */
+	uint8_t added:1;
+	uint8_t linkTestOn:1;
+	uint8_t shortPreambleEnabled:1;
+	uint8_t shortSlotTimeEnabled:1;
+	uint8_t stopTx:1;
+	/* set if both ap and sta are wme capable */
+	uint8_t wmeEnabled:1;
+	/* set if both ap and sta are 11e capable */
+	uint8_t lleEnabled:1;
+	/* BYTE 2 */
+	/* set if both ap and sta are wsm capable */
+	uint8_t wsmEnabled:1;
+	/* station gave version info */
+	uint8_t versionPresent:1;
+	/* allow bursting regardless of qosMode */
+	uint8_t burstEnableForce:1;
+	uint8_t staAuthenticated:1;
+	uint8_t fAniCount:1;
+	uint8_t rmfEnabled:1;
+	/* Number of Tim to wait if the STA doesn't respond / fetch data */
+	uint8_t timWaitCount;
+	/* Fragmentation size */
+	uint16_t fragSize;
+	/* Taurus capabilities */
+	uint16_t baPolicyFlag;  /* BA Policy for each TID. */
+	/* LIM state */
+	tLimMlmStaContext mlmStaContext;
+	/* number of consecutive TIMs sent without response */
+	uint8_t numTimSent;
+	/* Number of Successful MPDU's being sent */
+	uint32_t curTxMpduCnt;
+	/* qos parameter info */
+	tDphQosParams qos;
+	/* station version info - valid only if versionPresent is set */
+	tSirMacPropVersion version;
+#ifdef PLM_WDS
+	uint8_t wdsIndex;
+	uint8_t wdsPeerBeaconSeen;
+#endif
+	/*
+	 * All the legacy and airgo supported rates.
+	 */
+	tSirSupportedRates supportedRates;
+	/* MIMO Power Save */
+	tSirMacHTMIMOPowerSaveState htMIMOPSState;
+	uint8_t htGreenfield:1;
+	uint8_t htShortGI40Mhz:1;
+	uint8_t htShortGI20Mhz:1;
+	/* DSSS/CCK at 40 MHz: Enabled 1 or Disabled */
+	uint8_t htDsssCckRate40MHzSupport:1;
+	/* L-SIG TXOP Protection used only if peer support available */
+	uint8_t htLsigTXOPProtection:1;
+	/*
+	 * A-MPDU Density
+	 * 000 - No restriction
+	 * 001 - 1/8 usec
+	 * 010 - 1/4 usec
+	 * 011 - 1/2 usec
+	 * 100 - 1 usec
+	 * 101 - 2 usec
+	 * 110 - 4 usec
+	 * 111 - 8 usec
+	 */
+	uint8_t htAMpduDensity:3;
+	/* Set to 0 for 3839 octets */
+	/* Set to 1 for 7935 octets */
+	uint8_t htMaxAmsduLength;
+	/* */
+	/* Maximum Rx A-MPDU factor */
+	uint8_t htMaxRxAMpduFactor:3;
+	/*
+	 * Recommended Tx Width Set
+	 * 0 - use 20 MHz channel (control channel)
+	 * 1 - use 40 Mhz channel
+	 */
+	uint8_t htSupportedChannelWidthSet:1;
+	uint8_t htSecondaryChannelOffset:2;
+	uint8_t rsvd1:2;
+	/* DPH HASH ENTRY FIELDS NEEDED IN HAL ONLY */
+	uint8_t dpuSig:4;       /* DPU signiture */
+	uint8_t staSig:4;       /* STA signature */
+	uint16_t bssId;         /* BSSID */
+	uint16_t assocId;       /* Association ID */
+	/* This is the real sta index generated by HAL */
+	uint16_t staIndex;
+	uint8_t staAddr[6];
+	uint8_t staType;
+
+	uint8_t vhtSupportedChannelWidthSet;
+	uint8_t vhtSupportedRxNss;
+	uint8_t vhtBeamFormerCapable;
+	uint8_t vht_su_bfee_capable;
+#ifdef WLAN_FEATURE_11W
+	TX_TIMER pmfSaQueryTimer;
+	uint16_t pmfSaQueryCurrentTransId;
+	uint16_t pmfSaQueryStartTransId;
+	uint8_t pmfSaQueryState;
+	uint8_t pmfSaQueryRetryCount;
+	uint8_t proct_deauh_disassoc_cnt;
+#endif
+	uint8_t htLdpcCapable;
+	uint8_t vhtLdpcCapable;
+#ifdef FEATURE_WLAN_TDLS
+	uint16_t ht_caps;
+	uint32_t vht_caps;
+#endif
+	uint8_t timingMeasCap;
+	/* key installed for this STA or not in the firmware */
+	uint8_t is_key_installed;
+	uint8_t is_disassoc_deauth_in_progress;
+	qdf_time_t last_assoc_received_time;
+	qdf_time_t last_disassoc_deauth_received_time;
+
+	uint8_t nss;
+	int8_t del_sta_ctx_rssi;
+	bool sta_deletion_in_progress;
+	/* Flag indicating connected STA doesn't support ECSA */
+	uint8_t non_ecsa_capable;
+	struct parsed_ies parsed_ies;
+
+#ifdef WLAN_FEATURE_11AX
+	tDot11fIEhe_cap he_config;
+#endif
+
+	/*
+	 * When a station with already an existing dph entry tries to
+	 * associate again, the old dph entry will be zeroed out except
+	 * for the next pointer. The next pointer must be defined at the
+	 * end of the structure.
+	 */
+	struct sDphHashNode *next;
+} tDphHashNode, *tpDphHashNode;
+
+#include "dph_hash_table.h"
+
+/* ------------------------------------------------------------------- */
+typedef struct sAniSirDph {
+	/* The hash table object */
+	dphHashTableClass dphHashTable;
+} tAniSirDph, *tpAniSirDph;
+
+#endif
diff --git a/core/mac/src/include/parser_api.h b/core/mac/src/include/parser_api.h
new file mode 100644
index 0000000..a063ad9
--- /dev/null
+++ b/core/mac/src/include/parser_api.h
@@ -0,0 +1,1264 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file parser_api.h contains the definitions used
+ * for parsing received 802.11 frames
+ * Author:        Chandra Modumudi
+ * Date:          02/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __PARSE_H__
+#define __PARSE_H__
+
+#include <stdarg.h>
+#include "sir_mac_prop_exts.h"
+#include "dot11f.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+
+#define COUNTRY_STRING_LENGTH    (3)
+#define COUNTRY_INFO_MAX_CHANNEL (84)
+#define MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE (COUNTRY_STRING_LENGTH * \
+						COUNTRY_INFO_MAX_CHANNEL)
+#define HIGHEST_24GHZ_CHANNEL_NUM  (14)
+
+#define IS_24G_CH(__chNum) ((__chNum > 0) && (__chNum < 15))
+#define IS_5G_CH(__chNum) ((__chNum >= 36) && (__chNum <= 165))
+#define IS_2X2_CHAIN(__chain) ((__chain & 0x3) == 0x3)
+#define DISABLE_NSS2_MCS 0xC
+#define VHT_1x1_MCS9_MAP 0x2
+#define VHT_2x2_MCS9_MAP 0xA
+#define VHT_1x1_MCS8_VAL 0xFFFD
+#define VHT_2x2_MCS8_VAL 0xFFF5
+#define VHT_1x1_MCS_MASK 0x3
+#define VHT_2x2_MCS_MASK 0xF
+#define DISABLE_VHT_MCS_9(mcs, nss) \
+	(mcs = (nss > 1) ? VHT_2x2_MCS8_VAL : VHT_1x1_MCS8_VAL)
+
+#define NSS_1x1_MODE 1
+#define NSS_2x2_MODE 2
+#define MBO_IE_ASSOC_DISALLOWED_SUBATTR_ID 0x04
+
+/* QCN IE definitions */
+#define QCN_IE_HDR_LEN     6
+
+#define QCN_IE_VERSION_SUBATTR_ID        1
+#define QCN_IE_VERSION_SUBATTR_DATA_LEN  2
+#define QCN_IE_VERSION_SUBATTR_LEN       4
+#define QCN_IE_VERSION_SUPPORTED    1
+#define QCN_IE_SUBVERSION_SUPPORTED 0
+
+#define SIZE_OF_FIXED_PARAM 12
+#define SIZE_OF_TAG_PARAM_NUM 1
+#define SIZE_OF_TAG_PARAM_LEN 1
+#define RSNIEID 0x30
+#define RSNIE_CAPABILITY_LEN 2
+#define DEFAULT_RSNIE_CAP_VAL 0x00
+
+#define SIZE_MASK 0x7FFF
+#define FIXED_MASK 0x8000
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+#define QCOM_VENDOR_IE_MCC_AVOID_CH 0x01
+
+struct sAvoidChannelIE {
+	/* following must be 0xDD (221) */
+	uint8_t tag_number;
+	uint8_t length;
+	/* following must be 00-A0-C6 */
+	uint8_t oui[3];
+	/* following must be 0x01 */
+	uint8_t type;
+	uint8_t channel;
+};
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+typedef struct sSirCountryInformation {
+	uint8_t countryString[COUNTRY_STRING_LENGTH];
+	uint8_t numIntervals;   /* number of channel intervals */
+	struct channelPowerLim {
+		uint8_t channelNumber;
+		uint8_t numChannel;
+		uint8_t maxTransmitPower;
+	} channelTransmitPower[COUNTRY_INFO_MAX_CHANNEL];
+} tSirCountryInformation, *tpSirCountryInformation;
+
+typedef struct sSirQCNIE {
+	bool    is_present;
+	uint8_t version;
+	uint8_t sub_version;
+} tSirQCNIE, *tpSirQCNIE;
+
+#ifdef WLAN_FEATURE_FILS_SK
+#define SIR_MAX_IDENTIFIER_CNT 7
+#define SIR_CACHE_IDENTIFIER_LEN 2
+#define SIR_HESSID_LEN 6
+#define SIR_MAX_KEY_CNT 7
+#define SIR_MAX_KEY_LEN 48
+#define SIR_FILS_IND_ELEM_OFFSET 2
+/*
+ * struct public_key_identifier: structure for public key identifier
+ * present in fils indication element
+ * @is_present: if Key info is present
+ * @key_cnt:  number of keys present
+ * @key_type: type of key used
+ * @length: length of key
+ * @key: key data
+ */
+struct public_key_identifier {
+	bool is_present;
+	uint8_t key_cnt;
+	uint8_t key_type;
+	uint8_t length;
+	uint8_t key[SIR_MAX_KEY_CNT][SIR_MAX_KEY_LEN];
+};
+
+/*
+ * struct fils_cache_identifier: structure for fils cache identifier
+ * present in fils indication element
+ * @is_present: if cache identifier is present
+ * @identifier: cache identifier
+ */
+struct fils_cache_identifier {
+	bool is_present;
+	uint8_t identifier[SIR_CACHE_IDENTIFIER_LEN];
+};
+
+/*
+ * struct fils_hessid: structure for fils hessid
+ * present in fils indication element
+ * @is_present: if hessid info is present
+ * @hessid: hessid data
+ */
+struct fils_hessid {
+	bool is_present;
+	uint8_t hessid[SIR_HESSID_LEN];
+};
+
+/*
+ * struct fils_realm_identifier: structure for fils_realm_identifier
+ * present in fils indication element
+ * @is_present: if realm info is present
+ * @realm_cnt: realm count
+ * @realm: realm data
+ */
+struct fils_realm_identifier {
+	bool is_present;
+	uint8_t realm_cnt;
+	uint8_t realm[SIR_MAX_REALM_COUNT][SIR_REALM_LEN];
+};
+
+/*
+ * struct sir_fils_indication: structure for fils indication element
+ * @is_present: if indication element is present
+ * @is_ip_config_supported: if IP config is supported
+ * @is_fils_sk_auth_supported: if fils sk suppprted
+ * @is_fils_sk_auth_pfs_supported: if fils sk with pfs supported
+ * @is_pk_auth_supported: if fils public key supported
+ * @cache_identifier: fils cache idenfier info
+ * @hessid: fils hessid info
+ * @realm_identifier: fils realm info
+ * @key_identifier: fils key identifier info
+ */
+struct sir_fils_indication {
+	bool is_present;
+	uint8_t is_ip_config_supported;
+	uint8_t is_fils_sk_auth_supported;
+	uint8_t is_fils_sk_auth_pfs_supported;
+	uint8_t is_pk_auth_supported;
+	struct fils_cache_identifier cache_identifier;
+	struct fils_hessid hessid;
+	struct fils_realm_identifier realm_identifier;
+	struct public_key_identifier key_identifier;
+};
+#endif
+
+/* Structure common to Beacons & Probe Responses */
+typedef struct sSirProbeRespBeacon {
+	tSirMacTimeStamp timeStamp;
+	uint16_t beaconInterval;
+	tSirMacCapabilityInfo capabilityInfo;
+
+	tSirMacSSid ssId;
+	tSirMacRateSet supportedRates;
+	tSirMacRateSet extendedRates;
+	tSirMacChanNum channelNumber;
+	tSirMacCfParamSet cfParamSet;
+	tSirMacTim tim;
+	tSirMacEdcaParamSetIE edcaParams;
+	tSirMacQosCapabilityIE qosCapability;
+
+	tSirCountryInformation countryInfoParam;
+	tSirMacWpaInfo wpa;
+	tSirMacRsnInfo rsn;
+
+	tSirMacErpInfo erpIEInfo;
+
+	tSirPropIEStruct propIEinfo;
+	tDot11fIEPowerConstraints localPowerConstraint;
+	tDot11fIETPCReport tpcReport;
+	tDot11fIEChanSwitchAnn channelSwitchIE;
+	tDot11fIEsec_chan_offset_ele sec_chan_offset;
+	tDot11fIEext_chan_switch_ann ext_chan_switch;
+	tDot11fIESuppOperatingClasses supp_operating_classes;
+	tSirMacAddr bssid;
+	tDot11fIEQuiet quietIE;
+	tDot11fIEHTCaps HTCaps;
+	tDot11fIEHTInfo HTInfo;
+	tDot11fIEP2PProbeRes P2PProbeRes;
+	uint8_t mdie[SIR_MDIE_SIZE];
+#ifdef FEATURE_WLAN_ESE
+	tDot11fIEESETxmitPower eseTxPwr;
+	tDot11fIEQBSSLoad QBSSLoad;
+#endif
+	uint8_t ssidPresent;
+	uint8_t suppRatesPresent;
+	uint8_t extendedRatesPresent;
+	uint8_t supp_operating_class_present;
+	uint8_t cfPresent;
+	uint8_t dsParamsPresent;
+	uint8_t timPresent;
+
+	uint8_t edcaPresent;
+	uint8_t qosCapabilityPresent;
+	uint8_t wmeEdcaPresent;
+	uint8_t wmeInfoPresent;
+	uint8_t wsmCapablePresent;
+
+	uint8_t countryInfoPresent;
+	uint8_t wpaPresent;
+	uint8_t rsnPresent;
+	uint8_t erpPresent;
+	uint8_t channelSwitchPresent;
+	uint8_t sec_chan_offset_present;
+	uint8_t ext_chan_switch_present;
+	uint8_t quietIEPresent;
+	uint8_t tpcReportPresent;
+	uint8_t powerConstraintPresent;
+
+	uint8_t mdiePresent;
+
+	tDot11fIEVHTCaps VHTCaps;
+	tDot11fIEVHTOperation VHTOperation;
+	tDot11fIEVHTExtBssLoad VHTExtBssLoad;
+	tDot11fIEExtCap ext_cap;
+	tDot11fIEOperatingMode OperatingMode;
+	uint8_t WiderBWChanSwitchAnnPresent;
+	tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
+	uint8_t Vendor1IEPresent;
+	tDot11fIEvendor_vht_ie vendor_vht_ie;
+	uint8_t Vendor3IEPresent;
+	tDot11fIEhs20vendor_ie hs20vendor_ie;
+	tDot11fIEIBSSParams IBSSParams;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	tDot11fIEQComVendorIE   AvoidChannelIE;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+#ifdef FEATURE_WLAN_ESE
+	uint8_t    is_ese_ver_ie_present;
+#endif
+	tDot11fIEOBSSScanParameters obss_scanparams;
+	bool MBO_IE_present;
+	uint8_t MBO_capability;
+	bool assoc_disallowed;
+	uint8_t assoc_disallowed_reason;
+	tSirQCNIE QCN_IE;
+	tDot11fIEhe_cap he_cap;
+	tDot11fIEhe_op he_op;
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+	tDot11fIEbss_color_change vendor_he_bss_color_change;
+#endif
+#ifdef WLAN_FEATURE_FILS_SK
+	struct sir_fils_indication fils_ind;
+#endif
+} tSirProbeRespBeacon, *tpSirProbeRespBeacon;
+
+/* probe Request structure */
+typedef struct sSirProbeReq {
+	tSirMacSSid ssId;
+	tSirMacRateSet supportedRates;
+	tSirMacRateSet extendedRates;
+	tDot11fIEWscProbeReq probeReqWscIeInfo;
+	tDot11fIEHTCaps HTCaps;
+	uint8_t ssidPresent;
+	uint8_t suppRatesPresent;
+	uint8_t extendedRatesPresent;
+	uint8_t wscIePresent;
+	uint8_t p2pIePresent;
+	tDot11fIEVHTCaps VHTCaps;
+	tDot11fIEhe_cap he_cap;
+} tSirProbeReq, *tpSirProbeReq;
+
+/* / Association Request structure (one day to be replaced by */
+/* / tDot11fAssocRequest) */
+typedef struct sSirAssocReq {
+
+	tSirMacCapabilityInfo capabilityInfo;
+	uint16_t listenInterval;
+	tSirMacAddr currentApAddr;      /* only in reassoc frames */
+	tSirMacSSid ssId;
+	tSirMacRateSet supportedRates;
+	tSirMacRateSet extendedRates;
+
+	tSirAddtsReqInfo addtsReq;
+	tSirMacQosCapabilityStaIE qosCapability;
+
+	tSirMacWapiInfo wapi;
+	tSirMacWpaInfo wpa;
+	tSirMacRsnInfo rsn;
+	tSirAddie addIE;
+
+	tSirPropIEStruct propIEinfo;
+	tSirMacPowerCapabilityIE powerCapability;
+	tSirMacSupportedChannelIE supportedChannels;
+	tDot11fIEHTCaps HTCaps;
+	tDot11fIEWMMInfoStation WMMInfoStation;
+	/* / This is set if the frame is a reassoc request: */
+	uint8_t reassocRequest;
+	uint8_t ssidPresent;
+	uint8_t suppRatesPresent;
+	uint8_t extendedRatesPresent;
+
+	uint8_t wmeInfoPresent;
+	uint8_t qosCapabilityPresent;
+	uint8_t addtsPresent;
+	uint8_t wsmCapablePresent;
+
+	uint8_t wapiPresent;
+	uint8_t wpaPresent;
+	uint8_t rsnPresent;
+	uint8_t addIEPresent;
+
+	uint8_t powerCapabilityPresent;
+	uint8_t supportedChannelsPresent;
+	/* keeping copy of association request received, this is
+	   required for indicating the frame to upper layers */
+	uint32_t assocReqFrameLength;
+	uint8_t *assocReqFrame;
+	tDot11fIEVHTCaps VHTCaps;
+	tDot11fIEOperatingMode operMode;
+	tDot11fIEExtCap ExtCap;
+	tDot11fIEvendor_vht_ie vendor_vht_ie;
+	tDot11fIEhs20vendor_ie hs20vendor_ie;
+	tDot11fIEhe_cap he_cap;
+} tSirAssocReq, *tpSirAssocReq;
+
+/* / Association Response structure (one day to be replaced by */
+/* / tDot11fAssocRequest) */
+typedef struct sSirAssocRsp {
+
+	tSirMacCapabilityInfo capabilityInfo;
+	uint16_t aid;
+	uint16_t statusCode;
+	tSirMacRateSet supportedRates;
+	tSirMacRateSet extendedRates;
+	tSirPropIEStruct propIEinfo;
+	tSirMacEdcaParamSetIE edca;
+	tSirAddtsRspInfo addtsRsp;
+	tDot11fIEHTCaps HTCaps;
+	tDot11fIEHTInfo HTInfo;
+	tDot11fIEFTInfo FTInfo;
+	uint8_t mdie[SIR_MDIE_SIZE];
+	uint8_t num_RICData;
+	tDot11fIERICDataDesc RICData[2];
+
+#ifdef FEATURE_WLAN_ESE
+	uint8_t num_tspecs;
+	tDot11fIEWMMTSPEC TSPECInfo[SIR_ESE_MAX_TSPEC_IES];
+	tSirMacESETSMIE tsmIE;
+#endif
+
+	uint8_t suppRatesPresent;
+	uint8_t extendedRatesPresent;
+
+	uint8_t edcaPresent;
+	uint8_t wmeEdcaPresent;
+	uint8_t addtsPresent;
+	uint8_t wsmCapablePresent;
+	uint8_t ftinfoPresent;
+	uint8_t mdiePresent;
+	uint8_t ricPresent;
+#ifdef FEATURE_WLAN_ESE
+	uint8_t tspecPresent;
+	uint8_t tsmPresent;
+#endif
+	tDot11fIEVHTCaps VHTCaps;
+	tDot11fIEVHTOperation VHTOperation;
+	tDot11fIEExtCap ExtCap;
+	tSirQosMapSet QosMapSet;
+#ifdef WLAN_FEATURE_11W
+	tDot11fIETimeoutInterval TimeoutInterval;
+#endif
+	tDot11fIEvendor_vht_ie vendor_vht_ie;
+	tDot11fIEOBSSScanParameters obss_scanparams;
+	tDot11fTLVrssi_assoc_rej rssi_assoc_rej;
+	tSirQCNIE QCN_IE;
+	tDot11fIEhe_cap he_cap;
+	tDot11fIEhe_op he_op;
+	bool mu_edca_present;
+	tSirMacEdcaParamSetIE mu_edca;
+#ifdef WLAN_FEATURE_FILS_SK
+	tDot11fIEfils_session fils_session;
+	tDot11fIEfils_key_confirmation fils_key_auth;
+	tDot11fIEfils_kde fils_kde;
+	struct qdf_mac_addr dst_mac;
+	struct qdf_mac_addr src_mac;
+	uint16_t hlp_data_len;
+	uint8_t hlp_data[FILS_MAX_HLP_DATA_LEN];
+#endif
+} tSirAssocRsp, *tpSirAssocRsp;
+
+#ifdef FEATURE_WLAN_ESE
+/* Structure to hold ESE Beacon report mandatory IEs */
+typedef struct sSirEseBcnReportMandatoryIe {
+	tSirMacSSid ssId;
+	tSirMacRateSet supportedRates;
+	tSirMacFHParamSet fhParamSet;
+	tSirMacDsParamSetIE dsParamSet;
+	tSirMacCfParamSet cfParamSet;
+	tSirMacIBSSParams ibssParamSet;
+	tSirMacTim tim;
+	tSirMacRRMEnabledCap rmEnabledCapabilities;
+
+	uint8_t ssidPresent;
+	uint8_t suppRatesPresent;
+	uint8_t fhParamPresent;
+	uint8_t dsParamsPresent;
+	uint8_t cfPresent;
+	uint8_t ibssParamPresent;
+	uint8_t timPresent;
+	uint8_t rrmPresent;
+} tSirEseBcnReportMandatoryIe, *tpSirEseBcnReportMandatoryIe;
+#endif /* FEATURE_WLAN_ESE */
+
+/**
+ * struct s_ext_cap - holds bitfields of extended capability IE
+ *
+ * s_ext_cap holds bitfields of extended capability IE. In dot11f files
+ * extended capability IE information is stored as an array of bytes.
+ * This structure is used to encode/decode the byte array present in
+ * dot11f IE structure.
+ */
+
+struct s_ext_cap {
+	uint8_t bss_coexist_mgmt_support:1;
+	uint8_t reserved1:1;
+	uint8_t ext_chan_switch:1;
+	uint8_t reserved2:1;
+	uint8_t psmp_cap:1;
+	uint8_t reserved3:1;
+	uint8_t spsmp_cap:1;
+	uint8_t event:1;
+	uint8_t diagnostics:1;
+	uint8_t multi_diagnostics:1;
+	uint8_t loc_tracking:1;
+	uint8_t fms:1;
+	uint8_t proxy_arp_service:1;
+	uint8_t co_loc_intf_reporting:1;
+	uint8_t civic_loc:1;
+	uint8_t geospatial_loc:1;
+	uint8_t tfs:1;
+	uint8_t wnm_sleep_mode:1;
+	uint8_t tim_broadcast:1;
+	uint8_t bss_transition:1;
+	uint8_t qos_traffic_cap:1;
+	uint8_t ac_sta_cnt:1;
+	uint8_t multi_bssid:1;
+	uint8_t timing_meas:1;
+	uint8_t chan_usage:1;
+	uint8_t ssid_list:1;
+	uint8_t dms:1;
+	uint8_t utctsf_offset:1;
+	uint8_t tdls_peer_uapsd_buffer_sta:1;
+	uint8_t tdls_peer_psm_supp:1;
+	uint8_t tdls_channel_switching:1;
+	uint8_t interworking_service:1;
+	uint8_t qos_map:1;
+	uint8_t ebr:1;
+	uint8_t sspn_interface:1;
+	uint8_t reserved4:1;
+	uint8_t msg_cf_cap:1;
+	uint8_t tdls_support:1;
+	uint8_t tdls_prohibited:1;
+	uint8_t tdls_chan_swit_prohibited:1;
+	uint8_t reject_unadmitted_traffic:1;
+	uint8_t service_interval_granularity:3;
+	uint8_t identifier_loc:1;
+	uint8_t uapsd_coexistence:1;
+	uint8_t wnm_notification:1;
+	uint8_t qa_bcapbility:1;
+	uint8_t utf8_ssid:1;
+	uint8_t qmf_activated:1;
+	uint8_t qm_frecon_act:1;
+	uint8_t robust_av_streaming:1;
+	uint8_t advanced_gcr:1;
+	uint8_t mesh_gcr:1;
+	uint8_t scs:1;
+	uint8_t q_load_report:1;
+	uint8_t alternate_edca:1;
+	uint8_t unprot_txo_pneg:1;
+	uint8_t prot_txo_pneg:1;
+	uint8_t reserved6:1;
+	uint8_t prot_q_load_report:1;
+	uint8_t tdls_wider_bw:1;
+	uint8_t oper_mode_notification:1;
+	uint8_t max_num_of_msdu_bit1:1;
+	uint8_t max_num_of_msdu_bit2:1;
+	uint8_t chan_sch_mgmt:1;
+	uint8_t geo_db_inband_en_signal:1;
+	uint8_t nw_chan_control:1;
+	uint8_t white_space_map:1;
+	uint8_t chan_avail_query:1;
+	uint8_t fine_time_meas_responder:1;
+	uint8_t fine_time_meas_initiator:1;
+	uint8_t fils_capability:1;
+	uint8_t ext_spectrum_management:1;
+	uint8_t future_channel_guidance:1;
+	uint8_t reserved7:2;
+	uint8_t twt_requestor_support:1;
+	uint8_t twt_responder_support:1;
+};
+
+uint8_t sirIsPropCapabilityEnabled(struct mac_context *pMac, uint32_t bitnum);
+
+#define CFG_GET_INT(nStatus, pMac, nItem, cfg)  do { \
+		(nStatus) = wlan_cfg_get_int((pMac), (nItem), &(cfg)); \
+		if (QDF_STATUS_SUCCESS != (nStatus)) { \
+			pe_err("Failed to retrieve nItem from CFG status: %d", (nStatus)); \
+			return nStatus; \
+		} \
+} while (0)
+
+#define CFG_GET_INT_NO_STATUS(nStatus, pMac, nItem, cfg) do { \
+		(nStatus) = wlan_cfg_get_int((pMac), (nItem), &(cfg)); \
+		if (QDF_STATUS_SUCCESS != (nStatus)) { \
+			pe_err("Failed to retrieve nItem from CFG status: %d", (nStatus)); \
+			return; \
+		} \
+} while (0)
+
+#define CFG_GET_STR(nStatus, pMac, nItem, cfg, nCfg, nMaxCfg) do { \
+		(nCfg) = (nMaxCfg); \
+		(nStatus) = wlan_cfg_get_str((pMac), (nItem), (cfg), &(nCfg)); \
+		if (QDF_STATUS_SUCCESS != (nStatus)) { \
+			pe_err("Failed to retrieve nItem from CFG status: %d", (nStatus)); \
+			return nStatus; \
+		} \
+} while (0)
+
+#define CFG_GET_STR_NO_STATUS(nStatus, pMac, nItem, cfg, nCfg, nMaxCfg) do { \
+		(nCfg) = (nMaxCfg); \
+		(nStatus) = wlan_cfg_get_str((pMac), (nItem), (cfg), &(nCfg)); \
+		if (QDF_STATUS_SUCCESS != (nStatus)) { \
+			pe_err("Failed to retrieve nItem from CFG status: %d", (nStatus)); \
+			return; \
+		} \
+} while (0)
+
+void swap_bit_field16(uint16_t in, uint16_t *out);
+
+/* Currently implemented as "shims" between callers & the new framesc- */
+/* generated code: */
+
+QDF_STATUS
+sir_convert_probe_req_frame2_struct(struct mac_context *pMac,
+				uint8_t *frame, uint32_t len,
+				tpSirProbeReq probe);
+
+QDF_STATUS
+sir_convert_probe_frame2_struct(struct mac_context *pMac, uint8_t *frame,
+				uint32_t len, tpSirProbeRespBeacon probe);
+
+QDF_STATUS
+sir_convert_assoc_req_frame2_struct(struct mac_context *pMac,
+				uint8_t *frame, uint32_t len,
+				tpSirAssocReq assoc);
+
+QDF_STATUS
+sir_convert_assoc_resp_frame2_struct(struct mac_context *pMac,
+				tpPESession session_entry,
+				uint8_t *frame, uint32_t len,
+				tpSirAssocRsp assoc);
+
+QDF_STATUS
+sir_convert_reassoc_req_frame2_struct(struct mac_context *pMac,
+				uint8_t *frame, uint32_t len,
+				tpSirAssocReq assoc);
+
+QDF_STATUS
+sir_parse_beacon_ie(struct mac_context *pMac,
+		tpSirProbeRespBeacon pBeaconStruct,
+		uint8_t *pPayload, uint32_t payloadLength);
+
+QDF_STATUS
+sir_convert_beacon_frame2_struct(struct mac_context *pMac,
+				uint8_t *pBeaconFrame,
+				tpSirProbeRespBeacon pBeaconStruct);
+
+QDF_STATUS
+sir_convert_auth_frame2_struct(struct mac_context *pMac,
+			uint8_t *frame, uint32_t len,
+			tpSirMacAuthFrameBody auth);
+
+QDF_STATUS
+sir_convert_addts_req2_struct(struct mac_context *pMac,
+			uint8_t *frame, uint32_t len,
+			tSirAddtsReqInfo *addTs);
+
+QDF_STATUS
+sir_convert_addts_rsp2_struct(struct mac_context *pMac,
+			uint8_t *frame, uint32_t len,
+			tSirAddtsRspInfo *addts);
+
+QDF_STATUS
+sir_convert_delts_req2_struct(struct mac_context *pMac,
+			uint8_t *frame, uint32_t len,
+			tSirDeltsReqInfo *delTs);
+QDF_STATUS
+sir_convert_qos_map_configure_frame2_struct(tpAniSirGlobal pMac,
+					uint8_t *pFrame, uint32_t nFrame,
+					tSirQosMapSet *pQosMapSet);
+
+#ifdef ANI_SUPPORT_11H
+QDF_STATUS
+sir_convert_tpc_req_frame2_struct(struct mac_context *, uint8_t *,
+				tpSirMacTpcReqActionFrame, uint32_t);
+
+QDF_STATUS
+sir_convert_meas_req_frame2_struct(struct mac_context *, uint8_t *,
+				tpSirMacMeasReqActionFrame, uint32_t);
+#endif
+
+/**
+ * \brief Populated a tDot11fFfCapabilities
+ *
+ * \sa PopulatedDot11fCapabilities2
+ *
+ *
+ * \param pMac Pointer to the global MAC data structure
+ *
+ * \param pDot11f Address of a tDot11fFfCapabilities to be filled in
+ *
+ *
+ * \note If SIR_MAC_PROP_CAPABILITY_11EQOS is enabled, we'll clear the QOS
+ * bit in pDot11f
+ *
+ *
+ */
+
+QDF_STATUS
+populate_dot11f_capabilities(tpAniSirGlobal pMac,
+			tDot11fFfCapabilities *pDot11f,
+			tpPESession psessionEntry);
+
+/**
+ * \brief Populated a tDot11fFfCapabilities
+ *
+ * \sa PopulatedDot11fCapabilities2
+ *
+ *
+ * \param pMac Pointer to the global MAC data structure
+ *
+ * \param pDot11f Address of a tDot11fFfCapabilities to be filled in
+ *
+ * \param pSta Pointer to a tDphHashNode representing a peer
+ *
+ *
+ * \note If SIR_MAC_PROP_CAPABILITY_11EQOS is enabled on our peer, we'll
+ * clear the QOS bit in pDot11f
+ *
+ *
+ */
+
+struct sDphHashNode;
+
+QDF_STATUS
+populate_dot11f_capabilities2(tpAniSirGlobal pMac,
+			tDot11fFfCapabilities *pDot11f,
+			struct sDphHashNode *pSta,
+			tpPESession psessionEntry);
+
+/* / Populate a tDot11fIEChanSwitchAnn */
+void
+populate_dot11f_chan_switch_ann(tpAniSirGlobal pMac,
+				tDot11fIEChanSwitchAnn *pDot11f,
+				tpPESession psessionEntry);
+
+void
+populate_dot_11_f_ext_chann_switch_ann(tpAniSirGlobal mac_ptr,
+				tDot11fIEext_chan_switch_ann *dot_11_ptr,
+				tpPESession session_entry);
+
+/* / Populate a tDot11fIEChannelSwitchWrapper */
+void
+populate_dot11f_chan_switch_wrapper(tpAniSirGlobal pMac,
+				tDot11fIEChannelSwitchWrapper *pDot11f,
+				tpPESession psessionEntry);
+
+/* / Populate a tDot11fIECountry */
+QDF_STATUS
+populate_dot11f_country(tpAniSirGlobal pMac,
+			tDot11fIECountry *pDot11f, tpPESession psessionEntry);
+
+/* Populated a populate_dot11f_ds_params */
+QDF_STATUS
+populate_dot11f_ds_params(tpAniSirGlobal pMac,
+			tDot11fIEDSParams *pDot11f, uint8_t channel);
+
+/* / Populated a tDot11fIEEDCAParamSet */
+void
+populate_dot11f_edca_param_set(tpAniSirGlobal pMac,
+			tDot11fIEEDCAParamSet *pDot11f,
+			tpPESession psessionEntry);
+
+QDF_STATUS
+populate_dot11f_erp_info(tpAniSirGlobal pMac,
+			tDot11fIEERPInfo *pDot11f, tpPESession psessionEntry);
+
+QDF_STATUS
+populate_dot11f_ext_supp_rates(tpAniSirGlobal pMac,
+			uint8_t nChannelNum, tDot11fIEExtSuppRates *pDot11f,
+			tpPESession psessionEntry);
+
+/**
+ * populate_dot11f_beacon_report() - Populate the Beacon Report IE
+ * @pMac: Pointer to the global MAC context
+ * @pDot11f: Pointer to the measurement report structure
+ * @pBeaconReport: Pointer to the Beacon Report structure
+ * @last_beacon_report_params: Last Beacon Report indication params
+ *
+ * Return: Ret Status
+ */
+QDF_STATUS
+populate_dot11f_beacon_report(tpAniSirGlobal pMac,
+			tDot11fIEMeasurementReport *pDot11f,
+			tSirMacBeaconReport *pBeaconReport,
+			struct rrm_beacon_report_last_beacon_params
+			*last_beacon_report_params);
+
+/**
+ * \brief Populate a tDot11fIEExtSuppRates
+ *
+ *
+ * \param pMac Pointer to the global MAC data structure
+ *
+ * \param nChannelNum Channel on which the enclosing frame will be going out
+ *
+ * \param pDot11f Address of a tDot11fIEExtSuppRates struct to be filled in.
+ *
+ *
+ * This method is a NOP if the channel is greater than 14.
+ *
+ *
+ */
+
+QDF_STATUS
+populate_dot11f_ext_supp_rates1(tpAniSirGlobal pMac,
+				uint8_t nChannelNum,
+				tDot11fIEExtSuppRates *pDot11f);
+
+QDF_STATUS
+populate_dot11f_ht_caps(tpAniSirGlobal pMac,
+			tpPESession psessionEntry, tDot11fIEHTCaps *pDot11f);
+
+QDF_STATUS
+populate_dot11f_ht_info(tpAniSirGlobal pMac,
+			tDot11fIEHTInfo *pDot11f, tpPESession psessionEntry);
+
+void populate_dot11f_ibss_params(tpAniSirGlobal pMac,
+				tDot11fIEIBSSParams *pDot11f,
+				tpPESession psessionEntry);
+
+#ifdef ANI_SUPPORT_11H
+QDF_STATUS
+populate_dot11f_measurement_report0(tpAniSirGlobal pMac,
+				tpSirMacMeasReqActionFrame pReq,
+				tDot11fIEMeasurementReport *pDot11f);
+
+/* / Populate a tDot11fIEMeasurementReport when the report type is CCA */
+QDF_STATUS
+populate_dot11f_measurement_report1(tpAniSirGlobal pMac,
+				tpSirMacMeasReqActionFrame pReq,
+				tDot11fIEMeasurementReport *pDot11f);
+
+/* / Populate a tDot11fIEMeasurementReport when the report type is RPI Hist */
+QDF_STATUS
+populate_dot11f_measurement_report2(tpAniSirGlobal pMac,
+				tpSirMacMeasReqActionFrame pReq,
+				tDot11fIEMeasurementReport *pDot11f);
+#endif /* ANI_SUPPORT_11H */
+
+/* / Populate a tDot11fIEPowerCaps */
+void
+populate_dot11f_power_caps(tpAniSirGlobal pMac,
+			tDot11fIEPowerCaps *pCaps,
+			uint8_t nAssocType, tpPESession psessionEntry);
+
+/* / Populate a tDot11fIEPowerConstraints */
+QDF_STATUS
+populate_dot11f_power_constraints(tpAniSirGlobal pMac,
+				tDot11fIEPowerConstraints *pDot11f);
+
+void
+populate_dot11f_qos_caps_ap(tpAniSirGlobal pMac,
+			tDot11fIEQOSCapsAp *pDot11f,
+			tpPESession psessionEntry);
+
+void
+populate_dot11f_qos_caps_station(tpAniSirGlobal pMac, tpPESession session,
+				tDot11fIEQOSCapsStation *pDot11f);
+
+QDF_STATUS
+populate_dot11f_rsn(tpAniSirGlobal pMac,
+		tpSirRSNie pRsnIe, tDot11fIERSN *pDot11f);
+
+QDF_STATUS
+populate_dot11f_rsn_opaque(tpAniSirGlobal pMac,
+		tpSirRSNie pRsnIe, tDot11fIERSNOpaque *pDot11f);
+
+#if defined(FEATURE_WLAN_WAPI)
+
+QDF_STATUS
+populate_dot11f_wapi(tpAniSirGlobal pMac,
+		tpSirRSNie pRsnIe, tDot11fIEWAPI *pDot11f);
+
+QDF_STATUS populate_dot11f_wapi_opaque(tpAniSirGlobal pMac,
+					tpSirRSNie pRsnIe,
+					tDot11fIEWAPIOpaque *pDot11f);
+
+#endif /* defined(FEATURE_WLAN_WAPI) */
+
+/* / Populate a tDot11fIESSID given a tSirMacSSid */
+void
+populate_dot11f_ssid(tpAniSirGlobal pMac,
+		tSirMacSSid *pInternal, tDot11fIESSID *pDot11f);
+
+/* / Populate a tDot11fIESSID from CFG */
+QDF_STATUS populate_dot11f_ssid2(tpAniSirGlobal pMac,
+				tDot11fIESSID *pDot11f);
+
+/**
+ * \brief Populate a tDot11fIESchedule
+ *
+ * \sa populate_dot11f_wmm_schedule
+ *
+ *
+ * \param pSchedule Address of a tSirMacScheduleIE struct
+ *
+ * \param pDot11f Address of a tDot11fIESchedule to be filled in
+ *
+ *
+ */
+
+void
+populate_dot11f_schedule(tSirMacScheduleIE *pSchedule,
+			tDot11fIESchedule *pDot11f);
+
+void
+populate_dot11f_supp_channels(tpAniSirGlobal pMac,
+			tDot11fIESuppChannels *pDot11f,
+			uint8_t nAssocType, tpPESession psessionEntry);
+
+/**
+ * \brief Populated a tDot11fIESuppRates
+ *
+ *
+ * \param pMac Pointer to the global MAC data structure
+ *
+ * \param nChannelNum Channel the enclosing frame will be going out on; see
+ * below
+ *
+ * \param pDot11f Address of a tDot11fIESuppRates struct to be filled in.
+ *
+ *
+ * If nChannelNum is greater than 13, the supported rates will be
+ * WNI_CFG_SUPPORTED_RATES_11B.  If it is less than or equal to 13, the
+ * supported rates will be WNI_CFG_SUPPORTED_RATES_11A.  If nChannelNum is
+ * set to the sentinel value POPULATE_DOT11F_RATES_OPERATIONAL, the struct
+ * will be populated with WNI_CFG_OPERATIONAL_RATE_SET.
+ *
+ *
+ */
+
+#define POPULATE_DOT11F_RATES_OPERATIONAL (0xff)
+
+QDF_STATUS
+populate_dot11f_supp_rates(tpAniSirGlobal pMac,
+			uint8_t nChannelNum,
+			tDot11fIESuppRates *pDot11f, tpPESession);
+
+QDF_STATUS
+populate_dot11f_rates_tdls(tpAniSirGlobal p_mac,
+			tDot11fIESuppRates *p_supp_rates,
+			tDot11fIEExtSuppRates *p_ext_supp_rates,
+			uint8_t curr_oper_channel);
+
+QDF_STATUS populate_dot11f_tpc_report(tpAniSirGlobal pMac,
+					tDot11fIETPCReport *pDot11f,
+					tpPESession psessionEntry);
+
+/* / Populate a tDot11FfTSInfo */
+void populate_dot11f_ts_info(tSirMacTSInfo *pInfo, tDot11fFfTSInfo *pDot11f);
+
+void populate_dot11f_wmm(tpAniSirGlobal pMac,
+			tDot11fIEWMMInfoAp *pInfo,
+			tDot11fIEWMMParams *pParams,
+			tDot11fIEWMMCaps *pCaps, tpPESession psessionEntry);
+
+void populate_dot11f_wmm_caps(tDot11fIEWMMCaps *pCaps);
+
+#if defined(FEATURE_WLAN_ESE)
+/* Fill the ESE version IE */
+void populate_dot11f_ese_version(tDot11fIEESEVersion *pESEVersion);
+/* Fill the Radio Management Capability */
+void populate_dot11f_ese_rad_mgmt_cap(tDot11fIEESERadMgmtCap *pESERadMgmtCap);
+/* Fill the CCKM IE */
+QDF_STATUS populate_dot11f_ese_cckm_opaque(tpAniSirGlobal pMac,
+					tpSirCCKMie pCCKMie,
+					tDot11fIEESECckmOpaque *pDot11f);
+
+void populate_dot11_tsrsie(tpAniSirGlobal pMac,
+			tSirMacESETSRSIE *pOld,
+			tDot11fIEESETrafStrmRateSet *pDot11f,
+			uint8_t rate_length);
+void populate_dot11f_re_assoc_tspec(tpAniSirGlobal pMac,
+				tDot11fReAssocRequest *pReassoc,
+				tpPESession psessionEntry);
+QDF_STATUS
+sir_beacon_ie_ese_bcn_report(tpAniSirGlobal pMac,
+		uint8_t *pPayload, const uint32_t payloadLength,
+		uint8_t **outIeBuf, uint32_t *pOutIeLen);
+
+/**
+ * ese_populate_wmm_tspec() - Populates TSPEC info for
+ * reassoc
+ * @source: source structure
+ * @dest: destination structure
+ *
+ * This function copies TSPEC parameters from source
+ * structure to destination structure.
+ *
+ * Return: None
+ */
+void ese_populate_wmm_tspec(tSirMacTspecIE *source, ese_wmm_tspec_ie *dest);
+
+#endif
+
+void populate_dot11f_wmm_info_ap(tpAniSirGlobal pMac,
+				tDot11fIEWMMInfoAp *pInfo,
+				tpPESession psessionEntry);
+
+void populate_dot11f_wmm_info_station_per_session(tpAniSirGlobal pMac,
+					tpPESession psessionEntry,
+					tDot11fIEWMMInfoStation *pInfo);
+
+void populate_dot11f_wmm_params(tpAniSirGlobal pMac,
+				tDot11fIEWMMParams *pParams,
+				tpPESession psessionEntry);
+
+/**
+ * \brief Populate a tDot11fIEWMMSchedule
+ *
+ * \sa PopulatedDot11fSchedule
+ *
+ *
+ * \param pSchedule Address of a tSirMacScheduleIE struct
+ *
+ * \param pDot11f Address of a tDot11fIEWMMSchedule to be filled in
+ *
+ *
+ */
+
+void
+populate_dot11f_wmm_schedule(tSirMacScheduleIE *pSchedule,
+			tDot11fIEWMMSchedule *pDot11f);
+
+QDF_STATUS
+populate_dot11f_wpa(tpAniSirGlobal pMac,
+		tpSirRSNie pRsnIe, tDot11fIEWPA *pDot11f);
+
+QDF_STATUS
+populate_dot11f_wpa_opaque(tpAniSirGlobal pMac,
+			tpSirRSNie pRsnIe, tDot11fIEWPAOpaque *pDot11f);
+
+void populate_dot11f_tspec(tSirMacTspecIE *pOld, tDot11fIETSPEC *pDot11f);
+
+void populate_dot11f_wmmtspec(tSirMacTspecIE *pOld, tDot11fIEWMMTSPEC *pDot11f);
+
+QDF_STATUS
+populate_dot11f_tclas(tpAniSirGlobal pMac,
+		tSirTclasInfo *pOld, tDot11fIETCLAS *pDot11f);
+
+QDF_STATUS
+populate_dot11f_wmmtclas(tpAniSirGlobal pMac,
+			tSirTclasInfo *pOld, tDot11fIEWMMTCLAS *pDot11f);
+
+QDF_STATUS populate_dot11f_wsc(tpAniSirGlobal pMac,
+			tDot11fIEWscBeacon *pDot11f);
+
+QDF_STATUS populate_dot11f_wsc_registrar_info(tpAniSirGlobal pMac,
+						tDot11fIEWscBeacon *pDot11f);
+
+QDF_STATUS de_populate_dot11f_wsc_registrar_info(tpAniSirGlobal pMac,
+						tDot11fIEWscBeacon *pDot11f);
+
+QDF_STATUS populate_dot11f_probe_res_wpsi_es(tpAniSirGlobal pMac,
+						tDot11fIEWscProbeRes *pDot11f,
+						tpPESession psessionEntry);
+QDF_STATUS populate_dot11f_assoc_res_wpsi_es(tpAniSirGlobal pMac,
+						tDot11fIEWscAssocRes *pDot11f,
+						tpPESession psessionEntry);
+QDF_STATUS populate_dot11f_beacon_wpsi_es(tpAniSirGlobal pMac,
+					tDot11fIEWscBeacon *pDot11f,
+					tpPESession psessionEntry);
+
+QDF_STATUS populate_dot11f_wsc_in_probe_res(tpAniSirGlobal pMac,
+					tDot11fIEWscProbeRes *pDot11f);
+
+QDF_STATUS
+populate_dot11f_wsc_registrar_info_in_probe_res(tpAniSirGlobal pMac,
+					tDot11fIEWscProbeRes *pDot11f);
+
+QDF_STATUS
+de_populate_dot11f_wsc_registrar_info_in_probe_res(tpAniSirGlobal pMac,
+						tDot11fIEWscProbeRes *pDot11f);
+
+QDF_STATUS populate_dot11f_assoc_res_wsc_ie(tpAniSirGlobal pMac,
+					tDot11fIEWscAssocRes *pDot11f,
+					tpSirAssocReq pRcvdAssocReq);
+
+QDF_STATUS populate_dot11_assoc_res_p2p_ie(tpAniSirGlobal pMac,
+					tDot11fIEP2PAssocRes *pDot11f,
+					tpSirAssocReq pRcvdAssocReq);
+
+QDF_STATUS populate_dot11f_wscInAssocRes(tpAniSirGlobal pMac,
+					tDot11fIEWscAssocRes *pDot11f);
+
+QDF_STATUS populate_dot11f_wfatpc(tpAniSirGlobal pMac,
+				tDot11fIEWFATPC *pDot11f, uint8_t txPower,
+				uint8_t linkMargin);
+
+QDF_STATUS populate_dot11f_rrm_ie(tpAniSirGlobal pMac,
+				tDot11fIERRMEnabledCap *pDot11f,
+				tpPESession psessionEntry);
+
+void populate_mdie(tpAniSirGlobal pMac,
+		tDot11fIEMobilityDomain * pDot11f, uint8_t mdie[]);
+void populate_ft_info(tpAniSirGlobal pMac, tDot11fIEFTInfo *pDot11f);
+
+void populate_dot11f_assoc_rsp_rates(tpAniSirGlobal pMac,
+				tDot11fIESuppRates *pSupp,
+				tDot11fIEExtSuppRates *pExt,
+				uint16_t *_11bRates, uint16_t *_11aRates);
+
+int find_ie_location(tpAniSirGlobal pMac, tpSirRSNie pRsnIe, uint8_t EID);
+
+void lim_log_vht_cap(tpAniSirGlobal pMac, tDot11fIEVHTCaps *pDot11f);
+
+QDF_STATUS
+populate_dot11f_vht_caps(tpAniSirGlobal pMac, tpPESession psessionEntry,
+			tDot11fIEVHTCaps *pDot11f);
+
+QDF_STATUS
+populate_dot11f_vht_operation(tpAniSirGlobal pMac,
+			tpPESession psessionEntry,
+			tDot11fIEVHTOperation *pDot11f);
+
+QDF_STATUS
+populate_dot11f_ext_cap(tpAniSirGlobal pMac, bool isVHTEnabled,
+			tDot11fIEExtCap *pDot11f, tpPESession psessionEntry);
+
+void populate_dot11f_qcn_ie(tDot11fIEQCN_IE *pDot11f);
+
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * populate_dot11f_fils_params() - Populate FILS IE to frame
+ * @mac_ctx: global mac context
+ * @frm: Assoc request frame
+ * @pe_session: PE session
+ *
+ * This API is used to populate FILS IE to Association request
+ *
+ * Return: None
+ */
+void populate_dot11f_fils_params(tpAniSirGlobal mac_ctx,
+				 tDot11fAssocRequest * frm,
+				 tpPESession pe_session);
+#else
+static inline void populate_dot11f_fils_params(tpAniSirGlobal mac_ctx,
+				 tDot11fAssocRequest *frm,
+				 tpPESession pe_session)
+{ }
+#endif
+
+QDF_STATUS
+populate_dot11f_operating_mode(tpAniSirGlobal pMac,
+			tDot11fIEOperatingMode *pDot11f,
+			tpPESession psessionEntry);
+
+void
+populate_dot11f_wider_bw_chan_switch_ann(tpAniSirGlobal pMac,
+					tDot11fIEWiderBWChanSwitchAnn *pDot11f,
+					tpPESession psessionEntry);
+
+void populate_dot11f_timeout_interval(tpAniSirGlobal pMac,
+				tDot11fIETimeoutInterval *pDot11f,
+				uint8_t type, uint32_t value);
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+/* Populate a tDot11fIEQComVendorIE */
+void
+populate_dot11f_avoid_channel_ie(tpAniSirGlobal mac_ctx,
+				tDot11fIEQComVendorIE *dot11f,
+				tpPESession session_entry);
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+QDF_STATUS populate_dot11f_timing_advert_frame(tpAniSirGlobal pMac,
+	tDot11fTimingAdvertisementFrame *frame);
+void populate_dot11_supp_operating_classes(tpAniSirGlobal mac_ptr,
+	tDot11fIESuppOperatingClasses *dot_11_ptr, tpPESession session_entry);
+
+QDF_STATUS
+sir_validate_and_rectify_ies(tpAniSirGlobal mac_ctx,
+				uint8_t *mgmt_frame,
+				uint32_t frame_bytes,
+				uint32_t *missing_rsn_bytes);
+/**
+ * sir_copy_caps_info() - Copy Caps info from tDot11fFfCapabilities to
+ *                        beacon/probe response structure.
+ * @mac_ctx: MAC Context
+ * @caps: tDot11fFfCapabilities structure
+ * @pProbeResp: beacon/probe response structure
+ *
+ * Copy the caps info to beacon/probe response structure
+ *
+ * Return: None
+ */
+void sir_copy_caps_info(tpAniSirGlobal mac_ctx, tDot11fFfCapabilities caps,
+			tpSirProbeRespBeacon pProbeResp);
+
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * update_fils_data: update fils params from beacon/probe response
+ * @fils_ind: pointer to sir_fils_indication
+ * @fils_indication: pointer to tDot11fIEfils_indication
+ *
+ * Return: None
+ */
+void update_fils_data(struct sir_fils_indication *fils_ind,
+				 tDot11fIEfils_indication * fils_indication);
+#endif
+#ifdef WLAN_FEATURE_11AX
+QDF_STATUS populate_dot11f_he_caps(tpAniSirGlobal, tpPESession,
+				   tDot11fIEhe_cap *);
+QDF_STATUS populate_dot11f_he_operation(tpAniSirGlobal, tpPESession,
+					tDot11fIEhe_op *);
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+QDF_STATUS populate_dot11f_he_bss_color_change(tpAniSirGlobal mac_ctx,
+				tpPESession session,
+				tDot11fIEbss_color_change *bss_color);
+#else
+static inline QDF_STATUS populate_dot11f_he_bss_color_change(
+				tpAniSirGlobal mac_ctx,
+				tpPESession session,
+				tDot11fIEbss_color_change *bss_color)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#else
+static inline QDF_STATUS populate_dot11f_he_caps(tpAniSirGlobal mac_ctx,
+			tpPESession session, tDot11fIEhe_cap *he_cap)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS populate_dot11f_he_operation(tpAniSirGlobal mac_ctx,
+			tpPESession session, tDot11fIEhe_op *he_op)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS populate_dot11f_he_bss_color_change(
+				tpAniSirGlobal mac_ctx,
+				tpPESession session,
+				tDot11fIEbss_color_change *bss_color)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef WLAN_SUPPORT_TWT
+/**
+ * populate_dot11f_twt_extended_caps() - populate TWT extended capabilities
+ * @mac_ctx: Global MAC context.
+ * @pe_session: Pointer to the PE session.
+ * @dot11f: Pointer to the extended capabilities of the session.
+ *
+ * Populate the TWT extended capabilities based on the target and INI support.
+ *
+ * Return: QDF_STATUS Success or Failure
+ */
+QDF_STATUS populate_dot11f_twt_extended_caps(tpAniSirGlobal mac_ctx,
+					     tpPESession pe_session,
+					     tDot11fIEExtCap *dot11f);
+#else
+static inline
+QDF_STATUS populate_dot11f_twt_extended_caps(tpAniSirGlobal mac_ctx,
+					     tpPESession pe_session,
+					     tDot11fIEExtCap *dot11f)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * sir_unpack_beacon_ie: wrapper to unpack beacon and update def RSN params
+ * if optional fields are not present.
+ * @mac_ctx: mac context
+ * @buf: beacon buffer pointer
+ * @buf_len: beacon buffer length
+ * @frame: outframe frame structure
+ * @append_ie: flag to indicate if the frame need to be appended from buf
+ *
+ * Return: parse status
+ */
+uint32_t sir_unpack_beacon_ie(tpAniSirGlobal mac_ctx, uint8_t *buf,
+				       uint32_t buf_len,
+				       tDot11fBeaconIEs *frame, bool append_ie);
+
+/**
+ * lim_truncate_ppet: truncates ppet of trailling zeros
+ * @ppet: ppet to truncate
+ * max_len: max length of ppet
+ *
+ * Return: new length after truncation
+ */
+static inline uint32_t lim_truncate_ppet(uint8_t *ppet, uint32_t max_len)
+{
+	while (max_len) {
+		if (ppet[max_len - 1])
+			break;
+		max_len--;
+	}
+	return max_len;
+}
+#endif /* __PARSE_H__ */
diff --git a/core/mac/src/include/sir_common.h b/core/mac/src/include/sir_common.h
new file mode 100644
index 0000000..66078b9
--- /dev/null
+++ b/core/mac/src/include/sir_common.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011-2014 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.
+ */
+
+/*
+ *
+ * This file sir_common.h contains the common definitions used by all
+ * Firmware modules.
+ *
+ * Author:      V. K. Kandarpa
+ * Date:        04/12/2002
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#ifndef __SIRCOMMON_H
+#define __SIRCOMMON_H
+
+#include "sir_api.h"
+#include "sir_params.h"
+#include "sys_wrapper.h"
+
+/* ********************************************* *
+*                                               *
+*       SIRIUS SYSTEM EXTERNAL GLOBALS          *
+*                                               *
+* ********************************************* */
+
+/* All the following are resource definitions */
+
+#endif /* __SIRCOMMON_H */
diff --git a/core/mac/src/include/sir_debug.h b/core/mac/src/include/sir_debug.h
new file mode 100644
index 0000000..61d1e28
--- /dev/null
+++ b/core/mac/src/include/sir_debug.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2015, 2017-2018 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.
+ */
+
+/*
+ * Author:      Sandesh Goel
+ * Date:        02/25/02
+ */
+
+#ifndef __POL_DEBUG_H__
+#define __POL_DEBUG_H__
+
+#define LOGOFF  0
+#define LOGP    1
+#define LOGE    2
+#define LOGW    3
+#define LOG1    4
+#define LOG2    5
+#define LOG3    6
+#define LOG4    7
+#define LOGD    8
+
+#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+#define pe_alert_rl(params...) QDF_TRACE_FATAL_RL(QDF_MODULE_ID_PE, params)
+#define pe_err_rl(params...) QDF_TRACE_ERROR_RL(QDF_MODULE_ID_PE, params)
+#define pe_warn_rl(params...) QDF_TRACE_WARN_RL(QDF_MODULE_ID_PE, params)
+#define pe_info_rl(params...) QDF_TRACE_INFO_RL(QDF_MODULE_ID_PE, params)
+#define pe_debug_rl(params...) QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_PE, params)
+
+#define pe_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_PE, params)
+#define pe_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_PE, params)
+#define pe_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_PE, params)
+#define pe_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_PE, params)
+#define pe_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_PE, params)
+
+#define pe_nofl_alert(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_PE, params)
+#define pe_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_PE, params)
+#define pe_nofl_warn(params...) \
+	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_PE, params)
+#define pe_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_PE, params)
+#define pe_nofl_debug(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_PE, params)
+
+#define PE_ENTER() QDF_TRACE_ENTER(QDF_MODULE_ID_PE, "enter")
+#define PE_EXIT() QDF_TRACE_EXIT(QDF_MODULE_ID_PE, "exit")
+#endif
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
new file mode 100644
index 0000000..d41bdad
--- /dev/null
+++ b/core/mac/src/include/sir_params.h
@@ -0,0 +1,825 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file sir_params.h contains the common parameter definitions, which
+ * are not dependent on threadX API. These can be used by all Firmware
+ * modules.
+ *
+ * Author:      Sandesh Goel
+ * Date:        04/13/2002
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#ifndef __SIRPARAMS_H
+#define __SIRPARAMS_H
+
+#include "sir_types.h"
+
+#define WAKELOCK_DURATION_RECOMMENDED	1000
+#define WAKELOCK_DURATION_MAX		3000
+
+
+#define SYSTEM_TIME_MSEC_TO_USEC      1000
+#define SYSTEM_TIME_SEC_TO_MSEC       1000
+#define SYSTEM_TIME_NSEC_TO_USEC      1000
+
+/*
+ * Following time is used to program WOW_TIMER_PATTERN to FW so that FW will
+ * wake host up to do graceful disconnect in case PEER remains un-authorized
+ * for this long.
+ */
+#define SIR_INSTALL_KEY_TIMEOUT_SEC      70
+#define SIR_INSTALL_KEY_TIMEOUT_MS       \
+			(SIR_INSTALL_KEY_TIMEOUT_SEC * SYSTEM_TIME_SEC_TO_MSEC)
+
+/* defines for WPS config states */
+#define       SAP_WPS_DISABLED             0
+#define       SAP_WPS_ENABLED_UNCONFIGURED 1
+#define       SAP_WPS_ENABLED_CONFIGURED   2
+
+
+/* Firmware wide constants */
+
+#define SIR_MAX_PACKET_SIZE     512
+#define SIR_MAX_NUM_CHANNELS    64
+#define SIR_MAX_NUM_STA_IN_IBSS 16
+#define SIR_ESE_MAX_MEAS_IE_REQS   8
+
+typedef enum {
+	PHY_SINGLE_CHANNEL_CENTERED = 0,        /* 20MHz IF bandwidth centered on IF carrier */
+	PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1,     /* 40MHz IF bandwidth with lower 20MHz supporting the primary channel */
+	PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3,    /* 40MHz IF bandwidth with higher 20MHz supporting the primary channel */
+	PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED = 4,     /* 20/40MHZ offset LOW 40/80MHZ offset CENTERED */
+	PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED = 5,        /* 20/40MHZ offset CENTERED 40/80MHZ offset CENTERED */
+	PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED = 6,    /* 20/40MHZ offset HIGH 40/80MHZ offset CENTERED */
+	PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW = 7,  /* 20/40MHZ offset LOW 40/80MHZ offset LOW */
+	PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW = 8, /* 20/40MHZ offset HIGH 40/80MHZ offset LOW */
+	PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH = 9, /* 20/40MHZ offset LOW 40/80MHZ offset HIGH */
+	PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH = 10,       /* 20/40MHZ offset-HIGH 40/80MHZ offset HIGH */
+	PHY_CHANNEL_BONDING_STATE_MAX = 11
+} ePhyChanBondState;
+
+#define MAX_BONDED_CHANNELS 8
+/**
+ * enum cap_bitmap - bit field for FW capability
+ * MCC - indicate MCC
+ * P2P - indicate P2P
+ * DOT11AC - indicate 11AC
+ * SLM_SESSIONIZATION - indicate SLM_SESSIONIZATION
+ * DOT11AC_OPMODE - indicate 11ac opmode
+ * SAP32STA - indicate SAP32STA
+ * TDLS - indicate TDLS
+ * P2P_GO_NOA_DECOUPLE_INIT_SCAN - indicate P2P_GO_NOA_DECOUPLE_INIT_SCAN
+ * WLANACTIVE_OFFLOAD - indicate active offload
+ * EXTENDED_SCAN - indicate extended scan
+ * PNO - indicate PNO
+ * NAN - indicate NAN
+ * RTT - indicate RTT
+ * DOT11AX - indicate 11ax
+ * WOW - indicate WOW
+ * WLAN_ROAM_SCAN_OFFLOAD - indicate Roam scan offload
+ * IBSS_HEARTBEAT_OFFLOAD - indicate IBSS HB offload
+ * WLAN_PERIODIC_TX_PTRN - indicate WLAN_PERIODIC_TX_PTRN
+ * ADVANCE_TDLS - indicate advanced TDLS
+ * TDLS_OFF_CHANNEL - indicate TDLS off channel
+ *
+ * This definition is independent of any other modules.
+ * We can use any unused numbers.
+ */
+#define MAX_SUPPORTED_FEATURE 32
+enum cap_bitmap {
+	MCC = 0,
+	P2P = 1,
+	DOT11AC = 2,
+	SLM_SESSIONIZATION = 3,
+	DOT11AC_OPMODE = 4,
+	SAP32STA = 5,
+	TDLS = 6,
+	P2P_GO_NOA_DECOUPLE_INIT_SCAN = 7,
+	WLANACTIVE_OFFLOAD = 8,
+	EXTENDED_SCAN = 9,
+#ifdef FEATURE_WLAN_SCAN_PNO
+	PNO = 10,
+#endif
+#ifdef WLAN_FEATURE_NAN
+	NAN = 11,
+#endif
+	RTT = 12,
+	DOT11AX = 13,
+	WOW = 22,
+	WLAN_ROAM_SCAN_OFFLOAD = 23,
+	IBSS_HEARTBEAT_OFFLOAD = 26,
+	WLAN_PERIODIC_TX_PTRN = 28,
+#ifdef FEATURE_WLAN_TDLS
+	ADVANCE_TDLS = 29,
+	TDLS_OFF_CHANNEL = 30,
+#endif
+
+	/* MAX_FEATURE_SUPPORTED = 32 */
+};
+
+typedef enum eSriLinkState {
+	eSIR_LINK_IDLE_STATE = 0,
+	eSIR_LINK_PREASSOC_STATE = 1,
+	eSIR_LINK_POSTASSOC_STATE = 2,
+	eSIR_LINK_AP_STATE = 3,
+	eSIR_LINK_IBSS_STATE = 4,
+	eSIR_LINK_DOWN_STATE = 5,
+} tSirLinkState;
+
+/* / Mailbox Message Structure Define */
+typedef struct sSirMbMsg {
+	uint16_t type;
+
+	/**
+	 * This length includes 4 bytes of header, that is,
+	 * 2 bytes type + 2 bytes msgLen + n*4 bytes of data.
+	 * This field is byte length.
+	 */
+	uint16_t msgLen;
+
+	/**
+	 * This is the first data word in the mailbox message.
+	 * It is followed by n words of data.
+	 * NOTE: data[1] is not a place holder to store data
+	 * instead to dereference the message body.
+	 */
+	uint32_t data[1];
+} tSirMbMsg, *tpSirMbMsg;
+
+/* / Mailbox Message Structure for P2P */
+typedef struct sSirMbMsgP2p {
+	uint16_t type;
+
+	/**
+	 * This length includes 4 bytes of header, that is,
+	 * 2 bytes type + 2 bytes msgLen + n*4 bytes of data.
+	 * This field is byte length.
+	 */
+	uint16_t msgLen;
+
+	uint8_t sessionId;
+	uint8_t noack;
+	uint16_t wait;
+	uint16_t channel_freq;
+	uint32_t scan_id;
+
+	/**
+	 * This is the first data word in the mailbox message.
+	 * It is followed by n words of data.
+	 * NOTE: data[1] is not a place holder to store data
+	 * instead to dereference the message body.
+	 */
+	uint32_t data[1];
+} tSirMbMsgP2p, *tpSirMbMsgP2p;
+
+/**
+ * struct sir_mgmt_msg - Structure used to send auth frame from CSR to LIM
+ * @type: Message type
+ * @msg_len: Message length
+ * @session_id: session id
+ * @data: Pointer to data tobe transmitted
+ */
+struct sir_mgmt_msg {
+	uint16_t type;
+	uint16_t msg_len;
+	uint8_t session_id;
+	uint8_t *data;
+};
+
+/* ******************************************* *
+*                                             *
+*         SIRIUS MESSAGE TYPES                *
+*                                             *
+* ******************************************* */
+
+/*
+ * The following message types have bounds defined for each module for
+ * inter thread/module communications.
+ * Each module will get 256 message types in total.
+ * Note that message type definitions for mailbox messages for
+ * communication with Host are in wni_api.h file.
+ *
+ * Any addition/deletion to this message list should also be
+ * reflected in the halUtil_getMsgString() routine.
+ */
+
+/* HAL message types */
+#define SIR_HAL_MSG_TYPES_BEGIN            (SIR_HAL_MODULE_ID << 8)
+#define SIR_HAL_ITC_MSG_TYPES_BEGIN        (SIR_HAL_MSG_TYPES_BEGIN+0x20)
+#define SIR_HAL_RADAR_DETECTED_IND         SIR_HAL_ITC_MSG_TYPES_BEGIN
+
+/*
+ * New Taurus related messages
+ */
+#define SIR_HAL_ADD_STA_REQ                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 1)
+#define SIR_HAL_ADD_STA_RSP                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 2)
+#define SIR_HAL_DELETE_STA_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 3)
+#define SIR_HAL_DELETE_STA_RSP             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 4)
+#define SIR_HAL_ADD_BSS_REQ                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 5)
+#define SIR_HAL_ADD_BSS_RSP                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 6)
+#define SIR_HAL_DELETE_BSS_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 7)
+#define SIR_HAL_DELETE_BSS_RSP             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 8)
+#define SIR_HAL_INIT_SCAN_REQ              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 9)
+#define SIR_HAL_INIT_SCAN_RSP              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 10)
+#define SIR_HAL_START_SCAN_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 11)
+#define SIR_HAL_START_SCAN_RSP             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 12)
+#define SIR_HAL_END_SCAN_REQ               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 13)
+#define SIR_HAL_END_SCAN_RSP               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 14)
+#define SIR_HAL_FINISH_SCAN_REQ            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 15)
+#define SIR_HAL_FINISH_SCAN_RSP            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 16)
+#define SIR_HAL_SEND_BEACON_REQ            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 17)
+
+#define SIR_HAL_SET_BSSKEY_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 18)
+#define SIR_HAL_SET_BSSKEY_RSP             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 19)
+#define SIR_HAL_SET_STAKEY_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 20)
+#define SIR_HAL_SET_STAKEY_RSP             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 21)
+#define SIR_HAL_UPDATE_EDCA_PROFILE_IND    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 22)
+
+#define SIR_HAL_UPDATE_BEACON_IND          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 23)
+#define SIR_HAL_UPDATE_CF_IND              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 24)
+#define SIR_HAL_CHNL_SWITCH_REQ            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 25)
+#define SIR_HAL_ADD_TS_REQ                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 26)
+#define SIR_HAL_DEL_TS_REQ                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 27)
+
+#define SIR_HAL_MISSED_BEACON_IND          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 34)
+
+#define SIR_HAL_SWITCH_CHANNEL_RSP         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 35)
+#define SIR_HAL_PWR_SAVE_CFG               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 36)
+
+#define SIR_HAL_REGISTER_PE_CALLBACK       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 37)
+
+#define SIR_HAL_IBSS_STA_ADD               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 43)
+#define SIR_HAL_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND \
+					   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 44)
+#define SIR_HAL_SET_LINK_STATE             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 45)
+#define SIR_HAL_DELETE_BSS_HO_FAIL_REQ     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 46)
+#define SIR_HAL_DELETE_BSS_HO_FAIL_RSP     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 47)
+
+/*
+ * (SIR_HAL_ITC_MSG_TYPES_BEGIN + 48) to
+ * (SIR_HAL_ITC_MSG_TYPES_BEGIN + 57) are unused
+ */
+
+#define SIR_HAL_SET_STA_BCASTKEY_REQ       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 58)
+#define SIR_HAL_SET_STA_BCASTKEY_RSP       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 59)
+#define SIR_HAL_ADD_TS_RSP                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 60)
+#define SIR_HAL_DPU_MIC_ERROR              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 61)
+#define SIR_HAL_TIMER_CHIP_MONITOR_TIMEOUT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 63)
+#define SIR_HAL_TIMER_TRAFFIC_ACTIVITY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 64)
+#define SIR_HAL_TIMER_ADC_RSSI_STATS       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 65)
+/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 66) is unused */
+#define SIR_HAL_SET_MIMOPS_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 67)
+#define SIR_HAL_SET_MIMOPS_RSP             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 68)
+#define SIR_HAL_SYS_READY_IND              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 69)
+#define SIR_HAL_SET_TX_POWER_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 70)
+#define SIR_HAL_SET_TX_POWER_RSP           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 71)
+#define SIR_HAL_GET_TX_POWER_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 72)
+#define SIR_HAL_GET_TX_POWER_RSP           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 73)
+#define SIR_HAL_GET_NOISE_RSP              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 74)
+
+/* Messages to support transmit_halt and transmit_resume */
+#define SIR_HAL_TRANSMISSION_CONTROL_IND   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 75)
+
+#define SIR_HAL_LOW_RSSI_IND               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 80)
+#define SIR_HAL_BEACON_FILTER_IND          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 81)
+
+/* 82-87 are unused */
+
+/* / PE <-> HAL statistics messages */
+#define SIR_HAL_GET_STATISTICS_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 88)
+#define SIR_HAL_GET_STATISTICS_RSP         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 89)
+#define SIR_HAL_SET_KEY_DONE               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 90)
+
+/* / PE <-> HAL BTC messages */
+#define SIR_HAL_BTC_SET_CFG                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 91)
+/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 92) is unused */
+#define SIR_HAL_HANDLE_FW_MBOX_RSP         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 93)
+#define SIR_HAL_SEND_PROBE_RSP_TMPL        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 94)
+
+/* PE <-> HAL addr2 mismatch message */
+#define SIR_LIM_ADDR2_MISS_IND             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 95)
+#ifdef FEATURE_OEM_DATA_SUPPORT
+/* PE <-> HAL OEM_DATA RELATED MESSAGES */
+#define SIR_HAL_START_OEM_DATA_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 96)
+#define SIR_HAL_START_OEM_DATA_RSP         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 97)
+#endif
+
+#define SIR_HAL_SET_MAX_TX_POWER_REQ       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 98)
+#define SIR_HAL_SET_MAX_TX_POWER_RSP       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 99)
+
+/* / PE <-> HAL Host Offload message */
+#define SIR_HAL_SET_HOST_OFFLOAD           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 100)
+
+#define SIR_HAL_ADD_STA_SELF_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 101)
+#define SIR_HAL_ADD_STA_SELF_RSP           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 102)
+#define SIR_HAL_DEL_STA_SELF_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 103)
+#define SIR_HAL_DEL_STA_SELF_RSP           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 104)
+
+#define SIR_HAL_CFG_RXP_FILTER_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 106)
+
+#define SIR_HAL_AGGR_ADD_TS_REQ            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 107)
+#define SIR_HAL_AGGR_ADD_TS_RSP            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 108)
+#define SIR_HAL_AGGR_QOS_REQ               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 109)
+#define SIR_HAL_AGGR_QOS_RSP               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 110)
+
+/* P2P <-> HAL P2P msg */
+#define SIR_HAL_SET_P2P_GO_NOA_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 111)
+#define SIR_HAL_P2P_NOA_ATTR_IND           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 112)
+#define SIR_HAL_P2P_NOA_START_IND          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 113)
+
+#define SIR_HAL_SET_LINK_STATE_RSP         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 114)
+
+#define SIR_HAL_WLAN_SUSPEND_IND           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 115)
+#define SIR_HAL_WLAN_RESUME_REQ            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 116)
+
+/* / PE <-> HAL Keep Alive message */
+#define SIR_HAL_SET_KEEP_ALIVE             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 117)
+
+#ifdef WLAN_NS_OFFLOAD
+#define SIR_HAL_SET_NS_OFFLOAD             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 118)
+#endif /* WLAN_NS_OFFLOAD */
+
+#define SIR_HAL_SOC_ANTENNA_MODE_REQ        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 120)
+#define SIR_HAL_SOC_ANTENNA_MODE_RESP       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 121)
+
+/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 122) is unused */
+
+#define SIR_HAL_8023_MULTICAST_LIST_REQ \
+					   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 123)
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+#define SIR_HAL_RECEIVE_FILTER_SET_FILTER_REQ \
+					   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 124)
+#define SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ \
+					   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 125)
+#define SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP \
+					   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 126)
+#define SIR_HAL_RECEIVE_FILTER_CLEAR_FILTER_REQ \
+					   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 127)
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+
+/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 128) is unused */
+
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+#define SIR_HAL_GTK_OFFLOAD_REQ            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 129)
+#define SIR_HAL_GTK_OFFLOAD_GETINFO_REQ    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 130)
+#define SIR_HAL_GTK_OFFLOAD_GETINFO_RSP    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 131)
+#endif /* WLAN_FEATURE_GTK_OFFLOAD */
+
+#ifdef FEATURE_WLAN_ESE
+#define SIR_HAL_TSM_STATS_REQ              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 132)
+#define SIR_HAL_TSM_STATS_RSP              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 133)
+#endif
+
+#define SIR_HAL_SET_TM_LEVEL_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 134)
+
+#define SIR_HAL_UPDATE_OP_MODE             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 135)
+
+#ifdef FEATURE_WLAN_TDLS
+/* / PE <-> HAL TDLS messages */
+#define SIR_HAL_TDLS_LINK_ESTABLISH        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 136)
+#define SIR_HAL_TDLS_LINK_TEARDOWN         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 137)
+#endif
+#define SIR_HAL_ROAM_SCAN_OFFLOAD_REQ      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 138)
+
+#define SIR_HAL_TRAFFIC_STATS_IND          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 141)
+
+#ifdef WLAN_FEATURE_11W
+#define SIR_HAL_EXCLUDE_UNENCRYPTED_IND    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 142)
+#endif
+#ifdef FEATURE_WLAN_TDLS
+/* / PE <-> HAL TDLS messages */
+#define SIR_HAL_TDLS_LINK_ESTABLISH_REQ     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 143)
+#define SIR_HAL_TDLS_LINK_ESTABLISH_REQ_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 144)
+#define SIR_HAL_TDLS_IND                    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 145)
+#endif
+
+#define SIR_HAL_STOP_SCAN_OFFLOAD_REQ      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 146)
+#define SIR_HAL_RX_SCAN_EVENT              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 147)
+#define SIR_HAL_DHCP_START_IND             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 148)
+#define SIR_HAL_DHCP_STOP_IND              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 149)
+#define SIR_HAL_IBSS_PEER_INACTIVITY_IND   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 150)
+
+#define SIR_HAL_LPHB_CONF_IND              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 151)
+
+#define SIR_HAL_ADD_PERIODIC_TX_PTRN_IND   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 152)
+#define SIR_HAL_DEL_PERIODIC_TX_PTRN_IND   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 153)
+
+/* Messages between 156 to 157 are not used */
+#define SIR_HAL_PDEV_DUAL_MAC_CFG_REQ      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 154)
+#define SIR_HAL_PDEV_MAC_CFG_RESP          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 155)
+
+/* For IBSS peer info related messages */
+#define SIR_HAL_IBSS_PEER_INFO_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 158)
+
+#define SIR_HAL_RATE_UPDATE_IND            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 159)
+
+#define SIR_HAL_FLUSH_LOG_TO_FW            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 160)
+
+#define SIR_HAL_PDEV_SET_PCL_TO_FW         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161)
+
+/* 162 unused */
+
+#define SIR_HAL_CLI_SET_CMD                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 163)
+#ifndef REMOVE_PKT_LOG
+#define SIR_HAL_PKTLOG_ENABLE_REQ          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 164)
+#endif
+#define SIR_HAL_START_SCAN_OFFLOAD_REQ     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 166)
+#define SIR_HAL_UPDATE_CHAN_LIST_REQ       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 167)
+#define SIR_CSA_OFFLOAD_EVENT               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 169)
+
+#define SIR_HAL_SET_MAX_TX_POWER_PER_BAND_REQ \
+					    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 170)
+
+#define SIR_HAL_TX_FAIL_MONITOR_IND         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 171)
+
+#define SIR_HAL_UPDATE_MEMBERSHIP           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 172)
+#define SIR_HAL_UPDATE_USERPOS              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 173)
+
+#ifdef FEATURE_WLAN_TDLS
+/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 174) is not used */
+#define SIR_HAL_UPDATE_TDLS_PEER_STATE      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 175)
+#define SIR_HAL_TDLS_SHOULD_DISCOVER        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 176)
+#define SIR_HAL_TDLS_SHOULD_TEARDOWN        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 177)
+#define SIR_HAL_TDLS_PEER_DISCONNECTED      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 178)
+#endif
+
+/* Handling of beacon tx indication from FW */
+#define SIR_HAL_BEACON_TX_SUCCESS_IND       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 179)
+#define SIR_HAL_DFS_RADAR_IND               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 180)
+
+#define SIR_HAL_IBSS_CESIUM_ENABLE_IND      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 181)
+
+#define SIR_HAL_RMC_ENABLE_IND              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 182)
+#define SIR_HAL_RMC_DISABLE_IND             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 183)
+#define SIR_HAL_RMC_ACTION_PERIOD_IND       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 184)
+#define SIR_HAL_INIT_THERMAL_INFO_CMD       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 185)
+#define SIR_HAL_SET_THERMAL_LEVEL           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 186)
+
+#ifdef FEATURE_WLAN_ESE
+#define SIR_HAL_SET_PLM_REQ                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 187)
+#endif
+
+#define SIR_HAL_SET_TX_POWER_LIMIT          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 188)
+#define SIR_HAL_SET_SAP_INTRABSS_DIS        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 189)
+
+#define SIR_HAL_MODEM_POWER_STATE_IND       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 190)
+
+#define SIR_HAL_DISASSOC_TX_COMP            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 191)
+#define SIR_HAL_DEAUTH_TX_COMP              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 192)
+
+#define SIR_HAL_UPDATE_RX_NSS               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 193)
+
+#ifdef WLAN_FEATURE_STATS_EXT
+#define SIR_HAL_STATS_EXT_REQUEST           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 194)
+#define SIR_HAL_STATS_EXT_EVENT             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 195)
+#endif /* WLAN_FEATURE_STATS_EXT */
+
+#define SIR_HAL_HIDE_SSID_VDEV_RESTART      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 196)
+
+#define SIR_HAL_GET_LINK_SPEED              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 197)
+
+#ifdef FEATURE_WLAN_EXTSCAN
+#define SIR_HAL_EXTSCAN_GET_CAPABILITIES_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 198)
+#define SIR_HAL_EXTSCAN_START_REQ            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 199)
+#define SIR_HAL_EXTSCAN_STOP_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 200)
+#define SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_REQ  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 201)
+#define SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_REQ \
+					     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 202)
+#define SIR_HAL_EXTSCAN_SET_SIGNF_CHANGE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 203)
+#define SIR_HAL_EXTSCAN_RESET_SIGNF_CHANGE_REQ \
+					     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 204)
+#define SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_REQ \
+					     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 205)
+#endif /* FEATURE_WLAN_EXTSCAN */
+
+#ifdef FEATURE_WLAN_CH_AVOID
+#define SIR_HAL_CH_AVOID_UPDATE_REQ          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 206)
+#endif
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+#define SIR_HAL_LL_STATS_CLEAR_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 207)
+#define SIR_HAL_LL_STATS_SET_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 208)
+#define SIR_HAL_LL_STATS_GET_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 209)
+#define SIR_HAL_LL_STATS_RESULTS_RSP         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 210)
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+#define SIR_HAL_ROAM_OFFLOAD_SYNCH_CNF       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 211)
+#endif
+#ifdef WLAN_FEATURE_NAN
+#define SIR_HAL_NAN_REQUEST                  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 212)
+#endif /* WLAN_FEATURE_NAN */
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+#define SIR_HAL_SET_AUTO_SHUTDOWN_TIMER_REQ  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 213)
+#endif
+
+#define SIR_HAL_SET_BASE_MACADDR_IND         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 214)
+
+/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 215) is unused */
+
+#define SIR_HAL_LINK_STATUS_GET_REQ          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 216)
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+#define SIR_HAL_CONFIG_EXT_WOW               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 217)
+#define SIR_HAL_CONFIG_APP_TYPE1_PARAMS      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 218)
+#define SIR_HAL_CONFIG_APP_TYPE2_PARAMS      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 219)
+#endif
+
+#define SIR_HAL_GET_TEMPERATURE_REQ          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 220)
+#define SIR_HAL_SET_SCAN_MAC_OUI_REQ         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 221)
+#ifdef DHCP_SERVER_OFFLOAD
+#define SIR_HAL_SET_DHCP_SERVER_OFFLOAD      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 222)
+#endif /* DHCP_SERVER_OFFLOAD */
+#define SIR_HAL_LED_FLASHING_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 223)
+#define SIR_HAL_PROCESS_FW_EVENT             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 224)
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+#define SIR_HAL_ROAM_OFFLOAD_SYNCH_IND       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 225)
+#define SIR_HAL_ROAM_OFFLOAD_SYNCH_FAIL      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 226)
+#define SIR_HAL_ROAM_INVOKE                  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 227)
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+#define SIR_HAL_TDLS_SET_OFFCHAN_MODE        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 228)
+#endif
+
+#define SIR_HAL_SET_MAS                    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 229)
+#define SIR_HAL_SET_MIRACAST               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 230)
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+#define SIR_HAL_UPDATE_Q2Q_IE_IND          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 231)
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+#define SIR_HAL_CONFIG_STATS_FACTOR        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 232)
+#define SIR_HAL_CONFIG_GUARD_TIME          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 233)
+#define SIR_HAL_IPA_OFFLOAD_ENABLE_DISABLE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 234)
+
+#define SIR_HAL_ENTER_PS_REQ                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 235)
+#define SIR_HAL_EXIT_PS_REQ                  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 236)
+#define SIR_HAL_ENABLE_UAPSD_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 237)
+#define SIR_HAL_DISABLE_UAPSD_REQ            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 238)
+#define SIR_HAL_GATEWAY_PARAM_UPDATE_REQ    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 239)
+
+#define SIR_HAL_RUNTIME_PM_SUSPEND_IND	(SIR_HAL_ITC_MSG_TYPES_BEGIN + 308)
+#define SIR_HAL_RUNTIME_PM_RESUME_IND	(SIR_HAL_ITC_MSG_TYPES_BEGIN + 309)
+
+#define SIR_HAL_SET_EPNO_LIST_REQ          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 313)
+#define SIR_HAL_SET_PASSPOINT_LIST_REQ     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 316)
+#define SIR_HAL_RESET_PASSPOINT_LIST_REQ   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 317)
+/* 318 unused */
+
+#define SIR_HAL_OCB_SET_CONFIG_CMD          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 319)
+#define SIR_HAL_OCB_SET_UTC_TIME_CMD        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 320)
+#define SIR_HAL_OCB_START_TIMING_ADVERT_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 321)
+#define SIR_HAL_OCB_STOP_TIMING_ADVERT_CMD  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 322)
+#define SIR_HAL_OCB_GET_TSF_TIMER_CMD       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 323)
+#define SIR_HAL_DCC_GET_STATS_CMD           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 324)
+#define SIR_HAL_DCC_CLEAR_STATS_CMD         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 325)
+#define SIR_HAL_DCC_UPDATE_NDL_CMD          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 326)
+
+/* FW Memory Dump feature is deprecated */
+
+#define SIR_HAL_START_STOP_LOGGING           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 328)
+#define SIR_HAL_PDEV_SET_HW_MODE             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 329)
+#define SIR_HAL_PDEV_SET_HW_MODE_RESP        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 330)
+#define SIR_HAL_PDEV_HW_MODE_TRANS_IND       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 331)
+
+#define SIR_HAL_BAD_PEER_TX_CTL_INI_CMD     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 332)
+#define SIR_HAL_SET_RSSI_MONITOR_REQ        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 333)
+#define SIR_HAL_SET_IE_INFO                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 334)
+
+#define SIR_HAL_LRO_CONFIG_CMD              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 335)
+
+#define SIR_HAL_HT40_OBSS_SCAN_IND          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 337)
+
+#define SIR_HAL_TSF_GPIO_PIN_REQ            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 338)
+
+#define SIR_HAL_ADD_BCN_FILTER_CMDID        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 339)
+#define SIR_HAL_REMOVE_BCN_FILTER_CMDID     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 340)
+
+
+#define SIR_HAL_APF_GET_CAPABILITIES_REQ    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 341)
+#define SIR_HAL_APF_SET_INSTRUCTIONS_REQ    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 342)
+
+#define SIR_HAL_SET_WISA_PARAMS             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 343)
+#define SIR_HAL_SET_ADAPT_DWELLTIME_PARAMS  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 344)
+#define SIR_HAL_SET_PDEV_IE_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 345)
+
+#ifdef FEATURE_WLAN_TDLS
+#define SIR_HAL_TDLS_CONNECTION_TRACKER_NOTIFICATION (SIR_HAL_ITC_MSG_TYPES_BEGIN + 346)
+#endif
+
+#define SIR_HAL_NDP_GET_CAP_REQ             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 347)
+#define SIR_HAL_NDP_INITIATOR_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 348)
+#define SIR_HAL_NDP_RESPONDER_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 349)
+#define SIR_HAL_NDP_END_REQ                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 350)
+#define SIR_HAL_NDI_CAP_RSP                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 351)
+#define SIR_HAL_NDP_INITIATOR_RSP           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 352)
+#define SIR_HAL_NDP_RESPONDER_RSP           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 353)
+#define SIR_HAL_NDP_END_RSP                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 354)
+#define SIR_HAL_NDP_INDICATION              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 355)
+#define SIR_HAL_NDP_CONFIRM                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 356)
+#define SIR_HAL_NDP_END_IND                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 357)
+#define SIR_HAL_UPDATE_WEP_DEFAULT_KEY      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 358)
+
+#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 360)
+#define SIR_HAL_POWER_DBG_CMD               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 362)
+#define SIR_HAL_SET_DTIM_PERIOD             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 363)
+#define SIR_HAL_ENCRYPT_DECRYPT_MSG         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 364)
+#define SIR_HAL_SHORT_RETRY_LIMIT_CNT       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 365)
+#define SIR_HAL_LONG_RETRY_LIMIT_CNT        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 366)
+#define SIR_HAL_UPDATE_TX_FAIL_CNT_TH       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 367)
+#define SIR_HAL_POWER_DEBUG_STATS_REQ       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 368)
+
+#define SIR_HAL_SET_WOW_PULSE_CMD           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 369)
+
+#define SIR_HAL_SET_UDP_RESP_OFFLOAD        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 370)
+
+#define SIR_HAL_SET_PER_ROAM_CONFIG_CMD     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 371)
+#define SIR_HAL_RX_CHN_STATUS_EVENT         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 372)
+
+#define SIR_HAL_GET_RCPI_REQ                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 373)
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+#define SIR_HAL_LL_STATS_EXT_SET_THRESHOLD  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 378)
+#endif
+#define SIR_HAL_SET_DBS_SCAN_SEL_PARAMS     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 379)
+
+#define SIR_HAL_HIDDEN_SSID_RESTART_RSP     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 379)
+
+#define SIR_HAL_GET_PEER_INFO               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 386)
+#define SIR_HAL_GET_PEER_INFO_EXT           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 387)
+
+/* ARP Debug stats */
+#define SIR_HAL_SET_ARP_STATS_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 388)
+#define SIR_HAL_GET_ARP_STATS_REQ           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 389)
+
+#define SIR_HAL_SET_LIMIT_OFF_CHAN          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 390)
+
+#define SIR_HAL_SET_DEL_PMKID_CACHE         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 391)
+#define SIR_HAL_HLP_IE_INFO                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 392)
+#define SIR_HAL_OBSS_DETECTION_REQ          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 393)
+#define SIR_HAL_OBSS_DETECTION_INFO         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 394)
+#define SIR_HAL_INVOKE_NEIGHBOR_REPORT      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 395)
+#define SIR_HAL_OBSS_COLOR_COLLISION_REQ    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 396)
+#define SIR_HAL_OBSS_COLOR_COLLISION_INFO   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 397)
+
+#define SIR_HAL_SEND_ADDBA_REQ              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 398)
+#define SIR_HAL_GET_ROAM_SCAN_STATS         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 399)
+#define SIR_HAL_SEND_AP_VDEV_UP             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 400)
+#define SIR_HAL_SEND_BCN_RSP                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 401)
+
+#define SIR_HAL_MSG_TYPES_END               (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
+
+/* CFG message types */
+#define SIR_CFG_MSG_TYPES_BEGIN        (SIR_CFG_MODULE_ID << 8)
+#define SIR_CFG_ITC_MSG_TYPES_BEGIN    (SIR_CFG_MSG_TYPES_BEGIN+0xB0)
+#define SIR_CFG_PARAM_UPDATE_IND       (SIR_CFG_ITC_MSG_TYPES_BEGIN)
+#define SIR_CFG_DOWNLOAD_COMPLETE_IND  (SIR_CFG_ITC_MSG_TYPES_BEGIN + 1)
+#define SIR_CFG_MSG_TYPES_END          (SIR_CFG_MSG_TYPES_BEGIN+0xFF)
+
+/* LIM message types */
+#define SIR_LIM_MSG_TYPES_BEGIN        (SIR_LIM_MODULE_ID << 8)
+#define SIR_LIM_ITC_MSG_TYPES_BEGIN    (SIR_LIM_MSG_TYPES_BEGIN+0xB0)
+
+/* Messages to/from HAL */
+/* Removed as part of moving HAL down to FW */
+
+/* Message from ISR upon TFP retry interrupt */
+#define SIR_LIM_RETRY_INTERRUPT_MSG        (SIR_LIM_ITC_MSG_TYPES_BEGIN + 3)
+/* Message from BB Transport */
+#define SIR_BB_XPORT_MGMT_MSG              (SIR_LIM_ITC_MSG_TYPES_BEGIN + 4)
+/* UNUSED                                  SIR_LIM_ITC_MSG_TYPES_BEGIN + 6 */
+/* Message from ISR upon SP's Invalid session key interrupt */
+#define SIR_LIM_INV_KEY_INTERRUPT_MSG      (SIR_LIM_ITC_MSG_TYPES_BEGIN + 7)
+/* Message from ISR upon SP's Invalid key ID interrupt */
+#define SIR_LIM_KEY_ID_INTERRUPT_MSG       (SIR_LIM_ITC_MSG_TYPES_BEGIN + 8)
+/* Message from ISR upon SP's Replay threshold reached interrupt */
+#define SIR_LIM_REPLAY_THRES_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 9)
+/* Message from HDD after the TD dummy packet is cleaned up */
+#define SIR_LIM_TD_DUMMY_CALLBACK_MSG      (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xA)
+/* Message from SCH when the STA is ready to be deleted */
+#define SIR_LIM_SCH_CLEAN_MSG              (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xB)
+/* Message from ISR upon Radar Detection */
+#define SIR_LIM_RADAR_DETECT_IND           (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xC)
+/* Message id 0xD available */
+
+/* Message from Hal to send out a DEL-TS indication */
+#define SIR_LIM_DEL_TS_IND                  (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xE)
+/* Indication from HAL to delete Station context */
+#define SIR_LIM_DELETE_STA_CONTEXT_IND      (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x11)
+/* Indication from HAL to delete BA */
+#define SIR_LIM_UPDATE_BEACON               (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x13)
+/* Indication from HAL to handle RX invalid peer */
+#define SIR_LIM_RX_INVALID_PEER            (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x15)
+
+/* LIM Timeout messages */
+#define SIR_LIM_TIMEOUT_MSG_START      ((SIR_LIM_MODULE_ID << 8) + 0xD0)
+#define SIR_LIM_JOIN_FAIL_TIMEOUT      (SIR_LIM_TIMEOUT_MSG_START + 2)
+#define SIR_LIM_AUTH_FAIL_TIMEOUT      (SIR_LIM_TIMEOUT_MSG_START + 3)
+#define SIR_LIM_AUTH_RSP_TIMEOUT       (SIR_LIM_TIMEOUT_MSG_START + 4)
+#define SIR_LIM_ASSOC_FAIL_TIMEOUT     (SIR_LIM_TIMEOUT_MSG_START + 5)
+#define SIR_LIM_REASSOC_FAIL_TIMEOUT   (SIR_LIM_TIMEOUT_MSG_START + 6)
+#define SIR_LIM_HEART_BEAT_TIMEOUT     (SIR_LIM_TIMEOUT_MSG_START + 7)
+/* currently unused                    SIR_LIM_TIMEOUT_MSG_START + 0x8 */
+/* Link Monitoring Messages */
+#define SIR_LIM_PROBE_HB_FAILURE_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0xB)
+#define SIR_LIM_ADDTS_RSP_TIMEOUT        (SIR_LIM_TIMEOUT_MSG_START + 0xC)
+#define SIR_LIM_LINK_TEST_DURATION_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x13)
+#define SIR_LIM_CNF_WAIT_TIMEOUT         (SIR_LIM_TIMEOUT_MSG_START + 0x17)
+/* currently unused			(SIR_LIM_TIMEOUT_MSG_START + 0x18) */
+#define SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x19)
+#define SIR_LIM_CHANNEL_SWITCH_TIMEOUT   (SIR_LIM_TIMEOUT_MSG_START + 0x1A)
+#define SIR_LIM_QUIET_TIMEOUT            (SIR_LIM_TIMEOUT_MSG_START + 0x1B)
+#define SIR_LIM_QUIET_BSS_TIMEOUT        (SIR_LIM_TIMEOUT_MSG_START + 0x1C)
+
+#define SIR_LIM_WPS_OVERLAP_TIMEOUT      (SIR_LIM_TIMEOUT_MSG_START + 0x1D)
+#define SIR_LIM_FT_PREAUTH_RSP_TIMEOUT   (SIR_LIM_TIMEOUT_MSG_START + 0x1E)
+
+#define SIR_LIM_BEACON_GEN_IND          (SIR_LIM_TIMEOUT_MSG_START + 0x23)
+#define SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT    (SIR_LIM_TIMEOUT_MSG_START + 0x24)
+
+/* currently unused                     (SIR_LIM_TIMEOUT_MSG_START + 0x25) */
+
+#define SIR_LIM_DISASSOC_ACK_TIMEOUT       (SIR_LIM_TIMEOUT_MSG_START + 0x26)
+#define SIR_LIM_DEAUTH_ACK_TIMEOUT       (SIR_LIM_TIMEOUT_MSG_START + 0x27)
+#define SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT \
+					 (SIR_LIM_TIMEOUT_MSG_START + 0x28)
+
+#define SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE \
+					 (SIR_LIM_TIMEOUT_MSG_START + 0x2C)
+#define SIR_LIM_AUTH_RETRY_TIMEOUT     (SIR_LIM_TIMEOUT_MSG_START + 0x2D)
+
+#define SIR_LIM_AUTH_SAE_TIMEOUT     (SIR_LIM_TIMEOUT_MSG_START + 0x2E)
+
+#define SIR_LIM_MSG_TYPES_END            (SIR_LIM_MSG_TYPES_BEGIN+0xFF)
+
+/* PMM message types */
+#define SIR_PMM_MSG_TYPES_BEGIN        (SIR_PMM_MODULE_ID << 8)
+#define SIR_PMM_CHANGE_PM_MODE         (SIR_PMM_MSG_TYPES_BEGIN)
+#define SIR_PMM_MSG_TYPES_END          (SIR_PMM_MSG_TYPES_BEGIN+0xFF)
+
+/* MNT message types */
+#define SIR_MNT_MSG_TYPES_BEGIN        (SIR_MNT_MODULE_ID << 8)
+#define SIR_MNT_RELEASE_BD             (SIR_MNT_MSG_TYPES_BEGIN + 0)
+#define SIR_MNT_MSG_TYPES_END          (SIR_MNT_MSG_TYPES_BEGIN + 0xFF)
+
+/* ****************************************** *
+*                                            *
+*         EVENT TYPE Definitions              *
+*                                            *
+* ****************************************** */
+
+/* MMH Events that are used in other modules to post events to MMH */
+#define SIR_HSTEMUL_TXMB_DONE_EVT         0x00000100
+#define SIR_HSTEMUL_RXMB_READY_EVT        0x00000200
+#define SIR_HSTEMUL_MSGQ_NE_EVT           0x00000400
+
+#define SIR_TST_XMIT_MSG_QS_EMPTY_EVT     0x00000080
+
+/* Param Change Bitmap sent to HAL */
+#define PARAM_BCN_INTERVAL_CHANGED                      (1 << 0)
+#define PARAM_SHORT_PREAMBLE_CHANGED                 (1 << 1)
+#define PARAM_SHORT_SLOT_TIME_CHANGED                 (1 << 2)
+#define PARAM_llACOEXIST_CHANGED                            (1 << 3)
+#define PARAM_llBCOEXIST_CHANGED                            (1 << 4)
+#define PARAM_llGCOEXIST_CHANGED                            (1 << 5)
+#define PARAM_HT20MHZCOEXIST_CHANGED                  (1<<6)
+#define PARAM_NON_GF_DEVICES_PRESENT_CHANGED (1<<7)
+#define PARAM_RIFS_MODE_CHANGED                            (1<<8)
+#define PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED   (1<<9)
+#define PARAM_OBSS_MODE_CHANGED                               (1<<10)
+#define PARAM_BSS_COLOR_CHANGED			(1 << 11)
+#define PARAM_BEACON_UPDATE_MASK    (PARAM_BCN_INTERVAL_CHANGED | \
+				     PARAM_SHORT_PREAMBLE_CHANGED | \
+				     PARAM_SHORT_SLOT_TIME_CHANGED | \
+				     PARAM_llACOEXIST_CHANGED | \
+				     PARAM_llBCOEXIST_CHANGED | \
+				     PARAM_llGCOEXIST_CHANGED | \
+				     PARAM_HT20MHZCOEXIST_CHANGED | \
+				     PARAM_NON_GF_DEVICES_PRESENT_CHANGED | \
+				     PARAM_RIFS_MODE_CHANGED | \
+				     PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED | \
+				     PARAM_OBSS_MODE_CHANGED | \
+				     PARAM_BSS_COLOR_CHANGED)
+
+#endif
diff --git a/core/mac/src/include/sys_global.h b/core/mac/src/include/sys_global.h
new file mode 100644
index 0000000..98c6980
--- /dev/null
+++ b/core/mac/src/include/sys_global.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013-2014, 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.
+ */
+
+#ifndef __SYS_GLOBAL_H__
+#define __SYS_GLOBAL_H__
+
+typedef struct sAniSirSys {
+	uint32_t gSysFrameCount[4][16];
+	uint32_t gSysBbtReceived;
+	uint32_t sys_bbt_pending_mgmt_count;
+	uint32_t gSysBbtPostedToLim;
+	uint32_t gSysBbtDropped;
+	uint32_t gSysEnableLinkMonitorMode;
+	qdf_spinlock_t bbt_mgmt_lock;
+} tAniSirSys, *tpAniSirSys;
+
+#endif
diff --git a/core/mac/src/include/utils_api.h b/core/mac/src/include/utils_api.h
new file mode 100644
index 0000000..82143cf
--- /dev/null
+++ b/core/mac/src/include/utils_api.h
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#ifndef __UTILSAPI_H
+#define __UTILSAPI_H
+
+#include <stdarg.h>
+#include <sir_common.h>
+#include "ani_global.h"
+#include "sys_wrapper.h"
+#include "wlan_vdev_mlme_api.h"
+
+/* / System role definition on a per BSS */
+typedef enum eBssSystemRole {
+	eSYSTEM_UNKNOWN_ROLE,
+	eSYSTEM_AP_ROLE,
+	eSYSTEM_STA_IN_IBSS_ROLE,
+	eSYSTEM_STA_ROLE,
+	eSYSTEM_BTAMP_STA_ROLE,
+	eSYSTEM_BTAMP_AP_ROLE,
+
+	eSYSTEM_LAST_ROLE,
+	eSYSTEM_MULTI_BSS_ROLE = eSYSTEM_LAST_ROLE
+} tBssSystemRole;
+
+QDF_STATUS cfg_init(tpAniSirGlobal);
+void cfg_de_init(tpAniSirGlobal);
+
+/**
+ * sir_swap_u16()
+ *
+ * FUNCTION:
+ * This function is called to swap two U8s of an uint16_t value
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  val    uint16_t value to be uint8_t swapped
+ * @return        Swapped uint16_t value
+ */
+
+static inline uint16_t sir_swap_u16(uint16_t val)
+{
+	return ((val & 0x00FF) << 8) | ((val & 0xFF00) >> 8);
+} /*** end sir_swap_u16() ***/
+
+/**
+ * sir_swap_u16if_needed()
+ *
+ * FUNCTION:
+ * This function is called to swap two U8s of an uint16_t value depending
+ * on endiannes of the target processor/compiler the software is
+ * running on
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  val    uint16_t value to be uint8_t swapped
+ * @return        Swapped uint16_t value
+ */
+
+static inline uint16_t sir_swap_u16if_needed(uint16_t val)
+{
+#ifndef ANI_LITTLE_BYTE_ENDIAN
+	return sir_swap_u16(val);
+#else
+	return val;
+#endif
+} /*** end sir_swap_u16if_needed() ***/
+
+/**
+ * sir_swap_u32()
+ *
+ * FUNCTION:
+ * This function is called to swap four U8s of an uint32_t value
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  val    uint32_t value to be uint8_t swapped
+ * @return        Swapped uint32_t value
+ */
+
+static inline uint32_t sir_swap_u32(uint32_t val)
+{
+	return (val << 24) |
+		(val >> 24) |
+		((val & 0x0000FF00) << 8) | ((val & 0x00FF0000) >> 8);
+} /*** end sir_swap_u32() ***/
+
+/**
+ * sir_swap_u32if_needed()
+ *
+ * FUNCTION:
+ * This function is called to swap U8s of an uint32_t value depending
+ * on endiannes of the target processor/compiler the software is
+ * running on
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  val    uint32_t value to be uint8_t swapped
+ * @return        Swapped uint32_t value
+ */
+
+static inline uint32_t sir_swap_u32if_needed(uint32_t val)
+{
+#ifndef ANI_LITTLE_BYTE_ENDIAN
+	return sir_swap_u32(val);
+#else
+	return val;
+#endif
+} /*** end sir_swap_u32if_needed() ***/
+
+/**
+ * sir_swap_u32_buf
+ *
+ * FUNCTION:
+ * It swaps N dwords into the same buffer
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  ptr address of uint32_t array
+ * @return void
+ *
+ */
+
+static inline void sir_swap_u32_buf(uint32_t *ptr, uint32_t nWords)
+{
+	uint32_t i;
+
+	for (i = 0; i < nWords; i++)
+		ptr[i] = sir_swap_u32(ptr[i]);
+}
+
+/**
+ * sir_swap_u32_buf_if_needed()
+ *
+ * FUNCTION:
+ * This function is called to swap U8s of U32s in the buffer depending
+ * on endiannes of the target processor/compiler the software is
+ * running on
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  pBuf   Buffer that will get swapped
+ * @param  nWords Number DWORDS will be swapped
+ * @return        void
+ */
+
+static inline void sir_swap_u32_buf_if_needed(uint32_t *pBuf, uint32_t nWords)
+{
+#ifdef ANI_LITTLE_BYTE_ENDIAN
+	sir_swap_u32_buf(pBuf, nWords);
+#endif
+} /*** end sir_swap_u32if_needed() ***/
+
+/**
+ * sir_swap_bd_if_needed
+ *
+ * FUNCTION:
+ * Byte swap all the dwords in the BD, except the PHY/MAC headers
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  pBd    BD that will get swapped
+ * @return        void
+ */
+
+static inline void sir_swap_bd_if_needed(uint32_t *pBd)
+{
+	sir_swap_u32_buf_if_needed(pBd, 6);
+	sir_swap_u32_buf_if_needed(pBd + 18, 14);
+}
+
+/**
+ * sir_store_u16_n
+ *
+ * FUNCTION:
+ * It stores a 16 bit number into the byte array in network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  ptr address of destination byte array
+ * @param  val value to store
+ * @return None
+ */
+
+static inline void sir_store_u16_n(uint8_t *ptr, uint16_t val)
+{
+	*ptr++ = (val >> 8) & 0xff;
+	*ptr = val & 0xff;
+}
+
+/**
+ * sir_store_u32_n
+ *
+ * FUNCTION:
+ * It stores a 32 bit number into the byte array in network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  ptr address of destination byte array
+ * @param  val value to store
+ * @return None
+ */
+
+static inline void sir_store_u32_n(uint8_t *ptr, uint32_t val)
+{
+	*ptr++ = (uint8_t) (val >> 24) & 0xff;
+	*ptr++ = (uint8_t) (val >> 16) & 0xff;
+	*ptr++ = (uint8_t) (val >> 8) & 0xff;
+	*ptr = (uint8_t) (val) & 0xff;
+}
+
+/**
+ * sir_store_u16
+ *
+ * FUNCTION:
+ * It stores a 16 bit number into the byte array in NON-network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  ptr address of destination byte array
+ * @param  val value to store
+ * @return None
+ */
+
+static inline void sir_store_u16(uint8_t *ptr, uint16_t val)
+{
+	*ptr++ = val & 0xff;
+	*ptr = (val >> 8) & 0xff;
+}
+
+/**
+ * sir_store_u32
+ *
+ * FUNCTION:
+ * It stores a 32 bit number into the byte array in NON-network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  ptr address of destination byte array
+ * @param  val value to store
+ * @return None
+ */
+
+static inline void sir_store_u32(uint8_t *ptr, uint32_t val)
+{
+	*ptr++ = (uint8_t) val & 0xff;
+	*ptr++ = (uint8_t) (val >> 8) & 0xff;
+	*ptr++ = (uint8_t) (val >> 16) & 0xff;
+	*ptr = (uint8_t) (val >> 24) & 0xff;
+}
+
+/**
+ * sir_store_u32BufN
+ *
+ * FUNCTION:
+ * It stores a 32 bit number into the byte array in network byte order
+ * i.e. the least significant byte first. It performs the above operation
+ * on entire buffer and writes to the dst buffer
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * Assumes that the pSrc buffer is of all uint32_t data type fields.
+ *
+ * NOTE:
+ * Must be used if all the fields in the buffer must be of uint32_t types.
+ *
+ * @param  pDst   address of destination byte array
+ * @param  pSrc   address of the source DWORD array
+ * @param  length number of DWORDs
+ * @return None
+ */
+
+static inline void
+sir_store_buf_n(uint8_t *pDst, uint32_t *pSrc, uint32_t length)
+{
+	while (length) {
+		sir_store_u32_n(pDst, *pSrc);
+		pDst += 4;
+		pSrc++;
+		length--;
+	}
+}
+
+/**
+ * sir_read_u16_n
+ *
+ * FUNCTION:
+ * It reads a 16 bit number from the byte array in network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  ptr address of  byte array
+ * @return 16 bit value
+ */
+
+static inline uint16_t sir_read_u16_n(uint8_t *ptr)
+{
+	return ((*ptr) << 8) | (*(ptr + 1));
+}
+
+/**
+ * sir_swap_u32_buf
+ *
+ * FUNCTION:
+ * It swaps N dwords into the same buffer
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  ptr address of uint32_t array
+ * @return void
+ *
+ */
+
+static inline void
+sir_swap_n_store(uint32_t *src, uint32_t *dst, uint32_t nWords)
+{
+	uint32_t i;
+
+	for (i = 0; i < nWords; i++)
+		dst[i] = sir_swap_u32(src[i]);
+}
+
+/**
+ * sir_read_u32_n
+ *
+ * FUNCTION:
+ * It reads a 32 bit number from the byte array in network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  ptr address of  byte array
+ * @return 32 bit value
+ */
+
+static inline uint32_t sir_read_u32_n(uint8_t *ptr)
+{
+	return (*(ptr) << 24) |
+		(*(ptr + 1) << 16) | (*(ptr + 2) << 8) | (*(ptr + 3));
+}
+
+/**
+ * sir_read_u16
+ *
+ * FUNCTION:
+ * It reads a 16 bit number from the byte array in NON-network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  ptr address of  byte array
+ * @return 16 bit value
+ */
+
+static inline uint16_t sir_read_u16(uint8_t *ptr)
+{
+	return (*ptr) | (*(ptr + 1) << 8);
+}
+
+/**
+ * sir_read_u32
+ *
+ * FUNCTION:
+ * It reads a 32 bit number from the byte array in NON-network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param  ptr address of  byte array
+ * @return 32 bit value
+ */
+
+static inline uint32_t sir_read_u32(uint8_t *ptr)
+{
+	return (*(ptr)) |
+		(*(ptr + 1) << 8) | (*(ptr + 2) << 16) | (*(ptr + 3) << 24);
+}
+
+/* / Copy a MAC address from 'from' to 'to' */
+static inline void sir_copy_mac_addr(uint8_t to[], uint8_t from[])
+{
+#if defined(_X86_)
+	uint32_t align = (0x3 & ((uint32_t) to | (uint32_t) from));
+
+	if (align == 0) {
+		*((uint16_t *) &(to[4])) = *((uint16_t *) &(from[4]));
+		*((uint32_t *) to) = *((uint32_t *) from);
+	} else if (align == 2) {
+		*((uint16_t *) &to[4]) = *((uint16_t *) &from[4]);
+		*((uint16_t *) &to[2]) = *((uint16_t *) &from[2]);
+		*((uint16_t *) &to[0]) = *((uint16_t *) &from[0]);
+	} else {
+		to[5] = from[5];
+		to[4] = from[4];
+		to[3] = from[3];
+		to[2] = from[2];
+		to[1] = from[1];
+		to[0] = from[0];
+	}
+#else
+	to[0] = from[0];
+	to[1] = from[1];
+	to[2] = from[2];
+	to[3] = from[3];
+	to[4] = from[4];
+	to[5] = from[5];
+#endif
+}
+
+static inline uint8_t sir_compare_mac_addr(uint8_t addr1[], uint8_t addr2[])
+{
+#if defined(_X86_)
+	uint32_t align = (0x3 & ((uint32_t) addr1 | (uint32_t) addr2));
+
+	if (align == 0) {
+		return (*((uint16_t *) &(addr1[4])) ==
+			 *((uint16_t *) &(addr2[4])))
+			&& (*((uint32_t *) addr1) == *((uint32_t *) addr2));
+	} else if (align == 2) {
+		return (*((uint16_t *) &addr1[4]) ==
+			 *((uint16_t *) &addr2[4]))
+			&& (*((uint16_t *) &addr1[2]) ==
+			    *((uint16_t *) &addr2[2]))
+			&& (*((uint16_t *) &addr1[0]) ==
+			    *((uint16_t *) &addr2[0]));
+	} else {
+		return (addr1[5] == addr2[5]) &&
+			(addr1[4] == addr2[4]) &&
+			(addr1[3] == addr2[3]) &&
+			(addr1[2] == addr2[2]) &&
+			(addr1[1] == addr2[1]) && (addr1[0] == addr2[0]);
+	}
+#else
+	return (addr1[0] == addr2[0]) &&
+		(addr1[1] == addr2[1]) &&
+		(addr1[2] == addr2[2]) &&
+		(addr1[3] == addr2[3]) &&
+		(addr1[4] == addr2[4]) && (addr1[5] == addr2[5]);
+#endif
+}
+
+/*
+ * converts uint16_t CW value to 4 bit value to be inserted in IE
+ */
+static inline uint8_t convert_cw(uint16_t cw)
+{
+	uint8_t val = 0;
+
+	while (cw > 0) {
+		val++;
+		cw >>= 1;
+	}
+	if (val > 15)
+		return 0xF;
+	return val;
+}
+
+/* The user priority to AC mapping is such:
+ *   UP(1, 2) ---> AC_BK(1)
+ *   UP(0, 3) ---> AC_BE(0)
+ *   UP(4, 5) ---> AC_VI(2)
+ *   UP(6, 7) ---> AC_VO(3)
+ */
+#define WLAN_UP_TO_AC_MAP            0x33220110
+#define upToAc(up)                ((WLAN_UP_TO_AC_MAP >> ((up) << 2)) & 0x03)
+
+/* ------------------------------------------------------------------- */
+
+/* New functions for endianness conversion */
+#ifdef ANI_LITTLE_BYTE_ENDIAN
+#define ani_cpu_to_be16(x) sir_swap_u16((x))
+#define ani_cpu_to_le16(x) (x)
+#define ani_cpu_to_be32(x) sir_swap_u32((x))
+#define ani_cpu_to_le32(x) (x)
+#else                           /* ANI_LITTLE_BYTE_ENDIAN */
+#define ani_cpu_to_be16(x) (x)
+#define ani_cpu_to_le16(x) sir_swap_u16((x))
+#define ani_cpu_to_be32(x) (x)
+#define ani_cpu_to_le32(x) sir_swap_u32((x))
+#endif /* ANI_LITTLE_BYTE_ENDIAN */
+
+#define ani_le16_to_cpu(x)  ani_cpu_to_le16(x)
+#define ani_le32_to_cpu(x)  ani_cpu_to_le32(x)
+#define ani_be16_to_cpu(x)  ani_cpu_to_be16(x)
+#define ani_be32_to_cpu(x)  ani_cpu_to_be32(x)
+
+#endif /* __UTILSAPI_H */
diff --git a/core/mac/src/pe/include/lim_admit_control.h b/core/mac/src/pe/include/lim_admit_control.h
new file mode 100644
index 0000000..b8cb161
--- /dev/null
+++ b/core/mac/src/pe/include/lim_admit_control.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2018 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.
+ */
+
+/*
+ *
+ * Author:      Dinesh Upadhyay
+ * Date:        10/24/06
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __LIM_ADMIT_CONTROL_H__
+#define __LIM_ADMIT_CONTROL_H__
+
+#include "sir_common.h"
+#include "sir_mac_prot_def.h"
+
+#include "ani_global.h"
+
+QDF_STATUS
+lim_tspec_find_by_assoc_id(tpAniSirGlobal, uint16_t, tSirMacTspecIE *,
+			   tpLimTspecInfo, tpLimTspecInfo *);
+
+/* Add TSPEC in lim local table */
+QDF_STATUS lim_tspec_add(tpAniSirGlobal pMac,
+			    uint8_t *pAddr,
+			    uint16_t assocId,
+			    tSirMacTspecIE *pTspec,
+			    uint32_t interval, tpLimTspecInfo *ppInfo);
+
+/* admit control interface */
+extern QDF_STATUS lim_admit_control_add_ts(tpAniSirGlobal pMac,
+				uint8_t *pAddr, tSirAddtsReqInfo *addts,
+				tSirMacQosCapabilityStaIE *qos,
+				uint16_t assocId, uint8_t alloc,
+				tSirMacScheduleIE *pSch,
+				/* index to the lim tspec table. */
+				uint8_t *pTspecIdx,
+				tpPESession psessionEntry);
+
+static inline QDF_STATUS
+lim_admit_control_add_sta(tpAniSirGlobal pMac, uint8_t *staAddr, uint8_t alloc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+extern QDF_STATUS
+lim_admit_control_delete_sta(tpAniSirGlobal pMac, uint16_t assocId);
+
+extern QDF_STATUS
+lim_admit_control_delete_ts(tpAniSirGlobal pMac,
+			    uint16_t assocId,
+			    tSirMacTSInfo *tsinfo,
+			    uint8_t *tsStatus, uint8_t *tspecIdx);
+
+QDF_STATUS lim_admit_control_init(tpAniSirGlobal pMac);
+#ifdef FEATURE_WLAN_ESE
+QDF_STATUS lim_send_hal_msg_add_ts(tpAniSirGlobal pMac,
+				      uint16_t staIdx,
+				      uint8_t tspecIdx,
+				      tSirMacTspecIE tspecIE,
+				      uint8_t sessionId, uint16_t tsm_interval);
+#else
+QDF_STATUS lim_send_hal_msg_add_ts(tpAniSirGlobal pMac,
+				      uint16_t staIdx,
+				      uint8_t tspecIdx,
+				      tSirMacTspecIE tspecIE,
+				      uint8_t sessionId);
+#endif
+
+QDF_STATUS lim_send_hal_msg_del_ts(tpAniSirGlobal pMac,
+				      uint16_t staIdx,
+				      uint8_t tspecIdx,
+				      tSirDeltsReqInfo delts,
+				      uint8_t sessionId, uint8_t *bssId);
+void lim_process_hal_add_ts_rsp(tpAniSirGlobal pMac,
+				struct scheduler_msg *limMsg);
+
+#endif
diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h
new file mode 100644
index 0000000..26f1971
--- /dev/null
+++ b/core/mac/src/pe/include/lim_api.h
@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_api.h contains the definitions exported by
+ * LIM module.
+ * Author:        Chandra Modumudi
+ * Date:          02/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_API_H
+#define __LIM_API_H
+#include "wni_api.h"
+#include "sir_api.h"
+#include "ani_global.h"
+#include "sir_mac_prot_def.h"
+#include "sir_common.h"
+#include "sir_debug.h"
+#include "sch_global.h"
+#include "utils_api.h"
+#include "lim_global.h"
+#include "wma_if.h"
+#include "wma_types.h"
+#include "scheduler_api.h"
+
+/* Macro to count heartbeat */
+#define limResetHBPktCount(psessionEntry)   (psessionEntry->LimRxedBeaconCntDuringHB = 0)
+
+/* Useful macros for fetching various states in pMac->lim */
+/* gLimSystemRole */
+#define GET_LIM_SYSTEM_ROLE(psessionEntry)      (psessionEntry->limSystemRole)
+#define LIM_IS_AP_ROLE(psessionEntry)           (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_AP_ROLE)
+#define LIM_IS_STA_ROLE(psessionEntry)          (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_ROLE)
+#define LIM_IS_IBSS_ROLE(psessionEntry)         (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_IN_IBSS_ROLE)
+#define LIM_IS_UNKNOWN_ROLE(psessionEntry)      (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_UNKNOWN_ROLE)
+#define LIM_IS_P2P_DEVICE_ROLE(psessionEntry)   (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_P2P_DEVICE_ROLE)
+#define LIM_IS_P2P_DEVICE_GO(psessionEntry)     (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_P2P_DEVICE_GO)
+#define LIM_IS_NDI_ROLE(psessionEntry) \
+		(GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_NDI_ROLE)
+/* gLimSmeState */
+#define GET_LIM_SME_STATE(pMac)                 (pMac->lim.gLimSmeState)
+#define SET_LIM_SME_STATE(pMac, state)          (pMac->lim.gLimSmeState = state)
+/* gLimMlmState */
+#define GET_LIM_MLM_STATE(pMac)                 (pMac->lim.gLimMlmState)
+#define SET_LIM_MLM_STATE(pMac, state)          (pMac->lim.gLimMlmState = state)
+/*tpdphHashNode mlmStaContext*/
+#define GET_LIM_STA_CONTEXT_MLM_STATE(pStaDs)   (pStaDs->mlmStaContext.mlmState)
+#define SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs, state)  (pStaDs->mlmStaContext.mlmState = state)
+/* gLimQuietState */
+#define GET_LIM_QUIET_STATE(pMac)               (pMac->lim.gLimSpecMgmt.quietState)
+#define SET_LIM_QUIET_STATE(pMac, state)        (pMac->lim.gLimSpecMgmt.quietState = state)
+#define LIM_IS_CONNECTION_ACTIVE(psessionEntry)  (psessionEntry->LimRxedBeaconCntDuringHB)
+/*pMac->lim.gLimProcessDefdMsgs*/
+#define GET_LIM_PROCESS_DEFD_MESGS(pMac) (pMac->lim.gLimProcessDefdMsgs)
+#define SET_LIM_PROCESS_DEFD_MESGS(pMac, val) \
+		pMac->lim.gLimProcessDefdMsgs = val; \
+		pe_debug("%s Defer LIM messages - value %d", __func__, val);
+
+/* LIM exported function templates */
+#define LIM_MIN_BCN_PR_LENGTH  12
+#define LIM_BCN_PR_CAPABILITY_OFFSET 10
+#define LIM_ASSOC_REQ_IE_OFFSET 4
+
+/**
+ * enum lim_vendor_ie_access_policy - vendor ie access policy
+ * @LIM_ACCESS_POLICY_NONE: access policy not valid
+ * @LIM_ACCESS_POLICY_RESPOND_IF_IE_IS_PRESENT: respond only if vendor ie
+ *         is present in probe request and assoc request frames
+ * @LIM_ACCESS_POLICY_DONOT_RESPOND_IF_IE_IS_PRESENT: do not respond if vendor
+ *         ie is present in probe request or assoc request frames
+ */
+enum lim_vendor_ie_access_policy {
+	LIM_ACCESS_POLICY_NONE,
+	LIM_ACCESS_POLICY_RESPOND_IF_IE_IS_PRESENT,
+	LIM_ACCESS_POLICY_DONOT_RESPOND_IF_IE_IS_PRESENT,
+};
+
+typedef enum eMgmtFrmDropReason {
+	eMGMT_DROP_NO_DROP,
+	eMGMT_DROP_NOT_LAST_IBSS_BCN,
+	eMGMT_DROP_INFRA_BCN_IN_IBSS,
+	eMGMT_DROP_SCAN_MODE_FRAME,
+	eMGMT_DROP_NON_SCAN_MODE_FRAME,
+	eMGMT_DROP_INVALID_SIZE,
+	eMGMT_DROP_SPURIOUS_FRAME,
+	eMGMT_DROP_DUPLICATE_AUTH_FRAME,
+	eMGMT_DROP_EXCESSIVE_MGMT_FRAME,
+} tMgmtFrmDropReason;
+
+/**
+ * Function to initialize LIM state machines.
+ * This called upon LIM thread creation.
+ */
+extern QDF_STATUS lim_initialize(tpAniSirGlobal);
+QDF_STATUS pe_open(tpAniSirGlobal pMac, struct cds_config_info *cds_cfg);
+QDF_STATUS pe_close(tpAniSirGlobal pMac);
+void pe_register_tl_handle(tpAniSirGlobal pMac);
+QDF_STATUS lim_start(tpAniSirGlobal pMac);
+QDF_STATUS pe_start(tpAniSirGlobal pMac);
+void pe_stop(tpAniSirGlobal pMac);
+QDF_STATUS peProcessMsg(tpAniSirGlobal pMac, struct scheduler_msg *limMsg);
+
+/**
+ * pe_register_mgmt_rx_frm_callback() - registers callback for receiving
+ *                                      mgmt rx frames
+ * @mac_ctx: mac global ctx
+ *
+ * This function registers a PE function to mgmt txrx component and a WMA
+ * function to WMI layer as event handler for receiving mgmt frames.
+ *
+ * Return: None
+ */
+void pe_register_mgmt_rx_frm_callback(tpAniSirGlobal mac_ctx);
+
+/**
+ * pe_deregister_mgmt_rx_frm_callback() - degisters callback for receiving
+ *                                        mgmt rx frames
+ * @mac_ctx: mac global ctx
+ *
+ * This function deregisters the PE function registered to mgmt txrx component
+ * and the WMA function registered to WMI layer as event handler for receiving
+ * mgmt frames.
+ *
+ * Return: None
+ */
+void pe_deregister_mgmt_rx_frm_callback(tpAniSirGlobal mac_ctx);
+
+/**
+ * pe_register_callbacks_with_wma() - register SME and PE callback functions to
+ * WMA.
+ * @pMac: mac global ctx
+ * @ready_req: Ready request parameters, containing callback pointers
+ *
+ * Return: None
+ */
+void pe_register_callbacks_with_wma(tpAniSirGlobal pMac,
+				    tSirSmeReadyReq *ready_req);
+
+/**
+ * Function to cleanup LIM state.
+ * This called upon reset/persona change etc
+ */
+extern void lim_cleanup(tpAniSirGlobal);
+
+/**
+ * lim_post_msg_api() - post normal priority PE message
+ * @mac: mac context
+ * @msg: message to be posted
+ *
+ * This function is called to post a message to the tail of the PE
+ * message queue to be processed in the MC Thread with normal
+ * priority.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, other QDF_STATUS on error
+ */
+QDF_STATUS lim_post_msg_api(tpAniSirGlobal mac, struct scheduler_msg *msg);
+
+/**
+ * lim_post_msg_high_priority() - post high priority PE message
+ * @mac: mac context
+ * @msg: message to be posted
+ *
+ * This function is called to post a message to the head of the PE
+ * message queue to be processed in the MC Thread with expedited
+ * priority.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, other QDF_STATUS on error
+ */
+QDF_STATUS lim_post_msg_high_priority(tpAniSirGlobal mac,
+				      struct scheduler_msg *msg);
+
+/**
+ * Function to process messages posted to LIM thread
+ * and dispatch to various sub modules within LIM module.
+ */
+extern void lim_message_processor(tpAniSirGlobal, struct scheduler_msg *);
+/**
+ * Function to check the LIM state if system is in Scan/Learn state.
+ */
+extern uint8_t lim_is_system_in_scan_state(tpAniSirGlobal);
+/**
+ * Function to handle IBSS coalescing.
+ * Beacon Processing module to call this.
+ */
+extern QDF_STATUS lim_handle_ibss_coalescing(tpAniSirGlobal,
+						tpSchBeaconStruct,
+						uint8_t *, tpPESession);
+/* / Function used by other Sirius modules to read global SME state */
+static inline tLimSmeStates lim_get_sme_state(tpAniSirGlobal pMac)
+{
+	return pMac->lim.gLimSmeState;
+}
+
+extern void lim_received_hb_handler(tpAniSirGlobal, uint8_t, tpPESession);
+extern void limCheckAndQuietBSS(tpAniSirGlobal);
+/* / Function that triggers STA context deletion */
+extern void lim_trigger_sta_deletion(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+				     tpPESession psessionEntry);
+
+#ifdef FEATURE_WLAN_TDLS
+/* Function that sends TDLS Del Sta indication to SME */
+extern void lim_send_sme_tdls_del_sta_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+					  tpPESession psessionEntry,
+					  uint16_t reasonCode);
+/**
+ * lim_set_tdls_flags() - update tdls flags based on newer STA connection
+ * information
+ * @roam_sync_ind_ptr: pointer to roam offload structure
+ * @ft_session_ptr: pointer to PE session
+ *
+ * Set TDLS flags as per new STA connection capabilities.
+ *
+ * Return: None
+ */
+void lim_set_tdls_flags(roam_offload_synch_ind *roam_sync_ind_ptr,
+		   tpPESession ft_session_ptr);
+#else
+static inline void lim_set_tdls_flags(roam_offload_synch_ind *roam_sync_ind_ptr,
+		   tpPESession ft_session_ptr)
+{
+}
+#endif
+
+/* / Function that checks for change in AP's capabilties on STA */
+extern void lim_detect_change_in_ap_capabilities(tpAniSirGlobal,
+						 tpSirProbeRespBeacon, tpPESession);
+QDF_STATUS lim_update_short_slot(tpAniSirGlobal pMac,
+				    tpSirProbeRespBeacon pBeacon,
+				    tpUpdateBeaconParams pBeaconParams,
+				    tpPESession);
+
+void lim_ps_offload_handle_missed_beacon_ind(tpAniSirGlobal pMac,
+					     struct scheduler_msg *pMsg);
+void lim_send_heart_beat_timeout_ind(tpAniSirGlobal pMac, tpPESession psessionEntry);
+tMgmtFrmDropReason lim_is_pkt_candidate_for_drop(tpAniSirGlobal pMac,
+						 uint8_t *pRxPacketInfo,
+						 uint32_t subType);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx,
+	struct sSirSmeRoamOffloadSynchInd *roam_sync_ind_ptr,
+	tpSirBssDescription  bss_desc_ptr, enum sir_roam_op_code reason);
+#else
+static inline QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx,
+	struct sSirSmeRoamOffloadSynchInd *roam_sync_ind_ptr,
+	tpSirBssDescription  bss_desc_ptr, enum sir_roam_op_code reason)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+
+/**
+ * lim_update_lost_link_info() - update lost link information to SME
+ * @mac: global MAC handle
+ * @session: PE session
+ * @rssi: rssi value from the received frame
+ *
+ * Return: None
+ */
+void lim_update_lost_link_info(tpAniSirGlobal mac, tpPESession session,
+				int32_t rssi);
+
+/**
+ * lim_mon_init_session() - create PE session for monitor mode operation
+ * @mac_ptr: mac pointer
+ * @msg: Pointer to struct sir_create_session type.
+ *
+ * Return: NONE
+ */
+void lim_mon_init_session(tpAniSirGlobal mac_ptr,
+			  struct sir_create_session *msg);
+
+#define limGetQosMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limQosEnabled)
+#define limGetWmeMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWmeEnabled)
+#define limGetWsmMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWsmEnabled)
+#define limGet11dMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->lim11dEnabled)
+/* ----------------------------------------------------------------------- */
+static inline void lim_get_phy_mode(tpAniSirGlobal pMac, uint32_t *phyMode,
+				    tpPESession psessionEntry)
+{
+	*phyMode =
+		psessionEntry ? psessionEntry->gLimPhyMode : pMac->lim.gLimPhyMode;
+}
+
+/* ----------------------------------------------------------------------- */
+static inline void lim_get_rf_band_new(tpAniSirGlobal pMac,
+				       enum band_info *band,
+				       tpPESession psessionEntry)
+{
+	*band = psessionEntry ? psessionEntry->limRFBand : BAND_UNKNOWN;
+}
+
+/**
+ * pe_mc_process_handler() - Message Processor for PE
+ * @msg: Pointer to the message structure
+ *
+ * Verifies the system is in a mode where messages are expected to be
+ * processed, and if so, routes the message to the appropriate handler
+ * based upon message type.
+ *
+ * Return: QDF_STATUS_SUCCESS if the message was handled, otherwise an
+ *         appropriate QDF_STATUS error code
+ */
+QDF_STATUS pe_mc_process_handler(struct scheduler_msg *msg);
+
+/** -------------------------------------------------------------
+   \fn pe_free_msg
+   \brief Called by CDS scheduler (function cds_sched_flush_mc_mqs)
+ \      to free a given PE message on the TX and MC thread.
+ \      This happens when there are messages pending in the PE
+ \      queue when system is being stopped and reset.
+   \param   tpAniSirGlobal pMac
+   \param   struct scheduler_msg       pMsg
+   \return none
+   -----------------------------------------------------------------*/
+void pe_free_msg(tpAniSirGlobal pMac, struct scheduler_msg *pMsg);
+
+/*--------------------------------------------------------------------------
+
+   \brief lim_remain_on_chn_rsp() - API for sending remain on channel response.
+
+   LIM calls this api to send the remain on channel response to SME.
+
+   \param pMac - Pointer to Global MAC structure
+   \param status - status of the response
+   \param data - pointer to msg
+
+   \return  void
+
+   --------------------------------------------------------------------------*/
+void lim_remain_on_chn_rsp(tpAniSirGlobal pMac, QDF_STATUS status, uint32_t *data);
+
+/**
+ * lim_process_abort_scan_ind() - abort the scan which is presently being run
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @vdev_id: vdev_id
+ * @scan_id: Scan ID from the scan request
+ * @scan_requesor_id: Entity requesting the scan
+ *
+ * @return: None
+ */
+void lim_process_abort_scan_ind(tpAniSirGlobal pMac, uint8_t vdev_id,
+	uint32_t scan_id, uint32_t scan_requestor_id);
+
+void __lim_process_sme_assoc_cnf_new(tpAniSirGlobal, uint32_t, uint32_t *);
+
+/**
+ * lim_process_sme_addts_rsp_timeout(): Send addts rsp timeout to SME
+ * @pMac: Pointer to Global MAC structure
+ * @param: Addts rsp timer count
+ *
+ * This function is used to reset the addts sent flag and
+ * send addts rsp timeout to SME
+ *
+ * Return: None
+ */
+void lim_process_sme_addts_rsp_timeout(tpAniSirGlobal pMac, uint32_t param);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+void lim_fill_join_rsp_ht_caps(tpPESession session, tpSirSmeJoinRsp rsp);
+#else
+static inline void lim_fill_join_rsp_ht_caps(tpPESession session,
+	tpSirSmeJoinRsp rsp)
+{}
+#endif
+QDF_STATUS lim_update_ext_cap_ie(tpAniSirGlobal mac_ctx,
+	uint8_t *ie_data, uint8_t *local_ie_buf, uint16_t *local_ie_len);
+
+/**
+ * lim_handle_sap_beacon(): Handle the beacon received from scan module for SAP
+ * @pdev: pointer to the pdev object
+ * @scan_entry: pointer to the scan cache entry for the beacon
+ *
+ * Registered as callback to the scan module for handling beacon frames.
+ * This API filters the and allows beacons for SAP protection mechanisms
+ * if there are active SAP sessions and the received beacon's channel
+ * matches the SAP active channel
+ *
+ * Return: None
+ */
+void lim_handle_sap_beacon(struct wlan_objmgr_pdev *pdev,
+					struct scan_cache_entry *scan_entry);
+
+/************************************************************/
+#endif /* __LIM_API_H */
diff --git a/core/mac/src/pe/include/lim_fils_defs.h b/core/mac/src/pe/include/lim_fils_defs.h
new file mode 100644
index 0000000..c109763
--- /dev/null
+++ b/core/mac/src/pe/include/lim_fils_defs.h
@@ -0,0 +1,273 @@
+/*
+ * 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.
+ */
+
+#define FILS_EAP_TLV_MAX_DATA_LEN 255
+#define FILS_SHA256_128_AUTH_TAG 16
+#define FILS_SHA256_256_AUTH_TAG 32
+
+#define FILS_SHA256_CRYPTO_TYPE "hmac(sha256)"
+#define FILS_SHA384_CRYPTO_TYPE "hmac(sha384)"
+
+/* RFC 6696 */
+#define RMSK_LABEL "Re-authentication Master Session Key@ietf.org"
+
+/* 12.12.2.5.3 80211-ai draft */
+#define PTK_KEY_LABEL "FILS PTK Derivation"
+#define MAX_ICK_LEN 48
+#define MAX_KEK_LEN 64
+#define MAX_TK_LEN 32
+#define MAX_KEY_AUTH_DATA_LEN 48
+#define MAX_GTK_LEN 255
+#define MAX_IGTK_LEN 255
+#define SIR_FILS_SESSION_IE_LEN 11
+#define FILS_KEY_RSC_LEN 8
+#define FILS_MAX_KEY_AUTH_LEN (MAX_ICK_LEN + MAX_KEK_LEN + MAX_TK_LEN)
+
+#define IPN_LEN 6
+#define FILS_SESSION_LENGTH 8
+#define FILS_MAX_KDE_LIST_LEN 255
+#define FILS_MAX_HLP_DATA_LEN 2048
+
+/* 12.12.2.5.3 80211-ai draft */
+#define FILS_SHA384_KEK_LEN 64
+#define FILS_SHA256_KEK_LEN 32
+
+/* 12.12.2.5.3 80211-ai draft */
+#define FILS_SHA256_ICK_LEN 32
+#define FILS_SHA384_ICK_LEN 48
+
+#define TK_LEN_TKIP 32
+#define TK_LEN_CCMP 16
+#define TK_LEN_AES_128_CMAC 32
+
+#define FILS_SHA256_PKM_LEN 32
+#define FILS_SHA384_PKM_LEN 48
+
+#define PMKID_LEN 16
+
+#define MAX_PRF_INTERATIONS_COUNT 255
+
+/* 9.4.2.180 FILS Session element */
+#define SIR_FILS_SESSION_LENGTH    8
+#define SIR_FILS_SESSION_EXT_EID   4
+
+/* 9.4.2.184 FILS HLP Container Element */
+#define SIR_FILS_HLP_EXT_EID 5
+
+/* 9.4.2.190 FILS Nonce element */
+#define SIR_FILS_NONCE_LENGTH      16
+#define SIR_FILS_NONCE_EXT_EID   13
+
+/*9.4.2.188 FILS Wrapped Data element */
+#define SIR_FILS_WRAPPED_DATA_MAX_SIZE 255
+#define SIR_FILS_WRAPPED_DATA_EXT_EID   8
+
+#define MAX_IE_LENGTH 255
+
+/* RFC 6696 5.3.1: EAP-Initiate/Re-auth-Start Packet */
+#define SIR_FILS_EAP_REAUTH_PACKET_TYPE 1
+#define SIR_FILS_EAP_INIT_PACKET_TYPE 2
+
+#define FILS_AUTH_TAG_MAX_LENGTH 32
+
+#define SIR_FILS_OPTIONAL_DATA_LEN 3
+/* RFC 6696 4.3: RiK deriavtion */
+#define SIR_FILS_RIK_LABEL "Re-authentication Integrity Key@ietf.org"
+
+/* RFC 6696 5.3.1: EAP-Initiate/Re-auth-Start Packet */
+#define SIR_FILS_EAP_TLV_KEYNAME_NAI 1
+#define SIR_FILS_EAP_TLV_R_RK_LIFETIME 2
+#define SIR_FILS_EAP_TLV_R_MSK_LIFETIME 3
+#define SIR_FILS_EAP_TLV_DOMAIN_NAME 4
+#define SIR_FILS_EAP_TLV_CRYPTO_LIST 5
+#define SIR_FILS_EAP_TLV_AUTH_INDICATION 6
+
+#define DATA_TYPE_GTK 1
+#define DATA_TYPE_IGTK 9
+#define KEY_RSC_LEN 8
+#define KDE_IE_DATA_OFFSET 4
+#define KDE_DATA_TYPE_OFFSET 3
+#define GTK_OFFSET 2
+#define IPN_OFFSET 2
+#define IGTK_OFFSET 8
+
+#define KDE_OUI_TYPE   "\x00\x0F\xAC"
+#define KDE_OUI_TYPE_SIZE  3
+
+#define SINGLE_ELEMENT_HASH_CNT 1
+
+/*
+ * struct eap_auth_reserved: this structure defines flags format in eap packets
+ * as defined in RFC 6696 5.3.1
+ * flag_r:
+ * flag_b:
+ * flag_l:
+ */
+struct eap_auth_reserved {
+	uint8_t flag_r:1;
+	uint8_t flag_b:1;
+	uint8_t flag_l:1;
+	uint8_t reverved:5;
+};
+
+/*
+ * enum fils_erp_cryptosuite: this enum defines the cryptosuites used
+ * to calculate auth tag and auth tag length as defined by RFC 6696 5.3.1
+ * @HMAC_SHA256_64: sha256 with auth tag len as 64 bits
+ * @HMAC_SHA256_128: sha256 with auth tag len as 128 bits
+ * @HMAC_SHA256_256: sha256 with auth tag len as 256 bits
+ */
+enum fils_erp_cryptosuite {
+	INVALID_CRYPTO = 0, /* reserved */
+	HMAC_SHA256_64,
+	HMAC_SHA256_128,
+	HMAC_SHA256_256,
+};
+
+/*
+ * struct fils_eap_tlv: this structure defines the eap header
+ * for eap packet present in warpped data element IE
+ * @type: type of packet
+ * @length: length of packet
+ * @data: pointer to eap data
+ */
+struct fils_eap_tlv {
+	uint8_t type;
+	uint8_t length;
+	uint8_t data[FILS_EAP_TLV_MAX_DATA_LEN];
+};
+
+/* struct fils_auth_rsp_info: this structure saves the info from
+ * fils auth response.
+ * @keyname: pointer to keyname nai
+ * @keylength: keyname nai length
+ * @domain_name: pointer to domain name
+ * @domain_len: domain length
+ * @r_rk_lifetime: rRk lifetime
+ * @r_msk_lifetime: RMSK lifetime
+ * @sequence: sequence number to be validated
+ * @fils_nonce: anonce
+ * @assoc_delay: time in ms, DUT needs to wait after association req
+ */
+struct fils_auth_rsp_info {
+	uint8_t *keyname;
+	uint8_t keylength;
+	uint8_t *domain_name;
+	uint8_t domain_len;
+	uint32_t r_rk_lifetime;
+	uint32_t r_msk_lifetime;
+	uint16_t sequence;
+	uint8_t fils_nonce[SIR_FILS_NONCE_LENGTH];
+	uint8_t assoc_delay;
+};
+
+/*
+ * struct pe_fils_session: fils session info used in PE session
+ * @is_fils_connection: whether connection is fils or not
+ * @keyname_nai_data: keyname nai data
+ * @keyname_nai_length: keyname nai length
+ * @akm: akm type will be used
+ * @auth: authentication type
+ * @cipher: cipher type
+ * @fils_erp_reauth_pkt: pointer to fils reauth packet data
+ * @fils_erp_reauth_pkt_len: reauth packet length
+ * @fils_rrk: pointer to fils rRk
+ * @fils_rrk_len: fils rRk length
+ * @fils_rik: pointer to fils rIk
+ * @fils_rik_len: fils rIk length
+ * @sequence_number: sequence number needs to be used in eap packet
+ * @fils_session: fils session IE element
+ * @fils_nonce: fils snonce
+ * @rsn_ie: rsn ie used in auth request
+ * @rsn_ie_len: rsn ie length
+ * @fils_eap_finish_pkt: pointer to eap finish packet
+ * @fils_eap_finish_pkt_len: eap finish packet length
+ * @fils_rmsk: rmsk data pointer
+ * @fils_rmsk_len: rmsk data length
+ * @fils_pmk: pointer to pmk data
+ * @fils_pmk_len: pmk length
+ * @fils_pmkid: pointer to pmkid derived
+ * @auth_info: data obtained from auth response
+ * @ick: pointer to ick
+ * @ick_len: ick length
+ * @kek: pointer to kek
+ * @kek_len: kek length
+ * @tk: pointer to tk
+ * @tk_len: tk length
+ * @key_auth: data needs to be sent in assoc req, will be validated by AP
+ * @key_auth_len: key auth data length
+ * @ap_key_auth_data: data needs to be validated in assoc rsp
+ * @ap_key_auth_len:  ap key data length
+ * @gtk_len: gtk key length
+ * @gtk: pointer to gtk data
+ * @rsc: rsc value
+ * @igtk_len: igtk length
+ * @igtk: igtk data pointer
+ * @ipn: pointer to ipn data
+ * @dst_mac: HLP destination mac address
+ * @src_mac: HLP source mac address
+ * @hlp_data_len: HLP data length
+ * @hlp_data: pointer to HLP data
+ */
+struct pe_fils_session {
+	bool is_fils_connection;
+	uint8_t *keyname_nai_data;
+	uint8_t keyname_nai_length;
+	uint8_t akm;
+	uint8_t auth;
+	uint8_t cipher;
+	uint8_t *fils_erp_reauth_pkt;
+	uint32_t fils_erp_reauth_pkt_len;
+	uint8_t *fils_rrk;
+	uint8_t fils_rrk_len;
+	uint8_t *fils_rik;
+	uint32_t fils_rik_len;
+	uint16_t sequence_number;
+	uint8_t fils_session[SIR_FILS_SESSION_LENGTH];
+	uint8_t fils_nonce[SIR_FILS_NONCE_LENGTH];
+	uint8_t rsn_ie[MAX_IE_LENGTH];
+	uint8_t rsn_ie_len;
+	uint8_t *fils_eap_finish_pkt;
+	uint8_t fils_eap_finish_pkt_len;
+	uint8_t *fils_rmsk;
+	uint8_t fils_rmsk_len;
+	uint8_t *fils_pmk;
+	uint8_t fils_pmk_len;
+	uint8_t fils_pmkid[PMKID_LEN];
+	struct fils_auth_rsp_info auth_info;
+	uint8_t ick[MAX_ICK_LEN];
+	uint8_t ick_len;
+	uint8_t kek[MAX_KEK_LEN];
+	uint8_t kek_len;
+	uint8_t tk[MAX_TK_LEN];
+	uint8_t tk_len;
+	uint8_t key_auth[MAX_KEY_AUTH_DATA_LEN];
+	uint8_t key_auth_len;
+	uint8_t ap_key_auth_data[MAX_KEY_AUTH_DATA_LEN];
+	uint8_t ap_key_auth_len;
+	uint8_t gtk_len;
+	uint8_t gtk[MAX_GTK_LEN];
+	uint8_t rsc;
+	uint8_t igtk_len;
+	uint8_t igtk[MAX_IGTK_LEN];
+	uint8_t ipn[IPN_LEN];
+	struct qdf_mac_addr dst_mac;
+	struct qdf_mac_addr src_mac;
+	uint16_t hlp_data_len;
+	uint8_t *hlp_data;
+};
diff --git a/core/mac/src/pe/include/lim_ft.h b/core/mac/src/pe/include/lim_ft.h
new file mode 100644
index 0000000..1c01af3
--- /dev/null
+++ b/core/mac/src/pe/include/lim_ft.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**=========================================================================
+
+   Macros and Function prototypes FT and 802.11R purposes
+
+   ========================================================================*/
+
+#ifndef __LIMFT_H__
+#define __LIMFT_H__
+
+#include <cds_api.h>
+#include <lim_global.h>
+#include <ani_global.h>
+#include <lim_ser_des_utils.h>
+
+/*-------------------------------------------------------------------------
+   Function declarations and documenation
+   ------------------------------------------------------------------------*/
+void lim_ft_open(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void lim_ft_cleanup(tpAniSirGlobal pMac, tpPESession psessionEntry);
+#ifdef WLAN_FEATURE_HOST_ROAM
+void lim_ft_cleanup_pre_auth_info(tpAniSirGlobal pMac,
+		tpPESession psessionEntry);
+int lim_process_ft_pre_auth_req(tpAniSirGlobal pMac,
+				struct scheduler_msg *pMsg);
+void lim_process_ft_preauth_rsp_timeout(tpAniSirGlobal pMac);
+
+/**
+ * lim_process_mlm_ft_reassoc_req() - Handle the Reassoc request
+ * @pMac: Global MAC context
+ * @reassoc_req: reassoc req
+ *
+ *  This function handles the Reassoc Req from SME
+ *
+ *  Return: None
+ */
+void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac,
+				    tLimMlmReassocReq *reassoc_req);
+void lim_perform_ft_pre_auth(tpAniSirGlobal pMac, QDF_STATUS status,
+		uint32_t *data, tpPESession psessionEntry);
+void lim_post_ft_pre_auth_rsp(tpAniSirGlobal pMac, QDF_STATUS status,
+		uint8_t *auth_rsp, uint16_t auth_rsp_length,
+		tpPESession psessionEntry);
+void lim_handle_ft_pre_auth_rsp(tpAniSirGlobal pMac, QDF_STATUS status,
+		uint8_t *auth_rsp, uint16_t auth_rsp_len,
+		tpPESession psessionEntry);
+QDF_STATUS lim_ft_setup_auth_session(tpAniSirGlobal pMac,
+		tpPESession psessionEntry);
+void lim_process_mlm_reassoc_cnf(tpAniSirGlobal mac_ctx, uint32_t *msg);
+void lim_process_sta_mlm_add_bss_rsp_ft(tpAniSirGlobal pMac,
+		struct scheduler_msg *limMsgQ, tpPESession psessionEntry);
+void lim_process_mlm_reassoc_req(tpAniSirGlobal mac_ctx,
+				 tLimMlmReassocReq *reassoc_req);
+void lim_preauth_scan_event_handler(tpAniSirGlobal mac_ctx,
+				enum sir_scan_event_type event,
+				uint8_t session_id,
+				uint32_t scan_id);
+QDF_STATUS lim_send_preauth_scan_offload(tpAniSirGlobal mac_ctx,
+		tpPESession session_entry, tSirFTPreAuthReq *ft_preauth_req);
+#else
+static inline void lim_ft_cleanup_pre_auth_info(tpAniSirGlobal pMac,
+		tpPESession psessionEntry)
+{}
+static inline void lim_process_ft_preauth_rsp_timeout(tpAniSirGlobal pMac)
+{}
+static inline
+void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac,
+				    tLimMlmReassocReq *reassoc_req)
+{}
+static inline void lim_handle_ft_pre_auth_rsp(tpAniSirGlobal pMac,
+		QDF_STATUS status, uint8_t *auth_rsp,
+		uint16_t auth_rsp_len, tpPESession psessionEntry)
+{}
+static inline void lim_process_mlm_reassoc_cnf(tpAniSirGlobal mac_ctx,
+		uint32_t *msg)
+{}
+static inline void lim_process_sta_mlm_add_bss_rsp_ft(tpAniSirGlobal pMac,
+		struct scheduler_msg *limMsgQ, tpPESession psessionEntry)
+{}
+static inline void lim_process_mlm_reassoc_req(tpAniSirGlobal mac_ctx,
+					       tLimMlmReassocReq *reassoc_req)
+{}
+static inline void lim_preauth_scan_event_handler(tpAniSirGlobal mac_ctx,
+		enum sir_scan_event_type event,
+		uint8_t session_id, uint32_t scan_id)
+{}
+static inline int lim_process_ft_pre_auth_req(tpAniSirGlobal pMac,
+		struct scheduler_msg *pMsg)
+{
+	return 0;
+}
+#endif
+
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+void lim_fill_ft_session(tpAniSirGlobal pMac,
+		tpSirBssDescription pbssDescription,
+		tpPESession pftSessionEntry,
+		tpPESession psessionEntry);
+void lim_ft_prepare_add_bss_req(tpAniSirGlobal pMac, uint8_t updateEntry,
+		tpPESession pftSessionEntry,
+		tpSirBssDescription bssDescription);
+QDF_STATUS lim_send_preauth_scan_offload(tpAniSirGlobal mac_ctx,
+		tpPESession session_entry, tSirFTPreAuthReq *ft_preauth_req);
+#else
+static inline void lim_fill_ft_session(tpAniSirGlobal pMac,
+		tpSirBssDescription pbssDescription,
+		tpPESession pftSessionEntry,
+		tpPESession psessionEntry)
+{}
+static inline void lim_ft_prepare_add_bss_req(tpAniSirGlobal pMac,
+		uint8_t updateEntry, tpPESession pftSessionEntry,
+		tpSirBssDescription bssDescription)
+{}
+#endif
+
+bool lim_process_ft_update_key(tpAniSirGlobal pMac, uint32_t *pMsgBuf);
+QDF_STATUS lim_process_ft_aggr_qos_req(tpAniSirGlobal pMac,
+		uint32_t *pMsgBuf);
+void lim_process_ft_aggr_qo_s_rsp(tpAniSirGlobal pMac,
+				  struct scheduler_msg *limMsg);
+void lim_ft_cleanup_all_ft_sessions(tpAniSirGlobal pMac);
+#endif /* __LIMFT_H__ */
diff --git a/core/mac/src/pe/include/lim_ft_defs.h b/core/mac/src/pe/include/lim_ft_defs.h
new file mode 100644
index 0000000..909143c
--- /dev/null
+++ b/core/mac/src/pe/include/lim_ft_defs.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/**=========================================================================
+
+   Macros and Function prototypes FT and 802.11R purposes
+
+   ========================================================================*/
+
+#ifndef __LIMFTDEFS_H__
+#define __LIMFTDEFS_H__
+
+#include <cds_api.h>
+#include "wma_if.h"
+
+/*--------------------------------------------------------------------------
+   Preprocessor definitions and constants
+   ------------------------------------------------------------------------*/
+#define MAX_FTIE_SIZE             384   /* Max size limited to 384, on acct. of IW custom events */
+
+/* Time to dwell on preauth channel during roaming, in milliseconds */
+#define LIM_FT_PREAUTH_SCAN_TIME 50
+
+/*--------------------------------------------------------------------------
+   Type declarations
+   ------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------
+   FT Pre Auth Req SME<->PE
+   ------------------------------------------------------------------------*/
+typedef struct sSirFTPreAuthReq {
+	uint16_t messageType;   /* eWNI_SME_FT_PRE_AUTH_REQ */
+	uint16_t length;
+	uint32_t dot11mode;
+	/*
+	 * Track if response is processed for this request
+	 * We expect only one response per request.
+	 */
+	bool bPreAuthRspProcessed;
+	uint8_t preAuthchannelNum;
+	/* BSSID currently associated to suspend the link */
+	tSirMacAddr currbssId;
+	tSirMacAddr preAuthbssId;       /* BSSID to preauth to */
+	tSirMacAddr self_mac_addr;
+	uint32_t scan_id;
+	uint16_t ft_ies_length;
+	uint8_t ft_ies[MAX_FTIE_SIZE];
+	tpSirBssDescription pbssDescription;
+} tSirFTPreAuthReq, *tpSirFTPreAuthReq;
+
+/*-------------------------------------------------------------------------
+   FT Pre Auth Rsp PE<->SME
+   ------------------------------------------------------------------------*/
+typedef struct sSirFTPreAuthRsp {
+	uint16_t messageType;   /* eWNI_SME_FT_PRE_AUTH_RSP */
+	uint16_t length;
+	uint8_t smeSessionId;
+	tSirMacAddr preAuthbssId;       /* BSSID to preauth to */
+	QDF_STATUS status;
+	uint16_t ft_ies_length;
+	uint8_t ft_ies[MAX_FTIE_SIZE];
+	uint16_t ric_ies_length;
+	uint8_t ric_ies[MAX_FTIE_SIZE];
+} tSirFTPreAuthRsp, *tpSirFTPreAuthRsp;
+
+/*--------------------------------------------------------------------------
+   FT Pre Auth Rsp Key SME<->PE
+   ------------------------------------------------------------------------*/
+typedef struct sSirFTUpdateKeyInfo {
+	uint16_t messageType;
+	uint16_t length;
+	uint32_t smeSessionId;
+	struct qdf_mac_addr bssid;
+	tSirKeyMaterial keyMaterial;
+} tSirFTUpdateKeyInfo, *tpSirFTUpdateKeyInfo;
+
+/*--------------------------------------------------------------------------
+   FT Pre Auth Rsp Key SME<->PE
+   ------------------------------------------------------------------------*/
+typedef struct sSirFTPreAuthKeyInfo {
+	uint8_t extSetStaKeyParamValid; /* Ext Bss Config Msg if set */
+	/* SetStaKeyParams for ext bss msg */
+	tLimMlmSetKeysReq extSetStaKeyParam;
+} tSirFTPreAuthKeyInfo, *tpSirFTPreAuthKeyInfo;
+
+/*-------------------------------------------------------------------------
+   Global FT Information
+   ------------------------------------------------------------------------*/
+typedef struct sFTPEContext {
+	tpSirFTPreAuthReq pFTPreAuthReq;        /* Saved FT Pre Auth Req */
+	QDF_STATUS ftPreAuthStatus;
+	uint16_t saved_auth_rsp_length;
+	uint8_t saved_auth_rsp[MAX_FTIE_SIZE];
+	tSirFTPreAuthKeyInfo PreAuthKeyInfo;
+	/* Items created for the new FT, session */
+	void *pAddBssReq;       /* Save add bss req */
+	void *pAddStaReq;       /*Save add sta req  */
+	uint32_t peSessionId;
+	uint32_t smeSessionId;
+
+	/* This flag is required to indicate on which session the preauth
+	 * has taken place, since the auth response for preauth will come
+	 * for a new BSSID for which there is no session yet. This flag
+	 * will be used to extract the session from the session preauth
+	 * has been initiated
+	 */
+	bool ftPreAuthSession;
+} tftPEContext, *tpftPEContext;
+
+#endif /* __LIMFTDEFS_H__ */
diff --git a/core/mac/src/pe/include/lim_global.h b/core/mac/src/pe/include/lim_global.h
new file mode 100644
index 0000000..2f19145
--- /dev/null
+++ b/core/mac/src/pe/include/lim_global.h
@@ -0,0 +1,581 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_global.h contains the definitions exported by
+ * LIM module.
+ * Author:        Chandra Modumudi
+ * Date:          02/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_GLOBAL_H
+#define __LIM_GLOBAL_H
+
+#include "wni_api.h"
+#include "sir_api.h"
+#include "sir_mac_prot_def.h"
+#include "sir_mac_prop_exts.h"
+#include "sir_common.h"
+#include "sir_debug.h"
+#include "wni_cfg.h"
+#include "csr_api.h"
+#include "sap_api.h"
+#include "dot11f.h"
+#include "wma_if.h"
+
+/* Deferred Message Queue Length */
+#define MAX_DEFERRED_QUEUE_LEN                  80
+
+/* Maximum number of PS - TIM's to be sent with out wakeup from STA */
+#define LIM_TIM_WAIT_COUNT_FACTOR          5
+
+/*
+ * Use this count if (LIM_TIM_WAIT_FACTOR * ListenInterval)
+ * is less than LIM_MIN_TIM_WAIT_CNT
+ */
+#define LIM_MIN_TIM_WAIT_COUNT          50
+
+#define GET_TIM_WAIT_COUNT(LIntrvl) \
+	((LIntrvl * LIM_TIM_WAIT_COUNT_FACTOR) > LIM_MIN_TIM_WAIT_COUNT ? \
+	(LIntrvl * LIM_TIM_WAIT_COUNT_FACTOR) : LIM_MIN_TIM_WAIT_COUNT)
+
+#ifdef CHANNEL_HOPPING_ALL_BANDS
+#define CHAN_HOP_ALL_BANDS_ENABLE        1
+#else
+#define CHAN_HOP_ALL_BANDS_ENABLE        0
+#endif
+
+/* enums exported by LIM are as follows */
+
+/*System role definition */
+typedef enum eLimSystemRole {
+	eLIM_UNKNOWN_ROLE,
+	eLIM_AP_ROLE,
+	eLIM_STA_IN_IBSS_ROLE,
+	eLIM_STA_ROLE,
+	eLIM_P2P_DEVICE_ROLE,
+	eLIM_P2P_DEVICE_GO,
+	eLIM_P2P_DEVICE_CLIENT,
+	eLIM_NDI_ROLE
+} tLimSystemRole;
+
+/*
+ * SME state definition accessible across all Sirius modules.
+ * AP only states are LIM_SME_CHANNEL_SCAN_STATE &
+ * LIM_SME_NORMAL_CHANNEL_SCAN_STATE.
+ * Note that these states may also be present in STA
+ * side too when DFS support is present for a STA in IBSS mode.
+ */
+typedef enum eLimSmeStates {
+	eLIM_SME_OFFLINE_STATE,
+	eLIM_SME_IDLE_STATE,
+	eLIM_SME_SUSPEND_STATE,
+	eLIM_SME_WT_SCAN_STATE,
+	eLIM_SME_WT_JOIN_STATE,
+	eLIM_SME_WT_AUTH_STATE,
+	eLIM_SME_WT_ASSOC_STATE,
+	eLIM_SME_WT_REASSOC_STATE,
+	eLIM_SME_JOIN_FAILURE_STATE,
+	eLIM_SME_ASSOCIATED_STATE,
+	eLIM_SME_REASSOCIATED_STATE,
+	eLIM_SME_LINK_EST_STATE,
+	eLIM_SME_LINK_EST_WT_SCAN_STATE,
+	eLIM_SME_WT_PRE_AUTH_STATE,
+	eLIM_SME_WT_DISASSOC_STATE,
+	eLIM_SME_WT_DEAUTH_STATE,
+	eLIM_SME_WT_START_BSS_STATE,
+	eLIM_SME_WT_STOP_BSS_STATE,
+	eLIM_SME_NORMAL_STATE,
+	eLIM_SME_CHANNEL_SCAN_STATE,
+	eLIM_SME_NORMAL_CHANNEL_SCAN_STATE
+} tLimSmeStates;
+
+/*
+ * MLM state definition.
+ * While these states are present on AP too when it is
+ * STA mode, per-STA MLM state exclusive to AP is:
+ * eLIM_MLM_WT_AUTH_FRAME3.
+ */
+typedef enum eLimMlmStates {
+	eLIM_MLM_OFFLINE_STATE,
+	eLIM_MLM_IDLE_STATE,
+	eLIM_MLM_WT_PROBE_RESP_STATE,
+	eLIM_MLM_PASSIVE_SCAN_STATE,
+	eLIM_MLM_WT_JOIN_BEACON_STATE,
+	eLIM_MLM_JOINED_STATE,
+	eLIM_MLM_BSS_STARTED_STATE,
+	eLIM_MLM_WT_AUTH_FRAME2_STATE,
+	eLIM_MLM_WT_AUTH_FRAME3_STATE,
+	eLIM_MLM_WT_AUTH_FRAME4_STATE,
+	eLIM_MLM_AUTH_RSP_TIMEOUT_STATE,
+	eLIM_MLM_AUTHENTICATED_STATE,
+	eLIM_MLM_WT_ASSOC_RSP_STATE,
+	eLIM_MLM_WT_REASSOC_RSP_STATE,
+	eLIM_MLM_ASSOCIATED_STATE,
+	eLIM_MLM_REASSOCIATED_STATE,
+	eLIM_MLM_LINK_ESTABLISHED_STATE,
+	eLIM_MLM_WT_ASSOC_CNF_STATE,
+	eLIM_MLM_LEARN_STATE,
+	eLIM_MLM_WT_ADD_BSS_RSP_STATE,
+	eLIM_MLM_WT_DEL_BSS_RSP_STATE,
+	eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE,
+	eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE,
+	eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE,
+	eLIM_MLM_WT_ADD_STA_RSP_STATE,
+	eLIM_MLM_WT_DEL_STA_RSP_STATE,
+	/*
+	 * MLM goes to this state when LIM initiates DELETE_STA
+	 * as processing of Assoc req because the entry already exists.
+	 * LIM comes out of this state when DELETE_STA response from
+	 * HAL is received. LIM needs to maintain this state so that ADD_STA
+	 * can be issued while processing DELETE_STA response from HAL.
+	 */
+	eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE,
+	eLIM_MLM_WT_SET_BSS_KEY_STATE,
+	eLIM_MLM_WT_SET_STA_KEY_STATE,
+	eLIM_MLM_WT_SET_STA_BCASTKEY_STATE,
+	eLIM_MLM_WT_SET_MIMOPS_STATE,
+	eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE,
+	eLIM_MLM_WT_FT_REASSOC_RSP_STATE,
+	eLIM_MLM_P2P_LISTEN_STATE,
+	eLIM_MLM_WT_SAE_AUTH_STATE,
+} tLimMlmStates;
+
+/* 11h channel quiet states */
+
+/*
+ * This enum indicates in which state the device is in
+ * when it receives quiet element in beacon or probe-response.
+ * The default quiet state of the device is always INIT
+ * eLIM_QUIET_BEGIN - When Quiet period is started
+ * eLIM_QUIET_CHANGED - When Quiet period is updated
+ * eLIM_QUIET_RUNNING - Between two successive Quiet updates
+ * eLIM_QUIET_END - When quiet period ends
+ */
+typedef enum eLimQuietStates {
+	eLIM_QUIET_INIT,
+	eLIM_QUIET_BEGIN,
+	eLIM_QUIET_CHANGED,
+	eLIM_QUIET_RUNNING,
+	eLIM_QUIET_END
+} tLimQuietStates;
+
+/* 11h channel switch states */
+
+/*
+ * This enum indicates in which state the channel-swith
+ * is presently operating.
+ * eLIM_11H_CHANSW_INIT - Default state
+ * eLIM_11H_CHANSW_RUNNING - When channel switch is running
+ * eLIM_11H_CHANSW_END - After channel switch is complete
+ */
+typedef enum eLimDot11hChanSwStates {
+	eLIM_11H_CHANSW_INIT,
+	eLIM_11H_CHANSW_RUNNING,
+	eLIM_11H_CHANSW_END
+} tLimDot11hChanSwStates;
+
+/* MLM Req/Cnf structure definitions */
+typedef struct sLimMlmAuthReq {
+	tSirMacAddr peerMacAddr;
+	tAniAuthType authType;
+	uint8_t sessionId;
+} tLimMlmAuthReq, *tpLimMlmAuthReq;
+
+typedef struct sLimMlmJoinReq {
+	tSirMacRateSet operationalRateSet;
+	uint8_t sessionId;
+	tSirBssDescription bssDescription;
+	/*
+	 * WARNING: Pls make bssDescription as last variable in struct
+	 * tLimMlmJoinReq as it has ieFields followed after this bss
+	 * description. Adding a variable after this corrupts the ieFields
+	 */
+} tLimMlmJoinReq, *tpLimMlmJoinReq;
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
+/* OEM Data related structure definitions */
+typedef struct sLimMlmOemDataReq {
+	struct qdf_mac_addr selfMacAddr;
+	uint32_t data_len;
+	uint8_t *data;
+} tLimMlmOemDataReq, *tpLimMlmOemDataReq;
+
+typedef struct sLimMlmOemDataRsp {
+	bool target_rsp;
+	uint32_t rsp_len;
+	uint8_t *oem_data_rsp;
+} tLimMlmOemDataRsp, *tpLimMlmOemDataRsp;
+#endif
+
+/* Pre-authentication structure definition */
+typedef struct tLimPreAuthNode {
+	struct tLimPreAuthNode *next;
+	tSirMacAddr peerMacAddr;
+	tAniAuthType authType;
+	tLimMlmStates mlmState;
+	uint8_t authNodeIdx;
+	uint8_t challengeText[SIR_MAC_AUTH_CHALLENGE_LENGTH];
+	uint8_t fTimerStarted:1;
+	uint8_t fSeen:1;
+	uint8_t fFree:1;
+	uint8_t rsvd:5;
+	TX_TIMER timer;
+	uint16_t seq_num;
+	unsigned long timestamp;
+} tLimPreAuthNode, *tpLimPreAuthNode;
+
+/* Pre-authentication table definition */
+typedef struct tLimPreAuthTable {
+	uint32_t numEntry;
+	tLimPreAuthNode **pTable;
+} tLimPreAuthTable, *tpLimPreAuthTable;
+
+/* / Per STA context structure definition */
+typedef struct sLimMlmStaContext {
+	tLimMlmStates mlmState;
+	tAniAuthType authType;
+	uint16_t listenInterval;
+	tSirMacCapabilityInfo capabilityInfo;
+	tSirMacReasonCodes disassocReason;
+
+	tSirResultCodes resultCode;
+
+	tSirMacPropRateSet propRateSet;
+	uint8_t subType:1;      /* Indicates ASSOC (0) or REASSOC (1) */
+	uint8_t updateContext:1;
+	uint8_t schClean:1;
+	/* 802.11n HT Capability in Station: Enabled 1 or DIsabled 0 */
+	uint8_t htCapability:1;
+	uint8_t vhtCapability:1;
+	uint16_t cleanupTrigger;
+	uint16_t protStatusCode;
+#ifdef WLAN_FEATURE_11AX
+	bool he_capable;
+#endif
+} tLimMlmStaContext, *tpLimMlmStaContext;
+
+/* Structure definition to hold deferred messages queue parameters */
+typedef struct sLimDeferredMsgQParams {
+	struct scheduler_msg deferredQueue[MAX_DEFERRED_QUEUE_LEN];
+	uint16_t size;
+	uint16_t read;
+	uint16_t write;
+} tLimDeferredMsgQParams, *tpLimDeferredMsgQParams;
+
+typedef struct sCfgProtection {
+	uint32_t overlapFromlla:1;
+	uint32_t overlapFromllb:1;
+	uint32_t overlapFromllg:1;
+	uint32_t overlapHt20:1;
+	uint32_t overlapNonGf:1;
+	uint32_t overlapLsigTxop:1;
+	uint32_t overlapRifs:1;
+	uint32_t overlapOBSS:1; /* added for obss */
+	uint32_t fromlla:1;
+	uint32_t fromllb:1;
+	uint32_t fromllg:1;
+	uint32_t ht20:1;
+	uint32_t nonGf:1;
+	uint32_t lsigTxop:1;
+	uint32_t rifs:1;
+	uint32_t obss:1;        /* added for Obss */
+} tCfgProtection, *tpCfgProtection;
+
+typedef enum eLimProtStaCacheType {
+	eLIM_PROT_STA_CACHE_TYPE_INVALID,
+	eLIM_PROT_STA_CACHE_TYPE_llB,
+	eLIM_PROT_STA_CACHE_TYPE_llG,
+	eLIM_PROT_STA_CACHE_TYPE_HT20
+} tLimProtStaCacheType;
+
+typedef struct sCacheParams {
+	uint8_t active;
+	tSirMacAddr addr;
+	tLimProtStaCacheType protStaCacheType;
+
+} tCacheParams, *tpCacheParams;
+
+#define LIM_PROT_STA_OVERLAP_CACHE_SIZE    HAL_NUM_ASSOC_STA
+#define LIM_PROT_STA_CACHE_SIZE            HAL_NUM_ASSOC_STA
+
+typedef struct sLimProtStaParams {
+	uint8_t numSta;
+	uint8_t protectionEnabled;
+} tLimProtStaParams, *tpLimProtStaParams;
+
+typedef struct sLimNoShortParams {
+	uint8_t numNonShortPreambleSta;
+	tCacheParams staNoShortCache[LIM_PROT_STA_CACHE_SIZE];
+} tLimNoShortParams, *tpLimNoShortParams;
+
+typedef struct sLimNoShortSlotParams {
+	uint8_t numNonShortSlotSta;
+	tCacheParams staNoShortSlotCache[LIM_PROT_STA_CACHE_SIZE];
+} tLimNoShortSlotParams, *tpLimNoShortSlotParams;
+
+typedef struct tLimIbssPeerNode tLimIbssPeerNode;
+struct tLimIbssPeerNode {
+	tLimIbssPeerNode *next;
+	tSirMacAddr peerMacAddr;
+	uint8_t extendedRatesPresent:1;
+	uint8_t edcaPresent:1;
+	uint8_t wmeEdcaPresent:1;
+	uint8_t wmeInfoPresent:1;
+	uint8_t htCapable:1;
+	uint8_t vhtCapable:1;
+	uint8_t rsvd:2;
+	uint8_t htSecondaryChannelOffset;
+	tSirMacCapabilityInfo capabilityInfo;
+	tSirMacRateSet supportedRates;
+	tSirMacRateSet extendedRates;
+	uint8_t supportedMCSSet[SIZE_OF_SUPPORTED_MCS_SET];
+	tSirMacEdcaParamSetIE edcaParams;
+	uint8_t erpIePresent;
+
+	/* HT Capabilities of IBSS Peer */
+	uint8_t htGreenfield;
+	uint8_t htShortGI40Mhz;
+	uint8_t htShortGI20Mhz;
+
+	/* DSSS/CCK at 40 MHz: Enabled 1 or Disabled */
+	uint8_t htDsssCckRate40MHzSupport;
+
+	/* MIMO Power Save */
+	tSirMacHTMIMOPowerSaveState htMIMOPSState;
+
+	/* */
+	/* A-MPDU Density */
+	/* 000 - No restriction */
+	/* 001 - 1/8 usec */
+	/* 010 - 1/4 usec */
+	/* 011 - 1/2 usec */
+	/* 100 - 1 usec */
+	/* 101 - 2 usec */
+	/* 110 - 4 usec */
+	/* 111 - 8 usec */
+	/* */
+	uint8_t htAMpduDensity;
+
+	/* Maximum Rx A-MPDU factor */
+	uint8_t htMaxRxAMpduFactor;
+
+	/* Set to 0 for 3839 octets */
+	/* Set to 1 for 7935 octets */
+	uint8_t htMaxAmsduLength;
+
+	/* */
+	/* Recommended Tx Width Set */
+	/* 0 - use 20 MHz channel (control channel) */
+	/* 1 - use 40 Mhz channel */
+	/* */
+	uint8_t htSupportedChannelWidthSet;
+
+	uint8_t htLdpcCapable;
+
+	uint8_t beaconHBCount;
+	uint8_t heartbeatFailure;
+
+	uint8_t *beacon;        /* Hold beacon to be sent to HDD/CSR */
+	uint16_t beaconLen;
+
+	tDot11fIEVHTCaps VHTCaps;
+	uint8_t vhtSupportedChannelWidthSet;
+	uint8_t vhtBeamFormerCapable;
+	/*
+	 * Peer Atim Info
+	 */
+	uint8_t atimIePresent;
+	uint32_t peerAtimWindowLength;
+};
+
+/* Enums used for channel switching. */
+typedef enum eLimChannelSwitchState {
+	eLIM_CHANNEL_SWITCH_IDLE,
+	eLIM_CHANNEL_SWITCH_PRIMARY_ONLY,
+	eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY
+} tLimChannelSwitchState;
+
+/* Channel Switch Info */
+typedef struct sLimChannelSwitchInfo {
+	tLimChannelSwitchState state;
+	uint8_t primaryChannel;
+	uint8_t ch_center_freq_seg0;
+	uint8_t ch_center_freq_seg1;
+	uint8_t sec_ch_offset;
+	enum phy_ch_width ch_width;
+	int8_t switchCount;
+	uint32_t switchTimeoutValue;
+	uint8_t switchMode;
+} tLimChannelSwitchInfo, *tpLimChannelSwitchInfo;
+
+typedef struct sLimOperatingModeInfo {
+	uint8_t present;
+	uint8_t chanWidth:2;
+	uint8_t reserved:2;
+	uint8_t rxNSS:3;
+	uint8_t rxNSSType:1;
+} tLimOperatingModeInfo, *tpLimOperatingModeInfo;
+
+typedef struct sLimWiderBWChannelSwitch {
+	uint8_t newChanWidth;
+	uint8_t newCenterChanFreq0;
+	uint8_t newCenterChanFreq1;
+} tLimWiderBWChannelSwitchInfo, *tpLimWiderBWChannelSwitchInfo;
+
+/* Enums used when stopping the Tx. */
+typedef enum eLimQuietTxMode {
+	/* Stop/resume transmission of all stations,Uses the global flag */
+	eLIM_TX_ALL = 0,
+	/*
+	 * Stops/resumes the transmission of specific stations identified
+	 * by staId.
+	 */
+	eLIM_TX_STA,
+	/* Stops/resumes the transmission of all the packets in BSS */
+	eLIM_TX_BSS,
+	/*
+	 * Stops/resumes the transmission of all packets except beacons in BSS
+	 * This is used when radar is detected in the current operating channel.
+	 * Beacon has to be sent to notify the stations associated about the
+	 * scheduled channel switch
+	 */
+	eLIM_TX_BSS_BUT_BEACON
+} tLimQuietTxMode;
+
+typedef enum eLimControlTx {
+	eLIM_RESUME_TX = 0,
+	eLIM_STOP_TX
+} tLimControlTx;
+
+/* -------------------------------------------------------------------- */
+
+typedef struct sLimTspecInfo {
+	/* 0==free, else used */
+	uint8_t inuse;
+	/* index in list */
+	uint8_t idx;
+	tSirMacAddr staAddr;
+	uint16_t assocId;
+	tSirMacTspecIE tspec;
+	/* number of Tclas elements */
+	uint8_t numTclas;
+	tSirTclasInfo tclasInfo[SIR_MAC_TCLASIE_MAXNUM];
+	uint8_t tclasProc;
+	/* tclassProc is valid only if this is set to 1. */
+	uint8_t tclasProcPresent:1;
+} qdf_packed tLimTspecInfo, *tpLimTspecInfo;
+
+typedef struct sLimAdmitPolicyInfo {
+	/* admit control policy type */
+	uint8_t type;
+	/* oversubscription factor : 0 means nothing is allowed */
+	uint8_t bw_factor;
+	/* valid only when 'type' is set BW_FACTOR */
+} tLimAdmitPolicyInfo, *tpLimAdmitPolicyInfo;
+
+typedef enum eLimWscEnrollState {
+	eLIM_WSC_ENROLL_NOOP,
+	eLIM_WSC_ENROLL_BEGIN,
+	eLIM_WSC_ENROLL_IN_PROGRESS,
+	eLIM_WSC_ENROLL_END
+} tLimWscEnrollState;
+
+#define WSC_PASSWD_ID_PUSH_BUTTON         (0x0004)
+
+typedef struct sLimWscIeInfo {
+	bool apSetupLocked;
+	bool selectedRegistrar;
+	uint16_t selectedRegistrarConfigMethods;
+	tLimWscEnrollState wscEnrollmentState;
+	tLimWscEnrollState probeRespWscEnrollmentState;
+	uint8_t reqType;
+	uint8_t respType;
+} tLimWscIeInfo, *tpLimWscIeInfo;
+
+/* maximum number of tspec's supported */
+#define LIM_NUM_TSPEC_MAX      15
+
+/* structure to hold all 11h specific data */
+typedef struct sLimSpecMgmtInfo {
+	tLimQuietStates quietState;
+	uint32_t quietCount;
+	/* This is in units of system TICKS */
+	uint32_t quietDuration;
+	/* This is in units of TU, for over the air transmission */
+	uint32_t quietDuration_TU;
+	/* After this timeout, actual quiet starts */
+	uint32_t quietTimeoutValue;
+	/* Used on AP, if quiet is enabled during learning */
+	bool fQuietEnabled;
+	tLimDot11hChanSwStates dot11hChanSwState;
+	/* Radar detected in cur oper chan on AP */
+	bool fRadarDetCurOperChan;
+	/* Whether radar interrupt has been configured */
+	bool fRadarIntrConfigured;
+} tLimSpecMgmtInfo, *tpLimSpecMgmtInfo;
+
+#ifdef FEATURE_WLAN_TDLS
+/*
+ * Peer info needed for TDLS setup..
+ */
+typedef struct tLimTDLSPeerSta {
+	struct tLimTDLSPeerSta *next;
+	uint8_t dialog;
+	tSirMacAddr peerMac;
+	tSirMacCapabilityInfo capabilityInfo;
+	tSirMacRateSet supportedRates;
+	tSirMacRateSet extendedRates;
+	tSirMacQosCapabilityStaIE qosCaps;
+	tSirMacEdcaParamSetIE edcaParams;
+	uint8_t mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
+	uint8_t tdls_bIsResponder;
+	/* HT Capabilties */
+	tDot11fIEHTCaps tdlsPeerHTCaps;
+	tDot11fIEExtCap tdlsPeerExtCaps;
+	uint8_t tdls_flags;
+	uint8_t tdls_link_state;
+	uint8_t tdls_prev_link_state;
+	uint8_t tdls_sessionId;
+	uint8_t ExtRatesPresent;
+	TX_TIMER gLimTdlsLinkSetupRspTimeoutTimer;
+	TX_TIMER gLimTdlsLinkSetupCnfTimeoutTimer;
+} tLimTdlsLinkSetupPeer, *tpLimTdlsLinkSetupPeer;
+
+typedef struct tLimTdlsLinkSetupInfo {
+	tLimTdlsLinkSetupPeer *tdlsLinkSetupList;
+	uint8_t num_tdls_peers;
+	uint8_t tdls_flags;
+	uint8_t tdls_state;
+	uint8_t tdls_prev_state;
+} tLimTdlsLinkSetupInfo, *tpLimTdlsLinkSetupInfo;
+
+typedef enum tdlsLinkMode {
+	TDLS_LINK_MODE_BG,
+	TDLS_LINK_MODE_N,
+	TDLS_LINK_MODE_AC,
+	TDLS_LINK_MODE_NONE
+} eLimTdlsLinkMode;
+#endif /* FEATURE_WLAN_TDLS */
+
+#endif
diff --git a/core/mac/src/pe/include/lim_process_fils.h b/core/mac/src/pe/include/lim_process_fils.h
new file mode 100644
index 0000000..3e6f9b9
--- /dev/null
+++ b/core/mac/src/pe/include/lim_process_fils.h
@@ -0,0 +1,282 @@
+/*
+ * 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.
+ */
+
+#include <cds_api.h>
+#include <lim_global.h>
+#include <ani_global.h>
+#include <lim_ser_des_utils.h>
+
+#ifdef WLAN_FEATURE_FILS_SK
+
+/**
+ * lim_process_fils_auth_frame2()- This API processes fils data from auth resp
+ * @mac_ctx: mac context
+ * @session: PE session
+ * @rx_auth_frm_body: pointer to auth frame
+ *
+ * Return: true if fils data needs to be processed else false
+ */
+bool lim_process_fils_auth_frame2(tpAniSirGlobal mac_ctx,
+				tpPESession pe_session,
+				tSirMacAuthFrameBody * rx_auth_frm_body);
+
+/**
+ * lim_add_fils_data_to_auth_frame()- This API adds fils data to auth frame.
+ * Following will be added in this.
+ *     1. RSNIE
+ *     2. SNonce
+ *     3. Session
+ *     4. Wrapped data
+ * @session: PE session
+ * @body: pointer to auth frame where data needs to be added
+ *
+ * Return: None
+ */
+void lim_add_fils_data_to_auth_frame(tpPESession session, uint8_t *body);
+
+/**
+ * lim_is_valid_fils_auth_frame()- This API checks whether auth frame is a
+ * valid frame.
+ * @mac_ctx: mac context
+ * @pe_session: pe session pointer
+ * @rx_auth_frm_body: pointer to autherntication frame
+ *
+ * Return: true if frame is valid or fils is disable, false otherwise
+ */
+bool lim_is_valid_fils_auth_frame(tpAniSirGlobal mac_ctx,
+	tpPESession pe_session, tSirMacAuthFrameBody *rx_auth_frm_body);
+
+/**
+ * lim_create_fils_rik()- This API create rik using rrk coming from
+ * supplicant.
+ * @rrk: input rrk
+ * @rrk_len: rrk length
+ * @rik: Created rik
+ * @rik_len: rik length to be filled
+ *
+ * rIK = KDF (K, S), where
+ * K = rRK and
+ * S = rIK Label + "\0" + cryptosuite + length
+ * The rIK Label is the 8-bit ASCII string:
+ * Re-authentication Integrity Key@ietf.org
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_create_fils_rik(uint8_t *rrk, uint8_t rrk_len,
+			       uint8_t *rik, uint32_t *rik_len);
+
+/**
+ * lim_update_fils_config()- This API updates fils session info to csr config
+ * from join request.
+ * @session: PE session
+ * @sme_join_req: pointer to join request
+ *
+ * Return: None
+ */
+void lim_update_fils_config(tpPESession session, tpSirSmeJoinReq sme_join_req);
+
+/**
+ * lim_create_fils_auth_data()- This API creates the fils auth data
+ * which needs to be sent in auth req.
+ * @mac_ctx: mac context
+ * @auth_frame: pointer to auth frame
+ * @session: PE session
+ *
+ * Return: length of fils data
+ */
+uint32_t lim_create_fils_auth_data(tpAniSirGlobal mac_ctx,
+		tpSirMacAuthFrameBody auth_frame, tpPESession session);
+
+/**
+ * lim_increase_fils_sequence_number: this API increases fils sequence number in
+ * the event of resending auth packet
+ * @session_entry: pointer to PE session
+ *
+ * Return: None
+ */
+static inline void lim_increase_fils_sequence_number(tpPESession session_entry)
+{
+	if (!session_entry->fils_info)
+		return;
+
+	if (session_entry->fils_info->is_fils_connection)
+		session_entry->fils_info->sequence_number++;
+}
+
+/**
+ * populate_fils_connect_params() - Populate FILS connect params to join rsp
+ * @mac_ctx: Mac context
+ * @session: PE session
+ * @sme_join_rsp: SME join rsp
+ *
+ * This API copies the FILS connect params from PE session to SME join rsp
+ *
+ * Return: None
+ */
+void populate_fils_connect_params(tpAniSirGlobal mac_ctx,
+				  tpPESession session,
+				  tpSirSmeJoinRsp sme_join_rsp);
+
+/**
+ * aead_encrypt_assoc_req() - Encrypt FILS IE's in assoc request
+ * @mac_ctx: mac context
+ * @pe_session: PE session
+ * @frame: packed frame buffer
+ * @payload: length of @frame
+ *
+ * This API is used to encrypt the all the IE present after FILS session IE
+ * in Association request frame
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS aead_encrypt_assoc_req(tpAniSirGlobal mac_ctx,
+				  tpPESession pe_session,
+				  uint8_t *frame, uint32_t *payload);
+
+/**
+ * aead_decrypt_assoc_rsp() - API for AEAD decryption in FILS connection
+ * @mac_ctx: MAC context
+ * @session: PE session
+ * @ar: Assoc response frame structure
+ * @p_frame: frame buffer received
+ * @n_frame: length of @p_frame
+ *
+ * This API is used to decrypt the AEAD encrypted part of FILS assoc response
+ * and populate the decrypted FILS IE's to Assoc response frame structure(ar)
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS aead_decrypt_assoc_rsp(tpAniSirGlobal mac_ctx,
+				  tpPESession session,
+				  tDot11fAssocResponse *ar,
+				  uint8_t *p_frame, uint32_t *n_frame);
+/**
+ * lim_is_fils_connection() - Check if it is FILS connection
+ * @pe_session: PE session
+ *
+ * This API is used to check if current PE session is FILS connection
+ *
+ * Return: True if FILS connection, false if not
+ */
+static inline bool lim_is_fils_connection(tpPESession pe_session)
+{
+	if (pe_session->fils_info->is_fils_connection)
+		return true;
+	return false;
+}
+
+/**
+ * lim_verify_fils_params_assoc_rsp() - Verify FILS params in assoc rsp
+ * @mac_ctx: Mac context
+ * @session_entry: PE session
+ * @assoc_rsp: Assoc response received
+ * @assoc_cnf: Assoc cnf msg to be sent to MLME
+ *
+ * This API is used to match FILS params received in Assoc response
+ * with Assoc params received/derived at the Authentication stage
+ *
+ * Return: True, if successfully matches. False, otherwise
+ */
+bool lim_verify_fils_params_assoc_rsp(tpAniSirGlobal mac_ctx,
+				      tpPESession session_entry,
+				      tpSirAssocRsp assoc_rsp,
+				      tLimMlmAssocCnf * assoc_cnf);
+
+/**
+ * lim_update_fils_rik() - API to update FILS RIK in RSO
+ * @pe_session: PE Session
+ * @req_buffer: Pointer to RSO request
+ *
+ * This API is used to calculate(if required) RIK and fill
+ * the same in RSO request to fw.
+ *
+ * Return: None
+ */
+void lim_update_fils_rik(tpPESession pe_session,
+			 tSirRoamOffloadScanReq *req_buffer);
+#else
+static inline bool lim_process_fils_auth_frame2(tpAniSirGlobal mac_ctx,
+		tpPESession pe_session, tSirMacAuthFrameBody *rx_auth_frm_body)
+{
+	return false;
+}
+
+static inline void
+lim_increase_fils_sequence_number(tpPESession session_entry)
+{ }
+
+static inline void
+lim_add_fils_data_to_auth_frame(tpPESession session, uint8_t *body)
+{
+}
+
+static inline bool lim_is_valid_fils_auth_frame(tpAniSirGlobal mac_ctx,
+	tpPESession pe_session, tSirMacAuthFrameBody *rx_auth_frm_body)
+{
+	return true;
+}
+
+static inline void
+lim_update_fils_config(tpPESession session, tpSirSmeJoinReq sme_join_req)
+{ }
+
+static inline uint32_t lim_create_fils_auth_data(tpAniSirGlobal mac_ctx,
+		tpSirMacAuthFrameBody auth_frame, tpPESession session)
+{
+	return 0;
+}
+
+static inline bool lim_is_fils_connection(tpPESession pe_session)
+{
+	return false;
+}
+
+static inline void populate_fils_connect_params(tpAniSirGlobal mac_ctx,
+						tpPESession session,
+						tpSirSmeJoinRsp sme_join_rsp)
+{ }
+
+static inline QDF_STATUS aead_encrypt_assoc_req(tpAniSirGlobal mac_ctx,
+						tpPESession pe_session,
+						uint8_t *frame,
+						uint32_t *payload)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS aead_decrypt_assoc_rsp(tpAniSirGlobal mac_ctx,
+				  tpPESession session,
+				  tDot11fAssocResponse *ar,
+				  uint8_t *p_frame, uint32_t *n_frame)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline bool lim_verify_fils_params_assoc_rsp(tpAniSirGlobal mac_ctx,
+			tpPESession session_entry,
+			tpSirAssocRsp assoc_rsp,
+			tLimMlmAssocCnf *assoc_cnf)
+
+{
+	return true;
+}
+
+static inline void lim_update_fils_rik(tpPESession pe_session,
+				       tSirRoamOffloadScanReq *req_buffer)
+{ }
+#endif
diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h
new file mode 100644
index 0000000..7c02727
--- /dev/null
+++ b/core/mac/src/pe/include/lim_session.h
@@ -0,0 +1,787 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#if !defined(__LIM_SESSION_H)
+#define __LIM_SESSION_H
+
+/**=========================================================================
+
+   \file  lim_session.h
+
+   \brief prototype for lim Session related APIs
+
+   \author Sunit Bhatia
+
+   ========================================================================*/
+
+/* Powersave Offload Implementation */
+typedef enum ePowersaveState {
+	PMM_FULL_POWER,
+	PMM_POWER_SAVE
+} tPowersaveState;
+
+/* Master Structure: This will be part of PE Session Entry */
+typedef struct sPowersaveoffloadInfo {
+	tPowersaveState psstate;
+	uint8_t bcnmiss;
+} tPowersaveoffloadInfo, tpPowersaveoffloadInfo;
+
+#ifdef WLAN_FEATURE_11W
+typedef struct tagComebackTimerInfo {
+	tpAniSirGlobal pMac;
+	uint8_t sessionID;
+	tLimMlmStates limPrevMlmState;  /* Previous MLM State */
+	tLimMlmStates limMlmState;      /* MLM State */
+} tComebackTimerInfo;
+#endif /* WLAN_FEATURE_11W */
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------------
+   Preprocessor definitions and constants
+   ------------------------------------------------------------------------*/
+/* Maximum Number of WEP KEYS */
+#define MAX_WEP_KEYS 4
+
+#define SCH_PROTECTION_RESET_TIME 4000
+
+/*--------------------------------------------------------------------------
+   Type declarations
+   ------------------------------------------------------------------------*/
+typedef struct {
+	tSirMacBeaconInterval beaconInterval;
+	uint8_t fShortPreamble;
+	uint8_t llaCoexist;
+	uint8_t llbCoexist;
+	uint8_t llgCoexist;
+	uint8_t ht20Coexist;
+	uint8_t llnNonGFCoexist;
+	uint8_t fRIFSMode;
+	uint8_t fLsigTXOPProtectionFullSupport;
+	uint8_t gHTObssMode;
+} tBeaconParams, *tpBeaconParams;
+
+typedef struct join_params {
+	uint16_t prot_status_code;
+	uint16_t pe_session_id;
+	tSirResultCodes result_code;
+} join_params;
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+#define MAX_BSS_COLOR_VALUE 63
+#define TIME_BEACON_NOT_UPDATED 30000
+#define BSS_COLOR_SWITCH_COUNTDOWN 5
+#define OBSS_COLOR_COLLISION_DETECTION_STA_PERIOD_MS 10000
+#define OBSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS 5000
+#define OBSS_COLOR_COLLISION_SCAN_PERIOD_MS 200
+#define OBSS_COLOR_COLLISION_FREE_SLOT_EXPIRY_MS 50000
+struct bss_color_info {
+	qdf_time_t timestamp;
+	uint64_t seen_count;
+};
+#endif
+
+/**
+ * struct obss_detection_cfg - current obss detection cfg set to firmware
+ * @obss_11b_ap_detect_mode: detection mode for 11b access point.
+ * @obss_11b_sta_detect_mode: detection mode for 11b station.
+ * @obss_11g_ap_detect_mode: detection mode for 11g access point.
+ * @obss_11a_detect_mode: detection mode for 11a access point.
+ * @obss_ht_legacy_detect_mode: detection mode for ht ap with legacy mode.
+ * @obss_ht_mixed_detect_mode: detection mode for ht ap with mixed mode.
+ * @obss_ht_20mhz_detect_mode: detection mode for ht ap with 20mhz mode.
+ */
+struct obss_detection_cfg {
+	uint8_t obss_11b_ap_detect_mode;
+	uint8_t obss_11b_sta_detect_mode;
+	uint8_t obss_11g_ap_detect_mode;
+	uint8_t obss_11a_detect_mode;
+	uint8_t obss_ht_legacy_detect_mode;
+	uint8_t obss_ht_mixed_detect_mode;
+	uint8_t obss_ht_20mhz_detect_mode;
+};
+
+typedef struct sPESession       /* Added to Support BT-AMP */
+{
+	/* To check session table is in use or free */
+	uint8_t available;
+	uint16_t peSessionId;
+	uint8_t smeSessionId;
+	struct wlan_objmgr_vdev *vdev;
+	uint16_t transactionId;
+
+	/* In AP role: BSSID and selfMacAddr will be the same. */
+	/* In STA role: they will be different */
+	tSirMacAddr bssId;
+	tSirMacAddr selfMacAddr;
+	tSirMacSSid ssId;
+	uint8_t bssIdx;
+	uint8_t valid;
+	tLimMlmStates limMlmState;      /* MLM State */
+	tLimMlmStates limPrevMlmState;  /* Previous MLM State */
+	tLimSmeStates limSmeState;      /* SME State */
+	tLimSmeStates limPrevSmeState;  /* Previous SME State */
+	tLimSystemRole limSystemRole;
+	tSirBssType bssType;
+	uint8_t operMode;       /* AP - 0; STA - 1 ; */
+	tSirNwType nwType;
+	tpSirSmeStartBssReq pLimStartBssReq;    /* handle to smestart bss req */
+	tpSirSmeJoinReq pLimJoinReq;    /* handle to sme join req */
+	tpSirSmeJoinReq pLimReAssocReq; /* handle to sme reassoc req */
+	tpLimMlmJoinReq pLimMlmJoinReq; /* handle to MLM join Req */
+	void *pLimMlmReassocRetryReq;   /* keep reasoc req for retry */
+	void *pLimMlmReassocReq;        /* handle to MLM reassoc Req */
+	uint16_t channelChangeReasonCode;
+	uint8_t dot11mode;
+	uint8_t htCapability;
+	/* Supported Channel Width Set: 0-20MHz 1 - 40MHz */
+	uint8_t htSupportedChannelWidthSet;
+	/* Recommended Tx Width Set
+	 * 0 - use 20 MHz channel (control channel)
+	 * 1 - use channel width enabled under Supported Channel Width Set
+	 */
+	uint8_t htRecommendedTxWidthSet;
+	/* Identifies the 40 MHz extension channel */
+	ePhyChanBondState htSecondaryChannelOffset;
+	enum band_info limRFBand;
+	uint8_t limIbssActive;  /* TO SUPPORT CONCURRENCY */
+
+	/* These global varibales moved to session Table to support BT-AMP : Oct 9th review */
+	tAniAuthType limCurrentAuthType;
+	uint16_t limCurrentBssCaps;
+	uint8_t limCurrentBssQosCaps;
+	uint16_t limCurrentBssPropCap;
+	uint8_t limSentCapsChangeNtf;
+	uint16_t limAID;
+
+	/* Parameters  For Reassociation */
+	tSirMacAddr limReAssocbssId;
+	tSirMacChanNum limReassocChannelId;
+	/* CB paramaters required/duplicated for Reassoc since re-assoc mantains its own params in lim */
+	uint8_t reAssocHtSupportedChannelWidthSet;
+	uint8_t reAssocHtRecommendedTxWidthSet;
+	ePhyChanBondState reAssocHtSecondaryChannelOffset;
+	tSirMacSSid limReassocSSID;
+	uint16_t limReassocBssCaps;
+	uint8_t limReassocBssQosCaps;
+	uint16_t limReassocBssPropCap;
+
+	/* Assoc or ReAssoc Response Data/Frame */
+	void *limAssocResponseData;
+
+	/** BSS Table parameters **/
+
+	/*
+	 * staId:  Start BSS: this is the  Sta Id for the BSS.
+	 * Join: this is the selfStaId
+	 * In both cases above, the peer STA ID wll be stored in dph hash table.
+	 */
+	uint16_t staId;
+	uint16_t statypeForBss; /* to know session is for PEER or SELF */
+	uint8_t shortSlotTimeSupported;
+	uint8_t dtimPeriod;
+	tSirMacRateSet rateSet;
+	tSirMacRateSet extRateSet;
+	tSirMacHTOperatingMode htOperMode;
+	uint8_t currentOperChannel;
+	uint8_t currentReqChannel;
+	uint8_t LimRxedBeaconCntDuringHB;
+
+	/* Time stamp of the last beacon received from the BSS to which STA is connected. */
+	uint64_t lastBeaconTimeStamp;
+	/* RX Beacon count for the current BSS to which STA is connected. */
+	uint32_t currentBssBeaconCnt;
+	uint8_t bcon_dtim_period;
+
+	uint32_t bcnLen;
+	uint8_t *beacon;        /* Used to store last beacon / probe response before assoc. */
+
+	uint32_t assocReqLen;
+	uint8_t *assocReq;      /* Used to store association request frame sent out while associating. */
+
+	uint32_t assocRspLen;
+	uint8_t *assocRsp;      /* Used to store association response received while associating */
+	tAniSirDph dph;
+	void **parsedAssocReq;  /* Used to store parsed assoc req from various requesting station */
+	uint32_t RICDataLen;    /* Used to store the Ric data received in the assoc response */
+	uint8_t *ricData;
+#ifdef FEATURE_WLAN_ESE
+	uint32_t tspecLen;      /* Used to store the TSPEC IEs received in the assoc response */
+	uint8_t *tspecIes;
+#endif
+	uint32_t encryptType;
+
+	bool bTkipCntrMeasActive;       /* Used to keep record of TKIP counter measures start/stop */
+
+	uint8_t gLimProtectionControl;  /* used for 11n protection */
+
+	uint8_t gHTNonGFDevicesPresent;
+
+	/* protection related config cache */
+	tCfgProtection cfgProtection;
+
+	/* Number of legacy STAs associated */
+	tLimProtStaParams gLim11bParams;
+
+	/* Number of 11A STAs associated */
+	tLimProtStaParams gLim11aParams;
+
+	/* Number of non-ht non-legacy STAs associated */
+	tLimProtStaParams gLim11gParams;
+
+	/* Number of nonGf STA associated */
+	tLimProtStaParams gLimNonGfParams;
+
+	/* Number of HT 20 STAs associated */
+	tLimProtStaParams gLimHt20Params;
+
+	/* Number of Lsig Txop not supported STAs associated */
+	tLimProtStaParams gLimLsigTxopParams;
+
+	/* Number of STAs that do not support short preamble */
+	tLimNoShortParams gLimNoShortParams;
+
+	/* Number of STAs that do not support short slot time */
+	tLimNoShortSlotParams gLimNoShortSlotParams;
+
+	/* OLBC parameters */
+	tLimProtStaParams gLimOlbcParams;
+
+	/* OLBC parameters */
+	tLimProtStaParams gLimOverlap11gParams;
+
+	tLimProtStaParams gLimOverlap11aParams;
+	tLimProtStaParams gLimOverlapHt20Params;
+	tLimProtStaParams gLimOverlapNonGfParams;
+
+	/* cache for each overlap */
+	tCacheParams protStaCache[LIM_PROT_STA_CACHE_SIZE];
+
+	uint8_t privacy;
+	tAniAuthType authType;
+	tSirKeyMaterial WEPKeyMaterial[MAX_WEP_KEYS];
+
+	tDot11fIERSN gStartBssRSNIe;
+	tDot11fIEWPA gStartBssWPAIe;
+	tSirAPWPSIEs APWPSIEs;
+	uint8_t apUapsdEnable;
+	tSirWPSPBCSession *pAPWPSPBCSession;
+	uint32_t DefProbeRspIeBitmap[8];
+	uint32_t proxyProbeRspEn;
+	tDot11fProbeResponse probeRespFrame;
+	uint8_t ssidHidden;
+	bool fwdWPSPBCProbeReq;
+	uint8_t wps_state;
+	bool wps_registration;
+
+	uint8_t limQosEnabled:1;        /* 11E */
+	uint8_t limWmeEnabled:1;        /* WME */
+	uint8_t limWsmEnabled:1;        /* WSM */
+	uint8_t limHcfEnabled:1;
+	uint8_t lim11dEnabled:1;
+#ifdef WLAN_FEATURE_11W
+	uint8_t limRmfEnabled:1;        /* 11W */
+#endif
+	uint32_t lim11hEnable;
+
+	int8_t maxTxPower;   /* MIN (Regulatory and local power constraint) */
+	enum QDF_OPMODE pePersona;
+	int8_t txMgmtPower;
+	bool is11Rconnection;
+
+#ifdef FEATURE_WLAN_ESE
+	bool isESEconnection;
+	tEsePEContext eseContext;
+#endif
+	bool isFastTransitionEnabled;
+	bool isFastRoamIniFeatureEnabled;
+	tSirNoAParam p2pNoA;
+	tSirP2PNoaAttr p2pGoPsUpdate;
+	uint32_t defaultAuthFailureTimeout;
+	tSirP2PNoaStart p2pGoPsNoaStartInd;
+
+	/* EDCA QoS parameters
+	 * gLimEdcaParams - These EDCA parameters are used locally on AP or STA.
+	 * If STA, then these are values taken from the Assoc Rsp when associating,
+	 * or Beacons/Probe Response after association.  If AP, then these are
+	 * values originally set locally on AP.
+	 *
+	 * gLimEdcaParamsBC - These EDCA parameters are use by AP to broadcast
+	 * to other STATIONs in the BSS.
+	 *
+	 * gLimEdcaParamsActive: These EDCA parameters are what's actively being
+	 * used on station. Specific AC values may be downgraded depending on
+	 * admission control for that particular AC.
+	 */
+	tSirMacEdcaParamRecord gLimEdcaParams[MAX_NUM_AC];      /* used locally */
+	tSirMacEdcaParamRecord gLimEdcaParamsBC[MAX_NUM_AC];    /* used for broadcast */
+	tSirMacEdcaParamRecord gLimEdcaParamsActive[MAX_NUM_AC];
+
+	uint8_t gLimEdcaParamSetCount;
+
+	tBeaconParams beaconParams;
+	uint8_t vhtCapability;
+	tLimOperatingModeInfo gLimOperatingMode;
+	uint8_t vhtCapabilityPresentInBeacon;
+	uint8_t ch_center_freq_seg0;
+	enum phy_ch_width ch_width;
+	uint8_t ch_center_freq_seg1;
+	uint8_t enableVhtpAid;
+	uint8_t enableVhtGid;
+	tLimWiderBWChannelSwitchInfo gLimWiderBWChannelSwitch;
+	uint8_t enableAmpduPs;
+	uint8_t enableHtSmps;
+	uint8_t htSmpsvalue;
+	bool send_smps_action;
+	uint8_t spectrumMgtEnabled;
+	/* *********************11H related**************************** */
+	tLimSpecMgmtInfo gLimSpecMgmt;
+	/* CB Primary/Secondary Channel Switch Info */
+	tLimChannelSwitchInfo gLimChannelSwitch;
+	/* *********************End 11H related**************************** */
+
+	/*Flag to Track Status/Indicate HBFailure on this session */
+	bool LimHBFailureStatus;
+	uint32_t gLimPhyMode;
+	uint8_t amsduSupportedInBA;
+	uint8_t txLdpcIniFeatureEnabled;
+	/**
+	 * Following is the place holder for free peer index pool.
+	 * A non-zero value indicates that peer index is available
+	 * for assignment.
+	 */
+	uint8_t *gpLimPeerIdxpool;
+	uint8_t freePeerIdxHead;
+	uint8_t freePeerIdxTail;
+	uint16_t gLimNumOfCurrentSTAs;
+#ifdef FEATURE_WLAN_TDLS
+	 /* TDLS parameters to check whether TDLS
+	  * and TDLS channel switch is allowed in the
+	  * AP network
+	  */
+	uint32_t peerAIDBitmap[2];
+	bool tdls_prohibited;
+	bool tdls_chan_swit_prohibited;
+#endif
+	bool fWaitForProbeRsp;
+	bool fIgnoreCapsChange;
+	bool fDeauthReceived;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+	int8_t rssi;
+#endif
+	uint8_t max_amsdu_num;
+	uint8_t isCoalesingInIBSSAllowed;
+
+	tSirHTConfig htConfig;
+	struct sir_vht_config vht_config;
+	/*
+	 * Place holder for StartBssReq message
+	 * received by SME state machine
+	 */
+	uint8_t gLimCurrentBssUapsd;
+
+	/* Used on STA, this is a static UAPSD mask setting
+	 * derived from SME_JOIN_REQ and SME_REASSOC_REQ. If a
+	 * particular AC bit is set, it means the AC is both
+	 * trigger enabled and delivery enabled.
+	 */
+	uint8_t gUapsdPerAcBitmask;
+
+	/* Used on STA, this is a dynamic UPASD mask setting
+	 * derived from AddTS Rsp and DelTS frame. If a
+	 * particular AC bit is set, it means AC is trigger
+	 * enabled.
+	 */
+	uint8_t gUapsdPerAcTriggerEnableMask;
+
+	/* Used on STA, dynamic UPASD mask setting
+	 * derived from AddTS Rsp and DelTs frame. If
+	 * a particular AC bit is set, it means AC is
+	 * delivery enabled.
+	 */
+	uint8_t gUapsdPerAcDeliveryEnableMask;
+
+	/* Flag to skip CSA IE processing when CSA
+	 * offload is enabled.
+	 */
+	uint8_t csaOffloadEnable;
+
+	/* Used on STA for AC downgrade. This is a dynamic mask
+	 * setting which keep tracks of ACs being admitted.
+	 * If bit is set to 0: That partiular AC is not admitted
+	 * If bit is set to 1: That particular AC is admitted
+	 */
+	uint8_t gAcAdmitMask[SIR_MAC_DIRECTION_DIRECT];
+
+	/* Power Save Off load Parameters */
+	tPowersaveoffloadInfo pmmOffloadInfo;
+	/* SMPS mode */
+	uint8_t smpsMode;
+
+	uint8_t chainMask;
+
+	/* Flag to indicate Chan Sw announcement is required */
+	uint8_t dfsIncludeChanSwIe;
+
+	/* Flag to indicate Chan Wrapper Element is required */
+	uint8_t dfsIncludeChanWrapperIe;
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	uint8_t cc_switch_mode;
+#endif
+
+	bool isCiscoVendorAP;
+
+	tSirAddIeParams addIeParams;
+
+	uint8_t *pSchProbeRspTemplate;
+	/* Beginning portion of the beacon frame to be written to TFP */
+	uint8_t *pSchBeaconFrameBegin;
+	/* Trailing portion of the beacon frame to be written to TFP */
+	uint8_t *pSchBeaconFrameEnd;
+	/* Size of the beginning portion */
+	uint16_t schBeaconOffsetBegin;
+	/* Size of the trailing portion */
+	uint16_t schBeaconOffsetEnd;
+	bool isOSENConnection;
+	/*  DSCP to UP mapping for HS 2.0 */
+	tSirQosMapSet QosMapSet;
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	bool bRoamSynchInProgress;
+#endif
+
+	/* Fast Transition (FT) */
+	tftPEContext ftPEContext;
+	bool isNonRoamReassoc;
+#ifdef WLAN_FEATURE_11W
+	qdf_mc_timer_t pmfComebackTimer;
+	tComebackTimerInfo pmfComebackTimerInfo;
+#endif /* WLAN_FEATURE_11W */
+	uint8_t  is_key_installed;
+	/* timer for resetting protection fileds at regular intervals */
+	qdf_mc_timer_t protection_fields_reset_timer;
+	/* timer to decrement CSA/ECSA count */
+	qdf_mc_timer_t ap_ecsa_timer;
+	tpAniSirGlobal mac_ctx;
+	/*
+	 * variable to store state of various protection struct like
+	 * gLimOlbcParams, gLimOverlap11gParams, gLimOverlapHt20Params etc
+	 */
+	uint16_t old_protection_state;
+	tSirMacAddr prev_ap_bssid;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	/* tells if Q2Q IE, from another MDM device in AP MCC mode was recvd */
+	bool sap_advertise_avoid_ch_ie;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+#ifdef FEATURE_WLAN_ESE
+	uint8_t is_ese_version_ie_present;
+#endif
+	uint8_t sap_dot11mc;
+	bool is_vendor_specific_vhtcaps;
+	uint8_t vendor_specific_vht_ie_sub_type;
+	bool vendor_vht_sap;
+	/* HS 2.0 Indication */
+	tDot11fIEhs20vendor_ie hs20vendor_ie;
+	/* flag to indicate country code in beacon */
+	uint8_t country_info_present;
+	uint8_t nss;
+	bool nss_forced_1x1;
+	bool add_bss_failed;
+	/* To hold OBSS Scan IE Parameters */
+	struct obss_scanparam obss_ht40_scanparam;
+	uint8_t vdev_nss;
+	/* Supported NSS is intersection of self and peer NSS */
+	bool supported_nss_1x1;
+	bool is_ext_caps_present;
+	uint16_t beacon_tx_rate;
+	uint8_t *access_policy_vendor_ie;
+	uint8_t access_policy;
+	bool ignore_assoc_disallowed;
+	bool send_p2p_conf_frame;
+	bool process_ho_fail;
+	/* Number of STAs that do not support ECSA capability */
+	uint8_t lim_non_ecsa_cap_num;
+#ifdef WLAN_FEATURE_11AX
+	bool he_capable;
+	tDot11fIEhe_cap he_config;
+	tDot11fIEhe_op he_op;
+	uint32_t he_sta_obsspd;
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+	tDot11fIEbss_color_change he_bss_color_change;
+	struct bss_color_info bss_color_info[MAX_BSS_COLOR_VALUE];
+	uint8_t bss_color_changing;
+#endif
+#endif
+	bool enable_bcast_probe_rsp;
+	uint8_t ht_client_cnt;
+	bool force_24ghz_in_ht20;
+	bool ch_switch_in_progress;
+	bool he_with_wep_tkip;
+#ifdef WLAN_FEATURE_FILS_SK
+	struct pe_fils_session *fils_info;
+	struct qdf_mac_addr dst_mac;
+	struct qdf_mac_addr src_mac;
+	uint16_t hlp_data_len;
+	uint8_t *hlp_data;
+#endif
+	/* previous auth frame's sequence number */
+	uint16_t prev_auth_seq_num;
+	struct obss_detection_cfg obss_offload_cfg;
+	struct obss_detection_cfg current_obss_detection;
+	bool is_session_obss_offload_enabled;
+	bool is_obss_reset_timer_initialized;
+	bool sae_pmk_cached;
+	bool fw_roaming_started;
+	bool recvd_deauth_while_roaming;
+	bool recvd_disassoc_while_roaming;
+	bool deauth_disassoc_rc;
+	enum wmi_obss_color_collision_evt_type obss_color_collision_dec_evt;
+	bool is_session_obss_color_collision_det_enabled;
+	tSirMacEdcaParamRecord ap_mu_edca_params[MAX_NUM_AC];
+	bool mu_edca_present;
+	int8_t def_max_tx_pwr;
+	bool active_ba_64_session;
+#ifdef WLAN_SUPPORT_TWT
+	uint8_t peer_twt_requestor;
+	uint8_t peer_twt_responder;
+#endif
+	bool enable_session_twt_support;
+	uint32_t cac_duration_ms;
+	uint32_t dfs_regdomain;
+} tPESession, *tpPESession;
+
+struct session_params {
+	uint16_t session_id;
+};
+
+/*-------------------------------------------------------------------------
+   Function declarations and documenation
+   ------------------------------------------------------------------------*/
+
+#ifdef WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY
+/**
+ * pe_allocate_dph_node_array_buffer() - Allocate g_dph_node_array
+ * memory dynamically
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_NOMEM on failure
+ */
+QDF_STATUS pe_allocate_dph_node_array_buffer(void);
+
+/**
+ * pe_free_dph_node_array_buffer() - Free memory allocated dynamically
+ *
+ * Return: None
+ */
+void pe_free_dph_node_array_buffer(void);
+#else /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
+static inline QDF_STATUS pe_allocate_dph_node_array_buffer(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void pe_free_dph_node_array_buffer(void)
+{
+}
+#endif /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
+
+/**
+ * pe_create_session() - Creates a new PE session given the BSSID
+ * @pMac: pointer to global adapter context
+ * @bssid: BSSID of the new session
+ * @sessionId: PE session ID is returned here, if PE session is created.
+ * @numSta: number of stations
+ * @bssType: bss type of new session to do conditional memory allocation.
+ * @sme_session_id: sme session identifier
+ *
+ * This function returns the session context and the session ID if the session
+ * corresponding to the passed BSSID is found in the PE session table.
+ *
+ * Return: ptr to the session context or NULL if session can not be created.
+ */
+tpPESession pe_create_session(tpAniSirGlobal pMac,
+			      uint8_t *bssid,
+			      uint8_t *sessionId,
+			      uint16_t numSta, tSirBssType bssType,
+			      uint8_t sme_session_id);
+
+/**
+ * pe_find_session_by_bssid() - looks up the PE session given the BSSID.
+ *
+ * @pMac:          pointer to global adapter context
+ * @bssid:         BSSID of the new session
+ * @sessionId:     session ID is returned here, if session is created.
+ *
+ * This function returns the session context and the session ID if the session
+ * corresponding to the given BSSID is found in the PE session table.
+ *
+ * Return: pointer to the session context or NULL if session is not found.
+ */
+tpPESession pe_find_session_by_bssid(tpAniSirGlobal pMac, uint8_t *bssid,
+				     uint8_t *sessionId);
+
+/**
+ * pe_find_session_by_bss_idx() - looks up the PE session given the bssIdx.
+ *
+ * @pMac:          pointer to global adapter context
+ * @bssIdx:        bss index of the session
+ *
+ * This function returns the session context  if the session
+ * corresponding to the given bssIdx is found in the PE session table.
+ *
+ * Return: pointer to the session context or NULL if session is not found.
+ */
+tpPESession pe_find_session_by_bss_idx(tpAniSirGlobal pMac, uint8_t bssIdx);
+
+/**
+ * pe_find_session_by_peer_sta() - looks up the PE session given the Peer
+ * Station Address.
+ *
+ * @pMac:          pointer to global adapter context
+ * @sa:            Peer STA Address of the session
+ * @sessionId:     session ID is returned here, if session is found.
+ *
+ * This function returns the session context and the session ID if the session
+ * corresponding to the given destination address is found in the PE session
+ * table.
+ *
+ * Return: pointer to the session context or NULL if session is not found.
+ */
+tpPESession pe_find_session_by_peer_sta(tpAniSirGlobal pMac, uint8_t *sa,
+					uint8_t *sessionId);
+
+/**
+ * pe_find_session_by_session_id() - looks up the PE session given the session
+ * ID.
+ *
+ * @pMac:          pointer to global adapter context
+ * @sessionId:     session ID for which session context needs to be looked up.
+ *
+ * This function returns the session context  if the session corresponding to
+ * the given session ID is found in the PE session table.
+ *
+ * Return: pointer to the session context or NULL if session is not found.
+ */
+tpPESession pe_find_session_by_session_id(tpAniSirGlobal pMac,
+					  uint8_t sessionId);
+
+/**
+ * pe_find_session_by_bssid() - looks up the PE session given staid.
+ *
+ * @pMac:          pointer to global adapter context
+ * @staid:         StaId of the session
+ * @sessionId:     session ID is returned here, if session is found.
+ *
+ * This function returns the session context and the session ID if the session
+ * corresponding to the given StaId is found in the PE session table.
+ *
+ * Return: pointer to the session context or NULL if session is not found.
+ */
+tpPESession pe_find_session_by_sta_id(tpAniSirGlobal pMac, uint8_t staid,
+				      uint8_t *sessionId);
+
+/**
+ * pe_delete_session() - deletes the PE session given the session ID.
+ *
+ * @pMac:          pointer to global adapter context
+ * @sessionId:     session ID to delete.
+ *
+ * Return: void
+ */
+void pe_delete_session(tpAniSirGlobal pMac, tpPESession psessionEntry);
+
+
+/**
+ * pe_find_session_by_sme_session_id() - looks up the PE session for given sme
+ * session id
+ * @mac_ctx:          pointer to global adapter context
+ * @sme_session_id:   sme session id
+ *
+ * looks up the PE session for given sme session id
+ *
+ * Return: pe session entry for given sme session if found else NULL
+ */
+tpPESession pe_find_session_by_sme_session_id(tpAniSirGlobal mac_ctx,
+					      uint8_t sme_session_id);
+
+/**
+ * pe_find_session_by_scan_id() - looks up the PE session for given scan id
+ * @mac_ctx:   pointer to global adapter context
+ * @scan_id:   scan id
+ *
+ * looks up the PE session for given scan id
+ *
+ * Return: pe session entry for given scan id if found else NULL
+ */
+tpPESession pe_find_session_by_scan_id(tpAniSirGlobal mac_ctx,
+				       uint32_t scan_id);
+
+uint8_t pe_get_active_session_count(tpAniSirGlobal mac_ctx);
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * pe_delete_fils_info: API to delete fils session info
+ * @session: pe session
+ *
+ * Return: void
+ */
+void pe_delete_fils_info(tpPESession session);
+#endif
+
+/**
+ * lim_set_bcn_probe_filter - set the beacon/probe filter in mac context
+ *
+ * @mac_ctx: pointer to global mac context
+ * @session: pointer to the PE session
+ * @ibss_ssid: SSID of the session for IBSS sessions
+ * @sap_channel: Operating Channel of the session for SAP sessions
+ *
+ * Sets the beacon/probe filter in the global mac context to filter
+ * and drop beacon/probe frames before posting it to PE queue
+ *
+ * Return: None
+ */
+void lim_set_bcn_probe_filter(tpAniSirGlobal mac_ctx,
+				tpPESession session,
+				tSirMacSSid *ibss_ssid,
+				uint8_t sap_channel);
+
+/**
+ * lim_reset_bcn_probe_filter - clear the beacon/probe filter in mac context
+ *
+ * @mac_ctx: pointer to the global mac context
+ * @session: pointer to the PE session whose filter is to be cleared
+ *
+ * Return: None
+ */
+void lim_reset_bcn_probe_filter(tpAniSirGlobal mac_ctx, tpPESession session);
+
+/**
+ * lim_update_bcn_probe_filter - Update the beacon/probe filter in mac context
+ *
+ * @mac_ctx: pointer to the global mac context
+ * @session: pointer to the PE session whose filter is to be cleared
+ *
+ * This API is applicable only for SAP sessions to update the SAP channel
+ * in the filter during a channel switch
+ *
+ * Return: None
+ */
+void lim_update_bcn_probe_filter(tpAniSirGlobal mac_ctx, tpPESession session);
+
+#endif /* #if !defined( __LIM_SESSION_H ) */
diff --git a/core/mac/src/pe/include/lim_trace.h b/core/mac/src/pe/include/lim_trace.h
new file mode 100644
index 0000000..e4228b0
--- /dev/null
+++ b/core/mac/src/pe/include/lim_trace.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2013-2016, 2018 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.
+ */
+
+/**=========================================================================
+
+ *  \file  lim_trace.h
+
+ *  \brief definition for trace related APIs
+
+ *  \author Sunit Bhatia
+
+   ========================================================================*/
+
+#ifndef __LIM_TRACE_H
+#define __LIM_TRACE_H
+
+#include "lim_global.h"
+#include "mac_trace.h"
+#include "qdf_trace.h"
+#ifdef LIM_TRACE_RECORD
+
+#define LIM_TRACE_GET_SSN(data)    (((data) >> 16) & 0xff)
+#define LIM_TRACE_GET_SUBTYPE(data)    (data & 0xff)
+#define LIM_TRACE_GET_DEFERRED(data) (data & 0x80000000)
+#define LIM_TRACE_GET_DEFRD_OR_DROPPED(data) (data & 0xc0000000)
+
+#define LIM_MSG_PROCESSED 0
+#define LIM_MSG_DEFERRED   1
+#define LIM_MSG_DROPPED     2
+
+#define LIM_TRACE_MAKE_RXMGMT(type, ssn) \
+	((ssn << 16) | (type))
+#define LIM_TRACE_MAKE_RXMSG(msg, action) \
+	((msg) | (action << 30))
+
+enum {
+	TRACE_CODE_MLM_STATE,
+	TRACE_CODE_SME_STATE,
+	TRACE_CODE_TX_MGMT,
+	TRACE_CODE_RX_MGMT,
+	TRACE_CODE_RX_MGMT_TSF,
+	TRACE_CODE_TX_COMPLETE,
+	TRACE_CODE_TX_SME_MSG,
+	TRACE_CODE_RX_SME_MSG,
+	TRACE_CODE_TX_WMA_MSG,
+	TRACE_CODE_RX_WMA_MSG,
+	TRACE_CODE_TX_LIM_MSG,
+	TRACE_CODE_RX_LIM_MSG,
+	TRACE_CODE_TX_CFG_MSG,
+	TRACE_CODE_RX_CFG_MSG,
+	TRACE_CODE_RX_MGMT_DROP,
+
+	TRACE_CODE_TIMER_ACTIVATE,
+	TRACE_CODE_TIMER_DEACTIVATE,
+	TRACE_CODE_INFO_LOG
+};
+
+void lim_trace_init(tpAniSirGlobal pMac);
+void limTraceReset(tpAniSirGlobal pMac);
+void limTraceUpdateMgmtStat(tpAniSirGlobal pMac, uint8_t subtype);
+void lim_trace_dumpMgmtStat(tpAniSirGlobal pMac, uint8_t subtype);
+uint8_t *lim_trace_get_mlm_state_string(uint32_t mlmState);
+uint8_t *lim_trace_get_sme_state_string(uint32_t smeState);
+void lim_trace_dump(void *pMac, tp_qdf_trace_record pRecord,
+		    uint16_t recIndex);
+void mac_trace_msg_tx(tpAniSirGlobal pMac, uint8_t session, uint32_t data);
+void mac_trace_msg_rx(tpAniSirGlobal pMac, uint8_t session, uint32_t data);
+
+void mac_trace_msg_rx_new(tpAniSirGlobal pMac, uint8_t module, uint8_t session,
+			  uint32_t data);
+void mac_trace_msg_tx_new(tpAniSirGlobal pMac, uint8_t module, uint8_t session,
+			  uint32_t data);
+#endif /* endof LIM_TRACE_RECORD MACRO */
+
+#endif
diff --git a/core/mac/src/pe/include/rrm_api.h b/core/mac/src/pe/include/rrm_api.h
new file mode 100644
index 0000000..d20f4db
--- /dev/null
+++ b/core/mac/src/pe/include/rrm_api.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2018 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.
+ */
+
+/**=========================================================================
+
+   \file  rrm_api.h
+
+   \brief RRM APIs
+
+   ========================================================================*/
+
+/* $Header$ */
+
+#ifndef __RRM_API_H__
+#define __RRM_API_H__
+
+#define RRM_MIN_TX_PWR_CAP    13
+#define RRM_MAX_TX_PWR_CAP    19
+
+#define RRM_BCN_RPT_NO_BSS_INFO    0
+#define RRM_BCN_RPT_MIN_RPT        1
+
+uint8_t rrm_get_min_of_max_tx_power(tpAniSirGlobal pMac, int8_t regMax,
+				    int8_t apTxPower);
+
+QDF_STATUS rrm_initialize(tpAniSirGlobal pMac);
+
+QDF_STATUS rrm_cleanup(tpAniSirGlobal pMac);
+
+QDF_STATUS rrm_process_link_measurement_request(tpAniSirGlobal pMac,
+						uint8_t *pRxPacketInfo,
+						tDot11fLinkMeasurementRequest
+							  *pLinkReq,
+						tpPESession
+							  pSessionEntry);
+
+QDF_STATUS rrm_process_radio_measurement_request(tpAniSirGlobal pMac,
+						 tSirMacAddr peer,
+						 tDot11fRadioMeasurementRequest
+							   *pRRMReq,
+						 tpPESession
+							   pSessionEntry);
+
+QDF_STATUS rrm_process_neighbor_report_response(tpAniSirGlobal pMac,
+						tDot11fNeighborReportResponse
+							  *pNeighborRep,
+						tpPESession
+							  pSessionEntry);
+
+QDF_STATUS rrm_send_set_max_tx_power_req(tpAniSirGlobal pMac,
+					 int8_t txPower,
+					 tpPESession pSessionEntry);
+
+int8_t rrm_get_mgmt_tx_power(tpAniSirGlobal pMac,
+			     tpPESession pSessionEntry);
+
+void rrm_cache_mgmt_tx_power(tpAniSirGlobal pMac,
+			     int8_t txPower, tpPESession pSessionEntry);
+
+tpRRMCaps rrm_get_capabilities(tpAniSirGlobal pMac,
+			       tpPESession pSessionEntry);
+
+void rrm_get_start_tsf(tpAniSirGlobal pMac, uint32_t *pStartTSF);
+
+void rrm_update_start_tsf(tpAniSirGlobal pMac, uint32_t startTSF[2]);
+
+QDF_STATUS rrm_set_max_tx_power_rsp(tpAniSirGlobal pMac,
+				    struct scheduler_msg *limMsgQ);
+
+QDF_STATUS
+rrm_process_neighbor_report_req(tpAniSirGlobal pMac,
+				tpSirNeighborReportReqInd pNeighborReq);
+
+QDF_STATUS
+rrm_process_beacon_report_xmit(tpAniSirGlobal pMac,
+			       tpSirBeaconReportXmitInd pBcnReport);
+
+void lim_update_rrm_capability(tpAniSirGlobal mac_ctx,
+			       tpSirSmeJoinReq join_req);
+#endif
diff --git a/core/mac/src/pe/include/rrm_global.h b/core/mac/src/pe/include/rrm_global.h
new file mode 100644
index 0000000..fe4ac20
--- /dev/null
+++ b/core/mac/src/pe/include/rrm_global.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2018 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.
+ */
+
+#if !defined(__RRMGLOBAL_H)
+#define __RRMGLOBAL_H
+
+/**=========================================================================
+
+   \file  rrm_global.h
+
+   \brief Definitions for SME APIs
+
+   ========================================================================*/
+
+typedef enum eRrmRetStatus {
+	eRRM_SUCCESS,
+	eRRM_INCAPABLE,
+	eRRM_REFUSED,
+	eRRM_FAILURE
+} tRrmRetStatus;
+
+typedef enum eRrmMsgReqSource {
+	eRRM_MSG_SOURCE_LEGACY_ESE = 1, /* legacy ese */
+	eRRM_MSG_SOURCE_11K = 2,        /* 11k */
+	eRRM_MSG_SOURCE_ESE_UPLOAD = 3, /* ese upload approach */
+} tRrmMsgReqSource;
+
+typedef struct sSirChannelInfo {
+	uint8_t regulatoryClass;
+	uint8_t channelNum;
+} tSirChannelInfo, *tpSirChannelInfo;
+
+typedef struct sSirBeaconReportReqInd {
+	uint16_t messageType;   /* eWNI_SME_BEACON_REPORT_REQ_IND */
+	uint16_t length;
+	tSirMacAddr bssId;
+	uint16_t measurementDuration[SIR_ESE_MAX_MEAS_IE_REQS]; /* ms */
+	uint16_t randomizationInterval; /* ms */
+	tSirChannelInfo channelInfo;
+	/* 0: wildcard */
+	tSirMacAddr macaddrBssid;
+	/* 0:Passive, 1: Active, 2: table mode */
+	uint8_t fMeasurementtype[SIR_ESE_MAX_MEAS_IE_REQS];
+	tAniSSID ssId;          /* May be wilcard. */
+	uint16_t uDialogToken;
+	tSirChannelList channelList;    /* From AP channel report. */
+	tRrmMsgReqSource msgSource;
+} tSirBeaconReportReqInd, *tpSirBeaconReportReqInd;
+
+typedef struct sSirBeaconReportXmitInd {
+	uint16_t messageType;   /* eWNI_SME_BEACON_REPORT_RESP_XMIT_IND */
+	uint16_t length;
+	tSirMacAddr bssId;
+	uint16_t uDialogToken;
+	uint8_t fMeasureDone;
+	uint16_t duration;
+	uint8_t regClass;
+	uint8_t numBssDesc;
+	tpSirBssDescription pBssDescription[SIR_BCN_REPORT_MAX_BSS_DESC];
+} tSirBeaconReportXmitInd, *tpSirBeaconReportXmitInd;
+
+typedef struct sSirNeighborReportReqInd {
+	/* eWNI_SME_NEIGHBOR_REPORT_REQ_IND */
+	uint16_t messageType;
+	uint16_t length;
+	/* For the session. */
+	tSirMacAddr bssId;
+	/* true - dont include SSID in the request. */
+	uint16_t noSSID;
+	/* false  include the SSID. It may be null (wildcard) */
+	tSirMacSSid ucSSID;
+} tSirNeighborReportReqInd, *tpSirNeighborReportReqInd;
+
+typedef struct sSirNeighborBssDescription {
+	uint16_t length;
+	tSirMacAddr bssId;
+	uint8_t regClass;
+	uint8_t channel;
+	uint8_t phyType;
+	union sSirNeighborBssidInfo {
+		struct _rrmInfo {
+			 /* see IEEE 802.11k Table 7-43a */
+			uint32_t fApPreauthReachable:2;
+			uint32_t fSameSecurityMode:1;
+			uint32_t fSameAuthenticator:1;
+			/* see IEEE 802.11k Table 7-95d */
+			uint32_t fCapSpectrumMeasurement:1;
+			uint32_t fCapQos:1;
+			uint32_t fCapApsd:1;
+			uint32_t fCapRadioMeasurement:1;
+			uint32_t fCapDelayedBlockAck:1;
+			uint32_t fCapImmediateBlockAck:1;
+			uint32_t fMobilityDomain:1;
+			uint32_t reserved:21;
+		} rrmInfo;
+		struct _eseInfo {
+			uint32_t channelBand:8;
+			uint32_t minRecvSigPower:8;
+			uint32_t apTxPower:8;
+			uint32_t roamHysteresis:8;
+			uint32_t adaptScanThres:8;
+
+			uint32_t transitionTime:8;
+			uint32_t tsfOffset:16;
+
+			uint32_t beaconInterval:16;
+			uint32_t reserved:16;
+		} eseInfo;
+	} bssidInfo;
+
+	/* Optional sub IEs....ignoring for now. */
+} tSirNeighborBssDescription, *tpSirNeighborBssDescripton;
+
+typedef struct sSirNeighborReportInd {
+	uint16_t messageType;   /* eWNI_SME_NEIGHBOR_REPORT_IND */
+	uint16_t length;
+	uint8_t sessionId;
+	uint16_t numNeighborReports;
+	tSirMacAddr bssId;      /* For the session. */
+	tSirNeighborBssDescription sNeighborBssDescription[1];
+} tSirNeighborReportInd, *tpSirNeighborReportInd;
+
+typedef struct sRRMBeaconReportRequestedIes {
+	uint8_t num;
+	uint8_t *pElementIds;
+} tRRMBeaconReportRequestedIes, *tpRRMBeaconReportRequestedIes;
+
+/* Reporting detail defines. */
+/* Reference - IEEE Std 802.11k-2008 section 7.3.2.21.6 Table 7-29h */
+#define BEACON_REPORTING_DETAIL_NO_FF_IE 0
+#define BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE 1
+#define BEACON_REPORTING_DETAIL_ALL_FF_IE 2
+
+typedef struct sRRMReq {
+	uint8_t dialog_token;   /* In action frame; */
+	uint8_t token;          /* Within individual request; */
+	uint8_t type;
+	union {
+		struct {
+			uint8_t reportingDetail;
+			uint8_t last_beacon_report_indication;
+			tRRMBeaconReportRequestedIes reqIes;
+		} Beacon;
+	} request;
+	uint8_t sendEmptyBcnRpt;
+} tRRMReq, *tpRRMReq;
+
+/**
+ * rrm_beacon_report_last_beacon_params - Last Beacon Report Indication params
+ * @last_beacon_ind: flag for whether last beacon indication is required
+ * @report_id: Report ID of the corresponding Beacon Report Request
+ * @frag_id: Current fragment's Fragment ID
+ * @num_frags: Total number of fragments in the Beacon Report
+ */
+struct rrm_beacon_report_last_beacon_params {
+	uint8_t last_beacon_ind;
+	uint8_t report_id;
+	uint8_t frag_id;
+	uint8_t num_frags;
+};
+
+typedef struct sRRMCaps {
+	uint8_t LinkMeasurement:1;
+	uint8_t NeighborRpt:1;
+	uint8_t parallel:1;
+	uint8_t repeated:1;
+	uint8_t BeaconPassive:1;
+	uint8_t BeaconActive:1;
+	uint8_t BeaconTable:1;
+	uint8_t BeaconRepCond:1;
+	uint8_t FrameMeasurement:1;
+	uint8_t ChannelLoad:1;
+	uint8_t NoiseHistogram:1;
+	uint8_t statistics:1;
+	uint8_t LCIMeasurement:1;
+	uint8_t LCIAzimuth:1;
+	uint8_t TCMCapability:1;
+	uint8_t triggeredTCM:1;
+	uint8_t APChanReport:1;
+	uint8_t RRMMIBEnabled:1;
+	uint8_t operatingChanMax:3;
+	uint8_t nonOperatingChanMax:3;
+	uint8_t MeasurementPilot:3;
+	uint8_t MeasurementPilotEnabled:1;
+	uint8_t NeighborTSFOffset:1;
+	uint8_t RCPIMeasurement:1;
+	uint8_t RSNIMeasurement:1;
+	uint8_t BssAvgAccessDelay:1;
+	uint8_t BSSAvailAdmission:1;
+	uint8_t AntennaInformation:1;
+	uint8_t fine_time_meas_rpt:1;
+	uint8_t lci_capability:1;
+	uint8_t reserved:4;
+} tRRMCaps, *tpRRMCaps;
+
+typedef struct sRrmPEContext {
+	uint8_t rrmEnable;
+	/*
+	 * Used during scan/measurement to store the start TSF.
+	 * this is not used directly in beacon reports.
+	 */
+	uint32_t startTSF[2];
+	/*
+	 * This value is stored into bssdescription and beacon report
+	 * gets it from bss decsription.
+	 */
+	tRRMCaps rrmEnabledCaps;
+	int8_t txMgmtPower;
+	/* Dialog token for the request initiated from station. */
+	uint8_t DialogToken;
+	uint16_t prev_rrm_report_seq_num;
+	tpRRMReq pCurrentReq;
+} tRrmPEContext, *tpRrmPEContext;
+
+/* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */
+#define RCPI_LOW_RSSI_VALUE   (-110)
+#define RCPI_MAX_VALUE        (220)
+#define CALCULATE_RCPI(rssi)  (((rssi) + 110) * 2)
+
+/* Bit mask are defined as per Draft P802.11REVmc_D4.2 */
+
+/**
+ * enum mask_rm_capability_byte1 - mask for supported capability
+ * @RM_CAP_LINK_MEASUREMENT: Link Measurement capability
+ * @RM_CAP_NEIGHBOR_REPORT: Neighbor report capability
+ * @RM_CAP_PARALLEL_MEASUREMENT: Parallel Measurement capability
+ * @RM_CAP_REPEATED_MEASUREMENT: Repeated Measurement capability
+ * @RM_CAP_BCN_PASSIVE_MEASUREMENT: Beacon passive measurement capability
+ * @RM_CAP_BCN_ACTIVE_MEASUREMENT: Beacon active measurement capability
+ * @RM_CAP_BCN_TABLE_MEASUREMENT: Beacon table measurement capability
+ * @RM_CAP_BCN_MEAS_REPORTING_COND: Beacon measurement reporting conditions
+ */
+enum mask_rm_capability_byte1 {
+	RM_CAP_LINK_MEASUREMENT = (1 << (0)),
+	RM_CAP_NEIGHBOR_REPORT = (1 << (1)),
+	RM_CAP_PARALLEL_MEASUREMENT = (1 << (2)),
+	RM_CAP_REPEATED_MEASUREMENT = (1 << (3)),
+	RM_CAP_BCN_PASSIVE_MEASUREMENT = (1 << (4)),
+	RM_CAP_BCN_ACTIVE_MEASUREMENT = (1 << (5)),
+	RM_CAP_BCN_TABLE_MEASUREMENT = (1 << (6)),
+	RM_CAP_BCN_MEAS_REPORTING_COND = (1 << (7)),
+};
+
+/**
+ * enum mask_rm_capability_byte2 - mask for supported capability
+ * @RM_CAP_FRAME_MEASUREMENT: Frame Measurement capability
+ * @RM_CAP_CHAN_LOAD_MEASUREMENT: Channel load measurement capability
+ * @RM_CAP_NOISE_HIST_MEASUREMENT: Noise Histogram Measurement capability
+ * @RM_CAP_STATISTICS_MEASUREMENT: Statistics Measurement capability
+ * @RM_CAP_LCI_MEASUREMENT: LCI measurement capability
+ * @RM_CAP_LCI_AZIMUTH: LCI Azimuth capability
+ * @RM_CAP_TX_CATEGORY_MEASUREMENT: Transmit category measurement capability
+ * @RM_CAP_TRIG_TX_CATEGORY_MEASUREMENT:
+ *		    Triggered Transmit category measurement capability
+ */
+enum mask_rm_capability_byte2 {
+	RM_CAP_FRAME_MEASUREMENT = (1 << (0)),
+	RM_CAP_CHAN_LOAD_MEASUREMENT = (1 << (1)),
+	RM_CAP_NOISE_HIST_MEASUREMENT = (1 << (2)),
+	RM_CAP_STATISTICS_MEASUREMENT = (1 << (3)),
+	RM_CAP_LCI_MEASUREMENT = (1 << (4)),
+	RM_CAP_LCI_AZIMUTH = (1 << (5)),
+	RM_CAP_TX_CATEGORY_MEASUREMENT = (1 << (6)),
+	RM_CAP_TRIG_TX_CATEGORY_MEASUREMENT = (1 << (7)),
+};
+
+/**
+ * enum mask_rm_capability_byte3 - mask for supported capability
+ * @RM_CAP_AP_CHAN_REPORT: AP channel report capability
+ * @RM_CAP_RM_MIB: RM MIB capability
+ * @RM_CAP_OPER_CHAN_MAX_DURATION_1: OPER_CHAN_MAX_DURATION bit1
+ * @RM_CAP_OPER_CHAN_MAX_DURATION_2: OPER_CHAN_MAX_DURATION bit2
+ * @RM_CAP_OPER_CHAN_MAX_DURATION_3: OPER_CHAN_MAX_DURATION bit3
+ * @RM_CAP_NONOPER_CHAN_MAX_DURATION_1: NONOPER_CHAN_MAX bit1
+ * @RM_CAP_NONOPER_CHAN_MAX_DURATION_2: NONOPER_CHAN_MAX bit2
+ * @RM_CAP_NONOPER_CHAN_MAX_DURATION_3: NONOPER_CHAN_MAX bit3
+ * @RM_CAP_OPER_CHAN_MAX_DURATION: Operating Channel Max Measurement Duration
+ * @RM_CAP_NONOPER_CHAN_MAX_DURATION:
+ *		    Nonoperating Channel Max Measurement Duration
+ */
+
+enum mask_rm_capability_byte3 {
+	RM_CAP_AP_CHAN_REPORT = (1 << (0)),
+	RM_CAP_RM_MIB = (1 << (1)),
+	RM_CAP_OPER_CHAN_MAX_DURATION_1 = (1 << (2)),
+	RM_CAP_OPER_CHAN_MAX_DURATION_2 = (1 << (3)),
+	RM_CAP_OPER_CHAN_MAX_DURATION_3 = (1 << (4)),
+	RM_CAP_NONOPER_CHAN_MAX_DURATION_1 = (1 << (5)),
+	RM_CAP_NONOPER_CHAN_MAX_DURATION_2 = (1 << (6)),
+	RM_CAP_NONOPER_CHAN_MAX_DURATION_3 = (1 << (7)),
+	RM_CAP_OPER_CHAN_MAX_DURATION = (RM_CAP_OPER_CHAN_MAX_DURATION_1 |
+					 RM_CAP_OPER_CHAN_MAX_DURATION_2 |
+					 RM_CAP_OPER_CHAN_MAX_DURATION_3),
+	RM_CAP_NONOPER_CHAN_MAX_DURATION =
+				(RM_CAP_NONOPER_CHAN_MAX_DURATION_1 |
+				 RM_CAP_NONOPER_CHAN_MAX_DURATION_2 |
+				 RM_CAP_NONOPER_CHAN_MAX_DURATION_3),
+};
+
+/**
+ * enum mask_rm_capability_byte4 - mask for supported capability
+ * @RM_CAP_MEASUREMENT_PILOT_1: MEASUREMENT_PILOT bit1
+ * @RM_CAP_MEASUREMENT_PILOT_2: MEASUREMENT_PILOT bit2
+ * @RM_CAP_MEASUREMENT_PILOT_3: MEASUREMENT_PILOT bit3
+ * @RM_CAP_MEAS_PILOT_TX_INFO: Measurement Pilot Transmission Capability
+ * @RM_CAP_NEIGHBOR_RPT_TSF_OFFSET: Neighbor Report TSF Offset Capability
+ * @RM_CAP_RCPI_MEASUREMENT: RCPI Measurement Capability
+ * @RM_CAP_RSNI_MEASUREMENT: RSNI Measurement Capability
+ * @RM_CAP_BSS_AVG_ACCESS_DELAY: BSS Average Access Delay Capability
+ * @RM_CAP_MEASUREMENT_PILOT: Measurement pilot capability
+ */
+
+enum mask_rm_capability_byte4 {
+	RM_CAP_MEASUREMENT_PILOT_1 = (1 << (0)),
+	RM_CAP_MEASUREMENT_PILOT_2 = (1 << (1)),
+	RM_CAP_MEASUREMENT_PILOT_3 = (1 << (2)),
+	RM_CAP_MEAS_PILOT_TX_INFO = (1 << (3)),
+	RM_CAP_NEIGHBOR_RPT_TSF_OFFSET = (1 << (4)),
+	RM_CAP_RCPI_MEASUREMENT1 = (1 << (5)),
+	RM_CAP_RSNI_MEASUREMENT = (1 << (6)),
+	RM_CAP_BSS_AVG_ACCESS_DELAY = (1 << (7)),
+	RM_CAP_MEASUREMENT_PILOT = (RM_CAP_MEASUREMENT_PILOT_1 |
+				    RM_CAP_MEASUREMENT_PILOT_2 |
+				    RM_CAP_MEASUREMENT_PILOT_3),
+};
+
+/**
+ * enum mask_rm_capability_byte5 - mask for supported capability
+ * @RM_CAP_BSS_AVAIL_ADMISSION: BSS Available Admission Capacity Capability
+ * @RM_CAP_ANTENNA: Antenna Capability
+ * @RM_CAP_FTM_RANGE_REPORT: FTM Range Report Capability
+ * @RM_CAP_CIVIC_LOC_MEASUREMENT: Civic Location Measurement capability
+ *
+ * 4 bits are reserved
+ */
+enum mask_rm_capability_byte5 {
+	RM_CAP_BSS_AVAIL_ADMISSION  = (1 << (0)),
+	RM_CAP_ANTENNA = (1 << (1)),
+	RM_CAP_FTM_RANGE_REPORT = (1 << (2)),
+	RM_CAP_CIVIC_LOC_MEASUREMENT = (1 << (3)),
+};
+
+#endif /* #if defined __RRMGLOBAL_H */
diff --git a/core/mac/src/pe/include/sch_api.h b/core/mac/src/pe/include/sch_api.h
new file mode 100644
index 0000000..9744040
--- /dev/null
+++ b/core/mac/src/pe/include/sch_api.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2011-2015, 2017-2018 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.
+ */
+
+/*
+ *
+ * Author:      Sandesh Goel
+ * Date:        02/25/02
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __SCH_API_H__
+#define __SCH_API_H__
+
+#include "sir_common.h"
+#include "sir_mac_prot_def.h"
+
+#include "ani_global.h"
+
+/* update only the broadcast qos params */
+void sch_qos_update_broadcast(tpAniSirGlobal pMac,
+			      tpPESession psessionEntry);
+
+/* fill in the default local edca parameter into gLimEdcaParams[] */
+void sch_set_default_edca_params(tpAniSirGlobal pMac, tpPESession psessionE);
+
+/* update only local qos params */
+void sch_qos_update_local(tpAniSirGlobal pMac, tpPESession psessionEntry);
+
+/* update the edca profile parameters */
+void sch_edca_profile_update(tpAniSirGlobal pMac,
+			     tpPESession psessionEntry);
+
+/* / Set the fixed fields in a beacon frame */
+QDF_STATUS sch_set_fixed_beacon_fields(tpAniSirGlobal pMac,
+				       tpPESession psessionEntry);
+
+/* / Process the scheduler messages */
+void sch_process_message(tpAniSirGlobal pMac,
+			 struct scheduler_msg *pSchMsg);
+
+/**
+ * sch_process_pre_beacon_ind() - Process the PreBeacon Indication from the Lim
+ * @pMac: pointer to mac structure
+ * @msg: schedular msg
+ * @reason: beaon update reason
+ *
+ * return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS sch_process_pre_beacon_ind(tpAniSirGlobal pMac,
+				      struct scheduler_msg *msg,
+				      enum sir_bcn_update_reason reason);
+
+/* / Post a message to the scheduler message queue */
+QDF_STATUS sch_post_message(tpAniSirGlobal pMac,
+			    struct scheduler_msg *pMsg);
+
+void sch_beacon_process(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+			tpPESession psessionEntry);
+
+QDF_STATUS sch_beacon_edca_process(tpAniSirGlobal pMac,
+				   tSirMacEdcaParamSetIE *edca,
+				   tpPESession psessionEntry);
+
+void sch_generate_tim(tpAniSirGlobal, uint8_t **, uint16_t *, uint8_t);
+
+void sch_set_beacon_interval(tpAniSirGlobal pMac, tpPESession psessionEntry);
+
+/**
+ * sch_send_beacon_req() - send beacon update req to wma
+ * @mac_ctx: pointer to mac structure
+ * @bcn_payload: beacon payload
+ * @size: beacon size
+ * @session:pe session
+ * @reason: beaon update reason
+ *
+ * return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS sch_send_beacon_req(tpAniSirGlobal mac_ctx, uint8_t *bcn_payload,
+			       uint16_t size, tpPESession session,
+			       enum sir_bcn_update_reason reason);
+
+
+QDF_STATUS lim_update_probe_rsp_template_ie_bitmap_beacon1(tpAniSirGlobal,
+							   tDot11fBeacon1 *,
+							   tpPESession
+							   psessionEntry);
+void lim_update_probe_rsp_template_ie_bitmap_beacon2(tpAniSirGlobal,
+						     tDot11fBeacon2 *,
+						     uint32_t *,
+						     tDot11fProbeResponse *);
+void set_probe_rsp_ie_bitmap(uint32_t *, uint32_t);
+uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal,
+					    tpPESession,
+					    uint32_t *);
+
+int sch_gen_timing_advert_frame(tpAniSirGlobal pMac, tSirMacAddr self_addr,
+				uint8_t **buf, uint32_t *timestamp_offset,
+				uint32_t *time_value_offset);
+
+/*
+ * sch_beacon_process_for_ap() - process the beacon frame for AP sessions
+ * @mac_ctx: pointer to the global mac_ctx
+ * @rx_pkt_info: pointer to the frame Rx Meta
+ * @bcn: pointer to the beacon struct
+ *
+ * Process the beacon in the context of any existing AP or BTAP
+ * session. This takes cares of following two scenarios:
+ *  - session = NULL:
+ * e.g. beacon received from a neighboring BSS, you want to apply the
+ * protection settings to BTAP/InfraAP beacons
+ *  - session is non NULL:
+ * e.g. beacon received is from the INFRA AP to which you are connected
+ * on another concurrent link. In this case also, we want to apply the
+ * protection settings(as advertised by Infra AP) to BTAP beacons
+ *
+ * Return: None
+ */
+void sch_beacon_process_for_ap(tpAniSirGlobal mac_ctx,
+			       uint8_t session_id,
+			       uint8_t *rx_pkt_info,
+			       tSchBeaconStruct *bcn);
+
+#endif
diff --git a/core/mac/src/pe/include/sch_global.h b/core/mac/src/pe/include/sch_global.h
new file mode 100644
index 0000000..03e9cf2
--- /dev/null
+++ b/core/mac/src/pe/include/sch_global.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013-2014, 2017-2018 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.
+ */
+
+/*
+ *
+ *
+ * Author:      Sandesh Goel
+ * Date:        02/25/02
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __SCH_GLOBAL_H__
+#define __SCH_GLOBAL_H__
+
+#include "sir_mac_prop_exts.h"
+#include "lim_global.h"
+
+#include "parser_api.h"
+
+#define TIM_IE_SIZE 0xB
+
+/* ----------------------- Beacon processing ------------------------ */
+
+/* / Beacon structure */
+#define tSchBeaconStruct tSirProbeRespBeacon
+#define tpSchBeaconStruct struct sSirProbeRespBeacon *
+
+/* ------------------------------------------------------------------- */
+
+/* ****************** MISC defs ********************************* */
+
+struct schMisc {
+	uint16_t gSchBeaconInterval;
+
+	/* --------- STA ONLY state ----------- */
+
+	/* / flag to indicate that beacon template has been updated */
+	uint8_t fBeaconChanged;
+
+	uint16_t p2pIeOffset;
+
+	/* CSA and ECSA Switch Count Offsets to be sent to FW */
+	uint32_t csa_count_offset;
+	uint32_t ecsa_count_offset;
+};
+
+/* ****************** MISC defs ********************************* */
+
+/* / Global SCH structure */
+typedef struct sAniSirSch {
+	/* / The scheduler object */
+	struct schMisc schObject;
+} tAniSirSch, *tpAniSirSch;
+
+#endif
diff --git a/core/mac/src/pe/include/wmm_apsd.h b/core/mac/src/pe/include/wmm_apsd.h
new file mode 100644
index 0000000..86f6017
--- /dev/null
+++ b/core/mac/src/pe/include/wmm_apsd.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013-2014 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.
+ */
+
+#ifndef __WMMAPSD_H__
+#define __WMMAPSD_H__
+
+#include "ani_global.h"
+
+/* UAPSD Flag for each AC (WMM spec 2.2.1) */
+#define LIM_UAPSD_BITOFFSET_ACVO     0
+#define LIM_UAPSD_BITOFFSET_ACVI     1
+#define LIM_UAPSD_BITOFFSET_ACBK     2
+#define LIM_UAPSD_BITOFFSET_ACBE     3
+
+#define LIM_UAPSD_FLAG_ACVO     (1 << LIM_UAPSD_BITOFFSET_ACVO)
+#define LIM_UAPSD_FLAG_ACVI     (1 << LIM_UAPSD_BITOFFSET_ACVI)
+#define LIM_UAPSD_FLAG_ACBK     (1 << LIM_UAPSD_BITOFFSET_ACBK)
+#define LIM_UAPSD_FLAG_ACBE     (1 << LIM_UAPSD_BITOFFSET_ACBE)
+
+#define LIM_UAPSD_GET(ac, mask)      (((mask) & (LIM_UAPSD_FLAG_ ## ac)) >> LIM_UAPSD_BITOFFSET_ ## ac)
+
+/* Definition for setting/clearing Uapsd Mask */
+#define SET_UAPSD_MASK    1
+#define CLEAR_UAPSD_MASK  0
+
+#endif /* __WMMAPSD_H__ */
diff --git a/core/mac/src/pe/lim/lim_admit_control.c b/core/mac/src/pe/lim/lim_admit_control.c
new file mode 100644
index 0000000..e5d0fc9
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_admit_control.c
@@ -0,0 +1,1047 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * This file contains TSPEC and STA admit control related functions
+ * NOTE: applies only to AP builds
+ *
+ * Author:      Sandesh Goel
+ * Date:        02/25/02
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "sys_def.h"
+#include "lim_api.h"
+#include "cfg_api.h"             /* wlan_cfg_get_int() */
+#include "lim_trace.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "lim_types.h"
+#include "lim_admit_control.h"
+
+#define ADMIT_CONTROL_LOGLEVEL        LOGD
+#define ADMIT_CONTROL_POLICY_LOGLEVEL LOGD
+
+/* total available bandwidth in bps in each phy mode
+ * these should be defined in hal or dph - replace these later
+ */
+#define LIM_TOTAL_BW_11A   54000000
+#define LIM_MIN_BW_11A     6000000
+#define LIM_TOTAL_BW_11B   11000000
+#define LIM_MIN_BW_11B     1000000
+#define LIM_TOTAL_BW_11G   LIM_TOTAL_BW_11A
+#define LIM_MIN_BW_11G     LIM_MIN_BW_11B
+
+/* conversion factors */
+#define LIM_CONVERT_SIZE_BITS(numBytes) ((numBytes) * 8)
+#define LIM_CONVERT_RATE_MBPS(rate)     ((rate)/1000000)
+
+/* ------------------------------------------------------------------------------ */
+/* local protos */
+
+static QDF_STATUS
+lim_calculate_svc_int(tpAniSirGlobal, tSirMacTspecIE *, uint32_t *);
+static QDF_STATUS
+lim_validate_tspec_edca(tpAniSirGlobal, tSirMacTspecIE *, tpPESession);
+static QDF_STATUS
+lim_validate_tspec(tpAniSirGlobal, tSirMacTspecIE *, tpPESession);
+static void
+lim_compute_mean_bw_used(tpAniSirGlobal, uint32_t *, uint32_t, tpLimTspecInfo,
+			 tpPESession);
+static void lim_get_available_bw(tpAniSirGlobal, uint32_t *, uint32_t *, uint32_t,
+				 uint32_t);
+static QDF_STATUS lim_admit_policy_oversubscription(tpAniSirGlobal,
+						       tSirMacTspecIE *,
+						       tpLimAdmitPolicyInfo,
+						       tpLimTspecInfo,
+						       tpPESession);
+static QDF_STATUS lim_tspec_find_by_sta_addr(tpAniSirGlobal, uint8_t *,
+						tSirMacTspecIE *, tpLimTspecInfo,
+						tpLimTspecInfo *);
+static QDF_STATUS lim_validate_access_policy(tpAniSirGlobal, uint8_t, uint16_t,
+						tpPESession);
+
+/** -------------------------------------------------------------
+   \fn lim_calculate_svc_int
+   \brief TSPEC validation and servcie interval determination
+   \param     tpAniSirGlobal    pMac
+   \param         tSirMacTspecIE *pTspec
+   \param         uint32_t            *pSvcInt
+   \return QDF_STATUS - status of the comparison
+   -------------------------------------------------------------*/
+
+static QDF_STATUS
+lim_calculate_svc_int(tpAniSirGlobal pMac,
+		      tSirMacTspecIE *pTspec, uint32_t *pSvcInt)
+{
+	uint32_t msduSz, dataRate;
+	*pSvcInt = 0;
+
+	/* if a service interval is already specified, we are done */
+	if ((pTspec->minSvcInterval != 0) || (pTspec->maxSvcInterval != 0)) {
+		*pSvcInt = (pTspec->maxSvcInterval != 0)
+			   ? pTspec->maxSvcInterval : pTspec->minSvcInterval;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* Masking off the fixed bits according to definition of MSDU size
+	 * in IEEE 802.11-2007 spec (section 7.3.2.30). Nominal MSDU size
+	 * is defined as:  Bit[0:14]=Size, Bit[15]=Fixed
+	 */
+	if (pTspec->nomMsduSz != 0)
+		msduSz = (pTspec->nomMsduSz & 0x7fff);
+	else if (pTspec->maxMsduSz != 0)
+		msduSz = pTspec->maxMsduSz;
+	else {
+		pe_err("MsduSize not specified");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* need to calculate a reasonable service interval
+	 * this is simply the msduSz/meanDataRate
+	 */
+	if (pTspec->meanDataRate != 0)
+		dataRate = pTspec->meanDataRate;
+	else if (pTspec->peakDataRate != 0)
+		dataRate = pTspec->peakDataRate;
+	else if (pTspec->minDataRate != 0)
+		dataRate = pTspec->minDataRate;
+	else {
+		pe_err("DataRate not specified");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*pSvcInt =
+		LIM_CONVERT_SIZE_BITS(msduSz) / LIM_CONVERT_RATE_MBPS(dataRate);
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * lim_validate_tspec_edca() - Validate the parameters
+ * @mac_ctx: Global MAC context
+ * @tspec:   Pointer to the TSPEC
+ * @session_entry: Session Entry
+ *
+ * validate the parameters in the edca tspec
+ * mandatory fields are derived from 11e Annex I (Table I.1)
+ *
+ * Return: Status
+ **/
+static QDF_STATUS
+lim_validate_tspec_edca(tpAniSirGlobal mac_ctx,
+			tSirMacTspecIE *tspec, tpPESession session_entry)
+{
+	uint32_t max_phy_rate, min_phy_rate;
+	uint32_t phy_mode;
+	QDF_STATUS retval = QDF_STATUS_SUCCESS;
+
+	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+	lim_get_available_bw(mac_ctx, &max_phy_rate, &min_phy_rate, phy_mode,
+			     1 /* bandwidth mult factor */);
+	/* mandatory fields are derived from 11e Annex I (Table I.1) */
+	if ((tspec->nomMsduSz == 0) ||
+	    (tspec->meanDataRate == 0) ||
+	    (tspec->surplusBw == 0) ||
+	    (tspec->minPhyRate == 0) ||
+	    (tspec->minPhyRate > max_phy_rate)) {
+		pe_warn("Invalid EDCA Tspec: NomMsdu: %d meanDataRate: %d surplusBw: %d min_phy_rate: %d",
+			tspec->nomMsduSz, tspec->meanDataRate,
+			tspec->surplusBw, tspec->minPhyRate);
+		retval = QDF_STATUS_E_FAILURE;
+	}
+
+	pe_debug("return status: %d", retval);
+	return retval;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_validate_tspec
+   \brief validate the offered tspec
+   \param   tpAniSirGlobal pMac
+   \param         tSirMacTspecIE *pTspec
+   \return QDF_STATUS - status
+   -------------------------------------------------------------*/
+
+static QDF_STATUS
+lim_validate_tspec(tpAniSirGlobal pMac,
+		   tSirMacTspecIE *pTspec, tpPESession psessionEntry)
+{
+	QDF_STATUS retval = QDF_STATUS_SUCCESS;
+
+	switch (pTspec->tsinfo.traffic.accessPolicy) {
+	case SIR_MAC_ACCESSPOLICY_EDCA:
+		retval = lim_validate_tspec_edca(pMac, pTspec, psessionEntry);
+		if (retval != QDF_STATUS_SUCCESS)
+			pe_warn("EDCA tspec invalid");
+			break;
+
+	case SIR_MAC_ACCESSPOLICY_HCCA:
+	case SIR_MAC_ACCESSPOLICY_BOTH:
+	/* TBD: should we support hybrid tspec as well?? for now, just fall through */
+	default:
+		pe_warn("AccessType: %d not supported",
+			pTspec->tsinfo.traffic.accessPolicy);
+		retval = QDF_STATUS_E_FAILURE;
+		break;
+	}
+	return retval;
+}
+
+/* ----------------------------------------------------------------------------- */
+/* Admit Control Policy */
+
+/** -------------------------------------------------------------
+   \fn lim_compute_mean_bw_used
+   \brief determime the used/allocated bandwidth
+   \param   tpAniSirGlobal pMac
+   \param       uint32_t              *pBw
+   \param       uint32_t               phyMode
+   \param       tpLimTspecInfo    pTspecInfo
+   \return void
+   -------------------------------------------------------------*/
+
+static void
+lim_compute_mean_bw_used(tpAniSirGlobal pMac,
+			 uint32_t *pBw,
+			 uint32_t phyMode,
+			 tpLimTspecInfo pTspecInfo, tpPESession psessionEntry)
+{
+	uint32_t ctspec;
+	*pBw = 0;
+	for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++) {
+		if (pTspecInfo->inuse) {
+			tpDphHashNode pSta =
+				dph_get_hash_entry(pMac, pTspecInfo->assocId,
+						   &psessionEntry->dph.dphHashTable);
+			if (pSta == NULL) {
+				/* maybe we should delete the tspec?? */
+				pe_err("Tspec: %d assocId: %d dphNode not found",
+					ctspec, pTspecInfo->assocId);
+				continue;
+			}
+			*pBw += pTspecInfo->tspec.meanDataRate;
+		}
+	}
+}
+
+/** -------------------------------------------------------------
+   \fn lim_get_available_bw
+   \brief based on the phy mode and the bw_factor, determine the total bandwidth that
+       can be supported
+   \param   tpAniSirGlobal pMac
+   \param       uint32_t              *pMaxBw
+   \param       uint32_t              *pMinBw
+   \param       uint32_t               phyMode
+   \param       uint32_t               bw_factor
+   \return void
+   -------------------------------------------------------------*/
+
+static void
+lim_get_available_bw(tpAniSirGlobal pMac,
+		     uint32_t *pMaxBw,
+		     uint32_t *pMinBw, uint32_t phyMode, uint32_t bw_factor)
+{
+	switch (phyMode) {
+	case WNI_CFG_PHY_MODE_11B:
+		*pMaxBw = LIM_TOTAL_BW_11B;
+		*pMinBw = LIM_MIN_BW_11B;
+		break;
+
+	case WNI_CFG_PHY_MODE_11A:
+		*pMaxBw = LIM_TOTAL_BW_11A;
+		*pMinBw = LIM_MIN_BW_11A;
+		break;
+
+	case WNI_CFG_PHY_MODE_11G:
+	case WNI_CFG_PHY_MODE_NONE:
+	default:
+		*pMaxBw = LIM_TOTAL_BW_11G;
+		*pMinBw = LIM_MIN_BW_11G;
+		break;
+	}
+	*pMaxBw *= bw_factor;
+}
+
+/**
+ * lim_admit_policy_oversubscription() - Admission control policy
+ * @mac_ctx:        Global MAC Context
+ * @tspec:          Pointer to the tspec
+ * @admit_policy:   Admission policy
+ * @tspec_info:     TSPEC information
+ * @session_entry:  Session Entry
+ *
+ * simple admission control policy based on oversubscription
+ * if the total bandwidth of all admitted tspec's exceeds (factor * phy-bw) then
+ * reject the tspec, else admit it. The phy-bw is the peak available bw in the
+ * current phy mode. The 'factor' is the configured oversubscription factor.
+ *
+ * Return: Status
+ **/
+static QDF_STATUS
+lim_admit_policy_oversubscription(tpAniSirGlobal mac_ctx,
+				  tSirMacTspecIE *tspec,
+				  tpLimAdmitPolicyInfo admit_policy,
+				  tpLimTspecInfo tspec_info,
+				  tpPESession session_entry)
+{
+	uint32_t totalbw, minbw, usedbw;
+	uint32_t phy_mode;
+
+	/* determine total bandwidth used so far */
+	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+	lim_compute_mean_bw_used(mac_ctx, &usedbw, phy_mode,
+			tspec_info, session_entry);
+
+	/* determine how much bw is available based on the current phy mode */
+	lim_get_available_bw(mac_ctx, &totalbw, &minbw, phy_mode,
+			     admit_policy->bw_factor);
+
+	if (usedbw > totalbw)   /* this can't possibly happen */
+		return QDF_STATUS_E_FAILURE;
+
+	if ((totalbw - usedbw) < tspec->meanDataRate) {
+		pe_warn("Total BW: %d Used: %d Tspec request: %d not possible",
+			totalbw, usedbw, tspec->meanDataRate);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_admit_policy
+   \brief determine the current admit control policy and apply it for the offered tspec
+   \param   tpAniSirGlobal pMac
+   \param         tSirMacTspecIE   *pTspec
+   \return QDF_STATUS - status
+   -------------------------------------------------------------*/
+
+static QDF_STATUS lim_admit_policy(tpAniSirGlobal pMac,
+				      tSirMacTspecIE *pTspec,
+				      tpPESession psessionEntry)
+{
+	QDF_STATUS retval = QDF_STATUS_E_FAILURE;
+	tpLimAdmitPolicyInfo pAdmitPolicy = &pMac->lim.admitPolicyInfo;
+
+	switch (pAdmitPolicy->type) {
+	case WNI_CFG_ADMIT_POLICY_ADMIT_ALL:
+		retval = QDF_STATUS_SUCCESS;
+		break;
+
+	case WNI_CFG_ADMIT_POLICY_BW_FACTOR:
+		retval = lim_admit_policy_oversubscription(pMac, pTspec,
+							   &pMac->lim.
+							   admitPolicyInfo,
+							   &pMac->lim.tspecInfo[0],
+							   psessionEntry);
+		if (retval != QDF_STATUS_SUCCESS)
+			pe_err("rejected by BWFactor policy");
+			break;
+
+	case WNI_CFG_ADMIT_POLICY_REJECT_ALL:
+		retval = QDF_STATUS_E_FAILURE;
+		break;
+
+	default:
+		retval = QDF_STATUS_SUCCESS;
+		pe_warn("Admit Policy: %d unknown, admitting all traffic",
+			pAdmitPolicy->type);
+		break;
+	}
+	return retval;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_tspec_delete
+   \brief delete the specified tspec
+   \param   tpAniSirGlobal pMac
+   \param     tpLimTspecInfo pInfo
+   \return void
+   -------------------------------------------------------------*/
+
+/* ----------------------------------------------------------------------------- */
+/* delete the specified tspec */
+static void lim_tspec_delete(tpAniSirGlobal pMac, tpLimTspecInfo pInfo)
+{
+	if (pInfo == NULL)
+		return;
+	/* pierre */
+	pe_debug("tspec entry: %d delete tspec: %pK", pInfo->idx, pInfo);
+	pInfo->inuse = 0;
+
+	return;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_tspec_find_by_sta_addr
+   \brief Send halMsg_AddTs to HAL
+   \param   tpAniSirGlobal pMac
+   \param   \param       uint8_t               *pAddr
+   \param       tSirMacTspecIE    *pTspecIE
+   \param       tpLimTspecInfo    pTspecList
+   \param       tpLimTspecInfo   *ppInfo
+   \return QDF_STATUS - status
+   -------------------------------------------------------------*/
+
+/* find the specified tspec in the list */
+static QDF_STATUS
+lim_tspec_find_by_sta_addr(tpAniSirGlobal pMac,
+			   uint8_t *pAddr,
+			   tSirMacTspecIE *pTspecIE,
+			   tpLimTspecInfo pTspecList, tpLimTspecInfo *ppInfo)
+{
+	int ctspec;
+
+	*ppInfo = NULL;
+
+	for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) {
+		if ((pTspecList->inuse)
+		    &&
+		    (!qdf_mem_cmp
+			     (pAddr, pTspecList->staAddr, sizeof(pTspecList->staAddr)))
+		    &&
+		    (!qdf_mem_cmp
+			     ((uint8_t *) pTspecIE, (uint8_t *) &pTspecList->tspec,
+			     sizeof(tSirMacTspecIE)))) {
+			*ppInfo = pTspecList;
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	return QDF_STATUS_E_FAILURE;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_tspec_find_by_assoc_id
+   \brief find tspec with matchin staid and Tspec
+   \param   tpAniSirGlobal pMac
+   \param       uint32_t               staid
+   \param       tSirMacTspecIE    *pTspecIE
+   \param       tpLimTspecInfo    pTspecList
+   \param       tpLimTspecInfo   *ppInfo
+   \return QDF_STATUS - status
+   -------------------------------------------------------------*/
+
+QDF_STATUS
+lim_tspec_find_by_assoc_id(tpAniSirGlobal pMac,
+			   uint16_t assocId,
+			   tSirMacTspecIE *pTspecIE,
+			   tpLimTspecInfo pTspecList, tpLimTspecInfo *ppInfo)
+{
+	int ctspec;
+
+	*ppInfo = NULL;
+
+	pe_debug("Trying to find tspec entry for assocId: %d pTsInfo->traffic.direction: %d pTsInfo->traffic.tsid: %d",
+		assocId, pTspecIE->tsinfo.traffic.direction,
+		pTspecIE->tsinfo.traffic.tsid);
+
+	for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) {
+		if ((pTspecList->inuse)
+		    && (assocId == pTspecList->assocId)
+		    &&
+		    (!qdf_mem_cmp
+			     ((uint8_t *) pTspecIE, (uint8_t *) &pTspecList->tspec,
+			     sizeof(tSirMacTspecIE)))) {
+			*ppInfo = pTspecList;
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	return QDF_STATUS_E_FAILURE;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_find_tspec
+   \brief finding a TSPEC entry with assocId, tsinfo.direction and tsinfo.tsid
+   \param    uint16_t               assocId
+   \param     tpAniSirGlobal    pMac
+   \param     tSirMacTSInfo   *pTsInfo
+   \param         tpLimTspecInfo    pTspecList
+   \param         tpLimTspecInfo   *ppInfo
+   \return QDF_STATUS - status of the comparison
+   -------------------------------------------------------------*/
+
+static QDF_STATUS
+lim_find_tspec(tpAniSirGlobal pMac,
+	       uint16_t assocId,
+	       tSirMacTSInfo *pTsInfo,
+	       tpLimTspecInfo pTspecList, tpLimTspecInfo *ppInfo)
+{
+	int ctspec;
+
+	*ppInfo = NULL;
+
+	pe_debug("Trying to find tspec entry for assocId: %d pTsInfo->traffic.direction: %d pTsInfo->traffic.tsid: %d",
+		assocId, pTsInfo->traffic.direction, pTsInfo->traffic.tsid);
+
+	for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) {
+		if ((pTspecList->inuse)
+		    && (assocId == pTspecList->assocId)
+		    && (pTsInfo->traffic.direction ==
+			pTspecList->tspec.tsinfo.traffic.direction)
+		    && (pTsInfo->traffic.tsid ==
+			pTspecList->tspec.tsinfo.traffic.tsid)) {
+			*ppInfo = pTspecList;
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	return QDF_STATUS_E_FAILURE;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_tspec_add
+   \brief add or update the specified tspec to the tspec list
+   \param tpAniSirGlobal    pMac
+   \param uint8_t               *pAddr
+   \param uint16_t               assocId
+   \param tSirMacTspecIE   *pTspec
+   \param uint32_t               interval
+   \param tpLimTspecInfo   *ppInfo
+
+   \return QDF_STATUS - status of the comparison
+   -------------------------------------------------------------*/
+
+QDF_STATUS lim_tspec_add(tpAniSirGlobal pMac,
+			    uint8_t *pAddr,
+			    uint16_t assocId,
+			    tSirMacTspecIE *pTspec,
+			    uint32_t interval, tpLimTspecInfo *ppInfo)
+{
+	tpLimTspecInfo pTspecList = &pMac->lim.tspecInfo[0];
+	*ppInfo = NULL;
+
+	/* validate the assocId */
+	if (assocId >= pMac->lim.maxStation) {
+		pe_err("Invalid assocId 0x%x", assocId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* decide whether to add/update */
+	{
+		*ppInfo = NULL;
+
+		if (QDF_STATUS_SUCCESS ==
+		    lim_find_tspec(pMac, assocId, &pTspec->tsinfo, pTspecList,
+				   ppInfo)) {
+			/* update this entry. */
+			pe_debug("updating TSPEC table entry: %d",
+				(*ppInfo)->idx);
+		} else {
+			/* We didn't find one to update. So find a free slot in the
+			 * LIM TSPEC list and add this new entry
+			 */
+			uint8_t ctspec = 0;
+
+			for (ctspec = 0, pTspecList = &pMac->lim.tspecInfo[0];
+			     ctspec < LIM_NUM_TSPEC_MAX;
+			     ctspec++, pTspecList++) {
+				if (!pTspecList->inuse) {
+					pe_debug("Found free slot in TSPEC list. Add to TSPEC table entry: %d",
+						ctspec);
+					break;
+				}
+			}
+
+			if (ctspec >= LIM_NUM_TSPEC_MAX)
+				return QDF_STATUS_E_FAILURE;
+
+			/* Record the new index entry */
+			pTspecList->idx = ctspec;
+		}
+	}
+
+	/* update the tspec info */
+	pTspecList->tspec = *pTspec;
+	pTspecList->assocId = assocId;
+	qdf_mem_copy(pTspecList->staAddr, pAddr, sizeof(pTspecList->staAddr));
+
+	/* for edca tspec's, we are all done */
+	if (pTspec->tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) {
+		pTspecList->inuse = 1;
+		*ppInfo = pTspecList;
+		pe_debug("added entry for EDCA AccessPolicy");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/*
+	 * for hcca tspec's, must set the parameterized bit in the queues
+	 * the 'ts' bit in the queue data structure indicates that the queue is
+	 * parameterized (hcca). When the schedule is written this bit is used
+	 * in the tsid field (bit 3) and the other three bits (0-2) are simply
+	 * filled in as the user priority (or qid). This applies only to uplink
+	 * polls where the qos control field must contain the tsid specified in the
+	 * tspec.
+	 */
+	pTspecList->inuse = 1;
+	*ppInfo = pTspecList;
+	pe_debug("added entry for HCCA AccessPolicy");
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_validate_access_policy
+   \brief Validates Access policy
+   \param   tpAniSirGlobal pMac
+   \param       uint8_t              accessPolicy
+   \param       uint16_t             assocId
+   \return QDF_STATUS - status
+   -------------------------------------------------------------*/
+
+static QDF_STATUS
+lim_validate_access_policy(tpAniSirGlobal pMac,
+			   uint8_t accessPolicy,
+			   uint16_t assocId, tpPESession psessionEntry)
+{
+	QDF_STATUS retval = QDF_STATUS_E_FAILURE;
+	tpDphHashNode pSta =
+		dph_get_hash_entry(pMac, assocId, &psessionEntry->dph.dphHashTable);
+
+	if ((pSta == NULL) || (!pSta->valid)) {
+		pe_err("invalid station address passed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	switch (accessPolicy) {
+	case SIR_MAC_ACCESSPOLICY_EDCA:
+		if (pSta->wmeEnabled || pSta->lleEnabled)
+			retval = QDF_STATUS_SUCCESS;
+		break;
+
+	case SIR_MAC_ACCESSPOLICY_HCCA:
+	case SIR_MAC_ACCESSPOLICY_BOTH:
+	default:
+		pe_err("Invalid accessPolicy: %d",
+			       accessPolicy);
+		break;
+	}
+
+	if (retval != QDF_STATUS_SUCCESS)
+		pe_warn("accPol: %d staId: %d lle: %d wme: %d wsm: %d",
+			accessPolicy, pSta->staIndex, pSta->lleEnabled,
+			pSta->wmeEnabled, pSta->wsmEnabled);
+
+	return retval;
+}
+
+/**
+ * lim_admit_control_add_ts() -        Check if STA can be admitted
+ * @pMac:               Global MAC context
+ * @pAddr:              Address
+ * @pAddts:             ADD TS
+ * @pQos:               QOS fields
+ * @assocId:            Association ID
+ * @alloc:              Allocate bandwidth for this tspec
+ * @pSch:               Schedule IE
+ * @pTspecIdx:          TSPEC index
+ * @psessionEntry:      PE Session Entry
+ *
+ * Determine if STA with the specified TSPEC can be admitted. If it can,
+ * a schedule element is provided
+ *
+ * Return: status
+ **/
+QDF_STATUS lim_admit_control_add_ts(tpAniSirGlobal pMac, uint8_t *pAddr,
+		tSirAddtsReqInfo *pAddts, tSirMacQosCapabilityStaIE *pQos,
+		uint16_t assocId, uint8_t alloc, tSirMacScheduleIE *pSch,
+		uint8_t *pTspecIdx, tpPESession psessionEntry)
+{
+	tpLimTspecInfo pTspecInfo;
+	QDF_STATUS retval;
+	uint32_t svcInterval;
+	(void)pQos;
+
+	/* TBD: modify tspec as needed */
+	/* EDCA: need to fill in the medium time and the minimum phy rate */
+	/* to be consistent with the desired traffic parameters. */
+
+	pe_debug("tsid: %d directn: %d start: %d intvl: %d accPolicy: %d up: %d",
+		pAddts->tspec.tsinfo.traffic.tsid,
+		pAddts->tspec.tsinfo.traffic.direction,
+		pAddts->tspec.svcStartTime, pAddts->tspec.minSvcInterval,
+		pAddts->tspec.tsinfo.traffic.accessPolicy,
+		pAddts->tspec.tsinfo.traffic.userPrio);
+
+	/* check for duplicate tspec */
+	retval = (alloc)
+		 ? lim_tspec_find_by_assoc_id(pMac, assocId, &pAddts->tspec,
+					      &pMac->lim.tspecInfo[0], &pTspecInfo)
+		 : lim_tspec_find_by_sta_addr(pMac, pAddr, &pAddts->tspec,
+					      &pMac->lim.tspecInfo[0], &pTspecInfo);
+
+	if (retval == QDF_STATUS_SUCCESS) {
+		pe_err("duplicate tspec index: %d", pTspecInfo->idx);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* check that the tspec's are well formed and acceptable */
+	if (lim_validate_tspec(pMac, &pAddts->tspec, psessionEntry) !=
+	    QDF_STATUS_SUCCESS) {
+		pe_warn("tspec validation failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* determine a service interval for the tspec */
+	if (lim_calculate_svc_int(pMac, &pAddts->tspec, &svcInterval) !=
+	    QDF_STATUS_SUCCESS) {
+		pe_warn("SvcInt calculate failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* determine if the tspec can be admitted or not based on current policy */
+	if (lim_admit_policy(pMac, &pAddts->tspec, psessionEntry) != QDF_STATUS_SUCCESS) {
+		pe_warn("tspec rejected by admit control policy");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* fill in a schedule if requested */
+	if (pSch != NULL) {
+		qdf_mem_set((uint8_t *) pSch, sizeof(*pSch), 0);
+		pSch->svcStartTime = pAddts->tspec.svcStartTime;
+		pSch->svcInterval = svcInterval;
+		pSch->maxSvcDuration = (uint16_t) pSch->svcInterval;    /* use SP = SI */
+		pSch->specInterval = 0x1000;    /* fixed for now: TBD */
+
+		pSch->info.direction = pAddts->tspec.tsinfo.traffic.direction;
+		pSch->info.tsid = pAddts->tspec.tsinfo.traffic.tsid;
+		pSch->info.aggregation = 0;     /* no support for aggregation for now: TBD */
+	}
+	/* if no allocation is requested, done */
+	if (!alloc)
+		return QDF_STATUS_SUCCESS;
+
+	/* check that we are in the proper mode to deal with the tspec type */
+	if (lim_validate_access_policy
+		    (pMac, (uint8_t) pAddts->tspec.tsinfo.traffic.accessPolicy, assocId,
+		    psessionEntry) != QDF_STATUS_SUCCESS) {
+		pe_warn("AccessPolicy: %d is not valid in current mode",
+			pAddts->tspec.tsinfo.traffic.accessPolicy);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* add tspec to list */
+	if (lim_tspec_add
+		    (pMac, pAddr, assocId, &pAddts->tspec, svcInterval, &pTspecInfo)
+	    != QDF_STATUS_SUCCESS) {
+		pe_err("no space in tspec list");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* passing lim tspec table index to the caller */
+	*pTspecIdx = pTspecInfo->idx;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_admit_control_delete_ts
+   \brief Delete the specified Tspec for the specified STA
+   \param   tpAniSirGlobal pMac
+   \param       uint16_t               assocId
+   \param       tSirMacTSInfo    *pTsInfo
+   \param       uint8_t               *pTsStatus
+   \param       uint8_t             *ptspecIdx
+   \return QDF_STATUS - status
+   -------------------------------------------------------------*/
+
+QDF_STATUS
+lim_admit_control_delete_ts(tpAniSirGlobal pMac,
+			    uint16_t assocId,
+			    tSirMacTSInfo *pTsInfo,
+			    uint8_t *pTsStatus, uint8_t *ptspecIdx)
+{
+	tpLimTspecInfo pTspecInfo = NULL;
+
+	if (pTsStatus != NULL)
+		*pTsStatus = 0;
+
+	if (lim_find_tspec
+		    (pMac, assocId, pTsInfo, &pMac->lim.tspecInfo[0],
+		    &pTspecInfo) == QDF_STATUS_SUCCESS) {
+		if (pTspecInfo != NULL) {
+			pe_debug("Tspec entry: %d found", pTspecInfo->idx);
+
+			*ptspecIdx = pTspecInfo->idx;
+			lim_tspec_delete(pMac, pTspecInfo);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	return QDF_STATUS_E_FAILURE;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_admit_control_delete_sta
+   \brief Delete all TSPEC for the specified STA
+   \param   tpAniSirGlobal pMac
+   \param     uint16_t assocId
+   \return QDF_STATUS - status
+   -------------------------------------------------------------*/
+
+QDF_STATUS lim_admit_control_delete_sta(tpAniSirGlobal pMac, uint16_t assocId)
+{
+	tpLimTspecInfo pTspecInfo = &pMac->lim.tspecInfo[0];
+	int ctspec;
+
+	for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++) {
+		if (assocId == pTspecInfo->assocId) {
+			lim_tspec_delete(pMac, pTspecInfo);
+			pe_debug("Deleting TSPEC: %d for assocId: %d", ctspec,
+				assocId);
+		}
+	}
+	pe_debug("assocId: %d done", assocId);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_admit_control_init
+   \brief init tspec table
+   \param   tpAniSirGlobal pMac
+   \return QDF_STATUS - status
+   -------------------------------------------------------------*/
+QDF_STATUS lim_admit_control_init(tpAniSirGlobal pMac)
+{
+	qdf_mem_set(pMac->lim.tspecInfo,
+		    LIM_NUM_TSPEC_MAX * sizeof(tLimTspecInfo), 0);
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_send_hal_msg_add_ts
+   \brief Send halMsg_AddTs to HAL
+   \param   tpAniSirGlobal pMac
+   \param     uint16_t        staIdx
+   \param     uint8_t         tspecIdx
+   \param       tSirMacTspecIE tspecIE
+   \param       tSirTclasInfo   *tclasInfo
+   \param       uint8_t           tclasProc
+   \param       uint16_t          tsm_interval
+   \return QDF_STATUS - status
+   -------------------------------------------------------------*/
+#ifdef FEATURE_WLAN_ESE
+QDF_STATUS
+lim_send_hal_msg_add_ts(tpAniSirGlobal pMac,
+			uint16_t staIdx,
+			uint8_t tspecIdx,
+			tSirMacTspecIE tspecIE,
+			uint8_t sessionId, uint16_t tsm_interval)
+#else
+QDF_STATUS
+lim_send_hal_msg_add_ts(tpAniSirGlobal pMac,
+			uint16_t staIdx,
+			uint8_t tspecIdx, tSirMacTspecIE tspecIE, uint8_t sessionId)
+#endif
+{
+	struct scheduler_msg msg = {0};
+	tpAddTsParams pAddTsParam;
+
+	tpPESession psessionEntry = pe_find_session_by_session_id(pMac, sessionId);
+
+	if (psessionEntry == NULL) {
+		pe_err("Unable to get Session for session Id: %d",
+			sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pAddTsParam = qdf_mem_malloc(sizeof(tAddTsParams));
+	if (!pAddTsParam)
+		return QDF_STATUS_E_NOMEM;
+
+	pAddTsParam->staIdx = staIdx;
+	pAddTsParam->tspecIdx = tspecIdx;
+	qdf_mem_copy(&pAddTsParam->tspec, &tspecIE, sizeof(tSirMacTspecIE));
+	pAddTsParam->sessionId = sessionId;
+	pAddTsParam->sme_session_id = psessionEntry->smeSessionId;
+
+#ifdef FEATURE_WLAN_ESE
+	pAddTsParam->tsm_interval = tsm_interval;
+#endif
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (pMac->mlme_cfg->lfr.lfr3_roaming_offload &&
+	    psessionEntry->is11Rconnection)
+		pAddTsParam->setRICparams = 1;
+#endif
+
+	msg.type = WMA_ADD_TS_REQ;
+	msg.bodyptr = pAddTsParam;
+	msg.bodyval = 0;
+
+	/* We need to defer any incoming messages until we get a
+	 * WMA_ADD_TS_RSP from HAL.
+	 */
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+	MTRACE(mac_trace_msg_tx(pMac, sessionId, msg.type));
+
+	if (QDF_STATUS_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
+		pe_warn("wma_post_ctrl_msg() failed");
+		SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+		qdf_mem_free(pAddTsParam);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_send_hal_msg_del_ts
+   \brief Send halMsg_AddTs to HAL
+   \param   tpAniSirGlobal pMac
+   \param     uint16_t        staIdx
+   \param     uint8_t         tspecIdx
+   \param     tSirAddtsReqInfo addts
+   \return QDF_STATUS - status
+   -------------------------------------------------------------*/
+
+QDF_STATUS
+lim_send_hal_msg_del_ts(tpAniSirGlobal pMac,
+			uint16_t staIdx,
+			uint8_t tspecIdx,
+			tSirDeltsReqInfo delts, uint8_t sessionId, uint8_t *bssId)
+{
+	struct scheduler_msg msg = {0};
+	tpDelTsParams pDelTsParam;
+	tpPESession psessionEntry = NULL;
+
+	pDelTsParam = qdf_mem_malloc(sizeof(tDelTsParams));
+	if (!pDelTsParam)
+		return QDF_STATUS_E_NOMEM;
+
+	msg.type = WMA_DEL_TS_REQ;
+	msg.bodyptr = pDelTsParam;
+	msg.bodyval = 0;
+
+	/* filling message parameters. */
+	pDelTsParam->staIdx = staIdx;
+	pDelTsParam->tspecIdx = tspecIdx;
+	qdf_mem_copy(&pDelTsParam->bssId, bssId, sizeof(tSirMacAddr));
+
+	psessionEntry = pe_find_session_by_session_id(pMac, sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session does Not exist with given sessionId: %d",
+			       sessionId);
+		goto err;
+	}
+	pDelTsParam->sessionId = psessionEntry->smeSessionId;
+	pDelTsParam->userPrio = delts.wmeTspecPresent ?
+			delts.tspec.tsinfo.traffic.userPrio :
+			delts.tsinfo.traffic.userPrio;
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (pMac->mlme_cfg->lfr.lfr3_roaming_offload &&
+	    psessionEntry->is11Rconnection) {
+		qdf_mem_copy(&pDelTsParam->delTsInfo, &delts,
+			     sizeof(tSirDeltsReqInfo));
+		pDelTsParam->setRICparams = 1;
+	}
+#endif
+	MTRACE(mac_trace_msg_tx(pMac, sessionId, msg.type));
+
+	if (QDF_STATUS_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
+		pe_warn("wma_post_ctrl_msg() failed");
+		goto err;
+	}
+	return QDF_STATUS_SUCCESS;
+
+err:
+	qdf_mem_free(pDelTsParam);
+	return QDF_STATUS_E_FAILURE;
+}
+
+/** -------------------------------------------------------------
+   \fn     lim_process_hal_add_ts_rsp
+   \brief  This function process the WMA_ADD_TS_RSP from HAL.
+ \       If response is successful, then send back SME_ADDTS_RSP.
+ \       Otherwise, send DELTS action frame to peer and then
+ \       then send back SME_ADDTS_RSP.
+ \
+   \param  tpAniSirGlobal  pMac
+   \param  struct scheduler_msg *limMsg
+   -------------------------------------------------------------*/
+void lim_process_hal_add_ts_rsp(tpAniSirGlobal pMac,
+				struct scheduler_msg *limMsg)
+{
+	tpAddTsParams pAddTsRspMsg = NULL;
+	tpDphHashNode pSta = NULL;
+	uint16_t assocId = 0;
+	tSirMacAddr peerMacAddr;
+	uint8_t rspReqd = 1;
+	tpPESession psessionEntry = NULL;
+
+	/* Need to process all the deferred messages enqueued
+	 * since sending the WMA_ADD_TS_REQ.
+	 */
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+
+	if (NULL == limMsg->bodyptr) {
+		pe_err("Received WMA_ADD_TS_RSP with NULL");
+		goto end;
+	}
+
+	pAddTsRspMsg = (tpAddTsParams) (limMsg->bodyptr);
+
+	/* 090803: Use pe_find_session_by_session_id() to obtain the PE session context */
+	/* from the sessionId in the Rsp Msg from HAL */
+	psessionEntry = pe_find_session_by_session_id(pMac, pAddTsRspMsg->sessionId);
+
+	if (psessionEntry == NULL) {
+		pe_err("Session does Not exist with given sessionId: %d",
+			       pAddTsRspMsg->sessionId);
+		lim_send_sme_addts_rsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED,
+				       psessionEntry, pAddTsRspMsg->tspec,
+				       pMac->lim.gLimAddtsReq.sessionId,
+				       pMac->lim.gLimAddtsReq.transactionId);
+		goto end;
+	}
+
+	if (pAddTsRspMsg->status == QDF_STATUS_SUCCESS) {
+		pe_debug("Received successful ADDTS response from HAL");
+		/* Use the smesessionId and smetransactionId from the PE session context */
+		lim_send_sme_addts_rsp(pMac, rspReqd, eSIR_SME_SUCCESS,
+				       psessionEntry, pAddTsRspMsg->tspec,
+				       psessionEntry->smeSessionId,
+				       psessionEntry->transactionId);
+		goto end;
+	} else {
+		pe_debug("Received failure ADDTS response from HAL");
+		/* Send DELTS action frame to AP */
+		/* 090803: Get peer MAC addr from session */
+		sir_copy_mac_addr(peerMacAddr, psessionEntry->bssId);
+
+		/* 090803: Add the SME Session ID */
+		lim_send_delts_req_action_frame(pMac, peerMacAddr, rspReqd,
+						&pAddTsRspMsg->tspec.tsinfo,
+						&pAddTsRspMsg->tspec, psessionEntry);
+
+		/* Delete TSPEC */
+		/* 090803: Pull the hash table from the session */
+		pSta = dph_lookup_assoc_id(pMac, pAddTsRspMsg->staIdx, &assocId,
+					   &psessionEntry->dph.dphHashTable);
+		if (pSta != NULL)
+			lim_admit_control_delete_ts(pMac, assocId,
+						    &pAddTsRspMsg->tspec.tsinfo,
+						    NULL,
+						    (uint8_t *) &pAddTsRspMsg->
+						    tspecIdx);
+
+		/* Send SME_ADDTS_RSP */
+		/* 090803: Use the smesessionId and smetransactionId from the PE session context */
+		lim_send_sme_addts_rsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED,
+				       psessionEntry, pAddTsRspMsg->tspec,
+				       psessionEntry->smeSessionId,
+				       psessionEntry->transactionId);
+		goto end;
+	}
+
+end:
+	if (pAddTsRspMsg != NULL)
+		qdf_mem_free(pAddTsRspMsg);
+	return;
+}
diff --git a/core/mac/src/pe/lim/lim_aid_mgmt.c b/core/mac/src/pe/lim/lim_aid_mgmt.c
new file mode 100644
index 0000000..3414c9b
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_aid_mgmt.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2011-2016, 2018 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.
+ */
+
+/*
+ *
+ * This file lim_aid_mgmt.c contains the functions related to
+ * AID pool management like initialization, assignment etc.
+ * Author:        Chandra Modumudi
+ * Date:          03/20/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "cds_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+#include "sir_params.h"
+#include "lim_utils.h"
+#include "lim_timer_utils.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "lim_session_utils.h"
+
+#define LIM_START_PEER_IDX   1
+
+/**
+ * lim_init_peer_idxpool() -- initializes peer index pool
+ * @pMac: mac context
+ * @pSessionEntry: session entry
+ *
+ * This function is called while starting a BSS at AP
+ * to initialize AID pool. This may also be called while
+ * starting/joining an IBSS if 'Association' is allowed
+ * in IBSS.
+ *
+ * Return: None
+ */
+
+void lim_init_peer_idxpool(tpAniSirGlobal pMac, tpPESession pSessionEntry)
+{
+	uint8_t i;
+	uint8_t maxAssocSta = pMac->lim.maxStation;
+
+	pSessionEntry->gpLimPeerIdxpool[0] = 0;
+
+#ifdef FEATURE_WLAN_TDLS
+	/*
+	* In station role, DPH_STA_HASH_INDEX_PEER (index 1) is reserved
+	* for peer station index corresponding to AP. Avoid choosing that index
+	* and get index starting from (DPH_STA_HASH_INDEX_PEER + 1)
+	* (index 2) for TDLS stations;
+	*/
+	if (LIM_IS_STA_ROLE(pSessionEntry)) {
+		pSessionEntry->freePeerIdxHead = DPH_STA_HASH_INDEX_PEER + 1;
+	} else
+#endif
+#ifdef QCA_IBSS_SUPPORT
+	if (LIM_IS_IBSS_ROLE(pSessionEntry)) {
+		pSessionEntry->freePeerIdxHead = LIM_START_PEER_IDX;
+	} else
+#endif
+	{
+		pSessionEntry->freePeerIdxHead = LIM_START_PEER_IDX;
+	}
+
+	for (i = pSessionEntry->freePeerIdxHead; i < maxAssocSta; i++) {
+		pSessionEntry->gpLimPeerIdxpool[i] = i + 1;
+	}
+	pSessionEntry->gpLimPeerIdxpool[i] = 0;
+
+	pSessionEntry->freePeerIdxTail = i;
+
+}
+
+/**
+ * lim_assign_peer_idx()
+ *
+ ***FUNCTION:
+ * This function is called to get a peer station index. This index is
+ * used during Association/Reassociation
+ * frame handling to assign association ID (aid) to a STA.
+ * In case of TDLS, this is used to assign a index into the Dph hash entry.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @return peerIdx  - assigned peer Station IDx for STA
+ */
+
+uint16_t lim_assign_peer_idx(tpAniSirGlobal pMac, tpPESession pSessionEntry)
+{
+	uint16_t peerId;
+
+	/* make sure we haven't exceeded the configurable limit on associations */
+	/* This count is global to ensure that it doesn't exceed the hardware limits. */
+	if (pe_get_current_stas_count(pMac) >=
+	    pMac->mlme_cfg->sap_cfg.assoc_sta_limit) {
+		/* too many associations already active */
+		return 0;
+	}
+
+	/* return head of free list */
+
+	if (pSessionEntry->freePeerIdxHead) {
+		peerId = pSessionEntry->freePeerIdxHead;
+		pSessionEntry->freePeerIdxHead =
+			pSessionEntry->gpLimPeerIdxpool[pSessionEntry->
+							freePeerIdxHead];
+		if (pSessionEntry->freePeerIdxHead == 0)
+			pSessionEntry->freePeerIdxTail = 0;
+		pSessionEntry->gLimNumOfCurrentSTAs++;
+		return peerId;
+	}
+
+	return 0;               /* no more free peer index */
+}
+
+/**
+ * lim_release_peer_idx()
+ *
+ ***FUNCTION:
+ * This function is called when a STA context is removed
+ * at AP (or at a STA in IBSS mode or TDLS) to return peer Index
+ * to free pool.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  peerIdx - peer station index that need to return to free pool
+ *
+ * @return None
+ */
+
+void
+lim_release_peer_idx(tpAniSirGlobal pMac, uint16_t peerIdx,
+		     tpPESession pSessionEntry)
+{
+	pSessionEntry->gLimNumOfCurrentSTAs--;
+
+	/* insert at tail of free list */
+	if (pSessionEntry->freePeerIdxTail) {
+		pSessionEntry->gpLimPeerIdxpool[pSessionEntry->
+						freePeerIdxTail] =
+			(uint8_t) peerIdx;
+		pSessionEntry->freePeerIdxTail = (uint8_t) peerIdx;
+	} else {
+		pSessionEntry->freePeerIdxTail =
+			pSessionEntry->freePeerIdxHead = (uint8_t) peerIdx;
+	}
+	pSessionEntry->gpLimPeerIdxpool[(uint8_t) peerIdx] = 0;
+}
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
new file mode 100644
index 0000000..fb245f4
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -0,0 +1,2758 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * This file lim_api.cc contains the functions that are
+ * exported by LIM to other modules.
+ *
+ * Author:        Chandra Modumudi
+ * Date:          02/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "wni_cfg.h"
+#include "wni_api.h"
+#include "sir_common.h"
+#include "sir_debug.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_api.h"
+#include "lim_global.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_admit_control.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "lim_security_utils.h"
+#include "wmm_apsd.h"
+#include "lim_trace.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "wma_types.h"
+
+#include "rrm_api.h"
+
+#include <lim_ft.h>
+#include "qdf_types.h"
+#include "cds_packet.h"
+#include "cds_utils.h"
+#include "sys_startup.h"
+#include "cds_api.h"
+#include "wlan_policy_mgr_api.h"
+#include "nan_datapath.h"
+#include "wma.h"
+#include "wlan_mgmt_txrx_utils_api.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "os_if_nan.h"
+#include <wlan_scan_ucfg_api.h>
+#include <wlan_scan_public_structs.h>
+#include <wlan_p2p_ucfg_api.h>
+#include "wlan_utility.h"
+#include <wlan_tdls_cfg_api.h>
+#include "cfg_ucfg_api.h"
+#include "wlan_mlme_public_struct.h"
+
+static void __lim_init_scan_vars(tpAniSirGlobal pMac)
+{
+	qdf_mem_set(&pMac->lim.dfschannelList, sizeof(tSirDFSChannelList), 0);
+}
+
+static void __lim_init_bss_vars(tpAniSirGlobal pMac)
+{
+	qdf_mem_set((void *)pMac->lim.gpSession,
+		    sizeof(*pMac->lim.gpSession) * pMac->lim.maxBssId, 0);
+
+	/* This is for testing purposes only, be default should always be off */
+	pMac->lim.gpLimMlmSetKeysReq = NULL;
+}
+
+static void __lim_init_stats_vars(tpAniSirGlobal pMac)
+{
+	pMac->lim.gLimNumBeaconsRcvd = 0;
+	pMac->lim.gLimNumBeaconsIgnored = 0;
+
+	pMac->lim.gLimNumDeferredMsgs = 0;
+
+	/* / Variable to keep track of number of currently associated STAs */
+	pMac->lim.gLimNumOfAniSTAs = 0; /* count of ANI peers */
+
+	/* Heart-Beat interval value */
+	pMac->lim.gLimHeartBeatCount = 0;
+
+	qdf_mem_zero(pMac->lim.gLimHeartBeatApMac[0],
+			sizeof(tSirMacAddr));
+	qdf_mem_zero(pMac->lim.gLimHeartBeatApMac[1],
+			sizeof(tSirMacAddr));
+	pMac->lim.gLimHeartBeatApMacIndex = 0;
+
+	/* Statistics to keep track of no. beacons rcvd in heart beat interval */
+	qdf_mem_set(pMac->lim.gLimHeartBeatBeaconStats,
+		    sizeof(pMac->lim.gLimHeartBeatBeaconStats), 0);
+
+#ifdef WLAN_DEBUG
+	/* Debug counters */
+	pMac->lim.numTot = 0;
+	pMac->lim.numBbt = 0;
+	pMac->lim.numProtErr = 0;
+	pMac->lim.numLearn = 0;
+	pMac->lim.numLearnIgnore = 0;
+	pMac->lim.numSme = 0;
+	qdf_mem_set(pMac->lim.numMAC, sizeof(pMac->lim.numMAC), 0);
+	pMac->lim.gLimNumAssocReqDropInvldState = 0;
+	pMac->lim.gLimNumAssocReqDropACRejectTS = 0;
+	pMac->lim.gLimNumAssocReqDropACRejectSta = 0;
+	pMac->lim.gLimNumReassocReqDropInvldState = 0;
+	pMac->lim.gLimNumHashMissIgnored = 0;
+	pMac->lim.gLimUnexpBcnCnt = 0;
+	pMac->lim.gLimBcnSSIDMismatchCnt = 0;
+	pMac->lim.gLimNumLinkEsts = 0;
+	pMac->lim.gLimNumRxCleanup = 0;
+	pMac->lim.gLim11bStaAssocRejectCount = 0;
+#endif
+}
+
+static void __lim_init_states(tpAniSirGlobal pMac)
+{
+	/* Counts Heartbeat failures */
+	pMac->lim.gLimHBfailureCntInLinkEstState = 0;
+	pMac->lim.gLimProbeFailureAfterHBfailedCnt = 0;
+	pMac->lim.gLimHBfailureCntInOtherStates = 0;
+	pMac->lim.gLimRspReqd = 0;
+	pMac->lim.gLimPrevSmeState = eLIM_SME_OFFLINE_STATE;
+
+	/* / MLM State visible across all Sirius modules */
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, NO_SESSION, eLIM_MLM_IDLE_STATE));
+	pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
+
+	/* / Previous MLM State */
+	pMac->lim.gLimPrevMlmState = eLIM_MLM_OFFLINE_STATE;
+
+	/**
+	 * Initialize state to eLIM_SME_OFFLINE_STATE
+	 */
+	pMac->lim.gLimSmeState = eLIM_SME_OFFLINE_STATE;
+
+	/**
+	 * By default assume 'unknown' role. This will be updated
+	 * when SME_START_BSS_REQ is received.
+	 */
+
+	qdf_mem_set(&pMac->lim.gLimNoShortParams, sizeof(tLimNoShortParams), 0);
+	qdf_mem_set(&pMac->lim.gLimNoShortSlotParams,
+		    sizeof(tLimNoShortSlotParams), 0);
+
+	pMac->lim.gLimPhyMode = 0;
+	pMac->lim.gLimProbeRespDisableFlag = 0; /* control over probe resp */
+}
+
+static void __lim_init_vars(tpAniSirGlobal pMac)
+{
+	/* Place holder for Measurement Req/Rsp/Ind related info */
+
+
+	/* Deferred Queue Parameters */
+	qdf_mem_set(&pMac->lim.gLimDeferredMsgQ, sizeof(tSirAddtsReq), 0);
+
+	/* addts request if any - only one can be outstanding at any time */
+	qdf_mem_set(&pMac->lim.gLimAddtsReq, sizeof(tSirAddtsReq), 0);
+	pMac->lim.gLimAddtsSent = 0;
+	pMac->lim.gLimAddtsRspTimerCount = 0;
+
+	/* protection related config cache */
+	qdf_mem_set(&pMac->lim.cfgProtection, sizeof(tCfgProtection), 0);
+	pMac->lim.gLimProtectionControl = 0;
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+
+	/* WMM Related Flag */
+	pMac->lim.gUapsdEnable = 0;
+
+	/* QoS-AC Downgrade: Initially, no AC is admitted */
+	pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] = 0;
+	pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] = 0;
+
+	/* dialogue token List head/tail for Action frames request sent. */
+	pMac->lim.pDialogueTokenHead = NULL;
+	pMac->lim.pDialogueTokenTail = NULL;
+
+	qdf_mem_set(&pMac->lim.tspecInfo,
+		    sizeof(tLimTspecInfo) * LIM_NUM_TSPEC_MAX, 0);
+
+	/* admission control policy information */
+	qdf_mem_set(&pMac->lim.admitPolicyInfo, sizeof(tLimAdmitPolicyInfo), 0);
+}
+
+static void __lim_init_assoc_vars(tpAniSirGlobal pMac)
+{
+	pMac->lim.gLimIbssStaLimit = 0;
+	/* Place holder for current authentication request */
+	/* being handled */
+	pMac->lim.gpLimMlmAuthReq = NULL;
+
+	/* / MAC level Pre-authentication related globals */
+	pMac->lim.gLimPreAuthChannelNumber = 0;
+	pMac->lim.gLimPreAuthType = eSIR_OPEN_SYSTEM;
+	qdf_mem_set(&pMac->lim.gLimPreAuthPeerAddr, sizeof(tSirMacAddr), 0);
+	pMac->lim.gLimNumPreAuthContexts = 0;
+	qdf_mem_set(&pMac->lim.gLimPreAuthTimerTable, sizeof(tLimPreAuthTable),
+		    0);
+
+	/* Placed holder to deauth reason */
+	pMac->lim.gLimDeauthReasonCode = 0;
+
+	/* Place holder for Pre-authentication node list */
+	pMac->lim.pLimPreAuthList = NULL;
+
+	/* One cache for each overlap and associated case. */
+	qdf_mem_set(pMac->lim.protStaOverlapCache,
+		    sizeof(tCacheParams) * LIM_PROT_STA_OVERLAP_CACHE_SIZE, 0);
+	qdf_mem_set(pMac->lim.protStaCache,
+		    sizeof(tCacheParams) * LIM_PROT_STA_CACHE_SIZE, 0);
+
+	pMac->lim.pSessionEntry = NULL;
+	pMac->lim.reAssocRetryAttempt = 0;
+
+}
+
+static void __lim_init_ht_vars(tpAniSirGlobal pMac)
+{
+	pMac->lim.htCapabilityPresentInBeacon = 0;
+	pMac->lim.gHTGreenfield = 0;
+	pMac->lim.gHTShortGI40Mhz = 0;
+	pMac->lim.gHTShortGI20Mhz = 0;
+	pMac->lim.gHTMaxAmsduLength = 0;
+	pMac->lim.gHTDsssCckRate40MHzSupport = 0;
+	pMac->lim.gHTPSMPSupport = 0;
+	pMac->lim.gHTLsigTXOPProtection = 0;
+	pMac->lim.gHTMIMOPSState = eSIR_HT_MIMO_PS_STATIC;
+	pMac->lim.gHTAMpduDensity = 0;
+
+	pMac->lim.gMaxAmsduSizeEnabled = false;
+	pMac->lim.gHTMaxRxAMpduFactor = 0;
+	pMac->lim.gHTServiceIntervalGranularity = 0;
+	pMac->lim.gHTControlledAccessOnly = 0;
+	pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+	pMac->lim.gHTPCOActive = 0;
+
+	pMac->lim.gHTPCOPhase = 0;
+	pMac->lim.gHTSecondaryBeacon = 0;
+	pMac->lim.gHTDualCTSProtection = 0;
+	pMac->lim.gHTSTBCBasicMCS = 0;
+}
+
+static QDF_STATUS __lim_init_config(tpAniSirGlobal pMac)
+{
+	uint32_t val1;
+	bool valb;
+	struct mlme_ht_capabilities_info *ht_cap_info;
+	QDF_STATUS status;
+
+	/* Read all the CFGs here that were updated before pe_start is called */
+	/* All these CFG READS/WRITES are only allowed in init, at start when there is no session
+	 * and they will be used throughout when there is no session
+	 */
+	pMac->lim.gLimIbssStaLimit = pMac->mlme_cfg->sap_cfg.assoc_sta_limit;
+	ht_cap_info = &pMac->mlme_cfg->ht_caps.ht_cap_info;
+
+	/* channel bonding mode could be set to anything from 0 to 4(Titan had these */
+	/* modes But for Taurus we have only two modes: enable(>0) or disable(=0) */
+	ht_cap_info->supported_channel_width_set =
+			pMac->mlme_cfg->feature_flags.channel_bonding_mode ?
+			WNI_CFG_CHANNEL_BONDING_MODE_ENABLE :
+			WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+
+	pMac->mlme_cfg->ht_caps.info_field_1.recommended_tx_width_set =
+		ht_cap_info->supported_channel_width_set;
+
+	if (!pMac->mlme_cfg->timeouts.heart_beat_threshold) {
+		pMac->sys.gSysEnableLinkMonitorMode = 0;
+	} else {
+		/* No need to activate the timer during init time. */
+		pMac->sys.gSysEnableLinkMonitorMode = 1;
+	}
+
+	/* WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA - not needed */
+
+	/* This was initially done after resume notification from HAL. Now, DAL is
+	   started before PE so this can be done here */
+	handle_ht_capabilityand_ht_info(pMac, NULL);
+	if (QDF_STATUS_SUCCESS !=
+	    wlan_cfg_get_int(pMac, WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP,
+			     (uint32_t *) &pMac->lim.disableLDPCWithTxbfAP)) {
+		pe_err("cfg get disableLDPCWithTxbfAP failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+#ifdef FEATURE_WLAN_TDLS
+	status = cfg_tdls_get_buffer_sta_enable(pMac->psoc, &valb);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("cfg get LimTDLSBufStaEnabled failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pMac->lim.gLimTDLSBufStaEnabled = (uint8_t)valb;
+
+	status = cfg_tdls_get_uapsd_mask(pMac->psoc, &val1);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("cfg get LimTDLSUapsdMask failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pMac->lim.gLimTDLSUapsdMask = (uint8_t)val1;
+
+	status = cfg_tdls_get_off_channel_enable(pMac->psoc, &valb);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("cfg get LimTDLSUapsdMask failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pMac->lim.gLimTDLSOffChannelEnabled = (uint8_t)valb;
+
+	status = cfg_tdls_get_wmm_mode_enable(pMac->psoc, &valb);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("cfg get LimTDLSWmmMode failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pMac->lim.gLimTDLSWmmMode = (uint8_t)valb;
+#endif
+
+	if (QDF_STATUS_SUCCESS != wlan_cfg_get_int(pMac,
+					     WNI_CFG_OBSS_DETECTION_OFFLOAD,
+					     (uint32_t *)&pMac->lim.
+					     global_obss_offload_enabled)) {
+		pe_err("cfg get obss_detection_offloaded failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (QDF_STATUS_SUCCESS !=
+	    wlan_cfg_get_int(pMac, WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD,
+			     (uint32_t *) &pMac->lim.
+			     global_obss_color_collision_det_offload)) {
+		pe_err("cfg get obss_color_collision_offload failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+   lim_start
+   This function is to replace the __lim_process_sme_start_req since there is no
+   eWNI_SME_START_REQ post to PE.
+ */
+QDF_STATUS lim_start(tpAniSirGlobal pMac)
+{
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+
+	pe_debug("enter");
+
+	if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) {
+		pMac->lim.gLimSmeState = eLIM_SME_IDLE_STATE;
+
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_SME_STATE, NO_SESSION,
+			       pMac->lim.gLimSmeState));
+
+		/* Initialize MLM state machine */
+		if (QDF_STATUS_SUCCESS != lim_init_mlm(pMac)) {
+			pe_err("Init MLM failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		/**
+		 * Should not have received eWNI_SME_START_REQ in states
+		 * other than OFFLINE. Return response to host and
+		 * log error
+		 */
+		pe_warn("Invalid SME state: %X",
+			pMac->lim.gLimSmeState);
+		retCode = QDF_STATUS_E_FAILURE;
+	}
+
+	pMac->lim.req_id =
+		ucfg_scan_register_requester(pMac->psoc,
+					     "LIM",
+					     lim_process_rx_scan_handler,
+					     pMac);
+	return retCode;
+}
+
+/**
+ * lim_initialize()
+ *
+ ***FUNCTION:
+ * This function is called from LIM thread entry function.
+ * LIM related global data structures are initialized in this function.
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac - Pointer to global MAC structure
+ * @return None
+ */
+
+QDF_STATUS lim_initialize(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	pMac->lim.mgmtFrameSessionId = NO_SESSION;
+	pMac->lim.tdls_frm_session_id = NO_SESSION;
+	pMac->lim.deferredMsgCnt = 0;
+	pMac->lim.retry_packet_cnt = 0;
+	pMac->lim.ibss_retry_cnt = 0;
+	pMac->lim.deauthMsgCnt = 0;
+	pMac->lim.disassocMsgCnt = 0;
+
+	if (QDF_IS_STATUS_ERROR(qdf_mutex_create(
+			&pMac->lim.lkPeGlobalLock))) {
+		pe_err("lim lock init failed!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	__lim_init_assoc_vars(pMac);
+	__lim_init_vars(pMac);
+	__lim_init_states(pMac);
+	__lim_init_stats_vars(pMac);
+	__lim_init_bss_vars(pMac);
+	__lim_init_scan_vars(pMac);
+	__lim_init_ht_vars(pMac);
+
+	/* Initializations for maintaining peers in IBSS */
+	lim_ibss_init(pMac);
+
+	rrm_initialize(pMac);
+
+	if (QDF_IS_STATUS_ERROR(qdf_mutex_create(
+		&pMac->lim.lim_frame_register_lock))) {
+		pe_err("lim lock init failed!");
+		qdf_mutex_destroy(&pMac->lim.lkPeGlobalLock);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_list_create(&pMac->lim.gLimMgmtFrameRegistratinQueue, 0);
+
+	/* initialize the TSPEC admission control table. */
+	/* Note that this was initially done after resume notification from HAL. */
+	/* Now, DAL is started before PE so this can be done here */
+	lim_admit_control_init(pMac);
+	return status;
+
+} /*** end lim_initialize() ***/
+
+/**
+ * lim_cleanup()
+ *
+ ***FUNCTION:
+ * This function is called upon reset or persona change
+ * to cleanup LIM state
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_cleanup(tpAniSirGlobal pMac)
+{
+	uint8_t i;
+	qdf_list_node_t *lst_node;
+
+	/*
+	 * Before destroying the list making sure all the nodes have been
+	 * deleted
+	 */
+	while (qdf_list_remove_front(
+			&pMac->lim.gLimMgmtFrameRegistratinQueue,
+			&lst_node) == QDF_STATUS_SUCCESS) {
+		qdf_mem_free(lst_node);
+	}
+	qdf_list_destroy(&pMac->lim.gLimMgmtFrameRegistratinQueue);
+	qdf_mutex_destroy(&pMac->lim.lim_frame_register_lock);
+
+	pe_deregister_mgmt_rx_frm_callback(pMac);
+
+	qdf_mem_free(pMac->lim.gpLimRemainOnChanReq);
+	pMac->lim.gpLimRemainOnChanReq = NULL;
+
+	/* free up preAuth table */
+	if (pMac->lim.gLimPreAuthTimerTable.pTable != NULL) {
+		for (i = 0; i < pMac->lim.gLimPreAuthTimerTable.numEntry; i++)
+			qdf_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable[i]);
+		qdf_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable);
+		pMac->lim.gLimPreAuthTimerTable.pTable = NULL;
+		pMac->lim.gLimPreAuthTimerTable.numEntry = 0;
+	}
+
+	if (NULL != pMac->lim.pDialogueTokenHead) {
+		lim_delete_dialogue_token_list(pMac);
+	}
+
+	if (NULL != pMac->lim.pDialogueTokenTail) {
+		qdf_mem_free(pMac->lim.pDialogueTokenTail);
+		pMac->lim.pDialogueTokenTail = NULL;
+	}
+
+	if (pMac->lim.gpLimMlmSetKeysReq != NULL) {
+		qdf_mem_free(pMac->lim.gpLimMlmSetKeysReq);
+		pMac->lim.gpLimMlmSetKeysReq = NULL;
+	}
+
+	if (pMac->lim.gpLimMlmAuthReq != NULL) {
+		qdf_mem_free(pMac->lim.gpLimMlmAuthReq);
+		pMac->lim.gpLimMlmAuthReq = NULL;
+	}
+
+	if (pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq) {
+		qdf_mem_free(pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq);
+		pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
+	}
+
+	if (pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq) {
+		qdf_mem_free(pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq);
+		pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
+	}
+
+	/* Now, finally reset the deferred message queue pointers */
+	lim_reset_deferred_msg_q(pMac);
+
+	rrm_cleanup(pMac);
+
+	lim_ft_cleanup_all_ft_sessions(pMac);
+
+	ucfg_scan_unregister_requester(pMac->psoc, pMac->lim.req_id);
+} /*** end lim_cleanup() ***/
+
+#ifdef WLAN_FEATURE_MEMDUMP_ENABLE
+/**
+ * lim_state_info_dump() - print state information of lim layer
+ * @buf: buffer pointer
+ * @size: size of buffer to be filled
+ *
+ * This function is used to print state information of lim layer
+ *
+ * Return: None
+ */
+static void lim_state_info_dump(char **buf_ptr, uint16_t *size)
+{
+	tHalHandle hal;
+	tpAniSirGlobal mac;
+	uint16_t len = 0;
+	char *buf = *buf_ptr;
+
+	hal = cds_get_context(QDF_MODULE_ID_PE);
+	if (hal == NULL) {
+		QDF_ASSERT(0);
+		return;
+	}
+
+	mac = PMAC_STRUCT(hal);
+
+	pe_debug("size of buffer: %d", *size);
+
+	len += qdf_scnprintf(buf + len, *size - len,
+		"\n SmeState: %d", mac->lim.gLimSmeState);
+	len += qdf_scnprintf(buf + len, *size - len,
+		"\n PrevSmeState: %d", mac->lim.gLimPrevSmeState);
+	len += qdf_scnprintf(buf + len, *size - len,
+		"\n MlmState: %d", mac->lim.gLimMlmState);
+	len += qdf_scnprintf(buf + len, *size - len,
+		"\n PrevMlmState: %d", mac->lim.gLimPrevMlmState);
+	len += qdf_scnprintf(buf + len, *size - len,
+		"\n ProcessDefdMsgs: %d", mac->lim.gLimProcessDefdMsgs);
+
+	*size -= len;
+	*buf_ptr += len;
+}
+
+/**
+ * lim_register_debug_callback() - registration function for lim layer
+ * to print lim state information
+ *
+ * Return: None
+ */
+static void lim_register_debug_callback(void)
+{
+	qdf_register_debug_callback(QDF_MODULE_ID_PE, &lim_state_info_dump);
+}
+#else /* WLAN_FEATURE_MEMDUMP_ENABLE */
+static void lim_register_debug_callback(void)
+{
+}
+#endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
+static void lim_nan_register_callbacks(tpAniSirGlobal mac_ctx)
+{
+	struct nan_callbacks cb_obj = {0};
+
+	cb_obj.add_ndi_peer = lim_add_ndi_peer_converged;
+	cb_obj.ndp_delete_peers = lim_ndp_delete_peers_converged;
+	cb_obj.delete_peers_by_addr = lim_ndp_delete_peers_by_addr_converged;
+
+	ucfg_nan_register_lim_callbacks(mac_ctx->psoc, &cb_obj);
+}
+
+/*
+ * pe_shutdown_notifier_cb - Shutdown notifier callback
+ * @ctx: Pointer to Global MAC structure
+ *
+ * Return: None
+ */
+static void pe_shutdown_notifier_cb(void *ctx)
+{
+	tpAniSirGlobal mac_ctx = (tpAniSirGlobal)ctx;
+	tpPESession session;
+	uint8_t i;
+
+	lim_deactivate_timers(mac_ctx);
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		session = &mac_ctx->lim.gpSession[i];
+		if (session->valid == true) {
+			if (LIM_IS_AP_ROLE(session))
+				qdf_mc_timer_stop(&session->
+						 protection_fields_reset_timer);
+#ifdef WLAN_FEATURE_11W
+			qdf_mc_timer_stop(&session->pmfComebackTimer);
+#endif
+		}
+	}
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * is_mgmt_protected - check RMF enabled for the peer
+ * @vdev_id: vdev id
+ * @peer_mac_addr: peer mac address
+ *
+ * The function check the mgmt frame protection enabled or not
+ * for station mode and AP mode
+ *
+ * Return: true, if the connection is RMF enabled.
+ */
+static bool is_mgmt_protected(uint32_t vdev_id,
+				  const uint8_t *peer_mac_addr)
+{
+	uint16_t aid;
+	tpDphHashNode sta_ds;
+	tpPESession session;
+	bool protected = false;
+	tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac_ctx)
+		return false;
+
+	session = pe_find_session_by_sme_session_id(mac_ctx,
+						    vdev_id);
+	if (!session) {
+		/* couldn't find session */
+		pe_err("Session not found for vdev_id: %d", vdev_id);
+		return false;
+	}
+
+	if (LIM_IS_AP_ROLE(session)) {
+		sta_ds = dph_lookup_hash_entry(mac_ctx,
+					       (uint8_t *)peer_mac_addr, &aid,
+					       &session->dph.dphHashTable);
+		if (sta_ds) {
+			/* rmfenabled will be set at the time of addbss.
+			 * but sometimes EAP auth fails and keys are not
+			 * installed then if we send any management frame
+			 * like deauth/disassoc with this bit set then
+			 * firmware crashes. so check for keys are
+			 * installed or not also before setting the bit
+			 */
+			if (sta_ds->rmfEnabled && sta_ds->is_key_installed)
+				protected = true;
+		}
+	} else if (session->limRmfEnabled &&
+		   session->is_key_installed) {
+		protected = true;
+	}
+
+	return protected;
+}
+#else
+/**
+ * is_mgmt_protected - check RMF enabled for the peer
+ * @vdev_id: vdev id
+ * @peer_mac_addr: peer mac address
+ *
+ * The function check the mgmt frame protection enabled or not
+ * for station mode and AP mode
+ *
+ * Return: true, if the connection is RMF enabled.
+ */
+static bool is_mgmt_protected(uint32_t vdev_id,
+				  const uint8_t *peer_mac_addr)
+{
+	return false;
+}
+#endif
+
+static void p2p_register_callbacks(tpAniSirGlobal mac_ctx)
+{
+	struct p2p_protocol_callbacks p2p_cb = {0};
+
+	p2p_cb.is_mgmt_protected = is_mgmt_protected;
+	ucfg_p2p_register_callbacks(mac_ctx->psoc, &p2p_cb);
+}
+
+/*
+ * lim_register_sap_bcn_callback(): Register a callback with scan module for SAP
+ * @mac_ctx: pointer to the global mac context
+ *
+ * Registers the function lim_handle_sap_beacon as callback with the Scan
+ * module to handle beacon frames for SAP sessions
+ *
+ * Return: QDF Status
+ */
+static QDF_STATUS lim_register_sap_bcn_callback(tpAniSirGlobal mac_ctx)
+{
+	QDF_STATUS status;
+
+	status = ucfg_scan_register_bcn_cb(mac_ctx->psoc,
+			lim_handle_sap_beacon,
+			SCAN_CB_TYPE_UPDATE_BCN);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		pe_err("failed with status code %08d [x%08x]",
+			status, status);
+	}
+
+	return status;
+}
+
+/*
+ * lim_unregister_sap_bcn_callback(): Unregister the callback with scan module
+ * @mac_ctx: pointer to the global mac context
+ *
+ * Unregisters the callback registered with the Scan
+ * module to handle beacon frames for SAP sessions
+ *
+ * Return: QDF Status
+ */
+static QDF_STATUS lim_unregister_sap_bcn_callback(tpAniSirGlobal mac_ctx)
+{
+	QDF_STATUS status;
+
+	status = ucfg_scan_register_bcn_cb(mac_ctx->psoc,
+			NULL, SCAN_CB_TYPE_UPDATE_BCN);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		pe_err("failed with status code %08d [x%08x]",
+			status, status);
+	}
+
+	return status;
+}
+
+/** -------------------------------------------------------------
+   \fn pe_open
+   \brief will be called in Open sequence from mac_open
+   \param   tpAniSirGlobal pMac
+   \param   tHalOpenParameters *pHalOpenParam
+   \return  QDF_STATUS
+   -------------------------------------------------------------*/
+
+QDF_STATUS pe_open(tpAniSirGlobal pMac, struct cds_config_info *cds_cfg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (QDF_DRIVER_TYPE_MFG == cds_cfg->driver_type)
+		return QDF_STATUS_SUCCESS;
+
+	pMac->lim.maxBssId = cds_cfg->max_bssid;
+	pMac->lim.maxStation = cds_cfg->max_station;
+	qdf_spinlock_create(&pMac->sys.bbt_mgmt_lock);
+
+	if ((pMac->lim.maxBssId == 0) || (pMac->lim.maxStation == 0)) {
+		pe_err("max number of Bssid or Stations cannot be zero!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!QDF_IS_STATUS_SUCCESS(pe_allocate_dph_node_array_buffer())) {
+		pe_err("g_dph_node_array memory allocate failed!");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	pMac->lim.limTimers.gpLimCnfWaitTimer =
+		qdf_mem_malloc(sizeof(TX_TIMER) * (pMac->lim.maxStation + 1));
+	if (!pMac->lim.limTimers.gpLimCnfWaitTimer) {
+		status = QDF_STATUS_E_NOMEM;
+		goto pe_open_timer_fail;
+	}
+
+	pMac->lim.gpSession =
+		qdf_mem_malloc(sizeof(tPESession) * pMac->lim.maxBssId);
+	if (!pMac->lim.gpSession) {
+		status = QDF_STATUS_E_NOMEM;
+		goto pe_open_psession_fail;
+	}
+
+	status = lim_initialize(pMac);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("lim_initialize failed!");
+		status = QDF_STATUS_E_FAILURE;
+		goto  pe_open_lock_fail;
+	}
+
+	/*
+	 * pe_open is successful by now, so it is right time to initialize
+	 * MTRACE for PE module. if LIM_TRACE_RECORD is not defined in build
+	 * file then nothing will be logged for PE module.
+	 */
+#ifdef LIM_TRACE_RECORD
+	MTRACE(lim_trace_init(pMac));
+#endif
+	lim_register_debug_callback();
+	lim_nan_register_callbacks(pMac);
+	p2p_register_callbacks(pMac);
+	lim_register_sap_bcn_callback(pMac);
+
+	if (!QDF_IS_STATUS_SUCCESS(
+	    cds_shutdown_notifier_register(pe_shutdown_notifier_cb, pMac))) {
+		pe_err("%s: Shutdown notifier register failed", __func__);
+	}
+
+	return status; /* status here will be QDF_STATUS_SUCCESS */
+
+pe_open_lock_fail:
+	qdf_mem_free(pMac->lim.gpSession);
+	pMac->lim.gpSession = NULL;
+pe_open_psession_fail:
+	qdf_mem_free(pMac->lim.limTimers.gpLimCnfWaitTimer);
+	pMac->lim.limTimers.gpLimCnfWaitTimer = NULL;
+pe_open_timer_fail:
+	pe_free_dph_node_array_buffer();
+
+	return status;
+}
+
+/** -------------------------------------------------------------
+   \fn pe_close
+   \brief will be called in close sequence from mac_close
+   \param   tpAniSirGlobal pMac
+   \return  QDF_STATUS
+   -------------------------------------------------------------*/
+
+QDF_STATUS pe_close(tpAniSirGlobal pMac)
+{
+	uint8_t i;
+
+	if (ANI_DRIVER_TYPE(pMac) == QDF_DRIVER_TYPE_MFG)
+		return QDF_STATUS_SUCCESS;
+
+	lim_cleanup(pMac);
+	lim_unregister_sap_bcn_callback(pMac);
+
+	if (pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq) {
+		qdf_mem_free(pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq);
+		pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
+	}
+
+	qdf_spinlock_destroy(&pMac->sys.bbt_mgmt_lock);
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		if (pMac->lim.gpSession[i].valid == true)
+			pe_delete_session(pMac, &pMac->lim.gpSession[i]);
+	}
+	qdf_mem_free(pMac->lim.limTimers.gpLimCnfWaitTimer);
+	pMac->lim.limTimers.gpLimCnfWaitTimer = NULL;
+
+	qdf_mem_free(pMac->lim.gpSession);
+	pMac->lim.gpSession = NULL;
+
+	pe_free_dph_node_array_buffer();
+
+	if (!QDF_IS_STATUS_SUCCESS
+		    (qdf_mutex_destroy(&pMac->lim.lkPeGlobalLock))) {
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn pe_start
+   \brief will be called in start sequence from mac_start
+   \param   tpAniSirGlobal pMac
+   \return QDF_STATUS_SUCCESS on success, other QDF_STATUS on error
+   -------------------------------------------------------------*/
+
+QDF_STATUS pe_start(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	status = lim_start(pMac);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("lim_start failed!");
+		return status;
+	}
+	/* Initialize the configurations needed by PE */
+	if (QDF_STATUS_E_FAILURE == __lim_init_config(pMac)) {
+		pe_err("lim init config failed!");
+		/* We need to undo everything in lim_start */
+		lim_cleanup_mlm(pMac);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Initialize the configurations needed by PE */
+	lim_register_hal_ind_call_back(pMac);
+	return status;
+}
+
+/** -------------------------------------------------------------
+   \fn pe_stop
+   \brief will be called in stop sequence from mac_stop
+   \param   tpAniSirGlobal pMac
+   \return none
+   -------------------------------------------------------------*/
+
+void pe_stop(tpAniSirGlobal pMac)
+{
+	lim_cleanup_mlm(pMac);
+	pe_debug(" PE STOP: Set LIM state to eLIM_MLM_OFFLINE_STATE");
+	SET_LIM_MLM_STATE(pMac, eLIM_MLM_OFFLINE_STATE);
+	return;
+}
+
+static void pe_free_nested_messages(struct scheduler_msg *msg)
+{
+	switch (msg->type) {
+	case WMA_SET_LINK_STATE_RSP:
+		pe_debug("WMA_SET_LINK_STATE_RSP");
+		qdf_mem_free(((tpLinkStateParams) msg->bodyptr)->callbackArg);
+		break;
+	default:
+		break;
+	}
+}
+
+/** -------------------------------------------------------------
+   \fn pe_free_msg
+   \brief Called by CDS scheduler (function cds_sched_flush_mc_mqs)
+ \      to free a given PE message on the TX and MC thread.
+ \      This happens when there are messages pending in the PE
+ \      queue when system is being stopped and reset.
+   \param   tpAniSirGlobal pMac
+   \param   struct scheduler_msg       pMsg
+   \return none
+   -----------------------------------------------------------------*/
+void pe_free_msg(tpAniSirGlobal pMac, struct scheduler_msg *pMsg)
+{
+	if (pMsg != NULL) {
+		if (NULL != pMsg->bodyptr) {
+			if (SIR_BB_XPORT_MGMT_MSG == pMsg->type) {
+				cds_pkt_return_packet((cds_pkt_t *) pMsg->
+						      bodyptr);
+			} else {
+				pe_free_nested_messages(pMsg);
+				qdf_mem_free((void *)pMsg->bodyptr);
+			}
+		}
+		pMsg->bodyptr = 0;
+		pMsg->bodyval = 0;
+		pMsg->type = 0;
+	}
+	return;
+}
+
+QDF_STATUS lim_post_msg_api(tpAniSirGlobal mac, struct scheduler_msg *msg)
+{
+	return scheduler_post_message(QDF_MODULE_ID_PE,
+				      QDF_MODULE_ID_PE,
+				      QDF_MODULE_ID_PE, msg);
+}
+
+QDF_STATUS lim_post_msg_high_priority(tpAniSirGlobal mac,
+				      struct scheduler_msg *msg)
+{
+	return scheduler_post_msg_by_priority(QDF_MODULE_ID_PE,
+					       msg, true);
+}
+
+QDF_STATUS pe_mc_process_handler(struct scheduler_msg *msg)
+{
+	tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (mac_ctx == NULL)
+		return QDF_STATUS_E_FAILURE;
+
+	if (ANI_DRIVER_TYPE(mac_ctx) == QDF_DRIVER_TYPE_MFG)
+		return QDF_STATUS_SUCCESS;
+
+	/*
+	 * If the Message to be handled is for CFG Module call the CFG Msg
+	 * Handler and for all the other cases post it to LIM
+	 */
+	if (SIR_CFG_PARAM_UPDATE_IND != msg->type && IS_CFG_MSG(msg->type))
+		cfg_process_mb_msg(mac_ctx, msg->bodyptr);
+	else
+		lim_message_processor(mac_ctx, msg);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * pe_drop_pending_rx_mgmt_frames: To drop pending RX mgmt frames
+ * @mac_ctx: Pointer to global MAC structure
+ * @hdr: Management header
+ * @cds_pkt: Packet
+ *
+ * This function is used to drop RX pending mgmt frames if pe mgmt queue
+ * reaches threshold
+ *
+ * Return: QDF_STATUS_SUCCESS on success or QDF_STATUS_E_FAILURE on failure
+ */
+static QDF_STATUS pe_drop_pending_rx_mgmt_frames(tpAniSirGlobal mac_ctx,
+				tpSirMacMgmtHdr hdr, cds_pkt_t *cds_pkt)
+{
+	qdf_spin_lock(&mac_ctx->sys.bbt_mgmt_lock);
+	if (mac_ctx->sys.sys_bbt_pending_mgmt_count >=
+	     MGMT_RX_PACKETS_THRESHOLD) {
+		qdf_spin_unlock(&mac_ctx->sys.bbt_mgmt_lock);
+		pe_debug("No.of pending RX management frames reaches to threshold, dropping management frames");
+		cds_pkt_return_packet(cds_pkt);
+		cds_pkt = NULL;
+		mac_ctx->rx_packet_drop_counter++;
+		return QDF_STATUS_E_FAILURE;
+	} else if (mac_ctx->sys.sys_bbt_pending_mgmt_count >
+		   (MGMT_RX_PACKETS_THRESHOLD / 2)) {
+		/* drop all probereq, proberesp and beacons */
+		if (hdr->fc.subType == SIR_MAC_MGMT_BEACON ||
+		    hdr->fc.subType == SIR_MAC_MGMT_PROBE_REQ ||
+		    hdr->fc.subType == SIR_MAC_MGMT_PROBE_RSP) {
+			qdf_spin_unlock(&mac_ctx->sys.bbt_mgmt_lock);
+			if (!(mac_ctx->rx_packet_drop_counter % 100))
+				pe_debug("No.of pending RX mgmt frames reaches 1/2 thresh, dropping frame subtype: %d rx_packet_drop_counter: %d",
+					hdr->fc.subType,
+					mac_ctx->rx_packet_drop_counter);
+			mac_ctx->rx_packet_drop_counter++;
+			cds_pkt_return_packet(cds_pkt);
+			cds_pkt = NULL;
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	mac_ctx->sys.sys_bbt_pending_mgmt_count++;
+	qdf_spin_unlock(&mac_ctx->sys.bbt_mgmt_lock);
+	if (mac_ctx->sys.sys_bbt_pending_mgmt_count ==
+	    (MGMT_RX_PACKETS_THRESHOLD / 4)) {
+		if (!(mac_ctx->rx_packet_drop_counter % 100))
+			pe_debug("No.of pending RX management frames reaches to 1/4th of threshold, rx_packet_drop_counter: %d",
+				mac_ctx->rx_packet_drop_counter);
+			mac_ctx->rx_packet_drop_counter++;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * pe_is_ext_scan_bcn - Check if the beacon is from Ext or EPNO scan
+ *
+ * @hdr: pointer to the 802.11 header of the frame
+ * @rx_pkt_info: pointer to the rx packet meta
+ *
+ * Checks if the beacon is from Ext Scan or EPNO scan
+ *
+ * Return: true or false
+ */
+#ifdef FEATURE_WLAN_EXTSCAN
+static inline bool pe_is_ext_scan_bcn(tpSirMacMgmtHdr hdr,
+				uint8_t *rx_pkt_info)
+{
+	if ((hdr->fc.subType == SIR_MAC_MGMT_BEACON) &&
+	    (WMA_IS_EXTSCAN_SCAN_SRC(rx_pkt_info) ||
+	    WMA_IS_EPNO_SCAN_SRC(rx_pkt_info)))
+		return true;
+
+	return false;
+}
+#else
+static inline bool pe_is_ext_scan_bcn(tpSirMacMgmtHdr hdr,
+				uint8_t *rx_pkt_info)
+{
+	return false;
+}
+#endif
+
+/**
+ * pe_filter_drop_bcn_probe_frame - Apply filter on the received frame
+ *
+ * @mac_ctx: pointer to the global mac context
+ * @hdr: pointer to the 802.11 header of the frame
+ * @rx_pkt_info: pointer to the rx packet meta
+ *
+ * Applies the filter from global mac context on the received beacon/
+ * probe response frame before posting it to the PE queue
+ *
+ * Return: true if frame is allowed, false if frame is to be dropped.
+ */
+static bool pe_filter_bcn_probe_frame(tpAniSirGlobal mac_ctx,
+					tpSirMacMgmtHdr hdr,
+					uint8_t *rx_pkt_info)
+{
+	uint8_t session_id;
+	uint8_t *body;
+	const uint8_t *ssid_ie;
+	uint16_t frame_len;
+	struct mgmt_beacon_probe_filter *filter;
+	tpSirMacCapabilityInfo bcn_caps;
+	tSirMacSSid bcn_ssid;
+
+	if (pe_is_ext_scan_bcn(hdr, rx_pkt_info))
+		return true;
+
+	filter = &mac_ctx->bcn_filter;
+
+	/*
+	 * If any STA session exists and beacon source matches any of the
+	 * STA BSSIDs, allow the frame
+	 */
+	if (filter->num_sta_sessions) {
+		for (session_id = 0; session_id < SIR_MAX_SUPPORTED_BSS;
+		     session_id++) {
+			if (sir_compare_mac_addr(filter->sta_bssid[session_id],
+			    hdr->bssId)) {
+				return true;
+			}
+		}
+	}
+
+	/*
+	 * If any IBSS session exists and beacon is has IBSS capability set
+	 * and SSID matches the IBSS SSID, allow the frame
+	 */
+	if (filter->num_ibss_sessions) {
+		body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+		frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+		if (frame_len < SIR_MAC_B_PR_SSID_OFFSET)
+			return false;
+
+		bcn_caps = (tpSirMacCapabilityInfo)
+				(body + SIR_MAC_B_PR_CAPAB_OFFSET);
+		if (!bcn_caps->ibss)
+			return false;
+
+		ssid_ie = wlan_get_ie_ptr_from_eid(SIR_MAC_SSID_EID,
+				body + SIR_MAC_B_PR_SSID_OFFSET,
+				frame_len);
+
+		if (!ssid_ie)
+			return false;
+
+		bcn_ssid.length = ssid_ie[1];
+		qdf_mem_copy(&bcn_ssid.ssId,
+			     &ssid_ie[2],
+			     bcn_ssid.length);
+
+		for (session_id = 0; session_id < SIR_MAX_SUPPORTED_BSS;
+		     session_id++) {
+			if (filter->ibss_ssid[session_id].length ==
+			    bcn_ssid.length &&
+			    (!qdf_mem_cmp(filter->ibss_ssid[session_id].ssId,
+			    bcn_ssid.ssId, bcn_ssid.length))) {
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+static QDF_STATUS pe_handle_probe_req_frames(tpAniSirGlobal mac_ctx,
+					cds_pkt_t *pkt)
+{
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+	uint32_t scan_queue_size = 0;
+
+	/* Check if the probe request frame can be posted in the scan queue */
+	status = scheduler_get_queue_size(QDF_MODULE_ID_SCAN, &scan_queue_size);
+	if (!QDF_IS_STATUS_SUCCESS(status) ||
+	    scan_queue_size > MAX_BCN_PROBE_IN_SCAN_QUEUE) {
+		pe_debug_rl("Dropping probe req frame, queue size %d",
+			    scan_queue_size);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Forward to MAC via mesg = SIR_BB_XPORT_MGMT_MSG */
+	msg.type = SIR_BB_XPORT_MGMT_MSG;
+	msg.bodyptr = pkt;
+	msg.bodyval = 0;
+	msg.callback = pe_mc_process_handler;
+
+	status = scheduler_post_message(QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_SCAN, &msg);
+
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		pe_err_rl("Failed to post probe req frame to Scan Queue");
+
+	return status;
+}
+
+/* --------------------------------------------------------------------------- */
+/**
+ * pe_handle_mgmt_frame() - Process the Management frames from TXRX
+ * @psoc: psoc context
+ * @peer: peer
+ * @buf: buffer
+ * @mgmt_rx_params; rx event params
+ * @frm_type: frame type
+ *
+ * This function handles the mgmt rx frame from mgmt txrx component and forms
+ * a cds packet and schedule it in controller thread for further processing.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+static QDF_STATUS pe_handle_mgmt_frame(struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_peer *peer, qdf_nbuf_t buf,
+			struct mgmt_rx_event_params *mgmt_rx_params,
+			uint32_t frm_type)
+{
+	tpAniSirGlobal pMac;
+	tpSirMacMgmtHdr mHdr;
+	struct scheduler_msg msg = {0};
+	cds_pkt_t *pVosPkt;
+	QDF_STATUS qdf_status;
+	uint8_t *pRxPacketInfo;
+	int ret;
+
+	pMac = cds_get_context(QDF_MODULE_ID_PE);
+	if (NULL == pMac) {
+		/* cannot log a failure without a valid pMac */
+		qdf_nbuf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pVosPkt = qdf_mem_malloc(sizeof(*pVosPkt));
+	if (!pVosPkt) {
+		qdf_nbuf_free(buf);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	ret = wma_form_rx_packet(buf, mgmt_rx_params, pVosPkt);
+	if (ret) {
+		pe_err_rl("Failed to fill cds packet from event buffer");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_status =
+		wma_ds_peek_rx_packet_info(pVosPkt, (void *)&pRxPacketInfo, false);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_pkt_return_packet(pVosPkt);
+		pVosPkt = NULL;
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * The MPDU header is now present at a certain "offset" in
+	 * the BD and is specified in the BD itself
+	 */
+
+	mHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+	/*
+	 * Filter the beacon/probe response frames before posting it
+	 * on the PE queue
+	 */
+	if ((mHdr->fc.subType == SIR_MAC_MGMT_BEACON ||
+	    mHdr->fc.subType == SIR_MAC_MGMT_PROBE_RSP) &&
+	    !pe_filter_bcn_probe_frame(pMac, mHdr, pRxPacketInfo)) {
+		cds_pkt_return_packet(pVosPkt);
+		pVosPkt = NULL;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/*
+	 * Post Probe Req frames to Scan queue and return
+	 */
+	if (mHdr->fc.subType == SIR_MAC_MGMT_PROBE_REQ) {
+		qdf_status = pe_handle_probe_req_frames(pMac, pVosPkt);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			cds_pkt_return_packet(pVosPkt);
+			pVosPkt = NULL;
+		}
+		return qdf_status;
+	}
+
+	if (QDF_STATUS_SUCCESS !=
+	    pe_drop_pending_rx_mgmt_frames(pMac, mHdr, pVosPkt))
+		return QDF_STATUS_E_FAILURE;
+
+	/* Forward to MAC via mesg = SIR_BB_XPORT_MGMT_MSG */
+	msg.type = SIR_BB_XPORT_MGMT_MSG;
+	msg.bodyptr = pVosPkt;
+	msg.bodyval = 0;
+
+	if (QDF_STATUS_SUCCESS != sys_bbt_process_message_core(pMac,
+							 &msg,
+							 mHdr->fc.type,
+							 mHdr->fc.subType)) {
+		cds_pkt_return_packet(pVosPkt);
+		pVosPkt = NULL;
+		/*
+		 * Decrement sys_bbt_pending_mgmt_count if packet
+		 * is dropped before posting to LIM
+		 */
+		lim_decrement_pending_mgmt_count(pMac);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void pe_register_mgmt_rx_frm_callback(tpAniSirGlobal mac_ctx)
+{
+	QDF_STATUS status;
+	struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info;
+
+	frm_cb_info.frm_type = MGMT_FRAME_TYPE_ALL;
+	frm_cb_info.mgmt_rx_cb = (mgmt_frame_rx_callback)
+				pe_handle_mgmt_frame;
+
+	status = wlan_mgmt_txrx_register_rx_cb(mac_ctx->psoc,
+					 WLAN_UMAC_COMP_MLME, &frm_cb_info, 1);
+	if (status != QDF_STATUS_SUCCESS)
+		pe_err("Registering the PE Handle with MGMT TXRX layer has failed");
+
+	wma_register_mgmt_frm_client();
+}
+
+void pe_deregister_mgmt_rx_frm_callback(tpAniSirGlobal mac_ctx)
+{
+	QDF_STATUS status;
+	struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info;
+
+	frm_cb_info.frm_type = MGMT_FRAME_TYPE_ALL;
+	frm_cb_info.mgmt_rx_cb = (mgmt_frame_rx_callback)
+				pe_handle_mgmt_frame;
+
+	status = wlan_mgmt_txrx_deregister_rx_cb(mac_ctx->psoc,
+					 WLAN_UMAC_COMP_MLME, &frm_cb_info, 1);
+	if (status != QDF_STATUS_SUCCESS)
+		pe_err("Deregistering the PE Handle with MGMT TXRX layer has failed");
+
+	wma_de_register_mgmt_frm_client();
+}
+
+
+/**
+ * pe_register_callbacks_with_wma() - register SME and PE callback functions to
+ * WMA.
+ * (function documentation in lim_api.h)
+ */
+void pe_register_callbacks_with_wma(tpAniSirGlobal pMac,
+				    tSirSmeReadyReq *ready_req)
+{
+	QDF_STATUS status;
+
+	status = wma_register_roaming_callbacks(
+			ready_req->csr_roam_synch_cb,
+			ready_req->pe_roam_synch_cb);
+	if (status != QDF_STATUS_SUCCESS)
+		pe_err("Registering roaming callbacks with WMA failed");
+}
+
+/**
+ * lim_is_system_in_scan_state()
+ *
+ ***FUNCTION:
+ * This function is called by various MAC software modules to
+ * determine if System is in Scan/Learn state
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param  pMac  - Pointer to Global MAC structure
+ * @return true  - System is in Scan/Learn state
+ *         false - System is NOT in Scan/Learn state
+ */
+
+uint8_t lim_is_system_in_scan_state(tpAniSirGlobal pMac)
+{
+	switch (pMac->lim.gLimSmeState) {
+	case eLIM_SME_CHANNEL_SCAN_STATE:
+	case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE:
+	case eLIM_SME_LINK_EST_WT_SCAN_STATE:
+	case eLIM_SME_WT_SCAN_STATE:
+		/* System is in Learn mode */
+		return true;
+
+	default:
+		/* System is NOT in Learn mode */
+		return false;
+	}
+} /*** end lim_is_system_in_scan_state() ***/
+
+/**
+ *\brief lim_received_hb_handler()
+ *
+ * This function is called by sch_beacon_process() upon
+ * receiving a Beacon on STA. This also gets called upon
+ * receiving Probe Response after heat beat failure is
+ * detected.
+ *
+ * param pMac - global mac structure
+ * param channel - channel number indicated in Beacon, Probe Response
+ * return - none
+ */
+
+void
+lim_received_hb_handler(tpAniSirGlobal pMac, uint8_t channelId,
+			tpPESession psessionEntry)
+{
+	if ((channelId == 0)
+	    || (channelId == psessionEntry->currentOperChannel))
+		psessionEntry->LimRxedBeaconCntDuringHB++;
+
+	psessionEntry->pmmOffloadInfo.bcnmiss = false;
+} /*** lim_init_wds_info_params() ***/
+
+/** -------------------------------------------------------------
+   \fn lim_update_overlap_sta_param
+   \brief Updates overlap cache and param data structure
+   \param      tpAniSirGlobal    pMac
+   \param      tSirMacAddr bssId
+   \param      tpLimProtStaParams pStaParams
+   \return      None
+   -------------------------------------------------------------*/
+void
+lim_update_overlap_sta_param(tpAniSirGlobal pMac, tSirMacAddr bssId,
+			     tpLimProtStaParams pStaParams)
+{
+	int i;
+
+	if (!pStaParams->numSta) {
+		qdf_mem_copy(pMac->lim.protStaOverlapCache[0].addr,
+			     bssId, sizeof(tSirMacAddr));
+		pMac->lim.protStaOverlapCache[0].active = true;
+
+		pStaParams->numSta = 1;
+
+		return;
+	}
+
+	for (i = 0; i < LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++) {
+		if (pMac->lim.protStaOverlapCache[i].active) {
+			if (!qdf_mem_cmp
+				    (pMac->lim.protStaOverlapCache[i].addr, bssId,
+				    sizeof(tSirMacAddr))) {
+				return;
+			}
+		} else
+			break;
+	}
+
+	if (i == LIM_PROT_STA_OVERLAP_CACHE_SIZE) {
+		pe_debug("Overlap cache is full");
+	} else {
+		qdf_mem_copy(pMac->lim.protStaOverlapCache[i].addr,
+			     bssId, sizeof(tSirMacAddr));
+		pMac->lim.protStaOverlapCache[i].active = true;
+
+		pStaParams->numSta++;
+	}
+}
+
+/**
+ * lim_ibss_enc_type_matched
+ *
+ ***FUNCTION:
+ * This function compares the encryption type of the peer with self
+ * while operating in IBSS mode and detects mismatch.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pBeacon  - Parsed Beacon Frame structure
+ * @param  pSession - Pointer to the PE session
+ *
+ * @return true if encryption type is matched; false otherwise
+ */
+static bool lim_ibss_enc_type_matched(tpSchBeaconStruct pBeacon,
+					  tpPESession pSession)
+{
+	if (!pBeacon || !pSession)
+		return false;
+
+	/* Open case */
+	if (pBeacon->capabilityInfo.privacy == 0
+	    && pSession->encryptType == eSIR_ED_NONE)
+		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 true;
+
+	/* WPA-None case */
+	if (pBeacon->capabilityInfo.privacy == 1 && pBeacon->wpaPresent == 1
+	    && pBeacon->rsnPresent == 0
+	    && ((pSession->encryptType == eSIR_ED_CCMP) ||
+		(pSession->encryptType == eSIR_ED_GCMP) ||
+		(pSession->encryptType == eSIR_ED_GCMP_256) ||
+		(pSession->encryptType == eSIR_ED_TKIP)))
+		return true;
+
+	return false;
+}
+
+/**
+ * lim_handle_ibs_scoalescing()
+ *
+ ***FUNCTION:
+ * This function is called upon receiving Beacon/Probe Response
+ * while operating in IBSS mode.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ * @param  pBeacon - Parsed Beacon Frame structure
+ * @param  pRxPacketInfo - Pointer to RX packet info structure
+ *
+ * @return Status whether to process or ignore received Beacon Frame
+ */
+
+QDF_STATUS
+lim_handle_ibss_coalescing(tpAniSirGlobal pMac,
+			   tpSchBeaconStruct pBeacon,
+			   uint8_t *pRxPacketInfo, tpPESession psessionEntry)
+{
+	tpSirMacMgmtHdr pHdr;
+	QDF_STATUS retCode;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+	/* Ignore the beacon when any of the conditions below is met:
+	   1. The beacon claims no IBSS network
+	   2. SSID in the beacon does not match SSID of self station
+	   3. Operational channel in the beacon does not match self station
+	   4. Encyption type in the beacon does not match with self station
+	 */
+	if ((!pBeacon->capabilityInfo.ibss) ||
+	    lim_cmp_ssid(&pBeacon->ssId, psessionEntry) ||
+	    (psessionEntry->currentOperChannel != pBeacon->channelNumber))
+		retCode = QDF_STATUS_E_INVAL;
+	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,
+			       psessionEntry->encryptType);
+		retCode = QDF_STATUS_E_INVAL;
+	} else {
+		uint32_t ieLen;
+		uint16_t tsfLater;
+		uint8_t *pIEs;
+
+		ieLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+		tsfLater = WMA_GET_RX_TSF_LATER(pRxPacketInfo);
+		pIEs = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+		pe_debug("BEFORE Coalescing tsfLater val: %d", tsfLater);
+		retCode =
+			lim_ibss_coalesce(pMac, pHdr, pBeacon, pIEs, ieLen, tsfLater,
+					  psessionEntry);
+	}
+	return retCode;
+} /*** end lim_handle_ibs_scoalescing() ***/
+
+/**
+ * lim_enc_type_matched() - matches security type of incoming beracon with
+ * current
+ * @mac_ctx      Pointer to Global MAC structure
+ * @bcn          Pointer to parsed Beacon structure
+ * @session      PE session entry
+ *
+ * This function matches security type of incoming beracon with current
+ *
+ * @return true if matched, false otherwise
+ */
+static bool
+lim_enc_type_matched(tpAniSirGlobal mac_ctx,
+		     tpSchBeaconStruct bcn,
+		     tpPESession session)
+{
+	if (!bcn || !session)
+		return false;
+
+	pe_debug("Beacon/Probe:: Privacy: %d WPA Present: %d RSN Present: %d",
+		bcn->capabilityInfo.privacy, bcn->wpaPresent, bcn->rsnPresent);
+	pe_debug("session:: Privacy: %d EncyptionType: %d OSEN: %d WPS: %d",
+		SIR_MAC_GET_PRIVACY(session->limCurrentBssCaps),
+		session->encryptType, session->isOSENConnection,
+		session->wps_registration);
+
+	/*
+	 * This is handled by sending probe req due to IOT issues so
+	 * return TRUE
+	 */
+	if ((bcn->capabilityInfo.privacy) !=
+		SIR_MAC_GET_PRIVACY(session->limCurrentBssCaps)) {
+		pe_warn("Privacy bit miss match");
+		return true;
+	}
+
+	/* Open */
+	if ((bcn->capabilityInfo.privacy == 0) &&
+	    (session->encryptType == eSIR_ED_NONE))
+		return true;
+
+	/* WEP */
+	if ((bcn->capabilityInfo.privacy == 1) &&
+	    (bcn->wpaPresent == 0) && (bcn->rsnPresent == 0) &&
+	    ((session->encryptType == eSIR_ED_WEP40) ||
+		(session->encryptType == eSIR_ED_WEP104)
+#ifdef FEATURE_WLAN_WAPI
+		|| (session->encryptType == eSIR_ED_WPI)
+#endif
+	    ))
+		return true;
+
+	/* WPA OR RSN*/
+	if ((bcn->capabilityInfo.privacy == 1) &&
+	    ((bcn->wpaPresent == 1) || (bcn->rsnPresent == 1)) &&
+	    ((session->encryptType == eSIR_ED_TKIP) ||
+		(session->encryptType == eSIR_ED_CCMP) ||
+		(session->encryptType == eSIR_ED_GCMP) ||
+		(session->encryptType == eSIR_ED_GCMP_256) ||
+		(session->encryptType == eSIR_ED_AES_128_CMAC)))
+		return true;
+
+	/*
+	 * For HS2.0, RSN ie is not present
+	 * in beacon. Therefore no need to
+	 * check for security type in case
+	 * OSEN session.
+	 * For WPS registration session no need to detect
+	 * detect security mismatch as it wont match and
+	 * driver may end up sending probe request without
+	 * WPS IE during WPS registration process.
+	 */
+	if (session->isOSENConnection ||
+	   session->wps_registration)
+		return true;
+
+	return false;
+}
+
+/**
+ * lim_detect_change_in_ap_capabilities()
+ *
+ ***FUNCTION:
+ * This function is called while SCH is processing
+ * received Beacon from AP on STA to detect any
+ * change in AP's capabilities. If there any change
+ * is detected, Roaming is informed of such change
+ * so that it can trigger reassociation.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * Notification is enabled for STA product only since
+ * it is not a requirement on BP side.
+ *
+ * @param  pMac      Pointer to Global MAC structure
+ * @param  pBeacon   Pointer to parsed Beacon structure
+ * @return None
+ */
+
+void
+lim_detect_change_in_ap_capabilities(tpAniSirGlobal pMac,
+				     tpSirProbeRespBeacon pBeacon,
+				     tpPESession psessionEntry)
+{
+	uint8_t len;
+	tSirSmeApNewCaps apNewCaps;
+	uint8_t newChannel;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	bool security_caps_matched = true;
+
+	apNewCaps.capabilityInfo =
+		lim_get_u16((uint8_t *) &pBeacon->capabilityInfo);
+	newChannel = (uint8_t) pBeacon->channelNumber;
+
+	security_caps_matched = lim_enc_type_matched(pMac, pBeacon,
+						     psessionEntry);
+	if ((false == psessionEntry->limSentCapsChangeNtf) &&
+	    (((!lim_is_null_ssid(&pBeacon->ssId)) &&
+	       lim_cmp_ssid(&pBeacon->ssId, psessionEntry)) ||
+	     ((SIR_MAC_GET_ESS(apNewCaps.capabilityInfo) !=
+	       SIR_MAC_GET_ESS(psessionEntry->limCurrentBssCaps)) ||
+	      (SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) !=
+	       SIR_MAC_GET_PRIVACY(psessionEntry->limCurrentBssCaps)) ||
+	      (SIR_MAC_GET_SHORT_PREAMBLE(apNewCaps.capabilityInfo) !=
+	       SIR_MAC_GET_SHORT_PREAMBLE(psessionEntry->limCurrentBssCaps)) ||
+	      (SIR_MAC_GET_QOS(apNewCaps.capabilityInfo) !=
+	       SIR_MAC_GET_QOS(psessionEntry->limCurrentBssCaps)) ||
+	      ((newChannel != psessionEntry->currentOperChannel) &&
+		(newChannel != 0)) ||
+	      (false == security_caps_matched)
+	     ))) {
+		if (false == psessionEntry->fWaitForProbeRsp) {
+			/* If Beacon capabilities is not matching with the current capability,
+			 * then send unicast probe request to AP and take decision after
+			 * receiving probe response */
+			if (true == psessionEntry->fIgnoreCapsChange) {
+				pe_debug("Ignoring the Capability change as it is false alarm");
+				return;
+			}
+			psessionEntry->fWaitForProbeRsp = true;
+			pe_warn("AP capabilities are not matching, sending directed probe request");
+			status =
+				lim_send_probe_req_mgmt_frame(pMac, &psessionEntry->ssId,
+					      psessionEntry->bssId,
+					      psessionEntry->currentOperChannel,
+					      psessionEntry->selfMacAddr,
+					      psessionEntry->dot11mode,
+					      NULL, NULL);
+
+			if (QDF_STATUS_SUCCESS != status) {
+				pe_err("send ProbeReq failed");
+				psessionEntry->fWaitForProbeRsp = false;
+			}
+			return;
+		}
+		/**
+		 * BSS capabilities have changed.
+		 * Inform Roaming.
+		 */
+		len = sizeof(tSirMacCapabilityInfo) + sizeof(tSirMacAddr) + sizeof(uint8_t) + 3 * sizeof(uint8_t) + /* reserved fields */
+		      pBeacon->ssId.length + 1;
+
+		qdf_mem_copy(apNewCaps.bssId.bytes,
+			     psessionEntry->bssId, QDF_MAC_ADDR_SIZE);
+		if (newChannel != psessionEntry->currentOperChannel) {
+			pe_err("Channel Change from %d --> %d Ignoring beacon!",
+				psessionEntry->currentOperChannel, newChannel);
+			return;
+		}
+
+		/**
+		 * When Cisco 1262 Enterprise APs are configured with WPA2-PSK with
+		 * AES+TKIP Pairwise ciphers and WEP-40 Group cipher, they do not set
+		 * the privacy bit in Beacons (wpa/rsnie is still present in beacons),
+		 * the privacy bit is set in Probe and association responses.
+		 * Due to this anomaly, we detect a change in
+		 * AP capabilities when we receive a beacon after association and
+		 * disconnect from the AP. The following check makes sure that we can
+		 * connect to such APs
+		 */
+		else if ((SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) == 0) &&
+			 (pBeacon->rsnPresent || pBeacon->wpaPresent)) {
+			pe_err("BSS Caps (Privacy) bit 0 in beacon, but WPA or RSN IE present, Ignore Beacon!");
+			return;
+		} else
+			apNewCaps.channelId = psessionEntry->currentOperChannel;
+		qdf_mem_copy((uint8_t *) &apNewCaps.ssId,
+			     (uint8_t *) &pBeacon->ssId,
+			     pBeacon->ssId.length + 1);
+
+		psessionEntry->fIgnoreCapsChange = false;
+		psessionEntry->fWaitForProbeRsp = false;
+		psessionEntry->limSentCapsChangeNtf = true;
+		lim_send_sme_wm_status_change_ntf(pMac, eSIR_SME_AP_CAPS_CHANGED,
+						  (uint32_t *) &apNewCaps,
+						  len, psessionEntry->smeSessionId);
+	} else if (true == psessionEntry->fWaitForProbeRsp) {
+		/* Only for probe response frames and matching capabilities the control
+		 * will come here. If beacon is with broadcast ssid then fWaitForProbeRsp
+		 * will be false, the control will not come here*/
+
+		pe_debug("capabilities in probe response are"
+				       "matching with the current setting,"
+				       "Ignoring subsequent capability"
+				       "mismatch");
+		psessionEntry->fIgnoreCapsChange = true;
+		psessionEntry->fWaitForProbeRsp = false;
+	}
+
+} /*** lim_detect_change_in_ap_capabilities() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * lim_update_short_slot
+ *
+ * FUNCTION:
+ * Enable/Disable short slot
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param enable        Flag to enable/disable short slot
+ * @return None
+ */
+
+QDF_STATUS lim_update_short_slot(tpAniSirGlobal pMac,
+				    tpSirProbeRespBeacon pBeacon,
+				    tpUpdateBeaconParams pBeaconParams,
+				    tpPESession psessionEntry)
+{
+
+	tSirSmeApNewCaps apNewCaps;
+	uint32_t nShortSlot;
+	uint32_t phyMode;
+
+	/* Check Admin mode first. If it is disabled just return */
+	if (!pMac->mlme_cfg->feature_flags.enable_short_slot_time_11g)
+		return QDF_STATUS_SUCCESS;
+
+	/* Check for 11a mode or 11b mode. In both cases return since slot time is constant and cannot/should not change in beacon */
+	lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+	if ((phyMode == WNI_CFG_PHY_MODE_11A)
+	    || (phyMode == WNI_CFG_PHY_MODE_11B))
+		return QDF_STATUS_SUCCESS;
+
+	apNewCaps.capabilityInfo =
+		lim_get_u16((uint8_t *) &pBeacon->capabilityInfo);
+
+	/*  Earlier implementation: determine the appropriate short slot mode based on AP advertised modes */
+	/* when erp is present, apply short slot always unless, prot=on  && shortSlot=off */
+	/* if no erp present, use short slot based on current ap caps */
+
+	/* Issue with earlier implementation : Cisco 1231 BG has shortSlot = 0, erpIEPresent and useProtection = 0 (Case4); */
+
+	/* Resolution : always use the shortSlot setting the capability info to decide slot time. */
+	/* The difference between the earlier implementation and the new one is only Case4. */
+	/*
+	   ERP IE Present  |   useProtection   |   shortSlot   =   QC STA Short Slot
+	   Case1        1                                   1                       1                       1           //AP should not advertise this combination.
+	   Case2        1                                   1                       0                       0
+	   Case3        1                                   0                       1                       1
+	   Case4        1                                   0                       0                       0
+	   Case5        0                                   1                       1                       1
+	   Case6        0                                   1                       0                       0
+	   Case7        0                                   0                       1                       1
+	   Case8        0                                   0                       0                       0
+	 */
+	nShortSlot = SIR_MAC_GET_SHORT_SLOT_TIME(apNewCaps.capabilityInfo);
+
+	if (nShortSlot != psessionEntry->shortSlotTimeSupported) {
+		/* Short slot time capability of AP has changed. Adopt to it. */
+		pe_debug("Shortslot capability of AP changed: %d",
+			       nShortSlot);
+			((tpSirMacCapabilityInfo) & psessionEntry->
+			limCurrentBssCaps)->shortSlotTime = (uint16_t) nShortSlot;
+		psessionEntry->shortSlotTimeSupported = nShortSlot;
+		pBeaconParams->fShortSlotTime = (uint8_t) nShortSlot;
+		pBeaconParams->paramChangeBitmap |=
+			PARAM_SHORT_SLOT_TIME_CHANGED;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+
+void lim_send_heart_beat_timeout_ind(tpAniSirGlobal pMac,
+				     tpPESession psessionEntry)
+{
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+
+	/* Prepare and post message to LIM Message Queue */
+	msg.type = (uint16_t) SIR_LIM_HEART_BEAT_TIMEOUT;
+	msg.bodyptr = psessionEntry;
+	msg.bodyval = 0;
+	pe_err("Heartbeat failure from Fw");
+
+	status = lim_post_msg_api(pMac, &msg);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		pe_err("posting message: %X to LIM failed, reason: %d",
+			msg.type, status);
+	}
+}
+
+/**
+ * lim_ps_offload_handle_missed_beacon_ind(): handles missed beacon indication
+ * @pMac : global mac context
+ * @pMsg: message
+ *
+ * This function process the SIR_HAL_MISSED_BEACON_IND
+ * message from HAL, to do active AP probing.
+ *
+ * Return: void
+ */
+void lim_ps_offload_handle_missed_beacon_ind(tpAniSirGlobal pMac,
+					     struct scheduler_msg *pMsg)
+{
+	tpSirSmeMissedBeaconInd pSirMissedBeaconInd =
+		(tpSirSmeMissedBeaconInd) pMsg->bodyptr;
+	tpPESession psessionEntry =
+		pe_find_session_by_bss_idx(pMac, pSirMissedBeaconInd->bssIdx);
+
+	if (!psessionEntry) {
+		pe_err("session does not exist for given BSSId");
+		return;
+	}
+
+	/* Set Beacon Miss in Powersave Offload */
+	psessionEntry->pmmOffloadInfo.bcnmiss = true;
+	pe_err("Received Heart Beat Failure");
+
+	/*  Do AP probing immediately */
+	lim_send_heart_beat_timeout_ind(pMac, psessionEntry);
+	return;
+}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * lim_fill_join_rsp_ht_caps() - Fill the HT caps in join response
+ * @session: PE Session
+ * @join_rsp: Join response buffer to be filled up.
+ *
+ * Return: None
+ */
+void lim_fill_join_rsp_ht_caps(tpPESession session, tpSirSmeJoinRsp join_rsp)
+{
+	tSirSmeHTProfile *ht_profile;
+
+	if (session == NULL) {
+		pe_err("Invalid Session");
+		return;
+	}
+	if (join_rsp == NULL) {
+		pe_err("Invalid Join Response");
+		return;
+	}
+
+	if (session->cc_switch_mode == QDF_MCC_TO_SCC_SWITCH_DISABLE)
+		return;
+
+	ht_profile = &join_rsp->HTProfile;
+	ht_profile->htSupportedChannelWidthSet =
+		session->htSupportedChannelWidthSet;
+	ht_profile->htRecommendedTxWidthSet =
+		session->htRecommendedTxWidthSet;
+	ht_profile->htSecondaryChannelOffset =
+		session->htSecondaryChannelOffset;
+	ht_profile->dot11mode = session->dot11mode;
+	ht_profile->htCapability = session->htCapability;
+	ht_profile->vhtCapability = session->vhtCapability;
+	ht_profile->apCenterChan = session->ch_center_freq_seg0;
+	ht_profile->apChanWidth = session->ch_width;
+}
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * sir_parse_bcn_fixed_fields() - Parse fixed fields in Beacon IE's
+ *
+ * @mac_ctx: MAC Context
+ * @beacon_struct: Beacon/Probe Response structure
+ * @buf: Fixed Fields buffer
+ */
+static void sir_parse_bcn_fixed_fields(tpAniSirGlobal mac_ctx,
+					tpSirProbeRespBeacon beacon_struct,
+					uint8_t *buf)
+{
+	tDot11fFfCapabilities dst;
+
+	beacon_struct->timeStamp[0] = lim_get_u32(buf);
+	beacon_struct->timeStamp[1] = lim_get_u32(buf + 4);
+	buf += 8;
+
+	beacon_struct->beaconInterval = lim_get_u16(buf);
+	buf += 2;
+
+	dot11f_unpack_ff_capabilities(mac_ctx, buf, &dst);
+
+	sir_copy_caps_info(mac_ctx, dst, beacon_struct);
+}
+
+static QDF_STATUS
+lim_roam_fill_bss_descr(tpAniSirGlobal pMac,
+			roam_offload_synch_ind *roam_offload_synch_ind_ptr,
+			tpSirBssDescription  bss_desc_ptr)
+{
+	uint32_t ie_len = 0;
+	tpSirProbeRespBeacon parsed_frm_ptr;
+	tpSirMacMgmtHdr mac_hdr;
+	uint8_t *bcn_proberesp_ptr;
+
+	bcn_proberesp_ptr = (uint8_t *)roam_offload_synch_ind_ptr +
+		roam_offload_synch_ind_ptr->beaconProbeRespOffset;
+	mac_hdr = (tpSirMacMgmtHdr)bcn_proberesp_ptr;
+	parsed_frm_ptr = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
+	if (!parsed_frm_ptr)
+		return QDF_STATUS_E_NOMEM;
+
+	if (roam_offload_synch_ind_ptr->beaconProbeRespLength <=
+			SIR_MAC_HDR_LEN_3A) {
+		pe_err("%s: very few bytes in synchInd beacon / probe resp frame! length: %d",
+		__func__, roam_offload_synch_ind_ptr->beaconProbeRespLength);
+		qdf_mem_free(parsed_frm_ptr);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pe_debug("LFR3:Beacon/Prb Rsp: %d", roam_offload_synch_ind_ptr->isBeacon);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+	bcn_proberesp_ptr, roam_offload_synch_ind_ptr->beaconProbeRespLength);
+	if (roam_offload_synch_ind_ptr->isBeacon) {
+		if (sir_parse_beacon_ie(pMac, parsed_frm_ptr,
+			&bcn_proberesp_ptr[SIR_MAC_HDR_LEN_3A +
+			SIR_MAC_B_PR_SSID_OFFSET],
+			roam_offload_synch_ind_ptr->beaconProbeRespLength -
+			SIR_MAC_HDR_LEN_3A) != QDF_STATUS_SUCCESS ||
+			!parsed_frm_ptr->ssidPresent) {
+			pe_err("Parse error Beacon, length: %d",
+			roam_offload_synch_ind_ptr->beaconProbeRespLength);
+			qdf_mem_free(parsed_frm_ptr);
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		if (sir_convert_probe_frame2_struct(pMac,
+			&bcn_proberesp_ptr[SIR_MAC_HDR_LEN_3A],
+			roam_offload_synch_ind_ptr->beaconProbeRespLength -
+			SIR_MAC_HDR_LEN_3A, parsed_frm_ptr) != QDF_STATUS_SUCCESS ||
+			!parsed_frm_ptr->ssidPresent) {
+			pe_err("Parse error ProbeResponse, length: %d",
+			roam_offload_synch_ind_ptr->beaconProbeRespLength);
+			qdf_mem_free(parsed_frm_ptr);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	/*
+	 * For probe response, unpack core parses beacon interval, capabilities,
+	 * timestamp. For beacon IEs, these fields are not parsed.
+	 */
+	if (roam_offload_synch_ind_ptr->isBeacon)
+		sir_parse_bcn_fixed_fields(pMac, parsed_frm_ptr,
+			&bcn_proberesp_ptr[SIR_MAC_HDR_LEN_3A]);
+
+	/* 24 byte MAC header and 12 byte to ssid IE */
+	if (roam_offload_synch_ind_ptr->beaconProbeRespLength >
+		(SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET)) {
+		ie_len = roam_offload_synch_ind_ptr->beaconProbeRespLength -
+			(SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
+	}
+	/*
+	 * Length of BSS desription is without length of
+	 * length itself and length of pointer
+	 * that holds ieFields
+	 *
+	 * tSirBssDescription
+	 * +--------+---------------------------------+---------------+
+	 * | length | other fields                    | pointer to IEs|
+	 * +--------+---------------------------------+---------------+
+	 *                                            ^
+	 *                                            ieFields
+	 */
+	bss_desc_ptr->length = (uint16_t) (offsetof(tSirBssDescription,
+					   ieFields[0]) -
+				sizeof(bss_desc_ptr->length) + ie_len);
+
+	bss_desc_ptr->fProbeRsp = !roam_offload_synch_ind_ptr->isBeacon;
+	/* Copy Timestamp */
+	bss_desc_ptr->scansystimensec = qdf_get_monotonic_boottime_ns();
+	if (parsed_frm_ptr->dsParamsPresent) {
+		bss_desc_ptr->channelId = parsed_frm_ptr->channelNumber;
+	} else if (parsed_frm_ptr->HTInfo.present) {
+		bss_desc_ptr->channelId = parsed_frm_ptr->HTInfo.primaryChannel;
+	} else {
+		/*
+		 * If DS Params or HTIE is not present in the probe resp or
+		 * beacon, then use the channel frequency provided by firmware
+		 * to fill the channel in the BSS descriptor.*/
+		bss_desc_ptr->channelId =
+			cds_freq_to_chan(roam_offload_synch_ind_ptr->chan_freq);
+	}
+	bss_desc_ptr->channelIdSelf = bss_desc_ptr->channelId;
+
+	bss_desc_ptr->nwType = lim_get_nw_type(pMac, bss_desc_ptr->channelId,
+					       SIR_MAC_MGMT_FRAME,
+					       parsed_frm_ptr);
+
+	bss_desc_ptr->sinr = 0;
+	bss_desc_ptr->beaconInterval = parsed_frm_ptr->beaconInterval;
+	bss_desc_ptr->timeStamp[0]   = parsed_frm_ptr->timeStamp[0];
+	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));
+	bss_desc_ptr->received_time =
+		      (uint64_t)qdf_mc_timer_get_system_time();
+	if (parsed_frm_ptr->mdiePresent) {
+		bss_desc_ptr->mdiePresent = parsed_frm_ptr->mdiePresent;
+		qdf_mem_copy((uint8_t *)bss_desc_ptr->mdie,
+				(uint8_t *)parsed_frm_ptr->mdie,
+				SIR_MDIE_SIZE);
+	}
+	pe_debug("LFR3: BssDescr Info:");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			bss_desc_ptr->bssId, sizeof(tSirMacAddr));
+	pe_debug("chan: %d rssi: %d", bss_desc_ptr->channelId,
+			bss_desc_ptr->rssi);
+	if (ie_len) {
+		qdf_mem_copy(&bss_desc_ptr->ieFields,
+			bcn_proberesp_ptr +
+			(SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET),
+			ie_len);
+	}
+	qdf_mem_free(parsed_frm_ptr);
+	return QDF_STATUS_SUCCESS;
+}
+
+#if defined(WLAN_FEATURE_FILS_SK)
+/**
+ * lim_copy_and_free_hlp_data_from_session - Copy HLP info
+ * @session_ptr: PE session
+ * @roam_sync_ind_ptr: Roam Synch Indication pointer
+ *
+ * This API is used to copy the parsed HLP info from PE session
+ * to roam synch indication data. THe HLP info is expected to be
+ * parsed/stored in PE session already from assoc IE's received
+ * from fw as part of Roam Synch Indication.
+ *
+ * Return: None
+ */
+static void lim_copy_and_free_hlp_data_from_session(tpPESession session_ptr,
+				    roam_offload_synch_ind *roam_sync_ind_ptr)
+{
+	if (session_ptr->hlp_data && session_ptr->hlp_data_len) {
+		cds_copy_hlp_info(&session_ptr->dst_mac,
+				&session_ptr->src_mac,
+				session_ptr->hlp_data_len,
+				session_ptr->hlp_data,
+				&roam_sync_ind_ptr->dst_mac,
+				&roam_sync_ind_ptr->src_mac,
+				&roam_sync_ind_ptr->hlp_data_len,
+				roam_sync_ind_ptr->hlp_data);
+		qdf_mem_free(session_ptr->hlp_data);
+		session_ptr->hlp_data = NULL;
+		session_ptr->hlp_data_len = 0;
+	}
+}
+#else
+static inline void lim_copy_and_free_hlp_data_from_session(
+					tpPESession session_ptr,
+					roam_offload_synch_ind
+					*roam_sync_ind_ptr)
+{}
+#endif
+
+/**
+ * pe_roam_synch_callback() - PE level callback for roam synch propagation
+ * @mac_ctx: MAC Context
+ * @roam_sync_ind_ptr: Roam synch indication buffer pointer
+ * @bss_desc: BSS Descriptor pointer
+ * @reason: Reason for calling callback which decides the action to be taken.
+ *
+ * This is a PE level callback called from WMA to complete the roam synch
+ * propagation at PE level and also fill the BSS descriptor which will be
+ * helpful further to complete the roam synch propagation.
+ *
+ * Return: Success or Failure status
+ */
+QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx,
+	roam_offload_synch_ind *roam_sync_ind_ptr,
+	tpSirBssDescription  bss_desc, enum sir_roam_op_code reason)
+{
+	tpPESession session_ptr;
+	tpPESession ft_session_ptr;
+	uint8_t session_id;
+	tpDphHashNode curr_sta_ds;
+	uint16_t aid;
+	tpAddBssParams add_bss_params;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint16_t join_rsp_len;
+
+	if (!roam_sync_ind_ptr) {
+		pe_err("LFR3:roam_sync_ind_ptr is NULL");
+		return status;
+	}
+	session_ptr = pe_find_session_by_sme_session_id(mac_ctx,
+				roam_sync_ind_ptr->roamedVdevId);
+	if (session_ptr == NULL) {
+		pe_err("LFR3:Unable to find session");
+		return status;
+	}
+
+	if (!LIM_IS_STA_ROLE(session_ptr)) {
+		pe_err("LFR3:session is not in STA mode");
+		return status;
+	}
+
+	pe_debug("LFR3: PE callback reason: %d", reason);
+	switch (reason) {
+	case SIR_ROAMING_START:
+		session_ptr->fw_roaming_started = true;
+		return QDF_STATUS_SUCCESS;
+	case SIR_ROAMING_ABORT:
+		session_ptr->fw_roaming_started = false;
+		/*
+		 * If there was a disassoc or deauth that was received
+		 * during roaming and it was not honored, then we have
+		 * to internally initiate a disconnect because with
+		 * ROAM_ABORT we come back to original AP.
+		 */
+		if (session_ptr->recvd_deauth_while_roaming)
+			lim_perform_deauth(mac_ctx, session_ptr,
+					   session_ptr->deauth_disassoc_rc,
+					   session_ptr->bssId, 0);
+		if (session_ptr->recvd_disassoc_while_roaming) {
+			lim_disassoc_tdls_peers(mac_ctx, session_ptr,
+						session_ptr->bssId);
+			lim_perform_disassoc(mac_ctx, 0,
+					     session_ptr->deauth_disassoc_rc,
+					     session_ptr, session_ptr->bssId);
+		}
+		return QDF_STATUS_SUCCESS;
+	case SIR_ROAM_SYNCH_PROPAGATION:
+		session_ptr->fw_roaming_started = false;
+		break;
+	default:
+		return status;
+	}
+
+	pe_debug("LFR3:Received WMA_ROAM_OFFLOAD_SYNCH_IND LFR3:auth: %d vdevId: %d",
+		roam_sync_ind_ptr->authStatus, roam_sync_ind_ptr->roamedVdevId);
+	lim_print_mac_addr(mac_ctx, roam_sync_ind_ptr->bssid.bytes,
+			QDF_TRACE_LEVEL_DEBUG);
+	/*
+	 * If deauth from AP already in progress, ignore Roam Synch Indication
+	 * from firmware.
+	 */
+	if (session_ptr->limSmeState != eLIM_SME_LINK_EST_STATE) {
+		pe_err("LFR3: Not in Link est state");
+		return status;
+	}
+	status = lim_roam_fill_bss_descr(mac_ctx, roam_sync_ind_ptr, bss_desc);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		pe_err("LFR3:Failed to fill Bss Descr");
+		return status;
+	}
+	status = QDF_STATUS_E_FAILURE;
+	ft_session_ptr = pe_create_session(mac_ctx, bss_desc->bssId,
+					   &session_id, mac_ctx->lim.maxStation,
+					   eSIR_INFRASTRUCTURE_MODE,
+					   session_ptr->smeSessionId);
+	if (!ft_session_ptr) {
+		pe_err("LFR3:Cannot create PE Session");
+		lim_print_mac_addr(mac_ctx, bss_desc->bssId, LOGE);
+		return status;
+	}
+	/* Update the beacon/probe filter in mac_ctx */
+	lim_set_bcn_probe_filter(mac_ctx, ft_session_ptr, NULL, 0);
+
+	sir_copy_mac_addr(ft_session_ptr->selfMacAddr, session_ptr->selfMacAddr);
+	sir_copy_mac_addr(roam_sync_ind_ptr->self_mac.bytes,
+			session_ptr->selfMacAddr);
+	sir_copy_mac_addr(ft_session_ptr->limReAssocbssId, bss_desc->bssId);
+	session_ptr->bRoamSynchInProgress = true;
+	ft_session_ptr->bRoamSynchInProgress = true;
+	ft_session_ptr->limSystemRole = eLIM_STA_ROLE;
+	sir_copy_mac_addr(session_ptr->limReAssocbssId, bss_desc->bssId);
+	ft_session_ptr->csaOffloadEnable = session_ptr->csaOffloadEnable;
+
+	/* Assign default configured nss value in the new session */
+	if (IS_5G_CH(ft_session_ptr->currentOperChannel))
+		ft_session_ptr->vdev_nss = mac_ctx->vdev_type_nss_5g.sta;
+	else
+		ft_session_ptr->vdev_nss = mac_ctx->vdev_type_nss_2g.sta;
+
+	ft_session_ptr->nss = ft_session_ptr->vdev_nss;
+
+	/* Next routine will update nss and vdev_nss with AP's capabilities */
+	lim_fill_ft_session(mac_ctx, bss_desc, ft_session_ptr, session_ptr);
+
+	/* Next routine may update nss based on dot11Mode */
+	lim_ft_prepare_add_bss_req(mac_ctx, false, ft_session_ptr, bss_desc);
+	roam_sync_ind_ptr->add_bss_params =
+		(tpAddBssParams) ft_session_ptr->ftPEContext.pAddBssReq;
+	add_bss_params = ft_session_ptr->ftPEContext.pAddBssReq;
+	lim_delete_tdls_peers(mac_ctx, session_ptr);
+	curr_sta_ds = dph_lookup_hash_entry(mac_ctx, session_ptr->bssId,
+			&aid, &session_ptr->dph.dphHashTable);
+	if (curr_sta_ds == NULL) {
+		pe_err("LFR3:failed to lookup hash entry");
+		ft_session_ptr->bRoamSynchInProgress = false;
+		return status;
+	}
+	session_ptr->limSmeState = eLIM_SME_IDLE_STATE;
+	lim_cleanup_rx_path(mac_ctx, curr_sta_ds, session_ptr);
+	lim_delete_dph_hash_entry(mac_ctx, curr_sta_ds->staAddr,
+			aid, session_ptr);
+	pe_delete_session(mac_ctx, session_ptr);
+	session_ptr = NULL;
+	curr_sta_ds = dph_add_hash_entry(mac_ctx,
+			roam_sync_ind_ptr->bssid.bytes, DPH_STA_HASH_INDEX_PEER,
+			&ft_session_ptr->dph.dphHashTable);
+	if (curr_sta_ds == NULL) {
+		pe_err("LFR3:failed to add hash entry for");
+		lim_print_mac_addr(mac_ctx,
+				add_bss_params->staContext.staMac, LOGE);
+		ft_session_ptr->bRoamSynchInProgress = false;
+		return status;
+	}
+
+	add_bss_params->bssIdx = roam_sync_ind_ptr->roamedVdevId;
+	ft_session_ptr->bssIdx = (uint8_t) add_bss_params->bssIdx;
+
+	curr_sta_ds->bssId = add_bss_params->bssIdx;
+	curr_sta_ds->staIndex =
+		add_bss_params->staContext.staIdx;
+	rrm_cache_mgmt_tx_power(mac_ctx,
+		add_bss_params->txMgmtPower, ft_session_ptr);
+	mac_ctx->roam.reassocRespLen = roam_sync_ind_ptr->reassocRespLength;
+	mac_ctx->roam.pReassocResp =
+		qdf_mem_malloc(mac_ctx->roam.reassocRespLen);
+	if (!mac_ctx->roam.pReassocResp) {
+		ft_session_ptr->bRoamSynchInProgress = false;
+		return QDF_STATUS_E_NOMEM;
+	}
+	qdf_mem_copy(mac_ctx->roam.pReassocResp,
+			(uint8_t *)roam_sync_ind_ptr +
+			roam_sync_ind_ptr->reassocRespOffset,
+			mac_ctx->roam.reassocRespLen);
+
+	pe_debug("LFR3:the reassoc resp frame data:");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			mac_ctx->roam.pReassocResp,
+			mac_ctx->roam.reassocRespLen);
+	ft_session_ptr->bRoamSynchInProgress = true;
+
+	lim_process_assoc_rsp_frame(mac_ctx, mac_ctx->roam.pReassocResp,
+			LIM_REASSOC, ft_session_ptr);
+
+	lim_copy_and_free_hlp_data_from_session(ft_session_ptr,
+						roam_sync_ind_ptr);
+
+	roam_sync_ind_ptr->aid = ft_session_ptr->limAID;
+	curr_sta_ds->mlmStaContext.mlmState =
+		eLIM_MLM_LINK_ESTABLISHED_STATE;
+	curr_sta_ds->nss = ft_session_ptr->nss;
+	roam_sync_ind_ptr->nss = ft_session_ptr->nss;
+	ft_session_ptr->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+	lim_init_tdls_data(mac_ctx, ft_session_ptr);
+	join_rsp_len = ft_session_ptr->RICDataLen +
+			sizeof(tSirSmeJoinRsp) - sizeof(uint8_t);
+
+#ifdef FEATURE_WLAN_ESE
+	join_rsp_len += ft_session_ptr->tspecLen;
+	pe_debug("tspecLen: %d", ft_session_ptr->tspecLen);
+#endif
+
+	roam_sync_ind_ptr->join_rsp = qdf_mem_malloc(join_rsp_len);
+	if (!roam_sync_ind_ptr->join_rsp) {
+		ft_session_ptr->bRoamSynchInProgress = false;
+		if (mac_ctx->roam.pReassocResp)
+			qdf_mem_free(mac_ctx->roam.pReassocResp);
+		mac_ctx->roam.pReassocResp = NULL;
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	pe_debug("Session RicLength: %d", ft_session_ptr->RICDataLen);
+	if (ft_session_ptr->ricData != NULL) {
+		roam_sync_ind_ptr->join_rsp->parsedRicRspLen =
+			ft_session_ptr->RICDataLen;
+		qdf_mem_copy(roam_sync_ind_ptr->join_rsp->frames,
+				ft_session_ptr->ricData,
+				roam_sync_ind_ptr->join_rsp->parsedRicRspLen);
+		qdf_mem_free(ft_session_ptr->ricData);
+		ft_session_ptr->ricData = NULL;
+		ft_session_ptr->RICDataLen = 0;
+	}
+
+#ifdef FEATURE_WLAN_ESE
+	if (ft_session_ptr->tspecIes != NULL) {
+		roam_sync_ind_ptr->join_rsp->tspecIeLen =
+			ft_session_ptr->tspecLen;
+		qdf_mem_copy(roam_sync_ind_ptr->join_rsp->frames +
+				roam_sync_ind_ptr->join_rsp->parsedRicRspLen,
+				ft_session_ptr->tspecIes,
+				roam_sync_ind_ptr->join_rsp->tspecIeLen);
+		qdf_mem_free(ft_session_ptr->tspecIes);
+		ft_session_ptr->tspecIes = NULL;
+		ft_session_ptr->tspecLen = 0;
+	}
+#endif
+
+	roam_sync_ind_ptr->join_rsp->vht_channel_width =
+		ft_session_ptr->ch_width;
+	roam_sync_ind_ptr->join_rsp->staId = curr_sta_ds->staIndex;
+	roam_sync_ind_ptr->join_rsp->timingMeasCap = curr_sta_ds->timingMeasCap;
+	roam_sync_ind_ptr->join_rsp->nss = curr_sta_ds->nss;
+	roam_sync_ind_ptr->join_rsp->max_rate_flags =
+		lim_get_max_rate_flags(mac_ctx, curr_sta_ds);
+	lim_set_tdls_flags(roam_sync_ind_ptr, ft_session_ptr);
+	roam_sync_ind_ptr->join_rsp->aid = ft_session_ptr->limAID;
+	lim_fill_join_rsp_ht_caps(ft_session_ptr, roam_sync_ind_ptr->join_rsp);
+	ft_session_ptr->limPrevSmeState = ft_session_ptr->limSmeState;
+	ft_session_ptr->limSmeState = eLIM_SME_LINK_EST_STATE;
+	ft_session_ptr->bRoamSynchInProgress = false;
+	if (mac_ctx->roam.pReassocResp)
+		qdf_mem_free(mac_ctx->roam.pReassocResp);
+	mac_ctx->roam.pReassocResp = NULL;
+
+	if (roam_sync_ind_ptr->authStatus == CSR_ROAM_AUTH_STATUS_AUTHENTICATED)
+		ft_session_ptr->is_key_installed = true;
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+static bool lim_is_beacon_miss_scenario(tpAniSirGlobal pMac,
+					uint8_t *pRxPacketInfo)
+{
+	tpSirMacMgmtHdr pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	uint8_t sessionId;
+	tpPESession psessionEntry =
+		pe_find_session_by_bssid(pMac, pHdr->bssId, &sessionId);
+
+	if (psessionEntry && psessionEntry->pmmOffloadInfo.bcnmiss)
+		return true;
+	return false;
+}
+
+/** -----------------------------------------------------------------
+   \brief lim_is_pkt_candidate_for_drop() - decides whether to drop the frame or not
+
+   This function is called before enqueuing the frame to PE queue for further processing.
+   This prevents unnecessary frames getting into PE Queue and drops them right away.
+   Frames will be droped in the following scenarios:
+
+   - In Scan State, drop the frames which are not marked as scan frames
+   - In non-Scan state, drop the frames which are marked as scan frames.
+   - Drop INFRA Beacons and Probe Responses in IBSS Mode
+   - Drop the Probe Request in IBSS mode, if STA did not send out the last beacon
+
+   \param pMac - global mac structure
+   \return - none
+   \sa
+   ----------------------------------------------------------------- */
+
+tMgmtFrmDropReason lim_is_pkt_candidate_for_drop(tpAniSirGlobal pMac,
+						 uint8_t *pRxPacketInfo,
+						 uint32_t subType)
+{
+	uint32_t framelen;
+	uint8_t *pBody;
+	tSirMacCapabilityInfo capabilityInfo;
+	tpSirMacMgmtHdr pHdr = NULL;
+	tpPESession psessionEntry = NULL;
+	uint8_t sessionId;
+
+	/*
+	 *
+	 * In scan mode, drop only Beacon/Probe Response which are NOT marked as scan-frames.
+	 * In non-scan mode, drop only Beacon/Probe Response which are marked as scan frames.
+	 * Allow other mgmt frames, they must be from our own AP, as we don't allow
+	 * other than beacons or probe responses in scan state.
+	 */
+	if ((subType == SIR_MAC_MGMT_BEACON) ||
+	    (subType == SIR_MAC_MGMT_PROBE_RSP)) {
+		if (lim_is_beacon_miss_scenario(pMac, pRxPacketInfo)) {
+			MTRACE(mac_trace(pMac, TRACE_CODE_INFO_LOG, 0,
+					 eLOG_NODROP_MISSED_BEACON_SCENARIO));
+			return eMGMT_DROP_NO_DROP;
+		}
+		if (lim_is_system_in_scan_state(pMac))
+			return eMGMT_DROP_NO_DROP;
+		else if (WMA_IS_RX_IN_SCAN(pRxPacketInfo))
+			return eMGMT_DROP_SCAN_MODE_FRAME;
+
+		framelen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+		pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+		/* drop the frame if length is less than 12 */
+		if (framelen < LIM_MIN_BCN_PR_LENGTH)
+			return eMGMT_DROP_INVALID_SIZE;
+
+		*((uint16_t *) &capabilityInfo) =
+			sir_read_u16(pBody + LIM_BCN_PR_CAPABILITY_OFFSET);
+
+		/* Note sure if this is sufficient, basically this condition allows all probe responses and
+		 *   beacons from an infrastructure network
+		 */
+		if (!capabilityInfo.ibss)
+			return eMGMT_DROP_NO_DROP;
+
+		/* Drop INFRA Beacons and Probe Responses in IBSS Mode */
+		/* This can be enhanced to even check the SSID before deciding to enque the frame. */
+		if (capabilityInfo.ess)
+			return eMGMT_DROP_INFRA_BCN_IN_IBSS;
+
+	} else if ((subType == SIR_MAC_MGMT_PROBE_REQ) &&
+		   (!WMA_GET_RX_BEACON_SENT(pRxPacketInfo))) {
+		pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+		psessionEntry = pe_find_session_by_bssid(pMac,
+							 pHdr->bssId,
+							 &sessionId);
+		if ((psessionEntry && !LIM_IS_IBSS_ROLE(psessionEntry)) ||
+		    (!psessionEntry))
+			return eMGMT_DROP_NO_DROP;
+
+		/* Drop the Probe Request in IBSS mode, if STA did not send out the last beacon */
+		/* In IBSS, the node which sends out the beacon, is supposed to respond to ProbeReq */
+		return eMGMT_DROP_NOT_LAST_IBSS_BCN;
+	} else if (subType == SIR_MAC_MGMT_AUTH) {
+		uint16_t curr_seq_num = 0;
+		struct tLimPreAuthNode *auth_node;
+
+		pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+		psessionEntry = pe_find_session_by_bssid(pMac, pHdr->bssId,
+							 &sessionId);
+		if (!psessionEntry)
+			return eMGMT_DROP_NO_DROP;
+
+		curr_seq_num = ((pHdr->seqControl.seqNumHi << 4) |
+				(pHdr->seqControl.seqNumLo));
+		auth_node = lim_search_pre_auth_list(pMac, pHdr->sa);
+		if (auth_node && pHdr->fc.retry &&
+		    (auth_node->seq_num == curr_seq_num)) {
+			pe_err_rl("auth frame, seq num: %d is already processed, drop it",
+				  curr_seq_num);
+			return eMGMT_DROP_DUPLICATE_AUTH_FRAME;
+		}
+	} else if ((subType == SIR_MAC_MGMT_ASSOC_REQ) &&
+		   (subType == SIR_MAC_MGMT_DISASSOC) &&
+		   (subType == SIR_MAC_MGMT_DEAUTH)) {
+		uint16_t assoc_id;
+		dphHashTableClass *dph_table;
+		tDphHashNode *sta_ds;
+		qdf_time_t *timestamp;
+
+		pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+		psessionEntry = pe_find_session_by_bssid(pMac, pHdr->bssId,
+				&sessionId);
+		if (!psessionEntry)
+			return eMGMT_DROP_NO_DROP;
+		dph_table = &psessionEntry->dph.dphHashTable;
+		sta_ds = dph_lookup_hash_entry(pMac, pHdr->sa, &assoc_id,
+					       dph_table);
+		if (!sta_ds) {
+			if (subType == SIR_MAC_MGMT_ASSOC_REQ)
+				return eMGMT_DROP_NO_DROP;
+			else
+				return eMGMT_DROP_EXCESSIVE_MGMT_FRAME;
+		}
+
+		if (subType == SIR_MAC_MGMT_ASSOC_REQ)
+			timestamp = &sta_ds->last_assoc_received_time;
+		else
+			timestamp = &sta_ds->last_disassoc_deauth_received_time;
+		if (*timestamp > 0 &&
+		    qdf_system_time_before(qdf_get_system_timestamp(),
+					   *timestamp +
+					   LIM_DOS_PROTECTION_TIME)) {
+			pe_debug_rl(FL("Dropping subtype 0x%x frame. %s %d ms %s %d ms"),
+				    subType, "It is received after",
+				    (int)(qdf_get_system_timestamp() - *timestamp),
+				    "of last frame. Allow it only after",
+				    LIM_DOS_PROTECTION_TIME);
+			return eMGMT_DROP_EXCESSIVE_MGMT_FRAME;
+		}
+
+		*timestamp = qdf_get_system_timestamp();
+
+	}
+
+	return eMGMT_DROP_NO_DROP;
+}
+
+void lim_update_lost_link_info(tpAniSirGlobal mac, tpPESession session,
+				int32_t rssi)
+{
+	struct sir_lost_link_info *lost_link_info;
+	struct scheduler_msg mmh_msg = {0};
+
+	if ((NULL == mac) || (NULL == session)) {
+		pe_err("parameter NULL");
+		return;
+	}
+	if (!LIM_IS_STA_ROLE(session))
+		return;
+
+	lost_link_info = qdf_mem_malloc(sizeof(*lost_link_info));
+	if (!lost_link_info)
+		return;
+
+	lost_link_info->vdev_id = session->smeSessionId;
+	lost_link_info->rssi = rssi;
+	mmh_msg.type = eWNI_SME_LOST_LINK_INFO_IND;
+	mmh_msg.bodyptr = lost_link_info;
+	mmh_msg.bodyval = 0;
+	pe_debug("post eWNI_SME_LOST_LINK_INFO_IND, bss_idx: %d rssi: %d",
+		lost_link_info->vdev_id, lost_link_info->rssi);
+
+	lim_sys_process_mmh_msg_api(mac, &mmh_msg, ePROT);
+}
+
+QDF_STATUS pe_acquire_global_lock(tAniSirLim *psPe)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	if (psPe) {
+		if (QDF_IS_STATUS_SUCCESS
+			    (qdf_mutex_acquire(&psPe->lkPeGlobalLock))) {
+			status = QDF_STATUS_SUCCESS;
+		}
+	}
+	return status;
+}
+
+QDF_STATUS pe_release_global_lock(tAniSirLim *psPe)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	if (psPe) {
+		if (QDF_IS_STATUS_SUCCESS
+			    (qdf_mutex_release(&psPe->lkPeGlobalLock))) {
+			status = QDF_STATUS_SUCCESS;
+		}
+	}
+	return status;
+}
+
+/**
+ * lim_mon_init_session() - create PE session for monitor mode operation
+ * @mac_ptr: mac pointer
+ * @msg: Pointer to struct sir_create_session type.
+ *
+ * Return: NONE
+ */
+void lim_mon_init_session(tpAniSirGlobal mac_ptr,
+			  struct sir_create_session *msg)
+{
+	tpPESession psession_entry;
+	uint8_t session_id;
+
+	psession_entry = pe_create_session(mac_ptr, msg->bss_id.bytes,
+					   &session_id,
+					   mac_ptr->lim.maxStation,
+					   eSIR_MONITOR_MODE,
+					   msg->vdev_id);
+	if (psession_entry == NULL) {
+		pe_err("Monitor mode: Session Can not be created");
+		lim_print_mac_addr(mac_ptr, msg->bss_id.bytes, LOGE);
+		return;
+	}
+	psession_entry->vhtCapability = 1;
+}
+
+/**
+ * lim_update_ext_cap_ie() - Update Extended capabilities IE(if present)
+ *          with capabilities of Fine Time measurements(FTM) if set in driver
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @ie_data: Default Scan IE data
+ * @local_ie_buf: Local Scan IE data
+ * @local_ie_len: Pointer to length of @ie_data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_update_ext_cap_ie(tpAniSirGlobal mac_ctx,
+		uint8_t *ie_data, uint8_t *local_ie_buf, uint16_t *local_ie_len)
+{
+	uint32_t dot11mode;
+	bool vht_enabled = false;
+	tDot11fIEExtCap default_scan_ext_cap = {0}, driver_ext_cap = {0};
+	QDF_STATUS status;
+
+	status = lim_strip_extcap_update_struct(mac_ctx, ie_data,
+				   local_ie_len, &default_scan_ext_cap);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("Strip ext cap fails %d", status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if ((*local_ie_len) > (MAX_DEFAULT_SCAN_IE_LEN - EXT_CAP_IE_HDR_LEN)) {
+		pe_err("Invalid Scan IE length");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* copy ie prior to ext cap to local buffer */
+	qdf_mem_copy(local_ie_buf, ie_data, (*local_ie_len));
+
+	/* from here ext cap ie starts, set EID */
+	local_ie_buf[*local_ie_len] = DOT11F_EID_EXTCAP;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &dot11mode);
+	if (IS_DOT11_MODE_VHT(dot11mode))
+		vht_enabled = true;
+
+	status = populate_dot11f_ext_cap(mac_ctx, vht_enabled,
+					&driver_ext_cap, NULL);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("Failed %d to create ext cap IE. Use default value instead",
+				status);
+		local_ie_buf[*local_ie_len + 1] = DOT11F_IE_EXTCAP_MAX_LEN;
+
+		if ((*local_ie_len) > (MAX_DEFAULT_SCAN_IE_LEN -
+		    (DOT11F_IE_EXTCAP_MAX_LEN + EXT_CAP_IE_HDR_LEN))) {
+			pe_err("Invalid Scan IE length");
+			return QDF_STATUS_E_FAILURE;
+		}
+		(*local_ie_len) += EXT_CAP_IE_HDR_LEN;
+		qdf_mem_copy(local_ie_buf + (*local_ie_len),
+				default_scan_ext_cap.bytes,
+				DOT11F_IE_EXTCAP_MAX_LEN);
+		(*local_ie_len) += DOT11F_IE_EXTCAP_MAX_LEN;
+		return QDF_STATUS_SUCCESS;
+	}
+	lim_merge_extcap_struct(&driver_ext_cap, &default_scan_ext_cap, true);
+	local_ie_buf[*local_ie_len + 1] = driver_ext_cap.num_bytes;
+
+	if ((*local_ie_len) > (MAX_DEFAULT_SCAN_IE_LEN -
+	    (EXT_CAP_IE_HDR_LEN + driver_ext_cap.num_bytes))) {
+		pe_err("Invalid Scan IE length");
+		return QDF_STATUS_E_FAILURE;
+	}
+	(*local_ie_len) += EXT_CAP_IE_HDR_LEN;
+	qdf_mem_copy(local_ie_buf + (*local_ie_len),
+			driver_ext_cap.bytes, driver_ext_cap.num_bytes);
+	(*local_ie_len) += driver_ext_cap.num_bytes;
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c
new file mode 100644
index 0000000..f8d79fa
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_assoc_utils.c
@@ -0,0 +1,4855 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * This file lim_assoc_utils.cc contains the utility functions
+ * LIM uses while processing (Re) Association messages.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ * 05/26/10       js             WPA handling in (Re)Assoc frames
+ *
+ */
+
+#include "cds_api.h"
+#include "ani_global.h"
+#include "wni_api.h"
+#include "sir_common.h"
+
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include "cfg_ucfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_sta_hash_api.h"
+#include "lim_admit_control.h"
+#include "lim_send_messages.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+
+#include "qdf_types.h"
+#include "wma_types.h"
+#include "lim_types.h"
+#include "wlan_utility.h"
+#include "wlan_mlme_api.h"
+
+#ifdef FEATURE_WLAN_TDLS
+#define IS_TDLS_PEER(type)  ((type) == STA_ENTRY_TDLS_PEER)
+#else
+#define IS_TDLS_PEER(type) 0
+#endif
+
+/**
+ * lim_cmp_ssid() - utility function to compare SSIDs
+ * @rx_ssid: Received SSID
+ * @session_entry: Session entry
+ *
+ * This function is called in various places within LIM code
+ * to determine whether received SSID is same as SSID in use.
+ *
+ * Return: zero if SSID matched, non-zero otherwise.
+ */
+uint32_t lim_cmp_ssid(tSirMacSSid *rx_ssid, tpPESession session_entry)
+{
+	return qdf_mem_cmp(rx_ssid, &session_entry->ssId,
+				session_entry->ssId.length);
+}
+
+/**
+ * lim_compare_capabilities()
+ *
+ ***FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received capabilities
+ * match with local capabilities or not.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac         - Pointer to Global MAC structure
+ * @param  pAssocReq    - Pointer to received Assoc Req frame
+ * @param  pLocalCapabs - Pointer to local capabilities
+ *
+ * @return status - true for Capabilitity match else false.
+ */
+
+uint8_t
+lim_compare_capabilities(tpAniSirGlobal pMac,
+			 tSirAssocReq *pAssocReq,
+			 tSirMacCapabilityInfo *pLocalCapabs,
+			 tpPESession psessionEntry)
+{
+	if (LIM_IS_AP_ROLE(psessionEntry) &&
+	    (pAssocReq->capabilityInfo.ibss)) {
+		/* Requesting STA asserting IBSS capability. */
+		pe_debug("Requesting STA asserting IBSS capability");
+		return false;
+	}
+	/* Compare CF capabilities */
+	if (pAssocReq->capabilityInfo.cfPollable ||
+	    pAssocReq->capabilityInfo.cfPollReq) {
+		/* AP does not support PCF functionality */
+		pe_debug(" AP does not support PCF functionality");
+		return false;
+	}
+	/* Compare short preamble capability */
+	if (pAssocReq->capabilityInfo.shortPreamble &&
+	    (pAssocReq->capabilityInfo.shortPreamble !=
+	     pLocalCapabs->shortPreamble)) {
+		/* Allowing a STA requesting short preamble while */
+		/* AP does not support it */
+	}
+
+	pe_debug("QoS in AssocReq: %d, local capabs qos: %d",
+		pAssocReq->capabilityInfo.qos, pLocalCapabs->qos);
+
+	/* Compare QoS capability */
+	if (pAssocReq->capabilityInfo.qos &&
+	    (pAssocReq->capabilityInfo.qos != pLocalCapabs->qos))
+		pe_debug("Received unmatched QOS but cfg to suppress - continuing");
+
+	/*
+	 * If AP supports shortSlot and if apple user has
+	 * enforced association only from shortSlot station,
+	 * then AP must reject any station that does not support
+	 * shortSlot
+	 */
+	if (LIM_IS_AP_ROLE(psessionEntry) &&
+	    (pLocalCapabs->shortSlotTime == 1)) {
+		if (pMac->mlme_cfg->feature_flags.accept_short_slot_assoc) {
+			if (pAssocReq->capabilityInfo.shortSlotTime !=
+			    pLocalCapabs->shortSlotTime) {
+				pe_err("AP rejects association as station doesn't support shortslot time");
+				return false;
+			}
+			return false;
+		}
+	}
+
+	return true;
+} /****** end lim_compare_capabilities() ******/
+
+/**
+ * lim_check_rx_basic_rates()
+ *
+ ***FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received rates in
+ * Assoc/Reassoc request frames include all BSS basic rates
+ * or not.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  rxRateSet - pointer to SSID structure
+ *
+ * @return status - true if ALL BSS basic rates are present in the
+ *                  received rateset else false.
+ */
+
+uint8_t
+lim_check_rx_basic_rates(tpAniSirGlobal pMac, tSirMacRateSet rxRateSet,
+			 tpPESession psessionEntry)
+{
+	tSirMacRateSet *pRateSet, basicRate;
+	uint8_t i, j, k, match;
+
+	pRateSet = qdf_mem_malloc(sizeof(tSirMacRateSet));
+	if (!pRateSet)
+		return false;
+
+	/* Copy operational rate set from session Entry */
+	qdf_mem_copy(pRateSet->rate, (psessionEntry->rateSet.rate),
+		     psessionEntry->rateSet.numRates);
+
+	pRateSet->numRates = psessionEntry->rateSet.numRates;
+
+	/* Extract BSS basic rateset from operational rateset */
+	for (i = 0, j = 0;
+	     ((i < pRateSet->numRates) && (i < SIR_MAC_RATESET_EID_MAX)); i++) {
+		if ((pRateSet->rate[i] & 0x80) == 0x80) {
+			/* msb is set, so this is a basic rate */
+			basicRate.rate[j++] = pRateSet->rate[i];
+		}
+	}
+
+	/*
+	 * For each BSS basic rate, find if it is present in the
+	 * received rateset.
+	 */
+	for (k = 0; k < j; k++) {
+		match = 0;
+		for (i = 0;
+		     ((i < rxRateSet.numRates)
+		      && (i < SIR_MAC_RATESET_EID_MAX)); i++) {
+			if ((rxRateSet.rate[i] | 0x80) == basicRate.rate[k])
+				match = 1;
+		}
+
+		if (!match) {
+			/* Free up memory allocated for rateset */
+			qdf_mem_free((uint8_t *) pRateSet);
+
+			return false;
+		}
+	}
+
+	/* Free up memory allocated for rateset */
+	qdf_mem_free((uint8_t *) pRateSet);
+
+	return true;
+} /****** end lim_check_rx_basic_rates() ******/
+
+/**
+ * lim_check_mcs_set()
+ *
+ ***FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received MCS rates in
+ * Assoc/Reassoc request frames includes all Basic MCS Rate Set or not.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  supportedMCSSet - pointer to Supported MCS Rate Set
+ *
+ * @return status - true if ALL MCS Basic Rate Set rates are present in the
+ *                  received rateset else false.
+ */
+
+uint8_t lim_check_mcs_set(tpAniSirGlobal pMac, uint8_t *supportedMCSSet)
+{
+	uint8_t basicMCSSet[SIZE_OF_BASIC_MCS_SET] = { 0 };
+	qdf_size_t cfg_len = 0;
+	uint8_t i;
+	uint8_t validBytes;
+	uint8_t lastByteMCSMask = 0x1f;
+
+	cfg_len = pMac->mlme_cfg->rates.basic_mcs_set.len;
+	if (wlan_mlme_get_cfg_str((uint8_t *)basicMCSSet,
+				  &pMac->mlme_cfg->rates.basic_mcs_set,
+				  &cfg_len) != QDF_STATUS_SUCCESS) {
+		/* / Could not get Basic MCS rateset from CFG. Log error. */
+		pe_err("could not retrieve Basic MCS rateset");
+		return false;
+	}
+
+	validBytes = VALID_MCS_SIZE / 8;
+
+	/* check if all the Basic MCS Bits are set in supported MCS bitmap */
+	for (i = 0; i < validBytes; i++) {
+		if ((basicMCSSet[i] & supportedMCSSet[i]) != basicMCSSet[i]) {
+			pe_warn("One of Basic MCS Set Rates is not supported by the Station");
+			return false;
+		}
+	}
+
+	/* check the last 5 bits of the valid MCS bitmap */
+	if (((basicMCSSet[i] & lastByteMCSMask) &
+	     (supportedMCSSet[i] & lastByteMCSMask)) !=
+	    (basicMCSSet[i] & lastByteMCSMask)) {
+		pe_warn("One of Basic MCS Set Rates is not supported by the Station");
+		return false;
+	}
+
+	return true;
+}
+
+#define SECURITY_SUITE_TYPE_MASK 0xFF
+#define SECURITY_SUITE_TYPE_WEP40 0x1
+#define SECURITY_SUITE_TYPE_TKIP 0x2
+#define SECURITY_SUITE_TYPE_CCMP 0x4
+#define SECURITY_SUITE_TYPE_WEP104 0x4
+#define SECURITY_SUITE_TYPE_GCMP 0x8
+#define SECURITY_SUITE_TYPE_GCMP_256 0x9
+
+/**
+ * is_non_rsn_cipher()- API to check whether cipher suit is rsn or not
+ * @cipher_suite: cipher suit
+ *
+ * Return: True in case non ht cipher else false
+ */
+static inline bool is_non_rsn_cipher(uint8_t cipher_suite)
+{
+	uint8_t cipher_mask;
+
+	cipher_mask = cipher_suite & SECURITY_SUITE_TYPE_MASK;
+	if ((cipher_mask == SECURITY_SUITE_TYPE_CCMP) ||
+	    (cipher_mask == SECURITY_SUITE_TYPE_GCMP) ||
+	    (cipher_mask == SECURITY_SUITE_TYPE_GCMP_256))
+		return false;
+
+	return true;
+}
+
+/**
+ * lim_check_rx_rsn_ie_match()- validate received rsn ie with supported cipher
+ *      suites.
+ * @mac_ctx: pointer to global mac structure
+ * @rx_rsn_ie: received rsn IE pointer
+ * @session_entry: pe session entry
+ * @sta_is_ht: peer station HT capability
+ * @pmf_connection: set to true if this is pmf connection
+ *
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received RSN in
+ * Assoc/Reassoc request frames include supported cipher suites or not.
+ *
+ * Return: QDF_STATUS_SUCCESS if ALL supported cipher suites are present in the
+ *                  received rsn IE else failure status.
+ */
+
+uint8_t lim_check_rx_rsn_ie_match(tpAniSirGlobal mac_ctx,
+				  tDot11fIERSN * const rx_rsn_ie,
+				  tpPESession session_entry, uint8_t sta_is_ht,
+				  bool *pmf_connection)
+{
+	tDot11fIERSN *rsn_ie;
+	uint8_t i, j, match, only_non_ht_cipher = 1;
+#ifdef WLAN_FEATURE_11W
+	bool we_are_pmf_capable;
+	bool we_require_pmf;
+	bool they_are_pmf_capable;
+	bool they_require_pmf;
+#endif
+
+	/* RSN IE should be received from PE */
+	rsn_ie = &session_entry->gStartBssRSNIe;
+
+	if (!rx_rsn_ie) {
+		pe_debug("Rx RSN IE is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Check groupwise cipher suite */
+	for (i = 0; i < sizeof(rx_rsn_ie->gp_cipher_suite); i++)
+		if (rsn_ie->gp_cipher_suite[i] !=
+				 rx_rsn_ie->gp_cipher_suite[i]) {
+			pe_debug("Invalid groupwise cipher suite");
+			return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS;
+		}
+
+	/*
+	 * For each Pairwise cipher suite check whether we support
+	 * received pairwise
+	 */
+	match = 0;
+	for (i = 0; i < rx_rsn_ie->pwise_cipher_suite_count; i++) {
+		for (j = 0; j < rsn_ie->pwise_cipher_suite_count; j++) {
+			if (!qdf_mem_cmp(&rx_rsn_ie->pwise_cipher_suites[i],
+			    &rsn_ie->pwise_cipher_suites[j],
+			    sizeof(rsn_ie->pwise_cipher_suites[j]))) {
+				match = 1;
+				break;
+			}
+		}
+
+		if (sta_is_ht)
+#ifdef ANI_LITTLE_BYTE_ENDIAN
+			only_non_ht_cipher = is_non_rsn_cipher(
+				rx_rsn_ie->pwise_cipher_suites[i][3]);
+#else
+			only_non_ht_cipher = is_non_rsn_cipher(
+				rx_rsn_ie->pwise_cipher_suites[i][0]);
+#endif
+	}
+
+	if ((!match) || ((sta_is_ht) && only_non_ht_cipher)) {
+		pe_debug("Invalid pairwise cipher suite");
+		return eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS;
+	}
+	/*
+	 * Check RSN capabilities
+	 * Bit 0 of First Byte - PreAuthentication Capability
+	 */
+	if (((rx_rsn_ie->RSN_Cap[0] >> 0) & 0x1) == true) {
+		/* this is supported by AP only */
+		pe_debug("Invalid RSN information element capabilities");
+		return eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS;
+	}
+
+	*pmf_connection = false;
+
+#ifdef WLAN_FEATURE_11W
+	we_are_pmf_capable = session_entry->pLimStartBssReq->pmfCapable;
+	we_require_pmf = session_entry->pLimStartBssReq->pmfRequired;
+	they_are_pmf_capable = (rx_rsn_ie->RSN_Cap[0] >> 7) & 0x1;
+	they_require_pmf = (rx_rsn_ie->RSN_Cap[0] >> 6) & 0x1;
+
+	if ((they_require_pmf && they_are_pmf_capable && !we_are_pmf_capable) ||
+	    (we_require_pmf && !they_are_pmf_capable)) {
+		pe_debug("Association fail, robust management frames policy"
+				" violation they_require_pmf =%d"
+				" theyArePMFCapable %d weArePMFCapable %d"
+				" weRequirePMF %d theyArePMFCapable %d",
+			they_require_pmf, they_are_pmf_capable,
+			we_are_pmf_capable, we_require_pmf,
+			they_are_pmf_capable);
+		return eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION;
+	}
+
+	if (they_are_pmf_capable && we_are_pmf_capable)
+		*pmf_connection = true;
+
+	pe_debug("weAreCapable %d, weRequire %d, theyAreCapable %d,"
+			" theyRequire %d, PMFconnection %d",
+		we_are_pmf_capable, we_require_pmf, they_are_pmf_capable,
+		they_require_pmf, *pmf_connection);
+#endif
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_check_rx_wpa_ie_match() - to check supported cipher suites
+ *
+ * @mac: pointer to global mac structure
+ * @rx_wpaie: Received WPA IE in (Re)Assco req
+ * @session_entry: pointer to PE session
+ * @sta_is_ht: peer station is HT
+ *
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received RSN in
+ * Assoc/Reassoc request frames include supported cipher suites or not.
+ *
+ * Return: Success if ALL supported cipher suites are present in the
+ *                  received wpa IE else failure status.
+ */
+
+uint8_t
+lim_check_rx_wpa_ie_match(tpAniSirGlobal mac, tDot11fIEWPA rx_wpaie,
+			  tpPESession session_entry, uint8_t sta_is_ht)
+{
+	tDot11fIEWPA *wpa_ie;
+	uint8_t i, j, match, only_non_ht_cipher = 1;
+
+	/* WPA IE should be received from PE */
+	wpa_ie = &session_entry->gStartBssWPAIe;
+
+	/* Check groupwise cipher suite */
+	for (i = 0; i < 4; i++) {
+		if (wpa_ie->multicast_cipher[i] != rx_wpaie.multicast_cipher[i]) {
+			pe_debug("Invalid groupwise cipher suite");
+			return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS;
+		}
+	}
+
+	/*
+	 * For each Pairwise cipher suite check whether we support
+	 * received pairwise
+	 */
+	match = 0;
+	for (i = 0; i < rx_wpaie.unicast_cipher_count; i++) {
+		for (j = 0; j < wpa_ie->unicast_cipher_count; j++) {
+			if (!qdf_mem_cmp(rx_wpaie.unicast_ciphers[i],
+					    wpa_ie->unicast_ciphers[j], 4)) {
+				match = 1;
+				break;
+			}
+		}
+
+		if ((sta_is_ht)
+#ifdef ANI_LITTLE_BYTE_ENDIAN
+		    &&
+		    ((rx_wpaie.
+		      unicast_ciphers[i][3] & SECURITY_SUITE_TYPE_MASK) ==
+		     SECURITY_SUITE_TYPE_CCMP))
+#else
+		    &&
+		    ((rx_wpaie.
+		      unicast_ciphers[i][0] & SECURITY_SUITE_TYPE_MASK) ==
+		     SECURITY_SUITE_TYPE_CCMP))
+#endif
+		{
+			only_non_ht_cipher = 0;
+		}
+
+	}
+
+	if ((!match) || ((sta_is_ht) && only_non_ht_cipher)) {
+		pe_debug("Invalid pairwise cipher suite");
+		return eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_cleanup_rx_path()
+ *
+ ***FUNCTION:
+ * This function is called to cleanup STA state at SP & RFP.
+ *
+ ***LOGIC:
+ * To circumvent RFP's handling of dummy packet when it does not
+ * have an incomplete packet for the STA to be deleted, a packet
+ * with 'more framgents' bit set will be queued to RFP's WQ before
+ * queuing 'dummy packet'.
+ * A 'dummy' BD is pushed into RFP's WQ with type=00, subtype=1010
+ * (Disassociation frame) and routing flags in BD set to eCPU's
+ * Low Priority WQ.
+ * RFP cleans up its local context for the STA id mentioned in the
+ * BD and then pushes BD to eCPU's low priority WQ.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac    Pointer to Global MAC structure
+ * @param pStaDs  Pointer to the per STA data structure
+ *                initialized by LIM and maintained at DPH
+ *
+ * @return None
+ */
+
+QDF_STATUS
+lim_cleanup_rx_path(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+		    tpPESession psessionEntry)
+{
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+
+	pe_debug("Cleanup Rx Path for AID: %d"
+		"psessionEntry->limSmeState: %d, mlmState: %d",
+		pStaDs->assocId, psessionEntry->limSmeState,
+		pStaDs->mlmStaContext.mlmState);
+
+	psessionEntry->isCiscoVendorAP = false;
+
+	if (pMac->lim.gLimAddtsSent) {
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+			       psessionEntry->peSessionId, eLIM_ADDTS_RSP_TIMER));
+		tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer);
+		pe_debug("Reset gLimAddtsSent flag and send addts timeout to SME");
+		lim_process_sme_addts_rsp_timeout(pMac,
+					pMac->lim.gLimAddtsRspTimerCount);
+	}
+
+	if (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_ASSOC_CNF_STATE) {
+		lim_deactivate_and_change_per_sta_id_timer(pMac, eLIM_CNF_WAIT_TIMER,
+							   pStaDs->assocId);
+
+		if (!pStaDs->mlmStaContext.updateContext) {
+			/**
+			 * There is no context at Polaris to delete.
+			 * Release our assigned AID back to the free pool
+			 */
+			if (LIM_IS_AP_ROLE(psessionEntry)) {
+				lim_del_sta(pMac, pStaDs, false, psessionEntry);
+				lim_release_peer_idx(pMac, pStaDs->assocId,
+						     psessionEntry);
+			}
+			lim_delete_dph_hash_entry(pMac, pStaDs->staAddr,
+						  pStaDs->assocId, psessionEntry);
+
+			return retCode;
+		}
+	}
+	/* delete all tspecs associated with this sta. */
+	lim_admit_control_delete_sta(pMac, pStaDs->assocId);
+
+	/**
+	 * Make STA hash entry invalid at eCPU so that DPH
+	 * does not process any more data packets and
+	 * releases those BDs
+	 */
+	pStaDs->valid = 0;
+	lim_send_sme_tsm_ie_ind(pMac, psessionEntry, 0, 0, 0);
+	/* Any roaming related changes should be above this line */
+	if (lim_is_roam_synch_in_progress(psessionEntry))
+		return QDF_STATUS_SUCCESS;
+	pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+
+	if (LIM_IS_STA_ROLE(psessionEntry)) {
+		MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+		       eLIM_MLM_WT_DEL_STA_RSP_STATE));
+		psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+		/* Deactivating probe after heart beat timer */
+		lim_deactivate_and_change_timer(pMac, eLIM_PROBE_AFTER_HB_TIMER);
+		lim_deactivate_and_change_timer(pMac, eLIM_JOIN_FAIL_TIMER);
+	}
+#ifdef WLAN_DEBUG
+	/* increment a debug count */
+	pMac->lim.gLimNumRxCleanup++;
+#endif
+	/* Do DEL BSS or DEL STA only if ADD BSS was success */
+	if (!psessionEntry->add_bss_failed) {
+		if (psessionEntry->limSmeState == eLIM_SME_JOIN_FAILURE_STATE) {
+			retCode =
+				lim_del_bss(pMac, pStaDs, psessionEntry->bssIdx,
+					    psessionEntry);
+		} else
+			retCode = lim_del_sta(pMac,
+					 pStaDs, true, psessionEntry);
+	}
+
+	return retCode;
+
+} /*** end lim_cleanup_rx_path() ***/
+
+/**
+ * lim_send_del_sta_cnf() - Send Del sta confirmation
+ * @pMac: Pointer to Global MAC structure
+ * @sta_dsaddr: sta ds address
+ * @staDsAssocId: sta ds association id
+ * @mlmStaContext: MLM station context
+ * @statusCode: Status code
+ * @psessionEntry: Session entry
+ *
+ * This function is called to send appropriate CNF message to SME.
+ *
+ * Return: None
+ */
+void
+lim_send_del_sta_cnf(tpAniSirGlobal pMac, struct qdf_mac_addr sta_dsaddr,
+		     uint16_t staDsAssocId, tLimMlmStaContext mlmStaContext,
+		     tSirResultCodes statusCode, tpPESession psessionEntry)
+{
+	tLimMlmDisassocCnf mlmDisassocCnf;
+	tLimMlmDeauthCnf mlmDeauthCnf;
+	tLimMlmPurgeStaInd mlmPurgeStaInd;
+
+	pe_debug("Sessionid: %d staDsAssocId: %d Trigger: %d statusCode: %d sta_dsaddr: "MAC_ADDRESS_STR,
+		psessionEntry->peSessionId, staDsAssocId,
+		mlmStaContext.cleanupTrigger, statusCode,
+		MAC_ADDR_ARRAY(sta_dsaddr.bytes));
+
+	if (LIM_IS_STA_ROLE(psessionEntry)) {
+		/* Set BSSID at CFG to null */
+		tSirMacAddr nullAddr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+		sir_copy_mac_addr(nullAddr, psessionEntry->bssId);
+
+		/* Free up buffer allocated for JoinReq held by */
+		/* MLM state machine */
+		if (psessionEntry->pLimMlmJoinReq) {
+			qdf_mem_free(psessionEntry->pLimMlmJoinReq);
+			psessionEntry->pLimMlmJoinReq = NULL;
+		}
+
+		psessionEntry->limAID = 0;
+	}
+
+	if ((mlmStaContext.cleanupTrigger ==
+					eLIM_HOST_DISASSOC) ||
+		(mlmStaContext.cleanupTrigger ==
+					eLIM_LINK_MONITORING_DISASSOC) ||
+		(mlmStaContext.cleanupTrigger ==
+					eLIM_PROMISCUOUS_MODE_DISASSOC)) {
+		/**
+		 * Host or LMM driven Disassociation.
+		 * Issue Disassoc Confirm to SME.
+		 */
+		pe_debug("Lim Posting DISASSOC_CNF to Sme. Trigger: %d",
+			mlmStaContext.cleanupTrigger);
+
+		qdf_mem_copy((uint8_t *) &mlmDisassocCnf.peerMacAddr,
+			     (uint8_t *) sta_dsaddr.bytes, QDF_MAC_ADDR_SIZE);
+		mlmDisassocCnf.resultCode = statusCode;
+		mlmDisassocCnf.disassocTrigger = mlmStaContext.cleanupTrigger;
+		/* Update PE session Id */
+		mlmDisassocCnf.sessionId = psessionEntry->peSessionId;
+
+		lim_post_sme_message(pMac,
+				     LIM_MLM_DISASSOC_CNF,
+				     (uint32_t *) &mlmDisassocCnf);
+	} else if ((mlmStaContext.cleanupTrigger ==
+					eLIM_HOST_DEAUTH) ||
+			(mlmStaContext.cleanupTrigger ==
+					eLIM_LINK_MONITORING_DEAUTH)) {
+		/**
+		 * Host or LMM driven Deauthentication.
+		 * Issue Deauth Confirm to SME.
+		 */
+		pe_debug("Lim Posting DEAUTH_CNF to Sme. Trigger: %d",
+			mlmStaContext.cleanupTrigger);
+		qdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr, &sta_dsaddr);
+		mlmDeauthCnf.resultCode = statusCode;
+		mlmDeauthCnf.deauthTrigger = mlmStaContext.cleanupTrigger;
+		/* PE session Id */
+		mlmDeauthCnf.sessionId = psessionEntry->peSessionId;
+
+		lim_post_sme_message(pMac,
+				     LIM_MLM_DEAUTH_CNF,
+				     (uint32_t *) &mlmDeauthCnf);
+	} else if ((mlmStaContext.cleanupTrigger ==
+		    eLIM_PEER_ENTITY_DISASSOC) ||
+		   (mlmStaContext.cleanupTrigger == eLIM_PEER_ENTITY_DEAUTH)) {
+		/**
+		 * Received Disassociation/Deauthentication from peer.
+		 * Issue Purge Ind to SME.
+		 */
+		pe_debug("Lim Posting PURGE_STA_IND to Sme. Trigger: %d",
+			mlmStaContext.cleanupTrigger);
+		qdf_mem_copy((uint8_t *) &mlmPurgeStaInd.peerMacAddr,
+			     (uint8_t *) sta_dsaddr.bytes, QDF_MAC_ADDR_SIZE);
+		mlmPurgeStaInd.reasonCode =
+			(uint8_t) mlmStaContext.disassocReason;
+		mlmPurgeStaInd.aid = staDsAssocId;
+		mlmPurgeStaInd.purgeTrigger = mlmStaContext.cleanupTrigger;
+		mlmPurgeStaInd.sessionId = psessionEntry->peSessionId;
+
+		lim_post_sme_message(pMac,
+				     LIM_MLM_PURGE_STA_IND,
+				     (uint32_t *) &mlmPurgeStaInd);
+	} else if (mlmStaContext.cleanupTrigger == eLIM_JOIN_FAILURE) {
+		/* PE setup the peer entry in HW upfront, right after join is completed. */
+		/* If there is a failure during rest of the assoc sequence, this context needs to be cleaned up. */
+		uint8_t smesessionId;
+		uint16_t smetransactionId;
+
+		smesessionId = psessionEntry->smeSessionId;
+		smetransactionId = psessionEntry->transactionId;
+
+		psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+			       psessionEntry->limSmeState));
+
+		/* if it is a reassoc failure to join new AP */
+		if ((mlmStaContext.resultCode ==
+		     eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE)
+		    || (mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_FAILURE)
+		    || (mlmStaContext.resultCode ==
+			eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE)) {
+			pe_debug("Lim Posting eWNI_SME_REASSOC_RSP to SME"
+				"resultCode: %d, statusCode: %d,"
+				"sessionId: %d",
+				mlmStaContext.resultCode,
+				mlmStaContext.protStatusCode,
+				psessionEntry->peSessionId);
+
+			lim_send_sme_join_reassoc_rsp(pMac, eWNI_SME_REASSOC_RSP,
+						      mlmStaContext.resultCode,
+						      mlmStaContext.protStatusCode,
+						      psessionEntry, smesessionId,
+						      smetransactionId);
+			if (mlmStaContext.resultCode != eSIR_SME_SUCCESS) {
+				pe_delete_session(pMac, psessionEntry);
+				psessionEntry = NULL;
+			}
+		} else {
+			qdf_mem_free(psessionEntry->pLimJoinReq);
+			psessionEntry->pLimJoinReq = NULL;
+
+			pe_debug("Lim Posting eWNI_SME_JOIN_RSP to SME."
+				"resultCode: %d,statusCode: %d,"
+				"sessionId: %d",
+				mlmStaContext.resultCode,
+				mlmStaContext.protStatusCode,
+				psessionEntry->peSessionId);
+
+			lim_send_sme_join_reassoc_rsp(pMac, eWNI_SME_JOIN_RSP,
+						      mlmStaContext.resultCode,
+						      mlmStaContext.protStatusCode,
+						      psessionEntry, smesessionId,
+						      smetransactionId);
+
+			if (mlmStaContext.resultCode != eSIR_SME_SUCCESS) {
+				pe_delete_session(pMac, psessionEntry);
+				psessionEntry = NULL;
+			}
+		}
+
+	} else if (mlmStaContext.cleanupTrigger == eLIM_DUPLICATE_ENTRY) {
+		/**
+		 * LIM driven Disassociation.
+		 * Issue Disassoc Confirm to SME.
+		 */
+		pe_debug("Lim Posting DISASSOC_CNF to Sme. Trigger: %d",
+			mlmStaContext.cleanupTrigger);
+
+		qdf_mem_copy((uint8_t *) &mlmDisassocCnf.peerMacAddr,
+			     (uint8_t *) sta_dsaddr.bytes, QDF_MAC_ADDR_SIZE);
+		mlmDisassocCnf.resultCode = statusCode;
+		mlmDisassocCnf.disassocTrigger = eLIM_DUPLICATE_ENTRY;
+		/* Update PE session Id */
+		mlmDisassocCnf.sessionId = psessionEntry->peSessionId;
+
+		lim_post_sme_message(pMac,
+				     LIM_MLM_DISASSOC_CNF,
+				     (uint32_t *) &mlmDisassocCnf);
+	}
+
+	if (NULL != psessionEntry && !LIM_IS_AP_ROLE(psessionEntry)) {
+		pe_delete_session(pMac, psessionEntry);
+		psessionEntry = NULL;
+	}
+}
+
+/**
+ * lim_reject_association() - function to reject Re/Association Request
+ *
+ * @mac_ctx: pointer to global mac structure
+ * @peer_addr: mac address of the peer
+ * @sub_type: Indicates whether it is Association Request (=0) or
+ *            Reassociation Request (=1) frame
+ * @add_pre_auth_context:Indicates whether pre-auth context
+ *                     to be added for this STA
+ * @auth_type: Indicates auth type to be added
+ * @sta_id: Indicates staId of the STA being rejected
+ *          association
+ * @delete_sta: Indicates whether to delete STA context
+ *              at Polaris
+ * @result_code: Indicates what reasonCode to be sent in
+ *          Re/Assoc response to STA
+ * @session_entry: pointer to PE session
+ *
+ * This function is called whenever Re/Association Request need
+ * to be rejected due to failure in assigning an AID or failure
+ * in adding STA context at Polaris or reject by applications.
+ * Resources allocated if any are freedup and (Re) Association
+ * Response frame is sent to requesting STA. Pre-Auth context
+ * will be added for this STA if it does not exist already
+ *
+ * Return: none
+ */
+
+void
+lim_reject_association(tpAniSirGlobal mac_ctx, tSirMacAddr peer_addr,
+			uint8_t sub_type, uint8_t add_pre_auth_context,
+			tAniAuthType auth_type, uint16_t sta_id,
+			uint8_t delete_sta, enum eSirMacStatusCodes result_code,
+			tpPESession session_entry)
+{
+	tpDphHashNode sta_ds;
+
+	pe_debug("Sessionid: %d auth_type: %d sub_type: %d add_pre_auth_context: %d sta_id: %d delete_sta: %d result_code : %d peer_addr: " MAC_ADDRESS_STR,
+		session_entry->peSessionId, auth_type, sub_type,
+		add_pre_auth_context, sta_id, delete_sta, result_code,
+		MAC_ADDR_ARRAY(peer_addr));
+
+	if (add_pre_auth_context) {
+		/* Create entry for this STA in pre-auth list */
+		struct tLimPreAuthNode *auth_node;
+
+		auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
+			       &mac_ctx->lim.gLimPreAuthTimerTable);
+
+		if (auth_node) {
+			qdf_mem_copy((uint8_t *) auth_node->peerMacAddr,
+				     peer_addr, sizeof(tSirMacAddr));
+			auth_node->fTimerStarted = 0;
+			auth_node->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
+			auth_node->authType = (tAniAuthType) auth_type;
+			auth_node->timestamp = qdf_mc_timer_get_system_ticks();
+			lim_add_pre_auth_node(mac_ctx, auth_node);
+		}
+	}
+
+	if (delete_sta == false) {
+		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+				eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS,
+				1, peer_addr, sub_type, 0, session_entry);
+		pe_warn("received Re/Assoc req when max associated STAs reached from");
+		lim_print_mac_addr(mac_ctx, peer_addr, LOGW);
+		lim_send_sme_max_assoc_exceeded_ntf(mac_ctx, peer_addr,
+					session_entry->smeSessionId);
+		return;
+	}
+
+	sta_ds = dph_get_hash_entry(mac_ctx, sta_id,
+		   &session_entry->dph.dphHashTable);
+
+	if (sta_ds == NULL) {
+		pe_err("No STA context, yet rejecting Association");
+		return;
+	}
+
+	/*
+	 * Polaris has state for this STA.
+	 * Trigger cleanup.
+	 */
+	sta_ds->mlmStaContext.cleanupTrigger = eLIM_REASSOC_REJECT;
+
+	/* Receive path cleanup */
+	lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry);
+
+	/*
+	 * Send Re/Association Response with
+	 * status code to requesting STA.
+	 */
+	lim_send_assoc_rsp_mgmt_frame(mac_ctx, result_code, 0, peer_addr,
+					 sub_type, 0, session_entry);
+
+	if (session_entry->parsedAssocReq[sta_ds->assocId] != NULL) {
+		uint8_t *assoc_req_frame;
+
+		assoc_req_frame = (uint8_t *)((tpSirAssocReq) (session_entry->
+			parsedAssocReq[sta_ds->assocId]))->assocReqFrame;
+		/*
+		 *Assoction confirmation is complete,
+		 *free the copy of association request frame.
+		 */
+		if (assoc_req_frame) {
+			qdf_mem_free(assoc_req_frame);
+			assoc_req_frame = NULL;
+		}
+
+		qdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]);
+		session_entry->parsedAssocReq[sta_ds->assocId] = NULL;
+	}
+}
+
+/**
+ * lim_decide_ap_protection_on_ht20_delete() - function to update protection
+ *                                              parameters.
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @beacon_params: ap beacon parameters
+ * @session_entry: pe session entry
+ *
+ * protection related function while HT20 station is getting deleted.
+ *
+ * Return: none
+ */
+static void
+lim_decide_ap_protection_on_ht20_delete(tpAniSirGlobal mac_ctx,
+					tpDphHashNode sta_ds,
+					tpUpdateBeaconParams beacon_params,
+					tpPESession session_entry)
+{
+	uint32_t i = 0;
+
+	pe_debug("(%d) A HT 20 STA is disassociated. Addr is %pM",
+		session_entry->gLimHt20Params.numSta, sta_ds->staAddr);
+
+	if (session_entry->gLimHt20Params.numSta > 0) {
+		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+			if (!session_entry->protStaCache[i].active)
+				continue;
+
+			if (!qdf_mem_cmp(session_entry->protStaCache[i].addr,
+				sta_ds->staAddr, sizeof(tSirMacAddr))) {
+				session_entry->gLimHt20Params.numSta--;
+				session_entry->protStaCache[i].active =
+						false;
+				break;
+			}
+		}
+	}
+
+	if (session_entry->gLimHt20Params.numSta == 0) {
+		/* disable protection */
+		pe_debug("No 11B STA exists, PESessionID %d",
+				session_entry->peSessionId);
+		lim_enable_ht20_protection(mac_ctx, false, false, beacon_params,
+					session_entry);
+	}
+}
+
+/**
+ * lim_decide_ap_protection_on_delete() - update SAP protection on station
+ *                                       deletion.
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @beacon_params: ap beacon parameters
+ * @session_entry: pe session entry
+ *
+ * Decides about protection related settings when a station is getting deleted.
+ *
+ * Return: none
+ */
+void
+lim_decide_ap_protection_on_delete(tpAniSirGlobal mac_ctx,
+				   tpDphHashNode sta_ds,
+				   tpUpdateBeaconParams beacon_params,
+				   tpPESession session_entry)
+{
+	uint32_t phy_mode;
+	tHalBitVal erp_enabled = eHAL_CLEAR;
+	enum band_info rf_band = BAND_UNKNOWN;
+	uint32_t i;
+
+	if (NULL == sta_ds)
+		return;
+
+	lim_get_rf_band_new(mac_ctx, &rf_band, session_entry);
+	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+	erp_enabled = sta_ds->erpEnabled;
+
+	if ((BAND_5G == rf_band) &&
+		(true == session_entry->htCapability) &&
+		(session_entry->beaconParams.llaCoexist) &&
+		(false == sta_ds->mlmStaContext.htCapability)) {
+		/*
+		 * we are HT. if we are 11A, then protection is not required or
+		 * we are HT and 11A station is leaving.
+		 * protection consideration required.
+		 * HT station leaving ==> this case is commonly handled
+		 * between both the bands below.
+		 */
+		pe_debug("(%d) A 11A STA is disassociated. Addr is %pM",
+			session_entry->gLim11aParams.numSta, sta_ds->staAddr);
+		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+			if (session_entry->protStaCache[i].active &&
+				(!qdf_mem_cmp(
+					session_entry->protStaCache[i].addr,
+					 sta_ds->staAddr,
+					sizeof(tSirMacAddr)))) {
+				session_entry->protStaCache[i].active = false;
+				break;
+			}
+		}
+
+		if (session_entry->gLim11aParams.numSta == 0) {
+			/* disable protection */
+			lim_update_11a_protection(mac_ctx, false, false,
+				beacon_params, session_entry);
+		}
+	}
+
+	/* we are HT or 11G and 11B station is getting deleted */
+	if ((BAND_2G == rf_band) &&
+		(phy_mode == WNI_CFG_PHY_MODE_11G ||
+		session_entry->htCapability) &&
+		(erp_enabled == eHAL_CLEAR)) {
+		pe_debug("(%d) A legacy STA is disassociated. Addr is %pM",
+			session_entry->gLim11bParams.numSta, sta_ds->staAddr);
+		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+			if (session_entry->protStaCache[i].active &&
+				(!qdf_mem_cmp(
+					session_entry->protStaCache[i].addr,
+					sta_ds->staAddr,
+					sizeof(tSirMacAddr)))) {
+					session_entry->gLim11bParams.numSta--;
+					session_entry->protStaCache[i].active =
+						 false;
+				break;
+			}
+		}
+
+		if (session_entry->gLim11bParams.numSta == 0) {
+			/* disable protection */
+			lim_enable11g_protection(mac_ctx, false, false,
+						 beacon_params, session_entry);
+		}
+	}
+
+	/*
+	 * we are HT AP and non-11B station is leaving.
+	 * 11g station is leaving
+	 */
+	if ((BAND_2G == rf_band) &&
+		session_entry->htCapability &&
+		!sta_ds->mlmStaContext.htCapability) {
+		pe_debug("(%d) A 11g STA is disassociated. Addr is %pM",
+			session_entry->gLim11bParams.numSta, sta_ds->staAddr);
+		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+			if (session_entry->protStaCache[i].active &&
+				(!qdf_mem_cmp(
+					session_entry->protStaCache[i].addr,
+					sta_ds->staAddr,
+					sizeof(tSirMacAddr)))) {
+				session_entry->gLim11gParams.numSta--;
+				session_entry->protStaCache[i].active = false;
+				break;
+			}
+		}
+
+		if (session_entry->gLim11gParams.numSta == 0) {
+		    /* disable protection */
+		    lim_enable_ht_protection_from11g(mac_ctx, false, false,
+							 beacon_params,
+							 session_entry);
+		}
+	}
+
+	if (!((true == session_entry->htCapability) &&
+		(true == sta_ds->mlmStaContext.htCapability)))
+		return;
+
+	/*
+	 * Applies to 2.4 as well as 5 GHZ.
+	 * HT non-GF leaving
+	 */
+	if (!sta_ds->htGreenfield) {
+		pe_debug("(%d) A non-GF STA is disassociated. Addr is %pM",
+			session_entry->gLimNonGfParams.numSta, sta_ds->staAddr);
+		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+			if (session_entry->protStaCache[i].active &&
+				(!qdf_mem_cmp(
+					session_entry->protStaCache[i].addr,
+					sta_ds->staAddr,
+					sizeof(tSirMacAddr)))) {
+				session_entry->protStaCache[i].active = false;
+				break;
+			}
+		}
+
+		if (session_entry->gLimNonGfParams.numSta == 0) {
+			/* disable protection */
+			lim_enable_ht_non_gf_protection(mac_ctx, false, false,
+					beacon_params, session_entry);
+		}
+	}
+
+	/*
+	 * Applies to 2.4 as well as 5 GHZ.
+	 * HT 20Mhz station leaving
+	 */
+	if (session_entry->beaconParams.ht20Coexist &&
+		(eHT_CHANNEL_WIDTH_20MHZ ==
+			 sta_ds->htSupportedChannelWidthSet)) {
+		lim_decide_ap_protection_on_ht20_delete(mac_ctx, sta_ds,
+					beacon_params, session_entry);
+	}
+
+	/*
+	 * Applies to 2.4 as well as 5 GHZ.
+	 * LSIG TXOP not supporting staiton leaving
+	 */
+	if ((false == session_entry->beaconParams.
+				fLsigTXOPProtectionFullSupport) &&
+		(false == sta_ds->htLsigTXOPProtection)) {
+		pe_debug("(%d) A HT LSIG not supporting STA is disassociated. Addr is %pM",
+			session_entry->gLimLsigTxopParams.numSta,
+			sta_ds->staAddr);
+		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+			if (session_entry->protStaCache[i].active &&
+				(!qdf_mem_cmp(
+					session_entry->protStaCache[i].addr,
+					sta_ds->staAddr,
+					sizeof(tSirMacAddr)))) {
+				session_entry->protStaCache[i].active = false;
+				break;
+			}
+		}
+
+		if (session_entry->gLimLsigTxopParams.numSta == 0) {
+			/* disable protection */
+			lim_enable_ht_lsig_txop_protection(mac_ctx, true,
+				false, beacon_params, session_entry);
+		}
+	}
+}
+
+/**
+ * lim_decide_short_preamble() - update short preamble parameters
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @beacon_params: ap beacon parameters
+ * @session_entry: pe session entry
+ *
+ * Decides about any short preamble related change because of new station
+ * joining.
+ *
+ * Return: None
+ */
+static void lim_decide_short_preamble(tpAniSirGlobal mac_ctx,
+				      tpDphHashNode sta_ds,
+				      tpUpdateBeaconParams beacon_params,
+				      tpPESession session_entry)
+{
+	uint32_t i;
+
+	if (sta_ds->shortPreambleEnabled == eHAL_CLEAR) {
+		pe_debug("(%d) A non-short preamble STA is disassociated. Addr is %pM",
+		       session_entry->gLimNoShortParams.numNonShortPreambleSta,
+			 sta_ds->staAddr);
+		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+			if (session_entry->gLimNoShortParams.
+				staNoShortCache[i].active &&
+				(!qdf_mem_cmp(session_entry->
+					gLimNoShortParams.
+					staNoShortCache[i].addr,
+					sta_ds->staAddr,
+					sizeof(tSirMacAddr)))) {
+				session_entry->gLimNoShortParams.
+					numNonShortPreambleSta--;
+				session_entry->gLimNoShortParams.
+					staNoShortCache[i].active = false;
+				break;
+			}
+		}
+
+		if (session_entry->gLimNoShortParams.numNonShortPreambleSta)
+			return;
+
+		/*
+		 * enable short preamble
+		 * reset the cache
+		 */
+		qdf_mem_set((uint8_t *) &session_entry->gLimNoShortParams,
+				sizeof(tLimNoShortParams), 0);
+		if (lim_enable_short_preamble(mac_ctx, true,
+			beacon_params, session_entry) != QDF_STATUS_SUCCESS)
+			pe_err("Cannot enable short preamble");
+	}
+}
+
+/**
+ * lim_decide_short_slot() - update short slot time related  parameters
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @beacon_params: ap beacon parameters
+ * @session_entry: pe session entry
+ *
+ * Decides about any short slot time related change because of station leaving
+ *        the BSS.
+ * Return: None
+ */
+static void
+lim_decide_short_slot(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+		      tpUpdateBeaconParams beacon_params,
+		      tpPESession session_entry)
+{
+	uint32_t i, val, non_short_slot_sta_count;
+
+	if (sta_ds->shortSlotTimeEnabled != eHAL_CLEAR)
+		return;
+
+	pe_debug("(%d) A non-short slottime STA is disassociated. Addr is %pM",
+		mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta,
+		sta_ds->staAddr);
+
+	val = mac_ctx->mlme_cfg->feature_flags.enable_short_slot_time_11g;
+
+	if (LIM_IS_AP_ROLE(session_entry)) {
+		non_short_slot_sta_count =
+		      session_entry->gLimNoShortSlotParams.numNonShortSlotSta;
+		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+			if (session_entry->gLimNoShortSlotParams.
+				staNoShortSlotCache[i].active &&
+				(!qdf_mem_cmp(session_entry->
+					gLimNoShortSlotParams.
+						staNoShortSlotCache[i].addr,
+					sta_ds->staAddr,
+					sizeof(tSirMacAddr)))) {
+				non_short_slot_sta_count--;
+				session_entry->gLimNoShortSlotParams.
+					staNoShortSlotCache[i].active = false;
+				break;
+			}
+		}
+
+		if (non_short_slot_sta_count == 0 && val) {
+			/*
+			 * enable short slot time
+			 * reset the cache
+			 */
+			qdf_mem_set((uint8_t *) &session_entry->
+				gLimNoShortSlotParams,
+				sizeof(tLimNoShortSlotParams), 0);
+			beacon_params->fShortSlotTime = true;
+			beacon_params->paramChangeBitmap |=
+				PARAM_SHORT_SLOT_TIME_CHANGED;
+			session_entry->shortSlotTimeSupported = true;
+		}
+		session_entry->gLimNoShortSlotParams.numNonShortSlotSta =
+			non_short_slot_sta_count;
+	} else {
+		non_short_slot_sta_count =
+			mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta;
+		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+			if (mac_ctx->lim.gLimNoShortSlotParams.
+				staNoShortSlotCache[i].active &&
+				(!qdf_mem_cmp(
+					mac_ctx->lim.gLimNoShortSlotParams.
+						staNoShortSlotCache[i].addr,
+					sta_ds->staAddr,
+					sizeof(tSirMacAddr)))) {
+				non_short_slot_sta_count--;
+				mac_ctx->lim.gLimNoShortSlotParams.
+					staNoShortSlotCache[i].active = false;
+				break;
+			}
+		}
+
+		if (val && !non_short_slot_sta_count) {
+			/*
+			 * enable short slot time
+			 * reset the cache
+			 */
+			qdf_mem_set(
+				(uint8_t *) &mac_ctx->lim.gLimNoShortSlotParams,
+				sizeof(tLimNoShortSlotParams), 0);
+			/*in case of AP set SHORT_SLOT_TIME to enable*/
+			if (LIM_IS_AP_ROLE(session_entry)) {
+				beacon_params->fShortSlotTime = true;
+				beacon_params->paramChangeBitmap |=
+					PARAM_SHORT_SLOT_TIME_CHANGED;
+				session_entry->shortSlotTimeSupported = true;
+			}
+		}
+		mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta =
+			non_short_slot_sta_count;
+	}
+}
+
+/**
+ * lim_populate_vht_mcs_set - function to populate vht mcs rate set
+ * @mac_ctx: pointer to global mac structure
+ * @rates: pointer to supported rate set
+ * @peer_vht_caps: pointer to peer vht capabilities
+ * @session_entry: pe session entry
+ *
+ * Populates vht mcs rate set based on peer and self capabilities
+ *
+ * Return: QDF_STATUS_SUCCESS on success else QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS lim_populate_vht_mcs_set(tpAniSirGlobal mac_ctx,
+				       tpSirSupportedRates rates,
+				       tDot11fIEVHTCaps *peer_vht_caps,
+				       tpPESession session_entry,
+				       uint8_t nss)
+{
+	uint32_t self_sta_dot11mode = 0;
+	uint16_t mcs_map_mask = MCSMAPMASK1x1;
+	uint16_t mcs_map_mask2x2 = 0;
+	struct mlme_vht_capabilities_info vht_cap_info;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_sta_dot11mode);
+
+	if (!IS_DOT11_MODE_VHT(self_sta_dot11mode))
+		return QDF_STATUS_SUCCESS;
+
+	vht_cap_info = mac_ctx->mlme_cfg->vht_caps.vht_cap_info;
+
+	rates->vhtRxMCSMap = (uint16_t)vht_cap_info.rx_mcs_map;
+	rates->vhtTxMCSMap = (uint16_t)vht_cap_info.tx_mcs_map;
+	rates->vhtRxHighestDataRate =
+			(uint16_t)vht_cap_info.rx_supp_data_rate;
+	rates->vhtTxHighestDataRate = (uint16_t)vht_cap_info.tx_supp_data_rate;
+
+	if (NSS_1x1_MODE == nss) {
+		rates->vhtRxMCSMap |= VHT_MCS_1x1;
+		rates->vhtTxMCSMap |= VHT_MCS_1x1;
+		rates->vhtTxHighestDataRate =
+			VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+		rates->vhtRxHighestDataRate =
+			VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+		if (session_entry && !session_entry->ch_width &&
+		    !vht_cap_info.enable_vht20_mcs9 &&
+		    ((rates->vhtRxMCSMap & VHT_1x1_MCS_MASK) ==
+				 VHT_1x1_MCS9_MAP)) {
+			DISABLE_VHT_MCS_9(rates->vhtRxMCSMap,
+					NSS_1x1_MODE);
+			DISABLE_VHT_MCS_9(rates->vhtTxMCSMap,
+					NSS_1x1_MODE);
+		}
+	} else {
+		if (session_entry && !session_entry->ch_width &&
+				!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable_vht20_mcs9 &&
+				((rates->vhtRxMCSMap & VHT_2x2_MCS_MASK) ==
+				 VHT_2x2_MCS9_MAP)) {
+			DISABLE_VHT_MCS_9(rates->vhtRxMCSMap,
+					NSS_2x2_MODE);
+			DISABLE_VHT_MCS_9(rates->vhtTxMCSMap,
+					NSS_2x2_MODE);
+		}
+	}
+
+	if ((peer_vht_caps == NULL) || (!peer_vht_caps->present))
+		return QDF_STATUS_SUCCESS;
+
+	rates->vhtTxHighestDataRate =
+		QDF_MIN(rates->vhtTxHighestDataRate,
+			peer_vht_caps->txSupDataRate);
+	rates->vhtRxHighestDataRate =
+		QDF_MIN(rates->vhtRxHighestDataRate,
+			peer_vht_caps->rxHighSupDataRate);
+
+	if (session_entry && session_entry->nss == NSS_2x2_MODE)
+		mcs_map_mask2x2 = MCSMAPMASK2x2;
+
+	if ((peer_vht_caps->txMCSMap & mcs_map_mask) <
+	    (rates->vhtRxMCSMap & mcs_map_mask)) {
+		rates->vhtRxMCSMap &= ~(mcs_map_mask);
+		rates->vhtRxMCSMap |=
+			(peer_vht_caps->txMCSMap & mcs_map_mask);
+	}
+	if ((peer_vht_caps->rxMCSMap & mcs_map_mask) <
+	    (rates->vhtTxMCSMap & mcs_map_mask)) {
+		rates->vhtTxMCSMap &= ~(mcs_map_mask);
+		rates->vhtTxMCSMap |=
+			(peer_vht_caps->rxMCSMap & mcs_map_mask);
+	}
+
+	if (mcs_map_mask2x2) {
+
+		uint16_t peer_mcs_map, self_mcs_map;
+
+		peer_mcs_map =
+			peer_vht_caps->txMCSMap & mcs_map_mask2x2;
+		self_mcs_map =
+			rates->vhtRxMCSMap & mcs_map_mask2x2;
+
+		if ((self_mcs_map != mcs_map_mask2x2) &&
+		    ((peer_mcs_map == mcs_map_mask2x2) ||
+		     (peer_mcs_map < self_mcs_map))) {
+			rates->vhtRxMCSMap &= ~mcs_map_mask2x2;
+			rates->vhtRxMCSMap |= peer_mcs_map;
+		}
+
+		peer_mcs_map =
+		 (peer_vht_caps->rxMCSMap & mcs_map_mask2x2);
+		self_mcs_map =
+			(rates->vhtTxMCSMap & mcs_map_mask2x2);
+
+		if ((self_mcs_map != mcs_map_mask2x2) &&
+		    ((peer_mcs_map == mcs_map_mask2x2) ||
+		     (peer_mcs_map < self_mcs_map))) {
+			rates->vhtTxMCSMap &= ~mcs_map_mask2x2;
+			rates->vhtTxMCSMap |= peer_mcs_map;
+		}
+	}
+
+	pe_debug("enable2x2 - %d nss %d vhtRxMCSMap - %x vhtTxMCSMap - %x",
+		mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2, nss,
+		rates->vhtRxMCSMap, rates->vhtTxMCSMap);
+
+	if (NULL != session_entry) {
+		session_entry->supported_nss_1x1 =
+			((rates->vhtTxMCSMap & VHT_MCS_1x1) ==
+			 VHT_MCS_1x1) ? true : false;
+		pe_debug("VHT supported nss 1x1: %d",
+		       session_entry->supported_nss_1x1);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_populate_own_rate_set() - comprises the basic and extended rates read
+ *                                from CFG
+ * @mac_ctx: pointer to global mac structure
+ * @rates: pointer to supported rates
+ * @supported_mcs_set: pointer to supported mcs rates
+ * @basic_only: update only basic rates if set true
+ * @session_entry: pe session entry
+ * @vht_caps: pointer to vht capability
+ *
+ * This function is called by limProcessAssocRsp() or
+ * lim_add_staInIBSS()
+ * - It creates a combined rate set of 12 rates max which
+ *   comprises the basic and extended rates read from CFG
+ * - It sorts the combined rate Set and copy it in the
+ *   rate array of the pSTA descriptor
+ * - It sets the erpEnabled bit of the STA descriptor
+ * ERP bit is set iff the dph PHY mode is 11G and there is at least
+ * an A rate in the supported or extended rate sets
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
+ */
+QDF_STATUS
+lim_populate_own_rate_set(tpAniSirGlobal mac_ctx,
+		tpSirSupportedRates rates, uint8_t *supported_mcs_set,
+		uint8_t basic_only, tpPESession session_entry,
+		struct sDot11fIEVHTCaps *vht_caps,
+		struct sDot11fIEhe_cap *he_caps)
+{
+	tSirMacRateSet temp_rate_set;
+	tSirMacRateSet temp_rate_set2;
+	uint32_t i, j, val, min, is_arate;
+	uint32_t phy_mode = 0;
+	uint32_t self_sta_dot11mode = 0;
+	uint8_t a_rate_index = 0;
+	uint8_t b_rate_index = 0;
+	qdf_size_t val_len;
+
+	is_arate = 0;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_sta_dot11mode);
+	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+	/*
+	 * Include 11b rates only when the device configured in
+	 *  auto, 11a/b/g or 11b_only
+	 */
+	if ((self_sta_dot11mode == WNI_CFG_DOT11_MODE_ALL) ||
+	    (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11A) ||
+	    (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11AC) ||
+	    (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11N) ||
+	    (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11G) ||
+	    (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11B)) {
+		val_len = mac_ctx->mlme_cfg->rates.supported_11b.len;
+		wlan_mlme_get_cfg_str((uint8_t *)&temp_rate_set.rate,
+				      &mac_ctx->mlme_cfg->rates.supported_11b,
+				      &val_len);
+		temp_rate_set.numRates = (uint8_t)val_len;
+	} else {
+		temp_rate_set.numRates = 0;
+	}
+
+	/* Include 11a rates when the device configured in non-11b mode */
+	if (!IS_DOT11_MODE_11B(self_sta_dot11mode)) {
+		val_len = mac_ctx->mlme_cfg->rates.supported_11a.len;
+		wlan_mlme_get_cfg_str((uint8_t *)&temp_rate_set2.rate,
+				      &mac_ctx->mlme_cfg->rates.supported_11a,
+				      &val_len);
+		temp_rate_set2.numRates = (uint8_t)val_len;
+	} else {
+		temp_rate_set2.numRates = 0;
+	}
+
+	if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
+		pe_err("more than 12 rates in CFG");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* copy all rates in temp_rate_set, there are 12 rates max */
+	for (i = 0; i < temp_rate_set2.numRates; i++)
+		temp_rate_set.rate[i + temp_rate_set.numRates] =
+			temp_rate_set2.rate[i];
+
+	temp_rate_set.numRates += temp_rate_set2.numRates;
+
+	/**
+	 * Sort rates in temp_rate_set (they are likely to be already sorted)
+	 * put the result in pSupportedRates
+	 */
+
+	qdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
+	for (i = 0; i < temp_rate_set.numRates; i++) {
+		min = 0;
+		val = 0xff;
+		is_arate = 0;
+
+		for (j = 0; (j < temp_rate_set.numRates) &&
+			 (j < SIR_MAC_RATESET_EID_MAX); j++) {
+			if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) <
+					val) {
+				val = temp_rate_set.rate[j] & 0x7f;
+				min = j;
+			}
+		}
+
+		if (sirIsArate(temp_rate_set.rate[min] & 0x7f))
+			is_arate = 1;
+
+		if (is_arate)
+			rates->llaRates[a_rate_index++] =
+						temp_rate_set.rate[min];
+		else
+			rates->llbRates[b_rate_index++] =
+						temp_rate_set.rate[min];
+		temp_rate_set.rate[min] = 0xff;
+	}
+
+	if (IS_DOT11_MODE_HT(self_sta_dot11mode)) {
+		val_len = SIZE_OF_SUPPORTED_MCS_SET;
+		if (wlan_mlme_get_cfg_str(
+			rates->supportedMCSSet,
+			&mac_ctx->mlme_cfg->rates.supported_mcs_set,
+			&val_len) != QDF_STATUS_SUCCESS) {
+			pe_err("could not retrieve supportedMCSSet");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (session_entry->nss == NSS_1x1_MODE)
+			rates->supportedMCSSet[1] = 0;
+		/*
+		 * if supported MCS Set of the peer is passed in,
+		 * then do the intersection
+		 * else use the MCS set from local CFG.
+		 */
+
+		if (supported_mcs_set != NULL) {
+			for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
+				rates->supportedMCSSet[i] &=
+					 supported_mcs_set[i];
+		}
+
+		pe_debug("MCS Rate Set Bitmap: ");
+		for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
+			pe_debug("%x ", rates->supportedMCSSet[i]);
+	}
+	lim_populate_vht_mcs_set(mac_ctx, rates, vht_caps,
+			session_entry, session_entry->nss);
+	lim_populate_he_mcs_set(mac_ctx, rates, he_caps,
+			session_entry, session_entry->nss);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_11AX
+/**
+ * lim_calculate_he_nss() - function to calculate new nss from he rates
+ * @rates: supported rtes struct object
+ * @session: pe session entry
+ * This function calculates nss from rx_he_mcs_map_lt_80 within rates struct
+ * object and assigns new value to nss within pe_session
+ *
+ * Return: None
+ */
+static void lim_calculate_he_nss(tpSirSupportedRates rates, tpPESession session)
+{
+	HE_GET_NSS(rates->rx_he_mcs_map_lt_80, session->nss);
+}
+#else
+static void lim_calculate_he_nss(tpSirSupportedRates rates, tpPESession session)
+{
+}
+#endif
+
+QDF_STATUS
+lim_populate_peer_rate_set(tpAniSirGlobal pMac,
+		tpSirSupportedRates pRates, uint8_t *pSupportedMCSSet,
+		uint8_t basicOnly, tpPESession psessionEntry,
+		tDot11fIEVHTCaps *pVHTCaps, tDot11fIEhe_cap *he_caps)
+{
+	tSirMacRateSet tempRateSet;
+	tSirMacRateSet tempRateSet2;
+	uint32_t i, j, val, min, isArate = 0;
+	qdf_size_t val_len;
+
+	/* copy operational rate set from psessionEntry */
+	if (psessionEntry->rateSet.numRates <= SIR_MAC_RATESET_EID_MAX) {
+		qdf_mem_copy((uint8_t *) tempRateSet.rate,
+			     (uint8_t *) (psessionEntry->rateSet.rate),
+			     psessionEntry->rateSet.numRates);
+		tempRateSet.numRates = psessionEntry->rateSet.numRates;
+	} else {
+		pe_err("more than SIR_MAC_RATESET_EID_MAX rates");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if ((psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G) ||
+		(psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11A) ||
+		(psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11AC) ||
+		(psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N)) {
+		if (psessionEntry->extRateSet.numRates <=
+		    SIR_MAC_RATESET_EID_MAX) {
+			qdf_mem_copy((uint8_t *) tempRateSet2.rate,
+				     (uint8_t *) (psessionEntry->extRateSet.
+						  rate),
+				     psessionEntry->extRateSet.numRates);
+			tempRateSet2.numRates =
+				psessionEntry->extRateSet.numRates;
+		} else {
+			pe_err("psessionEntry->extRateSet.numRates more than SIR_MAC_RATESET_EID_MAX rates");
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else
+		tempRateSet2.numRates = 0;
+	if ((tempRateSet.numRates + tempRateSet2.numRates) >
+	    SIR_MAC_RATESET_EID_MAX) {
+		pe_err("more than 12 rates in CFG");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* copy all rates in tempRateSet, there are 12 rates max */
+	for (i = 0; i < tempRateSet2.numRates; i++)
+		tempRateSet.rate[i + tempRateSet.numRates] =
+			tempRateSet2.rate[i];
+	tempRateSet.numRates += tempRateSet2.numRates;
+	/**
+	 * Sort rates in tempRateSet (they are likely to be already sorted)
+	 * put the result in pSupportedRates
+	 */
+	{
+		uint8_t aRateIndex = 0;
+		uint8_t bRateIndex = 0;
+
+		qdf_mem_set((uint8_t *) pRates, sizeof(tSirSupportedRates), 0);
+		for (i = 0; i < tempRateSet.numRates; i++) {
+			min = 0;
+			val = 0xff;
+			isArate = 0;
+			for (j = 0;
+			     (j < tempRateSet.numRates)
+			     && (j < SIR_MAC_RATESET_EID_MAX); j++) {
+				if ((uint32_t) (tempRateSet.rate[j] & 0x7f) <
+				    val) {
+					val = tempRateSet.rate[j] & 0x7f;
+					min = j;
+				}
+			}
+			if (sirIsArate(tempRateSet.rate[min] & 0x7f))
+				isArate = 1;
+			/*
+			 * HAL needs to know whether the rate is basic rate or not, as it needs to
+			 * update the response rate table accordingly. e.g. if one of the 11a rates is
+			 * basic rate, then that rate can be used for sending control frames.
+			 * HAL updates the response rate table whenever basic rate set is changed.
+			 */
+			if (basicOnly) {
+				if (tempRateSet.rate[min] & 0x80) {
+					if (isArate)
+						pRates->llaRates[aRateIndex++] =
+							tempRateSet.rate[min];
+					else
+						pRates->llbRates[bRateIndex++] =
+							tempRateSet.rate[min];
+				}
+			} else {
+				if (isArate)
+					pRates->llaRates[aRateIndex++] =
+						tempRateSet.rate[min];
+				else
+					pRates->llbRates[bRateIndex++] =
+						tempRateSet.rate[min];
+			}
+			tempRateSet.rate[min] = 0xff;
+		}
+	}
+
+	if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)) {
+		val_len = SIZE_OF_SUPPORTED_MCS_SET;
+		if (wlan_mlme_get_cfg_str(
+			pRates->supportedMCSSet,
+			&pMac->mlme_cfg->rates.supported_mcs_set,
+			&val_len) != QDF_STATUS_SUCCESS) {
+			pe_err("could not retrieve supportedMCSSet");
+			return QDF_STATUS_E_FAILURE;
+		}
+		if (psessionEntry->nss == NSS_1x1_MODE)
+			pRates->supportedMCSSet[1] = 0;
+
+		/* if supported MCS Set of the peer is passed in, then do the
+		 * intersection, else use the MCS set from local CFG.
+		 */
+		if (pSupportedMCSSet != NULL) {
+			for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
+				pRates->supportedMCSSet[i] &=
+					pSupportedMCSSet[i];
+		}
+		pe_debug("MCS Rate Set Bitmap: ");
+		for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
+			pe_debug("%x ", pRates->supportedMCSSet[i]);
+
+		if (pRates->supportedMCSSet[0] == 0) {
+			pe_debug("Incorrect MCS 0 - 7. They must be supported");
+			pRates->supportedMCSSet[0] = 0xFF;
+		}
+
+		psessionEntry->supported_nss_1x1 =
+			((pRates->supportedMCSSet[1] != 0) ? false : true);
+		pe_debug("HT supported nss 1x1: %d",
+			psessionEntry->supported_nss_1x1);
+	}
+	lim_populate_vht_mcs_set(pMac, pRates, pVHTCaps,
+			psessionEntry, psessionEntry->nss);
+
+	lim_populate_he_mcs_set(pMac, pRates, he_caps,
+			psessionEntry, psessionEntry->nss);
+
+	if (IS_DOT11_MODE_HE(psessionEntry->dot11mode) && he_caps) {
+		lim_calculate_he_nss(pRates, psessionEntry);
+	} else if (IS_DOT11_MODE_VHT(psessionEntry->dot11mode)) {
+		if ((pRates->vhtRxMCSMap & MCSMAPMASK2x2) == MCSMAPMASK2x2)
+			psessionEntry->nss = NSS_1x1_MODE;
+	} else if (pRates->supportedMCSSet[1] == 0) {
+		psessionEntry->nss = NSS_1x1_MODE;
+	}
+	pe_debug("nss: %d", psessionEntry->nss);
+
+	return QDF_STATUS_SUCCESS;
+} /*** lim_populate_peer_rate_set() ***/
+
+/**
+ * lim_populate_matching_rate_set() -process the CFG rate sets and
+ *          the rate sets received in the Assoc request on AP.
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @oper_rate_set: pointer to operating rate set
+ * @ext_rate_set: pointer to extended rate set
+ * @supported_mcs_set: pointer to supported rate set
+ * @session_entry: pointer to pe session entry
+ * @vht_caps: pointer to vht capabilities
+ *
+ * This is called at the time of Association Request
+ * processing on AP and while adding peer's context
+ * in IBSS role to process the CFG rate sets and
+ * the rate sets received in the Assoc request on AP
+ * or Beacon/Probe Response from peer in IBSS.
+ *
+ * 1. It makes the intersection between our own rate Sat
+ *    and extemcded rate set and the ones received in the
+ *    association request.
+ * 2. It creates a combined rate set of 12 rates max which
+ *    comprised the basic and extended rates
+ * 3. It sorts the combined rate Set and copy it in the
+ *    rate array of the pSTA descriptor
+ *
+ * The parser has already ensured unicity of the rates in the
+ * association request structure
+ *
+ * Return: QDF_STATUS_SUCCESS on success else QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS lim_populate_matching_rate_set(tpAniSirGlobal mac_ctx,
+					     tpDphHashNode sta_ds,
+					     tSirMacRateSet *oper_rate_set,
+					     tSirMacRateSet *ext_rate_set,
+					     uint8_t *supported_mcs_set,
+					     tpPESession session_entry,
+					     tDot11fIEVHTCaps *vht_caps,
+					     tDot11fIEhe_cap *he_caps)
+{
+	tSirMacRateSet temp_rate_set;
+	tSirMacRateSet temp_rate_set2;
+	uint32_t i, j, val, min, is_arate;
+	uint32_t phy_mode;
+	uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
+	tpSirSupportedRates rates;
+	uint8_t a_rate_index = 0;
+	uint8_t b_rate_index = 0;
+	qdf_size_t val_len;
+
+	is_arate = 0;
+
+	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+	/* copy operational rate set from session_entry */
+	qdf_mem_copy((temp_rate_set.rate), (session_entry->rateSet.rate),
+		     session_entry->rateSet.numRates);
+	temp_rate_set.numRates = (uint8_t) session_entry->rateSet.numRates;
+
+	if (phy_mode == WNI_CFG_PHY_MODE_11G) {
+		qdf_mem_copy((temp_rate_set2.rate),
+			     (session_entry->extRateSet.rate),
+			     session_entry->extRateSet.numRates);
+		temp_rate_set2.numRates =
+			(uint8_t) session_entry->extRateSet.numRates;
+	} else {
+		temp_rate_set2.numRates = 0;
+	}
+
+	/*
+	 * absolute sum of both num_rates should be less than 12. following
+	 * 16-bit sum avoids false codition where 8-bit arthematic overflow
+	 * might have caused total sum to be less than 12
+	 */
+	if (((uint16_t)temp_rate_set.numRates +
+		(uint16_t)temp_rate_set2.numRates) > 12) {
+		pe_err("more than 12 rates in CFG");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Handling of the rate set IEs is the following:
+	 * - keep only rates that we support and that the station supports
+	 * - sort and the rates into the pSta->rate array
+	 */
+
+	/* Copy all rates in temp_rate_set, there are 12 rates max */
+	for (i = 0; i < temp_rate_set2.numRates; i++)
+		temp_rate_set.rate[i + temp_rate_set.numRates] =
+			temp_rate_set2.rate[i];
+
+	temp_rate_set.numRates += temp_rate_set2.numRates;
+
+	/*
+	 * Sort rates in temp_rate_set (they are likely to be already sorted)
+	 * put the result in temp_rate_set2
+	 */
+	temp_rate_set2.numRates = 0;
+
+	for (i = 0; i < temp_rate_set.numRates; i++) {
+		min = 0;
+		val = 0xff;
+
+		for (j = 0; j < temp_rate_set.numRates; j++)
+			if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) < val) {
+				val = temp_rate_set.rate[j] & 0x7f;
+				min = j;
+			}
+
+		temp_rate_set2.rate[temp_rate_set2.numRates++] =
+			temp_rate_set.rate[min];
+		temp_rate_set.rate[min] = 0xff;
+	}
+
+	/*
+	 * Copy received rates in temp_rate_set, the parser has ensured
+	 * unicity of the rates so there cannot be more than 12
+	 */
+	for (i = 0; (i < oper_rate_set->numRates &&
+			 i < SIR_MAC_RATESET_EID_MAX); i++)
+		temp_rate_set.rate[i] = oper_rate_set->rate[i];
+
+	temp_rate_set.numRates = oper_rate_set->numRates;
+
+	pe_debug("Sum of SUPPORTED and EXTENDED Rate Set (%1d)",
+		temp_rate_set.numRates + ext_rate_set->numRates);
+
+	if (ext_rate_set->numRates &&
+		((temp_rate_set.numRates + ext_rate_set->numRates) > 12) &&
+		temp_rate_set.numRates < 12) {
+		int found = 0;
+		int tail = temp_rate_set.numRates;
+
+		for (i = 0; (i < ext_rate_set->numRates &&
+				i < SIR_MAC_RATESET_EID_MAX); i++) {
+			found = 0;
+			for (j = 0; j < (uint32_t) tail; j++) {
+				if ((temp_rate_set.rate[j] & 0x7F) ==
+					(ext_rate_set->rate[i] & 0x7F)) {
+					found = 1;
+					break;
+				}
+			}
+
+			if (!found) {
+				temp_rate_set.rate[temp_rate_set.numRates++] =
+						ext_rate_set->rate[i];
+				if (temp_rate_set.numRates >= 12)
+					break;
+			}
+		}
+	} else if (ext_rate_set->numRates &&
+		 ((temp_rate_set.numRates + ext_rate_set->numRates) <= 12)) {
+		for (j = 0; ((j < ext_rate_set->numRates) &&
+				 (j < SIR_MAC_RATESET_EID_MAX) &&
+				 ((i + j) < SIR_MAC_RATESET_EID_MAX)); j++)
+			temp_rate_set.rate[i + j] = ext_rate_set->rate[j];
+
+		temp_rate_set.numRates += ext_rate_set->numRates;
+	} else if (ext_rate_set->numRates) {
+		pe_debug("Relying only on the SUPPORTED Rate Set IE");
+	}
+
+	rates = &sta_ds->supportedRates;
+	qdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
+	for (i = 0; (i < temp_rate_set2.numRates &&
+			 i < SIR_MAC_RATESET_EID_MAX); i++) {
+		for (j = 0; (j < temp_rate_set.numRates &&
+				 j < SIR_MAC_RATESET_EID_MAX); j++) {
+			if ((temp_rate_set2.rate[i] & 0x7F) !=
+				(temp_rate_set.rate[j] & 0x7F))
+				continue;
+
+			if (sirIsArate(temp_rate_set2.rate[i] & 0x7f) &&
+				a_rate_index < SIR_NUM_11A_RATES) {
+				is_arate = 1;
+				rates->llaRates[a_rate_index++] =
+							temp_rate_set2.rate[i];
+			} else if ((b_rate_index < SIR_NUM_11B_RATES) &&
+				!(sirIsArate(temp_rate_set2.rate[i] & 0x7f))) {
+				rates->llbRates[b_rate_index++] =
+					temp_rate_set2.rate[i];
+			}
+			break;
+		}
+	}
+
+	/*
+	 * Now add the Polaris rates only when Proprietary rates are enabled.
+	 * compute the matching MCS rate set, if peer is 11n capable and self
+	 * mode is 11n
+	 */
+#ifdef FEATURE_WLAN_TDLS
+	if (sta_ds->mlmStaContext.htCapability)
+#else
+	if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
+		(sta_ds->mlmStaContext.htCapability))
+#endif
+	{
+		val_len = SIZE_OF_SUPPORTED_MCS_SET;
+		if (wlan_mlme_get_cfg_str(
+			mcs_set,
+			&mac_ctx->mlme_cfg->rates.supported_mcs_set,
+			&val_len) != QDF_STATUS_SUCCESS) {
+			pe_err("could not retrieve supportedMCSet");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (session_entry->nss == NSS_1x1_MODE)
+			mcs_set[1] = 0;
+
+		for (i = 0; i < val_len; i++)
+			sta_ds->supportedRates.supportedMCSSet[i] =
+				mcs_set[i] & supported_mcs_set[i];
+
+		pe_debug("MCS Rate Set Bitmap from CFG and DPH: ");
+		for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) {
+			pe_debug("%x %x ", mcs_set[i],
+			    sta_ds->supportedRates.supportedMCSSet[i]);
+		}
+	}
+	lim_populate_vht_mcs_set(mac_ctx, &sta_ds->supportedRates, vht_caps,
+				 session_entry, session_entry->nss);
+	lim_populate_he_mcs_set(mac_ctx, &sta_ds->supportedRates, he_caps,
+				session_entry, session_entry->nss);
+	/*
+	 * Set the erpEnabled bit if the phy is in G mode and at least
+	 * one A rate is supported
+	 */
+	if ((phy_mode == WNI_CFG_PHY_MODE_11G) && is_arate)
+		sta_ds->erpEnabled = eHAL_SET;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_populate_vht_caps() - populates vht capabilities based on input
+ *        capabilities
+ * @input_caps: input capabilities based on which we format the vht
+ *      capabilities
+ *
+ * function to populate the supported vht capabilities.
+ *
+ * Return: vht capabilities derived based on input parameters.
+ */
+static uint32_t lim_populate_vht_caps(tDot11fIEVHTCaps input_caps)
+{
+	uint32_t vht_caps;
+
+	vht_caps = ((input_caps.maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
+			(input_caps.supportedChannelWidthSet <<
+				 SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
+			(input_caps.ldpcCodingCap <<
+				SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
+			(input_caps.shortGI80MHz <<
+				 SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
+			(input_caps.shortGI160and80plus80MHz <<
+				SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
+			(input_caps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) |
+			(input_caps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) |
+			(input_caps.suBeamFormerCap <<
+				SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
+			(input_caps.suBeamformeeCap <<
+				SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
+			(input_caps.csnofBeamformerAntSup <<
+				SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
+			(input_caps.numSoundingDim <<
+				SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
+			(input_caps.muBeamformerCap <<
+				SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) |
+			(input_caps.muBeamformeeCap <<
+				SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
+			(input_caps.vhtTXOPPS <<
+				SIR_MAC_VHT_CAP_TXOPPS) |
+			(input_caps.htcVHTCap <<
+				 SIR_MAC_VHT_CAP_HTC_CAP) |
+			(input_caps.maxAMPDULenExp <<
+				SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
+			(input_caps.vhtLinkAdaptCap <<
+				SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
+			(input_caps.rxAntPattern <<
+				SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
+			(input_caps.txAntPattern <<
+				SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
+			(input_caps.reserved1 <<
+				SIR_MAC_VHT_CAP_RESERVED2));
+
+	return vht_caps;
+}
+
+/**
+ * lim_update_he_stbc_capable() - Update stbc capable flag based on
+ * HE capability
+ * @add_sta_params: add sta related parameters
+ *
+ * Update stbc cpable flag based on HE capability
+ *
+ * Return: None
+ */
+#ifdef WLAN_FEATURE_11AX
+static void lim_update_he_stbc_capable(tpAddStaParams add_sta_params)
+{
+	if (add_sta_params &&
+	    add_sta_params->he_capable &&
+	    add_sta_params->stbc_capable)
+		add_sta_params->stbc_capable =
+			add_sta_params->he_config.rx_stbc_lt_80mhz;
+}
+#else
+static void lim_update_he_stbc_capable(tpAddStaParams add_sta_params)
+{}
+#endif
+
+/**
+ * lim_add_sta()- called to add an STA context at hardware
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @update_entry: set to true for updating the entry
+ * @session_entry: pe session entry
+ *
+ * This function is called to add an STA context at hardware
+ * whenever a STA is (Re) Associated.
+ *
+ * Return: QDF_STATUS_SUCCESS on success else QDF_STATUS failure codes
+ */
+
+QDF_STATUS
+lim_add_sta(tpAniSirGlobal mac_ctx,
+	tpDphHashNode sta_ds, uint8_t update_entry, tpPESession session_entry)
+{
+	tpAddStaParams add_sta_params = NULL;
+	struct scheduler_msg msg_q = {0};
+	QDF_STATUS ret_code = QDF_STATUS_SUCCESS;
+	tSirMacAddr sta_mac, *sta_Addr;
+	tpSirAssocReq assoc_req;
+	uint8_t i, nw_type_11b = 0;
+	tLimIbssPeerNode *peer_node; /* for IBSS mode */
+	const uint8_t *p2p_ie = NULL;
+	tDot11fIEVHTCaps vht_caps;
+
+	sir_copy_mac_addr(sta_mac, session_entry->selfMacAddr);
+
+	pe_debug("sessionid: %d update_entry = %d limsystemrole = %d",
+		session_entry->smeSessionId, update_entry,
+		GET_LIM_SYSTEM_ROLE(session_entry));
+
+	add_sta_params = qdf_mem_malloc(sizeof(tAddStaParams));
+	if (!add_sta_params)
+		return QDF_STATUS_E_NOMEM;
+
+	if (LIM_IS_AP_ROLE(session_entry) || LIM_IS_IBSS_ROLE(session_entry) ||
+		LIM_IS_NDI_ROLE(session_entry))
+		sta_Addr = &sta_ds->staAddr;
+#ifdef FEATURE_WLAN_TDLS
+	/* SystemRole shouldn't be matter if staType is TDLS peer */
+	else if (STA_ENTRY_TDLS_PEER == sta_ds->staType)
+		sta_Addr = &sta_ds->staAddr;
+#endif
+	else
+		sta_Addr = &sta_mac;
+
+	pe_debug(MAC_ADDRESS_STR ": Subtype(Assoc/Reassoc): %d",
+		MAC_ADDR_ARRAY(*sta_Addr), sta_ds->mlmStaContext.subType);
+
+	qdf_mem_copy((uint8_t *) add_sta_params->staMac,
+		     (uint8_t *) *sta_Addr, sizeof(tSirMacAddr));
+	qdf_mem_copy((uint8_t *) add_sta_params->bssId,
+		     session_entry->bssId, sizeof(tSirMacAddr));
+	qdf_mem_copy(&add_sta_params->capab_info,
+		     &sta_ds->mlmStaContext.capabilityInfo,
+		     sizeof(add_sta_params->capab_info));
+
+	/* Copy legacy rates */
+	qdf_mem_copy((uint8_t *) &add_sta_params->supportedRates,
+		     (uint8_t *) &sta_ds->supportedRates,
+		     sizeof(tSirSupportedRates));
+
+	add_sta_params->assocId = sta_ds->assocId;
+
+	add_sta_params->wmmEnabled = sta_ds->qosMode;
+	add_sta_params->listenInterval = sta_ds->mlmStaContext.listenInterval;
+	add_sta_params->shortPreambleSupported = sta_ds->shortPreambleEnabled;
+	if (LIM_IS_AP_ROLE(session_entry) &&
+	   (sta_ds->mlmStaContext.subType == LIM_REASSOC)) {
+		/*
+		 * TBD - need to remove this REASSOC check
+		 * after fixinf rmmod issue
+		 */
+		add_sta_params->updateSta = sta_ds->mlmStaContext.updateContext;
+	}
+	sta_ds->valid = 0;
+	sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+
+	pe_debug("Assoc ID: %d wmmEnabled: %d listenInterval: %d"
+		 " shortPreambleSupported: %d", add_sta_params->assocId,
+		add_sta_params->wmmEnabled, add_sta_params->listenInterval,
+		add_sta_params->shortPreambleSupported);
+	/* This will indicate HAL to "allocate" a new STA index */
+#ifdef FEATURE_WLAN_TDLS
+	/*
+	 * As there is corner case in-between add_sta and change_sta,if del_sta
+	 * for other staIdx happened, firmware return wrong staIdx
+	 * (recently removed staIdx). Until we get a confirmation from the
+	 * firmware team it is now return correct staIdx for same sta_mac_addr
+	 * for update case, we want to get around it by passing valid staIdx
+	 * given by add_sta time.
+	 */
+	if ((STA_ENTRY_TDLS_PEER == sta_ds->staType) && (true == update_entry))
+		add_sta_params->staIdx = sta_ds->staIndex;
+	else
+#endif
+	add_sta_params->staIdx = STA_INVALID_IDX;
+	add_sta_params->staType = sta_ds->staType;
+
+	add_sta_params->updateSta = update_entry;
+
+	add_sta_params->status = QDF_STATUS_SUCCESS;
+	add_sta_params->respReqd = 1;
+
+	/* Update VHT/HT Capability */
+	if (LIM_IS_AP_ROLE(session_entry) ||
+	    LIM_IS_IBSS_ROLE(session_entry)) {
+		add_sta_params->htCapable = sta_ds->mlmStaContext.htCapability;
+		add_sta_params->vhtCapable =
+			 sta_ds->mlmStaContext.vhtCapability;
+	}
+#ifdef FEATURE_WLAN_TDLS
+	/* SystemRole shouldn't be matter if staType is TDLS peer */
+	else if (STA_ENTRY_TDLS_PEER == sta_ds->staType) {
+		add_sta_params->htCapable = sta_ds->mlmStaContext.htCapability;
+		add_sta_params->vhtCapable =
+			 sta_ds->mlmStaContext.vhtCapability;
+	}
+#endif
+	else {
+		add_sta_params->htCapable = session_entry->htCapability;
+		add_sta_params->vhtCapable = session_entry->vhtCapability;
+	}
+
+	pe_debug("StaIdx: %d updateSta: %d htcapable: %d vhtCapable: %d",
+		add_sta_params->staIdx, add_sta_params->updateSta,
+		add_sta_params->htCapable, add_sta_params->vhtCapable);
+
+	/*
+	 * If HT client is connected to SAP DUT and self cap is NSS = 2 then
+	 * disable ASYNC DBS scan by sending WMI_VDEV_PARAM_SMPS_INTOLERANT
+	 * to FW, because HT client's can't drop down chain using SMPS frames.
+	 */
+	if (!policy_mgr_is_hw_dbs_2x2_capable(mac_ctx->psoc) &&
+		LIM_IS_AP_ROLE(session_entry) &&
+		(STA_ENTRY_PEER == sta_ds->staType) &&
+		!add_sta_params->vhtCapable &&
+		(session_entry->nss == 2)) {
+		session_entry->ht_client_cnt++;
+		if (session_entry->ht_client_cnt == 1) {
+			pe_debug("setting SMPS intolrent vdev_param");
+			wma_cli_set_command(session_entry->smeSessionId,
+				(int)WMI_VDEV_PARAM_SMPS_INTOLERANT,
+				1, VDEV_CMD);
+		}
+	}
+
+	lim_update_sta_he_capable(mac_ctx, add_sta_params, sta_ds,
+				  session_entry);
+
+	add_sta_params->greenFieldCapable = sta_ds->htGreenfield;
+	add_sta_params->maxAmpduDensity = sta_ds->htAMpduDensity;
+	add_sta_params->maxAmpduSize = sta_ds->htMaxRxAMpduFactor;
+	add_sta_params->fDsssCckMode40Mhz = sta_ds->htDsssCckRate40MHzSupport;
+	add_sta_params->fShortGI20Mhz = sta_ds->htShortGI20Mhz;
+	add_sta_params->fShortGI40Mhz = sta_ds->htShortGI40Mhz;
+	add_sta_params->lsigTxopProtection = sta_ds->htLsigTXOPProtection;
+	add_sta_params->maxAmsduSize = sta_ds->htMaxAmsduLength;
+	add_sta_params->ch_width = sta_ds->htSupportedChannelWidthSet;
+	add_sta_params->mimoPS = sta_ds->htMIMOPSState;
+
+	pe_debug("greenFieldCapable: %d maxAmpduDensity: %d maxAmpduDensity: %d",
+		add_sta_params->greenFieldCapable,
+		add_sta_params->maxAmpduDensity, add_sta_params->maxAmpduSize);
+
+	pe_debug("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d fShortGI40Mhz: %d",
+		add_sta_params->fDsssCckMode40Mhz,
+		 add_sta_params->fShortGI20Mhz,	add_sta_params->fShortGI40Mhz);
+
+	pe_debug("lsigTxopProtection: %d maxAmsduSize: %d txChannelWidth: %d mimoPS: %d",
+		add_sta_params->lsigTxopProtection,
+		add_sta_params->maxAmsduSize, add_sta_params->ch_width,
+		add_sta_params->mimoPS);
+
+	if (add_sta_params->vhtCapable) {
+		if (sta_ds->vhtSupportedChannelWidthSet)
+			add_sta_params->ch_width =
+				sta_ds->vhtSupportedChannelWidthSet + 1;
+
+		add_sta_params->vhtSupportedRxNss = sta_ds->vhtSupportedRxNss;
+		if (LIM_IS_AP_ROLE(session_entry) ||
+				LIM_IS_P2P_DEVICE_GO(session_entry))
+			add_sta_params->vhtSupportedRxNss = QDF_MIN(
+					add_sta_params->vhtSupportedRxNss,
+					session_entry->nss);
+		add_sta_params->vhtTxBFCapable =
+#ifdef FEATURE_WLAN_TDLS
+			((STA_ENTRY_PEER == sta_ds->staType)
+			 || (STA_ENTRY_TDLS_PEER == sta_ds->staType)) ?
+				 sta_ds->vhtBeamFormerCapable :
+				 session_entry->vht_config.su_beam_formee;
+#else
+			(STA_ENTRY_PEER == sta_ds->staType) ?
+				 sta_ds->vhtBeamFormerCapable :
+				 session_entry->vht_config.su_beam_formee;
+#endif
+		add_sta_params->enable_su_tx_bformer =
+			sta_ds->vht_su_bfee_capable;
+	}
+
+	pe_debug("TxChWidth %d vhtTxBFCap %d, su_bfer %d",
+		add_sta_params->ch_width, add_sta_params->vhtTxBFCapable,
+		add_sta_params->enable_su_tx_bformer);
+#ifdef FEATURE_WLAN_TDLS
+	if ((STA_ENTRY_PEER == sta_ds->staType) ||
+		(STA_ENTRY_TDLS_PEER == sta_ds->staType))
+#else
+	if (STA_ENTRY_PEER == sta_ds->staType)
+#endif
+	{
+		/*
+		 * peer STA get the LDPC capability from sta_ds,
+		 * which populated from
+		 * HT/VHT capability
+		 */
+		if (add_sta_params->vhtTxBFCapable
+		    && mac_ctx->lim.disableLDPCWithTxbfAP) {
+			add_sta_params->htLdpcCapable = 0;
+			add_sta_params->vhtLdpcCapable = 0;
+		} else {
+			if (session_entry->txLdpcIniFeatureEnabled & 0x1)
+				add_sta_params->htLdpcCapable =
+						sta_ds->htLdpcCapable;
+			else
+				add_sta_params->htLdpcCapable = 0;
+
+			if (session_entry->txLdpcIniFeatureEnabled & 0x2)
+				add_sta_params->vhtLdpcCapable =
+						sta_ds->vhtLdpcCapable;
+			else
+				add_sta_params->vhtLdpcCapable = 0;
+		}
+	} else if (STA_ENTRY_SELF == sta_ds->staType) {
+		/* For Self STA get the LDPC capability from config.ini */
+		add_sta_params->htLdpcCapable =
+			(session_entry->txLdpcIniFeatureEnabled & 0x01);
+		add_sta_params->vhtLdpcCapable =
+			((session_entry->txLdpcIniFeatureEnabled >> 1) & 0x01);
+	}
+
+	/* Update PE session ID */
+	add_sta_params->sessionId = session_entry->peSessionId;
+
+	/* Update SME session ID */
+	add_sta_params->smesessionId = session_entry->smeSessionId;
+
+	add_sta_params->maxTxPower = session_entry->maxTxPower;
+
+	if (session_entry->parsedAssocReq != NULL) {
+		uint16_t aid = sta_ds->assocId;
+		/* Get a copy of the already parsed Assoc Request */
+		assoc_req =
+			(tpSirAssocReq) session_entry->parsedAssocReq[aid];
+		if (assoc_req && assoc_req->addIEPresent
+		    && assoc_req->addIE.length) {
+			p2p_ie = limGetP2pIEPtr(mac_ctx,
+					assoc_req->addIE.addIEdata,
+					assoc_req->addIE.length);
+		}
+
+		add_sta_params->p2pCapableSta = (p2p_ie != NULL);
+		if (assoc_req && add_sta_params->htCapable) {
+			qdf_mem_copy(&add_sta_params->ht_caps,
+				     ((uint8_t *) &assoc_req->HTCaps) + 1,
+				     sizeof(add_sta_params->ht_caps));
+		}
+
+		if (assoc_req && add_sta_params->vhtCapable) {
+			if (assoc_req->vendor_vht_ie.VHTCaps.present)
+				vht_caps = assoc_req->vendor_vht_ie.VHTCaps;
+			else
+				vht_caps = assoc_req->VHTCaps;
+			add_sta_params->vht_caps =
+				lim_populate_vht_caps(vht_caps);
+		}
+
+		lim_add_he_cap(add_sta_params, assoc_req);
+
+	} else if (LIM_IS_IBSS_ROLE(session_entry)) {
+
+		/*
+		 * in IBSS mode, use peer node as the source of ht_caps
+		 * and vht_caps
+		 */
+		peer_node = lim_ibss_peer_find(mac_ctx, *sta_Addr);
+		if (!peer_node) {
+			pe_err("Can't find IBSS peer node for ADD_STA");
+			return QDF_STATUS_E_NOENT;
+		}
+
+		if (peer_node->atimIePresent) {
+			add_sta_params->atimIePresent =
+				 peer_node->atimIePresent;
+			add_sta_params->peerAtimWindowLength =
+				peer_node->peerAtimWindowLength;
+		}
+
+		add_sta_params->ht_caps =
+			(peer_node->htSupportedChannelWidthSet <<
+			 SIR_MAC_HT_CAP_CHWIDTH40_S) |
+			(peer_node->htGreenfield <<
+			 SIR_MAC_HT_CAP_GREENFIELD_S) |
+			(peer_node->htShortGI20Mhz <<
+			 SIR_MAC_HT_CAP_SHORTGI20MHZ_S) |
+			(peer_node->htShortGI40Mhz <<
+			 SIR_MAC_HT_CAP_SHORTGI40MHZ_S) |
+			(SIR_MAC_TXSTBC <<
+			 SIR_MAC_HT_CAP_TXSTBC_S) |
+			(SIR_MAC_RXSTBC <<
+			 SIR_MAC_HT_CAP_RXSTBC_S) |
+			(peer_node->htMaxAmsduLength <<
+			 SIR_MAC_HT_CAP_MAXAMSDUSIZE_S) |
+			(peer_node->htDsssCckRate40MHzSupport <<
+			 SIR_MAC_HT_CAP_DSSSCCK40_S);
+
+		add_sta_params->vht_caps =
+			 lim_populate_vht_caps(peer_node->VHTCaps);
+	}
+#ifdef FEATURE_WLAN_TDLS
+	if (STA_ENTRY_TDLS_PEER == sta_ds->staType) {
+		add_sta_params->ht_caps = sta_ds->ht_caps;
+		add_sta_params->vht_caps = sta_ds->vht_caps;
+
+		pe_debug("Sta type is TDLS_PEER, ht_caps: 0x%x, vht_caps: 0x%x",
+			  add_sta_params->ht_caps,
+			  add_sta_params->vht_caps);
+	}
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+	if (sta_ds->wmeEnabled &&
+	   (LIM_IS_AP_ROLE(session_entry) ||
+	   (STA_ENTRY_TDLS_PEER == sta_ds->staType)))
+#else
+	if (sta_ds->wmeEnabled && LIM_IS_AP_ROLE(session_entry))
+#endif
+	{
+		add_sta_params->uAPSD = 0;
+		/*
+		 * update UAPSD and send it to LIM to add STA
+		 * bitmap MSB <- LSB MSB 4 bits are for
+		 * trigger enabled AC setting and LSB 4 bits
+		 * are for delivery enabled AC setting
+		 * 7   6    5    4    3    2    1    0
+		 * BE  BK   VI   VO   BE   BK   VI   VO
+		 */
+		add_sta_params->uAPSD |=
+			sta_ds->qos.capability.qosInfo.acvo_uapsd;
+		add_sta_params->uAPSD |=
+			(sta_ds->qos.capability.qosInfo.acvi_uapsd << 1);
+		add_sta_params->uAPSD |=
+			(sta_ds->qos.capability.qosInfo.acbk_uapsd << 2);
+		add_sta_params->uAPSD |=
+			(sta_ds->qos.capability.qosInfo.acbe_uapsd << 3);
+		/*
+		 * making delivery enabled and
+		 * trigger enabled setting the same.
+		 */
+		add_sta_params->uAPSD |= add_sta_params->uAPSD << 4;
+
+		add_sta_params->maxSPLen =
+			sta_ds->qos.capability.qosInfo.maxSpLen;
+		pe_debug("uAPSD = 0x%x, maxSpLen = %d",
+			add_sta_params->uAPSD, add_sta_params->maxSPLen);
+	}
+#ifdef WLAN_FEATURE_11W
+	add_sta_params->rmfEnabled = sta_ds->rmfEnabled;
+	pe_debug("PMF enabled %d", add_sta_params->rmfEnabled);
+#endif
+
+	pe_debug("htLdpcCapable: %d vhtLdpcCapable: %d "
+			"p2pCapableSta: %d",
+		add_sta_params->htLdpcCapable, add_sta_params->vhtLdpcCapable,
+		add_sta_params->p2pCapableSta);
+
+	if (!add_sta_params->htLdpcCapable)
+		add_sta_params->ht_caps &= ~(1 << SIR_MAC_HT_CAP_ADVCODING_S);
+	if (!add_sta_params->vhtLdpcCapable)
+		add_sta_params->vht_caps &=
+			~(1 << SIR_MAC_VHT_CAP_LDPC_CODING_CAP);
+
+	/*
+	 * we need to defer the message until we get the
+	 * response back from HAL.
+	 */
+	if (add_sta_params->respReqd)
+		SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, false);
+
+	add_sta_params->nwType = session_entry->nwType;
+
+	if (!(add_sta_params->htCapable || add_sta_params->vhtCapable)) {
+		nw_type_11b = 1;
+		for (i = 0; i < SIR_NUM_11A_RATES; i++) {
+			if (sirIsArate(sta_ds->supportedRates.llaRates[i] &
+						0x7F)) {
+				nw_type_11b = 0;
+				break;
+			}
+		}
+		if (nw_type_11b)
+			add_sta_params->nwType = eSIR_11B_NW_TYPE;
+	}
+
+	if (add_sta_params->htCapable && session_entry->htConfig.ht_tx_stbc) {
+		struct sDot11fIEHTCaps *ht_caps = (struct sDot11fIEHTCaps *)
+			&add_sta_params->ht_caps;
+		if (ht_caps->rxSTBC)
+			add_sta_params->stbc_capable = 1;
+		else
+			add_sta_params->stbc_capable = 0;
+	}
+
+	if (add_sta_params->vhtCapable && add_sta_params->stbc_capable) {
+		struct sDot11fIEVHTCaps *vht_caps = (struct sDot11fIEVHTCaps *)
+			&add_sta_params->vht_caps;
+		if (vht_caps->rxSTBC)
+			add_sta_params->stbc_capable = 1;
+		else
+			add_sta_params->stbc_capable = 0;
+	}
+
+	lim_update_he_stbc_capable(add_sta_params);
+
+	msg_q.type = WMA_ADD_STA_REQ;
+	msg_q.reserved = 0;
+	msg_q.bodyptr = add_sta_params;
+	msg_q.bodyval = 0;
+
+	pe_debug("Sending WMA_ADD_STA_REQ for assocId %d", sta_ds->assocId);
+	MTRACE(mac_trace_msg_tx(mac_ctx, session_entry->peSessionId,
+			 msg_q.type));
+
+	ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q);
+	if (QDF_STATUS_SUCCESS != ret_code) {
+		if (add_sta_params->respReqd)
+			SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+		pe_err("ADD_STA_REQ for aId %d failed (reason %X)",
+			sta_ds->assocId, ret_code);
+		qdf_mem_free(add_sta_params);
+	}
+
+	return ret_code;
+}
+
+/**
+ * lim_del_sta()
+ *
+ ***FUNCTION:
+ * This function is called to delete an STA context at hardware
+ * whenever a STA is disassociated
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ * @param  pStaDs  - Pointer to the STA datastructure created by
+ *                   LIM and maintained by DPH
+ * @param  fRespReqd - flag to indicate whether the delete is synchronous (true)
+ *                   or not (false)
+ * @return retCode - Indicates success or failure return code
+ */
+
+QDF_STATUS
+lim_del_sta(tpAniSirGlobal pMac,
+	    tpDphHashNode pStaDs, bool fRespReqd, tpPESession psessionEntry)
+{
+	tpDeleteStaParams pDelStaParams = NULL;
+	struct scheduler_msg msgQ = {0};
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+
+	pDelStaParams = qdf_mem_malloc(sizeof(tDeleteStaParams));
+	if (!pDelStaParams)
+		return QDF_STATUS_E_NOMEM;
+
+	/*
+	 * 2G-AS platform: SAP associates with HT (11n)clients as 2x1 in 2G and
+	 * 2X2 in 5G
+	 * Non-2G-AS platform: SAP associates with HT (11n) clients as 2X2 in 2G
+	 * and 5G; and enable async dbs scan when all HT clients are gone
+	 * 5G-AS: Don't care
+	 */
+	if (!policy_mgr_is_hw_dbs_2x2_capable(pMac->psoc) &&
+		LIM_IS_AP_ROLE(psessionEntry) &&
+		(pStaDs->staType == STA_ENTRY_PEER) &&
+		!pStaDs->mlmStaContext.vhtCapability &&
+		(psessionEntry->nss == 2)) {
+		psessionEntry->ht_client_cnt--;
+		if (psessionEntry->ht_client_cnt == 0) {
+			pe_debug("clearing SMPS intolrent vdev_param");
+			wma_cli_set_command(psessionEntry->smeSessionId,
+				(int)WMI_VDEV_PARAM_SMPS_INTOLERANT,
+				0, VDEV_CMD);
+		}
+	}
+	/* */
+	/* DPH contains the STA index only for "peer" STA entries. */
+	/* LIM global contains "self" STA index */
+	/* Thus, */
+	/*    if( STA role ) */
+	/*      get STA index from LIM global */
+	/*    else */
+	/*      get STA index from DPH */
+	/* */
+
+#ifdef FEATURE_WLAN_TDLS
+	if (LIM_IS_STA_ROLE(psessionEntry) &&
+	    (pStaDs->staType != STA_ENTRY_TDLS_PEER))
+#else
+	if (LIM_IS_STA_ROLE(psessionEntry))
+#endif
+		pDelStaParams->staIdx = psessionEntry->staId;
+
+	else
+		pDelStaParams->staIdx = pStaDs->staIndex;
+
+	pDelStaParams->assocId = pStaDs->assocId;
+	pStaDs->valid = 0;
+
+	if (!fRespReqd)
+		pDelStaParams->respReqd = 0;
+	else {
+		if (!(IS_TDLS_PEER(pStaDs->staType))) {
+			/* when lim_del_sta is called from processSmeAssocCnf
+			 * then mlmState is already set properly. */
+			if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE !=
+				GET_LIM_STA_CONTEXT_MLM_STATE(pStaDs)) {
+				MTRACE(mac_trace
+					(pMac, TRACE_CODE_MLM_STATE,
+					 psessionEntry->peSessionId,
+					 eLIM_MLM_WT_DEL_STA_RSP_STATE));
+				SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs,
+					eLIM_MLM_WT_DEL_STA_RSP_STATE);
+			}
+			if (LIM_IS_STA_ROLE(psessionEntry)) {
+				MTRACE(mac_trace
+					(pMac, TRACE_CODE_MLM_STATE,
+					 psessionEntry->peSessionId,
+					 eLIM_MLM_WT_DEL_STA_RSP_STATE));
+
+				psessionEntry->limMlmState =
+					eLIM_MLM_WT_DEL_STA_RSP_STATE;
+
+			}
+		}
+
+		/* we need to defer the message until we get the
+		 * response back from HAL. */
+		SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+		pDelStaParams->respReqd = 1;
+	}
+
+	/* Update PE session ID */
+	pDelStaParams->sessionId = psessionEntry->peSessionId;
+	pDelStaParams->smesessionId = psessionEntry->smeSessionId;
+
+	pDelStaParams->staType = pStaDs->staType;
+	qdf_mem_copy((uint8_t *) pDelStaParams->staMac,
+		     (uint8_t *) pStaDs->staAddr, sizeof(tSirMacAddr));
+
+	pDelStaParams->status = QDF_STATUS_SUCCESS;
+	msgQ.type = WMA_DELETE_STA_REQ;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pDelStaParams;
+	msgQ.bodyval = 0;
+
+	pe_debug("Sessionid %d :Sending SIR_HAL_DELETE_STA_REQ "
+		 "for STAID: %X and AssocID: %d MAC : "
+		 MAC_ADDRESS_STR, pDelStaParams->sessionId,
+		pDelStaParams->staIdx, pDelStaParams->assocId,
+		MAC_ADDR_ARRAY(pStaDs->staAddr));
+
+	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		if (fRespReqd)
+			SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+		pe_err("Posting DELETE_STA_REQ to HAL failed, reason=%X",
+			retCode);
+		qdf_mem_free(pDelStaParams);
+	}
+
+	return retCode;
+}
+
+
+/**
+ * lim_add_sta_self()
+ *
+ ***FUNCTION:
+ * This function is called to add an STA context at hardware
+ * whenever a STA is (Re) Associated.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ * @param  pStaDs  - Pointer to the STA datastructure created by
+ *                   LIM and maintained by DPH
+ * @return retCode - Indicates success or failure return code
+ */
+
+QDF_STATUS
+lim_add_sta_self(tpAniSirGlobal pMac, uint16_t staIdx, uint8_t updateSta,
+		 tpPESession psessionEntry)
+{
+	tpAddStaParams pAddStaParams = NULL;
+	struct scheduler_msg msgQ = {0};
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	tSirMacAddr staMac;
+	uint32_t listenInterval = MLME_CFG_LISTEN_INTERVAL;
+	/*This self Sta dot 11 mode comes from the cfg and the expectation here is
+	 * that cfg carries the systemwide capability that device under
+	 * consideration can support. This capability gets plumbed into the cfg
+	 * cache at system initialization time via the .dat and .ini file override
+	 * mechanisms and will not change. If it does change, it is the
+	 * responsibility of SME to evict the selfSta and reissue a new AddStaSelf
+	 * command.*/
+	uint32_t selfStaDot11Mode = 0, selfTxWidth = 0;
+
+	wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode);
+	wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET,
+			 &selfTxWidth);
+	pe_debug("cfgDot11Mode: %d selfTxWidth: %d",
+		(int)selfStaDot11Mode, (int)selfTxWidth);
+	pe_debug("Roam Channel Bonding Mode %d",
+		(int)pMac->roam.configParam.uCfgDot11Mode);
+
+	sir_copy_mac_addr(staMac, psessionEntry->selfMacAddr);
+	pe_debug(MAC_ADDRESS_STR ": ", MAC_ADDR_ARRAY(staMac));
+	pAddStaParams = qdf_mem_malloc(sizeof(tAddStaParams));
+	if (!pAddStaParams)
+		return QDF_STATUS_E_NOMEM;
+
+	/* / Add STA context at MAC HW (BMU, RHP & TFP) */
+	qdf_mem_copy((uint8_t *) pAddStaParams->staMac,
+		     (uint8_t *) staMac, sizeof(tSirMacAddr));
+
+	qdf_mem_copy((uint8_t *) pAddStaParams->bssId,
+		     psessionEntry->bssId, sizeof(tSirMacAddr));
+
+	pAddStaParams->assocId = psessionEntry->limAID;
+	pAddStaParams->staType = STA_ENTRY_SELF;
+	pAddStaParams->status = QDF_STATUS_SUCCESS;
+	pAddStaParams->respReqd = 1;
+
+	/* Update  PE session ID */
+	pAddStaParams->sessionId = psessionEntry->peSessionId;
+
+	/* Update SME session ID */
+	pAddStaParams->smesessionId = psessionEntry->smeSessionId;
+
+	pAddStaParams->maxTxPower = psessionEntry->maxTxPower;
+
+	/* This will indicate HAL to "allocate" a new STA index */
+	pAddStaParams->staIdx = staIdx;
+	pAddStaParams->updateSta = updateSta;
+
+	pAddStaParams->shortPreambleSupported =
+					pMac->mlme_cfg->ht_caps.short_preamble;
+
+	lim_populate_own_rate_set(pMac, &pAddStaParams->supportedRates, NULL, false,
+				  psessionEntry, NULL, NULL);
+	if (IS_DOT11_MODE_HT(selfStaDot11Mode)) {
+		pAddStaParams->htCapable = true;
+#ifdef DISABLE_GF_FOR_INTEROP
+		if ((psessionEntry->pLimJoinReq != NULL)
+		    && (!psessionEntry->pLimJoinReq->bssDescription.
+			aniIndicator)) {
+			pe_err("Turning off Greenfield, when adding self entry");
+			pAddStaParams->greenFieldCapable =
+				WNI_CFG_GREENFIELD_CAPABILITY_DISABLE;
+		} else
+#endif
+		{
+			pAddStaParams->greenFieldCapable =
+				lim_get_ht_capability(pMac, eHT_GREENFIELD,
+						      psessionEntry);
+			pAddStaParams->ch_width =
+				pMac->roam.configParam.channelBondingMode5GHz;
+			pAddStaParams->mimoPS =
+				lim_get_ht_capability(pMac, eHT_MIMO_POWER_SAVE,
+						      psessionEntry);
+			pAddStaParams->rifsMode =
+				lim_get_ht_capability(pMac, eHT_RIFS_MODE,
+						      psessionEntry);
+			pAddStaParams->lsigTxopProtection =
+				lim_get_ht_capability(pMac, eHT_LSIG_TXOP_PROTECTION,
+						      psessionEntry);
+			pAddStaParams->maxAmpduDensity =
+				lim_get_ht_capability(pMac, eHT_MPDU_DENSITY,
+						      psessionEntry);
+			pAddStaParams->maxAmpduSize =
+				lim_get_ht_capability(pMac, eHT_MAX_RX_AMPDU_FACTOR,
+						      psessionEntry);
+			pAddStaParams->maxAmsduSize =
+				lim_get_ht_capability(pMac, eHT_MAX_AMSDU_LENGTH,
+						      psessionEntry);
+			pAddStaParams->max_amsdu_num =
+				lim_get_ht_capability(pMac, eHT_MAX_AMSDU_NUM,
+						      psessionEntry);
+			pAddStaParams->fDsssCckMode40Mhz =
+				lim_get_ht_capability(pMac, eHT_DSSS_CCK_MODE_40MHZ,
+						      psessionEntry);
+			pAddStaParams->fShortGI20Mhz =
+					psessionEntry->htConfig.ht_sgi20;
+			pAddStaParams->fShortGI40Mhz =
+					psessionEntry->htConfig.ht_sgi40;
+			pe_debug("greenFieldCapable: %d maxAmpduDensity: %d "
+				 "maxAmpduSize: %d",
+				pAddStaParams->greenFieldCapable,
+				pAddStaParams->maxAmpduDensity,
+				pAddStaParams->maxAmpduSize);
+
+			pe_debug("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d "
+				 "fShortGI40Mhz: %d lsigTxopProtection: %d",
+				pAddStaParams->fDsssCckMode40Mhz,
+				pAddStaParams->fShortGI20Mhz,
+				pAddStaParams->fShortGI40Mhz,
+				pAddStaParams->lsigTxopProtection);
+
+			pe_debug("maxAmsduSize: %d txChannelWidth: %d mimoPS: %d rifsMode %d",
+				pAddStaParams->maxAmsduSize,
+				pAddStaParams->ch_width,
+				pAddStaParams->mimoPS, pAddStaParams->rifsMode);
+		}
+	}
+	pAddStaParams->vhtCapable = IS_DOT11_MODE_VHT(selfStaDot11Mode);
+	if (pAddStaParams->vhtCapable) {
+		pAddStaParams->ch_width =
+			psessionEntry->ch_width;
+		pe_debug("VHT WIDTH SET %d", pAddStaParams->ch_width);
+	}
+	pAddStaParams->vhtTxBFCapable =
+		psessionEntry->vht_config.su_beam_formee;
+	pAddStaParams->enable_su_tx_bformer =
+		psessionEntry->vht_config.su_beam_former;
+	pe_debug("vhtCapable: %d vhtTxBFCapable %d, su_bfer %d",
+		pAddStaParams->vhtCapable, pAddStaParams->vhtTxBFCapable,
+		pAddStaParams->enable_su_tx_bformer);
+
+	/* In 11ac mode, the hardware is capable of supporting 128K AMPDU size */
+	if (IS_DOT11_MODE_VHT(selfStaDot11Mode))
+		pAddStaParams->maxAmpduSize =
+		pMac->mlme_cfg->vht_caps.vht_cap_info.ampdu_len_exponent;
+
+	pAddStaParams->vhtTxMUBformeeCapable =
+				psessionEntry->vht_config.mu_beam_formee;
+	pAddStaParams->enableVhtpAid = psessionEntry->enableVhtpAid;
+	pAddStaParams->enableAmpduPs = psessionEntry->enableAmpduPs;
+	pAddStaParams->enableHtSmps = (psessionEntry->enableHtSmps &&
+				(!psessionEntry->supported_nss_1x1));
+	pAddStaParams->htSmpsconfig = psessionEntry->htSmpsvalue;
+	pAddStaParams->send_smps_action =
+		psessionEntry->send_smps_action;
+
+	/* For Self STA get the LDPC capability from session i.e config.ini */
+	pAddStaParams->htLdpcCapable =
+		(psessionEntry->txLdpcIniFeatureEnabled & 0x01);
+	pAddStaParams->vhtLdpcCapable =
+		((psessionEntry->txLdpcIniFeatureEnabled >> 1) & 0x01);
+
+	listenInterval = pMac->mlme_cfg->sap_cfg.listen_interval;
+	pAddStaParams->listenInterval = (uint16_t) listenInterval;
+
+	if (QDF_P2P_CLIENT_MODE == psessionEntry->pePersona) {
+		pAddStaParams->p2pCapableSta = 1;
+	}
+
+	pe_debug(" StaIdx: %d updateSta = %d htcapable = %d ",
+		pAddStaParams->staIdx, pAddStaParams->updateSta,
+		pAddStaParams->htCapable);
+
+	pe_debug("htLdpcCapable: %d vhtLdpcCapable: %d "
+			       "p2pCapableSta: %d",
+		pAddStaParams->htLdpcCapable, pAddStaParams->vhtLdpcCapable,
+		pAddStaParams->p2pCapableSta);
+
+	if (psessionEntry->isNonRoamReassoc) {
+		pAddStaParams->nonRoamReassoc = 1;
+		psessionEntry->isNonRoamReassoc = 0;
+	}
+	pe_debug("sessionid: %d  Assoc ID: %d listenInterval = %d "
+			       "shortPreambleSupported: %d",
+		psessionEntry->smeSessionId, pAddStaParams->assocId,
+		pAddStaParams->listenInterval,
+		pAddStaParams->shortPreambleSupported);
+
+	if (IS_DOT11_MODE_HE(selfStaDot11Mode))
+		lim_add_self_he_cap(pAddStaParams, psessionEntry);
+
+	msgQ.type = WMA_ADD_STA_REQ;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pAddStaParams;
+	msgQ.bodyval = 0;
+
+	pe_debug(MAC_ADDRESS_STR ":Sessionid %d : "
+			       "Sending WMA_ADD_STA_REQ. (aid %d)",
+		MAC_ADDR_ARRAY(pAddStaParams->staMac),
+		pAddStaParams->sessionId, pAddStaParams->assocId);
+	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		pe_err("Posting WMA_ADD_STA_REQ to HAL failed, reason=%X",
+			retCode);
+		qdf_mem_free(pAddStaParams);
+	}
+	return retCode;
+}
+
+/**
+ * limTeardownInfraBSS()
+ *
+ ***FUNCTION:
+ * This function is called by various LIM functions to teardown
+ * an established Infrastructure BSS
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_teardown_infra_bss(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	tSirMacAddr bcAddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+	/**
+	 * Send Broadcast Disassociate frame with
+	 * 'leaving BSS' reason.
+	 */
+	lim_send_disassoc_mgmt_frame(pMac,
+				     eSIR_MAC_DISASSOC_LEAVING_BSS_REASON,
+				     bcAddr, psessionEntry, false);
+} /*** end lim_teardown_infra_bss() ***/
+
+/**
+ * lim_handle_cnf_wait_timeout()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue to handle
+ * various confirmation failure cases.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  pStaDs - Pointer to a sta descriptor
+ * @return None
+ */
+
+void lim_handle_cnf_wait_timeout(tpAniSirGlobal pMac, uint16_t staId)
+{
+	tpDphHashNode pStaDs;
+	tpPESession psessionEntry = NULL;
+
+	psessionEntry = pe_find_session_by_session_id(pMac,
+			pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+	pStaDs = dph_get_hash_entry(pMac, staId, &psessionEntry->dph.dphHashTable);
+
+	if (pStaDs == NULL) {
+		pe_err("No STA context in SIR_LIM_CNF_WAIT_TIMEOUT");
+		return;
+	}
+
+	switch (pStaDs->mlmStaContext.mlmState) {
+	case eLIM_MLM_WT_ASSOC_CNF_STATE:
+		pe_debug("Did not receive Assoc Cnf in eLIM_MLM_WT_ASSOC_CNF_STATE sta Assoc id %d",
+				pStaDs->assocId);
+		lim_print_mac_addr(pMac, pStaDs->staAddr, LOGD);
+
+		if (LIM_IS_AP_ROLE(psessionEntry)) {
+			lim_reject_association(pMac, pStaDs->staAddr,
+					       pStaDs->mlmStaContext.subType,
+					       true,
+					       pStaDs->mlmStaContext.authType,
+					       pStaDs->assocId, true,
+					       eSIR_MAC_UNSPEC_FAILURE_STATUS,
+					       psessionEntry);
+		}
+		break;
+
+	default:
+		pe_warn("Received CNF_WAIT_TIMEOUT in state %d",
+			pStaDs->mlmStaContext.mlmState);
+	}
+}
+
+/**
+ * lim_delete_dph_hash_entry()- function to delete dph hash entry
+ * @mac_ctx: pointer to global mac structure
+ * @sta_addr: peer station address
+ * @sta_id: id assigned to peer station
+ * @session_entry: pe session entry
+ *
+ * This function is called whenever we need to delete
+ * the dph hash entry
+ *
+ * Return: none
+ */
+
+void
+lim_delete_dph_hash_entry(tpAniSirGlobal mac_ctx, tSirMacAddr sta_addr,
+				 uint16_t sta_id, tpPESession session_entry)
+{
+	uint16_t aid;
+	tpDphHashNode sta_ds;
+	tUpdateBeaconParams beacon_params;
+
+	qdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
+	beacon_params.paramChangeBitmap = 0;
+	lim_deactivate_and_change_per_sta_id_timer(mac_ctx, eLIM_CNF_WAIT_TIMER,
+		 sta_id);
+	if (NULL == session_entry) {
+		pe_err("NULL session_entry");
+		return;
+	}
+
+	beacon_params.bssIdx = session_entry->bssIdx;
+	sta_ds = dph_lookup_hash_entry(mac_ctx, sta_addr, &aid,
+			 &session_entry->dph.dphHashTable);
+
+	if (sta_ds == NULL) {
+		pe_err("sta_ds is NULL");
+		return;
+	}
+
+	pe_debug("Deleting DPH Hash entry for STAID: %X", sta_id);
+	/*
+	 * update the station count and perform associated actions
+	 * do this before deleting the dph hash entry
+	 */
+	lim_util_count_sta_del(mac_ctx, sta_ds, session_entry);
+
+	if (LIM_IS_AP_ROLE(session_entry) || LIM_IS_IBSS_ROLE(session_entry)) {
+		if (LIM_IS_AP_ROLE(session_entry)) {
+			if (session_entry->gLimProtectionControl !=
+				MLME_FORCE_POLICY_PROTECTION_DISABLE)
+				lim_decide_ap_protection_on_delete(mac_ctx,
+					sta_ds, &beacon_params, session_entry);
+		}
+
+		if (sta_ds->non_ecsa_capable) {
+			if (session_entry->lim_non_ecsa_cap_num == 0) {
+				pe_debug("NonECSA sta 0, id %d is ecsa",
+					 sta_id);
+			} else {
+				session_entry->lim_non_ecsa_cap_num--;
+				pe_debug("reducing the non ECSA num to %d",
+					 session_entry->lim_non_ecsa_cap_num);
+			}
+		}
+
+		if (LIM_IS_IBSS_ROLE(session_entry))
+			lim_ibss_decide_protection_on_delete(mac_ctx, sta_ds,
+				     &beacon_params, session_entry);
+
+		lim_decide_short_preamble(mac_ctx, sta_ds, &beacon_params,
+					  session_entry);
+		lim_decide_short_slot(mac_ctx, sta_ds, &beacon_params,
+				      session_entry);
+
+		/* Send message to HAL about beacon parameter change. */
+		pe_debug("param bitmap: %d", beacon_params.paramChangeBitmap);
+		if (beacon_params.paramChangeBitmap &&
+			(false ==
+			 mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
+			sch_set_fixed_beacon_fields(mac_ctx, session_entry);
+			lim_send_beacon_params(mac_ctx, &beacon_params,
+					       session_entry);
+		}
+
+		lim_obss_send_detection_cfg(mac_ctx, session_entry, false);
+
+#ifdef WLAN_FEATURE_11W
+		if (sta_ds->rmfEnabled) {
+			pe_debug("delete pmf timer sta-idx:%d assoc-id:%d",
+				 sta_ds->staIndex, sta_ds->assocId);
+			tx_timer_delete(&sta_ds->pmfSaQueryTimer);
+		}
+#endif
+	}
+
+	if (dph_delete_hash_entry(mac_ctx, sta_addr, sta_id,
+		 &session_entry->dph.dphHashTable) != QDF_STATUS_SUCCESS)
+		pe_err("error deleting hash entry");
+}
+
+/**
+ * lim_check_and_announce_join_success()- function to check if the received
+ * Beacon/Probe Response is from the BSS that we're attempting to join.
+ * @mac: pointer to global mac structure
+ * @beacon_probe_rsp: pointer to reveived beacon/probe response frame
+ * @header: pointer to received management frame header
+ * @session_entry: pe session entry
+ *
+ * This function is called upon receiving Beacon/Probe Response
+ * frame in WT_JOIN_BEACON_STATE to check if the received
+ * Beacon/Probe Response is from the BSS that we're attempting
+ * to join.
+ * If the Beacon/Probe Response is indeed from the BSS we're
+ * attempting to join, join success is sent to SME.
+ *
+ * Return: none
+ */
+
+void
+lim_check_and_announce_join_success(tpAniSirGlobal mac_ctx,
+		tSirProbeRespBeacon *beacon_probe_rsp, tpSirMacMgmtHdr header,
+		tpPESession session_entry)
+{
+	tSirMacSSid current_ssid;
+	tLimMlmJoinCnf mlm_join_cnf;
+	uint32_t val;
+	uint32_t *noa_duration_from_beacon = NULL;
+	uint32_t *noa2_duration_from_beacon = NULL;
+	uint32_t noa;
+	uint32_t total_num_noa_desc = 0;
+
+	qdf_mem_copy(current_ssid.ssId,
+		     session_entry->ssId.ssId, session_entry->ssId.length);
+
+	current_ssid.length = (uint8_t) session_entry->ssId.length;
+
+	/*
+	 * Check for SSID only in probe response. Beacons may not carry
+	 * SSID information in hidden SSID case
+	 */
+	if (((SIR_MAC_MGMT_FRAME == header->fc.type) &&
+		(SIR_MAC_MGMT_PROBE_RSP == header->fc.subType)) &&
+		current_ssid.length &&
+		(qdf_mem_cmp((uint8_t *) &beacon_probe_rsp->ssId,
+				  (uint8_t *) &current_ssid,
+				  (uint8_t) (1 + current_ssid.length)))) {
+		/*
+		 * Received SSID does not match with the one we've.
+		 * Ignore received Beacon frame
+		 */
+		pe_debug("SSID received in Beacon does not match");
+#ifdef WLAN_DEBUG
+		mac_ctx->lim.gLimBcnSSIDMismatchCnt++;
+#endif
+		return;
+	}
+
+	if (!LIM_IS_STA_ROLE(session_entry))
+		return;
+
+	pe_debug("Received Beacon/PR with matching BSSID:%pM PESessionID %d",
+			session_entry->bssId, session_entry->peSessionId);
+
+	/* Deactivate Join Failure timer */
+	lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);
+	/* Deactivate Periodic Join timer */
+	lim_deactivate_and_change_timer(mac_ctx,
+		eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
+
+	if (QDF_P2P_CLIENT_MODE == session_entry->pePersona &&
+		beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.present) {
+
+		noa_duration_from_beacon = (uint32_t *)
+		(beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.NoADesc + 1);
+
+		if (beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.num_NoADesc)
+			total_num_noa_desc =
+				beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.
+				num_NoADesc / SIZE_OF_NOA_DESCRIPTOR;
+
+		noa = *noa_duration_from_beacon;
+
+		if (total_num_noa_desc > 1) {
+			noa2_duration_from_beacon = (uint32_t *)
+			(beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.NoADesc +
+				SIZE_OF_NOA_DESCRIPTOR + 1);
+			noa += *noa2_duration_from_beacon;
+		}
+
+		/*
+		 * If MAX Noa exceeds 3 secs we will consider only 3 secs to
+		 * avoid arbitrary values in noa duration field
+		 */
+		noa = noa > MAX_NOA_PERIOD_IN_MICROSECS ?
+				MAX_NOA_PERIOD_IN_MICROSECS : noa;
+		noa = noa / 1000; /* Convert to ms */
+
+		session_entry->defaultAuthFailureTimeout =
+			mac_ctx->mlme_cfg->timeouts.auth_failure_timeout;
+		val = mac_ctx->mlme_cfg->timeouts.auth_failure_timeout + noa;
+		if (cfg_in_range(CFG_AUTH_FAILURE_TIMEOUT, val))
+			mac_ctx->mlme_cfg->timeouts.auth_failure_timeout = val;
+		else
+			mac_ctx->mlme_cfg->timeouts.auth_failure_timeout =
+				cfg_default(CFG_AUTH_FAILURE_TIMEOUT);
+	} else {
+		session_entry->defaultAuthFailureTimeout = 0;
+	}
+
+
+	/*
+	 * Check if MBO Association disallowed subattr is present and post
+	 * failure status to LIM if present
+	 */
+	if (!session_entry->ignore_assoc_disallowed &&
+			beacon_probe_rsp->assoc_disallowed) {
+		pe_err("Connection fails due to assoc disallowed reason(%d):%pM PESessionID %d",
+				beacon_probe_rsp->assoc_disallowed_reason,
+				session_entry->bssId,
+				session_entry->peSessionId);
+		mlm_join_cnf.resultCode = eSIR_SME_ASSOC_REFUSED;
+		mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+		session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
+		mlm_join_cnf.sessionId = session_entry->peSessionId;
+		if (session_entry->pLimMlmJoinReq) {
+			qdf_mem_free(session_entry->pLimMlmJoinReq);
+			session_entry->pLimMlmJoinReq = NULL;
+		}
+		lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
+				(uint32_t *) &mlm_join_cnf);
+		return;
+	}
+
+	/* Update Beacon Interval at CFG database */
+
+	if (beacon_probe_rsp->HTCaps.present)
+		lim_update_sta_run_time_ht_capability(mac_ctx,
+			 &beacon_probe_rsp->HTCaps);
+	if (beacon_probe_rsp->HTInfo.present)
+		lim_update_sta_run_time_ht_info(mac_ctx,
+			 &beacon_probe_rsp->HTInfo, session_entry);
+	session_entry->limMlmState = eLIM_MLM_JOINED_STATE;
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+			 session_entry->peSessionId, eLIM_MLM_JOINED_STATE));
+
+	/*
+	 * update the capability info based on recently received beacon/probe
+	 * response frame
+	 */
+	session_entry->limCurrentBssCaps =
+		lim_get_u16((uint8_t *)&beacon_probe_rsp->capabilityInfo);
+
+	/*
+	 * Announce join success by sending
+	 * Join confirm to SME.
+	 */
+	mlm_join_cnf.resultCode = eSIR_SME_SUCCESS;
+	mlm_join_cnf.protStatusCode = eSIR_MAC_SUCCESS_STATUS;
+	/* Update PE sessionId */
+	mlm_join_cnf.sessionId = session_entry->peSessionId;
+	lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
+			     (uint32_t *) &mlm_join_cnf);
+
+	if ((IS_DOT11_MODE_VHT(session_entry->dot11mode)) &&
+		beacon_probe_rsp->vendor_vht_ie.VHTCaps.present) {
+		session_entry->is_vendor_specific_vhtcaps = true;
+		session_entry->vendor_specific_vht_ie_sub_type =
+			beacon_probe_rsp->vendor_vht_ie.sub_type;
+		pe_debug("VHT caps are present in vendor specific IE");
+	}
+
+	/* Update HS 2.0 Information Element */
+	if (beacon_probe_rsp->hs20vendor_ie.present) {
+		pe_debug("HS20 Indication Element Present, rel#:%u, id:%u",
+			beacon_probe_rsp->hs20vendor_ie.release_num,
+			beacon_probe_rsp->hs20vendor_ie.hs_id_present);
+		qdf_mem_copy(&session_entry->hs20vendor_ie,
+			&beacon_probe_rsp->hs20vendor_ie,
+			sizeof(tDot11fIEhs20vendor_ie) -
+			sizeof(beacon_probe_rsp->hs20vendor_ie.hs_id));
+		if (beacon_probe_rsp->hs20vendor_ie.hs_id_present)
+			qdf_mem_copy(&session_entry->hs20vendor_ie.hs_id,
+				&beacon_probe_rsp->hs20vendor_ie.hs_id,
+				sizeof(beacon_probe_rsp->hs20vendor_ie.hs_id));
+	}
+}
+
+/**
+ * lim_extract_ap_capabilities()
+ *
+ ***FUNCTION:
+ * This function is called to extract all of the AP's capabilities
+ * from the IEs received from it in Beacon/Probe Response frames
+ *
+ ***LOGIC:
+ * This routine mimics the lim_extract_ap_capability() API. The difference here
+ * is that this API returns the entire tSirProbeRespBeacon info as is. It is
+ * left to the caller of this API to use this info as required
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param   pMac         Pointer to Global MAC structure
+ * @param   pIE          Pointer to starting IE in Beacon/Probe Response
+ * @param   ieLen        Length of all IEs combined
+ * @param   beaconStruct A pointer to tSirProbeRespBeacon that needs to be
+ *                       populated
+ * @return  status       A status reporting QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS lim_extract_ap_capabilities(tpAniSirGlobal pMac,
+					  uint8_t *pIE,
+					  uint16_t ieLen,
+					  tpSirProbeRespBeacon beaconStruct)
+{
+	qdf_mem_set((uint8_t *) beaconStruct, sizeof(tSirProbeRespBeacon), 0);
+
+	pe_debug("The IE's being received are:");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				pIE, ieLen);
+	/* Parse the Beacon IE's, Don't try to parse if we dont have anything in IE */
+	if (ieLen > 0) {
+		if (QDF_STATUS_SUCCESS !=
+		    sir_parse_beacon_ie(pMac, beaconStruct, pIE,
+					(uint32_t) ieLen)) {
+			pe_err("APCapExtract: Beacon parsing error!");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_del_bss()
+ *
+ ***FUNCTION:
+ * This function is called to delete BSS context at hardware
+ * whenever a STA is disassociated
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ * @param  pStaDs  - Pointer to the STA datastructure created by
+ *                   LIM and maintained by DPH
+ * @return retCode - Indicates success or failure return code
+ */
+
+QDF_STATUS
+lim_del_bss(tpAniSirGlobal pMac, tpDphHashNode pStaDs, uint16_t bssIdx,
+	    tpPESession psessionEntry)
+{
+	tpDeleteBssParams pDelBssParams = NULL;
+	struct scheduler_msg msgQ = {0};
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+
+	pDelBssParams = qdf_mem_malloc(sizeof(tDeleteBssParams));
+	if (!pDelBssParams)
+		return QDF_STATUS_E_NOMEM;
+
+	pDelBssParams->sessionId = psessionEntry->peSessionId; /* update PE session Id */
+
+	/* DPH was storing the AssocID in staID field, */
+	/* staID is actually assigned by HAL when AddSTA message is sent. */
+	if (pStaDs != NULL) {
+		pDelBssParams->bssIdx = pStaDs->bssId;
+		pStaDs->valid = 0;
+		pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+	} else
+		pDelBssParams->bssIdx = bssIdx;
+	psessionEntry->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+		       eLIM_MLM_WT_DEL_BSS_RSP_STATE));
+
+	if ((psessionEntry->peSessionId ==
+	     pMac->lim.limTimers.gLimJoinFailureTimer.sessionId)
+	    && (true ==
+		tx_timer_running(&pMac->lim.limTimers.gLimJoinFailureTimer))) {
+		lim_deactivate_and_change_timer(pMac, eLIM_JOIN_FAIL_TIMER);
+	}
+
+	pDelBssParams->status = QDF_STATUS_SUCCESS;
+	pDelBssParams->respReqd = 1;
+	qdf_mem_copy(pDelBssParams->bssid, psessionEntry->bssId,
+		     sizeof(tSirMacAddr));
+	pDelBssParams->smesessionId = psessionEntry->smeSessionId;
+	pe_debug("Sessionid %d : Sending HAL_DELETE_BSS_REQ "
+			  "for bss idx: %X BSSID:" MAC_ADDRESS_STR,
+		       pDelBssParams->sessionId, pDelBssParams->bssIdx,
+		       MAC_ADDR_ARRAY(psessionEntry->bssId));
+	/* we need to defer the message until we get the response back from HAL. */
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+	pe_debug("process_ho_fail = %d", psessionEntry->process_ho_fail);
+	if (psessionEntry->process_ho_fail)
+		msgQ.type = WMA_DELETE_BSS_HO_FAIL_REQ;
+	else
+		msgQ.type = WMA_DELETE_BSS_REQ;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pDelBssParams;
+	msgQ.bodyval = 0;
+
+	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+		pe_err("Posting DELETE_BSS_REQ to HAL failed, reason=%X",
+			retCode);
+		qdf_mem_free(pDelBssParams);
+	}
+
+	return retCode;
+}
+
+/**
+ * lim_update_vhtcaps_assoc_resp : Update VHT caps in assoc response.
+ * @mac_ctx Pointer to Global MAC structure
+ * @pAddBssParams: parameters required for add bss params.
+ * @vht_caps: VHT capabilities.
+ * @psessionEntry : session entry.
+ *
+ * Return : void
+ */
+static void lim_update_vhtcaps_assoc_resp(tpAniSirGlobal mac_ctx,
+		tpAddBssParams pAddBssParams,
+		tDot11fIEVHTCaps *vht_caps, tpPESession psessionEntry)
+{
+	pAddBssParams->staContext.vht_caps =
+		((vht_caps->maxMPDULen <<
+		  SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
+		 (vht_caps->supportedChannelWidthSet <<
+		  SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
+		 (vht_caps->ldpcCodingCap <<
+		  SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
+		 (vht_caps->shortGI80MHz <<
+		  SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
+		 (vht_caps->shortGI160and80plus80MHz <<
+		  SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
+		 (vht_caps->txSTBC <<
+		  SIR_MAC_VHT_CAP_TXSTBC) |
+		 (vht_caps->rxSTBC <<
+		  SIR_MAC_VHT_CAP_RXSTBC) |
+		 (vht_caps->suBeamFormerCap <<
+		  SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
+		 (vht_caps->suBeamformeeCap <<
+		  SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
+		 (vht_caps->csnofBeamformerAntSup <<
+		  SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
+		 (vht_caps->numSoundingDim <<
+		  SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
+		 (vht_caps->muBeamformerCap <<
+		  SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) |
+		 (vht_caps->muBeamformeeCap <<
+		  SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
+		 (vht_caps->vhtTXOPPS <<
+		  SIR_MAC_VHT_CAP_TXOPPS) |
+		 (vht_caps->htcVHTCap <<
+		  SIR_MAC_VHT_CAP_HTC_CAP) |
+		 (vht_caps->maxAMPDULenExp <<
+		  SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
+		 (vht_caps->vhtLinkAdaptCap <<
+		  SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
+		 (vht_caps->rxAntPattern <<
+		  SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
+		 (vht_caps->txAntPattern <<
+		  SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
+		 (vht_caps->reserved1 <<
+		  SIR_MAC_VHT_CAP_RESERVED2));
+
+	pAddBssParams->staContext.maxAmpduSize =
+		SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(
+				pAddBssParams->staContext.vht_caps);
+
+	pe_debug("Updating VHT caps in assoc Response");
+}
+
+/**
+ * lim_update_vht_oper_assoc_resp : Update VHT Operations in assoc response.
+ * @mac_ctx Pointer to Global MAC structure
+ * @pAddBssParams: parameters required for add bss params.
+ * @vht_oper: VHT Operations to update.
+ * @psessionEntry : session entry.
+ *
+ * Return : void
+ */
+static void lim_update_vht_oper_assoc_resp(tpAniSirGlobal mac_ctx,
+		tpAddBssParams pAddBssParams,
+		tDot11fIEVHTOperation *vht_oper, tpPESession psessionEntry)
+{
+	if (vht_oper->chanWidth &&
+			psessionEntry->ch_width) {
+		pAddBssParams->ch_width = vht_oper->chanWidth + 1;
+
+		pAddBssParams->ch_center_freq_seg0 =
+			vht_oper->chanCenterFreqSeg1;
+
+		pAddBssParams->ch_center_freq_seg1 =
+			vht_oper->chanCenterFreqSeg2;
+	}
+	pe_debug("Updating VHT Operation in assoc Response");
+}
+
+#ifdef WLAN_SUPPORT_TWT
+/**
+ * lim_set_sta_ctx_twt() - Save the TWT settings in STA context
+ * @sta_ctx: Pointer to Station Context
+ * @session: Pointer to PE session
+ *
+ * Return: None
+ */
+static void lim_set_sta_ctx_twt(tAddStaParams *sta_ctx, tpPESession session)
+{
+	sta_ctx->twt_requestor = session->peer_twt_requestor;
+	sta_ctx->twt_responder = session->peer_twt_responder;
+}
+#else
+static inline void lim_set_sta_ctx_twt(tAddStaParams *sta_ctx,
+				       tpPESession session)
+{
+}
+#endif
+
+/**
+ * limSendAddBss()
+ *
+ ***FUNCTION:
+ *
+ ***LOGIC:
+ * 1) LIM receives eWNI_SME_JOIN_REQ
+ * 2) For a valid eWNI_SME_JOIN_REQ, LIM sends
+ * SIR_HAL_ADD_BSS_REQ to HAL
+ *
+ ***ASSUMPTIONS:
+ * JOIN REQ parameters are saved in pMac->lim.gLimMlmJoinReq
+ * ADD BSS parameters can be obtained from two sources:
+ * 1) pMac->lim.gLimMlmJoinReq
+ * 2) beaconStruct, passed as parameter
+ * So, if a reqd parameter is found in bssDescriptions
+ * then it is given preference over beaconStruct
+ *
+ ***NOTE:
+ *
+ * @param  pMac Pointer to Global MAC structure
+ *              pAssocRsp    contains the structured assoc/reassoc Response got from AP
+ *              beaconstruct        Has the ProbeRsp/Beacon structured details
+ *              bssDescription      bssDescription passed to PE from the SME
+ * @return None
+ */
+
+QDF_STATUS lim_sta_send_add_bss(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
+				   tpSchBeaconStruct pBeaconStruct,
+				   tpSirBssDescription bssDescription,
+				   uint8_t updateEntry, tpPESession psessionEntry)
+{
+	struct scheduler_msg msgQ = {0};
+	tpAddBssParams pAddBssParams = NULL;
+	uint32_t retCode;
+	tpDphHashNode pStaDs = NULL;
+	uint8_t chanWidthSupp = 0;
+	bool is_vht_cap_in_vendor_ie = false;
+	tDot11fIEVHTCaps *vht_caps = NULL;
+	tDot11fIEVHTOperation *vht_oper = NULL;
+	tAddStaParams *sta_context;
+	uint32_t listen_interval = MLME_CFG_LISTEN_INTERVAL;
+	struct mlme_vht_capabilities_info vht_cap_info;
+
+	vht_cap_info = pMac->mlme_cfg->vht_caps.vht_cap_info;
+
+	/* Package SIR_HAL_ADD_BSS_REQ message parameters */
+	pAddBssParams = qdf_mem_malloc(sizeof(tAddBssParams));
+	if (!pAddBssParams) {
+		retCode = QDF_STATUS_E_NOMEM;
+		goto returnFailure;
+	}
+
+	qdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
+		     sizeof(tSirMacAddr));
+	/* Fill in tAddBssParams selfMacAddr */
+	qdf_mem_copy(pAddBssParams->selfMacAddr,
+		     psessionEntry->selfMacAddr, sizeof(tSirMacAddr));
+
+	pe_debug("sessionid: %d updateEntry: %d limsystemrole: %d",
+		psessionEntry->smeSessionId, updateEntry,
+		GET_LIM_SYSTEM_ROLE(psessionEntry));
+
+	pe_debug("BSSID: " MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pAddBssParams->bssId));
+
+	pAddBssParams->bssType = eSIR_INFRASTRUCTURE_MODE;
+
+	pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
+
+	/* Update PE session ID */
+	pAddBssParams->sessionId = psessionEntry->peSessionId;
+
+	pAddBssParams->beaconInterval = bssDescription->beaconInterval;
+
+	pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
+	pAddBssParams->updateBss = updateEntry;
+
+	pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount;
+	pAddBssParams->cfParamSet.cfpPeriod =
+		pBeaconStruct->cfParamSet.cfpPeriod;
+	pAddBssParams->cfParamSet.cfpMaxDuration =
+		pBeaconStruct->cfParamSet.cfpMaxDuration;
+	pAddBssParams->cfParamSet.cfpDurRemaining =
+		pBeaconStruct->cfParamSet.cfpDurRemaining;
+
+	pAddBssParams->rateSet.numRates = pAssocRsp->supportedRates.numRates;
+	qdf_mem_copy(pAddBssParams->rateSet.rate,
+		     pAssocRsp->supportedRates.rate,
+		     pAssocRsp->supportedRates.numRates);
+
+	if (IS_DOT11_MODE_11B(psessionEntry->dot11mode) &&
+	    bssDescription->nwType != eSIR_11B_NW_TYPE) {
+		pAddBssParams->nwType = eSIR_11B_NW_TYPE;
+	} else {
+		pAddBssParams->nwType = bssDescription->nwType;
+	}
+
+	pAddBssParams->shortSlotTimeSupported =
+		(uint8_t) pAssocRsp->capabilityInfo.shortSlotTime;
+	pAddBssParams->llaCoexist =
+		(uint8_t) psessionEntry->beaconParams.llaCoexist;
+	pAddBssParams->llbCoexist =
+		(uint8_t) psessionEntry->beaconParams.llbCoexist;
+	pAddBssParams->llgCoexist =
+		(uint8_t) psessionEntry->beaconParams.llgCoexist;
+	pAddBssParams->ht20Coexist =
+		(uint8_t) psessionEntry->beaconParams.ht20Coexist;
+
+	pe_debug("BSS Type %d Beacon Interval: %d dtimPeriod: %d "
+		 "cfpCount: %d", pAddBssParams->bssType,
+		pAddBssParams->beaconInterval, pAddBssParams->dtimPeriod,
+		pAddBssParams->cfParamSet.cfpCount);
+
+	pe_debug("cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining: %d "
+		 "numRates: %d", pAddBssParams->cfParamSet.cfpPeriod,
+		pAddBssParams->cfParamSet.cfpMaxDuration,
+		pAddBssParams->cfParamSet.cfpDurRemaining,
+		pAddBssParams->rateSet.numRates);
+
+	pe_debug("nwType:%d shortSlotTimeSupported: %d llaCoexist: %d "
+		"llbCoexist: %d llgCoexist: %d ht20Coexist: %d",
+		pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported,
+		pAddBssParams->llaCoexist, pAddBssParams->llbCoexist,
+		pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist);
+
+	pAddBssParams->dot11_mode = psessionEntry->dot11mode;
+	pe_debug("dot11_mode: %d", pAddBssParams->dot11_mode);
+
+	if (IS_DOT11_MODE_HT(psessionEntry->dot11mode))
+		chanWidthSupp = lim_get_ht_capability(pMac,
+						eHT_SUPPORTED_CHANNEL_WIDTH_SET,
+						psessionEntry);
+
+	/* Use the advertised capabilities from the received beacon/PR */
+	if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
+	    && (pAssocRsp->HTCaps.present)) {
+		pAddBssParams->htCapable = pAssocRsp->HTCaps.present;
+		pe_debug("htCapable: %d", pAddBssParams->htCapable);
+		if (pBeaconStruct->HTInfo.present) {
+			pAddBssParams->htOperMode =
+				(tSirMacHTOperatingMode) pAssocRsp->HTInfo.opMode;
+			pAddBssParams->dualCTSProtection =
+				(uint8_t) pAssocRsp->HTInfo.dualCTSProtection;
+
+			if ((pAssocRsp->HTCaps.supportedChannelWidthSet)
+			    && (chanWidthSupp)) {
+				pAddBssParams->ch_width = (uint8_t)
+					pAssocRsp->HTInfo.recommendedTxWidthSet;
+				if (pAssocRsp->HTInfo.secondaryChannelOffset ==
+						PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+					pAddBssParams->ch_center_freq_seg0 =
+						bssDescription->channelId + 2;
+				else if (pAssocRsp->HTInfo.secondaryChannelOffset ==
+						PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+					pAddBssParams->ch_center_freq_seg0 =
+						bssDescription->channelId - 2;
+			} else {
+				pAddBssParams->ch_width = CH_WIDTH_20MHZ;
+				pAddBssParams->ch_center_freq_seg0 = 0;
+			}
+			pAddBssParams->llnNonGFCoexist =
+				(uint8_t) pAssocRsp->HTInfo.nonGFDevicesPresent;
+			pAddBssParams->fLsigTXOPProtectionFullSupport =
+				(uint8_t) pAssocRsp->HTInfo.
+				lsigTXOPProtectionFullSupport;
+			pAddBssParams->fRIFSMode = pAssocRsp->HTInfo.rifsMode;
+
+			pe_debug("htOperMode: %d dualCTSProtection: %d txChannelWidth: %d center_freq_0: %d",
+				pAddBssParams->htOperMode,
+				pAddBssParams->dualCTSProtection,
+				pAddBssParams->ch_width,
+				pAddBssParams->ch_center_freq_seg0);
+
+			pe_debug("llnNonGFCoexist: %d "
+					"fLsigTXOPProtectionFullSupport: %d fRIFSMode %d",
+				pAddBssParams->llnNonGFCoexist,
+				pAddBssParams->fLsigTXOPProtectionFullSupport,
+				pAddBssParams->fRIFSMode);
+		}
+	}
+
+	pAddBssParams->currentOperChannel = bssDescription->channelId;
+	pe_debug("currentOperChannel %d", pAddBssParams->currentOperChannel);
+	if (psessionEntry->vhtCapability && (pAssocRsp->VHTCaps.present)) {
+		pAddBssParams->vhtCapable = pAssocRsp->VHTCaps.present;
+		vht_caps =  &pAssocRsp->VHTCaps;
+		vht_oper = &pAssocRsp->VHTOperation;
+	} else if (psessionEntry->vhtCapability &&
+			pAssocRsp->vendor_vht_ie.VHTCaps.present){
+		pAddBssParams->vhtCapable =
+			pAssocRsp->vendor_vht_ie.VHTCaps.present;
+		pe_debug("VHT Caps and Operation are present in vendor Specific IE");
+		vht_caps = &pAssocRsp->vendor_vht_ie.VHTCaps;
+		vht_oper = &pAssocRsp->vendor_vht_ie.VHTOperation;
+	} else {
+		pAddBssParams->vhtCapable = 0;
+	}
+	if (pAddBssParams->vhtCapable) {
+		if (vht_oper != NULL)
+			lim_update_vht_oper_assoc_resp(pMac, pAddBssParams,
+					vht_oper, psessionEntry);
+		if (vht_caps != NULL)
+			lim_update_vhtcaps_assoc_resp(pMac, pAddBssParams,
+					vht_caps, psessionEntry);
+	}
+
+	pe_debug("vhtCapable %d TxChannelWidth %d center_freq_0 %d center_freq_1 %d",
+			pAddBssParams->vhtCapable, pAddBssParams->ch_width,
+			pAddBssParams->ch_center_freq_seg0,
+			pAddBssParams->ch_center_freq_seg1);
+
+	if (lim_is_session_he_capable(psessionEntry) &&
+			(pAssocRsp->he_cap.present)) {
+		lim_add_bss_he_cap(pAddBssParams, pAssocRsp);
+		lim_add_bss_he_cfg(pAddBssParams, psessionEntry);
+	}
+	/*
+	 * Populate the STA-related parameters here
+	 * Note that the STA here refers to the AP
+	 * staType = PEER
+	 */
+	sta_context = &pAddBssParams->staContext;
+	/* Identifying AP as an STA */
+	pAddBssParams->staContext.staType = STA_ENTRY_OTHER;
+
+	qdf_mem_copy(pAddBssParams->staContext.bssId,
+			bssDescription->bssId, sizeof(tSirMacAddr));
+
+	listen_interval = pMac->mlme_cfg->sap_cfg.listen_interval;
+	pAddBssParams->staContext.listenInterval = listen_interval;
+
+	/* Fill Assoc id from the dph table */
+	pStaDs = dph_lookup_hash_entry(pMac, pAddBssParams->staContext.bssId,
+				&pAddBssParams->staContext.assocId,
+				&psessionEntry->dph.dphHashTable);
+	if (pStaDs == NULL) {
+		pe_err("Couldn't get assoc id for " "MAC ADDR: "
+			MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(
+				pAddBssParams->staContext.staMac));
+			return QDF_STATUS_E_FAILURE;
+	}
+
+	pAddBssParams->staContext.uAPSD =
+		psessionEntry->gUapsdPerAcBitmask;
+
+	pAddBssParams->staContext.maxSPLen = 0;
+	pAddBssParams->staContext.shortPreambleSupported =
+		(uint8_t) pAssocRsp->capabilityInfo.shortPreamble;
+	pAddBssParams->staContext.updateSta = updateEntry;
+
+	pe_debug("StaContext: " MAC_ADDRESS_STR
+			" shortPreambleSupported: %d",
+			MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac),
+			pAddBssParams->staContext.shortPreambleSupported);
+
+	if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
+			&& pBeaconStruct->HTCaps.present) {
+		pAddBssParams->staContext.us32MaxAmpduDuration = 0;
+		pAddBssParams->staContext.htCapable = 1;
+		pAddBssParams->staContext.greenFieldCapable =
+			(uint8_t) pAssocRsp->HTCaps.greenField;
+		pAddBssParams->staContext.lsigTxopProtection =
+			(uint8_t) pAssocRsp->HTCaps.lsigTXOPProtection;
+		pe_debug("StaCtx: htCap %d GFcap %d lsigTxopProtn %d",
+				pAddBssParams->staContext.htCapable,
+				pAddBssParams->staContext.greenFieldCapable,
+				pAddBssParams->staContext.lsigTxopProtection);
+		if (psessionEntry->htConfig.ht_tx_stbc)
+			pAddBssParams->staContext.stbc_capable =
+				pAssocRsp->HTCaps.rxSTBC;
+
+		if (psessionEntry->vhtCapability &&
+				(IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
+				 IS_BSS_VHT_CAPABLE(pBeaconStruct->
+						    vendor_vht_ie.VHTCaps))) {
+			pAddBssParams->staContext.vhtCapable = 1;
+			pAddBssParams->staContext.vhtSupportedRxNss =
+				pStaDs->vhtSupportedRxNss;
+			if (pAssocRsp->VHTCaps.present)
+				vht_caps = &pAssocRsp->VHTCaps;
+			else if (pAssocRsp->vendor_vht_ie.VHTCaps.present) {
+				vht_caps = &pAssocRsp->vendor_vht_ie.VHTCaps;
+				pe_debug("VHT Caps are in vendor Specific IE");
+				is_vht_cap_in_vendor_ie = true;
+			}
+
+			if ((vht_caps != NULL) && (vht_caps->suBeamFormerCap ||
+				vht_caps->muBeamformerCap) &&
+				psessionEntry->vht_config.su_beam_formee)
+				sta_context->vhtTxBFCapable = 1;
+
+			if ((vht_caps != NULL) && vht_caps->muBeamformerCap &&
+				psessionEntry->vht_config.mu_beam_formee)
+				sta_context->vhtTxMUBformeeCapable = 1;
+
+			if ((vht_caps != NULL) && vht_caps->suBeamformeeCap &&
+				psessionEntry->vht_config.su_beam_former)
+				sta_context->enable_su_tx_bformer = 1;
+
+			if (vht_caps && pAddBssParams->staContext.stbc_capable)
+				pAddBssParams->staContext.stbc_capable =
+					vht_caps->rxSTBC;
+		}
+		if (lim_is_session_he_capable(psessionEntry) &&
+		    pAssocRsp->he_cap.present) {
+			lim_intersect_ap_he_caps(psessionEntry,
+						 pAddBssParams,
+						 NULL,
+						 pAssocRsp);
+			lim_update_he_stbc_capable(&pAddBssParams->staContext);
+		}
+
+		/*
+		 * in limExtractApCapability function intersection of FW
+		 * advertised channel width and AP advertised channel
+		 * width has been taken into account for calculating
+		 * psessionEntry->ch_width
+		 */
+		if (chanWidthSupp &&
+		    ((pAssocRsp->HTCaps.supportedChannelWidthSet) ||
+		    (pBeaconStruct->HTCaps.supportedChannelWidthSet))) {
+			pAddBssParams->staContext.ch_width =
+					psessionEntry->ch_width;
+		} else {
+			sta_context->ch_width =	CH_WIDTH_20MHZ;
+			if (!vht_cap_info.enable_txbf_20mhz)
+				sta_context->vhtTxBFCapable = 0;
+		}
+
+		pe_debug("StaCtx: vhtCap %d ChBW %d TxBF %d",
+			 pAddBssParams->staContext.vhtCapable,
+			 pAddBssParams->staContext.ch_width,
+			 sta_context->vhtTxBFCapable);
+		pe_debug("StaContext su_tx_bfer %d",
+			 sta_context->enable_su_tx_bformer);
+
+		pAddBssParams->staContext.mimoPS =
+			(tSirMacHTMIMOPowerSaveState)
+			pAssocRsp->HTCaps.mimoPowerSave;
+		pAddBssParams->staContext.maxAmsduSize =
+			(uint8_t) pAssocRsp->HTCaps.maximalAMSDUsize;
+		pAddBssParams->staContext.maxAmpduDensity =
+			pAssocRsp->HTCaps.mpduDensity;
+		pAddBssParams->staContext.fDsssCckMode40Mhz =
+			(uint8_t) pAssocRsp->HTCaps.dsssCckMode40MHz;
+		/*
+		 * We will check gShortGI20Mhz and gShortGI40Mhz from
+		 * session entry  if they are set then we will use what ever
+		 * Assoc response coming from AP supports. If these
+		 * values are set as 0 in session entry then we will
+		 * hardcode this values to 0.
+		 */
+		if (psessionEntry->htConfig.ht_sgi20) {
+			pAddBssParams->staContext.fShortGI20Mhz =
+				(uint8_t)pAssocRsp->HTCaps.shortGI20MHz;
+		} else {
+			pAddBssParams->staContext.fShortGI20Mhz = false;
+		}
+
+		if (psessionEntry->htConfig.ht_sgi40) {
+			pAddBssParams->staContext.fShortGI40Mhz =
+				(uint8_t) pAssocRsp->HTCaps.shortGI40MHz;
+		} else {
+			pAddBssParams->staContext.fShortGI40Mhz = false;
+		}
+
+		if (!pAddBssParams->staContext.vhtCapable)
+			/* Use max ampd factor advertised in
+			 * HTCAP for non-vht connection */
+		{
+			pAddBssParams->staContext.maxAmpduSize =
+				pAssocRsp->HTCaps.maxRxAMPDUFactor;
+		} else if (pAddBssParams->staContext.maxAmpduSize <
+				pAssocRsp->HTCaps.maxRxAMPDUFactor) {
+			pAddBssParams->staContext.maxAmpduSize =
+				pAssocRsp->HTCaps.maxRxAMPDUFactor;
+		}
+		if (pAddBssParams->staContext.vhtTxBFCapable
+				&& pMac->lim.disableLDPCWithTxbfAP) {
+			pAddBssParams->staContext.htLdpcCapable = 0;
+			pAddBssParams->staContext.vhtLdpcCapable = 0;
+		} else {
+			if (psessionEntry->txLdpcIniFeatureEnabled & 0x1)
+				pAddBssParams->staContext.htLdpcCapable =
+				    (uint8_t) pAssocRsp->HTCaps.advCodingCap;
+			else
+				pAddBssParams->staContext.htLdpcCapable = 0;
+
+			if (pAssocRsp->VHTCaps.present)
+				vht_caps = &pAssocRsp->VHTCaps;
+			else if (pAssocRsp->vendor_vht_ie.VHTCaps.present) {
+				vht_caps = &pAssocRsp->vendor_vht_ie.VHTCaps;
+				pe_debug("VHT Caps is in vendor Specific IE");
+			}
+			if (vht_caps != NULL &&
+				(psessionEntry->txLdpcIniFeatureEnabled & 0x2)) {
+				if (!is_vht_cap_in_vendor_ie)
+					pAddBssParams->staContext.vhtLdpcCapable =
+					  (uint8_t) pAssocRsp->VHTCaps.ldpcCodingCap;
+				else
+					pAddBssParams->staContext.vhtLdpcCapable =
+					    (uint8_t) vht_caps->ldpcCodingCap;
+			} else {
+				pAddBssParams->staContext.vhtLdpcCapable = 0;
+			}
+		}
+
+		if (pBeaconStruct->HTInfo.present)
+			pAddBssParams->staContext.rifsMode =
+				pAssocRsp->HTInfo.rifsMode;
+
+		pe_debug("StaCtx: ChBW %d mimoPS %d maxAmsduSize %d",
+				pAddBssParams->staContext.ch_width,
+				pAddBssParams->staContext.mimoPS,
+				pAddBssParams->staContext.maxAmsduSize);
+
+		pe_debug("maxAmpduDens %d CckMode40Mhz %d SGI20Mhz %d",
+				pAddBssParams->staContext.maxAmpduDensity,
+				pAddBssParams->staContext.fDsssCckMode40Mhz,
+				pAddBssParams->staContext.fShortGI20Mhz);
+
+		pe_debug("SGI40M %d maxAmpdu %d htLdpc %d vhtLdpc %d",
+				pAddBssParams->staContext.fShortGI40Mhz,
+				pAddBssParams->staContext.maxAmpduSize,
+				pAddBssParams->staContext.htLdpcCapable,
+				pAddBssParams->staContext.vhtLdpcCapable);
+	}
+	pAddBssParams->staContext.smesessionId =
+		psessionEntry->smeSessionId;
+	pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent;
+	pAddBssParams->staContext.wpa_rsn |=
+		(pBeaconStruct->wpaPresent << 1);
+	/* For OSEN Connection AP does not advertise RSN or WPA IE
+	 * so from the IEs we get from supplicant we get this info
+	 * so for FW to transmit EAPOL message 4 we shall set
+	 * wpa_rsn
+	 */
+	if ((!pAddBssParams->staContext.wpa_rsn)
+			&& (psessionEntry->isOSENConnection))
+		pAddBssParams->staContext.wpa_rsn = 1;
+	qdf_mem_copy(&pAddBssParams->staContext.capab_info,
+			&pAssocRsp->capabilityInfo,
+			sizeof(pAddBssParams->staContext.capab_info));
+	qdf_mem_copy(&pAddBssParams->staContext.ht_caps,
+			(uint8_t *) &pAssocRsp->HTCaps + sizeof(uint8_t),
+			sizeof(pAddBssParams->staContext.ht_caps));
+
+	/* If WMM IE or 802.11E IE is present then enable WMM */
+	if ((psessionEntry->limWmeEnabled && pAssocRsp->wmeEdcaPresent) ||
+		(psessionEntry->limQosEnabled && pAssocRsp->edcaPresent))
+		pAddBssParams->staContext.wmmEnabled = 1;
+	else
+		pAddBssParams->staContext.wmmEnabled = 0;
+
+	/* Update the rates */
+	pStaDs = dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+				&psessionEntry->dph.dphHashTable);
+	if (pStaDs != NULL) {
+		qdf_mem_copy((uint8_t *) &pAddBssParams->staContext.
+				supportedRates,
+				(uint8_t *)&pStaDs->supportedRates,
+				sizeof(tSirSupportedRates));
+	} else
+		pe_err("could not Update the supported rates");
+	pAddBssParams->staContext.encryptType = psessionEntry->encryptType;
+
+	pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
+	pe_debug("maxTxPower: %d", pAddBssParams->maxTxPower);
+	/* FIXME_GEN4 - Any other value that can be used for initialization? */
+	pAddBssParams->status = QDF_STATUS_SUCCESS;
+	pAddBssParams->respReqd = true;
+	/* update persona */
+	pAddBssParams->halPersona = (uint8_t) psessionEntry->pePersona;
+
+	if (QDF_P2P_CLIENT_MODE == psessionEntry->pePersona)
+		pAddBssParams->staContext.p2pCapableSta = 1;
+
+	pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;
+
+	pAddBssParams->extSetStaKeyParamValid = 0;
+	pe_debug("extSetStaKeyParamValid: %d",
+		pAddBssParams->extSetStaKeyParamValid);
+
+#ifdef WLAN_FEATURE_11W
+	if (psessionEntry->limRmfEnabled) {
+		pAddBssParams->rmfEnabled = 1;
+		pAddBssParams->staContext.rmfEnabled = 1;
+	}
+#endif
+
+	/* Set a new state for MLME */
+	if (eLIM_MLM_WT_ASSOC_RSP_STATE == psessionEntry->limMlmState)
+		psessionEntry->limMlmState =
+			eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE;
+	else
+		psessionEntry->limMlmState =
+			eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE;
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+		       psessionEntry->limMlmState));
+
+	if (!pAddBssParams->staContext.htLdpcCapable)
+		pAddBssParams->staContext.ht_caps &=
+			~(1 << SIR_MAC_HT_CAP_ADVCODING_S);
+	if (!pAddBssParams->staContext.vhtLdpcCapable)
+		pAddBssParams->staContext.vht_caps &=
+			~(1 << SIR_MAC_VHT_CAP_LDPC_CODING_CAP);
+
+	pe_debug("staContext wmmEnabled: %d encryptType: %d "
+		"p2pCapableSta: %d",
+		pAddBssParams->staContext.wmmEnabled,
+		pAddBssParams->staContext.encryptType,
+		pAddBssParams->staContext.p2pCapableSta);
+
+	pe_debug("bSpectrumMgtEnabled: %d halPersona: %d setting "
+		"LimMlm state to %d",
+		pAddBssParams->bSpectrumMgtEnabled, pAddBssParams->halPersona,
+		psessionEntry->limMlmState);
+	if (psessionEntry->isNonRoamReassoc)
+		pAddBssParams->nonRoamReassoc = 1;
+	pAddBssParams->nss = psessionEntry->nss;
+	pe_debug("nss value: %d", pAddBssParams->nss);
+
+	/* we need to defer the message until we get the response back from HAL. */
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+	if (cds_is_5_mhz_enabled()) {
+		pAddBssParams->ch_width = CH_WIDTH_5MHZ;
+		pAddBssParams->staContext.ch_width = CH_WIDTH_5MHZ;
+	} else if (cds_is_10_mhz_enabled()) {
+		pAddBssParams->ch_width = CH_WIDTH_10MHZ;
+		pAddBssParams->staContext.ch_width = CH_WIDTH_10MHZ;
+	}
+	lim_set_sta_ctx_twt(&pAddBssParams->staContext, psessionEntry);
+
+	msgQ.type = WMA_ADD_BSS_REQ;
+	/** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pAddBssParams;
+	msgQ.bodyval = 0;
+
+	pe_debug("SessionId: %d Sending WMA_ADD_BSS_REQ",
+		psessionEntry->peSessionId);
+	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+		qdf_mem_free(pAddBssParams);
+		pe_err("Posting ADD_BSS_REQ to HAL failed, reason=%X",
+			retCode);
+		goto returnFailure;
+
+	} else
+		return retCode;
+
+returnFailure:
+	/* Clean-up will be done by the caller... */
+	return retCode;
+}
+
+QDF_STATUS lim_sta_send_add_bss_pre_assoc(tpAniSirGlobal pMac, uint8_t updateEntry,
+					     tpPESession psessionEntry)
+{
+	struct scheduler_msg msgQ = {0};
+	tpAddBssParams pAddBssParams = NULL;
+	uint32_t retCode;
+	tSchBeaconStruct *pBeaconStruct;
+	uint8_t chanWidthSupp = 0;
+	tDot11fIEVHTOperation *vht_oper = NULL;
+	tDot11fIEVHTCaps *vht_caps = NULL;
+	uint32_t listen_interval = MLME_CFG_LISTEN_INTERVAL;
+
+	tpSirBssDescription bssDescription =
+		&psessionEntry->pLimJoinReq->bssDescription;
+
+	pBeaconStruct = qdf_mem_malloc(sizeof(tSchBeaconStruct));
+	if (!pBeaconStruct)
+		return QDF_STATUS_E_NOMEM;
+
+	/* Package SIR_HAL_ADD_BSS_REQ message parameters */
+	pAddBssParams = qdf_mem_malloc(sizeof(tAddBssParams));
+	if (!pAddBssParams) {
+		retCode = QDF_STATUS_E_NOMEM;
+		goto returnFailure;
+	}
+
+	lim_extract_ap_capabilities(pMac, (uint8_t *) bssDescription->ieFields,
+			lim_get_ielen_from_bss_description(bssDescription),
+			pBeaconStruct);
+
+	if (pMac->lim.gLimProtectionControl !=
+	    MLME_FORCE_POLICY_PROTECTION_DISABLE)
+		lim_decide_sta_protection_on_assoc(pMac, pBeaconStruct,
+						   psessionEntry);
+	qdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
+		     sizeof(tSirMacAddr));
+
+	/* Fill in tAddBssParams selfMacAddr */
+	qdf_mem_copy(pAddBssParams->selfMacAddr,
+		     psessionEntry->selfMacAddr, sizeof(tSirMacAddr));
+	pe_debug("sessionid: %d updateEntry = %d limsystemrole = %d",
+		psessionEntry->smeSessionId, updateEntry,
+		GET_LIM_SYSTEM_ROLE(psessionEntry));
+
+	pe_debug("BSSID: " MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(pAddBssParams->bssId));
+	/* Incorrect BSS Type which caused UMA Descriptor to be overwritten on
+	 * top of an already established Infra link. This lead to issues in
+	 * concurrent data transfer.
+	 */
+
+	pAddBssParams->bssType = psessionEntry->bssType; /* eSIR_INFRASTRUCTURE_MODE; */
+	pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
+
+	pAddBssParams->beaconInterval = bssDescription->beaconInterval;
+
+	pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
+	pAddBssParams->updateBss = updateEntry;
+
+	pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount;
+	pAddBssParams->cfParamSet.cfpPeriod =
+		pBeaconStruct->cfParamSet.cfpPeriod;
+	pAddBssParams->cfParamSet.cfpMaxDuration =
+		pBeaconStruct->cfParamSet.cfpMaxDuration;
+	pAddBssParams->cfParamSet.cfpDurRemaining =
+		pBeaconStruct->cfParamSet.cfpDurRemaining;
+
+	pAddBssParams->rateSet.numRates =
+		pBeaconStruct->supportedRates.numRates;
+	qdf_mem_copy(pAddBssParams->rateSet.rate,
+		     pBeaconStruct->supportedRates.rate,
+		     pBeaconStruct->supportedRates.numRates);
+
+	pAddBssParams->nwType = bssDescription->nwType;
+
+	pAddBssParams->shortSlotTimeSupported =
+		(uint8_t) pBeaconStruct->capabilityInfo.shortSlotTime;
+	pAddBssParams->llaCoexist =
+		(uint8_t) psessionEntry->beaconParams.llaCoexist;
+	pAddBssParams->llbCoexist =
+		(uint8_t) psessionEntry->beaconParams.llbCoexist;
+	pAddBssParams->llgCoexist =
+		(uint8_t) psessionEntry->beaconParams.llgCoexist;
+	pAddBssParams->ht20Coexist =
+		(uint8_t) psessionEntry->beaconParams.ht20Coexist;
+
+	pe_debug("BSS Type %d Beacon Interval: %d dtimPeriod: %d "
+		"cfpCount: %d", pAddBssParams->bssType,
+		pAddBssParams->beaconInterval, pAddBssParams->dtimPeriod,
+		pAddBssParams->cfParamSet.cfpCount);
+
+	pe_debug("cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining: %d"
+		" numRates: %d", pAddBssParams->cfParamSet.cfpPeriod,
+		pAddBssParams->cfParamSet.cfpMaxDuration,
+		pAddBssParams->cfParamSet.cfpDurRemaining,
+		pAddBssParams->rateSet.numRates);
+
+	pe_debug("nwType:%d shortSlotTimeSupported: %d"
+		"llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d",
+		pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported,
+		pAddBssParams->llaCoexist, pAddBssParams->llbCoexist,
+		pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist);
+	/* Use the advertised capabilities from the received beacon/PR */
+	if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
+	    && (pBeaconStruct->HTCaps.present)) {
+		pAddBssParams->htCapable = pBeaconStruct->HTCaps.present;
+		pe_debug("htCapable: %d", pAddBssParams->htCapable);
+		if (pBeaconStruct->HTInfo.present) {
+			pAddBssParams->htOperMode =
+				(tSirMacHTOperatingMode) pBeaconStruct->HTInfo.
+				opMode;
+			pAddBssParams->dualCTSProtection =
+				(uint8_t) pBeaconStruct->HTInfo.dualCTSProtection;
+
+			chanWidthSupp =
+				lim_get_ht_capability(pMac,
+						      eHT_SUPPORTED_CHANNEL_WIDTH_SET,
+						      psessionEntry);
+			if ((pBeaconStruct->HTCaps.supportedChannelWidthSet)
+			    && (chanWidthSupp)) {
+				pAddBssParams->ch_width =
+					(uint8_t) pBeaconStruct->HTInfo.
+					recommendedTxWidthSet;
+				if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+						PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+					pAddBssParams->ch_center_freq_seg0 =
+						bssDescription->channelId + 2;
+
+				if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+						PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+					pAddBssParams->ch_center_freq_seg0 =
+						bssDescription->channelId - 2;
+			} else {
+				pAddBssParams->ch_width = CH_WIDTH_20MHZ;
+				pAddBssParams->ch_center_freq_seg0 = 0;
+			}
+			pAddBssParams->llnNonGFCoexist =
+				(uint8_t) pBeaconStruct->HTInfo.nonGFDevicesPresent;
+			pAddBssParams->fLsigTXOPProtectionFullSupport =
+				(uint8_t) pBeaconStruct->HTInfo.
+				lsigTXOPProtectionFullSupport;
+			pAddBssParams->fRIFSMode =
+				pBeaconStruct->HTInfo.rifsMode;
+
+			pe_debug("htOperMode: %d dualCTSProtection: %d txChannelWidthSet: %d center_freq_seg0: %d",
+				pAddBssParams->htOperMode,
+				pAddBssParams->dualCTSProtection,
+				pAddBssParams->txChannelWidthSet,
+				pAddBssParams->ch_center_freq_seg0);
+
+			pe_debug("llnNonGFCoexist: %d "
+				"fLsigTXOPProtectionFullSupport: %d fRIFSMode %d",
+				pAddBssParams->llnNonGFCoexist,
+				pAddBssParams->fLsigTXOPProtectionFullSupport,
+				pAddBssParams->fRIFSMode);
+		}
+	}
+
+	pAddBssParams->currentOperChannel = bssDescription->channelId;
+	pe_debug("currentOperChannel %d",
+		pAddBssParams->currentOperChannel);
+
+	if (psessionEntry->vhtCapability &&
+		(IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
+		 IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor_vht_ie.VHTCaps))) {
+
+		pAddBssParams->vhtCapable = 1;
+		if (pBeaconStruct->VHTOperation.present)
+			vht_oper = &pBeaconStruct->VHTOperation;
+		else if (pBeaconStruct->vendor_vht_ie.VHTOperation.present) {
+			vht_oper = &pBeaconStruct->vendor_vht_ie.VHTOperation;
+			pe_debug("VHT Operation is present in vendor Specific IE");
+		}
+
+
+		if ((vht_oper != NULL) &&
+			vht_oper->chanWidth &&
+			chanWidthSupp) {
+			pAddBssParams->ch_center_freq_seg0 =
+				vht_oper->chanCenterFreqSeg1;
+			pAddBssParams->ch_center_freq_seg1 =
+				vht_oper->chanCenterFreqSeg2;
+		}
+		/*
+		 * in limExtractApCapability function intersection of FW
+		 * advertised channel width and AP advertised channel width has
+		 * been taken into account for calculating
+		 * psessionEntry->ch_width
+		 */
+		pAddBssParams->ch_width =
+			psessionEntry->ch_width;
+		pAddBssParams->staContext.maxAmpduSize =
+			SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(
+					pAddBssParams->staContext.vht_caps);
+	} else {
+		pAddBssParams->vhtCapable = 0;
+	}
+
+	if (lim_is_session_he_capable(psessionEntry) &&
+	    pBeaconStruct->he_cap.present) {
+		lim_update_bss_he_capable(pMac, pAddBssParams);
+		lim_add_bss_he_cfg(pAddBssParams, psessionEntry);
+	}
+	pe_debug("vhtCapable %d vhtTxChannelWidthSet %d center_freq_seg0 - %d, center_freq_seg1 - %d",
+		pAddBssParams->vhtCapable, pAddBssParams->ch_width,
+		pAddBssParams->ch_center_freq_seg0,
+		pAddBssParams->ch_center_freq_seg1);
+	/*
+	 * Populate the STA-related parameters here
+	 * Note that the STA here refers to the AP
+	 */
+	/* Identifying AP as an STA */
+	pAddBssParams->staContext.staType = STA_ENTRY_OTHER;
+
+	qdf_mem_copy(pAddBssParams->staContext.bssId,
+			bssDescription->bssId, sizeof(tSirMacAddr));
+
+	listen_interval = pMac->mlme_cfg->sap_cfg.listen_interval;
+	pAddBssParams->staContext.listenInterval = listen_interval;
+	pAddBssParams->staContext.assocId = 0;
+	pAddBssParams->staContext.uAPSD = 0;
+	pAddBssParams->staContext.maxSPLen = 0;
+	pAddBssParams->staContext.shortPreambleSupported =
+		(uint8_t) pBeaconStruct->capabilityInfo.shortPreamble;
+	pAddBssParams->staContext.updateSta = updateEntry;
+
+	pe_debug("StaCtx: " MAC_ADDRESS_STR " shortPreamble: %d",
+			MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac),
+			pAddBssParams->staContext.shortPreambleSupported);
+
+	pAddBssParams->dot11_mode = psessionEntry->dot11mode;
+	pe_debug("dot11_mode:%d", pAddBssParams->dot11_mode);
+
+	if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
+			&& (pBeaconStruct->HTCaps.present)) {
+		pAddBssParams->staContext.us32MaxAmpduDuration = 0;
+		pAddBssParams->staContext.htCapable = 1;
+		pAddBssParams->staContext.greenFieldCapable =
+			(uint8_t) pBeaconStruct->HTCaps.greenField;
+		pAddBssParams->staContext.lsigTxopProtection =
+			(uint8_t) pBeaconStruct->HTCaps.lsigTXOPProtection;
+		pe_debug("StaCtx: htCap %d GFCap %d lsigTxopProtn %d",
+				pAddBssParams->staContext.htCapable,
+				pAddBssParams->staContext.greenFieldCapable,
+				pAddBssParams->staContext.lsigTxopProtection);
+		if (psessionEntry->vhtCapability &&
+			(IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
+			 IS_BSS_VHT_CAPABLE(
+				 pBeaconStruct->vendor_vht_ie.VHTCaps))) {
+			pAddBssParams->staContext.vhtCapable = 1;
+			if (pBeaconStruct->VHTCaps.present)
+				vht_caps = &pBeaconStruct->VHTCaps;
+			else if (pBeaconStruct->vendor_vht_ie.VHTCaps.present)
+				vht_caps = &pBeaconStruct->
+						vendor_vht_ie.VHTCaps;
+
+			if ((vht_caps != NULL) && (vht_caps->suBeamFormerCap ||
+				vht_caps->muBeamformerCap) &&
+				psessionEntry->vht_config.su_beam_formee)
+				pAddBssParams->staContext.vhtTxBFCapable = 1;
+
+			if ((vht_caps != NULL) && vht_caps->muBeamformerCap &&
+				psessionEntry->vht_config.mu_beam_formee)
+				pAddBssParams->staContext.vhtTxMUBformeeCapable
+						= 1;
+
+			if ((vht_caps != NULL) && vht_caps->suBeamformeeCap &&
+				psessionEntry->vht_config.su_beam_former)
+				pAddBssParams->staContext.enable_su_tx_bformer
+						= 1;
+
+			pe_debug("StaContext: su_tx_bfer %d",
+				pAddBssParams->staContext.enable_su_tx_bformer);
+		}
+		if (lim_is_session_he_capable(psessionEntry) &&
+			pBeaconStruct->he_cap.present)
+			lim_intersect_ap_he_caps(psessionEntry, pAddBssParams,
+					      pBeaconStruct, NULL);
+
+		if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
+				(chanWidthSupp)) {
+			pAddBssParams->staContext.ch_width =
+				(uint8_t) pBeaconStruct->HTInfo.
+				recommendedTxWidthSet;
+			if ((vht_oper != NULL) &&
+					pAddBssParams->staContext.vhtCapable &&
+					vht_oper->chanWidth)
+				pAddBssParams->staContext.ch_width =
+					vht_oper->chanWidth + 1;
+			pe_debug("StaCtx: vhtCap %d ch_bw %d TxBF %d",
+				   pAddBssParams->staContext.vhtCapable,
+				   pAddBssParams->staContext.ch_width,
+				   pAddBssParams->staContext.vhtTxBFCapable);
+		} else {
+			pAddBssParams->staContext.ch_width =
+				CH_WIDTH_20MHZ;
+		}
+		pAddBssParams->staContext.mimoPS =
+			(tSirMacHTMIMOPowerSaveState) pBeaconStruct->HTCaps.
+			mimoPowerSave;
+		pAddBssParams->staContext.maxAmsduSize =
+			(uint8_t) pBeaconStruct->HTCaps.maximalAMSDUsize;
+		pAddBssParams->staContext.maxAmpduDensity =
+			pBeaconStruct->HTCaps.mpduDensity;
+		pAddBssParams->staContext.fDsssCckMode40Mhz =
+			(uint8_t) pBeaconStruct->HTCaps.dsssCckMode40MHz;
+		/*
+		 * We will check gShortGI20Mhz and gShortGI40Mhz from ini file.
+		 * if they are set then we will use what ever Beacon coming
+		 * from AP supports. If these values are set as 0 in ini file
+		 * then we will hardcode this values to 0.
+		 */
+		if (true == psessionEntry->htConfig.ht_sgi20)
+			pAddBssParams->staContext.fShortGI20Mhz =
+				(uint8_t)pBeaconStruct->HTCaps.shortGI20MHz;
+		else
+				pAddBssParams->staContext.fShortGI20Mhz =
+					false;
+
+		if (true == psessionEntry->htConfig.ht_sgi40)
+			pAddBssParams->staContext.fShortGI40Mhz =
+				(uint8_t) pBeaconStruct->HTCaps.shortGI40MHz;
+		else
+			pAddBssParams->staContext.fShortGI40Mhz = false;
+
+		pAddBssParams->staContext.maxAmpduSize =
+			pBeaconStruct->HTCaps.maxRxAMPDUFactor;
+		if (pAddBssParams->staContext.vhtTxBFCapable
+				&& pMac->lim.disableLDPCWithTxbfAP) {
+			pAddBssParams->staContext.htLdpcCapable = 0;
+			pAddBssParams->staContext.vhtLdpcCapable = 0;
+		} else {
+			if (psessionEntry->txLdpcIniFeatureEnabled & 0x1)
+				pAddBssParams->staContext.htLdpcCapable =
+					(uint8_t) pBeaconStruct->HTCaps.
+						advCodingCap;
+			else
+				pAddBssParams->staContext.htLdpcCapable = 0;
+
+			if (pBeaconStruct->VHTCaps.present)
+				vht_caps = &pBeaconStruct->VHTCaps;
+			else if (pBeaconStruct->vendor_vht_ie.VHTCaps.present) {
+				vht_caps =
+					&pBeaconStruct->vendor_vht_ie.VHTCaps;
+				pe_debug("VHT Caps are in vendor Specific IE");
+			}
+			if (vht_caps != NULL &&
+				(psessionEntry->txLdpcIniFeatureEnabled & 0x2))
+				pAddBssParams->staContext.vhtLdpcCapable =
+					(uint8_t) vht_caps->ldpcCodingCap;
+			else
+				pAddBssParams->staContext.vhtLdpcCapable = 0;
+		}
+
+		if (pBeaconStruct->HTInfo.present)
+			pAddBssParams->staContext.rifsMode =
+				pBeaconStruct->HTInfo.rifsMode;
+		pe_debug("StaContext ChannelWidth: %d mimoPS: %d maxAmsduSize: %d",
+				pAddBssParams->staContext.ch_width,
+				pAddBssParams->staContext.mimoPS,
+				pAddBssParams->staContext.maxAmsduSize);
+
+		pe_debug("maxAmpduDensity %d Cck40Mhz %d SGI20Mhz %d",
+				pAddBssParams->staContext.maxAmpduDensity,
+				pAddBssParams->staContext.fDsssCckMode40Mhz,
+				pAddBssParams->staContext.fShortGI20Mhz);
+
+		pe_debug("SGI40M %d maxAmpdu %d htLdpc %d vhtLdpc %d",
+				pAddBssParams->staContext.fShortGI40Mhz,
+				pAddBssParams->staContext.maxAmpduSize,
+				pAddBssParams->staContext.htLdpcCapable,
+				pAddBssParams->staContext.vhtLdpcCapable);
+	}
+	/*
+	 * If WMM IE or 802.11E IE is not present
+	 * and AP is HT AP then enable WMM
+	 */
+	if ((psessionEntry->limWmeEnabled && (pBeaconStruct->wmeEdcaPresent ||
+			pAddBssParams->staContext.htCapable)) ||
+			(psessionEntry->limQosEnabled &&
+			 (pBeaconStruct->edcaPresent ||
+			  pAddBssParams->staContext.htCapable)))
+		pAddBssParams->staContext.wmmEnabled = 1;
+	else
+		pAddBssParams->staContext.wmmEnabled = 0;
+
+	/* Update the rates */
+	lim_populate_peer_rate_set(pMac,
+			&pAddBssParams->staContext.
+			supportedRates,
+			pBeaconStruct->HTCaps.supportedMCSSet,
+			false, psessionEntry,
+			&pBeaconStruct->VHTCaps,
+			&pBeaconStruct->he_cap);
+
+	pAddBssParams->staContext.encryptType = psessionEntry->encryptType;
+
+	pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
+	pe_debug("maxTxPower: %d", pAddBssParams->maxTxPower);
+
+	pAddBssParams->status = QDF_STATUS_SUCCESS;
+	pAddBssParams->respReqd = true;
+
+	pAddBssParams->staContext.smesessionId = psessionEntry->smeSessionId;
+	pAddBssParams->staContext.sessionId = psessionEntry->peSessionId;
+	pAddBssParams->sessionId = psessionEntry->peSessionId;
+
+	pAddBssParams->halPersona = (uint8_t) psessionEntry->pePersona; /* update persona */
+
+	pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;
+
+	pAddBssParams->extSetStaKeyParamValid = 0;
+	pe_debug("extSetStaKeyParamValid: %d",
+		pAddBssParams->extSetStaKeyParamValid);
+
+#ifdef WLAN_FEATURE_11W
+	if (psessionEntry->limRmfEnabled) {
+		pAddBssParams->rmfEnabled = 1;
+		pAddBssParams->staContext.rmfEnabled = 1;
+	}
+#endif
+
+	pAddBssParams->nss = psessionEntry->nss;
+	pe_debug("nss value: %d", pAddBssParams->nss);
+
+	/* Set a new state for MLME */
+	psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE;
+
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+		       psessionEntry->limMlmState));
+
+	pe_debug("staContext wmmEnabled: %d encryptType: %d "
+			       "p2pCapableSta: %d",
+		pAddBssParams->staContext.wmmEnabled,
+		pAddBssParams->staContext.encryptType,
+		pAddBssParams->staContext.p2pCapableSta);
+
+	pe_debug("bSpectrumMgtEnabled: %d halPersona: %d setting "
+			       "LimMlm state to %d",
+		pAddBssParams->bSpectrumMgtEnabled, pAddBssParams->halPersona,
+		psessionEntry->limMlmState);
+
+	/* we need to defer the message until we get the response back from HAL. */
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+	if (cds_is_5_mhz_enabled()) {
+		pAddBssParams->ch_width = CH_WIDTH_5MHZ;
+		pAddBssParams->staContext.ch_width = CH_WIDTH_5MHZ;
+	} else if (cds_is_10_mhz_enabled()) {
+		pAddBssParams->ch_width = CH_WIDTH_10MHZ;
+		pAddBssParams->staContext.ch_width = CH_WIDTH_10MHZ;
+	}
+
+	msgQ.type = WMA_ADD_BSS_REQ;
+	/** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pAddBssParams;
+	msgQ.bodyval = 0;
+
+	pe_debug("SessionId:%d Sending WMA_ADD_BSS_REQ",
+		psessionEntry->peSessionId);
+	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+		qdf_mem_free(pAddBssParams);
+		pe_err("Posting ADD_BSS_REQ to HAL failed, reason=%X",
+			retCode);
+		goto returnFailure;
+
+	} else {
+		qdf_mem_free(pBeaconStruct);
+		return retCode;
+	}
+
+returnFailure:
+	/* Clean-up will be done by the caller... */
+	qdf_mem_free(pBeaconStruct);
+	return retCode;
+}
+
+/**
+ * lim_prepare_and_send_del_sta_cnf() - prepares and send del sta cnf
+ *
+ * @pMac:          mac global context
+ * @pStaDs:        sta dph node
+ * @statusCode:    status code
+ * @psessionEntry: session context
+ *
+ * deletes DPH entry, changes the MLM mode for station, calls
+ * lim_send_del_sta_cnf
+ *
+ * Return: void
+ */
+void
+lim_prepare_and_send_del_sta_cnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+				 tSirResultCodes statusCode,
+				 tpPESession psessionEntry)
+{
+	uint16_t staDsAssocId = 0;
+	struct qdf_mac_addr sta_dsaddr;
+	tLimMlmStaContext mlmStaContext;
+
+	if (pStaDs == NULL) {
+		pe_err("pStaDs is NULL");
+		return;
+	}
+	staDsAssocId = pStaDs->assocId;
+	qdf_mem_copy((uint8_t *) sta_dsaddr.bytes,
+		     pStaDs->staAddr, QDF_MAC_ADDR_SIZE);
+
+	mlmStaContext = pStaDs->mlmStaContext;
+	if (LIM_IS_AP_ROLE(psessionEntry))
+		lim_release_peer_idx(pMac, pStaDs->assocId, psessionEntry);
+
+	lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, pStaDs->assocId,
+				  psessionEntry);
+
+	if (LIM_IS_STA_ROLE(psessionEntry)) {
+		psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+		MTRACE(mac_trace(pMac, TRACE_CODE_MLM_STATE,
+				 psessionEntry->peSessionId,
+				 psessionEntry->limMlmState));
+	}
+	lim_send_del_sta_cnf(pMac, sta_dsaddr, staDsAssocId, mlmStaContext,
+			     statusCode, psessionEntry);
+}
+
+/** -------------------------------------------------------------
+   \fn lim_init_pre_auth_timer_table
+   \brief Initialize the Pre Auth Tanle and creates the timer for
+       each node for the timeout value got from cfg.
+   \param     tpAniSirGlobal    pMac
+   \param     tpLimPreAuthTable pPreAuthTimerTable
+   \return none
+   -------------------------------------------------------------*/
+void lim_init_pre_auth_timer_table(tpAniSirGlobal pMac,
+				   tpLimPreAuthTable pPreAuthTimerTable)
+{
+	uint32_t cfgValue;
+	uint32_t authNodeIdx;
+
+	tLimPreAuthNode **pAuthNode = pPreAuthTimerTable->pTable;
+
+	/* Get AUTH_RSP Timers value */
+	cfgValue = SYS_MS_TO_TICKS(pMac->mlme_cfg->timeouts.auth_rsp_timeout);
+	for (authNodeIdx = 0; authNodeIdx < pPreAuthTimerTable->numEntry;
+	     authNodeIdx++) {
+		if (tx_timer_create(pMac, &(pAuthNode[authNodeIdx]->timer),
+			"AUTH RESPONSE TIMEOUT",
+			lim_auth_response_timer_handler, authNodeIdx,
+			cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+			pe_err("Cannot create Auth Rsp timer of Index: %d",
+				authNodeIdx);
+			return;
+		}
+		pAuthNode[authNodeIdx]->authNodeIdx = (uint8_t) authNodeIdx;
+		pAuthNode[authNodeIdx]->fFree = 1;
+	}
+}
+
+/** -------------------------------------------------------------
+   \fn lim_acquire_free_pre_auth_node
+   \brief Retrives a free Pre Auth node from Pre Auth Table.
+   \param     tpAniSirGlobal    pMac
+   \param     tpLimPreAuthTable pPreAuthTimerTable
+   \return none
+   -------------------------------------------------------------*/
+tLimPreAuthNode *lim_acquire_free_pre_auth_node(tpAniSirGlobal pMac,
+						tpLimPreAuthTable pPreAuthTimerTable)
+{
+	uint32_t i;
+	tLimPreAuthNode **pTempNode = pPreAuthTimerTable->pTable;
+
+	for (i = 0; i < pPreAuthTimerTable->numEntry; i++) {
+		if (pTempNode[i]->fFree == 1) {
+			pTempNode[i]->fFree = 0;
+			return pTempNode[i];
+		}
+	}
+
+	return NULL;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_get_pre_auth_node_from_index
+   \brief Depending on the Index this retrieves the pre auth node.
+   \param     tpAniSirGlobal    pMac
+   \param     tpLimPreAuthTable pAuthTable
+   \param     uint32_t authNodeIdx
+   \return none
+   -------------------------------------------------------------*/
+tLimPreAuthNode *lim_get_pre_auth_node_from_index(tpAniSirGlobal pMac,
+						  tpLimPreAuthTable pAuthTable,
+						  uint32_t authNodeIdx)
+{
+	if ((authNodeIdx >= pAuthTable->numEntry)
+	    || (pAuthTable->pTable == NULL)) {
+		pe_err("Invalid Auth Timer Index: %d NumEntry: %d",
+			authNodeIdx, pAuthTable->numEntry);
+		return NULL;
+	}
+
+	return pAuthTable->pTable[authNodeIdx];
+}
+
+/* Util API to check if the channels supported by STA is within range */
+QDF_STATUS lim_is_dot11h_supported_channels_valid(tpAniSirGlobal pMac,
+						     tSirAssocReq *assoc)
+{
+	/*
+	 * Allow all the stations to join with us.
+	 * 802.11h-2003 11.6.1 => An AP may use the supported channels list for associated STAs
+	 * as an input into an algorithm used to select a new channel for the BSS.
+	 * The specification of the algorithm is beyond the scope of this amendment.
+	 */
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/* Util API to check if the txpower supported by STA is within range */
+QDF_STATUS lim_is_dot11h_power_capabilities_in_range(tpAniSirGlobal pMac,
+							tSirAssocReq *assoc,
+							tpPESession psessionEntry)
+{
+	int8_t localMaxTxPower;
+	uint32_t localPwrConstraint;
+
+	localMaxTxPower =
+		cfg_get_regulatory_max_transmit_power(pMac,
+						      psessionEntry->currentOperChannel);
+
+	if (wlan_cfg_get_int
+		    (pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT,
+		    &localPwrConstraint) != QDF_STATUS_SUCCESS) {
+		pe_err("Unable to get Local Power Constraint from cfg");
+		return QDF_STATUS_E_FAILURE;
+	}
+	localMaxTxPower -= (int8_t) localPwrConstraint;
+
+	/**
+	 *  The min Tx Power of the associating station should not be greater than (regulatory
+	 *  max tx power - local power constraint configured on AP).
+	 */
+	if (assoc->powerCapability.minTxPower > localMaxTxPower) {
+		pe_warn("minTxPower (STA): %d, localMaxTxPower (AP): %d",
+			assoc->powerCapability.minTxPower, localMaxTxPower);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn     lim_fill_rx_highest_supported_rate
+   \brief  Fills in the Rx Highest Supported Data Rate field from
+ \       the 'supported MCS set' field in HT capability element.
+   \param  tpAniSirGlobal    pMac
+   \param  tpSirSupportedRates  pRates
+   \param  uint8_t*  pSupportedMCSSet
+   \return none
+   -------------------------------------------------------------*/
+void lim_fill_rx_highest_supported_rate(tpAniSirGlobal pMac,
+					uint16_t *rxHighestRate,
+					uint8_t *pSupportedMCSSet)
+{
+	tSirMacRxHighestSupportRate *pRxHighestRate;
+	uint8_t *pBuf;
+	uint16_t rate = 0;
+
+	pBuf = pSupportedMCSSet + MCS_RX_HIGHEST_SUPPORTED_RATE_BYTE_OFFSET;
+	rate = lim_get_u16(pBuf);
+
+	pRxHighestRate = (tSirMacRxHighestSupportRate *) &rate;
+	*rxHighestRate = pRxHighestRate->rate;
+
+	return;
+}
+
+#ifdef WLAN_FEATURE_11W
+/** -------------------------------------------------------------
+   \fn     lim_send_sme_unprotected_mgmt_frame_ind
+   \brief  Forwards the unprotected management frame to SME.
+   \param  tpAniSirGlobal    pMac
+   \param  frameType - 802.11 frame type
+   \param  frame - frame buffer
+   \param  sessionId - id for the current session
+   \param  psessionEntry - PE session context
+   \return none
+   -------------------------------------------------------------*/
+void lim_send_sme_unprotected_mgmt_frame_ind(tpAniSirGlobal pMac, uint8_t frameType,
+					     uint8_t *frame, uint32_t frameLen,
+					     uint16_t sessionId,
+					     tpPESession psessionEntry)
+{
+	struct scheduler_msg mmhMsg = {0};
+	tSirSmeUnprotMgmtFrameInd *pSirSmeMgmtFrame = NULL;
+	uint16_t length;
+
+	length = sizeof(tSirSmeUnprotMgmtFrameInd) + frameLen;
+
+	pSirSmeMgmtFrame = qdf_mem_malloc(length);
+	if (!pSirSmeMgmtFrame)
+		return;
+
+	pSirSmeMgmtFrame->sessionId = sessionId;
+	pSirSmeMgmtFrame->frameType = frameType;
+
+	qdf_mem_copy(pSirSmeMgmtFrame->frameBuf, frame, frameLen);
+	pSirSmeMgmtFrame->frameLen = frameLen;
+
+	mmhMsg.type = eWNI_SME_UNPROT_MGMT_FRM_IND;
+	mmhMsg.bodyptr = pSirSmeMgmtFrame;
+	mmhMsg.bodyval = 0;
+
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+	return;
+}
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+/** -------------------------------------------------------------
+   \fn     lim_send_sme_tsm_ie_ind
+   \brief  Forwards the TSM IE information to SME.
+   \param  tpAniSirGlobal    pMac
+   \param  psessionEntry - PE session context
+   \param  tid - traffic id
+   \param  state - tsm state (enabled/disabled)
+   \param  measurementInterval - measurement interval
+   \return none
+   -------------------------------------------------------------*/
+void lim_send_sme_tsm_ie_ind(tpAniSirGlobal pMac, tpPESession psessionEntry,
+			     uint8_t tid, uint8_t state, uint16_t measInterval)
+{
+	struct scheduler_msg mmhMsg = {0};
+	tpSirSmeTsmIEInd pSirSmeTsmIeInd = NULL;
+
+	if (!pMac || !psessionEntry)
+		return;
+
+	pSirSmeTsmIeInd = qdf_mem_malloc(sizeof(tSirSmeTsmIEInd));
+	if (!pSirSmeTsmIeInd)
+		return;
+
+	pSirSmeTsmIeInd->sessionId = psessionEntry->smeSessionId;
+	pSirSmeTsmIeInd->tsmIe.tsid = tid;
+	pSirSmeTsmIeInd->tsmIe.state = state;
+	pSirSmeTsmIeInd->tsmIe.msmt_interval = measInterval;
+
+	mmhMsg.type = eWNI_SME_TSM_IE_IND;
+	mmhMsg.bodyptr = pSirSmeTsmIeInd;
+	mmhMsg.bodyval = 0;
+
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+	return;
+}
+#endif /* FEATURE_WLAN_ESE */
diff --git a/core/mac/src/pe/lim/lim_assoc_utils.h b/core/mac/src/pe/lim/lim_assoc_utils.h
new file mode 100644
index 0000000..6b11583
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_assoc_utils.h
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * This file lim_assoc_utils.h contains the utility definitions
+ * LIM uses while processing Re/Association messages.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ * 05/26/10       js             WPA handling in (Re)Assoc frames
+ *
+ */
+#ifndef __LIM_ASSOC_UTILS_H
+#define __LIM_ASSOC_UTILS_H
+
+#include "sir_api.h"
+#include "sir_debug.h"
+#include "cfg_api.h"
+
+#include "lim_types.h"
+
+#define SIZE_OF_NOA_DESCRIPTOR 13
+#define MAX_NOA_PERIOD_IN_MICROSECS 3000000
+
+uint32_t lim_cmp_ssid(tSirMacSSid *, tpPESession);
+uint8_t lim_compare_capabilities(tpAniSirGlobal,
+				 tSirAssocReq *,
+				 tSirMacCapabilityInfo *, tpPESession);
+uint8_t lim_check_rx_basic_rates(tpAniSirGlobal, tSirMacRateSet, tpPESession);
+uint8_t lim_check_rx_rsn_ie_match(tpAniSirGlobal mac_ctx,
+				  tDot11fIERSN * const rx_rsn_ie,
+				  tpPESession session_entry, uint8_t sta_is_ht,
+				  bool *pmf_connection);
+uint8_t lim_check_rx_wpa_ie_match(tpAniSirGlobal, tDot11fIEWPA, tpPESession,
+				  uint8_t);
+uint8_t lim_check_mcs_set(tpAniSirGlobal pMac, uint8_t *supportedMCSSet);
+void limPostDummyToTmRing(tpAniSirGlobal, tpDphHashNode);
+void limPostPacketToTdRing(tpAniSirGlobal, tpDphHashNode, uint8_t);
+QDF_STATUS lim_cleanup_rx_path(tpAniSirGlobal, tpDphHashNode, tpPESession);
+void lim_reject_association(tpAniSirGlobal, tSirMacAddr, uint8_t,
+			    uint8_t, tAniAuthType, uint16_t, uint8_t,
+			    enum eSirMacStatusCodes, tpPESession);
+
+QDF_STATUS lim_populate_peer_rate_set(tpAniSirGlobal pMac,
+					 tpSirSupportedRates pRates,
+					 uint8_t *pSupportedMCSSet,
+					 uint8_t basicOnly,
+					 tpPESession psessionEntry,
+					 tDot11fIEVHTCaps *pVHTCaps,
+					 tDot11fIEhe_cap *he_caps);
+
+QDF_STATUS lim_populate_own_rate_set(tpAniSirGlobal pMac,
+					tpSirSupportedRates pRates,
+					uint8_t *pSupportedMCSSet,
+					uint8_t basicOnly,
+					tpPESession psessionEntry,
+					tDot11fIEVHTCaps *pVHTCaps,
+					tDot11fIEhe_cap *he_caps);
+
+QDF_STATUS
+lim_populate_matching_rate_set(tpAniSirGlobal pMac,
+			       tpDphHashNode pStaDs,
+			       tSirMacRateSet *pOperRateSet,
+			       tSirMacRateSet *pExtRateSet,
+			       uint8_t *pSupportedMCSSet,
+			       tpPESession psessionEntry,
+			       tDot11fIEVHTCaps *pVHTCaps,
+			       tDot11fIEhe_cap *he_caps);
+
+QDF_STATUS lim_add_sta(tpAniSirGlobal, tpDphHashNode, uint8_t, tpPESession);
+QDF_STATUS lim_del_bss(tpAniSirGlobal, tpDphHashNode, uint16_t, tpPESession);
+QDF_STATUS lim_del_sta(tpAniSirGlobal, tpDphHashNode, bool, tpPESession);
+QDF_STATUS lim_add_sta_self(tpAniSirGlobal, uint16_t, uint8_t, tpPESession);
+
+void lim_teardown_infra_bss(tpAniSirGlobal, tpPESession);
+#ifdef WLAN_FEATURE_HOST_ROAM
+void lim_restore_pre_reassoc_state(tpAniSirGlobal,
+				   tSirResultCodes, uint16_t, tpPESession);
+void lim_post_reassoc_failure(tpAniSirGlobal,
+			      tSirResultCodes, uint16_t, tpPESession);
+bool lim_is_reassoc_in_progress(tpAniSirGlobal, tpPESession);
+
+void lim_handle_add_bss_in_re_assoc_context(tpAniSirGlobal pMac,
+		tpDphHashNode pStaDs, tpPESession psessionEntry);
+void lim_handle_del_bss_in_re_assoc_context(tpAniSirGlobal pMac,
+		   tpDphHashNode pStaDs, tpPESession psessionEntry);
+void lim_send_retry_reassoc_req_frame(tpAniSirGlobal pMac,
+	      tLimMlmReassocReq *pMlmReassocReq, tpPESession psessionEntry);
+QDF_STATUS lim_add_ft_sta_self(tpAniSirGlobal pMac, uint16_t assocId,
+				  tpPESession psessionEntry);
+#else
+static inline void lim_restore_pre_reassoc_state(tpAniSirGlobal mac_ctx,
+			tSirResultCodes res_code, uint16_t prot_status,
+			tpPESession pe_session)
+{}
+static inline void lim_post_reassoc_failure(tpAniSirGlobal mac_ctx,
+			      tSirResultCodes res_code, uint16_t prot_status,
+			      tpPESession pe_session)
+{}
+static inline void lim_handle_add_bss_in_re_assoc_context(tpAniSirGlobal pMac,
+		tpDphHashNode pStaDs, tpPESession psessionEntry)
+{}
+static inline void lim_handle_del_bss_in_re_assoc_context(tpAniSirGlobal pMac,
+		   tpDphHashNode pStaDs, tpPESession psessionEntry)
+{}
+static inline void lim_send_retry_reassoc_req_frame(tpAniSirGlobal pMac,
+	      tLimMlmReassocReq *pMlmReassocReq, tpPESession psessionEntry)
+{}
+static inline bool lim_is_reassoc_in_progress(tpAniSirGlobal mac_ctx,
+		tpPESession pe_session)
+{
+	return false;
+}
+static inline QDF_STATUS lim_add_ft_sta_self(tpAniSirGlobal pMac,
+		uint16_t assocId, tpPESession psessionEntry)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static inline bool lim_is_roam_synch_in_progress(tpPESession pe_session)
+{
+	return pe_session->bRoamSynchInProgress;
+}
+#else
+static inline bool lim_is_roam_synch_in_progress(tpPESession pe_session)
+{
+	return false;
+}
+#endif
+
+void
+lim_send_del_sta_cnf(tpAniSirGlobal pMac, struct qdf_mac_addr sta_dsaddr,
+		     uint16_t staDsAssocId, tLimMlmStaContext mlmStaContext,
+		     tSirResultCodes statusCode, tpPESession psessionEntry);
+
+void lim_handle_cnf_wait_timeout(tpAniSirGlobal pMac, uint16_t staId);
+void lim_delete_dph_hash_entry(tpAniSirGlobal, tSirMacAddr, uint16_t, tpPESession);
+void lim_check_and_announce_join_success(tpAniSirGlobal,
+					 tSirProbeRespBeacon *,
+					 tpSirMacMgmtHdr, tpPESession);
+void lim_update_re_assoc_globals(tpAniSirGlobal pMac,
+				 tpSirAssocRsp pAssocRsp,
+				 tpPESession psessionEntry);
+
+void lim_update_assoc_sta_datas(tpAniSirGlobal pMac,
+				tpDphHashNode pStaDs, tpSirAssocRsp pAssocRsp,
+				tpPESession psessionEntry);
+
+QDF_STATUS lim_sta_send_add_bss(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
+				   tpSchBeaconStruct pBeaconStruct,
+				   tpSirBssDescription bssDescription,
+				   uint8_t updateEntry, tpPESession psessionEntry);
+QDF_STATUS lim_sta_send_add_bss_pre_assoc(tpAniSirGlobal pMac, uint8_t updateEntry,
+					     tpPESession psessionEntry);
+
+void lim_prepare_and_send_del_sta_cnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+				      tSirResultCodes statusCode, tpPESession);
+QDF_STATUS lim_extract_ap_capabilities(tpAniSirGlobal pMac, uint8_t *pIE,
+					  uint16_t ieLen,
+					  tpSirProbeRespBeacon beaconStruct);
+void lim_init_pre_auth_timer_table(tpAniSirGlobal pMac,
+				   tpLimPreAuthTable pPreAuthTimerTable);
+tpLimPreAuthNode lim_acquire_free_pre_auth_node(tpAniSirGlobal pMac,
+						tpLimPreAuthTable
+						pPreAuthTimerTable);
+tpLimPreAuthNode lim_get_pre_auth_node_from_index(tpAniSirGlobal pMac,
+						  tpLimPreAuthTable pAuthTable,
+						  uint32_t authNodeIdx);
+
+/* Util API to check if the channels supported by STA is within range */
+QDF_STATUS lim_is_dot11h_supported_channels_valid(tpAniSirGlobal pMac,
+						     tSirAssocReq *assoc);
+
+/* Util API to check if the txpower supported by STA is within range */
+QDF_STATUS lim_is_dot11h_power_capabilities_in_range(tpAniSirGlobal pMac,
+							tSirAssocReq *assoc,
+							tpPESession);
+/* API to fill in RX Highest Supported data Rate */
+void lim_fill_rx_highest_supported_rate(tpAniSirGlobal pMac,
+					uint16_t *rxHighestRate,
+					uint8_t *pSupportedMCSSet);
+#ifdef WLAN_FEATURE_11W
+void lim_send_sme_unprotected_mgmt_frame_ind(tpAniSirGlobal pMac, uint8_t frameType,
+					     uint8_t *frame, uint32_t frameLen,
+					     uint16_t sessionId,
+					     tpPESession psessionEntry);
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+void lim_send_sme_tsm_ie_ind(tpAniSirGlobal pMac, tpPESession psessionEntry,
+			     uint8_t tid, uint8_t state, uint16_t measInterval);
+#else
+static inline void lim_send_sme_tsm_ie_ind(tpAniSirGlobal pMac,
+	tpPESession psessionEntry, uint8_t tid,
+	uint8_t state, uint16_t measInterval)
+{}
+#endif /* FEATURE_WLAN_ESE */
+
+QDF_STATUS lim_populate_vht_mcs_set(tpAniSirGlobal pMac,
+				       tpSirSupportedRates pRates,
+				       tDot11fIEVHTCaps *pPeerVHTCaps,
+				       tpPESession psessionEntry,
+				       uint8_t nss);
+
+#endif /* __LIM_ASSOC_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_ft.c b/core/mac/src/pe/lim/lim_ft.c
new file mode 100644
index 0000000..72ad125
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ft.c
@@ -0,0 +1,1089 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/**=========================================================================
+
+   \brief implementation for PE 11r VoWiFi FT Protocol
+
+   ========================================================================*/
+
+/* $Header$ */
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include <lim_send_messages.h>
+#include <lim_types.h>
+#include <lim_ft.h>
+#include <lim_ft_defs.h>
+#include <lim_utils.h>
+#include <lim_prop_exts_utils.h>
+#include <lim_assoc_utils.h>
+#include <lim_session.h>
+#include <lim_admit_control.h>
+#include "wmm_apsd.h"
+#include "wma.h"
+
+extern void lim_send_set_sta_key_req(tpAniSirGlobal pMac,
+				     tLimMlmSetKeysReq * pMlmSetKeysReq,
+				     uint16_t staIdx,
+				     uint8_t defWEPIdx,
+				     tpPESession sessionEntry, bool sendRsp);
+
+/*--------------------------------------------------------------------------
+   Initialize the FT variables.
+   ------------------------------------------------------------------------*/
+void lim_ft_open(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	if (psessionEntry)
+		qdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext),
+			    0);
+}
+
+void lim_ft_cleanup_all_ft_sessions(tpAniSirGlobal pMac)
+{
+	/* Wrapper function to cleanup all FT sessions */
+	int i;
+
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		if (true == pMac->lim.gpSession[i].valid) {
+			/* The session is valid, may have FT data */
+			lim_ft_cleanup(pMac, &pMac->lim.gpSession[i]);
+		}
+	}
+}
+
+void lim_ft_cleanup(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	if (NULL == psessionEntry) {
+		pe_err("psessionEntry is NULL");
+		return;
+	}
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("psessionEntry is not in STA mode");
+		return;
+	}
+
+	if (NULL != psessionEntry->ftPEContext.pFTPreAuthReq) {
+		pe_debug("Freeing pFTPreAuthReq: %pK",
+			       psessionEntry->ftPEContext.pFTPreAuthReq);
+		if (NULL !=
+		    psessionEntry->ftPEContext.pFTPreAuthReq->
+		    pbssDescription) {
+			qdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq->
+				     pbssDescription);
+			psessionEntry->ftPEContext.pFTPreAuthReq->
+			pbssDescription = NULL;
+		}
+		qdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq);
+		psessionEntry->ftPEContext.pFTPreAuthReq = NULL;
+	}
+
+	if (psessionEntry->ftPEContext.pAddBssReq) {
+		qdf_mem_free(psessionEntry->ftPEContext.pAddBssReq);
+		psessionEntry->ftPEContext.pAddBssReq = NULL;
+	}
+
+	if (psessionEntry->ftPEContext.pAddStaReq) {
+		qdf_mem_free(psessionEntry->ftPEContext.pAddStaReq);
+		psessionEntry->ftPEContext.pAddStaReq = NULL;
+	}
+
+	/* The session is being deleted, cleanup the contents */
+	qdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0);
+}
+
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/*------------------------------------------------------------------
+ *
+ * Create the new Add Bss Req to the new AP.
+ * This will be used when we are ready to FT to the new AP.
+ * The newly created ft Session entry is passed to this function
+ *
+ *------------------------------------------------------------------*/
+void lim_ft_prepare_add_bss_req(tpAniSirGlobal pMac,
+		uint8_t updateEntry, tpPESession pftSessionEntry,
+		tpSirBssDescription bssDescription)
+{
+	tpAddBssParams pAddBssParams = NULL;
+	tAddStaParams *sta_ctx;
+	uint8_t chanWidthSupp = 0;
+	tSchBeaconStruct *pBeaconStruct;
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(pftSessionEntry)) {
+		pe_err("psessionEntry is not in STA mode");
+		return;
+	}
+
+	pBeaconStruct = qdf_mem_malloc(sizeof(tSchBeaconStruct));
+	if (!pBeaconStruct)
+		return;
+
+	/* Package SIR_HAL_ADD_BSS_REQ message parameters */
+	pAddBssParams = qdf_mem_malloc(sizeof(tAddBssParams));
+	if (!pAddBssParams) {
+		qdf_mem_free(pBeaconStruct);
+		return;
+	}
+
+	lim_extract_ap_capabilities(pMac, (uint8_t *) bssDescription->ieFields,
+			lim_get_ielen_from_bss_description(bssDescription),
+			pBeaconStruct);
+
+	if (pMac->lim.gLimProtectionControl !=
+	    MLME_FORCE_POLICY_PROTECTION_DISABLE)
+		lim_decide_sta_protection_on_assoc(pMac, pBeaconStruct,
+						   pftSessionEntry);
+
+	qdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
+		     sizeof(tSirMacAddr));
+
+	/* Fill in tAddBssParams selfMacAddr */
+	qdf_mem_copy(pAddBssParams->selfMacAddr, pftSessionEntry->selfMacAddr,
+		     sizeof(tSirMacAddr));
+
+	pAddBssParams->bssType = pftSessionEntry->bssType;
+	pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
+
+	pAddBssParams->beaconInterval = bssDescription->beaconInterval;
+
+	pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
+	pAddBssParams->updateBss = updateEntry;
+
+	pAddBssParams->reassocReq = true;
+
+	pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount;
+	pAddBssParams->cfParamSet.cfpPeriod =
+		pBeaconStruct->cfParamSet.cfpPeriod;
+	pAddBssParams->cfParamSet.cfpMaxDuration =
+		pBeaconStruct->cfParamSet.cfpMaxDuration;
+	pAddBssParams->cfParamSet.cfpDurRemaining =
+		pBeaconStruct->cfParamSet.cfpDurRemaining;
+
+	pAddBssParams->rateSet.numRates =
+		pBeaconStruct->supportedRates.numRates;
+	qdf_mem_copy(pAddBssParams->rateSet.rate,
+		     pBeaconStruct->supportedRates.rate,
+		     pBeaconStruct->supportedRates.numRates);
+
+	pAddBssParams->nwType = bssDescription->nwType;
+
+	pAddBssParams->shortSlotTimeSupported =
+		(uint8_t) pBeaconStruct->capabilityInfo.shortSlotTime;
+	pAddBssParams->llaCoexist =
+		(uint8_t) pftSessionEntry->beaconParams.llaCoexist;
+	pAddBssParams->llbCoexist =
+		(uint8_t) pftSessionEntry->beaconParams.llbCoexist;
+	pAddBssParams->llgCoexist =
+		(uint8_t) pftSessionEntry->beaconParams.llgCoexist;
+	pAddBssParams->ht20Coexist =
+		(uint8_t) pftSessionEntry->beaconParams.ht20Coexist;
+#ifdef WLAN_FEATURE_11W
+	pAddBssParams->rmfEnabled = pftSessionEntry->limRmfEnabled;
+#endif
+
+	/* Use the advertised capabilities from the received beacon/PR */
+	if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) &&
+	    (pBeaconStruct->HTCaps.present)) {
+		pAddBssParams->htCapable = pBeaconStruct->HTCaps.present;
+		qdf_mem_copy(&pAddBssParams->staContext.capab_info,
+			     &pBeaconStruct->capabilityInfo,
+			     sizeof(pAddBssParams->staContext.capab_info));
+		qdf_mem_copy(&pAddBssParams->staContext.ht_caps,
+			     (uint8_t *) &pBeaconStruct->HTCaps +
+			     sizeof(uint8_t),
+			     sizeof(pAddBssParams->staContext.ht_caps));
+
+		if (pBeaconStruct->HTInfo.present) {
+			pAddBssParams->htOperMode =
+				(tSirMacHTOperatingMode) pBeaconStruct->HTInfo.
+				opMode;
+			pAddBssParams->dualCTSProtection =
+				(uint8_t) pBeaconStruct->HTInfo.dualCTSProtection;
+
+			chanWidthSupp = lim_get_ht_capability(pMac,
+							      eHT_SUPPORTED_CHANNEL_WIDTH_SET,
+							      pftSessionEntry);
+			if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
+			    (chanWidthSupp)) {
+				pAddBssParams->ch_width = (uint8_t)
+					pBeaconStruct->HTInfo.recommendedTxWidthSet;
+				if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+						PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+					pAddBssParams->ch_center_freq_seg0 =
+						bssDescription->channelId + 2;
+				else if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+						PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+					pAddBssParams->ch_center_freq_seg0 =
+						bssDescription->channelId - 2;
+			} else {
+				pAddBssParams->ch_width = CH_WIDTH_20MHZ;
+				pAddBssParams->ch_center_freq_seg0 = 0;
+			}
+			pAddBssParams->llnNonGFCoexist =
+				(uint8_t) pBeaconStruct->HTInfo.nonGFDevicesPresent;
+			pAddBssParams->fLsigTXOPProtectionFullSupport =
+				(uint8_t) pBeaconStruct->HTInfo.
+				lsigTXOPProtectionFullSupport;
+			pAddBssParams->fRIFSMode =
+				pBeaconStruct->HTInfo.rifsMode;
+		}
+	}
+
+	pAddBssParams->currentOperChannel = bssDescription->channelId;
+	pftSessionEntry->htSecondaryChannelOffset =
+		pBeaconStruct->HTInfo.secondaryChannelOffset;
+	sta_ctx = &pAddBssParams->staContext;
+
+	if (pftSessionEntry->vhtCapability &&
+	    pftSessionEntry->vhtCapabilityPresentInBeacon) {
+		pAddBssParams->vhtCapable = pBeaconStruct->VHTCaps.present;
+		if (pBeaconStruct->VHTOperation.chanWidth && chanWidthSupp) {
+			pAddBssParams->ch_width =
+				pBeaconStruct->VHTOperation.chanWidth + 1;
+			pAddBssParams->ch_center_freq_seg0 =
+				pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
+			pAddBssParams->ch_center_freq_seg1 =
+				pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
+		}
+		pAddBssParams->staContext.vht_caps =
+			((pBeaconStruct->VHTCaps.maxMPDULen <<
+			  SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
+			 (pBeaconStruct->VHTCaps.supportedChannelWidthSet <<
+			  SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
+			 (pBeaconStruct->VHTCaps.ldpcCodingCap <<
+			  SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
+			 (pBeaconStruct->VHTCaps.shortGI80MHz <<
+			  SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
+			 (pBeaconStruct->VHTCaps.shortGI160and80plus80MHz <<
+			  SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
+			 (pBeaconStruct->VHTCaps.txSTBC <<
+			  SIR_MAC_VHT_CAP_TXSTBC) |
+			 (pBeaconStruct->VHTCaps.rxSTBC <<
+			  SIR_MAC_VHT_CAP_RXSTBC) |
+			 (pBeaconStruct->VHTCaps.suBeamFormerCap <<
+			  SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
+			 (pBeaconStruct->VHTCaps.suBeamformeeCap <<
+			  SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
+			 (pBeaconStruct->VHTCaps.csnofBeamformerAntSup <<
+			  SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
+			 (pBeaconStruct->VHTCaps.numSoundingDim <<
+			  SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
+			 (pBeaconStruct->VHTCaps.muBeamformerCap <<
+			  SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) |
+			 (pBeaconStruct->VHTCaps.muBeamformeeCap <<
+			  SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
+			 (pBeaconStruct->VHTCaps.vhtTXOPPS <<
+			  SIR_MAC_VHT_CAP_TXOPPS) |
+			 (pBeaconStruct->VHTCaps.htcVHTCap <<
+			  SIR_MAC_VHT_CAP_HTC_CAP) |
+			 (pBeaconStruct->VHTCaps.maxAMPDULenExp <<
+			  SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
+			 (pBeaconStruct->VHTCaps.vhtLinkAdaptCap <<
+			  SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
+			 (pBeaconStruct->VHTCaps.rxAntPattern <<
+			  SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
+			 (pBeaconStruct->VHTCaps.txAntPattern <<
+			  SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
+			 (pBeaconStruct->VHTCaps.reserved1 <<
+			  SIR_MAC_VHT_CAP_RESERVED2));
+	} else {
+		pAddBssParams->vhtCapable = 0;
+	}
+
+	pe_debug("SIR_HAL_ADD_BSS_REQ with channel: %d",
+		pAddBssParams->currentOperChannel);
+
+	/* Populate the STA-related parameters here */
+	/* Note that the STA here refers to the AP */
+	{
+		pAddBssParams->staContext.staType = STA_ENTRY_OTHER;
+
+		qdf_mem_copy(pAddBssParams->staContext.bssId,
+			     bssDescription->bssId, sizeof(tSirMacAddr));
+		pAddBssParams->staContext.listenInterval =
+			bssDescription->beaconInterval;
+
+		pAddBssParams->staContext.assocId = 0;
+		pAddBssParams->staContext.uAPSD = 0;
+		pAddBssParams->staContext.maxSPLen = 0;
+		pAddBssParams->staContext.shortPreambleSupported =
+			(uint8_t) pBeaconStruct->capabilityInfo.shortPreamble;
+		pAddBssParams->staContext.updateSta = updateEntry;
+		pAddBssParams->staContext.encryptType =
+			pftSessionEntry->encryptType;
+#ifdef WLAN_FEATURE_11W
+		pAddBssParams->staContext.rmfEnabled =
+			pftSessionEntry->limRmfEnabled;
+#endif
+
+		if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) &&
+		    (pBeaconStruct->HTCaps.present)) {
+			pAddBssParams->staContext.us32MaxAmpduDuration = 0;
+			pAddBssParams->staContext.htCapable = 1;
+			pAddBssParams->staContext.greenFieldCapable =
+				(uint8_t) pBeaconStruct->HTCaps.greenField;
+			pAddBssParams->staContext.lsigTxopProtection =
+				(uint8_t) pBeaconStruct->HTCaps.lsigTXOPProtection;
+			if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
+			    (chanWidthSupp)) {
+				pAddBssParams->staContext.ch_width = (uint8_t)
+					pBeaconStruct->HTInfo.recommendedTxWidthSet;
+			} else {
+				pAddBssParams->staContext.ch_width =
+					CH_WIDTH_20MHZ;
+			}
+			if (pftSessionEntry->vhtCapability &&
+			    IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) {
+				pAddBssParams->staContext.vhtCapable = 1;
+				if ((pBeaconStruct->VHTCaps.suBeamFormerCap ||
+				     pBeaconStruct->VHTCaps.muBeamformerCap) &&
+				    pftSessionEntry->vht_config.su_beam_formee)
+					sta_ctx->vhtTxBFCapable
+						= 1;
+				if (pBeaconStruct->VHTCaps.suBeamformeeCap &&
+				    pftSessionEntry->vht_config.su_beam_former)
+					sta_ctx->enable_su_tx_bformer = 1;
+			}
+			if (lim_is_session_he_capable(pftSessionEntry) &&
+				pBeaconStruct->he_cap.present)
+				lim_intersect_ap_he_caps(pftSessionEntry,
+					pAddBssParams, pBeaconStruct, NULL);
+
+			if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
+			    (chanWidthSupp)) {
+				sta_ctx->ch_width = (uint8_t)
+					pBeaconStruct->HTInfo.recommendedTxWidthSet;
+				if (pAddBssParams->staContext.vhtCapable &&
+					pBeaconStruct->VHTOperation.chanWidth)
+					sta_ctx->ch_width =
+					pBeaconStruct->VHTOperation.chanWidth
+						+ 1;
+			} else {
+				pAddBssParams->staContext.ch_width =
+					CH_WIDTH_20MHZ;
+			}
+			pAddBssParams->staContext.mimoPS =
+				(tSirMacHTMIMOPowerSaveState) pBeaconStruct->HTCaps.
+				mimoPowerSave;
+			pAddBssParams->staContext.maxAmsduSize =
+				(uint8_t) pBeaconStruct->HTCaps.maximalAMSDUsize;
+			pAddBssParams->staContext.maxAmpduDensity =
+				pBeaconStruct->HTCaps.mpduDensity;
+			pAddBssParams->staContext.fDsssCckMode40Mhz =
+				(uint8_t) pBeaconStruct->HTCaps.dsssCckMode40MHz;
+			pAddBssParams->staContext.fShortGI20Mhz =
+				(uint8_t) pBeaconStruct->HTCaps.shortGI20MHz;
+			pAddBssParams->staContext.fShortGI40Mhz =
+				(uint8_t) pBeaconStruct->HTCaps.shortGI40MHz;
+			pAddBssParams->staContext.maxAmpduSize =
+				pBeaconStruct->HTCaps.maxRxAMPDUFactor;
+
+			if (pBeaconStruct->HTInfo.present)
+				pAddBssParams->staContext.rifsMode =
+					pBeaconStruct->HTInfo.rifsMode;
+		}
+
+		if ((pftSessionEntry->limWmeEnabled
+		     && pBeaconStruct->wmeEdcaPresent)
+		    || (pftSessionEntry->limQosEnabled
+			&& pBeaconStruct->edcaPresent))
+			pAddBssParams->staContext.wmmEnabled = 1;
+		else
+			pAddBssParams->staContext.wmmEnabled = 0;
+
+		pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent;
+		/* For OSEN Connection AP does not advertise RSN or WPA IE
+		 * so from the IEs we get from supplicant we get this info
+		 * so for FW to transmit EAPOL message 4 we shall set
+		 * wpa_rsn
+		 */
+		pAddBssParams->staContext.wpa_rsn |=
+			(pBeaconStruct->wpaPresent << 1);
+		if ((!pAddBssParams->staContext.wpa_rsn)
+		    && (pftSessionEntry->isOSENConnection))
+			pAddBssParams->staContext.wpa_rsn = 1;
+		/* Update the rates */
+		lim_populate_peer_rate_set(pMac,
+					   &pAddBssParams->staContext.
+					   supportedRates,
+					   pBeaconStruct->HTCaps.supportedMCSSet,
+					   false, pftSessionEntry,
+					   &pBeaconStruct->VHTCaps,
+					   &pBeaconStruct->he_cap);
+	}
+
+	pAddBssParams->maxTxPower = pftSessionEntry->maxTxPower;
+
+#ifdef WLAN_FEATURE_11W
+	if (pftSessionEntry->limRmfEnabled) {
+		pAddBssParams->rmfEnabled = 1;
+		pAddBssParams->staContext.rmfEnabled = 1;
+	}
+#endif
+
+	pAddBssParams->status = QDF_STATUS_SUCCESS;
+	pAddBssParams->respReqd = true;
+
+	pAddBssParams->staContext.sessionId = pftSessionEntry->peSessionId;
+	pAddBssParams->staContext.smesessionId = pftSessionEntry->smeSessionId;
+	pAddBssParams->sessionId = pftSessionEntry->peSessionId;
+
+	/* Set a new state for MLME */
+	if (!lim_is_roam_synch_in_progress(pftSessionEntry)) {
+		pftSessionEntry->limMlmState =
+			eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE;
+		MTRACE(mac_trace
+			(pMac, TRACE_CODE_MLM_STATE,
+			pftSessionEntry->peSessionId,
+			eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE));
+	}
+	pAddBssParams->halPersona = (uint8_t) pftSessionEntry->pePersona;
+
+	pftSessionEntry->ftPEContext.pAddBssReq = pAddBssParams;
+
+	pe_debug("Saving SIR_HAL_ADD_BSS_REQ for pre-auth ap");
+
+	qdf_mem_free(pBeaconStruct);
+	return;
+}
+#endif
+
+#if defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * lim_fill_dot11mode() - to fill 802.11 mode in FT session
+ * @mac_ctx: pointer to mac ctx
+ * @pftSessionEntry: FT session
+ * @psessionEntry: PE session
+ *
+ * This API fills FT session's dot11mode either from pe session or
+ * from CFG depending on the condition.
+ *
+ * Return: none
+ */
+static void lim_fill_dot11mode(tpAniSirGlobal mac_ctx,
+			tpPESession pftSessionEntry, tpPESession psessionEntry)
+{
+	uint32_t self_dot11_mode;
+
+	if (psessionEntry->ftPEContext.pFTPreAuthReq &&
+			!mac_ctx->roam.configParam.isRoamOffloadEnabled) {
+		pftSessionEntry->dot11mode =
+			psessionEntry->ftPEContext.pFTPreAuthReq->dot11mode;
+	} else {
+		wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_dot11_mode);
+		pe_debug("selfDot11Mode: %d", self_dot11_mode);
+		pftSessionEntry->dot11mode = self_dot11_mode;
+	}
+}
+#elif defined(WLAN_FEATURE_HOST_ROAM)
+/**
+ * lim_fill_dot11mode() - to fill 802.11 mode in FT session
+ * @mac_ctx: pointer to mac ctx
+ * @pftSessionEntry: FT session
+ * @psessionEntry: PE session
+ *
+ * This API fills FT session's dot11mode either from pe session.
+ *
+ * Return: none
+ */
+static void lim_fill_dot11mode(tpAniSirGlobal mac_ctx,
+			tpPESession pftSessionEntry, tpPESession psessionEntry)
+{
+	pftSessionEntry->dot11mode =
+			psessionEntry->ftPEContext.pFTPreAuthReq->dot11mode;
+}
+#endif
+
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/*------------------------------------------------------------------
+ *
+ * Setup the new session for the pre-auth AP.
+ * Return the newly created session entry.
+ *
+ *------------------------------------------------------------------*/
+void lim_fill_ft_session(tpAniSirGlobal pMac,
+			 tpSirBssDescription pbssDescription,
+			 tpPESession pftSessionEntry, tpPESession psessionEntry)
+{
+	uint8_t currentBssUapsd;
+	int8_t localPowerConstraint;
+	int8_t regMax;
+	tSchBeaconStruct *pBeaconStruct;
+	ePhyChanBondState cbEnabledMode;
+
+	pBeaconStruct = qdf_mem_malloc(sizeof(tSchBeaconStruct));
+	if (!pBeaconStruct)
+		return;
+
+	/* Retrieve the session that was already created and update the entry */
+	pftSessionEntry->limWmeEnabled = psessionEntry->limWmeEnabled;
+	pftSessionEntry->limQosEnabled = psessionEntry->limQosEnabled;
+	pftSessionEntry->limWsmEnabled = psessionEntry->limWsmEnabled;
+	pftSessionEntry->lim11hEnable = psessionEntry->lim11hEnable;
+	pftSessionEntry->isOSENConnection = psessionEntry->isOSENConnection;
+
+	/* Fields to be filled later */
+	pftSessionEntry->pLimJoinReq = NULL;
+	pftSessionEntry->smeSessionId = psessionEntry->smeSessionId;
+	pftSessionEntry->transactionId = 0;
+
+	lim_extract_ap_capabilities(pMac, (uint8_t *) pbssDescription->ieFields,
+			lim_get_ielen_from_bss_description(pbssDescription),
+			pBeaconStruct);
+
+	pftSessionEntry->rateSet.numRates =
+		pBeaconStruct->supportedRates.numRates;
+	qdf_mem_copy(pftSessionEntry->rateSet.rate,
+		     pBeaconStruct->supportedRates.rate,
+		     pBeaconStruct->supportedRates.numRates);
+
+	pftSessionEntry->extRateSet.numRates =
+		pBeaconStruct->extendedRates.numRates;
+	qdf_mem_copy(pftSessionEntry->extRateSet.rate,
+		     pBeaconStruct->extendedRates.rate,
+		     pftSessionEntry->extRateSet.numRates);
+
+	pftSessionEntry->ssId.length = pBeaconStruct->ssId.length;
+	qdf_mem_copy(pftSessionEntry->ssId.ssId, pBeaconStruct->ssId.ssId,
+		     pftSessionEntry->ssId.length);
+	lim_fill_dot11mode(pMac, pftSessionEntry, psessionEntry);
+
+	pe_debug("dot11mode: %d", pftSessionEntry->dot11mode);
+	pftSessionEntry->vhtCapability =
+		(IS_DOT11_MODE_VHT(pftSessionEntry->dot11mode)
+		 && IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps));
+	pftSessionEntry->htCapability =
+		(IS_DOT11_MODE_HT(pftSessionEntry->dot11mode)
+		 && pBeaconStruct->HTCaps.present);
+
+	/* Copy The channel Id to the session Table */
+	pftSessionEntry->limReassocChannelId = pbssDescription->channelId;
+	pftSessionEntry->currentOperChannel = pbssDescription->channelId;
+
+	pftSessionEntry->limRFBand = lim_get_rf_band(
+				pftSessionEntry->currentOperChannel);
+
+	if (pftSessionEntry->limRFBand == BAND_2G) {
+		cbEnabledMode = pMac->roam.configParam.channelBondingMode24GHz;
+	} else {
+		cbEnabledMode = pMac->roam.configParam.channelBondingMode5GHz;
+	}
+	pftSessionEntry->htSupportedChannelWidthSet =
+	    (pBeaconStruct->HTInfo.present) ?
+	    (cbEnabledMode && pBeaconStruct->HTInfo.recommendedTxWidthSet) : 0;
+	pftSessionEntry->htRecommendedTxWidthSet =
+		pftSessionEntry->htSupportedChannelWidthSet;
+
+	if (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) &&
+		pBeaconStruct->VHTOperation.present &&
+		pftSessionEntry->vhtCapability) {
+		pftSessionEntry->vhtCapabilityPresentInBeacon = 1;
+	} else {
+		pftSessionEntry->vhtCapabilityPresentInBeacon = 0;
+	}
+	if (pftSessionEntry->htRecommendedTxWidthSet) {
+		pftSessionEntry->ch_width = CH_WIDTH_40MHZ;
+		if (pftSessionEntry->vhtCapabilityPresentInBeacon &&
+				pBeaconStruct->VHTOperation.chanWidth) {
+			pftSessionEntry->ch_width =
+				pBeaconStruct->VHTOperation.chanWidth + 1;
+			pftSessionEntry->ch_center_freq_seg0 =
+				pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
+			pftSessionEntry->ch_center_freq_seg1 =
+				pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
+		} else {
+			if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+					PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+				pftSessionEntry->ch_center_freq_seg0 =
+					pbssDescription->channelId + 2;
+			else if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+					PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+				pftSessionEntry->ch_center_freq_seg0 =
+					pbssDescription->channelId - 2;
+			else
+				pe_warn("Invalid sec ch offset");
+		}
+	} else {
+		pftSessionEntry->ch_width = CH_WIDTH_20MHZ;
+		pftSessionEntry->ch_center_freq_seg0 = 0;
+		pftSessionEntry->ch_center_freq_seg1 = 0;
+	}
+
+	sir_copy_mac_addr(pftSessionEntry->selfMacAddr,
+			  psessionEntry->selfMacAddr);
+	sir_copy_mac_addr(pftSessionEntry->limReAssocbssId,
+			  pbssDescription->bssId);
+	sir_copy_mac_addr(pftSessionEntry->prev_ap_bssid, psessionEntry->bssId);
+
+	/* Store beaconInterval */
+	pftSessionEntry->beaconParams.beaconInterval =
+		pbssDescription->beaconInterval;
+	pftSessionEntry->bssType = psessionEntry->bssType;
+
+	pftSessionEntry->statypeForBss = STA_ENTRY_PEER;
+	pftSessionEntry->nwType = pbssDescription->nwType;
+
+
+	if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) {
+		pftSessionEntry->limSystemRole = eLIM_STA_ROLE;
+	} else {
+		/* Throw an error & return & make sure to delete the session */
+		pe_warn("Invalid bss type");
+	}
+
+	pftSessionEntry->limCurrentBssCaps = pbssDescription->capabilityInfo;
+	pftSessionEntry->limReassocBssCaps = pbssDescription->capabilityInfo;
+	if (pMac->roam.configParam.shortSlotTime &&
+	    SIR_MAC_GET_SHORT_SLOT_TIME(pftSessionEntry->limReassocBssCaps)) {
+		pftSessionEntry->shortSlotTimeSupported = true;
+	}
+
+	regMax = cfg_get_regulatory_max_transmit_power(pMac,
+						       pftSessionEntry->
+						       currentOperChannel);
+	localPowerConstraint = regMax;
+	lim_extract_ap_capability(pMac, (uint8_t *) pbssDescription->ieFields,
+		lim_get_ielen_from_bss_description(pbssDescription),
+		&pftSessionEntry->limCurrentBssQosCaps,
+		&pftSessionEntry->limCurrentBssPropCap, &currentBssUapsd,
+		&localPowerConstraint, pftSessionEntry);
+
+	pftSessionEntry->limReassocBssQosCaps =
+		pftSessionEntry->limCurrentBssQosCaps;
+	pftSessionEntry->limReassocBssPropCap =
+		pftSessionEntry->limCurrentBssPropCap;
+
+	pftSessionEntry->is11Rconnection = psessionEntry->is11Rconnection;
+#ifdef FEATURE_WLAN_ESE
+	pftSessionEntry->isESEconnection = psessionEntry->isESEconnection;
+	pftSessionEntry->is_ese_version_ie_present =
+		pBeaconStruct->is_ese_ver_ie_present;
+#endif
+	pftSessionEntry->isFastTransitionEnabled =
+		psessionEntry->isFastTransitionEnabled;
+
+	pftSessionEntry->isFastRoamIniFeatureEnabled =
+		psessionEntry->isFastRoamIniFeatureEnabled;
+
+#ifdef FEATURE_WLAN_ESE
+	pftSessionEntry->maxTxPower =
+		lim_get_max_tx_power(regMax, localPowerConstraint,
+				     pMac->roam.configParam.nTxPowerCap);
+#else
+	pftSessionEntry->maxTxPower = QDF_MIN(regMax, (localPowerConstraint));
+#endif
+
+	pe_debug("Reg max: %d local pwr: %d, ini tx pwr: %d max tx pwr: %d",
+		regMax, localPowerConstraint,
+		pMac->roam.configParam.nTxPowerCap,
+		pftSessionEntry->maxTxPower);
+	if (!lim_is_roam_synch_in_progress(psessionEntry)) {
+		pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState;
+		pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+		MTRACE(mac_trace(pMac,
+				TRACE_CODE_SME_STATE,
+				pftSessionEntry->peSessionId,
+				pftSessionEntry->limSmeState));
+	}
+	pftSessionEntry->encryptType = psessionEntry->encryptType;
+#ifdef WLAN_FEATURE_11W
+	pftSessionEntry->limRmfEnabled = psessionEntry->limRmfEnabled;
+#endif
+	if ((pftSessionEntry->limRFBand == BAND_2G) &&
+		(pftSessionEntry->htSupportedChannelWidthSet ==
+		eHT_CHANNEL_WIDTH_40MHZ))
+		lim_init_obss_params(pMac, pftSessionEntry);
+
+	pftSessionEntry->enableHtSmps = psessionEntry->enableHtSmps;
+	pftSessionEntry->htSmpsvalue = psessionEntry->htSmpsvalue;
+	/*
+	 * By default supported NSS 1x1 is set to true
+	 * and later on updated while determining session
+	 * supported rates which is the intersection of
+	 * self and peer rates
+	 */
+	pftSessionEntry->supported_nss_1x1 = true;
+	pe_debug("FT enable smps: %d mode: %d supported nss 1x1: %d",
+		pftSessionEntry->enableHtSmps,
+		pftSessionEntry->htSmpsvalue,
+		pftSessionEntry->supported_nss_1x1);
+
+	qdf_mem_free(pBeaconStruct);
+}
+#endif
+
+/*------------------------------------------------------------------
+ *
+ * This function is called to process the update key request from SME
+ *
+ *------------------------------------------------------------------*/
+bool lim_process_ft_update_key(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	tAddBssParams *pAddBssParams;
+	tSirFTUpdateKeyInfo *pKeyInfo;
+	tpPESession psessionEntry;
+	uint8_t sessionId;
+
+	/* Sanity Check */
+	if (pMac == NULL || pMsgBuf == NULL) {
+		return false;
+	}
+
+	pKeyInfo = (tSirFTUpdateKeyInfo *) pMsgBuf;
+
+	psessionEntry = pe_find_session_by_bssid(pMac, pKeyInfo->bssid.bytes,
+						 &sessionId);
+	if (NULL == psessionEntry) {
+		pe_err("%s: Unable to find session for the following bssid",
+			       __func__);
+		lim_print_mac_addr(pMac, pKeyInfo->bssid.bytes, LOGE);
+		return false;
+	}
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("psessionEntry is not in STA mode");
+		return false;
+	}
+
+	if (NULL == psessionEntry->ftPEContext.pAddBssReq) {
+		/* AddBss Req is NULL, save the keys to configure them later. */
+		tpLimMlmSetKeysReq pMlmSetKeysReq =
+			&psessionEntry->ftPEContext.PreAuthKeyInfo.
+			extSetStaKeyParam;
+
+		qdf_mem_zero(pMlmSetKeysReq, sizeof(tLimMlmSetKeysReq));
+		qdf_copy_macaddr(&pMlmSetKeysReq->peer_macaddr,
+				 &pKeyInfo->bssid);
+		pMlmSetKeysReq->sessionId = psessionEntry->peSessionId;
+		pMlmSetKeysReq->smesessionId = psessionEntry->smeSessionId;
+		pMlmSetKeysReq->edType = pKeyInfo->keyMaterial.edType;
+		pMlmSetKeysReq->numKeys = pKeyInfo->keyMaterial.numKeys;
+		qdf_mem_copy((uint8_t *) &pMlmSetKeysReq->key,
+			     (uint8_t *) &pKeyInfo->keyMaterial.key,
+			     sizeof(tSirKeys));
+
+		psessionEntry->ftPEContext.PreAuthKeyInfo.
+		extSetStaKeyParamValid = true;
+
+		if (psessionEntry->ftPEContext.pAddStaReq == NULL) {
+			pe_err("pAddStaReq is NULL");
+			lim_send_set_sta_key_req(pMac, pMlmSetKeysReq, 0, 0,
+						 psessionEntry, false);
+			psessionEntry->ftPEContext.PreAuthKeyInfo.
+			extSetStaKeyParamValid = false;
+		}
+	} else {
+		pAddBssParams = psessionEntry->ftPEContext.pAddBssReq;
+
+		/* Store the key information in the ADD BSS parameters */
+		pAddBssParams->extSetStaKeyParamValid = 1;
+		pAddBssParams->extSetStaKeyParam.encType =
+			pKeyInfo->keyMaterial.edType;
+		qdf_mem_copy((uint8_t *) &pAddBssParams->extSetStaKeyParam.key,
+			     (uint8_t *) &pKeyInfo->keyMaterial.key,
+			     sizeof(tSirKeys));
+
+		pAddBssParams->extSetStaKeyParam.singleTidRc =
+			(uint8_t)pMac->mlme_cfg->sta.single_tid;
+		pe_debug("Key valid: %d keyLength: %d",
+			pAddBssParams->extSetStaKeyParamValid,
+			pAddBssParams->extSetStaKeyParam.key[0].keyLength);
+
+		pAddBssParams->extSetStaKeyParam.staIdx = 0;
+
+		pe_debug("BSSID: " MAC_ADDRESS_STR,
+			       MAC_ADDR_ARRAY(pKeyInfo->bssid.bytes));
+
+		qdf_copy_macaddr(&pAddBssParams->extSetStaKeyParam.peer_macaddr,
+				 &pKeyInfo->bssid);
+
+		pAddBssParams->extSetStaKeyParam.sendRsp = false;
+
+	}
+	return true;
+}
+
+static void
+lim_ft_send_aggr_qos_rsp(tpAniSirGlobal pMac, uint8_t rspReqd,
+			 tpAggrAddTsParams aggrQosRsp, uint8_t smesessionId)
+{
+	tpSirAggrQosRsp rsp;
+	int i = 0;
+
+	if (!rspReqd) {
+		return;
+	}
+	rsp = qdf_mem_malloc(sizeof(tSirAggrQosRsp));
+	if (!rsp)
+		return;
+
+	rsp->messageType = eWNI_SME_FT_AGGR_QOS_RSP;
+	rsp->sessionId = smesessionId;
+	rsp->length = sizeof(*rsp);
+	rsp->aggrInfo.tspecIdx = aggrQosRsp->tspecIdx;
+	for (i = 0; i < SIR_QOS_NUM_AC_MAX; i++) {
+		if ((1 << i) & aggrQosRsp->tspecIdx) {
+			if (QDF_IS_STATUS_SUCCESS(aggrQosRsp->status[i]))
+				rsp->aggrInfo.aggrRsp[i].status =
+					eSIR_MAC_SUCCESS_STATUS;
+			else
+				rsp->aggrInfo.aggrRsp[i].status =
+					eSIR_MAC_UNSPEC_FAILURE_STATUS;
+			rsp->aggrInfo.aggrRsp[i].tspec = aggrQosRsp->tspec[i];
+		}
+	}
+	lim_send_sme_aggr_qos_rsp(pMac, rsp, smesessionId);
+	return;
+}
+
+void lim_process_ft_aggr_qo_s_rsp(tpAniSirGlobal pMac,
+				  struct scheduler_msg *limMsg)
+{
+	tpAggrAddTsParams pAggrQosRspMsg = NULL;
+	tAddTsParams addTsParam = { 0 };
+	tpDphHashNode pSta = NULL;
+	uint16_t assocId = 0;
+	tSirMacAddr peerMacAddr;
+	uint8_t rspReqd = 1;
+	tpPESession psessionEntry = NULL;
+	int i = 0;
+
+	pe_debug(" Received AGGR_QOS_RSP from HAL");
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+	pAggrQosRspMsg = (tpAggrAddTsParams) (limMsg->bodyptr);
+	if (NULL == pAggrQosRspMsg) {
+		pe_err("NULL pAggrQosRspMsg");
+		return;
+	}
+	psessionEntry =
+		pe_find_session_by_session_id(pMac, pAggrQosRspMsg->sessionId);
+	if (NULL == psessionEntry) {
+		pe_err("Cant find session entry for %s", __func__);
+		if (pAggrQosRspMsg != NULL) {
+			qdf_mem_free(pAggrQosRspMsg);
+		}
+		return;
+	}
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("psessionEntry is not in STA mode");
+		return;
+	}
+	for (i = 0; i < HAL_QOS_NUM_AC_MAX; i++) {
+		if ((((1 << i) & pAggrQosRspMsg->tspecIdx)) &&
+		    (pAggrQosRspMsg->status[i] != QDF_STATUS_SUCCESS)) {
+			sir_copy_mac_addr(peerMacAddr, psessionEntry->bssId);
+			addTsParam.staIdx = pAggrQosRspMsg->staIdx;
+			addTsParam.sessionId = pAggrQosRspMsg->sessionId;
+			addTsParam.tspec = pAggrQosRspMsg->tspec[i];
+			addTsParam.tspecIdx = pAggrQosRspMsg->tspecIdx;
+			lim_send_delts_req_action_frame(pMac, peerMacAddr, rspReqd,
+							&addTsParam.tspec.tsinfo,
+							&addTsParam.tspec,
+							psessionEntry);
+			pSta =
+				dph_lookup_assoc_id(pMac, addTsParam.staIdx, &assocId,
+						    &psessionEntry->dph.dphHashTable);
+			if (pSta != NULL) {
+				lim_admit_control_delete_ts(pMac, assocId,
+							    &addTsParam.tspec.
+							    tsinfo, NULL,
+							    (uint8_t *) &
+							    addTsParam.tspecIdx);
+			}
+		}
+	}
+	lim_ft_send_aggr_qos_rsp(pMac, rspReqd, pAggrQosRspMsg,
+				 psessionEntry->smeSessionId);
+	if (pAggrQosRspMsg != NULL) {
+		qdf_mem_free(pAggrQosRspMsg);
+	}
+	return;
+}
+
+QDF_STATUS lim_process_ft_aggr_qos_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	struct scheduler_msg msg = {0};
+	tSirAggrQosReq *aggrQosReq = (tSirAggrQosReq *) pMsgBuf;
+	tpAggrAddTsParams pAggrAddTsParam;
+	tpPESession psessionEntry = NULL;
+	tpLimTspecInfo tspecInfo;
+	uint8_t ac;
+	tpDphHashNode pSta;
+	uint16_t aid;
+	uint8_t sessionId;
+	int i;
+
+	pAggrAddTsParam = qdf_mem_malloc(sizeof(tAggrAddTsParams));
+	if (!pAggrAddTsParam)
+		return QDF_STATUS_E_NOMEM;
+
+	psessionEntry = pe_find_session_by_bssid(pMac, aggrQosReq->bssid.bytes,
+						 &sessionId);
+
+	if (psessionEntry == NULL) {
+		pe_err("psession Entry Null for sessionId: %d",
+			       aggrQosReq->sessionId);
+		qdf_mem_free(pAggrAddTsParam);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("psessionEntry is not in STA mode");
+		qdf_mem_free(pAggrAddTsParam);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pSta = dph_lookup_hash_entry(pMac, aggrQosReq->bssid.bytes, &aid,
+				     &psessionEntry->dph.dphHashTable);
+	if (pSta == NULL) {
+		pe_err("Station context not found - ignoring AddTsRsp");
+		qdf_mem_free(pAggrAddTsParam);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pAggrAddTsParam->staIdx = psessionEntry->staId;
+	/* Fill in the sessionId specific to PE */
+	pAggrAddTsParam->sessionId = sessionId;
+	pAggrAddTsParam->tspecIdx = aggrQosReq->aggrInfo.tspecIdx;
+	pAggrAddTsParam->vdev_id = psessionEntry->smeSessionId;
+
+	for (i = 0; i < HAL_QOS_NUM_AC_MAX; i++) {
+		if (aggrQosReq->aggrInfo.tspecIdx & (1 << i)) {
+			tSirMacTspecIE *pTspec =
+				&aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
+			/* Since AddTS response was successful, check for the PSB flag
+			 * and directional flag inside the TS Info field.
+			 * An AC is trigger enabled AC if the PSB subfield is set to 1
+			 * in the uplink direction.
+			 * An AC is delivery enabled AC if the PSB subfield is set to 1
+			 * in the downlink direction.
+			 * An AC is trigger and delivery enabled AC if the PSB subfield
+			 * is set to 1 in the bi-direction field.
+			 */
+			if (pTspec->tsinfo.traffic.psb == 1) {
+				lim_set_tspec_uapsd_mask_per_session(pMac,
+								     psessionEntry,
+								     &pTspec->
+								     tsinfo,
+								     SET_UAPSD_MASK);
+			} else {
+				lim_set_tspec_uapsd_mask_per_session(pMac,
+								     psessionEntry,
+								     &pTspec->
+								     tsinfo,
+								     CLEAR_UAPSD_MASK);
+			}
+			/*
+			 * ADDTS success, so AC is now admitted.
+			 * We shall now use the default
+			 * EDCA parameters as advertised by AP and
+			 * send the updated EDCA params
+			 * to HAL.
+			 */
+			ac = upToAc(pTspec->tsinfo.traffic.userPrio);
+			if (pTspec->tsinfo.traffic.direction ==
+			    SIR_MAC_DIRECTION_UPLINK) {
+				psessionEntry->
+				gAcAdmitMask
+				[SIR_MAC_DIRECTION_UPLINK] |=
+					(1 << ac);
+			} else if (pTspec->tsinfo.traffic.direction ==
+				   SIR_MAC_DIRECTION_DNLINK) {
+				psessionEntry->
+				gAcAdmitMask
+				[SIR_MAC_DIRECTION_DNLINK] |=
+					(1 << ac);
+			} else if (pTspec->tsinfo.traffic.direction ==
+				   SIR_MAC_DIRECTION_BIDIR) {
+				psessionEntry->
+				gAcAdmitMask
+				[SIR_MAC_DIRECTION_UPLINK] |=
+					(1 << ac);
+				psessionEntry->
+					gAcAdmitMask
+					[SIR_MAC_DIRECTION_DNLINK] |=
+					(1 << ac);
+			}
+			lim_set_active_edca_params(pMac,
+						   psessionEntry->gLimEdcaParams,
+						   psessionEntry);
+
+				lim_send_edca_params(pMac,
+					     psessionEntry->gLimEdcaParamsActive,
+					     pSta->bssId, false);
+
+			if (QDF_STATUS_SUCCESS !=
+			    lim_tspec_add(pMac, pSta->staAddr, pSta->assocId,
+					  pTspec, 0, &tspecInfo)) {
+				pe_err("Adding entry in lim Tspec Table failed");
+				pMac->lim.gLimAddtsSent = false;
+				qdf_mem_free(pAggrAddTsParam);
+				return QDF_STATUS_E_FAILURE;
+			}
+
+			pAggrAddTsParam->tspec[i] =
+				aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
+		}
+	}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (!pMac->mlme_cfg->lfr.lfr3_roaming_offload ||
+	    (pMac->mlme_cfg->lfr.lfr3_roaming_offload &&
+	     !psessionEntry->is11Rconnection))
+#endif
+	{
+	msg.type = WMA_AGGR_QOS_REQ;
+	msg.bodyptr = pAggrAddTsParam;
+	msg.bodyval = 0;
+
+	/* We need to defer any incoming messages until we get a
+	 * WMA_AGGR_QOS_RSP from HAL.
+	 */
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msg.type));
+
+	if (QDF_STATUS_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
+			pe_warn("wma_post_ctrl_msg() failed");
+			SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+			qdf_mem_free(pAggrAddTsParam);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	else {
+		/* Implies it is a LFR3.0 based 11r connection
+		 * so donot send add ts request to firmware since it
+		 * already has the RIC IEs */
+
+		/* Send the Aggr QoS response to SME */
+		lim_ft_send_aggr_qos_rsp(pMac, true, pAggrAddTsParam,
+					 psessionEntry->smeSessionId);
+		if (pAggrAddTsParam != NULL) {
+			qdf_mem_free(pAggrAddTsParam);
+		}
+	}
+#endif
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/core/mac/src/pe/lim/lim_ft_preauth.c b/core/mac/src/pe/lim/lim_ft_preauth.c
new file mode 100644
index 0000000..397cc59
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ft_preauth.c
@@ -0,0 +1,810 @@
+/*
+ * Copyright (c) 2016-2018 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: lim_ft_preauth.c
+ *
+ * Pre-Authentication implementation for host based roaming
+ */
+#include <lim_send_messages.h>
+#include <lim_types.h>
+#include <lim_ft.h>
+#include <lim_ft_defs.h>
+#include <lim_utils.h>
+#include <lim_prop_exts_utils.h>
+#include <lim_assoc_utils.h>
+#include <lim_session.h>
+#include <lim_session_utils.h>
+#include <lim_admit_control.h>
+#include <wlan_scan_ucfg_api.h>
+#include "wma.h"
+
+/**
+ * lim_ft_cleanup_pre_auth_info() - Cleanup preauth related information
+ * @pMac: Global MAC Context
+ * @psessionEntry: PE Session
+ *
+ * This routine is called to free the FT context, session and other
+ * information used during preauth operation.
+ *
+ * Return: None
+ */
+void lim_ft_cleanup_pre_auth_info(tpAniSirGlobal pMac,
+		tpPESession psessionEntry)
+{
+	tpPESession pReAssocSessionEntry = NULL;
+	uint8_t sessionId = 0;
+
+	if (!psessionEntry) {
+		pe_err("psessionEntry is NULL");
+		return;
+	}
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("psessionEntry is not in STA mode");
+		return;
+	}
+
+	if (psessionEntry->ftPEContext.pFTPreAuthReq) {
+		pReAssocSessionEntry =
+			pe_find_session_by_bssid(pMac,
+						 psessionEntry->ftPEContext.
+						 pFTPreAuthReq->preAuthbssId,
+						 &sessionId);
+
+		if (psessionEntry->ftPEContext.pFTPreAuthReq->
+		    pbssDescription) {
+			qdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq->
+				     pbssDescription);
+			psessionEntry->ftPEContext.pFTPreAuthReq->
+			pbssDescription = NULL;
+		}
+		qdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq);
+		psessionEntry->ftPEContext.pFTPreAuthReq = NULL;
+	}
+
+	if (psessionEntry->ftPEContext.pAddBssReq) {
+		qdf_mem_free(psessionEntry->ftPEContext.pAddBssReq);
+		psessionEntry->ftPEContext.pAddBssReq = NULL;
+	}
+
+	if (psessionEntry->ftPEContext.pAddStaReq) {
+		qdf_mem_free(psessionEntry->ftPEContext.pAddStaReq);
+		psessionEntry->ftPEContext.pAddStaReq = NULL;
+	}
+
+	/* The session is being deleted, cleanup the contents */
+	qdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0);
+
+	/* Delete the session created while handling pre-auth response */
+	if (pReAssocSessionEntry) {
+		/* If we have successful pre-auth response, then we would have
+		 * created a session on which reassoc request will be sent
+		 */
+		if (pReAssocSessionEntry->valid &&
+		    pReAssocSessionEntry->limSmeState ==
+		    eLIM_SME_WT_REASSOC_STATE) {
+			QDF_TRACE(QDF_MODULE_ID_PE,
+				  QDF_TRACE_LEVEL_DEBUG,
+				  FL("Deleting Preauth session(%d)"),
+				  pReAssocSessionEntry->peSessionId);
+			pe_delete_session(pMac, pReAssocSessionEntry);
+		}
+	}
+}
+
+/*
+ * lim_process_ft_pre_auth_req() - process ft pre auth req
+ *
+ * @mac_ctx:    global mac ctx
+ * @msg:        pointer to message
+ *
+ * In this function, we process the FT Pre Auth Req:
+ *   We receive Pre-Auth, suspend link, register a call back. In the call back,
+ *   we will need to accept frames from the new bssid. Send out the auth req to
+ *   new AP. Start timer and when the timer is done or if we receive the Auth
+ *   response. We change channel. Resume link
+ *
+ * Return: value to indicate if buffer was consumed
+ */
+int lim_process_ft_pre_auth_req(tpAniSirGlobal mac_ctx,
+				struct scheduler_msg *msg)
+{
+	int buf_consumed = false;
+	tpPESession session;
+	uint8_t session_id;
+	tpSirFTPreAuthReq ft_pre_auth_req = (tSirFTPreAuthReq *) msg->bodyptr;
+
+	if (NULL == ft_pre_auth_req) {
+		pe_err("tSirFTPreAuthReq is NULL");
+		return buf_consumed;
+	}
+
+	/* Get the current session entry */
+	session = pe_find_session_by_bssid(mac_ctx,
+					   ft_pre_auth_req->currbssId,
+					   &session_id);
+	if (session == NULL) {
+		pe_err("Unable to find session for the bssid"
+			   MAC_ADDRESS_STR,
+			   MAC_ADDR_ARRAY(ft_pre_auth_req->currbssId));
+		/* Post the FT Pre Auth Response to SME */
+		lim_post_ft_pre_auth_rsp(mac_ctx, QDF_STATUS_E_FAILURE, NULL, 0,
+					 session);
+		buf_consumed = true;
+		return buf_consumed;
+	}
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(session)) {
+		pe_err("session is not in STA mode");
+		buf_consumed = true;
+		return buf_consumed;
+	}
+
+	/* Can set it only after sending auth */
+	session->ftPEContext.ftPreAuthStatus = QDF_STATUS_E_FAILURE;
+	session->ftPEContext.ftPreAuthSession = true;
+
+	/* Indicate that this is the session on which preauth is being done */
+	if (session->ftPEContext.pFTPreAuthReq) {
+		if (session->ftPEContext.pFTPreAuthReq->pbssDescription) {
+			qdf_mem_free(
+			  session->ftPEContext.pFTPreAuthReq->pbssDescription);
+			session->ftPEContext.pFTPreAuthReq->pbssDescription =
+									NULL;
+		}
+		qdf_mem_free(session->ftPEContext.pFTPreAuthReq);
+		session->ftPEContext.pFTPreAuthReq = NULL;
+	}
+
+	/* We need information from the Pre-Auth Req. Lets save that */
+	session->ftPEContext.pFTPreAuthReq = ft_pre_auth_req;
+
+	pe_debug("PRE Auth ft_ies_length=%02x%02x%02x",
+		session->ftPEContext.pFTPreAuthReq->ft_ies[0],
+		session->ftPEContext.pFTPreAuthReq->ft_ies[1],
+		session->ftPEContext.pFTPreAuthReq->ft_ies[2]);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT,
+			      session, 0, 0);
+#endif
+
+	/*
+	 * Dont need to suspend if APs are in same channel and DUT
+	 * is not in MCC state
+	 */
+	if ((session->currentOperChannel !=
+	    session->ftPEContext.pFTPreAuthReq->preAuthchannelNum)
+	    || lim_is_in_mcc(mac_ctx)) {
+		/* Need to suspend link only if the channels are different */
+		pe_debug("Performing pre-auth on diff channel(session %pK)",
+			session);
+		lim_send_preauth_scan_offload(mac_ctx, session,
+					session->ftPEContext.pFTPreAuthReq);
+	} else {
+		pe_debug("Performing pre-auth on same channel (session %pK)",
+			session);
+		/* We are in the same channel. Perform pre-auth */
+		lim_perform_ft_pre_auth(mac_ctx, QDF_STATUS_SUCCESS, NULL,
+					session);
+	}
+
+	return buf_consumed;
+}
+
+/**
+ * lim_perform_ft_pre_auth() - Perform preauthentication
+ * @pMac: Global MAC Context
+ * @status: Status Code
+ * @data: pre-auth data
+ * @psessionEntry: PE Session
+ *
+ * This routine will trigger the sending of authentication frame
+ * to the peer.
+ *
+ * Return: None
+ */
+void lim_perform_ft_pre_auth(tpAniSirGlobal pMac, QDF_STATUS status,
+			     uint32_t *data, tpPESession psessionEntry)
+{
+	tSirMacAuthFrameBody authFrame;
+	unsigned int session_id;
+	eCsrAuthType auth_type;
+
+	if (NULL == psessionEntry) {
+		pe_err("psessionEntry is NULL");
+		return;
+	}
+	session_id = psessionEntry->smeSessionId;
+	auth_type =
+		pMac->roam.roamSession[session_id].connectedProfile.AuthType;
+
+	if (psessionEntry->is11Rconnection &&
+	    psessionEntry->ftPEContext.pFTPreAuthReq) {
+		/* Only 11r assoc has FT IEs */
+		if ((auth_type != eCSR_AUTH_TYPE_OPEN_SYSTEM) &&
+			(psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies_length
+									== 0)) {
+			pe_err("FTIEs for Auth Req Seq 1 is absent");
+			goto preauth_fail;
+		}
+	}
+
+	if (status != QDF_STATUS_SUCCESS) {
+		pe_err("Change channel not successful for FT pre-auth");
+		goto preauth_fail;
+	}
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("psessionEntry is not in STA mode");
+		return;
+	}
+	pe_debug("Entered wait auth2 state for FT (old session %pK)",
+			psessionEntry);
+	if (psessionEntry->is11Rconnection) {
+		/* Now we are on the right channel and need to send out Auth1
+		 * and receive Auth2
+		 */
+		authFrame.authAlgoNumber = eSIR_FT_AUTH;
+	} else {
+		/* Will need to make isESEconnection a enum may be for further
+		 * improvements to this to match this algorithm number
+		 */
+		authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM;
+	}
+	authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
+	authFrame.authStatusCode = 0;
+
+	pMac->lim.limTimers.g_lim_periodic_auth_retry_timer.sessionId =
+				psessionEntry->peSessionId;
+
+	/* Start timer here to come back to operating channel */
+	pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId =
+		psessionEntry->peSessionId;
+	if (TX_SUCCESS !=
+	    tx_timer_activate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer)) {
+		pe_err("FT Auth Rsp Timer Start Failed");
+		goto preauth_fail;
+	}
+	MTRACE(mac_trace(pMac, TRACE_CODE_TIMER_ACTIVATE,
+		psessionEntry->peSessionId, eLIM_FT_PREAUTH_RSP_TIMER));
+
+	pe_debug("FT Auth Rsp Timer Started");
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_ROAM_AUTH_START_EVENT,
+			pMac->lim.pSessionEntry, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+#endif
+	if (psessionEntry->ftPEContext.pFTPreAuthReq)
+		lim_send_auth_mgmt_frame(pMac, &authFrame,
+			 psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId,
+			 LIM_NO_WEP_IN_FC, psessionEntry);
+
+	return;
+
+preauth_fail:
+	lim_handle_ft_pre_auth_rsp(pMac, QDF_STATUS_E_FAILURE, NULL, 0, psessionEntry);
+	return;
+}
+
+/**
+ * lim_ft_setup_auth_session() - Fill the FT Session
+ * @pMac: Global MAC Context
+ * @psessionEntry: PE Session
+ *
+ * Setup the session and the add bss req for the pre-auth AP.
+ *
+ * Return: Success or Failure Status
+ */
+QDF_STATUS lim_ft_setup_auth_session(tpAniSirGlobal pMac,
+					tpPESession psessionEntry)
+{
+	tpPESession pftSessionEntry = NULL;
+	uint8_t sessionId = 0;
+
+	pftSessionEntry =
+		pe_find_session_by_bssid(pMac, psessionEntry->limReAssocbssId,
+					 &sessionId);
+	if (pftSessionEntry == NULL) {
+		pe_err("No session found for bssid");
+		lim_print_mac_addr(pMac, psessionEntry->limReAssocbssId, LOGE);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("psessionEntry is not in STA mode");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (psessionEntry->ftPEContext.pFTPreAuthReq &&
+	    psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) {
+		lim_fill_ft_session(pMac,
+				    psessionEntry->ftPEContext.pFTPreAuthReq->
+				    pbssDescription, pftSessionEntry,
+				    psessionEntry);
+
+		lim_ft_prepare_add_bss_req(pMac, false, pftSessionEntry,
+		     psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_ft_process_pre_auth_result() - Process the Auth frame
+ * @pMac: Global MAC context
+ * @psessionEntry: PE Session
+ *
+ * Return: None
+ */
+static void lim_ft_process_pre_auth_result(tpAniSirGlobal pMac,
+					   tpPESession psessionEntry)
+{
+	if (NULL == psessionEntry ||
+	    NULL == psessionEntry->ftPEContext.pFTPreAuthReq)
+		return;
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("psessionEntry is not in STA mode");
+		return;
+	}
+
+	if (psessionEntry->ftPEContext.ftPreAuthStatus == QDF_STATUS_SUCCESS) {
+		psessionEntry->ftPEContext.ftPreAuthStatus =
+			lim_ft_setup_auth_session(pMac, psessionEntry);
+	}
+	/* Post the FT Pre Auth Response to SME */
+	lim_post_ft_pre_auth_rsp(pMac,
+		psessionEntry->ftPEContext.ftPreAuthStatus,
+		psessionEntry->ftPEContext.saved_auth_rsp,
+		psessionEntry->ftPEContext.saved_auth_rsp_length,
+		psessionEntry);
+}
+
+/**
+ * lim_handle_ft_pre_auth_rsp() - Handle the Auth response
+ * @pMac: Global MAC Context
+ * @status: Status Code
+ * @auth_rsp: Auth Response
+ * @auth_rsp_length: Auth response length
+ * @psessionEntry: PE Session
+ *
+ * Send the FT Pre Auth Response to SME whenever we have a status
+ * ready to be sent to SME
+ *
+ * SME will be the one to send it up to the supplicant to receive
+ * FTIEs which will be required for Reassoc Req.
+ *
+ * @Return: None
+ */
+void lim_handle_ft_pre_auth_rsp(tpAniSirGlobal pMac, QDF_STATUS status,
+				uint8_t *auth_rsp, uint16_t auth_rsp_length,
+				tpPESession psessionEntry)
+{
+	tpPESession pftSessionEntry = NULL;
+	uint8_t sessionId = 0;
+	tpSirBssDescription pbssDescription = NULL;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT,
+			      psessionEntry, (uint16_t) status, 0);
+#endif
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("psessionEntry is not in STA mode");
+		return;
+	}
+
+	/* Save the status of pre-auth */
+	psessionEntry->ftPEContext.ftPreAuthStatus = status;
+
+	/* Save the auth rsp, so we can send it to
+	 * SME once we resume link
+	 */
+	psessionEntry->ftPEContext.saved_auth_rsp_length = 0;
+	if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) {
+		qdf_mem_copy(psessionEntry->ftPEContext.saved_auth_rsp,
+			     auth_rsp, auth_rsp_length);
+		psessionEntry->ftPEContext.saved_auth_rsp_length =
+			auth_rsp_length;
+	}
+
+	if (!psessionEntry->ftPEContext.pFTPreAuthReq ||
+	    !psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) {
+		pe_err("pFTPreAuthReq or pbssDescription is NULL");
+		return;
+	}
+
+	/* Create FT session for the re-association at this point */
+	if (psessionEntry->ftPEContext.ftPreAuthStatus == QDF_STATUS_SUCCESS) {
+		pbssDescription =
+		      psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription;
+		pftSessionEntry =
+			pe_create_session(pMac, pbssDescription->bssId,
+					  &sessionId, pMac->lim.maxStation,
+					  psessionEntry->bssType,
+					  psessionEntry->smeSessionId);
+		if (!pftSessionEntry) {
+			pe_err("Session not created for pre-auth 11R AP");
+			status = QDF_STATUS_E_FAILURE;
+			psessionEntry->ftPEContext.ftPreAuthStatus = status;
+			goto send_rsp;
+		}
+
+		sir_copy_mac_addr(pftSessionEntry->selfMacAddr,
+				  psessionEntry->selfMacAddr);
+		sir_copy_mac_addr(pftSessionEntry->limReAssocbssId,
+				  pbssDescription->bssId);
+
+		/* Update the beacon/probe filter in mac_ctx */
+		lim_set_bcn_probe_filter(pMac,
+					 pftSessionEntry,
+					 NULL, 0);
+
+		if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE)
+			pftSessionEntry->limSystemRole = eLIM_STA_ROLE;
+		else
+			pe_err("Invalid bss type");
+
+		pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState;
+		qdf_mem_copy(&(pftSessionEntry->htConfig),
+			     &(psessionEntry->htConfig),
+			     sizeof(psessionEntry->htConfig));
+		pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+
+		if (IS_5G_CH(psessionEntry->ftPEContext.pFTPreAuthReq->
+			preAuthchannelNum))
+			pftSessionEntry->vdev_nss = pMac->vdev_type_nss_5g.sta;
+		else
+			pftSessionEntry->vdev_nss = pMac->vdev_type_nss_2g.sta;
+
+		pe_debug("created session (%pK) with id = %d",
+			pftSessionEntry, pftSessionEntry->peSessionId);
+
+		/* Update the ReAssoc BSSID of the current session */
+		sir_copy_mac_addr(psessionEntry->limReAssocbssId,
+				  pbssDescription->bssId);
+		lim_print_mac_addr(pMac, psessionEntry->limReAssocbssId, LOGD);
+	}
+send_rsp:
+	if ((psessionEntry->currentOperChannel !=
+	     psessionEntry->ftPEContext.pFTPreAuthReq->preAuthchannelNum) ||
+	    lim_is_in_mcc(pMac)) {
+		/* Need to move to the original AP channel */
+		lim_process_abort_scan_ind(pMac, psessionEntry->smeSessionId,
+			psessionEntry->ftPEContext.pFTPreAuthReq->scan_id,
+			pMac->lim.req_id | PREAUTH_REQUESTOR_ID);
+	} else {
+		pe_debug("Pre auth on same channel as connected AP channel %d\
+			and no mcc pe sessions exist",
+			psessionEntry->ftPEContext.pFTPreAuthReq->
+			preAuthchannelNum);
+		lim_ft_process_pre_auth_result(pMac, psessionEntry);
+	}
+}
+
+/*
+ * lim_process_ft_preauth_rsp_timeout() - process ft preauth rsp timeout
+ *
+ * @mac_ctx:		global mac ctx
+ *
+ * This function is called if preauth response is not received from the AP
+ * within this timeout while FT in progress
+ *
+ * Return: void
+ */
+void lim_process_ft_preauth_rsp_timeout(tpAniSirGlobal mac_ctx)
+{
+	tpPESession session;
+
+	/*
+	 * We have failed pre auth. We need to resume link and get back on
+	 * home channel
+	 */
+	pe_err("FT Pre-Auth Time Out!!!!");
+	session = pe_find_session_by_session_id(mac_ctx,
+			mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId);
+	if (NULL == session) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(session)) {
+		pe_err("session is not in STA mode");
+		return;
+	}
+
+	/* Reset the flag to indicate preauth request session */
+	session->ftPEContext.ftPreAuthSession = false;
+
+	if (NULL == session->ftPEContext.pFTPreAuthReq) {
+		/* Auth Rsp might already be posted to SME and ftcleanup done */
+		pe_err("pFTPreAuthReq is NULL sessionId: %d",
+			mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId);
+		return;
+	}
+
+	/*
+	 * To handle the race condition where we receive preauth rsp after
+	 * timer has expired.
+	 */
+	if (true ==
+	    session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) {
+		pe_err("Auth rsp already posted to SME (session %pK)",
+			session);
+		return;
+	} else {
+		/*
+		 * Here we are sending preauth rsp with failure state
+		 * and which is forwarded to SME. Now, if we receive an preauth
+		 * resp from AP with success it would create a FT pesession, but
+		 * will be dropped in SME leaving behind the pesession. Mark
+		 * Preauth rsp processed so that any rsp from AP is dropped in
+		 * lim_process_auth_frame_no_session.
+		 */
+		pe_debug("Auth rsp not yet posted to SME (session %pK)",
+			session);
+		session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed = true;
+	}
+
+	/*
+	 * Attempted at Pre-Auth and failed. If we are off channel. We need
+	 * to get back to home channel
+	 */
+	lim_handle_ft_pre_auth_rsp(mac_ctx, QDF_STATUS_E_FAILURE, NULL, 0, session);
+}
+
+/*
+ * lim_post_ft_pre_auth_rsp() - post ft pre auth response to SME.
+ *
+ * @mac_ctx:		global mac ctx
+ * @status:		status code to post in auth rsp
+ * @auth_rsp:		pointer to auth rsp FT ie
+ * @auth_rsp_length:	len of the IE field
+ * @session:	        pe session
+ *
+ * post pre auth response to SME.
+ *
+ * Return: void
+ */
+void lim_post_ft_pre_auth_rsp(tpAniSirGlobal mac_ctx,
+			      QDF_STATUS status,
+			      uint8_t *auth_rsp,
+			      uint16_t auth_rsp_length,
+			      tpPESession session)
+{
+	tpSirFTPreAuthRsp ft_pre_auth_rsp;
+	struct scheduler_msg mmh_msg = {0};
+	uint16_t rsp_len = sizeof(tSirFTPreAuthRsp);
+
+	ft_pre_auth_rsp = qdf_mem_malloc(rsp_len);
+	if (!ft_pre_auth_rsp) {
+		QDF_ASSERT(ft_pre_auth_rsp != NULL);
+		return;
+	}
+
+	pe_debug("Auth Rsp = %pK", ft_pre_auth_rsp);
+	if (session) {
+		/* Nothing to be done if the session is not in STA mode */
+		if (!LIM_IS_STA_ROLE(session)) {
+			pe_err("session is not in STA mode");
+			qdf_mem_free(ft_pre_auth_rsp);
+			return;
+		}
+		ft_pre_auth_rsp->smeSessionId = session->smeSessionId;
+		/* The bssid of the AP we are sending Auth1 to. */
+		if (session->ftPEContext.pFTPreAuthReq)
+			sir_copy_mac_addr(ft_pre_auth_rsp->preAuthbssId,
+			    session->ftPEContext.pFTPreAuthReq->preAuthbssId);
+	}
+
+	ft_pre_auth_rsp->messageType = eWNI_SME_FT_PRE_AUTH_RSP;
+	ft_pre_auth_rsp->length = (uint16_t) rsp_len;
+	ft_pre_auth_rsp->status = status;
+
+	/* Attach the auth response now back to SME */
+	ft_pre_auth_rsp->ft_ies_length = 0;
+	if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) {
+		/* Only 11r assoc has FT IEs */
+		qdf_mem_copy(ft_pre_auth_rsp->ft_ies,
+			     auth_rsp, auth_rsp_length);
+		ft_pre_auth_rsp->ft_ies_length = auth_rsp_length;
+	}
+
+	if (status != QDF_STATUS_SUCCESS) {
+		/*
+		 * Ensure that on Pre-Auth failure the cached Pre-Auth Req and
+		 * other allocated memory is freed up before returning.
+		 */
+		pe_debug("Pre-Auth Failed, Cleanup!");
+		lim_ft_cleanup(mac_ctx, session);
+	}
+
+	mmh_msg.type = ft_pre_auth_rsp->messageType;
+	mmh_msg.bodyptr = ft_pre_auth_rsp;
+	mmh_msg.bodyval = 0;
+
+	pe_debug("Posted Auth Rsp to SME with status of 0x%x", status);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	if (status == QDF_STATUS_SUCCESS)
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_PREAUTH_DONE,
+				      session, status, 0);
+#endif
+	lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT);
+}
+
+/**
+ * lim_send_preauth_scan_offload() - Send scan command to handle preauth.
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_entry: pe session
+ * @ft_preauth_req: Preauth request with parameters
+ *
+ * Builds a single channel scan request and sends it to scan module.
+ * Scan dwell time is the time allocated to go to preauth candidate
+ * channel for auth frame exchange.
+ *
+ * Return: Status of sending message to scan module.
+ */
+QDF_STATUS lim_send_preauth_scan_offload(tpAniSirGlobal mac_ctx,
+					 tpPESession session_entry,
+					 tSirFTPreAuthReq *ft_preauth_req)
+{
+	struct scan_start_request *req;
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t session_id;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (session_entry == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+			  FL("Session entry is NULL"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	session_id = session_entry->smeSessionId;
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_zero(req, sizeof(*req));
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev,
+						    session_id, WLAN_OSIF_ID);
+	if (vdev == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+			  FL("vdev object is NULL"));
+		qdf_mem_free(req);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ucfg_scan_init_default_params(vdev, req);
+
+	qdf_mem_copy(req->scan_req.bssid_list,
+		     (uint8_t *)ft_preauth_req->currbssId,
+		     QDF_MAC_ADDR_SIZE);
+
+	req->scan_req.scan_id = ucfg_scan_get_scan_id(mac_ctx->psoc);
+	if (!req->scan_req.scan_id) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
+		qdf_mem_free(req);
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid scan ID"));
+		return QDF_STATUS_E_FAILURE;
+	}
+	ft_preauth_req->scan_id = req->scan_req.scan_id;
+	req->scan_req.vdev_id = session_id;
+	req->scan_req.scan_req_id = mac_ctx->lim.req_id | PREAUTH_REQUESTOR_ID;
+	req->scan_req.scan_priority = SCAN_PRIORITY_VERY_HIGH;
+	req->scan_req.scan_f_passive = true;
+
+	req->scan_req.chan_list.num_chan = 1;
+	req->scan_req.chan_list.chan[0].freq =
+			cds_chan_to_freq(ft_preauth_req->preAuthchannelNum);
+
+	req->scan_req.dwell_time_active = LIM_FT_PREAUTH_SCAN_TIME;
+	req->scan_req.dwell_time_passive = LIM_FT_PREAUTH_SCAN_TIME;
+
+	status = ucfg_scan_start(req);
+	if (status != QDF_STATUS_SUCCESS)
+		/* Don't free req here, ucfg_scan_start will do free */
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("Issue scan req failed"));
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
+	return status;
+}
+
+/**
+ * lim_preauth_scan_event_handler() - Process firmware preauth scan events
+ *
+ * @mac_ctx:Pointer to global MAC structure
+ * @event: Scan event
+ * @session_id: session entry
+ * @scan_id: scan id from WMA scan event.
+ *
+ * If scan event signifies failure or successful completion, operation
+ * is complete.
+ * If scan event signifies that STA is on foreign channel, send auth frame
+ *
+ * Return: void
+ */
+
+void lim_preauth_scan_event_handler(tpAniSirGlobal mac_ctx,
+				enum sir_scan_event_type event,
+				uint8_t session_id,
+				uint32_t scan_id)
+{
+	tpPESession session_entry;
+
+	session_entry = pe_find_session_by_scan_id(mac_ctx, scan_id);
+	/* Pre-auth request is sent */
+	if (session_entry) {
+		if ((event == SIR_SCAN_EVENT_FOREIGN_CHANNEL) &&
+		    (session_entry->ftPEContext.ftPreAuthStatus
+		     == QDF_STATUS_SUCCESS)) {
+			pe_err("Pre-auth is done, skip sending pre-auth req");
+			return;
+		}
+	} else {
+		/* For the first pre-auth request
+		 * need to get it by sme session id (vdev id)
+		 */
+		session_entry = pe_find_session_by_sme_session_id(mac_ctx,
+								  session_id);
+	}
+
+	if (session_entry == NULL) {
+		pe_err("SmeSessionId:%d PeSessionId:%d does not exist",
+			session_id,
+			mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId);
+		return;
+	}
+
+	switch (event) {
+	case SIR_SCAN_EVENT_START_FAILED:
+		/* Scan command is rejected by firmware */
+		pe_err("Failed to start preauth scan");
+		lim_post_ft_pre_auth_rsp(mac_ctx, QDF_STATUS_E_FAILURE, NULL, 0,
+					 session_entry);
+		return;
+
+	case SIR_SCAN_EVENT_COMPLETED:
+		/*
+		 * Scan either completed successfully or or got terminated
+		 * after successful auth, or timed out. Either way, STA
+		 * is back to home channel. Data traffic can continue.
+		 */
+		lim_ft_process_pre_auth_result(mac_ctx, session_entry);
+		break;
+
+	case SIR_SCAN_EVENT_FOREIGN_CHANNEL:
+		/* Sta is on candidate channel. Send auth */
+		lim_perform_ft_pre_auth(mac_ctx, QDF_STATUS_SUCCESS, NULL,
+					session_entry);
+		break;
+	default:
+		/* Don't print message for scan events that are ignored */
+		break;
+	}
+}
+
diff --git a/core/mac/src/pe/lim/lim_ibss_peer_mgmt.c b/core/mac/src/pe/lim/lim_ibss_peer_mgmt.c
new file mode 100644
index 0000000..b2e6017
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ibss_peer_mgmt.c
@@ -0,0 +1,1812 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#include "cds_api.h"
+#include "ani_global.h"
+#include "sir_common.h"
+#include "wni_cfg.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_sta_hash_api.h"
+#include "sch_api.h"             /* sch_set_fixed_beacon_fields for IBSS coalesce */
+#include "lim_security_utils.h"
+#include "lim_send_messages.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_types.h"
+#include "wlan_mlme_api.h"
+
+/**
+ * ibss_peer_find
+ *
+ ***FUNCTION:
+ * This function is called while adding a context at
+ * DPH & Polaris for a peer in IBSS.
+ * If peer is found in the list, capabilities from the
+ * returned BSS description are used at DPH node & Polaris.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  macAddr - MAC address of the peer
+ *
+ * @return Pointer to peer node if found, else NULL
+ */
+
+static tLimIbssPeerNode *ibss_peer_find(tpAniSirGlobal pMac,
+					tSirMacAddr macAddr)
+{
+	tLimIbssPeerNode *pTempNode = pMac->lim.gLimIbssPeerList;
+
+	while (pTempNode != NULL) {
+		if (!qdf_mem_cmp((uint8_t *) macAddr,
+				    (uint8_t *) &pTempNode->peerMacAddr,
+				    sizeof(tSirMacAddr)))
+			break;
+		pTempNode = pTempNode->next;
+	}
+	return pTempNode;
+} /*** end ibss_peer_find() ***/
+
+/**
+ * ibss_peer_add
+ *
+ ***FUNCTION:
+ * This is called on a STA in IBSS upon receiving Beacon/
+ * Probe Response from a peer.
+ *
+ ***LOGIC:
+ * Node is always added to the front of the list
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac      - Pointer to Global MAC structure
+ * @param  pPeerNode - Pointer to peer node to be added to the list.
+ *
+ * @return None
+ */
+
+static QDF_STATUS
+ibss_peer_add(tpAniSirGlobal pMac, tLimIbssPeerNode *pPeerNode)
+{
+#ifdef ANI_SIR_IBSS_PEER_CACHING
+	uint32_t numIbssPeers = (2 * pMac->lim.maxStation);
+
+	if (pMac->lim.gLimNumIbssPeers >= numIbssPeers) {
+		/**
+		 * Reached max number of peers to be maintained.
+		 * Delete last entry & add new entry at the beginning.
+		 */
+		tLimIbssPeerNode *pTemp, *pPrev;
+
+		pTemp = pPrev = pMac->lim.gLimIbssPeerList;
+		while (pTemp->next != NULL) {
+			pPrev = pTemp;
+			pTemp = pTemp->next;
+		}
+		if (pTemp->beacon) {
+			qdf_mem_free(pTemp->beacon);
+		}
+
+		qdf_mem_free(pTemp);
+		pPrev->next = NULL;
+	} else
+#endif
+	pMac->lim.gLimNumIbssPeers++;
+
+	pPeerNode->next = pMac->lim.gLimIbssPeerList;
+	pMac->lim.gLimIbssPeerList = pPeerNode;
+
+	return QDF_STATUS_SUCCESS;
+
+} /*** end limAddIbssPeerToList() ***/
+
+/**
+ * ibss_peer_collect
+ *
+ ***FUNCTION:
+ * This is called to collect IBSS peer information
+ * from received Beacon/Probe Response frame from it.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ * @param  pBeacon - Parsed Beacon Frame structure
+ * @param  pBD     - Pointer to received BD
+ * @param  pPeer   - Pointer to IBSS peer node
+ *
+ * @return None
+ */
+
+static void
+ibss_peer_collect(tpAniSirGlobal pMac,
+		  tpSchBeaconStruct pBeacon,
+		  tpSirMacMgmtHdr pHdr,
+		  tLimIbssPeerNode *pPeer, tpPESession psessionEntry)
+{
+	qdf_mem_copy(pPeer->peerMacAddr, pHdr->sa, sizeof(tSirMacAddr));
+
+	pPeer->capabilityInfo = pBeacon->capabilityInfo;
+	pPeer->extendedRatesPresent = pBeacon->extendedRatesPresent;
+	pPeer->edcaPresent = pBeacon->edcaPresent;
+	pPeer->wmeEdcaPresent = pBeacon->wmeEdcaPresent;
+	pPeer->wmeInfoPresent = pBeacon->wmeInfoPresent;
+
+	if (pBeacon->IBSSParams.present) {
+		pPeer->atimIePresent = pBeacon->IBSSParams.present;
+		pPeer->peerAtimWindowLength = pBeacon->IBSSParams.atim;
+	}
+
+	if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
+	    (pBeacon->HTCaps.present)) {
+		pPeer->htCapable = pBeacon->HTCaps.present;
+		qdf_mem_copy((uint8_t *) pPeer->supportedMCSSet,
+			     (uint8_t *) pBeacon->HTCaps.supportedMCSSet,
+			     sizeof(pPeer->supportedMCSSet));
+		pPeer->htGreenfield = (uint8_t) pBeacon->HTCaps.greenField;
+		pPeer->htSupportedChannelWidthSet =
+			(uint8_t) pBeacon->HTCaps.supportedChannelWidthSet;
+		pPeer->htMIMOPSState =
+			(tSirMacHTMIMOPowerSaveState) pBeacon->HTCaps.mimoPowerSave;
+		pPeer->htMaxAmsduLength =
+			(uint8_t) pBeacon->HTCaps.maximalAMSDUsize;
+		pPeer->htAMpduDensity = pBeacon->HTCaps.mpduDensity;
+		pPeer->htDsssCckRate40MHzSupport =
+			(uint8_t) pBeacon->HTCaps.dsssCckMode40MHz;
+		pPeer->htShortGI20Mhz = (uint8_t) pBeacon->HTCaps.shortGI20MHz;
+		pPeer->htShortGI40Mhz = (uint8_t) pBeacon->HTCaps.shortGI40MHz;
+		pPeer->htMaxRxAMpduFactor = pBeacon->HTCaps.maxRxAMPDUFactor;
+		pPeer->htSecondaryChannelOffset =
+			pBeacon->HTInfo.secondaryChannelOffset;
+		pPeer->htLdpcCapable = (uint8_t) pBeacon->HTCaps.advCodingCap;
+	}
+
+	/* Collect peer VHT capabilities based on the received beacon from the peer */
+	if (pBeacon->VHTCaps.present) {
+		pPeer->vhtSupportedChannelWidthSet =
+			pBeacon->VHTOperation.chanWidth;
+		pPeer->vhtCapable = pBeacon->VHTCaps.present;
+
+		/* Collect VHT capabilities from beacon */
+		qdf_mem_copy((uint8_t *) &pPeer->VHTCaps,
+			     (uint8_t *) &pBeacon->VHTCaps,
+			     sizeof(tDot11fIEVHTCaps));
+	}
+	pPeer->erpIePresent = pBeacon->erpPresent;
+
+	qdf_mem_copy((uint8_t *) &pPeer->supportedRates,
+		     (uint8_t *) &pBeacon->supportedRates,
+		     pBeacon->supportedRates.numRates + 1);
+	if (pPeer->extendedRatesPresent)
+		qdf_mem_copy((uint8_t *) &pPeer->extendedRates,
+			     (uint8_t *) &pBeacon->extendedRates,
+			     pBeacon->extendedRates.numRates + 1);
+	else
+		pPeer->extendedRates.numRates = 0;
+
+	pPeer->next = NULL;
+} /*** end ibss_peer_collect() ***/
+
+/* handle change in peer qos/wme capabilities */
+static void
+ibss_sta_caps_update(tpAniSirGlobal pMac,
+		     tLimIbssPeerNode *pPeerNode, tpPESession psessionEntry)
+{
+	uint16_t peerIdx;
+	tpDphHashNode pStaDs;
+
+	pPeerNode->beaconHBCount++;     /* Update beacon count. */
+
+	/* if the peer node exists, update its qos capabilities */
+	pStaDs = dph_lookup_hash_entry(pMac, pPeerNode->peerMacAddr, &peerIdx,
+				       &psessionEntry->dph.dphHashTable);
+	if (pStaDs == NULL)
+		return;
+
+	/* Update HT Capabilities */
+	if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)) {
+		pStaDs->mlmStaContext.htCapability = pPeerNode->htCapable;
+		if (pPeerNode->htCapable) {
+			pStaDs->htGreenfield = pPeerNode->htGreenfield;
+			pStaDs->htSupportedChannelWidthSet =
+				pPeerNode->htSupportedChannelWidthSet;
+			pStaDs->htSecondaryChannelOffset =
+				pPeerNode->htSecondaryChannelOffset;
+			pStaDs->htMIMOPSState = pPeerNode->htMIMOPSState;
+			pStaDs->htMaxAmsduLength = pPeerNode->htMaxAmsduLength;
+			pStaDs->htAMpduDensity = pPeerNode->htAMpduDensity;
+			pStaDs->htDsssCckRate40MHzSupport =
+				pPeerNode->htDsssCckRate40MHzSupport;
+			pStaDs->htShortGI20Mhz = pPeerNode->htShortGI20Mhz;
+			pStaDs->htShortGI40Mhz = pPeerNode->htShortGI40Mhz;
+			pStaDs->htMaxRxAMpduFactor =
+				pPeerNode->htMaxRxAMpduFactor;
+			/* In the future, may need to check for "delayedBA" */
+			/* For now, it is IMMEDIATE BA only on ALL TID's */
+			pStaDs->baPolicyFlag = 0xFF;
+			pStaDs->htLdpcCapable = pPeerNode->htLdpcCapable;
+		}
+	}
+	if (IS_DOT11_MODE_VHT(psessionEntry->dot11mode)) {
+		pStaDs->mlmStaContext.vhtCapability = pPeerNode->vhtCapable;
+		if (pPeerNode->vhtCapable) {
+			pStaDs->vhtSupportedChannelWidthSet =
+				pPeerNode->vhtSupportedChannelWidthSet;
+
+			/* If in 11AC mode and if session requires 11AC mode, consider peer's */
+			/* max AMPDU length factor */
+			pStaDs->htMaxRxAMpduFactor =
+				pPeerNode->VHTCaps.maxAMPDULenExp;
+			pStaDs->vhtLdpcCapable =
+				(uint8_t) pPeerNode->VHTCaps.ldpcCodingCap;
+		}
+	}
+	/* peer is 11e capable but is not 11e enabled yet */
+	/* some STA's when joining Airgo IBSS, assert qos capability even when */
+	/* they don't support qos. however, they do not include the edca parameter */
+	/* set. so let's check for edcaParam in addition to the qos capability */
+	if (pPeerNode->capabilityInfo.qos && (psessionEntry->limQosEnabled)
+	    && pPeerNode->edcaPresent) {
+		pStaDs->qosMode = 1;
+		pStaDs->wmeEnabled = 0;
+		if (!pStaDs->lleEnabled) {
+			pStaDs->lleEnabled = 1;
+			/* dphSetACM(pMac, pStaDs); */
+		}
+		return;
+	}
+	/* peer is not 11e capable now but was 11e enabled earlier */
+	else if (pStaDs->lleEnabled) {
+		pStaDs->qosMode = 0;
+		pStaDs->lleEnabled = 0;
+	}
+	/* peer is wme capable but is not wme enabled yet */
+	if (pPeerNode->wmeInfoPresent && psessionEntry->limWmeEnabled) {
+		pStaDs->qosMode = 1;
+		pStaDs->lleEnabled = 0;
+		if (!pStaDs->wmeEnabled) {
+			pStaDs->wmeEnabled = 1;
+		}
+		return;
+	}
+	/* When the peer device supports EDCA parameters, then we were not
+	   considering. Added this code when we saw that one of the Peer Device
+	   was advertising WMM param where we were not honouring that. CR# 210756
+	 */
+	if (pPeerNode->wmeEdcaPresent && psessionEntry->limWmeEnabled) {
+		pStaDs->qosMode = 1;
+		pStaDs->lleEnabled = 0;
+		if (!pStaDs->wmeEnabled) {
+			pStaDs->wmeEnabled = 1;
+		}
+		return;
+	}
+	/* peer is not wme capable now but was wme enabled earlier */
+	else if (pStaDs->wmeEnabled) {
+		pStaDs->qosMode = 0;
+		pStaDs->wmeEnabled = 0;
+	}
+
+}
+
+static void
+ibss_sta_rates_update(tpAniSirGlobal pMac,
+		      tpDphHashNode pStaDs,
+		      tLimIbssPeerNode *pPeer, tpPESession psessionEntry)
+{
+	lim_populate_matching_rate_set(pMac, pStaDs, &pPeer->supportedRates,
+				       &pPeer->extendedRates,
+				       pPeer->supportedMCSSet, psessionEntry,
+				       &pPeer->VHTCaps, NULL);
+	pStaDs->mlmStaContext.capabilityInfo = pPeer->capabilityInfo;
+} /*** end ibss_sta_info_update() ***/
+
+/**
+ * ibss_sta_info_update
+ *
+ ***FUNCTION:
+ * This is called to program both SW & Polaris context
+ * for peer in IBSS.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac   - Pointer to Global MAC structure
+ * @param  pStaDs - Pointer to DPH node
+ * @param  pPeer  - Pointer to IBSS peer node
+ *
+ * @return None
+ */
+
+static void
+ibss_sta_info_update(tpAniSirGlobal pMac,
+		     tpDphHashNode pStaDs,
+		     tLimIbssPeerNode *pPeer, tpPESession psessionEntry)
+{
+	pStaDs->staType = STA_ENTRY_PEER;
+	ibss_sta_caps_update(pMac, pPeer, psessionEntry);
+	ibss_sta_rates_update(pMac, pStaDs, pPeer, psessionEntry);
+} /*** end ibss_sta_info_update() ***/
+
+static void ibss_coalesce_free(tpAniSirGlobal pMac)
+{
+	if (pMac->lim.ibssInfo.pHdr != NULL)
+		qdf_mem_free(pMac->lim.ibssInfo.pHdr);
+	if (pMac->lim.ibssInfo.pBeacon != NULL)
+		qdf_mem_free(pMac->lim.ibssInfo.pBeacon);
+
+	pMac->lim.ibssInfo.pHdr = NULL;
+	pMac->lim.ibssInfo.pBeacon = NULL;
+}
+
+/*
+ * save the beacon params for use when adding the bss
+ */
+static void
+ibss_coalesce_save(tpAniSirGlobal pMac,
+		   tpSirMacMgmtHdr pHdr, tpSchBeaconStruct pBeacon)
+{
+	/* get rid of any saved info */
+	ibss_coalesce_free(pMac);
+
+	pMac->lim.ibssInfo.pHdr = qdf_mem_malloc(sizeof(*pHdr));
+	if (!pMac->lim.ibssInfo.pHdr)
+		return;
+
+	pMac->lim.ibssInfo.pBeacon = qdf_mem_malloc(sizeof(*pBeacon));
+	if (!pMac->lim.ibssInfo.pBeacon) {
+		ibss_coalesce_free(pMac);
+		return;
+	}
+
+	qdf_mem_copy(pMac->lim.ibssInfo.pHdr, pHdr, sizeof(*pHdr));
+	qdf_mem_copy(pMac->lim.ibssInfo.pBeacon, pBeacon, sizeof(*pBeacon));
+}
+
+/*
+ * tries to add a new entry to dph hash node
+ * if necessary, an existing entry is eliminated
+ */
+static QDF_STATUS
+ibss_dph_entry_add(tpAniSirGlobal pMac,
+		   tSirMacAddr peerAddr,
+		   tpDphHashNode *ppSta, tpPESession psessionEntry)
+{
+	uint16_t peerIdx;
+	tpDphHashNode pStaDs;
+
+	*ppSta = NULL;
+
+	pStaDs =
+		dph_lookup_hash_entry(pMac, peerAddr, &peerIdx,
+				      &psessionEntry->dph.dphHashTable);
+	if (pStaDs != NULL) {
+		/* Trying to add context for already existing STA in IBSS */
+		pe_err("STA exists already");
+		lim_print_mac_addr(pMac, peerAddr, LOGE);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/**
+	 * Assign an AID, delete context existing with that
+	 * AID and then add an entry to hash table maintained
+	 * by DPH module.
+	 */
+	peerIdx = lim_assign_peer_idx(pMac, psessionEntry);
+
+	pStaDs =
+		dph_get_hash_entry(pMac, peerIdx, &psessionEntry->dph.dphHashTable);
+	if (pStaDs) {
+		(void)lim_del_sta(pMac, pStaDs, false /*asynchronous */,
+				  psessionEntry);
+		lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, peerIdx,
+					  psessionEntry);
+	}
+
+	pStaDs =
+		dph_add_hash_entry(pMac, peerAddr, peerIdx,
+				   &psessionEntry->dph.dphHashTable);
+	if (pStaDs == NULL) {
+		/* Could not add hash table entry */
+		pe_err("could not add hash entry at DPH for peerIdx/aid: %d MACaddr:",
+			       peerIdx);
+		lim_print_mac_addr(pMac, peerAddr, LOGE);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*ppSta = pStaDs;
+	return QDF_STATUS_SUCCESS;
+}
+
+/* send a status change notification */
+static void
+ibss_status_chg_notify(tpAniSirGlobal pMac, tSirMacAddr peerAddr,
+		       uint16_t staIndex, uint16_t status, uint8_t sessionId)
+{
+
+	tLimIbssPeerNode *peerNode;
+	uint8_t *beacon = NULL;
+	uint16_t bcnLen = 0;
+
+	peerNode = ibss_peer_find(pMac, peerAddr);
+	if (peerNode != NULL) {
+		if (peerNode->beacon == NULL)
+			peerNode->beaconLen = 0;
+		beacon = peerNode->beacon;
+		bcnLen = peerNode->beaconLen;
+		peerNode->beacon = NULL;
+		peerNode->beaconLen = 0;
+	}
+
+	lim_send_sme_ibss_peer_ind(pMac, peerAddr, staIndex,
+				   beacon, bcnLen, status, sessionId);
+
+	if (beacon != NULL) {
+		qdf_mem_free(beacon);
+	}
+}
+
+void ibss_bss_add(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	tLimMlmStartReq mlmStartReq;
+	uint32_t cfg;
+	tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr;
+	tpSchBeaconStruct pBeacon =
+		(tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon;
+	qdf_size_t num_ext_rates = 0;
+
+	if ((pHdr == NULL) || (pBeacon == NULL)) {
+		pe_err("Unable to add BSS (no cached BSS info)");
+		return;
+	}
+
+	qdf_mem_copy(psessionEntry->bssId, pHdr->bssId, sizeof(tSirMacAddr));
+
+	sir_copy_mac_addr(pHdr->bssId, psessionEntry->bssId);
+
+	/* Copy beacon interval from sessionTable */
+	cfg = psessionEntry->beaconParams.beaconInterval;
+	if (cfg != pBeacon->beaconInterval)
+		psessionEntry->beaconParams.beaconInterval =
+			pBeacon->beaconInterval;
+
+	/* This function ibss_bss_add (and hence the below code) is only called during ibss coalescing. We need to
+	 * adapt to peer's capability with respect to short slot time. Changes have been made to lim_apply_configuration()
+	 * so that the IBSS doesn't blindly start with short slot = 1. If IBSS start is part of coalescing then it will adapt
+	 * to peer's short slot using code below.
+	 */
+	/* If cfg is already set to current peer's capability then no need to set it again */
+	if (psessionEntry->shortSlotTimeSupported !=
+	    pBeacon->capabilityInfo.shortSlotTime) {
+		psessionEntry->shortSlotTimeSupported =
+			pBeacon->capabilityInfo.shortSlotTime;
+	}
+	qdf_mem_copy((uint8_t *) &psessionEntry->pLimStartBssReq->
+		     operationalRateSet, (uint8_t *) &pBeacon->supportedRates,
+		     pBeacon->supportedRates.numRates);
+
+	/**
+	 * WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET CFG needs to be reset, when
+	 * there is no extended rate IE present in beacon. This is especially important when
+	 * supportedRateSet IE contains all the extended rates as well and STA decides to coalesce.
+	 * In this IBSS coalescing scenario LIM will tear down the BSS and Add a new one. So LIM needs to
+	 * reset this CFG, just in case CSR originally had set this CFG when IBSS was started from the local profile.
+	 * If IBSS was started by CSR from the BssDescription, then it would reset this CFG before StartBss is issued.
+	 * The idea is that the count of OpRateSet and ExtendedOpRateSet rates should not be more than 12.
+	 */
+
+	if (pBeacon->extendedRatesPresent)
+		num_ext_rates = pBeacon->extendedRates.numRates;
+	if (wlan_mlme_set_cfg_str(
+		(uint8_t *)&pBeacon->extendedRates.rate,
+		&pMac->mlme_cfg->rates.ext_opr_rate_set,
+		num_ext_rates) != QDF_STATUS_SUCCESS) {
+		pe_err("could not update ExtendedOperRateset at CFG");
+		return;
+	}
+
+	/*
+	 * Each IBSS node will advertise its own HT Capabilities instead of adapting to the Peer's capabilities
+	 * If we don't do this then IBSS may not go back to full capabilities when the STA with lower capabilities
+	 * leaves the IBSS.  e.g. when non-CB STA joins an IBSS and then leaves, the IBSS will be stuck at non-CB mode
+	 * even though all the nodes are capable of doing CB.
+	 * so it is decided to leave the self HT capabilties intact. This may change if some issues are found in interop.
+	 */
+	qdf_mem_set((void *)&mlmStartReq, sizeof(mlmStartReq), 0);
+
+	qdf_mem_copy(mlmStartReq.bssId, pHdr->bssId, sizeof(tSirMacAddr));
+	mlmStartReq.rateSet.numRates =
+		psessionEntry->pLimStartBssReq->operationalRateSet.numRates;
+	qdf_mem_copy(&mlmStartReq.rateSet.rate[0],
+		     &psessionEntry->pLimStartBssReq->operationalRateSet.
+		     rate[0], mlmStartReq.rateSet.numRates);
+	mlmStartReq.bssType = eSIR_IBSS_MODE;
+	mlmStartReq.beaconPeriod = pBeacon->beaconInterval;
+	mlmStartReq.nwType = psessionEntry->pLimStartBssReq->nwType;    /* psessionEntry->nwType is also OK???? */
+	mlmStartReq.htCapable = psessionEntry->htCapability;
+	mlmStartReq.htOperMode = pMac->lim.gHTOperMode;
+	mlmStartReq.dualCTSProtection = pMac->lim.gHTDualCTSProtection;
+	mlmStartReq.txChannelWidthSet = psessionEntry->htRecommendedTxWidthSet;
+
+	/* reading the channel num from session Table */
+	mlmStartReq.channelNumber = psessionEntry->currentOperChannel;
+
+	mlmStartReq.cbMode = psessionEntry->pLimStartBssReq->cbMode;
+
+	/* Copy the SSID for RxP filtering based on SSID. */
+	qdf_mem_copy((uint8_t *) &mlmStartReq.ssId,
+		     (uint8_t *) &psessionEntry->pLimStartBssReq->ssId,
+		     psessionEntry->pLimStartBssReq->ssId.length + 1);
+
+	pe_debug("invoking ADD_BSS as part of coalescing!");
+#ifdef CONFIG_VDEV_SM
+	wlan_vdev_mlme_sm_deliver_evt(psessionEntry->vdev,
+				      WLAN_VDEV_SM_EV_START,
+				      sizeof(mlmStartReq), &mlmStartReq);
+#else
+	if (lim_mlm_add_bss(pMac, &mlmStartReq, psessionEntry) !=
+	    eSIR_SME_SUCCESS) {
+		pe_err("AddBss failure");
+		return;
+	}
+#endif
+	/* Update fields in Beacon */
+	if (sch_set_fixed_beacon_fields(pMac, psessionEntry) != QDF_STATUS_SUCCESS) {
+		pe_err("Unable to set fixed Beacon fields");
+		return;
+	}
+
+}
+
+void ibss_bss_delete(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+	QDF_STATUS status;
+
+	pe_debug("Initiating IBSS Delete BSS");
+	if (session->limMlmState != eLIM_MLM_BSS_STARTED_STATE) {
+		pe_warn("Incorrect LIM MLM state for delBss: %d",
+			session->limMlmState);
+		return;
+	}
+	status = lim_del_bss(mac_ctx, NULL, session->bssIdx, session);
+	if (QDF_IS_STATUS_ERROR(status))
+		pe_err("delBss failed for bss: %d", session->bssIdx);
+}
+
+/**
+ * lim_ibss_init
+ *
+ ***FUNCTION:
+ * This function is called while starting an IBSS
+ * to initialize list used to maintain IBSS peers.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_ibss_init(tpAniSirGlobal pMac)
+{
+	pMac->lim.gLimIbssCoalescingHappened = 0;
+	pMac->lim.gLimIbssPeerList = NULL;
+	pMac->lim.gLimNumIbssPeers = 0;
+
+	/* ibss info - params for which ibss to join while coalescing */
+	qdf_mem_set(&pMac->lim.ibssInfo, sizeof(tAniSirLimIbss), 0);
+} /*** end lim_ibss_init() ***/
+
+/**
+ * lim_ibss_delete_all_peers
+ *
+ ***FUNCTION:
+ * This function is called to delete all peers.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @return None
+ */
+void lim_ibss_delete_all_peers(tpAniSirGlobal pMac,
+			       tpPESession psessionEntry)
+{
+	tLimIbssPeerNode *pCurrNode, *pTempNode;
+	tpDphHashNode pStaDs;
+	uint16_t peerIdx;
+#ifdef CONFIG_VDEV_SM
+	QDF_STATUS status;
+#endif
+
+	pCurrNode = pTempNode = pMac->lim.gLimIbssPeerList;
+
+	while (pCurrNode != NULL) {
+		if (!pMac->lim.gLimNumIbssPeers) {
+			pe_err("Number of peers in the list is zero and node present");
+			return;
+		}
+		/* Delete the dph entry for the station
+		 * Since it is called to remove all peers, just delete from dph,
+		 * no need to do any beacon related params i.e., dont call lim_delete_dph_hash_entry
+		 */
+		pStaDs =
+			dph_lookup_hash_entry(pMac, pCurrNode->peerMacAddr, &peerIdx,
+					      &psessionEntry->dph.dphHashTable);
+		if (pStaDs) {
+
+			ibss_status_chg_notify(pMac, pCurrNode->peerMacAddr,
+					       pStaDs->staIndex,
+					       eWNI_SME_IBSS_PEER_DEPARTED_IND,
+					       psessionEntry->smeSessionId);
+			lim_del_sta(pMac, pStaDs, false, psessionEntry);
+			lim_release_peer_idx(pMac, peerIdx, psessionEntry);
+			dph_delete_hash_entry(pMac, pStaDs->staAddr, peerIdx,
+					      &psessionEntry->dph.dphHashTable);
+		}
+
+		pTempNode = pCurrNode->next;
+
+		/* TODO :Sessionize this code */
+		/* Fix CR 227642: PeerList should point to the next node since the current node is being
+		 * freed in the next line. In ibss_peerfind in ibss_status_chg_notify above, we use this
+		 * peer list to find the next peer. So this list needs to be updated with the no of peers left
+		 * after each iteration in this while loop since one by one peers are deleted (freed) in this
+		 * loop causing the lim.gLimIbssPeerList to point to some freed memory.
+		 */
+		pMac->lim.gLimIbssPeerList = pTempNode;
+
+		if (pCurrNode->beacon) {
+			qdf_mem_free(pCurrNode->beacon);
+		}
+		qdf_mem_free(pCurrNode);
+		if (pMac->lim.gLimNumIbssPeers > 0) /* be paranoid */
+			pMac->lim.gLimNumIbssPeers--;
+		pCurrNode = pTempNode;
+	}
+
+	if (pMac->lim.gLimNumIbssPeers)
+		pe_err("Number of peers: %d in the list is non-zero",
+			pMac->lim.gLimNumIbssPeers);
+
+	pMac->lim.gLimNumIbssPeers = 0;
+	pMac->lim.gLimIbssPeerList = NULL;
+#ifdef CONFIG_VDEV_SM
+	status =
+	   wlan_vdev_mlme_sm_deliver_evt(psessionEntry->vdev,
+					 WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE,
+					 sizeof(*psessionEntry), psessionEntry);
+	if (!pMac->lim.gLimIbssCoalescingHappened &&
+	    QDF_IS_STATUS_ERROR(status)) {
+		pe_err("failed to post WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE for vdevid %d",
+		       psessionEntry->smeSessionId);
+		lim_send_stop_bss_failure_resp(pMac, psessionEntry);
+	}
+#endif
+}
+
+/**
+ * lim_ibss_delete() - This function is called while tearing down an IBSS
+ *
+ * @pMac: Pointer to Global MAC structure
+ * @psessionEntry: Pointer to session entry
+ *
+ * Return: none
+ */
+
+void lim_ibss_delete(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+#ifndef CONFIG_VDEV_SM
+	lim_ibss_delete_all_peers(pMac, psessionEntry);
+#endif
+	ibss_coalesce_free(pMac);
+}
+
+/** -------------------------------------------------------------
+   \fn lim_ibss_set_protection
+   \brief Decides all the protection related information.
+ \
+   \param  tpAniSirGlobal    pMac
+   \param  tSirMacAddr peerMacAddr
+   \param  tpUpdateBeaconParams pBeaconParams
+   \return None
+   -------------------------------------------------------------*/
+static void
+lim_ibss_set_protection(tpAniSirGlobal pMac, uint8_t enable,
+			tpUpdateBeaconParams pBeaconParams,
+			tpPESession psessionEntry)
+{
+
+	if (!pMac->lim.cfgProtection.fromllb) {
+		pe_err("protection from 11b is disabled");
+		return;
+	}
+
+	if (enable) {
+		psessionEntry->gLim11bParams.protectionEnabled = true;
+		if (false ==
+		    psessionEntry->beaconParams.
+		    llbCoexist /*pMac->lim.llbCoexist */) {
+			pe_debug("=> IBSS: Enable Protection");
+			pBeaconParams->llbCoexist =
+				psessionEntry->beaconParams.llbCoexist = true;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_llBCOEXIST_CHANGED;
+		}
+	} else if (true ==
+		   psessionEntry->beaconParams.
+		   llbCoexist /*pMac->lim.llbCoexist */) {
+		psessionEntry->gLim11bParams.protectionEnabled = false;
+		pe_debug("===> IBSS: Disable protection");
+		pBeaconParams->llbCoexist =
+			psessionEntry->beaconParams.llbCoexist = false;
+		pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
+	}
+	return;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_ibss_update_protection_params
+   \brief Decides all the protection related information.
+ \
+   \param  tpAniSirGlobal    pMac
+   \param  tSirMacAddr peerMacAddr
+   \param  tpUpdateBeaconParams pBeaconParams
+   \return None
+   -------------------------------------------------------------*/
+static void
+lim_ibss_update_protection_params(tpAniSirGlobal pMac,
+				  tSirMacAddr peerMacAddr,
+				  tLimProtStaCacheType protStaCacheType,
+				  tpPESession psessionEntry)
+{
+	uint32_t i;
+
+	pe_debug("STA is associated Addr :");
+	lim_print_mac_addr(pMac, peerMacAddr, LOGD);
+
+	for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+		if (pMac->lim.protStaCache[i].active) {
+			pe_debug("Addr:");
+			lim_print_mac_addr
+				(pMac, pMac->lim.protStaCache[i].addr, LOGD);
+
+			if (!qdf_mem_cmp(pMac->lim.protStaCache[i].addr,
+					    peerMacAddr,
+					    sizeof(tSirMacAddr))) {
+				pe_debug("matching cache entry at: %d already active",
+					i);
+				return;
+			}
+		}
+	}
+
+	for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+		if (!pMac->lim.protStaCache[i].active)
+			break;
+	}
+
+	if (i >= LIM_PROT_STA_CACHE_SIZE) {
+		pe_err("No space in ProtStaCache");
+		return;
+	}
+
+	qdf_mem_copy(pMac->lim.protStaCache[i].addr,
+		     peerMacAddr, sizeof(tSirMacAddr));
+
+	pMac->lim.protStaCache[i].protStaCacheType = protStaCacheType;
+	pMac->lim.protStaCache[i].active = true;
+	if (eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType) {
+		psessionEntry->gLim11bParams.numSta++;
+	} else if (eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType) {
+		psessionEntry->gLim11gParams.numSta++;
+	}
+}
+
+/** -------------------------------------------------------------
+   \fn lim_ibss_decide_protection
+   \brief Decides all the protection related information.
+ \
+   \param  tpAniSirGlobal    pMac
+   \param  tSirMacAddr peerMacAddr
+   \param  tpUpdateBeaconParams pBeaconParams
+   \return None
+   -------------------------------------------------------------*/
+static void
+lim_ibss_decide_protection(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+			   tpUpdateBeaconParams pBeaconParams,
+			   tpPESession psessionEntry)
+{
+	enum band_info rfBand = BAND_UNKNOWN;
+	uint32_t phyMode;
+	tLimProtStaCacheType protStaCacheType =
+		eLIM_PROT_STA_CACHE_TYPE_INVALID;
+
+	pBeaconParams->paramChangeBitmap = 0;
+
+	if (NULL == pStaDs) {
+		pe_err("pStaDs is NULL");
+		return;
+	}
+
+	lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
+	if (BAND_2G == rfBand) {
+		lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+		/* We are 11G or 11n. Check if we need protection from 11b Stations. */
+		if ((phyMode == WNI_CFG_PHY_MODE_11G)
+		    || (psessionEntry->htCapability)) {
+			/* As we found in the past, it is possible that a 11n STA sends
+			 * Beacon with HT IE but not ERP IE.  So the absence of ERP IE
+			 * in the Beacon is not enough to conclude that STA is 11b.
+			 */
+			if ((pStaDs->erpEnabled == eHAL_CLEAR) &&
+			    (!pStaDs->mlmStaContext.htCapability)) {
+				protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
+				pe_err("Enable protection from 11B");
+				lim_ibss_set_protection(pMac, true,
+							pBeaconParams,
+							psessionEntry);
+			}
+		}
+	}
+	lim_ibss_update_protection_params(pMac, pStaDs->staAddr, protStaCacheType,
+					  psessionEntry);
+	return;
+}
+
+/**
+ * lim_ibss_peer_find()
+ *
+ ***FUNCTION:
+ * This function is called while adding a context at
+ * DPH & Polaris for a peer in IBSS.
+ * If peer is found in the list, capabilities from the
+ * returned BSS description are used at DPH node & Polaris.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  macAddr - MAC address of the peer
+ *
+ * @return Pointer to peer node if found, else NULL
+ */
+tLimIbssPeerNode *lim_ibss_peer_find(tpAniSirGlobal pMac, tSirMacAddr macAddr)
+{
+	return ibss_peer_find(pMac, macAddr);
+}
+
+/**
+ * lim_ibss_sta_add()
+ *
+ ***FUNCTION:
+ * This function is called to add an STA context in IBSS role
+ * whenever a data frame is received from/for a STA that failed
+ * hash lookup at DPH.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac       Pointer to Global MAC structure
+ * @param  peerAdddr  MAC address of the peer being added
+ * @return retCode    Indicates success or failure return code
+ * @return
+ */
+
+QDF_STATUS
+lim_ibss_sta_add(tpAniSirGlobal pMac, void *pBody, tpPESession psessionEntry)
+{
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	tpDphHashNode pStaDs;
+	tLimIbssPeerNode *pPeerNode;
+	tLimMlmStates prevState;
+	tSirMacAddr *pPeerAddr = (tSirMacAddr *) pBody;
+	tUpdateBeaconParams beaconParams;
+
+	qdf_mem_set((uint8_t *) &beaconParams, sizeof(tUpdateBeaconParams), 0);
+
+	if (pBody == 0) {
+		pe_err("Invalid IBSS AddSta");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pe_debug("Rx Add-Ibss-Sta for MAC:");
+	lim_print_mac_addr(pMac, *pPeerAddr, LOGD);
+
+	pPeerNode = ibss_peer_find(pMac, *pPeerAddr);
+	if (NULL != pPeerNode) {
+		retCode =
+			ibss_dph_entry_add(pMac, *pPeerAddr, &pStaDs,
+					   psessionEntry);
+		if (QDF_STATUS_SUCCESS == retCode) {
+			prevState = pStaDs->mlmStaContext.mlmState;
+			pStaDs->erpEnabled = pPeerNode->erpIePresent;
+
+			ibss_sta_info_update(pMac, pStaDs, pPeerNode,
+					     psessionEntry);
+			pe_debug("initiating ADD STA for the IBSS peer");
+			retCode =
+				lim_add_sta(pMac, pStaDs, false, psessionEntry);
+			if (retCode != QDF_STATUS_SUCCESS) {
+				pe_err("ibss-sta-add failed (reason %x)",
+					       retCode);
+				lim_print_mac_addr(pMac, *pPeerAddr, LOGE);
+				pStaDs->mlmStaContext.mlmState = prevState;
+				dph_delete_hash_entry(pMac, pStaDs->staAddr,
+						      pStaDs->assocId,
+						      &psessionEntry->dph.
+						      dphHashTable);
+			} else {
+				if (pMac->lim.gLimProtectionControl !=
+				    MLME_FORCE_POLICY_PROTECTION_DISABLE)
+					lim_ibss_decide_protection(pMac, pStaDs,
+								   &beaconParams,
+								   psessionEntry);
+
+				if (beaconParams.paramChangeBitmap) {
+					pe_debug("---> Update Beacon Params");
+					sch_set_fixed_beacon_fields(pMac,
+								    psessionEntry);
+					beaconParams.bssIdx =
+						psessionEntry->bssIdx;
+					lim_send_beacon_params(pMac, &beaconParams,
+							       psessionEntry);
+				}
+			}
+		} else {
+			pe_err("hashTblAdd failed reason: %x", retCode);
+			lim_print_mac_addr(pMac, *pPeerAddr, LOGE);
+		}
+	} else {
+		retCode = QDF_STATUS_E_FAILURE;
+	}
+
+	return retCode;
+}
+
+/**
+ * lim_ibss_search_and_delete_peer()- to cleanup the IBSS
+ * peer from lim ibss peer list
+ *
+ * @mac_ptr: Pointer to Global MAC structure
+ * @session_entry: Session entry
+ * @mac_addr: Mac Address of the IBSS peer
+ *
+ * This function is called to cleanup the IBSS peer from
+ * lim ibss peer list
+ *
+ * Return: None
+ *
+ */
+static void
+lim_ibss_search_and_delete_peer(tpAniSirGlobal mac_ctx,
+			tpPESession session_entry, tSirMacAddr mac_addr)
+{
+	tLimIbssPeerNode *temp_node, *prev_node;
+	tLimIbssPeerNode *temp_next_node = NULL;
+
+	prev_node = temp_node = mac_ctx->lim.gLimIbssPeerList;
+
+	pe_debug(" PEER ADDR :" MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(mac_addr));
+
+	/** Compare Peer */
+	while (NULL != temp_node) {
+		temp_next_node = temp_node->next;
+
+		/* Delete the STA with MAC address */
+		if (!qdf_mem_cmp((uint8_t *) mac_addr,
+				    (uint8_t *) &temp_node->peerMacAddr,
+				    sizeof(tSirMacAddr))) {
+			if (temp_node ==
+			   mac_ctx->lim.gLimIbssPeerList) {
+				mac_ctx->lim.gLimIbssPeerList =
+					temp_node->next;
+				prev_node =
+					mac_ctx->lim.gLimIbssPeerList;
+			} else
+				prev_node->next = temp_node->next;
+			if (temp_node->beacon)
+				qdf_mem_free(temp_node->beacon);
+
+			qdf_mem_free(temp_node);
+			mac_ctx->lim.gLimNumIbssPeers--;
+
+			temp_node = temp_next_node;
+			break;
+		}
+		prev_node = temp_node;
+		temp_node = temp_next_node;
+	}
+	/*
+	 * if it is the last peer walking out, we better
+	 * we set IBSS state to inactive.
+	 */
+	if (0 == mac_ctx->lim.gLimNumIbssPeers) {
+		pe_debug("Last STA from IBSS walked out");
+		session_entry->limIbssActive = false;
+	}
+}
+
+/**
+ * lim_ibss_delete_peer()- to delete IBSS peer
+ *
+ * @mac_ptr: Pointer to Global MAC structure
+ * @session_entry: Session entry
+ * @mac_addr: Mac Address of the IBSS peer
+ *
+ * This function is called delete IBSS peer.
+ *
+ * Return: None
+ *
+ */
+static void
+lim_ibss_delete_peer(tpAniSirGlobal mac_ctx,
+			tpPESession session_entry, tSirMacAddr mac_addr)
+{
+	tpDphHashNode sta = NULL;
+	uint16_t peer_idx = 0;
+
+	pe_debug("Delete peer :" MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(mac_addr));
+
+	sta = dph_lookup_hash_entry(mac_ctx, mac_addr,
+			&peer_idx,
+			&session_entry->dph.
+			dphHashTable);
+
+	if (!sta) {
+		pe_err("DPH Entry for STA %pM is missing",
+			mac_addr);
+		return;
+	}
+
+	if (STA_INVALID_IDX != sta->staIndex) {
+		lim_del_sta(mac_ctx, sta,
+			  true, session_entry);
+	} else {
+		/*
+		 * This mean ADD STA failed, thus remove the sta from
+		 * from database and no need to send del sta to firmware
+		 * and peer departed indication to upper layer.
+		 */
+		lim_delete_dph_hash_entry(mac_ctx, sta->staAddr,
+			  peer_idx, session_entry);
+		lim_release_peer_idx(mac_ctx,
+			peer_idx, session_entry);
+		lim_ibss_search_and_delete_peer(mac_ctx,
+			session_entry, mac_addr);
+	}
+
+}
+
+void lim_process_ibss_del_sta_rsp(tpAniSirGlobal mac_ctx,
+	struct scheduler_msg *lim_msg,
+	tpPESession pe_session)
+{
+	tpDphHashNode sta_ds = NULL;
+	tpDeleteStaParams del_sta_params = (tpDeleteStaParams) lim_msg->bodyptr;
+	tSirResultCodes status = eSIR_SME_SUCCESS;
+
+	if (!del_sta_params) {
+		pe_err("del_sta_params is NULL");
+		return;
+	}
+	if (!LIM_IS_IBSS_ROLE(pe_session)) {
+		pe_err("Session %d is not IBSS role", del_sta_params->assocId);
+		status = eSIR_SME_REFUSED;
+		goto skip_event;
+	}
+
+	sta_ds = dph_get_hash_entry(mac_ctx, del_sta_params->assocId,
+			&pe_session->dph.dphHashTable);
+	if (!sta_ds) {
+		pe_err("DPH Entry for STA %X is missing",
+			del_sta_params->assocId);
+		status = eSIR_SME_REFUSED;
+		goto skip_event;
+	}
+
+	if (QDF_STATUS_SUCCESS != del_sta_params->status) {
+		pe_err("DEL STA failed!");
+		status = eSIR_SME_REFUSED;
+		goto skip_event;
+	}
+	pe_debug("Deleted STA associd %d staId %d MAC " MAC_ADDRESS_STR,
+		sta_ds->assocId, sta_ds->staIndex,
+		MAC_ADDR_ARRAY(sta_ds->staAddr));
+
+	lim_delete_dph_hash_entry(mac_ctx, sta_ds->staAddr,
+			  del_sta_params->assocId, pe_session);
+	lim_release_peer_idx(mac_ctx,
+			del_sta_params->assocId, pe_session);
+
+	ibss_status_chg_notify(mac_ctx,
+		del_sta_params->staMac,
+		sta_ds->staIndex,
+		eWNI_SME_IBSS_PEER_DEPARTED_IND,
+		pe_session->smeSessionId);
+
+	lim_ibss_search_and_delete_peer(mac_ctx,
+				pe_session, del_sta_params->staMac);
+
+skip_event:
+	qdf_mem_free(del_sta_params);
+	lim_msg->bodyptr = NULL;
+}
+
+/* handle the response from HAL for an ADD STA request */
+QDF_STATUS
+lim_ibss_add_sta_rsp(tpAniSirGlobal pMac, void *msg, tpPESession psessionEntry)
+{
+	tpDphHashNode pStaDs;
+	uint16_t peerIdx;
+	tpAddStaParams pAddStaParams = (tpAddStaParams) msg;
+
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+	if (pAddStaParams == NULL) {
+		pe_err("IBSS: ADD_STA_RSP with no body!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pStaDs =
+		dph_lookup_hash_entry(pMac, pAddStaParams->staMac, &peerIdx,
+				      &psessionEntry->dph.dphHashTable);
+	if (pStaDs == NULL) {
+		pe_err("IBSS: ADD_STA_RSP for unknown MAC addr: "MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(pAddStaParams->staMac));
+		qdf_mem_free(pAddStaParams);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pAddStaParams->status != QDF_STATUS_SUCCESS) {
+		pe_err("IBSS: ADD_STA_RSP error: %x for MAC:"MAC_ADDRESS_STR,
+			pAddStaParams->status,
+			MAC_ADDR_ARRAY(pAddStaParams->staMac));
+		lim_ibss_delete_peer(pMac,
+			psessionEntry, pAddStaParams->staMac);
+		qdf_mem_free(pAddStaParams);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pStaDs->bssId = pAddStaParams->bssIdx;
+	pStaDs->staIndex = pAddStaParams->staIdx;
+	pStaDs->valid = 1;
+	pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+
+	pe_debug("IBSS: sending IBSS_NEW_PEER msg to SME!");
+
+	ibss_status_chg_notify(pMac, pAddStaParams->staMac,
+			       pStaDs->staIndex,
+			       eWNI_SME_IBSS_NEW_PEER_IND,
+			       psessionEntry->smeSessionId);
+
+	qdf_mem_free(pAddStaParams);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void lim_ibss_del_bss_rsp_when_coalescing(tpAniSirGlobal pMac, void *msg,
+					  tpPESession psessionEntry)
+{
+	tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg;
+
+	pe_debug("IBSS: DEL_BSS_RSP Rcvd during coalescing!");
+
+	if (pDelBss == NULL) {
+		pe_err("IBSS: DEL_BSS_RSP(coalesce) with no body!");
+		goto end;
+	}
+
+	if (pDelBss->status != QDF_STATUS_SUCCESS) {
+		pe_err("IBSS: DEL_BSS_RSP(coalesce) error: %x Bss: %d",
+			pDelBss->status, pDelBss->bssIdx);
+		goto end;
+	}
+
+#ifndef CONFIG_VDEV_SM
+	/* Delete peer entries. */
+	lim_ibss_delete_all_peers(pMac, psessionEntry);
+#endif
+	/* add the new bss */
+	ibss_bss_add(pMac, psessionEntry);
+end:
+	if (pDelBss != NULL)
+		qdf_mem_free(pDelBss);
+}
+
+void lim_ibss_add_bss_rsp_when_coalescing(tpAniSirGlobal pMac, void *msg,
+					  tpPESession pSessionEntry)
+{
+	uint8_t infoLen;
+	tSirSmeNewBssInfo newBssInfo;
+
+	tpAddBssParams pAddBss = (tpAddBssParams) msg;
+
+	tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr;
+	tpSchBeaconStruct pBeacon =
+		(tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon;
+
+	if ((pHdr == NULL) || (pBeacon == NULL)) {
+		pe_err("Unable to handle AddBssRspWhenCoalescing (no cached BSS info)");
+		goto end;
+	}
+	/* Inform Host of IBSS coalescing */
+	infoLen = sizeof(tSirMacAddr) + sizeof(tSirMacChanNum) +
+		  sizeof(uint8_t) + pBeacon->ssId.length + 1;
+
+	qdf_mem_set((void *)&newBssInfo, sizeof(newBssInfo), 0);
+	qdf_mem_copy(newBssInfo.bssId.bytes, pHdr->bssId, QDF_MAC_ADDR_SIZE);
+	newBssInfo.channelNumber = (tSirMacChanNum) pAddBss->currentOperChannel;
+	qdf_mem_copy((uint8_t *) &newBssInfo.ssId,
+		     (uint8_t *) &pBeacon->ssId, pBeacon->ssId.length + 1);
+
+	pe_debug("Sending JOINED_NEW_BSS notification to SME");
+
+	lim_send_sme_wm_status_change_ntf(pMac, eSIR_SME_JOINED_NEW_BSS,
+					  (uint32_t *) &newBssInfo,
+					  infoLen, pSessionEntry->smeSessionId);
+	{
+		/* Configure beacon and send beacons to HAL */
+		lim_send_beacon(pMac, pSessionEntry);
+	}
+
+end:
+	ibss_coalesce_free(pMac);
+}
+
+void lim_ibss_del_bss_rsp(tpAniSirGlobal pMac, void *msg, tpPESession psessionEntry)
+{
+	tSirResultCodes rc = eSIR_SME_SUCCESS;
+	tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg;
+	tSirMacAddr nullBssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+	if (pDelBss == NULL) {
+		pe_err("IBSS: DEL_BSS_RSP with no body!");
+		rc = eSIR_SME_REFUSED;
+		goto end;
+	}
+
+	psessionEntry = pe_find_session_by_session_id(pMac, pDelBss->sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given sessionID");
+		goto end;
+	}
+
+	/*
+	 * If delBss was issued as part of IBSS Coalescing, gLimIbssCoalescingHappened flag will be true.
+	 * BSS has to be added again in this scenario, so this case needs to be handled separately.
+	 * If delBss was issued as a result of trigger from SME_STOP_BSS Request, then limSme state changes to
+	 * 'IDLE' and gLimIbssCoalescingHappened flag will be false. In this case STOP BSS RSP has to be sent to SME.
+	 */
+	if (true == pMac->lim.gLimIbssCoalescingHappened) {
+
+		lim_ibss_del_bss_rsp_when_coalescing(pMac, msg, psessionEntry);
+		return;
+	}
+
+	if (pDelBss->status != QDF_STATUS_SUCCESS) {
+		pe_err("IBSS: DEL_BSS_RSP error: %x Bss: %d",
+			       pDelBss->status, pDelBss->bssIdx);
+		rc = eSIR_SME_STOP_BSS_FAILURE;
+		goto end;
+	}
+
+	if (lim_set_link_state(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
+			       psessionEntry->selfMacAddr, NULL,
+			       NULL) != QDF_STATUS_SUCCESS) {
+		pe_err("IBSS: DEL_BSS_RSP setLinkState failed");
+		rc = eSIR_SME_REFUSED;
+		goto end;
+	}
+
+	lim_ibss_delete(pMac, psessionEntry);
+
+	dph_hash_table_class_init(pMac, &psessionEntry->dph.dphHashTable);
+	lim_delete_pre_auth_list(pMac);
+
+	psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+		       psessionEntry->limMlmState));
+
+	psessionEntry->limSystemRole = eLIM_STA_ROLE;
+
+	/* Change the short slot operating mode to Default (which is 1 for now) so that when IBSS starts next time with Libra
+	 * as originator, it picks up the default. This enables us to remove hard coding of short slot = 1 from lim_apply_configuration
+	 */
+	psessionEntry->shortSlotTimeSupported = WNI_CFG_SHORT_SLOT_TIME_STADEF;
+
+end:
+	if (pDelBss != NULL)
+		qdf_mem_free(pDelBss);
+	/* Delete PE session once BSS is deleted */
+	if (NULL != psessionEntry) {
+		lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP, rc,
+				 psessionEntry->smeSessionId,
+				 psessionEntry->transactionId);
+		pe_delete_session(pMac, psessionEntry);
+		psessionEntry = NULL;
+	}
+}
+
+/**
+ * lim_ibss_coalesce()
+ *
+ ***FUNCTION:
+ * This function is called upon receiving Beacon/Probe Response
+ * while operating in IBSS mode.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ * @param  pBeacon - Parsed Beacon Frame structure
+ * @param  pBD     - Pointer to received BD
+ *
+ * @return Status whether to process or ignore received Beacon Frame
+ */
+
+QDF_STATUS
+lim_ibss_coalesce(tpAniSirGlobal pMac,
+		  tpSirMacMgmtHdr pHdr,
+		  tpSchBeaconStruct pBeacon,
+		  uint8_t *pIEs,
+		  uint32_t ieLen, uint16_t fTsfLater, tpPESession psessionEntry)
+{
+	uint16_t peerIdx;
+	tSirMacAddr currentBssId;
+	tLimIbssPeerNode *pPeerNode;
+	tpDphHashNode pStaDs;
+	tUpdateBeaconParams beaconParams;
+
+	qdf_mem_set((uint8_t *) &beaconParams, sizeof(tUpdateBeaconParams), 0);
+
+	sir_copy_mac_addr(currentBssId, psessionEntry->bssId);
+
+	pe_debug("Current BSSID :" MAC_ADDRESS_STR " Received BSSID :"
+		   MAC_ADDRESS_STR, MAC_ADDR_ARRAY(currentBssId),
+		MAC_ADDR_ARRAY(pHdr->bssId));
+
+	/* Check for IBSS Coalescing only if Beacon is from different BSS */
+	if (qdf_mem_cmp(currentBssId, pHdr->bssId, sizeof(tSirMacAddr))
+	    && psessionEntry->isCoalesingInIBSSAllowed) {
+		/*
+		 * If STA entry is already available in the LIM hash table, then it is
+		 * possible that the peer may have left and rejoined within the heartbeat
+		 * timeout. In the offloaded case with 32 peers, the HB timeout is whopping
+		 * 128 seconds. In that case, the FW will not let any frames come in until
+		 * atleast the last sequence number is received before the peer is left
+		 * Hence, if the coalescing peer is already there in the peer list and if
+		 * the BSSID matches then, invoke delSta() to cleanup the entries. We will
+		 * let the peer coalesce when we receive next beacon from the peer
+		 */
+		pPeerNode = ibss_peer_find(pMac, pHdr->sa);
+		if (NULL != pPeerNode) {
+			lim_ibss_delete_peer(pMac, psessionEntry,
+							  pHdr->sa);
+			pe_warn("Peer attempting to reconnect before HB timeout, deleted");
+			return QDF_STATUS_E_INVAL;
+		}
+
+		if (!fTsfLater) { /* No Coalescing happened. */
+			pe_warn("No Coalescing happened");
+			return QDF_STATUS_E_INVAL;
+		}
+		/*
+		 * IBSS Coalescing happened.
+		 * save the received beacon, and delete the current BSS. The rest of the
+		 * processing will be done in the delBss response processing
+		 */
+		pMac->lim.gLimIbssCoalescingHappened = true;
+		ibss_coalesce_save(pMac, pHdr, pBeacon);
+		pe_debug("IBSS Coalescing happened Delete BSSID :" MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(currentBssId));
+#ifdef CONFIG_VDEV_SM
+		wlan_vdev_mlme_sm_deliver_evt(psessionEntry->vdev,
+					      WLAN_VDEV_SM_EV_DOWN,
+					      sizeof(*psessionEntry),
+					      psessionEntry);
+#else
+		ibss_bss_delete(pMac, psessionEntry);
+#endif
+		return QDF_STATUS_SUCCESS;
+	} else {
+		if (qdf_mem_cmp
+			    (currentBssId, pHdr->bssId, sizeof(tSirMacAddr)))
+			return QDF_STATUS_E_INVAL;
+	}
+
+	/* STA in IBSS mode and SSID matches with ours */
+	pPeerNode = ibss_peer_find(pMac, pHdr->sa);
+	if (pPeerNode == NULL) {
+		/* Peer not in the list - Collect BSS description & add to the list */
+		uint32_t frameLen;
+		QDF_STATUS retCode;
+
+		/*
+		 * Limit the Max number of IBSS Peers allowed as the max
+		 * number of STA's allowed
+		 * pMac->lim.gLimNumIbssPeers will be increamented after exiting
+		 * this function. so we will add additional 1 to compare against
+		 * pMac->lim.gLimIbssStaLimit
+		 */
+		if ((pMac->lim.gLimNumIbssPeers + 1) >=
+		    pMac->lim.gLimIbssStaLimit) {
+			/*Print every 100th time */
+			if (pMac->lim.ibss_retry_cnt % 100 == 0) {
+				pe_debug("**** MAX STA LIMIT HAS REACHED ****");
+			}
+			pMac->lim.ibss_retry_cnt++;
+			return QDF_STATUS_E_NOSPC;
+		}
+		pe_debug("IBSS Peer node does not exist, adding it");
+		frameLen =
+			sizeof(tLimIbssPeerNode) + ieLen - sizeof(uint32_t);
+
+		pPeerNode = qdf_mem_malloc((uint16_t) frameLen);
+		if (!pPeerNode)
+			return QDF_STATUS_E_NOMEM;
+
+		pPeerNode->beacon = NULL;
+		pPeerNode->beaconLen = 0;
+
+		ibss_peer_collect(pMac, pBeacon, pHdr, pPeerNode,
+				  psessionEntry);
+		pPeerNode->beacon = qdf_mem_malloc(ieLen);
+		if (pPeerNode->beacon) {
+			qdf_mem_copy(pPeerNode->beacon, pIEs, ieLen);
+			pPeerNode->beaconLen = (uint16_t) ieLen;
+		}
+		ibss_peer_add(pMac, pPeerNode);
+
+		pStaDs =
+			dph_lookup_hash_entry(pMac, pPeerNode->peerMacAddr, &peerIdx,
+					      &psessionEntry->dph.dphHashTable);
+		if (pStaDs != NULL) {
+			/* / DPH node already exists for the peer */
+			pe_warn("DPH Node present for just learned peer");
+			lim_print_mac_addr(pMac, pPeerNode->peerMacAddr, LOGD);
+			ibss_sta_info_update(pMac, pStaDs, pPeerNode,
+					     psessionEntry);
+			return QDF_STATUS_SUCCESS;
+		}
+		retCode =
+			lim_ibss_sta_add(pMac, pPeerNode->peerMacAddr, psessionEntry);
+		if (retCode != QDF_STATUS_SUCCESS) {
+			pe_err("lim-ibss-sta-add failed reason: %x", retCode);
+			lim_print_mac_addr(pMac, pPeerNode->peerMacAddr, LOGE);
+			return retCode;
+		}
+		/* Decide protection mode */
+		pStaDs =
+			dph_lookup_hash_entry(pMac, pPeerNode->peerMacAddr, &peerIdx,
+					      &psessionEntry->dph.dphHashTable);
+		if (pMac->lim.gLimProtectionControl !=
+		    MLME_FORCE_POLICY_PROTECTION_DISABLE)
+			lim_ibss_decide_protection(pMac, pStaDs, &beaconParams,
+						   psessionEntry);
+
+		if (beaconParams.paramChangeBitmap) {
+			pe_err("beaconParams.paramChangeBitmap=1 ---> Update Beacon Params");
+			sch_set_fixed_beacon_fields(pMac, psessionEntry);
+			beaconParams.bssIdx = psessionEntry->bssIdx;
+			lim_send_beacon_params(pMac, &beaconParams, psessionEntry);
+		}
+	} else
+		ibss_sta_caps_update(pMac, pPeerNode, psessionEntry);
+
+	if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE)
+		return QDF_STATUS_SUCCESS;
+
+	/* Received Beacon from same IBSS we're */
+	/* currently part of. Inform Roaming algorithm */
+	/* if not already that IBSS is active. */
+	if (psessionEntry->limIbssActive == false) {
+		limResetHBPktCount(psessionEntry);
+		pe_warn("Partner joined our IBSS, Sending IBSS_ACTIVE Notification to SME");
+		psessionEntry->limIbssActive = true;
+		lim_send_sme_wm_status_change_ntf(pMac, eSIR_SME_IBSS_ACTIVE, NULL, 0,
+						  psessionEntry->smeSessionId);
+	}
+
+	return QDF_STATUS_SUCCESS;
+} /*** end lim_handle_ibs_scoalescing() ***/
+
+/**
+ * lim_ibss_heart_beat_handle() - handle IBSS hearbeat failure
+ *
+ * @mac_ctx: global mac context
+ * @session: PE session entry
+ *
+ * Hanlde IBSS hearbeat failure.
+ *
+ * Return: None.
+ */
+void lim_ibss_heart_beat_handle(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+	tLimIbssPeerNode *tempnode, *prevnode;
+	tLimIbssPeerNode *temp_next = NULL;
+	uint16_t peer_idx = 0;
+	tpDphHashNode stads = 0;
+	uint32_t threshold = 0;
+	uint16_t sta_idx = 0;
+
+	/*
+	 * MLM BSS is started and if PE in scanmode then MLM state will be
+	 * waiting for probe resp. If Heart beat timeout triggers during this
+	 * corner case then we need to reactivate HeartBeat timer.
+	 */
+	if (session->limMlmState != eLIM_MLM_BSS_STARTED_STATE)
+		return;
+
+	/* If LinkMonitor is Disabled */
+	if (!mac_ctx->sys.gSysEnableLinkMonitorMode)
+		return;
+
+	prevnode = tempnode = mac_ctx->lim.gLimIbssPeerList;
+	threshold = (mac_ctx->lim.gLimNumIbssPeers / 4) + 1;
+
+	/* Monitor the HeartBeat with the Individual PEERS in the IBSS */
+	while (tempnode != NULL) {
+		temp_next = tempnode->next;
+		if (tempnode->beaconHBCount) {
+			/* There was a beacon for this peer during heart beat */
+			tempnode->beaconHBCount = 0;
+			tempnode->heartbeatFailure = 0;
+			prevnode = tempnode;
+			tempnode = temp_next;
+			continue;
+		}
+
+		/* There wasnt any beacon received during heartbeat timer. */
+		tempnode->heartbeatFailure++;
+		pe_err("Heartbeat fail: %d  thres: %d",
+		    tempnode->heartbeatFailure, mac_ctx->lim.gLimNumIbssPeers);
+		if (tempnode->heartbeatFailure >= threshold) {
+			/* Remove this entry from the list. */
+			stads = dph_lookup_hash_entry(mac_ctx,
+					tempnode->peerMacAddr, &peer_idx,
+					&session->dph.dphHashTable);
+			if (stads) {
+				sta_idx = stads->staIndex;
+
+				(void)lim_del_sta(mac_ctx, stads, false,
+						  session);
+				lim_delete_dph_hash_entry(mac_ctx,
+					stads->staAddr, peer_idx, session);
+				lim_release_peer_idx(mac_ctx, peer_idx,
+						     session);
+				/* Send indication. */
+				ibss_status_chg_notify(mac_ctx,
+					tempnode->peerMacAddr, sta_idx,
+					eWNI_SME_IBSS_PEER_DEPARTED_IND,
+					session->smeSessionId);
+			}
+			if (tempnode == mac_ctx->lim.gLimIbssPeerList) {
+				mac_ctx->lim.gLimIbssPeerList = tempnode->next;
+				prevnode = mac_ctx->lim.gLimIbssPeerList;
+			} else {
+				prevnode->next = tempnode->next;
+			}
+
+			if (tempnode->beacon)
+				qdf_mem_free(tempnode->beacon);
+			qdf_mem_free(tempnode);
+			mac_ctx->lim.gLimNumIbssPeers--;
+
+			/* we deleted current node, so prevNode remains same. */
+			tempnode = temp_next;
+			continue;
+		}
+		prevnode = tempnode;
+		tempnode = temp_next;
+	}
+
+	/*
+	 * General IBSS Activity Monitor,
+	 * check if in IBSS Mode we are received any Beacons
+	 */
+	if (mac_ctx->lim.gLimNumIbssPeers) {
+		if (session->LimRxedBeaconCntDuringHB <
+		    MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL)
+			mac_ctx->lim.gLimHeartBeatBeaconStats[
+				session->LimRxedBeaconCntDuringHB]++;
+		else
+			mac_ctx->lim.gLimHeartBeatBeaconStats[0]++;
+
+		/* Reset number of beacons received */
+		limResetHBPktCount(session);
+		return;
+	} else {
+		pe_warn("Heartbeat Failure");
+		mac_ctx->lim.gLimHBfailureCntInLinkEstState++;
+
+		if (session->limIbssActive == true) {
+			/*
+			 * We don't receive Beacon frames from any
+			 * other STA in IBSS. Announce IBSS inactive
+			 * to Roaming algorithm
+			 */
+			pe_warn("Alone in IBSS");
+			session->limIbssActive = false;
+
+			lim_send_sme_wm_status_change_ntf(mac_ctx,
+				eSIR_SME_IBSS_INACTIVE, NULL, 0,
+				session->smeSessionId);
+		}
+	}
+}
+
+/**
+ * lim_ibss_decide_protection_on_delete() - decides protection related info.
+ *
+ * @mac_ctx: global mac context
+ * @stads: station hash node
+ * @bcn_param: beacon parameters
+ * @session: PE session entry
+ *
+ * Decides all the protection related information.
+ *
+ * Return: None
+ */
+void lim_ibss_decide_protection_on_delete(tpAniSirGlobal mac_ctx,
+					  tpDphHashNode stads,
+					  tpUpdateBeaconParams bcn_param,
+					  tpPESession session)
+{
+	uint32_t phymode;
+	tHalBitVal erpenabled = eHAL_CLEAR;
+	enum band_info rfband = BAND_UNKNOWN;
+	uint32_t i;
+
+	if (NULL == stads)
+		return;
+
+	lim_get_rf_band_new(mac_ctx, &rfband, session);
+	if (BAND_2G != rfband)
+		return;
+
+	lim_get_phy_mode(mac_ctx, &phymode, session);
+	erpenabled = stads->erpEnabled;
+	/* we are HT or 11G and 11B station is getting deleted. */
+	if (((phymode == WNI_CFG_PHY_MODE_11G) ||
+	     session->htCapability) && (erpenabled == eHAL_CLEAR)) {
+		pe_err("%d A legacy STA is disassociated Addr is",
+			session->gLim11bParams.numSta);
+			lim_print_mac_addr(mac_ctx, stads->staAddr, LOGE);
+		if (session->gLim11bParams.numSta == 0) {
+			pe_err("No 11B STA exists. Disable protection");
+			lim_ibss_set_protection(mac_ctx, false,
+				bcn_param, session);
+		}
+
+		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+			if (!mac_ctx->lim.protStaCache[i].active)
+				continue;
+			if (!qdf_mem_cmp(mac_ctx->lim.protStaCache[i].addr,
+				stads->staAddr, sizeof(tSirMacAddr))) {
+				session->gLim11bParams.numSta--;
+				mac_ctx->lim.protStaCache[i].active = false;
+				break;
+			}
+		}
+
+	}
+}
+
+/** -----------------------------------------------------------------
+   \fn __lim_ibss_peer_inactivity_handler
+   \brief Internal function. Deletes FW indicated peer which is inactive
+ \
+   \param  tpAniSirGlobal    pMac
+   \param  tpPESession       psessionEntry
+   \param  tpSirIbssPeerInactivityInd peerInactivityInd
+   \return None
+   -----------------------------------------------------------------*/
+static void
+__lim_ibss_peer_inactivity_handler(tpAniSirGlobal pMac,
+				   tpPESession psessionEntry,
+				   tpSirIbssPeerInactivityInd peerInactivityInd)
+{
+	if (psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) {
+		return;
+	}
+
+	/* delete the peer for which heartbeat is observed */
+	lim_ibss_delete_peer(pMac, psessionEntry,
+					  peerInactivityInd->peer_addr.bytes);
+}
+
+/** -------------------------------------------------------------
+   \fn lim_process_ibss_peer_inactivity
+   \brief Peer inactivity message handler
+ \
+   \param  tpAniSirGlobal    pMac
+   \param  void*             buf
+   \return None
+   -------------------------------------------------------------*/
+void lim_process_ibss_peer_inactivity(tpAniSirGlobal pMac, void *buf)
+{
+	/*
+	 * --------------- HEARTBEAT OFFLOAD CASE ------------------
+	 * This message handler is executed when the firmware identifies
+	 * inactivity from one or more peer devices. We will come here
+	 * for every inactive peer device
+	 */
+	uint8_t i;
+
+	tSirIbssPeerInactivityInd *peerInactivityInd =
+		(tSirIbssPeerInactivityInd *) buf;
+
+	/*
+	 * If IBSS is not started or heartbeat offload is not enabled
+	 * we should not handle this request
+	 */
+	if (eLIM_STA_IN_IBSS_ROLE != pMac->lim.gLimSystemRole &&
+	    !IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE) {
+		return;
+	}
+
+	/** If LinkMonitor is Disabled */
+	if (!pMac->sys.gSysEnableLinkMonitorMode) {
+		return;
+	}
+
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		if (true == pMac->lim.gpSession[i].valid &&
+		    eSIR_IBSS_MODE == pMac->lim.gpSession[i].bssType) {
+			__lim_ibss_peer_inactivity_handler(pMac,
+							   &pMac->lim.gpSession[i],
+							   peerInactivityInd);
+			break;
+		}
+	}
+}
diff --git a/core/mac/src/pe/lim/lim_ibss_peer_mgmt.h b/core/mac/src/pe/lim/lim_ibss_peer_mgmt.h
new file mode 100644
index 0000000..44eb4c2
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ibss_peer_mgmt.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2018 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.
+ */
+
+/*
+ *
+ * This file lim_ibss_peer_mgmt.h contains prototypes for
+ * the utility functions LIM uses to maintain peers in IBSS.
+ * Author:        Chandra Modumudi
+ * Date:          03/12/04
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "sir_common.h"
+#include "lim_utils.h"
+
+/**
+ * ibss_bss_delete()- start the ibss
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session: pe session
+ *
+ * Return: None
+ */
+void ibss_bss_add(tpAniSirGlobal mac_ctx, tpPESession session);
+
+/**
+ * ibss_bss_delete()- delete the current BSS
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session: pe session
+ *
+ * Return: None
+ */
+void ibss_bss_delete(tpAniSirGlobal mac_ctx, tpPESession session);
+
+/**
+ * lim_ibss_delete_all_peers: delete all IBSS peers.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session: pe session
+ *
+ * Return: None
+ */
+void lim_ibss_delete_all_peers(tpAniSirGlobal mac_ctx, tpPESession session);
+
+void lim_ibss_init(tpAniSirGlobal);
+void lim_ibss_delete(tpAniSirGlobal, tpPESession psessionEntry);
+QDF_STATUS lim_ibss_coalesce(tpAniSirGlobal, tpSirMacMgmtHdr,
+				tpSchBeaconStruct, uint8_t *, uint32_t, uint16_t,
+				tpPESession);
+QDF_STATUS lim_ibss_sta_add(tpAniSirGlobal, void *, tpPESession);
+QDF_STATUS lim_ibss_add_sta_rsp(tpAniSirGlobal, void *, tpPESession);
+
+/**
+ * lim_process_ibss_del_sta_rsp()- Handle ibss delete
+ * peer resp from firmware
+ *
+ * @mac_ptr: Pointer to Global MAC structure
+ * @lim_msg: delete sta response
+ * @pe_session: pe session
+ *
+ * Return: None
+ *
+ */
+void lim_process_ibss_del_sta_rsp(tpAniSirGlobal mac_ctx,
+	struct scheduler_msg *lim_msg,
+	tpPESession pe_session);
+tLimIbssPeerNode *lim_ibss_peer_find(tpAniSirGlobal pMac, tSirMacAddr macAddr);
+void lim_ibss_del_bss_rsp(tpAniSirGlobal, void *, tpPESession);
+void lim_ibss_del_bss_rsp_when_coalescing(tpAniSirGlobal, void *, tpPESession);
+void lim_ibss_add_bss_rsp_when_coalescing(tpAniSirGlobal pMac, void *msg,
+					  tpPESession pSessionEntry);
+void lim_ibss_decide_protection_on_delete(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+					  tpUpdateBeaconParams pBeaconParams,
+					  tpPESession pSessionEntry);
+void lim_ibss_heart_beat_handle(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void lim_process_ibss_peer_inactivity(tpAniSirGlobal pMac, void *buf);
diff --git a/core/mac/src/pe/lim/lim_link_monitoring_algo.c b/core/mac/src/pe/lim/lim_link_monitoring_algo.c
new file mode 100644
index 0000000..cbe1efc
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_link_monitoring_algo.c
@@ -0,0 +1,599 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file lim_link_monitoring_algo.cc contains the code for
+ * Link monitoring algorithm on AP and heart beat failure
+ * handling on STA.
+ * Author:        Chandra Modumudi
+ * Date:          03/01/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "ani_global.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_assoc_utils.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_prop_exts_utils.h"
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+#include "host_diag_core_log.h"
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "lim_ser_des_utils.h"
+
+/**
+ * lim_delete_sta_util - utility function for deleting station context
+ *
+ * @mac_ctx: global MAC context
+ * @msg: pointer to delte station context
+ * @session_entry: PE session entry
+ *
+ * utility function called to clear up station context.
+ *
+ * Return: None.
+ */
+static void lim_delete_sta_util(tpAniSirGlobal mac_ctx, tpDeleteStaContext msg,
+				tpPESession session_entry)
+{
+	tpDphHashNode stads;
+
+	pe_debug("Deleting station: staId: %d, reasonCode: %d",
+		msg->staId, msg->reasonCode);
+
+	if (LIM_IS_IBSS_ROLE(session_entry)) {
+		return;
+	}
+
+	stads = dph_lookup_assoc_id(mac_ctx, msg->staId, &msg->assocId,
+				    &session_entry->dph.dphHashTable);
+
+	if (!stads) {
+		pe_err("Invalid STA limSystemRole: %d",
+			GET_LIM_SYSTEM_ROLE(session_entry));
+		return;
+	}
+	stads->del_sta_ctx_rssi = msg->rssi;
+
+	/* check and see if same staId. This is to avoid the scenario
+	 * where we're trying to delete a staId we just added.
+	 */
+	if (stads->staIndex != msg->staId) {
+		pe_err("staid mismatch: %d vs %d", stads->staIndex, msg->staId);
+		return;
+	}
+
+	if (LIM_IS_AP_ROLE(session_entry)) {
+		pe_debug("Delete Station staId: %d, assocId: %d",
+			msg->staId, msg->assocId);
+		/*
+		 * Check if Deauth/Disassoc is triggered from Host.
+		 * If mlmState is in some transient state then
+		 * don't trigger STA deletion to avoid the race
+		 * condition.
+		 */
+		if ((stads &&
+		     ((stads->mlmStaContext.mlmState !=
+			eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+		      (stads->mlmStaContext.mlmState !=
+			eLIM_MLM_WT_ASSOC_CNF_STATE) &&
+		      (stads->mlmStaContext.mlmState !=
+			eLIM_MLM_ASSOCIATED_STATE)))) {
+			pe_err("Inv Del STA staId: %d, assocId: %d",
+				msg->staId, msg->assocId);
+			return;
+		} else {
+			lim_send_disassoc_mgmt_frame(mac_ctx,
+				eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON,
+				stads->staAddr, session_entry, false);
+			lim_trigger_sta_deletion(mac_ctx, stads, session_entry);
+		}
+	} else {
+#ifdef FEATURE_WLAN_TDLS
+		if (LIM_IS_STA_ROLE(session_entry) &&
+		    STA_ENTRY_TDLS_PEER == stads->staType) {
+			/*
+			 * TeardownLink with PEER reason code
+			 * HAL_DEL_STA_REASON_CODE_KEEP_ALIVE means
+			 * eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE
+			 */
+			lim_send_sme_tdls_del_sta_ind(mac_ctx, stads,
+			    session_entry,
+			    eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE);
+		} else {
+#endif
+		/* TearDownLink with AP */
+		tLimMlmDeauthInd mlm_deauth_ind;
+
+		pe_debug("Delete Station (staId: %d, assocId: %d)",
+			msg->staId, msg->assocId);
+
+		if ((stads &&
+			((stads->mlmStaContext.mlmState !=
+					eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+			(stads->mlmStaContext.mlmState !=
+					eLIM_MLM_WT_ASSOC_CNF_STATE) &&
+			(stads->mlmStaContext.mlmState !=
+					eLIM_MLM_ASSOCIATED_STATE)))) {
+
+			/*
+			 * Received SIR_LIM_DELETE_STA_CONTEXT_IND for STA that
+			 * does not have context or in some transit state.
+			 * Log error
+			 */
+			pe_debug("Received SIR_LIM_DELETE_STA_CONTEXT_IND for "
+					"STA that either has no context or "
+					"in some transit state, Addr = "
+					MAC_ADDRESS_STR,
+					MAC_ADDR_ARRAY(msg->bssId));
+			return;
+		}
+
+		stads->mlmStaContext.disassocReason =
+			eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
+		stads->mlmStaContext.cleanupTrigger =
+			eLIM_LINK_MONITORING_DEAUTH;
+
+		/* Issue Deauth Indication to SME. */
+		qdf_mem_copy((uint8_t *) &mlm_deauth_ind.peerMacAddr,
+			     stads->staAddr, sizeof(tSirMacAddr));
+		mlm_deauth_ind.reasonCode =
+			(uint8_t) stads->mlmStaContext.disassocReason;
+		mlm_deauth_ind.deauthTrigger =
+			stads->mlmStaContext.cleanupTrigger;
+
+#ifdef FEATURE_WLAN_TDLS
+		/* Delete all TDLS peers connected before leaving BSS */
+		lim_delete_tdls_peers(mac_ctx, session_entry);
+#endif
+		if (LIM_IS_STA_ROLE(session_entry))
+			lim_post_sme_message(mac_ctx, LIM_MLM_DEAUTH_IND,
+				     (uint32_t *) &mlm_deauth_ind);
+
+		lim_send_sme_deauth_ind(mac_ctx, stads,	session_entry);
+#ifdef FEATURE_WLAN_TDLS
+	}
+#endif
+	}
+}
+
+/**
+ * lim_delete_sta_context() - delete sta context.
+ *
+ * @mac_ctx: global mac_ctx context
+ * @lim_msg: lim message.
+ *
+ * This function handles the message from HAL: WMA_DELETE_STA_CONTEXT_IND.
+ * This function validates that the given station id exist, and if so,
+ * deletes the station by calling lim_trigger_sta_deletion.
+ *
+ * Return: none
+ */
+void lim_delete_sta_context(tpAniSirGlobal mac_ctx,
+			    struct scheduler_msg *lim_msg)
+{
+	tpDeleteStaContext msg = (tpDeleteStaContext) lim_msg->bodyptr;
+	tpPESession session_entry;
+	tpDphHashNode sta_ds;
+
+	if (NULL == msg) {
+		pe_err("Invalid body pointer in message");
+		return;
+	}
+	session_entry = pe_find_session_by_sme_session_id(mac_ctx, msg->vdev_id);
+	if (NULL == session_entry) {
+		pe_err("session not found for given sme session");
+		qdf_mem_free(msg);
+		return;
+	}
+
+	switch (msg->reasonCode) {
+	case HAL_DEL_STA_REASON_CODE_KEEP_ALIVE:
+		if (LIM_IS_STA_ROLE(session_entry) && !msg->is_tdls) {
+			if (!((session_entry->limMlmState ==
+			    eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+			    (session_entry->limSmeState !=
+			    eLIM_SME_WT_DISASSOC_STATE) &&
+			    (session_entry->limSmeState !=
+			    eLIM_SME_WT_DEAUTH_STATE))) {
+				pe_err("Do not process in limMlmState %s(%x) limSmeState %s(%x)",
+				  lim_mlm_state_str(session_entry->limMlmState),
+				  session_entry->limMlmState,
+				  lim_sme_state_str(session_entry->limSmeState),
+				  session_entry->limSmeState);
+				qdf_mem_free(msg);
+				return;
+			}
+			sta_ds = dph_get_hash_entry(mac_ctx,
+					DPH_STA_HASH_INDEX_PEER,
+					&session_entry->dph.dphHashTable);
+			if (NULL == sta_ds) {
+				pe_err("Dph entry not found");
+				qdf_mem_free(msg);
+				return;
+			}
+			lim_send_deauth_mgmt_frame(mac_ctx,
+				eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON,
+				msg->addr2, session_entry, false);
+			lim_tear_down_link_with_ap(mac_ctx,
+				session_entry->peSessionId,
+				eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON);
+			/* only break for STA role (non TDLS) */
+			break;
+		}
+		lim_delete_sta_util(mac_ctx, msg, session_entry);
+		break;
+
+	case HAL_DEL_STA_REASON_CODE_UNKNOWN_A2:
+		pe_err("Deleting Unknown station");
+		lim_print_mac_addr(mac_ctx, msg->addr2, LOGE);
+		lim_send_deauth_mgmt_frame(mac_ctx,
+			eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON,
+			msg->addr2, session_entry, false);
+		break;
+
+	case HAL_DEL_STA_REASON_CODE_BTM_DISASSOC_IMMINENT:
+		if (session_entry->limMlmState !=
+		    eLIM_MLM_LINK_ESTABLISHED_STATE) {
+			pe_err("BTM request received in state %s",
+				lim_mlm_state_str(session_entry->limMlmState));
+			qdf_mem_free(msg);
+			lim_msg->bodyptr = NULL;
+			return;
+		}
+		lim_send_deauth_mgmt_frame(mac_ctx,
+				eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON,
+				session_entry->bssId, session_entry, false);
+		lim_tear_down_link_with_ap(mac_ctx, session_entry->peSessionId,
+					   eSIR_MAC_UNSPEC_FAILURE_REASON);
+		break;
+
+	default:
+		pe_err("Unknown reason code");
+		break;
+	}
+	qdf_mem_free(msg);
+	lim_msg->bodyptr = NULL;
+	return;
+}
+
+/**
+ * lim_trigger_sta_deletion() -
+ *          This function is called to trigger STA context deletion.
+ *
+ * @param  mac_ctx   - Pointer to global MAC structure
+ * @param  sta_ds - Pointer to internal STA Datastructure
+ * @session_entry: PE session entry
+
+ * @return None
+ */
+void
+lim_trigger_sta_deletion(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+			 tpPESession session_entry)
+{
+	tLimMlmDisassocInd mlm_disassoc_ind;
+
+	if (!sta_ds) {
+		pe_warn("Skip STA deletion (invalid STA)");
+		return;
+	}
+
+	if ((sta_ds->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
+		(sta_ds->mlmStaContext.mlmState ==
+			eLIM_MLM_WT_DEL_BSS_RSP_STATE) ||
+		sta_ds->sta_deletion_in_progress) {
+		/* Already in the process of deleting context for the peer */
+		pe_debug("Deletion is in progress (%d) for peer:%pK in mlmState %d",
+			sta_ds->sta_deletion_in_progress, sta_ds->staAddr,
+			sta_ds->mlmStaContext.mlmState);
+		return;
+	}
+	sta_ds->sta_deletion_in_progress = true;
+
+	sta_ds->mlmStaContext.disassocReason =
+		eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
+	sta_ds->mlmStaContext.cleanupTrigger = eLIM_LINK_MONITORING_DISASSOC;
+	qdf_mem_copy(&mlm_disassoc_ind.peerMacAddr, sta_ds->staAddr,
+		sizeof(tSirMacAddr));
+	mlm_disassoc_ind.reasonCode =
+		eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
+	mlm_disassoc_ind.disassocTrigger = eLIM_LINK_MONITORING_DISASSOC;
+
+	/* Update PE session Id */
+	mlm_disassoc_ind.sessionId = session_entry->peSessionId;
+	lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_IND,
+			(uint32_t *) &mlm_disassoc_ind);
+	if (mac_ctx->mlme_cfg->gen.fatal_event_trigger)
+		cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+				WLAN_LOG_INDICATOR_HOST_DRIVER,
+				WLAN_LOG_REASON_HB_FAILURE,
+				false, false);
+	/* Issue Disassoc Indication to SME */
+	lim_send_sme_disassoc_ind(mac_ctx, sta_ds, session_entry);
+} /*** end lim_trigger_st_adeletion() ***/
+
+/**
+ * lim_tear_down_link_with_ap()
+ *
+ ***FUNCTION:
+ * This function is called when heartbeat (beacon reception)
+ * fails on STA
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+lim_tear_down_link_with_ap(tpAniSirGlobal pMac, uint8_t sessionId,
+			   tSirMacReasonCodes reasonCode)
+{
+	tpDphHashNode pStaDs = NULL;
+
+	/* tear down the following sessionEntry */
+	tpPESession psessionEntry;
+
+	psessionEntry = pe_find_session_by_session_id(pMac, sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+	/**
+	 * Heart beat failed for upto threshold value
+	 * and AP did not respond for Probe request.
+	 * Trigger link tear down.
+	 */
+	psessionEntry->pmmOffloadInfo.bcnmiss = false;
+
+	pe_info("No ProbeRsp from AP after HB failure. Tearing down link");
+
+	/* Announce loss of link to Roaming algorithm */
+	/* and cleanup by sending SME_DISASSOC_REQ to SME */
+
+	pStaDs =
+		dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+				   &psessionEntry->dph.dphHashTable);
+
+	if (pStaDs != NULL) {
+		tLimMlmDeauthInd mlmDeauthInd;
+
+#ifdef FEATURE_WLAN_TDLS
+		/* Delete all TDLS peers connected before leaving BSS */
+		lim_delete_tdls_peers(pMac, psessionEntry);
+#endif
+
+		pStaDs->mlmStaContext.disassocReason = reasonCode;
+		pStaDs->mlmStaContext.cleanupTrigger =
+			eLIM_LINK_MONITORING_DEAUTH;
+		/* / Issue Deauth Indication to SME. */
+		qdf_mem_copy((uint8_t *) &mlmDeauthInd.peerMacAddr,
+			     pStaDs->staAddr, sizeof(tSirMacAddr));
+
+	/*
+	* if deauth_before_connection is enabled and reasoncode is
+	* Beacon Missed Store the MAC of AP in the flip flop
+	* buffer. This MAC will be used to send Deauth before
+	* connection, if we connect to same AP after HB failure.
+	*/
+	if (pMac->mlme_cfg->sta.deauth_before_connection &&
+	    eSIR_BEACON_MISSED == reasonCode) {
+		int apCount = pMac->lim.gLimHeartBeatApMacIndex;
+
+		if (pMac->lim.gLimHeartBeatApMacIndex)
+			pMac->lim.gLimHeartBeatApMacIndex = 0;
+		else
+			pMac->lim.gLimHeartBeatApMacIndex = 1;
+
+		pe_debug("HB Failure on MAC "
+			MAC_ADDRESS_STR" Store it on Index %d",
+			MAC_ADDR_ARRAY(pStaDs->staAddr), apCount);
+
+		sir_copy_mac_addr(pMac->lim.gLimHeartBeatApMac[apCount],
+							pStaDs->staAddr);
+	}
+
+		mlmDeauthInd.reasonCode =
+			(uint8_t) pStaDs->mlmStaContext.disassocReason;
+		mlmDeauthInd.deauthTrigger =
+			pStaDs->mlmStaContext.cleanupTrigger;
+
+		if (LIM_IS_STA_ROLE(psessionEntry))
+			lim_post_sme_message(pMac, LIM_MLM_DEAUTH_IND,
+				     (uint32_t *) &mlmDeauthInd);
+		if (pMac->mlme_cfg->gen.fatal_event_trigger)
+			cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+					WLAN_LOG_INDICATOR_HOST_DRIVER,
+					WLAN_LOG_REASON_HB_FAILURE,
+					false, false);
+
+		lim_send_sme_deauth_ind(pMac, pStaDs, psessionEntry);
+	}
+} /*** lim_tear_down_link_with_ap() ***/
+
+/**
+ * lim_handle_heart_beat_failure() - handle hear beat failure in STA
+ *
+ * @mac_ctx: global MAC context
+ * @session: PE session entry
+ *
+ * This function is called when heartbeat (beacon reception)
+ * fails on STA
+ *
+ * Return: None
+ */
+
+void lim_handle_heart_beat_failure(tpAniSirGlobal mac_ctx,
+				   tpPESession session)
+{
+	uint8_t curr_chan;
+	tpSirAddie scan_ie = NULL;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	host_log_beacon_update_pkt_type *log_ptr = NULL;
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_beacon_update_pkt_type,
+				 LOG_WLAN_BEACON_UPDATE_C);
+	if (log_ptr)
+		log_ptr->bcn_rx_cnt = session->LimRxedBeaconCntDuringHB;
+	WLAN_HOST_DIAG_LOG_REPORT(log_ptr);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	/* Ensure HB Status for the session has been reseted */
+	session->LimHBFailureStatus = false;
+
+	if (LIM_IS_STA_ROLE(session) &&
+	    (session->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+	    (session->limSmeState != eLIM_SME_WT_DISASSOC_STATE) &&
+	    (session->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) {
+		if (!mac_ctx->sys.gSysEnableLinkMonitorMode) {
+			goto hb_handler_fail;
+		}
+
+		/* Ignore HB if channel switch is in progress */
+		if (session->gLimSpecMgmt.dot11hChanSwState ==
+		   eLIM_11H_CHANSW_RUNNING) {
+			pe_debug("Ignore Heartbeat failure as Channel switch is in progress");
+			session->pmmOffloadInfo.bcnmiss = false;
+			goto hb_handler_fail;
+		}
+		/* Beacon frame not received within heartbeat timeout. */
+		pe_warn("Heartbeat Failure");
+		mac_ctx->lim.gLimHBfailureCntInLinkEstState++;
+
+		/*
+		 * Check if connected on the DFS channel, if not connected on
+		 * DFS channel then only send the probe request otherwise tear
+		 * down the link
+		 */
+		curr_chan = session->currentOperChannel;
+		if (!lim_isconnected_on_dfs_channel(mac_ctx, curr_chan)) {
+			/* Detected continuous Beacon Misses */
+			session->LimHBFailureStatus = true;
+
+			/*Reset the HB packet count before sending probe*/
+			limResetHBPktCount(session);
+			/**
+			 * Send Probe Request frame to AP to see if
+			 * it is still around. Wait until certain
+			 * timeout for Probe Response from AP.
+			 */
+			pe_debug("HB missed from AP. Sending Probe Req");
+			/* for searching AP, we don't include any more IE */
+			if (session->pLimJoinReq != NULL) {
+				scan_ie = &session->pLimJoinReq->addIEScan;
+				lim_send_probe_req_mgmt_frame(mac_ctx,
+					&session->ssId,
+					session->bssId, curr_chan,
+					session->selfMacAddr,
+					session->dot11mode,
+					&scan_ie->length, scan_ie->addIEdata);
+			} else {
+				lim_send_probe_req_mgmt_frame(mac_ctx,
+					&session->ssId,
+					session->bssId, curr_chan,
+					session->selfMacAddr,
+					session->dot11mode, NULL, NULL);
+			}
+		} else {
+			pe_debug("HB missed from AP on DFS chanel moving to passive");
+			if (curr_chan < SIR_MAX_24G_5G_CHANNEL_RANGE) {
+				lim_covert_channel_scan_type(mac_ctx, curr_chan,
+					false);
+				mac_ctx->lim.dfschannelList.
+					timeStamp[curr_chan] = 0;
+			}
+			/*
+			 * Connected on DFS channel so should not send the
+			 * probe request tear down the link directly
+			 */
+			lim_tear_down_link_with_ap(mac_ctx,
+				session->peSessionId,
+				eSIR_BEACON_MISSED);
+		}
+	} else {
+		/**
+		 * Heartbeat timer may have timed out
+		 * while we're doing background scanning/learning
+		 * or in states other than link-established state.
+		 * Log error.
+		 */
+		pe_debug("received heartbeat timeout in state %X",
+			session->limMlmState);
+		lim_print_mlm_state(mac_ctx, LOG1, session->limMlmState);
+		mac_ctx->lim.gLimHBfailureCntInOtherStates++;
+	}
+
+hb_handler_fail:
+	if (mac_ctx->sme.tx_queue_cb)
+		mac_ctx->sme.tx_queue_cb(mac_ctx->hdd_handle,
+					 session->smeSessionId,
+					 WLAN_WAKE_ALL_NETIF_QUEUE,
+					 WLAN_CONTROL_PATH);
+}
+
+void lim_rx_invalid_peer_process(tpAniSirGlobal mac_ctx,
+				 struct scheduler_msg *lim_msg)
+{
+	struct ol_rx_inv_peer_params *msg =
+			(struct ol_rx_inv_peer_params *)lim_msg->bodyptr;
+	tpPESession session_entry;
+	uint16_t reason_code =
+		eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON;
+
+	if (NULL == msg) {
+		pe_err("Invalid body pointer in message");
+		return;
+	}
+
+	session_entry = pe_find_session_by_sme_session_id(mac_ctx,
+							  msg->vdev_id);
+	if (NULL == session_entry) {
+		pe_err_rl("session not found for given sme session");
+		qdf_mem_free(msg);
+		return;
+	}
+
+	/* only if SAP mode */
+	if (session_entry->operMode == BSS_OPERATIONAL_MODE_AP) {
+		pe_debug("send deauth frame to non-assoc STA");
+		lim_send_deauth_mgmt_frame(mac_ctx,
+					   reason_code,
+					   msg->ta,
+					   session_entry,
+					   false);
+	}
+
+	qdf_mem_free(msg);
+	lim_msg->bodyptr = NULL;
+}
diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c
new file mode 100644
index 0000000..4291203
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_action_frame.c
@@ -0,0 +1,2306 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file lim_process_action_frame.cc contains the code
+ * for processing Action Frame.
+ * Author:      Michael Lui
+ * Date:        05/23/03
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "wni_api.h"
+#include "sir_api.h"
+#include "ani_global.h"
+#include "wni_cfg.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "parser_api.h"
+#include "lim_admit_control.h"
+#include "wmm_apsd.h"
+#include "lim_send_messages.h"
+#include "rrm_api.h"
+#include "lim_session_utils.h"
+#include "wlan_policy_mgr_api.h"
+#include "wma_types.h"
+#include "wma.h"
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_peer_ops.h>
+#include "dot11f.h"
+
+#define BA_DEFAULT_TX_BUFFER_SIZE 64
+
+static last_processed_msg rrm_link_action_frm;
+
+/* Note: The test passes if the STAUT stops sending any frames, and no further
+   frames are transmitted on this channel by the station when the AP has sent
+   the last 6 beacons, with the channel switch information elements as seen
+   with the sniffer.*/
+#define SIR_CHANSW_TX_STOP_MAX_COUNT 6
+/**-----------------------------------------------------------------
+   \fn     lim_stop_tx_and_switch_channel
+   \brief  Stops the transmission if channel switch mode is silent and
+   starts the channel switch timer.
+
+   \param  pMac
+   \return NONE
+   -----------------------------------------------------------------*/
+void lim_stop_tx_and_switch_channel(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	tpPESession psessionEntry;
+
+	psessionEntry = pe_find_session_by_session_id(pMac, sessionId);
+
+	if (NULL == psessionEntry) {
+		pe_err("Session: %d not active", sessionId);
+		return;
+	}
+
+	if (psessionEntry->ftPEContext.pFTPreAuthReq) {
+		pe_debug("Avoid Switch Channel req during pre auth");
+		return;
+	}
+
+	pe_debug("Channel switch Mode: %d",
+		       psessionEntry->gLimChannelSwitch.switchMode);
+
+	if (psessionEntry->gLimChannelSwitch.switchMode ==
+	    eSIR_CHANSW_MODE_SILENT
+	    || psessionEntry->gLimChannelSwitch.switchCount <=
+	    SIR_CHANSW_TX_STOP_MAX_COUNT) {
+		/* Freeze the transmission */
+		lim_frame_transmission_control(pMac, eLIM_TX_ALL, eLIM_STOP_TX);
+
+	} else {
+		/* Resume the transmission */
+		lim_frame_transmission_control(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+	}
+
+	pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId = sessionId;
+	/* change the channel immediately only if
+	 * the channel switch count is 0
+	 */
+	if (psessionEntry->gLimChannelSwitch.switchCount == 0) {
+		lim_process_channel_switch_timeout(pMac);
+		return;
+	}
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_TIMER_ACTIVATE, sessionId,
+		       eLIM_CHANNEL_SWITCH_TIMER));
+
+	if (tx_timer_activate(&pMac->lim.limTimers.gLimChannelSwitchTimer) !=
+	    TX_SUCCESS) {
+		pe_err("tx_timer_activate failed");
+	}
+	return;
+}
+
+/**------------------------------------------------------------
+   \fn     lim_start_channel_switch
+   \brief  Switches the channel if switch count == 0, otherwise
+   starts the timer for channel switch and stops BG scan
+   and heartbeat timer tempororily.
+
+   \param  pMac
+   \param  psessionEntry
+   \return NONE
+   ------------------------------------------------------------*/
+QDF_STATUS lim_start_channel_switch(tpAniSirGlobal pMac,
+				       tpPESession psessionEntry)
+{
+	pe_debug("Starting the channel switch");
+
+	/*If channel switch is already running and it is on a different session, just return */
+	/*This need to be removed for MCC */
+	if ((lim_is_chan_switch_running(pMac) &&
+	     psessionEntry->gLimSpecMgmt.dot11hChanSwState !=
+	     eLIM_11H_CHANSW_RUNNING) || psessionEntry->csaOffloadEnable) {
+		pe_warn("Ignoring channel switch on session: %d",
+			psessionEntry->peSessionId);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* Deactivate and change reconfigure the timeout value */
+	/* lim_deactivate_and_change_timer(pMac, eLIM_CHANNEL_SWITCH_TIMER); */
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId,
+		       eLIM_CHANNEL_SWITCH_TIMER));
+	if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) !=
+	    QDF_STATUS_SUCCESS) {
+		pe_err("tx_timer_deactivate failed!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (tx_timer_change(&pMac->lim.limTimers.gLimChannelSwitchTimer,
+			    psessionEntry->gLimChannelSwitch.switchTimeoutValue,
+			    0) != TX_SUCCESS) {
+		pe_err("tx_timer_change failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Follow the channel switch, forget about the previous quiet. */
+	/* If quiet is running, chance is there to resume tx on its timeout. */
+	/* so stop timer for a safer side. */
+	if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) {
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+			       psessionEntry->peSessionId, eLIM_QUIET_TIMER));
+		if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) !=
+		    TX_SUCCESS) {
+			pe_err("tx_timer_deactivate failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) {
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+			       psessionEntry->peSessionId, eLIM_QUIET_BSS_TIMER));
+		if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer)
+		    != TX_SUCCESS) {
+			pe_err("tx_timer_deactivate failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+
+	/* Prepare for 11h channel switch */
+	lim_prepare_for11h_channel_switch(pMac, psessionEntry);
+
+	/** Dont add any more statements here as we posted finish scan request
+	 * to HAL, wait till we get the response
+	 */
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ *  __lim_process_channel_switch_action_frame() - to process channel switch
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_pkt_info: A pointer to packet info structure
+ *
+ * This routine will be called to process channel switch action frame
+ *
+ * Return: None
+ */
+
+static void __lim_process_channel_switch_action_frame(tpAniSirGlobal mac_ctx,
+			  uint8_t *rx_pkt_info, tpPESession session)
+{
+	tpSirMacMgmtHdr mac_hdr;
+	uint8_t *body_ptr;
+	tDot11fChannelSwitch *chnl_switch_frame;
+	uint16_t bcn_period;
+	uint32_t val, frame_len, status;
+	tLimChannelSwitchInfo *ch_switch_params;
+	struct sDot11fIEWiderBWChanSwitchAnn *wbw_chnlswitch_ie = NULL;
+	struct sLimWiderBWChannelSwitch *lim_wbw_chnlswitch_info = NULL;
+	struct sDot11fIEsec_chan_offset_ele *sec_chnl_offset = NULL;
+
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+	pe_debug("Received Channel switch action frame");
+	if (!session->lim11hEnable)
+		return;
+
+	chnl_switch_frame = qdf_mem_malloc(sizeof(*chnl_switch_frame));
+	if (!chnl_switch_frame)
+		return;
+
+	/* Unpack channel switch frame */
+	status = dot11f_unpack_channel_switch(mac_ctx, body_ptr, frame_len,
+			chnl_switch_frame, false);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
+			status, frame_len);
+		qdf_mem_free(chnl_switch_frame);
+		return;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("warning: unpack 11h-CHANSW Req(0x%08x, %d bytes)",
+			status, frame_len);
+	}
+
+	if (qdf_mem_cmp((uint8_t *) &session->bssId,
+			(uint8_t *) &mac_hdr->sa, sizeof(tSirMacAddr))) {
+		pe_warn("Rcvd action frame not from our BSS, dropping");
+		qdf_mem_free(chnl_switch_frame);
+		return;
+	}
+	/* copy the beacon interval from session */
+	val = session->beaconParams.beaconInterval;
+	ch_switch_params = &session->gLimChannelSwitch;
+	bcn_period = (uint16_t)val;
+	ch_switch_params->primaryChannel =
+		chnl_switch_frame->ChanSwitchAnn.newChannel;
+	ch_switch_params->switchCount =
+		chnl_switch_frame->ChanSwitchAnn.switchCount;
+	ch_switch_params->switchTimeoutValue =
+		SYS_MS_TO_TICKS(bcn_period) *
+		session->gLimChannelSwitch.switchCount;
+	ch_switch_params->switchMode =
+		chnl_switch_frame->ChanSwitchAnn.switchMode;
+
+	/* Only primary channel switch element is present */
+	ch_switch_params->state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+	ch_switch_params->ch_width = CH_WIDTH_20MHZ;
+
+	if (chnl_switch_frame->WiderBWChanSwitchAnn.present
+			&& session->vhtCapability) {
+		wbw_chnlswitch_ie = &chnl_switch_frame->WiderBWChanSwitchAnn;
+		session->gLimWiderBWChannelSwitch.newChanWidth =
+			wbw_chnlswitch_ie->newChanWidth;
+		session->gLimWiderBWChannelSwitch.newCenterChanFreq0 =
+			wbw_chnlswitch_ie->newCenterChanFreq0;
+		session->gLimWiderBWChannelSwitch.newCenterChanFreq1 =
+			wbw_chnlswitch_ie->newCenterChanFreq1;
+	}
+	pe_debug("Rcv Chnl Swtch Frame: Timeout in %d ticks",
+		session->gLimChannelSwitch.switchTimeoutValue);
+	if (session->htSupportedChannelWidthSet) {
+		sec_chnl_offset = &chnl_switch_frame->sec_chan_offset_ele;
+		if (sec_chnl_offset->secondaryChannelOffset ==
+				PHY_DOUBLE_CHANNEL_LOW_PRIMARY) {
+			ch_switch_params->state =
+				eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+			ch_switch_params->ch_width = CH_WIDTH_40MHZ;
+			ch_switch_params->ch_center_freq_seg0 =
+				ch_switch_params->primaryChannel + 2;
+		} else if (sec_chnl_offset->secondaryChannelOffset ==
+				PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) {
+			ch_switch_params->state =
+				eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+			ch_switch_params->ch_width = CH_WIDTH_40MHZ;
+			ch_switch_params->ch_center_freq_seg0 =
+				ch_switch_params->primaryChannel - 2;
+
+		}
+		if (session->vhtCapability &&
+			chnl_switch_frame->WiderBWChanSwitchAnn.present) {
+			wbw_chnlswitch_ie =
+				&chnl_switch_frame->WiderBWChanSwitchAnn;
+			ch_switch_params->ch_width =
+				wbw_chnlswitch_ie->newChanWidth + 1;
+			lim_wbw_chnlswitch_info =
+				&session->gLimWiderBWChannelSwitch;
+			ch_switch_params->ch_center_freq_seg0 =
+				lim_wbw_chnlswitch_info->newCenterChanFreq0;
+			ch_switch_params->ch_center_freq_seg1 =
+				lim_wbw_chnlswitch_info->newCenterChanFreq1;
+
+		}
+	}
+
+	if (CH_WIDTH_20MHZ == ch_switch_params->ch_width) {
+		session->htSupportedChannelWidthSet =
+			WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+		session->htRecommendedTxWidthSet =
+			session->htSupportedChannelWidthSet;
+	}
+
+	if (QDF_STATUS_SUCCESS != lim_start_channel_switch(mac_ctx, session))
+		pe_err("Could not start channel switch");
+
+	qdf_mem_free(chnl_switch_frame);
+	return;
+}
+
+/**
+ * lim_process_ext_channel_switch_action_frame()- Process ECSA Action
+ * Frames.
+ * @mac_ctx: pointer to global mac structure
+ * @rx_packet_info: rx packet meta information
+ * @session_entry: Session entry.
+ *
+ * This function is called when ECSA action frame is received.
+ *
+ * Return: void
+ */
+static void
+lim_process_ext_channel_switch_action_frame(tpAniSirGlobal mac_ctx,
+		uint8_t *rx_packet_info, tpPESession session_entry)
+{
+
+	tpSirMacMgmtHdr         hdr;
+	uint8_t                 *body;
+	tDot11fext_channel_switch_action_frame *ext_channel_switch_frame;
+	uint32_t                frame_len;
+	uint32_t                status;
+	uint8_t                 target_channel;
+
+	hdr = WMA_GET_RX_MAC_HEADER(rx_packet_info);
+	body = WMA_GET_RX_MPDU_DATA(rx_packet_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_packet_info);
+
+	pe_debug("Received EXT Channel switch action frame");
+
+	ext_channel_switch_frame =
+		 qdf_mem_malloc(sizeof(*ext_channel_switch_frame));
+	if (!ext_channel_switch_frame)
+		return;
+
+	/* Unpack channel switch frame */
+	status = dot11f_unpack_ext_channel_switch_action_frame(mac_ctx,
+			body, frame_len, ext_channel_switch_frame, false);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse CHANSW action frame (0x%08x, len %d):",
+			status, frame_len);
+		qdf_mem_free(ext_channel_switch_frame);
+		return;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking CHANSW Request (0x%08x, %d bytes):",
+		  status, frame_len);
+	}
+
+	target_channel =
+	 ext_channel_switch_frame->ext_chan_switch_ann_action.new_channel;
+
+	/* Free ext_channel_switch_frame here as its no longer needed */
+	qdf_mem_free(ext_channel_switch_frame);
+	/*
+	 * Now, validate if channel change is required for the passed
+	 * channel and if is valid in the current regulatory domain,
+	 * and no concurrent session is running.
+	 */
+	if (!((session_entry->currentOperChannel != target_channel) &&
+		((wlan_reg_get_channel_state(mac_ctx->pdev, target_channel) ==
+		  CHANNEL_STATE_ENABLE) ||
+		 (wlan_reg_get_channel_state(mac_ctx->pdev, target_channel) ==
+		  CHANNEL_STATE_DFS &&
+		  !policy_mgr_concurrent_open_sessions_running(
+			  mac_ctx->psoc))))) {
+		pe_err("Channel: %d is not valid", target_channel);
+		return;
+	}
+
+	if ((eLIM_STA_ROLE == session_entry->limSystemRole) ||
+	    (eLIM_P2P_DEVICE_CLIENT == session_entry->limSystemRole)) {
+
+		struct sir_sme_ext_cng_chan_ind *ext_cng_chan_ind;
+		struct scheduler_msg mmh_msg = {0};
+
+		ext_cng_chan_ind = qdf_mem_malloc(sizeof(*ext_cng_chan_ind));
+		if (!ext_cng_chan_ind)
+			return;
+
+		ext_cng_chan_ind->session_id =
+					session_entry->smeSessionId;
+
+		/* No need to extract op mode as BW will be decided in
+		 *  in SAP FSM depending on previous BW.
+		 */
+		ext_cng_chan_ind->new_channel = target_channel;
+
+		mmh_msg.type = eWNI_SME_EXT_CHANGE_CHANNEL_IND;
+		mmh_msg.bodyptr = ext_cng_chan_ind;
+		mmh_msg.bodyval = 0;
+		lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT);
+	}
+	return;
+} /*** end lim_process_ext_channel_switch_action_frame() ***/
+
+/**
+ * __lim_process_operating_mode_action_frame() - To process op mode frames
+ * @mac_ctx: pointer to mac context
+ * @rx_pkt_info: pointer to received packet info
+ * @session: pointer to session
+ *
+ * This routine is called to process operating mode action frames
+ *
+ * Return: None
+ */
+static void __lim_process_operating_mode_action_frame(tpAniSirGlobal mac_ctx,
+			uint8_t *rx_pkt_info, tpPESession session)
+{
+
+	tpSirMacMgmtHdr mac_hdr;
+	uint8_t *body_ptr;
+	tDot11fOperatingMode *operating_mode_frm;
+	uint32_t frame_len;
+	uint32_t status;
+	tpDphHashNode sta_ptr;
+	uint16_t aid;
+	uint8_t oper_mode;
+	uint8_t cb_mode;
+	uint8_t ch_bw = 0;
+	uint8_t skip_opmode_update = false;
+
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+	pe_debug("Received Operating Mode action frame");
+	operating_mode_frm = qdf_mem_malloc(sizeof(*operating_mode_frm));
+	if (!operating_mode_frm)
+		return;
+
+	/* Unpack channel switch frame */
+	status = dot11f_unpack_operating_mode(mac_ctx, body_ptr, frame_len,
+			operating_mode_frm, false);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
+			status, frame_len);
+		qdf_mem_free(operating_mode_frm);
+		return;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("warnings while unpacking (0x%08x, %d bytes):",
+			status, frame_len);
+	}
+	sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
+			&session->dph.dphHashTable);
+
+	if (sta_ptr == NULL) {
+		pe_err("Station context not found");
+		goto end;
+	}
+
+	if (CHAN_ENUM_14 >= session->currentOperChannel)
+		cb_mode = mac_ctx->roam.configParam.channelBondingMode24GHz;
+	else
+		cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz;
+	/*
+	 * Do not update the channel bonding mode if channel bonding
+	 * mode is disabled in INI.
+	 */
+	if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == cb_mode) {
+		pe_debug("channel bonding disabled");
+		goto update_nss;
+	}
+
+	if (sta_ptr->htSupportedChannelWidthSet) {
+		if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ <
+				sta_ptr->vhtSupportedChannelWidthSet)
+			oper_mode = eHT_CHANNEL_WIDTH_160MHZ;
+		else
+			oper_mode = sta_ptr->vhtSupportedChannelWidthSet + 1;
+	} else {
+		oper_mode = eHT_CHANNEL_WIDTH_20MHZ;
+	}
+
+	if ((oper_mode == eHT_CHANNEL_WIDTH_80MHZ) &&
+			(operating_mode_frm->OperatingMode.chanWidth >
+				eHT_CHANNEL_WIDTH_80MHZ))
+		skip_opmode_update = true;
+
+	if (!skip_opmode_update && (oper_mode !=
+		operating_mode_frm->OperatingMode.chanWidth)) {
+		uint32_t fw_vht_ch_wd = wma_get_vht_ch_width();
+
+		pe_debug("received Chanwidth: %d staIdx: %d",
+			(operating_mode_frm->OperatingMode.chanWidth),
+			sta_ptr->staIndex);
+
+		pe_debug(" MAC: %0x:%0x:%0x:%0x:%0x:%0x",
+			mac_hdr->sa[0], mac_hdr->sa[1], mac_hdr->sa[2],
+			mac_hdr->sa[3], mac_hdr->sa[4], mac_hdr->sa[5]);
+
+		if (operating_mode_frm->OperatingMode.chanWidth >=
+				eHT_CHANNEL_WIDTH_160MHZ
+				&& (fw_vht_ch_wd >= eHT_CHANNEL_WIDTH_160MHZ)) {
+			sta_ptr->vhtSupportedChannelWidthSet =
+				WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
+			sta_ptr->htSupportedChannelWidthSet =
+				eHT_CHANNEL_WIDTH_40MHZ;
+			ch_bw = eHT_CHANNEL_WIDTH_160MHZ;
+		} else if (operating_mode_frm->OperatingMode.chanWidth >=
+				eHT_CHANNEL_WIDTH_80MHZ) {
+			sta_ptr->vhtSupportedChannelWidthSet =
+				WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+			sta_ptr->htSupportedChannelWidthSet =
+				eHT_CHANNEL_WIDTH_40MHZ;
+			ch_bw = eHT_CHANNEL_WIDTH_80MHZ;
+		} else if (operating_mode_frm->OperatingMode.chanWidth ==
+				eHT_CHANNEL_WIDTH_40MHZ) {
+			sta_ptr->vhtSupportedChannelWidthSet =
+				WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+			sta_ptr->htSupportedChannelWidthSet =
+				eHT_CHANNEL_WIDTH_40MHZ;
+			ch_bw = eHT_CHANNEL_WIDTH_40MHZ;
+		} else if (operating_mode_frm->OperatingMode.chanWidth ==
+				eHT_CHANNEL_WIDTH_20MHZ) {
+			sta_ptr->vhtSupportedChannelWidthSet =
+				WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+			sta_ptr->htSupportedChannelWidthSet =
+				eHT_CHANNEL_WIDTH_20MHZ;
+			ch_bw = eHT_CHANNEL_WIDTH_20MHZ;
+		}
+		lim_check_vht_op_mode_change(mac_ctx, session, ch_bw,
+					     sta_ptr->staIndex, mac_hdr->sa);
+	}
+
+update_nss:
+	if (sta_ptr->vhtSupportedRxNss !=
+			(operating_mode_frm->OperatingMode.rxNSS + 1)) {
+		sta_ptr->vhtSupportedRxNss =
+			operating_mode_frm->OperatingMode.rxNSS + 1;
+		lim_set_nss_change(mac_ctx, session, sta_ptr->vhtSupportedRxNss,
+			sta_ptr->staIndex, mac_hdr->sa);
+	}
+
+end:
+	qdf_mem_free(operating_mode_frm);
+	return;
+}
+
+/**
+ * __lim_process_gid_management_action_frame() - To process group-id mgmt frames
+ * @mac_ctx: Pointer to mac context
+ * @rx_pkt_info: Rx packet info
+ * @session: pointer to session
+ *
+ * This routine will be called to process group id management frames
+ *
+ * Return: none
+ */
+static void __lim_process_gid_management_action_frame(tpAniSirGlobal mac_ctx,
+			uint8_t *rx_pkt_info, tpPESession session)
+{
+
+	uint8_t *body_ptr;
+	uint16_t aid;
+	uint32_t frame_len, status, membership = 0, usr_position = 0;
+	uint32_t *mem_lower, *mem_upper, *mem_cur;
+	tpSirMacMgmtHdr mac_hdr;
+	tDot11fVHTGidManagementActionFrame *gid_mgmt_frame;
+	tpDphHashNode sta_ptr;
+	struct sDot11fFfVhtMembershipStatusArray *vht_member_status = NULL;
+	struct sDot11fFfVhtUserPositionArray *vht_user_position = NULL;
+
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+	pe_debug("Received GID Management action frame");
+	gid_mgmt_frame = qdf_mem_malloc(sizeof(*gid_mgmt_frame));
+	if (!gid_mgmt_frame)
+		return;
+
+	/* Unpack Gid Management Action frame */
+	status = dot11f_unpack_vht_gid_management_action_frame(mac_ctx,
+			body_ptr, frame_len, gid_mgmt_frame, false);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Fail to parse an Grp id frame (0x%08x, %d bytes):",
+			status, frame_len);
+		qdf_mem_free(gid_mgmt_frame);
+		return;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("warnings while unpacking Grp id frm (0x%08x, %d bytes):",
+		 status, frame_len);
+	}
+	sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
+			&session->dph.dphHashTable);
+	if (!sta_ptr) {
+		pe_err("Failed to get STA entry from hash table");
+		goto out;
+	}
+	pe_debug("received Gid Management Action Frame staIdx: %d",
+		sta_ptr->staIndex);
+
+	pe_debug(" MAC: %0x:%0x:%0x:%0x:%0x:%0x",
+		mac_hdr->sa[0], mac_hdr->sa[1], mac_hdr->sa[2],
+		mac_hdr->sa[3], mac_hdr->sa[4], mac_hdr->sa[5]);
+	vht_member_status = &gid_mgmt_frame->VhtMembershipStatusArray;
+	mem_lower =  (uint32_t *) vht_member_status->membershipStatusArray;
+	mem_upper = (uint32_t *) &vht_member_status->membershipStatusArray[4];
+
+	if (*mem_lower && *mem_upper) {
+		pe_err("rcved frame with mult group ID set, staIdx = %d",
+			sta_ptr->staIndex);
+		goto out;
+	}
+	if (*mem_lower) {
+		mem_cur = mem_lower;
+	} else if (*mem_upper) {
+		mem_cur = mem_upper;
+		membership += sizeof(uint32_t);
+	} else {
+		pe_err("rcved Gid frame with no group ID set, staIdx: %d",
+			sta_ptr->staIndex);
+		goto out;
+	}
+	while (!(*mem_cur & 1)) {
+		*mem_cur >>= 1;
+		++membership;
+	}
+	if (*mem_cur) {
+		pe_err("rcved frame with mult group ID set, staIdx: %d",
+			sta_ptr->staIndex);
+		goto out;
+	}
+
+	/*Just read the last two bits */
+	vht_user_position = &gid_mgmt_frame->VhtUserPositionArray;
+	usr_position = vht_user_position->userPositionArray[membership] & 0x3;
+	lim_check_membership_user_position(mac_ctx, session, membership,
+			usr_position, sta_ptr->staIndex);
+out:
+	qdf_mem_free(gid_mgmt_frame);
+	return;
+}
+
+static void
+__lim_process_add_ts_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+			 tpPESession psessionEntry)
+{
+}
+
+/**
+ * __lim_process_add_ts_rsp() - To process add ts response frame
+ * @mac_ctx: pointer to mac context
+ * @rx_pkt_info: Received packet info
+ * @session: pointer to session
+ *
+ * This routine is to handle add ts response frame
+ *
+ * Return: none
+ */
+static void __lim_process_add_ts_rsp(tpAniSirGlobal mac_ctx,
+		uint8_t *rx_pkt_info, tpPESession session)
+{
+	tSirAddtsRspInfo addts;
+	QDF_STATUS retval;
+	tpSirMacMgmtHdr mac_hdr;
+	tpDphHashNode sta_ptr;
+	uint16_t aid;
+	uint32_t frameLen;
+	uint8_t *body_ptr;
+	tpLimTspecInfo tspec_info;
+	uint8_t ac;
+	tpDphHashNode sta_ds_ptr = NULL;
+	uint8_t rsp_reqd = 1;
+	uint32_t cfg_len;
+	tSirMacAddr peer_macaddr;
+
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	frameLen = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+	pe_warn("Recv AddTs Response");
+	if (LIM_IS_AP_ROLE(session)) {
+		pe_warn("AddTsRsp recvd at AP: ignoring");
+		return;
+	}
+
+	sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
+				&session->dph.dphHashTable);
+	if (sta_ptr == NULL) {
+		pe_err("Station context not found - ignoring AddTsRsp");
+		return;
+	}
+
+	retval = sir_convert_addts_rsp2_struct(mac_ctx, body_ptr,
+			frameLen, &addts);
+	if (retval != QDF_STATUS_SUCCESS) {
+		pe_err("AddTsRsp parsing failed %d", retval);
+		return;
+	}
+	/*
+	 * don't have to check for qos/wme capabilities since we wouldn't have
+	 * this flag set otherwise
+	 */
+	if (!mac_ctx->lim.gLimAddtsSent) {
+		/* we never sent an addts request! */
+		pe_warn("rx AddTsRsp but no req was ever sent-ignoring");
+		return;
+	}
+
+	if (mac_ctx->lim.gLimAddtsReq.req.dialogToken != addts.dialogToken) {
+		pe_warn("token mismatch got: %d exp: %d - ignoring",
+			addts.dialogToken,
+			mac_ctx->lim.gLimAddtsReq.req.dialogToken);
+		return;
+	}
+
+	/*
+	 * for successful addts response, try to add the classifier.
+	 * if this fails for any reason, we should send a delts request to the
+	 * ap for now, its ok not to send a delts since we are going to add
+	 * support for multiple tclas soon and until then we won't send any
+	 * addts requests with multiple tclas elements anyway.
+	 * In case of addClassifier failure, we just let the addts timer run out
+	 */
+	if (((addts.tspec.tsinfo.traffic.accessPolicy ==
+		SIR_MAC_ACCESSPOLICY_HCCA) ||
+		(addts.tspec.tsinfo.traffic.accessPolicy ==
+			SIR_MAC_ACCESSPOLICY_BOTH)) &&
+		(addts.status == eSIR_MAC_SUCCESS_STATUS)) {
+		/* add the classifier - this should always succeed */
+		if (addts.numTclas > 1) {
+			/* currently no support for multiple tclas elements */
+			pe_err("Sta: %d Too many Tclas: %d 1 supported",
+				aid, addts.numTclas);
+			return;
+		} else if (addts.numTclas == 1) {
+			pe_debug("Response from STA: %d tsid: %d UP: %d OK!",
+				aid, addts.tspec.tsinfo.traffic.tsid,
+				addts.tspec.tsinfo.traffic.userPrio);
+		}
+	}
+	pe_debug("Recv AddTsRsp: tsid: %d UP: %d status: %d",
+		addts.tspec.tsinfo.traffic.tsid,
+		addts.tspec.tsinfo.traffic.userPrio, addts.status);
+
+	/* deactivate the response timer */
+	lim_deactivate_and_change_timer(mac_ctx, eLIM_ADDTS_RSP_TIMER);
+
+	if (addts.status != eSIR_MAC_SUCCESS_STATUS) {
+		pe_debug("Recv AddTsRsp: tsid: %d UP: %d status: %d",
+			addts.tspec.tsinfo.traffic.tsid,
+			addts.tspec.tsinfo.traffic.userPrio, addts.status);
+		lim_send_sme_addts_rsp(mac_ctx, true, addts.status, session,
+				       addts.tspec, session->smeSessionId,
+				       session->transactionId);
+
+		/* clear the addts flag */
+		mac_ctx->lim.gLimAddtsSent = false;
+
+		return;
+	}
+#ifdef FEATURE_WLAN_ESE
+	if (addts.tsmPresent) {
+		pe_debug("TSM IE Present");
+		session->eseContext.tsm.tid =
+			addts.tspec.tsinfo.traffic.userPrio;
+		qdf_mem_copy(&session->eseContext.tsm.tsmInfo,
+			     &addts.tsmIE, sizeof(tSirMacESETSMIE));
+		lim_send_sme_tsm_ie_ind(mac_ctx, session, addts.tsmIE.tsid,
+					addts.tsmIE.state,
+					addts.tsmIE.msmt_interval);
+	}
+#endif
+	/*
+	 * Since AddTS response was successful, check for the PSB flag
+	 * and directional flag inside the TS Info field.
+	 * An AC is trigger enabled AC if the PSB subfield is set to 1
+	 * in the uplink direction.
+	 * An AC is delivery enabled AC if the PSB subfield is set to 1
+	 * in the downlink direction.
+	 * An AC is trigger and delivery enabled AC if the PSB subfield
+	 * is set to 1 in the bi-direction field.
+	 */
+	if (addts.tspec.tsinfo.traffic.psb == 1)
+		lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
+						     &addts.tspec.tsinfo,
+						     SET_UAPSD_MASK);
+	else
+		lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
+						     &addts.tspec.tsinfo,
+						     CLEAR_UAPSD_MASK);
+
+	/*
+	 * ADDTS success, so AC is now admitted. We shall now use the default
+	 * EDCA parameters as advertised by AP and send the updated EDCA params
+	 * to HAL.
+	 */
+	ac = upToAc(addts.tspec.tsinfo.traffic.userPrio);
+	if (addts.tspec.tsinfo.traffic.direction ==
+	    SIR_MAC_DIRECTION_UPLINK) {
+		session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |=
+			(1 << ac);
+	} else if (addts.tspec.tsinfo.traffic.direction ==
+		   SIR_MAC_DIRECTION_DNLINK) {
+		session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |=
+			(1 << ac);
+	} else if (addts.tspec.tsinfo.traffic.direction ==
+		   SIR_MAC_DIRECTION_BIDIR) {
+		session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |=
+			(1 << ac);
+		session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |=
+			(1 << ac);
+	}
+	lim_set_active_edca_params(mac_ctx, session->gLimEdcaParams,
+				   session);
+	sta_ds_ptr = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+				   &session->dph.dphHashTable);
+	if (sta_ds_ptr != NULL)
+		lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive,
+				     sta_ds_ptr->bssId, false);
+	else
+		pe_err("Self entry missing in Hash Table");
+	sir_copy_mac_addr(peer_macaddr, session->bssId);
+	/* if schedule is not present then add TSPEC with svcInterval as 0. */
+	if (!addts.schedulePresent)
+		addts.schedule.svcInterval = 0;
+	if (QDF_STATUS_SUCCESS !=
+	    lim_tspec_add(mac_ctx, sta_ptr->staAddr, sta_ptr->assocId,
+		&addts.tspec, addts.schedule.svcInterval, &tspec_info)) {
+		pe_err("Adding entry in lim Tspec Table failed");
+		lim_send_delts_req_action_frame(mac_ctx, peer_macaddr, rsp_reqd,
+						&addts.tspec.tsinfo,
+						&addts.tspec, session);
+		mac_ctx->lim.gLimAddtsSent = false;
+		return;
+		/*
+		 * Error handling. send the response with error status.
+		 * need to send DelTS to tear down the TSPEC status.
+		 */
+	}
+	if ((addts.tspec.tsinfo.traffic.accessPolicy !=
+			SIR_MAC_ACCESSPOLICY_EDCA) ||
+		((upToAc(addts.tspec.tsinfo.traffic.userPrio) < MAX_NUM_AC))) {
+#ifdef FEATURE_WLAN_ESE
+		retval = lim_send_hal_msg_add_ts(mac_ctx,
+				sta_ptr->staIndex, tspec_info->idx,
+				addts.tspec, session->peSessionId,
+				addts.tsmIE.msmt_interval);
+#else
+		retval = lim_send_hal_msg_add_ts(mac_ctx,
+				sta_ptr->staIndex, tspec_info->idx,
+				addts.tspec, session->peSessionId);
+#endif
+		if (QDF_STATUS_SUCCESS != retval) {
+			lim_admit_control_delete_ts(mac_ctx, sta_ptr->assocId,
+				&addts.tspec.tsinfo, NULL, &tspec_info->idx);
+
+			/* Send DELTS action frame to AP */
+			cfg_len = sizeof(tSirMacAddr);
+			lim_send_delts_req_action_frame(mac_ctx, peer_macaddr,
+					rsp_reqd, &addts.tspec.tsinfo,
+					&addts.tspec, session);
+			lim_send_sme_addts_rsp(mac_ctx, true, retval,
+					session, addts.tspec,
+					session->smeSessionId,
+					session->transactionId);
+			mac_ctx->lim.gLimAddtsSent = false;
+			return;
+		}
+		pe_debug("AddTsRsp received successfully UP: %d TSID: %d",
+			addts.tspec.tsinfo.traffic.userPrio,
+			addts.tspec.tsinfo.traffic.tsid);
+	} else {
+		pe_debug("AddTsRsp received successfully UP: %d TSID: %d",
+			addts.tspec.tsinfo.traffic.userPrio,
+			addts.tspec.tsinfo.traffic.tsid);
+		pe_debug("no ACM: Bypass sending WMA_ADD_TS_REQ to HAL");
+		/*
+		 * Use the smesessionId and smetransactionId from the PE
+		 * session context
+		 */
+		lim_send_sme_addts_rsp(mac_ctx, true, eSIR_SME_SUCCESS,
+			session, addts.tspec, session->smeSessionId,
+			session->transactionId);
+	}
+	/* clear the addts flag */
+	mac_ctx->lim.gLimAddtsSent = false;
+	return;
+}
+
+/**
+ * __lim_process_del_ts_req() - To process del ts response frame
+ * @mac_ctx: pointer to mac context
+ * @rx_pkt_info: Received packet info
+ * @session: pointer to session
+ *
+ * This routine is to handle del ts request frame
+ *
+ * Return: none
+ */
+static void __lim_process_del_ts_req(tpAniSirGlobal mac_ctx,
+		uint8_t *rx_pkt_info, tpPESession session)
+{
+	QDF_STATUS retval;
+	tSirDeltsReqInfo delts;
+	tpSirMacMgmtHdr mac_hdr;
+	tpDphHashNode sta_ptr;
+	uint32_t frame_len;
+	uint16_t aid;
+	uint8_t *body_ptr;
+	uint8_t ts_status;
+	tSirMacTSInfo *tsinfo;
+	uint8_t tspec_idx;
+	uint8_t ac;
+	tpDphHashNode sta_ds_ptr = NULL;
+
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+	sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
+				      &session->dph.dphHashTable);
+	if (sta_ptr == NULL) {
+		pe_err("Station context not found - ignoring DelTs");
+		return;
+	}
+	/* parse the delts request */
+	retval = sir_convert_delts_req2_struct(mac_ctx, body_ptr,
+			frame_len, &delts);
+	if (retval != QDF_STATUS_SUCCESS) {
+		pe_err("DelTs parsing failed %d", retval);
+		return;
+	}
+
+	if (delts.wmeTspecPresent) {
+		if ((!session->limWmeEnabled) || (!sta_ptr->wmeEnabled)) {
+			pe_warn("Ignore delts req: wme not enabled");
+			return;
+		}
+		pe_debug("WME Delts received");
+	} else if ((session->limQosEnabled) && sta_ptr->lleEnabled) {
+		pe_debug("11e QoS Delts received");
+	} else if ((session->limWsmEnabled) && sta_ptr->wsmEnabled) {
+		pe_debug("WSM Delts received");
+	} else {
+		pe_warn("Ignoring delts request: qos not enabled/capable");
+		return;
+	}
+
+	tsinfo = delts.wmeTspecPresent ? &delts.tspec.tsinfo : &delts.tsinfo;
+
+	/* if no Admit Control, ignore the request */
+	if (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) {
+		if (upToAc(tsinfo->traffic.userPrio) >= MAX_NUM_AC) {
+			pe_warn("DelTs with UP: %d has no AC - ignoring req",
+				tsinfo->traffic.userPrio);
+			return;
+		}
+	}
+
+	if (!LIM_IS_AP_ROLE(session))
+		lim_send_sme_delts_ind(mac_ctx, &delts, aid, session);
+
+	/* try to delete the TS */
+	if (QDF_STATUS_SUCCESS !=
+	    lim_admit_control_delete_ts(mac_ctx, sta_ptr->assocId, tsinfo,
+				&ts_status, &tspec_idx)) {
+		pe_warn("Unable to Delete TS");
+		return;
+	} else if (!((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA)
+			|| (tsinfo->traffic.accessPolicy ==
+					SIR_MAC_ACCESSPOLICY_BOTH))){
+		/* send message to HAL to delete TS */
+		if (QDF_STATUS_SUCCESS != lim_send_hal_msg_del_ts(mac_ctx,
+						sta_ptr->staIndex, tspec_idx,
+						delts, session->peSessionId,
+						session->bssId)) {
+			pe_warn("DelTs with UP: %d failed ignoring request",
+				tsinfo->traffic.userPrio);
+			return;
+		}
+	}
+	/*
+	 * We successfully deleted the TSPEC. Update the dynamic UAPSD Mask.
+	 * The AC for this TSPEC is no longer trigger enabled if this Tspec
+	 * was set-up in uplink direction only.
+	 * The AC for this TSPEC is no longer delivery enabled if this Tspec
+	 * was set-up in downlink direction only.
+	 * The AC for this TSPEC is no longer triiger enabled and delivery
+	 * enabled if this Tspec was a bidirectional TSPEC.
+	 */
+	lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
+					     tsinfo, CLEAR_UAPSD_MASK);
+	/*
+	 * We're deleting the TSPEC.
+	 * The AC for this TSPEC is no longer admitted in uplink/downlink
+	 * direction if this TSPEC was set-up in uplink/downlink direction only.
+	 * The AC for this TSPEC is no longer admitted in both uplink and
+	 * downlink directions if this TSPEC was a bi-directional TSPEC.
+	 * If ACM is set for this AC and this AC is admitted only in downlink
+	 * direction, PE needs to downgrade the EDCA parameter
+	 * (for the AC for which TS is being deleted) to the
+	 * next best AC for which ACM is not enabled, and send the
+	 * updated values to HAL.
+	 */
+	ac = upToAc(tsinfo->traffic.userPrio);
+	if (tsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) {
+		session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
+			~(1 << ac);
+	} else if (tsinfo->traffic.direction ==
+		   SIR_MAC_DIRECTION_DNLINK) {
+		session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
+			~(1 << ac);
+	} else if (tsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR) {
+		session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
+			~(1 << ac);
+		session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
+			~(1 << ac);
+	}
+	lim_set_active_edca_params(mac_ctx, session->gLimEdcaParams,
+				   session);
+	sta_ds_ptr = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+				   &session->dph.dphHashTable);
+	if (sta_ds_ptr != NULL)
+		lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive,
+				     sta_ds_ptr->bssId, false);
+	else
+		pe_err("Self entry missing in Hash Table");
+
+	pe_debug("DeleteTS succeeded");
+#ifdef FEATURE_WLAN_ESE
+	lim_send_sme_tsm_ie_ind(mac_ctx, session, 0, 0, 0);
+#endif
+}
+
+/**
+ * __lim_process_qos_map_configure_frame() - to process QoS map configure frame
+ * @mac_ctx: pointer to mac context
+ * @rx_pkt_info: pointer to received packet info
+ * @session: pointer to session
+ *
+ * This routine will called to process qos map configure frame
+ *
+ * Return: none
+ */
+static void __lim_process_qos_map_configure_frame(tpAniSirGlobal mac_ctx,
+			uint8_t *rx_pkt_info, tpPESession session)
+{
+	tpSirMacMgmtHdr mac_hdr;
+	uint32_t frame_len;
+	uint8_t *body_ptr;
+	QDF_STATUS retval;
+
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+	retval = sir_convert_qos_map_configure_frame2_struct(mac_ctx,
+				body_ptr, frame_len, &session->QosMapSet);
+	if (retval != QDF_STATUS_SUCCESS) {
+		pe_err("QosMapConfigure frame parsing fail %d", retval);
+		return;
+	}
+	lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
+			(uint8_t *) mac_hdr,
+			frame_len + sizeof(tSirMacMgmtHdr), 0,
+			WMA_GET_RX_CH(rx_pkt_info), session,
+			WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info));
+}
+
+#ifdef ANI_SUPPORT_11H
+static void
+__lim_process_basic_meas_req(tpAniSirGlobal pMac,
+			     tpSirMacMeasReqActionFrame pMeasReqFrame,
+			     tSirMacAddr peerMacAddr, tpPESession psessionEntry)
+{
+	if (lim_send_meas_report_frame(pMac, pMeasReqFrame,
+				       peerMacAddr, psessionEntry) !=
+					 QDF_STATUS_SUCCESS) {
+		pe_err("fail to send Basic Meas report");
+		return;
+	}
+}
+static void
+__lim_process_cca_meas_req(tpAniSirGlobal pMac,
+			   tpSirMacMeasReqActionFrame pMeasReqFrame,
+			   tSirMacAddr peerMacAddr, tpPESession psessionEntry)
+{
+	if (lim_send_meas_report_frame(pMac, pMeasReqFrame,
+				       peerMacAddr, psessionEntry) !=
+					 QDF_STATUS_SUCCESS) {
+		pe_err("fail to send CCA Meas report");
+		return;
+	}
+}
+static void
+__lim_process_rpi_meas_req(tpAniSirGlobal pMac,
+			   tpSirMacMeasReqActionFrame pMeasReqFrame,
+			   tSirMacAddr peerMacAddr, tpPESession psessionEntry)
+{
+	if (lim_send_meas_report_frame(pMac, pMeasReqFrame,
+				       peerMacAddr, psessionEntry) !=
+					 QDF_STATUS_SUCCESS) {
+		pe_err("fail to send RPI Meas report");
+		return;
+	}
+}
+static void
+__lim_process_measurement_request_frame(tpAniSirGlobal pMac,
+					uint8_t *pRxPacketInfo,
+					tpPESession psessionEntry)
+{
+	tpSirMacMgmtHdr pHdr;
+	uint8_t *pBody;
+	tpSirMacMeasReqActionFrame pMeasReqFrame;
+	uint32_t frameLen;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+	pMeasReqFrame = qdf_mem_malloc(sizeof(tSirMacMeasReqActionFrame));
+	if (!pMeasReqFrame)
+		return;
+
+	if (sir_convert_meas_req_frame2_struct(pMac, pBody, pMeasReqFrame, frameLen)
+	    != QDF_STATUS_SUCCESS) {
+		pe_warn("Rcv invalid Measurement Request Action Frame");
+		return;
+	}
+	switch (pMeasReqFrame->measReqIE.measType) {
+	case SIR_MAC_BASIC_MEASUREMENT_TYPE:
+		__lim_process_basic_meas_req(pMac, pMeasReqFrame, pHdr->sa,
+					     psessionEntry);
+		break;
+	case SIR_MAC_CCA_MEASUREMENT_TYPE:
+		__lim_process_cca_meas_req(pMac, pMeasReqFrame, pHdr->sa,
+					   psessionEntry);
+		break;
+	case SIR_MAC_RPI_MEASUREMENT_TYPE:
+		__lim_process_rpi_meas_req(pMac, pMeasReqFrame, pHdr->sa,
+					   psessionEntry);
+		break;
+	default:
+		pe_warn("Unknown Measurement Type: %d",
+			       pMeasReqFrame->measReqIE.measType);
+		break;
+	}
+} /*** end limProcessMeasurementRequestFrame ***/
+static void
+__lim_process_tpc_request_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+				tpPESession psessionEntry)
+{
+	tpSirMacMgmtHdr pHdr;
+	uint8_t *pBody;
+	tpSirMacTpcReqActionFrame pTpcReqFrame;
+	uint32_t frameLen;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+	pe_debug("****LIM: Processing TPC Request from peer ****");
+
+	pTpcReqFrame = qdf_mem_malloc(sizeof(tSirMacTpcReqActionFrame));
+	if (!pTpcReqFrame)
+		return;
+
+	if (sir_convert_tpc_req_frame2_struct(pMac, pBody, pTpcReqFrame, frameLen) !=
+	    QDF_STATUS_SUCCESS) {
+		pe_warn("Rcv invalid TPC Req Action Frame");
+		return;
+	}
+	if (lim_send_tpc_report_frame(pMac,
+				      pTpcReqFrame,
+				      pHdr->sa, psessionEntry) != QDF_STATUS_SUCCESS) {
+		pe_err("fail to send TPC Report Frame");
+		return;
+	}
+}
+#endif
+
+static void
+__lim_process_sm_power_save_update(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+				   tpPESession psessionEntry)
+{
+
+	tpSirMacMgmtHdr pHdr;
+	tDot11fSMPowerSave frmSMPower;
+	tSirMacHTMIMOPowerSaveState state;
+	tpDphHashNode pSta;
+	uint16_t aid;
+	uint32_t frameLen, nStatus;
+	uint8_t *pBody;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+	pSta =
+		dph_lookup_hash_entry(pMac, pHdr->sa, &aid,
+				      &psessionEntry->dph.dphHashTable);
+	if (pSta == NULL) {
+		pe_err("STA context not found - ignoring UpdateSM PSave Mode from");
+		lim_print_mac_addr(pMac, pHdr->sa, LOGE);
+		return;
+	}
+
+	/**Unpack the received frame */
+	nStatus = dot11f_unpack_sm_power_save(pMac, pBody, frameLen,
+					      &frmSMPower, false);
+
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to unpack and parse a Update SM Power (0x%08x, %d bytes):",
+			nStatus, frameLen);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pBody, frameLen);
+		return;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_debug("There were warnings while unpacking a SMPower Save update (0x%08x, %d bytes):",
+			nStatus, frameLen);
+	}
+
+	pe_debug("Received SM Power save Mode update Frame with PS_Enable: %d"
+		   "PS Mode: %d", frmSMPower.SMPowerModeSet.PowerSave_En,
+		frmSMPower.SMPowerModeSet.Mode);
+
+	/** Update in the DPH Table about the Update in the SM Power Save mode*/
+	if (frmSMPower.SMPowerModeSet.PowerSave_En
+	    && frmSMPower.SMPowerModeSet.Mode)
+		state = eSIR_HT_MIMO_PS_DYNAMIC;
+	else if ((frmSMPower.SMPowerModeSet.PowerSave_En)
+		 && (frmSMPower.SMPowerModeSet.Mode == 0))
+		state = eSIR_HT_MIMO_PS_STATIC;
+	else if ((frmSMPower.SMPowerModeSet.PowerSave_En == 0)
+		 && (frmSMPower.SMPowerModeSet.Mode == 0))
+		state = eSIR_HT_MIMO_PS_NO_LIMIT;
+	else {
+		pe_warn("Received SM Power save Mode update Frame with invalid mode");
+		return;
+	}
+
+	if (state == pSta->htMIMOPSState) {
+		pe_err("The PEER is already set in the same mode");
+		return;
+	}
+
+	/** Update in the HAL Station Table for the Update of the Protection Mode */
+	pSta->htMIMOPSState = state;
+	lim_post_sm_state_update(pMac, pSta->staIndex, pSta->htMIMOPSState,
+				 pSta->staAddr, psessionEntry->smeSessionId);
+}
+
+
+static void
+__lim_process_radio_measure_request(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+				    tpPESession psessionEntry)
+{
+	tpSirMacMgmtHdr pHdr;
+	tDot11fRadioMeasurementRequest *frm;
+	uint32_t frameLen, nStatus;
+	uint8_t *pBody;
+	uint16_t curr_seq_num;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+	if (psessionEntry == NULL) {
+		return;
+	}
+
+	curr_seq_num = ((pHdr->seqControl.seqNumHi <<
+			 HIGH_SEQ_NUM_OFFSET) |
+			pHdr->seqControl.seqNumLo);
+	if (curr_seq_num == pMac->rrm.rrmPEContext.prev_rrm_report_seq_num &&
+	    pMac->rrm.rrmPEContext.pCurrentReq) {
+		pe_err("rrm report req frame, seq num: %d is already in progress, drop it",
+			curr_seq_num);
+		return;
+	}
+	/* Save seq no of currently processing rrm report req frame */
+	pMac->rrm.rrmPEContext.prev_rrm_report_seq_num = curr_seq_num;
+	lim_send_sme_mgmt_frame_ind(pMac, pHdr->fc.subType, (uint8_t *)pHdr,
+		frameLen + sizeof(tSirMacMgmtHdr), 0,
+		WMA_GET_RX_CH(pRxPacketInfo), psessionEntry,
+		WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo));
+
+	frm = qdf_mem_malloc(sizeof(*frm));
+	if (!frm)
+		return;
+
+	/**Unpack the received frame */
+	nStatus = dot11f_unpack_radio_measurement_request(pMac, pBody,
+							  frameLen, frm, false);
+
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to unpack and parse a Radio Measure request (0x%08x, %d bytes):",
+			nStatus, frameLen);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pBody, frameLen);
+		goto err;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_debug("There were warnings while unpacking a Radio Measure request (0x%08x, %d bytes):",
+			nStatus, frameLen);
+	}
+	/* Call rrm function to handle the request. */
+
+	rrm_process_radio_measurement_request(pMac, pHdr->sa, frm,
+					      psessionEntry);
+err:
+	qdf_mem_free(frm);
+}
+
+static QDF_STATUS
+__lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+				   tpPESession psessionEntry)
+{
+	tpSirMacMgmtHdr pHdr;
+	tDot11fLinkMeasurementRequest frm;
+	uint32_t frameLen, nStatus;
+	uint8_t *pBody;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+	if (psessionEntry == NULL) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/**Unpack the received frame */
+	nStatus =
+		dot11f_unpack_link_measurement_request(pMac, pBody, frameLen,
+						       &frm, false);
+
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to unpack and parse a Link Measure request (0x%08x, %d bytes):",
+			nStatus, frameLen);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pBody, frameLen);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_debug("There were warnings while unpacking a Link Measure request (0x%08x, %d bytes):",
+			nStatus, frameLen);
+	}
+	/* Call rrm function to handle the request. */
+
+	return rrm_process_link_measurement_request(pMac, pRxPacketInfo, &frm,
+					     psessionEntry);
+
+}
+
+static void
+__lim_process_neighbor_report(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+			      tpPESession psessionEntry)
+{
+	tpSirMacMgmtHdr pHdr;
+	tDot11fNeighborReportResponse *pFrm;
+	uint32_t frameLen, nStatus;
+	uint8_t *pBody;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+	pFrm = qdf_mem_malloc(sizeof(tDot11fNeighborReportResponse));
+	if (!pFrm)
+		return;
+
+	if (psessionEntry == NULL) {
+		qdf_mem_free(pFrm);
+		return;
+	}
+
+	/**Unpack the received frame */
+	nStatus =
+		dot11f_unpack_neighbor_report_response(pMac, pBody,
+						       frameLen, pFrm, false);
+
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to unpack and parse a Neighbor report response (0x%08x, %d bytes):",
+			nStatus, frameLen);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pBody, frameLen);
+		qdf_mem_free(pFrm);
+		return;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_debug("There were warnings while unpacking a Neighbor report response (0x%08x, %d bytes):",
+			nStatus, frameLen);
+	}
+	/* Call rrm function to handle the request. */
+	rrm_process_neighbor_report_response(pMac, pFrm, psessionEntry);
+
+	qdf_mem_free(pFrm);
+}
+
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * limProcessSAQueryRequestActionFrame
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_action_frame() upon
+ * SA query request Action frame reception.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  *pRxPacketInfo - Handle to the Rx packet info
+ * @param  psessionEntry - PE session entry
+ *
+ * @return None
+ */
+static void __lim_process_sa_query_request_action_frame(tpAniSirGlobal pMac,
+							uint8_t *pRxPacketInfo,
+							tpPESession psessionEntry)
+{
+	tpSirMacMgmtHdr pHdr;
+	uint8_t *pBody;
+	uint32_t frame_len;
+	uint8_t transId[2];
+
+	/* Prima  --- Below Macro not available in prima
+	   pHdr = SIR_MAC_BD_TO_MPDUHEADER(pBd);
+	   pBody = SIR_MAC_BD_TO_MPDUDATA(pBd); */
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+	if (frame_len < sizeof(struct sDot11fSaQueryReq)) {
+		pe_err("Invalid frame length");
+		return;
+	}
+	/* If this is an unprotected SA Query Request, then ignore it. */
+	if (pHdr->fc.wep == 0)
+		return;
+
+	/* 11w offload is enabled then firmware should not fwd this frame */
+	if (LIM_IS_STA_ROLE(psessionEntry) && pMac->pmf_offload) {
+		pe_err("11w offload enabled, SA Query req isn't expected");
+		return;
+	}
+
+	/*Extract 11w trsansId from SA query request action frame
+	   In SA query response action frame we will send same transId
+	   In SA query request action frame:
+	   Category       : 1 byte
+	   Action         : 1 byte
+	   Transaction ID : 2 bytes */
+	qdf_mem_copy(&transId[0], &pBody[2], 2);
+
+	/* Send 11w SA query response action frame */
+	if (lim_send_sa_query_response_frame(pMac,
+					     transId,
+					     pHdr->sa,
+					     psessionEntry) != QDF_STATUS_SUCCESS) {
+		pe_err("fail to send SA query response action frame");
+		return;
+	}
+}
+
+/**
+ * __lim_process_sa_query_response_action_frame
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_action_frame() upon
+ * SA query response Action frame reception.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  *pRxPacketInfo - Handle to the Rx packet info
+ * @param  psessionEntry - PE session entry
+ * @return None
+ */
+static void __lim_process_sa_query_response_action_frame(tpAniSirGlobal pMac,
+							 uint8_t *pRxPacketInfo,
+							 tpPESession psessionEntry)
+{
+	tpSirMacMgmtHdr pHdr;
+	uint32_t frame_len;
+	uint8_t *pBody;
+	tpDphHashNode pSta;
+	uint16_t aid;
+	uint16_t transId;
+	uint8_t retryNum;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	pe_debug("SA Query Response received");
+
+	if (frame_len < sizeof(struct sDot11fSaQueryRsp)) {
+		pe_err("Invalid frame length");
+		return;
+	}
+	/* When a station, supplicant handles SA Query Response.
+	 * Forward to SME to HDD to wpa_supplicant.
+	 */
+	if (LIM_IS_STA_ROLE(psessionEntry)) {
+		lim_send_sme_mgmt_frame_ind(pMac, pHdr->fc.subType,
+					    (uint8_t *)pHdr,
+					    frame_len + sizeof(tSirMacMgmtHdr),
+					    0,
+					    WMA_GET_RX_CH(pRxPacketInfo),
+					    psessionEntry,
+					    WMA_GET_RX_RSSI_NORMALIZED(
+					    pRxPacketInfo));
+		return;
+	}
+
+	/* If this is an unprotected SA Query Response, then ignore it. */
+	if (pHdr->fc.wep == 0)
+		return;
+
+	pSta =
+		dph_lookup_hash_entry(pMac, pHdr->sa, &aid,
+				      &psessionEntry->dph.dphHashTable);
+	if (NULL == pSta)
+		return;
+
+	pe_debug("SA Query Response source addr:  %0x:%0x:%0x:%0x:%0x:%0x",
+		pHdr->sa[0], pHdr->sa[1], pHdr->sa[2], pHdr->sa[3],
+		pHdr->sa[4], pHdr->sa[5]);
+	pe_debug("SA Query state for station: %d", pSta->pmfSaQueryState);
+
+	if (DPH_SA_QUERY_IN_PROGRESS != pSta->pmfSaQueryState)
+		return;
+
+	/* Extract 11w trsansId from SA query response action frame
+	   In SA query response action frame:
+	   Category       : 1 byte
+	   Action         : 1 byte
+	   Transaction ID : 2 bytes */
+	qdf_mem_copy(&transId, &pBody[2], 2);
+
+	/* If SA Query is in progress with the station and the station
+	   responds then the association request that triggered the SA
+	   query is from a rogue station, just go back to initial state. */
+	for (retryNum = 0; retryNum <= pSta->pmfSaQueryRetryCount; retryNum++)
+		if (transId == pSta->pmfSaQueryStartTransId + retryNum) {
+			pe_debug("Found matching SA Query Request - transaction ID: %d",
+				transId);
+			tx_timer_deactivate(&pSta->pmfSaQueryTimer);
+			pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
+			break;
+		}
+}
+#endif
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * lim_drop_unprotected_action_frame
+ *
+ ***FUNCTION:
+ * This function checks if an Action frame should be dropped since it is
+ * a Robust Management Frame, it is unprotected, and it is received on a
+ * connection where PMF is enabled.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Global MAC structure
+ * @param  psessionEntry - PE session entry
+ * @param  pHdr - Frame header
+ * @param  category - Action frame category
+ * @return true if frame should be dropped
+ */
+
+static bool
+lim_drop_unprotected_action_frame(tpAniSirGlobal pMac, tpPESession psessionEntry,
+				  tpSirMacMgmtHdr pHdr, uint8_t category)
+{
+	uint16_t aid;
+	tpDphHashNode pStaDs;
+	bool rmfConnection = false;
+
+	if (LIM_IS_AP_ROLE(psessionEntry)) {
+		pStaDs =
+			dph_lookup_hash_entry(pMac, pHdr->sa, &aid,
+					      &psessionEntry->dph.dphHashTable);
+		if (pStaDs != NULL)
+			if (pStaDs->rmfEnabled)
+				rmfConnection = true;
+	} else if (psessionEntry->limRmfEnabled)
+		rmfConnection = true;
+
+	if (rmfConnection && (pHdr->fc.wep == 0)) {
+		pe_err("Dropping unprotected Action category: %d frame since RMF is enabled",
+			category);
+		return true;
+	} else
+		return false;
+}
+#endif
+
+/**
+ * lim_process_addba_req() - process ADDBA Request
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_pkt_info: A pointer to packet info structure
+ * @session: PE session pointer
+ *
+ * This routine will be called to process ADDBA request action frame
+ *
+ * Return: None
+ */
+static void lim_process_addba_req(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+				  tpPESession session)
+{
+	tpSirMacMgmtHdr mac_hdr;
+	uint8_t *body_ptr;
+	tDot11faddba_req *addba_req;
+	uint32_t frame_len, status;
+	QDF_STATUS qdf_status;
+	uint8_t peer_id;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *peer, *pdev;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		pe_err("pdev is NULL");
+		return;
+	}
+
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
+			   body_ptr, frame_len);
+
+	addba_req = qdf_mem_malloc(sizeof(*addba_req));
+	if (!addba_req)
+		return;
+
+	/* Unpack ADDBA request frame */
+	status = dot11f_unpack_addba_req(mac_ctx, body_ptr, frame_len,
+					 addba_req, false);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
+			status, frame_len);
+		goto error;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("warning: unpack addba Req(0x%08x, %d bytes)",
+			status, frame_len);
+	}
+
+	peer = cdp_peer_get_ref_by_addr(soc, pdev, mac_hdr->sa, &peer_id,
+					PEER_DEBUG_ID_WMA_ADDBA_REQ);
+	if (!peer) {
+		pe_err("PEER [%pM] not found", mac_hdr->sa);
+		goto error;
+	}
+
+	qdf_status = cdp_addba_requestprocess(soc, peer,
+			addba_req->DialogToken.token,
+			addba_req->addba_param_set.tid,
+			addba_req->ba_timeout.timeout,
+			addba_req->addba_param_set.buff_size,
+			addba_req->ba_start_seq_ctrl.ssn);
+
+	cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_ADDBA_REQ);
+
+	if (QDF_STATUS_SUCCESS == qdf_status) {
+		lim_send_addba_response_frame(mac_ctx, mac_hdr->sa,
+			addba_req->addba_param_set.tid, session,
+			addba_req->addba_extn_element.present,
+			addba_req->addba_param_set.amsdu_supp);
+	} else {
+		pe_err("Failed to process addba request");
+	}
+
+error:
+	qdf_mem_free(addba_req);
+	return;
+}
+
+/**
+ * lim_process_delba_req() - process DELBA Request
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_pkt_info: A pointer to packet info structure
+ * @session: PE session pointer
+ *
+ * This routine will be called to process ADDBA request action frame
+ *
+ * Return: None
+ */
+static void lim_process_delba_req(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+				  tpPESession session)
+{
+	tpSirMacMgmtHdr mac_hdr;
+	uint8_t *body_ptr;
+	tDot11fdelba_req *delba_req;
+	uint32_t frame_len, status;
+	QDF_STATUS qdf_status;
+	uint8_t peer_id;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *peer, *pdev;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		pe_err("pdev is NULL");
+		return;
+	}
+
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
+			   body_ptr, frame_len);
+
+	delba_req = qdf_mem_malloc(sizeof(*delba_req));
+	if (!delba_req)
+		return;
+
+	/* Unpack DELBA request frame */
+	status = dot11f_unpack_delba_req(mac_ctx, body_ptr, frame_len,
+					 delba_req, false);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
+			status, frame_len);
+		goto error;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("warning: unpack addba Req(0x%08x, %d bytes)",
+			status, frame_len);
+	}
+
+	peer = cdp_peer_get_ref_by_addr(soc, pdev, mac_hdr->sa, &peer_id,
+					PEER_DEBUG_ID_WMA_DELBA_REQ);
+	if (!peer) {
+		pe_err("PEER [%pM] not found", mac_hdr->sa);
+		goto error;
+	}
+
+	qdf_status = cdp_delba_process(soc, peer,
+			delba_req->delba_param_set.tid, delba_req->Reason.code);
+
+	cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_DELBA_REQ);
+
+	if (QDF_STATUS_SUCCESS != qdf_status)
+		pe_err("Failed to process delba request");
+
+error:
+	qdf_mem_free(delba_req);
+	return;
+}
+
+/**
+ * lim_process_action_frame() - to process action frames
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_pkt_info: A pointer to packet info structure
+ *
+ * This function is called by limProcessMessageQueue() upon
+ * Action frame reception.
+ *
+ * Return: none
+ */
+
+void lim_process_action_frame(tpAniSirGlobal mac_ctx,
+		uint8_t *rx_pkt_info, tpPESession session)
+{
+	uint8_t *body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	tpSirMacActionFrameHdr action_hdr = (tpSirMacActionFrameHdr) body_ptr;
+#ifdef WLAN_FEATURE_11W
+	tpSirMacMgmtHdr mac_hdr_11w = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+#endif
+	tpSirMacMgmtHdr mac_hdr = NULL;
+	int8_t rssi;
+	uint32_t frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+	tpSirMacVendorSpecificFrameHdr vendor_specific;
+	uint8_t oui[] = { 0x00, 0x00, 0xf0 };
+	uint8_t dpp_oui[] = { 0x50, 0x6F, 0x9A, 0x1A };
+	tpSirMacVendorSpecificPublicActionFrameHdr pub_action;
+
+	if (frame_len < sizeof(*action_hdr)) {
+		pe_debug("frame_len %d less than Action Frame Hdr size",
+			 frame_len);
+		return;
+	}
+
+#ifdef WLAN_FEATURE_11W
+	if (lim_is_robust_mgmt_action_frame(action_hdr->category) &&
+	   lim_drop_unprotected_action_frame(mac_ctx, session,
+			mac_hdr_11w, action_hdr->category))
+		return;
+#endif
+
+	switch (action_hdr->category) {
+	case SIR_MAC_ACTION_QOS_MGMT:
+		if ((session->limQosEnabled) ||
+		    (action_hdr->actionID == SIR_MAC_QOS_MAP_CONFIGURE)) {
+			switch (action_hdr->actionID) {
+			case SIR_MAC_QOS_ADD_TS_REQ:
+				__lim_process_add_ts_req(mac_ctx,
+						(uint8_t *) rx_pkt_info,
+						session);
+				break;
+
+			case SIR_MAC_QOS_ADD_TS_RSP:
+				__lim_process_add_ts_rsp(mac_ctx,
+						 (uint8_t *) rx_pkt_info,
+						 session);
+				break;
+
+			case SIR_MAC_QOS_DEL_TS_REQ:
+				__lim_process_del_ts_req(mac_ctx,
+						(uint8_t *) rx_pkt_info,
+						session);
+				break;
+
+			case SIR_MAC_QOS_MAP_CONFIGURE:
+				__lim_process_qos_map_configure_frame(mac_ctx,
+						(uint8_t *)rx_pkt_info,
+						session);
+				break;
+			default:
+				pe_warn("Qos action: %d not handled",
+					action_hdr->actionID);
+				break;
+			}
+			break;
+		}
+		break;
+
+	case SIR_MAC_ACTION_SPECTRUM_MGMT:
+		switch (action_hdr->actionID) {
+#ifdef ANI_SUPPORT_11H
+		case SIR_MAC_ACTION_MEASURE_REQUEST_ID:
+			if (session->lim11hEnable)
+				__lim_process_measurement_request_frame(mac_ctx,
+							rx_pkt_info,
+							session);
+			break;
+		case SIR_MAC_ACTION_TPC_REQUEST_ID:
+			if ((LIM_IS_STA_ROLE(session) ||
+				LIM_IS_AP_ROLE(session)) &&
+				session->lim11hEnable)
+					__lim_process_tpc_request_frame(mac_ctx,
+						rx_pkt_info, session);
+			break;
+#endif
+		case SIR_MAC_ACTION_CHANNEL_SWITCH_ID:
+			if (LIM_IS_STA_ROLE(session))
+				__lim_process_channel_switch_action_frame(
+					mac_ctx, rx_pkt_info, session);
+			break;
+		default:
+			pe_warn("Spectrum mgmt action id: %d not handled",
+				action_hdr->actionID);
+			break;
+		}
+		break;
+
+	case SIR_MAC_ACTION_WME:
+		if (!session->limWmeEnabled) {
+			pe_warn("WME mode disabled - dropping frame: %d",
+				action_hdr->actionID);
+			break;
+		}
+		switch (action_hdr->actionID) {
+		case SIR_MAC_QOS_ADD_TS_REQ:
+			__lim_process_add_ts_req(mac_ctx,
+				(uint8_t *) rx_pkt_info, session);
+			break;
+
+		case SIR_MAC_QOS_ADD_TS_RSP:
+			__lim_process_add_ts_rsp(mac_ctx,
+				(uint8_t *) rx_pkt_info, session);
+			break;
+
+		case SIR_MAC_QOS_DEL_TS_REQ:
+			__lim_process_del_ts_req(mac_ctx,
+				(uint8_t *) rx_pkt_info, session);
+			break;
+
+		case SIR_MAC_QOS_MAP_CONFIGURE:
+			__lim_process_qos_map_configure_frame(mac_ctx,
+				(uint8_t *)rx_pkt_info, session);
+			break;
+
+		default:
+			pe_warn("WME action: %d not handled",
+				action_hdr->actionID);
+			break;
+		}
+		break;
+
+	case SIR_MAC_ACTION_HT:
+		/** Type of HT Action to be performed*/
+		switch (action_hdr->actionID) {
+		case SIR_MAC_SM_POWER_SAVE:
+			if (LIM_IS_AP_ROLE(session))
+				__lim_process_sm_power_save_update(mac_ctx,
+						(uint8_t *)rx_pkt_info,
+						session);
+			break;
+		default:
+			pe_warn("Action ID: %d not handled in HT category",
+				action_hdr->actionID);
+			break;
+		}
+		break;
+
+	case SIR_MAC_ACTION_WNM:
+		pe_debug("WNM Action category: %d action: %d",
+			action_hdr->category, action_hdr->actionID);
+		switch (action_hdr->actionID) {
+		case SIR_MAC_WNM_BSS_TM_QUERY:
+		case SIR_MAC_WNM_BSS_TM_REQUEST:
+		case SIR_MAC_WNM_BSS_TM_RESPONSE:
+		case SIR_MAC_WNM_NOTIF_REQUEST:
+		case SIR_MAC_WNM_NOTIF_RESPONSE:
+			rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
+			mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+			/* Forward to the SME to HDD to wpa_supplicant */
+			lim_send_sme_mgmt_frame_ind(mac_ctx,
+					mac_hdr->fc.subType,
+					(uint8_t *) mac_hdr,
+					frame_len + sizeof(tSirMacMgmtHdr),
+					session->smeSessionId,
+					WMA_GET_RX_CH(rx_pkt_info),
+					session, rssi);
+			break;
+		default:
+			pe_debug("Action ID: %d not handled in WNM category",
+				action_hdr->actionID);
+			break;
+		}
+		break;
+
+	case SIR_MAC_ACTION_RRM:
+		/* Ignore RRM measurement request until DHCP is set */
+		if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
+		    mac_ctx->roam.roamSession
+		    [session->smeSessionId].dhcp_done) {
+			switch (action_hdr->actionID) {
+			case SIR_MAC_RRM_RADIO_MEASURE_REQ:
+				__lim_process_radio_measure_request(mac_ctx,
+						(uint8_t *)rx_pkt_info,
+						session);
+				break;
+			case SIR_MAC_RRM_LINK_MEASUREMENT_REQ:
+				if (!lim_is_valid_frame(
+					&rrm_link_action_frm,
+					rx_pkt_info))
+					break;
+
+				if (__lim_process_link_measurement_req(
+						mac_ctx,
+						(uint8_t *)rx_pkt_info,
+						session) == QDF_STATUS_SUCCESS)
+					lim_update_last_processed_frame(
+							&rrm_link_action_frm,
+							rx_pkt_info);
+
+				break;
+			case SIR_MAC_RRM_NEIGHBOR_RPT:
+				__lim_process_neighbor_report(mac_ctx,
+						(uint8_t *)rx_pkt_info,
+						session);
+				break;
+			default:
+				pe_warn("Action ID: %d not handled in RRM",
+					action_hdr->actionID);
+				break;
+
+			}
+		} else {
+			/* Else we will just ignore the RRM messages. */
+			pe_debug("RRM frm ignored, it is disabled in cfg: %d or DHCP not completed: %d",
+			  mac_ctx->rrm.rrmPEContext.rrmEnable,
+			  mac_ctx->roam.roamSession
+			  [session->smeSessionId].dhcp_done);
+		}
+		break;
+
+	case SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY:
+		vendor_specific = (tpSirMacVendorSpecificFrameHdr) action_hdr;
+		mac_hdr = NULL;
+
+		mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+
+		if (frame_len < sizeof(*vendor_specific)) {
+			pe_debug("frame len %d less than Vendor Specific Hdr len",
+				 frame_len);
+			return;
+		}
+
+		/* Check if it is a vendor specific action frame. */
+		if (LIM_IS_STA_ROLE(session) &&
+		    (!qdf_mem_cmp(session->selfMacAddr,
+					&mac_hdr->da[0], sizeof(tSirMacAddr)))
+		    && IS_WES_MODE_ENABLED(mac_ctx)
+		    && !qdf_mem_cmp(vendor_specific->Oui, oui, 3)) {
+			pe_debug("Rcvd Vendor specific frame OUI: %x %x %x",
+				vendor_specific->Oui[0],
+				vendor_specific->Oui[1],
+				vendor_specific->Oui[2]);
+			/*
+			 * Forward to the SME to HDD to wpa_supplicant
+			 * type is ACTION
+			 */
+			lim_send_sme_mgmt_frame_ind(mac_ctx,
+					mac_hdr->fc.subType,
+					(uint8_t *) mac_hdr,
+					frame_len +
+					sizeof(tSirMacMgmtHdr),
+					session->smeSessionId,
+					WMA_GET_RX_CH(rx_pkt_info),
+					session,
+					WMA_GET_RX_RSSI_NORMALIZED(
+					rx_pkt_info));
+		} else {
+			pe_debug("Dropping the vendor specific action frame"
+					"beacause of (WES Mode not enabled "
+					"(WESMODE: %d) or OUI mismatch "
+					"(%02x %02x %02x) or not received with"
+					"SelfSta address) system role: %d",
+				IS_WES_MODE_ENABLED(mac_ctx),
+				vendor_specific->Oui[0],
+				vendor_specific->Oui[1],
+				vendor_specific->Oui[2],
+				GET_LIM_SYSTEM_ROLE(session));
+		}
+	break;
+	case SIR_MAC_ACTION_PUBLIC_USAGE:
+		mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+
+		switch (action_hdr->actionID) {
+		case SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID:
+			lim_process_ext_channel_switch_action_frame(mac_ctx,
+							rx_pkt_info, session);
+			break;
+		case SIR_MAC_ACTION_VENDOR_SPECIFIC:
+			pub_action =
+				(tpSirMacVendorSpecificPublicActionFrameHdr)
+				action_hdr;
+			if (frame_len < sizeof(*pub_action)) {
+				pe_debug("Received vendor specific public action frame of invalid len %d",
+					 frame_len);
+				return;
+			}
+			/*
+			 * Check if it is a DPP public action frame and fall
+			 * thru, else drop the frame.
+			 */
+			if (qdf_mem_cmp(pub_action->Oui, dpp_oui, 4)) {
+				pe_debug("Unhandled public action frame (Vendor specific) OUI: %x %x %x %x",
+					pub_action->Oui[0], pub_action->Oui[1],
+					pub_action->Oui[2], pub_action->Oui[3]);
+				break;
+			}
+			/* Fall through to send the frame to supplicant */
+		case SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY:
+		case SIR_MAC_ACTION_2040_BSS_COEXISTENCE:
+		case SIR_MAC_ACTION_GAS_INITIAL_REQUEST:
+		case SIR_MAC_ACTION_GAS_INITIAL_RESPONSE:
+		case SIR_MAC_ACTION_GAS_COMEBACK_REQUEST:
+		case SIR_MAC_ACTION_GAS_COMEBACK_RESPONSE:
+			/*
+			 * Forward to the SME to HDD to wpa_supplicant
+			 * type is ACTION
+			 */
+			lim_send_sme_mgmt_frame_ind(mac_ctx,
+					mac_hdr->fc.subType,
+					(uint8_t *) mac_hdr,
+					frame_len + sizeof(tSirMacMgmtHdr),
+					session->smeSessionId,
+					WMA_GET_RX_CH(rx_pkt_info), session,
+					WMA_GET_RX_RSSI_NORMALIZED(
+					rx_pkt_info));
+			break;
+		default:
+			pe_warn("Unhandled public action frame: %x",
+				action_hdr->actionID);
+			break;
+		}
+		break;
+
+#ifdef WLAN_FEATURE_11W
+	case SIR_MAC_ACTION_SA_QUERY:
+		pe_debug("SA Query Action category: %d action: %d",
+			action_hdr->category, action_hdr->actionID);
+		switch (action_hdr->actionID) {
+		case SIR_MAC_SA_QUERY_REQ:
+			/**11w SA query request action frame received**/
+			/* Respond directly to the incoming request in LIM */
+			__lim_process_sa_query_request_action_frame(mac_ctx,
+						(uint8_t *)rx_pkt_info,
+						session);
+			break;
+		case SIR_MAC_SA_QUERY_RSP:
+			/**11w SA query response action frame received**/
+			/* Handle based on the current SA Query state */
+			__lim_process_sa_query_response_action_frame(mac_ctx,
+						(uint8_t *)rx_pkt_info,
+						session);
+			break;
+		default:
+			break;
+		}
+		break;
+#endif
+	case SIR_MAC_ACTION_VHT:
+		if (!session->vhtCapability)
+			break;
+		switch (action_hdr->actionID) {
+		case SIR_MAC_VHT_OPMODE_NOTIFICATION:
+			__lim_process_operating_mode_action_frame(mac_ctx,
+					rx_pkt_info, session);
+			break;
+		case SIR_MAC_VHT_GID_NOTIFICATION:
+			/* Only if ini supports it */
+			if (session->enableVhtGid)
+				__lim_process_gid_management_action_frame(
+					mac_ctx, rx_pkt_info, session);
+			break;
+		default:
+			break;
+		}
+		break;
+	case SIR_MAC_ACTION_FST: {
+		tpSirMacMgmtHdr     hdr;
+
+		hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+
+		pe_debug("Received FST MGMT action frame");
+		/* Forward to the SME to HDD */
+		lim_send_sme_mgmt_frame_ind(mac_ctx, hdr->fc.subType,
+					    (uint8_t *)hdr,
+					    frame_len + sizeof(tSirMacMgmtHdr),
+					    session->smeSessionId,
+					    WMA_GET_RX_CH(rx_pkt_info),
+					    session,
+					    WMA_GET_RX_RSSI_NORMALIZED(
+					    rx_pkt_info));
+		break;
+	}
+	case SIR_MAC_ACTION_PROT_DUAL_PUB:
+		pe_debug("Rcvd Protected Dual of Public Action: %d",
+			action_hdr->actionID);
+		switch (action_hdr->actionID) {
+		case SIR_MAC_PDPA_GAS_INIT_REQ:
+		case SIR_MAC_PDPA_GAS_INIT_RSP:
+		case SIR_MAC_PDPA_GAS_COMEBACK_REQ:
+		case SIR_MAC_PDPA_GAS_COMEBACK_RSP:
+			mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+			rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
+			lim_send_sme_mgmt_frame_ind(mac_ctx,
+				mac_hdr->fc.subType, (uint8_t *) mac_hdr,
+				frame_len + sizeof(tSirMacMgmtHdr),
+				session->smeSessionId,
+				WMA_GET_RX_CH(rx_pkt_info), session, rssi);
+			break;
+		default:
+			pe_warn("Unhandled - Protected Dual Public Action");
+			break;
+		}
+		break;
+	case SIR_MAC_ACTION_BLKACK:
+		pe_debug("Rcvd Block Ack for %pM; action: %d",
+			session->selfMacAddr, action_hdr->actionID);
+		switch (action_hdr->actionID) {
+		case SIR_MAC_ADDBA_REQ:
+			lim_process_addba_req(mac_ctx, rx_pkt_info, session);
+			break;
+		case SIR_MAC_DELBA_REQ:
+			lim_process_delba_req(mac_ctx, rx_pkt_info, session);
+			break;
+		default:
+			pe_err("Unhandle BA action frame");
+			break;
+		}
+		break;
+	default:
+		pe_warn("Action category: %d not handled",
+			action_hdr->category);
+		break;
+	}
+}
+
+/**
+ * lim_process_action_frame_no_session
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Action frame reception and no session.
+ * Currently only public action frames can be received from
+ * a non-associated station.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  *pBd - A pointer to Buffer descriptor + associated PDUs
+ * @return None
+ */
+void lim_process_action_frame_no_session(tpAniSirGlobal pMac, uint8_t *pBd)
+{
+	tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(pBd);
+	uint32_t frame_len = WMA_GET_RX_PAYLOAD_LEN(pBd);
+	uint8_t *pBody = WMA_GET_RX_MPDU_DATA(pBd);
+	uint8_t dpp_oui[] = { 0x50, 0x6F, 0x9A, 0x1A };
+	tpSirMacActionFrameHdr action_hdr = (tpSirMacActionFrameHdr) pBody;
+	tpSirMacVendorSpecificPublicActionFrameHdr vendor_specific;
+
+	pe_debug("Received an Action frame -- no session");
+
+	if (frame_len < sizeof(*action_hdr)) {
+		pe_debug("frame_len %d less than action frame header len",
+			 frame_len);
+		return;
+	}
+
+	switch (action_hdr->category) {
+	case SIR_MAC_ACTION_PUBLIC_USAGE:
+		switch (action_hdr->actionID) {
+		case SIR_MAC_ACTION_VENDOR_SPECIFIC:
+			vendor_specific =
+				(tpSirMacVendorSpecificPublicActionFrameHdr)
+				action_hdr;
+
+			if (frame_len < sizeof(*vendor_specific)) {
+				pe_debug("Received vendor specific public action frame of invalid len %d",
+					 frame_len);
+				return;
+			}
+			/*
+			 * Check if it is a DPP public action frame and fall
+			 * thru, else drop the frame.
+			 */
+			if (qdf_mem_cmp(vendor_specific->Oui, dpp_oui, 4)) {
+				pe_debug("Unhandled public action frame (Vendor specific) OUI: %x %x %x %x",
+					vendor_specific->Oui[0],
+					vendor_specific->Oui[1],
+					vendor_specific->Oui[2],
+					vendor_specific->Oui[3]);
+				break;
+			}
+			/* Fall through to send the frame to supplicant */
+		case SIR_MAC_ACTION_GAS_INITIAL_REQUEST:
+		case SIR_MAC_ACTION_GAS_INITIAL_RESPONSE:
+		case SIR_MAC_ACTION_GAS_COMEBACK_REQUEST:
+		case SIR_MAC_ACTION_GAS_COMEBACK_RESPONSE:
+			/*
+			 * Forward the GAS frames to  wpa_supplicant
+			 * type is ACTION
+			 */
+			lim_send_sme_mgmt_frame_ind(pMac,
+					mac_hdr->fc.subType,
+					(uint8_t *) mac_hdr,
+					frame_len + sizeof(tSirMacMgmtHdr), 0,
+					WMA_GET_RX_CH(pBd), NULL,
+					WMA_GET_RX_RSSI_NORMALIZED(pBd));
+			break;
+		default:
+			pe_warn("Unhandled public action frame: %x",
+				       action_hdr->actionID);
+			break;
+		}
+		break;
+	default:
+		pe_warn("Unhandled action frame without session: %x",
+			       action_hdr->category);
+		break;
+
+	}
+}
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
new file mode 100644
index 0000000..c33d293
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
@@ -0,0 +1,2525 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file lim_process_assoc_req_frame.c contains the code
+ * for processing Re/Association Request Frame.
+ */
+#include "cds_api.h"
+#include "ani_global.h"
+#include "wni_cfg.h"
+#include "sir_api.h"
+#include "cfg_api.h"
+#include "cfg_ucfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_sta_hash_api.h"
+#include "lim_admit_control.h"
+#include "cds_packet.h"
+#include "lim_session_utils.h"
+
+#include "qdf_types.h"
+#include "cds_utils.h"
+#include "wlan_utility.h"
+
+/**
+ * lim_convert_supported_channels - Parses channel support IE
+ * @mac_ctx: A pointer to Global MAC structure
+ * @assoc_ind: A pointer to SME ASSOC/REASSOC IND
+ * @assoc_req: A pointer to ASSOC/REASSOC Request frame
+ *
+ * This function is called by lim_process_assoc_req_frame() to
+ * parse the channel support IE in the Assoc/Reassoc Request
+ * frame, and send relevant information in the SME_ASSOC_IND
+ *
+ * Return: None
+ */
+static void lim_convert_supported_channels(tpAniSirGlobal mac_ctx,
+					   tpLimMlmAssocInd assoc_ind,
+					   tSirAssocReq *assoc_req)
+{
+	uint16_t i, j, index = 0;
+	uint8_t first_ch_no;
+	uint8_t chn_count;
+	uint8_t next_ch_no;
+	uint8_t channel_offset = 0;
+
+	if (assoc_req->supportedChannels.length >=
+		SIR_MAX_SUPPORTED_CHANNEL_LIST) {
+		pe_err("Number of supported channels: %d is more than MAX",
+			assoc_req->supportedChannels.length);
+		assoc_ind->supportedChannels.numChnl = 0;
+		return;
+	}
+
+	for (i = 0; i < (assoc_req->supportedChannels.length); i++) {
+		/* Get First Channel Number */
+		first_ch_no = assoc_req->supportedChannels.supportedChannels[i];
+		assoc_ind->supportedChannels.channelList[index] = first_ch_no;
+		i++;
+		index++;
+
+		/* Get Number of Channels in a Subband */
+		chn_count = assoc_req->supportedChannels.supportedChannels[i];
+		pe_debug("Rcv assoc_req: chnl: %d numOfChnl: %d",
+			first_ch_no, chn_count);
+		if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) {
+			pe_warn("Ch count > max supported: %d", chn_count);
+			assoc_ind->supportedChannels.numChnl = 0;
+			return;
+		}
+		if (chn_count <= 1)
+			continue;
+		next_ch_no = first_ch_no;
+		if (BAND_5G == lim_get_rf_band(first_ch_no))
+			channel_offset =  SIR_11A_FREQUENCY_OFFSET;
+		else if (BAND_2G == lim_get_rf_band(first_ch_no))
+			channel_offset = SIR_11B_FREQUENCY_OFFSET;
+		else
+			continue;
+
+		for (j = 1; j < chn_count; j++) {
+			next_ch_no += channel_offset;
+			assoc_ind->supportedChannels.channelList[index]
+				= next_ch_no;
+			index++;
+			if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) {
+				pe_warn("Ch count > supported: %d", chn_count);
+				assoc_ind->supportedChannels.numChnl = 0;
+				return;
+			}
+		}
+	}
+
+	assoc_ind->supportedChannels.numChnl = (uint8_t) index;
+	pe_debug("Send AssocInd to WSM: minPwr: %d maxPwr: %d numChnl: %d",
+		assoc_ind->powerCap.minTxPower,
+		assoc_ind->powerCap.maxTxPower,
+		assoc_ind->supportedChannels.numChnl);
+}
+
+/**
+ * lim_check_sta_in_pe_entries() - checks if sta exists in any dph tables.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @hdr: A pointer to the MAC header
+ * @sessionid - session id for which session is initiated
+ *
+ * This function is called by lim_process_assoc_req_frame() to check if STA
+ * entry already exists in any of the PE entries of the AP. If it exists, deauth
+ * will be sent on that session and the STA deletion will happen. After this,
+ * the ASSOC request will be processed
+ *
+ * Return: True if duplicate entry found; FALSE otherwise.
+ */
+static bool lim_check_sta_in_pe_entries(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+				 uint16_t sessionid)
+{
+	uint8_t i;
+	uint16_t assoc_id = 0;
+	tpDphHashNode sta_ds = NULL;
+	tpPESession session = NULL;
+	bool dup_entry = false;
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		if ((&mac_ctx->lim.gpSession[i] != NULL) &&
+		    (mac_ctx->lim.gpSession[i].valid) &&
+		    (mac_ctx->lim.gpSession[i].pePersona == QDF_SAP_MODE)) {
+			session = &mac_ctx->lim.gpSession[i];
+			sta_ds = dph_lookup_hash_entry(mac_ctx, hdr->sa,
+					&assoc_id, &session->dph.dphHashTable);
+			if (sta_ds
+#ifdef WLAN_FEATURE_11W
+				&& (!sta_ds->rmfEnabled ||
+				    (sessionid != session->peSessionId))
+#endif
+			    ) {
+				pe_err("Sending Disassoc and Deleting existing STA entry:"
+					   MAC_ADDRESS_STR,
+					MAC_ADDR_ARRAY(session->selfMacAddr));
+				lim_send_disassoc_mgmt_frame(mac_ctx,
+					eSIR_MAC_UNSPEC_FAILURE_REASON,
+					(uint8_t *) hdr->sa, session, false);
+				/*
+				 * Cleanup Rx path posts eWNI_SME_DISASSOC_RSP
+				 * msg to SME after delete sta which will update
+				 * the userspace with disconnect
+				 */
+				sta_ds->mlmStaContext.cleanupTrigger =
+							eLIM_DUPLICATE_ENTRY;
+				sta_ds->mlmStaContext.disassocReason =
+				eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
+				lim_send_sme_disassoc_ind(mac_ctx, sta_ds,
+					session);
+				dup_entry = true;
+				break;
+			}
+		}
+	}
+	return dup_entry;
+}
+
+/**
+ * lim_chk_sa_da() - checks source addr to destination addr of assoc req frame
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ *
+ * Checks source addr to destination addr of assoc req frame
+ *
+ * Return: true if source and destination address are different
+ */
+static bool lim_chk_sa_da(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			  tpPESession session, uint8_t sub_type)
+{
+	if (qdf_mem_cmp((uint8_t *) hdr->sa,
+					(uint8_t *) hdr->da,
+					(uint8_t) (sizeof(tSirMacAddr))))
+		return true;
+
+	pe_err("Assoc Req rejected: wlan.sa = wlan.da");
+	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				      1, hdr->sa, sub_type, 0, session);
+	return false;
+}
+
+/**
+ * lim_chk_tkip() - checks TKIP counter measure is active
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ *
+ * Checks TKIP counter measure is active
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_chk_tkip(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			 tpPESession session, uint8_t sub_type)
+{
+	/*
+	 * If TKIP counter measures active send Assoc Rsp frame to station
+	 * with eSIR_MAC_MIC_FAILURE_REASON
+	 */
+	if (!(session->bTkipCntrMeasActive && LIM_IS_AP_ROLE(session)))
+		return true;
+
+	pe_err("Assoc Req rejected: TKIP counter measure is active");
+	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_MIC_FAILURE_REASON, 1,
+				      hdr->sa, sub_type, 0, session);
+	return false;
+}
+
+/**
+ * lim_chk_assoc_req_parse_error() - checks for error in frame parsing
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ * @frm_body: frame body
+ * @frame_len: frame len
+ *
+ * Checks for error in frame parsing
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_chk_assoc_req_parse_error(tpAniSirGlobal mac_ctx,
+					  tpSirMacMgmtHdr hdr,
+					  tpPESession session,
+					  tpSirAssocReq assoc_req,
+					  uint8_t sub_type, uint8_t *frm_body,
+					  uint32_t frame_len)
+{
+	QDF_STATUS status;
+
+	if (sub_type == LIM_ASSOC)
+		status = sir_convert_assoc_req_frame2_struct(mac_ctx, frm_body,
+							frame_len, assoc_req);
+	else
+		status = sir_convert_reassoc_req_frame2_struct(mac_ctx,
+						frm_body, frame_len, assoc_req);
+
+	if (status == QDF_STATUS_SUCCESS)
+		return true;
+
+	pe_warn("Assoc Req rejected: frame parsing error. source addr:"
+			MAC_ADDRESS_STR, MAC_ADDR_ARRAY(hdr->sa));
+	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				      1, hdr->sa, sub_type, 0, session);
+	return false;
+}
+
+/**
+ * lim_chk_capab() - checks for capab match
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ * @local_cap: local capabilities of SAP
+ *
+ * Checks for capab match
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_chk_capab(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			  tpPESession session, tpSirAssocReq assoc_req,
+			  uint8_t sub_type, tSirMacCapabilityInfo *local_cap)
+{
+	uint16_t temp;
+
+	if (cfg_get_capability_info(mac_ctx, &temp, session) != QDF_STATUS_SUCCESS) {
+		pe_err("could not retrieve Capabilities");
+		return false;
+	}
+
+	lim_copy_u16((uint8_t *) local_cap, temp);
+
+	if (lim_compare_capabilities(mac_ctx, assoc_req,
+				     local_cap, session) == false) {
+		pe_warn("Rcvd %s Req with unsupported capab from"
+				MAC_ADDRESS_STR,
+			(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
+			MAC_ADDR_ARRAY(hdr->sa));
+		/*
+		 * Capabilities of requesting STA does not match with
+		 * local capabilities. Respond with 'unsupported capabilities'
+		 * status code.
+		 */
+		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+			1, hdr->sa, sub_type, 0, session);
+		return false;
+	}
+	return true;
+}
+
+/**
+ * lim_chk_ssid() - checks for SSID match
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ *
+ * Checks for SSID match
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_chk_ssid(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			 tpPESession session, tpSirAssocReq assoc_req,
+			 uint8_t sub_type)
+{
+	if (lim_cmp_ssid(&assoc_req->ssId, session) != true)
+		return true;
+
+	pe_err("%s Req with ssid wrong(Rcvd: %.*s self: %.*s) from "
+			MAC_ADDRESS_STR,
+		(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
+		assoc_req->ssId.length, assoc_req->ssId.ssId,
+		session->ssId.length, session->ssId.ssId,
+		MAC_ADDR_ARRAY(hdr->sa));
+
+	/*
+	 * Received Re/Association Request with either Broadcast SSID OR with
+	 * SSID that does not match with local one. Respond with unspecified
+	 * status code.
+	 */
+	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				      1, hdr->sa, sub_type, 0, session);
+	return false;
+}
+
+/**
+ * lim_chk_rates() - checks for supported rates
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ *
+ * Checks for supported rates
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_chk_rates(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			  tpPESession session, tpSirAssocReq assoc_req,
+			  uint8_t sub_type)
+{
+	uint8_t i = 0, j = 0;
+	tSirMacRateSet basic_rates;
+	/*
+	 * Verify if the requested rates are available in supported rate
+	 * set or Extended rate set. Some APs are adding basic rates in
+	 * Extended rateset IE
+	 */
+	basic_rates.numRates = 0;
+
+	for (i = 0; i < assoc_req->supportedRates.numRates
+			&& (i < SIR_MAC_RATESET_EID_MAX); i++) {
+		basic_rates.rate[i] = assoc_req->supportedRates.rate[i];
+		basic_rates.numRates++;
+	}
+
+	for (j = 0; (j < assoc_req->extendedRates.numRates)
+			&& (i < SIR_MAC_RATESET_EID_MAX); i++, j++) {
+		basic_rates.rate[i] = assoc_req->extendedRates.rate[j];
+		basic_rates.numRates++;
+	}
+
+	if (lim_check_rx_basic_rates(mac_ctx, basic_rates, session) == true)
+		return true;
+
+	pe_warn("Assoc Req rejected: unsupported rates, soruce addr: %s"
+			MAC_ADDRESS_STR,
+		(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
+		MAC_ADDR_ARRAY(hdr->sa));
+	/*
+	 * Requesting STA does not support ALL BSS basic rates. Respond with
+	 * 'basic rates not supported' status code.
+	 */
+	lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+				eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, 1,
+				hdr->sa, sub_type, 0, session);
+	return false;
+}
+
+/**
+ * lim_chk_11g_only() - checks for non 11g STA
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ *
+ * Checks for non 11g STA
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_chk_11g_only(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			     tpPESession session, tpSirAssocReq assoc_req,
+			     uint8_t sub_type)
+{
+	if (LIM_IS_AP_ROLE(session) &&
+	    (session->dot11mode == WNI_CFG_DOT11_MODE_11G_ONLY) &&
+	    (assoc_req->HTCaps.present)) {
+		pe_err("SOFTAP was in 11G only mode, rejecting legacy STA: "
+				MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(hdr->sa));
+		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+				eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+				1, hdr->sa, sub_type, 0, session);
+		return false;
+	}
+	return true;
+}
+
+/**
+ * lim_chk_11n_only() - checks for non 11n STA
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ *
+ * Checks for non 11n STA
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_chk_11n_only(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			     tpPESession session, tpSirAssocReq assoc_req,
+			     uint8_t sub_type)
+{
+	if (LIM_IS_AP_ROLE(session) &&
+	    (session->dot11mode == WNI_CFG_DOT11_MODE_11N_ONLY) &&
+	    (!assoc_req->HTCaps.present)) {
+		pe_err("SOFTAP was in 11N only mode, rejecting legacy STA: "
+				MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(hdr->sa));
+		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+			1, hdr->sa, sub_type, 0, session);
+		return false;
+	}
+	return true;
+}
+
+/**
+ * lim_chk_11ac_only() - checks for non 11ac STA
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ *
+ * Checks for non 11ac STA
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_chk_11ac_only(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			      tpPESession session, tpSirAssocReq assoc_req,
+			      uint8_t sub_type)
+{
+	tDot11fIEVHTCaps *vht_caps;
+
+	if (assoc_req->VHTCaps.present)
+		vht_caps = &assoc_req->VHTCaps;
+	else if (assoc_req->vendor_vht_ie.VHTCaps.present &&
+		 session->vendor_vht_sap)
+		vht_caps = &assoc_req->vendor_vht_ie.VHTCaps;
+	else
+		vht_caps = NULL;
+
+	if (LIM_IS_AP_ROLE(session) &&
+		(session->dot11mode == WNI_CFG_DOT11_MODE_11AC_ONLY) &&
+		((vht_caps == NULL) || ((vht_caps != NULL) && (!vht_caps->present)))) {
+		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+			1, hdr->sa, sub_type, 0, session);
+		pe_err("SOFTAP was in 11AC only mode, reject");
+		return false;
+	}
+	return true;
+}
+
+/**
+ * lim_chk_11ax_only() - checks for non 11ax STA
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ *
+ * Checks for non 11ax STA
+ *
+ * Return: true of no error, false otherwise
+ */
+#ifdef WLAN_FEATURE_11AX
+static bool lim_chk_11ax_only(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			      tpPESession session, tpSirAssocReq assoc_req,
+			      uint8_t sub_type)
+{
+	if (LIM_IS_AP_ROLE(session) &&
+		(session->dot11mode == WNI_CFG_DOT11_MODE_11AX_ONLY) &&
+		 !assoc_req->he_cap.present) {
+		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+			1, hdr->sa, sub_type, 0, session);
+		pe_err("SOFTAP was in 11AX only mode, reject");
+		return false;
+	}
+	return true;
+}
+
+/**
+ * lim_check_11ax_basic_mcs() - checks for 11ax basic MCS rates
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ *
+ * Checks for non 11ax STA
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_check_11ax_basic_mcs(tpAniSirGlobal mac_ctx,
+				     tpSirMacMgmtHdr hdr,
+				     tpPESession session,
+				     tpSirAssocReq assoc_req,
+				     uint8_t sub_type)
+{
+	uint32_t val;
+	uint16_t basic_mcs, sta_mcs, rx_mcs, tx_mcs, final_mcs;
+
+	if (LIM_IS_AP_ROLE(session) &&
+	    assoc_req->he_cap.present) {
+		rx_mcs = assoc_req->he_cap.rx_he_mcs_map_lt_80;
+		tx_mcs = assoc_req->he_cap.tx_he_mcs_map_lt_80;
+		sta_mcs = HE_INTERSECT_MCS(rx_mcs, tx_mcs);
+		if (QDF_STATUS_SUCCESS != wlan_cfg_get_int(mac_ctx,
+				WNI_CFG_HE_OPS_BASIC_MCS_NSS, &val))
+			val = WNI_CFG_HE_OPS_BASIC_MCS_NSS_DEF;
+		basic_mcs = (uint16_t)val;
+		final_mcs = HE_INTERSECT_MCS(sta_mcs, basic_mcs);
+		if (final_mcs != basic_mcs) {
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+				eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+				1, hdr->sa, sub_type, 0, session);
+			pe_err("STA did not support basic MCS required by SAP");
+			return false;
+		}
+	}
+	return true;
+}
+#else
+static bool lim_chk_11ax_only(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			      tpPESession session, tpSirAssocReq assoc_req,
+			      uint8_t sub_type)
+{
+	return true;
+}
+
+static bool lim_check_11ax_basic_mcs(tpAniSirGlobal mac_ctx,
+				     tpSirMacMgmtHdr hdr,
+				     tpPESession session,
+				     tpSirAssocReq assoc_req,
+				     uint8_t sub_type)
+{
+	return true;
+}
+#endif
+
+/**
+ * lim_process_for_spectrum_mgmt() - process assoc req for spectrum mgmt
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ * @local_cap: local capabilities of SAP
+ *
+ * Checks for SSID match
+ *
+ * process assoc req for spectrum mgmt
+ */
+static void
+lim_process_for_spectrum_mgmt(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			      tpPESession session, tpSirAssocReq assoc_req,
+			      uint8_t sub_type, tSirMacCapabilityInfo local_cap)
+{
+	if (local_cap.spectrumMgt) {
+		QDF_STATUS status = QDF_STATUS_SUCCESS;
+		/*
+		 * If station is 11h capable, then it SHOULD send all mandatory
+		 * IEs in assoc request frame. Let us verify that
+		 */
+		if (assoc_req->capabilityInfo.spectrumMgt) {
+			if (!((assoc_req->powerCapabilityPresent)
+			     && (assoc_req->supportedChannelsPresent))) {
+				/*
+				 * One or more required information elements are
+				 * missing, log the peers error
+				 */
+				if (!assoc_req->powerCapabilityPresent) {
+					pe_warn("LIM Info: Missing Power capability IE in %s Req from "
+							MAC_ADDRESS_STR,
+						(LIM_ASSOC == sub_type) ?
+							"Assoc" : "ReAssoc",
+						MAC_ADDR_ARRAY(hdr->sa));
+				}
+				if (!assoc_req->supportedChannelsPresent) {
+					pe_warn("LIM Info: Missing Supported channel IE in %s Req from "
+							MAC_ADDRESS_STR,
+						(LIM_ASSOC == sub_type) ?
+							"Assoc" : "ReAssoc",
+						MAC_ADDR_ARRAY(hdr->sa));
+				}
+			} else {
+				/* Assoc request has mandatory fields */
+				status =
+				    lim_is_dot11h_power_capabilities_in_range(
+					mac_ctx, assoc_req, session);
+				if (QDF_STATUS_SUCCESS != status) {
+					pe_warn("LIM Info: MinTxPower(STA) > MaxTxPower(AP) in %s Req from "
+						MAC_ADDRESS_STR,
+						(LIM_ASSOC == sub_type) ?
+							"Assoc" : "ReAssoc",
+						MAC_ADDR_ARRAY(hdr->sa));
+				}
+				status = lim_is_dot11h_supported_channels_valid(
+							mac_ctx, assoc_req);
+				if (QDF_STATUS_SUCCESS != status) {
+					pe_warn("LIM Info: wrong supported channels (STA) in %s Req from "
+						MAC_ADDRESS_STR,
+						(LIM_ASSOC == sub_type) ?
+							"Assoc" : "ReAssoc",
+						MAC_ADDR_ARRAY(hdr->sa));
+				}
+				/* IEs are valid, use them if needed */
+			}
+		} /* if(assoc.capabilityInfo.spectrumMgt) */
+		else {
+			/*
+			 * As per the capabiities, the spectrum management is
+			 * not enabled on the station. The AP may allow the
+			 * associations to happen even if spectrum management
+			 * is not allowed, if the transmit power of station is
+			 * below the regulatory maximum
+			 */
+
+			/*
+			 * TODO: presently, this is not handled. In the current
+			 * implementation, the AP would allow the station to
+			 * associate even if it doesn't support spectrum
+			 * management.
+			 */
+		}
+	} /* end of spectrum management related processing */
+}
+
+/**
+ * lim_chk_mcs() - checks for supported MCS
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ *
+ * Checks for supported MCS
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_chk_mcs(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			tpPESession session, tpSirAssocReq assoc_req,
+			uint8_t sub_type)
+{
+	if ((assoc_req->HTCaps.present) && (lim_check_mcs_set(mac_ctx,
+			assoc_req->HTCaps.supportedMCSSet) == false)) {
+		pe_warn("rcvd %s req with unsupported MCS Rate Set from "
+				MAC_ADDRESS_STR,
+			(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
+			MAC_ADDR_ARRAY(hdr->sa));
+		/*
+		 * Requesting STA does not support ALL BSS MCS basic Rate set
+		 * rates. Spec does not define any status code for this
+		 * scenario.
+		 */
+		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+					eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
+					1, hdr->sa, sub_type, 0, session);
+		return false;
+	}
+	return true;
+}
+
+/**
+ * lim_chk_is_11b_sta_supported() - checks if STA is 11b
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ * @phy_mode: phy mode
+ *
+ * Checks if STA is 11b
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_chk_is_11b_sta_supported(tpAniSirGlobal mac_ctx,
+					 tpSirMacMgmtHdr hdr,
+					 tpPESession session,
+					 tpSirAssocReq assoc_req,
+					 uint8_t sub_type, uint32_t phy_mode)
+{
+	uint32_t cfg_11g_only;
+
+	if (phy_mode == WNI_CFG_PHY_MODE_11G) {
+		cfg_11g_only = mac_ctx->mlme_cfg->sap_cfg.sap_11g_policy;
+		if (!assoc_req->extendedRatesPresent && cfg_11g_only) {
+			/*
+			 * Received Re/Association Request from 11b STA when 11g
+			 * only policy option is set. Reject with unspecified
+			 * status code.
+			 */
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+				eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
+				1, hdr->sa, sub_type, 0, session);
+
+			pe_warn("Rejecting Re/Assoc req from 11b STA:");
+			lim_print_mac_addr(mac_ctx, hdr->sa, LOGW);
+
+#ifdef WLAN_DEBUG
+			mac_ctx->lim.gLim11bStaAssocRejectCount++;
+#endif
+			return false;
+		}
+	}
+	return true;
+}
+
+/**
+ * lim_print_ht_cap() - prints HT caps
+ * @mac_ctx: pointer to Global MAC structure
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ *
+ * Prints HT caps
+ *
+ * Return: void
+ */
+static void lim_print_ht_cap(tpAniSirGlobal mac_ctx, tpPESession session,
+			     tpSirAssocReq assoc_req)
+{
+	if (!session->htCapability)
+		return;
+
+	if (assoc_req->HTCaps.present) {
+		/* The station *does* support 802.11n HT capability... */
+		pe_debug("AdvCodingCap:%d ChaWidthSet:%d PowerSave:%d greenField:%d shortGI20:%d shortGI40:%d txSTBC:%d rxSTBC:%d delayBA:%d maxAMSDUsize:%d DSSS/CCK:%d  PSMP:%d stbcCntl:%d lsigTXProt:%d",
+			assoc_req->HTCaps.advCodingCap,
+			assoc_req->HTCaps.supportedChannelWidthSet,
+			assoc_req->HTCaps.mimoPowerSave,
+			assoc_req->HTCaps.greenField,
+			assoc_req->HTCaps.shortGI20MHz,
+			assoc_req->HTCaps.shortGI40MHz,
+			assoc_req->HTCaps.txSTBC,
+			assoc_req->HTCaps.rxSTBC,
+			assoc_req->HTCaps.delayedBA,
+			assoc_req->HTCaps.maximalAMSDUsize,
+			assoc_req->HTCaps.dsssCckMode40MHz,
+			assoc_req->HTCaps.psmp,
+			assoc_req->HTCaps.stbcControlFrame,
+			assoc_req->HTCaps.lsigTXOPProtection);
+		/*
+		 * Make sure the STA's caps are compatible with our own:
+		 * 11.15.2 Support of DSSS/CCK in 40 MHz the AP shall refuse
+		 * association requests from an HT STA that has the DSSS/CCK
+		 * Mode in 40 MHz subfield set to 1;
+		 */
+	}
+}
+
+/**
+  * lim_check_wpa_rsn_ie() - wpa and rsn ie related checks
+  * @session: pointer to pe session entry
+  * @mac_ctx: pointer to Global MAC structure
+  * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+  * @hdr: pointer to the MAC head
+  * @assoc_req: pointer to ASSOC/REASSOC Request frame
+  * @pmf_connection: flag indicating pmf connection
+  *
+  * This function checks if wpa/rsn IE is present and validates
+  * ie version, length and mismatch.
+  *
+  * Return: true if no error, false otherwise
+  */
+static bool lim_check_wpa_rsn_ie(tpPESession session, tpAniSirGlobal mac_ctx,
+				 uint8_t sub_type, tpSirMacMgmtHdr hdr,
+				 tpSirAssocReq assoc_req, bool *pmf_connection)
+{
+	uint32_t ret;
+	tDot11fIEWPA dot11f_ie_wpa = {0};
+	tDot11fIERSN dot11f_ie_rsn = {0};
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	/*
+	 * Clear the buffers so that frame parser knows that there isn't a
+	 * previously decoded IE in these buffers
+	 */
+	qdf_mem_set((uint8_t *) &dot11f_ie_rsn, sizeof(dot11f_ie_rsn), 0);
+	qdf_mem_set((uint8_t *) &dot11f_ie_wpa, sizeof(dot11f_ie_wpa), 0);
+	pe_err("RSN enabled auth, Re/Assoc req from STA: "
+		MAC_ADDRESS_STR, MAC_ADDR_ARRAY(hdr->sa));
+
+	if (assoc_req->rsnPresent) {
+		if (!(assoc_req->rsn.length)) {
+			pe_warn("Re/Assoc rejected from: "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(hdr->sa));
+			/*
+			 * rcvd Assoc req frame with RSN IE but
+			 * length is zero
+			 */
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+				eSIR_MAC_INVALID_IE_STATUS, 1,
+				hdr->sa, sub_type, 0, session);
+			return false;
+		}
+
+		/* Unpack the RSN IE */
+		ret = dot11f_unpack_ie_rsn(mac_ctx,
+					   &assoc_req->rsn.info[0],
+					   assoc_req->rsn.length,
+					   &dot11f_ie_rsn, false);
+		if (!DOT11F_SUCCEEDED(ret)) {
+			pe_err("Invalid RSN IE");
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1,
+				hdr->sa, sub_type, 0, session);
+			return false;
+		}
+
+		/* Check if the RSN version is supported */
+		if (SIR_MAC_OUI_VERSION_1 == dot11f_ie_rsn.version) {
+			/* check the groupwise and pairwise cipher suites */
+			status = lim_check_rx_rsn_ie_match(mac_ctx,
+					   &dot11f_ie_rsn, session,
+					   assoc_req->HTCaps.present,
+					   pmf_connection);
+			if (QDF_STATUS_SUCCESS != status) {
+				pe_warn("Re/Assoc rejected from: "
+					MAC_ADDRESS_STR,
+					MAC_ADDR_ARRAY(hdr->sa));
+
+				lim_send_assoc_rsp_mgmt_frame(mac_ctx, status,
+							 1, hdr->sa, sub_type,
+							 0, session);
+				return false;
+			}
+		} else {
+			pe_warn("Re/Assoc rejected from: " MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(hdr->sa));
+
+			/*
+			 * rcvd Assoc req frame with RSN IE but
+			 * IE version is wrong
+			 */
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+				eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS,
+				1, hdr->sa, sub_type, 0, session);
+			return false;
+		}
+	} else if (assoc_req->wpaPresent) {
+		if (!(assoc_req->wpa.length)) {
+			pe_warn("Re/Assoc rejected from: "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(hdr->sa));
+
+			/* rcvd Assoc req frame with invalid WPA IE length */
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+				eSIR_MAC_INVALID_IE_STATUS, 1,
+				hdr->sa, sub_type, 0, session);
+			return false;
+		}
+		/* Unpack the WPA IE */
+		ret = dot11f_unpack_ie_wpa(mac_ctx,
+					   &assoc_req->wpa.info[4],
+					   (assoc_req->wpa.length - 4),
+					   &dot11f_ie_wpa, false);
+		if (!DOT11F_SUCCEEDED(ret)) {
+			pe_err("Invalid WPA IE");
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1,
+				hdr->sa, sub_type, 0, session);
+			return false;
+		}
+
+		/* check the groupwise and pairwise cipher suites*/
+		status = lim_check_rx_wpa_ie_match(mac_ctx, dot11f_ie_wpa,
+					session, assoc_req->HTCaps.present);
+		if (QDF_STATUS_SUCCESS != status) {
+			pe_warn("Re/Assoc rejected from: "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(hdr->sa));
+
+			/*
+			 * rcvd Assoc req frame with WPA IE
+			 * but there is mismatch
+			 */
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx, status, 1,
+					hdr->sa, sub_type, 0, session);
+			return false;
+		}
+
+	}
+	return true;
+
+}
+
+/**
+ * lim_chk_n_process_wpa_rsn_ie() - wpa ie related checks
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ * @pmf_connection: flag indicating pmf connection
+ *
+ * wpa ie related checks
+ *
+ * Return: true if no error, false otherwise
+ */
+static bool lim_chk_n_process_wpa_rsn_ie(tpAniSirGlobal mac_ctx,
+					 tpSirMacMgmtHdr hdr,
+					 tpPESession session,
+					 tpSirAssocReq assoc_req,
+					 uint8_t sub_type, bool *pmf_connection)
+{
+	const uint8_t *wps_ie = NULL;
+
+	/* if additional IE is present, check if it has WscIE */
+	if (assoc_req->addIEPresent && assoc_req->addIE.length)
+		wps_ie = limGetWscIEPtr(mac_ctx, assoc_req->addIE.addIEdata,
+					assoc_req->addIE.length);
+	else
+		pe_debug("Assoc req addIEPresent: %d addIE length: %d",
+			 assoc_req->addIEPresent, assoc_req->addIE.length);
+
+	/* when wps_ie is present, RSN/WPA IE is ignored */
+	if (wps_ie == NULL) {
+		/* check whether RSN IE is present */
+		if (LIM_IS_AP_ROLE(session) &&
+		    session->pLimStartBssReq->privacy &&
+		    session->pLimStartBssReq->rsnIE.length)
+			return lim_check_wpa_rsn_ie(session, mac_ctx, sub_type,
+						hdr, assoc_req, pmf_connection);
+	} else {
+		pe_debug("Assoc req WSE IE is present");
+	}
+	return true;
+}
+
+/**
+ * lim_process_assoc_req_no_sta_ctx() - process assoc req for no sta ctx present
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ * @sta_pre_auth_ctx: sta pre auth context
+ * @sta_ds: station dph entry
+ * @auth_type: indicates security type
+ *
+ * Process assoc req for no sta ctx present
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_process_assoc_req_no_sta_ctx(tpAniSirGlobal mac_ctx,
+				tpSirMacMgmtHdr hdr, tpPESession session,
+				tpSirAssocReq assoc_req, uint8_t sub_type,
+				struct tLimPreAuthNode *sta_pre_auth_ctx,
+				tpDphHashNode sta_ds, tAniAuthType *auth_type)
+{
+	/* Requesting STA is not currently associated */
+	if (pe_get_current_stas_count(mac_ctx) ==
+			mac_ctx->mlme_cfg->sap_cfg.assoc_sta_limit) {
+		/*
+		 * Maximum number of STAs that AP can handle reached.
+		 * Send Association response to peer MAC entity
+		 */
+		pe_err("Max Sta count reached : %d",
+				mac_ctx->lim.maxStation);
+		lim_reject_association(mac_ctx, hdr->sa, sub_type, false,
+			(tAniAuthType) 0, 0, false,
+			eSIR_MAC_UNSPEC_FAILURE_STATUS,
+			session);
+		return false;
+	}
+	/* Check if STA is pre-authenticated. */
+	if ((sta_pre_auth_ctx == NULL) || (sta_pre_auth_ctx &&
+		(sta_pre_auth_ctx->mlmState != eLIM_MLM_AUTHENTICATED_STATE))) {
+		/*
+		 * STA is not pre-authenticated yet requesting Re/Association
+		 * before Authentication. OR STA is in the process of getting
+		 * authenticated and sent Re/Association request. Send
+		 * Deauthentication frame with 'prior authentication required'
+		 * reason code.
+		 */
+		lim_send_deauth_mgmt_frame(mac_ctx,
+				eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON,
+				hdr->sa, session, false);
+
+		pe_warn("rcvd %s req, sessionid: %d, without pre-auth ctx"
+				MAC_ADDRESS_STR,
+			(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
+			session->peSessionId, MAC_ADDR_ARRAY(hdr->sa));
+		return false;
+	}
+	/* Delete 'pre-auth' context of STA */
+	*auth_type = sta_pre_auth_ctx->authType;
+	lim_delete_pre_auth_node(mac_ctx, hdr->sa);
+	/* All is well. Assign AID (after else part) */
+	return true;
+}
+
+/**
+ * lim_process_assoc_req_sta_ctx() - process assoc req for sta context present
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ * @sta_pre_auth_ctx: sta pre auth context
+ * @sta_ds: station dph entry
+ * @peer_idx: peer index
+ * @auth_type: indicates security type
+ * @update_ctx: indicates if STA context already exist
+ *
+ * Process assoc req for sta context present
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_process_assoc_req_sta_ctx(tpAniSirGlobal mac_ctx,
+				tpSirMacMgmtHdr hdr, tpPESession session,
+				tpSirAssocReq assoc_req, uint8_t sub_type,
+				struct tLimPreAuthNode *sta_pre_auth_ctx,
+				tpDphHashNode sta_ds, uint16_t peer_idx,
+				tAniAuthType *auth_type, uint8_t *update_ctx)
+{
+	/* STA context does exist for this STA */
+	if (sta_ds->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) {
+		/*
+		 * Requesting STA is in some 'transient' state? Ignore the
+		 * Re/Assoc Req frame by incrementing debug counter & logging
+		 * error.
+		 */
+		if (sub_type == LIM_ASSOC) {
+#ifdef WLAN_DEBUG
+			mac_ctx->lim.gLimNumAssocReqDropInvldState++;
+#endif
+			pe_debug("received Assoc req in state: %X from",
+				sta_ds->mlmStaContext.mlmState);
+		} else {
+#ifdef WLAN_DEBUG
+			mac_ctx->lim.gLimNumReassocReqDropInvldState++;
+#endif
+			pe_debug("received ReAssoc req in state: %X from",
+				sta_ds->mlmStaContext.mlmState);
+		}
+		lim_print_mac_addr(mac_ctx, hdr->sa, LOGD);
+		lim_print_mlm_state(mac_ctx, LOGD,
+			(tLimMlmStates) sta_ds->mlmStaContext.mlmState);
+		return false;
+	}
+
+	/* STA sent assoc req frame while already in 'associated' state */
+
+#ifdef WLAN_FEATURE_11W
+	pe_debug("Re/Assoc request from station that is already associated");
+	pe_debug("PMF enabled: %d, SA Query state: %d",
+		sta_ds->rmfEnabled, sta_ds->pmfSaQueryState);
+	if (sta_ds->rmfEnabled) {
+		switch (sta_ds->pmfSaQueryState) {
+		/*
+		 * start SA Query procedure, respond to Association Request with
+		 * try again later
+		 */
+		case DPH_SA_QUERY_NOT_IN_PROGRESS:
+			/*
+			 * We should reset the retry counter before we start
+			 * the SA query procedure, otherwise in next set of SA
+			 * query procedure we will end up using the stale value.
+			 */
+			sta_ds->pmfSaQueryRetryCount = 0;
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+					eSIR_MAC_TRY_AGAIN_LATER, 1, hdr->sa,
+					sub_type, sta_ds, session);
+			lim_send_sa_query_request_frame(mac_ctx,
+				(uint8_t *) &(sta_ds->pmfSaQueryCurrentTransId),
+				hdr->sa, session);
+			sta_ds->pmfSaQueryStartTransId =
+				sta_ds->pmfSaQueryCurrentTransId;
+			sta_ds->pmfSaQueryCurrentTransId++;
+
+			/* start timer for SA Query retry */
+			if (tx_timer_activate(&sta_ds->pmfSaQueryTimer)
+					!= TX_SUCCESS) {
+				pe_err("PMF SA Query timer start failed!");
+				return false;
+			}
+			sta_ds->pmfSaQueryState = DPH_SA_QUERY_IN_PROGRESS;
+			return false;
+		/*
+		 * SA Query procedure still going, respond to Association
+		 * Request with try again later
+		 */
+		case DPH_SA_QUERY_IN_PROGRESS:
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+						eSIR_MAC_TRY_AGAIN_LATER, 1,
+						hdr->sa, sub_type, 0, session);
+			return false;
+
+		/*
+		 * SA Query procedure timed out, accept Association
+		 * Request normally
+		 */
+		case DPH_SA_QUERY_TIMED_OUT:
+			sta_ds->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
+			break;
+		}
+	}
+#endif
+
+	/* no change in the capability so drop the frame */
+	if ((sub_type == LIM_ASSOC) &&
+		(!qdf_mem_cmp(&sta_ds->mlmStaContext.capabilityInfo,
+			&assoc_req->capabilityInfo,
+			sizeof(tSirMacCapabilityInfo)))) {
+		pe_err("Received Assoc req in state: %X STAid: %d",
+			sta_ds->mlmStaContext.mlmState, peer_idx);
+		return false;
+	} else {
+		/*
+		 * STA sent Re/association Request frame while already in
+		 * 'associated' state. Update STA capabilities and send
+		 * Association response frame with same AID
+		 */
+		pe_debug("Rcvd Assoc req from STA already connected");
+		sta_ds->mlmStaContext.capabilityInfo =
+			assoc_req->capabilityInfo;
+		if (sta_pre_auth_ctx && (sta_pre_auth_ctx->mlmState ==
+			eLIM_MLM_AUTHENTICATED_STATE)) {
+			/* STA has triggered pre-auth again */
+			*auth_type = sta_pre_auth_ctx->authType;
+			lim_delete_pre_auth_node(mac_ctx, hdr->sa);
+		} else {
+			*auth_type = sta_ds->mlmStaContext.authType;
+		}
+
+		*update_ctx = true;
+		if (dph_init_sta_state(mac_ctx, hdr->sa, peer_idx, true,
+			&session->dph.dphHashTable) == NULL) {
+			pe_err("could not Init STAid: %d", peer_idx);
+			return false;
+		}
+	}
+	return true;
+}
+
+/**
+ * lim_chk_wmm() - wmm related checks
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ * @qos_mode: qos mode
+ *
+ * wmm related checks
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_chk_wmm(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			tpPESession session, tpSirAssocReq assoc_req,
+			uint8_t sub_type, tHalBitVal qos_mode)
+{
+	tHalBitVal wme_mode;
+
+	limGetWmeMode(session, &wme_mode);
+	if ((qos_mode == eHAL_SET) || (wme_mode == eHAL_SET)) {
+		/*
+		 * for a qsta, check if the requested Traffic spec is admissible
+		 * for a non-qsta check if the sta can be admitted
+		 */
+		if (assoc_req->addtsPresent) {
+			uint8_t tspecIdx = 0;
+
+			if (lim_admit_control_add_ts(mac_ctx, hdr->sa,
+				&(assoc_req->addtsReq),
+				&(assoc_req->qosCapability),
+				0, false, NULL, &tspecIdx, session) !=
+					QDF_STATUS_SUCCESS) {
+				pe_warn("AdmitControl: TSPEC rejected");
+				lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+					eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
+					1, hdr->sa, sub_type, 0, session);
+#ifdef WLAN_DEBUG
+				mac_ctx->lim.gLimNumAssocReqDropACRejectTS++;
+#endif
+				return false;
+			}
+		} else if (lim_admit_control_add_sta(mac_ctx, hdr->sa, false)
+				!= QDF_STATUS_SUCCESS) {
+			pe_warn("AdmitControl: Sta rejected");
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+				eSIR_MAC_QAP_NO_BANDWIDTH_REASON, 1,
+				hdr->sa, sub_type, 0, session);
+#ifdef WLAN_DEBUG
+			mac_ctx->lim.gLimNumAssocReqDropACRejectSta++;
+#endif
+			return false;
+		}
+		/* else all ok */
+		pe_debug("AdmitControl: Sta OK!");
+	}
+	return true;
+}
+
+/**
+ * lim_update_sta_ds() - updates ds dph entry
+ * @mac_ctx: pointer to Global MAC structure
+ * @hdr: pointer to the MAC head
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame pointer
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ * @sta_ds: station dph entry
+ * @auth_type: indicates security type
+ * @assoc_req_copied: boolean to indicate if assoc req was copied to tmp above
+ * @peer_idx: peer index
+ * @qos_mode: qos mode
+ * @pmf_connection: flag indicating pmf connection
+ *
+ * Updates ds dph entry
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_update_sta_ds(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
+			      tpPESession session, tpSirAssocReq assoc_req,
+			      uint8_t sub_type, tpDphHashNode sta_ds,
+			      tAniAuthType auth_type,
+			      bool *assoc_req_copied, uint16_t peer_idx,
+			      tHalBitVal qos_mode, bool pmf_connection)
+{
+	tHalBitVal wme_mode, wsm_mode;
+	uint8_t *ht_cap_ie = NULL;
+#ifdef WLAN_FEATURE_11W
+	tPmfSaQueryTimerId timer_id;
+	uint16_t retry_interval;
+#endif
+	tDot11fIEVHTCaps *vht_caps;
+	tpSirAssocReq tmp_assoc_req;
+
+	if (assoc_req->VHTCaps.present)
+		vht_caps = &assoc_req->VHTCaps;
+	else if (assoc_req->vendor_vht_ie.VHTCaps.present &&
+		 session->vendor_vht_sap)
+		vht_caps = &assoc_req->vendor_vht_ie.VHTCaps;
+	else
+		vht_caps = NULL;
+
+	/*
+	 * check here if the parsedAssocReq already pointing to the assoc_req
+	 * and free it before assigning this new assoc_req
+	 */
+	if (session->parsedAssocReq != NULL) {
+		tmp_assoc_req = session->parsedAssocReq[sta_ds->assocId];
+		if (tmp_assoc_req != NULL) {
+			if (tmp_assoc_req->assocReqFrame) {
+				qdf_mem_free(tmp_assoc_req->assocReqFrame);
+				tmp_assoc_req->assocReqFrame = NULL;
+				tmp_assoc_req->assocReqFrameLength = 0;
+			}
+			qdf_mem_free(tmp_assoc_req);
+			tmp_assoc_req = NULL;
+		}
+
+		session->parsedAssocReq[sta_ds->assocId] = assoc_req;
+		*assoc_req_copied = true;
+	}
+
+	sta_ds->mlmStaContext.htCapability = assoc_req->HTCaps.present;
+	if ((vht_caps != NULL) && vht_caps->present)
+		sta_ds->mlmStaContext.vhtCapability = vht_caps->present;
+	else
+		sta_ds->mlmStaContext.vhtCapability = false;
+	lim_update_stads_he_capable(sta_ds, assoc_req);
+	sta_ds->qos.addtsPresent =
+		(assoc_req->addtsPresent == 0) ? false : true;
+	sta_ds->qos.addts = assoc_req->addtsReq;
+	sta_ds->qos.capability = assoc_req->qosCapability;
+	sta_ds->versionPresent = 0;
+	/*
+	 * short slot and short preamble should be updated before doing
+	 * limaddsta
+	 */
+	sta_ds->shortPreambleEnabled =
+		(uint8_t) assoc_req->capabilityInfo.shortPreamble;
+	sta_ds->shortSlotTimeEnabled =
+		(uint8_t) assoc_req->capabilityInfo.shortSlotTime;
+
+	sta_ds->valid = 0;
+	sta_ds->mlmStaContext.authType = auth_type;
+	sta_ds->staType = STA_ENTRY_PEER;
+
+	/*
+	 * TODO: If listen interval is more than certain limit, reject the
+	 * association. Need to check customer requirements and then implement.
+	 */
+	sta_ds->mlmStaContext.listenInterval = assoc_req->listenInterval;
+	sta_ds->mlmStaContext.capabilityInfo = assoc_req->capabilityInfo;
+
+	/*
+	 * The following count will be used to knock-off the station if it
+	 * doesn't come back to receive the buffered data. The AP will wait
+	 * for numTimSent number of beacons after sending TIM information for
+	 * the station, before assuming that the station is no more associated
+	 * and disassociates it
+	 */
+
+	/* timWaitCount used by PMM for monitoring the STA's in PS for LINK */
+	sta_ds->timWaitCount =
+		(uint8_t) GET_TIM_WAIT_COUNT(assoc_req->listenInterval);
+
+	/* Init the Current successful MPDU's tranfered to this STA count = 0 */
+	sta_ds->curTxMpduCnt = 0;
+
+	if (IS_DOT11_MODE_HT(session->dot11mode) &&
+	    assoc_req->HTCaps.present && assoc_req->wmeInfoPresent) {
+		sta_ds->htGreenfield = (uint8_t) assoc_req->HTCaps.greenField;
+		sta_ds->htAMpduDensity = assoc_req->HTCaps.mpduDensity;
+		sta_ds->htDsssCckRate40MHzSupport =
+			(uint8_t) assoc_req->HTCaps.dsssCckMode40MHz;
+		sta_ds->htLsigTXOPProtection =
+			(uint8_t) assoc_req->HTCaps.lsigTXOPProtection;
+		sta_ds->htMaxAmsduLength =
+			(uint8_t) assoc_req->HTCaps.maximalAMSDUsize;
+		sta_ds->htMaxRxAMpduFactor = assoc_req->HTCaps.maxRxAMPDUFactor;
+		sta_ds->htMIMOPSState = assoc_req->HTCaps.mimoPowerSave;
+
+		/* assoc_req will be copied to session->parsedAssocReq later */
+		ht_cap_ie = ((uint8_t *) &assoc_req->HTCaps) + 1;
+
+		if (session->htConfig.ht_sgi20) {
+			sta_ds->htShortGI20Mhz =
+				(uint8_t)assoc_req->HTCaps.shortGI20MHz;
+		} else {
+			/* Unset htShortGI20Mhz in ht_caps*/
+			*ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI20MHZ_S);
+			sta_ds->htShortGI20Mhz = 0;
+		}
+
+		if (session->htConfig.ht_sgi40) {
+			sta_ds->htShortGI40Mhz =
+				(uint8_t)assoc_req->HTCaps.shortGI40MHz;
+		} else {
+			/* Unset htShortGI40Mhz in ht_caps */
+			*ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI40MHZ_S);
+			sta_ds->htShortGI40Mhz = 0;
+		}
+
+		sta_ds->htSupportedChannelWidthSet =
+			(uint8_t) assoc_req->HTCaps.supportedChannelWidthSet;
+		/*
+		 * peer just follows AP; so when we are softAP/GO,
+		 * we just store our session entry's secondary channel offset
+		 * here in peer INFRA STA. However, if peer's 40MHz channel
+		 * width support is disabled then secondary channel will be zero
+		 */
+		sta_ds->htSecondaryChannelOffset =
+			(sta_ds->htSupportedChannelWidthSet) ?
+				session->htSecondaryChannelOffset : 0;
+		if (assoc_req->operMode.present) {
+			sta_ds->vhtSupportedChannelWidthSet =
+				(uint8_t) ((assoc_req->operMode.chanWidth ==
+				eHT_CHANNEL_WIDTH_80MHZ) ?
+				WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ :
+				WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ);
+			sta_ds->htSupportedChannelWidthSet =
+				(uint8_t) (assoc_req->operMode.chanWidth ?
+				eHT_CHANNEL_WIDTH_40MHZ :
+				eHT_CHANNEL_WIDTH_20MHZ);
+		} else if ((vht_caps != NULL) && vht_caps->present) {
+			/*
+			 * Check if STA has enabled it's channel bonding mode.
+			 * If channel bonding mode is enabled, we decide based
+			 * on SAP's current configuration. else, we set it to
+			 * VHT20.
+			 */
+			sta_ds->vhtSupportedChannelWidthSet =
+				(uint8_t) ((sta_ds->htSupportedChannelWidthSet
+					== eHT_CHANNEL_WIDTH_20MHZ) ?
+					WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ :
+					session->ch_width - 1);
+			sta_ds->htMaxRxAMpduFactor =
+				vht_caps->maxAMPDULenExp;
+		}
+		/* Lesser among the AP and STA bandwidth of operation. */
+		sta_ds->htSupportedChannelWidthSet =
+			(sta_ds->htSupportedChannelWidthSet <
+			session->htSupportedChannelWidthSet) ?
+			sta_ds->htSupportedChannelWidthSet :
+			session->htSupportedChannelWidthSet;
+		sta_ds->baPolicyFlag = 0xFF;
+		sta_ds->htLdpcCapable =
+			(uint8_t) assoc_req->HTCaps.advCodingCap;
+	}
+
+	if ((vht_caps != NULL) && vht_caps->present &&
+	    assoc_req->wmeInfoPresent) {
+		sta_ds->vhtLdpcCapable =
+			(uint8_t) vht_caps->ldpcCodingCap;
+	}
+
+	if (assoc_req->ExtCap.present)
+		sta_ds->non_ecsa_capable =
+		    !((struct s_ext_cap *)assoc_req->ExtCap.bytes)->
+		    ext_chan_switch;
+	else
+		sta_ds->non_ecsa_capable = 1;
+
+	if (!assoc_req->wmeInfoPresent) {
+		sta_ds->mlmStaContext.htCapability = 0;
+		sta_ds->mlmStaContext.vhtCapability = 0;
+	}
+
+	if (sta_ds->mlmStaContext.vhtCapability && vht_caps) {
+		if (session->vht_config.su_beam_formee &&
+				vht_caps->suBeamFormerCap)
+			sta_ds->vhtBeamFormerCapable = 1;
+		else
+			sta_ds->vhtBeamFormerCapable = 0;
+		if (session->vht_config.su_beam_former &&
+				vht_caps->suBeamformeeCap)
+			sta_ds->vht_su_bfee_capable = 1;
+		else
+			sta_ds->vht_su_bfee_capable = 0;
+
+		pe_debug("peer_caps: suBformer: %d, suBformee: %d",
+			 vht_caps->suBeamFormerCap,
+			 vht_caps->suBeamformeeCap);
+		pe_debug("self_cap: suBformer: %d, suBformee: %d",
+			 session->vht_config.su_beam_former,
+			 session->vht_config.su_beam_formee);
+		pe_debug("connection's final cap: suBformer: %d, suBformee: %d",
+			 sta_ds->vhtBeamFormerCapable,
+			 sta_ds->vht_su_bfee_capable);
+	}
+
+	lim_intersect_sta_he_caps(assoc_req, session, sta_ds);
+
+	if (lim_populate_matching_rate_set(mac_ctx, sta_ds,
+			&(assoc_req->supportedRates),
+			&(assoc_req->extendedRates),
+			assoc_req->HTCaps.supportedMCSSet,
+			session, vht_caps,
+			&assoc_req->he_cap) != QDF_STATUS_SUCCESS) {
+		/* Could not update hash table entry at DPH with rateset */
+		pe_err("Couldn't update hash entry for aid: %d MacAddr: "
+		       MAC_ADDRESS_STR,
+		       peer_idx, MAC_ADDR_ARRAY(hdr->sa));
+
+		/* Release AID */
+		lim_release_peer_idx(mac_ctx, peer_idx, session);
+
+		lim_reject_association(mac_ctx, hdr->sa,
+			sub_type, true, auth_type, peer_idx, false,
+			eSIR_MAC_UNSPEC_FAILURE_STATUS,
+			session);
+		pe_err("Delete dph hash entry");
+		if (dph_delete_hash_entry(mac_ctx, hdr->sa, sta_ds->assocId,
+			 &session->dph.dphHashTable) != QDF_STATUS_SUCCESS)
+			pe_err("error deleting hash entry");
+		return false;
+	}
+	if (assoc_req->operMode.present) {
+		sta_ds->vhtSupportedRxNss = assoc_req->operMode.rxNSS + 1;
+	} else {
+		sta_ds->vhtSupportedRxNss =
+			((sta_ds->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2)
+				== MCSMAPMASK2x2) ? 1 : 2;
+	}
+
+	/* Add STA context at MAC HW (BMU, RHP & TFP) */
+	sta_ds->qosMode = false;
+	sta_ds->lleEnabled = false;
+	if (assoc_req->capabilityInfo.qos && (qos_mode == eHAL_SET)) {
+		sta_ds->lleEnabled = true;
+		sta_ds->qosMode = true;
+	}
+
+	sta_ds->wmeEnabled = false;
+	sta_ds->wsmEnabled = false;
+	limGetWmeMode(session, &wme_mode);
+	if ((!sta_ds->lleEnabled) && assoc_req->wmeInfoPresent
+	    && (wme_mode == eHAL_SET)) {
+		sta_ds->wmeEnabled = true;
+		sta_ds->qosMode = true;
+		limGetWsmMode(session, &wsm_mode);
+		/*
+		 * WMM_APSD - WMM_SA related processing should be separate;
+		 * WMM_SA and WMM_APSD can coexist
+		 */
+		if (assoc_req->WMMInfoStation.present) {
+			/* check whether AP supports or not */
+			if (LIM_IS_AP_ROLE(session) &&
+				(session->apUapsdEnable == 0) &&
+				(assoc_req->WMMInfoStation.acbe_uapsd ||
+					assoc_req->WMMInfoStation.acbk_uapsd ||
+					assoc_req->WMMInfoStation.acvo_uapsd ||
+					assoc_req->WMMInfoStation.acvi_uapsd)) {
+				/*
+				 * Rcvd Re/Assoc Req from STA when UPASD is
+				 * not supported.
+				 */
+				pe_err("UAPSD not supported, reply accordingly");
+				/* update UAPSD and send it to LIM to add STA */
+				sta_ds->qos.capability.qosInfo.acbe_uapsd = 0;
+				sta_ds->qos.capability.qosInfo.acbk_uapsd = 0;
+				sta_ds->qos.capability.qosInfo.acvo_uapsd = 0;
+				sta_ds->qos.capability.qosInfo.acvi_uapsd = 0;
+				sta_ds->qos.capability.qosInfo.maxSpLen = 0;
+			} else {
+				/* update UAPSD and send it to LIM to add STA */
+				sta_ds->qos.capability.qosInfo.acbe_uapsd =
+					assoc_req->WMMInfoStation.acbe_uapsd;
+				sta_ds->qos.capability.qosInfo.acbk_uapsd =
+					assoc_req->WMMInfoStation.acbk_uapsd;
+				sta_ds->qos.capability.qosInfo.acvo_uapsd =
+					assoc_req->WMMInfoStation.acvo_uapsd;
+				sta_ds->qos.capability.qosInfo.acvi_uapsd =
+					assoc_req->WMMInfoStation.acvi_uapsd;
+				sta_ds->qos.capability.qosInfo.maxSpLen =
+					assoc_req->WMMInfoStation.max_sp_length;
+			}
+		}
+		if (assoc_req->wsmCapablePresent && (wsm_mode == eHAL_SET))
+			sta_ds->wsmEnabled = true;
+	}
+	/* Re/Assoc Response frame to requesting STA */
+	sta_ds->mlmStaContext.subType = sub_type;
+
+#ifdef WLAN_FEATURE_11W
+	sta_ds->rmfEnabled = (pmf_connection) ? 1 : 0;
+	sta_ds->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
+	timer_id.fields.sessionId = session->peSessionId;
+	timer_id.fields.peerIdx = peer_idx;
+	retry_interval = mac_ctx->mlme_cfg->gen.pmf_sa_query_retry_interval;
+	if (cfg_min(CFG_PMF_SA_QUERY_RETRY_INTERVAL) > retry_interval) {
+		retry_interval = cfg_default(CFG_PMF_SA_QUERY_RETRY_INTERVAL);
+	}
+	if (sta_ds->rmfEnabled &&
+		tx_timer_create(mac_ctx, &sta_ds->pmfSaQueryTimer,
+			"PMF SA Query timer", lim_pmf_sa_query_timer_handler,
+			timer_id.value,
+			SYS_MS_TO_TICKS((retry_interval * 1024) / 1000),
+			0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("could not create PMF SA Query timer");
+		lim_reject_association(mac_ctx, hdr->sa, sub_type,
+			true, auth_type, peer_idx, false,
+			eSIR_MAC_UNSPEC_FAILURE_STATUS,
+			session);
+		return false;
+	}
+	if (sta_ds->rmfEnabled)
+	    pe_debug("Created pmf timer sta-idx:%d assoc-id:%d",
+		     sta_ds->staIndex, sta_ds->assocId);
+#endif
+
+	if (assoc_req->ExtCap.present) {
+		lim_set_stads_rtt_cap(sta_ds,
+			(struct s_ext_cap *) assoc_req->ExtCap.bytes, mac_ctx);
+	} else {
+		sta_ds->timingMeasCap = 0;
+		pe_debug("ExtCap not present");
+	}
+	return true;
+}
+
+/**
+ * lim_update_sta_ctx() - add/del sta depending on connection state machine
+ * @mac_ctx: pointer to Global MAC structure
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
+ * @sta_ds: station dph entry
+ * @update_ctx: indicates if STA context already exist
+ *
+ * Checks for SSID match
+ *
+ * Return: true of no error, false otherwise
+ */
+static bool lim_update_sta_ctx(tpAniSirGlobal mac_ctx, tpPESession session,
+			       tpSirAssocReq assoc_req, uint8_t sub_type,
+			       tpDphHashNode sta_ds, uint8_t update_ctx)
+{
+	tLimMlmStates mlm_prev_state;
+	/*
+	 * BTAMP: If STA context already exist (ie. update_ctx = 1) for this STA
+	 * then we should delete the old one, and add the new STA. This is taken
+	 * care of in the lim_del_sta() routine.
+	 *
+	 * Prior to BTAMP, we were setting this flag so that when PE receives
+	 * SME_ASSOC_CNF, and if this flag is set, then PE shall delete the old
+	 * station and then add. But now in BTAMP, we're directly adding station
+	 * before waiting for SME_ASSOC_CNF, so we can do this now.
+	 */
+	if (!(update_ctx)) {
+		sta_ds->mlmStaContext.updateContext = 0;
+
+		/*
+		 * BTAMP: Add STA context at HW - issue WMA_ADD_STA_REQ to HAL
+		 */
+		if (lim_add_sta(mac_ctx, sta_ds, false, session) !=
+		    QDF_STATUS_SUCCESS) {
+			pe_err("could not Add STA with assocId: %d",
+				sta_ds->assocId);
+			lim_reject_association(mac_ctx, sta_ds->staAddr,
+				sta_ds->mlmStaContext.subType, true,
+				sta_ds->mlmStaContext.authType,
+				sta_ds->assocId, true,
+				eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				session);
+
+			if (session->parsedAssocReq)
+				assoc_req =
+				    session->parsedAssocReq[sta_ds->assocId];
+			return false;
+		}
+	} else {
+		sta_ds->mlmStaContext.updateContext = 1;
+		mlm_prev_state = sta_ds->mlmStaContext.mlmState;
+
+		/*
+		 * As per the HAL/FW needs the reassoc req need not be calling
+		 * lim_del_sta
+		 */
+		if (sub_type != LIM_REASSOC) {
+			/*
+			 * we need to set the mlmState here in order
+			 * differentiate in lim_del_sta.
+			 */
+			sta_ds->mlmStaContext.mlmState =
+				eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE;
+			if (lim_del_sta(mac_ctx, sta_ds, true, session)
+					!= QDF_STATUS_SUCCESS) {
+				pe_err("Couldn't DEL STA, assocId: %d staId: %d",
+					sta_ds->assocId, sta_ds->staIndex);
+				lim_reject_association(mac_ctx, sta_ds->staAddr,
+					sta_ds->mlmStaContext.subType, true,
+					sta_ds->mlmStaContext.authType,
+					sta_ds->assocId, true,
+					eSIR_MAC_UNSPEC_FAILURE_STATUS,
+					session);
+
+				/* Restoring the state back. */
+				sta_ds->mlmStaContext.mlmState = mlm_prev_state;
+				if (session->parsedAssocReq)
+					assoc_req = session->parsedAssocReq[
+						sta_ds->assocId];
+				return false;
+			}
+		} else {
+			/*
+			 * mlmState is changed in lim_add_sta context use the
+			 * same AID, already allocated
+			 */
+			if (lim_add_sta(mac_ctx, sta_ds, false, session)
+				!= QDF_STATUS_SUCCESS) {
+				pe_err("UPASD not supported, REASSOC Failed");
+				lim_reject_association(mac_ctx, sta_ds->staAddr,
+					sta_ds->mlmStaContext.subType, true,
+					sta_ds->mlmStaContext.authType,
+					sta_ds->assocId, true,
+					eSIR_MAC_WME_REFUSED_STATUS,
+					session);
+
+				/* Restoring the state back. */
+				sta_ds->mlmStaContext.mlmState = mlm_prev_state;
+				if (session->parsedAssocReq)
+					assoc_req = session->parsedAssocReq[
+							sta_ds->assocId];
+				return false;
+			}
+		}
+	}
+	return true;
+}
+
+/**
+ * lim_process_assoc_cleanup() - frees up resources used in function
+ * lim_process_assoc_req_frame()
+ * @mac_ctx: pointer to Global MAC structure
+ * @session: pointer to pe session entry
+ * @assoc_req: pointer to ASSOC/REASSOC Request frame
+ * @sta_ds: station dph entry
+ * @tmp_assoc_req: pointer to tmp ASSOC/REASSOC Request frame
+ * @assoc_req_copied: boolean to indicate if assoc req was copied to tmp above
+ *
+ * Frees up resources used in function lim_process_assoc_req_frame
+ *
+ * Return: void
+ */
+static void lim_process_assoc_cleanup(tpAniSirGlobal mac_ctx,
+				      tpPESession session,
+				      tpSirAssocReq assoc_req,
+				      tpDphHashNode sta_ds,
+				      bool *assoc_req_copied)
+{
+	tpSirAssocReq tmp_assoc_req;
+
+	if (assoc_req != NULL) {
+		if (assoc_req->assocReqFrame) {
+			qdf_mem_free(assoc_req->assocReqFrame);
+			assoc_req->assocReqFrame = NULL;
+			assoc_req->assocReqFrameLength = 0;
+		}
+
+		qdf_mem_free(assoc_req);
+		/* to avoid double free */
+		if (*assoc_req_copied && session->parsedAssocReq)
+			session->parsedAssocReq[sta_ds->assocId] = NULL;
+	}
+
+	/* If it is not duplicate Assoc request then only make to Null */
+	if ((sta_ds != NULL) &&
+	    (sta_ds->mlmStaContext.mlmState != eLIM_MLM_WT_ADD_STA_RSP_STATE)) {
+		if (session->parsedAssocReq != NULL) {
+			tmp_assoc_req =
+				session->parsedAssocReq[sta_ds->assocId];
+			if (tmp_assoc_req != NULL) {
+				if (tmp_assoc_req->assocReqFrame) {
+					qdf_mem_free(
+						tmp_assoc_req->assocReqFrame);
+					tmp_assoc_req->assocReqFrame = NULL;
+					tmp_assoc_req->assocReqFrameLength = 0;
+				}
+				qdf_mem_free(tmp_assoc_req);
+				session->parsedAssocReq[sta_ds->assocId] = NULL;
+			}
+		}
+	}
+}
+
+/**
+ * lim_process_assoc_req_frame() - Process RE/ASSOC Request frame.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_pkt_info: A pointer to Buffer descriptor + associated PDUs
+ * @sub_type: Indicates whether it is Association Request(=0) or Reassociation
+ *            Request(=1) frame
+ * @session: pe session entry
+ *
+ * This function is called to process RE/ASSOC Request frame.
+ *
+ * @Return: void
+ */
+void lim_process_assoc_req_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+				 uint8_t sub_type, tpPESession session)
+{
+	bool pmf_connection = false, assoc_req_copied = false;
+	uint8_t update_ctx, *frm_body;
+	uint16_t peer_idx, assoc_id = 0;
+	uint32_t frame_len;
+	uint32_t phy_mode;
+	tHalBitVal qos_mode;
+	tpSirMacMgmtHdr hdr;
+	struct tLimPreAuthNode *sta_pre_auth_ctx;
+	tAniAuthType auth_type;
+	tSirMacCapabilityInfo local_cap;
+	tpDphHashNode sta_ds = NULL;
+	tpSirAssocReq assoc_req;
+	bool dup_entry = false;
+
+	lim_get_phy_mode(mac_ctx, &phy_mode, session);
+
+	limGetQosMode(session, &qos_mode);
+
+	hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+	pe_debug("Rcvd: %s Req Frame sessionid: %d systemrole: %d MlmState: %d from: "
+		   MAC_ADDRESS_STR,
+		(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
+		session->peSessionId, GET_LIM_SYSTEM_ROLE(session),
+		session->limMlmState, MAC_ADDR_ARRAY(hdr->sa));
+
+	if (LIM_IS_STA_ROLE(session)) {
+		pe_err("Rcvd unexpected ASSOC REQ, sessionid: %d sys sub_type: %d for role: %d from: "
+			   MAC_ADDRESS_STR,
+			session->peSessionId, sub_type,
+			GET_LIM_SYSTEM_ROLE(session),
+			MAC_ADDR_ARRAY(hdr->sa));
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				   WMA_GET_RX_MPDU_DATA(rx_pkt_info),
+				   frame_len);
+		return;
+	}
+	if (session->limMlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE) {
+		pe_err("drop ASSOC REQ on sessionid: %d "
+			"role: %d from: "MAC_ADDRESS_STR" in limMlmState: %d",
+			session->peSessionId,
+			GET_LIM_SYSTEM_ROLE(session),
+			MAC_ADDR_ARRAY(hdr->sa),
+			eLIM_MLM_WT_DEL_BSS_RSP_STATE);
+		return;
+	}
+
+	/*
+	 * If a STA is already present in DPH and it is initiating a Assoc
+	 * re-transmit, do not process it. This can happen when first Assoc Req
+	 * frame is received but ACK lost at STA side. The ACK for this dropped
+	 * Assoc Req frame should be sent by HW. Host simply does not process it
+	 * once the entry for the STA is already present in DPH.
+	 */
+	sta_ds = dph_lookup_hash_entry(mac_ctx, hdr->sa, &assoc_id,
+				&session->dph.dphHashTable);
+	if (NULL != sta_ds) {
+		if (hdr->fc.retry > 0) {
+			pe_err("STA is initiating Assoc Req after ACK lost. Do not process sessionid: %d sys sub_type=%d for role=%d from: "
+				MAC_ADDRESS_STR, session->peSessionId,
+			sub_type, GET_LIM_SYSTEM_ROLE(session),
+			MAC_ADDR_ARRAY(hdr->sa));
+			return;
+		} else if (!sta_ds->rmfEnabled && (sub_type == LIM_REASSOC)) {
+			/*
+			 * SAP should send reassoc response with reject code
+			 * to avoid IOT issues. as per the specification SAP
+			 * should do 4-way handshake after reassoc response and
+			 * some STA doesn't like 4way handshake after reassoc
+			 * where some STA does expect 4-way handshake.
+			 */
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+					eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
+					sta_ds->assocId, sta_ds->staAddr,
+					sub_type, sta_ds, session);
+			pe_err("Rejecting reassoc req from STA");
+			return;
+		} else if (!sta_ds->rmfEnabled) {
+			/*
+			 * Do this only for non PMF case.
+			 * STA might have missed the assoc response, so it is
+			 * sending assoc request frame again.
+			 */
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx, QDF_STATUS_SUCCESS,
+					sta_ds->assocId, sta_ds->staAddr,
+					sub_type,
+					sta_ds, session);
+			pe_err("DUT already received an assoc request frame and STA is sending another assoc req.So, do not Process sessionid: %d sys sub_type: %d for role: %d from: "
+					MAC_ADDRESS_STR,
+				session->peSessionId, sub_type,
+				session->limSystemRole,
+				MAC_ADDR_ARRAY(hdr->sa));
+			return;
+		}
+	}
+
+	dup_entry = lim_check_sta_in_pe_entries(mac_ctx, hdr,
+						session->peSessionId);
+
+	/* Get pointer to Re/Association Request frame body */
+	frm_body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+
+	if (lim_is_group_addr(hdr->sa)) {
+		/*
+		 * Rcvd Re/Assoc Req frame from BC/MC address Log error and
+		 * ignore it
+		 */
+		pe_err("Rcvd: %s Req, sessionid: %d from a BC/MC address"
+				MAC_ADDRESS_STR,
+			(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
+			session->peSessionId, MAC_ADDR_ARRAY(hdr->sa));
+		return;
+	}
+
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				(uint8_t *) frm_body, frame_len);
+
+	if (false == lim_chk_sa_da(mac_ctx, hdr, session, sub_type))
+		return;
+
+	if (false == lim_chk_tkip(mac_ctx, hdr, session, sub_type))
+		return;
+
+	/* check for the presence of vendor IE */
+	if ((session->access_policy_vendor_ie) &&
+		(session->access_policy ==
+		LIM_ACCESS_POLICY_RESPOND_IF_IE_IS_PRESENT)) {
+		if (frame_len <= LIM_ASSOC_REQ_IE_OFFSET) {
+			pe_debug("Received action frame of invalid len %d",
+				 frame_len);
+			return;
+		}
+		if (!wlan_get_vendor_ie_ptr_from_oui(
+				&session->access_policy_vendor_ie[2],
+				3, frm_body + LIM_ASSOC_REQ_IE_OFFSET,
+				 frame_len - LIM_ASSOC_REQ_IE_OFFSET)) {
+			pe_err("Vendor ie not present and access policy is %x, Rejected association",
+				session->access_policy);
+			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+				eSIR_MAC_UNSPEC_FAILURE_STATUS, 1, hdr->sa,
+				sub_type, 0, session);
+			return;
+		}
+	}
+	/* Allocate memory for the Assoc Request frame */
+	assoc_req = qdf_mem_malloc(sizeof(*assoc_req));
+	if (!assoc_req)
+		return;
+
+	/* Parse Assoc Request frame */
+	if (false == lim_chk_assoc_req_parse_error(mac_ctx, hdr, session,
+				assoc_req, sub_type, frm_body, frame_len))
+		goto error;
+
+	assoc_req->assocReqFrame = qdf_mem_malloc(frame_len);
+	if (!assoc_req->assocReqFrame)
+		goto error;
+
+	qdf_mem_copy((uint8_t *) assoc_req->assocReqFrame,
+		(uint8_t *) frm_body, frame_len);
+	assoc_req->assocReqFrameLength = frame_len;
+
+	if (false == lim_chk_capab(mac_ctx, hdr, session, assoc_req,
+				sub_type, &local_cap))
+		goto error;
+
+	update_ctx = false;
+
+	if (false == lim_chk_ssid(mac_ctx, hdr, session, assoc_req, sub_type))
+		goto error;
+
+	if (false == lim_chk_rates(mac_ctx, hdr, session, assoc_req, sub_type))
+		goto error;
+
+	if (false == lim_chk_11g_only(mac_ctx, hdr, session, assoc_req,
+				sub_type))
+		goto error;
+
+	if (false == lim_chk_11n_only(mac_ctx, hdr, session, assoc_req,
+				sub_type))
+		goto error;
+
+	if (false == lim_chk_11ac_only(mac_ctx, hdr, session, assoc_req,
+				sub_type))
+		goto error;
+
+	if (false == lim_chk_11ax_only(mac_ctx, hdr, session, assoc_req,
+				       sub_type))
+		goto error;
+
+	if (false == lim_check_11ax_basic_mcs(mac_ctx, hdr, session, assoc_req,
+					      sub_type))
+		goto error;
+
+	/* Spectrum Management (11h) specific checks */
+	lim_process_for_spectrum_mgmt(mac_ctx, hdr, session,
+				assoc_req, sub_type, local_cap);
+
+	if (false == lim_chk_mcs(mac_ctx, hdr, session, assoc_req, sub_type))
+		goto error;
+
+	if (false == lim_chk_is_11b_sta_supported(mac_ctx, hdr, session,
+				assoc_req, sub_type, phy_mode))
+		goto error;
+
+	/*
+	 * Check for 802.11n HT caps compatibility; are HT Capabilities
+	 * turned on in lim?
+	 */
+	lim_print_ht_cap(mac_ctx, session, assoc_req);
+
+	if (false == lim_chk_n_process_wpa_rsn_ie(mac_ctx, hdr, session,
+				assoc_req, sub_type, &pmf_connection))
+		goto error;
+
+	/* Extract 'associated' context for STA, if any. */
+	sta_ds = dph_lookup_hash_entry(mac_ctx, hdr->sa, &peer_idx,
+				&session->dph.dphHashTable);
+
+	/* Extract pre-auth context for the STA, if any. */
+	sta_pre_auth_ctx = lim_search_pre_auth_list(mac_ctx, hdr->sa);
+
+	if (sta_ds == NULL) {
+		if (false == lim_process_assoc_req_no_sta_ctx(mac_ctx, hdr,
+				session, assoc_req, sub_type, sta_pre_auth_ctx,
+				sta_ds, &auth_type))
+			goto error;
+	} else {
+		if (false == lim_process_assoc_req_sta_ctx(mac_ctx, hdr,
+				session, assoc_req, sub_type, sta_pre_auth_ctx,
+				sta_ds, peer_idx, &auth_type, &update_ctx))
+			goto error;
+		goto sendIndToSme;
+	}
+
+	/* check if sta is allowed per QoS AC rules */
+	if (false == lim_chk_wmm(mac_ctx, hdr, session,
+				assoc_req, sub_type, qos_mode))
+		goto error;
+
+	/* STA is Associated ! */
+	pe_debug("Received: %s Req  successful from " MAC_ADDRESS_STR,
+		 (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
+		 MAC_ADDR_ARRAY(hdr->sa));
+
+	/*
+	 * AID for this association will be same as the peer Index used in DPH
+	 * table. Assign unused/least recently used peer Index from perStaDs.
+	 * NOTE: lim_assign_peer_idx() assigns AID values ranging between
+	 * 1 - cfg_item(WNI_CFG_ASSOC_STA_LIMIT)
+	 */
+
+	peer_idx = lim_assign_peer_idx(mac_ctx, session);
+
+	if (!peer_idx) {
+		/* Could not assign AID. Reject association */
+		pe_err("PeerIdx not avaialble. Reject associaton");
+		lim_reject_association(mac_ctx, hdr->sa, sub_type,
+				true, auth_type, peer_idx, false,
+				eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				session);
+		goto error;
+	}
+
+	/* Add an entry to hash table maintained by DPH module */
+
+	sta_ds = dph_add_hash_entry(mac_ctx, hdr->sa, peer_idx,
+				&session->dph.dphHashTable);
+
+	if (sta_ds == NULL) {
+		/* Could not add hash table entry at DPH */
+		pe_err("couldn't add hash entry at DPH for aid: %d MacAddr:"
+			   MAC_ADDRESS_STR, peer_idx, MAC_ADDR_ARRAY(hdr->sa));
+
+		/* Release AID */
+		lim_release_peer_idx(mac_ctx, peer_idx, session);
+
+		lim_reject_association(mac_ctx, hdr->sa, sub_type,
+			true, auth_type, peer_idx, false,
+			eSIR_MAC_UNSPEC_FAILURE_STATUS,
+			session);
+		goto error;
+	}
+
+sendIndToSme:
+	if (false == lim_update_sta_ds(mac_ctx, hdr, session, assoc_req,
+				sub_type, sta_ds, auth_type,
+				&assoc_req_copied, peer_idx, qos_mode,
+				pmf_connection))
+		goto error;
+
+
+	/* BTAMP: Storing the parsed assoc request in the session array */
+	if (session->parsedAssocReq)
+		session->parsedAssocReq[sta_ds->assocId] = assoc_req;
+	assoc_req_copied = true;
+
+	/* If it is duplicate entry wait till the peer is deleted */
+	if (dup_entry != true) {
+		if (false == lim_update_sta_ctx(mac_ctx, session, assoc_req,
+					sub_type, sta_ds, update_ctx))
+		goto error;
+	}
+
+	/* AddSta is success here */
+	if (LIM_IS_AP_ROLE(session) && IS_DOT11_MODE_HT(session->dot11mode) &&
+		assoc_req->HTCaps.present && assoc_req->wmeInfoPresent) {
+		/*
+		 * Update in the HAL Sta Table for the Update of the Protection
+		 * Mode
+		 */
+		lim_post_sm_state_update(mac_ctx, sta_ds->staIndex,
+					 sta_ds->htMIMOPSState, sta_ds->staAddr,
+					 session->smeSessionId);
+	}
+
+	return;
+
+error:
+	lim_process_assoc_cleanup(mac_ctx, session, assoc_req, sta_ds,
+				  &assoc_req_copied);
+	return;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+/**
+ * lim_fill_assoc_ind_wapi_info()- Updates WAPI data in assoc indication
+ * @mac_ctx: Global Mac context
+ * @assoc_req: pointer to association request
+ * @assoc_ind: Pointer to association indication
+ * @wpsie: WPS IE
+ *
+ * This function updates WAPI meta data in association indication message
+ * sent to SME.
+ *
+ * Return: None
+ */
+static void lim_fill_assoc_ind_wapi_info(tpAniSirGlobal mac_ctx,
+	tpSirAssocReq assoc_req, tpLimMlmAssocInd assoc_ind,
+	const uint8_t *wpsie)
+{
+	if (assoc_req->wapiPresent && (NULL == wpsie)) {
+		pe_debug("Received WAPI IE length in Assoc Req is %d",
+			assoc_req->wapi.length);
+		assoc_ind->wapiIE.wapiIEdata[0] = SIR_MAC_WAPI_EID;
+		assoc_ind->wapiIE.wapiIEdata[1] = assoc_req->wapi.length;
+		qdf_mem_copy(&assoc_ind->wapiIE.wapiIEdata[2],
+			assoc_req->wapi.info, assoc_req->wapi.length);
+		assoc_ind->wapiIE.length =
+			2 + assoc_req->wapi.length;
+	}
+	return;
+}
+#endif
+
+/**
+ * lim_fill_assoc_ind_vht_info() - Updates VHT information in assoc indication
+ * @mac_ctx: Global Mac context
+ * @assoc_req: pointer to association request
+ * @session_entry: PE session entry
+ * @assoc_ind: Pointer to association indication
+ *
+ * This function updates VHT information in association indication message
+ * sent to SME.
+ *
+ * Return: None
+ */
+static void lim_fill_assoc_ind_vht_info(tpAniSirGlobal mac_ctx,
+					tpPESession session_entry,
+					tpSirAssocReq assoc_req,
+					tpLimMlmAssocInd assoc_ind,
+					tpDphHashNode sta_ds)
+{
+	uint8_t chan;
+	uint8_t i;
+	bool nw_type_11b = true;
+
+	if (session_entry->limRFBand == BAND_2G) {
+		if (session_entry->vhtCapability && assoc_req->VHTCaps.present)
+			assoc_ind->chan_info.info = MODE_11AC_VHT20_2G;
+		else if (session_entry->htCapability
+			    && assoc_req->HTCaps.present)
+			assoc_ind->chan_info.info = MODE_11NG_HT20;
+		else {
+			for (i = 0; i < SIR_NUM_11A_RATES; i++) {
+				if (sirIsArate(sta_ds->
+					       supportedRates.llaRates[i]
+					       & 0x7F)) {
+					assoc_ind->chan_info.info = MODE_11G;
+					nw_type_11b = false;
+					break;
+				}
+			}
+			if (nw_type_11b)
+				assoc_ind->chan_info.info = MODE_11B;
+		}
+		return;
+	}
+
+	if (session_entry->vhtCapability && assoc_req->VHTCaps.present) {
+		if ((session_entry->ch_width > CH_WIDTH_40MHZ)
+		    && assoc_req->HTCaps.supportedChannelWidthSet) {
+			chan = session_entry->ch_center_freq_seg0;
+			assoc_ind->chan_info.band_center_freq1 =
+				cds_chan_to_freq(chan);
+			assoc_ind->chan_info.info = MODE_11AC_VHT80;
+			return;
+		}
+
+		if ((session_entry->ch_width == CH_WIDTH_40MHZ)
+			&& assoc_req->HTCaps.supportedChannelWidthSet) {
+			assoc_ind->chan_info.info = MODE_11AC_VHT40;
+			if (session_entry->htSecondaryChannelOffset ==
+			    PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+				assoc_ind->chan_info.band_center_freq1 += 10;
+			else
+				assoc_ind->chan_info.band_center_freq1 -= 10;
+			return;
+		}
+
+		assoc_ind->chan_info.info = MODE_11AC_VHT20;
+		return;
+	}
+
+	if (session_entry->htCapability && assoc_req->HTCaps.present) {
+		if ((session_entry->ch_width == CH_WIDTH_40MHZ)
+		    && assoc_req->HTCaps.supportedChannelWidthSet) {
+			assoc_ind->chan_info.info = MODE_11NA_HT40;
+			if (session_entry->htSecondaryChannelOffset ==
+			    PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+				assoc_ind->chan_info.band_center_freq1 += 10;
+			else
+				assoc_ind->chan_info.band_center_freq1 -= 10;
+			return;
+		}
+
+		assoc_ind->chan_info.info = MODE_11NA_HT20;
+		return;
+	}
+
+	assoc_ind->chan_info.info = MODE_11A;
+	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
+ * @sta_ds: Station DPH hash entry
+ * @session_entry: PE session entry
+ *
+ * This function sends either LIM_MLM_ASSOC_IND
+ * or LIM_MLM_REASSOC_IND to SME.
+ *
+ * Return: None
+ */
+void lim_send_mlm_assoc_ind(tpAniSirGlobal mac_ctx,
+	tpDphHashNode sta_ds, tpPESession session_entry)
+{
+	tpLimMlmAssocInd assoc_ind = NULL;
+	tpSirAssocReq assoc_req;
+	uint16_t temp, rsn_len;
+	uint32_t phy_mode;
+	uint8_t sub_type;
+	const uint8_t *wpsie = NULL;
+	uint8_t maxidx, i;
+	bool wme_enable;
+
+	/* Get a copy of the already parsed Assoc Request */
+	assoc_req =
+		(tpSirAssocReq) session_entry->parsedAssocReq[sta_ds->assocId];
+
+	/* Get the phy_mode */
+	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+	/* Determine if its Assoc or ReAssoc Request */
+	if (assoc_req->reassocRequest == 1)
+		sub_type = LIM_REASSOC;
+	else
+		sub_type = LIM_ASSOC;
+
+	pe_debug("Sessionid: %d ssid: %s sub_type: %d Associd: %d staAddr: "
+		 MAC_ADDRESS_STR, session_entry->peSessionId,
+		assoc_req->ssId.ssId, sub_type, sta_ds->assocId,
+		MAC_ADDR_ARRAY(sta_ds->staAddr));
+
+	if (sub_type == LIM_ASSOC || sub_type == LIM_REASSOC) {
+		temp = sizeof(tLimMlmAssocInd);
+
+		assoc_ind = qdf_mem_malloc(temp);
+		if (!assoc_ind) {
+			lim_release_peer_idx(mac_ctx, sta_ds->assocId,
+				session_entry);
+			return;
+		}
+		qdf_mem_copy((uint8_t *) assoc_ind->peerMacAddr,
+			(uint8_t *) sta_ds->staAddr, sizeof(tSirMacAddr));
+		assoc_ind->aid = sta_ds->assocId;
+		qdf_mem_copy((uint8_t *) &assoc_ind->ssId,
+			(uint8_t *) &(assoc_req->ssId),
+			assoc_req->ssId.length + 1);
+		assoc_ind->sessionId = session_entry->peSessionId;
+		assoc_ind->authType = sta_ds->mlmStaContext.authType;
+		assoc_ind->capabilityInfo = assoc_req->capabilityInfo;
+
+		/* Fill in RSN IE information */
+		assoc_ind->rsnIE.length = 0;
+		/* if WPS IE is present, ignore RSN IE */
+		if (assoc_req->addIEPresent && assoc_req->addIE.length) {
+			wpsie = limGetWscIEPtr(mac_ctx,
+				assoc_req->addIE.addIEdata,
+				assoc_req->addIE.length);
+		}
+		if (assoc_req->rsnPresent && (NULL == wpsie)) {
+			pe_debug("Assoc Req RSN IE len: %d",
+				assoc_req->rsn.length);
+			assoc_ind->rsnIE.length = 2 + assoc_req->rsn.length;
+			assoc_ind->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
+			assoc_ind->rsnIE.rsnIEdata[1] =
+				assoc_req->rsn.length;
+			qdf_mem_copy(&assoc_ind->rsnIE.rsnIEdata[2],
+				assoc_req->rsn.info,
+				assoc_req->rsn.length);
+		}
+		/* Fill in 802.11h related info */
+		if (assoc_req->powerCapabilityPresent
+			&& assoc_req->supportedChannelsPresent) {
+			assoc_ind->spectrumMgtIndicator = true;
+			assoc_ind->powerCap.minTxPower =
+				assoc_req->powerCapability.minTxPower;
+			assoc_ind->powerCap.maxTxPower =
+				assoc_req->powerCapability.maxTxPower;
+			lim_convert_supported_channels(mac_ctx, assoc_ind,
+				 assoc_req);
+		} else {
+			assoc_ind->spectrumMgtIndicator = false;
+		}
+
+		/* This check is to avoid extra Sec IEs present incase of WPS */
+		if (assoc_req->wpaPresent && (NULL == wpsie)) {
+			rsn_len = assoc_ind->rsnIE.length;
+			if ((rsn_len + assoc_req->wpa.length)
+				>= SIR_MAC_MAX_IE_LENGTH) {
+				pe_err("rsnIEdata index out of bounds: %d",
+					rsn_len);
+				qdf_mem_free(assoc_ind);
+				return;
+			}
+			assoc_ind->rsnIE.rsnIEdata[rsn_len] =
+				SIR_MAC_WPA_EID;
+			assoc_ind->rsnIE.rsnIEdata[rsn_len + 1]
+				= assoc_req->wpa.length;
+			qdf_mem_copy(
+				&assoc_ind->rsnIE.rsnIEdata[rsn_len + 2],
+				assoc_req->wpa.info, assoc_req->wpa.length);
+			assoc_ind->rsnIE.length += 2 + assoc_req->wpa.length;
+		}
+#ifdef FEATURE_WLAN_WAPI
+		lim_fill_assoc_ind_wapi_info(mac_ctx, assoc_req, assoc_ind,
+			wpsie);
+#endif
+
+		assoc_ind->addIE.length = 0;
+		if (assoc_req->addIEPresent) {
+			qdf_mem_copy(&assoc_ind->addIE.addIEdata,
+				assoc_req->addIE.addIEdata,
+				assoc_req->addIE.length);
+			assoc_ind->addIE.length = assoc_req->addIE.length;
+		}
+		/*
+		 * Add HT Capabilities into addIE for OBSS
+		 * processing in hostapd
+		 */
+		if (assoc_req->HTCaps.present) {
+			qdf_mem_copy(&assoc_ind->ht_caps, &assoc_req->HTCaps,
+				     sizeof(tDot11fIEHTCaps));
+
+			rsn_len = assoc_ind->addIE.length;
+			if (assoc_ind->addIE.length + DOT11F_IE_HTCAPS_MIN_LEN
+				+ 2 < SIR_MAC_MAX_IE_LENGTH) {
+				assoc_ind->addIE.addIEdata[rsn_len] =
+					SIR_MAC_HT_CAPABILITIES_EID;
+				assoc_ind->addIE.addIEdata[rsn_len + 1] =
+					DOT11F_IE_HTCAPS_MIN_LEN;
+				qdf_mem_copy(
+					&assoc_ind->addIE.addIEdata[rsn_len+2],
+					((uint8_t *)&assoc_req->HTCaps) + 1,
+					DOT11F_IE_HTCAPS_MIN_LEN);
+				assoc_ind->addIE.length +=
+					2 + DOT11F_IE_HTCAPS_MIN_LEN;
+			} else {
+				pe_err("Fail:HT capabilities IE to addIE");
+			}
+		}
+
+		if (assoc_req->wmeInfoPresent) {
+			/* Set whether AP is enabled with WMM or not */
+			wme_enable = mac_ctx->mlme_cfg->wmm_params.wme_enabled;
+			assoc_ind->WmmStaInfoPresent = wme_enable;
+			/*
+			 * Note: we are not rejecting association here
+			 * because IOT will fail
+			 */
+		}
+		/* Required for indicating the frames to upper layer */
+		assoc_ind->assocReqLength = assoc_req->assocReqFrameLength;
+		assoc_ind->assocReqPtr = assoc_req->assocReqFrame;
+
+		assoc_ind->beaconPtr = session_entry->beacon;
+		assoc_ind->beaconLength = session_entry->bcnLen;
+
+		assoc_ind->chan_info.chan_id =
+			session_entry->currentOperChannel;
+		assoc_ind->chan_info.mhz =
+			cds_chan_to_freq(session_entry->currentOperChannel);
+		assoc_ind->chan_info.band_center_freq1 =
+			cds_chan_to_freq(session_entry->currentOperChannel);
+		assoc_ind->chan_info.band_center_freq2 = 0;
+		assoc_ind->chan_info.reg_info_1 =
+			(session_entry->maxTxPower << 16);
+		assoc_ind->chan_info.reg_info_2 =
+			(session_entry->maxTxPower << 8);
+		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);
+		if (assoc_req->ExtCap.present)
+			assoc_ind->ecsa_capable =
+			((struct s_ext_cap *)assoc_req->ExtCap.bytes)->
+			ext_chan_switch;
+
+		/* updates VHT information in assoc indication */
+		 qdf_mem_copy(&assoc_ind->vht_caps, &assoc_req->VHTCaps,
+			      sizeof(tDot11fIEVHTCaps));
+		lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req,
+					    assoc_ind, sta_ds);
+		lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_IND,
+			 (uint32_t *) assoc_ind);
+		qdf_mem_free(assoc_ind);
+	}
+	return;
+}
diff --git a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c
new file mode 100644
index 0000000..efa9f31
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_process_assoc_rsp_frame.cc contains the code
+ * for processing Re/Association Response Frame.
+ * Author:        Chandra Modumudi
+ * Date:          03/18/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+#include "sch_api.h"
+
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_sta_hash_api.h"
+#include "lim_send_messages.h"
+#include "lim_process_fils.h"
+
+extern QDF_STATUS sch_beacon_edca_process(tpAniSirGlobal pMac,
+	tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry);
+
+/**
+ * lim_update_stads_htcap() - Updates station Descriptor HT capability
+ * @mac_ctx: Pointer to Global MAC structure
+ * @sta_ds: Station Descriptor in DPH
+ * @assoc_rsp: Pointer to Association Response Structure
+ * @session_entry : PE session Entry
+ *
+ * This function is called to Update the HT capabilities in
+ * Station Descriptor (dph) Details from
+ * Association / ReAssociation Response Frame
+ *
+ * Return: None
+ */
+static void lim_update_stads_htcap(tpAniSirGlobal mac_ctx,
+		tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
+		tpPESession session_entry)
+{
+	uint16_t highest_rxrate = 0;
+	tDot11fIEHTCaps *ht_caps;
+
+	ht_caps = &assoc_rsp->HTCaps;
+	sta_ds->mlmStaContext.htCapability = assoc_rsp->HTCaps.present;
+	if (assoc_rsp->HTCaps.present) {
+		sta_ds->htGreenfield =
+			(uint8_t) ht_caps->greenField;
+		if (session_entry->htSupportedChannelWidthSet) {
+			sta_ds->htSupportedChannelWidthSet =
+				(uint8_t) (ht_caps->supportedChannelWidthSet ?
+				assoc_rsp->HTInfo.recommendedTxWidthSet :
+				ht_caps->supportedChannelWidthSet);
+		} else
+			sta_ds->htSupportedChannelWidthSet =
+				eHT_CHANNEL_WIDTH_20MHZ;
+		sta_ds->htLsigTXOPProtection =
+			(uint8_t) ht_caps->lsigTXOPProtection;
+		sta_ds->htMIMOPSState =
+			(tSirMacHTMIMOPowerSaveState)ht_caps->mimoPowerSave;
+		sta_ds->htMaxAmsduLength =
+			(uint8_t) ht_caps->maximalAMSDUsize;
+		sta_ds->htAMpduDensity = ht_caps->mpduDensity;
+		sta_ds->htDsssCckRate40MHzSupport =
+			(uint8_t) ht_caps->dsssCckMode40MHz;
+		sta_ds->htMaxRxAMpduFactor =
+			ht_caps->maxRxAMPDUFactor;
+		lim_fill_rx_highest_supported_rate(mac_ctx, &highest_rxrate,
+			ht_caps->supportedMCSSet);
+		sta_ds->supportedRates.rxHighestDataRate =
+			highest_rxrate;
+		/*
+		 * This is for AP as peer STA and we are INFRA STA
+		 *.We will put APs offset in dph node which is peer STA
+		 */
+		sta_ds->htSecondaryChannelOffset =
+			(uint8_t) assoc_rsp->HTInfo.secondaryChannelOffset;
+		/*
+		 * FIXME_AMPDU
+		 * In the future, may need to check for
+		 * "assoc.HTCaps.delayedBA"
+		 * For now, it is IMMEDIATE BA only on ALL TID's
+		 */
+		sta_ds->baPolicyFlag = 0xFF;
+
+		/* Check if we have support for gShortGI20Mhz and
+		 * gShortGI40Mhz from ini file
+		 */
+		if (session_entry->htConfig.ht_sgi20)
+			sta_ds->htShortGI20Mhz =
+			      (uint8_t)assoc_rsp->HTCaps.shortGI20MHz;
+		else
+			sta_ds->htShortGI20Mhz = false;
+
+		if (session_entry->htConfig.ht_sgi40)
+			sta_ds->htShortGI40Mhz =
+				      (uint8_t)assoc_rsp->HTCaps.shortGI40MHz;
+		else
+			sta_ds->htShortGI40Mhz = false;
+	}
+}
+
+/**
+ * lim_update_assoc_sta_datas() - Updates station Descriptor
+ * mac_ctx: Pointer to Global MAC structure
+ * sta_ds: Station Descriptor in DPH
+ * assoc_rsp: Pointer to Association Response Structure
+ * session_entry : PE session Entry
+ *
+ * This function is called to Update the Station Descriptor (dph) Details from
+ * Association / ReAssociation Response Frame
+ *
+ * Return: None
+ */
+void lim_update_assoc_sta_datas(tpAniSirGlobal mac_ctx,
+	tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
+	tpPESession session_entry)
+{
+	uint32_t phy_mode;
+	bool qos_mode;
+	tDot11fIEVHTCaps *vht_caps = NULL;
+	tDot11fIEhe_cap *he_cap = NULL;
+
+	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+	sta_ds->staType = STA_ENTRY_SELF;
+	limGetQosMode(session_entry, &qos_mode);
+	sta_ds->mlmStaContext.authType = session_entry->limCurrentAuthType;
+
+	/* Add capabilities information, rates and AID */
+	sta_ds->mlmStaContext.capabilityInfo = assoc_rsp->capabilityInfo;
+	sta_ds->shortPreambleEnabled =
+		(uint8_t) assoc_rsp->capabilityInfo.shortPreamble;
+
+	/* Update HT Capabilities only when the self mode supports HT */
+	if (IS_DOT11_MODE_HT(session_entry->dot11mode))
+		lim_update_stads_htcap(mac_ctx, sta_ds, assoc_rsp,
+				       session_entry);
+
+	if (assoc_rsp->VHTCaps.present)
+		vht_caps = &assoc_rsp->VHTCaps;
+	else if (assoc_rsp->vendor_vht_ie.VHTCaps.present)
+		vht_caps = &assoc_rsp->vendor_vht_ie.VHTCaps;
+
+	if (IS_DOT11_MODE_VHT(session_entry->dot11mode)) {
+		if ((vht_caps != NULL) && vht_caps->present) {
+			sta_ds->mlmStaContext.vhtCapability =
+				vht_caps->present;
+			/*
+			 * If 11ac is supported and if the peer is
+			 * sending VHT capabilities,
+			 * then htMaxRxAMpduFactor should be
+			 * overloaded with VHT maxAMPDULenExp
+			 */
+			sta_ds->htMaxRxAMpduFactor = vht_caps->maxAMPDULenExp;
+			if (session_entry->htSupportedChannelWidthSet) {
+				if (assoc_rsp->VHTOperation.present)
+					sta_ds->vhtSupportedChannelWidthSet =
+					assoc_rsp->VHTOperation.chanWidth;
+				else
+					sta_ds->vhtSupportedChannelWidthSet =
+						eHT_CHANNEL_WIDTH_40MHZ;
+			}
+		}
+	}
+
+	if (IS_DOT11_MODE_HE(session_entry->dot11mode))
+		lim_update_stads_he_caps(sta_ds, assoc_rsp, session_entry);
+
+	if (lim_is_sta_he_capable(sta_ds))
+		he_cap = &assoc_rsp->he_cap;
+
+	if (lim_populate_peer_rate_set(mac_ctx, &sta_ds->supportedRates,
+				assoc_rsp->HTCaps.supportedMCSSet,
+				false, session_entry,
+				vht_caps, he_cap) != QDF_STATUS_SUCCESS) {
+		pe_err("could not get rateset and extended rate set");
+		return;
+	}
+	sta_ds->vhtSupportedRxNss =
+		((sta_ds->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2)
+		 == MCSMAPMASK2x2) ? 1 : 2;
+
+	/* If one of the rates is 11g rates, set the ERP mode. */
+	if ((phy_mode == WNI_CFG_PHY_MODE_11G) &&
+		sirIsArate(sta_ds->supportedRates.llaRates[0] & 0x7f))
+		sta_ds->erpEnabled = eHAL_SET;
+
+	/* Could not get prop rateset from CFG. Log error. */
+	sta_ds->qosMode = 0;
+	sta_ds->lleEnabled = 0;
+
+	/* update TSID to UP mapping */
+	if (qos_mode) {
+		if (assoc_rsp->edcaPresent) {
+			QDF_STATUS status;
+
+			status =
+				sch_beacon_edca_process(mac_ctx,
+					&assoc_rsp->edca, session_entry);
+			pe_debug("Edca set update based on AssocRsp: status %d",
+				status);
+			if (status != QDF_STATUS_SUCCESS) {
+				pe_err("Edca error in AssocResp");
+			} else {
+				/* update default tidmap based on ACM */
+				sta_ds->qosMode = 1;
+				sta_ds->lleEnabled = 1;
+			}
+		}
+	}
+
+	sta_ds->wmeEnabled = 0;
+	sta_ds->wsmEnabled = 0;
+	if (session_entry->limWmeEnabled && assoc_rsp->wmeEdcaPresent) {
+		QDF_STATUS status;
+
+		status = sch_beacon_edca_process(mac_ctx, &assoc_rsp->edca,
+				session_entry);
+		pe_debug("WME Edca set update based on AssocRsp: status %d",
+			status);
+
+		if (status != QDF_STATUS_SUCCESS)
+			pe_err("WME Edca error in AssocResp - ignoring");
+
+			else {
+				/* update default tidmap based on HashACM */
+				sta_ds->qosMode = 1;
+				sta_ds->wmeEnabled = 1;
+			}
+	} else {
+		/*
+		 * We received assoc rsp from a legacy AP.
+		 * So fill in the default  local EDCA params.
+		 * This is needed (refer to bug #14989) as we'll
+		 * be passing the gLimEdcaParams to HAL in
+		 * lim_process_sta_mlm_add_bss_rsp().
+		 */
+		sch_set_default_edca_params(mac_ctx, session_entry);
+	}
+
+	if (qos_mode && (!sta_ds->qosMode) &&
+		 sta_ds->mlmStaContext.htCapability) {
+		/*
+		 * Enable QOS for all HT AP's even though WMM
+		 * or 802.11E IE is not present
+		 */
+		sta_ds->qosMode = 1;
+		sta_ds->wmeEnabled = 1;
+	}
+#ifdef WLAN_FEATURE_11W
+	if (session_entry->limRmfEnabled)
+		sta_ds->rmfEnabled = 1;
+#endif
+}
+
+/**
+ * lim_update_ric_data() - update session with ric data
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_entry: PE session handle
+ * @assoc_rsp:  pointer to assoc response
+ *
+ * This function is called by lim_process_assoc_rsp_frame() to
+ * update PE session context with RIC data.
+ *
+ * Return: None
+ */
+static void lim_update_ric_data(tpAniSirGlobal mac_ctx,
+	 tpPESession session_entry, tpSirAssocRsp assoc_rsp)
+{
+	if (session_entry->ricData != NULL) {
+		qdf_mem_free(session_entry->ricData);
+		session_entry->ricData = NULL;
+		session_entry->RICDataLen = 0;
+	}
+	if (assoc_rsp->ricPresent) {
+		session_entry->RICDataLen =
+			assoc_rsp->num_RICData * sizeof(tDot11fIERICDataDesc);
+		if (session_entry->RICDataLen) {
+			session_entry->ricData =
+				qdf_mem_malloc(session_entry->RICDataLen);
+			if (!session_entry->ricData)
+				session_entry->RICDataLen = 0;
+			else
+				qdf_mem_copy(session_entry->ricData,
+					&assoc_rsp->RICData[0],
+					session_entry->RICDataLen);
+		} else {
+			pe_err("RIC data not present");
+		}
+	} else {
+		pe_debug("Ric is not present");
+		session_entry->RICDataLen = 0;
+		session_entry->ricData = NULL;
+	}
+	return;
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * lim_update_ese_tspec() - update session with Tspec info.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_entry: PE session handle
+ * @assoc_rsp:  pointer to assoc response
+ *
+ * This function is called by lim_process_assoc_rsp_frame() to
+ * update PE session context with Tspec data.
+ *
+ * Return: None
+ */
+static void lim_update_ese_tspec(tpAniSirGlobal mac_ctx,
+	 tpPESession session_entry, tpSirAssocRsp assoc_rsp)
+{
+	if (session_entry->tspecIes != NULL) {
+		qdf_mem_free(session_entry->tspecIes);
+		session_entry->tspecIes = NULL;
+		session_entry->tspecLen = 0;
+	}
+	if (assoc_rsp->tspecPresent) {
+		pe_debug("Tspec EID present in assoc rsp");
+		session_entry->tspecLen =
+			assoc_rsp->num_tspecs * sizeof(tDot11fIEWMMTSPEC);
+		if (session_entry->tspecLen) {
+			session_entry->tspecIes =
+				qdf_mem_malloc(session_entry->tspecLen);
+			if (!session_entry->tspecIes)
+				session_entry->tspecLen = 0;
+			else
+				qdf_mem_copy(session_entry->tspecIes,
+						&assoc_rsp->TSPECInfo[0],
+						session_entry->tspecLen);
+		} else {
+			pe_err("TSPEC has Zero length");
+		}
+	} else {
+		session_entry->tspecLen = 0;
+		session_entry->tspecIes = NULL;
+		pe_debug("Tspec EID *NOT* present in assoc rsp");
+	}
+	return;
+}
+
+/**
+ * lim_update_ese_tsm() - update session with TSM info.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_entry: PE session handle
+ * @assoc_rsp:  pointer to assoc response
+ *
+ * This function is called by lim_process_assoc_rsp_frame() to
+ * update PE session context with TSM IE data and send
+ * eWNI_TSM_IE_IND to SME.
+ *
+ * Return: None
+ */
+static void lim_update_ese_tsm(tpAniSirGlobal mac_ctx,
+	 tpPESession session_entry, tpSirAssocRsp assoc_rsp)
+{
+	uint8_t cnt = 0;
+	tpEseTSMContext tsm_ctx;
+
+	pe_debug("TSM IE Present in Reassoc Rsp");
+	/*
+	 * Start the TSM  timer only if the TSPEC
+	 * Ie is present in the reassoc rsp
+	 */
+	if (!assoc_rsp->tspecPresent) {
+		pe_err("TSM present but TSPEC IE not present");
+		return;
+	}
+	tsm_ctx = &session_entry->eseContext.tsm;
+	/* Find the TSPEC IE with VO user priority */
+	for (cnt = 0; cnt < assoc_rsp->num_tspecs; cnt++) {
+		if (upToAc(assoc_rsp->TSPECInfo[cnt].user_priority) ==
+			EDCA_AC_VO) {
+			tsm_ctx->tid =
+				assoc_rsp->TSPECInfo[cnt].user_priority;
+			qdf_mem_copy(&tsm_ctx->tsmInfo,
+				&assoc_rsp->tsmIE, sizeof(tSirMacESETSMIE));
+			lim_send_sme_tsm_ie_ind(mac_ctx,
+				session_entry, assoc_rsp->tsmIE.tsid,
+				assoc_rsp->tsmIE.state,
+				assoc_rsp->tsmIE.msmt_interval);
+			if (tsm_ctx->tsmInfo.state)
+				tsm_ctx->tsmMetrics.RoamingCount++;
+			break;
+		}
+	}
+}
+#endif
+
+/**
+ * lim_update_stads_ext_cap() - update sta ds with ext cap
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_entry: PE session handle
+ * @assoc_rsp:  pointer to assoc response
+ *
+ * This function is called by lim_process_assoc_rsp_frame() to
+ * update STA DS with ext capablities.
+ *
+ * Return: None
+ */
+static void lim_update_stads_ext_cap(tpAniSirGlobal mac_ctx,
+	tpPESession session_entry, tpSirAssocRsp assoc_rsp,
+	tpDphHashNode sta_ds)
+{
+	struct s_ext_cap *ext_cap;
+
+	if (!assoc_rsp->ExtCap.present) {
+		sta_ds->timingMeasCap = 0;
+#ifdef FEATURE_WLAN_TDLS
+		session_entry->tdls_prohibited = false;
+		session_entry->tdls_chan_swit_prohibited = false;
+#endif
+		pe_debug("ExtCap not present");
+		return;
+	}
+
+	ext_cap = (struct s_ext_cap *)assoc_rsp->ExtCap.bytes;
+	lim_set_stads_rtt_cap(sta_ds, ext_cap, mac_ctx);
+#ifdef FEATURE_WLAN_TDLS
+	session_entry->tdls_prohibited = ext_cap->tdls_prohibited;
+	session_entry->tdls_chan_swit_prohibited =
+		ext_cap->tdls_chan_swit_prohibited;
+	pe_debug("ExtCap: tdls_prohibited: %d tdls_chan_swit_prohibited: %d",
+		ext_cap->tdls_prohibited,
+		ext_cap->tdls_chan_swit_prohibited);
+#endif
+	lim_set_peer_twt_cap(session_entry, ext_cap);
+}
+
+/**
+ * lim_stop_reassoc_retry_timer() - Cleanup after reassoc response is received
+ *  @mac_ctx: Global MAC context
+ *
+ *  Stop the reassoc retry timer and release the stored reassoc request.
+ *
+ *  Return: None
+ */
+static void lim_stop_reassoc_retry_timer(tpAniSirGlobal mac_ctx)
+{
+	mac_ctx->lim.reAssocRetryAttempt = 0;
+	if ((NULL != mac_ctx->lim.pSessionEntry)
+		&& (NULL !=
+			mac_ctx->lim.pSessionEntry->pLimMlmReassocRetryReq)) {
+		qdf_mem_free(
+			mac_ctx->lim.pSessionEntry->pLimMlmReassocRetryReq);
+		mac_ctx->lim.pSessionEntry->pLimMlmReassocRetryReq = NULL;
+	}
+	lim_deactivate_and_change_timer(mac_ctx, eLIM_REASSOC_FAIL_TIMER);
+}
+
+/**
+ * lim_process_assoc_rsp_frame() - Processes assoc response
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_packet_info    - A pointer to Rx packet info structure
+ * @sub_type - Indicates whether it is Association Response (=0) or
+ *                   Reassociation Response (=1) frame
+ *
+ * This function is called by limProcessMessageQueue() upon
+ * Re/Association Response frame reception.
+ *
+ * Return: None
+ */
+
+void
+lim_process_assoc_rsp_frame(tpAniSirGlobal mac_ctx,
+	uint8_t *rx_pkt_info, uint8_t subtype, tpPESession session_entry)
+{
+	uint8_t *body;
+	uint16_t caps, ie_len;
+	uint32_t frame_len;
+	tSirMacAddr current_bssid;
+	tpSirMacMgmtHdr hdr = NULL;
+	tSirMacCapabilityInfo mac_capab;
+	tpDphHashNode sta_ds;
+	tpSirAssocRsp assoc_rsp;
+	tLimMlmAssocCnf assoc_cnf;
+	tSchBeaconStruct *beacon;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	uint8_t sme_sessionid = 0;
+	struct csr_roam_session *roam_session;
+#endif
+	/* Initialize status code to success. */
+	if (lim_is_roam_synch_in_progress(session_entry))
+		hdr = (tpSirMacMgmtHdr) mac_ctx->roam.pReassocResp;
+	else
+		hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	sme_sessionid = session_entry->smeSessionId;
+#endif
+	assoc_cnf.resultCode = eSIR_SME_SUCCESS;
+	/* Update PE session Id */
+	assoc_cnf.sessionId = session_entry->peSessionId;
+	if (hdr == NULL) {
+		pe_err("LFR3: Reassoc response packet header is NULL");
+		return;
+	}
+
+	pe_debug("received Re/Assoc: %d resp on sessionid: %d systemrole: %d"
+		" and mlmstate: %d RSSI: %d from "MAC_ADDRESS_STR, subtype,
+		session_entry->peSessionId, GET_LIM_SYSTEM_ROLE(session_entry),
+		session_entry->limMlmState,
+		(uint) abs((int8_t) WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info)),
+		MAC_ADDR_ARRAY(hdr->sa));
+
+	beacon = qdf_mem_malloc(sizeof(tSchBeaconStruct));
+	if (!beacon)
+		return;
+
+	if (LIM_IS_AP_ROLE(session_entry)) {
+		/*
+		 * Should not have received Re/Association
+		 * Response frame on AP. Log error
+		 */
+		pe_err("Should not received Re/Assoc Response in role: %d",
+			GET_LIM_SYSTEM_ROLE(session_entry));
+		qdf_mem_free(beacon);
+		return;
+	}
+	if (lim_is_roam_synch_in_progress(session_entry)) {
+		hdr = (tpSirMacMgmtHdr) mac_ctx->roam.pReassocResp;
+		frame_len = mac_ctx->roam.reassocRespLen - SIR_MAC_HDR_LEN_3A;
+	} else {
+		hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+		frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+	}
+	if (((subtype == LIM_ASSOC) &&
+		(session_entry->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE)) ||
+		((subtype == LIM_REASSOC) &&
+		 !lim_is_roam_synch_in_progress(session_entry) &&
+		((session_entry->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE)
+		&& (session_entry->limMlmState !=
+		eLIM_MLM_WT_FT_REASSOC_RSP_STATE)
+		))) {
+		/* Received unexpected Re/Association Response frame */
+		pe_debug("Received Re/Assoc rsp in unexpected state: %d on session: %d",
+			session_entry->limMlmState, session_entry->peSessionId);
+		if (!hdr->fc.retry) {
+			if (!(mac_ctx->lim.retry_packet_cnt & 0xf)) {
+				pe_err("recvd Re/Assoc rsp:not a retry frame");
+				lim_print_mlm_state(mac_ctx, LOGE,
+						session_entry->limMlmState);
+			} else {
+				mac_ctx->lim.retry_packet_cnt++;
+			}
+		}
+		qdf_mem_free(beacon);
+		return;
+	}
+	sir_copy_mac_addr(current_bssid, session_entry->bssId);
+	if (subtype == LIM_ASSOC) {
+		if (qdf_mem_cmp
+			(hdr->sa, current_bssid, sizeof(tSirMacAddr))) {
+			/*
+			 * Received Association Response frame from an entity
+			 * other than one to which request was initiated.
+			 * Ignore this and wait until Assoc Failure Timeout
+			 */
+			pe_warn("received AssocRsp from unexpected peer "MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(hdr->sa));
+			qdf_mem_free(beacon);
+			return;
+		}
+	} else {
+		if (qdf_mem_cmp
+			(hdr->sa, session_entry->limReAssocbssId,
+			sizeof(tSirMacAddr))) {
+			/*
+			 * Received Reassociation Response frame from an entity
+			 * other than one to which request was initiated.
+			 * Ignore this and wait until Reassoc Failure Timeout.
+			 */
+			pe_warn("received ReassocRsp from unexpected peer "MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(hdr->sa));
+			qdf_mem_free(beacon);
+			return;
+		}
+	}
+
+	assoc_rsp = qdf_mem_malloc(sizeof(*assoc_rsp));
+	if (!assoc_rsp) {
+		qdf_mem_free(beacon);
+		return;
+	}
+	/* Get pointer to Re/Association Response frame body */
+	if (lim_is_roam_synch_in_progress(session_entry))
+		body = mac_ctx->roam.pReassocResp + SIR_MAC_HDR_LEN_3A;
+	else
+		body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	/* parse Re/Association Response frame. */
+	if (sir_convert_assoc_resp_frame2_struct(mac_ctx, session_entry, body,
+		frame_len, assoc_rsp) == QDF_STATUS_E_FAILURE) {
+		qdf_mem_free(assoc_rsp);
+		pe_err("Parse error Assoc resp subtype: %d" "length: %d",
+			frame_len, subtype);
+		qdf_mem_free(beacon);
+		return;
+	}
+
+	if (!assoc_rsp->suppRatesPresent) {
+		pe_debug("assoc response does not have supported rate set");
+		qdf_mem_copy(&assoc_rsp->supportedRates,
+			&session_entry->rateSet,
+			sizeof(tSirMacRateSet));
+	}
+
+	assoc_cnf.protStatusCode = assoc_rsp->statusCode;
+	if (session_entry->assocRsp != NULL) {
+		pe_warn("session_entry->assocRsp is not NULL freeing it and setting NULL");
+		qdf_mem_free(session_entry->assocRsp);
+		session_entry->assocRsp = NULL;
+		session_entry->assocRspLen = 0;
+	}
+
+	if (frame_len) {
+		session_entry->assocRsp = qdf_mem_malloc(frame_len);
+		if (session_entry->assocRsp) {
+			/*
+			 * Store the Assoc response. This is sent
+			 * to csr/hdd in join cnf response.
+			 */
+			qdf_mem_copy(session_entry->assocRsp, body, frame_len);
+			session_entry->assocRspLen = frame_len;
+		}
+	}
+
+	lim_update_ric_data(mac_ctx, session_entry, assoc_rsp);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	roam_session =
+		&mac_ctx->roam.roamSession[sme_sessionid];
+	if (assoc_rsp->FTInfo.R0KH_ID.present) {
+		roam_session->ftSmeContext.r0kh_id_len =
+			assoc_rsp->FTInfo.R0KH_ID.num_PMK_R0_ID;
+		qdf_mem_copy(roam_session->ftSmeContext.r0kh_id,
+			assoc_rsp->FTInfo.R0KH_ID.PMK_R0_ID,
+			roam_session->ftSmeContext.r0kh_id_len);
+	} else {
+		roam_session->ftSmeContext.r0kh_id_len = 0;
+		qdf_mem_zero(roam_session->ftSmeContext.r0kh_id,
+			SIR_ROAM_R0KH_ID_MAX_LEN);
+	}
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+	lim_update_ese_tspec(mac_ctx, session_entry, assoc_rsp);
+#endif
+
+	if (assoc_rsp->capabilityInfo.ibss) {
+		/*
+		 * Received Re/Association Response from peer
+		 * with IBSS capability set.
+		 * Ignore the frame and wait until Re/assoc
+		 * failure timeout.
+		 */
+		pe_err("received Re/AssocRsp frame with IBSS capability");
+		qdf_mem_free(assoc_rsp);
+		qdf_mem_free(beacon);
+		return;
+	}
+
+	if (cfg_get_capability_info(mac_ctx, &caps, session_entry)
+		!= QDF_STATUS_SUCCESS) {
+		qdf_mem_free(assoc_rsp);
+		qdf_mem_free(beacon);
+		pe_err("could not retrieve Capabilities");
+		return;
+	}
+	lim_copy_u16((uint8_t *) &mac_capab, caps);
+
+	/* Stop Association failure timer */
+	if (subtype == LIM_ASSOC)
+		lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER);
+	else
+		lim_stop_reassoc_retry_timer(mac_ctx);
+
+	if (eSIR_MAC_XS_FRAME_LOSS_POOR_CHANNEL_RSSI_STATUS ==
+	   assoc_rsp->statusCode &&
+	    assoc_rsp->rssi_assoc_rej.present)
+		lim_assoc_rej_add_to_rssi_based_reject_list(mac_ctx,
+			&assoc_rsp->rssi_assoc_rej, hdr->sa,
+			WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info));
+
+	if (assoc_rsp->statusCode != eSIR_MAC_SUCCESS_STATUS
+#ifdef WLAN_FEATURE_11W
+		&& (!session_entry->limRmfEnabled ||
+			assoc_rsp->statusCode != eSIR_MAC_TRY_AGAIN_LATER)
+#endif
+	    ) {
+		/*
+		 *Re/Association response was received
+		 * either with failure code.
+		*/
+		pe_err("received Re/AssocRsp frame failure code: %d",
+			 assoc_rsp->statusCode);
+		/*
+		 * Need to update 'association failure' error counter
+		 * along with STATUS CODE
+		 * Return Assoc confirm to SME with received failure code
+		*/
+		assoc_cnf.resultCode = eSIR_SME_ASSOC_REFUSED;
+		/* Delete Pre-auth context for the associated BSS */
+		if (lim_search_pre_auth_list(mac_ctx, hdr->sa))
+			lim_delete_pre_auth_node(mac_ctx, hdr->sa);
+		goto assocReject;
+	} else if ((assoc_rsp->aid & 0x3FFF) > 2007) {
+		/*
+		 * Re/Association response was received
+		 * with invalid AID value
+		*/
+		pe_err("received Re/AssocRsp frame with invalid aid: %X",
+			assoc_rsp->aid);
+		assoc_cnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED;
+		assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+		/* Send advisory Disassociation frame to AP */
+		lim_send_disassoc_mgmt_frame(mac_ctx,
+			eSIR_MAC_UNSPEC_FAILURE_REASON,
+			hdr->sa, session_entry, false);
+		goto assocReject;
+	}
+
+	/*
+	 * If it is FILS connection, check is FILS params are matching
+	 * with Authentication stage.
+	 */
+	if (!lim_verify_fils_params_assoc_rsp(mac_ctx, session_entry,
+						assoc_rsp, &assoc_cnf)) {
+		pe_err("FILS params doesnot match");
+		assoc_cnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED;
+		assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+		/* Send advisory Disassociation frame to AP */
+		lim_send_disassoc_mgmt_frame(mac_ctx,
+			eSIR_MAC_UNSPEC_FAILURE_REASON,
+			hdr->sa, session_entry, false);
+		goto assocReject;
+	}
+
+	/*
+	 * Association Response received with success code
+	 * Set the link state to POSTASSOC now that we have received
+	 * assoc/reassoc response
+	 * NOTE: for BTAMP case, it is being handled in
+	 * lim_process_mlm_assoc_req
+	 */
+#ifdef WLAN_FEATURE_11W
+	if (session_entry->limRmfEnabled &&
+		assoc_rsp->statusCode == eSIR_MAC_TRY_AGAIN_LATER) {
+		if (assoc_rsp->TimeoutInterval.present &&
+		(assoc_rsp->TimeoutInterval.timeoutType ==
+			SIR_MAC_TI_TYPE_ASSOC_COMEBACK)) {
+			uint16_t timeout_value =
+				assoc_rsp->TimeoutInterval.timeoutValue;
+			if (timeout_value < 10) {
+				/*
+				 * if this value is less than 10 then our timer
+				 * will fail to start and due to this we will
+				 * never re-attempt. Better modify the timer
+				 * value here.
+				 */
+				timeout_value = 10;
+			}
+			pe_debug("ASSOC res with eSIR_MAC_TRY_AGAIN_LATER recvd.Starting timer to wait timeout: %d",
+				timeout_value);
+			if (QDF_STATUS_SUCCESS !=
+				qdf_mc_timer_start(
+					&session_entry->pmfComebackTimer,
+					timeout_value)) {
+				pe_err("Failed to start comeback timer");
+
+				assoc_cnf.resultCode = eSIR_SME_ASSOC_REFUSED;
+				assoc_cnf.protStatusCode =
+					eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+				/*
+				 * Delete Pre-auth context for the
+				 * associated BSS
+				 */
+				if (lim_search_pre_auth_list(mac_ctx, hdr->sa))
+					lim_delete_pre_auth_node(mac_ctx,
+						hdr->sa);
+
+				goto assocReject;
+			}
+		} else {
+			pe_warn("ASSOC resp with try again event recvd, but try again time interval IE is wrong");
+
+			assoc_cnf.resultCode = eSIR_SME_ASSOC_REFUSED;
+			assoc_cnf.protStatusCode =
+				eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+			/* Delete Pre-auth context for the associated BSS */
+			if (lim_search_pre_auth_list(mac_ctx, hdr->sa))
+				lim_delete_pre_auth_node(mac_ctx, hdr->sa);
+
+			goto assocReject;
+		}
+		qdf_mem_free(beacon);
+		qdf_mem_free(assoc_rsp);
+		return;
+	}
+#endif
+	if (!lim_is_roam_synch_in_progress(session_entry)) {
+		if (lim_set_link_state
+			(mac_ctx, eSIR_LINK_POSTASSOC_STATE,
+			session_entry->bssId,
+			session_entry->selfMacAddr, NULL,
+			NULL) != QDF_STATUS_SUCCESS) {
+			pe_err("Set link state to POSTASSOC failed");
+			qdf_mem_free(beacon);
+			qdf_mem_free(assoc_rsp);
+			return;
+		}
+	}
+
+	if (assoc_rsp->QosMapSet.present)
+		qdf_mem_copy(&session_entry->QosMapSet,
+			&assoc_rsp->QosMapSet, sizeof(tSirQosMapSet));
+	else
+		qdf_mem_zero(&session_entry->QosMapSet, sizeof(tSirQosMapSet));
+
+	if (assoc_rsp->obss_scanparams.present)
+		lim_update_obss_scanparams(session_entry,
+				&assoc_rsp->obss_scanparams);
+
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT,
+			session_entry, assoc_rsp->statusCode ? QDF_STATUS_E_FAILURE :
+			QDF_STATUS_SUCCESS, assoc_rsp->statusCode);
+
+	if (subtype == LIM_REASSOC) {
+		pe_debug("Successfully Reassociated with BSS");
+#ifdef FEATURE_WLAN_ESE
+	if (assoc_rsp->tsmPresent)
+		lim_update_ese_tsm(mac_ctx, session_entry, assoc_rsp);
+#endif
+		if (session_entry->pLimMlmJoinReq) {
+			qdf_mem_free(session_entry->pLimMlmJoinReq);
+			session_entry->pLimMlmJoinReq = NULL;
+		}
+
+		session_entry->limAssocResponseData = (void *)assoc_rsp;
+		/*
+		 * Store the ReAssocRsp Frame in DphTable
+		 * to be used during processing DelSta and
+		 * DelBss to send AddBss again
+		 */
+		sta_ds =
+			dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+				&session_entry->dph.dphHashTable);
+
+		if (!sta_ds) {
+			pe_err("could not get hash entry at DPH for");
+			lim_print_mac_addr(mac_ctx, hdr->sa, LOGE);
+			assoc_cnf.resultCode =
+				eSIR_SME_INVALID_ASSOC_RSP_RXED;
+			assoc_cnf.protStatusCode =
+				eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+			/* Send advisory Disassociation frame to AP */
+			lim_send_disassoc_mgmt_frame(mac_ctx,
+				eSIR_MAC_UNSPEC_FAILURE_REASON, hdr->sa,
+				session_entry, false);
+			goto assocReject;
+		}
+		if ((session_entry->limMlmState ==
+		    eLIM_MLM_WT_FT_REASSOC_RSP_STATE) ||
+			lim_is_roam_synch_in_progress(session_entry)) {
+			pe_debug("Sending self sta");
+			lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp,
+				session_entry);
+			lim_update_stads_ext_cap(mac_ctx, session_entry,
+						 assoc_rsp, sta_ds);
+			/* Store assigned AID for TIM processing */
+			session_entry->limAID = assoc_rsp->aid & 0x3FFF;
+			/* Downgrade the EDCA parameters if needed */
+			lim_set_active_edca_params(mac_ctx,
+				session_entry->gLimEdcaParams,
+				session_entry);
+			/* Send the active EDCA parameters to HAL */
+			if (!lim_is_roam_synch_in_progress(session_entry)) {
+				lim_send_edca_params(mac_ctx,
+					session_entry->gLimEdcaParamsActive,
+					sta_ds->bssId, false);
+				lim_add_ft_sta_self(mac_ctx,
+					(assoc_rsp->aid & 0x3FFF),
+					session_entry);
+			}
+			qdf_mem_free(beacon);
+			return;
+		}
+
+		/*
+		 * If we're re-associating to the same BSS,
+		 * we don't want to invoke delete STA, delete
+		 * BSS, as that would remove the already
+		 * established TSPEC. Just go ahead and re-add
+		 * the BSS, STA with new capability information.
+		 * However, if we're re-associating to a different
+		 * BSS, then follow thru with del STA, del BSS,
+		 * add BSS, add STA.
+		 */
+		if (sir_compare_mac_addr(session_entry->bssId,
+			session_entry->limReAssocbssId))
+			lim_handle_add_bss_in_re_assoc_context(mac_ctx, sta_ds,
+				 session_entry);
+		else {
+			/*
+			 * reset the uapsd mask settings since
+			 * we're re-associating to new AP
+			 */
+			session_entry->gUapsdPerAcDeliveryEnableMask = 0;
+			session_entry->gUapsdPerAcTriggerEnableMask = 0;
+
+			if (lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry)
+				!= QDF_STATUS_SUCCESS) {
+				pe_err("Could not cleanup the rx path");
+				goto assocReject;
+			}
+		}
+		qdf_mem_free(beacon);
+		return;
+	}
+	pe_debug("Successfully Associated with BSS " MAC_ADDRESS_STR,
+		 MAC_ADDR_ARRAY(hdr->sa));
+#ifdef FEATURE_WLAN_ESE
+	if (session_entry->eseContext.tsm.tsmInfo.state)
+		session_entry->eseContext.tsm.tsmMetrics.RoamingCount = 0;
+#endif
+	/* Store assigned AID for TIM processing */
+	session_entry->limAID = assoc_rsp->aid & 0x3FFF;
+
+	/* STA entry was created during pre-assoc state. */
+	sta_ds = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+			&session_entry->dph.dphHashTable);
+	if (sta_ds == NULL) {
+		/* Could not add hash table entry */
+		pe_err("could not get hash entry at DPH");
+		lim_print_mac_addr(mac_ctx, hdr->sa, LOGE);
+		assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+		assoc_cnf.protStatusCode = eSIR_SME_SUCCESS;
+		lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
+			(uint32_t *) &assoc_cnf);
+		qdf_mem_free(assoc_rsp);
+		qdf_mem_free(beacon);
+		return;
+	}
+	/* Delete Pre-auth context for the associated BSS */
+	if (lim_search_pre_auth_list(mac_ctx, hdr->sa))
+		lim_delete_pre_auth_node(mac_ctx, hdr->sa);
+
+	lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp, session_entry);
+	/*
+	 * Extract the AP capabilities from the beacon that
+	 * was received earlier
+	*/
+	ie_len = lim_get_ielen_from_bss_description(
+		&session_entry->pLimJoinReq->bssDescription);
+	lim_extract_ap_capabilities(mac_ctx,
+		(uint8_t *) session_entry->pLimJoinReq->bssDescription.ieFields,
+		ie_len,
+		beacon);
+
+	if (lim_is_session_he_capable(session_entry)) {
+		session_entry->mu_edca_present = assoc_rsp->mu_edca_present;
+		if (session_entry->mu_edca_present) {
+			pe_debug("Save MU EDCA params to session");
+			session_entry->ap_mu_edca_params[EDCA_AC_BE] =
+				assoc_rsp->mu_edca.acbe;
+			session_entry->ap_mu_edca_params[EDCA_AC_BK] =
+				assoc_rsp->mu_edca.acbk;
+			session_entry->ap_mu_edca_params[EDCA_AC_VI] =
+				assoc_rsp->mu_edca.acvi;
+			session_entry->ap_mu_edca_params[EDCA_AC_VO] =
+				assoc_rsp->mu_edca.acvo;
+		}
+
+	}
+
+	if (beacon->VHTCaps.present)
+		sta_ds->parsed_ies.vht_caps = beacon->VHTCaps;
+	if (beacon->HTCaps.present)
+		sta_ds->parsed_ies.ht_caps = beacon->HTCaps;
+	if (beacon->hs20vendor_ie.present)
+		sta_ds->parsed_ies.hs20vendor_ie = beacon->hs20vendor_ie;
+	if (beacon->HTInfo.present)
+		sta_ds->parsed_ies.ht_operation = beacon->HTInfo;
+	if (beacon->VHTOperation.present)
+		sta_ds->parsed_ies.vht_operation = beacon->VHTOperation;
+
+	if (mac_ctx->lim.gLimProtectionControl !=
+	    MLME_FORCE_POLICY_PROTECTION_DISABLE)
+		lim_decide_sta_protection_on_assoc(mac_ctx, beacon,
+						   session_entry);
+
+	if (beacon->erpPresent) {
+		if (beacon->erpIEInfo.barkerPreambleMode)
+			session_entry->beaconParams.fShortPreamble = false;
+		else
+			session_entry->beaconParams.fShortPreamble = true;
+	}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_CONNECTED, session_entry,
+			      QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+#endif
+	lim_update_stads_ext_cap(mac_ctx, session_entry, assoc_rsp, sta_ds);
+	/* Update the BSS Entry, this entry was added during preassoc. */
+	if (QDF_STATUS_SUCCESS == lim_sta_send_add_bss(mac_ctx, assoc_rsp,
+			beacon,
+			&session_entry->pLimJoinReq->bssDescription, true,
+			 session_entry)) {
+		qdf_mem_free(assoc_rsp);
+		qdf_mem_free(beacon);
+		return;
+	} else {
+		pe_err("could not update the bss entry");
+		assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+		assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+	}
+
+assocReject:
+	if ((subtype == LIM_ASSOC)
+		|| ((subtype == LIM_REASSOC)
+		&& (session_entry->limMlmState ==
+		    eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) {
+		pe_err("Assoc Rejected by the peer mlmestate: %d sessionid: %d Reason: %d MACADDR:"
+			MAC_ADDRESS_STR,
+			session_entry->limMlmState,
+			session_entry->peSessionId,
+			assoc_cnf.resultCode, MAC_ADDR_ARRAY(hdr->sa));
+		session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+			session_entry->peSessionId,
+			session_entry->limMlmState));
+		if (session_entry->pLimMlmJoinReq) {
+			qdf_mem_free(session_entry->pLimMlmJoinReq);
+			session_entry->pLimMlmJoinReq = NULL;
+		}
+		if (subtype == LIM_ASSOC) {
+			lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
+				(uint32_t *) &assoc_cnf);
+		} else {
+			assoc_cnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
+			lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF,
+					(uint32_t *)&assoc_cnf);
+		}
+	} else {
+		lim_restore_pre_reassoc_state(mac_ctx,
+			eSIR_SME_REASSOC_REFUSED,
+			assoc_cnf.protStatusCode,
+			session_entry);
+	}
+
+	qdf_mem_free(beacon);
+	qdf_mem_free(assoc_rsp);
+	return;
+}
diff --git a/core/mac/src/pe/lim/lim_process_auth_frame.c b/core/mac/src/pe/lim/lim_process_auth_frame.c
new file mode 100644
index 0000000..8b95d6d
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_auth_frame.c
@@ -0,0 +1,1645 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_process_auth_frame.cc contains the code
+ * for processing received Authentication Frame.
+ * Author:        Chandra Modumudi
+ * Date:          03/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ * 05/12/2010     js             To support Shared key authentication at AP side
+ *
+ */
+
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+#include "cfg_ucfg_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_ft.h"
+#include "cds_utils.h"
+#include "lim_send_messages.h"
+#include "lim_process_fils.h"
+#include "wlan_mlme_api.h"
+
+/**
+ * is_auth_valid
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_auth_frame() upon Authentication
+ * frame reception.
+ *
+ ***LOGIC:
+ * This function is used to test validity of auth frame:
+ * - AUTH1 and AUTH3 must be received in AP mode
+ * - AUTH2 and AUTH4 must be received in STA mode
+ * - AUTH3 and AUTH4 must have challenge text IE, that is,'type' field has been set to
+ *                 SIR_MAC_CHALLENGE_TEXT_EID by parser
+ * -
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  *auth - Pointer to extracted auth frame body
+ *
+ * @return 0 or 1 (Valid)
+ */
+
+static inline unsigned int is_auth_valid(tpAniSirGlobal pMac,
+					 tpSirMacAuthFrameBody auth,
+					 tpPESession sessionEntry)
+{
+	unsigned int valid = 1;
+
+	if (((auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_1) ||
+	    (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_3)) &&
+	    (LIM_IS_STA_ROLE(sessionEntry)))
+		valid = 0;
+
+	if (((auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_2) ||
+	    (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_4)) &&
+	    (LIM_IS_AP_ROLE(sessionEntry)))
+		valid = 0;
+
+	if (((auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_3) ||
+	    (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_4)) &&
+	    (auth->type != SIR_MAC_CHALLENGE_TEXT_EID) &&
+	    (auth->authAlgoNumber != eSIR_SHARED_KEY))
+		valid = 0;
+
+	return valid;
+}
+
+static void lim_process_auth_shared_system_algo(tpAniSirGlobal mac_ctx,
+		tpSirMacMgmtHdr mac_hdr,
+		tSirMacAuthFrameBody *rx_auth_frm_body,
+		tSirMacAuthFrameBody *auth_frame,
+		tpPESession pe_session)
+{
+	uint32_t val;
+	uint8_t cfg_privacy_opt_imp;
+	struct tLimPreAuthNode *auth_node;
+	uint8_t challenge_txt_arr[SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH] = {0};
+
+	pe_debug("=======> eSIR_SHARED_KEY");
+	if (LIM_IS_AP_ROLE(pe_session))
+		val = pe_session->privacy;
+	else
+		val = mac_ctx->mlme_cfg->wep_params.is_privacy_enabled;
+
+	cfg_privacy_opt_imp = (uint8_t) val;
+	if (!cfg_privacy_opt_imp) {
+		pe_err("rx Auth frame for unsupported auth algorithm %d "
+			MAC_ADDRESS_STR,
+			rx_auth_frm_body->authAlgoNumber,
+			MAC_ADDR_ARRAY(mac_hdr->sa));
+
+		/*
+		 * Authenticator does not have WEP
+		 * implemented.
+		 * Reject by sending Authentication frame
+		 * with Auth algorithm not supported status
+		 * code.
+		 */
+		auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber;
+		auth_frame->authTransactionSeqNumber =
+			rx_auth_frm_body->authTransactionSeqNumber + 1;
+		auth_frame->authStatusCode =
+			eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+
+		lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+		return;
+	} else {
+		/* Create entry for this STA in pre-auth list */
+		auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
+					&mac_ctx->lim.gLimPreAuthTimerTable);
+		if (auth_node == NULL) {
+			pe_warn("Max preauth-nodes reached");
+			lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGW);
+			return;
+		}
+
+		qdf_mem_copy((uint8_t *) auth_node->peerMacAddr, mac_hdr->sa,
+				sizeof(tSirMacAddr));
+		auth_node->mlmState = eLIM_MLM_WT_AUTH_FRAME3_STATE;
+		auth_node->authType =
+			(tAniAuthType) rx_auth_frm_body->authAlgoNumber;
+		auth_node->fSeen = 0;
+		auth_node->fTimerStarted = 0;
+		auth_node->seq_num = ((mac_hdr->seqControl.seqNumHi << 4) |
+						(mac_hdr->seqControl.seqNumLo));
+		auth_node->timestamp = qdf_mc_timer_get_system_ticks();
+		lim_add_pre_auth_node(mac_ctx, auth_node);
+
+		pe_debug("Alloc new data: %pK id: %d peer ",
+			auth_node, auth_node->authNodeIdx);
+		lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGD);
+		/* / Create and activate Auth Response timer */
+		if (tx_timer_change_context(&auth_node->timer,
+				auth_node->authNodeIdx) != TX_SUCCESS) {
+			/* Could not start Auth response timer. Log error */
+			pe_warn("Unable to chg context auth response timer for peer");
+			lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGW);
+
+			/*
+			 * Send Auth frame with unspecified failure status code.
+			 */
+
+			auth_frame->authAlgoNumber =
+				rx_auth_frm_body->authAlgoNumber;
+			auth_frame->authTransactionSeqNumber =
+				rx_auth_frm_body->authTransactionSeqNumber + 1;
+			auth_frame->authStatusCode =
+				eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
+			return;
+		}
+
+		/*
+		 * get random bytes and use as challenge text.
+		 */
+		get_random_bytes(challenge_txt_arr,
+				 SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
+		qdf_mem_zero(auth_node->challengeText,
+			     SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
+		if (!qdf_mem_cmp(challenge_txt_arr,
+				 auth_node->challengeText,
+				 SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH)) {
+			pe_err("Challenge text preparation failed");
+			lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGW);
+			auth_frame->authAlgoNumber =
+				rx_auth_frm_body->authAlgoNumber;
+			auth_frame->authTransactionSeqNumber =
+				rx_auth_frm_body->authTransactionSeqNumber + 1;
+			auth_frame->authStatusCode = eSIR_MAC_TRY_AGAIN_LATER;
+			lim_send_auth_mgmt_frame(mac_ctx,
+						 auth_frame,
+						 mac_hdr->sa,
+						 LIM_NO_WEP_IN_FC,
+						 pe_session);
+			lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
+			return;
+		}
+
+		lim_activate_auth_rsp_timer(mac_ctx, auth_node);
+		auth_node->fTimerStarted = 1;
+
+		qdf_mem_copy(auth_node->challengeText,
+			     challenge_txt_arr,
+			     sizeof(challenge_txt_arr));
+		/*
+		 * Sending Authenticaton frame with challenge.
+		 */
+		auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber;
+		auth_frame->authTransactionSeqNumber =
+			rx_auth_frm_body->authTransactionSeqNumber + 1;
+		auth_frame->authStatusCode = eSIR_MAC_SUCCESS_STATUS;
+		auth_frame->type = SIR_MAC_CHALLENGE_TEXT_EID;
+		auth_frame->length = SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH;
+		qdf_mem_copy(auth_frame->challengeText,
+				auth_node->challengeText,
+				SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
+		lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+	}
+}
+
+static void lim_process_auth_open_system_algo(tpAniSirGlobal mac_ctx,
+		tpSirMacMgmtHdr mac_hdr,
+		tSirMacAuthFrameBody *rx_auth_frm_body,
+		tSirMacAuthFrameBody *auth_frame,
+		tpPESession pe_session)
+{
+	struct tLimPreAuthNode *auth_node;
+
+	pe_debug("=======> eSIR_OPEN_SYSTEM");
+	/* Create entry for this STA in pre-auth list */
+	auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
+				&mac_ctx->lim.gLimPreAuthTimerTable);
+	if (auth_node == NULL) {
+		pe_warn("Max pre-auth nodes reached ");
+		lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGW);
+		return;
+	}
+	pe_debug("Alloc new data: %pK peer", auth_node);
+	lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGD);
+	qdf_mem_copy((uint8_t *) auth_node->peerMacAddr,
+			mac_hdr->sa, sizeof(tSirMacAddr));
+	auth_node->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
+	auth_node->authType = (tAniAuthType) rx_auth_frm_body->authAlgoNumber;
+	auth_node->fSeen = 0;
+	auth_node->fTimerStarted = 0;
+	auth_node->seq_num = ((mac_hdr->seqControl.seqNumHi << 4) |
+				(mac_hdr->seqControl.seqNumLo));
+	auth_node->timestamp = qdf_mc_timer_get_system_ticks();
+	lim_add_pre_auth_node(mac_ctx, auth_node);
+	/*
+	 * Send Authenticaton frame with Success
+	 * status code.
+	 */
+	auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber;
+	auth_frame->authTransactionSeqNumber =
+			rx_auth_frm_body->authTransactionSeqNumber + 1;
+	auth_frame->authStatusCode = eSIR_MAC_SUCCESS_STATUS;
+	lim_send_auth_mgmt_frame(mac_ctx, auth_frame, mac_hdr->sa,
+					LIM_NO_WEP_IN_FC,
+					pe_session);
+}
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * lim_process_sae_auth_frame()-Process SAE authentication frame
+ * @mac_ctx: MAC context
+ * @rx_pkt_info: Rx packet
+ * @pe_session: PE session
+ *
+ * Return: None
+ */
+static void lim_process_sae_auth_frame(tpAniSirGlobal mac_ctx,
+		uint8_t *rx_pkt_info, tpPESession pe_session)
+{
+	tpSirMacMgmtHdr mac_hdr;
+	uint32_t frame_len;
+	uint8_t *body_ptr;
+
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+	pe_debug("Received SAE Auth frame type %d subtype %d",
+		mac_hdr->fc.type, mac_hdr->fc.subType);
+
+	if (pe_session->limMlmState != eLIM_MLM_WT_SAE_AUTH_STATE)
+		pe_err("received SAE auth response in unexpected state %x",
+				pe_session->limMlmState);
+
+	lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
+			(uint8_t *) mac_hdr,
+			frame_len + sizeof(tSirMacMgmtHdr), 0,
+			WMA_GET_RX_CH(rx_pkt_info), pe_session,
+			WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info));
+}
+#else
+static inline void  lim_process_sae_auth_frame(tpAniSirGlobal mac_ctx,
+		uint8_t *rx_pkt_info, tpPESession pe_session)
+{}
+#endif
+
+static void lim_process_auth_frame_type1(tpAniSirGlobal mac_ctx,
+		tpSirMacMgmtHdr mac_hdr,
+		tSirMacAuthFrameBody *rx_auth_frm_body,
+		uint8_t *rx_pkt_info, uint16_t curr_seq_num,
+		tSirMacAuthFrameBody *auth_frame, tpPESession pe_session)
+{
+	tpDphHashNode sta_ds_ptr = NULL;
+	struct tLimPreAuthNode *auth_node;
+	uint32_t maxnum_preauth;
+	uint16_t associd = 0;
+
+	/* AuthFrame 1 */
+	sta_ds_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa,
+				&associd, &pe_session->dph.dphHashTable);
+	if (sta_ds_ptr) {
+		tLimMlmDisassocReq *pMlmDisassocReq = NULL;
+		tLimMlmDeauthReq *pMlmDeauthReq = NULL;
+		bool isConnected = true;
+
+		pMlmDisassocReq =
+			mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
+		if (pMlmDisassocReq &&
+			(!qdf_mem_cmp((uint8_t *) mac_hdr->sa, (uint8_t *)
+				&pMlmDisassocReq->peer_macaddr.bytes,
+				QDF_MAC_ADDR_SIZE))) {
+			pe_debug("TODO:Ack for disassoc frame is pending Issue delsta for "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(
+					pMlmDisassocReq->peer_macaddr.bytes));
+			lim_process_disassoc_ack_timeout(mac_ctx);
+			isConnected = false;
+		}
+		pMlmDeauthReq =
+			mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
+		if (pMlmDeauthReq &&
+			(!qdf_mem_cmp((uint8_t *) mac_hdr->sa, (uint8_t *)
+				&pMlmDeauthReq->peer_macaddr.bytes,
+				QDF_MAC_ADDR_SIZE))) {
+			pe_debug("TODO:Ack for deauth frame is pending Issue delsta for "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(
+					pMlmDeauthReq->peer_macaddr.bytes));
+			lim_process_deauth_ack_timeout(mac_ctx);
+			isConnected = false;
+		}
+
+		/*
+		 * pStaDS != NULL and isConnected = 1 means the STA is already
+		 * connected, But SAP received the Auth from that station.
+		 * For non PMF connection send Deauth frame as STA will retry
+		 * to connect back. The reason for above logic is captured in
+		 * CR620403. If we silently drop the auth, the subsequent EAPOL
+		 * exchange will fail & peer STA will keep trying until DUT
+		 * SAP/GO gets a kickout event from FW & cleans up.
+		 *
+		 * For PMF connection the AP should not tear down or otherwise
+		 * modify the state of the existing association until the
+		 * SA-Query procedure determines that the original SA is
+		 * invalid.
+		 */
+		if (isConnected
+#ifdef WLAN_FEATURE_11W
+			&& !sta_ds_ptr->rmfEnabled
+#endif
+		   ) {
+			pe_err("STA is already connected but received auth frame"
+					"Send the Deauth and lim Delete Station Context"
+					"(staId: %d, associd: %d) ",
+				sta_ds_ptr->staIndex, associd);
+			lim_send_deauth_mgmt_frame(mac_ctx,
+				eSIR_MAC_UNSPEC_FAILURE_REASON,
+				(uint8_t *) mac_hdr->sa,
+				pe_session, false);
+			lim_trigger_sta_deletion(mac_ctx, sta_ds_ptr,
+				pe_session);
+			return;
+		}
+	}
+	/* Check if there exists pre-auth context for this STA */
+	auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
+	if (auth_node) {
+		/* Pre-auth context exists for the STA */
+		if (!(mac_hdr->fc.retry == 0 ||
+					auth_node->seq_num != curr_seq_num)) {
+			/*
+			 * This can happen when first authentication frame is
+			 * received but ACK lost at STA side, in this case 2nd
+			 * auth frame is already in transmission queue
+			 */
+			pe_warn("STA is initiating Auth after ACK lost");
+			return;
+		}
+		/*
+		 * STA is initiating brand-new Authentication
+		 * sequence after local Auth Response timeout Or STA
+		 * retrying to transmit First Auth frame due to packet
+		 * drop OTA Delete Pre-auth node and fall through.
+		 */
+		if (auth_node->fTimerStarted)
+			lim_deactivate_and_change_per_sta_id_timer(
+					mac_ctx, eLIM_AUTH_RSP_TIMER,
+					auth_node->authNodeIdx);
+		pe_debug("STA is initiating brand-new Auth");
+		lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
+		/*
+		 *  SAP Mode:Disassociate the station and
+		 *  delete its entry if we have its entry
+		 *  already and received "auth" from the
+		 *  same station.
+		 *  SAP dphHashTable.size = 8
+		 */
+		for (associd = 0; associd < pe_session->dph.dphHashTable.size;
+			associd++) {
+			sta_ds_ptr = dph_get_hash_entry(mac_ctx, associd,
+						&pe_session->dph.dphHashTable);
+			if (NULL == sta_ds_ptr)
+				continue;
+			if (sta_ds_ptr->valid && (!qdf_mem_cmp(
+					(uint8_t *)&sta_ds_ptr->staAddr,
+					(uint8_t *) &(mac_hdr->sa),
+					(uint8_t) sizeof(tSirMacAddr))))
+				break;
+			sta_ds_ptr = NULL;
+		}
+
+		if (NULL != sta_ds_ptr
+#ifdef WLAN_FEATURE_11W
+			&& !sta_ds_ptr->rmfEnabled
+#endif
+		   ) {
+			pe_debug("lim Delete Station Context staId: %d associd: %d",
+				sta_ds_ptr->staIndex, associd);
+			lim_send_deauth_mgmt_frame(mac_ctx,
+				eSIR_MAC_UNSPEC_FAILURE_REASON,
+				(uint8_t *)auth_node->peerMacAddr,
+				pe_session, false);
+			lim_trigger_sta_deletion(mac_ctx, sta_ds_ptr,
+				pe_session);
+			return;
+		}
+	}
+	maxnum_preauth = mac_ctx->mlme_cfg->lfr.max_num_pre_auth;
+	if (mac_ctx->lim.gLimNumPreAuthContexts == maxnum_preauth &&
+			!lim_delete_open_auth_pre_auth_node(mac_ctx)) {
+		pe_err("Max no of preauth context reached");
+		/*
+		 * Maximum number of pre-auth contexts reached.
+		 * Send Authentication frame with unspecified failure
+		 */
+		auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber;
+		auth_frame->authTransactionSeqNumber =
+			rx_auth_frm_body->authTransactionSeqNumber + 1;
+		auth_frame->authStatusCode =
+			eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+		lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+		return;
+	}
+	/* No Pre-auth context exists for the STA. */
+	if (lim_is_auth_algo_supported(mac_ctx,
+			(tAniAuthType) rx_auth_frm_body->authAlgoNumber,
+			pe_session)) {
+
+		if (lim_get_session_by_macaddr(mac_ctx, mac_hdr->sa)) {
+
+			auth_frame->authAlgoNumber =
+				rx_auth_frm_body->authAlgoNumber;
+			auth_frame->authTransactionSeqNumber =
+				rx_auth_frm_body->authTransactionSeqNumber + 1;
+			auth_frame->authStatusCode =
+				eSIR_MAC_WME_INVALID_PARAMS_STATUS;
+
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			return;
+		}
+
+		switch (rx_auth_frm_body->authAlgoNumber) {
+		case eSIR_OPEN_SYSTEM:
+			lim_process_auth_open_system_algo(mac_ctx, mac_hdr,
+				rx_auth_frm_body, auth_frame, pe_session);
+			break;
+
+		case eSIR_SHARED_KEY:
+			lim_process_auth_shared_system_algo(mac_ctx, mac_hdr,
+				rx_auth_frm_body, auth_frame, pe_session);
+			break;
+		default:
+			pe_err("rx Auth frm for unsupported auth algo %d "
+				MAC_ADDRESS_STR,
+				rx_auth_frm_body->authAlgoNumber,
+				MAC_ADDR_ARRAY(mac_hdr->sa));
+
+			/*
+			 * Responding party does not support the
+			 * authentication algorithm requested by
+			 * sending party.
+			 * Reject by sending Authentication frame
+			 * with auth algorithm not supported status code
+			 */
+			auth_frame->authAlgoNumber =
+				rx_auth_frm_body->authAlgoNumber;
+			auth_frame->authTransactionSeqNumber =
+				rx_auth_frm_body->authTransactionSeqNumber + 1;
+			auth_frame->authStatusCode =
+				eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			return;
+		}
+	} else {
+		pe_err("received Authentication frame for unsupported auth algorithm %d "
+			MAC_ADDRESS_STR,
+			rx_auth_frm_body->authAlgoNumber,
+			MAC_ADDR_ARRAY(mac_hdr->sa));
+
+		/*
+		 * Responding party does not support the
+		 * authentication algorithm requested by sending party.
+		 * Reject Authentication with StatusCode=13.
+		 */
+		auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber;
+		auth_frame->authTransactionSeqNumber =
+			rx_auth_frm_body->authTransactionSeqNumber + 1;
+		auth_frame->authStatusCode =
+			eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+
+		lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa,
+				LIM_NO_WEP_IN_FC,
+				pe_session);
+		return;
+	}
+}
+
+static void lim_process_auth_frame_type2(tpAniSirGlobal mac_ctx,
+		tpSirMacMgmtHdr mac_hdr,
+		tSirMacAuthFrameBody *rx_auth_frm_body,
+		tSirMacAuthFrameBody *auth_frame,
+		uint8_t *plainbody,
+		uint8_t *body_ptr, uint16_t frame_len,
+		tpPESession pe_session)
+{
+	uint8_t key_id, cfg_privacy_opt_imp;
+	uint32_t val, key_length = 8;
+	uint8_t defaultkey[SIR_MAC_KEY_LENGTH];
+	struct tLimPreAuthNode *auth_node;
+	uint8_t *encr_auth_frame;
+	struct wlan_mlme_wep_cfg *wep_params = &mac_ctx->mlme_cfg->wep_params;
+	QDF_STATUS qdf_status;
+
+	/* AuthFrame 2 */
+	if (pe_session->limMlmState != eLIM_MLM_WT_AUTH_FRAME2_STATE) {
+		/**
+		 * Check if a Reassociation is in progress and this is a
+		 * Pre-Auth frame
+		 */
+		if (LIM_IS_STA_ROLE(pe_session) &&
+		    (pe_session->limSmeState == eLIM_SME_WT_REASSOC_STATE) &&
+		    (rx_auth_frm_body->authStatusCode ==
+				eSIR_MAC_SUCCESS_STATUS) &&
+		    (pe_session->ftPEContext.pFTPreAuthReq != NULL) &&
+		    (!qdf_mem_cmp(
+			pe_session->ftPEContext.pFTPreAuthReq->preAuthbssId,
+			mac_hdr->sa, sizeof(tSirMacAddr)))) {
+
+			/* Update the FTIEs in the saved auth response */
+			pe_warn("rx PreAuth frm2 in smestate: %d from: %pM",
+				pe_session->limSmeState, mac_hdr->sa);
+			pe_session->ftPEContext.saved_auth_rsp_length = 0;
+
+			if ((body_ptr != NULL) && (frame_len < MAX_FTIE_SIZE)) {
+				qdf_mem_copy(
+					pe_session->ftPEContext.saved_auth_rsp,
+					body_ptr, frame_len);
+				pe_session->ftPEContext.saved_auth_rsp_length =
+					frame_len;
+			}
+		} else {
+			/*
+			 * Received Auth frame2 in an unexpected state.
+			 * Log error and ignore the frame.
+			 */
+			pe_debug("rx Auth frm2 from peer in state: %d addr",
+				pe_session->limMlmState);
+			lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGD);
+		}
+		return;
+	}
+
+	if (qdf_mem_cmp((uint8_t *) mac_hdr->sa,
+			(uint8_t *) &mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
+			sizeof(tSirMacAddr))) {
+		/*
+		 * Received Authentication frame from an entity
+		 * other than one request was initiated.
+		 * Wait until Authentication Failure Timeout.
+		 */
+
+		pe_warn("received Auth frame2 from unexpected peer"
+			MAC_ADDRESS_STR, MAC_ADDR_ARRAY(mac_hdr->sa));
+		return;
+	}
+
+	if (rx_auth_frm_body->authStatusCode ==
+			eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS) {
+		/*
+		 * Interoperability workaround: Linksys WAP4400N is returning
+		 * wrong authType in OpenAuth response in case of
+		 * SharedKey AP configuration. Pretend we don't see that,
+		 * so upper layer can fallback to SharedKey authType,
+		 * and successfully connect to the AP.
+		 */
+		if (rx_auth_frm_body->authAlgoNumber !=
+				mac_ctx->lim.gpLimMlmAuthReq->authType) {
+			rx_auth_frm_body->authAlgoNumber =
+				mac_ctx->lim.gpLimMlmAuthReq->authType;
+		}
+	}
+
+	if (rx_auth_frm_body->authAlgoNumber !=
+			mac_ctx->lim.gpLimMlmAuthReq->authType) {
+		/*
+		 * Auth algo is open in rx auth frame when auth type is SAE and
+		 * PMK is cached as driver sent auth algo as open in tx frame
+		 * as well.
+		 */
+		if ((mac_ctx->lim.gpLimMlmAuthReq->authType ==
+		    eSIR_AUTH_TYPE_SAE) && pe_session->sae_pmk_cached) {
+			pe_debug("rx Auth frame2 auth algo %d in SAE PMK case",
+				rx_auth_frm_body->authAlgoNumber);
+		} else {
+			/*
+			 * Received Authentication frame with an auth
+			 * algorithm other than one requested.
+			 * Wait until Authentication Failure Timeout.
+			 */
+
+			pe_warn("rx Auth frame2 for unexpected auth algo %d"
+				MAC_ADDRESS_STR,
+				rx_auth_frm_body->authAlgoNumber,
+				MAC_ADDR_ARRAY(mac_hdr->sa));
+			return;
+		}
+	}
+
+	if (rx_auth_frm_body->authStatusCode != eSIR_MAC_SUCCESS_STATUS) {
+		/*
+		 * Authentication failure.
+		 * Return Auth confirm with received failure code to SME
+		 */
+		pe_err("rx Auth frame from peer with failure code %d "
+			MAC_ADDRESS_STR,
+			rx_auth_frm_body->authStatusCode,
+			MAC_ADDR_ARRAY(mac_hdr->sa));
+		lim_restore_from_auth_state(mac_ctx, eSIR_SME_AUTH_REFUSED,
+			rx_auth_frm_body->authStatusCode,
+			pe_session);
+		return;
+	}
+
+	if (lim_process_fils_auth_frame2(mac_ctx, pe_session,
+					 rx_auth_frm_body)) {
+		lim_restore_from_auth_state(mac_ctx, eSIR_SME_SUCCESS,
+				rx_auth_frm_body->authStatusCode, pe_session);
+		return;
+	}
+
+	if (rx_auth_frm_body->authAlgoNumber == eSIR_OPEN_SYSTEM) {
+		pe_session->limCurrentAuthType = eSIR_OPEN_SYSTEM;
+		auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
+				&mac_ctx->lim.gLimPreAuthTimerTable);
+		if (auth_node == NULL) {
+			pe_warn("Max pre-auth nodes reached");
+			lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGW);
+			return;
+		}
+
+		pe_debug("Alloc new data: %pK peer", auth_node);
+		lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGD);
+		qdf_mem_copy((uint8_t *) auth_node->peerMacAddr,
+				mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
+				sizeof(tSirMacAddr));
+		auth_node->fTimerStarted = 0;
+		auth_node->authType =
+			mac_ctx->lim.gpLimMlmAuthReq->authType;
+		auth_node->seq_num =
+			((mac_hdr->seqControl.seqNumHi << 4) |
+			 (mac_hdr->seqControl.seqNumLo));
+		auth_node->timestamp = qdf_mc_timer_get_system_ticks();
+		lim_add_pre_auth_node(mac_ctx, auth_node);
+		lim_restore_from_auth_state(mac_ctx, eSIR_SME_SUCCESS,
+				rx_auth_frm_body->authStatusCode, pe_session);
+	} else {
+		/* Shared key authentication */
+		if (LIM_IS_AP_ROLE(pe_session))
+			cfg_privacy_opt_imp = pe_session->privacy;
+		else
+			cfg_privacy_opt_imp = wep_params->is_privacy_enabled;
+
+		if (!cfg_privacy_opt_imp) {
+			/*
+			 * Requesting STA does not have WEP implemented.
+			 * Reject with unsupported authentication algo
+			 * Status code & wait until auth failure timeout
+			 */
+
+			pe_err("rx Auth frm from peer for unsupported auth algo %d "
+						MAC_ADDRESS_STR,
+					rx_auth_frm_body->authAlgoNumber,
+					MAC_ADDR_ARRAY(mac_hdr->sa));
+
+			auth_frame->authAlgoNumber =
+				rx_auth_frm_body->authAlgoNumber;
+			auth_frame->authTransactionSeqNumber =
+				rx_auth_frm_body->authTransactionSeqNumber + 1;
+			auth_frame->authStatusCode =
+				eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+					mac_hdr->sa, LIM_NO_WEP_IN_FC,
+					pe_session);
+			return;
+		}
+		if (rx_auth_frm_body->type != SIR_MAC_CHALLENGE_TEXT_EID) {
+			pe_err("rx auth frm with invalid challenge txtie");
+			return;
+		}
+
+		key_id = mac_ctx->mlme_cfg->wep_params.wep_default_key_id;
+		val = SIR_MAC_KEY_LENGTH;
+		if (LIM_IS_AP_ROLE(pe_session)) {
+			tpSirKeys key_ptr =
+				&pe_session->WEPKeyMaterial[key_id].key[0];
+			qdf_mem_copy(defaultkey, key_ptr->key,
+					key_ptr->keyLength);
+		} else {
+			qdf_status = mlme_get_wep_key(wep_params,
+						      (MLME_WEP_DEFAULT_KEY_1 +
+						      key_id), defaultkey, val);
+			if (QDF_IS_STATUS_ERROR(qdf_status))
+				pe_warn("cant retrieve Defaultkey");
+
+			auth_frame->authAlgoNumber =
+				rx_auth_frm_body->authAlgoNumber;
+			auth_frame->authTransactionSeqNumber =
+				rx_auth_frm_body->authTransactionSeqNumber + 1;
+			auth_frame->authStatusCode =
+				eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+			lim_send_auth_mgmt_frame(mac_ctx,
+					auth_frame, mac_hdr->sa,
+					LIM_NO_WEP_IN_FC,
+					pe_session);
+			lim_restore_from_auth_state(mac_ctx,
+					eSIR_SME_INVALID_WEP_DEFAULT_KEY,
+					eSIR_MAC_UNSPEC_FAILURE_REASON,
+					pe_session);
+			return;
+		}
+		key_length = val;
+		((tpSirMacAuthFrameBody)plainbody)->authAlgoNumber =
+			sir_swap_u16if_needed(rx_auth_frm_body->authAlgoNumber);
+		((tpSirMacAuthFrameBody)plainbody)->authTransactionSeqNumber =
+			sir_swap_u16if_needed((uint16_t)(
+				rx_auth_frm_body->authTransactionSeqNumber
+				+ 1));
+		((tpSirMacAuthFrameBody)plainbody)->authStatusCode =
+			eSIR_MAC_SUCCESS_STATUS;
+		((tpSirMacAuthFrameBody)plainbody)->type =
+			SIR_MAC_CHALLENGE_TEXT_EID;
+		((tpSirMacAuthFrameBody)plainbody)->length =
+			rx_auth_frm_body->length;
+		qdf_mem_copy((uint8_t *) (
+			(tpSirMacAuthFrameBody)plainbody)->challengeText,
+			rx_auth_frm_body->challengeText,
+			rx_auth_frm_body->length);
+		encr_auth_frame = qdf_mem_malloc(rx_auth_frm_body->length +
+						 LIM_ENCR_AUTH_INFO_LEN);
+		if (!encr_auth_frame)
+			return;
+		lim_encrypt_auth_frame(mac_ctx, key_id,
+				defaultkey, plainbody,
+				encr_auth_frame, key_length);
+		pe_session->limMlmState = eLIM_MLM_WT_AUTH_FRAME4_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+					pe_session->peSessionId,
+					pe_session->limMlmState));
+		lim_send_auth_mgmt_frame(mac_ctx,
+				(tpSirMacAuthFrameBody)encr_auth_frame,
+				mac_hdr->sa, rx_auth_frm_body->length,
+				pe_session);
+		qdf_mem_free(encr_auth_frame);
+		return;
+	}
+}
+
+static void lim_process_auth_frame_type3(tpAniSirGlobal mac_ctx,
+		tpSirMacMgmtHdr mac_hdr,
+		tSirMacAuthFrameBody *rx_auth_frm_body,
+		tSirMacAuthFrameBody *auth_frame,
+		tpPESession pe_session)
+{
+	struct tLimPreAuthNode *auth_node;
+
+	/* AuthFrame 3 */
+	if (rx_auth_frm_body->authAlgoNumber != eSIR_SHARED_KEY) {
+		pe_err("rx Auth frame3 from peer with auth algo number %d "
+			MAC_ADDRESS_STR,
+			rx_auth_frm_body->authAlgoNumber,
+			MAC_ADDR_ARRAY(mac_hdr->sa));
+		/*
+		 * Received Authentication frame3 with algorithm other than
+		 * Shared Key authentication type. Reject with Auth frame4
+		 * with 'out of sequence' status code.
+		 */
+		auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
+		auth_frame->authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_4;
+		auth_frame->authStatusCode =
+			eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+		lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+			mac_hdr->sa, LIM_NO_WEP_IN_FC,
+			pe_session);
+		return;
+	}
+
+	if (LIM_IS_AP_ROLE(pe_session) ||
+			LIM_IS_IBSS_ROLE(pe_session)) {
+		/*
+		 * Check if wep bit was set in FC. If not set,
+		 * reject with Authentication frame4 with
+		 * 'challenge failure' status code.
+		 */
+		if (!mac_hdr->fc.wep) {
+			pe_err("received Auth frame3 from peer with no WEP bit set "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(mac_hdr->sa));
+			/* WEP bit is not set in FC of Auth Frame3 */
+			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
+			auth_frame->authTransactionSeqNumber =
+				SIR_MAC_AUTH_FRAME_4;
+			auth_frame->authStatusCode =
+				eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+					mac_hdr->sa,
+					LIM_NO_WEP_IN_FC,
+					pe_session);
+			return;
+		}
+
+		auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
+		if (auth_node == NULL) {
+			pe_warn("received AuthFrame3 from peer that has no preauth context "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(mac_hdr->sa));
+			/*
+			 * No 'pre-auth' context exists for this STA that sent
+			 * an Authentication frame3. Send Auth frame4 with
+			 * 'out of sequence' status code.
+			 */
+			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
+			auth_frame->authTransactionSeqNumber =
+				SIR_MAC_AUTH_FRAME_4;
+			auth_frame->authStatusCode =
+				eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			return;
+		}
+
+		if (auth_node->mlmState == eLIM_MLM_AUTH_RSP_TIMEOUT_STATE) {
+			pe_warn("auth response timer timedout for peer "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(mac_hdr->sa));
+			/*
+			 * Received Auth Frame3 after Auth Response timeout.
+			 * Reject by sending Auth Frame4 with
+			 * Auth respone timeout Status Code.
+			 */
+			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
+			auth_frame->authTransactionSeqNumber =
+				SIR_MAC_AUTH_FRAME_4;
+			auth_frame->authStatusCode =
+				eSIR_MAC_AUTH_RSP_TIMEOUT_STATUS;
+
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			/* Delete pre-auth context of STA */
+			lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
+			return;
+		}
+		if (rx_auth_frm_body->authStatusCode !=
+				eSIR_MAC_SUCCESS_STATUS) {
+			/*
+			 * Received Authenetication Frame 3 with status code
+			 * other than success. Wait until Auth response timeout
+			 * to delete STA context.
+			 */
+			pe_err("rx Auth frm3 from peer with status code %d "
+				MAC_ADDRESS_STR,
+				rx_auth_frm_body->authStatusCode,
+				MAC_ADDR_ARRAY(mac_hdr->sa));
+				return;
+		}
+		/*
+		 * Check if received challenge text is same as one sent in
+		 * Authentication frame3
+		 */
+		if (!qdf_mem_cmp(rx_auth_frm_body->challengeText,
+					auth_node->challengeText,
+					SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH)) {
+			/*
+			 * Challenge match. STA is autheticated
+			 * Delete Authentication response timer if running
+			 */
+			lim_deactivate_and_change_per_sta_id_timer(mac_ctx,
+				eLIM_AUTH_RSP_TIMER, auth_node->authNodeIdx);
+
+			auth_node->fTimerStarted = 0;
+			auth_node->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
+
+			/*
+			 * Send Auth Frame4 with 'success' Status Code.
+			 */
+			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
+			auth_frame->authTransactionSeqNumber =
+				SIR_MAC_AUTH_FRAME_4;
+			auth_frame->authStatusCode =
+				eSIR_MAC_SUCCESS_STATUS;
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			return;
+		} else {
+			pe_warn("Challenge failure for peer "MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(mac_hdr->sa));
+			/*
+			 * Challenge Failure.
+			 * Send Authentication frame4 with 'challenge failure'
+			 * status code and wait until Auth response timeout to
+			 * delete STA context.
+			 */
+			auth_frame->authAlgoNumber =
+				rx_auth_frm_body->authAlgoNumber;
+			auth_frame->authTransactionSeqNumber =
+				SIR_MAC_AUTH_FRAME_4;
+			auth_frame->authStatusCode =
+				eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			return;
+		}
+	}
+}
+
+static void lim_process_auth_frame_type4(tpAniSirGlobal mac_ctx,
+		tpSirMacMgmtHdr mac_hdr,
+		tSirMacAuthFrameBody *rx_auth_frm_body,
+		tpPESession pe_session)
+{
+	struct tLimPreAuthNode *auth_node;
+
+	if (pe_session->limMlmState != eLIM_MLM_WT_AUTH_FRAME4_STATE) {
+		/*
+		 * Received Authentication frame4 in an unexpected state.
+		 * Log error and ignore the frame.
+		 */
+		pe_warn("received unexpected Auth frame4 from peer in state %d, addr "
+			MAC_ADDRESS_STR,
+			pe_session->limMlmState,
+			MAC_ADDR_ARRAY(mac_hdr->sa));
+		return;
+	}
+
+	if (rx_auth_frm_body->authAlgoNumber != eSIR_SHARED_KEY) {
+		/*
+		 * Received Authentication frame4 with algorithm other than
+		 * Shared Key authentication type.
+		 * Wait until Auth failure timeout to report authentication
+		 * failure to SME.
+		 */
+		pe_err("received Auth frame4 from peer with invalid auth algo %d"
+			MAC_ADDRESS_STR,
+			rx_auth_frm_body->authAlgoNumber,
+			MAC_ADDR_ARRAY(mac_hdr->sa));
+		return;
+	}
+
+	if (qdf_mem_cmp((uint8_t *) mac_hdr->sa,
+			(uint8_t *) &mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
+			sizeof(tSirMacAddr))) {
+		/*
+		 * Received Authentication frame from an entity
+		 * other than one to which request was initiated.
+		 * Wait until Authentication Failure Timeout.
+		 */
+
+		pe_warn("received Auth frame4 from unexpected peer "MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(mac_hdr->sa));
+		return;
+	}
+
+	if (rx_auth_frm_body->authAlgoNumber !=
+			mac_ctx->lim.gpLimMlmAuthReq->authType) {
+		/*
+		 * Received Authentication frame with an auth algorithm
+		 * other than one requested.
+		 * Wait until Authentication Failure Timeout.
+		 */
+
+		pe_err("received Authentication frame from peer with invalid auth seq number %d "
+			MAC_ADDRESS_STR,
+			rx_auth_frm_body->authTransactionSeqNumber,
+			MAC_ADDR_ARRAY(mac_hdr->sa));
+		return;
+	}
+
+	if (rx_auth_frm_body->authStatusCode == eSIR_MAC_SUCCESS_STATUS) {
+		/*
+		 * Authentication Success, Inform SME of same.
+		 */
+		pe_session->limCurrentAuthType = eSIR_SHARED_KEY;
+		auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
+					&mac_ctx->lim.gLimPreAuthTimerTable);
+		if (auth_node == NULL) {
+			pe_warn("Max pre-auth nodes reached");
+			lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGW);
+			return;
+		}
+		pe_debug("Alloc new data: %pK peer", auth_node);
+		lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGD);
+		qdf_mem_copy((uint8_t *) auth_node->peerMacAddr,
+				mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
+				sizeof(tSirMacAddr));
+		auth_node->fTimerStarted = 0;
+		auth_node->authType = mac_ctx->lim.gpLimMlmAuthReq->authType;
+		auth_node->seq_num = ((mac_hdr->seqControl.seqNumHi << 4) |
+					(mac_hdr->seqControl.seqNumLo));
+		auth_node->timestamp = qdf_mc_timer_get_system_ticks();
+		lim_add_pre_auth_node(mac_ctx, auth_node);
+		lim_restore_from_auth_state(mac_ctx, eSIR_SME_SUCCESS,
+				rx_auth_frm_body->authStatusCode, pe_session);
+	} else {
+		/*
+		 * Authentication failure.
+		 * Return Auth confirm with received failure code to SME
+		 */
+		pe_err("Authentication failure from peer "MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(mac_hdr->sa));
+		lim_restore_from_auth_state(mac_ctx, eSIR_SME_AUTH_REFUSED,
+				rx_auth_frm_body->authStatusCode,
+				pe_session);
+	}
+}
+
+/**
+ * lim_process_auth_frame() - to process auth frame
+ * @mac_ctx - Pointer to Global MAC structure
+ * @rx_pkt_info - A pointer to Rx packet info structure
+ * @session - A pointer to session
+ *
+ * This function is called by limProcessMessageQueue() upon Authentication
+ * frame reception.
+ *
+ * LOGIC:
+ * This function processes received Authentication frame and responds
+ * with either next Authentication frame in sequence to peer MAC entity
+ * or LIM_MLM_AUTH_IND on AP or LIM_MLM_AUTH_CNF on STA.
+ *
+ * NOTE:
+ * 1. Authentication failures are reported to SME with same status code
+ *    received from the peer MAC entity.
+ * 2. Authentication frame2/4 received with alogirthm number other than
+ *    one requested in frame1/3 are logged with an error and auth confirm
+ *    will be sent to SME only after auth failure timeout.
+ * 3. Inconsistency in the spec:
+ *    On receiving Auth frame2, specs says that if WEP key mapping key
+ *    or default key is NULL, Auth frame3 with a status code 15 (challenge
+ *    failure to be returned to peer entity. However, section 7.2.3.10,
+ *    table 14 says that status code field is 'reserved' for frame3 !
+ *    In the current implementation, Auth frame3 is returned with status
+ *    code 15 overriding section 7.2.3.10.
+ * 4. If number pre-authentications reach configrable max limit,
+ *    Authentication frame with 'unspecified failure' status code is
+ *    returned to requesting entity.
+ *
+ * Return: None
+ */
+void
+lim_process_auth_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+		       tpPESession pe_session)
+{
+	uint8_t *body_ptr, key_id, cfg_privacy_opt_imp;
+	uint8_t defaultkey[SIR_MAC_KEY_LENGTH];
+	uint8_t *plainbody = NULL;
+	uint8_t decrypt_result;
+	uint16_t frame_len, curr_seq_num = 0, auth_alg;
+	uint32_t val, key_length = 8;
+	tSirMacAuthFrameBody *rx_auth_frm_body, *rx_auth_frame, *auth_frame;
+	tpSirMacMgmtHdr mac_hdr;
+	struct tLimPreAuthNode *auth_node;
+	struct wlan_mlme_wep_cfg *wep_params = &mac_ctx->mlme_cfg->wep_params;
+	QDF_STATUS qdf_status;
+
+	/* Get pointer to Authentication frame header and body */
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+	if (!frame_len) {
+		/* Log error */
+		pe_err("received Auth frame with no body from: %pM",
+			mac_hdr->sa);
+		return;
+	}
+
+	if (lim_is_group_addr(mac_hdr->sa)) {
+		/*
+		 * Received Auth frame from a BC/MC address
+		 * Log error and ignore it
+		 */
+		pe_err("received Auth frame from a BC/MC addr: %pM",
+			mac_hdr->sa);
+		return;
+	}
+	curr_seq_num = (mac_hdr->seqControl.seqNumHi << 4) |
+		(mac_hdr->seqControl.seqNumLo);
+
+	pe_debug("Sessionid: %d System role: %d limMlmState: %d: Auth response Received BSSID: "MAC_ADDRESS_STR" RSSI: %d",
+		 pe_session->peSessionId, GET_LIM_SYSTEM_ROLE(pe_session),
+		 pe_session->limMlmState, MAC_ADDR_ARRAY(mac_hdr->bssId),
+		 (uint) abs((int8_t) WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info)));
+
+	if (pe_session->prev_auth_seq_num == curr_seq_num &&
+	    mac_hdr->fc.retry) {
+		pe_debug("auth frame, seq num: %d is already processed, drop it",
+			 curr_seq_num);
+		return;
+	}
+
+	/* save seq number in pe_session */
+	pe_session->prev_auth_seq_num = curr_seq_num;
+
+	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+
+	if (frame_len < 2) {
+		pe_err("invalid frame len: %d", frame_len);
+		return;
+	}
+	auth_alg = *(uint16_t *) body_ptr;
+	pe_debug("auth_alg %d ", auth_alg);
+
+	/* Restore default failure timeout */
+	if (QDF_P2P_CLIENT_MODE == pe_session->pePersona &&
+	    pe_session->defaultAuthFailureTimeout) {
+		pe_debug("Restore default failure timeout");
+		if (cfg_in_range(CFG_AUTH_FAILURE_TIMEOUT,
+				 pe_session->defaultAuthFailureTimeout)) {
+			mac_ctx->mlme_cfg->timeouts.auth_failure_timeout =
+				pe_session->defaultAuthFailureTimeout;
+		} else {
+			mac_ctx->mlme_cfg->timeouts.auth_failure_timeout =
+				cfg_default(CFG_AUTH_FAILURE_TIMEOUT);
+			pe_session->defaultAuthFailureTimeout =
+				cfg_default(CFG_AUTH_FAILURE_TIMEOUT);
+		}
+	}
+
+	rx_auth_frame = qdf_mem_malloc(sizeof(tSirMacAuthFrameBody));
+	if (!rx_auth_frame)
+		return;
+
+	auth_frame = qdf_mem_malloc(sizeof(tSirMacAuthFrameBody));
+	if (!auth_frame)
+		goto free;
+
+	plainbody = qdf_mem_malloc(LIM_ENCR_AUTH_BODY_LEN);
+	if (!plainbody)
+		goto free;
+
+	qdf_mem_zero(plainbody, LIM_ENCR_AUTH_BODY_LEN);
+
+	/*
+	 * Determine if WEP bit is set in the FC or received MAC header
+	 * Note: WEP bit is set in FC of MAC header.
+	 */
+	if (mac_hdr->fc.wep) {
+		/*
+		 * If TKIP counter measures enabled then issue Deauth
+		 * frame to station
+		 */
+		if (pe_session->bTkipCntrMeasActive &&
+				LIM_IS_AP_ROLE(pe_session)) {
+			pe_err("Tkip counter enabled, send deauth to: %pM",
+				mac_hdr->sa);
+			lim_send_deauth_mgmt_frame(mac_ctx,
+					eSIR_MAC_MIC_FAILURE_REASON,
+					mac_hdr->sa, pe_session, false);
+			goto free;
+		}
+		if (frame_len < 4) {
+			pe_err("invalid frame len: %d", frame_len);
+			goto free;
+		}
+		/* Extract key ID from IV (most 2 bits of 4th byte of IV) */
+		key_id = (*(body_ptr + 3)) >> 6;
+
+		/*
+		 * On STA in infrastructure BSS, Authentication frames received
+		 * with WEP bit set in the FC must be rejected with challenge
+		 * failure status code (weird thing in the spec - this should've
+		 * been rejected with unspecified failure/unexpected assertion
+		 * of wep bit (this status code does not exist though) or
+		 * Out-of-sequence-Authentication-Frame status code.
+		 */
+		if (LIM_IS_STA_ROLE(pe_session)) {
+			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
+			auth_frame->authTransactionSeqNumber =
+				SIR_MAC_AUTH_FRAME_4;
+			auth_frame->authStatusCode =
+				eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+			/* Log error */
+			pe_err("rx Auth frm with wep bit set role: %d %pM",
+				GET_LIM_SYSTEM_ROLE(pe_session), mac_hdr->sa);
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			goto free;
+		}
+
+		if ((frame_len < LIM_ENCR_AUTH_BODY_LEN_SAP) ||
+		    (frame_len > LIM_ENCR_AUTH_BODY_LEN)) {
+			/* Log error */
+			pe_err("Not enough size: %d to decry rx Auth frm",
+				frame_len);
+			lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGE);
+			goto free;
+		}
+
+		/*
+		 * Accept Authentication frame only if Privacy is
+		 * implemented
+		 */
+		if (LIM_IS_AP_ROLE(pe_session))
+			cfg_privacy_opt_imp = pe_session->privacy;
+		else
+			cfg_privacy_opt_imp = wep_params->is_privacy_enabled;
+
+		if (!cfg_privacy_opt_imp) {
+			pe_err("received Authentication frame3 from peer that while privacy option is turned OFF "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(mac_hdr->sa));
+			/*
+			 * Privacy option is not implemented.
+			 * So reject Authentication frame received with
+			 * WEP bit set by sending Authentication frame
+			 * with 'challenge failure' status code. This is
+			 * another strange thing in the spec. Status code
+			 * should have been 'unsupported algorithm' status code.
+			 */
+			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
+			auth_frame->authTransactionSeqNumber =
+				SIR_MAC_AUTH_FRAME_4;
+			auth_frame->authStatusCode =
+				eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			goto free;
+		}
+
+		/*
+		 * Privacy option is implemented. Check if the received frame is
+		 * Authentication frame3 and there is a context for requesting
+		 * STA. If not, reject with unspecified failure status code
+		 */
+		auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
+		if (auth_node == NULL) {
+			pe_err("rx Auth frame with no preauth ctx with WEP bit set "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(mac_hdr->sa));
+			/*
+			 * No 'pre-auth' context exists for this STA
+			 * that sent an Authentication frame with FC
+			 * bit set. Send Auth frame4 with
+			 * 'out of sequence' status code.
+			 */
+			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
+			auth_frame->authTransactionSeqNumber =
+				SIR_MAC_AUTH_FRAME_4;
+			auth_frame->authStatusCode =
+				eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			goto free;
+		}
+		/* Change the auth-response timeout */
+		lim_deactivate_and_change_per_sta_id_timer(mac_ctx,
+				eLIM_AUTH_RSP_TIMER, auth_node->authNodeIdx);
+
+		/* 'Pre-auth' status exists for STA */
+		if ((auth_node->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE) &&
+			(auth_node->mlmState !=
+				eLIM_MLM_AUTH_RSP_TIMEOUT_STATE)) {
+			pe_err("received Authentication frame from peer that is in state %d "
+				MAC_ADDRESS_STR,
+				auth_node->mlmState,
+				MAC_ADDR_ARRAY(mac_hdr->sa));
+			/*
+			 * Should not have received Authentication frame
+			 * with WEP bit set in FC in other states.
+			 * Reject by sending Authenticaton frame with
+			 * out of sequence Auth frame status code.
+			 */
+			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
+			auth_frame->authTransactionSeqNumber =
+				SIR_MAC_AUTH_FRAME_4;
+			auth_frame->authStatusCode =
+				eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			goto free;
+		}
+
+		val = SIR_MAC_KEY_LENGTH;
+
+		if (LIM_IS_AP_ROLE(pe_session)) {
+			tpSirKeys key_ptr;
+
+			key_ptr = &pe_session->WEPKeyMaterial[key_id].key[0];
+			qdf_mem_copy(defaultkey, key_ptr->key,
+					key_ptr->keyLength);
+			val = key_ptr->keyLength;
+		} else {
+			qdf_status = mlme_get_wep_key(wep_params,
+						      (MLME_WEP_DEFAULT_KEY_1 +
+						      key_id), defaultkey, val);
+			if (QDF_IS_STATUS_ERROR(qdf_status))
+				pe_warn("could not retrieve Default key");
+
+			/*
+			 * Send Authentication frame
+			 * with challenge failure status code
+			 */
+			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
+			auth_frame->authTransactionSeqNumber =
+				SIR_MAC_AUTH_FRAME_4;
+			auth_frame->authStatusCode =
+				eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			goto free;
+		}
+
+		key_length = val;
+		decrypt_result = lim_decrypt_auth_frame(mac_ctx, defaultkey,
+					body_ptr, plainbody, key_length,
+					(uint16_t) (frame_len -
+							SIR_MAC_WEP_IV_LENGTH));
+		if (decrypt_result == LIM_DECRYPT_ICV_FAIL) {
+			pe_err("received Authentication frame from peer that failed decryption: "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(mac_hdr->sa));
+			/* ICV failure */
+			lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
+			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
+			auth_frame->authTransactionSeqNumber =
+				SIR_MAC_AUTH_FRAME_4;
+			auth_frame->authStatusCode =
+				eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
+				mac_hdr->sa, LIM_NO_WEP_IN_FC,
+				pe_session);
+			goto free;
+		}
+		if ((sir_convert_auth_frame2_struct(mac_ctx, plainbody,
+				frame_len - 8, rx_auth_frame) != QDF_STATUS_SUCCESS)
+				|| (!is_auth_valid(mac_ctx, rx_auth_frame,
+							pe_session))) {
+			pe_err("failed to convert Auth Frame to structure or Auth is not valid");
+			goto free;
+		}
+	} else if ((auth_alg == eSIR_AUTH_TYPE_SAE) &&
+		   (LIM_IS_STA_ROLE(pe_session))) {
+		lim_process_sae_auth_frame(mac_ctx, rx_pkt_info, pe_session);
+		goto free;
+	} else if ((sir_convert_auth_frame2_struct(mac_ctx, body_ptr,
+				frame_len, rx_auth_frame) != QDF_STATUS_SUCCESS)
+				|| (!is_auth_valid(mac_ctx, rx_auth_frame,
+						pe_session))) {
+		pe_err("failed to convert Auth Frame to structure or Auth is not valid");
+		goto free;
+	}
+
+	rx_auth_frm_body = rx_auth_frame;
+
+	pe_debug("Received Auth frame with type: %d seqnum: %d status: %d %d",
+		(uint32_t) rx_auth_frm_body->authAlgoNumber,
+		(uint32_t) rx_auth_frm_body->authTransactionSeqNumber,
+		(uint32_t) rx_auth_frm_body->authStatusCode,
+		(uint32_t) mac_ctx->lim.gLimNumPreAuthContexts);
+
+	if (!lim_is_valid_fils_auth_frame(mac_ctx, pe_session,
+			rx_auth_frm_body)) {
+		pe_err("Received invalid FILS auth packet");
+		goto free;
+	}
+
+	/*
+	 * IOT Workaround: with invalid WEP key, some APs reply
+	 * AuthFrame 4 with invalid seqNumber. This AuthFrame
+	 * will be dropped by driver, thus driver sends the
+	 * generic status code instead of protocol status code.
+	 * As a workaround, override AuthFrame 4's seqNumber.
+	 */
+	if ((pe_session->limMlmState ==
+		eLIM_MLM_WT_AUTH_FRAME4_STATE) &&
+		(rx_auth_frm_body->authTransactionSeqNumber !=
+		SIR_MAC_AUTH_FRAME_1) &&
+		(rx_auth_frm_body->authTransactionSeqNumber !=
+		SIR_MAC_AUTH_FRAME_2) &&
+		(rx_auth_frm_body->authTransactionSeqNumber !=
+		SIR_MAC_AUTH_FRAME_3)) {
+		pe_warn("Override AuthFrame 4's seqNumber to 4");
+		rx_auth_frm_body->authTransactionSeqNumber =
+			SIR_MAC_AUTH_FRAME_4;
+	}
+
+
+	switch (rx_auth_frm_body->authTransactionSeqNumber) {
+	case SIR_MAC_AUTH_FRAME_1:
+		lim_process_auth_frame_type1(mac_ctx,
+			mac_hdr, rx_auth_frm_body, rx_pkt_info,
+			curr_seq_num, auth_frame, pe_session);
+		break;
+	case SIR_MAC_AUTH_FRAME_2:
+		lim_process_auth_frame_type2(mac_ctx,
+			mac_hdr, rx_auth_frm_body, auth_frame, plainbody,
+			body_ptr, frame_len, pe_session);
+		break;
+	case SIR_MAC_AUTH_FRAME_3:
+		lim_process_auth_frame_type3(mac_ctx,
+			mac_hdr, rx_auth_frm_body, auth_frame, pe_session);
+		break;
+	case SIR_MAC_AUTH_FRAME_4:
+		lim_process_auth_frame_type4(mac_ctx,
+			mac_hdr, rx_auth_frm_body, pe_session);
+		break;
+	default:
+		/* Invalid Authentication Frame received. Ignore it. */
+		pe_warn("rx auth frm with invalid authseq no: %d from: %pM",
+			rx_auth_frm_body->authTransactionSeqNumber,
+			mac_hdr->sa);
+		break;
+	}
+free:
+	if (auth_frame)
+		qdf_mem_free(auth_frame);
+	if (rx_auth_frame)
+		qdf_mem_free(rx_auth_frame);
+	if (plainbody)
+		qdf_mem_free(plainbody);
+}
+
+/*----------------------------------------------------------------------
+ *
+ * Pass the received Auth frame. This is possibly the pre-auth from the
+ * neighbor AP, in the same mobility domain.
+ * This will be used in case of 11r FT.
+ *
+ * !!!! This is going to be renoved for the next checkin. We will be creating
+ * the session before sending out the Auth. Thus when auth response
+ * is received we will have a session in progress. !!!!!
+ ***----------------------------------------------------------------------
+ */
+QDF_STATUS lim_process_auth_frame_no_session(tpAniSirGlobal pMac, uint8_t *pBd,
+						void *body)
+{
+	tpSirMacMgmtHdr pHdr;
+	tpPESession psessionEntry = NULL;
+	uint8_t *pBody;
+	uint16_t frameLen;
+	tSirMacAuthFrameBody rxAuthFrame;
+	tSirMacAuthFrameBody *pRxAuthFrameBody = NULL;
+	QDF_STATUS ret_status = QDF_STATUS_E_FAILURE;
+	int i;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pBd);
+	pBody = WMA_GET_RX_MPDU_DATA(pBd);
+	frameLen = WMA_GET_RX_PAYLOAD_LEN(pBd);
+
+	pe_debug("Auth Frame Received: BSSID " MAC_ADDRESS_STR " (RSSI %d)",
+		 MAC_ADDR_ARRAY(pHdr->bssId),
+		 (uint) abs((int8_t) WMA_GET_RX_RSSI_NORMALIZED(pBd)));
+
+	/* Auth frame has come on a new BSS, however, we need to find the session
+	 * from where the auth-req was sent to the new AP
+	 */
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		/* Find first free room in session table */
+		if (pMac->lim.gpSession[i].valid == true &&
+		    pMac->lim.gpSession[i].ftPEContext.ftPreAuthSession ==
+		    true) {
+			/* Found the session */
+			psessionEntry = &pMac->lim.gpSession[i];
+			pMac->lim.gpSession[i].ftPEContext.ftPreAuthSession =
+				false;
+		}
+	}
+
+	if (psessionEntry == NULL) {
+		pe_debug("cannot find session id in FT pre-auth phase");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (psessionEntry->ftPEContext.pFTPreAuthReq == NULL) {
+		pe_err("Error: No FT");
+		/* No FT in progress. */
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (frameLen == 0) {
+		pe_err("Error: Frame len = 0");
+		return QDF_STATUS_E_FAILURE;
+	}
+	lim_print_mac_addr(pMac, pHdr->bssId, LOGD);
+	lim_print_mac_addr(pMac,
+			   psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId,
+			   LOGD);
+	pe_debug("seqControl: 0x%X",
+		((pHdr->seqControl.seqNumHi << 8) |
+		 (pHdr->seqControl.seqNumLo << 4) |
+		 (pHdr->seqControl.fragNum)));
+
+	/* Check that its the same bssId we have for preAuth */
+	if (qdf_mem_cmp
+		    (psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId,
+		    pHdr->bssId, sizeof(tSirMacAddr))) {
+		pe_err("Error: Same bssid as preauth BSSID");
+		/* In this case SME if indeed has triggered a */
+		/* pre auth it will time out. */
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (true ==
+	    psessionEntry->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) {
+		/*
+		 * This is likely a duplicate for the same pre-auth request.
+		 * PE/LIM already posted a response to SME. Hence, drop it.
+		 * TBD:
+		 * 1) How did we even receive multiple auth responses?
+		 * 2) Do we need to delete pre-auth session? Suppose we
+		 * previously received an auth resp with failure which
+		 * would not have created the session and forwarded to SME.
+		 * And, we subsequently received an auth resp with success
+		 * which would have created the session. This will now be
+		 * dropped without being forwarded to SME! However, it is
+		 * very unlikely to receive auth responses from the same
+		 * AP with different reason codes.
+		 * NOTE: return QDF_STATUS_SUCCESS so that the packet is dropped
+		 * as this was indeed a response from the BSSID we tried to
+		 * pre-auth.
+		 */
+		pe_debug("Auth rsp already posted to SME"
+			       " (session %pK, FT session %pK)", psessionEntry,
+			       psessionEntry);
+		return QDF_STATUS_SUCCESS;
+	} else {
+		pe_warn("Auth rsp not yet posted to SME"
+			       " (session %pK, FT session %pK)", psessionEntry,
+			       psessionEntry);
+		psessionEntry->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed =
+			true;
+	}
+
+	/* Stopping timer now, that we have our unicast from the AP */
+	/* of our choice. */
+	lim_deactivate_and_change_timer(pMac, eLIM_FT_PREAUTH_RSP_TIMER);
+
+	/* Save off the auth resp. */
+	if ((sir_convert_auth_frame2_struct(pMac, pBody, frameLen, &rxAuthFrame) !=
+	     QDF_STATUS_SUCCESS)) {
+		pe_err("failed to convert Auth frame to struct");
+		lim_handle_ft_pre_auth_rsp(pMac, QDF_STATUS_E_FAILURE, NULL, 0,
+					   psessionEntry);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pRxAuthFrameBody = &rxAuthFrame;
+
+	pe_debug("Received Auth frame with type: %d seqnum: %d status: %d %d",
+		       (uint32_t) pRxAuthFrameBody->authAlgoNumber,
+		       (uint32_t) pRxAuthFrameBody->authTransactionSeqNumber,
+		       (uint32_t) pRxAuthFrameBody->authStatusCode,
+		       (uint32_t) pMac->lim.gLimNumPreAuthContexts);
+	switch (pRxAuthFrameBody->authTransactionSeqNumber) {
+	case SIR_MAC_AUTH_FRAME_2:
+		if (pRxAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS) {
+			pe_err("Auth status code received is %d",
+				(uint32_t) pRxAuthFrameBody->authStatusCode);
+			if (eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS ==
+			    pRxAuthFrameBody->authStatusCode)
+				ret_status = QDF_STATUS_E_NOSPC;
+		} else {
+			ret_status = QDF_STATUS_SUCCESS;
+		}
+		break;
+
+	default:
+		pe_warn("Seq. no incorrect expected 2 received %d",
+			(uint32_t) pRxAuthFrameBody->authTransactionSeqNumber);
+		break;
+	}
+
+	/* Send the Auth response to SME */
+	lim_handle_ft_pre_auth_rsp(pMac, ret_status, pBody, frameLen, psessionEntry);
+
+	return ret_status;
+}
diff --git a/core/mac/src/pe/lim/lim_process_beacon_frame.c b/core/mac/src/pe/lim/lim_process_beacon_frame.c
new file mode 100644
index 0000000..db3f957
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_beacon_frame.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_process_beacon_frame.cc contains the code
+ * for processing Received Beacon Frame.
+ * Author:        Chandra Modumudi
+ * Date:          03/01/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_ser_des_utils.h"
+
+/**
+ * lim_process_beacon_frame() - to process beacon frames
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_pkt_info: A pointer to RX packet info structure
+ * @session: A pointer to session
+ *
+ * This function is called by limProcessMessageQueue() upon Beacon
+ * frame reception.
+ * Note:
+ * 1. Beacons received in 'normal' state in IBSS are handled by
+ *    Beacon Processing module.
+ *
+ * Return: none
+ */
+
+void
+lim_process_beacon_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+			 tpPESession session)
+{
+	tpSirMacMgmtHdr mac_hdr;
+	tSchBeaconStruct *bcn_ptr;
+
+	mac_ctx->lim.gLimNumBeaconsRcvd++;
+
+	/*
+	 * here is it required to increment session specific heartBeat
+	 * beacon counter
+	 */
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	pe_debug("Received Beacon frame with length: %d from",
+		WMA_GET_RX_MPDU_LEN(rx_pkt_info));
+		lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOG2);
+
+	/* Expect Beacon in any state as Scan is independent of LIM state */
+	bcn_ptr = qdf_mem_malloc(sizeof(*bcn_ptr));
+	if (!bcn_ptr)
+		return;
+
+	/* Parse received Beacon */
+	if (sir_convert_beacon_frame2_struct(mac_ctx,
+			rx_pkt_info, bcn_ptr) !=
+			QDF_STATUS_SUCCESS) {
+		/*
+		 * Received wrongly formatted/invalid Beacon.
+		 * Ignore it and move on.
+		 */
+		pe_warn("Received invalid Beacon in state: %X",
+			session->limMlmState);
+		lim_print_mlm_state(mac_ctx, LOGW,
+			session->limMlmState);
+		qdf_mem_free(bcn_ptr);
+		return;
+	}
+
+	/*
+	 * during scanning, when any session is active, and
+	 * beacon/Pr belongs to one of the session, fill up the
+	 * following, TBD - HB counter
+	 */
+	if (sir_compare_mac_addr(session->bssId,
+				bcn_ptr->bssid)) {
+		qdf_mem_copy((uint8_t *)&session->lastBeaconTimeStamp,
+			(uint8_t *) bcn_ptr->timeStamp,
+			sizeof(uint64_t));
+		session->currentBssBeaconCnt++;
+	}
+	MTRACE(mac_trace(mac_ctx,
+		TRACE_CODE_RX_MGMT_TSF, 0, bcn_ptr->timeStamp[0]));
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF, 0,
+		bcn_ptr->timeStamp[1]));
+
+	if ((mac_ctx->lim.gLimMlmState ==
+				eLIM_MLM_WT_PROBE_RESP_STATE) ||
+		(mac_ctx->lim.gLimMlmState ==
+				eLIM_MLM_PASSIVE_SCAN_STATE)) {
+		/*
+		 * Calling dfsChannelList which will convert DFS channel
+		 * to active channel for x secs if this channel is DFS
+		 */
+		lim_set_dfs_channel_list(mac_ctx,
+			bcn_ptr->channelNumber,
+			&mac_ctx->lim.dfschannelList);
+	} else if (session->limMlmState ==
+			eLIM_MLM_WT_JOIN_BEACON_STATE) {
+		if (session->beacon != NULL) {
+			qdf_mem_free(session->beacon);
+			session->beacon = NULL;
+			session->bcnLen = 0;
+		}
+		session->bcnLen = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+		session->beacon = qdf_mem_malloc(session->bcnLen);
+		if (session->beacon)
+			/*
+			 * Store the Beacon/ProbeRsp. This is sent to
+			 * csr/hdd in join cnf response.
+			 */
+			qdf_mem_copy(session->beacon,
+				WMA_GET_RX_MPDU_DATA(rx_pkt_info),
+				session->bcnLen);
+
+		lim_check_and_announce_join_success(mac_ctx, bcn_ptr,
+				mac_hdr, session);
+	}
+	qdf_mem_free(bcn_ptr);
+	return;
+}
diff --git a/core/mac/src/pe/lim/lim_process_cfg_updates.c b/core/mac/src/pe/lim/lim_process_cfg_updates.c
new file mode 100644
index 0000000..9eeda5f
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_cfg_updates.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file lim_process_cfg_updates.cc contains the utility functions
+ * to handle various CFG parameter update events
+ * Author:        Chandra Modumudi
+ * Date:          01/20/03
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "ani_global.h"
+
+#include "wni_cfg.h"
+#include "sir_mac_prot_def.h"
+#include "cfg_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "sch_api.h"
+#include "rrm_api.h"
+
+static void lim_update_config(tpAniSirGlobal pMac, tpPESession psessionEntry);
+
+void lim_set_cfg_protection(tpAniSirGlobal pMac, tpPESession pesessionEntry)
+{
+	uint32_t val = 0;
+	struct wlan_mlme_cfg *mlme_cfg = pMac->mlme_cfg;
+
+	if (pesessionEntry != NULL && LIM_IS_AP_ROLE(pesessionEntry)) {
+		if (pesessionEntry->gLimProtectionControl ==
+		    MLME_FORCE_POLICY_PROTECTION_DISABLE)
+			qdf_mem_set((void *)&pesessionEntry->cfgProtection,
+				    sizeof(tCfgProtection), 0);
+		else {
+			pe_debug("frm11a = %d, from11b = %d, frm11g = %d, "
+				   "ht20 = %d, nongf = %d, lsigTxop = %d, "
+				   "rifs = %d, obss = %d",
+				pesessionEntry->cfgProtection.fromlla,
+				pesessionEntry->cfgProtection.fromllb,
+				pesessionEntry->cfgProtection.fromllg,
+				pesessionEntry->cfgProtection.ht20,
+				pesessionEntry->cfgProtection.nonGf,
+				pesessionEntry->cfgProtection.lsigTxop,
+				pesessionEntry->cfgProtection.rifs,
+				pesessionEntry->cfgProtection.obss);
+		}
+	} else {
+		pMac->lim.gLimProtectionControl =
+			mlme_cfg->sap_protection_cfg.protection_force_policy;
+
+
+		if (pMac->lim.gLimProtectionControl ==
+		    MLME_FORCE_POLICY_PROTECTION_DISABLE)
+			qdf_mem_set((void *)&pMac->lim.cfgProtection,
+				    sizeof(tCfgProtection), 0);
+		else {
+			val = mlme_cfg->sap_protection_cfg.protection_enabled;
+
+			pMac->lim.cfgProtection.fromlla =
+				(val >> MLME_PROTECTION_ENABLED_FROM_llA) & 1;
+			pMac->lim.cfgProtection.fromllb =
+				(val >> MLME_PROTECTION_ENABLED_FROM_llB) & 1;
+			pMac->lim.cfgProtection.fromllg =
+				(val >> MLME_PROTECTION_ENABLED_FROM_llG) & 1;
+			pMac->lim.cfgProtection.ht20 =
+				(val >> MLME_PROTECTION_ENABLED_HT_20) & 1;
+			pMac->lim.cfgProtection.nonGf =
+				(val >> MLME_PROTECTION_ENABLED_NON_GF) & 1;
+			pMac->lim.cfgProtection.lsigTxop =
+				(val >> MLME_PROTECTION_ENABLED_LSIG_TXOP) & 1;
+			pMac->lim.cfgProtection.rifs =
+				(val >> MLME_PROTECTION_ENABLED_RIFS) & 1;
+			pMac->lim.cfgProtection.obss =
+				(val >> MLME_PROTECTION_ENABLED_OBSS) & 1;
+
+		}
+	}
+}
+
+/**
+ * lim_handle_param_update()
+ *
+ ***FUNCTION:
+ * This function is use to post a message whenever need indicate
+ * there is update of config parameter.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param  pMac  - Pointer to Global MAC structure
+ * @param  cfgId - ID of CFG parameter that got updated
+ * @return None
+ */
+void lim_handle_param_update(tpAniSirGlobal pMac, eUpdateIEsType cfgId)
+{
+	struct scheduler_msg msg = { 0 };
+	QDF_STATUS status;
+
+	pe_debug("Handling CFG parameter id %X update", cfgId);
+
+	switch (cfgId) {
+	case eUPDATE_IE_PROBE_BCN:
+	{
+		msg.type = SIR_LIM_UPDATE_BEACON;
+		status = lim_post_msg_api(pMac, &msg);
+
+		if (status != QDF_STATUS_SUCCESS)
+			pe_err("Failed lim_post_msg_api %u", status);
+			break;
+	}
+	default:
+		break;
+	}
+}
+
+/**
+ * lim_apply_configuration()
+ *
+ ***FUNCTION:
+ * This function is called to apply the configured parameters
+ * before joining or reassociating with a BSS or starting a BSS.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param  pMac  - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_apply_configuration(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	uint32_t val = 0, phyMode;
+
+	pe_debug("Applying config");
+
+	psessionEntry->limSentCapsChangeNtf = false;
+
+	lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+	lim_update_config(pMac, psessionEntry);
+
+	lim_get_short_slot_from_phy_mode(pMac, psessionEntry, phyMode,
+					 &psessionEntry->shortSlotTimeSupported);
+
+	lim_set_cfg_protection(pMac, psessionEntry);
+
+	/* Added for BT - AMP Support */
+	if (LIM_IS_AP_ROLE(psessionEntry) ||
+	    LIM_IS_IBSS_ROLE(psessionEntry)) {
+		/* This check is required to ensure the beacon generation is not done
+		   as a part of join request for a BT-AMP station */
+
+		if (psessionEntry->statypeForBss == STA_ENTRY_SELF) {
+			pe_debug("Initializing BT-AMP beacon generation");
+			sch_set_beacon_interval(pMac, psessionEntry);
+			sch_set_fixed_beacon_fields(pMac, psessionEntry);
+		}
+	}
+
+	if (wlan_cfg_get_int(pMac, WNI_CFG_SCAN_IN_POWERSAVE, &val) !=
+	    QDF_STATUS_SUCCESS) {
+		pe_err("could not retrieve WNI_CFG_SCAN_IN_POWERSAVE");
+		return;
+	}
+} /*** end lim_apply_configuration() ***/
+
+/**
+ * lim_update_config
+ *
+ * FUNCTION:
+ * Update the local state from CFG database
+ * (This used to be dphUpdateConfig)
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+static void lim_update_config(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	uint32_t val;
+	bool enabled;
+
+	psessionEntry->beaconParams.fShortPreamble =
+					pMac->mlme_cfg->ht_caps.short_preamble;
+
+	/* In STA case this parameter is filled during the join request */
+	if (LIM_IS_AP_ROLE(psessionEntry) ||
+		LIM_IS_IBSS_ROLE(psessionEntry)) {
+		enabled = pMac->mlme_cfg->wmm_params.wme_enabled;
+		psessionEntry->limWmeEnabled = enabled;
+	}
+	enabled = pMac->mlme_cfg->wmm_params.wsm_enabled;
+	psessionEntry->limWsmEnabled = enabled;
+
+	if ((!psessionEntry->limWmeEnabled) && (psessionEntry->limWsmEnabled)) {
+		pe_err("Can't enable WSM without WME");
+		psessionEntry->limWsmEnabled = 0;
+	}
+	/* In STA , this parameter is filled during the join request */
+	if (LIM_IS_AP_ROLE(psessionEntry) || LIM_IS_IBSS_ROLE(psessionEntry)) {
+		enabled = pMac->mlme_cfg->wmm_params.qos_enabled;
+		psessionEntry->limQosEnabled = enabled;
+	}
+	psessionEntry->limHcfEnabled = pMac->mlme_cfg->feature_flags.enable_hcf;
+
+	/* AP: WSM should enable HCF as well, for STA enable WSM only after */
+	/* association response is received */
+	if (psessionEntry->limWsmEnabled && LIM_IS_AP_ROLE(psessionEntry))
+		psessionEntry->limHcfEnabled = 1;
+
+	if (wlan_cfg_get_int(pMac, WNI_CFG_11D_ENABLED, &val) != QDF_STATUS_SUCCESS)
+		pe_err("cfg get 11d enabled failed");
+	psessionEntry->lim11dEnabled = (val) ? 1 : 0;
+
+	pe_debug("Updated Lim shadow state based on CFG");
+}
diff --git a/core/mac/src/pe/lim/lim_process_deauth_frame.c b/core/mac/src/pe/lim/lim_process_deauth_frame.c
new file mode 100644
index 0000000..5816ce4
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_deauth_frame.c
@@ -0,0 +1,580 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_process_deauth_frame.cc contains the code
+ * for processing Deauthentication Frame.
+ * Author:        Chandra Modumudi
+ * Date:          03/24/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "ani_global.h"
+
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "sch_api.h"
+#include "lim_send_messages.h"
+
+/**
+ * lim_process_deauth_frame
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Deauthentication frame reception.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  *pRxPacketInfo - A pointer to Buffer descriptor + associated PDUs
+ * @return None
+ */
+
+void
+lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+			 tpPESession psessionEntry)
+{
+	uint8_t *pBody;
+	uint16_t reasonCode;
+	tpSirMacMgmtHdr pHdr;
+	tpPESession pRoamSessionEntry = NULL;
+	uint8_t roamSessionId;
+#ifdef WLAN_FEATURE_11W
+	uint32_t frameLen;
+#endif
+	int32_t frame_rssi;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	frame_rssi = (int32_t)WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo);
+	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+	if (frameLen < sizeof(reasonCode)) {
+		pe_err("Deauth Frame length invalid %d", frameLen);
+		return ;
+	}
+
+	if (LIM_IS_STA_ROLE(psessionEntry) &&
+	    ((eLIM_SME_WT_DISASSOC_STATE == psessionEntry->limSmeState) ||
+	     (eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState))) {
+		/*Every 15th deauth frame will be logged in kmsg */
+		if (!(pMac->lim.deauthMsgCnt & 0xF)) {
+			pe_debug("received Deauth frame in DEAUTH_WT_STATE"
+				"(already processing previously received DEAUTH frame)"
+				"Dropping this.. Deauth Failed %d",
+				       ++pMac->lim.deauthMsgCnt);
+		} else {
+			pMac->lim.deauthMsgCnt++;
+		}
+		return;
+	}
+
+	if (lim_is_group_addr(pHdr->sa)) {
+		/* Received Deauth frame from a BC/MC address */
+		/* Log error and ignore it */
+		pe_debug("received Deauth frame from a BC/MC address");
+		return;
+	}
+
+	if (lim_is_group_addr(pHdr->da) && !lim_is_addr_bc(pHdr->da)) {
+		/* Received Deauth frame for a MC address */
+		/* Log error and ignore it */
+		pe_debug("received Deauth frame for a MC address");
+		return;
+	}
+	if (!lim_validate_received_frame_a1_addr(pMac,
+			pHdr->da, psessionEntry)) {
+		pe_err("rx frame doesn't have valid a1 address, drop it");
+		return;
+	}
+#ifdef WLAN_FEATURE_11W
+	/* PMF: If this session is a PMF session, then ensure that this frame was protected */
+	if (psessionEntry->limRmfEnabled
+	    && (WMA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) &
+		DPU_FEEDBACK_UNPROTECTED_ERROR)) {
+		pe_debug("received an unprotected deauth from AP");
+		/*
+		 * When 11w offload is enabled then
+		 * firmware should not fwd this frame
+		 */
+		if (LIM_IS_STA_ROLE(psessionEntry) && pMac->pmf_offload) {
+			pe_err("11w offload is enable,unprotected deauth is not expected");
+			return;
+		}
+
+		/* If the frame received is unprotected, forward it to the supplicant to initiate */
+		/* an SA query */
+
+		/* send the unprotected frame indication to SME */
+		lim_send_sme_unprotected_mgmt_frame_ind(pMac, pHdr->fc.subType,
+							(uint8_t *) pHdr,
+							(frameLen +
+							 sizeof(tSirMacMgmtHdr)),
+							psessionEntry->smeSessionId,
+							psessionEntry);
+		return;
+	}
+#endif
+
+	/* Get reasonCode from Deauthentication frame body */
+	reasonCode = sir_read_u16(pBody);
+
+	pe_debug("Received Deauth frame for Addr: " MAC_ADDRESS_STR
+			"(mlm state = %s, sme state = %d systemrole = %d "
+			"RSSI = %d) with reason code %d [%s] from "
+			MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHdr->da),
+			lim_mlm_state_str(psessionEntry->limMlmState),
+			psessionEntry->limSmeState,
+			GET_LIM_SYSTEM_ROLE(psessionEntry), frame_rssi,
+			reasonCode, lim_dot11_reason_str(reasonCode),
+			MAC_ADDR_ARRAY(pHdr->sa));
+
+	if (pMac->mlme_cfg->gen.fatal_event_trigger &&
+	    (reasonCode != eSIR_MAC_UNSPEC_FAILURE_REASON &&
+	    reasonCode != eSIR_MAC_DEAUTH_LEAVING_BSS_REASON &&
+	    reasonCode != eSIR_MAC_DISASSOC_LEAVING_BSS_REASON)) {
+		cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+			       WLAN_LOG_INDICATOR_HOST_DRIVER,
+			       WLAN_LOG_REASON_DISCONNECT,
+			       false, false);
+	}
+
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_FRAME_EVENT,
+		psessionEntry, 0, reasonCode);
+
+	if (lim_check_disassoc_deauth_ack_pending(pMac, (uint8_t *) pHdr->sa)) {
+		pe_debug("Ignore the Deauth received, while waiting for ack of "
+			"disassoc/deauth");
+		lim_clean_up_disassoc_deauth_req(pMac, (uint8_t *) pHdr->sa, 1);
+		return;
+	}
+
+	if (LIM_IS_AP_ROLE(psessionEntry)) {
+		switch (reasonCode) {
+		case eSIR_MAC_UNSPEC_FAILURE_REASON:
+		case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
+			/* Valid reasonCode in received Deauthentication frame */
+			break;
+
+		default:
+			/* Invalid reasonCode in received Deauthentication frame */
+			/* Log error and ignore the frame */
+			pe_err("received Deauth frame with invalid reasonCode %d from "
+				       MAC_ADDRESS_STR, reasonCode,
+				       MAC_ADDR_ARRAY(pHdr->sa));
+
+			break;
+		}
+	} else if (LIM_IS_STA_ROLE(psessionEntry)) {
+		switch (reasonCode) {
+		case eSIR_MAC_UNSPEC_FAILURE_REASON:
+		case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON:
+		case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
+		case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON:
+		case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON:
+		case eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON:
+			/* Valid reasonCode in received Deauth frame */
+			break;
+
+		default:
+			/* Invalid reasonCode in received Deauth frame */
+			/* Log error and ignore the frame */
+			pe_err("received Deauth frame with invalid reasonCode %d from "
+				       MAC_ADDRESS_STR, reasonCode,
+				       MAC_ADDR_ARRAY(pHdr->sa));
+
+			break;
+		}
+	} else {
+		/* Received Deauth frame in either IBSS */
+		/* or un-known role. Log and ignore it */
+		pe_err("received Deauth frame with reasonCode %d in role %d from "
+			MAC_ADDRESS_STR, reasonCode,
+			GET_LIM_SYSTEM_ROLE(psessionEntry),
+			MAC_ADDR_ARRAY(pHdr->sa));
+
+		return;
+	}
+
+	/** If we are in the middle of ReAssoc, a few things could happen:
+	 *  - STA is reassociating to current AP, and receives deauth from:
+	 *         a) current AP
+	 *         b) other AP
+	 *  - STA is reassociating to a new AP, and receives deauth from:
+	 *         c) current AP
+	 *         d) reassoc AP
+	 *         e) other AP
+	 *
+	 *  The logic is:
+	 *  1) If rcv deauth from an AP other than the one we're trying to
+	 *     reassociate with, then drop the deauth frame (case b, c, e)
+	 *  2) If rcv deauth from the "new" reassoc AP (case d), then restore
+	 *     context with previous AP and send SME_REASSOC_RSP failure.
+	 *  3) If rcv deauth from the reassoc AP, which is also the same
+	 *     AP we're currently associated with (case a), then proceed
+	 *     with normal deauth processing.
+	 */
+	pRoamSessionEntry =
+		pe_find_session_by_bssid(pMac, psessionEntry->limReAssocbssId,
+							&roamSessionId);
+
+	if (lim_is_reassoc_in_progress(pMac, psessionEntry) ||
+	    lim_is_reassoc_in_progress(pMac, pRoamSessionEntry) ||
+	    psessionEntry->fw_roaming_started) {
+		/*
+		 * For LFR3, the roaming bssid is not known during ROAM_START,
+		 * so check if the deauth is received from current AP when
+		 * roaming is being done in the firmware
+		 */
+		if (psessionEntry->fw_roaming_started &&
+		    IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)) {
+			pe_debug("LFR3: Drop deauth frame from connected AP");
+			/*
+			 * recvd_deauth_while_roaming will be stored in the
+			 * current AP session amd if roaming has been aborted
+			 * for some reason and come back to same AP, then issue
+			 * a disconnect internally if this flag is true. There
+			 * is no need to reset this flag to false, because if
+			 * roaming succeeds, then this session gets deleted and
+			 * new session is created.
+			 */
+			psessionEntry->recvd_deauth_while_roaming = true;
+			psessionEntry->deauth_disassoc_rc = reasonCode;
+			return;
+		}
+		if (!IS_REASSOC_BSSID(pMac, pHdr->sa, psessionEntry)) {
+			pe_debug("Rcv Deauth from unknown/different "
+				"AP while ReAssoc. Ignore " MAC_ADDRESS_STR
+				"limReAssocbssId : " MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(pHdr->sa),
+				MAC_ADDR_ARRAY(psessionEntry->limReAssocbssId));
+			return;
+		}
+
+		/** Received deauth from the new AP to which we tried to ReAssociate.
+		 *  Drop ReAssoc and Restore the Previous context( current connected AP).
+		 */
+		if (!IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)) {
+			pe_debug("received DeAuth from the New AP to "
+				"which ReAssoc is sent " MAC_ADDRESS_STR
+				"psessionEntry->bssId: " MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(pHdr->sa),
+				MAC_ADDR_ARRAY(psessionEntry->bssId));
+
+			lim_restore_pre_reassoc_state(pMac,
+						      eSIR_SME_REASSOC_REFUSED,
+						      reasonCode,
+						      psessionEntry);
+			return;
+		}
+	}
+
+	/* If received DeAuth from AP other than the one we're trying to join with
+	 * nor associated with, then ignore deauth and delete Pre-auth entry.
+	 */
+	if (!LIM_IS_AP_ROLE(psessionEntry)) {
+		if (!IS_CURRENT_BSSID(pMac, pHdr->bssId, psessionEntry)) {
+			pe_err("received DeAuth from an AP other "
+				"than we're trying to join. Ignore. "
+				MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHdr->sa));
+
+			if (lim_search_pre_auth_list(pMac, pHdr->sa)) {
+				pe_debug("Preauth entry exist. Deleting");
+				lim_delete_pre_auth_node(pMac, pHdr->sa);
+			}
+			return;
+		}
+	}
+
+	lim_perform_deauth(pMac, psessionEntry, reasonCode, pHdr->sa,
+			   frame_rssi);
+
+
+} /*** end lim_process_deauth_frame() ***/
+
+void lim_perform_deauth(tpAniSirGlobal mac_ctx, tpPESession pe_session,
+			uint16_t rc, tSirMacAddr addr, int32_t frame_rssi)
+{
+	tLimMlmDeauthInd mlmDeauthInd;
+	tLimMlmAssocCnf mlmAssocCnf;
+	uint16_t aid;
+	tpDphHashNode sta_ds;
+
+	sta_ds = dph_lookup_hash_entry(mac_ctx, addr, &aid,
+				       &pe_session->dph.dphHashTable);
+	if (sta_ds == NULL) {
+		pe_debug("Hash entry not found");
+		return;
+	}
+	/* Check for pre-assoc states */
+	switch (GET_LIM_SYSTEM_ROLE(pe_session)) {
+	case eLIM_STA_ROLE:
+		switch (pe_session->limMlmState) {
+		case eLIM_MLM_WT_AUTH_FRAME2_STATE:
+			/**
+			 * AP sent Deauth frame while waiting
+			 * for Auth frame2. Report Auth failure
+			 * to SME.
+			 */
+
+			pe_debug("received Deauth frame state %X with failure "
+				"code %d from " MAC_ADDRESS_STR,
+				pe_session->limMlmState, rc,
+				MAC_ADDR_ARRAY(addr));
+
+			lim_restore_from_auth_state(mac_ctx,
+				eSIR_SME_DEAUTH_WHILE_JOIN,
+				rc, pe_session);
+
+			return;
+
+		case eLIM_MLM_AUTHENTICATED_STATE:
+			pe_debug("received Deauth frame state %X with "
+				"reasonCode=%d from " MAC_ADDRESS_STR,
+				pe_session->limMlmState, rc,
+				MAC_ADDR_ARRAY(addr));
+			/* / Issue Deauth Indication to SME. */
+			qdf_mem_copy((uint8_t *) &mlmDeauthInd.peerMacAddr,
+				addr, sizeof(tSirMacAddr));
+				mlmDeauthInd.reasonCode = rc;
+
+			pe_session->limMlmState = eLIM_MLM_IDLE_STATE;
+			MTRACE(mac_trace
+				(mac_ctx, TRACE_CODE_MLM_STATE,
+				 pe_session->peSessionId,
+				 pe_session->limMlmState));
+
+			lim_post_sme_message(mac_ctx,
+					LIM_MLM_DEAUTH_IND,
+					(uint32_t *) &mlmDeauthInd);
+			return;
+
+		case eLIM_MLM_WT_ASSOC_RSP_STATE:
+			/**
+			 * AP may have 'aged-out' our Pre-auth
+			 * context. Delete local pre-auth context
+			 * if any and issue ASSOC_CNF to SME.
+			 */
+			pe_debug("received Deauth frame state %X with "
+				"reasonCode=%d from " MAC_ADDRESS_STR,
+				pe_session->limMlmState, rc,
+				MAC_ADDR_ARRAY(addr));
+			if (lim_search_pre_auth_list(mac_ctx, addr))
+				lim_delete_pre_auth_node(mac_ctx, addr);
+
+			if (pe_session->pLimMlmJoinReq) {
+				qdf_mem_free(pe_session->pLimMlmJoinReq);
+				pe_session->pLimMlmJoinReq = NULL;
+			}
+
+			mlmAssocCnf.resultCode = eSIR_SME_DEAUTH_WHILE_JOIN;
+			mlmAssocCnf.protStatusCode = rc;
+
+			/* PE session Id */
+			mlmAssocCnf.sessionId = pe_session->peSessionId;
+
+			pe_session->limMlmState =
+			pe_session->limPrevMlmState;
+			MTRACE(mac_trace
+				(mac_ctx, TRACE_CODE_MLM_STATE,
+				 pe_session->peSessionId,
+				 pe_session->limMlmState));
+
+			/* Deactive Association response timeout */
+			lim_deactivate_and_change_timer(mac_ctx,
+					eLIM_ASSOC_FAIL_TIMER);
+
+			lim_post_sme_message(mac_ctx,
+					LIM_MLM_ASSOC_CNF,
+			(uint32_t *) &mlmAssocCnf);
+
+			return;
+
+		case eLIM_MLM_WT_ADD_STA_RSP_STATE:
+			pe_session->fDeauthReceived = true;
+			pe_debug("Received Deauth frame in state %X with Reason "
+				"Code %d from Peer" MAC_ADDRESS_STR,
+				pe_session->limMlmState, rc,
+				MAC_ADDR_ARRAY(addr));
+			return;
+
+		case eLIM_MLM_IDLE_STATE:
+		case eLIM_MLM_LINK_ESTABLISHED_STATE:
+#ifdef FEATURE_WLAN_TDLS
+			if ((NULL != sta_ds)
+				&& (STA_ENTRY_TDLS_PEER == sta_ds->staType)) {
+				pe_err("received Deauth frame in state %X with "
+					"reason code %d from Tdls peer"
+					MAC_ADDRESS_STR,
+					pe_session->limMlmState, rc,
+					MAC_ADDR_ARRAY(addr));
+			lim_send_sme_tdls_del_sta_ind(mac_ctx, sta_ds,
+							pe_session,
+							rc);
+			return;
+			} else {
+
+			/*
+			 * Delete all the TDLS peers only if Deauth
+			 * is received from the AP
+			 */
+				if (IS_CURRENT_BSSID(mac_ctx, addr, pe_session))
+					lim_delete_tdls_peers(mac_ctx, pe_session);
+#endif
+			/**
+			 * This could be Deauthentication frame from
+			 * a BSS with which pre-authentication was
+			 * performed. Delete Pre-auth entry if found.
+			 */
+			if (lim_search_pre_auth_list(mac_ctx, addr))
+				lim_delete_pre_auth_node(mac_ctx, addr);
+#ifdef FEATURE_WLAN_TDLS
+			}
+#endif
+			break;
+
+		case eLIM_MLM_WT_REASSOC_RSP_STATE:
+			pe_err("received Deauth frame state %X with "
+				"reasonCode=%d from " MAC_ADDRESS_STR,
+				pe_session->limMlmState, rc,
+				MAC_ADDR_ARRAY(addr));
+			break;
+
+		case eLIM_MLM_WT_FT_REASSOC_RSP_STATE:
+			pe_err("received Deauth frame in FT state %X with "
+				"reasonCode=%d from " MAC_ADDRESS_STR,
+				pe_session->limMlmState, rc,
+				MAC_ADDR_ARRAY(addr));
+			break;
+
+		default:
+			pe_err("received Deauth frame in state %X with "
+				"reasonCode=%d from " MAC_ADDRESS_STR,
+				pe_session->limMlmState, rc,
+				MAC_ADDR_ARRAY(addr));
+			return;
+		}
+		break;
+
+	case eLIM_STA_IN_IBSS_ROLE:
+		break;
+
+	case eLIM_AP_ROLE:
+		break;
+
+	default:
+		return;
+	} /* end switch (pMac->lim.gLimSystemRole) */
+
+	/**
+	 * Extract 'associated' context for STA, if any.
+	 * This is maintained by DPH and created by LIM.
+	 */
+	if (NULL == sta_ds) {
+		pe_err("sta_ds is NULL");
+		return;
+	}
+
+	if ((sta_ds->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
+	    (sta_ds->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE) ||
+	    sta_ds->sta_deletion_in_progress) {
+		/**
+		 * Already in the process of deleting context for the peer
+		 * and received Deauthentication frame. Log and Ignore.
+		 */
+		pe_debug("Deletion is in progress (%d) for peer:%pM in mlmState %d",
+			 sta_ds->sta_deletion_in_progress, addr,
+			 sta_ds->mlmStaContext.mlmState);
+		return;
+	}
+	sta_ds->mlmStaContext.disassocReason = (tSirMacReasonCodes) rc;
+	sta_ds->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DEAUTH;
+	sta_ds->sta_deletion_in_progress = true;
+
+	/* / Issue Deauth Indication to SME. */
+	qdf_mem_copy((uint8_t *) &mlmDeauthInd.peerMacAddr,
+			sta_ds->staAddr, sizeof(tSirMacAddr));
+	mlmDeauthInd.reasonCode =
+		(uint8_t) sta_ds->mlmStaContext.disassocReason;
+	mlmDeauthInd.deauthTrigger = eLIM_PEER_ENTITY_DEAUTH;
+
+	/*
+	 * If we're in the middle of ReAssoc and received deauth from
+	 * the ReAssoc AP, then notify SME by sending REASSOC_RSP with
+	 * failure result code. SME will post the disconnect to the
+	 * supplicant and the latter would start a fresh assoc.
+	 */
+	if (lim_is_reassoc_in_progress(mac_ctx, pe_session)) {
+		/**
+		 * AP may have 'aged-out' our Pre-auth
+		 * context. Delete local pre-auth context
+		 * if any and issue REASSOC_CNF to SME.
+		 */
+		if (lim_search_pre_auth_list(mac_ctx, addr))
+			lim_delete_pre_auth_node(mac_ctx, addr);
+
+		if (pe_session->limAssocResponseData) {
+			qdf_mem_free(pe_session->limAssocResponseData);
+			pe_session->limAssocResponseData = NULL;
+		}
+
+		pe_debug("Rcv Deauth from ReAssoc AP Issue REASSOC_CNF");
+		/*
+		 * TODO: Instead of overloading eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE
+		 * it would have been good to define/use a different failure type.
+		 * Using eSIR_SME_FT_REASSOC_FAILURE does not seem to clean-up
+		 * properly and we end up seeing "transmit queue timeout".
+		 */
+		lim_post_reassoc_failure(mac_ctx,
+				eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE,
+				eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				pe_session);
+		return;
+	}
+	/* reset the deauthMsgCnt here since we are able to Process
+	 * the deauth frame and sending up the indication as well */
+	if (mac_ctx->lim.deauthMsgCnt != 0) {
+		mac_ctx->lim.deauthMsgCnt = 0;
+	}
+	if (LIM_IS_STA_ROLE(pe_session))
+		wma_tx_abort(pe_session->smeSessionId);
+
+	lim_update_lost_link_info(mac_ctx, pe_session, frame_rssi);
+
+	/* / Deauthentication from peer MAC entity */
+	if (LIM_IS_STA_ROLE(pe_session))
+		lim_post_sme_message(mac_ctx, LIM_MLM_DEAUTH_IND,
+				(uint32_t *) &mlmDeauthInd);
+
+	/* send eWNI_SME_DEAUTH_IND to SME */
+	lim_send_sme_deauth_ind(mac_ctx, sta_ds, pe_session);
+	return;
+
+}
diff --git a/core/mac/src/pe/lim/lim_process_disassoc_frame.c b/core/mac/src/pe/lim/lim_process_disassoc_frame.c
new file mode 100644
index 0000000..97a284c
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_disassoc_frame.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_process_disassoc_frame.cc contains the code
+ * for processing Disassocation Frame.
+ * Author:        Chandra Modumudi
+ * Date:          03/24/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "wni_api.h"
+#include "sir_api.h"
+#include "ani_global.h"
+#include "wni_cfg.h"
+
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_send_messages.h"
+#include "sch_api.h"
+
+/**
+ * lim_process_disassoc_frame
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Disassociation frame reception.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * DPH drops packets for STA with 'valid' bit in pStaDs set to '0'.
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  *pRxPacketInfo - A pointer to Rx packet info structure
+ * @return None
+ */
+void
+lim_process_disassoc_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+			   tpPESession psessionEntry)
+{
+	uint8_t *pBody;
+	uint16_t aid, reasonCode;
+	tpSirMacMgmtHdr pHdr;
+	tpDphHashNode pStaDs;
+	uint32_t frame_len;
+	int32_t frame_rssi;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+	frame_rssi = (int32_t)WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo);
+
+	if (lim_is_group_addr(pHdr->sa)) {
+		/* Received Disassoc frame from a BC/MC address */
+		/* Log error and ignore it */
+		pe_err("received Disassoc frame from a BC/MC address");
+		return;
+	}
+
+	if (lim_is_group_addr(pHdr->da) && !lim_is_addr_bc(pHdr->da)) {
+		/* Received Disassoc frame for a MC address */
+		/* Log error and ignore it */
+		pe_err("received Disassoc frame for a MC address");
+		return;
+	}
+	if (!lim_validate_received_frame_a1_addr(pMac,
+			pHdr->da, psessionEntry)) {
+		pe_err("rx frame doesn't have valid a1 address, drop it");
+		return;
+	}
+
+	if (LIM_IS_STA_ROLE(psessionEntry) &&
+		((eLIM_SME_WT_DISASSOC_STATE == psessionEntry->limSmeState) ||
+		(eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState))) {
+		if (!(pMac->lim.disassocMsgCnt & 0xF)) {
+			pe_debug("received Disassoc frame in %s"
+				"already processing previously received Disassoc frame, dropping this %d",
+				 lim_sme_state_str(psessionEntry->limSmeState),
+				 ++pMac->lim.disassocMsgCnt);
+		} else {
+			pMac->lim.disassocMsgCnt++;
+		}
+		return;
+	}
+#ifdef WLAN_FEATURE_11W
+	/* PMF: If this session is a PMF session, then ensure that this frame was protected */
+	if (psessionEntry->limRmfEnabled
+	    && (WMA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) &
+		DPU_FEEDBACK_UNPROTECTED_ERROR)) {
+		pe_err("received an unprotected disassoc from AP");
+		/*
+		 * When 11w offload is enabled then
+		 * firmware should not fwd this frame
+		 */
+		if (LIM_IS_STA_ROLE(psessionEntry) &&  pMac->pmf_offload) {
+			pe_err("11w offload is enable,unprotected disassoc is not expected");
+			return;
+		}
+
+		/* If the frame received is unprotected, forward it to the supplicant to initiate */
+		/* an SA query */
+		/* send the unprotected frame indication to SME */
+		lim_send_sme_unprotected_mgmt_frame_ind(pMac, pHdr->fc.subType,
+							(uint8_t *) pHdr,
+							(frame_len +
+							 sizeof(tSirMacMgmtHdr)),
+							psessionEntry->smeSessionId,
+							psessionEntry);
+		return;
+	}
+#endif
+
+	if (frame_len < 2) {
+		pe_err("frame len less than 2");
+		return;
+	}
+
+	/* Get reasonCode from Disassociation frame body */
+	reasonCode = sir_read_u16(pBody);
+
+	pe_debug("Received Disassoc frame for Addr: " MAC_ADDRESS_STR
+		 "(mlm state=%s, sme state=%d RSSI=%d),"
+		 "with reason code %d [%s] from " MAC_ADDRESS_STR,
+		 MAC_ADDR_ARRAY(pHdr->da),
+		 lim_mlm_state_str(psessionEntry->limMlmState),
+		 psessionEntry->limSmeState, frame_rssi, reasonCode,
+		 lim_dot11_reason_str(reasonCode), MAC_ADDR_ARRAY(pHdr->sa));
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_FRAME_EVENT,
+		psessionEntry, 0, reasonCode);
+
+	if (pMac->mlme_cfg->gen.fatal_event_trigger &&
+	    (reasonCode != eSIR_MAC_UNSPEC_FAILURE_REASON &&
+	    reasonCode != eSIR_MAC_DEAUTH_LEAVING_BSS_REASON &&
+	    reasonCode != eSIR_MAC_DISASSOC_LEAVING_BSS_REASON)) {
+		cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+			       WLAN_LOG_INDICATOR_HOST_DRIVER,
+			       WLAN_LOG_REASON_DISCONNECT,
+			       false, false);
+	}
+	/**
+	 * Extract 'associated' context for STA, if any.
+	 * This is maintained by DPH and created by LIM.
+	 */
+	pStaDs =
+		dph_lookup_hash_entry(pMac, pHdr->sa, &aid,
+				      &psessionEntry->dph.dphHashTable);
+
+	if (pStaDs == NULL) {
+		/**
+		 * Disassociating STA is not associated.
+		 * Log error.
+		 */
+		pe_err("received Disassoc frame from STA that does not have context"
+			"reasonCode=%d, addr " MAC_ADDRESS_STR,
+			reasonCode, MAC_ADDR_ARRAY(pHdr->sa));
+		return;
+	}
+
+	if (lim_check_disassoc_deauth_ack_pending(pMac, (uint8_t *) pHdr->sa)) {
+		pe_err("Ignore the DisAssoc received, while waiting for ack of disassoc/deauth");
+		lim_clean_up_disassoc_deauth_req(pMac, (uint8_t *) pHdr->sa, 1);
+		return;
+	}
+
+	if (pMac->lim.disassocMsgCnt != 0) {
+		pMac->lim.disassocMsgCnt = 0;
+	}
+
+	/** If we are in the Wait for ReAssoc Rsp state */
+	if (lim_is_reassoc_in_progress(pMac, psessionEntry)) {
+		/*
+		 * For LFR3, the roaming bssid is not known during ROAM_START,
+		 * so check if the disassoc is received from current AP when
+		 * roaming is being done in the firmware
+		 */
+		if (psessionEntry->fw_roaming_started &&
+		    IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)) {
+			pe_debug("Dropping disassoc frame from connected AP");
+			psessionEntry->recvd_disassoc_while_roaming = true;
+			psessionEntry->deauth_disassoc_rc = reasonCode;
+			return;
+		}
+		/** If we had received the DisAssoc from,
+		 *     a. the Current AP during ReAssociate to different AP in same ESS
+		 *     b. Unknown AP
+		 *   drop/ignore the DisAssoc received
+		 */
+		if (!IS_REASSOC_BSSID(pMac, pHdr->sa, psessionEntry)) {
+			pe_err("Ignore DisAssoc while Processing ReAssoc");
+			return;
+		}
+		/** If the Disassoc is received from the new AP to which we tried to ReAssociate
+		 *  Drop ReAssoc and Restore the Previous context( current connected AP).
+		 */
+		if (!IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)) {
+			pe_debug("received Disassoc from the New AP to which ReAssoc is sent");
+			lim_restore_pre_reassoc_state(pMac,
+						      eSIR_SME_REASSOC_REFUSED,
+						      reasonCode,
+						      psessionEntry);
+			return;
+		}
+	}
+
+	if (LIM_IS_AP_ROLE(psessionEntry)) {
+		switch (reasonCode) {
+		case eSIR_MAC_UNSPEC_FAILURE_REASON:
+		case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
+		case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
+		case eSIR_MAC_MIC_FAILURE_REASON:
+		case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
+		case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
+		case eSIR_MAC_RSN_IE_MISMATCH_REASON:
+		case eSIR_MAC_1X_AUTH_FAILURE_REASON:
+			/* Valid reasonCode in received Disassociation frame */
+			break;
+
+		default:
+			/* Invalid reasonCode in received Disassociation frame */
+			pe_warn("received Disassoc frame with invalid reasonCode: %d from " MAC_ADDRESS_STR,
+				reasonCode, MAC_ADDR_ARRAY(pHdr->sa));
+			break;
+		}
+	} else if (LIM_IS_STA_ROLE(psessionEntry) &&
+		   ((psessionEntry->limSmeState != eLIM_SME_WT_JOIN_STATE) &&
+		   (psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) &&
+		   (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE) &&
+		   (psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE))) {
+		switch (reasonCode) {
+		case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
+		case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
+			/* Valid reasonCode in received Disassociation frame */
+			/* as long as we're not about to channel switch */
+			if (psessionEntry->gLimChannelSwitch.state !=
+			    eLIM_CHANNEL_SWITCH_IDLE) {
+				pe_err("Ignoring disassoc frame due to upcoming channel switch, from "MAC_ADDRESS_STR,
+					MAC_ADDR_ARRAY(pHdr->sa));
+				return;
+			}
+			break;
+
+		default:
+			break;
+		}
+	} else {
+		/* Received Disassociation frame in either IBSS */
+		/* or un-known role. Log and ignore it */
+		pe_err("received Disassoc frame with invalid reasonCode: %d in role:"
+				"%d in sme state: %d from " MAC_ADDRESS_STR, reasonCode,
+			GET_LIM_SYSTEM_ROLE(psessionEntry), psessionEntry->limSmeState,
+			MAC_ADDR_ARRAY(pHdr->sa));
+
+		return;
+	}
+
+	if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
+	    (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE) ||
+	    pStaDs->sta_deletion_in_progress) {
+		/**
+		 * Already in the process of deleting context for the peer
+		 * and received Disassociation frame. Log and Ignore.
+		 */
+		pe_debug("Deletion is in progress (%d) for peer:%pM in mlmState %d",
+			 pStaDs->sta_deletion_in_progress, pHdr->sa,
+			 pStaDs->mlmStaContext.mlmState);
+		return;
+	}
+	pStaDs->sta_deletion_in_progress = true;
+	lim_disassoc_tdls_peers(pMac, psessionEntry, pHdr->sa);
+	if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) {
+		/**
+		 * Requesting STA is in some 'transient' state?
+		 * Log error.
+		 */
+		if (pStaDs->mlmStaContext.mlmState ==
+		    eLIM_MLM_WT_ASSOC_CNF_STATE)
+			pStaDs->mlmStaContext.updateContext = 1;
+
+		pe_err("received Disassoc frame from peer that is in state: %X, addr "MAC_ADDRESS_STR,
+			pStaDs->mlmStaContext.mlmState,
+			       MAC_ADDR_ARRAY(pHdr->sa));
+
+	} /* if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) */
+
+	lim_perform_disassoc(pMac, frame_rssi, reasonCode,
+			     psessionEntry, pHdr->sa);
+
+} /*** end lim_process_disassoc_frame() ***/
+
+#ifdef FEATURE_WLAN_TDLS
+void lim_disassoc_tdls_peers(tpAniSirGlobal mac_ctx,
+				    tpPESession pe_session, tSirMacAddr addr)
+{
+	tpDphHashNode sta_ds;
+	uint16_t aid;
+
+	sta_ds = dph_lookup_hash_entry(mac_ctx, addr, &aid,
+				       &pe_session->dph.dphHashTable);
+	if (sta_ds == NULL) {
+		pe_debug("Hash entry not found");
+		return;
+	}
+	/**
+	 *  Delete all the TDLS peers only if Disassoc is received
+	 *  from the AP
+	 */
+	if ((LIM_IS_STA_ROLE(pe_session)) &&
+	    ((sta_ds->mlmStaContext.mlmState ==
+	      eLIM_MLM_LINK_ESTABLISHED_STATE) ||
+	     (sta_ds->mlmStaContext.mlmState ==
+	      eLIM_MLM_IDLE_STATE)) &&
+	    (IS_CURRENT_BSSID(mac_ctx, addr, pe_session)))
+		lim_delete_tdls_peers(mac_ctx, pe_session);
+}
+#endif
+
+void lim_perform_disassoc(tpAniSirGlobal mac_ctx, int32_t frame_rssi,
+			  uint16_t rc, tpPESession pe_session, tSirMacAddr addr)
+{
+	tLimMlmDisassocInd mlmDisassocInd;
+	uint16_t aid;
+	tpDphHashNode sta_ds;
+
+	sta_ds = dph_lookup_hash_entry(mac_ctx, addr, &aid,
+				       &pe_session->dph.dphHashTable);
+	if (sta_ds == NULL) {
+		pe_debug("Hash entry not found");
+		return;
+	}
+	sta_ds->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC;
+	sta_ds->mlmStaContext.disassocReason = (tSirMacReasonCodes) rc;
+
+	/* Issue Disassoc Indication to SME. */
+	qdf_mem_copy((uint8_t *) &mlmDisassocInd.peerMacAddr,
+			(uint8_t *) sta_ds->staAddr, sizeof(tSirMacAddr));
+	mlmDisassocInd.reasonCode =
+		(uint8_t) sta_ds->mlmStaContext.disassocReason;
+	mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC;
+
+	/* Update PE session Id  */
+	mlmDisassocInd.sessionId = pe_session->peSessionId;
+
+	if (lim_is_reassoc_in_progress(mac_ctx, pe_session)) {
+
+		/* If we're in the middle of ReAssoc and received disassoc from
+		 * the ReAssoc AP, then notify SME by sending REASSOC_RSP with
+		 * failure result code. By design, SME will then issue "Disassoc"
+		 * and cleanup will happen at that time.
+		 */
+		pe_debug("received Disassoc from AP while waiting for Reassoc Rsp");
+
+		if (pe_session->limAssocResponseData) {
+			qdf_mem_free(pe_session->limAssocResponseData);
+			pe_session->limAssocResponseData = NULL;
+		}
+
+		lim_restore_pre_reassoc_state(mac_ctx, eSIR_SME_REASSOC_REFUSED,
+				rc, pe_session);
+		return;
+	}
+
+	lim_update_lost_link_info(mac_ctx, pe_session, frame_rssi);
+	lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_IND,
+			(uint32_t *) &mlmDisassocInd);
+
+	/* send eWNI_SME_DISASSOC_IND to SME */
+	lim_send_sme_disassoc_ind(mac_ctx, sta_ds, pe_session);
+
+	return;
+}
diff --git a/core/mac/src/pe/lim/lim_process_fils.c b/core/mac/src/pe/lim/lim_process_fils.c
new file mode 100644
index 0000000..680d164
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_fils.c
@@ -0,0 +1,1860 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#include "lim_process_fils.h"
+#include <lim_send_messages.h>
+#include <lim_types.h>
+#include <lim_utils.h>
+#include <lim_prop_exts_utils.h>
+#include <lim_assoc_utils.h>
+#include <lim_session.h>
+#include <cds_ieee80211_defines.h>
+#include <qdf_crypto.h>
+
+#ifdef WLAN_FEATURE_FILS_SK
+
+#ifdef WLAN_FILS_DEBUG
+/**
+ * lim_fils_data_dump()- dump fils data
+ * @type: Data name
+ * @data: pointer to data buffer
+ * @len: data len
+ *
+ * Return: None
+ */
+static void lim_fils_data_dump(char *type, uint8_t *data, uint32_t len)
+{
+
+	QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+		 ("%s : length %d"), type, len);
+	qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO, data, len);
+}
+#else
+static void lim_fils_data_dump(char *type, uint8_t *data, uint32_t len)
+{ }
+#endif
+
+/**
+ * lim_get_crypto_digest_len()- Returns hash length based on crypto type
+ * @type: Crypto type
+ *
+ * Return: hash length
+ */
+static int lim_get_crypto_digest_len(uint8_t *type)
+{
+	if (!strcmp(type, HMAC_SHA386_CRYPTO_TYPE))
+		return SHA384_DIGEST_SIZE;
+	else if (!strcmp(type, HMAC_SHA256_CRYPTO_TYPE))
+		return SHA256_DIGEST_SIZE;
+	return -EINVAL;
+}
+
+/**
+ * lim_get_auth_tag_len()- This API returns auth tag len based on crypto suit
+ * used to encrypt erp packet.
+ * @crypto_suite: Crtpto suit
+ *
+ * Return: tag length
+ */
+static uint8_t lim_get_auth_tag_len(enum fils_erp_cryptosuite crypto_suite)
+{
+	switch (crypto_suite) {
+	case HMAC_SHA256_64:
+		return -EINVAL;
+	case HMAC_SHA256_128:
+		return FILS_SHA256_128_AUTH_TAG;
+	case HMAC_SHA256_256:
+		return FILS_SHA256_256_AUTH_TAG;
+	default:
+		return -EINVAL;
+	}
+}
+
+
+/**
+ * lim_get_crypto_type()- This API returns crypto type based on akm suite used
+ * @akm: akm used for authentication
+ *
+ * Return: Crypto type
+ */
+static uint8_t *lim_get_crypto_type(uint8_t akm)
+{
+	switch (akm) {
+	case eCSR_AUTH_TYPE_FILS_SHA384:
+	case eCSR_AUTH_TYPE_FT_FILS_SHA384:
+		return FILS_SHA384_CRYPTO_TYPE;
+	case eCSR_AUTH_TYPE_FILS_SHA256:
+	case eCSR_AUTH_TYPE_FT_FILS_SHA256:
+	default:
+		return FILS_SHA256_CRYPTO_TYPE;
+	}
+}
+
+/**
+ * lim_get_pmk_length()- This API returns pmk length based on akm used
+ * @akm: akm used for authentication
+ *
+ * Return: PMK length
+ */
+static uint8_t lim_get_pmk_length(int akm_type)
+{
+	switch (akm_type) {
+	case eCSR_AUTH_TYPE_FILS_SHA256:
+	case eCSR_AUTH_TYPE_FT_FILS_SHA256:
+		return FILS_SHA256_PKM_LEN;
+	case eCSR_AUTH_TYPE_FILS_SHA384:
+	case eCSR_AUTH_TYPE_FT_FILS_SHA384:
+		return FILS_SHA384_PKM_LEN;
+	default:
+		return FILS_SHA256_PKM_LEN;
+	}
+}
+
+/**
+ * lim_get_kek_len()- This API returns kek length based on akm used
+ * @akm: akm used for authentication
+ *
+ * Return: KEK length
+ */
+static uint8_t lim_get_kek_len(uint8_t akm)
+{
+	switch (akm) {
+	case eCSR_AUTH_TYPE_FILS_SHA384:
+	case eCSR_AUTH_TYPE_FT_FILS_SHA384:
+		return FILS_SHA384_KEK_LEN;
+	case eCSR_AUTH_TYPE_FILS_SHA256:
+	case eCSR_AUTH_TYPE_FT_FILS_SHA256:
+		return FILS_SHA256_KEK_LEN;
+	default:
+		return FILS_SHA256_KEK_LEN;
+	}
+}
+
+/**
+ * lim_get_tk_len()- This API returns tk length based on cypher used
+ * @akm: cypher used
+ *
+ * Return: TK length
+ */
+static uint8_t lim_get_tk_len(int cypher_suite)
+{
+	switch (cypher_suite) {
+	case eSIR_ED_TKIP:
+		return TK_LEN_TKIP;
+	case eSIR_ED_CCMP:
+		return TK_LEN_CCMP;
+	case eSIR_ED_AES_128_CMAC:
+		return TK_LEN_AES_128_CMAC;
+	default:
+		return 0;
+	}
+}
+
+/**
+ * lim_get_ick_len()- This API returns ick length based on akm used
+ * @akm: akm used for authentication
+ *
+ * Return: ICK length
+ */
+static int lim_get_ick_len(uint8_t akm)
+{
+	switch (akm) {
+	case eCSR_AUTH_TYPE_FILS_SHA384:
+	case eCSR_AUTH_TYPE_FT_FILS_SHA384:
+		return FILS_SHA384_ICK_LEN;
+	case eCSR_AUTH_TYPE_FILS_SHA256:
+	case eCSR_AUTH_TYPE_FT_FILS_SHA256:
+	default:
+		return FILS_SHA256_ICK_LEN;
+	}
+}
+
+/**
+ * lim_get_key_from_prf()- This API returns key data using PRF-X as defined in
+ * 11.6.1.7.2 ieee-80211-2012.
+ * @type: crypto type needs to be used
+ * @secret: key which needs to be used in crypto
+ * @secret_len: key_len of secret
+ * @label: PRF label
+ * @optional_data: Data used for hash
+ * @optional_data_len: data length
+ * @key: key data output
+ * @keylen: key data length
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS lim_get_key_from_prf(uint8_t *type, uint8_t *secret,
+		uint32_t secret_len, uint8_t *label, uint8_t *optional_data,
+		uint32_t optional_data_len, uint8_t *key, uint32_t keylen)
+{
+	uint8_t count[2];
+	uint8_t *addr[4];
+	uint32_t len[4];
+	uint16_t key_bit_length = keylen * 8;
+	uint8_t key_length[2];
+	uint32_t i = 0, remain_len;
+	uint16_t interation;
+	uint8_t crypto_digest_len = lim_get_crypto_digest_len(type);
+	uint8_t tmp_hash[SHA384_DIGEST_SIZE] = {0};
+
+	addr[0] = count;
+	len[0] = sizeof(count);
+
+	addr[1] = label;
+	len[1] = strlen(label);
+
+	addr[2] = optional_data;
+	len[2] = optional_data_len;
+
+	qdf_mem_copy(key_length, &key_bit_length, sizeof(key_bit_length));
+	addr[3] = key_length;
+	len[3] = sizeof(key_length);
+
+	for (interation = 1; i < keylen; interation++) {
+		remain_len = keylen - i;
+		qdf_mem_copy(count, &interation, sizeof(interation));
+
+		if (remain_len >= crypto_digest_len)
+			remain_len = crypto_digest_len;
+
+		if (qdf_get_hmac_hash(type, secret, secret_len, 4,
+				addr, len, tmp_hash) < 0) {
+			pe_err("qdf_get_hmac_hash failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+		qdf_mem_copy(&key[i], tmp_hash, remain_len);
+		i += crypto_digest_len;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_default_hmac_sha256_kdf()- This API calculates key data using default kdf
+ * defined in RFC4306.
+ * @secret: key which needs to be used in crypto
+ * @secret_len: key_len of secret
+ * @label: PRF label
+ * @optional_data: Data used for hash
+ * @optional_data_len: data length
+ * @key: key data output
+ * @keylen: key data length
+ *
+ * This API creates default KDF as defined in RFC4306
+ * PRF+ (K,S) = T1 | T2 | T3 | T4 | ...
+ * T1 = PRF (K, S | 0x01)
+ * T2 = PRF (K, T1 | S | 0x02)
+ * T3 = PRF (K, T2 | S | 0x03)
+ * T4 = PRF (K, T3 | S | 0x04)
+ *
+ * for every iteration its creates 32 bit of hash
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+lim_default_hmac_sha256_kdf(uint8_t *secret, uint32_t secret_len,
+		uint8_t *label, uint8_t *optional_data,
+		uint32_t optional_data_len, uint8_t *key, uint32_t keylen)
+{
+	uint8_t tmp_hash[SHA256_DIGEST_SIZE] = {0};
+	uint8_t count = 1;
+	uint8_t *addr[4];
+	uint32_t len[4];
+	uint32_t current_position = 0, remaining_data = SHA256_DIGEST_SIZE;
+
+	addr[0] = tmp_hash;
+	len[0] = SHA256_DIGEST_SIZE;
+	addr[1] = label;
+	len[1] = strlen(label) + 1;
+	addr[2] = optional_data;
+	len[2] = optional_data_len;
+	addr[3] = &count;
+	len[3] = 1;
+
+	if (keylen == 0 ||
+	   (keylen > (MAX_PRF_INTERATIONS_COUNT * SHA256_DIGEST_SIZE))) {
+		pe_err("invalid key length %d", keylen);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Create T1 */
+	if (qdf_get_hmac_hash(FILS_SHA256_CRYPTO_TYPE, secret, secret_len, 3,
+			&addr[1], &len[1], tmp_hash) < 0) {
+		pe_err("failed to get hmac hash");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Update hash from tmp_hash */
+	qdf_mem_copy(key + current_position, tmp_hash, remaining_data);
+	current_position += remaining_data;
+
+	for (count = 2; current_position < keylen; count++) {
+		remaining_data = keylen - current_position;
+		if (remaining_data > SHA256_DIGEST_SIZE)
+			remaining_data = SHA256_DIGEST_SIZE;
+
+		/* Create T-n */
+		if (qdf_get_hmac_hash(FILS_SHA256_CRYPTO_TYPE, secret,
+				secret_len, 4, addr, len, tmp_hash) < 0) {
+			pe_err("failed to get hmac hash");
+			return QDF_STATUS_E_FAILURE;
+		}
+		/* Update hash from tmp_hash */
+		qdf_mem_copy(key + current_position, tmp_hash, remaining_data);
+		current_position += remaining_data;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_process_fils_eap_tlv()- This API process eap tlv available in auth resp
+ * and returns remaining length.
+ * @pe_session: PE session
+ * @wrapped_data: wrapped data
+ * @data_len: length of tlv
+ *
+ * Return: remaining length
+ */
+static uint32_t lim_process_fils_eap_tlv(tpPESession pe_session,
+				uint8_t *wrapped_data, uint32_t data_len)
+{
+	struct fils_eap_tlv *tlv;
+	struct fils_auth_rsp_info *auth_info;
+	uint8_t auth_tag_len;
+
+	auth_info = &pe_session->fils_info->auth_info;
+	/* Minimum */
+	auth_tag_len = lim_get_auth_tag_len(HMAC_SHA256_128);
+
+	while (data_len > (auth_tag_len + 1)) {
+		tlv = (struct fils_eap_tlv *) wrapped_data;
+
+		pe_debug("tlv type %x len %u total %u",
+			tlv->type, tlv->length, data_len);
+
+		if (tlv->length > (data_len - 2)) {
+			pe_err("tlv len %d greater data_len %d",
+				tlv->length, data_len);
+			return 0;
+		}
+
+		switch (tlv->type) {
+		case SIR_FILS_EAP_TLV_KEYNAME_NAI:
+			auth_info->keyname = qdf_mem_malloc(tlv->length);
+			if (!auth_info->keyname)
+				return 0;
+
+			qdf_mem_copy(auth_info->keyname,
+				     tlv->data, tlv->length);
+			auth_info->keylength = tlv->length;
+			data_len -= (tlv->length + 2);
+			wrapped_data += (tlv->length + 2);
+			break;
+		case SIR_FILS_EAP_TLV_R_RK_LIFETIME:
+			/* TODO check this */
+			auth_info->r_rk_lifetime = lim_get_u32(tlv->data);
+			data_len -= (tlv->length + 2);
+			wrapped_data += (tlv->length + 2);
+			break;
+		case SIR_FILS_EAP_TLV_R_MSK_LIFETIME:
+			/* TODO check this */
+			auth_info->r_msk_lifetime = lim_get_u32(tlv->data);
+			data_len -= (tlv->length + 2);
+			wrapped_data += (tlv->length + 2);
+			break;
+		case SIR_FILS_EAP_TLV_DOMAIN_NAME:
+			auth_info->domain_name = qdf_mem_malloc(tlv->length);
+			if (!auth_info->domain_name)
+				return 0;
+
+			qdf_mem_copy(auth_info->domain_name,
+				     tlv->data, tlv->length);
+			auth_info->domain_len = tlv->length;
+			data_len -= (tlv->length + 2);
+			wrapped_data += (tlv->length + 2);
+			break;
+			/* TODO process these now */
+		case SIR_FILS_EAP_TLV_CRYPTO_LIST:
+		case SIR_FILS_EAP_TLV_AUTH_INDICATION:
+			data_len -= (tlv->length + 2);
+			wrapped_data += (tlv->length + 2);
+			break;
+		default:
+			pe_debug("Unknown type");
+			return data_len;
+		}
+	}
+	return data_len;
+}
+
+/**
+ * lim_generate_key_data()- This API generates key data using prf
+ * FILS-Key-Data = KDF-X(PMK, "FILS PTK Derivation", SPA||AA||SNonce||ANonce)
+ * @fils_info: fils session info
+ * @key_label: label used
+ * @data: data buffer
+ * @data_len: data buffer len
+ * @key_data: hash data needs to be generated
+ * @key_data_len: hash data len
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS lim_generate_key_data(struct pe_fils_session *fils_info,
+			uint8_t *key_label, uint8_t *data, uint32_t data_len,
+			uint8_t *key_data, uint32_t key_data_len)
+{
+	QDF_STATUS status;
+
+	if (!fils_info)
+		return QDF_STATUS_E_FAILURE;
+
+	status = lim_get_key_from_prf(lim_get_crypto_type(fils_info->akm),
+			fils_info->fils_pmk,
+			fils_info->fils_pmk_len,
+			key_label, data, data_len, key_data, key_data_len);
+	if (status != QDF_STATUS_SUCCESS)
+		pe_err("failed to generate keydata");
+	return status;
+}
+
+/**
+ * lim_generate_ap_key_auth()- This API generates ap auth data which needs to be
+ * verified in assoc response.
+ * @pe_session: pe session pointer
+ *
+ * Return: None
+ */
+static void lim_generate_ap_key_auth(tpPESession pe_session)
+{
+	uint8_t *buf, *addr[1];
+	uint32_t len;
+	struct pe_fils_session *fils_info = pe_session->fils_info;
+	uint8_t data[SIR_FILS_NONCE_LENGTH + SIR_FILS_NONCE_LENGTH
+			+ QDF_MAC_ADDR_SIZE + QDF_MAC_ADDR_SIZE] = {0};
+
+	if (!fils_info)
+		return;
+
+	len = SIR_FILS_NONCE_LENGTH + SIR_FILS_NONCE_LENGTH +
+			QDF_MAC_ADDR_SIZE +  QDF_MAC_ADDR_SIZE;
+	addr[0] = data;
+	buf = data;
+	qdf_mem_copy(buf, fils_info->auth_info.fils_nonce,
+			SIR_FILS_NONCE_LENGTH);
+	buf += SIR_FILS_NONCE_LENGTH;
+	qdf_mem_copy(buf, fils_info->fils_nonce, SIR_FILS_NONCE_LENGTH);
+	buf += SIR_FILS_NONCE_LENGTH;
+	qdf_mem_copy(buf, pe_session->bssId, QDF_MAC_ADDR_SIZE);
+	buf += QDF_MAC_ADDR_SIZE;
+	qdf_mem_copy(buf, pe_session->selfMacAddr, QDF_MAC_ADDR_SIZE);
+	buf += QDF_MAC_ADDR_SIZE;
+
+	if (qdf_get_hmac_hash(lim_get_crypto_type(fils_info->akm),
+				fils_info->ick, fils_info->ick_len, 1, &addr[0],
+				&len, fils_info->ap_key_auth_data) < 0)
+		pe_err("failed to generate PMK id");
+	fils_info->ap_key_auth_len = lim_get_crypto_digest_len(
+					lim_get_crypto_type(fils_info->akm));
+	lim_fils_data_dump("AP Key Auth", fils_info->ap_key_auth_data,
+		fils_info->ap_key_auth_len);
+}
+
+/**
+ * lim_generate_key_auth()- This API generates sta auth data which needs to be
+ * send to AP in assoc request, AP will generate the same the verify it.
+ * @pe_session: pe session pointer
+ *
+ * Return: None
+ */
+static void lim_generate_key_auth(tpPESession pe_session)
+{
+	uint8_t *buf, *addr[1];
+	uint32_t len;
+	struct pe_fils_session *fils_info = pe_session->fils_info;
+	uint8_t data[SIR_FILS_NONCE_LENGTH + SIR_FILS_NONCE_LENGTH
+			+ QDF_MAC_ADDR_SIZE + QDF_MAC_ADDR_SIZE] = {0};
+
+	if (!fils_info)
+		return;
+
+	len = SIR_FILS_NONCE_LENGTH + SIR_FILS_NONCE_LENGTH +
+			QDF_MAC_ADDR_SIZE +  QDF_MAC_ADDR_SIZE;
+
+	addr[0] = data;
+	buf = data;
+	qdf_mem_copy(buf, fils_info->fils_nonce, SIR_FILS_NONCE_LENGTH);
+	buf += SIR_FILS_NONCE_LENGTH;
+	qdf_mem_copy(buf, fils_info->auth_info.fils_nonce,
+			SIR_FILS_NONCE_LENGTH);
+	buf += SIR_FILS_NONCE_LENGTH;
+	qdf_mem_copy(buf, pe_session->selfMacAddr, QDF_MAC_ADDR_SIZE);
+	buf += QDF_MAC_ADDR_SIZE;
+	qdf_mem_copy(buf, pe_session->bssId, QDF_MAC_ADDR_SIZE);
+	buf += QDF_MAC_ADDR_SIZE;
+
+	if (qdf_get_hmac_hash(lim_get_crypto_type(fils_info->akm),
+				fils_info->ick, fils_info->ick_len, 1,
+				&addr[0], &len, fils_info->key_auth) < 0)
+		pe_err("failed to generate key auth");
+	fils_info->key_auth_len = lim_get_crypto_digest_len(
+				lim_get_crypto_type(fils_info->akm));
+	lim_fils_data_dump("STA Key Auth",
+			fils_info->key_auth, fils_info->key_auth_len);
+}
+
+/**
+ * lim_get_keys()- This API generates keys keydata which is generated after
+ * parsing of auth response.
+ * KCK = L(FILS-Key-Data, 0, KCK_bits)
+ * KEK = L(FILS-Key-Data, KCK_bits, KEK_bits)
+ * TK = L(FILS-Key-Data, KCK_bits + KEK_bits, TK_bits)
+ * FILS-FT = L(FILS-Key-Data, KCK_bits + KEK_bits + TK_bits, FILS-FT_bits)
+ * @pe_session: pe session pointer
+ *
+ * Return: None
+ */
+static void lim_get_keys(tpPESession pe_session)
+{
+	uint8_t key_label[] = PTK_KEY_LABEL;
+	uint8_t *data;
+	uint8_t data_len;
+	struct pe_fils_session *fils_info = pe_session->fils_info;
+	uint8_t key_data[MAX_ICK_LEN + MAX_KEK_LEN + MAX_TK_LEN] = {0};
+	uint8_t key_data_len;
+	uint8_t ick_len;
+	uint8_t kek_len;
+	uint8_t tk_len = lim_get_tk_len(pe_session->encryptType);
+	uint8_t *buf;
+
+	if (!fils_info)
+		return;
+
+	ick_len = lim_get_ick_len(fils_info->akm);
+	kek_len = lim_get_kek_len(fils_info->akm);
+
+	key_data_len = ick_len + kek_len + tk_len;
+
+	data_len = 2 * SIR_FILS_NONCE_LENGTH + 2 * QDF_MAC_ADDR_SIZE;
+	data = qdf_mem_malloc(data_len);
+	if (!data)
+		return;
+
+	/* Update data */
+	buf = data;
+	qdf_mem_copy(buf, pe_session->selfMacAddr, QDF_MAC_ADDR_SIZE);
+	buf += QDF_MAC_ADDR_SIZE;
+	qdf_mem_copy(buf, pe_session->bssId, QDF_MAC_ADDR_SIZE);
+	buf += QDF_MAC_ADDR_SIZE;
+	qdf_mem_copy(buf, fils_info->fils_nonce, SIR_FILS_NONCE_LENGTH);
+	buf += SIR_FILS_NONCE_LENGTH;
+	qdf_mem_copy(buf, fils_info->auth_info.fils_nonce,
+			SIR_FILS_NONCE_LENGTH);
+	lim_generate_key_data(fils_info, key_label, data, data_len,
+				key_data, key_data_len);
+	buf = key_data;
+	qdf_mem_copy(fils_info->ick, buf, ick_len);
+	fils_info->ick_len = ick_len;
+	buf += ick_len;
+	qdf_mem_copy(fils_info->kek, buf, kek_len);
+	fils_info->kek_len = kek_len;
+	buf += kek_len;
+	qdf_mem_copy(fils_info->tk, buf, tk_len);
+	fils_info->tk_len = tk_len;
+	qdf_mem_free(data);
+}
+
+/**
+ * lim_generate_pmkid()- This API generates PMKID using hash of erp auth packet
+ * parsing of auth response.
+ * PMKID = Truncate-128(Hash(EAP-Initiate/Reauth))
+ * @pe_session: pe session pointer
+ *
+ * Return: None
+ */
+static void lim_generate_pmkid(tpPESession pe_session)
+{
+	uint8_t hash[SHA384_DIGEST_SIZE];
+	struct pe_fils_session *fils_info = pe_session->fils_info;
+
+	if (!fils_info)
+		return;
+
+	qdf_get_hash(lim_get_crypto_type(fils_info->akm), 1,
+		&fils_info->fils_erp_reauth_pkt,
+		&fils_info->fils_erp_reauth_pkt_len, hash);
+	qdf_mem_copy(fils_info->fils_pmkid, hash, PMKID_LEN);
+	lim_fils_data_dump("PMKID", fils_info->fils_pmkid, PMKID_LEN);
+}
+
+/**
+ * lim_generate_pmk()- This API generates PMK using hmac hash of rmsk data
+ * anonce, snonce will be used as key for this
+ * PMK = HMAC-Hash(SNonce || ANonce, rMSK [ || DHss ])
+ * @pe_session: pe session pointer
+ *
+ * Return: None
+ */
+static void lim_generate_pmk(tpPESession pe_session)
+{
+	uint8_t nounce[2 * SIR_FILS_NONCE_LENGTH] = {0};
+	uint8_t nounce_len = 2 * SIR_FILS_NONCE_LENGTH;
+	uint8_t *addr[1];
+	uint32_t len[1];
+	struct pe_fils_session *fils_info = pe_session->fils_info;
+
+	if (!fils_info)
+		return;
+
+	/* Snounce */
+	qdf_mem_copy(nounce, pe_session->fils_info->fils_nonce,
+			SIR_FILS_NONCE_LENGTH);
+	/* anounce */
+	qdf_mem_copy(nounce + SIR_FILS_NONCE_LENGTH,
+			pe_session->fils_info->auth_info.fils_nonce,
+			SIR_FILS_NONCE_LENGTH);
+	fils_info->fils_pmk_len = lim_get_pmk_length(fils_info->akm);
+
+	if (fils_info->fils_pmk)
+		qdf_mem_free(fils_info->fils_pmk);
+
+	fils_info->fils_pmk = qdf_mem_malloc(fils_info->fils_pmk_len);
+	if (!fils_info->fils_pmk)
+		return;
+
+	addr[0] = fils_info->fils_rmsk;
+	len[0] = fils_info->fils_rmsk_len;
+	lim_fils_data_dump("Nonce", nounce, nounce_len);
+	if (qdf_get_hmac_hash(lim_get_crypto_type(fils_info->akm), nounce,
+				nounce_len, 1,
+				&addr[0], &len[0], fils_info->fils_pmk) < 0)
+		pe_err("failed to generate PMK");
+}
+
+/**
+ * lim_generate_rmsk_data()- This API generates RMSK data using
+ * default kdf as defined in RFC4306.
+ * @pe_session: pe session pointer
+ *
+ * Return: None
+ */
+static void lim_generate_rmsk_data(tpPESession pe_session)
+{
+	uint8_t optional_data[4] = {0};
+	uint8_t rmsk_label[] = RMSK_LABEL;
+	struct pe_fils_session *fils_info = pe_session->fils_info;
+	struct fils_auth_rsp_info *auth_info;
+
+	if (!fils_info)
+		return;
+
+	auth_info = &(pe_session->fils_info->auth_info);
+	fils_info->fils_rmsk_len = fils_info->fils_rrk_len;
+	fils_info->fils_rmsk = qdf_mem_malloc(fils_info->fils_rrk_len);
+	if (!fils_info->fils_rmsk)
+		return;
+
+	/*
+	 * Sequence number sent in EAP-INIT packet,
+	 * it should be in network byte order
+	 */
+	lim_copy_u16_be(&optional_data[0], fils_info->sequence_number);
+	lim_copy_u16_be(&optional_data[2], fils_info->fils_rrk_len);
+	lim_default_hmac_sha256_kdf(fils_info->fils_rrk,
+			fils_info->fils_rrk_len, rmsk_label,
+			optional_data, sizeof(optional_data),
+			fils_info->fils_rmsk, fils_info->fils_rmsk_len);
+}
+
+/**
+ * lim_process_auth_wrapped_data()- This API process wrapped data element
+ * of auth response.
+ * @pe_session: pe session pointer
+ * @wrapped_data: wrapped data pointer
+ * @data_len: wrapped data len
+ *
+ * Return: None
+ */
+static QDF_STATUS lim_process_auth_wrapped_data(tpPESession pe_session,
+			uint8_t *wrapped_data, uint32_t data_len)
+{
+	uint8_t code;
+	uint8_t identifier;
+	uint16_t length;
+	uint8_t type;
+	unsigned long flags;
+	struct pe_fils_session *fils_info;
+	uint8_t hash[32] = {0}, crypto;
+	uint32_t remaining_len = data_len, new_len;
+	uint8_t *input_data[1];
+	uint32_t input_len[1];
+	uint8_t auth_tag_len;
+
+	fils_info = pe_session->fils_info;
+	input_data[0] = wrapped_data;
+	input_len[0] = data_len;
+
+	if (!fils_info)
+		return QDF_STATUS_E_FAILURE;
+
+	pe_debug("trying to process the wrappped data");
+
+	code = *wrapped_data;
+	wrapped_data++;
+	remaining_len--;
+	identifier = *wrapped_data;
+	wrapped_data++;
+	remaining_len--;
+
+	length = lim_get_u16(wrapped_data);
+	wrapped_data += sizeof(uint16_t);
+	remaining_len -= sizeof(uint16_t);
+
+	type = *wrapped_data; /* val should be 2 here */
+	wrapped_data++;
+	remaining_len--;
+
+	flags = *wrapped_data;
+	if (test_bit(7, &flags)) {
+		pe_err("R bit is set in flag, error");
+		return QDF_STATUS_E_FAILURE;
+	}
+	wrapped_data++;
+	remaining_len--;
+
+	fils_info->auth_info.sequence = lim_get_u16_be(wrapped_data);
+	wrapped_data += sizeof(uint16_t);
+	remaining_len -= sizeof(uint16_t);
+	/* Validate Auth sequence number */
+	if (fils_info->auth_info.sequence < fils_info->sequence_number) {
+		pe_err("sequence EAP-finish:%d is less than EAP-init:%d",
+			fils_info->auth_info.sequence,
+			fils_info->sequence_number);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Parse attached TLVs */
+	new_len = lim_process_fils_eap_tlv(pe_session,
+				wrapped_data, remaining_len);
+
+	wrapped_data += remaining_len - new_len;
+	remaining_len = new_len;
+	/* Remove cryptosuite */
+	crypto = *wrapped_data;
+	wrapped_data++;
+	remaining_len--;
+
+	auth_tag_len = lim_get_auth_tag_len(crypto);
+	input_len[0] -= auth_tag_len;
+	/* if we have auth tag remaining */
+	if (remaining_len == auth_tag_len) {
+		qdf_get_hmac_hash(FILS_SHA256_CRYPTO_TYPE,
+				fils_info->fils_rik,
+				fils_info->fils_rik_len,
+				SINGLE_ELEMENT_HASH_CNT,
+				input_data, input_len, hash);
+	} else {
+		pe_err("invalid remaining len %d",
+			remaining_len);
+	}
+	if (qdf_mem_cmp(wrapped_data, hash, auth_tag_len)) {
+		pe_err("integratity check failed for auth, crypto %d",
+			crypto);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	lim_generate_rmsk_data(pe_session);
+	lim_generate_pmk(pe_session);
+	lim_generate_pmkid(pe_session);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_is_valid_fils_auth_frame()- This API check whether auth frame is a
+ * valid frame.
+ * @mac_ctx: mac context
+ * @pe_session: pe session pointer
+ * @rx_auth_frm_body: pointer to autherntication frame
+ *
+ * Return: true if frame is valid or fils is disable, false otherwise
+ */
+bool lim_is_valid_fils_auth_frame(tpAniSirGlobal mac_ctx,
+		tpPESession pe_session,
+		tSirMacAuthFrameBody *rx_auth_frm_body)
+{
+	if (!pe_session->fils_info)
+		return true;
+
+	if (pe_session->fils_info->is_fils_connection == false)
+		return true;
+
+	if (qdf_mem_cmp(rx_auth_frm_body->session,
+				pe_session->fils_info->fils_session,
+				SIR_FILS_SESSION_LENGTH)) {
+		lim_fils_data_dump("Current FILS session",
+				pe_session->fils_info->fils_session,
+				SIR_FILS_SESSION_LENGTH);
+		lim_fils_data_dump("FILS Session in pkt",
+				rx_auth_frm_body->session,
+				SIR_FILS_SESSION_LENGTH);
+		return false;
+	}
+	qdf_mem_copy(pe_session->fils_info->auth_info.fils_nonce,
+			rx_auth_frm_body->nonce, SIR_FILS_NONCE_LENGTH);
+	pe_session->fils_info->auth_info.assoc_delay =
+			rx_auth_frm_body->assoc_delay_info;
+	return true;
+}
+
+QDF_STATUS lim_create_fils_rik(uint8_t *rrk, uint8_t rrk_len,
+					uint8_t *rik, uint32_t *rik_len)
+{
+	uint8_t optional_data[SIR_FILS_OPTIONAL_DATA_LEN];
+	uint8_t label[] = SIR_FILS_RIK_LABEL;
+
+	if (!rrk || !rik) {
+		pe_err("FILS rrk/rik NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	optional_data[0] = HMAC_SHA256_128;
+	/* basic validation */
+	if (rrk_len <= 0) {
+		pe_err("invalid r_rk length %d", rrk_len);
+		return QDF_STATUS_E_FAILURE;
+	}
+	lim_copy_u16_be(&optional_data[1], rrk_len);
+	if (lim_default_hmac_sha256_kdf(rrk, rrk_len, label,
+				optional_data, sizeof(optional_data),
+				rik, rrk_len)
+			!= QDF_STATUS_SUCCESS) {
+		pe_err("failed to create rik");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*rik_len = rrk_len;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_create_fils_wrapper_data()- This API create warpped data which will be
+ * sent in auth request.
+ * @fils_info: fils session info
+ *
+ * Return: length of the created wrapped data
+ */
+static int lim_create_fils_wrapper_data(struct pe_fils_session *fils_info)
+{
+	uint8_t *buf;
+	uint8_t auth_tag[FILS_AUTH_TAG_MAX_LENGTH] = {0};
+	uint32_t length = 0;
+	QDF_STATUS status;
+	int buf_len;
+
+	if (!fils_info)
+		return 0;
+
+	buf_len =
+		/* code + identifier */
+		sizeof(uint8_t) * 2 +
+		/* length */
+		sizeof(uint16_t) +
+		/* type + flags */
+		sizeof(uint8_t) * 2 +
+		/* sequence */
+		sizeof(uint16_t) +
+		/* tlv : type, length, data */
+		sizeof(uint8_t) * 2 + fils_info->keyname_nai_length +
+		/* cryptosuite + auth_tag */
+		sizeof(uint8_t) + lim_get_auth_tag_len(HMAC_SHA256_128);
+
+	fils_info->fils_erp_reauth_pkt = qdf_mem_malloc(buf_len);
+	if (!fils_info->fils_erp_reauth_pkt)
+		return -EINVAL;
+
+	buf = fils_info->fils_erp_reauth_pkt;
+	*buf = 5;
+	buf++;
+	/* Identifier */
+	*buf = 0;
+	buf++;
+	/* Length */
+	lim_copy_u16_be(buf, buf_len);
+	buf += sizeof(uint16_t);
+	/* type */
+	*buf = SIR_FILS_EAP_INIT_PACKET_TYPE;
+	buf++;
+
+	/**
+	 *  flag
+	 *  0 1 2  <-- 5 -->
+	 * ----------------
+	 * |R|B|L| Reserved|
+	 * -----------------
+	 */
+	*buf = 0x20; /* l=1, b=0, r=0 */
+	buf++;
+	/* sequence */
+	lim_copy_u16_be(buf, fils_info->sequence_number);
+	buf += sizeof(uint16_t);
+
+	/* tlv */
+	/* Type */
+	*buf = SIR_FILS_EAP_TLV_KEYNAME_NAI;
+	buf++;
+	/* NAI Length */
+	*buf = fils_info->keyname_nai_length;
+	buf++;
+	/* NAI Data */
+	qdf_mem_copy(buf, fils_info->keyname_nai_data,
+			fils_info->keyname_nai_length);
+	buf += fils_info->keyname_nai_length;
+
+	/* cryptosuite */
+	*buf = HMAC_SHA256_128;
+	buf++;
+
+	/*
+	 * This should be moved to just after sending probe to save time
+	 * lim_process_switch_channel_join_req ??
+	 */
+	fils_info->fils_rik = qdf_mem_malloc(fils_info->fils_rrk_len);
+	if (!fils_info->fils_rik) {
+		qdf_mem_free(fils_info->fils_erp_reauth_pkt);
+		fils_info->fils_erp_reauth_pkt = NULL;
+		return -EINVAL;
+	}
+	status = lim_create_fils_rik(fils_info->fils_rrk,
+				     fils_info->fils_rrk_len,
+				     fils_info->fils_rik,
+				     &fils_info->fils_rik_len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("RIK create fails");
+		qdf_mem_free(fils_info->fils_erp_reauth_pkt);
+		qdf_mem_free(fils_info->fils_rik);
+		fils_info->fils_erp_reauth_pkt = NULL;
+		fils_info->fils_rik = NULL;
+		return -EINVAL;
+	}
+
+	fils_info->fils_erp_reauth_pkt_len = buf_len;
+	length = fils_info->fils_erp_reauth_pkt_len -
+			lim_get_auth_tag_len(HMAC_SHA256_128);
+	qdf_get_hmac_hash(FILS_SHA256_CRYPTO_TYPE,
+			fils_info->fils_rik, fils_info->fils_rik_len, 1,
+			&fils_info->fils_erp_reauth_pkt, &length, auth_tag);
+
+	lim_fils_data_dump("Auth tag", auth_tag,
+			lim_get_auth_tag_len(HMAC_SHA256_128));
+	lim_fils_data_dump("EAP init pkt", fils_info->fils_erp_reauth_pkt,
+			fils_info->fils_erp_reauth_pkt_len);
+
+	qdf_mem_copy(buf, auth_tag, lim_get_auth_tag_len(HMAC_SHA256_128));
+	buf += lim_get_auth_tag_len(HMAC_SHA256_128);
+
+	return buf_len;
+}
+
+/**
+ * lim_add_fils_data_to_auth_frame()- This API add fils data to auth frame.
+ * Following will be added in this.
+ * RSNIE
+ * SNonce
+ * Session
+ * Wrapped data
+ * @session: PE session
+ * @body: pointer to auth frame where data needs to be added
+ *
+ * Return: None
+ */
+void lim_add_fils_data_to_auth_frame(tpPESession session,
+		uint8_t *body)
+{
+	struct pe_fils_session *fils_info;
+
+	fils_info = session->fils_info;
+
+	if (!fils_info)
+		return;
+
+	/* RSN IE */
+	qdf_mem_copy(body, fils_info->rsn_ie, fils_info->rsn_ie_len);
+	body += fils_info->rsn_ie_len;
+	lim_fils_data_dump("FILS RSN", fils_info->rsn_ie,
+			fils_info->rsn_ie_len);
+
+	/* ***Nounce*** */
+	/* Add element id */
+	*body = SIR_MAX_ELEMENT_ID;
+	body++;
+	/* Add nounce length + 1 for ext element id */
+	*body = SIR_FILS_NONCE_LENGTH + 1;
+	body++;
+	/* Add ext element */
+	*body = SIR_FILS_NONCE_EXT_EID;
+	body++;
+	/* Add data */
+	cds_rand_get_bytes(0, fils_info->fils_nonce, SIR_FILS_NONCE_LENGTH);
+	qdf_mem_copy(body, fils_info->fils_nonce, SIR_FILS_NONCE_LENGTH);
+	body = body + SIR_FILS_NONCE_LENGTH;
+	/* Dump data */
+	lim_fils_data_dump("fils anonce", fils_info->fils_nonce,
+			SIR_FILS_NONCE_LENGTH);
+
+	/*   *** Session ***  */
+	/* Add element id */
+	*body = SIR_MAX_ELEMENT_ID;
+	body++;
+	/* Add nounce length + 1 for ext element id */
+	*body = SIR_FILS_SESSION_LENGTH + 1;
+	body++;
+	/* Add ext element */
+	*body = SIR_FILS_SESSION_EXT_EID;
+	body++;
+	/* Add data */
+	cds_rand_get_bytes(0, fils_info->fils_session, SIR_FILS_SESSION_LENGTH);
+	qdf_mem_copy(body, fils_info->fils_session, SIR_FILS_SESSION_LENGTH);
+	body = body + SIR_FILS_SESSION_LENGTH;
+	/* dump data */
+	lim_fils_data_dump("Fils Session",
+		fils_info->fils_session, SIR_FILS_SESSION_LENGTH);
+
+	/*  ERP Packet  */
+	/* Add element id */
+	*body = SIR_MAX_ELEMENT_ID;
+	body++;
+	/* Add packet length + 1 for ext element id */
+	*body = fils_info->fils_erp_reauth_pkt_len + 1;
+	body++;
+	/* Add ext element */
+	*body = SIR_FILS_WRAPPED_DATA_EXT_EID;
+	body++;
+	/* Copy data */
+	qdf_mem_copy(body, fils_info->fils_erp_reauth_pkt,
+			fils_info->fils_erp_reauth_pkt_len);
+	lim_fils_data_dump("Fils ERP reauth Pkt",
+			fils_info->fils_erp_reauth_pkt,
+			fils_info->fils_erp_reauth_pkt_len);
+	body = body + fils_info->fils_erp_reauth_pkt_len;
+}
+
+/**
+ * lim_process_fils_auth_frame2()- This API process fils data from auth response
+ * @mac_ctx: mac context
+ * @session: PE session
+ * @rx_auth_frm_body: pointer to auth frame
+ *
+ * Return: true if fils data needs to be processed else false
+ */
+bool lim_process_fils_auth_frame2(tpAniSirGlobal mac_ctx,
+		tpPESession pe_session,
+		tSirMacAuthFrameBody *rx_auth_frm_body)
+{
+	int i;
+	uint32_t ret;
+	bool pmkid_found = false;
+	tDot11fIERSN dot11f_ie_rsn = {0};
+
+	if (!pe_session->fils_info)
+		return false;
+
+	if (rx_auth_frm_body->authAlgoNumber != SIR_FILS_SK_WITHOUT_PFS)
+		return false;
+
+	ret = dot11f_unpack_ie_rsn(mac_ctx, &rx_auth_frm_body->rsn_ie.info[0],
+				rx_auth_frm_body->rsn_ie.length,
+				&dot11f_ie_rsn, 0);
+	if (!DOT11F_SUCCEEDED(ret)) {
+		pe_err("unpack failed, ret: %d", ret);
+		return false;
+	}
+
+	for (i = 0; i < dot11f_ie_rsn.pmkid_count; i++) {
+		if (qdf_mem_cmp(dot11f_ie_rsn.pmkid[i],
+		    pe_session->fils_info->fils_pmkid,
+		    PMKID_LEN) == 0) {
+			pmkid_found = true;
+			pe_debug("pmkid match in rsn ie total_count %d",
+				dot11f_ie_rsn.pmkid_count);
+			break;
+		}
+	}
+	if (!pmkid_found) {
+		if (QDF_STATUS_SUCCESS !=
+		    lim_process_auth_wrapped_data(pe_session,
+			rx_auth_frm_body->wrapped_data,
+			rx_auth_frm_body->wrapped_data_len))
+			return false;
+	}
+	lim_get_keys(pe_session);
+	lim_generate_key_auth(pe_session);
+	lim_generate_ap_key_auth(pe_session);
+	return true;
+}
+
+/**
+ * lim_update_fils_config()- This API update fils session info to csr config
+ * from join request.
+ * @session: PE session
+ * @sme_join_req: pointer to join request
+ *
+ * Return: None
+ */
+void lim_update_fils_config(tpPESession session,
+		tpSirSmeJoinReq sme_join_req)
+{
+	struct pe_fils_session *csr_fils_info;
+	struct cds_fils_connection_info *fils_config_info;
+
+	fils_config_info = &sme_join_req->fils_con_info;
+	csr_fils_info = session->fils_info;
+
+	if (!csr_fils_info)
+		return;
+
+	if (fils_config_info->is_fils_connection == false)
+		return;
+
+	csr_fils_info->is_fils_connection =
+		fils_config_info->is_fils_connection;
+	csr_fils_info->keyname_nai_length =
+		fils_config_info->key_nai_length;
+	csr_fils_info->fils_rrk_len =
+		fils_config_info->r_rk_length;
+	csr_fils_info->akm = fils_config_info->akm_type;
+	csr_fils_info->auth = fils_config_info->auth_type;
+	csr_fils_info->sequence_number = fils_config_info->sequence_number;
+	if (fils_config_info->key_nai_length > FILS_MAX_KEYNAME_NAI_LENGTH) {
+		pe_err("Restricting the key_nai_length of  %d to max %d",
+		       fils_config_info->key_nai_length,
+		       FILS_MAX_KEYNAME_NAI_LENGTH);
+		fils_config_info->key_nai_length = FILS_MAX_KEYNAME_NAI_LENGTH;
+	}
+	csr_fils_info->keyname_nai_data =
+		qdf_mem_malloc(fils_config_info->key_nai_length);
+	if (!csr_fils_info->keyname_nai_data)
+		return;
+
+	qdf_mem_copy(csr_fils_info->keyname_nai_data,
+			fils_config_info->keyname_nai,
+			fils_config_info->key_nai_length);
+	csr_fils_info->fils_rrk =
+		qdf_mem_malloc(fils_config_info->r_rk_length);
+	if (!csr_fils_info->fils_rrk) {
+		qdf_mem_free(csr_fils_info->keyname_nai_data);
+		return;
+	}
+
+	if (fils_config_info->r_rk_length <= FILS_MAX_RRK_LENGTH)
+		qdf_mem_copy(csr_fils_info->fils_rrk,
+				fils_config_info->r_rk,
+				fils_config_info->r_rk_length);
+
+	qdf_mem_copy(csr_fils_info->fils_pmkid,
+			fils_config_info->pmkid, PMKID_LEN);
+	csr_fils_info->rsn_ie_len = sme_join_req->rsnIE.length;
+	qdf_mem_copy(csr_fils_info->rsn_ie,
+			sme_join_req->rsnIE.rsnIEdata,
+			sme_join_req->rsnIE.length);
+
+	csr_fils_info->fils_pmk_len = fils_config_info->pmk_len;
+	if (fils_config_info->pmk_len) {
+		csr_fils_info->fils_pmk =
+			qdf_mem_malloc(fils_config_info->pmk_len);
+		if (!csr_fils_info->fils_pmk) {
+			qdf_mem_free(csr_fils_info->keyname_nai_data);
+			qdf_mem_free(csr_fils_info->fils_rrk);
+			return;
+		}
+		qdf_mem_copy(csr_fils_info->fils_pmk, fils_config_info->pmk,
+			fils_config_info->pmk_len);
+	}
+	pe_debug("fils=%d nai-len=%d rrk_len=%d akm=%d auth=%d pmk_len=%d",
+		fils_config_info->is_fils_connection,
+		fils_config_info->key_nai_length,
+		fils_config_info->r_rk_length,
+		fils_config_info->akm_type,
+		fils_config_info->auth_type,
+		fils_config_info->pmk_len);
+}
+
+#define EXTENDED_IE_HEADER_LEN 3
+/**
+ * lim_create_fils_auth_data()- This API creates the fils auth data
+ * which needs to be sent in auth req.
+ * @mac_ctx: mac context
+ * @auth_frame: pointer to auth frame
+ * @session: PE session
+ *
+ * Return: length of fils data
+ */
+uint32_t lim_create_fils_auth_data(tpAniSirGlobal mac_ctx,
+		tpSirMacAuthFrameBody auth_frame,
+		tpPESession session)
+{
+	uint32_t frame_len = 0;
+	int32_t wrapped_data_len;
+
+	if (!session->fils_info)
+		return 0;
+
+	/* These memory may already been allocated if auth retry */
+	if (session->fils_info->fils_rik) {
+		qdf_mem_free(session->fils_info->fils_rik);
+		session->fils_info->fils_rik = NULL;
+	}
+	if  (session->fils_info->fils_erp_reauth_pkt) {
+		qdf_mem_free(session->fils_info->fils_erp_reauth_pkt);
+		session->fils_info->fils_erp_reauth_pkt = NULL;
+	}
+	if (auth_frame->authAlgoNumber == SIR_FILS_SK_WITHOUT_PFS) {
+		frame_len += session->fils_info->rsn_ie_len;
+		/* FILS nounce */
+		frame_len += SIR_FILS_NONCE_LENGTH + EXTENDED_IE_HEADER_LEN;
+		/* FILS Session */
+		frame_len += SIR_FILS_SESSION_LENGTH + EXTENDED_IE_HEADER_LEN;
+		/* Calculate data/length for FILS Wrapped Data */
+		wrapped_data_len =
+			lim_create_fils_wrapper_data(session->fils_info);
+		if (wrapped_data_len < 0) {
+			pe_err("failed to create warpped data");
+			return 0;
+		}
+		frame_len += wrapped_data_len + EXTENDED_IE_HEADER_LEN;
+	}
+	return frame_len;
+}
+
+void populate_fils_connect_params(tpAniSirGlobal mac_ctx,
+				  tpPESession session,
+				  tpSirSmeJoinRsp sme_join_rsp)
+{
+	struct fils_join_rsp_params *fils_join_rsp;
+	struct pe_fils_session *fils_info = session->fils_info;
+
+	if (!lim_is_fils_connection(session))
+		return;
+
+	if (!fils_info->fils_pmk_len ||
+			!fils_info->tk_len || !fils_info->gtk_len ||
+			!fils_info->fils_pmk || !fils_info->kek_len) {
+		pe_err("Invalid FILS info pmk len %d kek len %d tk len %d gtk len %d",
+			fils_info->fils_pmk_len,
+			fils_info->kek_len,
+			fils_info->tk_len,
+			fils_info->gtk_len);
+		return;
+	}
+
+	sme_join_rsp->fils_join_rsp = qdf_mem_malloc(sizeof(*fils_join_rsp));
+	if (!sme_join_rsp->fils_join_rsp) {
+		pe_delete_fils_info(session);
+		return;
+	}
+
+	fils_join_rsp = sme_join_rsp->fils_join_rsp;
+	fils_join_rsp->fils_pmk = qdf_mem_malloc(fils_info->fils_pmk_len);
+	if (!fils_join_rsp->fils_pmk) {
+		qdf_mem_free(fils_join_rsp);
+		pe_delete_fils_info(session);
+		return;
+	}
+
+	fils_join_rsp->fils_pmk_len = fils_info->fils_pmk_len;
+	qdf_mem_copy(fils_join_rsp->fils_pmk, fils_info->fils_pmk,
+			fils_info->fils_pmk_len);
+
+	qdf_mem_copy(fils_join_rsp->fils_pmkid, fils_info->fils_pmkid,
+			IEEE80211_PMKID_LEN);
+
+	fils_join_rsp->kek_len = fils_info->kek_len;
+	qdf_mem_copy(fils_join_rsp->kek, fils_info->kek, fils_info->kek_len);
+
+	fils_join_rsp->tk_len = fils_info->tk_len;
+	qdf_mem_copy(fils_join_rsp->tk, fils_info->tk, fils_info->tk_len);
+
+	fils_join_rsp->gtk_len = fils_info->gtk_len;
+	qdf_mem_copy(fils_join_rsp->gtk, fils_info->gtk, fils_info->gtk_len);
+
+	cds_copy_hlp_info(&fils_info->dst_mac, &fils_info->src_mac,
+			  fils_info->hlp_data_len, fils_info->hlp_data,
+			  &fils_join_rsp->dst_mac, &fils_join_rsp->src_mac,
+			  &fils_join_rsp->hlp_data_len,
+			  fils_join_rsp->hlp_data);
+
+	pe_debug("FILS connect params copied lim");
+}
+
+/**
+ * lim_parse_kde_elements() - Parse Key Delivery Elements
+ * @mac_ctx: mac context
+ * @fils_info: FILS info
+ * @kde_list: KDE list buffer
+ * @kde_list_len: Length of @kde_list
+ *
+ * This API is used to parse the Key Delivery Elements from buffer
+ * and populate them in PE FILS session struct i.e @fils_info
+ *
+ *             Key Delivery Element[KDE] format
+ * +----------+--------+-----------+------------+----------+
+ * | ID(0xDD) | length |  KDE OUI  |  data type |  IE data |
+ * |----------|--------|-----------|------------|----------|
+ * |  1 byte  | 1 byte |  3 bytes  |   1 byte   | variable |
+ * +----------+--------+-----------+------------+----------+
+ *
+ * there can be multiple KDE present inside KDE list.
+ * the IE data could be GTK, IGTK etc based on the data type
+ *
+ * Return: QDF_STATUS_SUCCESS if we parse GTK successfully,
+ *         QDF_STATUS_E_FAILURE otherwise
+ */
+static QDF_STATUS lim_parse_kde_elements(tpAniSirGlobal mac_ctx,
+					 struct pe_fils_session *fils_info,
+					 uint8_t *kde_list,
+					 uint8_t kde_list_len)
+{
+	uint8_t rem_len = kde_list_len;
+	uint8_t *temp_ie = kde_list;
+	uint8_t elem_id, data_type, data_len, *ie_data = NULL, *current_ie;
+	uint16_t elem_len;
+
+	if (!kde_list_len || !kde_list) {
+		pe_err("kde_list NULL or kde_list_len %d", kde_list_len);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	while (rem_len >= 2) {
+		current_ie = temp_ie;
+		elem_id = *temp_ie++;
+		elem_len = *temp_ie++;
+		rem_len -= 2;
+
+		if (rem_len < elem_len || elem_len > kde_list_len) {
+			pe_err("Invalid elem_len %d rem_len %d list_len %d",
+				elem_len, rem_len, kde_list_len);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (elem_len < KDE_IE_DATA_OFFSET) {
+			pe_err("Not enough len to parse elem_len %d",
+				elem_len);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (lim_check_if_vendor_oui_match(mac_ctx, KDE_OUI_TYPE,
+				KDE_OUI_TYPE_SIZE, current_ie, elem_len)) {
+
+			data_type = *(temp_ie + KDE_DATA_TYPE_OFFSET);
+			ie_data = (temp_ie + KDE_IE_DATA_OFFSET);
+			data_len = (elem_len - KDE_IE_DATA_OFFSET);
+
+			switch (data_type) {
+			case DATA_TYPE_GTK:
+				if (data_len < GTK_OFFSET) {
+					pe_err("Invalid KDE data_len %d",
+						data_len);
+					return QDF_STATUS_E_FAILURE;
+				}
+				qdf_mem_copy(fils_info->gtk, (ie_data +
+					     GTK_OFFSET), (data_len -
+					     GTK_OFFSET));
+				fils_info->gtk_len = (data_len - GTK_OFFSET);
+				break;
+
+			case DATA_TYPE_IGTK:
+				if (data_len < IGTK_OFFSET) {
+					pe_err("Invalid KDE data_len %d",
+						data_len);
+					return QDF_STATUS_E_FAILURE;
+				}
+				fils_info->igtk_len = (data_len - IGTK_OFFSET);
+				qdf_mem_copy(fils_info->igtk, (ie_data +
+					     IGTK_OFFSET), (data_len -
+					     IGTK_OFFSET));
+				qdf_mem_copy(fils_info->ipn, (ie_data +
+					     IPN_OFFSET), IPN_LEN);
+			break;
+			default:
+				pe_err("Unknown KDE data type %x", data_type);
+			break;
+			}
+		}
+
+		temp_ie += elem_len;
+		rem_len -= elem_len;
+		ie_data = NULL;
+	}
+
+	/* Expecting GTK in KDE */
+	if (!fils_info->gtk_len) {
+		pe_err("GTK not found in KDE");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool lim_verify_fils_params_assoc_rsp(tpAniSirGlobal mac_ctx,
+				      tpPESession session_entry,
+				      tpSirAssocRsp assoc_rsp,
+				      tLimMlmAssocCnf *assoc_cnf)
+{
+	struct pe_fils_session *fils_info = session_entry->fils_info;
+	tDot11fIEfils_session fils_session = assoc_rsp->fils_session;
+	tDot11fIEfils_key_confirmation fils_key_auth = assoc_rsp->fils_key_auth;
+	tDot11fIEfils_kde fils_kde = assoc_rsp->fils_kde;
+	QDF_STATUS status;
+
+	if (!lim_is_fils_connection(session_entry))
+		return true;
+
+	if (!fils_info) {
+		pe_err("FILS Info not present");
+		goto verify_fils_params_fails;
+	}
+
+	if (!assoc_rsp->fils_session.present) {
+		pe_err("FILS IE not present");
+		goto verify_fils_params_fails;
+	}
+
+	/* Compare FILS session */
+	if (qdf_mem_cmp(fils_info->fils_session,
+			fils_session.session, DOT11F_IE_FILS_SESSION_MAX_LEN)) {
+		pe_err("FILS session mismatch");
+		goto verify_fils_params_fails;
+	}
+
+	/* Compare FILS key auth */
+	if ((fils_key_auth.num_key_auth != fils_info->key_auth_len) ||
+		qdf_mem_cmp(fils_info->ap_key_auth_data, fils_key_auth.key_auth,
+					 fils_info->ap_key_auth_len)) {
+		lim_fils_data_dump("session keyauth",
+				   fils_info->ap_key_auth_data,
+				   fils_info->ap_key_auth_len);
+		lim_fils_data_dump("Pkt keyauth",
+				   fils_key_auth.key_auth,
+				   fils_key_auth.num_key_auth);
+		goto verify_fils_params_fails;
+	}
+
+	/* Verify the Key Delivery Element presence */
+	if (!fils_kde.num_kde_list) {
+		pe_err("FILS KDE list absent");
+		goto verify_fils_params_fails;
+	}
+
+	/* Derive KDE elements */
+	status = lim_parse_kde_elements(mac_ctx, fils_info, fils_kde.kde_list,
+					fils_kde.num_kde_list);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		pe_err("KDE parsing fails");
+		goto verify_fils_params_fails;
+	}
+	return true;
+
+verify_fils_params_fails:
+	assoc_cnf->resultCode = eSIR_SME_ASSOC_REFUSED;
+	assoc_cnf->protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+	return false;
+}
+
+/**
+ * find_ie_data_after_fils_session_ie() - Find IE pointer after FILS Session IE
+ * @mac_ctx: MAC context
+ * @buf: IE buffer
+ * @buf_len: Length of @buf
+ * @ie: Pointer to update the found IE pointer after FILS session IE
+ * @ie_len: length of the IE data after FILS session IE
+ *
+ * This API is used to find the IE data ptr and length after FILS session IE
+ *
+ * Return: QDF_STATUS_SUCCESS if found, else QDF_STATUS_E_FAILURE
+ */
+static QDF_STATUS find_ie_data_after_fils_session_ie(tpAniSirGlobal mac_ctx,
+						     uint8_t *buf,
+						     uint32_t buf_len,
+						     uint8_t **ie,
+						     uint32_t *ie_len)
+{
+	uint32_t left = buf_len;
+	uint8_t *ptr = buf;
+	uint8_t elem_id, elem_len;
+
+	if (NULL == buf || 0 == buf_len)
+		return QDF_STATUS_E_FAILURE;
+
+	while (left >= 2) {
+		elem_id = ptr[0];
+		elem_len = ptr[1];
+		left -= 2;
+		if (elem_len > left)
+			return QDF_STATUS_E_FAILURE;
+
+		if (elem_id == SIR_MAC_REQUEST_EID_MAX &&
+			ptr[2] == SIR_FILS_SESSION_EXT_EID) {
+			(*ie) = ((&ptr[1]) + ptr[1] + 1);
+			(*ie_len) = (left - elem_len);
+			return QDF_STATUS_SUCCESS;
+		}
+		left -= elem_len;
+		ptr += (elem_len + 2);
+	}
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * fils_aead_encrypt() - API to do FILS AEAD encryption
+ *
+ * @kek: Pointer to KEK
+ * @kek_len: KEK length
+ * @own_mac: Pointer to own MAC address
+ * @bssid: Bssid
+ * @snonce: Supplicant Nonce
+ * @anonce: Authenticator Nonce
+ * @data: Pointer to data after MAC header
+ * @data_len: length of @data
+ * @plain_text: Pointer to data after FILS Session IE
+ * @plain_text_len: length of @plain_text
+ * @out: Pointer to the encrypted data
+ *
+ * length of AEAD encryption @out is @plain_text_len + AES_BLOCK_SIZE[16 bytes]
+ *
+ * Return: zero on success, error otherwise
+ */
+static int fils_aead_encrypt(const uint8_t *kek, unsigned int kek_len,
+			     const uint8_t *own_mac, const uint8_t *bssid,
+			     const uint8_t *snonce, const uint8_t *anonce,
+			     const uint8_t *data, size_t data_len,
+			     uint8_t *plain_text, size_t plain_text_len,
+			     uint8_t *out)
+{
+	uint8_t v[AES_BLOCK_SIZE];
+	const uint8_t *aad[6];
+	size_t aad_len[6];
+	uint8_t *buf;
+	int ret;
+
+	/* SIV Encrypt/Decrypt takes input key of length 256, 384 or 512 bits */
+	if (kek_len != 32 && kek_len != 48 && kek_len != 64) {
+		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid key length: %u"), kek_len);
+		return -EINVAL;
+	}
+
+	if (own_mac == NULL || bssid == NULL || snonce == NULL ||
+	    anonce == NULL || data_len == 0 || plain_text_len == 0 ||
+	    out == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+			  FL("Error missing params mac:%pK bssid:%pK snonce:%pK anonce:%pK data_len:%zu plain_text_len:%zu out:%pK"),
+			  own_mac, bssid, snonce, anonce, data_len,
+			  plain_text_len, out);
+		return -EINVAL;
+	}
+
+	if (plain_text == out) {
+		buf = qdf_mem_malloc(plain_text_len);
+		if (!buf)
+			return -ENOMEM;
+		qdf_mem_copy(buf, plain_text, plain_text_len);
+	} else {
+		buf = plain_text;
+	}
+
+	aad[0] = own_mac;
+	aad_len[0] = QDF_MAC_ADDR_SIZE;
+	aad[1] = bssid;
+	aad_len[1] = QDF_MAC_ADDR_SIZE;
+	aad[2] = snonce;
+	aad_len[2] = SIR_FILS_NONCE_LENGTH;
+	aad[3] = anonce;
+	aad_len[3] = SIR_FILS_NONCE_LENGTH;
+	aad[4] = data;
+	aad_len[4] = data_len;
+	/* Plain text, P, is Sn in AES-SIV */
+	aad[5] = buf;
+	aad_len[5] = plain_text_len;
+
+	/* AES-SIV S2V */
+	/* K1 = leftmost(K, len(K)/2) */
+	ret = qdf_aes_s2v(kek, kek_len/2, aad, aad_len, 6, v);
+	if (ret)
+		goto error;
+
+	/* out = SIV || C (Synthetic Initialization Vector || Ciphered text) */
+	qdf_mem_copy(out, v, AES_BLOCK_SIZE);
+
+	/* AES-SIV CTR */
+	/* K2 = rightmost(K, len(K)/2) */
+	/* Clear 31st and 63rd bits in counter synthetic iv */
+	v[12] &= 0x7F;
+	v[8] &= 0x7F;
+
+	ret = qdf_aes_ctr(kek + kek_len/2, kek_len/2, v, buf, plain_text_len,
+		      out + AES_BLOCK_SIZE, true);
+
+error:
+	if (plain_text == out)
+		qdf_mem_free(buf);
+	return ret;
+}
+
+QDF_STATUS aead_encrypt_assoc_req(tpAniSirGlobal mac_ctx,
+				  tpPESession pe_session,
+				  uint8_t *frm, uint32_t *frm_len)
+{
+	uint8_t *plain_text = NULL, *data;
+	uint32_t plain_text_len = 0, data_len;
+	QDF_STATUS status;
+	struct pe_fils_session *fils_info = pe_session->fils_info;
+
+	/*
+	 * data is the packet data after MAC header till
+	 * FILS session IE(inclusive)
+	 */
+	data = frm + sizeof(tSirMacMgmtHdr);
+
+	/*
+	 * plain_text is the packet data after FILS session IE
+	 * which needs to be encrypted. Get plain_text ptr and
+	 * plain_text_len values using find_ptr_aft_fils_session_ie()
+	 */
+	status = find_ie_data_after_fils_session_ie(mac_ctx, data +
+					      FIXED_PARAM_OFFSET_ASSOC_REQ,
+					      (*frm_len -
+					      FIXED_PARAM_OFFSET_ASSOC_REQ),
+					      &plain_text, &plain_text_len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("Could not find FILS session IE");
+		return QDF_STATUS_E_FAILURE;
+	}
+	data_len = ((*frm_len) - plain_text_len);
+
+	lim_fils_data_dump("Plain text: ", plain_text, plain_text_len);
+
+	/* Overwrite the AEAD encrypted output @ plain_text */
+	if (fils_aead_encrypt(fils_info->kek, fils_info->kek_len,
+			      pe_session->selfMacAddr, pe_session->bssId,
+			      fils_info->fils_nonce,
+			      fils_info->auth_info.fils_nonce,
+			      data, data_len, plain_text, plain_text_len,
+			      plain_text)) {
+		pe_err("AEAD Encryption fails!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * AEAD encrypted output(cipher_text) will have length equals to
+	 * plain_text_len + AES_BLOCK_SIZE(AEAD encryption header info).
+	 * Add this to frm_len
+	 */
+	(*frm_len) += (AES_BLOCK_SIZE);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * fils_aead_decrypt() - API to do AEAD decryption
+ *
+ * @kek: Pointer to KEK
+ * @kek_len: KEK length
+ * @own_mac: Pointer to own MAC address
+ * @bssid: Bssid
+ * @snonce: Supplicant Nonce
+ * @anonce: Authenticator Nonce
+ * @data: Pointer to data after MAC header
+ * @data_len: length of @data
+ * @plain_text: Pointer to data after FILS Session IE
+ * @plain_text_len: length of @plain_text
+ * @out: Pointer to the encrypted data
+ *
+ * Return: zero on success, error otherwise
+ */
+static int fils_aead_decrypt(const uint8_t *kek, unsigned int kek_len,
+			     const uint8_t *own_mac, const uint8_t *bssid,
+			     const uint8_t *snonce, const uint8_t *anonce,
+			     const uint8_t *data, size_t data_len,
+			     uint8_t *ciphered_text, size_t ciphered_text_len,
+			     uint8_t *plain_text)
+{
+	const uint8_t *aad[6];
+	size_t aad_len[6];
+	uint8_t *buf;
+	size_t buf_len;
+	uint8_t v[AES_BLOCK_SIZE];
+	uint8_t siv[AES_BLOCK_SIZE];
+	int ret;
+
+	/* SIV Encrypt/Decrypt takes input key of length 256, 384 or 512 bits */
+	if (kek_len != 32 && kek_len != 48 && kek_len != 64) {
+		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid key length: %u"), kek_len);
+		return -EINVAL;
+	}
+
+	if (own_mac == NULL || bssid == NULL || snonce == NULL ||
+	    anonce == NULL || data_len == 0 || ciphered_text_len == 0 ||
+	    plain_text == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+			  FL("Error missing params mac:%pK bssid:%pK snonce:%pK anonce:%pK data_len:%zu ciphered_text_len:%zu plain_text:%pK"),
+			  own_mac, bssid, snonce, anonce, data_len,
+			  ciphered_text_len, plain_text);
+		return -EINVAL;
+	}
+
+	qdf_mem_copy(v, ciphered_text, AES_BLOCK_SIZE);
+	qdf_mem_copy(siv, ciphered_text, AES_BLOCK_SIZE);
+	v[12] &= 0x7F;
+	v[8] &= 0x7F;
+
+	buf_len = ciphered_text_len - AES_BLOCK_SIZE;
+	if (ciphered_text == plain_text) {
+		/* in place decryption */
+		buf = qdf_mem_malloc(buf_len);
+		if (!buf)
+			return -ENOMEM;
+		qdf_mem_copy(buf, ciphered_text + AES_BLOCK_SIZE, buf_len);
+	} else {
+		buf = ciphered_text + AES_BLOCK_SIZE;
+	}
+
+	/* AES-SIV CTR */
+	/* K2 = rightmost(K, len(K)/2) */
+	ret = qdf_aes_ctr(kek + kek_len/2, kek_len/2, v, buf, buf_len,
+			  plain_text, false);
+	if (ret)
+		goto error;
+
+	aad[0] = bssid;
+	aad_len[0] = QDF_MAC_ADDR_SIZE;
+	aad[1] = own_mac;
+	aad_len[1] = QDF_MAC_ADDR_SIZE;
+	aad[2] = anonce;
+	aad_len[2] = SIR_FILS_NONCE_LENGTH;
+	aad[3] = snonce;
+	aad_len[3] = SIR_FILS_NONCE_LENGTH;
+	aad[4] = data;
+	aad_len[4] = data_len;
+	aad[5] = plain_text;
+	aad_len[5] = buf_len;
+
+	/* AES-SIV S2V */
+	/* K1 = leftmost(K, len(K)/2) */
+	ret = qdf_aes_s2v(kek, kek_len/2, aad, aad_len, 6, v);
+	if (ret)
+		goto error;
+
+	/* compare the iv generated against the one sent by AP */
+	if (memcmp(v, siv, AES_BLOCK_SIZE) != 0) {
+		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+			  FL("siv not same as frame siv"));
+		ret = -EINVAL;
+	}
+
+error:
+	if (ciphered_text == plain_text)
+		qdf_mem_free(buf);
+	return ret;
+}
+
+QDF_STATUS aead_decrypt_assoc_rsp(tpAniSirGlobal mac_ctx,
+				  tpPESession session,
+				  tDot11fAssocResponse *ar,
+				  uint8_t *p_frame, uint32_t *n_frame)
+{
+	QDF_STATUS status;
+	uint32_t data_len, fils_ies_len;
+	uint8_t *fils_ies;
+	struct pe_fils_session *fils_info = session->fils_info;
+
+	status = find_ie_data_after_fils_session_ie(mac_ctx, p_frame +
+					      FIXED_PARAM_OFFSET_ASSOC_RSP,
+					      ((*n_frame) -
+					      FIXED_PARAM_OFFSET_ASSOC_RSP),
+					      &fils_ies, &fils_ies_len);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		pe_err("FILS session IE not present");
+		return status;
+	}
+
+	data_len = (*n_frame) - fils_ies_len;
+
+	if (fils_aead_decrypt(fils_info->kek, fils_info->kek_len,
+			      session->selfMacAddr, session->bssId,
+			      fils_info->fils_nonce,
+			      fils_info->auth_info.fils_nonce,
+			      p_frame, data_len,
+			      fils_ies, fils_ies_len, fils_ies)){
+		pe_err("AEAD decryption fails");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Dump the output of AEAD decrypt */
+	lim_fils_data_dump("Plain text: ", fils_ies,
+			   fils_ies_len - AES_BLOCK_SIZE);
+
+	(*n_frame) -= AES_BLOCK_SIZE;
+	return status;
+}
+
+void lim_update_fils_rik(tpPESession pe_session,
+			 tSirRoamOffloadScanReq *req_buffer)
+{
+	struct pe_fils_session *pe_fils_info = pe_session->fils_info;
+	struct roam_fils_params *roam_fils_params =
+		&req_buffer->roam_fils_params;
+
+	/*
+	 * If it is first connection, LIM session entries will not be
+	 * set with FILS. However in RSO, CSR filled the RRK, realm
+	 * info and is_fils_connection to true in req_buffer, RIK
+	 * can be created with RRK and send all the FILS info to fw
+	 */
+	if ((!lim_is_fils_connection(pe_session) ||
+	     !pe_fils_info) && (req_buffer->is_fils_connection)) {
+		if (roam_fils_params->rrk_length > FILS_MAX_RRK_LENGTH) {
+			pe_debug("FILS rrk len(%d) max (%d)",
+				 roam_fils_params->rrk_length,
+				 FILS_MAX_RRK_LENGTH);
+			return;
+		}
+
+		lim_create_fils_rik(roam_fils_params->rrk,
+				    roam_fils_params->rrk_length,
+				    roam_fils_params->rik,
+				    &roam_fils_params->rik_length);
+		pe_debug("Fils created rik len %d",
+					roam_fils_params->rik_length);
+		return;
+	}
+
+	if (!pe_fils_info) {
+		pe_debug("No FILS info available in the session");
+		return;
+	}
+	if ((pe_fils_info->fils_rik_len > FILS_MAX_RIK_LENGTH) ||
+	    !pe_fils_info->fils_rik) {
+		pe_err("Fils rik len(%d) max %d", pe_fils_info->fils_rik_len,
+				FILS_MAX_RIK_LENGTH);
+		return;
+	}
+
+	roam_fils_params->rik_length = pe_fils_info->fils_rik_len;
+	qdf_mem_copy(roam_fils_params->rik, pe_fils_info->fils_rik,
+			roam_fils_params->rik_length);
+	pe_debug("fils rik len %d", roam_fils_params->rik_length);
+}
+#endif
diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c
new file mode 100644
index 0000000..0f80ed7
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_message_queue.c
@@ -0,0 +1,2299 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * This file lim ProcessMessageQueue.cc contains the code
+ * for processing LIM message Queue.
+ * Author:        Chandra Modumudi
+ * Date:          02/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "wni_api.h"
+#include "wma_types.h"
+
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include "sir_common.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+
+#include "lim_admit_control.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "sch_api.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "lim_send_messages.h"
+
+#include "rrm_api.h"
+
+#include "lim_ft.h"
+
+#include "qdf_types.h"
+#include "cds_packet.h"
+#include "qdf_mem.h"
+#include "wlan_policy_mgr_api.h"
+#include "nan_datapath.h"
+#include "wlan_reg_services_api.h"
+#include "lim_security_utils.h"
+#include "cds_ieee80211_common.h"
+#include <wlan_scan_ucfg_api.h>
+#include "wlan_mlme_public_struct.h"
+
+void lim_log_session_states(tpAniSirGlobal pMac);
+static void lim_process_normal_hdd_msg(tpAniSirGlobal mac_ctx,
+	struct scheduler_msg *msg, uint8_t rsp_reqd);
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * lim_process_sae_msg() - Process SAE message
+ * @mac: Global MAC pointer
+ * @body: Buffer pointer
+ *
+ * Return: None
+ */
+static void lim_process_sae_msg(tpAniSirGlobal mac, struct sir_sae_msg *body)
+{
+	struct sir_sae_msg *sae_msg = body;
+	tpPESession session;
+
+	if (!sae_msg) {
+		pe_err("SAE msg is NULL");
+		return;
+	}
+
+	session = pe_find_session_by_sme_session_id(mac,
+				sae_msg->session_id);
+	if (session == NULL) {
+		pe_err("SAE:Unable to find session");
+		return;
+	}
+
+	if (session->pePersona != QDF_STA_MODE) {
+		pe_err("SAE:Not supported in this mode %d",
+				session->pePersona);
+		return;
+	}
+
+	pe_debug("SAE:status %d limMlmState %d pePersona %d",
+		sae_msg->sae_status, session->limMlmState,
+		session->pePersona);
+	switch (session->limMlmState) {
+	case eLIM_MLM_WT_SAE_AUTH_STATE:
+		/* SAE authentication is completed. Restore from auth state */
+		if (tx_timer_running(&mac->lim.limTimers.sae_auth_timer))
+			lim_deactivate_and_change_timer(mac,
+				eLIM_AUTH_SAE_TIMER);
+		/* success */
+		if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS)
+			lim_restore_from_auth_state(mac,
+				eSIR_SME_SUCCESS,
+				eSIR_MAC_SUCCESS_STATUS,
+				session);
+		else
+			lim_restore_from_auth_state(mac,
+				eSIR_SME_AUTH_REFUSED,
+				eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				session);
+		break;
+	default:
+		/* SAE msg is received in unexpected state */
+		pe_err("received SAE msg in state %X",
+			session->limMlmState);
+		lim_print_mlm_state(mac, LOGE, session->limMlmState);
+		break;
+	}
+}
+#else
+static inline void lim_process_sae_msg(tpAniSirGlobal mac, void *body)
+{}
+#endif
+
+/**
+ * lim_process_dual_mac_cfg_resp() - Process set dual mac config response
+ * @mac: Global MAC pointer
+ * @body: Set dual mac config response in sir_dual_mac_config_resp format
+ *
+ * Process the set dual mac config response and post the message
+ * to SME to process this further and release the active
+ * command list
+ *
+ * Return: None
+ */
+static void lim_process_dual_mac_cfg_resp(tpAniSirGlobal mac, void *body)
+{
+	struct sir_dual_mac_config_resp *resp, *param;
+	uint32_t len, fail_resp = 0;
+	struct scheduler_msg msg = {0};
+
+	resp = (struct sir_dual_mac_config_resp *)body;
+	if (!resp) {
+		pe_err("Set dual mac cfg param is NULL");
+		fail_resp = 1;
+		/* Not returning here. If possible, let us proceed
+		 * and send fail response to SME
+		 */
+	}
+
+	len = sizeof(*param);
+
+	param = qdf_mem_malloc(len);
+	if (!param)
+		return;
+
+	if (fail_resp) {
+		pe_err("Send fail status to SME");
+		param->status = SET_HW_MODE_STATUS_ECANCELED;
+	} else {
+		param->status = resp->status;
+		/*
+		 * TODO: Update this HW mode info in any UMAC params, if needed
+		 */
+	}
+
+	msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP;
+	msg.bodyptr = param;
+	msg.bodyval = 0;
+	pe_debug("Send eWNI_SME_SET_DUAL_MAC_CFG_RESP to SME");
+	lim_sys_process_mmh_msg_api(mac, &msg, ePROT);
+	return;
+}
+
+/**
+ * lim_process_set_hw_mode_resp() - Process set HW mode response
+ * @mac: Global MAC pointer
+ * @body: Set HW mode response in sir_set_hw_mode_resp format
+ *
+ * Process the set HW mode response and post the message
+ * to SME to process this further and release the active
+ * command list
+ *
+ * Return: None
+ */
+static void lim_process_set_hw_mode_resp(tpAniSirGlobal mac, void *body)
+{
+	struct sir_set_hw_mode_resp *resp, *param;
+	uint32_t len, i, fail_resp = 0;
+	struct scheduler_msg msg = {0};
+
+	resp = (struct sir_set_hw_mode_resp *)body;
+	if (!resp) {
+		pe_err("Set HW mode param is NULL");
+		fail_resp = 1;
+		/* Not returning here. If possible, let us proceed
+		 * and send fail response to SME */
+	}
+
+	len = sizeof(*param);
+
+	param = qdf_mem_malloc(len);
+	if (!param)
+		return;
+
+	if (fail_resp) {
+		pe_err("Send fail status to SME");
+		param->status = SET_HW_MODE_STATUS_ECANCELED;
+		param->cfgd_hw_mode_index = 0;
+		param->num_vdev_mac_entries = 0;
+	} else {
+		param->status = resp->status;
+		param->cfgd_hw_mode_index = resp->cfgd_hw_mode_index;
+		param->num_vdev_mac_entries = resp->num_vdev_mac_entries;
+
+		for (i = 0; i < resp->num_vdev_mac_entries; i++) {
+			param->vdev_mac_map[i].vdev_id =
+				resp->vdev_mac_map[i].vdev_id;
+			param->vdev_mac_map[i].mac_id =
+				resp->vdev_mac_map[i].mac_id;
+		}
+		/*
+		 * TODO: Update this HW mode info in any UMAC params, if needed
+		 */
+	}
+
+	msg.type = eWNI_SME_SET_HW_MODE_RESP;
+	msg.bodyptr = param;
+	msg.bodyval = 0;
+	pe_err("Send eWNI_SME_SET_HW_MODE_RESP to SME");
+	lim_sys_process_mmh_msg_api(mac, &msg, ePROT);
+	return;
+}
+
+/**
+ * lim_process_antenna_mode_resp() - Process set antenna mode
+ * response
+ * @mac: Global MAC pointer
+ * @body: Set antenna mode response in sir_antenna_mode_resp
+ * format
+ *
+ * Process the set antenna mode response and post the message
+ * to SME to process this further and release the active
+ * command list
+ *
+ * Return: None
+ */
+static void lim_process_set_antenna_resp(tpAniSirGlobal mac, void *body)
+{
+	struct sir_antenna_mode_resp *resp, *param;
+	bool fail_resp = false;
+	struct scheduler_msg msg = {0};
+
+	resp = (struct sir_antenna_mode_resp *)body;
+	if (!resp) {
+		pe_err("Set antenna mode resp is NULL");
+		fail_resp = true;
+		/* Not returning here. If possible, let us proceed
+		 * and send fail response to SME
+		 */
+	}
+
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return;
+
+	if (fail_resp) {
+		pe_err("Send fail status to SME");
+		param->status = SET_ANTENNA_MODE_STATUS_ECANCELED;
+	} else {
+		param->status = resp->status;
+	}
+
+	msg.type = eWNI_SME_SET_ANTENNA_MODE_RESP;
+	msg.bodyptr = param;
+	msg.bodyval = 0;
+	pe_debug("Send eWNI_SME_SET_ANTENNA_MODE_RESP to SME");
+	lim_sys_process_mmh_msg_api(mac, &msg, ePROT);
+	return;
+}
+
+/**
+ * lim_process_set_default_scan_ie_request() - Process the Set default
+ * Scan IE request from HDD.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: Pointer to incoming data
+ *
+ * This function receives the default scan IEs and updates the ext cap IE
+ * (if present) with FTM capabilities and pass the Scan IEs to WMA.
+ *
+ * Return: None
+ */
+static void lim_process_set_default_scan_ie_request(tpAniSirGlobal mac_ctx,
+							uint32_t *msg_buf)
+{
+	struct hdd_default_scan_ie *set_ie_params;
+	struct vdev_ie_info *wma_ie_params;
+	uint8_t *local_ie_buf;
+	uint16_t local_ie_len;
+	struct scheduler_msg msg_q = {0};
+	QDF_STATUS ret_code;
+
+	if (!msg_buf) {
+		pe_err("msg_buf is NULL");
+		return;
+	}
+
+	set_ie_params = (struct hdd_default_scan_ie *) msg_buf;
+	local_ie_len = set_ie_params->ie_len;
+
+	local_ie_buf = qdf_mem_malloc(MAX_DEFAULT_SCAN_IE_LEN);
+	if (!local_ie_buf)
+		return;
+
+	if (lim_update_ext_cap_ie(mac_ctx,
+			(uint8_t *)set_ie_params->ie_data,
+			local_ie_buf, &local_ie_len)) {
+		pe_err("Update ext cap IEs fails");
+		goto scan_ie_send_fail;
+	}
+
+	wma_ie_params = qdf_mem_malloc(sizeof(*wma_ie_params) + local_ie_len);
+	if (!wma_ie_params)
+		goto scan_ie_send_fail;
+
+	wma_ie_params->vdev_id = set_ie_params->session_id;
+	wma_ie_params->ie_id = DEFAULT_SCAN_IE_ID;
+	wma_ie_params->length = local_ie_len;
+	wma_ie_params->data = (uint8_t *)(wma_ie_params)
+					+ sizeof(*wma_ie_params);
+	qdf_mem_copy(wma_ie_params->data, local_ie_buf, local_ie_len);
+
+	msg_q.type = WMA_SET_IE_INFO;
+	msg_q.bodyptr = wma_ie_params;
+	msg_q.bodyval = 0;
+	ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q);
+	if (QDF_STATUS_SUCCESS != ret_code) {
+		pe_err("fail to send WMA_SET_IE_INFO");
+		qdf_mem_free(wma_ie_params);
+	}
+scan_ie_send_fail:
+	qdf_mem_free(local_ie_buf);
+}
+
+/**
+ * lim_process_hw_mode_trans_ind() - Process set HW mode transition indication
+ * @mac: Global MAC pointer
+ * @body: Set HW mode response in sir_hw_mode_trans_ind format
+ *
+ * Process the set HW mode transition indication and post the message
+ * to SME to invoke the HDD callback
+ * command list
+ *
+ * Return: None
+ */
+static void lim_process_hw_mode_trans_ind(tpAniSirGlobal mac, void *body)
+{
+	struct sir_hw_mode_trans_ind *ind, *param;
+	uint32_t len, i;
+	struct scheduler_msg msg = {0};
+
+	ind = (struct sir_hw_mode_trans_ind *)body;
+	if (!ind) {
+		pe_err("Set HW mode trans ind param is NULL");
+		return;
+	}
+
+	len = sizeof(*param);
+
+	param = qdf_mem_malloc(len);
+	if (!param)
+		return;
+
+	param->old_hw_mode_index = ind->old_hw_mode_index;
+	param->new_hw_mode_index = ind->new_hw_mode_index;
+	param->num_vdev_mac_entries = ind->num_vdev_mac_entries;
+
+	for (i = 0; i < ind->num_vdev_mac_entries; i++) {
+		param->vdev_mac_map[i].vdev_id =
+			ind->vdev_mac_map[i].vdev_id;
+		param->vdev_mac_map[i].mac_id =
+			ind->vdev_mac_map[i].mac_id;
+	}
+
+	/* TODO: Update this HW mode info in any UMAC params, if needed */
+
+	msg.type = eWNI_SME_HW_MODE_TRANS_IND;
+	msg.bodyptr = param;
+	msg.bodyval = 0;
+	pe_err("Send eWNI_SME_HW_MODE_TRANS_IND to SME");
+	lim_sys_process_mmh_msg_api(mac, &msg, ePROT);
+	return;
+}
+
+/** -------------------------------------------------------------
+   \fn def_msg_decision
+   \brief The function decides whether to defer a message or not in limProcessMessage function
+   \param   tpAniSirGlobal pMac
+   \param       struct scheduler_msg  limMsg
+   \param       tSirMacTspecIE   *ppInfo
+   \return none
+   -------------------------------------------------------------*/
+
+static uint8_t def_msg_decision(tpAniSirGlobal mac_ctx,
+				struct scheduler_msg *lim_msg)
+{
+	uint8_t type, subtype;
+	QDF_STATUS status;
+	bool mgmt_pkt_defer = true;
+
+	/* this function should not changed */
+	if (mac_ctx->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) {
+		/* Defer processing this message */
+		if (lim_defer_msg(mac_ctx, lim_msg) != TX_SUCCESS) {
+			QDF_TRACE(QDF_MODULE_ID_PE, LOGE,
+					FL("Unable to Defer Msg"));
+			lim_log_session_states(mac_ctx);
+			lim_handle_defer_msg_error(mac_ctx, lim_msg);
+		}
+		return true;
+	}
+
+	/*
+	 * When defer is requested then defer all the messages except
+	 * HAL responses.
+	 */
+	if (!lim_is_system_in_scan_state(mac_ctx) &&
+	    !GET_LIM_PROCESS_DEFD_MESGS(mac_ctx)) {
+		if (lim_msg->type == SIR_BB_XPORT_MGMT_MSG) {
+			/*
+			 * Dont defer beacon and probe response
+			 * because it will fill the differ queue quickly
+			 */
+			status = lim_util_get_type_subtype(lim_msg->bodyptr,
+							   &type, &subtype);
+			if (QDF_IS_STATUS_SUCCESS(status) &&
+				(type == SIR_MAC_MGMT_FRAME) &&
+				((subtype == SIR_MAC_MGMT_BEACON) ||
+				 (subtype == SIR_MAC_MGMT_PROBE_RSP)))
+				mgmt_pkt_defer = false;
+		}
+
+		if ((lim_msg->type != WMA_ADD_BSS_RSP) &&
+		    (lim_msg->type != WMA_DELETE_BSS_RSP) &&
+		    (lim_msg->type != WMA_DELETE_BSS_HO_FAIL_RSP) &&
+		    (lim_msg->type != WMA_ADD_STA_RSP) &&
+		    (lim_msg->type != WMA_DELETE_STA_RSP) &&
+		    (lim_msg->type != WMA_SET_BSSKEY_RSP) &&
+		    (lim_msg->type != WMA_SET_STAKEY_RSP) &&
+		    (lim_msg->type != WMA_SET_STA_BCASTKEY_RSP) &&
+		    (lim_msg->type != WMA_AGGR_QOS_RSP) &&
+		    (lim_msg->type != WMA_SET_MIMOPS_RSP) &&
+		    (lim_msg->type != WMA_SWITCH_CHANNEL_RSP) &&
+		    (lim_msg->type != WMA_P2P_NOA_ATTR_IND) &&
+		    (lim_msg->type != WMA_ADD_TS_RSP) &&
+		    /*
+		     * LIM won't process any defer queue commands if gLimAddtsSent is
+		     * set to TRUE. gLimAddtsSent will be set TRUE to while sending
+		     * ADDTS REQ. Say, when deferring is enabled, if
+		     * SIR_LIM_ADDTS_RSP_TIMEOUT is posted (because of not receiving ADDTS
+		     * RSP) then this command will be added to defer queue and as
+		     * gLimAddtsSent is set TRUE LIM will never process any commands from
+		     * defer queue, including SIR_LIM_ADDTS_RSP_TIMEOUT. Hence allowing
+		     * SIR_LIM_ADDTS_RSP_TIMEOUT command to be processed with deferring
+		     * enabled, so that this will be processed immediately and sets
+		     * gLimAddtsSent to FALSE.
+		     */
+		    (lim_msg->type != SIR_LIM_ADDTS_RSP_TIMEOUT) &&
+		    /* Allow processing of RX frames while awaiting reception
+		     * of ADD TS response over the air. This logic particularly
+		     * handles the case when host sends ADD BA request to FW
+		     * after ADD TS request is sent over the air and
+		     * ADD TS response received over the air */
+		    !(lim_msg->type == SIR_BB_XPORT_MGMT_MSG &&
+		    mac_ctx->lim.gLimAddtsSent) &&
+		    (mgmt_pkt_defer)) {
+			pe_debug("Defer the current message %s , gLimProcessDefdMsgs is false and system is not in scan/learn mode",
+				 lim_msg_str(lim_msg->type));
+			/* Defer processing this message */
+			if (lim_defer_msg(mac_ctx, lim_msg) != TX_SUCCESS) {
+				QDF_TRACE(QDF_MODULE_ID_PE, LOGE,
+					  FL("Unable to Defer Msg"));
+				lim_log_session_states(mac_ctx);
+				lim_handle_defer_msg_error(mac_ctx, lim_msg);
+			}
+			return true;
+		}
+	}
+	return false;
+}
+
+#ifdef FEATURE_WLAN_EXTSCAN
+static void
+__lim_pno_match_fwd_bcn_probepsp(tpAniSirGlobal pmac, uint8_t *rx_pkt_info,
+				tSirProbeRespBeacon *frame, uint32_t ie_len,
+				uint32_t msg_type)
+{
+	struct pno_match_found  *result;
+	uint8_t                 *body;
+	struct scheduler_msg    mmh_msg = {0};
+	tpSirMacMgmtHdr         hdr;
+	uint32_t num_results = 1, len, i;
+
+	/* Upon receiving every matched beacon, bss info is forwarded to the
+	 * the upper layer, hence num_results is set to 1 */
+	len = sizeof(*result) + (num_results * sizeof(tSirWifiScanResult)) +
+		ie_len;
+
+	result = qdf_mem_malloc(len);
+	if (!result)
+		return;
+
+	hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+
+	/* Received frame does not have request id, hence set 0 */
+	result->request_id = 0;
+	result->more_data = 0;
+	result->num_results = num_results;
+
+	for (i = 0; i < result->num_results; i++) {
+		result->ap[i].ts = qdf_mc_timer_get_system_time();
+		result->ap[i].beaconPeriod = frame->beaconInterval;
+		result->ap[i].capability =
+			lim_get_u16((uint8_t *) &frame->capabilityInfo);
+		result->ap[i].channel = WMA_GET_RX_CH(rx_pkt_info);
+		result->ap[i].rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
+		result->ap[i].rtt = 0;
+		result->ap[i].rtt_sd = 0;
+		result->ap[i].ieLength = ie_len;
+		qdf_mem_copy((uint8_t *) &result->ap[i].ssid[0],
+			(uint8_t *) frame->ssId.ssId, frame->ssId.length);
+		result->ap[i].ssid[frame->ssId.length] = '\0';
+		qdf_mem_copy((uint8_t *) &result->ap[i].bssid,
+				(uint8_t *) hdr->bssId,
+				sizeof(tSirMacAddr));
+		/* Copy IE fields */
+		qdf_mem_copy((uint8_t *) &result->ap[i].ieData,
+				body + SIR_MAC_B_PR_SSID_OFFSET, ie_len);
+	}
+
+	mmh_msg.type = msg_type;
+	mmh_msg.bodyptr = result;
+	mmh_msg.bodyval = 0;
+	lim_sys_process_mmh_msg_api(pmac, &mmh_msg, ePROT);
+}
+
+
+static void
+__lim_ext_scan_forward_bcn_probe_rsp(tpAniSirGlobal pmac, uint8_t *rx_pkt_info,
+					tSirProbeRespBeacon *frame,
+					uint32_t ie_len,
+					uint32_t msg_type)
+{
+	tpSirWifiFullScanResultEvent result;
+	uint8_t                     *body;
+	struct scheduler_msg         mmh_msg = {0};
+	tpSirMacMgmtHdr              hdr;
+	uint32_t frame_len;
+	tSirBssDescription *bssdescr;
+
+	result = qdf_mem_malloc(sizeof(*result) + ie_len);
+	if (!result)
+		return;
+
+	hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+
+	/* Received frame does not have request id, hence set 0 */
+	result->requestId = 0;
+
+	result->moreData = 0;
+	result->ap.ts = qdf_mc_timer_get_system_time();
+	result->ap.beaconPeriod = frame->beaconInterval;
+	result->ap.capability =
+			lim_get_u16((uint8_t *) &frame->capabilityInfo);
+	result->ap.channel = WMA_GET_RX_CH(rx_pkt_info);
+	result->ap.rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
+	result->ap.rtt = 0;
+	result->ap.rtt_sd = 0;
+	result->ap.ieLength = ie_len;
+
+	qdf_mem_copy((uint8_t *) &result->ap.ssid[0],
+			(uint8_t *) frame->ssId.ssId, frame->ssId.length);
+	result->ap.ssid[frame->ssId.length] = '\0';
+	qdf_mem_copy((uint8_t *) &result->ap.bssid.bytes,
+			(uint8_t *) hdr->bssId,
+			QDF_MAC_ADDR_SIZE);
+	/* Copy IE fields */
+	qdf_mem_copy((uint8_t *) &result->ap.ieData,
+			body + SIR_MAC_B_PR_SSID_OFFSET, ie_len);
+
+	frame_len = sizeof(*bssdescr) + ie_len - sizeof(bssdescr->ieFields[1]);
+	bssdescr = qdf_mem_malloc(frame_len);
+
+	if (!bssdescr)
+		return;
+
+	qdf_mem_zero(bssdescr, frame_len);
+
+	lim_collect_bss_description(pmac, bssdescr, frame, rx_pkt_info, false);
+
+	qdf_mem_free(bssdescr);
+
+	mmh_msg.type = msg_type;
+	mmh_msg.bodyptr = result;
+	mmh_msg.bodyval = 0;
+	lim_sys_process_mmh_msg_api(pmac, &mmh_msg, ePROT);
+}
+
+static void
+__lim_process_ext_scan_beacon_probe_rsp(tpAniSirGlobal pmac,
+					uint8_t *rx_pkt_info,
+					uint8_t sub_type)
+{
+	tSirProbeRespBeacon  *frame;
+	uint8_t              *body;
+	uint32_t             frm_len;
+	QDF_STATUS        status;
+
+	frm_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+	if (frm_len <= SIR_MAC_B_PR_SSID_OFFSET) {
+		pe_err("RX packet has invalid length %d", frm_len);
+		return;
+	}
+
+	frame = qdf_mem_malloc(sizeof(*frame));
+	if (!frame)
+		return;
+
+	if (sub_type == SIR_MAC_MGMT_BEACON) {
+		pe_debug("Beacon due to ExtScan/epno");
+		status = sir_convert_beacon_frame2_struct(pmac,
+						(uint8_t *)rx_pkt_info,
+						frame);
+	} else if (sub_type == SIR_MAC_MGMT_PROBE_RSP) {
+		pe_debug("Probe Rsp due to ExtScan/epno");
+		body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+		status = sir_convert_probe_frame2_struct(pmac, body,
+							frm_len, frame);
+	} else {
+		qdf_mem_free(frame);
+		return;
+	}
+
+	if (status != QDF_STATUS_SUCCESS) {
+		pe_err("Frame parsing failed");
+		qdf_mem_free(frame);
+		return;
+	}
+
+	if (WMA_IS_EXTSCAN_SCAN_SRC(rx_pkt_info))
+		__lim_ext_scan_forward_bcn_probe_rsp(pmac, rx_pkt_info, frame,
+					(frm_len - SIR_MAC_B_PR_SSID_OFFSET),
+					eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND);
+
+	if (WMA_IS_EPNO_SCAN_SRC(rx_pkt_info))
+		__lim_pno_match_fwd_bcn_probepsp(pmac, rx_pkt_info, frame,
+					(frm_len - SIR_MAC_B_PR_SSID_OFFSET),
+					eWNI_SME_EPNO_NETWORK_FOUND_IND);
+
+	qdf_mem_free(frame);
+}
+#endif
+
+/*
+ * Beacon Handling Cases:
+ * during scanning, when no session is active:
+ *    handled by lim_handle_frames_in_scan_state before __lim_handle_beacon call is invoked.
+ * during scanning, when any session is active, but beacon/Pr does not belong to that session, psessionEntry will be null.
+ *    handled by lim_handle_frames_in_scan_state before __lim_handle_beacon call is invoked.
+ * during scanning, when any session is active, and beacon/Pr belongs to one of the session, psessionEntry will not be null.
+ *    handled by lim_handle_frames_in_scan_state before __lim_handle_beacon call is invoked.
+ * Not scanning, no session:
+ *    there should not be any beacon coming, if coming, should be dropped.
+ * Not Scanning,
+ */
+static void
+__lim_handle_beacon(tpAniSirGlobal pMac, struct scheduler_msg *pMsg,
+		    tpPESession psessionEntry)
+{
+	uint8_t *pRxPacketInfo;
+
+	lim_get_b_dfrom_rx_packet(pMac, pMsg->bodyptr,
+				  (uint32_t **) &pRxPacketInfo);
+
+	/* This function should not be called if beacon is received in scan state. */
+	/* So not doing any checks for the global state. */
+
+	if (psessionEntry == NULL) {
+		sch_beacon_process(pMac, pRxPacketInfo, NULL);
+	} else if ((psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE) ||
+		   (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE)) {
+		sch_beacon_process(pMac, pRxPacketInfo, psessionEntry);
+	} else
+		lim_process_beacon_frame(pMac, pRxPacketInfo, psessionEntry);
+
+	return;
+}
+
+/*
+ * lim_fill_sap_bcn_pkt_meta(): Fills essential fields in Rx Pkt Meta
+ * @scan_entry: pointer to the scan cache entry of the beacon
+ * @rx_pkt: pointer to the cds pkt allocated
+ *
+ * This API fills only the essential parameters in the Rx Pkt Meta which are
+ * required while converting the beacon frame to struct and while handling
+ * the beacon for implementation of SAP protection mechanisms.
+ *
+ * Return: None
+ */
+static void lim_fill_sap_bcn_pkt_meta(struct scan_cache_entry *scan_entry,
+					cds_pkt_t *rx_pkt)
+{
+	rx_pkt->pkt_meta.channel = scan_entry->channel.chan_idx;
+
+	rx_pkt->pkt_meta.mpdu_hdr_len = sizeof(struct ieee80211_frame);
+	rx_pkt->pkt_meta.mpdu_len = scan_entry->raw_frame.len;
+	rx_pkt->pkt_meta.mpdu_data_len = rx_pkt->pkt_meta.mpdu_len -
+					rx_pkt->pkt_meta.mpdu_hdr_len;
+
+	rx_pkt->pkt_meta.mpdu_hdr_ptr = scan_entry->raw_frame.ptr;
+	rx_pkt->pkt_meta.mpdu_data_ptr = rx_pkt->pkt_meta.mpdu_hdr_ptr +
+					rx_pkt->pkt_meta.mpdu_hdr_len;
+
+	/*
+	 * The scan_entry->raw_frame contains the qdf_nbuf->data from the SKB
+	 * of the beacon. We set the rx_pkt->pkt_meta.mpdu_hdr_ptr to point
+	 * to this memory directly. However we do not have the pointer to
+	 * the SKB itself here which is usually is pointed by rx_pkt->pkt_buf.
+	 * Also, we always get the pkt data using WMA_GET_RX_MPDU_DATA and
+	 * dont actually use the pkt_buf. So setting this to NULL.
+	 */
+	rx_pkt->pkt_buf = NULL;
+}
+
+/*
+ * lim_allocate_and_get_bcn() - Allocate and get the bcn frame pkt and structure
+ * @mac_ctx: pointer to global mac_ctx
+ * @pkt: pointer to the pkt to be allocated
+ * @rx_pkt_info: pointer to the allocated pkt meta
+ * @bcn: pointer to the beacon struct
+ * @scan_entry: pointer to the scan cache entry from scan module
+ *
+ * Allocates a cds_pkt for beacon frame in scan cache entry,
+ * fills the essential pkt_meta elements and converts the
+ * pkt to beacon strcut.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS lim_allocate_and_get_bcn(
+				tpAniSirGlobal mac_ctx,
+				cds_pkt_t **pkt,
+				uint8_t **rx_pkt_info,
+				tSchBeaconStruct **bcn,
+				struct scan_cache_entry *scan_entry)
+{
+	QDF_STATUS status;
+	uint8_t *rx_pkt_info_l = NULL;
+	tSchBeaconStruct *bcn_l = NULL;
+	cds_pkt_t *pkt_l = NULL;
+
+	pkt_l = qdf_mem_malloc(sizeof(cds_pkt_t));
+	if (!pkt_l)
+		return QDF_STATUS_E_FAILURE;
+
+	status = wma_ds_peek_rx_packet_info(
+		pkt_l, (void *)&rx_pkt_info_l, false);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		pe_err("Failed to get Rx Pkt meta");
+		goto free;
+	}
+
+	bcn_l = qdf_mem_malloc(sizeof(tSchBeaconStruct));
+	if (!bcn_l)
+		goto free;
+
+	lim_fill_sap_bcn_pkt_meta(scan_entry, pkt_l);
+
+	/* Convert the beacon frame into a structure */
+	if (sir_convert_beacon_frame2_struct(mac_ctx,
+	    (uint8_t *)rx_pkt_info_l,
+	    bcn_l) != QDF_STATUS_SUCCESS) {
+		pe_err("beacon parsing failed");
+		goto free;
+	}
+
+	*pkt = pkt_l;
+	*bcn = bcn_l;
+	*rx_pkt_info = rx_pkt_info_l;
+
+	return QDF_STATUS_SUCCESS;
+
+free:
+	if (pkt_l) {
+		qdf_mem_free(pkt_l);
+		pkt_l = NULL;
+	}
+
+	if (bcn_l) {
+		qdf_mem_free(bcn_l);
+		bcn_l = NULL;
+	}
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+void lim_handle_sap_beacon(struct wlan_objmgr_pdev *pdev,
+				struct scan_cache_entry *scan_entry)
+{
+	tpAniSirGlobal mac_ctx;
+	cds_pkt_t *pkt = NULL;
+	tSchBeaconStruct *bcn = NULL;
+	struct mgmt_beacon_probe_filter *filter;
+	QDF_STATUS status;
+	uint8_t *rx_pkt_info = NULL;
+	int session_id;
+
+	if (!scan_entry) {
+		pe_err("scan_entry is NULL");
+		return;
+	}
+
+	if (scan_entry->frm_subtype != MGMT_SUBTYPE_BEACON)
+		return;
+
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac_ctx) {
+		pe_err("Failed to get mac_ctx");
+		return;
+	}
+
+	filter = &mac_ctx->bcn_filter;
+
+	if (!filter->num_sap_sessions) {
+		return;
+	}
+	for (session_id = 0; session_id < mac_ctx->lim.maxBssId; session_id++) {
+		if (filter->sap_channel[session_id] &&
+		    (filter->sap_channel[session_id] ==
+		    scan_entry->channel.chan_idx)) {
+			if (!pkt) {
+				status = lim_allocate_and_get_bcn(
+					mac_ctx, &pkt, &rx_pkt_info,
+					&bcn, scan_entry);
+				if (!QDF_IS_STATUS_SUCCESS(status)) {
+					pe_debug("lim_allocate_and_get_bcn fail!");
+					return;
+				}
+			}
+			sch_beacon_process_for_ap(mac_ctx, session_id,
+						  rx_pkt_info, bcn);
+		}
+	}
+
+	/*
+	 * Free only the pkt memory we allocated and not the pkt->pkt_buf.
+	 * The actual SKB buffer is freed in the scan module from where
+	 * this API is invoked via callback
+	 */
+	if (bcn)
+		qdf_mem_free(bcn);
+	if (pkt)
+		qdf_mem_free(pkt);
+}
+
+/**
+ * lim_defer_msg()
+ *
+ ***FUNCTION:
+ * This function is called to defer the messages received
+ * during Learn mode
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  pMsg of type struct scheduler_msg - Pointer to the message structure
+ * @return None
+ */
+
+uint32_t lim_defer_msg(tpAniSirGlobal pMac, struct scheduler_msg *pMsg)
+{
+	uint32_t retCode = TX_SUCCESS;
+
+	retCode = lim_write_deferred_msg_q(pMac, pMsg);
+
+	if (retCode == TX_SUCCESS) {
+		MTRACE(mac_trace_msg_rx
+			(pMac, NO_SESSION,
+			LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DEFERRED)));
+	} else {
+		pe_err("Dropped lim message (0x%X) Message %s", pMsg->type, lim_msg_str(pMsg->type));
+		MTRACE(mac_trace_msg_rx
+			(pMac, NO_SESSION,
+			LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DROPPED)));
+	}
+
+	return retCode;
+} /*** end lim_defer_msg() ***/
+
+/**
+ * lim_handle_unknown_a2_index_frames() - This function handles Unknown Unicast
+ *                                        (A2 Index) packets
+ * @mac_ctx:          Pointer to the Global Mac Context.
+ * @rx_pkt_buffer:    Pointer to the packet Buffer descriptor.
+ * @session_entry:    Pointer to the PE Session Entry.
+ *
+ * This routine will handle public action frames.
+ *
+ * Return:      None.
+ */
+static void lim_handle_unknown_a2_index_frames(tpAniSirGlobal mac_ctx,
+	void *rx_pkt_buffer, tpPESession session_entry)
+{
+#ifdef FEATURE_WLAN_TDLS
+	tpSirMacDataHdr3a mac_hdr;
+#endif
+	if (LIM_IS_P2P_DEVICE_ROLE(session_entry))
+		lim_process_action_frame_no_session(mac_ctx,
+			(uint8_t *) rx_pkt_buffer);
+#ifdef FEATURE_WLAN_TDLS
+	mac_hdr = WMA_GET_RX_MPDUHEADER3A(rx_pkt_buffer);
+
+	if (lim_is_group_addr(mac_hdr->addr2)) {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			FL("Ignoring A2 Invalid Packet received for MC/BC:"));
+		lim_print_mac_addr(mac_ctx, mac_hdr->addr2, LOGD);
+		return;
+	}
+	QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			FL("type=0x%x, subtype=0x%x"),
+		mac_hdr->fc.type, mac_hdr->fc.subType);
+	/* Currently only following type and subtype are handled.
+	 * If there are more combinations, then add switch-case
+	 * statements.
+	 */
+	if (LIM_IS_STA_ROLE(session_entry) &&
+		(mac_hdr->fc.type == SIR_MAC_MGMT_FRAME) &&
+		(mac_hdr->fc.subType == SIR_MAC_MGMT_ACTION))
+		lim_process_action_frame(mac_ctx, rx_pkt_buffer, session_entry);
+#endif
+	return;
+}
+
+/**
+ * lim_check_mgmt_registered_frames() - This function handles registered
+ *                                      management frames.
+ *
+ * @mac_ctx:          Pointer to the Global Mac Context.
+ * @buff_desc:        Pointer to the packet Buffer descriptor.
+ * @session_entry:    Pointer to the PE Session Entry.
+ *
+ * This function is called to process to check if received frame match with
+ * any of the registered frame from HDD. If yes pass this frame to SME.
+ *
+ * Return:      True or False for Match or Mismatch respectively.
+ */
+static bool
+lim_check_mgmt_registered_frames(tpAniSirGlobal mac_ctx, uint8_t *buff_desc,
+				 tpPESession session_entry)
+{
+	tSirMacFrameCtl fc;
+	tpSirMacMgmtHdr hdr;
+	uint8_t *body;
+	struct mgmt_frm_reg_info *mgmt_frame = NULL;
+	struct mgmt_frm_reg_info *next_frm = NULL;
+	uint16_t frm_type;
+	uint16_t frm_len;
+	uint8_t type, sub_type;
+	bool match = false;
+	QDF_STATUS qdf_status;
+
+	hdr = WMA_GET_RX_MAC_HEADER(buff_desc);
+	fc = hdr->fc;
+	frm_type = (fc.type << 2) | (fc.subType << 4);
+	body = WMA_GET_RX_MPDU_DATA(buff_desc);
+	frm_len = WMA_GET_RX_PAYLOAD_LEN(buff_desc);
+
+	qdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
+	qdf_list_peek_front(&mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
+			    (qdf_list_node_t **) &mgmt_frame);
+	qdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
+
+	while (mgmt_frame != NULL) {
+		type = (mgmt_frame->frameType >> 2) & 0x03;
+		sub_type = (mgmt_frame->frameType >> 4) & 0x0f;
+		if ((type == SIR_MAC_MGMT_FRAME)
+		    && (fc.type == SIR_MAC_MGMT_FRAME)
+		    && (sub_type == SIR_MAC_MGMT_RESERVED15)) {
+			QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				FL
+				("rcvd frm match for SIR_MAC_MGMT_RESERVED15"));
+			match = true;
+			break;
+		}
+		if (mgmt_frame->frameType == frm_type) {
+			if (mgmt_frame->matchLen <= 0) {
+				match = true;
+				break;
+			}
+			if (mgmt_frame->matchLen <= frm_len &&
+				(!qdf_mem_cmp(mgmt_frame->matchData, body,
+				mgmt_frame->matchLen))) {
+				/* found match! */
+				match = true;
+				break;
+			}
+		}
+
+		qdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
+		qdf_status =
+			qdf_list_peek_next(
+			&mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
+			(qdf_list_node_t *) mgmt_frame,
+			(qdf_list_node_t **) &next_frm);
+		qdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
+		mgmt_frame = next_frm;
+		next_frm = NULL;
+	}
+
+	if (match) {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			FL("rcvd frame match with registered frame params"));
+		/* Indicate this to SME */
+		lim_send_sme_mgmt_frame_ind(mac_ctx, hdr->fc.subType,
+			(uint8_t *) hdr,
+			WMA_GET_RX_PAYLOAD_LEN(buff_desc) +
+			sizeof(tSirMacMgmtHdr), mgmt_frame->sessionId,
+			WMA_GET_RX_CH(buff_desc), session_entry,
+			WMA_GET_RX_RSSI_NORMALIZED(buff_desc));
+
+		if ((type == SIR_MAC_MGMT_FRAME)
+		    && (fc.type == SIR_MAC_MGMT_FRAME)
+		    && (sub_type == SIR_MAC_MGMT_RESERVED15))
+			/* These packets needs to be processed by PE/SME
+			 * as well as HDD.If it returns true here,
+			 * the packet is forwarded to HDD only.
+			 */
+			match = false;
+	}
+
+	return match;
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * lim_is_mgmt_frame_loggable() - to log non-excessive mgmt frames
+ * @type: type of frames i.e. mgmt, control, data
+ * @subtype: subtype of frames i.e. beacon, probe rsp, probe req and etc
+ *
+ * This API tells if given mgmt frame is expected to come excessive in
+ * amount or not.
+ *
+ * Return: true if mgmt is expected to come not that often, so makes it
+ *         loggable. false if mgmt is expected to come too often, so makes
+ *         it not loggable
+ */
+static bool
+lim_is_mgmt_frame_loggable(uint8_t type, uint8_t subtype)
+{
+	if (type != SIR_MAC_MGMT_FRAME)
+		return false;
+
+	switch (subtype) {
+	case SIR_MAC_MGMT_BEACON:
+	case SIR_MAC_MGMT_PROBE_REQ:
+	case SIR_MAC_MGMT_PROBE_RSP:
+		return false;
+	default:
+		return true;
+	}
+}
+#else
+static bool
+lim_is_mgmt_frame_loggable(uint8_t type, uint8_t subtype)
+{
+	return false;
+}
+#endif
+
+/**
+ * lim_handle80211_frames()
+ *
+ ***FUNCTION:
+ * This function is called to process 802.11 frames
+ * received by LIM.
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  pMsg of type struct scheduler_msg - Pointer to the message structure
+ * @return None
+ */
+
+static void
+lim_handle80211_frames(tpAniSirGlobal pMac, struct scheduler_msg *limMsg,
+		       uint8_t *pDeferMsg)
+{
+	uint8_t *pRxPacketInfo = NULL;
+	tSirMacFrameCtl fc;
+	tpSirMacMgmtHdr pHdr = NULL;
+	tpPESession psessionEntry = NULL;
+	uint8_t sessionId;
+	bool isFrmFt = false;
+	uint8_t channel;
+	bool is_hw_sbs_capable = false;
+
+	*pDeferMsg = false;
+	lim_get_b_dfrom_rx_packet(pMac, limMsg->bodyptr,
+				  (uint32_t **) &pRxPacketInfo);
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	isFrmFt = WMA_GET_RX_FT_DONE(pRxPacketInfo);
+	channel = WMA_GET_RX_CH(pRxPacketInfo);
+	fc = pHdr->fc;
+
+	is_hw_sbs_capable =
+		policy_mgr_is_hw_sbs_capable(pMac->psoc);
+	if (IS_5G_CH(channel) &&
+	   (!is_hw_sbs_capable ||
+	   (is_hw_sbs_capable && wlan_reg_is_dfs_ch(pMac->pdev, channel))) &&
+	    pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+		psessionEntry = pe_find_session_by_bssid(pMac,
+					pHdr->bssId, &sessionId);
+		if (psessionEntry &&
+		    (QDF_SAP_MODE == psessionEntry->pePersona)) {
+			pe_debug("CAC timer running - drop the frame");
+			goto end;
+		}
+	}
+
+#ifdef WLAN_DUMP_MGMTFRAMES
+	pe_debug("ProtVersion %d, Type %d, Subtype %d rateIndex=%d",
+		fc.protVer, fc.type, fc.subType,
+		WMA_GET_RX_MAC_RATE_IDX(pRxPacketInfo));
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, pHdr,
+			   WMA_GET_RX_MPDU_HEADER_LEN(pRxPacketInfo));
+#endif
+	if (pMac->mlme_cfg->gen.debug_packet_log & 0x1) {
+		if ((fc.type == SIR_MAC_MGMT_FRAME) &&
+		    (fc.subType != SIR_MAC_MGMT_PROBE_REQ) &&
+		    (fc.subType != SIR_MAC_MGMT_PROBE_RSP) &&
+		    (fc.subType != SIR_MAC_MGMT_BEACON)) {
+			pe_debug("RX MGMT - Type %hu, SubType %hu, seq num[%d]",
+				   fc.type,
+				   fc.subType,
+				   ((pHdr->seqControl.seqNumHi <<
+				   HIGH_SEQ_NUM_OFFSET) |
+				   pHdr->seqControl.seqNumLo));
+		}
+	}
+#ifdef FEATURE_WLAN_EXTSCAN
+	if (WMA_IS_EXTSCAN_SCAN_SRC(pRxPacketInfo) ||
+		WMA_IS_EPNO_SCAN_SRC(pRxPacketInfo)) {
+		if (fc.subType == SIR_MAC_MGMT_BEACON ||
+		    fc.subType == SIR_MAC_MGMT_PROBE_RSP) {
+			__lim_process_ext_scan_beacon_probe_rsp(pMac,
+								pRxPacketInfo,
+								fc.subType);
+		} else {
+			pe_err("Wrong frameType %d, Subtype %d for %d",
+				fc.type, fc.subType,
+				WMA_GET_SCAN_SRC(pRxPacketInfo));
+		}
+		goto end;
+	}
+#endif
+	/* Added For BT-AMP Support */
+	psessionEntry = pe_find_session_by_bssid(pMac, pHdr->bssId,
+						 &sessionId);
+	if (psessionEntry == NULL) {
+		if (fc.subType == SIR_MAC_MGMT_AUTH) {
+			pe_debug("ProtVersion %d, Type %d, Subtype %d rateIndex=%d",
+				fc.protVer, fc.type, fc.subType,
+				WMA_GET_RX_MAC_RATE_IDX(pRxPacketInfo));
+			lim_print_mac_addr(pMac, pHdr->bssId, LOGD);
+			if (lim_process_auth_frame_no_session
+				    (pMac, pRxPacketInfo,
+				    limMsg->bodyptr) == QDF_STATUS_SUCCESS) {
+				goto end;
+			}
+		}
+		/* Public action frame can be received from non-assoc stations*/
+		if ((fc.subType != SIR_MAC_MGMT_PROBE_RSP) &&
+		    (fc.subType != SIR_MAC_MGMT_BEACON) &&
+		    (fc.subType != SIR_MAC_MGMT_PROBE_REQ)
+		    && (fc.subType != SIR_MAC_MGMT_ACTION)) {
+
+			psessionEntry = pe_find_session_by_peer_sta(pMac,
+						pHdr->sa, &sessionId);
+			if (psessionEntry == NULL) {
+				pe_debug("session does not exist for bssId");
+				lim_print_mac_addr(pMac, pHdr->sa, LOGD);
+				goto end;
+			} else {
+				pe_debug("SessionId:%d exists for given Bssid",
+					psessionEntry->peSessionId);
+			}
+		}
+		/*  For p2p resp frames search for valid session with DA as */
+		/*  BSSID will be SA and session will be present with DA only */
+		if (fc.subType == SIR_MAC_MGMT_ACTION) {
+			psessionEntry =
+				pe_find_session_by_bssid(pMac, pHdr->da, &sessionId);
+		}
+	}
+
+	/* Check if frame is registered by HDD */
+	if (lim_check_mgmt_registered_frames(pMac, pRxPacketInfo, psessionEntry)) {
+		pe_debug("Received frame is passed to SME");
+		goto end;
+	}
+
+	if (fc.protVer != SIR_MAC_PROTOCOL_VERSION) {   /* Received Frame with non-zero Protocol Version */
+		pe_err("Unexpected frame with protVersion %d received",
+			fc.protVer);
+		lim_pkt_free(pMac, TXRX_FRM_802_11_MGMT, pRxPacketInfo,
+			     (void *)limMsg->bodyptr);
+#ifdef WLAN_DEBUG
+		pMac->lim.numProtErr++;
+#endif
+		goto end;
+	}
+
+/* Chance of crashing : to be done BT-AMP ........happens when broadcast probe req is received */
+
+#ifdef WLAN_DEBUG
+	pMac->lim.numMAC[fc.type][fc.subType]++;
+#endif
+
+	switch (fc.type) {
+	case SIR_MAC_MGMT_FRAME:
+	{
+		/* Received Management frame */
+		switch (fc.subType) {
+		case SIR_MAC_MGMT_ASSOC_REQ:
+			/* Make sure the role supports Association */
+			if (LIM_IS_AP_ROLE(psessionEntry))
+				lim_process_assoc_req_frame(pMac,
+							    pRxPacketInfo,
+							    LIM_ASSOC,
+							    psessionEntry);
+			else {
+				pe_err("unexpected message received %X",
+					limMsg->type);
+				lim_print_msg_name(pMac, LOGE,
+						   limMsg->type);
+			}
+			break;
+
+		case SIR_MAC_MGMT_ASSOC_RSP:
+			lim_process_assoc_rsp_frame(pMac, pRxPacketInfo,
+						    LIM_ASSOC,
+						    psessionEntry);
+			break;
+
+		case SIR_MAC_MGMT_REASSOC_REQ:
+			/* Make sure the role supports Reassociation */
+			if (LIM_IS_AP_ROLE(psessionEntry)) {
+				lim_process_assoc_req_frame(pMac,
+							    pRxPacketInfo,
+							    LIM_REASSOC,
+							    psessionEntry);
+			} else {
+				pe_err("unexpected message received %X",
+					limMsg->type);
+				lim_print_msg_name(pMac, LOGE,
+					limMsg->type);
+			}
+			break;
+
+		case SIR_MAC_MGMT_REASSOC_RSP:
+			lim_process_assoc_rsp_frame(pMac, pRxPacketInfo,
+						    LIM_REASSOC,
+						    psessionEntry);
+			break;
+
+		case SIR_MAC_MGMT_PROBE_REQ:
+			lim_process_probe_req_frame_multiple_bss(pMac,
+								 pRxPacketInfo,
+								 psessionEntry);
+			break;
+
+		case SIR_MAC_MGMT_PROBE_RSP:
+			if (psessionEntry)
+				lim_process_probe_rsp_frame(pMac,
+							    pRxPacketInfo,
+							    psessionEntry);
+			break;
+
+		case SIR_MAC_MGMT_BEACON:
+			__lim_handle_beacon(pMac, limMsg, psessionEntry);
+			break;
+
+		case SIR_MAC_MGMT_DISASSOC:
+			lim_process_disassoc_frame(pMac, pRxPacketInfo,
+						   psessionEntry);
+			break;
+
+		case SIR_MAC_MGMT_AUTH:
+			lim_process_auth_frame(pMac, pRxPacketInfo,
+					       psessionEntry);
+			break;
+
+		case SIR_MAC_MGMT_DEAUTH:
+			lim_process_deauth_frame(pMac, pRxPacketInfo,
+						 psessionEntry);
+			break;
+
+		case SIR_MAC_MGMT_ACTION:
+			if (psessionEntry == NULL)
+				lim_process_action_frame_no_session(pMac,
+								    pRxPacketInfo);
+			else {
+				if (WMA_GET_RX_UNKNOWN_UCAST
+					    (pRxPacketInfo))
+					lim_handle_unknown_a2_index_frames
+						(pMac, pRxPacketInfo,
+						psessionEntry);
+				else
+					lim_process_action_frame(pMac,
+								 pRxPacketInfo,
+								 psessionEntry);
+			}
+			break;
+		default:
+			/* Received Management frame of 'reserved' subtype */
+			break;
+		} /* switch (fc.subType) */
+
+	}
+	break;
+	case SIR_MAC_DATA_FRAME:
+	{
+	}
+	break;
+	default:
+		/* Received frame of type 'reserved' */
+		break;
+
+	} /* switch (fc.type) */
+	if (lim_is_mgmt_frame_loggable(fc.type, fc.subType))
+		lim_diag_mgmt_rx_event_report(pMac, pHdr,
+					      psessionEntry,
+					      QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+end:
+	lim_pkt_free(pMac, TXRX_FRM_802_11_MGMT, pRxPacketInfo,
+		     (void *)limMsg->bodyptr);
+	return;
+} /*** end lim_handle80211_frames() ***/
+
+void lim_process_abort_scan_ind(tpAniSirGlobal mac_ctx,
+	uint8_t vdev_id, uint32_t scan_id, uint32_t scan_requestor_id)
+{
+	QDF_STATUS status;
+	struct scan_cancel_request *req;
+	struct wlan_objmgr_vdev *vdev;
+
+	pe_debug("scan_id %d, scan_requestor_id 0x%x",
+			scan_id, scan_requestor_id);
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+			mac_ctx->psoc, vdev_id,
+			WLAN_LEGACY_MAC_ID);
+	if (!vdev) {
+		pe_debug("vdev is NULL");
+		return;
+	}
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		goto fail;
+
+	req->vdev = vdev;
+	req->cancel_req.requester = scan_requestor_id;
+	req->cancel_req.scan_id = scan_id;
+	req->cancel_req.vdev_id = vdev_id;
+	req->cancel_req.req_type = WLAN_SCAN_CANCEL_SINGLE;
+
+	status = ucfg_scan_cancel(req);
+	if (QDF_IS_STATUS_ERROR(status))
+		pe_err("Cancel scan request failed");
+
+fail:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
+}
+
+static void lim_process_sme_obss_scan_ind(tpAniSirGlobal mac_ctx,
+					  struct scheduler_msg *msg)
+{
+	struct sPESession *session;
+	uint8_t session_id;
+	struct sme_obss_ht40_scanind_msg *ht40_scanind;
+
+	ht40_scanind = (struct sme_obss_ht40_scanind_msg *)msg->bodyptr;
+	session = pe_find_session_by_bssid(mac_ctx,
+			ht40_scanind->mac_addr.bytes, &session_id);
+	if (session == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			"OBSS Scan not started: session id is NULL");
+		return;
+	}
+	if (session->htSupportedChannelWidthSet ==
+			WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			"OBSS Scan Start Req: session id %d"
+			"htSupportedChannelWidthSet %d",
+			session->peSessionId,
+			session->htSupportedChannelWidthSet);
+		lim_send_ht40_obss_scanind(mac_ctx, session);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			"OBSS Scan not started: channel width - %d session %d",
+			session->htSupportedChannelWidthSet,
+			session->peSessionId);
+	}
+	return;
+}
+
+/**
+ * lim_process_messages() - Process messages from upper layers.
+ *
+ * @mac_ctx: Pointer to the Global Mac Context.
+ * @msg: Received message.
+ *
+ * Return:  None.
+ */
+static void lim_process_messages(tpAniSirGlobal mac_ctx,
+				 struct scheduler_msg *msg)
+{
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	uint8_t vdev_id = 0;
+	tUpdateBeaconParams beacon_params;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+	uint8_t i;
+	tpPESession session_entry = NULL;
+	uint8_t defer_msg = false;
+	tLinkStateParams *link_state_param;
+	uint16_t pkt_len = 0;
+	cds_pkt_t *body_ptr = NULL;
+	QDF_STATUS qdf_status;
+	struct scheduler_msg new_msg = {0};
+	uint8_t session_id;
+
+#ifdef FEATURE_WLAN_TDLS
+	tSirTdlsInd *tdls_ind = NULL;
+	tpDphHashNode sta_ds = NULL;
+#endif
+	if (msg == NULL) {
+		pe_err("Message pointer is Null");
+		QDF_ASSERT(0);
+		return;
+	}
+
+	if (ANI_DRIVER_TYPE(mac_ctx) == QDF_DRIVER_TYPE_MFG) {
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+		return;
+	}
+
+#ifdef WLAN_DEBUG
+	mac_ctx->lim.numTot++;
+#endif
+	/*
+	 * MTRACE logs not captured for events received from SME
+	 * SME enums (eWNI_SME_START_REQ) starts with 0x16xx.
+	 * Compare received SME events with SIR_SME_MODULE_ID
+	 */
+	if ((SIR_SME_MODULE_ID ==
+	    (uint8_t)MAC_TRACE_GET_MODULE_ID(msg->type)) &&
+	    (msg->type != eWNI_SME_REGISTER_MGMT_FRAME_REQ)) {
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_SME_MSG,
+				 NO_SESSION, msg->type));
+	} else {
+		/*
+		 * Omitting below message types as these are too frequent
+		 * and when crash happens we loose critical trace logs
+		 * if these are also logged
+		 */
+		if (msg->type != SIR_CFG_PARAM_UPDATE_IND &&
+		    msg->type != SIR_BB_XPORT_MGMT_MSG &&
+		    msg->type != WMA_RX_SCAN_EVENT)
+			MTRACE(mac_trace_msg_rx(mac_ctx, NO_SESSION,
+				LIM_TRACE_MAKE_RXMSG(msg->type,
+				LIM_MSG_PROCESSED)));
+	}
+
+	switch (msg->type) {
+
+	case SIR_LIM_UPDATE_BEACON:
+		lim_update_beacon(mac_ctx);
+		break;
+	case SIR_CFG_PARAM_UPDATE_IND:
+		if (!lim_is_system_in_scan_state(mac_ctx))
+			break;
+		/* System is in DFS (Learn) mode.
+		 * Defer processing this message
+		 */
+		if (lim_defer_msg(mac_ctx, msg) != TX_SUCCESS) {
+			if (!(mac_ctx->lim.deferredMsgCnt & 0xF))
+				QDF_TRACE(QDF_MODULE_ID_PE, LOGE,
+					FL("Unable to Defer Msg"));
+			lim_log_session_states(mac_ctx);
+			lim_print_msg_name(mac_ctx, LOGE, msg->type);
+		}
+		break;
+	case WMA_SWITCH_CHANNEL_RSP:
+		lim_process_switch_channel_rsp(mac_ctx, msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+#ifdef ANI_SIR_IBSS_PEER_CACHING
+	case WMA_IBSS_STA_ADD:
+		lim_ibss_sta_add(mac_ctx, msg->bodyptr);
+		break;
+#endif
+	case SIR_BB_XPORT_MGMT_MSG:
+		/* These messages are from Peer MAC entity. */
+#ifdef WLAN_DEBUG
+		mac_ctx->lim.numBbt++;
+#endif
+		/* The original msg which we were deferring have the
+		 * bodyPointer point to 'BD' instead of 'cds pkt'. If we
+		 * don't make a copy of msg, then overwrite the
+		 * msg->bodyPointer and next time when we try to
+		 * process the msg, we will try to use 'BD' as
+		 * 'cds Pkt' which will cause a crash
+		 */
+		if (msg->bodyptr == NULL) {
+			pe_err("Message bodyptr is Null");
+			QDF_ASSERT(0);
+			break;
+		}
+		qdf_mem_copy((uint8_t *) &new_msg,
+			(uint8_t *) msg, sizeof(struct scheduler_msg));
+		body_ptr = (cds_pkt_t *) new_msg.bodyptr;
+		cds_pkt_get_packet_length(body_ptr, &pkt_len);
+
+		qdf_status = wma_ds_peek_rx_packet_info(body_ptr,
+			(void **) &new_msg.bodyptr, false);
+
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			lim_decrement_pending_mgmt_count(mac_ctx);
+			cds_pkt_return_packet(body_ptr);
+			break;
+		}
+		if (WMA_GET_ROAMCANDIDATEIND(new_msg.bodyptr))
+			pe_debug("roamCandidateInd: %d",
+				 WMA_GET_ROAMCANDIDATEIND(new_msg.bodyptr));
+		if (WMA_GET_OFFLOADSCANLEARN(new_msg.bodyptr))
+			pe_debug("offloadScanLearn: %d",
+				 WMA_GET_OFFLOADSCANLEARN(new_msg.bodyptr));
+
+		lim_handle80211_frames(mac_ctx, &new_msg, &defer_msg);
+
+		if (defer_msg == true) {
+			QDF_TRACE(QDF_MODULE_ID_PE, LOGD,
+					FL("Defer Msg type=%x"), msg->type);
+			if (lim_defer_msg(mac_ctx, msg) != TX_SUCCESS) {
+				QDF_TRACE(QDF_MODULE_ID_PE, LOGE,
+						FL("Unable to Defer Msg"));
+				lim_log_session_states(mac_ctx);
+				lim_decrement_pending_mgmt_count(mac_ctx);
+				cds_pkt_return_packet(body_ptr);
+			}
+		} else {
+			/* PE is not deferring this 802.11 frame so we need to
+			 * call cds_pkt_return. Asumption here is when Rx mgmt
+			 * frame processing is done, cds packet could be
+			 * freed here.
+			 */
+			lim_decrement_pending_mgmt_count(mac_ctx);
+			cds_pkt_return_packet(body_ptr);
+		}
+		break;
+	case eWNI_SME_DISASSOC_REQ:
+	case eWNI_SME_DEAUTH_REQ:
+#ifdef FEATURE_WLAN_TDLS
+	case eWNI_SME_TDLS_SEND_MGMT_REQ:
+	case eWNI_SME_TDLS_ADD_STA_REQ:
+	case eWNI_SME_TDLS_DEL_STA_REQ:
+	case eWNI_SME_TDLS_LINK_ESTABLISH_REQ:
+#endif
+	case eWNI_SME_RESET_AP_CAPS_CHANGED:
+	case eWNI_SME_SET_HW_MODE_REQ:
+	case eWNI_SME_SET_DUAL_MAC_CFG_REQ:
+	case eWNI_SME_SET_ANTENNA_MODE_REQ:
+	case eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE:
+	case eWNI_SME_UPDATE_CONFIG:
+		/* These messages are from HDD. Need to respond to HDD */
+		lim_process_normal_hdd_msg(mac_ctx, msg, true);
+		break;
+	case eWNI_SME_SEND_DISASSOC_FRAME:
+		/* Need to response to hdd */
+		lim_process_normal_hdd_msg(mac_ctx, msg, true);
+		break;
+	case eWNI_SME_PDEV_SET_HT_VHT_IE:
+	case eWNI_SME_SET_VDEV_IES_PER_BAND:
+	case eWNI_SME_SYS_READY_IND:
+	case eWNI_SME_JOIN_REQ:
+	case eWNI_SME_REASSOC_REQ:
+	case eWNI_SME_START_BSS_REQ:
+	case eWNI_SME_STOP_BSS_REQ:
+	case eWNI_SME_SWITCH_CHL_IND:
+	case eWNI_SME_SETCONTEXT_REQ:
+	case eWNI_SME_DISASSOC_CNF:
+	case eWNI_SME_DEAUTH_CNF:
+	case eWNI_SME_ASSOC_CNF:
+	case eWNI_SME_ADDTS_REQ:
+	case eWNI_SME_DELTS_REQ:
+	case eWNI_SME_GET_ASSOC_STAS_REQ:
+	case eWNI_SME_SESSION_UPDATE_PARAM:
+	case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
+	case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
+	case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
+#if defined FEATURE_WLAN_ESE
+	case eWNI_SME_ESE_ADJACENT_AP_REPORT:
+#endif
+	case eWNI_SME_FT_UPDATE_KEY:
+	case eWNI_SME_FT_PRE_AUTH_REQ:
+	case eWNI_SME_FT_AGGR_QOS_REQ:
+	case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
+	case eWNI_SME_CLEAR_DFS_CHANNEL_LIST:
+	case eWNI_SME_GET_STATISTICS_REQ:
+#ifdef FEATURE_WLAN_ESE
+	case eWNI_SME_GET_TSM_STATS_REQ:
+#endif  /* FEATURE_WLAN_ESE */
+	case eWNI_SME_REGISTER_MGMT_FRAME_CB:
+	case eWNI_SME_EXT_CHANGE_CHANNEL:
+	case eWNI_SME_ROAM_INVOKE:
+		/* fall through */
+	case eWNI_SME_ROAM_SCAN_OFFLOAD_REQ:
+	case eWNI_SME_SET_ADDBA_ACCEPT:
+	case eWNI_SME_UPDATE_EDCA_PROFILE:
+	case WNI_SME_UPDATE_MU_EDCA_PARAMS:
+		/* These messages are from HDD.No need to respond to HDD */
+		lim_process_normal_hdd_msg(mac_ctx, msg, false);
+		break;
+	case eWNI_SME_SEND_MGMT_FRAME_TX:
+		lim_send_mgmt_frame_tx(mac_ctx, msg);
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case eWNI_SME_MON_INIT_SESSION:
+		lim_mon_init_session(mac_ctx, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+#ifdef FEATURE_WLAN_TDLS
+	case SIR_HAL_TDLS_IND:
+		tdls_ind = (tpSirTdlsInd) msg->bodyptr;
+		session_entry = pe_find_session_by_sta_id(mac_ctx,
+			tdls_ind->staIdx, &session_id);
+		if (session_entry == NULL) {
+			pe_debug("No session exist for given bssId");
+				qdf_mem_free(msg->bodyptr);
+				msg->bodyptr = NULL;
+				return;
+			}
+		sta_ds = dph_get_hash_entry(mac_ctx, tdls_ind->assocId,
+			&session_entry->dph.dphHashTable);
+			if (sta_ds == NULL) {
+				pe_debug("No sta_ds exist for given staId");
+				qdf_mem_free(msg->bodyptr);
+				msg->bodyptr = NULL;
+				return;
+			}
+
+			if (STA_ENTRY_TDLS_PEER == sta_ds->staType) {
+				pe_err("rcvd TDLS IND from FW with RC %d",
+					tdls_ind->reasonCode);
+				lim_send_sme_tdls_del_sta_ind(mac_ctx, sta_ds,
+					session_entry, tdls_ind->reasonCode);
+			}
+			qdf_mem_free(msg->bodyptr);
+			msg->bodyptr = NULL;
+		break;
+#endif
+	case SIR_HAL_P2P_NOA_ATTR_IND:
+		session_entry = &mac_ctx->lim.gpSession[0];
+		pe_debug("Received message Noa_ATTR %x",
+			msg->type);
+		for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+			session_entry = &mac_ctx->lim.gpSession[i];
+			if ((session_entry != NULL) && (session_entry->valid)
+				&& (session_entry->pePersona ==
+				QDF_P2P_GO_MODE)) { /* Save P2P attr for Go */
+					qdf_mem_copy(
+						&session_entry->p2pGoPsUpdate,
+						msg->bodyptr,
+						sizeof(tSirP2PNoaAttr));
+					pe_debug("bssId"
+						MAC_ADDRESS_STR
+						" ctWin=%d oppPsFlag=%d",
+						MAC_ADDR_ARRAY(
+							session_entry->bssId),
+						session_entry->p2pGoPsUpdate.ctWin,
+						session_entry->p2pGoPsUpdate.oppPsFlag);
+					pe_debug("uNoa1IntervalCnt=%d uNoa1Duration=%d uNoa1Interval=%d uNoa1StartTime=%d",
+						session_entry->p2pGoPsUpdate.uNoa1IntervalCnt,
+						session_entry->p2pGoPsUpdate.uNoa1Duration,
+						session_entry->p2pGoPsUpdate.uNoa1Interval,
+						session_entry->p2pGoPsUpdate.uNoa1StartTime);
+					break;
+			}
+		}
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case WMA_MISSED_BEACON_IND:
+		lim_ps_offload_handle_missed_beacon_ind(mac_ctx, msg);
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case SIR_LIM_ADDTS_RSP_TIMEOUT:
+		lim_process_sme_req_messages(mac_ctx, msg);
+		break;
+#ifdef FEATURE_WLAN_ESE
+	case WMA_TSM_STATS_RSP:
+		lim_send_sme_pe_ese_tsm_rsp(mac_ctx,
+			(tAniGetTsmStatsRsp *) msg->bodyptr);
+		break;
+#endif
+	case WMA_ADD_TS_RSP:
+		lim_process_hal_add_ts_rsp(mac_ctx, msg);
+		break;
+	case SIR_LIM_DEL_TS_IND:
+		lim_process_del_ts_ind(mac_ctx, msg);
+		break;
+	case SIR_LIM_BEACON_GEN_IND:
+		if (mac_ctx->lim.gLimSystemRole != eLIM_AP_ROLE)
+			sch_process_pre_beacon_ind(mac_ctx,
+						   msg, REASON_DEFAULT);
+		break;
+	case SIR_LIM_DELETE_STA_CONTEXT_IND:
+		lim_delete_sta_context(mac_ctx, msg);
+		break;
+	case SIR_LIM_RX_INVALID_PEER:
+		lim_rx_invalid_peer_process(mac_ctx, msg);
+		break;
+	case SIR_LIM_JOIN_FAIL_TIMEOUT:
+	case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT:
+	case SIR_LIM_AUTH_FAIL_TIMEOUT:
+	case SIR_LIM_AUTH_RSP_TIMEOUT:
+	case SIR_LIM_ASSOC_FAIL_TIMEOUT:
+	case SIR_LIM_REASSOC_FAIL_TIMEOUT:
+	case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
+	case SIR_LIM_DISASSOC_ACK_TIMEOUT:
+	case SIR_LIM_DEAUTH_ACK_TIMEOUT:
+	case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
+	case SIR_LIM_AUTH_RETRY_TIMEOUT:
+	case SIR_LIM_AUTH_SAE_TIMEOUT:
+		/* These timeout messages are handled by MLM sub module */
+		lim_process_mlm_req_messages(mac_ctx, msg);
+		break;
+	case SIR_LIM_HEART_BEAT_TIMEOUT:
+		/** check if heart beat failed, even if one Beacon
+		 * is rcvd within the Heart Beat interval continue
+		 * normal processing
+		 */
+		if (NULL == msg->bodyptr)
+			pe_err("Can't Process HB TO - bodyptr is Null");
+		else {
+			session_entry = (tpPESession) msg->bodyptr;
+			pe_err("SIR_LIM_HEART_BEAT_TIMEOUT, Session %d",
+				((tpPESession) msg->bodyptr)->peSessionId);
+			limResetHBPktCount(session_entry);
+			lim_handle_heart_beat_timeout_for_session(mac_ctx,
+							session_entry);
+		}
+		break;
+	case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT:
+		lim_handle_heart_beat_failure_timeout(mac_ctx);
+		break;
+	case SIR_LIM_CNF_WAIT_TIMEOUT:
+		/* Does not receive CNF or dummy packet */
+		lim_handle_cnf_wait_timeout(mac_ctx, (uint16_t) msg->bodyval);
+		break;
+	case SIR_LIM_RETRY_INTERRUPT_MSG:
+		/* Message from ISR upon TFP's max retry limit interrupt */
+		break;
+	case SIR_LIM_INV_KEY_INTERRUPT_MSG:
+		/* Message from ISR upon SP's Invalid session key interrupt */
+		break;
+	case SIR_LIM_KEY_ID_INTERRUPT_MSG:
+		/* Message from ISR upon SP's Invalid key ID interrupt */
+		break;
+	case SIR_LIM_REPLAY_THRES_INTERRUPT_MSG:
+		/* Message from ISR upon SP's Replay threshold interrupt */
+		break;
+	case SIR_LIM_CHANNEL_SWITCH_TIMEOUT:
+		lim_process_channel_switch_timeout(mac_ctx);
+		break;
+	case SIR_LIM_QUIET_TIMEOUT:
+		lim_process_quiet_timeout(mac_ctx);
+		break;
+	case SIR_LIM_QUIET_BSS_TIMEOUT:
+		lim_process_quiet_bss_timeout(mac_ctx);
+		break;
+	case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT:
+		lim_handle_update_olbc_cache(mac_ctx);
+		break;
+	case WMA_ADD_BSS_RSP:
+		lim_process_mlm_add_bss_rsp(mac_ctx, msg);
+		break;
+	case WMA_HIDDEN_SSID_RESTART_RSP:
+		lim_process_mlm_update_hidden_ssid_rsp(mac_ctx, msg);
+		break;
+	case WMA_ADD_STA_RSP:
+		lim_process_add_sta_rsp(mac_ctx, msg);
+		break;
+	case WMA_DELETE_STA_RSP:
+		lim_process_mlm_del_sta_rsp(mac_ctx, msg);
+		break;
+	case WMA_DELETE_BSS_RSP:
+	case WMA_DELETE_BSS_HO_FAIL_RSP:
+		lim_handle_delete_bss_rsp(mac_ctx, msg);
+		break;
+	case WMA_CSA_OFFLOAD_EVENT:
+		lim_handle_csa_offload_msg(mac_ctx, msg);
+		break;
+	case WMA_SET_BSSKEY_RSP:
+	case WMA_SET_STA_BCASTKEY_RSP:
+		lim_process_mlm_set_bss_key_rsp(mac_ctx, msg);
+		break;
+	case WMA_SET_STAKEY_RSP:
+		lim_process_mlm_set_sta_key_rsp(mac_ctx, msg);
+		break;
+	case WMA_GET_STATISTICS_RSP:
+		lim_send_sme_pe_statistics_rsp(mac_ctx, msg->type,
+					     (void *)msg->bodyptr);
+		break;
+	case WMA_SET_MIMOPS_RSP:
+	case WMA_SET_TX_POWER_RSP:
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case WMA_SET_MAX_TX_POWER_RSP:
+		rrm_set_max_tx_power_rsp(mac_ctx, msg);
+		if (msg->bodyptr != NULL) {
+			qdf_mem_free((void *)msg->bodyptr);
+			msg->bodyptr = NULL;
+		}
+		break;
+	case SIR_LIM_ADDR2_MISS_IND:
+		pe_err(
+			FL("Addr2 mismatch interrupt received %X"), msg->type);
+		/* message from HAL indicating addr2 mismatch interrupt occurred
+		 * msg->bodyptr contains only pointer to 48-bit addr2 field
+		 */
+		qdf_mem_free((void *)(msg->bodyptr));
+		msg->bodyptr = NULL;
+		break;
+	case WMA_AGGR_QOS_RSP:
+		lim_process_ft_aggr_qo_s_rsp(mac_ctx, msg);
+		break;
+	case WMA_SET_LINK_STATE_RSP:
+		link_state_param = (tLinkStateParams *) msg->bodyptr;
+		session_entry = link_state_param->session;
+		if (link_state_param->ft
+#if defined WLAN_FEATURE_ROAM_OFFLOAD
+			&& !session_entry->bRoamSynchInProgress
+#endif
+		)
+			lim_send_reassoc_req_with_ft_ies_mgmt_frame(mac_ctx,
+				session_entry->pLimMlmReassocReq,
+				session_entry);
+		if (link_state_param->callback)
+			link_state_param->callback(mac_ctx,
+				link_state_param->callbackArg,
+				link_state_param->status);
+		qdf_mem_free((void *)(msg->bodyptr));
+		msg->bodyptr = NULL;
+		break;
+	case WMA_RX_CHN_STATUS_EVENT:
+		lim_process_rx_channel_status_event(mac_ctx, msg->bodyptr);
+		break;
+	case WMA_IBSS_PEER_INACTIVITY_IND:
+		lim_process_ibss_peer_inactivity(mac_ctx, msg->bodyptr);
+		qdf_mem_free((void *)(msg->bodyptr));
+		msg->bodyptr = NULL;
+		break;
+	case WMA_DFS_BEACON_TX_SUCCESS_IND:
+		lim_process_beacon_tx_success_ind(mac_ctx, msg->type,
+				(void *)msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case WMA_DISASSOC_TX_COMP:
+		lim_disassoc_tx_complete_cnf(mac_ctx, msg->bodyval,
+					     msg->bodyptr);
+		break;
+	case WMA_DEAUTH_TX_COMP:
+		lim_deauth_tx_complete_cnf(mac_ctx, msg->bodyval,
+					   msg->bodyptr);
+		break;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	case WMA_UPDATE_Q2Q_IE_IND:
+		qdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
+		beacon_params.paramChangeBitmap = 0;
+		for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+			vdev_id = ((uint8_t *)msg->bodyptr)[i];
+			session_entry = pe_find_session_by_sme_session_id(
+				mac_ctx, vdev_id);
+			if (session_entry == NULL)
+				continue;
+			session_entry->sap_advertise_avoid_ch_ie =
+				(uint8_t)msg->bodyval;
+			/*
+			 * if message comes for DFS channel, no need to update:
+			 * 1) We wont have MCC with DFS channels. so no need to
+			 *    add Q2Q IE
+			 * 2) We cannot end up in DFS channel SCC by channel
+			 *    switch from non DFS MCC scenario, so no need to
+			 *    remove Q2Q IE
+			 * 3) There is however a case where device start MCC and
+			 *    then user modifies hostapd.conf and does SAP
+			 *    restart, in such a case, beacon params will be
+			 *    reset and thus will not contain Q2Q IE, by default
+			 */
+			if (wlan_reg_get_channel_state(mac_ctx->pdev,
+					session_entry->currentOperChannel)
+					!= CHANNEL_STATE_DFS) {
+				beacon_params.bssIdx = session_entry->bssIdx;
+				beacon_params.beaconInterval =
+					session_entry->beaconParams.beaconInterval;
+				beacon_params.paramChangeBitmap |=
+					PARAM_BCN_INTERVAL_CHANGED;
+				sch_set_fixed_beacon_fields(mac_ctx,
+					session_entry);
+				lim_send_beacon_params(mac_ctx, &beacon_params,
+					session_entry);
+			}
+		}
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+	case eWNI_SME_NSS_UPDATE_REQ:
+	case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ:
+		lim_process_sme_req_messages(mac_ctx, msg);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case eWNI_SME_CHANNEL_CHANGE_REQ:
+		lim_process_sme_req_messages(mac_ctx, msg);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case eWNI_SME_START_BEACON_REQ:
+		lim_process_sme_req_messages(mac_ctx, msg);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case eWNI_SME_UPDATE_ADDITIONAL_IES:
+		lim_process_sme_req_messages(mac_ctx, msg);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case eWNI_SME_MODIFY_ADDITIONAL_IES:
+		lim_process_sme_req_messages(mac_ctx, msg);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+#ifdef QCA_HT_2040_COEX
+	case eWNI_SME_SET_HT_2040_MODE:
+		lim_process_sme_req_messages(mac_ctx, msg);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+#endif
+	case SIR_HAL_PDEV_SET_HW_MODE_RESP:
+		lim_process_set_hw_mode_resp(mac_ctx, msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case SIR_HAL_PDEV_HW_MODE_TRANS_IND:
+		lim_process_hw_mode_trans_ind(mac_ctx, msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case SIR_HAL_PDEV_MAC_CFG_RESP:
+		lim_process_dual_mac_cfg_resp(mac_ctx, msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case eWNI_SME_SET_IE_REQ:
+		lim_process_sme_req_messages(mac_ctx, msg);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case eWNI_SME_HT40_OBSS_SCAN_IND:
+		lim_process_sme_obss_scan_ind(mac_ctx, msg);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_SOC_ANTENNA_MODE_RESP:
+		lim_process_set_antenna_resp(mac_ctx, msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case eWNI_SME_DEFAULT_SCAN_IE:
+		lim_process_set_default_scan_ie_request(mac_ctx, msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case eWNI_SME_SET_HE_BSS_COLOR:
+		lim_process_set_he_bss_color(mac_ctx, msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case eWNI_SME_DEL_ALL_TDLS_PEERS:
+		lim_process_sme_del_all_tdls_peers(mac_ctx, msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case WMA_OBSS_DETECTION_INFO:
+		lim_process_obss_detection_ind(mac_ctx, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case eWNI_SME_SEND_SAE_MSG:
+		lim_process_sae_msg(mac_ctx, msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	case WMA_OBSS_COLOR_COLLISION_INFO:
+		lim_process_obss_color_collision_info(mac_ctx, msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+#ifdef CONFIG_VDEV_SM
+	case eWNI_SME_CSA_RESTART_REQ:
+		lim_send_csa_restart_req(mac_ctx, msg->bodyval);
+		break;
+#endif
+	case WMA_SEND_BCN_RSP:
+		lim_send_bcn_rsp(mac_ctx, (tpSendbeaconParams)msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
+	default:
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		pe_debug("Discarding unexpected message received %X",
+			msg->type);
+		lim_print_msg_name(mac_ctx, LOGE, msg->type);
+		break;
+
+	} /* switch (msg->type) */
+} /*** end lim_process_messages() ***/
+
+/**
+ * lim_process_deferred_message_queue()
+ *
+ * This function is called by LIM while exiting from Learn
+ * mode. This function fetches messages posted to the LIM
+ * deferred message queue limDeferredMsgQ.
+ *
+ * @pMac: Pointer to Global MAC structure
+ * @return None
+ */
+
+static void lim_process_deferred_message_queue(tpAniSirGlobal pMac)
+{
+	struct scheduler_msg limMsg = {0};
+	struct scheduler_msg *readMsg;
+	uint16_t size;
+
+	/*
+	** check any deferred messages need to be processed
+	**/
+	size = pMac->lim.gLimDeferredMsgQ.size;
+	if (size > 0) {
+		while ((readMsg = lim_read_deferred_msg_q(pMac)) != NULL) {
+			qdf_mem_copy((uint8_t *) &limMsg,
+				     (uint8_t *) readMsg,
+				     sizeof(struct scheduler_msg));
+			size--;
+			lim_process_messages(pMac, &limMsg);
+
+			if ((lim_is_system_in_scan_state(pMac))
+			    || (true != GET_LIM_PROCESS_DEFD_MESGS(pMac))
+			    ||  pMac->lim.gLimAddtsSent)
+				break;
+		}
+	}
+} /*** end lim_process_deferred_message_queue() ***/
+
+/**
+ * lim_message_processor() - Process messages from LIM.
+ * @mac_ctx: Pointer to the Global Mac Context.
+ * @msg: Received LIM message.
+ *
+ * Wrapper function for lim_process_messages when handling messages received by
+ * LIM. Could either defer messages or process them.
+ *
+ * Return:  None.
+ */
+void lim_message_processor(tpAniSirGlobal mac_ctx, struct scheduler_msg *msg)
+{
+	if (eLIM_MLM_OFFLINE_STATE == mac_ctx->lim.gLimMlmState) {
+		pe_free_msg(mac_ctx, msg);
+		return;
+	}
+
+	if (!def_msg_decision(mac_ctx, msg)) {
+		lim_process_messages(mac_ctx, msg);
+		/* process deferred message queue if allowed */
+		if ((!(mac_ctx->lim.gLimAddtsSent)) &&
+		    (!(lim_is_system_in_scan_state(mac_ctx))) &&
+		    (true == GET_LIM_PROCESS_DEFD_MESGS(mac_ctx)))
+			lim_process_deferred_message_queue(mac_ctx);
+	}
+}
+
+/**
+ * lim_process_normal_hdd_msg() - Process the message and defer if needed
+ * @mac_ctx :     Pointer to Global MAC structure
+ * @msg     :     The message need to be processed
+ * @rsp_reqd:     whether return result to hdd
+ *
+ * This function checks the current lim state and decide whether the message
+ * passed will be deferred or not.
+ *
+ * Return: None
+ */
+static void lim_process_normal_hdd_msg(tpAniSirGlobal mac_ctx,
+				       struct scheduler_msg *msg,
+				       uint8_t rsp_reqd)
+{
+	bool defer_msg = true;
+
+	/* Added For BT-AMP Support */
+	if ((mac_ctx->lim.gLimSystemRole == eLIM_AP_ROLE)
+		|| (mac_ctx->lim.gLimSystemRole == eLIM_UNKNOWN_ROLE)) {
+		/*
+		 * This check is required only for the AP and in 2 cases.
+		 * 1. If we are in learn mode and we receive any of these
+		 * messages, you have to come out of scan and process the
+		 * message, hence dont defer the message here. In handler,
+		 * these message could be defered till we actually come out of
+		 * scan mode.
+		 * 2. If radar is detected, you might have to defer all of
+		 * these messages except Stop BSS request/ Switch channel
+		 * request. This decision is also made inside its handler.
+		 *
+		 * Please be careful while using the flag defer_msg. Possibly
+		 * you might end up in an infinite loop.
+		 */
+		if ((msg->type == eWNI_SME_START_BSS_REQ) ||
+			(msg->type == eWNI_SME_STOP_BSS_REQ) ||
+			(msg->type == eWNI_SME_SWITCH_CHL_IND))
+			defer_msg = false;
+	}
+
+	if (((mac_ctx->lim.gLimAddtsSent) ||
+		(lim_is_system_in_scan_state(mac_ctx))) && defer_msg) {
+		/*
+		 * System is in DFS (Learn) mode or awaiting addts response or
+		 * if radar is detected, Defer processing this message
+		 */
+		if (lim_defer_msg(mac_ctx, msg) != TX_SUCCESS) {
+#ifdef WLAN_DEBUG
+			mac_ctx->lim.numSme++;
+#endif
+			lim_log_session_states(mac_ctx);
+			/* Release body */
+			qdf_mem_free(msg->bodyptr);
+			msg->bodyptr = NULL;
+		}
+	} else {
+		/*
+		 * These messages are from HDD.Since these requests may also be
+		 * generated internally within LIM module, need to distinquish
+		 * and send response to host
+		 */
+		if (rsp_reqd)
+			mac_ctx->lim.gLimRspReqd = true;
+#ifdef WLAN_DEBUG
+		mac_ctx->lim.numSme++;
+#endif
+		if (lim_process_sme_req_messages(mac_ctx, msg)) {
+			/*
+			 * Release body. limProcessSmeReqMessage consumed the
+			 * buffer. We can free it.
+			 */
+			qdf_mem_free(msg->bodyptr);
+			msg->bodyptr = NULL;
+		}
+	}
+}
+
+void
+handle_ht_capabilityand_ht_info(struct mac_context *pMac,
+				tpPESession psessionEntry)
+{
+	struct mlme_ht_capabilities_info *ht_cap_info;
+
+	ht_cap_info = &pMac->mlme_cfg->ht_caps.ht_cap_info;
+	pMac->lim.gHTLsigTXOPProtection =
+		(uint8_t)ht_cap_info->l_sig_tx_op_protection;
+	pMac->lim.gHTMIMOPSState =
+		(tSirMacHTMIMOPowerSaveState)ht_cap_info->mimo_power_save;
+	pMac->lim.gHTGreenfield = (uint8_t)ht_cap_info->green_field;
+	pMac->lim.gHTMaxAmsduLength =
+		(uint8_t)ht_cap_info->maximal_amsdu_size;
+	pMac->lim.gHTShortGI20Mhz = (uint8_t)ht_cap_info->short_gi_20_mhz;
+	pMac->lim.gHTShortGI40Mhz = (uint8_t)ht_cap_info->short_gi_40_mhz;
+	pMac->lim.gHTPSMPSupport = (uint8_t)ht_cap_info->psmp;
+	pMac->lim.gHTDsssCckRate40MHzSupport =
+		(uint8_t)ht_cap_info->dsss_cck_mode_40_mhz;
+
+	pMac->lim.gHTAMpduDensity =
+		(uint8_t)pMac->mlme_cfg->ht_caps.ampdu_params.mpdu_density;
+	pMac->lim.gHTMaxRxAMpduFactor =
+		(uint8_t)pMac->mlme_cfg->ht_caps.ampdu_params.
+		max_rx_ampdu_factor;
+
+	/* Get HT IE Info */
+	pMac->lim.gHTServiceIntervalGranularity =
+		(uint8_t)pMac->mlme_cfg->ht_caps.info_field_1.
+		service_interval_granularity;
+	pMac->lim.gHTControlledAccessOnly =
+		(uint8_t)pMac->mlme_cfg->ht_caps.info_field_1.
+		controlled_access_only;
+	pMac->lim.gHTRifsMode = (uint8_t)pMac->mlme_cfg->ht_caps.info_field_1.
+		rifs_mode;
+
+	pMac->lim.gHTPCOActive = (uint8_t)pMac->mlme_cfg->ht_caps.info_field_3.
+								pco_active;
+	pMac->lim.gHTPCOPhase = (uint8_t)pMac->mlme_cfg->ht_caps.info_field_3.
+								pco_phase;
+	pMac->lim.gHTSecondaryBeacon =
+		(uint8_t)pMac->mlme_cfg->ht_caps.info_field_3.secondary_beacon;
+	pMac->lim.gHTDualCTSProtection = (uint8_t)pMac->mlme_cfg->ht_caps.
+					info_field_3.dual_cts_protection;
+	pMac->lim.gHTSTBCBasicMCS = (uint8_t)pMac->mlme_cfg->ht_caps.
+					info_field_3.basic_stbc_mcs;
+
+	/* The lim globals for channelwidth and secondary chnl have been removed and should not be used during no session;
+	 * instead direct cfg is read and used when no session for transmission of mgmt frames (same as old);
+	 * For now, we might come here during init and join with sessionEntry = NULL; in that case just fill the globals which exist
+	 * Sessionized entries values will be filled in join or add bss req. The ones which are missed in join are filled below
+	 */
+	if (psessionEntry != NULL) {
+		psessionEntry->htCapability =
+			IS_DOT11_MODE_HT(psessionEntry->dot11mode);
+		psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport =
+			(uint8_t)pMac->mlme_cfg->ht_caps.info_field_3.
+			lsig_txop_protection_full_support;
+		lim_init_obss_params(pMac, psessionEntry);
+	}
+}
+
+void lim_log_session_states(tpAniSirGlobal mac_ctx)
+{
+#ifdef WLAN_DEBUG
+	int i;
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		if (mac_ctx->lim.gpSession[i].valid) {
+			QDF_TRACE(QDF_MODULE_ID_PE, LOGD,
+				FL("sysRole(%d) Session (%d)"),
+				mac_ctx->lim.gLimSystemRole, i);
+			QDF_TRACE(QDF_MODULE_ID_PE, LOGD,
+				FL("SME: Curr %s,Prev %s,MLM: Curr %s,Prev %s"),
+				lim_sme_state_str(
+				mac_ctx->lim.gpSession[i].limSmeState),
+				lim_sme_state_str(
+				mac_ctx->lim.gpSession[i].limPrevSmeState),
+				lim_mlm_state_str(
+				mac_ctx->lim.gpSession[i].limMlmState),
+				lim_mlm_state_str(
+				mac_ctx->lim.gpSession[i].limPrevMlmState));
+		}
+	}
+#endif
+}
diff --git a/core/mac/src/pe/lim/lim_process_mlm_host_roam.c b/core/mac/src/pe/lim/lim_process_mlm_host_roam.c
new file mode 100644
index 0000000..bada9af
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_mlm_host_roam.c
@@ -0,0 +1,667 @@
+/*
+ * Copyright (c) 2016-2018 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: lim_process_mlm_host_roam.c
+ *
+ * Host based roaming MLM implementation
+ */
+#include "cds_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "sir_api.h"
+#include "sir_params.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_security_utils.h"
+#include "lim_send_messages.h"
+#include "lim_send_messages.h"
+#include "lim_session_utils.h"
+#include <lim_ft.h>
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+#include "host_diag_core_log.h"
+#endif
+#include "wma_if.h"
+#include "rrm_api.h"
+static void lim_handle_sme_reaasoc_result(tpAniSirGlobal, tSirResultCodes,
+		uint16_t, tpPESession);
+/**
+ * lim_process_mlm_reassoc_req() - process mlm reassoc request.
+ *
+ * @mac_ctx:     pointer to Global MAC structure
+ * @msg:  pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_REASSOC_REQ message
+ * from SME
+ *
+ * Return: None
+ */
+void lim_process_mlm_reassoc_req(tpAniSirGlobal mac_ctx,
+				 tLimMlmReassocReq *reassoc_req)
+{
+	uint8_t channel, sec_ch_offset;
+	struct tLimPreAuthNode *auth_node;
+	tLimMlmReassocCnf reassoc_cnf;
+	tpPESession session;
+
+	session = pe_find_session_by_session_id(mac_ctx,
+			reassoc_req->sessionId);
+	if (NULL == session) {
+		pe_err("Session Does not exist for given sessionId: %d",
+			reassoc_req->sessionId);
+		qdf_mem_free(reassoc_req);
+		return;
+	}
+
+	pe_debug("ReAssoc Req on session: %d role: %d mlm: %d " MAC_ADDRESS_STR,
+		reassoc_req->sessionId, GET_LIM_SYSTEM_ROLE(session),
+		session->limMlmState, MAC_ADDR_ARRAY(reassoc_req->peerMacAddr));
+
+	if (LIM_IS_AP_ROLE(session) ||
+		(session->limMlmState !=
+		eLIM_MLM_LINK_ESTABLISHED_STATE)) {
+		/*
+		 * Received Reassoc request in invalid state or
+		 * in AP role.Return Reassoc confirm with Invalid
+		 * parameters code.
+		 */
+
+		pe_warn("unexpect msg state: %X role: %d MAC" MAC_ADDRESS_STR,
+			session->limMlmState, GET_LIM_SYSTEM_ROLE(session),
+			MAC_ADDR_ARRAY(reassoc_req->peerMacAddr));
+		lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
+		reassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+		reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+		goto end;
+	}
+
+	if (session->pLimMlmReassocReq)
+		qdf_mem_free(session->pLimMlmReassocReq);
+
+	/*
+	 * Hold Re-Assoc request as part of Session, knock-out mac_ctx
+	 * Hold onto Reassoc request parameters
+	 */
+	session->pLimMlmReassocReq = reassoc_req;
+
+	/* See if we have pre-auth context with new AP */
+	auth_node = lim_search_pre_auth_list(mac_ctx, session->limReAssocbssId);
+
+	if (!auth_node && (qdf_mem_cmp(reassoc_req->peerMacAddr,
+					    session->bssId,
+					    sizeof(tSirMacAddr)))) {
+		/*
+		 * Either pre-auth context does not exist AND
+		 * we are not reassociating with currently
+		 * associated AP.
+		 * Return Reassoc confirm with not authenticated
+		 */
+		reassoc_cnf.resultCode = eSIR_SME_STA_NOT_AUTHENTICATED;
+		reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+		goto end;
+	}
+	/* assign the sessionId to the timer object */
+	mac_ctx->lim.limTimers.gLimReassocFailureTimer.sessionId =
+		reassoc_req->sessionId;
+	session->limPrevMlmState = session->limMlmState;
+	session->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
+			 session->limMlmState));
+
+	/* Derive channel from BSS description and store it at CFG. */
+	channel = session->limReassocChannelId;
+	sec_ch_offset = session->reAssocHtSecondaryChannelOffset;
+
+	/* Apply previously set configuration at HW */
+	lim_apply_configuration(mac_ctx, session);
+
+	/* store the channel switch sessionEntry in the lim global var */
+	session->channelChangeReasonCode =
+		LIM_SWITCH_CHANNEL_REASSOC;
+
+	/* Switch channel to the new Operating channel for Reassoc */
+	lim_set_channel(mac_ctx, channel,
+			session->ch_center_freq_seg0,
+			session->ch_center_freq_seg1,
+			session->ch_width,
+			session->maxTxPower,
+			session->peSessionId, 0, 0);
+
+	return;
+end:
+	reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+	/* Update PE sessio Id */
+	reassoc_cnf.sessionId = reassoc_req->sessionId;
+	/* Free up buffer allocated for reassocReq */
+	qdf_mem_free(reassoc_req);
+	session->pLimReAssocReq = NULL;
+	lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF,
+			     (uint32_t *) &reassoc_cnf);
+}
+
+/**
+ * lim_handle_sme_reaasoc_result() - Handle the reassoc result
+ * @pMac: Global MAC Context
+ * @resultCode: Result code
+ * @protStatusCode: Protocol Status Code
+ * @psessionEntry: PE Session
+ *
+ * This function is called to process reassoc failures
+ * upon receiving REASSOC_CNF with a failure code or
+ * MLM_REASSOC_CNF with a success code in case of STA role
+ *
+ * Return: None
+ */
+static void lim_handle_sme_reaasoc_result(tpAniSirGlobal pMac,
+		tSirResultCodes resultCode, uint16_t protStatusCode,
+		tpPESession psessionEntry)
+{
+	tpDphHashNode pStaDs = NULL;
+	uint8_t smesessionId;
+	uint16_t smetransactionId;
+
+	if (psessionEntry == NULL) {
+		pe_err("psessionEntry is NULL");
+		return;
+	}
+	smesessionId = psessionEntry->smeSessionId;
+	smetransactionId = psessionEntry->transactionId;
+	if (resultCode != eSIR_SME_SUCCESS) {
+		pStaDs =
+			dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+					   &psessionEntry->dph.dphHashTable);
+		if (pStaDs != NULL) {
+			pStaDs->mlmStaContext.disassocReason =
+				eSIR_MAC_UNSPEC_FAILURE_REASON;
+			pStaDs->mlmStaContext.cleanupTrigger =
+				eLIM_JOIN_FAILURE;
+			pStaDs->mlmStaContext.resultCode = resultCode;
+			pStaDs->mlmStaContext.protStatusCode = protStatusCode;
+			lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
+			/* Cleanup if add bss failed */
+			if (psessionEntry->add_bss_failed) {
+				dph_delete_hash_entry(pMac,
+					 pStaDs->staAddr, pStaDs->assocId,
+					 &psessionEntry->dph.dphHashTable);
+				goto error;
+			}
+			return;
+		}
+	}
+error:
+	/* Delete the session if REASSOC failure occurred. */
+	if (resultCode != eSIR_SME_SUCCESS) {
+		if (NULL != psessionEntry) {
+			pe_delete_session(pMac, psessionEntry);
+			psessionEntry = NULL;
+		}
+	}
+	lim_send_sme_join_reassoc_rsp(pMac, eWNI_SME_REASSOC_RSP, resultCode,
+		protStatusCode, psessionEntry, smesessionId, smetransactionId);
+}
+
+/**
+ * lim_process_mlm_reassoc_cnf() - process mlm reassoc cnf msg
+ *
+ * @mac_ctx:       Pointer to Global MAC structure
+ * @msg_buf:       A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_REASSOC_CNF message from MLM State
+ * machine.
+ *
+ * @Return: void
+ */
+void lim_process_mlm_reassoc_cnf(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+	tpPESession session;
+	tLimMlmReassocCnf *lim_mlm_reassoc_cnf;
+
+	if (msg_buf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	lim_mlm_reassoc_cnf = (tLimMlmReassocCnf *) msg_buf;
+	session = pe_find_session_by_session_id(mac_ctx,
+				lim_mlm_reassoc_cnf->sessionId);
+	if (session == NULL) {
+		pe_err("session Does not exist for given session Id");
+		return;
+	}
+	if ((session->limSmeState != eLIM_SME_WT_REASSOC_STATE) ||
+	    LIM_IS_AP_ROLE(session)) {
+		/*
+		 * Should not have received Reassocication confirm
+		 * from MLM in other states OR on AP.
+		 */
+		pe_err("Rcv unexpected MLM_REASSOC_CNF role: %d sme 0x%X",
+			GET_LIM_SYSTEM_ROLE(session), session->limSmeState);
+		return;
+	}
+
+	/*
+	 * Upon Reassoc success or failure, freeup the cached preauth request,
+	 * to ensure that channel switch is now allowed following any change in
+	 * HT params.
+	 */
+	if (session->ftPEContext.pFTPreAuthReq) {
+		pe_debug("Freeing pFTPreAuthReq: %pK",
+			session->ftPEContext.pFTPreAuthReq);
+		if (session->ftPEContext.pFTPreAuthReq->pbssDescription) {
+			qdf_mem_free(
+			  session->ftPEContext.pFTPreAuthReq->pbssDescription);
+			session->ftPEContext.pFTPreAuthReq->pbssDescription =
+									NULL;
+		}
+		qdf_mem_free(session->ftPEContext.pFTPreAuthReq);
+		session->ftPEContext.pFTPreAuthReq = NULL;
+		session->ftPEContext.ftPreAuthSession = false;
+	}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (session->bRoamSynchInProgress) {
+		pe_debug("LFR3:Re-set the LIM Ctxt Roam Synch In Progress");
+		session->bRoamSynchInProgress = false;
+	}
+#endif
+
+	pe_debug("Rcv MLM_REASSOC_CNF with result code: %d",
+		lim_mlm_reassoc_cnf->resultCode);
+	if (lim_mlm_reassoc_cnf->resultCode == eSIR_SME_SUCCESS) {
+		/* Successful Reassociation */
+		pe_debug("*** Reassociated with new BSS ***");
+
+		session->limSmeState = eLIM_SME_LINK_EST_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+		      session->peSessionId, session->limSmeState));
+
+		/* Need to send Reassoc rsp with Reassoc success to Host. */
+		lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_REASSOC_RSP,
+					lim_mlm_reassoc_cnf->resultCode,
+					lim_mlm_reassoc_cnf->protStatusCode,
+					session, session->smeSessionId,
+					session->transactionId);
+	} else if (lim_mlm_reassoc_cnf->resultCode
+			== eSIR_SME_REASSOC_REFUSED) {
+		/*
+		 * Reassociation failure With the New AP but we still have the
+		 * link with the Older AP
+		 */
+		session->limSmeState = eLIM_SME_LINK_EST_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+		       session->peSessionId, session->limSmeState));
+
+		/* Need to send Reassoc rsp with Assoc failure to Host. */
+		lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_REASSOC_RSP,
+					lim_mlm_reassoc_cnf->resultCode,
+					lim_mlm_reassoc_cnf->protStatusCode,
+					session, session->smeSessionId,
+					session->transactionId);
+	} else {
+		/* Reassociation failure */
+		session->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+					   session->peSessionId, session->limSmeState));
+		/* Need to send Reassoc rsp with Assoc failure to Host. */
+		lim_handle_sme_reaasoc_result(mac_ctx,
+					lim_mlm_reassoc_cnf->resultCode,
+					lim_mlm_reassoc_cnf->protStatusCode,
+					session);
+	}
+
+	if (session->pLimReAssocReq) {
+		qdf_mem_free(session->pLimReAssocReq);
+		session->pLimReAssocReq = NULL;
+	}
+}
+
+/**
+ * lim_process_sta_mlm_add_bss_rsp_ft() - Handle the ADD BSS response
+ * @pMac: Global MAC context
+ * @limMsgQ: ADD BSS Parameters
+ * @psessionEntry: PE Session
+ *
+ * Function to handle WMA_ADD_BSS_RSP, in FT reassoc state.
+ * Send ReAssociation Request.
+ *
+ *Return: None
+ */
+void lim_process_sta_mlm_add_bss_rsp_ft(tpAniSirGlobal pMac,
+		struct scheduler_msg *limMsgQ, tpPESession psessionEntry)
+{
+	tLimMlmReassocCnf mlmReassocCnf; /* keep sme */
+	tpDphHashNode pStaDs = NULL;
+	tpAddStaParams pAddStaParams = NULL;
+	uint32_t listenInterval = MLME_CFG_LISTEN_INTERVAL;
+	tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+	uint32_t selfStaDot11Mode = 0;
+
+	/* Sanity Checks */
+
+	if (pAddBssParams == NULL) {
+		pe_err("Invalid parameters");
+		goto end;
+	}
+	if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE !=
+	    psessionEntry->limMlmState) {
+		goto end;
+	}
+
+	pStaDs = dph_add_hash_entry(pMac, pAddBssParams->bssId,
+					DPH_STA_HASH_INDEX_PEER,
+					&psessionEntry->dph.dphHashTable);
+	if (pStaDs == NULL) {
+		/* Could not add hash table entry */
+		pe_err("could not add hash entry at DPH for");
+		lim_print_mac_addr(pMac, pAddBssParams->staContext.staMac,
+				   LOGE);
+		goto end;
+	}
+	/* Prepare and send Reassociation request frame */
+	/* start reassoc timer. */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (psessionEntry->bRoamSynchInProgress != true) {
+#endif
+		pMac->lim.limTimers.gLimReassocFailureTimer.sessionId =
+			psessionEntry->peSessionId;
+		/* / Start reassociation failure timer */
+		MTRACE(mac_trace
+			(pMac, TRACE_CODE_TIMER_ACTIVATE,
+			 psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER));
+		if (tx_timer_activate
+			(&pMac->lim.limTimers.gLimReassocFailureTimer)
+			!= TX_SUCCESS) {
+			/* / Could not start reassoc failure timer. */
+			/* Log error */
+			pe_err("could not start Reassoc failure timer");
+			/* Return Reassoc confirm with */
+			/* Resources Unavailable */
+			mlmReassocCnf.resultCode =
+				eSIR_SME_RESOURCES_UNAVAILABLE;
+			mlmReassocCnf.protStatusCode =
+				eSIR_MAC_UNSPEC_FAILURE_STATUS;
+			goto end;
+		}
+		pMac->lim.pSessionEntry = psessionEntry;
+		if (NULL == pMac->lim.pSessionEntry->pLimMlmReassocRetryReq) {
+			/* Take a copy of reassoc request for retrying */
+			pMac->lim.pSessionEntry->pLimMlmReassocRetryReq =
+				qdf_mem_malloc(sizeof(tLimMlmReassocReq));
+			if (!pMac->lim.pSessionEntry->pLimMlmReassocRetryReq)
+				goto end;
+			qdf_mem_copy(pMac->lim.pSessionEntry->
+					pLimMlmReassocRetryReq,
+					psessionEntry->pLimMlmReassocReq,
+					sizeof(tLimMlmReassocReq));
+		}
+		pMac->lim.reAssocRetryAttempt = 0;
+		lim_send_reassoc_req_with_ft_ies_mgmt_frame(pMac,
+				psessionEntry->
+				pLimMlmReassocReq,
+				psessionEntry);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	} else {
+		pe_debug("LFR3:Do not activate timer and dont send the reassoc");
+	}
+#endif
+	psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
+	psessionEntry->limMlmState = eLIM_MLM_WT_FT_REASSOC_RSP_STATE;
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+		       eLIM_MLM_WT_FT_REASSOC_RSP_STATE));
+	pe_debug("Set the mlm state: %d session: %d",
+		       psessionEntry->limMlmState, psessionEntry->peSessionId);
+
+	psessionEntry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
+
+	/* Success, handle below */
+	pStaDs->bssId = pAddBssParams->bssIdx;
+	/* STA Index(genr by HAL) for the BSS entry is stored here */
+	pStaDs->staIndex = pAddBssParams->staContext.staIdx;
+
+	rrm_cache_mgmt_tx_power(pMac, pAddBssParams->txMgmtPower,
+			psessionEntry);
+
+	pAddStaParams = qdf_mem_malloc(sizeof(tAddStaParams));
+	if (!pAddStaParams)
+		goto end;
+
+	/* / Add STA context at MAC HW (BMU, RHP & TFP) */
+	qdf_mem_copy((uint8_t *) pAddStaParams->staMac,
+		     (uint8_t *) psessionEntry->selfMacAddr,
+		     sizeof(tSirMacAddr));
+
+	qdf_mem_copy((uint8_t *) pAddStaParams->bssId,
+		     psessionEntry->bssId, sizeof(tSirMacAddr));
+
+	pAddStaParams->staType = STA_ENTRY_SELF;
+	pAddStaParams->status = QDF_STATUS_SUCCESS;
+	pAddStaParams->respReqd = 1;
+
+	/* Update  PE session ID */
+	pAddStaParams->sessionId = psessionEntry->peSessionId;
+	pAddStaParams->smesessionId = psessionEntry->smeSessionId;
+
+	/* This will indicate HAL to "allocate" a new STA index */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (psessionEntry->bRoamSynchInProgress != true)
+#endif
+		pAddStaParams->staIdx = STA_INVALID_IDX;
+	pAddStaParams->updateSta = false;
+
+	pAddStaParams->shortPreambleSupported =
+		(uint8_t) psessionEntry->beaconParams.fShortPreamble;
+	lim_populate_peer_rate_set(pMac, &pAddStaParams->supportedRates, NULL,
+				   false, psessionEntry, NULL, NULL);
+
+	if (psessionEntry->htCapability) {
+		pAddStaParams->htCapable = psessionEntry->htCapability;
+		pAddStaParams->vhtCapable = psessionEntry->vhtCapability;
+		pAddStaParams->ch_width = psessionEntry->ch_width;
+		pAddStaParams->greenFieldCapable =
+			lim_get_ht_capability(pMac, eHT_GREENFIELD,
+					      psessionEntry);
+		pAddStaParams->mimoPS =
+			lim_get_ht_capability(pMac, eHT_MIMO_POWER_SAVE,
+					      psessionEntry);
+		pAddStaParams->rifsMode =
+			lim_get_ht_capability(pMac, eHT_RIFS_MODE,
+					psessionEntry);
+		pAddStaParams->lsigTxopProtection =
+			lim_get_ht_capability(pMac, eHT_LSIG_TXOP_PROTECTION,
+					      psessionEntry);
+		pAddStaParams->maxAmpduDensity =
+			lim_get_ht_capability(pMac, eHT_MPDU_DENSITY,
+					psessionEntry);
+		pAddStaParams->maxAmpduSize =
+			lim_get_ht_capability(pMac, eHT_MAX_RX_AMPDU_FACTOR,
+					      psessionEntry);
+		pAddStaParams->maxAmsduSize =
+			lim_get_ht_capability(pMac, eHT_MAX_AMSDU_LENGTH,
+					      psessionEntry);
+		pAddStaParams->max_amsdu_num =
+			lim_get_ht_capability(pMac, eHT_MAX_AMSDU_NUM,
+					      psessionEntry);
+		pAddStaParams->fDsssCckMode40Mhz =
+			lim_get_ht_capability(pMac, eHT_DSSS_CCK_MODE_40MHZ,
+					      psessionEntry);
+		pAddStaParams->fShortGI20Mhz =
+			lim_get_ht_capability(pMac, eHT_SHORT_GI_20MHZ,
+					psessionEntry);
+		pAddStaParams->fShortGI40Mhz =
+			lim_get_ht_capability(pMac, eHT_SHORT_GI_40MHZ,
+					psessionEntry);
+	}
+
+	listenInterval = pMac->mlme_cfg->sap_cfg.listen_interval;
+	pAddStaParams->listenInterval = (uint16_t) listenInterval;
+
+	wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode);
+	pAddStaParams->encryptType = psessionEntry->encryptType;
+	pAddStaParams->maxTxPower = psessionEntry->maxTxPower;
+
+	/* Lets save this for when we receive the Reassoc Rsp */
+	psessionEntry->ftPEContext.pAddStaReq = pAddStaParams;
+
+	if (pAddBssParams != NULL) {
+		qdf_mem_free(pAddBssParams);
+		pAddBssParams = NULL;
+		limMsgQ->bodyptr = NULL;
+	}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (psessionEntry->bRoamSynchInProgress) {
+		pe_debug("LFR3:Prep and save AddStaReq for post-assoc-rsp");
+		lim_process_assoc_rsp_frame(pMac, pMac->roam.pReassocResp,
+					    LIM_REASSOC, psessionEntry);
+	}
+#endif
+	return;
+
+end:
+	/* Free up buffer allocated for reassocReq */
+	if (psessionEntry != NULL)
+		if (psessionEntry->pLimMlmReassocReq != NULL) {
+			qdf_mem_free(psessionEntry->pLimMlmReassocReq);
+			psessionEntry->pLimMlmReassocReq = NULL;
+		}
+
+	if (pAddBssParams != NULL) {
+		qdf_mem_free(pAddBssParams);
+		pAddBssParams = NULL;
+		limMsgQ->bodyptr = NULL;
+	}
+
+	mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
+	mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+	/* Update PE session Id */
+	if (psessionEntry != NULL)
+		mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+	else
+		mlmReassocCnf.sessionId = 0;
+
+	lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+			     (uint32_t *) &mlmReassocCnf);
+}
+
+void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac,
+				    tLimMlmReassocReq *reassoc_req)
+{
+	uint8_t chanNum = 0;
+	tpPESession session;
+	uint16_t caps;
+	uint32_t val;
+	struct scheduler_msg msgQ = {0};
+	QDF_STATUS retCode;
+	uint32_t teleBcnEn = 0;
+
+	if (!reassoc_req) {
+		pe_err("reassoc_req is NULL");
+		return;
+	}
+
+	session = pe_find_session_by_session_id(pMac, reassoc_req->sessionId);
+	if (!session) {
+		pe_err("session Does not exist for given session Id");
+		qdf_mem_free(reassoc_req);
+		return;
+	}
+
+	chanNum = session->currentOperChannel;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_REASSOCIATING,
+			session, 0, 0);
+#endif
+
+	/* Nothing to be done if the session is not in STA mode */
+	if (!LIM_IS_STA_ROLE(session)) {
+		pe_err("psessionEntry is not in STA mode");
+		qdf_mem_free(reassoc_req);
+		return;
+	}
+
+	if (NULL == session->ftPEContext.pAddBssReq) {
+		pe_err("pAddBssReq is NULL");
+		return;
+	}
+
+	qdf_mem_copy(reassoc_req->peerMacAddr,
+		     session->bssId, sizeof(tSirMacAddr));
+
+	if (cfg_get_capability_info(pMac, &caps, session) !=
+			QDF_STATUS_SUCCESS) {
+		/**
+		 * Could not get Capabilities value
+		 * from CFG. Log error.
+		 */
+		pe_err("could not get Capabilities value");
+		qdf_mem_free(reassoc_req);
+		return;
+	}
+
+	lim_update_caps_info_for_bss(pMac, &caps,
+		session->pLimReAssocReq->bssDescription.capabilityInfo);
+	pe_debug("Capabilities info FT Reassoc: 0x%X", caps);
+
+	reassoc_req->capabilityInfo = caps;
+
+	/* If telescopic beaconing is enabled, set listen interval
+	   to CFG_TELE_BCN_MAX_LI
+	 */
+	teleBcnEn = pMac->mlme_cfg->sap_cfg.tele_bcn_wakeup_en;
+	if (teleBcnEn)
+		val = pMac->mlme_cfg->sap_cfg.tele_bcn_max_li;
+	else
+		val = pMac->mlme_cfg->sap_cfg.listen_interval;
+
+	if (lim_set_link_state
+		    (pMac, eSIR_LINK_PREASSOC_STATE, session->bssId,
+		    session->selfMacAddr, NULL, NULL) != QDF_STATUS_SUCCESS) {
+		qdf_mem_free(reassoc_req);
+		return;
+	}
+
+	reassoc_req->listenInterval = (uint16_t) val;
+	session->pLimMlmReassocReq = reassoc_req;
+
+	/* we need to defer the message until we get response back from HAL */
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+	msgQ.type = SIR_HAL_ADD_BSS_REQ;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = session->ftPEContext.pAddBssReq;
+	msgQ.bodyval = 0;
+
+	pe_debug("Sending SIR_HAL_ADD_BSS_REQ");
+	MTRACE(mac_trace_msg_tx(pMac, session->peSessionId, msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		qdf_mem_free(session->ftPEContext.pAddBssReq);
+		pe_err("Posting ADD_BSS_REQ to HAL failed, reason: %X",
+			retCode);
+	}
+
+	session->ftPEContext.pAddBssReq = NULL;
+	return;
+}
+
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
new file mode 100644
index 0000000..e477f3b
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
@@ -0,0 +1,2639 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#include "cds_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "sir_api.h"
+#include "sir_params.h"
+#include "cfg_api.h"
+#include "cfg_ucfg_api.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_security_utils.h"
+#include "lim_send_messages.h"
+#include "lim_send_messages.h"
+#include "lim_session_utils.h"
+#include <lim_ft.h>
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+#include "host_diag_core_log.h"
+#endif
+#include "wma_if.h"
+#include "wlan_reg_services_api.h"
+#include "lim_process_fils.h"
+#include "wlan_mlme_public_struct.h"
+
+static void lim_process_mlm_auth_req(tpAniSirGlobal, uint32_t *);
+static void lim_process_mlm_assoc_req(tpAniSirGlobal, uint32_t *);
+static void lim_process_mlm_disassoc_req(tpAniSirGlobal, uint32_t *);
+static void lim_process_mlm_set_keys_req(tpAniSirGlobal, uint32_t *);
+
+/* MLM Timeout event handler templates */
+static void lim_process_auth_rsp_timeout(tpAniSirGlobal, uint32_t);
+static void lim_process_periodic_join_probe_req_timer(tpAniSirGlobal);
+static void lim_process_auth_retry_timer(tpAniSirGlobal);
+
+/**
+ * lim_process_sae_auth_timeout() - This function is called to process sae
+ * auth timeout
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * @Return: None
+ */
+static void lim_process_sae_auth_timeout(tpAniSirGlobal mac_ctx)
+{
+	tpPESession session;
+
+	session = pe_find_session_by_session_id(mac_ctx,
+			mac_ctx->lim.limTimers.sae_auth_timer.sessionId);
+	if (session == NULL) {
+		pe_err("Session does not exist for given session id");
+		return;
+	}
+
+	pe_warn("SAE auth timeout sessionid %d mlmstate %X SmeState %X",
+		session->peSessionId, session->limMlmState,
+		session->limSmeState);
+
+	switch (session->limMlmState) {
+	case eLIM_MLM_WT_SAE_AUTH_STATE:
+		/*
+		 * SAE authentication is not completed. Restore from
+		 * auth state.
+		 */
+		if (session->pePersona == QDF_STA_MODE)
+			lim_restore_from_auth_state(mac_ctx,
+				eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,
+				eSIR_MAC_UNSPEC_FAILURE_REASON, session);
+		break;
+	default:
+		/* SAE authentication is timed out in unexpected state */
+		pe_err("received unexpected SAE auth timeout in state %X",
+			session->limMlmState);
+		lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
+		break;
+	}
+}
+
+/**
+ * lim_process_mlm_req_messages() - process mlm request messages
+ * @mac_ctx: global MAC context
+ * @msg: mlm request message
+ *
+ * This function is called by lim_post_mlm_message(). This
+ * function handles MLM primitives invoked by SME.
+ * Depending on the message type, corresponding function will be
+ * called.
+ * ASSUMPTIONS:
+ * 1. Upon receiving Beacon in WT_JOIN_STATE, MLM module invokes
+ *    APIs exposed by Beacon Processing module for setting parameters
+ *    at MAC hardware.
+ * 2. If attempt to Reassociate with an AP fails, link with current
+ *    AP is restored back.
+ *
+ * Return: None
+ */
+void lim_process_mlm_req_messages(tpAniSirGlobal mac_ctx,
+				  struct scheduler_msg *msg)
+{
+	switch (msg->type) {
+	case LIM_MLM_AUTH_REQ:
+		lim_process_mlm_auth_req(mac_ctx, msg->bodyptr);
+		break;
+	case LIM_MLM_ASSOC_REQ:
+		lim_process_mlm_assoc_req(mac_ctx, msg->bodyptr);
+		break;
+	case LIM_MLM_REASSOC_REQ:
+		lim_process_mlm_reassoc_req(mac_ctx, msg->bodyptr);
+		break;
+	case LIM_MLM_DISASSOC_REQ:
+		lim_process_mlm_disassoc_req(mac_ctx, msg->bodyptr);
+		break;
+	case LIM_MLM_SETKEYS_REQ:
+		lim_process_mlm_set_keys_req(mac_ctx, msg->bodyptr);
+		break;
+	case SIR_LIM_JOIN_FAIL_TIMEOUT:
+		lim_process_join_failure_timeout(mac_ctx);
+		break;
+	case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT:
+		lim_process_periodic_join_probe_req_timer(mac_ctx);
+		break;
+	case SIR_LIM_AUTH_FAIL_TIMEOUT:
+		lim_process_auth_failure_timeout(mac_ctx);
+		break;
+	case SIR_LIM_AUTH_RSP_TIMEOUT:
+		lim_process_auth_rsp_timeout(mac_ctx, msg->bodyval);
+		break;
+	case SIR_LIM_ASSOC_FAIL_TIMEOUT:
+		lim_process_assoc_failure_timeout(mac_ctx, msg->bodyval);
+		break;
+	case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
+		lim_process_ft_preauth_rsp_timeout(mac_ctx);
+		break;
+	case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
+		lim_convert_active_channel_to_passive_channel(mac_ctx);
+		break;
+	case SIR_LIM_DISASSOC_ACK_TIMEOUT:
+		lim_process_disassoc_ack_timeout(mac_ctx);
+		break;
+	case SIR_LIM_DEAUTH_ACK_TIMEOUT:
+		lim_process_deauth_ack_timeout(mac_ctx);
+		break;
+	case SIR_LIM_AUTH_RETRY_TIMEOUT:
+		lim_process_auth_retry_timer(mac_ctx);
+		break;
+	case SIR_LIM_AUTH_SAE_TIMEOUT:
+		lim_process_sae_auth_timeout(mac_ctx);
+		break;
+	case LIM_MLM_TSPEC_REQ:
+	default:
+		break;
+	} /* switch (msg->type) */
+}
+
+/**
+ * lim_change_channel_with_callback() - change channel and register callback
+ * @mac_ctx: global MAC context
+ * @new_chan: new channel to switch
+ * @callback: Callback function
+ * @cbdata: callback data
+ * @session_entry: PE session pointer
+ *
+ * This function is called to change channel and perform off channel operation
+ * if required. The caller registers a callback to be called at the end of the
+ * channel change.
+ *
+ * Return: None
+ */
+void
+lim_change_channel_with_callback(tpAniSirGlobal mac_ctx, uint8_t new_chan,
+				 CHANGE_CHANNEL_CALLBACK callback,
+				 uint32_t *cbdata, tpPESession session_entry)
+{
+	pe_debug("Switching channel to %d", new_chan);
+	session_entry->channelChangeReasonCode =
+		LIM_SWITCH_CHANNEL_OPERATION;
+
+	mac_ctx->lim.gpchangeChannelCallback = callback;
+	mac_ctx->lim.gpchangeChannelData = cbdata;
+
+	lim_send_switch_chnl_params(mac_ctx, new_chan, 0, 0,
+		CH_WIDTH_20MHZ, session_entry->maxTxPower,
+		session_entry->peSessionId, false, 0, 0);
+
+	return;
+}
+
+/**
+ * lim_covert_channel_scan_type() - switch between ACTIVE and PASSIVE scan type
+ * @mac_ctx: global MAC context
+ * @chan_num: channel number to change the scan type
+ * @passive_to_active: flag to indicate if switch allowed
+ *
+ * This function is called to get the list,
+ * change the channel type and set again.
+ * NOTE: If a channel is ACTIVE, this function will make it as PASSIVE
+ *       If a channel is PASSIVE, this function will make it as ACTIVE
+ *
+ * Return: None
+ */
+
+void lim_covert_channel_scan_type(tpAniSirGlobal mac_ctx, uint8_t chan_num,
+				  bool passive_to_active)
+{
+
+	uint32_t i;
+	uint8_t chan_pair[WNI_CFG_SCAN_CONTROL_LIST_LEN];
+	uint32_t len = WNI_CFG_SCAN_CONTROL_LIST_LEN;
+	QDF_STATUS status;
+
+	status  = wlan_cfg_get_str(mac_ctx, WNI_CFG_SCAN_CONTROL_LIST,
+				   chan_pair, &len);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("Unable to get scan control list");
+		return;
+	}
+	if (len > WNI_CFG_SCAN_CONTROL_LIST_LEN) {
+		pe_err("Invalid scan control list length: %d", len);
+		return;
+	}
+	for (i = 0; (i + 1) < len; i += 2) {
+		if (chan_pair[i] != chan_num) /* skip this channel */
+			continue;
+		if ((eSIR_PASSIVE_SCAN == chan_pair[i + 1]) &&
+		     true == passive_to_active) {
+			pe_debug("Channel %d changed from Passive to Active",
+				chan_num);
+			chan_pair[i + 1] = eSIR_ACTIVE_SCAN;
+			break;
+		}
+		if ((eSIR_ACTIVE_SCAN == chan_pair[i + 1]) &&
+		     false == passive_to_active) {
+			pe_debug("Channel %d changed from Active to Passive",
+				chan_num);
+			chan_pair[i + 1] = eSIR_PASSIVE_SCAN;
+			break;
+		}
+	}
+
+	cfg_set_str_notify(mac_ctx, WNI_CFG_SCAN_CONTROL_LIST,
+			   (uint8_t *) chan_pair, len, false);
+	return;
+}
+
+/**
+ * lim_set_dfs_channel_list() - convert dfs channel list to active channel list
+ * @mac_ctx: global MAC context.
+ * @chan_num: channel number
+ * @dfs_ch_list: list of DFS channels
+ *
+ * This function is called to convert DFS channel list to active channel list
+ * when any beacon is present on that channel. This function store time for
+ * passive channels which help to know that for how much time channel has been
+ * passive.
+ *
+ * NOTE: If a channel is ACTIVE, it won't store any time
+ *       If a channel is PAssive, it will store time as timestamp
+ *
+ * Return: None
+ */
+void lim_set_dfs_channel_list(tpAniSirGlobal mac_ctx, uint8_t chan_num,
+			      tSirDFSChannelList *dfs_ch_list)
+{
+	bool pass_to_active = true;
+
+	if (!((1 <= chan_num) && (165 >= chan_num))) {
+		pe_err("Invalid Channel: %d", chan_num);
+		return;
+	}
+
+	if (lim_isconnected_on_dfs_channel(mac_ctx, chan_num)) {
+		if (dfs_ch_list->timeStamp[chan_num] == 0) {
+			/*
+			 * Received first beacon;
+			 * Convert DFS channel to Active channel.
+			 */
+			pe_debug("Received first beacon on DFS channel: %d",
+				chan_num);
+			lim_covert_channel_scan_type(mac_ctx, chan_num,
+						     pass_to_active);
+		}
+		dfs_ch_list->timeStamp[chan_num] =
+					qdf_mc_timer_get_system_time();
+	} else {
+		return;
+	}
+
+	if (!tx_timer_running
+		    (&mac_ctx->lim.limTimers.gLimActiveToPassiveChannelTimer)) {
+		tx_timer_activate(
+		    &mac_ctx->lim.limTimers.gLimActiveToPassiveChannelTimer);
+	}
+
+	return;
+}
+
+/**
+ * mlm_add_sta() - MLM add sta
+ * @mac_ctx: global MAC context
+ * @sta_param: Add sta params
+ * @bssid: BSSID
+ * @ht_capable: HT capability
+ * @session_entry: PE session entry
+ *
+ * This function is called to update station parameters
+ *
+ * Return: None
+ */
+static void mlm_add_sta(tpAniSirGlobal mac_ctx, tpAddStaParams sta_param,
+		uint8_t *bssid, uint8_t ht_capable, tpPESession session_entry)
+{
+	uint32_t val;
+	uint32_t self_dot11mode = 0;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_dot11mode);
+	sta_param->staType = STA_ENTRY_SELF; /* Identifying self */
+
+	qdf_mem_copy(sta_param->bssId, bssid, sizeof(tSirMacAddr));
+	qdf_mem_copy(sta_param->staMac, session_entry->selfMacAddr,
+		     sizeof(tSirMacAddr));
+
+	/* Configuration related parameters to be changed to support BT-AMP */
+
+	val = mac_ctx->mlme_cfg->sap_cfg.listen_interval;
+	sta_param->listenInterval = (uint16_t) val;
+
+	sta_param->shortPreambleSupported =
+		mac_ctx->mlme_cfg->ht_caps.short_preamble;
+
+	sta_param->assocId = 0;      /* Is SMAC OK with this? */
+	sta_param->wmmEnabled = 0;
+	sta_param->uAPSD = 0;
+	sta_param->maxSPLen = 0;
+	sta_param->us32MaxAmpduDuration = 0;
+	sta_param->maxAmpduSize = 0; /* 0: 8k, 1: 16k,2: 32k,3: 64k, 4:128k */
+
+	/* For Self STA get the LDPC capability from config.ini */
+	sta_param->htLdpcCapable =
+		(session_entry->txLdpcIniFeatureEnabled & 0x01);
+	sta_param->vhtLdpcCapable =
+		((session_entry->txLdpcIniFeatureEnabled >> 1) & 0x01);
+
+	if (IS_DOT11_MODE_HT(session_entry->dot11mode)) {
+		sta_param->htCapable = ht_capable;
+		sta_param->greenFieldCapable =
+			lim_get_ht_capability(mac_ctx, eHT_GREENFIELD,
+					      session_entry);
+		sta_param->ch_width =
+			lim_get_ht_capability(mac_ctx,
+				eHT_SUPPORTED_CHANNEL_WIDTH_SET, session_entry);
+		sta_param->mimoPS =
+			(tSirMacHTMIMOPowerSaveState)lim_get_ht_capability(
+				mac_ctx, eHT_MIMO_POWER_SAVE, session_entry);
+		sta_param->rifsMode =
+			lim_get_ht_capability(mac_ctx, eHT_RIFS_MODE,
+					      session_entry);
+		sta_param->lsigTxopProtection =
+			lim_get_ht_capability(mac_ctx, eHT_LSIG_TXOP_PROTECTION,
+					      session_entry);
+		sta_param->maxAmpduDensity =
+			lim_get_ht_capability(mac_ctx, eHT_MPDU_DENSITY,
+					      session_entry);
+		sta_param->maxAmsduSize =
+			lim_get_ht_capability(mac_ctx, eHT_MAX_AMSDU_LENGTH,
+					      session_entry);
+		sta_param->max_amsdu_num =
+			lim_get_ht_capability(mac_ctx, eHT_MAX_AMSDU_NUM,
+					      session_entry);
+		sta_param->fDsssCckMode40Mhz =
+			lim_get_ht_capability(mac_ctx, eHT_DSSS_CCK_MODE_40MHZ,
+					      session_entry);
+		sta_param->fShortGI20Mhz =
+			lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_20MHZ,
+					      session_entry);
+		sta_param->fShortGI40Mhz =
+			lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_40MHZ,
+					      session_entry);
+	}
+	if (session_entry->vhtCapability) {
+		sta_param->vhtCapable = true;
+		sta_param->vhtTxBFCapable =
+				session_entry->vht_config.su_beam_formee;
+		sta_param->vhtTxMUBformeeCapable =
+				session_entry->vht_config.mu_beam_formee;
+		sta_param->enable_su_tx_bformer =
+				session_entry->vht_config.su_beam_former;
+	}
+
+	if (lim_is_session_he_capable(session_entry))
+		lim_add_self_he_cap(sta_param, session_entry);
+
+	/*
+	 * Since this is Self-STA, need to populate Self MAX_AMPDU_SIZE
+	 * capabilities
+	 */
+	if (IS_DOT11_MODE_VHT(self_dot11mode)) {
+		sta_param->maxAmpduSize =
+		mac_ctx->mlme_cfg->vht_caps.vht_cap_info.ampdu_len_exponent;
+	}
+	sta_param->enableVhtpAid = session_entry->enableVhtpAid;
+	sta_param->enableAmpduPs = session_entry->enableAmpduPs;
+	sta_param->enableHtSmps = session_entry->enableHtSmps;
+	sta_param->htSmpsconfig = session_entry->htSmpsvalue;
+	sta_param->send_smps_action = session_entry->send_smps_action;
+
+	lim_populate_own_rate_set(mac_ctx, &sta_param->supportedRates, NULL,
+				  false, session_entry, NULL, NULL);
+
+	pe_debug("GF: %d, ChnlWidth: %d, MimoPS: %d, lsigTXOP: %d, dsssCCK: %d,"
+		" SGI20: %d, SGI40%d", sta_param->greenFieldCapable,
+		sta_param->ch_width, sta_param->mimoPS,
+		sta_param->lsigTxopProtection, sta_param->fDsssCckMode40Mhz,
+		sta_param->fShortGI20Mhz, sta_param->fShortGI40Mhz);
+
+	if (QDF_P2P_GO_MODE == session_entry->pePersona)
+		sta_param->p2pCapableSta = 1;
+}
+
+/**
+ * lim_mlm_add_bss() - HAL interface for WMA_ADD_BSS_REQ
+ * @mac_ctx: global MAC context
+ * @mlm_start_req: MLM start request
+ * @session: PE session entry
+ *
+ * Package WMA_ADD_BSS_REQ to HAL, in order to start a BSS
+ *
+ * Return: eSIR_SME_SUCCESS on success, other error codes otherwise
+ */
+tSirResultCodes
+lim_mlm_add_bss(tpAniSirGlobal mac_ctx,
+		tLimMlmStartReq *mlm_start_req, tpPESession session)
+{
+	struct scheduler_msg msg_buf = {0};
+	tpAddBssParams addbss_param = NULL;
+	struct wlan_mlme_qos *qos_aggr = &mac_ctx->mlme_cfg->qos_mlme_params;
+	uint32_t retcode;
+	bool is_ch_dfs = false;
+
+	/* Package WMA_ADD_BSS_REQ message parameters */
+	addbss_param = qdf_mem_malloc(sizeof(tAddBssParams));
+	if (!addbss_param)
+		return eSIR_SME_RESOURCES_UNAVAILABLE;
+
+	/* Fill in tAddBssParams members */
+	qdf_mem_copy(addbss_param->bssId, mlm_start_req->bssId,
+		     sizeof(tSirMacAddr));
+
+	/* Fill in tAddBssParams selfMacAddr */
+	qdf_mem_copy(addbss_param->selfMacAddr,
+		     session->selfMacAddr, sizeof(tSirMacAddr));
+
+	addbss_param->bssType = mlm_start_req->bssType;
+	if (mlm_start_req->bssType == eSIR_IBSS_MODE)
+		addbss_param->operMode = BSS_OPERATIONAL_MODE_STA;
+	else if (mlm_start_req->bssType == eSIR_INFRA_AP_MODE)
+		addbss_param->operMode = BSS_OPERATIONAL_MODE_AP;
+	else if (mlm_start_req->bssType == eSIR_NDI_MODE)
+		addbss_param->operMode = BSS_OPERATIONAL_MODE_NDI;
+
+	addbss_param->shortSlotTimeSupported = session->shortSlotTimeSupported;
+	addbss_param->beaconInterval = mlm_start_req->beaconPeriod;
+	addbss_param->dtimPeriod = mlm_start_req->dtimPeriod;
+	addbss_param->wps_state = mlm_start_req->wps_state;
+	addbss_param->cfParamSet.cfpCount = mlm_start_req->cfParamSet.cfpCount;
+	addbss_param->cfParamSet.cfpPeriod =
+		mlm_start_req->cfParamSet.cfpPeriod;
+	addbss_param->cfParamSet.cfpMaxDuration =
+		mlm_start_req->cfParamSet.cfpMaxDuration;
+	addbss_param->cfParamSet.cfpDurRemaining =
+		mlm_start_req->cfParamSet.cfpDurRemaining;
+
+	addbss_param->rateSet.numRates = mlm_start_req->rateSet.numRates;
+	if (addbss_param->rateSet.numRates > SIR_MAC_RATESET_EID_MAX) {
+		pe_warn("num of sup rates %d exceeding the limit %d, resetting",
+			addbss_param->rateSet.numRates,
+			SIR_MAC_RATESET_EID_MAX);
+		addbss_param->rateSet.numRates = SIR_MAC_RATESET_EID_MAX;
+	}
+	qdf_mem_copy(addbss_param->rateSet.rate, mlm_start_req->rateSet.rate,
+		     addbss_param->rateSet.numRates);
+
+	addbss_param->nwType = mlm_start_req->nwType;
+	addbss_param->htCapable = mlm_start_req->htCapable;
+	addbss_param->vhtCapable = session->vhtCapability;
+	if (lim_is_session_he_capable(session)) {
+		lim_update_bss_he_capable(mac_ctx, addbss_param);
+		lim_decide_he_op(mac_ctx, addbss_param, session);
+		lim_update_usr_he_cap(mac_ctx, session);
+	}
+
+	addbss_param->ch_width = session->ch_width;
+	addbss_param->ch_center_freq_seg0 =
+		session->ch_center_freq_seg0;
+	addbss_param->ch_center_freq_seg1 =
+		session->ch_center_freq_seg1;
+	addbss_param->htOperMode = mlm_start_req->htOperMode;
+	addbss_param->dualCTSProtection = mlm_start_req->dualCTSProtection;
+	addbss_param->txChannelWidthSet = mlm_start_req->txChannelWidthSet;
+
+	addbss_param->currentOperChannel = mlm_start_req->channelNumber;
+#ifdef WLAN_FEATURE_11W
+	addbss_param->rmfEnabled = session->limRmfEnabled;
+#endif
+
+	/* Update PE sessionId */
+	addbss_param->sessionId = mlm_start_req->sessionId;
+
+	/* Send the SSID to HAL to enable SSID matching for IBSS */
+	addbss_param->ssId.length = mlm_start_req->ssId.length;
+	if (addbss_param->ssId.length > SIR_MAC_MAX_SSID_LENGTH) {
+		pe_err("Invalid ssid length %d, max length allowed %d",
+		       addbss_param->ssId.length,
+		       SIR_MAC_MAX_SSID_LENGTH);
+		qdf_mem_free(addbss_param);
+		return eSIR_SME_INVALID_PARAMETERS;
+	}
+	qdf_mem_copy(addbss_param->ssId.ssId,
+		     mlm_start_req->ssId.ssId, addbss_param->ssId.length);
+	addbss_param->bHiddenSSIDEn = mlm_start_req->ssidHidden;
+	pe_debug("TRYING TO HIDE SSID %d", addbss_param->bHiddenSSIDEn);
+	/* CR309183. Disable Proxy Probe Rsp.  Host handles Probe Requests.  Until FW fixed. */
+	addbss_param->bProxyProbeRespEn = 0;
+	addbss_param->obssProtEnabled = mlm_start_req->obssProtEnabled;
+
+	addbss_param->maxTxPower = session->maxTxPower;
+
+	mlm_add_sta(mac_ctx, &addbss_param->staContext,
+		    addbss_param->bssId, addbss_param->htCapable,
+		    session);
+
+	addbss_param->status = QDF_STATUS_SUCCESS;
+	addbss_param->respReqd = 1;
+
+	/* Set a new state for MLME */
+	session->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_STATE;
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
+			 session->limMlmState));
+
+	/* pass on the session persona to hal */
+	addbss_param->halPersona = session->pePersona;
+
+	if (session->ch_width == CH_WIDTH_160MHZ) {
+		is_ch_dfs = true;
+	} else if (session->ch_width == CH_WIDTH_80P80MHZ) {
+		if (wlan_reg_get_channel_state(mac_ctx->pdev,
+					mlm_start_req->channelNumber) ==
+				CHANNEL_STATE_DFS ||
+				wlan_reg_get_channel_state(mac_ctx->pdev,
+					session->ch_center_freq_seg1 -
+					SIR_80MHZ_START_CENTER_CH_DIFF) ==
+				CHANNEL_STATE_DFS)
+			is_ch_dfs = true;
+	} else {
+		if (wlan_reg_get_channel_state(mac_ctx->pdev,
+					mlm_start_req->channelNumber) ==
+				CHANNEL_STATE_DFS)
+			is_ch_dfs = true;
+	}
+
+	addbss_param->bSpectrumMgtEnabled =
+				session->spectrumMgtEnabled || is_ch_dfs;
+	addbss_param->extSetStaKeyParamValid = 0;
+
+	addbss_param->dot11_mode = session->dot11mode;
+	addbss_param->nss = session->nss;
+	addbss_param->cac_duration_ms = mlm_start_req->cac_duration_ms;
+	addbss_param->dfs_regdomain = mlm_start_req->dfs_regdomain;
+	addbss_param->beacon_tx_rate = session->beacon_tx_rate;
+	if (QDF_IBSS_MODE == addbss_param->halPersona) {
+		if (!(mac_ctx->mlme_cfg)) {
+			pe_err("Mlme cfg NULL");
+			return eSIR_SME_INVALID_PARAMETERS;
+		}
+		addbss_param->nss_2g = mac_ctx->vdev_type_nss_2g.ibss;
+		addbss_param->nss_5g = mac_ctx->vdev_type_nss_5g.ibss;
+		addbss_param->tx_aggregation_size =
+					qos_aggr->tx_aggregation_size;
+		addbss_param->tx_aggregation_size_be =
+					qos_aggr->tx_aggregation_size_be;
+		addbss_param->tx_aggregation_size_bk =
+					qos_aggr->tx_aggregation_size_bk;
+		addbss_param->tx_aggregation_size_vi =
+					qos_aggr->tx_aggregation_size_vi;
+		addbss_param->tx_aggregation_size_vo =
+					qos_aggr->tx_aggregation_size_vo;
+		addbss_param->rx_aggregation_size =
+					qos_aggr->rx_aggregation_size;
+	}
+	pe_debug("dot11_mode:%d nss value:%d",
+			addbss_param->dot11_mode, addbss_param->nss);
+
+	if (cds_is_5_mhz_enabled()) {
+		addbss_param->ch_width = CH_WIDTH_5MHZ;
+		addbss_param->staContext.ch_width = CH_WIDTH_5MHZ;
+	} else if (cds_is_10_mhz_enabled()) {
+		addbss_param->ch_width = CH_WIDTH_10MHZ;
+		addbss_param->staContext.ch_width = CH_WIDTH_10MHZ;
+	}
+
+	msg_buf.type = WMA_ADD_BSS_REQ;
+	msg_buf.reserved = 0;
+	msg_buf.bodyptr = addbss_param;
+	msg_buf.bodyval = 0;
+	MTRACE(mac_trace_msg_tx(mac_ctx, session->peSessionId, msg_buf.type));
+
+	pe_debug("Sending WMA_ADD_BSS_REQ...");
+	retcode = wma_post_ctrl_msg(mac_ctx, &msg_buf);
+	if (QDF_STATUS_SUCCESS != retcode) {
+		pe_err("Posting ADD_BSS_REQ to HAL failed, reason=%X",
+			retcode);
+		qdf_mem_free(addbss_param);
+		return eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+	}
+
+	return eSIR_SME_SUCCESS;
+}
+
+void lim_process_mlm_start_req(tpAniSirGlobal mac_ctx,
+			       tLimMlmStartReq *mlm_start_req)
+{
+	tLimMlmStartCnf mlm_start_cnf;
+	tpPESession session = NULL;
+
+	if (!mlm_start_req) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	session = pe_find_session_by_session_id(mac_ctx,
+				mlm_start_req->sessionId);
+	if (NULL == session) {
+		pe_err("Session Does not exist for given sessionID");
+		mlm_start_cnf.resultCode = eSIR_SME_REFUSED;
+		goto end;
+	}
+
+	if (session->limMlmState != eLIM_MLM_IDLE_STATE) {
+		/*
+		 * Should not have received Start req in states other than idle.
+		 * Return Start confirm with failure code.
+		 */
+		pe_err("received unexpected MLM_START_REQ in state %X",
+			session->limMlmState);
+		lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
+		mlm_start_cnf.resultCode =
+				eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+		goto end;
+	}
+
+	mlm_start_cnf.resultCode =
+		lim_mlm_add_bss(mac_ctx, mlm_start_req, session);
+
+end:
+	/* Update PE session Id */
+	mlm_start_cnf.sessionId = mlm_start_req->sessionId;
+
+	/*
+	 * Respond immediately to LIM, only if MLME has not been
+	 * successfully able to send WMA_ADD_BSS_REQ to HAL.
+	 * Else, LIM_MLM_START_CNF will be sent after receiving
+	 * WMA_ADD_BSS_RSP from HAL
+	 */
+	if (eSIR_SME_SUCCESS != mlm_start_cnf.resultCode)
+		lim_send_start_bss_confirm(mac_ctx, &mlm_start_cnf);
+}
+
+/**
+ * lim_post_join_set_link_state_callback()- registered callback to perform post
+ * peer creation operations
+ *
+ * @mac: pointer to global mac structure
+ * @callback_arg: registered callback argument
+ * @status: peer creation status
+ *
+ * this is registered callback function during association to perform
+ * post peer creation operation based on the peer creation status
+ *
+ * Return: none
+ */
+static void lim_post_join_set_link_state_callback(tpAniSirGlobal mac,
+		void *callback_arg, bool status)
+{
+	uint8_t chan_num, sec_chan_offset;
+	struct session_params *session_cb_param =
+					(struct session_params *)callback_arg;
+	tLimMlmJoinCnf mlm_join_cnf;
+
+	tpPESession session_entry = pe_find_session_by_session_id(mac,
+					session_cb_param->session_id);
+	if (!session_entry) {
+		pe_err("sessionId:%d does not exist",
+		       session_cb_param->session_id);
+		qdf_mem_free(session_cb_param);
+		return;
+	}
+
+	qdf_mem_free(session_cb_param);
+	pe_debug("Sessionid %d set link state(%d) cb status: %d",
+			session_entry->peSessionId, session_entry->limMlmState,
+			status);
+
+	if (!status) {
+		pe_err("failed to find pe session for session id:%d",
+			session_entry->peSessionId);
+		goto failure;
+	}
+
+	chan_num = session_entry->currentOperChannel;
+	sec_chan_offset = session_entry->htSecondaryChannelOffset;
+	/*
+	 * store the channel switch session_entry in the lim
+	 * global variable
+	 */
+	session_entry->channelChangeReasonCode =
+			 LIM_SWITCH_CHANNEL_JOIN;
+	session_entry->pLimMlmReassocRetryReq = NULL;
+	pe_debug("[lim_process_mlm_join_req]: suspend link success(%d) "
+		"on sessionid: %d setting channel to: %d with ch_width :%d "
+		"and maxtxPower: %d", status, session_entry->peSessionId,
+		session_entry->currentOperChannel,
+		session_entry->ch_width,
+		session_entry->maxTxPower);
+	lim_set_channel(mac, session_entry->currentOperChannel,
+		session_entry->ch_center_freq_seg0,
+		session_entry->ch_center_freq_seg1,
+		session_entry->ch_width,
+		session_entry->maxTxPower,
+		session_entry->peSessionId, 0, 0);
+	return;
+
+failure:
+	MTRACE(mac_trace(mac, TRACE_CODE_MLM_STATE, session_entry->peSessionId,
+			 session_entry->limMlmState));
+	session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
+	mlm_join_cnf.resultCode = eSIR_SME_PEER_CREATE_FAILED;
+	mlm_join_cnf.sessionId = session_entry->peSessionId;
+	mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+	lim_post_sme_message(mac, LIM_MLM_JOIN_CNF, (uint32_t *) &mlm_join_cnf);
+}
+
+/**
+ * lim_process_mlm_post_join_suspend_link() - This function is called after the
+ * suspend link while joining off channel.
+ *
+ * @mac_ctx:    Pointer to Global MAC structure
+ * @status:  status of suspend link.
+ * @ctx:     passed while calling suspend link(session)
+ *
+ * This function does following:
+ *   Check for suspend state.
+ *   If success, proceed with setting link state to receive the
+ *   probe response/beacon from intended AP.
+ *   Switch to the APs channel.
+ *   On an error case, send the MLM_JOIN_CNF with error status.
+ *
+ * @Return None
+ */
+static void
+lim_process_mlm_post_join_suspend_link(tpAniSirGlobal mac_ctx,
+				       QDF_STATUS status,
+				       uint32_t *ctx)
+{
+	tLimMlmJoinCnf mlm_join_cnf;
+	tpPESession session = (tpPESession) ctx;
+	tSirLinkState lnk_state;
+	struct session_params *pe_session_param = NULL;
+
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("Sessionid %d Suspend link(NOTIFY_BSS) failed. Still proceeding with join",
+			session->peSessionId);
+	}
+	lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);
+
+	/* assign appropriate sessionId to the timer object */
+	mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId =
+		session->peSessionId;
+
+	lnk_state = eSIR_LINK_PREASSOC_STATE;
+	pe_debug("[lim_process_mlm_join_req]: lnk_state: %d",
+		lnk_state);
+
+	pe_session_param = qdf_mem_malloc(sizeof(struct session_params));
+	if (!pe_session_param)
+		goto error;
+
+	pe_session_param->session_id = session->peSessionId;
+	if (lim_set_link_state(mac_ctx, lnk_state,
+			session->pLimMlmJoinReq->bssDescription.bssId,
+			session->selfMacAddr,
+			lim_post_join_set_link_state_callback,
+			pe_session_param) != QDF_STATUS_SUCCESS) {
+		pe_err("SessionId:%d lim_set_link_state to eSIR_LINK_PREASSOC_STATE Failed!!",
+			session->peSessionId);
+		lim_print_mac_addr(mac_ctx,
+			session->pLimMlmJoinReq->bssDescription.bssId, LOGE);
+		mlm_join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+		session->limMlmState = eLIM_MLM_IDLE_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+				 session->peSessionId, session->limMlmState));
+		qdf_mem_free(pe_session_param);
+		goto error;
+	}
+
+	return;
+error:
+	mlm_join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+	mlm_join_cnf.sessionId = session->peSessionId;
+	mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+	lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
+			     (uint32_t *) &mlm_join_cnf);
+}
+
+/**
+ * lim_process_mlm_join_req() - process mlm join request.
+ *
+ * @mac_ctx:    Pointer to Global MAC structure
+ * @mlm_join_req:        Pointer to the mlme join request
+ *
+ * This function is called to process MLM_JOIN_REQ message
+ * from SME. It does following:
+ * 1) Initialize LIM, HAL, DPH
+ * 2) Configure the BSS for which the JOIN REQ was received
+ *   a) Send WMA_ADD_BSS_REQ to HAL -
+ *   This will identify the BSS that we are interested in
+ *   --AND--
+ *   Add a STA entry for the AP (in a STA context)
+ *   b) Wait for WMA_ADD_BSS_RSP
+ *   c) Send WMA_ADD_STA_REQ to HAL
+ *   This will add the "local STA" entry to the STA table
+ * 3) Continue as before, i.e,
+ *   a) Send a PROBE REQ
+ *   b) Wait for PROBE RSP/BEACON containing the SSID that
+ *   we are interested in
+ *   c) Then start an AUTH seq
+ *   d) Followed by the ASSOC seq
+ *
+ * @Return: None
+ */
+void lim_process_mlm_join_req(tpAniSirGlobal mac_ctx,
+			      tLimMlmJoinReq *mlm_join_req)
+{
+	tLimMlmJoinCnf mlmjoin_cnf;
+	uint8_t sessionid;
+	tpPESession session;
+
+	sessionid = mlm_join_req->sessionId;
+
+	session = pe_find_session_by_session_id(mac_ctx, sessionid);
+	if (NULL == session) {
+		pe_err("SessionId:%d does not exist", sessionid);
+		goto error;
+	}
+
+	if (!LIM_IS_AP_ROLE(session) &&
+	     ((session->limMlmState == eLIM_MLM_IDLE_STATE) ||
+	     (session->limMlmState == eLIM_MLM_JOINED_STATE)) &&
+	     (SIR_MAC_GET_ESS
+		(mlm_join_req->bssDescription.capabilityInfo) !=
+		SIR_MAC_GET_IBSS(mlm_join_req->bssDescription.
+			capabilityInfo))) {
+		/* Hold onto Join request parameters */
+
+		session->pLimMlmJoinReq = mlm_join_req;
+		if (is_lim_session_off_channel(mac_ctx, sessionid)) {
+			pe_debug("SessionId:%d LimSession is on OffChannel",
+				sessionid);
+			/* suspend link */
+			pe_debug("Suspend link, sessionid %d is off channel",
+				sessionid);
+			lim_process_mlm_post_join_suspend_link(mac_ctx,
+				QDF_STATUS_SUCCESS, (uint32_t *)session);
+		} else {
+			pe_debug("No need to Suspend link");
+			 /*
+			  * No need to Suspend link as LimSession is not
+			  * off channel, calling
+			  * lim_process_mlm_post_join_suspend_link with
+			  * status as SUCCESS.
+			  */
+			pe_debug("SessionId:%d Join req on current chan",
+				sessionid);
+			lim_process_mlm_post_join_suspend_link(mac_ctx,
+				QDF_STATUS_SUCCESS, (uint32_t *)session);
+		}
+		return;
+	} else {
+		/**
+		 * Should not have received JOIN req in states other than
+		 * Idle state or on AP.
+		 * Return join confirm with invalid parameters code.
+		 */
+		pe_err("Session:%d Unexpected Join req, role %d state %X",
+			session->peSessionId, GET_LIM_SYSTEM_ROLE(session),
+			session->limMlmState);
+		lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
+	}
+
+error:
+	qdf_mem_free(mlm_join_req);
+	if (session != NULL)
+		session->pLimMlmJoinReq = NULL;
+	mlmjoin_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+	mlmjoin_cnf.sessionId = sessionid;
+	mlmjoin_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+	lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
+		(uint32_t *)&mlmjoin_cnf);
+
+}
+
+/**
+ * lim_is_auth_req_expected() - check if auth request is expected
+ *
+ * @mac_ctx: global MAC context
+ * @session: PE session entry
+ *
+ * This function is called by lim_process_mlm_auth_req to check
+ * if auth request is expected.
+ *
+ * Return: true if expected and false otherwise
+ */
+static bool lim_is_auth_req_expected(tpAniSirGlobal mac_ctx,
+				     tpPESession session)
+{
+	bool flag = false;
+
+	/*
+	 * Expect Auth request only when:
+	 * 1. STA joined/associated with a BSS or
+	 * 2. STA is in IBSS mode
+	 * and STA is going to authenticate with a unicast
+	 * address and requested authentication algorithm is
+	 * supported.
+	 */
+
+	flag = (((LIM_IS_STA_ROLE(session) &&
+		 ((session->limMlmState == eLIM_MLM_JOINED_STATE) ||
+		  (session->limMlmState ==
+					eLIM_MLM_LINK_ESTABLISHED_STATE))) ||
+		  (LIM_IS_IBSS_ROLE(session) &&
+		  (session->limMlmState ==
+					eLIM_MLM_BSS_STARTED_STATE))) &&
+		(!lim_is_group_addr(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr))
+		 && lim_is_auth_algo_supported(mac_ctx,
+			mac_ctx->lim.gpLimMlmAuthReq->authType, session));
+
+	return flag;
+}
+
+/**
+ * lim_is_preauth_ctx_exisits() - check if preauth context exists
+ *
+ * @mac_ctx:          global MAC context
+ * @session:          PE session entry
+ * @preauth_node_ptr: pointer to preauth node pointer
+ *
+ * This function is called by lim_process_mlm_auth_req to check
+ * if preauth context already exists
+ *
+ * Return: true if exists and false otherwise
+ */
+static bool lim_is_preauth_ctx_exists(tpAniSirGlobal mac_ctx,
+				      tpPESession session,
+				      struct tLimPreAuthNode **preauth_node_ptr)
+{
+	bool fl = false;
+	struct tLimPreAuthNode *preauth_node;
+	tpDphHashNode stads;
+	tSirMacAddr curr_bssid;
+
+	preauth_node = *preauth_node_ptr;
+	sir_copy_mac_addr(curr_bssid, session->bssId);
+	stads = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+				   &session->dph.dphHashTable);
+	preauth_node = lim_search_pre_auth_list(mac_ctx,
+				mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr);
+
+	fl = (((LIM_IS_STA_ROLE(session)) &&
+	       (session->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+	      ((stads != NULL) &&
+	       (mac_ctx->lim.gpLimMlmAuthReq->authType ==
+			stads->mlmStaContext.authType)) &&
+	       (!qdf_mem_cmp(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
+			curr_bssid, sizeof(tSirMacAddr)))) ||
+	      ((preauth_node != NULL) &&
+	       (preauth_node->authType ==
+			mac_ctx->lim.gpLimMlmAuthReq->authType)));
+
+	return fl;
+}
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * lim_process_mlm_auth_req_sae() - Handle SAE authentication
+ * @mac_ctx: global MAC context
+ * @session: PE session entry
+ *
+ * This function is called by lim_process_mlm_auth_req to handle SAE
+ * authentication.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS lim_process_mlm_auth_req_sae(tpAniSirGlobal mac_ctx,
+		tpPESession session)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct sir_sae_info *sae_info;
+	struct scheduler_msg msg = {0};
+
+	sae_info = qdf_mem_malloc(sizeof(*sae_info));
+	if (!sae_info)
+		return QDF_STATUS_E_FAILURE;
+
+	sae_info->msg_type = eWNI_SME_TRIGGER_SAE;
+	sae_info->msg_len = sizeof(*sae_info);
+	sae_info->vdev_id = session->smeSessionId;
+
+	qdf_mem_copy(sae_info->peer_mac_addr.bytes,
+		session->bssId,
+		QDF_MAC_ADDR_SIZE);
+
+	sae_info->ssid.length = session->ssId.length;
+	qdf_mem_copy(sae_info->ssid.ssId,
+		session->ssId.ssId,
+		session->ssId.length);
+
+	pe_debug("vdev_id %d ssid %.*s "MAC_ADDRESS_STR"",
+		sae_info->vdev_id,
+		sae_info->ssid.length,
+		sae_info->ssid.ssId,
+		MAC_ADDR_ARRAY(sae_info->peer_mac_addr.bytes));
+
+	msg.type = eWNI_SME_TRIGGER_SAE;
+	msg.bodyptr = sae_info;
+	msg.bodyval = 0;
+
+	qdf_status = mac_ctx->lim.sme_msg_callback(mac_ctx, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("SAE failed for AUTH frame");
+		qdf_mem_free(sae_info);
+		return qdf_status;
+	}
+	session->limMlmState = eLIM_MLM_WT_SAE_AUTH_STATE;
+
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
+		       session->limMlmState));
+
+	mac_ctx->lim.limTimers.sae_auth_timer.sessionId =
+					session->peSessionId;
+
+	/* Activate SAE auth timer */
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
+			 session->peSessionId, eLIM_AUTH_SAE_TIMER));
+	if (tx_timer_activate(&mac_ctx->lim.limTimers.sae_auth_timer)
+		    != TX_SUCCESS) {
+		pe_err("could not start Auth SAE timer");
+	}
+
+	return qdf_status;
+}
+#else
+static QDF_STATUS lim_process_mlm_auth_req_sae(tpAniSirGlobal mac_ctx,
+		tpPESession session)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+
+
+/**
+ * lim_process_mlm_auth_req() - process lim auth request
+ *
+ * @mac_ctx:   global MAC context
+ * @msg:       MLM auth request message
+ *
+ * This function is called to process MLM_AUTH_REQ message from SME
+ *
+ * @Return: None
+ */
+static void lim_process_mlm_auth_req(tpAniSirGlobal mac_ctx, uint32_t *msg)
+{
+	uint32_t num_preauth_ctx;
+	tSirMacAddr curr_bssid;
+	tSirMacAuthFrameBody auth_frame_body;
+	tLimMlmAuthCnf mlm_auth_cnf;
+	struct tLimPreAuthNode *preauth_node = NULL;
+	uint8_t session_id;
+	tpPESession session;
+
+	if (msg == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	mac_ctx->lim.gpLimMlmAuthReq = (tLimMlmAuthReq *) msg;
+	session_id = mac_ctx->lim.gpLimMlmAuthReq->sessionId;
+	session = pe_find_session_by_session_id(mac_ctx, session_id);
+	if (NULL == session) {
+		pe_err("SessionId:%d does not exist", session_id);
+		qdf_mem_free(msg);
+		mac_ctx->lim.gpLimMlmAuthReq = NULL;
+		return;
+	}
+
+	pe_debug("Process Auth Req sessionID %d Systemrole %d"
+		       "mlmstate %d from: " MAC_ADDRESS_STR
+		       " with authtype %d", session_id,
+		GET_LIM_SYSTEM_ROLE(session), session->limMlmState,
+		MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr),
+		mac_ctx->lim.gpLimMlmAuthReq->authType);
+
+	sir_copy_mac_addr(curr_bssid, session->bssId);
+
+	if (!lim_is_auth_req_expected(mac_ctx, session)) {
+		/*
+		 * Unexpected auth request.
+		 * Return Auth confirm with Invalid parameters code.
+		 */
+		mlm_auth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+		goto end;
+	}
+
+	/*
+	 * This is a request for pre-authentication. Check if there exists
+	 * context already for the requested peer OR
+	 * if this request is for the AP we're currently associated with.
+	 * If yes, return auth confirm immediately when
+	 * requested auth type is same as the one used before.
+	 */
+	if (lim_is_preauth_ctx_exists(mac_ctx, session, &preauth_node)) {
+		pe_debug("Already have pre-auth context with peer: "
+		    MAC_ADDRESS_STR,
+		    MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr));
+		mlm_auth_cnf.resultCode = (tSirResultCodes)
+						eSIR_MAC_SUCCESS_STATUS;
+		goto end;
+	} else {
+		num_preauth_ctx = mac_ctx->mlme_cfg->lfr.max_num_pre_auth;
+		if (mac_ctx->lim.gLimNumPreAuthContexts == num_preauth_ctx) {
+			pe_warn("Number of pre-auth reached max limit");
+			/* Return Auth confirm with reject code */
+			mlm_auth_cnf.resultCode =
+				eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED;
+			goto end;
+		}
+	}
+
+	/* Delete pre-auth node if exists */
+	if (preauth_node)
+		lim_delete_pre_auth_node(mac_ctx,
+			 mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr);
+
+	session->limPrevMlmState = session->limMlmState;
+
+	if ((mac_ctx->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) &&
+	     !session->sae_pmk_cached) {
+		if (lim_process_mlm_auth_req_sae(mac_ctx, session) !=
+					QDF_STATUS_SUCCESS) {
+			mlm_auth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+			goto end;
+		} else {
+			pe_debug("lim_process_mlm_auth_req_sae is successful");
+			lim_diag_event_report(mac_ctx,
+					      WLAN_PE_DIAG_AUTH_ALGO_NUM,
+					      session, QDF_STATUS_SUCCESS,
+					      eSIR_AUTH_TYPE_SAE);
+			return;
+		}
+	} else
+		session->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE;
+
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
+		       session->limMlmState));
+
+	/* Mark auth algo as open when auth type is SAE and PMK is cached */
+	if ((mac_ctx->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) &&
+	   session->sae_pmk_cached) {
+		auth_frame_body.authAlgoNumber = eSIR_OPEN_SYSTEM;
+	} else {
+		auth_frame_body.authAlgoNumber =
+		(uint8_t) mac_ctx->lim.gpLimMlmAuthReq->authType;
+	}
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ALGO_NUM, session,
+			      QDF_STATUS_SUCCESS, auth_frame_body.authAlgoNumber);
+
+	/* Prepare & send Authentication frame */
+	auth_frame_body.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
+	auth_frame_body.authStatusCode = 0;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_START_EVENT, session,
+			      QDF_STATUS_SUCCESS, auth_frame_body.authStatusCode);
+#endif
+	mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
+	lim_send_auth_mgmt_frame(mac_ctx,
+		&auth_frame_body, mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
+		LIM_NO_WEP_IN_FC, session);
+
+	/* assign appropriate session_id to the timer object */
+	mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId = session_id;
+
+	/* assign appropriate sessionId to the timer object */
+	 mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer.sessionId =
+								  session_id;
+	 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
+	/* Activate Auth failure timer */
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
+			 session->peSessionId, eLIM_AUTH_FAIL_TIMER));
+	 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_FAIL_TIMER);
+	if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAuthFailureTimer)
+	    != TX_SUCCESS) {
+		pe_err("could not start Auth failure timer");
+		/* Cleanup as if auth timer expired */
+		lim_process_auth_failure_timeout(mac_ctx);
+	} else {
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
+			   session->peSessionId, eLIM_AUTH_RETRY_TIMER));
+		/* Activate Auth Retry timer */
+		if (tx_timer_activate
+		    (&mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer)
+							      != TX_SUCCESS)
+			pe_err("could not activate Auth Retry timer");
+	}
+
+	return;
+end:
+	qdf_mem_copy((uint8_t *) &mlm_auth_cnf.peerMacAddr,
+		     (uint8_t *) &mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
+		     sizeof(tSirMacAddr));
+
+	mlm_auth_cnf.authType = mac_ctx->lim.gpLimMlmAuthReq->authType;
+	mlm_auth_cnf.sessionId = session_id;
+
+	qdf_mem_free(mac_ctx->lim.gpLimMlmAuthReq);
+	mac_ctx->lim.gpLimMlmAuthReq = NULL;
+	pe_debug("SessionId:%d LimPostSme LIM_MLM_AUTH_CNF",
+		session_id);
+	lim_post_sme_message(mac_ctx, LIM_MLM_AUTH_CNF,
+			     (uint32_t *) &mlm_auth_cnf);
+}
+
+/**
+ * lim_process_mlm_assoc_req() - This function is called to process
+ * MLM_ASSOC_REQ message from SME
+ *
+ * @mac_ctx:       Pointer to Global MAC structure
+ * @msg_buf:       A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_ASSOC_REQ message from SME
+ *
+ * @Return None
+ */
+
+static void lim_process_mlm_assoc_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+	tSirMacAddr curr_bssId;
+	tLimMlmAssocReq *mlm_assoc_req;
+	tLimMlmAssocCnf mlm_assoc_cnf;
+	tpPESession session_entry;
+
+	if (msg_buf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	mlm_assoc_req = (tLimMlmAssocReq *) msg_buf;
+	session_entry = pe_find_session_by_session_id(mac_ctx,
+						      mlm_assoc_req->sessionId);
+	if (session_entry == NULL) {
+		pe_err("SessionId:%d Session Does not exist",
+			mlm_assoc_req->sessionId);
+		qdf_mem_free(mlm_assoc_req);
+		return;
+	}
+
+	sir_copy_mac_addr(curr_bssId, session_entry->bssId);
+
+	if (!(!LIM_IS_AP_ROLE(session_entry) &&
+		(session_entry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE ||
+		 session_entry->limMlmState == eLIM_MLM_JOINED_STATE) &&
+		(!qdf_mem_cmp(mlm_assoc_req->peerMacAddr,
+		 curr_bssId, sizeof(tSirMacAddr))))) {
+		/*
+		 * Received Association request either in invalid state
+		 * or to a peer MAC entity whose address is different
+		 * from one that STA is currently joined with or on AP.
+		 * Return Assoc confirm with Invalid parameters code.
+		 */
+		pe_warn("received unexpected MLM_ASSOC_CNF in state %X for role=%d, MAC addr= "
+			   MAC_ADDRESS_STR, session_entry->limMlmState,
+			GET_LIM_SYSTEM_ROLE(session_entry),
+			MAC_ADDR_ARRAY(mlm_assoc_req->peerMacAddr));
+		lim_print_mlm_state(mac_ctx, LOGW, session_entry->limMlmState);
+		mlm_assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+		mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+		goto end;
+	}
+
+	/* map the session entry pointer to the AssocFailureTimer */
+	mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId =
+		mlm_assoc_req->sessionId;
+#ifdef WLAN_FEATURE_11W
+	/*
+	 * Store current MLM state in case ASSOC response returns with
+	 * TRY_AGAIN_LATER return code.
+	 */
+	if (session_entry->limRmfEnabled) {
+		session_entry->pmfComebackTimerInfo.limPrevMlmState =
+			session_entry->limPrevMlmState;
+		session_entry->pmfComebackTimerInfo.limMlmState =
+			session_entry->limMlmState;
+	}
+#endif /* WLAN_FEATURE_11W */
+
+	session_entry->limPrevMlmState = session_entry->limMlmState;
+	session_entry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE;
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+			 session_entry->peSessionId,
+			 session_entry->limMlmState));
+	pe_debug("SessionId:%d Sending Assoc_Req Frame",
+		session_entry->peSessionId);
+
+	/* Prepare and send Association request frame */
+	lim_send_assoc_req_mgmt_frame(mac_ctx, mlm_assoc_req, session_entry);
+
+	/* Start association failure timer */
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
+			 session_entry->peSessionId, eLIM_ASSOC_FAIL_TIMER));
+	if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAssocFailureTimer)
+	    != TX_SUCCESS) {
+		pe_warn("SessionId:%d couldn't start Assoc failure timer",
+			session_entry->peSessionId);
+		/* Cleanup as if assoc timer expired */
+		lim_process_assoc_failure_timeout(mac_ctx, LIM_ASSOC);
+	}
+
+	return;
+end:
+	/* Update PE session Id */
+	mlm_assoc_cnf.sessionId = mlm_assoc_req->sessionId;
+	/* Free up buffer allocated for assocReq */
+	qdf_mem_free(mlm_assoc_req);
+	lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
+			     (uint32_t *) &mlm_assoc_cnf);
+}
+
+/**
+ * lim_process_mlm_disassoc_req_ntf() - process disassoc request notification
+ *
+ * @mac_ctx:        global MAC context
+ * @suspend_status: suspend status
+ * @msg:            mlm message buffer
+ *
+ * This function is used to process MLM disassoc notification
+ *
+ * Return: None
+ */
+static void
+lim_process_mlm_disassoc_req_ntf(tpAniSirGlobal mac_ctx,
+				 QDF_STATUS suspend_status, uint32_t *msg)
+{
+	uint16_t aid;
+	struct qdf_mac_addr curr_bssid;
+	tpDphHashNode stads;
+	tLimMlmDisassocReq *mlm_disassocreq;
+	tLimMlmDisassocCnf mlm_disassoccnf;
+	tpPESession session;
+	extern bool send_disassoc_frame;
+	tLimMlmStates mlm_state;
+	tSirSmeDisassocRsp *sme_disassoc_rsp;
+
+	if (QDF_STATUS_SUCCESS != suspend_status)
+		pe_err("Suspend Status is not success %X",
+			suspend_status);
+
+	mlm_disassocreq = (tLimMlmDisassocReq *) msg;
+
+	session = pe_find_session_by_session_id(mac_ctx,
+				mlm_disassocreq->sessionId);
+	if (NULL == session) {
+		pe_err("session does not exist for given sessionId %d",
+			mlm_disassocreq->sessionId);
+		mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+		goto end;
+	}
+
+	pe_debug("Process DisAssoc Req on sessionID %d Systemrole %d"
+		   "mlmstate %d from: " MAC_ADDRESS_STR,
+		mlm_disassocreq->sessionId, GET_LIM_SYSTEM_ROLE(session),
+		session->limMlmState,
+		MAC_ADDR_ARRAY(mlm_disassocreq->peer_macaddr.bytes));
+
+	qdf_mem_copy(curr_bssid.bytes, session->bssId, QDF_MAC_ADDR_SIZE);
+
+	switch (GET_LIM_SYSTEM_ROLE(session)) {
+	case eLIM_STA_ROLE:
+		if (!qdf_is_macaddr_equal(&mlm_disassocreq->peer_macaddr,
+				     &curr_bssid)) {
+			pe_warn("received MLM_DISASSOC_REQ with invalid BSS id");
+			lim_print_mac_addr(mac_ctx,
+				mlm_disassocreq->peer_macaddr.bytes, LOGW);
+
+			/*
+			 * Disassociation response due to host triggered
+			 * disassociation
+			 */
+			sme_disassoc_rsp =
+				qdf_mem_malloc(sizeof(tSirSmeDisassocRsp));
+			if (!sme_disassoc_rsp) {
+				qdf_mem_free(mlm_disassocreq);
+				return;
+			}
+
+			pe_debug("send disassoc rsp with ret code %d for" MAC_ADDRESS_STR,
+				eSIR_SME_DEAUTH_STATUS,
+				MAC_ADDR_ARRAY(
+					mlm_disassocreq->peer_macaddr.bytes));
+
+			sme_disassoc_rsp->messageType = eWNI_SME_DISASSOC_RSP;
+			sme_disassoc_rsp->length = sizeof(tSirSmeDisassocRsp);
+			sme_disassoc_rsp->sessionId =
+					mlm_disassocreq->sessionId;
+			sme_disassoc_rsp->transactionId = 0;
+			sme_disassoc_rsp->statusCode = eSIR_SME_DEAUTH_STATUS;
+
+			qdf_copy_macaddr(&sme_disassoc_rsp->peer_macaddr,
+					 &mlm_disassocreq->peer_macaddr);
+			msg = (uint32_t *)sme_disassoc_rsp;
+
+			lim_send_sme_disassoc_deauth_ntf(mac_ctx,
+					QDF_STATUS_SUCCESS, msg);
+			qdf_mem_free(mlm_disassocreq);
+			return;
+
+		}
+		break;
+	case eLIM_STA_IN_IBSS_ROLE:
+		break;
+	case eLIM_AP_ROLE:
+	case eLIM_P2P_DEVICE_GO:
+		if (true ==
+			 mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+			pe_err("CAC timer is running, drop disassoc from going out");
+			mlm_disassoccnf.resultCode = eSIR_SME_SUCCESS;
+			goto end;
+		}
+		break;
+	default:
+		break;
+	} /* end switch (GET_LIM_SYSTEM_ROLE(session)) */
+
+	/*
+	 * Check if there exists a context for the peer entity
+	 * to be disassociated with.
+	 */
+	stads = dph_lookup_hash_entry(mac_ctx,
+				      mlm_disassocreq->peer_macaddr.bytes,
+				      &aid, &session->dph.dphHashTable);
+	if (stads)
+		mlm_state = stads->mlmStaContext.mlmState;
+
+	if ((stads == NULL) ||
+	    (stads &&
+	     ((mlm_state != eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+	      (mlm_state != eLIM_MLM_WT_ASSOC_CNF_STATE) &&
+	      (mlm_state != eLIM_MLM_ASSOCIATED_STATE)))) {
+		/*
+		 * Received LIM_MLM_DISASSOC_REQ for STA that does not
+		 * have context or in some transit state.
+		 */
+		pe_warn("Invalid MLM_DISASSOC_REQ, Addr= " MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(mlm_disassocreq->peer_macaddr.bytes));
+		if (stads != NULL)
+			pe_err("Sta MlmState: %d", stads->mlmStaContext.mlmState);
+
+		/* Prepare and Send LIM_MLM_DISASSOC_CNF */
+		mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+		goto end;
+	}
+
+	stads->mlmStaContext.disassocReason = (tSirMacReasonCodes)
+					       mlm_disassocreq->reasonCode;
+	stads->mlmStaContext.cleanupTrigger = mlm_disassocreq->disassocTrigger;
+
+	/*
+	 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
+	 * This is to address the issue of race condition between
+	 * disconnect request from the HDD and deauth from AP
+	 */
+
+	stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+
+	/* Send Disassociate frame to peer entity */
+	if (send_disassoc_frame && (mlm_disassocreq->reasonCode !=
+		eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
+		if (mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq) {
+			pe_err("pMlmDisassocReq is not NULL, freeing");
+			qdf_mem_free(mac_ctx->lim.limDisassocDeauthCnfReq.
+				     pMlmDisassocReq);
+		}
+		mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq =
+			mlm_disassocreq;
+		/*
+		 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
+		 * This is to address the issue of race condition between
+		 * disconnect request from the HDD and deauth from AP
+		 */
+		stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+
+		lim_send_disassoc_mgmt_frame(mac_ctx,
+			mlm_disassocreq->reasonCode,
+			mlm_disassocreq->peer_macaddr.bytes, session, true);
+		/*
+		 * Abort Tx so that data frames won't be sent to the AP
+		 * after sending Disassoc.
+		 */
+		if (LIM_IS_STA_ROLE(session))
+			wma_tx_abort(session->smeSessionId);
+	} else {
+		/* Disassoc frame is not sent OTA */
+		send_disassoc_frame = 1;
+		/* Receive path cleanup with dummy packet */
+		if (QDF_STATUS_SUCCESS !=
+		    lim_cleanup_rx_path(mac_ctx, stads, session)) {
+			mlm_disassoccnf.resultCode =
+				eSIR_SME_RESOURCES_UNAVAILABLE;
+			goto end;
+		}
+		/* Free up buffer allocated for mlmDisassocReq */
+		qdf_mem_free(mlm_disassocreq);
+	}
+
+	return;
+
+end:
+	qdf_mem_copy((uint8_t *) &mlm_disassoccnf.peerMacAddr,
+		     (uint8_t *) mlm_disassocreq->peer_macaddr.bytes,
+		     QDF_MAC_ADDR_SIZE);
+	mlm_disassoccnf.aid = mlm_disassocreq->aid;
+	mlm_disassoccnf.disassocTrigger = mlm_disassocreq->disassocTrigger;
+
+	/* Update PE session ID */
+	mlm_disassoccnf.sessionId = mlm_disassocreq->sessionId;
+
+	/* Free up buffer allocated for mlmDisassocReq */
+	qdf_mem_free(mlm_disassocreq);
+
+	lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
+			     (uint32_t *) &mlm_disassoccnf);
+}
+
+/**
+ * lim_check_disassoc_deauth_ack_pending() - check if deauth is pending
+ *
+ * @mac_ctx - global MAC context
+ * @sta_mac - station MAC
+ *
+ * This function checks if diassociation or deauthentication is pending for
+ * given station MAC address.
+ *
+ * Return: true if pending and false otherwise.
+ */
+bool lim_check_disassoc_deauth_ack_pending(tpAniSirGlobal mac_ctx,
+					   uint8_t *sta_mac)
+{
+	tLimMlmDisassocReq *disassoc_req;
+	tLimMlmDeauthReq *deauth_req;
+
+	disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
+	deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
+	if ((disassoc_req && (!qdf_mem_cmp((uint8_t *) sta_mac,
+			      (uint8_t *) &disassoc_req->peer_macaddr.bytes,
+			       QDF_MAC_ADDR_SIZE))) ||
+	    (deauth_req && (!qdf_mem_cmp((uint8_t *) sta_mac,
+			      (uint8_t *) &deauth_req->peer_macaddr.bytes,
+			       QDF_MAC_ADDR_SIZE)))) {
+		pe_debug("Disassoc/Deauth ack pending");
+		return true;
+	} else {
+		pe_debug("Disassoc/Deauth Ack not pending");
+		return false;
+	}
+}
+
+/*
+ * lim_clean_up_disassoc_deauth_req() - cleans up pending disassoc or deauth req
+ *
+ * @mac_ctx:        mac_ctx
+ * @sta_mac:        sta mac address
+ * @clean_rx_path:  flag to indicate whether to cleanup rx path or not
+ *
+ * This function cleans up pending disassoc or deauth req
+ *
+ * Return: void
+ */
+void lim_clean_up_disassoc_deauth_req(tpAniSirGlobal mac_ctx,
+				      uint8_t *sta_mac, bool clean_rx_path)
+{
+	tLimMlmDisassocReq *mlm_disassoc_req;
+	tLimMlmDeauthReq *mlm_deauth_req;
+
+	mlm_disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
+	if (mlm_disassoc_req &&
+	    (!qdf_mem_cmp((uint8_t *) sta_mac,
+			     (uint8_t *) &mlm_disassoc_req->peer_macaddr.bytes,
+			     QDF_MAC_ADDR_SIZE))) {
+		if (clean_rx_path) {
+			lim_process_disassoc_ack_timeout(mac_ctx);
+		} else {
+			if (tx_timer_running(
+				&mac_ctx->lim.limTimers.gLimDisassocAckTimer)) {
+				lim_deactivate_and_change_timer(mac_ctx,
+						eLIM_DISASSOC_ACK_TIMER);
+			}
+			qdf_mem_free(mlm_disassoc_req);
+			mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq =
+				NULL;
+		}
+	}
+
+	mlm_deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
+	if (mlm_deauth_req &&
+	    (!qdf_mem_cmp((uint8_t *) sta_mac,
+			     (uint8_t *) &mlm_deauth_req->peer_macaddr.bytes,
+			     QDF_MAC_ADDR_SIZE))) {
+		if (clean_rx_path) {
+			lim_process_deauth_ack_timeout(mac_ctx);
+		} else {
+			if (tx_timer_running(
+				&mac_ctx->lim.limTimers.gLimDeauthAckTimer)) {
+				lim_deactivate_and_change_timer(mac_ctx,
+						eLIM_DEAUTH_ACK_TIMER);
+			}
+			qdf_mem_free(mlm_deauth_req);
+			mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq =
+				NULL;
+		}
+	}
+}
+
+/*
+ * lim_process_disassoc_ack_timeout() - wrapper function around
+ * lim_send_disassoc_cnf
+ *
+ * @mac_ctx:        mac_ctx
+ *
+ * wrapper function around lim_send_disassoc_cnf
+ *
+ * Return: void
+ */
+void lim_process_disassoc_ack_timeout(tpAniSirGlobal mac_ctx)
+{
+	lim_send_disassoc_cnf(mac_ctx);
+}
+
+/**
+ * lim_process_mlm_disassoc_req() - This function is called to process
+ * MLM_DISASSOC_REQ message from SME
+ *
+ * @mac_ctx:      Pointer to Global MAC structure
+ * @msg_buf:      A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_DISASSOC_REQ message from SME
+ *
+ * @Return: None
+ */
+static void
+lim_process_mlm_disassoc_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+	tLimMlmDisassocReq *mlm_disassoc_req;
+
+	if (msg_buf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	mlm_disassoc_req = (tLimMlmDisassocReq *) msg_buf;
+	pe_debug("Process disassoc req, sessionID %d from: "MAC_ADDRESS_STR,
+		mlm_disassoc_req->sessionId,
+		MAC_ADDR_ARRAY(mlm_disassoc_req->peer_macaddr.bytes));
+
+	lim_process_mlm_disassoc_req_ntf(mac_ctx, QDF_STATUS_SUCCESS,
+					 (uint32_t *) msg_buf);
+}
+
+/**
+ * lim_process_mlm_deauth_req_ntf() - This function is process mlm deauth req
+ * notification
+ *
+ * @mac_ctx:         Pointer to Global MAC structure
+ * @suspend_status:  suspend status
+ * @msg_buf:         A pointer to the MLM message buffer
+ *
+ * This function is process mlm deauth req notification
+ *
+ * @Return: None
+ */
+static void
+lim_process_mlm_deauth_req_ntf(tpAniSirGlobal mac_ctx,
+			       QDF_STATUS suspend_status, uint32_t *msg_buf)
+{
+	uint16_t aid;
+	tSirMacAddr curr_bssId;
+	tpDphHashNode sta_ds;
+	struct tLimPreAuthNode *auth_node;
+	tLimMlmDeauthReq *mlm_deauth_req;
+	tLimMlmDeauthCnf mlm_deauth_cnf;
+	tpPESession session;
+	tSirSmeDeauthRsp *sme_deauth_rsp;
+
+	if (QDF_STATUS_SUCCESS != suspend_status)
+		pe_err("Suspend Status is not success %X",
+			suspend_status);
+
+	mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf;
+	session = pe_find_session_by_session_id(mac_ctx,
+				mlm_deauth_req->sessionId);
+	if (NULL == session) {
+		pe_err("session does not exist for given sessionId %d",
+			mlm_deauth_req->sessionId);
+		qdf_mem_free(mlm_deauth_req);
+		return;
+	}
+	pe_debug("Process Deauth Req on sessionID %d Systemrole %d"
+		       "mlmstate %d from: " MAC_ADDRESS_STR,
+		mlm_deauth_req->sessionId,
+		GET_LIM_SYSTEM_ROLE(session),
+		session->limMlmState,
+		MAC_ADDR_ARRAY(mlm_deauth_req->peer_macaddr.bytes));
+	sir_copy_mac_addr(curr_bssId, session->bssId);
+
+	switch (GET_LIM_SYSTEM_ROLE(session)) {
+	case eLIM_STA_ROLE:
+		switch (session->limMlmState) {
+		case eLIM_MLM_IDLE_STATE:
+			/*
+			 * Attempting to Deauthenticate with a pre-authenticated
+			 * peer. Deauthetiate with peer if there exists a
+			 * pre-auth context below.
+			 */
+			break;
+		case eLIM_MLM_AUTHENTICATED_STATE:
+		case eLIM_MLM_WT_ASSOC_RSP_STATE:
+		case eLIM_MLM_LINK_ESTABLISHED_STATE:
+			if (qdf_mem_cmp(mlm_deauth_req->peer_macaddr.bytes,
+					curr_bssId, QDF_MAC_ADDR_SIZE)) {
+				pe_err("received MLM_DEAUTH_REQ with invalid BSS id "
+					   "Peer MAC: "MAC_ADDRESS_STR
+					   " CFG BSSID Addr : "MAC_ADDRESS_STR,
+					MAC_ADDR_ARRAY(
+						mlm_deauth_req->peer_macaddr.bytes),
+					MAC_ADDR_ARRAY(curr_bssId));
+				/*
+				 * Deauthentication response to host triggered
+				 * deauthentication
+				 */
+				sme_deauth_rsp =
+				    qdf_mem_malloc(sizeof(tSirSmeDeauthRsp));
+				if (!sme_deauth_rsp) {
+					qdf_mem_free(mlm_deauth_req);
+					return;
+				}
+
+				pe_debug("send deauth rsp with ret code %d for" MAC_ADDRESS_STR,
+					eSIR_SME_DEAUTH_STATUS,
+					MAC_ADDR_ARRAY(
+					  mlm_deauth_req->peer_macaddr.bytes));
+
+				sme_deauth_rsp->messageType =
+						eWNI_SME_DEAUTH_RSP;
+				sme_deauth_rsp->length =
+						sizeof(tSirSmeDeauthRsp);
+				sme_deauth_rsp->statusCode =
+						eSIR_SME_DEAUTH_STATUS;
+				sme_deauth_rsp->sessionId =
+						mlm_deauth_req->sessionId;
+				sme_deauth_rsp->transactionId = 0;
+
+				qdf_mem_copy(sme_deauth_rsp->peer_macaddr.bytes,
+					     mlm_deauth_req->peer_macaddr.bytes,
+					     QDF_MAC_ADDR_SIZE);
+
+				msg_buf = (uint32_t *)sme_deauth_rsp;
+
+				lim_send_sme_disassoc_deauth_ntf(mac_ctx,
+						QDF_STATUS_SUCCESS, msg_buf);
+				qdf_mem_free(mlm_deauth_req);
+				return;
+			}
+
+			if ((session->limMlmState ==
+			     eLIM_MLM_AUTHENTICATED_STATE) ||
+			    (session->limMlmState ==
+			     eLIM_MLM_WT_ASSOC_RSP_STATE)) {
+				/* Send deauth frame to peer entity */
+				lim_send_deauth_mgmt_frame(mac_ctx,
+					mlm_deauth_req->reasonCode,
+					mlm_deauth_req->peer_macaddr.bytes,
+					session, false);
+				/* Prepare and Send LIM_MLM_DEAUTH_CNF */
+				mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
+				session->limMlmState = eLIM_MLM_IDLE_STATE;
+				MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+						 session->peSessionId,
+						 session->limMlmState));
+				goto end;
+			}
+			break;
+		default:
+			pe_warn("received MLM_DEAUTH_REQ with in state %d for peer "
+				   MAC_ADDRESS_STR,
+				session->limMlmState,
+				MAC_ADDR_ARRAY(
+					mlm_deauth_req->peer_macaddr.bytes));
+			lim_print_mlm_state(mac_ctx, LOGW,
+					    session->limMlmState);
+			/* Prepare and Send LIM_MLM_DEAUTH_CNF */
+			mlm_deauth_cnf.resultCode =
+				eSIR_SME_STA_NOT_AUTHENTICATED;
+
+			goto end;
+		}
+		break;
+	case eLIM_STA_IN_IBSS_ROLE:
+		pe_err("received MLM_DEAUTH_REQ IBSS Mode");
+		mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+		goto end;
+	case eLIM_AP_ROLE:
+	case eLIM_P2P_DEVICE_GO:
+		if (true ==
+			mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+			pe_err("CAC timer is running, drop disassoc from going out");
+			mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
+			goto end;
+		}
+		break;
+
+	default:
+		break;
+	} /* end switch (GET_LIM_SYSTEM_ROLE(session)) */
+
+	/*
+	 * Check if there exists a context for the peer entity
+	 * to be deauthenticated with.
+	 */
+	sta_ds = dph_lookup_hash_entry(mac_ctx,
+				       mlm_deauth_req->peer_macaddr.bytes,
+				       &aid, &session->dph.dphHashTable);
+
+	if (sta_ds == NULL) {
+		/* Check if there exists pre-auth context for this STA */
+		auth_node = lim_search_pre_auth_list(mac_ctx,
+					mlm_deauth_req->peer_macaddr.bytes);
+		if (auth_node == NULL) {
+			/*
+			 * Received DEAUTH REQ for a STA that is neither
+			 * Associated nor Pre-authenticated. Log error,
+			 * Prepare and Send LIM_MLM_DEAUTH_CNF
+			 */
+			pe_warn("received MLM_DEAUTH_REQ in mlme state %d for STA that "
+				   "does not have context, Addr="
+				   MAC_ADDRESS_STR,
+				session->limMlmState,
+				MAC_ADDR_ARRAY(
+					mlm_deauth_req->peer_macaddr.bytes));
+			mlm_deauth_cnf.resultCode =
+				eSIR_SME_STA_NOT_AUTHENTICATED;
+		} else {
+			mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
+			/* Delete STA from pre-auth STA list */
+			lim_delete_pre_auth_node(mac_ctx,
+					 mlm_deauth_req->peer_macaddr.bytes);
+			/* Send Deauthentication frame to peer entity */
+			lim_send_deauth_mgmt_frame(mac_ctx,
+					   mlm_deauth_req->reasonCode,
+					   mlm_deauth_req->peer_macaddr.bytes,
+					   session, false);
+		}
+		goto end;
+	} else if ((sta_ds->mlmStaContext.mlmState !=
+		    eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+		   (sta_ds->mlmStaContext.mlmState !=
+		    eLIM_MLM_WT_ASSOC_CNF_STATE)) {
+		/*
+		 * received MLM_DEAUTH_REQ for STA that either has no context or
+		 * in some transit state
+		 */
+		pe_warn("Invalid MLM_DEAUTH_REQ, Addr="MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(mlm_deauth_req->peer_macaddr.bytes));
+		/* Prepare and Send LIM_MLM_DEAUTH_CNF */
+		mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+		goto end;
+	}
+	/* sta_ds->mlmStaContext.rxPurgeReq     = 1; */
+	sta_ds->mlmStaContext.disassocReason = (tSirMacReasonCodes)
+					       mlm_deauth_req->reasonCode;
+	sta_ds->mlmStaContext.cleanupTrigger = mlm_deauth_req->deauthTrigger;
+
+	if (mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq) {
+		pe_err("pMlmDeauthReq is not NULL, freeing");
+		qdf_mem_free(mac_ctx->lim.limDisassocDeauthCnfReq.
+			     pMlmDeauthReq);
+	}
+	mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = mlm_deauth_req;
+
+	/*
+	 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
+	 * This is to address the issue of race condition between
+	 * disconnect request from the HDD and disassoc from
+	 * inactivity timer. This will make sure that we will not
+	 * process disassoc if deauth is in progress for the station
+	 * and thus mlmStaContext.cleanupTrigger will not be overwritten.
+	 */
+	sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+	/* Send Deauthentication frame to peer entity */
+	lim_send_deauth_mgmt_frame(mac_ctx, mlm_deauth_req->reasonCode,
+				   mlm_deauth_req->peer_macaddr.bytes,
+				   session, true);
+	return;
+end:
+	qdf_copy_macaddr(&mlm_deauth_cnf.peer_macaddr,
+			 &mlm_deauth_req->peer_macaddr);
+	mlm_deauth_cnf.deauthTrigger = mlm_deauth_req->deauthTrigger;
+	mlm_deauth_cnf.aid = mlm_deauth_req->aid;
+	mlm_deauth_cnf.sessionId = mlm_deauth_req->sessionId;
+
+	/* Free up buffer allocated for mlmDeauthReq */
+	qdf_mem_free(mlm_deauth_req);
+	lim_post_sme_message(mac_ctx,
+			     LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlm_deauth_cnf);
+}
+
+/*
+ * lim_process_deauth_ack_timeout() - wrapper function around
+ * lim_send_deauth_cnf
+ *
+ * @mac_ctx:        mac_ctx
+ *
+ * wrapper function around lim_send_deauth_cnf
+ *
+ * Return: void
+ */
+void lim_process_deauth_ack_timeout(tpAniSirGlobal mac_ctx)
+{
+	lim_send_deauth_cnf(mac_ctx);
+}
+
+/*
+ * lim_process_mlm_deauth_req() - This function is called to process
+ * MLM_DEAUTH_REQ message from SME
+ *
+ * @mac_ctx:      Pointer to Global MAC structure
+ * @msg_buf:      A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_DEAUTH_REQ message from SME
+ *
+ * @Return: None
+ */
+void lim_process_mlm_deauth_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+	tLimMlmDeauthReq *mlm_deauth_req;
+	tpPESession session;
+
+	if (msg_buf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf;
+	pe_debug("Process Deauth Req on sessionID %d from: "
+		   MAC_ADDRESS_STR,
+		mlm_deauth_req->sessionId,
+		MAC_ADDR_ARRAY(mlm_deauth_req->peer_macaddr.bytes));
+
+	session = pe_find_session_by_session_id(mac_ctx,
+				mlm_deauth_req->sessionId);
+	if (NULL == session) {
+		pe_err("session does not exist for given sessionId %d",
+			mlm_deauth_req->sessionId);
+		qdf_mem_free(mlm_deauth_req);
+		return;
+	}
+	lim_process_mlm_deauth_req_ntf(mac_ctx, QDF_STATUS_SUCCESS,
+				       (uint32_t *) msg_buf);
+}
+
+/**
+ * lim_process_mlm_set_keys_req() - This function is called to process
+ * MLM_SETKEYS_REQ message from SME
+ *
+ * @mac_ctx:      Pointer to Global MAC structure
+ * @msg_buf:      A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_SETKEYS_REQ message from SME
+ *
+ * @Return: None
+ */
+static void
+lim_process_mlm_set_keys_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+	uint16_t aid;
+	uint16_t sta_idx = 0;
+	uint32_t default_key_id = 0;
+	struct qdf_mac_addr curr_bssid;
+	tpDphHashNode sta_ds;
+	tLimMlmSetKeysReq *mlm_set_keys_req;
+	tLimMlmSetKeysCnf mlm_set_keys_cnf;
+	tpPESession session;
+
+	if (msg_buf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	mlm_set_keys_req = (tLimMlmSetKeysReq *) msg_buf;
+	if (mac_ctx->lim.gpLimMlmSetKeysReq != NULL) {
+		qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
+		mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
+	}
+	/* Hold onto the SetKeys request parameters */
+	mac_ctx->lim.gpLimMlmSetKeysReq = (void *)mlm_set_keys_req;
+	session = pe_find_session_by_session_id(mac_ctx,
+				mlm_set_keys_req->sessionId);
+	if (NULL == session) {
+		pe_err("session does not exist for given sessionId");
+		qdf_mem_free(mlm_set_keys_req);
+		mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
+		return;
+	}
+
+	pe_debug("Received MLM_SETKEYS_REQ with parameters:"
+		   "AID [%d], ED Type [%d], # Keys [%d] & Peer MAC Addr - ",
+		mlm_set_keys_req->aid, mlm_set_keys_req->edType,
+		mlm_set_keys_req->numKeys);
+	lim_print_mac_addr(mac_ctx, mlm_set_keys_req->peer_macaddr.bytes, LOGD);
+	qdf_mem_copy(curr_bssid.bytes, session->bssId, QDF_MAC_ADDR_SIZE);
+
+	switch (GET_LIM_SYSTEM_ROLE(session)) {
+	case eLIM_STA_ROLE:
+		/*
+		 * In case of TDLS, peerMac address need not be BssId. Skip this
+		 * check if TDLS is enabled.
+		 */
+#ifndef FEATURE_WLAN_TDLS
+		if ((!qdf_is_macaddr_broadcast(
+				&mlm_set_keys_req->peer_macaddr)) &&
+		    (!qdf_is_macaddr_equal(&mlm_set_keys_req->peer_macaddr,
+					   &curr_bssid))) {
+			pe_debug("Received MLM_SETKEYS_REQ with invalid BSSID"
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(mlm_set_keys_req->
+						peer_macaddr.bytes));
+			/*
+			 * Prepare and Send LIM_MLM_SETKEYS_CNF with error code
+			 */
+			mlm_set_keys_cnf.resultCode =
+				eSIR_SME_INVALID_PARAMETERS;
+			goto end;
+		}
+#endif
+		break;
+	case eLIM_STA_IN_IBSS_ROLE:
+		/*
+		 * update the IBSS PE session encrption type based on the
+		 * key type
+		 */
+		session->encryptType = mlm_set_keys_req->edType;
+		break;
+	default:
+		break;
+	}
+
+	/*
+	 * Use the "unicast" parameter to determine if the "Group Keys"
+	 * are being set.
+	 * mlm_set_keys_req->key.unicast = 0 -> Multicast/broadcast
+	 * mlm_set_keys_req->key.unicast - 1 -> Unicast keys are being set
+	 */
+	if (qdf_is_macaddr_broadcast(&mlm_set_keys_req->peer_macaddr)) {
+		pe_debug("Trying to set Group Keys...%d",
+			mlm_set_keys_req->sessionId);
+		/*
+		 * When trying to set Group Keys for any security mode other
+		 * than WEP, use the STA Index corresponding to the AP...
+		 */
+		switch (mlm_set_keys_req->edType) {
+		case eSIR_ED_CCMP:
+		case eSIR_ED_GCMP:
+		case eSIR_ED_GCMP_256:
+#ifdef WLAN_FEATURE_11W
+		case eSIR_ED_AES_128_CMAC:
+		case eSIR_ED_AES_GMAC_128:
+		case eSIR_ED_AES_GMAC_256:
+#endif
+			sta_idx = session->staId;
+			break;
+		default:
+			break;
+		}
+	} else {
+		pe_debug("Trying to set Unicast Keys...");
+		/*
+		 * Check if there exists a context for the
+		 * peer entity for which keys need to be set.
+		 */
+		sta_ds = dph_lookup_hash_entry(mac_ctx,
+				mlm_set_keys_req->peer_macaddr.bytes, &aid,
+				&session->dph.dphHashTable);
+		if ((sta_ds == NULL) ||
+		    ((sta_ds->mlmStaContext.mlmState !=
+		    eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+		    !LIM_IS_AP_ROLE(session))) {
+			/*
+			 * Received LIM_MLM_SETKEYS_REQ for STA that does not
+			 * have context or in some transit state.
+			 */
+			pe_debug("Invalid MLM_SETKEYS_REQ, Addr = "
+				   MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(mlm_set_keys_req->
+						peer_macaddr.bytes));
+			/* Prepare and Send LIM_MLM_SETKEYS_CNF */
+			mlm_set_keys_cnf.resultCode =
+				eSIR_SME_INVALID_PARAMETERS;
+			goto end;
+		} else {
+			sta_idx = sta_ds->staIndex;
+		}
+	}
+
+	if ((mlm_set_keys_req->numKeys == 0)
+	    && (mlm_set_keys_req->edType != eSIR_ED_NONE)) {
+		/*
+		 * Broadcast/Multicast Keys (for WEP!!) are NOT sent
+		 * via this interface!! This indicates to HAL that the WEP Keys
+		 * need to be extracted from the CFG and applied to hardware
+		 */
+		default_key_id = 0xff;
+	} else if (mlm_set_keys_req->key[0].keyId &&
+		   ((mlm_set_keys_req->edType == eSIR_ED_WEP40) ||
+		    (mlm_set_keys_req->edType == eSIR_ED_WEP104))) {
+		/*
+		 * If the Key Id is non zero and encryption mode is WEP,
+		 * the key index is coming from the upper layers so that key
+		 * only need to be used as the default tx key, This is being
+		 * used only in case of WEP mode in HAL
+		 */
+		default_key_id = mlm_set_keys_req->key[0].keyId;
+	} else {
+		default_key_id = 0;
+	}
+	pe_debug("Trying to set keys for STA Index [%d], using default_key_id [%d]",
+		sta_idx, default_key_id);
+
+	if (qdf_is_macaddr_broadcast(&mlm_set_keys_req->peer_macaddr)) {
+		session->limPrevMlmState = session->limMlmState;
+		session->limMlmState = eLIM_MLM_WT_SET_BSS_KEY_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+				 session->peSessionId, session->limMlmState));
+		pe_debug("Trying to set Group Keys...%d",
+			session->peSessionId);
+		/* Package WMA_SET_BSSKEY_REQ message parameters */
+		lim_send_set_bss_key_req(mac_ctx, mlm_set_keys_req, session);
+		return;
+	} else {
+		/*
+		 * Package WMA_SET_STAKEY_REQ / WMA_SET_STA_BCASTKEY_REQ message
+		 * parameters
+		 */
+		lim_send_set_sta_key_req(mac_ctx, mlm_set_keys_req, sta_idx,
+					 (uint8_t) default_key_id, session,
+					 true);
+		return;
+	}
+end:
+	mlm_set_keys_cnf.sessionId = mlm_set_keys_req->sessionId;
+	lim_post_sme_set_keys_cnf(mac_ctx, mlm_set_keys_req, &mlm_set_keys_cnf);
+}
+
+void lim_process_join_failure_timeout(tpAniSirGlobal mac_ctx)
+{
+	tLimMlmJoinCnf mlm_join_cnf;
+	uint32_t len;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+	host_log_rssi_pkt_type *rssi_log = NULL;
+#endif
+	tpPESession session;
+
+	session = pe_find_session_by_session_id(mac_ctx,
+			mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId);
+	if (NULL == session) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+	WLAN_HOST_DIAG_LOG_ALLOC(rssi_log,
+				host_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C);
+	if (rssi_log)
+		rssi_log->rssi = session->rssi;
+	WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
+#endif
+
+	if (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) {
+		len = sizeof(tSirMacAddr);
+		/* Change timer for future activations */
+		lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);
+		/* Change Periodic probe req timer for future activation */
+		lim_deactivate_and_change_timer(mac_ctx,
+					eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
+		/* Issue MLM join confirm with timeout reason code */
+		pe_err("Join Failure Timeout, In eLIM_MLM_WT_JOIN_BEACON_STATE session:%d "
+			   MAC_ADDRESS_STR,
+			session->peSessionId, MAC_ADDR_ARRAY(session->bssId));
+
+		mlm_join_cnf.resultCode = eSIR_SME_JOIN_TIMEOUT_RESULT_CODE;
+		mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+		session->limMlmState = eLIM_MLM_IDLE_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+				 session->peSessionId, session->limMlmState));
+		/* Update PE session Id */
+		mlm_join_cnf.sessionId = session->peSessionId;
+		/* Freeup buffer allocated to join request */
+		if (session->pLimMlmJoinReq) {
+			qdf_mem_free(session->pLimMlmJoinReq);
+			session->pLimMlmJoinReq = NULL;
+		}
+		lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
+				     (uint32_t *) &mlm_join_cnf);
+		return;
+	} else {
+		pe_warn("received unexpected JOIN failure timeout in state %X",
+			session->limMlmState);
+		lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
+	}
+}
+
+/**
+ * lim_process_periodic_join_probe_req_timer() - This function is called to
+ * process periodic probe request send during joining process.
+ *
+ * @mac_ctx:      Pointer to Global MAC structure
+ *
+ * This function is called to process periodic probe request send during
+ * joining process.
+ *
+ * @Return None
+ */
+static void lim_process_periodic_join_probe_req_timer(tpAniSirGlobal mac_ctx)
+{
+	tpPESession session;
+	tSirMacSSid ssid;
+
+	session = pe_find_session_by_session_id(mac_ctx,
+		mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId);
+	if (NULL == session) {
+		pe_err("session does not exist for given SessionId: %d",
+			mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.
+			sessionId);
+		return;
+	}
+
+	if ((true ==
+	    tx_timer_running(&mac_ctx->lim.limTimers.gLimJoinFailureTimer))
+		&& (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)) {
+		qdf_mem_copy(ssid.ssId, session->ssId.ssId,
+			     session->ssId.length);
+		ssid.length = session->ssId.length;
+		lim_send_probe_req_mgmt_frame(mac_ctx, &ssid,
+			session->pLimMlmJoinReq->bssDescription.bssId,
+			session->currentOperChannel /*chanNum */,
+			session->selfMacAddr, session->dot11mode,
+			&session->pLimJoinReq->addIEScan.length,
+			session->pLimJoinReq->addIEScan.addIEdata);
+		lim_deactivate_and_change_timer(mac_ctx,
+				eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
+		/* Activate Join Periodic Probe Req timer */
+		if (tx_timer_activate(
+		    &mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer) !=
+		    TX_SUCCESS) {
+			pe_warn("could not activate Periodic Join req failure timer");
+			return;
+		}
+	}
+}
+
+/**
+ * lim_process_auth_retry_timer()- function to Retry Auth
+ * @mac_ctx:pointer to global mac
+ *
+ * Return: void
+ */
+
+static void lim_process_auth_retry_timer(tpAniSirGlobal mac_ctx)
+{
+	tpPESession  session_entry;
+
+	session_entry =
+	  pe_find_session_by_session_id(mac_ctx,
+	  mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer.sessionId);
+	if (NULL == session_entry) {
+		pe_err("session does not exist for given SessionId: %d",
+		  mac_ctx->lim.limTimers.
+			g_lim_periodic_auth_retry_timer.sessionId);
+		return;
+	}
+
+	if (tx_timer_running(&mac_ctx->lim.limTimers.gLimAuthFailureTimer) &&
+	     (session_entry->limMlmState == eLIM_MLM_WT_AUTH_FRAME2_STATE) &&
+	     (LIM_AUTH_ACK_RCD_SUCCESS != mac_ctx->auth_ack_status)) {
+		tSirMacAuthFrameBody    auth_frame;
+
+		/*
+		 * Send the auth retry only in case we have received ack failure
+		 * else just restart the retry timer.
+		 */
+		if (LIM_AUTH_ACK_RCD_FAILURE == mac_ctx->auth_ack_status) {
+			/* Prepare & send Authentication frame */
+			auth_frame.authAlgoNumber =
+			    (uint8_t) mac_ctx->lim.gpLimMlmAuthReq->authType;
+			auth_frame.authTransactionSeqNumber =
+						SIR_MAC_AUTH_FRAME_1;
+			auth_frame.authStatusCode = 0;
+			pe_debug("Retry Auth");
+			mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
+			lim_increase_fils_sequence_number(session_entry);
+			lim_send_auth_mgmt_frame(mac_ctx,
+				&auth_frame,
+				mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
+				LIM_NO_WEP_IN_FC, session_entry);
+		}
+
+		lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
+
+		/* Activate Auth Retry timer */
+		if (tx_timer_activate
+		     (&mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer)
+			 != TX_SUCCESS) {
+			pe_err("could not activate Auth Retry failure timer");
+			return;
+		}
+	}
+	return;
+} /*** lim_process_auth_retry_timer() ***/
+
+void lim_process_auth_failure_timeout(tpAniSirGlobal mac_ctx)
+{
+	/* fetch the sessionEntry based on the sessionId */
+	tpPESession session;
+	uint32_t val;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+	host_log_rssi_pkt_type *rssi_log = NULL;
+#endif
+
+	session = pe_find_session_by_session_id(mac_ctx,
+			mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId);
+	if (NULL == session) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+
+	pe_warn("received AUTH failure timeout in sessionid %d "
+		   "limMlmstate %X limSmeState %X",
+		session->peSessionId, session->limMlmState,
+		session->limSmeState);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_TIMEOUT, session,
+				0, AUTH_FAILURE_TIMEOUT);
+
+	WLAN_HOST_DIAG_LOG_ALLOC(rssi_log, host_log_rssi_pkt_type,
+				 LOG_WLAN_RSSI_UPDATE_C);
+	if (rssi_log)
+		rssi_log->rssi = session->rssi;
+	WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
+#endif
+
+	switch (session->limMlmState) {
+	case eLIM_MLM_WT_AUTH_FRAME2_STATE:
+	case eLIM_MLM_WT_AUTH_FRAME4_STATE:
+		/*
+		 * Requesting STA did not receive next auth frame before Auth
+		 * Failure timeout. Issue MLM auth confirm with timeout reason
+		 * code. Restore default failure timeout
+		 */
+		if (QDF_P2P_CLIENT_MODE == session->pePersona &&
+		    session->defaultAuthFailureTimeout) {
+			if (cfg_in_range(CFG_AUTH_FAILURE_TIMEOUT,
+					 session->defaultAuthFailureTimeout)) {
+				val = session->defaultAuthFailureTimeout;
+			} else {
+				val = cfg_default(CFG_AUTH_FAILURE_TIMEOUT);
+				session->defaultAuthFailureTimeout = val;
+			}
+			mac_ctx->mlme_cfg->timeouts.auth_failure_timeout = val;
+		}
+
+		lim_restore_from_auth_state(mac_ctx,
+				eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,
+				eSIR_MAC_UNSPEC_FAILURE_REASON, session);
+		break;
+	default:
+		/*
+		 * Auth failure timer should not have timed out
+		 * in states other than wt_auth_frame2/4
+		 */
+		pe_err("received unexpected AUTH failure timeout in state %X",
+			session->limMlmState);
+		lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
+		break;
+	}
+}
+
+/**
+ * lim_process_auth_rsp_timeout() - This function is called to process Min
+ * Channel Timeout during channel scan.
+ *
+ * @mac_ctx:      Pointer to Global MAC structure
+ *
+ * This function is called to process Min Channel Timeout during channel scan.
+ *
+ * @Return: None
+ */
+static void
+lim_process_auth_rsp_timeout(tpAniSirGlobal mac_ctx, uint32_t auth_idx)
+{
+	struct tLimPreAuthNode *auth_node;
+	tpPESession session;
+	uint8_t session_id;
+
+	auth_node = lim_get_pre_auth_node_from_index(mac_ctx,
+				&mac_ctx->lim.gLimPreAuthTimerTable, auth_idx);
+	if (NULL == auth_node) {
+		pe_warn("Invalid auth node");
+		return;
+	}
+
+	session = pe_find_session_by_bssid(mac_ctx, auth_node->peerMacAddr,
+					   &session_id);
+	if (NULL == session) {
+		pe_warn("session does not exist for given BSSID");
+		return;
+	}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_TIMEOUT,
+				session, 0, AUTH_RESPONSE_TIMEOUT);
+#endif
+
+	if (LIM_IS_AP_ROLE(session) || LIM_IS_IBSS_ROLE(session)) {
+		if (auth_node->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE) {
+			pe_err("received AUTH rsp timeout in unexpected "
+				   "state for MAC address: " MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(auth_node->peerMacAddr));
+		} else {
+			auth_node->mlmState = eLIM_MLM_AUTH_RSP_TIMEOUT_STATE;
+			auth_node->fTimerStarted = 0;
+			pe_debug("AUTH rsp timedout for MAC address "
+				   MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(auth_node->peerMacAddr));
+			/* Change timer to reactivate it in future */
+			lim_deactivate_and_change_per_sta_id_timer(mac_ctx,
+				eLIM_AUTH_RSP_TIMER, auth_node->authNodeIdx);
+			lim_delete_pre_auth_node(mac_ctx,
+						 auth_node->peerMacAddr);
+		}
+	}
+}
+
+void lim_process_assoc_failure_timeout(tpAniSirGlobal mac_ctx,
+						     uint32_t msg_type)
+{
+
+	tLimMlmAssocCnf mlm_assoc_cnf;
+	tpPESession session;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+	host_log_rssi_pkt_type *rssi_log = NULL;
+#endif
+	/*
+	 * to fetch the lim/mlm state based on the session_id, use the
+	 * below sessionEntry
+	 */
+	uint8_t session_id;
+
+	if (msg_type == LIM_ASSOC)
+		session_id =
+		    mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId;
+	else
+		session_id =
+		    mac_ctx->lim.limTimers.gLimReassocFailureTimer.sessionId;
+
+	session = pe_find_session_by_session_id(mac_ctx, session_id);
+	if (NULL == session) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_TIMEOUT,
+				session, 0, 0);
+
+	WLAN_HOST_DIAG_LOG_ALLOC(rssi_log,
+				 host_log_rssi_pkt_type,
+				 LOG_WLAN_RSSI_UPDATE_C);
+	if (rssi_log)
+		rssi_log->rssi = session->rssi;
+	WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
+#endif
+
+	pe_debug("Re/Association Response not received before timeout");
+
+	/*
+	 * Send Deauth to handle the scenareo where association timeout happened
+	 * when device has missed the assoc resp sent by peer.
+	 * By sending deauth try to clear the session created on peer device.
+	 */
+	pe_debug("Sessionid: %d try sending deauth on channel %d to BSSID: "
+		MAC_ADDRESS_STR, session->peSessionId,
+		session->currentOperChannel,
+		MAC_ADDR_ARRAY(session->bssId));
+	lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON,
+		session->bssId, session, false);
+
+	if ((LIM_IS_AP_ROLE(session)) ||
+	    ((session->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) &&
+	    (session->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) &&
+	    (session->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) {
+		/*
+		 * Re/Assoc failure timer should not have timedout on AP
+		 * or in a state other than wt_re/assoc_response.
+		 */
+		pe_warn("received unexpected REASSOC failure timeout in state %X for role %d",
+			session->limMlmState,
+			GET_LIM_SYSTEM_ROLE(session));
+		lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
+		return;
+	}
+
+	if ((msg_type == LIM_ASSOC) || ((msg_type == LIM_REASSOC)
+	     && (session->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) {
+		pe_err("(Re)Assoc Failure Timeout occurred");
+		session->limMlmState = eLIM_MLM_IDLE_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+			session->peSessionId, session->limMlmState));
+		/* Change timer for future activations */
+		lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER);
+		/*
+		 * Free up buffer allocated for JoinReq held by
+		 * MLM state machine
+		 */
+		if (session->pLimMlmJoinReq) {
+			qdf_mem_free(session->pLimMlmJoinReq);
+			session->pLimMlmJoinReq = NULL;
+		}
+		/* To remove the preauth node in case of fail to associate */
+		if (lim_search_pre_auth_list(mac_ctx, session->bssId)) {
+			pe_debug("delete pre auth node for "MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(session->bssId));
+			lim_delete_pre_auth_node(mac_ctx,
+						 session->bssId);
+		}
+
+		mlm_assoc_cnf.resultCode = eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE;
+		mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+		/* Update PE session Id */
+		mlm_assoc_cnf.sessionId = session->peSessionId;
+		if (msg_type == LIM_ASSOC) {
+			lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
+					     (uint32_t *) &mlm_assoc_cnf);
+		} else {
+			/*
+			 * Will come here only in case of 11r, Ese FT
+			 * when reassoc rsp is not received and we
+			 * receive a reassoc - timesout
+			 */
+			mlm_assoc_cnf.resultCode =
+				eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE;
+			lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF,
+					     (uint32_t *) &mlm_assoc_cnf);
+		}
+	} else {
+		/*
+		 * Restore pre-reassoc req state.
+		 * Set BSSID to currently associated AP address.
+		 */
+		session->limMlmState = session->limPrevMlmState;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+				 session->peSessionId, session->limMlmState));
+		lim_restore_pre_reassoc_state(mac_ctx,
+				eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE,
+				eSIR_MAC_UNSPEC_FAILURE_STATUS, session);
+	}
+}
+
+/**
+ * lim_set_channel() - set channel api for lim
+ *
+ * @mac_ctx:                Pointer to Global MAC structure
+ * @channel:                power save state
+ * @ch_center_freq_seg0:    center freq seq 0
+ * @ch_center_freq_seg1:    center freq seq 1
+ * @ch_width:               channel width
+ * @max_tx_power:           max tx power
+ * @pe_session_id:          pe session id
+ *
+ * set channel api for lim
+ *
+ * @Return: None
+ */
+void lim_set_channel(tpAniSirGlobal mac_ctx, uint8_t channel,
+		     uint8_t ch_center_freq_seg0, uint8_t ch_center_freq_seg1,
+		     enum phy_ch_width ch_width, int8_t max_tx_power,
+		     uint8_t pe_session_id, uint32_t cac_duration_ms,
+		     uint32_t dfs_regdomain)
+{
+	tpPESession pe_session;
+
+	pe_session = pe_find_session_by_session_id(mac_ctx, pe_session_id);
+
+	if (NULL == pe_session) {
+		pe_err("Invalid PE session: %d", pe_session_id);
+		return;
+	}
+	lim_send_switch_chnl_params(mac_ctx, channel, ch_center_freq_seg0,
+				    ch_center_freq_seg1, ch_width,
+				    max_tx_power, pe_session_id, false,
+				    cac_duration_ms, dfs_regdomain);
+}
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
new file mode 100644
index 0000000..74cd2de
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
@@ -0,0 +1,3365 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include "sir_api.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_timer_utils.h"
+#include "lim_send_messages.h"
+#include "lim_admit_control.h"
+#include "lim_send_messages.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_ft.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "lim_session_utils.h"
+#include "rrm_api.h"
+#include "wma_types.h"
+#include "cds_utils.h"
+#include "lim_types.h"
+#include "wlan_policy_mgr_api.h"
+#include "nan_datapath.h"
+#include "wlan_reg_services_api.h"
+
+#define MAX_SUPPORTED_PEERS_WEP 16
+
+void lim_process_mlm_join_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_auth_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_assoc_ind(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_assoc_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_reassoc_ind(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_set_keys_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_disassoc_ind(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_disassoc_cnf(tpAniSirGlobal, uint32_t *);
+static void lim_process_mlm_deauth_ind(tpAniSirGlobal, tLimMlmDeauthInd *);
+void lim_process_mlm_deauth_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_purge_sta_ind(tpAniSirGlobal, uint32_t *);
+void lim_get_session_info(tpAniSirGlobal pMac, uint8_t *, uint8_t *,
+				uint16_t *);
+/**
+ * lim_process_mlm_rsp_messages()
+ *
+ ***FUNCTION:
+ * This function is called to processes various MLM response (CNF/IND
+ * messages from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac       Pointer to Global MAC structure
+ * @param  msgType   Indicates the MLM message type
+ * @param  *pMsgBuf  A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+lim_process_mlm_rsp_messages(tpAniSirGlobal pMac, uint32_t msgType,
+			     uint32_t *pMsgBuf)
+{
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_LIM_MSG, 0, msgType));
+	switch (msgType) {
+	case LIM_MLM_AUTH_CNF:
+		lim_process_mlm_auth_cnf(pMac, pMsgBuf);
+		break;
+	case LIM_MLM_ASSOC_CNF:
+		lim_process_mlm_assoc_cnf(pMac, pMsgBuf);
+		break;
+	case LIM_MLM_START_CNF:
+		lim_process_mlm_start_cnf(pMac, pMsgBuf);
+		break;
+	case LIM_MLM_JOIN_CNF:
+		lim_process_mlm_join_cnf(pMac, pMsgBuf);
+		break;
+	case LIM_MLM_ASSOC_IND:
+		lim_process_mlm_assoc_ind(pMac, pMsgBuf);
+		break;
+	case LIM_MLM_REASSOC_CNF:
+		lim_process_mlm_reassoc_cnf(pMac, pMsgBuf);
+		break;
+	case LIM_MLM_DISASSOC_CNF:
+		lim_process_mlm_disassoc_cnf(pMac, pMsgBuf);
+		break;
+	case LIM_MLM_DISASSOC_IND:
+		lim_process_mlm_disassoc_ind(pMac, pMsgBuf);
+		break;
+	case LIM_MLM_PURGE_STA_IND:
+		lim_process_mlm_purge_sta_ind(pMac, pMsgBuf);
+		break;
+	case LIM_MLM_DEAUTH_CNF:
+		lim_process_mlm_deauth_cnf(pMac, pMsgBuf);
+		break;
+	case LIM_MLM_DEAUTH_IND:
+		lim_process_mlm_deauth_ind(pMac, (tLimMlmDeauthInd *)pMsgBuf);
+		break;
+	case LIM_MLM_SETKEYS_CNF:
+		lim_process_mlm_set_keys_cnf(pMac, pMsgBuf);
+		break;
+	case LIM_MLM_TSPEC_CNF:
+		break;
+	default:
+		break;
+	} /* switch (msgType) */
+	return;
+} /*** end lim_process_mlm_rsp_messages() ***/
+
+/**
+ * lim_process_mlm_start_cnf()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_START_CNF
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac       Pointer to Global MAC structure
+ * @param pMsgBuf    A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_start_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	tpPESession psessionEntry = NULL;
+	tLimMlmStartCnf *pLimMlmStartCnf;
+	uint8_t smesessionId;
+	uint16_t smetransactionId;
+	uint8_t channelId;
+	uint8_t send_bcon_ind = false;
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	pLimMlmStartCnf = (tLimMlmStartCnf *) pMsgBuf;
+	psessionEntry = pe_find_session_by_session_id(pMac,
+				pLimMlmStartCnf->sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session does Not exist with given sessionId");
+		return;
+	}
+	smesessionId = psessionEntry->smeSessionId;
+	smetransactionId = psessionEntry->transactionId;
+
+	if (psessionEntry->limSmeState != eLIM_SME_WT_START_BSS_STATE) {
+		/*
+		 * Should not have received Start confirm from MLM
+		 * in other states. Log error.
+		 */
+		pe_err("received unexpected MLM_START_CNF in state %X",
+				psessionEntry->limSmeState);
+		return;
+	}
+	if (((tLimMlmStartCnf *) pMsgBuf)->resultCode == eSIR_SME_SUCCESS) {
+
+		/*
+		 * Update global SME state so that Beacon Generation
+		 * module starts writing Beacon frames into TFP's
+		 * Beacon file register.
+		 */
+		psessionEntry->limSmeState = eLIM_SME_NORMAL_STATE;
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+			       psessionEntry->limSmeState));
+		if (psessionEntry->bssType == eSIR_INFRA_AP_MODE)
+			pe_debug("*** Started BSS in INFRA AP SIDE***");
+		else if (psessionEntry->bssType == eSIR_NDI_MODE)
+			pe_debug("*** Started BSS in NDI mode ***");
+		else
+			pe_debug("*** Started BSS ***");
+	} else {
+		/* Start BSS is a failure */
+		pe_delete_session(pMac, psessionEntry);
+		psessionEntry = NULL;
+		pe_err("Start BSS Failed");
+	}
+	/* Send response to Host */
+	lim_send_sme_start_bss_rsp(pMac, eWNI_SME_START_BSS_RSP,
+				((tLimMlmStartCnf *)pMsgBuf)->resultCode,
+				psessionEntry, smesessionId, smetransactionId);
+	if ((psessionEntry != NULL) &&
+		(((tLimMlmStartCnf *) pMsgBuf)->resultCode ==
+						eSIR_SME_SUCCESS)) {
+		channelId = psessionEntry->pLimStartBssReq->channelId;
+		lim_ndi_mlme_vdev_up_transition(psessionEntry);
+
+		/* We should start beacon transmission only if the channel
+		 * on which we are operating is non-DFS until the channel
+		 * availability check is done. The PE will receive an explicit
+		 * request from upper layers to start the beacon transmission
+		 */
+		if (!(LIM_IS_IBSS_ROLE(psessionEntry) ||
+			(LIM_IS_AP_ROLE(psessionEntry))))
+				return;
+		if (psessionEntry->ch_width == CH_WIDTH_160MHZ) {
+			send_bcon_ind = false;
+		} else if (psessionEntry->ch_width == CH_WIDTH_80P80MHZ) {
+			if ((wlan_reg_get_channel_state(pMac->pdev, channelId)
+						!= CHANNEL_STATE_DFS) &&
+			    (wlan_reg_get_channel_state(pMac->pdev,
+					psessionEntry->ch_center_freq_seg1 -
+					SIR_80MHZ_START_CENTER_CH_DIFF) !=
+						CHANNEL_STATE_DFS))
+				send_bcon_ind = true;
+		} else {
+			if (wlan_reg_get_channel_state(pMac->pdev, channelId)
+					!= CHANNEL_STATE_DFS)
+				send_bcon_ind = true;
+		}
+		if (send_bcon_ind) {
+			/* Configure beacon and send beacons to HAL */
+			QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+					FL("Start Beacon with ssid %s Ch %d"),
+					psessionEntry->ssId.ssId,
+					psessionEntry->currentOperChannel);
+			lim_send_beacon(pMac, psessionEntry);
+			lim_enable_obss_detection_config(pMac, psessionEntry);
+			lim_send_obss_color_collision_cfg(pMac, psessionEntry,
+					OBSS_COLOR_COLLISION_DETECTION);
+		}
+	}
+}
+
+/*** end lim_process_mlm_start_cnf() ***/
+
+/**
+ * lim_process_mlm_join_cnf() - Processes join confirmation
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: A pointer to the MLM message buffer
+ *
+ * This Function handles the join confirmation message
+ * LIM_MLM_JOIN_CNF.
+ *
+ * Return: None
+ */
+void lim_process_mlm_join_cnf(tpAniSirGlobal mac_ctx,
+	uint32_t *msg)
+{
+	tSirResultCodes result_code;
+	tLimMlmJoinCnf *join_cnf;
+	tpPESession session_entry;
+
+	join_cnf = (tLimMlmJoinCnf *) msg;
+	session_entry = pe_find_session_by_session_id(mac_ctx,
+		join_cnf->sessionId);
+	if (session_entry == NULL) {
+		pe_err("SessionId:%d does not exist", join_cnf->sessionId);
+		return;
+	}
+
+	if (session_entry->limSmeState != eLIM_SME_WT_JOIN_STATE) {
+		pe_err("received unexpected MLM_JOIN_CNF in state %X",
+			session_entry->limSmeState);
+		return;
+	}
+
+	result_code = ((tLimMlmJoinCnf *) msg)->resultCode;
+	/* Process Join confirm from MLM */
+	if (result_code == eSIR_SME_SUCCESS) {
+		pe_debug("***SessionId:%d Joined ESS ***",
+			join_cnf->sessionId);
+		/* Setup hardware upfront */
+		if (lim_sta_send_add_bss_pre_assoc(mac_ctx, false,
+			session_entry) == QDF_STATUS_SUCCESS)
+			return;
+		else
+			result_code = eSIR_SME_REFUSED;
+	}
+
+	/*  Join failure */
+	session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+		session_entry->peSessionId,
+		session_entry->limSmeState));
+	/* Send Join response to Host */
+	lim_handle_sme_join_result(mac_ctx, result_code,
+		((tLimMlmJoinCnf *) msg)->protStatusCode, session_entry);
+	return;
+}
+
+/**
+ * lim_send_mlm_assoc_req() - Association request will be processed
+ * mac_ctx:  Pointer to Global MAC structure
+ * session_entry:  Pointer to session etnry
+ *
+ * This function is sends ASSOC request MLM message to MLM State machine.
+ * ASSOC request packet would be by picking parameters from psessionEntry
+ * automatically based on the current state of MLM state machine.
+ * ASSUMPTIONS:
+ * this function is called in middle of connection state machine and is
+ * expected to be called after auth cnf has been received or after ASSOC rsp
+ * with TRY_AGAIN_LATER was received and required time has elapsed after that.
+ *
+ * Return: None
+ */
+
+static void lim_send_mlm_assoc_req(tpAniSirGlobal mac_ctx,
+	tpPESession session_entry)
+{
+	tLimMlmAssocReq *assoc_req;
+	uint32_t val;
+	uint16_t caps;
+	uint32_t tele_bcn = 0;
+	tpSirMacCapabilityInfo cap_info;
+
+	/* Successful MAC based authentication. Trigger Association with BSS */
+	pe_debug("SessionId: %d Authenticated with BSS",
+		session_entry->peSessionId);
+
+	if (NULL == session_entry->pLimJoinReq) {
+		pe_err("Join Request is NULL");
+		/* No need to Assert. JOIN timeout will handle this error */
+		return;
+	}
+
+	assoc_req = qdf_mem_malloc(sizeof(tLimMlmAssocReq));
+	if (NULL == assoc_req) {
+		pe_err("call to AllocateMemory failed for mlmAssocReq");
+		return;
+	}
+	val = sizeof(tSirMacAddr);
+	sir_copy_mac_addr(assoc_req->peerMacAddr, session_entry->bssId);
+
+	if (cfg_get_capability_info(mac_ctx, &caps, session_entry)
+			!= QDF_STATUS_SUCCESS)
+		/* Could not get Capabilities value from CFG.*/
+		pe_err("could not retrieve Capabilities value");
+
+	/* Clear spectrum management bit if AP doesn't support it */
+	if (!(session_entry->pLimJoinReq->bssDescription.capabilityInfo &
+		LIM_SPECTRUM_MANAGEMENT_BIT_MASK))
+		/*
+		 * AP doesn't support spectrum management
+		 * clear spectrum management bit
+		 */
+		caps &= (~LIM_SPECTRUM_MANAGEMENT_BIT_MASK);
+
+	/* Clear rrm bit if AP doesn't support it */
+	if (!(session_entry->pLimJoinReq->bssDescription.capabilityInfo &
+		LIM_RRM_BIT_MASK))
+		caps &= (~LIM_RRM_BIT_MASK);
+
+	/* Clear short preamble bit if AP does not support it */
+	if (!(session_entry->pLimJoinReq->bssDescription.capabilityInfo &
+		(LIM_SHORT_PREAMBLE_BIT_MASK))) {
+		caps &= (~LIM_SHORT_PREAMBLE_BIT_MASK);
+		pe_debug("Clearing short preamble:no AP support");
+	}
+
+	/* Clear immediate block ack bit if AP does not support it */
+	if (!(session_entry->pLimJoinReq->bssDescription.capabilityInfo &
+		(LIM_IMMEDIATE_BLOCK_ACK_MASK))) {
+		caps &= (~LIM_IMMEDIATE_BLOCK_ACK_MASK);
+		pe_debug("Clearing Immed Blk Ack:no AP support");
+	}
+
+	assoc_req->capabilityInfo = caps;
+	cap_info = ((tpSirMacCapabilityInfo) &assoc_req->capabilityInfo);
+	pe_debug("Capabilities to be used in AssocReq=0x%X,"
+		"privacy bit=%x shortSlotTime %x", caps,
+		cap_info->privacy,
+		cap_info->shortSlotTime);
+
+	/*
+	 * If telescopic beaconing is enabled, set listen interval to
+	 * CFG_TELE_BCN_MAX_LI
+	 */
+	tele_bcn = mac_ctx->mlme_cfg->sap_cfg.tele_bcn_wakeup_en;
+	if (tele_bcn)
+		val = mac_ctx->mlme_cfg->sap_cfg.tele_bcn_max_li;
+	else
+		val = mac_ctx->mlme_cfg->sap_cfg.listen_interval;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_REQ_EVENT,
+		session_entry, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+#endif
+	assoc_req->listenInterval = (uint16_t) val;
+	/* Update PE session ID */
+	assoc_req->sessionId = session_entry->peSessionId;
+	session_entry->limPrevSmeState = session_entry->limSmeState;
+	session_entry->limSmeState = eLIM_SME_WT_ASSOC_STATE;
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+		session_entry->peSessionId, session_entry->limSmeState));
+	lim_post_mlm_message(mac_ctx, LIM_MLM_ASSOC_REQ,
+		(uint32_t *) assoc_req);
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * lim_pmf_comeback_timer_callback() -PMF callback handler
+ * @context: Timer context
+ *
+ * This function is called to processes the PMF comeback
+ * callback
+ *
+ * Return: None
+ */
+void lim_pmf_comeback_timer_callback(void *context)
+{
+	tComebackTimerInfo *info = (tComebackTimerInfo *) context;
+	tpAniSirGlobal mac_ctx = info->pMac;
+	tpPESession psessionEntry = &mac_ctx->lim.gpSession[info->sessionID];
+
+	pe_err("comeback later timer expired. sending MLM ASSOC req");
+	/* set MLM state such that ASSOC REQ packet will be sent out */
+	psessionEntry->limPrevMlmState = info->limPrevMlmState;
+	psessionEntry->limMlmState = info->limMlmState;
+	lim_send_mlm_assoc_req(mac_ctx, psessionEntry);
+}
+#endif /* WLAN_FEATURE_11W */
+
+/**
+ * lim_process_mlm_auth_cnf()-Process Auth confirmation
+ * @mac_ctx:  Pointer to Global MAC structure
+ * @msg: A pointer to the MLM message buffer
+ *
+ * This function is called to processes MLM_AUTH_CNF
+ * message from MLM State machine.
+ *
+ * Return: None
+ */
+void lim_process_mlm_auth_cnf(tpAniSirGlobal mac_ctx, uint32_t *msg)
+{
+	tAniAuthType auth_type, auth_mode;
+	tLimMlmAuthReq *auth_req;
+	tLimMlmAuthCnf *auth_cnf;
+	tpPESession session_entry;
+
+	if (msg == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	auth_cnf = (tLimMlmAuthCnf *) msg;
+	session_entry = pe_find_session_by_session_id(mac_ctx,
+			auth_cnf->sessionId);
+	if (session_entry == NULL) {
+		pe_err("SessionId:%d session doesn't exist",
+			auth_cnf->sessionId);
+		return;
+	}
+
+	if ((session_entry->limSmeState != eLIM_SME_WT_AUTH_STATE &&
+		session_entry->limSmeState != eLIM_SME_WT_PRE_AUTH_STATE) ||
+		LIM_IS_AP_ROLE(session_entry)) {
+		/**
+		 * Should not have received AUTH confirm
+		 * from MLM in other states or on AP.
+		 * Log error
+		 */
+		pe_err("SessionId:%d received MLM_AUTH_CNF in state %X",
+			session_entry->peSessionId, session_entry->limSmeState);
+		return;
+	}
+
+	if (auth_cnf->resultCode == eSIR_SME_SUCCESS) {
+		if (session_entry->limSmeState == eLIM_SME_WT_AUTH_STATE) {
+			lim_send_mlm_assoc_req(mac_ctx, session_entry);
+		} else {
+			/*
+			 * Successful Pre-authentication. Send
+			 * Pre-auth response to host
+			 */
+			session_entry->limSmeState =
+				session_entry->limPrevSmeState;
+			MTRACE(mac_trace
+				(mac_ctx, TRACE_CODE_SME_STATE,
+				session_entry->peSessionId,
+				session_entry->limSmeState));
+		}
+		/* Return for success case */
+		return;
+	}
+	/*
+	 * Failure case handle:
+	 * Process AUTH confirm from MLM
+	 */
+	if (session_entry->limSmeState == eLIM_SME_WT_AUTH_STATE)
+		auth_type = mac_ctx->mlme_cfg->wep_params.auth_type;
+	else
+		auth_type = mac_ctx->lim.gLimPreAuthType;
+
+	if ((auth_type == eSIR_AUTO_SWITCH) &&
+		(auth_cnf->authType == eSIR_SHARED_KEY) &&
+		((eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS ==
+			auth_cnf->protStatusCode) ||
+		(auth_cnf->resultCode == eSIR_SME_AUTH_TIMEOUT_RESULT_CODE))) {
+		/*
+		 * When shared authentication fails with reason
+		 * code "13" and authType set to 'auto switch',
+		 * Try with open Authentication
+		 */
+		auth_mode = eSIR_OPEN_SYSTEM;
+		/* Trigger MAC based Authentication */
+		auth_req = qdf_mem_malloc(sizeof(tLimMlmAuthReq));
+		if (NULL == auth_req) {
+			pe_err("mlmAuthReq :Memory alloc failed");
+			return;
+		}
+		if (session_entry->limSmeState ==
+			eLIM_SME_WT_AUTH_STATE) {
+			sir_copy_mac_addr(auth_req->peerMacAddr,
+				session_entry->bssId);
+		} else {
+			qdf_mem_copy((uint8_t *)&auth_req->peerMacAddr,
+			(uint8_t *)&mac_ctx->lim.gLimPreAuthPeerAddr,
+			sizeof(tSirMacAddr));
+		}
+		auth_req->authType = auth_mode;
+		/* Update PE session Id */
+		auth_req->sessionId = auth_cnf->sessionId;
+		lim_post_mlm_message(mac_ctx, LIM_MLM_AUTH_REQ,
+			(uint32_t *) auth_req);
+		return;
+	} else {
+		/* MAC based authentication failure */
+		if (session_entry->limSmeState ==
+			eLIM_SME_WT_AUTH_STATE) {
+			pe_err("Auth Failure occurred");
+			session_entry->limSmeState =
+				eLIM_SME_JOIN_FAILURE_STATE;
+			MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+				session_entry->peSessionId,
+				session_entry->limSmeState));
+			session_entry->limMlmState =
+				eLIM_MLM_IDLE_STATE;
+			MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+				session_entry->peSessionId,
+				session_entry->limMlmState));
+			/*
+			 * Need to send Join response with
+			 * auth failure to Host.
+			 */
+			lim_handle_sme_join_result(mac_ctx,
+				auth_cnf->resultCode,
+				auth_cnf->protStatusCode,
+				session_entry);
+		} else {
+			/*
+			 * Pre-authentication failure.
+			 * Send Pre-auth failure response to host
+			 */
+			session_entry->limSmeState =
+				session_entry->limPrevSmeState;
+			MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+				session_entry->peSessionId,
+				session_entry->limSmeState));
+		}
+	}
+}
+
+/**
+ * lim_process_mlm_assoc_cnf() - Process association confirmation
+ * @mac_ctx:  Pointer to Global MAC structure
+ * @msg:  A pointer to the MLM message buffer
+ *
+ * This function is called to processes MLM_ASSOC_CNF
+ * message from MLM State machine.
+ *
+ * Return: None
+ */
+void lim_process_mlm_assoc_cnf(tpAniSirGlobal mac_ctx,
+	uint32_t *msg)
+{
+	tpPESession session_entry;
+	tLimMlmAssocCnf *assoc_cnf;
+
+	if (msg == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	assoc_cnf = (tLimMlmAssocCnf *) msg;
+	session_entry = pe_find_session_by_session_id(mac_ctx,
+				assoc_cnf->sessionId);
+	if (session_entry == NULL) {
+		pe_err("SessionId:%d Session does not exist",
+			assoc_cnf->sessionId);
+		return;
+	}
+	if (session_entry->limSmeState != eLIM_SME_WT_ASSOC_STATE ||
+		 LIM_IS_AP_ROLE(session_entry)) {
+		/*
+		 * Should not have received Assocication confirm
+		 * from MLM in other states OR on AP.
+		 * Log error
+		 */
+		pe_err("SessionId:%d Received MLM_ASSOC_CNF in state %X",
+			session_entry->peSessionId, session_entry->limSmeState);
+		return;
+	}
+	if (((tLimMlmAssocCnf *) msg)->resultCode != eSIR_SME_SUCCESS) {
+		/* Association failure */
+		pe_err("SessionId:%d Association failure resultCode: %d limSmeState:%d",
+			session_entry->peSessionId,
+			((tLimMlmAssocCnf *) msg)->resultCode,
+			session_entry->limSmeState);
+
+		/* If driver gets deauth when its waiting for ADD_STA_RSP then
+		 * we need to do DEL_STA followed by DEL_BSS. So based on below
+		 * reason-code here we decide whether to do only DEL_BSS or
+		 * DEL_STA + DEL_BSS.
+		 */
+		if (((tLimMlmAssocCnf *) msg)->resultCode !=
+		    eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA)
+			session_entry->limSmeState =
+				eLIM_SME_JOIN_FAILURE_STATE;
+
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+			session_entry->peSessionId, mac_ctx->lim.gLimSmeState));
+		/*
+		 * Need to send Join response with
+		 * Association failure to Host.
+		 */
+		lim_handle_sme_join_result(mac_ctx,
+			((tLimMlmAssocCnf *) msg)->resultCode,
+			((tLimMlmAssocCnf *) msg)->protStatusCode,
+			session_entry);
+	} else {
+		/* Successful Association */
+		pe_debug("SessionId:%d Associated with BSS",
+			session_entry->peSessionId);
+		session_entry->limSmeState = eLIM_SME_LINK_EST_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+			session_entry->peSessionId,
+			session_entry->limSmeState));
+		/**
+		 * Need to send Join response with
+		 * Association success to Host.
+		 */
+		lim_handle_sme_join_result(mac_ctx,
+			((tLimMlmAssocCnf *) msg)->resultCode,
+			((tLimMlmAssocCnf *) msg)->protStatusCode,
+			session_entry);
+	}
+}
+
+/**
+ * lim_fill_assoc_ind_params() - Initialize association indication
+ * mac_ctx: Pointer to Global MAC structure
+ * assoc_ind: PE association indication structure
+ * sme_assoc_ind: SME association indication
+ * session_entry: PE session entry
+ *
+ * This function is called to initialzie the association
+ * indication strucutre to process association indication.
+ *
+ * Return: None
+ */
+
+static void
+lim_fill_assoc_ind_params(tpAniSirGlobal mac_ctx,
+	tpLimMlmAssocInd assoc_ind, tSirSmeAssocInd *sme_assoc_ind,
+	tpPESession session_entry)
+{
+	sme_assoc_ind->length = sizeof(tSirSmeAssocInd);
+	sme_assoc_ind->sessionId = session_entry->smeSessionId;
+
+	/* Required for indicating the frames to upper layer */
+	sme_assoc_ind->assocReqLength = assoc_ind->assocReqLength;
+	sme_assoc_ind->assocReqPtr = assoc_ind->assocReqPtr;
+
+	sme_assoc_ind->beaconPtr = session_entry->beacon;
+	sme_assoc_ind->beaconLength = session_entry->bcnLen;
+
+	/* Fill in peerMacAddr */
+	qdf_mem_copy(sme_assoc_ind->peerMacAddr, assoc_ind->peerMacAddr,
+		sizeof(tSirMacAddr));
+
+	/* Fill in aid */
+	sme_assoc_ind->aid = assoc_ind->aid;
+	/* Fill in bssId */
+	qdf_mem_copy(sme_assoc_ind->bssId, session_entry->bssId,
+		sizeof(tSirMacAddr));
+	/* Fill in authType */
+	sme_assoc_ind->authType = assoc_ind->authType;
+	/* Fill in ssId */
+	qdf_mem_copy((uint8_t *) &sme_assoc_ind->ssId,
+		(uint8_t *) &(assoc_ind->ssId), assoc_ind->ssId.length + 1);
+	sme_assoc_ind->rsnIE.length = assoc_ind->rsnIE.length;
+	qdf_mem_copy((uint8_t *) &sme_assoc_ind->rsnIE.rsnIEdata,
+		(uint8_t *) &(assoc_ind->rsnIE.rsnIEdata),
+		assoc_ind->rsnIE.length);
+
+#ifdef FEATURE_WLAN_WAPI
+	sme_assoc_ind->wapiIE.length = assoc_ind->wapiIE.length;
+	qdf_mem_copy((uint8_t *) &sme_assoc_ind->wapiIE.wapiIEdata,
+		(uint8_t *) &(assoc_ind->wapiIE.wapiIEdata),
+		assoc_ind->wapiIE.length);
+#endif
+	sme_assoc_ind->addIE.length = assoc_ind->addIE.length;
+	qdf_mem_copy((uint8_t *) &sme_assoc_ind->addIE.addIEdata,
+		(uint8_t *) &(assoc_ind->addIE.addIEdata),
+		assoc_ind->addIE.length);
+
+	/* Copy the new TITAN capabilities */
+	sme_assoc_ind->spectrumMgtIndicator = assoc_ind->spectrumMgtIndicator;
+	if (assoc_ind->spectrumMgtIndicator == true) {
+		sme_assoc_ind->powerCap.minTxPower =
+			assoc_ind->powerCap.minTxPower;
+		sme_assoc_ind->powerCap.maxTxPower =
+			assoc_ind->powerCap.maxTxPower;
+		sme_assoc_ind->supportedChannels.numChnl =
+			assoc_ind->supportedChannels.numChnl;
+		qdf_mem_copy((uint8_t *) &sme_assoc_ind->supportedChannels.
+			channelList,
+			(uint8_t *) &(assoc_ind->supportedChannels.channelList),
+			assoc_ind->supportedChannels.numChnl);
+	}
+	qdf_mem_copy(&sme_assoc_ind->chan_info, &assoc_ind->chan_info,
+		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;
+	sme_assoc_ind->ecsa_capable = assoc_ind->ecsa_capable;
+
+	if (assoc_ind->ht_caps.present)
+		sme_assoc_ind->HTCaps = assoc_ind->ht_caps;
+	if (assoc_ind->vht_caps.present)
+		sme_assoc_ind->VHTCaps = assoc_ind->vht_caps;
+}
+
+/**
+ * lim_process_mlm_assoc_ind()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_ASSOC_IND
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac       Pointer to Global MAC structure
+ * @param pMsgBuf    A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_assoc_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	uint32_t len;
+	struct scheduler_msg msg = {0};
+	tSirSmeAssocInd *pSirSmeAssocInd;
+	tpDphHashNode pStaDs = 0;
+	tpPESession psessionEntry;
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	psessionEntry = pe_find_session_by_session_id(pMac,
+				((tpLimMlmAssocInd) pMsgBuf)->
+				sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given sessionId");
+		return;
+	}
+	/* / Inform Host of STA association */
+	len = sizeof(tSirSmeAssocInd);
+	pSirSmeAssocInd = qdf_mem_malloc(len);
+	if (NULL == pSirSmeAssocInd) {
+		pe_err("call to AllocateMemory failed for eWNI_SME_ASSOC_IND");
+		return;
+	}
+
+	pSirSmeAssocInd->messageType = eWNI_SME_ASSOC_IND;
+	lim_fill_assoc_ind_params(pMac, (tpLimMlmAssocInd) pMsgBuf,
+				  pSirSmeAssocInd,
+				  psessionEntry);
+	msg.type = eWNI_SME_ASSOC_IND;
+	msg.bodyptr = pSirSmeAssocInd;
+	msg.bodyval = 0;
+	pStaDs = dph_get_hash_entry(pMac,
+				    ((tpLimMlmAssocInd) pMsgBuf)->aid,
+				    &psessionEntry->dph.dphHashTable);
+	if (!pStaDs) {
+		pe_err("MLM AssocInd: Station context no longer valid (aid %d)",
+			((tpLimMlmAssocInd) pMsgBuf)->aid);
+		qdf_mem_free(pSirSmeAssocInd);
+
+		return;
+	}
+	pSirSmeAssocInd->staId = pStaDs->staIndex;
+	pSirSmeAssocInd->reassocReq = pStaDs->mlmStaContext.subType;
+	pSirSmeAssocInd->timingMeasCap = pStaDs->timingMeasCap;
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+			 psessionEntry->peSessionId, msg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_ASSOC_IND_EVENT, psessionEntry, 0,
+			      0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+	pe_debug("Create CNF_WAIT_TIMER after received LIM_MLM_ASSOC_IND");
+	/*
+	** turn on a timer to detect the loss of ASSOC CNF
+	**/
+	lim_activate_cnf_timer(pMac,
+			       (uint16_t) ((tpLimMlmAssocInd) pMsgBuf)->aid,
+			       psessionEntry);
+
+	pMac->lim.sme_msg_callback(pMac, &msg);
+} /*** end lim_process_mlm_assoc_ind() ***/
+
+/**
+ * lim_process_mlm_disassoc_ind()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_DISASSOC_IND
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac       Pointer to Global MAC structure
+ * @param pMsgBuf    A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_disassoc_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	tLimMlmDisassocInd *pMlmDisassocInd;
+	tpPESession psessionEntry;
+
+	pMlmDisassocInd = (tLimMlmDisassocInd *) pMsgBuf;
+	psessionEntry = pe_find_session_by_session_id(pMac,
+				pMlmDisassocInd->sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+	switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+	case eLIM_STA_IN_IBSS_ROLE:
+		break;
+	case eLIM_STA_ROLE:
+		psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE;
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+			       psessionEntry->limSmeState));
+		break;
+	default:        /* eLIM_AP_ROLE */
+		pe_debug("*** Peer staId=%d Disassociated ***",
+			       pMlmDisassocInd->aid);
+		/* Send SME_DISASOC_IND after Polaris cleanup */
+		/* (after receiving LIM_MLM_PURGE_STA_IND) */
+		break;
+	} /* end switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) */
+} /*** end lim_process_mlm_disassoc_ind() ***/
+
+/**
+ * lim_process_mlm_disassoc_cnf() - Processes disassociation
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: A pointer to the MLM message buffer
+ *
+ * This function is called to processes MLM_DISASSOC_CNF
+ * message from MLM State machine.
+ *
+ * Return: None
+ */
+void lim_process_mlm_disassoc_cnf(tpAniSirGlobal mac_ctx,
+	uint32_t *msg)
+{
+	tSirResultCodes result_code;
+	tLimMlmDisassocCnf *disassoc_cnf;
+	tpPESession session_entry;
+
+	disassoc_cnf = (tLimMlmDisassocCnf *) msg;
+
+	session_entry =
+		pe_find_session_by_session_id(mac_ctx, disassoc_cnf->sessionId);
+	if (session_entry == NULL) {
+		pe_err("session Does not exist for given session Id");
+		return;
+	}
+	result_code = (tSirResultCodes)(disassoc_cnf->disassocTrigger ==
+		eLIM_LINK_MONITORING_DISASSOC) ?
+		eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE :
+		disassoc_cnf->resultCode;
+	if (LIM_IS_STA_ROLE(session_entry)) {
+		/* Disassociate Confirm from MLM */
+		if ((session_entry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)
+			&& (session_entry->limSmeState !=
+			eLIM_SME_WT_DEAUTH_STATE)) {
+			/*
+			 * Should not have received
+			 * Disassocate confirm
+			 * from MLM in other states.Log error
+			 */
+			pe_err("received MLM_DISASSOC_CNF in state %X",
+				session_entry->limSmeState);
+			return;
+		}
+		if (mac_ctx->lim.gLimRspReqd)
+			mac_ctx->lim.gLimRspReqd = false;
+		if (disassoc_cnf->disassocTrigger ==
+			eLIM_PROMISCUOUS_MODE_DISASSOC) {
+			if (disassoc_cnf->resultCode != eSIR_SME_SUCCESS)
+				session_entry->limSmeState =
+					session_entry->limPrevSmeState;
+			else
+				session_entry->limSmeState =
+					eLIM_SME_OFFLINE_STATE;
+			MTRACE(mac_trace
+				(mac_ctx, TRACE_CODE_SME_STATE,
+				session_entry->peSessionId,
+				session_entry->limSmeState));
+		} else {
+			if (disassoc_cnf->resultCode != eSIR_SME_SUCCESS)
+				session_entry->limSmeState =
+					session_entry->limPrevSmeState;
+			else
+				session_entry->limSmeState =
+					eLIM_SME_IDLE_STATE;
+			MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+				session_entry->peSessionId,
+				session_entry->limSmeState));
+			lim_send_sme_disassoc_ntf(mac_ctx,
+				disassoc_cnf->peerMacAddr, result_code,
+				disassoc_cnf->disassocTrigger,
+				disassoc_cnf->aid, session_entry->smeSessionId,
+				session_entry->transactionId, session_entry);
+		}
+	} else if (LIM_IS_AP_ROLE(session_entry)) {
+		lim_send_sme_disassoc_ntf(mac_ctx, disassoc_cnf->peerMacAddr,
+			result_code, disassoc_cnf->disassocTrigger,
+			disassoc_cnf->aid, session_entry->smeSessionId,
+			session_entry->transactionId, session_entry);
+	}
+}
+
+/**
+ * lim_process_mlm_deauth_ind() - processes MLM_DEAUTH_IND
+ * @mac_ctx: global mac structure
+ * @deauth_ind: deauth indication
+ *
+ * This function is called to processes MLM_DEAUTH_IND
+ * message from MLM State machine.
+ *
+ * Return: None
+ */
+static void lim_process_mlm_deauth_ind(tpAniSirGlobal mac_ctx,
+				       tLimMlmDeauthInd *deauth_ind)
+{
+	tpPESession session;
+	uint8_t session_id;
+	enum eLimSystemRole role;
+
+	if (!deauth_ind) {
+		pe_err("deauth_ind is null");
+		return;
+	}
+	session = pe_find_session_by_bssid(mac_ctx,
+					   deauth_ind->peerMacAddr,
+					   &session_id);
+	if (!session) {
+		pe_err("session does not exist for Addr:" MAC_ADDRESS_STR,
+		       MAC_ADDR_ARRAY(deauth_ind->peerMacAddr));
+		return;
+	}
+	role = GET_LIM_SYSTEM_ROLE(session);
+	pe_debug("*** Received Deauthentication from staId=%d role=%d***",
+		 deauth_ind->aid, role);
+	if (role == eLIM_STA_ROLE) {
+		session->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+				 session->peSessionId, session->limSmeState));
+	}
+}
+
+/**
+ * lim_process_mlm_deauth_cnf()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_DEAUTH_CNF
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac       Pointer to Global MAC structure
+ * @param pMsgBuf    A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_deauth_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	uint16_t aid;
+	tSirResultCodes resultCode;
+	tLimMlmDeauthCnf *pMlmDeauthCnf;
+	tpPESession psessionEntry;
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	pMlmDeauthCnf = (tLimMlmDeauthCnf *) pMsgBuf;
+	psessionEntry = pe_find_session_by_session_id(pMac,
+				pMlmDeauthCnf->sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("session does not exist for given session Id");
+		return;
+	}
+
+	resultCode = (tSirResultCodes)
+		     (pMlmDeauthCnf->deauthTrigger ==
+		      eLIM_LINK_MONITORING_DEAUTH) ?
+		     eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE :
+		     pMlmDeauthCnf->resultCode;
+	aid = LIM_IS_AP_ROLE(psessionEntry) ? pMlmDeauthCnf->aid : 1;
+	if (LIM_IS_STA_ROLE(psessionEntry)) {
+		/* Deauth Confirm from MLM */
+		if ((psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)
+			&& psessionEntry->limSmeState !=
+					eLIM_SME_WT_DEAUTH_STATE) {
+			/**
+			 * Should not have received Deauth confirm
+			 * from MLM in other states.
+			 * Log error
+			 */
+			pe_err("received unexpected MLM_DEAUTH_CNF in state %X",
+				       psessionEntry->limSmeState);
+			return;
+		}
+		if (pMlmDeauthCnf->resultCode == eSIR_SME_SUCCESS) {
+			psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
+			pe_debug("*** Deauthenticated with BSS ***");
+		} else
+			psessionEntry->limSmeState =
+				psessionEntry->limPrevSmeState;
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+			       psessionEntry->limSmeState));
+
+		if (pMac->lim.gLimRspReqd)
+			pMac->lim.gLimRspReqd = false;
+	}
+	/* On STA or on BASIC AP, send SME_DEAUTH_RSP to host */
+	lim_send_sme_deauth_ntf(pMac, pMlmDeauthCnf->peer_macaddr.bytes,
+				resultCode,
+				pMlmDeauthCnf->deauthTrigger,
+				aid, psessionEntry->smeSessionId,
+				psessionEntry->transactionId);
+} /*** end lim_process_mlm_deauth_cnf() ***/
+
+/**
+ * lim_process_mlm_purge_sta_ind()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_PURGE_STA_IND
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac       Pointer to Global MAC structure
+ * @param pMsgBuf    A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_purge_sta_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	tSirResultCodes resultCode;
+	tpLimMlmPurgeStaInd pMlmPurgeStaInd;
+	tpPESession psessionEntry;
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	pMlmPurgeStaInd = (tpLimMlmPurgeStaInd) pMsgBuf;
+	psessionEntry = pe_find_session_by_session_id(pMac,
+				pMlmPurgeStaInd->sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("session does not exist for given bssId");
+		return;
+	}
+	/* Purge STA indication from MLM */
+	resultCode = (tSirResultCodes) pMlmPurgeStaInd->reasonCode;
+	switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+	case eLIM_STA_IN_IBSS_ROLE:
+		break;
+	case eLIM_STA_ROLE:
+	default:        /* eLIM_AP_ROLE */
+		if (LIM_IS_STA_ROLE(psessionEntry) &&
+		   (psessionEntry->limSmeState !=
+			eLIM_SME_WT_DISASSOC_STATE) &&
+		   (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) {
+			/**
+			 * Should not have received
+			 * Purge STA indication
+			 * from MLM in other states.
+			 * Log error
+			 */
+			pe_err("received unexpected MLM_PURGE_STA_IND in state %X",
+				       psessionEntry->limSmeState);
+			break;
+		}
+		pe_debug("*** Cleanup completed for staId=%d ***",
+			       pMlmPurgeStaInd->aid);
+		if (LIM_IS_STA_ROLE(psessionEntry)) {
+			psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
+			MTRACE(mac_trace
+				       (pMac, TRACE_CODE_SME_STATE,
+				       psessionEntry->peSessionId,
+				       psessionEntry->limSmeState));
+
+		}
+		if (pMlmPurgeStaInd->purgeTrigger == eLIM_PEER_ENTITY_DEAUTH) {
+			lim_send_sme_deauth_ntf(pMac,
+						pMlmPurgeStaInd->peerMacAddr,
+						resultCode,
+						pMlmPurgeStaInd->purgeTrigger,
+						pMlmPurgeStaInd->aid,
+						psessionEntry->smeSessionId,
+						psessionEntry->transactionId);
+		} else
+			lim_send_sme_disassoc_ntf(pMac,
+						  pMlmPurgeStaInd->peerMacAddr,
+						  resultCode,
+						  pMlmPurgeStaInd->purgeTrigger,
+						  pMlmPurgeStaInd->aid,
+						  psessionEntry->smeSessionId,
+						  psessionEntry->transactionId,
+						  psessionEntry);
+	} /* end switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) */
+} /*** end lim_process_mlm_purge_sta_ind() ***/
+
+/**
+ * lim_process_mlm_set_keys_cnf()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_SETKEYS_CNF
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac       Pointer to Global MAC structure
+ * @param pMsgBuf    A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_set_keys_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	/* Prepare and send SME_SETCONTEXT_RSP message */
+	tLimMlmSetKeysCnf *pMlmSetKeysCnf;
+	tpPESession psessionEntry;
+	uint16_t aid;
+	tpDphHashNode sta_ds;
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	pMlmSetKeysCnf = (tLimMlmSetKeysCnf *) pMsgBuf;
+	psessionEntry = pe_find_session_by_session_id(pMac,
+					   pMlmSetKeysCnf->sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("session does not exist for given sessionId");
+		return;
+	}
+	psessionEntry->is_key_installed = 0;
+	pe_debug("Received MLM_SETKEYS_CNF with resultCode = %d",
+		pMlmSetKeysCnf->resultCode);
+	/* if the status is success keys are installed in the
+	* Firmware so we can set the protection bit
+	*/
+	if (eSIR_SME_SUCCESS == pMlmSetKeysCnf->resultCode) {
+		if (pMlmSetKeysCnf->key_len_nonzero)
+			psessionEntry->is_key_installed = 1;
+		if (LIM_IS_AP_ROLE(psessionEntry)) {
+			sta_ds = dph_lookup_hash_entry(pMac,
+				pMlmSetKeysCnf->peer_macaddr.bytes,
+				&aid, &psessionEntry->dph.dphHashTable);
+			if (sta_ds != NULL && pMlmSetKeysCnf->key_len_nonzero)
+				sta_ds->is_key_installed = 1;
+		}
+	}
+	pe_debug("is_key_installed = %d", psessionEntry->is_key_installed);
+
+	lim_send_sme_set_context_rsp(pMac,
+				     pMlmSetKeysCnf->peer_macaddr,
+				     1,
+				     (tSirResultCodes) pMlmSetKeysCnf->resultCode,
+				     psessionEntry, psessionEntry->smeSessionId,
+				     psessionEntry->transactionId);
+} /*** end lim_process_mlm_set_keys_cnf() ***/
+
+/**
+ * lim_join_result_callback() - Callback to handle join rsp
+ * @mac: Pointer to Global MAC structure
+ * @param: callback argument
+ * @status: status
+ *
+ * This callback function is used to delete PE session
+ * entry and send join response to sme.
+ *
+ * Return: None
+ */
+static void lim_join_result_callback(tpAniSirGlobal mac, void *param,
+				     bool status)
+{
+	join_params *link_state_params = (join_params *) param;
+	tpPESession session;
+	uint8_t sme_session_id;
+	uint16_t sme_trans_id;
+
+	if (!link_state_params) {
+		pe_err("Link state params is NULL");
+		return;
+	}
+	session = pe_find_session_by_session_id(mac, link_state_params->
+						pe_session_id);
+	if (!session) {
+		qdf_mem_free(link_state_params);
+		return;
+	}
+	sme_session_id = session->smeSessionId;
+	sme_trans_id = session->transactionId;
+	lim_send_sme_join_reassoc_rsp(mac, eWNI_SME_JOIN_RSP,
+				      link_state_params->result_code,
+				      link_state_params->prot_status_code,
+				      session, sme_session_id, sme_trans_id);
+	pe_delete_session(mac, session);
+	qdf_mem_free(link_state_params);
+}
+
+#ifdef CONFIG_VDEV_SM
+QDF_STATUS lim_sta_send_down_link(join_params *param)
+{
+	tpPESession session;
+	tpAniSirGlobal mac_ctx;
+	tpDphHashNode sta_ds = NULL;
+
+	if (!param) {
+		pe_err("param is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac_ctx) {
+		pe_err("Mac context is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	session = pe_find_session_by_session_id(mac_ctx, param->pe_session_id);
+	if (!session) {
+		pe_err("session is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	sta_ds = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+				    &session->dph.dphHashTable);
+	if (sta_ds) {
+		sta_ds->mlmStaContext.disassocReason =
+			eSIR_MAC_UNSPEC_FAILURE_REASON;
+		sta_ds->mlmStaContext.cleanupTrigger =
+			eLIM_JOIN_FAILURE;
+		sta_ds->mlmStaContext.resultCode = param->result_code;
+		sta_ds->mlmStaContext.protStatusCode = param->prot_status_code;
+		/*
+		 * FIX_ME: at the end of lim_cleanup_rx_path,
+		 * make sure PE is sending eWNI_SME_JOIN_RSP
+		 * to SME
+		 */
+		lim_cleanup_rx_path(mac_ctx, sta_ds, session);
+		qdf_mem_free(session->pLimJoinReq);
+		session->pLimJoinReq = NULL;
+		/* Cleanup if add bss failed */
+		if (session->add_bss_failed) {
+			dph_delete_hash_entry(mac_ctx,
+				 sta_ds->staAddr, sta_ds->assocId,
+				 &session->dph.dphHashTable);
+			goto error;
+		}
+		return QDF_STATUS_SUCCESS;
+	}
+	qdf_mem_free(session->pLimJoinReq);
+	session->pLimJoinReq = NULL;
+
+error:
+	/*
+	 * Delete the session if JOIN failure occurred.
+	 * if the peer is not created, then there is no
+	 * need to send down the set link state which will
+	 * try to delete the peer. Instead a join response
+	 * failure should be sent to the upper layers.
+	 */
+	if (param->result_code != eSIR_SME_PEER_CREATE_FAILED) {
+		join_params *link_state_arg;
+
+		link_state_arg = qdf_mem_malloc(sizeof(*link_state_arg));
+		if (link_state_arg) {
+			link_state_arg->result_code = param->result_code;
+			link_state_arg->prot_status_code =
+							param->prot_status_code;
+			link_state_arg->pe_session_id = session->peSessionId;
+		}
+		if (lim_set_link_state(mac_ctx, eSIR_LINK_DOWN_STATE,
+				       session->bssId,
+				       session->selfMacAddr,
+				       lim_join_result_callback,
+				       link_state_arg) != QDF_STATUS_SUCCESS) {
+			qdf_mem_free(link_state_arg);
+			pe_err("Failed to set the LinkState");
+		}
+		return QDF_STATUS_SUCCESS;
+	}
+
+
+	lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP,
+				      param->result_code,
+				      param->prot_status_code,
+				      session, session->smeSessionId,
+				      session->transactionId);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_handle_sme_join_result() - Handles sme join result
+ * @mac_ctx:  Pointer to Global MAC structure
+ * @result_code: Failure code to be sent
+ * @prot_status_code : Protocol status code
+ * @session_entry: PE session handle
+ *
+ * This function is called to process join/auth/assoc failures
+ * upon receiving MLM_JOIN/AUTH/ASSOC_CNF with a failure code or
+ * MLM_ASSOC_CNF with a success code in case of STA role and
+ * MLM_JOIN_CNF with success in case of STA in IBSS role.
+ *
+ * Return: None
+ */
+void lim_handle_sme_join_result(tpAniSirGlobal mac_ctx,
+	tSirResultCodes result_code, uint16_t prot_status_code,
+	tpPESession session)
+{
+	join_params param;
+	QDF_STATUS status;
+
+	if (!session) {
+		pe_err("session is NULL");
+		return;
+	}
+	if (result_code == eSIR_SME_SUCCESS)
+		return lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP,
+						     result_code,
+						     prot_status_code, session,
+						     session->smeSessionId,
+						     session->transactionId);
+
+	param.result_code = result_code;
+	param.prot_status_code = prot_status_code;
+	param.pe_session_id = session->peSessionId;
+
+	mlme_set_connection_fail(session->vdev, true);
+	status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					       WLAN_VDEV_SM_EV_CONNECTION_FAIL,
+					       sizeof(param), &param);
+	return;
+}
+#else
+void lim_handle_sme_join_result(tpAniSirGlobal mac_ctx,
+	tSirResultCodes result_code, uint16_t prot_status_code,
+	tpPESession session_entry)
+{
+	tpDphHashNode sta_ds = NULL;
+	uint8_t sme_session_id;
+	uint16_t sme_trans_id;
+	join_params *param = NULL;
+
+	if (session_entry == NULL) {
+		pe_err("psessionEntry is NULL");
+		return;
+	}
+	sme_session_id = session_entry->smeSessionId;
+	sme_trans_id = session_entry->transactionId;
+	/*
+	 * When associations is failed , delete the session created
+	 * and pass NULL  to  limsendsmeJoinReassocRsp()
+	 */
+	if (result_code != eSIR_SME_SUCCESS) {
+		sta_ds =
+			dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+				&session_entry->dph.dphHashTable);
+		if (sta_ds != NULL) {
+			sta_ds->mlmStaContext.disassocReason =
+				eSIR_MAC_UNSPEC_FAILURE_REASON;
+			sta_ds->mlmStaContext.cleanupTrigger =
+				eLIM_JOIN_FAILURE;
+			sta_ds->mlmStaContext.resultCode = result_code;
+			sta_ds->mlmStaContext.protStatusCode = prot_status_code;
+			/*
+			 * FIX_ME: at the end of lim_cleanup_rx_path,
+			 * make sure PE is sending eWNI_SME_JOIN_RSP
+			 * to SME
+			 */
+			lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry);
+			qdf_mem_free(session_entry->pLimJoinReq);
+			session_entry->pLimJoinReq = NULL;
+			/* Cleanup if add bss failed */
+			if (session_entry->add_bss_failed) {
+				dph_delete_hash_entry(mac_ctx,
+					 sta_ds->staAddr, sta_ds->assocId,
+					 &session_entry->dph.dphHashTable);
+				goto error;
+			}
+			return;
+		}
+		qdf_mem_free(session_entry->pLimJoinReq);
+		session_entry->pLimJoinReq = NULL;
+	}
+error:
+	/* Delete the session if JOIN failure occurred.
+	 * if the peer is not created, then there is no
+	 * need to send down the set link state which will
+	 * try to delete the peer. Instead a join response
+	 * failure should be sent to the upper layers.
+	 */
+	if (result_code != eSIR_SME_SUCCESS &&
+	    result_code != eSIR_SME_PEER_CREATE_FAILED) {
+		param = qdf_mem_malloc(sizeof(join_params));
+		if (param != NULL) {
+			param->result_code = result_code;
+			param->prot_status_code = prot_status_code;
+			param->pe_session_id = session_entry->peSessionId;
+		}
+		if (lim_set_link_state(mac_ctx, eSIR_LINK_DOWN_STATE,
+				       session_entry->bssId,
+				       session_entry->selfMacAddr,
+				       lim_join_result_callback,
+				       param) != QDF_STATUS_SUCCESS) {
+			qdf_mem_free(param);
+			pe_err("Failed to set the LinkState");
+		}
+		return;
+	}
+
+	lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP, result_code,
+		prot_status_code, session_entry, sme_session_id, sme_trans_id);
+}
+#endif
+
+
+/**
+ * lim_process_mlm_add_sta_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to process a WMA_ADD_STA_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Determines the "state" in which this message was received
+ * > Forwards it to the appropriate callback
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac      Pointer to Global MAC structure
+ * @param  struct scheduler_msg  The MsgQ header, which contains the
+ *  response buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_add_sta_rsp(tpAniSirGlobal pMac,
+				 struct scheduler_msg *limMsgQ,
+				 tpPESession psessionEntry)
+{
+	/* we need to process the deferred message since the initiating req. there might be nested request. */
+	/* in the case of nested request the new request initiated from the response will take care of resetting */
+	/* the deffered flag. */
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+	if (LIM_IS_AP_ROLE(psessionEntry)) {
+		lim_process_ap_mlm_add_sta_rsp(pMac, limMsgQ, psessionEntry);
+		return;
+	}
+	lim_process_sta_mlm_add_sta_rsp(pMac, limMsgQ, psessionEntry);
+}
+
+/**
+ * lim_process_sta_mlm_add_sta_rsp () - Process add sta response
+ * @mac_ctx:  Pointer to mac context
+ * @msg:  struct scheduler_msg *an Message structure
+ * @session_entry: PE session entry
+ *
+ * Process ADD STA response sent from WMA and posts results
+ * to SME.
+ *
+ * Return: Null
+ */
+
+void lim_process_sta_mlm_add_sta_rsp(tpAniSirGlobal mac_ctx,
+	struct scheduler_msg *msg, tpPESession session_entry)
+{
+	tLimMlmAssocCnf mlm_assoc_cnf;
+	tpDphHashNode sta_ds;
+	uint32_t msg_type = LIM_MLM_ASSOC_CNF;
+	tpAddStaParams add_sta_params = (tpAddStaParams) msg->bodyptr;
+	tpPESession ft_session = NULL;
+	uint8_t ft_session_id;
+
+	if (NULL == add_sta_params) {
+		pe_err("Encountered NULL Pointer");
+		return;
+	}
+
+	if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE)
+		msg_type = LIM_MLM_REASSOC_CNF;
+
+	if (true == session_entry->fDeauthReceived) {
+		pe_err("Received Deauth frame in ADD_STA_RESP state");
+		if (QDF_STATUS_SUCCESS == add_sta_params->status) {
+			pe_err("ADD_STA success, send update result code with eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA staIdx: %d limMlmState: %d",
+				add_sta_params->staIdx,
+				session_entry->limMlmState);
+
+			if (session_entry->limSmeState ==
+					eLIM_SME_WT_REASSOC_STATE)
+				msg_type = LIM_MLM_REASSOC_CNF;
+			/*
+			 * We are sending result code
+			 * eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA which
+			 * will trigger proper cleanup (DEL_STA/DEL_BSS both
+			 * required) in either assoc cnf or reassoc cnf handler.
+			 */
+			mlm_assoc_cnf.resultCode =
+				eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA;
+			mlm_assoc_cnf.protStatusCode =
+					   eSIR_MAC_UNSPEC_FAILURE_STATUS;
+			session_entry->staId = add_sta_params->staIdx;
+			goto end;
+		}
+	}
+
+	if (QDF_STATUS_SUCCESS == add_sta_params->status) {
+		if (eLIM_MLM_WT_ADD_STA_RSP_STATE !=
+			session_entry->limMlmState) {
+			pe_err("Received WMA_ADD_STA_RSP in state %X",
+				session_entry->limMlmState);
+			mlm_assoc_cnf.resultCode =
+				(tSirResultCodes) eSIR_SME_REFUSED;
+			goto end;
+		}
+		if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE) {
+			/* check if we have keys(PTK)to install in case of 11r */
+			tpftPEContext ft_ctx = &session_entry->ftPEContext;
+
+			ft_session = pe_find_session_by_bssid(mac_ctx,
+				session_entry->limReAssocbssId, &ft_session_id);
+			if (ft_session != NULL &&
+				ft_ctx->PreAuthKeyInfo.extSetStaKeyParamValid
+				== true) {
+				tpLimMlmSetKeysReq pMlmStaKeys =
+					&ft_ctx->PreAuthKeyInfo.extSetStaKeyParam;
+				lim_send_set_sta_key_req(mac_ctx, pMlmStaKeys,
+					0, 0, ft_session, false);
+				ft_ctx->PreAuthKeyInfo.extSetStaKeyParamValid =
+					false;
+			}
+		}
+		/*
+		 * Update the DPH Hash Entry for this STA
+		 * with proper state info
+		 */
+		sta_ds =
+			dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+				&session_entry->dph.dphHashTable);
+		if (NULL != sta_ds) {
+			sta_ds->mlmStaContext.mlmState =
+				eLIM_MLM_LINK_ESTABLISHED_STATE;
+			sta_ds->nss = add_sta_params->nss;
+		} else
+			pe_warn("Fail to get DPH Hash Entry for AID - %d",
+				DPH_STA_HASH_INDEX_PEER);
+		session_entry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+			session_entry->peSessionId,
+			session_entry->limMlmState));
+		/*
+		 * Storing the self StaIndex(Generated by HAL) in
+		 * session context, instead of storing it in DPH Hash
+		 * entry for Self STA.
+		 * DPH entry for the self STA stores the sta index for
+		 * the BSS entry to which the STA is associated
+		 */
+		session_entry->staId = add_sta_params->staIdx;
+
+#ifdef WLAN_DEBUG
+		mac_ctx->lim.gLimNumLinkEsts++;
+#endif
+#ifdef FEATURE_WLAN_TDLS
+		/* initialize TDLS peer related data */
+		lim_init_tdls_data(mac_ctx, session_entry);
+#endif
+		/*
+		 * Return Assoc confirm to SME with success
+		 * FIXME - Need the correct ASSOC RSP code to
+		 * be passed in here
+		 */
+		mlm_assoc_cnf.resultCode = (tSirResultCodes) eSIR_SME_SUCCESS;
+		lim_send_obss_color_collision_cfg(mac_ctx, session_entry,
+					OBSS_COLOR_COLLISION_DETECTION);
+		if (lim_is_session_he_capable(session_entry)) {
+			if (mac_ctx->usr_cfg_mu_edca_params) {
+				pe_debug("Send user cfg MU EDCA params to FW");
+				lim_send_edca_params(mac_ctx,
+					     mac_ctx->usr_mu_edca_params,
+					     sta_ds->bssId, true);
+			} else if (session_entry->mu_edca_present) {
+				pe_debug("Send MU EDCA params to FW");
+				lim_send_edca_params(mac_ctx,
+					session_entry->ap_mu_edca_params,
+					sta_ds->bssId, true);
+			}
+		}
+	} else {
+		pe_err("ADD_STA failed!");
+		if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE)
+			mlm_assoc_cnf.resultCode =
+				(tSirResultCodes) eSIR_SME_FT_REASSOC_FAILURE;
+		else
+			mlm_assoc_cnf.resultCode =
+				(tSirResultCodes) eSIR_SME_REFUSED;
+		mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+	}
+end:
+	if (NULL != msg->bodyptr) {
+		qdf_mem_free(add_sta_params);
+		msg->bodyptr = NULL;
+	}
+	/* Updating PE session Id */
+	mlm_assoc_cnf.sessionId = session_entry->peSessionId;
+	lim_post_sme_message(mac_ctx, msg_type, (uint32_t *) &mlm_assoc_cnf);
+	if (true == session_entry->fDeauthReceived)
+		session_entry->fDeauthReceived = false;
+	return;
+}
+
+void lim_process_mlm_del_bss_rsp(tpAniSirGlobal pMac,
+				 struct scheduler_msg *limMsgQ,
+				 tpPESession psessionEntry)
+{
+	/* we need to process the deferred message since the initiating req. there might be nested request. */
+	/* in the case of nested request the new request initiated from the response will take care of resetting */
+	/* the deffered flag. */
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+	pMac->sys.gSysFrameCount[SIR_MAC_MGMT_FRAME][SIR_MAC_MGMT_DEAUTH] = 0;
+
+	if (LIM_IS_AP_ROLE(psessionEntry) &&
+	    (psessionEntry->statypeForBss == STA_ENTRY_SELF)) {
+		lim_process_ap_mlm_del_bss_rsp(pMac, limMsgQ, psessionEntry);
+		return;
+	}
+	lim_process_sta_mlm_del_bss_rsp(pMac, limMsgQ, psessionEntry);
+
+#ifdef WLAN_FEATURE_11W
+	if (psessionEntry->limRmfEnabled) {
+		if (QDF_STATUS_SUCCESS !=
+		    lim_send_exclude_unencrypt_ind(pMac, true, psessionEntry)) {
+			pe_err("Could not send down Exclude Unencrypted Indication!");
+		}
+	}
+#endif
+}
+
+void lim_process_sta_mlm_del_bss_rsp(tpAniSirGlobal pMac,
+				     struct scheduler_msg *limMsgQ,
+				     tpPESession psessionEntry)
+{
+	tpDeleteBssParams pDelBssParams = (tpDeleteBssParams) limMsgQ->bodyptr;
+	tpDphHashNode pStaDs =
+		dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+				   &psessionEntry->dph.dphHashTable);
+	tSirResultCodes statusCode = eSIR_SME_SUCCESS;
+
+	if (NULL == pDelBssParams) {
+		pe_err("Invalid body pointer in message");
+		goto end;
+	}
+	if (QDF_STATUS_SUCCESS == pDelBssParams->status) {
+		pe_debug("STA received the DEL_BSS_RSP for BSSID: %X",
+			       pDelBssParams->bssIdx);
+		if (lim_set_link_state
+			    (pMac, eSIR_LINK_IDLE_STATE, psessionEntry->bssId,
+			    psessionEntry->selfMacAddr, NULL,
+			    NULL) != QDF_STATUS_SUCCESS) {
+			pe_err("Failure in setting link state to IDLE");
+			statusCode = eSIR_SME_REFUSED;
+			goto end;
+		}
+		if (pStaDs == NULL) {
+			pe_err("DPH Entry for STA 1 missing");
+			statusCode = eSIR_SME_REFUSED;
+			goto end;
+		}
+		if (eLIM_MLM_WT_DEL_BSS_RSP_STATE !=
+		    pStaDs->mlmStaContext.mlmState) {
+			pe_err("Received unexpected WMA_DEL_BSS_RSP in state %X",
+				       pStaDs->mlmStaContext.mlmState);
+			statusCode = eSIR_SME_REFUSED;
+			goto end;
+		}
+		pe_debug("STA AssocID %d MAC",	pStaDs->assocId);
+		       lim_print_mac_addr(pMac, pStaDs->staAddr, LOGD);
+	} else {
+		pe_err("DEL BSS failed!");
+		statusCode = eSIR_SME_STOP_BSS_FAILURE;
+	}
+end:
+	if (0 != limMsgQ->bodyptr) {
+		qdf_mem_free(pDelBssParams);
+		limMsgQ->bodyptr = NULL;
+	}
+	if (pStaDs == NULL)
+		return;
+	if ((LIM_IS_STA_ROLE(psessionEntry)) &&
+	    (psessionEntry->limSmeState !=
+			eLIM_SME_WT_DISASSOC_STATE &&
+	    psessionEntry->limSmeState !=
+			eLIM_SME_WT_DEAUTH_STATE) &&
+	    pStaDs->mlmStaContext.cleanupTrigger !=
+			eLIM_JOIN_FAILURE) {
+		/** The Case where the DelBss is invoked from
+		 *  context of other than normal DisAssoc / Deauth OR
+		 *  as part of Join Failure.
+		 */
+		lim_handle_del_bss_in_re_assoc_context(pMac, pStaDs, psessionEntry);
+		return;
+	}
+	lim_prepare_and_send_del_sta_cnf(pMac, pStaDs, statusCode, psessionEntry);
+	return;
+}
+
+void lim_process_ap_mlm_del_bss_rsp(tpAniSirGlobal pMac,
+				    struct scheduler_msg *limMsgQ,
+				    tpPESession psessionEntry)
+{
+	tSirResultCodes rc = eSIR_SME_SUCCESS;
+	QDF_STATUS status;
+	tpDeleteBssParams pDelBss = (tpDeleteBssParams) limMsgQ->bodyptr;
+	tSirMacAddr nullBssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+	if (psessionEntry == NULL) {
+		pe_err("Session entry passed is NULL");
+		if (pDelBss != NULL) {
+			qdf_mem_free(pDelBss);
+			limMsgQ->bodyptr = NULL;
+		}
+		return;
+	}
+
+	if (pDelBss == NULL) {
+		pe_err("BSS: DEL_BSS_RSP with no body!");
+		rc = eSIR_SME_REFUSED;
+		goto end;
+	}
+	pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, NO_SESSION,
+		       pMac->lim.gLimMlmState));
+
+	if (eLIM_MLM_WT_DEL_BSS_RSP_STATE != psessionEntry->limMlmState) {
+		pe_err("Received unexpected WMA_DEL_BSS_RSP in state %X",
+			psessionEntry->limMlmState);
+		rc = eSIR_SME_REFUSED;
+		goto end;
+	}
+	if (pDelBss->status != QDF_STATUS_SUCCESS) {
+		pe_err("BSS: DEL_BSS_RSP error (%x) Bss %d",
+			pDelBss->status, pDelBss->bssIdx);
+		rc = eSIR_SME_STOP_BSS_FAILURE;
+		goto end;
+	}
+	status = lim_set_link_state(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
+				    psessionEntry->selfMacAddr, NULL, NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		rc = eSIR_SME_REFUSED;
+		goto end;
+	}
+	/** Softmac may send all the buffered packets right after resuming the transmission hence
+	 * to occupy the medium during non channel occupancy period. So resume the transmission after
+	 * HAL gives back the response.
+	 */
+	dph_hash_table_class_init(pMac, &psessionEntry->dph.dphHashTable);
+	lim_delete_pre_auth_list(pMac);
+	/* Initialize number of associated stations during cleanup */
+	psessionEntry->gLimNumOfCurrentSTAs = 0;
+end:
+	lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP, rc,
+			 psessionEntry->smeSessionId,
+			 psessionEntry->transactionId);
+	pe_delete_session(pMac, psessionEntry);
+
+	if (pDelBss != NULL) {
+		qdf_mem_free(pDelBss);
+		limMsgQ->bodyptr = NULL;
+	}
+}
+
+/**
+ * lim_process_mlm_del_sta_rsp() - Process DEL STA response
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: The MsgQ header, which contains the response buffer
+ *
+ * This function is called to process a WMA_DEL_STA_RSP from
+ * WMA Upon receipt of this message from FW.
+ *
+ * Return: None
+ */
+void lim_process_mlm_del_sta_rsp(tpAniSirGlobal mac_ctx,
+	struct scheduler_msg *msg)
+{
+	/*
+	 * we need to process the deferred message since the
+	 * initiating req. there might be nested request
+	 * in the case of nested request the new request
+	 * initiated from the response will take care of resetting
+	 * the deffered flag.
+	 */
+	tpPESession session_entry;
+	tpDeleteStaParams del_sta_params;
+
+	del_sta_params = (tpDeleteStaParams) msg->bodyptr;
+	if (NULL == del_sta_params) {
+		pe_err("null pointer del_sta_params msg");
+		return;
+	}
+	SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+
+	session_entry = pe_find_session_by_session_id(mac_ctx,
+				del_sta_params->sessionId);
+	if (NULL == session_entry) {
+		pe_err("Session Doesn't exist: %d",
+			del_sta_params->sessionId);
+		qdf_mem_free(del_sta_params);
+		msg->bodyptr = NULL;
+		return;
+	}
+
+	if (LIM_IS_AP_ROLE(session_entry)) {
+		lim_process_ap_mlm_del_sta_rsp(mac_ctx, msg,
+				session_entry);
+		return;
+	}
+	if (LIM_IS_IBSS_ROLE(session_entry)) {
+		lim_process_ibss_del_sta_rsp(mac_ctx, msg,
+				session_entry);
+		return;
+	}
+	if (LIM_IS_NDI_ROLE(session_entry)) {
+		lim_process_ndi_del_sta_rsp(mac_ctx, msg, session_entry);
+		return;
+	}
+	lim_process_sta_mlm_del_sta_rsp(mac_ctx, msg, session_entry);
+}
+
+/**
+ * lim_process_ap_mlm_del_sta_rsp() - Process WMA_DEL_STA_RSP
+ * @mac_ctx: Global pointer to MAC context
+ * @msg: Received message
+ * @session_entry: Session entry
+ *
+ * Process WMA_DEL_STA_RSP for AP role
+ *
+ * Retunrn: None
+ */
+void lim_process_ap_mlm_del_sta_rsp(tpAniSirGlobal mac_ctx,
+					   struct scheduler_msg *msg,
+					   tpPESession session_entry)
+{
+	tpDeleteStaParams del_sta_params = (tpDeleteStaParams) msg->bodyptr;
+	tpDphHashNode sta_ds;
+	tSirResultCodes status_code = eSIR_SME_SUCCESS;
+
+	if (msg->bodyptr == NULL) {
+		pe_err("msg->bodyptr NULL");
+		return;
+	}
+
+	sta_ds = dph_get_hash_entry(mac_ctx, del_sta_params->assocId,
+				    &session_entry->dph.dphHashTable);
+	if (sta_ds == NULL) {
+		pe_err("DPH Entry for STA %X missing",
+			del_sta_params->assocId);
+		status_code = eSIR_SME_REFUSED;
+		qdf_mem_free(del_sta_params);
+		msg->bodyptr = NULL;
+		return;
+	}
+	pe_debug("Received del Sta Rsp in StaD MlmState: %d",
+		sta_ds->mlmStaContext.mlmState);
+	if (QDF_STATUS_SUCCESS != del_sta_params->status) {
+		pe_warn("DEL STA failed!");
+		status_code = eSIR_SME_REFUSED;
+		goto end;
+	}
+
+	pe_warn("AP received the DEL_STA_RSP for assocID: %X",
+		del_sta_params->assocId);
+	if ((eLIM_MLM_WT_DEL_STA_RSP_STATE != sta_ds->mlmStaContext.mlmState) &&
+	    (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE !=
+	     sta_ds->mlmStaContext.mlmState)) {
+		pe_err("Received unexpected WMA_DEL_STA_RSP in state %s for staId %d assocId %d",
+			lim_mlm_state_str(sta_ds->mlmStaContext.mlmState),
+			sta_ds->staIndex, sta_ds->assocId);
+		status_code = eSIR_SME_REFUSED;
+		goto end;
+	}
+
+	pe_debug("Deleted STA AssocID %d staId %d MAC",
+		sta_ds->assocId, sta_ds->staIndex);
+	lim_print_mac_addr(mac_ctx, sta_ds->staAddr, LOGD);
+	if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE ==
+	    sta_ds->mlmStaContext.mlmState) {
+		qdf_mem_free(del_sta_params);
+		msg->bodyptr = NULL;
+		if (lim_add_sta(mac_ctx, sta_ds, false, session_entry) !=
+		    QDF_STATUS_SUCCESS) {
+			pe_err("could not Add STA with assocId: %d",
+				sta_ds->assocId);
+			/*
+			 * delete the TS if it has already been added.
+			 * send the response with error status.
+			 */
+			if (sta_ds->qos.addtsPresent) {
+				tpLimTspecInfo pTspecInfo;
+
+				if (QDF_STATUS_SUCCESS ==
+				    lim_tspec_find_by_assoc_id(mac_ctx,
+					sta_ds->assocId,
+					&sta_ds->qos.addts.tspec,
+					&mac_ctx->lim.tspecInfo[0],
+					&pTspecInfo)) {
+					lim_admit_control_delete_ts(mac_ctx,
+						sta_ds->assocId,
+						&sta_ds->qos.addts.tspec.tsinfo,
+						NULL,
+						&pTspecInfo->idx);
+				}
+			}
+			lim_reject_association(mac_ctx, sta_ds->staAddr,
+				sta_ds->mlmStaContext.subType, true,
+				sta_ds->mlmStaContext.authType, sta_ds->assocId,
+				true,
+				eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				session_entry);
+		}
+		return;
+	}
+end:
+	qdf_mem_free(del_sta_params);
+	msg->bodyptr = NULL;
+	if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE !=
+	    sta_ds->mlmStaContext.mlmState) {
+		lim_prepare_and_send_del_sta_cnf(mac_ctx, sta_ds, status_code,
+						 session_entry);
+	}
+	return;
+}
+
+void lim_process_sta_mlm_del_sta_rsp(tpAniSirGlobal pMac,
+				     struct scheduler_msg *limMsgQ,
+				     tpPESession psessionEntry)
+{
+	tSirResultCodes statusCode = eSIR_SME_SUCCESS;
+	tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr;
+	tpDphHashNode pStaDs = NULL;
+#ifdef CONFIG_VDEV_SM
+	QDF_STATUS status;
+#endif
+
+	if (NULL == pDelStaParams) {
+		pe_err("Encountered NULL Pointer");
+		goto end;
+	}
+	pe_debug("Del STA RSP received. Status: %d AssocID: %d",
+			pDelStaParams->status, pDelStaParams->assocId);
+
+#ifdef FEATURE_WLAN_TDLS
+	if (pDelStaParams->staType == STA_ENTRY_TDLS_PEER) {
+		pe_debug("TDLS Del STA RSP received");
+		lim_process_tdls_del_sta_rsp(pMac, limMsgQ, psessionEntry);
+		return;
+	}
+#endif
+	if (QDF_STATUS_SUCCESS != pDelStaParams->status)
+		pe_err("Del STA failed! Status:%d, proceeding with Del BSS",
+			pDelStaParams->status);
+
+	pStaDs = dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+			&psessionEntry->dph.dphHashTable);
+	if (pStaDs == NULL) {
+		pe_err("DPH Entry for STA %X missing",
+				pDelStaParams->assocId);
+		statusCode = eSIR_SME_REFUSED;
+		goto end;
+	}
+	if (eLIM_MLM_WT_DEL_STA_RSP_STATE != psessionEntry->limMlmState) {
+		pe_err("Received unexpected WDA_DELETE_STA_RSP in state %s",
+			lim_mlm_state_str(psessionEntry->limMlmState));
+		statusCode = eSIR_SME_REFUSED;
+		goto end;
+	}
+	pe_debug("STA AssocID %d MAC", pStaDs->assocId);
+	lim_print_mac_addr(pMac, pStaDs->staAddr, LOGD);
+	/*
+	 * we must complete all cleanup related to delSta before
+	 * calling limDelBSS.
+	 */
+	if (0 != limMsgQ->bodyptr) {
+		qdf_mem_free(pDelStaParams);
+		limMsgQ->bodyptr = NULL;
+	}
+#ifdef CONFIG_VDEV_SM
+	status =
+	    wlan_vdev_mlme_sm_deliver_evt(psessionEntry->vdev,
+					  WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE,
+					  sizeof(*psessionEntry),
+					  psessionEntry);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("failed to post WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE for vdevid %d",
+		       psessionEntry->smeSessionId);
+	}
+#else
+	/* Proceed to do DelBSS even if DelSta resulted in failure */
+	statusCode = (tSirResultCodes)lim_del_bss(pMac, pStaDs, 0,
+			psessionEntry);
+#endif
+
+	return;
+end:
+	if (0 != limMsgQ->bodyptr) {
+		qdf_mem_free(pDelStaParams);
+		limMsgQ->bodyptr = NULL;
+	}
+	return;
+}
+
+void lim_process_ap_mlm_add_sta_rsp(tpAniSirGlobal pMac,
+				    struct scheduler_msg *limMsgQ,
+				    tpPESession psessionEntry)
+{
+	tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr;
+	tpDphHashNode pStaDs = NULL;
+
+	if (NULL == pAddStaParams) {
+		pe_err("Invalid body pointer in message");
+		goto end;
+	}
+
+	pStaDs =
+		dph_get_hash_entry(pMac, pAddStaParams->assocId,
+				   &psessionEntry->dph.dphHashTable);
+	if (pStaDs == NULL) {
+		pe_err("DPH Entry for STA %X missing", pAddStaParams->assocId);
+		goto end;
+	}
+
+	if (eLIM_MLM_WT_ADD_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState) {
+		pe_err("Received unexpected WMA_ADD_STA_RSP in state %X",
+			pStaDs->mlmStaContext.mlmState);
+		goto end;
+	}
+	if (QDF_STATUS_SUCCESS != pAddStaParams->status) {
+		pe_err("Error! rcvd delSta rsp from HAL with status %d",
+			       pAddStaParams->status);
+		lim_reject_association(pMac, pStaDs->staAddr,
+				       pStaDs->mlmStaContext.subType,
+				       true, pStaDs->mlmStaContext.authType,
+				       pStaDs->assocId, true,
+				       eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				       psessionEntry);
+		goto end;
+	}
+	pStaDs->bssId = pAddStaParams->bssIdx;
+	pStaDs->staIndex = pAddStaParams->staIdx;
+	pStaDs->nss = pAddStaParams->nss;
+	/* if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state */
+	pStaDs->valid = 1;
+	pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_CNF_STATE;
+	pe_debug("AddStaRsp Success.STA AssocID %d staId %d MAC",
+		pStaDs->assocId, pStaDs->staIndex);
+	lim_print_mac_addr(pMac, pStaDs->staAddr, LOGD);
+
+	/* For BTAMP-AP, the flow sequence shall be:
+	 * 1) PE sends eWNI_SME_ASSOC_IND to SME
+	 * 2) PE receives eWNI_SME_ASSOC_CNF from SME
+	 * 3) BTAMP-AP sends Re/Association Response to BTAMP-STA
+	 */
+	lim_send_mlm_assoc_ind(pMac, pStaDs, psessionEntry);
+	/* fall though to reclaim the original Add STA Response message */
+end:
+	if (0 != limMsgQ->bodyptr) {
+		qdf_mem_free(pAddStaParams);
+		limMsgQ->bodyptr = NULL;
+	}
+	return;
+}
+
+/**
+ * lim_process_ap_mlm_add_bss_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to process a WMA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Validates the result of WMA_ADD_BSS_REQ
+ * > Init other remaining LIM variables
+ * > Init the AID pool, for that BSSID
+ * > Init the Pre-AUTH list, for that BSSID
+ * > Create LIM timers, specific to that BSSID
+ * > Init DPH related parameters that are specific to that BSSID
+ * > TODO - When do we do the actual change channel?
+ *
+ ***LOGIC:
+ * SME sends eWNI_SME_START_BSS_REQ to LIM
+ * LIM sends LIM_MLM_START_REQ to MLME
+ * MLME sends WMA_ADD_BSS_REQ to HAL
+ * HAL responds with WMA_ADD_BSS_RSP to MLME
+ * MLME responds with LIM_MLM_START_CNF to LIM
+ * LIM responds with eWNI_SME_START_BSS_RSP to SME
+ *
+ ***ASSUMPTIONS:
+ * struct scheduler_msg.body is allocated by MLME during
+ * lim_process_mlm_start_req
+ * struct scheduler_msg.body will now be freed by this routine
+ *
+ ***NOTE:
+ *
+ * @param  pMac      Pointer to Global MAC structure
+ * @param  struct scheduler_msg  The MsgQ header, which contains
+ *  the response buffer
+ *
+ * @return None
+ */
+static void lim_process_ap_mlm_add_bss_rsp(tpAniSirGlobal pMac,
+					   struct scheduler_msg *limMsgQ)
+{
+	tLimMlmStartCnf mlmStartCnf;
+	tpPESession psessionEntry;
+	uint8_t isWepEnabled = false;
+	tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+
+	if (NULL == pAddBssParams) {
+		pe_err("Encountered NULL Pointer");
+		goto end;
+	}
+	/* TBD: free the memory before returning, do it for all places where lookup fails. */
+	psessionEntry = pe_find_session_by_session_id(pMac,
+					   pAddBssParams->sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("session does not exist for given sessionId");
+		if (NULL != pAddBssParams) {
+			qdf_mem_free(pAddBssParams);
+			limMsgQ->bodyptr = NULL;
+		}
+		return;
+	}
+	/* Update PE session Id */
+	mlmStartCnf.sessionId = pAddBssParams->sessionId;
+	if (QDF_STATUS_SUCCESS == pAddBssParams->status) {
+		pe_debug("WMA_ADD_BSS_RSP returned with QDF_STATUS_SUCCESS");
+		if (lim_set_link_state
+			    (pMac, eSIR_LINK_AP_STATE, psessionEntry->bssId,
+			    psessionEntry->selfMacAddr, NULL,
+			    NULL) != QDF_STATUS_SUCCESS)
+			goto end;
+		/* Set MLME state */
+		psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE;
+		psessionEntry->chainMask = pAddBssParams->chainMask;
+		psessionEntry->smpsMode = pAddBssParams->smpsMode;
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+			       psessionEntry->limMlmState));
+		if (eSIR_IBSS_MODE == pAddBssParams->bssType) {
+			/** IBSS is 'active' when we receive
+			 * Beacon frames from other STAs that are part of same IBSS.
+			 * Mark internal state as inactive until then.
+			 */
+			psessionEntry->limIbssActive = false;
+			psessionEntry->statypeForBss = STA_ENTRY_PEER; /* to know session created for self/peer */
+			limResetHBPktCount(psessionEntry);
+		}
+		psessionEntry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
+
+		psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+
+		if (eSIR_INFRA_AP_MODE == pAddBssParams->bssType)
+			psessionEntry->limSystemRole = eLIM_AP_ROLE;
+		else
+			psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+		sch_edca_profile_update(pMac, psessionEntry);
+		lim_init_pre_auth_list(pMac);
+		/* Check the SAP security configuration.If configured to
+		 * WEP then max clients supported is 16
+		 */
+		if (psessionEntry->privacy) {
+			if ((psessionEntry->gStartBssRSNIe.present)
+			    || (psessionEntry->gStartBssWPAIe.present))
+				pe_debug("WPA/WPA2 SAP configuration");
+			else {
+				if (pMac->mlme_cfg->sap_cfg.assoc_sta_limit >
+				    MAX_SUPPORTED_PEERS_WEP) {
+					pe_debug("WEP SAP Configuration");
+					pMac->mlme_cfg->sap_cfg.assoc_sta_limit
+					= MAX_SUPPORTED_PEERS_WEP;
+					isWepEnabled = true;
+				}
+			}
+		}
+		lim_init_peer_idxpool(pMac, psessionEntry);
+
+		/* Start OLBC timer */
+		if (tx_timer_activate
+			    (&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer) !=
+		    TX_SUCCESS) {
+			pe_err("tx_timer_activate failed");
+		}
+
+		/* Apply previously set configuration at HW */
+		lim_apply_configuration(pMac, psessionEntry);
+
+		/* In lim_apply_configuration gLimAssocStaLimit is assigned from cfg.
+		 * So update the value to 16 in case SoftAP is configured in WEP.
+		 */
+		if ((pMac->mlme_cfg->sap_cfg.assoc_sta_limit >
+		    MAX_SUPPORTED_PEERS_WEP)
+		    && (isWepEnabled))
+			pMac->mlme_cfg->sap_cfg.assoc_sta_limit =
+			MAX_SUPPORTED_PEERS_WEP;
+		psessionEntry->staId = pAddBssParams->staContext.staIdx;
+		mlmStartCnf.resultCode = eSIR_SME_SUCCESS;
+	} else {
+		pe_err("WMA_ADD_BSS_REQ failed with status %d",
+			pAddBssParams->status);
+		mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+	}
+
+	lim_send_start_bss_confirm(pMac, &mlmStartCnf);
+end:
+	if (0 != limMsgQ->bodyptr) {
+		qdf_mem_free(pAddBssParams);
+		limMsgQ->bodyptr = NULL;
+	}
+}
+
+/**
+ * lim_process_ibss_mlm_add_bss_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to process a WMA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Validates the result of WMA_ADD_BSS_REQ
+ * > Init other remaining LIM variables
+ * > Init the AID pool, for that BSSID
+ * > Init the Pre-AUTH list, for that BSSID
+ * > Create LIM timers, specific to that BSSID
+ * > Init DPH related parameters that are specific to that BSSID
+ * > TODO - When do we do the actual change channel?
+ *
+ ***LOGIC:
+ * SME sends eWNI_SME_START_BSS_REQ to LIM
+ * LIM sends LIM_MLM_START_REQ to MLME
+ * MLME sends WMA_ADD_BSS_REQ to HAL
+ * HAL responds with WMA_ADD_BSS_RSP to MLME
+ * MLME responds with LIM_MLM_START_CNF to LIM
+ * LIM responds with eWNI_SME_START_BSS_RSP to SME
+ *
+ ***ASSUMPTIONS:
+ * struct scheduler_msg.body is allocated by MLME during
+ * lim_process_mlm_start_req
+ * struct scheduler_msg.body will now be freed by this routine
+ *
+ ***NOTE:
+ *
+ * @param  pMac      Pointer to Global MAC structure
+ * @param  struct scheduler_msg  The MsgQ header, which contains
+ *  the response buffer
+ *
+ * @return None
+ */
+static void
+lim_process_ibss_mlm_add_bss_rsp(tpAniSirGlobal pMac,
+				 struct scheduler_msg *limMsgQ,
+				 tpPESession psessionEntry)
+{
+	tLimMlmStartCnf mlmStartCnf;
+	tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+
+	if (NULL == pAddBssParams) {
+		pe_err("Invalid body pointer in message");
+		goto end;
+	}
+	if (QDF_STATUS_SUCCESS == pAddBssParams->status) {
+		pe_debug("WMA_ADD_BSS_RSP returned with QDF_STATUS_SUCCESS");
+
+		if (lim_set_link_state
+			    (pMac, eSIR_LINK_IBSS_STATE, psessionEntry->bssId,
+			    psessionEntry->selfMacAddr, NULL,
+			    NULL) != QDF_STATUS_SUCCESS)
+			goto end;
+		/* Set MLME state */
+		psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE;
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+			       psessionEntry->limMlmState));
+		/** IBSS is 'active' when we receive
+		 * Beacon frames from other STAs that are part of same IBSS.
+		 * Mark internal state as inactive until then.
+		 */
+		psessionEntry->limIbssActive = false;
+		limResetHBPktCount(psessionEntry);
+		psessionEntry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
+		psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+		psessionEntry->statypeForBss = STA_ENTRY_SELF;
+		sch_edca_profile_update(pMac, psessionEntry);
+		if (0 == psessionEntry->freePeerIdxHead)
+			lim_init_peer_idxpool(pMac, psessionEntry);
+
+		/* Apply previously set configuration at HW */
+		lim_apply_configuration(pMac, psessionEntry);
+		psessionEntry->staId = pAddBssParams->staContext.staIdx;
+		mlmStartCnf.resultCode = eSIR_SME_SUCCESS;
+		/* If ADD BSS was issued as part of IBSS coalescing, don't send the message to SME, as that is internal to LIM */
+		if (true == pMac->lim.gLimIbssCoalescingHappened) {
+			lim_ibss_add_bss_rsp_when_coalescing(pMac, limMsgQ->bodyptr,
+							     psessionEntry);
+			goto end;
+		}
+	} else {
+		pe_err("WMA_ADD_BSS_REQ failed with status %d",
+			pAddBssParams->status);
+		mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+	}
+	/* Send this message to SME, when ADD_BSS is initiated by SME */
+	/* If ADD_BSS is done as part of coalescing, this won't happen. */
+	/* Update PE session Id */
+	mlmStartCnf.sessionId = psessionEntry->peSessionId;
+	lim_send_start_bss_confirm(pMac, &mlmStartCnf);
+end:
+	if (0 != limMsgQ->bodyptr) {
+		qdf_mem_free(pAddBssParams);
+		limMsgQ->bodyptr = NULL;
+	}
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/*
+ * lim_update_fils_auth_mode: API to update Auth mode in case of fils session
+ * @session_entry: pe session entry
+ * @auth_mode: auth mode needs to be updated
+ *
+ * Return: None
+ */
+static void lim_update_fils_auth_mode(tpPESession session_entry,
+			tAniAuthType *auth_mode)
+{
+	if (!session_entry->fils_info)
+		return;
+
+	if (session_entry->fils_info->is_fils_connection)
+		*auth_mode = session_entry->fils_info->auth;
+}
+#else
+static void lim_update_fils_auth_mode(tpPESession session_entry,
+			tAniAuthType *auth_mode)
+{ }
+#endif
+
+/**
+ * csr_neighbor_roam_handoff_req_hdlr - Processes handoff request
+ * @mac_ctx:  Pointer to mac context
+ * @msg:  message sent to HDD
+ * @session_entry: PE session handle
+ *
+ * This function is called to process a WMA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL if the state is pre assoc.
+ *
+ * Return: Null
+ */
+static void
+lim_process_sta_add_bss_rsp_pre_assoc(tpAniSirGlobal mac_ctx,
+	struct scheduler_msg *msg, tpPESession session_entry)
+{
+	tpAddBssParams pAddBssParams = (tpAddBssParams) msg->bodyptr;
+	tAniAuthType cfgAuthType, authMode;
+	tLimMlmAuthReq *pMlmAuthReq;
+	tpDphHashNode pStaDs = NULL;
+
+	if (NULL == pAddBssParams) {
+		pe_err("Invalid body pointer in message");
+		goto joinFailure;
+	}
+	if (QDF_STATUS_SUCCESS == pAddBssParams->status) {
+		pStaDs = dph_add_hash_entry(mac_ctx,
+				pAddBssParams->staContext.staMac,
+				DPH_STA_HASH_INDEX_PEER,
+				&session_entry->dph.dphHashTable);
+		if (pStaDs == NULL) {
+			/* Could not add hash table entry */
+			pe_err("could not add hash entry at DPH for");
+			lim_print_mac_addr(mac_ctx,
+				pAddBssParams->staContext.staMac, LOGE);
+			goto joinFailure;
+		}
+		session_entry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
+		/* Success, handle below */
+		pStaDs->bssId = pAddBssParams->bssIdx;
+		/* STA Index(genr by HAL) for the BSS entry is stored here */
+		pStaDs->staIndex = pAddBssParams->staContext.staIdx;
+		/* Trigger Authentication with AP */
+		cfgAuthType = mac_ctx->mlme_cfg->wep_params.auth_type;
+
+		/* Try shared Authentication first */
+		if (cfgAuthType == eSIR_AUTO_SWITCH)
+			authMode = eSIR_SHARED_KEY;
+		else
+			authMode = cfgAuthType;
+
+		lim_update_fils_auth_mode(session_entry, &authMode);
+		/* Trigger MAC based Authentication */
+		pMlmAuthReq = qdf_mem_malloc(sizeof(tLimMlmAuthReq));
+		if (NULL == pMlmAuthReq) {
+			pe_err("Allocate Memory failed for mlmAuthReq");
+			return;
+		}
+		sir_copy_mac_addr(pMlmAuthReq->peerMacAddr,
+			session_entry->bssId);
+
+		pMlmAuthReq->authType = authMode;
+		session_entry->limMlmState = eLIM_MLM_JOINED_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+			session_entry->peSessionId, eLIM_MLM_JOINED_STATE));
+		pMlmAuthReq->sessionId = session_entry->peSessionId;
+		session_entry->limPrevSmeState = session_entry->limSmeState;
+		session_entry->limSmeState = eLIM_SME_WT_AUTH_STATE;
+		/* remember staId in case of assoc timeout/failure handling */
+		session_entry->staId = pAddBssParams->staContext.staIdx;
+
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+			session_entry->peSessionId,
+			session_entry->limSmeState));
+		pe_debug("SessionId:%d lim_post_mlm_message "
+			"LIM_MLM_AUTH_REQ with limSmeState: %d",
+			session_entry->peSessionId, session_entry->limSmeState);
+		lim_post_mlm_message(mac_ctx, LIM_MLM_AUTH_REQ,
+			(uint32_t *) pMlmAuthReq);
+		return;
+	}
+
+joinFailure:
+	{
+		session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+			session_entry->peSessionId,
+			session_entry->limSmeState));
+
+		/* Send Join response to Host */
+		lim_handle_sme_join_result(mac_ctx, eSIR_SME_REFUSED,
+			eSIR_MAC_UNSPEC_FAILURE_STATUS, session_entry);
+	}
+
+}
+
+/**
+ * lim_process_sta_mlm_add_bss_rsp() - Process ADD BSS response
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: The MsgQ header, which contains the response buffer
+ *
+ * This function is called to process a WMA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Validates the result of WMA_ADD_BSS_REQ
+ * > Now, send an ADD_STA to HAL and ADD the "local" STA itself
+ *
+ * MLME had sent WMA_ADD_BSS_REQ to HAL
+ * HAL responded with WMA_ADD_BSS_RSP to MLME
+ * MLME now sends WMA_ADD_STA_REQ to HAL
+ * ASSUMPTIONS:
+ * struct scheduler_msg.body is allocated by MLME during
+ * lim_process_mlm_join_req
+ * struct scheduler_msg.body will now be freed by this routine
+ *
+ * Return: None
+ */
+static void
+lim_process_sta_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
+	struct scheduler_msg *msg, tpPESession session_entry)
+{
+	tpAddBssParams add_bss_params = (tpAddBssParams) msg->bodyptr;
+	tLimMlmAssocCnf mlm_assoc_cnf;
+	uint32_t msg_type = LIM_MLM_ASSOC_CNF;
+	uint32_t sub_type = LIM_ASSOC;
+	tpDphHashNode sta_ds = NULL;
+	uint16_t sta_idx = STA_INVALID_IDX;
+	uint8_t update_sta = false;
+
+	mlm_assoc_cnf.resultCode = eSIR_SME_SUCCESS;
+
+	if (eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE ==
+		session_entry->limMlmState) {
+		pe_debug("SessionId: %d lim_process_sta_add_bss_rsp_pre_assoc",
+			session_entry->peSessionId);
+		lim_process_sta_add_bss_rsp_pre_assoc(mac_ctx, msg,
+			session_entry);
+		goto end;
+	}
+	if (eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE == session_entry->limMlmState
+		|| (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
+		session_entry->limMlmState)) {
+		msg_type = LIM_MLM_REASSOC_CNF;
+		sub_type = LIM_REASSOC;
+		/*
+		 * If Reassoc is happening for the same BSS, then
+		 * use the existing StaId and indicate to HAL to update
+		 * the existing STA entry.
+		 * If Reassoc is happening for the new BSS, then
+		 * old BSS and STA entry would have been already deleted
+		 * before PE tries to add BSS for the new BSS, so set the
+		 * updateSta to false and pass INVALID STA Index.
+		 */
+		if (sir_compare_mac_addr(session_entry->bssId,
+			session_entry->limReAssocbssId)) {
+			sta_idx = session_entry->staId;
+			update_sta = true;
+		}
+	}
+
+	if (add_bss_params == 0)
+		goto end;
+
+	if (QDF_STATUS_SUCCESS == add_bss_params->status) {
+		if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
+			session_entry->limMlmState) {
+			pe_debug("Mlm=%d %d", session_entry->limMlmState,
+				eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);
+			lim_process_sta_mlm_add_bss_rsp_ft(mac_ctx, msg,
+				session_entry);
+			goto end;
+		}
+
+		/* Set MLME state */
+		session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+			session_entry->peSessionId,
+			session_entry->limMlmState));
+		/* to know the session  started for self or for  peer  */
+		session_entry->statypeForBss = STA_ENTRY_PEER;
+		/* Now, send WMA_ADD_STA_REQ */
+		pe_debug("SessionId: %d On STA: ADD_BSS was successful",
+			session_entry->peSessionId);
+		sta_ds =
+			dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+				&session_entry->dph.dphHashTable);
+		if (sta_ds == NULL) {
+			pe_err("Session:%d Fail to add Self Entry for STA",
+				session_entry->peSessionId);
+			mlm_assoc_cnf.resultCode =
+				(tSirResultCodes) eSIR_SME_REFUSED;
+		} else {
+			session_entry->bssIdx =
+				(uint8_t) add_bss_params->bssIdx;
+			/* Success, handle below */
+			sta_ds->bssId = add_bss_params->bssIdx;
+			/*
+			 * STA Index(genr by HAL) for the BSS
+			 * entry is stored here
+			*/
+			sta_ds->staIndex = add_bss_params->staContext.staIdx;
+			/* Downgrade the EDCA parameters if needed */
+			lim_set_active_edca_params(mac_ctx,
+				session_entry->gLimEdcaParams, session_entry);
+			lim_send_edca_params(mac_ctx,
+				session_entry->gLimEdcaParamsActive,
+				sta_ds->bssId, false);
+			rrm_cache_mgmt_tx_power(mac_ctx,
+				add_bss_params->txMgmtPower, session_entry);
+			if (lim_add_sta_self(mac_ctx, sta_idx, update_sta,
+				session_entry) != QDF_STATUS_SUCCESS) {
+				/* Add STA context at HW */
+				pe_err("Session:%d could not Add Self"
+					"Entry for the station",
+					session_entry->peSessionId);
+				mlm_assoc_cnf.resultCode =
+					(tSirResultCodes) eSIR_SME_REFUSED;
+			}
+		}
+	} else {
+		pe_err("SessionId: %d ADD_BSS failed!",
+			session_entry->peSessionId);
+		mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+		/* Return Assoc confirm to SME with failure */
+		if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
+				session_entry->limMlmState)
+			mlm_assoc_cnf.resultCode =
+				(tSirResultCodes) eSIR_SME_FT_REASSOC_FAILURE;
+		else
+			mlm_assoc_cnf.resultCode =
+				(tSirResultCodes) eSIR_SME_REFUSED;
+		session_entry->add_bss_failed = true;
+	}
+
+	if (mlm_assoc_cnf.resultCode != eSIR_SME_SUCCESS) {
+		session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
+		if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE,
+					session_entry->bssId,
+					session_entry->selfMacAddr,
+					NULL, NULL) != QDF_STATUS_SUCCESS)
+			pe_err("Failed to set the LinkState");
+		/* Update PE session Id */
+		mlm_assoc_cnf.sessionId = session_entry->peSessionId;
+		lim_post_sme_message(mac_ctx, msg_type,
+			(uint32_t *) &mlm_assoc_cnf);
+	}
+end:
+	if (0 != msg->bodyptr) {
+		qdf_mem_free(add_bss_params);
+		msg->bodyptr = NULL;
+	}
+}
+
+/**
+ * lim_process_mlm_add_bss_rsp() - Processes ADD BSS Response
+ *
+ * @mac_ctx - Pointer to Global MAC structure
+ * @msg - The MsgQ header, which contains the response buffer
+ *
+ * This function is called to process a WMA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ *  Determines the "state" in which this message was received
+ *  Forwards it to the appropriate callback
+ *
+ *LOGIC:
+ * WMA_ADD_BSS_RSP can be received by MLME while the LIM is
+ * in the following two states:
+ * 1) As AP, LIM state = eLIM_SME_WT_START_BSS_STATE
+ * 2) As STA, LIM state = eLIM_SME_WT_JOIN_STATE
+ * Based on these two states, this API will determine where to
+ * route the message to
+ *
+ * Return None
+ */
+void lim_process_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
+	struct scheduler_msg *msg)
+{
+	tLimMlmStartCnf mlm_start_cnf;
+	tpPESession session_entry;
+	tpAddBssParams add_bss_param = (tpAddBssParams) (msg->bodyptr);
+	tSirBssType bss_type;
+
+	if (NULL == add_bss_param) {
+		pe_err("Encountered NULL Pointer");
+		return;
+	}
+
+	/*
+	 * we need to process the deferred message since the
+	 * initiating req.there might be nested request.
+	 * in the case of nested request the new request initiated
+	 * from the response will take care of resetting the deffered
+	 * flag.
+	 */
+	SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+	/* Validate SME/LIM/MLME state */
+	session_entry = pe_find_session_by_session_id(mac_ctx,
+			add_bss_param->sessionId);
+	if (session_entry == NULL) {
+		pe_err("SessionId:%d Session Doesn't exist",
+			add_bss_param->sessionId);
+		if (NULL != add_bss_param) {
+			qdf_mem_free(add_bss_param);
+			msg->bodyptr = NULL;
+		}
+		return;
+	}
+
+	bss_type = session_entry->bssType;
+	/* update PE session Id */
+	mlm_start_cnf.sessionId = session_entry->peSessionId;
+	if (eSIR_IBSS_MODE == bss_type) {
+		lim_process_ibss_mlm_add_bss_rsp(mac_ctx, msg, session_entry);
+	} else if (eSIR_NDI_MODE == session_entry->bssType) {
+		lim_process_ndi_mlm_add_bss_rsp(mac_ctx, msg, session_entry);
+	} else {
+		if (eLIM_SME_WT_START_BSS_STATE == session_entry->limSmeState) {
+			if (eLIM_MLM_WT_ADD_BSS_RSP_STATE !=
+				session_entry->limMlmState) {
+				pe_err("SessionId:%d Received "
+					" WMA_ADD_BSS_RSP in state %X",
+					session_entry->peSessionId,
+					session_entry->limMlmState);
+				mlm_start_cnf.resultCode =
+					eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+				if (0 != msg->bodyptr) {
+					qdf_mem_free(add_bss_param);
+					msg->bodyptr = NULL;
+				}
+
+				lim_send_start_bss_confirm(mac_ctx, &mlm_start_cnf);
+			} else
+				lim_process_ap_mlm_add_bss_rsp(mac_ctx, msg);
+		} else {
+			/* Called while processing assoc response */
+			lim_process_sta_mlm_add_bss_rsp(mac_ctx, msg,
+				session_entry);
+		}
+	}
+
+#ifdef WLAN_FEATURE_11W
+	if (session_entry->limRmfEnabled) {
+		if (QDF_STATUS_SUCCESS !=
+			lim_send_exclude_unencrypt_ind(mac_ctx, false,
+				session_entry)) {
+			pe_err("Failed to send Exclude Unencrypted Ind");
+		}
+	}
+#endif
+}
+
+void lim_process_mlm_update_hidden_ssid_rsp(tpAniSirGlobal mac_ctx,
+	struct scheduler_msg *msg)
+{
+	tpPESession session_entry;
+	tpHalHiddenSsidVdevRestart hidden_ssid_vdev_restart;
+
+	hidden_ssid_vdev_restart = (tpHalHiddenSsidVdevRestart)(msg->bodyptr);
+
+	if (NULL == hidden_ssid_vdev_restart) {
+		pe_err("NULL msg pointer");
+		return;
+	}
+
+	session_entry = pe_find_session_by_session_id(mac_ctx,
+			hidden_ssid_vdev_restart->pe_session_id);
+
+	if (session_entry == NULL) {
+		pe_err("SessionId:%d Session Doesn't exist",
+			hidden_ssid_vdev_restart->pe_session_id);
+		goto free_req;
+	}
+	/* Update beacon */
+	sch_set_fixed_beacon_fields(mac_ctx, session_entry);
+	lim_send_beacon(mac_ctx, session_entry);
+
+free_req:
+	if (NULL != hidden_ssid_vdev_restart) {
+		qdf_mem_free(hidden_ssid_vdev_restart);
+		msg->bodyptr = NULL;
+	}
+}
+
+/**
+ * lim_process_mlm_set_sta_key_rsp() - Process STA key response
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: The MsgQ header, which contains the response buffer
+ *
+ * This function is called to process the following two
+ * messages from HAL:
+ * 1) WMA_SET_BSSKEY_RSP
+ * 2) WMA_SET_STAKEY_RSP
+ * 3) WMA_SET_STA_BCASTKEY_RSP
+ * Upon receipt of this message from HAL,
+ * MLME -
+ * > Determines the "state" in which this message was received
+ * > Forwards it to the appropriate callback
+ * LOGIC:
+ * WMA_SET_BSSKEY_RSP/WMA_SET_STAKEY_RSP can be
+ * received by MLME while in the following state:
+ * MLME state = eLIM_MLM_WT_SET_BSS_KEY_STATE --OR--
+ * MLME state = eLIM_MLM_WT_SET_STA_KEY_STATE --OR--
+ * MLME state = eLIM_MLM_WT_SET_STA_BCASTKEY_STATE
+ * Based on this state, this API will determine where to
+ * route the message to
+ * Assumption:
+ * ONLY the MLME state is being taken into account for now.
+ * This is because, it appears that the handling of the
+ * SETKEYS REQ is handled symmetrically on both the AP & STA
+ *
+ * Return: None
+ */
+void lim_process_mlm_set_sta_key_rsp(tpAniSirGlobal mac_ctx,
+	struct scheduler_msg *msg)
+{
+	uint8_t resp_reqd = 1;
+	struct sLimMlmSetKeysCnf mlm_set_key_cnf;
+	uint8_t session_id = 0;
+	uint8_t sme_session_id;
+	tpPESession session_entry;
+	uint16_t key_len;
+	uint16_t result_status;
+
+	SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+	qdf_mem_set((void *)&mlm_set_key_cnf, sizeof(tLimMlmSetKeysCnf), 0);
+	if (NULL == msg->bodyptr) {
+		pe_err("msg bodyptr is NULL");
+		return;
+	}
+	session_id = ((tpSetStaKeyParams) msg->bodyptr)->sessionId;
+	sme_session_id = ((tpSetBssKeyParams) msg->bodyptr)->smesessionId;
+	session_entry = pe_find_session_by_session_id(mac_ctx, session_id);
+	if (session_entry == NULL) {
+		pe_err("session does not exist for given session_id");
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+		lim_send_sme_set_context_rsp(mac_ctx,
+					     mlm_set_key_cnf.peer_macaddr,
+					     0, eSIR_SME_INVALID_SESSION, NULL,
+					     sme_session_id, 0);
+		return;
+	}
+	if (eLIM_MLM_WT_SET_STA_KEY_STATE != session_entry->limMlmState) {
+		pe_err("Received unexpected [Mesg Id - %d] in state %X",
+			msg->type, session_entry->limMlmState);
+		resp_reqd = 0;
+	} else {
+		mlm_set_key_cnf.resultCode =
+			(uint16_t)(((tpSetStaKeyParams) msg->bodyptr)->status);
+	}
+
+	result_status = (uint16_t)(((tpSetStaKeyParams) msg->bodyptr)->status);
+	key_len = ((tpSetStaKeyParams)msg->bodyptr)->key[0].keyLength;
+
+	if (result_status == eSIR_SME_SUCCESS && key_len)
+		mlm_set_key_cnf.key_len_nonzero = true;
+	else
+		mlm_set_key_cnf.key_len_nonzero = false;
+
+
+	qdf_mem_free(msg->bodyptr);
+	msg->bodyptr = NULL;
+	/* Restore MLME state */
+	session_entry->limMlmState = session_entry->limPrevMlmState;
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+		session_entry->peSessionId, session_entry->limMlmState));
+	if (resp_reqd) {
+		tpLimMlmSetKeysReq lpLimMlmSetKeysReq =
+			(tpLimMlmSetKeysReq) mac_ctx->lim.gpLimMlmSetKeysReq;
+		/* Prepare and Send LIM_MLM_SETKEYS_CNF */
+		if (NULL != lpLimMlmSetKeysReq) {
+			qdf_copy_macaddr(&mlm_set_key_cnf.peer_macaddr,
+					 &lpLimMlmSetKeysReq->peer_macaddr);
+			/*
+			 * Free the buffer cached for the global
+			 * mac_ctx->lim.gpLimMlmSetKeysReq
+			 */
+			qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
+			mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
+		}
+		mlm_set_key_cnf.sessionId = session_id;
+		lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF,
+			(uint32_t *) &mlm_set_key_cnf);
+	}
+}
+
+/**
+ * lim_process_mlm_set_bss_key_rsp() - handles BSS key
+ *
+ * @mac_ctx: A pointer to Global MAC structure
+ * @msg: Message from SME
+ *
+ * This function processes BSS key response and updates
+ * PE status accordingly.
+ *
+ * Return: NULL
+ */
+void lim_process_mlm_set_bss_key_rsp(tpAniSirGlobal mac_ctx,
+	struct scheduler_msg *msg)
+{
+	struct sLimMlmSetKeysCnf set_key_cnf;
+	uint16_t result_status;
+	uint8_t session_id = 0;
+	uint8_t sme_session_id;
+	tpPESession session_entry;
+	tpLimMlmSetKeysReq set_key_req;
+	uint16_t key_len;
+
+	SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+	qdf_mem_set((void *)&set_key_cnf, sizeof(tLimMlmSetKeysCnf), 0);
+	if (NULL == msg->bodyptr) {
+		pe_err("msg bodyptr is null");
+		return;
+	}
+	session_id = ((tpSetBssKeyParams) msg->bodyptr)->sessionId;
+	sme_session_id = ((tpSetBssKeyParams) msg->bodyptr)->smesessionId;
+	session_entry = pe_find_session_by_session_id(mac_ctx, session_id);
+	if (session_entry == NULL) {
+		pe_err("session does not exist for given sessionId [%d]",
+			session_id);
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+		lim_send_sme_set_context_rsp(mac_ctx, set_key_cnf.peer_macaddr,
+					     0, eSIR_SME_INVALID_SESSION, NULL,
+					     sme_session_id, 0);
+		return;
+	}
+	if (eLIM_MLM_WT_SET_BSS_KEY_STATE == session_entry->limMlmState) {
+		result_status =
+			(uint16_t)(((tpSetBssKeyParams)msg->bodyptr)->status);
+		key_len = ((tpSetBssKeyParams)msg->bodyptr)->key[0].keyLength;
+	} else {
+		/*
+		 * BCAST key also uses tpSetStaKeyParams.
+		 * Done this way for readabilty.
+		 */
+		result_status =
+			(uint16_t)(((tpSetStaKeyParams)msg->bodyptr)->status);
+		key_len = ((tpSetStaKeyParams)msg->bodyptr)->key[0].keyLength;
+	}
+
+	if (result_status == eSIR_SME_SUCCESS && key_len)
+		set_key_cnf.key_len_nonzero = true;
+	else
+		set_key_cnf.key_len_nonzero = false;
+
+	/* Validate MLME state */
+	if (eLIM_MLM_WT_SET_BSS_KEY_STATE != session_entry->limMlmState &&
+		eLIM_MLM_WT_SET_STA_BCASTKEY_STATE !=
+			session_entry->limMlmState) {
+		pe_err("Received unexpected [Mesg Id - %d] in state %X",
+			msg->type, session_entry->limMlmState);
+	} else {
+		set_key_cnf.resultCode = result_status;
+	}
+
+	qdf_mem_free(msg->bodyptr);
+	msg->bodyptr = NULL;
+	/* Restore MLME state */
+	session_entry->limMlmState = session_entry->limPrevMlmState;
+
+	MTRACE(mac_trace
+		(mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId,
+		session_entry->limMlmState));
+	set_key_req =
+		(tpLimMlmSetKeysReq) mac_ctx->lim.gpLimMlmSetKeysReq;
+	set_key_cnf.sessionId = session_id;
+
+	/* Prepare and Send LIM_MLM_SETKEYS_CNF */
+	if (NULL != set_key_req) {
+		qdf_copy_macaddr(&set_key_cnf.peer_macaddr,
+				 &set_key_req->peer_macaddr);
+		/*
+		 * Free the buffer cached for the
+		 * global mac_ctx->lim.gpLimMlmSetKeysReq
+		 */
+		qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
+		mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
+	}
+	lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF,
+		(uint32_t *) &set_key_cnf);
+}
+
+/**
+ * lim_process_switch_channel_re_assoc_req()
+ *
+ ***FUNCTION:
+ * This function is called to send the reassoc req mgmt frame after the
+ * switchChannelRsp message is received from HAL.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac          - Pointer to Global MAC structure.
+ * @param  psessionEntry - session related information.
+ * @param  status        - channel switch success/failure.
+ *
+ * @return None
+ */
+static void lim_process_switch_channel_re_assoc_req(tpAniSirGlobal pMac,
+						    tpPESession psessionEntry,
+						    QDF_STATUS status)
+{
+	tLimMlmReassocCnf mlmReassocCnf;
+	tLimMlmReassocReq *pMlmReassocReq;
+
+	pMlmReassocReq =
+		(tLimMlmReassocReq *) (psessionEntry->pLimMlmReassocReq);
+	if (pMlmReassocReq == NULL) {
+		pe_err("pLimMlmReassocReq does not exist for given switchChanSession");
+		mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+		goto end;
+	}
+
+	if (status != QDF_STATUS_SUCCESS) {
+		pe_err("Change channel failed!!");
+		mlmReassocCnf.resultCode = eSIR_SME_CHANNEL_SWITCH_FAIL;
+		goto end;
+	}
+	/* / Start reassociation failure timer */
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId,
+		       eLIM_REASSOC_FAIL_TIMER));
+	if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer)
+	    != TX_SUCCESS) {
+		pe_err("could not start Reassociation failure timer");
+		/* Return Reassoc confirm with */
+		/* Resources Unavailable */
+		mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+		goto end;
+	}
+	/* / Prepare and send Reassociation request frame */
+	lim_send_reassoc_req_mgmt_frame(pMac, pMlmReassocReq, psessionEntry);
+	return;
+end:
+	/* Free up buffer allocated for reassocReq */
+	if (pMlmReassocReq != NULL) {
+		/* Update PE session Id */
+		mlmReassocCnf.sessionId = pMlmReassocReq->sessionId;
+		qdf_mem_free(pMlmReassocReq);
+		psessionEntry->pLimMlmReassocReq = NULL;
+	} else {
+		mlmReassocCnf.sessionId = 0;
+	}
+
+	mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+	/* Update PE sessio Id */
+	mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+
+	lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+			     (uint32_t *) &mlmReassocCnf);
+}
+
+
+/**
+ * lim_process_switch_channel_join_req() -Initiates probe request
+ *
+ * @mac_ctx - A pointer to Global MAC structure
+ * @sessionEntry - session related information.
+ * @status        - channel switch success/failure
+ *
+ * This function is called to send the probe req mgmt frame
+ * after the switchChannelRsp message is received from HAL.
+ *
+ * Return None
+ */
+static void lim_process_switch_channel_join_req(
+	tpAniSirGlobal mac_ctx, tpPESession session_entry,
+	QDF_STATUS status)
+{
+	tSirMacSSid ssId;
+	tLimMlmJoinCnf join_cnf;
+
+	if (status != QDF_STATUS_SUCCESS) {
+		pe_err("Change channel failed!!");
+		goto error;
+	}
+
+	if ((NULL == session_entry) || (NULL == session_entry->pLimMlmJoinReq)
+		|| (NULL == session_entry->pLimJoinReq)) {
+		pe_err("invalid pointer!!");
+		goto error;
+	}
+
+	session_entry->limPrevMlmState = session_entry->limMlmState;
+	session_entry->limMlmState = eLIM_MLM_WT_JOIN_BEACON_STATE;
+	pe_debug("Sessionid %d prev lim state %d new lim state %d "
+		"systemrole = %d", session_entry->peSessionId,
+		session_entry->limPrevMlmState,
+		session_entry->limMlmState, GET_LIM_SYSTEM_ROLE(session_entry));
+
+	/* Apply previously set configuration at HW */
+	lim_apply_configuration(mac_ctx, session_entry);
+
+	/*
+	* If deauth_before_connection is enabled, Send Deauth first to AP if
+	* last disconnection was caused by HB failure.
+	*/
+	if (mac_ctx->mlme_cfg->sta.deauth_before_connection) {
+		int apCount;
+
+		for (apCount = 0; apCount < 2; apCount++) {
+
+			if (!qdf_mem_cmp(session_entry->pLimMlmJoinReq->bssDescription.bssId,
+				mac_ctx->lim.gLimHeartBeatApMac[apCount], sizeof(tSirMacAddr))) {
+
+				pe_err("Index %d Sessionid: %d Send deauth on "
+				"channel %d to BSSID: "MAC_ADDRESS_STR, apCount,
+				session_entry->peSessionId, session_entry->currentOperChannel,
+				MAC_ADDR_ARRAY(session_entry->pLimMlmJoinReq->bssDescription.
+											bssId));
+
+				lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON,
+					session_entry->pLimMlmJoinReq->bssDescription.bssId,
+					session_entry, false);
+
+				qdf_mem_zero(mac_ctx->lim.gLimHeartBeatApMac[apCount],
+					sizeof(tSirMacAddr));
+				break;
+			}
+		}
+	}
+
+	/* Wait for Beacon to announce join success */
+	qdf_mem_copy(ssId.ssId,
+		session_entry->ssId.ssId, session_entry->ssId.length);
+	ssId.length = session_entry->ssId.length;
+
+	lim_deactivate_and_change_timer(mac_ctx,
+		eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
+
+	/* assign appropriate sessionId to the timer object */
+	mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId =
+		session_entry->peSessionId;
+	pe_debug("Sessionid: %d Send Probe req on channel %d ssid:%.*s "
+		"BSSID: " MAC_ADDRESS_STR, session_entry->peSessionId,
+		session_entry->currentOperChannel, ssId.length, ssId.ssId,
+		MAC_ADDR_ARRAY(
+		session_entry->pLimMlmJoinReq->bssDescription.bssId));
+
+	/*
+	 * We need to wait for probe response, so start join
+	 * timeout timer.This timer will be deactivated once
+	 * we receive probe response.
+	 */
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
+		session_entry->peSessionId, eLIM_JOIN_FAIL_TIMER));
+	if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimJoinFailureTimer) !=
+		TX_SUCCESS) {
+		pe_err("couldn't activate Join failure timer");
+		session_entry->limMlmState = session_entry->limPrevMlmState;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+			 session_entry->peSessionId,
+			 mac_ctx->lim.gLimMlmState));
+		goto error;
+	}
+	/* include additional IE if there is */
+	lim_send_probe_req_mgmt_frame(mac_ctx, &ssId,
+		session_entry->pLimMlmJoinReq->bssDescription.bssId,
+		session_entry->currentOperChannel, session_entry->selfMacAddr,
+		session_entry->dot11mode,
+		&session_entry->pLimJoinReq->addIEScan.length,
+		session_entry->pLimJoinReq->addIEScan.addIEdata);
+
+	if (session_entry->pePersona == QDF_P2P_CLIENT_MODE) {
+		/* Activate Join Periodic Probe Req timer */
+		if (tx_timer_activate
+			(&mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer)
+			!= TX_SUCCESS) {
+			pe_err("Periodic JoinReq timer activate failed");
+			goto error;
+		}
+	}
+	return;
+error:
+	if (NULL != session_entry) {
+		if (session_entry->pLimMlmJoinReq) {
+			qdf_mem_free(session_entry->pLimMlmJoinReq);
+			session_entry->pLimMlmJoinReq = NULL;
+		}
+		if (session_entry->pLimJoinReq) {
+			qdf_mem_free(session_entry->pLimJoinReq);
+			session_entry->pLimJoinReq = NULL;
+		}
+		join_cnf.sessionId = session_entry->peSessionId;
+	} else {
+		join_cnf.sessionId = 0;
+	}
+	join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+	join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+	lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, (uint32_t *)&join_cnf);
+}
+
+/**
+ * lim_process_switch_channel_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to process switchChannelRsp message from HAL.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ * @param  body - message body.
+ *
+ * @return None
+ */
+void lim_process_switch_channel_rsp(tpAniSirGlobal pMac, void *body)
+{
+	tpSwitchChannelParams pChnlParams = NULL;
+	QDF_STATUS status;
+	uint16_t channelChangeReasonCode;
+	uint8_t peSessionId;
+	tpPESession psessionEntry;
+	/* we need to process the deferred message since the initiating req. there might be nested request. */
+	/* in the case of nested request the new request initiated from the response will take care of resetting */
+	/* the deffered flag. */
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+	pChnlParams = (tpSwitchChannelParams) body;
+	status = pChnlParams->status;
+	peSessionId = pChnlParams->peSessionId;
+
+	psessionEntry = pe_find_session_by_session_id(pMac, peSessionId);
+	if (psessionEntry == NULL) {
+		pe_err("session does not exist for given sessionId");
+		goto free;
+	}
+	psessionEntry->ch_switch_in_progress = false;
+	/* HAL fills in the tx power used for mgmt frames in this field. */
+	/* Store this value to use in TPC report IE. */
+	rrm_cache_mgmt_tx_power(pMac, pChnlParams->txMgmtPower, psessionEntry);
+	channelChangeReasonCode = psessionEntry->channelChangeReasonCode;
+	/* initialize it back to invalid id */
+	psessionEntry->chainMask = pChnlParams->chainMask;
+	psessionEntry->smpsMode = pChnlParams->smpsMode;
+	psessionEntry->channelChangeReasonCode = 0xBAD;
+	pe_debug("channelChangeReasonCode %d", channelChangeReasonCode);
+	switch (channelChangeReasonCode) {
+	case LIM_SWITCH_CHANNEL_REASSOC:
+		lim_process_switch_channel_re_assoc_req(pMac, psessionEntry, status);
+		break;
+	case LIM_SWITCH_CHANNEL_JOIN:
+		lim_process_switch_channel_join_req(pMac, psessionEntry, status);
+		break;
+
+	case LIM_SWITCH_CHANNEL_OPERATION:
+		/*
+		 * The above code should also use the callback.
+		 * mechanism below, there is scope for cleanup here.
+		 * THat way all this response handler does is call the call back
+		 * We can get rid of the reason code here.
+		 */
+		if (pMac->lim.gpchangeChannelCallback) {
+			pe_debug("Channel changed hence invoke registered call back");
+			pMac->lim.gpchangeChannelCallback(pMac, status,
+							  pMac->lim.
+							  gpchangeChannelData,
+							  psessionEntry);
+		}
+		/* If MCC upgrade/DBS downgrade happended during channel switch,
+		 * the policy manager connection table needs to be updated.
+		 */
+		policy_mgr_update_connection_info(pMac->psoc,
+			psessionEntry->smeSessionId);
+		if (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) {
+			pe_debug("Send p2p operating channel change conf action frame once first beacon is received on new channel");
+			psessionEntry->send_p2p_conf_frame = true;
+		}
+		break;
+	case LIM_SWITCH_CHANNEL_SAP_DFS:
+	{
+		/* Note: This event code specific to SAP mode
+		 * When SAP session issues channel change as performing
+		 * DFS, we will come here. Other sessions, for e.g. P2P
+		 * will have to define their own event code and channel
+		 * switch handler. This is required since the SME may
+		 * require completely different information for P2P unlike
+		 * SAP.
+		 */
+		lim_send_sme_ap_channel_switch_resp(pMac, psessionEntry,
+						pChnlParams);
+		/* If MCC upgrade/DBS downgrade happended during channel switch,
+		 * the policy manager connection table needs to be updated.
+		 */
+		policy_mgr_update_connection_info(pMac->psoc,
+						psessionEntry->smeSessionId);
+		policy_mgr_set_do_hw_mode_change_flag(pMac->psoc, true);
+	}
+	break;
+	default:
+		break;
+	}
+free:
+	qdf_mem_free(body);
+}
+
+QDF_STATUS lim_send_beacon_ind(tpAniSirGlobal pMac, tpPESession psessionEntry,
+			       enum sir_bcn_update_reason reason)
+{
+	tBeaconGenParams *pBeaconGenParams = NULL;
+	struct scheduler_msg limMsg = {0};
+	/** Allocate the Memory for Beacon Pre Message and for Stations in PoweSave*/
+	if (!psessionEntry) {
+		pe_err("Error:Unable to get the PESessionEntry");
+		return QDF_STATUS_E_INVAL;
+	}
+	pBeaconGenParams = qdf_mem_malloc(sizeof(*pBeaconGenParams));
+	if (!pBeaconGenParams) {
+		pe_err("Unable to allocate memory during sending beaconPreMessage");
+		return QDF_STATUS_E_NOMEM;
+	}
+	qdf_mem_copy((void *)pBeaconGenParams->bssId,
+		     (void *)psessionEntry->bssId, QDF_MAC_ADDR_SIZE);
+	limMsg.bodyptr = pBeaconGenParams;
+	return sch_process_pre_beacon_ind(pMac, &limMsg, reason);
+}
+
+void lim_process_rx_channel_status_event(tpAniSirGlobal mac_ctx, void *buf)
+{
+	struct lim_channel_status *chan_status = buf;
+
+	if (NULL == chan_status) {
+		QDF_TRACE(QDF_MODULE_ID_PE,
+			  QDF_TRACE_LEVEL_ERROR,
+			  "%s: ACS evt report buf NULL", __func__);
+		return;
+	}
+
+	if (mac_ctx->sap.acs_with_more_param)
+		lim_add_channel_status_info(mac_ctx, chan_status,
+					    chan_status->channel_id);
+	else
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_WARN,
+			  "%s: Error evt report", __func__);
+
+	qdf_mem_free(buf);
+
+	return;
+}
diff --git a/core/mac/src/pe/lim/lim_process_probe_req_frame.c b/core/mac/src/pe/lim/lim_process_probe_req_frame.c
new file mode 100644
index 0000000..e4d6658
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_probe_req_frame.c
@@ -0,0 +1,668 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file lim_process_probe_req_frame.cc contains the code
+ * for processing Probe Request Frame.
+ * Author:        Chandra Modumudi
+ * Date:          02/28/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_ser_des_utils.h"
+#include "parser_api.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "wlan_utility.h"
+
+void
+
+lim_send_sme_probe_req_ind(tpAniSirGlobal pMac,
+			   tSirMacAddr peerMacAddr,
+			   uint8_t *pProbeReqIE,
+			   uint32_t ProbeReqIELen, tpPESession psessionEntry);
+
+/**
+ * lim_get_wpspbc_sessions() - to get wps pbs sessions
+ * @mac_ctx: Pointer to Global MAC structure
+ * @addr: probe request source MAC address
+ * @uuid_e: A pointer to UUIDE element of WPS IE in WPS PBC probe request
+ * @session: A pointer to station PE session
+ *
+ * This function is called to query the WPS PBC overlap. This function
+ * check WPS PBC probe request link list for PBC overlap
+ *
+ * @return None
+ */
+
+void lim_get_wpspbc_sessions(tpAniSirGlobal mac_ctx, struct qdf_mac_addr addr,
+		uint8_t *uuid_e, eWPSPBCOverlap *overlap,
+		tpPESession session)
+{
+	int count = 0;
+	tSirWPSPBCSession *pbc;
+	uint32_t cur_time;
+
+	cur_time = (uint32_t) (qdf_mc_timer_get_system_ticks() /
+						QDF_TICKS_PER_SECOND);
+	qdf_zero_macaddr(&addr);
+	qdf_mem_set((uint8_t *) uuid_e, SIR_WPS_UUID_LEN, 0);
+	for (pbc = session->pAPWPSPBCSession; pbc; pbc = pbc->next) {
+		if (cur_time > pbc->timestamp + SIR_WPS_PBC_WALK_TIME)
+			break;
+		count++;
+		if (count > 1)
+			break;
+		qdf_copy_macaddr(&addr, &pbc->addr);
+		qdf_mem_copy((uint8_t *) uuid_e, (uint8_t *) pbc->uuid_e,
+				SIR_WPS_UUID_LEN);
+	}
+	if (count > 1)
+		/* Overlap */
+		*overlap = eSAP_WPSPBC_OVERLAP_IN120S;
+	else if (count == 0)
+		/* no WPS probe request in 120 second */
+		*overlap = eSAP_WPSPBC_NO_WPSPBC_PROBE_REQ_IN120S;
+	else
+		/* One WPS probe request in 120 second */
+		*overlap = eSAP_WPSPBC_ONE_WPSPBC_PROBE_REQ_IN120S;
+
+	pe_debug("overlap: %d", *overlap);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			   addr.bytes, QDF_MAC_ADDR_SIZE);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			   uuid_e, SIR_WPS_UUID_LEN);
+	return;
+}
+
+/**
+ * lim_remove_timeout_pbc_sessions() - remove pbc probe req entries.
+ * @pMac - Pointer to Global MAC structure
+ * @pbc - The beginning entry in WPS PBC probe request link list
+ *
+ * This function is called to remove the WPS PBC probe request entries from
+ * specific entry to end.
+ *
+ * Return - None
+ */
+static void lim_remove_timeout_pbc_sessions(tpAniSirGlobal pMac,
+					    tSirWPSPBCSession *pbc)
+{
+	tSirWPSPBCSession *prev;
+
+	while (pbc) {
+		prev = pbc;
+		pbc = pbc->next;
+		pe_debug("WPS PBC sessions remove");
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			   prev->addr.bytes, QDF_MAC_ADDR_SIZE);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			   prev->uuid_e, SIR_WPS_UUID_LEN);
+
+		qdf_mem_free(prev);
+	}
+}
+
+/**
+ * lim_remove_pbc_sessions() - Remove PBC sessions
+ * @mac: Pointer to Global MAC structure
+ * @remove_mac: MAC Address of STA in WPS Session to be removed
+ * @session_entry: session entry
+ *
+ * Return: none
+ */
+void lim_remove_pbc_sessions(tpAniSirGlobal mac, struct qdf_mac_addr remove_mac,
+			     tpPESession session_entry)
+{
+	tSirWPSPBCSession *pbc, *prev = NULL;
+
+	prev = pbc = session_entry->pAPWPSPBCSession;
+
+	while (pbc) {
+		if (qdf_is_macaddr_equal(&pbc->addr, &remove_mac)) {
+			prev->next = pbc->next;
+			if (pbc == session_entry->pAPWPSPBCSession)
+				session_entry->pAPWPSPBCSession = pbc->next;
+			qdf_mem_free(pbc);
+			return;
+		}
+		prev = pbc;
+		pbc = pbc->next;
+	}
+}
+
+/**
+ * lim_update_pbc_session_entry
+ *
+ ***FUNCTION:
+ * This function is called when probe request with WPS PBC IE is received
+ *
+ ***LOGIC:
+ * This function add the WPS PBC probe request in the WPS PBC probe request link list
+ * The link list is in decreased time order of probe request that is received.
+ * The entry that is more than 120 second is removed.
+ *
+ ***ASSUMPTIONS:
+ *
+ *
+ ***NOTE:
+ *
+ * @param  pMac   Pointer to Global MAC structure
+ * @param  addr   A pointer to probe request source MAC address
+ * @param  uuid_e A pointer to UUIDE element of WPS IE
+ * @param  psessionEntry   A pointer to station PE session
+ *
+ * @return None
+ */
+
+static void lim_update_pbc_session_entry(tpAniSirGlobal pMac,
+					 uint8_t *addr, uint8_t *uuid_e,
+					 tpPESession psessionEntry)
+{
+	tSirWPSPBCSession *pbc, *prev = NULL;
+
+	uint32_t curTime;
+
+	curTime =
+		(uint32_t) (qdf_mc_timer_get_system_ticks() /
+			    QDF_TICKS_PER_SECOND);
+
+	pe_debug("Receive WPS probe reques curTime: %d", curTime);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			   addr, QDF_MAC_ADDR_SIZE);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			   uuid_e, SIR_WPS_UUID_LEN);
+
+	pbc = psessionEntry->pAPWPSPBCSession;
+
+	while (pbc) {
+		if ((!qdf_mem_cmp
+			    ((uint8_t *) pbc->addr.bytes, (uint8_t *) addr,
+			    QDF_MAC_ADDR_SIZE))
+		    && (!qdf_mem_cmp((uint8_t *) pbc->uuid_e,
+				       (uint8_t *) uuid_e, SIR_WPS_UUID_LEN))) {
+			if (prev)
+				prev->next = pbc->next;
+			else
+				psessionEntry->pAPWPSPBCSession = pbc->next;
+			break;
+		}
+		prev = pbc;
+		pbc = pbc->next;
+	}
+
+	if (!pbc) {
+		pbc = qdf_mem_malloc(sizeof(tSirWPSPBCSession));
+		if (!pbc)
+			return;
+		qdf_mem_copy((uint8_t *) pbc->addr.bytes, (uint8_t *) addr,
+			     QDF_MAC_ADDR_SIZE);
+
+		if (uuid_e)
+			qdf_mem_copy((uint8_t *) pbc->uuid_e,
+				     (uint8_t *) uuid_e, SIR_WPS_UUID_LEN);
+	}
+
+	pbc->next = psessionEntry->pAPWPSPBCSession;
+	psessionEntry->pAPWPSPBCSession = pbc;
+	pbc->timestamp = curTime;
+
+	/* remove entries that have timed out */
+	prev = pbc;
+	pbc = pbc->next;
+
+	while (pbc) {
+		if (curTime > pbc->timestamp + SIR_WPS_PBC_WALK_TIME) {
+			prev->next = NULL;
+			lim_remove_timeout_pbc_sessions(pMac, pbc);
+			break;
+		}
+		prev = pbc;
+		pbc = pbc->next;
+	}
+}
+
+/**
+ * lim_wpspbc_close
+ *
+ ***FUNCTION:
+ * This function is called when BSS is closed
+ *
+ ***LOGIC:
+ * This function remove all the WPS PBC entries
+ *
+ ***ASSUMPTIONS:
+ *
+ *
+ ***NOTE:
+ *
+ * @param  pMac   Pointer to Global MAC structure
+ * @param  psessionEntry   A pointer to station PE session
+ *
+ * @return None
+ */
+
+void lim_wpspbc_close(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+
+	lim_remove_timeout_pbc_sessions(pMac, psessionEntry->pAPWPSPBCSession);
+
+}
+
+/**
+ * lim_check11b_rates
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_probe_req_frame() upon
+ * Probe Request frame reception.
+ *
+ ***LOGIC:
+ * This function check 11b rates in supportedRates and extendedRates rates
+ *
+ ***NOTE:
+ *
+ * @param  rate
+ *
+ * @return BOOLEAN
+ */
+
+static bool lim_check11b_rates(uint8_t rate)
+{
+	if ((0x02 == (rate))
+	    || (0x04 == (rate))
+	    || (0x0b == (rate))
+	    || (0x16 == (rate))
+	    ) {
+		return true;
+	}
+	return false;
+}
+
+/**
+ * lim_process_probe_req_frame: to process probe req frame
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_pkt_info: A pointer to Buffer descriptor + associated PDUs
+ * @session: a ponter to session entry
+ *
+ * This function is called by limProcessMessageQueue() upon
+ * Probe Request frame reception. This function processes received
+ * Probe Request frame and responds with Probe Response.
+ * Only AP or STA in IBSS mode that sent last Beacon will respond to
+ * Probe Request.
+ * ASSUMPTIONS:
+ * 1. AP or STA in IBSS mode that sent last Beacon will always respond
+ *    to Probe Request received with broadcast SSID.
+ * NOTE:
+ * 1. Dunno what to do with Rates received in Probe Request frame
+ * 2. Frames with out-of-order fields/IEs are dropped.
+ *
+ *
+ * Return: none
+ */
+
+void
+lim_process_probe_req_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+		tpPESession session)
+{
+	uint8_t *body_ptr;
+	tpSirMacMgmtHdr mac_hdr;
+	uint32_t frame_len;
+	tSirProbeReq probe_req;
+	tAniSSID ssid;
+
+	/* Don't send probe responses if disabled */
+	if (mac_ctx->lim.gLimProbeRespDisableFlag)
+		return;
+
+	/*
+	 * Don't send probe response if P2P go is scanning till scan
+	 * come to idle state.
+	 */
+	if ((session->pePersona == QDF_P2P_GO_MODE) &&
+	    mac_ctx->lim.gpLimRemainOnChanReq) {
+		pe_debug("GO is scanning, don't send probersp on diff chnl");
+		return;
+	}
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	if (LIM_IS_AP_ROLE(session) ||
+		(LIM_IS_IBSS_ROLE(session) &&
+			 (WMA_GET_RX_BEACON_SENT(rx_pkt_info)))) {
+		frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+		pe_debug("Received Probe Request: %d bytes from",
+			frame_len);
+			lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGD);
+		/* Get pointer to Probe Request frame body */
+		body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+
+		/* check for vendor IE presence */
+		if ((session->access_policy_vendor_ie) &&
+			(session->access_policy ==
+			LIM_ACCESS_POLICY_RESPOND_IF_IE_IS_PRESENT)) {
+			if (!wlan_get_vendor_ie_ptr_from_oui(
+				&session->access_policy_vendor_ie[2],
+				3, body_ptr, frame_len)) {
+				pe_warn("Vendor IE is not present and access policy is: %x dropping probe request",
+					session->access_policy);
+				return;
+			}
+		}
+
+		/* Parse Probe Request frame */
+		if (sir_convert_probe_req_frame2_struct(mac_ctx, body_ptr,
+				frame_len, &probe_req) == QDF_STATUS_E_FAILURE) {
+			pe_err("Parse error ProbeReq, length: %d, SA is: "
+					MAC_ADDRESS_STR, frame_len,
+					MAC_ADDR_ARRAY(mac_hdr->sa));
+			return;
+		}
+		if (session->pePersona == QDF_P2P_GO_MODE) {
+			uint8_t i = 0, rate_11b = 0, other_rates = 0;
+			/* Check 11b rates in supported rates */
+			for (i = 0; i < probe_req.supportedRates.numRates;
+				i++) {
+				if (lim_check11b_rates(
+					probe_req.supportedRates.rate[i] &
+								0x7f))
+					rate_11b++;
+				else
+					other_rates++;
+			}
+
+			/* Check 11b rates in extended rates */
+			for (i = 0; i < probe_req.extendedRates.numRates; i++) {
+				if (lim_check11b_rates(
+					probe_req.extendedRates.rate[i] & 0x7f))
+					rate_11b++;
+				else
+					other_rates++;
+			}
+
+			if ((rate_11b > 0) && (other_rates == 0)) {
+				pe_debug("Received a probe req frame with only 11b rates, SA is: ");
+					lim_print_mac_addr(mac_ctx,
+						mac_hdr->sa, LOGD);
+					return;
+			}
+		}
+		if (LIM_IS_AP_ROLE(session) &&
+			((session->APWPSIEs.SirWPSProbeRspIE.FieldPresent
+				& SIR_WPS_PROBRSP_VER_PRESENT)
+			&& (probe_req.wscIePresent == 1)
+			&& (probe_req.probeReqWscIeInfo.DevicePasswordID.id ==
+				WSC_PASSWD_ID_PUSH_BUTTON)
+			&& (probe_req.probeReqWscIeInfo.UUID_E.present == 1))) {
+			if (session->fwdWPSPBCProbeReq) {
+				QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+						   QDF_TRACE_LEVEL_DEBUG,
+						   mac_hdr->sa,
+						   QDF_MAC_ADDR_SIZE);
+				QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+						   QDF_TRACE_LEVEL_DEBUG,
+						   body_ptr, frame_len);
+				lim_send_sme_probe_req_ind(mac_ctx, mac_hdr->sa,
+					body_ptr, frame_len, session);
+			} else {
+				lim_update_pbc_session_entry(mac_ctx,
+					mac_hdr->sa,
+					probe_req.probeReqWscIeInfo.UUID_E.uuid,
+					session);
+			}
+		}
+		ssid.length = session->ssId.length;
+		/* Copy the SSID from sessio entry to local variable */
+		qdf_mem_copy(ssid.ssId, session->ssId.ssId,
+				session->ssId.length);
+
+		/*
+		 * Compare received SSID with current SSID. If they match,
+		 * reply with Probe Response
+		 */
+		if (probe_req.ssId.length) {
+			if (!ssid.length)
+				goto multipleSSIDcheck;
+
+			if (!qdf_mem_cmp((uint8_t *) &ssid,
+						(uint8_t *) &(probe_req.ssId),
+						(uint8_t) (ssid.length + 1))) {
+				lim_send_probe_rsp_mgmt_frame(mac_ctx,
+						mac_hdr->sa, &ssid,
+						DPH_USE_MGMT_STAID,
+						DPH_NON_KEEPALIVE_FRAME,
+						session,
+						probe_req.p2pIePresent);
+				return;
+			} else if (session->pePersona ==
+					QDF_P2P_GO_MODE) {
+				uint8_t direct_ssid[7] = "DIRECT-";
+				uint8_t direct_ssid_len = 7;
+
+				if (!qdf_mem_cmp((uint8_t *) &direct_ssid,
+					(uint8_t *) &(probe_req.ssId.ssId),
+					(uint8_t) (direct_ssid_len))) {
+					lim_send_probe_rsp_mgmt_frame(mac_ctx,
+							mac_hdr->sa,
+							&ssid,
+							DPH_USE_MGMT_STAID,
+							DPH_NON_KEEPALIVE_FRAME,
+							session,
+							probe_req.p2pIePresent);
+					return;
+				}
+			} else {
+				pe_debug("Ignore ProbeReq frm with unmatch SSID received from");
+					lim_print_mac_addr(mac_ctx, mac_hdr->sa,
+						LOGD);
+			}
+		} else {
+			/*
+			 * Broadcast SSID in the Probe Request.
+			 * Reply with SSID we're configured with.
+			 * Turn off the SSID length to 0 if hidden SSID feature
+			 * is present
+			 */
+			if (session->ssidHidden)
+				/*
+				 * We are returning from here as probe request
+				 * contains the broadcast SSID. So no need to
+				 * send the probe resp
+				 */
+				return;
+			lim_send_probe_rsp_mgmt_frame(mac_ctx, mac_hdr->sa,
+					&ssid,
+					DPH_USE_MGMT_STAID,
+					DPH_NON_KEEPALIVE_FRAME,
+					session,
+					probe_req.p2pIePresent);
+			return;
+		}
+multipleSSIDcheck:
+		pe_debug("Ignore ProbeReq frm with unmatch SSID rcved from");
+			lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGD);
+	} else {
+		/* Ignore received Probe Request frame */
+		pe_debug("Ignoring Probe Request frame received from");
+		lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGD);
+	}
+	return;
+}
+
+/**
+ * lim_indicate_probe_req_to_hdd
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_probe_req_frame_multiple_bss() upon
+ * Probe Request frame reception.
+ *
+ ***LOGIC:
+ * This function processes received Probe Request frame and Pass
+ * Probe Request Frame to HDD.
+ *
+ * @param  pMac              Pointer to Global MAC structure
+ * @param  *pBd              A pointer to Buffer descriptor + associated PDUs
+ * @param  psessionEntry     A pointer to PE session
+ *
+ * @return None
+ */
+
+static void
+lim_indicate_probe_req_to_hdd(tpAniSirGlobal pMac, uint8_t *pBd,
+			      tpPESession psessionEntry)
+{
+	tpSirMacMgmtHdr pHdr;
+	uint32_t frameLen;
+
+	pe_debug("Received a probe request frame");
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pBd);
+	frameLen = WMA_GET_RX_PAYLOAD_LEN(pBd);
+
+	/* send the probe req to SME. */
+	lim_send_sme_mgmt_frame_ind(pMac, pHdr->fc.subType,
+				    (uint8_t *) pHdr,
+				    (frameLen + sizeof(tSirMacMgmtHdr)),
+				    psessionEntry->smeSessionId, WMA_GET_RX_CH(pBd),
+				    psessionEntry,
+				    WMA_GET_RX_RSSI_NORMALIZED(pBd));
+} /*** end lim_indicate_probe_req_to_hdd() ***/
+
+/**
+ * lim_process_probe_req_frame_multiple_bss() - to process probe req
+ * @mac_ctx: Pointer to Global MAC structure
+ * @buf_descr: A pointer to Buffer descriptor + associated PDUs
+ * @session: A pointer to PE session
+ *
+ * This function is called by limProcessMessageQueue() upon
+ * Probe Request frame reception. This function call
+ * lim_indicate_probe_req_to_hdd function to indicate
+ * Probe Request frame to HDD. It also call lim_process_probe_req_frame
+ * function which process received Probe Request frame and responds
+ * with Probe Response.
+ *
+ * @return None
+ */
+void
+lim_process_probe_req_frame_multiple_bss(tpAniSirGlobal mac_ctx,
+			uint8_t *buf_descr, tpPESession session)
+{
+	uint8_t i;
+
+	if (session != NULL) {
+		if (LIM_IS_AP_ROLE(session)) {
+			lim_indicate_probe_req_to_hdd(mac_ctx,
+					buf_descr, session);
+		}
+		lim_process_probe_req_frame(mac_ctx, buf_descr, session);
+		return;
+	}
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		session = pe_find_session_by_session_id(mac_ctx, i);
+		if (session == NULL)
+			continue;
+		if (LIM_IS_AP_ROLE(session))
+			lim_indicate_probe_req_to_hdd(mac_ctx,
+					buf_descr, session);
+		if (LIM_IS_AP_ROLE(session) ||
+			LIM_IS_IBSS_ROLE(session))
+			lim_process_probe_req_frame(mac_ctx,
+					buf_descr, session);
+	}
+}
+
+/**
+ * lim_send_sme_probe_req_ind()
+ *
+ ***FUNCTION:
+ * This function is to send
+ *  eWNI_SME_WPS_PBC_PROBE_REQ_IND message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * This function is used for sending  eWNI_SME_WPS_PBC_PROBE_REQ_IND
+ * to host.
+ *
+ * @param peerMacAddr       Indicates the peer MAC addr that the probe request
+ *                          is generated.
+ * @param pProbeReqIE       pointer to RAW probe request IE
+ * @param ProbeReqIELen     The length of probe request IE.
+ * @param psessionEntry     A pointer to PE session
+ *
+ * @return None
+ */
+void
+lim_send_sme_probe_req_ind(tpAniSirGlobal pMac,
+			   tSirMacAddr peerMacAddr,
+			   uint8_t *pProbeReqIE,
+			   uint32_t ProbeReqIELen, tpPESession psessionEntry)
+{
+	tSirSmeProbeReqInd *pSirSmeProbeReqInd;
+	struct scheduler_msg msgQ = {0};
+
+	pSirSmeProbeReqInd = qdf_mem_malloc(sizeof(tSirSmeProbeReqInd));
+	if (!pSirSmeProbeReqInd)
+		return;
+
+	msgQ.type = eWNI_SME_WPS_PBC_PROBE_REQ_IND;
+	msgQ.bodyval = 0;
+	msgQ.bodyptr = pSirSmeProbeReqInd;
+
+	pSirSmeProbeReqInd->messageType = eWNI_SME_WPS_PBC_PROBE_REQ_IND;
+	pSirSmeProbeReqInd->length = sizeof(tSirSmeProbeReq);
+	pSirSmeProbeReqInd->sessionId = psessionEntry->smeSessionId;
+
+	qdf_mem_copy(pSirSmeProbeReqInd->bssid.bytes, psessionEntry->bssId,
+		     QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(pSirSmeProbeReqInd->WPSPBCProbeReq.peer_macaddr.bytes,
+		     peerMacAddr, QDF_MAC_ADDR_SIZE);
+
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+				psessionEntry->peSessionId, msgQ.type));
+
+	if (ProbeReqIELen > sizeof(pSirSmeProbeReqInd->WPSPBCProbeReq.
+	    probeReqIE)) {
+		ProbeReqIELen = sizeof(pSirSmeProbeReqInd->WPSPBCProbeReq.
+				       probeReqIE);
+	}
+
+	pSirSmeProbeReqInd->WPSPBCProbeReq.probeReqIELen =
+		(uint16_t) ProbeReqIELen;
+	qdf_mem_copy(pSirSmeProbeReqInd->WPSPBCProbeReq.probeReqIE, pProbeReqIE,
+		     ProbeReqIELen);
+
+	if (lim_sys_process_mmh_msg_api(pMac, &msgQ, ePROT) != QDF_STATUS_SUCCESS)
+		pe_err("couldnt send the probe req to hdd");
+
+} /*** end lim_send_sme_probe_req_ind() ***/
diff --git a/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c b/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c
new file mode 100644
index 0000000..e48faad
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_process_probe_rsp_frame.cc contains the code
+ * for processing Probe Response Frame.
+ * Author:        Chandra Modumudi
+ * Date:          03/01/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_send_messages.h"
+
+#include "parser_api.h"
+
+/**
+ * lim_validate_ie_information_in_probe_rsp_frame () - validates ie
+ * information in probe response.
+ * @mac_ctx: mac context
+ * @pRxPacketInfo: Rx packet info
+ *
+ * Return: 0 on success, one on failure
+ */
+static QDF_STATUS
+lim_validate_ie_information_in_probe_rsp_frame(tpAniSirGlobal mac_ctx,
+				uint8_t *pRxPacketInfo)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t *pframe;
+	uint32_t nframe;
+	uint32_t missing_rsn_bytes;
+
+	/*
+	 * Validate a Probe response frame for malformed frame.
+	 * If the frame is malformed then do not consider as it
+	 * may cause problem fetching wrong IE values
+	 */
+
+	if (WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) <
+		(SIR_MAC_B_PR_SSID_OFFSET + SIR_MAC_MIN_IE_LEN))
+		return QDF_STATUS_E_FAILURE;
+
+	pframe = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	nframe = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+	missing_rsn_bytes = 0;
+
+	status = sir_validate_and_rectify_ies(mac_ctx,
+			pframe, nframe, &missing_rsn_bytes);
+
+	if (status == QDF_STATUS_SUCCESS)
+		WMA_GET_RX_MPDU_LEN(pRxPacketInfo) += missing_rsn_bytes;
+
+	return status;
+}
+
+/**
+ * lim_process_probe_rsp_frame() - processes received Probe Response frame
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_Packet_info: A pointer to Buffer descriptor + associated PDUs
+ * @session_entry: Handle to the session.
+ *
+ * This function processes received Probe Response frame.
+ * Frames with out-of-order IEs are dropped.
+ * In case of IBSS, join 'success' makes MLM state machine
+ * transition into 'BSS started' state. This may have to change
+ * depending on supporting what kinda Authentication in IBSS.
+ *
+ * Return: None
+ */
+void
+lim_process_probe_rsp_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_Packet_info,
+			    tpPESession session_entry)
+{
+	uint8_t *body;
+	uint32_t frame_len = 0;
+	tSirMacAddr current_bssid;
+	tpSirMacMgmtHdr header;
+	tSirProbeRespBeacon *probe_rsp;
+	uint8_t qos_enabled = false;
+	uint8_t wme_enabled = false;
+
+	if (!session_entry) {
+		pe_err("session_entry is NULL");
+		return;
+	}
+	pe_debug("SessionId: %d ProbeRsp Frame is received",
+		session_entry->peSessionId);
+
+	probe_rsp = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
+	if (NULL == probe_rsp) {
+		pe_err("Unable to allocate memory");
+		return;
+	}
+
+	probe_rsp->ssId.length = 0;
+	probe_rsp->wpa.length = 0;
+
+	header = WMA_GET_RX_MAC_HEADER(rx_Packet_info);
+
+	pe_debug("Rx Probe Response with length = %d from "MAC_ADDRESS_STR,
+		WMA_GET_RX_MPDU_LEN(rx_Packet_info),
+		MAC_ADDR_ARRAY(header->sa));
+
+	/* Validate IE information before processing Probe Response Frame */
+	if (lim_validate_ie_information_in_probe_rsp_frame(mac_ctx,
+				rx_Packet_info) !=
+		QDF_STATUS_SUCCESS) {
+		pe_err("Parse error ProbeResponse, length=%d", frame_len);
+		qdf_mem_free(probe_rsp);
+		return;
+	}
+
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_Packet_info);
+	QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+		FL("Probe Resp Frame Received: BSSID "
+		MAC_ADDRESS_STR " (RSSI %d)"),
+		MAC_ADDR_ARRAY(header->bssId),
+		(uint) abs((int8_t)WMA_GET_RX_RSSI_NORMALIZED(rx_Packet_info)));
+	/* Get pointer to Probe Response frame body */
+	body = WMA_GET_RX_MPDU_DATA(rx_Packet_info);
+		/* Enforce Mandatory IEs */
+	if ((sir_convert_probe_frame2_struct(mac_ctx,
+		body, frame_len, probe_rsp) == QDF_STATUS_E_FAILURE) ||
+		!probe_rsp->ssidPresent) {
+		pe_err("Parse error ProbeResponse, length=%d", frame_len);
+		qdf_mem_free(probe_rsp);
+		return;
+	}
+
+	if (session_entry->limMlmState ==
+			eLIM_MLM_WT_JOIN_BEACON_STATE) {
+		/*
+		 * Either Beacon/probe response is required.
+		 * Hence store it in same buffer.
+		 */
+		if (session_entry->beacon != NULL) {
+			qdf_mem_free(session_entry->beacon);
+			session_entry->beacon = NULL;
+			session_entry->bcnLen = 0;
+		}
+		session_entry->bcnLen =
+			WMA_GET_RX_PAYLOAD_LEN(rx_Packet_info);
+			session_entry->beacon =
+			qdf_mem_malloc(session_entry->bcnLen);
+		if (NULL == session_entry->beacon) {
+			pe_err("No Memory to store beacon");
+		} else {
+			/*
+			 * Store the Beacon/ProbeRsp.
+			 * This is sent to csr/hdd in join cnf response.
+			 */
+			qdf_mem_copy(session_entry->beacon,
+				     WMA_GET_RX_MPDU_DATA
+					     (rx_Packet_info),
+				     session_entry->bcnLen);
+		}
+			/* STA in WT_JOIN_BEACON_STATE */
+		lim_check_and_announce_join_success(mac_ctx, probe_rsp,
+						header,
+						session_entry);
+	} else if (session_entry->limMlmState ==
+		   eLIM_MLM_LINK_ESTABLISHED_STATE) {
+		tpDphHashNode sta_ds = NULL;
+		/*
+		 * Check if this Probe Response is for
+		 * our Probe Request sent upon reaching
+		 * heart beat threshold
+		 */
+		sir_copy_mac_addr(current_bssid, session_entry->bssId);
+		if (qdf_mem_cmp(current_bssid, header->bssId,
+				sizeof(tSirMacAddr))) {
+			qdf_mem_free(probe_rsp);
+			return;
+		}
+		if (!LIM_IS_CONNECTION_ACTIVE(session_entry)) {
+			pe_warn("Recved Probe Resp from AP,AP-alive");
+			if (probe_rsp->HTInfo.present)
+				lim_received_hb_handler(mac_ctx,
+					probe_rsp->HTInfo.primaryChannel,
+					session_entry);
+			else
+				lim_received_hb_handler(mac_ctx,
+					(uint8_t)probe_rsp->channelNumber,
+					session_entry);
+		}
+		if (LIM_IS_STA_ROLE(session_entry) &&
+				!wma_is_csa_offload_enabled()) {
+			if (probe_rsp->channelSwitchPresent) {
+				/*
+				 * on receiving channel switch announcement
+				 * from AP, delete all TDLS peers before
+				 * leaving BSS and proceed for channel switch
+				 */
+				lim_delete_tdls_peers(mac_ctx, session_entry);
+
+				lim_update_channel_switch(mac_ctx,
+					probe_rsp,
+					session_entry);
+			} else if (session_entry->gLimSpecMgmt.dot11hChanSwState
+				== eLIM_11H_CHANSW_RUNNING) {
+				lim_cancel_dot11h_channel_switch(
+					mac_ctx, session_entry);
+			}
+		}
+		/*
+		 * Now Process EDCA Parameters, if EDCAParamSet
+		 * count is different.
+		 * -- While processing beacons in link established
+		 * state if it is determined that
+		 * QoS Info IE has a different count for EDCA Params,
+		 * and EDCA IE is not present in beacon,
+		 * then probe req is sent out to get the EDCA params.
+		 */
+		sta_ds = dph_get_hash_entry(mac_ctx,
+				DPH_STA_HASH_INDEX_PEER,
+				&session_entry->dph.dphHashTable);
+		limGetQosMode(session_entry, &qos_enabled);
+		limGetWmeMode(session_entry, &wme_enabled);
+		pe_debug("wmeEdcaPresent: %d wme_enabled: %d"
+			"edcaPresent: %d, qos_enabled: %d"
+			"edcaParams.qosInfo.count: %d"
+			"schObject.gLimEdcaParamSetCount: %d",
+			probe_rsp->wmeEdcaPresent, wme_enabled,
+			probe_rsp->edcaPresent, qos_enabled,
+			probe_rsp->edcaParams.qosInfo.count,
+			session_entry->gLimEdcaParamSetCount);
+
+		if (((probe_rsp->wmeEdcaPresent && wme_enabled) ||
+		     (probe_rsp->edcaPresent && qos_enabled)) &&
+		    (probe_rsp->edcaParams.qosInfo.count !=
+		     session_entry->gLimEdcaParamSetCount)) {
+			if (sch_beacon_edca_process(mac_ctx,
+				&probe_rsp->edcaParams,
+				session_entry) != QDF_STATUS_SUCCESS) {
+				pe_err("EDCA param process error");
+			} else if (sta_ds != NULL) {
+				/*
+				 * If needed, downgrade the
+				 * EDCA parameters
+				 */
+				lim_set_active_edca_params(mac_ctx,
+						session_entry->
+						gLimEdcaParams,
+						session_entry);
+				lim_send_edca_params(mac_ctx,
+					session_entry->gLimEdcaParamsActive,
+					sta_ds->bssId, false);
+			} else {
+				pe_err("SelfEntry missing in Hash");
+			}
+		}
+		if (session_entry->fWaitForProbeRsp == true) {
+			pe_warn("Check probe resp for caps change");
+			lim_detect_change_in_ap_capabilities(
+				mac_ctx, probe_rsp, session_entry);
+		}
+	} else {
+		if (LIM_IS_IBSS_ROLE(session_entry) &&
+		    (session_entry->limMlmState ==
+				eLIM_MLM_BSS_STARTED_STATE))
+			lim_handle_ibss_coalescing(mac_ctx, probe_rsp,
+					rx_Packet_info, session_entry);
+	}
+	qdf_mem_free(probe_rsp);
+
+	/* Ignore Probe Response frame in all other states */
+	return;
+}
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
new file mode 100644
index 0000000..2383a28
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -0,0 +1,6490 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file lim_process_sme_req_messages.cc contains the code
+ * for processing SME request messages.
+ * Author:        Chandra Modumudi
+ * Date:          02/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "cds_api.h"
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include "sir_api.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_sme_req_utils.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_admit_control.h"
+#include "dph_hash_table.h"
+#include "lim_send_messages.h"
+#include "lim_api.h"
+#include "wmm_apsd.h"
+#include "sir_mac_prot_def.h"
+#include "rrm_api.h"
+#include "nan_datapath.h"
+#include "sap_api.h"
+#include <lim_ft.h>
+#include "cds_regdomain.h"
+#include "lim_process_fils.h"
+#include "wlan_utility.h"
+
+/*
+ * This overhead is time for sending NOA start to host in case of GO/sending
+ * NULL data & receiving ACK in case of P2P Client and starting actual scanning
+ * with init scan req/rsp plus in case of concurrency, taking care of sending
+ * null data and receiving ACK to/from AP/Also SetChannel with calibration
+ * is taking around 7ms .
+ */
+#define SCAN_MESSAGING_OVERHEAD             20  /* in msecs */
+#define JOIN_NOA_DURATION                   2000        /* in msecs */
+#define OEM_DATA_NOA_DURATION               60  /* in msecs */
+#define DEFAULT_PASSIVE_MAX_CHANNEL_TIME    110 /* in msecs */
+
+#define CONV_MS_TO_US 1024      /* conversion factor from ms to us */
+
+#define BEACON_INTERVAL_THRESHOLD 50  /* in msecs */
+#define STA_BURST_SCAN_DURATION 120   /* in msecs */
+
+/* SME REQ processing function templates */
+static bool __lim_process_sme_sys_ready_ind(tpAniSirGlobal, uint32_t *);
+static bool __lim_process_sme_start_bss_req(tpAniSirGlobal,
+					    struct scheduler_msg *pMsg);
+static void __lim_process_sme_join_req(tpAniSirGlobal, uint32_t *);
+static void __lim_process_sme_reassoc_req(tpAniSirGlobal, uint32_t *);
+static void __lim_process_sme_disassoc_req(tpAniSirGlobal, uint32_t *);
+static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal, uint32_t *);
+static void __lim_process_sme_deauth_req(tpAniSirGlobal, uint32_t *);
+static void __lim_process_sme_set_context_req(tpAniSirGlobal, uint32_t *);
+static bool __lim_process_sme_stop_bss_req(tpAniSirGlobal,
+					   struct scheduler_msg *pMsg);
+static void __lim_process_send_disassoc_frame(tpAniSirGlobal mac_ctx,
+				uint32_t *msg_buf);
+static void lim_process_sme_channel_change_request(tpAniSirGlobal pMac,
+						   uint32_t *pMsg);
+static void lim_process_sme_start_beacon_req(tpAniSirGlobal pMac, uint32_t *pMsg);
+static void lim_process_sme_dfs_csa_ie_request(tpAniSirGlobal pMac, uint32_t *pMsg);
+static void lim_process_nss_update_request(tpAniSirGlobal pMac, uint32_t *pMsg);
+static void lim_process_set_ie_req(tpAniSirGlobal pMac, uint32_t *pMsg);
+
+static void lim_start_bss_update_add_ie_buffer(tpAniSirGlobal pMac,
+					       uint8_t **pDstData_buff,
+					       uint16_t *pDstDataLen,
+					       uint8_t *pSrcData_buff,
+					       uint16_t srcDataLen);
+
+static void lim_update_add_ie_buffer(tpAniSirGlobal pMac,
+				     uint8_t **pDstData_buff,
+				     uint16_t *pDstDataLen,
+				     uint8_t *pSrcData_buff, uint16_t srcDataLen);
+static bool lim_update_ibss_prop_add_ies(tpAniSirGlobal pMac,
+					 uint8_t **pDstData_buff,
+					 uint16_t *pDstDataLen,
+					 tSirModifyIE *pModifyIE);
+static void lim_process_modify_add_ies(tpAniSirGlobal pMac, uint32_t *pMsg);
+
+static void lim_process_update_add_ies(tpAniSirGlobal pMac, uint32_t *pMsg);
+
+static void lim_process_ext_change_channel(tpAniSirGlobal mac_ctx,
+						uint32_t *msg);
+
+/**
+ * lim_process_set_hw_mode() - Send set HW mode command to WMA
+ * @mac: Globacl MAC pointer
+ * @msg: Message containing the hw mode index
+ *
+ * Send the set HW mode command to WMA
+ *
+ * Return: QDF_STATUS_SUCCESS if message posting is successful
+ */
+static QDF_STATUS lim_process_set_hw_mode(tpAniSirGlobal mac, uint32_t *msg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg message = {0};
+	struct policy_mgr_hw_mode *req_msg;
+	uint32_t len;
+	struct s_sir_set_hw_mode *buf;
+	struct scheduler_msg resp_msg = {0};
+	struct sir_set_hw_mode_resp *param;
+
+	buf = (struct s_sir_set_hw_mode *) msg;
+	if (!buf) {
+		pe_err("Set HW mode param is NULL");
+		status = QDF_STATUS_E_INVAL;
+		/* To free the active command list */
+		goto fail;
+	}
+
+	len = sizeof(*req_msg);
+
+	req_msg = qdf_mem_malloc(len);
+	if (!req_msg) {
+		pe_debug("failed to allocate memory");
+		status = QDF_STATUS_E_NOMEM;
+		goto fail;
+	}
+
+	req_msg->hw_mode_index = buf->set_hw.hw_mode_index;
+	req_msg->reason = buf->set_hw.reason;
+	/* Other parameters are not needed for WMA */
+
+	message.bodyptr = req_msg;
+	message.type    = SIR_HAL_PDEV_SET_HW_MODE;
+
+	pe_debug("Posting SIR_HAL_SOC_SET_HW_MOD to WMA");
+	status = scheduler_post_message(QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		pe_err("scheduler_post_msg failed!(err=%d)",
+			status);
+		qdf_mem_free(req_msg);
+		goto fail;
+	}
+	return status;
+fail:
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return QDF_STATUS_E_FAILURE;
+	param->status = SET_HW_MODE_STATUS_ECANCELED;
+	param->cfgd_hw_mode_index = 0;
+	param->num_vdev_mac_entries = 0;
+	resp_msg.type = eWNI_SME_SET_HW_MODE_RESP;
+	resp_msg.bodyptr = param;
+	resp_msg.bodyval = 0;
+	lim_sys_process_mmh_msg_api(mac, &resp_msg, ePROT);
+	return status;
+}
+
+/**
+ * lim_process_set_dual_mac_cfg_req() - Set dual mac config command to WMA
+ * @mac: Global MAC pointer
+ * @msg: Message containing the dual mac config parameter
+ *
+ * Send the set dual mac config command to WMA
+ *
+ * Return: QDF_STATUS_SUCCESS if message posting is successful
+ */
+static QDF_STATUS lim_process_set_dual_mac_cfg_req(tpAniSirGlobal mac,
+		uint32_t *msg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg message = {0};
+	struct policy_mgr_dual_mac_config *req_msg;
+	uint32_t len;
+	struct sir_set_dual_mac_cfg *buf;
+	struct scheduler_msg resp_msg = {0};
+	struct sir_dual_mac_config_resp *param;
+
+	buf = (struct sir_set_dual_mac_cfg *) msg;
+	if (!buf) {
+		pe_err("Set Dual mac config is NULL");
+		status = QDF_STATUS_E_INVAL;
+		/* To free the active command list */
+		goto fail;
+	}
+
+	len = sizeof(*req_msg);
+
+	req_msg = qdf_mem_malloc(len);
+	if (!req_msg) {
+		pe_debug("failed to allocate memory");
+		status = QDF_STATUS_E_NOMEM;
+		goto fail;
+	}
+
+	req_msg->scan_config = buf->set_dual_mac.scan_config;
+	req_msg->fw_mode_config = buf->set_dual_mac.fw_mode_config;
+	/* Other parameters are not needed for WMA */
+
+	message.bodyptr = req_msg;
+	message.type    = SIR_HAL_PDEV_DUAL_MAC_CFG_REQ;
+
+	pe_debug("Post SIR_HAL_PDEV_DUAL_MAC_CFG_REQ to WMA: %x %x",
+		req_msg->scan_config, req_msg->fw_mode_config);
+	status = scheduler_post_message(QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		pe_err("scheduler_post_msg failed!(err=%d)",
+				status);
+		qdf_mem_free(req_msg);
+		goto fail;
+	}
+	return status;
+fail:
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return QDF_STATUS_E_FAILURE;
+	param->status = SET_HW_MODE_STATUS_ECANCELED;
+	resp_msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP;
+	resp_msg.bodyptr = param;
+	resp_msg.bodyval = 0;
+	lim_sys_process_mmh_msg_api(mac, &resp_msg, ePROT);
+	return status;
+}
+
+/**
+ * lim_process_set_antenna_mode_req() - Set antenna mode command
+ * to WMA
+ * @mac: Global MAC pointer
+ * @msg: Message containing the antenna mode parameter
+ *
+ * Send the set antenna mode command to WMA
+ *
+ * Return: QDF_STATUS_SUCCESS if message posting is successful
+ */
+static QDF_STATUS lim_process_set_antenna_mode_req(tpAniSirGlobal mac,
+		uint32_t *msg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg message = {0};
+	struct sir_antenna_mode_param *req_msg;
+	struct sir_set_antenna_mode *buf;
+	struct scheduler_msg resp_msg = {0};
+	struct sir_antenna_mode_resp *param;
+
+	buf = (struct sir_set_antenna_mode *) msg;
+	if (!buf) {
+		pe_err("Set antenna mode is NULL");
+		status = QDF_STATUS_E_INVAL;
+		/* To free the active command list */
+		goto fail;
+	}
+
+	req_msg = qdf_mem_malloc(sizeof(*req_msg));
+	if (!req_msg) {
+		pe_debug("failed to allocate memory");
+		status = QDF_STATUS_E_NOMEM;
+		goto fail;
+	}
+
+	req_msg->num_rx_chains = buf->set_antenna_mode.num_rx_chains;
+	req_msg->num_tx_chains = buf->set_antenna_mode.num_tx_chains;
+
+	message.bodyptr = req_msg;
+	message.type    = SIR_HAL_SOC_ANTENNA_MODE_REQ;
+
+	pe_debug("Post SIR_HAL_SOC_ANTENNA_MODE_REQ to WMA: %d %d",
+		req_msg->num_rx_chains,
+		req_msg->num_tx_chains);
+	status = scheduler_post_message(QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		pe_err("scheduler_post_msg failed!(err=%d)",
+				status);
+		qdf_mem_free(req_msg);
+		goto fail;
+	}
+	return status;
+fail:
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return QDF_STATUS_E_NOMEM;
+	param->status = SET_ANTENNA_MODE_STATUS_ECANCELED;
+	resp_msg.type = eWNI_SME_SET_ANTENNA_MODE_RESP;
+	resp_msg.bodyptr = param;
+	resp_msg.bodyval = 0;
+	lim_sys_process_mmh_msg_api(mac, &resp_msg, ePROT);
+	return status;
+}
+
+/**
+ * __lim_is_sme_assoc_cnf_valid()
+ *
+ ***FUNCTION:
+ * This function is called by __lim_process_sme_assoc_cnf_new() upon
+ * receiving SME_ASSOC_CNF.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMeasReq  Pointer to Received ASSOC_CNF message
+ * @return true      When received SME_ASSOC_CNF is formatted
+ *                   correctly
+ *         false     otherwise
+ */
+
+static inline uint8_t __lim_is_sme_assoc_cnf_valid(tpSirSmeAssocCnf pAssocCnf)
+{
+	if (qdf_is_macaddr_group(&pAssocCnf->peer_macaddr))
+		return false;
+	else
+		return true;
+} /*** end __lim_is_sme_assoc_cnf_valid() ***/
+
+/**
+ * __lim_get_sme_join_req_size_for_alloc()
+ *
+ ***FUNCTION:
+ * This function is called in various places to get IE length
+ * from tSirBssDescription structure
+ * number being scanned.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param     pBssDescr
+ * @return    Total IE length
+ */
+
+static uint16_t __lim_get_sme_join_req_size_for_alloc(uint8_t *pBuf)
+{
+	uint16_t len = 0;
+
+	if (!pBuf)
+		return len;
+
+	pBuf += sizeof(uint16_t);
+	len = lim_get_u16(pBuf);
+	return len;
+}
+
+/**
+ * __lim_is_defered_msg_for_learn() - message handling in SME learn state
+ * @pMac: Global MAC context
+ * @pMsg: Pointer to message posted from SME to LIM.
+ *
+ * Has role only if 11h is enabled. Not used on STA side.
+ * Defers the message if SME is in learn state and brings
+ * the LIM back to normal mode.
+ *
+ * Return: true - If defered false - Otherwise
+ */
+
+static bool __lim_is_defered_msg_for_learn(tpAniSirGlobal pMac,
+					   struct scheduler_msg *pMsg)
+{
+	if (lim_is_system_in_scan_state(pMac)) {
+		if (lim_defer_msg(pMac, pMsg) != TX_SUCCESS) {
+			pe_err("Could not defer Msg: %d", pMsg->type);
+			return false;
+		}
+		pe_debug("Defer the message, in learn mode type: %d",
+			pMsg->type);
+		return true;
+	}
+	return false;
+}
+
+/**
+ * __lim_is_defered_msg_for_radar() - Defers the message if radar is detected
+ * @mac_ctx: Pointer to Global MAC structure
+ * @message: Pointer to message posted from SME to LIM.
+ *
+ * Has role only if 11h is enabled. Not used on STA side.
+ * Defers the message if radar is detected.
+ *
+ * Return: true, if defered otherwise return false.
+ */
+static bool
+__lim_is_defered_msg_for_radar(tpAniSirGlobal mac_ctx,
+			       struct scheduler_msg *message)
+{
+	/*
+	 * fRadarDetCurOperChan will be set only if we
+	 * detect radar in current operating channel and
+	 * System Role == AP ROLE
+	 *
+	 * TODO: Need to take care radar detection.
+	 *
+	 * if (LIM_IS_RADAR_DETECTED(mac_ctx))
+	 */
+	if (0) {
+		if (lim_defer_msg(mac_ctx, message) != TX_SUCCESS) {
+			pe_err("Could not defer Msg: %d", message->type);
+			return false;
+		}
+		pe_debug("Defer the message, in learn mode type: %d",
+			message->type);
+		return true;
+	}
+	return false;
+}
+
+/**
+ * __lim_process_sme_sys_ready_ind () - Process ready indication from WMA
+ * @pMac: Global MAC context
+ * @pMsgBuf: Message from WMA
+ *
+ * handles the notification from HDD. PE just forwards this message to HAL.
+ *
+ * Return: true-Posting to HAL failed, so PE will consume the buffer.
+ *         false-Posting to HAL successful, so HAL will consume the buffer.
+ */
+
+static bool __lim_process_sme_sys_ready_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	struct scheduler_msg msg = {0};
+	tSirSmeReadyReq *ready_req = (tSirSmeReadyReq *) pMsgBuf;
+
+	msg.type = WMA_SYS_READY_IND;
+	msg.reserved = 0;
+	msg.bodyptr = pMsgBuf;
+	msg.bodyval = 0;
+
+	if (ANI_DRIVER_TYPE(pMac) != QDF_DRIVER_TYPE_MFG) {
+		ready_req->pe_roam_synch_cb = pe_roam_synch_callback;
+		pe_register_mgmt_rx_frm_callback(pMac);
+		pe_register_callbacks_with_wma(pMac, ready_req);
+		pMac->lim.sme_msg_callback = ready_req->sme_msg_cb;
+		pMac->lim.stop_roaming_callback = ready_req->stop_roaming_cb;
+	}
+
+	pe_debug("sending WMA_SYS_READY_IND msg to HAL");
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msg.type));
+
+	if (QDF_STATUS_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
+		pe_err("wma_post_ctrl_msg failed");
+		return true;
+	}
+	return false;
+}
+
+/**
+ *lim_configure_ap_start_bss_session() - Configure the AP Start BSS in session.
+ *@mac_ctx: Pointer to Global MAC structure
+ *@session: A pointer to session entry
+ *@sme_start_bss_req: Start BSS Request from upper layers.
+ *
+ * This function is used to configure the start bss parameters
+ * in to the session.
+ *
+ * Return: None.
+ */
+static void
+lim_configure_ap_start_bss_session(tpAniSirGlobal mac_ctx, tpPESession session,
+			tpSirSmeStartBssReq sme_start_bss_req)
+{
+	session->limSystemRole = eLIM_AP_ROLE;
+	session->privacy = sme_start_bss_req->privacy;
+	session->fwdWPSPBCProbeReq = sme_start_bss_req->fwdWPSPBCProbeReq;
+	session->authType = sme_start_bss_req->authType;
+	/* Store the DTIM period */
+	session->dtimPeriod = (uint8_t) sme_start_bss_req->dtimPeriod;
+	/* Enable/disable UAPSD */
+	session->apUapsdEnable = sme_start_bss_req->apUapsdEnable;
+	if (session->pePersona == QDF_P2P_GO_MODE) {
+		session->proxyProbeRspEn = 0;
+	} else {
+		/*
+		 * To detect PBC overlap in SAP WPS mode,
+		 * Host handles Probe Requests.
+		 */
+		if (SAP_WPS_DISABLED == sme_start_bss_req->wps_state)
+			session->proxyProbeRspEn = 1;
+		else
+			session->proxyProbeRspEn = 0;
+	}
+	session->ssidHidden = sme_start_bss_req->ssidHidden;
+	session->wps_state = sme_start_bss_req->wps_state;
+	session->sap_dot11mc = sme_start_bss_req->sap_dot11mc;
+	session->vendor_vht_sap =
+			sme_start_bss_req->vendor_vht_sap;
+	lim_get_short_slot_from_phy_mode(mac_ctx, session, session->gLimPhyMode,
+		&session->shortSlotTimeSupported);
+	session->isCoalesingInIBSSAllowed =
+		sme_start_bss_req->isCoalesingInIBSSAllowed;
+
+	session->beacon_tx_rate = sme_start_bss_req->beacon_tx_rate;
+
+}
+
+/**
+ * lim_send_start_vdev_req() - send vdev start request
+ *@session: pe session
+ *@mlm_start_req: vdev start req
+ *
+ * Return: QDF_STATUS
+ */
+#ifdef CONFIG_VDEV_SM
+static QDF_STATUS
+lim_send_start_vdev_req(tpPESession session, tLimMlmStartReq *mlm_start_req)
+{
+	return wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					     WLAN_VDEV_SM_EV_START,
+					     sizeof(*mlm_start_req),
+					     mlm_start_req);
+}
+#else
+static QDF_STATUS
+lim_send_start_vdev_req(tpPESession session, tLimMlmStartReq *mlm_start_req)
+{
+	lim_process_mlm_start_req(session->mac_ctx, mlm_start_req);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * __lim_handle_sme_start_bss_request() - process SME_START_BSS_REQ message
+ *@mac_ctx: Pointer to Global MAC structure
+ *@msg_buf: A pointer to the SME message buffer
+ *
+ * This function is called to process SME_START_BSS_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+static void
+__lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+	uint16_t size;
+	uint32_t val = 0;
+	QDF_STATUS ret_status;
+	tSirMacChanNum channel_number;
+	tLimMlmStartReq *mlm_start_req = NULL;
+	tpSirSmeStartBssReq sme_start_bss_req = NULL;
+	tSirResultCodes ret_code = eSIR_SME_SUCCESS;
+	/* Flag Used in case of IBSS to Auto generate BSSID. */
+	uint32_t auto_gen_bssid = false;
+	uint8_t session_id;
+	tpPESession session = NULL;
+	uint8_t sme_session_id = 0xFF;
+	uint16_t sme_transaction_id = 0xFF;
+	uint32_t chanwidth;
+	struct vdev_type_nss *vdev_type_nss;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+/* FEATURE_WLAN_DIAG_SUPPORT */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+	/*
+	 * Since the session is not created yet, sending NULL.
+	 * The response should have the correct state.
+	 */
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_START_BSS_REQ_EVENT,
+			      NULL, 0, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	pe_debug("Received START_BSS_REQ");
+	size = sizeof(tSirSmeStartBssReq);
+	sme_start_bss_req = qdf_mem_malloc(size);
+	if (!sme_start_bss_req) {
+		ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+		goto free;
+	}
+	qdf_mem_copy(sme_start_bss_req, msg_buf, sizeof(tSirSmeStartBssReq));
+	sme_session_id = sme_start_bss_req->sessionId;
+	sme_transaction_id = sme_start_bss_req->transactionId;
+
+	if ((mac_ctx->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) ||
+	    (mac_ctx->lim.gLimSmeState == eLIM_SME_IDLE_STATE)) {
+		if (!lim_is_sme_start_bss_req_valid(mac_ctx,
+					sme_start_bss_req)) {
+			pe_warn("Received invalid eWNI_SME_START_BSS_REQ");
+			ret_code = eSIR_SME_INVALID_PARAMETERS;
+			goto free;
+		}
+
+		/*
+		 * This is the place where PE is going to create a session.
+		 * If session is not existed, then create a new session
+		 */
+		session = pe_find_session_by_bssid(mac_ctx,
+				sme_start_bss_req->bssid.bytes, &session_id);
+		if (session != NULL) {
+			pe_warn("Session Already exists for given BSSID");
+			ret_code = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+			session = NULL;
+			goto free;
+		} else {
+			session = pe_create_session(mac_ctx,
+					sme_start_bss_req->bssid.bytes,
+					&session_id, mac_ctx->lim.maxStation,
+					sme_start_bss_req->bssType,
+					sme_start_bss_req->sessionId);
+			if (!session) {
+				pe_warn("Session Can not be created");
+				ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+				goto free;
+			}
+
+			/* Update the beacon/probe filter in mac_ctx */
+			lim_set_bcn_probe_filter(mac_ctx, session,
+						 &sme_start_bss_req->ssId,
+						 sme_start_bss_req->channelId);
+		}
+
+		if (QDF_NDI_MODE != sme_start_bss_req->bssPersona) {
+			/* Probe resp add ie */
+			lim_start_bss_update_add_ie_buffer(mac_ctx,
+				&session->addIeParams.probeRespData_buff,
+				&session->addIeParams.probeRespDataLen,
+				sme_start_bss_req->addIeParams.
+					probeRespData_buff,
+				sme_start_bss_req->addIeParams.
+					probeRespDataLen);
+
+			/* Probe Beacon add ie */
+			lim_start_bss_update_add_ie_buffer(mac_ctx,
+				&session->addIeParams.probeRespBCNData_buff,
+				&session->addIeParams.probeRespBCNDataLen,
+				sme_start_bss_req->addIeParams.
+					probeRespBCNData_buff,
+				sme_start_bss_req->addIeParams.
+					probeRespBCNDataLen);
+
+			/* Assoc resp IE */
+			lim_start_bss_update_add_ie_buffer(mac_ctx,
+				&session->addIeParams.assocRespData_buff,
+				&session->addIeParams.assocRespDataLen,
+				sme_start_bss_req->addIeParams.
+					assocRespData_buff,
+				sme_start_bss_req->addIeParams.
+					assocRespDataLen);
+		}
+		/* Store the session related params in newly created session */
+		session->pLimStartBssReq = sme_start_bss_req;
+
+		session->transactionId = sme_start_bss_req->transactionId;
+
+		qdf_mem_copy(&(session->htConfig),
+			     &(sme_start_bss_req->htConfig),
+			     sizeof(session->htConfig));
+
+		qdf_mem_copy(&(session->vht_config),
+			     &(sme_start_bss_req->vht_config),
+			     sizeof(session->vht_config));
+
+		sir_copy_mac_addr(session->selfMacAddr,
+				  sme_start_bss_req->self_macaddr.bytes);
+
+		/* Copy SSID to session table */
+		qdf_mem_copy((uint8_t *) &session->ssId,
+			     (uint8_t *) &sme_start_bss_req->ssId,
+			     (sme_start_bss_req->ssId.length + 1));
+
+		session->bssType = sme_start_bss_req->bssType;
+
+		session->nwType = sme_start_bss_req->nwType;
+
+		session->beaconParams.beaconInterval =
+			sme_start_bss_req->beaconInterval;
+
+		/* Store the channel number in session Table */
+		session->currentOperChannel =
+			sme_start_bss_req->channelId;
+
+		/* Store Persona */
+		session->pePersona = sme_start_bss_req->bssPersona;
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			  FL("PE PERSONA=%d"), session->pePersona);
+
+		/* Update the phymode */
+		session->gLimPhyMode = sme_start_bss_req->nwType;
+
+		session->maxTxPower =
+			cfg_get_regulatory_max_transmit_power(mac_ctx,
+				session->currentOperChannel);
+		/* Store the dot 11 mode in to the session Table */
+		session->dot11mode = sme_start_bss_req->dot11mode;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+		session->cc_switch_mode =
+			sme_start_bss_req->cc_switch_mode;
+#endif
+		session->htCapability =
+			IS_DOT11_MODE_HT(session->dot11mode);
+		session->vhtCapability =
+			IS_DOT11_MODE_VHT(session->dot11mode);
+
+		pe_debug("HT[%d], VHT[%d]",
+			session->htCapability, session->vhtCapability);
+
+		if (IS_DOT11_MODE_HE(session->dot11mode)) {
+			lim_update_session_he_capable(mac_ctx, session);
+			lim_copy_bss_he_cap(session, sme_start_bss_req);
+		}
+
+		session->txLdpcIniFeatureEnabled =
+			sme_start_bss_req->txLdpcIniFeatureEnabled;
+#ifdef WLAN_FEATURE_11W
+		session->limRmfEnabled =
+			sme_start_bss_req->pmfCapable ? 1 : 0;
+		pe_debug("Session RMF enabled: %d", session->limRmfEnabled);
+#endif
+
+		qdf_mem_copy((void *)&session->rateSet,
+			     (void *)&sme_start_bss_req->operationalRateSet,
+			     sizeof(tSirMacRateSet));
+		qdf_mem_copy((void *)&session->extRateSet,
+			     (void *)&sme_start_bss_req->extendedRateSet,
+			     sizeof(tSirMacRateSet));
+
+		if (IS_5G_CH(session->currentOperChannel))
+			vdev_type_nss = &mac_ctx->vdev_type_nss_5g;
+		else
+			vdev_type_nss = &mac_ctx->vdev_type_nss_2g;
+
+		switch (sme_start_bss_req->bssType) {
+		case eSIR_INFRA_AP_MODE:
+			lim_configure_ap_start_bss_session(mac_ctx, session,
+				sme_start_bss_req);
+			if (session->pePersona == QDF_SAP_MODE)
+				session->vdev_nss = vdev_type_nss->sap;
+			else
+				session->vdev_nss = vdev_type_nss->p2p_go;
+			break;
+		case eSIR_IBSS_MODE:
+			session->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+			lim_get_short_slot_from_phy_mode(mac_ctx, session,
+				session->gLimPhyMode,
+				&session->shortSlotTimeSupported);
+
+			/*
+			 * initialize to "OPEN".
+			 * will be updated upon key installation
+			 */
+			session->encryptType = eSIR_ED_NONE;
+			session->vdev_nss = vdev_type_nss->ibss;
+
+			break;
+		case eSIR_NDI_MODE:
+			session->limSystemRole = eLIM_NDI_ROLE;
+			break;
+
+
+		/*
+		 * There is one more mode called auto mode.
+		 * which is used no where
+		 */
+
+		/* FORBUILD -TEMPFIX.. HOW TO use AUTO MODE????? */
+
+		default:
+			/* not used anywhere...used in scan function */
+			break;
+		}
+
+		pe_debug("persona - %d, nss - %d",
+				session->pePersona, session->vdev_nss);
+		session->nss = session->vdev_nss;
+		if (!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2)
+			session->nss = 1;
+		/*
+		 * Allocate memory for the array of
+		 * parsed (Re)Assoc request structure
+		 */
+		if (sme_start_bss_req->bssType == eSIR_INFRA_AP_MODE) {
+			session->parsedAssocReq =
+				qdf_mem_malloc(session->dph.dphHashTable.
+						size * sizeof(tpSirAssocReq));
+			if (!session->parsedAssocReq) {
+				ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+				goto free;
+			}
+		}
+
+		if (!sme_start_bss_req->channelId &&
+		    sme_start_bss_req->bssType != eSIR_NDI_MODE) {
+			pe_err("Received invalid eWNI_SME_START_BSS_REQ");
+			ret_code = eSIR_SME_INVALID_PARAMETERS;
+			goto free;
+		}
+		channel_number = sme_start_bss_req->channelId;
+#ifdef QCA_HT_2040_COEX
+		if (sme_start_bss_req->obssEnabled)
+			session->htSupportedChannelWidthSet =
+				session->htCapability;
+		else
+#endif
+		session->htSupportedChannelWidthSet =
+			(sme_start_bss_req->sec_ch_offset) ? 1 : 0;
+		session->htSecondaryChannelOffset =
+			sme_start_bss_req->sec_ch_offset;
+		session->htRecommendedTxWidthSet =
+			(session->htSecondaryChannelOffset) ? 1 : 0;
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			  FL("cbMode %u"), sme_start_bss_req->cbMode);
+		if (lim_is_session_he_capable(session) ||
+		    session->vhtCapability || session->htCapability) {
+			chanwidth = sme_start_bss_req->vht_channel_width;
+			pe_debug("vht_channel_width %u htSupportedChannelWidthSet %d",
+				sme_start_bss_req->vht_channel_width,
+				session->htSupportedChannelWidthSet);
+			session->ch_width = chanwidth;
+			if (session->htSupportedChannelWidthSet) {
+				session->ch_center_freq_seg0 =
+					sme_start_bss_req->center_freq_seg0;
+				session->ch_center_freq_seg1 =
+					sme_start_bss_req->center_freq_seg1;
+			} else {
+				session->ch_center_freq_seg0 = 0;
+				session->ch_center_freq_seg1 = 0;
+			}
+		}
+
+		if (session->vhtCapability &&
+			(session->ch_width > CH_WIDTH_80MHZ)) {
+			session->nss = 1;
+			pe_debug("nss set to [%d]", session->nss);
+		}
+		pe_debug("vht su tx bformer %d",
+			session->vht_config.su_beam_former);
+
+		/* Delete pre-auth list if any */
+		lim_delete_pre_auth_list(mac_ctx);
+
+		/*
+		 * keep the RSN/WPA IE information in PE Session Entry
+		 * later will be using this to check when received (Re)Assoc req
+		 */
+		lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message(mac_ctx,
+				&sme_start_bss_req->rsnIE, session);
+
+		if (LIM_IS_AP_ROLE(session) ||
+		    LIM_IS_IBSS_ROLE(session) ||
+		    LIM_IS_NDI_ROLE(session)) {
+			session->gLimProtectionControl =
+				sme_start_bss_req->protEnabled;
+			/*
+			 * each byte will have the following info
+			 * bit7       bit6    bit5   bit4 bit3   bit2  bit1 bit0
+			 * reserved reserved   RIFS   Lsig n-GF   ht20  11g  11b
+			 */
+			qdf_mem_copy((void *)&session->cfgProtection,
+				     (void *)&sme_start_bss_req->ht_capab,
+				     sizeof(uint16_t));
+			/* Initialize WPS PBC session link list */
+			session->pAPWPSPBCSession = NULL;
+		}
+		/* Prepare and Issue LIM_MLM_START_REQ to MLM */
+		mlm_start_req = qdf_mem_malloc(sizeof(tLimMlmStartReq));
+		if (!mlm_start_req) {
+			ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+			goto free;
+		}
+
+		/* Copy SSID to the MLM start structure */
+		qdf_mem_copy((uint8_t *) &mlm_start_req->ssId,
+			     (uint8_t *) &sme_start_bss_req->ssId,
+			     sme_start_bss_req->ssId.length + 1);
+		mlm_start_req->ssidHidden = sme_start_bss_req->ssidHidden;
+		mlm_start_req->obssProtEnabled =
+			sme_start_bss_req->obssProtEnabled;
+
+		mlm_start_req->bssType = session->bssType;
+
+		/* Fill PE session Id from the session Table */
+		mlm_start_req->sessionId = session->peSessionId;
+
+		if (mlm_start_req->bssType == eSIR_INFRA_AP_MODE ||
+		    mlm_start_req->bssType == eSIR_NDI_MODE) {
+			/*
+			 * Copy the BSSId from sessionTable to
+			 * mlmStartReq struct
+			 */
+			sir_copy_mac_addr(mlm_start_req->bssId, session->bssId);
+		} else {
+			/* ibss mode */
+			mac_ctx->lim.gLimIbssCoalescingHappened = false;
+
+			ret_status = wlan_cfg_get_int(mac_ctx,
+					WNI_CFG_IBSS_AUTO_BSSID,
+					&auto_gen_bssid);
+			if (ret_status != QDF_STATUS_SUCCESS) {
+				pe_err("Get Auto Gen BSSID fail,Status: %d",
+					ret_status);
+				ret_code = eSIR_LOGE_EXCEPTION;
+				goto free;
+			}
+
+			if (!auto_gen_bssid) {
+				/*
+				 * We're not auto generating BSSID.
+				 * Instead, get it from session entry
+				 */
+				sir_copy_mac_addr(mlm_start_req->bssId,
+						  session->bssId);
+				/*
+				 * Start IBSS group BSSID
+				 * Auto Generating BSSID.
+				 */
+				auto_gen_bssid = ((mlm_start_req->bssId[0] &
+							0x01) ? true : false);
+			}
+
+			if (auto_gen_bssid) {
+				/*
+				 * if BSSID is not any uc id.
+				 * then use locally generated BSSID.
+				 * Autogenerate the BSSID
+				 */
+				lim_get_random_bssid(mac_ctx,
+						mlm_start_req->bssId);
+				mlm_start_req->bssId[0] = 0x02;
+
+				/*
+				 * Copy randomly generated BSSID
+				 * to the session Table
+				 */
+				sir_copy_mac_addr(session->bssId,
+						  mlm_start_req->bssId);
+			}
+		}
+		/* store the channel num in mlmstart req structure */
+		mlm_start_req->channelNumber = session->currentOperChannel;
+		mlm_start_req->cbMode = sme_start_bss_req->cbMode;
+		mlm_start_req->beaconPeriod =
+			session->beaconParams.beaconInterval;
+		mlm_start_req->cac_duration_ms =
+			sme_start_bss_req->cac_duration_ms;
+		mlm_start_req->dfs_regdomain =
+			sme_start_bss_req->dfs_regdomain;
+		if (LIM_IS_AP_ROLE(session)) {
+			mlm_start_req->dtimPeriod = session->dtimPeriod;
+			mlm_start_req->wps_state = session->wps_state;
+
+		} else {
+			val = mac_ctx->mlme_cfg->sap_cfg.dtim_interval;
+			mlm_start_req->dtimPeriod = (uint8_t) val;
+		}
+
+		mlm_start_req->cfParamSet.cfpPeriod =
+			mac_ctx->mlme_cfg->rates.cfp_period;
+		mlm_start_req->cfParamSet.cfpMaxDuration =
+			mac_ctx->mlme_cfg->rates.cfp_max_duration;
+
+		/*
+		 * this may not be needed anymore now,
+		 * as rateSet is now included in the
+		 * session entry and MLM has session context.
+		 */
+		qdf_mem_copy((void *)&mlm_start_req->rateSet,
+			     (void *)&session->rateSet,
+			     sizeof(tSirMacRateSet));
+
+		/* Now populate the 11n related parameters */
+		mlm_start_req->nwType = session->nwType;
+		mlm_start_req->htCapable = session->htCapability;
+
+		mlm_start_req->htOperMode = mac_ctx->lim.gHTOperMode;
+		/* Unused */
+		mlm_start_req->dualCTSProtection =
+			mac_ctx->lim.gHTDualCTSProtection;
+		mlm_start_req->txChannelWidthSet =
+			session->htRecommendedTxWidthSet;
+
+		session->limRFBand = lim_get_rf_band(channel_number);
+
+		/* Initialize 11h Enable Flag */
+		session->lim11hEnable = 0;
+		if (mlm_start_req->bssType != eSIR_IBSS_MODE &&
+		    (CHAN_HOP_ALL_BANDS_ENABLE ||
+		     BAND_5G == session->limRFBand)) {
+			if (wlan_cfg_get_int(mac_ctx,
+				WNI_CFG_11H_ENABLED, &val) != QDF_STATUS_SUCCESS)
+				pe_err("Fail to get WNI_CFG_11H_ENABLED");
+			else
+				session->lim11hEnable = val;
+
+			if (session->lim11hEnable &&
+				(eSIR_INFRA_AP_MODE ==
+					mlm_start_req->bssType)) {
+				session->lim11hEnable =
+					mac_ctx->mlme_cfg->
+					dfs_cfg.dfs_master_capable;
+			}
+		}
+
+		if (!session->lim11hEnable) {
+			if (cfg_set_int(mac_ctx,
+				WNI_CFG_LOCAL_POWER_CONSTRAINT, 0) !=
+				QDF_STATUS_SUCCESS)
+				/*
+				 * Failed to set the CFG param
+				 * WNI_CFG_LOCAL_POWER_CONSTRAINT
+				 */
+				pe_err("Set LOCAL_POWER_CONSTRAINT failed");
+		}
+
+		mlm_start_req->beacon_tx_rate = session->beacon_tx_rate;
+
+		session->limPrevSmeState = session->limSmeState;
+		session->limSmeState = eLIM_SME_WT_START_BSS_STATE;
+		MTRACE(mac_trace
+			(mac_ctx, TRACE_CODE_SME_STATE,
+			session->peSessionId,
+			session->limSmeState));
+
+		qdf_status = lim_send_start_vdev_req(session, mlm_start_req);
+		if (QDF_IS_STATUS_ERROR(qdf_status))
+			goto free;
+		qdf_mem_free(mlm_start_req);
+		return;
+	} else {
+
+		pe_err("Received unexpected START_BSS_REQ, in state %X",
+			mac_ctx->lim.gLimSmeState);
+		ret_code = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+		goto free;
+	} /* if (mac_ctx->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) */
+
+free:
+	if ((session != NULL) &&
+	    (session->pLimStartBssReq == sme_start_bss_req)) {
+		session->pLimStartBssReq = NULL;
+	}
+	if (NULL != sme_start_bss_req)
+		qdf_mem_free(sme_start_bss_req);
+	if (NULL != mlm_start_req)
+		qdf_mem_free(mlm_start_req);
+	if (NULL != session) {
+		pe_delete_session(mac_ctx, session);
+		session = NULL;
+	}
+	lim_send_sme_start_bss_rsp(mac_ctx, eWNI_SME_START_BSS_RSP, ret_code,
+		session, sme_session_id, sme_transaction_id);
+}
+
+/**
+ * __lim_process_sme_start_bss_req() - Call handler to start BSS
+ *
+ * @pMac: Global MAC context
+ * @pMsg: Message pointer
+ *
+ * Wrapper for the function __lim_handle_sme_start_bss_request
+ * This message will be defered until softmac come out of
+ * scan mode or if we have detected radar on the current
+ * operating channel.
+ *
+ * return true - If we consumed the buffer
+ *        false - If have defered the message.
+ */
+static bool __lim_process_sme_start_bss_req(tpAniSirGlobal pMac,
+					    struct scheduler_msg *pMsg)
+{
+	if (__lim_is_defered_msg_for_learn(pMac, pMsg) ||
+	    __lim_is_defered_msg_for_radar(pMac, pMsg)) {
+		/**
+		 * If message defered, buffer is not consumed yet.
+		 * So return false
+		 */
+		return false;
+	}
+
+	__lim_handle_sme_start_bss_request(pMac, (uint32_t *) pMsg->bodyptr);
+	return true;
+}
+
+/**
+ *  lim_get_random_bssid()
+ *
+ *  FUNCTION:This function is called to process generate the random number for bssid
+ *  This function is called to process SME_SCAN_REQ message
+ *  from HDD or upper layer application.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ * 1. geneartes the unique random number for bssid in ibss
+ *
+ *  @param  pMac      Pointer to Global MAC structure
+ *  @param  *data      Pointer to  bssid  buffer
+ *  @return None
+ */
+void lim_get_random_bssid(tpAniSirGlobal pMac, uint8_t *data)
+{
+	uint32_t random[2];
+
+	random[0] = tx_time_get();
+	random[0] |= (random[0] << 15);
+	random[1] = random[0] >> 1;
+	qdf_mem_copy(data, (uint8_t *) random, sizeof(tSirMacAddr));
+}
+
+/**
+ * __lim_process_clear_dfs_channel_list()
+ *
+ ***FUNCTION:
+ ***Clear DFS channel list  when country is changed/acquired.
+   .*This message is sent from SME.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac      Pointer to Global MAC structure
+ * @param  *pMsgBuf  A pointer to the SME message buffer
+ * @return None
+ */
+static void __lim_process_clear_dfs_channel_list(tpAniSirGlobal pMac,
+						 struct scheduler_msg *pMsg)
+{
+	qdf_mem_set(&pMac->lim.dfschannelList, sizeof(tSirDFSChannelList), 0);
+}
+
+#ifdef WLAN_FEATURE_SAE
+
+/**
+ * lim_update_sae_config()- This API update SAE session info to csr config
+ * from join request.
+ * @session: PE session
+ * @sme_join_req: pointer to join request
+ *
+ * Return: None
+ */
+static void lim_update_sae_config(tpPESession session,
+		tpSirSmeJoinReq sme_join_req)
+{
+	session->sae_pmk_cached = sme_join_req->sae_pmk_cached;
+
+	pe_debug("pmk_cached %d for BSSID=" MAC_ADDRESS_STR,
+		session->sae_pmk_cached,
+		MAC_ADDR_ARRAY(sme_join_req->bssDescription.bssId));
+}
+#else
+static inline void lim_update_sae_config(tpPESession session,
+		tpSirSmeJoinReq sme_join_req)
+{}
+#endif
+
+/**
+ * lim_send_join_req() - send vdev start request for assoc
+ *@session: pe session
+ *@mlm_join_req: join req
+ *
+ * Return: QDF_STATUS
+ */
+
+#ifdef CONFIG_VDEV_SM
+static QDF_STATUS lim_send_join_req(tpPESession session,
+				    tLimMlmJoinReq *mlm_join_req)
+{
+	QDF_STATUS status;
+
+	status = mlme_set_assoc_type(session->vdev, VDEV_ASSOC);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	return wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					     WLAN_VDEV_SM_EV_START,
+					     sizeof(*mlm_join_req),
+					     mlm_join_req);
+}
+#else
+static QDF_STATUS lim_send_join_req(tpPESession session,
+				    tLimMlmJoinReq *mlm_join_req)
+{
+	lim_process_mlm_join_req(session->mac_ctx, mlm_join_req);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * lim_send_reassoc_req() - send vdev start request for reassoc
+ *@session: pe session
+ *@mlm_join_req: join req
+ *
+ * Return: QDF_STATUS
+ */
+
+#ifdef CONFIG_VDEV_SM
+static QDF_STATUS lim_send_reassoc_req(tpPESession session,
+				       tLimMlmReassocReq *reassoc_req)
+{
+	QDF_STATUS status;
+
+	status = mlme_set_assoc_type(session->vdev, VDEV_REASSOC);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	return wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					     WLAN_VDEV_SM_EV_START,
+					     sizeof(*reassoc_req),
+					     reassoc_req);
+}
+#else
+static QDF_STATUS lim_send_reassoc_req(tpPESession session,
+				       tLimMlmReassocReq *reassoc_req)
+{
+	lim_process_mlm_reassoc_req(session->mac_ctx, reassoc_req);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * lim_send_ft_reassoc_req() - send vdev start request for ft_reassoc
+ *@session: pe session
+ *@mlm_join_req: join req
+ *
+ * Return: QDF_STATUS
+ */
+
+#ifdef CONFIG_VDEV_SM
+static QDF_STATUS lim_send_ft_reassoc_req(tpPESession session,
+					  tLimMlmReassocReq *reassoc_req)
+{
+	QDF_STATUS status;
+
+	status = mlme_set_assoc_type(session->vdev, VDEV_FT_REASSOC);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	return wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					     WLAN_VDEV_SM_EV_START,
+					     sizeof(*reassoc_req),
+					     reassoc_req);
+}
+#else
+static QDF_STATUS lim_send_ft_reassoc_req(tpPESession session,
+					  tLimMlmReassocReq *reassoc_req)
+{
+	lim_process_mlm_ft_reassoc_req(session->mac_ctx, reassoc_req);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * __lim_process_sme_join_req() - process SME_JOIN_REQ message
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: A pointer to the SME message buffer
+ *
+ * This function is called to process SME_JOIN_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+static void
+__lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+	tpSirSmeJoinReq sme_join_req = NULL;
+	tLimMlmJoinReq *mlm_join_req;
+	tSirResultCodes ret_code = eSIR_SME_SUCCESS;
+	uint32_t val = 0;
+	uint16_t n_size;
+	uint8_t session_id;
+	tpPESession session = NULL;
+	uint8_t sme_session_id = 0;
+	uint16_t sme_transaction_id = 0;
+	int8_t local_power_constraint = 0, reg_max = 0;
+	uint16_t ie_len;
+	const uint8_t *vendor_ie;
+	tSirBssDescription *bss_desc;
+	QDF_STATUS status;
+
+	if (!mac_ctx || !msg_buf) {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+			  FL("JOIN REQ with invalid data"));
+		return;
+	}
+
+/* FEATURE_WLAN_DIAG_SUPPORT */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+	/*
+	 * Not sending any session, since it is not created yet.
+	 * The response whould have correct state.
+	 */
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_JOIN_REQ_EVENT, NULL, 0, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	/*
+	 * Expect Join request in idle state.
+	 * Reassociate request is expected in link established state.
+	 */
+
+	/* Global SME and LIM states are not defined yet for BT-AMP Support */
+	if (mac_ctx->lim.gLimSmeState == eLIM_SME_IDLE_STATE) {
+		n_size = __lim_get_sme_join_req_size_for_alloc((uint8_t *)
+				msg_buf);
+
+		sme_join_req = qdf_mem_malloc(n_size);
+		if (!sme_join_req) {
+			ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+			goto end;
+		}
+		(void)qdf_mem_copy((void *)sme_join_req, (void *)msg_buf,
+			n_size);
+
+		if (!lim_is_sme_join_req_valid(mac_ctx, sme_join_req)) {
+			/* Received invalid eWNI_SME_JOIN_REQ */
+			/* Log the event */
+			pe_warn("SessionId:%d JOIN REQ with invalid data",
+				sme_join_req->sessionId);
+			ret_code = eSIR_SME_INVALID_PARAMETERS;
+			goto end;
+		}
+
+		/*
+		 * Update the capability here itself as this is used in
+		 * lim_extract_ap_capability() below. If not updated issues
+		 * like not honoring power constraint on 1st association after
+		 * driver loading might occur.
+		 */
+		lim_update_rrm_capability(mac_ctx, sme_join_req);
+
+		bss_desc = &sme_join_req->bssDescription;
+		/* check for the existence of start BSS session  */
+		session = pe_find_session_by_bssid(mac_ctx, bss_desc->bssId,
+				&session_id);
+
+		if (session != NULL) {
+			pe_err("Session(%d) Already exists for BSSID: "
+				   MAC_ADDRESS_STR " in limSmeState = %X",
+				session_id,
+				MAC_ADDR_ARRAY(bss_desc->bssId),
+				session->limSmeState);
+
+			if (session->limSmeState == eLIM_SME_LINK_EST_STATE &&
+			    session->smeSessionId == sme_join_req->sessionId) {
+				/*
+				 * Received eWNI_SME_JOIN_REQ for same
+				 * BSS as currently associated.
+				 * Log the event and send success
+				 */
+				pe_warn("SessionId: %d", session_id);
+				pe_warn("JOIN_REQ for current joined BSS");
+				/* Send Join success response to host */
+				ret_code = eSIR_SME_ALREADY_JOINED_A_BSS;
+				session = NULL;
+				goto end;
+			} else {
+				pe_err("JOIN_REQ not for current joined BSS");
+				ret_code = eSIR_SME_REFUSED;
+				session = NULL;
+				goto end;
+			}
+		} else {
+			/*
+			 * Session Entry does not exist for given BSSId
+			 * Try to Create a new session
+			 */
+			session = pe_create_session(mac_ctx, bss_desc->bssId,
+					&session_id, mac_ctx->lim.maxStation,
+					eSIR_INFRASTRUCTURE_MODE,
+					sme_join_req->sessionId);
+			if (session == NULL) {
+				pe_err("Session Can not be created");
+				ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+				goto end;
+			} else {
+				pe_debug("SessionId:%d New session created",
+					session_id);
+			}
+
+			/* Update the beacon/probe filter in mac_ctx */
+			lim_set_bcn_probe_filter(mac_ctx, session,
+						 &sme_join_req->ssId,
+						 bss_desc->channelId);
+		}
+		session->max_amsdu_num = sme_join_req->max_amsdu_num;
+		session->enable_session_twt_support =
+			sme_join_req->enable_session_twt_support;
+		/*
+		 * Store Session related parameters
+		 */
+
+		/* store the smejoin req handle in session table */
+		session->pLimJoinReq = sme_join_req;
+
+		/* Store SME transaction Id in session Table */
+		session->transactionId = sme_join_req->transactionId;
+
+		/* Store beaconInterval */
+		session->beaconParams.beaconInterval =
+			bss_desc->beaconInterval;
+
+		qdf_mem_copy(&(session->htConfig), &(sme_join_req->htConfig),
+			sizeof(session->htConfig));
+
+		qdf_mem_copy(&(session->vht_config),
+			&(sme_join_req->vht_config),
+			sizeof(session->vht_config));
+
+		/* Copying of bssId is already done, while creating session */
+		sir_copy_mac_addr(session->selfMacAddr,
+			sme_join_req->selfMacAddr);
+		session->bssType = sme_join_req->bsstype;
+
+		session->statypeForBss = STA_ENTRY_PEER;
+		session->limWmeEnabled = sme_join_req->isWMEenabled;
+		session->limQosEnabled = sme_join_req->isQosEnabled;
+		session->wps_registration = sme_join_req->wps_registration;
+		session->he_with_wep_tkip = sme_join_req->he_with_wep_tkip;
+
+		session->enable_bcast_probe_rsp =
+				sme_join_req->enable_bcast_probe_rsp;
+
+		/* Store vendor specific IE for CISCO AP */
+		ie_len = (bss_desc->length + sizeof(bss_desc->length) -
+			 GET_FIELD_OFFSET(tSirBssDescription, ieFields));
+
+		vendor_ie = wlan_get_vendor_ie_ptr_from_oui(
+				SIR_MAC_CISCO_OUI, SIR_MAC_CISCO_OUI_SIZE,
+				((uint8_t *)&bss_desc->ieFields), ie_len);
+
+		if (NULL != vendor_ie) {
+			pe_debug("Cisco vendor OUI present");
+			session->isCiscoVendorAP = true;
+		} else {
+			session->isCiscoVendorAP = false;
+		}
+
+		/* Copy the dot 11 mode in to the session table */
+
+		session->dot11mode = sme_join_req->dot11mode;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+		session->cc_switch_mode = sme_join_req->cc_switch_mode;
+#endif
+		session->nwType = bss_desc->nwType;
+		session->enableAmpduPs = sme_join_req->enableAmpduPs;
+		session->enableHtSmps = sme_join_req->enableHtSmps;
+		session->htSmpsvalue = sme_join_req->htSmps;
+		session->send_smps_action =
+			sme_join_req->send_smps_action;
+		/*
+		 * By default supported NSS 1x1 is set to true
+		 * and later on updated while determining session
+		 * supported rates which is the intersection of
+		 * self and peer rates
+		 */
+		session->supported_nss_1x1 = true;
+		/*Store Persona */
+		session->pePersona = sme_join_req->staPersona;
+		pe_debug("enable Smps: %d mode: %d send action: %d supported nss 1x1: %d pePersona %d cbMode %d",
+			session->enableHtSmps,
+			session->htSmpsvalue,
+			session->send_smps_action,
+			session->supported_nss_1x1,
+			session->pePersona,
+			sme_join_req->cbMode);
+
+		/*Store Persona */
+		session->pePersona = sme_join_req->staPersona;
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			  FL("PE PERSONA=%d cbMode %u nwType: %d dot11mode: %d force_24ghz_in_ht20 %d"),
+			  session->pePersona, sme_join_req->cbMode,
+			  session->nwType, session->dot11mode,
+			  sme_join_req->force_24ghz_in_ht20);
+
+		/* Copy The channel Id to the session Table */
+		session->currentOperChannel = bss_desc->channelId;
+
+		session->vhtCapability =
+			IS_DOT11_MODE_VHT(session->dot11mode);
+		if (session->vhtCapability) {
+			if (session->pePersona == QDF_STA_MODE) {
+				session->vht_config.su_beam_formee =
+					sme_join_req->vht_config.su_beam_formee;
+			} else {
+				session->vht_config.su_beam_formee = 0;
+			}
+			session->enableVhtpAid =
+				sme_join_req->enableVhtpAid;
+			session->enableVhtGid =
+				sme_join_req->enableVhtGid;
+			pe_debug("vht su bformer [%d]",
+					session->vht_config.su_beam_former);
+		}
+
+		pe_debug("vhtCapability: %d su_beam_formee: %d txbf_csn_value: %d su_tx_bformer %d",
+				session->vhtCapability,
+				session->vht_config.su_beam_formee,
+				session->vht_config.csnof_beamformer_antSup,
+				session->vht_config.su_beam_former);
+		/*Phy mode */
+		session->gLimPhyMode = bss_desc->nwType;
+		handle_ht_capabilityand_ht_info(mac_ctx, session);
+		session->force_24ghz_in_ht20 =
+			sme_join_req->force_24ghz_in_ht20;
+		/* cbMode is already merged value of peer and self -
+		 * done by csr in csr_get_cb_mode_from_ies */
+		session->htSupportedChannelWidthSet =
+			(sme_join_req->cbMode) ? 1 : 0;
+		session->htRecommendedTxWidthSet =
+			session->htSupportedChannelWidthSet;
+		session->htSecondaryChannelOffset = sme_join_req->cbMode;
+
+		if (PHY_DOUBLE_CHANNEL_HIGH_PRIMARY == sme_join_req->cbMode) {
+			session->ch_center_freq_seg0 =
+				session->currentOperChannel - 2;
+			session->ch_width = CH_WIDTH_40MHZ;
+		} else if (PHY_DOUBLE_CHANNEL_LOW_PRIMARY ==
+				sme_join_req->cbMode) {
+			session->ch_center_freq_seg0 =
+				session->currentOperChannel + 2;
+			session->ch_width = CH_WIDTH_40MHZ;
+		} else {
+			session->ch_center_freq_seg0 = 0;
+			session->ch_width = CH_WIDTH_20MHZ;
+		}
+
+		if (IS_DOT11_MODE_HE(session->dot11mode)) {
+			lim_update_session_he_capable(mac_ctx, session);
+			lim_copy_join_req_he_cap(session, sme_join_req);
+		}
+
+
+		/* Record if management frames need to be protected */
+#ifdef WLAN_FEATURE_11W
+		if ((eSIR_ED_AES_128_CMAC ==
+					    sme_join_req->MgmtEncryptionType) ||
+		   (eSIR_ED_AES_GMAC_128 == sme_join_req->MgmtEncryptionType) ||
+		   (eSIR_ED_AES_GMAC_256 == sme_join_req->MgmtEncryptionType))
+			session->limRmfEnabled = 1;
+		else
+			session->limRmfEnabled = 0;
+#endif
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+		session->rssi = bss_desc->rssi;
+#endif
+
+		/* Copy the SSID from smejoinreq to session entry  */
+		session->ssId.length = sme_join_req->ssId.length;
+		qdf_mem_copy(session->ssId.ssId, sme_join_req->ssId.ssId,
+			session->ssId.length);
+
+		/*
+		 * Determin 11r or ESE connection based on input from SME
+		 * which inturn is dependent on the profile the user wants
+		 * to connect to, So input is coming from supplicant
+		 */
+		session->is11Rconnection = sme_join_req->is11Rconnection;
+#ifdef FEATURE_WLAN_ESE
+		session->isESEconnection = sme_join_req->isESEconnection;
+#endif
+		session->isFastTransitionEnabled =
+			sme_join_req->isFastTransitionEnabled;
+
+		session->isFastRoamIniFeatureEnabled =
+			sme_join_req->isFastRoamIniFeatureEnabled;
+		session->txLdpcIniFeatureEnabled =
+			sme_join_req->txLdpcIniFeatureEnabled;
+
+		lim_update_fils_config(session, sme_join_req);
+		lim_update_sae_config(session, sme_join_req);
+		if (session->bssType == eSIR_INFRASTRUCTURE_MODE) {
+			session->limSystemRole = eLIM_STA_ROLE;
+		} else {
+			/*
+			 * Throw an error and return and make
+			 * sure to delete the session.
+			 */
+			pe_err("recvd JOIN_REQ with invalid bss type %d",
+				session->bssType);
+			ret_code = eSIR_SME_INVALID_PARAMETERS;
+			goto end;
+		}
+
+		if (sme_join_req->addIEScan.length)
+			qdf_mem_copy(&session->pLimJoinReq->addIEScan,
+				&sme_join_req->addIEScan, sizeof(tSirAddie));
+
+		if (sme_join_req->addIEAssoc.length)
+			qdf_mem_copy(&session->pLimJoinReq->addIEAssoc,
+				&sme_join_req->addIEAssoc, sizeof(tSirAddie));
+
+		val = sizeof(tLimMlmJoinReq) +
+			session->pLimJoinReq->bssDescription.length + 2;
+		mlm_join_req = qdf_mem_malloc(val);
+		if (!mlm_join_req) {
+			ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+			goto end;
+		}
+
+		/* PE SessionId is stored as a part of JoinReq */
+		mlm_join_req->sessionId = session->peSessionId;
+
+		/* copy operational rate from session */
+		qdf_mem_copy((void *)&session->rateSet,
+			(void *)&sme_join_req->operationalRateSet,
+			sizeof(tSirMacRateSet));
+		qdf_mem_copy((void *)&session->extRateSet,
+			(void *)&sme_join_req->extendedRateSet,
+			sizeof(tSirMacRateSet));
+		/*
+		 * this may not be needed anymore now, as rateSet is now
+		 * included in the session entry and MLM has session context.
+		 */
+		qdf_mem_copy((void *)&mlm_join_req->operationalRateSet,
+			(void *)&session->rateSet,
+			sizeof(tSirMacRateSet));
+
+		session->encryptType = sme_join_req->UCEncryptionType;
+
+		session->supported_nss_1x1 = sme_join_req->supported_nss_1x1;
+		session->vdev_nss = sme_join_req->vdev_nss;
+		session->nss = sme_join_req->nss;
+		session->nss_forced_1x1 = sme_join_req->nss_forced_1x1;
+
+		pe_debug("nss %d, vdev_nss %d, supported_nss_1x1 %d",
+			 session->nss,
+			 session->vdev_nss,
+			 session->supported_nss_1x1);
+
+		mlm_join_req->bssDescription.length =
+			session->pLimJoinReq->bssDescription.length;
+
+		qdf_mem_copy((uint8_t *) &mlm_join_req->bssDescription.bssId,
+			(uint8_t *)
+			&session->pLimJoinReq->bssDescription.bssId,
+			session->pLimJoinReq->bssDescription.length + 2);
+
+		session->limCurrentBssCaps =
+			session->pLimJoinReq->bssDescription.capabilityInfo;
+
+		reg_max = cfg_get_regulatory_max_transmit_power(mac_ctx,
+				session->currentOperChannel);
+		local_power_constraint = reg_max;
+
+		lim_extract_ap_capability(mac_ctx,
+			(uint8_t *)
+			session->pLimJoinReq->bssDescription.ieFields,
+			lim_get_ielen_from_bss_description(
+			&session->pLimJoinReq->bssDescription),
+			&session->limCurrentBssQosCaps,
+			&session->limCurrentBssPropCap,
+			&session->gLimCurrentBssUapsd,
+			&local_power_constraint, session);
+
+		session->maxTxPower = lim_get_max_tx_power(reg_max,
+					local_power_constraint,
+					mac_ctx->roam.configParam.nTxPowerCap);
+		session->def_max_tx_pwr = session->maxTxPower;
+
+		pe_debug("Reg max %d local power con %d max tx pwr %d",
+			reg_max, local_power_constraint, session->maxTxPower);
+
+		if (sme_join_req->powerCap.maxTxPower > session->maxTxPower) {
+			sme_join_req->powerCap.maxTxPower = session->maxTxPower;
+			pe_debug("Update MaxTxPower in join Req to %d",
+				sme_join_req->powerCap.maxTxPower);
+		}
+
+		if (session->gLimCurrentBssUapsd) {
+			session->gUapsdPerAcBitmask =
+				session->pLimJoinReq->uapsdPerAcBitmask;
+			pe_debug("UAPSD flag for all AC - 0x%2x",
+				session->gUapsdPerAcBitmask);
+
+			/* resetting the dynamic uapsd mask  */
+			session->gUapsdPerAcDeliveryEnableMask = 0;
+			session->gUapsdPerAcTriggerEnableMask = 0;
+		}
+
+		session->limRFBand =
+			lim_get_rf_band(session->currentOperChannel);
+
+		/* Initialize 11h Enable Flag */
+		if (BAND_5G == session->limRFBand) {
+			if (wlan_cfg_get_int(mac_ctx, WNI_CFG_11H_ENABLED,
+				&val) != QDF_STATUS_SUCCESS) {
+				pe_err("Fail to get WNI_CFG_11H_ENABLED");
+				session->lim11hEnable =
+					WNI_CFG_11H_ENABLED_STADEF;
+			} else {
+				session->lim11hEnable = val;
+			}
+		} else {
+			session->lim11hEnable = 0;
+		}
+
+		/*
+		 * To care of the scenario when STA transitions from
+		 * IBSS to Infrastructure mode.
+		 */
+		mac_ctx->lim.gLimIbssCoalescingHappened = false;
+
+		session->limPrevSmeState = session->limSmeState;
+		session->limSmeState = eLIM_SME_WT_JOIN_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+				session->peSessionId,
+				session->limSmeState));
+
+		/* Indicate whether spectrum management is enabled */
+		session->spectrumMgtEnabled =
+			sme_join_req->spectrumMgtIndicator;
+
+		/* Enable the spectrum management if this is a DFS channel */
+		if (session->country_info_present &&
+			lim_isconnected_on_dfs_channel(mac_ctx,
+					session->currentOperChannel))
+			session->spectrumMgtEnabled = true;
+
+		session->isOSENConnection = sme_join_req->isOSENConnection;
+
+		/* Issue LIM_MLM_JOIN_REQ to MLM */
+		status = lim_send_join_req(session, mlm_join_req);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			qdf_mem_free(mlm_join_req);
+			ret_code = eSIR_SME_REFUSED;
+			goto end;
+		}
+		return;
+
+	} else {
+		/* Received eWNI_SME_JOIN_REQ un expected state */
+		pe_err("received unexpected SME_JOIN_REQ in state %X",
+			mac_ctx->lim.gLimSmeState);
+		lim_print_sme_state(mac_ctx, LOGE, mac_ctx->lim.gLimSmeState);
+		ret_code = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+		session = NULL;
+		goto end;
+	}
+
+end:
+	lim_get_session_info(mac_ctx, (uint8_t *) msg_buf,
+		&sme_session_id, &sme_transaction_id);
+
+	if (sme_join_req) {
+		qdf_mem_free(sme_join_req);
+		sme_join_req = NULL;
+		if (NULL != session)
+			session->pLimJoinReq = NULL;
+	}
+	if (ret_code != eSIR_SME_SUCCESS) {
+		if (NULL != session) {
+			pe_delete_session(mac_ctx, session);
+			session = NULL;
+		}
+	}
+	pe_debug("Send failure status on sessionid: %d with ret_code: %d",
+		sme_session_id, ret_code);
+	lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP, ret_code,
+		eSIR_MAC_UNSPEC_FAILURE_STATUS, session, sme_session_id,
+		sme_transaction_id);
+}
+
+uint8_t lim_get_max_tx_power(int8_t regMax, int8_t apTxPower,
+			     uint8_t iniTxPower)
+{
+	uint8_t maxTxPower = 0;
+	uint8_t txPower = QDF_MIN(regMax, (apTxPower));
+
+	txPower = QDF_MIN(txPower, iniTxPower);
+	if ((txPower >= MIN_TX_PWR_CAP) && (txPower <= MAX_TX_PWR_CAP))
+		maxTxPower = txPower;
+	else if (txPower < MIN_TX_PWR_CAP)
+		maxTxPower = MIN_TX_PWR_CAP;
+	else
+		maxTxPower = MAX_TX_PWR_CAP;
+
+	return maxTxPower;
+}
+
+/**
+ * __lim_process_sme_reassoc_req() - process reassoc req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process SME_REASSOC_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+
+static void __lim_process_sme_reassoc_req(tpAniSirGlobal mac_ctx,
+		uint32_t *msg_buf)
+{
+	uint16_t caps;
+	uint32_t val;
+	tpSirSmeJoinReq reassoc_req = NULL;
+	tLimMlmReassocReq *mlm_reassoc_req;
+	tSirResultCodes ret_code = eSIR_SME_SUCCESS;
+	tpPESession session_entry = NULL;
+	uint8_t session_id;
+	uint8_t sme_session_id;
+	uint16_t transaction_id;
+	int8_t local_pwr_constraint = 0, reg_max = 0;
+	uint32_t tele_bcn_en = 0;
+	uint16_t size;
+	QDF_STATUS status;
+
+	size = __lim_get_sme_join_req_size_for_alloc((uint8_t *)msg_buf);
+	reassoc_req = qdf_mem_malloc(size);
+	if (!reassoc_req) {
+		ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+		goto end;
+	}
+	(void)qdf_mem_copy((void *)reassoc_req, (void *)msg_buf, size);
+
+	if (!lim_is_sme_join_req_valid(mac_ctx,
+				(tpSirSmeJoinReq)reassoc_req)) {
+		/*
+		 * Received invalid eWNI_SME_REASSOC_REQ
+		 */
+		pe_warn("received SME_REASSOC_REQ with invalid data");
+
+		ret_code = eSIR_SME_INVALID_PARAMETERS;
+		goto end;
+	}
+	lim_get_session_info(mac_ctx, (uint8_t *)msg_buf,
+			     &sme_session_id, &transaction_id);
+
+	session_entry = pe_find_session_by_bssid(mac_ctx,
+			reassoc_req->bssDescription.bssId,
+			&session_id);
+	if (session_entry == NULL) {
+		pe_err("Session does not exist for given bssId");
+		lim_print_mac_addr(mac_ctx, reassoc_req->bssDescription.bssId,
+				LOGE);
+		ret_code = eSIR_SME_INVALID_PARAMETERS;
+		session_entry =
+			pe_find_session_by_sme_session_id(mac_ctx,
+					sme_session_id);
+		if (session_entry != NULL)
+			lim_handle_sme_join_result(mac_ctx,
+					eSIR_SME_INVALID_PARAMETERS,
+					eSIR_MAC_UNSPEC_FAILURE_STATUS,
+					session_entry);
+		goto end;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_REQ_EVENT,
+			session_entry, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+	/* mac_ctx->lim.gpLimReassocReq = reassoc_req;//TO SUPPORT BT-AMP */
+
+	/* Store the reassoc handle in the session Table */
+	session_entry->pLimReAssocReq = reassoc_req;
+
+	session_entry->dot11mode = reassoc_req->dot11mode;
+	session_entry->vhtCapability =
+		IS_DOT11_MODE_VHT(reassoc_req->dot11mode);
+
+	if (session_entry->vhtCapability) {
+		if (session_entry->pePersona == QDF_STA_MODE) {
+			session_entry->vht_config.su_beam_formee =
+				reassoc_req->vht_config.su_beam_formee;
+		} else {
+			reassoc_req->vht_config.su_beam_formee = 0;
+		}
+		session_entry->enableVhtpAid =
+			reassoc_req->enableVhtpAid;
+		session_entry->enableVhtGid =
+			reassoc_req->enableVhtGid;
+		pe_debug("vht su bformer [%d]", session_entry->vht_config.su_beam_former);
+	}
+
+	session_entry->supported_nss_1x1 = reassoc_req->supported_nss_1x1;
+	session_entry->vdev_nss = reassoc_req->vdev_nss;
+	session_entry->nss = reassoc_req->nss;
+	session_entry->nss_forced_1x1 = reassoc_req->nss_forced_1x1;
+
+	pe_debug("vhtCapability: %d su_beam_formee: %d su_tx_bformer %d",
+		session_entry->vhtCapability,
+		session_entry->vht_config.su_beam_formee,
+		session_entry->vht_config.su_beam_former);
+
+	session_entry->enableHtSmps = reassoc_req->enableHtSmps;
+	session_entry->htSmpsvalue = reassoc_req->htSmps;
+	session_entry->send_smps_action =
+		reassoc_req->send_smps_action;
+	pe_debug("enableHtSmps: %d htSmps: %d send action: %d supported nss 1x1: %d",
+		session_entry->enableHtSmps,
+		session_entry->htSmpsvalue,
+		session_entry->send_smps_action,
+		session_entry->supported_nss_1x1);
+	/*
+	 * Reassociate request is expected
+	 * in link established state only.
+	 */
+
+	if (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE) {
+		if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE) {
+			/*
+			 * May be from 11r FT pre-auth. So lets check it
+			 * before we bail out
+			 */
+			pe_debug("Session in reassoc state is %d",
+					session_entry->peSessionId);
+
+			/* Make sure its our preauth bssid */
+			if (qdf_mem_cmp(reassoc_req->bssDescription.bssId,
+					     session_entry->limReAssocbssId,
+					     6)) {
+				lim_print_mac_addr(mac_ctx,
+						   reassoc_req->bssDescription.
+						   bssId, LOGE);
+				pe_err("Unknown bssId in reassoc state");
+				ret_code = eSIR_SME_INVALID_PARAMETERS;
+				goto end;
+			}
+
+			session_entry->smeSessionId = sme_session_id;
+			session_entry->transactionId = transaction_id;
+			mlm_reassoc_req =
+				qdf_mem_malloc(sizeof(*mlm_reassoc_req));
+			if (!mlm_reassoc_req) {
+				ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+				goto end;
+			}
+
+			/* Update PE sessionId */
+			mlm_reassoc_req->sessionId = session_entry->peSessionId;
+			status = lim_send_ft_reassoc_req(session_entry,
+							 mlm_reassoc_req);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				qdf_mem_free(mlm_reassoc_req);
+				ret_code = eSIR_SME_REFUSED;
+				goto end;
+			}
+			return;
+		}
+		/*
+		 * Should not have received eWNI_SME_REASSOC_REQ
+		 */
+		pe_err("received unexpected SME_REASSOC_REQ in state %X",
+			session_entry->limSmeState);
+		lim_print_sme_state(mac_ctx, LOGE, session_entry->limSmeState);
+
+		ret_code = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+		goto end;
+	}
+
+	qdf_mem_copy(session_entry->limReAssocbssId,
+		     session_entry->pLimReAssocReq->bssDescription.bssId,
+		     sizeof(tSirMacAddr));
+
+	session_entry->limReassocChannelId =
+		session_entry->pLimReAssocReq->bssDescription.channelId;
+
+	session_entry->reAssocHtSupportedChannelWidthSet =
+		(session_entry->pLimReAssocReq->cbMode) ? 1 : 0;
+	session_entry->reAssocHtRecommendedTxWidthSet =
+		session_entry->reAssocHtSupportedChannelWidthSet;
+	session_entry->reAssocHtSecondaryChannelOffset =
+		session_entry->pLimReAssocReq->cbMode;
+
+	session_entry->limReassocBssCaps =
+		session_entry->pLimReAssocReq->bssDescription.capabilityInfo;
+	reg_max = cfg_get_regulatory_max_transmit_power(mac_ctx,
+			session_entry->currentOperChannel);
+	local_pwr_constraint = reg_max;
+
+	lim_extract_ap_capability(mac_ctx,
+		(uint8_t *)session_entry->pLimReAssocReq->bssDescription.ieFields,
+		lim_get_ielen_from_bss_description(
+			&session_entry->pLimReAssocReq->bssDescription),
+		&session_entry->limReassocBssQosCaps,
+		&session_entry->limReassocBssPropCap,
+		&session_entry->gLimCurrentBssUapsd,
+		&local_pwr_constraint, session_entry);
+	session_entry->maxTxPower = QDF_MIN(reg_max, (local_pwr_constraint));
+	pe_err("Reg max = %d, local pwr constraint = %d, max tx = %d",
+		reg_max, local_pwr_constraint, session_entry->maxTxPower);
+	/* Copy the SSID from session entry to local variable */
+	session_entry->limReassocSSID.length = reassoc_req->ssId.length;
+	qdf_mem_copy(session_entry->limReassocSSID.ssId,
+		     reassoc_req->ssId.ssId,
+		     session_entry->limReassocSSID.length);
+	if (session_entry->gLimCurrentBssUapsd) {
+		session_entry->gUapsdPerAcBitmask =
+			session_entry->pLimReAssocReq->uapsdPerAcBitmask;
+		pe_debug("UAPSD flag for all AC - 0x%2x",
+			session_entry->gUapsdPerAcBitmask);
+	}
+
+	mlm_reassoc_req = qdf_mem_malloc(sizeof(tLimMlmReassocReq));
+	if (!mlm_reassoc_req) {
+		ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+		goto end;
+	}
+
+	qdf_mem_copy(mlm_reassoc_req->peerMacAddr,
+		     session_entry->limReAssocbssId, sizeof(tSirMacAddr));
+
+	if (cfg_get_capability_info(mac_ctx, &caps, session_entry) !=
+			QDF_STATUS_SUCCESS)
+		pe_err("could not retrieve Capabilities value");
+
+	lim_update_caps_info_for_bss(mac_ctx, &caps,
+				reassoc_req->bssDescription.capabilityInfo);
+	pe_debug("Capabilities info Reassoc: 0x%X", caps);
+
+	mlm_reassoc_req->capabilityInfo = caps;
+
+	/* Update PE session_id */
+	mlm_reassoc_req->sessionId = session_id;
+
+	/*
+	 * If telescopic beaconing is enabled, set listen interval to
+	 * CFG_TELE_BCN_MAX_LI
+	 */
+
+	tele_bcn_en = mac_ctx->mlme_cfg->sap_cfg.tele_bcn_wakeup_en;
+
+	if (tele_bcn_en)
+		val = mac_ctx->mlme_cfg->sap_cfg.tele_bcn_max_li;
+	else
+		val = mac_ctx->mlme_cfg->sap_cfg.listen_interval;
+
+	mlm_reassoc_req->listenInterval = (uint16_t) val;
+
+	/* Indicate whether spectrum management is enabled */
+	session_entry->spectrumMgtEnabled = reassoc_req->spectrumMgtIndicator;
+
+	/* Enable the spectrum management if this is a DFS channel */
+	if (session_entry->country_info_present &&
+			lim_isconnected_on_dfs_channel(mac_ctx,
+				session_entry->currentOperChannel))
+		session_entry->spectrumMgtEnabled = true;
+
+	session_entry->limPrevSmeState = session_entry->limSmeState;
+	session_entry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+				session_entry->peSessionId,
+				session_entry->limSmeState));
+
+	status = lim_send_reassoc_req(session_entry, mlm_reassoc_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		qdf_mem_free(mlm_reassoc_req);
+		ret_code = eSIR_SME_REFUSED;
+		goto end;
+	}
+
+	return;
+end:
+	if (reassoc_req) {
+		qdf_mem_free(reassoc_req);
+		if (session_entry)
+			session_entry->pLimReAssocReq = NULL;
+	}
+
+	if (session_entry) {
+		/*
+		 * error occurred after we determined the session so extract
+		 * session and transaction info from there
+		 */
+		sme_session_id = session_entry->smeSessionId;
+		transaction_id = session_entry->transactionId;
+	} else {
+		/*
+		 * error occurred before or during the time we determined
+		 * the session so extract the session and transaction info
+		 * from the message
+		 */
+		lim_get_session_info(mac_ctx, (uint8_t *) msg_buf,
+				&sme_session_id, &transaction_id);
+	}
+	/*
+	 * Send Reassoc failure response to host
+	 * (note session_entry may be NULL, but that's OK)
+	 */
+	lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_REASSOC_RSP,
+				      ret_code, eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				      session_entry, sme_session_id,
+				      transaction_id);
+}
+
+bool send_disassoc_frame = 1;
+/**
+ * __lim_process_sme_disassoc_req()
+ *
+ ***FUNCTION:
+ * This function is called to process SME_DISASSOC_REQ message
+ * from HDD or upper layer application.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac      Pointer to Global MAC structure
+ * @param  *pMsgBuf  A pointer to the SME message buffer
+ * @return None
+ */
+
+static void __lim_process_sme_disassoc_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	uint16_t disassocTrigger, reasonCode;
+	tLimMlmDisassocReq *pMlmDisassocReq;
+	tSirResultCodes retCode = eSIR_SME_SUCCESS;
+	tSirSmeDisassocReq smeDisassocReq;
+	tpPESession psessionEntry = NULL;
+	uint8_t sessionId;
+	uint8_t smesessionId;
+	uint16_t smetransactionId;
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	qdf_mem_copy(&smeDisassocReq, pMsgBuf, sizeof(tSirSmeDisassocReq));
+	smesessionId = smeDisassocReq.sessionId;
+	smetransactionId = smeDisassocReq.transactionId;
+	if (!lim_is_sme_disassoc_req_valid(pMac,
+					   &smeDisassocReq,
+					   psessionEntry)) {
+		pe_err("received invalid SME_DISASSOC_REQ message");
+		if (pMac->lim.gLimRspReqd) {
+			pMac->lim.gLimRspReqd = false;
+
+			retCode = eSIR_SME_INVALID_PARAMETERS;
+			disassocTrigger = eLIM_HOST_DISASSOC;
+			goto sendDisassoc;
+		}
+
+		return;
+	}
+
+	psessionEntry = pe_find_session_by_bssid(pMac,
+				smeDisassocReq.bssid.bytes,
+				&sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("session does not exist for given bssId "
+			   MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(smeDisassocReq.bssid.bytes));
+		retCode = eSIR_SME_INVALID_PARAMETERS;
+		disassocTrigger = eLIM_HOST_DISASSOC;
+		goto sendDisassoc;
+	}
+	pe_debug("received DISASSOC_REQ message on sessionid %d Systemrole %d Reason: %u SmeState: %d from: "
+			MAC_ADDRESS_STR, smesessionId,
+		GET_LIM_SYSTEM_ROLE(psessionEntry), smeDisassocReq.reasonCode,
+		pMac->lim.gLimSmeState,
+		MAC_ADDR_ARRAY(smeDisassocReq.peer_macaddr.bytes));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_REQ_EVENT, psessionEntry,
+			      0, smeDisassocReq.reasonCode);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	/* Update SME session Id and SME transaction ID */
+
+	psessionEntry->smeSessionId = smesessionId;
+	psessionEntry->transactionId = smetransactionId;
+	pe_debug("ho_fail: %d ", smeDisassocReq.process_ho_fail);
+	psessionEntry->process_ho_fail = smeDisassocReq.process_ho_fail;
+
+	switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+	case eLIM_STA_ROLE:
+		switch (psessionEntry->limSmeState) {
+		case eLIM_SME_ASSOCIATED_STATE:
+		case eLIM_SME_LINK_EST_STATE:
+			pe_debug("Rcvd SME_DISASSOC_REQ in limSmeState: %d ",
+				psessionEntry->limSmeState);
+			psessionEntry->limPrevSmeState =
+				psessionEntry->limSmeState;
+			psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE;
+			/* Delete all TDLS peers connected before leaving BSS */
+			lim_delete_tdls_peers(pMac, psessionEntry);
+			MTRACE(mac_trace(pMac, TRACE_CODE_SME_STATE,
+				psessionEntry->peSessionId,
+				psessionEntry->limSmeState));
+			break;
+
+		case eLIM_SME_WT_DEAUTH_STATE:
+			/* PE shall still process the DISASSOC_REQ and proceed with
+			 * link tear down even if it had already sent a DEAUTH_IND to
+			 * to SME. pMac->lim.gLimPrevSmeState shall remain the same as
+			 * its been set when PE entered WT_DEAUTH_STATE.
+			 */
+			psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE;
+			MTRACE(mac_trace
+				       (pMac, TRACE_CODE_SME_STATE,
+				       psessionEntry->peSessionId,
+				       psessionEntry->limSmeState));
+			pe_debug("Rcvd SME_DISASSOC_REQ while in SME_WT_DEAUTH_STATE");
+			break;
+
+		case eLIM_SME_WT_DISASSOC_STATE:
+			/* PE Received a Disassoc frame. Normally it gets DISASSOC_CNF but it
+			 * received DISASSOC_REQ. Which means host is also trying to disconnect.
+			 * PE can continue processing DISASSOC_REQ and send the response instead
+			 * of failing the request. SME will anyway ignore DEAUTH_IND that was sent
+			 * for disassoc frame.
+			 *
+			 * It will send a disassoc, which is ok. However, we can use the global flag
+			 * sendDisassoc to not send disassoc frame.
+			 */
+			pe_debug("Rcvd SME_DISASSOC_REQ while in SME_WT_DISASSOC_STATE");
+			break;
+
+		case eLIM_SME_JOIN_FAILURE_STATE: {
+			/* Already in Disconnected State, return success */
+			pe_debug("Rcvd SME_DISASSOC_REQ while in eLIM_SME_JOIN_FAILURE_STATE");
+			if (pMac->lim.gLimRspReqd) {
+				retCode = eSIR_SME_SUCCESS;
+				disassocTrigger = eLIM_HOST_DISASSOC;
+				goto sendDisassoc;
+			}
+		}
+		break;
+		default:
+			/**
+			 * STA is not currently associated.
+			 * Log error and send response to host
+			 */
+			pe_err("received unexpected SME_DISASSOC_REQ in state %X",
+				psessionEntry->limSmeState);
+			lim_print_sme_state(pMac, LOGE,
+				psessionEntry->limSmeState);
+
+			if (pMac->lim.gLimRspReqd) {
+				if (psessionEntry->limSmeState !=
+				    eLIM_SME_WT_ASSOC_STATE)
+					pMac->lim.gLimRspReqd = false;
+
+				retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+				disassocTrigger = eLIM_HOST_DISASSOC;
+				goto sendDisassoc;
+			}
+
+			return;
+		}
+
+		break;
+
+	case eLIM_AP_ROLE:
+		/* Fall through */
+		break;
+
+	case eLIM_STA_IN_IBSS_ROLE:
+	default:
+		/* eLIM_UNKNOWN_ROLE */
+		pe_err("received unexpected SME_DISASSOC_REQ for role %d",
+			GET_LIM_SYSTEM_ROLE(psessionEntry));
+
+		retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+		disassocTrigger = eLIM_HOST_DISASSOC;
+		goto sendDisassoc;
+	} /* end switch (pMac->lim.gLimSystemRole) */
+
+	disassocTrigger = eLIM_HOST_DISASSOC;
+	reasonCode = smeDisassocReq.reasonCode;
+
+	if (smeDisassocReq.doNotSendOverTheAir) {
+		pe_debug("do not send dissoc over the air");
+		send_disassoc_frame = 0;
+	}
+	/* Trigger Disassociation frame to peer MAC entity */
+	pe_debug("Sending Disasscoc with disassoc Trigger"
+				" : %d, reasonCode : %d",
+			disassocTrigger, reasonCode);
+
+	pMlmDisassocReq = qdf_mem_malloc(sizeof(tLimMlmDisassocReq));
+	if (!pMlmDisassocReq)
+		return;
+
+	qdf_copy_macaddr(&pMlmDisassocReq->peer_macaddr,
+			 &smeDisassocReq.peer_macaddr);
+
+	pMlmDisassocReq->reasonCode = reasonCode;
+	pMlmDisassocReq->disassocTrigger = disassocTrigger;
+
+	/* Update PE session ID */
+	pMlmDisassocReq->sessionId = sessionId;
+
+	lim_post_mlm_message(pMac,
+			     LIM_MLM_DISASSOC_REQ, (uint32_t *) pMlmDisassocReq);
+	return;
+
+sendDisassoc:
+	if (psessionEntry)
+		lim_send_sme_disassoc_ntf(pMac,
+					  smeDisassocReq.peer_macaddr.bytes,
+					  retCode,
+					  disassocTrigger,
+					  1, smesessionId, smetransactionId,
+					  psessionEntry);
+	else
+		lim_send_sme_disassoc_ntf(pMac,
+					  smeDisassocReq.peer_macaddr.bytes,
+					  retCode, disassocTrigger, 1,
+					  smesessionId, smetransactionId, NULL);
+
+} /*** end __lim_process_sme_disassoc_req() ***/
+
+/** -----------------------------------------------------------------
+   \brief __lim_process_sme_disassoc_cnf() - Process SME_DISASSOC_CNF
+
+   This function is called to process SME_DISASSOC_CNF message
+   from HDD or upper layer application.
+
+   \param pMac - global mac structure
+   \param pStaDs - station dph hash node
+   \return none
+   \sa
+   ----------------------------------------------------------------- */
+void __lim_process_sme_disassoc_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	tSirSmeDisassocCnf smeDisassocCnf;
+	uint16_t aid;
+	tpDphHashNode pStaDs;
+	tpPESession psessionEntry;
+	uint8_t sessionId;
+	uint32_t *msg = NULL;
+	QDF_STATUS status;
+
+	qdf_mem_copy(&smeDisassocCnf, pMsgBuf,
+			sizeof(struct sSirSmeDisassocCnf));
+
+	psessionEntry = pe_find_session_by_bssid(pMac,
+				smeDisassocCnf.bssid.bytes,
+				&sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("session does not exist for given bssId");
+		status = lim_prepare_disconnect_done_ind(pMac, &msg,
+						smeDisassocCnf.sme_session_id,
+						eSIR_SME_INVALID_SESSION,
+						NULL);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			lim_send_sme_disassoc_deauth_ntf(pMac,
+							 QDF_STATUS_SUCCESS,
+							 (uint32_t *)msg);
+		return;
+	}
+
+	if (!lim_is_sme_disassoc_cnf_valid(pMac, &smeDisassocCnf, psessionEntry)) {
+		pe_err("received invalid SME_DISASSOC_CNF message");
+		status = lim_prepare_disconnect_done_ind(pMac, &msg,
+						psessionEntry->smeSessionId,
+						eSIR_SME_INVALID_PARAMETERS,
+						&smeDisassocCnf.bssid.bytes[0]);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			lim_send_sme_disassoc_deauth_ntf(pMac,
+							 QDF_STATUS_SUCCESS,
+							 (uint32_t *)msg);
+		return;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	if (smeDisassocCnf.messageType == eWNI_SME_DISASSOC_CNF)
+		lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_CNF_EVENT,
+				      psessionEntry,
+				      (uint16_t) smeDisassocCnf.statusCode, 0);
+	else if (smeDisassocCnf.messageType == eWNI_SME_DEAUTH_CNF)
+		lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_CNF_EVENT,
+				      psessionEntry,
+				      (uint16_t) smeDisassocCnf.statusCode, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+	case eLIM_STA_ROLE:
+		if ((psessionEntry->limSmeState != eLIM_SME_IDLE_STATE) &&
+		    (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)
+		    && (psessionEntry->limSmeState !=
+			eLIM_SME_WT_DEAUTH_STATE)) {
+			pe_err("received unexp SME_DISASSOC_CNF in state %X",
+				psessionEntry->limSmeState);
+			lim_print_sme_state(pMac, LOGE,
+					    psessionEntry->limSmeState);
+			status = lim_prepare_disconnect_done_ind(pMac, &msg,
+						psessionEntry->smeSessionId,
+						eSIR_SME_INVALID_STATE,
+						&smeDisassocCnf.bssid.bytes[0]);
+			if (QDF_IS_STATUS_SUCCESS(status))
+				lim_send_sme_disassoc_deauth_ntf(pMac,
+							QDF_STATUS_SUCCESS,
+							(uint32_t *)msg);
+			return;
+		}
+		break;
+
+	case eLIM_AP_ROLE:
+		/* Fall through */
+		break;
+
+	case eLIM_STA_IN_IBSS_ROLE:
+	default:                /* eLIM_UNKNOWN_ROLE */
+		pe_err("received unexpected SME_DISASSOC_CNF role %d",
+			GET_LIM_SYSTEM_ROLE(psessionEntry));
+		status = lim_prepare_disconnect_done_ind(pMac, &msg,
+						psessionEntry->smeSessionId,
+						eSIR_SME_INVALID_STATE,
+						&smeDisassocCnf.bssid.bytes[0]);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			lim_send_sme_disassoc_deauth_ntf(pMac,
+							 QDF_STATUS_SUCCESS,
+							 (uint32_t *)msg);
+		return;
+	}
+
+	if ((psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE) ||
+	    (psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE) ||
+	    LIM_IS_AP_ROLE(psessionEntry)) {
+		pStaDs = dph_lookup_hash_entry(pMac,
+				smeDisassocCnf.peer_macaddr.bytes, &aid,
+				&psessionEntry->dph.dphHashTable);
+		if (pStaDs == NULL) {
+			pe_err("DISASSOC_CNF for a STA with no context, addr= "
+				MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(smeDisassocCnf.peer_macaddr.bytes));
+			status = lim_prepare_disconnect_done_ind(pMac, &msg,
+						psessionEntry->smeSessionId,
+						eSIR_SME_INVALID_PARAMETERS,
+						&smeDisassocCnf.bssid.bytes[0]);
+			if (QDF_IS_STATUS_SUCCESS(status))
+				lim_send_sme_disassoc_deauth_ntf(pMac,
+							QDF_STATUS_SUCCESS,
+							(uint32_t *)msg);
+			return;
+		}
+
+		if ((pStaDs->mlmStaContext.mlmState ==
+				eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
+			(pStaDs->mlmStaContext.mlmState ==
+				eLIM_MLM_WT_DEL_BSS_RSP_STATE)) {
+			pe_err("No need of cleanup for addr:" MAC_ADDRESS_STR "as MLM state is %d",
+				MAC_ADDR_ARRAY(smeDisassocCnf.peer_macaddr.bytes),
+				pStaDs->mlmStaContext.mlmState);
+			status = lim_prepare_disconnect_done_ind(pMac, &msg,
+						psessionEntry->smeSessionId,
+						eSIR_SME_SUCCESS,
+						NULL);
+			if (QDF_IS_STATUS_SUCCESS(status))
+				lim_send_sme_disassoc_deauth_ntf(pMac,
+							QDF_STATUS_SUCCESS,
+							(uint32_t *)msg);
+			return;
+		}
+
+		/* Delete FT session if there exists one */
+		lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
+		lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
+
+		lim_clean_up_disassoc_deauth_req(pMac,
+				 (char *)&smeDisassocCnf.peer_macaddr, 0);
+	}
+
+	return;
+}
+
+/**
+ * __lim_process_sme_deauth_req() - process sme deauth req
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process SME_DEAUTH_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+
+static void __lim_process_sme_deauth_req(tpAniSirGlobal mac_ctx,
+		uint32_t *msg_buf)
+{
+	uint16_t deauth_trigger, reason_code;
+	tLimMlmDeauthReq *mlm_deauth_req;
+	tSirSmeDeauthReq sme_deauth_req;
+	tSirResultCodes ret_code = eSIR_SME_SUCCESS;
+	tpPESession session_entry;
+	uint8_t session_id;      /* PE sessionId */
+	uint8_t sme_session_id;
+	uint16_t sme_transaction_id;
+
+	qdf_mem_copy(&sme_deauth_req, msg_buf, sizeof(tSirSmeDeauthReq));
+	sme_session_id = sme_deauth_req.sessionId;
+	sme_transaction_id = sme_deauth_req.transactionId;
+
+	/*
+	 * We need to get a session first but we don't even know
+	 * if the message is correct.
+	 */
+	session_entry = pe_find_session_by_bssid(mac_ctx,
+					sme_deauth_req.bssid.bytes,
+					&session_id);
+	if (session_entry == NULL) {
+		pe_err("session does not exist for given bssId");
+		ret_code = eSIR_SME_INVALID_PARAMETERS;
+		deauth_trigger = eLIM_HOST_DEAUTH;
+		goto send_deauth;
+	}
+
+	if (!lim_is_sme_deauth_req_valid(mac_ctx, &sme_deauth_req,
+				session_entry)) {
+		pe_err("received invalid SME_DEAUTH_REQ message");
+		mac_ctx->lim.gLimRspReqd = false;
+
+		ret_code = eSIR_SME_INVALID_PARAMETERS;
+		deauth_trigger = eLIM_HOST_DEAUTH;
+		goto send_deauth;
+	}
+	pe_debug("received DEAUTH_REQ sessionid %d Systemrole %d reasoncode %u limSmestate %d from "
+		MAC_ADDRESS_STR, sme_session_id,
+		GET_LIM_SYSTEM_ROLE(session_entry), sme_deauth_req.reasonCode,
+		session_entry->limSmeState,
+		MAC_ADDR_ARRAY(sme_deauth_req.peer_macaddr.bytes));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_DEAUTH_REQ_EVENT,
+			session_entry, 0, sme_deauth_req.reasonCode);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	/* Update SME session ID and Transaction ID */
+	session_entry->smeSessionId = sme_session_id;
+	session_entry->transactionId = sme_transaction_id;
+
+	switch (GET_LIM_SYSTEM_ROLE(session_entry)) {
+	case eLIM_STA_ROLE:
+		switch (session_entry->limSmeState) {
+		case eLIM_SME_ASSOCIATED_STATE:
+		case eLIM_SME_LINK_EST_STATE:
+			/* Delete all TDLS peers connected before leaving BSS */
+			lim_delete_tdls_peers(mac_ctx, session_entry);
+		/* fallthrough */
+		case eLIM_SME_WT_ASSOC_STATE:
+		case eLIM_SME_JOIN_FAILURE_STATE:
+		case eLIM_SME_IDLE_STATE:
+			session_entry->limPrevSmeState =
+				session_entry->limSmeState;
+			session_entry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
+			MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+				       session_entry->peSessionId,
+				       session_entry->limSmeState));
+			/* Send Deauthentication request to MLM below */
+			break;
+		case eLIM_SME_WT_DEAUTH_STATE:
+		case eLIM_SME_WT_DISASSOC_STATE:
+			/*
+			 * PE Received a Deauth/Disassoc frame. Normally it get
+			 * DEAUTH_CNF/DISASSOC_CNF but it received DEAUTH_REQ.
+			 * Which means host is also trying to disconnect.
+			 * PE can continue processing DEAUTH_REQ and send
+			 * the response instead of failing the request.
+			 * SME will anyway ignore DEAUTH_IND/DISASSOC_IND that
+			 * was sent for deauth/disassoc frame.
+			 */
+			session_entry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
+			pe_debug("Rcvd SME_DEAUTH_REQ while in SME_WT_DEAUTH_STATE");
+			break;
+		default:
+			/*
+			 * STA is not in a state to deauthenticate with
+			 * peer. Log error and send response to host.
+			 */
+			pe_err("received unexp SME_DEAUTH_REQ in state %X",
+				session_entry->limSmeState);
+			lim_print_sme_state(mac_ctx, LOGE,
+					    session_entry->limSmeState);
+
+			if (mac_ctx->lim.gLimRspReqd) {
+				mac_ctx->lim.gLimRspReqd = false;
+
+				ret_code = eSIR_SME_STA_NOT_AUTHENTICATED;
+				deauth_trigger = eLIM_HOST_DEAUTH;
+
+				/*
+				 * here we received deauth request from AP so
+				 * sme state is eLIM_SME_WT_DEAUTH_STATE.if we
+				 * have ISSUED delSta then mlm state should be
+				 * eLIM_MLM_WT_DEL_STA_RSP_STATE and ifwe got
+				 * delBSS rsp then mlm state should be
+				 * eLIM_MLM_IDLE_STATE so the below condition
+				 * captures the state where delSta not done
+				 * and firmware still in connected state.
+				 */
+				if (session_entry->limSmeState ==
+					eLIM_SME_WT_DEAUTH_STATE &&
+					session_entry->limMlmState !=
+					eLIM_MLM_IDLE_STATE &&
+					session_entry->limMlmState !=
+					eLIM_MLM_WT_DEL_STA_RSP_STATE)
+					ret_code = eSIR_SME_DEAUTH_STATUS;
+				goto send_deauth;
+			}
+			return;
+		}
+		break;
+
+	case eLIM_STA_IN_IBSS_ROLE:
+		pe_err("Deauth not allowed in IBSS");
+		if (mac_ctx->lim.gLimRspReqd) {
+			mac_ctx->lim.gLimRspReqd = false;
+			ret_code = eSIR_SME_INVALID_PARAMETERS;
+			deauth_trigger = eLIM_HOST_DEAUTH;
+			goto send_deauth;
+		}
+		return;
+	case eLIM_AP_ROLE:
+		break;
+	default:
+		pe_err("received unexpected SME_DEAUTH_REQ for role %X",
+			GET_LIM_SYSTEM_ROLE(session_entry));
+		if (mac_ctx->lim.gLimRspReqd) {
+			mac_ctx->lim.gLimRspReqd = false;
+			ret_code = eSIR_SME_INVALID_PARAMETERS;
+			deauth_trigger = eLIM_HOST_DEAUTH;
+			goto send_deauth;
+		}
+		return;
+	} /* end switch (mac_ctx->lim.gLimSystemRole) */
+
+	if (sme_deauth_req.reasonCode == eLIM_LINK_MONITORING_DEAUTH &&
+	    session_entry->limSystemRole == eLIM_STA_ROLE) {
+		/* Deauthentication is triggered by Link Monitoring */
+		pe_debug("** Lost link with AP **");
+		deauth_trigger = eLIM_LINK_MONITORING_DEAUTH;
+		reason_code = eSIR_MAC_UNSPEC_FAILURE_REASON;
+	} else {
+		deauth_trigger = eLIM_HOST_DEAUTH;
+		reason_code = sme_deauth_req.reasonCode;
+	}
+
+	/* Trigger Deauthentication frame to peer MAC entity */
+	mlm_deauth_req = qdf_mem_malloc(sizeof(tLimMlmDeauthReq));
+	if (!mlm_deauth_req) {
+		if (mac_ctx->lim.gLimRspReqd) {
+			mac_ctx->lim.gLimRspReqd = false;
+			ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+			deauth_trigger = eLIM_HOST_DEAUTH;
+			goto send_deauth;
+		}
+		return;
+	}
+
+	qdf_copy_macaddr(&mlm_deauth_req->peer_macaddr,
+			 &sme_deauth_req.peer_macaddr);
+
+	mlm_deauth_req->reasonCode = reason_code;
+	mlm_deauth_req->deauthTrigger = deauth_trigger;
+
+	/* Update PE session Id */
+	mlm_deauth_req->sessionId = session_id;
+	lim_process_mlm_deauth_req(mac_ctx, (uint32_t *)mlm_deauth_req);
+
+	return;
+
+send_deauth:
+	lim_send_sme_deauth_ntf(mac_ctx, sme_deauth_req.peer_macaddr.bytes,
+				ret_code, deauth_trigger, 1,
+				sme_session_id, sme_transaction_id);
+}
+
+/**
+ * __lim_process_sme_set_context_req()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process SME_SETCONTEXT_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+
+static void
+__lim_process_sme_set_context_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+	tpSirSmeSetContextReq set_context_req;
+	tLimMlmSetKeysReq *mlm_set_key_req;
+	tpPESession session_entry;
+	uint8_t session_id;      /* PE sessionID */
+	uint8_t sme_session_id;
+	uint16_t sme_transaction_id;
+
+	if (msg_buf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	set_context_req = qdf_mem_malloc(sizeof(struct sSirSmeSetContextReq));
+	if (!set_context_req)
+		return;
+	qdf_mem_copy(set_context_req, msg_buf,
+			sizeof(struct sSirSmeSetContextReq));
+	sme_session_id = set_context_req->sessionId;
+	sme_transaction_id = set_context_req->transactionId;
+
+	if ((!lim_is_sme_set_context_req_valid(mac_ctx, set_context_req))) {
+		pe_warn("received invalid SME_SETCONTEXT_REQ message");
+		goto end;
+	}
+
+	if (set_context_req->keyMaterial.numKeys >
+			SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) {
+		pe_err("numKeys:%d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS",
+					set_context_req->keyMaterial.numKeys);
+		lim_send_sme_set_context_rsp(mac_ctx,
+				set_context_req->peer_macaddr, 1,
+				eSIR_SME_INVALID_PARAMETERS, NULL,
+				sme_session_id, sme_transaction_id);
+		goto end;
+	}
+
+	session_entry = pe_find_session_by_bssid(mac_ctx,
+			set_context_req->bssid.bytes, &session_id);
+	if (session_entry == NULL) {
+		pe_err("Session does not exist for given BSSID");
+		lim_send_sme_set_context_rsp(mac_ctx,
+				set_context_req->peer_macaddr, 1,
+				eSIR_SME_INVALID_PARAMETERS, NULL,
+				sme_session_id, sme_transaction_id);
+		goto end;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT,
+			      session_entry, 0, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	if ((LIM_IS_STA_ROLE(session_entry) &&
+	    (session_entry->limSmeState == eLIM_SME_LINK_EST_STATE)) ||
+	    ((LIM_IS_IBSS_ROLE(session_entry) ||
+	    LIM_IS_AP_ROLE(session_entry)) &&
+	    (session_entry->limSmeState == eLIM_SME_NORMAL_STATE))) {
+		/* Trigger MLM_SETKEYS_REQ */
+		mlm_set_key_req = qdf_mem_malloc(sizeof(tLimMlmSetKeysReq));
+		if (!mlm_set_key_req)
+			goto end;
+		mlm_set_key_req->edType = set_context_req->keyMaterial.edType;
+		mlm_set_key_req->numKeys =
+			set_context_req->keyMaterial.numKeys;
+		if (mlm_set_key_req->numKeys >
+				SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) {
+			pe_err("no.of keys exceeded max num of default keys limit");
+			qdf_mem_free(mlm_set_key_req);
+			goto end;
+		}
+		qdf_copy_macaddr(&mlm_set_key_req->peer_macaddr,
+				 &set_context_req->peer_macaddr);
+
+		qdf_mem_copy((uint8_t *) &mlm_set_key_req->key,
+			     (uint8_t *) &set_context_req->keyMaterial.key,
+			     sizeof(tSirKeys) *
+			     (mlm_set_key_req->numKeys ? mlm_set_key_req->
+			      numKeys : 1));
+
+		mlm_set_key_req->sessionId = session_id;
+		mlm_set_key_req->smesessionId = sme_session_id;
+		pe_debug("received SETCONTEXT_REQ message sessionId=%d",
+					mlm_set_key_req->sessionId);
+
+		if (((set_context_req->keyMaterial.edType == eSIR_ED_WEP40) ||
+		    (set_context_req->keyMaterial.edType == eSIR_ED_WEP104)) &&
+		    LIM_IS_AP_ROLE(session_entry)) {
+			if (set_context_req->keyMaterial.key[0].keyLength) {
+				uint8_t key_id;
+
+				key_id =
+					set_context_req->keyMaterial.key[0].keyId;
+				qdf_mem_copy((uint8_t *)
+					&session_entry->WEPKeyMaterial[key_id],
+					(uint8_t *) &set_context_req->keyMaterial,
+					sizeof(tSirKeyMaterial));
+			} else {
+				uint32_t i;
+
+				for (i = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
+				     i++) {
+					qdf_mem_copy((uint8_t *)
+						&mlm_set_key_req->key[i],
+						(uint8_t *)session_entry->WEPKeyMaterial[i].key,
+						sizeof(tSirKeys));
+				}
+			}
+		}
+		lim_post_mlm_message(mac_ctx, LIM_MLM_SETKEYS_REQ,
+				     (uint32_t *) mlm_set_key_req);
+	} else {
+		pe_err("rcvd unexpected SME_SETCONTEXT_REQ for role %d, state=%X",
+				GET_LIM_SYSTEM_ROLE(session_entry),
+				session_entry->limSmeState);
+		lim_print_sme_state(mac_ctx, LOGE, session_entry->limSmeState);
+
+		lim_send_sme_set_context_rsp(mac_ctx,
+				set_context_req->peer_macaddr, 1,
+				eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,
+				session_entry, sme_session_id,
+				sme_transaction_id);
+	}
+end:
+	qdf_mem_free(set_context_req);
+	return;
+}
+
+/**
+ * lim_process_sme_get_assoc_sta_info() - process sme assoc sta req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process SME_GET_ASSOC_STAS_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+
+static void lim_process_sme_get_assoc_sta_info(tpAniSirGlobal mac_ctx,
+					       uint32_t *msg_buf)
+{
+	tSirSmeGetAssocSTAsReq get_assoc_stas_req;
+	tpDphHashNode sta_ds = NULL;
+	tpPESession session_entry = NULL;
+	tSap_Event sap_event;
+	tpWLAN_SAPEventCB sap_event_cb = NULL;
+	tpSap_AssocMacAddr assoc_sta_tmp = NULL;
+	uint8_t session_id = CSR_SESSION_ID_INVALID;
+	uint8_t assoc_id = 0;
+	uint8_t sta_cnt = 0;
+
+	if (msg_buf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	qdf_mem_copy(&get_assoc_stas_req, msg_buf,
+				sizeof(struct sSirSmeGetAssocSTAsReq));
+	/*
+	 * Get Associated stations from PE.
+	 * Find PE session Entry
+	 */
+	session_entry = pe_find_session_by_bssid(mac_ctx,
+			get_assoc_stas_req.bssid.bytes,
+			&session_id);
+	if (session_entry == NULL) {
+		pe_err("session does not exist for given bssId");
+		goto lim_assoc_sta_end;
+	}
+
+	if (!LIM_IS_AP_ROLE(session_entry)) {
+		pe_err("Received unexpected message in state %X, in role %X",
+			session_entry->limSmeState,
+			GET_LIM_SYSTEM_ROLE(session_entry));
+		goto lim_assoc_sta_end;
+	}
+	/* Retrieve values obtained in the request message */
+	sap_event_cb = (tpWLAN_SAPEventCB)get_assoc_stas_req.pSapEventCallback;
+	assoc_sta_tmp = (tpSap_AssocMacAddr)get_assoc_stas_req.pAssocStasArray;
+
+	if (NULL == assoc_sta_tmp)
+		goto lim_assoc_sta_end;
+	for (assoc_id = 0; assoc_id < session_entry->dph.dphHashTable.size;
+		assoc_id++) {
+		sta_ds = dph_get_hash_entry(mac_ctx, assoc_id,
+				&session_entry->dph.dphHashTable);
+		if (NULL == sta_ds)
+			continue;
+		if (sta_ds->valid) {
+			qdf_mem_copy((uint8_t *) &assoc_sta_tmp->staMac,
+					(uint8_t *) &sta_ds->staAddr,
+					 QDF_MAC_ADDR_SIZE);
+			assoc_sta_tmp->assocId = (uint8_t) sta_ds->assocId;
+			assoc_sta_tmp->staId = (uint8_t) sta_ds->staIndex;
+
+			qdf_mem_copy((uint8_t *)&assoc_sta_tmp->supportedRates,
+				     (uint8_t *)&sta_ds->supportedRates,
+				     sizeof(tSirSupportedRates));
+			assoc_sta_tmp->ShortGI40Mhz = sta_ds->htShortGI40Mhz;
+			assoc_sta_tmp->ShortGI20Mhz = sta_ds->htShortGI20Mhz;
+			assoc_sta_tmp->Support40Mhz =
+				sta_ds->htDsssCckRate40MHzSupport;
+
+			pe_debug("dph Station Number = %d",
+				sta_cnt + 1);
+			pe_debug("MAC = " MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(sta_ds->staAddr));
+			pe_debug("Association Id: %d Station Index: %d",
+				sta_ds->assocId, sta_ds->staIndex);
+			assoc_sta_tmp++;
+			sta_cnt++;
+		}
+	}
+lim_assoc_sta_end:
+	/*
+	 * Call hdd callback with sap event to send the list of
+	 * associated stations from PE
+	 */
+	if (sap_event_cb != NULL) {
+		sap_event.sapHddEventCode = eSAP_ASSOC_STA_CALLBACK_EVENT;
+		sap_event.sapevt.sapAssocStaListEvent.module =
+			QDF_MODULE_ID_PE;
+		sap_event.sapevt.sapAssocStaListEvent.noOfAssocSta = sta_cnt;
+		sap_event.sapevt.sapAssocStaListEvent.pAssocStas =
+			(tpSap_AssocMacAddr)get_assoc_stas_req.pAssocStasArray;
+		sap_event_cb(&sap_event, get_assoc_stas_req.pUsrContext);
+	}
+}
+
+/**
+ * __lim_counter_measures()
+ *
+ * FUNCTION:
+ * This function is called to "implement" MIC counter measure
+ * and is *temporary* only
+ *
+ * LOGIC: on AP, disassoc all STA associated thru TKIP,
+ * we don't do the proper STA disassoc sequence since the
+ * BSS will be stopped anyway
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac      Pointer to Global MAC structure
+ * @return None
+ */
+
+static void __lim_counter_measures(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	tSirMacAddr mac = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+	if (LIM_IS_AP_ROLE(psessionEntry))
+		lim_send_disassoc_mgmt_frame(pMac, eSIR_MAC_MIC_FAILURE_REASON,
+					     mac, psessionEntry, false);
+};
+
+void lim_send_stop_bss_failure_resp(tpAniSirGlobal mac_ctx,
+				    tpPESession session)
+{
+	session->limSmeState = session->limPrevSmeState;
+
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, session->peSessionId,
+			  session->limSmeState));
+
+	lim_send_sme_rsp(mac_ctx, eWNI_SME_STOP_BSS_RSP,
+			 eSIR_SME_STOP_BSS_FAILURE, session->smeSessionId,
+			 session->transactionId);
+}
+
+void lim_delete_all_peers(tpPESession session)
+{
+	uint8_t i = 0;
+	tpAniSirGlobal mac_ctx = session->mac_ctx;
+	tpDphHashNode sta_ds = NULL;
+	QDF_STATUS status;
+
+	for (i = 1; i < session->dph.dphHashTable.size; i++) {
+		sta_ds = dph_get_hash_entry(mac_ctx, i,
+					    &session->dph.dphHashTable);
+		if (!sta_ds)
+			continue;
+		status = lim_del_sta(mac_ctx, sta_ds, false, session);
+		if (QDF_STATUS_SUCCESS == status) {
+			lim_delete_dph_hash_entry(mac_ctx, sta_ds->staAddr,
+						  sta_ds->assocId, session);
+			lim_release_peer_idx(mac_ctx, sta_ds->assocId, session);
+		} else {
+			pe_err("lim_del_sta failed with Status: %d", status);
+			QDF_ASSERT(0);
+		}
+	}
+
+#ifdef CONFIG_VDEV_SM
+	status =
+	    wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					  WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE,
+					  sizeof(*session), session);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("failed to post WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE for vdevid %d",
+		       session->smeSessionId);
+		lim_send_stop_bss_failure_resp(mac_ctx, session);
+	}
+#endif
+
+}
+
+QDF_STATUS lim_sta_send_del_bss(tpPESession session)
+{
+	tpAniSirGlobal mac_ctx = session->mac_ctx;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpDphHashNode sta_ds = NULL;
+
+	sta_ds = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+				    &session->dph.dphHashTable);
+	if (!sta_ds) {
+		pe_err("DPH Entry for STA is missing, failed to send delbss");
+		goto end;
+	}
+
+	status = lim_del_bss(mac_ctx, sta_ds, 0, session);
+	if (QDF_IS_STATUS_ERROR(status))
+		pe_err("delBss failed for bss %d", session->bssIdx);
+
+end:
+	return status;
+}
+
+QDF_STATUS lim_send_vdev_stop(tpPESession session)
+{
+	tpAniSirGlobal mac_ctx = session->mac_ctx;
+	QDF_STATUS status;
+
+	status = lim_del_bss(mac_ctx, NULL, session->bssIdx, session);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("delBss failed for bss %d", session->bssIdx);
+		lim_send_stop_bss_failure_resp(mac_ctx, session);
+	}
+
+	return status;
+}
+
+/**
+ * lim_delete_peers_and_send_vdev_stop() -delete peers and send vdev stop
+ * @session: session pointer
+ *
+ * Return None
+ */
+#ifdef CONFIG_VDEV_SM
+static void lim_delete_peers_and_send_vdev_stop(tpPESession session)
+{
+	tpAniSirGlobal mac_ctx = session->mac_ctx;
+	QDF_STATUS status;
+
+	if (wlan_vdev_mlme_get_substate(session->vdev) ==
+	    WLAN_VDEV_SS_START_RESTART_PROGRESS)
+		status =
+		 wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					       WLAN_VDEV_SM_EV_RESTART_REQ_FAIL,
+					       sizeof(*session), session);
+	else
+		status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+						       WLAN_VDEV_SM_EV_DOWN,
+						       sizeof(*session),
+						       session);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("failed to post WLAN_VDEV_SM_EV_DOWN for vdevid %d",
+		       session->smeSessionId);
+		lim_send_stop_bss_failure_resp(mac_ctx, session);
+	}
+}
+#else
+static void lim_delete_peers_and_send_vdev_stop(tpPESession session)
+{
+	lim_delete_all_peers(session);
+	/* send a delBss to HAL and wait for a response */
+	lim_send_vdev_stop(session);
+}
+#endif
+
+static void
+__lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	tSirSmeStopBssReq stopBssReq;
+	tLimSmeStates prevState;
+	tpPESession psessionEntry;
+	uint8_t smesessionId;
+	uint8_t sessionId;
+	uint16_t smetransactionId;
+
+	qdf_mem_copy(&stopBssReq, pMsgBuf, sizeof(tSirSmeStopBssReq));
+	smesessionId = stopBssReq.sessionId;
+	smetransactionId = stopBssReq.transactionId;
+
+	if (!lim_is_sme_stop_bss_req_valid(pMsgBuf)) {
+		pe_warn("received invalid SME_STOP_BSS_REQ message");
+		/* Send Stop BSS response to host */
+		lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
+				 eSIR_SME_INVALID_PARAMETERS, smesessionId,
+				 smetransactionId);
+		return;
+	}
+
+	psessionEntry = pe_find_session_by_bssid(pMac,
+				stopBssReq.bssid.bytes,
+				&sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("session does not exist for given BSSID");
+		lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
+				 eSIR_SME_INVALID_PARAMETERS, smesessionId,
+				 smetransactionId);
+		return;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_STOP_BSS_REQ_EVENT, psessionEntry,
+			      0, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE ||    /* Added For BT -AMP Support */
+	    LIM_IS_STA_ROLE(psessionEntry)) {
+		/**
+		 * Should not have received STOP_BSS_REQ in states
+		 * other than 'normal' state or on STA in Infrastructure
+		 * mode. Log error and return response to host.
+		 */
+		pe_err("received unexpected SME_STOP_BSS_REQ in state %X, for role %d",
+			psessionEntry->limSmeState,
+			GET_LIM_SYSTEM_ROLE(psessionEntry));
+		lim_print_sme_state(pMac, LOGE, psessionEntry->limSmeState);
+		/* / Send Stop BSS response to host */
+		lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
+				 eSIR_SME_UNEXPECTED_REQ_RESULT_CODE, smesessionId,
+				 smetransactionId);
+		return;
+	}
+
+	if (LIM_IS_AP_ROLE(psessionEntry))
+		lim_wpspbc_close(pMac, psessionEntry);
+
+	pe_debug("RECEIVED STOP_BSS_REQ with reason code=%d",
+		stopBssReq.reasonCode);
+
+	prevState = psessionEntry->limSmeState;
+	psessionEntry->limPrevSmeState = prevState;
+
+	psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+		       psessionEntry->limSmeState));
+
+	/* Update SME session Id and Transaction Id */
+	psessionEntry->smeSessionId = smesessionId;
+	psessionEntry->transactionId = smetransactionId;
+
+	/* STA_IN_IBSS and NDI should NOT send Disassoc frame */
+	if (!LIM_IS_IBSS_ROLE(psessionEntry) &&
+	    !LIM_IS_NDI_ROLE(psessionEntry)) {
+		tSirMacAddr bcAddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+		if (stopBssReq.reasonCode == eSIR_SME_MIC_COUNTER_MEASURES)
+			/* Send disassoc all stations associated thru TKIP */
+			__lim_counter_measures(pMac, psessionEntry);
+		else
+			lim_send_disassoc_mgmt_frame(pMac,
+				eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
+				bcAddr, psessionEntry, false);
+	}
+
+	if (!LIM_IS_NDI_ROLE(psessionEntry)) {
+		/* Free the buffer allocated in START_BSS_REQ */
+		qdf_mem_free(psessionEntry->addIeParams.probeRespData_buff);
+		psessionEntry->addIeParams.probeRespDataLen = 0;
+		psessionEntry->addIeParams.probeRespData_buff = NULL;
+
+		qdf_mem_free(psessionEntry->addIeParams.assocRespData_buff);
+		psessionEntry->addIeParams.assocRespDataLen = 0;
+		psessionEntry->addIeParams.assocRespData_buff = NULL;
+
+		qdf_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
+		psessionEntry->addIeParams.probeRespBCNDataLen = 0;
+		psessionEntry->addIeParams.probeRespBCNData_buff = NULL;
+
+		/*
+		 * lim_del_bss is also called as part of coalescing,
+		 * when we send DEL BSS followed by Add Bss msg.
+		 */
+		pMac->lim.gLimIbssCoalescingHappened = false;
+	}
+
+	lim_delete_peers_and_send_vdev_stop(psessionEntry);
+
+}
+
+/**
+ * __lim_process_sme_stop_bss_req() - Process STOP_BSS from SME
+ * @pMac: Global MAC context
+ * @pMsg: Message from SME
+ *
+ * Wrapper for the function __lim_handle_sme_stop_bss_request
+ * This message will be defered until softmac come out of
+ * scan mode. Message should be handled even if we have
+ * detected radar in the current operating channel.
+ *
+ * Return: true - If we consumed the buffer
+ *         false - If have defered the message.
+ */
+
+static bool __lim_process_sme_stop_bss_req(tpAniSirGlobal pMac,
+					   struct scheduler_msg *pMsg)
+{
+	if (__lim_is_defered_msg_for_learn(pMac, pMsg)) {
+		/**
+		 * If message defered, buffer is not consumed yet.
+		 * So return false
+		 */
+		return false;
+	}
+	__lim_handle_sme_stop_bss_request(pMac, (uint32_t *) pMsg->bodyptr);
+	return true;
+} /*** end __lim_process_sme_stop_bss_req() ***/
+
+void lim_process_sme_del_bss_rsp(tpAniSirGlobal pMac,
+				 uint32_t body, tpPESession psessionEntry)
+{
+
+	(void)body;
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+	lim_ibss_delete(pMac, psessionEntry);
+	dph_hash_table_class_init(pMac, &psessionEntry->dph.dphHashTable);
+	lim_delete_pre_auth_list(pMac);
+	lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_SUCCESS,
+			 psessionEntry->smeSessionId,
+			 psessionEntry->transactionId);
+	return;
+}
+
+/**
+ * __lim_process_sme_assoc_cnf_new() - process sme assoc/reassoc cnf
+ *
+ * @mac_ctx: pointer to mac context
+ * @msg_type: message type
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function handles SME_ASSOC_CNF/SME_REASSOC_CNF
+ * in BTAMP AP.
+ *
+ * Return: None
+ */
+
+void __lim_process_sme_assoc_cnf_new(tpAniSirGlobal mac_ctx, uint32_t msg_type,
+				uint32_t *msg_buf)
+{
+	tSirSmeAssocCnf assoc_cnf;
+	tpDphHashNode sta_ds = NULL;
+	tpPESession session_entry = NULL;
+	uint8_t session_id;
+	tpSirAssocReq assoc_req;
+
+	if (msg_buf == NULL) {
+		pe_err("msg_buf is NULL");
+		goto end;
+	}
+
+	qdf_mem_copy(&assoc_cnf, msg_buf, sizeof(struct sSirSmeAssocCnf));
+	if (!__lim_is_sme_assoc_cnf_valid(&assoc_cnf)) {
+		pe_err("Received invalid SME_RE(ASSOC)_CNF message");
+		goto end;
+	}
+
+	session_entry = pe_find_session_by_bssid(mac_ctx, assoc_cnf.bssid.bytes,
+			&session_id);
+	if (session_entry == NULL) {
+		pe_err("session does not exist for given bssId");
+		goto end;
+	}
+
+	if ((!LIM_IS_AP_ROLE(session_entry)) ||
+	    ((session_entry->limSmeState != eLIM_SME_NORMAL_STATE) &&
+	    (session_entry->limSmeState !=
+			eLIM_SME_NORMAL_CHANNEL_SCAN_STATE))) {
+		pe_err("Rcvd unexpected msg %X in state %X, in role %X",
+			msg_type, session_entry->limSmeState,
+			GET_LIM_SYSTEM_ROLE(session_entry));
+		goto end;
+	}
+	sta_ds = dph_get_hash_entry(mac_ctx, assoc_cnf.aid,
+			&session_entry->dph.dphHashTable);
+	if (sta_ds == NULL) {
+		pe_err("Rcvd invalid msg %X due to no STA ctx, aid %d, peer",
+				msg_type, assoc_cnf.aid);
+		lim_print_mac_addr(mac_ctx, assoc_cnf.peer_macaddr.bytes, LOGE);
+
+		/*
+		 * send a DISASSOC_IND message to WSM to make sure
+		 * the state in WSM and LIM is the same
+		 */
+		lim_send_sme_disassoc_ntf(mac_ctx, assoc_cnf.peer_macaddr.bytes,
+				eSIR_SME_STA_NOT_ASSOCIATED,
+				eLIM_PEER_ENTITY_DISASSOC, assoc_cnf.aid,
+				session_entry->smeSessionId,
+				session_entry->transactionId,
+				session_entry);
+		goto end;
+	}
+	if (qdf_mem_cmp((uint8_t *)sta_ds->staAddr,
+				(uint8_t *) assoc_cnf.peer_macaddr.bytes,
+				QDF_MAC_ADDR_SIZE)) {
+		pe_debug("peerMacAddr mismatched for aid %d, peer ",
+				assoc_cnf.aid);
+		lim_print_mac_addr(mac_ctx, assoc_cnf.peer_macaddr.bytes, LOGD);
+		goto end;
+	}
+
+	if ((sta_ds->mlmStaContext.mlmState != eLIM_MLM_WT_ASSOC_CNF_STATE) ||
+		((sta_ds->mlmStaContext.subType == LIM_ASSOC) &&
+		 (msg_type != eWNI_SME_ASSOC_CNF)) ||
+		((sta_ds->mlmStaContext.subType == LIM_REASSOC) &&
+		 (msg_type != eWNI_SME_ASSOC_CNF))) {
+		pe_debug("not in MLM_WT_ASSOC_CNF_STATE, for aid %d, peer"
+			"StaD mlmState: %d",
+			assoc_cnf.aid, sta_ds->mlmStaContext.mlmState);
+		lim_print_mac_addr(mac_ctx, assoc_cnf.peer_macaddr.bytes, LOGD);
+		goto end;
+	}
+	/*
+	 * Deactivate/delet CNF_WAIT timer since ASSOC_CNF
+	 * has been received
+	 */
+	pe_debug("Received SME_ASSOC_CNF. Delete Timer");
+	lim_deactivate_and_change_per_sta_id_timer(mac_ctx,
+			eLIM_CNF_WAIT_TIMER, sta_ds->assocId);
+
+	if (assoc_cnf.statusCode == eSIR_SME_SUCCESS) {
+		/*
+		 * In BTAMP-AP, PE already finished the WMA_ADD_STA sequence
+		 * when it had received Assoc Request frame. Now, PE just needs
+		 * to send association rsp frame to the requesting BTAMP-STA.
+		 */
+		sta_ds->mlmStaContext.mlmState =
+			eLIM_MLM_LINK_ESTABLISHED_STATE;
+		pe_debug("sending Assoc Rsp frame to STA (assoc id=%d)",
+			sta_ds->assocId);
+		lim_send_assoc_rsp_mgmt_frame(mac_ctx, QDF_STATUS_SUCCESS,
+					sta_ds->assocId, sta_ds->staAddr,
+					sta_ds->mlmStaContext.subType, sta_ds,
+					session_entry);
+		goto end;
+	} else {
+		/*
+		 * SME_ASSOC_CNF status is non-success, so STA is not allowed
+		 * to be associated since the HAL sta entry is created for
+		 * denied STA we need to remove this HAL entry.
+		 * So to do that set updateContext to 1
+		 */
+		if (!sta_ds->mlmStaContext.updateContext)
+			sta_ds->mlmStaContext.updateContext = 1;
+		pe_debug("Recv Assoc Cnf, status Code : %d(assoc id=%d)",
+			assoc_cnf.statusCode, sta_ds->assocId);
+		lim_reject_association(mac_ctx, sta_ds->staAddr,
+				       sta_ds->mlmStaContext.subType,
+				       true, sta_ds->mlmStaContext.authType,
+				       sta_ds->assocId, true,
+				       eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				       session_entry);
+	}
+end:
+	if (((session_entry != NULL) && (sta_ds != NULL)) &&
+		(session_entry->parsedAssocReq[sta_ds->assocId] != NULL)) {
+		assoc_req = (tpSirAssocReq)
+			session_entry->parsedAssocReq[sta_ds->assocId];
+		if (assoc_req->assocReqFrame) {
+			qdf_mem_free(assoc_req->assocReqFrame);
+			assoc_req->assocReqFrame = NULL;
+		}
+		qdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]);
+		session_entry->parsedAssocReq[sta_ds->assocId] = NULL;
+	}
+}
+
+static void __lim_process_sme_addts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	tpDphHashNode pStaDs;
+	tSirMacAddr peerMac;
+	tpSirAddtsReq pSirAddts;
+	uint32_t timeout;
+	tpPESession psessionEntry;
+	uint8_t sessionId;      /* PE sessionId */
+	uint8_t smesessionId;
+	uint16_t smetransactionId;
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	lim_get_session_info(pMac, (uint8_t *) pMsgBuf, &smesessionId,
+			     &smetransactionId);
+
+	pSirAddts = (tpSirAddtsReq) pMsgBuf;
+
+	psessionEntry = pe_find_session_by_bssid(pMac, pSirAddts->bssid.bytes,
+						 &sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given bssId");
+		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, QDF_STATUS_E_FAILURE,
+				       NULL, pSirAddts->req.tspec,
+				       smesessionId, smetransactionId);
+		return;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_ADDTS_REQ_EVENT, psessionEntry, 0,
+			      0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	/* if sta
+	 *  - verify assoc state
+	 *  - send addts request to ap
+	 *  - wait for addts response from ap
+	 * if ap, just ignore with error log
+	 */
+	pe_debug("Received SME_ADDTS_REQ (TSid %d, UP %d)",
+		pSirAddts->req.tspec.tsinfo.traffic.tsid,
+		pSirAddts->req.tspec.tsinfo.traffic.userPrio);
+
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("AddTs received on AP - ignoring");
+		goto send_failure_addts_rsp;
+	}
+
+	pStaDs =
+		dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+				   &psessionEntry->dph.dphHashTable);
+
+	if (pStaDs == NULL) {
+		pe_err("Cannot find AP context for addts req");
+		goto send_failure_addts_rsp;
+	}
+
+	if ((!pStaDs->valid) || (pStaDs->mlmStaContext.mlmState !=
+	    eLIM_MLM_LINK_ESTABLISHED_STATE)) {
+		pe_err("AddTs received in invalid MLM state");
+		goto send_failure_addts_rsp;
+	}
+
+	pSirAddts->req.wsmTspecPresent = 0;
+	pSirAddts->req.wmeTspecPresent = 0;
+	pSirAddts->req.lleTspecPresent = 0;
+
+	if ((pStaDs->wsmEnabled) &&
+	    (pSirAddts->req.tspec.tsinfo.traffic.accessPolicy !=
+	     SIR_MAC_ACCESSPOLICY_EDCA))
+		pSirAddts->req.wsmTspecPresent = 1;
+	else if (pStaDs->wmeEnabled)
+		pSirAddts->req.wmeTspecPresent = 1;
+	else if (pStaDs->lleEnabled)
+		pSirAddts->req.lleTspecPresent = 1;
+	else {
+		pe_warn("ADDTS_REQ ignore - qos is disabled");
+		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);
+		goto send_failure_addts_rsp;
+	}
+
+	if (pMac->lim.gLimAddtsSent) {
+		pe_err("Addts (token %d, tsid %d, up %d) is still pending",
+			pMac->lim.gLimAddtsReq.req.dialogToken,
+			pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.tsid,
+			pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.
+			userPrio);
+		goto send_failure_addts_rsp;
+	}
+
+	sir_copy_mac_addr(peerMac, psessionEntry->bssId);
+
+	/* save the addts request */
+	pMac->lim.gLimAddtsSent = true;
+	qdf_mem_copy((uint8_t *) &pMac->lim.gLimAddtsReq,
+		     (uint8_t *) pSirAddts, sizeof(tSirAddtsReq));
+
+	/* ship out the message now */
+	lim_send_addts_req_action_frame(pMac, peerMac, &pSirAddts->req,
+					psessionEntry);
+	pe_err("Sent ADDTS request");
+	/* start a timer to wait for the response */
+	if (pSirAddts->timeout)
+		timeout = pSirAddts->timeout;
+	else
+		timeout = pMac->mlme_cfg->timeouts.addts_rsp_timeout;
+
+	timeout = SYS_MS_TO_TICKS(timeout);
+	if (tx_timer_change(&pMac->lim.limTimers.gLimAddtsRspTimer, timeout, 0)
+	    != TX_SUCCESS) {
+		pe_err("AddtsRsp timer change failed!");
+		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!");
+		goto send_failure_addts_rsp;
+	}
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId,
+		       eLIM_ADDTS_RSP_TIMER));
+
+	/* add the sessionId to the timer object */
+	pMac->lim.limTimers.gLimAddtsRspTimer.sessionId = sessionId;
+	if (tx_timer_activate(&pMac->lim.limTimers.gLimAddtsRspTimer) !=
+	    TX_SUCCESS) {
+		pe_err("AddtsRsp timer activation failed!");
+		goto send_failure_addts_rsp;
+	}
+	return;
+
+send_failure_addts_rsp:
+	lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, QDF_STATUS_E_FAILURE,
+			       psessionEntry, pSirAddts->req.tspec,
+			       smesessionId, smetransactionId);
+}
+
+static void __lim_process_sme_delts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	tSirMacAddr peerMacAddr;
+	uint8_t ac;
+	tSirMacTSInfo *pTsinfo;
+	tpSirDeltsReq pDeltsReq = (tpSirDeltsReq) pMsgBuf;
+	tpDphHashNode pStaDs = NULL;
+	tpPESession psessionEntry;
+	uint8_t sessionId;
+	uint32_t status = QDF_STATUS_SUCCESS;
+	uint8_t smesessionId;
+	uint16_t smetransactionId;
+
+	lim_get_session_info(pMac, (uint8_t *) pMsgBuf, &smesessionId,
+			     &smetransactionId);
+
+	psessionEntry = pe_find_session_by_bssid(pMac,
+				pDeltsReq->bssid.bytes,
+				&sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given bssId");
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_REQ_EVENT, psessionEntry, 0,
+			      0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	if (QDF_STATUS_SUCCESS !=
+	    lim_validate_delts_req(pMac, pDeltsReq, peerMacAddr, psessionEntry)) {
+		pe_err("lim_validate_delts_req failed");
+		status = QDF_STATUS_E_FAILURE;
+		lim_send_sme_delts_rsp(pMac, pDeltsReq, QDF_STATUS_E_FAILURE, psessionEntry,
+				       smesessionId, smetransactionId);
+		return;
+	}
+
+	pe_debug("Sent DELTS request to station with assocId = %d MacAddr = "
+		MAC_ADDRESS_STR,
+		pDeltsReq->aid, MAC_ADDR_ARRAY(peerMacAddr));
+
+	lim_send_delts_req_action_frame(pMac, peerMacAddr,
+					pDeltsReq->req.wmeTspecPresent,
+					&pDeltsReq->req.tsinfo,
+					&pDeltsReq->req.tspec, psessionEntry);
+
+	pTsinfo =
+		pDeltsReq->req.wmeTspecPresent ? &pDeltsReq->req.tspec.
+		tsinfo : &pDeltsReq->req.tsinfo;
+
+	/* We've successfully send DELTS frame to AP. Update the
+	 * dynamic UAPSD mask. The AC for this TSPEC to be deleted
+	 * is no longer trigger enabled or delivery enabled
+	 */
+	lim_set_tspec_uapsd_mask_per_session(pMac, psessionEntry,
+					     pTsinfo, CLEAR_UAPSD_MASK);
+
+	/* We're deleting the TSPEC, so this particular AC is no longer
+	 * admitted.  PE needs to downgrade the EDCA
+	 * parameters(for the AC for which TS is being deleted) to the
+	 * next best AC for which ACM is not enabled, and send the
+	 * updated values to HAL.
+	 */
+	ac = upToAc(pTsinfo->traffic.userPrio);
+
+	if (pTsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) {
+		psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
+			~(1 << ac);
+	} else if (pTsinfo->traffic.direction ==
+		   SIR_MAC_DIRECTION_DNLINK) {
+		psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
+			~(1 << ac);
+	} else if (pTsinfo->traffic.direction ==
+		   SIR_MAC_DIRECTION_BIDIR) {
+		psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
+			~(1 << ac);
+		psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
+			~(1 << ac);
+	}
+
+	lim_set_active_edca_params(pMac, psessionEntry->gLimEdcaParams,
+				   psessionEntry);
+
+	pStaDs =
+		dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+				   &psessionEntry->dph.dphHashTable);
+	if (pStaDs != NULL) {
+		lim_send_edca_params(pMac, psessionEntry->gLimEdcaParamsActive,
+				     pStaDs->bssId, false);
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		pe_err("Self entry missing in Hash Table");
+		status = QDF_STATUS_E_FAILURE;
+	}
+#ifdef FEATURE_WLAN_ESE
+	lim_send_sme_tsm_ie_ind(pMac, psessionEntry, 0, 0, 0);
+#endif
+
+	/* send an sme response back */
+end:
+	lim_send_sme_delts_rsp(pMac, pDeltsReq, QDF_STATUS_SUCCESS, psessionEntry,
+			       smesessionId, smetransactionId);
+}
+
+void lim_process_sme_addts_rsp_timeout(tpAniSirGlobal pMac, uint32_t param)
+{
+	/* fetch the sessionEntry based on the sessionId */
+	tpPESession psessionEntry;
+
+	psessionEntry = pe_find_session_by_session_id(pMac,
+				pMac->lim.limTimers.gLimAddtsRspTimer.
+				sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_warn("AddtsRspTimeout in non-Sta role (%d)",
+			GET_LIM_SYSTEM_ROLE(psessionEntry));
+		pMac->lim.gLimAddtsSent = false;
+		return;
+	}
+
+	if (!pMac->lim.gLimAddtsSent) {
+		pe_warn("AddtsRspTimeout but no AddtsSent");
+		return;
+	}
+
+	if (param != pMac->lim.gLimAddtsRspTimerCount) {
+		pe_err("Invalid AddtsRsp Timer count %d (exp %d)", param,
+			pMac->lim.gLimAddtsRspTimerCount);
+		return;
+	}
+	/* this a real response timeout */
+	pMac->lim.gLimAddtsSent = false;
+	pMac->lim.gLimAddtsRspTimerCount++;
+
+	lim_send_sme_addts_rsp(pMac, true, eSIR_SME_ADDTS_RSP_TIMEOUT,
+			       psessionEntry, pMac->lim.gLimAddtsReq.req.tspec,
+			       psessionEntry->smeSessionId,
+			       psessionEntry->transactionId);
+}
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * __lim_process_sme_get_statistics_request()
+ *
+ ***FUNCTION:
+ *
+ *
+ ***NOTE:
+ *
+ * @param  pMac      Pointer to Global MAC structure
+ * @param  *pMsgBuf  A pointer to the SME message buffer
+ * @return None
+ */
+static void
+__lim_process_sme_get_statistics_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	tpAniGetPEStatsReq pPEStatsReq;
+	struct scheduler_msg msgQ = {0};
+
+	pPEStatsReq = (tpAniGetPEStatsReq) pMsgBuf;
+
+	msgQ.type = WMA_GET_STATISTICS_REQ;
+
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pMsgBuf;
+	msgQ.bodyval = 0;
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+
+	if (QDF_STATUS_SUCCESS != (wma_post_ctrl_msg(pMac, &msgQ))) {
+		qdf_mem_free(pMsgBuf);
+		pMsgBuf = NULL;
+		pe_err("Unable to forward request");
+		return;
+	}
+
+	return;
+}
+#else
+static void __lim_process_sme_get_statistics_request(
+			struct mac_context *mac_ctx, uint32_t *pMsgBuf) {}
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * __lim_process_sme_get_tsm_stats_request() - get tsm stats request
+ *
+ * @pMac: Pointer to Global MAC structure
+ * @pMsgBuf: A pointer to the SME message buffer
+ *
+ * Return: None
+ */
+static void
+__lim_process_sme_get_tsm_stats_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	struct scheduler_msg msgQ = {0};
+
+	msgQ.type = WMA_TSM_STATS_REQ;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pMsgBuf;
+	msgQ.bodyval = 0;
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+
+	if (QDF_STATUS_SUCCESS != (wma_post_ctrl_msg(pMac, &msgQ))) {
+		qdf_mem_free(pMsgBuf);
+		pMsgBuf = NULL;
+		pe_err("Unable to forward request");
+		return;
+	}
+}
+#endif /* FEATURE_WLAN_ESE */
+
+static void lim_process_sme_set_addba_accept(tpAniSirGlobal mac_ctx,
+		struct sme_addba_accept *msg)
+{
+	if (!msg) {
+		pe_err("Msg Buffer is NULL");
+		return;
+	}
+	if (!msg->addba_accept)
+		mac_ctx->reject_addba_req = 1;
+	else
+		mac_ctx->reject_addba_req = 0;
+}
+
+static void lim_process_sme_update_edca_params(tpAniSirGlobal mac_ctx,
+					       uint32_t sme_session_id)
+{
+	tpPESession pe_session;
+	tpDphHashNode sta_ds_ptr;
+
+	pe_session = pe_find_session_by_sme_session_id(mac_ctx, sme_session_id);
+	if (!pe_session) {
+		pe_err("Session does not exist: sme_id %d", sme_session_id);
+		return;
+	}
+	pe_session->gLimEdcaParamsActive[EDCA_AC_BE].no_ack =
+		mac_ctx->no_ack_policy_cfg[EDCA_AC_BE];
+	pe_session->gLimEdcaParamsActive[EDCA_AC_BK].no_ack =
+		mac_ctx->no_ack_policy_cfg[EDCA_AC_BK];
+	pe_session->gLimEdcaParamsActive[EDCA_AC_VI].no_ack =
+		mac_ctx->no_ack_policy_cfg[EDCA_AC_VI];
+	pe_session->gLimEdcaParamsActive[EDCA_AC_VO].no_ack =
+		mac_ctx->no_ack_policy_cfg[EDCA_AC_VO];
+	sta_ds_ptr = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+					&pe_session->dph.dphHashTable);
+	if (sta_ds_ptr)
+		lim_send_edca_params(mac_ctx,
+				     pe_session->gLimEdcaParamsActive,
+				     sta_ds_ptr->bssId, false);
+	else
+		pe_err("Self entry missing in Hash Table");
+}
+
+static void lim_process_sme_update_mu_edca_params(tpAniSirGlobal mac_ctx,
+						  uint32_t sme_session_id)
+{
+	tpPESession pe_session;
+	tpDphHashNode sta_ds_ptr;
+
+	pe_session = pe_find_session_by_sme_session_id(mac_ctx, sme_session_id);
+	if (!pe_session) {
+		pe_err("Session does not exist: sme_id %d", sme_session_id);
+		return;
+	}
+	sta_ds_ptr = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+					&pe_session->dph.dphHashTable);
+	if (sta_ds_ptr)
+		lim_send_edca_params(mac_ctx, mac_ctx->usr_mu_edca_params,
+				     sta_ds_ptr->bssId, true);
+	else
+		pe_err("Self entry missing in Hash Table");
+}
+
+static void lim_process_sme_update_config(tpAniSirGlobal mac_ctx,
+					  struct update_config *msg)
+{
+	tpPESession pe_session;
+
+	pe_debug("received eWNI_SME_UPDATE_HT_CONFIG message");
+	if (msg == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	pe_session = pe_find_session_by_sme_session_id(mac_ctx,
+						       msg->sme_session_id);
+	if (pe_session == NULL) {
+		pe_warn("Session does not exist for given BSSID");
+		return;
+	}
+
+	switch (msg->capab) {
+	case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
+		pe_session->htConfig.ht_rx_ldpc = msg->value;
+		break;
+	case WNI_CFG_HT_CAP_INFO_TX_STBC:
+		pe_session->htConfig.ht_tx_stbc = msg->value;
+		break;
+	case WNI_CFG_HT_CAP_INFO_RX_STBC:
+		pe_session->htConfig.ht_rx_stbc = msg->value;
+		break;
+	case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
+		pe_session->htConfig.ht_sgi20 = msg->value;
+		break;
+	case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
+		pe_session->htConfig.ht_sgi40 = msg->value;
+		break;
+	}
+
+	if (LIM_IS_AP_ROLE(pe_session)) {
+		sch_set_fixed_beacon_fields(mac_ctx, pe_session);
+		lim_send_beacon_ind(mac_ctx, pe_session, REASON_CONFIG_UPDATE);
+	}
+}
+
+void
+lim_send_vdev_restart(tpAniSirGlobal pMac,
+		      tpPESession psessionEntry, uint8_t sessionId)
+{
+	tpHalHiddenSsidVdevRestart pHalHiddenSsidVdevRestart = NULL;
+	struct scheduler_msg msgQ = {0};
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+
+	if (psessionEntry == NULL) {
+		pe_err("Invalid parameters");
+		return;
+	}
+
+	pHalHiddenSsidVdevRestart =
+		qdf_mem_malloc(sizeof(tHalHiddenSsidVdevRestart));
+	if (!pHalHiddenSsidVdevRestart)
+		return;
+
+	pHalHiddenSsidVdevRestart->ssidHidden = psessionEntry->ssidHidden;
+	pHalHiddenSsidVdevRestart->sessionId = sessionId;
+	pHalHiddenSsidVdevRestart->pe_session_id = psessionEntry->peSessionId;
+
+	msgQ.type = WMA_HIDDEN_SSID_VDEV_RESTART;
+	msgQ.bodyptr = pHalHiddenSsidVdevRestart;
+	msgQ.bodyval = 0;
+
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		pe_err("wma_post_ctrl_msg() failed");
+		qdf_mem_free(pHalHiddenSsidVdevRestart);
+	}
+}
+
+/**
+ * __lim_process_roam_scan_offload_req() - Process Roam scan offload from csr
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: Pointer to SME message buffer
+ *
+ * Return: None
+ */
+static void __lim_process_roam_scan_offload_req(tpAniSirGlobal mac_ctx,
+						uint32_t *msg_buf)
+{
+	tpPESession pe_session;
+	struct scheduler_msg wma_msg = {0};
+	QDF_STATUS status;
+	tSirRoamOffloadScanReq *req_buffer;
+	uint16_t local_ie_len;
+	uint8_t *local_ie_buf;
+
+	req_buffer = (tSirRoamOffloadScanReq *)msg_buf;
+	pe_session = pe_find_session_by_sme_session_id(mac_ctx,
+					req_buffer->sessionId);
+
+	local_ie_buf = qdf_mem_malloc(MAX_DEFAULT_SCAN_IE_LEN);
+	if (!local_ie_buf) {
+		qdf_mem_free(req_buffer);
+		return;
+	}
+
+	local_ie_len = req_buffer->assoc_ie.length;
+	/* Update ext cap IE if present */
+	if (local_ie_len &&
+	    !lim_update_ext_cap_ie(mac_ctx, req_buffer->assoc_ie.addIEdata,
+				   local_ie_buf, &local_ie_len)) {
+		if (local_ie_len <
+		    QDF_ARRAY_SIZE(req_buffer->assoc_ie.addIEdata)) {
+			req_buffer->assoc_ie.length = local_ie_len;
+			qdf_mem_copy(req_buffer->assoc_ie.addIEdata,
+				     local_ie_buf, local_ie_len);
+		}
+	}
+	qdf_mem_free(local_ie_buf);
+
+	if (pe_session)
+		lim_update_fils_rik(pe_session, req_buffer);
+
+	wma_msg.type = WMA_ROAM_SCAN_OFFLOAD_REQ;
+	wma_msg.bodyptr = req_buffer;
+
+	status = wma_post_ctrl_msg(mac_ctx, &wma_msg);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("Posting WMA_ROAM_SCAN_OFFLOAD_REQ failed");
+		qdf_mem_free(req_buffer);
+	}
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * lim_process_roam_invoke() - process the Roam Invoke req
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: Pointer to the SME message buffer
+ *
+ * This function is called by limProcessMessageQueue(). This function sends the
+ * ROAM_INVOKE command to WMA.
+ *
+ * Return: None
+ */
+static void lim_process_roam_invoke(tpAniSirGlobal mac_ctx,
+				    uint32_t *msg_buf)
+{
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+
+	msg.type = SIR_HAL_ROAM_INVOKE;
+	msg.bodyptr = msg_buf;
+	msg.reserved = 0;
+
+	status = wma_post_ctrl_msg(mac_ctx, &msg);
+	if (QDF_STATUS_SUCCESS != status)
+		pe_err("Not able to post SIR_HAL_ROAM_INVOKE to WMA");
+}
+#else
+static void lim_process_roam_invoke(tpAniSirGlobal mac_ctx,
+				    uint32_t *msg_buf)
+{
+	qdf_mem_free(msg_buf);
+}
+#endif
+
+/*
+ * lim_handle_update_ssid_hidden() - Processes SSID hidden update
+ * @mac_ctx: Pointer to global mac context
+ * @session: Pointer to PE session
+ * @ssid_hidden: SSID hidden value to set; 0 - Broadcast SSID,
+ *    1 - Disable broadcast SSID
+ *
+ * Return: None
+ */
+static void lim_handle_update_ssid_hidden(tpAniSirGlobal mac_ctx,
+				tpPESession session, uint8_t ssid_hidden)
+{
+	pe_debug("rcvd HIDE_SSID message old HIDE_SSID: %d new HIDE_SSID: %d",
+			session->ssidHidden, ssid_hidden);
+
+	if (ssid_hidden != session->ssidHidden) {
+		session->ssidHidden = ssid_hidden;
+	} else {
+		pe_debug("Dont process HIDE_SSID msg with existing setting");
+		return;
+	}
+
+#ifdef CONFIG_VDEV_SM
+	ap_mlme_set_hidden_ssid_restart_in_progress(session->vdev, true);
+	wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+				      WLAN_VDEV_SM_EV_FW_VDEV_RESTART,
+				      sizeof(*session), session);
+#else
+
+	/* Send vdev restart */
+	lim_send_vdev_restart(mac_ctx, session, session->smeSessionId);
+#endif
+
+	return;
+}
+
+/**
+ * __lim_process_sme_session_update - process SME session update msg
+ *
+ * @mac_ctx: Pointer to global mac context
+ * @msg_buf: Pointer to the received message buffer
+ *
+ * Return: None
+ */
+static void __lim_process_sme_session_update(tpAniSirGlobal mac_ctx,
+						uint32_t *msg_buf)
+{
+	struct sir_update_session_param *msg;
+	tpPESession session;
+
+	if (!msg_buf) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	msg = (struct sir_update_session_param *) msg_buf;
+
+	session = pe_find_session_by_sme_session_id(mac_ctx, msg->session_id);
+	if (!session) {
+		pe_warn("Session does not exist for given sessionId %d",
+			msg->session_id);
+		return;
+	}
+
+	pe_debug("received SME Session update for %d val %d",
+			msg->param_type, msg->param_val);
+	switch (msg->param_type) {
+	case SIR_PARAM_SSID_HIDDEN:
+		lim_handle_update_ssid_hidden(mac_ctx, session, msg->param_val);
+		break;
+	case SIR_PARAM_IGNORE_ASSOC_DISALLOWED:
+		session->ignore_assoc_disallowed = msg->param_val;
+		break;
+	default:
+		pe_err("Unknown session param");
+		break;
+	}
+}
+
+/*
+   Update the beacon Interval dynamically if beaconInterval is different in MCC
+ */
+static void __lim_process_sme_change_bi(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	tpSirChangeBIParams pChangeBIParams;
+	tpPESession psessionEntry;
+	uint8_t sessionId = 0;
+	tUpdateBeaconParams beaconParams;
+
+	pe_debug("received Update Beacon Interval message");
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	qdf_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
+	pChangeBIParams = (tpSirChangeBIParams) pMsgBuf;
+
+	psessionEntry = pe_find_session_by_bssid(pMac,
+				pChangeBIParams->bssid.bytes,
+				&sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session does not exist for given BSSID");
+		return;
+	}
+
+	/*Update sessionEntry Beacon Interval */
+	if (psessionEntry->beaconParams.beaconInterval !=
+	    pChangeBIParams->beaconInterval) {
+		psessionEntry->beaconParams.beaconInterval =
+			pChangeBIParams->beaconInterval;
+	}
+
+	/*Update sch beaconInterval */
+	if (pMac->sch.schObject.gSchBeaconInterval !=
+	    pChangeBIParams->beaconInterval) {
+		pMac->sch.schObject.gSchBeaconInterval =
+			pChangeBIParams->beaconInterval;
+
+		pe_debug("LIM send update BeaconInterval Indication: %d",
+			pChangeBIParams->beaconInterval);
+
+		if (false == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+			/* Update beacon */
+			sch_set_fixed_beacon_fields(pMac, psessionEntry);
+
+			beaconParams.bssIdx = psessionEntry->bssIdx;
+			/* Set change in beacon Interval */
+			beaconParams.beaconInterval =
+				pChangeBIParams->beaconInterval;
+			beaconParams.paramChangeBitmap =
+				PARAM_BCN_INTERVAL_CHANGED;
+			lim_send_beacon_params(pMac, &beaconParams, psessionEntry);
+		}
+	}
+
+	return;
+} /*** end __lim_process_sme_change_bi(tpAniSirGlobal pMac, uint32_t *pMsgBuf) ***/
+
+#ifdef QCA_HT_2040_COEX
+static void __lim_process_sme_set_ht2040_mode(tpAniSirGlobal pMac,
+					      uint32_t *pMsgBuf)
+{
+	tpSirSetHT2040Mode pSetHT2040Mode;
+	tpPESession psessionEntry;
+	uint8_t sessionId = 0;
+	struct scheduler_msg msg = {0};
+	tUpdateVHTOpMode *pHtOpMode = NULL;
+	uint16_t staId = 0;
+	tpDphHashNode pStaDs = NULL;
+
+	pe_debug("received Set HT 20/40 mode message");
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	pSetHT2040Mode = (tpSirSetHT2040Mode) pMsgBuf;
+
+	psessionEntry = pe_find_session_by_bssid(pMac,
+				pSetHT2040Mode->bssid.bytes,
+				&sessionId);
+	if (psessionEntry == NULL) {
+		pe_debug("Session does not exist for given BSSID");
+		lim_print_mac_addr(pMac, pSetHT2040Mode->bssid.bytes, LOGD);
+		return;
+	}
+
+	pe_debug("Update session entry for cbMod=%d",
+		pSetHT2040Mode->cbMode);
+	/*Update sessionEntry HT related fields */
+	switch (pSetHT2040Mode->cbMode) {
+	case PHY_SINGLE_CHANNEL_CENTERED:
+		psessionEntry->htSecondaryChannelOffset =
+			PHY_SINGLE_CHANNEL_CENTERED;
+		psessionEntry->htRecommendedTxWidthSet = 0;
+		if (pSetHT2040Mode->obssEnabled)
+			psessionEntry->htSupportedChannelWidthSet
+					= eHT_CHANNEL_WIDTH_40MHZ;
+		else
+			psessionEntry->htSupportedChannelWidthSet
+					= eHT_CHANNEL_WIDTH_20MHZ;
+		break;
+	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+		psessionEntry->htSecondaryChannelOffset =
+			PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+		psessionEntry->htRecommendedTxWidthSet = 1;
+		break;
+	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+		psessionEntry->htSecondaryChannelOffset =
+			PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+		psessionEntry->htRecommendedTxWidthSet = 1;
+		break;
+	default:
+		pe_err("Invalid cbMode");
+		return;
+	}
+
+	/* Update beacon */
+	sch_set_fixed_beacon_fields(pMac, psessionEntry);
+	lim_send_beacon_ind(pMac, psessionEntry, REASON_SET_HT2040);
+
+	/* update OP Mode for each associated peer */
+	for (staId = 0; staId < psessionEntry->dph.dphHashTable.size; staId++) {
+		pStaDs = dph_get_hash_entry(pMac, staId,
+				&psessionEntry->dph.dphHashTable);
+		if (NULL == pStaDs)
+			continue;
+
+		if (pStaDs->valid && pStaDs->htSupportedChannelWidthSet) {
+			pHtOpMode = qdf_mem_malloc(sizeof(tUpdateVHTOpMode));
+			if (!pHtOpMode)
+				return;
+			pHtOpMode->opMode =
+				(psessionEntry->htSecondaryChannelOffset ==
+				 PHY_SINGLE_CHANNEL_CENTERED) ?
+				eHT_CHANNEL_WIDTH_20MHZ : eHT_CHANNEL_WIDTH_40MHZ;
+			pHtOpMode->staId = staId;
+			qdf_mem_copy(pHtOpMode->peer_mac, &pStaDs->staAddr,
+				     sizeof(tSirMacAddr));
+			pHtOpMode->smesessionId = sessionId;
+
+			msg.type = WMA_UPDATE_OP_MODE;
+			msg.reserved = 0;
+			msg.bodyptr = pHtOpMode;
+			if (!QDF_IS_STATUS_SUCCESS
+				    (scheduler_post_message(QDF_MODULE_ID_PE,
+							    QDF_MODULE_ID_WMA,
+							    QDF_MODULE_ID_WMA,
+							    &msg))) {
+				pe_err("Not able to post WMA_UPDATE_OP_MODE message to WMA");
+				qdf_mem_free(pHtOpMode);
+				return;
+			}
+			pe_debug("Notified FW about OP mode: %d for staId=%d",
+				pHtOpMode->opMode, staId);
+
+		} else
+			pe_debug("station %d does not support HT40", staId);
+	}
+
+	return;
+}
+#endif
+
+/* -------------------------------------------------------------------- */
+/**
+ * __lim_process_report_message
+ *
+ * FUNCTION:  Processes the next received Radio Resource Management message
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+static void __lim_process_report_message(tpAniSirGlobal pMac,
+					 struct scheduler_msg *pMsg)
+{
+	switch (pMsg->type) {
+	case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
+		rrm_process_neighbor_report_req(pMac, pMsg->bodyptr);
+		break;
+	case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
+		rrm_process_beacon_report_xmit(pMac, pMsg->bodyptr);
+		break;
+	default:
+		pe_err("Invalid msg type: %d", pMsg->type);
+	}
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * lim_send_set_max_tx_power_req
+ *
+ * FUNCTION:  Send SIR_HAL_SET_MAX_TX_POWER_REQ message to change the max tx power.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param txPower txPower to be set.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+QDF_STATUS
+lim_send_set_max_tx_power_req(tpAniSirGlobal pMac, int8_t txPower,
+			      tpPESession pSessionEntry)
+{
+	tpMaxTxPowerParams pMaxTxParams = NULL;
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msgQ = {0};
+
+	if (pSessionEntry == NULL) {
+		pe_err("Invalid parameters");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pMaxTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams));
+	if (!pMaxTxParams)
+		return QDF_STATUS_E_NOMEM;
+	pMaxTxParams->power = txPower;
+	qdf_mem_copy(pMaxTxParams->bssId.bytes, pSessionEntry->bssId,
+		     QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(pMaxTxParams->selfStaMacAddr.bytes,
+			pSessionEntry->selfMacAddr,
+			QDF_MAC_ADDR_SIZE);
+
+	msgQ.type = WMA_SET_MAX_TX_POWER_REQ;
+	msgQ.bodyptr = pMaxTxParams;
+	msgQ.bodyval = 0;
+	pe_debug("Post WMA_SET_MAX_TX_POWER_REQ to WMA");
+	MTRACE(mac_trace_msg_tx(pMac, pSessionEntry->peSessionId, msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		pe_err("wma_post_ctrl_msg() failed");
+		qdf_mem_free(pMaxTxParams);
+	}
+	return retCode;
+}
+
+/**
+ * __lim_process_sme_register_mgmt_frame_req() - process sme reg mgmt frame req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process eWNI_SME_REGISTER_MGMT_FRAME_REQ message
+ * from SME. It Register this information within PE.
+ *
+ * Return: None
+ */
+static void __lim_process_sme_register_mgmt_frame_req(tpAniSirGlobal mac_ctx,
+		uint32_t *msg_buf)
+{
+	QDF_STATUS qdf_status;
+	tpSirRegisterMgmtFrame sme_req = (tpSirRegisterMgmtFrame)msg_buf;
+	struct mgmt_frm_reg_info *lim_mgmt_regn = NULL;
+	struct mgmt_frm_reg_info *next = NULL;
+	bool match = false;
+
+	pe_debug("registerFrame %d, frameType %d, matchLen %d",
+				sme_req->registerFrame, sme_req->frameType,
+				sme_req->matchLen);
+	/* First check whether entry exists already */
+	qdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
+	qdf_list_peek_front(&mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
+			    (qdf_list_node_t **) &lim_mgmt_regn);
+	qdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
+
+	while (lim_mgmt_regn != NULL) {
+		if (lim_mgmt_regn->frameType != sme_req->frameType)
+			goto skip_match;
+		if (sme_req->matchLen) {
+			if ((lim_mgmt_regn->matchLen == sme_req->matchLen) &&
+				(!qdf_mem_cmp(lim_mgmt_regn->matchData,
+					sme_req->matchData,
+					lim_mgmt_regn->matchLen))) {
+					/* found match! */
+					match = true;
+					break;
+			}
+		} else {
+			/* found match! */
+			match = true;
+			break;
+		}
+skip_match:
+		qdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
+		qdf_status = qdf_list_peek_next(
+				&mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
+				(qdf_list_node_t *)lim_mgmt_regn,
+				(qdf_list_node_t **)&next);
+		qdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
+		lim_mgmt_regn = next;
+		next = NULL;
+	}
+	if (match) {
+		qdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
+		if (QDF_STATUS_SUCCESS ==
+				qdf_list_remove_node(
+				&mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
+				(qdf_list_node_t *)lim_mgmt_regn))
+			qdf_mem_free(lim_mgmt_regn);
+		qdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
+	}
+
+	if (sme_req->registerFrame) {
+		lim_mgmt_regn =
+			qdf_mem_malloc(sizeof(struct mgmt_frm_reg_info) +
+					sme_req->matchLen);
+		if (lim_mgmt_regn != NULL) {
+			lim_mgmt_regn->frameType = sme_req->frameType;
+			lim_mgmt_regn->matchLen = sme_req->matchLen;
+			lim_mgmt_regn->sessionId = sme_req->sessionId;
+			if (sme_req->matchLen) {
+				qdf_mem_copy(lim_mgmt_regn->matchData,
+					     sme_req->matchData,
+					     sme_req->matchLen);
+			}
+			qdf_mutex_acquire(
+					&mac_ctx->lim.lim_frame_register_lock);
+			qdf_list_insert_front(&mac_ctx->lim.
+					      gLimMgmtFrameRegistratinQueue,
+					      &lim_mgmt_regn->node);
+			qdf_mutex_release(
+					&mac_ctx->lim.lim_frame_register_lock);
+		}
+	}
+	return;
+}
+
+static void
+__lim_process_sme_reset_ap_caps_change(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+	tpSirResetAPCapsChange pResetCapsChange;
+	tpPESession psessionEntry;
+	uint8_t sessionId = 0;
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	pResetCapsChange = (tpSirResetAPCapsChange) pMsgBuf;
+	psessionEntry =
+		pe_find_session_by_bssid(pMac, pResetCapsChange->bssId.bytes,
+					 &sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session does not exist for given BSSID");
+		return;
+	}
+
+	psessionEntry->limSentCapsChangeNtf = false;
+	return;
+}
+
+/**
+ * lim_register_mgmt_frame_ind_cb() - Save the Management frame
+ * indication callback in PE.
+ * @mac_ptr: Mac pointer
+ * @msg_buf: Msg pointer containing the callback
+ *
+ * This function is used save the Management frame
+ * indication callback in PE.
+ *
+ * Return: None
+ */
+static void lim_register_mgmt_frame_ind_cb(tpAniSirGlobal mac_ctx,
+							uint32_t *msg_buf)
+{
+	struct sir_sme_mgmt_frame_cb_req *sme_req =
+		(struct sir_sme_mgmt_frame_cb_req *)msg_buf;
+
+	if (NULL == msg_buf) {
+		pe_err("msg_buf is null");
+		return;
+	}
+	if (sme_req->callback)
+		mac_ctx->mgmt_frame_ind_cb =
+			(sir_mgmt_frame_ind_callback)sme_req->callback;
+	else
+		pe_err("sme_req->callback is null");
+}
+
+/**
+ *__lim_process_send_disassoc_frame: function processes disassoc frame
+ * @mac_ctx: pointer to mac context
+ * @msg_buf: message buffer
+ *
+ * function processes disassoc request received from SME
+ *
+ * return: none
+ */
+static void __lim_process_send_disassoc_frame(tpAniSirGlobal mac_ctx,
+					uint32_t *msg_buf)
+{
+	struct sme_send_disassoc_frm_req sme_send_disassoc_frame_req;
+	QDF_STATUS status;
+	tpPESession session_entry = NULL;
+	uint8_t sme_session_id;
+	uint16_t sme_trans_id;
+
+	if (msg_buf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	lim_get_session_info(mac_ctx, (uint8_t *)msg_buf, &sme_session_id,
+			&sme_trans_id);
+
+	status = lim_send_disassoc_frm_req_ser_des(mac_ctx,
+				&sme_send_disassoc_frame_req,
+				(uint8_t *)msg_buf);
+
+	if ((QDF_STATUS_E_FAILURE == status) ||
+		(lim_is_group_addr(sme_send_disassoc_frame_req.peer_mac) &&
+		!lim_is_addr_bc(sme_send_disassoc_frame_req.peer_mac))) {
+		pe_err("received invalid SME_DISASSOC_REQ message");
+		return;
+	}
+
+	session_entry = pe_find_session_by_sme_session_id(
+				mac_ctx, sme_session_id);
+	if (session_entry == NULL) {
+		pe_err("session does not exist for given bssId "MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(sme_send_disassoc_frame_req.peer_mac));
+		return;
+	}
+
+	pe_debug("msg_type->%d len->%d sess_id->%d trans_id->%d mac->"MAC_ADDRESS_STR" reason->%d wait_for_ack->%d",
+			sme_send_disassoc_frame_req.msg_type,
+			sme_send_disassoc_frame_req.length,
+			sme_send_disassoc_frame_req.session_id,
+			sme_send_disassoc_frame_req.trans_id,
+			MAC_ADDR_ARRAY(sme_send_disassoc_frame_req.peer_mac),
+			sme_send_disassoc_frame_req.reason,
+			sme_send_disassoc_frame_req.wait_for_ack);
+
+	lim_send_disassoc_mgmt_frame(mac_ctx,
+		sme_send_disassoc_frame_req.reason,
+		sme_send_disassoc_frame_req.peer_mac,
+		session_entry, sme_send_disassoc_frame_req.wait_for_ack);
+}
+
+/**
+ * lim_set_pdev_ht_ie() - sends the set HT IE req to FW
+ * @mac_ctx: Pointer to Global MAC structure
+ * @pdev_id: pdev id to set the IE.
+ * @nss: Nss values to prepare the HT IE.
+ *
+ * Prepares the HT IE with self capabilities for different
+ * Nss values and sends the set HT IE req to FW.
+ *
+ * Return: None
+ */
+static void lim_set_pdev_ht_ie(tpAniSirGlobal mac_ctx, uint8_t pdev_id,
+		uint8_t nss)
+{
+	struct set_ie_param *ie_params;
+	struct scheduler_msg msg = {0};
+	QDF_STATUS rc = QDF_STATUS_SUCCESS;
+	const uint8_t *p_ie = NULL;
+	tHtCaps *p_ht_cap;
+	int i;
+
+	for (i = 1; i <= nss; i++) {
+		ie_params = qdf_mem_malloc(sizeof(*ie_params));
+		if (!ie_params)
+			return;
+		ie_params->nss = i;
+		ie_params->pdev_id = pdev_id;
+		ie_params->ie_type = DOT11_HT_IE;
+		/* 2 for IE len and EID */
+		ie_params->ie_len = 2 + sizeof(tHtCaps);
+		ie_params->ie_ptr = qdf_mem_malloc(ie_params->ie_len);
+		if (!ie_params->ie_ptr) {
+			qdf_mem_free(ie_params);
+			return;
+		}
+		*ie_params->ie_ptr = SIR_MAC_HT_CAPABILITIES_EID;
+		*(ie_params->ie_ptr + 1) = ie_params->ie_len - 2;
+		lim_set_ht_caps(mac_ctx, NULL, ie_params->ie_ptr,
+				ie_params->ie_len);
+
+		if (NSS_1x1_MODE == i) {
+			p_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_HTCAPS,
+					ie_params->ie_ptr, ie_params->ie_len);
+			if (NULL == p_ie) {
+				qdf_mem_free(ie_params->ie_ptr);
+				qdf_mem_free(ie_params);
+				pe_err("failed to get IE ptr");
+				return;
+			}
+			p_ht_cap = (tHtCaps *)&p_ie[2];
+			p_ht_cap->supportedMCSSet[1] = 0;
+			p_ht_cap->txSTBC = 0;
+		}
+
+		msg.type = WMA_SET_PDEV_IE_REQ;
+		msg.bodyptr = ie_params;
+		msg.bodyval = 0;
+
+		rc = wma_post_ctrl_msg(mac_ctx, &msg);
+		if (rc != QDF_STATUS_SUCCESS) {
+			pe_err("wma_post_ctrl_msg() return failure");
+			qdf_mem_free(ie_params->ie_ptr);
+			qdf_mem_free(ie_params);
+			return;
+		}
+	}
+}
+
+/**
+ * lim_set_pdev_vht_ie() - sends the set VHT IE to req FW
+ * @mac_ctx: Pointer to Global MAC structure
+ * @pdev_id: pdev id to set the IE.
+ * @nss: Nss values to prepare the VHT IE.
+ *
+ * Prepares the VHT IE with self capabilities for different
+ * Nss values and sends the set VHT IE req to FW.
+ *
+ * Return: None
+ */
+static void lim_set_pdev_vht_ie(tpAniSirGlobal mac_ctx, uint8_t pdev_id,
+		uint8_t nss)
+{
+	struct set_ie_param *ie_params;
+	struct scheduler_msg msg = {0};
+	QDF_STATUS rc = QDF_STATUS_SUCCESS;
+	const uint8_t *p_ie = NULL;
+	tSirMacVHTCapabilityInfo *vht_cap;
+	int i;
+	tSirVhtMcsInfo *vht_mcs;
+
+	for (i = 1; i <= nss; i++) {
+		ie_params = qdf_mem_malloc(sizeof(*ie_params));
+		if (!ie_params)
+			return;
+		ie_params->nss = i;
+		ie_params->pdev_id = pdev_id;
+		ie_params->ie_type = DOT11_VHT_IE;
+		/* 2 for IE len and EID */
+		ie_params->ie_len = 2 + sizeof(tSirMacVHTCapabilityInfo) +
+			sizeof(tSirVhtMcsInfo);
+		ie_params->ie_ptr = qdf_mem_malloc(ie_params->ie_len);
+		if (!ie_params->ie_ptr) {
+			qdf_mem_free(ie_params);
+			return;
+		}
+		*ie_params->ie_ptr = SIR_MAC_VHT_CAPABILITIES_EID;
+		*(ie_params->ie_ptr + 1) = ie_params->ie_len - 2;
+		lim_set_vht_caps(mac_ctx, NULL, ie_params->ie_ptr,
+				ie_params->ie_len);
+
+		if (NSS_1x1_MODE == i) {
+			p_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_VHTCAPS,
+					ie_params->ie_ptr, ie_params->ie_len);
+			if (NULL == p_ie) {
+				qdf_mem_free(ie_params->ie_ptr);
+				qdf_mem_free(ie_params);
+				pe_err("failed to get IE ptr");
+				return;
+			}
+			vht_cap = (tSirMacVHTCapabilityInfo *)&p_ie[2];
+			vht_cap->txSTBC = 0;
+			vht_mcs =
+				(tSirVhtMcsInfo *)&p_ie[2 +
+				sizeof(tSirMacVHTCapabilityInfo)];
+			vht_mcs->rxMcsMap |= DISABLE_NSS2_MCS;
+			vht_mcs->rxHighest =
+				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+			vht_mcs->txMcsMap |= DISABLE_NSS2_MCS;
+			vht_mcs->txHighest =
+				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+		}
+		msg.type = WMA_SET_PDEV_IE_REQ;
+		msg.bodyptr = ie_params;
+		msg.bodyval = 0;
+
+		rc = wma_post_ctrl_msg(mac_ctx, &msg);
+		if (rc != QDF_STATUS_SUCCESS) {
+			pe_err("wma_post_ctrl_msg failure");
+			qdf_mem_free(ie_params->ie_ptr);
+			qdf_mem_free(ie_params);
+			return;
+		}
+	}
+}
+
+/**
+ * lim_process_set_vdev_ies_per_band() - process the set vdev IE req
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: Pointer to the SME message buffer
+ *
+ * This function is called by limProcessMessageQueue(). This function sets the
+ * VDEV IEs to the FW.
+ *
+ * Return: None
+ */
+static void lim_process_set_vdev_ies_per_band(tpAniSirGlobal mac_ctx,
+						uint32_t *msg_buf)
+{
+	struct sir_set_vdev_ies_per_band *p_msg =
+				(struct sir_set_vdev_ies_per_band *)msg_buf;
+
+	if (NULL == p_msg) {
+		pe_err("NULL p_msg");
+		return;
+	}
+
+	pe_debug("rcvd set vdev ie per band req vdev_id = %d",
+		p_msg->vdev_id);
+	/* intentionally using NULL here so that self capabilty are sent */
+	if (lim_send_ies_per_band(mac_ctx, NULL, p_msg->vdev_id) !=
+			QDF_STATUS_SUCCESS)
+		pe_err("Unable to send HT/VHT Cap to FW");
+}
+
+/**
+ * lim_process_set_pdev_IEs() - process the set pdev IE req
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: Pointer to the SME message buffer
+ *
+ * This function is called by limProcessMessageQueue(). This
+ * function sets the PDEV IEs to the FW.
+ *
+ * Return: None
+ */
+static void lim_process_set_pdev_IEs(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+	struct sir_set_ht_vht_cfg *ht_vht_cfg;
+
+	ht_vht_cfg = (struct sir_set_ht_vht_cfg *)msg_buf;
+
+	if (NULL == ht_vht_cfg) {
+		pe_err("NULL ht_vht_cfg");
+		return;
+	}
+
+	pe_debug("rcvd set pdev ht vht ie req with nss = %d",
+			ht_vht_cfg->nss);
+	lim_set_pdev_ht_ie(mac_ctx, ht_vht_cfg->pdev_id, ht_vht_cfg->nss);
+
+	if (IS_DOT11_MODE_VHT(ht_vht_cfg->dot11mode))
+		lim_set_pdev_vht_ie(mac_ctx, ht_vht_cfg->pdev_id,
+				ht_vht_cfg->nss);
+}
+
+/**
+ * lim_process_sme_update_access_policy_vendor_ie: function updates vendor IE
+ *
+ * access policy
+ * @mac_ctx: pointer to mac context
+ * @msg: message buffer
+ *
+ * function processes vendor IE and access policy from SME and updates PE
+ *
+ * session entry
+ *
+ * return: none
+*/
+static void lim_process_sme_update_access_policy_vendor_ie(
+						tpAniSirGlobal mac_ctx,
+						uint32_t *msg)
+{
+	struct sme_update_access_policy_vendor_ie *update_vendor_ie;
+	struct sPESession *pe_session_entry;
+	uint16_t num_bytes;
+
+	if (!msg) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	update_vendor_ie = (struct sme_update_access_policy_vendor_ie *) msg;
+	pe_session_entry = pe_find_session_by_sme_session_id(mac_ctx,
+					update_vendor_ie->sme_session_id);
+
+	if (!pe_session_entry) {
+		pe_err("Session does not exist for given sme session id(%hu)",
+			update_vendor_ie->sme_session_id);
+		return;
+	}
+	if (pe_session_entry->access_policy_vendor_ie)
+		qdf_mem_free(pe_session_entry->access_policy_vendor_ie);
+
+	num_bytes = update_vendor_ie->ie[1] + 2;
+	pe_session_entry->access_policy_vendor_ie = qdf_mem_malloc(num_bytes);
+	if (!pe_session_entry->access_policy_vendor_ie)
+		return;
+	qdf_mem_copy(pe_session_entry->access_policy_vendor_ie,
+		&update_vendor_ie->ie[0], num_bytes);
+
+	pe_session_entry->access_policy = update_vendor_ie->access_policy;
+}
+
+#ifdef CONFIG_VDEV_SM
+QDF_STATUS lim_sta_mlme_vdev_disconnect_bss(struct vdev_mlme_obj *vdev_mlme,
+					    uint16_t data_len, void *data)
+{
+	tpAniSirGlobal mac_ctx;
+	struct scheduler_msg *msg = (struct scheduler_msg *)data;
+
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac_ctx) {
+		pe_err("mac_ctx is NULL");
+		if (data)
+			qdf_mem_free(data);
+		return QDF_STATUS_E_INVAL;
+	}
+	pe_debug("VDEV Manager disconnect bss callback type:(%d)", msg->type);
+
+	switch (msg->type) {
+	case eWNI_SME_DEAUTH_REQ:
+		__lim_process_sme_deauth_req(mac_ctx,
+					     (uint32_t *)msg->bodyptr);
+		break;
+	case eWNI_SME_DISASSOC_CNF:
+	case eWNI_SME_DEAUTH_CNF:
+		__lim_process_sme_disassoc_cnf(mac_ctx,
+					       (uint32_t *)msg->bodyptr);
+		break;
+	case eWNI_SME_DISASSOC_REQ:
+		__lim_process_sme_disassoc_req(mac_ctx,
+					       (uint32_t *)msg->bodyptr);
+		break;
+	default:
+		pe_debug("Wrong message type received %d", msg->type);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+static void lim_process_sme_disassoc_cnf(tpAniSirGlobal mac_ctx,
+					 struct scheduler_msg *msg)
+{
+#ifdef CONFIG_VDEV_SM
+	tSirSmeDisassocCnf sme_disassoc_cnf;
+	tpPESession session;
+	uint8_t session_id;
+	QDF_STATUS status;
+
+	qdf_mem_copy(&sme_disassoc_cnf, msg->bodyptr,
+		     sizeof(struct sSirSmeDisassocCnf));
+
+	session = pe_find_session_by_bssid(mac_ctx,
+					   sme_disassoc_cnf.bssid.bytes,
+					   &session_id);
+
+	if (LIM_IS_STA_ROLE(session)) {
+		status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+						       WLAN_VDEV_SM_EV_DOWN,
+						       sizeof(*msg),
+						       msg);
+	} else {
+		__lim_process_sme_disassoc_cnf(mac_ctx,
+					       (uint32_t *)msg->bodyptr);
+	}
+#else
+	__lim_process_sme_disassoc_cnf(mac_ctx, (uint32_t *)msg->bodyptr);
+#endif
+}
+
+static void lim_process_sme_disassoc_req(tpAniSirGlobal mac_ctx,
+					 struct scheduler_msg *msg)
+{
+#ifdef CONFIG_VDEV_SM
+	tSirSmeDisassocReq disassoc_req;
+	tpPESession session;
+	uint8_t session_id;
+	QDF_STATUS status;
+
+	qdf_mem_copy(&disassoc_req, msg->bodyptr, sizeof(tSirSmeDisassocReq));
+
+	session = pe_find_session_by_bssid(mac_ctx,
+					   disassoc_req.bssid.bytes,
+					   &session_id);
+	if (LIM_IS_STA_ROLE(session)) {
+		status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+						       WLAN_VDEV_SM_EV_DOWN,
+						       sizeof(*msg),
+						       msg);
+	} else {
+		__lim_process_sme_disassoc_req(mac_ctx,
+					       (uint32_t *)msg->bodyptr);
+	}
+#else
+	__lim_process_sme_disassoc_req(mac_ctx, (uint32_t *)msg->bodyptr);
+#endif
+}
+
+static void lim_process_sme_deauth_req(tpAniSirGlobal mac_ctx,
+				       struct scheduler_msg *msg)
+{
+#ifdef CONFIG_VDEV_SM
+	tSirSmeDeauthReq sme_deauth_req;
+	tpPESession session;
+	uint8_t session_id;
+	QDF_STATUS status;
+
+	qdf_mem_copy(&sme_deauth_req, msg->bodyptr, sizeof(tSirSmeDeauthReq));
+
+	session = pe_find_session_by_bssid(mac_ctx,
+					   sme_deauth_req.bssid.bytes,
+					   &session_id);
+	if (LIM_IS_STA_ROLE(session)) {
+		status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+						       WLAN_VDEV_SM_EV_DOWN,
+						       sizeof(*msg),
+						       msg);
+	} else {
+		__lim_process_sme_deauth_req(mac_ctx,
+					     (uint32_t *)msg->bodyptr);
+	}
+#else
+	__lim_process_sme_deauth_req(mac_ctx, (uint32_t *)msg->bodyptr);
+#endif
+}
+
+/**
+ * lim_process_sme_req_messages()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue(). This
+ * function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac      Pointer to Global MAC structure
+ * @param  msgType   Indicates the SME message type
+ * @param  *pMsgBuf  A pointer to the SME message buffer
+ * @return Boolean - true - if pMsgBuf is consumed and can be freed.
+ *                   false - if pMsgBuf is not to be freed.
+ */
+
+bool lim_process_sme_req_messages(tpAniSirGlobal pMac,
+				  struct scheduler_msg *pMsg)
+{
+	bool bufConsumed = true;        /* Set this flag to false within case block of any following message, that doesn't want pMsgBuf to be freed. */
+	uint32_t *pMsgBuf = pMsg->bodyptr;
+
+	pe_debug("LIM Received SME Message %s(%d) Global LimSmeState:%s(%d) Global LimMlmState: %s(%d)",
+		       lim_msg_str(pMsg->type), pMsg->type,
+		       lim_sme_state_str(pMac->lim.gLimSmeState), pMac->lim.gLimSmeState,
+		       lim_mlm_state_str(pMac->lim.gLimMlmState), pMac->lim.gLimMlmState);
+
+	/* If no insert NOA required then execute the code below */
+
+	switch (pMsg->type) {
+	case eWNI_SME_SYS_READY_IND:
+		bufConsumed = __lim_process_sme_sys_ready_ind(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_START_BSS_REQ:
+		bufConsumed = __lim_process_sme_start_bss_req(pMac, pMsg);
+		break;
+
+	case eWNI_SME_CLEAR_DFS_CHANNEL_LIST:
+		__lim_process_clear_dfs_channel_list(pMac, pMsg);
+		break;
+	case eWNI_SME_JOIN_REQ:
+		__lim_process_sme_join_req(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_REASSOC_REQ:
+		__lim_process_sme_reassoc_req(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_DISASSOC_REQ:
+		lim_process_sme_disassoc_req(pMac, pMsg);
+		break;
+
+	case eWNI_SME_DISASSOC_CNF:
+	case eWNI_SME_DEAUTH_CNF:
+		lim_process_sme_disassoc_cnf(pMac, pMsg);
+		break;
+
+	case eWNI_SME_DEAUTH_REQ:
+		lim_process_sme_deauth_req(pMac, pMsg);
+		break;
+
+	case eWNI_SME_SEND_DISASSOC_FRAME:
+		__lim_process_send_disassoc_frame(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_SETCONTEXT_REQ:
+		__lim_process_sme_set_context_req(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_STOP_BSS_REQ:
+		bufConsumed = __lim_process_sme_stop_bss_req(pMac, pMsg);
+		break;
+
+	case eWNI_SME_ASSOC_CNF:
+		if (pMsg->type == eWNI_SME_ASSOC_CNF)
+			pe_debug("Received ASSOC_CNF message");
+			__lim_process_sme_assoc_cnf_new(pMac, pMsg->type,
+							pMsgBuf);
+		break;
+
+	case eWNI_SME_ADDTS_REQ:
+		pe_debug("Received ADDTS_REQ message");
+		__lim_process_sme_addts_req(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_DELTS_REQ:
+		pe_debug("Received DELTS_REQ message");
+		__lim_process_sme_delts_req(pMac, pMsgBuf);
+		break;
+
+	case SIR_LIM_ADDTS_RSP_TIMEOUT:
+		pe_debug("Received SIR_LIM_ADDTS_RSP_TIMEOUT message");
+		lim_process_sme_addts_rsp_timeout(pMac, pMsg->bodyval);
+		break;
+
+	case eWNI_SME_GET_STATISTICS_REQ:
+		__lim_process_sme_get_statistics_request(pMac, pMsgBuf);
+		/* HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false. */
+		bufConsumed = false;
+		break;
+#ifdef FEATURE_WLAN_ESE
+	case eWNI_SME_GET_TSM_STATS_REQ:
+		__lim_process_sme_get_tsm_stats_request(pMac, pMsgBuf);
+		bufConsumed = false;
+		break;
+#endif /* FEATURE_WLAN_ESE */
+	case eWNI_SME_GET_ASSOC_STAS_REQ:
+		lim_process_sme_get_assoc_sta_info(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_SESSION_UPDATE_PARAM:
+		__lim_process_sme_session_update(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_ROAM_SCAN_OFFLOAD_REQ:
+		__lim_process_roam_scan_offload_req(pMac, pMsgBuf);
+		bufConsumed = false;
+		break;
+	case eWNI_SME_ROAM_INVOKE:
+		lim_process_roam_invoke(pMac, pMsgBuf);
+		bufConsumed = false;
+		break;
+	case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
+		/* Update the beaconInterval */
+		__lim_process_sme_change_bi(pMac, pMsgBuf);
+		break;
+
+#ifdef QCA_HT_2040_COEX
+	case eWNI_SME_SET_HT_2040_MODE:
+		__lim_process_sme_set_ht2040_mode(pMac, pMsgBuf);
+		break;
+#endif
+
+	case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
+	case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
+		__lim_process_report_message(pMac, pMsg);
+		break;
+
+	case eWNI_SME_FT_PRE_AUTH_REQ:
+		bufConsumed = (bool) lim_process_ft_pre_auth_req(pMac, pMsg);
+		break;
+	case eWNI_SME_FT_UPDATE_KEY:
+		lim_process_ft_update_key(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_FT_AGGR_QOS_REQ:
+		lim_process_ft_aggr_qos_req(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
+		__lim_process_sme_register_mgmt_frame_req(pMac, pMsgBuf);
+		break;
+#ifdef FEATURE_WLAN_TDLS
+	case eWNI_SME_TDLS_SEND_MGMT_REQ:
+		lim_process_sme_tdls_mgmt_send_req(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_TDLS_ADD_STA_REQ:
+		lim_process_sme_tdls_add_sta_req(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_TDLS_DEL_STA_REQ:
+		lim_process_sme_tdls_del_sta_req(pMac, pMsgBuf);
+		break;
+#endif
+	case eWNI_SME_RESET_AP_CAPS_CHANGED:
+		__lim_process_sme_reset_ap_caps_change(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_CHANNEL_CHANGE_REQ:
+		lim_process_sme_channel_change_request(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_START_BEACON_REQ:
+		lim_process_sme_start_beacon_req(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ:
+		lim_process_sme_dfs_csa_ie_request(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_UPDATE_ADDITIONAL_IES:
+		lim_process_update_add_ies(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_MODIFY_ADDITIONAL_IES:
+		lim_process_modify_add_ies(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_SET_HW_MODE_REQ:
+		lim_process_set_hw_mode(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_NSS_UPDATE_REQ:
+		lim_process_nss_update_request(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_SET_DUAL_MAC_CFG_REQ:
+		lim_process_set_dual_mac_cfg_req(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_SET_IE_REQ:
+		lim_process_set_ie_req(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_REGISTER_MGMT_FRAME_CB:
+		lim_register_mgmt_frame_ind_cb(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_EXT_CHANGE_CHANNEL:
+		lim_process_ext_change_channel(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_SET_ANTENNA_MODE_REQ:
+		lim_process_set_antenna_mode_req(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_PDEV_SET_HT_VHT_IE:
+		lim_process_set_pdev_IEs(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_SET_VDEV_IES_PER_BAND:
+		lim_process_set_vdev_ies_per_band(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE:
+		lim_process_sme_update_access_policy_vendor_ie(pMac, pMsgBuf);
+		break;
+	case eWNI_SME_UPDATE_CONFIG:
+		lim_process_sme_update_config(pMac,
+					(struct update_config *)pMsgBuf);
+		break;
+	case eWNI_SME_SET_ADDBA_ACCEPT:
+		lim_process_sme_set_addba_accept(pMac,
+					(struct sme_addba_accept *)pMsgBuf);
+		break;
+	case eWNI_SME_UPDATE_EDCA_PROFILE:
+		lim_process_sme_update_edca_params(pMac, pMsg->bodyval);
+		break;
+	case WNI_SME_UPDATE_MU_EDCA_PARAMS:
+		lim_process_sme_update_mu_edca_params(pMac, pMsg->bodyval);
+		break;
+	default:
+		qdf_mem_free((void *)pMsg->bodyptr);
+		pMsg->bodyptr = NULL;
+		break;
+	} /* switch (msgType) */
+
+	return bufConsumed;
+} /*** end lim_process_sme_req_messages() ***/
+
+/**
+ * lim_process_sme_start_beacon_req()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue(). This
+ * function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac      Pointer to Global MAC structure
+ * @param  msgType   Indicates the SME message type
+ * @param  *pMsgBuf  A pointer to the SME message buffer
+ * @return Boolean - true - if pMsgBuf is consumed and can be freed.
+ *                   false - if pMsgBuf is not to be freed.
+ */
+static void lim_process_sme_start_beacon_req(tpAniSirGlobal pMac, uint32_t *pMsg)
+{
+	tpSirStartBeaconIndication pBeaconStartInd;
+	tpPESession psessionEntry;
+	uint8_t sessionId;      /* PE sessionID */
+
+	if (pMsg == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	pBeaconStartInd = (tpSirStartBeaconIndication) pMsg;
+	psessionEntry = pe_find_session_by_bssid(pMac,
+				pBeaconStartInd->bssid,
+				&sessionId);
+	if (psessionEntry == NULL) {
+		lim_print_mac_addr(pMac, pBeaconStartInd->bssid, LOGE);
+		pe_err("Session does not exist for given bssId");
+		return;
+	}
+
+	if (pBeaconStartInd->beaconStartStatus == true) {
+		/*
+		 * Currently this Indication comes from SAP
+		 * to start Beacon Tx on a DFS channel
+		 * since beaconing has to be done on DFS
+		 * channel only after CAC WAIT is completed.
+		 * On a DFS Channel LIM does not start beacon
+		 * Tx right after the WMA_ADD_BSS_RSP.
+		 */
+		lim_apply_configuration(pMac, psessionEntry);
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			  FL("Start Beacon with ssid %s Ch %d"),
+			  psessionEntry->ssId.ssId,
+			  psessionEntry->currentOperChannel);
+		lim_send_beacon(pMac, psessionEntry);
+		lim_enable_obss_detection_config(pMac, psessionEntry);
+		lim_send_obss_color_collision_cfg(pMac, psessionEntry,
+					OBSS_COLOR_COLLISION_DETECTION);
+	} else {
+		pe_err("Invalid Beacon Start Indication");
+		return;
+	}
+}
+
+/**
+ * lim_process_sme_channel_change_request() - process sme ch change req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process SME_CHANNEL_CHANGE_REQ message
+ *
+ * Return: None
+ */
+static void lim_process_sme_channel_change_request(tpAniSirGlobal mac_ctx,
+		uint32_t *msg_buf)
+{
+	tpSirChanChangeRequest ch_change_req;
+	tpPESession session_entry;
+	uint8_t session_id;      /* PE session_id */
+	int8_t max_tx_pwr;
+	uint32_t val = 0;
+
+	if (msg_buf == NULL) {
+		pe_err("msg_buf is NULL");
+		return;
+	}
+	ch_change_req = (tpSirChanChangeRequest)msg_buf;
+
+	max_tx_pwr = cfg_get_regulatory_max_transmit_power(mac_ctx,
+			ch_change_req->targetChannel);
+
+	if ((ch_change_req->messageType != eWNI_SME_CHANNEL_CHANGE_REQ) ||
+			(max_tx_pwr == WMA_MAX_TXPOWER_INVALID)) {
+		pe_err("Invalid Request/max_tx_pwr");
+		return;
+	}
+
+	session_entry = pe_find_session_by_bssid(mac_ctx,
+			ch_change_req->bssid, &session_id);
+	if (session_entry == NULL) {
+		lim_print_mac_addr(mac_ctx, ch_change_req->bssid, LOGE);
+		pe_err("Session does not exist for given bssId");
+		return;
+	}
+
+	if ((session_entry->currentOperChannel ==
+			ch_change_req->targetChannel) &&
+	     (session_entry->ch_width == ch_change_req->ch_width)) {
+		pe_err("Target channel and mode is same as current channel and mode channel %d and mode %d",
+		       session_entry->currentOperChannel, session_entry->ch_width);
+		return;
+	}
+
+	if (LIM_IS_AP_ROLE(session_entry))
+		session_entry->channelChangeReasonCode =
+			LIM_SWITCH_CHANNEL_SAP_DFS;
+	else
+		session_entry->channelChangeReasonCode =
+			LIM_SWITCH_CHANNEL_OPERATION;
+
+	pe_debug("switch old chnl %d to new chnl %d, ch_bw %d, nw_type %d, dot11mode %d",
+		 session_entry->currentOperChannel,
+		 ch_change_req->targetChannel,
+		 ch_change_req->ch_width,
+		 ch_change_req->nw_type,
+		 ch_change_req->dot11mode);
+
+	/* Store the New Channel Params in session_entry */
+	session_entry->ch_width = ch_change_req->ch_width;
+	session_entry->ch_center_freq_seg0 =
+		ch_change_req->center_freq_seg_0;
+	session_entry->ch_center_freq_seg1 =
+		ch_change_req->center_freq_seg_1;
+	session_entry->htSecondaryChannelOffset = ch_change_req->sec_ch_offset;
+	session_entry->htSupportedChannelWidthSet =
+		(ch_change_req->ch_width ? 1 : 0);
+	session_entry->htRecommendedTxWidthSet =
+		session_entry->htSupportedChannelWidthSet;
+	session_entry->currentOperChannel =
+		ch_change_req->targetChannel;
+	session_entry->limRFBand =
+		lim_get_rf_band(session_entry->currentOperChannel);
+	session_entry->cac_duration_ms = ch_change_req->cac_duration_ms;
+	session_entry->dfs_regdomain = ch_change_req->dfs_regdomain;
+	session_entry->maxTxPower = max_tx_pwr;
+
+	/* Update the global beacon filter */
+	lim_update_bcn_probe_filter(mac_ctx, session_entry);
+
+	/* Initialize 11h Enable Flag */
+	if (CHAN_HOP_ALL_BANDS_ENABLE ||
+	    BAND_5G == session_entry->limRFBand) {
+		if (wlan_cfg_get_int(mac_ctx, WNI_CFG_11H_ENABLED, &val) !=
+				QDF_STATUS_SUCCESS)
+			pe_err("Fail to get WNI_CFG_11H_ENABLED");
+	}
+
+	session_entry->lim11hEnable = val;
+	session_entry->dot11mode = ch_change_req->dot11mode;
+	session_entry->nwType = ch_change_req->nw_type;
+	qdf_mem_copy(&session_entry->rateSet,
+			&ch_change_req->operational_rateset,
+			sizeof(session_entry->rateSet));
+	qdf_mem_copy(&session_entry->extRateSet,
+			&ch_change_req->extended_rateset,
+			sizeof(session_entry->extRateSet));
+
+#ifdef CONFIG_VDEV_SM
+	mlme_set_chan_switch_in_progress(session_entry->vdev, true);
+	if (wlan_vdev_mlme_get_state(session_entry->vdev) ==
+	    WLAN_VDEV_S_DFS_CAC_WAIT)
+		wlan_vdev_mlme_sm_deliver_evt(session_entry->vdev,
+					      WLAN_VDEV_SM_EV_RADAR_DETECTED,
+					      sizeof(*session_entry),
+					      session_entry);
+	else
+		wlan_vdev_mlme_sm_deliver_evt(session_entry->vdev,
+					      WLAN_VDEV_SM_EV_CSA_COMPLETE,
+					      sizeof(*session_entry),
+					      session_entry);
+
+
+#else
+	lim_set_channel(mac_ctx, ch_change_req->targetChannel,
+			session_entry->ch_center_freq_seg0,
+			session_entry->ch_center_freq_seg1,
+			session_entry->ch_width,
+			max_tx_pwr, session_entry->peSessionId,
+			ch_change_req->cac_duration_ms,
+			ch_change_req->dfs_regdomain);
+#endif
+}
+
+/******************************************************************************
+* lim_start_bss_update_add_ie_buffer()
+*
+***FUNCTION:
+* This function checks the src buffer and its length and then malloc for
+* dst buffer update the same
+*
+***LOGIC:
+*
+***ASSUMPTIONS:
+*
+***NOTE:
+*
+* @param  pMac      Pointer to Global MAC structure
+* @param  **pDstData_buff  A pointer to pointer of  uint8_t dst buffer
+* @param  *pDstDataLen  A pointer to pointer of  uint16_t dst buffer length
+* @param  *pSrcData_buff  A pointer of  uint8_t  src buffer
+* @param  srcDataLen  src buffer length
+******************************************************************************/
+
+static void
+lim_start_bss_update_add_ie_buffer(tpAniSirGlobal pMac,
+				   uint8_t **pDstData_buff,
+				   uint16_t *pDstDataLen,
+				   uint8_t *pSrcData_buff, uint16_t srcDataLen)
+{
+
+	if (srcDataLen > 0 && pSrcData_buff != NULL) {
+		*pDstDataLen = srcDataLen;
+
+		*pDstData_buff = qdf_mem_malloc(*pDstDataLen);
+		if (!*pDstData_buff)
+			return;
+		qdf_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen);
+	} else {
+		*pDstData_buff = NULL;
+		*pDstDataLen = 0;
+	}
+}
+
+/******************************************************************************
+* lim_update_add_ie_buffer()
+*
+***FUNCTION:
+* This function checks the src buffer and length if src buffer length more
+* than dst buffer length then free the dst buffer and malloc for the new src
+* length, and update the dst buffer and length. But if dst buffer is bigger
+* than src buffer length then it just update the dst buffer and length
+*
+***LOGIC:
+*
+***ASSUMPTIONS:
+*
+***NOTE:
+*
+* @param  pMac      Pointer to Global MAC structure
+* @param  **pDstData_buff  A pointer to pointer of  uint8_t dst buffer
+* @param  *pDstDataLen  A pointer to pointer of  uint16_t dst buffer length
+* @param  *pSrcData_buff  A pointer of  uint8_t  src buffer
+* @param  srcDataLen  src buffer length
+******************************************************************************/
+
+static void
+lim_update_add_ie_buffer(tpAniSirGlobal pMac,
+			 uint8_t **pDstData_buff,
+			 uint16_t *pDstDataLen,
+			 uint8_t *pSrcData_buff, uint16_t srcDataLen)
+{
+
+	if (NULL == pSrcData_buff) {
+		pe_err("src buffer is null");
+		return;
+	}
+
+	if (srcDataLen > *pDstDataLen) {
+		*pDstDataLen = srcDataLen;
+		/* free old buffer */
+		qdf_mem_free(*pDstData_buff);
+		/* allocate a new */
+		*pDstData_buff = qdf_mem_malloc(*pDstDataLen);
+		if (!*pDstData_buff) {
+			*pDstDataLen = 0;
+			return;
+		}
+	}
+
+	/* copy the content of buffer into dst buffer
+	 */
+	*pDstDataLen = srcDataLen;
+	qdf_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen);
+
+}
+
+/**
+ * lim_update_ibss_prop_add_ies() - update IBSS prop IE
+ * @pMac          : Pointer to Global MAC structure
+ * @pDstData_buff : A pointer to pointer of  dst buffer
+ * @pDstDataLen  :  A pointer to pointer of  dst buffer length
+ * @pModifyIE    :  A pointer to tSirModifyIE
+ *
+ * This function replaces previous ibss prop_ie with new ibss prop_ie.
+ *
+ * Return:
+ *  True or false depending upon whether IE is updated or not
+ */
+static bool
+lim_update_ibss_prop_add_ies(tpAniSirGlobal pMac, uint8_t **pDstData_buff,
+			     uint16_t *pDstDataLen, tSirModifyIE *pModifyIE)
+{
+	int32_t oui_length;
+	uint8_t *ibss_ie = NULL;
+	uint8_t *vendor_ie;
+#define MAC_VENDOR_OUI  "\x00\x16\x32"
+#define MAC_VENDOR_SIZE 3
+
+	ibss_ie = pModifyIE->pIEBuffer;
+	oui_length = pModifyIE->oui_length;
+
+	if ((0 == oui_length) || (NULL == ibss_ie)) {
+		pe_err("Invalid set IBSS vendor IE command length %d",
+			oui_length);
+		return false;
+	}
+
+	/*
+	 * Why replace only beacon OUI data here:
+	 * 1. other ie (such as wpa) shall not be overwritten here.
+	 * 2. per spec, beacon oui ie might be set twice and original one
+	 * shall be updated.
+	 */
+	vendor_ie = (uint8_t *)wlan_get_vendor_ie_ptr_from_oui(MAC_VENDOR_OUI,
+			MAC_VENDOR_SIZE, *pDstData_buff, *pDstDataLen);
+	if (vendor_ie) {
+		QDF_ASSERT((vendor_ie[1] + 2) == pModifyIE->ieBufferlength);
+		qdf_mem_copy(vendor_ie, pModifyIE->pIEBuffer,
+				pModifyIE->ieBufferlength);
+	} else {
+		uint16_t new_length;
+		uint8_t *new_ptr;
+
+		/*
+		 * check for uint16 overflow before using sum of two numbers as
+		 * length of size to malloc
+		 */
+		if (USHRT_MAX - pModifyIE->ieBufferlength < *pDstDataLen) {
+			pe_err("U16 overflow due to %d + %d",
+				pModifyIE->ieBufferlength, *pDstDataLen);
+			return false;
+		}
+
+		new_length = pModifyIE->ieBufferlength + *pDstDataLen;
+		new_ptr = qdf_mem_malloc(new_length);
+		if (!new_ptr)
+			return false;
+		qdf_mem_copy(new_ptr, *pDstData_buff, *pDstDataLen);
+		qdf_mem_copy(&new_ptr[*pDstDataLen], pModifyIE->pIEBuffer,
+				pModifyIE->ieBufferlength);
+		qdf_mem_free(*pDstData_buff);
+		*pDstDataLen = new_length;
+		*pDstData_buff = new_ptr;
+	}
+	return true;
+}
+
+/*
+* lim_process_modify_add_ies() - process modify additional IE req.
+*
+* @mac_ctx: Pointer to Global MAC structure
+* @msg_buf: pointer to the SME message buffer
+*
+* This function update the PE buffers for additional IEs.
+*
+* Return: None
+*/
+static void lim_process_modify_add_ies(tpAniSirGlobal mac_ctx,
+		uint32_t *msg_buf)
+{
+	tpSirModifyIEsInd modify_add_ies;
+	tpPESession session_entry;
+	uint8_t session_id;
+	bool ret = false;
+	tSirAddIeParams *add_ie_params;
+
+	if (msg_buf == NULL) {
+		pe_err("msg_buf is NULL");
+		return;
+	}
+
+	modify_add_ies = (tpSirModifyIEsInd)msg_buf;
+	/* Incoming message has smeSession, use BSSID to find PE session */
+	session_entry = pe_find_session_by_bssid(mac_ctx,
+			modify_add_ies->modifyIE.bssid.bytes, &session_id);
+
+	if (NULL == session_entry) {
+		pe_err("Session not found for given bssid"
+					MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(modify_add_ies->modifyIE.bssid.bytes));
+		goto end;
+	}
+	if ((0 == modify_add_ies->modifyIE.ieBufferlength) ||
+		(0 == modify_add_ies->modifyIE.ieIDLen) ||
+		(NULL == modify_add_ies->modifyIE.pIEBuffer)) {
+		pe_err("Invalid request pIEBuffer %pK ieBufferlength %d ieIDLen %d ieID %d. update Type %d",
+				modify_add_ies->modifyIE.pIEBuffer,
+				modify_add_ies->modifyIE.ieBufferlength,
+				modify_add_ies->modifyIE.ieID,
+				modify_add_ies->modifyIE.ieIDLen,
+				modify_add_ies->updateType);
+		goto end;
+	}
+	add_ie_params = &session_entry->addIeParams;
+	switch (modify_add_ies->updateType) {
+	case eUPDATE_IE_PROBE_RESP:
+		/* Probe resp */
+		if (LIM_IS_IBSS_ROLE(session_entry)) {
+			lim_update_ibss_prop_add_ies(mac_ctx,
+				&add_ie_params->probeRespData_buff,
+				&add_ie_params->probeRespDataLen,
+				&modify_add_ies->modifyIE);
+		}
+		break;
+	case eUPDATE_IE_ASSOC_RESP:
+		/* assoc resp IE */
+		if (add_ie_params->assocRespDataLen == 0) {
+			QDF_TRACE(QDF_MODULE_ID_PE,
+					QDF_TRACE_LEVEL_ERROR, FL(
+				"assoc resp add ie not present %d"),
+				add_ie_params->assocRespDataLen);
+		}
+		/* search through the buffer and modify the IE */
+		break;
+	case eUPDATE_IE_PROBE_BCN:
+		/*probe beacon IE */
+		if (LIM_IS_IBSS_ROLE(session_entry)) {
+			ret = lim_update_ibss_prop_add_ies(mac_ctx,
+				&add_ie_params->probeRespBCNData_buff,
+				&add_ie_params->probeRespBCNDataLen,
+				&modify_add_ies->modifyIE);
+		}
+		if (ret == true && modify_add_ies->modifyIE.notify) {
+			lim_handle_param_update(mac_ctx,
+					modify_add_ies->updateType);
+		}
+		break;
+	default:
+		pe_err("unhandled buffer type %d",
+				modify_add_ies->updateType);
+		break;
+	}
+end:
+	qdf_mem_free(modify_add_ies->modifyIE.pIEBuffer);
+	modify_add_ies->modifyIE.pIEBuffer = NULL;
+}
+
+/*
+* lim_process_update_add_ies() - process additional IE update req
+*
+* @mac_ctx: Pointer to Global MAC structure
+* @msg_buf: pointer to the SME message buffer
+*
+* This function update the PE buffers for additional IEs.
+*
+* Return: None
+*/
+static void lim_process_update_add_ies(tpAniSirGlobal mac_ctx,
+		uint32_t *msg_buf)
+{
+	tpSirUpdateIEsInd update_add_ies = (tpSirUpdateIEsInd)msg_buf;
+	uint8_t session_id;
+	tpPESession session_entry;
+	tSirAddIeParams *addn_ie;
+	uint16_t new_length = 0;
+	uint8_t *new_ptr = NULL;
+	tSirUpdateIE *update_ie;
+
+	if (msg_buf == NULL) {
+		pe_err("msg_buf is NULL");
+		return;
+	}
+	update_ie = &update_add_ies->updateIE;
+	/* incoming message has smeSession, use BSSID to find PE session */
+	session_entry = pe_find_session_by_bssid(mac_ctx,
+			update_ie->bssid.bytes, &session_id);
+
+	if (NULL == session_entry) {
+		pe_debug("Session not found for given bssid"
+			 MAC_ADDRESS_STR,
+			 MAC_ADDR_ARRAY(update_ie->bssid.bytes));
+		goto end;
+	}
+	addn_ie = &session_entry->addIeParams;
+	/* if len is 0, upper layer requested freeing of buffer */
+	if (0 == update_ie->ieBufferlength) {
+		switch (update_add_ies->updateType) {
+		case eUPDATE_IE_PROBE_RESP:
+			qdf_mem_free(addn_ie->probeRespData_buff);
+			addn_ie->probeRespData_buff = NULL;
+			addn_ie->probeRespDataLen = 0;
+			break;
+		case eUPDATE_IE_ASSOC_RESP:
+			qdf_mem_free(addn_ie->assocRespData_buff);
+			addn_ie->assocRespData_buff = NULL;
+			addn_ie->assocRespDataLen = 0;
+			break;
+		case eUPDATE_IE_PROBE_BCN:
+			qdf_mem_free(addn_ie->probeRespBCNData_buff);
+			addn_ie->probeRespBCNData_buff = NULL;
+			addn_ie->probeRespBCNDataLen = 0;
+
+			if (update_ie->notify)
+				lim_handle_param_update(mac_ctx,
+						update_add_ies->updateType);
+			break;
+		default:
+			break;
+		}
+		return;
+	}
+	switch (update_add_ies->updateType) {
+	case eUPDATE_IE_PROBE_RESP:
+		if (update_ie->append) {
+			/*
+			 * In case of append, allocate new memory
+			 * with combined length.
+			 * Multiple back to back append commands
+			 * can lead to a huge length.So, check
+			 * for the validity of the length.
+			 */
+			if (addn_ie->probeRespDataLen >
+				(USHRT_MAX - update_ie->ieBufferlength)) {
+				pe_err("IE Length overflow, curr:%d, new:%d",
+					addn_ie->probeRespDataLen,
+					update_ie->ieBufferlength);
+				goto end;
+			}
+			new_length = update_ie->ieBufferlength +
+				addn_ie->probeRespDataLen;
+			new_ptr = qdf_mem_malloc(new_length);
+			if (!new_ptr)
+				goto end;
+			/* append buffer to end of local buffers */
+			qdf_mem_copy(new_ptr, addn_ie->probeRespData_buff,
+					addn_ie->probeRespDataLen);
+			qdf_mem_copy(&new_ptr[addn_ie->probeRespDataLen],
+				     update_ie->pAdditionIEBuffer,
+				     update_ie->ieBufferlength);
+			/* free old memory */
+			qdf_mem_free(addn_ie->probeRespData_buff);
+			/* adjust length accordingly */
+			addn_ie->probeRespDataLen = new_length;
+			/* save refernece of local buffer in PE session */
+			addn_ie->probeRespData_buff = new_ptr;
+			goto end;
+		}
+		lim_update_add_ie_buffer(mac_ctx, &addn_ie->probeRespData_buff,
+				&addn_ie->probeRespDataLen,
+				update_ie->pAdditionIEBuffer,
+				update_ie->ieBufferlength);
+		break;
+	case eUPDATE_IE_ASSOC_RESP:
+		/* assoc resp IE */
+		lim_update_add_ie_buffer(mac_ctx, &addn_ie->assocRespData_buff,
+				&addn_ie->assocRespDataLen,
+				update_ie->pAdditionIEBuffer,
+				update_ie->ieBufferlength);
+		break;
+	case eUPDATE_IE_PROBE_BCN:
+		/* probe resp Bcn IE */
+		lim_update_add_ie_buffer(mac_ctx,
+				&addn_ie->probeRespBCNData_buff,
+				&addn_ie->probeRespBCNDataLen,
+				update_ie->pAdditionIEBuffer,
+				update_ie->ieBufferlength);
+		if (update_ie->notify)
+			lim_handle_param_update(mac_ctx,
+					update_add_ies->updateType);
+		break;
+	default:
+		pe_err("unhandled buffer type %d", update_add_ies->updateType);
+		break;
+	}
+end:
+	qdf_mem_free(update_ie->pAdditionIEBuffer);
+	update_ie->pAdditionIEBuffer = NULL;
+}
+
+/**
+ * send_extended_chan_switch_action_frame()- function to send ECSA
+ * action frame for each sta connected to SAP/GO and AP in case of
+ * STA .
+ * @mac_ctx: pointer to global mac structure
+ * @new_channel: new channel to switch to.
+ * @ch_bandwidth: BW of channel to calculate op_class
+ * @session_entry: pe session
+ *
+ * This function is called to send ECSA frame for STA/CLI and SAP/GO.
+ *
+ * Return: void
+ */
+
+static void send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
+				uint16_t new_channel, uint8_t ch_bandwidth,
+						tpPESession session_entry)
+{
+	uint16_t op_class;
+	uint8_t switch_mode = 0, i;
+	tpDphHashNode psta;
+	uint8_t switch_count;
+
+	op_class = wlan_reg_dmn_get_opclass_from_channel(
+				mac_ctx->scan.countryCodeCurrent,
+				new_channel,
+				ch_bandwidth);
+
+	if (LIM_IS_AP_ROLE(session_entry) &&
+		(mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false))
+		switch_mode = session_entry->gLimChannelSwitch.switchMode;
+
+	switch_count = session_entry->gLimChannelSwitch.switchCount;
+
+	if (LIM_IS_AP_ROLE(session_entry)) {
+		for (i = 0; i <= mac_ctx->lim.maxStation; i++) {
+			psta =
+			  session_entry->dph.dphHashTable.pDphNodeArray + i;
+			if (psta && psta->added)
+				lim_send_extended_chan_switch_action_frame(
+					mac_ctx,
+					psta->staAddr,
+					switch_mode, op_class, new_channel,
+					switch_count, session_entry);
+		}
+	} else if (LIM_IS_STA_ROLE(session_entry)) {
+		lim_send_extended_chan_switch_action_frame(mac_ctx,
+					session_entry->bssId,
+					switch_mode, op_class, new_channel,
+					switch_count, session_entry);
+	}
+
+}
+
+void lim_send_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
+				       uint16_t new_channel,
+				       uint8_t ch_bandwidth,
+				       tpPESession session_entry)
+{
+	uint16_t op_class;
+	uint8_t switch_mode = 0, i;
+	uint8_t switch_count;
+	tpDphHashNode psta;
+	tpDphHashNode dph_node_array_ptr;
+
+	dph_node_array_ptr = session_entry->dph.dphHashTable.pDphNodeArray;
+
+	op_class = wlan_reg_dmn_get_opclass_from_channel(
+			mac_ctx->scan.countryCodeCurrent,
+			new_channel, ch_bandwidth);
+
+	if (LIM_IS_AP_ROLE(session_entry) &&
+	    (false == mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch))
+		switch_mode = session_entry->gLimChannelSwitch.switchMode;
+
+	switch_count = session_entry->gLimChannelSwitch.switchCount;
+
+	if (LIM_IS_AP_ROLE(session_entry)) {
+		for (i = 0; i < mac_ctx->lim.maxStation; i++) {
+			psta = dph_node_array_ptr + i;
+			if (!(psta && psta->added))
+				continue;
+			if (session_entry->lim_non_ecsa_cap_num == 0)
+				lim_send_extended_chan_switch_action_frame
+					(mac_ctx, psta->staAddr, switch_mode,
+					 op_class, new_channel, switch_count,
+					 session_entry);
+			else
+				lim_send_channel_switch_mgmt_frame
+					(mac_ctx, psta->staAddr, switch_mode,
+					 new_channel, switch_count,
+					 session_entry);
+		}
+	} else if (LIM_IS_STA_ROLE(session_entry)) {
+		lim_send_extended_chan_switch_action_frame
+			(mac_ctx, session_entry->bssId, switch_mode, op_class,
+			 new_channel, switch_count, session_entry);
+	}
+}
+
+/**
+ * lim_process_sme_dfs_csa_ie_request() - process sme dfs csa ie req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ * Return: None
+ */
+static void lim_process_sme_dfs_csa_ie_request(tpAniSirGlobal mac_ctx,
+		uint32_t *msg_buf)
+{
+	tpSirDfsCsaIeRequest dfs_csa_ie_req;
+	tpPESession session_entry = NULL;
+	uint8_t session_id;
+	tLimWiderBWChannelSwitchInfo *wider_bw_ch_switch;
+	enum offset_t ch_offset;
+
+	if (msg_buf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	dfs_csa_ie_req = (tSirDfsCsaIeRequest *)msg_buf;
+	session_entry = pe_find_session_by_bssid(mac_ctx,
+			dfs_csa_ie_req->bssid, &session_id);
+	if (session_entry == NULL) {
+		pe_err("Session not found for given BSSID" MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(dfs_csa_ie_req->bssid));
+		return;
+	}
+
+	if (session_entry->valid && !LIM_IS_AP_ROLE(session_entry)) {
+		pe_err("Invalid SystemRole %d",
+			GET_LIM_SYSTEM_ROLE(session_entry));
+		return;
+	}
+
+	/* target channel */
+	session_entry->gLimChannelSwitch.primaryChannel =
+		dfs_csa_ie_req->targetChannel;
+
+	/* Channel switch announcement needs to be included in beacon */
+	session_entry->dfsIncludeChanSwIe = true;
+	session_entry->gLimChannelSwitch.switchCount =
+		 dfs_csa_ie_req->ch_switch_beacon_cnt;
+	session_entry->gLimChannelSwitch.ch_width =
+				 dfs_csa_ie_req->ch_params.ch_width;
+	session_entry->gLimChannelSwitch.sec_ch_offset =
+				 dfs_csa_ie_req->ch_params.sec_ch_offset;
+	if (mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false)
+		session_entry->gLimChannelSwitch.switchMode =
+			 dfs_csa_ie_req->ch_switch_mode;
+
+	/*
+	 * Validate if SAP is operating HT or VHT mode and set the Channel
+	 * Switch Wrapper element with the Wide Band Switch subelement.
+	 */
+	if (true != session_entry->vhtCapability)
+		goto skip_vht;
+
+	/* Now encode the Wider Ch BW element depending on the ch width */
+	wider_bw_ch_switch = &session_entry->gLimWiderBWChannelSwitch;
+	switch (dfs_csa_ie_req->ch_params.ch_width) {
+	case CH_WIDTH_20MHZ:
+		/*
+		 * Wide channel BW sublement in channel wrapper element is not
+		 * required in case of 20 Mhz operation. Currently It is set
+		 * only set in case of 40/80 Mhz Operation.
+		 */
+		session_entry->dfsIncludeChanWrapperIe = false;
+		wider_bw_ch_switch->newChanWidth =
+			WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+		break;
+	case CH_WIDTH_40MHZ:
+		session_entry->dfsIncludeChanWrapperIe = false;
+		wider_bw_ch_switch->newChanWidth =
+			WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+		break;
+	case CH_WIDTH_80MHZ:
+		session_entry->dfsIncludeChanWrapperIe = true;
+		wider_bw_ch_switch->newChanWidth =
+			WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+		break;
+	case CH_WIDTH_160MHZ:
+		session_entry->dfsIncludeChanWrapperIe = true;
+		wider_bw_ch_switch->newChanWidth =
+			WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
+		break;
+	case CH_WIDTH_80P80MHZ:
+		session_entry->dfsIncludeChanWrapperIe = true;
+		wider_bw_ch_switch->newChanWidth =
+			WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ;
+		/*
+		 * This is not applicable for 20/40/80 Mhz.
+		 * Only used when we support 80+80 Mhz operation.
+		 * In case of 80+80 Mhz, this parameter indicates
+		 * center channel frequency index of 80 Mhz channel of
+		 * frequency segment 1.
+		 */
+		wider_bw_ch_switch->newCenterChanFreq1 =
+			dfs_csa_ie_req->ch_params.center_freq_seg1;
+		break;
+	default:
+		session_entry->dfsIncludeChanWrapperIe = false;
+		/*
+		 * Need to handle 80+80 Mhz Scenario. When 80+80 is supported
+		 * set the gLimWiderBWChannelSwitch.newChanWidth to 3
+		 */
+		pe_err("Invalid Channel Width");
+		break;
+	}
+	/* Fetch the center channel based on the channel width */
+	wider_bw_ch_switch->newCenterChanFreq0 =
+		dfs_csa_ie_req->ch_params.center_freq_seg0;
+skip_vht:
+	/* Send CSA IE request from here */
+	lim_send_dfs_chan_sw_ie_update(mac_ctx, session_entry);
+
+	if (dfs_csa_ie_req->ch_params.ch_width == CH_WIDTH_80MHZ)
+		ch_offset = BW80;
+	else
+		ch_offset = dfs_csa_ie_req->ch_params.sec_ch_offset;
+
+	pe_debug("IE count:%d chan:%d width:%d wrapper:%d ch_offset:%d",
+			session_entry->gLimChannelSwitch.switchCount,
+			session_entry->gLimChannelSwitch.primaryChannel,
+			session_entry->gLimChannelSwitch.ch_width,
+			session_entry->dfsIncludeChanWrapperIe,
+			ch_offset);
+
+	/* Send ECSA/CSA Action frame after updating the beacon */
+	if (CHAN_HOP_ALL_BANDS_ENABLE)
+		lim_send_chan_switch_action_frame(mac_ctx,
+			session_entry->gLimChannelSwitch.primaryChannel,
+			ch_offset, session_entry);
+	else
+		send_extended_chan_switch_action_frame(mac_ctx,
+			session_entry->gLimChannelSwitch.primaryChannel,
+			ch_offset, session_entry);
+}
+
+/**
+ * lim_process_ext_change_channel()- function to send ECSA
+ * action frame for STA/CLI .
+ * @mac_ctx: pointer to global mac structure
+ * @msg: params from sme for new channel.
+ *
+ * This function is called to send ECSA frame for STA/CLI.
+ *
+ * Return: void
+ */
+
+static void lim_process_ext_change_channel(tpAniSirGlobal mac_ctx,
+							uint32_t *msg)
+{
+	struct sir_sme_ext_cng_chan_req *ext_chng_channel =
+				(struct sir_sme_ext_cng_chan_req *) msg;
+	tpPESession session_entry = NULL;
+
+	if (NULL == msg) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	session_entry =
+		pe_find_session_by_sme_session_id(mac_ctx,
+						ext_chng_channel->session_id);
+	if (NULL == session_entry) {
+		pe_err("Session not found for given session %d",
+			ext_chng_channel->session_id);
+		return;
+	}
+	if (LIM_IS_AP_ROLE(session_entry)) {
+		pe_err("not an STA/CLI session");
+		return;
+	}
+	send_extended_chan_switch_action_frame(mac_ctx,
+			ext_chng_channel->new_channel,
+				0, session_entry);
+}
+
+/**
+ * lim_nss_update_rsp() - send NSS update response to SME
+ * @mac_ctx Pointer to Global MAC structure
+ * @vdev_id: vdev id
+ * @status: nss update status
+ *
+ * Return: None
+ */
+static void lim_nss_update_rsp(tpAniSirGlobal mac_ctx,
+			       uint8_t vdev_id, QDF_STATUS status)
+{
+	struct scheduler_msg msg = {0};
+	struct sir_bcn_update_rsp *nss_rsp;
+	QDF_STATUS qdf_status;
+
+	nss_rsp = qdf_mem_malloc(sizeof(*nss_rsp));
+	if (!nss_rsp) {
+		pe_err("AllocateMemory failed for nss_rsp");
+		return;
+	}
+
+	nss_rsp->vdev_id = vdev_id;
+	nss_rsp->status = status;
+	nss_rsp->reason = REASON_NSS_UPDATE;
+
+	msg.type = eWNI_SME_NSS_UPDATE_RSP;
+	msg.bodyptr = nss_rsp;
+	msg.bodyval = 0;
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_PE, QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &msg);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		pe_err("Failed to post eWNI_SME_NSS_UPDATE_RSP");
+		qdf_mem_free(nss_rsp);
+	}
+}
+
+void lim_send_bcn_rsp(tpAniSirGlobal mac_ctx, tpSendbeaconParams rsp)
+{
+	if (!rsp) {
+		pe_err("rsp is NULL");
+		return;
+	}
+
+	pe_debug("Send beacon resp status %d for reason %d",
+		 rsp->status, rsp->reason);
+
+	if (rsp->reason == REASON_NSS_UPDATE)
+		lim_nss_update_rsp(mac_ctx, rsp->vdev_id, rsp->status);
+}
+
+/**
+ * lim_process_nss_update_request() - process sme nss update req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ * Return: None
+ */
+static void lim_process_nss_update_request(tpAniSirGlobal mac_ctx,
+		uint32_t *msg_buf)
+{
+	struct sir_nss_update_request *nss_update_req_ptr;
+	tpPESession session_entry = NULL;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint8_t vdev_id;
+
+	if (!msg_buf) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	nss_update_req_ptr = (struct sir_nss_update_request *)msg_buf;
+	vdev_id = nss_update_req_ptr->vdev_id;
+	session_entry = pe_find_session_by_sme_session_id(mac_ctx,
+				nss_update_req_ptr->vdev_id);
+	if (!session_entry) {
+		pe_err("Session not found for given session_id %d",
+			nss_update_req_ptr->vdev_id);
+		goto end;
+	}
+
+	if (session_entry->valid && !LIM_IS_AP_ROLE(session_entry)) {
+		pe_err("Invalid SystemRole %d",
+			GET_LIM_SYSTEM_ROLE(session_entry));
+		goto end;
+	}
+
+	/* populate nss field in the beacon */
+	session_entry->gLimOperatingMode.present = 1;
+	session_entry->gLimOperatingMode.rxNSS = nss_update_req_ptr->new_nss;
+	session_entry->gLimOperatingMode.chanWidth = session_entry->ch_width;
+
+	if ((nss_update_req_ptr->new_nss == NSS_1x1_MODE) &&
+			(session_entry->ch_width > CH_WIDTH_80MHZ))
+		session_entry->gLimOperatingMode.chanWidth = CH_WIDTH_80MHZ;
+
+	pe_debug("ch width %d Rx NSS %d",
+		 session_entry->gLimOperatingMode.chanWidth,
+		 session_entry->gLimOperatingMode.rxNSS);
+
+	/* Send nss update request from here */
+	status = sch_set_fixed_beacon_fields(mac_ctx, session_entry);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("Unable to set op mode IE in beacon");
+		goto end;
+	}
+
+	status = lim_send_beacon_ind(mac_ctx, session_entry, REASON_NSS_UPDATE);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return;
+
+	pe_err("Unable to send beacon");
+end:
+	/*
+	 * send resp only in case of failure,
+	 * success case response will be from wma.
+	 */
+	lim_nss_update_rsp(mac_ctx, vdev_id, status);
+}
+
+/**
+ * lim_process_set_ie_req() - process sme set IE request
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ * Return: None
+ */
+static void lim_process_set_ie_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+	struct send_extcap_ie *msg;
+	QDF_STATUS status;
+
+	if (msg_buf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	msg = (struct send_extcap_ie *)msg_buf;
+	status = lim_send_ext_cap_ie(mac_ctx, msg->session_id, NULL, false);
+	if (QDF_STATUS_SUCCESS != status)
+		pe_err("Unable to send ExtCap to FW");
+
+}
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+
+/**
+ * obss_color_collision_process_color_disable() - Disable bss color
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session: pointer to session
+ *
+ * This function will disbale bss color.
+ *
+ * Return: None
+ */
+static void obss_color_collision_process_color_disable(tpAniSirGlobal mac_ctx,
+						       tpPESession session)
+{
+	tUpdateBeaconParams beacon_params;
+
+	if (!session) {
+		pe_err("Invalid session");
+		return;
+	}
+
+	if (session->valid && !LIM_IS_AP_ROLE(session)) {
+		pe_err("Invalid SystemRole %d",
+		       GET_LIM_SYSTEM_ROLE(session));
+		return;
+	}
+
+	if (session->bss_color_changing == 1) {
+		pe_warn("%d: color change in progress", session->smeSessionId);
+		/* Continue color collision detection */
+		lim_send_obss_color_collision_cfg(mac_ctx, session,
+				OBSS_COLOR_COLLISION_DETECTION);
+		return;
+	}
+
+	if (session->he_op.bss_col_disabled == 1) {
+		pe_warn("%d: bss color already disabled",
+			session->smeSessionId);
+		/* Continue free color detection */
+		lim_send_obss_color_collision_cfg(mac_ctx, session,
+				OBSS_COLOR_FREE_SLOT_AVAILABLE);
+		return;
+	}
+
+	qdf_mem_zero(&beacon_params, sizeof(beacon_params));
+	beacon_params.paramChangeBitmap |= PARAM_BSS_COLOR_CHANGED;
+	session->he_op.bss_col_disabled = 1;
+	beacon_params.bss_color_disabled = 1;
+	beacon_params.bss_color = session->he_op.bss_color;
+
+	if (sch_set_fixed_beacon_fields(mac_ctx, session) !=
+	    QDF_STATUS_SUCCESS) {
+		pe_err("Unable to set op mode IE in beacon");
+		return;
+	}
+
+	lim_send_beacon_params(mac_ctx, &beacon_params, session);
+	lim_send_obss_color_collision_cfg(mac_ctx, session,
+					  OBSS_COLOR_FREE_SLOT_AVAILABLE);
+}
+
+/**
+ * obss_color_collision_process_color_change() - Process bss color change
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session: pointer to session
+ * @obss_color_info: obss color collision/free slot indication info
+ *
+ * This function selects new color ib case of bss color collision.
+ *
+ * Return: None
+ */
+static void obss_color_collision_process_color_change(tpAniSirGlobal mac_ctx,
+		tpPESession session,
+		struct wmi_obss_color_collision_info *obss_color_info)
+{
+	int i, num_bss_color = 0;
+	uint32_t bss_color_bitmap;
+	uint8_t bss_color_index_array[MAX_BSS_COLOR_VALUE];
+	uint32_t rand_byte = 0;
+	struct sir_set_he_bss_color he_bss_color;
+	bool is_color_collision = false;
+
+
+	if (session->bss_color_changing == 1) {
+		pe_err("%d: color change in progress", session->smeSessionId);
+		return;
+	}
+
+	if (!session->he_op.bss_col_disabled) {
+		if (session->he_op.bss_color < 32)
+			is_color_collision = (obss_color_info->
+					     obss_color_bitmap_bit0to31 >>
+					     session->he_op.bss_color) & 0x01;
+		else
+			is_color_collision = (obss_color_info->
+					     obss_color_bitmap_bit32to63 >>
+					     (session->he_op.bss_color -
+					      32)) & 0x01;
+		if (!is_color_collision) {
+			pe_err("%d: color collision not found, curr_color: %d",
+			       session->smeSessionId,
+			       session->he_op.bss_color);
+			return;
+		}
+	}
+
+	bss_color_bitmap = obss_color_info->obss_color_bitmap_bit0to31;
+
+	/* Skip color zero */
+	bss_color_bitmap = bss_color_bitmap >> 1;
+	for (i = 0; (i < 31) && (num_bss_color < MAX_BSS_COLOR_VALUE); i++) {
+		if (!(bss_color_bitmap & 0x01)) {
+			bss_color_index_array[num_bss_color] = i + 1;
+			num_bss_color++;
+		}
+		bss_color_bitmap = bss_color_bitmap >> 1;
+	}
+
+	bss_color_bitmap = obss_color_info->obss_color_bitmap_bit32to63;
+	for (i = 0; (i < 32) && (num_bss_color < MAX_BSS_COLOR_VALUE); i++) {
+		if (!(bss_color_bitmap & 0x01)) {
+			bss_color_index_array[num_bss_color] = i + 32;
+			num_bss_color++;
+		}
+		bss_color_bitmap = bss_color_bitmap >> 1;
+	}
+
+	if (num_bss_color) {
+		qdf_get_random_bytes((void *) &rand_byte, 1);
+		i = (rand_byte + qdf_mc_timer_get_system_ticks()) %
+		    num_bss_color;
+		pe_debug("New bss color = %d", bss_color_index_array[i]);
+		he_bss_color.session_id = obss_color_info->vdev_id;
+		he_bss_color.bss_color = bss_color_index_array[i];
+		lim_process_set_he_bss_color(mac_ctx,
+					     (uint32_t *)&he_bss_color);
+	} else {
+		pe_err("Unable to find bss color from bitmasp");
+		if (obss_color_info->evt_type ==
+		    OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY &&
+		    session->obss_color_collision_dec_evt ==
+		    OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY)
+			/* In dot11BSSColorCollisionAPPeriod and
+			 * timer expired, time to disable bss color.
+			 */
+			obss_color_collision_process_color_disable(mac_ctx,
+								   session);
+		else
+			/*
+			 * Enter dot11BSSColorCollisionAPPeriod period.
+			 */
+			lim_send_obss_color_collision_cfg(mac_ctx, session,
+					OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY);
+	}
+}
+
+void lim_process_set_he_bss_color(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+	struct sir_set_he_bss_color *bss_color;
+	tpPESession session_entry = NULL;
+	tUpdateBeaconParams beacon_params;
+
+	if (!msg_buf) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	bss_color = (struct sir_set_he_bss_color *)msg_buf;
+	session_entry = pe_find_session_by_sme_session_id(mac_ctx,
+				bss_color->session_id);
+	if (!session_entry) {
+		pe_err("Session not found for given session_id %d",
+			bss_color->session_id);
+		return;
+	}
+
+	if (session_entry->valid && !LIM_IS_AP_ROLE(session_entry)) {
+		pe_err("Invalid SystemRole %d",
+			GET_LIM_SYSTEM_ROLE(session_entry));
+		return;
+	}
+
+	if (bss_color->bss_color == session_entry->he_op.bss_color) {
+		pe_err("No change in  BSS color, current BSS color %d",
+			bss_color->bss_color);
+		return;
+	}
+	qdf_mem_zero(&beacon_params, sizeof(beacon_params));
+	beacon_params.paramChangeBitmap |= PARAM_BSS_COLOR_CHANGED;
+	session_entry->he_op.bss_col_disabled = 1;
+	session_entry->he_bss_color_change.countdown =
+		BSS_COLOR_SWITCH_COUNTDOWN;
+	session_entry->he_bss_color_change.new_color = bss_color->bss_color;
+	beacon_params.bss_color_disabled = 1;
+	beacon_params.bss_color = session_entry->he_op.bss_color;
+	session_entry->bss_color_changing = 1;
+
+	if (sch_set_fixed_beacon_fields(mac_ctx, session_entry) !=
+			QDF_STATUS_SUCCESS) {
+		pe_err("Unable to set op mode IE in beacon");
+		return;
+	}
+
+	lim_send_beacon_params(mac_ctx, &beacon_params, session_entry);
+	lim_send_obss_color_collision_cfg(mac_ctx, session_entry,
+			OBSS_COLOR_COLLISION_DETECTION_DISABLE);
+}
+
+void lim_send_obss_color_collision_cfg(tpAniSirGlobal mac_ctx,
+				       tpPESession session,
+				       enum wmi_obss_color_collision_evt_type
+				       event_type)
+{
+	struct wmi_obss_color_collision_cfg_param *cfg_param;
+	struct scheduler_msg msg = {0};
+
+	if (!session) {
+		pe_err("Invalid session");
+		return;
+	}
+
+	if (!session->he_capable ||
+	    !session->is_session_obss_color_collision_det_enabled) {
+		pe_debug("%d: obss color det not enabled, he_cap:%d, sup:%d:%d",
+			 session->smeSessionId, session->he_capable,
+			 session->is_session_obss_color_collision_det_enabled,
+			 mac_ctx->lim.global_obss_color_collision_det_offload);
+		return;
+	}
+
+	cfg_param = qdf_mem_malloc(sizeof(*cfg_param));
+	if (!cfg_param)
+		return;
+
+	pe_debug("%d: sending event:%d", session->smeSessionId, event_type);
+	qdf_mem_zero(cfg_param, sizeof(*cfg_param));
+	cfg_param->vdev_id = session->smeSessionId;
+	cfg_param->evt_type = event_type;
+	if (LIM_IS_AP_ROLE(session))
+		cfg_param->detection_period_ms =
+			OBSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS;
+	else
+		cfg_param->detection_period_ms =
+			OBSS_COLOR_COLLISION_DETECTION_STA_PERIOD_MS;
+
+	cfg_param->scan_period_ms = OBSS_COLOR_COLLISION_SCAN_PERIOD_MS;
+	if (event_type == OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY)
+		cfg_param->free_slot_expiry_time_ms =
+			OBSS_COLOR_COLLISION_FREE_SLOT_EXPIRY_MS;
+
+	msg.type = WMA_OBSS_COLOR_COLLISION_REQ;
+	msg.bodyptr = cfg_param;
+	msg.reserved = 0;
+
+	if (QDF_IS_STATUS_ERROR(scheduler_post_message(QDF_MODULE_ID_PE,
+						       QDF_MODULE_ID_WMA,
+						       QDF_MODULE_ID_WMA,
+						       &msg))) {
+		pe_err("Failed to post WMA_OBSS_COLOR_COLLISION_REQ to WMA");
+		qdf_mem_free(cfg_param);
+	} else {
+		session->obss_color_collision_dec_evt = event_type;
+	}
+}
+
+void lim_process_obss_color_collision_info(tpAniSirGlobal mac_ctx,
+					   uint32_t *msg_buf)
+{
+	struct wmi_obss_color_collision_info *obss_color_info;
+	tpPESession session;
+
+	if (!msg_buf) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	obss_color_info = (struct wmi_obss_color_collision_info *)msg_buf;
+	session = pe_find_session_by_sme_session_id(mac_ctx,
+						    obss_color_info->vdev_id);
+	if (!session) {
+		pe_err("Session not found for given session_id %d",
+			obss_color_info->vdev_id);
+		return;
+	}
+
+	pe_debug("vdev_id:%d, evt:%d:%d, 0to31:0x%x, 32to63:0x%x, cap:%d:%d:%d",
+		 obss_color_info->vdev_id,
+		 obss_color_info->evt_type,
+		 session->obss_color_collision_dec_evt,
+		 obss_color_info->obss_color_bitmap_bit0to31,
+		 obss_color_info->obss_color_bitmap_bit32to63,
+		 session->he_capable,
+		 session->is_session_obss_color_collision_det_enabled,
+		 mac_ctx->lim.global_obss_color_collision_det_offload);
+
+	if (!session->he_capable ||
+	    !session->is_session_obss_color_collision_det_enabled) {
+		return;
+	}
+
+	switch (obss_color_info->evt_type) {
+	case OBSS_COLOR_COLLISION_DETECTION_DISABLE:
+		pe_err("%d: FW disabled obss color det. he_cap:%d, sup:%d:%d",
+		       session->smeSessionId, session->he_capable,
+		       session->is_session_obss_color_collision_det_enabled,
+		       mac_ctx->lim.global_obss_color_collision_det_offload);
+		session->is_session_obss_color_collision_det_enabled = false;
+		return;
+	case OBSS_COLOR_FREE_SLOT_AVAILABLE:
+	case OBSS_COLOR_COLLISION_DETECTION:
+	case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
+		if (session->valid && !LIM_IS_AP_ROLE(session)) {
+			pe_debug("Invalid System Role %d",
+				 GET_LIM_SYSTEM_ROLE(session));
+			return;
+		}
+
+		if (session->obss_color_collision_dec_evt !=
+		    obss_color_info->evt_type) {
+			pe_debug("%d: Wrong event: %d, skiping",
+				 obss_color_info->vdev_id,
+				 obss_color_info->evt_type);
+			return;
+		}
+		obss_color_collision_process_color_change(mac_ctx, session,
+							  obss_color_info);
+		break;
+	default:
+		pe_err("%d: Invalid event type %d",
+		       obss_color_info->vdev_id, obss_color_info->evt_type);
+		return;
+	}
+}
+#endif
+
+#ifdef CONFIG_VDEV_SM
+void lim_send_csa_restart_req(tpAniSirGlobal mac_ctx, uint8_t vdev_id)
+{
+	tpPESession session;
+
+	session = pe_find_session_by_sme_session_id(mac_ctx, vdev_id);
+
+	if (!session) {
+		pe_err("session not found for vdev id %d", vdev_id);
+		return;
+	}
+
+	wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+				      WLAN_VDEV_SM_EV_CSA_RESTART,
+				      sizeof(*session), session);
+}
+#endif
diff --git a/core/mac/src/pe/lim/lim_process_tdls.c b/core/mac/src/pe/lim/lim_process_tdls.c
new file mode 100644
index 0000000..81b59f0
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_tdls.c
@@ -0,0 +1,3302 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*===========================================================================
+ * lim_process_tdls.c
+ * OVERVIEW:
+ *
+ * DEPENDENCIES:
+ *
+ * Are listed for each API below.
+ * ===========================================================================*/
+
+/*===========================================================================
+
+ *                      EDIT HISTORY FOR FILE
+
+ *  This section contains comments describing changes made to the module.
+ *  Notice that changes are listed in reverse chronological order.
+
+ *  $Header$$DateTime$$Author$
+
+ *  when        who     what, where, why
+ *  ----------    ---    ------------------------------------------------------
+ *  05/05/2010   Ashwani    Initial Creation, added TDLS action frame
+ *  functionality,TDLS message exchange with SME..etc..
+
+   ===========================================================================*/
+
+/**
+ * \file lim_process_tdls.c
+ *
+ * \brief Code for preparing,processing and sending 802.11z action frames
+ *
+ */
+
+#ifdef FEATURE_WLAN_TDLS
+
+#include "sir_api.h"
+#include "ani_global.h"
+#include "sir_mac_prot_def.h"
+#include "cfg_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_security_utils.h"
+#include "dot11f.h"
+#include "lim_sta_hash_api.h"
+#include "sch_api.h"
+#include "lim_send_messages.h"
+#include "utils_parser.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "dph_hash_table.h"
+#include "wma_types.h"
+#include "cds_regdomain.h"
+#include "cds_utils.h"
+#include "wlan_reg_services_api.h"
+#include "wlan_tdls_tgt_api.h"
+#include "wlan_mlme_public_struct.h"
+#include "wlan_mlme_api.h"
+
+/* define NO_PAD_TDLS_MIN_8023_SIZE to NOT padding: See CR#447630
+   There was IOT issue with cisco 1252 open mode, where it pads
+   discovery req/teardown frame with some junk value up to min size.
+   To avoid this issue, we pad QCOM_VENDOR_IE.
+   If there is other IOT issue because of this bandage, define NO_PAD...
+ */
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+#define MIN_IEEE_8023_SIZE              46
+#define MIN_VENDOR_SPECIFIC_IE_SIZE     5
+#endif
+
+static QDF_STATUS lim_tdls_setup_add_sta(tpAniSirGlobal pMac,
+		tSirTdlsAddStaReq * pAddStaReq, tpPESession psessionEntry);
+
+/*
+ * TDLS data frames will go out/come in as non-qos data.
+ * so, eth_890d_header will be aligned access..
+ */
+static const uint8_t eth_890d_header[] = {
+	0xaa, 0xaa, 0x03, 0x00,
+	0x00, 0x00, 0x89, 0x0d,
+};
+
+/*
+ * type of links used in TDLS
+ */
+enum tdlsLinks {
+	TDLS_LINK_AP,
+	TDLS_LINK_DIRECT
+} e_tdls_link;
+
+/*
+ * node status in node searching
+ */
+enum tdlsLinkNodeStatus {
+	TDLS_NODE_NOT_FOUND,
+	TDLS_NODE_FOUND
+} e_tdls_link_node_status;
+
+enum tdlsReqType {
+	TDLS_INITIATOR,
+	TDLS_RESPONDER
+} e_tdls_req_type;
+
+typedef enum tdlsLinkSetupStatus {
+	TDLS_SETUP_STATUS_SUCCESS = 0,
+	TDLS_SETUP_STATUS_FAILURE = 37
+} etdlsLinkSetupStatus;
+
+/* These maps to Kernel TDLS peer capability
+ * flags and should get changed as and when necessary
+ */
+enum tdls_peer_capability {
+	TDLS_PEER_HT_CAP = 0,
+	TDLS_PEER_VHT_CAP = 1,
+	TDLS_PEER_WMM_CAP = 2
+} e_tdls_peer_capability;
+
+/* some local defines */
+#define LINK_IDEN_ADDR_OFFSET(x) (&x.LinkIdentifier)
+#define PTI_LINK_IDEN_OFFSET     (5)
+#define PTI_BUF_STATUS_OFFSET    (25)
+
+/* TODO, Move this parameters to configuration */
+#define PEER_PSM_SUPPORT          (0)
+#define TDLS_SUPPORT              (1)
+#define TDLS_PROHIBITED           (0)
+#define TDLS_CH_SWITCH_PROHIBITED (1)
+/** @brief Set bit manipulation macro */
+#define SET_BIT(value, mask)       ((value) |= (1 << (mask)))
+/** @brief Clear bit manipulation macro */
+#define CLEAR_BIT(value, mask)     ((value) &= ~(1 << (mask)))
+/** @brief Check bit manipulation macro */
+#define CHECK_BIT(value, mask)    ((value) & (1 << (mask)))
+
+#define SET_PEER_AID_BITMAP(peer_bitmap, aid) \
+	do { \
+	if ((aid) < (sizeof(uint32_t) << 3)) \
+		SET_BIT(peer_bitmap[0], (aid));	\
+	else if ((aid) < (sizeof(uint32_t) << 4)) \
+		SET_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
+	} while (0);
+
+#define CLEAR_PEER_AID_BITMAP(peer_bitmap, aid)	\
+	do { \
+	if ((aid) < (sizeof(uint32_t) << 3)) \
+		CLEAR_BIT(peer_bitmap[0], (aid)); \
+	else if ((aid) < (sizeof(uint32_t) << 4)) \
+		CLEAR_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
+	} while (0);
+
+#ifdef FEATURE_WLAN_TDLS
+#define WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT         (800)
+#define WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT         (200)
+#endif
+
+#define IS_QOS_ENABLED(psessionEntry) ((((psessionEntry)->limQosEnabled) && \
+					SIR_MAC_GET_QOS((psessionEntry)->limCurrentBssCaps)) ||	\
+				       (((psessionEntry)->limWmeEnabled) && \
+					LIM_BSS_CAPS_GET(WME, (psessionEntry)->limCurrentBssQosCaps)))
+
+#define TID_AC_VI                  4
+#define TID_AC_BK                  1
+
+static const uint8_t *lim_trace_tdls_action_string(uint8_t tdlsActionCode)
+{
+	switch (tdlsActionCode) {
+		CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_REQ);
+		CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_RSP);
+		CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_CNF);
+		CASE_RETURN_STRING(SIR_MAC_TDLS_TEARDOWN);
+		CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_IND);
+		CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_REQ);
+		CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_RSP);
+		CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_RSP);
+		CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_REQ);
+		CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_RSP);
+	}
+	return (const uint8_t *)"UNKNOWN";
+}
+
+/*
+ * initialize TDLS setup list and related data structures.
+ */
+void lim_init_tdls_data(tpAniSirGlobal pMac, tpPESession pSessionEntry)
+{
+	lim_init_peer_idxpool(pMac, pSessionEntry);
+
+	return;
+}
+
+static void populate_dot11f_tdls_offchannel_params(
+				tpAniSirGlobal pMac,
+				tpPESession psessionEntry,
+				tDot11fIESuppChannels *suppChannels,
+				tDot11fIESuppOperatingClasses *suppOperClasses)
+{
+	uint32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+	uint8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	uint8_t i;
+	uint8_t valid_count = 0;
+	uint8_t chanOffset;
+	uint8_t op_class;
+	uint8_t numClasses;
+	uint8_t classes[REG_MAX_SUPP_OPER_CLASSES];
+	uint32_t band;
+	uint8_t nss_2g;
+	uint8_t nss_5g;
+
+	if (wlan_cfg_get_str(pMac, WNI_CFG_VALID_CHANNEL_LIST,
+			     validChan, &numChans) != QDF_STATUS_SUCCESS) {
+		/**
+		 * Could not get Valid channel list from CFG.
+		 * Log error.
+		 */
+		pe_err("could not retrieve Valid channel list");
+		return;
+	}
+
+	if (IS_5G_CH(psessionEntry->currentOperChannel))
+		band = BAND_5G;
+	else
+		band = BAND_2G;
+
+	nss_5g = QDF_MIN(pMac->vdev_type_nss_5g.tdls,
+			 pMac->user_configured_nss);
+	nss_2g = QDF_MIN(pMac->vdev_type_nss_2g.tdls,
+			 pMac->user_configured_nss);
+
+	/* validating the channel list for DFS and 2G channels */
+	for (i = 0U; i < numChans; i++) {
+		if ((band == BAND_5G) &&
+		    (NSS_2x2_MODE == nss_5g) &&
+		    (NSS_1x1_MODE == nss_2g) &&
+		    (wlan_reg_is_dfs_ch(pMac->pdev, validChan[i]))) {
+			pe_debug("skipping channel: %d, nss_5g: %d, nss_2g: %d",
+				validChan[i], nss_5g, nss_2g);
+			continue;
+		} else {
+			if (wlan_reg_is_dsrc_chan(pMac->pdev, validChan[i])) {
+				pe_debug("skipping channel: %d from the valid channel list",
+					validChan[i]);
+				continue;
+			}
+		}
+
+		if (valid_count >= ARRAY_SIZE(suppChannels->bands))
+			break;
+		suppChannels->bands[valid_count][0] = validChan[i];
+		suppChannels->bands[valid_count][1] = 1;
+		valid_count++;
+	}
+
+	suppChannels->num_bands = valid_count;
+	suppChannels->present = 1;
+
+	/* find channel offset and get op class for current operating channel */
+	switch (psessionEntry->htSecondaryChannelOffset) {
+	case PHY_SINGLE_CHANNEL_CENTERED:
+		chanOffset = BW20;
+		break;
+
+	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+		chanOffset = BW40_LOW_PRIMARY;
+		break;
+
+	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+		chanOffset = BW40_HIGH_PRIMARY;
+		break;
+
+	default:
+		chanOffset = BWALL;
+		break;
+	}
+
+	op_class = wlan_reg_dmn_get_opclass_from_channel(
+		pMac->scan.countryCodeCurrent,
+		psessionEntry->currentOperChannel,
+		chanOffset);
+
+	pe_debug("countryCodeCurrent: %s, currentOperChannel: %d, htSecondaryChannelOffset: %d, chanOffset: %d op class: %d",
+			pMac->scan.countryCodeCurrent,
+			psessionEntry->currentOperChannel,
+			psessionEntry->htSecondaryChannelOffset,
+			chanOffset, op_class);
+	suppOperClasses->present = 1;
+	suppOperClasses->classes[0] = op_class;
+
+	wlan_reg_dmn_get_curr_opclasses(&numClasses, &classes[0]);
+
+	for (i = 0; i < numClasses; i++)
+		suppOperClasses->classes[i + 1] = classes[i];
+
+	/* add one for present operating class, added in the beginning */
+	suppOperClasses->num_classes = numClasses + 1;
+
+	return;
+}
+
+/*
+ * FUNCTION: Populate Link Identifier element IE
+ *
+ */
+
+static void populate_dot11f_link_iden(tpAniSirGlobal pMac,
+				      tpPESession psessionEntry,
+				      tDot11fIELinkIdentifier *linkIden,
+				      struct qdf_mac_addr peer_mac,
+				      uint8_t reqType)
+{
+	uint8_t *initStaAddr = NULL;
+	uint8_t *respStaAddr = NULL;
+
+	(reqType == TDLS_INITIATOR) ? ((initStaAddr = linkIden->InitStaAddr),
+				       (respStaAddr = linkIden->RespStaAddr))
+	: ((respStaAddr = linkIden->InitStaAddr),
+	   (initStaAddr = linkIden->RespStaAddr));
+	qdf_mem_copy((uint8_t *) linkIden->bssid,
+		     (uint8_t *) psessionEntry->bssId, QDF_MAC_ADDR_SIZE);
+
+	qdf_mem_copy((uint8_t *) initStaAddr,
+		     psessionEntry->selfMacAddr, QDF_MAC_ADDR_SIZE);
+
+	qdf_mem_copy((uint8_t *) respStaAddr, (uint8_t *) peer_mac.bytes,
+		     QDF_MAC_ADDR_SIZE);
+
+	linkIden->present = 1;
+	return;
+
+}
+
+static void populate_dot11f_tdls_ext_capability(tpAniSirGlobal pMac,
+						tpPESession psessionEntry,
+						tDot11fIEExtCap *extCapability)
+{
+	struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)extCapability->bytes;
+
+	p_ext_cap->tdls_peer_psm_supp = PEER_PSM_SUPPORT;
+	p_ext_cap->tdls_peer_uapsd_buffer_sta = pMac->lim.gLimTDLSBufStaEnabled;
+
+	/*
+	 * Set TDLS channel switching bits only if offchannel is enabled
+	 * and TDLS Channel Switching is not prohibited by AP in ExtCap
+	 * IE in assoc/re-assoc response.
+	 */
+	if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
+	    (!psessionEntry->tdls_chan_swit_prohibited)) {
+		p_ext_cap->tdls_channel_switching = 1;
+		p_ext_cap->tdls_chan_swit_prohibited = 0;
+	} else {
+	    p_ext_cap->tdls_channel_switching = 0;
+	    p_ext_cap->tdls_chan_swit_prohibited = TDLS_CH_SWITCH_PROHIBITED;
+	}
+	p_ext_cap->tdls_support = TDLS_SUPPORT;
+	p_ext_cap->tdls_prohibited = TDLS_PROHIBITED;
+
+	extCapability->present = 1;
+	extCapability->num_bytes = lim_compute_ext_cap_ie_length(extCapability);
+
+	return;
+}
+
+/*
+ * prepare TDLS frame header, it includes
+ * |             |              |                |
+ * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD
+ * |             |              |                |
+ */
+static uint32_t lim_prepare_tdls_frame_header(tpAniSirGlobal pMac, uint8_t *pFrame,
+					      tDot11fIELinkIdentifier *link_iden,
+					      uint8_t tdlsLinkType, uint8_t reqType,
+					      uint8_t tid,
+					      tpPESession psessionEntry)
+{
+	tpSirMacDataHdr3a pMacHdr;
+	uint32_t header_offset = 0;
+	uint8_t *addr1 = NULL;
+	uint8_t *addr3 = NULL;
+	uint8_t toDs = (tdlsLinkType == TDLS_LINK_AP)
+		       ? ANI_TXDIR_TODS : ANI_TXDIR_IBSS;
+	uint8_t *peerMac = (reqType == TDLS_INITIATOR)
+			   ? link_iden->RespStaAddr : link_iden->InitStaAddr;
+	uint8_t *staMac = (reqType == TDLS_INITIATOR)
+			  ? link_iden->InitStaAddr : link_iden->RespStaAddr;
+	tpDphHashNode sta_ds;
+	uint16_t aid = 0;
+	uint8_t qos_mode = 0;
+
+	pMacHdr = (tpSirMacDataHdr3a) (pFrame);
+
+	/*
+	 * if TDLS frame goes through the AP link, it follows normal address
+	 * pattern, if TDLS frame goes thorugh the direct link, then
+	 * A1--> Peer STA addr, A2-->Self STA address, A3--> BSSID
+	 */
+	(tdlsLinkType == TDLS_LINK_AP) ? ((addr1 = (link_iden->bssid)),
+					  (addr3 = (peerMac)))
+	: ((addr1 = (peerMac)), (addr3 = (link_iden->bssid)));
+	/*
+	 * prepare 802.11 header
+	 */
+	pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
+	pMacHdr->fc.type = SIR_MAC_DATA_FRAME;
+
+	sta_ds = dph_lookup_hash_entry(pMac, peerMac, &aid,
+					&psessionEntry->dph.dphHashTable);
+	if (sta_ds)
+		qos_mode = sta_ds->qosMode;
+
+	pMacHdr->fc.subType =
+		((IS_QOS_ENABLED(psessionEntry) &&
+		(tdlsLinkType == TDLS_LINK_AP)) ||
+		((tdlsLinkType == TDLS_LINK_DIRECT) && qos_mode))
+		? SIR_MAC_DATA_QOS_DATA : SIR_MAC_DATA_DATA;
+
+	/*
+	 * TL is not setting up below fields, so we are doing it here
+	 */
+	pMacHdr->fc.toDS = toDs;
+	pMacHdr->fc.powerMgmt = 0;
+	pMacHdr->fc.wep = (psessionEntry->encryptType == eSIR_ED_NONE) ? 0 : 1;
+
+	qdf_mem_copy((uint8_t *) pMacHdr->addr1,
+		     (uint8_t *) addr1, sizeof(tSirMacAddr));
+	qdf_mem_copy((uint8_t *) pMacHdr->addr2,
+		     (uint8_t *) staMac, sizeof(tSirMacAddr));
+
+	qdf_mem_copy((uint8_t *) pMacHdr->addr3,
+		     (uint8_t *) (addr3), sizeof(tSirMacAddr));
+
+	pe_debug("Preparing TDLS frame header to %s A1:"
+		   MAC_ADDRESS_STR", A2:"MAC_ADDRESS_STR", A3:"
+		   MAC_ADDRESS_STR,
+		(tdlsLinkType == TDLS_LINK_AP) ? "AP" : "DIRECT",
+		MAC_ADDR_ARRAY(pMacHdr->addr1),
+		MAC_ADDR_ARRAY(pMacHdr->addr2),
+		MAC_ADDR_ARRAY(pMacHdr->addr3));
+
+	if (pMacHdr->fc.subType == SIR_MAC_DATA_QOS_DATA) {
+		pMacHdr->qosControl.tid = tid;
+		header_offset += sizeof(tSirMacDataHdr3a);
+	} else
+		header_offset += sizeof(tSirMacMgmtHdr);
+
+	/*
+	 * Now form RFC1042 header
+	 */
+	qdf_mem_copy((uint8_t *) (pFrame + header_offset),
+		     (uint8_t *) eth_890d_header, sizeof(eth_890d_header));
+
+	header_offset += sizeof(eth_890d_header);
+
+	/* add payload type as TDLS */
+	*(pFrame + header_offset) = PAYLOAD_TYPE_TDLS;
+	header_offset += PAYLOAD_TYPE_TDLS_SIZE;
+	return header_offset;
+}
+
+/**
+ * lim_mgmt_tdls_tx_complete - callback to indicate Tx completion
+ * @context: pointer to mac structure
+ * @buf: buffer
+ * @tx_complete: indicates tx success/failure
+ * @params: tx completion params
+ *
+ * function will be invoked on receiving tx completion indication
+ *
+ * return: success: eHAL_STATUS_SUCCESS failure: eHAL_STATUS_FAILURE
+ */
+static QDF_STATUS lim_mgmt_tdls_tx_complete(void *context,
+					    qdf_nbuf_t buf,
+					    uint32_t tx_complete,
+					    void *params)
+{
+	tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
+
+	pe_debug("tdls_frm_session_id: %x tx_complete: %x",
+		mac_ctx->lim.tdls_frm_session_id, tx_complete);
+
+	if (NO_SESSION != mac_ctx->lim.tdls_frm_session_id) {
+		lim_send_sme_mgmt_tx_completion(mac_ctx,
+				mac_ctx->lim.tdls_frm_session_id,
+				tx_complete);
+		mac_ctx->lim.tdls_frm_session_id = NO_SESSION;
+	}
+
+	if (buf)
+		qdf_nbuf_free(buf);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * This function can be used for bacst or unicast discovery request
+ * We are not differentiating it here, it will all depnds on peer MAC address,
+ */
+static QDF_STATUS lim_send_tdls_dis_req_frame(tpAniSirGlobal pMac,
+						 struct qdf_mac_addr peer_mac,
+						 uint8_t dialog,
+						 tpPESession psessionEntry,
+						 enum wifi_traffic_ac ac)
+{
+	tDot11fTDLSDisReq tdlsDisReq;
+	uint32_t status = 0;
+	uint32_t nPayload = 0;
+	uint32_t size = 0;
+	uint32_t nBytes = 0;
+	uint32_t header_offset = 0;
+	uint8_t *pFrame;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+	uint32_t padLen = 0;
+#endif
+	uint8_t smeSessionId = 0;
+
+	if (NULL == psessionEntry) {
+		pe_err("psessionEntry is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	smeSessionId = psessionEntry->smeSessionId;
+	/*
+	 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+	 * and then hand it off to 'dot11f_pack_probe_request' (for
+	 * serialization).  We start by zero-initializing the structure:
+	 */
+	qdf_mem_set((uint8_t *) &tdlsDisReq, sizeof(tDot11fTDLSDisReq), 0);
+
+	/*
+	 * setup Fixed fields,
+	 */
+	tdlsDisReq.Category.category = SIR_MAC_ACTION_TDLS;
+	tdlsDisReq.Action.action = SIR_MAC_TDLS_DIS_REQ;
+	tdlsDisReq.DialogToken.token = dialog;
+
+	size = sizeof(tSirMacAddr);
+
+	populate_dot11f_link_iden(pMac, psessionEntry, &tdlsDisReq.LinkIdentifier,
+				  peer_mac, TDLS_INITIATOR);
+
+	/*
+	 * now we pack it.  First, how much space are we going to need?
+	 */
+	status = dot11f_get_packed_tdls_dis_req_size(pMac, &tdlsDisReq, &nPayload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to calculate the packed size for a discovery Request (0x%08x)",
+			status);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fTDLSDisReq);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while calculating the packed size for a discovery Request (0x%08x)",
+			status);
+	}
+
+	/*
+	 * This frame is going out from PE as data frames with special ethertype
+	 * 89-0d.
+	 * 8 bytes of RFC 1042 header
+	 */
+
+	nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
+			     ? sizeof(tSirMacDataHdr3a) :
+			     sizeof(tSirMacMgmtHdr))
+		 + sizeof(eth_890d_header)
+		 + PAYLOAD_TYPE_TDLS_SIZE;
+
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+	/* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
+	   Hence AP itself padding some bytes, which caused teardown packet is dropped at
+	   receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
+	 */
+	if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
+		padLen =
+			MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
+
+		/* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
+		if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
+			padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
+
+		nBytes += padLen;
+	}
+#endif
+
+	/* Ok-- try to allocate memory from MGMT PKT pool */
+
+	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				      (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate: %d bytes for a TDLS Discovery Request",
+			nBytes);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	/* zero out the memory */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/*
+	 * IE formation, memory allocation is completed, Now form TDLS discovery
+	 * request frame
+	 */
+
+	/* fill out the buffer descriptor */
+
+	header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
+			      LINK_IDEN_ADDR_OFFSET(tdlsDisReq), TDLS_LINK_AP,
+			      TDLS_INITIATOR,
+			      (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
+			      psessionEntry);
+
+	status = dot11f_pack_tdls_dis_req(pMac, &tdlsDisReq, pFrame
+					  + header_offset, nPayload, &nPayload);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to pack a TDLS discovery req (0x%08x)",
+			status);
+		cds_packet_free((void *)pPacket);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while packing TDLS Discovery Request (0x%08x)",
+			status);
+	}
+
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+	if (padLen != 0) {
+		/* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
+		uint8_t *padVendorSpecific = pFrame + header_offset + nPayload;
+		/* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
+		padVendorSpecific[0] = 221;
+		padVendorSpecific[1] = padLen - 2;
+		padVendorSpecific[2] = 0x00;
+		padVendorSpecific[3] = 0xA0;
+		padVendorSpecific[4] = 0xC6;
+
+		pe_debug("Padding Vendor Specific Ie Len: %d", padLen);
+
+		/* padding zero if more than 5 bytes are required */
+		if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
+			qdf_mem_set(pFrame + header_offset + nPayload +
+				    MIN_VENDOR_SPECIFIC_IE_SIZE,
+				    padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
+	}
+#endif
+
+	pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
+		SIR_MAC_TDLS_DIS_REQ,
+		lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_REQ),
+		MAC_ADDR_ARRAY(peer_mac.bytes));
+
+	pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
+	lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
+				      psessionEntry, QDF_STATUS_SUCCESS,
+				      QDF_STATUS_SUCCESS);
+	qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket,
+					(uint16_t) nBytes,
+					TXRX_FRM_802_11_DATA,
+					ANI_TXDIR_TODS,
+					TID_AC_VI,
+					lim_tx_complete, pFrame,
+					lim_mgmt_tdls_tx_complete,
+					HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME |
+					HAL_USE_PEER_STA_REQUESTED_MASK,
+					smeSessionId, false, 0, RATEID_DEFAULT);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pMac->lim.tdls_frm_session_id = NO_SESSION;
+		pe_err("could not send TDLS Discovery Request frame");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+}
+
+/*
+ * This static function is consistent with any kind of TDLS management
+ * frames we are sending. Currently it is being used by lim_send_tdls_dis_rsp_frame,
+ * lim_send_tdls_link_setup_req_frame and lim_send_tdls_setup_rsp_frame
+ */
+static void populate_dot11f_tdls_ht_vht_cap(tpAniSirGlobal pMac,
+					    uint32_t selfDot11Mode,
+					    tDot11fIEHTCaps *htCap,
+					    tDot11fIEVHTCaps *vhtCap,
+					    tpPESession psessionEntry)
+{
+	uint8_t nss;
+	qdf_size_t val_len;
+	struct mlme_vht_capabilities_info vht_cap_info;
+
+	vht_cap_info = pMac->mlme_cfg->vht_caps.vht_cap_info;
+
+	if (IS_5G_CH(psessionEntry->currentOperChannel))
+		nss = pMac->vdev_type_nss_5g.tdls;
+	else
+		nss = pMac->vdev_type_nss_2g.tdls;
+
+	nss = QDF_MIN(nss, pMac->user_configured_nss);
+	if (IS_DOT11_MODE_HT(selfDot11Mode)) {
+		/* Include HT Capability IE */
+		populate_dot11f_ht_caps(pMac, NULL, htCap);
+		val_len = SIZE_OF_SUPPORTED_MCS_SET;
+		wlan_mlme_get_cfg_str(&htCap->supportedMCSSet[0],
+				      &pMac->mlme_cfg->rates.supported_mcs_set,
+				      &val_len);
+		if (NSS_1x1_MODE == nss)
+			htCap->supportedMCSSet[1] = 0;
+		/*
+		 * Advertise ht capability and max supported channel bandwidth
+		 * when populating HT IE in TDLS Setup Request/Setup Response/
+		 * Setup Confirmation frames.
+		 * 11.21.6.2 Setting up a 40 MHz direct link: A 40 MHz
+		 * off-channel direct link may be started if both TDLS peer STAs
+		 * indicated 40 MHz support in the Supported Channel Width Set
+		 * field of the HT Capabilities element (which is included in
+		 * the TDLS Setup Request frame and the TDLS Setup Response
+		 * frame). Switching to a 40 MHz off-channel direct link is
+		 * achieved by including the following information in the TDLS
+		 * Channel Switch Request
+		 * 11.21.1 General: The channel width of the TDLS direct link on
+		 * the base channel shall not exceed the channel width of the
+		 * BSS to which the TDLS peer STAs are associated.
+		 */
+		htCap->supportedChannelWidthSet = 1;
+	} else {
+		htCap->present = 0;
+	}
+	pe_debug("HT present: %hu, Chan Width: %hu",
+		htCap->present, htCap->supportedChannelWidthSet);
+	if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
+	     pMac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band) ||
+	    (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) {
+		if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
+		    IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			/* Include VHT Capability IE */
+			populate_dot11f_vht_caps(pMac, psessionEntry, vhtCap);
+
+			/*
+			 * Set to 0 if the TDLS STA does not support either 160
+			 * or 80+80 MHz.
+			 * Set to 1 if the TDLS STA supports 160 MHz.
+			 * Set to 2 if the TDLS STA supports 160 MHz and
+			 * 80+80 MHz.
+			 * The value 3 is reserved
+			 */
+			vhtCap->supportedChannelWidthSet = 0;
+
+			vhtCap->suBeamformeeCap = 0;
+			vhtCap->suBeamFormerCap = 0;
+			vhtCap->muBeamformeeCap = 0;
+			vhtCap->muBeamformerCap = 0;
+
+			vhtCap->rxMCSMap = vht_cap_info.rx_mcs_map;
+
+			vhtCap->rxHighSupDataRate =
+				vht_cap_info.rx_supp_data_rate;
+			vhtCap->txMCSMap = vht_cap_info.tx_mcs_map;
+			vhtCap->txSupDataRate = vht_cap_info.tx_supp_data_rate;
+			if (nss == NSS_1x1_MODE) {
+				vhtCap->txMCSMap |= DISABLE_NSS2_MCS;
+				vhtCap->rxMCSMap |= DISABLE_NSS2_MCS;
+				vhtCap->txSupDataRate =
+					VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+				vhtCap->rxHighSupDataRate =
+					VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+			}
+		} else {
+			vhtCap->present = 0;
+		}
+	} else {
+		/* Vht Disable from ini in 2.4 GHz */
+		vhtCap->present = 0;
+	}
+	pe_debug("VHT present: %hu, Chan Width: %hu",
+		vhtCap->present, vhtCap->supportedChannelWidthSet);
+}
+
+/*
+ * Send TDLS discovery response frame on direct link.
+ */
+
+static QDF_STATUS lim_send_tdls_dis_rsp_frame(tpAniSirGlobal pMac,
+						 struct qdf_mac_addr peer_mac,
+						 uint8_t dialog,
+						 tpPESession psessionEntry,
+						 uint8_t *addIe,
+						 uint16_t addIeLen)
+{
+	tDot11fTDLSDisRsp tdlsDisRsp;
+	uint16_t caps = 0;
+	uint32_t status = 0;
+	uint32_t nPayload = 0;
+	uint32_t nBytes = 0;
+	uint8_t *pFrame;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint32_t selfDot11Mode;
+/*  Placeholder to support different channel bonding mode of TDLS than AP. */
+/*  Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
+/*  To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
+/*  As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
+/*  uint32_t tdlsChannelBondingMode; */
+	uint8_t smeSessionId = 0;
+
+	if (NULL == psessionEntry) {
+		pe_err("psessionEntry is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	smeSessionId = psessionEntry->smeSessionId;
+
+	/*
+	 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+	 * and then hand it off to 'dot11f_pack_probe_request' (for
+	 * serialization).  We start by zero-initializing the structure:
+	 */
+	qdf_mem_set((uint8_t *) &tdlsDisRsp, sizeof(tDot11fTDLSDisRsp), 0);
+
+	/*
+	 * setup Fixed fields,
+	 */
+	tdlsDisRsp.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
+	tdlsDisRsp.Action.action = SIR_MAC_TDLS_DIS_RSP;
+	tdlsDisRsp.DialogToken.token = dialog;
+
+	populate_dot11f_link_iden(pMac, psessionEntry,
+				  &tdlsDisRsp.LinkIdentifier,
+				  peer_mac, TDLS_RESPONDER);
+
+	if (cfg_get_capability_info(pMac, &caps, psessionEntry)
+		!= QDF_STATUS_SUCCESS) {
+		/*
+		 * Could not get Capabilities value
+		 * from CFG. Log error.
+		 */
+		pe_err("could not retrieve Capabilities value");
+	}
+	swap_bit_field16(caps, (uint16_t *) &tdlsDisRsp.Capabilities);
+
+	/* populate supported rate and ext supported rate IE */
+	if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(pMac,
+					&tdlsDisRsp.SuppRates,
+					&tdlsDisRsp.ExtSuppRates,
+					psessionEntry->currentOperChannel))
+		pe_err("could not populate supported data rates");
+
+	/* populate extended capability IE */
+	populate_dot11f_tdls_ext_capability(pMac,
+					    psessionEntry,
+					    &tdlsDisRsp.ExtCap);
+
+	wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
+
+	/* Populate HT/VHT Capabilities */
+	populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsDisRsp.HTCaps,
+					&tdlsDisRsp.VHTCaps, psessionEntry);
+
+	/* Populate TDLS offchannel param only if offchannel is enabled
+	 * and TDLS Channel Switching is not prohibited by AP in ExtCap
+	 * IE in assoc/re-assoc response.
+	 */
+	if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
+	    (!psessionEntry->tdls_chan_swit_prohibited)) {
+		populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
+						       &tdlsDisRsp.SuppChannels,
+						       &tdlsDisRsp.
+						       SuppOperatingClasses);
+		if (pMac->mlme_cfg->gen.band_capability != BAND_2G) {
+			tdlsDisRsp.ht2040_bss_coexistence.present = 1;
+			tdlsDisRsp.ht2040_bss_coexistence.info_request = 1;
+		}
+	} else {
+		pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d",
+			pMac->lim.gLimTDLSOffChannelEnabled,
+			psessionEntry->tdls_chan_swit_prohibited);
+	}
+	/*
+	 * now we pack it.  First, how much space are we going to need?
+	 */
+	status = dot11f_get_packed_tdls_dis_rsp_size(pMac, &tdlsDisRsp, &nPayload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to calculate the packed size for a Discovery Response (0x%08x)",
+			status);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fProbeRequest);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while calculating the packed size for a Discovery Response (0x%08x)",
+			status);
+	}
+
+	/*
+	 * This frame is going out from PE as data frames with special ethertype
+	 * 89-0d.
+	 * 8 bytes of RFC 1042 header
+	 */
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr) + addIeLen;
+
+	/* Ok-- try to allocate memory from MGMT PKT pool */
+	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				(void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a TDLS Discovery Request",
+			nBytes);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	/* zero out the memory */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/*
+	 * IE formation, memory allocation is completed, Now form TDLS discovery
+	 * response frame
+	 */
+
+	/* Make public Action Frame */
+
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+				SIR_MAC_MGMT_ACTION, peer_mac.bytes,
+				psessionEntry->selfMacAddr);
+
+	{
+		tpSirMacMgmtHdr pMacHdr;
+
+		pMacHdr = (tpSirMacMgmtHdr) pFrame;
+		pMacHdr->fc.toDS = ANI_TXDIR_IBSS;
+		pMacHdr->fc.powerMgmt = 0;
+		sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+	}
+
+	status = dot11f_pack_tdls_dis_rsp(pMac, &tdlsDisRsp, pFrame +
+					  sizeof(tSirMacMgmtHdr),
+					  nPayload, &nPayload);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to pack a TDLS discovery response (0x%08x)",
+			status);
+		cds_packet_free((void *)pPacket);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while packing TDLS Discovery Response (0x%08x)",
+			status);
+	}
+
+	if (0 != addIeLen) {
+		pe_debug("Copy Additional Ie Len: %d", addIeLen);
+		qdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, addIe,
+			     addIeLen);
+	}
+	pe_debug("[TDLS] action: %d (%s) -DIRECT-> OTA peer="MAC_ADDRESS_STR,
+		SIR_MAC_TDLS_DIS_RSP,
+		lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_RSP),
+		MAC_ADDR_ARRAY(peer_mac.bytes));
+
+	pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
+	lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
+				      psessionEntry, QDF_STATUS_SUCCESS,
+				      QDF_STATUS_SUCCESS);
+	/*
+	 * Transmit Discovery response and watch if this is delivered to
+	 * peer STA.
+	 */
+	/* In CLD 2.0, pass Discovery Response as mgmt frame so that
+	 * wma does not do header conversion to 802.3 before calling tx/rx
+	 * routine and subsequenly target also sends frame as is OTA
+	 */
+	qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
+					      TXRX_FRM_802_11_MGMT,
+					      ANI_TXDIR_IBSS,
+					      0,
+					      lim_tx_complete, pFrame,
+					      lim_mgmt_tdls_tx_complete,
+					      HAL_USE_SELF_STA_REQUESTED_MASK,
+					      smeSessionId, false, 0,
+					      RATEID_DEFAULT);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pMac->lim.tdls_frm_session_id = NO_SESSION;
+		pe_err("could not send TDLS Discovery Response frame!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+}
+
+/*
+ * This static function is currently used by lim_send_tdls_link_setup_req_frame and
+ * lim_send_tdls_setup_rsp_frame to populate the AID if device is 11ac capable.
+ */
+static void populate_dotf_tdls_vht_aid(tpAniSirGlobal pMac, uint32_t selfDot11Mode,
+				       struct qdf_mac_addr peerMac,
+				       tDot11fIEAID *Aid,
+				       tpPESession psessionEntry)
+{
+	if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
+	     pMac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band) ||
+	    (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) {
+		if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
+		    IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+
+			uint16_t aid;
+			tpDphHashNode pStaDs;
+
+			pStaDs =
+				dph_lookup_hash_entry(pMac, peerMac.bytes, &aid,
+						      &psessionEntry->dph.
+						      dphHashTable);
+			if (NULL != pStaDs) {
+				Aid->present = 1;
+				Aid->assocId = aid | LIM_AID_MASK;      /* set bit 14 and 15 1's */
+			} else {
+				Aid->present = 0;
+				pe_err("pStaDs is NULL for "
+					   MAC_ADDRESS_STR,
+					MAC_ADDR_ARRAY(peerMac.bytes));
+			}
+		}
+	} else {
+		Aid->present = 0;
+		pe_warn("Vht not enable from ini for 2.4GHz");
+	}
+}
+
+#ifdef CONFIG_HL_SUPPORT
+
+/**
+ * wma_tx_frame_with_tx_complete_send() - Send tx frames on Direct link or AP link
+ *				       depend on reason code
+ * @pMac: pointer to MAC Sirius parameter structure
+ * @pPacket: pointer to mgmt packet
+ * @nBytes: number of bytes to send
+ * @tid:tid value for AC
+ * @pFrame: pointer to tdls frame
+ * @smeSessionId:session id
+ * @flag: tdls flag
+ *
+ * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
+ *
+ * Return: None
+ */
+static inline QDF_STATUS
+wma_tx_frame_with_tx_complete_send(tpAniSirGlobal pMac, void *pPacket,
+				uint16_t nBytes,
+				uint8_t tid,
+				uint8_t *pFrame,
+				uint8_t smeSessionId, bool flag)
+{
+	return wma_tx_frameWithTxComplete(pMac, pPacket,
+					  (uint16_t) nBytes,
+					  TXRX_FRM_802_11_DATA,
+					  ANI_TXDIR_TODS,
+					  tid,
+					  lim_tx_complete, pFrame,
+					  lim_mgmt_tdls_tx_complete,
+					  HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME
+					  | HAL_USE_PEER_STA_REQUESTED_MASK,
+					  smeSessionId, flag, 0,
+					  RATEID_DEFAULT);
+}
+#else
+
+static inline QDF_STATUS
+wma_tx_frame_with_tx_complete_send(tpAniSirGlobal pMac, void *pPacket,
+				uint16_t nBytes,
+				uint8_t tid,
+				uint8_t *pFrame,
+				uint8_t smeSessionId, bool flag)
+{
+	return wma_tx_frameWithTxComplete(pMac, pPacket,
+					  (uint16_t) nBytes,
+					  TXRX_FRM_802_11_DATA,
+					  ANI_TXDIR_TODS,
+					  tid,
+					  lim_tx_complete, pFrame,
+					  lim_mgmt_tdls_tx_complete,
+					  HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME
+					  | HAL_USE_PEER_STA_REQUESTED_MASK,
+					  smeSessionId, false, 0,
+					  RATEID_DEFAULT);
+}
+#endif
+
+void lim_set_tdls_flags(roam_offload_synch_ind *roam_sync_ind_ptr,
+		   tpPESession ft_session_ptr)
+{
+	roam_sync_ind_ptr->join_rsp->tdls_prohibited =
+		ft_session_ptr->tdls_prohibited;
+	roam_sync_ind_ptr->join_rsp->tdls_chan_swit_prohibited =
+		ft_session_ptr->tdls_chan_swit_prohibited;
+}
+
+/*
+ * TDLS setup Request frame on AP link
+ */
+static
+QDF_STATUS lim_send_tdls_link_setup_req_frame(tpAniSirGlobal pMac,
+						 struct qdf_mac_addr peer_mac,
+						 uint8_t dialog,
+						 tpPESession psessionEntry,
+						 uint8_t *addIe,
+						 uint16_t addIeLen,
+						 enum wifi_traffic_ac ac)
+{
+	tDot11fTDLSSetupReq tdlsSetupReq;
+	uint16_t caps = 0;
+	uint32_t status = 0;
+	uint32_t nPayload = 0;
+	uint32_t nBytes = 0;
+	uint32_t header_offset = 0;
+	uint8_t *pFrame;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint32_t selfDot11Mode;
+	uint8_t smeSessionId = 0;
+	uint8_t sp_length = 0;
+
+/*  Placeholder to support different channel bonding mode of TDLS than AP. */
+/*  Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
+/*  To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
+/*  As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
+/*  uint32_t tdlsChannelBondingMode; */
+
+	/*
+	 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+	 * and then hand it off to 'dot11f_pack_probe_request' (for
+	 * serialization).  We start by zero-initializing the structure:
+	 */
+	smeSessionId = psessionEntry->smeSessionId;
+
+	qdf_mem_set((uint8_t *) &tdlsSetupReq, sizeof(tDot11fTDLSSetupReq), 0);
+	tdlsSetupReq.Category.category = SIR_MAC_ACTION_TDLS;
+	tdlsSetupReq.Action.action = SIR_MAC_TDLS_SETUP_REQ;
+	tdlsSetupReq.DialogToken.token = dialog;
+
+	populate_dot11f_link_iden(pMac, psessionEntry,
+				  &tdlsSetupReq.LinkIdentifier, peer_mac,
+				  TDLS_INITIATOR);
+
+	if (cfg_get_capability_info(pMac, &caps, psessionEntry) != QDF_STATUS_SUCCESS) {
+		/*
+		 * Could not get Capabilities value
+		 * from CFG. Log error.
+		 */
+		pe_err("could not retrieve Capabilities value");
+	}
+	swap_bit_field16(caps, (uint16_t *) &tdlsSetupReq.Capabilities);
+
+	/* populate supported rate and ext supported rate IE */
+	if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(pMac,
+					&tdlsSetupReq.SuppRates,
+					&tdlsSetupReq.ExtSuppRates,
+					psessionEntry->currentOperChannel))
+		pe_err("could not populate supported data rates");
+
+	/* Populate extended capability IE */
+	populate_dot11f_tdls_ext_capability(pMac,
+					    psessionEntry,
+					    &tdlsSetupReq.ExtCap);
+
+	if (1 == pMac->lim.gLimTDLSWmmMode) {
+
+		pe_debug("populate WMM IE in Setup Request Frame");
+		sp_length = pMac->mlme_cfg->wmm_params.max_sp_length;
+		/* include WMM IE */
+		tdlsSetupReq.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
+		tdlsSetupReq.WMMInfoStation.acvo_uapsd =
+			(pMac->lim.gLimTDLSUapsdMask & 0x01);
+		tdlsSetupReq.WMMInfoStation.acvi_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
+		tdlsSetupReq.WMMInfoStation.acbk_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
+		tdlsSetupReq.WMMInfoStation.acbe_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
+		tdlsSetupReq.WMMInfoStation.max_sp_length = sp_length;
+		tdlsSetupReq.WMMInfoStation.present = 1;
+	} else {
+		/*
+		 * TODO: we need to see if we have to support conditions where
+		 * we have EDCA parameter info element is needed a) if we need
+		 * different QOS parameters for off channel operations or QOS
+		 * is not supported on AP link and we wanted to QOS on direct
+		 * link.
+		 */
+
+		/* Populate QOS info, needed for Peer U-APSD session */
+
+		/*
+		 * TODO: Now hardcoded, since populate_dot11f_qos_caps_station()
+		 * depends on AP's capability, and TDLS doesn't want to depend
+		 * on AP's capability
+		 */
+
+		pe_debug("populate QOS IE in Setup Request Frame");
+		tdlsSetupReq.QOSCapsStation.present = 1;
+		tdlsSetupReq.QOSCapsStation.max_sp_length = 0;
+		tdlsSetupReq.QOSCapsStation.qack = 0;
+		tdlsSetupReq.QOSCapsStation.acbe_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
+		tdlsSetupReq.QOSCapsStation.acbk_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
+		tdlsSetupReq.QOSCapsStation.acvi_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
+		tdlsSetupReq.QOSCapsStation.acvo_uapsd =
+			(pMac->lim.gLimTDLSUapsdMask & 0x01);
+	}
+
+	/*
+	 * we will always try to init TDLS link with 11n capabilities
+	 * let TDLS setup response to come, and we will set our caps based
+	 * of peer caps
+	 */
+
+	wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
+
+	/* Populate HT/VHT Capabilities */
+	populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsSetupReq.HTCaps,
+					&tdlsSetupReq.VHTCaps, psessionEntry);
+
+	/* Populate AID */
+	populate_dotf_tdls_vht_aid(pMac, selfDot11Mode, peer_mac,
+				   &tdlsSetupReq.AID, psessionEntry);
+
+	/* Populate TDLS offchannel param only if offchannel is enabled
+	 * and TDLS Channel Switching is not prohibited by AP in ExtCap
+	 * IE in assoc/re-assoc response.
+	 */
+	if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
+	    (!psessionEntry->tdls_chan_swit_prohibited)) {
+		populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
+						     &tdlsSetupReq.SuppChannels,
+						     &tdlsSetupReq.
+						     SuppOperatingClasses);
+		if (pMac->mlme_cfg->gen.band_capability != BAND_2G) {
+			tdlsSetupReq.ht2040_bss_coexistence.present = 1;
+			tdlsSetupReq.ht2040_bss_coexistence.info_request = 1;
+		}
+	} else {
+		pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d",
+			pMac->lim.gLimTDLSOffChannelEnabled,
+			psessionEntry->tdls_chan_swit_prohibited);
+	}
+	/*
+	 * now we pack it.  First, how much space are we going to need?
+	 */
+	status = dot11f_get_packed_tdls_setup_req_size(pMac, &tdlsSetupReq,
+						       &nPayload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to calculate the packed size for a Setup Request (0x%08x)",
+			status);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fProbeRequest);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while calculating the packed size for a Setup Request (0x%08x)",
+			status);
+	}
+
+	/*
+	 * This frame is going out from PE as data frames with special ethertype
+	 * 89-0d.
+	 * 8 bytes of RFC 1042 header
+	 */
+
+	nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
+			     ? sizeof(tSirMacDataHdr3a) :
+			     sizeof(tSirMacMgmtHdr))
+		 + sizeof(eth_890d_header)
+		 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
+
+	/* Ok-- try to allocate memory from MGMT PKT pool */
+	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+			(void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a TDLS Setup Request",
+			nBytes);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	/* zero out the memory */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/*
+	 * IE formation, memory allocation is completed, Now form TDLS discovery
+	 * request frame
+	 */
+
+	/* fill out the buffer descriptor */
+
+	header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
+			LINK_IDEN_ADDR_OFFSET(tdlsSetupReq),
+			TDLS_LINK_AP, TDLS_INITIATOR,
+			(ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
+			psessionEntry);
+
+	pe_debug("SupportedChnlWidth: %x rxMCSMap: %x rxMCSMap: %x txSupDataRate: %x",
+		tdlsSetupReq.VHTCaps.supportedChannelWidthSet,
+		tdlsSetupReq.VHTCaps.rxMCSMap,
+		tdlsSetupReq.VHTCaps.txMCSMap,
+		tdlsSetupReq.VHTCaps.txSupDataRate);
+
+	status = dot11f_pack_tdls_setup_req(pMac, &tdlsSetupReq, pFrame
+					    + header_offset, nPayload, &nPayload);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to pack a TDLS Setup request (0x%08x)",
+			status);
+		cds_packet_free((void *)pPacket);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while packing TDLS Setup Request (0x%08x)",
+			status);
+	}
+
+	/* Copy the additional IE. */
+	/* TODO : addIe is added at the end of the frame. This means it doesn't */
+	/* follow the order. This should be ok, but we should consider changing this */
+	/* if there is any IOT issue. */
+	if (addIeLen != 0) {
+		pe_debug("Copy Additional Ie Len = %d", addIeLen);
+		qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
+			     addIeLen);
+	}
+
+	pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
+		SIR_MAC_TDLS_SETUP_REQ,
+		lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_REQ),
+		MAC_ADDR_ARRAY(peer_mac.bytes));
+
+	pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
+	lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
+				      psessionEntry, QDF_STATUS_SUCCESS,
+				      QDF_STATUS_SUCCESS);
+
+	qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
+						     (uint16_t) nBytes,
+						     TID_AC_VI,
+						     pFrame,
+						     smeSessionId, true);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pMac->lim.tdls_frm_session_id = NO_SESSION;
+		pe_err("could not send TDLS Setup Request frame!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+}
+
+/*
+ * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
+ */
+static
+QDF_STATUS lim_send_tdls_teardown_frame(tpAniSirGlobal pMac,
+					   struct qdf_mac_addr peer_mac,
+					   uint16_t reason,
+					   uint8_t responder,
+					   tpPESession psessionEntry,
+					   uint8_t *addIe, uint16_t addIeLen,
+					   enum wifi_traffic_ac ac)
+{
+	tDot11fTDLSTeardown teardown;
+	uint32_t status = 0;
+	uint32_t nPayload = 0;
+	uint32_t nBytes = 0;
+	uint32_t header_offset = 0;
+	uint8_t *pFrame;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+	uint32_t padLen = 0;
+#endif
+	uint8_t smeSessionId = 0;
+	tpDphHashNode sta_ds;
+	uint16_t aid = 0;
+	uint8_t qos_mode = 0;
+	uint8_t tdls_link_type;
+
+	if (NULL == psessionEntry) {
+		pe_err("psessionEntry is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	smeSessionId = psessionEntry->smeSessionId;
+	/*
+	 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+	 * and then hand it off to 'dot11f_pack_probe_request' (for
+	 * serialization).  We start by zero-initializing the structure:
+	 */
+	qdf_mem_set((uint8_t *) &teardown, sizeof(tDot11fTDLSTeardown), 0);
+	teardown.Category.category = SIR_MAC_ACTION_TDLS;
+	teardown.Action.action = SIR_MAC_TDLS_TEARDOWN;
+	teardown.Reason.code = reason;
+
+	populate_dot11f_link_iden(pMac, psessionEntry, &teardown.LinkIdentifier,
+				  peer_mac,
+				  (responder ==
+				   true) ? TDLS_RESPONDER : TDLS_INITIATOR);
+
+	/*
+	 * now we pack it.  First, how much space are we going to need?
+	 */
+	status = dot11f_get_packed_tdls_teardown_size(pMac, &teardown, &nPayload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to calculate the packed size for a discovery Request (0x%08x)",
+			status);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fProbeRequest);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while calculating the packed size for a discovery Request (0x%08x)",
+			status);
+	}
+
+	/*
+	 * This frame is going out from PE as data frames with special ethertype
+	 * 89-0d.
+	 * 8 bytes of RFC 1042 header
+	 */
+	sta_ds = dph_lookup_hash_entry(pMac, psessionEntry->bssId, &aid,
+					&psessionEntry->dph.dphHashTable);
+	if (sta_ds)
+		qos_mode = sta_ds->qosMode;
+	tdls_link_type = (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
+				? TDLS_LINK_AP : TDLS_LINK_DIRECT;
+	nBytes = nPayload + (((IS_QOS_ENABLED(psessionEntry) &&
+			     (tdls_link_type == TDLS_LINK_AP)) ||
+			     ((tdls_link_type == TDLS_LINK_DIRECT) && qos_mode))
+			     ? sizeof(tSirMacDataHdr3a) :
+			     sizeof(tSirMacMgmtHdr))
+		 + sizeof(eth_890d_header)
+		 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
+
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+	/* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
+	   Hence AP itself padding some bytes, which caused teardown packet is dropped at
+	   receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
+	 */
+	if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
+		padLen =
+			MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
+
+		/* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
+		if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
+			padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
+
+		nBytes += padLen;
+	}
+#endif
+
+	/* Ok-- try to allocate memory from MGMT PKT pool */
+	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+			(void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a TDLS Teardown Frame.",
+			nBytes);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	/* zero out the memory */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/*
+	 * IE formation, memory allocation is completed, Now form TDLS discovery
+	 * request frame
+	 */
+
+	/* fill out the buffer descriptor */
+	pe_debug("Reason of TDLS Teardown: %d", reason);
+	header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
+			LINK_IDEN_ADDR_OFFSET(teardown),
+			(reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ?
+			TDLS_LINK_AP : TDLS_LINK_DIRECT,
+			(responder == true) ? TDLS_RESPONDER : TDLS_INITIATOR,
+			(ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
+			psessionEntry);
+
+	status = dot11f_pack_tdls_teardown(pMac, &teardown, pFrame
+					   + header_offset, nPayload, &nPayload);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to pack a TDLS Teardown frame (0x%08x)",
+			status);
+		cds_packet_free((void *)pPacket);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while packing TDLS Teardown frame (0x%08x)",
+			status);
+	}
+
+	if (addIeLen != 0) {
+		pe_debug("Copy Additional Ie Len = %d", addIeLen);
+		qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
+			     addIeLen);
+	}
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+	if (padLen != 0) {
+		/* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
+		uint8_t *padVendorSpecific =
+			pFrame + header_offset + nPayload + addIeLen;
+		/* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
+		padVendorSpecific[0] = 221;
+		padVendorSpecific[1] = padLen - 2;
+		padVendorSpecific[2] = 0x00;
+		padVendorSpecific[3] = 0xA0;
+		padVendorSpecific[4] = 0xC6;
+
+		pe_debug("Padding Vendor Specific Ie Len = %d", padLen);
+
+		/* padding zero if more than 5 bytes are required */
+		if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
+			qdf_mem_set(pFrame + header_offset + nPayload +
+				    addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
+				    padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
+	}
+#endif
+	pe_debug("[TDLS] action: %d (%s) -%s-> OTA peer="MAC_ADDRESS_STR,
+		SIR_MAC_TDLS_TEARDOWN,
+		lim_trace_tdls_action_string(SIR_MAC_TDLS_TEARDOWN),
+		((reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? "AP" :
+		    "DIRECT"),
+		MAC_ADDR_ARRAY(peer_mac.bytes));
+
+	pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
+	lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
+				      psessionEntry, QDF_STATUS_SUCCESS,
+				      QDF_STATUS_SUCCESS);
+
+	qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
+						     (uint16_t) nBytes,
+						     TID_AC_VI,
+						     pFrame,
+						     smeSessionId,
+						     (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
+						     ? true : false);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pMac->lim.tdls_frm_session_id = NO_SESSION;
+		pe_err("could not send TDLS Teardown frame");
+		return QDF_STATUS_E_FAILURE;
+
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * Send Setup RSP frame on AP link.
+ */
+static QDF_STATUS lim_send_tdls_setup_rsp_frame(tpAniSirGlobal pMac,
+						   struct qdf_mac_addr peer_mac,
+						   uint8_t dialog,
+						   tpPESession psessionEntry,
+						   etdlsLinkSetupStatus setupStatus,
+						   uint8_t *addIe,
+						   uint16_t addIeLen,
+						   enum wifi_traffic_ac ac)
+{
+	tDot11fTDLSSetupRsp tdlsSetupRsp;
+	uint32_t status = 0;
+	uint16_t caps = 0;
+	uint32_t nPayload = 0;
+	uint32_t header_offset = 0;
+	uint32_t nBytes = 0;
+	uint8_t *pFrame;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint32_t selfDot11Mode;
+	uint8_t max_sp_length = 0;
+/*  Placeholder to support different channel bonding mode of TDLS than AP. */
+/*  Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
+/*  To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
+/*  As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
+/*  uint32_t tdlsChannelBondingMode; */
+	uint8_t smeSessionId = 0;
+
+	if (NULL == psessionEntry) {
+		pe_err("psessionEntry is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	smeSessionId = psessionEntry->smeSessionId;
+
+	/*
+	 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+	 * and then hand it off to 'dot11f_pack_probe_request' (for
+	 * serialization).  We start by zero-initializing the structure:
+	 */
+	qdf_mem_set((uint8_t *) &tdlsSetupRsp, sizeof(tDot11fTDLSSetupRsp), 0);
+
+	/*
+	 * setup Fixed fields,
+	 */
+	tdlsSetupRsp.Category.category = SIR_MAC_ACTION_TDLS;
+	tdlsSetupRsp.Action.action = SIR_MAC_TDLS_SETUP_RSP;
+	tdlsSetupRsp.DialogToken.token = dialog;
+
+	populate_dot11f_link_iden(pMac, psessionEntry,
+				  &tdlsSetupRsp.LinkIdentifier, peer_mac,
+				  TDLS_RESPONDER);
+
+	if (cfg_get_capability_info(pMac, &caps, psessionEntry) != QDF_STATUS_SUCCESS) {
+		/*
+		 * Could not get Capabilities value
+		 * from CFG. Log error.
+		 */
+		pe_err("could not retrieve Capabilities value");
+	}
+	swap_bit_field16(caps, (uint16_t *) &tdlsSetupRsp.Capabilities);
+
+	/* populate supported rate and ext supported rate IE */
+	if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(pMac,
+					&tdlsSetupRsp.SuppRates,
+					&tdlsSetupRsp.ExtSuppRates,
+					psessionEntry->currentOperChannel))
+		pe_err("could not populate supported data rates");
+
+	/* Populate extended capability IE */
+	populate_dot11f_tdls_ext_capability(pMac,
+					    psessionEntry,
+					    &tdlsSetupRsp.ExtCap);
+
+	if (1 == pMac->lim.gLimTDLSWmmMode) {
+
+		pe_debug("populate WMM IE in Setup Response frame");
+		max_sp_length = pMac->mlme_cfg->wmm_params.max_sp_length;
+		/* include WMM IE */
+		tdlsSetupRsp.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
+		tdlsSetupRsp.WMMInfoStation.acvo_uapsd =
+			(pMac->lim.gLimTDLSUapsdMask & 0x01);
+		tdlsSetupRsp.WMMInfoStation.acvi_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
+		tdlsSetupRsp.WMMInfoStation.acbk_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
+		tdlsSetupRsp.WMMInfoStation.acbe_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
+		tdlsSetupRsp.WMMInfoStation.max_sp_length = max_sp_length;
+		tdlsSetupRsp.WMMInfoStation.present = 1;
+	} else {
+		/*
+		 * TODO: we need to see if we have to support conditions where
+		 * we have EDCA parameter info element is needed a) if we need
+		 * different QOS parameters for off channel operations or QOS
+		 * is not supported on AP link and we wanted to QOS on direct
+		 * link.
+		 */
+		/* Populate QOS info, needed for Peer U-APSD session */
+		/*
+		 * TODO: Now hardcoded, because
+		 * populate_dot11f_qos_caps_station() depends on AP's
+		 * capability, and TDLS doesn't want to depend on AP's
+		 * capability
+		 */
+		pe_debug("populate QOS IE in Setup Response frame");
+		tdlsSetupRsp.QOSCapsStation.present = 1;
+		tdlsSetupRsp.QOSCapsStation.max_sp_length = 0;
+		tdlsSetupRsp.QOSCapsStation.qack = 0;
+		tdlsSetupRsp.QOSCapsStation.acbe_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
+		tdlsSetupRsp.QOSCapsStation.acbk_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
+		tdlsSetupRsp.QOSCapsStation.acvi_uapsd =
+			((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
+		tdlsSetupRsp.QOSCapsStation.acvo_uapsd =
+			(pMac->lim.gLimTDLSUapsdMask & 0x01);
+	}
+
+	wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
+
+	/* Populate HT/VHT Capabilities */
+	populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsSetupRsp.HTCaps,
+					&tdlsSetupRsp.VHTCaps, psessionEntry);
+
+	/* Populate AID */
+	populate_dotf_tdls_vht_aid(pMac, selfDot11Mode, peer_mac,
+				   &tdlsSetupRsp.AID, psessionEntry);
+
+	/* Populate TDLS offchannel param only if offchannel is enabled
+	 * and TDLS Channel Switching is not prohibited by AP in ExtCap
+	 * IE in assoc/re-assoc response.
+	 */
+	if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
+	    (!psessionEntry->tdls_chan_swit_prohibited)) {
+		populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
+						    &tdlsSetupRsp.SuppChannels,
+						    &tdlsSetupRsp.
+						    SuppOperatingClasses);
+		if (pMac->mlme_cfg->gen.band_capability != BAND_2G) {
+			tdlsSetupRsp.ht2040_bss_coexistence.present = 1;
+			tdlsSetupRsp.ht2040_bss_coexistence.info_request = 1;
+		}
+	} else {
+		pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d",
+			pMac->lim.gLimTDLSOffChannelEnabled,
+			psessionEntry->tdls_chan_swit_prohibited);
+	}
+	tdlsSetupRsp.Status.status = setupStatus;
+	/*
+	 * now we pack it.  First, how much space are we going to need?
+	 */
+	status = dot11f_get_packed_tdls_setup_rsp_size(pMac, &tdlsSetupRsp,
+						       &nPayload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to calculate the packed size for a Setup Response (0x%08x)",
+			status);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fProbeRequest);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while calculating the packed size for Setup Response (0x%08x)",
+			status);
+	}
+
+	/*
+	 * This frame is going out from PE as data frames with special ethertype
+	 * 89-0d.
+	 * 8 bytes of RFC 1042 header
+	 */
+
+	nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
+			     ? sizeof(tSirMacDataHdr3a) :
+			     sizeof(tSirMacMgmtHdr))
+		 + sizeof(eth_890d_header)
+		 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
+
+	/* Ok-- try to allocate memory from MGMT PKT pool */
+	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				      (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a TDLS Setup Response",
+			nBytes);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	/* zero out the memory */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/*
+	 * IE formation, memory allocation is completed, Now form TDLS discovery
+	 * request frame
+	 */
+
+	/* fill out the buffer descriptor */
+
+	header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
+			LINK_IDEN_ADDR_OFFSET(tdlsSetupRsp), TDLS_LINK_AP,
+			TDLS_RESPONDER,
+			(ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
+			psessionEntry);
+
+	pe_debug("SupportedChnlWidth: %x rxMCSMap: %x rxMCSMap: %x txSupDataRate: %x",
+		tdlsSetupRsp.VHTCaps.supportedChannelWidthSet,
+		tdlsSetupRsp.VHTCaps.rxMCSMap,
+		tdlsSetupRsp.VHTCaps.txMCSMap,
+		tdlsSetupRsp.VHTCaps.txSupDataRate);
+	status = dot11f_pack_tdls_setup_rsp(pMac, &tdlsSetupRsp,
+					    pFrame + header_offset,
+					    nPayload, &nPayload);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to pack a TDLS Setup Response (0x%08x)",
+			status);
+		cds_packet_free((void *)pPacket);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while packing TDLS Setup Response (0x%08x)",
+			status);
+	}
+
+	/* Copy the additional IE. */
+	/* TODO : addIe is added at the end of the frame. This means it doesn't */
+	/* follow the order. This should be ok, but we should consider changing this */
+	/* if there is any IOT issue. */
+	if (addIeLen != 0) {
+		qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
+			     addIeLen);
+	}
+
+	pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
+		SIR_MAC_TDLS_SETUP_RSP,
+		lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_RSP),
+		MAC_ADDR_ARRAY(peer_mac.bytes));
+
+	pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
+	lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
+				      psessionEntry, QDF_STATUS_SUCCESS,
+				      QDF_STATUS_SUCCESS);
+
+	qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
+						     (uint16_t) nBytes,
+						     TID_AC_VI,
+						     pFrame,
+						     smeSessionId, true);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pMac->lim.tdls_frm_session_id = NO_SESSION;
+		pe_err("could not send TDLS Dis Request frame!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * Send TDLS setup CNF frame on AP link
+ */
+static
+QDF_STATUS lim_send_tdls_link_setup_cnf_frame(tpAniSirGlobal pMac,
+						 struct qdf_mac_addr peer_mac,
+						 uint8_t dialog,
+						 uint32_t peerCapability,
+						 tpPESession psessionEntry,
+						 uint8_t *addIe,
+						 uint16_t addIeLen,
+						 enum wifi_traffic_ac ac)
+{
+	tDot11fTDLSSetupCnf tdlsSetupCnf;
+	uint32_t status = 0;
+	uint32_t nPayload = 0;
+	uint32_t nBytes = 0;
+	uint32_t header_offset = 0;
+	uint8_t *pFrame;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+	uint32_t padLen = 0;
+#endif
+	uint8_t smeSessionId = 0;
+
+	/*
+	 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+	 * and then hand it off to 'dot11f_pack_probe_request' (for
+	 * serialization).  We start by zero-initializing the structure:
+	 */
+	smeSessionId = psessionEntry->smeSessionId;
+
+	qdf_mem_set((uint8_t *) &tdlsSetupCnf, sizeof(tDot11fTDLSSetupCnf), 0);
+
+	/*
+	 * setup Fixed fields,
+	 */
+	tdlsSetupCnf.Category.category = SIR_MAC_ACTION_TDLS;
+	tdlsSetupCnf.Action.action = SIR_MAC_TDLS_SETUP_CNF;
+	tdlsSetupCnf.DialogToken.token = dialog;
+
+	populate_dot11f_link_iden(pMac, psessionEntry,
+				  &tdlsSetupCnf.LinkIdentifier, peer_mac,
+				  TDLS_INITIATOR);
+	/*
+	 * TODO: we need to see if we have to support conditions where we have
+	 * EDCA parameter info element is needed a) if we need different QOS
+	 * parameters for off channel operations or QOS is not supported on
+	 * AP link and we wanted to QOS on direct link.
+	 */
+
+	/* Check self and peer WMM capable */
+	if ((1 == pMac->lim.gLimTDLSWmmMode) &&
+	    (CHECK_BIT(peerCapability, TDLS_PEER_WMM_CAP))) {
+		pe_debug("populate WMM praram in Setup Confirm");
+		populate_dot11f_wmm_params(pMac, &tdlsSetupCnf.WMMParams,
+					   psessionEntry);
+	}
+
+	/* Check peer is VHT capable */
+	if (CHECK_BIT(peerCapability, TDLS_PEER_VHT_CAP)) {
+		populate_dot11f_vht_operation(pMac,
+					      psessionEntry,
+					      &tdlsSetupCnf.VHTOperation);
+		populate_dot11f_ht_info(pMac, &tdlsSetupCnf.HTInfo, psessionEntry);
+	} else if (CHECK_BIT(peerCapability, TDLS_PEER_HT_CAP)) {       /* Check peer is HT capable */
+		populate_dot11f_ht_info(pMac, &tdlsSetupCnf.HTInfo, psessionEntry);
+	}
+
+	/*
+	 * now we pack it.  First, how much space are we going to need?
+	 */
+	status = dot11f_get_packed_tdls_setup_cnf_size(pMac, &tdlsSetupCnf,
+						       &nPayload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to calculate the packed size for a Setup Confirm (0x%08x)",
+			status);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fProbeRequest);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while calculating the packed size for Setup Confirm (0x%08x)",
+			status);
+	}
+
+	/*
+	 * This frame is going out from PE as data frames with special ethertype
+	 * 89-0d.
+	 * 8 bytes of RFC 1042 header
+	 */
+
+	nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
+			     ? sizeof(tSirMacDataHdr3a) :
+			     sizeof(tSirMacMgmtHdr))
+		 + sizeof(eth_890d_header)
+		 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
+
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+	/* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
+	   Hence AP itself padding some bytes, which caused teardown packet is dropped at
+	   receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
+	 */
+	if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
+		padLen =
+			MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
+
+		/* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
+		if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
+			padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
+
+		nBytes += padLen;
+	}
+#endif
+
+	/* Ok-- try to allocate memory from MGMT PKT pool */
+	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				      (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a TDLS Setup Confirm",
+			nBytes);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	/* zero out the memory */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/*
+	 * IE formation, memory allocation is completed, Now form TDLS discovery
+	 * request frame
+	 */
+
+	/* fill out the buffer descriptor */
+
+	header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
+				LINK_IDEN_ADDR_OFFSET(tdlsSetupCnf),
+				TDLS_LINK_AP,
+				TDLS_INITIATOR,
+				(ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
+				psessionEntry);
+
+	status = dot11f_pack_tdls_setup_cnf(pMac, &tdlsSetupCnf, pFrame
+					    + header_offset, nPayload, &nPayload);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to pack a TDLS discovery req (0x%08x)", status);
+		cds_packet_free((void *)pPacket);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while packing TDLS Discovery Request (0x%08x)",
+			status);
+	}
+
+	/* Copy the additional IE. */
+	/* TODO : addIe is added at the end of the frame. This means it doesn't */
+	/* follow the order. This should be ok, but we should consider changing this */
+	/* if there is any IOT issue. */
+	if (addIeLen != 0) {
+		qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
+			     addIeLen);
+	}
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+	if (padLen != 0) {
+		/* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
+		uint8_t *padVendorSpecific =
+			pFrame + header_offset + nPayload + addIeLen;
+		/* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
+		padVendorSpecific[0] = 221;
+		padVendorSpecific[1] = padLen - 2;
+		padVendorSpecific[2] = 0x00;
+		padVendorSpecific[3] = 0xA0;
+		padVendorSpecific[4] = 0xC6;
+
+		pe_debug("Padding Vendor Specific Ie Len: %d", padLen);
+
+		/* padding zero if more than 5 bytes are required */
+		if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
+			qdf_mem_set(pFrame + header_offset + nPayload +
+				    addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
+				    padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
+	}
+#endif
+
+	pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
+		SIR_MAC_TDLS_SETUP_CNF,
+		lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_CNF),
+	       MAC_ADDR_ARRAY(peer_mac.bytes));
+
+	pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
+	lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
+				      psessionEntry, QDF_STATUS_SUCCESS,
+				      QDF_STATUS_SUCCESS);
+
+	qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
+						     (uint16_t) nBytes,
+						     TID_AC_VI,
+						     pFrame,
+						     smeSessionId, true);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pMac->lim.tdls_frm_session_id = NO_SESSION;
+		pe_err("could not send TDLS Setup Confirm frame");
+		return QDF_STATUS_E_FAILURE;
+
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/* This Function is similar to populate_dot11f_ht_caps, except that the HT Capabilities
+ * are considered from the AddStaReq rather from the cfg.dat as in populate_dot11f_ht_caps
+ */
+static QDF_STATUS lim_tdls_populate_dot11f_ht_caps(tpAniSirGlobal pMac,
+						      tpPESession psessionEntry,
+						      tSirTdlsAddStaReq *
+						      pTdlsAddStaReq,
+						      tDot11fIEHTCaps *pDot11f)
+{
+	uint32_t nCfgValue;
+	uint8_t nCfgValue8;
+	tSirMacHTParametersInfo *pHTParametersInfo;
+	union {
+		uint16_t nCfgValue16;
+		struct mlme_ht_capabilities_info ht_cap_info;
+		tSirMacExtendedHTCapabilityInfo extHtCapInfo;
+	} uHTCapabilityInfo;
+
+	tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo;
+	tSirMacASCapabilityInfo *pASCapabilityInfo;
+
+	nCfgValue = pTdlsAddStaReq->htCap.capInfo;
+
+	uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
+
+	pDot11f->advCodingCap = uHTCapabilityInfo.ht_cap_info.adv_coding_cap;
+	pDot11f->mimoPowerSave = uHTCapabilityInfo.ht_cap_info.mimo_power_save;
+	pDot11f->greenField = uHTCapabilityInfo.ht_cap_info.green_field;
+	pDot11f->shortGI20MHz = uHTCapabilityInfo.ht_cap_info.short_gi_20_mhz;
+	pDot11f->shortGI40MHz = uHTCapabilityInfo.ht_cap_info.short_gi_40_mhz;
+	pDot11f->txSTBC = uHTCapabilityInfo.ht_cap_info.tx_stbc;
+	pDot11f->rxSTBC = uHTCapabilityInfo.ht_cap_info.rx_stbc;
+	pDot11f->delayedBA = uHTCapabilityInfo.ht_cap_info.delayed_ba;
+	pDot11f->maximalAMSDUsize =
+		uHTCapabilityInfo.ht_cap_info.maximal_amsdu_size;
+	pDot11f->dsssCckMode40MHz =
+		uHTCapabilityInfo.ht_cap_info.dsss_cck_mode_40_mhz;
+	pDot11f->psmp = uHTCapabilityInfo.ht_cap_info.psmp;
+	pDot11f->stbcControlFrame =
+		uHTCapabilityInfo.ht_cap_info.stbc_control_frame;
+	pDot11f->lsigTXOPProtection =
+		uHTCapabilityInfo.ht_cap_info.l_sig_tx_op_protection;
+
+	/*
+	 * All sessionized entries will need the check below
+	 * Only in case of NO session
+	 */
+	if (psessionEntry == NULL) {
+		pDot11f->supportedChannelWidthSet =
+			uHTCapabilityInfo.ht_cap_info.
+			supported_channel_width_set;
+	} else {
+		pDot11f->supportedChannelWidthSet =
+			psessionEntry->htSupportedChannelWidthSet;
+	}
+
+	/* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is
+	   eHT_CHANNEL_WIDTH_20MHZ */
+	if (pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) {
+		pDot11f->shortGI40MHz = 0;
+	}
+
+	pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d",
+		pDot11f->supportedChannelWidthSet,
+		pDot11f->mimoPowerSave,
+		pDot11f->greenField,
+		pDot11f->shortGI20MHz,
+		pDot11f->shortGI40MHz,
+		pDot11f->dsssCckMode40MHz);
+
+	nCfgValue = pTdlsAddStaReq->htCap.ampduParamsInfo;
+
+	nCfgValue8 = (uint8_t) nCfgValue;
+	pHTParametersInfo = (tSirMacHTParametersInfo *) &nCfgValue8;
+
+	pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor;
+	pDot11f->mpduDensity = pHTParametersInfo->mpduDensity;
+	pDot11f->reserved1 = pHTParametersInfo->reserved;
+
+	pe_debug("AMPDU Param: %x", nCfgValue);
+
+	qdf_mem_copy(pDot11f->supportedMCSSet, pTdlsAddStaReq->htCap.suppMcsSet,
+		     SIZE_OF_SUPPORTED_MCS_SET);
+
+	nCfgValue = pTdlsAddStaReq->htCap.extendedHtCapInfo;
+
+	uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
+
+	pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco;
+	pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime;
+	pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback;
+
+	nCfgValue = pTdlsAddStaReq->htCap.txBFCapInfo;
+
+	pTxBFCapabilityInfo = (tSirMacTxBFCapabilityInfo *) &nCfgValue;
+	pDot11f->txBF = pTxBFCapabilityInfo->txBF;
+	pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding;
+	pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding;
+	pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF;
+	pDot11f->txZLF = pTxBFCapabilityInfo->txZLF;
+	pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF;
+	pDot11f->calibration = pTxBFCapabilityInfo->calibration;
+	pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF;
+	pDot11f->explicitUncompressedSteeringMatrix =
+		pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix;
+	pDot11f->explicitBFCSIFeedback =
+		pTxBFCapabilityInfo->explicitBFCSIFeedback;
+	pDot11f->explicitUncompressedSteeringMatrixFeedback =
+		pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback;
+	pDot11f->explicitCompressedSteeringMatrixFeedback =
+		pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback;
+	pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae;
+	pDot11f->uncompressedSteeringMatrixBFAntennae =
+		pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae;
+	pDot11f->compressedSteeringMatrixBFAntennae =
+		pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae;
+
+	nCfgValue = pTdlsAddStaReq->htCap.antennaSelectionInfo;
+
+	nCfgValue8 = (uint8_t) nCfgValue;
+
+	pASCapabilityInfo = (tSirMacASCapabilityInfo *) &nCfgValue8;
+	pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection;
+	pDot11f->explicitCSIFeedbackTx =
+		pASCapabilityInfo->explicitCSIFeedbackTx;
+	pDot11f->antennaIndicesFeedbackTx =
+		pASCapabilityInfo->antennaIndicesFeedbackTx;
+	pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback;
+	pDot11f->antennaIndicesFeedback =
+		pASCapabilityInfo->antennaIndicesFeedback;
+	pDot11f->rxAS = pASCapabilityInfo->rxAS;
+	pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs;
+
+	pDot11f->present = pTdlsAddStaReq->htcap_present;
+
+	return QDF_STATUS_SUCCESS;
+
+}
+
+static QDF_STATUS
+lim_tdls_populate_dot11f_vht_caps(tpAniSirGlobal pMac,
+				  tSirTdlsAddStaReq *pTdlsAddStaReq,
+				  tDot11fIEVHTCaps *pDot11f)
+{
+	uint32_t nCfgValue = 0;
+	union {
+		uint32_t nCfgValue32;
+		tSirMacVHTCapabilityInfo vhtCapInfo;
+	} uVHTCapabilityInfo;
+	union {
+		uint16_t nCfgValue16;
+		tSirMacVHTTxSupDataRateInfo vhtTxSupDataRateInfo;
+		tSirMacVHTRxSupDataRateInfo vhtRxsupDataRateInfo;
+	} uVHTSupDataRateInfo;
+
+	pDot11f->present = pTdlsAddStaReq->vhtcap_present;
+
+	nCfgValue = pTdlsAddStaReq->vhtCap.vhtCapInfo;
+	uVHTCapabilityInfo.nCfgValue32 = nCfgValue;
+
+	pDot11f->maxMPDULen = uVHTCapabilityInfo.vhtCapInfo.maxMPDULen;
+	pDot11f->supportedChannelWidthSet =
+		uVHTCapabilityInfo.vhtCapInfo.supportedChannelWidthSet;
+	pDot11f->ldpcCodingCap = uVHTCapabilityInfo.vhtCapInfo.ldpcCodingCap;
+	pDot11f->shortGI80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI80MHz;
+	pDot11f->shortGI160and80plus80MHz =
+		uVHTCapabilityInfo.vhtCapInfo.shortGI160and80plus80MHz;
+	pDot11f->txSTBC = uVHTCapabilityInfo.vhtCapInfo.txSTBC;
+	pDot11f->rxSTBC = uVHTCapabilityInfo.vhtCapInfo.rxSTBC;
+	pDot11f->suBeamFormerCap = 0;
+	pDot11f->suBeamformeeCap = 0;
+	pDot11f->csnofBeamformerAntSup =
+		uVHTCapabilityInfo.vhtCapInfo.csnofBeamformerAntSup;
+	pDot11f->numSoundingDim = uVHTCapabilityInfo.vhtCapInfo.numSoundingDim;
+	pDot11f->muBeamformerCap = 0;
+	pDot11f->muBeamformeeCap = 0;
+	pDot11f->vhtTXOPPS = uVHTCapabilityInfo.vhtCapInfo.vhtTXOPPS;
+	pDot11f->htcVHTCap = uVHTCapabilityInfo.vhtCapInfo.htcVHTCap;
+	pDot11f->maxAMPDULenExp = uVHTCapabilityInfo.vhtCapInfo.maxAMPDULenExp;
+	pDot11f->vhtLinkAdaptCap =
+		uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap;
+	pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern;
+	pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern;
+	pDot11f->reserved1 = uVHTCapabilityInfo.vhtCapInfo.reserved1;
+
+	pDot11f->rxMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.rxMcsMap;
+
+	nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.rxHighest;
+	uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
+	pDot11f->rxHighSupDataRate =
+		uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate;
+
+	pDot11f->txMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.txMcsMap;
+
+	nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.txHighest;
+	uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
+	pDot11f->txSupDataRate =
+		uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate;
+
+	pDot11f->reserved3 = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.reserved;
+
+	lim_log_vht_cap(pMac, pDot11f);
+
+	return QDF_STATUS_SUCCESS;
+
+}
+
+/**
+ * lim_tdls_populate_matching_rate_set() - populate matching rate set
+ *
+ * @mac_ctx  - global MAC context
+ * @stads - station hash entry
+ * @supp_rate_set - pointer to supported rate set
+ * @supp_rates_len - length of the supported rates
+ * @supp_mcs_set - pointer to supported MSC set
+ * @session_entry - pointer to PE session entry
+ * @vht_caps - pointer to VHT capability
+ *
+ *
+ * This function gets set of available rates from the config and compare them
+ * against the set of received supported rates. After the comparison station
+ * entry's rates is populated with 11A rates and 11B rates.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure.
+ */
+static QDF_STATUS
+lim_tdls_populate_matching_rate_set(tpAniSirGlobal mac_ctx, tpDphHashNode stads,
+				    uint8_t *supp_rate_set,
+				    uint8_t supp_rates_len,
+				    uint8_t *supp_mcs_set,
+				    tpPESession session_entry,
+				    tDot11fIEVHTCaps *vht_caps)
+{
+	tSirMacRateSet temp_rate_set;
+	uint32_t i, j, val, min, is_a_rate;
+	tSirMacRateSet temp_rate_set2;
+	uint32_t phymode;
+	uint8_t mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
+	tpSirSupportedRates rates;
+	uint8_t a_rateindex = 0;
+	uint8_t b_rateindex = 0;
+	uint8_t nss;
+	qdf_size_t val_len;
+
+	is_a_rate = 0;
+	temp_rate_set2.numRates = 0;
+
+	lim_get_phy_mode(mac_ctx, &phymode, NULL);
+
+	/* get own rate set */
+	val_len = mac_ctx->mlme_cfg->rates.opr_rate_set.len;
+	if (wlan_mlme_get_cfg_str((uint8_t *)&temp_rate_set.rate,
+				  &mac_ctx->mlme_cfg->rates.opr_rate_set,
+				  &val_len) != QDF_STATUS_SUCCESS) {
+		/* Could not get rateset from CFG. Log error. */
+		pe_err("could not retrieve rateset");
+		val_len = 0;
+	}
+	temp_rate_set.numRates = val_len;
+
+	if (phymode == WNI_CFG_PHY_MODE_11G) {
+		/* get own extended rate set */
+		val_len = mac_ctx->mlme_cfg->rates.ext_opr_rate_set.len;
+		if (wlan_mlme_get_cfg_str(
+			(uint8_t *)&temp_rate_set2.rate,
+			&mac_ctx->mlme_cfg->rates.ext_opr_rate_set,
+			&val_len) != QDF_STATUS_SUCCESS) {
+			/* Could not get rateset from CFG. Log error. */
+			pe_err("could not retrieve extrateset");
+			val_len = 0;
+		}
+			temp_rate_set2.numRates = val_len;
+	}
+
+	if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
+		pe_err("more than 12 rates in CFG");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/**
+	 * Handling of the rate set IEs is the following:
+	 * - keep only rates that we support and that the station supports
+	 * - sort and the rates into the pSta->rate array
+	 */
+
+	/* Copy all rates in temp_rate_set, there are 12 rates max */
+	for (i = 0; i < temp_rate_set2.numRates; i++)
+		temp_rate_set.rate[i + temp_rate_set.numRates] =
+			temp_rate_set2.rate[i];
+
+	temp_rate_set.numRates += temp_rate_set2.numRates;
+
+	/**
+	 * Sort rates in temp_rate_set (they are likely to be already sorted)
+	 * put the result in temp_rate_set2
+	 */
+	temp_rate_set2.numRates = 0;
+
+	for (i = 0; i < temp_rate_set.numRates; i++) {
+		min = 0;
+		val = 0xff;
+
+		for (j = 0; j < temp_rate_set.numRates; j++)
+			if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) < val) {
+				val = temp_rate_set.rate[j] & 0x7f;
+				min = j;
+			}
+
+		temp_rate_set2.rate[temp_rate_set2.numRates++] =
+			temp_rate_set.rate[min];
+		temp_rate_set.rate[min] = 0xff;
+	}
+
+	/**
+	 * Copy received rates in temp_rate_set, the parser has ensured
+	 * unicity of the rates so there cannot be more than 12 .
+	 */
+	if (supp_rates_len > SIR_MAC_RATESET_EID_MAX) {
+		pe_warn("Supported rates length: %d more than the Max limit, reset to Max",
+			supp_rates_len);
+		supp_rates_len = SIR_MAC_RATESET_EID_MAX;
+	}
+
+	for (i = 0; i < supp_rates_len; i++)
+		temp_rate_set.rate[i] = supp_rate_set[i];
+
+	temp_rate_set.numRates = supp_rates_len;
+
+	rates = &stads->supportedRates;
+	qdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
+
+	for (i = 0; i < temp_rate_set2.numRates; i++) {
+		for (j = 0; j < temp_rate_set.numRates; j++) {
+			if ((temp_rate_set2.rate[i] & 0x7F) !=
+				(temp_rate_set.rate[j] & 0x7F))
+				continue;
+
+			if ((b_rateindex > SIR_NUM_11B_RATES) ||
+			    (a_rateindex > SIR_NUM_11A_RATES)) {
+				pe_warn("Invalid number of rates (11b->%d, 11a->%d)",
+					b_rateindex, a_rateindex);
+				return QDF_STATUS_E_FAILURE;
+			}
+			if (sirIsArate(temp_rate_set2.rate[i] & 0x7f)) {
+				is_a_rate = 1;
+				if (a_rateindex < SIR_NUM_11A_RATES)
+					rates->llaRates[a_rateindex++] = temp_rate_set2.rate[i];
+			} else {
+				if (b_rateindex < SIR_NUM_11B_RATES)
+					rates->llbRates[b_rateindex++] = temp_rate_set2.rate[i];
+			}
+			break;
+		}
+	}
+
+	if (IS_5G_CH(session_entry->currentOperChannel))
+		nss = mac_ctx->vdev_type_nss_5g.tdls;
+	else
+		nss = mac_ctx->vdev_type_nss_2g.tdls;
+
+	nss = QDF_MIN(nss, mac_ctx->user_configured_nss);
+
+	/* compute the matching MCS rate set, if peer is 11n capable and self mode is 11n */
+#ifdef FEATURE_WLAN_TDLS
+	if (stads->mlmStaContext.htCapability)
+#else
+	if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
+	    (stads->mlmStaContext.htCapability))
+#endif
+	{
+		val_len = SIZE_OF_SUPPORTED_MCS_SET;
+		if (wlan_mlme_get_cfg_str(
+			mcsSet,
+			&mac_ctx->mlme_cfg->rates.supported_mcs_set,
+			&val_len) != QDF_STATUS_SUCCESS) {
+			/* Could not get rateset from CFG. Log error. */
+			pe_err("could not retrieve supportedMCSSet");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (NSS_1x1_MODE == nss)
+			mcsSet[1] = 0;
+		for (i = 0; i < val_len; i++)
+			stads->supportedRates.supportedMCSSet[i] =
+				mcsSet[i] & supp_mcs_set[i];
+
+		pe_debug("MCS Rate Set Bitmap from CFG and DPH");
+		for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) {
+			pe_debug("%x %x", mcsSet[i],
+				stads->supportedRates.supportedMCSSet[i]);
+		}
+	}
+	lim_populate_vht_mcs_set(mac_ctx, &stads->supportedRates, vht_caps,
+				 session_entry, nss);
+	/**
+	 * Set the erpEnabled bit if the phy is in G mode and at least
+	 * one A rate is supported
+	 */
+	if ((phymode == WNI_CFG_PHY_MODE_11G) && is_a_rate)
+		stads->erpEnabled = eHAL_SET;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * update HASH node entry info
+ */
+static void lim_tdls_update_hash_node_info(tpAniSirGlobal pMac,
+					   tDphHashNode *pStaDs,
+					   tSirTdlsAddStaReq *pTdlsAddStaReq,
+					   tpPESession psessionEntry)
+{
+	tDot11fIEHTCaps htCap = {0,};
+	tDot11fIEHTCaps *htCaps;
+	tDot11fIEVHTCaps *pVhtCaps = NULL;
+	tDot11fIEVHTCaps *pVhtCaps_txbf = NULL;
+	tDot11fIEVHTCaps vhtCap;
+	uint8_t cbMode;
+
+	if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
+		populate_dot11f_ht_caps(pMac, psessionEntry, &htCap);
+	} else if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) {
+		lim_tdls_populate_dot11f_ht_caps(pMac, NULL, pTdlsAddStaReq, &htCap);
+	}
+	htCaps = &htCap;
+	if (htCaps->present) {
+		pStaDs->mlmStaContext.htCapability = 1;
+		pStaDs->htGreenfield = htCaps->greenField;
+		/*
+		 * pStaDs->htSupportedChannelWidthSet should have the base
+		 * channel capability. The htSupportedChannelWidthSet of the
+		 * TDLS link on base channel should be less than or equal to
+		 * channel width of STA-AP link. So take this setting from the
+		 * psessionEntry.
+		 */
+		pe_debug("supportedChannelWidthSet: 0x%x htSupportedChannelWidthSet: 0x%x",
+				htCaps->supportedChannelWidthSet,
+				psessionEntry->htSupportedChannelWidthSet);
+		pStaDs->htSupportedChannelWidthSet =
+				(htCaps->supportedChannelWidthSet <
+				 psessionEntry->htSupportedChannelWidthSet) ?
+				htCaps->supportedChannelWidthSet :
+				psessionEntry->htSupportedChannelWidthSet;
+		pe_debug("pStaDs->htSupportedChannelWidthSet: 0x%x",
+				pStaDs->htSupportedChannelWidthSet);
+
+		pStaDs->htMIMOPSState = htCaps->mimoPowerSave;
+		pStaDs->htMaxAmsduLength = htCaps->maximalAMSDUsize;
+		pStaDs->htAMpduDensity = htCaps->mpduDensity;
+		pStaDs->htDsssCckRate40MHzSupport = htCaps->dsssCckMode40MHz;
+		pStaDs->htShortGI20Mhz = htCaps->shortGI20MHz;
+		pStaDs->htShortGI40Mhz = htCaps->shortGI40MHz;
+		pStaDs->htMaxRxAMpduFactor = htCaps->maxRxAMPDUFactor;
+		lim_fill_rx_highest_supported_rate(pMac,
+						   &pStaDs->supportedRates.
+						   rxHighestDataRate,
+						   htCaps->supportedMCSSet);
+		pStaDs->baPolicyFlag = 0xFF;
+		pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_N;
+		pStaDs->ht_caps = pTdlsAddStaReq->htCap.capInfo;
+	} else {
+		pStaDs->mlmStaContext.htCapability = 0;
+		pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_BG;
+	}
+	lim_tdls_populate_dot11f_vht_caps(pMac, pTdlsAddStaReq, &vhtCap);
+	pVhtCaps = &vhtCap;
+	if (pVhtCaps->present) {
+		pStaDs->mlmStaContext.vhtCapability = 1;
+
+		/*
+		 * 11.21.1 General: The channel width of the TDLS direct
+		 * link on the base channel shall not exceed the channel
+		 * width of the BSS to which the TDLS peer STAs are
+		 * associated.
+		 */
+		if (psessionEntry->ch_width)
+			pStaDs->vhtSupportedChannelWidthSet =
+					psessionEntry->ch_width - 1;
+		else
+			pStaDs->vhtSupportedChannelWidthSet =
+					psessionEntry->ch_width;
+
+		pe_debug("vhtSupportedChannelWidthSet: %hu htSupportedChannelWidthSet: %hu",
+			pStaDs->vhtSupportedChannelWidthSet,
+			pStaDs->htSupportedChannelWidthSet);
+
+		pStaDs->vhtLdpcCapable = pVhtCaps->ldpcCodingCap;
+		pStaDs->vhtBeamFormerCapable = 0;
+		pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_AC;
+		pVhtCaps_txbf = (tDot11fIEVHTCaps *) (&pTdlsAddStaReq->vhtCap);
+		pVhtCaps_txbf->suBeamformeeCap = 0;
+		pVhtCaps_txbf->suBeamFormerCap = 0;
+		pVhtCaps_txbf->muBeamformerCap = 0;
+		pVhtCaps_txbf->muBeamformeeCap = 0;
+		pStaDs->vht_caps = pTdlsAddStaReq->vhtCap.vhtCapInfo;
+	} else {
+		pStaDs->mlmStaContext.vhtCapability = 0;
+		pStaDs->vhtSupportedChannelWidthSet =
+			WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+	}
+
+	/*
+	 * Calculate the Secondary Coannel Offset if our
+	 * own channel bonding state is enabled
+	 */
+	if (psessionEntry->htSupportedChannelWidthSet) {
+		cbMode = lim_select_cb_mode(pStaDs, psessionEntry,
+				    psessionEntry->currentOperChannel,
+				    pStaDs->vhtSupportedChannelWidthSet);
+
+		if (pStaDs->mlmStaContext.vhtCapability)
+			pStaDs->htSecondaryChannelOffset =
+					lim_get_htcb_state(cbMode);
+		else
+			pStaDs->htSecondaryChannelOffset = cbMode;
+	}
+	/* Lets enable QOS parameter */
+	pStaDs->qosMode = (pTdlsAddStaReq->capability & CAPABILITIES_QOS_OFFSET)
+				|| pTdlsAddStaReq->htcap_present;
+	pStaDs->wmeEnabled = 1;
+	pStaDs->lleEnabled = 0;
+	/*  TDLS Dummy AddSTA does not have qosInfo , is it OK ??
+	 */
+	pStaDs->qos.capability.qosInfo =
+		(*(tSirMacQosInfoStation *) &pTdlsAddStaReq->uapsd_queues);
+
+	/* populate matching rate set */
+
+	/* TDLS Dummy AddSTA does not have HTCap,VHTCap,Rates info , is it OK ??
+	 */
+	lim_tdls_populate_matching_rate_set(pMac, pStaDs,
+					    pTdlsAddStaReq->supported_rates,
+					    pTdlsAddStaReq->supported_rates_length,
+					    (uint8_t *) pTdlsAddStaReq->htCap.
+					    suppMcsSet, psessionEntry, pVhtCaps);
+
+	/*  TDLS Dummy AddSTA does not have right capability , is it OK ??
+	 */
+	pStaDs->mlmStaContext.capabilityInfo =
+		(*(tSirMacCapabilityInfo *) &pTdlsAddStaReq->capability);
+
+	return;
+}
+
+/*
+ * Add STA for TDLS setup procedure
+ */
+static QDF_STATUS lim_tdls_setup_add_sta(tpAniSirGlobal pMac,
+					    tSirTdlsAddStaReq *pAddStaReq,
+					    tpPESession psessionEntry)
+{
+	tpDphHashNode pStaDs = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint16_t aid = 0;
+
+	pStaDs = dph_lookup_hash_entry(pMac, pAddStaReq->peermac.bytes, &aid,
+				       &psessionEntry->dph.dphHashTable);
+
+	if (pStaDs && pAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
+		pe_err("TDLS entry for peer: "MAC_ADDRESS_STR " already exist, cannot add new entry",
+			MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
+			return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pStaDs && pStaDs->staType != STA_ENTRY_TDLS_PEER) {
+		pe_err("Non TDLS entry for peer: "MAC_ADDRESS_STR " already exist",
+			MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
+			return QDF_STATUS_E_FAILURE;
+	}
+
+	if (NULL == pStaDs) {
+		aid = lim_assign_peer_idx(pMac, psessionEntry);
+
+		if (!aid) {
+			pe_err("No more free AID for peer: "MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		/* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */
+		SET_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, aid);
+
+		pe_debug("Aid: %d, for peer: " MAC_ADDRESS_STR,
+			aid, MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
+		pStaDs =
+			dph_get_hash_entry(pMac, aid,
+					   &psessionEntry->dph.dphHashTable);
+
+		if (pStaDs) {
+			(void)lim_del_sta(pMac, pStaDs, false /*asynchronous */,
+					  psessionEntry);
+			lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, aid,
+						  psessionEntry);
+		}
+
+		pStaDs = dph_add_hash_entry(pMac, pAddStaReq->peermac.bytes,
+					 aid, &psessionEntry->dph.dphHashTable);
+
+		if (NULL == pStaDs) {
+			pe_err("add hash entry failed");
+			QDF_ASSERT(0);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	lim_tdls_update_hash_node_info(pMac, pStaDs, pAddStaReq, psessionEntry);
+
+	pStaDs->staType = STA_ENTRY_TDLS_PEER;
+
+	status =
+		lim_add_sta(pMac, pStaDs,
+			    (pAddStaReq->tdlsAddOper ==
+			     TDLS_OPER_UPDATE) ? true : false, psessionEntry);
+
+	if (QDF_STATUS_SUCCESS != status) {
+		/* should not fail */
+		QDF_ASSERT(0);
+	}
+	return status;
+}
+
+/*
+ * Del STA, after Link is teardown or discovery response sent on direct link
+ */
+static QDF_STATUS lim_tdls_del_sta(tpAniSirGlobal pMac,
+				      struct qdf_mac_addr peerMac,
+				      tpPESession psessionEntry,
+				      bool resp_reqd)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint16_t peerIdx = 0;
+	tpDphHashNode pStaDs;
+
+	pStaDs = dph_lookup_hash_entry(pMac, peerMac.bytes, &peerIdx,
+				       &psessionEntry->dph.dphHashTable);
+
+	if (pStaDs) {
+		pe_debug("DEL STA peer MAC: "MAC_ADDRESS_STR,
+			 MAC_ADDR_ARRAY(pStaDs->staAddr));
+
+		pe_debug("STA type: %x, sta idx: %x resp_reqd: %d",
+			 pStaDs->staType,
+			 pStaDs->staIndex,
+			 resp_reqd);
+
+		status = lim_del_sta(pMac, pStaDs, resp_reqd, psessionEntry);
+	} else {
+		pe_debug("DEL STA peer MAC: "MAC_ADDRESS_STR" not found",
+			 MAC_ADDR_ARRAY(peerMac.bytes));
+	}
+
+	return status;
+}
+
+/*
+ * Once Link is setup with PEER, send Add STA ind to SME
+ */
+static QDF_STATUS lim_send_sme_tdls_add_sta_rsp(tpAniSirGlobal pMac,
+						uint8_t sessionId,
+						tSirMacAddr peerMac,
+						uint8_t updateSta,
+						tDphHashNode *pStaDs, uint8_t status)
+{
+	struct scheduler_msg mmhMsg = { 0 };
+	tSirTdlsAddStaRsp *addStaRsp = NULL;
+
+	mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP;
+
+	addStaRsp = qdf_mem_malloc(sizeof(tSirTdlsAddStaRsp));
+	if (!addStaRsp)
+		return QDF_STATUS_E_NOMEM;
+
+	addStaRsp->sessionId = sessionId;
+	addStaRsp->statusCode = status;
+	if (pStaDs) {
+		addStaRsp->staId = pStaDs->staIndex;
+	}
+	if (peerMac) {
+		qdf_mem_copy(addStaRsp->peermac.bytes,
+			     (uint8_t *) peerMac, QDF_MAC_ADDR_SIZE);
+	}
+	if (updateSta)
+		addStaRsp->tdlsAddOper = TDLS_OPER_UPDATE;
+	else
+		addStaRsp->tdlsAddOper = TDLS_OPER_ADD;
+
+	addStaRsp->length = sizeof(tSirTdlsAddStaRsp);
+	addStaRsp->messageType = eWNI_SME_TDLS_ADD_STA_RSP;
+	addStaRsp->psoc = pMac->psoc;
+	mmhMsg.bodyptr = addStaRsp;
+	mmhMsg.callback = tgt_tdls_add_peer_rsp;
+
+	return scheduler_post_message(QDF_MODULE_ID_PE,
+				      QDF_MODULE_ID_TDLS,
+				      QDF_MODULE_ID_TARGET_IF, &mmhMsg);
+}
+
+/*
+ * STA RSP received from HAL
+ */
+QDF_STATUS lim_process_tdls_add_sta_rsp(tpAniSirGlobal pMac, void *msg,
+					tpPESession psessionEntry)
+{
+	tAddStaParams *pAddStaParams = (tAddStaParams *) msg;
+	uint8_t status = QDF_STATUS_SUCCESS;
+	tDphHashNode *pStaDs = NULL;
+	uint16_t aid = 0;
+
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+	pe_debug("staIdx: %d, staMac: "MAC_ADDRESS_STR,
+	       pAddStaParams->staIdx,
+	       MAC_ADDR_ARRAY(pAddStaParams->staMac));
+
+	if (pAddStaParams->status != QDF_STATUS_SUCCESS) {
+		QDF_ASSERT(0);
+		pe_err("Add sta failed ");
+		status = QDF_STATUS_E_FAILURE;
+		goto add_sta_error;
+	}
+
+	pStaDs = dph_lookup_hash_entry(pMac, pAddStaParams->staMac, &aid,
+				       &psessionEntry->dph.dphHashTable);
+	if (NULL == pStaDs) {
+		pe_err("pStaDs is NULL ");
+		status = QDF_STATUS_E_FAILURE;
+		goto add_sta_error;
+	}
+
+	pStaDs->bssId = pAddStaParams->bssIdx;
+	pStaDs->staIndex = pAddStaParams->staIdx;
+	pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+	pStaDs->valid = 1;
+add_sta_error:
+	status = lim_send_sme_tdls_add_sta_rsp(pMac, psessionEntry->smeSessionId,
+					       pAddStaParams->staMac,
+					       pAddStaParams->updateSta, pStaDs,
+					       status);
+	qdf_mem_free(pAddStaParams);
+	return status;
+}
+
+/**
+ * lim_send_tdls_comp_mgmt_rsp() - Send Response to upper layers
+ * @mac_ctx:          Pointer to Global MAC structure
+ * @msg_type:         Indicates message type
+ * @result_code:       Indicates the result of previously issued
+ *                    eWNI_SME_msg_type_REQ message
+ *
+ * This function is called by lim_process_sme_req_messages() to send
+ * eWNI_SME_START_RSP, eWNI_SME_STOP_BSS_RSP
+ * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC
+ * Software.
+ *
+ * Return: None
+ */
+
+static void
+lim_send_tdls_comp_mgmt_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+	 tSirResultCodes result_code, uint8_t sme_session_id,
+	 uint16_t sme_transaction_id)
+{
+	struct scheduler_msg msg = {0};
+	tSirSmeRsp *sme_rsp;
+
+	pe_debug("Sending message %s with reasonCode %s",
+		lim_msg_str(msg_type), lim_result_code_str(result_code));
+
+	sme_rsp = qdf_mem_malloc(sizeof(tSirSmeRsp));
+	if (!sme_rsp)
+		return;
+
+	sme_rsp->messageType = msg_type;
+	sme_rsp->length = sizeof(tSirSmeRsp);
+	sme_rsp->statusCode = result_code;
+
+	sme_rsp->sessionId = sme_session_id;
+	sme_rsp->transactionId = sme_transaction_id;
+
+	msg.type = msg_type;
+	sme_rsp->psoc = mac_ctx->psoc;
+	msg.bodyptr = sme_rsp;
+	msg.callback = tgt_tdls_send_mgmt_rsp;
+	scheduler_post_message(QDF_MODULE_ID_PE,
+			       QDF_MODULE_ID_TDLS,
+			       QDF_MODULE_ID_TARGET_IF, &msg);
+
+}
+
+/**
+ * lim_process_sme_tdls_mgmt_send_req() - send out tdls management frames
+ *
+ * @mac_ctx - global mac context
+ * @msg - message buffer received from SME.
+ *
+ * Process Send Mgmt Request from SME and transmit to AP.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error code otherwise
+ */
+QDF_STATUS lim_process_sme_tdls_mgmt_send_req(tpAniSirGlobal mac_ctx,
+						 uint32_t *msg)
+{
+	/* get all discovery request parameters */
+	tSirTdlsSendMgmtReq *send_req = (tSirTdlsSendMgmtReq *) msg;
+	tpPESession session_entry;
+	uint8_t session_id;
+	tSirResultCodes result_code = eSIR_SME_INVALID_PARAMETERS;
+
+	pe_debug("Send Mgmt Received");
+	session_entry = pe_find_session_by_bssid(mac_ctx,
+					 send_req->bssid.bytes, &session_id);
+	if (NULL == session_entry) {
+		pe_err("PE Session does not exist for given sme session_id %d",
+			send_req->sessionId);
+		goto lim_tdls_send_mgmt_error;
+	}
+
+	/* check if we are in proper state to work as TDLS client */
+	if (!LIM_IS_STA_ROLE(session_entry)) {
+		pe_err("send mgmt received in wrong system Role: %d",
+			  GET_LIM_SYSTEM_ROLE(session_entry));
+		goto lim_tdls_send_mgmt_error;
+	}
+
+	if (lim_is_roam_synch_in_progress(session_entry)) {
+		pe_err("roaming in progress, reject mgmt! for session %d",
+		       send_req->sessionId);
+		result_code = eSIR_SME_REFUSED;
+		goto lim_tdls_send_mgmt_error;
+	}
+
+	/*
+	 * if we are still good, go ahead and check if we are in proper state to
+	 * do TDLS discovery req/rsp/....frames.
+	 */
+	if ((session_entry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
+	    (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
+		pe_err("send mgmt received in invalid LIMsme state: %d",
+			session_entry->limSmeState);
+		goto lim_tdls_send_mgmt_error;
+	}
+
+	cds_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS,
+		SIR_MAC_ACTION_TX, SIR_MAC_MGMT_ACTION,
+		send_req->reqType, send_req->peer_mac.bytes);
+
+	switch (send_req->reqType) {
+	case SIR_MAC_TDLS_DIS_REQ:
+		pe_debug("Transmit Discovery Request Frame");
+		/* format TDLS discovery request frame and transmit it */
+		lim_send_tdls_dis_req_frame(mac_ctx, send_req->peer_mac,
+					    send_req->dialog, session_entry,
+					    send_req->ac);
+		result_code = eSIR_SME_SUCCESS;
+		break;
+	case SIR_MAC_TDLS_DIS_RSP:
+		pe_debug("Transmit Discovery Response Frame");
+		/* Send a response mgmt action frame */
+		lim_send_tdls_dis_rsp_frame(mac_ctx, send_req->peer_mac,
+			send_req->dialog, session_entry, &send_req->addIe[0],
+			(send_req->length - sizeof(tSirTdlsSendMgmtReq)));
+		result_code = eSIR_SME_SUCCESS;
+		break;
+	case SIR_MAC_TDLS_SETUP_REQ:
+		pe_debug("Transmit Setup Request Frame");
+		lim_send_tdls_link_setup_req_frame(mac_ctx,
+			send_req->peer_mac, send_req->dialog, session_entry,
+			&send_req->addIe[0],
+			(send_req->length - sizeof(tSirTdlsSendMgmtReq)),
+			send_req->ac);
+		result_code = eSIR_SME_SUCCESS;
+		break;
+	case SIR_MAC_TDLS_SETUP_RSP:
+		pe_debug("Transmit Setup Response Frame");
+		lim_send_tdls_setup_rsp_frame(mac_ctx,
+			send_req->peer_mac, send_req->dialog, session_entry,
+			send_req->statusCode, &send_req->addIe[0],
+			(send_req->length - sizeof(tSirTdlsSendMgmtReq)),
+			send_req->ac);
+		result_code = eSIR_SME_SUCCESS;
+		break;
+	case SIR_MAC_TDLS_SETUP_CNF:
+		pe_debug("Transmit Setup Confirm Frame");
+		lim_send_tdls_link_setup_cnf_frame(mac_ctx,
+			send_req->peer_mac, send_req->dialog,
+			send_req->peerCapability, session_entry,
+			&send_req->addIe[0],
+			(send_req->length - sizeof(tSirTdlsSendMgmtReq)),
+			send_req->ac);
+		result_code = eSIR_SME_SUCCESS;
+		break;
+	case SIR_MAC_TDLS_TEARDOWN:
+		pe_debug("Transmit Teardown Frame");
+		lim_send_tdls_teardown_frame(mac_ctx,
+			send_req->peer_mac, send_req->statusCode,
+			send_req->responder, session_entry,
+			&send_req->addIe[0],
+			(send_req->length - sizeof(tSirTdlsSendMgmtReq)),
+			send_req->ac);
+		result_code = eSIR_SME_SUCCESS;
+		break;
+	case SIR_MAC_TDLS_PEER_TRAFFIC_IND:
+		break;
+	case SIR_MAC_TDLS_CH_SWITCH_REQ:
+		break;
+	case SIR_MAC_TDLS_CH_SWITCH_RSP:
+		break;
+	case SIR_MAC_TDLS_PEER_TRAFFIC_RSP:
+		break;
+	default:
+		break;
+	}
+
+lim_tdls_send_mgmt_error:
+	lim_send_tdls_comp_mgmt_rsp(mac_ctx, eWNI_SME_TDLS_SEND_MGMT_RSP,
+		 result_code, send_req->sessionId,
+		 send_req->transactionId);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * Once link is teardown, send Del Peer Ind to SME
+ */
+static QDF_STATUS lim_send_sme_tdls_del_sta_rsp(tpAniSirGlobal pMac,
+						uint8_t sessionId,
+						struct qdf_mac_addr peerMac,
+						tDphHashNode *pStaDs, uint8_t status)
+{
+	struct scheduler_msg mmhMsg = { 0 };
+	tSirTdlsDelStaRsp *pDelSta = NULL;
+
+	mmhMsg.type = eWNI_SME_TDLS_DEL_STA_RSP;
+
+	pDelSta = qdf_mem_malloc(sizeof(tSirTdlsDelStaRsp));
+	if (!pDelSta)
+		return QDF_STATUS_E_NOMEM;
+
+	pDelSta->sessionId = sessionId;
+	pDelSta->statusCode = status;
+	if (pStaDs) {
+		pDelSta->staId = pStaDs->staIndex;
+	} else
+		pDelSta->staId = STA_INVALID_IDX;
+
+	qdf_copy_macaddr(&pDelSta->peermac, &peerMac);
+
+	pDelSta->length = sizeof(tSirTdlsDelStaRsp);
+	pDelSta->messageType = eWNI_SME_TDLS_DEL_STA_RSP;
+	pDelSta->psoc = pMac->psoc;
+	mmhMsg.bodyptr = pDelSta;
+	mmhMsg.callback = tgt_tdls_del_peer_rsp;
+	return scheduler_post_message(QDF_MODULE_ID_PE,
+				      QDF_MODULE_ID_TDLS,
+				      QDF_MODULE_ID_TARGET_IF, &mmhMsg);
+}
+
+/*
+ * Process Send Mgmt Request from SME and transmit to AP.
+ */
+QDF_STATUS lim_process_sme_tdls_add_sta_req(tpAniSirGlobal pMac,
+					       uint32_t *pMsgBuf)
+{
+	/* get all discovery request parameters */
+	tSirTdlsAddStaReq *pAddStaReq = (tSirTdlsAddStaReq *) pMsgBuf;
+	tpPESession psessionEntry;
+	uint8_t sessionId;
+
+	pe_debug("TDLS Add STA Request Received");
+	psessionEntry =
+		pe_find_session_by_bssid(pMac, pAddStaReq->bssid.bytes,
+					 &sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("PE Session does not exist for given sme sessionId: %d",
+			pAddStaReq->sessionId);
+		goto lim_tdls_add_sta_error;
+	}
+
+	/* check if we are in proper state to work as TDLS client */
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("send mgmt received in wrong system Role: %d",
+			  GET_LIM_SYSTEM_ROLE(psessionEntry));
+		goto lim_tdls_add_sta_error;
+	}
+
+	if (lim_is_roam_synch_in_progress(psessionEntry)) {
+		pe_err("roaming in progress, reject add sta! for session %d",
+		       pAddStaReq->sessionId);
+		goto lim_tdls_add_sta_error;
+	}
+
+	/*
+	 * if we are still good, go ahead and check if we are in proper state to
+	 * do TDLS discovery req/rsp/....frames.
+	 */
+	if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
+	    (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
+		pe_err("send mgmt received in invalid LIMsme state: %d",
+			psessionEntry->limSmeState);
+		goto lim_tdls_add_sta_error;
+	}
+
+
+	/* To start with, send add STA request to HAL */
+	if (QDF_STATUS_E_FAILURE == lim_tdls_setup_add_sta(pMac, pAddStaReq, psessionEntry)) {
+		pe_err("Add TDLS Station request failed");
+		goto lim_tdls_add_sta_error;
+	}
+	return QDF_STATUS_SUCCESS;
+lim_tdls_add_sta_error:
+	lim_send_sme_tdls_add_sta_rsp(pMac,
+				      pAddStaReq->sessionId,
+				      pAddStaReq->peermac.bytes,
+				      (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE),
+				      NULL, QDF_STATUS_E_FAILURE);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * Process Del Sta Request from SME .
+ */
+QDF_STATUS lim_process_sme_tdls_del_sta_req(tpAniSirGlobal pMac,
+					       uint32_t *pMsgBuf)
+{
+	/* get all discovery request parameters */
+	tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq *) pMsgBuf;
+	tpPESession psessionEntry;
+	uint8_t sessionId;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	pe_debug("TDLS Delete STA Request Received");
+	psessionEntry =
+		pe_find_session_by_bssid(pMac, pDelStaReq->bssid.bytes,
+					 &sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("PE Session does not exist for given sme sessionId: %d",
+			pDelStaReq->sessionId);
+		lim_send_sme_tdls_del_sta_rsp(pMac, pDelStaReq->sessionId,
+					      pDelStaReq->peermac, NULL,
+					      QDF_STATUS_E_FAILURE);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* check if we are in proper state to work as TDLS client */
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_err("Del sta received in wrong system Role %d",
+			  GET_LIM_SYSTEM_ROLE(psessionEntry));
+		goto lim_tdls_del_sta_error;
+	}
+
+	if (lim_is_roam_synch_in_progress(psessionEntry)) {
+		pe_err("roaming in progress, reject del sta! for session %d",
+		       pDelStaReq->sessionId);
+		lim_send_sme_tdls_del_sta_rsp(pMac, pDelStaReq->sessionId,
+					      pDelStaReq->peermac, NULL,
+					      QDF_STATUS_E_FAILURE);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * if we are still good, go ahead and check if we are in proper state to
+	 * do TDLS discovery req/rsp/....frames.
+	 */
+	if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
+	    (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
+
+		pe_err("Del Sta received in invalid LIMsme state: (%d",
+			psessionEntry->limSmeState);
+		goto lim_tdls_del_sta_error;
+	}
+
+	status = lim_tdls_del_sta(pMac, pDelStaReq->peermac,
+				  psessionEntry, true);
+	if (status == QDF_STATUS_SUCCESS)
+		return status;
+
+lim_tdls_del_sta_error:
+	lim_send_sme_tdls_del_sta_rsp(pMac, psessionEntry->smeSessionId,
+				      pDelStaReq->peermac, NULL, QDF_STATUS_E_FAILURE);
+
+	return status;
+}
+
+/**
+ * lim_check_aid_and_delete_peer() - Function to check aid and delete peer
+ * @p_mac: pointer to mac context
+ * @session_entry: pointer to PE session
+ *
+ * This function verifies aid and delete's peer with that aid from hash table
+ *
+ * Return: None
+ */
+static void lim_check_aid_and_delete_peer(tpAniSirGlobal p_mac,
+					  tpPESession session_entry)
+{
+	tpDphHashNode stads = NULL;
+	int i, aid;
+	size_t aid_bitmap_size = sizeof(session_entry->peerAIDBitmap);
+	struct qdf_mac_addr mac_addr;
+	QDF_STATUS status;
+
+	/*
+	 * Check all the set bit in peerAIDBitmap and delete the peer
+	 * (with that aid) entry from the hash table and add the aid
+	 * in free pool
+	 */
+	pe_debug("Delete all the TDLS peer connected");
+	for (i = 0; i < aid_bitmap_size / sizeof(uint32_t); i++) {
+		for (aid = 0; aid < (sizeof(uint32_t) << 3); aid++) {
+			if (!CHECK_BIT(session_entry->peerAIDBitmap[i], aid))
+				continue;
+			stads = dph_get_hash_entry(p_mac,
+					(aid + i * (sizeof(uint32_t) << 3)),
+					&session_entry->dph.dphHashTable);
+
+			if (NULL == stads)
+				goto skip;
+
+			pe_debug("Deleting "MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(stads->staAddr));
+
+			if (!lim_is_roam_synch_in_progress(session_entry)) {
+				lim_send_deauth_mgmt_frame(p_mac,
+					eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
+					stads->staAddr, session_entry, false);
+
+				/* Delete TDLS peer */
+				qdf_mem_copy(mac_addr.bytes, stads->staAddr,
+					     QDF_MAC_ADDR_SIZE);
+
+				status = lim_tdls_del_sta(p_mac, mac_addr,
+							 session_entry, false);
+				if (status != QDF_STATUS_SUCCESS)
+					pe_debug("peer "MAC_ADDRESS_STR" not found",
+						MAC_ADDR_ARRAY(stads->staAddr));
+			}
+
+			dph_delete_hash_entry(p_mac,
+				stads->staAddr, stads->assocId,
+				&session_entry->dph.dphHashTable);
+skip:
+			lim_release_peer_idx(p_mac,
+				(aid + i * (sizeof(uint32_t) << 3)),
+				session_entry);
+			CLEAR_BIT(session_entry->peerAIDBitmap[i], aid);
+		}
+	}
+}
+
+/**
+ * lim_delete_tdls_peers() - delete tdls peers
+ *
+ * @mac_ctx - global MAC context
+ * @session_entry - PE session entry
+ *
+ * Delete all the TDLS peer connected before leaving the BSS
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error code otherwise
+ */
+QDF_STATUS lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
+				    tpPESession session_entry)
+{
+	pe_debug("Enter");
+
+	if (NULL == session_entry) {
+		pe_err("NULL session_entry");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	lim_check_aid_and_delete_peer(mac_ctx, session_entry);
+
+	if (lim_is_roam_synch_in_progress(session_entry))
+		return QDF_STATUS_SUCCESS;
+
+	tgt_tdls_peers_deleted_notification(mac_ctx->psoc,
+					    session_entry->smeSessionId);
+
+	tgt_tdls_delete_all_peers_indication(mac_ctx->psoc,
+					     session_entry->smeSessionId);
+
+	pe_debug("Exit");
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_process_sme_del_all_tdls_peers(): process delete tdls peers
+ * @p_mac: pointer to mac context
+ * @msg_buf: message buffer
+ *
+ * This function processes request to delete tdls peers
+ *
+ * Return: Success: QDF_STATUS_SUCCESS Failure: Error value
+ */
+QDF_STATUS lim_process_sme_del_all_tdls_peers(tpAniSirGlobal p_mac,
+						 uint32_t *msg_buf)
+{
+	struct sir_del_all_tdls_peers *msg;
+	tpPESession session_entry;
+	uint8_t session_id;
+
+	msg = (struct sir_del_all_tdls_peers *)msg_buf;
+	if (msg == NULL) {
+		pe_err("NULL msg");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	session_entry = pe_find_session_by_bssid(p_mac,
+						 msg->bssid.bytes, &session_id);
+	if (NULL == session_entry) {
+		pe_err("NULL psessionEntry");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	lim_check_aid_and_delete_peer(p_mac, session_entry);
+
+	tgt_tdls_peers_deleted_notification(p_mac->psoc,
+					    session_entry->smeSessionId);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_process_tdls_del_sta_rsp() - Handle WDA_DELETE_STA_RSP for TDLS
+ * @mac_ctx: Global MAC context
+ * @lim_msg: LIM message
+ * @pe_session: PE session
+ *
+ * Return: None
+ */
+void lim_process_tdls_del_sta_rsp(tpAniSirGlobal mac_ctx,
+				  struct scheduler_msg *lim_msg,
+				  tpPESession session_entry)
+{
+	tpDeleteStaParams del_sta_params = (tpDeleteStaParams) lim_msg->bodyptr;
+	tpDphHashNode sta_ds;
+	uint16_t peer_idx = 0;
+	struct qdf_mac_addr peer_mac;
+
+	if (!del_sta_params) {
+		pe_err("del_sta_params is NULL");
+		return;
+	}
+
+	sta_ds = dph_lookup_hash_entry(mac_ctx, del_sta_params->staMac,
+			&peer_idx, &session_entry->dph.dphHashTable);
+	if (!sta_ds) {
+		pe_err("DPH Entry for STA: %X is missing",
+			DPH_STA_HASH_INDEX_PEER);
+		goto skip_event;
+	}
+
+	qdf_mem_copy(peer_mac.bytes,
+			del_sta_params->staMac, QDF_MAC_ADDR_SIZE);
+
+	if (QDF_STATUS_SUCCESS != del_sta_params->status) {
+		pe_err("DEL STA failed!");
+		lim_send_sme_tdls_del_sta_rsp(mac_ctx,
+				      session_entry->smeSessionId,
+				      peer_mac, NULL, QDF_STATUS_E_FAILURE);
+		goto skip_event;
+	}
+
+	pe_debug("DEL STA success");
+
+	/* now send indication to SME-->HDD->TL to remove STA from TL */
+
+	lim_send_sme_tdls_del_sta_rsp(mac_ctx, session_entry->smeSessionId,
+				      peer_mac, sta_ds,
+				      QDF_STATUS_SUCCESS);
+	lim_release_peer_idx(mac_ctx, sta_ds->assocId, session_entry);
+
+	/* Clear the aid in peerAIDBitmap as this aid is now in freepool */
+	CLEAR_PEER_AID_BITMAP(session_entry->peerAIDBitmap,
+			      sta_ds->assocId);
+	lim_delete_dph_hash_entry(mac_ctx, sta_ds->staAddr, sta_ds->assocId,
+				  session_entry);
+
+skip_event:
+	qdf_mem_free(del_sta_params);
+	lim_msg->bodyptr = NULL;
+}
+
+
+#endif
diff --git a/core/mac/src/pe/lim/lim_prop_exts_utils.c b/core/mac/src/pe/lim/lim_prop_exts_utils.c
new file mode 100644
index 0000000..8ba34ed
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_prop_exts_utils.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_prop_exts_utils.cc contains the utility functions
+ * to populate, parse proprietary extensions required to
+ * support ANI feature set.
+ *
+ * Author:        Chandra Modumudi
+ * Date:          11/27/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "ani_global.h"
+#include "wni_cfg.h"
+#include "sir_common.h"
+#include "sir_debug.h"
+#include "utils_api.h"
+#include "cfg_api.h"
+#include "lim_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_trace.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "wma.h"
+#include "wlan_utility.h"
+
+#define LIM_GET_NOISE_MAX_TRY 5
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * get_local_power_constraint_probe_response() - extracts local constraint
+ * from probe response
+ * @beacon_struct: beacon structure
+ * @local_constraint: local constraint pointer
+ * @session: A pointer to session entry.
+ *
+ * Return: None
+ */
+static void get_local_power_constraint_probe_response(
+		tpSirProbeRespBeacon beacon_struct,
+		int8_t *local_constraint,
+		tpPESession session)
+{
+	if (beacon_struct->eseTxPwr.present)
+		*local_constraint =
+			beacon_struct->eseTxPwr.power_limit;
+}
+
+/**
+ * get_ese_version_ie_probe_response() - extracts ESE version IE
+ * from probe response
+ * @beacon_struct: beacon structure
+ * @session: A pointer to session entry.
+ *
+ * Return: None
+ */
+static void get_ese_version_ie_probe_response(tpAniSirGlobal mac_ctx,
+					tpSirProbeRespBeacon beacon_struct,
+					tpPESession session)
+{
+	if (mac_ctx->roam.configParam.isEseIniFeatureEnabled)
+		session->is_ese_version_ie_present =
+			beacon_struct->is_ese_ver_ie_present;
+}
+#else
+static void get_local_power_constraint_probe_response(
+		tpSirProbeRespBeacon beacon_struct,
+		int8_t *local_constraint,
+		tpPESession session)
+{
+
+}
+
+static inline void get_ese_version_ie_probe_response(tpAniSirGlobal mac_ctx,
+					tpSirProbeRespBeacon beacon_struct,
+					tpPESession session)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_11AX
+static void lim_extract_he_op(tpPESession session,
+		tSirProbeRespBeacon *beacon_struct)
+{
+	if (session->he_capable && beacon_struct->he_op.present) {
+		qdf_mem_copy(&session->he_op, &beacon_struct->he_op,
+				sizeof(session->he_op));
+		pe_debug("he_op.bss_color %d", session->he_op.bss_color);
+		pe_debug("he_op.default_pe %d", session->he_op.default_pe);
+	}
+}
+
+static bool lim_check_he_80_mcs11_supp(tpPESession session,
+		tSirProbeRespBeacon *beacon_struct) {
+	uint8_t rx_mcs_map;
+	uint8_t tx_mcs_map;
+	rx_mcs_map = beacon_struct->he_cap.rx_he_mcs_map_lt_80;
+	tx_mcs_map = beacon_struct->he_cap.tx_he_mcs_map_lt_80;
+	if ((session->nss == NSS_1x1_MODE) &&
+		((HE_GET_MCS_4_NSS(rx_mcs_map, 1) == HE_MCS_0_11) ||
+		(HE_GET_MCS_4_NSS(tx_mcs_map, 1) == HE_MCS_0_11)))
+		return true;
+
+	if ((session->nss == NSS_2x2_MODE) &&
+		((HE_GET_MCS_4_NSS(rx_mcs_map, 2) == HE_MCS_0_11) ||
+		(HE_GET_MCS_4_NSS(tx_mcs_map, 2) == HE_MCS_0_11)))
+		return true;
+
+	return false;
+}
+
+static void lim_check_he_ldpc_cap(tpPESession session,
+		tSirProbeRespBeacon *beacon_struct)
+{
+	if (session->he_capable && beacon_struct->he_cap.present) {
+		if (beacon_struct->he_cap.ldpc_coding)
+			return;
+		else if ((session->ch_width == CH_WIDTH_20MHZ) &&
+				!lim_check_he_80_mcs11_supp(session,
+					beacon_struct))
+			return;
+		session->he_capable = false;
+		pe_err("LDPC check failed for HE operation");
+		if (session->vhtCapability) {
+			session->dot11mode = WNI_CFG_DOT11_MODE_11AC;
+			pe_debug("Update dot11mode to 11ac");
+		} else {
+			session->dot11mode = WNI_CFG_DOT11_MODE_11N;
+			pe_debug("Update dot11mode to 11N");
+		}
+	}
+}
+#else
+static inline void lim_extract_he_op(tpPESession session,
+		tSirProbeRespBeacon *beacon_struct)
+{}
+static void lim_check_he_ldpc_cap(tpPESession session,
+		tSirProbeRespBeacon *beacon_struct)
+{}
+#endif
+
+static void lim_objmgr_update_vdev_nss(struct wlan_objmgr_psoc *psoc,
+				       uint8_t vdev_id, uint8_t nss)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_LEGACY_MAC_ID);
+	if (!vdev) {
+		pe_err("vdev not found for id: %d", vdev_id);
+		return;
+	}
+	wlan_vdev_obj_lock(vdev);
+	wlan_vdev_mlme_set_nss(vdev, nss);
+	wlan_vdev_obj_unlock(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
+}
+/**
+ * lim_extract_ap_capability() - extract AP's HCF/WME/WSM capability
+ * @mac_ctx: Pointer to Global MAC structure
+ * @p_ie: Pointer to starting IE in Beacon/Probe Response
+ * @ie_len: Length of all IEs combined
+ * @qos_cap: Bits are set according to capabilities
+ * @prop_cap: Pointer to prop info IE.
+ * @uapsd: pointer to uapsd
+ * @local_constraint: Pointer to local power constraint.
+ * @session: A pointer to session entry.
+ *
+ * This function is called to extract AP's HCF/WME/WSM capability
+ * from the IEs received from it in Beacon/Probe Response frames
+ *
+ * Return: None
+ */
+void
+lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie,
+	uint16_t ie_len, uint8_t *qos_cap, uint16_t *prop_cap, uint8_t *uapsd,
+	int8_t *local_constraint, tpPESession session)
+{
+	tSirProbeRespBeacon *beacon_struct;
+	uint8_t ap_bcon_ch_width;
+	bool new_ch_width_dfn = false;
+	tDot11fIEVHTOperation *vht_op;
+	uint8_t fw_vht_ch_wd;
+	uint8_t vht_ch_wd;
+	uint8_t center_freq_diff;
+	struct s_ext_cap *ext_cap;
+
+	beacon_struct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
+	if (!beacon_struct)
+		return;
+
+	*qos_cap = 0;
+	*prop_cap = 0;
+	*uapsd = 0;
+	pe_debug("The IE's being received:");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			   p_ie, ie_len);
+	if (sir_parse_beacon_ie(mac_ctx, beacon_struct, p_ie,
+		(uint32_t) ie_len) != QDF_STATUS_SUCCESS) {
+		pe_err("sir_parse_beacon_ie failed to parse beacon");
+		qdf_mem_free(beacon_struct);
+		return;
+	}
+
+	if (beacon_struct->wmeInfoPresent ||
+	    beacon_struct->wmeEdcaPresent ||
+	    beacon_struct->HTCaps.present)
+		LIM_BSS_CAPS_SET(WME, *qos_cap);
+	if (LIM_BSS_CAPS_GET(WME, *qos_cap)
+			&& beacon_struct->wsmCapablePresent)
+		LIM_BSS_CAPS_SET(WSM, *qos_cap);
+	if (beacon_struct->propIEinfo.capabilityPresent)
+		*prop_cap = beacon_struct->propIEinfo.capability;
+	if (beacon_struct->HTCaps.present)
+		mac_ctx->lim.htCapabilityPresentInBeacon = 1;
+	else
+		mac_ctx->lim.htCapabilityPresentInBeacon = 0;
+
+	pe_debug("Bcon: VHTCap.present: %d SU Beamformer: %d BSS_VHT_CAPABLE: %d",
+		beacon_struct->VHTCaps.present,
+		beacon_struct->VHTCaps.suBeamFormerCap,
+		IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps));
+
+	vht_op = &beacon_struct->VHTOperation;
+	if (IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps) &&
+			vht_op->present &&
+			session->vhtCapability) {
+		session->vhtCapabilityPresentInBeacon = 1;
+		if (((beacon_struct->Vendor1IEPresent &&
+		      beacon_struct->vendor_vht_ie.present &&
+		      beacon_struct->Vendor3IEPresent)) &&
+		      (((beacon_struct->VHTCaps.txMCSMap & VHT_MCS_3x3_MASK) ==
+			VHT_MCS_3x3_MASK) &&
+		      ((beacon_struct->VHTCaps.txMCSMap & VHT_MCS_2x2_MASK) !=
+		       VHT_MCS_2x2_MASK)))
+			session->vht_config.su_beam_formee = 0;
+	} else {
+		session->vhtCapabilityPresentInBeacon = 0;
+	}
+
+	if (session->vhtCapabilityPresentInBeacon == 1 &&
+			!session->htSupportedChannelWidthSet) {
+		if (!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable_txbf_20mhz)
+			session->vht_config.su_beam_formee = 0;
+	} else if (session->vhtCapabilityPresentInBeacon &&
+			vht_op->chanWidth) {
+		/* If VHT is supported min 80 MHz support is must */
+		ap_bcon_ch_width = vht_op->chanWidth;
+		if ((ap_bcon_ch_width == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) &&
+		     vht_op->chanCenterFreqSeg2) {
+			new_ch_width_dfn = true;
+			if (vht_op->chanCenterFreqSeg2 >
+			    vht_op->chanCenterFreqSeg1)
+			    center_freq_diff = vht_op->chanCenterFreqSeg2 -
+				    vht_op->chanCenterFreqSeg1;
+			else
+			    center_freq_diff = vht_op->chanCenterFreqSeg1 -
+				    vht_op->chanCenterFreqSeg2;
+			if (center_freq_diff == 8)
+				ap_bcon_ch_width =
+					WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
+			else if (center_freq_diff > 16)
+				ap_bcon_ch_width =
+					WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ;
+		}
+
+		fw_vht_ch_wd = wma_get_vht_ch_width();
+		vht_ch_wd = QDF_MIN(fw_vht_ch_wd, ap_bcon_ch_width);
+		/*
+		 * If the supported channel width is greater than 80MHz and
+		 * AP supports Nss > 1 in 160MHz mode then connect the STA
+		 * in 2x2 80MHz mode instead of connecting in 160MHz mode.
+		 */
+		if ((vht_ch_wd > WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) &&
+		    mac_ctx->mlme_cfg->sta.sta_prefer_80mhz_over_160mhz) {
+			if (!(IS_VHT_NSS_1x1(beacon_struct->VHTCaps.txMCSMap))
+					&&
+			   (!IS_VHT_NSS_1x1(beacon_struct->VHTCaps.rxMCSMap)))
+				vht_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+		}
+		/*
+		 * VHT OP IE old definition:
+		 * vht_op->chanCenterFreqSeg1: center freq of 80MHz/160MHz/
+		 * primary 80 in 80+80MHz.
+		 *
+		 * vht_op->chanCenterFreqSeg2: center freq of secondary 80
+		 * in 80+80MHz.
+		 *
+		 * VHT OP IE NEW definition:
+		 * vht_op->chanCenterFreqSeg1: center freq of 80MHz/primary
+		 * 80 in 80+80MHz/center freq of the 80 MHz channel segment
+		 * that contains the primary channel in 160MHz mode.
+		 *
+		 * vht_op->chanCenterFreqSeg2: center freq of secondary 80
+		 * in 80+80MHz/center freq of 160MHz.
+		 */
+		session->ch_center_freq_seg0 = vht_op->chanCenterFreqSeg1;
+		session->ch_center_freq_seg1 = vht_op->chanCenterFreqSeg2;
+		if (vht_ch_wd == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) {
+			/* DUT or AP supports only 160MHz */
+			if (ap_bcon_ch_width ==
+					WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) {
+				/* AP is in 160MHz mode */
+				if (!new_ch_width_dfn) {
+					session->ch_center_freq_seg1 =
+						vht_op->chanCenterFreqSeg1;
+					session->ch_center_freq_seg0 =
+						lim_get_80Mhz_center_channel(
+						beacon_struct->channelNumber);
+				}
+			} else {
+				/* DUT supports only 160MHz and AP is
+				 * in 80+80 mode
+				 */
+				vht_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+				session->ch_center_freq_seg1 = 0;
+			}
+		} else if (vht_ch_wd == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) {
+			/* DUT or AP supports only 80MHz */
+			if (ap_bcon_ch_width ==
+					WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ &&
+					!new_ch_width_dfn)
+				/* AP is in 160MHz mode */
+				session->ch_center_freq_seg0 =
+					lim_get_80Mhz_center_channel(
+						beacon_struct->channelNumber);
+			else
+				session->ch_center_freq_seg1 = 0;
+		}
+		session->ch_width = vht_ch_wd + 1;
+		pe_debug("cntr_freq0: %d cntr_freq1: %d width: %d",
+				session->ch_center_freq_seg0,
+				session->ch_center_freq_seg1,
+				session->ch_width);
+		if (CH_WIDTH_80MHZ < session->ch_width) {
+			session->vht_config.su_beam_former = 0;
+			session->nss = 1;
+		}
+	}
+
+	if (session->vhtCapability &&
+		session->vhtCapabilityPresentInBeacon &&
+		beacon_struct->ext_cap.present) {
+		ext_cap = (struct s_ext_cap *)beacon_struct->ext_cap.bytes;
+		session->gLimOperatingMode.present =
+			ext_cap->oper_mode_notification;
+		if (ext_cap->oper_mode_notification) {
+			if (CH_WIDTH_160MHZ > session->ch_width)
+				session->gLimOperatingMode.chanWidth =
+						session->ch_width;
+			else
+				session->gLimOperatingMode.chanWidth =
+					CH_WIDTH_160MHZ;
+		} else {
+			pe_err("AP does not support op_mode rx");
+		}
+	}
+	lim_check_he_ldpc_cap(session, beacon_struct);
+	lim_extract_he_op(session, beacon_struct);
+	/* Extract the UAPSD flag from WMM Parameter element */
+	if (beacon_struct->wmeEdcaPresent)
+		*uapsd = beacon_struct->edcaParams.qosInfo.uapsd;
+
+	if (mac_ctx->roam.configParam.allow_tpc_from_ap) {
+		if (beacon_struct->powerConstraintPresent) {
+			*local_constraint -=
+				beacon_struct->localPowerConstraint.
+					localPowerConstraints;
+		} else {
+			get_local_power_constraint_probe_response(
+				beacon_struct, local_constraint, session);
+		}
+	}
+
+	get_ese_version_ie_probe_response(mac_ctx, beacon_struct, session);
+
+	session->country_info_present = false;
+	/* Initializing before first use */
+	if (beacon_struct->countryInfoPresent)
+		session->country_info_present = true;
+	/* Check if Extended caps are present in probe resp or not */
+	if (beacon_struct->ext_cap.present)
+		session->is_ext_caps_present = true;
+	/* Update HS 2.0 Information Element */
+	if (beacon_struct->hs20vendor_ie.present) {
+		pe_debug("HS20 Indication Element Present, rel#: %u id: %u",
+			beacon_struct->hs20vendor_ie.release_num,
+			beacon_struct->hs20vendor_ie.hs_id_present);
+		qdf_mem_copy(&session->hs20vendor_ie,
+			&beacon_struct->hs20vendor_ie,
+			sizeof(tDot11fIEhs20vendor_ie) -
+			sizeof(beacon_struct->hs20vendor_ie.hs_id));
+		if (beacon_struct->hs20vendor_ie.hs_id_present)
+			qdf_mem_copy(&session->hs20vendor_ie.hs_id,
+				&beacon_struct->hs20vendor_ie.hs_id,
+				sizeof(beacon_struct->hs20vendor_ie.hs_id));
+	}
+
+	lim_objmgr_update_vdev_nss(mac_ctx->psoc, session->smeSessionId,
+				   session->nss);
+	qdf_mem_free(beacon_struct);
+	return;
+} /****** end lim_extract_ap_capability() ******/
+
+/**
+ * lim_get_htcb_state
+ *
+ ***FUNCTION:
+ * This routing provides the translation of Airgo Enum to HT enum for determining
+ * secondary channel offset.
+ * Airgo Enum is required for backward compatibility purposes.
+ *
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @return The corresponding HT enumeration
+ */
+ePhyChanBondState lim_get_htcb_state(ePhyChanBondState aniCBMode)
+{
+	switch (aniCBMode) {
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+		return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+		return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
+		return PHY_SINGLE_CHANNEL_CENTERED;
+	default:
+		return PHY_SINGLE_CHANNEL_CENTERED;
+	}
+}
diff --git a/core/mac/src/pe/lim/lim_prop_exts_utils.h b/core/mac/src/pe/lim/lim_prop_exts_utils.h
new file mode 100644
index 0000000..69026ab
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_prop_exts_utils.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011-2014, 2016 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.
+ */
+
+/*
+ *
+ * This file lim_prop_exts_utils.h contains the definitions
+ * used by all LIM modules to support proprietary features.
+ * Author:        Chandra Modumudi
+ * Date:          12/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __LIM_PROP_EXTS_UTILS_H
+#define __LIM_PROP_EXTS_UTILS_H
+
+/* Function templates */
+void limQuietBss(tpAniSirGlobal, uint32_t);
+void lim_cleanupMeasData(tpAniSirGlobal);
+void limDeleteMeasTimers(tpAniSirGlobal);
+void limStopMeasTimers(tpAniSirGlobal pMac);
+void lim_cleanupMeasResources(tpAniSirGlobal);
+void limRestorePreLearnState(tpAniSirGlobal);
+void limCollectMeasurementData(tpAniSirGlobal, uint32_t *, tpSchBeaconStruct);
+void limCollectRSSI(tpAniSirGlobal);
+void limDeleteCurrentBssWdsNode(tpAniSirGlobal);
+uint32_t limComputeAvg(tpAniSirGlobal, uint32_t, uint32_t);
+
+/* / Function to extract AP's HCF capability from IE fields */
+void lim_extract_ap_capability(tpAniSirGlobal, uint8_t *, uint16_t, uint8_t *,
+			       uint16_t *, uint8_t *, int8_t *, tpPESession);
+
+ePhyChanBondState lim_get_htcb_state(ePhyChanBondState aniCBMode);
+
+#endif /* __LIM_PROP_EXTS_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_reassoc_utils.c b/core/mac/src/pe/lim/lim_reassoc_utils.c
new file mode 100644
index 0000000..a94108f
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_reassoc_utils.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2016-2018 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: lim_reassoc_utils.c
+ *
+ * Host based roaming re-association utilities
+ */
+
+#include "cds_api.h"
+#include "ani_global.h"
+#include "wni_api.h"
+#include "sir_common.h"
+
+#include "wni_cfg.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_sta_hash_api.h"
+#include "lim_admit_control.h"
+#include "lim_send_messages.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+
+#include "qdf_types.h"
+#include "wma_types.h"
+#include "lim_types.h"
+
+/**
+ * lim_update_re_assoc_globals() - Update reassoc global data
+ * @pMac: Global MAC context
+ * @pAssocRsp: Reassociation response data
+ * @psessionEntry: PE Session
+ *
+ * This function is called to Update the Globals (LIM) during ReAssoc.
+ *
+ * Return: None
+ */
+
+void lim_update_re_assoc_globals(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
+				 tpPESession psessionEntry)
+{
+	/* Update the current Bss Information */
+	qdf_mem_copy(psessionEntry->bssId,
+		     psessionEntry->limReAssocbssId, sizeof(tSirMacAddr));
+	psessionEntry->currentOperChannel = psessionEntry->limReassocChannelId;
+	psessionEntry->htSecondaryChannelOffset =
+		psessionEntry->reAssocHtSupportedChannelWidthSet;
+	psessionEntry->htRecommendedTxWidthSet =
+		psessionEntry->reAssocHtRecommendedTxWidthSet;
+	psessionEntry->htSecondaryChannelOffset =
+		psessionEntry->reAssocHtSecondaryChannelOffset;
+	psessionEntry->limCurrentBssCaps = psessionEntry->limReassocBssCaps;
+	psessionEntry->limCurrentBssQosCaps =
+		psessionEntry->limReassocBssQosCaps;
+	psessionEntry->limCurrentBssPropCap =
+		psessionEntry->limReassocBssPropCap;
+
+	qdf_mem_copy((uint8_t *) &psessionEntry->ssId,
+		     (uint8_t *) &psessionEntry->limReassocSSID,
+		     psessionEntry->limReassocSSID.length + 1);
+
+	/* Store assigned AID for TIM processing */
+	psessionEntry->limAID = pAssocRsp->aid & 0x3FFF;
+	/** Set the State Back to ReAssoc Rsp*/
+	psessionEntry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+		       psessionEntry->limMlmState));
+
+}
+
+/**
+ * @lim_handle_del_bss_in_re_assoc_context() - DEL BSS during reassociation
+ * @pMac: Global MAC Context
+ * @pStaDs: Station Hash entry
+ * @psessionEntry: PE Session
+ *
+ * While Processing the ReAssociation Response Frame in STA,
+ *     a.immediately after receiving the Reassoc Response the RxCleanUp is
+ *        being issued and the end of DelBSS the new BSS is being added.
+ *
+ *     b. If an AP rejects the ReAssociation (Disassoc/Deauth) with some context
+ *        change, We need to update CSR with ReAssocCNF Response with the
+ *        ReAssoc Fail and the reason Code, that is also being handled in the
+ *        DELBSS context only
+ *
+ * Return: None
+ */
+void lim_handle_del_bss_in_re_assoc_context(tpAniSirGlobal pMac,
+		tpDphHashNode pStaDs, tpPESession psessionEntry)
+{
+	tLimMlmReassocCnf mlmReassocCnf;
+	tpSirBssDescription bss_desc;
+	/*
+	 * Skipped the DeleteDPH Hash Entry as we need it for the new BSS
+	 * Set the MlmState to IDLE
+	 */
+	psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+	/* Update PE session Id */
+	mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+	switch (psessionEntry->limSmeState) {
+	case eLIM_SME_WT_REASSOC_STATE:
+	{
+		tpSirAssocRsp assocRsp;
+		tpDphHashNode pStaDs;
+		QDF_STATUS retStatus = QDF_STATUS_SUCCESS;
+		tpSchBeaconStruct beacon_struct;
+
+		beacon_struct = qdf_mem_malloc(sizeof(tSchBeaconStruct));
+		if (!beacon_struct) {
+			mlmReassocCnf.resultCode =
+					eSIR_SME_RESOURCES_UNAVAILABLE;
+			mlmReassocCnf.protStatusCode =
+					eSIR_MAC_UNSPEC_FAILURE_STATUS;
+			lim_delete_dph_hash_entry(pMac, psessionEntry->bssId,
+				DPH_STA_HASH_INDEX_PEER, psessionEntry);
+			goto error;
+		}
+		/* Delete the older STA Table entry */
+		lim_delete_dph_hash_entry(pMac, psessionEntry->bssId,
+				DPH_STA_HASH_INDEX_PEER, psessionEntry);
+		/*
+		 * Add an entry for AP to hash table
+		 * maintained by DPH module
+		 */
+		pStaDs = dph_add_hash_entry(pMac,
+				psessionEntry->limReAssocbssId,
+				DPH_STA_HASH_INDEX_PEER,
+				&psessionEntry->dph.dphHashTable);
+		if (pStaDs == NULL) {
+			/* Could not add hash table entry */
+			pe_err("could not add hash entry at DPH for");
+			lim_print_mac_addr(pMac,
+				psessionEntry->limReAssocbssId, LOGE);
+			mlmReassocCnf.resultCode =
+				eSIR_SME_RESOURCES_UNAVAILABLE;
+			mlmReassocCnf.protStatusCode = eSIR_SME_SUCCESS;
+			qdf_mem_free(beacon_struct);
+			goto error;
+		}
+		/*
+		 * While Processing the ReAssoc Response Frame the Rsp Frame
+		 * is being stored to be used here for sending ADDBSS
+		 */
+		assocRsp =
+			(tpSirAssocRsp) psessionEntry->limAssocResponseData;
+		lim_update_assoc_sta_datas(pMac, pStaDs, assocRsp,
+			psessionEntry);
+		lim_update_re_assoc_globals(pMac, assocRsp, psessionEntry);
+		bss_desc = &psessionEntry->pLimReAssocReq->bssDescription;
+		lim_extract_ap_capabilities(pMac,
+			(uint8_t *) bss_desc->ieFields,
+			lim_get_ielen_from_bss_description(bss_desc),
+			beacon_struct);
+		if (pMac->lim.gLimProtectionControl !=
+		    MLME_FORCE_POLICY_PROTECTION_DISABLE)
+			lim_decide_sta_protection_on_assoc(pMac,
+				beacon_struct,
+				psessionEntry);
+		if (beacon_struct->erpPresent) {
+			if (beacon_struct->erpIEInfo.barkerPreambleMode)
+				psessionEntry->beaconParams.fShortPreamble = 0;
+			else
+				psessionEntry->beaconParams.fShortPreamble = 1;
+		}
+		/*
+		 * updateBss flag is false, as in this case, PE is first
+		 * deleting the existing BSS and then adding a new one
+		 */
+		if (QDF_STATUS_SUCCESS !=
+		    lim_sta_send_add_bss(pMac, assocRsp, beacon_struct,
+				bss_desc,
+				false, psessionEntry)) {
+			pe_err("Posting ADDBSS in the ReAssocCtx Failed");
+			retStatus = QDF_STATUS_E_FAILURE;
+		}
+		if (retStatus != QDF_STATUS_SUCCESS) {
+			mlmReassocCnf.resultCode =
+				eSIR_SME_RESOURCES_UNAVAILABLE;
+			mlmReassocCnf.protStatusCode =
+				eSIR_MAC_UNSPEC_FAILURE_STATUS;
+			qdf_mem_free(assocRsp);
+			pMac->lim.gLimAssocResponseData = NULL;
+			qdf_mem_free(beacon_struct);
+			goto error;
+		}
+		qdf_mem_free(assocRsp);
+		qdf_mem_free(beacon_struct);
+		psessionEntry->limAssocResponseData = NULL;
+	}
+	break;
+	default:
+		pe_err("DelBss in wrong system Role and SME State");
+		mlmReassocCnf.resultCode = eSIR_SME_REFUSED;
+		mlmReassocCnf.protStatusCode =
+			eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+		goto error;
+	}
+	return;
+error:
+	lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+			     (uint32_t *) &mlmReassocCnf);
+}
+
+/**
+ * @lim_handle_add_bss_in_re_assoc_context() - ADD BSS during reassociation
+ * @pMac: Global MAC Context
+ * @pStaDs: Station Hash entry
+ * @psessionEntry: PE Session
+ *
+ * While Processing the ReAssociation Response Frame in STA,
+ *     a. immediately after receiving the Reassoc Response the RxCleanUp is
+ *         being issued and the end of DelBSS the new BSS is being added.
+ *
+ *     b. If an AP rejects the ReAssociation (Disassoc/Deauth) with some context
+ *        change, We need to update CSR with ReAssocCNF Response with the
+ *        ReAssoc Fail and the reason Code, that is also being handled in the
+ *        DELBSS context only
+ *
+ * Return: None
+ */
+void lim_handle_add_bss_in_re_assoc_context(tpAniSirGlobal pMac,
+		tpDphHashNode pStaDs, tpPESession psessionEntry)
+{
+	tLimMlmReassocCnf mlmReassocCnf;
+	/** Skipped the DeleteDPH Hash Entry as we need it for the new BSS*/
+	/** Set the MlmState to IDLE*/
+	psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+		       psessionEntry->limMlmState));
+	switch (psessionEntry->limSmeState) {
+	case eLIM_SME_WT_REASSOC_STATE: {
+		tpSirAssocRsp assocRsp;
+		tpDphHashNode pStaDs;
+		QDF_STATUS retStatus = QDF_STATUS_SUCCESS;
+		tSchBeaconStruct *pBeaconStruct;
+
+		pBeaconStruct =
+			qdf_mem_malloc(sizeof(tSchBeaconStruct));
+		if (!pBeaconStruct) {
+			mlmReassocCnf.resultCode =
+				eSIR_SME_RESOURCES_UNAVAILABLE;
+			mlmReassocCnf.protStatusCode =
+				eSIR_SME_RESOURCES_UNAVAILABLE;
+			goto Error;
+		}
+		/* Get the AP entry from DPH hash table */
+		pStaDs =
+			dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+					   &psessionEntry->dph.dphHashTable);
+		if (pStaDs == NULL) {
+			pe_err("Fail to get STA PEER entry from hash");
+			mlmReassocCnf.resultCode =
+				eSIR_SME_RESOURCES_UNAVAILABLE;
+			mlmReassocCnf.protStatusCode = eSIR_SME_SUCCESS;
+			qdf_mem_free(pBeaconStruct);
+			goto Error;
+		}
+		/*
+		 * While Processing the ReAssoc Response Frame the Rsp Frame
+		 * is being stored to be used here for sending ADDBSS
+		 */
+		assocRsp =
+			(tpSirAssocRsp) psessionEntry->limAssocResponseData;
+		lim_update_assoc_sta_datas(pMac, pStaDs, assocRsp,
+					   psessionEntry);
+		lim_update_re_assoc_globals(pMac, assocRsp, psessionEntry);
+		lim_extract_ap_capabilities(pMac,
+					    (uint8_t *) psessionEntry->
+					    pLimReAssocReq->bssDescription.
+					    ieFields,
+					    lim_get_ielen_from_bss_description
+						    (&psessionEntry->
+						    pLimReAssocReq->
+						    bssDescription),
+					    pBeaconStruct);
+		if (pMac->lim.gLimProtectionControl !=
+		    MLME_FORCE_POLICY_PROTECTION_DISABLE)
+			lim_decide_sta_protection_on_assoc(pMac,
+							   pBeaconStruct,
+							   psessionEntry);
+
+		if (pBeaconStruct->erpPresent) {
+			if (pBeaconStruct->erpIEInfo.barkerPreambleMode)
+				psessionEntry->beaconParams.
+				fShortPreamble = 0;
+			else
+				psessionEntry->beaconParams.
+				fShortPreamble = 1;
+		}
+
+		psessionEntry->isNonRoamReassoc = 1;
+		if (QDF_STATUS_SUCCESS !=
+		    lim_sta_send_add_bss(pMac, assocRsp, pBeaconStruct,
+					 &psessionEntry->pLimReAssocReq->
+					 bssDescription, true,
+					 psessionEntry)) {
+			pe_err("Post ADDBSS in the ReAssocCtxt Failed");
+			retStatus = QDF_STATUS_E_FAILURE;
+		}
+		if (retStatus != QDF_STATUS_SUCCESS) {
+			mlmReassocCnf.resultCode =
+				eSIR_SME_RESOURCES_UNAVAILABLE;
+			mlmReassocCnf.protStatusCode =
+				eSIR_MAC_UNSPEC_FAILURE_STATUS;
+			qdf_mem_free(assocRsp);
+			pMac->lim.gLimAssocResponseData = NULL;
+			qdf_mem_free(pBeaconStruct);
+			goto Error;
+		}
+		qdf_mem_free(assocRsp);
+		psessionEntry->limAssocResponseData = NULL;
+		qdf_mem_free(pBeaconStruct);
+	}
+	break;
+	default:
+		pe_err("DelBss in the wrong system Role and SME State");
+		mlmReassocCnf.resultCode = eSIR_SME_REFUSED;
+		mlmReassocCnf.protStatusCode =
+			eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+		goto Error;
+	}
+	return;
+Error:
+	lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+			     (uint32_t *) &mlmReassocCnf);
+}
+
+/**
+ * lim_is_reassoc_in_progress() - Check if reassoiciation is in progress
+ * @pMac: Global MAC Context
+ * @psessionEntry: PE Session
+ *
+ * Return: true  When STA is waiting for Reassoc response from AP
+ *         else false
+ */
+bool lim_is_reassoc_in_progress(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	if (psessionEntry == NULL)
+		return false;
+
+	if (LIM_IS_STA_ROLE(psessionEntry) &&
+	    (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE))
+		return true;
+
+	return false;
+}
+
+/**
+ * lim_add_ft_sta_self()- function to add STA once we have connected with a
+ *          new AP
+ * @mac_ctx: pointer to global mac structure
+ * @assoc_id: association id for the station connection
+ * @session_entry: pe session entr
+ *
+ * This function is called to add a STA once we have connected with a new
+ * AP, that we have performed an FT to.
+ *
+ * The Add STA Response is created and now after the ADD Bss Is Successful
+ * we add the self sta. We update with the association id from the reassoc
+ * response from the AP.
+ *
+ * Return: QDF_STATUS_SUCCESS on success else QDF_STATUS failure codes
+ */
+QDF_STATUS lim_add_ft_sta_self(tpAniSirGlobal mac_ctx, uint16_t assoc_id,
+				tpPESession session_entry)
+{
+	tpAddStaParams add_sta_params = NULL;
+	QDF_STATUS ret_code = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msg_q = {0};
+
+	add_sta_params = session_entry->ftPEContext.pAddStaReq;
+	add_sta_params->assocId = assoc_id;
+	add_sta_params->smesessionId = session_entry->smeSessionId;
+
+	msg_q.type = WMA_ADD_STA_REQ;
+	msg_q.reserved = 0;
+	msg_q.bodyptr = add_sta_params;
+	msg_q.bodyval = 0;
+
+	QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			"Sending WMA_ADD_STA_REQ (aid %d)",
+			 add_sta_params->assocId);
+	MTRACE(mac_trace_msg_tx(mac_ctx, session_entry->peSessionId,
+			 msg_q.type));
+
+	session_entry->limPrevMlmState = session_entry->limMlmState;
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+		session_entry->peSessionId, eLIM_MLM_WT_ADD_STA_RSP_STATE));
+	session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+	ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q);
+	if (QDF_STATUS_SUCCESS != ret_code) {
+		pe_err("Posting WMA_ADD_STA_REQ to HAL failed, reason=%X",
+			ret_code);
+		qdf_mem_free(add_sta_params);
+	}
+
+	session_entry->ftPEContext.pAddStaReq = NULL;
+	return ret_code;
+}
+
+/**
+ * lim_restore_pre_reassoc_state() - Restore the pre-association context
+ * @pMac: Global MAC Context
+ * @resultCode: Assoc response result
+ * @protStatusCode: Internal protocol status code
+ * @psessionEntry: PE Session
+ *
+ * This function is called on STA role whenever Reasociation
+ * Response with a reject code is received from AP.
+ * Reassociation failure timer is stopped, Old (or current) AP's
+ * context is restored both at Polaris & software
+ *
+ * Return: None
+ */
+
+void
+lim_restore_pre_reassoc_state(tpAniSirGlobal pMac,
+		tSirResultCodes resultCode, uint16_t protStatusCode,
+		tpPESession psessionEntry)
+{
+	tLimMlmReassocCnf mlmReassocCnf;
+
+	pe_debug("sessionid: %d protStatusCode: %d resultCode: %d",
+		psessionEntry->smeSessionId, protStatusCode, resultCode);
+
+	psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+		       eLIM_MLM_LINK_ESTABLISHED_STATE));
+
+	/* 'Change' timer for future activations */
+	lim_deactivate_and_change_timer(pMac, eLIM_REASSOC_FAIL_TIMER);
+
+	lim_set_channel(pMac, psessionEntry->currentOperChannel,
+			psessionEntry->ch_center_freq_seg0,
+			psessionEntry->ch_center_freq_seg1,
+			psessionEntry->ch_width,
+			psessionEntry->maxTxPower,
+			psessionEntry->peSessionId,
+			0, 0);
+
+	/* @ToDo:Need to Integrate the STOP the Dataxfer to AP from 11H code */
+
+	mlmReassocCnf.resultCode = resultCode;
+	mlmReassocCnf.protStatusCode = protStatusCode;
+	mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+	lim_post_sme_message(pMac,
+			     LIM_MLM_REASSOC_CNF, (uint32_t *) &mlmReassocCnf);
+}
+
+/**
+ * lim_post_reassoc_failure() - Post failure message to SME
+ * @pMac: Global MAC Context
+ * @resultCode: Result Code
+ * @protStatusCode: Protocol Status Code
+ * @psessionEntry: PE Session
+ *
+ * Return: None
+ */
+void lim_post_reassoc_failure(tpAniSirGlobal pMac,
+		tSirResultCodes resultCode, uint16_t protStatusCode,
+		tpPESession psessionEntry)
+{
+	tLimMlmReassocCnf mlmReassocCnf;
+
+	psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+		       eLIM_MLM_LINK_ESTABLISHED_STATE));
+
+	lim_deactivate_and_change_timer(pMac, eLIM_REASSOC_FAIL_TIMER);
+
+	mlmReassocCnf.resultCode = resultCode;
+	mlmReassocCnf.protStatusCode = protStatusCode;
+	mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+	lim_post_sme_message(pMac,
+			     LIM_MLM_REASSOC_CNF, (uint32_t *) &mlmReassocCnf);
+}
+
diff --git a/core/mac/src/pe/lim/lim_roam_timer_utils.c b/core/mac/src/pe/lim/lim_roam_timer_utils.c
new file mode 100644
index 0000000..73ad9ef
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_roam_timer_utils.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016-2018 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: lim_roam_timer_utils.c
+ *
+ * Host based roaming timers implementation
+ */
+
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+
+/**
+ * lim_create_timers_host_roam() - Create timers used in host based roaming
+ * @mac_ctx: Global MAC context
+ *
+ * Create reassoc and preauth timers
+ *
+ * Return: TX_SUCCESS or TX_TIMER_ERROR
+ */
+uint32_t lim_create_timers_host_roam(tpAniSirGlobal mac_ctx)
+{
+	uint32_t cfg_value;
+
+	cfg_value = SYS_MS_TO_TICKS(
+			mac_ctx->mlme_cfg->timeouts.reassoc_failure_timeout);
+	/* Create Association failure timer and activate it later */
+	if (tx_timer_create(mac_ctx,
+			&mac_ctx->lim.limTimers.gLimReassocFailureTimer,
+		    "REASSOC FAILURE TIMEOUT", lim_assoc_failure_timer_handler,
+		    LIM_REASSOC, cfg_value, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("failed to create Reassoc timer");
+		return TX_TIMER_ERROR;
+	}
+	cfg_value = 1000;
+	cfg_value = SYS_MS_TO_TICKS(cfg_value);
+	if (tx_timer_create(mac_ctx,
+			&mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer,
+			"FT PREAUTH RSP TIMEOUT",
+			lim_timer_handler, SIR_LIM_FT_PREAUTH_RSP_TIMEOUT,
+			cfg_value, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("failed to create Join fail timer");
+		goto err_roam_timer;
+	}
+	return TX_SUCCESS;
+
+err_roam_timer:
+	tx_timer_delete(&mac_ctx->lim.limTimers.gLimReassocFailureTimer);
+	return TX_TIMER_ERROR;
+}
+
+void lim_delete_timers_host_roam(tpAniSirGlobal mac_ctx)
+{
+	tLimTimers *lim_timer = &mac_ctx->lim.limTimers;
+
+	/* Delete Reassociation failure timer. */
+	tx_timer_delete(&lim_timer->gLimReassocFailureTimer);
+	/* Delete FT Preauth response timer */
+	tx_timer_delete(&lim_timer->gLimFTPreAuthRspTimer);
+}
+
+void lim_deactivate_timers_host_roam(tpAniSirGlobal mac_ctx)
+{
+	tLimTimers *lim_timer = &mac_ctx->lim.limTimers;
+
+	/* Deactivate Reassociation failure timer. */
+	tx_timer_deactivate(&lim_timer->gLimReassocFailureTimer);
+	/* Deactivate FT Preauth response timer */
+	tx_timer_deactivate(&lim_timer->gLimFTPreAuthRspTimer);
+}
+
+/**
+ * lim_deactivate_and_change_timer_host_roam() - Change timers in host roaming
+ * @mac_ctx: Pointer to Global MAC structure
+ * @timer_id: enum of timer to be deactivated and changed
+ *
+ * This function is called to deactivate and change a timer for future
+ * re-activation for host roaming timers.
+ *
+ * Return: None
+ */
+void lim_deactivate_and_change_timer_host_roam(tpAniSirGlobal mac_ctx,
+		uint32_t timer_id)
+{
+	uint32_t val = 0;
+
+	switch (timer_id) {
+	case eLIM_REASSOC_FAIL_TIMER:
+		if (tx_timer_deactivate
+			(&mac_ctx->lim.limTimers.gLimReassocFailureTimer) !=
+				TX_SUCCESS)
+			pe_warn("unable to deactivate Reassoc fail timer");
+
+		val = SYS_MS_TO_TICKS(
+			mac_ctx->mlme_cfg->timeouts.reassoc_failure_timeout);
+		if (tx_timer_change
+			(&mac_ctx->lim.limTimers.gLimReassocFailureTimer, val,
+			 0) != TX_SUCCESS)
+			pe_warn("unable to change Reassoc fail timer");
+		break;
+
+	case eLIM_FT_PREAUTH_RSP_TIMER:
+		if (tx_timer_deactivate
+			(&mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer) !=
+			TX_SUCCESS) {
+			pe_err("Unable to deactivate Preauth Fail timer");
+			return;
+		}
+		val = 1000;
+		val = SYS_MS_TO_TICKS(val);
+		if (tx_timer_change(
+				&mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer,
+				val, 0) != TX_SUCCESS) {
+			pe_err("Unable to change Join Failure timer");
+			return;
+		}
+		break;
+	}
+}
+
diff --git a/core/mac/src/pe/lim/lim_scan_result_utils.c b/core/mac/src/pe/lim/lim_scan_result_utils.c
new file mode 100644
index 0000000..f2cc1a1
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_scan_result_utils.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * This file lim_scan_result_utils.cc contains the utility functions
+ * LIM uses for maintaining and accessing scan results on STA.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_api.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "rrm_api.h"
+#include "cds_utils.h"
+
+/**
+ * lim_collect_bss_description()
+ *
+ ***FUNCTION:
+ * This function is called during scan upon receiving
+ * Beacon/Probe Response frame to check if the received
+ * frame matches scan criteria, collect BSS description
+ * and add it to cached scan results.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  pBPR - Pointer to parsed Beacon/Probe Response structure
+ * @param  pRxPacketInfo  - Pointer to Received frame's BD
+ * @param  fScanning - flag to indicate if it is during scan.
+ * ---------------------------------------------
+ *
+ * @return None
+ */
+void
+lim_collect_bss_description(tpAniSirGlobal pMac,
+			    tSirBssDescription *pBssDescr,
+			    tpSirProbeRespBeacon pBPR,
+			    uint8_t *pRxPacketInfo, uint8_t fScanning)
+{
+	uint8_t *pBody;
+	uint32_t ieLen = 0;
+	tpSirMacMgmtHdr pHdr;
+	uint8_t channelNum;
+	uint8_t rxChannel;
+	uint8_t rfBand = 0;
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+	if (SIR_MAC_B_PR_SSID_OFFSET > WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo)) {
+		QDF_ASSERT(WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) >=
+			   SIR_MAC_B_PR_SSID_OFFSET);
+		return;
+	}
+	ieLen =
+		WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET;
+	rxChannel = WMA_GET_RX_CH(pRxPacketInfo);
+	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+	rfBand = WMA_GET_RX_RFBAND(pRxPacketInfo);
+
+	/**
+	 * Length of BSS desription is without length of
+	 * length itself and length of pointer that holds ieFields.
+	 *
+	 * tSirBssDescription
+	 * +--------+---------------------------------+---------------+
+	 * | length | other fields                    | pointer to IEs|
+	 * +--------+---------------------------------+---------------+
+	 *                                            ^
+	 *                                            ieFields
+	 */
+	pBssDescr->length = (uint16_t)(offsetof(tSirBssDescription, ieFields[0])
+					- sizeof(pBssDescr->length) + ieLen);
+
+	/* Copy BSS Id */
+	qdf_mem_copy((uint8_t *) &pBssDescr->bssId,
+		     (uint8_t *) pHdr->bssId, sizeof(tSirMacAddr));
+
+	/* Copy Timestamp, Beacon Interval and Capability Info */
+	pBssDescr->scansystimensec = qdf_get_bootbased_boottime_ns();
+
+	pBssDescr->timeStamp[0] = pBPR->timeStamp[0];
+	pBssDescr->timeStamp[1] = pBPR->timeStamp[1];
+	pBssDescr->beaconInterval = pBPR->beaconInterval;
+	pBssDescr->capabilityInfo =
+		lim_get_u16((uint8_t *) &pBPR->capabilityInfo);
+
+	if (!pBssDescr->beaconInterval) {
+		pe_warn("Beacon Interval is ZERO, making it to default 100 "
+			   MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHdr->bssId));
+		pBssDescr->beaconInterval = 100;
+	}
+	/*
+	 * There is a narrow window after Channel Switch msg is sent to HAL and before the AGC is shut
+	 * down and beacons/Probe Rsps can trickle in and we may report the incorrect channel in 5Ghz
+	 * band, so not relying on the 'last Scanned Channel' stored in LIM.
+	 * Instead use the value returned by RXP in BD. This the the same value which HAL programs into
+	 * RXP before every channel switch.
+	 * Right now there is a problem in 5Ghz, where we are receiving beacons from a channel different from
+	 * the currently scanned channel. so incorrect channel is reported to CSR and association does not happen.
+	 * So for now we keep on looking for the channel info in the beacon (DSParamSet IE OR HT Info IE), and only if it
+	 * is not present in the beacon, we go for the channel info present in RXP.
+	 * This fix will work for 5Ghz 11n devices, but for 11a devices, we have to rely on RXP routing flag to get the correct channel.
+	 * So The problem of incorrect channel reporting in 5Ghz will still remain for 11a devices.
+	 */
+	pBssDescr->channelId = lim_get_channel_from_beacon(pMac, pBPR);
+
+	pBssDescr->channelIdSelf = pBssDescr->channelId;
+	pBssDescr->rx_channel = rxChannel;
+
+	/* set the network type in bss description */
+	channelNum = pBssDescr->channelId;
+	pBssDescr->nwType =
+		lim_get_nw_type(pMac, channelNum, SIR_MAC_MGMT_FRAME, pBPR);
+
+	/* Copy RSSI & SINR from BD */
+	pBssDescr->rssi = (int8_t) WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo);
+	pBssDescr->rssi_raw = (int8_t) WMA_GET_RX_RSSI_RAW(pRxPacketInfo);
+
+	/* SINR no longer reported by HW */
+	pBssDescr->sinr = 0;
+	pe_debug(MAC_ADDRESS_STR " rssi: normalized: %d, absolute: %d",
+		MAC_ADDR_ARRAY(pHdr->bssId), pBssDescr->rssi,
+		pBssDescr->rssi_raw);
+
+	pBssDescr->received_time = (uint64_t)qdf_mc_timer_get_system_time();
+	pBssDescr->tsf_delta = WMA_GET_RX_TSF_DELTA(pRxPacketInfo);
+	pBssDescr->seq_ctrl = pHdr->seqControl;
+
+	pe_debug("Received %s from BSSID: %pM tsf_delta = %u Seq Num: %x ssid:%.*s, rssi: %d",
+		 pBssDescr->fProbeRsp ? "Probe Rsp" : "Beacon", pHdr->bssId,
+		 pBssDescr->tsf_delta, ((pHdr->seqControl.seqNumHi <<
+		 HIGH_SEQ_NUM_OFFSET) | pHdr->seqControl.seqNumLo),
+		 pBPR->ssId.length, pBPR->ssId.ssId, pBssDescr->rssi_raw);
+
+	if (fScanning) {
+		rrm_get_start_tsf(pMac, pBssDescr->startTSF);
+		pBssDescr->parentTSF = WMA_GET_RX_TIMESTAMP(pRxPacketInfo);
+	}
+
+	/* MobilityDomain */
+	pBssDescr->mdie[0] = 0;
+	pBssDescr->mdie[1] = 0;
+	pBssDescr->mdie[2] = 0;
+	pBssDescr->mdiePresent = false;
+	/* If mdie is present in the probe resp we */
+	/* fill it in the bss description */
+	if (pBPR->mdiePresent) {
+		pBssDescr->mdiePresent = true;
+		pBssDescr->mdie[0] = pBPR->mdie[0];
+		pBssDescr->mdie[1] = pBPR->mdie[1];
+		pBssDescr->mdie[2] = pBPR->mdie[2];
+	}
+
+#ifdef FEATURE_WLAN_ESE
+	pBssDescr->QBSSLoad_present = false;
+	pBssDescr->QBSSLoad_avail = 0;
+	if (pBPR->QBSSLoad.present) {
+		pBssDescr->QBSSLoad_present = true;
+		pBssDescr->QBSSLoad_avail = pBPR->QBSSLoad.avail;
+	}
+#endif
+	/* Copy IE fields */
+	qdf_mem_copy((uint8_t *) &pBssDescr->ieFields,
+		     pBody + SIR_MAC_B_PR_SSID_OFFSET, ieLen);
+
+	/*set channel number in beacon in case it is not present */
+	pBPR->channelNumber = pBssDescr->channelId;
+	pMac->lim.beacon_probe_rsp_cnt_per_scan++;
+
+	return;
+} /*** end lim_collect_bss_description() ***/
diff --git a/core/mac/src/pe/lim/lim_scan_result_utils.h b/core/mac/src/pe/lim/lim_scan_result_utils.h
new file mode 100644
index 0000000..cdaad9d
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_scan_result_utils.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2014-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.
+ */
+
+/*
+ * This file lim_scan_result_utils.h contains the utility definitions
+ * LIM uses for maintaining and accessing scan results on STA.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SCAN_UTILS_H
+#define __LIM_SCAN_UTILS_H
+
+#include "parser_api.h"
+#include "lim_types.h"
+
+/* Scan result hash related functions */
+uint8_t lim_scan_hash_function(tSirMacAddr);
+void lim_restore_pre_scan_state(tpAniSirGlobal);
+void lim_copy_scan_result(tpAniSirGlobal, uint8_t *);
+void lim_collect_bss_description(tpAniSirGlobal pMac,
+			    tSirBssDescription *pBssDescr,
+			    tpSirProbeRespBeacon pBPR,
+			    uint8_t *pRxPacketInfo, uint8_t fScanning);
+#endif /* __LIM_SCAN_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_security_utils.c b/core/mac/src/pe/lim/lim_security_utils.c
new file mode 100644
index 0000000..158c1dd
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_security_utils.c
@@ -0,0 +1,1008 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/*
+ *
+ * This file lim_utils.cc contains the utility functions
+ * LIM uses.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "ani_global.h"
+#include "wni_api.h"
+
+#include "sir_common.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+
+#define LIM_SEED_LENGTH 16
+/*
+ * preauth node timeout value in interval of 10msec
+ */
+#define LIM_OPENAUTH_TIMEOUT 500
+
+/**
+ * lim_is_auth_algo_supported()
+ *
+ ***FUNCTION:
+ * This function is called in various places within LIM code
+ * to determine whether passed authentication algorithm is enabled
+ * or not
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param authType Indicates MAC based authentication type
+ *                 (eSIR_OPEN_SYSTEM or eSIR_SHARED_KEY)
+ *                 If Shared Key authentication to be used,
+ *                 'Privacy Option Implemented' flag is also
+ *                 checked.
+ *
+ * @return true if passed authType is enabled else false
+ */
+uint8_t
+lim_is_auth_algo_supported(tpAniSirGlobal pMac, tAniAuthType authType,
+			   tpPESession psessionEntry)
+{
+	bool algoEnable, privacyOptImp;
+	struct wlan_mlme_wep_cfg *wep_params = &pMac->mlme_cfg->wep_params;
+
+	if (authType == eSIR_OPEN_SYSTEM) {
+
+		if (LIM_IS_AP_ROLE(psessionEntry)) {
+			if ((psessionEntry->authType == eSIR_OPEN_SYSTEM)
+			    || (psessionEntry->authType == eSIR_AUTO_SWITCH))
+				return true;
+			else
+				return false;
+		}
+
+		algoEnable = wep_params->is_auth_open_system;
+		return algoEnable > 0 ? true : false;
+
+	} else {
+
+		if (LIM_IS_AP_ROLE(psessionEntry)) {
+			if ((psessionEntry->authType == eSIR_SHARED_KEY)
+			    || (psessionEntry->authType == eSIR_AUTO_SWITCH))
+				algoEnable = true;
+			else
+				algoEnable = false;
+
+		} else {
+			algoEnable = wep_params->is_shared_key_auth;
+		}
+
+		if (LIM_IS_AP_ROLE(psessionEntry))
+			privacyOptImp = psessionEntry->privacy;
+		else
+			privacyOptImp = wep_params->is_privacy_enabled;
+
+		return algoEnable && privacyOptImp;
+	}
+} /****** end lim_is_auth_algo_supported() ******/
+
+/**
+ * lim_init_pre_auth_list
+ *
+ ***FUNCTION:
+ * This function is called while starting a BSS at AP
+ * to initialize MAC authenticated STA list. This may also be called
+ * while joining/starting an IBSS if MAC authentication is allowed
+ * in IBSS mode.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_init_pre_auth_list(tpAniSirGlobal pMac)
+{
+	pMac->lim.pLimPreAuthList = NULL;
+
+} /*** end lim_init_pre_auth_list() ***/
+
+/**
+ * lim_delete_pre_auth_list
+ *
+ ***FUNCTION:
+ * This function is called cleanup Pre-auth list either on
+ * AP or on STA when moving from one persona to other.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_delete_pre_auth_list(tpAniSirGlobal pMac)
+{
+	struct tLimPreAuthNode *pCurrNode, *pTempNode;
+
+	pCurrNode = pTempNode = pMac->lim.pLimPreAuthList;
+	while (pCurrNode != NULL) {
+		pTempNode = pCurrNode->next;
+		lim_release_pre_auth_node(pMac, pCurrNode);
+
+		pCurrNode = pTempNode;
+	}
+	pMac->lim.pLimPreAuthList = NULL;
+} /*** end lim_delete_pre_auth_list() ***/
+
+/**
+ * lim_search_pre_auth_list
+ *
+ ***FUNCTION:
+ * This function is called when Authentication frame is received
+ * by AP (or at a STA in IBSS supporting MAC based authentication)
+ * to search if a STA is in the middle of MAC Authentication
+ * transaction sequence.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  macAddr - MAC address of the STA that sent
+ *                       Authentication frame.
+ *
+ * @return Pointer to pre-auth node if found, else NULL
+ */
+
+struct tLimPreAuthNode *lim_search_pre_auth_list(tpAniSirGlobal pMac,
+						 tSirMacAddr macAddr)
+{
+	struct tLimPreAuthNode *pTempNode = pMac->lim.pLimPreAuthList;
+
+	while (pTempNode != NULL) {
+		if (!qdf_mem_cmp((uint8_t *) macAddr,
+				    (uint8_t *) &pTempNode->peerMacAddr,
+				    sizeof(tSirMacAddr)))
+			break;
+
+		pTempNode = pTempNode->next;
+	}
+
+	return pTempNode;
+} /*** end lim_search_pre_auth_list() ***/
+
+/**
+ * lim_delete_open_auth_pre_auth_node() - delete any stale preauth nodes
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * This function is called to delete any stale preauth nodes on
+ * receiving authentication frame and existing preauth nodes
+ * reached the maximum allowed limit.
+ *
+ * Return: return true if any preauthnode deleted else false
+ */
+uint8_t
+lim_delete_open_auth_pre_auth_node(tpAniSirGlobal mac_ctx)
+{
+	struct tLimPreAuthNode    *prev_node, *temp_node, *found_node;
+	uint8_t auth_node_freed = false;
+
+	temp_node = prev_node = mac_ctx->lim.pLimPreAuthList;
+
+	if (temp_node == NULL)
+		return auth_node_freed;
+
+	while (temp_node != NULL) {
+		if (temp_node->mlmState == eLIM_MLM_AUTHENTICATED_STATE &&
+		    temp_node->authType == eSIR_OPEN_SYSTEM &&
+		    (qdf_mc_timer_get_system_ticks() >
+		    (LIM_OPENAUTH_TIMEOUT + temp_node->timestamp) ||
+		    qdf_mc_timer_get_system_ticks() < temp_node->timestamp)) {
+			/* Found node to be deleted */
+			auth_node_freed = true;
+			found_node = temp_node;
+			if (mac_ctx->lim.pLimPreAuthList == temp_node) {
+				prev_node = mac_ctx->lim.pLimPreAuthList =
+					temp_node = found_node->next;
+			} else {
+				prev_node->next = temp_node->next;
+				temp_node = prev_node->next;
+			}
+
+			lim_release_pre_auth_node(mac_ctx, found_node);
+		} else {
+			prev_node = temp_node;
+			temp_node = prev_node->next;
+		}
+	}
+
+	return auth_node_freed;
+}
+
+/**
+ * lim_add_pre_auth_node
+ *
+ ***FUNCTION:
+ * This function is called at AP while sending Authentication
+ * frame2.
+ * This may also be called on a STA in IBSS if MAC authentication is
+ * allowed in IBSS mode.
+ *
+ ***LOGIC:
+ * Node is always added to the front of the list
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  pAuthNode - Pointer to pre-auth node to be added to the list.
+ *
+ * @return None
+ */
+
+void lim_add_pre_auth_node(tpAniSirGlobal pMac, struct tLimPreAuthNode *pAuthNode)
+{
+	pMac->lim.gLimNumPreAuthContexts++;
+
+	pAuthNode->next = pMac->lim.pLimPreAuthList;
+
+	pMac->lim.pLimPreAuthList = pAuthNode;
+} /*** end lim_add_pre_auth_node() ***/
+
+/**
+ * lim_release_pre_auth_node
+ *
+ ***FUNCTION:
+ * This function is called to realease the acquired
+ * pre auth node from list.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  pAuthNode - Pointer to Pre Auth node to be released
+ * @return None
+ */
+
+void lim_release_pre_auth_node(tpAniSirGlobal pMac, tpLimPreAuthNode pAuthNode)
+{
+	pAuthNode->fFree = 1;
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION,
+		       eLIM_PRE_AUTH_CLEANUP_TIMER));
+	tx_timer_deactivate(&pAuthNode->timer);
+	pMac->lim.gLimNumPreAuthContexts--;
+} /*** end lim_release_pre_auth_node() ***/
+
+/**
+ * lim_delete_pre_auth_node
+ *
+ ***FUNCTION:
+ * This function is called at AP when a pre-authenticated STA is
+ * Associated/Reassociated or when AuthFrame4 is received after
+ * Auth Response timeout.
+ * This may also be called on a STA in IBSS if MAC authentication and
+ * Association/Reassociation is allowed in IBSS mode.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  peerMacAddr - MAC address of the STA that need to be deleted
+ *                       from pre-auth node list.
+ *
+ * @return None
+ */
+
+void lim_delete_pre_auth_node(tpAniSirGlobal pMac, tSirMacAddr macAddr)
+{
+	struct tLimPreAuthNode *pPrevNode, *pTempNode;
+
+	pTempNode = pPrevNode = pMac->lim.pLimPreAuthList;
+
+	if (pTempNode == NULL)
+		return;
+
+	if (!qdf_mem_cmp((uint8_t *) macAddr,
+			    (uint8_t *) &pTempNode->peerMacAddr,
+			    sizeof(tSirMacAddr))) {
+		/* First node to be deleted */
+
+		pMac->lim.pLimPreAuthList = pTempNode->next;
+
+		pe_debug("first node to delete, Release data entry: %pK id %d peer",
+			       pTempNode, pTempNode->authNodeIdx);
+		lim_print_mac_addr(pMac, macAddr, LOGD);
+		lim_release_pre_auth_node(pMac, pTempNode);
+
+		return;
+	}
+
+	pTempNode = pTempNode->next;
+
+	while (pTempNode != NULL) {
+		if (!qdf_mem_cmp((uint8_t *) macAddr,
+				    (uint8_t *) &pTempNode->peerMacAddr,
+				    sizeof(tSirMacAddr))) {
+			/* Found node to be deleted */
+
+			pPrevNode->next = pTempNode->next;
+
+			pe_debug("subsequent node to delete, Release data entry: %pK id %d peer",
+				       pTempNode, pTempNode->authNodeIdx);
+			       lim_print_mac_addr(pMac, macAddr, LOG1);
+			lim_release_pre_auth_node(pMac, pTempNode);
+
+			return;
+		}
+
+		pPrevNode = pTempNode;
+		pTempNode = pTempNode->next;
+	}
+
+	pe_err("peer not found in pre-auth list, addr= ");
+	lim_print_mac_addr(pMac, macAddr, LOGE);
+
+} /*** end lim_delete_pre_auth_node() ***/
+
+/**
+ * limRestoreFromPreAuthState
+ *
+ ***FUNCTION:
+ * This function is called on STA whenever an Authentication
+ * sequence is complete and state prior to auth need to be
+ * restored.
+ *
+ ***LOGIC:
+ * MLM_AUTH_CNF is prepared and sent to SME state machine.
+ * In case of restoring from pre-auth:
+ *     - Channel Id is programmed at LO/RF synthesizer
+ *     - BSSID is programmed at RHP
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac       - Pointer to Global MAC structure
+ * @param  resultCode - result of authentication attempt
+ * @return None
+ */
+
+void
+lim_restore_from_auth_state(tpAniSirGlobal pMac, tSirResultCodes resultCode,
+			    uint16_t protStatusCode, tpPESession sessionEntry)
+{
+	tSirMacAddr currentBssId;
+	tLimMlmAuthCnf mlmAuthCnf;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_AUTH_COMP_EVENT, sessionEntry,
+			      resultCode, protStatusCode);
+#endif
+
+	qdf_mem_copy((uint8_t *) &mlmAuthCnf.peerMacAddr,
+		     (uint8_t *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+		     sizeof(tSirMacAddr));
+	mlmAuthCnf.authType = pMac->lim.gpLimMlmAuthReq->authType;
+	mlmAuthCnf.resultCode = resultCode;
+	mlmAuthCnf.protStatusCode = protStatusCode;
+
+	/* Update PE session ID */
+	mlmAuthCnf.sessionId = sessionEntry->peSessionId;
+
+	/* / Free up buffer allocated */
+	/* / for pMac->lim.gLimMlmAuthReq */
+	qdf_mem_free(pMac->lim.gpLimMlmAuthReq);
+	pMac->lim.gpLimMlmAuthReq = NULL;
+
+	sessionEntry->limMlmState = sessionEntry->limPrevMlmState;
+
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, sessionEntry->peSessionId,
+		       sessionEntry->limMlmState));
+
+	/*
+	 * Set the auth_ack_status status flag as success as
+	 * host have received the auth rsp and no longer auth
+	 * retry is needed also cancel the auth rety timer
+	 */
+	pMac->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS;
+
+	/* Auth retry and AUth failure timers are not started for SAE */
+	/* 'Change' timer for future activations */
+	if (tx_timer_running(&pMac->lim.limTimers.
+	    g_lim_periodic_auth_retry_timer))
+		lim_deactivate_and_change_timer(pMac,
+				eLIM_AUTH_RETRY_TIMER);
+	/* 'Change' timer for future activations */
+	if (tx_timer_running(&pMac->lim.limTimers.gLimAuthFailureTimer))
+		lim_deactivate_and_change_timer(pMac,
+				eLIM_AUTH_FAIL_TIMER);
+
+	sir_copy_mac_addr(currentBssId, sessionEntry->bssId);
+
+	if (sessionEntry->limSmeState == eLIM_SME_WT_PRE_AUTH_STATE) {
+		pMac->lim.gLimPreAuthChannelNumber = 0;
+	}
+
+	lim_post_sme_message(pMac, LIM_MLM_AUTH_CNF, (uint32_t *) &mlmAuthCnf);
+} /*** end lim_restore_from_auth_state() ***/
+
+/**
+ * lim_encrypt_auth_frame()
+ *
+ ***FUNCTION:
+ * This function is called in lim_process_auth_frame() function
+ * to encrypt Authentication frame3 body.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac           Pointer to Global MAC structure
+ * @param  keyId          key id to used
+ * @param  pKey           Pointer to the key to be used for encryption
+ * @param  pPlainText     Pointer to the body to be encrypted
+ * @param  pEncrBody      Pointer to the encrypted auth frame body
+ * @param  keyLength      8 (WEP40) or 16 (WEP104)
+ * @return None
+ */
+
+void
+lim_encrypt_auth_frame(tpAniSirGlobal pMac, uint8_t keyId, uint8_t *pKey,
+		       uint8_t *pPlainText, uint8_t *pEncrBody,
+		       uint32_t keyLength)
+{
+	uint8_t seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH];
+	uint16_t frame_len;
+
+	frame_len = ((tpSirMacAuthFrameBody)pPlainText)->length +
+			SIR_MAC_AUTH_FRAME_INFO_LEN + SIR_MAC_CHALLENGE_ID_LEN;
+	keyLength += 3;
+
+	/* Bytes 3-7 of seed is key */
+	qdf_mem_copy((uint8_t *) &seed[3], pKey, keyLength - 3);
+
+	/* Compute CRC-32 and place them in last 4 bytes of plain text */
+	lim_compute_crc32(icv, pPlainText, frame_len);
+
+	qdf_mem_copy(pPlainText + frame_len,
+		     icv, SIR_MAC_WEP_ICV_LENGTH);
+
+	/* Run RC4 on plain text with the seed */
+	lim_rc4(pEncrBody + SIR_MAC_WEP_IV_LENGTH,
+		(uint8_t *) pPlainText, seed, keyLength,
+		frame_len + SIR_MAC_WEP_ICV_LENGTH);
+
+	/* Prepare IV */
+	pEncrBody[0] = seed[0];
+	pEncrBody[1] = seed[1];
+	pEncrBody[2] = seed[2];
+	pEncrBody[3] = keyId << 6;
+} /****** end lim_encrypt_auth_frame() ******/
+
+/**
+ * lim_compute_crc32()
+ *
+ ***FUNCTION:
+ * This function is called to compute CRC-32 on a given source.
+ * Used while encrypting/decrypting Authentication frame 3.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pDest    Destination location for computed CRC
+ * @param  pSrc     Source location to be CRC computed
+ * @param  len      Length over which CRC to be computed
+ * @return None
+ */
+
+void lim_compute_crc32(uint8_t *pDest, uint8_t *pSrc, uint16_t len)
+{
+	uint32_t crc;
+	int i;
+
+	crc = 0;
+	crc = ~crc;
+
+	while (len-- > 0)
+		crc = lim_crc_update(crc, *pSrc++);
+
+	crc = ~crc;
+
+	for (i = 0; i < SIR_MAC_WEP_IV_LENGTH; i++) {
+		pDest[i] = (uint8_t) crc;
+		crc >>= 8;
+	}
+} /****** end lim_compute_crc32() ******/
+
+/**
+ * lim_rc4()
+ *
+ ***FUNCTION:
+ * This function is called to run RC4 algorithm. Called while
+ * encrypting/decrypting Authentication frame 3.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pDest          Destination location for encrypted text
+ * @param  pSrc           Source location to be encrypted
+ * @param  seed           Contains seed (IV + key) for PRNG
+ * @param  keyLength      8 (WEP40) or 16 (WEP104)
+ * @param  frameLen       Length of the frame
+ *
+ * @return None
+ */
+
+void
+lim_rc4(uint8_t *pDest, uint8_t *pSrc, uint8_t *seed, uint32_t keyLength,
+	uint16_t frameLen)
+{
+	typedef struct {
+		uint8_t i, j;
+		uint8_t sbox[256];
+	} tRC4Context;
+
+	tRC4Context ctx;
+
+	{
+		uint16_t i, j, k;
+
+		/* */
+		/* Initialize sbox using seed */
+		/* */
+
+		ctx.i = ctx.j = 0;
+		for (i = 0; i < 256; i++)
+			ctx.sbox[i] = (uint8_t) i;
+
+		j = 0;
+		k = 0;
+		for (i = 0; i < 256; i++) {
+			uint8_t temp;
+
+			if (k < LIM_SEED_LENGTH)
+				j = (uint8_t) (j + ctx.sbox[i] + seed[k]);
+			temp = ctx.sbox[i];
+			ctx.sbox[i] = ctx.sbox[j];
+			ctx.sbox[j] = temp;
+
+			if (++k >= keyLength)
+				k = 0;
+		}
+	}
+
+	{
+		uint8_t i = ctx.i;
+		uint8_t j = ctx.j;
+		uint16_t len = frameLen;
+
+		while (len-- > 0) {
+			uint8_t temp1, temp2;
+
+			i = (uint8_t) (i + 1);
+			temp1 = ctx.sbox[i];
+			j = (uint8_t) (j + temp1);
+
+			ctx.sbox[i] = temp2 = ctx.sbox[j];
+			ctx.sbox[j] = temp1;
+
+			temp1 = (uint8_t) (temp1 + temp2);
+			temp1 = ctx.sbox[temp1];
+			temp2 = (uint8_t) (pSrc ? *pSrc++ : 0);
+
+			*pDest++ = (uint8_t) (temp1 ^ temp2);
+		}
+
+		ctx.i = i;
+		ctx.j = j;
+	}
+} /****** end lim_rc4() ******/
+
+/**
+ * lim_decrypt_auth_frame()
+ *
+ ***FUNCTION:
+ * This function is called in lim_process_auth_frame() function
+ * to decrypt received Authentication frame3 body.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac       Pointer to Global MAC structure
+ * @param pKey       Pointer to the key to be used for decryption
+ * @param pEncrBody  Pointer to the body to be decrypted
+ * @param pPlainBody Pointer to the decrypted body
+ * @param keyLength  8 (WEP40) or 16 (WEP104)
+ *
+ * @return Decrypt result - QDF_STATUS_SUCCESS for success and
+ *                          LIM_DECRYPT_ICV_FAIL for ICV mismatch.
+ *                          If decryption is a success, pBody will
+ *                          have decrypted auth frame body.
+ */
+
+uint8_t
+lim_decrypt_auth_frame(tpAniSirGlobal pMac, uint8_t *pKey, uint8_t *pEncrBody,
+		       uint8_t *pPlainBody, uint32_t keyLength, uint16_t frameLen)
+{
+	uint8_t seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH];
+	int i;
+
+	keyLength += 3;
+
+	/* Bytes 0-2 of seed is received IV */
+	qdf_mem_copy((uint8_t *) seed, pEncrBody, SIR_MAC_WEP_IV_LENGTH - 1);
+
+	/* Bytes 3-7 of seed is key */
+	qdf_mem_copy((uint8_t *) &seed[3], pKey, keyLength - 3);
+
+	/* Run RC4 on encrypted text with the seed */
+	lim_rc4(pPlainBody,
+		pEncrBody + SIR_MAC_WEP_IV_LENGTH, seed, keyLength, frameLen);
+
+	/* Compute CRC-32 and place them in last 4 bytes of encrypted body */
+	lim_compute_crc32(icv,
+			  (uint8_t *) pPlainBody,
+			  (frameLen - SIR_MAC_WEP_ICV_LENGTH));
+
+	/* Compare RX_ICV with computed ICV */
+	for (i = 0; i < SIR_MAC_WEP_ICV_LENGTH; i++) {
+		pe_debug("computed ICV%d[%x], rxed ICV%d[%x]",
+			i, icv[i], i,
+			pPlainBody[frameLen - SIR_MAC_WEP_ICV_LENGTH + i]);
+
+		if (icv[i] !=
+		    pPlainBody[frameLen - SIR_MAC_WEP_ICV_LENGTH + i])
+			return LIM_DECRYPT_ICV_FAIL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+} /****** end lim_decrypt_auth_frame() ******/
+
+/**
+ * lim_post_sme_set_keys_cnf
+ *
+ * A utility API to send MLM_SETKEYS_CNF to SME
+ */
+void lim_post_sme_set_keys_cnf(tpAniSirGlobal pMac,
+			       tLimMlmSetKeysReq *pMlmSetKeysReq,
+			       tLimMlmSetKeysCnf *mlmSetKeysCnf)
+{
+	/* Prepare and Send LIM_MLM_SETKEYS_CNF */
+	qdf_copy_macaddr(&mlmSetKeysCnf->peer_macaddr,
+			 &pMlmSetKeysReq->peer_macaddr);
+
+	/* Free up buffer allocated for mlmSetKeysReq */
+	qdf_mem_free(pMlmSetKeysReq);
+	pMac->lim.gpLimMlmSetKeysReq = NULL;
+
+	lim_post_sme_message(pMac,
+			     LIM_MLM_SETKEYS_CNF, (uint32_t *) mlmSetKeysCnf);
+}
+
+/**
+ * lim_send_set_bss_key_req()
+ *
+ ***FUNCTION:
+ * This function is called from lim_process_mlm_set_keys_req(),
+ * when PE is trying to setup the Group Keys related
+ * to a specified encryption type
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac           Pointer to Global MAC structure
+ * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer
+ * @return none
+ */
+void lim_send_set_bss_key_req(tpAniSirGlobal pMac,
+			      tLimMlmSetKeysReq *pMlmSetKeysReq,
+			      tpPESession psessionEntry)
+{
+	struct scheduler_msg msgQ = {0};
+	tpSetBssKeyParams pSetBssKeyParams = NULL;
+	tLimMlmSetKeysCnf mlmSetKeysCnf;
+	QDF_STATUS retCode;
+
+	if (pMlmSetKeysReq->numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) {
+		pe_debug("numKeys = %d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS",
+			pMlmSetKeysReq->numKeys);
+
+		/* Respond to SME with error code */
+		mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+		goto end;
+	}
+	/* Package WMA_SET_BSSKEY_REQ message parameters */
+
+	pSetBssKeyParams = qdf_mem_malloc(sizeof(tSetBssKeyParams));
+	if (!pSetBssKeyParams) {
+		/* Respond to SME with error code */
+		mlmSetKeysCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+		goto end;
+	}
+
+	/* Update the WMA_SET_BSSKEY_REQ parameters */
+	pSetBssKeyParams->bssIdx = psessionEntry->bssIdx;
+	pSetBssKeyParams->encType = pMlmSetKeysReq->edType;
+
+	pSetBssKeyParams->singleTidRc =
+		(uint8_t)(pMac->mlme_cfg->sta.single_tid);
+	/* Update PE session Id */
+	pSetBssKeyParams->sessionId = psessionEntry->peSessionId;
+
+	pSetBssKeyParams->smesessionId = pMlmSetKeysReq->smesessionId;
+
+	if (pMlmSetKeysReq->key[0].keyId &&
+	    ((pMlmSetKeysReq->edType == eSIR_ED_WEP40) ||
+	     (pMlmSetKeysReq->edType == eSIR_ED_WEP104))
+	    ) {
+		/* IF the key id is non-zero and encryption type is WEP, Send all the 4
+		 * keys to HAL with filling the key at right index in pSetBssKeyParams->key. */
+		pSetBssKeyParams->numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
+		qdf_mem_copy((uint8_t *) &pSetBssKeyParams->
+			     key[pMlmSetKeysReq->key[0].keyId],
+			     (uint8_t *) &pMlmSetKeysReq->key[0],
+			     sizeof(pMlmSetKeysReq->key[0]));
+
+	} else {
+		pSetBssKeyParams->numKeys = pMlmSetKeysReq->numKeys;
+		qdf_mem_copy((uint8_t *) &pSetBssKeyParams->key,
+			     (uint8_t *) &pMlmSetKeysReq->key,
+			     sizeof(tSirKeys) * pMlmSetKeysReq->numKeys);
+	}
+
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+	msgQ.type = WMA_SET_BSSKEY_REQ;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pSetBssKeyParams;
+	msgQ.bodyval = 0;
+
+	pe_debug("Sending WMA_SET_BSSKEY_REQ...");
+	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		pe_err("Posting SET_BSSKEY to HAL failed, reason=%X",
+			retCode);
+
+		/* Respond to SME with LIM_MLM_SETKEYS_CNF */
+		mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+	} else
+		return;         /* Continue after WMA_SET_BSSKEY_RSP... */
+
+end:
+	lim_post_sme_set_keys_cnf(pMac, pMlmSetKeysReq, &mlmSetKeysCnf);
+
+}
+
+/**
+ * @function : lim_send_set_sta_key_req()
+ *
+ * @brief :  This function is called from lim_process_mlm_set_keys_req(),
+ * when PE is trying to setup the Unicast Keys related
+ * to a specified STA with specified encryption type
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac           Pointer to Global MAC structure
+ * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer
+ * @param staIdx         STA index for which the keys are being set
+ * @param defWEPIdx      The default WEP key index [0..3]
+ * @return none
+ */
+void lim_send_set_sta_key_req(tpAniSirGlobal pMac,
+			      tLimMlmSetKeysReq *pMlmSetKeysReq,
+			      uint16_t staIdx,
+			      uint8_t defWEPIdx,
+			      tpPESession sessionEntry, bool sendRsp)
+{
+	struct scheduler_msg msgQ = {0};
+	tpSetStaKeyParams pSetStaKeyParams = NULL;
+	tLimMlmSetKeysCnf mlmSetKeysCnf;
+	QDF_STATUS retCode;
+
+	/* Package WMA_SET_STAKEY_REQ message parameters */
+	pSetStaKeyParams = qdf_mem_malloc(sizeof(tSetStaKeyParams));
+	if (!pSetStaKeyParams)
+		goto fail;
+
+	/* Update the WMA_SET_STAKEY_REQ parameters */
+	pSetStaKeyParams->staIdx = staIdx;
+	pSetStaKeyParams->encType = pMlmSetKeysReq->edType;
+
+	pSetStaKeyParams->singleTidRc =
+		(uint8_t)(pMac->mlme_cfg->sta.single_tid);
+	/* Update  PE session ID */
+	pSetStaKeyParams->sessionId = sessionEntry->peSessionId;
+
+	/**
+	 * For WEP - defWEPIdx indicates the default WEP
+	 * Key to be used for TX
+	 * For all others, there's just one key that can
+	 * be used and hence it is assumed that
+	 * defWEPIdx = 0 (from the caller)
+	 */
+
+	pSetStaKeyParams->defWEPIdx = defWEPIdx;
+
+	pSetStaKeyParams->smesessionId = pMlmSetKeysReq->smesessionId;
+	qdf_copy_macaddr(&pSetStaKeyParams->peer_macaddr,
+			 &pMlmSetKeysReq->peer_macaddr);
+
+	if (sendRsp == true) {
+		/** Store the Previous MlmState*/
+		sessionEntry->limPrevMlmState = sessionEntry->limMlmState;
+		SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+	}
+
+	if (LIM_IS_IBSS_ROLE(sessionEntry)
+	    && !pMlmSetKeysReq->key[0].unicast) {
+		if (sendRsp == true)
+			sessionEntry->limMlmState =
+				eLIM_MLM_WT_SET_STA_BCASTKEY_STATE;
+		msgQ.type = WMA_SET_STA_BCASTKEY_REQ;
+	} else {
+		if (sendRsp == true)
+			sessionEntry->limMlmState =
+				eLIM_MLM_WT_SET_STA_KEY_STATE;
+		msgQ.type = WMA_SET_STAKEY_REQ;
+	}
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_MLM_STATE, sessionEntry->peSessionId,
+		       sessionEntry->limMlmState));
+
+	/**
+	 * In the Case of WEP_DYNAMIC, ED_TKIP and ED_CCMP
+	 * the Key[0] contains the KEY, so just copy that alone,
+	 * for the case of WEP_STATIC the hal gets the key from cfg
+	 */
+	switch (pMlmSetKeysReq->edType) {
+	case eSIR_ED_WEP40:
+	case eSIR_ED_WEP104:
+		/* FIXME! Is this OK? */
+		if (0 == pMlmSetKeysReq->numKeys) {
+			uint32_t i;
+
+			for (i = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) {
+				qdf_mem_copy((uint8_t *) &pSetStaKeyParams->
+					     key[i],
+					     (uint8_t *) &pMlmSetKeysReq->
+					     key[i], sizeof(tSirKeys));
+			}
+			pSetStaKeyParams->wepType = eSIR_WEP_STATIC;
+			sessionEntry->limMlmState =
+				eLIM_MLM_WT_SET_STA_KEY_STATE;
+			MTRACE(mac_trace
+				       (pMac, TRACE_CODE_MLM_STATE,
+				       sessionEntry->peSessionId,
+				       sessionEntry->limMlmState));
+		} else {
+			/*This case the keys are coming from upper layer so need to fill the
+			 * key at the default wep key index and send to the HAL */
+			if (defWEPIdx < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) {
+				qdf_mem_copy((uint8_t *) &pSetStaKeyParams->
+					     key[defWEPIdx],
+					     (uint8_t *) &pMlmSetKeysReq->
+					     key[0],
+					     sizeof(pMlmSetKeysReq->key[0]));
+				pMlmSetKeysReq->numKeys =
+					SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
+			} else {
+				pe_err("Wrong Key Index %d", defWEPIdx);
+				goto free_sta_key;
+			}
+		}
+		break;
+	case eSIR_ED_TKIP:
+	case eSIR_ED_CCMP:
+	case eSIR_ED_GCMP:
+	case eSIR_ED_GCMP_256:
+#ifdef FEATURE_WLAN_WAPI
+	case eSIR_ED_WPI:
+#endif
+		{
+			qdf_mem_copy((uint8_t *) &pSetStaKeyParams->key,
+				     (uint8_t *) &pMlmSetKeysReq->key[0],
+				     sizeof(tSirKeys));
+		}
+		break;
+	default:
+		break;
+	}
+
+	pSetStaKeyParams->sendRsp = sendRsp;
+
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pSetStaKeyParams;
+	msgQ.bodyval = 0;
+
+	pe_debug("Sending WMA_SET_STAKEY_REQ...");
+	MTRACE(mac_trace_msg_tx(pMac, sessionEntry->peSessionId, msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		pe_err("Posting SET_STAKEY to HAL failed, reason=%X",
+			retCode);
+		goto free_sta_key;
+	} else
+		return;         /* Continue after WMA_SET_STAKEY_RSP... */
+
+free_sta_key:
+	qdf_mem_free(pSetStaKeyParams);
+fail:
+	/* Respond to SME with LIM_MLM_SETKEYS_CNF */
+	mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+	if (sendRsp == true)
+		lim_post_sme_set_keys_cnf(pMac, pMlmSetKeysReq, &mlmSetKeysCnf);
+}
diff --git a/core/mac/src/pe/lim/lim_security_utils.h b/core/mac/src/pe/lim/lim_security_utils.h
new file mode 100644
index 0000000..4974e78
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_security_utils.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2011-2015, 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.
+ */
+
+/*
+ *
+ * This file lim_security_utils.h contains the utility definitions
+ * related to WEP encryption/decryption etc.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SECURITY_UTILS_H
+#define __LIM_SECURITY_UTILS_H
+#include "sir_mac_prot_def.h"      /* for tSirMacAuthFrameBody */
+
+#define LIM_ENCR_AUTH_BODY_LEN  (SIR_MAC_AUTH_FRAME_INFO_LEN + \
+				 SIR_MAC_AUTH_CHALLENGE_BODY_LEN + \
+				 SIR_MAC_WEP_IV_LENGTH + \
+				 SIR_MAC_WEP_ICV_LENGTH)
+
+#define LIM_ENCR_AUTH_BODY_LEN_SAP  (SIR_MAC_AUTH_FRAME_INFO_LEN + \
+					 SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH + \
+					 SIR_MAC_CHALLENGE_ID_LEN + \
+					 SIR_MAC_WEP_IV_LENGTH + \
+					 SIR_MAC_WEP_ICV_LENGTH)
+
+#define LIM_ENCR_AUTH_INFO_LEN	(SIR_MAC_AUTH_FRAME_INFO_LEN +\
+				 SIR_MAC_WEP_IV_LENGTH + \
+				 SIR_MAC_WEP_ICV_LENGTH + \
+				 SIR_MAC_CHALLENGE_ID_LEN)
+
+
+struct tLimPreAuthNode;
+
+uint8_t lim_is_auth_algo_supported(tpAniSirGlobal, tAniAuthType, tpPESession);
+
+/* MAC based authentication related functions */
+void lim_init_pre_auth_list(tpAniSirGlobal);
+void lim_delete_pre_auth_list(tpAniSirGlobal);
+struct tLimPreAuthNode *lim_search_pre_auth_list(tpAniSirGlobal, tSirMacAddr);
+void lim_add_pre_auth_node(tpAniSirGlobal, struct tLimPreAuthNode *);
+void lim_delete_pre_auth_node(tpAniSirGlobal, tSirMacAddr);
+void lim_release_pre_auth_node(tpAniSirGlobal pMac, tpLimPreAuthNode pAuthNode);
+void lim_restore_from_auth_state(tpAniSirGlobal,
+				 tSirResultCodes, uint16_t, tpPESession);
+uint8_t lim_delete_open_auth_pre_auth_node(tpAniSirGlobal mac_ctx);
+
+/* Encryption/Decryption related functions */
+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);
+uint8_t lim_decrypt_auth_frame(tpAniSirGlobal, uint8_t *, uint8_t *, uint8_t *,
+			       uint32_t, uint16_t);
+
+void lim_send_set_bss_key_req(tpAniSirGlobal, tLimMlmSetKeysReq *, tpPESession);
+void lim_send_set_sta_key_req(tpAniSirGlobal, tLimMlmSetKeysReq *, uint16_t, uint8_t,
+			      tpPESession, bool sendRsp);
+void lim_post_sme_set_keys_cnf(tpAniSirGlobal, tLimMlmSetKeysReq *,
+			       tLimMlmSetKeysCnf *);
+
+#define  PTAPS  0xedb88320
+
+static inline uint32_t lim_crc_update(uint32_t crc, uint8_t x)
+{
+
+	/* Update CRC computation for 8 bits contained in x */
+	/* */
+	uint32_t z;
+	uint32_t fb;
+	int i;
+
+	z = crc ^ x;
+	for (i = 0; i < 8; i++) {
+		fb = z & 1;
+		z >>= 1;
+		if (fb)
+			z ^= PTAPS;
+	}
+	return z;
+}
+
+#endif /* __LIM_SECURITY_UTILS_H */
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
new file mode 100644
index 0000000..9b63e5c
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_frames_host_roam.c
@@ -0,0 +1,850 @@
+/*
+ * Copyright (c) 2016-2018 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: lim_send_frames_host_roam.c
+ *
+ * Send management frames for host based roaming
+ */
+#include "sir_api.h"
+#include "ani_global.h"
+#include "sir_mac_prot_def.h"
+#include "cfg_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_security_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "dot11f.h"
+#include "lim_sta_hash_api.h"
+#include "sch_api.h"
+#include "lim_send_messages.h"
+#include "lim_assoc_utils.h"
+#include "lim_ft.h"
+#ifdef WLAN_FEATURE_11W
+#include "wni_cfg.h"
+#endif
+
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "cds_utils.h"
+#include "sme_trace.h"
+#include "rrm_api.h"
+
+#include "wma_types.h"
+#include "wlan_utility.h"
+
+/**
+ * lim_send_reassoc_req_with_ft_ies_mgmt_frame() - Send Reassoc Req with FTIEs.
+ *
+ * @mac_ctx: Handle to mac context
+ * @mlm_reassoc_req: Original reassoc request
+ * @pe_session: PE session information
+ *
+ * It builds a reassoc request with FT IEs and sends it to AP through WMA.
+ * Then it creates assoc request and stores it for sending after join
+ * confirmation.
+ *
+ * Return: None
+ */
+void lim_send_reassoc_req_with_ft_ies_mgmt_frame(tpAniSirGlobal mac_ctx,
+	tLimMlmReassocReq *mlm_reassoc_req,
+	tpPESession pe_session)
+{
+	tDot11fReAssocRequest *frm;
+	uint16_t caps;
+	uint8_t *frame;
+	uint32_t bytes, payload, status;
+	uint8_t qos_enabled, wme_enabled, wsm_enabled;
+	void *packet;
+	QDF_STATUS qdf_status;
+	uint8_t power_caps_populated = false;
+	uint16_t ft_ies_length = 0;
+	uint8_t *body;
+	uint16_t add_ie_len;
+	uint8_t *add_ie;
+	const uint8_t *wps_ie = NULL;
+	uint8_t tx_flag = 0;
+	uint8_t sme_sessionid = 0;
+	bool vht_enabled = false;
+	tpSirMacMgmtHdr mac_hdr;
+	tftSMEContext *ft_sme_context;
+
+	if (NULL == pe_session)
+		return;
+
+	sme_sessionid = pe_session->smeSessionId;
+
+	/* check this early to avoid unncessary operation */
+	if (NULL == pe_session->pLimReAssocReq)
+		return;
+
+	frm = qdf_mem_malloc(sizeof(*frm));
+	if (!frm)
+		goto err;
+
+	add_ie_len = pe_session->pLimReAssocReq->addIEAssoc.length;
+	add_ie = pe_session->pLimReAssocReq->addIEAssoc.addIEdata;
+	pe_debug("called in state: %d", pe_session->limMlmState);
+
+	qdf_mem_set((uint8_t *) frm, sizeof(*frm), 0);
+
+	caps = mlm_reassoc_req->capabilityInfo;
+#if defined(FEATURE_WLAN_WAPI)
+	/*
+	 * According to WAPI standard:
+	 * 7.3.1.4 Capability Information field
+	 * In WAPI, non-AP STAs within an ESS set the Privacy subfield
+	 * to 0 in transmitted Association or Reassociation management
+	 * frames. APs ignore the Privacy subfield within received
+	 * Association and Reassociation management frames.
+	 */
+	if (pe_session->encryptType == eSIR_ED_WPI)
+		((tSirMacCapabilityInfo *) &caps)->privacy = 0;
+#endif
+	swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
+
+	frm->ListenInterval.interval = mlm_reassoc_req->listenInterval;
+
+	/*
+	 * Get the old bssid of the older AP.
+	 * The previous ap bssid is stored in the FT Session
+	 * while creating the PE FT Session for reassociation.
+	 */
+	qdf_mem_copy((uint8_t *)frm->CurrentAPAddress.mac,
+			pe_session->prev_ap_bssid, sizeof(tSirMacAddr));
+
+	populate_dot11f_ssid2(mac_ctx, &frm->SSID);
+	populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
+		&frm->SuppRates, pe_session);
+
+	qos_enabled = (pe_session->limQosEnabled) &&
+		      SIR_MAC_GET_QOS(pe_session->limReassocBssCaps);
+
+	wme_enabled = (pe_session->limWmeEnabled) &&
+		      LIM_BSS_CAPS_GET(WME, pe_session->limReassocBssQosCaps);
+
+	wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
+		      LIM_BSS_CAPS_GET(WSM, pe_session->limReassocBssQosCaps);
+
+	if (pe_session->lim11hEnable &&
+	    pe_session->pLimReAssocReq->spectrumMgtIndicator == true) {
+		power_caps_populated = true;
+
+		populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
+					   LIM_REASSOC, pe_session);
+		populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
+			LIM_REASSOC, pe_session);
+	}
+	if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
+	    SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
+		if (power_caps_populated == false) {
+			power_caps_populated = true;
+			populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
+				LIM_REASSOC, pe_session);
+		}
+	}
+
+	if (qos_enabled)
+		populate_dot11f_qos_caps_station(mac_ctx, pe_session,
+						&frm->QOSCapsStation);
+
+	populate_dot11f_ext_supp_rates(mac_ctx,
+		POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
+		pe_session);
+
+	if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
+	    SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
+		populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap, pe_session);
+
+	/*
+	 * Ideally this should be enabled for 11r also. But 11r does
+	 * not follow the usual norm of using the Opaque object
+	 * for rsnie and fties. Instead we just add the rsnie and fties
+	 * at the end of the pack routine for 11r.
+	 * This should ideally! be fixed.
+	 */
+	/*
+	 * The join request *should* contain zero or one of the WPA and RSN
+	 * IEs.  The payload send along with the request is a
+	 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
+	 *
+	 *     typedef struct sSirRSNie
+	 *     {
+	 *         uint16_t       length;
+	 *         uint8_t        rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
+	 *     } tSirRSNie, *tpSirRSNie;
+	 *
+	 * So, we should be able to make the following two calls harmlessly,
+	 * since they do nothing if they don't find the given IE in the
+	 * bytestream with which they're provided.
+	 *
+	 * The net effect of this will be to faithfully transmit whatever
+	 * security IE is in the join request.
+
+	 * However, if we're associating for the purpose of WPS
+	 * enrollment, and we've been configured to indicate that by
+	 * eliding the WPA or RSN IE, we just skip this:
+	 */
+	if (!pe_session->is11Rconnection) {
+		if (add_ie_len && add_ie)
+			wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
+		if (NULL == wps_ie) {
+			populate_dot11f_rsn_opaque(mac_ctx,
+				&(pe_session->pLimReAssocReq->rsnIE),
+				&frm->RSNOpaque);
+			populate_dot11f_wpa_opaque(mac_ctx,
+				&(pe_session->pLimReAssocReq->rsnIE),
+				&frm->WPAOpaque);
+		}
+#ifdef FEATURE_WLAN_ESE
+		if (pe_session->pLimReAssocReq->cckmIE.length) {
+			populate_dot11f_ese_cckm_opaque(mac_ctx,
+				&(pe_session->pLimReAssocReq->cckmIE),
+				&frm->ESECckmOpaque);
+		}
+#endif
+	}
+#ifdef FEATURE_WLAN_ESE
+	/*
+	 * ESE Version IE will be included in re-association request
+	 * when ESE is enabled on DUT through ini and it is also
+	 * advertised by the peer AP to which we are trying to
+	 * associate to.
+	 */
+	if (pe_session->is_ese_version_ie_present &&
+		mac_ctx->roam.configParam.isEseIniFeatureEnabled)
+		populate_dot11f_ese_version(&frm->ESEVersion);
+	/* For ESE Associations fill the ESE IEs */
+	if (pe_session->isESEconnection &&
+	    pe_session->pLimReAssocReq->isESEFeatureIniEnabled) {
+#ifndef FEATURE_DISABLE_RM
+		populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
+#endif
+	}
+#endif /* FEATURE_WLAN_ESE */
+
+	/* include WME EDCA IE as well */
+	if (wme_enabled) {
+		populate_dot11f_wmm_info_station_per_session(mac_ctx,
+			pe_session, &frm->WMMInfoStation);
+		if (wsm_enabled)
+			populate_dot11f_wmm_caps(&frm->WMMCaps);
+#ifdef FEATURE_WLAN_ESE
+		if (pe_session->isESEconnection) {
+			uint32_t phymode;
+			uint8_t rate;
+
+			populate_dot11f_re_assoc_tspec(mac_ctx, frm,
+				pe_session);
+
+			/*
+			 * Populate the TSRS IE if TSPEC is included in
+			 * the reassoc request
+			 */
+			lim_get_phy_mode(mac_ctx, &phymode, pe_session);
+			if (phymode == WNI_CFG_PHY_MODE_11G ||
+			    phymode == WNI_CFG_PHY_MODE_11A)
+				rate = TSRS_11AG_RATE_6MBPS;
+			else
+				rate = TSRS_11B_RATE_5_5MBPS;
+
+			if (pe_session->pLimReAssocReq->eseTspecInfo.
+			    numTspecs) {
+				tSirMacESETSRSIE tsrs_ie;
+
+				tsrs_ie.tsid = 0;
+				tsrs_ie.rates[0] = rate;
+				populate_dot11_tsrsie(mac_ctx, &tsrs_ie,
+					&frm->ESETrafStrmRateSet,
+					sizeof(uint8_t));
+			}
+		}
+#endif
+	}
+
+	ft_sme_context = &mac_ctx->roam.roamSession[sme_sessionid].ftSmeContext;
+	if (pe_session->htCapability &&
+	    mac_ctx->lim.htCapabilityPresentInBeacon) {
+		populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
+	}
+	if (pe_session->pLimReAssocReq->bssDescription.mdiePresent &&
+	    (ft_sme_context->addMDIE == true)
+#if defined FEATURE_WLAN_ESE
+	    && !pe_session->isESEconnection
+#endif
+	    ) {
+		populate_mdie(mac_ctx, &frm->MobilityDomain,
+			pe_session->pLimReAssocReq->bssDescription.mdie);
+	}
+	if (pe_session->vhtCapability &&
+	    pe_session->vhtCapabilityPresentInBeacon) {
+		pe_debug("Populate VHT IEs in Re-Assoc Request");
+		populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
+		vht_enabled = true;
+		populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm->ExtCap,
+			pe_session);
+	}
+	if (!vht_enabled &&
+			pe_session->is_vendor_specific_vhtcaps) {
+		pe_debug("Populate Vendor VHT IEs in Re-Assoc Request");
+		frm->vendor_vht_ie.present = 1;
+		frm->vendor_vht_ie.sub_type =
+			pe_session->vendor_specific_vht_ie_sub_type;
+		frm->vendor_vht_ie.VHTCaps.present = 1;
+		populate_dot11f_vht_caps(mac_ctx, pe_session,
+				&frm->vendor_vht_ie.VHTCaps);
+		vht_enabled = true;
+	}
+
+	if (lim_is_session_he_capable(pe_session)) {
+		pe_debug("Populate HE IEs");
+		populate_dot11f_he_caps(mac_ctx, pe_session,
+					&frm->he_cap);
+	}
+
+	status = dot11f_get_packed_re_assoc_request_size(mac_ctx, frm,
+			&payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failure in size calculation (0x%08x)", status);
+		/* We'll fall back on the worst case scenario: */
+		payload = sizeof(tDot11fReAssocRequest);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("Warnings in size calculation (0x%08x)", status);
+	}
+
+	bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
+
+	pe_debug("FT IE Reassoc Req %d",
+		ft_sme_context->reassoc_ft_ies_length);
+
+	if (pe_session->is11Rconnection)
+		ft_ies_length = ft_sme_context->reassoc_ft_ies_length;
+
+	qdf_status = cds_packet_alloc((uint16_t) bytes + ft_ies_length,
+				 (void **)&frame, (void **)&packet);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_session->limMlmState = pe_session->limPrevMlmState;
+		MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
+				 pe_session->peSessionId,
+				 pe_session->limMlmState));
+		pe_err("Failed to alloc memory %d", bytes);
+		goto end;
+	}
+	/* Paranoia: */
+	qdf_mem_set(frame, bytes + ft_ies_length, 0);
+
+	lim_print_mac_addr(mac_ctx, pe_session->limReAssocbssId, LOGD);
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_REASSOC_REQ, pe_session->limReAssocbssId,
+		pe_session->selfMacAddr);
+	mac_hdr = (tpSirMacMgmtHdr) frame;
+	/* That done, pack the ReAssoc Request: */
+	status = dot11f_pack_re_assoc_request(mac_ctx, frm, frame +
+					       sizeof(tSirMacMgmtHdr),
+					       payload, &payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failure in pack (0x%08x)", status);
+		cds_packet_free((void *)packet);
+		goto end;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("Warnings in pack (0x%08x)", status);
+	}
+
+	pe_debug("*** Sending Re-Assoc Request length: %d %d to",
+		       bytes, payload);
+
+	if (pe_session->assocReq != NULL) {
+		qdf_mem_free(pe_session->assocReq);
+		pe_session->assocReq = NULL;
+		pe_session->assocReqLen = 0;
+	}
+
+	if (add_ie_len) {
+		qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+			     add_ie, add_ie_len);
+		payload += add_ie_len;
+	}
+
+	pe_session->assocReq = qdf_mem_malloc(payload);
+	if (pe_session->assocReq) {
+		/*
+		 * Store the Assoc request. This is sent to csr/hdd in
+		 * join cnf response.
+		 */
+		qdf_mem_copy(pe_session->assocReq,
+			     frame + sizeof(tSirMacMgmtHdr), payload);
+		pe_session->assocReqLen = payload;
+	}
+
+	if (pe_session->is11Rconnection && ft_sme_context->reassoc_ft_ies) {
+		int i = 0;
+
+		body = frame + bytes;
+		for (i = 0; i < ft_ies_length; i++) {
+			*body = ft_sme_context->reassoc_ft_ies[i];
+			body++;
+		}
+	}
+	pe_debug("Re-assoc Req Frame is:");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			   (uint8_t *) frame, (bytes + ft_ies_length));
+
+	if ((NULL != pe_session->ftPEContext.pFTPreAuthReq) &&
+	    (BAND_5G == lim_get_rf_band(
+	     pe_session->ftPEContext.pFTPreAuthReq->preAuthchannelNum)))
+		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	else if ((BAND_5G ==
+		  lim_get_rf_band(pe_session->currentOperChannel))
+		 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE)
+		 || (pe_session->pePersona == QDF_P2P_GO_MODE))
+		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+	if (NULL != pe_session->assocReq) {
+		qdf_mem_free(pe_session->assocReq);
+		pe_session->assocReq = NULL;
+		pe_session->assocReqLen = 0;
+	}
+	if (ft_ies_length) {
+		pe_session->assocReq = qdf_mem_malloc(ft_ies_length);
+		if (!pe_session->assocReq) {
+			pe_session->assocReqLen = 0;
+		} else {
+			/*
+			 * Store the FT IEs. This is sent to csr/hdd in
+			 * join cnf response.
+			 */
+			qdf_mem_copy(pe_session->assocReq,
+				ft_sme_context->reassoc_ft_ies, ft_ies_length);
+			pe_session->assocReqLen = ft_ies_length;
+		}
+	} else {
+		pe_debug("FT IEs not present");
+		pe_session->assocReqLen = 0;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 pe_session->peSessionId, mac_hdr->fc.subType));
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_START_EVENT,
+			      pe_session, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+	lim_diag_mgmt_tx_event_report(mac_ctx, mac_hdr,
+				      pe_session, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+	qdf_status = wma_tx_frame(mac_ctx, packet,
+				(uint16_t) (bytes + ft_ies_length),
+				TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+				lim_tx_complete, frame, tx_flag, sme_sessionid,
+				0, RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+		       pe_session->peSessionId, qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to send Re-Assoc Request: %X!", qdf_status);
+	}
+
+end:
+	qdf_mem_free(frm);
+err:
+	/* Free up buffer allocated for mlmAssocReq */
+	qdf_mem_free(mlm_reassoc_req);
+	pe_session->pLimMlmReassocReq = NULL;
+
+}
+
+/**
+ * lim_send_retry_reassoc_req_frame() - Retry for reassociation
+ * @pMac: Global MAC Context
+ * @pMlmReassocReq: Request buffer to be sent
+ * @psessionEntry: PE Session
+ *
+ * Return: None
+ */
+void lim_send_retry_reassoc_req_frame(tpAniSirGlobal pMac,
+				      tLimMlmReassocReq *pMlmReassocReq,
+				      tpPESession psessionEntry)
+{
+	tLimMlmReassocCnf mlmReassocCnf;        /* keep sme */
+	tLimMlmReassocReq *pTmpMlmReassocReq = NULL;
+
+	if (NULL == pTmpMlmReassocReq) {
+		pTmpMlmReassocReq = qdf_mem_malloc(sizeof(tLimMlmReassocReq));
+		if (NULL == pTmpMlmReassocReq)
+			goto end;
+		qdf_mem_copy(pTmpMlmReassocReq, pMlmReassocReq,
+			     sizeof(tLimMlmReassocReq));
+	}
+	/* Prepare and send Reassociation request frame */
+	/* start reassoc timer. */
+	pMac->lim.limTimers.gLimReassocFailureTimer.sessionId =
+		psessionEntry->peSessionId;
+	/* Start reassociation failure timer */
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TIMER_ACTIVATE,
+			 psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER));
+	if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer)
+	    != TX_SUCCESS) {
+		/* Could not start reassoc failure timer. */
+		/* Log error */
+		pe_err("could not start Reassociation failure timer");
+		/* Return Reassoc confirm with */
+		/* Resources Unavailable */
+		mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+		mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+		goto end;
+	}
+
+	lim_send_reassoc_req_with_ft_ies_mgmt_frame(pMac, pTmpMlmReassocReq,
+						    psessionEntry);
+	return;
+
+end:
+	/* Free up buffer allocated for reassocReq */
+	if (pMlmReassocReq != NULL) {
+		qdf_mem_free(pMlmReassocReq);
+		pMlmReassocReq = NULL;
+	}
+	if (pTmpMlmReassocReq != NULL) {
+		qdf_mem_free(pTmpMlmReassocReq);
+		pTmpMlmReassocReq = NULL;
+	}
+	mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
+	mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+	/* Update PE sessio Id */
+	mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+
+	lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+			     (uint32_t *) &mlmReassocCnf);
+}
+
+/**
+ * lim_send_reassoc_req_mgmt_frame() - Send the reassociation frame
+ * @pMac: Global MAC Context
+ * @pMlmReassocReq: Reassociation request buffer to be sent
+ * @psessionEntry: PE Session
+ *
+ * Return: None
+ */
+void lim_send_reassoc_req_mgmt_frame(tpAniSirGlobal pMac,
+				tLimMlmReassocReq *pMlmReassocReq,
+				tpPESession psessionEntry)
+{
+	tDot11fReAssocRequest *frm;
+	uint16_t caps;
+	uint8_t *pFrame;
+	uint32_t nBytes, nPayload, nStatus;
+	uint8_t fQosEnabled, fWmeEnabled, fWsmEnabled;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint16_t nAddIELen;
+	uint8_t *pAddIE;
+	const uint8_t *wpsIe = NULL;
+	uint8_t txFlag = 0;
+	uint8_t PowerCapsPopulated = false;
+	uint8_t smeSessionId = 0;
+	bool isVHTEnabled = false;
+	tpSirMacMgmtHdr pMacHdr;
+
+	if (NULL == psessionEntry)
+		return;
+
+	smeSessionId = psessionEntry->smeSessionId;
+	if (NULL == psessionEntry->pLimReAssocReq)
+		return;
+
+	frm = qdf_mem_malloc(sizeof(*frm));
+	if (!frm)
+		goto err;
+	nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length;
+	pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata;
+
+	qdf_mem_set((uint8_t *) frm, sizeof(*frm), 0);
+
+	caps = pMlmReassocReq->capabilityInfo;
+#if defined(FEATURE_WLAN_WAPI)
+	/*
+	 * CR: 262463 :
+	 * According to WAPI standard:
+	 * 7.3.1.4 Capability Information field
+	 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in
+	 * transmitted. Association or Reassociation management frames. APs
+	 * ignore the Privacy subfield within received Association and
+	 * Reassociation management frames.
+	 */
+	if (psessionEntry->encryptType == eSIR_ED_WPI)
+		((tSirMacCapabilityInfo *) &caps)->privacy = 0;
+#endif
+	swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
+
+	frm->ListenInterval.interval = pMlmReassocReq->listenInterval;
+
+	qdf_mem_copy((uint8_t *) frm->CurrentAPAddress.mac,
+		     (uint8_t *) psessionEntry->bssId, 6);
+
+	populate_dot11f_ssid2(pMac, &frm->SSID);
+	populate_dot11f_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+				   &frm->SuppRates, psessionEntry);
+
+	fQosEnabled = (psessionEntry->limQosEnabled) &&
+		      SIR_MAC_GET_QOS(psessionEntry->limReassocBssCaps);
+
+	fWmeEnabled = (psessionEntry->limWmeEnabled) &&
+		     LIM_BSS_CAPS_GET(WME, psessionEntry->limReassocBssQosCaps);
+
+	fWsmEnabled = (psessionEntry->limWsmEnabled) && fWmeEnabled &&
+		     LIM_BSS_CAPS_GET(WSM, psessionEntry->limReassocBssQosCaps);
+
+	if (psessionEntry->lim11hEnable &&
+	    psessionEntry->pLimReAssocReq->spectrumMgtIndicator == true) {
+		PowerCapsPopulated = true;
+		populate_dot11f_power_caps(pMac, &frm->PowerCaps, LIM_REASSOC,
+					   psessionEntry);
+		populate_dot11f_supp_channels(pMac, &frm->SuppChannels,
+				LIM_REASSOC, psessionEntry);
+	}
+	if (pMac->rrm.rrmPEContext.rrmEnable &&
+	    SIR_MAC_GET_RRM(psessionEntry->limCurrentBssCaps)) {
+		if (PowerCapsPopulated == false) {
+			PowerCapsPopulated = true;
+			populate_dot11f_power_caps(pMac, &frm->PowerCaps,
+						   LIM_REASSOC, psessionEntry);
+		}
+	}
+
+	if (fQosEnabled)
+		populate_dot11f_qos_caps_station(pMac, psessionEntry,
+						&frm->QOSCapsStation);
+
+	populate_dot11f_ext_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+				       &frm->ExtSuppRates, psessionEntry);
+
+	if (pMac->rrm.rrmPEContext.rrmEnable &&
+	    SIR_MAC_GET_RRM(psessionEntry->limCurrentBssCaps))
+		populate_dot11f_rrm_ie(pMac, &frm->RRMEnabledCap, psessionEntry);
+	/* The join request *should* contain zero or one of the WPA and RSN */
+	/* IEs.  The payload send along with the request is a */
+	/* 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': */
+
+	/*     typedef struct sSirRSNie */
+	/*     { */
+	/*         uint16_t       length; */
+	/*         uint8_t        rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; */
+	/*     } tSirRSNie, *tpSirRSNie; */
+
+	/* So, we should be able to make the following two calls harmlessly, */
+	/* since they do nothing if they don't find the given IE in the */
+	/* bytestream with which they're provided. */
+
+	/* The net effect of this will be to faithfully transmit whatever */
+	/* security IE is in the join request. */
+
+	/**However*, if we're associating for the purpose of WPS */
+	/* enrollment, and we've been configured to indicate that by */
+	/* eliding the WPA or RSN IE, we just skip this: */
+	if (nAddIELen && pAddIE)
+		wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen);
+	if (NULL == wpsIe) {
+		populate_dot11f_rsn_opaque(pMac,
+				&(psessionEntry->pLimReAssocReq->rsnIE),
+				&frm->RSNOpaque);
+		populate_dot11f_wpa_opaque(pMac,
+				&(psessionEntry->pLimReAssocReq->rsnIE),
+				&frm->WPAOpaque);
+#if defined(FEATURE_WLAN_WAPI)
+		populate_dot11f_wapi_opaque(pMac,
+					    &(psessionEntry->pLimReAssocReq->
+					      rsnIE), &frm->WAPIOpaque);
+#endif /* defined(FEATURE_WLAN_WAPI) */
+	}
+	/* include WME EDCA IE as well */
+	if (fWmeEnabled) {
+		populate_dot11f_wmm_info_station_per_session(pMac,
+				psessionEntry, &frm->WMMInfoStation);
+
+		if (fWsmEnabled)
+			populate_dot11f_wmm_caps(&frm->WMMCaps);
+	}
+
+	if (psessionEntry->htCapability &&
+	    pMac->lim.htCapabilityPresentInBeacon) {
+		populate_dot11f_ht_caps(pMac, psessionEntry, &frm->HTCaps);
+	}
+	if (psessionEntry->vhtCapability &&
+	    psessionEntry->vhtCapabilityPresentInBeacon) {
+		pe_warn("Populate VHT IEs in Re-Assoc Request");
+		populate_dot11f_vht_caps(pMac, psessionEntry, &frm->VHTCaps);
+		isVHTEnabled = true;
+	}
+	populate_dot11f_ext_cap(pMac, isVHTEnabled, &frm->ExtCap, psessionEntry);
+
+	if (lim_is_session_he_capable(psessionEntry)) {
+		pe_debug("Populate HE IEs");
+		populate_dot11f_he_caps(pMac, psessionEntry,
+					&frm->he_cap);
+	}
+
+	nStatus =
+		dot11f_get_packed_re_assoc_request_size(pMac, frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Fail to get size:ReassocReq: (0x%08x)", nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fReAssocRequest);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_err("warning for size:ReAssoc Req: (0x%08x)", nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr) + nAddIELen;
+
+	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				      (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
+		MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
+				 psessionEntry->peSessionId,
+				 psessionEntry->limMlmState));
+		pe_err("Failed to alloc %d bytes for a ReAssociation Req",
+			nBytes);
+		goto end;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_REASSOC_REQ, psessionEntry->limReAssocbssId,
+		psessionEntry->selfMacAddr);
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	/* That done, pack the Probe Request: */
+	nStatus = dot11f_pack_re_assoc_request(pMac, frm, pFrame +
+					       sizeof(tSirMacMgmtHdr),
+					       nPayload, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Fail to pack a Re-Assoc Req: (0x%08x)", nStatus);
+		cds_packet_free((void *)pPacket);
+		goto end;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("warning packing a Re-AssocReq: (0x%08x)", nStatus);
+	}
+
+	pe_debug("*** Sending Re-Association Request length: %d" "to", nBytes);
+
+	if (psessionEntry->assocReq != NULL) {
+		qdf_mem_free(psessionEntry->assocReq);
+		psessionEntry->assocReq = NULL;
+		psessionEntry->assocReqLen = 0;
+	}
+
+	if (nAddIELen) {
+		qdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload,
+			     pAddIE, nAddIELen);
+		nPayload += nAddIELen;
+	}
+
+	psessionEntry->assocReq = qdf_mem_malloc(nPayload);
+	if (psessionEntry->assocReq) {
+		/* Store the Assocrequest. It is sent to csr in joincnfrsp */
+		qdf_mem_copy(psessionEntry->assocReq,
+			     pFrame + sizeof(tSirMacMgmtHdr), nPayload);
+		psessionEntry->assocReqLen = nPayload;
+	}
+
+	if ((BAND_5G ==
+		lim_get_rf_band(psessionEntry->currentOperChannel))
+			|| (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
+			(psessionEntry->pePersona == QDF_P2P_GO_MODE))
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+	if (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE ||
+		psessionEntry->pePersona == QDF_STA_MODE)
+		txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 psessionEntry->peSessionId, pMacHdr->fc.subType));
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_REASSOC_START_EVENT,
+			      psessionEntry, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+	lim_diag_mgmt_tx_event_report(pMac, pMacHdr,
+				      psessionEntry, QDF_STATUS_SUCCESS,
+				      QDF_STATUS_SUCCESS);
+	qdf_status =
+		wma_tx_frame(pMac, pPacket,
+			   (uint16_t) (sizeof(tSirMacMgmtHdr) + nPayload),
+			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+			   lim_tx_complete, pFrame, txFlag, smeSessionId, 0,
+			   RATEID_DEFAULT);
+	MTRACE(qdf_trace
+		       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+		       psessionEntry->peSessionId, qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to send Re-Association Request: %X!",
+			qdf_status);
+		/* Pkt will be freed up by the callback */
+	}
+
+end:
+	qdf_mem_free(frm);
+err:
+	/* Free up buffer allocated for mlmAssocReq */
+	qdf_mem_free(pMlmReassocReq);
+	psessionEntry->pLimMlmReassocReq = NULL;
+
+}
+
+void lim_process_rx_scan_handler(struct wlan_objmgr_vdev *vdev,
+				 struct scan_event *event,
+				 void *arg)
+{
+	tpAniSirGlobal mac_ctx;
+	enum sir_scan_event_type event_type;
+
+	QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+		  "event: %u, id: 0x%x, requestor: 0x%x, freq: %u, reason: %u",
+		  event->type, event->scan_id, event->requester,
+		  event->chan_freq, event->reason);
+
+	mac_ctx = (tpAniSirGlobal)arg;
+	event_type = 0x1 << event->type;
+
+	qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_PE, event->type,
+		   event->vdev_id, event->scan_id);
+
+	switch (event_type) {
+	case SIR_SCAN_EVENT_STARTED:
+		break;
+	case SIR_SCAN_EVENT_COMPLETED:
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			  "No.of beacons and probe response received per scan %d",
+			  mac_ctx->lim.beacon_probe_rsp_cnt_per_scan);
+	/* Fall through */
+	case SIR_SCAN_EVENT_FOREIGN_CHANNEL:
+	case SIR_SCAN_EVENT_START_FAILED:
+		if ((mac_ctx->lim.req_id | PREAUTH_REQUESTOR_ID) ==
+		    event->requester)
+			lim_preauth_scan_event_handler(mac_ctx,
+						       event_type,
+						       event->vdev_id,
+						       event->scan_id);
+		break;
+	case SIR_SCAN_EVENT_BSS_CHANNEL:
+	case SIR_SCAN_EVENT_DEQUEUED:
+	case SIR_SCAN_EVENT_PREEMPTED:
+	default:
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			  "Received unhandled scan event %u",
+			  event_type);
+	}
+}
diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c
new file mode 100644
index 0000000..aa304f1
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_management_frames.c
@@ -0,0 +1,5049 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ * \file lim_send_management_frames.c
+ *
+ * \brief Code for preparing and sending 802.11 Management frames
+ *
+ *
+ */
+
+#include "sir_api.h"
+#include "ani_global.h"
+#include "sir_mac_prot_def.h"
+#include "cfg_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_security_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "dot11f.h"
+#include "lim_sta_hash_api.h"
+#include "sch_api.h"
+#include "lim_send_messages.h"
+#include "lim_assoc_utils.h"
+#include "lim_ft.h"
+#ifdef WLAN_FEATURE_11W
+#include "wni_cfg.h"
+#endif
+
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "cds_utils.h"
+#include "sme_trace.h"
+#include "rrm_api.h"
+#include "qdf_crypto.h"
+
+#include "wma_types.h"
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_peer_ops.h>
+#include "lim_process_fils.h"
+#include "wlan_utility.h"
+
+/**
+ *
+ * \brief This function is called to add the sequence number to the
+ * management frames
+ *
+ * \param  pMac Pointer to Global MAC structure
+ *
+ * \param  pMacHdr Pointer to MAC management header
+ *
+ * The pMacHdr argument points to the MAC management header. The
+ * sequence number stored in the pMac structure will be incremented
+ * and updated to the MAC management header. The start sequence
+ * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
+ * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
+ * number will roll over.
+ *
+ */
+static void lim_add_mgmt_seq_num(tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr)
+{
+	if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) {
+		pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
+	}
+
+	pMac->mgmtSeqNum++;
+
+	pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK);
+	pMacHdr->seqControl.seqNumHi =
+		((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET);
+}
+
+/**
+ *
+ * \brief This function is called before sending a p2p action frame
+ * inorder to add sequence numbers to action packets
+ *
+ * \param  pMac Pointer to Global MAC structure
+ *
+ * \param pBD Pointer to the frame buffer that needs to be populate
+ *
+ * The pMacHdr argument points to the MAC management header. The
+ * sequence number stored in the pMac structure will be incremented
+ * and updated to the MAC management header. The start sequence
+ * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
+ * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
+ * number will roll over.
+ *
+ */
+void lim_populate_p2p_mac_header(tpAniSirGlobal pMac, uint8_t *pBD)
+{
+	tpSirMacMgmtHdr pMacHdr;
+
+	/* / Prepare MAC management header */
+	pMacHdr = (tpSirMacMgmtHdr) (pBD);
+
+	/* Prepare sequence number */
+	lim_add_mgmt_seq_num(pMac, pMacHdr);
+	pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
+		pMacHdr->seqControl.seqNumLo,
+		pMacHdr->seqControl.seqNumHi, pMac->mgmtSeqNum);
+}
+
+/**
+ * lim_populate_mac_header() - Fill in 802.11 header of frame
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @buf: Pointer to the frame buffer that needs to be populate
+ * @type: 802.11 Type of the frame
+ * @sub_type: 802.11 Subtype of the frame
+ * @peer_addr: dst address
+ * @self_mac_addr: local mac address
+ *
+ * This function is called by various LIM modules to prepare the
+ * 802.11 frame MAC header
+ *
+ * The buf argument points to the beginning of the frame buffer to
+ * which - a) The 802.11 MAC header is set b) Following this MAC header
+ * will be the MGMT frame payload The payload itself is populated by the
+ * caller API
+ *
+ * Return: None
+ */
+
+void lim_populate_mac_header(tpAniSirGlobal mac_ctx, uint8_t *buf,
+		uint8_t type, uint8_t sub_type, tSirMacAddr peer_addr,
+		tSirMacAddr self_mac_addr)
+{
+	tpSirMacMgmtHdr mac_hdr;
+
+	/* Prepare MAC management header */
+	mac_hdr = (tpSirMacMgmtHdr) (buf);
+
+	/* Prepare FC */
+	mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
+	mac_hdr->fc.type = type;
+	mac_hdr->fc.subType = sub_type;
+
+	/* Prepare Address 1 */
+	qdf_mem_copy((uint8_t *) mac_hdr->da,
+		     (uint8_t *) peer_addr, sizeof(tSirMacAddr));
+
+	/* Prepare Address 2 */
+	sir_copy_mac_addr(mac_hdr->sa, self_mac_addr);
+
+	/* Prepare Address 3 */
+	qdf_mem_copy((uint8_t *) mac_hdr->bssId,
+		     (uint8_t *) peer_addr, sizeof(tSirMacAddr));
+
+	/* Prepare sequence number */
+	lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
+	pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
+		mac_hdr->seqControl.seqNumLo,
+		mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum);
+}
+
+/**
+ * lim_send_probe_req_mgmt_frame() - send probe request management frame
+ * @mac_ctx: Pointer to Global MAC structure
+ * @ssid: SSID to be sent in Probe Request frame
+ * @bssid: BSSID to be sent in Probe Request frame
+ * @channel: Channel # on which the Probe Request is going out
+ * @self_macaddr: self MAC address
+ * @dot11mode: self dotllmode
+ * @additional_ielen: if non-zero, include additional_ie in the Probe Request
+ *                   frame
+ * @additional_ie: if additional_ielen is non zero, include this field in the
+ *                Probe Request frame
+ *
+ * This function is called by various LIM modules to send Probe Request frame
+ * during active scan/learn phase.
+ * Probe request is sent out in the following scenarios:
+ * --heartbeat failure:  session needed
+ * --join req:           session needed
+ * --foreground scan:    no session
+ * --background scan:    no session
+ * --sch_beacon_processing:  to get EDCA parameters:  session needed
+ *
+ * Return: QDF_STATUS (QDF_STATUS_SUCCESS on success and error codes otherwise)
+ */
+QDF_STATUS
+lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
+			      tSirMacSSid *ssid,
+			      tSirMacAddr bssid,
+			      uint8_t channel,
+			      tSirMacAddr self_macaddr,
+			      uint32_t dot11mode,
+			      uint16_t *additional_ielen, uint8_t *additional_ie)
+{
+	tDot11fProbeRequest pr;
+	uint32_t status, bytes, payload;
+	uint8_t *frame;
+	void *packet;
+	QDF_STATUS qdf_status;
+	tpPESession pesession;
+	uint8_t sessionid;
+	const uint8_t *p2pie = NULL;
+	uint8_t txflag = 0;
+	uint8_t sme_sessionid = 0;
+	bool is_vht_enabled = false;
+	uint8_t txPower;
+	uint16_t addn_ielen = 0;
+	bool extracted_ext_cap_flag = false;
+	tDot11fIEExtCap extracted_ext_cap;
+	QDF_STATUS sir_status;
+	const uint8_t *qcn_ie = NULL;
+
+	if (additional_ielen)
+		addn_ielen = *additional_ielen;
+
+	/* The probe req should not send 11ac capabilieties if band is 2.4GHz,
+	 * unless enableVhtFor24GHz is enabled in INI. So if enableVhtFor24GHz
+	 * is false and dot11mode is 11ac set it to 11n.
+	 */
+	if (channel <= SIR_11B_CHANNEL_END &&
+	    !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band &&
+	    (WNI_CFG_DOT11_MODE_11AC == dot11mode ||
+	     WNI_CFG_DOT11_MODE_11AC_ONLY == dot11mode))
+		dot11mode = WNI_CFG_DOT11_MODE_11N;
+	/*
+	 * session context may or may not be present, when probe request needs
+	 * to be sent out. Following cases exist:
+	 * --heartbeat failure:  session needed
+	 * --join req:           session needed
+	 * --foreground scan:    no session
+	 * --background scan:    no session
+	 * --sch_beacon_processing:  to get EDCA parameters:  session needed
+	 * If session context does not exist, some IEs will be populated from
+	 * CFGs, e.g. Supported and Extended rate set IEs
+	 */
+	pesession = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid);
+
+	if (pesession != NULL)
+		sme_sessionid = pesession->smeSessionId;
+
+	/* The scheme here is to fill out a 'tDot11fProbeRequest' structure */
+	/* and then hand it off to 'dot11f_pack_probe_request' (for */
+	/* serialization).  We start by zero-initializing the structure: */
+	qdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
+
+	/* & delegating to assorted helpers: */
+	populate_dot11f_ssid(mac_ctx, ssid, &pr.SSID);
+
+	if (addn_ielen && additional_ie)
+		p2pie = limGetP2pIEPtr(mac_ctx, additional_ie, addn_ielen);
+
+	/*
+	 * Don't include 11b rate if it is a P2P serach or probe request is
+	 * sent by P2P Client
+	 */
+	if ((WNI_CFG_DOT11_MODE_11B != dot11mode) && (p2pie != NULL) &&
+	    ((pesession != NULL) &&
+	      (QDF_P2P_CLIENT_MODE == pesession->pePersona))) {
+		/*
+		 * In the below API pass channel number > 14, do that it fills
+		 * only 11a rates in supported rates
+		 */
+		populate_dot11f_supp_rates(mac_ctx, 15, &pr.SuppRates,
+					   pesession);
+	} else {
+		populate_dot11f_supp_rates(mac_ctx, channel,
+					   &pr.SuppRates, pesession);
+
+		if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
+			populate_dot11f_ext_supp_rates1(mac_ctx, channel,
+							&pr.ExtSuppRates);
+		}
+	}
+
+	/*
+	 * Table 7-14 in IEEE Std. 802.11k-2008 says
+	 * DS params "can" be present in RRM is disabled and "is" present if
+	 * RRM is enabled. It should be ok even if we add it into probe req when
+	 * RRM is not enabled.
+	 */
+	populate_dot11f_ds_params(mac_ctx, &pr.DSParams, channel);
+	/* Call RRM module to get the tx power for management used. */
+	txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession);
+	populate_dot11f_wfatpc(mac_ctx, &pr.WFATPC, txPower, 0);
+
+
+	if (pesession != NULL) {
+		pesession->htCapability = IS_DOT11_MODE_HT(dot11mode);
+		/* Include HT Capability IE */
+		if (pesession->htCapability)
+			populate_dot11f_ht_caps(mac_ctx, pesession, &pr.HTCaps);
+	} else {                /* pesession == NULL */
+		if (IS_DOT11_MODE_HT(dot11mode))
+			populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps);
+	}
+
+	/*
+	 * Set channelbonding information as "disabled" when tunned to a
+	 * 2.4 GHz channel
+	 */
+	if (channel <= SIR_11B_CHANNEL_END) {
+		if (mac_ctx->roam.configParam.channelBondingMode24GHz
+		    == PHY_SINGLE_CHANNEL_CENTERED) {
+			pr.HTCaps.supportedChannelWidthSet =
+				eHT_CHANNEL_WIDTH_20MHZ;
+			pr.HTCaps.shortGI40MHz = 0;
+		} else {
+			pr.HTCaps.supportedChannelWidthSet =
+				eHT_CHANNEL_WIDTH_40MHZ;
+		}
+	}
+	if (pesession != NULL) {
+		pesession->vhtCapability = IS_DOT11_MODE_VHT(dot11mode);
+		/* Include VHT Capability IE */
+		if (pesession->vhtCapability) {
+			populate_dot11f_vht_caps(mac_ctx, pesession,
+						 &pr.VHTCaps);
+			is_vht_enabled = true;
+		}
+	} else {
+		if (IS_DOT11_MODE_VHT(dot11mode)) {
+			populate_dot11f_vht_caps(mac_ctx, pesession,
+						 &pr.VHTCaps);
+			is_vht_enabled = true;
+		}
+	}
+	if (pesession != NULL)
+		populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &pr.ExtCap,
+			pesession);
+
+	if (IS_DOT11_MODE_HE(dot11mode) && NULL != pesession)
+		lim_update_session_he_capable(mac_ctx, pesession);
+
+	pe_debug("Populate HE IEs");
+	populate_dot11f_he_caps(mac_ctx, pesession, &pr.he_cap);
+
+	if (addn_ielen && additional_ie) {
+		qdf_mem_zero((uint8_t *)&extracted_ext_cap,
+			sizeof(tDot11fIEExtCap));
+		sir_status = lim_strip_extcap_update_struct(mac_ctx,
+					additional_ie,
+					&addn_ielen,
+					&extracted_ext_cap);
+		if (QDF_STATUS_SUCCESS != sir_status) {
+			pe_debug("Unable to Stripoff ExtCap IE from Probe Req");
+		} else {
+			struct s_ext_cap *p_ext_cap =
+				(struct s_ext_cap *)
+					extracted_ext_cap.bytes;
+			if (p_ext_cap->interworking_service)
+				p_ext_cap->qos_map = 1;
+			extracted_ext_cap.num_bytes =
+				lim_compute_ext_cap_ie_length
+					(&extracted_ext_cap);
+			extracted_ext_cap_flag =
+				(extracted_ext_cap.num_bytes > 0);
+			if (additional_ielen)
+				*additional_ielen = addn_ielen;
+		}
+		qcn_ie = wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_QCN_OUI_TYPE,
+				SIR_MAC_QCN_OUI_TYPE_SIZE,
+				additional_ie, addn_ielen);
+	}
+	/* Add qcn_ie only if qcn ie is not present in additional_ie */
+	if (mac_ctx->mlme_cfg->sta.qcn_ie_support && !qcn_ie)
+		populate_dot11f_qcn_ie(&pr.QCN_IE);
+
+	/*
+	 * Extcap IE now support variable length, merge Extcap IE from addn_ie
+	 * may change the frame size. Therefore, MUST merge ExtCap IE before
+	 * dot11f get packed payload size.
+	 */
+	if (extracted_ext_cap_flag)
+		lim_merge_extcap_struct(&pr.ExtCap, &extracted_ext_cap, true);
+
+	/* That's it-- now we pack it.  First, how much space are we going to */
+	status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to calculate the packed size for a Probe Request (0x%08x)",
+			status);
+		/* We'll fall back on the worst case scenario: */
+		payload = sizeof(tDot11fProbeRequest);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while calculating the packed size for a Probe Request (0x%08x)",
+			status);
+	}
+
+	bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen;
+
+	/* Ok-- try to allocate some memory: */
+	qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
+				      (void **)&packet);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a Probe Request", bytes);
+		return QDF_STATUS_E_NOMEM;
+	}
+	/* Paranoia: */
+	qdf_mem_set(frame, bytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_PROBE_REQ, bssid, self_macaddr);
+
+	/* That done, pack the Probe Request: */
+	status = dot11f_pack_probe_request(mac_ctx, &pr, frame +
+					    sizeof(tSirMacMgmtHdr),
+					    payload, &payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to pack a Probe Request (0x%08x)", status);
+		cds_packet_free((void *)packet);
+		return QDF_STATUS_E_FAILURE;    /* allocated! */
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while packing a Probe Request (0x%08x)", status);
+	}
+	/* Append any AddIE if present. */
+	if (addn_ielen) {
+		qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+			     additional_ie, addn_ielen);
+		payload += addn_ielen;
+	}
+
+	/* If this probe request is sent during P2P Search State, then we need
+	 * to send it at OFDM rate.
+	 */
+	if ((BAND_5G == lim_get_rf_band(channel)) ||
+		/*
+		 * For unicast probe req mgmt from Join function we don't set
+		 * above variables. So we need to add one more check whether it
+		 * is pePersona is P2P_CLIENT or not
+		 */
+	    ((pesession != NULL) &&
+		(QDF_P2P_CLIENT_MODE == pesession->pePersona))) {
+		txflag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	qdf_status =
+		wma_tx_frame(mac_ctx, packet,
+			   (uint16_t) sizeof(tSirMacMgmtHdr) + payload,
+			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+			   lim_tx_complete, frame, txflag, sme_sessionid,
+			   0, RATEID_DEFAULT);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("could not send Probe Request frame!");
+		/* Pkt will be freed up by the callback */
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+} /* End lim_send_probe_req_mgmt_frame. */
+
+static QDF_STATUS lim_get_addn_ie_for_probe_resp(tpAniSirGlobal pMac,
+					     uint8_t *addIE, uint16_t *addnIELen,
+					     uint8_t probeReqP2pIe)
+{
+	/* If Probe request doesn't have P2P IE, then take out P2P IE
+	   from additional IE */
+	if (!probeReqP2pIe) {
+		uint8_t *tempbuf = NULL;
+		uint16_t tempLen = 0;
+		int left = *addnIELen;
+		uint8_t *ptr = addIE;
+		uint8_t elem_id, elem_len;
+
+		if (NULL == addIE) {
+			pe_err("NULL addIE pointer");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		tempbuf = qdf_mem_malloc(left);
+		if (!tempbuf)
+			return QDF_STATUS_E_NOMEM;
+
+		while (left >= 2) {
+			elem_id = ptr[0];
+			elem_len = ptr[1];
+			left -= 2;
+			if (elem_len > left) {
+				pe_err("Invalid IEs eid: %d elem_len: %d left: %d",
+					elem_id, elem_len, left);
+				qdf_mem_free(tempbuf);
+				return QDF_STATUS_E_FAILURE;
+			}
+			if (!((SIR_MAC_EID_VENDOR == elem_id) &&
+			      (memcmp
+				       (&ptr[2], SIR_MAC_P2P_OUI,
+				       SIR_MAC_P2P_OUI_SIZE) == 0))) {
+				qdf_mem_copy(tempbuf + tempLen, &ptr[0],
+					     elem_len + 2);
+				tempLen += (elem_len + 2);
+			}
+			left -= elem_len;
+			ptr += (elem_len + 2);
+		}
+		qdf_mem_copy(addIE, tempbuf, tempLen);
+		*addnIELen = tempLen;
+		qdf_mem_free(tempbuf);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_send_probe_rsp_mgmt_frame() - Send probe response
+ *
+ * @mac_ctx: Handle for mac context
+ * @peer_macaddr: Mac address of requesting peer
+ * @ssid: SSID for response
+ * @n_staid: Station ID, currently unused.
+ * @pe_session: PE session id
+ * @keepalive: Keep alive flag. Currently unused.
+ * @preq_p2pie: P2P IE in incoming probe request
+ *
+ * Builds and sends probe response frame to the requesting peer
+ *
+ * Return: void
+ */
+
+void
+lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
+			      tSirMacAddr peer_macaddr,
+			      tpAniSSID ssid,
+			      short n_staid,
+			      uint8_t keepalive,
+			      tpPESession pe_session, uint8_t preq_p2pie)
+{
+	tDot11fProbeResponse *frm;
+	QDF_STATUS sir_status;
+	uint32_t cfg, payload, bytes = 0, status;
+	tpSirMacMgmtHdr mac_hdr;
+	uint8_t *frame;
+	void *packet = NULL;
+	QDF_STATUS qdf_status;
+	uint32_t addn_ie_present = false;
+
+	uint16_t addn_ie_len = 0;
+	bool wps_ap = 0;
+	uint8_t tx_flag = 0;
+	uint8_t *add_ie = NULL;
+	const uint8_t *p2p_ie = NULL;
+	uint8_t noalen = 0;
+	uint8_t total_noalen = 0;
+	uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
+	uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
+	uint8_t sme_sessionid = 0;
+	bool is_vht_enabled = false;
+	tDot11fIEExtCap extracted_ext_cap = {0};
+	bool extracted_ext_cap_flag = false;
+
+	/* We don't answer requests in this case*/
+	if (ANI_DRIVER_TYPE(mac_ctx) == QDF_DRIVER_TYPE_MFG)
+		return;
+
+	if (NULL == pe_session)
+		return;
+
+	/*
+	 * In case when cac timer is running for this SAP session then
+	 * avoid sending probe rsp out. It is violation of dfs specification.
+	 */
+	if (((pe_session->pePersona == QDF_SAP_MODE) ||
+	    (pe_session->pePersona == QDF_P2P_GO_MODE)) &&
+	    (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			  FL("CAC timer is running, probe response dropped"));
+		return;
+	}
+	sme_sessionid = pe_session->smeSessionId;
+	frm = qdf_mem_malloc(sizeof(tDot11fProbeResponse));
+	if (!frm)
+		return;
+
+	/*
+	 * Fill out 'frm', after which we'll just hand the struct off to
+	 * 'dot11f_pack_probe_response'.
+	 */
+	qdf_mem_set((uint8_t *) frm, sizeof(tDot11fProbeResponse), 0);
+
+	/*
+	 * Timestamp to be updated by TFP, below.
+	 *
+	 * Beacon Interval:
+	 */
+	if (LIM_IS_AP_ROLE(pe_session)) {
+		frm->BeaconInterval.interval =
+			mac_ctx->sch.schObject.gSchBeaconInterval;
+	} else {
+		cfg = mac_ctx->mlme_cfg->sap_cfg.beacon_interval;
+		frm->BeaconInterval.interval = (uint16_t) cfg;
+	}
+
+	populate_dot11f_capabilities(mac_ctx, &frm->Capabilities, pe_session);
+	populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID);
+	populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
+		&frm->SuppRates, pe_session);
+
+	populate_dot11f_ds_params(mac_ctx, &frm->DSParams,
+		pe_session->currentOperChannel);
+	populate_dot11f_ibss_params(mac_ctx, &frm->IBSSParams, pe_session);
+
+	if (LIM_IS_AP_ROLE(pe_session)) {
+		if (pe_session->wps_state != SAP_WPS_DISABLED)
+			populate_dot11f_probe_res_wpsi_es(mac_ctx,
+				&frm->WscProbeRes,
+				pe_session);
+	} else {
+		wps_ap = mac_ctx->mlme_cfg->wps_params.enable_wps &
+					    WNI_CFG_WPS_ENABLE_AP;
+		if (wps_ap)
+			populate_dot11f_wsc_in_probe_res(mac_ctx,
+				&frm->WscProbeRes);
+
+		if (mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState ==
+		    eLIM_WSC_ENROLL_BEGIN) {
+			populate_dot11f_wsc_registrar_info_in_probe_res(mac_ctx,
+				&frm->WscProbeRes);
+			mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
+				eLIM_WSC_ENROLL_IN_PROGRESS;
+		}
+
+		if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
+		    eLIM_WSC_ENROLL_END) {
+			de_populate_dot11f_wsc_registrar_info_in_probe_res(
+				mac_ctx, &frm->WscProbeRes);
+			mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
+				eLIM_WSC_ENROLL_NOOP;
+		}
+	}
+
+	populate_dot11f_country(mac_ctx, &frm->Country, pe_session);
+	populate_dot11f_edca_param_set(mac_ctx, &frm->EDCAParamSet, pe_session);
+
+	if (pe_session->dot11mode != WNI_CFG_DOT11_MODE_11B)
+		populate_dot11f_erp_info(mac_ctx, &frm->ERPInfo, pe_session);
+
+	populate_dot11f_ext_supp_rates(mac_ctx,
+		POPULATE_DOT11F_RATES_OPERATIONAL,
+		&frm->ExtSuppRates, pe_session);
+
+	/* Populate HT IEs, when operating in 11n */
+	if (pe_session->htCapability) {
+		populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
+		populate_dot11f_ht_info(mac_ctx, &frm->HTInfo, pe_session);
+	}
+	if (pe_session->vhtCapability) {
+		pe_debug("Populate VHT IE in Probe Response");
+		populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
+		populate_dot11f_vht_operation(mac_ctx, pe_session,
+			&frm->VHTOperation);
+		/*
+		 * we do not support multi users yet.
+		 * populate_dot11f_vht_ext_bss_load( mac_ctx,
+		 *         &frm.VHTExtBssLoad );
+		 */
+		is_vht_enabled = true;
+	}
+
+	if (lim_is_session_he_capable(pe_session)) {
+		pe_debug("Populate HE IEs");
+		populate_dot11f_he_caps(mac_ctx, pe_session,
+					&frm->he_cap);
+		populate_dot11f_he_operation(mac_ctx, pe_session,
+					     &frm->he_op);
+	}
+
+	populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap,
+		pe_session);
+
+	if (pe_session->pLimStartBssReq) {
+		populate_dot11f_wpa(mac_ctx,
+			&(pe_session->pLimStartBssReq->rsnIE),
+			&frm->WPA);
+		populate_dot11f_rsn_opaque(mac_ctx,
+			&(pe_session->pLimStartBssReq->rsnIE),
+			&frm->RSNOpaque);
+	}
+
+	populate_dot11f_wmm(mac_ctx, &frm->WMMInfoAp, &frm->WMMParams,
+		&frm->WMMCaps, pe_session);
+
+#if defined(FEATURE_WLAN_WAPI)
+	if (pe_session->pLimStartBssReq)
+		populate_dot11f_wapi(mac_ctx,
+			&(pe_session->pLimStartBssReq->rsnIE),
+			&frm->WAPI);
+#endif /* defined(FEATURE_WLAN_WAPI) */
+
+	if (mac_ctx->lim.gpLimRemainOnChanReq)
+		bytes += (mac_ctx->lim.gpLimRemainOnChanReq->length -
+			 sizeof(tSirRemainOnChnReq));
+	else
+		/*
+		 * Only use CFG for non-listen mode. This CFG is not working for
+		 * concurrency. In listening mode, probe rsp IEs is passed in
+		 * the message from SME to PE.
+		 */
+		addn_ie_present =
+			(pe_session->addIeParams.probeRespDataLen != 0);
+
+	if (addn_ie_present) {
+
+		add_ie = qdf_mem_malloc(
+				pe_session->addIeParams.probeRespDataLen);
+		if (!add_ie)
+			goto err_ret;
+
+		qdf_mem_copy(add_ie,
+			     pe_session->addIeParams.probeRespData_buff,
+			     pe_session->addIeParams.probeRespDataLen);
+		addn_ie_len = pe_session->addIeParams.probeRespDataLen;
+
+		if (QDF_STATUS_SUCCESS != lim_get_addn_ie_for_probe_resp(mac_ctx,
+					add_ie, &addn_ie_len, preq_p2pie)) {
+			pe_err("Unable to get addn_ie");
+			goto err_ret;
+		}
+
+		sir_status = lim_strip_extcap_update_struct(mac_ctx,
+					add_ie, &addn_ie_len,
+					&extracted_ext_cap);
+		if (QDF_STATUS_SUCCESS != sir_status) {
+			pe_debug("Unable to strip off ExtCap IE");
+		} else {
+			extracted_ext_cap_flag = true;
+		}
+
+		bytes = bytes + addn_ie_len;
+
+		if (preq_p2pie)
+			p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0],
+					addn_ie_len);
+
+		if (p2p_ie != NULL) {
+			/* get NoA attribute stream P2P IE */
+			noalen = lim_get_noa_attr_stream(mac_ctx,
+					noa_stream, pe_session);
+			if (noalen != 0) {
+				total_noalen =
+					lim_build_p2p_ie(mac_ctx, &noa_ie[0],
+						&noa_stream[0], noalen);
+				bytes = bytes + total_noalen;
+			}
+		}
+	}
+
+	/*
+	 * Extcap IE now support variable length, merge Extcap IE from addn_ie
+	 * may change the frame size. Therefore, MUST merge ExtCap IE before
+	 * dot11f get packed payload size.
+	 */
+	if (extracted_ext_cap_flag)
+		lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap,
+					true);
+
+	status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Probe Response size error (0x%08x)",
+			status);
+		/* We'll fall back on the worst case scenario: */
+		payload = sizeof(tDot11fProbeResponse);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("Probe Response size warning (0x%08x)",
+			status);
+	}
+
+	bytes += payload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
+				      (void **)&packet);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Probe Response allocation failed");
+		goto err_ret;
+	}
+	/* Paranoia: */
+	qdf_mem_set(frame, bytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_PROBE_RSP, peer_macaddr,
+		pe_session->selfMacAddr);
+
+	mac_hdr = (tpSirMacMgmtHdr) frame;
+
+	sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
+
+	/* That done, pack the Probe Response: */
+	status =
+		dot11f_pack_probe_response(mac_ctx, frm,
+			frame + sizeof(tSirMacMgmtHdr),
+			payload, &payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Probe Response pack failure (0x%08x)",
+			status);
+			goto err_ret;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("Probe Response pack warning (0x%08x)", status);
+	}
+
+	pe_debug("Sending Probe Response frame to");
+	lim_print_mac_addr(mac_ctx, peer_macaddr, LOGD);
+
+	if (mac_ctx->lim.gpLimRemainOnChanReq)
+		qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+			     mac_ctx->lim.gpLimRemainOnChanReq->probeRspIe,
+			     (mac_ctx->lim.gpLimRemainOnChanReq->length -
+			      sizeof(tSirRemainOnChnReq)));
+
+	if (addn_ie_present)
+		qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+			     &add_ie[0], addn_ie_len);
+
+	if (noalen != 0) {
+		if (total_noalen >
+		    (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) {
+			pe_err("Not able to insert NoA, total len=%d",
+				total_noalen);
+			goto err_ret;
+		} else {
+			qdf_mem_copy(&frame[bytes - (total_noalen)],
+				     &noa_ie[0], total_noalen);
+		}
+	}
+
+	if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel))
+	    || (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
+	    (pe_session->pePersona == QDF_P2P_GO_MODE)
+	    )
+		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+	/* Queue Probe Response frame in high priority WQ */
+	qdf_status = wma_tx_frame((tHalHandle) mac_ctx, packet,
+				(uint16_t) bytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, frame, tx_flag,
+				sme_sessionid, 0, RATEID_DEFAULT);
+
+	/* Pkt will be freed up by the callback */
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		pe_err("Could not send Probe Response");
+
+	if (add_ie != NULL)
+		qdf_mem_free(add_ie);
+
+	qdf_mem_free(frm);
+	return;
+
+err_ret:
+	if (add_ie != NULL)
+		qdf_mem_free(add_ie);
+	if (frm != NULL)
+		qdf_mem_free(frm);
+	if (packet != NULL)
+		cds_packet_free((void *)packet);
+	return;
+
+} /* End lim_send_probe_rsp_mgmt_frame. */
+
+void
+lim_send_addts_req_action_frame(tpAniSirGlobal pMac,
+				tSirMacAddr peerMacAddr,
+				tSirAddtsReqInfo *pAddTS, tpPESession psessionEntry)
+{
+	uint16_t i;
+	uint8_t *pFrame;
+	tDot11fAddTSRequest AddTSReq;
+	tDot11fWMMAddTSRequest WMMAddTSReq;
+	uint32_t nPayload, nBytes, nStatus;
+	tpSirMacMgmtHdr pMacHdr;
+	void *pPacket;
+#ifdef FEATURE_WLAN_ESE
+	uint32_t phyMode;
+#endif
+	QDF_STATUS qdf_status;
+	uint8_t txFlag = 0;
+	uint8_t smeSessionId = 0;
+
+	if (NULL == psessionEntry) {
+		return;
+	}
+
+	smeSessionId = psessionEntry->smeSessionId;
+
+	if (!pAddTS->wmeTspecPresent) {
+		qdf_mem_set((uint8_t *) &AddTSReq, sizeof(AddTSReq), 0);
+
+		AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
+		AddTSReq.DialogToken.token = pAddTS->dialogToken;
+		AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT;
+		if (pAddTS->lleTspecPresent) {
+			populate_dot11f_tspec(&pAddTS->tspec, &AddTSReq.TSPEC);
+		} else {
+			populate_dot11f_wmmtspec(&pAddTS->tspec,
+						 &AddTSReq.WMMTSPEC);
+		}
+
+		if (pAddTS->lleTspecPresent) {
+			AddTSReq.num_WMMTCLAS = 0;
+			AddTSReq.num_TCLAS = pAddTS->numTclas;
+			for (i = 0; i < pAddTS->numTclas; ++i) {
+				populate_dot11f_tclas(pMac, &pAddTS->tclasInfo[i],
+						      &AddTSReq.TCLAS[i]);
+			}
+		} else {
+			AddTSReq.num_TCLAS = 0;
+			AddTSReq.num_WMMTCLAS = pAddTS->numTclas;
+			for (i = 0; i < pAddTS->numTclas; ++i) {
+				populate_dot11f_wmmtclas(pMac,
+							 &pAddTS->tclasInfo[i],
+							 &AddTSReq.WMMTCLAS[i]);
+			}
+		}
+
+		if (pAddTS->tclasProcPresent) {
+			if (pAddTS->lleTspecPresent) {
+				AddTSReq.TCLASSPROC.processing =
+					pAddTS->tclasProc;
+				AddTSReq.TCLASSPROC.present = 1;
+			} else {
+				AddTSReq.WMMTCLASPROC.version = 1;
+				AddTSReq.WMMTCLASPROC.processing =
+					pAddTS->tclasProc;
+				AddTSReq.WMMTCLASPROC.present = 1;
+			}
+		}
+
+		nStatus =
+			dot11f_get_packed_add_ts_request_size(pMac, &AddTSReq, &nPayload);
+		if (DOT11F_FAILED(nStatus)) {
+			pe_err("Failed to calculate the packed size for an Add TS Request (0x%08x)",
+				nStatus);
+			/* We'll fall back on the worst case scenario: */
+			nPayload = sizeof(tDot11fAddTSRequest);
+		} else if (DOT11F_WARNED(nStatus)) {
+			pe_warn("There were warnings while calculating the packed size for an Add TS Request (0x%08x)",
+				nStatus);
+		}
+	} else {
+		qdf_mem_set((uint8_t *) &WMMAddTSReq, sizeof(WMMAddTSReq), 0);
+
+		WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
+		WMMAddTSReq.DialogToken.token = pAddTS->dialogToken;
+		WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME;
+
+		/* WMM spec 2.2.10 - status code is only filled in for ADDTS response */
+		WMMAddTSReq.StatusCode.statusCode = 0;
+
+		populate_dot11f_wmmtspec(&pAddTS->tspec, &WMMAddTSReq.WMMTSPEC);
+#ifdef FEATURE_WLAN_ESE
+		lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+		if (phyMode == WNI_CFG_PHY_MODE_11G
+		    || phyMode == WNI_CFG_PHY_MODE_11A) {
+			pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
+		} else {
+			pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
+		}
+		populate_dot11_tsrsie(pMac, &pAddTS->tsrsIE,
+				      &WMMAddTSReq.ESETrafStrmRateSet,
+				      sizeof(uint8_t));
+#endif
+		/* fillWmeTspecIE */
+
+		nStatus =
+			dot11f_get_packed_wmm_add_ts_request_size(pMac, &WMMAddTSReq,
+								  &nPayload);
+		if (DOT11F_FAILED(nStatus)) {
+			pe_err("Failed to calculate the packed size for a WMM Add TS Request (0x%08x)",
+				nStatus);
+			/* We'll fall back on the worst case scenario: */
+			nPayload = sizeof(tDot11fAddTSRequest);
+		} else if (DOT11F_WARNED(nStatus)) {
+			pe_warn("There were warnings while calculating the packed size for a WMM Add TS Request (0x%08x)",
+				nStatus);
+		}
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				      (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for an Add TS Request",
+			nBytes);
+		return;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peerMacAddr, psessionEntry->selfMacAddr);
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+	lim_set_protected_bit(pMac, psessionEntry, peerMacAddr, pMacHdr);
+
+	/* That done, pack the struct: */
+	if (!pAddTS->wmeTspecPresent) {
+		nStatus = dot11f_pack_add_ts_request(pMac, &AddTSReq,
+						     pFrame +
+						     sizeof(tSirMacMgmtHdr),
+						     nPayload, &nPayload);
+		if (DOT11F_FAILED(nStatus)) {
+			pe_err("Failed to pack an Add TS Request "
+				"(0x%08x)", nStatus);
+			cds_packet_free((void *)pPacket);
+			return; /* allocated! */
+		} else if (DOT11F_WARNED(nStatus)) {
+			pe_warn("There were warnings while packing an Add TS Request (0x%08x)",
+				nStatus);
+		}
+	} else {
+		nStatus = dot11f_pack_wmm_add_ts_request(pMac, &WMMAddTSReq,
+							 pFrame +
+							 sizeof(tSirMacMgmtHdr),
+							 nPayload, &nPayload);
+		if (DOT11F_FAILED(nStatus)) {
+			pe_err("Failed to pack a WMM Add TS Request (0x%08x)",
+				nStatus);
+			cds_packet_free((void *)pPacket);
+			return; /* allocated! */
+		} else if (DOT11F_WARNED(nStatus)) {
+			pe_warn("There were warnings while packing a WMM Add TS Request (0x%08x)",
+				nStatus);
+		}
+	}
+
+	pe_debug("Sending an Add TS Request frame to");
+	lim_print_mac_addr(pMac, peerMacAddr, LOGD);
+
+	if ((BAND_5G ==
+	     lim_get_rf_band(psessionEntry->currentOperChannel))
+	    || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
+	    || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
+	    ) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 psessionEntry->peSessionId, pMacHdr->fc.subType));
+	lim_diag_mgmt_tx_event_report(pMac, pMacHdr,
+				      psessionEntry, QDF_STATUS_SUCCESS,
+				      QDF_STATUS_SUCCESS);
+
+	/* Queue Addts Response frame in high priority WQ */
+	qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, pFrame, txFlag,
+				smeSessionId, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			 psessionEntry->peSessionId, qdf_status));
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		pe_err("Could not send an Add TS Request (%X",
+			qdf_status);
+} /* End lim_send_addts_req_action_frame. */
+
+/**
+ * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
+ * @mac_ctx: Handle for mac context
+ * @status_code: Status code for assoc response frame
+ * @aid: Association ID
+ * @peer_addr: Mac address of requesting peer
+ * @subtype: Assoc/Reassoc
+ * @sta: Pointer to station node
+ * @pe_session: PE session id.
+ *
+ * Builds and sends association response frame to the requesting peer.
+ *
+ * Return: void
+ */
+
+void
+lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
+	uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
+	uint8_t subtype, tpDphHashNode sta, tpPESession pe_session)
+{
+	static tDot11fAssocResponse frm;
+	uint8_t *frame;
+	tpSirMacMgmtHdr mac_hdr;
+	QDF_STATUS sir_status;
+	uint8_t lle_mode = 0, addts;
+	tHalBitVal qos_mode, wme_mode;
+	uint32_t payload, bytes = 0, status;
+	void *packet;
+	QDF_STATUS qdf_status;
+	tUpdateBeaconParams beacon_params;
+	uint8_t tx_flag = 0;
+	uint32_t addn_ie_len = 0;
+	uint8_t add_ie[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN];
+	tpSirAssocReq assoc_req = NULL;
+	uint8_t sme_session = 0;
+	bool is_vht = false;
+	uint16_t stripoff_len = 0;
+	tDot11fIEExtCap extracted_ext_cap;
+	bool extracted_flag = false;
+#ifdef WLAN_FEATURE_11W
+	uint8_t retry_int;
+	uint16_t max_retries;
+#endif
+
+	if (NULL == pe_session) {
+		pe_err("pe_session is NULL");
+		return;
+	}
+
+	sme_session = pe_session->smeSessionId;
+
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+	limGetQosMode(pe_session, &qos_mode);
+	limGetWmeMode(pe_session, &wme_mode);
+
+	/*
+	 * An Add TS IE is added only if the AP supports it and
+	 * the requesting STA sent a traffic spec.
+	 */
+	addts = (qos_mode && sta && sta->qos.addtsPresent) ? 1 : 0;
+
+	frm.Status.status = status_code;
+
+	frm.AID.associd = aid | LIM_AID_MASK;
+
+	if (NULL == sta) {
+		populate_dot11f_supp_rates(mac_ctx,
+			POPULATE_DOT11F_RATES_OPERATIONAL,
+			&frm.SuppRates, pe_session);
+		populate_dot11f_ext_supp_rates(mac_ctx,
+			POPULATE_DOT11F_RATES_OPERATIONAL,
+			&frm.ExtSuppRates, pe_session);
+	} else {
+		populate_dot11f_assoc_rsp_rates(mac_ctx, &frm.SuppRates,
+			&frm.ExtSuppRates,
+			sta->supportedRates.llbRates,
+			sta->supportedRates.llaRates);
+	}
+
+	if (LIM_IS_AP_ROLE(pe_session) && sta != NULL &&
+	    QDF_STATUS_SUCCESS == status_code) {
+		assoc_req = (tpSirAssocReq)
+			pe_session->parsedAssocReq[sta->assocId];
+		/*
+		 * populate P2P IE in AssocRsp when assocReq from the peer
+		 * includes P2P IE
+		 */
+		if (assoc_req != NULL && assoc_req->addIEPresent)
+			populate_dot11_assoc_res_p2p_ie(mac_ctx,
+				&frm.P2PAssocRes,
+				assoc_req);
+	}
+
+	if (NULL != sta) {
+		if (eHAL_SET == qos_mode) {
+			if (sta->lleEnabled) {
+				lle_mode = 1;
+				populate_dot11f_edca_param_set(mac_ctx,
+					&frm.EDCAParamSet, pe_session);
+			}
+		}
+
+		if ((!lle_mode) && (eHAL_SET == wme_mode) && sta->wmeEnabled) {
+			populate_dot11f_wmm_params(mac_ctx, &frm.WMMParams,
+				pe_session);
+
+			if (sta->wsmEnabled)
+				populate_dot11f_wmm_caps(&frm.WMMCaps);
+		}
+
+		if (sta->mlmStaContext.htCapability &&
+		    pe_session->htCapability) {
+			pe_debug("Populate HT IEs in Assoc Response");
+			populate_dot11f_ht_caps(mac_ctx, pe_session,
+				&frm.HTCaps);
+			/*
+			 * Check the STA capability and
+			 * update the HTCaps accordingly
+			 */
+			frm.HTCaps.supportedChannelWidthSet = (
+				sta->htSupportedChannelWidthSet <
+				     pe_session->htSupportedChannelWidthSet) ?
+				      sta->htSupportedChannelWidthSet :
+				       pe_session->htSupportedChannelWidthSet;
+			if (!frm.HTCaps.supportedChannelWidthSet)
+				frm.HTCaps.shortGI40MHz = 0;
+
+			populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
+				pe_session);
+		}
+		pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x",
+			frm.HTCaps.supportedChannelWidthSet,
+			frm.HTCaps.mimoPowerSave,
+			frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz,
+			frm.HTCaps.shortGI40MHz,
+			frm.HTCaps.dsssCckMode40MHz,
+			frm.HTCaps.maxRxAMPDUFactor);
+
+		if (sta->mlmStaContext.vhtCapability &&
+		    pe_session->vhtCapability) {
+			pe_debug("Populate VHT IEs in Assoc Response");
+			populate_dot11f_vht_caps(mac_ctx, pe_session,
+				&frm.VHTCaps);
+			populate_dot11f_vht_operation(mac_ctx, pe_session,
+					&frm.VHTOperation);
+			is_vht = true;
+		}
+
+		if (pe_session->vhtCapability &&
+		    pe_session->vendor_vht_sap &&
+		    (assoc_req != NULL) &&
+		    assoc_req->vendor_vht_ie.VHTCaps.present) {
+			pe_debug("Populate Vendor VHT IEs in Assoc Rsponse");
+			frm.vendor_vht_ie.present = 1;
+			frm.vendor_vht_ie.sub_type =
+				pe_session->vendor_specific_vht_ie_sub_type;
+			frm.vendor_vht_ie.VHTCaps.present = 1;
+			populate_dot11f_vht_caps(mac_ctx, pe_session,
+				&frm.vendor_vht_ie.VHTCaps);
+			populate_dot11f_vht_operation(mac_ctx, pe_session,
+					&frm.vendor_vht_ie.VHTOperation);
+			is_vht = true;
+		}
+		populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
+			pe_session);
+
+		if (lim_is_sta_he_capable(sta) &&
+		    lim_is_session_he_capable(pe_session)) {
+			pe_debug("Populate HE IEs");
+			populate_dot11f_he_caps(mac_ctx, pe_session,
+						&frm.he_cap);
+			populate_dot11f_he_operation(mac_ctx, pe_session,
+						     &frm.he_op);
+		}
+#ifdef WLAN_FEATURE_11W
+		if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
+			max_retries =
+			mac_ctx->mlme_cfg->gen.pmf_sa_query_max_retries;
+			retry_int =
+			mac_ctx->mlme_cfg->gen.pmf_sa_query_retry_interval;
+			populate_dot11f_timeout_interval(mac_ctx,
+							 &frm.TimeoutInterval,
+						SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
+						(max_retries -
+						sta->pmfSaQueryRetryCount)
+						* retry_int);
+		}
+#endif
+
+		if (LIM_IS_AP_ROLE(pe_session)  && sta->non_ecsa_capable)
+			pe_session->lim_non_ecsa_cap_num++;
+	}
+
+	qdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);
+
+	if (LIM_IS_AP_ROLE(pe_session) &&
+	    (pe_session->gLimProtectionControl !=
+	     MLME_FORCE_POLICY_PROTECTION_DISABLE))
+		lim_decide_ap_protection(mac_ctx, peer_addr, &beacon_params,
+					 pe_session);
+
+	lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
+		pe_session);
+	lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
+		pe_session);
+
+	/*
+	 * Populate Do11capabilities after updating session with
+	 * Assos req details
+	 */
+	populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);
+
+	beacon_params.bssIdx = pe_session->bssIdx;
+
+	/* Send message to HAL about beacon parameter change. */
+	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
+	    && beacon_params.paramChangeBitmap) {
+		sch_set_fixed_beacon_fields(mac_ctx, pe_session);
+		lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
+	}
+
+	lim_obss_send_detection_cfg(mac_ctx, pe_session, false);
+
+	if (assoc_req != NULL) {
+		addn_ie_len = pe_session->addIeParams.assocRespDataLen;
+
+		/* Nonzero length indicates Assoc rsp IE available */
+		if (addn_ie_len > 0 &&
+		    addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN &&
+		    (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
+			qdf_mem_copy(add_ie,
+				pe_session->addIeParams.assocRespData_buff,
+				pe_session->addIeParams.assocRespDataLen);
+
+			qdf_mem_set((uint8_t *) &extracted_ext_cap,
+				    sizeof(extracted_ext_cap), 0);
+
+			stripoff_len = addn_ie_len;
+			sir_status =
+				lim_strip_extcap_update_struct
+					(mac_ctx, &add_ie[0], &stripoff_len,
+					&extracted_ext_cap);
+			if (QDF_STATUS_SUCCESS != sir_status) {
+				pe_debug("strip off extcap IE failed");
+			} else {
+				addn_ie_len = stripoff_len;
+				extracted_flag = true;
+			}
+			bytes = bytes + addn_ie_len;
+		}
+		pe_debug("addn_ie_len: %d for Assoc Resp: %d",
+			addn_ie_len, assoc_req->addIEPresent);
+	}
+
+	/*
+	 * Extcap IE now support variable length, merge Extcap IE from addn_ie
+	 * may change the frame size. Therefore, MUST merge ExtCap IE before
+	 * dot11f get packed payload size.
+	 */
+	if (extracted_flag)
+		lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap,
+					true);
+
+	/* Allocate a buffer for this frame: */
+	status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("get Association Response size failure (0x%08x)",
+			status);
+		return;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("get Association Response size warning (0x%08x)",
+			status);
+	}
+
+	bytes += sizeof(tSirMacMgmtHdr) + payload;
+
+	qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
+				      (void **)&packet);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("cds_packet_alloc failed");
+		return;
+	}
+	/* Paranoia: */
+	qdf_mem_set(frame, bytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+		(LIM_ASSOC == subtype) ?
+			SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
+			peer_addr,
+			pe_session->selfMacAddr);
+	mac_hdr = (tpSirMacMgmtHdr) frame;
+
+	sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
+
+	status = dot11f_pack_assoc_response(mac_ctx, &frm,
+					     frame + sizeof(tSirMacMgmtHdr),
+					     payload, &payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Association Response pack failure(0x%08x)",
+			status);
+		cds_packet_free((void *)packet);
+		return;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("Association Response pack warning (0x%08x)",
+			status);
+	}
+
+	if (subtype == LIM_ASSOC)
+		pe_debug("*** Sending Assoc Resp status %d aid %d to",
+			status_code, aid);
+	else
+		pe_debug("*** Sending ReAssoc Resp status %d aid %d to",
+			status_code, aid);
+
+	lim_print_mac_addr(mac_ctx, mac_hdr->da, LOGD);
+
+	if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
+		qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+			     &add_ie[0], addn_ie_len);
+
+	if ((BAND_5G ==
+		lim_get_rf_band(pe_session->currentOperChannel)) ||
+			(pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
+			(pe_session->pePersona == QDF_P2P_GO_MODE))
+		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 pe_session->peSessionId, mac_hdr->fc.subType));
+	lim_diag_mgmt_tx_event_report(mac_ctx, mac_hdr,
+				      pe_session, QDF_STATUS_SUCCESS, status_code);
+	/* Queue Association Response frame in high priority WQ */
+	qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, frame, tx_flag,
+				sme_session, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			 pe_session->peSessionId, qdf_status));
+
+	/* Pkt will be freed up by the callback */
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		pe_err("Could not Send Re/AssocRsp, retCode=%X",
+			qdf_status);
+
+	/*
+	 * update the ANI peer station count.
+	 * FIXME_PROTECTION : take care of different type of station
+	 * counter inside this function.
+	 */
+	lim_util_count_sta_add(mac_ctx, sta, pe_session);
+
+}
+
+void
+lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
+				tSirMacAddr peer,
+				uint8_t wmmTspecPresent,
+				tSirMacTSInfo *pTsinfo,
+				tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
+{
+	uint8_t *pFrame;
+	tpSirMacMgmtHdr pMacHdr;
+	tDot11fDelTS DelTS;
+	tDot11fWMMDelTS WMMDelTS;
+	uint32_t nBytes, nPayload, nStatus;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint8_t txFlag = 0;
+	uint8_t smeSessionId = 0;
+
+	if (NULL == psessionEntry) {
+		return;
+	}
+
+	smeSessionId = psessionEntry->smeSessionId;
+
+	if (!wmmTspecPresent) {
+		qdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);
+
+		DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
+		DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
+		populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);
+
+		nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
+		if (DOT11F_FAILED(nStatus)) {
+			pe_err("Failed to calculate the packed size for a Del TS (0x%08x)", nStatus);
+			/* We'll fall back on the worst case scenario: */
+			nPayload = sizeof(tDot11fDelTS);
+		} else if (DOT11F_WARNED(nStatus)) {
+			pe_warn("There were warnings while calculating the packed size for a Del TS (0x%08x)",
+				nStatus);
+		}
+	} else {
+		qdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);
+
+		WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
+		WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
+		WMMDelTS.DialogToken.token = 0;
+		WMMDelTS.StatusCode.statusCode = 0;
+		populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
+		nStatus =
+			dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
+		if (DOT11F_FAILED(nStatus)) {
+			pe_err("Failed to calculate the packed size for a WMM Del TS (0x%08x)", nStatus);
+			/* We'll fall back on the worst case scenario: */
+			nPayload = sizeof(tDot11fDelTS);
+		} else if (DOT11F_WARNED(nStatus)) {
+			pe_warn("There were warnings while calculating the packed size for a WMM Del TS (0x%08x)",
+				nStatus);
+		}
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status =
+		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				 (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for an Add TS Response",
+			nBytes);
+		return;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	/* That done, pack the struct: */
+	if (!wmmTspecPresent) {
+		nStatus = dot11f_pack_del_ts(pMac, &DelTS,
+					     pFrame + sizeof(tSirMacMgmtHdr),
+					     nPayload, &nPayload);
+		if (DOT11F_FAILED(nStatus)) {
+			pe_err("Failed to pack a Del TS frame (0x%08x)",
+				nStatus);
+			cds_packet_free((void *)pPacket);
+			return; /* allocated! */
+		} else if (DOT11F_WARNED(nStatus)) {
+			pe_warn("There were warnings while packing a Del TS frame (0x%08x)",
+				nStatus);
+		}
+	} else {
+		nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
+						 pFrame + sizeof(tSirMacMgmtHdr),
+						 nPayload, &nPayload);
+		if (DOT11F_FAILED(nStatus)) {
+			pe_err("Failed to pack a WMM Del TS frame (0x%08x)",
+				nStatus);
+			cds_packet_free((void *)pPacket);
+			return; /* allocated! */
+		} else if (DOT11F_WARNED(nStatus)) {
+			pe_warn("There were warnings while packing a WMM Del TS frame (0x%08x)",
+				nStatus);
+		}
+	}
+
+	pe_debug("Sending DELTS REQ (size %d) to ", nBytes);
+	lim_print_mac_addr(pMac, pMacHdr->da, LOGD);
+
+	if ((BAND_5G ==
+	     lim_get_rf_band(psessionEntry->currentOperChannel))
+	    || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
+	    || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
+	    ) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 psessionEntry->peSessionId, pMacHdr->fc.subType));
+	lim_diag_mgmt_tx_event_report(pMac, pMacHdr,
+				      psessionEntry, QDF_STATUS_SUCCESS,
+				      QDF_STATUS_SUCCESS);
+	qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, pFrame, txFlag,
+				smeSessionId, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			 psessionEntry->peSessionId, qdf_status));
+	/* Pkt will be freed up by the callback */
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		pe_err("Failed to send Del TS (%X)!", qdf_status);
+
+} /* End lim_send_delts_req_action_frame. */
+
+/**
+ * lim_assoc_tx_complete_cnf()- Confirmation for assoc sent over the air
+ * @context: pointer to global mac
+ * @buf: buffer
+ * @tx_complete : Sent status
+ * @params; tx completion params
+ *
+ * Return: This returns QDF_STATUS
+ */
+
+static QDF_STATUS lim_assoc_tx_complete_cnf(void *context,
+					   qdf_nbuf_t buf,
+					   uint32_t tx_complete,
+					   void *params)
+{
+	uint16_t assoc_ack_status;
+	uint16_t reason_code;
+	tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
+
+	pe_debug("tx_complete= %d", tx_complete);
+	if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) {
+		assoc_ack_status = ACKED;
+		reason_code = QDF_STATUS_SUCCESS;
+	} else {
+		assoc_ack_status = NOT_ACKED;
+		reason_code = QDF_STATUS_E_FAILURE;
+	}
+	if (buf)
+		qdf_nbuf_free(buf);
+
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_ACK_EVENT,
+			NULL, assoc_ack_status, reason_code);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_send_assoc_req_mgmt_frame() - Send association request
+ * @mac_ctx: Handle to MAC context
+ * @mlm_assoc_req: Association request information
+ * @pe_session: PE session information
+ *
+ * Builds and transmits association request frame to AP.
+ *
+ * Return: Void
+ */
+
+void
+lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
+			      tLimMlmAssocReq *mlm_assoc_req,
+			      tpPESession pe_session)
+{
+	int ret;
+	tDot11fAssocRequest *frm;
+	uint16_t caps;
+	uint8_t *frame;
+	QDF_STATUS sir_status;
+	tLimMlmAssocCnf assoc_cnf;
+	uint32_t bytes = 0, payload, status;
+	uint8_t qos_enabled, wme_enabled, wsm_enabled;
+	void *packet;
+	QDF_STATUS qdf_status;
+	uint16_t add_ie_len;
+	uint8_t *add_ie;
+	const uint8_t *wps_ie = NULL;
+	uint8_t power_caps = false;
+	uint8_t tx_flag = 0;
+	uint8_t sme_sessionid = 0;
+	bool vht_enabled = false;
+	tDot11fIEExtCap extr_ext_cap;
+	bool extr_ext_flag = true;
+	tpSirMacMgmtHdr mac_hdr;
+	uint32_t ie_offset = 0;
+	uint8_t *p_ext_cap = NULL;
+	tDot11fIEExtCap bcn_ext_cap;
+	uint8_t *bcn_ie = NULL;
+	uint32_t bcn_ie_len = 0;
+	uint32_t aes_block_size_len = 0;
+	enum rateid min_rid = RATEID_DEFAULT;
+	uint8_t *mbo_ie = NULL;
+	uint8_t mbo_ie_len = 0;
+
+	if (NULL == pe_session) {
+		pe_err("pe_session is NULL");
+		qdf_mem_free(mlm_assoc_req);
+		return;
+	}
+
+	sme_sessionid = pe_session->smeSessionId;
+
+	/* 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;
+	add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;
+
+	frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
+	if (!frm) {
+		qdf_mem_free(mlm_assoc_req);
+		return;
+	}
+	qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
+
+	if (add_ie_len && pe_session->is_ext_caps_present) {
+		qdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
+			    0);
+		sir_status = lim_strip_extcap_update_struct(mac_ctx,
+					add_ie, &add_ie_len, &extr_ext_cap);
+		if (QDF_STATUS_SUCCESS != sir_status) {
+			extr_ext_flag = false;
+			pe_debug("Unable to Stripoff ExtCap IE from Assoc Req");
+		} else {
+			struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
+							extr_ext_cap.bytes;
+
+			if (p_ext_cap->interworking_service)
+				p_ext_cap->qos_map = 1;
+			extr_ext_cap.num_bytes =
+				lim_compute_ext_cap_ie_length(&extr_ext_cap);
+			extr_ext_flag = (extr_ext_cap.num_bytes > 0);
+		}
+	} else {
+		pe_debug("No addn IE or peer doesn't support addnIE for Assoc Req");
+		extr_ext_flag = false;
+	}
+
+	caps = mlm_assoc_req->capabilityInfo;
+#if defined(FEATURE_WLAN_WAPI)
+	/*
+	 * According to WAPI standard:
+	 * 7.3.1.4 Capability Information field
+	 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
+	 * in transmitted Association or Reassociation management frames.
+	 * APs ignore the Privacy subfield within received Association and
+	 * Reassociation management frames.
+	 */
+	if (pe_session->encryptType == eSIR_ED_WPI)
+		((tSirMacCapabilityInfo *) &caps)->privacy = 0;
+#endif
+	swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
+
+	frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
+	populate_dot11f_ssid2(mac_ctx, &frm->SSID);
+	populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
+		&frm->SuppRates, pe_session);
+
+	qos_enabled = (pe_session->limQosEnabled) &&
+		      SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);
+
+	wme_enabled = (pe_session->limWmeEnabled) &&
+		      LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);
+
+	/* We prefer .11e asociations: */
+	if (qos_enabled)
+		wme_enabled = false;
+
+	wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
+		      LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
+
+	if (pe_session->lim11hEnable &&
+	    pe_session->pLimJoinReq->spectrumMgtIndicator == true) {
+		power_caps = true;
+
+		populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
+			LIM_ASSOC, pe_session);
+		populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
+			LIM_ASSOC, pe_session);
+
+	}
+	if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
+	    SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
+		if (power_caps == false) {
+			power_caps = true;
+			populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
+				LIM_ASSOC, pe_session);
+		}
+	}
+	if (qos_enabled)
+		populate_dot11f_qos_caps_station(mac_ctx, pe_session,
+						&frm->QOSCapsStation);
+
+	populate_dot11f_ext_supp_rates(mac_ctx,
+		POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
+		pe_session);
+
+	if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
+	    SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
+		populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
+			pe_session);
+
+	/*
+	 * The join request *should* contain zero or one of the WPA and RSN
+	 * IEs.  The payload send along with the request is a
+	 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
+	 *     typedef struct sSirRSNie
+	 *     {
+	 *         uint16_t       length;
+	 *         uint8_t        rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
+	 *     } tSirRSNie, *tpSirRSNie;
+	 * So, we should be able to make the following two calls harmlessly,
+	 * since they do nothing if they don't find the given IE in the
+	 * bytestream with which they're provided.
+	 * The net effect of this will be to faithfully transmit whatever
+	 * security IE is in the join request.
+	 * However, if we're associating for the purpose of WPS
+	 * enrollment, and we've been configured to indicate that by
+	 * eliding the WPA or RSN IE, we just skip this:
+	 */
+	if (add_ie_len && add_ie)
+		wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
+
+	if (NULL == wps_ie) {
+		populate_dot11f_rsn_opaque(mac_ctx,
+			&(pe_session->pLimJoinReq->rsnIE),
+			&frm->RSNOpaque);
+		populate_dot11f_wpa_opaque(mac_ctx,
+			&(pe_session->pLimJoinReq->rsnIE),
+			&frm->WPAOpaque);
+#if defined(FEATURE_WLAN_WAPI)
+		populate_dot11f_wapi_opaque(mac_ctx,
+			&(pe_session->pLimJoinReq->rsnIE),
+			&frm->WAPIOpaque);
+#endif /* defined(FEATURE_WLAN_WAPI) */
+	}
+	/* include WME EDCA IE as well */
+	if (wme_enabled) {
+		populate_dot11f_wmm_info_station_per_session(mac_ctx,
+			pe_session, &frm->WMMInfoStation);
+
+		if (wsm_enabled)
+			populate_dot11f_wmm_caps(&frm->WMMCaps);
+	}
+
+	/*
+	 * Populate HT IEs, when operating in 11n and
+	 * when AP is also operating in 11n mode
+	 */
+	if (pe_session->htCapability &&
+	    mac_ctx->lim.htCapabilityPresentInBeacon) {
+		pe_debug("Populate HT Caps in Assoc Request");
+		populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				   &frm->HTCaps, sizeof(frm->HTCaps));
+	} else if (pe_session->he_with_wep_tkip) {
+		pe_debug("Populate HT Caps in Assoc Request with WEP/TKIP");
+		populate_dot11f_ht_caps(mac_ctx, NULL, &frm->HTCaps);
+	}
+	pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x",
+		frm->HTCaps.supportedChannelWidthSet,
+		frm->HTCaps.mimoPowerSave,
+		frm->HTCaps.greenField, frm->HTCaps.shortGI20MHz,
+		frm->HTCaps.shortGI40MHz,
+		frm->HTCaps.dsssCckMode40MHz,
+		frm->HTCaps.maxRxAMPDUFactor);
+
+	if (pe_session->vhtCapability &&
+	    pe_session->vhtCapabilityPresentInBeacon) {
+		pe_debug("Populate VHT IEs in Assoc Request");
+		populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				   &frm->VHTCaps, sizeof(frm->VHTCaps));
+		vht_enabled = true;
+		if (pe_session->enableHtSmps &&
+				!pe_session->supported_nss_1x1) {
+			pe_err("VHT OP mode IE in Assoc Req");
+			populate_dot11f_operating_mode(mac_ctx,
+					&frm->OperatingMode, pe_session);
+		}
+	} else if (pe_session->he_with_wep_tkip) {
+		pe_debug("Populate VHT IEs in Assoc Request with WEP/TKIP");
+		populate_dot11f_vht_caps(mac_ctx, NULL, &frm->VHTCaps);
+	}
+
+	if (!vht_enabled &&
+			pe_session->is_vendor_specific_vhtcaps) {
+		pe_debug("Populate Vendor VHT IEs in Assoc Request");
+		frm->vendor_vht_ie.present = 1;
+		frm->vendor_vht_ie.sub_type =
+			pe_session->vendor_specific_vht_ie_sub_type;
+		frm->vendor_vht_ie.VHTCaps.present = 1;
+		if (!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.vendor_vhtie &&
+		    pe_session->vht_config.su_beam_formee) {
+			pe_debug("Disable SU beamformee for vendor IE");
+			pe_session->vht_config.su_beam_formee = 0;
+		}
+		populate_dot11f_vht_caps(mac_ctx, pe_session,
+				&frm->vendor_vht_ie.VHTCaps);
+		vht_enabled = true;
+	}
+	if (pe_session->is_ext_caps_present)
+		populate_dot11f_ext_cap(mac_ctx, vht_enabled,
+				&frm->ExtCap, pe_session);
+
+	if (mac_ctx->mlme_cfg->sta.qcn_ie_support)
+		populate_dot11f_qcn_ie(&frm->QCN_IE);
+
+	if (lim_is_session_he_capable(pe_session)) {
+		pe_debug("Populate HE IEs");
+		populate_dot11f_he_caps(mac_ctx, pe_session,
+					&frm->he_cap);
+	} else if (pe_session->he_with_wep_tkip) {
+		pe_debug("Populate HE IEs in Assoc Request with WEP/TKIP");
+		populate_dot11f_he_caps(mac_ctx, NULL, &frm->he_cap);
+	}
+
+	if (pe_session->pLimJoinReq->is11Rconnection) {
+		tSirBssDescription *bssdescr;
+
+		bssdescr = &pe_session->pLimJoinReq->bssDescription;
+		pe_debug("mdie = %02x %02x %02x",
+			(unsigned int) bssdescr->mdie[0],
+			(unsigned int) bssdescr->mdie[1],
+			(unsigned int) bssdescr->mdie[2]);
+		populate_mdie(mac_ctx, &frm->MobilityDomain,
+			pe_session->pLimJoinReq->bssDescription.mdie);
+	} else {
+		/* No 11r IEs dont send any MDIE */
+		pe_debug("MDIE not present");
+	}
+
+#ifdef FEATURE_WLAN_ESE
+	/*
+	 * ESE Version IE will be included in association request
+	 * when ESE is enabled on DUT through ini and it is also
+	 * advertised by the peer AP to which we are trying to
+	 * associate to.
+	 */
+	if (pe_session->is_ese_version_ie_present &&
+		mac_ctx->roam.configParam.isEseIniFeatureEnabled)
+		populate_dot11f_ese_version(&frm->ESEVersion);
+	/* For ESE Associations fill the ESE IEs */
+	if (pe_session->isESEconnection &&
+	    pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
+#ifndef FEATURE_DISABLE_RM
+		populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
+#endif
+	}
+#endif
+
+	/*
+	 * Extcap IE now support variable length, merge Extcap IE from addn_ie
+	 * may change the frame size. Therefore, MUST merge ExtCap IE before
+	 * dot11f get packed payload size.
+	 */
+	if (extr_ext_flag)
+		lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap, true);
+
+	/* Clear the bits in EXTCAP IE if AP not advertise it in beacon */
+	if (frm->ExtCap.present && pe_session->is_ext_caps_present) {
+		ie_offset = DOT11F_FF_TIMESTAMP_LEN +
+				DOT11F_FF_BEACONINTERVAL_LEN +
+				DOT11F_FF_CAPABILITIES_LEN;
+
+		qdf_mem_zero((uint8_t *)&bcn_ext_cap, sizeof(tDot11fIEExtCap));
+		if (pe_session->beacon && pe_session->bcnLen > ie_offset) {
+			bcn_ie = pe_session->beacon + ie_offset;
+			bcn_ie_len = pe_session->bcnLen - ie_offset;
+			p_ext_cap = (uint8_t *)wlan_get_ie_ptr_from_eid(
+							DOT11F_EID_EXTCAP,
+							bcn_ie, bcn_ie_len);
+			lim_update_extcap_struct(mac_ctx, p_ext_cap,
+							&bcn_ext_cap);
+			lim_merge_extcap_struct(&frm->ExtCap, &bcn_ext_cap,
+							false);
+		}
+		/*
+		 * TWT extended capabilities should be populated after the
+		 * intersection of beacon caps and self caps is done because
+		 * the bits for TWT are unique to STA and AP and cannot be
+		 * intersected.
+		 */
+		populate_dot11f_twt_extended_caps(mac_ctx, pe_session,
+						  &frm->ExtCap);
+	}
+
+	if (QDF_STATUS_SUCCESS != lim_strip_supp_op_class_update_struct(mac_ctx,
+			add_ie, &add_ie_len, &frm->SuppOperatingClasses))
+		pe_debug("Unable to Stripoff supp op classes IE from Assoc Req");
+
+	if (lim_is_fils_connection(pe_session)) {
+		populate_dot11f_fils_params(mac_ctx, frm, pe_session);
+		aes_block_size_len = AES_BLOCK_SIZE;
+	}
+
+	/*
+	 * MBO IE needs to be appendded at the end of the assoc request
+	 * frame and is not parsed and unpacked by the frame parser
+	 * as the supplicant can send multiple TLVs with same Attribute
+	 * in the MBO IE and the frame parser does not support multiple
+	 * TLVs with same attribute in a single IE.
+	 * Strip off the MBO IE from add_ie and append it at the end.
+	 */
+	if (wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_MBO_OUI,
+	    SIR_MAC_MBO_OUI_SIZE, add_ie, add_ie_len)) {
+		mbo_ie = qdf_mem_malloc(DOT11F_IE_MBO_IE_MAX_LEN + 2);
+		if (!mbo_ie)
+			goto end;
+
+		qdf_status = lim_strip_ie(mac_ctx, add_ie, &add_ie_len,
+					  SIR_MAC_EID_VENDOR, ONE_BYTE,
+					  SIR_MAC_MBO_OUI,
+					  SIR_MAC_MBO_OUI_SIZE,
+					  mbo_ie, DOT11F_IE_MBO_IE_MAX_LEN);
+		if (QDF_IS_STATUS_ERROR(qdf_status)) {
+			pe_err("Failed to strip MBO IE");
+			goto free_mbo_ie;
+		}
+
+		/* Include the EID and length fields */
+		mbo_ie_len = mbo_ie[1] + 2;
+		pe_debug("Stripped MBO IE of length %d", mbo_ie_len);
+	}
+
+	/*
+	 * Do unpack to populate the add_ie buffer to frm structure
+	 * before packing the frm structure. In this way, the IE ordering
+	 * which the latest 802.11 spec mandates is maintained.
+	 */
+	if (add_ie_len) {
+		ret = dot11f_unpack_assoc_request(mac_ctx, add_ie,
+					    add_ie_len, frm, true);
+		if (DOT11F_FAILED(ret)) {
+			pe_err("unpack failed, ret: 0x%x", ret);
+			goto end;
+		}
+	}
+
+	status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Association Request packet size failure(0x%08x)",
+			status);
+		/* We'll fall back on the worst case scenario: */
+		payload = sizeof(tDot11fAssocRequest);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("Association request packet size warning (0x%08x)",
+			status);
+	}
+
+	bytes = payload + sizeof(tSirMacMgmtHdr) +
+			aes_block_size_len + mbo_ie_len;
+
+	qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
+				(void **)&packet);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes", bytes);
+
+		pe_session->limMlmState = pe_session->limPrevMlmState;
+		MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
+				 pe_session->peSessionId,
+				 pe_session->limMlmState));
+
+		/* Update PE session id */
+		assoc_cnf.sessionId = pe_session->peSessionId;
+
+		assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+
+		lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
+			(uint32_t *) &assoc_cnf);
+
+		goto end;
+	}
+	/* Paranoia: */
+	qdf_mem_set(frame, bytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
+		pe_session->selfMacAddr);
+	/* That done, pack the Assoc Request: */
+	status = dot11f_pack_assoc_request(mac_ctx, frm,
+			frame + sizeof(tSirMacMgmtHdr), payload, &payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Assoc request pack failure (0x%08x)", status);
+		cds_packet_free((void *)packet);
+		goto end;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("Assoc request pack warning (0x%08x)", status);
+	}
+
+	/* Copy the MBO IE to the end of the frame */
+	qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+		     mbo_ie, mbo_ie_len);
+	payload = payload + mbo_ie_len;
+
+	if (pe_session->assocReq != NULL) {
+		qdf_mem_free(pe_session->assocReq);
+		pe_session->assocReq = NULL;
+		pe_session->assocReqLen = 0;
+	}
+
+	if (lim_is_fils_connection(pe_session)) {
+		qdf_status = aead_encrypt_assoc_req(mac_ctx, pe_session,
+						    frame, &payload);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			cds_packet_free((void *)packet);
+			qdf_mem_free(frm);
+			return;
+		}
+	}
+
+	pe_session->assocReq = qdf_mem_malloc(payload);
+	if (pe_session->assocReq) {
+		/*
+		 * Store the Assoc request. This is sent to csr/hdd in
+		 * join cnf response.
+		 */
+		qdf_mem_copy(pe_session->assocReq,
+			     frame + sizeof(tSirMacMgmtHdr), payload);
+		pe_session->assocReqLen = payload;
+	}
+
+	if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel))
+	    || (pe_session->pePersona == QDF_P2P_CLIENT_MODE)
+	    || (pe_session->pePersona == QDF_P2P_GO_MODE)
+	    )
+		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+	if (pe_session->pePersona == QDF_P2P_CLIENT_MODE ||
+		pe_session->pePersona == QDF_STA_MODE)
+		tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
+
+	mac_hdr = (tpSirMacMgmtHdr) frame;
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 pe_session->peSessionId, mac_hdr->fc.subType));
+
+	pe_debug("Sending Association Request length %d to ", bytes);
+	min_rid = lim_get_min_session_txrate(pe_session);
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
+			      pe_session, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+	lim_diag_mgmt_tx_event_report(mac_ctx, mac_hdr,
+				      pe_session, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+	qdf_status =
+		wma_tx_frameWithTxComplete(mac_ctx, packet,
+			   (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
+			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+			   lim_tx_complete, frame, lim_assoc_tx_complete_cnf,
+			   tx_flag, sme_sessionid, false, 0, min_rid);
+	MTRACE(qdf_trace
+		       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+		       pe_session->peSessionId, qdf_status));
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to send Association Request (%X)!",
+			qdf_status);
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_ACK_EVENT,
+				pe_session, SENT_FAIL, QDF_STATUS_E_FAILURE);
+		/* Pkt will be freed up by the callback */
+	}
+free_mbo_ie:
+	if (mbo_ie)
+		qdf_mem_free(mbo_ie);
+
+end:
+	/* Free up buffer allocated for mlm_assoc_req */
+	qdf_mem_free(mlm_assoc_req);
+	mlm_assoc_req = NULL;
+	qdf_mem_free(frm);
+	return;
+}
+
+/**
+ * lim_addba_rsp_tx_complete_cnf() - Confirmation for add BA response OTA
+ * @context: pointer to global mac
+ * @buf: buffer which is nothing but entire ADD BA frame
+ * @tx_complete : Sent status
+ * @params; tx completion params
+ *
+ * Return: This returns QDF_STATUS
+ */
+static QDF_STATUS lim_addba_rsp_tx_complete_cnf(void *context,
+						qdf_nbuf_t buf,
+						uint32_t tx_complete,
+						void *params)
+{
+	tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
+	tSirMacMgmtHdr *mac_hdr;
+	tDot11faddba_rsp rsp;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	uint8_t peer_id;
+	void *peer;
+	uint32_t frame_len;
+	QDF_STATUS status;
+	uint8_t *data;
+
+	if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK)
+		pe_debug("Add ba response successfully sent");
+	else
+		pe_debug("Fail to send add ba response");
+
+	if (!buf) {
+		pe_err("Addba response frame buffer is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	data = qdf_nbuf_data(buf);
+
+	if (!data) {
+		pe_err("Addba response frame is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mac_hdr = (tSirMacMgmtHdr *)data;
+	qdf_mem_zero((void *)&rsp, sizeof(tDot11faddba_rsp));
+	frame_len = sizeof(rsp);
+	status = dot11f_unpack_addba_rsp(mac_ctx, (uint8_t *)data +
+					 sizeof(*mac_hdr), frame_len,
+					 &rsp, false);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
+			status, frame_len);
+		goto error;
+	}
+
+	peer = cdp_peer_get_ref_by_addr(soc, pdev, mac_hdr->da, &peer_id,
+					PEER_DEBUG_ID_WMA_ADDBA_REQ);
+	if (!peer) {
+		pe_debug("no PEER found for mac_addr:%pM", mac_hdr->da);
+		goto error;
+	}
+	cdp_addba_resp_tx_completion(soc, peer, rsp.addba_param_set.tid,
+				     tx_complete);
+	cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_ADDBA_REQ);
+error:
+	if (buf)
+		qdf_nbuf_free(buf);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_auth_tx_complete_cnf()- Confirmation for auth sent over the air
+ * @context: pointer to global mac
+ * @buf: buffer
+ * @tx_complete : Sent status
+ * @params; tx completion params
+ *
+ * Return: This returns QDF_STATUS
+ */
+
+static QDF_STATUS lim_auth_tx_complete_cnf(void *context,
+					   qdf_nbuf_t buf,
+					   uint32_t tx_complete,
+					   void *params)
+{
+	tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
+	uint16_t auth_ack_status;
+	uint16_t reason_code;
+
+	pe_debug("tx_complete = %d %s", tx_complete,
+		(tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) ?
+		 "success" : "fail");
+	if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) {
+		mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS;
+		auth_ack_status = ACKED;
+		reason_code = QDF_STATUS_SUCCESS;
+		/* 'Change' timer for future activations */
+		lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
+	} else {
+		mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
+		auth_ack_status = NOT_ACKED;
+		reason_code = QDF_STATUS_E_FAILURE;
+	}
+
+	if (buf)
+		qdf_nbuf_free(buf);
+
+	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT,
+				NULL, auth_ack_status, reason_code);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_send_auth_mgmt_frame() - Send an Authentication frame
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @auth_frame: Pointer to Authentication frame structure
+ * @peer_addr: MAC address of destination peer
+ * @wep_bit: wep bit in frame control for Authentication frame3
+ * @session: PE session information
+ *
+ * This function is called by lim_process_mlm_messages(). Authentication frame
+ * is formatted and sent when this function is called.
+ *
+ * Return: void
+ */
+void
+lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
+			 tpSirMacAuthFrameBody auth_frame,
+			 tSirMacAddr peer_addr,
+			 uint8_t wep_challenge_len,
+			 tpPESession session)
+{
+	uint8_t *frame, *body;
+	uint32_t frame_len = 0, body_len = 0;
+	tpSirMacMgmtHdr mac_hdr;
+	void *packet;
+	QDF_STATUS qdf_status;
+	uint8_t tx_flag = 0;
+	uint8_t sme_sessionid = 0;
+	uint16_t ft_ies_length = 0;
+	bool challenge_req = false;
+	enum rateid min_rid = RATEID_DEFAULT;
+
+	if (NULL == session) {
+		pe_err("Error: psession Entry is NULL");
+		return;
+	}
+
+	sme_sessionid = session->smeSessionId;
+
+	if (wep_challenge_len) {
+		/*
+		 * Auth frame3 to be sent with encrypted framebody
+		 *
+		 * Allocate buffer for Authenticaton frame of size
+		 * equal to management frame header length plus 2 bytes
+		 * each for auth algorithm number, transaction number,
+		 * status code, 128 bytes for challenge text and
+		 * 4 bytes each for IV & ICV.
+		 */
+		pe_debug("Sending encrypted auth frame to " MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(peer_addr));
+
+		body_len = wep_challenge_len + LIM_ENCR_AUTH_INFO_LEN;
+		frame_len = sizeof(tSirMacMgmtHdr) + body_len;
+
+		goto alloc_packet;
+	}
+
+	pe_debug("Sending Auth seq# %d status %d (%d) to "
+		MAC_ADDRESS_STR,
+		auth_frame->authTransactionSeqNumber,
+		auth_frame->authStatusCode,
+		(auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
+		MAC_ADDR_ARRAY(peer_addr));
+
+	switch (auth_frame->authTransactionSeqNumber) {
+	case SIR_MAC_AUTH_FRAME_1:
+		/*
+		 * Allocate buffer for Authenticaton frame of size
+		 * equal to management frame header length plus 2 bytes
+		 * each for auth algorithm number, transaction number
+		 * and status code.
+		 */
+
+		body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
+		frame_len = sizeof(tSirMacMgmtHdr) + body_len;
+
+		frame_len += lim_create_fils_auth_data(mac_ctx,
+						auth_frame, session);
+		if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
+			if (NULL != session->ftPEContext.pFTPreAuthReq &&
+			    0 != session->ftPEContext.pFTPreAuthReq->
+				ft_ies_length) {
+				ft_ies_length = session->ftPEContext.
+					pFTPreAuthReq->ft_ies_length;
+				frame_len += ft_ies_length;
+				pe_debug("Auth frame, FTIES length added=%d",
+					ft_ies_length);
+			} else {
+				pe_debug("Auth frame, Does not contain FTIES!");
+				frame_len += (2 + SIR_MDIE_SIZE);
+			}
+		}
+		break;
+
+	case SIR_MAC_AUTH_FRAME_2:
+		if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
+		    ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
+			(auth_frame->authStatusCode !=
+			 eSIR_MAC_SUCCESS_STATUS))) {
+			/*
+			 * Allocate buffer for Authenticaton frame of size
+			 * equal to management frame header length plus
+			 * 2 bytes each for auth algorithm number,
+			 * transaction number and status code.
+			 */
+
+			body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
+			frame_len = sizeof(tSirMacMgmtHdr) + body_len;
+		} else {
+			/*
+			 * Shared Key algorithm with challenge text
+			 * to be sent.
+			 *
+			 * Allocate buffer for Authenticaton frame of size
+			 * equal to management frame header length plus
+			 * 2 bytes each for auth algorithm number,
+			 * transaction number, status code and 128 bytes
+			 * for challenge text.
+			 */
+
+			challenge_req = true;
+			body_len = SIR_MAC_AUTH_FRAME_INFO_LEN +
+				   SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH +
+				   SIR_MAC_CHALLENGE_ID_LEN;
+			frame_len = sizeof(tSirMacMgmtHdr) + body_len;
+		}
+		break;
+
+	case SIR_MAC_AUTH_FRAME_3:
+		/*
+		 * Auth frame3 to be sent without encrypted framebody
+		 *
+		 * Allocate buffer for Authenticaton frame of size equal
+		 * to management frame header length plus 2 bytes each
+		 * for auth algorithm number, transaction number and
+		 * status code.
+		 */
+
+		body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
+		frame_len = sizeof(tSirMacMgmtHdr) + body_len;
+		break;
+
+	case SIR_MAC_AUTH_FRAME_4:
+		/*
+		 * Allocate buffer for Authenticaton frame of size equal
+		 * to management frame header length plus 2 bytes each
+		 * for auth algorithm number, transaction number and
+		 * status code.
+		 */
+
+		body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
+		frame_len = sizeof(tSirMacMgmtHdr) + body_len;
+
+		break;
+	default:
+		pe_err("Invalid auth transaction seq num");
+		return;
+	} /* switch (auth_frame->authTransactionSeqNumber) */
+
+alloc_packet:
+	qdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
+				 (void **)&packet);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("call to bufAlloc failed for AUTH frame");
+		return;
+	}
+
+	qdf_mem_zero(frame, frame_len);
+
+	/* Prepare BD */
+	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
+	mac_hdr = (tpSirMacMgmtHdr) frame;
+	if (wep_challenge_len)
+		mac_hdr->fc.wep = LIM_WEP_IN_FC;
+	else
+		mac_hdr->fc.wep = LIM_NO_WEP_IN_FC;
+
+	/* Prepare BSSId */
+	if (LIM_IS_AP_ROLE(session))
+		qdf_mem_copy((uint8_t *) mac_hdr->bssId,
+			     (uint8_t *) session->bssId,
+			     sizeof(tSirMacAddr));
+
+	/* Prepare Authentication frame body */
+	body = frame + sizeof(tSirMacMgmtHdr);
+
+	if (wep_challenge_len) {
+		qdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
+
+		pe_debug("Sending Auth seq# 3 to " MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(mac_hdr->da));
+
+	} else {
+		*((uint16_t *) (body)) =
+			sir_swap_u16if_needed(auth_frame->authAlgoNumber);
+		body += sizeof(uint16_t);
+		body_len -= sizeof(uint16_t);
+
+		*((uint16_t *) (body)) =
+			sir_swap_u16if_needed(
+				auth_frame->authTransactionSeqNumber);
+		body += sizeof(uint16_t);
+		body_len -= sizeof(uint16_t);
+
+		*((uint16_t *) (body)) =
+			sir_swap_u16if_needed(auth_frame->authStatusCode);
+		body += sizeof(uint16_t);
+		body_len -= sizeof(uint16_t);
+
+		if (challenge_req) {
+			if (body_len < SIR_MAC_AUTH_CHALLENGE_BODY_LEN) {
+				/* copy challenge IE id, len, challenge text */
+				*body = auth_frame->type;
+				body++;
+				body_len -= sizeof(uint8_t);
+				*body = auth_frame->length;
+				body++;
+				body_len -= sizeof(uint8_t);
+				qdf_mem_copy(body, auth_frame->challengeText,
+					     body_len);
+				pe_err("Incomplete challenge info: length: %d, expected: %d",
+				       body_len,
+				       SIR_MAC_AUTH_CHALLENGE_BODY_LEN);
+				body += body_len;
+				body_len = 0;
+			} else {
+				/* copy challenge IE id, len, challenge text */
+				*body = auth_frame->type;
+				body++;
+				*body = auth_frame->length;
+				body++;
+				qdf_mem_copy(body, auth_frame->challengeText,
+					     SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
+				body += SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH;
+
+				body_len -= SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH +
+							SIR_MAC_CHALLENGE_ID_LEN;
+			}
+		}
+
+		if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
+		    (auth_frame->authTransactionSeqNumber ==
+		     SIR_MAC_AUTH_FRAME_1) &&
+		     (session->ftPEContext.pFTPreAuthReq != NULL)) {
+
+			if (ft_ies_length > 0) {
+				qdf_mem_copy(body,
+					session->ftPEContext.
+						pFTPreAuthReq->ft_ies,
+					ft_ies_length);
+				pe_debug("Auth1 Frame FTIE is: ");
+				QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+						   QDF_TRACE_LEVEL_DEBUG,
+						   (uint8_t *) body,
+						   ft_ies_length);
+			} else if (NULL != session->ftPEContext.
+					pFTPreAuthReq->pbssDescription) {
+				/* MDID attr is 54 */
+				*body = SIR_MDIE_ELEMENT_ID;
+				body++;
+				*body = SIR_MDIE_SIZE;
+				body++;
+				qdf_mem_copy(body,
+					&session->ftPEContext.pFTPreAuthReq->
+						pbssDescription->mdie[0],
+					SIR_MDIE_SIZE);
+			}
+		} else if (auth_frame->authAlgoNumber ==
+				SIR_FILS_SK_WITHOUT_PFS) {
+			/* TODO MDIE */
+			pe_debug("appending fils Auth data");
+			lim_add_fils_data_to_auth_frame(session, body);
+		}
+
+		pe_debug("*** Sending Auth seq# %d status %d (%d) to "
+				MAC_ADDRESS_STR,
+			auth_frame->authTransactionSeqNumber,
+			auth_frame->authStatusCode,
+			(auth_frame->authStatusCode ==
+				eSIR_MAC_SUCCESS_STATUS),
+			MAC_ADDR_ARRAY(mac_hdr->da));
+	}
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+			   QDF_TRACE_LEVEL_DEBUG,
+			   frame, frame_len);
+
+	if ((NULL != session->ftPEContext.pFTPreAuthReq) &&
+	    (BAND_5G == lim_get_rf_band(
+	     session->ftPEContext.pFTPreAuthReq->preAuthchannelNum)))
+		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	else if ((BAND_5G ==
+		  lim_get_rf_band(session->currentOperChannel))
+		  || (session->pePersona == QDF_P2P_CLIENT_MODE)
+		  || (session->pePersona == QDF_P2P_GO_MODE))
+		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+	if (session->pePersona == QDF_P2P_CLIENT_MODE ||
+		session->pePersona == QDF_STA_MODE)
+		tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 session->peSessionId, mac_hdr->fc.subType));
+
+	mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
+	min_rid = lim_get_min_session_txrate(session);
+	lim_diag_mgmt_tx_event_report(mac_ctx, mac_hdr,
+				      session, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+	qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
+				 (uint16_t)frame_len,
+				 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
+				 7, lim_tx_complete, frame,
+				 lim_auth_tx_complete_cnf,
+				 tx_flag, sme_sessionid, false, 0, min_rid);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+		session->peSessionId, qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("*** Could not send Auth frame, retCode=%X ***",
+			qdf_status);
+		mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT,
+				session, SENT_FAIL, QDF_STATUS_E_FAILURE);
+	/* Pkt will be freed up by the callback */
+	}
+	return;
+}
+
+QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal mac_ctx)
+{
+	uint16_t aid;
+	tpDphHashNode sta_ds;
+	tLimMlmDeauthReq *deauth_req;
+	tLimMlmDeauthCnf deauth_cnf;
+	tpPESession session_entry;
+
+	deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
+	if (deauth_req) {
+		if (tx_timer_running(
+			&mac_ctx->lim.limTimers.gLimDeauthAckTimer))
+			lim_deactivate_and_change_timer(mac_ctx,
+							eLIM_DEAUTH_ACK_TIMER);
+
+		session_entry = pe_find_session_by_session_id(mac_ctx,
+					deauth_req->sessionId);
+		if (session_entry == NULL) {
+			pe_err("session does not exist for given sessionId");
+			deauth_cnf.resultCode =
+				eSIR_SME_INVALID_PARAMETERS;
+			goto end;
+		}
+
+		sta_ds =
+			dph_lookup_hash_entry(mac_ctx,
+					      deauth_req->peer_macaddr.bytes,
+					      &aid,
+					      &session_entry->dph.dphHashTable);
+		if (sta_ds == NULL) {
+			deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+			goto end;
+		}
+
+		/* / Receive path cleanup with dummy packet */
+		lim_ft_cleanup_pre_auth_info(mac_ctx, session_entry);
+		lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry);
+		if ((session_entry->limSystemRole == eLIM_STA_ROLE) &&
+		    (
+#ifdef FEATURE_WLAN_ESE
+		    (session_entry->isESEconnection) ||
+#endif
+		    (session_entry->isFastRoamIniFeatureEnabled) ||
+		    (session_entry->is11Rconnection))) {
+			pe_debug("FT Preauth (%pK,%d) Deauth rc %d src = %d",
+				 session_entry,
+				 session_entry->peSessionId,
+				 deauth_req->reasonCode,
+				 deauth_req->deauthTrigger);
+			lim_ft_cleanup(mac_ctx, session_entry);
+		} else {
+			pe_debug("No FT Preauth Session Cleanup in role %d"
+#ifdef FEATURE_WLAN_ESE
+				 " isESE %d"
+#endif
+				 " isLFR %d"
+				 " is11r %d, Deauth reason %d Trigger = %d",
+				 session_entry->limSystemRole,
+#ifdef FEATURE_WLAN_ESE
+				 session_entry->isESEconnection,
+#endif
+				 session_entry->isFastRoamIniFeatureEnabled,
+				 session_entry->is11Rconnection,
+				 deauth_req->reasonCode,
+				 deauth_req->deauthTrigger);
+		}
+		/* Free up buffer allocated for mlmDeauthReq */
+		qdf_mem_free(deauth_req);
+		mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
+	}
+	return QDF_STATUS_SUCCESS;
+end:
+	qdf_copy_macaddr(&deauth_cnf.peer_macaddr,
+			 &deauth_req->peer_macaddr);
+	deauth_cnf.deauthTrigger = deauth_req->deauthTrigger;
+	deauth_cnf.aid = deauth_req->aid;
+	deauth_cnf.sessionId = deauth_req->sessionId;
+
+	/* Free up buffer allocated */
+	/* for mlmDeauthReq */
+	qdf_mem_free(deauth_req);
+	mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
+
+	lim_post_sme_message(mac_ctx,
+			     LIM_MLM_DEAUTH_CNF, (uint32_t *) &deauth_cnf);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
+ *
+ * @mac_ctx: Handle to MAC context
+ *
+ * Sends disassoc confirmation to SME. Removes disassoc request stored
+ * in lim.
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+
+QDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
+{
+	uint16_t aid;
+	tpDphHashNode sta_ds;
+	tLimMlmDisassocCnf disassoc_cnf;
+	tpPESession pe_session;
+	tLimMlmDisassocReq *disassoc_req;
+
+	disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
+	if (disassoc_req) {
+		if (tx_timer_running(
+			&mac_ctx->lim.limTimers.gLimDisassocAckTimer))
+			lim_deactivate_and_change_timer(mac_ctx,
+				eLIM_DISASSOC_ACK_TIMER);
+
+		pe_session = pe_find_session_by_session_id(
+					mac_ctx, disassoc_req->sessionId);
+		if (pe_session == NULL) {
+			pe_err("No session for given sessionId");
+			disassoc_cnf.resultCode =
+				eSIR_SME_INVALID_PARAMETERS;
+			goto end;
+		}
+
+		sta_ds = dph_lookup_hash_entry(mac_ctx,
+				disassoc_req->peer_macaddr.bytes, &aid,
+				&pe_session->dph.dphHashTable);
+		if (sta_ds == NULL) {
+			pe_err("StaDs Null");
+			disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+			goto end;
+		}
+		/* Receive path cleanup with dummy packet */
+		if (QDF_STATUS_SUCCESS !=
+		    lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
+			disassoc_cnf.resultCode =
+				eSIR_SME_RESOURCES_UNAVAILABLE;
+			pe_err("cleanup_rx_path error");
+			goto end;
+		}
+		if (LIM_IS_STA_ROLE(pe_session) &&
+		    (disassoc_req->reasonCode !=
+		    eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
+			pe_debug("FT Preauth Session (%pK %d) Clean up",
+				 pe_session, pe_session->peSessionId);
+
+			/* Delete FT session if there exists one */
+			lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
+		}
+		/* Free up buffer allocated for mlmDisassocReq */
+		qdf_mem_free(disassoc_req);
+		mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
+		return QDF_STATUS_SUCCESS;
+	} else {
+		return QDF_STATUS_SUCCESS;
+	}
+end:
+	qdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
+		     (uint8_t *) disassoc_req->peer_macaddr.bytes,
+		     QDF_MAC_ADDR_SIZE);
+	disassoc_cnf.aid = disassoc_req->aid;
+	disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
+
+	/* Update PE session ID */
+	disassoc_cnf.sessionId = disassoc_req->sessionId;
+
+	if (disassoc_req != NULL) {
+		/* / Free up buffer allocated for mlmDisassocReq */
+		qdf_mem_free(disassoc_req);
+		mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
+	}
+
+	lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
+		(uint32_t *) &disassoc_cnf);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
+					uint32_t tx_success,
+					void *params)
+{
+	tpAniSirGlobal max_ctx = (tpAniSirGlobal)context;
+
+	pe_debug("tx_success: %d", tx_success);
+
+	return lim_send_disassoc_cnf(max_ctx);
+}
+
+static QDF_STATUS lim_disassoc_tx_complete_cnf_handler(void *context,
+						       qdf_nbuf_t buf,
+						       uint32_t tx_success,
+						       void *params)
+{
+	tpAniSirGlobal max_ctx = (tpAniSirGlobal)context;
+	QDF_STATUS status_code;
+	struct scheduler_msg msg = {0};
+
+	pe_debug("tx_success: %d", tx_success);
+
+	if (buf)
+		qdf_nbuf_free(buf);
+	msg.type = (uint16_t) WMA_DISASSOC_TX_COMP;
+	msg.bodyptr = params;
+	msg.bodyval = tx_success;
+
+	status_code = lim_post_msg_high_priority(max_ctx, &msg);
+	if (status_code != QDF_STATUS_SUCCESS)
+		pe_err("posting message: %X to LIM failed, reason: %d",
+		       msg.type, status_code);
+	return status_code;
+}
+
+QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
+				      uint32_t tx_success,
+				      void *params)
+{
+	tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
+
+	pe_debug("tx_success: %d", tx_success);
+
+	return lim_send_deauth_cnf(mac_ctx);
+}
+
+static QDF_STATUS lim_deauth_tx_complete_cnf_handler(void *context,
+						     qdf_nbuf_t buf,
+						     uint32_t tx_success,
+						     void *params)
+{
+	tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
+	QDF_STATUS status_code;
+	struct scheduler_msg msg = {0};
+
+	pe_debug("tx_success: %d", tx_success);
+
+	if (buf)
+		qdf_nbuf_free(buf);
+	msg.type = (uint16_t) WMA_DEAUTH_TX_COMP;
+	msg.bodyptr = params;
+	msg.bodyval = tx_success;
+
+	status_code = lim_post_msg_high_priority(mac_ctx, &msg);
+	if (status_code != QDF_STATUS_SUCCESS)
+		pe_err("posting message: %X to LIM failed, reason: %d",
+		       msg.type, status_code);
+	return status_code;
+}
+
+/**
+ * \brief This function is called to send Disassociate frame.
+ *
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param nReason Indicates the reason that need to be sent in
+ * Disassociation frame
+ *
+ * \param peerMacAddr MAC address of the STA to which Disassociation frame is
+ * sent
+ *
+ *
+ */
+
+void
+lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
+			     uint16_t nReason,
+			     tSirMacAddr peer,
+			     tpPESession psessionEntry, bool waitForAck)
+{
+	tDot11fDisassociation frm;
+	uint8_t *pFrame;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload, nStatus;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint8_t txFlag = 0;
+	uint32_t val = 0;
+	uint8_t smeSessionId = 0;
+
+	if (NULL == psessionEntry) {
+		return;
+	}
+
+	/*
+	 * In case when cac timer is running for this SAP session then
+	 * avoid sending disassoc out. It is violation of dfs specification.
+	 */
+	if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
+	    (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			  FL
+				  ("CAC timer is running, drop disassoc from going out"));
+		return;
+	}
+	smeSessionId = psessionEntry->smeSessionId;
+
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+	frm.Reason.code = nReason;
+
+	nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a Disassociation (0x%08x)",
+			nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fDisassociation);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for a Disassociation (0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				      (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a Disassociation",
+			nBytes);
+		return;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	/* Prepare the BSSID */
+	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
+					     sizeof(tSirMacMgmtHdr),
+					     nPayload, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack a Disassociation (0x%08x)",
+			nStatus);
+		cds_packet_free((void *)pPacket);
+		return;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing a Disassociation (0x%08x)",
+			nStatus);
+	}
+
+	pe_debug("***Sessionid %d Sending Disassociation frame with "
+		   "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
+		   MAC_ADDRESS_STR, psessionEntry->peSessionId, nReason,
+		waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
+		MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
+
+	if ((BAND_5G == lim_get_rf_band(psessionEntry->currentOperChannel))
+	    || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)
+	    ) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
+
+	if (waitForAck) {
+		MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+				 psessionEntry->peSessionId,
+				 pMacHdr->fc.subType));
+		lim_diag_mgmt_tx_event_report(pMac, pMacHdr,
+					      psessionEntry, QDF_STATUS_SUCCESS,
+					      QDF_STATUS_SUCCESS);
+		/* Queue Disassociation frame in high priority WQ */
+		/* get the duration from the request */
+		qdf_status =
+			wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
+					 TXRX_FRM_802_11_MGMT,
+					 ANI_TXDIR_TODS, 7, lim_tx_complete,
+					 pFrame, lim_disassoc_tx_complete_cnf_handler,
+					 txFlag, smeSessionId, false, 0,
+					 RATEID_DEFAULT);
+		MTRACE(qdf_trace
+			       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			       psessionEntry->peSessionId, qdf_status));
+
+		val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
+
+		if (tx_timer_change
+			    (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
+		    != TX_SUCCESS) {
+			pe_err("Unable to change Disassoc ack Timer val");
+			return;
+		} else if (TX_SUCCESS !=
+			   tx_timer_activate(&pMac->lim.limTimers.
+					     gLimDisassocAckTimer)) {
+			pe_err("Unable to activate Disassoc ack Timer");
+			lim_deactivate_and_change_timer(pMac,
+							eLIM_DISASSOC_ACK_TIMER);
+			return;
+		}
+	} else {
+		MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+				 psessionEntry->peSessionId,
+				 pMacHdr->fc.subType));
+		lim_diag_mgmt_tx_event_report(pMac, pMacHdr,
+					      psessionEntry,
+					      QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+		/* Queue Disassociation frame in high priority WQ */
+		qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+					TXRX_FRM_802_11_MGMT,
+					ANI_TXDIR_TODS,
+					7,
+					lim_tx_complete, pFrame, txFlag,
+					smeSessionId, 0, RATEID_DEFAULT);
+		MTRACE(qdf_trace
+			       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			       psessionEntry->peSessionId, qdf_status));
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			pe_err("Failed to send Disassociation (%X)!",
+				qdf_status);
+			/* Pkt will be freed up by the callback */
+		}
+	}
+} /* End lim_send_disassoc_mgmt_frame. */
+
+/**
+ * \brief This function is called to send a Deauthenticate frame
+ *
+ *
+ * \param pMac Pointer to global MAC structure
+ *
+ * \param nReason Indicates the reason that need to be sent in the
+ * Deauthenticate frame
+ *
+ * \param peeer address of the STA to which the frame is to be sent
+ *
+ *
+ */
+
+void
+lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
+			   uint16_t nReason,
+			   tSirMacAddr peer,
+			   tpPESession psessionEntry, bool waitForAck)
+{
+	tDot11fDeAuth frm;
+	uint8_t *pFrame;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload, nStatus;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint8_t txFlag = 0;
+	uint32_t val = 0;
+#ifdef FEATURE_WLAN_TDLS
+	uint16_t aid;
+	tpDphHashNode pStaDs;
+#endif
+	uint8_t smeSessionId = 0;
+
+	if (NULL == psessionEntry) {
+		return;
+	}
+
+	/*
+	 * In case when cac timer is running for this SAP session then
+	 * avoid deauth frame out. It is violation of dfs specification.
+	 */
+	if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
+	    (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			  FL
+				  ("CAC timer is running, drop the deauth from going out"));
+		return;
+	}
+	smeSessionId = psessionEntry->smeSessionId;
+
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+	frm.Reason.code = nReason;
+
+	nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a De-Authentication (0x%08x)",
+			nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fDeAuth);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for a De-Authentication (0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				      (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a De-Authentication",
+			nBytes);
+		return;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	/* Prepare the BSSID */
+	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
+				      sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack a DeAuthentication (0x%08x)",
+			nStatus);
+		cds_packet_free((void *)pPacket);
+		return;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing a De-Authentication (0x%08x)",
+			nStatus);
+	}
+	pe_debug("***Sessionid %d Sending Deauth frame with "
+		       "reason %u and waitForAck %d to " MAC_ADDRESS_STR
+		       " ,From " MAC_ADDRESS_STR,
+		psessionEntry->peSessionId, nReason, waitForAck,
+		MAC_ADDR_ARRAY(pMacHdr->da),
+		MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
+
+	if ((BAND_5G == lim_get_rf_band(psessionEntry->currentOperChannel))
+	    || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)
+	    ) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
+#ifdef FEATURE_WLAN_TDLS
+	pStaDs =
+		dph_lookup_hash_entry(pMac, peer, &aid,
+				      &psessionEntry->dph.dphHashTable);
+#endif
+
+	if (waitForAck) {
+		MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+				 psessionEntry->peSessionId,
+				 pMacHdr->fc.subType));
+		lim_diag_mgmt_tx_event_report(pMac, pMacHdr,
+					      psessionEntry,
+					      QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+		/* Queue Disassociation frame in high priority WQ */
+		qdf_status =
+			wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
+					 TXRX_FRM_802_11_MGMT,
+					 ANI_TXDIR_TODS, 7, lim_tx_complete,
+					 pFrame, lim_deauth_tx_complete_cnf_handler,
+					 txFlag, smeSessionId, false, 0,
+					 RATEID_DEFAULT);
+		MTRACE(qdf_trace
+			       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			       psessionEntry->peSessionId, qdf_status));
+		/* Pkt will be freed up by the callback lim_tx_complete */
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			pe_err("Failed to send De-Authentication (%X)!",
+				qdf_status);
+
+			/* Call lim_process_deauth_ack_timeout which will send
+			 * DeauthCnf for this frame
+			 */
+			lim_process_deauth_ack_timeout(pMac);
+			return;
+		}
+
+		val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
+
+		if (tx_timer_change
+			    (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
+		    != TX_SUCCESS) {
+			pe_err("Unable to change Deauth ack Timer val");
+			return;
+		} else if (TX_SUCCESS !=
+			   tx_timer_activate(&pMac->lim.limTimers.
+					     gLimDeauthAckTimer)) {
+			pe_err("Unable to activate Deauth ack Timer");
+			lim_deactivate_and_change_timer(pMac,
+							eLIM_DEAUTH_ACK_TIMER);
+			return;
+		}
+	} else {
+		MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+				 psessionEntry->peSessionId,
+				 pMacHdr->fc.subType));
+#ifdef FEATURE_WLAN_TDLS
+		if ((NULL != pStaDs)
+		    && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
+			/* Queue Disassociation frame in high priority WQ */
+			lim_diag_mgmt_tx_event_report(pMac, pMacHdr,
+						      psessionEntry,
+						      QDF_STATUS_SUCCESS,
+						      QDF_STATUS_SUCCESS);
+			qdf_status =
+				wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+					   TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
+					   7, lim_tx_complete, pFrame, txFlag,
+					   smeSessionId, 0, RATEID_DEFAULT);
+		} else {
+#endif
+		lim_diag_mgmt_tx_event_report(pMac, pMacHdr,
+					      psessionEntry,
+					      QDF_STATUS_SUCCESS,
+					      QDF_STATUS_SUCCESS);
+		/* Queue Disassociation frame in high priority WQ */
+		qdf_status =
+			wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+				   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
+				   7, lim_tx_complete, pFrame, txFlag,
+				   smeSessionId, 0, RATEID_DEFAULT);
+#ifdef FEATURE_WLAN_TDLS
+	}
+#endif
+		MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+				 psessionEntry->peSessionId, qdf_status));
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			pe_err("Failed to send De-Authentication (%X)!",
+				qdf_status);
+			/* Pkt will be freed up by the callback */
+		}
+	}
+
+} /* End lim_send_deauth_mgmt_frame. */
+
+#ifdef ANI_SUPPORT_11H
+/**
+ * \brief Send a Measurement Report Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
+ *
+ * \return QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE else
+ *
+ *
+ */
+
+QDF_STATUS
+lim_send_meas_report_frame(tpAniSirGlobal pMac,
+			   tpSirMacMeasReqActionFrame pMeasReqFrame,
+			   tSirMacAddr peer, tpPESession psessionEntry)
+{
+	tDot11fMeasurementReport frm;
+	uint8_t *pFrame;
+	QDF_STATUS nSirStatus;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload, nStatus;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+	frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+	frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
+	frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
+
+	switch (pMeasReqFrame->measReqIE.measType) {
+	case SIR_MAC_BASIC_MEASUREMENT_TYPE:
+		nSirStatus =
+			populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
+							    &frm.MeasurementReport);
+		break;
+	case SIR_MAC_CCA_MEASUREMENT_TYPE:
+		nSirStatus =
+			populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
+							    &frm.MeasurementReport);
+		break;
+	case SIR_MAC_RPI_MEASUREMENT_TYPE:
+		nSirStatus =
+			populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
+							    &frm.MeasurementReport);
+		break;
+	default:
+		pe_err("Unknown measurement type %d in limSen"
+		       "dMeasReportFrame",
+			pMeasReqFrame->measReqIE.measType);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (QDF_STATUS_SUCCESS != nSirStatus)
+		return QDF_STATUS_E_FAILURE;
+
+	nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a Measurement Report (0x%08x)",
+			nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fMeasurementReport);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for a Measurement Report (0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status =
+		cds_packet_alloc(pMac->hdd_handle, TXRX_FRM_802_11_MGMT,
+				 (uint16_t) nBytes, (void **)&pFrame,
+				 (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a "
+		       "De-Authentication", nBytes);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer);
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
+
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
+						 sizeof(tSirMacMgmtHdr),
+						 nPayload, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack a Measurement Report (0x%08x)",
+			nStatus);
+		cds_packet_free(pMac->hdd_handle, TXRX_FRM_802_11_MGMT,
+				(void *)pFrame, (void *)pPacket);
+		return QDF_STATUS_E_FAILURE;    /* allocated! */
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing a Measurement Report (0x%08x)",
+			nStatus);
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 ((psessionEntry) ? psessionEntry->
+			  peSessionId : NO_SESSION), pMacHdr->fc.subType));
+	qdf_status =
+		wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+			   lim_tx_complete, pFrame, 0, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace
+		       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+		       ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
+		       qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to send a Measurement Report (%X)!",
+			qdf_status);
+		/* Pkt will be freed up by the callback */
+		return QDF_STATUS_E_FAILURE;    /* just allocated... */
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End lim_send_meas_report_frame. */
+
+/**
+ * \brief Send a TPC Request Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC datastructure
+ *
+ * \param peer MAC address to which the frame should be sent
+ *
+ *
+ */
+
+void
+lim_send_tpc_request_frame(tpAniSirGlobal pMac,
+			   tSirMacAddr peer, tpPESession psessionEntry)
+{
+	tDot11fTPCRequest frm;
+	uint8_t *pFrame;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload, nStatus;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+	frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+	frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
+	frm.DialogToken.token = 1;
+	frm.TPCRequest.present = 1;
+
+	nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a TPC Request (0x%08x)", nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fTPCRequest);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for a TPC Request (0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status =
+		cds_packet_alloc(pMac->hdd_handle, TXRX_FRM_802_11_MGMT,
+				 (uint16_t) nBytes, (void **)&pFrame,
+				 (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a TPC"
+			" Request", nBytes);
+		return;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer);
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
+
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
+					  sizeof(tSirMacMgmtHdr),
+					  nPayload, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack a TPC Request (0x%08x)",
+			nStatus);
+		cds_packet_free(pMac->hdd_handle, TXRX_FRM_802_11_MGMT,
+				(void *)pFrame, (void *)pPacket);
+		return;         /* allocated! */
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing a TPC Request (0x%08x)",
+			nStatus);
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 ((psessionEntry) ? psessionEntry->
+			  peSessionId : NO_SESSION), pMacHdr->fc.subType));
+	qdf_status =
+		wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+			   lim_tx_complete, pFrame, 0, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace
+		       (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+		       ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
+		       qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to send a TPC Request (%X)!",
+			qdf_status);
+		/* Pkt will be freed up by the callback */
+	}
+
+} /* End lim_send_tpc_request_frame. */
+
+/**
+ * \brief Send a TPC Report Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC datastructure
+ *
+ * \param pTpcReqFrame Pointer to the received TPC Request
+ *
+ * \return QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE else
+ *
+ *
+ */
+
+QDF_STATUS
+lim_send_tpc_report_frame(tpAniSirGlobal pMac,
+			  tpSirMacTpcReqActionFrame pTpcReqFrame,
+			  tSirMacAddr peer, tpPESession psessionEntry)
+{
+	tDot11fTPCReport frm;
+	uint8_t *pFrame;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload, nStatus;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+	frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+	frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
+	frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
+
+	frm.TPCReport.tx_power = 0;
+	frm.TPCReport.link_margin = 0;
+	frm.TPCReport.present = 1;
+
+	nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a TPC Report (0x%08x)", nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fTPCReport);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for a TPC Report (0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status =
+		cds_packet_alloc(pMac->hdd_handle, TXRX_FRM_802_11_MGMT,
+				 (uint16_t) nBytes, (void **)&pFrame,
+				 (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a TPC"
+			" Report", nBytes);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer);
+
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
+
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
+					 sizeof(tSirMacMgmtHdr),
+					 nPayload, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack a TPC Report (0x%08x)",
+			nStatus);
+		cds_packet_free(pMac->hdd_handle, TXRX_FRM_802_11_MGMT,
+				(void *)pFrame, (void *)pPacket);
+		return QDF_STATUS_E_FAILURE;    /* allocated! */
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing a TPC Report (0x%08x)",
+			nStatus);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 ((psessionEntry) ? psessionEntry->
+			  peSessionId : NO_SESSION), pMacHdr->fc.subType));
+	qdf_status =
+		wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+			   lim_tx_complete, pFrame, 0, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace
+		(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+		((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
+		qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to send a TPC Report (%X)!",
+			qdf_status);
+		/* Pkt will be freed up by the callback */
+		return QDF_STATUS_E_FAILURE;    /* just allocated... */
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End lim_send_tpc_report_frame. */
+#endif /* ANI_SUPPORT_11H */
+
+/**
+ * \brief Send a Channel Switch Announcement
+ *
+ *
+ * \param pMac Pointer to the global MAC datastructure
+ *
+ * \param peer MAC address to which this frame will be sent
+ *
+ * \param nMode
+ *
+ * \param nNewChannel
+ *
+ * \param nCount
+ *
+ * \return QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE else
+ *
+ *
+ */
+
+QDF_STATUS
+lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
+				   tSirMacAddr peer,
+				   uint8_t nMode,
+				   uint8_t nNewChannel,
+				   uint8_t nCount, tpPESession psessionEntry)
+{
+	tDot11fChannelSwitch frm;
+	uint8_t *pFrame;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload, nStatus;     /* , nCfg; */
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint8_t txFlag = 0;
+
+	uint8_t smeSessionId = 0;
+
+	if (psessionEntry == NULL) {
+		pe_err("Session entry is NULL!!!");
+		return QDF_STATUS_E_FAILURE;
+	}
+	smeSessionId = psessionEntry->smeSessionId;
+
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+	frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+	frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
+	frm.ChanSwitchAnn.switchMode = nMode;
+	frm.ChanSwitchAnn.newChannel = nNewChannel;
+	frm.ChanSwitchAnn.switchCount = nCount;
+	frm.ChanSwitchAnn.present = 1;
+
+	nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a Channel Switch (0x%08x)",
+			nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fChannelSwitch);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for a Channel Switch (0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status =
+		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				 (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a TPC Report", nBytes);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer,
+		psessionEntry->selfMacAddr);
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+	qdf_mem_copy((uint8_t *) pMacHdr->bssId,
+		     (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
+
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
+					     sizeof(tSirMacMgmtHdr),
+					     nPayload, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack a Channel Switch (0x%08x)",
+			nStatus);
+		cds_packet_free((void *)pPacket);
+		return QDF_STATUS_E_FAILURE;    /* allocated! */
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing a Channel Switch (0x%08x)",
+			nStatus);
+	}
+
+	if ((BAND_5G == lim_get_rf_band(psessionEntry->currentOperChannel))
+	    || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)
+	    ) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 psessionEntry->peSessionId, pMacHdr->fc.subType));
+	qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, pFrame, txFlag,
+				smeSessionId, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			 psessionEntry->peSessionId, qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to send a Channel Switch (%X)!",
+			qdf_status);
+		/* Pkt will be freed up by the callback */
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End lim_send_channel_switch_mgmt_frame. */
+
+/**
+ * lim_send_extended_chan_switch_action_frame()- function to send ECSA
+ * action frame over the air .
+ * @mac_ctx: pointer to global mac structure
+ * @peer: Destination mac.
+ * @mode: channel switch mode
+ * @new_op_class: new op class
+ * @new_channel: new channel to switch
+ * @count: channel switch count
+ *
+ * This function is called to send ECSA frame.
+ *
+ * Return: success if frame is sent else return failure
+ */
+
+QDF_STATUS
+lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
+		tSirMacAddr peer, uint8_t mode, uint8_t new_op_class,
+		uint8_t new_channel, uint8_t count, tpPESession session_entry)
+{
+	tDot11fext_channel_switch_action_frame frm;
+	uint8_t                  *frame;
+	tpSirMacMgmtHdr          mac_hdr;
+	uint32_t                 num_bytes, n_payload, status;
+	void                     *packet;
+	QDF_STATUS               qdf_status;
+	uint8_t                  txFlag = 0;
+	uint8_t                  sme_session_id = 0;
+	uint8_t                  ch_spacing;
+	tLimWiderBWChannelSwitchInfo *wide_bw_ie;
+
+	if (session_entry == NULL) {
+		pe_err("Session entry is NULL!!!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_session_id = session_entry->smeSessionId;
+
+	qdf_mem_set(&frm, sizeof(frm), 0);
+
+	frm.Category.category     = SIR_MAC_ACTION_PUBLIC_USAGE;
+	frm.Action.action         = SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID;
+
+	frm.ext_chan_switch_ann_action.switch_mode = mode;
+	frm.ext_chan_switch_ann_action.op_class = new_op_class;
+	frm.ext_chan_switch_ann_action.new_channel = new_channel;
+	frm.ext_chan_switch_ann_action.switch_count = count;
+
+	ch_spacing = wlan_reg_dmn_get_chanwidth_from_opclass(
+			mac_ctx->scan.countryCodeCurrent, new_channel,
+			new_op_class);
+	pe_debug("wrapper: ch_spacing %hu", ch_spacing);
+
+	if ((ch_spacing == 80) || (ch_spacing == 160)) {
+		wide_bw_ie = &session_entry->gLimWiderBWChannelSwitch;
+		frm.WiderBWChanSwitchAnn.newChanWidth =
+			wide_bw_ie->newChanWidth;
+		frm.WiderBWChanSwitchAnn.newCenterChanFreq0 =
+			wide_bw_ie->newCenterChanFreq0;
+		frm.WiderBWChanSwitchAnn.newCenterChanFreq1 =
+			wide_bw_ie->newCenterChanFreq1;
+		frm.WiderBWChanSwitchAnn.present = 1;
+		pe_debug("wrapper: width:%d f0:%d f1:%d",
+			 frm.WiderBWChanSwitchAnn.newChanWidth,
+			 frm.WiderBWChanSwitchAnn.newCenterChanFreq0,
+			 frm.WiderBWChanSwitchAnn.newCenterChanFreq1);
+	}
+
+	status = dot11f_get_packed_ext_channel_switch_action_frame_size(mac_ctx,
+							    &frm, &n_payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to get packed size for Channel Switch 0x%08x",
+				 status);
+		/* We'll fall back on the worst case scenario*/
+		n_payload = sizeof(tDot11fext_channel_switch_action_frame);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while calculating the packed size for a Ext Channel Switch (0x%08x)",
+		 status);
+	}
+
+	num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status = cds_packet_alloc((uint16_t)num_bytes,
+				(void **) &frame, (void **) &packet);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a Ext Channel Switch",
+								 num_bytes);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Paranoia*/
+	qdf_mem_set(frame, num_bytes, 0);
+
+	/* Next, we fill out the buffer descriptor */
+	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
+	mac_hdr = (tpSirMacMgmtHdr) frame;
+	qdf_mem_copy((uint8_t *) mac_hdr->bssId,
+				   (uint8_t *) session_entry->bssId,
+				   sizeof(tSirMacAddr));
+
+	lim_set_protected_bit(mac_ctx, session_entry, peer, mac_hdr);
+
+	status = dot11f_pack_ext_channel_switch_action_frame(mac_ctx, &frm,
+		frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to pack a Channel Switch 0x%08x", status);
+		cds_packet_free((void *)packet);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while packing a Channel Switch 0x%08x",
+		 status);
+	}
+
+	if ((BAND_5G ==
+		lim_get_rf_band(session_entry->currentOperChannel)) ||
+		(session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
+		(session_entry->pePersona == QDF_P2P_GO_MODE)) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	pe_debug("Send Ext channel Switch to :"MAC_ADDRESS_STR" with swcount %d, swmode %d , newchannel %d newops %d",
+		MAC_ADDR_ARRAY(mac_hdr->da),
+		frm.ext_chan_switch_ann_action.switch_count,
+		frm.ext_chan_switch_ann_action.switch_mode,
+		frm.ext_chan_switch_ann_action.new_channel,
+			 frm.ext_chan_switch_ann_action.op_class);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			session_entry->peSessionId, mac_hdr->fc.subType));
+	qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) num_bytes,
+						 TXRX_FRM_802_11_MGMT,
+						 ANI_TXDIR_TODS,
+						 7,
+						 lim_tx_complete, frame,
+						 txFlag, sme_session_id, 0,
+						 RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			session_entry->peSessionId, qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to send a Ext Channel Switch %X!",
+							 qdf_status);
+		/* Pkt will be freed up by the callback */
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+} /* End lim_send_extended_chan_switch_action_frame */
+
+
+/**
+ * lim_oper_chan_change_confirm_tx_complete_cnf()- Confirmation for oper_chan_change_confirm
+ * sent over the air
+ *
+ * @context: pointer to global mac
+ * @buf: buffer
+ * @tx_complete : Sent status
+ * @params: tx completion params
+ *
+ * Return: This returns QDF_STATUS
+ */
+
+static QDF_STATUS lim_oper_chan_change_confirm_tx_complete_cnf(
+			void *context,
+			qdf_nbuf_t buf,
+			uint32_t tx_complete,
+			void *params)
+{
+	pe_debug("tx_complete: %d", tx_complete);
+	if (buf)
+		qdf_nbuf_free(buf);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_p2p_oper_chan_change_confirm_action_frame()- function to send
+ * p2p oper chan change confirm action frame
+ * @mac_ctx: pointer to global mac structure
+ * @peer: Destination mac.
+ * @session_entry: session entry
+ *
+ * This function is called to send p2p oper chan change confirm action frame.
+ *
+ * Return: success if frame is sent else return failure
+ */
+
+QDF_STATUS
+lim_p2p_oper_chan_change_confirm_action_frame(tpAniSirGlobal mac_ctx,
+		tSirMacAddr peer, tpPESession session_entry)
+{
+	tDot11fp2p_oper_chan_change_confirm frm;
+	uint8_t                  *frame;
+	tpSirMacMgmtHdr          mac_hdr;
+	uint32_t                 num_bytes, n_payload, status;
+	void                     *packet;
+	QDF_STATUS               qdf_status;
+	uint8_t                  tx_flag = 0;
+	uint8_t                  sme_session_id = 0;
+
+	if (session_entry == NULL) {
+		pe_err("Session entry is NULL!!!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_session_id = session_entry->smeSessionId;
+
+	qdf_mem_set(&frm, sizeof(frm), 0);
+
+	frm.Category.category     = SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY;
+
+	qdf_mem_copy(frm.p2p_action_oui.oui_data,
+		SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
+	frm.p2p_action_subtype.subtype = 0x04;
+	frm.DialogToken.token = 0x0;
+
+	if (session_entry->htCapability) {
+		pe_debug("Populate HT Caps in Assoc Request");
+		populate_dot11f_ht_caps(mac_ctx, session_entry, &frm.HTCaps);
+	}
+
+	if (session_entry->vhtCapability) {
+		pe_debug("Populate VHT Caps in Assoc Request");
+		populate_dot11f_vht_caps(mac_ctx, session_entry, &frm.VHTCaps);
+		populate_dot11f_operating_mode(mac_ctx,
+					&frm.OperatingMode, session_entry);
+	}
+
+	status = dot11f_get_packed_p2p_oper_chan_change_confirmSize(mac_ctx,
+							    &frm, &n_payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to get packed size 0x%08x", status);
+		/* We'll fall back on the worst case scenario*/
+		n_payload = sizeof(tDot11fp2p_oper_chan_change_confirm);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while calculating the packed size (0x%08x)",
+			status);
+	}
+
+	num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status = cds_packet_alloc((uint16_t)num_bytes,
+				(void **) &frame, (void **) &packet);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes", num_bytes);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_set(frame, num_bytes, 0);
+
+	/* Next, fill out the buffer descriptor */
+	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
+	mac_hdr = (tpSirMacMgmtHdr) frame;
+	qdf_mem_copy((uint8_t *) mac_hdr->bssId,
+				   (uint8_t *) session_entry->bssId,
+				   sizeof(tSirMacAddr));
+
+	status = dot11f_pack_p2p_oper_chan_change_confirm(mac_ctx, &frm,
+		frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to pack 0x%08x", status);
+		cds_packet_free((void *)packet);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while packing 0x%08x",
+		 status);
+	}
+
+	if ((BAND_5G ==
+		lim_get_rf_band(session_entry->currentOperChannel)) ||
+		(session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
+		(session_entry->pePersona == QDF_P2P_GO_MODE)) {
+		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+	pe_debug("Send frame on channel %d to mac "
+		MAC_ADDRESS_STR, session_entry->currentOperChannel,
+		MAC_ADDR_ARRAY(peer));
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			session_entry->peSessionId, mac_hdr->fc.subType));
+
+	qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
+			(uint16_t)num_bytes,
+			TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
+			7, lim_tx_complete, frame,
+			lim_oper_chan_change_confirm_tx_complete_cnf,
+			tx_flag, sme_session_id, false, 0, RATEID_DEFAULT);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			session_entry->peSessionId, qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to send status %X!", qdf_status);
+		/* Pkt will be freed up by the callback */
+		return QDF_STATUS_E_FAILURE;
+	}
+		return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS
+lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
+				       tSirMacAddr peer,
+				       uint8_t nMode, tpPESession psessionEntry)
+{
+	tDot11fOperatingMode frm;
+	uint8_t *pFrame;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint8_t txFlag = 0;
+
+	uint8_t smeSessionId = 0;
+
+	if (psessionEntry == NULL) {
+		pe_err("Session entry is NULL!!!");
+		return QDF_STATUS_E_FAILURE;
+	}
+	smeSessionId = psessionEntry->smeSessionId;
+
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+	frm.Category.category = SIR_MAC_ACTION_VHT;
+	frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
+	frm.OperatingMode.chanWidth = nMode;
+	frm.OperatingMode.rxNSS = 0;
+	frm.OperatingMode.rxNSSType = 0;
+
+	nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a Operating Mode (0x%08x)",
+			nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fOperatingMode);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for a Operating Mode (0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status =
+		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				 (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a Operating Mode Report",
+			nBytes);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	if (psessionEntry->pePersona == QDF_SAP_MODE)
+		lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+			SIR_MAC_MGMT_ACTION, peer,
+			psessionEntry->selfMacAddr);
+	else
+		lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+			SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
+			psessionEntry->selfMacAddr);
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+	qdf_mem_copy((uint8_t *) pMacHdr->bssId,
+		     (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
+	nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
+					     sizeof(tSirMacMgmtHdr),
+					     nPayload, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack a Operating Mode (0x%08x)",
+			nStatus);
+		cds_packet_free((void *)pPacket);
+		return QDF_STATUS_E_FAILURE;    /* allocated! */
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing a Operating Mode (0x%08x)",
+			nStatus);
+	}
+	if ((BAND_5G == lim_get_rf_band(psessionEntry->currentOperChannel))
+	    || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)
+	    ) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 psessionEntry->peSessionId, pMacHdr->fc.subType));
+	qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, pFrame, txFlag,
+				smeSessionId, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			 psessionEntry->peSessionId, qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to send a Channel Switch (%X)!",
+			qdf_status);
+		/* Pkt will be freed up by the callback */
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * \brief Send a Neighbor Report Request Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pNeighborReq Address of a tSirMacNeighborReportReq
+ *
+ * \param peer mac address of peer station.
+ *
+ * \param psessionEntry address of session entry.
+ *
+ * \return QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE else
+ *
+ *
+ */
+
+QDF_STATUS
+lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
+				       tpSirMacNeighborReportReq pNeighborReq,
+				       tSirMacAddr peer, tpPESession psessionEntry)
+{
+	QDF_STATUS statusCode = QDF_STATUS_SUCCESS;
+	tDot11fNeighborReportRequest frm;
+	uint8_t *pFrame;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload, nStatus;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint8_t txFlag = 0;
+	uint8_t smeSessionId = 0;
+
+	if (psessionEntry == NULL) {
+		pe_err("(psession == NULL) in Request to send Neighbor Report request action frame");
+		return QDF_STATUS_E_FAILURE;
+	}
+	smeSessionId = psessionEntry->smeSessionId;
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+	frm.Category.category = SIR_MAC_ACTION_RRM;
+	frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
+	frm.DialogToken.token = pNeighborReq->dialogToken;
+
+	if (pNeighborReq->ssid_present) {
+		populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
+	}
+
+	nStatus =
+		dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a Neighbor Report Request(0x%08x)",
+			nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fNeighborReportRequest);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for a Neighbor Report Request(0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status =
+		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				 (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a Neighbor "
+			   "Report Request", nBytes);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Copy necessary info to BD */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+
+	/* Update A3 with the BSSID */
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	/* Now, we're ready to "pack" the frames */
+	nStatus = dot11f_pack_neighbor_report_request(pMac,
+						      &frm,
+						      pFrame +
+						      sizeof(tSirMacMgmtHdr),
+						      nPayload, &nPayload);
+
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack an Neighbor Report Request (0x%08x)",
+			nStatus);
+
+		/* FIXME - Need to convert to QDF_STATUS */
+		statusCode = QDF_STATUS_E_FAILURE;
+		goto returnAfterError;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing Neighbor Report Request (0x%08x)",
+			nStatus);
+	}
+
+	pe_debug("Sending a Neighbor Report Request to");
+	lim_print_mac_addr(pMac, peer, LOGD);
+
+	if ((BAND_5G == lim_get_rf_band(psessionEntry->currentOperChannel))
+	    || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)
+	    ) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 psessionEntry->peSessionId, pMacHdr->fc.subType));
+	qdf_status = wma_tx_frame(pMac,
+				pPacket,
+				(uint16_t) nBytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, pFrame, txFlag,
+				smeSessionId, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			 psessionEntry->peSessionId, qdf_status));
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
+		statusCode = QDF_STATUS_E_FAILURE;
+		/* Pkt will be freed up by the callback */
+		return statusCode;
+	} else
+		return QDF_STATUS_SUCCESS;
+
+returnAfterError:
+	cds_packet_free((void *)pPacket);
+
+	return statusCode;
+} /* End lim_send_neighbor_report_request_frame. */
+
+/**
+ * \brief Send a Link Report Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pLinkReport Address of a tSirMacLinkReport
+ *
+ * \param peer mac address of peer station.
+ *
+ * \param psessionEntry address of session entry.
+ *
+ * \return QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE else
+ *
+ *
+ */
+
+QDF_STATUS
+lim_send_link_report_action_frame(tpAniSirGlobal pMac,
+				  tpSirMacLinkReport pLinkReport,
+				  tSirMacAddr peer, tpPESession psessionEntry)
+{
+	QDF_STATUS statusCode = QDF_STATUS_SUCCESS;
+	tDot11fLinkMeasurementReport frm;
+	uint8_t *pFrame;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload, nStatus;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint8_t txFlag = 0;
+	uint8_t smeSessionId = 0;
+
+	if (psessionEntry == NULL) {
+		pe_err("(psession == NULL) in Request to send Link Report action frame");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+	frm.Category.category = SIR_MAC_ACTION_RRM;
+	frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
+	frm.DialogToken.token = pLinkReport->dialogToken;
+
+	/* IEEE Std. 802.11 7.3.2.18. for the report element. */
+	/* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
+	/* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
+	/* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
+	/* such case this way than changing the frame parser. */
+	frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
+	frm.TPCEleLen.TPCLen = 2;
+	frm.TxPower.txPower = pLinkReport->txPower;
+	frm.LinkMargin.linkMargin = 0;
+
+	frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
+	frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
+	frm.RCPI.rcpi = pLinkReport->rcpi;
+	frm.RSNI.rsni = pLinkReport->rsni;
+
+	nStatus =
+		dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a Link Report (0x%08x)", nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fLinkMeasurementReport);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for a Link Report (0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status =
+		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				 (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a Link "
+			"Report", nBytes);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Copy necessary info to BD */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+
+	/* Update A3 with the BSSID */
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	/* Now, we're ready to "pack" the frames */
+	nStatus = dot11f_pack_link_measurement_report(pMac,
+						      &frm,
+						      pFrame +
+						      sizeof(tSirMacMgmtHdr),
+						      nPayload, &nPayload);
+
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack an Link Report (0x%08x)", nStatus);
+
+		/* FIXME - Need to convert to QDF_STATUS */
+		statusCode = QDF_STATUS_E_FAILURE;
+		goto returnAfterError;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing Link Report (0x%08x)",
+			nStatus);
+	}
+
+	pe_warn("Sending a Link Report to");
+	lim_print_mac_addr(pMac, peer, LOGW);
+
+	if ((BAND_5G == lim_get_rf_band(psessionEntry->currentOperChannel))
+	    || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 psessionEntry->peSessionId, pMacHdr->fc.subType));
+	qdf_status = wma_tx_frame(pMac,
+				pPacket,
+				(uint16_t) nBytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, pFrame, txFlag,
+				smeSessionId, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			 psessionEntry->peSessionId, qdf_status));
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
+		statusCode = QDF_STATUS_E_FAILURE;
+		/* Pkt will be freed up by the callback */
+		return statusCode;
+	} else
+		return QDF_STATUS_SUCCESS;
+
+returnAfterError:
+	cds_packet_free((void *)pPacket);
+
+	return statusCode;
+} /* End lim_send_link_report_action_frame. */
+
+QDF_STATUS
+lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
+				uint8_t dialog_token,
+				uint8_t num_report,
+				struct rrm_beacon_report_last_beacon_params
+				*last_beacon_report_params,
+				tpSirMacRadioMeasureReport pRRMReport,
+				tSirMacAddr peer,
+				tpPESession psessionEntry)
+{
+	QDF_STATUS statusCode = QDF_STATUS_SUCCESS;
+	uint8_t *pFrame;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload, nStatus;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint8_t i;
+	uint8_t txFlag = 0;
+	uint8_t smeSessionId = 0;
+
+	tDot11fRadioMeasurementReport *frm =
+		qdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
+	if (!frm)
+		return QDF_STATUS_E_NOMEM;
+
+	if (psessionEntry == NULL) {
+		pe_err("(psession == NULL) in Request to send Beacon Report action frame");
+		qdf_mem_free(frm);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	smeSessionId = psessionEntry->smeSessionId;
+
+	pe_debug("dialog_token %d num_report %d",
+			dialog_token, num_report);
+
+	frm->Category.category = SIR_MAC_ACTION_RRM;
+	frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
+	frm->DialogToken.token = dialog_token;
+
+	frm->num_MeasurementReport =
+		(num_report >
+		 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
+		num_report;
+
+	for (i = 0; i < frm->num_MeasurementReport; i++) {
+		frm->MeasurementReport[i].type = pRRMReport[i].type;
+		frm->MeasurementReport[i].token = pRRMReport[i].token;
+		frm->MeasurementReport[i].late = 0;     /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
+		switch (pRRMReport[i].type) {
+		case SIR_MAC_RRM_BEACON_TYPE:
+			populate_dot11f_beacon_report(pMac,
+						     &frm->MeasurementReport[i],
+						     &pRRMReport[i].report.
+						     beaconReport,
+						     last_beacon_report_params);
+			frm->MeasurementReport[i].incapable =
+				pRRMReport[i].incapable;
+			frm->MeasurementReport[i].refused =
+				pRRMReport[i].refused;
+			frm->MeasurementReport[i].present = 1;
+			break;
+		default:
+			frm->MeasurementReport[i].incapable =
+				pRRMReport[i].incapable;
+			frm->MeasurementReport[i].refused =
+				pRRMReport[i].refused;
+			frm->MeasurementReport[i].present = 1;
+			break;
+		}
+	}
+
+	nStatus =
+		dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a Radio Measure Report (0x%08x)",
+			nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fLinkMeasurementReport);
+		qdf_mem_free(frm);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for a Radio Measure Report (0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	qdf_status =
+		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+				 (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a Radio Measure "
+			   "Report", nBytes);
+		qdf_mem_free(frm);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Copy necessary info to BD */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+
+	/* Update A3 with the BSSID */
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	/* Now, we're ready to "pack" the frames */
+	nStatus = dot11f_pack_radio_measurement_report(pMac,
+						       frm,
+						       pFrame +
+						       sizeof(tSirMacMgmtHdr),
+						       nPayload, &nPayload);
+
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack an Radio Measure Report (0x%08x)",
+			nStatus);
+
+		/* FIXME - Need to convert to QDF_STATUS */
+		statusCode = QDF_STATUS_E_FAILURE;
+		goto returnAfterError;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing Radio Measure Report (0x%08x)",
+			nStatus);
+	}
+
+	pe_warn("Sending a Radio Measure Report to");
+	lim_print_mac_addr(pMac, peer, LOGW);
+
+	if ((BAND_5G == lim_get_rf_band(psessionEntry->currentOperChannel))
+	    || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)
+	    ) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 psessionEntry->peSessionId, pMacHdr->fc.subType));
+	qdf_status = wma_tx_frame(pMac,
+				pPacket,
+				(uint16_t) nBytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, pFrame, txFlag,
+				smeSessionId, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			 psessionEntry->peSessionId, qdf_status));
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
+		statusCode = QDF_STATUS_E_FAILURE;
+		/* Pkt will be freed up by the callback */
+		qdf_mem_free(frm);
+		return statusCode;
+	} else {
+		qdf_mem_free(frm);
+		return QDF_STATUS_SUCCESS;
+	}
+
+returnAfterError:
+	qdf_mem_free(frm);
+	cds_packet_free((void *)pPacket);
+	return statusCode;
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * \brief Send SA query request action frame to peer
+ *
+ * \sa lim_send_sa_query_request_frame
+ *
+ *
+ * \param pMac    The global tpAniSirGlobal object
+ *
+ * \param transId Transaction identifier
+ *
+ * \param peer    The Mac address of the station to which this action frame is addressed
+ *
+ * \param psessionEntry The PE session entry
+ *
+ * \return QDF_STATUS_SUCCESS if setup completes successfully
+ *         QDF_STATUS_E_FAILURE is some problem is encountered
+ */
+
+QDF_STATUS lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
+					      tSirMacAddr peer,
+					      tpPESession psessionEntry)
+{
+
+	tDot11fSaQueryReq frm;  /* SA query request action frame */
+	uint8_t *pFrame;
+	QDF_STATUS nSirStatus;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload, nStatus;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint8_t txFlag = 0;
+	uint8_t smeSessionId = 0;
+
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+	frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
+	/* 11w action  field is :
+	   action: 0 --> SA Query Request action frame
+	   action: 1 --> SA Query Response action frame */
+	frm.Action.action = SIR_MAC_SA_QUERY_REQ;
+	/* 11w SA Query Request transId */
+	qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
+
+	nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for an SA Query Request (0x%08x)",
+			nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fSaQueryReq);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for an SA Query Request (0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+	qdf_status =
+		cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a SA Query Request "
+			   "action frame", nBytes);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Copy necessary info to BD */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+
+	/* Update A3 with the BSSID */
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+	/* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
+	/* in the FC */
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	/* Pack 11w SA Query Request frame */
+	nStatus = dot11f_pack_sa_query_req(pMac,
+					   &frm,
+					   pFrame + sizeof(tSirMacMgmtHdr),
+					   nPayload, &nPayload);
+
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack an SA Query Request (0x%08x)",
+			nStatus);
+		/* FIXME - Need to convert to QDF_STATUS */
+		nSirStatus = QDF_STATUS_E_FAILURE;
+		goto returnAfterError;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing SA Query Request (0x%08x)",
+			nStatus);
+	}
+
+	pe_debug("Sending an SA Query Request to");
+	lim_print_mac_addr(pMac, peer, LOGD);
+	pe_debug("Sending an SA Query Request from ");
+	lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOGD);
+
+	if ((BAND_5G == lim_get_rf_band(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+	    || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)
+#endif
+	    ) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+	smeSessionId = psessionEntry->smeSessionId;
+
+	qdf_status = wma_tx_frame(pMac,
+				pPacket,
+				(uint16_t) nBytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, pFrame, txFlag,
+				smeSessionId, 0, RATEID_DEFAULT);
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
+		nSirStatus = QDF_STATUS_E_FAILURE;
+		/* Pkt will be freed up by the callback */
+		return nSirStatus;
+	} else {
+		return QDF_STATUS_SUCCESS;
+	}
+
+returnAfterError:
+	cds_packet_free((void *)pPacket);
+	return nSirStatus;
+} /* End lim_send_sa_query_request_frame */
+
+/**
+ * \brief Send SA query response action frame to peer
+ *
+ * \sa lim_send_sa_query_response_frame
+ *
+ *
+ * \param pMac    The global tpAniSirGlobal object
+ *
+ * \param transId Transaction identifier received in SA query request action frame
+ *
+ * \param peer    The Mac address of the AP to which this action frame is addressed
+ *
+ * \param psessionEntry The PE session entry
+ *
+ * \return QDF_STATUS_SUCCESS if setup completes successfully
+ *         QDF_STATUS_E_FAILURE is some problem is encountered
+ */
+
+QDF_STATUS lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
+					       uint8_t *transId, tSirMacAddr peer,
+					       tpPESession psessionEntry)
+{
+
+	tDot11fSaQueryRsp frm;  /* SA query response action frame */
+	uint8_t *pFrame;
+	QDF_STATUS nSirStatus;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t nBytes, nPayload, nStatus;
+	void *pPacket;
+	QDF_STATUS qdf_status;
+	uint8_t txFlag = 0;
+	uint8_t smeSessionId = 0;
+
+	smeSessionId = psessionEntry->smeSessionId;
+
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+	frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
+	/*11w action  field is :
+	   action: 0 --> SA query request action frame
+	   action: 1 --> SA query response action frame */
+	frm.Action.action = SIR_MAC_SA_QUERY_RSP;
+	/*11w SA query response transId is same as
+	   SA query request transId */
+	qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
+
+	nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a SA Query Response (0x%08x)",
+			nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fSaQueryRsp);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while calculating the packed size for an SA Query Response (0x%08x)",
+			nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+	qdf_status =
+		cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("Failed to allocate %d bytes for a SA query response"
+			   " action frame", nBytes);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Paranoia: */
+	qdf_mem_set(pFrame, nBytes, 0);
+
+	/* Copy necessary info to BD */
+	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+
+	/* Update A3 with the BSSID */
+	pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+	/* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
+	/* in the FC */
+	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+	/* Pack 11w SA query response frame */
+	nStatus = dot11f_pack_sa_query_rsp(pMac,
+					   &frm,
+					   pFrame + sizeof(tSirMacMgmtHdr),
+					   nPayload, &nPayload);
+
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack an SA Query Response (0x%08x)",
+			nStatus);
+		/* FIXME - Need to convert to QDF_STATUS */
+		nSirStatus = QDF_STATUS_E_FAILURE;
+		goto returnAfterError;
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing SA Query Response (0x%08x)",
+			nStatus);
+	}
+
+	pe_debug("Sending a SA Query Response to");
+	lim_print_mac_addr(pMac, peer, LOGD);
+
+	if ((BAND_5G == lim_get_rf_band(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+	    || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)
+#endif
+	    ) {
+		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 psessionEntry->peSessionId, pMacHdr->fc.subType));
+	qdf_status = wma_tx_frame(pMac,
+				pPacket,
+				(uint16_t) nBytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, pFrame, txFlag,
+				smeSessionId, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			 psessionEntry->peSessionId, qdf_status));
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
+		nSirStatus = QDF_STATUS_E_FAILURE;
+		/* Pkt will be freed up by the callback */
+		return nSirStatus;
+	} else {
+		return QDF_STATUS_SUCCESS;
+	}
+
+returnAfterError:
+	cds_packet_free((void *)pPacket);
+	return nSirStatus;
+} /* End lim_send_sa_query_response_frame */
+#endif
+
+/**
+ * lim_send_addba_response_frame(): Send ADDBA response action frame to peer
+ * @mac_ctx: mac context
+ * @peer_mac: Peer MAC address
+ * @tid: TID for which addba response is being sent
+ * @session: PE session entry
+ * @addba_extn_present: ADDBA extension present flag
+ * @amsdu_support: amsdu in ampdu support
+ *
+ * This function is called when ADDBA request is successful. ADDBA response is
+ * setup by calling addba_response_setup API and frame is then sent out OTA.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_send_addba_response_frame(tpAniSirGlobal mac_ctx,
+		tSirMacAddr peer_mac, uint16_t tid,
+		tpPESession session, uint8_t addba_extn_present,
+		uint8_t amsdu_support)
+{
+
+	tDot11faddba_rsp frm;
+	uint8_t *frame_ptr;
+	tpSirMacMgmtHdr mgmt_hdr;
+	uint32_t num_bytes, payload_size, status;
+	void *pkt_ptr = NULL;
+	QDF_STATUS qdf_status;
+	uint8_t tx_flag = 0;
+	uint8_t sme_sessionid = 0;
+	uint16_t buff_size, status_code, batimeout;
+	uint8_t peer_id, dialog_token;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *peer, *pdev;
+	uint8_t he_frag = 0;
+
+	sme_sessionid = session->smeSessionId;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		pe_err("pdev is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	peer = cdp_peer_get_ref_by_addr(soc, pdev, peer_mac, &peer_id,
+					PEER_DEBUG_ID_LIM_SEND_ADDBA_RESP);
+	if (!peer) {
+		pe_err("PEER [%pM] not found", peer_mac);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cdp_addba_responsesetup(soc, peer, tid, &dialog_token,
+		&status_code, &buff_size, &batimeout);
+
+	cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_LIM_SEND_ADDBA_RESP);
+	qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+	frm.Category.category = SIR_MAC_ACTION_BLKACK;
+	frm.Action.action = SIR_MAC_ADDBA_RSP;
+
+	frm.DialogToken.token = dialog_token;
+	frm.Status.status = status_code;
+	if (mac_ctx->reject_addba_req) {
+		frm.Status.status = eSIR_MAC_REQ_DECLINED_STATUS;
+		pe_err("refused addba req");
+	}
+	frm.addba_param_set.tid = tid;
+	frm.addba_param_set.buff_size = SIR_MAC_BA_DEFAULT_BUFF_SIZE;
+	if (mac_ctx->usr_cfg_ba_buff_size)
+		frm.addba_param_set.buff_size = mac_ctx->usr_cfg_ba_buff_size;
+
+	if (frm.addba_param_set.buff_size > MAX_BA_BUFF_SIZE)
+		frm.addba_param_set.buff_size = MAX_BA_BUFF_SIZE;
+
+	if (frm.addba_param_set.buff_size > SIR_MAC_BA_DEFAULT_BUFF_SIZE) {
+		if (session->active_ba_64_session) {
+			frm.addba_param_set.buff_size =
+				SIR_MAC_BA_DEFAULT_BUFF_SIZE;
+		}
+	} else if (!session->active_ba_64_session) {
+		session->active_ba_64_session = true;
+	}
+	if (mac_ctx->is_usr_cfg_amsdu_enabled)
+		frm.addba_param_set.amsdu_supp = amsdu_support;
+	else
+		frm.addba_param_set.amsdu_supp = 0;
+	frm.addba_param_set.policy = SIR_MAC_BA_POLICY_IMMEDIATE;
+	frm.ba_timeout.timeout = batimeout;
+	if (addba_extn_present) {
+		frm.addba_extn_element.present = 1;
+		frm.addba_extn_element.no_fragmentation = 1;
+		if (lim_is_session_he_capable(session)) {
+			he_frag = lim_get_session_he_frag_cap(session);
+			if (he_frag != 0) {
+				frm.addba_extn_element.no_fragmentation = 0;
+				frm.addba_extn_element.he_frag_operation =
+					he_frag;
+			}
+		}
+	}
+
+	pe_debug("Sending a ADDBA Response from %pM to %pM",
+		session->selfMacAddr, peer_mac);
+	pe_debug("tid: %d, dialog_token: %d, status: %d, buff_size: %d",
+		tid, frm.DialogToken.token, frm.Status.status,
+		frm.addba_param_set.buff_size);
+	pe_debug("addba_extn %d he_capable %d no_frag %d he_frag %d",
+		addba_extn_present,
+		lim_is_session_he_capable(session),
+		frm.addba_extn_element.no_fragmentation,
+		frm.addba_extn_element.he_frag_operation);
+
+	status = dot11f_get_packed_addba_rsp_size(mac_ctx, &frm, &payload_size);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to calculate the packed size for a ADDBA Response (0x%08x).",
+			status);
+		/* We'll fall back on the worst case scenario: */
+		payload_size = sizeof(tDot11faddba_rsp);
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while calculating the packed size for a ADDBA Response (0x%08x).", status);
+	}
+
+	num_bytes = payload_size + sizeof(*mgmt_hdr);
+	qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr,
+				      (void **)&pkt_ptr);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status) || (!pkt_ptr)) {
+		pe_err("Failed to allocate %d bytes for a ADDBA response action frame",
+			num_bytes);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_set(frame_ptr, num_bytes, 0);
+
+	lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_ACTION, peer_mac, session->selfMacAddr);
+
+	/* Update A3 with the BSSID */
+	mgmt_hdr = (tpSirMacMgmtHdr) frame_ptr;
+	sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId);
+
+	/* ADDBA Response is a robust mgmt action frame,
+	 * set the "protect" (aka WEP) bit in the FC
+	 */
+	lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr);
+
+	status = dot11f_pack_addba_rsp(mac_ctx, &frm,
+			frame_ptr + sizeof(tSirMacMgmtHdr), payload_size,
+			&payload_size);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to pack a ADDBA Response (0x%08x)",
+			status);
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto error_addba_rsp;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("There were warnings while packing ADDBA Response (0x%08x)",
+			status);
+	}
+
+
+	if ((BAND_5G == lim_get_rf_band(session->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+	    || (session->pePersona == QDF_P2P_CLIENT_MODE) ||
+	    (session->pePersona == QDF_P2P_GO_MODE)
+#endif
+	    ) {
+		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+			 session->peSessionId, mgmt_hdr->fc.subType));
+	qdf_status = wma_tx_frameWithTxComplete(mac_ctx, pkt_ptr,
+						(uint16_t)num_bytes,
+						TXRX_FRM_802_11_MGMT,
+						ANI_TXDIR_TODS, 7,
+						NULL, frame_ptr,
+						lim_addba_rsp_tx_complete_cnf,
+						tx_flag, sme_sessionid,
+						false, 0, RATEID_DEFAULT);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+			 session->peSessionId, qdf_status));
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		pe_err("wma_tx_frame FAILED! Status [%d]",
+			qdf_status);
+		qdf_status = QDF_STATUS_E_FAILURE;
+		/*
+		 * wma_tx_frame free memory in certain cases, free pkt_ptr
+		 * only if not freed already.
+		 */
+		if (pkt_ptr)
+			cds_packet_free((void *)pkt_ptr);
+		return qdf_status;
+	} else {
+		return QDF_STATUS_SUCCESS;
+	}
+
+error_addba_rsp:
+	cds_packet_free((void *)pkt_ptr);
+	return qdf_status;
+}
+
+/**
+ * lim_tx_mgmt_frame() - Transmits Auth mgmt frame
+ * @mac_ctx Pointer to Global MAC structure
+ * @mb_msg: Received message info
+ * @msg_len: Received message length
+ * @packet: Packet to be transmitted
+ * @frame: Received frame
+ *
+ * Return: None
+ */
+static void lim_tx_mgmt_frame(tpAniSirGlobal mac_ctx,
+	struct sir_mgmt_msg *mb_msg, uint32_t msg_len,
+	void *packet, uint8_t *frame)
+{
+	tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
+	QDF_STATUS qdf_status;
+	uint8_t sme_session_id = 0;
+	tpPESession session;
+	uint16_t auth_ack_status;
+	enum rateid min_rid = RATEID_DEFAULT;
+
+	sme_session_id = mb_msg->session_id;
+	session = pe_find_session_by_sme_session_id(mac_ctx, sme_session_id);
+	if (session == NULL) {
+		pe_err("session not found for given sme session");
+		return;
+	}
+
+	qdf_mtrace(QDF_MODULE_ID_PE, QDF_MODULE_ID_WMA, TRACE_CODE_TX_MGMT,
+		   session->peSessionId, 0);
+
+	mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
+	min_rid = lim_get_min_session_txrate(session);
+
+	qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
+					 (uint16_t)msg_len,
+					 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
+					 7, lim_tx_complete, frame,
+					 lim_auth_tx_complete_cnf,
+					 0, sme_session_id, false, 0, min_rid);
+	MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+		session->peSessionId, qdf_status));
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("*** Could not send Auth frame (subType: %d), retCode=%X ***",
+			fc->subType, qdf_status);
+		mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
+		auth_ack_status = SENT_FAIL;
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT,
+				session, auth_ack_status, QDF_STATUS_E_FAILURE);
+		/* Pkt will be freed up by the callback */
+	}
+}
+
+void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx,
+		struct scheduler_msg *msg)
+{
+	struct sir_mgmt_msg *mb_msg = (struct sir_mgmt_msg *)msg->bodyptr;
+	uint32_t msg_len;
+	tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
+	uint8_t sme_session_id;
+	QDF_STATUS qdf_status;
+	uint8_t *frame;
+	void *packet;
+
+	msg_len = mb_msg->msg_len - sizeof(*mb_msg);
+	pe_debug("sending fc->type: %d fc->subType: %d",
+		fc->type, fc->subType);
+
+	sme_session_id = mb_msg->session_id;
+
+	qdf_status = cds_packet_alloc((uint16_t) msg_len, (void **)&frame,
+				 (void **)&packet);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		pe_err("call to bufAlloc failed for AUTH frame");
+		return;
+	}
+
+	qdf_mem_copy(frame, mb_msg->data, msg_len);
+
+	lim_tx_mgmt_frame(mac_ctx, mb_msg, msg_len, packet, frame);
+}
diff --git a/core/mac/src/pe/lim/lim_send_messages.c b/core/mac/src/pe/lim/lim_send_messages.c
new file mode 100644
index 0000000..447aa67
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_messages.c
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * lim_send_messages.c: Provides functions to send messages or Indications to HAL.
+ * Author:    Sunit Bhatia
+ * Date:       09/21/2006
+ * History:-
+ * Date        Modified by            Modification Information
+ *
+ * --------------------------------------------------------------------------
+ *
+ */
+#include "lim_send_messages.h"
+#include "cfg_api.h"
+#include "lim_trace.h"
+#include "wlan_reg_services_api.h"
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+#include "host_diag_core_log.h"
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+#include "lim_utils.h"
+
+/**
+ * lim_send_cf_params()
+ *
+ ***FUNCTION:
+ * This function is called to send CFP Parameters to WMA, when they are changed.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac  pointer to Global Mac structure.
+ * @param bssIdx Bss Index of the BSS to which STA is associated.
+ * @param cfpCount CFP Count, if that is changed.
+ * @param cfpPeriod CFP Period if that is changed.
+ *
+ * @return success if message send is ok, else false.
+ */
+QDF_STATUS lim_send_cf_params(tpAniSirGlobal pMac, uint8_t bssIdx,
+				 uint8_t cfpCount, uint8_t cfpPeriod)
+{
+	tpUpdateCFParams pCFParams = NULL;
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msgQ = {0};
+
+	pCFParams = qdf_mem_malloc(sizeof(tUpdateCFParams));
+	if (!pCFParams)
+		return QDF_STATUS_E_NOMEM;
+	pCFParams->cfpCount = cfpCount;
+	pCFParams->cfpPeriod = cfpPeriod;
+	pCFParams->bssIdx = bssIdx;
+
+	msgQ.type = WMA_UPDATE_CF_IND;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pCFParams;
+	msgQ.bodyval = 0;
+	pe_debug("Sending WMA_UPDATE_CF_IND");
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		qdf_mem_free(pCFParams);
+		pe_err("Posting WMA_UPDATE_CF_IND failed, reason=%X",
+			retCode);
+	}
+	return retCode;
+}
+
+/**
+ * lim_send_beacon_params() - updates bcn params to WMA
+ *
+ * @pMac                 : pointer to Global Mac structure.
+ * @tpUpdateBeaconParams : pointer to the structure, which contains the beacon
+ * parameters which are changed.
+ *
+ * This function is called to send beacon interval, short preamble or other
+ * parameters to WMA, which are changed and indication is received in beacon.
+ *
+ * @return success if message send is ok, else false.
+ */
+QDF_STATUS lim_send_beacon_params(tpAniSirGlobal pMac,
+				     tpUpdateBeaconParams pUpdatedBcnParams,
+				     tpPESession psessionEntry)
+{
+	tpUpdateBeaconParams pBcnParams = NULL;
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msgQ = {0};
+
+	pBcnParams = qdf_mem_malloc(sizeof(*pBcnParams));
+	if (!pBcnParams)
+		return QDF_STATUS_E_NOMEM;
+	qdf_mem_copy((uint8_t *) pBcnParams, pUpdatedBcnParams,
+		     sizeof(*pBcnParams));
+	msgQ.type = WMA_UPDATE_BEACON_IND;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pBcnParams;
+	msgQ.bodyval = 0;
+	pe_debug("Sending WMA_UPDATE_BEACON_IND, paramChangeBitmap in hex: %x",
+	       pUpdatedBcnParams->paramChangeBitmap);
+	if (NULL == psessionEntry) {
+		qdf_mem_free(pBcnParams);
+		MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+		return QDF_STATUS_E_FAILURE;
+	} else {
+		MTRACE(mac_trace_msg_tx(pMac,
+					psessionEntry->peSessionId,
+					msgQ.type));
+	}
+	pBcnParams->smeSessionId = psessionEntry->smeSessionId;
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		qdf_mem_free(pBcnParams);
+		pe_err("Posting WMA_UPDATE_BEACON_IND, reason=%X",
+			retCode);
+	}
+	lim_send_beacon_ind(pMac, psessionEntry, REASON_DEFAULT);
+	return retCode;
+}
+
+/**
+ * lim_send_switch_chnl_params()
+ *
+ ***FUNCTION:
+ * This function is called to send Channel Switch Indication to WMA
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac  pointer to Global Mac structure.
+ * @param chnlNumber New Channel Number to be switched to.
+ * @param ch_width an enum for channel width.
+ * @param localPowerConstraint 11h local power constraint value
+ *
+ * @return success if message send is ok, else false.
+ */
+QDF_STATUS lim_send_switch_chnl_params(tpAniSirGlobal pMac,
+					  uint8_t chnlNumber,
+					  uint8_t ch_center_freq_seg0,
+					  uint8_t ch_center_freq_seg1,
+					  enum phy_ch_width ch_width,
+					  int8_t maxTxPower,
+					  uint8_t peSessionId,
+					  uint8_t is_restart,
+					  uint32_t cac_duration_ms,
+					  uint32_t dfs_regdomain)
+{
+	tpSwitchChannelParams pChnlParams = NULL;
+	struct scheduler_msg msgQ = {0};
+	tpPESession pSessionEntry;
+
+	pSessionEntry = pe_find_session_by_session_id(pMac, peSessionId);
+	if (pSessionEntry == NULL) {
+		pe_err("Unable to get Session for session Id %d",
+				peSessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pChnlParams = qdf_mem_malloc(sizeof(tSwitchChannelParams));
+	if (!pChnlParams)
+		return QDF_STATUS_E_NOMEM;
+	pChnlParams->channelNumber = chnlNumber;
+	pChnlParams->ch_center_freq_seg0 = ch_center_freq_seg0;
+	pChnlParams->ch_center_freq_seg1 = ch_center_freq_seg1;
+	pChnlParams->ch_width = ch_width;
+	qdf_mem_copy(pChnlParams->selfStaMacAddr, pSessionEntry->selfMacAddr,
+		     sizeof(tSirMacAddr));
+	pChnlParams->maxTxPower = maxTxPower;
+	qdf_mem_copy(pChnlParams->bssId, pSessionEntry->bssId,
+		     sizeof(tSirMacAddr));
+	pChnlParams->peSessionId = peSessionId;
+	pChnlParams->vhtCapable = pSessionEntry->vhtCapability;
+	if (lim_is_session_he_capable(pSessionEntry))
+		lim_update_chan_he_capable(pMac, pChnlParams);
+	pChnlParams->dot11_mode = pSessionEntry->dot11mode;
+	pChnlParams->nss = pSessionEntry->nss;
+	pe_debug("dot11mode: %d, vht_capable: %d nss value: %d",
+		pChnlParams->dot11_mode, pChnlParams->vhtCapable,
+		pChnlParams->nss);
+
+	/*Set DFS flag for DFS channel */
+	if (ch_width == CH_WIDTH_160MHZ) {
+		pChnlParams->isDfsChannel = true;
+	} else if (ch_width == CH_WIDTH_80P80MHZ) {
+		pChnlParams->isDfsChannel = false;
+		if (wlan_reg_get_channel_state(pMac->pdev, chnlNumber) ==
+				CHANNEL_STATE_DFS ||
+		    wlan_reg_get_channel_state(pMac->pdev,
+			    pChnlParams->ch_center_freq_seg1 -
+				SIR_80MHZ_START_CENTER_CH_DIFF) ==
+							CHANNEL_STATE_DFS)
+			pChnlParams->isDfsChannel = true;
+	} else {
+		if (wlan_reg_get_channel_state(pMac->pdev, chnlNumber) ==
+				CHANNEL_STATE_DFS)
+			pChnlParams->isDfsChannel = true;
+		else
+			pChnlParams->isDfsChannel = false;
+	}
+
+	pChnlParams->restart_on_chan_switch = is_restart;
+	pChnlParams->cac_duration_ms = cac_duration_ms;
+	pChnlParams->dfs_regdomain = dfs_regdomain;
+	pChnlParams->reduced_beacon_interval =
+		pMac->sap.SapDfsInfo.reduced_beacon_interval;
+
+	if (cds_is_5_mhz_enabled())
+		pChnlParams->ch_width = CH_WIDTH_5MHZ;
+	else if (cds_is_10_mhz_enabled())
+		pChnlParams->ch_width = CH_WIDTH_10MHZ;
+
+	/* we need to defer the message until we
+	 * get the response back from WMA
+	 */
+	SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+	msgQ.type = WMA_CHNL_SWITCH_REQ;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pChnlParams;
+	msgQ.bodyval = 0;
+	pe_debug("Sending CH_SWITCH_REQ, ch_width %d, ch_num %d, maxTxPower %d",
+		       pChnlParams->ch_width,
+		       pChnlParams->channelNumber, pChnlParams->maxTxPower);
+	MTRACE(mac_trace_msg_tx(pMac, peSessionId, msgQ.type));
+	if (QDF_STATUS_SUCCESS != wma_post_ctrl_msg(pMac, &msgQ)) {
+		qdf_mem_free(pChnlParams);
+		pe_err("Posting  CH_SWITCH_REQ to WMA failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pSessionEntry->ch_switch_in_progress = true;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_send_edca_params()
+ *
+ ***FUNCTION:
+ * This function is called to send dynamically changing EDCA Parameters to WMA.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac  pointer to Global Mac structure.
+ * @param tpUpdatedEdcaParams pointer to the structure which contains
+ *                                       dynamically changing EDCA parameters.
+ * @param highPerformance  If the peer is Airgo (taurus) then switch to highPerformance is true.
+ *
+ * @return success if message send is ok, else false.
+ */
+QDF_STATUS lim_send_edca_params(tpAniSirGlobal pMac,
+				   tSirMacEdcaParamRecord *pUpdatedEdcaParams,
+				   uint16_t bssIdx, bool mu_edca)
+{
+	tEdcaParams *pEdcaParams = NULL;
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msgQ = {0};
+
+	pEdcaParams = qdf_mem_malloc(sizeof(tEdcaParams));
+	if (!pEdcaParams)
+		return QDF_STATUS_E_NOMEM;
+	pEdcaParams->bssIdx = bssIdx;
+	pEdcaParams->acbe = pUpdatedEdcaParams[EDCA_AC_BE];
+	pEdcaParams->acbk = pUpdatedEdcaParams[EDCA_AC_BK];
+	pEdcaParams->acvi = pUpdatedEdcaParams[EDCA_AC_VI];
+	pEdcaParams->acvo = pUpdatedEdcaParams[EDCA_AC_VO];
+	pEdcaParams->mu_edca_params = mu_edca;
+	msgQ.type = WMA_UPDATE_EDCA_PROFILE_IND;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pEdcaParams;
+	msgQ.bodyval = 0;
+	pe_debug("Sending WMA_UPDATE_EDCA_PROFILE_IND");
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		qdf_mem_free(pEdcaParams);
+		pe_err("Posting WMA_UPDATE_EDCA_PROFILE_IND failed, reason=%X",
+			retCode);
+	}
+	return retCode;
+}
+
+/**
+ * lim_set_active_edca_params() - Choose best EDCA parameters
+ *
+ * @mac_ctx:  pointer to Global Mac structure.
+ * @edca_params: pointer to the local EDCA parameters
+ * @pe_session: point to the session entry
+ *
+ *  This function is called to set the most up-to-date EDCA parameters
+ *  given the default local EDCA parameters.  The rules are as following:
+ *  - If ACM bit is set for all ACs, then downgrade everything to Best Effort.
+ *  - If ACM is not set for any AC, then PE will use the default EDCA
+ *    parameters as advertised by AP.
+ *  - If ACM is set in any of the ACs, PE will use the EDCA parameters
+ *    from the next best AC for which ACM is not enabled.
+ *
+ * Return: none
+ */
+
+void lim_set_active_edca_params(tpAniSirGlobal mac_ctx,
+				tSirMacEdcaParamRecord *edca_params,
+				tpPESession pe_session)
+{
+	uint8_t ac, new_ac, i;
+	uint8_t ac_admitted;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	host_log_qos_edca_pkt_type *log_ptr = NULL;
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+	/* Initialize gLimEdcaParamsActive[] to be same as localEdcaParams */
+	pe_session->gLimEdcaParamsActive[EDCA_AC_BE] = edca_params[EDCA_AC_BE];
+	pe_session->gLimEdcaParamsActive[EDCA_AC_BK] = edca_params[EDCA_AC_BK];
+	pe_session->gLimEdcaParamsActive[EDCA_AC_VI] = edca_params[EDCA_AC_VI];
+	pe_session->gLimEdcaParamsActive[EDCA_AC_VO] = edca_params[EDCA_AC_VO];
+
+	pe_session->gLimEdcaParamsActive[EDCA_AC_BE].no_ack =
+					mac_ctx->no_ack_policy_cfg[EDCA_AC_BE];
+	pe_session->gLimEdcaParamsActive[EDCA_AC_BK].no_ack =
+					mac_ctx->no_ack_policy_cfg[EDCA_AC_BK];
+	pe_session->gLimEdcaParamsActive[EDCA_AC_VI].no_ack =
+					mac_ctx->no_ack_policy_cfg[EDCA_AC_VI];
+	pe_session->gLimEdcaParamsActive[EDCA_AC_VO].no_ack =
+					mac_ctx->no_ack_policy_cfg[EDCA_AC_VO];
+
+	/* An AC requires downgrade if the ACM bit is set, and the AC has not
+	 * yet been admitted in uplink or bi-directions.
+	 * If an AC requires downgrade, it will downgrade to the next beset AC
+	 * for which ACM is not enabled.
+	 *
+	 * - There's no need to downgrade AC_BE since it IS the lowest AC. Hence
+	 *   start the for loop with AC_BK.
+	 * - If ACM bit is set for an AC, initially downgrade it to AC_BE. Then
+	 *   traverse thru the AC list. If we do find the next best AC which is
+	 *   better than AC_BE, then use that one. For example, if ACM bits are set
+	 *   such that: BE_ACM=1, BK_ACM=1, VI_ACM=1, VO_ACM=0
+	 *   then all AC will be downgraded to AC_BE.
+	 */
+	pe_debug("adAdmitMask[UPLINK] = 0x%x ",
+		pe_session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK]);
+	pe_debug("adAdmitMask[DOWNLINK] = 0x%x ",
+		pe_session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK]);
+	for (ac = EDCA_AC_BK; ac <= EDCA_AC_VO; ac++) {
+		ac_admitted =
+			((pe_session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &
+			 (1 << ac)) >> ac);
+
+		pe_debug("For AC[%d]: acm=%d,  ac_admitted=%d ",
+			ac, edca_params[ac].aci.acm, ac_admitted);
+		if ((edca_params[ac].aci.acm == 1) && (ac_admitted == 0)) {
+			pe_debug("We need to downgrade AC %d!!", ac);
+			/* Loop backwards through AC values until it finds
+			 * acm == 0 or reaches EDCA_AC_BE.
+			 * Note that for block has no executable statements.
+			 */
+			for (i = ac - 1;
+			    (i > EDCA_AC_BE &&
+				(edca_params[i].aci.acm != 0));
+			     i--)
+				;
+			new_ac = i;
+			pe_debug("Downgrading AC %d ---> AC %d ", ac, new_ac);
+			pe_session->gLimEdcaParamsActive[ac] =
+				edca_params[new_ac];
+		}
+	}
+/* log: LOG_WLAN_QOS_EDCA_C */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_qos_edca_pkt_type,
+				 LOG_WLAN_QOS_EDCA_C);
+	if (log_ptr) {
+		tSirMacEdcaParamRecord *rec;
+
+		rec = &pe_session->gLimEdcaParamsActive[EDCA_AC_BE];
+		log_ptr->aci_be = rec->aci.aci;
+		log_ptr->cw_be = rec->cw.max << 4 | rec->cw.min;
+		log_ptr->txoplimit_be = rec->txoplimit;
+
+		rec = &pe_session->gLimEdcaParamsActive[EDCA_AC_BK];
+		log_ptr->aci_bk = rec->aci.aci;
+		log_ptr->cw_bk = rec->cw.max << 4 | rec->cw.min;
+		log_ptr->txoplimit_bk = rec->txoplimit;
+
+		rec = &pe_session->gLimEdcaParamsActive[EDCA_AC_VI];
+		log_ptr->aci_vi = rec->aci.aci;
+		log_ptr->cw_vi = rec->cw.max << 4 | rec->cw.min;
+		log_ptr->txoplimit_vi = rec->txoplimit;
+
+		rec = &pe_session->gLimEdcaParamsActive[EDCA_AC_VO];
+		log_ptr->aci_vo = rec->aci.aci;
+		log_ptr->cw_vo = rec->cw.max << 4 | rec->cw.min;
+		log_ptr->txoplimit_vo = rec->txoplimit;
+	}
+	WLAN_HOST_DIAG_LOG_REPORT(log_ptr);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	return;
+}
+
+/** ---------------------------------------------------------
+   \fn      lim_set_link_state
+   \brief   LIM sends a message to WMA to set the link state
+   \param   tpAniSirGlobal  pMac
+   \param   tSirLinkState      state
+   \return  None
+   -----------------------------------------------------------*/
+QDF_STATUS lim_set_link_state(tpAniSirGlobal pMac, tSirLinkState state,
+				 tSirMacAddr bssId, tSirMacAddr selfMacAddr,
+				 tpSetLinkStateCallback callback,
+				 void *callbackArg)
+{
+	struct scheduler_msg msgQ = {0};
+	QDF_STATUS retCode;
+	tpLinkStateParams pLinkStateParams = NULL;
+	/* Allocate memory. */
+	pLinkStateParams = qdf_mem_malloc(sizeof(tLinkStateParams));
+	if (!pLinkStateParams)
+		return QDF_STATUS_E_NOMEM;
+	pLinkStateParams->state = state;
+	pLinkStateParams->callback = callback;
+	pLinkStateParams->callbackArg = callbackArg;
+
+	/* Copy Mac address */
+	sir_copy_mac_addr(pLinkStateParams->bssid, bssId);
+	sir_copy_mac_addr(pLinkStateParams->selfMacAddr, selfMacAddr);
+
+	msgQ.type = WMA_SET_LINK_STATE;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pLinkStateParams;
+	msgQ.bodyval = 0;
+
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+
+	retCode = (uint32_t) wma_post_ctrl_msg(pMac, &msgQ);
+	if (retCode != QDF_STATUS_SUCCESS) {
+		qdf_mem_free(pLinkStateParams);
+		pe_err("Posting link state %d failed, reason = %x", state,
+			retCode);
+	}
+	return retCode;
+}
+
+extern QDF_STATUS lim_set_link_state_ft(tpAniSirGlobal pMac, tSirLinkState
+					   state, tSirMacAddr bssId,
+					   tSirMacAddr selfMacAddr, int ft,
+					   tpPESession psessionEntry)
+{
+	struct scheduler_msg msgQ = {0};
+	QDF_STATUS retCode;
+	tpLinkStateParams pLinkStateParams = NULL;
+	/* Allocate memory. */
+	pLinkStateParams = qdf_mem_malloc(sizeof(tLinkStateParams));
+	if (!pLinkStateParams)
+		return QDF_STATUS_E_NOMEM;
+	pLinkStateParams->state = state;
+	/* Copy Mac address */
+	sir_copy_mac_addr(pLinkStateParams->bssid, bssId);
+	sir_copy_mac_addr(pLinkStateParams->selfMacAddr, selfMacAddr);
+	pLinkStateParams->ft = 1;
+	pLinkStateParams->session = psessionEntry;
+
+	msgQ.type = WMA_SET_LINK_STATE;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pLinkStateParams;
+	msgQ.bodyval = 0;
+	if (NULL == psessionEntry) {
+		MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+	} else {
+		MTRACE(mac_trace_msg_tx
+			       (pMac, psessionEntry->peSessionId, msgQ.type));
+	}
+
+	retCode = (uint32_t) wma_post_ctrl_msg(pMac, &msgQ);
+	if (retCode != QDF_STATUS_SUCCESS) {
+		qdf_mem_free(pLinkStateParams);
+		pe_err("Posting link state %d failed, reason = %x", state,
+			retCode);
+	}
+	return retCode;
+}
+
+QDF_STATUS lim_send_mode_update(tpAniSirGlobal pMac,
+				   tUpdateVHTOpMode *pTempParam,
+				   tpPESession psessionEntry)
+{
+	tUpdateVHTOpMode *pVhtOpMode = NULL;
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msgQ = {0};
+
+	pVhtOpMode = qdf_mem_malloc(sizeof(tUpdateVHTOpMode));
+	if (!pVhtOpMode)
+		return QDF_STATUS_E_NOMEM;
+	qdf_mem_copy((uint8_t *) pVhtOpMode, pTempParam,
+		     sizeof(tUpdateVHTOpMode));
+	msgQ.type = WMA_UPDATE_OP_MODE;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pVhtOpMode;
+	msgQ.bodyval = 0;
+	pe_debug("Sending WMA_UPDATE_OP_MODE, op_mode %d, sta_id %d",
+			pVhtOpMode->opMode, pVhtOpMode->staId);
+	if (NULL == psessionEntry)
+		MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+	else
+		MTRACE(mac_trace_msg_tx(pMac,
+					psessionEntry->peSessionId,
+					msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		qdf_mem_free(pVhtOpMode);
+		pe_err("Posting WMA_UPDATE_OP_MODE failed, reason=%X",
+			retCode);
+	}
+
+	return retCode;
+}
+
+QDF_STATUS lim_send_rx_nss_update(tpAniSirGlobal pMac,
+				     tUpdateRxNss *pTempParam,
+				     tpPESession psessionEntry)
+{
+	tUpdateRxNss *pRxNss = NULL;
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msgQ = {0};
+
+	pRxNss = qdf_mem_malloc(sizeof(tUpdateRxNss));
+	if (!pRxNss)
+		return QDF_STATUS_E_NOMEM;
+	qdf_mem_copy((uint8_t *) pRxNss, pTempParam, sizeof(tUpdateRxNss));
+	msgQ.type = WMA_UPDATE_RX_NSS;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pRxNss;
+	msgQ.bodyval = 0;
+	pe_debug("Sending WMA_UPDATE_RX_NSS");
+	if (NULL == psessionEntry)
+		MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+	else
+		MTRACE(mac_trace_msg_tx(pMac,
+					psessionEntry->peSessionId,
+					msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		qdf_mem_free(pRxNss);
+		pe_err("Posting WMA_UPDATE_RX_NSS failed, reason=%X",
+			retCode);
+	}
+
+	return retCode;
+}
+
+QDF_STATUS lim_set_membership(tpAniSirGlobal pMac,
+				 tUpdateMembership *pTempParam,
+				 tpPESession psessionEntry)
+{
+	tUpdateMembership *pMembership = NULL;
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msgQ = {0};
+
+	pMembership = qdf_mem_malloc(sizeof(tUpdateMembership));
+	if (!pMembership)
+		return QDF_STATUS_E_NOMEM;
+	qdf_mem_copy((uint8_t *) pMembership, pTempParam,
+		     sizeof(tUpdateMembership));
+
+	msgQ.type = WMA_UPDATE_MEMBERSHIP;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pMembership;
+	msgQ.bodyval = 0;
+	pe_debug("Sending WMA_UPDATE_MEMBERSHIP");
+	if (NULL == psessionEntry)
+		MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+	else
+		MTRACE(mac_trace_msg_tx(pMac,
+					psessionEntry->peSessionId,
+					msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		qdf_mem_free(pMembership);
+		pe_err("Posting WMA_UPDATE_MEMBERSHIP failed, reason=%X",
+			retCode);
+	}
+
+	return retCode;
+}
+
+QDF_STATUS lim_set_user_pos(tpAniSirGlobal pMac,
+			       tUpdateUserPos *pTempParam,
+			       tpPESession psessionEntry)
+{
+	tUpdateUserPos *pUserPos = NULL;
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msgQ = {0};
+
+	pUserPos = qdf_mem_malloc(sizeof(tUpdateUserPos));
+	if (!pUserPos)
+		return QDF_STATUS_E_NOMEM;
+	qdf_mem_copy((uint8_t *) pUserPos, pTempParam, sizeof(tUpdateUserPos));
+
+	msgQ.type = WMA_UPDATE_USERPOS;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pUserPos;
+	msgQ.bodyval = 0;
+	pe_debug("Sending WMA_UPDATE_USERPOS");
+	if (NULL == psessionEntry)
+		MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+	else
+		MTRACE(mac_trace_msg_tx(pMac,
+					psessionEntry->peSessionId,
+					msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		qdf_mem_free(pUserPos);
+		pe_err("Posting WMA_UPDATE_USERPOS failed, reason=%X",
+			retCode);
+	}
+
+	return retCode;
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * lim_send_exclude_unencrypt_ind() - sends WMA_EXCLUDE_UNENCRYPTED_IND to HAL
+ * @pMac:          mac global context
+ * @excludeUnenc:  true: ignore, false: indicate
+ * @psessionEntry: session context
+ *
+ * LIM sends a message to HAL to indicate whether to ignore or indicate the
+ * unprotected packet error.
+ *
+ * Return: status of operation
+ */
+QDF_STATUS lim_send_exclude_unencrypt_ind(tpAniSirGlobal pMac,
+					     bool excludeUnenc,
+					     tpPESession psessionEntry)
+{
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msgQ = {0};
+	tSirWlanExcludeUnencryptParam *pExcludeUnencryptParam;
+
+	pExcludeUnencryptParam =
+		qdf_mem_malloc(sizeof(tSirWlanExcludeUnencryptParam));
+	if (!pExcludeUnencryptParam)
+		return QDF_STATUS_E_NOMEM;
+
+	pExcludeUnencryptParam->excludeUnencrypt = excludeUnenc;
+	qdf_mem_copy(pExcludeUnencryptParam->bssid.bytes, psessionEntry->bssId,
+			QDF_MAC_ADDR_SIZE);
+
+	msgQ.type = WMA_EXCLUDE_UNENCRYPTED_IND;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pExcludeUnencryptParam;
+	msgQ.bodyval = 0;
+	pe_debug("Sending WMA_EXCLUDE_UNENCRYPTED_IND");
+	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		qdf_mem_free(pExcludeUnencryptParam);
+		pe_err("Posting WMA_EXCLUDE_UNENCRYPTED_IND failed, reason=%X",
+			retCode);
+	}
+
+	return retCode;
+}
+#endif
+
+/**
+ * lim_send_ht40_obss_scanind() - send ht40 obss start scan request
+ * mac: mac context
+ * session  PE session handle
+ *
+ * LIM sends a HT40 start scan message to WMA
+ *
+ * Return: status of operation
+ */
+QDF_STATUS lim_send_ht40_obss_scanind(tpAniSirGlobal mac_ctx,
+						struct sPESession *session)
+{
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+	struct obss_ht40_scanind *ht40_obss_scanind;
+	uint32_t channelnum;
+	struct scheduler_msg msg = {0};
+	uint8_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	uint8_t channel24gnum, count;
+
+	ht40_obss_scanind = qdf_mem_malloc(sizeof(struct obss_ht40_scanind));
+	if (!ht40_obss_scanind)
+		return QDF_STATUS_E_FAILURE;
+	QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+		"OBSS Scan Indication bssIdx- %d staId %d",
+		session->bssIdx, session->staId);
+
+	ht40_obss_scanind->cmd = HT40_OBSS_SCAN_PARAM_START;
+	ht40_obss_scanind->scan_type = eSIR_ACTIVE_SCAN;
+	ht40_obss_scanind->obss_passive_dwelltime =
+		session->obss_ht40_scanparam.obss_passive_dwelltime;
+	ht40_obss_scanind->obss_active_dwelltime =
+		session->obss_ht40_scanparam.obss_active_dwelltime;
+	ht40_obss_scanind->obss_width_trigger_interval =
+		session->obss_ht40_scanparam.obss_width_trigger_interval;
+	ht40_obss_scanind->obss_passive_total_per_channel =
+		session->obss_ht40_scanparam.obss_passive_total_per_channel;
+	ht40_obss_scanind->obss_active_total_per_channel =
+		session->obss_ht40_scanparam.obss_active_total_per_channel;
+	ht40_obss_scanind->bsswidth_ch_trans_delay =
+		session->obss_ht40_scanparam.bsswidth_ch_trans_delay;
+	ht40_obss_scanind->obss_activity_threshold =
+		session->obss_ht40_scanparam.obss_activity_threshold;
+	ht40_obss_scanind->current_operatingclass =
+		wlan_reg_dmn_get_opclass_from_channel(
+			mac_ctx->scan.countryCodeCurrent,
+			session->currentOperChannel,
+			session->ch_width);
+	channelnum = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+	if (wlan_cfg_get_str(mac_ctx, WNI_CFG_VALID_CHANNEL_LIST,
+			chan_list, &channelnum) != QDF_STATUS_SUCCESS) {
+		pe_err("could not retrieve Valid channel list");
+		qdf_mem_free(ht40_obss_scanind);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Extract 24G channel list */
+	channel24gnum = 0;
+	for (count = 0; count < channelnum &&
+		(channel24gnum < SIR_ROAM_MAX_CHANNELS); count++) {
+		if ((chan_list[count] > CHAN_ENUM_1) &&
+			(chan_list[count] < CHAN_ENUM_14)) {
+			ht40_obss_scanind->channels[channel24gnum] =
+				chan_list[count];
+			channel24gnum++;
+		}
+	}
+	ht40_obss_scanind->channel_count = channel24gnum;
+	/* FW API requests BSS IDX */
+	ht40_obss_scanind->self_sta_idx = session->staId;
+	ht40_obss_scanind->bss_id = session->bssIdx;
+	ht40_obss_scanind->fortymhz_intolerent = 0;
+	ht40_obss_scanind->iefield_len = 0;
+	msg.type = WMA_HT40_OBSS_SCAN_IND;
+	msg.reserved = 0;
+	msg.bodyptr = (void *)ht40_obss_scanind;
+	msg.bodyval = 0;
+	pe_debug("Sending WDA_HT40_OBSS_SCAN_IND to WDA"
+		"Obss Scan trigger width: %d, delay factor: %d",
+		ht40_obss_scanind->obss_width_trigger_interval,
+		ht40_obss_scanind->bsswidth_ch_trans_delay);
+	ret = wma_post_ctrl_msg(mac_ctx, &msg);
+	if (QDF_STATUS_SUCCESS != ret) {
+		pe_err("WDA_HT40_OBSS_SCAN_IND msg failed, reason=%X",
+			ret);
+		qdf_mem_free(ht40_obss_scanind);
+	}
+	return ret;
+}
diff --git a/core/mac/src/pe/lim/lim_send_messages.h b/core/mac/src/pe/lim/lim_send_messages.h
new file mode 100644
index 0000000..6d3d405
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_messages.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * lim_send_messages.h: Provides functions to send messages or Indications to HAL.
+ * Author:    Sunit Bhatia
+ * Date:       09/21/2006
+ * History:-
+ * Date        Modified by            Modification Information
+ *
+ * --------------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_SEND_MESSAGES_H
+#define __LIM_SEND_MESSAGES_H
+
+#include "ani_global.h"
+#include "lim_types.h"
+#include "wma_if.h"
+#include "sir_params.h"
+QDF_STATUS lim_send_cf_params(tpAniSirGlobal pMac, uint8_t bssIdx,
+				 uint8_t cfpCount, uint8_t cfpPeriod);
+QDF_STATUS lim_send_beacon_params(tpAniSirGlobal pMac,
+				     tpUpdateBeaconParams pUpdatedBcnParams,
+				     tpPESession psessionEntry);
+/* QDF_STATUS lim_send_beacon_params(tpAniSirGlobal pMac, tpUpdateBeaconParams pUpdatedBcnParams); */
+QDF_STATUS lim_send_mode_update(tpAniSirGlobal pMac,
+				   tUpdateVHTOpMode *tempParam,
+				   tpPESession psessionEntry);
+QDF_STATUS lim_send_rx_nss_update(tpAniSirGlobal pMac,
+				     tUpdateRxNss *tempParam,
+				     tpPESession psessionEntry);
+
+QDF_STATUS lim_set_membership(tpAniSirGlobal pMac,
+				 tUpdateMembership *pTempParam,
+				 tpPESession psessionEntry);
+
+QDF_STATUS lim_set_user_pos(tpAniSirGlobal pMac,
+			       tUpdateUserPos *pTempParam,
+			       tpPESession psessionEntry);
+QDF_STATUS lim_send_switch_chnl_params(tpAniSirGlobal pMac,
+					  uint8_t chnlNumber,
+					  uint8_t ch_center_freq_seg0,
+					  uint8_t ch_center_freq_seg1,
+					  enum phy_ch_width ch_width,
+					  int8_t maxTxPower,
+					  uint8_t peSessionId,
+					  uint8_t is_restart,
+					  uint32_t cac_duration_ms,
+					  uint32_t dfs_regdomain);
+
+QDF_STATUS lim_send_edca_params(tpAniSirGlobal pMac,
+				   tSirMacEdcaParamRecord *pUpdatedEdcaParams,
+				   uint16_t bssIdx, bool mu_edca);
+QDF_STATUS lim_set_link_state(tpAniSirGlobal pMac, tSirLinkState state,
+				 tSirMacAddr bssId, tSirMacAddr selfMac,
+				 tpSetLinkStateCallback callback,
+				 void *callbackArg);
+extern QDF_STATUS lim_set_link_state_ft(tpAniSirGlobal pMac, tSirLinkState
+					   state, tSirMacAddr bssId,
+					   tSirMacAddr selfMacAddr, int ft,
+					   tpPESession psessionEntry);
+void lim_set_active_edca_params(tpAniSirGlobal pMac,
+				tSirMacEdcaParamRecord *plocalEdcaParams,
+				tpPESession psessionEntry);
+#define CAPABILITY_FILTER_MASK  0x73CF
+#define ERP_FILTER_MASK         0xF8
+#define EDCA_FILTER_MASK        0xF0
+#define QOS_FILTER_MASK         0xF0
+#define HT_BYTE0_FILTER_MASK    0x0
+#define HT_BYTE2_FILTER_MASK    0xEB
+#define HT_BYTE5_FILTER_MASK    0xFD
+#define DS_PARAM_CHANNEL_MASK   0x0
+#define VHTOP_CHWIDTH_MASK      0xFC
+
+#ifdef WLAN_FEATURE_11W
+QDF_STATUS lim_send_exclude_unencrypt_ind(tpAniSirGlobal pMac,
+					     bool excludeUnenc,
+					     tpPESession psessionEntry);
+#endif
+QDF_STATUS lim_send_ht40_obss_scanind(tpAniSirGlobal mac_ctx,
+						tpPESession session);
+void lim_handle_sme_join_result(tpAniSirGlobal,
+		tSirResultCodes, uint16_t, tpPESession);
+#endif
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
new file mode 100644
index 0000000..92ea73c
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -0,0 +1,2440 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file lim_send_sme_rspMessages.cc contains the functions
+ * for sending SME response/notification messages to applications
+ * above MAC software.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "qdf_types.h"
+#include "wni_api.h"
+#include "sir_common.h"
+#include "ani_global.h"
+
+#include "wni_cfg.h"
+#include "sys_def.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_session_utils.h"
+#include "lim_types.h"
+#include "sir_api.h"
+#include "cds_regdomain.h"
+#include "lim_send_messages.h"
+#include "nan_datapath.h"
+#include "lim_assoc_utils.h"
+#include "wlan_reg_services_api.h"
+#include "wlan_utility.h"
+
+#include "wlan_tdls_tgt_api.h"
+#include "lim_process_fils.h"
+#include "wma.h"
+
+static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
+	tpPESession session_entry, tSirResultCodes result_code,
+	tpSirSmeJoinRsp sme_join_rsp);
+
+/**
+ * lim_send_sme_rsp() - Send Response to upper layers
+ * @mac_ctx:          Pointer to Global MAC structure
+ * @msg_type:         Indicates message type
+ * @result_code:       Indicates the result of previously issued
+ *                    eWNI_SME_msg_type_REQ message
+ *
+ * This function is called by lim_process_sme_req_messages() to send
+ * eWNI_SME_START_RSP, eWNI_SME_STOP_BSS_RSP
+ * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC
+ * Software.
+ *
+ * Return: None
+ */
+
+void
+lim_send_sme_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+	 tSirResultCodes result_code, uint8_t sme_session_id,
+	 uint16_t sme_transaction_id)
+{
+	struct scheduler_msg msg = {0};
+	tSirSmeRsp *sme_rsp;
+
+	pe_debug("Sending message: %s with reasonCode: %s",
+		lim_msg_str(msg_type), lim_result_code_str(result_code));
+
+	sme_rsp = qdf_mem_malloc(sizeof(tSirSmeRsp));
+	if (!sme_rsp)
+		return;
+
+	sme_rsp->messageType = msg_type;
+	sme_rsp->length = sizeof(tSirSmeRsp);
+	sme_rsp->statusCode = result_code;
+
+	sme_rsp->sessionId = sme_session_id;
+	sme_rsp->transactionId = sme_transaction_id;
+
+	msg.type = msg_type;
+	msg.bodyptr = sme_rsp;
+	msg.bodyval = 0;
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG,
+			 sme_session_id, msg.type));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	switch (msg_type) {
+	case eWNI_SME_STOP_BSS_RSP:
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_STOP_BSS_RSP_EVENT,
+				NULL, (uint16_t) result_code, 0);
+		break;
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
+}
+
+
+
+/**
+ * lim_send_sme_roc_rsp() - Send Response to SME
+ * @mac_ctx:          Pointer to Global MAC structure
+ * @status:           Resume link status
+ * @result_code:  Result of the ROC request
+ * @sme_session_id:   SME sesson Id
+ * @scan_id:  Scan Identifier
+ *
+ * This function is called to send ROC rsp
+ * message to SME.
+ *
+ * Return: None
+ */
+void
+lim_send_sme_roc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+	 tSirResultCodes result_code, uint8_t sme_session_id,
+	 uint32_t scan_id)
+{
+	struct scheduler_msg msg = {0};
+	struct sir_roc_rsp *sme_rsp;
+
+	pe_debug("Sending message: %s with reasonCode: %s scanId: %d",
+		lim_msg_str(msg_type), lim_result_code_str(result_code),
+		scan_id);
+
+	sme_rsp = qdf_mem_malloc(sizeof(struct sir_roc_rsp));
+	if (!sme_rsp)
+		return;
+
+	sme_rsp->message_type = msg_type;
+	sme_rsp->length = sizeof(struct sir_roc_rsp);
+	sme_rsp->status = result_code;
+
+	sme_rsp->session_id = sme_session_id;
+	sme_rsp->scan_id = scan_id;
+
+	msg.type = msg_type;
+	msg.bodyptr = sme_rsp;
+	msg.bodyval = 0;
+	MTRACE(mac_trace_msg_tx(mac_ctx, sme_session_id, msg.type));
+	lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
+}
+
+
+/**
+ * lim_get_max_rate_flags() - Get rate flags
+ * @mac_ctx: Pointer to global MAC structure
+ * @sta_ds: Pointer to station ds structure
+ *
+ * This function is called to get the rate flags for a connection
+ * from the station ds structure depending on the ht and the vht
+ * channel width supported.
+ *
+ * Return: Returns the populated rate_flags
+ */
+uint32_t lim_get_max_rate_flags(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds)
+{
+	uint32_t rate_flags = 0;
+
+	if (sta_ds == NULL) {
+		pe_err("sta_ds is NULL");
+		return rate_flags;
+	}
+
+	if (!sta_ds->mlmStaContext.htCapability &&
+	    !sta_ds->mlmStaContext.vhtCapability) {
+		rate_flags |= TX_RATE_LEGACY;
+	} else {
+		if (sta_ds->mlmStaContext.vhtCapability) {
+			if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ ==
+				sta_ds->vhtSupportedChannelWidthSet) {
+				rate_flags |= TX_RATE_VHT80;
+			} else if (WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ ==
+					sta_ds->vhtSupportedChannelWidthSet) {
+				if (sta_ds->htSupportedChannelWidthSet)
+					rate_flags |= TX_RATE_VHT40;
+				else
+					rate_flags |= TX_RATE_VHT20;
+			}
+		} else if (sta_ds->mlmStaContext.htCapability) {
+			if (sta_ds->htSupportedChannelWidthSet)
+				rate_flags |= TX_RATE_HT40;
+			else
+				rate_flags |= TX_RATE_HT20;
+		}
+	}
+
+	if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz)
+		rate_flags |= TX_RATE_SGI;
+
+	return rate_flags;
+}
+
+/**
+ * lim_send_sme_join_reassoc_rsp_after_resume() - Send Response to SME
+ * @mac_ctx          Pointer to Global MAC structure
+ * @status           Resume link status
+ * @ctx              context passed while calling resmune link.
+ *                   (join response to be sent)
+ *
+ * This function is called to send Join/Reassoc rsp
+ * message to SME after the resume link.
+ *
+ * Return: None
+ */
+static void lim_send_sme_join_reassoc_rsp_after_resume(tpAniSirGlobal mac_ctx,
+	QDF_STATUS status, uint32_t *ctx)
+{
+	struct scheduler_msg msg = {0};
+	tpSirSmeJoinRsp sme_join_rsp = (tpSirSmeJoinRsp) ctx;
+
+	msg.type = sme_join_rsp->messageType;
+	msg.bodyptr = sme_join_rsp;
+	msg.bodyval = 0;
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG, NO_SESSION, msg.type));
+	lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
+}
+
+/**
+ * lim_handle_join_rsp_status() - Handle the response.
+ * @mac_ctx:            Pointer to Global MAC structure
+ * @session_entry:      PE Session Info
+ * @result_code:        Indicates the result of previously issued
+ *                      eWNI_SME_msgType_REQ message
+ * @sme_join_rsp        The received response.
+ *
+ * This function will handle both the success and failure status
+ * of the received response.
+ *
+ * Return: None
+ */
+static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
+	tpPESession session_entry, tSirResultCodes result_code,
+	tpSirSmeJoinRsp sme_join_rsp)
+{
+	uint16_t bss_ie_len;
+	void *bss_ies;
+	bool is_vendor_ap_1_present;
+	tpSirSmeJoinReq join_reassoc_req = NULL;
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	tSirSmeHTProfile *ht_profile;
+#endif
+	if (result_code == eSIR_SME_SUCCESS) {
+		if (session_entry->beacon != NULL) {
+			sme_join_rsp->beaconLength = session_entry->bcnLen;
+			qdf_mem_copy(sme_join_rsp->frames,
+				session_entry->beacon,
+				sme_join_rsp->beaconLength);
+			qdf_mem_free(session_entry->beacon);
+			session_entry->beacon = NULL;
+			session_entry->bcnLen = 0;
+			pe_debug("Beacon: %d",
+				sme_join_rsp->beaconLength);
+		}
+		if (session_entry->assocReq != NULL) {
+			sme_join_rsp->assocReqLength =
+				session_entry->assocReqLen;
+			qdf_mem_copy(sme_join_rsp->frames +
+				sme_join_rsp->beaconLength,
+				session_entry->assocReq,
+				sme_join_rsp->assocReqLength);
+			qdf_mem_free(session_entry->assocReq);
+			session_entry->assocReq = NULL;
+			session_entry->assocReqLen = 0;
+			pe_debug("AssocReq: %d",
+				sme_join_rsp->assocReqLength);
+		}
+		if (session_entry->assocRsp != NULL) {
+			sme_join_rsp->assocRspLength =
+				session_entry->assocRspLen;
+			qdf_mem_copy(sme_join_rsp->frames +
+				sme_join_rsp->beaconLength +
+				sme_join_rsp->assocReqLength,
+				session_entry->assocRsp,
+				sme_join_rsp->assocRspLength);
+			qdf_mem_free(session_entry->assocRsp);
+			session_entry->assocRsp = NULL;
+			session_entry->assocRspLen = 0;
+		}
+		if (session_entry->ricData != NULL) {
+			sme_join_rsp->parsedRicRspLen =
+				session_entry->RICDataLen;
+			qdf_mem_copy(sme_join_rsp->frames +
+				sme_join_rsp->beaconLength +
+				sme_join_rsp->assocReqLength +
+				sme_join_rsp->assocRspLength,
+				session_entry->ricData,
+				sme_join_rsp->parsedRicRspLen);
+			qdf_mem_free(session_entry->ricData);
+			session_entry->ricData = NULL;
+			session_entry->RICDataLen = 0;
+			pe_debug("RicLength: %d",
+				sme_join_rsp->parsedRicRspLen);
+		}
+#ifdef FEATURE_WLAN_ESE
+		if (session_entry->tspecIes != NULL) {
+			sme_join_rsp->tspecIeLen =
+				session_entry->tspecLen;
+			qdf_mem_copy(sme_join_rsp->frames +
+				sme_join_rsp->beaconLength +
+				sme_join_rsp->assocReqLength +
+				sme_join_rsp->assocRspLength +
+				sme_join_rsp->parsedRicRspLen,
+				session_entry->tspecIes,
+				sme_join_rsp->tspecIeLen);
+			qdf_mem_free(session_entry->tspecIes);
+			session_entry->tspecIes = NULL;
+			session_entry->tspecLen = 0;
+			pe_debug("ESE-TspecLen: %d",
+				sme_join_rsp->tspecIeLen);
+		}
+#endif
+		sme_join_rsp->aid = session_entry->limAID;
+		pe_debug("AssocRsp: %d",
+			sme_join_rsp->assocRspLength);
+		sme_join_rsp->vht_channel_width =
+			session_entry->ch_width;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+		if (session_entry->cc_switch_mode !=
+				QDF_MCC_TO_SCC_SWITCH_DISABLE) {
+			ht_profile = &sme_join_rsp->HTProfile;
+			ht_profile->htSupportedChannelWidthSet =
+				session_entry->htSupportedChannelWidthSet;
+			ht_profile->htRecommendedTxWidthSet =
+				session_entry->htRecommendedTxWidthSet;
+			ht_profile->htSecondaryChannelOffset =
+				session_entry->htSecondaryChannelOffset;
+			ht_profile->dot11mode = session_entry->dot11mode;
+			ht_profile->htCapability = session_entry->htCapability;
+			ht_profile->vhtCapability =
+				session_entry->vhtCapability;
+			ht_profile->apCenterChan = session_entry->ch_center_freq_seg0;
+			ht_profile->apChanWidth = session_entry->ch_width;
+		}
+#endif
+		pe_debug("pLimJoinReq:%pK, pLimReAssocReq:%pK",
+			session_entry->pLimJoinReq,
+			session_entry->pLimReAssocReq);
+
+		if (session_entry->pLimJoinReq)
+			join_reassoc_req = session_entry->pLimJoinReq;
+
+		if (session_entry->pLimReAssocReq)
+			join_reassoc_req = session_entry->pLimReAssocReq;
+
+		if (!join_reassoc_req) {
+			pe_err("both  pLimJoinReq and pLimReAssocReq NULL");
+			return;
+		}
+
+		bss_ie_len = lim_get_ielen_from_bss_description(
+				&join_reassoc_req->bssDescription);
+		bss_ies = &join_reassoc_req->bssDescription.ieFields;
+		is_vendor_ap_1_present = (wlan_get_vendor_ie_ptr_from_oui(
+			SIR_MAC_VENDOR_AP_1_OUI, SIR_MAC_VENDOR_AP_1_OUI_LEN,
+			bss_ies, bss_ie_len) != NULL);
+
+		if (mac_ctx->roam.configParam.is_force_1x1 &&
+		    is_vendor_ap_1_present && (session_entry->nss == 2) &&
+		    (mac_ctx->lteCoexAntShare == 0 ||
+				IS_5G_CH(session_entry->currentOperChannel))) {
+			/* SET vdev param */
+			pe_debug("sending SMPS intolrent vdev_param");
+			wma_cli_set_command(session_entry->smeSessionId,
+					   (int)WMI_VDEV_PARAM_SMPS_INTOLERANT,
+					    1, VDEV_CMD);
+
+		}
+	} else {
+		if (session_entry->beacon != NULL) {
+			qdf_mem_free(session_entry->beacon);
+			session_entry->beacon = NULL;
+			session_entry->bcnLen = 0;
+		}
+		if (session_entry->assocReq != NULL) {
+			qdf_mem_free(session_entry->assocReq);
+			session_entry->assocReq = NULL;
+			session_entry->assocReqLen = 0;
+		}
+		if (session_entry->assocRsp != NULL) {
+			qdf_mem_free(session_entry->assocRsp);
+			session_entry->assocRsp = NULL;
+			session_entry->assocRspLen = 0;
+		}
+		if (session_entry->ricData != NULL) {
+			qdf_mem_free(session_entry->ricData);
+			session_entry->ricData = NULL;
+			session_entry->RICDataLen = 0;
+		}
+#ifdef FEATURE_WLAN_ESE
+		if (session_entry->tspecIes != NULL) {
+			qdf_mem_free(session_entry->tspecIes);
+			session_entry->tspecIes = NULL;
+			session_entry->tspecLen = 0;
+		}
+#endif
+	}
+}
+
+/**
+ * lim_add_bss_info() - copy data from session entry to join rsp
+ * @sta_ds: Station dph entry
+ * @sme_join_rsp: Join response buffer to be filled up
+ *
+ * Return: None
+ */
+static void lim_add_bss_info(tpDphHashNode sta_ds, tpSirSmeJoinRsp sme_join_rsp)
+{
+	struct parsed_ies *parsed_ies = &sta_ds->parsed_ies;
+
+	if (parsed_ies->hs20vendor_ie.present)
+		sme_join_rsp->hs20vendor_ie = parsed_ies->hs20vendor_ie;
+	if (parsed_ies->vht_caps.present)
+		sme_join_rsp->vht_caps = parsed_ies->vht_caps;
+	if (parsed_ies->ht_caps.present)
+		sme_join_rsp->ht_caps = parsed_ies->ht_caps;
+	if (parsed_ies->ht_operation.present)
+		sme_join_rsp->ht_operation = parsed_ies->ht_operation;
+	if (parsed_ies->vht_operation.present)
+		sme_join_rsp->vht_operation = parsed_ies->vht_operation;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+static void lim_update_fils_seq_num(tpSirSmeJoinRsp sme_join_rsp,
+				    tpPESession session_entry)
+{
+	sme_join_rsp->fils_seq_num =
+		session_entry->fils_info->sequence_number;
+}
+#else
+static inline void lim_update_fils_seq_num(tpSirSmeJoinRsp sme_join_rsp,
+					   tpPESession session_entry)
+{}
+#endif
+/**
+ * lim_send_sme_join_reassoc_rsp() - Send Response to Upper Layers
+ * @mac_ctx:            Pointer to Global MAC structure
+ * @msg_type:           Indicates message type
+ * @result_code:        Indicates the result of previously issued
+ *                      eWNI_SME_msgType_REQ message
+ * @prot_status_code:   Protocol Status Code
+ * @session_entry:      PE Session Info
+ * @sme_session_id:     SME Session ID
+ * @sme_transaction_id: SME Transaction ID
+ *
+ * This function is called by lim_process_sme_req_messages() to send
+ * eWNI_SME_JOIN_RSP or eWNI_SME_REASSOC_RSP messages to applications
+ * above MAC Software.
+ *
+ * Return: None
+ */
+
+void
+lim_send_sme_join_reassoc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+	tSirResultCodes result_code, uint16_t prot_status_code,
+	tpPESession session_entry, uint8_t sme_session_id,
+	uint16_t sme_transaction_id)
+{
+	tpSirSmeJoinRsp sme_join_rsp;
+	uint32_t rsp_len;
+	tpDphHashNode sta_ds = NULL;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	if (msg_type == eWNI_SME_REASSOC_RSP)
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_RSP_EVENT,
+			session_entry, (uint16_t) result_code, 0);
+	else
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_JOIN_RSP_EVENT,
+			session_entry, (uint16_t) result_code, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	pe_debug("Sending message: %s with reasonCode: %s",
+		lim_msg_str(msg_type), lim_result_code_str(result_code));
+
+	if (session_entry == NULL) {
+		rsp_len = sizeof(tSirSmeJoinRsp);
+		sme_join_rsp = qdf_mem_malloc(rsp_len);
+		if (!sme_join_rsp)
+			return;
+
+		sme_join_rsp->beaconLength = 0;
+		sme_join_rsp->assocReqLength = 0;
+		sme_join_rsp->assocRspLength = 0;
+	} else {
+		rsp_len = session_entry->assocReqLen +
+			session_entry->assocRspLen + session_entry->bcnLen +
+			session_entry->RICDataLen +
+#ifdef FEATURE_WLAN_ESE
+			session_entry->tspecLen +
+#endif
+			sizeof(tSirSmeJoinRsp) - sizeof(uint8_t);
+		sme_join_rsp = qdf_mem_malloc(rsp_len);
+		if (!sme_join_rsp)
+			return;
+
+		if (lim_is_fils_connection(session_entry)) {
+			sme_join_rsp->is_fils_connection = true;
+			lim_update_fils_seq_num(sme_join_rsp,
+						session_entry);
+		}
+
+		if (result_code == eSIR_SME_SUCCESS) {
+			sta_ds = dph_get_hash_entry(mac_ctx,
+				DPH_STA_HASH_INDEX_PEER,
+				&session_entry->dph.dphHashTable);
+			if (sta_ds == NULL) {
+				pe_err("Get Self Sta Entry fail");
+			} else {
+				/* Pass the peer's staId */
+				sme_join_rsp->staId = sta_ds->staIndex;
+				sme_join_rsp->timingMeasCap =
+					sta_ds->timingMeasCap;
+#ifdef FEATURE_WLAN_TDLS
+				sme_join_rsp->tdls_prohibited =
+					session_entry->tdls_prohibited;
+				sme_join_rsp->tdls_chan_swit_prohibited =
+				   session_entry->tdls_chan_swit_prohibited;
+#endif
+				sme_join_rsp->nss = sta_ds->nss;
+				sme_join_rsp->max_rate_flags =
+					lim_get_max_rate_flags(mac_ctx, sta_ds);
+				lim_add_bss_info(sta_ds, sme_join_rsp);
+
+				/* Copy FILS params only for Successful join */
+				populate_fils_connect_params(mac_ctx,
+						session_entry, sme_join_rsp);
+			}
+		}
+
+		sme_join_rsp->beaconLength = 0;
+		sme_join_rsp->assocReqLength = 0;
+		sme_join_rsp->assocRspLength = 0;
+		sme_join_rsp->parsedRicRspLen = 0;
+#ifdef FEATURE_WLAN_ESE
+		sme_join_rsp->tspecIeLen = 0;
+#endif
+		lim_handle_join_rsp_status(mac_ctx, session_entry, result_code,
+			sme_join_rsp);
+
+		/* Send supported NSS 1x1 to SME */
+		sme_join_rsp->supported_nss_1x1 =
+			session_entry->supported_nss_1x1;
+		pe_debug("SME Join Rsp is supported NSS 1X1: %d",
+		       sme_join_rsp->supported_nss_1x1);
+	}
+
+	sme_join_rsp->messageType = msg_type;
+	sme_join_rsp->length = (uint16_t) rsp_len;
+	sme_join_rsp->statusCode = result_code;
+	sme_join_rsp->protStatusCode = prot_status_code;
+
+	sme_join_rsp->sessionId = sme_session_id;
+	sme_join_rsp->transactionId = sme_transaction_id;
+
+	lim_send_sme_join_reassoc_rsp_after_resume(mac_ctx, QDF_STATUS_SUCCESS,
+			(uint32_t *)sme_join_rsp);
+}
+
+/**
+ * lim_send_sme_start_bss_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to send eWNI_SME_START_BSS_RSP
+ * message to applications above MAC Software.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac         Pointer to Global MAC structure
+ * @param msgType      Indicates message type
+ * @param resultCode   Indicates the result of previously issued
+ *                     eWNI_SME_msgType_REQ message
+ *
+ * @return None
+ */
+
+void
+lim_send_sme_start_bss_rsp(tpAniSirGlobal pMac,
+			   uint16_t msgType, tSirResultCodes resultCode,
+			   tpPESession psessionEntry, uint8_t smesessionId,
+			   uint16_t smetransactionId)
+{
+
+	uint16_t size = 0;
+	struct scheduler_msg mmhMsg = {0};
+	tSirSmeStartBssRsp *pSirSmeRsp;
+	uint16_t ieLen;
+	uint16_t ieOffset, curLen;
+
+	pe_debug("Sending message: %s with reasonCode: %s",
+		       lim_msg_str(msgType), lim_result_code_str(resultCode));
+
+	size = sizeof(tSirSmeStartBssRsp);
+
+	if (psessionEntry == NULL) {
+		pSirSmeRsp = qdf_mem_malloc(size);
+		if (!pSirSmeRsp)
+			return;
+	} else {
+		/* subtract size of beaconLength + Mac Hdr + Fixed Fields before SSID */
+		ieOffset = sizeof(tAniBeaconStruct) + SIR_MAC_B_PR_SSID_OFFSET;
+		ieLen = psessionEntry->schBeaconOffsetBegin
+			+ psessionEntry->schBeaconOffsetEnd - ieOffset;
+		/* calculate the memory size to allocate */
+		size += ieLen;
+
+		pSirSmeRsp = qdf_mem_malloc(size);
+		if (!pSirSmeRsp)
+			return;
+		size = sizeof(tSirSmeStartBssRsp);
+		if (resultCode == eSIR_SME_SUCCESS) {
+
+			sir_copy_mac_addr(pSirSmeRsp->bssDescription.bssId,
+					  psessionEntry->bssId);
+
+			/* Read beacon interval from session */
+			pSirSmeRsp->bssDescription.beaconInterval =
+				(uint16_t) psessionEntry->beaconParams.
+				beaconInterval;
+			pSirSmeRsp->bssType = psessionEntry->bssType;
+
+			if (cfg_get_capability_info
+				    (pMac, &pSirSmeRsp->bssDescription.capabilityInfo,
+				    psessionEntry)
+			    != QDF_STATUS_SUCCESS)
+				pe_err("could not retrieve Capabilities value");
+
+			lim_get_phy_mode(pMac,
+					 (uint32_t *) &pSirSmeRsp->bssDescription.
+					 nwType, psessionEntry);
+
+			pSirSmeRsp->bssDescription.channelId =
+				psessionEntry->currentOperChannel;
+
+		if (!LIM_IS_NDI_ROLE(psessionEntry)) {
+			curLen = psessionEntry->schBeaconOffsetBegin - ieOffset;
+			qdf_mem_copy((uint8_t *) &pSirSmeRsp->bssDescription.
+				     ieFields,
+				     psessionEntry->pSchBeaconFrameBegin +
+				     ieOffset, (uint32_t) curLen);
+
+			qdf_mem_copy(((uint8_t *) &pSirSmeRsp->bssDescription.
+				      ieFields) + curLen,
+				     psessionEntry->pSchBeaconFrameEnd,
+				     (uint32_t) psessionEntry->
+				     schBeaconOffsetEnd);
+
+			pSirSmeRsp->bssDescription.length = (uint16_t)
+				(offsetof(tSirBssDescription, ieFields[0])
+				- sizeof(pSirSmeRsp->bssDescription.length)
+				+ ieLen);
+			/* This is the size of the message, subtracting the size of the pointer to ieFields */
+			size += ieLen - sizeof(uint32_t);
+		}
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+			if (psessionEntry->cc_switch_mode
+			    != QDF_MCC_TO_SCC_SWITCH_DISABLE) {
+				pSirSmeRsp->HTProfile.
+				htSupportedChannelWidthSet =
+					psessionEntry->htSupportedChannelWidthSet;
+				pSirSmeRsp->HTProfile.htRecommendedTxWidthSet =
+					psessionEntry->htRecommendedTxWidthSet;
+				pSirSmeRsp->HTProfile.htSecondaryChannelOffset =
+					psessionEntry->htSecondaryChannelOffset;
+				pSirSmeRsp->HTProfile.dot11mode =
+					psessionEntry->dot11mode;
+				pSirSmeRsp->HTProfile.htCapability =
+					psessionEntry->htCapability;
+				pSirSmeRsp->HTProfile.vhtCapability =
+					psessionEntry->vhtCapability;
+				pSirSmeRsp->HTProfile.apCenterChan =
+					psessionEntry->ch_center_freq_seg0;
+				pSirSmeRsp->HTProfile.apChanWidth =
+					psessionEntry->ch_width;
+			}
+#endif
+		}
+	}
+	pSirSmeRsp->messageType = msgType;
+	pSirSmeRsp->length = size;
+
+	/* Update SME session Id and transaction Id */
+	pSirSmeRsp->sessionId = smesessionId;
+	pSirSmeRsp->transactionId = smetransactionId;
+	pSirSmeRsp->statusCode = resultCode;
+	if (psessionEntry != NULL)
+		pSirSmeRsp->staId = psessionEntry->staId;       /* else it will be always zero smeRsp StaID = 0 */
+
+	mmhMsg.type = msgType;
+	mmhMsg.bodyptr = pSirSmeRsp;
+	mmhMsg.bodyval = 0;
+	if (psessionEntry == NULL) {
+		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+				 NO_SESSION, mmhMsg.type));
+	} else {
+		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+				 psessionEntry->peSessionId, mmhMsg.type));
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_START_BSS_RSP_EVENT,
+			      psessionEntry, (uint16_t) resultCode, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+} /*** end lim_send_sme_start_bss_rsp() ***/
+
+void lim_send_sme_disassoc_deauth_ntf(tpAniSirGlobal pMac,
+				      QDF_STATUS status, uint32_t *pCtx)
+{
+	struct scheduler_msg mmhMsg = {0};
+	struct scheduler_msg *pMsg = (struct scheduler_msg *) pCtx;
+
+	mmhMsg.type = pMsg->type;
+	mmhMsg.bodyptr = pMsg;
+	mmhMsg.bodyval = 0;
+
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type));
+
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+}
+
+/**
+ * lim_send_sme_disassoc_ntf()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_DISASSOC_RSP/IND message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * This function is used for sending eWNI_SME_DISASSOC_CNF,
+ * or eWNI_SME_DISASSOC_IND to host depending on
+ * disassociation trigger.
+ *
+ * @param peerMacAddr       Indicates the peer MAC addr to which
+ *                          disassociate was initiated
+ * @param reasonCode        Indicates the reason for Disassociation
+ * @param disassocTrigger   Indicates the trigger for Disassociation
+ * @param aid               Indicates the STAID. This parameter is
+ *                          present only on AP.
+ *
+ * @return None
+ */
+void
+lim_send_sme_disassoc_ntf(tpAniSirGlobal pMac,
+			  tSirMacAddr peerMacAddr,
+			  tSirResultCodes reasonCode,
+			  uint16_t disassocTrigger,
+			  uint16_t aid,
+			  uint8_t smesessionId,
+			  uint16_t smetransactionId, tpPESession psessionEntry)
+{
+
+	uint8_t *pBuf;
+	tSirSmeDisassocRsp *pSirSmeDisassocRsp;
+	tSirSmeDisassocInd *pSirSmeDisassocInd;
+	uint32_t *pMsg = NULL;
+	bool failure = false;
+	tpPESession session = NULL;
+	uint16_t i, assoc_id;
+	tpDphHashNode sta_ds = NULL;
+	QDF_STATUS status;
+
+	pe_debug("Disassoc Ntf with trigger : %d reasonCode: %d",
+		disassocTrigger, reasonCode);
+
+	switch (disassocTrigger) {
+	case eLIM_DUPLICATE_ENTRY:
+		/*
+		 * Duplicate entry is removed at LIM.
+		 * Initiate new entry for other session
+		 */
+		pe_debug("Rcvd eLIM_DUPLICATE_ENTRY for " MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(peerMacAddr));
+
+		for (i = 0; i < pMac->lim.maxBssId; i++) {
+			if ((&pMac->lim.gpSession[i] != NULL) &&
+					(pMac->lim.gpSession[i].valid) &&
+					(pMac->lim.gpSession[i].pePersona ==
+								QDF_SAP_MODE)) {
+				/* Find the sta ds entry in another session */
+				session = &pMac->lim.gpSession[i];
+				sta_ds = dph_lookup_hash_entry(pMac,
+						peerMacAddr, &assoc_id,
+						&session->dph.dphHashTable);
+				if (sta_ds)
+					break;
+			}
+		}
+		if (sta_ds
+#ifdef WLAN_FEATURE_11W
+			&& (!sta_ds->rmfEnabled)
+#endif
+		) {
+			if (lim_add_sta(pMac, sta_ds, false, session) !=
+					QDF_STATUS_SUCCESS)
+					pe_err("could not Add STA with assocId: %d",
+					sta_ds->assocId);
+		}
+		status = lim_prepare_disconnect_done_ind(pMac, &pMsg,
+							 smesessionId,
+							 reasonCode,
+							 &peerMacAddr[0]);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			pe_err("Failed to prepare message");
+			return;
+		}
+		break;
+
+	case eLIM_HOST_DISASSOC:
+		/**
+		 * Disassociation response due to
+		 * host triggered disassociation
+		 */
+
+		pSirSmeDisassocRsp = qdf_mem_malloc(sizeof(tSirSmeDisassocRsp));
+		if (!pSirSmeDisassocRsp) {
+			failure = true;
+			goto error;
+		}
+		pe_debug("send eWNI_SME_DISASSOC_RSP with retCode: %d for " MAC_ADDRESS_STR,
+			reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+		pSirSmeDisassocRsp->messageType = eWNI_SME_DISASSOC_RSP;
+		pSirSmeDisassocRsp->length = sizeof(tSirSmeDisassocRsp);
+		/* sessionId */
+		pBuf = (uint8_t *) &pSirSmeDisassocRsp->sessionId;
+		*pBuf = smesessionId;
+		pBuf++;
+
+		/* transactionId */
+		lim_copy_u16(pBuf, smetransactionId);
+		pBuf += sizeof(uint16_t);
+
+		/* statusCode */
+		lim_copy_u32(pBuf, reasonCode);
+		pBuf += sizeof(tSirResultCodes);
+
+		/* peerMacAddr */
+		qdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
+		pBuf += sizeof(tSirMacAddr);
+
+		/* Clear Station Stats */
+		/* for sta, it is always 1, IBSS is handled at halInitSta */
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+
+		lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_RSP_EVENT,
+				      psessionEntry, (uint16_t) reasonCode, 0);
+#endif
+		pMsg = (uint32_t *) pSirSmeDisassocRsp;
+		break;
+
+	case eLIM_PEER_ENTITY_DISASSOC:
+	case eLIM_LINK_MONITORING_DISASSOC:
+		status = lim_prepare_disconnect_done_ind(pMac, &pMsg,
+						smesessionId,
+						reasonCode, &peerMacAddr[0]);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			pe_err("Failed to prepare message");
+			return;
+		}
+		break;
+
+	default:
+		/**
+		 * Disassociation indication due to Disassociation
+		 * frame reception from peer entity or due to
+		 * loss of link with peer entity.
+		 */
+		pSirSmeDisassocInd = qdf_mem_malloc(sizeof(tSirSmeDisassocInd));
+		if (!pSirSmeDisassocInd) {
+			failure = true;
+			goto error;
+		}
+		pe_debug("send eWNI_SME_DISASSOC_IND with retCode: %d for " MAC_ADDRESS_STR,
+			reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+		pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND;
+		pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd);
+
+		/* Update SME session Id and Transaction Id */
+		pSirSmeDisassocInd->sessionId = smesessionId;
+		pSirSmeDisassocInd->transactionId = smetransactionId;
+		pSirSmeDisassocInd->reasonCode = reasonCode;
+		pBuf = (uint8_t *) &pSirSmeDisassocInd->statusCode;
+
+		lim_copy_u32(pBuf, reasonCode);
+		pBuf += sizeof(tSirResultCodes);
+
+		qdf_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+		pBuf += sizeof(tSirMacAddr);
+
+		qdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+		lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT,
+				      psessionEntry, (uint16_t) reasonCode, 0);
+#endif
+		pMsg = (uint32_t *) pSirSmeDisassocInd;
+
+		break;
+	}
+
+error:
+	/* Delete the PE session Created */
+	if ((psessionEntry != NULL) && LIM_IS_STA_ROLE(psessionEntry))
+		pe_delete_session(pMac, psessionEntry);
+
+	if (false == failure)
+		lim_send_sme_disassoc_deauth_ntf(pMac, QDF_STATUS_SUCCESS,
+						 (uint32_t *) pMsg);
+} /*** end lim_send_sme_disassoc_ntf() ***/
+
+/** -----------------------------------------------------------------
+   \brief lim_send_sme_disassoc_ind() - sends SME_DISASSOC_IND
+
+   After receiving disassociation frame from peer entity, this
+   function sends a eWNI_SME_DISASSOC_IND to SME with a specific
+   reason code.
+
+   \param pMac - global mac structure
+   \param pStaDs - station dph hash node
+   \return none
+   \sa
+   ----------------------------------------------------------------- */
+void
+lim_send_sme_disassoc_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+			  tpPESession psessionEntry)
+{
+	struct scheduler_msg mmhMsg = {0};
+	tSirSmeDisassocInd *pSirSmeDisassocInd;
+
+	pSirSmeDisassocInd = qdf_mem_malloc(sizeof(tSirSmeDisassocInd));
+	if (!pSirSmeDisassocInd)
+		return;
+
+	pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND;
+	pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd);
+
+	pSirSmeDisassocInd->sessionId = psessionEntry->smeSessionId;
+	pSirSmeDisassocInd->transactionId = psessionEntry->transactionId;
+	pSirSmeDisassocInd->statusCode = eSIR_SME_DEAUTH_STATUS;
+	pSirSmeDisassocInd->reasonCode = pStaDs->mlmStaContext.disassocReason;
+
+	qdf_mem_copy(pSirSmeDisassocInd->bssid.bytes, psessionEntry->bssId,
+		     QDF_MAC_ADDR_SIZE);
+
+	qdf_mem_copy(pSirSmeDisassocInd->peer_macaddr.bytes, pStaDs->staAddr,
+		     QDF_MAC_ADDR_SIZE);
+
+	pSirSmeDisassocInd->staId = pStaDs->staIndex;
+
+	mmhMsg.type = eWNI_SME_DISASSOC_IND;
+	mmhMsg.bodyptr = pSirSmeDisassocInd;
+	mmhMsg.bodyval = 0;
+
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+			 psessionEntry->peSessionId, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT, psessionEntry,
+			      0, (uint16_t) pStaDs->mlmStaContext.disassocReason);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+} /*** end lim_send_sme_disassoc_ind() ***/
+
+/** -----------------------------------------------------------------
+   \brief lim_send_sme_deauth_ind() - sends SME_DEAUTH_IND
+
+   After receiving deauthentication frame from peer entity, this
+   function sends a eWNI_SME_DEAUTH_IND to SME with a specific
+   reason code.
+
+   \param pMac - global mac structure
+   \param pStaDs - station dph hash node
+   \return none
+   \sa
+   ----------------------------------------------------------------- */
+void
+lim_send_sme_deauth_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+			tpPESession psessionEntry)
+{
+	struct scheduler_msg mmhMsg = {0};
+	tSirSmeDeauthInd *pSirSmeDeauthInd;
+
+	pSirSmeDeauthInd = qdf_mem_malloc(sizeof(tSirSmeDeauthInd));
+	if (!pSirSmeDeauthInd)
+		return;
+
+	pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND;
+	pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd);
+
+	pSirSmeDeauthInd->sessionId = psessionEntry->smeSessionId;
+	pSirSmeDeauthInd->transactionId = psessionEntry->transactionId;
+	if (eSIR_INFRA_AP_MODE == psessionEntry->bssType) {
+		pSirSmeDeauthInd->statusCode =
+			(tSirResultCodes) pStaDs->mlmStaContext.cleanupTrigger;
+	} else {
+		/* Need to indicatet he reascon code over the air */
+		pSirSmeDeauthInd->statusCode =
+			(tSirResultCodes) pStaDs->mlmStaContext.disassocReason;
+	}
+	/* BSSID */
+	qdf_mem_copy(pSirSmeDeauthInd->bssid.bytes, psessionEntry->bssId,
+		     QDF_MAC_ADDR_SIZE);
+	/* peerMacAddr */
+	qdf_mem_copy(pSirSmeDeauthInd->peer_macaddr.bytes, pStaDs->staAddr,
+		     QDF_MAC_ADDR_SIZE);
+	pSirSmeDeauthInd->reasonCode = pStaDs->mlmStaContext.disassocReason;
+
+	pSirSmeDeauthInd->staId = pStaDs->staIndex;
+	if (eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON ==
+		pStaDs->mlmStaContext.disassocReason)
+		pSirSmeDeauthInd->rssi = pStaDs->del_sta_ctx_rssi;
+
+	mmhMsg.type = eWNI_SME_DEAUTH_IND;
+	mmhMsg.bodyptr = pSirSmeDeauthInd;
+	mmhMsg.bodyval = 0;
+
+	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT, psessionEntry,
+			      0, pStaDs->mlmStaContext.cleanupTrigger);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+	return;
+} /*** end lim_send_sme_deauth_ind() ***/
+
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * lim_send_sme_tdls_del_sta_ind()
+ *
+ ***FUNCTION:
+ * This function is called to send the TDLS STA context deletion to SME.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac   - Pointer to global MAC structure
+ * @param  pStaDs - Pointer to internal STA Datastructure
+ * @param  psessionEntry - Pointer to the session entry
+ * @param  reasonCode - Reason for TDLS sta deletion
+ * @return None
+ */
+void
+lim_send_sme_tdls_del_sta_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+			      tpPESession psessionEntry, uint16_t reasonCode)
+{
+	struct tdls_event_info info;
+
+	pe_debug("Delete TDLS Peer "MAC_ADDRESS_STR "with reason code: %d",
+			MAC_ADDR_ARRAY(pStaDs->staAddr), reasonCode);
+	info.vdev_id = psessionEntry->smeSessionId;
+	qdf_mem_copy(info.peermac.bytes, pStaDs->staAddr, QDF_MAC_ADDR_SIZE);
+	info.message_type = TDLS_PEER_DISCONNECTED;
+	info.peer_reason = TDLS_DISCONNECTED_PEER_DELETE;
+
+	tgt_tdls_event_handler(pMac->psoc, &info);
+
+	return;
+} /*** end lim_send_sme_tdls_del_sta_ind() ***/
+
+/**
+ * lim_send_sme_mgmt_tx_completion()
+ *
+ ***FUNCTION:
+ * This function is called to send the eWNI_SME_MGMT_FRM_TX_COMPLETION_IND
+ * message to SME.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac   - Pointer to global MAC structure
+ * @param  psessionEntry - Pointer to the session entry
+ * @param  txCompleteStatus - TX Complete Status of Mgmt Frames
+ * @return None
+ */
+void
+lim_send_sme_mgmt_tx_completion(tpAniSirGlobal pMac,
+				uint32_t sme_session_id,
+				uint32_t txCompleteStatus)
+{
+	struct scheduler_msg mmhMsg = {0};
+	tSirMgmtTxCompletionInd *pSirMgmtTxCompletionInd;
+
+	pSirMgmtTxCompletionInd =
+		qdf_mem_malloc(sizeof(tSirMgmtTxCompletionInd));
+	if (!pSirMgmtTxCompletionInd)
+		return;
+	/* messageType */
+	pSirMgmtTxCompletionInd->messageType =
+		eWNI_SME_MGMT_FRM_TX_COMPLETION_IND;
+	pSirMgmtTxCompletionInd->length = sizeof(tSirMgmtTxCompletionInd);
+
+	/* sessionId */
+	pSirMgmtTxCompletionInd->sessionId = sme_session_id;
+
+	pSirMgmtTxCompletionInd->txCompleteStatus = txCompleteStatus;
+
+	mmhMsg.type = eWNI_SME_MGMT_FRM_TX_COMPLETION_IND;
+	mmhMsg.bodyptr = pSirMgmtTxCompletionInd;
+	mmhMsg.bodyval = 0;
+
+	pSirMgmtTxCompletionInd->psoc = pMac->psoc;
+	mmhMsg.callback = tgt_tdls_send_mgmt_tx_completion;
+	scheduler_post_message(QDF_MODULE_ID_PE,
+			       QDF_MODULE_ID_TDLS,
+			       QDF_MODULE_ID_TARGET_IF, &mmhMsg);
+	return;
+} /*** end lim_send_sme_tdls_delete_all_peer_ind() ***/
+
+#endif /* FEATURE_WLAN_TDLS */
+
+QDF_STATUS lim_prepare_disconnect_done_ind(tpAniSirGlobal mac_ctx,
+					   uint32_t **msg,
+					   uint8_t session_id,
+					   tSirResultCodes reason_code,
+					   uint8_t *peer_mac_addr)
+{
+	struct sir_sme_discon_done_ind *sir_sme_dis_ind;
+
+	sir_sme_dis_ind = qdf_mem_malloc(sizeof(*sir_sme_dis_ind));
+	if (!sir_sme_dis_ind)
+		return QDF_STATUS_E_FAILURE;
+
+	pe_debug("Prepare eWNI_SME_DISCONNECT_DONE_IND withretCode: %d",
+		 reason_code);
+
+	sir_sme_dis_ind->message_type = eWNI_SME_DISCONNECT_DONE_IND;
+	sir_sme_dis_ind->length = sizeof(*sir_sme_dis_ind);
+	sir_sme_dis_ind->session_id = session_id;
+	if (peer_mac_addr)
+		qdf_mem_copy(sir_sme_dis_ind->peer_mac,
+			     peer_mac_addr, ETH_ALEN);
+
+	/*
+	 * Instead of sending deauth reason code as 505 which is
+	 * internal value(eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE)
+	 * Send reason code as zero to Supplicant
+	 */
+	if (reason_code == eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE)
+		sir_sme_dis_ind->reason_code = 0;
+	else
+		sir_sme_dis_ind->reason_code = reason_code;
+
+	*msg = (uint32_t *)sir_sme_dis_ind;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_send_sme_deauth_ntf()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_DISASSOC_RSP/IND message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * This function is used for sending eWNI_SME_DEAUTH_CNF or
+ * eWNI_SME_DEAUTH_IND to host depending on deauthentication trigger.
+ *
+ * @param peerMacAddr       Indicates the peer MAC addr to which
+ *                          deauthentication was initiated
+ * @param reasonCode        Indicates the reason for Deauthetication
+ * @param deauthTrigger     Indicates the trigger for Deauthetication
+ * @param aid               Indicates the STAID. This parameter is present
+ *                          only on AP.
+ *
+ * @return None
+ */
+void
+lim_send_sme_deauth_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+			tSirResultCodes reasonCode, uint16_t deauthTrigger,
+			uint16_t aid, uint8_t smesessionId,
+			uint16_t smetransactionId)
+{
+	uint8_t *pBuf;
+	tSirSmeDeauthRsp *pSirSmeDeauthRsp;
+	tSirSmeDeauthInd *pSirSmeDeauthInd;
+	tpPESession psessionEntry;
+	uint8_t sessionId;
+	uint32_t *pMsg = NULL;
+	QDF_STATUS status;
+
+	psessionEntry = pe_find_session_by_bssid(pMac, peerMacAddr, &sessionId);
+	switch (deauthTrigger) {
+	case eLIM_HOST_DEAUTH:
+		/**
+		 * Deauthentication response to host triggered
+		 * deauthentication.
+		 */
+		pSirSmeDeauthRsp = qdf_mem_malloc(sizeof(tSirSmeDeauthRsp));
+		if (!pSirSmeDeauthRsp)
+			return;
+		pe_debug("send eWNI_SME_DEAUTH_RSP with retCode: %d for" MAC_ADDRESS_STR,
+			reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+		pSirSmeDeauthRsp->messageType = eWNI_SME_DEAUTH_RSP;
+		pSirSmeDeauthRsp->length = sizeof(tSirSmeDeauthRsp);
+		pSirSmeDeauthRsp->statusCode = reasonCode;
+		pSirSmeDeauthRsp->sessionId = smesessionId;
+		pSirSmeDeauthRsp->transactionId = smetransactionId;
+
+		pBuf = (uint8_t *) pSirSmeDeauthRsp->peer_macaddr.bytes;
+		qdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+		lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_RSP_EVENT,
+				      psessionEntry, 0, (uint16_t) reasonCode);
+#endif
+		pMsg = (uint32_t *) pSirSmeDeauthRsp;
+
+		break;
+
+	case eLIM_PEER_ENTITY_DEAUTH:
+	case eLIM_LINK_MONITORING_DEAUTH:
+		status = lim_prepare_disconnect_done_ind(pMac, &pMsg,
+						smesessionId, reasonCode,
+						&peerMacAddr[0]);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			pe_err("Failed to prepare message");
+			return;
+		}
+		break;
+	default:
+		/**
+		 * Deauthentication indication due to Deauthentication
+		 * frame reception from peer entity or due to
+		 * loss of link with peer entity.
+		 */
+		pSirSmeDeauthInd = qdf_mem_malloc(sizeof(tSirSmeDeauthInd));
+		if (!pSirSmeDeauthInd)
+			return;
+		pe_debug("send eWNI_SME_DEAUTH_IND with retCode: %d for " MAC_ADDRESS_STR,
+			reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+		pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND;
+		pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd);
+		pSirSmeDeauthInd->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
+
+		/* sessionId */
+		pBuf = (uint8_t *) &pSirSmeDeauthInd->sessionId;
+		*pBuf++ = smesessionId;
+
+		/* transaction ID */
+		lim_copy_u16(pBuf, smetransactionId);
+		pBuf += sizeof(uint16_t);
+
+		/* status code */
+		lim_copy_u32(pBuf, reasonCode);
+		pBuf += sizeof(tSirResultCodes);
+
+		/* bssId */
+		qdf_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+		pBuf += sizeof(tSirMacAddr);
+
+		/* peerMacAddr */
+		qdf_mem_copy(pSirSmeDeauthInd->peer_macaddr.bytes, peerMacAddr,
+			     QDF_MAC_ADDR_SIZE);
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+		lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT,
+				      psessionEntry, 0, (uint16_t) reasonCode);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+		pMsg = (uint32_t *) pSirSmeDeauthInd;
+
+		break;
+	}
+
+	/*Delete the PE session  created */
+	if (psessionEntry != NULL) {
+		pe_delete_session(pMac, psessionEntry);
+	}
+
+	lim_send_sme_disassoc_deauth_ntf(pMac, QDF_STATUS_SUCCESS,
+					 (uint32_t *) pMsg);
+
+} /*** end lim_send_sme_deauth_ntf() ***/
+
+/**
+ * lim_send_sme_wm_status_change_ntf() - Send Notification
+ * @mac_ctx:             Global MAC Context
+ * @status_change_code:  Indicates the change in the wireless medium.
+ * @status_change_info:  Indicates the information associated with
+ *                       change in the wireless medium.
+ * @info_len:            Indicates the length of status change information
+ *                       being sent.
+ * @session_id           SessionID
+ *
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_WM_STATUS_CHANGE_NTF message to host.
+ *
+ * Return: None
+ */
+void
+lim_send_sme_wm_status_change_ntf(tpAniSirGlobal mac_ctx,
+	tSirSmeStatusChangeCode status_change_code,
+	uint32_t *status_change_info, uint16_t info_len, uint8_t session_id)
+{
+	struct scheduler_msg msg = {0};
+	tSirSmeWmStatusChangeNtf *wm_status_change_ntf;
+	uint32_t max_info_len;
+
+	wm_status_change_ntf = qdf_mem_malloc(sizeof(tSirSmeWmStatusChangeNtf));
+	if (!wm_status_change_ntf)
+		return;
+
+	msg.type = eWNI_SME_WM_STATUS_CHANGE_NTF;
+	msg.bodyval = 0;
+	msg.bodyptr = wm_status_change_ntf;
+
+	switch (status_change_code) {
+	case eSIR_SME_AP_CAPS_CHANGED:
+		max_info_len = sizeof(tSirSmeApNewCaps);
+		break;
+	case eSIR_SME_JOINED_NEW_BSS:
+		max_info_len = sizeof(tSirSmeNewBssInfo);
+		break;
+	default:
+		max_info_len = sizeof(wm_status_change_ntf->statusChangeInfo);
+		break;
+	}
+
+	switch (status_change_code) {
+	case eSIR_SME_RADAR_DETECTED:
+		break;
+	default:
+		wm_status_change_ntf->messageType =
+			eWNI_SME_WM_STATUS_CHANGE_NTF;
+		wm_status_change_ntf->statusChangeCode = status_change_code;
+		wm_status_change_ntf->length = sizeof(tSirSmeWmStatusChangeNtf);
+		wm_status_change_ntf->sessionId = session_id;
+		if (info_len <= max_info_len && status_change_info) {
+			qdf_mem_copy(
+			    (uint8_t *) &wm_status_change_ntf->statusChangeInfo,
+			    (uint8_t *) status_change_info, info_len);
+		}
+		pe_debug("StatusChg code: 0x%x length: %d",
+			status_change_code, info_len);
+		break;
+	}
+
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG, session_id, msg.type));
+	if (QDF_STATUS_SUCCESS != lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT)) {
+		qdf_mem_free(wm_status_change_ntf);
+		pe_err("lim_sys_process_mmh_msg_api failed");
+	}
+
+} /*** end lim_send_sme_wm_status_change_ntf() ***/
+
+/**
+ * lim_send_sme_set_context_rsp()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_SETCONTEXT_RSP message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param pMac         Pointer to Global MAC structure
+ * @param peerMacAddr  Indicates the peer MAC addr to which
+ *                     setContext was performed
+ * @param aid          Indicates the aid corresponding to the peer MAC
+ *                     address
+ * @param resultCode   Indicates the result of previously issued
+ *                     eWNI_SME_SETCONTEXT_RSP message
+ *
+ * @return None
+ */
+void
+lim_send_sme_set_context_rsp(tpAniSirGlobal pMac,
+			     struct qdf_mac_addr peer_macaddr, uint16_t aid,
+			     tSirResultCodes resultCode,
+			     tpPESession psessionEntry, uint8_t smesessionId,
+			     uint16_t smetransactionId)
+{
+	struct scheduler_msg mmhMsg = {0};
+	tSirSmeSetContextRsp *pSirSmeSetContextRsp;
+
+	pSirSmeSetContextRsp = qdf_mem_malloc(sizeof(tSirSmeSetContextRsp));
+	if (!pSirSmeSetContextRsp)
+		return;
+
+	pSirSmeSetContextRsp->messageType = eWNI_SME_SETCONTEXT_RSP;
+	pSirSmeSetContextRsp->length = sizeof(tSirSmeSetContextRsp);
+	pSirSmeSetContextRsp->statusCode = resultCode;
+
+	qdf_copy_macaddr(&pSirSmeSetContextRsp->peer_macaddr, &peer_macaddr);
+
+	/* Update SME session and transaction Id */
+	pSirSmeSetContextRsp->sessionId = smesessionId;
+	pSirSmeSetContextRsp->transactionId = smetransactionId;
+
+	mmhMsg.type = eWNI_SME_SETCONTEXT_RSP;
+	mmhMsg.bodyptr = pSirSmeSetContextRsp;
+	mmhMsg.bodyval = 0;
+	if (NULL == psessionEntry) {
+		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+				 NO_SESSION, mmhMsg.type));
+	} else {
+		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+				 psessionEntry->peSessionId, mmhMsg.type));
+	}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT,
+			      psessionEntry, (uint16_t) resultCode, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	pMac->lim.sme_msg_callback(pMac, &mmhMsg);
+} /*** end lim_send_sme_set_context_rsp() ***/
+
+/** -----------------------------------------------------------------
+   \brief lim_send_sme_addts_rsp() - sends SME ADDTS RSP
+ \      This function sends a eWNI_SME_ADDTS_RSP to SME.
+ \      SME only looks at rc and tspec field.
+   \param pMac - global mac structure
+   \param rspReqd - is SmeAddTsRsp required
+   \param status - status code of SME_ADD_TS_RSP
+   \return tspec
+   \sa
+   ----------------------------------------------------------------- */
+void
+lim_send_sme_addts_rsp(tpAniSirGlobal pMac, uint8_t rspReqd, uint32_t status,
+		       tpPESession psessionEntry, tSirMacTspecIE tspec,
+		       uint8_t smesessionId, uint16_t smetransactionId)
+{
+	tpSirAddtsRsp rsp;
+	struct scheduler_msg mmhMsg = {0};
+
+	if (!rspReqd)
+		return;
+
+	rsp = qdf_mem_malloc(sizeof(tSirAddtsRsp));
+	if (!rsp)
+		return;
+
+	rsp->messageType = eWNI_SME_ADDTS_RSP;
+	rsp->rc = status;
+	rsp->rsp.status = (enum eSirMacStatusCodes)status;
+	rsp->rsp.tspec = tspec;
+	/* Update SME session Id and transcation Id */
+	rsp->sessionId = smesessionId;
+	rsp->transactionId = smetransactionId;
+
+	mmhMsg.type = eWNI_SME_ADDTS_RSP;
+	mmhMsg.bodyptr = rsp;
+	mmhMsg.bodyval = 0;
+	if (NULL == psessionEntry) {
+		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+				 NO_SESSION, mmhMsg.type));
+	} else {
+		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+				 psessionEntry->peSessionId, mmhMsg.type));
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_ADDTS_RSP_EVENT, psessionEntry, 0,
+			      0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+	return;
+}
+
+void
+lim_send_sme_delts_rsp(tpAniSirGlobal pMac, tpSirDeltsReq delts, uint32_t status,
+		       tpPESession psessionEntry, uint8_t smesessionId,
+		       uint16_t smetransactionId)
+{
+	tpSirDeltsRsp rsp;
+	struct scheduler_msg mmhMsg = {0};
+
+	pe_debug("SendSmeDeltsRsp aid: %d tsid: %d up: %d status: %d",
+		delts->aid,
+		delts->req.tsinfo.traffic.tsid,
+		delts->req.tsinfo.traffic.userPrio, status);
+	if (!delts->rspReqd)
+		return;
+
+	rsp = qdf_mem_malloc(sizeof(tSirDeltsRsp));
+	if (!rsp)
+		return;
+
+	if (psessionEntry != NULL) {
+
+		rsp->aid = delts->aid;
+		qdf_copy_macaddr(&rsp->macaddr, &delts->macaddr);
+		qdf_mem_copy((uint8_t *) &rsp->rsp, (uint8_t *) &delts->req,
+			     sizeof(tSirDeltsReqInfo));
+	}
+
+	rsp->messageType = eWNI_SME_DELTS_RSP;
+	rsp->rc = status;
+
+	/* Update SME session Id and transcation Id */
+	rsp->sessionId = smesessionId;
+	rsp->transactionId = smetransactionId;
+
+	mmhMsg.type = eWNI_SME_DELTS_RSP;
+	mmhMsg.bodyptr = rsp;
+	mmhMsg.bodyval = 0;
+	if (NULL == psessionEntry) {
+		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+				 NO_SESSION, mmhMsg.type));
+	} else {
+		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+				 psessionEntry->peSessionId, mmhMsg.type));
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_RSP_EVENT, psessionEntry,
+			      (uint16_t) status, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+}
+
+void
+lim_send_sme_delts_ind(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, uint16_t aid,
+		       tpPESession psessionEntry)
+{
+	tpSirDeltsRsp rsp;
+	struct scheduler_msg mmhMsg = {0};
+
+	pe_debug("SendSmeDeltsInd aid: %d tsid: %d up: %d",
+		aid, delts->tsinfo.traffic.tsid, delts->tsinfo.traffic.userPrio);
+
+	rsp = qdf_mem_malloc(sizeof(tSirDeltsRsp));
+	if (!rsp)
+		return;
+
+	rsp->messageType = eWNI_SME_DELTS_IND;
+	rsp->rc = QDF_STATUS_SUCCESS;
+	rsp->aid = aid;
+	qdf_mem_copy((uint8_t *) &rsp->rsp, (uint8_t *) delts, sizeof(*delts));
+
+	/* Update SME  session Id and SME transaction Id */
+
+	rsp->sessionId = psessionEntry->smeSessionId;
+	rsp->transactionId = psessionEntry->transactionId;
+
+	mmhMsg.type = eWNI_SME_DELTS_IND;
+	mmhMsg.bodyptr = rsp;
+	mmhMsg.bodyval = 0;
+	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
+	lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_IND_EVENT, psessionEntry, 0,
+			      0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+}
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * lim_send_sme_pe_statistics_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to send 802.11 statistics response to HDD.
+ * This function posts the result back to HDD. This is a response to
+ * HDD's request for statistics.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac         Pointer to Global MAC structure
+ * @param p80211Stats  Statistics sent in response
+ * @param resultCode   TODO:
+ *
+ *
+ * @return none
+ */
+
+void
+lim_send_sme_pe_statistics_rsp(tpAniSirGlobal pMac, uint16_t msgType, void *stats)
+{
+	struct scheduler_msg mmhMsg = {0};
+	uint8_t sessionId;
+	tAniGetPEStatsRsp *pPeStats = (tAniGetPEStatsRsp *) stats;
+	tpPESession pPeSessionEntry;
+
+	/* Get the Session Id based on Sta Id */
+	pPeSessionEntry =
+		pe_find_session_by_sta_id(pMac, pPeStats->staId, &sessionId);
+
+	/* Fill the Session Id */
+	if (NULL != pPeSessionEntry) {
+		/* Fill the Session Id */
+		pPeStats->sessionId = pPeSessionEntry->smeSessionId;
+	}
+
+	pPeStats->msgType = eWNI_SME_GET_STATISTICS_RSP;
+
+	/* msgType should be WMA_GET_STATISTICS_RSP */
+	mmhMsg.type = eWNI_SME_GET_STATISTICS_RSP;
+
+	mmhMsg.bodyptr = stats;
+	mmhMsg.bodyval = 0;
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type));
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+	return;
+
+} /*** end lim_send_sme_pe_statistics_rsp() ***/
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * lim_send_sme_pe_ese_tsm_rsp() - send tsm response
+ * @pMac:   Pointer to global pMac structure
+ * @pStats: Pointer to TSM Stats
+ *
+ * This function is called to send tsm stats response to HDD.
+ * This function posts the result back to HDD. This is a response to
+ * HDD's request to get tsm stats.
+ *
+ * Return: None
+ */
+void lim_send_sme_pe_ese_tsm_rsp(tpAniSirGlobal pMac,
+				 tAniGetTsmStatsRsp *pStats)
+{
+	struct scheduler_msg mmhMsg = {0};
+	uint8_t sessionId;
+	tAniGetTsmStatsRsp *pPeStats = (tAniGetTsmStatsRsp *) pStats;
+	tpPESession pPeSessionEntry = NULL;
+
+	/* Get the Session Id based on Sta Id */
+	pPeSessionEntry =
+		pe_find_session_by_sta_id(pMac, pPeStats->staId, &sessionId);
+
+	/* Fill the Session Id */
+	if (NULL != pPeSessionEntry) {
+		/* Fill the Session Id */
+		pPeStats->sessionId = pPeSessionEntry->smeSessionId;
+	} else {
+		pe_err("Session not found for the Sta id: %d",
+		       pPeStats->staId);
+		qdf_mem_free(pPeStats->tsmStatsReq);
+		qdf_mem_free(pPeStats);
+		return;
+	}
+
+	pPeStats->msgType = eWNI_SME_GET_TSM_STATS_RSP;
+	pPeStats->tsmMetrics.RoamingCount
+		= pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingCount;
+	pPeStats->tsmMetrics.RoamingDly
+		= pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly;
+
+	mmhMsg.type = eWNI_SME_GET_TSM_STATS_RSP;
+	mmhMsg.bodyptr = pStats;
+	mmhMsg.bodyval = 0;
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type));
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+	return;
+} /*** end lim_send_sme_pe_ese_tsm_rsp() ***/
+
+#endif /* FEATURE_WLAN_ESE */
+
+void
+lim_send_sme_ibss_peer_ind(tpAniSirGlobal pMac,
+			   tSirMacAddr peerMacAddr,
+			   uint16_t staIndex,
+			   uint8_t *beacon,
+			   uint16_t beaconLen, uint16_t msgType, uint8_t sessionId)
+{
+	struct scheduler_msg mmhMsg = {0};
+	tSmeIbssPeerInd *pNewPeerInd;
+
+	pNewPeerInd = qdf_mem_malloc(sizeof(tSmeIbssPeerInd) + beaconLen);
+	if (!pNewPeerInd)
+		return;
+
+	qdf_mem_copy((uint8_t *) pNewPeerInd->peer_addr.bytes,
+		     peerMacAddr, QDF_MAC_ADDR_SIZE);
+	pNewPeerInd->staId = staIndex;
+	pNewPeerInd->mesgLen = sizeof(tSmeIbssPeerInd) + beaconLen;
+	pNewPeerInd->mesgType = msgType;
+	pNewPeerInd->sessionId = sessionId;
+
+	if (beacon != NULL) {
+		qdf_mem_copy((void *)((uint8_t *) pNewPeerInd +
+				      sizeof(tSmeIbssPeerInd)), (void *)beacon,
+			     beaconLen);
+	}
+
+	mmhMsg.type = msgType;
+	mmhMsg.bodyptr = pNewPeerInd;
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type));
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+}
+
+/**
+ * lim_process_csa_wbw_ie() - Process CSA Wide BW IE
+ * @mac_ctx:         pointer to global adapter context
+ * @csa_params:      pointer to CSA parameters
+ * @chnl_switch_info:pointer to channel switch parameters
+ * @session_entry:   session pointer
+ *
+ * Return: None
+ */
+static QDF_STATUS lim_process_csa_wbw_ie(tpAniSirGlobal mac_ctx,
+		struct csa_offload_params *csa_params,
+		tLimWiderBWChannelSwitchInfo *chnl_switch_info,
+		tpPESession session_entry)
+{
+	struct ch_params ch_params = {0};
+	uint8_t ap_new_ch_width;
+	bool new_ch_width_dfn = false;
+	uint8_t center_freq_diff;
+	uint32_t fw_vht_ch_wd = wma_get_vht_ch_width() + 1;
+
+	ap_new_ch_width = csa_params->new_ch_width + 1;
+
+	pe_debug("new channel: %d new_ch_width: %d seg0: %d seg1: %d",
+		 csa_params->channel, ap_new_ch_width,
+		 csa_params->new_ch_freq_seg1,
+		 csa_params->new_ch_freq_seg2);
+
+	if ((ap_new_ch_width != CH_WIDTH_80MHZ) &&
+			(ap_new_ch_width != CH_WIDTH_160MHZ) &&
+			(ap_new_ch_width != CH_WIDTH_80P80MHZ)) {
+		pe_err("CSA wide BW IE has wrong ch_width %d",
+				csa_params->new_ch_width);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!csa_params->new_ch_freq_seg1 && !csa_params->new_ch_freq_seg2) {
+		pe_err("CSA wide BW IE has invalid center freq");
+		return QDF_STATUS_E_INVAL;
+	}
+	if ((ap_new_ch_width == CH_WIDTH_80MHZ) &&
+			csa_params->new_ch_freq_seg2) {
+		new_ch_width_dfn = true;
+		if (csa_params->new_ch_freq_seg2 >
+				csa_params->new_ch_freq_seg1)
+			center_freq_diff = csa_params->new_ch_freq_seg2 -
+				csa_params->new_ch_freq_seg1;
+		else
+			center_freq_diff = csa_params->new_ch_freq_seg1 -
+				csa_params->new_ch_freq_seg2;
+		if (center_freq_diff == CENTER_FREQ_DIFF_160MHz)
+			ap_new_ch_width = CH_WIDTH_160MHZ;
+		else if (center_freq_diff > CENTER_FREQ_DIFF_80P80MHz)
+			ap_new_ch_width = CH_WIDTH_80P80MHZ;
+		else
+			ap_new_ch_width = CH_WIDTH_80MHZ;
+	}
+	session_entry->gLimChannelSwitch.state =
+		eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+	if ((ap_new_ch_width == CH_WIDTH_160MHZ) &&
+			!new_ch_width_dfn) {
+		if (csa_params->new_ch_freq_seg1 != csa_params->channel +
+				CH_TO_CNTR_FREQ_DIFF_160MHz) {
+			pe_err("CSA wide BW IE has invalid center freq");
+			return QDF_STATUS_E_INVAL;
+		}
+
+		if (ap_new_ch_width > fw_vht_ch_wd) {
+			pe_debug("New BW is not supported, setting BW to %d",
+				 fw_vht_ch_wd);
+			ap_new_ch_width = fw_vht_ch_wd;
+		}
+		ch_params.ch_width = ap_new_ch_width ;
+		wlan_reg_set_channel_params(mac_ctx->pdev,
+					    csa_params->channel, 0, &ch_params);
+		ap_new_ch_width = ch_params.ch_width;
+		csa_params->new_ch_freq_seg1 = ch_params.center_freq_seg0;
+		csa_params->new_ch_freq_seg2 = ch_params.center_freq_seg1;
+	} else if (!new_ch_width_dfn) {
+		if (ap_new_ch_width > fw_vht_ch_wd) {
+			pe_debug("New BW is not supported, setting BW to %d",
+				 fw_vht_ch_wd);
+			ap_new_ch_width = fw_vht_ch_wd;
+		}
+		if (csa_params->new_ch_freq_seg1 != csa_params->channel +
+				CH_TO_CNTR_FREQ_DIFF_80MHz) {
+			pe_err("CSA wide BW IE has invalid center freq");
+			return QDF_STATUS_E_INVAL;
+		}
+		csa_params->new_ch_freq_seg2 = 0;
+	}
+	if (new_ch_width_dfn) {
+		if (csa_params->new_ch_freq_seg1 != csa_params->channel +
+				CH_TO_CNTR_FREQ_DIFF_80MHz) {
+			pe_err("CSA wide BW IE has invalid center freq");
+			return QDF_STATUS_E_INVAL;
+		}
+		if (ap_new_ch_width > fw_vht_ch_wd) {
+			pe_debug("New width is not supported, setting BW to %d",
+				 fw_vht_ch_wd);
+			ap_new_ch_width = fw_vht_ch_wd;
+		}
+		if ((ap_new_ch_width == CH_WIDTH_160MHZ) &&
+				(csa_params->new_ch_freq_seg1 !=
+				 csa_params->channel +
+				 CH_TO_CNTR_FREQ_DIFF_160MHz)) {
+			pe_err("wide BW IE has invalid 160M center freq");
+			csa_params->new_ch_freq_seg2 = 0;
+			ap_new_ch_width = CH_WIDTH_80MHZ;
+		}
+	}
+	chnl_switch_info->newChanWidth = ap_new_ch_width;
+	chnl_switch_info->newCenterChanFreq0 = csa_params->new_ch_freq_seg1;
+	chnl_switch_info->newCenterChanFreq1 = csa_params->new_ch_freq_seg2;
+
+	if (session_entry->ch_width == ap_new_ch_width)
+		goto prnt_log;
+
+	if (session_entry->ch_width == CH_WIDTH_80MHZ) {
+		chnl_switch_info->newChanWidth = CH_WIDTH_80MHZ;
+		chnl_switch_info->newCenterChanFreq1 = 0;
+	} else {
+		session_entry->ch_width = ap_new_ch_width;
+		chnl_switch_info->newChanWidth = ap_new_ch_width;
+	}
+prnt_log:
+	pe_debug("new channel: %d new_ch_width: %d seg0: %d seg1: %d",
+			csa_params->channel,
+			chnl_switch_info->newChanWidth,
+			chnl_switch_info->newCenterChanFreq0,
+			chnl_switch_info->newCenterChanFreq1);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_handle_csa_offload_msg() - Handle CSA offload message
+ * @mac_ctx:         pointer to global adapter context
+ * @msg:             Message pointer.
+ *
+ * Return: None
+ */
+void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx,
+				struct scheduler_msg *msg)
+{
+	tpPESession session_entry;
+	struct scheduler_msg mmh_msg = {0};
+	struct csa_offload_params *csa_params =
+				(struct csa_offload_params *) (msg->bodyptr);
+	tpSmeCsaOffloadInd csa_offload_ind;
+	tpDphHashNode sta_ds = NULL;
+	uint8_t session_id;
+	uint16_t aid = 0;
+	uint16_t chan_space = 0;
+	struct ch_params ch_params = {0};
+
+	tLimWiderBWChannelSwitchInfo *chnl_switch_info = NULL;
+	tLimChannelSwitchInfo *lim_ch_switch = NULL;
+
+	pe_debug("handle csa offload msg");
+
+	if (!csa_params) {
+		pe_err("limMsgQ body ptr is NULL");
+		return;
+	}
+
+	csa_offload_ind = qdf_mem_malloc(sizeof(tSmeCsaOffloadInd));
+	if (!csa_offload_ind)
+		goto err;
+
+	session_entry =
+		pe_find_session_by_bssid(mac_ctx,
+			csa_params->bssId, &session_id);
+	if (!session_entry) {
+		pe_err("Session does not exists for %pM",
+				csa_params->bssId);
+		qdf_mem_free(csa_offload_ind);
+		goto err;
+	}
+
+	sta_ds = dph_lookup_hash_entry(mac_ctx, session_entry->bssId, &aid,
+		&session_entry->dph.dphHashTable);
+
+	if (!sta_ds) {
+		pe_err("sta_ds does not exist");
+		qdf_mem_free(csa_offload_ind);
+		goto err;
+	}
+
+	if (!LIM_IS_STA_ROLE(session_entry)) {
+		pe_debug("Invalid role to handle CSA");
+		qdf_mem_free(csa_offload_ind);
+		goto err;
+	}
+
+	/*
+	 * on receiving channel switch announcement from AP, delete all
+	 * TDLS peers before leaving BSS and proceed for channel switch
+	 */
+	lim_delete_tdls_peers(mac_ctx, session_entry);
+
+	lim_ch_switch = &session_entry->gLimChannelSwitch;
+	session_entry->gLimChannelSwitch.switchMode =
+		csa_params->switch_mode;
+	/* timer already started by firmware, switch immediately */
+	session_entry->gLimChannelSwitch.switchCount = 0;
+	session_entry->gLimChannelSwitch.primaryChannel =
+		csa_params->channel;
+	session_entry->gLimChannelSwitch.state =
+		eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+	session_entry->gLimChannelSwitch.ch_width = CH_WIDTH_20MHZ;
+	lim_ch_switch->sec_ch_offset =
+		session_entry->htSecondaryChannelOffset;
+	session_entry->gLimChannelSwitch.ch_center_freq_seg0 = 0;
+	session_entry->gLimChannelSwitch.ch_center_freq_seg1 = 0;
+	chnl_switch_info =
+		&session_entry->gLimWiderBWChannelSwitch;
+
+	pe_debug("vht: %d ht: %d flag: %x chan: %d, sec_ch_offset %d",
+		 session_entry->vhtCapability,
+		 session_entry->htSupportedChannelWidthSet,
+		 csa_params->ies_present_flag,
+		 csa_params->channel,
+		 csa_params->sec_chan_offset);
+	pe_debug("seg1: %d seg2: %d width: %d country: %s class: %d",
+		 csa_params->new_ch_freq_seg1,
+		 csa_params->new_ch_freq_seg2,
+		 csa_params->new_ch_width,
+		 mac_ctx->scan.countryCodeCurrent,
+		 csa_params->new_op_class);
+
+	if (session_entry->vhtCapability &&
+			session_entry->htSupportedChannelWidthSet) {
+		if ((csa_params->ies_present_flag & lim_wbw_ie_present) &&
+			(QDF_STATUS_SUCCESS == lim_process_csa_wbw_ie(mac_ctx,
+					csa_params, chnl_switch_info,
+					session_entry))) {
+			pe_debug("CSA wide BW IE process successful");
+			lim_ch_switch->sec_ch_offset =
+				PHY_SINGLE_CHANNEL_CENTERED;
+			if (chnl_switch_info->newChanWidth) {
+				if (csa_params->channel <
+				  csa_params->new_ch_freq_seg1)
+					lim_ch_switch->sec_ch_offset =
+						PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+				else
+					lim_ch_switch->sec_ch_offset =
+						PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+			}
+		} else if (csa_params->ies_present_flag
+				& lim_xcsa_ie_present) {
+			chan_space =
+				wlan_reg_dmn_get_chanwidth_from_opclass(
+						mac_ctx->scan.countryCodeCurrent,
+						csa_params->channel,
+						csa_params->new_op_class);
+			session_entry->gLimChannelSwitch.state =
+				eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+
+			if (chan_space == 80) {
+				chnl_switch_info->newChanWidth =
+					CH_WIDTH_80MHZ;
+			} else if (chan_space == 40) {
+				chnl_switch_info->newChanWidth =
+					CH_WIDTH_40MHZ;
+			} else {
+				chnl_switch_info->newChanWidth =
+					CH_WIDTH_20MHZ;
+				lim_ch_switch->state =
+					eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+			}
+
+			ch_params.ch_width =
+				chnl_switch_info->newChanWidth;
+			wlan_reg_set_channel_params(mac_ctx->pdev,
+					csa_params->channel, 0, &ch_params);
+			chnl_switch_info->newCenterChanFreq0 =
+				ch_params.center_freq_seg0;
+			/*
+			 * This is not applicable for 20/40/80 MHz.
+			 * Only used when we support 80+80 MHz operation.
+			 * In case of 80+80 MHz, this parameter indicates
+			 * center channel frequency index of 80 MHz
+			 * channel offrequency segment 1.
+			 */
+			chnl_switch_info->newCenterChanFreq1 =
+				ch_params.center_freq_seg1;
+			lim_ch_switch->sec_ch_offset =
+				ch_params.sec_ch_offset;
+
+		} else {
+			lim_ch_switch->state =
+				eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+			ch_params.ch_width = CH_WIDTH_40MHZ;
+			wlan_reg_set_channel_params(mac_ctx->pdev,
+					csa_params->channel, 0, &ch_params);
+			lim_ch_switch->sec_ch_offset =
+				ch_params.sec_ch_offset;
+			chnl_switch_info->newChanWidth = CH_WIDTH_40MHZ;
+			chnl_switch_info->newCenterChanFreq0 =
+				ch_params.center_freq_seg0;
+			chnl_switch_info->newCenterChanFreq1 = 0;
+		}
+		session_entry->gLimChannelSwitch.ch_center_freq_seg0 =
+			chnl_switch_info->newCenterChanFreq0;
+		session_entry->gLimChannelSwitch.ch_center_freq_seg1 =
+			chnl_switch_info->newCenterChanFreq1;
+		session_entry->gLimChannelSwitch.ch_width =
+			chnl_switch_info->newChanWidth;
+
+	} else if (session_entry->htSupportedChannelWidthSet) {
+		if (csa_params->ies_present_flag
+				& lim_xcsa_ie_present) {
+			chan_space =
+				wlan_reg_dmn_get_chanwidth_from_opclass(
+						mac_ctx->scan.countryCodeCurrent,
+						csa_params->channel,
+						csa_params->new_op_class);
+			lim_ch_switch->state =
+				eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+			if (chan_space == 40) {
+				lim_ch_switch->ch_width =
+					CH_WIDTH_40MHZ;
+				chnl_switch_info->newChanWidth =
+					CH_WIDTH_40MHZ;
+				ch_params.ch_width =
+					chnl_switch_info->newChanWidth;
+				wlan_reg_set_channel_params(mac_ctx->pdev,
+						csa_params->channel,
+						0, &ch_params);
+				lim_ch_switch->ch_center_freq_seg0 =
+					ch_params.center_freq_seg0;
+				lim_ch_switch->sec_ch_offset =
+					ch_params.sec_ch_offset;
+			} else {
+				lim_ch_switch->ch_width =
+					CH_WIDTH_20MHZ;
+				chnl_switch_info->newChanWidth =
+					CH_WIDTH_40MHZ;
+				lim_ch_switch->state =
+					eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+				lim_ch_switch->sec_ch_offset =
+					PHY_SINGLE_CHANNEL_CENTERED;
+			}
+		} else {
+			lim_ch_switch->ch_width =
+				CH_WIDTH_40MHZ;
+			lim_ch_switch->state =
+				eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+			ch_params.ch_width = CH_WIDTH_40MHZ;
+			wlan_reg_set_channel_params(mac_ctx->pdev,
+					csa_params->channel, 0, &ch_params);
+			lim_ch_switch->ch_center_freq_seg0 =
+				ch_params.center_freq_seg0;
+			lim_ch_switch->sec_ch_offset =
+				ch_params.sec_ch_offset;
+		}
+
+	}
+	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");
+		qdf_mem_free(csa_offload_ind);
+		goto err;
+	}
+
+	if (WLAN_REG_IS_24GHZ_CH(csa_params->channel) &&
+	    (session_entry->dot11mode == WNI_CFG_DOT11_MODE_11A))
+		session_entry->dot11mode = WNI_CFG_DOT11_MODE_11G;
+	else if (WLAN_REG_IS_5GHZ_CH(csa_params->channel) &&
+		 ((session_entry->dot11mode == WNI_CFG_DOT11_MODE_11G) ||
+		 (session_entry->dot11mode == WNI_CFG_DOT11_MODE_11G_ONLY)))
+		session_entry->dot11mode = WNI_CFG_DOT11_MODE_11A;
+
+	/* Send RSO Stop to FW before triggering the vdev restart for CSA */
+	if (mac_ctx->lim.stop_roaming_callback)
+		mac_ctx->lim.stop_roaming_callback(mac_ctx,
+						   session_entry->smeSessionId,
+						   ecsr_driver_disabled);
+
+	lim_prepare_for11h_channel_switch(mac_ctx, session_entry);
+
+	csa_offload_ind->mesgType = eWNI_SME_CSA_OFFLOAD_EVENT;
+	csa_offload_ind->mesgLen = sizeof(tSmeCsaOffloadInd);
+	qdf_mem_copy(csa_offload_ind->bssid.bytes, session_entry->bssId,
+			QDF_MAC_ADDR_SIZE);
+	mmh_msg.type = eWNI_SME_CSA_OFFLOAD_EVENT;
+	mmh_msg.bodyptr = csa_offload_ind;
+	mmh_msg.bodyval = 0;
+	pe_debug("Sending eWNI_SME_CSA_OFFLOAD_EVENT to SME");
+	MTRACE(mac_trace_msg_tx
+			(mac_ctx, session_entry->peSessionId, mmh_msg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	lim_diag_event_report(mac_ctx,
+			WLAN_PE_DIAG_SWITCH_CHL_IND_EVENT, session_entry,
+			QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
+#endif
+	lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT);
+
+err:
+	qdf_mem_free(csa_params);
+}
+
+/*--------------------------------------------------------------------------
+   \brief pe_delete_session() - Handle the Delete BSS Response from HAL.
+
+   \param pMac                   - pointer to global adapter context
+   \param sessionId             - Message pointer.
+
+   \sa
+   --------------------------------------------------------------------------*/
+
+void lim_handle_delete_bss_rsp(tpAniSirGlobal pMac, struct scheduler_msg *MsgQ)
+{
+	tpPESession psessionEntry;
+	tpDeleteBssParams pDelBss = (tpDeleteBssParams) (MsgQ->bodyptr);
+
+	psessionEntry =
+		pe_find_session_by_session_id(pMac, pDelBss->sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given sessionID: %d",
+			pDelBss->sessionId);
+		qdf_mem_free(MsgQ->bodyptr);
+		MsgQ->bodyptr = NULL;
+		return;
+	}
+
+	/*
+	 * During DEL BSS handling, the PE Session will be deleted, but it is
+	 * better to clear this flag if the session is hanging around due
+	 * to some error conditions so that the next DEL_BSS request does
+	 * not take the HO_FAIL path
+	 */
+	psessionEntry->process_ho_fail = false;
+	if (LIM_IS_IBSS_ROLE(psessionEntry))
+		lim_ibss_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry);
+	else if (LIM_IS_UNKNOWN_ROLE(psessionEntry))
+		lim_process_sme_del_bss_rsp(pMac, MsgQ->bodyval, psessionEntry);
+	else if (LIM_IS_NDI_ROLE(psessionEntry))
+		lim_ndi_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry);
+	else
+		lim_process_mlm_del_bss_rsp(pMac, MsgQ, psessionEntry);
+
+}
+
+/** -----------------------------------------------------------------
+   \brief lim_send_sme_aggr_qos_rsp() - sends SME FT AGGR QOS RSP
+ \      This function sends a eWNI_SME_FT_AGGR_QOS_RSP to SME.
+ \      SME only looks at rc and tspec field.
+   \param pMac - global mac structure
+   \param rspReqd - is SmeAddTsRsp required
+   \param status - status code of eWNI_SME_FT_AGGR_QOS_RSP
+   \return tspec
+   \sa
+   ----------------------------------------------------------------- */
+void
+lim_send_sme_aggr_qos_rsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp,
+			  uint8_t smesessionId)
+{
+	struct scheduler_msg mmhMsg = {0};
+
+	mmhMsg.type = eWNI_SME_FT_AGGR_QOS_RSP;
+	mmhMsg.bodyptr = aggrQosRsp;
+	mmhMsg.bodyval = 0;
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+			 smesessionId, mmhMsg.type));
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+	return;
+}
+
+void lim_send_sme_max_assoc_exceeded_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+					 uint8_t smesessionId)
+{
+	struct scheduler_msg mmhMsg = {0};
+	tSmeMaxAssocInd *pSmeMaxAssocInd;
+
+	pSmeMaxAssocInd = qdf_mem_malloc(sizeof(tSmeMaxAssocInd));
+	if (!pSmeMaxAssocInd)
+		return;
+	qdf_mem_copy((uint8_t *) pSmeMaxAssocInd->peer_mac.bytes,
+		     (uint8_t *) peerMacAddr, QDF_MAC_ADDR_SIZE);
+	pSmeMaxAssocInd->mesgType = eWNI_SME_MAX_ASSOC_EXCEEDED;
+	pSmeMaxAssocInd->mesgLen = sizeof(tSmeMaxAssocInd);
+	pSmeMaxAssocInd->sessionId = smesessionId;
+	mmhMsg.type = pSmeMaxAssocInd->mesgType;
+	mmhMsg.bodyptr = pSmeMaxAssocInd;
+	pe_debug("msgType: %s peerMacAddr "MAC_ADDRESS_STR "sme session id %d",
+		"eWNI_SME_MAX_ASSOC_EXCEEDED", MAC_ADDR_ARRAY(peerMacAddr),
+		pSmeMaxAssocInd->sessionId);
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+			 smesessionId, mmhMsg.type));
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+	return;
+}
+
+/** -----------------------------------------------------------------
+   \brief lim_send_sme_ap_channel_switch_resp() - sends
+   eWNI_SME_CHANNEL_CHANGE_RSP
+   After receiving WMA_SWITCH_CHANNEL_RSP indication this
+   function sends a eWNI_SME_CHANNEL_CHANGE_RSP to SME to notify
+   that the Channel change has been done to the specified target
+   channel in the Channel change request
+   \param pMac - global mac structure
+   \param psessionEntry - session info
+   \param pChnlParams - Channel switch params
+   --------------------------------------------------------------------*/
+void
+lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac,
+				    tpPESession psessionEntry,
+				    tpSwitchChannelParams pChnlParams)
+{
+	struct scheduler_msg mmhMsg = {0};
+	tpSwitchChannelParams pSmeSwithChnlParams;
+	uint8_t channelId;
+	bool is_ch_dfs = false;
+	enum phy_ch_width ch_width;
+	uint8_t ch_center_freq_seg1;
+
+	pSmeSwithChnlParams = qdf_mem_malloc(sizeof(tSwitchChannelParams));
+	if (!pSmeSwithChnlParams)
+		return;
+
+	qdf_mem_copy(pSmeSwithChnlParams, pChnlParams,
+		     sizeof(tSwitchChannelParams));
+
+	channelId = pSmeSwithChnlParams->channelNumber;
+	ch_width = pSmeSwithChnlParams->ch_width;
+	ch_center_freq_seg1 = pSmeSwithChnlParams->ch_center_freq_seg1;
+
+	/*
+	 * Pass the sme sessionID to SME instead
+	 * PE session ID.
+	 */
+	pSmeSwithChnlParams->peSessionId = psessionEntry->smeSessionId;
+
+	mmhMsg.type = eWNI_SME_CHANNEL_CHANGE_RSP;
+	mmhMsg.bodyptr = (void *)pSmeSwithChnlParams;
+	mmhMsg.bodyval = 0;
+	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+	/*
+	 * We should start beacon transmission only if the new
+	 * channel after channel change is Non-DFS. For a DFS
+	 * channel, PE will receive an explicit request from
+	 * upper layers to start the beacon transmission .
+	 */
+
+	if (ch_width == CH_WIDTH_160MHZ) {
+		is_ch_dfs = true;
+	} else if (ch_width == CH_WIDTH_80P80MHZ) {
+		if (wlan_reg_get_channel_state(pMac->pdev, channelId) ==
+				CHANNEL_STATE_DFS ||
+		    wlan_reg_get_channel_state(pMac->pdev,
+			    ch_center_freq_seg1 -
+			    SIR_80MHZ_START_CENTER_CH_DIFF) ==
+							CHANNEL_STATE_DFS)
+			is_ch_dfs = true;
+	} else {
+		if (wlan_reg_get_channel_state(pMac->pdev, channelId) ==
+				CHANNEL_STATE_DFS)
+			is_ch_dfs = true;
+	}
+
+	if (!is_ch_dfs) {
+		if (channelId == psessionEntry->currentOperChannel) {
+			lim_apply_configuration(pMac, psessionEntry);
+			lim_send_beacon(pMac, psessionEntry);
+		} else {
+			pe_debug("Failed to Transmit Beacons on channel: %d after AP channel change response",
+				       psessionEntry->bcnLen);
+		}
+
+		lim_obss_send_detection_cfg(pMac, psessionEntry, true);
+	}
+	return;
+}
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+/**
+ *  lim_send_bss_color_change_ie_update() - update bss color change IE in
+ *   beacon template
+ *
+ *  @mac_ctx: pointer to global adapter context
+ *  @session: session pointer
+ *
+ *  Return: none
+ */
+static void
+lim_send_bss_color_change_ie_update(tpAniSirGlobal mac_ctx,
+						tpPESession session)
+{
+	/* Update the beacon template and send to FW */
+	if (sch_set_fixed_beacon_fields(mac_ctx, session) != QDF_STATUS_SUCCESS) {
+		pe_err("Unable to set BSS color change IE in beacon");
+		return;
+	}
+
+	/* Send update beacon template message */
+	lim_send_beacon_ind(mac_ctx, session, REASON_COLOR_CHANGE);
+	pe_debug("Updated BSS color change countdown = %d",
+		 session->he_bss_color_change.countdown);
+}
+
+static void
+lim_handle_bss_color_change_ie(tpAniSirGlobal mac_ctx,
+					tpPESession session)
+{
+	tUpdateBeaconParams beacon_params;
+
+	/* handle bss color change IE */
+	if (LIM_IS_AP_ROLE(session) &&
+			session->he_op.bss_col_disabled) {
+		if (session->he_bss_color_change.countdown > 0) {
+			session->he_bss_color_change.countdown--;
+		} else {
+			session->bss_color_changing = 0;
+			qdf_mem_zero(&beacon_params, sizeof(beacon_params));
+			if (session->he_bss_color_change.new_color != 0) {
+				session->he_op.bss_col_disabled = 0;
+				session->he_op.bss_color =
+					session->he_bss_color_change.new_color;
+				beacon_params.paramChangeBitmap |=
+					PARAM_BSS_COLOR_CHANGED;
+				beacon_params.bss_color_disabled = 0;
+				beacon_params.bss_color =
+					session->he_op.bss_color;
+				lim_send_beacon_params(mac_ctx,
+						       &beacon_params,
+						       session);
+				lim_send_obss_color_collision_cfg(mac_ctx,
+						session,
+						OBSS_COLOR_COLLISION_DETECTION);
+			}
+		}
+
+		lim_send_bss_color_change_ie_update(mac_ctx, session);
+	}
+}
+
+#else
+static void
+lim_handle_bss_color_change_ie(tpAniSirGlobal mac_ctx,
+					tpPESession session)
+{
+}
+#endif
+
+void
+lim_process_beacon_tx_success_ind(tpAniSirGlobal mac_ctx, uint16_t msgType,
+				  void *event)
+{
+	tpPESession session;
+	tpSirFirstBeaconTxCompleteInd bcn_ind =
+		(tSirFirstBeaconTxCompleteInd *) event;
+
+	session = pe_find_session_by_bss_idx(mac_ctx, bcn_ind->bssIdx);
+	if (!session) {
+		pe_err("Session Does not exist for given session id");
+		return;
+	}
+
+	pe_debug("role: %d swIe: %d opIe: %d switch cnt:%d",
+		 GET_LIM_SYSTEM_ROLE(session),
+		 session->dfsIncludeChanSwIe,
+		 session->gLimOperatingMode.present,
+		 session->gLimChannelSwitch.switchCount);
+
+	if (!LIM_IS_AP_ROLE(session))
+		return;
+
+	if (session->dfsIncludeChanSwIe &&
+	    (session->gLimChannelSwitch.switchCount ==
+	    mac_ctx->sap.SapDfsInfo.sap_ch_switch_beacon_cnt))
+		lim_process_ap_ecsa_timeout(session);
+
+
+	if (session->gLimOperatingMode.present)
+		/* Done with nss update */
+		session->gLimOperatingMode.present = 0;
+
+	lim_handle_bss_color_change_ie(mac_ctx, session);
+
+	return;
+}
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h
new file mode 100644
index 0000000..6ff6e2e
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file lim_send_sme_rsp_messages.h contains the definitions for
+ * sending SME response/notification messages to applications above
+ * MAC software.
+ * Author:        Chandra Modumudi
+ * Date:          02/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_SEND_SME_RSP_H
+#define __LIM_SEND_SME_RSP_H
+
+#include "sir_common.h"
+#include "sir_api.h"
+#include "sir_mac_prot_def.h"
+
+/* Functions for sending responses to Host */
+void lim_send_sme_rsp(tpAniSirGlobal, uint16_t, tSirResultCodes, uint8_t,
+		      uint16_t);
+void lim_send_sme_roc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+	 tSirResultCodes result_code, uint8_t sme_session_id,
+	 uint32_t scan_id);
+void lim_send_sme_start_bss_rsp(tpAniSirGlobal, uint16_t, tSirResultCodes,
+				tpPESession, uint8_t, uint16_t);
+void lim_send_sme_join_reassoc_rsp(tpAniSirGlobal, uint16_t, tSirResultCodes,
+				   uint16_t, tpPESession, uint8_t, uint16_t);
+
+/*
+ * lim_prepare_disconnect_done_ind() - Prepares the disconnect done ind message
+ * @mac_ctx: Global mac_ctx
+ * @session_id: PE session id
+ * @reason_code: Disconnect indication reason code
+ * @peer_mac_addr: MAC address of the peer
+ *
+ * Prepares the disconnect done indication message to be sent to the upper layer
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS lim_prepare_disconnect_done_ind(tpAniSirGlobal mac_ctx,
+					   uint32_t **msg,
+					   uint8_t session_id,
+					   tSirResultCodes reason_code,
+					   uint8_t *peer_mac_addr);
+void lim_send_sme_disassoc_ntf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes,
+			       uint16_t, uint16_t, uint8_t, uint16_t, tpPESession);
+void lim_send_sme_deauth_ntf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, uint16_t,
+			     uint16_t, uint8_t, uint16_t);
+void lim_send_sme_disassoc_ind(tpAniSirGlobal, tpDphHashNode, tpPESession);
+void lim_send_sme_deauth_ind(tpAniSirGlobal, tpDphHashNode,
+			     tpPESession psessionEntry);
+void lim_send_sme_wm_status_change_ntf(tpAniSirGlobal, tSirSmeStatusChangeCode,
+				       uint32_t *, uint16_t, uint8_t);
+void lim_send_sme_set_context_rsp(tpAniSirGlobal, struct qdf_mac_addr, uint16_t,
+				  tSirResultCodes, tpPESession, uint8_t, uint16_t);
+void lim_handle_delete_bss_rsp(tpAniSirGlobal pMac, struct scheduler_msg *MsgQ);
+void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx,
+				struct scheduler_msg *msg);
+
+void
+lim_send_sme_aggr_qos_rsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp,
+			  uint8_t smesessionId);
+
+void lim_send_sme_addts_rsp(tpAniSirGlobal pMac, uint8_t rspReqd, uint32_t status,
+			    tpPESession psessionEntry, tSirMacTspecIE tspec,
+			    uint8_t smesessionId, uint16_t smetransactionId);
+void lim_send_sme_delts_rsp(tpAniSirGlobal pMac, tpSirDeltsReq delts,
+			    uint32_t status, tpPESession psessionEntry,
+			    uint8_t smessionId, uint16_t smetransactionId);
+void lim_send_sme_delts_ind(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts,
+			    uint16_t aid, tpPESession);
+void lim_send_sme_stats_rsp(tpAniSirGlobal pMac, uint16_t msgtype, void *stats);
+
+#ifdef QCA_SUPPORT_CP_STATS
+static inline void lim_send_sme_pe_statistics_rsp(tpAniSirGlobal pMac,
+					uint16_t msgtype, void *stats) {}
+#else
+void lim_send_sme_pe_statistics_rsp(tpAniSirGlobal pMac, uint16_t msgtype,
+				    void *stats);
+#endif /* QCA_SUPPORT_CP_STATS */
+
+#ifdef FEATURE_WLAN_ESE
+void lim_send_sme_pe_ese_tsm_rsp(tpAniSirGlobal pMac, tAniGetTsmStatsRsp *pStats);
+#endif
+
+void lim_send_sme_ibss_peer_ind(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+				uint16_t staIndex, uint8_t *beacon,
+				uint16_t beaconLen, uint16_t msgType,
+				uint8_t sessionId);
+void lim_send_sme_max_assoc_exceeded_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+					 uint8_t smesessionId);
+
+void lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac,
+					 tpPESession psessionEntry,
+					 tpSwitchChannelParams pChnlParams);
+/*
+ * lim_process_beacon_tx_success_ind() - handle successful beacon transmission
+ * indication from the FW This is a generic event generated by the FW afer the
+ * first beacon is sent out after the beacon template update by the host.
+ *
+ * @mac_ctx: Global mac_ctx
+ * @msg_type: msg_type
+ */
+void
+lim_process_beacon_tx_success_ind(tpAniSirGlobal pMac, uint16_t msgType,
+				  void *event);
+
+typedef enum {
+	lim_csa_ie_present = 0x00000001,
+	lim_xcsa_ie_present = 0x00000002,
+	lim_wbw_ie_present = 0x00000004,
+	lim_cswarp_ie_present = 0x00000008,
+} lim_csa_event_ies_present_flag;
+
+#endif /* __LIM_SEND_SME_RSP_H */
diff --git a/core/mac/src/pe/lim/lim_ser_des_utils.c b/core/mac/src/pe/lim/lim_ser_des_utils.c
new file mode 100644
index 0000000..a76d386
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ser_des_utils.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_ser_des_utils.cc contains the serializer/deserializer
+ * utility functions LIM uses while communicating with upper layer
+ * software entities
+ * Author:        Chandra Modumudi
+ * Date:          10/20/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "ani_system_defs.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_ser_des_utils.h"
+
+
+/**---------------------------------------------------------------
+   \fn     lim_get_session_info
+   \brief  This function returns the sessionId and transactionId
+ \       of a message. This assumes that the message structure
+ \       is of format:
+ \          uint16_t   messageType
+ \          uint16_t   messageLength
+ \          uint8_t    sessionId
+ \          uint16_t   transactionId
+   \param  pMac          - pMac global structure
+   \param  *pBuf         - pointer to the message buffer
+   \param  sessionId     - returned session id value
+   \param  transactionId - returned transaction ID value
+   \return None
+   ------------------------------------------------------------------*/
+void
+lim_get_session_info(tpAniSirGlobal pMac, uint8_t *pBuf, uint8_t *sessionId,
+		     uint16_t *transactionId)
+{
+	if (!pBuf) {
+		pe_err("NULL ptr received");
+		return;
+	}
+
+	pBuf += sizeof(uint16_t);       /* skip message type */
+	pBuf += sizeof(uint16_t);       /* skip message length */
+
+	*sessionId = *pBuf;     /* get sessionId */
+	pBuf++;
+	*transactionId = lim_get_u16(pBuf);       /* get transactionId */
+
+	return;
+}
+
+/**
+ * lim_send_disassoc_frm_req_ser_des - called on receiving SME_DISASSOC_REQ
+ * @mac_ctx: pointer to mac context
+ * @disassoc_frm_req: pointer to structure sme_send_disassoc_frm_req
+ *
+ * function send's disassoc frame request on receiving SME_DISASSOC_REQ
+ *
+ * return: QDF_STATUS_SUCCESS:Success Error value: Failure
+ */
+QDF_STATUS lim_send_disassoc_frm_req_ser_des(tpAniSirGlobal mac_ctx,
+			struct sme_send_disassoc_frm_req *disassoc_frm_req,
+			uint8_t *buf)
+{
+	A_INT16 len = 0;
+
+	if (!disassoc_frm_req || !buf)
+		return QDF_STATUS_E_FAILURE;
+
+	disassoc_frm_req->msg_type = lim_get_u16(buf);
+	buf += sizeof(A_UINT16);
+
+	len = disassoc_frm_req->length = lim_get_u16(buf);
+	buf += sizeof(A_UINT16);
+
+	if (len < (A_INT16) sizeof(A_UINT32))
+		return QDF_STATUS_E_FAILURE;
+
+	/* skip message header */
+	len -= sizeof(A_UINT32);
+	if (len < 0)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Extract sessionID */
+	disassoc_frm_req->session_id = *buf;
+	buf += sizeof(A_UINT8);
+	len -= sizeof(A_UINT8);
+	if (len < 0)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Extract transactionid */
+	disassoc_frm_req->trans_id = lim_get_u16(buf);
+	buf += sizeof(A_UINT16);
+	len -= sizeof(A_UINT16);
+
+	if (len < 0)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Extract peerMacAddr */
+	qdf_mem_copy(disassoc_frm_req->peer_mac, buf, sizeof(tSirMacAddr));
+	buf += sizeof(tSirMacAddr);
+	len  -= sizeof(tSirMacAddr);
+
+	if (len < 0)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Extract reasonCode */
+	disassoc_frm_req->reason = lim_get_u16(buf);
+	buf += sizeof(A_UINT16);
+	len  -= sizeof(A_UINT16);
+
+	if (len < 0)
+		return QDF_STATUS_E_FAILURE;
+
+	disassoc_frm_req->wait_for_ack = *buf;
+	buf += sizeof(A_UINT8);
+	len -= sizeof(A_UINT8);
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/core/mac/src/pe/lim/lim_ser_des_utils.h b/core/mac/src/pe/lim/lim_ser_des_utils.h
new file mode 100644
index 0000000..eb5c036
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ser_des_utils.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_ser_des_utils.h contains the utility definitions
+ * LIM uses while processing messages from upper layer software
+ * modules
+ * Author:        Chandra Modumudi
+ * Date:          10/20/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SERDES_UTILS_H
+#define __LIM_SERDES_UTILS_H
+
+#include "sir_api.h"
+#include "ani_system_defs.h"
+#include "sir_mac_prot_def.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_prop_exts_utils.h"
+
+void lim_get_session_info(tpAniSirGlobal pMac, uint8_t *,
+			  uint8_t *, uint16_t *);
+
+/* Byte String <--> uint16_t/uint32_t copy functions */
+static inline void lim_copy_u16(uint8_t *ptr, uint16_t u16Val)
+{
+#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) ||	\
+	(defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+	*ptr++ = (uint8_t) (u16Val & 0xff);
+	*ptr = (uint8_t) ((u16Val >> 8) & 0xff);
+#else
+#error "Unknown combination of OS Type and endianness"
+#endif
+}
+
+static inline uint16_t lim_get_u16(uint8_t *ptr)
+{
+#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) ||	\
+	(defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+	return ((uint16_t) (*(ptr + 1) << 8)) | ((uint16_t) (*ptr));
+#else
+#error "Unknown combination of OS Type and endianness"
+#endif
+}
+
+static inline void lim_copy_u32(uint8_t *ptr, uint32_t u32Val)
+{
+#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) ||	\
+	(defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+	*ptr++ = (uint8_t) (u32Val & 0xff);
+	*ptr++ = (uint8_t) ((u32Val >> 8) & 0xff);
+	*ptr++ = (uint8_t) ((u32Val >> 16) & 0xff);
+	*ptr = (uint8_t) ((u32Val >> 24) & 0xff);
+#else
+#error "Unknown combination of OS Type and endianness"
+#endif
+}
+
+static inline uint32_t lim_get_u32(uint8_t *ptr)
+{
+#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) ||	\
+	(defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+	return ((*(ptr + 3) << 24) |
+		(*(ptr + 2) << 16) | (*(ptr + 1) << 8) | (*(ptr)));
+#else
+#error "Unknown combination of OS Type and endianness"
+#endif
+}
+
+/**
+ * lim_copy_u16_be()- This API copies a u16 value in buffer
+ * to network byte order
+ * @ptr: pointer to buffer
+ * @u16_val: value needs to be copied
+ *
+ * Return: None
+ */
+static inline void lim_copy_u16_be(uint8_t *ptr, uint16_t u16_val)
+{
+	ptr[0] = u16_val >> 8;
+	ptr[1] = u16_val & 0xff;
+}
+
+/**
+ * lim_copy_u16_be()- This API reads u16 value from network byte order buffer
+ * @ptr: pointer to buffer
+ *
+ * Return: 16bit value
+ */
+static inline uint16_t lim_get_u16_be(uint8_t *buf)
+{
+	return (buf[0] << 8) | buf[1];
+}
+
+QDF_STATUS lim_send_disassoc_frm_req_ser_des(tpAniSirGlobal mac_ctx,
+		struct sme_send_disassoc_frm_req *disassoc_frm_req,
+		uint8_t *buf);
+
+#endif /* __LIM_SERDES_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c
new file mode 100644
index 0000000..10e1c69
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_session.c
@@ -0,0 +1,1166 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**=========================================================================
+
+   \file  lim_session.c
+
+   \brief implementation for lim Session related APIs
+
+   \author Sunit Bhatia
+
+   ========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include "ani_global.h"
+#include "lim_ft_defs.h"
+#include "lim_ft.h"
+#include "lim_session.h"
+#include "lim_utils.h"
+
+#include "sch_api.h"
+#include "lim_send_messages.h"
+#include "cfg_ucfg_api.h"
+
+#ifdef WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY
+static struct sDphHashNode *g_dph_node_array;
+
+QDF_STATUS pe_allocate_dph_node_array_buffer(void)
+{
+	uint32_t buf_size;
+
+	buf_size = SIR_MAX_SUPPORTED_BSS * (SIR_SAP_MAX_NUM_PEERS + 1)
+		   * sizeof(struct sDphHashNode);
+	g_dph_node_array = qdf_mem_malloc(buf_size);
+	if (!g_dph_node_array)
+		return QDF_STATUS_E_NOMEM;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void pe_free_dph_node_array_buffer(void)
+{
+	qdf_mem_free(g_dph_node_array);
+	g_dph_node_array = NULL;
+}
+
+static inline
+struct sDphHashNode *pe_get_session_dph_node_array(uint8_t session_id)
+{
+	return &g_dph_node_array[session_id * (SIR_SAP_MAX_NUM_PEERS + 1)];
+}
+
+#else /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
+static struct sDphHashNode
+	g_dph_node_array[SIR_MAX_SUPPORTED_BSS][SIR_SAP_MAX_NUM_PEERS + 1];
+
+static inline
+struct sDphHashNode *pe_get_session_dph_node_array(uint8_t session_id)
+{
+	return g_dph_node_array[session_id];
+}
+#endif /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
+
+/*--------------------------------------------------------------------------
+
+   \brief pe_init_beacon_params() - Initialize the beaconParams structure
+
+   \param tpPESession          - pointer to the session context or NULL if session can not be created.
+   \return void
+   \sa
+
+   --------------------------------------------------------------------------*/
+
+static void pe_init_beacon_params(tpAniSirGlobal pMac,
+				  tpPESession psessionEntry)
+{
+	psessionEntry->beaconParams.beaconInterval = 0;
+	psessionEntry->beaconParams.fShortPreamble = 0;
+	psessionEntry->beaconParams.llaCoexist = 0;
+	psessionEntry->beaconParams.llbCoexist = 0;
+	psessionEntry->beaconParams.llgCoexist = 0;
+	psessionEntry->beaconParams.ht20Coexist = 0;
+	psessionEntry->beaconParams.llnNonGFCoexist = 0;
+	psessionEntry->beaconParams.fRIFSMode = 0;
+	psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = 0;
+	psessionEntry->beaconParams.gHTObssMode = 0;
+
+	/* Number of legacy STAs associated */
+	qdf_mem_set((void *)&psessionEntry->gLim11bParams,
+		    sizeof(tLimProtStaParams), 0);
+	qdf_mem_set((void *)&psessionEntry->gLim11aParams,
+		    sizeof(tLimProtStaParams), 0);
+	qdf_mem_set((void *)&psessionEntry->gLim11gParams,
+		    sizeof(tLimProtStaParams), 0);
+	qdf_mem_set((void *)&psessionEntry->gLimNonGfParams,
+		    sizeof(tLimProtStaParams), 0);
+	qdf_mem_set((void *)&psessionEntry->gLimHt20Params,
+		    sizeof(tLimProtStaParams), 0);
+	qdf_mem_set((void *)&psessionEntry->gLimLsigTxopParams,
+		    sizeof(tLimProtStaParams), 0);
+	qdf_mem_set((void *)&psessionEntry->gLimOlbcParams,
+		    sizeof(tLimProtStaParams), 0);
+}
+
+/*
+ * pe_reset_protection_callback() - resets protection structs so that when an AP
+ * causing use of protection goes away, corresponding protection bit can be
+ * reset
+ * @ptr:        pointer to pSessionEntry
+ *
+ * This function resets protection structs so that when an AP causing use of
+ * protection goes away, corresponding protection bit can be reset. This allowes
+ * protection bits to be reset once legacy overlapping APs are gone.
+ *
+ * Return: void
+ */
+static void pe_reset_protection_callback(void *ptr)
+{
+	tpPESession pe_session_entry = (tpPESession)ptr;
+	tpAniSirGlobal mac_ctx = pe_session_entry->mac_ctx;
+	int8_t i = 0;
+	tUpdateBeaconParams beacon_params;
+	uint16_t current_protection_state = 0;
+	tpDphHashNode station_hash_node = NULL;
+	tSirMacHTOperatingMode old_op_mode;
+	bool bcn_prms_changed = false;
+
+	if (pe_session_entry->valid == false) {
+		pe_err("session already deleted. exiting timer callback");
+		return;
+	}
+
+	/*
+	 * During CAC period, if the callback is triggered, the beacon
+	 * template may get updated. Subsequently if the vdev is not up, the
+	 * vdev would be made up -- which should not happen during the CAC
+	 * period. To avoid this, ignore the protection callback if the session
+	 * is not yet up.
+	 */
+	if (!wma_is_vdev_up(pe_session_entry->smeSessionId)) {
+		pe_err("session is not up yet. exiting timer callback");
+		return;
+	}
+
+	/*
+	 * If dfsIncludeChanSwIe is set restrat timer as we are going to change
+	 * channel and no point in checking protection mode for this channel.
+	 */
+	if (pe_session_entry->dfsIncludeChanSwIe) {
+		pe_err("CSA going on restart timer");
+		goto restart_timer;
+	}
+	current_protection_state |=
+	       pe_session_entry->gLimOverlap11gParams.protectionEnabled        |
+	       pe_session_entry->gLimOverlap11aParams.protectionEnabled   << 1 |
+	       pe_session_entry->gLimOverlapHt20Params.protectionEnabled  << 2 |
+	       pe_session_entry->gLimOverlapNonGfParams.protectionEnabled << 3 |
+	       pe_session_entry->gLimOlbcParams.protectionEnabled         << 4;
+
+	pe_debug("old protection state: 0x%04X, new protection state: 0x%04X",
+		  pe_session_entry->old_protection_state,
+		  current_protection_state);
+
+	qdf_mem_zero(&pe_session_entry->gLimOverlap11gParams,
+		     sizeof(pe_session_entry->gLimOverlap11gParams));
+	qdf_mem_zero(&pe_session_entry->gLimOverlap11aParams,
+		     sizeof(pe_session_entry->gLimOverlap11aParams));
+	qdf_mem_zero(&pe_session_entry->gLimOverlapHt20Params,
+		     sizeof(pe_session_entry->gLimOverlapHt20Params));
+	qdf_mem_zero(&pe_session_entry->gLimOverlapNonGfParams,
+		     sizeof(pe_session_entry->gLimOverlapNonGfParams));
+
+	qdf_mem_zero(&pe_session_entry->gLimOlbcParams,
+		     sizeof(pe_session_entry->gLimOlbcParams));
+
+	/*
+	 * Do not reset fShortPreamble and beaconInterval, as they
+	 * are not updated.
+	 */
+	pe_session_entry->beaconParams.llaCoexist = 0;
+	pe_session_entry->beaconParams.llbCoexist = 0;
+	pe_session_entry->beaconParams.llgCoexist = 0;
+	pe_session_entry->beaconParams.ht20Coexist = 0;
+	pe_session_entry->beaconParams.llnNonGFCoexist = 0;
+	pe_session_entry->beaconParams.fRIFSMode = 0;
+	pe_session_entry->beaconParams.fLsigTXOPProtectionFullSupport = 0;
+	pe_session_entry->beaconParams.gHTObssMode = 0;
+
+
+	old_op_mode = pe_session_entry->htOperMode;
+	pe_session_entry->htOperMode = eSIR_HT_OP_MODE_PURE;
+	mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+
+	qdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
+	/* index 0, is self node, peers start from 1 */
+	for (i = 1 ; i <= mac_ctx->mlme_cfg->sap_cfg.assoc_sta_limit ; i++) {
+		station_hash_node = dph_get_hash_entry(mac_ctx, i,
+					&pe_session_entry->dph.dphHashTable);
+		if (NULL == station_hash_node)
+			continue;
+		lim_decide_ap_protection(mac_ctx, station_hash_node->staAddr,
+		&beacon_params, pe_session_entry);
+	}
+
+	if (pe_session_entry->htOperMode != old_op_mode)
+		bcn_prms_changed = true;
+
+	if ((current_protection_state !=
+		pe_session_entry->old_protection_state) &&
+		(false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
+		pe_debug("protection changed, update beacon template");
+		/* update beacon fix params and send update to FW */
+		qdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
+		beacon_params.bssIdx = pe_session_entry->bssIdx;
+		beacon_params.fShortPreamble =
+				pe_session_entry->beaconParams.fShortPreamble;
+		beacon_params.beaconInterval =
+				pe_session_entry->beaconParams.beaconInterval;
+		beacon_params.llaCoexist =
+				pe_session_entry->beaconParams.llaCoexist;
+		beacon_params.llbCoexist =
+				pe_session_entry->beaconParams.llbCoexist;
+		beacon_params.llgCoexist =
+				pe_session_entry->beaconParams.llgCoexist;
+		beacon_params.ht20MhzCoexist =
+				pe_session_entry->beaconParams.ht20Coexist;
+		beacon_params.llnNonGFCoexist =
+				pe_session_entry->beaconParams.llnNonGFCoexist;
+		beacon_params.fLsigTXOPProtectionFullSupport =
+				pe_session_entry->beaconParams.
+					fLsigTXOPProtectionFullSupport;
+		beacon_params.fRIFSMode =
+				pe_session_entry->beaconParams.fRIFSMode;
+		beacon_params.smeSessionId =
+				pe_session_entry->smeSessionId;
+		beacon_params.paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
+		bcn_prms_changed = true;
+	}
+
+	if (bcn_prms_changed) {
+		sch_set_fixed_beacon_fields(mac_ctx, pe_session_entry);
+		lim_send_beacon_params(mac_ctx, &beacon_params, pe_session_entry);
+	}
+
+	pe_session_entry->old_protection_state = current_protection_state;
+restart_timer:
+	if (qdf_mc_timer_start(&pe_session_entry->
+				protection_fields_reset_timer,
+				SCH_PROTECTION_RESET_TIME)
+		!= QDF_STATUS_SUCCESS) {
+		pe_err("cannot create or start protectionFieldsResetTimer");
+	}
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * pe_init_pmf_comeback_timer: init PMF comeback timer
+ * @mac_ctx: pointer to global adapter context
+ * @session: pe session
+ * @session_id: session ID
+ *
+ * Return: void
+ */
+static void pe_init_pmf_comeback_timer(tpAniSirGlobal mac_ctx,
+tpPESession session, uint8_t session_id)
+{
+	QDF_STATUS status;
+
+	session->pmfComebackTimerInfo.pMac = mac_ctx;
+	session->pmfComebackTimerInfo.sessionID = session_id;
+	status = qdf_mc_timer_init(&session->pmfComebackTimer,
+			QDF_TIMER_TYPE_SW, lim_pmf_comeback_timer_callback,
+			(void *)&session->pmfComebackTimerInfo);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		pe_err("cannot init pmf comeback timer");
+}
+#else
+static inline void
+pe_init_pmf_comeback_timer(tpAniSirGlobal mac_ctx,
+	tpPESession session, uint8_t session_id)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * pe_delete_fils_info: API to delete fils session info
+ * @session: pe session
+ *
+ * Return: void
+ */
+void pe_delete_fils_info(tpPESession session)
+{
+	struct pe_fils_session *fils_info;
+
+	if (!session || (session && !session->valid)) {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			  FL("session is not valid"));
+		return;
+	}
+	fils_info = session->fils_info;
+	if (!fils_info) {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			  FL("fils info not found"));
+		return;
+	}
+	if (fils_info->keyname_nai_data)
+		qdf_mem_free(fils_info->keyname_nai_data);
+	if (fils_info->fils_erp_reauth_pkt)
+		qdf_mem_free(fils_info->fils_erp_reauth_pkt);
+	if (fils_info->fils_rrk)
+		qdf_mem_free(fils_info->fils_rrk);
+	if (fils_info->fils_rik)
+		qdf_mem_free(fils_info->fils_rik);
+	if (fils_info->fils_eap_finish_pkt)
+		qdf_mem_free(fils_info->fils_eap_finish_pkt);
+	if (fils_info->fils_rmsk)
+		qdf_mem_free(fils_info->fils_rmsk);
+	if (fils_info->fils_pmk)
+		qdf_mem_free(fils_info->fils_pmk);
+	if (fils_info->auth_info.keyname)
+		qdf_mem_free(fils_info->auth_info.keyname);
+	if (fils_info->auth_info.domain_name)
+		qdf_mem_free(fils_info->auth_info.domain_name);
+	if (fils_info->hlp_data)
+		qdf_mem_free(fils_info->hlp_data);
+	qdf_mem_free(fils_info);
+	session->fils_info = NULL;
+}
+/**
+ * pe_init_fils_info: API to initialize fils session info elements to null
+ * @session: pe session
+ *
+ * Return: void
+ */
+static void pe_init_fils_info(tpPESession session)
+{
+	struct pe_fils_session *fils_info;
+
+	if (!session || (session && !session->valid)) {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+			  FL("session is not valid"));
+		return;
+	}
+	session->fils_info = qdf_mem_malloc(sizeof(struct pe_fils_session));
+	fils_info = session->fils_info;
+	if (!fils_info)
+		return;
+	fils_info->keyname_nai_data = NULL;
+	fils_info->fils_erp_reauth_pkt = NULL;
+	fils_info->fils_rrk = NULL;
+	fils_info->fils_rik = NULL;
+	fils_info->fils_eap_finish_pkt = NULL;
+	fils_info->fils_rmsk = NULL;
+	fils_info->fils_pmk = NULL;
+	fils_info->auth_info.keyname = NULL;
+	fils_info->auth_info.domain_name = NULL;
+}
+#else
+static void pe_delete_fils_info(tpPESession session) { }
+static void pe_init_fils_info(tpPESession session) { }
+#endif
+
+/**
+ * lim_get_peer_idxpool_size: get number of peer idx pool size
+ * @num_sta: Max number of STA
+ * @bss_type: BSS type
+ *
+ * The peer index start from 1 and thus index 0 is not used, so
+ * add 1 to the max sta. For STA if TDLS is enabled add 2 as
+ * index 1 is reserved for peer BSS.
+ *
+ * Return: number of peer idx pool size
+ */
+#ifdef FEATURE_WLAN_TDLS
+static inline uint8_t
+lim_get_peer_idxpool_size(uint16_t num_sta, tSirBssType bss_type)
+{
+	/*
+	 * In station role, index 1 is reserved for peer
+	 * corresponding to AP. For TDLS the index should
+	 * start from 2
+	 */
+	if (bss_type == eSIR_INFRASTRUCTURE_MODE)
+		return num_sta + 2;
+	else
+		return num_sta + 1;
+
+}
+#else
+static inline uint8_t
+lim_get_peer_idxpool_size(uint16_t num_sta, tSirBssType bss_type)
+{
+	return num_sta + 1;
+}
+#endif
+
+void lim_set_bcn_probe_filter(tpAniSirGlobal mac_ctx,
+				tpPESession session,
+				tSirMacSSid *ibss_ssid,
+				uint8_t sap_channel)
+{
+	struct mgmt_beacon_probe_filter *filter;
+	tSirBssType bss_type;
+	uint8_t session_id;
+	tSirMacAddr *bssid;
+
+	if (!session) {
+		pe_err("Invalid session pointer");
+		return;
+	}
+
+	bss_type = session->bssType;
+	session_id = session->peSessionId;
+	bssid = &session->bssId;
+
+	if (session_id >= SIR_MAX_SUPPORTED_BSS) {
+		pe_err("Invalid session_id %d of type %d",
+			session_id, bss_type);
+		return;
+	}
+
+	filter = &mac_ctx->bcn_filter;
+
+	if (eSIR_INFRASTRUCTURE_MODE == bss_type) {
+		filter->num_sta_sessions++;
+		sir_copy_mac_addr(filter->sta_bssid[session_id], *bssid);
+		pe_debug("Set filter for STA Session %d bssid "MAC_ADDRESS_STR,
+			session_id, MAC_ADDR_ARRAY(*bssid));
+	} else if (eSIR_IBSS_MODE == bss_type) {
+		if (!ibss_ssid) {
+			pe_err("IBSS Type with NULL SSID");
+			goto done;
+		}
+		filter->num_ibss_sessions++;
+		filter->ibss_ssid[session_id].length = ibss_ssid->length;
+		qdf_mem_copy(&filter->ibss_ssid[session_id].length,
+			     ibss_ssid->ssId,
+			     ibss_ssid->length);
+		pe_debug("Set filter for IBSS session %d ssid %s",
+			session_id, ibss_ssid->ssId);
+	} else if (eSIR_INFRA_AP_MODE == bss_type) {
+		if (!sap_channel) {
+			pe_err("SAP Type with invalid channel");
+			goto done;
+		}
+		filter->num_sap_sessions++;
+		filter->sap_channel[session_id] = sap_channel;
+		pe_debug("Set filter for SAP session %d channel %d",
+			session_id, sap_channel);
+	}
+
+done:
+	pe_debug("sta %d ibss %d sap %d",
+		filter->num_sta_sessions, filter->num_ibss_sessions,
+		filter->num_sap_sessions);
+}
+
+void lim_reset_bcn_probe_filter(tpAniSirGlobal mac_ctx,
+				tpPESession session)
+{
+	struct mgmt_beacon_probe_filter *filter;
+	tSirBssType bss_type;
+	uint8_t session_id;
+
+	if (!session) {
+		pe_err("Invalid session pointer");
+		return;
+	}
+
+	bss_type = session->bssType;
+	session_id = session->peSessionId;
+
+	if (session_id >= SIR_MAX_SUPPORTED_BSS) {
+		pe_err("Invalid session_id %d of type %d",
+			session_id, bss_type);
+		return;
+	}
+
+	filter = &mac_ctx->bcn_filter;
+
+	if (eSIR_INFRASTRUCTURE_MODE == bss_type) {
+		if (filter->num_sta_sessions)
+			filter->num_sta_sessions--;
+		qdf_mem_set(&filter->sta_bssid[session_id],
+			    sizeof(tSirMacAddr), 0);
+		pe_debug("Cleared STA Filter for session %d", session_id);
+	} else if (eSIR_IBSS_MODE == bss_type) {
+		if (filter->num_ibss_sessions)
+			filter->num_ibss_sessions--;
+		filter->ibss_ssid[session_id].length = 0;
+		qdf_mem_set(&filter->ibss_ssid[session_id].ssId,
+			    SIR_MAC_MAX_SSID_LENGTH, 0);
+		pe_debug("Cleared IBSS Filter for session %d", session_id);
+	} else if (eSIR_INFRA_AP_MODE == bss_type) {
+		if (filter->num_sap_sessions)
+			filter->num_sap_sessions--;
+		filter->sap_channel[session_id] = 0;
+		pe_debug("Cleared SAP Filter for session %d", session_id);
+	}
+
+	pe_debug("sta %d ibss %d sap %d",
+		filter->num_sta_sessions, filter->num_ibss_sessions,
+		filter->num_sap_sessions);
+}
+
+void lim_update_bcn_probe_filter(tpAniSirGlobal mac_ctx,
+					tpPESession session)
+{
+	struct mgmt_beacon_probe_filter *filter;
+	tSirBssType bss_type;
+	uint8_t session_id;
+
+	if (!session) {
+		pe_err("Invalid session pointer");
+		return;
+	}
+
+	bss_type = session->bssType;
+	session_id = session->peSessionId;
+
+	if (session_id >= SIR_MAX_SUPPORTED_BSS) {
+		pe_err("Invalid session_id %d of type %d",
+			session_id, bss_type);
+		return;
+	}
+
+	filter = &mac_ctx->bcn_filter;
+
+	if (eSIR_INFRA_AP_MODE == bss_type) {
+		filter->sap_channel[session_id] = session->currentOperChannel;
+		pe_debug("Updated SAP Filter for session %d channel %d",
+			session_id, filter->sap_channel[session_id]);
+	} else {
+		pe_debug("Invalid session type %d session id %d",
+			bss_type, session_id);
+	}
+
+	pe_debug("sta %d ibss %d sap %d",
+		filter->num_sta_sessions, filter->num_ibss_sessions,
+		filter->num_sap_sessions);
+}
+
+tpPESession pe_create_session(tpAniSirGlobal pMac,
+			      uint8_t *bssid,
+			      uint8_t *sessionId,
+			      uint16_t numSta, tSirBssType bssType,
+			      uint8_t sme_session_id)
+{
+	QDF_STATUS status;
+	uint8_t i;
+	tpPESession session_ptr;
+	struct wlan_objmgr_vdev *vdev;
+
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		/* Find first free room in session table */
+		if (pMac->lim.gpSession[i].valid == true)
+			continue;
+		break;
+	}
+
+	if (i == pMac->lim.maxBssId) {
+		pe_err("Session can't be created. Reached max sessions");
+		return NULL;
+	}
+
+	session_ptr = &pMac->lim.gpSession[i];
+	qdf_mem_set((void *)session_ptr, sizeof(tPESession), 0);
+	/* Allocate space for Station Table for this session. */
+	session_ptr->dph.dphHashTable.pHashTable =
+		qdf_mem_malloc(sizeof(tpDphHashNode) * (numSta + 1));
+	if (!session_ptr->dph.dphHashTable.pHashTable)
+		return NULL;
+
+	session_ptr->dph.dphHashTable.pDphNodeArray =
+					pe_get_session_dph_node_array(i);
+	session_ptr->dph.dphHashTable.size = numSta + 1;
+	dph_hash_table_class_init(pMac, &session_ptr->dph.dphHashTable);
+	session_ptr->gpLimPeerIdxpool = qdf_mem_malloc(
+		sizeof(*(session_ptr->gpLimPeerIdxpool)) *
+		lim_get_peer_idxpool_size(numSta, bssType));
+	if (!session_ptr->gpLimPeerIdxpool)
+		goto free_dp_hash_table;
+
+	session_ptr->freePeerIdxHead = 0;
+	session_ptr->freePeerIdxTail = 0;
+	session_ptr->gLimNumOfCurrentSTAs = 0;
+	/* Copy the BSSID to the session table */
+	sir_copy_mac_addr(session_ptr->bssId, bssid);
+	if (bssType == eSIR_MONITOR_MODE)
+		sir_copy_mac_addr(pMac->lim.gpSession[i].selfMacAddr, bssid);
+	session_ptr->valid = true;
+	/* Initialize the SME and MLM states to IDLE */
+	session_ptr->limMlmState = eLIM_MLM_IDLE_STATE;
+	session_ptr->limSmeState = eLIM_SME_IDLE_STATE;
+	session_ptr->limCurrentAuthType = eSIR_OPEN_SYSTEM;
+	pe_init_beacon_params(pMac, &pMac->lim.gpSession[i]);
+	session_ptr->is11Rconnection = false;
+#ifdef FEATURE_WLAN_ESE
+	session_ptr->isESEconnection = false;
+#endif
+	session_ptr->isFastTransitionEnabled = false;
+	session_ptr->isFastRoamIniFeatureEnabled = false;
+	*sessionId = i;
+	session_ptr->peSessionId = i;
+	session_ptr->bssType = bssType;
+	session_ptr->gLimPhyMode = WNI_CFG_PHY_MODE_11G;
+	/* Initialize CB mode variables when session is created */
+	session_ptr->htSupportedChannelWidthSet = 0;
+	session_ptr->htRecommendedTxWidthSet = 0;
+	session_ptr->htSecondaryChannelOffset = 0;
+#ifdef FEATURE_WLAN_TDLS
+	qdf_mem_set(session_ptr->peerAIDBitmap,
+		    sizeof(session_ptr->peerAIDBitmap), 0);
+	session_ptr->tdls_prohibited = false;
+	session_ptr->tdls_chan_swit_prohibited = false;
+#endif
+	session_ptr->fWaitForProbeRsp = 0;
+	session_ptr->fIgnoreCapsChange = 0;
+	session_ptr->ignore_assoc_disallowed = pMac->ignore_assoc_disallowed;
+	session_ptr->is_session_obss_color_collision_det_enabled =
+		pMac->lim.global_obss_color_collision_det_offload;
+
+	pe_debug("Create a new PE session: %d BSSID: "MAC_ADDRESS_STR" Max No of STA: %d",
+		*sessionId, MAC_ADDR_ARRAY(bssid), numSta);
+
+	if (eSIR_INFRA_AP_MODE == bssType || eSIR_IBSS_MODE == bssType) {
+		session_ptr->pSchProbeRspTemplate =
+			qdf_mem_malloc(SIR_MAX_PROBE_RESP_SIZE);
+		session_ptr->pSchBeaconFrameBegin =
+			qdf_mem_malloc(SIR_MAX_BEACON_SIZE);
+		session_ptr->pSchBeaconFrameEnd =
+			qdf_mem_malloc(SIR_MAX_BEACON_SIZE);
+		if ((NULL == session_ptr->pSchProbeRspTemplate)
+		    || (NULL == session_ptr->pSchBeaconFrameBegin)
+		    || (NULL == session_ptr->pSchBeaconFrameEnd)) {
+			goto free_session_attrs;
+		}
+	}
+
+	/*
+	 * Get vdev object from soc which automatically increments
+	 * reference count.
+	 */
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(pMac->psoc,
+						    sme_session_id,
+						    WLAN_LEGACY_MAC_ID);
+	if (!vdev) {
+		pe_err("vdev is NULL for vdev_id: %u", sme_session_id);
+		goto free_session_attrs;
+	}
+	session_ptr->vdev = vdev;
+	session_ptr->smeSessionId = sme_session_id;
+	session_ptr->mac_ctx = pMac;
+
+	if (eSIR_INFRASTRUCTURE_MODE == bssType)
+		lim_ft_open(pMac, &pMac->lim.gpSession[i]);
+
+	if (eSIR_MONITOR_MODE == bssType)
+		lim_ft_open(pMac, &pMac->lim.gpSession[i]);
+
+	if (eSIR_INFRA_AP_MODE == bssType) {
+		session_ptr->old_protection_state = 0;
+		session_ptr->is_session_obss_offload_enabled = false;
+		session_ptr->is_obss_reset_timer_initialized = false;
+
+		status = qdf_mc_timer_init(&session_ptr->
+					   protection_fields_reset_timer,
+					   QDF_TIMER_TYPE_SW,
+					   pe_reset_protection_callback,
+					   (void *)&pMac->lim.gpSession[i]);
+
+		if (QDF_IS_STATUS_ERROR(status))
+			pe_err("cannot create protection fields reset timer");
+		else
+			session_ptr->is_obss_reset_timer_initialized = true;
+
+		status = qdf_mc_timer_init(&session_ptr->ap_ecsa_timer,
+					   QDF_TIMER_TYPE_WAKE_APPS,
+					   lim_process_ap_ecsa_timeout,
+					   (void *)&pMac->lim.gpSession[i]);
+		if (status != QDF_STATUS_SUCCESS)
+			pe_err("cannot create ap_ecsa_timer");
+	}
+	pe_init_fils_info(session_ptr);
+	pe_init_pmf_comeback_timer(pMac, session_ptr, *sessionId);
+	session_ptr->ht_client_cnt = 0;
+	/* following is invalid value since seq number is 12 bit */
+	session_ptr->prev_auth_seq_num = 0xFFFF;
+
+	return &pMac->lim.gpSession[i];
+
+free_session_attrs:
+	qdf_mem_free(session_ptr->gpLimPeerIdxpool);
+	qdf_mem_free(session_ptr->pSchProbeRspTemplate);
+	qdf_mem_free(session_ptr->pSchBeaconFrameBegin);
+	qdf_mem_free(session_ptr->pSchBeaconFrameEnd);
+
+	session_ptr->gpLimPeerIdxpool = NULL;
+	session_ptr->pSchProbeRspTemplate = NULL;
+	session_ptr->pSchBeaconFrameBegin = NULL;
+	session_ptr->pSchBeaconFrameEnd = NULL;
+
+free_dp_hash_table:
+	qdf_mem_free(session_ptr->dph.dphHashTable.pHashTable);
+	qdf_mem_zero(session_ptr->dph.dphHashTable.pDphNodeArray,
+		     sizeof(struct sDphHashNode) * (SIR_SAP_MAX_NUM_PEERS + 1));
+
+	session_ptr->dph.dphHashTable.pHashTable = NULL;
+	session_ptr->dph.dphHashTable.pDphNodeArray = NULL;
+	session_ptr->valid = false;
+
+	return NULL;
+}
+
+/*--------------------------------------------------------------------------
+   \brief pe_find_session_by_bssid() - looks up the PE session given the BSSID.
+
+   This function returns the session context and the session ID if the session
+   corresponding to the given BSSID is found in the PE session table.
+
+   \param pMac                   - pointer to global adapter context
+   \param bssid                   - BSSID of the session
+   \param sessionId             -session ID is returned here, if session is found.
+
+   \return tpPESession          - pointer to the session context or NULL if session is not found.
+
+   \sa
+   --------------------------------------------------------------------------*/
+tpPESession pe_find_session_by_bssid(tpAniSirGlobal pMac, uint8_t *bssid,
+				     uint8_t *sessionId)
+{
+	uint8_t i;
+
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		/* If BSSID matches return corresponding tables address */
+		if ((pMac->lim.gpSession[i].valid)
+		    && (sir_compare_mac_addr(pMac->lim.gpSession[i].bssId,
+					    bssid))) {
+			*sessionId = i;
+			return &pMac->lim.gpSession[i];
+		}
+	}
+
+	return NULL;
+
+}
+
+/*--------------------------------------------------------------------------
+   \brief pe_find_session_by_bss_idx() - looks up the PE session given the bssIdx.
+
+   This function returns the session context  if the session
+   corresponding to the given bssIdx is found in the PE session table.
+   \param pMac                   - pointer to global adapter context
+   \param bssIdx                   - bss index of the session
+   \return tpPESession          - pointer to the session context or NULL if session is not found.
+   \sa
+   --------------------------------------------------------------------------*/
+tpPESession pe_find_session_by_bss_idx(tpAniSirGlobal pMac, uint8_t bssIdx)
+{
+	uint8_t i;
+
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		/* If BSSID matches return corresponding tables address */
+		if ((pMac->lim.gpSession[i].valid)
+		    && (pMac->lim.gpSession[i].bssIdx == bssIdx)) {
+			return &pMac->lim.gpSession[i];
+		}
+	}
+	pe_debug("Session lookup fails for bssIdx: %d", bssIdx);
+	return NULL;
+}
+
+/*--------------------------------------------------------------------------
+   \brief pe_find_session_by_session_id() - looks up the PE session given the session ID.
+
+   This function returns the session context  if the session
+   corresponding to the given session ID is found in the PE session table.
+
+   \param pMac                   - pointer to global adapter context
+   \param sessionId             -session ID for which session context needs to be looked up.
+
+   \return tpPESession          - pointer to the session context or NULL if session is not found.
+
+   \sa
+   --------------------------------------------------------------------------*/
+tpPESession pe_find_session_by_session_id(tpAniSirGlobal pMac,
+					  uint8_t sessionId)
+{
+	if (sessionId >= pMac->lim.maxBssId) {
+		pe_err("Invalid sessionId: %d", sessionId);
+		return NULL;
+	}
+
+	if (pMac->lim.gpSession[sessionId].valid)
+		return &pMac->lim.gpSession[sessionId];
+
+	return NULL;
+}
+
+/**
+ * pe_find_session_by_sta_id() - looks up the PE session given staid.
+ * @mac_ctx:       pointer to global adapter context
+ * @staid:         StaId of the session
+ * @session_id:    session ID is returned here, if session is found.
+ *
+ * This function returns the session context and the session ID if the session
+ * corresponding to the given StaId is found in the PE session table.
+ *
+ * Return: session pointer
+ */
+tpPESession
+pe_find_session_by_sta_id(tpAniSirGlobal mac_ctx,
+			  uint8_t staid,
+			  uint8_t *session_id)
+{
+	uint8_t i, j;
+	tpPESession session_ptr;
+	dphHashTableClass *dph_ptr;
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		if (!mac_ctx->lim.gpSession[i].valid)
+			continue;
+		session_ptr = &mac_ctx->lim.gpSession[i];
+		dph_ptr = &session_ptr->dph.dphHashTable;
+		for (j = 0; j < dph_ptr->size; j++) {
+			if (dph_ptr->pDphNodeArray[j].valid
+			    && dph_ptr->pDphNodeArray[j].added
+			    && staid == dph_ptr->pDphNodeArray[j].staIndex) {
+				*session_id = i;
+				return session_ptr;
+			}
+		}
+	}
+
+	pe_debug("Session lookup fails for StaId: %d", staid);
+	return NULL;
+}
+
+/**
+ * pe_delete_session() - deletes the PE session given the session ID.
+ * @mac_ctx: pointer to global adapter context
+ * @session: session to be deleted.
+ *
+ * Deletes the given PE session
+ *
+ * Return: void
+ */
+void pe_delete_session(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+	uint16_t i = 0;
+	uint16_t n;
+	TX_TIMER *timer_ptr;
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!session || (session && !session->valid)) {
+		pe_err("session is not valid");
+		return;
+	}
+
+	pe_debug("Trying to delete PE session: %d Opmode: %d BssIdx: %d BSSID: "MAC_ADDRESS_STR,
+		session->peSessionId, session->operMode,
+		session->bssIdx,
+		MAC_ADDR_ARRAY(session->bssId));
+
+	lim_reset_bcn_probe_filter(mac_ctx, session);
+
+	/* Restore default failure timeout */
+	if (session->defaultAuthFailureTimeout) {
+		pe_debug("Restore default failure timeout");
+		if (cfg_in_range(CFG_AUTH_FAILURE_TIMEOUT,
+				 session->defaultAuthFailureTimeout))
+			mac_ctx->mlme_cfg->timeouts.auth_failure_timeout =
+				session->defaultAuthFailureTimeout;
+		else
+			mac_ctx->mlme_cfg->timeouts.auth_failure_timeout =
+				cfg_default(CFG_AUTH_FAILURE_TIMEOUT);
+	}
+
+	for (n = 0; n < (mac_ctx->lim.maxStation + 1); n++) {
+		timer_ptr = &mac_ctx->lim.limTimers.gpLimCnfWaitTimer[n];
+		if (session->peSessionId == timer_ptr->sessionId)
+			if (true == tx_timer_running(timer_ptr))
+				tx_timer_deactivate(timer_ptr);
+	}
+
+	if (LIM_IS_AP_ROLE(session)) {
+		qdf_mc_timer_stop(&session->protection_fields_reset_timer);
+		qdf_mc_timer_destroy(&session->protection_fields_reset_timer);
+		qdf_mc_timer_stop(&session->ap_ecsa_timer);
+		qdf_mc_timer_destroy(&session->ap_ecsa_timer);
+		lim_del_pmf_sa_query_timer(mac_ctx, session);
+	}
+
+	/* Delete FT related information */
+	lim_ft_cleanup(mac_ctx, session);
+	if (session->pLimStartBssReq != NULL) {
+		qdf_mem_free(session->pLimStartBssReq);
+		session->pLimStartBssReq = NULL;
+	}
+
+	if (session->pLimJoinReq != NULL) {
+		qdf_mem_free(session->pLimJoinReq);
+		session->pLimJoinReq = NULL;
+	}
+
+	if (session->pLimReAssocReq != NULL) {
+		qdf_mem_free(session->pLimReAssocReq);
+		session->pLimReAssocReq = NULL;
+	}
+
+	if (session->pLimMlmJoinReq != NULL) {
+		qdf_mem_free(session->pLimMlmJoinReq);
+		session->pLimMlmJoinReq = NULL;
+	}
+
+	if (session->dph.dphHashTable.pHashTable != NULL) {
+		qdf_mem_free(session->dph.dphHashTable.pHashTable);
+		session->dph.dphHashTable.pHashTable = NULL;
+	}
+
+	if (session->dph.dphHashTable.pDphNodeArray != NULL) {
+		qdf_mem_zero(session->dph.dphHashTable.pDphNodeArray,
+			sizeof(struct sDphHashNode) *
+			(SIR_SAP_MAX_NUM_PEERS + 1));
+		session->dph.dphHashTable.pDphNodeArray = NULL;
+	}
+
+	if (session->gpLimPeerIdxpool != NULL) {
+		qdf_mem_free(session->gpLimPeerIdxpool);
+		session->gpLimPeerIdxpool = NULL;
+	}
+
+	if (session->beacon != NULL) {
+		qdf_mem_free(session->beacon);
+		session->beacon = NULL;
+		session->bcnLen = 0;
+	}
+
+	if (session->assocReq != NULL) {
+		qdf_mem_free(session->assocReq);
+		session->assocReq = NULL;
+		session->assocReqLen = 0;
+	}
+
+	if (session->assocRsp != NULL) {
+		qdf_mem_free(session->assocRsp);
+		session->assocRsp = NULL;
+		session->assocRspLen = 0;
+	}
+
+	if (session->parsedAssocReq != NULL) {
+		tpSirAssocReq tmp_ptr = NULL;
+		/* Cleanup the individual allocation first */
+		for (i = 0; i < session->dph.dphHashTable.size; i++) {
+			if (session->parsedAssocReq[i] == NULL)
+				continue;
+			tmp_ptr = ((tpSirAssocReq)
+				  (session->parsedAssocReq[i]));
+			if (tmp_ptr->assocReqFrame) {
+				qdf_mem_free(tmp_ptr->assocReqFrame);
+				tmp_ptr->assocReqFrame = NULL;
+				tmp_ptr->assocReqFrameLength = 0;
+			}
+			qdf_mem_free(session->parsedAssocReq[i]);
+			session->parsedAssocReq[i] = NULL;
+		}
+		/* Cleanup the whole block */
+		qdf_mem_free(session->parsedAssocReq);
+		session->parsedAssocReq = NULL;
+	}
+	if (NULL != session->limAssocResponseData) {
+		qdf_mem_free(session->limAssocResponseData);
+		session->limAssocResponseData = NULL;
+	}
+	if (NULL != session->pLimMlmReassocRetryReq) {
+		qdf_mem_free(session->pLimMlmReassocRetryReq);
+		session->pLimMlmReassocRetryReq = NULL;
+	}
+	if (NULL != session->pLimMlmReassocReq) {
+		qdf_mem_free(session->pLimMlmReassocReq);
+		session->pLimMlmReassocReq = NULL;
+	}
+
+	if (NULL != session->pSchProbeRspTemplate) {
+		qdf_mem_free(session->pSchProbeRspTemplate);
+		session->pSchProbeRspTemplate = NULL;
+	}
+
+	if (NULL != session->pSchBeaconFrameBegin) {
+		qdf_mem_free(session->pSchBeaconFrameBegin);
+		session->pSchBeaconFrameBegin = NULL;
+	}
+
+	if (NULL != session->pSchBeaconFrameEnd) {
+		qdf_mem_free(session->pSchBeaconFrameEnd);
+		session->pSchBeaconFrameEnd = NULL;
+	}
+
+	/* Must free the buffer before peSession invalid */
+	if (NULL != session->addIeParams.probeRespData_buff) {
+		qdf_mem_free(session->addIeParams.probeRespData_buff);
+		session->addIeParams.probeRespData_buff = NULL;
+		session->addIeParams.probeRespDataLen = 0;
+	}
+	if (NULL != session->addIeParams.assocRespData_buff) {
+		qdf_mem_free(session->addIeParams.assocRespData_buff);
+		session->addIeParams.assocRespData_buff = NULL;
+		session->addIeParams.assocRespDataLen = 0;
+	}
+	if (NULL != session->addIeParams.probeRespBCNData_buff) {
+		qdf_mem_free(session->addIeParams.probeRespBCNData_buff);
+		session->addIeParams.probeRespBCNData_buff = NULL;
+		session->addIeParams.probeRespBCNDataLen = 0;
+	}
+#ifdef WLAN_FEATURE_11W
+	if (QDF_TIMER_STATE_RUNNING ==
+	    qdf_mc_timer_get_current_state(&session->pmfComebackTimer))
+		qdf_mc_timer_stop(&session->pmfComebackTimer);
+	qdf_mc_timer_destroy(&session->pmfComebackTimer);
+#endif
+	pe_delete_fils_info(session);
+	session->valid = false;
+
+	session->mac_ctx = NULL;
+	if (session->access_policy_vendor_ie)
+		qdf_mem_free(session->access_policy_vendor_ie);
+
+	session->access_policy_vendor_ie = NULL;
+
+	if (LIM_IS_AP_ROLE(session))
+		lim_check_and_reset_protection_params(mac_ctx);
+
+	vdev = session->vdev;
+	session->vdev = NULL;
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
+}
+
+/*--------------------------------------------------------------------------
+   \brief pe_find_session_by_peer_sta() - looks up the PE session given the Station Address.
+
+   This function returns the session context and the session ID if the session
+   corresponding to the given station address is found in the PE session table.
+
+   \param pMac                   - pointer to global adapter context
+   \param sa                       - Peer STA Address of the session
+   \param sessionId             -session ID is returned here, if session is found.
+
+   \return tpPESession          - pointer to the session context or NULL if session is not found.
+
+   \sa
+   --------------------------------------------------------------------------*/
+
+tpPESession pe_find_session_by_peer_sta(tpAniSirGlobal pMac, uint8_t *sa,
+					uint8_t *sessionId)
+{
+	uint8_t i;
+	tpDphHashNode pSta;
+	uint16_t aid;
+
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		if ((pMac->lim.gpSession[i].valid)) {
+			pSta =
+				dph_lookup_hash_entry(pMac, sa, &aid,
+						      &pMac->lim.gpSession[i].dph.
+						      dphHashTable);
+			if (pSta != NULL) {
+				*sessionId = i;
+				return &pMac->lim.gpSession[i];
+			}
+		}
+	}
+
+	pe_debug("Session lookup fails for Peer StaId:");
+	lim_print_mac_addr(pMac, sa, LOGD);
+	return NULL;
+}
+
+/**
+ * pe_find_session_by_sme_session_id() - looks up the PE session for given sme
+ * session id
+ * @mac_ctx:          pointer to global adapter context
+ * @sme_session_id:   sme session id
+ *
+ * looks up the PE session for given sme session id
+ *
+ * Return: pe session entry for given sme session if found else NULL
+ */
+tpPESession pe_find_session_by_sme_session_id(tpAniSirGlobal mac_ctx,
+					      uint8_t sme_session_id)
+{
+	uint8_t i;
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		if ((mac_ctx->lim.gpSession[i].valid) &&
+		     (mac_ctx->lim.gpSession[i].smeSessionId ==
+			sme_session_id)) {
+			return &mac_ctx->lim.gpSession[i];
+		}
+	}
+	return NULL;
+}
+
+/**
+ * pe_find_session_by_scan_id() - looks up the PE session for given scan id
+ * @mac_ctx:   pointer to global adapter context
+ * @scan_id:   scan id
+ *
+ * looks up the PE session for given scan id
+ *
+ * Return: pe session entry for given scan id if found else NULL
+ */
+tpPESession pe_find_session_by_scan_id(tpAniSirGlobal mac_ctx,
+				       uint32_t scan_id)
+{
+	uint8_t i;
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		if ((mac_ctx->lim.gpSession[i].valid) &&
+		    (mac_ctx->lim.gpSession[i].ftPEContext.pFTPreAuthReq) &&
+		    (mac_ctx->lim.gpSession[i].ftPEContext.pFTPreAuthReq
+		     ->scan_id == scan_id)) {
+			return &mac_ctx->lim.gpSession[i];
+		}
+	}
+	return NULL;
+}
+
+/**
+ * pe_get_active_session_count() - function to return active pe session count
+ *
+ * @mac_ctx: pointer to global mac structure
+ *
+ * returns number of active pe session count
+ *
+ * Return: 0 if there are no active sessions else return number of active
+ *          sessions
+ */
+uint8_t pe_get_active_session_count(tpAniSirGlobal mac_ctx)
+{
+	uint8_t i, active_session_count = 0;
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++)
+		if (mac_ctx->lim.gpSession[i].valid)
+			active_session_count++;
+
+	return active_session_count;
+}
diff --git a/core/mac/src/pe/lim/lim_session_utils.c b/core/mac/src/pe/lim/lim_session_utils.c
new file mode 100644
index 0000000..ab6b539
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_session_utils.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**=========================================================================
+
+   \file  lim_session_utils.c
+   \brief implementation for lim Session Utility  APIs
+   \author Sunit Bhatia
+   ========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include "ani_global.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "lim_session_utils.h"
+#include "lim_utils.h"
+
+/**
+ * is_lim_session_off_channel() - checks if any other off channel session exists
+ * @mac_ctx: Global MAC context.
+ * @sessionId: PE session ID.
+ *
+ * Return: This function returns true if the session Id passed needs to be on
+ *         a different channel than atleast one session already active.
+ **/
+uint8_t is_lim_session_off_channel(tpAniSirGlobal mac_ctx, uint8_t session_id)
+{
+	uint8_t i;
+
+	if (session_id >= mac_ctx->lim.maxBssId) {
+		pe_warn("Invalid session_id: %d", session_id);
+		return false;
+	}
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		/* Skip the session_id that is to be joined. */
+		if (i == session_id)
+			continue;
+		/*
+		 * if another session is valid and it is on different channel
+		 * then it is an off channel operation.
+		 */
+		if ((mac_ctx->lim.gpSession[i].valid) &&
+		    (mac_ctx->lim.gpSession[i].currentOperChannel !=
+		     mac_ctx->lim.gpSession[session_id].currentOperChannel))
+			return true;
+	}
+	return false;
+
+}
+
+/**
+ * lim_is_chan_switch_running() - check if channel switch is happening
+ * @mac_ctx: Global MAC context.
+ *
+ * Return: 1 - if channel switch is happening on any session.
+ *         0 - if channel switch is not happening.
+ **/
+uint8_t lim_is_chan_switch_running(tpAniSirGlobal mac_ctx)
+{
+	uint8_t i;
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++)
+		if (mac_ctx->lim.gpSession[i].valid &&
+			mac_ctx->lim.gpSession[i].gLimSpecMgmt.dot11hChanSwState
+			== eLIM_11H_CHANSW_RUNNING)
+			return 1;
+	return 0;
+}
+
+/**
+ * lim_is_in_mcc() - check if device is in MCC
+ * @mac_ctx: Global MAC context.
+ *
+ * Return: true - if in MCC.
+ *         false - Not in MCC
+ **/
+uint8_t lim_is_in_mcc(tpAniSirGlobal mac_ctx)
+{
+	uint8_t i;
+	uint8_t chan = 0;
+	uint8_t curr_oper_channel = 0;
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		/*
+		 * if another session is valid and it is on different channel
+		 * it is an off channel operation.
+		 */
+		if ((mac_ctx->lim.gpSession[i].valid)) {
+			curr_oper_channel =
+				mac_ctx->lim.gpSession[i].currentOperChannel;
+			if (curr_oper_channel == 0)
+				continue;
+			if (chan == 0)
+				chan = curr_oper_channel;
+			else if (chan != curr_oper_channel)
+				return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * pe_get_current_stas_count() - Total stations associated on all sessions.
+ * @mac_ctx: Global MAC context.
+ *
+ * Return: true - Number of stations active on all sessions.
+ **/
+uint8_t pe_get_current_stas_count(tpAniSirGlobal mac_ctx)
+{
+	uint8_t i;
+	uint8_t stacount = 0;
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++)
+		if (mac_ctx->lim.gpSession[i].valid == true)
+			stacount +=
+				mac_ctx->lim.gpSession[i].gLimNumOfCurrentSTAs;
+	return stacount;
+}
diff --git a/core/mac/src/pe/lim/lim_session_utils.h b/core/mac/src/pe/lim/lim_session_utils.h
new file mode 100644
index 0000000..9639d27
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_session_utils.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012-2015 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.
+ */
+
+#if !defined(__LIM_SESSION_UTILS_H)
+#define __LIM_SESSION_UTILS_H
+
+uint8_t is_lim_session_off_channel(tpAniSirGlobal pMac, uint8_t sessionId);
+uint8_t lim_is_chan_switch_running(tpAniSirGlobal pMac);
+uint8_t lim_is_in_mcc(tpAniSirGlobal pMac);
+uint8_t pe_get_current_stas_count(tpAniSirGlobal pMac);
+
+#endif /* #if !defined( __LIM_SESSION_UTILS_H ) */
diff --git a/core/mac/src/pe/lim/lim_sme_req_utils.c b/core/mac/src/pe/lim/lim_sme_req_utils.c
new file mode 100644
index 0000000..9e27af6
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_sme_req_utils.c
@@ -0,0 +1,823 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file lim_sme_req_utils.cc contains the utility functions
+ * for processing SME request messages.
+ * Author:        Chandra Modumudi
+ * Date:          02/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ * 05/26/10       js             WPA handling in (Re)Assoc frames
+ *
+ */
+
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include "sir_api.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_sme_req_utils.h"
+
+/**
+ * lim_is_rsn_ie_valid_in_sme_req_message()
+ *
+ * @mac_ctx   Pointer to Global MAC structure
+ * @rsn_ie    Pointer to received RSN IE
+ *
+ * This function is called to verify if the RSN IE received in various SME_REQ
+ * messages is valid or not
+ *
+ * Return: true when RSN IE is valid, false otherwise
+ *
+ */
+static uint8_t
+lim_is_rsn_ie_valid_in_sme_req_message(tpAniSirGlobal mac_ctx,
+				       tpSirRSNie rsn_ie)
+{
+	uint8_t start = 0, privacy;
+	uint32_t val;
+	int len;
+
+	privacy = mac_ctx->mlme_cfg->wep_params.is_privacy_enabled;
+
+	val = mac_ctx->mlme_cfg->feature_flags.enable_rsn;
+	if (rsn_ie->length && (!privacy || !val)) {
+		/* Privacy & RSN not enabled in CFG.
+		 * In order to allow mixed mode for Guest access
+		 * allow BSS creation/join with no Privacy capability
+		 * yet advertising WPA IE
+		 */
+		pe_debug("RSN ie len: %d PRIVACY: %d RSN: %d",
+			       rsn_ie->length, privacy, val);
+	}
+
+	if (!rsn_ie->length)
+		return true;
+
+	if ((rsn_ie->rsnIEdata[0] != DOT11F_EID_RSN)
+#ifdef FEATURE_WLAN_WAPI
+	    && (rsn_ie->rsnIEdata[0] != DOT11F_EID_WAPI)
+#endif
+	    && (rsn_ie->rsnIEdata[0] != DOT11F_EID_WPA)) {
+		pe_err("RSN/WPA/WAPI EID: %d not [%d || %d]",
+			rsn_ie->rsnIEdata[0], DOT11F_EID_RSN,
+			DOT11F_EID_WPA);
+		return false;
+	}
+
+	len = rsn_ie->length;
+	start = 0;
+	while (len > 0) {
+		switch (rsn_ie->rsnIEdata[start]) {
+		case DOT11F_EID_RSN:
+		/* Check validity of RSN IE */
+			if ((rsn_ie->rsnIEdata[start + 1] >
+			    DOT11F_IE_RSN_MAX_LEN)
+			    || (rsn_ie->rsnIEdata[start + 1] <
+				DOT11F_IE_RSN_MIN_LEN)) {
+				pe_err("RSN IE len: %d not [%d,%d]",
+					rsn_ie->rsnIEdata[start + 1],
+					DOT11F_IE_RSN_MIN_LEN,
+					DOT11F_IE_RSN_MAX_LEN);
+				return false;
+			}
+			break;
+		case DOT11F_EID_WPA:
+			/* Check validity of WPA IE */
+			if (SIR_MAC_MAX_IE_LENGTH <= start)
+				break;
+
+			if (start <= (SIR_MAC_MAX_IE_LENGTH - sizeof(uint32_t)))
+				val = sir_read_u32((uint8_t *) &
+					rsn_ie->rsnIEdata[start + 2]);
+
+			if ((rsn_ie->rsnIEdata[start + 1] <
+			     DOT11F_IE_WPA_MIN_LEN)
+			    || (rsn_ie->rsnIEdata[start + 1] >
+				DOT11F_IE_WPA_MAX_LEN)
+			    || (SIR_MAC_WPA_OUI != val)) {
+				pe_err("WPA IE len: %d not [%d,%d] OR data 0x%x not 0x%x",
+					rsn_ie->rsnIEdata[start + 1],
+					DOT11F_IE_WPA_MIN_LEN,
+					DOT11F_IE_WPA_MAX_LEN,
+					val, SIR_MAC_WPA_OUI);
+				return false;
+			}
+			break;
+#ifdef FEATURE_WLAN_WAPI
+		case DOT11F_EID_WAPI:
+			if ((rsn_ie->rsnIEdata[start + 1] >
+			    DOT11F_IE_WAPI_MAX_LEN)
+			    || (rsn_ie->rsnIEdata[start + 1] <
+				DOT11F_IE_WAPI_MIN_LEN)) {
+				pe_err("WAPI IE len: %d not [%d,%d]",
+					rsn_ie->rsnIEdata[start + 1],
+					DOT11F_IE_WAPI_MIN_LEN,
+					DOT11F_IE_WAPI_MAX_LEN);
+				return false;
+			}
+			break;
+#endif
+		default:
+			/* we will never be here, simply for completeness */
+			return false;
+		} /* end of switch */
+		/* EID + length field + length */
+		start += 2 + rsn_ie->rsnIEdata[start + 1];
+		len -= start;
+	} /* end while loop */
+	return true;
+} /*** end lim_is_rs_nie_valid_in_sme_req_message() ***/
+
+/**
+ * lim_is_addie_valid_in_sme_req_message()
+ *
+ ***FUNCTION:
+ * This function is called to verify if the Add IE
+ * received in various SME_REQ messages is valid or not
+ *
+ ***LOGIC:
+ * Add IE validity checks are performed on only length
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac   Pointer to Global MAC structure
+ * @param  pWSCie Pointer to received WSC IE
+ * @return true when WSC IE is valid, false otherwise
+ */
+
+static uint8_t
+lim_is_addie_valid_in_sme_req_message(tpAniSirGlobal pMac, tpSirAddie pAddie)
+{
+	int left = pAddie->length;
+	uint8_t *ptr = pAddie->addIEdata;
+	uint8_t elem_id, elem_len;
+
+	if (left == 0)
+		return true;
+
+	while (left >= 2) {
+		elem_id = ptr[0];
+		elem_len = ptr[1];
+		left -= 2;
+		if (elem_len > left) {
+			pe_err("Invalid Add IEs eid: %d elem_len: %d left: %d",
+				elem_id, elem_len, left);
+			return false;
+		}
+
+		left -= elem_len;
+		ptr += (elem_len + 2);
+	}
+	/* there shouldn't be any left byte */
+
+	return true;
+} /*** end lim_is_addie_valid_in_sme_req_message() ***/
+
+/**
+ * lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message() - to set rsnie/wpaie
+ *
+ * @mac_ctx : Pointer to Global MAC structure
+ * @rsn_ie  : Pointer to received RSN IE
+ * @session : Pointer to pe session
+ *
+ * This function is called to verify if the RSN IE received in various
+ * SME_REQ messages is valid or not. RSN IE validity checks are performed in
+ * this function
+ *
+ * Return: true when RSN IE is valid, false otherwise
+ */
+uint8_t
+lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message(tpAniSirGlobal mac_ctx,
+						    tpSirRSNie rsn_ie,
+						    tpPESession session)
+{
+	uint32_t ret;
+	uint8_t wpa_idx = 0;
+	uint32_t val;
+	bool privacy;
+
+	privacy = mac_ctx->mlme_cfg->wep_params.is_privacy_enabled;
+
+	val = mac_ctx->mlme_cfg->feature_flags.enable_rsn;
+	if (rsn_ie->length && (!privacy || !val)) {
+		/*
+		 * Privacy & RSN not enabled in CFG.
+		 * In order to allow mixed mode for Guest access
+		 * allow BSS creation/join with no Privacy capability
+		 * yet advertising WPA IE
+		 */
+		pe_debug("RSN ie len: %d but PRIVACY: %d RSN: %d",
+			rsn_ie->length, privacy, val);
+	}
+
+	if (!rsn_ie->length)
+		return true;
+
+	if ((rsn_ie->rsnIEdata[0] != SIR_MAC_RSN_EID) &&
+	    (rsn_ie->rsnIEdata[0] != SIR_MAC_WPA_EID)) {
+		pe_err("RSN/WPA EID: %d not [%d || %d]",
+			rsn_ie->rsnIEdata[0], SIR_MAC_RSN_EID,
+			SIR_MAC_WPA_EID);
+		return false;
+	}
+	/* Check validity of RSN IE */
+	if ((rsn_ie->rsnIEdata[0] == SIR_MAC_RSN_EID) &&
+	    (rsn_ie->rsnIEdata[1] < SIR_MAC_RSN_IE_MIN_LENGTH)) {
+		pe_err("RSN IE len: %d not [%d,%d]",
+			rsn_ie->rsnIEdata[1], SIR_MAC_RSN_IE_MIN_LENGTH,
+			SIR_MAC_RSN_IE_MAX_LENGTH);
+		return false;
+	}
+
+	if (rsn_ie->length > rsn_ie->rsnIEdata[1] + 2) {
+		if (rsn_ie->rsnIEdata[0] != SIR_MAC_RSN_EID) {
+			pe_err("First byte: %d in rsnIEdata isn't RSN_EID",
+				rsn_ie->rsnIEdata[1]);
+			return false;
+		}
+		pe_debug("WPA IE is present along with WPA2 IE");
+		wpa_idx = 2 + rsn_ie->rsnIEdata[1];
+	} else if ((rsn_ie->length == rsn_ie->rsnIEdata[1] + 2) &&
+		   (rsn_ie->rsnIEdata[0] == SIR_MAC_RSN_EID)) {
+		pe_debug("Only RSN IE is present");
+		ret = dot11f_unpack_ie_rsn(mac_ctx, &rsn_ie->rsnIEdata[2],
+					   rsn_ie->rsnIEdata[1],
+					   &session->gStartBssRSNIe, false);
+		if (!DOT11F_SUCCEEDED(ret)) {
+			pe_err("unpack failed, ret: %d", ret);
+			return false;
+		}
+		return true;
+	} else if ((rsn_ie->length == rsn_ie->rsnIEdata[1] + 2)
+		   && (rsn_ie->rsnIEdata[0] == SIR_MAC_WPA_EID)) {
+		pe_debug("Only WPA IE is present");
+		ret = dot11f_unpack_ie_wpa(mac_ctx, &rsn_ie->rsnIEdata[6],
+					   rsn_ie->rsnIEdata[1] - 4,
+					   &session->gStartBssWPAIe, false);
+		if (!DOT11F_SUCCEEDED(ret)) {
+			pe_err("unpack failed, ret: %d", ret);
+			return false;
+		}
+		return true;
+	}
+	/* Check validity of WPA IE */
+	if (wpa_idx + 6 >= SIR_MAC_MAX_IE_LENGTH)
+		return false;
+
+	val = sir_read_u32((uint8_t *)&rsn_ie->rsnIEdata[wpa_idx + 2]);
+	if ((rsn_ie->rsnIEdata[wpa_idx] == SIR_MAC_WPA_EID)
+	    && ((rsn_ie->rsnIEdata[wpa_idx + 1] < SIR_MAC_WPA_IE_MIN_LENGTH)
+	     || (SIR_MAC_WPA_OUI != val))) {
+		pe_err("WPA IE len: %d not [%d,%d] OR data 0x%x not 0x%x",
+			rsn_ie->rsnIEdata[1],
+			SIR_MAC_RSN_IE_MIN_LENGTH,
+			SIR_MAC_RSN_IE_MAX_LENGTH, val,
+			SIR_MAC_WPA_OUI);
+		return false;
+	} else {
+		/* Both RSN and WPA IEs are present */
+		ret = dot11f_unpack_ie_rsn(mac_ctx, &rsn_ie->rsnIEdata[2],
+					   rsn_ie->rsnIEdata[1],
+					   &session->gStartBssRSNIe, false);
+		if (!DOT11F_SUCCEEDED(ret)) {
+			pe_err("unpack failed, ret: %d", ret);
+			return false;
+		}
+		ret = dot11f_unpack_ie_wpa(mac_ctx,
+					   &rsn_ie->rsnIEdata[wpa_idx + 6],
+					   rsn_ie->rsnIEdata[wpa_idx + 1] - 4,
+					   &session->gStartBssWPAIe, false);
+		if (!DOT11F_SUCCEEDED(ret)) {
+			pe_err("unpack failed, ret: %d", ret);
+			return false;
+		}
+	}
+	return true;
+}
+
+/**
+ * lim_is_bss_descr_valid_in_sme_req_message()
+ *
+ ***FUNCTION:
+ * This function is called to verify if the BSS Descr
+ * received in various SME_REQ messages is valid or not
+ *
+ ***LOGIC:
+ * BSS Descritipion validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac      Pointer to Global MAC structure
+ * @param  pBssDescr Pointer to received Bss Descritipion
+ * @return true when BSS description is valid, false otherwise
+ */
+
+static uint8_t
+lim_is_bss_descr_valid_in_sme_req_message(tpAniSirGlobal pMac,
+					  tpSirBssDescription pBssDescr)
+{
+	uint8_t valid = true;
+
+	if (lim_is_addr_bc(pBssDescr->bssId) || !pBssDescr->channelId) {
+		valid = false;
+		goto end;
+	}
+
+end:
+	return valid;
+} /*** end lim_is_bss_descr_valid_in_sme_req_message() ***/
+
+/**
+ * lim_is_sme_start_bss_req_valid() - To validate sme start bss request
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @start_bss_req: Pointer to received SME_START_BSS_REQ message
+ *
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_START_BSS_REQ message from application.
+ *
+ * Return: true when received SME_START_BSS_REQ is formatted correctly false
+ *         otherwise
+ */
+
+uint8_t
+lim_is_sme_start_bss_req_valid(tpAniSirGlobal mac_ctx,
+			       tpSirSmeStartBssReq start_bss_req)
+{
+	uint8_t i = 0;
+	tSirMacRateSet *opr_rates = &start_bss_req->operationalRateSet;
+
+	pe_debug("Parsed START_BSS_REQ fields are bssType: %s (%d) channelId: %d SSID len: %d rsnIE len: %d nwType: %d rateset len: %d",
+	       lim_bss_type_to_string(start_bss_req->bssType),
+	       start_bss_req->bssType, start_bss_req->channelId,
+	       start_bss_req->ssId.length, start_bss_req->rsnIE.length,
+	       start_bss_req->nwType, opr_rates->numRates);
+
+	switch (start_bss_req->bssType) {
+	case eSIR_INFRASTRUCTURE_MODE:
+		/**
+		 * Should not have received start BSS req with bssType
+		 * Infrastructure on STA.
+		 */
+		pe_warn("Invalid bssType: %d in eWNI_SME_START_BSS_REQ",
+			start_bss_req->bssType);
+		return false;
+		break;
+	case eSIR_IBSS_MODE:
+		break;
+	case eSIR_INFRA_AP_MODE:
+		break;
+	case eSIR_NDI_MODE:
+		break;
+	default:
+		/**
+		 * Should not have received start BSS req with bssType
+		 * other than Infrastructure/IBSS.
+		 */
+		pe_warn("Invalid bssType: %d in eWNI_SME_START_BSS_REQ",
+			start_bss_req->bssType);
+		return false;
+	}
+
+	if (start_bss_req->bssType == eSIR_IBSS_MODE
+	    && (!start_bss_req->ssId.length
+		|| start_bss_req->ssId.length > SIR_MAC_MAX_SSID_LENGTH)) {
+		pe_warn("Invalid SSID length in eWNI_SME_START_BSS_REQ");
+		return false;
+	}
+
+	if (!lim_is_rsn_ie_valid_in_sme_req_message(mac_ctx,
+						    &start_bss_req->rsnIE))
+		return false;
+
+	if (start_bss_req->nwType != eSIR_11A_NW_TYPE
+	    && start_bss_req->nwType != eSIR_11B_NW_TYPE
+	    && start_bss_req->nwType != eSIR_11G_NW_TYPE)
+		return false;
+
+	if (start_bss_req->nwType == eSIR_11A_NW_TYPE) {
+		for (i = 0; i < opr_rates->numRates; i++) {
+			if (sirIsArate(opr_rates->rate[i] & 0x7F))
+				continue;
+
+			pe_warn("Invalid operational 11A rates");
+			QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+					   QDF_TRACE_LEVEL_WARN,
+					   opr_rates->rate,
+					   opr_rates->numRates);
+			return false;
+		}
+		return true;
+	}
+	/* check if all the rates in the opr rate set are legal 11G rates */
+	if (start_bss_req->nwType == eSIR_11G_NW_TYPE) {
+		for (i = 0; i < opr_rates->numRates; i++) {
+			if (sirIsGrate(opr_rates->rate[i] & 0x7F))
+				continue;
+
+			pe_warn("Invalid operational 11G rates");
+			QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+					   QDF_TRACE_LEVEL_WARN,
+					   opr_rates->rate,
+					   opr_rates->numRates);
+			return false;
+		}
+		return true;
+	}
+
+	for (i = 0; i < opr_rates->numRates; i++) {
+		if (sirIsBrate(opr_rates->rate[i] & 0x7F))
+			continue;
+
+		pe_warn("Invalid operational 11B rates");
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+				   QDF_TRACE_LEVEL_WARN,
+				   opr_rates->rate,
+				   opr_rates->numRates);
+		return false;
+	}
+	return true;
+}
+
+/**
+ * lim_is_sme_join_req_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_JOIN_REQ message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac       Pointer to Global MAC structure
+ * @param  pJoinReq   Pointer to received SME_JOIN_REQ message
+ * @return true  when received SME_JOIN_REQ is formatted correctly
+ *         false otherwise
+ */
+
+uint8_t lim_is_sme_join_req_valid(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq)
+{
+	uint8_t valid = true;
+
+	/*
+	 * If force_rsne_override is enabled that mean User has provided the
+	 * test RSNIE which need to be send as it is in assoc req and thus RSNIE
+	 * validity is not required.
+	 */
+	if (!pJoinReq->force_rsne_override &&
+	    !lim_is_rsn_ie_valid_in_sme_req_message(pMac, &pJoinReq->rsnIE)) {
+		pe_err("received SME_JOIN_REQ with invalid RSNIE");
+		valid = false;
+		goto end;
+	}
+
+	if (!lim_is_addie_valid_in_sme_req_message(pMac, &pJoinReq->addIEScan)) {
+		pe_err("received SME_JOIN_REQ with invalid additional IE for scan");
+		valid = false;
+		goto end;
+	}
+
+	if (!lim_is_addie_valid_in_sme_req_message(pMac, &pJoinReq->addIEAssoc)) {
+		pe_err("received SME_JOIN_REQ with invalid additional IE for assoc");
+		valid = false;
+		goto end;
+	}
+
+	if (!lim_is_bss_descr_valid_in_sme_req_message(pMac, &pJoinReq->bssDescription)) {
+		/* / Received eWNI_SME_JOIN_REQ with invalid BSS Info */
+		/* Log the event */
+		pe_err("received SME_JOIN_REQ with invalid bssInfo");
+
+		valid = false;
+		goto end;
+	}
+
+	/*
+	   Reject Join Req if the Self Mac Address and
+	   the Ap's Mac Address is same
+	 */
+	if (!qdf_mem_cmp((uint8_t *) pJoinReq->selfMacAddr,
+			    (uint8_t *) pJoinReq->bssDescription.bssId,
+			    (uint8_t) (sizeof(tSirMacAddr)))) {
+		/* Log the event */
+		pe_err("received SME_JOIN_REQ with Self Mac and BSSID Same");
+
+		valid = false;
+		goto end;
+	}
+
+end:
+	return valid;
+} /*** end lim_is_sme_join_req_valid() ***/
+
+/**
+ * lim_is_sme_disassoc_req_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_DISASSOC_REQ message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac         Pointer to Global MAC structure
+ * @param  pDisassocReq Pointer to received SME_DISASSOC_REQ message
+ * @return true         When received SME_DISASSOC_REQ is formatted
+ *                      correctly
+ *         false        otherwise
+ */
+
+uint8_t
+lim_is_sme_disassoc_req_valid(tpAniSirGlobal pMac,
+			      tpSirSmeDisassocReq pDisassocReq,
+			      tpPESession psessionEntry)
+{
+	if (qdf_is_macaddr_group(&pDisassocReq->peer_macaddr) &&
+	    !qdf_is_macaddr_broadcast(&pDisassocReq->peer_macaddr))
+		return false;
+
+	return true;
+} /*** end lim_is_sme_disassoc_req_valid() ***/
+
+/**
+ * lim_is_sme_disassoc_cnf_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_DISASSOC_CNF message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac         Pointer to Global MAC structure
+ * @param  pDisassocCnf Pointer to received SME_DISASSOC_REQ message
+ * @return true         When received SME_DISASSOC_CNF is formatted
+ *                      correctly
+ *         false        otherwise
+ */
+
+uint8_t
+lim_is_sme_disassoc_cnf_valid(tpAniSirGlobal pMac,
+			      tpSirSmeDisassocCnf pDisassocCnf,
+			      tpPESession psessionEntry)
+{
+	if (qdf_is_macaddr_group(&pDisassocCnf->peer_macaddr))
+		return false;
+
+	return true;
+} /*** end lim_is_sme_disassoc_cnf_valid() ***/
+
+/**
+ * lim_is_sme_deauth_req_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_DEAUTH_REQ message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac       Pointer to Global MAC structure
+ * @param  pDeauthReq Pointer to received SME_DEAUTH_REQ message
+ * @return true       When received SME_DEAUTH_REQ is formatted correctly
+ *         false      otherwise
+ */
+
+uint8_t
+lim_is_sme_deauth_req_valid(tpAniSirGlobal pMac, tpSirSmeDeauthReq pDeauthReq,
+			    tpPESession psessionEntry)
+{
+	if (qdf_is_macaddr_group(&pDeauthReq->peer_macaddr) &&
+	    !qdf_is_macaddr_broadcast(&pDeauthReq->peer_macaddr))
+		return false;
+
+	return true;
+} /*** end lim_is_sme_deauth_req_valid() ***/
+
+/**
+ * lim_is_sme_set_context_req_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_SET_CONTEXT_REQ message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMsg - Pointer to received SME_SET_CONTEXT_REQ message
+ * @return true  when received SME_SET_CONTEXT_REQ is formatted correctly
+ *         false otherwise
+ */
+
+uint8_t
+lim_is_sme_set_context_req_valid(tpAniSirGlobal pMac,
+				 tpSirSmeSetContextReq pSetContextReq)
+{
+	uint8_t i = 0;
+	uint8_t valid = true;
+	tpSirKeys pKey = pSetContextReq->keyMaterial.key;
+
+	if ((pSetContextReq->keyMaterial.edType != eSIR_ED_WEP40) &&
+	    (pSetContextReq->keyMaterial.edType != eSIR_ED_WEP104) &&
+	    (pSetContextReq->keyMaterial.edType != eSIR_ED_NONE) &&
+#ifdef FEATURE_WLAN_WAPI
+	    (pSetContextReq->keyMaterial.edType != eSIR_ED_WPI) &&
+#endif
+	    !pSetContextReq->keyMaterial.numKeys) {
+		/**
+		 * No keys present in case of TKIP or CCMP
+		 * Log error.
+		 */
+		pe_warn("No keys present in SME_SETCONTEXT_REQ for edType: %d",
+			pSetContextReq->keyMaterial.edType);
+
+		valid = false;
+		goto end;
+	}
+
+	if (pSetContextReq->keyMaterial.numKeys &&
+	    (pSetContextReq->keyMaterial.edType == eSIR_ED_NONE)) {
+		/**
+		 * Keys present in case of no ED policy
+		 * Log error.
+		 */
+		pe_warn("Keys present in SME_SETCONTEXT_REQ for edType: %d",
+			pSetContextReq->keyMaterial.edType);
+
+		valid = false;
+		goto end;
+	}
+
+	if (pSetContextReq->keyMaterial.edType >= eSIR_ED_NOT_IMPLEMENTED) {
+		/**
+		 * Invalid edType in the message
+		 * Log error.
+		 */
+		pe_warn("Invalid edType: %d in SME_SETCONTEXT_REQ",
+			pSetContextReq->keyMaterial.edType);
+
+		valid = false;
+		goto end;
+	} else if (pSetContextReq->keyMaterial.edType > eSIR_ED_NONE) {
+		bool privacy;
+
+		privacy = pMac->mlme_cfg->wep_params.is_privacy_enabled;
+
+		if (!privacy) {
+			/**
+			 * Privacy is not enabled
+			 * In order to allow mixed mode for Guest access
+			 * allow BSS creation/join with no Privacy capability
+			 * yet advertising WPA IE
+			 */
+			pe_debug("Privacy is not enabled, yet non-None EDtype: %d in SME_SETCONTEXT_REQ",
+				       pSetContextReq->keyMaterial.edType);
+		}
+	}
+
+	for (i = 0; i < pSetContextReq->keyMaterial.numKeys; i++) {
+		if (((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP40) &&
+		     (pKey->keyLength != 5)) ||
+		    ((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP104) &&
+		     (pKey->keyLength != 13)) ||
+		    ((pSetContextReq->keyMaterial.edType == eSIR_ED_TKIP) &&
+		     (pKey->keyLength != 32)) ||
+#ifdef FEATURE_WLAN_WAPI
+		    ((pSetContextReq->keyMaterial.edType == eSIR_ED_WPI) &&
+		     (pKey->keyLength != 32)) ||
+#endif
+		    ((pSetContextReq->keyMaterial.edType == eSIR_ED_GCMP) &&
+		     (pKey->keyLength != 16)) ||
+		    ((pSetContextReq->keyMaterial.edType == eSIR_ED_GCMP_256) &&
+		     (pKey->keyLength != 32)) ||
+		    ((pSetContextReq->keyMaterial.edType == eSIR_ED_CCMP) &&
+		     (pKey->keyLength != 16))) {
+			/**
+			 * Invalid key length for a given ED type
+			 * Log error.
+			 */
+			pe_warn("Invalid keyLength: %d for edType: %d in SME_SETCONTEXT_REQ",
+				pKey->keyLength,
+				pSetContextReq->keyMaterial.edType);
+
+			valid = false;
+			goto end;
+		}
+		pKey++;
+	}
+
+end:
+	return valid;
+} /*** end lim_is_sme_set_context_req_valid() ***/
+
+/**
+ * lim_is_sme_stop_bss_req_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_STOP_BSS_REQ message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMsg - Pointer to received SME_STOP_BSS_REQ message
+ * @return true  when received SME_STOP_BSS_REQ is formatted correctly
+ *         false otherwise
+ */
+
+uint8_t lim_is_sme_stop_bss_req_valid(uint32_t *pMsg)
+{
+	uint8_t valid = true;
+
+	return valid;
+} /*** end lim_is_sme_stop_bss_req_valid() ***/
+
+/**
+ * lim_get_bss_id_from_sme_join_req_msg()
+ *
+ ***FUNCTION:
+ * This function is called in various places to get BSSID
+ * from BSS description/Neighbor BSS Info in the SME_JOIN_REQ/
+ * SME_REASSOC_REQ message.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param     pBuf   - Pointer to received SME_JOIN/SME_REASSOC_REQ
+ *                     message
+ * @return    pBssId - Pointer to BSSID
+ */
+
+uint8_t *lim_get_bss_id_from_sme_join_req_msg(uint8_t *pBuf)
+{
+	if (!pBuf)
+		return NULL;
+
+	pBuf += sizeof(uint32_t);       /* skip message header */
+
+	pBuf += lim_get_u16(pBuf) + sizeof(uint16_t);     /* skip RSN IE */
+
+	pBuf += sizeof(uint16_t);       /* skip length of BSS description */
+
+	return pBuf;
+} /*** end lim_get_bss_id_from_sme_join_req_msg() ***/
diff --git a/core/mac/src/pe/lim/lim_sme_req_utils.h b/core/mac/src/pe/lim/lim_sme_req_utils.h
new file mode 100644
index 0000000..7bcf5b8
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_sme_req_utils.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011-2012,2014-2015,2018 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.
+ */
+
+/*
+ *
+ * This file lim_sme_req_utils.h contains the utility definitions
+ * LIM uses while processing SME request messages.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SME_REQ_UTILS_H
+#define __LIM_SME_REQ_UTILS_H
+
+#include "sir_api.h"
+#include "lim_types.h"
+
+/* LIM SME request messages related utility functions */
+uint8_t lim_is_sme_start_bss_req_valid(tpAniSirGlobal, tpSirSmeStartBssReq);
+uint8_t lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message(tpAniSirGlobal,
+							    tpSirRSNie, tpPESession);
+uint8_t lim_is_sme_join_req_valid(tpAniSirGlobal, tpSirSmeJoinReq);
+uint8_t lim_is_sme_disassoc_req_valid(tpAniSirGlobal, tpSirSmeDisassocReq,
+				      tpPESession);
+uint8_t lim_is_sme_deauth_req_valid(tpAniSirGlobal, tpSirSmeDeauthReq, tpPESession);
+uint8_t lim_is_sme_set_context_req_valid(tpAniSirGlobal, tpSirSmeSetContextReq);
+uint8_t lim_is_sme_stop_bss_req_valid(uint32_t *);
+uint8_t *lim_get_bss_id_from_sme_join_req_msg(uint8_t *);
+uint8_t lim_is_sme_disassoc_cnf_valid(tpAniSirGlobal, tpSirSmeDisassocCnf,
+				      tpPESession);
+
+#endif /* __LIM_SME_REQ_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_sta_hash_api.c b/core/mac/src/pe/lim/lim_sta_hash_api.c
new file mode 100644
index 0000000..3fa1df7
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_sta_hash_api.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011-2012, 2017-2018 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.
+ */
+
+/*
+ *
+ * lim_sta_hash_api.c: Provides access functions to get/set values of station hash entry fields.
+ * Author:    Sunit Bhatia
+ * Date:       09/19/2006
+ * History:-
+ * Date        Modified by            Modification Information
+ *
+ * --------------------------------------------------------------------------
+ *
+ */
+
+#include "lim_sta_hash_api.h"
+
+/**
+ * lim_get_sta_hash_bssidx()
+ *
+ ***FUNCTION:
+ * This function is called to Get the Bss Index of the currently associated Station.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac  pointer to Global Mac structure.
+ * @param assocId AssocID of the Station.
+ * @param bssidx pointer to the bss index, which will be returned by the function.
+ *
+ * @return success if GET operation is ok, else Failure.
+ */
+
+QDF_STATUS lim_get_sta_hash_bssidx(tpAniSirGlobal pMac, uint16_t assocId,
+				      uint8_t *bssidx, tpPESession psessionEntry)
+{
+	tpDphHashNode pSta =
+		dph_get_hash_entry(pMac, assocId, &psessionEntry->dph.dphHashTable);
+
+	if (pSta == NULL) {
+		pe_err("invalid STA: %d", assocId);
+		return QDF_STATUS_E_NOENT;
+	}
+
+	*bssidx = (uint8_t) pSta->bssId;
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/core/mac/src/pe/lim/lim_sta_hash_api.h b/core/mac/src/pe/lim/lim_sta_hash_api.h
new file mode 100644
index 0000000..ad02da7
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_sta_hash_api.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011-2012, 2014, 2018 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.
+ */
+
+/*
+ *
+ * This file lim_sta_hash_api.h contains the
+ * function prototypes for accessing station hash entry fields.
+ *
+ * Author:      Sunit Bhatia
+ * Date:        09/19/2006
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __LIM_STA_HASH_API_H__
+#define __LIM_STA_HASH_API_H__
+
+#include "ani_global.h"
+#include "lim_types.h"
+
+QDF_STATUS lim_get_sta_hash_bssidx(tpAniSirGlobal pMac, uint16_t assocId,
+				      uint8_t *bssidx, tpPESession psessionEntry);
+
+#endif
diff --git a/core/mac/src/pe/lim/lim_timer_utils.c b/core/mac/src/pe/lim/lim_timer_utils.c
new file mode 100644
index 0000000..da72943
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_timer_utils.c
@@ -0,0 +1,1028 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * This file lim_timer_utils.cc contains the utility functions
+ * LIM uses for handling various timers.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "wlan_mlme_public_struct.h"
+#include <lim_api.h>
+
+/* channel Switch Timer in ticks */
+#define LIM_CHANNEL_SWITCH_TIMER_TICKS           1
+/* Lim Quite timer in ticks */
+#define LIM_QUIET_TIMER_TICKS                    100
+/* Lim Quite BSS timer interval in ticks */
+#define LIM_QUIET_BSS_TIMER_TICK                 100
+/* Lim KeepAlive timer default (3000)ms */
+#define LIM_KEEPALIVE_TIMER_MS                   3000
+/* Lim JoinProbeRequest Retry  timer default (200)ms */
+#define LIM_JOIN_PROBE_REQ_TIMER_MS              200
+/* Lim Periodic Auth Retry timer default 60 ms */
+#define LIM_AUTH_RETRY_TIMER_MS   60
+
+/*
+ * SAE auth timer of 5secs. This is required for duration of entire SAE
+ * authentication.
+ */
+#define LIM_AUTH_SAE_TIMER_MS 5000
+
+
+/* This timer is a periodic timer which expires at every 1 sec to
+   convert  ACTIVE DFS channel to DFS channels */
+#define ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT     1000
+
+static bool lim_create_non_ap_timers(tpAniSirGlobal pMac)
+{
+	uint32_t cfgValue;
+	/* Create Channel Switch Timer */
+	if (tx_timer_create(pMac, &pMac->lim.limTimers.gLimChannelSwitchTimer,
+			    "CHANNEL SWITCH TIMER",
+			    lim_channel_switch_timer_handler, 0,
+			    LIM_CHANNEL_SWITCH_TIMER_TICKS,
+			    0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("failed to create Ch Switch timer");
+		return false;
+	}
+	/* Create Quiet Timer
+	 * This is used on the STA to go and shut-off Tx/Rx "after" the
+	 * specified quiteInterval
+	 */
+	if (tx_timer_create(pMac, &pMac->lim.limTimers.gLimQuietTimer,
+			    "QUIET TIMER", lim_quiet_timer_handler,
+			    SIR_LIM_QUIET_TIMEOUT, LIM_QUIET_TIMER_TICKS,
+			    0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("failed to create Quiet Begin Timer");
+		return false;
+	}
+	/* Create Quiet BSS Timer
+	 * After the specified quiteInterval, determined by gLimQuietTimer, this
+	 * timer, gLimQuietBssTimer, trigger and put the STA to sleep for the
+	 * specified gLimQuietDuration
+	 */
+	if (tx_timer_create(pMac, &pMac->lim.limTimers.gLimQuietBssTimer,
+			    "QUIET BSS TIMER", lim_quiet_bss_timer_handler,
+			    SIR_LIM_QUIET_BSS_TIMEOUT, LIM_QUIET_BSS_TIMER_TICK,
+			    0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("failed to create Quiet Bss Timer");
+		return false;
+	}
+
+	cfgValue = SYS_MS_TO_TICKS(
+			pMac->mlme_cfg->timeouts.join_failure_timeout);
+	/* Create Join failure timer and activate it later */
+	if (tx_timer_create(pMac, &pMac->lim.limTimers.gLimJoinFailureTimer,
+			    "JOIN FAILURE TIMEOUT",
+			    lim_timer_handler, SIR_LIM_JOIN_FAIL_TIMEOUT,
+			    cfgValue, 0,
+			    TX_NO_ACTIVATE) != TX_SUCCESS) {
+		/* / Could not create Join failure timer. */
+		/* Log error */
+		pe_err("could not create Join failure timer");
+		return false;
+	}
+	/* Send unicast probe req frame every 200 ms */
+	if (tx_timer_create(pMac,
+			    &pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer,
+			    "Periodic Join Probe Request Timer",
+			    lim_timer_handler,
+			    SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT,
+			    SYS_MS_TO_TICKS(LIM_JOIN_PROBE_REQ_TIMER_MS), 0,
+			    TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("could not create Periodic Join Probe Request tmr");
+		return false;
+	}
+
+	/* Send Auth frame every 60 ms */
+	if ((tx_timer_create(pMac,
+		&pMac->lim.limTimers.g_lim_periodic_auth_retry_timer,
+		"Periodic AUTH Timer",
+		lim_timer_handler, SIR_LIM_AUTH_RETRY_TIMEOUT,
+		SYS_MS_TO_TICKS(LIM_AUTH_RETRY_TIMER_MS), 0,
+		TX_NO_ACTIVATE)) != TX_SUCCESS) {
+		pe_err("could not create Periodic AUTH Timer");
+		return false;
+	}
+
+	cfgValue = SYS_MS_TO_TICKS(
+			pMac->mlme_cfg->timeouts.assoc_failure_timeout);
+	/* Create Association failure timer and activate it later */
+	if (tx_timer_create(pMac, &pMac->lim.limTimers.gLimAssocFailureTimer,
+			    "ASSOC FAILURE TIMEOUT",
+			    lim_assoc_failure_timer_handler, LIM_ASSOC,
+			    cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("could not create Association failure timer");
+		return false;
+	}
+
+	cfgValue = SYS_MS_TO_TICKS(pMac->mlme_cfg->timeouts.addts_rsp_timeout);
+
+	/* Create Addts response timer and activate it later */
+	if (tx_timer_create(pMac, &pMac->lim.limTimers.gLimAddtsRspTimer,
+			    "ADDTS RSP TIMEOUT",
+			    lim_addts_response_timer_handler,
+			    SIR_LIM_ADDTS_RSP_TIMEOUT,
+			    cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("could not create Addts response timer");
+		return false;
+	}
+
+	cfgValue = SYS_MS_TO_TICKS(
+			pMac->mlme_cfg->timeouts.auth_failure_timeout);
+	/* Create Auth failure timer and activate it later */
+	if (tx_timer_create(pMac, &pMac->lim.limTimers.gLimAuthFailureTimer,
+			    "AUTH FAILURE TIMEOUT",
+			    lim_timer_handler,
+			    SIR_LIM_AUTH_FAIL_TIMEOUT,
+			    cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("could not create Auth failure timer");
+		return false;
+	}
+
+	/* Change timer to reactivate it in future */
+	cfgValue = SYS_MS_TO_TICKS(
+		pMac->mlme_cfg->timeouts.probe_after_hb_fail_timeout);
+	if (tx_timer_create(pMac, &pMac->lim.limTimers.gLimProbeAfterHBTimer,
+			    "Probe after Heartbeat TIMEOUT",
+			    lim_timer_handler,
+			    SIR_LIM_PROBE_HB_FAILURE_TIMEOUT,
+			    cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("unable to create ProbeAfterHBTimer");
+		return false;
+	}
+
+	/*
+	 * SAE auth timer of 5secs. This is required for duration of entire SAE
+	 * authentication.
+	 */
+	if ((tx_timer_create(pMac,
+		&pMac->lim.limTimers.sae_auth_timer,
+		"SAE AUTH Timer",
+		lim_timer_handler, SIR_LIM_AUTH_SAE_TIMEOUT,
+		SYS_MS_TO_TICKS(LIM_AUTH_SAE_TIMER_MS), 0,
+		TX_NO_ACTIVATE)) != TX_SUCCESS) {
+		pe_err("could not create SAE AUTH Timer");
+		return false;
+	}
+
+	return true;
+}
+/**
+ * lim_create_timers()
+ *
+ * @pMac : Pointer to Global MAC structure
+ *
+ * This function is called upon receiving
+ * 1. SME_START_REQ for STA in ESS role
+ * 2. SME_START_BSS_REQ for AP role & STA in IBSS role
+ *
+ * @return : status of operation
+ */
+
+uint32_t lim_create_timers(tpAniSirGlobal pMac)
+{
+	uint32_t cfgValue, i = 0;
+
+	pe_debug("Creating Timers used by LIM module in Role: %d",
+	       pMac->lim.gLimSystemRole);
+	/* Create timers required for host roaming feature */
+	if (TX_SUCCESS != lim_create_timers_host_roam(pMac))
+		return TX_TIMER_ERROR;
+
+	if (pMac->lim.gLimSystemRole != eLIM_AP_ROLE)
+		if (false == lim_create_non_ap_timers(pMac))
+			goto err_timer;
+
+	cfgValue = pMac->mlme_cfg->sta.wait_cnf_timeout;
+	cfgValue = SYS_MS_TO_TICKS(cfgValue);
+	for (i = 0; i < (pMac->lim.maxStation + 1); i++) {
+		if (tx_timer_create(pMac,
+				    &pMac->lim.limTimers.gpLimCnfWaitTimer[i],
+				    "CNF_MISS_TIMEOUT",
+				    lim_cnf_wait_tmer_handler,
+				    (uint32_t) i, cfgValue,
+				    0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+			pe_err("Cannot create CNF wait timer");
+			goto err_timer;
+		}
+	}
+
+	/* Alloc and init table for the preAuth timer list */
+	cfgValue = pMac->mlme_cfg->lfr.max_num_pre_auth;
+	pMac->lim.gLimPreAuthTimerTable.numEntry = cfgValue;
+	pMac->lim.gLimPreAuthTimerTable.pTable =
+		qdf_mem_malloc(cfgValue * sizeof(tLimPreAuthNode *));
+
+	if (!pMac->lim.gLimPreAuthTimerTable.pTable)
+		goto err_timer;
+
+	for (i = 0; i < cfgValue; i++) {
+		pMac->lim.gLimPreAuthTimerTable.pTable[i] =
+					qdf_mem_malloc(sizeof(tLimPreAuthNode));
+		if (pMac->lim.gLimPreAuthTimerTable.pTable[i] == NULL) {
+			pMac->lim.gLimPreAuthTimerTable.numEntry = 0;
+			goto err_timer;
+		}
+	}
+
+	lim_init_pre_auth_timer_table(pMac, &pMac->lim.gLimPreAuthTimerTable);
+	pe_debug("alloc and init table for preAuth timers");
+
+	cfgValue = SYS_MS_TO_TICKS(
+			pMac->mlme_cfg->timeouts.olbc_detect_timeout);
+	if (tx_timer_create(pMac, &pMac->lim.limTimers.gLimUpdateOlbcCacheTimer,
+			    "OLBC UPDATE CACHE TIMEOUT",
+			    lim_update_olbc_cache_timer_handler,
+			    SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT, cfgValue,
+			    cfgValue, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("Cannot create update OLBC cache tmr");
+		goto err_timer;
+	}
+
+	cfgValue = 1000;
+	cfgValue = SYS_MS_TO_TICKS(cfgValue);
+	if (tx_timer_create(pMac, &pMac->lim.limTimers.gLimDisassocAckTimer,
+			    "DISASSOC ACK TIMEOUT",
+			    lim_timer_handler, SIR_LIM_DISASSOC_ACK_TIMEOUT,
+			    cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("could not DISASSOC ACK TIMEOUT timer");
+		goto err_timer;
+	}
+
+	cfgValue = 1000;
+	cfgValue = SYS_MS_TO_TICKS(cfgValue);
+	if (tx_timer_create(pMac, &pMac->lim.limTimers.gLimDeauthAckTimer,
+			    "DISASSOC ACK TIMEOUT",
+			    lim_timer_handler, SIR_LIM_DEAUTH_ACK_TIMEOUT,
+			    cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_err("could not create DEAUTH ACK TIMEOUT timer");
+		goto err_timer;
+	}
+
+	cfgValue = ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT;
+	cfgValue = SYS_MS_TO_TICKS(cfgValue);
+	if (tx_timer_create(pMac,
+		&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer,
+		"ACTIVE TO PASSIVE CHANNEL", lim_timer_handler,
+		SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE, cfgValue, 0,
+		TX_NO_ACTIVATE) != TX_SUCCESS) {
+		pe_warn("could not create timer for passive channel to active channel");
+		goto err_timer;
+	}
+
+	return TX_SUCCESS;
+
+err_timer:
+	lim_delete_timers_host_roam(pMac);
+	tx_timer_delete(&pMac->lim.limTimers.gLimDeauthAckTimer);
+	tx_timer_delete(&pMac->lim.limTimers.gLimDisassocAckTimer);
+	tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer);
+	while (((int32_t)-- i) >= 0) {
+		tx_timer_delete(&pMac->lim.limTimers.gpLimCnfWaitTimer[i]);
+	}
+	tx_timer_delete(&pMac->lim.limTimers.gLimProbeAfterHBTimer);
+	tx_timer_delete(&pMac->lim.limTimers.gLimAuthFailureTimer);
+	tx_timer_delete(&pMac->lim.limTimers.gLimAddtsRspTimer);
+	tx_timer_delete(&pMac->lim.limTimers.gLimAssocFailureTimer);
+	tx_timer_delete(&pMac->lim.limTimers.gLimJoinFailureTimer);
+	tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer);
+	tx_timer_delete(&pMac->lim.limTimers.g_lim_periodic_auth_retry_timer);
+	tx_timer_delete(&pMac->lim.limTimers.gLimQuietBssTimer);
+	tx_timer_delete(&pMac->lim.limTimers.gLimQuietTimer);
+	tx_timer_delete(&pMac->lim.limTimers.gLimChannelSwitchTimer);
+	tx_timer_delete(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer);
+	tx_timer_delete(&pMac->lim.limTimers.sae_auth_timer);
+
+	if (NULL != pMac->lim.gLimPreAuthTimerTable.pTable) {
+		for (i = 0; i < pMac->lim.gLimPreAuthTimerTable.numEntry; i++)
+			qdf_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable[i]);
+		qdf_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable);
+		pMac->lim.gLimPreAuthTimerTable.pTable = NULL;
+	}
+	return TX_TIMER_ERROR;
+} /****** end lim_create_timers() ******/
+
+/**
+ * lim_timer_handler()
+ *
+ ***FUNCTION:
+ * This function is called upon
+ * 1. MIN_CHANNEL, MAX_CHANNEL timer expiration during scanning
+ * 2. JOIN_FAILURE timer expiration while joining a BSS
+ * 3. AUTH_FAILURE timer expiration while authenticating with a peer
+ * 4. Heartbeat timer expiration on STA
+ * 5. Background scan timer expiration on STA
+ * 6. AID release, Pre-auth cleanup and Link monitoring timer
+ *    expiration on AP
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  param - Message corresponding to the timer that expired
+ *
+ * @return None
+ */
+
+void lim_timer_handler(void *pMacGlobal, uint32_t param)
+{
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+	/* Prepare and post message to LIM Message Queue */
+
+	msg.type = (uint16_t) param;
+	msg.bodyptr = NULL;
+	msg.bodyval = 0;
+
+	status = lim_post_msg_high_priority(pMac, &msg);
+	if (status != QDF_STATUS_SUCCESS)
+		pe_err("posting message: %X to LIM failed, reason: %d",
+			msg.type, status);
+} /****** end lim_timer_handler() ******/
+
+/**
+ * lim_addts_response_timer_handler()
+ *
+ ***FUNCTION:
+ * This function is called upon Addts response timer expiration on sta
+ *
+ ***LOGIC:
+ * Message SIR_LIM_ADDTS_RSP_TIMEOUT is posted to gSirLimMsgQ
+ * when this function is executed.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  param - pointer to pre-auth node
+ *
+ * @return None
+ */
+
+void lim_addts_response_timer_handler(void *pMacGlobal, uint32_t param)
+{
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+	/* Prepare and post message to LIM Message Queue */
+
+	msg.type = SIR_LIM_ADDTS_RSP_TIMEOUT;
+	msg.bodyval = param;
+	msg.bodyptr = NULL;
+
+	lim_post_msg_api(pMac, &msg);
+} /****** end lim_auth_response_timer_handler() ******/
+
+/**
+ * lim_auth_response_timer_handler()
+ *
+ ***FUNCTION:
+ * This function is called upon Auth response timer expiration on AP
+ *
+ ***LOGIC:
+ * Message SIR_LIM_AUTH_RSP_TIMEOUT is posted to gSirLimMsgQ
+ * when this function is executed.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  param - pointer to pre-auth node
+ *
+ * @return None
+ */
+
+void lim_auth_response_timer_handler(void *pMacGlobal, uint32_t param)
+{
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+	/* Prepare and post message to LIM Message Queue */
+
+	msg.type = SIR_LIM_AUTH_RSP_TIMEOUT;
+	msg.bodyptr = NULL;
+	msg.bodyval = (uint32_t) param;
+
+	lim_post_msg_api(pMac, &msg);
+} /****** end lim_auth_response_timer_handler() ******/
+
+/**
+ * lim_assoc_failure_timer_handler()
+ *
+ * @mac_global  : Pointer to Global MAC structure
+ * @param       : Indicates whether this is assoc or reassoc failure timeout
+ *
+ * This function is called upon Re/Assoc failure timer expiration on STA.
+ * Message SIR_LIM_ASSOC_FAIL_TIMEOUT is posted to gSirLimMsgQ when this
+ * function is executed.
+ *
+ * Return void
+ */
+void lim_assoc_failure_timer_handler(void *mac_global, uint32_t param)
+{
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal mac_ctx = (tpAniSirGlobal) mac_global;
+	tpPESession session = NULL;
+
+	session = mac_ctx->lim.pSessionEntry;
+	if (LIM_REASSOC == param && NULL != session
+	    && session->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE) {
+		pe_err("Reassoc timeout happened");
+		if (mac_ctx->lim.reAssocRetryAttempt <
+		    LIM_MAX_REASSOC_RETRY_LIMIT) {
+			lim_send_retry_reassoc_req_frame(mac_ctx,
+			    session->pLimMlmReassocRetryReq, session);
+			mac_ctx->lim.reAssocRetryAttempt++;
+			pe_warn("Reassoc request retry is sent %d times",
+				mac_ctx->lim.reAssocRetryAttempt);
+			return;
+		} else {
+			pe_warn("Reassoc request retry MAX: %d reached",
+				LIM_MAX_REASSOC_RETRY_LIMIT);
+			if (NULL != session->pLimMlmReassocRetryReq) {
+				qdf_mem_free(session->pLimMlmReassocRetryReq);
+				session->pLimMlmReassocRetryReq = NULL;
+			}
+		}
+	}
+	/* Prepare and post message to LIM Message Queue */
+	msg.type = SIR_LIM_ASSOC_FAIL_TIMEOUT;
+	msg.bodyval = (uint32_t) param;
+	msg.bodyptr = NULL;
+	lim_post_msg_api(mac_ctx, &msg);
+} /****** end lim_assoc_failure_timer_handler() ******/
+
+/**
+ * lim_update_olbc_cache_timer_handler()
+ *
+ ***FUNCTION:
+ * This function is called upon update olbc cache timer expiration
+ * on STA
+ *
+ ***LOGIC:
+ * Message SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT is posted to gSirLimMsgQ
+ * when this function is executed.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param
+ *
+ * @return None
+ */
+void lim_update_olbc_cache_timer_handler(void *pMacGlobal, uint32_t param)
+{
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+	/* Prepare and post message to LIM Message Queue */
+
+	msg.type = SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT;
+	msg.bodyval = 0;
+	msg.bodyptr = NULL;
+
+	lim_post_msg_api(pMac, &msg);
+} /****** end lim_update_olbc_cache_timer_handler() ******/
+
+/**
+ * lim_deactivate_and_change_timer()
+ *
+ ***FUNCTION:
+ * This function is called to deactivate and change a timer
+ * for future re-activation
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ * @param  timerId - enum of timer to be deactivated and changed
+ *                   This enum is defined in lim_utils.h file
+ *
+ * @return None
+ */
+
+void lim_deactivate_and_change_timer(tpAniSirGlobal pMac, uint32_t timerId)
+{
+	uint32_t val = 0;
+	tpPESession  session_entry;
+
+	switch (timerId) {
+	case eLIM_REASSOC_FAIL_TIMER:
+	case eLIM_FT_PREAUTH_RSP_TIMER:
+		lim_deactivate_and_change_timer_host_roam(pMac, timerId);
+		break;
+
+	case eLIM_ADDTS_RSP_TIMER:
+		pMac->lim.gLimAddtsRspTimerCount++;
+		if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer)
+		    != TX_SUCCESS) {
+			/* Could not deactivate AddtsRsp Timer */
+			/* Log error */
+			pe_err("Unable to deactivate AddtsRsp timer");
+		}
+		break;
+
+	case eLIM_JOIN_FAIL_TIMER:
+		if (tx_timer_deactivate
+			    (&pMac->lim.limTimers.gLimJoinFailureTimer)
+		    != TX_SUCCESS) {
+			/**
+			 * Could not deactivate Join Failure
+			 * timer. Log error.
+			 */
+			pe_err("Unable to deactivate Join Failure timer");
+		}
+
+		val = SYS_MS_TO_TICKS(
+				pMac->mlme_cfg->timeouts.join_failure_timeout);
+
+		if (tx_timer_change(&pMac->lim.limTimers.gLimJoinFailureTimer,
+				    val, 0) != TX_SUCCESS) {
+			/**
+			 * Could not change Join Failure
+			 * timer. Log error.
+			 */
+			pe_err("Unable to change Join Failure timer");
+		}
+
+		break;
+
+	case eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER:
+		if (tx_timer_deactivate
+			    (&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer)
+		    != TX_SUCCESS) {
+			/* Could not deactivate periodic join req Times. */
+			pe_err("Unable to deactivate periodic join request timer");
+		}
+
+		val = SYS_MS_TO_TICKS(LIM_JOIN_PROBE_REQ_TIMER_MS);
+		if (tx_timer_change
+			    (&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer, val,
+			    0) != TX_SUCCESS) {
+			/* Could not change periodic join req times. */
+			/* Log error */
+			pe_err("Unable to change periodic join request timer");
+		}
+
+		break;
+
+	case eLIM_AUTH_FAIL_TIMER:
+		if (tx_timer_deactivate
+			    (&pMac->lim.limTimers.gLimAuthFailureTimer)
+		    != TX_SUCCESS) {
+			/* Could not deactivate Auth failure timer. */
+			/* Log error */
+			pe_err("Unable to deactivate auth failure timer");
+		}
+		/* Change timer to reactivate it in future */
+		val = SYS_MS_TO_TICKS(
+				pMac->mlme_cfg->timeouts.auth_failure_timeout);
+
+		if (tx_timer_change(&pMac->lim.limTimers.gLimAuthFailureTimer,
+				    val, 0) != TX_SUCCESS) {
+			/* Could not change Authentication failure timer. */
+			/* Log error */
+			pe_err("unable to change Auth failure timer");
+		}
+
+		break;
+
+	case eLIM_AUTH_RETRY_TIMER:
+
+		if (tx_timer_deactivate
+			  (&pMac->lim.limTimers.g_lim_periodic_auth_retry_timer)
+							 != TX_SUCCESS) {
+			/* Could not deactivate Auth Retry Timer. */
+			pe_err("Unable to deactivate Auth Retry timer");
+		}
+		session_entry = pe_find_session_by_session_id(pMac,
+			pMac->lim.limTimers.
+				g_lim_periodic_auth_retry_timer.sessionId);
+		if (NULL == session_entry) {
+			pe_err("session does not exist for given SessionId : %d",
+			pMac->lim.limTimers.
+				g_lim_periodic_auth_retry_timer.sessionId);
+			break;
+		}
+		/* 3/5 of the beacon interval */
+		val = (session_entry->beaconParams.beaconInterval * 3) / 5;
+		val = SYS_MS_TO_TICKS(val);
+		if (tx_timer_change
+			 (&pMac->lim.limTimers.g_lim_periodic_auth_retry_timer,
+							val, 0) != TX_SUCCESS) {
+			/* Could not change Auth Retry timer. */
+			pe_err("Unable to change Auth Retry timer");
+		}
+		break;
+
+	case eLIM_ASSOC_FAIL_TIMER:
+		if (tx_timer_deactivate
+			    (&pMac->lim.limTimers.gLimAssocFailureTimer) !=
+		    TX_SUCCESS) {
+			/* Could not deactivate Association failure timer. */
+			/* Log error */
+			pe_err("unable to deactivate Association failure timer");
+		}
+		/* Change timer to reactivate it in future */
+		val = SYS_MS_TO_TICKS(
+				pMac->mlme_cfg->timeouts.assoc_failure_timeout);
+
+		if (tx_timer_change(&pMac->lim.limTimers.gLimAssocFailureTimer,
+				    val, 0) != TX_SUCCESS) {
+			/* Could not change Association failure timer. */
+			/* Log error */
+			pe_err("unable to change Assoc failure timer");
+		}
+
+		break;
+
+	case eLIM_PROBE_AFTER_HB_TIMER:
+		if (tx_timer_deactivate
+			    (&pMac->lim.limTimers.gLimProbeAfterHBTimer) !=
+		    TX_SUCCESS) {
+			/* Could not deactivate Heartbeat timer. */
+			/* Log error */
+			pe_err("unable to deactivate probeAfterHBTimer");
+		} else {
+			pe_debug("Deactivated probe after hb timer");
+		}
+
+		/* Change timer to reactivate it in future */
+		val = SYS_MS_TO_TICKS(
+			pMac->mlme_cfg->timeouts.probe_after_hb_fail_timeout);
+
+		if (tx_timer_change(&pMac->lim.limTimers.gLimProbeAfterHBTimer,
+				    val, 0) != TX_SUCCESS) {
+			/* Could not change HeartBeat timer. */
+			/* Log error */
+			pe_err("unable to change ProbeAfterHBTimer");
+		} else {
+			pe_debug("Probe after HB timer value is changed: %u",
+				val);
+		}
+
+		break;
+
+	case eLIM_LEARN_DURATION_TIMER:
+		break;
+
+	case eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
+		if (tx_timer_deactivate
+			    (&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer) !=
+		    TX_SUCCESS) {
+			/**
+			** Could not deactivate Active to passive channel timer.
+			** Log error.
+			**/
+			pe_err("Unable to Deactivate Active to passive channel timer");
+			return;
+		}
+		val = ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT;
+		val = SYS_MS_TO_TICKS(val);
+		if (tx_timer_change
+			    (&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer, val,
+			    0) != TX_SUCCESS) {
+			/**
+			 * Could not change timer to check scan type for passive channel.
+			 * timer. Log error.
+			 */
+			pe_err("Unable to change timer");
+			return;
+		}
+		break;
+
+	case eLIM_DISASSOC_ACK_TIMER:
+		if (tx_timer_deactivate
+			    (&pMac->lim.limTimers.gLimDisassocAckTimer) != TX_SUCCESS) {
+			/**
+			** Could not deactivate Join Failure
+			** timer. Log error.
+			**/
+			pe_err("Unable to deactivate Disassoc ack timer");
+			return;
+		}
+		val = 1000;
+		val = SYS_MS_TO_TICKS(val);
+		if (tx_timer_change(&pMac->lim.limTimers.gLimDisassocAckTimer,
+				    val, 0) != TX_SUCCESS) {
+			/**
+			 * Could not change Join Failure
+			 * timer. Log error.
+			 */
+			pe_err("Unable to change timer");
+			return;
+		}
+		break;
+
+	case eLIM_DEAUTH_ACK_TIMER:
+		if (tx_timer_deactivate(&pMac->lim.limTimers.gLimDeauthAckTimer)
+		    != TX_SUCCESS) {
+			/**
+			** Could not deactivate Join Failure
+			** timer. Log error.
+			**/
+			pe_err("Unable to deactivate Deauth ack timer");
+			return;
+		}
+		val = 1000;
+		val = SYS_MS_TO_TICKS(val);
+		if (tx_timer_change(&pMac->lim.limTimers.gLimDeauthAckTimer,
+				    val, 0) != TX_SUCCESS) {
+			/**
+			 * Could not change Join Failure
+			 * timer. Log error.
+			 */
+			pe_err("Unable to change timer");
+			return;
+		}
+		break;
+
+	case eLIM_AUTH_SAE_TIMER:
+		if (tx_timer_deactivate
+		   (&pMac->lim.limTimers.sae_auth_timer)
+		    != TX_SUCCESS)
+			pe_err("Unable to deactivate SAE auth timer");
+
+		/* Change timer to reactivate it in future */
+		val = SYS_MS_TO_TICKS(LIM_AUTH_SAE_TIMER_MS);
+
+		if (tx_timer_change(&pMac->lim.limTimers.sae_auth_timer,
+				    val, 0) != TX_SUCCESS)
+			pe_err("unable to change SAE auth timer");
+
+		break;
+
+	default:
+		/* Invalid timerId. Log error */
+		break;
+	}
+} /****** end lim_deactivate_and_change_timer() ******/
+
+/**
+ * lim_deactivate_and_change_per_sta_id_timer()
+ *
+ *
+ * @brief: This function is called to deactivate and change a per STA timer
+ * for future re-activation
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ * @note   staId for eLIM_AUTH_RSP_TIMER is auth Node Index.
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ * @param  timerId - enum of timer to be deactivated and changed
+ *                   This enum is defined in lim_utils.h file
+ * @param  staId   - staId
+ *
+ * @return None
+ */
+
+void
+lim_deactivate_and_change_per_sta_id_timer(tpAniSirGlobal pMac, uint32_t timerId,
+					   uint16_t staId)
+{
+	uint32_t val;
+
+	switch (timerId) {
+	case eLIM_CNF_WAIT_TIMER:
+
+		if (tx_timer_deactivate
+			    (&pMac->lim.limTimers.gpLimCnfWaitTimer[staId])
+		    != TX_SUCCESS) {
+			pe_err("unable to deactivate CNF wait timer");
+		}
+		/* Change timer to reactivate it in future */
+		val = pMac->mlme_cfg->sta.wait_cnf_timeout;
+		val = SYS_MS_TO_TICKS(val);
+
+		if (tx_timer_change
+			    (&pMac->lim.limTimers.gpLimCnfWaitTimer[staId], val,
+			    val) != TX_SUCCESS) {
+			/* Could not change cnf timer. */
+			/* Log error */
+			pe_err("unable to change cnf wait timer");
+		}
+
+		break;
+
+	case eLIM_AUTH_RSP_TIMER:
+	{
+		tLimPreAuthNode *pAuthNode;
+
+		pAuthNode =
+			lim_get_pre_auth_node_from_index(pMac,
+							 &pMac->lim.
+							 gLimPreAuthTimerTable,
+							 staId);
+
+		if (pAuthNode == NULL) {
+			pe_err("Invalid Pre Auth Index passed :%d",
+				staId);
+			break;
+		}
+
+		if (tx_timer_deactivate(&pAuthNode->timer) !=
+		    TX_SUCCESS) {
+			/* Could not deactivate auth response timer. */
+			/* Log error */
+			pe_err("unable to deactivate auth response timer");
+		}
+		/* Change timer to reactivate it in future */
+		val = SYS_MS_TO_TICKS(
+				pMac->mlme_cfg->timeouts.auth_rsp_timeout);
+
+		if (tx_timer_change(&pAuthNode->timer, val, 0) !=
+		    TX_SUCCESS) {
+			/* Could not change auth rsp timer. */
+			/* Log error */
+			pe_err("unable to change auth rsp timer");
+		}
+	}
+	break;
+
+	default:
+		/* Invalid timerId. Log error */
+		break;
+
+	}
+}
+
+/**
+ * lim_activate_cnf_timer()
+ *
+ ***FUNCTION:
+ * This function is called to activate a per STA timer
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ * @param  StaId   - staId
+ *
+ * @return None
+ */
+
+void lim_activate_cnf_timer(tpAniSirGlobal pMac, uint16_t staId,
+			    tpPESession psessionEntry)
+{
+	pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId =
+		psessionEntry->peSessionId;
+	if (tx_timer_activate(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId])
+	    != TX_SUCCESS) {
+		pe_err("could not activate cnf wait timer");
+	}
+}
+
+/**
+ * lim_activate_auth_rsp_timer()
+ *
+ ***FUNCTION:
+ * This function is called to activate a per STA timer
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ * @param  id      - id
+ *
+ * @return None
+ */
+
+void lim_activate_auth_rsp_timer(tpAniSirGlobal pMac, tLimPreAuthNode *pAuthNode)
+{
+	if (tx_timer_activate(&pAuthNode->timer) != TX_SUCCESS) {
+		/* / Could not activate auth rsp timer. */
+		/* Log error */
+		pe_err("could not activate auth rsp timer");
+	}
+}
+
+/**
+ * limAssocCnfWaitTmerHandler()
+ *
+ ***FUNCTION:
+ *        This function post a message to send a disassociate frame out.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param
+ *
+ * @return None
+ */
+
+void lim_cnf_wait_tmer_handler(void *pMacGlobal, uint32_t param)
+{
+	struct scheduler_msg msg = {0};
+	uint32_t statusCode;
+	tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+	msg.type = SIR_LIM_CNF_WAIT_TIMEOUT;
+	msg.bodyval = (uint32_t) param;
+	msg.bodyptr = NULL;
+
+	statusCode = lim_post_msg_api(pMac, &msg);
+	if (statusCode != QDF_STATUS_SUCCESS)
+		pe_err("posting to LIM failed, reason: %d", statusCode);
+
+}
+
+void lim_channel_switch_timer_handler(void *pMacGlobal, uint32_t param)
+{
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+	pe_debug("ChannelSwitch Timer expired.  Posting msg to LIM");
+
+	msg.type = SIR_LIM_CHANNEL_SWITCH_TIMEOUT;
+	msg.bodyval = (uint32_t) param;
+	msg.bodyptr = NULL;
+
+	lim_post_msg_api(pMac, &msg);
+}
+
+void lim_quiet_timer_handler(void *pMacGlobal, uint32_t param)
+{
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+	msg.type = SIR_LIM_QUIET_TIMEOUT;
+	msg.bodyval = (uint32_t) param;
+	msg.bodyptr = NULL;
+
+	pe_debug("Post SIR_LIM_QUIET_TIMEOUT msg");
+	lim_post_msg_api(pMac, &msg);
+}
+
+void lim_quiet_bss_timer_handler(void *pMacGlobal, uint32_t param)
+{
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+	msg.type = SIR_LIM_QUIET_BSS_TIMEOUT;
+	msg.bodyval = (uint32_t) param;
+	msg.bodyptr = NULL;
+	pe_debug("Post SIR_LIM_QUIET_BSS_TIMEOUT msg");
+	lim_post_msg_api(pMac, &msg);
+}
+
diff --git a/core/mac/src/pe/lim/lim_timer_utils.h b/core/mac/src/pe/lim/lim_timer_utils.h
new file mode 100644
index 0000000..f6afa72
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_timer_utils.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2011-2014, 2016-2018 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.
+ */
+
+/*
+ *
+ * This file lim_timer_utils.h contains the utility definitions
+ * LIM uses for timer handling.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_TIMER_UTILS_H
+#define __LIM_TIMER_UTILS_H
+
+#include "lim_types.h"
+
+/* Timer related functions */
+enum {
+	eLIM_MIN_CHANNEL_TIMER,
+	eLIM_MAX_CHANNEL_TIMER,
+	eLIM_JOIN_FAIL_TIMER,
+	eLIM_AUTH_FAIL_TIMER,
+	eLIM_AUTH_RESP_TIMER,
+	eLIM_ASSOC_FAIL_TIMER,
+	eLIM_REASSOC_FAIL_TIMER,
+	eLIM_PRE_AUTH_CLEANUP_TIMER,
+	eLIM_CNF_WAIT_TIMER,
+	eLIM_AUTH_RSP_TIMER,
+	eLIM_UPDATE_OLBC_CACHE_TIMER,
+	eLIM_PROBE_AFTER_HB_TIMER,
+	eLIM_ADDTS_RSP_TIMER,
+	eLIM_CHANNEL_SWITCH_TIMER,
+	eLIM_LEARN_DURATION_TIMER,
+	eLIM_QUIET_TIMER,
+	eLIM_QUIET_BSS_TIMER,
+	eLIM_WPS_OVERLAP_TIMER,
+	eLIM_FT_PREAUTH_RSP_TIMER,
+	eLIM_REMAIN_CHN_TIMER,
+	eLIM_DISASSOC_ACK_TIMER,
+	eLIM_DEAUTH_ACK_TIMER,
+	eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER,
+	eLIM_INSERT_SINGLESHOT_NOA_TIMER,
+	eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE,
+	eLIM_AUTH_RETRY_TIMER,
+	eLIM_AUTH_SAE_TIMER
+};
+
+#define LIM_DISASSOC_DEAUTH_ACK_TIMEOUT         500
+
+/* Timer Handler functions */
+uint32_t lim_create_timers(tpAniSirGlobal);
+void lim_timer_handler(void *, uint32_t);
+void lim_auth_response_timer_handler(void *, uint32_t);
+void lim_assoc_failure_timer_handler(void *, uint32_t);
+void limReassocFailureTimerHandler(void *, uint32_t);
+
+void lim_deactivate_and_change_timer(tpAniSirGlobal, uint32_t);
+void limDummyPktExpTimerHandler(void *, uint32_t);
+void lim_cnf_wait_tmer_handler(void *, uint32_t);
+void lim_deactivate_and_change_per_sta_id_timer(tpAniSirGlobal, uint32_t, uint16_t);
+void lim_activate_cnf_timer(tpAniSirGlobal, uint16_t, tpPESession);
+void lim_activate_auth_rsp_timer(tpAniSirGlobal, tLimPreAuthNode *);
+void lim_update_olbc_cache_timer_handler(void *, uint32_t);
+void lim_addts_response_timer_handler(void *, uint32_t);
+void lim_channel_switch_timer_handler(void *, uint32_t);
+void lim_quiet_timer_handler(void *, uint32_t);
+void lim_quiet_bss_timer_handler(void *, uint32_t);
+void limCBScanIntervalTimerHandler(void *, uint32_t);
+void limCBScanDurationTimerHandler(void *, uint32_t);
+#endif /* __LIM_TIMER_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_trace.c b/core/mac/src/pe/lim/lim_trace.c
new file mode 100644
index 0000000..5ddc39c
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_trace.c
@@ -0,0 +1,462 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/**=========================================================================
+
+   \file  lim_trace.c
+
+   \brief implementation for trace related APIs
+
+   \author Sunit Bhatia
+
+   ========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+
+#include "ani_global.h"          /* for tpAniSirGlobal */
+
+#include "lim_trace.h"
+#include "lim_timer_utils.h"
+#include "qdf_trace.h"
+
+#ifdef LIM_TRACE_RECORD
+uint32_t g_mgmt_frame_stats[14];
+
+#define LIM_TRACE_MAX_SUBTYPES 14
+
+static uint8_t *__lim_trace_get_timer_string(uint16_t timerId)
+{
+	switch (timerId) {
+		CASE_RETURN_STRING(eLIM_MIN_CHANNEL_TIMER);
+		CASE_RETURN_STRING(eLIM_MAX_CHANNEL_TIMER);
+		CASE_RETURN_STRING(eLIM_JOIN_FAIL_TIMER);
+		CASE_RETURN_STRING(eLIM_AUTH_FAIL_TIMER);
+		CASE_RETURN_STRING(eLIM_AUTH_RESP_TIMER);
+		CASE_RETURN_STRING(eLIM_ASSOC_FAIL_TIMER);
+		CASE_RETURN_STRING(eLIM_REASSOC_FAIL_TIMER);
+		CASE_RETURN_STRING(eLIM_PRE_AUTH_CLEANUP_TIMER);
+		CASE_RETURN_STRING(eLIM_CNF_WAIT_TIMER);
+		CASE_RETURN_STRING(eLIM_AUTH_RSP_TIMER);
+		CASE_RETURN_STRING(eLIM_UPDATE_OLBC_CACHE_TIMER);
+		CASE_RETURN_STRING(eLIM_PROBE_AFTER_HB_TIMER);
+		CASE_RETURN_STRING(eLIM_ADDTS_RSP_TIMER);
+		CASE_RETURN_STRING(eLIM_CHANNEL_SWITCH_TIMER);
+		CASE_RETURN_STRING(eLIM_LEARN_DURATION_TIMER);
+		CASE_RETURN_STRING(eLIM_QUIET_TIMER);
+		CASE_RETURN_STRING(eLIM_QUIET_BSS_TIMER);
+		CASE_RETURN_STRING(eLIM_WPS_OVERLAP_TIMER);
+		CASE_RETURN_STRING(eLIM_FT_PREAUTH_RSP_TIMER);
+		CASE_RETURN_STRING(eLIM_REMAIN_CHN_TIMER);
+		CASE_RETURN_STRING(eLIM_DISASSOC_ACK_TIMER);
+		CASE_RETURN_STRING(eLIM_DEAUTH_ACK_TIMER);
+		CASE_RETURN_STRING(eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
+		CASE_RETURN_STRING(eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE);
+		CASE_RETURN_STRING(eLIM_AUTH_RETRY_TIMER);
+	default:
+		return "UNKNOWN";
+		break;
+	}
+}
+
+static uint8_t *__lim_trace_get_mgmt_drop_reason_string(uint16_t dropReason)
+{
+
+	switch (dropReason) {
+		CASE_RETURN_STRING(eMGMT_DROP_INFRA_BCN_IN_IBSS);
+		CASE_RETURN_STRING(eMGMT_DROP_INVALID_SIZE);
+		CASE_RETURN_STRING(eMGMT_DROP_NON_SCAN_MODE_FRAME);
+		CASE_RETURN_STRING(eMGMT_DROP_NOT_LAST_IBSS_BCN);
+		CASE_RETURN_STRING(eMGMT_DROP_NO_DROP);
+		CASE_RETURN_STRING(eMGMT_DROP_SCAN_MODE_FRAME);
+		CASE_RETURN_STRING(eMGMT_DROP_SPURIOUS_FRAME);
+
+	default:
+		return "UNKNOWN";
+		break;
+	}
+}
+
+void lim_trace_init(tpAniSirGlobal pMac)
+{
+	qdf_trace_register(QDF_MODULE_ID_PE, &lim_trace_dump);
+}
+
+void lim_trace_dump(void *pMac, tp_qdf_trace_record pRecord,
+		    uint16_t recIndex)
+{
+	static char *frameSubtypeStr[LIM_TRACE_MAX_SUBTYPES] = {
+		"Association request",
+		"Association response",
+		"Reassociation request",
+		"Reassociation response",
+		"Probe request",
+		"Probe response",
+		NULL,
+		NULL,
+		"Beacon",
+		"ATIM",
+		"Disassociation",
+		"Authentication",
+		"Deauthentication",
+		"Action"
+	};
+
+	switch (pRecord->code) {
+	case TRACE_CODE_MLM_STATE:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			"MLM State:",
+			lim_trace_get_mlm_state_string(
+						(uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+	case TRACE_CODE_SME_STATE:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			"SME State:",
+			lim_trace_get_sme_state_string(
+						(uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+	case TRACE_CODE_TX_MGMT:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			"TX Mgmt:", frameSubtypeStr[pRecord->data],
+			pRecord->data);
+		break;
+
+	case TRACE_CODE_RX_MGMT:
+		if (LIM_TRACE_MAX_SUBTYPES <=
+		    LIM_TRACE_GET_SUBTYPE(pRecord->data))
+			pe_debug("Wrong Subtype - %d",
+				LIM_TRACE_GET_SUBTYPE(pRecord->data));
+		else
+			pe_debug("%04d %012llu %s S%d %-14s %-30s(%d) SN: %d",
+				recIndex, pRecord->qtime, pRecord->time,
+				pRecord->session, "RX Mgmt:",
+				frameSubtypeStr[LIM_TRACE_GET_SUBTYPE
+							(pRecord->data)],
+				LIM_TRACE_GET_SUBTYPE(pRecord->data),
+				LIM_TRACE_GET_SSN(pRecord->data));
+		break;
+	case TRACE_CODE_RX_MGMT_DROP:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(%d)",
+			recIndex, pRecord->qtime, pRecord->time,
+			pRecord->session, "Drop RX Mgmt:",
+			__lim_trace_get_mgmt_drop_reason_string(
+					(uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+
+	case TRACE_CODE_RX_MGMT_TSF:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s0x%x(%d)",
+			recIndex, pRecord->qtime, pRecord->time,
+			pRecord->session, "RX Mgmt TSF:", " ",
+			pRecord->data, pRecord->data);
+		break;
+
+	case TRACE_CODE_TX_COMPLETE:
+		pe_debug("%04d %012llu %s S%d %-14s %d", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			"TX Complete", pRecord->data);
+		break;
+
+	case TRACE_CODE_TX_SME_MSG:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			"TX SME Msg:",
+			mac_trace_get_sme_msg_string((uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+	case TRACE_CODE_RX_SME_MSG:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			LIM_TRACE_GET_DEFRD_OR_DROPPED(
+			pRecord->data) ? "Def/Drp LIM Msg:" : "RX Sme Msg:",
+			mac_trace_get_sme_msg_string((uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+
+	case TRACE_CODE_TX_WMA_MSG:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			"TX WMA Msg:",
+			mac_trace_get_wma_msg_string((uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+
+	case TRACE_CODE_RX_WMA_MSG:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			LIM_TRACE_GET_DEFRD_OR_DROPPED(
+			pRecord->data) ? "Def/Drp LIM Msg:" : "RX WMA Msg:",
+			mac_trace_get_wma_msg_string((uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+
+	case TRACE_CODE_TX_LIM_MSG:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			"TX LIM Msg:",
+			mac_trace_get_lim_msg_string((uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+	case TRACE_CODE_RX_LIM_MSG:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			LIM_TRACE_GET_DEFRD_OR_DROPPED(
+			pRecord->data) ? "Def/Drp LIM Msg:" : "RX LIM Msg",
+			mac_trace_get_lim_msg_string((uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+	case TRACE_CODE_TX_CFG_MSG:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x) ", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			"TX CFG Msg:",
+			mac_trace_get_cfg_msg_string((uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+	case TRACE_CODE_RX_CFG_MSG:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x) ", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			LIM_TRACE_GET_DEFRD_OR_DROPPED(
+			pRecord->data) ? "Def/Drp LIM Msg:" : "RX CFG Msg:",
+			mac_trace_get_cfg_msg_string(
+				(uint16_t)MAC_TRACE_GET_MSG_ID(pRecord->data)),
+			pRecord->data);
+		break;
+
+	case TRACE_CODE_TIMER_ACTIVATE:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			"Timer Actvtd",
+			__lim_trace_get_timer_string((uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+	case TRACE_CODE_TIMER_DEACTIVATE:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex,
+			pRecord->qtime, pRecord->time, pRecord->session,
+			"Timer DeActvtd",
+			__lim_trace_get_timer_string((uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+
+	case TRACE_CODE_INFO_LOG:
+		pe_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)",
+			recIndex, pRecord->qtime, pRecord->time,
+			pRecord->session, "INFORMATION_LOG",
+			mac_trace_get_info_log_string((uint16_t) pRecord->data),
+			pRecord->data);
+		break;
+	default:
+		pe_debug("%04d %012llu %s S%d %-14s(%d) (0x%x)",
+			recIndex, pRecord->qtime, pRecord->time,
+			pRecord->session, "Unknown Code",
+			pRecord->code, pRecord->data);
+		break;
+	}
+}
+
+void mac_trace_msg_tx(tpAniSirGlobal pMac, uint8_t session, uint32_t data)
+{
+
+	uint16_t msgId = (uint16_t) MAC_TRACE_GET_MSG_ID(data);
+	uint8_t module_id = (uint8_t) MAC_TRACE_GET_MODULE_ID(data);
+
+	switch (module_id) {
+	case SIR_LIM_MODULE_ID:
+		if (msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+			mac_trace(pMac, TRACE_CODE_TX_LIM_MSG, session, data);
+		else
+			mac_trace(pMac, TRACE_CODE_TX_SME_MSG, session, data);
+		break;
+	case SIR_WMA_MODULE_ID:
+		mac_trace(pMac, TRACE_CODE_TX_WMA_MSG, session, data);
+		break;
+	case SIR_CFG_MODULE_ID:
+		mac_trace(pMac, TRACE_CODE_TX_CFG_MSG, session, data);
+		break;
+	default:
+		mac_trace(pMac, module_id, session, data);
+		break;
+	}
+}
+
+void mac_trace_msg_tx_new(tpAniSirGlobal pMac, uint8_t module, uint8_t session,
+			  uint32_t data)
+{
+	uint16_t msgId = (uint16_t) MAC_TRACE_GET_MSG_ID(data);
+	uint8_t module_id = (uint8_t) MAC_TRACE_GET_MODULE_ID(data);
+
+	switch (module_id) {
+	case SIR_LIM_MODULE_ID:
+		if (msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+			mac_trace_new(pMac, module, TRACE_CODE_TX_LIM_MSG,
+				      session, data);
+		else
+			mac_trace_new(pMac, module, TRACE_CODE_TX_SME_MSG,
+				      session, data);
+		break;
+	case SIR_WMA_MODULE_ID:
+		mac_trace_new(pMac, module, TRACE_CODE_TX_WMA_MSG, session, data);
+		break;
+	case SIR_CFG_MODULE_ID:
+		mac_trace_new(pMac, module, TRACE_CODE_TX_CFG_MSG, session, data);
+		break;
+	default:
+		mac_trace(pMac, module_id, session, data);
+		break;
+	}
+}
+
+/*
+ * bit31: Rx message deferred or not
+ * bit 0-15: message ID:
+ */
+void mac_trace_msg_rx(tpAniSirGlobal pMac, uint8_t session, uint32_t data)
+{
+	uint16_t msgId = (uint16_t) MAC_TRACE_GET_MSG_ID(data);
+	uint8_t module_id = (uint8_t) MAC_TRACE_GET_MODULE_ID(data);
+
+	switch (module_id) {
+	case SIR_LIM_MODULE_ID:
+		if (msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+			mac_trace(pMac, TRACE_CODE_RX_LIM_MSG, session, data);
+		else
+			mac_trace(pMac, TRACE_CODE_RX_SME_MSG, session, data);
+		break;
+	case SIR_WMA_MODULE_ID:
+		mac_trace(pMac, TRACE_CODE_RX_WMA_MSG, session, data);
+		break;
+	case SIR_CFG_MODULE_ID:
+		mac_trace(pMac, TRACE_CODE_RX_CFG_MSG, session, data);
+		break;
+	default:
+		mac_trace(pMac, module_id, session, data);
+		break;
+	}
+}
+
+/*
+ * bit31: Rx message deferred or not
+ * bit 0-15: message ID:
+ */
+void mac_trace_msg_rx_new(tpAniSirGlobal pMac, uint8_t module, uint8_t session,
+			  uint32_t data)
+{
+	uint16_t msgId = (uint16_t) MAC_TRACE_GET_MSG_ID(data);
+	uint8_t module_id = (uint8_t) MAC_TRACE_GET_MODULE_ID(data);
+
+	switch (module_id) {
+	case SIR_LIM_MODULE_ID:
+		if (msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+			mac_trace_new(pMac, module, TRACE_CODE_RX_LIM_MSG,
+				      session, data);
+		else
+			mac_trace_new(pMac, module, TRACE_CODE_RX_SME_MSG,
+				      session, data);
+		break;
+	case SIR_WMA_MODULE_ID:
+		mac_trace_new(pMac, module, TRACE_CODE_RX_WMA_MSG, session, data);
+		break;
+	case SIR_CFG_MODULE_ID:
+		mac_trace_new(pMac, module, TRACE_CODE_RX_CFG_MSG, session, data);
+		break;
+	default:
+		mac_trace(pMac, module_id, session, data);
+		break;
+	}
+}
+
+uint8_t *lim_trace_get_mlm_state_string(uint32_t mlmState)
+{
+	switch (mlmState) {
+		CASE_RETURN_STRING(eLIM_MLM_OFFLINE_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_IDLE_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_PROBE_RESP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_PASSIVE_SCAN_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_JOIN_BEACON_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_JOINED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_BSS_STARTED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME2_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME3_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME4_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_AUTH_RSP_TIMEOUT_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_AUTHENTICATED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_REASSOC_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_ASSOCIATED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_REASSOCIATED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_LINK_ESTABLISHED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_CNF_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_LEARN_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_DEL_BSS_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ADD_STA_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_DEL_STA_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_SET_BSS_KEY_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_SET_STA_KEY_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_SET_STA_BCASTKEY_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_SET_MIMOPS_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_FT_REASSOC_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_P2P_LISTEN_STATE);
+	default:
+		return "UNKNOWN";
+		break;
+	}
+}
+
+uint8_t *lim_trace_get_sme_state_string(uint32_t smeState)
+{
+	switch (smeState) {
+
+		CASE_RETURN_STRING(eLIM_SME_OFFLINE_STATE);
+		CASE_RETURN_STRING(eLIM_SME_IDLE_STATE);
+		CASE_RETURN_STRING(eLIM_SME_SUSPEND_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_SCAN_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_JOIN_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_AUTH_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_ASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_SME_JOIN_FAILURE_STATE);
+		CASE_RETURN_STRING(eLIM_SME_ASSOCIATED_STATE);
+		CASE_RETURN_STRING(eLIM_SME_REASSOCIATED_STATE);
+		CASE_RETURN_STRING(eLIM_SME_LINK_EST_STATE);
+		CASE_RETURN_STRING(eLIM_SME_LINK_EST_WT_SCAN_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_PRE_AUTH_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_DISASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_DEAUTH_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_START_BSS_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_STOP_BSS_STATE);
+		CASE_RETURN_STRING(eLIM_SME_NORMAL_STATE);
+		CASE_RETURN_STRING(eLIM_SME_CHANNEL_SCAN_STATE);
+		CASE_RETURN_STRING(eLIM_SME_NORMAL_CHANNEL_SCAN_STATE);
+	default:
+		return "UNKNOWN";
+		break;
+	}
+}
+
+#endif
diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h
new file mode 100644
index 0000000..308cf00
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_types.h
@@ -0,0 +1,1177 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file lim_types.h contains the definitions used by all
+ * all LIM modules.
+ * Author:        Chandra Modumudi
+ * Date:          02/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_TYPES_H
+#define __LIM_TYPES_H
+
+#include "wni_api.h"
+#include "sir_api.h"
+#include "sir_common.h"
+#include "sir_mac_prot_def.h"
+#include "utils_api.h"
+
+#include "lim_api.h"
+#include "lim_trace.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "sys_global.h"
+#include "dph_global.h"
+#include "parser_api.h"
+#include "wma_if.h"
+
+#define LINK_TEST_DEFER 1
+
+#define TRACE_EVENT_CNF_TIMER_DEACT        0x6600
+#define TRACE_EVENT_CNF_TIMER_ACT          0x6601
+#define TRACE_EVENT_AUTH_RSP_TIMER_DEACT   0x6602
+#define TRACE_EVENT_AUTH_RSP_TIMER_ACT     0x6603
+
+/* MLM message types */
+#define LIM_MLM_MSG_START           1000
+#define LIM_MLM_SCAN_REQ            LIM_MLM_MSG_START
+#define LIM_MLM_SCAN_CNF            (LIM_MLM_MSG_START + 1)
+#define LIM_MLM_START_CNF           (LIM_MLM_MSG_START + 3)
+#define LIM_MLM_JOIN_REQ            (LIM_MLM_MSG_START + 4)
+#define LIM_MLM_JOIN_CNF            (LIM_MLM_MSG_START + 5)
+#define LIM_MLM_AUTH_REQ            (LIM_MLM_MSG_START + 6)
+#define LIM_MLM_AUTH_CNF            (LIM_MLM_MSG_START + 7)
+#define LIM_MLM_AUTH_IND            (LIM_MLM_MSG_START + 8)
+#define LIM_MLM_ASSOC_REQ           (LIM_MLM_MSG_START + 9)
+#define LIM_MLM_ASSOC_CNF           (LIM_MLM_MSG_START + 10)
+#define LIM_MLM_ASSOC_IND           (LIM_MLM_MSG_START + 11)
+#define LIM_MLM_DISASSOC_REQ        (LIM_MLM_MSG_START + 12)
+#define LIM_MLM_DISASSOC_CNF        (LIM_MLM_MSG_START + 13)
+#define LIM_MLM_DISASSOC_IND        (LIM_MLM_MSG_START + 14)
+#define LIM_MLM_REASSOC_REQ         (LIM_MLM_MSG_START + 15)
+#define LIM_MLM_REASSOC_CNF         (LIM_MLM_MSG_START + 16)
+#define LIM_MLM_REASSOC_IND         (LIM_MLM_MSG_START + 17)
+#define LIM_MLM_DEAUTH_REQ          (LIM_MLM_MSG_START + 18)
+#define LIM_MLM_DEAUTH_CNF          (LIM_MLM_MSG_START + 19)
+#define LIM_MLM_DEAUTH_IND          (LIM_MLM_MSG_START + 20)
+#define LIM_MLM_TSPEC_REQ           (LIM_MLM_MSG_START + 21)
+#define LIM_MLM_TSPEC_CNF           (LIM_MLM_MSG_START + 22)
+#define LIM_MLM_TSPEC_IND           (LIM_MLM_MSG_START + 23)
+#define LIM_MLM_SETKEYS_REQ         (LIM_MLM_MSG_START + 24)
+#define LIM_MLM_SETKEYS_CNF         (LIM_MLM_MSG_START + 25)
+#define LIM_MLM_LINK_TEST_STOP_REQ  (LIM_MLM_MSG_START + 30)
+#define LIM_MLM_PURGE_STA_IND       (LIM_MLM_MSG_START + 31)
+/*
+ * Values (LIM_MLM_MSG_START + 32) through
+ * (LIM_MLM_MSG_START + 40) are unused.
+ */
+
+#define LIM_HASH_ADD            0
+#define LIM_HASH_UPDATE         1
+
+#define LIM_WEP_IN_FC           1
+#define LIM_NO_WEP_IN_FC        0
+
+#define LIM_DECRYPT_ICV_FAIL    1
+
+/* / Definitions to distinquish between Association/Reassociaton */
+#define LIM_ASSOC    0
+#define LIM_REASSOC  1
+
+/* / Minimum Memory blocks require for different scenario */
+#define LIM_MIN_MEM_ASSOC       4
+
+/* / Verifies whether given mac addr matches the CURRENT Bssid */
+#define IS_CURRENT_BSSID(pMac, addr, psessionEntry)  (!qdf_mem_cmp(addr, \
+								      psessionEntry->bssId, \
+								      sizeof(psessionEntry->bssId)))
+/* / Verifies whether given addr matches the REASSOC Bssid */
+#define IS_REASSOC_BSSID(pMac, addr, psessionEntry)  (!qdf_mem_cmp(addr, \
+								      psessionEntry->limReAssocbssId, \
+								      sizeof(psessionEntry->limReAssocbssId)))
+
+#define REQ_TYPE_REGISTRAR                   (0x2)
+#define REQ_TYPE_WLAN_MANAGER_REGISTRAR      (0x3)
+
+#define RESP_TYPE_REGISTRAR                  (0x2)
+#define RESP_TYPE_ENROLLEE_INFO_ONLY         (0x0)
+#define RESP_TYPE_ENROLLEE_OPEN_8021X        (0x1)
+#define RESP_TYPE_AP                         (0x3)
+#define LIM_TX_FRAMES_THRESHOLD_ON_CHIP       300
+
+
+#define HAL_TXCOMP_REQUESTED_MASK           0x1 /* bit 0 for TxComp intr requested. */
+#define HAL_USE_SELF_STA_REQUESTED_MASK     0x2 /* bit 1 for STA overwrite with selfSta Requested. */
+#define HAL_TX_NO_ENCRYPTION_MASK           0x4 /* bit 2. If set, the frame is not to be encrypted */
+#if defined(LIBRA_WAPI_SUPPORT)
+#define HAL_WAPI_STA_MASK            0x8        /* bit 3. If set, this frame is for WAPI station */
+#endif
+
+#define HAL_TRIGGER_ENABLED_AC_MASK         0x10        /* bit 4 for data frames belonging to trigger enabled AC */
+#define HAL_USE_NO_ACK_REQUESTED_MASK       0x20
+
+#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40      /* Bit 6 will be used to control BD rate for Management frames */
+#define HAL_USE_PEER_STA_REQUESTED_MASK   0x80  /* bit 7 will be used to control frames for p2p interface */
+
+#ifdef FEATURE_WLAN_TDLS
+#define HAL_TDLS_PEER_STA_MASK              0x80        /* bit 7 set for TDLS peer station */
+#endif
+
+#define LIM_DOS_PROTECTION_TIME 1000 //1000ms
+
+/* enums used by LIM are as follows */
+
+enum eLimDisassocTrigger {
+	eLIM_HOST_DISASSOC,
+	eLIM_PEER_ENTITY_DISASSOC,
+	eLIM_LINK_MONITORING_DISASSOC,
+	eLIM_PROMISCUOUS_MODE_DISASSOC,
+	eLIM_HOST_DEAUTH,
+	eLIM_PEER_ENTITY_DEAUTH,
+	eLIM_LINK_MONITORING_DEAUTH,
+	eLIM_JOIN_FAILURE,
+	eLIM_REASSOC_REJECT,
+	eLIM_DUPLICATE_ENTRY
+};
+
+/* Reason code to determine the channel change context while sending
+ * WMA_CHNL_SWITCH_REQ message to HAL
+ */
+enum eChannelChangeReasonCodes {
+	LIM_SWITCH_CHANNEL_REASSOC,
+	LIM_SWITCH_CHANNEL_JOIN,
+	LIM_SWITCH_CHANNEL_OPERATION,   /* Generic change channel */
+	LIM_SWITCH_CHANNEL_SAP_DFS,     /* DFS channel change */
+};
+
+typedef struct sLimAuthRspTimeout {
+	tSirMacAddr peerMacAddr;
+} tLimAuthRspTimeout;
+
+typedef struct sLimMlmStartReq {
+	tSirMacSSid ssId;
+	tSirBssType bssType;
+	tSirMacAddr bssId;
+	tSirMacBeaconInterval beaconPeriod;
+	uint8_t dtimPeriod;
+	tSirMacCfParamSet cfParamSet;
+	tSirMacChanNum channelNumber;
+	ePhyChanBondState cbMode;
+	uint16_t atimWindow;
+	tSirMacRateSet rateSet;
+	uint8_t sessionId;      /* Added For BT-AMP Support */
+
+	/* Parameters reqd for new HAL (message) interface */
+	tSirNwType nwType;
+	uint8_t htCapable;
+	tSirMacHTOperatingMode htOperMode;
+	uint8_t dualCTSProtection;
+	uint8_t txChannelWidthSet;
+	uint8_t ssidHidden;
+	uint8_t wps_state;
+	uint8_t obssProtEnabled;
+	uint16_t beacon_tx_rate;
+	uint32_t cac_duration_ms;
+	uint32_t dfs_regdomain;
+} tLimMlmStartReq, *tpLimMlmStartReq;
+
+typedef struct sLimMlmStartCnf {
+	tSirResultCodes resultCode;
+	uint8_t sessionId;
+} tLimMlmStartCnf, *tpLimMlmStartCnf;
+
+typedef struct sLimMlmScanCnf {
+	tSirResultCodes resultCode;
+	uint16_t scanResultLength;
+	uint8_t sessionId;
+	tSirBssDescription bssDescription[1];
+	/*
+	 * WARNING: Pls make bssDescription as last variable in struct
+	 * tLimMlmScanCnf as it has ieFields followed after this bss
+	 * description. Adding a variable after this corrupts the ieFields
+	 */
+} tLimMlmScanCnf, *tpLimMlmScanCnf;
+
+typedef struct sLimScanResult {
+	uint16_t numBssDescriptions;
+	tSirBssDescription bssDescription[1];
+} tLimScanResult;
+
+typedef struct sLimMlmJoinCnf {
+	tSirResultCodes resultCode;
+	uint16_t protStatusCode;
+	uint8_t sessionId;
+} tLimMlmJoinCnf, *tpLimMlmJoinCnf;
+
+typedef struct sLimMlmAssocReq {
+	tSirMacAddr peerMacAddr;
+	uint16_t capabilityInfo;
+	tSirMacListenInterval listenInterval;
+	uint8_t sessionId;
+} tLimMlmAssocReq, *tpLimMlmAssocReq;
+
+typedef struct sLimMlmAssocCnf {
+	tSirResultCodes resultCode;     /* Internal status code. */
+	uint16_t protStatusCode;        /* Protocol Status code. */
+	uint8_t sessionId;
+} tLimMlmAssocCnf, *tpLimMlmAssocCnf;
+
+typedef struct sLimMlmAssocInd {
+	tSirMacAddr peerMacAddr;
+	uint16_t aid;
+	tAniAuthType authType;
+	tAniSSID ssId;
+	tSirRSNie rsnIE;
+	tSirWAPIie wapiIE;
+	tSirAddie addIE;        /* additional IE received from the peer, which possibly includes WSC IE and/or P2P IE. */
+	tSirMacCapabilityInfo capabilityInfo;
+	bool spectrumMgtIndicator;
+	tSirMacPowerCapInfo powerCap;
+	tSirSupChnl supportedChannels;
+	uint8_t sessionId;
+
+	bool WmmStaInfoPresent;
+
+	/* Required for indicating the frames to upper layer */
+	uint32_t beaconLength;
+	uint8_t *beaconPtr;
+	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;
+	uint8_t ecsa_capable;
+
+	tDot11fIEHTCaps ht_caps;
+	tDot11fIEVHTCaps vht_caps;
+} tLimMlmAssocInd, *tpLimMlmAssocInd;
+
+typedef struct sLimMlmReassocReq {
+	tSirMacAddr peerMacAddr;
+	uint16_t capabilityInfo;
+	tSirMacListenInterval listenInterval;
+	uint8_t sessionId;
+} tLimMlmReassocReq, *tpLimMlmReassocReq;
+
+typedef struct sLimMlmReassocCnf {
+	tSirResultCodes resultCode;
+	uint16_t protStatusCode;        /* Protocol Status code. */
+	uint8_t sessionId;
+} tLimMlmReassocCnf, *tpLimMlmReassocCnf;
+
+typedef struct sLimMlmReassocInd {
+	tSirMacAddr peerMacAddr;
+	tSirMacAddr currentApAddr;
+	uint16_t aid;
+	tAniAuthType authType;
+	tAniSSID ssId;
+	tSirRSNie rsnIE;
+	tSirWAPIie wapiIE;
+	tSirAddie addIE;        /* additional IE received from the peer, which can be WSC IE and/or P2P IE. */
+	tSirMacCapabilityInfo capabilityInfo;
+	bool spectrumMgtIndicator;
+	tSirMacPowerCapInfo powerCap;
+	tSirSupChnl supportedChannels;
+
+	bool WmmStaInfoPresent;
+
+	/* Required for indicating the frames to upper layer */
+	uint32_t beaconLength;
+	uint8_t *beaconPtr;
+	uint32_t assocReqLength;
+	uint8_t *assocReqPtr;
+	uint8_t ecsa_capable;
+} tLimMlmReassocInd, *tpLimMlmReassocInd;
+
+typedef struct sLimMlmAuthCnf {
+	tSirMacAddr peerMacAddr;
+	tAniAuthType authType;
+	tSirResultCodes resultCode;
+	uint16_t protStatusCode;
+	uint8_t sessionId;
+} tLimMlmAuthCnf, *tpLimMlmAuthCnf;
+
+typedef struct sLimMlmDeauthReq {
+	struct qdf_mac_addr peer_macaddr;
+	uint16_t reasonCode;
+	uint16_t deauthTrigger;
+	uint16_t aid;
+	uint8_t sessionId;      /* Added for BT-AMP SUPPORT */
+
+} tLimMlmDeauthReq, *tpLimMlmDeauthReq;
+
+typedef struct sLimMlmDeauthCnf {
+	struct qdf_mac_addr peer_macaddr;
+	tSirResultCodes resultCode;
+	uint16_t deauthTrigger;
+	uint16_t aid;
+	uint8_t sessionId;
+} tLimMlmDeauthCnf, *tpLimMLmDeauthCnf;
+
+typedef struct sLimMlmDeauthInd {
+	tSirMacAddr peerMacAddr;
+	uint16_t reasonCode;
+	uint16_t deauthTrigger;
+	uint16_t aid;
+} tLimMlmDeauthInd, *tpLimMlmDeauthInd;
+
+typedef struct sLimMlmDisassocReq {
+	struct qdf_mac_addr peer_macaddr;
+	uint16_t reasonCode;
+	uint16_t disassocTrigger;
+	uint16_t aid;
+	uint8_t sessionId;
+} tLimMlmDisassocReq, *tpLimMlmDisassocReq;
+
+typedef struct sLimMlmDisassocCnf {
+	tSirMacAddr peerMacAddr;
+	tSirResultCodes resultCode;
+	uint16_t disassocTrigger;
+	uint16_t aid;
+	uint8_t sessionId;
+} tLimMlmDisassocCnf, *tpLimMlmDisassocCnf;
+
+typedef struct sLimMlmDisassocInd {
+	tSirMacAddr peerMacAddr;
+	uint16_t reasonCode;
+	uint16_t disassocTrigger;
+	uint16_t aid;
+	uint8_t sessionId;
+} tLimMlmDisassocInd, *tpLimMlmDisassocInd;
+
+typedef struct sLimMlmPurgeStaReq {
+	tSirMacAddr peerMacAddr;
+	uint16_t aid;
+	uint8_t sessionId;      /* Added For BT-AMP Support */
+} tLimMlmPurgeStaReq, *tpLimMlmPurgeStaReq;
+
+typedef struct sLimMlmPurgeStaInd {
+	tSirMacAddr peerMacAddr;
+	uint16_t reasonCode;
+	uint16_t purgeTrigger;
+	uint16_t aid;
+	uint8_t sessionId;
+} tLimMlmPurgeStaInd, *tpLimMlmPurgeStaInd;
+
+/**
+ * struct sLimMlmSetKeysCnf - set key confirmation parameters
+ * @peer_macaddr: peer mac address
+ * @resultCode: Result of set key operation
+ * @aid: association id
+ * @sessionId: PE session id
+ * @key_len_nonzero: Keys are non-zero length
+ */
+typedef struct sLimMlmSetKeysCnf {
+	struct qdf_mac_addr peer_macaddr;
+	uint16_t resultCode;
+	uint16_t aid;
+	uint8_t sessionId;
+	bool key_len_nonzero;
+} tLimMlmSetKeysCnf, *tpLimMlmSetKeysCnf;
+
+typedef struct sLimMlmResetReq {
+	tSirMacAddr macAddr;
+	uint8_t performCleanup;
+	uint8_t sessionId;
+} tLimMlmResetReq, *tpLimMlmResetReq;
+
+typedef struct sLimMlmResetCnf {
+	tSirMacAddr macAddr;
+	tSirResultCodes resultCode;
+	uint8_t sessionId;
+} tLimMlmResetCnf, *tpLimMlmResetCnf;
+
+typedef struct sLimMlmLinkTestStopReq {
+	tSirMacAddr peerMacAddr;
+	uint8_t sessionId;
+} tLimMlmLinkTestStopReq, *tpLimMlmLinkTestStopReq;
+
+/* Function templates */
+
+bool lim_process_sme_req_messages(tpAniSirGlobal, struct scheduler_msg *);
+void lim_process_mlm_req_messages(tpAniSirGlobal, struct scheduler_msg *);
+void lim_process_mlm_rsp_messages(tpAniSirGlobal, uint32_t, uint32_t *);
+void lim_process_sme_del_bss_rsp(tpAniSirGlobal, uint32_t, tpPESession);
+
+/**
+ * lim_process_mlm_start_cnf(): called to processes MLM_START_CNF message from
+ * MLM State machine.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: A pointer to the MLM message buffer
+ *
+ * Return: None
+ */
+void lim_process_mlm_start_cnf(tpAniSirGlobal mac_ctx, uint32_t *msg_buf);
+
+void lim_get_random_bssid(tpAniSirGlobal pMac, uint8_t *data);
+
+/* Function to handle HT and HT IE CFG parameter intializations */
+void handle_ht_capabilityand_ht_info(struct mac_context *pMac,
+				     tpPESession psessionEntry);
+
+void lim_handle_param_update(tpAniSirGlobal pMac, eUpdateIEsType cfgId);
+
+/* Function to apply CFG parameters before join/reassoc/start BSS */
+void lim_apply_configuration(tpAniSirGlobal, tpPESession);
+
+/**
+ * lim_set_cfg_protection() - sets lim global cfg cache from the config
+ * @pMac: global mac context
+ * @pesessionEntry: PE session
+ *
+ * Return none
+ */
+void lim_set_cfg_protection(tpAniSirGlobal pMac, tpPESession pesessionEntry);
+
+/* Function to Initialize MLM state machine on STA */
+QDF_STATUS lim_init_mlm(tpAniSirGlobal);
+
+/* Function to cleanup MLM state machine */
+void lim_cleanup_mlm(tpAniSirGlobal);
+
+/* Management frame handling functions */
+void lim_process_beacon_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+void lim_process_probe_req_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+void lim_process_probe_rsp_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+void lim_process_probe_req_frame_multiple_bss(tpAniSirGlobal, uint8_t *,
+					      tpPESession);
+
+/* Process Auth frame when we have a session in progress. */
+void lim_process_auth_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+QDF_STATUS lim_process_auth_frame_no_session(tpAniSirGlobal pMac, uint8_t *,
+						void *body);
+
+void lim_process_assoc_req_frame(tpAniSirGlobal, uint8_t *, uint8_t, tpPESession);
+void lim_send_mlm_assoc_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+			    tpPESession psessionEntry);
+
+void lim_process_assoc_rsp_frame(tpAniSirGlobal, uint8_t *, uint8_t, tpPESession);
+void lim_process_disassoc_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+/*
+ * lim_perform_disassoc() - Actual action taken after receiving disassoc
+ * @mac_ctx: Global MAC context
+ * @frame_rssi: RSSI of the frame
+ * @rc: Reason code of the deauth
+ * @pe_session: PE session entry pointer
+ * @addr: BSSID from which the disassoc is received
+ *
+ * Return: None
+ */
+void lim_perform_disassoc(tpAniSirGlobal mac_ctx, int32_t frame_rssi,
+			  uint16_t rc, tpPESession pe_session,
+			  tSirMacAddr addr);
+/*
+ * lim_disassoc_tdls_peers() - Disassoc action for tdls peers
+ * @mac_ctx: Global MAC context
+ * @pe_session: PE session entry pointer
+ * @addr: BSSID from which the disassoc is received
+ *
+ * Return: None
+ */
+#ifdef FEATURE_WLAN_TDLS
+void lim_disassoc_tdls_peers(tpAniSirGlobal mac_ctx,
+				    tpPESession pe_session, tSirMacAddr addr);
+#else
+static inline void lim_disassoc_tdls_peers(tpAniSirGlobal mac_ctx,
+				    tpPESession pe_session, tSirMacAddr addr)
+{
+}
+#endif
+void lim_process_deauth_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+/*
+ * lim_perform_deauth() - Actual action taken after receiving deauth
+ * @mac_ctx: Global MAC context
+ * @pe_session: PE session entry pointer
+ * @rc: Reason code of the deauth
+ * @addr: BSSID from which the deauth is received
+ * @frame_rssi: RSSI of the frame
+ *
+ * Return: None
+ */
+void lim_perform_deauth(tpAniSirGlobal mac_ctx, tpPESession pe_session,
+			uint16_t rc, tSirMacAddr addr, int32_t frame_rssi);
+void lim_process_action_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+void lim_process_action_frame_no_session(tpAniSirGlobal pMac, uint8_t *pRxMetaInfo);
+
+void lim_populate_p2p_mac_header(tpAniSirGlobal, uint8_t *);
+void lim_populate_mac_header(tpAniSirGlobal, uint8_t *, uint8_t, uint8_t,
+				      tSirMacAddr, tSirMacAddr);
+QDF_STATUS lim_send_probe_req_mgmt_frame(tpAniSirGlobal, tSirMacSSid *,
+					    tSirMacAddr, uint8_t, tSirMacAddr,
+					    uint32_t, uint16_t *, uint8_t *);
+void lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal, tSirMacAddr, tpAniSSID, short,
+				   uint8_t, tpPESession, uint8_t);
+void lim_send_auth_mgmt_frame(tpAniSirGlobal, tSirMacAuthFrameBody *, tSirMacAddr,
+			      uint8_t, tpPESession);
+void lim_send_assoc_req_mgmt_frame(tpAniSirGlobal, tLimMlmAssocReq *, tpPESession);
+#ifdef WLAN_FEATURE_HOST_ROAM
+void lim_send_reassoc_req_with_ft_ies_mgmt_frame(tpAniSirGlobal pMac,
+		tLimMlmReassocReq *pMlmReassocReq, tpPESession psessionEntry);
+void lim_send_reassoc_req_mgmt_frame(tpAniSirGlobal, tLimMlmReassocReq *,
+				     tpPESession);
+/**
+ * lim_process_rx_scan_handler() -
+ *	process the event for scan which is issued by LIM
+ * @vdev: wlan objmgr vdev pointer
+ * @event: scan event
+ * @arg: global mac context pointer
+ *
+ * Return: void
+ */
+void lim_process_rx_scan_handler(struct wlan_objmgr_vdev *vdev,
+				 struct scan_event *event, void *arg);
+#else
+static inline void lim_send_reassoc_req_with_ft_ies_mgmt_frame(
+		tpAniSirGlobal pMac, tLimMlmReassocReq *pMlmReassocReq,
+		tpPESession psessionEntry)
+{}
+static inline void lim_send_reassoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
+		tLimMlmReassocReq *reassoc_req, tpPESession pe_session)
+{}
+static inline void lim_process_rx_scan_handler(struct wlan_objmgr_vdev *vdev,
+				 struct scan_event *event, void *arg)
+{}
+#endif
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+/**
+ * lim_process_set_he_bss_color() - process the set he bss color request
+ *
+ * @mac_ctx: global mac context pointer
+ * @msg_buf: message buffer pointer
+ *
+ * Return: void
+ */
+void lim_process_set_he_bss_color(tpAniSirGlobal mac_ctx, uint32_t *msg_buf);
+
+/**
+ * lim_process_obss_color_collision_info() - Process the obss color collision
+ *  request.
+ * @mac_ctx: global mac context pointer
+ * @msg_buf: message buffer pointer
+ *
+ * Return: void
+ */
+void lim_process_obss_color_collision_info(tpAniSirGlobal mac_ctx,
+					   uint32_t *msg_buf);
+
+/**
+ * lim_send_obss_color_collision_cfg() - Send obss color collision cfg.
+ * @mac_ctx: global mac context pointer
+ * @session: Pointer to session
+ * @event_type: obss color collision detection type
+ *
+ * Return: void
+ */
+void lim_send_obss_color_collision_cfg(tpAniSirGlobal mac_ctx,
+				       tpPESession session,
+				       enum wmi_obss_color_collision_evt_type
+				       event_type);
+#else
+static inline void lim_process_set_he_bss_color(tpAniSirGlobal mac_ctx,
+		uint32_t *msg_buf)
+{}
+static inline void lim_process_obss_color_collision_info(tpAniSirGlobal mac_ctx,
+							 uint32_t *msg_buf)
+{}
+static inline void lim_send_obss_color_collision_cfg(tpAniSirGlobal mac_ctx,
+			tpPESession session,
+			enum wmi_obss_color_collision_evt_type event_type)
+{}
+#endif
+void lim_send_delts_req_action_frame(tpAniSirGlobal pMac, tSirMacAddr peer,
+				     uint8_t wmmTspecPresent,
+				     tSirMacTSInfo * pTsinfo,
+				     tSirMacTspecIE * pTspecIe,
+				     tpPESession psessionEntry);
+void lim_send_addts_req_action_frame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+				     tSirAddtsReqInfo *addts, tpPESession);
+void lim_send_addts_rsp_action_frame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+				     uint16_t statusCode, tSirAddtsReqInfo *addts,
+				     tSirMacScheduleIE *pSchedule, tpPESession);
+
+void lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal, uint16_t, uint16_t, tSirMacAddr,
+				   uint8_t, tpDphHashNode pSta, tpPESession);
+
+void lim_send_disassoc_mgmt_frame(tpAniSirGlobal, uint16_t, tSirMacAddr,
+				  tpPESession, bool waitForAck);
+void lim_send_deauth_mgmt_frame(tpAniSirGlobal, uint16_t, tSirMacAddr, tpPESession,
+				bool waitForAck);
+
+void lim_process_mlm_update_hidden_ssid_rsp(tpAniSirGlobal mac_ctx,
+		struct scheduler_msg *msg);
+
+tSirResultCodes lim_mlm_add_bss(tpAniSirGlobal, tLimMlmStartReq *,
+				tpPESession psessionEntry);
+
+QDF_STATUS lim_send_channel_switch_mgmt_frame(tpAniSirGlobal, tSirMacAddr,
+						 uint8_t, uint8_t, uint8_t,
+						 tpPESession);
+
+QDF_STATUS lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
+	tSirMacAddr peer, uint8_t mode, uint8_t new_op_class,
+	uint8_t new_channel, uint8_t count, tpPESession session_entry);
+QDF_STATUS lim_p2p_oper_chan_change_confirm_action_frame(
+	tpAniSirGlobal mac_ctx, tSirMacAddr peer,
+	tpPESession session_entry);
+
+QDF_STATUS lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
+						     tSirMacAddr peer, uint8_t nMode,
+						     tpPESession psessionEntry);
+
+QDF_STATUS lim_send_neighbor_report_request_frame(tpAniSirGlobal,
+						     tpSirMacNeighborReportReq,
+						     tSirMacAddr, tpPESession);
+QDF_STATUS lim_send_link_report_action_frame(tpAniSirGlobal, tpSirMacLinkReport,
+						tSirMacAddr, tpPESession);
+
+/**
+ * lim_send_radio_measure_report_action_frame - Send RRM report action frame
+ * @pMac: pointer to global MAC context
+ * @dialog_token: Dialog token to be used in the action frame
+ * @num_report: number of reports in pRRMReport
+ * @last_beacon_report_params: Last Beacon Report indication params
+ * @pRRMReport: Pointer to the RRM report structure
+ * @peer: MAC address of the peer
+ * @psessionEntry: Pointer to the PE session entry
+ *
+ * Return: Ret Status
+ */
+QDF_STATUS
+lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
+				uint8_t dialog_token,
+				uint8_t num_report,
+				struct rrm_beacon_report_last_beacon_params
+				*last_beacon_report_params,
+				tpSirMacRadioMeasureReport pRRMReport,
+				tSirMacAddr peer,
+				tpPESession psessionEntry);
+
+#ifdef FEATURE_WLAN_TDLS
+void lim_init_tdls_data(tpAniSirGlobal, tpPESession);
+QDF_STATUS lim_process_sme_tdls_mgmt_send_req(tpAniSirGlobal pMac,
+						 uint32_t *pMsgBuf);
+QDF_STATUS lim_process_sme_tdls_add_sta_req(tpAniSirGlobal pMac,
+					       uint32_t *pMsgBuf);
+QDF_STATUS lim_process_sme_tdls_del_sta_req(tpAniSirGlobal pMac,
+					       uint32_t *pMsgBuf);
+void lim_send_sme_mgmt_tx_completion(
+		tpAniSirGlobal pMac,
+		uint32_t sme_session_id,
+		uint32_t txCompleteStatus);
+QDF_STATUS lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
+				    tpPESession session_entry);
+QDF_STATUS lim_process_tdls_add_sta_rsp(tpAniSirGlobal pMac, void *msg, tpPESession);
+void lim_process_tdls_del_sta_rsp(tpAniSirGlobal mac_ctx,
+				  struct scheduler_msg *lim_msg,
+				  tpPESession session_entry);
+#else
+static inline QDF_STATUS lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
+						tpPESession session_entry)
+{
+	return QDF_STATUS_SUCCESS;
+}
+static inline void lim_init_tdls_data(tpAniSirGlobal pMac,
+					tpPESession pSessionEntry)
+{
+
+}
+#endif
+
+/* Algorithms & Link Monitoring related functions */
+/* / Function that handles heartbeat failure */
+void lim_handle_heart_beat_failure(tpAniSirGlobal, tpPESession);
+
+/* / Function that triggers link tear down with AP upon HB failure */
+void lim_tear_down_link_with_ap(tpAniSirGlobal, uint8_t, tSirMacReasonCodes);
+
+/* / Function that processes Max retries interrupt from TFP */
+void limHandleMaxRetriesInterrupt(uint32_t);
+
+/* / Function that defers the messages received */
+uint32_t lim_defer_msg(tpAniSirGlobal, struct scheduler_msg *);
+
+/* / Function that Switches the Channel and sets the CB Mode */
+void lim_set_channel(tpAniSirGlobal pMac, uint8_t channel,
+		uint8_t ch_center_freq_seg0, uint8_t ch_center_freq_seg1,
+		enum phy_ch_width ch_width, int8_t maxTxPower,
+		uint8_t peSessionId, uint32_t cac_duration_ms,
+		uint32_t dfs_regdomain);
+
+
+#ifdef ANI_SUPPORT_11H
+/* / Function that sends Measurement Report action frame */
+QDF_STATUS lim_send_meas_report_frame(tpAniSirGlobal, tpSirMacMeasReqActionFrame,
+					 tSirMacAddr, tpPESession psessionEntry);
+
+/* / Function that sends TPC Report action frame */
+QDF_STATUS lim_send_tpc_report_frame(tpAniSirGlobal, tpSirMacTpcReqActionFrame,
+					tSirMacAddr, tpPESession psessionEntry);
+#endif
+
+/* / Function that sends TPC Request action frame */
+void lim_send_tpc_request_frame(tpAniSirGlobal, tSirMacAddr,
+				tpPESession psessionEntry);
+
+/* Function(s) to handle responses received from HAL */
+void lim_process_mlm_add_bss_rsp(tpAniSirGlobal pMac,
+				 struct scheduler_msg *limMsgQ);
+void lim_process_mlm_add_sta_rsp(tpAniSirGlobal pMac,
+				struct scheduler_msg *limMsgQt,
+				 tpPESession psessionEntry);
+void lim_process_mlm_del_sta_rsp(tpAniSirGlobal pMac,
+				 struct scheduler_msg *limMsgQ);
+void lim_process_mlm_del_bss_rsp(tpAniSirGlobal pMac,
+				 struct scheduler_msg *limMsgQ,
+				 tpPESession);
+void lim_process_sta_mlm_add_sta_rsp(tpAniSirGlobal pMac,
+				     struct scheduler_msg *limMsgQ,
+				     tpPESession psessionEntry);
+void lim_process_sta_mlm_del_sta_rsp(tpAniSirGlobal pMac,
+				     struct scheduler_msg *limMsgQ,
+				     tpPESession psessionEntry);
+void lim_process_sta_mlm_del_bss_rsp(tpAniSirGlobal pMac,
+				     struct scheduler_msg *limMsgQ,
+				     tpPESession psessionEntry);
+void lim_process_mlm_set_sta_key_rsp(tpAniSirGlobal pMac,
+				     struct scheduler_msg *limMsgQ);
+void lim_process_mlm_set_bss_key_rsp(tpAniSirGlobal pMac,
+				     struct scheduler_msg *limMsgQ);
+
+/* Function to process WMA_SWITCH_CHANNEL_RSP message */
+void lim_process_switch_channel_rsp(tpAniSirGlobal pMac, void *);
+
+void lim_covert_channel_scan_type(tpAniSirGlobal pMac, uint8_t channelNum,
+				  bool passiveToActive);
+void lim_set_dfs_channel_list(tpAniSirGlobal pMac, uint8_t channelNum,
+			      tSirDFSChannelList *dfsChannelList);
+void limContinueChannelLearn(tpAniSirGlobal);
+QDF_STATUS lim_sta_send_down_link(join_params *param);
+
+#ifdef WLAN_FEATURE_11W
+/* 11w send SA query request action frame */
+QDF_STATUS lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
+					      tSirMacAddr peer,
+					      tpPESession psessionEntry);
+/* 11w SA query request action frame handler */
+QDF_STATUS lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
+					       uint8_t *transId, tSirMacAddr peer,
+					       tpPESession psessionEntry);
+#endif
+
+/* Inline functions */
+
+/**
+ * lim_post_sme_message()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMlmMessages(). In this
+ * function MLM sub-module invokes MLM ind/cnf primitives.
+ *
+ ***LOGIC:
+ * Initially MLM makes an SME function call to invoke MLM ind/cnf
+ * primitive. In future this can be enhanced to 'post' messages to SME.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac      Pointer to Global MAC structure
+ * @param msgType   Indicates the MLM primitive message type
+ * @param *pMsgBuf  A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+static inline void
+lim_post_sme_message(tpAniSirGlobal pMac, uint32_t msgType, uint32_t *pMsgBuf)
+{
+	struct scheduler_msg msg = {0};
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+
+	msg.type = (uint16_t) msgType;
+	msg.bodyptr = pMsgBuf;
+	msg.bodyval = 0;
+	if (msgType > eWNI_SME_MSG_TYPES_BEGIN) {
+		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION,
+				 msg.type));
+		lim_process_sme_req_messages(pMac, &msg);
+	} else {
+		lim_process_mlm_rsp_messages(pMac, msgType, pMsgBuf);
+	}
+} /*** end lim_post_sme_message() ***/
+
+/**
+ * lim_post_mlm_message()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages(). In this
+ * function SME invokes MLME primitives.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ * Initially SME makes an MLM function call to invoke MLM primitive.
+ * In future this can be enhanced to 'post' messages to MLM.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac      Pointer to Global MAC structure
+ * @param msgType   Indicates the MLM primitive message type
+ * @param *pMsgBuf  A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+static inline void
+lim_post_mlm_message(tpAniSirGlobal pMac, uint32_t msgType, uint32_t *pMsgBuf)
+{
+	struct scheduler_msg msg = {0};
+
+	if (pMsgBuf == NULL) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	msg.type = (uint16_t) msgType;
+	msg.bodyptr = pMsgBuf;
+	msg.bodyval = 0;
+	MTRACE(mac_trace_msg_rx(pMac, NO_SESSION, msg.type));
+	lim_process_mlm_req_messages(pMac, &msg);
+} /*** end lim_post_mlm_message() ***/
+
+/**
+ * lim_get_ielen_from_bss_description()
+ *
+ ***FUNCTION:
+ * This function is called in various places to get IE length
+ * from tSirBssDescription structure
+ * number being scanned.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param     pBssDescr
+ * @return    Total IE length
+ */
+
+static inline uint16_t
+lim_get_ielen_from_bss_description(tpSirBssDescription pBssDescr)
+{
+	uint16_t ielen;
+
+	if (!pBssDescr)
+		return 0;
+
+	/*
+	 * Length of BSS desription is without length of
+	 * length itself and length of pointer
+	 * that holds ieFields
+	 *
+	 * <------------sizeof(tSirBssDescription)-------------------->
+	 * +--------+---------------------------------+---------------+
+	 * | length | other fields                    | pointer to IEs|
+	 * +--------+---------------------------------+---------------+
+	 *                                            ^
+	 *                                            ieFields
+	 */
+
+	ielen = (uint16_t)(pBssDescr->length + sizeof(pBssDescr->length) -
+			   GET_FIELD_OFFSET(tSirBssDescription, ieFields));
+
+	return ielen;
+} /*** end lim_get_ielen_from_bss_description() ***/
+
+/**
+ * lim_send_beacon_ind() - send the beacon indication
+ * @mac_ctx: pointer to mac structure
+ * @session: pe session
+ * @reason: beacon update reason
+ *
+ * return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS lim_send_beacon_ind(tpAniSirGlobal mac_ctx, tpPESession session,
+			       enum sir_bcn_update_reason reason);
+
+void
+lim_send_vdev_restart(tpAniSirGlobal pMac, tpPESession psessionEntry,
+		      uint8_t sessionId);
+
+void lim_get_wpspbc_sessions(tpAniSirGlobal pMac, struct qdf_mac_addr addr,
+			uint8_t *uuid_e, eWPSPBCOverlap *overlap,
+			tpPESession psessionEntry);
+void limWPSPBCTimeout(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void lim_wpspbc_close(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void lim_remove_pbc_sessions(tpAniSirGlobal pMac,
+				struct qdf_mac_addr pRemoveMac,
+				tpPESession psessionEntry);
+
+#define LIM_WPS_OVERLAP_TIMER_MS                 10000
+void
+lim_change_channel_with_callback(tpAniSirGlobal pMac, uint8_t newChannel,
+				 CHANGE_CHANNEL_CALLBACK callback,
+				 uint32_t *cbdata, tpPESession psessionEntry);
+
+void lim_process_remain_on_chn_timeout(tpAniSirGlobal pMac);
+void lim_send_p2p_action_frame(tpAniSirGlobal pMac, struct scheduler_msg *pMsg);
+
+void lim_process_disassoc_ack_timeout(tpAniSirGlobal pMac);
+void lim_process_deauth_ack_timeout(tpAniSirGlobal pMac);
+QDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal pMac);
+QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac);
+
+/**
+ * lim_disassoc_tx_complete_cnf() - callback to indicate Tx completion
+ * @context: pointer to mac structure
+ * @txCompleteSuccess: indicates tx success/failure
+ * @params: tx completion params
+ *
+ * function will be invoked on receiving tx completion indication
+ *
+ * return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
+					uint32_t txCompleteSuccess,
+					void *params);
+
+/**
+ * lim_deauth_tx_complete_cnf() - callback to indicate Tx completion
+ * @context: pointer to mac structure
+ * @txCompleteSuccess: indicates tx success/failure
+ * @params: tx completion params
+ *
+ * function will be invoked on receiving tx completion indication
+ *
+ * return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
+				      uint32_t txCompleteSuccess,
+				      void *params);
+
+typedef struct sSetLinkCbackParams {
+	void *cbackDataPtr;
+} tSetLinkCbackParams;
+
+int lim_process_remain_on_chnl_req(tpAniSirGlobal pMac, uint32_t *pMsg);
+void lim_remain_on_chn_rsp(tpAniSirGlobal pMac, QDF_STATUS status, uint32_t *data);
+void lim_send_sme_disassoc_deauth_ntf(tpAniSirGlobal mac_ctx,
+				QDF_STATUS status, uint32_t *ctx);
+
+#ifdef FEATURE_WLAN_TDLS
+QDF_STATUS lim_process_sme_del_all_tdls_peers(tpAniSirGlobal p_mac,
+						 uint32_t *msg_buf);
+#else
+static inline
+QDF_STATUS lim_process_sme_del_all_tdls_peers(tpAniSirGlobal p_mac,
+						 uint32_t *msg_buf)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * lim_send_bcn_rsp() - handle beacon send response
+ * @mac_ctx Pointer to Global MAC structure
+ * @rsp: beacon send response
+ *
+ * Return: None
+ */
+void lim_send_bcn_rsp(tpAniSirGlobal mac_ctx, tpSendbeaconParams rsp);
+
+/**
+ * lim_process_rx_channel_status_event() - processes
+ * event WDA_RX_CHN_STATUS_EVENT
+ * @mac_ctx Pointer to Global MAC structure
+ * @buf: Received message info
+ *
+ * Return: None
+ */
+void lim_process_rx_channel_status_event(tpAniSirGlobal mac_ctx, void *buf);
+
+/* / Bit value data structure */
+typedef enum sHalBitVal         /* For Bit operations */
+{
+	eHAL_CLEAR,
+	eHAL_SET
+} tHalBitVal;
+
+enum {
+	eHI_PRI,
+	ePROT,
+	eDBG
+};
+
+QDF_STATUS lim_send_addba_response_frame(tpAniSirGlobal mac_ctx,
+					 tSirMacAddr peer_mac, uint16_t tid,
+					 tpPESession session,
+					 uint8_t addba_extn_present,
+					 uint8_t amsdu_support);
+/**
+ * lim_process_join_failure_timeout() - This function is called to process
+ * JoinFailureTimeout
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * This function is called to process JoinFailureTimeout
+ *
+ * @Return None
+ */
+void lim_process_join_failure_timeout(tpAniSirGlobal mac_ctx);
+
+/**
+ * lim_process_auth_failure_timeout() - This function is called to process Min
+ * Channel Timeout during channel scan.
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * This function is called to process Min Channel Timeout during channel scan.
+ *
+ * @Return: None
+ */
+void lim_process_auth_failure_timeout(tpAniSirGlobal mac_ctx);
+
+/**
+ * lim_process_assoc_failure_timeout() - This function is called to process Min
+ * Channel Timeout during channel scan.
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_type: Assoc or reassoc
+ *
+ * This function is called to process Min Channel Timeout during channel scan.
+ *
+ * @Return: None
+ */
+void lim_process_assoc_failure_timeout(tpAniSirGlobal mac_ctx,
+				       uint32_t msg_type);
+
+/**
+ * lim_send_mgmt_frame_tx() - Sends mgmt frame
+ * @mac_ctx Pointer to Global MAC structure
+ * @msg: Received message info
+ *
+ * Return: None
+ */
+void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx,
+		struct scheduler_msg *msg);
+
+/**
+ * lim_send_csa_restart_req() - send csa restart req
+ * @mac_ctx Pointer to Global MAC structure
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void lim_send_csa_restart_req(tpAniSirGlobal mac_ctx, uint8_t vdev_id);
+
+/**
+ * lim_process_mlm_start_req() - process MLM_START_REQ message
+ *
+ * @mac_ctx: global MAC context
+ * @mlm_start_req: Pointer to start req
+ *
+ * This function is called to process MLM_START_REQ message
+ * from SME. MLME now waits for HAL to send WMA_ADD_BSS_RSP.
+ *
+ * Return: None
+ */
+void lim_process_mlm_start_req(tpAniSirGlobal mac_ctx,
+					  tLimMlmStartReq *mlm_start_req);
+
+/**
+ * lim_process_mlm_join_req() - process mlm join request.
+ *
+ * @mac_ctx:    Pointer to Global MAC structure
+ * @msg:        Pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_JOIN_REQ message
+ * from SME. It does following:
+ * 1) Initialize LIM, HAL, DPH
+ * 2) Configure the BSS for which the JOIN REQ was received
+ *   a) Send WMA_ADD_BSS_REQ to HAL -
+ *   This will identify the BSS that we are interested in
+ *   --AND--
+ *   Add a STA entry for the AP (in a STA context)
+ *   b) Wait for WMA_ADD_BSS_RSP
+ *   c) Send WMA_ADD_STA_REQ to HAL
+ *   This will add the "local STA" entry to the STA table
+ * 3) Continue as before, i.e,
+ *   a) Send a PROBE REQ
+ *   b) Wait for PROBE RSP/BEACON containing the SSID that
+ *   we are interested in
+ *   c) Then start an AUTH seq
+ *   d) Followed by the ASSOC seq
+ *
+ * @Return: None
+ */
+void lim_process_mlm_join_req(tpAniSirGlobal mac_ctx,
+			      tLimMlmJoinReq *mlm_join_req);
+
+/*
+ * lim_process_mlm_deauth_req() - This function is called to process
+ * MLM_DEAUTH_REQ message from SME
+ *
+ * @mac_ctx:      Pointer to Global MAC structure
+ * @msg_buf:      A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_DEAUTH_REQ message from SME
+ *
+ * @Return: None
+ */
+void lim_process_mlm_deauth_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf);
+
+#ifdef CONFIG_VDEV_SM
+/**
+ * lim_sta_mlme_vdev_disconnect_bss() - Disconnect from BSS
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes BSS disconnection
+ *
+ * Return: SUCCESS on successful completion of disconnection
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_sta_mlme_vdev_disconnect_bss(struct vdev_mlme_obj *vdev_mlme,
+					    uint16_t data_len, void *data);
+#endif
+#endif /* __LIM_TYPES_H */
diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c
new file mode 100644
index 0000000..94313b2
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -0,0 +1,8672 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * This file lim_utils.cc contains the utility functions
+ * LIM uses.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "sch_api.h"
+#include "lim_utils.h"
+#include "lim_types.h"
+#include "lim_security_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_send_messages.h"
+#include "lim_ser_des_utils.h"
+#include "lim_admit_control.h"
+#include "lim_sta_hash_api.h"
+#include "dot11f.h"
+#include "dot11fdefs.h"
+#include "wmm_apsd.h"
+#include "lim_trace.h"
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+#include "host_diag_core_event.h"
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_session_utils.h"
+#include "lim_ft_defs.h"
+#include "lim_session.h"
+#include "cds_reg_service.h"
+#include "nan_datapath.h"
+#include "wma.h"
+#include "wlan_reg_services_api.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_mlme_public_struct.h"
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+#include "wma_he.h"
+#endif
+#include "wlan_utility.h"
+
+#ifdef WLAN_FEATURE_11W
+#include "wni_cfg.h"
+#endif
+#include "cfg_mlme_obss_ht40.h"
+#include "cfg_ucfg_api.h"
+#include "lim_ft.h"
+
+#define ASCII_SPACE_CHARACTER 0x20
+
+/* A DFS channel can be ACTIVE for max 9000 msec, from the last
+   received Beacon/Prpbe Resp. */
+#define   MAX_TIME_TO_BE_ACTIVE_CHANNEL 9000
+
+
+/** -------------------------------------------------------------
+   \fn lim_delete_dialogue_token_list
+   \brief deletes the complete lim dialogue token linked list.
+   \param     tpAniSirGlobal    pMac
+   \return     None
+   -------------------------------------------------------------*/
+void lim_delete_dialogue_token_list(tpAniSirGlobal pMac)
+{
+	tpDialogueToken pCurrNode = pMac->lim.pDialogueTokenHead;
+
+	while (NULL != pMac->lim.pDialogueTokenHead) {
+		pCurrNode = pMac->lim.pDialogueTokenHead;
+		pMac->lim.pDialogueTokenHead =
+			pMac->lim.pDialogueTokenHead->next;
+		qdf_mem_free(pCurrNode);
+		pCurrNode = NULL;
+	}
+	pMac->lim.pDialogueTokenTail = NULL;
+}
+
+char *lim_dot11_reason_str(uint16_t reasonCode)
+{
+	switch (reasonCode) {
+	case 0:
+		return " ";
+		CASE_RETURN_STRING(eSIR_MAC_UNSPEC_FAILURE_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_PREV_AUTH_NOT_VALID_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_DEAUTH_LEAVING_BSS_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON);
+		CASE_RETURN_STRING
+			(eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON);
+		CASE_RETURN_STRING
+			(eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_DISASSOC_LEAVING_BSS_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_PWR_CAPABILITY_BAD_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_SPRTD_CHANNELS_BAD_REASON);
+
+		CASE_RETURN_STRING(eSIR_MAC_INVALID_IE_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_MIC_FAILURE_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_RSN_IE_MISMATCH_REASON);
+
+		CASE_RETURN_STRING(eSIR_MAC_INVALID_MC_CIPHER_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_INVALID_UC_CIPHER_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_INVALID_AKMP_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_UNSUPPORTED_RSN_IE_VER_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_INVALID_RSN_CAPABILITIES_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_1X_AUTH_FAILURE_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_CIPHER_SUITE_REJECTED_REASON);
+#ifdef FEATURE_WLAN_TDLS
+		CASE_RETURN_STRING(eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE);
+		CASE_RETURN_STRING(eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
+#endif
+		/* Reserved   27 - 30 */
+#ifdef WLAN_FEATURE_11W
+		CASE_RETURN_STRING
+			(eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION);
+#endif
+		CASE_RETURN_STRING(eSIR_MAC_QOS_UNSPECIFIED_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_QAP_NO_BANDWIDTH_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_XS_UNACKED_FRAMES_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_BAD_TXOP_USE_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_PEER_REJECT_MECHANISIM_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_MECHANISM_NOT_SETUP_REASON);
+
+		CASE_RETURN_STRING(eSIR_MAC_PEER_TIMEDOUT_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_CIPHER_NOT_SUPPORTED_REASON);
+		CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON);
+	/* Reserved 47 - 65535 */
+	default:
+		return "Unknown";
+	}
+}
+
+char *lim_mlm_state_str(tLimMlmStates state)
+{
+	switch (state) {
+	case eLIM_MLM_OFFLINE_STATE:
+		return "eLIM_MLM_OFFLINE_STATE";
+	case eLIM_MLM_IDLE_STATE:
+		return "eLIM_MLM_IDLE_STATE";
+	case eLIM_MLM_WT_PROBE_RESP_STATE:
+		return "eLIM_MLM_WT_PROBE_RESP_STATE";
+	case eLIM_MLM_PASSIVE_SCAN_STATE:
+		return "eLIM_MLM_PASSIVE_SCAN_STATE";
+	case eLIM_MLM_WT_JOIN_BEACON_STATE:
+		return "eLIM_MLM_WT_JOIN_BEACON_STATE";
+	case eLIM_MLM_JOINED_STATE:
+		return "eLIM_MLM_JOINED_STATE";
+	case eLIM_MLM_BSS_STARTED_STATE:
+		return "eLIM_MLM_BSS_STARTED_STATE";
+	case eLIM_MLM_WT_AUTH_FRAME2_STATE:
+		return "eLIM_MLM_WT_AUTH_FRAME2_STATE";
+	case eLIM_MLM_WT_AUTH_FRAME3_STATE:
+		return "eLIM_MLM_WT_AUTH_FRAME3_STATE";
+	case eLIM_MLM_WT_AUTH_FRAME4_STATE:
+		return "eLIM_MLM_WT_AUTH_FRAME4_STATE";
+	case eLIM_MLM_AUTH_RSP_TIMEOUT_STATE:
+		return "eLIM_MLM_AUTH_RSP_TIMEOUT_STATE";
+	case eLIM_MLM_AUTHENTICATED_STATE:
+		return "eLIM_MLM_AUTHENTICATED_STATE";
+	case eLIM_MLM_WT_ASSOC_RSP_STATE:
+		return "eLIM_MLM_WT_ASSOC_RSP_STATE";
+	case eLIM_MLM_WT_REASSOC_RSP_STATE:
+		return "eLIM_MLM_WT_REASSOC_RSP_STATE";
+	case eLIM_MLM_WT_FT_REASSOC_RSP_STATE:
+		return "eLIM_MLM_WT_FT_REASSOC_RSP_STATE";
+	case eLIM_MLM_WT_DEL_STA_RSP_STATE:
+		return "eLIM_MLM_WT_DEL_STA_RSP_STATE";
+	case eLIM_MLM_WT_DEL_BSS_RSP_STATE:
+		return "eLIM_MLM_WT_DEL_BSS_RSP_STATE";
+	case eLIM_MLM_WT_ADD_STA_RSP_STATE:
+		return "eLIM_MLM_WT_ADD_STA_RSP_STATE";
+	case eLIM_MLM_WT_ADD_BSS_RSP_STATE:
+		return "eLIM_MLM_WT_ADD_BSS_RSP_STATE";
+	case eLIM_MLM_REASSOCIATED_STATE:
+		return "eLIM_MLM_REASSOCIATED_STATE";
+	case eLIM_MLM_LINK_ESTABLISHED_STATE:
+		return "eLIM_MLM_LINK_ESTABLISHED_STATE";
+	case eLIM_MLM_WT_ASSOC_CNF_STATE:
+		return "eLIM_MLM_WT_ASSOC_CNF_STATE";
+	case eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE:
+		return "eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE";
+	case eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE:
+		return "eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE";
+	case eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE:
+		return "eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE";
+	case eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE:
+		return "eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE";
+	case eLIM_MLM_WT_SET_BSS_KEY_STATE:
+		return "eLIM_MLM_WT_SET_BSS_KEY_STATE";
+	case eLIM_MLM_WT_SET_STA_KEY_STATE:
+		return "eLIM_MLM_WT_SET_STA_KEY_STATE";
+	default:
+		return "INVALID MLM state";
+	}
+}
+
+void
+lim_print_mlm_state(tpAniSirGlobal pMac, uint16_t logLevel, tLimMlmStates state)
+{
+	pe_debug("Mlm state: %s", lim_mlm_state_str(state));
+}
+
+char *lim_sme_state_str(tLimSmeStates state)
+{
+	switch (state) {
+	case eLIM_SME_OFFLINE_STATE:
+		return "eLIM_SME_OFFLINE_STATE";
+	case  eLIM_SME_IDLE_STATE:
+		return "eLIM_SME_OFFLINE_STATE";
+	case eLIM_SME_SUSPEND_STATE:
+		return "eLIM_SME_SUSPEND_STATE";
+	case eLIM_SME_WT_SCAN_STATE:
+		return "eLIM_SME_WT_SCAN_STATE";
+	case eLIM_SME_WT_JOIN_STATE:
+		return "eLIM_SME_WT_JOIN_STATE";
+	case eLIM_SME_WT_AUTH_STATE:
+		return "eLIM_SME_WT_AUTH_STATE";
+	case eLIM_SME_WT_ASSOC_STATE:
+		return "eLIM_SME_WT_ASSOC_STATE";
+	case eLIM_SME_WT_REASSOC_STATE:
+		return "eLIM_SME_WT_REASSOC_STATE";
+	case eLIM_SME_JOIN_FAILURE_STATE:
+		return "eLIM_SME_JOIN_FAILURE_STATE";
+	case eLIM_SME_ASSOCIATED_STATE:
+		return "eLIM_SME_ASSOCIATED_STATE";
+	case eLIM_SME_REASSOCIATED_STATE:
+		return "eLIM_SME_REASSOCIATED_STATE";
+	case eLIM_SME_LINK_EST_STATE:
+		return "eLIM_SME_LINK_EST_STATE";
+	case eLIM_SME_LINK_EST_WT_SCAN_STATE:
+		return "eLIM_SME_LINK_EST_WT_SCAN_STATE";
+	case eLIM_SME_WT_PRE_AUTH_STATE:
+		return "eLIM_SME_WT_PRE_AUTH_STATE";
+	case eLIM_SME_WT_DISASSOC_STATE:
+		return "eLIM_SME_WT_DISASSOC_STATE";
+	case eLIM_SME_WT_DEAUTH_STATE:
+		return "eLIM_SME_WT_DEAUTH_STATE";
+	case eLIM_SME_WT_START_BSS_STATE:
+		return "eLIM_SME_WT_START_BSS_STATE";
+	case eLIM_SME_WT_STOP_BSS_STATE:
+		return "eLIM_SME_WT_STOP_BSS_STATE";
+	case eLIM_SME_NORMAL_STATE:
+		return "eLIM_SME_NORMAL_STATE";
+	case eLIM_SME_CHANNEL_SCAN_STATE:
+		return "eLIM_SME_CHANNEL_SCAN_STATE";
+	case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE:
+		return "eLIM_SME_NORMAL_CHANNEL_SCAN_STATE";
+	default:
+		return "INVALID SME STATE";
+	}
+}
+
+void
+lim_print_sme_state(tpAniSirGlobal pMac, uint16_t logLevel, tLimSmeStates state)
+{
+	pe_debug("SME state: %s", lim_sme_state_str(state));
+}
+
+char *lim_msg_str(uint32_t msgType)
+{
+#ifdef FIXME_GEN6
+	switch (msgType) {
+	case eWNI_SME_SYS_READY_IND:
+		return "eWNI_SME_SYS_READY_IND";
+	case eWNI_SME_JOIN_REQ:
+		return "eWNI_SME_JOIN_REQ";
+	case eWNI_SME_JOIN_RSP:
+		return "eWNI_SME_JOIN_RSP";
+	case eWNI_SME_SETCONTEXT_REQ:
+		return "eWNI_SME_SETCONTEXT_REQ";
+	case eWNI_SME_SETCONTEXT_RSP:
+		return "eWNI_SME_SETCONTEXT_RSP";
+	case eWNI_SME_REASSOC_REQ:
+		return "eWNI_SME_REASSOC_REQ";
+	case eWNI_SME_REASSOC_RSP:
+		return "eWNI_SME_REASSOC_RSP";
+	case eWNI_SME_DISASSOC_REQ:
+		return "eWNI_SME_DISASSOC_REQ";
+	case eWNI_SME_DISASSOC_RSP:
+		return "eWNI_SME_DISASSOC_RSP";
+	case eWNI_SME_DISASSOC_IND:
+		return "eWNI_SME_DISASSOC_IND";
+	case eWNI_SME_DISASSOC_CNF:
+		return "eWNI_SME_DISASSOC_CNF";
+	case eWNI_SME_DEAUTH_REQ:
+		return "eWNI_SME_DEAUTH_REQ";
+	case eWNI_SME_DEAUTH_RSP:
+		return "eWNI_SME_DEAUTH_RSP";
+	case eWNI_SME_DEAUTH_IND:
+		return "eWNI_SME_DEAUTH_IND";
+	case eWNI_SME_WM_STATUS_CHANGE_NTF:
+		return "eWNI_SME_WM_STATUS_CHANGE_NTF";
+	case eWNI_SME_START_BSS_REQ:
+		return "eWNI_SME_START_BSS_REQ";
+	case eWNI_SME_START_BSS_RSP:
+		return "eWNI_SME_START_BSS_RSP";
+	case eWNI_SME_ASSOC_IND:
+		return "eWNI_SME_ASSOC_IND";
+	case eWNI_SME_ASSOC_CNF:
+		return "eWNI_SME_ASSOC_CNF";
+	case eWNI_SME_SWITCH_CHL_IND:
+		return "eWNI_SME_SWITCH_CHL_IND";
+	case eWNI_SME_STOP_BSS_REQ:
+		return "eWNI_SME_STOP_BSS_REQ";
+	case eWNI_SME_STOP_BSS_RSP:
+		return "eWNI_SME_STOP_BSS_RSP";
+	case eWNI_SME_DEAUTH_CNF:
+		return "eWNI_SME_DEAUTH_CNF";
+	case eWNI_SME_ADDTS_REQ:
+		return "eWNI_SME_ADDTS_REQ";
+	case eWNI_SME_ADDTS_RSP:
+		return "eWNI_SME_ADDTS_RSP";
+	case eWNI_SME_DELTS_REQ:
+		return "eWNI_SME_DELTS_REQ";
+	case eWNI_SME_DELTS_RSP:
+		return "eWNI_SME_DELTS_RSP";
+	case eWNI_SME_DELTS_IND:
+		return "eWNI_SME_DELTS_IND";
+	case WMA_SUSPEND_ACTIVITY_RSP:
+		return "WMA_SUSPEND_ACTIVITY_RSP";
+	case SIR_LIM_RETRY_INTERRUPT_MSG:
+		return "SIR_LIM_RETRY_INTERRUPT_MSG";
+	case SIR_BB_XPORT_MGMT_MSG:
+		return "SIR_BB_XPORT_MGMT_MSG";
+	case SIR_LIM_INV_KEY_INTERRUPT_MSG:
+		return "SIR_LIM_INV_KEY_INTERRUPT_MSG";
+	case SIR_LIM_KEY_ID_INTERRUPT_MSG:
+		return "SIR_LIM_KEY_ID_INTERRUPT_MSG";
+	case SIR_LIM_REPLAY_THRES_INTERRUPT_MSG:
+		return "SIR_LIM_REPLAY_THRES_INTERRUPT_MSG";
+	case SIR_LIM_JOIN_FAIL_TIMEOUT:
+		return "SIR_LIM_JOIN_FAIL_TIMEOUT";
+	case SIR_LIM_AUTH_FAIL_TIMEOUT:
+		return "SIR_LIM_AUTH_FAIL_TIMEOUT";
+	case SIR_LIM_AUTH_RSP_TIMEOUT:
+		return "SIR_LIM_AUTH_RSP_TIMEOUT";
+	case SIR_LIM_ASSOC_FAIL_TIMEOUT:
+		return "SIR_LIM_ASSOC_FAIL_TIMEOUT";
+	case SIR_LIM_REASSOC_FAIL_TIMEOUT:
+		return "SIR_LIM_REASSOC_FAIL_TIMEOUT";
+	case SIR_LIM_HEART_BEAT_TIMEOUT:
+		return "SIR_LIM_HEART_BEAT_TIMEOUT";
+	case SIR_LIM_ADDTS_RSP_TIMEOUT:
+		return "SIR_LIM_ADDTS_RSP_TIMEOUT";
+	case SIR_LIM_LINK_TEST_DURATION_TIMEOUT:
+		return "SIR_LIM_LINK_TEST_DURATION_TIMEOUT";
+	case SIR_LIM_HASH_MISS_THRES_TIMEOUT:
+		return "SIR_LIM_HASH_MISS_THRES_TIMEOUT";
+	case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT:
+		return "SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT";
+	case SIR_LIM_CNF_WAIT_TIMEOUT:
+		return "SIR_LIM_CNF_WAIT_TIMEOUT";
+	case SIR_LIM_RADAR_DETECT_IND:
+		return "SIR_LIM_RADAR_DETECT_IND";
+	case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
+		return "SIR_LIM_FT_PREAUTH_RSP_TIMEOUT";
+	case WNI_CFG_PARAM_UPDATE_IND:
+		return "WNI_CFG_PARAM_UPDATE_IND";
+	case WNI_CFG_DNLD_REQ:
+		return "WNI_CFG_DNLD_REQ";
+	case WNI_CFG_DNLD_CNF:
+		return "WNI_CFG_DNLD_CNF";
+	case WNI_CFG_GET_RSP:
+		return "WNI_CFG_GET_RSP";
+	case WNI_CFG_SET_CNF:
+		return "WNI_CFG_SET_CNF";
+	case WNI_CFG_GET_ATTRIB_RSP:
+		return "WNI_CFG_GET_ATTRIB_RSP";
+	case WNI_CFG_ADD_GRP_ADDR_CNF:
+		return "WNI_CFG_ADD_GRP_ADDR_CNF";
+	case WNI_CFG_DEL_GRP_ADDR_CNF:
+		return "WNI_CFG_DEL_GRP_ADDR_CNF";
+	case ANI_CFG_GET_RADIO_STAT_RSP:
+		return "ANI_CFG_GET_RADIO_STAT_RSP";
+	case ANI_CFG_GET_PER_STA_STAT_RSP:
+		return "ANI_CFG_GET_PER_STA_STAT_RSP";
+	case ANI_CFG_GET_AGG_STA_STAT_RSP:
+		return "ANI_CFG_GET_AGG_STA_STAT_RSP";
+	case ANI_CFG_CLEAR_STAT_RSP:
+		return "ANI_CFG_CLEAR_STAT_RSP";
+	case WNI_CFG_DNLD_RSP:
+		return "WNI_CFG_DNLD_RSP";
+	case WNI_CFG_GET_REQ:
+		return "WNI_CFG_GET_REQ";
+	case eWNI_PMC_ENTER_IMPS_RSP:
+		return "eWNI_PMC_ENTER_IMPS_RSP";
+	case eWNI_PMC_EXIT_IMPS_RSP:
+		return "eWNI_PMC_EXIT_IMPS_RSP";
+	case eWNI_PMC_ENTER_BMPS_RSP:
+		return "eWNI_PMC_ENTER_BMPS_RSP";
+	case eWNI_PMC_EXIT_BMPS_RSP:
+		return "eWNI_PMC_EXIT_BMPS_RSP";
+	case eWNI_PMC_EXIT_BMPS_IND:
+		return "eWNI_PMC_EXIT_BMPS_IND";
+#ifdef FEATURE_WLAN_ESE
+	case eWNI_SME_GET_TSM_STATS_REQ:
+		return "eWNI_SME_GET_TSM_STATS_REQ";
+	case eWNI_SME_GET_TSM_STATS_RSP:
+		return "eWNI_SME_GET_TSM_STATS_RSP";
+#endif /* FEATURE_WLAN_ESE */
+	case eWNI_SME_CSA_OFFLOAD_EVENT:
+		return "eWNI_SME_CSA_OFFLOAD_EVENT";
+	case eWNI_SME_SET_HW_MODE_REQ:
+		return "eWNI_SME_SET_HW_MODE_REQ";
+	case eWNI_SME_SET_HW_MODE_RESP:
+		return "eWNI_SME_SET_HW_MODE_RESP";
+	case eWNI_SME_HW_MODE_TRANS_IND:
+		return "eWNI_SME_HW_MODE_TRANS_IND";
+	default:
+		return "INVALID SME message";
+	}
+#endif
+	return "";
+}
+
+char *lim_result_code_str(tSirResultCodes resultCode)
+{
+	switch (resultCode) {
+	case eSIR_SME_SUCCESS:
+		return "eSIR_SME_SUCCESS";
+	case eSIR_LOGE_EXCEPTION:
+		return "eSIR_LOGE_EXCEPTION";
+	case eSIR_SME_INVALID_PARAMETERS:
+		return "eSIR_SME_INVALID_PARAMETERS";
+	case eSIR_SME_UNEXPECTED_REQ_RESULT_CODE:
+		return "eSIR_SME_UNEXPECTED_REQ_RESULT_CODE";
+	case eSIR_SME_RESOURCES_UNAVAILABLE:
+		return "eSIR_SME_RESOURCES_UNAVAILABLE";
+	case eSIR_SME_SCAN_FAILED:
+		return "eSIR_SME_SCAN_FAILED";
+	case eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED:
+		return "eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED";
+	case eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE:
+		return "eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE";
+	case eSIR_SME_REFUSED:
+		return "eSIR_SME_REFUSED";
+	case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
+		return "eSIR_SME_JOIN_TIMEOUT_RESULT_CODE";
+	case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
+		return "eSIR_SME_AUTH_TIMEOUT_RESULT_CODE";
+	case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
+		return "eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE";
+	case eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE:
+		return "eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE";
+	case eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED:
+		return "eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED";
+	case eSIR_SME_AUTH_REFUSED:
+		return "eSIR_SME_AUTH_REFUSED";
+	case eSIR_SME_INVALID_WEP_DEFAULT_KEY:
+		return "eSIR_SME_INVALID_WEP_DEFAULT_KEY";
+	case eSIR_SME_ASSOC_REFUSED:
+		return "eSIR_SME_ASSOC_REFUSED";
+	case eSIR_SME_REASSOC_REFUSED:
+		return "eSIR_SME_REASSOC_REFUSED";
+	case eSIR_SME_STA_NOT_AUTHENTICATED:
+		return "eSIR_SME_STA_NOT_AUTHENTICATED";
+	case eSIR_SME_STA_NOT_ASSOCIATED:
+		return "eSIR_SME_STA_NOT_ASSOCIATED";
+	case eSIR_SME_ALREADY_JOINED_A_BSS:
+		return "eSIR_SME_ALREADY_JOINED_A_BSS";
+	case eSIR_SME_MORE_SCAN_RESULTS_FOLLOW:
+		return "eSIR_SME_MORE_SCAN_RESULTS_FOLLOW";
+	case eSIR_SME_INVALID_ASSOC_RSP_RXED:
+		return "eSIR_SME_INVALID_ASSOC_RSP_RXED";
+	case eSIR_SME_MIC_COUNTER_MEASURES:
+		return "eSIR_SME_MIC_COUNTER_MEASURES";
+	case eSIR_SME_ADDTS_RSP_TIMEOUT:
+		return "eSIR_SME_ADDTS_RSP_TIMEOUT";
+	case eSIR_SME_CHANNEL_SWITCH_FAIL:
+		return "eSIR_SME_CHANNEL_SWITCH_FAIL";
+	case eSIR_SME_HAL_SCAN_INIT_FAILED:
+		return "eSIR_SME_HAL_SCAN_INIT_FAILED";
+	case eSIR_SME_HAL_SCAN_END_FAILED:
+		return "eSIR_SME_HAL_SCAN_END_FAILED";
+	case eSIR_SME_HAL_SCAN_FINISH_FAILED:
+		return "eSIR_SME_HAL_SCAN_FINISH_FAILED";
+	case eSIR_SME_HAL_SEND_MESSAGE_FAIL:
+		return "eSIR_SME_HAL_SEND_MESSAGE_FAIL";
+
+	default:
+		return "INVALID resultCode";
+	}
+}
+
+void lim_print_msg_name(tpAniSirGlobal pMac, uint16_t logLevel, uint32_t msgType)
+{
+	pe_debug("Msg: %s", lim_msg_str(msgType));
+}
+
+/**
+ * lim_init_mlm() -  This function is called by limProcessSmeMessages() to
+ * initialize MLM state machine on STA
+ * @pMac: Pointer to Global MAC structure
+ *
+ * @Return: Status of operation
+ */
+QDF_STATUS lim_init_mlm(tpAniSirGlobal pMac)
+{
+	uint32_t retVal;
+
+	pMac->lim.gLimTimersCreated = 0;
+
+	MTRACE(mac_trace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION,
+			  pMac->lim.gLimMlmState));
+
+	/* Initialize number of pre-auth contexts */
+	pMac->lim.gLimNumPreAuthContexts = 0;
+
+	/* Initialize MAC based Authentication STA list */
+	lim_init_pre_auth_list(pMac);
+
+	/* Create timers used by LIM */
+	retVal = lim_create_timers(pMac);
+	if (retVal != TX_SUCCESS) {
+		pe_err("lim_create_timers Failed");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	pMac->lim.gLimTimersCreated = 1;
+	return QDF_STATUS_SUCCESS;
+} /*** end lim_init_mlm() ***/
+
+void lim_deactivate_timers(tpAniSirGlobal mac_ctx)
+{
+	uint32_t n;
+	tLimTimers *lim_timer = &mac_ctx->lim.limTimers;
+
+	lim_deactivate_timers_host_roam(mac_ctx);
+
+	/* Deactivate channel switch timer. */
+	tx_timer_deactivate(&lim_timer->gLimChannelSwitchTimer);
+
+	/* Deactivate addts response timer. */
+	tx_timer_deactivate(&lim_timer->gLimAddtsRspTimer);
+
+	if (tx_timer_running(&lim_timer->gLimJoinFailureTimer)) {
+		pe_err("Join failure timer running call the timeout API");
+		/* Cleanup as if join timer expired */
+		lim_timer_handler(mac_ctx, SIR_LIM_JOIN_FAIL_TIMEOUT);
+	}
+	/* Deactivate Join failure timer. */
+	tx_timer_deactivate(&lim_timer->gLimJoinFailureTimer);
+
+	/* Deactivate Periodic Join Probe Request timer. */
+	tx_timer_deactivate(&lim_timer->gLimPeriodicJoinProbeReqTimer);
+
+	/* Deactivate Auth Retry timer. */
+	tx_timer_deactivate
+			(&lim_timer->g_lim_periodic_auth_retry_timer);
+
+	if (tx_timer_running(&lim_timer->gLimAssocFailureTimer)) {
+		pe_err("Assoc failure timer running call the timeout API");
+		/* Cleanup as if assoc timer expired */
+		lim_assoc_failure_timer_handler(mac_ctx, LIM_ASSOC);
+	}
+	/* Deactivate Association failure timer. */
+	tx_timer_deactivate(&lim_timer->gLimAssocFailureTimer);
+
+	if (tx_timer_running(&mac_ctx->lim.limTimers.gLimAuthFailureTimer)) {
+		pe_err("Auth failure timer running call the timeout API");
+		/* Cleanup as if auth timer expired */
+		lim_timer_handler(mac_ctx, SIR_LIM_AUTH_FAIL_TIMEOUT);
+	}
+	/* Deactivate Authentication failure timer. */
+	tx_timer_deactivate(&lim_timer->gLimAuthFailureTimer);
+
+	/* Deactivate wait-for-probe-after-Heartbeat timer. */
+	tx_timer_deactivate(&lim_timer->gLimProbeAfterHBTimer);
+
+	/* Deactivate and delete Quiet timer. */
+	tx_timer_deactivate(&lim_timer->gLimQuietTimer);
+
+	/* Deactivate Quiet BSS timer. */
+	tx_timer_deactivate(&lim_timer->gLimQuietBssTimer);
+
+	/* Deactivate cnf wait timer */
+	for (n = 0; n < (mac_ctx->lim.maxStation + 1); n++) {
+		tx_timer_deactivate(&lim_timer->gpLimCnfWaitTimer[n]);
+	}
+
+	/* Deactivate any Authentication response timers */
+	lim_delete_pre_auth_list(mac_ctx);
+
+	tx_timer_deactivate(&lim_timer->gLimUpdateOlbcCacheTimer);
+	tx_timer_deactivate(&lim_timer->gLimPreAuthClnupTimer);
+
+	if (tx_timer_running(&lim_timer->gLimDisassocAckTimer)) {
+		pe_err("Disassoc timer running call the timeout API");
+		lim_timer_handler(mac_ctx, SIR_LIM_DISASSOC_ACK_TIMEOUT);
+	}
+	tx_timer_deactivate(&lim_timer->gLimDisassocAckTimer);
+
+	if (tx_timer_running(&lim_timer->gLimDeauthAckTimer)) {
+		pe_err("Deauth timer running call the timeout API");
+		lim_timer_handler(mac_ctx, SIR_LIM_DEAUTH_ACK_TIMEOUT);
+	}
+	tx_timer_deactivate(&lim_timer->gLimDeauthAckTimer);
+
+	tx_timer_deactivate(&lim_timer->
+			gLimActiveToPassiveChannelTimer);
+
+	tx_timer_deactivate(&lim_timer->sae_auth_timer);
+}
+
+
+/**
+ * lim_cleanup_mlm() - This function is called to cleanup
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * Function is called to cleanup any resources allocated by the  MLM
+ * state machine.
+ *
+ * Return: none
+ */
+void lim_cleanup_mlm(tpAniSirGlobal mac_ctx)
+{
+	uint32_t n;
+
+	tLimPreAuthNode **pAuthNode;
+	tLimTimers *lim_timer = NULL;
+
+	if (mac_ctx->lim.gLimTimersCreated == 1) {
+		lim_timer = &mac_ctx->lim.limTimers;
+
+		lim_deactivate_timers(mac_ctx);
+
+		lim_delete_timers_host_roam(mac_ctx);
+		/* Delete channel switch timer. */
+		tx_timer_delete(&lim_timer->gLimChannelSwitchTimer);
+
+		/* Delete addts response timer. */
+		tx_timer_delete(&lim_timer->gLimAddtsRspTimer);
+
+		/* Delete Join failure timer. */
+		tx_timer_delete(&lim_timer->gLimJoinFailureTimer);
+
+		/* Delete Periodic Join Probe Request timer. */
+		tx_timer_delete(&lim_timer->gLimPeriodicJoinProbeReqTimer);
+
+		/* Delete Auth Retry timer. */
+		tx_timer_delete(&lim_timer->g_lim_periodic_auth_retry_timer);
+
+		/* Delete Association failure timer. */
+		tx_timer_delete(&lim_timer->gLimAssocFailureTimer);
+
+		/* Delete Authentication failure timer. */
+		tx_timer_delete(&lim_timer->gLimAuthFailureTimer);
+
+		/* Delete wait-for-probe-after-Heartbeat timer. */
+		tx_timer_delete(&lim_timer->gLimProbeAfterHBTimer);
+
+		/* Delete Quiet timer. */
+		tx_timer_delete(&lim_timer->gLimQuietTimer);
+
+		/* Delete Quiet BSS timer. */
+		tx_timer_delete(&lim_timer->gLimQuietBssTimer);
+
+		/* Delete cnf wait timer */
+		for (n = 0; n < (mac_ctx->lim.maxStation + 1); n++) {
+			tx_timer_delete(&lim_timer->gpLimCnfWaitTimer[n]);
+		}
+
+		pAuthNode = mac_ctx->lim.gLimPreAuthTimerTable.pTable;
+
+		/* Delete any Auth rsp timers, which might have been started */
+		for (n = 0; n < mac_ctx->lim.gLimPreAuthTimerTable.numEntry;
+				n++)
+			tx_timer_delete(&pAuthNode[n]->timer);
+
+		tx_timer_delete(&lim_timer->gLimUpdateOlbcCacheTimer);
+		tx_timer_delete(&lim_timer->gLimPreAuthClnupTimer);
+
+		tx_timer_delete(&lim_timer->gLimDisassocAckTimer);
+
+		tx_timer_delete(&lim_timer->gLimDeauthAckTimer);
+
+		tx_timer_delete(&lim_timer->
+				gLimActiveToPassiveChannelTimer);
+
+		tx_timer_delete(&lim_timer->sae_auth_timer);
+
+		mac_ctx->lim.gLimTimersCreated = 0;
+	}
+} /*** end lim_cleanup_mlm() ***/
+
+/**
+ * lim_is_addr_bc()
+ *
+ ***FUNCTION:
+ * This function is called in various places within LIM code
+ * to determine whether passed MAC address is a broadcast or not
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param macAddr  Indicates MAC address that need to be determined
+ *                 whether it is Broadcast address or not
+ *
+ * @return true if passed address is Broadcast address else false
+ */
+
+uint8_t lim_is_addr_bc(tSirMacAddr macAddr)
+{
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		if ((macAddr[i] & 0xFF) != 0xFF)
+			return false;
+	}
+
+	return true;
+} /****** end lim_is_addr_bc() ******/
+
+/**
+ * lim_is_group_addr()
+ *
+ ***FUNCTION:
+ * This function is called in various places within LIM code
+ * to determine whether passed MAC address is a group address or not
+ *
+ ***LOGIC:
+ * If least significant bit of first octet of the MAC address is
+ * set to 1, it is a Group address.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param macAddr  Indicates MAC address that need to be determined
+ *                 whether it is Group address or not
+ *
+ * @return true if passed address is Group address else false
+ */
+
+uint8_t lim_is_group_addr(tSirMacAddr macAddr)
+{
+	if ((macAddr[0] & 0x01) == 0x01)
+		return true;
+	else
+		return false;
+} /****** end lim_is_group_addr() ******/
+
+/**
+ * lim_print_mac_addr()
+ *
+ ***FUNCTION:
+ * This function is called to print passed MAC address
+ * in : format.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * @param  macAddr  - MacAddr to be printed
+ * @param  logLevel - Loglevel to be used
+ *
+ * @return None.
+ */
+
+void lim_print_mac_addr(tpAniSirGlobal pMac, tSirMacAddr macAddr, uint8_t logLevel)
+{
+	pe_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
+} /****** end lim_print_mac_addr() ******/
+
+/*
+ * lim_reset_deferred_msg_q()
+ *
+ ***FUNCTION:
+ * This function resets the deferred message queue parameters.
+ *
+ ***PARAMS:
+ * @param pMac     - Pointer to Global MAC structure
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ ***RETURNS:
+ * None
+ */
+
+void lim_reset_deferred_msg_q(tpAniSirGlobal pMac)
+{
+	struct scheduler_msg *read_msg = {0};
+
+	if (pMac->lim.gLimDeferredMsgQ.size > 0) {
+		while ((read_msg = lim_read_deferred_msg_q(pMac)) != NULL) {
+			pe_free_msg(pMac, read_msg);
+		}
+	}
+
+	pMac->lim.gLimDeferredMsgQ.size =
+		pMac->lim.gLimDeferredMsgQ.write =
+			pMac->lim.gLimDeferredMsgQ.read = 0;
+
+}
+
+#define LIM_DEFERRED_Q_CHECK_THRESHOLD  (MAX_DEFERRED_QUEUE_LEN/2)
+#define LIM_MAX_NUM_MGMT_FRAME_DEFERRED (MAX_DEFERRED_QUEUE_LEN/2)
+
+/**
+ * lim_write_deferred_msg_q() - This function queues up a deferred message
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @lim_msg: a LIM message
+ *
+ * Function queues up a deferred message for later processing on the
+ * STA side.
+ *
+ * Return: none
+ */
+
+uint8_t lim_write_deferred_msg_q(tpAniSirGlobal mac_ctx,
+				 struct scheduler_msg *lim_msg)
+{
+	uint8_t type = 0, subtype = 0;
+
+	pe_debug("Queue a deferred message size: %d write: %d - type: 0x%x",
+		mac_ctx->lim.gLimDeferredMsgQ.size,
+		mac_ctx->lim.gLimDeferredMsgQ.write,
+		lim_msg->type);
+
+	/* check if the deferred message queue is full */
+	if (mac_ctx->lim.gLimDeferredMsgQ.size >= MAX_DEFERRED_QUEUE_LEN) {
+		if (!(mac_ctx->lim.deferredMsgCnt & 0xF)) {
+			pe_err("queue->MsgQ full Msg: %d Msgs Failed: %d",
+				lim_msg->type,
+				++mac_ctx->lim.deferredMsgCnt);
+			cds_flush_logs(WLAN_LOG_TYPE_NON_FATAL,
+				WLAN_LOG_INDICATOR_HOST_DRIVER,
+				WLAN_LOG_REASON_QUEUE_FULL,
+				true, false);
+		} else {
+			mac_ctx->lim.deferredMsgCnt++;
+		}
+		return TX_QUEUE_FULL;
+	}
+
+	/*
+	 * In the application, there should not be more than 1 message get
+	 * queued up. If happens, flags a warning. In the future, this can
+	 * happen.
+	 */
+	if (mac_ctx->lim.gLimDeferredMsgQ.size > 0)
+		pe_debug("%d Deferred Msg type: 0x%x scan: %d global sme: %d global mlme: %d addts: %d",
+			mac_ctx->lim.gLimDeferredMsgQ.size,
+			lim_msg->type,
+			lim_is_system_in_scan_state(mac_ctx),
+			mac_ctx->lim.gLimSmeState,
+			mac_ctx->lim.gLimMlmState,
+			mac_ctx->lim.gLimAddtsSent);
+
+	if (SIR_BB_XPORT_MGMT_MSG == lim_msg->type) {
+		lim_util_get_type_subtype(lim_msg->bodyptr,
+					&type, &subtype);
+		pe_debug(" Deferred management type %d subtype %d ",
+			type, subtype);
+	}
+
+	/*
+	 * To prevent the deferred Q is full of management frames, only give
+	 * them certain space
+	 */
+	if ((SIR_BB_XPORT_MGMT_MSG == lim_msg->type) &&
+		(LIM_DEFERRED_Q_CHECK_THRESHOLD <
+			mac_ctx->lim.gLimDeferredMsgQ.size)) {
+		uint16_t idx, count = 0;
+
+		for (idx = 0; idx < mac_ctx->lim.gLimDeferredMsgQ.size;
+								idx++) {
+			if (SIR_BB_XPORT_MGMT_MSG ==
+					mac_ctx->lim.gLimDeferredMsgQ.
+						deferredQueue[idx].type) {
+				count++;
+			}
+		}
+		if (LIM_MAX_NUM_MGMT_FRAME_DEFERRED < count) {
+			/*
+			 * We reach the quota for management frames,
+			 * drop this one
+			 */
+			pe_warn("Too many queue->MsgQ Msg: %d count: %d",
+				lim_msg->type, count);
+			/* Return error, caller knows what to do */
+			return TX_QUEUE_FULL;
+		}
+	}
+
+	++mac_ctx->lim.gLimDeferredMsgQ.size;
+
+	/* reset the count here since we are able to defer the message */
+	if (mac_ctx->lim.deferredMsgCnt != 0)
+		mac_ctx->lim.deferredMsgCnt = 0;
+
+	/* if the write pointer hits the end of the queue, rewind it */
+	if (mac_ctx->lim.gLimDeferredMsgQ.write >= MAX_DEFERRED_QUEUE_LEN)
+		mac_ctx->lim.gLimDeferredMsgQ.write = 0;
+
+	/* save the message to the queue and advanced the write pointer */
+	qdf_mem_copy((uint8_t *) &mac_ctx->lim.gLimDeferredMsgQ.
+			deferredQueue[mac_ctx->lim.gLimDeferredMsgQ.write++],
+				(uint8_t *) lim_msg,
+				sizeof(struct scheduler_msg));
+	return TX_SUCCESS;
+
+}
+
+/*
+ * lim_read_deferred_msg_q()
+ *
+ ***FUNCTION:
+ * This function dequeues a deferred message for processing on the
+ * STA side.
+ *
+ ***PARAMS:
+ * @param pMac     - Pointer to Global MAC structure
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ *
+ ***RETURNS:
+ * Returns the message at the head of the deferred message queue
+ */
+
+struct scheduler_msg *lim_read_deferred_msg_q(tpAniSirGlobal pMac)
+{
+	struct scheduler_msg *msg = {0};
+
+	/*
+	** check any messages left. If no, return
+	**/
+	if (pMac->lim.gLimDeferredMsgQ.size <= 0)
+		return NULL;
+
+	/*
+	** decrement the queue size
+	**/
+	pMac->lim.gLimDeferredMsgQ.size--;
+
+	/*
+	** retrieve the message from the head of the queue
+	**/
+	msg =
+		&pMac->lim.gLimDeferredMsgQ.deferredQueue[pMac->lim.
+							  gLimDeferredMsgQ.read];
+
+	/*
+	** advance the read pointer
+	**/
+	pMac->lim.gLimDeferredMsgQ.read++;
+
+	/*
+	** if the read pointer hits the end of the queue, rewind it
+	**/
+	if (pMac->lim.gLimDeferredMsgQ.read >= MAX_DEFERRED_QUEUE_LEN)
+		pMac->lim.gLimDeferredMsgQ.read = 0;
+
+	pe_debug("DeQueue a deferred message size: %d read: %d - type: 0x%x",
+			pMac->lim.gLimDeferredMsgQ.size,
+			pMac->lim.gLimDeferredMsgQ.read, msg->type);
+
+	pe_debug("DQ msg -- scan: %d global sme: %d global mlme: %d addts: %d",
+		lim_is_system_in_scan_state(pMac), pMac->lim.gLimSmeState,
+		pMac->lim.gLimMlmState, pMac->lim.gLimAddtsSent);
+
+	return msg;
+}
+
+QDF_STATUS
+lim_sys_process_mmh_msg_api(tpAniSirGlobal pMac,
+			    struct scheduler_msg *pMsg, uint8_t qType)
+{
+	/* FIXME */
+	sys_process_mmh_msg(pMac, pMsg);
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * lim_handle_update_olbc_cache() - This function update olbc cache
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * Function updates olbc cache
+ *
+ * Return: none
+ */
+void lim_handle_update_olbc_cache(tpAniSirGlobal mac_ctx)
+{
+	int i;
+	static int enable;
+	tUpdateBeaconParams beaconParams;
+
+	tpPESession psessionEntry = lim_is_ap_session_active(mac_ctx);
+
+	if (psessionEntry == NULL) {
+		pe_err(" Session not found");
+		return;
+	}
+
+	if (psessionEntry->is_session_obss_offload_enabled) {
+		pe_debug("protection offloaded");
+		return;
+	}
+	qdf_mem_set((uint8_t *) &beaconParams, sizeof(tUpdateBeaconParams), 0);
+	beaconParams.bssIdx = psessionEntry->bssIdx;
+
+	beaconParams.paramChangeBitmap = 0;
+	/*
+	 * This is doing a 2 pass check. The first pass is to invalidate
+	 * all the cache entries. The second pass is to decide whether to
+	 * disable protection.
+	 */
+	if (!enable) {
+		pe_debug("Resetting OLBC cache");
+		psessionEntry->gLimOlbcParams.numSta = 0;
+		psessionEntry->gLimOverlap11gParams.numSta = 0;
+		psessionEntry->gLimOverlapHt20Params.numSta = 0;
+		psessionEntry->gLimNonGfParams.numSta = 0;
+		psessionEntry->gLimLsigTxopParams.numSta = 0;
+
+		for (i = 0; i < LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++)
+			mac_ctx->lim.protStaOverlapCache[i].active = false;
+
+		enable = 1;
+	} else {
+		if ((!psessionEntry->gLimOlbcParams.numSta) &&
+			(psessionEntry->gLimOlbcParams.protectionEnabled) &&
+			(!psessionEntry->gLim11bParams.protectionEnabled)) {
+			pe_debug("Overlap cache clear and no 11B STA set");
+			lim_enable11g_protection(mac_ctx, false, true,
+						&beaconParams,
+						psessionEntry);
+		}
+
+		if ((!psessionEntry->gLimOverlap11gParams.numSta) &&
+			(psessionEntry->gLimOverlap11gParams.protectionEnabled)
+			&& (!psessionEntry->gLim11gParams.protectionEnabled)) {
+			pe_debug("Overlap cache clear and no 11G STA set");
+			lim_enable_ht_protection_from11g(mac_ctx, false, true,
+							&beaconParams,
+							psessionEntry);
+		}
+
+		if ((!psessionEntry->gLimOverlapHt20Params.numSta) &&
+			(psessionEntry->gLimOverlapHt20Params.protectionEnabled)
+			&& (!psessionEntry->gLimHt20Params.protectionEnabled)) {
+			pe_debug("Overlap cache clear and no HT20 STA set");
+			lim_enable11g_protection(mac_ctx, false, true,
+						&beaconParams,
+						psessionEntry);
+		}
+
+		enable = 0;
+	}
+
+	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
+					&& beaconParams.paramChangeBitmap) {
+		sch_set_fixed_beacon_fields(mac_ctx, psessionEntry);
+		lim_send_beacon_params(mac_ctx, &beaconParams, psessionEntry);
+	}
+	/* Start OLBC timer */
+	if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimUpdateOlbcCacheTimer)
+						!= TX_SUCCESS)
+		pe_err("tx_timer_activate failed");
+}
+
+/**
+ * lim_is_null_ssid() - This function checks if ssid supplied is Null SSID
+ * @ssid: pointer to tSirMacSSid
+ *
+ * Function checks if ssid supplied is Null SSID
+ *
+ * Return: none
+ */
+
+uint8_t lim_is_null_ssid(tSirMacSSid *ssid)
+{
+	uint8_t fnull_ssid = false;
+	uint32_t ssid_len;
+	uint8_t *ssid_str;
+
+	if (0 == ssid->length) {
+		fnull_ssid = true;
+		return fnull_ssid;
+	}
+	/* If the first charactes is space, then check if all
+	 * characters in SSID are spaces to consider it as NULL SSID
+	 */
+	if ((ASCII_SPACE_CHARACTER == ssid->ssId[0]) &&
+		(ssid->length == 1)) {
+			fnull_ssid = true;
+			return fnull_ssid;
+	} else {
+		/* check if all the charactes in SSID are NULL */
+		ssid_len = ssid->length;
+		ssid_str = ssid->ssId;
+
+		while (ssid_len) {
+			if (*ssid_str)
+				return fnull_ssid;
+
+			ssid_str++;
+			ssid_len--;
+		}
+
+		if (0 == ssid_len) {
+			fnull_ssid = true;
+			return fnull_ssid;
+		}
+	}
+
+	return fnull_ssid;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_update_prot_sta_params
+   \brief updates protection related counters.
+   \param      tpAniSirGlobal    pMac
+   \param      tSirMacAddr peerMacAddr
+   \param      tLimProtStaCacheType protStaCacheType
+   \param      tHalBitVal gfSupported
+   \param      tHalBitVal lsigTxopSupported
+   \return      None
+   -------------------------------------------------------------*/
+static void
+lim_update_prot_sta_params(tpAniSirGlobal pMac,
+			   tSirMacAddr peerMacAddr,
+			   tLimProtStaCacheType protStaCacheType,
+			   tHalBitVal gfSupported, tHalBitVal lsigTxopSupported,
+			   tpPESession psessionEntry)
+{
+	uint32_t i;
+
+	pe_debug("Associated STA addr is:");
+	lim_print_mac_addr(pMac, peerMacAddr, LOGD);
+
+	for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+		if (psessionEntry->protStaCache[i].active) {
+			pe_debug("Addr:");
+				lim_print_mac_addr
+				(pMac, psessionEntry->protStaCache[i].addr,
+				LOGD);
+
+			if (!qdf_mem_cmp
+				    (psessionEntry->protStaCache[i].addr,
+				    peerMacAddr, sizeof(tSirMacAddr))) {
+				pe_debug("matching cache entry at: %d already active",
+					i);
+				return;
+			}
+		}
+	}
+
+	for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+		if (!psessionEntry->protStaCache[i].active)
+			break;
+	}
+
+	if (i >= LIM_PROT_STA_CACHE_SIZE) {
+		pe_err("No space in ProtStaCache");
+		return;
+	}
+
+	qdf_mem_copy(psessionEntry->protStaCache[i].addr,
+		     peerMacAddr, sizeof(tSirMacAddr));
+
+	psessionEntry->protStaCache[i].protStaCacheType = protStaCacheType;
+	psessionEntry->protStaCache[i].active = true;
+	if (eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType) {
+		psessionEntry->gLim11bParams.numSta++;
+		pe_debug("11B,");
+	} else if (eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType) {
+		psessionEntry->gLim11gParams.numSta++;
+		pe_debug("11G,");
+	} else if (eLIM_PROT_STA_CACHE_TYPE_HT20 == protStaCacheType) {
+		psessionEntry->gLimHt20Params.numSta++;
+		pe_debug("HT20,");
+	}
+
+	if (!gfSupported) {
+		psessionEntry->gLimNonGfParams.numSta++;
+		pe_debug("NonGf,");
+	}
+	if (!lsigTxopSupported) {
+		psessionEntry->gLimLsigTxopParams.numSta++;
+		pe_debug("!lsigTxopSupported");
+	}
+} /* --------------------------------------------------------------------- */
+
+/** -------------------------------------------------------------
+   \fn lim_decide_ap_protection
+   \brief Decides all the protection related staiton coexistence and also sets
+ \        short preamble and short slot appropriately. This function will be called
+ \        when AP is ready to send assocRsp tp the station joining right now.
+   \param      tpAniSirGlobal    pMac
+   \param      tSirMacAddr peerMacAddr
+   \return      None
+   -------------------------------------------------------------*/
+void
+lim_decide_ap_protection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+			 tpUpdateBeaconParams pBeaconParams,
+			 tpPESession psessionEntry)
+{
+	uint16_t tmpAid;
+	tpDphHashNode pStaDs;
+	enum band_info rfBand = BAND_UNKNOWN;
+	uint32_t phyMode;
+	tLimProtStaCacheType protStaCacheType =
+		eLIM_PROT_STA_CACHE_TYPE_INVALID;
+	tHalBitVal gfSupported = eHAL_SET, lsigTxopSupported = eHAL_SET;
+
+	pBeaconParams->paramChangeBitmap = 0;
+	/* check whether to enable protection or not */
+	pStaDs =
+		dph_lookup_hash_entry(pMac, peerMacAddr, &tmpAid,
+				      &psessionEntry->dph.dphHashTable);
+	if (NULL == pStaDs) {
+		pe_err("pStaDs is NULL");
+		return;
+	}
+	lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
+	/* if we are in 5 GHZ band */
+	if (BAND_5G == rfBand) {
+		/* We are 11N. we need to protect from 11A and Ht20. we don't need any other protection in 5 GHZ. */
+		/* HT20 case is common between both the bands and handled down as common code. */
+		if (true == psessionEntry->htCapability) {
+			/* we are 11N and 11A station is joining. */
+			/* protection from 11A required. */
+			if (false == pStaDs->mlmStaContext.htCapability) {
+				lim_update_11a_protection(pMac, true, false,
+							 pBeaconParams,
+							 psessionEntry);
+				return;
+			}
+		}
+	} else if (BAND_2G == rfBand) {
+		lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+		/* We are 11G. Check if we need protection from 11b Stations. */
+		if ((phyMode == WNI_CFG_PHY_MODE_11G) &&
+		    (false == psessionEntry->htCapability)) {
+
+			if (pStaDs->erpEnabled == eHAL_CLEAR) {
+				protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
+				/* enable protection */
+				pe_debug("Enabling protection from 11B");
+				lim_enable11g_protection(pMac, true, false,
+							 pBeaconParams,
+							 psessionEntry);
+			}
+		}
+		/* HT station. */
+		if (true == psessionEntry->htCapability) {
+			/* check if we need protection from 11b station */
+			if ((pStaDs->erpEnabled == eHAL_CLEAR) &&
+			    (!pStaDs->mlmStaContext.htCapability)) {
+				protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
+				/* enable protection */
+				pe_debug("Enabling protection from 11B");
+				lim_enable11g_protection(pMac, true, false,
+							 pBeaconParams,
+							 psessionEntry);
+			}
+			/* station being joined is non-11b and non-ht ==> 11g device */
+			else if (!pStaDs->mlmStaContext.htCapability) {
+				protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llG;
+				/* enable protection */
+				lim_enable_ht_protection_from11g(pMac, true, false,
+								 pBeaconParams,
+								 psessionEntry);
+			}
+			/* ERP mode is enabled for the latest station joined */
+			/* latest station joined is HT capable */
+			/* This case is being handled in common code (commn between both the bands) below. */
+		}
+	}
+	/* we are HT and HT station is joining. This code is common for both the bands. */
+	if ((true == psessionEntry->htCapability) &&
+	    (true == pStaDs->mlmStaContext.htCapability)) {
+		if (!pStaDs->htGreenfield) {
+			lim_enable_ht_non_gf_protection(pMac, true, false,
+							pBeaconParams,
+							psessionEntry);
+			gfSupported = eHAL_CLEAR;
+		}
+		/* Station joining is HT 20Mhz */
+		if ((eHT_CHANNEL_WIDTH_20MHZ ==
+		pStaDs->htSupportedChannelWidthSet) &&
+		(eHT_CHANNEL_WIDTH_20MHZ !=
+		 psessionEntry->htSupportedChannelWidthSet)){
+			protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_HT20;
+			lim_enable_ht20_protection(pMac, true, false,
+						   pBeaconParams, psessionEntry);
+		}
+		/* Station joining does not support LSIG TXOP Protection */
+		if (!pStaDs->htLsigTXOPProtection) {
+			lim_enable_ht_lsig_txop_protection(pMac, false, false,
+							   pBeaconParams,
+							   psessionEntry);
+			lsigTxopSupported = eHAL_CLEAR;
+		}
+	}
+
+	lim_update_prot_sta_params(pMac, peerMacAddr, protStaCacheType,
+				   gfSupported, lsigTxopSupported, psessionEntry);
+
+	return;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_enable_overlap11g_protection
+   \brief wrapper function for setting overlap 11g protection.
+   \param      tpAniSirGlobal    pMac
+   \param      tpUpdateBeaconParams pBeaconParams
+   \param      tpSirMacMgmtHdr         pMh
+   \return      None
+   -------------------------------------------------------------*/
+void
+lim_enable_overlap11g_protection(tpAniSirGlobal pMac,
+				 tpUpdateBeaconParams pBeaconParams,
+				 tpSirMacMgmtHdr pMh, tpPESession psessionEntry)
+{
+	lim_update_overlap_sta_param(pMac, pMh->bssId,
+				     &(psessionEntry->gLimOlbcParams));
+
+	if (psessionEntry->gLimOlbcParams.numSta &&
+	    !psessionEntry->gLimOlbcParams.protectionEnabled) {
+		/* enable protection */
+		pe_debug("OLBC happens!!!");
+		lim_enable11g_protection(pMac, true, true, pBeaconParams,
+					 psessionEntry);
+	}
+}
+
+/**
+ * lim_update_short_preamble() - This function Updates short preamble
+ * @mac_ctx: pointer to Global MAC structure
+ * @peer_mac_addr: pointer to tSirMacAddr
+ * @pbeaconparams: pointer to tpUpdateBeaconParams
+ * @psession_entry: pointer to tpPESession
+ *
+ * Function Updates short preamble if needed when a new station joins
+ *
+ * Return: none
+ */
+void
+lim_update_short_preamble(tpAniSirGlobal mac_ctx, tSirMacAddr peer_mac_addr,
+				tpUpdateBeaconParams beaconparams,
+				tpPESession psession_entry)
+{
+	uint16_t aid;
+	tpDphHashNode sta_ds;
+	uint32_t phy_mode;
+	uint16_t i;
+
+	/* check whether to enable protection or not */
+	sta_ds =
+		dph_lookup_hash_entry(mac_ctx, peer_mac_addr, &aid,
+				      &psession_entry->dph.dphHashTable);
+
+	lim_get_phy_mode(mac_ctx, &phy_mode, psession_entry);
+
+	if (sta_ds == NULL || phy_mode != WNI_CFG_PHY_MODE_11G)
+		return;
+
+	if (sta_ds->shortPreambleEnabled != eHAL_CLEAR)
+		return;
+
+	pe_debug("Short Preamble is not enabled in Assoc Req from");
+
+	lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGD);
+
+	for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+		if (LIM_IS_AP_ROLE(psession_entry) &&
+			(psession_entry->gLimNoShortParams.
+				staNoShortCache[i].active) &&
+			(!qdf_mem_cmp
+				(psession_entry->gLimNoShortParams.
+				staNoShortCache[i].addr,
+				peer_mac_addr, sizeof(tSirMacAddr))))
+			return;
+		else if (!LIM_IS_AP_ROLE(psession_entry) &&
+				(mac_ctx->lim.gLimNoShortParams.
+					staNoShortCache[i].active) &&
+			(!qdf_mem_cmp(mac_ctx->lim.gLimNoShortParams.
+				staNoShortCache[i].addr,
+				peer_mac_addr,
+				sizeof(tSirMacAddr))))
+			return;
+	}
+
+	for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+		if (LIM_IS_AP_ROLE(psession_entry) &&
+			!psession_entry->gLimNoShortParams.
+				staNoShortCache[i].active)
+			break;
+		else if (!mac_ctx->lim.gLimNoShortParams.
+				staNoShortCache[i].active)
+			break;
+	}
+
+	if (i >= LIM_PROT_STA_CACHE_SIZE) {
+		tLimNoShortParams *lim_params =
+				&psession_entry->gLimNoShortParams;
+		if (LIM_IS_AP_ROLE(psession_entry)) {
+			pe_err("No space in Short cache active: %d sta: %d for sta",
+				i, lim_params->numNonShortPreambleSta);
+			lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGE);
+			return;
+		} else {
+			pe_err("No space in Short cache active: %d sta: %d for sta",
+				i, lim_params->numNonShortPreambleSta);
+			lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGE);
+			return;
+		}
+
+	}
+
+	if (LIM_IS_AP_ROLE(psession_entry)) {
+		qdf_mem_copy(psession_entry->gLimNoShortParams.
+				staNoShortCache[i].addr,
+				peer_mac_addr, sizeof(tSirMacAddr));
+		psession_entry->gLimNoShortParams.staNoShortCache[i].
+							active = true;
+		psession_entry->gLimNoShortParams.numNonShortPreambleSta++;
+	} else {
+		qdf_mem_copy(mac_ctx->lim.gLimNoShortParams.
+					staNoShortCache[i].addr,
+				peer_mac_addr, sizeof(tSirMacAddr));
+		mac_ctx->lim.gLimNoShortParams.staNoShortCache[i].active = true;
+		mac_ctx->lim.gLimNoShortParams.numNonShortPreambleSta++;
+	}
+
+	/* enable long preamble */
+	pe_debug("Disabling short preamble");
+
+	if (lim_enable_short_preamble(mac_ctx, false, beaconparams,
+					psession_entry) != QDF_STATUS_SUCCESS)
+		pe_err("Cannot enable long preamble");
+}
+
+/**
+ * lim_update_short_slot_time() - This function Updates short slot time
+ * @mac_ctx: pointer to Global MAC structure
+ * @peer_mac_addr: pointer to tSirMacAddr
+ * @beacon_params: pointer to tpUpdateBeaconParams
+ * @psession_entry: pointer to tpPESession
+ *
+ * Function Updates short slot time if needed when a new station joins
+ *
+ * Return: None
+ */
+void
+lim_update_short_slot_time(tpAniSirGlobal mac_ctx, tSirMacAddr peer_mac_addr,
+			   tpUpdateBeaconParams beacon_params,
+			   tpPESession session_entry)
+{
+	uint16_t aid;
+	tpDphHashNode sta_ds;
+	uint32_t phy_mode;
+	uint32_t val;
+	uint16_t i;
+
+	/* check whether to enable protection or not */
+	sta_ds = dph_lookup_hash_entry(mac_ctx, peer_mac_addr, &aid,
+				       &session_entry->dph.dphHashTable);
+	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+	if (sta_ds == NULL || phy_mode != WNI_CFG_PHY_MODE_11G)
+		return;
+
+	/*
+	 * Only in case of softap in 11g mode, slot time might change
+	 * depending on the STA being added. In 11a case, it should
+	 * be always 1 and in 11b case, it should be always 0.
+	 * Only when the new STA has short slot time disabled, we need to
+	 * change softap's overall slot time settings else the default for
+	 * softap is always short slot enabled. When the last long slot STA
+	 * leaves softAP, we take care of it in lim_decide_short_slot
+	 */
+	if (sta_ds->shortSlotTimeEnabled != eHAL_CLEAR)
+		return;
+
+	pe_debug("Short Slot Time is not enabled in Assoc Req from");
+	lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGD);
+	for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+		if (LIM_IS_AP_ROLE(session_entry) &&
+		    session_entry->gLimNoShortSlotParams.
+		    staNoShortSlotCache[i].active) {
+			if (!qdf_mem_cmp(session_entry->
+			    gLimNoShortSlotParams.staNoShortSlotCache[i].addr,
+			    peer_mac_addr, sizeof(tSirMacAddr)))
+				return;
+		} else if (!LIM_IS_AP_ROLE(session_entry)) {
+			if (mac_ctx->lim.gLimNoShortSlotParams.
+			    staNoShortSlotCache[i].active) {
+				if (!qdf_mem_cmp(mac_ctx->
+				    lim.gLimNoShortSlotParams.
+				    staNoShortSlotCache[i].addr,
+				    peer_mac_addr, sizeof(tSirMacAddr)))
+						return;
+			}
+		}
+	}
+	for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+		if (LIM_IS_AP_ROLE(session_entry) &&
+		    !session_entry->gLimNoShortSlotParams.
+		    staNoShortSlotCache[i].active)
+			break;
+		else
+			if (!mac_ctx->lim.gLimNoShortSlotParams.
+			    staNoShortSlotCache[i].active)
+				break;
+	}
+
+	if (i >= LIM_PROT_STA_CACHE_SIZE) {
+		if (LIM_IS_AP_ROLE(session_entry)) {
+			pe_err("No space in ShortSlot cache active: %d sta: %d for sta",
+				i, session_entry->gLimNoShortSlotParams.
+				numNonShortSlotSta);
+			lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGE);
+			return;
+		} else {
+			pe_err("No space in ShortSlot cache active: %d sta: %d for sta",
+				i, mac_ctx->lim.gLimNoShortSlotParams.
+				numNonShortSlotSta);
+			lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGE);
+			return;
+		}
+	}
+
+	if (LIM_IS_AP_ROLE(session_entry)) {
+		qdf_mem_copy(session_entry->gLimNoShortSlotParams.
+			staNoShortSlotCache[i].addr,
+			peer_mac_addr, sizeof(tSirMacAddr));
+		session_entry->gLimNoShortSlotParams.
+			staNoShortSlotCache[i].active = true;
+		session_entry->gLimNoShortSlotParams.numNonShortSlotSta++;
+	} else {
+		qdf_mem_copy(mac_ctx->lim.gLimNoShortSlotParams.
+			staNoShortSlotCache[i].addr,
+			peer_mac_addr, sizeof(tSirMacAddr));
+		mac_ctx->lim.gLimNoShortSlotParams.
+			staNoShortSlotCache[i].active = true;
+		mac_ctx->lim.gLimNoShortSlotParams.
+			numNonShortSlotSta++;
+	}
+	val = mac_ctx->mlme_cfg->feature_flags.enable_short_slot_time_11g;
+	/*
+	 * Here we check if we are AP role and short slot enabled
+	 * (both admin and oper modes) but we have atleast one STA
+	 * connected with only long slot enabled, we need to change
+	 * our beacon/pb rsp to broadcast short slot disabled
+	 */
+	if ((LIM_IS_AP_ROLE(session_entry)) && (val &&
+	    session_entry->gLimNoShortSlotParams.numNonShortSlotSta
+	    && session_entry->shortSlotTimeSupported)) {
+		/* enable long slot time */
+		beacon_params->fShortSlotTime = false;
+		beacon_params->paramChangeBitmap |=
+				PARAM_SHORT_SLOT_TIME_CHANGED;
+		pe_debug("Disable short slot time. Enable long slot time");
+		session_entry->shortSlotTimeSupported = false;
+	} else if (!LIM_IS_AP_ROLE(session_entry) &&
+		   (val && mac_ctx->lim.gLimNoShortSlotParams.
+		    numNonShortSlotSta &&
+		    session_entry->shortSlotTimeSupported)) {
+		/* enable long slot time */
+		beacon_params->fShortSlotTime = false;
+		beacon_params->paramChangeBitmap |=
+			PARAM_SHORT_SLOT_TIME_CHANGED;
+		pe_debug("Disable short slot time. Enable long slot time");
+		session_entry->shortSlotTimeSupported = false;
+	}
+}
+
+/** -------------------------------------------------------------
+   \fn lim_decide_sta_protection_on_assoc
+   \brief Decide protection related settings on Sta while association.
+   \param      tpAniSirGlobal    pMac
+   \param      tpSchBeaconStruct pBeaconStruct
+   \return      None
+   -------------------------------------------------------------*/
+void
+lim_decide_sta_protection_on_assoc(tpAniSirGlobal pMac,
+				   tpSchBeaconStruct pBeaconStruct,
+				   tpPESession psessionEntry)
+{
+	enum band_info rfBand = BAND_UNKNOWN;
+	uint32_t phyMode = WNI_CFG_PHY_MODE_NONE;
+
+	lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
+	lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+	if (BAND_5G == rfBand) {
+		if ((eSIR_HT_OP_MODE_MIXED == pBeaconStruct->HTInfo.opMode) ||
+		    (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+		     pBeaconStruct->HTInfo.opMode)) {
+			if (pMac->lim.cfgProtection.fromlla)
+				psessionEntry->beaconParams.llaCoexist = true;
+		} else if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
+			   pBeaconStruct->HTInfo.opMode) {
+			if (pMac->lim.cfgProtection.ht20)
+				psessionEntry->beaconParams.ht20Coexist = true;
+		}
+
+	} else if (BAND_2G == rfBand) {
+		/* spec 7.3.2.13 */
+		/* UseProtection will be set when nonERP STA is associated. */
+		/* NonERPPresent bit will be set when: */
+		/* --nonERP Sta is associated OR */
+		/* --nonERP Sta exists in overlapping BSS */
+		/* when useProtection is not set then protection from nonERP stations is optional. */
+
+		/* CFG protection from 11b is enabled and */
+		/* 11B device in the BSS */
+		/* TODO, This is not sessionized */
+		if (phyMode != WNI_CFG_PHY_MODE_11B) {
+			if (pMac->lim.cfgProtection.fromllb &&
+			    pBeaconStruct->erpPresent &&
+			    (pBeaconStruct->erpIEInfo.useProtection ||
+			     pBeaconStruct->erpIEInfo.nonErpPresent)) {
+				psessionEntry->beaconParams.llbCoexist = true;
+			}
+			/* AP has no 11b station associated. */
+			else {
+				psessionEntry->beaconParams.llbCoexist = false;
+			}
+		}
+		/* following code block is only for HT station. */
+		if ((psessionEntry->htCapability) &&
+		    (pBeaconStruct->HTInfo.present)) {
+			tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo;
+
+			/* Obss Non HT STA present mode */
+			psessionEntry->beaconParams.gHTObssMode =
+				(uint8_t) htInfo.obssNonHTStaPresent;
+
+			/* CFG protection from 11G is enabled and */
+			/* our AP has at least one 11G station associated. */
+			if (pMac->lim.cfgProtection.fromllg &&
+			    ((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) ||
+			     (eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode))
+			    && (!psessionEntry->beaconParams.llbCoexist)) {
+				if (pMac->lim.cfgProtection.fromllg)
+					psessionEntry->beaconParams.llgCoexist =
+						true;
+			}
+			/* AP has only HT stations associated and at least one station is HT 20 */
+			/* disable protection from any non-HT devices. */
+			/* decision for disabling protection from 11b has already been taken above. */
+			if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == htInfo.opMode) {
+				/* Disable protection from 11G station. */
+				psessionEntry->beaconParams.llgCoexist = false;
+				/* CFG protection from HT 20 is enabled. */
+				if (pMac->lim.cfgProtection.ht20)
+					psessionEntry->beaconParams.
+					ht20Coexist = true;
+			}
+			/* Disable protection from non-HT and HT20 devices. */
+			/* decision for disabling protection from 11b has already been taken above. */
+			if (eSIR_HT_OP_MODE_PURE == htInfo.opMode) {
+				psessionEntry->beaconParams.llgCoexist = false;
+				psessionEntry->beaconParams.ht20Coexist = false;
+			}
+
+		}
+	}
+	/* protection related factors other than HT operating mode. Applies to 2.4 GHZ as well as 5 GHZ. */
+	if ((psessionEntry->htCapability) && (pBeaconStruct->HTInfo.present)) {
+		tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo;
+
+		psessionEntry->beaconParams.fRIFSMode =
+			(uint8_t) htInfo.rifsMode;
+		psessionEntry->beaconParams.llnNonGFCoexist =
+			(uint8_t) htInfo.nonGFDevicesPresent;
+		psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport =
+			(uint8_t) htInfo.lsigTXOPProtectionFullSupport;
+	}
+}
+
+
+/**
+ * lim_decide_sta_11bg_protection() - decides protection related settings on sta
+ * @mac_ctx: pointer to global mac structure
+ * @beacon_struct: pointer to tpschbeaconstruct
+ * @beaconparams: pointer to tpupdatebeaconparams
+ * @psession_entry: pointer to tppesession
+ * @phy_mode: phy mode index
+ *
+ * decides 11bg protection related settings on sta while processing beacon
+ *
+ * Return: none
+ */
+static void
+lim_decide_sta_11bg_protection(tpAniSirGlobal mac_ctx,
+			tpSchBeaconStruct beacon_struct,
+			tpUpdateBeaconParams beaconparams,
+			tpPESession psession_entry,
+			uint32_t phy_mode)
+{
+
+	tDot11fIEHTInfo htInfo;
+
+	/*
+	 * spec 7.3.2.13
+	 * UseProtection will be set when nonERP STA is associated.
+	 * NonERPPresent bit will be set when:
+	 * --nonERP Sta is associated OR
+	 * --nonERP Sta exists in overlapping BSS
+	 * when useProtection is not set then protection from
+	 * nonERP stations is optional.
+	 */
+	if (phy_mode != WNI_CFG_PHY_MODE_11B) {
+		if (beacon_struct->erpPresent &&
+			(beacon_struct->erpIEInfo.useProtection ||
+			beacon_struct->erpIEInfo.nonErpPresent)) {
+			lim_enable11g_protection(mac_ctx, true, false,
+						beaconparams,
+						psession_entry);
+		}
+		/* AP has no 11b station associated. */
+		else {
+			/* disable protection from 11b station */
+			lim_enable11g_protection(mac_ctx, false, false,
+						beaconparams,
+						psession_entry);
+		}
+	}
+
+	if (!(psession_entry->htCapability) ||
+		!(beacon_struct->HTInfo.present))
+		return;
+
+	/* following code is only for HT station. */
+
+	htInfo = beacon_struct->HTInfo;
+	/* AP has at least one 11G station associated. */
+	if (((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) ||
+		(eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode)) &&
+		(!psession_entry->beaconParams.llbCoexist)) {
+		lim_enable_ht_protection_from11g(mac_ctx, true, false,
+						beaconparams, psession_entry);
+
+	}
+	/*
+	 * no HT operating mode change  ==> no change in
+	 * protection settings except for MIXED_MODE/Legacy
+	 * Mode.
+	 */
+	/*
+	 * in Mixed mode/legacy Mode even if there is no
+	 * change in HT operating mode, there might be
+	 * change in 11bCoexist or 11gCoexist. Hence this
+	 * check is being done after mixed/legacy mode
+	 * check.
+	 */
+	if (mac_ctx->lim.gHTOperMode !=
+		(tSirMacHTOperatingMode)htInfo.opMode) {
+		mac_ctx->lim.gHTOperMode =
+			(tSirMacHTOperatingMode) htInfo.opMode;
+		/*
+		 * AP has only HT stations associated and
+		 * at least one station is HT 20
+		 */
+
+		/* disable protection from any non-HT devices. */
+
+		/*
+		 * decision for disabling protection from
+		 * 11b has already been taken above.
+		 */
+		if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
+				htInfo.opMode) {
+			/* Disable protection from 11G station. */
+			lim_enable_ht_protection_from11g(mac_ctx, false,
+						false, beaconparams,
+						psession_entry);
+
+			lim_enable_ht20_protection(mac_ctx, true, false,
+						beaconparams,
+						psession_entry);
+		}
+		/*
+		 * Disable protection from non-HT and
+		 * HT20 devices.
+		 */
+		/*
+		 * decision for disabling protection from
+		 * 11b has already been taken above.
+		 */
+		else if (eSIR_HT_OP_MODE_PURE == htInfo.opMode) {
+			lim_enable_ht_protection_from11g(mac_ctx, false,
+						false, beaconparams,
+						psession_entry);
+
+			lim_enable_ht20_protection(mac_ctx, false,
+						false, beaconparams,
+						psession_entry);
+
+		}
+	}
+
+}
+
+/**
+ * lim_decide_sta_protection() -  decides protection related settings on sta
+ * @mac_ctx: pointer to global mac structure
+ * @beacon_struct: pointer to tpschbeaconstruct
+ * @beaconparams: pointer to tpupdatebeaconparams
+ * @psession_entry: pointer to tppesession
+ *
+ * decides protection related settings on sta while processing beacon
+ *
+ * Return: none
+ */
+void
+lim_decide_sta_protection(tpAniSirGlobal mac_ctx,
+				tpSchBeaconStruct beacon_struct,
+				tpUpdateBeaconParams beaconparams,
+				tpPESession psession_entry)
+{
+
+	enum band_info rfband = BAND_UNKNOWN;
+	uint32_t phy_mode = WNI_CFG_PHY_MODE_NONE;
+
+	lim_get_rf_band_new(mac_ctx, &rfband, psession_entry);
+	lim_get_phy_mode(mac_ctx, &phy_mode, psession_entry);
+
+	if ((BAND_5G == rfband) &&
+		/* we are HT capable. */
+		(true == psession_entry->htCapability) &&
+		(beacon_struct->HTInfo.present)) {
+		/*
+		 * we are HT capable, AP's HT OPMode is
+		 * mixed / overlap legacy ==> need protection
+		 * from 11A.
+		 */
+		if ((eSIR_HT_OP_MODE_MIXED ==
+				beacon_struct->HTInfo.opMode) ||
+			(eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+				beacon_struct->HTInfo.opMode)) {
+			lim_update_11a_protection(mac_ctx, true, false,
+						beaconparams, psession_entry);
+		}
+		/*
+		 * we are HT capable, AP's HT OPMode is
+		 * HT20 ==> disable protection from 11A if
+		 * enabled.
+		 */
+		/* protection from HT20 if needed. */
+		else if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
+					beacon_struct->HTInfo.opMode) {
+			lim_update_11a_protection(mac_ctx, false, false,
+						beaconparams, psession_entry);
+			lim_enable_ht20_protection(mac_ctx, true, false,
+						beaconparams, psession_entry);
+		} else if (eSIR_HT_OP_MODE_PURE ==
+				beacon_struct->HTInfo.opMode) {
+			lim_update_11a_protection(mac_ctx, false, false,
+						beaconparams, psession_entry);
+			lim_enable_ht20_protection(mac_ctx, false,
+						false, beaconparams,
+						psession_entry);
+		}
+	} else if (BAND_2G == rfband) {
+		lim_decide_sta_11bg_protection(mac_ctx, beacon_struct,
+					beaconparams, psession_entry, phy_mode);
+	}
+	/*
+	 * following code block is only for HT station.
+	 * (2.4 GHZ as well as 5 GHZ)
+	 */
+	if ((psession_entry->htCapability) && (beacon_struct->HTInfo.present)) {
+		tDot11fIEHTInfo htInfo = beacon_struct->HTInfo;
+		/*
+		 * Check for changes in protection related factors other
+		 * than HT operating mode.
+		 */
+		/*
+		 * Check for changes in RIFS mode, nonGFDevicesPresent,
+		 * lsigTXOPProtectionFullSupport.
+		 */
+		if (psession_entry->beaconParams.fRIFSMode !=
+				(uint8_t) htInfo.rifsMode) {
+			beaconparams->fRIFSMode =
+				psession_entry->beaconParams.fRIFSMode =
+						(uint8_t) htInfo.rifsMode;
+			beaconparams->paramChangeBitmap |=
+						PARAM_RIFS_MODE_CHANGED;
+		}
+
+		if (psession_entry->beaconParams.llnNonGFCoexist !=
+					htInfo.nonGFDevicesPresent) {
+			beaconparams->llnNonGFCoexist =
+				psession_entry->beaconParams.llnNonGFCoexist =
+					(uint8_t) htInfo.nonGFDevicesPresent;
+			beaconparams->paramChangeBitmap |=
+					PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+		}
+
+		if (psession_entry->beaconParams.
+			fLsigTXOPProtectionFullSupport !=
+			(uint8_t) htInfo.lsigTXOPProtectionFullSupport) {
+			beaconparams->fLsigTXOPProtectionFullSupport =
+				psession_entry->beaconParams.
+					fLsigTXOPProtectionFullSupport =
+						(uint8_t) htInfo.
+						lsigTXOPProtectionFullSupport;
+			beaconparams->paramChangeBitmap |=
+					PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+		}
+		/*
+		 * For Station just update the global lim variable,
+		 * no need to send message to HAL since Station already
+		 * taking care of HT OPR Mode=01,
+		 * meaning AP is seeing legacy
+		 */
+		/* stations in overlapping BSS. */
+		if (psession_entry->beaconParams.gHTObssMode !=
+				(uint8_t) htInfo.obssNonHTStaPresent)
+			psession_entry->beaconParams.gHTObssMode =
+				(uint8_t) htInfo.obssNonHTStaPresent;
+
+	}
+}
+
+/**
+ * lim_process_channel_switch_timeout()
+ *
+ ***FUNCTION:
+ * This function is invoked when Channel Switch Timer expires at
+ * the STA.  Now, STA must stop traffic, and then change/disable
+ * primary or secondary channel.
+ *
+ *
+ ***NOTE:
+ * @param  pMac           - Pointer to Global MAC structure
+ * @return None
+ */
+void lim_process_channel_switch_timeout(tpAniSirGlobal pMac)
+{
+	tpPESession psessionEntry = NULL;
+	uint8_t channel; /* This is received and stored from channelSwitch Action frame */
+
+	psessionEntry = pe_find_session_by_session_id(pMac,
+			pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+
+	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+		pe_warn("Channel switch can be done only in STA role, Current Role: %d",
+			       GET_LIM_SYSTEM_ROLE(psessionEntry));
+		return;
+	}
+
+	if (psessionEntry->gLimSpecMgmt.dot11hChanSwState !=
+	   eLIM_11H_CHANSW_RUNNING) {
+		pe_warn("Channel switch timer should not have been running in state: %d",
+			psessionEntry->gLimSpecMgmt.dot11hChanSwState);
+		return;
+	}
+
+	channel = psessionEntry->gLimChannelSwitch.primaryChannel;
+	/* Restore Channel Switch parameters to default */
+	psessionEntry->gLimChannelSwitch.switchTimeoutValue = 0;
+
+	/* Channel-switch timeout has occurred. reset the state */
+	psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_END;
+
+	/* Check if the AP is switching to a channel that we support.
+	 * Else, just don't bother to switch. Indicate HDD to look for a
+	 * better AP to associate
+	 */
+	if (!lim_is_channel_valid_for_channel_switch(pMac, channel)) {
+		/* We need to restore pre-channelSwitch state on the STA */
+		if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
+		    QDF_STATUS_SUCCESS) {
+			pe_err("Could not restore pre-channelSwitch (11h) state, resetting the system");
+			return;
+		}
+
+		/*
+		 * If the channel-list that AP is asking us to switch is invalid
+		 * then we cannot switch the channel. Just disassociate from AP.
+		 * We will find a better AP !!!
+		 */
+		if ((psessionEntry->limMlmState ==
+		   eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+		   (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) &&
+		   (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) {
+			pe_err("Invalid channel! Disconnect");
+			lim_tear_down_link_with_ap(pMac,
+					   pMac->lim.limTimers.
+					   gLimChannelSwitchTimer.sessionId,
+					   eSIR_MAC_UNSPEC_FAILURE_REASON);
+			return;
+		}
+	}
+	lim_covert_channel_scan_type(pMac, psessionEntry->currentOperChannel,
+				     false);
+	pMac->lim.dfschannelList.timeStamp[psessionEntry->currentOperChannel] =
+		0;
+	switch (psessionEntry->gLimChannelSwitch.state) {
+	case eLIM_CHANNEL_SWITCH_PRIMARY_ONLY:
+		pe_warn("CHANNEL_SWITCH_PRIMARY_ONLY");
+		lim_switch_primary_channel(pMac,
+					   psessionEntry->gLimChannelSwitch.
+					   primaryChannel, psessionEntry);
+		psessionEntry->gLimChannelSwitch.state =
+			eLIM_CHANNEL_SWITCH_IDLE;
+		break;
+	case eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY:
+		pe_warn("CHANNEL_SWITCH_PRIMARY_AND_SECONDARY");
+		lim_switch_primary_secondary_channel(pMac, psessionEntry,
+			psessionEntry->gLimChannelSwitch.primaryChannel,
+			psessionEntry->gLimChannelSwitch.ch_center_freq_seg0,
+			psessionEntry->gLimChannelSwitch.ch_center_freq_seg1,
+			psessionEntry->gLimChannelSwitch.ch_width);
+		psessionEntry->gLimChannelSwitch.state =
+			eLIM_CHANNEL_SWITCH_IDLE;
+		break;
+
+	case eLIM_CHANNEL_SWITCH_IDLE:
+	default:
+		pe_err("incorrect state");
+		if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
+		    QDF_STATUS_SUCCESS) {
+			pe_err("Could not restore pre-channelSwitch (11h) state, resetting the system");
+		}
+		return; /* Please note, this is 'return' and not 'break' */
+	}
+}
+
+/**
+ * lim_update_channel_switch() - This Function updates channel switch
+ * @mac_ctx: pointer to Global MAC structure
+ * @beacon: pointer to tpSirProbeRespBeacon
+ * @psessionentry: pointer to tpPESession
+ *
+ * This function is invoked whenever Station receives
+ * either 802.11h channel switch IE or airgo proprietary
+ * channel switch IE.
+ *
+ * Return: none
+ */
+void
+lim_update_channel_switch(struct mac_context *mac_ctx,
+			tpSirProbeRespBeacon beacon,
+			tpPESession psession_entry)
+{
+	uint16_t beacon_period;
+	tDot11fIEChanSwitchAnn *chnl_switch;
+	tLimChannelSwitchInfo *ch_switch_params;
+	tDot11fIEWiderBWChanSwitchAnn *widerchnl_switch;
+
+	beacon_period = psession_entry->beaconParams.beaconInterval;
+
+	/* 802.11h standard channel switch IE */
+	chnl_switch = &(beacon->channelSwitchIE);
+	ch_switch_params = &psession_entry->gLimChannelSwitch;
+	ch_switch_params->primaryChannel =
+		chnl_switch->newChannel;
+	ch_switch_params->switchCount = chnl_switch->switchCount;
+	ch_switch_params->switchTimeoutValue =
+		SYS_MS_TO_TICKS(beacon_period) * (chnl_switch->switchCount);
+	ch_switch_params->switchMode = chnl_switch->switchMode;
+	widerchnl_switch = &(beacon->WiderBWChanSwitchAnn);
+	if (beacon->WiderBWChanSwitchAnnPresent) {
+		psession_entry->gLimWiderBWChannelSwitch.newChanWidth =
+				widerchnl_switch->newChanWidth;
+		psession_entry->gLimWiderBWChannelSwitch.newCenterChanFreq0 =
+				widerchnl_switch->newCenterChanFreq0;
+		psession_entry->gLimWiderBWChannelSwitch.newCenterChanFreq1 =
+				widerchnl_switch->newCenterChanFreq1;
+	}
+	/* Only primary channel switch element is present */
+	ch_switch_params->state =
+			eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+	ch_switch_params->ch_width = CH_WIDTH_20MHZ;
+
+	/*
+	 * Do not bother to look and operate on extended channel switch element
+	 * if our own channel-bonding state is not enabled
+	 */
+	if (psession_entry->htSupportedChannelWidthSet &&
+			beacon->sec_chan_offset_present) {
+		if (beacon->sec_chan_offset.secondaryChannelOffset ==
+					PHY_DOUBLE_CHANNEL_LOW_PRIMARY) {
+			ch_switch_params->state =
+				    eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+			ch_switch_params->ch_width = CH_WIDTH_40MHZ;
+			ch_switch_params->ch_center_freq_seg0 =
+				ch_switch_params->primaryChannel + 2;
+		} else if (beacon->sec_chan_offset.secondaryChannelOffset ==
+				PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) {
+			ch_switch_params->state =
+				    eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+			ch_switch_params->ch_width = CH_WIDTH_40MHZ;
+			ch_switch_params->ch_center_freq_seg0 =
+				ch_switch_params->primaryChannel - 2;
+		}
+		if (psession_entry->vhtCapability &&
+			beacon->WiderBWChanSwitchAnnPresent) {
+			ch_switch_params->ch_width =
+				widerchnl_switch->newChanWidth + 1;
+			ch_switch_params->ch_center_freq_seg0 =
+				psession_entry->gLimWiderBWChannelSwitch.
+						newCenterChanFreq0;
+			ch_switch_params->ch_center_freq_seg1 =
+				psession_entry->gLimWiderBWChannelSwitch.
+						newCenterChanFreq1;
+		}
+	}
+	if (QDF_STATUS_SUCCESS != lim_start_channel_switch(mac_ctx, psession_entry))
+		pe_warn("Could not start Channel Switch");
+
+	pe_debug("session: %d primary chl: %d ch_width: %d count: %d (%d ticks)",
+		psession_entry->peSessionId,
+		psession_entry->gLimChannelSwitch.primaryChannel,
+		psession_entry->gLimChannelSwitch.ch_width,
+		psession_entry->gLimChannelSwitch.switchCount,
+		psession_entry->gLimChannelSwitch.switchTimeoutValue);
+	return;
+}
+
+/**
+ * lim_cancel_dot11h_channel_switch
+ *
+ ***FUNCTION:
+ * This function is called when STA does not send updated channel-swith IE
+ * after indicating channel-switch start. This will cancel the channel-swith
+ * timer which is already running.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param  pMac    - Pointer to Global MAC structure
+ *
+ * @return None
+ */
+void lim_cancel_dot11h_channel_switch(tpAniSirGlobal pMac,
+				      tpPESession psessionEntry)
+{
+	if (!LIM_IS_STA_ROLE(psessionEntry))
+		return;
+
+	pe_debug("Received a beacon without channel switch IE");
+
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+		       psessionEntry->peSessionId, eLIM_CHANNEL_SWITCH_TIMER));
+
+	if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) !=
+	    QDF_STATUS_SUCCESS) {
+		pe_err("tx_timer_deactivate failed!");
+	}
+
+	/* We need to restore pre-channelSwitch state on the STA */
+	if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
+	    QDF_STATUS_SUCCESS) {
+		pe_err("LIM: Could not restore pre-channelSwitch (11h) state, resetting the system");
+	}
+}
+
+/**
+ * lim_cancel_dot11h_quiet()
+ *
+ * @mac_ctx: pointer to global mac structure
+ * @psession_entry: pointer to tppesession
+ *
+ * Cancel the quieting on Station if latest beacon
+ * doesn't contain quiet IE in it.
+ *
+ * Return: none
+ */
+void lim_cancel_dot11h_quiet(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	if (!LIM_IS_STA_ROLE(psessionEntry))
+		return;
+
+	if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) {
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+			       psessionEntry->peSessionId, eLIM_QUIET_TIMER));
+		if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) !=
+		    TX_SUCCESS) {
+			pe_err("tx_timer_deactivate failed");
+		}
+	} else if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) {
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+			       psessionEntry->peSessionId, eLIM_QUIET_BSS_TIMER));
+		if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer)
+		    != TX_SUCCESS) {
+			pe_err("tx_timer_deactivate failed");
+		}
+		/**
+		 * If the channel switch is already running in silent mode, dont resume the
+		 * transmission. Channel switch timer when timeout, transmission will be resumed.
+		 */
+		if (!
+		    ((psessionEntry->gLimSpecMgmt.dot11hChanSwState ==
+		      eLIM_11H_CHANSW_RUNNING)
+		     && (psessionEntry->gLimChannelSwitch.switchMode ==
+			 eSIR_CHANSW_MODE_SILENT))) {
+			lim_frame_transmission_control(pMac, eLIM_TX_ALL,
+						       eLIM_RESUME_TX);
+			lim_restore_pre_quiet_state(pMac, psessionEntry);
+		}
+	}
+	psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+}
+
+/**
+ * lim_process_quiet_timeout
+ *
+ * FUNCTION:
+ * This function is active only on the STA.
+ * Handles SIR_LIM_QUIET_TIMEOUT
+ *
+ * LOGIC:
+ * This timeout can occur under only one circumstance:
+ *
+ * 1) When gLimQuietState = eLIM_QUIET_BEGIN
+ * This indicates that the timeout "interval" has
+ * expired. This is a trigger for the STA to now
+ * shut-off Tx/Rx for the specified gLimQuietDuration
+ * -> The TIMER object gLimQuietBssTimer is
+ * activated
+ * -> With timeout = gLimQuietDuration
+ * -> gLimQuietState is set to eLIM_QUIET_RUNNING
+ *
+ * ASSUMPTIONS:
+ * Using two TIMER objects -
+ * gLimQuietTimer & gLimQuietBssTimer
+ *
+ * NOTE:
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ *
+ * @return None
+ */
+void lim_process_quiet_timeout(tpAniSirGlobal pMac)
+{
+	tpPESession psessionEntry;
+
+	psessionEntry = pe_find_session_by_session_id(pMac,
+			pMac->lim.limTimers.gLimQuietTimer.sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+
+	pe_debug("quietState: %d", psessionEntry->gLimSpecMgmt.quietState);
+	switch (psessionEntry->gLimSpecMgmt.quietState) {
+	case eLIM_QUIET_BEGIN:
+		/* Time to Stop data traffic for quietDuration */
+		/* lim_deactivate_and_change_timer(pMac, eLIM_QUIET_BSS_TIMER); */
+		if (TX_SUCCESS != tx_timer_deactivate(
+				&pMac->lim.limTimers.gLimQuietBssTimer)) {
+			pe_err("Unable to de-activate gLimQuietBssTimer! Will attempt to activate anyway");
+		}
+		/* gLimQuietDuration appears to be in units of ticks */
+		/* Use it as is */
+		if (TX_SUCCESS !=
+		    tx_timer_change(&pMac->lim.limTimers.gLimQuietBssTimer,
+				    psessionEntry->gLimSpecMgmt.quietDuration,
+				    0)) {
+			pe_err("Unable to change gLimQuietBssTimer! Will still attempt to activate anyway");
+		}
+		MTRACE(mac_trace
+			       (pMac, TRACE_CODE_TIMER_ACTIVATE,
+			       pMac->lim.limTimers.gLimQuietTimer.sessionId,
+			       eLIM_QUIET_BSS_TIMER));
+		if (TX_SUCCESS !=
+		    tx_timer_activate(&pMac->lim.limTimers.gLimQuietBssTimer)) {
+			pe_warn("Unable to activate gLimQuietBssTimer! The STA will be unable to honor Quiet BSS");
+		} else {
+			/* Transition to eLIM_QUIET_RUNNING */
+			psessionEntry->gLimSpecMgmt.quietState =
+				eLIM_QUIET_RUNNING;
+			/* Shut-off Tx/Rx for gLimSpecMgmt.quietDuration */
+			/* freeze the transmission */
+			lim_frame_transmission_control(pMac, eLIM_TX_ALL,
+						       eLIM_STOP_TX);
+
+			pe_debug("Quiet BSS: STA shutting down for %d ticks",
+				psessionEntry->gLimSpecMgmt.quietDuration);
+		}
+		break;
+
+	case eLIM_QUIET_RUNNING:
+	case eLIM_QUIET_INIT:
+	case eLIM_QUIET_END:
+	default:
+		/* */
+		/* As of now, nothing to be done */
+		/* */
+		break;
+	}
+}
+
+/**
+ * lim_process_quiet_bss_timeout() - Handles SIR_LIM_QUIET_BSS_TIMEOUT
+ * @mac_ctx: pointer to Globale Mac Structure
+ *
+ * This function is active on the AP and STA.
+ * Handles SIR_LIM_QUIET_BSS_TIMEOUT
+ *
+ * On the AP -
+ * When the SIR_LIM_QUIET_BSS_TIMEOUT is triggered, it is
+ * an indication for the AP to START sending out the
+ * Quiet BSS IE.
+ * If 802.11H is enabled, the Quiet BSS IE is sent as per
+ * the 11H spec
+ * If 802.11H is not enabled, the Quiet BSS IE is sent as
+ * a Proprietary IE. This will be understood by all the
+ * TITAN STA's
+ * Transitioning gLimQuietState to eLIM_QUIET_BEGIN will
+ * initiate the SCH to include the Quiet BSS IE in all
+ * its subsequent Beacons/PR's.
+ * The Quiet BSS IE will be included in all the Beacons
+ * & PR's until the next DTIM period
+ *
+ * On the STA -
+ * When gLimQuietState = eLIM_QUIET_RUNNING
+ * This indicates that the STA was successfully shut-off
+ * for the specified gLimQuietDuration. This is a trigger
+ * for the STA to now resume data traffic.
+ * -> gLimQuietState is set to eLIM_QUIET_INIT
+ *
+ *
+ * Return: none
+ */
+void lim_process_quiet_bss_timeout(tpAniSirGlobal mac_ctx)
+{
+	tpPESession psession_entry = NULL;
+	tLimTimers *lim_timer = &mac_ctx->lim.limTimers;
+
+	psession_entry = pe_find_session_by_session_id(mac_ctx,
+					lim_timer->gLimQuietBssTimer.sessionId);
+
+	if (psession_entry == NULL) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+
+	pe_debug("quietState: %d",
+			psession_entry->gLimSpecMgmt.quietState);
+
+	if (LIM_IS_AP_ROLE(psession_entry))
+		return;
+
+	/* eLIM_STA_ROLE */
+	switch (psession_entry->gLimSpecMgmt.quietState) {
+	case eLIM_QUIET_RUNNING:
+		/* Transition to eLIM_QUIET_INIT */
+		psession_entry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+
+		/*
+		 * Resume data traffic only if channel switch is
+		 * not running in silent mode.
+		 */
+		if (!((psession_entry->gLimSpecMgmt.dot11hChanSwState ==
+				eLIM_11H_CHANSW_RUNNING) &&
+			(psession_entry->gLimChannelSwitch.switchMode ==
+				eSIR_CHANSW_MODE_SILENT))) {
+			lim_frame_transmission_control(mac_ctx, eLIM_TX_ALL,
+				eLIM_RESUME_TX);
+			lim_restore_pre_quiet_state(mac_ctx, psession_entry);
+		}
+		pe_debug("Quiet BSS: Resuming traffic");
+		break;
+
+	case eLIM_QUIET_INIT:
+	case eLIM_QUIET_BEGIN:
+	case eLIM_QUIET_END:
+		pe_debug("Quiet state not in RUNNING");
+		/*
+		 * If the quiet period has ended, then resume the
+		 * frame transmission
+		 */
+		lim_frame_transmission_control(mac_ctx, eLIM_TX_ALL,
+					eLIM_RESUME_TX);
+		lim_restore_pre_quiet_state(mac_ctx, psession_entry);
+		psession_entry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+		break;
+
+	default:
+		/* As of now, nothing to be done */
+		break;
+	}
+}
+
+/**----------------------------------------------
+   \fn        lim_start_quiet_timer
+   \brief    Starts the quiet timer.
+
+   \param pMac
+   \return NONE
+   -----------------------------------------------*/
+void lim_start_quiet_timer(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	tpPESession psessionEntry;
+
+	psessionEntry = pe_find_session_by_session_id(pMac, sessionId);
+
+	if (psessionEntry == NULL) {
+		pe_err("Session Does not exist for given sessionID");
+		return;
+	}
+
+	if (!LIM_IS_STA_ROLE(psessionEntry))
+		return;
+	/* First, de-activate Timer, if its already active */
+	lim_cancel_dot11h_quiet(pMac, psessionEntry);
+
+	MTRACE(mac_trace
+		       (pMac, TRACE_CODE_TIMER_ACTIVATE, sessionId, eLIM_QUIET_TIMER));
+	if (TX_SUCCESS !=
+	    tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer)) {
+		pe_err("Unable to deactivate gLimQuietTimer! Will still attempt to re-activate anyway");
+	}
+	/* Set the NEW timeout value, in ticks */
+	if (TX_SUCCESS != tx_timer_change(&pMac->lim.limTimers.gLimQuietTimer,
+					  SYS_MS_TO_TICKS(psessionEntry->
+							  gLimSpecMgmt.
+							  quietTimeoutValue),
+					  0)) {
+		pe_err("Unable to change gLimQuietTimer! Will still attempt to re-activate anyway");
+	}
+
+	pMac->lim.limTimers.gLimQuietTimer.sessionId = sessionId;
+	if (TX_SUCCESS !=
+	    tx_timer_activate(&pMac->lim.limTimers.gLimQuietTimer)) {
+		pe_err("Unable to activate gLimQuietTimer! STA cannot honor Quiet BSS!");
+		lim_restore_pre_quiet_state(pMac, psessionEntry);
+
+		psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+		return;
+	}
+}
+
+/** ------------------------------------------------------------------------ **/
+/**
+ * keep track of the number of ANI peers associated in the BSS
+ * For the first and last ANI peer, we have to update EDCA params as needed
+ *
+ * When the first ANI peer joins the BSS, we notify SCH
+ * When the last ANI peer leaves the BSS, we notfiy SCH
+ */
+void
+lim_util_count_sta_add(tpAniSirGlobal pMac,
+		       tpDphHashNode pSta, tpPESession psessionEntry)
+{
+
+	if ((!pSta) || (!pSta->valid) || (pSta->fAniCount))
+		return;
+
+	pSta->fAniCount = 1;
+
+	if (pMac->lim.gLimNumOfAniSTAs++ != 0)
+		return;
+
+	/* get here only if this is the first ANI peer in the BSS */
+	sch_edca_profile_update(pMac, psessionEntry);
+}
+
+void
+lim_util_count_sta_del(tpAniSirGlobal pMac,
+		       tpDphHashNode pSta, tpPESession psessionEntry)
+{
+
+	if ((pSta == NULL) || (!pSta->fAniCount))
+		return;
+
+	/* Only if sta is invalid and the validInDummyState bit is set to 1,
+	 * then go ahead and update the count and profiles. This ensures
+	 * that the "number of ani station" count is properly incremented/decremented.
+	 */
+	if (pSta->valid == 1)
+		return;
+
+	pSta->fAniCount = 0;
+
+	if (pMac->lim.gLimNumOfAniSTAs <= 0) {
+		pe_err("CountStaDel: ignoring Delete Req when AniPeer count: %d",
+			pMac->lim.gLimNumOfAniSTAs);
+		return;
+	}
+
+	pMac->lim.gLimNumOfAniSTAs--;
+
+	if (pMac->lim.gLimNumOfAniSTAs != 0)
+		return;
+
+	/* get here only if this is the last ANI peer in the BSS */
+	sch_edca_profile_update(pMac, psessionEntry);
+}
+
+/**
+ * lim_switch_channel_cback()
+ *
+ ***FUNCTION:
+ *  This is the callback function registered while requesting to switch channel
+ *  after AP indicates a channel switch for spectrum management (11h).
+ *
+ ***NOTE:
+ * @param  pMac               Pointer to Global MAC structure
+ * @param  status             Status of channel switch request
+ * @param  data               User data
+ * @param  psessionEntry      Session information
+ * @return NONE
+ */
+void lim_switch_channel_cback(tpAniSirGlobal pMac, QDF_STATUS status,
+			      uint32_t *data, tpPESession psessionEntry)
+{
+	struct scheduler_msg mmhMsg = { 0 };
+	tSirSmeSwitchChannelInd *pSirSmeSwitchChInd;
+
+	psessionEntry->currentOperChannel = psessionEntry->currentReqChannel;
+
+	/* We need to restore pre-channelSwitch state on the STA */
+	if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
+	    QDF_STATUS_SUCCESS) {
+		pe_err("Could not restore pre-channelSwitch (11h) state, resetting the system");
+		return;
+	}
+
+	mmhMsg.type = eWNI_SME_SWITCH_CHL_IND;
+	pSirSmeSwitchChInd = qdf_mem_malloc(sizeof(tSirSmeSwitchChannelInd));
+	if (!pSirSmeSwitchChInd)
+		return;
+
+	pSirSmeSwitchChInd->messageType = eWNI_SME_SWITCH_CHL_IND;
+	pSirSmeSwitchChInd->length = sizeof(tSirSmeSwitchChannelInd);
+	pSirSmeSwitchChInd->newChannelId =
+		psessionEntry->gLimChannelSwitch.primaryChannel;
+	pSirSmeSwitchChInd->sessionId = psessionEntry->smeSessionId;
+	pSirSmeSwitchChInd->chan_params.ch_width =
+			psessionEntry->gLimChannelSwitch.ch_width;
+	pSirSmeSwitchChInd->chan_params.sec_ch_offset =
+			psessionEntry->gLimChannelSwitch.sec_ch_offset;
+	pSirSmeSwitchChInd->chan_params.center_freq_seg0 =
+			psessionEntry->gLimChannelSwitch.ch_center_freq_seg0;
+	pSirSmeSwitchChInd->chan_params.center_freq_seg1 =
+			psessionEntry->gLimChannelSwitch.ch_center_freq_seg1;
+
+	pe_debug("session: %d chan: %d width: %d sec offset: %d seg0: %d seg1: %d",
+		pSirSmeSwitchChInd->sessionId,
+		pSirSmeSwitchChInd->newChannelId,
+		pSirSmeSwitchChInd->chan_params.ch_width,
+		pSirSmeSwitchChInd->chan_params.sec_ch_offset,
+		pSirSmeSwitchChInd->chan_params.center_freq_seg0,
+		pSirSmeSwitchChInd->chan_params.center_freq_seg1);
+
+	qdf_mem_copy(pSirSmeSwitchChInd->bssid.bytes, psessionEntry->bssId,
+		     QDF_MAC_ADDR_SIZE);
+	mmhMsg.bodyptr = pSirSmeSwitchChInd;
+	mmhMsg.bodyval = 0;
+
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+			 psessionEntry->peSessionId, mmhMsg.type));
+
+	sys_process_mmh_msg(pMac, &mmhMsg);
+}
+
+/**
+ * lim_switch_primary_channel()
+ *
+ ***FUNCTION:
+ *  This function changes the current operating channel
+ *  and sets the new new channel ID in WNI_CFG_CURRENT_CHANNEL.
+ *
+ ***NOTE:
+ * @param  pMac        Pointer to Global MAC structure
+ * @param  newChannel  new chnannel ID
+ * @return NONE
+ */
+void lim_switch_primary_channel(tpAniSirGlobal pMac, uint8_t newChannel,
+				tpPESession psessionEntry)
+{
+	pe_debug("old chnl: %d --> new chnl: %d",
+		       psessionEntry->currentOperChannel, newChannel);
+
+	psessionEntry->currentReqChannel = newChannel;
+	psessionEntry->limRFBand = lim_get_rf_band(newChannel);
+
+	psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION;
+
+	pMac->lim.gpchangeChannelCallback = lim_switch_channel_cback;
+	pMac->lim.gpchangeChannelData = NULL;
+
+	lim_send_switch_chnl_params(pMac, newChannel, 0, 0, CH_WIDTH_20MHZ,
+				    psessionEntry->maxTxPower,
+				    psessionEntry->peSessionId, false, 0, 0);
+	return;
+}
+
+/**
+ * lim_switch_primary_secondary_channel()
+ *
+ ***FUNCTION:
+ *  This function changes the primary and secondary channel.
+ *  If 11h is enabled and user provides a "new channel ID"
+ *  that is different from the current operating channel,
+ *  then we must set this new channel in WNI_CFG_CURRENT_CHANNEL,
+ *  assign notify LIM of such change.
+ *
+ ***NOTE:
+ * @param  pMac        Pointer to Global MAC structure
+ * @param  newChannel  New chnannel ID (or current channel ID)
+ * @param  subband     CB secondary info:
+ *                       - eANI_CB_SECONDARY_NONE
+ *                       - eANI_CB_SECONDARY_UP
+ *                       - eANI_CB_SECONDARY_DOWN
+ * @return NONE
+ */
+void lim_switch_primary_secondary_channel(tpAniSirGlobal pMac,
+					tpPESession psessionEntry,
+					uint8_t newChannel,
+					uint8_t ch_center_freq_seg0,
+					uint8_t ch_center_freq_seg1,
+					enum phy_ch_width ch_width)
+{
+
+	/* Assign the callback to resume TX once channel is changed. */
+	psessionEntry->currentReqChannel = newChannel;
+	psessionEntry->limRFBand = lim_get_rf_band(newChannel);
+	psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION;
+	pMac->lim.gpchangeChannelCallback = lim_switch_channel_cback;
+	pMac->lim.gpchangeChannelData = NULL;
+
+	lim_send_switch_chnl_params(pMac, newChannel, ch_center_freq_seg0,
+					ch_center_freq_seg1, ch_width,
+					psessionEntry->maxTxPower,
+					psessionEntry->peSessionId,
+					false, 0, 0);
+
+	/* Store the new primary and secondary channel in session entries if different */
+	if (psessionEntry->currentOperChannel != newChannel) {
+		pe_warn("switch old chnl: %d --> new chnl: %d",
+			psessionEntry->currentOperChannel, newChannel);
+		psessionEntry->currentOperChannel = newChannel;
+	}
+	if (psessionEntry->htSecondaryChannelOffset !=
+			psessionEntry->gLimChannelSwitch.sec_ch_offset) {
+		pe_warn("switch old sec chnl: %d --> new sec chnl: %d",
+			psessionEntry->htSecondaryChannelOffset,
+			psessionEntry->gLimChannelSwitch.sec_ch_offset);
+		psessionEntry->htSecondaryChannelOffset =
+			psessionEntry->gLimChannelSwitch.sec_ch_offset;
+		if (psessionEntry->htSecondaryChannelOffset ==
+		    PHY_SINGLE_CHANNEL_CENTERED) {
+			psessionEntry->htSupportedChannelWidthSet =
+				WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+		} else {
+			psessionEntry->htSupportedChannelWidthSet =
+				WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
+		}
+		psessionEntry->htRecommendedTxWidthSet =
+			psessionEntry->htSupportedChannelWidthSet;
+	}
+
+	return;
+}
+
+/**
+ * lim_get_ht_capability()
+ *
+ ***FUNCTION:
+ * A utility function that returns the "current HT capability state" for the HT
+ * capability of interest (as requested in the API)
+ *
+ ***LOGIC:
+ * This routine will return with the "current" setting of a requested HT
+ * capability. This state info could be retrieved from -
+ * a) CFG (for static entries)
+ * b) Run time info
+ *   - Dynamic state maintained by LIM
+ *   - Configured at radio init time by SME
+ *
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param  pMac  Pointer to Global MAC structure
+ * @param  htCap The HT capability being queried
+ * @return uint8_t The current state of the requested HT capability is returned in a
+ *            uint8_t variable
+ */
+
+uint8_t lim_get_ht_capability(tpAniSirGlobal pMac,
+			      uint32_t htCap, tpPESession psessionEntry)
+{
+	uint8_t retVal = 0;
+	uint8_t *ptr;
+	uint32_t cfgValue;
+	tSirMacTxBFCapabilityInfo macTxBFCapabilityInfo = { 0 };
+	tSirMacASCapabilityInfo macASCapabilityInfo = { 0 };
+
+	/* */
+	/* Determine which CFG to read from. Not ALL of the HT */
+	/* related CFG's need to be read each time this API is */
+	/* accessed */
+	/* */
+	if (htCap >= eHT_ANTENNA_SELECTION && htCap < eHT_SI_GRANULARITY) {
+		/* Get Antenna Seletion HT Capabilities */
+		if (QDF_STATUS_SUCCESS !=
+		    wlan_cfg_get_int(pMac, WNI_CFG_AS_CAP, &cfgValue))
+			cfgValue = 0;
+		ptr = (uint8_t *) &macASCapabilityInfo;
+		*((uint8_t *) ptr) = (uint8_t) (cfgValue & 0xff);
+	} else if (htCap >= eHT_TX_BEAMFORMING &&
+		   htCap < eHT_ANTENNA_SELECTION) {
+		/* Get Transmit Beam Forming HT Capabilities */
+		if (QDF_STATUS_SUCCESS !=
+		    wlan_cfg_get_int(pMac, WNI_CFG_TX_BF_CAP, &cfgValue))
+			cfgValue = 0;
+		ptr = (uint8_t *)&macTxBFCapabilityInfo;
+		*((uint32_t *)ptr) = (uint32_t)(cfgValue);
+	}
+
+	switch (htCap) {
+	case eHT_LSIG_TXOP_PROTECTION:
+		retVal = pMac->lim.gHTLsigTXOPProtection;
+		break;
+
+	case eHT_STBC_CONTROL_FRAME:
+		retVal = (uint8_t)pMac->mlme_cfg->ht_caps.ht_cap_info.
+			stbc_control_frame;
+		break;
+
+	case eHT_PSMP:
+		retVal = pMac->lim.gHTPSMPSupport;
+		break;
+
+	case eHT_DSSS_CCK_MODE_40MHZ:
+		retVal = pMac->lim.gHTDsssCckRate40MHzSupport;
+		break;
+
+	case eHT_MAX_AMSDU_LENGTH:
+		retVal = (uint8_t)pMac->mlme_cfg->ht_caps.ht_cap_info.
+			maximal_amsdu_size;
+		break;
+
+	case eHT_MAX_AMSDU_NUM:
+		retVal = (uint8_t) psessionEntry->max_amsdu_num;
+		break;
+
+	case eHT_RX_STBC:
+		retVal = (uint8_t) psessionEntry->htConfig.ht_rx_stbc;
+		break;
+
+	case eHT_TX_STBC:
+		retVal = (uint8_t) psessionEntry->htConfig.ht_tx_stbc;
+		break;
+
+	case eHT_SHORT_GI_40MHZ:
+		retVal = (uint8_t)(psessionEntry->htConfig.ht_sgi40) ?
+			pMac->mlme_cfg->ht_caps.ht_cap_info.short_gi_40_mhz : 0;
+		break;
+
+	case eHT_SHORT_GI_20MHZ:
+		retVal = (uint8_t)(psessionEntry->htConfig.ht_sgi20) ?
+			pMac->mlme_cfg->ht_caps.ht_cap_info.short_gi_20_mhz : 0;
+		break;
+
+	case eHT_GREENFIELD:
+		retVal = (uint8_t)pMac->mlme_cfg->ht_caps.ht_cap_info.
+			green_field;
+		break;
+
+	case eHT_MIMO_POWER_SAVE:
+		retVal = (uint8_t) pMac->lim.gHTMIMOPSState;
+		break;
+
+	case eHT_SUPPORTED_CHANNEL_WIDTH_SET:
+		retVal = (uint8_t) psessionEntry->htSupportedChannelWidthSet;
+		break;
+
+	case eHT_ADVANCED_CODING:
+		retVal = (uint8_t) psessionEntry->htConfig.ht_rx_ldpc;
+		break;
+
+	case eHT_MAX_RX_AMPDU_FACTOR:
+		retVal = pMac->lim.gHTMaxRxAMpduFactor;
+		break;
+
+	case eHT_MPDU_DENSITY:
+		retVal = pMac->lim.gHTAMpduDensity;
+		break;
+
+	case eHT_PCO:
+		retVal = (uint8_t)pMac->mlme_cfg->ht_caps.ext_cap_info.pco;
+		break;
+
+	case eHT_TRANSITION_TIME:
+		retVal = (uint8_t)pMac->mlme_cfg->ht_caps.ext_cap_info.
+			transition_time;
+		break;
+
+	case eHT_MCS_FEEDBACK:
+		retVal = (uint8_t)pMac->mlme_cfg->ht_caps.ext_cap_info.
+			mcs_feedback;
+		break;
+
+	case eHT_TX_BEAMFORMING:
+		retVal = (uint8_t) macTxBFCapabilityInfo.txBF;
+		break;
+
+	case eHT_ANTENNA_SELECTION:
+		retVal = (uint8_t) macASCapabilityInfo.antennaSelection;
+		break;
+
+	case eHT_SI_GRANULARITY:
+		retVal = pMac->lim.gHTServiceIntervalGranularity;
+		break;
+
+	case eHT_CONTROLLED_ACCESS:
+		retVal = pMac->lim.gHTControlledAccessOnly;
+		break;
+
+	case eHT_RIFS_MODE:
+		retVal = psessionEntry->beaconParams.fRIFSMode;
+		break;
+
+	case eHT_RECOMMENDED_TX_WIDTH_SET:
+		retVal = psessionEntry->htRecommendedTxWidthSet;
+		break;
+
+	case eHT_EXTENSION_CHANNEL_OFFSET:
+		retVal = psessionEntry->htSecondaryChannelOffset;
+		break;
+
+	case eHT_OP_MODE:
+		if (LIM_IS_AP_ROLE(psessionEntry))
+			retVal = psessionEntry->htOperMode;
+		else
+			retVal = pMac->lim.gHTOperMode;
+		break;
+
+	case eHT_BASIC_STBC_MCS:
+		retVal = pMac->lim.gHTSTBCBasicMCS;
+		break;
+
+	case eHT_DUAL_CTS_PROTECTION:
+		retVal = pMac->lim.gHTDualCTSProtection;
+		break;
+
+	case eHT_LSIG_TXOP_PROTECTION_FULL_SUPPORT:
+		retVal =
+			psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport;
+		break;
+
+	case eHT_PCO_ACTIVE:
+		retVal = pMac->lim.gHTPCOActive;
+		break;
+
+	case eHT_PCO_PHASE:
+		retVal = pMac->lim.gHTPCOPhase;
+		break;
+
+	default:
+		break;
+	}
+
+	return retVal;
+}
+
+/**
+ * lim_enable_11a_protection() - updates protection params for enable 11a
+ * protection request
+ * @mac_ctx:    pointer to Global MAC structure
+ * @overlap:    1=> called from overlap context, 0 => called from assoc context.
+ * @bcn_prms:   beacon parameters
+ * @pe_session: pe session entry
+ *
+ * This function updates protection params for enable 11a protection request
+ *
+ * @Return: void
+ */
+static void
+lim_enable_11a_protection(tpAniSirGlobal mac_ctx,
+			 uint8_t overlap,
+			 tpUpdateBeaconParams bcn_prms,
+			 tpPESession pe_session)
+{
+	/*
+	 * If we are AP and HT capable, we need to set the HT OP mode
+	 * appropriately.
+	 */
+	if (LIM_IS_AP_ROLE(pe_session) && (true == pe_session->htCapability)) {
+		if (overlap) {
+			pe_session->gLimOverlap11aParams.protectionEnabled =
+				true;
+			if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
+			    mac_ctx->lim.gHTOperMode)
+				&& (eSIR_HT_OP_MODE_MIXED !=
+				    mac_ctx->lim.gHTOperMode)) {
+				mac_ctx->lim.gHTOperMode =
+					eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+				pe_session->htOperMode =
+					eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+				lim_enable_ht_rifs_protection(mac_ctx, true,
+					overlap, bcn_prms, pe_session);
+				lim_enable_ht_obss_protection(mac_ctx, true,
+					overlap, bcn_prms, pe_session);
+			}
+		} else {
+			pe_session->gLim11aParams.protectionEnabled = true;
+			if (eSIR_HT_OP_MODE_MIXED != pe_session->htOperMode) {
+				mac_ctx->lim.gHTOperMode =
+					eSIR_HT_OP_MODE_MIXED;
+				pe_session->htOperMode = eSIR_HT_OP_MODE_MIXED;
+				lim_enable_ht_rifs_protection(mac_ctx, true,
+					overlap, bcn_prms, pe_session);
+				lim_enable_ht_obss_protection(mac_ctx, true,
+					overlap, bcn_prms, pe_session);
+			}
+		}
+	}
+	/* This part is common for station as well. */
+	if (false == pe_session->beaconParams.llaCoexist) {
+		pe_debug(" => protection from 11A Enabled");
+		bcn_prms->llaCoexist = true;
+		pe_session->beaconParams.llaCoexist = true;
+		bcn_prms->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
+	}
+}
+
+/**
+ * lim_disable_11a_protection() - updates protection params for disable 11a
+ * protection request
+ * @mac_ctx:    pointer to Global MAC structure
+ * @overlap:    1=> called from overlap context, 0 => called from assoc context.
+ * @bcn_prms:   beacon parameters
+ * @pe_session: pe session entry
+ *
+ * This function updates protection params for disable 11a protection request
+ *
+ * @Return: void
+ */
+static void
+lim_disable_11a_protection(tpAniSirGlobal mac_ctx,
+			   uint8_t overlap,
+			   tpUpdateBeaconParams bcn_prms,
+			   tpPESession pe_session)
+{
+	if (false == pe_session->beaconParams.llaCoexist)
+		return;
+
+	/* for station role */
+	if (!LIM_IS_AP_ROLE(pe_session)) {
+		pe_debug("===> Protection from 11A Disabled");
+		bcn_prms->llaCoexist = false;
+		pe_session->beaconParams.llaCoexist = false;
+		bcn_prms->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
+		return;
+	}
+	/*
+	 * for AP role.
+	 * we need to take care of HT OP mode change if needed.
+	 * We need to take care of Overlap cases.
+	 */
+	if (overlap) {
+		/* Overlap Legacy protection disabled. */
+		pe_session->gLimOverlap11aParams.protectionEnabled = false;
+
+		/*
+		 * We need to take care of HT OP mode iff we are HT AP.
+		 * OR no HT op-mode change is needed if any of the overlap
+		 * protection enabled.
+		 */
+		if (!pe_session->htCapability ||
+		     (pe_session->gLimOverlap11aParams.protectionEnabled
+		     || pe_session->gLimOverlapHt20Params.protectionEnabled
+		     || pe_session->gLimOverlapNonGfParams.protectionEnabled))
+			goto disable_11a_end;
+
+		/* Check if there is a need to change HT OP mode. */
+		if (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+		    mac_ctx->lim.gHTOperMode) {
+			lim_enable_ht_rifs_protection(mac_ctx, false, overlap,
+						      bcn_prms, pe_session);
+			lim_enable_ht_obss_protection(mac_ctx, false, overlap,
+						      bcn_prms, pe_session);
+
+			if (pe_session->gLimHt20Params.protectionEnabled)
+				mac_ctx->lim.gHTOperMode =
+					eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+			else
+				mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+		}
+	} else {
+		/* Disable protection from 11A stations. */
+		pe_session->gLim11aParams.protectionEnabled = false;
+		lim_enable_ht_obss_protection(mac_ctx, false, overlap,
+					      bcn_prms, pe_session);
+
+		/*
+		 * Check if any other non-HT protection enabled. Right now we
+		 * are in HT OP Mixed mode. Change HT op mode appropriately.
+		 */
+
+		/* Change HT OP mode to 01 if any overlap protection enabled */
+		if (pe_session->gLimOverlap11aParams.protectionEnabled
+		    || pe_session->gLimOverlapHt20Params.protectionEnabled
+		    || pe_session->gLimOverlapNonGfParams.protectionEnabled) {
+			mac_ctx->lim.gHTOperMode =
+				eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+			pe_session->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+			lim_enable_ht_rifs_protection(mac_ctx, true, overlap,
+						      bcn_prms, pe_session);
+		} else if (pe_session->gLimHt20Params.protectionEnabled) {
+			mac_ctx->lim.gHTOperMode =
+				eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+			pe_session->htOperMode =
+				eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+			lim_enable_ht_rifs_protection(mac_ctx, false, overlap,
+						      bcn_prms, pe_session);
+		} else {
+			mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+			pe_session->htOperMode = eSIR_HT_OP_MODE_PURE;
+			lim_enable_ht_rifs_protection(mac_ctx, false, overlap,
+						      bcn_prms, pe_session);
+		}
+	}
+
+disable_11a_end:
+	if (!pe_session->gLimOverlap11aParams.protectionEnabled &&
+	    !pe_session->gLim11aParams.protectionEnabled) {
+		pe_warn("===> Protection from 11A Disabled");
+		bcn_prms->llaCoexist = false;
+		pe_session->beaconParams.llaCoexist = false;
+		bcn_prms->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
+	}
+}
+
+/**
+ * lim_update_11a_protection() - based on config setting enables\disables 11a
+ * protection.
+ * @mac_ctx:    pointer to Global MAC structure
+ * @enable:     1=> enable protection, 0=> disable protection.
+ * @overlap:    1=> called from overlap context, 0 => called from assoc context.
+ * @bcn_prms:   beacon parameters
+ * @session:    pe session entry
+ *
+ * This based on config setting enables\disables 11a protection.
+ *
+ * @Return: success of failure of operation
+ */
+QDF_STATUS
+lim_update_11a_protection(tpAniSirGlobal mac_ctx, uint8_t enable,
+			 uint8_t overlap, tpUpdateBeaconParams bcn_prms,
+			 tpPESession session)
+{
+	if (NULL == session) {
+		pe_err("session is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* overlapping protection configuration check. */
+	if (!overlap) {
+		/* normal protection config check */
+		if ((LIM_IS_AP_ROLE(session)) &&
+		    (!session->cfgProtection.fromlla)) {
+			/* protection disabled. */
+			pe_warn("protection from 11a is disabled");
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	if (enable)
+		lim_enable_11a_protection(mac_ctx, overlap, bcn_prms, session);
+	else
+		lim_disable_11a_protection(mac_ctx, overlap, bcn_prms, session);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_handle_enable11g_protection_enabled() - handle 11g protection enabled
+ * @mac_ctx: pointer to Globale Mac structure
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @overlap: 1=> called from overlap context, 0 => called from assoc context.
+ * @session_entry: pointer to tpPESession
+ *
+ * Function handles 11g protection enaled case
+ *
+ * Return: none
+ */
+static void
+lim_handle_enable11g_protection_enabled(tpAniSirGlobal mac_ctx,
+			tpUpdateBeaconParams beaconparams,
+			uint8_t overlap, tpPESession session_entry)
+{
+	/*
+	 * If we are AP and HT capable, we need to set the HT OP mode
+	 * appropriately.
+	 */
+	if (LIM_IS_AP_ROLE(session_entry) && overlap) {
+		session_entry->gLimOlbcParams.protectionEnabled = true;
+
+		pe_debug("protection from olbc is enabled");
+
+		if (true == session_entry->htCapability) {
+			if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
+				session_entry->htOperMode) &&
+				(eSIR_HT_OP_MODE_MIXED !=
+				session_entry->htOperMode)) {
+				session_entry->htOperMode =
+					eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+			}
+			/*
+			 * CR-263021: OBSS bit is not switching back to 0 after
+			 * disabling the overlapping legacy BSS
+			 */
+			/*
+			 * This fixes issue of OBSS bit not set after 11b, 11g
+			 * station leaves
+			 */
+			lim_enable_ht_rifs_protection(mac_ctx, true,
+					overlap, beaconparams, session_entry);
+			/*
+			 * Not processing OBSS bit from other APs, as we are
+			 * already taking care of Protection from overlapping
+			 * BSS based on erp IE or useProtection bit
+			 */
+			lim_enable_ht_obss_protection(mac_ctx, true,
+					overlap, beaconparams, session_entry);
+		}
+	} else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
+		session_entry->gLim11bParams.protectionEnabled = true;
+		pe_debug("protection from 11b is enabled");
+		if (true == session_entry->htCapability) {
+			if (eSIR_HT_OP_MODE_MIXED !=
+				session_entry->htOperMode) {
+				session_entry->htOperMode =
+					eSIR_HT_OP_MODE_MIXED;
+				lim_enable_ht_rifs_protection(mac_ctx,
+						true, overlap, beaconparams,
+						session_entry);
+				lim_enable_ht_obss_protection(mac_ctx,
+						true, overlap, beaconparams,
+						session_entry);
+			}
+		}
+	}
+
+	/* This part is common for staiton as well. */
+	if (false == session_entry->beaconParams.llbCoexist) {
+		pe_debug("=> 11G Protection Enabled");
+		beaconparams->llbCoexist =
+			session_entry->beaconParams.llbCoexist = true;
+		beaconparams->paramChangeBitmap |=
+			PARAM_llBCOEXIST_CHANGED;
+	}
+}
+
+/**
+ * lim_handle_11g_protection_for_11bcoexist() - 11g protection for 11b co-ex
+ * @mac_ctx: pointer to Globale Mac structure
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @overlap: 1=> called from overlap context, 0 => called from assoc context.
+ * @session_entry: pointer to tpPESession
+ *
+ * Function handles 11g protection for 11b co-exist
+ *
+ * Return: none
+ */
+static void
+lim_handle_11g_protection_for_11bcoexist(tpAniSirGlobal mac_ctx,
+			tpUpdateBeaconParams beaconparams,
+			uint8_t overlap, tpPESession session_entry)
+{
+	/*
+	 * For AP role:
+	 * we need to take care of HT OP mode change if needed.
+	 * We need to take care of Overlap cases.
+	 */
+	if (LIM_IS_AP_ROLE(session_entry) && overlap) {
+		/* Overlap Legacy protection disabled. */
+		session_entry->gLimOlbcParams.protectionEnabled = false;
+
+		/* We need to take care of HT OP mode if we are HT AP. */
+		if (session_entry->htCapability) {
+			/*
+			 * no HT op mode change if any of the overlap
+			 * protection enabled.
+			 */
+			if (!(session_entry->gLimOverlap11gParams.
+					protectionEnabled ||
+				session_entry->gLimOverlapHt20Params.
+					protectionEnabled ||
+				session_entry->gLimOverlapNonGfParams.
+					protectionEnabled) &&
+				/*
+				 * Check if there is a need to change HT
+				 * OP mode.
+				 */
+				(eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+						session_entry->htOperMode)) {
+				lim_enable_ht_rifs_protection(mac_ctx, false,
+					overlap, beaconparams, session_entry);
+				lim_enable_ht_obss_protection(mac_ctx, false,
+					overlap, beaconparams, session_entry);
+				if (session_entry->gLimHt20Params.
+						protectionEnabled) {
+				if (eHT_CHANNEL_WIDTH_20MHZ ==
+					session_entry->htSupportedChannelWidthSet)
+					session_entry->htOperMode =
+						eSIR_HT_OP_MODE_PURE;
+				else
+					session_entry->htOperMode =
+					eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+				} else
+					session_entry->htOperMode =
+						eSIR_HT_OP_MODE_PURE;
+			}
+		}
+	} else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
+		/* Disable protection from 11B stations. */
+		session_entry->gLim11bParams.protectionEnabled = false;
+		pe_debug("===> 11B Protection Disabled");
+		/* Check if any other non-HT protection enabled. */
+		if (!session_entry->gLim11gParams.protectionEnabled) {
+			/* Right now we are in HT OP Mixed mode. */
+			/* Change HT op mode appropriately. */
+			lim_enable_ht_obss_protection(mac_ctx, false, overlap,
+					beaconparams, session_entry);
+			/*
+			 * Change HT OP mode to 01 if any overlap protection
+			 * enabled
+			 */
+			if (session_entry->gLimOlbcParams.protectionEnabled ||
+				session_entry->gLimOverlap11gParams.
+					protectionEnabled ||
+				session_entry->gLimOverlapHt20Params.
+					protectionEnabled ||
+				session_entry->gLimOverlapNonGfParams.
+					protectionEnabled) {
+				session_entry->htOperMode =
+					eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+				pe_debug("===> 11G Protection Disabled");
+				lim_enable_ht_rifs_protection(mac_ctx, true,
+						overlap, beaconparams,
+						session_entry);
+			} else if (session_entry->gLimHt20Params.
+						protectionEnabled) {
+				/* Commenting because of CR 258588 WFA cert */
+				/* session_entry->htOperMode =
+				eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; */
+				session_entry->htOperMode =
+						eSIR_HT_OP_MODE_PURE;
+				pe_debug("===> 11G Protection Disabled");
+				lim_enable_ht_rifs_protection(mac_ctx, false,
+						overlap, beaconparams,
+						session_entry);
+			} else {
+				session_entry->htOperMode =
+						eSIR_HT_OP_MODE_PURE;
+				lim_enable_ht_rifs_protection(mac_ctx, false,
+						overlap, beaconparams,
+						session_entry);
+			}
+		}
+	}
+	if (LIM_IS_AP_ROLE(session_entry)) {
+		if (!session_entry->gLimOlbcParams.protectionEnabled &&
+			!session_entry->gLim11bParams.protectionEnabled) {
+			pe_debug("===> 11G Protection Disabled");
+			beaconparams->llbCoexist =
+				session_entry->beaconParams.llbCoexist =
+							false;
+			beaconparams->paramChangeBitmap |=
+				PARAM_llBCOEXIST_CHANGED;
+		}
+	}
+	/* For station role */
+	if (!LIM_IS_AP_ROLE(session_entry)) {
+		pe_debug("===> 11G Protection Disabled");
+		beaconparams->llbCoexist =
+			session_entry->beaconParams.llbCoexist = false;
+		beaconparams->paramChangeBitmap |=
+			PARAM_llBCOEXIST_CHANGED;
+	}
+}
+
+/**
+ * lim_enable11g_protection() - Function to enable 11g protection
+ * @mac_ctx: pointer to Global Mac structure
+ * @enable: 1=> enable protection, 0=> disable protection.
+ * @overlap: 1=> called from overlap context, 0 => called from assoc context.
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @session_entry: pointer to tpPESession
+ *
+ * based on config setting enables\disables 11g protection.
+ *
+ * Return: Success - QDF_STATUS_SUCCESS - Success, Error number - Failure
+ */
+QDF_STATUS
+lim_enable11g_protection(tpAniSirGlobal mac_ctx, uint8_t enable,
+			 uint8_t overlap, tpUpdateBeaconParams beaconparams,
+			 tpPESession session_entry)
+{
+
+	/* overlapping protection configuration check. */
+	if (!overlap) {
+		/* normal protection config check */
+		if ((LIM_IS_AP_ROLE(session_entry)) &&
+			!session_entry->cfgProtection.fromllb) {
+			/* protection disabled. */
+			pe_debug("protection from 11b is disabled");
+			return QDF_STATUS_SUCCESS;
+		} else if (!LIM_IS_AP_ROLE(session_entry)) {
+			if (!mac_ctx->lim.cfgProtection.fromllb) {
+				/* protection disabled. */
+				pe_debug("protection from 11b is disabled");
+				return QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+
+	if (enable) {
+		lim_handle_enable11g_protection_enabled(mac_ctx, beaconparams,
+					overlap, session_entry);
+	} else if (true == session_entry->beaconParams.llbCoexist) {
+		lim_handle_11g_protection_for_11bcoexist(mac_ctx, beaconparams,
+					overlap, session_entry);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_enable_ht_protection_from11g
+   \brief based on cofig enables\disables protection from 11g.
+   \param      uint8_t enable : 1=> enable protection, 0=> disable protection.
+   \param      uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
+   \param      tpUpdateBeaconParams pBeaconParams
+   \return      None
+   -------------------------------------------------------------*/
+QDF_STATUS
+lim_enable_ht_protection_from11g(tpAniSirGlobal pMac, uint8_t enable,
+				 uint8_t overlap,
+				 tpUpdateBeaconParams pBeaconParams,
+				 tpPESession psessionEntry)
+{
+	if (!psessionEntry->htCapability)
+		return QDF_STATUS_SUCCESS;  /* protection from 11g is only for HT stations. */
+
+	/* overlapping protection configuration check. */
+	if (overlap) {
+		if ((LIM_IS_AP_ROLE(psessionEntry))
+		    && (!psessionEntry->cfgProtection.overlapFromllg)) {
+			/* protection disabled. */
+			pe_debug("overlap protection from 11g is disabled");
+			return QDF_STATUS_SUCCESS;
+		}
+	} else {
+		/* normal protection config check */
+		if (LIM_IS_AP_ROLE(psessionEntry) &&
+		    !psessionEntry->cfgProtection.fromllg) {
+			/* protection disabled. */
+			pe_debug("protection from 11g is disabled");
+			return QDF_STATUS_SUCCESS;
+		} else if (!LIM_IS_AP_ROLE(psessionEntry)) {
+			if (!pMac->lim.cfgProtection.fromllg) {
+				/* protection disabled. */
+				pe_debug("protection from 11g is disabled");
+				return QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+	if (enable) {
+		/* If we are AP and HT capable, we need to set the HT OP mode */
+		/* appropriately. */
+
+		if (LIM_IS_AP_ROLE(psessionEntry)) {
+			if (overlap) {
+				psessionEntry->gLimOverlap11gParams.
+				protectionEnabled = true;
+				/* 11g exists in overlap BSS. */
+				/* need not to change the operating mode to overlap_legacy */
+				/* if higher or same protection operating mode is enabled right now. */
+				if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
+				     psessionEntry->htOperMode)
+				    && (eSIR_HT_OP_MODE_MIXED !=
+					psessionEntry->htOperMode)) {
+					psessionEntry->htOperMode =
+						eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+				}
+				lim_enable_ht_rifs_protection(pMac, true, overlap,
+							      pBeaconParams,
+							      psessionEntry);
+				lim_enable_ht_obss_protection(pMac, true, overlap,
+							      pBeaconParams,
+							      psessionEntry);
+			} else {
+				/* 11g is associated to an AP operating in 11n mode. */
+				/* Change the HT operating mode to 'mixed mode'. */
+				psessionEntry->gLim11gParams.protectionEnabled =
+					true;
+				if (eSIR_HT_OP_MODE_MIXED !=
+				    psessionEntry->htOperMode) {
+					psessionEntry->htOperMode =
+						eSIR_HT_OP_MODE_MIXED;
+					lim_enable_ht_rifs_protection(pMac, true,
+								      overlap,
+								      pBeaconParams,
+								      psessionEntry);
+					lim_enable_ht_obss_protection(pMac, true,
+								      overlap,
+								      pBeaconParams,
+								      psessionEntry);
+				}
+			}
+		}
+		/* This part is common for staiton as well. */
+		if (false == psessionEntry->beaconParams.llgCoexist) {
+			pBeaconParams->llgCoexist =
+				psessionEntry->beaconParams.llgCoexist = true;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_llGCOEXIST_CHANGED;
+		} else if (true ==
+			   psessionEntry->gLimOverlap11gParams.
+			   protectionEnabled) {
+			/* As operating mode changed after G station assoc some way to update beacon */
+			/* This addresses the issue of mode not changing to - 11 in beacon when OBSS overlap is enabled */
+			/* pMac->sch.schObject.fBeaconChanged = 1; */
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_llGCOEXIST_CHANGED;
+		}
+	} else if (true == psessionEntry->beaconParams.llgCoexist) {
+		/* for AP role. */
+		/* we need to take care of HT OP mode change if needed. */
+		/* We need to take care of Overlap cases. */
+
+		if (LIM_IS_AP_ROLE(psessionEntry)) {
+			if (overlap) {
+				/* Overlap Legacy protection disabled. */
+				if (psessionEntry->gLim11gParams.numSta == 0)
+					psessionEntry->gLimOverlap11gParams.
+					protectionEnabled = false;
+
+				/* no HT op mode change if any of the overlap protection enabled. */
+				if (!
+				    (psessionEntry->gLimOlbcParams.
+				     protectionEnabled
+				     || psessionEntry->gLimOverlapHt20Params.
+				     protectionEnabled
+				     || psessionEntry->gLimOverlapNonGfParams.
+				     protectionEnabled)) {
+					/* Check if there is a need to change HT OP mode. */
+					if (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+					    psessionEntry->htOperMode) {
+						lim_enable_ht_rifs_protection(pMac,
+									      false,
+									      overlap,
+									      pBeaconParams,
+									      psessionEntry);
+						lim_enable_ht_obss_protection(pMac,
+									      false,
+									      overlap,
+									      pBeaconParams,
+									      psessionEntry);
+
+						if (psessionEntry->gLimHt20Params.protectionEnabled) {
+						if (eHT_CHANNEL_WIDTH_20MHZ ==
+							psessionEntry->htSupportedChannelWidthSet)
+							psessionEntry->htOperMode =
+								eSIR_HT_OP_MODE_PURE;
+						else
+							psessionEntry->htOperMode =
+								eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+						} else
+							psessionEntry->htOperMode =
+								eSIR_HT_OP_MODE_PURE;
+					}
+				}
+			} else {
+				/* Disable protection from 11G stations. */
+				psessionEntry->gLim11gParams.protectionEnabled =
+					false;
+				/* Check if any other non-HT protection enabled. */
+				if (!psessionEntry->gLim11bParams.
+				    protectionEnabled) {
+
+					/* Right now we are in HT OP Mixed mode. */
+					/* Change HT op mode appropriately. */
+					lim_enable_ht_obss_protection(pMac, false,
+								      overlap,
+								      pBeaconParams,
+								      psessionEntry);
+
+					/* Change HT OP mode to 01 if any overlap protection enabled */
+					if (psessionEntry->gLimOlbcParams.
+					    protectionEnabled
+					    || psessionEntry->
+					    gLimOverlap11gParams.
+					    protectionEnabled
+					    || psessionEntry->
+					    gLimOverlapHt20Params.
+					    protectionEnabled
+					    || psessionEntry->
+					    gLimOverlapNonGfParams.
+					    protectionEnabled) {
+						psessionEntry->htOperMode =
+							eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+						lim_enable_ht_rifs_protection(pMac,
+									      true,
+									      overlap,
+									      pBeaconParams,
+									      psessionEntry);
+					} else if (psessionEntry->
+						   gLimHt20Params.
+						   protectionEnabled) {
+						/* Commenting because of CR 258588 WFA cert */
+						/* psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; */
+						psessionEntry->htOperMode =
+							eSIR_HT_OP_MODE_PURE;
+						lim_enable_ht_rifs_protection(pMac,
+									      false,
+									      overlap,
+									      pBeaconParams,
+									      psessionEntry);
+					} else {
+						psessionEntry->htOperMode =
+							eSIR_HT_OP_MODE_PURE;
+						lim_enable_ht_rifs_protection(pMac,
+									      false,
+									      overlap,
+									      pBeaconParams,
+									      psessionEntry);
+					}
+				}
+			}
+			if (!psessionEntry->gLimOverlap11gParams.
+			    protectionEnabled
+			    && !psessionEntry->gLim11gParams.
+			    protectionEnabled) {
+				pe_debug("===> Protection from 11G Disabled");
+				pBeaconParams->llgCoexist =
+					psessionEntry->beaconParams.llgCoexist =
+						false;
+				pBeaconParams->paramChangeBitmap |=
+					PARAM_llGCOEXIST_CHANGED;
+			}
+		}
+		/* for station role */
+		else {
+			pe_debug("===> Protection from 11G Disabled");
+			pBeaconParams->llgCoexist =
+				psessionEntry->beaconParams.llgCoexist = false;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_llGCOEXIST_CHANGED;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/* FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection. */
+/* This check will be done at the caller. */
+
+/** -------------------------------------------------------------
+   \fn limEnableHtObssProtection
+   \brief based on cofig enables\disables obss protection.
+   \param      uint8_t enable : 1=> enable protection, 0=> disable protection.
+   \param      uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
+   \param      tpUpdateBeaconParams pBeaconParams
+   \return      None
+   -------------------------------------------------------------*/
+QDF_STATUS
+lim_enable_ht_obss_protection(tpAniSirGlobal pMac, uint8_t enable,
+			      uint8_t overlap, tpUpdateBeaconParams pBeaconParams,
+			      tpPESession psessionEntry)
+{
+
+	if (!psessionEntry->htCapability)
+		return QDF_STATUS_SUCCESS;  /* this protection  is only for HT stations. */
+
+	/* overlapping protection configuration check. */
+	if (overlap) {
+		/* overlapping protection configuration check. */
+	} else {
+		/* normal protection config check */
+		if ((LIM_IS_AP_ROLE(psessionEntry)) &&
+		    !psessionEntry->cfgProtection.obss) { /* ToDo Update this field */
+			/* protection disabled. */
+			pe_debug("protection from Obss is disabled");
+			return QDF_STATUS_SUCCESS;
+		} else if (!LIM_IS_AP_ROLE(psessionEntry)) {
+			if (!pMac->lim.cfgProtection.obss) { /* ToDo Update this field */
+				/* protection disabled. */
+				pe_debug("protection from Obss is disabled");
+				return QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+
+	if (LIM_IS_AP_ROLE(psessionEntry)) {
+		if ((enable)
+		    && (false == psessionEntry->beaconParams.gHTObssMode)) {
+			pe_debug("=>obss protection enabled");
+			psessionEntry->beaconParams.gHTObssMode = true;
+			pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; /* UPDATE AN ENUM FOR OBSS MODE <todo> */
+
+		} else if (!enable
+			   && (true ==
+			       psessionEntry->beaconParams.gHTObssMode)) {
+			pe_debug("===> obss Protection disabled");
+			psessionEntry->beaconParams.gHTObssMode = false;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_OBSS_MODE_CHANGED;
+
+		}
+/* CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS */
+		if (!enable && !overlap) {
+			psessionEntry->gLimOverlap11gParams.protectionEnabled =
+				false;
+		}
+	} else {
+		if ((enable)
+		    && (false == psessionEntry->beaconParams.gHTObssMode)) {
+			pe_debug("=>obss protection enabled");
+			psessionEntry->beaconParams.gHTObssMode = true;
+			pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; /* UPDATE AN ENUM FOR OBSS MODE <todo> */
+
+		} else if (!enable
+			   && (true ==
+			       psessionEntry->beaconParams.gHTObssMode)) {
+			pe_debug("===> obss Protection disabled");
+			psessionEntry->beaconParams.gHTObssMode = false;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_OBSS_MODE_CHANGED;
+
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_handle_ht20protection_enabled() - Handle ht20 protection  enabled
+ * @mac_ctx: pointer to Gloal Mac Structure
+ * @overlap: variable for overlap detection
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @session_entry: pointer to tpPESession
+ *
+ * Function handles ht20 protection enabled
+ *
+ * Return: none
+ */
+static void lim_handle_ht20protection_enabled(tpAniSirGlobal mac_ctx,
+			uint8_t overlap, tpUpdateBeaconParams beaconparams,
+			tpPESession session_entry)
+{
+	/*
+	 * If we are AP and HT capable, we need to set the HT OP mode
+	 * appropriately.
+	 */
+	if (LIM_IS_AP_ROLE(session_entry) && overlap) {
+		session_entry->gLimOverlapHt20Params.protectionEnabled = true;
+		if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
+				session_entry->htOperMode) &&
+			(eSIR_HT_OP_MODE_MIXED !=
+				session_entry->htOperMode)) {
+			session_entry->htOperMode =
+				eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+			lim_enable_ht_rifs_protection(mac_ctx, true,
+				overlap, beaconparams, session_entry);
+		}
+	} else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
+		session_entry->gLimHt20Params.protectionEnabled = true;
+		if (eSIR_HT_OP_MODE_PURE == session_entry->htOperMode) {
+			if (session_entry->htSupportedChannelWidthSet !=
+					eHT_CHANNEL_WIDTH_20MHZ)
+				 session_entry->htOperMode =
+					eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+			lim_enable_ht_rifs_protection(mac_ctx, false,
+				overlap, beaconparams, session_entry);
+			lim_enable_ht_obss_protection(mac_ctx, false,
+				overlap, beaconparams, session_entry);
+		}
+	}
+	/* This part is common for staiton as well. */
+	if (false == session_entry->beaconParams.ht20Coexist) {
+		pe_debug("=> Protection from HT20 Enabled");
+		beaconparams->ht20MhzCoexist =
+			session_entry->beaconParams.ht20Coexist = true;
+		beaconparams->paramChangeBitmap |=
+			PARAM_HT20MHZCOEXIST_CHANGED;
+	}
+}
+
+/**
+ * lim_handle_ht20coexist_ht20protection() - ht20 protection for ht20 coexist
+ * @mac_ctx: pointer to Gloal Mac Structure
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @session_entry: pointer to tpPESession
+ * @overlap: variable for overlap detection
+ *
+ * Function handles ht20 protection for ht20 coexist
+ *
+ * Return: none
+ */
+static void lim_handle_ht20coexist_ht20protection(tpAniSirGlobal mac_ctx,
+			tpUpdateBeaconParams beaconparams,
+			tpPESession session_entry, uint8_t overlap)
+{
+	/*
+	 * For AP role:
+	 * we need to take care of HT OP mode change if needed.
+	 * We need to take care of Overlap cases.
+	 */
+	if (LIM_IS_AP_ROLE(session_entry) && overlap) {
+		/* Overlap Legacy protection disabled. */
+		session_entry->gLimOverlapHt20Params.protectionEnabled =
+			false;
+		/*
+		 * no HT op mode change if any of the overlap
+		 * protection enabled.
+		 */
+		if (!(session_entry->gLimOlbcParams.protectionEnabled ||
+			session_entry->gLimOverlap11gParams.protectionEnabled ||
+			session_entry->gLimOverlapHt20Params.protectionEnabled
+			|| session_entry->gLimOverlapNonGfParams.
+				protectionEnabled) &&
+			/*
+			 * Check if there is a need to change HT
+			 * OP mode.
+			 */
+			(eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+				session_entry->htOperMode)) {
+			if (session_entry->gLimHt20Params.
+				protectionEnabled) {
+				if (eHT_CHANNEL_WIDTH_20MHZ ==
+					session_entry->
+					htSupportedChannelWidthSet)
+					session_entry->htOperMode =
+						eSIR_HT_OP_MODE_PURE;
+				else
+					session_entry->htOperMode =
+					eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+
+				lim_enable_ht_rifs_protection(mac_ctx,
+						false, overlap, beaconparams,
+						session_entry);
+				lim_enable_ht_obss_protection(mac_ctx,
+						false, overlap, beaconparams,
+						session_entry);
+			} else {
+				session_entry->htOperMode =
+					eSIR_HT_OP_MODE_PURE;
+			}
+		}
+	} else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
+		/* Disable protection from 11G stations. */
+		session_entry->gLimHt20Params.protectionEnabled = false;
+		/* Change HT op mode appropriately. */
+		if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
+				session_entry->htOperMode) {
+			session_entry->htOperMode =
+				eSIR_HT_OP_MODE_PURE;
+			lim_enable_ht_rifs_protection(mac_ctx, false,
+					overlap, beaconparams, session_entry);
+			lim_enable_ht_obss_protection(mac_ctx, false,
+					overlap, beaconparams, session_entry);
+		}
+	}
+	if (LIM_IS_AP_ROLE(session_entry)) {
+		pe_debug("===> Protection from HT 20 Disabled");
+		beaconparams->ht20MhzCoexist =
+			session_entry->beaconParams.ht20Coexist = false;
+		beaconparams->paramChangeBitmap |=
+			PARAM_HT20MHZCOEXIST_CHANGED;
+	}
+	if (!LIM_IS_AP_ROLE(session_entry)) {
+		/* For station role */
+		pe_debug("===> Protection from HT20 Disabled");
+		beaconparams->ht20MhzCoexist =
+			session_entry->beaconParams.ht20Coexist = false;
+		beaconparams->paramChangeBitmap |=
+			PARAM_HT20MHZCOEXIST_CHANGED;
+	}
+}
+
+/**
+ * lim_enable_ht20_protection() -  Function to enable ht20 protection
+ * @mac_ctx: pointer to Global Mac structure
+ * @enable: 1=> enable protection, 0=> disable protection.
+ * @overlap: 1=> called from overlap context, 0 => called from assoc context.
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @session_entry: pointer to tpPESession
+ *
+ * based on cofig enables\disables protection from Ht20
+ *
+ * Return: 0 - success
+ */
+QDF_STATUS lim_enable_ht20_protection(tpAniSirGlobal mac_ctx, uint8_t enable,
+			   uint8_t overlap, tpUpdateBeaconParams beaconparams,
+			   tpPESession session_entry)
+{
+	/* This protection  is only for HT stations. */
+	if (!session_entry->htCapability)
+		return QDF_STATUS_SUCCESS;
+
+	/* overlapping protection configuration check. */
+	if (!overlap) {
+		/* normal protection config check */
+		if ((LIM_IS_AP_ROLE(session_entry)) &&
+		    !session_entry->cfgProtection.ht20) {
+			/* protection disabled. */
+			pe_debug("protection from HT20 is disabled");
+			return QDF_STATUS_SUCCESS;
+		} else if (!LIM_IS_AP_ROLE(session_entry)) {
+			if (!mac_ctx->lim.cfgProtection.ht20) {
+				/* protection disabled. */
+				pe_debug("protection from HT20 is disabled");
+				return QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+
+	if (enable)
+		lim_handle_ht20protection_enabled(mac_ctx, overlap,
+				beaconparams, session_entry);
+	else if (true == session_entry->beaconParams.ht20Coexist)
+		lim_handle_ht20coexist_ht20protection(mac_ctx, beaconparams,
+					session_entry, overlap);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_enable_ht_non_gf_protection
+   \brief based on cofig enables\disables protection from NonGf.
+   \param      uint8_t enable : 1=> enable protection, 0=> disable protection.
+   \param      uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
+   \param      tpUpdateBeaconParams pBeaconParams
+   \return      None
+   -------------------------------------------------------------*/
+QDF_STATUS
+lim_enable_ht_non_gf_protection(tpAniSirGlobal pMac, uint8_t enable,
+				uint8_t overlap, tpUpdateBeaconParams pBeaconParams,
+				tpPESession psessionEntry)
+{
+	if (!psessionEntry->htCapability)
+		return QDF_STATUS_SUCCESS;  /* this protection  is only for HT stations. */
+
+	/* overlapping protection configuration check. */
+	if (overlap) {
+	} else {
+		/* normal protection config check */
+		if (LIM_IS_AP_ROLE(psessionEntry) &&
+		    !psessionEntry->cfgProtection.nonGf) {
+			/* protection disabled. */
+			pe_debug("protection from NonGf is disabled");
+			return QDF_STATUS_SUCCESS;
+		} else if (!LIM_IS_AP_ROLE(psessionEntry)) {
+			/* normal protection config check */
+			if (!pMac->lim.cfgProtection.nonGf) {
+				/* protection disabled. */
+				pe_debug("protection from NonGf is disabled");
+				return QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+	if (LIM_IS_AP_ROLE(psessionEntry)) {
+		if ((enable)
+		    && (false == psessionEntry->beaconParams.llnNonGFCoexist)) {
+			pe_debug(" => Protection from non GF Enabled");
+			pBeaconParams->llnNonGFCoexist =
+				psessionEntry->beaconParams.llnNonGFCoexist = true;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+		} else if (!enable
+			   && (true ==
+			       psessionEntry->beaconParams.llnNonGFCoexist)) {
+			pe_debug("===> Protection from Non GF Disabled");
+			pBeaconParams->llnNonGFCoexist =
+				psessionEntry->beaconParams.llnNonGFCoexist = false;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+		}
+	} else {
+		if ((enable)
+		    && (false == psessionEntry->beaconParams.llnNonGFCoexist)) {
+			pe_debug(" => Protection from non GF Enabled");
+			pBeaconParams->llnNonGFCoexist =
+				psessionEntry->beaconParams.llnNonGFCoexist = true;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+		} else if (!enable
+			   && (true ==
+			       psessionEntry->beaconParams.llnNonGFCoexist)) {
+			pe_debug("===> Protection from Non GF Disabled");
+			pBeaconParams->llnNonGFCoexist =
+				psessionEntry->beaconParams.llnNonGFCoexist = false;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_enable_ht_lsig_txop_protection
+   \brief based on cofig enables\disables LsigTxop protection.
+   \param      uint8_t enable : 1=> enable protection, 0=> disable protection.
+   \param      uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
+   \param      tpUpdateBeaconParams pBeaconParams
+   \return      None
+   -------------------------------------------------------------*/
+QDF_STATUS
+lim_enable_ht_lsig_txop_protection(tpAniSirGlobal pMac, uint8_t enable,
+				   uint8_t overlap,
+				   tpUpdateBeaconParams pBeaconParams,
+				   tpPESession psessionEntry)
+{
+	if (!psessionEntry->htCapability)
+		return QDF_STATUS_SUCCESS;  /* this protection  is only for HT stations. */
+
+	/* overlapping protection configuration check. */
+	if (overlap) {
+	} else {
+		/* normal protection config check */
+		if (LIM_IS_AP_ROLE(psessionEntry) &&
+			!psessionEntry->cfgProtection.lsigTxop) {
+			/* protection disabled. */
+			pe_debug("protection from LsigTxop not supported is disabled");
+			return QDF_STATUS_SUCCESS;
+		} else if (!LIM_IS_AP_ROLE(psessionEntry)) {
+			/* normal protection config check */
+			if (!pMac->lim.cfgProtection.lsigTxop) {
+				/* protection disabled. */
+				pe_debug("protection from LsigTxop not supported is disabled");
+				return QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+
+	if (LIM_IS_AP_ROLE(psessionEntry)) {
+		if ((enable)
+		    && (false ==
+			psessionEntry->beaconParams.
+			fLsigTXOPProtectionFullSupport)) {
+			pe_debug(" => Protection from LsigTxop Enabled");
+			pBeaconParams->fLsigTXOPProtectionFullSupport =
+				psessionEntry->beaconParams.
+				fLsigTXOPProtectionFullSupport = true;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+		} else if (!enable
+			   && (true ==
+			       psessionEntry->beaconParams.
+			       fLsigTXOPProtectionFullSupport)) {
+			pe_debug("===> Protection from LsigTxop Disabled");
+			pBeaconParams->fLsigTXOPProtectionFullSupport =
+				psessionEntry->beaconParams.
+				fLsigTXOPProtectionFullSupport = false;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+		}
+	} else {
+		if ((enable)
+		    && (false ==
+			psessionEntry->beaconParams.
+			fLsigTXOPProtectionFullSupport)) {
+			pe_debug(" => Protection from LsigTxop Enabled");
+			pBeaconParams->fLsigTXOPProtectionFullSupport =
+				psessionEntry->beaconParams.
+				fLsigTXOPProtectionFullSupport = true;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+		} else if (!enable
+			   && (true ==
+			       psessionEntry->beaconParams.
+			       fLsigTXOPProtectionFullSupport)) {
+			pe_debug("===> Protection from LsigTxop Disabled");
+			pBeaconParams->fLsigTXOPProtectionFullSupport =
+				psessionEntry->beaconParams.
+				fLsigTXOPProtectionFullSupport = false;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/* FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection. */
+/* This check will be done at the caller. */
+/** -------------------------------------------------------------
+   \fn lim_enable_ht_rifs_protection
+   \brief based on cofig enables\disables Rifs protection.
+   \param      uint8_t enable : 1=> enable protection, 0=> disable protection.
+   \param      uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
+   \param      tpUpdateBeaconParams pBeaconParams
+   \return      None
+   -------------------------------------------------------------*/
+QDF_STATUS
+lim_enable_ht_rifs_protection(tpAniSirGlobal pMac, uint8_t enable,
+			      uint8_t overlap, tpUpdateBeaconParams pBeaconParams,
+			      tpPESession psessionEntry)
+{
+	if (!psessionEntry->htCapability)
+		return QDF_STATUS_SUCCESS;  /* this protection  is only for HT stations. */
+
+	/* overlapping protection configuration check. */
+	if (overlap) {
+	} else {
+		/* normal protection config check */
+		if (LIM_IS_AP_ROLE(psessionEntry) &&
+		    !psessionEntry->cfgProtection.rifs) {
+			/* protection disabled. */
+			pe_debug("protection from Rifs is disabled");
+			return QDF_STATUS_SUCCESS;
+		} else if (!LIM_IS_AP_ROLE(psessionEntry)) {
+			/* normal protection config check */
+			if (!pMac->lim.cfgProtection.rifs) {
+				/* protection disabled. */
+				pe_debug("protection from Rifs is disabled");
+				return QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+
+	if (LIM_IS_AP_ROLE(psessionEntry)) {
+		/* Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS */
+		if ((!enable)
+		    && (false == psessionEntry->beaconParams.fRIFSMode)) {
+			pe_debug(" => Rifs protection Disabled");
+			pBeaconParams->fRIFSMode =
+				psessionEntry->beaconParams.fRIFSMode = true;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_RIFS_MODE_CHANGED;
+		}
+		/* Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS */
+		else if (enable
+			 && (true == psessionEntry->beaconParams.fRIFSMode)) {
+			pe_debug("===> Rifs Protection Enabled");
+			pBeaconParams->fRIFSMode =
+				psessionEntry->beaconParams.fRIFSMode = false;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_RIFS_MODE_CHANGED;
+		}
+	} else {
+		/* Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS */
+		if ((!enable)
+		    && (false == psessionEntry->beaconParams.fRIFSMode)) {
+			pe_debug(" => Rifs protection Disabled");
+			pBeaconParams->fRIFSMode =
+				psessionEntry->beaconParams.fRIFSMode = true;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_RIFS_MODE_CHANGED;
+		}
+		/* Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS */
+		else if (enable
+			 && (true == psessionEntry->beaconParams.fRIFSMode)) {
+			pe_debug("===> Rifs Protection Enabled");
+			pBeaconParams->fRIFSMode =
+				psessionEntry->beaconParams.fRIFSMode = false;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_RIFS_MODE_CHANGED;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * lim_enable_short_preamble
+ *
+ * FUNCTION:
+ * Enable/Disable short preamble
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param enable        Flag to enable/disable short preamble
+ * @return None
+ */
+
+QDF_STATUS
+lim_enable_short_preamble(tpAniSirGlobal pMac, uint8_t enable,
+			  tpUpdateBeaconParams pBeaconParams,
+			  tpPESession psessionEntry)
+{
+	if (!pMac->mlme_cfg->ht_caps.short_preamble)
+		return QDF_STATUS_SUCCESS;
+
+	/* 11G short preamble switching is disabled. */
+	if (!pMac->mlme_cfg->feature_flags.enable_short_preamble_11g)
+		return QDF_STATUS_SUCCESS;
+
+	if (LIM_IS_AP_ROLE(psessionEntry)) {
+		if (enable && (psessionEntry->beaconParams.fShortPreamble == 0)) {
+			pe_debug("===> Short Preamble Enabled");
+			psessionEntry->beaconParams.fShortPreamble = true;
+			pBeaconParams->fShortPreamble =
+				(uint8_t) psessionEntry->beaconParams.
+				fShortPreamble;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_SHORT_PREAMBLE_CHANGED;
+		} else if (!enable
+			   && (psessionEntry->beaconParams.fShortPreamble ==
+			       1)) {
+			pe_debug("===> Short Preamble Disabled");
+			psessionEntry->beaconParams.fShortPreamble = false;
+			pBeaconParams->fShortPreamble =
+				(uint8_t) psessionEntry->beaconParams.
+				fShortPreamble;
+			pBeaconParams->paramChangeBitmap |=
+				PARAM_SHORT_PREAMBLE_CHANGED;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_tx_complete
+ *
+ * Function:
+ * This is LIM's very own "TX MGMT frame complete" completion routine.
+ *
+ * Logic:
+ * LIM wants to send a MGMT frame (broadcast or unicast)
+ * LIM allocates memory using cds_packet_alloc( ..., **pData, **pPacket )
+ * LIM transmits the MGMT frame using the API:
+ *  wma_tx_frame( ... pPacket, ..., (void *) lim_tx_complete, pData )
+ * HDD, via wma_tx_frame/DXE, "transfers" the packet over to BMU
+ * HDD, if it determines that a TX completion routine (in this case
+ * lim_tx_complete) has been provided, will invoke this callback
+ * LIM will try to free the TX MGMT packet that was earlier allocated, in order
+ * to send this MGMT frame, using the PAL API cds_packet_free( ... pData, pPacket )
+ *
+ * Assumptions:
+ * Presently, this is ONLY being used for MGMT frames/packets
+ * TODO:
+ * Would it do good for LIM to have some sort of "signature" validation to
+ * ensure that the pData argument passed in was a buffer that was actually
+ * allocated by LIM and/or is not corrupted?
+ *
+ * Note: FIXME and TODO
+ * Looks like cds_packet_free() is interested in pPacket. But, when this completion
+ * routine is called, only pData is made available to LIM!!
+ *
+ * @param void A pointer to pData. Shouldn't it be pPacket?!
+ *
+ * @return QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS lim_tx_complete(void *context, qdf_nbuf_t buf, bool free)
+{
+	if (free)
+		cds_packet_free((void *)buf);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * \brief This function updates lim global structure, if CB parameters in the BSS
+ *  have changed, and sends an indication to HAL also with the
+ * updated HT Parameters.
+ * This function does not detect the change in the primary channel, that is done as part
+ * of channel Swtich IE processing.
+ * If STA is configured with '20Mhz only' mode, then this function does not do anything
+ * This function changes the CB mode, only if the self capability is set to '20 as well as 40Mhz'
+ *
+ *
+ * \param pMac Pointer to global MAC structure
+ *
+ * \param pRcvdHTInfo Pointer to HT Info IE obtained from a  Beacon or
+ * Probe Response
+ *
+ * \param bssIdx BSS Index of the Bss to which Station is associated.
+ *
+ *
+ */
+
+void lim_update_sta_run_time_ht_switch_chnl_params(tpAniSirGlobal pMac,
+						   tDot11fIEHTInfo *pHTInfo,
+						   uint8_t bssIdx,
+						   tpPESession psessionEntry)
+{
+	uint8_t center_freq = 0;
+	enum phy_ch_width ch_width = CH_WIDTH_20MHZ;
+
+	/* If self capability is set to '20Mhz only', then do not change the CB mode. */
+	if (!lim_get_ht_capability
+		    (pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry))
+		return;
+
+	if (WLAN_REG_IS_24GHZ_CH(psessionEntry->currentOperChannel) &&
+		psessionEntry->force_24ghz_in_ht20) {
+		pe_debug("force_24ghz_in_ht20 is set and channel is 2.4 Ghz");
+		return;
+	}
+
+	if (psessionEntry->ftPEContext.ftPreAuthSession) {
+		pe_err("FT PREAUTH channel change is in progress");
+		return;
+	}
+
+	/*
+	 * Do not try to switch channel if RoC is in progress. RoC code path
+	 * uses pMac->lim.gpLimRemainOnChanReq to notify the upper layers that
+	 * the device has started listening on the channel requested as part of
+	 * RoC, if we set pMac->lim.gpLimRemainOnChanReq to NULL as we do below
+	 * then the upper layers will think that the channel change is not
+	 * successful and the RoC from the upper layer perspective will never
+	 * end...
+	 */
+	if (pMac->lim.gpLimRemainOnChanReq) {
+		pe_debug("RoC is in progress");
+		return;
+	}
+
+	if (psessionEntry->ch_switch_in_progress == true) {
+		pe_debug("ch switch is in progress, ignore HT IE BW update");
+		return;
+	}
+
+	if (!pHTInfo->primaryChannel) {
+		pe_debug("Ignore as primary channel is 0 in HT info");
+		return;
+	}
+
+	if (psessionEntry->htSecondaryChannelOffset !=
+	    (uint8_t) pHTInfo->secondaryChannelOffset
+	    || psessionEntry->htRecommendedTxWidthSet !=
+	    (uint8_t) pHTInfo->recommendedTxWidthSet) {
+		psessionEntry->htSecondaryChannelOffset =
+			(ePhyChanBondState) pHTInfo->secondaryChannelOffset;
+		psessionEntry->htRecommendedTxWidthSet =
+			(uint8_t) pHTInfo->recommendedTxWidthSet;
+		if (eHT_CHANNEL_WIDTH_40MHZ ==
+		    psessionEntry->htRecommendedTxWidthSet) {
+			ch_width = CH_WIDTH_40MHZ;
+			if (PHY_DOUBLE_CHANNEL_LOW_PRIMARY ==
+					pHTInfo->secondaryChannelOffset)
+				center_freq = pHTInfo->primaryChannel + 2;
+			else if (PHY_DOUBLE_CHANNEL_HIGH_PRIMARY ==
+					pHTInfo->secondaryChannelOffset)
+				center_freq = pHTInfo->primaryChannel - 2;
+			else
+				ch_width = CH_WIDTH_20MHZ;
+		}
+
+		/* notify HAL */
+		pe_debug("Channel Information in HT IE change"
+				       "d; sending notification to HAL.");
+		pe_debug("Primary Channel: %d Secondary Chan"
+				       "nel Offset: %d Channel Width: %d",
+			pHTInfo->primaryChannel, center_freq,
+			psessionEntry->htRecommendedTxWidthSet);
+		psessionEntry->channelChangeReasonCode =
+			LIM_SWITCH_CHANNEL_OPERATION;
+		pMac->lim.gpchangeChannelCallback = NULL;
+		pMac->lim.gpchangeChannelData = NULL;
+
+		lim_send_switch_chnl_params(pMac, (uint8_t) pHTInfo->primaryChannel,
+					    center_freq, 0, ch_width,
+					    psessionEntry->maxTxPower,
+					    psessionEntry->peSessionId,
+					    true, 0, 0);
+
+		/* In case of IBSS, if STA should update HT Info IE in its beacons. */
+		if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+			sch_set_fixed_beacon_fields(pMac, psessionEntry);
+		}
+
+	}
+} /* End limUpdateStaRunTimeHTParams. */
+
+/**
+ * \brief This function updates the lim global structure, if any of the
+ * HT Capabilities have changed.
+ *
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param pHTCapability Pointer to HT Capability Information Element
+ * obtained from a Beacon or Probe Response
+ *
+ *
+ *
+ */
+
+void lim_update_sta_run_time_ht_capability(tpAniSirGlobal pMac,
+					   tDot11fIEHTCaps *pHTCaps)
+{
+
+	if (pMac->lim.gHTLsigTXOPProtection !=
+	    (uint8_t) pHTCaps->lsigTXOPProtection) {
+		pMac->lim.gHTLsigTXOPProtection =
+			(uint8_t) pHTCaps->lsigTXOPProtection;
+		/* Send change notification to HAL */
+	}
+
+	if (pMac->lim.gHTAMpduDensity != (uint8_t) pHTCaps->mpduDensity) {
+		pMac->lim.gHTAMpduDensity = (uint8_t) pHTCaps->mpduDensity;
+		/* Send change notification to HAL */
+	}
+
+	if (pMac->lim.gHTMaxRxAMpduFactor !=
+	    (uint8_t) pHTCaps->maxRxAMPDUFactor) {
+		pMac->lim.gHTMaxRxAMpduFactor =
+			(uint8_t) pHTCaps->maxRxAMPDUFactor;
+		/* Send change notification to HAL */
+	}
+
+} /* End lim_update_sta_run_time_ht_capability. */
+
+/**
+ * \brief This function updates lim global structure, if any of the HT
+ * Info Parameters have changed.
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pHTInfo Pointer to the HT Info IE obtained from a Beacon or
+ * Probe Response
+ *
+ *
+ */
+
+void lim_update_sta_run_time_ht_info(tpAniSirGlobal pMac,
+				     tDot11fIEHTInfo *pHTInfo,
+				     tpPESession psessionEntry)
+{
+	if (psessionEntry->htRecommendedTxWidthSet !=
+	    (uint8_t) pHTInfo->recommendedTxWidthSet) {
+		psessionEntry->htRecommendedTxWidthSet =
+			(uint8_t) pHTInfo->recommendedTxWidthSet;
+		/* Send change notification to HAL */
+	}
+
+	if (psessionEntry->beaconParams.fRIFSMode !=
+	    (uint8_t) pHTInfo->rifsMode) {
+		psessionEntry->beaconParams.fRIFSMode =
+			(uint8_t) pHTInfo->rifsMode;
+		/* Send change notification to HAL */
+	}
+
+	if (pMac->lim.gHTServiceIntervalGranularity !=
+	    (uint8_t) pHTInfo->serviceIntervalGranularity) {
+		pMac->lim.gHTServiceIntervalGranularity =
+			(uint8_t) pHTInfo->serviceIntervalGranularity;
+		/* Send change notification to HAL */
+	}
+
+	if (pMac->lim.gHTOperMode != (tSirMacHTOperatingMode) pHTInfo->opMode) {
+		pMac->lim.gHTOperMode =
+			(tSirMacHTOperatingMode) pHTInfo->opMode;
+		/* Send change notification to HAL */
+	}
+
+	if (psessionEntry->beaconParams.llnNonGFCoexist !=
+	    pHTInfo->nonGFDevicesPresent) {
+		psessionEntry->beaconParams.llnNonGFCoexist =
+			(uint8_t) pHTInfo->nonGFDevicesPresent;
+	}
+
+	if (pMac->lim.gHTSTBCBasicMCS != (uint8_t) pHTInfo->basicSTBCMCS) {
+		pMac->lim.gHTSTBCBasicMCS = (uint8_t) pHTInfo->basicSTBCMCS;
+		/* Send change notification to HAL */
+	}
+
+	if (pMac->lim.gHTDualCTSProtection !=
+	    (uint8_t) pHTInfo->dualCTSProtection) {
+		pMac->lim.gHTDualCTSProtection =
+			(uint8_t) pHTInfo->dualCTSProtection;
+		/* Send change notification to HAL */
+	}
+
+	if (pMac->lim.gHTSecondaryBeacon != (uint8_t) pHTInfo->secondaryBeacon) {
+		pMac->lim.gHTSecondaryBeacon =
+			(uint8_t) pHTInfo->secondaryBeacon;
+		/* Send change notification to HAL */
+	}
+
+	if (psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport !=
+	    (uint8_t) pHTInfo->lsigTXOPProtectionFullSupport) {
+		psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport =
+			(uint8_t) pHTInfo->lsigTXOPProtectionFullSupport;
+		/* Send change notification to HAL */
+	}
+
+	if (pMac->lim.gHTPCOActive != (uint8_t) pHTInfo->pcoActive) {
+		pMac->lim.gHTPCOActive = (uint8_t) pHTInfo->pcoActive;
+		/* Send change notification to HAL */
+	}
+
+	if (pMac->lim.gHTPCOPhase != (uint8_t) pHTInfo->pcoPhase) {
+		pMac->lim.gHTPCOPhase = (uint8_t) pHTInfo->pcoPhase;
+		/* Send change notification to HAL */
+	}
+
+} /* End lim_update_sta_run_time_ht_info. */
+
+/** -------------------------------------------------------------
+   \fn lim_process_hal_ind_messages
+   \brief callback function for HAL indication
+   \param   tpAniSirGlobal pMac
+   \param    uint32_t mesgId
+   \param    void *mesgParam
+   \return tSirRetStatu - status
+   -------------------------------------------------------------*/
+
+QDF_STATUS lim_process_hal_ind_messages(tpAniSirGlobal pMac, uint32_t msgId,
+					   void *msgParam)
+{
+	/* its PE's responsibility to free msgparam when its done extracting the message parameters. */
+	struct scheduler_msg msg = {0};
+
+	switch (msgId) {
+	case SIR_LIM_DEL_TS_IND:
+	case SIR_LIM_DELETE_STA_CONTEXT_IND:
+	case SIR_LIM_BEACON_GEN_IND:
+		msg.type = (uint16_t) msgId;
+		msg.bodyptr = msgParam;
+		msg.bodyval = 0;
+		break;
+
+	default:
+		qdf_mem_free(msgParam);
+		pe_err("invalid message id: %d received", msgId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (lim_post_msg_api(pMac, &msg) != QDF_STATUS_SUCCESS) {
+		qdf_mem_free(msgParam);
+		pe_err("lim_post_msg_api failed for msgid: %d", msg.type);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_validate_delts_req() - This function validates DelTs req
+ * @mac_ctx: pointer to Global Mac structure
+ * @delts_req: pointer to delete traffic stream structure
+ * @peer_mac_addr: variable for peer mac address
+ *
+ * Function validates DelTs req originated by SME or by HAL and also
+ * sends halMsg_DelTs to HAL
+ *
+ * Return: QDF_STATUS_SUCCESS - Success, QDF_STATUS_E_FAILURE - Failure
+ */
+
+QDF_STATUS
+lim_validate_delts_req(tpAniSirGlobal mac_ctx, tpSirDeltsReq delts_req,
+		       tSirMacAddr peer_mac_addr, tpPESession psession_entry)
+{
+	tpDphHashNode sta;
+	uint8_t ts_status;
+	tSirMacTSInfo *tsinfo;
+	uint32_t i;
+	uint8_t tspec_idx;
+
+	/*
+	 * if sta
+	 *  - verify assoc state
+	 *  - del tspec locally
+	 * if ap
+	 *  - verify sta is in assoc state
+	 *  - del sta tspec locally
+	 */
+	if (delts_req == NULL) {
+		pe_err("Delete TS request pointer is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (LIM_IS_STA_ROLE(psession_entry)) {
+		uint32_t val;
+
+		/* station always talks to the AP */
+		sta = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+					&psession_entry->dph.dphHashTable);
+
+		val = sizeof(tSirMacAddr);
+		sir_copy_mac_addr(peer_mac_addr, psession_entry->bssId);
+
+	} else {
+		uint16_t associd;
+		uint8_t *macaddr = (uint8_t *) peer_mac_addr;
+
+		associd = delts_req->aid;
+		if (associd != 0)
+			sta = dph_get_hash_entry(mac_ctx, associd,
+					&psession_entry->dph.dphHashTable);
+		else
+			sta = dph_lookup_hash_entry(mac_ctx,
+						delts_req->macaddr.bytes,
+						&associd,
+						&psession_entry->dph.
+							dphHashTable);
+
+		if (sta != NULL)
+			/* TBD: check sta assoc state as well */
+			for (i = 0; i < sizeof(tSirMacAddr); i++)
+				macaddr[i] = sta->staAddr[i];
+	}
+
+	if (sta == NULL) {
+		pe_err("Cannot find station context for delts req");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if ((!sta->valid) ||
+		(sta->mlmStaContext.mlmState !=
+			eLIM_MLM_LINK_ESTABLISHED_STATE)) {
+		pe_err("Invalid Sta (or state) for DelTsReq");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	delts_req->req.wsmTspecPresent = 0;
+	delts_req->req.wmeTspecPresent = 0;
+	delts_req->req.lleTspecPresent = 0;
+
+	if ((sta->wsmEnabled) &&
+		(delts_req->req.tspec.tsinfo.traffic.accessPolicy !=
+						SIR_MAC_ACCESSPOLICY_EDCA))
+		delts_req->req.wsmTspecPresent = 1;
+	else if (sta->wmeEnabled)
+		delts_req->req.wmeTspecPresent = 1;
+	else if (sta->lleEnabled)
+		delts_req->req.lleTspecPresent = 1;
+	else {
+		pe_warn("DELTS_REQ ignore - qos is disabled");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	tsinfo = delts_req->req.wmeTspecPresent ? &delts_req->req.tspec.tsinfo
+						: &delts_req->req.tsinfo;
+	pe_debug("received DELTS_REQ message wmeTspecPresent: %d lleTspecPresent: %d wsmTspecPresent: %d tsid: %d  up: %d direction: %d",
+		delts_req->req.wmeTspecPresent,
+		delts_req->req.lleTspecPresent,
+		delts_req->req.wsmTspecPresent, tsinfo->traffic.tsid,
+		tsinfo->traffic.userPrio, tsinfo->traffic.direction);
+
+	/* if no Access Control, ignore the request */
+	if (lim_admit_control_delete_ts(mac_ctx, sta->assocId, tsinfo,
+				&ts_status, &tspec_idx) != QDF_STATUS_SUCCESS) {
+		pe_err("DELTS request for sta assocId: %d tsid: %d up: %d",
+			sta->assocId, tsinfo->traffic.tsid,
+			tsinfo->traffic.userPrio);
+		return QDF_STATUS_E_FAILURE;
+	} else if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA)
+				|| (tsinfo->traffic.accessPolicy ==
+			SIR_MAC_ACCESSPOLICY_BOTH)) {
+		/* edca only now. */
+	} else if (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) {
+		/* send message to HAL to delete TS */
+		if (QDF_STATUS_SUCCESS !=
+			lim_send_hal_msg_del_ts(mac_ctx, sta->staIndex,
+						tspec_idx, delts_req->req,
+						psession_entry->peSessionId,
+						psession_entry->bssId)) {
+			pe_warn("DelTs with UP: %d failed in lim_send_hal_msg_del_ts - ignoring request",
+				tsinfo->traffic.userPrio);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+   \fn lim_register_hal_ind_call_back
+   \brief registers callback function to HAL for any indication.
+   \param   tpAniSirGlobal pMac
+   \return none.
+   -------------------------------------------------------------*/
+void lim_register_hal_ind_call_back(tpAniSirGlobal pMac)
+{
+	struct scheduler_msg msg = {0};
+	tpHalIndCB pHalCB;
+
+	pHalCB = qdf_mem_malloc(sizeof(tHalIndCB));
+	if (!pHalCB)
+		return;
+
+	pHalCB->pHalIndCB = lim_process_hal_ind_messages;
+
+	msg.type = WMA_REGISTER_PE_CALLBACK;
+	msg.bodyptr = pHalCB;
+	msg.bodyval = 0;
+
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msg.type));
+	if (QDF_STATUS_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
+		qdf_mem_free(pHalCB);
+		pe_err("wma_post_ctrl_msg() failed");
+	}
+
+	return;
+}
+
+/**
+ * lim_process_del_ts_ind() - handle del_ts_ind from HAL
+ *
+ * @mac_ctx: pointer to Global Mac Structure
+ * @lim_msg: pointer to msg buff
+ *
+ * handles the DeleteTS indication coming from HAL or generated by PE itself
+ * in some error cases. Validates the request, sends the DelTs action frame
+ * to the Peer and sends DelTs indicatoin to HDD.
+ *
+ * Return: none
+ */
+void lim_process_del_ts_ind(tpAniSirGlobal pMac, struct scheduler_msg *limMsg)
+{
+	tpDphHashNode pSta;
+	tpDelTsParams pDelTsParam = (tpDelTsParams) (limMsg->bodyptr);
+	tpSirDeltsReq pDelTsReq = NULL;
+	tSirMacAddr peerMacAddr;
+	tpSirDeltsReqInfo pDelTsReqInfo;
+	tpLimTspecInfo pTspecInfo;
+	tpPESession psessionEntry;
+	uint8_t sessionId;
+
+	psessionEntry = pe_find_session_by_bssid(pMac, pDelTsParam->bssId,
+			&sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("session does not exist for given BssId");
+		qdf_mem_free(limMsg->bodyptr);
+		limMsg->bodyptr = NULL;
+		return;
+	}
+
+	pTspecInfo = &(pMac->lim.tspecInfo[pDelTsParam->tspecIdx]);
+	if (pTspecInfo->inuse == false) {
+		pe_err("tspec entry with index: %d is not in use",
+				pDelTsParam->tspecIdx);
+		goto error1;
+	}
+
+	pSta =
+		dph_get_hash_entry(pMac, pTspecInfo->assocId,
+				   &psessionEntry->dph.dphHashTable);
+	if (pSta == NULL) {
+		pe_err("Could not find entry in DPH table for assocId: %d",
+			pTspecInfo->assocId);
+		goto error1;
+	}
+
+	pDelTsReq = qdf_mem_malloc(sizeof(tSirDeltsReq));
+	if (!pDelTsReq)
+		goto error1;
+
+	if (pSta->wmeEnabled)
+		qdf_mem_copy(&(pDelTsReq->req.tspec), &(pTspecInfo->tspec),
+			     sizeof(tSirMacTspecIE));
+	else
+		qdf_mem_copy(&(pDelTsReq->req.tsinfo),
+			     &(pTspecInfo->tspec.tsinfo),
+			     sizeof(tSirMacTSInfo));
+
+	/* validate the req */
+	if (QDF_STATUS_SUCCESS !=
+	    lim_validate_delts_req(pMac, pDelTsReq, peerMacAddr, psessionEntry)) {
+		pe_err("lim_validate_delts_req failed");
+		goto error2;
+	}
+	pe_debug("Sent DELTS request to station with "
+		       "assocId = %d MacAddr = " MAC_ADDRESS_STR,
+		       pDelTsReq->aid, MAC_ADDR_ARRAY(peerMacAddr));
+
+	lim_send_delts_req_action_frame(pMac, peerMacAddr,
+					pDelTsReq->req.wmeTspecPresent,
+					&pDelTsReq->req.tsinfo,
+					&pDelTsReq->req.tspec, psessionEntry);
+
+	/* prepare and send an sme indication to HDD */
+	pDelTsReqInfo = qdf_mem_malloc(sizeof(tSirDeltsReqInfo));
+	if (!pDelTsReqInfo)
+		goto error3;
+
+	if (pSta->wmeEnabled)
+		qdf_mem_copy(&(pDelTsReqInfo->tspec), &(pTspecInfo->tspec),
+			     sizeof(tSirMacTspecIE));
+	else
+		qdf_mem_copy(&(pDelTsReqInfo->tsinfo),
+			     &(pTspecInfo->tspec.tsinfo),
+			     sizeof(tSirMacTSInfo));
+
+	lim_send_sme_delts_ind(pMac, pDelTsReqInfo, pDelTsReq->aid, psessionEntry);
+
+error3:
+	qdf_mem_free(pDelTsReqInfo);
+error2:
+	qdf_mem_free(pDelTsReq);
+error1:
+	qdf_mem_free(limMsg->bodyptr);
+	limMsg->bodyptr = NULL;
+	return;
+}
+
+/**
+ * @function :  lim_post_sm_state_update()
+ *
+ * @brief  :  This function Updates the HAL and Softmac about the change in the STA's SMPS state.
+ *
+ *      LOGIC:
+ *
+ *      ASSUMPTIONS:
+ *          NA
+ *
+ *      NOTE:
+ *          NA
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  limMsg - Lim Message structure object with the MimoPSparam in body
+ * @return None
+ */
+QDF_STATUS
+lim_post_sm_state_update(tpAniSirGlobal pMac,
+			 uint16_t staIdx, tSirMacHTMIMOPowerSaveState state,
+			 uint8_t *pPeerStaMac, uint8_t sessionId)
+{
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msgQ = {0};
+	tpSetMIMOPS pMIMO_PSParams;
+
+	msgQ.reserved = 0;
+	msgQ.type = WMA_SET_MIMOPS_REQ;
+
+	/* Allocate for WMA_SET_MIMOPS_REQ */
+	pMIMO_PSParams = qdf_mem_malloc(sizeof(tSetMIMOPS));
+	if (!pMIMO_PSParams)
+		return QDF_STATUS_E_NOMEM;
+
+	pMIMO_PSParams->htMIMOPSState = state;
+	pMIMO_PSParams->staIdx = staIdx;
+	pMIMO_PSParams->fsendRsp = true;
+	pMIMO_PSParams->sessionId = sessionId;
+	qdf_mem_copy(pMIMO_PSParams->peerMac, pPeerStaMac, sizeof(tSirMacAddr));
+
+	msgQ.bodyptr = pMIMO_PSParams;
+	msgQ.bodyval = 0;
+
+	pe_debug("Sending WMA_SET_MIMOPS_REQ");
+
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		pe_err("Posting WMA_SET_MIMOPS_REQ to HAL failed! Reason: %d",
+			retCode);
+		qdf_mem_free(pMIMO_PSParams);
+		return retCode;
+	}
+
+	return retCode;
+}
+
+void lim_pkt_free(tpAniSirGlobal pMac,
+		  eFrameType frmType, uint8_t *pRxPacketInfo, void *pBody)
+{
+	(void)pMac;
+	(void)frmType;
+	(void)pRxPacketInfo;
+	(void)pBody;
+}
+
+/**
+ * lim_get_b_dfrom_rx_packet()
+ *
+ ***FUNCTION:
+ * This function is called to get pointer to Polaris
+ * Buffer Descriptor containing MAC header & other control
+ * info from the body of the message posted to LIM.
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param  body    - Received message body
+ * @param  pRxPacketInfo     - Pointer to received BD
+ * @return None
+ */
+
+void
+lim_get_b_dfrom_rx_packet(tpAniSirGlobal pMac, void *body, uint32_t **pRxPacketInfo)
+{
+	*pRxPacketInfo = (uint32_t *) body;
+} /*** end lim_get_b_dfrom_rx_packet() ***/
+
+void lim_add_channel_status_info(tpAniSirGlobal p_mac,
+				 struct lim_channel_status *channel_stat,
+				 uint8_t channel_id)
+{
+	uint8_t i;
+	bool found = false;
+	struct lim_scan_channel_status *channel_info =
+		&p_mac->lim.scan_channel_status;
+	struct lim_channel_status *channel_status_list =
+		channel_info->channel_status_list;
+	uint8_t total_channel = channel_info->total_channel;
+
+	if (!p_mac->sap.acs_with_more_param)
+		return;
+
+	for (i = 0; i < total_channel; i++) {
+		if (channel_status_list[i].channel_id == channel_id) {
+			if (channel_stat->cmd_flags ==
+			    WMI_CHAN_InFO_END_RESP &&
+			    channel_status_list[i].cmd_flags ==
+			    WMI_CHAN_InFO_START_RESP) {
+				/* adjust to delta value for counts */
+				channel_stat->rx_clear_count -=
+				    channel_status_list[i].rx_clear_count;
+				channel_stat->cycle_count -=
+				    channel_status_list[i].cycle_count;
+				channel_stat->rx_frame_count -=
+				    channel_status_list[i].rx_frame_count;
+				channel_stat->tx_frame_count -=
+				    channel_status_list[i].tx_frame_count;
+				channel_stat->bss_rx_cycle_count -=
+				    channel_status_list[i].bss_rx_cycle_count;
+			}
+			qdf_mem_copy(&channel_status_list[i], channel_stat,
+				     sizeof(*channel_status_list));
+			found = true;
+			break;
+		}
+	}
+
+	if (!found) {
+		if (total_channel < SIR_MAX_SUPPORTED_CHANNEL_LIST) {
+			qdf_mem_copy(&channel_status_list[total_channel++],
+				     channel_stat,
+				     sizeof(*channel_status_list));
+			channel_info->total_channel = total_channel;
+		} else {
+			pe_warn("Chan cnt exceed, channel_id=%d", channel_id);
+		}
+	}
+
+	return;
+}
+
+/**
+ * @function :  lim_is_channel_valid_for_channel_switch()
+ *
+ * @brief  :  This function checks if the channel to which AP
+ *            is expecting us to switch, is a valid channel for us.
+ *      LOGIC:
+ *
+ *      ASSUMPTIONS:
+ *          NA
+ *
+ *      NOTE:
+ *          NA
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  channel - New channel to which we are expected to move
+ * @return None
+ */
+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;
+	tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	bool ok = false;
+
+	if (policy_mgr_is_chan_ok_for_dnbs(pMac->psoc, channel, &ok)) {
+		pe_err("policy_mgr_is_chan_ok_for_dnbs() returned error");
+		return false;
+	}
+
+	if (!ok) {
+		pe_debug("channel not ok for DNBS");
+		return false;
+	}
+
+	if (wlan_cfg_get_str(pMac, WNI_CFG_VALID_CHANNEL_LIST,
+			     (uint8_t *) validChannelList,
+			     (uint32_t *) &validChannelListLen) !=
+			QDF_STATUS_SUCCESS) {
+		pe_err("could not retrieve valid channel list");
+		return false;
+	}
+
+	for (index = 0; index < validChannelListLen; index++) {
+		if (validChannelList[index] != channel)
+			continue;
+
+		ok = policy_mgr_is_valid_for_channel_switch(pMac->psoc,
+							    channel);
+		return ok;
+	}
+
+	/* channel does not belong to list of valid channels */
+	return false;
+}
+
+/**------------------------------------------------------
+   \fn     __lim_fill_tx_control_params
+   \brief  Fill the message for stopping/resuming tx.
+
+   \param  pMac
+   \param  pTxCtrlMsg - Pointer to tx control message.
+   \param  type - Which way we want to stop/ resume tx.
+   \param  mode - To stop/resume.
+   -------------------------------------------------------*/
+static QDF_STATUS
+__lim_fill_tx_control_params(tpAniSirGlobal pMac, tpTxControlParams pTxCtrlMsg,
+			     tLimQuietTxMode type, tLimControlTx mode)
+{
+
+	tpPESession psessionEntry = &pMac->lim.gpSession[0];
+
+	if (mode == eLIM_STOP_TX)
+		pTxCtrlMsg->stopTx = true;
+	else
+		pTxCtrlMsg->stopTx = false;
+
+	switch (type) {
+	case eLIM_TX_ALL:
+		/** Stops/resumes transmission completely */
+		pTxCtrlMsg->fCtrlGlobal = 1;
+		break;
+
+	case eLIM_TX_BSS_BUT_BEACON:
+		/** Stops/resumes transmission on a particular BSS. Stopping BSS, doesn't
+		 *  stop beacon transmission.
+		 */
+		pTxCtrlMsg->ctrlBss = 1;
+		pTxCtrlMsg->bssBitmap |= (1 << psessionEntry->bssIdx);
+		break;
+
+	case eLIM_TX_STA:
+	/** Memory for station bitmap is allocated dynamically in caller of this
+	 *  so decode properly here and fill the bitmap. Now not implemented,
+	 *  fall through.
+	 */
+	case eLIM_TX_BSS:
+	/* Fall thru... */
+	default:
+		pe_warn("Invalid case: Not Handled");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * @function :  lim_frame_transmission_control()
+ *
+ * @brief  :  This API is called by the user to halt/resume any frame
+ *       transmission from the device. If stopped, all frames will be
+ *            queued starting from hardware. Then back-pressure
+ *            is built till the driver.
+ *      LOGIC:
+ *
+ *      ASSUMPTIONS:
+ *          NA
+ *
+ *      NOTE:
+ *          NA
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @return None
+ */
+void lim_frame_transmission_control(tpAniSirGlobal pMac, tLimQuietTxMode type,
+				    tLimControlTx mode)
+{
+
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpTxControlParams pTxCtrlMsg;
+	struct scheduler_msg msgQ = {0};
+	uint8_t nBytes = 0; /* No of bytes required for station bitmap. */
+
+	/** Allocate only required number of bytes for station bitmap
+	 * Make it to align to 4 byte boundary  */
+	nBytes = (uint8_t) HALMSG_NUMBYTES_STATION_BITMAP(pMac->lim.maxStation);
+
+	pTxCtrlMsg = qdf_mem_malloc(sizeof(*pTxCtrlMsg) + nBytes);
+	if (!pTxCtrlMsg)
+		return;
+
+	status = __lim_fill_tx_control_params(pMac, pTxCtrlMsg, type, mode);
+	if (status != QDF_STATUS_SUCCESS) {
+		qdf_mem_free(pTxCtrlMsg);
+		pe_err("__lim_fill_tx_control_params failed, status: %d",
+			status);
+		return;
+	}
+
+	msgQ.bodyptr = (void *)pTxCtrlMsg;
+	msgQ.bodyval = 0;
+	msgQ.reserved = 0;
+	msgQ.type = WMA_TRANSMISSION_CONTROL_IND;
+
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+	if (wma_post_ctrl_msg(pMac, &msgQ) != QDF_STATUS_SUCCESS) {
+		qdf_mem_free(pTxCtrlMsg);
+		pe_err("Posting Message to HAL failed");
+		return;
+	}
+
+	pe_debug("Stopping the transmission of all packets, indicated softmac tx_control: %d",
+		mode);
+
+	return;
+}
+
+/**
+ * @function :  lim_restore_pre_channel_switch_state()
+ *
+ * @brief  :  This API is called by the user to undo any
+ *            specific changes done on the device during
+ *            channel switch.
+ *      LOGIC:
+ *
+ *      ASSUMPTIONS:
+ *          NA
+ *
+ *      NOTE:
+ *          NA
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+QDF_STATUS
+lim_restore_pre_channel_switch_state(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+
+	if (!LIM_IS_STA_ROLE(psessionEntry))
+		return retCode;
+
+	/* Channel switch should be ready for the next time */
+	psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT;
+
+	/* Restore the frame transmission, all the time. */
+	lim_frame_transmission_control(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+
+	return retCode;
+}
+
+/**--------------------------------------------
+   \fn       lim_restore_pre_quiet_state
+   \brief   Restore the pre quiet state
+
+   \param pMac
+   \return NONE
+   ---------------------------------------------*/
+QDF_STATUS lim_restore_pre_quiet_state(tpAniSirGlobal pMac,
+					  tpPESession psessionEntry)
+{
+
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+
+	if (pMac->lim.gLimSystemRole != eLIM_STA_ROLE)
+		return retCode;
+
+	/* Quiet should be ready for the next time */
+	psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+
+	/* Restore the frame transmission, all the time. */
+	if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING)
+		lim_frame_transmission_control(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+
+	return retCode;
+}
+
+/**
+ * @function: lim_prepare_for11h_channel_switch()
+ *
+ * @brief  :  This API is called by the user to prepare for
+ *            11h channel switch. As of now, the API does
+ *            very minimal work. User can add more into the
+ *            same API if needed.
+ *      LOGIC:
+ *
+ *      ASSUMPTIONS:
+ *          NA
+ *
+ *      NOTE:
+ *          NA
+ *
+ * @param  pMac - Pointer to Global MAC structure
+ * @param  psessionEntry
+ * @return None
+ */
+void
+lim_prepare_for11h_channel_switch(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	if (!LIM_IS_STA_ROLE(psessionEntry))
+		return;
+
+	/* Flag to indicate 11h channel switch in progress */
+	psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_RUNNING;
+
+	if (pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE ||
+	    pMac->lim.gLimSmeState == eLIM_SME_CHANNEL_SCAN_STATE) {
+		pe_debug("Posting finish scan as we are in scan state");
+		/* Stop ongoing scanning if any */
+		if (GET_LIM_PROCESS_DEFD_MESGS(pMac)) {
+			/* Set the resume channel to Any valid channel (invalid). */
+			/* This will instruct HAL to set it to any previous valid channel. */
+			pe_set_resume_channel(pMac, 0, 0);
+		} else {
+			lim_restore_pre_channel_switch_state(pMac, psessionEntry);
+		}
+		return;
+	} else {
+		pe_debug("Not in scan state, start channel switch timer");
+		/** We are safe to switch channel at this point */
+		lim_stop_tx_and_switch_channel(pMac, psessionEntry->peSessionId);
+	}
+}
+
+/**----------------------------------------------------
+   \fn        lim_get_nw_type
+
+   \brief    Get type of the network from data packet or beacon
+   \param pMac
+   \param channelNum - Channel number
+   \param type - Type of packet.
+   \param pBeacon - Pointer to beacon or probe response
+
+   \return Network type a/b/g.
+   -----------------------------------------------------*/
+tSirNwType lim_get_nw_type(tpAniSirGlobal pMac, uint8_t channelNum, uint32_t type,
+			   tpSchBeaconStruct pBeacon)
+{
+	tSirNwType nwType = eSIR_11B_NW_TYPE;
+
+	if (type == SIR_MAC_DATA_FRAME) {
+		if ((channelNum > 0) && (channelNum < 15)) {
+			nwType = eSIR_11G_NW_TYPE;
+		} else {
+			nwType = eSIR_11A_NW_TYPE;
+		}
+	} else {
+		if ((channelNum > 0) && (channelNum < 15)) {
+			int i;
+			/* 11b or 11g packet */
+			/* 11g iff extended Rate IE is present or */
+			/* if there is an A rate in suppRate IE */
+			for (i = 0; i < pBeacon->supportedRates.numRates; i++) {
+				if (sirIsArate
+					    (pBeacon->supportedRates.rate[i] & 0x7f)) {
+					nwType = eSIR_11G_NW_TYPE;
+					break;
+				}
+			}
+			if (pBeacon->extendedRatesPresent) {
+				nwType = eSIR_11G_NW_TYPE;
+			} else if (pBeacon->HTInfo.present ||
+				   IS_BSS_VHT_CAPABLE(pBeacon->VHTCaps)) {
+				nwType = eSIR_11G_NW_TYPE;
+			}
+		} else {
+			/* 11a packet */
+			nwType = eSIR_11A_NW_TYPE;
+		}
+	}
+	return nwType;
+}
+
+/**---------------------------------------------------------
+   \fn        lim_get_channel_from_beacon
+   \brief    To extract channel number from beacon
+
+   \param pMac
+   \param pBeacon - Pointer to beacon or probe rsp
+   \return channel number
+   -----------------------------------------------------------*/
+uint8_t lim_get_channel_from_beacon(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon)
+{
+	uint8_t channelNum = 0;
+
+	if (pBeacon->dsParamsPresent)
+		channelNum = pBeacon->channelNumber;
+	else if (pBeacon->HTInfo.present)
+		channelNum = pBeacon->HTInfo.primaryChannel;
+	else
+		channelNum = pBeacon->channelNumber;
+
+	return channelNum;
+}
+
+void lim_set_tspec_uapsd_mask_per_session(tpAniSirGlobal pMac,
+					  tpPESession psessionEntry,
+					  tSirMacTSInfo *pTsInfo, uint32_t action)
+{
+	uint8_t userPrio = (uint8_t) pTsInfo->traffic.userPrio;
+	uint16_t direction = pTsInfo->traffic.direction;
+	uint8_t ac = upToAc(userPrio);
+
+	pe_debug("Set UAPSD mask for AC: %d dir: %d action: %d"
+			, ac, direction, action);
+
+	/* Converting AC to appropriate Uapsd Bit Mask
+	 * AC_BE(0) --> UAPSD_BITOFFSET_ACVO(3)
+	 * AC_BK(1) --> UAPSD_BITOFFSET_ACVO(2)
+	 * AC_VI(2) --> UAPSD_BITOFFSET_ACVO(1)
+	 * AC_VO(3) --> UAPSD_BITOFFSET_ACVO(0)
+	 */
+	ac = ((~ac) & 0x3);
+
+	if (action == CLEAR_UAPSD_MASK) {
+		if (direction == SIR_MAC_DIRECTION_UPLINK)
+			psessionEntry->gUapsdPerAcTriggerEnableMask &=
+				~(1 << ac);
+		else if (direction == SIR_MAC_DIRECTION_DNLINK)
+			psessionEntry->gUapsdPerAcDeliveryEnableMask &=
+				~(1 << ac);
+		else if (direction == SIR_MAC_DIRECTION_BIDIR) {
+			psessionEntry->gUapsdPerAcTriggerEnableMask &=
+				~(1 << ac);
+			psessionEntry->gUapsdPerAcDeliveryEnableMask &=
+				~(1 << ac);
+		}
+	} else if (action == SET_UAPSD_MASK) {
+		if (direction == SIR_MAC_DIRECTION_UPLINK)
+			psessionEntry->gUapsdPerAcTriggerEnableMask |=
+				(1 << ac);
+		else if (direction == SIR_MAC_DIRECTION_DNLINK)
+			psessionEntry->gUapsdPerAcDeliveryEnableMask |=
+				(1 << ac);
+		else if (direction == SIR_MAC_DIRECTION_BIDIR) {
+			psessionEntry->gUapsdPerAcTriggerEnableMask |=
+				(1 << ac);
+			psessionEntry->gUapsdPerAcDeliveryEnableMask |=
+				(1 << ac);
+		}
+	}
+
+	pe_debug("New psessionEntry->gUapsdPerAcTriggerEnableMask 0x%x psessionEntry->gUapsdPerAcDeliveryEnableMask 0x%x",
+		psessionEntry->gUapsdPerAcTriggerEnableMask,
+		psessionEntry->gUapsdPerAcDeliveryEnableMask);
+
+	return;
+}
+
+/**
+ * lim_handle_heart_beat_timeout_for_session() - Handle heart beat time out
+ * @mac_ctx: pointer to Global Mac Structure
+ * @psession_entry: pointer to tpPESession
+ *
+ * Function handles heart beat time out for session
+ *
+ * Return: none
+ */
+void lim_handle_heart_beat_timeout_for_session(tpAniSirGlobal mac_ctx,
+					       tpPESession psession_entry)
+{
+	if (psession_entry->valid == true) {
+		if (psession_entry->bssType == eSIR_IBSS_MODE)
+			lim_ibss_heart_beat_handle(mac_ctx, psession_entry);
+
+		if ((psession_entry->bssType == eSIR_INFRASTRUCTURE_MODE) &&
+					(LIM_IS_STA_ROLE(psession_entry)))
+			lim_handle_heart_beat_failure(mac_ctx, psession_entry);
+	}
+	/*
+	 * In the function lim_handle_heart_beat_failure things can change
+	 * so check for the session entry  valid and the other things
+	 * again
+	 */
+	if ((psession_entry->valid == true) &&
+		(psession_entry->bssType == eSIR_INFRASTRUCTURE_MODE) &&
+			(LIM_IS_STA_ROLE(psession_entry)) &&
+				(psession_entry->LimHBFailureStatus == true)) {
+		tLimTimers *lim_timer  = &mac_ctx->lim.limTimers;
+		/*
+		 * Activate Probe After HeartBeat Timer incase HB
+		 * Failure detected
+		 */
+		pe_debug("Sending Probe for Session: %d",
+			psession_entry->bssIdx);
+		lim_deactivate_and_change_timer(mac_ctx,
+			eLIM_PROBE_AFTER_HB_TIMER);
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 0,
+			eLIM_PROBE_AFTER_HB_TIMER));
+		if (tx_timer_activate(&lim_timer->gLimProbeAfterHBTimer)
+					!= TX_SUCCESS)
+			pe_err("Fail to re-activate Probe-after-hb timer");
+	}
+}
+
+uint8_t lim_get_current_operating_channel(tpAniSirGlobal pMac)
+{
+	uint8_t i;
+
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		if (pMac->lim.gpSession[i].valid == true) {
+			if ((pMac->lim.gpSession[i].bssType ==
+			     eSIR_INFRASTRUCTURE_MODE)
+			    && (pMac->lim.gpSession[i].limSystemRole ==
+				eLIM_STA_ROLE)) {
+				return pMac->lim.gpSession[i].
+				       currentOperChannel;
+			}
+		}
+	}
+	return 0;
+}
+
+/**
+ * lim_process_add_sta_rsp() - process WDA_ADD_STA_RSP from WMA
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: msg from WMA
+ *
+ * @Return: void
+ */
+void lim_process_add_sta_rsp(tpAniSirGlobal mac_ctx, struct scheduler_msg *msg)
+{
+	tpPESession session;
+	tpAddStaParams add_sta_params;
+
+	add_sta_params = (tpAddStaParams) msg->bodyptr;
+
+	session = pe_find_session_by_session_id(mac_ctx,
+			add_sta_params->sessionId);
+	if (session == NULL) {
+		pe_err("Session Does not exist for given sessionID");
+		qdf_mem_free(add_sta_params);
+		return;
+	}
+	session->csaOffloadEnable = add_sta_params->csaOffloadEnable;
+	if (LIM_IS_IBSS_ROLE(session))
+		(void)lim_ibss_add_sta_rsp(mac_ctx, msg->bodyptr, session);
+	else if (LIM_IS_NDI_ROLE(session))
+		lim_ndp_add_sta_rsp(mac_ctx, session, msg->bodyptr);
+#ifdef FEATURE_WLAN_TDLS
+	else if (add_sta_params->staType == STA_ENTRY_TDLS_PEER)
+		lim_process_tdls_add_sta_rsp(mac_ctx, msg->bodyptr, session);
+#endif
+	else
+		lim_process_mlm_add_sta_rsp(mac_ctx, msg, session);
+
+}
+
+/**
+ * lim_update_beacon() - This function updates beacon
+ * @mac_ctx: pointer to Global Mac Structure
+ *
+ * This Function is invoked to update the beacon
+ *
+ * Return: none
+ */
+void lim_update_beacon(tpAniSirGlobal mac_ctx)
+{
+	uint8_t i;
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		if (mac_ctx->lim.gpSession[i].valid != true)
+			continue;
+		if (((mac_ctx->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE)
+			|| (mac_ctx->lim.gpSession[i].limSystemRole ==
+					eLIM_STA_IN_IBSS_ROLE))
+			&& (eLIM_SME_NORMAL_STATE ==
+				mac_ctx->lim.gpSession[i].limSmeState)) {
+
+			sch_set_fixed_beacon_fields(mac_ctx,
+						&mac_ctx->lim.gpSession[i]);
+
+			if (false == mac_ctx->sap.SapDfsInfo.
+					is_dfs_cac_timer_running)
+				lim_send_beacon_ind(mac_ctx,
+						&mac_ctx->lim.gpSession[i],
+						REASON_DEFAULT);
+		}
+	}
+}
+
+/**
+ * lim_handle_heart_beat_failure_timeout - handle heart beat failure
+ * @mac_ctx: pointer to Global Mac Structure
+ *
+ * Function handle heart beat failure timeout
+ *
+ * Return: none
+ */
+void lim_handle_heart_beat_failure_timeout(tpAniSirGlobal mac_ctx)
+{
+	uint8_t i;
+	tpPESession psession_entry;
+	/*
+	 * Probe response is not received  after HB failure.
+	 * This is handled by LMM sub module.
+	 */
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		if (mac_ctx->lim.gpSession[i].valid != true)
+			continue;
+		psession_entry = &mac_ctx->lim.gpSession[i];
+		if (psession_entry->LimHBFailureStatus != true)
+			continue;
+		pe_debug("SME: %d MLME: %d HB-Count: %d",
+				psession_entry->limSmeState,
+				psession_entry->limMlmState,
+				psession_entry->LimRxedBeaconCntDuringHB);
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_HB_FAILURE_TIMEOUT,
+					psession_entry, 0, 0);
+#endif
+		if ((psession_entry->limMlmState ==
+					eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+			(psession_entry->limSmeState !=
+					eLIM_SME_WT_DISASSOC_STATE) &&
+			(psession_entry->limSmeState !=
+					eLIM_SME_WT_DEAUTH_STATE) &&
+			((!LIM_IS_CONNECTION_ACTIVE(psession_entry)) ||
+			/*
+			 * Disconnect even if we have not received a single
+			 * beacon after connection.
+			 */
+			 (psession_entry->currentBssBeaconCnt == 0))) {
+			pe_debug("for session: %d",
+						psession_entry->peSessionId);
+
+			lim_send_deauth_mgmt_frame(mac_ctx,
+				eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON,
+				psession_entry->bssId, psession_entry, false);
+
+			/*
+			 * AP did not respond to Probe Request.
+			 * Tear down link with it.
+			 */
+			lim_tear_down_link_with_ap(mac_ctx,
+						psession_entry->peSessionId,
+						eSIR_BEACON_MISSED);
+			mac_ctx->lim.gLimProbeFailureAfterHBfailedCnt++;
+		} else {
+			pe_err("Unexpected wt-probe-timeout in state");
+			lim_print_mlm_state(mac_ctx, LOGE,
+				psession_entry->limMlmState);
+			if (mac_ctx->sme.tx_queue_cb)
+				mac_ctx->sme.tx_queue_cb(mac_ctx->hdd_handle,
+						psession_entry->smeSessionId,
+						WLAN_WAKE_ALL_NETIF_QUEUE,
+						WLAN_CONTROL_PATH);
+		}
+	}
+	/*
+	 * Deactivate Timer ProbeAfterHB Timer -> As its a oneshot timer,
+	 * need not deactivate the timer
+	 * tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer);
+	 */
+}
+
+/*
+ * This function assumes there will not be more than one IBSS session active at any time.
+ */
+tpPESession lim_is_ibss_session_active(tpAniSirGlobal pMac)
+{
+	uint8_t i;
+
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		if ((pMac->lim.gpSession[i].valid) &&
+		    (pMac->lim.gpSession[i].limSystemRole ==
+		     eLIM_STA_IN_IBSS_ROLE))
+			return &pMac->lim.gpSession[i];
+	}
+
+	return NULL;
+}
+
+tpPESession lim_is_ap_session_active(tpAniSirGlobal pMac)
+{
+	uint8_t i;
+
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		if (pMac->lim.gpSession[i].valid &&
+		    (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE))
+			return &pMac->lim.gpSession[i];
+	}
+
+	return NULL;
+}
+
+/**---------------------------------------------------------
+   \fn        lim_handle_defer_msg_error
+   \brief    handles error scenario, when the msg can not be deferred.
+   \param pMac
+   \param pLimMsg LIM msg, which could not be deferred.
+   \return void
+   -----------------------------------------------------------*/
+
+void lim_handle_defer_msg_error(tpAniSirGlobal pMac,
+				struct scheduler_msg *pLimMsg)
+{
+	if (SIR_BB_XPORT_MGMT_MSG == pLimMsg->type) {
+		lim_decrement_pending_mgmt_count(pMac);
+		cds_pkt_return_packet((cds_pkt_t *) pLimMsg->bodyptr);
+		pLimMsg->bodyptr = NULL;
+	} else if (pLimMsg->bodyptr != NULL) {
+		qdf_mem_free(pLimMsg->bodyptr);
+		pLimMsg->bodyptr = NULL;
+	}
+
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**---------------------------------------------------------
+   \fn    lim_diag_event_report
+   \brief This function reports Diag event
+   \param pMac
+   \param eventType
+   \param bssid
+   \param status
+   \param reasonCode
+   \return void
+   -----------------------------------------------------------*/
+void lim_diag_event_report(tpAniSirGlobal pMac, uint16_t eventType,
+			   tpPESession pSessionEntry, uint16_t status,
+			   uint16_t reasonCode)
+{
+	tSirMacAddr nullBssid = { 0, 0, 0, 0, 0, 0 };
+
+	WLAN_HOST_DIAG_EVENT_DEF(peEvent, host_event_wlan_pe_payload_type);
+
+	qdf_mem_set(&peEvent, sizeof(host_event_wlan_pe_payload_type), 0);
+
+	if (NULL == pSessionEntry) {
+		qdf_mem_copy(peEvent.bssid, nullBssid, sizeof(tSirMacAddr));
+		peEvent.sme_state = (uint16_t) pMac->lim.gLimSmeState;
+		peEvent.mlm_state = (uint16_t) pMac->lim.gLimMlmState;
+
+	} else {
+		qdf_mem_copy(peEvent.bssid, pSessionEntry->bssId,
+			     sizeof(tSirMacAddr));
+		peEvent.sme_state = (uint16_t) pSessionEntry->limSmeState;
+		peEvent.mlm_state = (uint16_t) pSessionEntry->limMlmState;
+	}
+	peEvent.event_type = eventType;
+	peEvent.status = status;
+	peEvent.reason_code = reasonCode;
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&peEvent, EVENT_WLAN_PE);
+	return;
+}
+
+static void lim_diag_fill_mgmt_event_report(tpAniSirGlobal mac_ctx,
+			tpSirMacMgmtHdr mac_hdr,
+			tpPESession session, uint16_t result_code,
+			uint16_t reason_code,
+			struct host_event_wlan_mgmt_payload_type *mgmt_event)
+{
+	uint8_t length;
+
+	qdf_mem_set(mgmt_event, sizeof(*mgmt_event), 0);
+	mgmt_event->mgmt_type = mac_hdr->fc.type;
+	mgmt_event->mgmt_subtype = mac_hdr->fc.subType;
+	qdf_mem_copy(mgmt_event->self_mac_addr, session->selfMacAddr,
+		     QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(mgmt_event->bssid, session->bssId,
+		     QDF_MAC_ADDR_SIZE);
+	length = session->ssId.length;
+	if (length > SIR_MAC_MAX_SSID_LENGTH)
+		length = SIR_MAC_MAX_SSID_LENGTH;
+	qdf_mem_copy(mgmt_event->ssid, session->ssId.ssId, length);
+	mgmt_event->ssid_len = length;
+	mgmt_event->operating_channel = session->currentOperChannel;
+	mgmt_event->result_code = result_code;
+	mgmt_event->reason_code = reason_code;
+}
+
+void lim_diag_mgmt_tx_event_report(tpAniSirGlobal mac_ctx, void *mgmt_hdr,
+				   tpPESession session, uint16_t result_code,
+				   uint16_t reason_code)
+{
+	tpSirMacMgmtHdr mac_hdr = mgmt_hdr;
+
+	WLAN_HOST_DIAG_EVENT_DEF(mgmt_event,
+				 struct host_event_wlan_mgmt_payload_type);
+	if (!session || !mac_hdr) {
+		pe_err("not valid input");
+		return;
+	}
+	lim_diag_fill_mgmt_event_report(mac_ctx, mac_hdr, session,
+					result_code, reason_code, &mgmt_event);
+
+	pe_debug("TX frame: type:%d sub_type:%d seq_num:%d ssid:%.*s selfmacaddr:%pM bssid:%pM channel:%d",
+		 mgmt_event.mgmt_type, mgmt_event.mgmt_subtype,
+		 ((mac_hdr->seqControl.seqNumHi << 4) |
+				mac_hdr->seqControl.seqNumLo),
+		 mgmt_event.ssid_len, mgmt_event.ssid,
+		 mgmt_event.self_mac_addr, mgmt_event.bssid,
+		 mgmt_event.operating_channel);
+	WLAN_HOST_DIAG_EVENT_REPORT(&mgmt_event, EVENT_WLAN_HOST_MGMT_TX_V2);
+}
+
+void lim_diag_mgmt_rx_event_report(tpAniSirGlobal mac_ctx, void *mgmt_hdr,
+				   tpPESession session, uint16_t result_code,
+				   uint16_t reason_code)
+{
+	tpSirMacMgmtHdr mac_hdr = mgmt_hdr;
+
+	WLAN_HOST_DIAG_EVENT_DEF(mgmt_event,
+				 struct host_event_wlan_mgmt_payload_type);
+	if (!session || !mac_hdr) {
+		pe_debug("not valid input");
+		return;
+	}
+	lim_diag_fill_mgmt_event_report(mac_ctx, mac_hdr, session,
+					result_code, reason_code, &mgmt_event);
+	pe_debug("RX frame: type:%d sub_type:%d seq_num:%d ssid:%.*s selfmacaddr:%pM bssid:%pM channel:%d",
+		 mgmt_event.mgmt_type, mgmt_event.mgmt_subtype,
+		 ((mac_hdr->seqControl.seqNumHi << 4) |
+				mac_hdr->seqControl.seqNumLo),
+		 mgmt_event.ssid_len, mgmt_event.ssid,
+		 mgmt_event.self_mac_addr, mgmt_event.bssid,
+		 mgmt_event.operating_channel);
+	WLAN_HOST_DIAG_EVENT_REPORT(&mgmt_event, EVENT_WLAN_HOST_MGMT_RX_V2);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+/* Returns length of P2P stream and Pointer ie passed to this function is filled with noa stream */
+
+uint8_t lim_build_p2p_ie(tpAniSirGlobal pMac, uint8_t *ie, uint8_t *data,
+			 uint8_t ie_len)
+{
+	int length = 0;
+	uint8_t *ptr = ie;
+
+	ptr[length++] = SIR_MAC_EID_VENDOR;
+	ptr[length++] = ie_len + SIR_MAC_P2P_OUI_SIZE;
+	qdf_mem_copy(&ptr[length], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
+	qdf_mem_copy(&ptr[length + SIR_MAC_P2P_OUI_SIZE], data, ie_len);
+	return ie_len + SIR_P2P_IE_HEADER_LEN;
+}
+
+/* Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream */
+
+uint8_t lim_get_noa_attr_stream_in_mult_p2p_ies(tpAniSirGlobal pMac,
+						uint8_t *noaStream, uint8_t noaLen,
+						uint8_t overFlowLen)
+{
+	uint8_t overFlowP2pStream[SIR_MAX_NOA_ATTR_LEN];
+
+	if ((noaLen <= (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) &&
+	    (noaLen >= overFlowLen) && (overFlowLen <= SIR_MAX_NOA_ATTR_LEN)) {
+		qdf_mem_copy(overFlowP2pStream,
+			     noaStream + noaLen - overFlowLen, overFlowLen);
+		noaStream[noaLen - overFlowLen] = SIR_MAC_EID_VENDOR;
+		noaStream[noaLen - overFlowLen + 1] =
+			overFlowLen + SIR_MAC_P2P_OUI_SIZE;
+		qdf_mem_copy(noaStream + noaLen - overFlowLen + 2,
+			     SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
+		qdf_mem_copy(noaStream + noaLen + 2 + SIR_MAC_P2P_OUI_SIZE -
+			     overFlowLen, overFlowP2pStream, overFlowLen);
+	}
+
+	return noaLen + SIR_P2P_IE_HEADER_LEN;
+
+}
+
+/* Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream */
+uint8_t lim_get_noa_attr_stream(tpAniSirGlobal pMac, uint8_t *pNoaStream,
+				tpPESession psessionEntry)
+{
+	uint8_t len = 0;
+
+	uint8_t *pBody = pNoaStream;
+
+	if ((psessionEntry != NULL) && (psessionEntry->valid) &&
+	    (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
+		if ((!(psessionEntry->p2pGoPsUpdate.uNoa1Duration))
+		    && (!(psessionEntry->p2pGoPsUpdate.uNoa2Duration))
+		    && (!psessionEntry->p2pGoPsUpdate.oppPsFlag)
+		    )
+			return 0;  /* No NoA Descriptor then return 0 */
+
+		pBody[0] = SIR_P2P_NOA_ATTR;
+
+		pBody[3] = psessionEntry->p2pGoPsUpdate.index;
+		pBody[4] =
+			psessionEntry->p2pGoPsUpdate.ctWin | (psessionEntry->
+							      p2pGoPsUpdate.
+							      oppPsFlag << 7);
+		len = 5;
+		pBody += len;
+
+		if (psessionEntry->p2pGoPsUpdate.uNoa1Duration) {
+			*pBody = psessionEntry->p2pGoPsUpdate.uNoa1IntervalCnt;
+			pBody += 1;
+			len += 1;
+
+			*((uint32_t *) (pBody)) =
+				sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+						      uNoa1Duration);
+			pBody += sizeof(uint32_t);
+			len += 4;
+
+			*((uint32_t *) (pBody)) =
+				sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+						      uNoa1Interval);
+			pBody += sizeof(uint32_t);
+			len += 4;
+
+			*((uint32_t *) (pBody)) =
+				sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+						      uNoa1StartTime);
+			pBody += sizeof(uint32_t);
+			len += 4;
+
+		}
+
+		if (psessionEntry->p2pGoPsUpdate.uNoa2Duration) {
+			*pBody = psessionEntry->p2pGoPsUpdate.uNoa2IntervalCnt;
+			pBody += 1;
+			len += 1;
+
+			*((uint32_t *) (pBody)) =
+				sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+						      uNoa2Duration);
+			pBody += sizeof(uint32_t);
+			len += 4;
+
+			*((uint32_t *) (pBody)) =
+				sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+						      uNoa2Interval);
+			pBody += sizeof(uint32_t);
+			len += 4;
+
+			*((uint32_t *) (pBody)) =
+				sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+						      uNoa2StartTime);
+			pBody += sizeof(uint32_t);
+			len += 4;
+
+		}
+
+		pBody = pNoaStream + 1;
+		*((uint16_t *) (pBody)) = sir_swap_u16if_needed(len - 3); /*one byte for Attr and 2 bytes for length */
+
+		return len;
+
+	}
+	return 0;
+
+}
+
+void pe_set_resume_channel(tpAniSirGlobal pMac, uint16_t channel,
+			   ePhyChanBondState phyCbState)
+{
+
+	pMac->lim.gResumeChannel = channel;
+	pMac->lim.gResumePhyCbState = phyCbState;
+}
+
+bool lim_is_noa_insert_reqd(tpAniSirGlobal pMac)
+{
+	uint8_t i;
+
+	for (i = 0; i < pMac->lim.maxBssId; i++) {
+		if (pMac->lim.gpSession[i].valid == true) {
+			if ((eLIM_AP_ROLE ==
+			     pMac->lim.gpSession[i].limSystemRole)
+			    && (QDF_P2P_GO_MODE ==
+				pMac->lim.gpSession[i].pePersona)
+			    ) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+bool lim_isconnected_on_dfs_channel(tpAniSirGlobal mac_ctx,
+		uint8_t currentChannel)
+{
+	if (CHANNEL_STATE_DFS ==
+	    wlan_reg_get_channel_state(mac_ctx->pdev, currentChannel)) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+#ifdef WLAN_FEATURE_11W
+void lim_pmf_sa_query_timer_handler(void *pMacGlobal, uint32_t param)
+{
+	tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+	tPmfSaQueryTimerId timerId;
+	tpPESession psessionEntry;
+	tpDphHashNode pSta;
+	uint8_t maxretries;
+
+	pe_debug("SA Query timer fires");
+	timerId.value = param;
+
+	/* Check that SA Query is in progress */
+	psessionEntry = pe_find_session_by_session_id(pMac,
+			timerId.fields.sessionId);
+	if (psessionEntry == NULL) {
+		pe_err("Session does not exist for given session ID: %d",
+			timerId.fields.sessionId);
+		return;
+	}
+	pSta = dph_get_hash_entry(pMac, timerId.fields.peerIdx,
+			       &psessionEntry->dph.dphHashTable);
+	if (pSta == NULL) {
+		pe_err("Entry does not exist for given peer index: %d",
+			timerId.fields.peerIdx);
+		return;
+	}
+	if (DPH_SA_QUERY_IN_PROGRESS != pSta->pmfSaQueryState)
+		return;
+
+	/* Increment the retry count, check if reached maximum */
+	maxretries = pMac->mlme_cfg->gen.pmf_sa_query_max_retries;
+	pSta->pmfSaQueryRetryCount++;
+	if (pSta->pmfSaQueryRetryCount >= maxretries) {
+		pe_err("SA Query timed out,Deleting STA");
+		lim_print_mac_addr(pMac, pSta->staAddr, LOGE);
+		lim_send_disassoc_mgmt_frame(pMac,
+			eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON,
+			pSta->staAddr, psessionEntry, false);
+		lim_trigger_sta_deletion(pMac, pSta, psessionEntry);
+		pSta->pmfSaQueryState = DPH_SA_QUERY_TIMED_OUT;
+		return;
+	}
+	/* Retry SA Query */
+	lim_send_sa_query_request_frame(pMac,
+					(uint8_t *) &(pSta->
+						      pmfSaQueryCurrentTransId),
+					pSta->staAddr, psessionEntry);
+	pSta->pmfSaQueryCurrentTransId++;
+	pe_debug("Starting SA Query retry: %d", pSta->pmfSaQueryRetryCount);
+	if (tx_timer_activate(&pSta->pmfSaQueryTimer) != TX_SUCCESS) {
+		pe_err("PMF SA Query timer activation failed!");
+		pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
+	}
+}
+#endif
+
+bool lim_check_vht_op_mode_change(tpAniSirGlobal pMac, tpPESession psessionEntry,
+				  uint8_t chanWidth, uint8_t staId,
+				  uint8_t *peerMac)
+{
+	tUpdateVHTOpMode tempParam;
+
+	tempParam.opMode = chanWidth;
+	tempParam.staId = staId;
+	tempParam.smesessionId = psessionEntry->smeSessionId;
+	qdf_mem_copy(tempParam.peer_mac, peerMac, sizeof(tSirMacAddr));
+
+	lim_send_mode_update(pMac, &tempParam, psessionEntry);
+
+	return true;
+}
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+bool lim_send_he_ie_update(tpAniSirGlobal mac_ctx, tpPESession pe_session)
+{
+	QDF_STATUS status;
+
+	status = wma_update_he_ops_ie(cds_get_context(QDF_MODULE_ID_WMA),
+				      pe_session->smeSessionId,
+				      &pe_session->he_op);
+	if (QDF_IS_STATUS_ERROR(status))
+		return false;
+
+	return true;
+}
+#endif
+
+bool lim_set_nss_change(tpAniSirGlobal pMac, tpPESession psessionEntry,
+			uint8_t rxNss, uint8_t staId, uint8_t *peerMac)
+{
+	tUpdateRxNss tempParam;
+
+	if (!rxNss) {
+		pe_err("Invalid rxNss value: %u", rxNss);
+		cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
+	}
+
+	tempParam.rxNss = rxNss;
+	tempParam.staId = staId;
+	tempParam.smesessionId = psessionEntry->smeSessionId;
+	qdf_mem_copy(tempParam.peer_mac, peerMac, sizeof(tSirMacAddr));
+
+	lim_send_rx_nss_update(pMac, &tempParam, psessionEntry);
+
+	return true;
+}
+
+bool lim_check_membership_user_position(tpAniSirGlobal pMac,
+					tpPESession psessionEntry,
+					uint32_t membership, uint32_t userPosition,
+					uint8_t staId)
+{
+	tUpdateMembership tempParamMembership;
+	tUpdateUserPos tempParamUserPosition;
+
+	tempParamMembership.membership = membership;
+	tempParamMembership.staId = staId;
+	tempParamMembership.smesessionId = psessionEntry->smeSessionId;
+	qdf_mem_copy(tempParamMembership.peer_mac, psessionEntry->bssId,
+		     sizeof(tSirMacAddr));
+
+	lim_set_membership(pMac, &tempParamMembership, psessionEntry);
+
+	tempParamUserPosition.userPos = userPosition;
+	tempParamUserPosition.staId = staId;
+	tempParamUserPosition.smesessionId = psessionEntry->smeSessionId;
+	qdf_mem_copy(tempParamUserPosition.peer_mac, psessionEntry->bssId,
+		     sizeof(tSirMacAddr));
+
+	lim_set_user_pos(pMac, &tempParamUserPosition, psessionEntry);
+
+	return true;
+}
+
+void lim_get_short_slot_from_phy_mode(tpAniSirGlobal pMac, tpPESession psessionEntry,
+				      uint32_t phyMode, uint8_t *pShortSlotEnabled)
+{
+	uint8_t val = 0;
+
+	/* only 2.4G band should have short slot enable, rest it should be default */
+	if (phyMode == WNI_CFG_PHY_MODE_11G) {
+		/* short slot is default in all other modes */
+		if ((psessionEntry->pePersona == QDF_SAP_MODE) ||
+		    (psessionEntry->pePersona == QDF_IBSS_MODE) ||
+		    (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
+			val = true;
+		}
+		/* Program Polaris based on AP capability */
+		if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) {
+			/* Joining BSS. */
+			val =
+				SIR_MAC_GET_SHORT_SLOT_TIME(psessionEntry->
+							    limCurrentBssCaps);
+		} else if (psessionEntry->limMlmState ==
+			   eLIM_MLM_WT_REASSOC_RSP_STATE) {
+			/* Reassociating with AP. */
+			val =
+				SIR_MAC_GET_SHORT_SLOT_TIME(psessionEntry->
+							    limReassocBssCaps);
+		}
+	} else {
+		/*
+		 * 11B does not short slot and short slot is default
+		 * for 11A mode. Hence, not need to set this bit
+		 */
+		val = false;
+	}
+
+	pe_debug("phyMode: %u shortslotsupported: %u", phyMode, val);
+	*pShortSlotEnabled = val;
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ *
+ * \brief This function is called by various LIM modules to correctly set
+ * the Protected bit in the Frame Control Field of the 802.11 frame MAC header
+ *
+ *
+ * \param  pMac Pointer to Global MAC structure
+ *
+ * \param psessionEntry Pointer to session corresponding to the connection
+ *
+ * \param peer Peer address of the STA to which the frame is to be sent
+ *
+ * \param pMacHdr Pointer to the frame MAC header
+ *
+ * \return nothing
+ *
+ *
+ */
+void
+lim_set_protected_bit(tpAniSirGlobal pMac,
+		      tpPESession psessionEntry,
+		      tSirMacAddr peer, tpSirMacMgmtHdr pMacHdr)
+{
+	uint16_t aid;
+	tpDphHashNode pStaDs;
+
+	if (LIM_IS_AP_ROLE(psessionEntry)) {
+
+		pStaDs = dph_lookup_hash_entry(pMac, peer, &aid,
+					       &psessionEntry->dph.dphHashTable);
+		if (pStaDs != NULL) {
+			/* rmfenabled will be set at the time of addbss.
+			 * but sometimes EAP auth fails and keys are not
+			 * installed then if we send any management frame
+			 * like deauth/disassoc with this bit set then
+			 * firmware crashes. so check for keys are
+			 * installed or not also before setting the bit
+			 */
+			if (pStaDs->rmfEnabled && pStaDs->is_key_installed)
+				pMacHdr->fc.wep = 1;
+		}
+	} else if (psessionEntry->limRmfEnabled &&
+			psessionEntry->is_key_installed) {
+		pMacHdr->fc.wep = 1;
+	}
+} /*** end lim_set_protected_bit() ***/
+#endif
+
+void lim_set_ht_caps(tpAniSirGlobal p_mac, tpPESession p_session_entry,
+		uint8_t *p_ie_start, uint32_t num_bytes)
+{
+	const uint8_t *p_ie = NULL;
+	tDot11fIEHTCaps dot11_ht_cap = {0,};
+
+	populate_dot11f_ht_caps(p_mac, p_session_entry, &dot11_ht_cap);
+	p_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_HTCAPS,
+					p_ie_start, num_bytes);
+	pe_debug("p_ie: %pK dot11_ht_cap.supportedMCSSet[0]: 0x%x",
+		p_ie, dot11_ht_cap.supportedMCSSet[0]);
+	if (p_ie) {
+		/* convert from unpacked to packed structure */
+		tHtCaps *p_ht_cap = (tHtCaps *) &p_ie[2];
+
+		p_ht_cap->advCodingCap = dot11_ht_cap.advCodingCap;
+		p_ht_cap->supportedChannelWidthSet =
+			dot11_ht_cap.supportedChannelWidthSet;
+		p_ht_cap->mimoPowerSave = dot11_ht_cap.mimoPowerSave;
+		p_ht_cap->greenField = dot11_ht_cap.greenField;
+		p_ht_cap->shortGI20MHz = dot11_ht_cap.shortGI20MHz;
+		p_ht_cap->shortGI40MHz = dot11_ht_cap.shortGI40MHz;
+		p_ht_cap->txSTBC = dot11_ht_cap.txSTBC;
+		p_ht_cap->rxSTBC = dot11_ht_cap.rxSTBC;
+		p_ht_cap->delayedBA = dot11_ht_cap.delayedBA;
+		p_ht_cap->maximalAMSDUsize = dot11_ht_cap.maximalAMSDUsize;
+		p_ht_cap->dsssCckMode40MHz = dot11_ht_cap.dsssCckMode40MHz;
+		p_ht_cap->psmp = dot11_ht_cap.psmp;
+		p_ht_cap->stbcControlFrame = dot11_ht_cap.stbcControlFrame;
+		p_ht_cap->lsigTXOPProtection = dot11_ht_cap.lsigTXOPProtection;
+		p_ht_cap->maxRxAMPDUFactor = dot11_ht_cap.maxRxAMPDUFactor;
+		p_ht_cap->mpduDensity = dot11_ht_cap.mpduDensity;
+		qdf_mem_copy((void *)p_ht_cap->supportedMCSSet,
+			(void *)(dot11_ht_cap.supportedMCSSet),
+			sizeof(p_ht_cap->supportedMCSSet));
+		p_ht_cap->pco = dot11_ht_cap.pco;
+		p_ht_cap->transitionTime = dot11_ht_cap.transitionTime;
+		p_ht_cap->mcsFeedback = dot11_ht_cap.mcsFeedback;
+		p_ht_cap->txBF = dot11_ht_cap.txBF;
+		p_ht_cap->rxStaggeredSounding =
+			dot11_ht_cap.rxStaggeredSounding;
+		p_ht_cap->txStaggeredSounding =
+			dot11_ht_cap.txStaggeredSounding;
+		p_ht_cap->rxZLF = dot11_ht_cap.rxZLF;
+		p_ht_cap->txZLF = dot11_ht_cap.txZLF;
+		p_ht_cap->implicitTxBF = dot11_ht_cap.implicitTxBF;
+		p_ht_cap->calibration = dot11_ht_cap.calibration;
+		p_ht_cap->explicitCSITxBF = dot11_ht_cap.explicitCSITxBF;
+		p_ht_cap->explicitUncompressedSteeringMatrix =
+			dot11_ht_cap.explicitUncompressedSteeringMatrix;
+		p_ht_cap->explicitBFCSIFeedback =
+			dot11_ht_cap.explicitBFCSIFeedback;
+		p_ht_cap->explicitUncompressedSteeringMatrixFeedback =
+			dot11_ht_cap.explicitUncompressedSteeringMatrixFeedback;
+		p_ht_cap->explicitCompressedSteeringMatrixFeedback =
+			dot11_ht_cap.explicitCompressedSteeringMatrixFeedback;
+		p_ht_cap->csiNumBFAntennae = dot11_ht_cap.csiNumBFAntennae;
+		p_ht_cap->uncompressedSteeringMatrixBFAntennae =
+			dot11_ht_cap.uncompressedSteeringMatrixBFAntennae;
+		p_ht_cap->compressedSteeringMatrixBFAntennae =
+			dot11_ht_cap.compressedSteeringMatrixBFAntennae;
+		p_ht_cap->antennaSelection = dot11_ht_cap.antennaSelection;
+		p_ht_cap->explicitCSIFeedbackTx =
+			dot11_ht_cap.explicitCSIFeedbackTx;
+		p_ht_cap->antennaIndicesFeedbackTx =
+			dot11_ht_cap.antennaIndicesFeedbackTx;
+		p_ht_cap->explicitCSIFeedback =
+			dot11_ht_cap.explicitCSIFeedback;
+		p_ht_cap->antennaIndicesFeedback =
+			dot11_ht_cap.antennaIndicesFeedback;
+		p_ht_cap->rxAS = dot11_ht_cap.rxAS;
+		p_ht_cap->txSoundingPPDUs = dot11_ht_cap.txSoundingPPDUs;
+	}
+}
+
+void lim_set_vht_caps(tpAniSirGlobal p_mac, tpPESession p_session_entry,
+		      uint8_t *p_ie_start, uint32_t num_bytes)
+{
+	const uint8_t       *p_ie = NULL;
+	tDot11fIEVHTCaps     dot11_vht_cap;
+
+	populate_dot11f_vht_caps(p_mac, p_session_entry, &dot11_vht_cap);
+	p_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_VHTCAPS, p_ie_start,
+					num_bytes);
+	if (p_ie) {
+		tSirMacVHTCapabilityInfo *vht_cap =
+					(tSirMacVHTCapabilityInfo *) &p_ie[2];
+		tSirVhtMcsInfo *vht_mcs = (tSirVhtMcsInfo *) &p_ie[2 +
+					  sizeof(tSirMacVHTCapabilityInfo)];
+
+		union {
+			uint16_t                       u_value;
+			tSirMacVHTRxSupDataRateInfo    vht_rx_supp_rate;
+			tSirMacVHTTxSupDataRateInfo    vht_tx_supp_rate;
+		} u_vht_data_rate_info;
+
+		vht_cap->maxMPDULen = dot11_vht_cap.maxMPDULen;
+		vht_cap->supportedChannelWidthSet =
+					dot11_vht_cap.supportedChannelWidthSet;
+		vht_cap->ldpcCodingCap = dot11_vht_cap.ldpcCodingCap;
+		vht_cap->shortGI80MHz = dot11_vht_cap.shortGI80MHz;
+		vht_cap->shortGI160and80plus80MHz =
+					dot11_vht_cap.shortGI160and80plus80MHz;
+		vht_cap->txSTBC = dot11_vht_cap.txSTBC;
+		vht_cap->rxSTBC = dot11_vht_cap.rxSTBC;
+		vht_cap->suBeamFormerCap = dot11_vht_cap.suBeamFormerCap;
+		vht_cap->suBeamformeeCap = dot11_vht_cap.suBeamformeeCap;
+		vht_cap->csnofBeamformerAntSup =
+					dot11_vht_cap.csnofBeamformerAntSup;
+		vht_cap->numSoundingDim = dot11_vht_cap.numSoundingDim;
+		vht_cap->muBeamformerCap = dot11_vht_cap.muBeamformerCap;
+		vht_cap->muBeamformeeCap = dot11_vht_cap.muBeamformeeCap;
+		vht_cap->vhtTXOPPS = dot11_vht_cap.vhtTXOPPS;
+		vht_cap->htcVHTCap = dot11_vht_cap.htcVHTCap;
+		vht_cap->maxAMPDULenExp = dot11_vht_cap.maxAMPDULenExp;
+		vht_cap->vhtLinkAdaptCap = dot11_vht_cap.vhtLinkAdaptCap;
+		vht_cap->rxAntPattern = dot11_vht_cap.rxAntPattern;
+		vht_cap->txAntPattern = dot11_vht_cap.txAntPattern;
+		vht_cap->reserved1 = dot11_vht_cap.reserved1;
+
+		/* Populate VHT MCS Information */
+		vht_mcs->rxMcsMap = dot11_vht_cap.rxMCSMap;
+		u_vht_data_rate_info.vht_rx_supp_rate.rxSupDataRate =
+					dot11_vht_cap.rxHighSupDataRate;
+		u_vht_data_rate_info.vht_rx_supp_rate.reserved =
+					dot11_vht_cap.reserved2;
+		vht_mcs->rxHighest = u_vht_data_rate_info.u_value;
+
+		vht_mcs->txMcsMap = dot11_vht_cap.txMCSMap;
+		u_vht_data_rate_info.vht_tx_supp_rate.txSupDataRate =
+					dot11_vht_cap.txSupDataRate;
+		u_vht_data_rate_info.vht_tx_supp_rate.reserved =
+					dot11_vht_cap.reserved3;
+		vht_mcs->txHighest = u_vht_data_rate_info.u_value;
+	}
+}
+
+/**
+ * lim_validate_received_frame_a1_addr() - To validate received frame's A1 addr
+ * @mac_ctx: pointer to mac context
+ * @a1: received frame's a1 address which is nothing but our self address
+ * @session: PE session pointer
+ *
+ * This routine will validate, A1 address of the received frame
+ *
+ * Return: true or false
+ */
+bool lim_validate_received_frame_a1_addr(tpAniSirGlobal mac_ctx,
+		tSirMacAddr a1, tpPESession session)
+{
+	if (mac_ctx == NULL || session == NULL) {
+		pe_err("mac or session context is null");
+		/* let main routine handle it */
+		return true;
+	}
+	if (lim_is_group_addr(a1) || lim_is_addr_bc(a1)) {
+		/* just for fail safe, don't handle MC/BC a1 in this routine */
+		return true;
+	}
+	if (qdf_mem_cmp(a1, session->selfMacAddr, 6)) {
+		pe_err("Invalid A1 address in received frame");
+		return false;
+	}
+	return true;
+}
+
+/**
+ * lim_check_and_reset_protection_params() - reset protection related parameters
+ *
+ * @mac_ctx: pointer to global mac structure
+ *
+ * resets protection related global parameters if the pe active session count
+ * is zero.
+ *
+ * Return: None
+ */
+void lim_check_and_reset_protection_params(tpAniSirGlobal mac_ctx)
+{
+	if (!pe_get_active_session_count(mac_ctx)) {
+		mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+	}
+}
+
+/**
+ * lim_set_stads_rtt_cap() - update station node RTT capability
+ * @sta_ds: Station hash node
+ * @ext_cap: Pointer to extended capability
+ * @mac_ctx: global MAC context
+ *
+ * This funciton update hash node's RTT capability based on received
+ * Extended capability IE.
+ *
+ * Return: None
+ */
+void lim_set_stads_rtt_cap(tpDphHashNode sta_ds, struct s_ext_cap *ext_cap,
+			   tpAniSirGlobal mac_ctx)
+{
+	sta_ds->timingMeasCap = 0;
+	sta_ds->timingMeasCap |= (ext_cap->timing_meas) ?
+				  RTT_TIMING_MEAS_CAPABILITY :
+				  RTT_INVALID;
+	sta_ds->timingMeasCap |= (ext_cap->fine_time_meas_initiator) ?
+				  RTT_FINE_TIME_MEAS_INITIATOR_CAPABILITY :
+				  RTT_INVALID;
+	sta_ds->timingMeasCap |= (ext_cap->fine_time_meas_responder) ?
+				  RTT_FINE_TIME_MEAS_RESPONDER_CAPABILITY :
+				  RTT_INVALID;
+
+	pe_debug("ExtCap present, timingMeas: %d Initiator: %d Responder: %d",
+	    ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
+	    ext_cap->fine_time_meas_responder);
+}
+
+#ifdef WLAN_SUPPORT_TWT
+void lim_set_peer_twt_cap(tpPESession session, struct s_ext_cap *ext_cap)
+{
+	if (session->enable_session_twt_support) {
+		session->peer_twt_requestor = ext_cap->twt_requestor_support;
+		session->peer_twt_responder = ext_cap->twt_responder_support;
+	}
+
+	pe_debug("Ext Cap peer TWT requestor: %d, responder: %d, enable_twt %d",
+		 ext_cap->twt_requestor_support,
+		 ext_cap->twt_responder_support,
+		 session->enable_session_twt_support);
+}
+#endif
+
+/**
+ * lim_send_ie() - sends IE to wma
+ * @mac_ctx: global MAC context
+ * @sme_session_id: sme session id
+ * @eid: IE id
+ * @band: band for which IE is intended
+ * @buf: buffer containing IE
+ * @len: length of buffer
+ *
+ * This funciton sends the IE data to WMA.
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS lim_send_ie(tpAniSirGlobal mac_ctx, uint32_t sme_session_id,
+			      uint8_t eid, enum cds_band_type band,
+			      uint8_t *buf, uint32_t len)
+{
+	struct vdev_ie_info *ie_msg;
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+
+	/* Allocate memory for the WMI request */
+	ie_msg = qdf_mem_malloc(sizeof(*ie_msg) + len);
+	if (!ie_msg)
+		return QDF_STATUS_E_NOMEM;
+
+	ie_msg->vdev_id = sme_session_id;
+	ie_msg->ie_id = eid;
+	ie_msg->length = len;
+	ie_msg->band = band;
+	/* IE data buffer starts at end of the struct */
+	ie_msg->data = (uint8_t *)&ie_msg[1];
+
+	qdf_mem_copy(ie_msg->data, buf, len);
+	msg.type = WMA_SET_IE_INFO;
+	msg.bodyptr = ie_msg;
+	msg.reserved = 0;
+
+	status = scheduler_post_message(QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("Not able to post WMA_SET_IE_INFO to WMA");
+		qdf_mem_free(ie_msg);
+		return status;
+	}
+
+	return status;
+}
+
+/**
+ * lim_get_rx_ldpc() - gets ldpc setting for given channel(band)
+ * @mac_ctx: global mac context
+ * @ch: channel enum for which ldpc setting is required
+ *      Note: ch param is not absolute channel number rather it is
+ *            channel number enum.
+ *
+ * Return: true if enabled and false otherwise
+ */
+static inline bool lim_get_rx_ldpc(tpAniSirGlobal mac_ctx, enum channel_enum ch)
+{
+	if (mac_ctx->roam.configParam.rx_ldpc_enable &&
+		wma_is_rx_ldpc_supported_for_channel(WLAN_REG_CH_NUM(ch)))
+		return true;
+	else
+		return false;
+}
+
+/**
+ * lim_send_ies_per_band() - gets ht and vht capability and send to firmware via
+ * wma
+ * @mac_ctx: global mac context
+ * @session: pe session. This can be NULL. In that case self cap will be sent
+ * @vdev_id: vdev for which IE is targeted
+ *
+ * This funciton gets ht and vht capability and send to firmware via wma
+ *
+ * Return: status of operation
+ */
+QDF_STATUS lim_send_ies_per_band(tpAniSirGlobal mac_ctx,
+				 tpPESession session,
+				 uint8_t vdev_id)
+{
+	uint8_t ht_caps[DOT11F_IE_HTCAPS_MIN_LEN + 2] = {0};
+	uint8_t vht_caps[DOT11F_IE_VHTCAPS_MAX_LEN + 2] = {0};
+	tHtCaps *p_ht_cap = (tHtCaps *)(&ht_caps[2]);
+	tSirMacVHTCapabilityInfo *p_vht_cap =
+			(tSirMacVHTCapabilityInfo *)(&vht_caps[2]);
+	QDF_STATUS status;
+
+	/*
+	 * Note: Do not use Dot11f VHT structure, since 1 byte present flag in
+	 * it is causing weird padding errors. Instead use Sir Mac VHT struct
+	 * to send IE to wma.
+	 */
+	ht_caps[0] = DOT11F_EID_HTCAPS;
+	ht_caps[1] = DOT11F_IE_HTCAPS_MIN_LEN;
+	lim_set_ht_caps(mac_ctx, session, ht_caps,
+			DOT11F_IE_HTCAPS_MIN_LEN + 2);
+	/* Get LDPC and over write for 2G */
+	p_ht_cap->advCodingCap = lim_get_rx_ldpc(mac_ctx, CHAN_ENUM_6);
+	/* Get self cap for HT40 support in 2G */
+	if (mac_ctx->roam.configParam.channelBondingMode24GHz) {
+		p_ht_cap->supportedChannelWidthSet = 1;
+		p_ht_cap->shortGI40MHz = 1;
+	} else {
+		p_ht_cap->supportedChannelWidthSet = 0;
+		p_ht_cap->shortGI40MHz = 0;
+	}
+	lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_HTCAPS,
+		CDS_BAND_2GHZ, &ht_caps[2], DOT11F_IE_HTCAPS_MIN_LEN);
+	/*
+	 * Get LDPC and over write for 5G - using channel 64 because it
+	 * is available in all reg domains.
+	 */
+	p_ht_cap->advCodingCap = lim_get_rx_ldpc(mac_ctx, CHAN_ENUM_64);
+	/* Get self cap for HT40 support in 5G */
+	if (mac_ctx->roam.configParam.channelBondingMode5GHz) {
+		p_ht_cap->supportedChannelWidthSet = 1;
+		p_ht_cap->shortGI40MHz = 1;
+	} else {
+		p_ht_cap->supportedChannelWidthSet = 0;
+		p_ht_cap->shortGI40MHz = 0;
+	}
+	lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_HTCAPS,
+		CDS_BAND_5GHZ, &ht_caps[2], DOT11F_IE_HTCAPS_MIN_LEN);
+
+	vht_caps[0] = DOT11F_EID_VHTCAPS;
+	vht_caps[1] = DOT11F_IE_VHTCAPS_MAX_LEN;
+	lim_set_vht_caps(mac_ctx, session, vht_caps,
+			 DOT11F_IE_VHTCAPS_MIN_LEN + 2);
+	/*
+	 * Get LDPC and over write for 5G - using channel 64 because it
+	 * is available in all reg domains.
+	 */
+	p_vht_cap->ldpcCodingCap = lim_get_rx_ldpc(mac_ctx, CHAN_ENUM_64);
+	/* Self VHT channel width for 5G is already negotiated with FW */
+	lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_VHTCAPS,
+			CDS_BAND_5GHZ, &vht_caps[2], DOT11F_IE_VHTCAPS_MIN_LEN);
+
+	/* Get LDPC and over write for 2G */
+	p_vht_cap->ldpcCodingCap = lim_get_rx_ldpc(mac_ctx, CHAN_ENUM_6);
+	/* Self VHT 80/160/80+80 channel width for 2G is 0 */
+	p_vht_cap->supportedChannelWidthSet = 0;
+	p_vht_cap->shortGI80MHz = 0;
+	p_vht_cap->shortGI160and80plus80MHz = 0;
+	lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_VHTCAPS,
+			CDS_BAND_2GHZ, &vht_caps[2], DOT11F_IE_VHTCAPS_MIN_LEN);
+
+	status = lim_send_he_caps_ie(mac_ctx, session, vdev_id);
+
+	return status;
+}
+
+/**
+ * lim_send_ext_cap_ie() - send ext cap IE to FW
+ * @mac_ctx: global MAC context
+ * @session_entry: PE session
+ * @extra_extcap: extracted ext cap
+ * @merge: merge extra ext cap
+ *
+ * This function is invoked after VDEV is created to update firmware
+ * about the extended capabilities that the corresponding VDEV is capable
+ * of. Since STA/SAP can have different Extended capabilities set, this function
+ * is called per vdev creation.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_send_ext_cap_ie(tpAniSirGlobal mac_ctx,
+			       uint32_t session_id,
+			       tDot11fIEExtCap *extra_extcap, bool merge)
+{
+	tDot11fIEExtCap ext_cap_data = {0};
+	uint32_t dot11mode, num_bytes;
+	bool vht_enabled = false;
+	struct vdev_ie_info *vdev_ie;
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &dot11mode);
+	if (IS_DOT11_MODE_VHT(dot11mode))
+		vht_enabled = true;
+
+	status = populate_dot11f_ext_cap(mac_ctx, vht_enabled, &ext_cap_data,
+					 NULL);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_err("Failed to populate ext cap IE");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	num_bytes = ext_cap_data.num_bytes;
+
+	if (merge && NULL != extra_extcap && extra_extcap->num_bytes > 0) {
+		if (extra_extcap->num_bytes > ext_cap_data.num_bytes)
+			num_bytes = extra_extcap->num_bytes;
+		lim_merge_extcap_struct(&ext_cap_data, extra_extcap, true);
+	}
+
+	/* Allocate memory for the WMI request, and copy the parameter */
+	vdev_ie = qdf_mem_malloc(sizeof(*vdev_ie) + num_bytes);
+	if (!vdev_ie)
+		return QDF_STATUS_E_NOMEM;
+
+	vdev_ie->vdev_id = session_id;
+	vdev_ie->ie_id = DOT11F_EID_EXTCAP;
+	vdev_ie->length = num_bytes;
+	vdev_ie->band = 0;
+
+	vdev_ie->data = (uint8_t *)vdev_ie + sizeof(*vdev_ie);
+	qdf_mem_copy(vdev_ie->data, ext_cap_data.bytes, num_bytes);
+
+	msg.type = WMA_SET_IE_INFO;
+	msg.bodyptr = vdev_ie;
+	msg.reserved = 0;
+
+	if (QDF_STATUS_SUCCESS !=
+		scheduler_post_message(QDF_MODULE_ID_PE,
+				       QDF_MODULE_ID_WMA,
+				       QDF_MODULE_ID_WMA, &msg)) {
+		pe_err("Not able to post WMA_SET_IE_INFO to WDA");
+		qdf_mem_free(vdev_ie);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_strip_ie() - strip requested IE from IE buffer
+ * @mac_ctx: global MAC context
+ * @addn_ie: Additional IE buffer
+ * @addn_ielen: Length of additional IE
+ * @eid: EID of IE to strip
+ * @size_of_len_field: length of IE length field
+ * @oui: if present matches OUI also
+ * @oui_length: if previous present, this is length of oui
+ * @extracted_ie: if not NULL, copy the stripped IE to this buffer
+ *
+ * This utility function is used to strip of the requested IE if present
+ * in IE buffer.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_strip_ie(tpAniSirGlobal mac_ctx,
+		uint8_t *addn_ie, uint16_t *addn_ielen,
+		uint8_t eid, eSizeOfLenField size_of_len_field,
+		uint8_t *oui, uint8_t oui_length, uint8_t *extracted_ie,
+		uint32_t eid_max_len)
+{
+	uint8_t *tempbuf = NULL;
+	uint16_t templen = 0;
+	int left = *addn_ielen;
+	uint8_t *ptr = addn_ie;
+	uint8_t elem_id;
+	uint16_t elem_len;
+
+	if (NULL == addn_ie) {
+		pe_debug("NULL addn_ie pointer");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tempbuf = qdf_mem_malloc(left);
+	if (!tempbuf)
+		return QDF_STATUS_E_NOMEM;
+
+	while (left >= 2) {
+		elem_id  = ptr[0];
+		left -= 1;
+		if (size_of_len_field == TWO_BYTE) {
+			elem_len = *((uint16_t *)&ptr[1]);
+			left -= 2;
+		} else {
+			elem_len = ptr[1];
+			left -= 1;
+		}
+		if (elem_len > left) {
+			pe_err("Invalid IEs eid: %d elem_len: %d left: %d",
+				elem_id, elem_len, left);
+			qdf_mem_free(tempbuf);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (eid != elem_id ||
+				(oui && qdf_mem_cmp(oui,
+						&ptr[size_of_len_field + 1],
+						oui_length))) {
+			qdf_mem_copy(tempbuf + templen, &ptr[0],
+				     elem_len + size_of_len_field + 1);
+			templen += (elem_len + size_of_len_field + 1);
+		} else {
+			/*
+			 * eid matched and if provided OUI also matched
+			 * take oui IE and store in provided buffer.
+			 */
+			if (NULL != extracted_ie) {
+				qdf_mem_set(extracted_ie,
+					    eid_max_len + size_of_len_field + 1,
+					    0);
+				if (elem_len <= eid_max_len)
+					qdf_mem_copy(extracted_ie, &ptr[0],
+					elem_len + size_of_len_field + 1);
+			}
+		}
+		left -= elem_len;
+		ptr += (elem_len + size_of_len_field + 1);
+	}
+	qdf_mem_copy(addn_ie, tempbuf, templen);
+
+	*addn_ielen = templen;
+	qdf_mem_free(tempbuf);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_11W
+void lim_del_pmf_sa_query_timer(tpAniSirGlobal mac_ctx, tpPESession pe_session)
+{
+	uint32_t associated_sta;
+	tpDphHashNode sta_ds = NULL;
+
+	for (associated_sta = 1;
+			associated_sta <
+			mac_ctx->mlme_cfg->sap_cfg.assoc_sta_limit;
+			associated_sta++) {
+		sta_ds = dph_get_hash_entry(mac_ctx, associated_sta,
+				&pe_session->dph.dphHashTable);
+		if (NULL == sta_ds)
+			continue;
+		if (!sta_ds->rmfEnabled) {
+			pe_debug("no PMF timer for sta-idx:%d assoc-id:%d",
+				 sta_ds->staIndex, sta_ds->assocId);
+			continue;
+		}
+
+		pe_debug("Deleting pmfSaQueryTimer for sta-idx:%d assoc-id:%d",
+			sta_ds->staIndex, sta_ds->assocId);
+		tx_timer_deactivate(&sta_ds->pmfSaQueryTimer);
+		tx_timer_delete(&sta_ds->pmfSaQueryTimer);
+	}
+}
+#endif
+
+QDF_STATUS lim_strip_supp_op_class_update_struct(tpAniSirGlobal mac_ctx,
+		uint8_t *addn_ie, uint16_t *addn_ielen,
+		tDot11fIESuppOperatingClasses *dst)
+{
+	uint8_t extracted_buff[DOT11F_IE_SUPPOPERATINGCLASSES_MAX_LEN + 2];
+	QDF_STATUS status;
+
+	qdf_mem_set((uint8_t *)&extracted_buff[0],
+		    DOT11F_IE_SUPPOPERATINGCLASSES_MAX_LEN + 2,
+		    0);
+	status = lim_strip_ie(mac_ctx, addn_ie, addn_ielen,
+			      DOT11F_EID_SUPPOPERATINGCLASSES, ONE_BYTE,
+			      NULL, 0, extracted_buff,
+			      DOT11F_IE_SUPPOPERATINGCLASSES_MAX_LEN);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_warn("Failed to strip supp_op_mode IE status: %d",
+		       status);
+		return status;
+	}
+
+	if (DOT11F_EID_SUPPOPERATINGCLASSES != extracted_buff[0] ||
+	    extracted_buff[1] > DOT11F_IE_SUPPOPERATINGCLASSES_MAX_LEN) {
+		pe_warn("Invalid IEs eid: %d elem_len: %d",
+			extracted_buff[0], extracted_buff[1]);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* update the extracted supp op class to struct*/
+	if (DOT11F_PARSE_SUCCESS != dot11f_unpack_ie_supp_operating_classes(
+	    mac_ctx, &extracted_buff[2], extracted_buff[1], dst, false)) {
+		pe_err("dot11f_unpack Parse Error");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_update_extcap_struct() - poputlate the dot11f structure
+ * @mac_ctx: global MAC context
+ * @buf: extracted IE buffer
+ * @dst: extended capability IE structure to be updated
+ *
+ * This function is used to update the extended capability structure
+ * with @buf.
+ *
+ * Return: None
+ */
+void lim_update_extcap_struct(tpAniSirGlobal mac_ctx,
+	uint8_t *buf, tDot11fIEExtCap *dst)
+{
+	uint8_t out[DOT11F_IE_EXTCAP_MAX_LEN];
+	uint32_t status;
+
+	if (NULL == buf) {
+		pe_err("Invalid Buffer Address");
+		return;
+	}
+
+	if (NULL == dst) {
+		pe_err("NULL dst pointer");
+		return;
+	}
+
+	if (DOT11F_EID_EXTCAP != buf[0] || buf[1] > DOT11F_IE_EXTCAP_MAX_LEN) {
+		pe_debug_rl("Invalid IEs eid: %d elem_len: %d", buf[0], buf[1]);
+		return;
+	}
+
+	qdf_mem_set((uint8_t *)&out[0], DOT11F_IE_EXTCAP_MAX_LEN, 0);
+	qdf_mem_copy(&out[0], &buf[2], buf[1]);
+
+	status = dot11f_unpack_ie_ext_cap(mac_ctx, &out[0],
+					buf[1], dst, false);
+	if (DOT11F_PARSE_SUCCESS != status)
+		pe_err("dot11f_unpack Parse Error %d", status);
+}
+
+/**
+ * lim_strip_extcap_update_struct - strip extended capability IE and populate
+ *				  the dot11f structure
+ * @mac_ctx: global MAC context
+ * @addn_ie: Additional IE buffer
+ * @addn_ielen: Length of additional IE
+ * @dst: extended capability IE structure to be updated
+ *
+ * This function is used to strip extended capability IE from IE buffer and
+ * update the passed structure.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_strip_extcap_update_struct(tpAniSirGlobal mac_ctx,
+		uint8_t *addn_ie, uint16_t *addn_ielen, tDot11fIEExtCap *dst)
+{
+	uint8_t extracted_buff[DOT11F_IE_EXTCAP_MAX_LEN + 2];
+	QDF_STATUS status;
+
+	qdf_mem_set((uint8_t *)&extracted_buff[0], DOT11F_IE_EXTCAP_MAX_LEN + 2,
+		     0);
+	status = lim_strip_ie(mac_ctx, addn_ie, addn_ielen,
+			      DOT11F_EID_EXTCAP, ONE_BYTE,
+			      NULL, 0, extracted_buff,
+			      DOT11F_IE_EXTCAP_MAX_LEN);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_debug("Failed to strip extcap IE status: %d", status);
+		return status;
+	}
+
+	/* update the extracted ExtCap to struct*/
+	lim_update_extcap_struct(mac_ctx, extracted_buff, dst);
+	return status;
+}
+
+/**
+ * lim_merge_extcap_struct() - merge extended capabilities info
+ * @dst: destination extended capabilities
+ * @src: source extended capabilities
+ * @add: true if add the capabilities, false if strip the capabilities.
+ *
+ * This function is used to take @src info and add/strip it to/from
+ * @dst extended capabilities info.
+ *
+ * Return: None
+ */
+void lim_merge_extcap_struct(tDot11fIEExtCap *dst,
+			     tDot11fIEExtCap *src,
+			     bool add)
+{
+	uint8_t *tempdst = (uint8_t *)dst->bytes;
+	uint8_t *tempsrc = (uint8_t *)src->bytes;
+	uint8_t structlen = member_size(tDot11fIEExtCap, bytes);
+
+	/* Return if @src not present */
+	if (!src->present)
+		return;
+
+	/* Return if strip the capabilities from @dst which not present */
+	if (!dst->present && !add)
+		return;
+
+	/* Merge the capabilities info in other cases */
+	while (tempdst && tempsrc && structlen--) {
+		if (add)
+			*tempdst |= *tempsrc;
+		else
+			*tempdst &= *tempsrc;
+		tempdst++;
+		tempsrc++;
+	}
+	dst->num_bytes = lim_compute_ext_cap_ie_length(dst);
+	if (dst->num_bytes == 0)
+		dst->present = 0;
+	else
+		dst->present = 1;
+}
+
+/**
+ * lim_get_80Mhz_center_channel - finds 80 Mhz center channel
+ *
+ * @primary_channel:   Primary channel for given 80 MHz band
+ *
+ * There are fixed 80MHz band and for each fixed band there is only one center
+ * valid channel. Also location of primary channel decides what 80 MHz band will
+ * it use, hence it decides what center channel will be used. This function
+ * does thus calculation and returns the center channel.
+ *
+ * Return: center channel
+ */
+uint8_t
+lim_get_80Mhz_center_channel(uint8_t primary_channel)
+{
+	if (primary_channel >= 36 && primary_channel <= 48)
+		return (36+48)/2;
+	if (primary_channel >= 52 && primary_channel <= 64)
+		return (52+64)/2;
+	if (primary_channel >= 100 && primary_channel <= 112)
+		return (100+112)/2;
+	if (primary_channel >= 116 && primary_channel <= 128)
+		return (116+128)/2;
+	if (primary_channel >= 132 && primary_channel <= 144)
+		return (132+144)/2;
+	if (primary_channel >= 149 && primary_channel <= 161)
+		return (149+161)/2;
+
+	return INVALID_CHANNEL_ID;
+}
+
+/**
+ * lim_bss_type_to_string(): converts bss type enum to string.
+ * @bss_type: enum value of bss_type.
+ *
+ * Return: Printable string for bss_type
+ */
+const char *lim_bss_type_to_string(const uint16_t bss_type)
+{
+	switch (bss_type) {
+	CASE_RETURN_STRING(eSIR_INFRASTRUCTURE_MODE);
+	CASE_RETURN_STRING(eSIR_INFRA_AP_MODE);
+	CASE_RETURN_STRING(eSIR_IBSS_MODE);
+	CASE_RETURN_STRING(eSIR_AUTO_MODE);
+	CASE_RETURN_STRING(eSIR_NDI_MODE);
+	default:
+		return "Unknown bss_type";
+	}
+}
+
+/**
+ * lim_init_obss_params(): Initializes the OBSS Scan Parameters
+ * @sesssion: LIM session
+ * @mac_ctx: Mac context
+ *
+ * Return: None
+ */
+void lim_init_obss_params(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+	struct wlan_mlme_obss_ht40 *obss_ht40;
+
+	if (!(mac_ctx->mlme_cfg)) {
+		pe_err("invalid mlme cfg");
+		return;
+	}
+
+	obss_ht40  = &mac_ctx->mlme_cfg->obss_ht40;
+
+	session->obss_ht40_scanparam.obss_active_dwelltime =
+		obss_ht40->active_dwelltime;
+
+	session->obss_ht40_scanparam.obss_passive_dwelltime =
+		obss_ht40->passive_dwelltime;
+
+	session->obss_ht40_scanparam.obss_width_trigger_interval =
+		obss_ht40->width_trigger_interval;
+
+	session->obss_ht40_scanparam.obss_active_total_per_channel =
+		obss_ht40->active_per_channel;
+
+	session->obss_ht40_scanparam.obss_passive_total_per_channel =
+		obss_ht40->passive_per_channel;
+
+	session->obss_ht40_scanparam.bsswidth_ch_trans_delay =
+		obss_ht40->width_trans_delay;
+
+	session->obss_ht40_scanparam.obss_activity_threshold =
+		obss_ht40->scan_activity_threshold;
+}
+
+/**
+ * lim_update_obss_scanparams(): Updates OBSS SCAN IE parameters to session
+ * @sesssion: LIM session
+ * @scan_params: Scan parameters
+ *
+ * Return: None
+ */
+void lim_update_obss_scanparams(tpPESession session,
+			tDot11fIEOBSSScanParameters *scan_params)
+{
+	/*
+	 * If the received value is not in the range specified
+	 * by the Specification then it will be the default value
+	 * configured through cfg
+	 */
+	if ((scan_params->obssScanActiveDwell >
+		cfg_min(CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME)) &&
+		(scan_params->obssScanActiveDwell <
+		cfg_max(CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME)))
+		session->obss_ht40_scanparam.obss_active_dwelltime =
+			scan_params->obssScanActiveDwell;
+
+	if ((scan_params->obssScanPassiveDwell >
+		cfg_min(CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME)) &&
+		(scan_params->obssScanPassiveDwell <
+		cfg_max(CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME)))
+		session->obss_ht40_scanparam.obss_passive_dwelltime =
+			scan_params->obssScanPassiveDwell;
+
+	if ((scan_params->bssWidthChannelTransitionDelayFactor >
+		cfg_min(CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY)) &&
+		(scan_params->bssWidthChannelTransitionDelayFactor <
+		cfg_max(CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY)))
+		session->obss_ht40_scanparam.bsswidth_ch_trans_delay =
+			scan_params->bssWidthChannelTransitionDelayFactor;
+
+	if ((scan_params->obssScanActiveTotalPerChannel >
+		cfg_min(CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL)) &&
+		(scan_params->obssScanActiveTotalPerChannel <
+		cfg_max(CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL)))
+		session->obss_ht40_scanparam.obss_active_total_per_channel =
+			scan_params->obssScanActiveTotalPerChannel;
+
+	if ((scan_params->obssScanPassiveTotalPerChannel >
+		cfg_min(CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL)) &&
+		(scan_params->obssScanPassiveTotalPerChannel <
+		cfg_max(CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL)))
+		session->obss_ht40_scanparam.obss_passive_total_per_channel =
+			scan_params->obssScanPassiveTotalPerChannel;
+
+	if ((scan_params->bssChannelWidthTriggerScanInterval >
+		cfg_min(CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL)) &&
+		(scan_params->bssChannelWidthTriggerScanInterval <
+		cfg_max(CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL)))
+		session->obss_ht40_scanparam.obss_width_trigger_interval =
+			scan_params->bssChannelWidthTriggerScanInterval;
+
+	if ((scan_params->obssScanActivityThreshold >
+		cfg_min(CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD)) &&
+		(scan_params->obssScanActivityThreshold <
+		cfg_max(CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD)))
+		session->obss_ht40_scanparam.obss_activity_threshold =
+			scan_params->obssScanActivityThreshold;
+	return;
+}
+
+/**
+ * lim_is_robust_mgmt_action_frame() - Check if action category is
+ * robust action frame
+ * @action_category: Action frame category.
+ *
+ * This function is used to check if given action category is robust
+ * action frame.
+ *
+ * Return: bool
+ */
+bool lim_is_robust_mgmt_action_frame(uint8_t action_category)
+{
+	switch (action_category) {
+	/*
+	 * NOTE: This function doesn't take care of the DMG
+	 * (Directional Multi-Gigatbit) BSS case as 8011ad
+	 * support is not yet added. In future, if the support
+	 * is required then this function need few more arguments
+	 * and little change in logic.
+	 */
+	case SIR_MAC_ACTION_SPECTRUM_MGMT:
+	case SIR_MAC_ACTION_QOS_MGMT:
+	case SIR_MAC_ACTION_DLP:
+	case SIR_MAC_ACTION_BLKACK:
+	case SIR_MAC_ACTION_RRM:
+	case SIR_MAC_ACTION_FAST_BSS_TRNST:
+	case SIR_MAC_ACTION_SA_QUERY:
+	case SIR_MAC_ACTION_PROT_DUAL_PUB:
+	case SIR_MAC_ACTION_WNM:
+	case SIR_MAC_ACITON_MESH:
+	case SIR_MAC_ACTION_MHF:
+	case SIR_MAC_ACTION_FST:
+		return true;
+	default:
+		pe_debug("non-PMF action category: %d", action_category);
+		break;
+	}
+	return false;
+}
+
+/**
+ * lim_compute_ext_cap_ie_length - compute the length of ext cap ie
+ * based on the bits set
+ * @ext_cap: extended IEs structure
+ *
+ * Return: length of the ext cap ie, 0 means should not present
+ */
+uint8_t lim_compute_ext_cap_ie_length(tDot11fIEExtCap *ext_cap)
+{
+	uint8_t i = DOT11F_IE_EXTCAP_MAX_LEN;
+
+	while (i) {
+		if (ext_cap->bytes[i-1])
+			break;
+		i--;
+	}
+
+	return i;
+}
+
+/**
+ * lim_update_caps_info_for_bss - Update capability info for this BSS
+ *
+ * @mac_ctx: mac context
+ * @caps: Pointer to capability info to be updated
+ * @bss_caps: Capability info of the BSS
+ *
+ * Update the capability info in Assoc/Reassoc request frames and reset
+ * the spectrum management, short preamble, immediate block ack bits
+ * if the BSS doesnot support it
+ *
+ * Return: None
+ */
+void lim_update_caps_info_for_bss(tpAniSirGlobal mac_ctx,
+		uint16_t *caps, uint16_t bss_caps)
+{
+	if (!(bss_caps & LIM_SPECTRUM_MANAGEMENT_BIT_MASK)) {
+		*caps &= (~LIM_SPECTRUM_MANAGEMENT_BIT_MASK);
+		pe_debug("Clearing spectrum management:no AP support");
+	}
+
+	if (!(bss_caps & LIM_SHORT_PREAMBLE_BIT_MASK)) {
+		*caps &= (~LIM_SHORT_PREAMBLE_BIT_MASK);
+		pe_debug("Clearing short preamble:no AP support");
+	}
+
+	if (!(bss_caps & LIM_IMMEDIATE_BLOCK_ACK_MASK)) {
+		*caps &= (~LIM_IMMEDIATE_BLOCK_ACK_MASK);
+		pe_debug("Clearing Immed Blk Ack:no AP support");
+	}
+}
+/**
+ * lim_send_set_dtim_period(): Send SIR_HAL_SET_DTIM_PERIOD message
+ * to set dtim period.
+ *
+ * @sesssion: LIM session
+ * @dtim_period: dtim value
+ * @mac_ctx: Mac context
+ * @return None
+ */
+void lim_send_set_dtim_period(tpAniSirGlobal mac_ctx, uint8_t dtim_period,
+			      tpPESession session)
+{
+	struct set_dtim_params *dtim_params = NULL;
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msg = {0};
+
+	if (!session) {
+		pe_err("Inavalid parameters");
+		return;
+	}
+	dtim_params = qdf_mem_malloc(sizeof(*dtim_params));
+	if (!dtim_params)
+		return;
+	dtim_params->dtim_period = dtim_period;
+	dtim_params->session_id = session->smeSessionId;
+	msg.type = WMA_SET_DTIM_PERIOD;
+	msg.bodyptr = dtim_params;
+	msg.bodyval = 0;
+	pe_debug("Post WMA_SET_DTIM_PERIOD to WMA");
+	ret = wma_post_ctrl_msg(mac_ctx, &msg);
+	if (QDF_STATUS_SUCCESS != ret) {
+		pe_err("wma_post_ctrl_msg() failed");
+		qdf_mem_free(dtim_params);
+	}
+}
+
+/**
+ * lim_is_valid_frame(): validate RX frame using last processed frame details
+ * to find if it is duplicate frame.
+ *
+ * @last_processed_frm: last processed frame pointer.
+ * @pRxPacketInfo: RX packet.
+ *
+ * Frame treat as duplicate:
+ * if retry bit is set and
+ *	 if source address and seq number matches with the last processed frame
+ *
+ * Return: false if duplicate frame, else true.
+ */
+bool lim_is_valid_frame(last_processed_msg *last_processed_frm,
+		uint8_t *pRxPacketInfo)
+{
+	uint16_t seq_num;
+	tpSirMacMgmtHdr pHdr;
+
+	if (!pRxPacketInfo) {
+		pe_err("Invalid RX frame");
+		return false;
+	}
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+	if (pHdr->fc.retry == 0)
+		return true;
+
+	seq_num = (((pHdr->seqControl.seqNumHi <<
+			HIGH_SEQ_NUM_OFFSET) |
+			pHdr->seqControl.seqNumLo));
+
+	if (last_processed_frm->seq_num == seq_num &&
+		qdf_mem_cmp(last_processed_frm->sa, pHdr->sa, ETH_ALEN) == 0) {
+		pe_err("Duplicate frame from "MAC_ADDRESS_STR " Seq Number %d",
+		MAC_ADDR_ARRAY(pHdr->sa), seq_num);
+		return false;
+	}
+	return true;
+}
+
+/**
+ * lim_update_last_processed_frame(): update new processed frame info to cache.
+ *
+ * @last_processed_frm: last processed frame pointer.
+ * @pRxPacketInfo: Successfully processed RX packet.
+ *
+ * Return: None.
+ */
+void lim_update_last_processed_frame(last_processed_msg *last_processed_frm,
+		uint8_t *pRxPacketInfo)
+{
+	uint16_t seq_num;
+	tpSirMacMgmtHdr pHdr;
+
+	if (!pRxPacketInfo) {
+		pe_err("Invalid RX frame");
+		return;
+	}
+
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+	seq_num = (((pHdr->seqControl.seqNumHi <<
+			HIGH_SEQ_NUM_OFFSET) |
+			pHdr->seqControl.seqNumLo));
+
+	qdf_mem_copy(last_processed_frm->sa, pHdr->sa, ETH_ALEN);
+	last_processed_frm->seq_num = seq_num;
+}
+
+#ifdef WLAN_FEATURE_11AX
+void lim_add_he_cap(tpAddStaParams add_sta_params, tpSirAssocReq assoc_req)
+{
+	if (!add_sta_params->he_capable || !assoc_req)
+		return;
+
+	qdf_mem_copy(&add_sta_params->he_config, &assoc_req->he_cap,
+		     sizeof(add_sta_params->he_config));
+}
+
+void lim_add_self_he_cap(tpAddStaParams add_sta_params, tpPESession session)
+{
+	if (!session)
+		return;
+
+	add_sta_params->he_capable = true;
+
+	qdf_mem_copy(&add_sta_params->he_config, &session->he_config,
+		     sizeof(add_sta_params->he_config));
+	qdf_mem_copy(&add_sta_params->he_op, &session->he_op,
+		     sizeof(add_sta_params->he_op));
+}
+
+/**
+ * lim_intersect_he_caps() - Intersect peer capability and self capability
+ * @rcvd_he: pointer to received peer capability
+ * @session_he: pointer to self capability
+ * @peer_he: pointer to Intersected capability
+ *
+ * Return: None
+ */
+static void lim_intersect_he_caps(tDot11fIEhe_cap *rcvd_he,
+			tDot11fIEhe_cap *session_he,
+			tDot11fIEhe_cap *peer_he)
+{
+	uint8_t val;
+
+	qdf_mem_copy(peer_he, rcvd_he, sizeof(*peer_he));
+
+	peer_he->fragmentation &= session_he->fragmentation;
+
+	if (session_he->tx_stbc_lt_80mhz && peer_he->rx_stbc_lt_80mhz)
+		peer_he->rx_stbc_lt_80mhz = 1;
+	else
+		peer_he->rx_stbc_lt_80mhz = 0;
+
+	if (session_he->rx_stbc_lt_80mhz && peer_he->tx_stbc_lt_80mhz)
+		peer_he->tx_stbc_lt_80mhz = 1;
+	else
+		peer_he->tx_stbc_lt_80mhz = 0;
+
+	if (session_he->tx_stbc_gt_80mhz && peer_he->rx_stbc_gt_80mhz)
+		peer_he->rx_stbc_gt_80mhz = 1;
+	else
+		peer_he->rx_stbc_gt_80mhz = 0;
+
+	if (session_he->rx_stbc_gt_80mhz && peer_he->tx_stbc_gt_80mhz)
+		peer_he->tx_stbc_gt_80mhz = 1;
+	else
+		peer_he->tx_stbc_gt_80mhz = 0;
+
+	/* Tx Doppler is first bit and Rx Doppler is second bit */
+	if (session_he->doppler) {
+		val = 0;
+		if ((session_he->doppler & 0x1) && (peer_he->doppler & 0x10))
+			val |= (1 << 1);
+		if ((session_he->doppler & 0x10) && (peer_he->doppler & 0x1))
+			val |= (1 << 0);
+		peer_he->doppler = val;
+	}
+
+	peer_he->su_beamformer = session_he->su_beamformee ?
+					peer_he->su_beamformer : 0;
+	peer_he->su_beamformee = (session_he->su_beamformer ||
+				  session_he->mu_beamformer) ?
+					peer_he->su_beamformee : 0;
+	peer_he->mu_beamformer = session_he->su_beamformee ?
+					peer_he->mu_beamformer : 0;
+
+	peer_he->twt_request = session_he->twt_responder ?
+					peer_he->twt_request : 0;
+	peer_he->twt_responder = session_he->twt_request ?
+					peer_he->twt_responder : 0;
+}
+
+void lim_intersect_sta_he_caps(tpSirAssocReq assoc_req, tpPESession session,
+		tpDphHashNode sta_ds)
+{
+	tDot11fIEhe_cap *rcvd_he = &assoc_req->he_cap;
+	tDot11fIEhe_cap *session_he = &session->he_config;
+	tDot11fIEhe_cap *peer_he = &sta_ds->he_config;
+
+	if (sta_ds->mlmStaContext.he_capable)
+		lim_intersect_he_caps(rcvd_he, session_he, peer_he);
+}
+
+void lim_intersect_ap_he_caps(tpPESession session, tpAddBssParams add_bss,
+		tSchBeaconStruct *beacon, tpSirAssocRsp assoc_rsp)
+{
+	tDot11fIEhe_cap *rcvd_he;
+	tDot11fIEhe_cap *session_he = &session->he_config;
+	tDot11fIEhe_cap *peer_he = &add_bss->staContext.he_config;
+
+	if (beacon)
+		rcvd_he = &beacon->he_cap;
+	else
+		rcvd_he = &assoc_rsp->he_cap;
+
+	lim_intersect_he_caps(rcvd_he, session_he, peer_he);
+	add_bss->staContext.he_capable = true;
+}
+
+void lim_add_bss_he_cap(tpAddBssParams add_bss, tpSirAssocRsp assoc_rsp)
+{
+	tDot11fIEhe_cap *he_cap;
+	tDot11fIEhe_op *he_op;
+
+	he_cap = &assoc_rsp->he_cap;
+	he_op = &assoc_rsp->he_op;
+	add_bss->he_capable = he_cap->present;
+	if (he_cap)
+		qdf_mem_copy(&add_bss->staContext.he_config,
+			     he_cap, sizeof(*he_cap));
+	if (he_op)
+		qdf_mem_copy(&add_bss->staContext.he_op,
+			     he_op, sizeof(*he_op));
+}
+
+void lim_add_bss_he_cfg(tpAddBssParams add_bss, tpPESession session)
+{
+	add_bss->he_sta_obsspd = session->he_sta_obsspd;
+}
+
+void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
+			      tpPESession session_entry)
+{
+	tDot11fIEhe_cap *he_cap;
+
+	he_cap = &assoc_rsp->he_cap;
+	sta_ds->mlmStaContext.he_capable = he_cap->present;
+
+	if (!he_cap->present)
+		return;
+
+	qdf_mem_copy(&sta_ds->he_config, he_cap, sizeof(*he_cap));
+
+}
+
+void lim_update_usr_he_cap(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+	tSirAddIeParams *add_ie = &session->addIeParams;
+	tDot11fIEhe_cap *he_cap = &session->he_config;
+	struct he_cap_network_endian *he_cap_from_ie;
+	uint8_t extracted_buff[DOT11F_IE_HE_CAP_MAX_LEN + 2];
+	QDF_STATUS status;
+	qdf_mem_zero(extracted_buff, sizeof(extracted_buff));
+	status = lim_strip_ie(mac_ctx, add_ie->probeRespBCNData_buff,
+			&add_ie->probeRespBCNDataLen,
+			DOT11F_EID_HE_CAP, ONE_BYTE,
+			HE_CAP_OUI_TYPE, (uint8_t)HE_CAP_OUI_SIZE,
+			extracted_buff, DOT11F_IE_HE_CAP_MAX_LEN);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_debug("Failed to strip HE cap IE status: %d", status);
+		return;
+	}
+
+	pe_debug("Before update: su_beamformer: %d, su_beamformee: %d, mu_beamformer: %d",
+		he_cap->su_beamformer, he_cap->su_beamformee, he_cap->mu_beamformer);
+
+	he_cap_from_ie = (struct he_cap_network_endian *)
+					&extracted_buff[HE_CAP_OUI_SIZE + 2];
+
+	he_cap->su_beamformer =
+		he_cap->su_beamformer & he_cap_from_ie->su_beamformer;
+	he_cap->su_beamformee =
+		he_cap->su_beamformee & he_cap_from_ie->su_beamformee;
+	he_cap->mu_beamformer =
+		he_cap->mu_beamformer & he_cap_from_ie->mu_beamformer;
+
+	pe_debug("After update: su_beamformer: %d, su_beamformee: %d, mu_beamformer: %d",
+		he_cap->su_beamformer, he_cap->su_beamformee, he_cap->mu_beamformer);
+}
+
+void lim_decide_he_op(tpAniSirGlobal mac_ctx, tpAddBssParams add_bss,
+		      tpPESession session)
+{
+	uint32_t val;
+	uint8_t color;
+	struct he_ops_network_endian *he_ops_from_ie;
+	tDot11fIEhe_op *he_ops = &add_bss->he_op;
+	tSirAddIeParams *add_ie = &session->addIeParams;
+	uint8_t extracted_buff[DOT11F_IE_HE_OP_MAX_LEN + 2];
+	QDF_STATUS status;
+
+	qdf_mem_zero(extracted_buff, sizeof(extracted_buff));
+	status = lim_strip_ie(mac_ctx, add_ie->probeRespBCNData_buff,
+			&add_ie->probeRespBCNDataLen,
+			DOT11F_EID_HE_OP, ONE_BYTE,
+			HE_OP_OUI_TYPE, (uint8_t)HE_OP_OUI_SIZE,
+			extracted_buff, DOT11F_IE_HE_OP_MAX_LEN);
+	if (QDF_STATUS_SUCCESS != status) {
+		pe_debug("Failed to strip HE OP IE status: %d", status);
+		return;
+	}
+	he_ops_from_ie = (struct he_ops_network_endian *)
+					&extracted_buff[HE_OP_OUI_SIZE + 2];
+
+	if (he_ops_from_ie->bss_color) {
+		he_ops->bss_color = he_ops_from_ie->bss_color;
+	} else {
+		cds_rand_get_bytes(0, &color, 1);
+		/* make sure color is within 1-63*/
+		he_ops->bss_color = (color % WNI_CFG_HE_OPS_BSS_COLOR_MAX) + 1;
+	}
+	he_ops->default_pe = he_ops_from_ie->default_pe;
+	he_ops->twt_required = he_ops_from_ie->twt_required;
+	he_ops->txop_rts_threshold = he_ops_from_ie->txop_rts_threshold;
+	he_ops->partial_bss_col = he_ops_from_ie->partial_bss_col;
+	he_ops->bss_col_disabled = he_ops_from_ie->bss_col_disabled;
+
+	if (QDF_STATUS_SUCCESS != wlan_cfg_get_int(mac_ctx,
+			WNI_CFG_HE_OPS_BASIC_MCS_NSS, &val))
+		val = WNI_CFG_HE_OPS_BASIC_MCS_NSS_DEF;
+	*((uint16_t *)he_ops->basic_mcs_nss) = (uint16_t)val;
+
+	qdf_mem_copy(&session->he_op, he_ops, sizeof(*he_ops));
+
+	pe_debug("HE Op: bss_color: 0x%0x, default_pe_duration: 0x%0x",
+		he_ops->bss_color, he_ops->default_pe);
+	pe_debug("He Op: twt_required: 0x%0x, txop_rts_threshold: 0x%0x",
+		 he_ops->twt_required, he_ops->txop_rts_threshold);
+	pe_debug("HE Op: partial_bss_color: 0x%0x",
+		 he_ops->partial_bss_col);
+	pe_debug("HE Op: BSS color disabled: 0x%0x",
+		he_ops->bss_col_disabled);
+	pe_debug("HE Op: Basic MCS NSS: 0x%04x",
+		*((uint16_t *)he_ops->basic_mcs_nss));
+}
+
+void lim_copy_bss_he_cap(tpPESession session,
+			 tpSirSmeStartBssReq sme_start_bss_req)
+{
+	qdf_mem_copy(&(session->he_config), &(sme_start_bss_req->he_config),
+		     sizeof(session->he_config));
+}
+
+void lim_copy_join_req_he_cap(tpPESession session,
+			      tpSirSmeJoinReq sme_join_req)
+{
+	qdf_mem_copy(&(session->he_config), &(sme_join_req->he_config),
+		     sizeof(session->he_config));
+
+	if (session->ch_width <= CH_WIDTH_80MHZ) {
+		*(uint16_t *)session->he_config.rx_he_mcs_map_160 =
+							HE_MCS_ALL_DISABLED;
+		*(uint16_t *)session->he_config.tx_he_mcs_map_160 =
+							HE_MCS_ALL_DISABLED;
+		*(uint16_t *)session->he_config.rx_he_mcs_map_80_80 =
+							HE_MCS_ALL_DISABLED;
+		*(uint16_t *)session->he_config.tx_he_mcs_map_80_80 =
+							HE_MCS_ALL_DISABLED;
+	}
+}
+
+void lim_log_he_cap(tpAniSirGlobal mac, tDot11fIEhe_cap *he_cap)
+{
+	uint8_t chan_width;
+	struct ppet_hdr *hdr;
+
+	if (!he_cap->present)
+		return;
+
+	pe_debug("HE Capabilities:");
+
+	/* HE MAC capabilities */
+	pe_debug("\tHTC-HE conrol: 0x%01x", he_cap->htc_he);
+	pe_debug("\tTWT Requestor support: 0x%01x",
+			he_cap->twt_request);
+	pe_debug("\tTWT Responder support: 0x%01x",
+			he_cap->twt_responder);
+	pe_debug("\tFragmentation support: 0x%02x",
+			he_cap->fragmentation);
+	pe_debug("\tMax no.of frag MSDUs: 0x%03x",
+			he_cap->max_num_frag_msdu_amsdu_exp);
+	pe_debug("\tMin. frag size: 0x%02x", he_cap->min_frag_size);
+	pe_debug("\tTrigger MAC pad duration: 0x%02x",
+			he_cap->trigger_frm_mac_pad);
+	pe_debug("\tMulti-TID aggr Rx support: 0x%03x",
+		 he_cap->multi_tid_aggr_rx_supp);
+	pe_debug("\tLink adaptation: 0x%02x",
+			he_cap->he_link_adaptation);
+	pe_debug("\tAll ACK support: 0x%01x", he_cap->all_ack);
+	pe_debug("\tTriggered resp. scheduling: 0x%01x",
+		 he_cap->trigd_rsp_sched);
+	pe_debug("\tA-Buff status report: 0x%01x", he_cap->a_bsr);
+	pe_debug("\tBroadcast TWT support: 0x%01x",
+			he_cap->broadcast_twt);
+	pe_debug("\t32bit BA bitmap support: 0x%01x",
+			he_cap->ba_32bit_bitmap);
+	pe_debug("\tMU Cascading support: 0x%01x",
+			he_cap->mu_cascade);
+	pe_debug("\tACK enabled Multi-TID: 0x%01x",
+			he_cap->ack_enabled_multitid);
+	pe_debug("\tOMI A-Control support: 0x%01x",
+			he_cap->omi_a_ctrl);
+	pe_debug("\tOFDMA RA support: 0x%01x", he_cap->ofdma_ra);
+	pe_debug("\tMax A-MPDU Length: 0x%02x",
+			he_cap->max_ampdu_len_exp_ext);
+	pe_debug("\tA-MSDU Fragmentation: 0x%01x",
+			he_cap->amsdu_frag);
+	pe_debug("\tFlex. TWT sched support: 0x%01x",
+			he_cap->flex_twt_sched);
+	pe_debug("\tRx Ctrl frame to MBSS: 0x%01x",
+			he_cap->rx_ctrl_frame);
+	pe_debug("\tBSRP A-MPDU Aggregation: 0x%01x",
+			he_cap->bsrp_ampdu_aggr);
+	pe_debug("\tQuite Time Period support: 0x%01x", he_cap->qtp);
+	pe_debug("\tA-BQR support: 0x%01x", he_cap->a_bqr);
+	pe_debug("\tSR Reponder support: 0x%01x",
+		 he_cap->spatial_reuse_param_rspder);
+	pe_debug("\tNDP Feedback support: 0x%01x", he_cap->ndp_feedback_supp);
+	pe_debug("\tOPS support: 0x%01x", he_cap->ops_supp);
+	pe_debug("\tAMSDU in AMPDU: 0x%01x", he_cap->amsdu_in_ampdu);
+	pe_debug("\tMulti-TID aggr Tx support: 0x%03x",
+		 he_cap->multi_tid_aggr_tx_supp);
+	pe_debug("\tHE sub ch sel tx supp: 0x%01x",
+		 he_cap->he_sub_ch_sel_tx_supp);
+	pe_debug("\tUL 2x996 tone RU supp: 0x%01x",
+		 he_cap->ul_2x996_tone_ru_supp);
+	pe_debug("\tOM ctrl UL MU data dis rx supp: 0x%01x",
+		 he_cap->om_ctrl_ul_mu_data_dis_rx);
+	/* HE PHY capabilities */
+	chan_width = HE_CH_WIDTH_COMBINE(he_cap->chan_width_0,
+			he_cap->chan_width_1, he_cap->chan_width_2,
+			he_cap->chan_width_3, he_cap->chan_width_4,
+			he_cap->chan_width_5, he_cap->chan_width_6);
+
+	pe_debug("\tChannel width support: 0x%07x", chan_width);
+	pe_debug("\tPreamble puncturing Rx: 0x%04x",
+			he_cap->rx_pream_puncturing);
+	pe_debug("\tClass of device: 0x%01x", he_cap->device_class);
+	pe_debug("\tLDPC coding support: 0x%01x",
+			he_cap->ldpc_coding);
+	pe_debug("\tLTF and GI for HE PPDUs: 0x%02x",
+			he_cap->he_1x_ltf_800_gi_ppdu);
+	pe_debug("\tMidamble TX Rx MAX NSTS: 0x%02x",
+		 he_cap->midamble_tx_rx_max_nsts);
+	pe_debug("\tLTF and GI for NDP: 0x%02x",
+			he_cap->he_4x_ltf_3200_gi_ndp);
+	pe_debug("\tSTBC Tx support (<= 80MHz): 0x%01x",
+		 he_cap->tx_stbc_lt_80mhz);
+	pe_debug("\tSTBC Rx support (<= 80MHz): 0x%01x",
+		 he_cap->rx_stbc_lt_80mhz);
+	pe_debug("\tDoppler support: 0x%02x", he_cap->doppler);
+	pe_debug("\tUL MU: 0x%02x", he_cap->ul_mu);
+	pe_debug("\tDCM encoding Tx: 0x%03x", he_cap->dcm_enc_tx);
+	pe_debug("\tDCM encoding Rx: 0x%03x", he_cap->dcm_enc_rx);
+	pe_debug("\tHE MU PPDU payload support: 0x%01x",
+			he_cap->ul_he_mu);
+	pe_debug("\tSU Beamformer: 0x%01x", he_cap->su_beamformer);
+	pe_debug("\tSU Beamformee: 0x%01x", he_cap->su_beamformee);
+	pe_debug("\tMU Beamformer: 0x%01x", he_cap->mu_beamformer);
+	pe_debug("\tBeamformee STS for <= 80Mhz: 0x%03x",
+			he_cap->bfee_sts_lt_80);
+	pe_debug("\tBeamformee STS for > 80Mhz: 0x%03x",
+			he_cap->bfee_sts_gt_80);
+	pe_debug("\tNo. of sounding dim <= 80Mhz: 0x%03x",
+			he_cap->num_sounding_lt_80);
+	pe_debug("\tNo. of sounding dim > 80Mhz: 0x%03x",
+			he_cap->num_sounding_gt_80);
+	pe_debug("\tNg=16 for SU feedback support: 0x%01x",
+			he_cap->su_feedback_tone16);
+	pe_debug("\tNg=16 for MU feedback support: 0x%01x",
+			he_cap->mu_feedback_tone16);
+	pe_debug("\tCodebook size for SU: 0x%01x",
+			he_cap->codebook_su);
+	pe_debug("\tCodebook size for MU: 0x%01x ",
+			he_cap->codebook_mu);
+	pe_debug("\tBeamforming trigger w/ Trigger: 0x%01x",
+			he_cap->beamforming_feedback);
+	pe_debug("\tHE ER SU PPDU payload: 0x%01x",
+			he_cap->he_er_su_ppdu);
+	pe_debug("\tDL MUMIMO on partial BW: 0x%01x",
+			he_cap->dl_mu_mimo_part_bw);
+	pe_debug("\tPPET present: 0x%01x", he_cap->ppet_present);
+	pe_debug("\tSRP based SR-support: 0x%01x", he_cap->srp);
+	pe_debug("\tPower boost factor: 0x%01x", he_cap->power_boost);
+	pe_debug("\t4x HE LTF support: 0x%01x", he_cap->he_ltf_800_gi_4x);
+	pe_debug("\tSTBC Tx support (> 80MHz): 0x%01x",
+		 he_cap->tx_stbc_gt_80mhz);
+	pe_debug("\tSTBC Rx support (> 80MHz): 0x%01x",
+		 he_cap->rx_stbc_gt_80mhz);
+	pe_debug("\tMax Nc: 0x%03x", he_cap->max_nc);
+	pe_debug("\tER 4x HE LTF support: 0x%01x", he_cap->er_he_ltf_800_gi_4x);
+	pe_debug("\tHE ppdu 20 in 40M in 2.4G: 0x%01x",
+		 he_cap->he_ppdu_20_in_40Mhz_2G);
+	pe_debug("\tHE ppdu 20 in 160 and 80p80: 0x%01x",
+		 he_cap->he_ppdu_20_in_160_80p80Mhz);
+	pe_debug("\tHE ppdu 80 in 160 and 80p80: 0x%01x",
+		 he_cap->he_ppdu_80_in_160_80p80Mhz);
+	pe_debug("\tER 1x HE LTF GI support: 0x%01x",
+		 he_cap->er_1x_he_ltf_gi);
+	pe_debug("\tmidamble txrx 1x he LTF: 0x%01x",
+		 he_cap->midamble_tx_rx_1x_he_ltf);
+	pe_debug("\tDCM max BW: 0x%02x",
+		 he_cap->dcm_max_bw);
+	pe_debug("\tlonger_than_16_he_sigb_ofdm_sym: 0x%01x",
+		 he_cap->longer_than_16_he_sigb_ofdm_sym);
+	pe_debug("\tnon_trig_cqi_feedback: 0x%01x",
+		 he_cap->non_trig_cqi_feedback);
+	pe_debug("\ttx_1024_qam_lt_242_tone_ru: 0x%01x",
+		 he_cap->tx_1024_qam_lt_242_tone_ru);
+	pe_debug("\trx_1024_qam_lt_242_tone_ru: 0x%01x",
+		 he_cap->rx_1024_qam_lt_242_tone_ru);
+	pe_debug("\trx_full_bw_su_he_mu_compress_sigb: 0x%01x",
+		 he_cap->rx_full_bw_su_he_mu_compress_sigb);
+	pe_debug("\trx_full_bw_su_he_mu_non_cmpr_sigb: 0x%01x",
+		 he_cap->rx_full_bw_su_he_mu_non_cmpr_sigb);
+	pe_debug("\tRx MCS map for <= 80 Mhz: 0x%04x",
+		he_cap->rx_he_mcs_map_lt_80);
+	pe_debug("\tTx MCS map for <= 80 Mhz: 0x%04x",
+		he_cap->tx_he_mcs_map_lt_80);
+	pe_debug("\tRx MCS map for <= 160 Mhz: 0x%04x",
+		*((uint16_t *)he_cap->rx_he_mcs_map_160));
+	pe_debug("\tTx MCS map for <= 160 Mhz: 0x%04x",
+		*((uint16_t *)he_cap->tx_he_mcs_map_160));
+	pe_debug("\tRx MCS map for <= 80+80 Mhz: 0x%04x",
+		*((uint16_t *)he_cap->rx_he_mcs_map_80_80));
+	pe_debug("\tTx MCS map for <= 80+80 Mhz: 0x%04x",
+		*((uint16_t *)he_cap->tx_he_mcs_map_80_80));
+
+	hdr = (struct ppet_hdr *)&he_cap->ppet;
+	pe_debug("\t ppe_th:: nss_count: %d, ru_idx_msk: %d",
+		hdr->nss, hdr->ru_idx_mask);
+
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+		&he_cap->ppet, HE_MAX_PPET_SIZE);
+}
+
+void lim_log_he_op(tpAniSirGlobal mac, tDot11fIEhe_op *he_ops)
+{
+	pe_debug("bss_color: %0x, default_pe_duration: %0x, twt_required: %0x, txop_rts_threshold: %0x, vht_oper_present: %0x",
+		 he_ops->bss_color, he_ops->default_pe,
+		 he_ops->twt_required, he_ops->txop_rts_threshold,
+		 he_ops->vht_oper_present);
+	pe_debug("\tpart_bss_color %0x, Co-located BSS %0x, BSS color dis %0x",
+		 he_ops->partial_bss_col, he_ops->co_located_bss,
+		 he_ops->bss_col_disabled);
+
+	pe_debug("he basic mcs nss: 0x%04x",
+		*((uint16_t *)he_ops->basic_mcs_nss));
+
+	if (he_ops->vht_oper_present)
+		pe_debug("VHT Info not present in HE Operation");
+	else
+		pe_debug("VHT Info: chan_width: %d, center_freq0: %d, center_freq1: %d",
+			he_ops->vht_oper.info.chan_width,
+			he_ops->vht_oper.info.center_freq_seg0,
+			he_ops->vht_oper.info.center_freq_seg1);
+}
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+void lim_log_he_bss_color(tpAniSirGlobal mac,
+				tDot11fIEbss_color_change *he_bss_color)
+{
+	pe_debug("countdown: %d, new_color: %d",
+			he_bss_color->countdown, he_bss_color->new_color);
+}
+#endif
+
+void lim_update_sta_he_capable(tpAniSirGlobal mac,
+	tpAddStaParams add_sta_params, tpDphHashNode sta_ds,
+	tpPESession session_entry)
+{
+	if (LIM_IS_AP_ROLE(session_entry) || LIM_IS_IBSS_ROLE(session_entry))
+		add_sta_params->he_capable = sta_ds->mlmStaContext.he_capable;
+	else
+		add_sta_params->he_capable = session_entry->he_capable;
+
+	pe_debug("he_capable: %d", add_sta_params->he_capable);
+}
+
+void lim_update_bss_he_capable(tpAniSirGlobal mac, tpAddBssParams add_bss)
+{
+	add_bss->he_capable = true;
+	pe_debug("he_capable: %d", add_bss->he_capable);
+}
+
+void lim_update_stads_he_capable(tpDphHashNode sta_ds, tpSirAssocReq assoc_req)
+{
+	sta_ds->mlmStaContext.he_capable = assoc_req->he_cap.present;
+}
+
+void lim_update_session_he_capable(tpAniSirGlobal mac, tpPESession session)
+{
+	session->he_capable = true;
+	pe_debug("he_capable: %d", session->he_capable);
+}
+
+void lim_update_chan_he_capable(tpAniSirGlobal mac, tpSwitchChannelParams chan)
+{
+	chan->he_capable = true;
+	pe_debug("he_capable: %d", chan->he_capable);
+}
+
+void lim_set_he_caps(tpAniSirGlobal mac, tpPESession session, uint8_t *ie_start,
+		     uint32_t num_bytes)
+{
+	const uint8_t *ie = NULL;
+	tDot11fIEhe_cap dot11_cap;
+	struct he_capability_info *he_cap;
+
+	populate_dot11f_he_caps(mac, session, &dot11_cap);
+	lim_log_he_cap(mac, &dot11_cap);
+	ie = wlan_get_ext_ie_ptr_from_ext_id(HE_CAP_OUI_TYPE,
+			HE_CAP_OUI_SIZE, ie_start, num_bytes);
+	if (ie) {
+		/* convert from unpacked to packed structure */
+		he_cap = (struct he_capability_info *) &ie[2 + HE_CAP_OUI_SIZE];
+
+		he_cap->htc_he = dot11_cap.htc_he;
+		he_cap->twt_request = dot11_cap.twt_request;
+		he_cap->twt_responder = dot11_cap.twt_responder;
+		he_cap->fragmentation = dot11_cap.fragmentation;
+		he_cap->max_num_frag_msdu_amsdu_exp =
+			dot11_cap.max_num_frag_msdu_amsdu_exp;
+		he_cap->min_frag_size = dot11_cap.min_frag_size;
+		he_cap->trigger_frm_mac_pad = dot11_cap.trigger_frm_mac_pad;
+		he_cap->multi_tid_aggr_rx_supp =
+			dot11_cap.multi_tid_aggr_rx_supp;
+		he_cap->he_link_adaptation = dot11_cap.he_link_adaptation;
+		he_cap->all_ack = dot11_cap.all_ack;
+		he_cap->trigd_rsp_sched = dot11_cap.trigd_rsp_sched;
+		he_cap->a_bsr = dot11_cap.a_bsr;
+		he_cap->broadcast_twt = dot11_cap.broadcast_twt;
+		he_cap->ba_32bit_bitmap = dot11_cap.ba_32bit_bitmap;
+		he_cap->mu_cascade = dot11_cap.mu_cascade;
+		he_cap->ack_enabled_multitid = dot11_cap.ack_enabled_multitid;
+		he_cap->omi_a_ctrl = dot11_cap.omi_a_ctrl;
+		he_cap->ofdma_ra = dot11_cap.ofdma_ra;
+		he_cap->max_ampdu_len_exp_ext = dot11_cap.max_ampdu_len_exp_ext;
+		he_cap->amsdu_frag = dot11_cap.amsdu_frag;
+		he_cap->flex_twt_sched = dot11_cap.flex_twt_sched;
+		he_cap->rx_ctrl_frame = dot11_cap.rx_ctrl_frame;
+
+		he_cap->bsrp_ampdu_aggr = dot11_cap.bsrp_ampdu_aggr;
+		he_cap->qtp = dot11_cap.qtp;
+		he_cap->a_bqr = dot11_cap.a_bqr;
+		he_cap->spatial_reuse_param_rspder =
+			dot11_cap.spatial_reuse_param_rspder;
+		he_cap->ops_supp = dot11_cap.ops_supp;
+		he_cap->ndp_feedback_supp = dot11_cap.ndp_feedback_supp;
+		he_cap->amsdu_in_ampdu = dot11_cap.amsdu_in_ampdu;
+		he_cap->reserved1 = dot11_cap.reserved1;
+
+		he_cap->chan_width = HE_CH_WIDTH_COMBINE(dot11_cap.chan_width_0,
+				dot11_cap.chan_width_1, dot11_cap.chan_width_2,
+				dot11_cap.chan_width_3, dot11_cap.chan_width_4,
+				dot11_cap.chan_width_5, dot11_cap.chan_width_6);
+
+		he_cap->rx_pream_puncturing = dot11_cap.rx_pream_puncturing;
+		he_cap->device_class = dot11_cap.device_class;
+		he_cap->ldpc_coding = dot11_cap.ldpc_coding;
+		he_cap->he_1x_ltf_800_gi_ppdu = dot11_cap.he_1x_ltf_800_gi_ppdu;
+		he_cap->midamble_tx_rx_max_nsts =
+			dot11_cap.midamble_tx_rx_max_nsts;
+		he_cap->he_4x_ltf_3200_gi_ndp = dot11_cap.he_4x_ltf_3200_gi_ndp;
+		he_cap->tx_stbc_lt_80mhz = dot11_cap.tx_stbc_lt_80mhz;
+		he_cap->rx_stbc_lt_80mhz = dot11_cap.rx_stbc_lt_80mhz;
+		he_cap->tx_stbc_gt_80mhz = dot11_cap.tx_stbc_gt_80mhz;
+		he_cap->rx_stbc_gt_80mhz = dot11_cap.rx_stbc_gt_80mhz;
+		he_cap->doppler = dot11_cap.doppler;
+		he_cap->ul_mu = dot11_cap.ul_mu;
+		he_cap->dcm_enc_tx = dot11_cap.dcm_enc_tx;
+		he_cap->dcm_enc_rx = dot11_cap.dcm_enc_rx;
+		he_cap->ul_he_mu = dot11_cap.ul_he_mu;
+		he_cap->su_beamformer = dot11_cap.su_beamformer;
+
+		he_cap->su_beamformee = dot11_cap.su_beamformee;
+		he_cap->mu_beamformer = dot11_cap.mu_beamformer;
+		he_cap->bfee_sts_lt_80 = dot11_cap.bfee_sts_lt_80;
+		he_cap->bfee_sts_gt_80 = dot11_cap.bfee_sts_gt_80;
+		he_cap->num_sounding_lt_80 = dot11_cap.num_sounding_lt_80;
+		he_cap->num_sounding_gt_80 = dot11_cap.num_sounding_gt_80;
+		he_cap->su_feedback_tone16 = dot11_cap.su_feedback_tone16;
+		he_cap->mu_feedback_tone16 = dot11_cap.mu_feedback_tone16;
+		he_cap->codebook_su = dot11_cap.codebook_su;
+		he_cap->codebook_mu = dot11_cap.codebook_mu;
+		he_cap->beamforming_feedback = dot11_cap.beamforming_feedback;
+		he_cap->he_er_su_ppdu = dot11_cap.he_er_su_ppdu;
+		he_cap->dl_mu_mimo_part_bw = dot11_cap.dl_mu_mimo_part_bw;
+		he_cap->ppet_present = dot11_cap.ppet_present;
+		he_cap->srp = dot11_cap.srp;
+		he_cap->power_boost = dot11_cap.power_boost;
+
+		he_cap->he_ltf_800_gi_4x = dot11_cap.he_ltf_800_gi_4x;
+		he_cap->max_nc = dot11_cap.max_nc;
+		he_cap->er_he_ltf_800_gi_4x = dot11_cap.er_he_ltf_800_gi_4x;
+		he_cap->he_ppdu_20_in_40Mhz_2G =
+					dot11_cap.he_ppdu_20_in_40Mhz_2G;
+		he_cap->he_ppdu_20_in_160_80p80Mhz =
+					dot11_cap.he_ppdu_20_in_160_80p80Mhz;
+		he_cap->he_ppdu_80_in_160_80p80Mhz =
+					dot11_cap.he_ppdu_80_in_160_80p80Mhz;
+		he_cap->er_1x_he_ltf_gi =
+					dot11_cap.er_1x_he_ltf_gi;
+		he_cap->midamble_tx_rx_1x_he_ltf =
+					dot11_cap.midamble_tx_rx_1x_he_ltf;
+		he_cap->reserved2 = dot11_cap.reserved2;
+
+		he_cap->rx_he_mcs_map_lt_80 = dot11_cap.rx_he_mcs_map_lt_80;
+		he_cap->tx_he_mcs_map_lt_80 = dot11_cap.tx_he_mcs_map_lt_80;
+		he_cap->rx_he_mcs_map_160 =
+				*((uint16_t *)dot11_cap.rx_he_mcs_map_160);
+		he_cap->tx_he_mcs_map_160 =
+				*((uint16_t *)dot11_cap.tx_he_mcs_map_160);
+		he_cap->rx_he_mcs_map_80_80 =
+				*((uint16_t *)dot11_cap.rx_he_mcs_map_80_80);
+		he_cap->tx_he_mcs_map_80_80 =
+				*((uint16_t *)dot11_cap.tx_he_mcs_map_80_80);
+	}
+}
+
+QDF_STATUS lim_send_he_caps_ie(tpAniSirGlobal mac_ctx, tpPESession session,
+			       uint8_t vdev_id)
+{
+	uint8_t he_caps[SIR_MAC_HE_CAP_MIN_LEN + 3];
+	struct he_capability_info *he_cap;
+	QDF_STATUS status_5g, status_2g;
+
+	/* Sending only minimal info(no PPET) to FW now, update if required */
+	qdf_mem_zero(he_caps, SIR_MAC_HE_CAP_MIN_LEN + 3);
+	he_caps[0] = DOT11F_EID_HE_CAP;
+	he_caps[1] = SIR_MAC_HE_CAP_MIN_LEN;
+	qdf_mem_copy(&he_caps[2], HE_CAP_OUI_TYPE, HE_CAP_OUI_SIZE);
+	lim_set_he_caps(mac_ctx, session, he_caps,
+			SIR_MAC_HE_CAP_MIN_LEN + 3);
+	he_cap = (struct he_capability_info *) (&he_caps[2 + HE_CAP_OUI_SIZE]);
+	he_cap->ppet_present = 0;
+
+	status_5g = lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_HE_CAP,
+			CDS_BAND_5GHZ, &he_caps[2],
+			SIR_MAC_HE_CAP_MIN_LEN + 1);
+	if (QDF_IS_STATUS_ERROR(status_5g))
+		pe_err("Unable send HE Cap IE for 5GHZ band, status: %d",
+			status_5g);
+
+	status_2g = lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_HE_CAP,
+			CDS_BAND_2GHZ, &he_caps[2],
+			SIR_MAC_HE_CAP_MIN_LEN + 1);
+	if (QDF_IS_STATUS_ERROR(status_2g))
+		pe_err("Unable send HE Cap IE for 2GHZ band, status: %d",
+			status_2g);
+
+	if (QDF_IS_STATUS_SUCCESS(status_2g) &&
+		QDF_IS_STATUS_SUCCESS(status_5g))
+		return QDF_STATUS_SUCCESS;
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * lim_populate_he_mcs_per_bw() - pouldate HE mcs set per BW (le 80, 160, 80+80)
+ * @mac_ctx: Global MAC context
+ * @self_rx: self rx mcs set
+ * @self_tx: self tx mcs set
+ * @peer_rx: peer rx mcs set
+ * @peer_tx: peer tx mcs set
+ * @nss: nss
+ * @cfg_rx_param: rx wni param to read
+ * @cfg_tx_param: tx wni param to read
+ *
+ * MCS values are interpreted as in IEEE 11ax-D1.4 spec onwards
+ * +-----------------------------------------------------+
+ * |  SS8  |  SS7  |  SS6  | SS5 | SS4 | SS3 | SS2 | SS1 |
+ * +-----------------------------------------------------+
+ * | 15-14 | 13-12 | 11-10 | 9-8 | 7-6 | 5-4 | 3-2 | 1-0 |
+ * +-----------------------------------------------------+
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS lim_populate_he_mcs_per_bw(tpAniSirGlobal mac_ctx,
+				uint16_t *self_rx, uint16_t *self_tx,
+				uint16_t peer_rx, uint16_t peer_tx, uint8_t nss,
+				uint32_t cfg_rx_param, uint32_t cfg_tx_param)
+{
+	uint32_t val;
+
+	pe_debug("peer rates: rx_mcs - 0x%04x tx_mcs - 0x%04x",
+		 peer_rx, peer_tx);
+	if (wlan_cfg_get_int(mac_ctx, cfg_rx_param, &val) != QDF_STATUS_SUCCESS) {
+		pe_err("could not retrieve HE_MCS");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*self_rx = (uint16_t) val;
+	if (wlan_cfg_get_int(mac_ctx, cfg_tx_param, &val) != QDF_STATUS_SUCCESS) {
+		pe_err("could not retrieve HE_MCS");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*self_tx = (uint16_t) val;
+
+	*self_rx = HE_INTERSECT_MCS(*self_rx, peer_tx);
+	*self_tx = HE_INTERSECT_MCS(*self_tx, peer_rx);
+
+	if (nss == NSS_1x1_MODE) {
+		*self_rx |= HE_MCS_INV_MSK_4_NSS(1);
+		*self_tx |= HE_MCS_INV_MSK_4_NSS(1);
+	}
+	/* if nss is 2, disable higher NSS */
+	if (nss == NSS_2x2_MODE) {
+		*self_rx |= (HE_MCS_INV_MSK_4_NSS(1) & HE_MCS_INV_MSK_4_NSS(2));
+		*self_tx |= (HE_MCS_INV_MSK_4_NSS(1) & HE_MCS_INV_MSK_4_NSS(2));
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS lim_populate_he_mcs_set(tpAniSirGlobal mac_ctx,
+				   tpSirSupportedRates rates,
+				   tDot11fIEhe_cap *peer_he_caps,
+				   tpPESession session_entry, uint8_t nss)
+{
+	bool support_2x2 = false;
+	uint32_t self_sta_dot11mode = 0;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_sta_dot11mode);
+
+	if (!IS_DOT11_MODE_HE(self_sta_dot11mode))
+		return QDF_STATUS_SUCCESS;
+
+	if ((peer_he_caps == NULL) || (!peer_he_caps->present)) {
+		pe_debug("peer not he capable or he_caps NULL");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	pe_debug("peer rates lt 80: rx_mcs - 0x%04x tx_mcs - 0x%04x",
+		peer_he_caps->rx_he_mcs_map_lt_80,
+		peer_he_caps->tx_he_mcs_map_lt_80);
+	pe_debug("peer rates 160: rx_mcs - 0x%04x tx_mcs - 0x%04x",
+		(*(uint16_t *)peer_he_caps->rx_he_mcs_map_160),
+		(*(uint16_t *)peer_he_caps->tx_he_mcs_map_160));
+	pe_debug("peer rates 80+80: rx_mcs - 0x%04x tx_mcs - 0x%04x",
+		(*(uint16_t *)peer_he_caps->rx_he_mcs_map_80_80),
+		(*(uint16_t *)peer_he_caps->tx_he_mcs_map_80_80));
+
+	if (session_entry && session_entry->nss == NSS_2x2_MODE) {
+		if (mac_ctx->lteCoexAntShare &&
+			IS_24G_CH(session_entry->currentOperChannel)) {
+			if (IS_2X2_CHAIN(session_entry->chainMask))
+				support_2x2 = true;
+			else
+				pe_err("2x2 not enabled %d",
+					session_entry->chainMask);
+		} else {
+			support_2x2 = true;
+		}
+	}
+
+	lim_populate_he_mcs_per_bw(mac_ctx,
+		&rates->rx_he_mcs_map_lt_80, &rates->tx_he_mcs_map_lt_80,
+		peer_he_caps->rx_he_mcs_map_lt_80,
+		peer_he_caps->tx_he_mcs_map_lt_80, nss,
+		WNI_CFG_HE_RX_MCS_MAP_LT_80, WNI_CFG_HE_TX_MCS_MAP_LT_80);
+	lim_populate_he_mcs_per_bw(mac_ctx,
+		&rates->rx_he_mcs_map_160, &rates->tx_he_mcs_map_160,
+		*((uint16_t *)peer_he_caps->rx_he_mcs_map_160),
+		*((uint16_t *)peer_he_caps->tx_he_mcs_map_160), nss,
+		WNI_CFG_HE_RX_MCS_MAP_160, WNI_CFG_HE_TX_MCS_MAP_160);
+	lim_populate_he_mcs_per_bw(mac_ctx,
+		&rates->rx_he_mcs_map_80_80, &rates->tx_he_mcs_map_80_80,
+		*((uint16_t *)peer_he_caps->rx_he_mcs_map_80_80),
+		*((uint16_t *)peer_he_caps->tx_he_mcs_map_80_80), nss,
+		WNI_CFG_HE_RX_MCS_MAP_80_80, WNI_CFG_HE_TX_MCS_MAP_80_80);
+	if (!support_2x2) {
+		/* disable 2 and higher NSS MCS sets */
+		rates->rx_he_mcs_map_lt_80 |= HE_MCS_INV_MSK_4_NSS(1);
+		rates->tx_he_mcs_map_lt_80 |= HE_MCS_INV_MSK_4_NSS(1);
+		rates->rx_he_mcs_map_160 |= HE_MCS_INV_MSK_4_NSS(1);
+		rates->tx_he_mcs_map_160 |= HE_MCS_INV_MSK_4_NSS(1);
+		rates->rx_he_mcs_map_80_80 |= HE_MCS_INV_MSK_4_NSS(1);
+		rates->tx_he_mcs_map_80_80 |= HE_MCS_INV_MSK_4_NSS(1);
+	}
+
+	pe_debug("enable2x2 - %d nss %d",
+		mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2, nss);
+	pe_debug("he_rx_lt_80 - 0x%x he_tx_lt_80 0x%x",
+		rates->rx_he_mcs_map_lt_80, rates->tx_he_mcs_map_lt_80);
+	pe_debug("he_rx_160 - 0x%x he_tx_160 0x%x",
+		rates->rx_he_mcs_map_160, rates->tx_he_mcs_map_160);
+	pe_debug("he_rx_80_80 - 0x%x he_tx_80_80 0x%x",
+		rates->rx_he_mcs_map_80_80, rates->tx_he_mcs_map_80_80);
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * lim_assoc_rej_get_remaining_delta() - Get remaining time delta for
+ * the rssi based disallowed list entry
+ * @node: rssi based disallowed list entry
+ *
+ * Return: remaining delta, can be -ve if time has already expired.
+ */
+static inline int
+lim_assoc_rej_get_remaining_delta(struct sir_rssi_disallow_lst *node)
+{
+	qdf_time_t cur_time;
+	uint32_t time_diff;
+
+	cur_time = qdf_do_div(qdf_get_monotonic_boottime(),
+				QDF_MC_TIMER_TO_MS_UNIT);
+	time_diff = cur_time - node->time_during_rejection;
+
+	return node->retry_delay - time_diff;
+}
+
+/**
+ * lim_assoc_rej_rem_entry_with_lowest_delta() - Remove the entry
+ * with lowest time delta
+ * @list: rssi based rejected BSSID list
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+lim_assoc_rej_rem_entry_with_lowest_delta(qdf_list_t *list)
+{
+	struct sir_rssi_disallow_lst *oldest_node = NULL;
+	struct sir_rssi_disallow_lst *cur_node;
+	qdf_list_node_t *cur_list = NULL;
+	qdf_list_node_t *next_list = NULL;
+
+	qdf_list_peek_front(list, &cur_list);
+	while (cur_list) {
+		cur_node = qdf_container_of(cur_list,
+			struct sir_rssi_disallow_lst, node);
+		if (!oldest_node ||
+		   (lim_assoc_rej_get_remaining_delta(oldest_node) >
+		    lim_assoc_rej_get_remaining_delta(cur_node)))
+			oldest_node = cur_node;
+
+		qdf_list_peek_next(list, cur_list, &next_list);
+		cur_list = next_list;
+		next_list = NULL;
+	}
+
+	if (oldest_node) {
+		pe_debug("remove node %pM with lowest delta %d",
+			oldest_node->bssid.bytes,
+			lim_assoc_rej_get_remaining_delta(oldest_node));
+		qdf_list_remove_node(list, &oldest_node->node);
+		qdf_mem_free(oldest_node);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	return QDF_STATUS_E_INVAL;
+}
+
+void lim_assoc_rej_add_to_rssi_based_reject_list(tpAniSirGlobal mac_ctx,
+	tDot11fTLVrssi_assoc_rej  *rssi_assoc_rej,
+	tSirMacAddr bssid, int8_t rssi)
+{
+	struct sir_rssi_disallow_lst *entry;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	entry = qdf_mem_malloc(sizeof(*entry));
+	if (!entry)
+		return;
+
+	pe_debug("%pM: assoc resp rssi %d, delta rssi %d retry delay %d sec and list size %d",
+		bssid, rssi, rssi_assoc_rej->delta_rssi,
+		rssi_assoc_rej->retry_delay,
+		qdf_list_size(&mac_ctx->roam.rssi_disallow_bssid));
+
+	qdf_mem_copy(entry->bssid.bytes,
+		bssid, QDF_MAC_ADDR_SIZE);
+	entry->retry_delay = rssi_assoc_rej->retry_delay *
+		QDF_MC_TIMER_TO_MS_UNIT;
+	entry->expected_rssi = rssi + rssi_assoc_rej->delta_rssi;
+	entry->time_during_rejection =
+		qdf_do_div(qdf_get_monotonic_boottime(),
+		QDF_MC_TIMER_TO_MS_UNIT);
+
+	if (qdf_list_size(&mac_ctx->roam.rssi_disallow_bssid) >=
+		MAX_RSSI_AVOID_BSSID_LIST) {
+		status = lim_assoc_rej_rem_entry_with_lowest_delta(
+					&mac_ctx->roam.rssi_disallow_bssid);
+		if (QDF_IS_STATUS_ERROR(status))
+			pe_err("Failed to remove entry with lowest delta");
+	}
+
+	if (QDF_IS_STATUS_SUCCESS(status))
+		status = qdf_list_insert_back(
+				&mac_ctx->roam.rssi_disallow_bssid,
+				&entry->node);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("Failed to enqueue bssid entry");
+		qdf_mem_free(entry);
+	}
+}
+
+void lim_decrement_pending_mgmt_count(tpAniSirGlobal mac_ctx)
+{
+	qdf_spin_lock(&mac_ctx->sys.bbt_mgmt_lock);
+	if (!mac_ctx->sys.sys_bbt_pending_mgmt_count) {
+		qdf_spin_unlock(&mac_ctx->sys.bbt_mgmt_lock);
+		return;
+	}
+	mac_ctx->sys.sys_bbt_pending_mgmt_count--;
+	qdf_spin_unlock(&mac_ctx->sys.bbt_mgmt_lock);
+}
+
+struct csr_roam_session *lim_get_session_by_macaddr(tpAniSirGlobal mac_ctx,
+		tSirMacAddr self_mac)
+{
+	int i = 0;
+	struct csr_roam_session *session;
+
+	if (!mac_ctx || !self_mac) {
+		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid arguments"));
+		return NULL;
+	}
+
+	for (i = 0; i < mac_ctx->sme.max_intf_count; i++) {
+		session = CSR_GET_SESSION(mac_ctx, i);
+		if (!session)
+			continue;
+		else if (!qdf_mem_cmp(&session->selfMacAddr,
+			 self_mac, sizeof(tSirMacAddr))) {
+
+			QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
+				  FL("session %d exists with mac address "
+				  MAC_ADDRESS_STR), session->sessionId,
+				  MAC_ADDR_ARRAY(self_mac));
+
+			return session;
+		}
+	}
+
+	return NULL;
+}
+
+bool lim_check_if_vendor_oui_match(tpAniSirGlobal mac_ctx,
+					uint8_t *oui, uint8_t oui_len,
+			       uint8_t *ie, uint8_t ie_len)
+{
+	uint8_t *ptr = ie;
+	uint8_t elem_id;
+
+	if (NULL == ie || 0 == ie_len) {
+		pe_err("IE Null or ie len zero %d", ie_len);
+		return false;
+	}
+
+	elem_id = *ie;
+
+	if (elem_id == IE_EID_VENDOR &&
+		!qdf_mem_cmp(&ptr[2], oui, oui_len))
+		return true;
+	else
+		return false;
+}
+
+QDF_STATUS lim_util_get_type_subtype(void *pkt, uint8_t *type,
+						uint8_t *subtype)
+{
+	cds_pkt_t *cds_pkt;
+	QDF_STATUS status;
+	tpSirMacMgmtHdr hdr;
+	uint8_t *rxpktinfor;
+
+	cds_pkt = (cds_pkt_t *) pkt;
+	if (!cds_pkt) {
+		pe_err("NULL packet received");
+		return QDF_STATUS_E_FAILURE;
+	}
+	status =
+		wma_ds_peek_rx_packet_info(cds_pkt, (void *)&rxpktinfor, false);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		pe_err("Failed extract cds packet. status %d", status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hdr = WMA_GET_RX_MAC_HEADER(rxpktinfor);
+	if (hdr->fc.type == SIR_MAC_MGMT_FRAME) {
+		pe_debug("RxBd: %pK mHdr: %pK Type: %d Subtype: %d SizeFC: %zu",
+				rxpktinfor, hdr, hdr->fc.type, hdr->fc.subType,
+				sizeof(tSirMacFrameCtl));
+		*type = hdr->fc.type;
+		*subtype = hdr->fc.subType;
+	} else {
+		pe_err("Not a management packet type %d", hdr->fc.type);
+		return QDF_STATUS_E_INVAL;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+enum rateid lim_get_min_session_txrate(tpPESession session)
+{
+	enum rateid rid = RATEID_DEFAULT;
+	uint8_t min_rate = SIR_MAC_RATE_54, curr_rate, i;
+	tSirMacRateSet *rateset = &session->rateSet;
+
+	if (!session)
+		return rid;
+
+	for (i = 0; i < rateset->numRates; i++) {
+		/* Ignore MSB - set to indicate basic rate */
+		curr_rate = rateset->rate[i] & 0x7F;
+		min_rate =  (curr_rate < min_rate) ? curr_rate : min_rate;
+	}
+	pe_debug("supported min_rate: %0x(%d)", min_rate, min_rate);
+
+	switch (min_rate) {
+	case SIR_MAC_RATE_1:
+		rid = RATEID_1MBPS;
+		break;
+	case SIR_MAC_RATE_2:
+		rid = RATEID_2MBPS;
+		break;
+	case SIR_MAC_RATE_5_5:
+		rid = RATEID_5_5MBPS;
+		break;
+	case SIR_MAC_RATE_11:
+		rid = RATEID_11MBPS;
+		break;
+	case SIR_MAC_RATE_6:
+		rid = RATEID_6MBPS;
+		break;
+	case SIR_MAC_RATE_9:
+		rid = RATEID_9MBPS;
+		break;
+	case SIR_MAC_RATE_12:
+		rid = RATEID_12MBPS;
+		break;
+	case SIR_MAC_RATE_18:
+		rid = RATEID_18MBPS;
+		break;
+	case SIR_MAC_RATE_24:
+		rid = RATEID_24MBPS;
+		break;
+	case SIR_MAC_RATE_36:
+		rid = RATEID_36MBPS;
+		break;
+	case SIR_MAC_RATE_48:
+		rid = RATEID_48MBPS;
+		break;
+	case SIR_MAC_RATE_54:
+		rid = RATEID_54MBPS;
+		break;
+	default:
+		rid = RATEID_DEFAULT;
+		break;
+	}
+
+	return rid;
+}
+
+void lim_convert_active_channel_to_passive_channel(tpAniSirGlobal mac_ctx)
+{
+	uint64_t current_time;
+	uint64_t last_time = 0;
+	uint64_t time_diff;
+	uint8_t i;
+
+	current_time = (uint64_t)qdf_mc_timer_get_system_time();
+	for (i = 1; i < SIR_MAX_24G_5G_CHANNEL_RANGE; i++) {
+		if ((mac_ctx->lim.dfschannelList.timeStamp[i]) != 0) {
+			last_time = mac_ctx->lim.dfschannelList.timeStamp[i];
+			if (current_time >= last_time) {
+				time_diff = (current_time - last_time);
+			} else {
+				time_diff =
+					(0xFFFFFFFF - last_time) + current_time;
+			}
+
+			if (time_diff >= MAX_TIME_TO_BE_ACTIVE_CHANNEL) {
+				lim_covert_channel_scan_type(mac_ctx, i, false);
+				mac_ctx->lim.dfschannelList.timeStamp[i] = 0;
+			}
+		}
+	}
+	/*
+	 * last_time is zero if there is no DFS active channels in the list.
+	 * If this is non zero then we have active DFS channels so restart
+	 * the timer.
+	 */
+	if (last_time != 0) {
+		if (tx_timer_activate
+		    (&mac_ctx->lim.limTimers.gLimActiveToPassiveChannelTimer)
+		    != TX_SUCCESS) {
+			pe_err("Active to Passive Channel timer not activated");
+		}
+	}
+	return;
+}
+
+void lim_send_sme_mgmt_frame_ind(tpAniSirGlobal mac_ctx, uint8_t frame_type,
+				 uint8_t *frame, uint32_t frame_len,
+				 uint16_t session_id, uint32_t rx_channel,
+				 tpPESession psession_entry, int8_t rx_rssi)
+{
+	tpSirSmeMgmtFrameInd sme_mgmt_frame = NULL;
+	uint16_t length;
+
+	length = sizeof(tSirSmeMgmtFrameInd) + frame_len;
+
+	sme_mgmt_frame = qdf_mem_malloc(length);
+	if (!sme_mgmt_frame)
+		return;
+
+	if (qdf_is_macaddr_broadcast(
+		(struct qdf_mac_addr *)(frame + 4)) &&
+		!session_id) {
+		pe_debug("Broadcast action frame");
+		session_id = SME_SESSION_ID_BROADCAST;
+	}
+
+	sme_mgmt_frame->frame_len = frame_len;
+	sme_mgmt_frame->sessionId = session_id;
+	sme_mgmt_frame->frameType = frame_type;
+	sme_mgmt_frame->rxRssi = rx_rssi;
+	sme_mgmt_frame->rxChan = rx_channel;
+
+	qdf_mem_zero(sme_mgmt_frame->frameBuf, frame_len);
+	qdf_mem_copy(sme_mgmt_frame->frameBuf, frame, frame_len);
+
+	if (mac_ctx->mgmt_frame_ind_cb)
+		mac_ctx->mgmt_frame_ind_cb(sme_mgmt_frame);
+	else
+		pe_debug_rl("Management indication callback not registered!!");
+	qdf_mem_free(sme_mgmt_frame);
+	return;
+}
+
+void
+lim_send_dfs_chan_sw_ie_update(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+	/* Update the beacon template and send to FW */
+	if (sch_set_fixed_beacon_fields(mac_ctx, session) !=
+					QDF_STATUS_SUCCESS) {
+		pe_err("Unable to set CSA IE in beacon");
+		return;
+	}
+
+	/* Send update beacon template message */
+	lim_send_beacon_ind(mac_ctx, session, REASON_CHANNEL_SWITCH);
+	pe_debug("Updated CSA IE, IE COUNT: %d",
+		 session->gLimChannelSwitch.switchCount);
+}
+
+void lim_process_ap_ecsa_timeout(void *data)
+{
+	tpPESession session = (tpPESession)data;
+	tpAniSirGlobal mac_ctx;
+	uint8_t bcn_int, ch, ch_width;
+	QDF_STATUS status;
+
+	if (!session) {
+		pe_err("Session is NULL");
+		return;
+	}
+
+	mac_ctx = session->mac_ctx;
+
+	if (!session->dfsIncludeChanSwIe) {
+		pe_debug("session->dfsIncludeChanSwIe not set");
+		return;
+	}
+
+	if (session->gLimChannelSwitch.switchCount) {
+		/* Decrement the beacon switch count */
+		session->gLimChannelSwitch.switchCount--;
+		pe_debug("current beacon count %d",
+			 session->gLimChannelSwitch.switchCount);
+	}
+
+	/*
+	 * Send only g_sap_chanswitch_beacon_cnt beacons with CSA IE Set in
+	 * when a radar is detected
+	 */
+	if (session->gLimChannelSwitch.switchCount > 0) {
+		/* Send the next beacon with updated CSA IE count */
+		lim_send_dfs_chan_sw_ie_update(mac_ctx, session);
+
+		ch = session->gLimChannelSwitch.primaryChannel;
+		ch_width = session->gLimChannelSwitch.ch_width;
+		if (mac_ctx->sap.SapDfsInfo.dfs_beacon_tx_enhanced)
+			/* Send Action frame after updating beacon */
+			lim_send_chan_switch_action_frame(mac_ctx, ch, ch_width,
+							  session);
+
+		/* Restart the timer */
+		if (session->beaconParams.beaconInterval)
+			bcn_int = session->beaconParams.beaconInterval;
+		else
+			bcn_int = MLME_CFG_BEACON_INTERVAL_DEF;
+
+		status = qdf_mc_timer_start(&session->ap_ecsa_timer,
+					    bcn_int);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pe_err("cannot start ap_ecsa_timer");
+			lim_process_ap_ecsa_timeout(session);
+		}
+	} else {
+		tSirSmeCSAIeTxCompleteRsp *chan_switch_tx_rsp;
+		struct scheduler_msg msg = {0};
+		uint8_t length = sizeof(*chan_switch_tx_rsp);
+
+		/* Done with CSA IE update, send response back to SME */
+		session->gLimChannelSwitch.switchCount = 0;
+		if (mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false)
+			session->gLimChannelSwitch.switchMode = 0;
+		session->dfsIncludeChanSwIe = false;
+		session->dfsIncludeChanWrapperIe = false;
+
+		chan_switch_tx_rsp = qdf_mem_malloc(length);
+		if (!chan_switch_tx_rsp)
+			return;
+
+		chan_switch_tx_rsp->sessionId = session->smeSessionId;
+		chan_switch_tx_rsp->chanSwIeTxStatus = QDF_STATUS_SUCCESS;
+
+		msg.type = eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND;
+		msg.bodyptr = chan_switch_tx_rsp;
+
+		status = scheduler_post_message(QDF_MODULE_ID_PE,
+						QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_SME, &msg);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			sme_err("Failed to post eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND");
+			qdf_mem_free(chan_switch_tx_rsp);
+		}
+	}
+}
+
+#ifdef CONFIG_VDEV_SM
+QDF_STATUS lim_sta_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
+					uint16_t data_len, void *data)
+{
+	tpAniSirGlobal mac_ctx;
+	enum vdev_assoc_type assoc_type;
+
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac_ctx) {
+		pe_err("mac_ctx is NULL");
+		if (data)
+			qdf_mem_free(data);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	assoc_type = mlme_get_assoc_type(vdev_mlme->vdev);
+	switch (assoc_type) {
+	case VDEV_ASSOC:
+		lim_process_mlm_join_req(mac_ctx, (tLimMlmJoinReq *)data);
+		break;
+	case VDEV_REASSOC:
+		lim_process_mlm_reassoc_req(mac_ctx, (tLimMlmReassocReq *)data);
+		break;
+	case VDEV_FT_REASSOC:
+		lim_process_mlm_ft_reassoc_req(mac_ctx,
+					       (tLimMlmReassocReq *)data);
+		break;
+	default:
+		pe_err("assoc_type %d is invalid", assoc_type);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS lim_sta_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
+				       uint16_t data_len, void *data)
+{
+	QDF_STATUS status;
+	bool connection_fail;
+
+	if (!data) {
+		pe_err("event_data is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	connection_fail = mlme_is_connection_fail(vdev_mlme->vdev);
+	pe_info("Send vdev stop, connection_fail %d", connection_fail);
+	if (connection_fail) {
+		status = lim_sta_send_down_link((join_params *)data);
+		mlme_set_connection_fail(vdev_mlme->vdev, false);
+	} else {
+		status = lim_sta_send_del_bss((tpPESession)data);
+	}
+
+	return status;
+}
+
+void lim_send_beacon(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+	if (wlan_vdev_mlme_get_state(session->vdev) ==
+	    WLAN_VDEV_S_DFS_CAC_WAIT)
+		wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					      WLAN_VDEV_SM_EV_DFS_CAC_COMPLETED,
+					      sizeof(*session), session);
+	else
+		wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					      WLAN_VDEV_SM_EV_START_SUCCESS,
+					      sizeof(*session), session);
+}
+
+void lim_ndi_mlme_vdev_up_transition(tpPESession session)
+{
+	if (!LIM_IS_NDI_ROLE(session))
+		return;
+
+	wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+				      WLAN_VDEV_SM_EV_START_SUCCESS,
+				      sizeof(*session), session);
+}
+
+QDF_STATUS lim_ap_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
+				       uint16_t data_len, void *data)
+{
+	tpPESession session;
+	tSirResultCodes ret;
+	tpLimMlmStartReq start_req = (tLimMlmStartReq *)data;
+	tpAniSirGlobal mac_ctx;
+
+	if (!data) {
+		pe_err("data is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac_ctx) {
+		pe_err("mac_ctx is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	session = pe_find_session_by_session_id(mac_ctx,
+						start_req->sessionId);
+	if (!session) {
+		pe_err("session is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (LIM_IS_IBSS_ROLE(session) &&
+	    session->mac_ctx->lim.gLimIbssCoalescingHappened) {
+		ibss_bss_add(session->mac_ctx, session);
+		ret = lim_mlm_add_bss(session->mac_ctx, start_req, session);
+		if (ret != eSIR_SME_SUCCESS) {
+			pe_err("AddBss failure");
+			return QDF_STATUS_E_INVAL;
+		}
+	} else {
+		lim_process_mlm_start_req(session->mac_ctx, start_req);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void lim_send_csa_restart_resp(tpAniSirGlobal mac_ctx,
+					     tpPESession session)
+{
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+
+	msg.type = eWNI_SME_CSA_RESTART_RSP;
+	msg.bodyptr = NULL;
+	msg.bodyval = session->smeSessionId;
+
+	status = scheduler_post_msg(QDF_MODULE_ID_SME, &msg);
+	if (QDF_IS_STATUS_ERROR(status))
+		sme_err("Failed to post eWNI_SME_CSA_RESTART_RSP");
+}
+
+QDF_STATUS lim_ap_mlme_vdev_update_beacon(struct vdev_mlme_obj *vdev_mlme,
+					  enum beacon_update_op op,
+					  uint16_t data_len, void *data)
+{
+	tpPESession session;
+
+	if (!data) {
+		pe_err("event_data is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	session = (tpPESession)data;
+	if (LIM_IS_NDI_ROLE(session))
+		return QDF_STATUS_SUCCESS;
+
+	if (op == BEACON_INIT)
+		lim_send_beacon_ind(session->mac_ctx, session, REASON_DEFAULT);
+	else if (op == BEACON_CSA)
+		lim_send_csa_restart_resp(session->mac_ctx, session);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS lim_ap_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
+				    uint16_t data_len, void *data)
+{
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+	tpPESession session = (tpPESession)data;
+
+	if (!session) {
+		pe_err("session is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	if (LIM_IS_NDI_ROLE(session))
+		return QDF_STATUS_SUCCESS;
+
+
+	msg.type = SIR_HAL_SEND_AP_VDEV_UP;
+	msg.bodyval = session->smeSessionId;
+
+	status = scheduler_post_msg(QDF_MODULE_ID_WMA, &msg);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGE("Failed to post SIR_HAL_SEND_AP_VDEV_UP");
+
+	return status;
+}
+
+QDF_STATUS lim_ap_mlme_vdev_disconnect_peers(struct vdev_mlme_obj *vdev_mlme,
+					     uint16_t data_len, void *data)
+{
+	tpPESession session = (tpPESession)data;
+
+	if (!data) {
+		pe_err("data is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (LIM_IS_IBSS_ROLE(session))
+		lim_ibss_delete_all_peers(session->mac_ctx, session);
+	else
+		lim_delete_all_peers(session);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS lim_ap_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
+				      uint16_t data_len, void *data)
+{
+	tpPESession session = (tpPESession)data;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!data) {
+		pe_err("data is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (LIM_IS_IBSS_ROLE(session) &&
+	    session->mac_ctx->lim.gLimIbssCoalescingHappened)
+		ibss_bss_delete(session->mac_ctx, session);
+	else
+		status =  lim_send_vdev_stop(session);
+
+	return status;
+}
+
+QDF_STATUS lim_ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
+					 uint16_t data_len, void *data)
+{
+	tpPESession session = (tpPESession)data;
+
+	if (!data) {
+		pe_err("data is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (ap_mlme_is_hidden_ssid_restart_in_progress(vdev_mlme->vdev))
+		lim_send_vdev_restart(session->mac_ctx, session,
+				      session->smeSessionId);
+	else
+		lim_set_channel(session->mac_ctx, session->currentOperChannel,
+				session->ch_center_freq_seg0,
+				session->ch_center_freq_seg1,
+				session->ch_width, session->maxTxPower,
+				session->peSessionId, session->cac_duration_ms,
+				session->dfs_regdomain);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS lim_ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme,
+					     uint16_t data_len, void *data)
+{
+	tpAniSirGlobal mac_ctx;
+
+	/* store mac ctx in vdev_mlme legacy_vdev_ptr?*/
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac_ctx) {
+		pe_err("mac_ctx is NULL");
+		if (data)
+			qdf_mem_free(data);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	lim_process_mlm_start_cnf(mac_ctx, data);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void lim_send_start_bss_confirm(tpAniSirGlobal mac_ctx,
+				tLimMlmStartCnf *start_cnf)
+{
+	if (start_cnf->resultCode == eSIR_SME_SUCCESS) {
+		lim_post_sme_message(mac_ctx, LIM_MLM_START_CNF,
+				     (uint32_t *)start_cnf);
+	} else {
+		tpPESession session;
+
+		session = pe_find_session_by_session_id(mac_ctx,
+							start_cnf->sessionId);
+		if (!session) {
+			pe_err("session is NULL");
+			return;
+		}
+		mlme_set_vdev_start_failed(session->vdev, true);
+		wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					      WLAN_VDEV_SM_EV_START_REQ_FAIL,
+					      sizeof(*start_cnf), start_cnf);
+	}
+}
+
+#else
+
+void lim_send_start_bss_confirm(tpAniSirGlobal mac_ctx,
+				tLimMlmStartCnf *start_cnf)
+{
+	lim_post_sme_message(mac_ctx, LIM_MLM_START_CNF,
+			     (uint32_t *)start_cnf);
+}
+
+void lim_send_beacon(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+	lim_send_beacon_ind(mac_ctx, session, REASON_DEFAULT);
+}
+
+void lim_ndi_mlme_vdev_up_transition(tpPESession session)
+{
+}
+#endif
diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h
new file mode 100644
index 0000000..bb31423
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_utils.h
@@ -0,0 +1,1656 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file lim_utils.h contains the utility definitions
+ * LIM uses.
+ * Author:        Chandra Modumudi
+ * Date:          02/13/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_UTILS_H
+#define __LIM_UTILS_H
+
+#include "sir_api.h"
+#include "sir_debug.h"
+#include "cfg_api.h"
+
+#include "lim_types.h"
+#include "lim_scan_result_utils.h"
+#include "lim_timer_utils.h"
+#include "lim_trace.h"
+#include "include/wlan_vdev_mlme.h"
+#include "wlan_mlme_vdev_mgr_interface.h"
+
+typedef enum {
+	ONE_BYTE = 1,
+	TWO_BYTE = 2
+} eSizeOfLenField;
+
+#define LIM_STA_ID_MASK                        0x00FF
+#define LIM_AID_MASK                              0xC000
+#define LIM_SPECTRUM_MANAGEMENT_BIT_MASK          0x0100
+#define LIM_RRM_BIT_MASK                          0x1000
+#define LIM_SHORT_PREAMBLE_BIT_MASK               0x0020
+#define LIM_IMMEDIATE_BLOCK_ACK_MASK              0x8000
+#define LIM_MAX_REASSOC_RETRY_LIMIT            2
+
+/* classifier ID is coded as 0-3: tsid, 4-5:direction */
+#define LIM_MAKE_CLSID(tsid, dir) (((tsid) & 0x0F) | (((dir) & 0x03) << 4))
+
+#define VHT_MCS_3x3_MASK    0x30
+#define VHT_MCS_2x2_MASK    0x0C
+
+#define CENTER_FREQ_DIFF_160MHz 8
+#define CENTER_FREQ_DIFF_80P80MHz 16
+
+#define CH_TO_CNTR_FREQ_DIFF_160MHz 14
+#define CH_TO_CNTR_FREQ_DIFF_80MHz 6
+
+#define IS_VHT_NSS_1x1(__mcs_map)	((__mcs_map & 0xFFFC) == 0xFFFC)
+
+#define MGMT_RX_PACKETS_THRESHOLD 200
+
+/* 11B AP detection bit position */
+#define OBSS_DETECTION_11B_AP_BIT_MASK       0x0001
+/* 11B STA detection bit position */
+#define OBSS_DETECTION_11B_STA_BIT_MASK      0x0002
+/* 11G AP detection bit position */
+#define OBSS_DETECTION_11G_AP_BIT_MASK       0x0004
+/* 11A AP detection bit position */
+#define OBSS_DETECTION_11A_BIT_MASK          0x0008
+/* HT legacy detection bit position */
+#define OBSS_DETECTION_HT_LEGACY_BIT_MASK    0x0010
+/* HT mixed detection bit position */
+#define OBSS_DETECTION_HT_MIXED_BIT_MASK     0x0020
+/* HT 20mhz detection bit position */
+#define OBSS_DETECTION_HT_20MHZ_BIT_MASK     0x0040
+
+/**
+ * OBSS detection period in ms, used by firmware to decide
+ * absent detection and also gap between same detection ind.
+ */
+#define OBSS_DETECTION_PERIOD_MS             4000
+
+/* To check if 11B AP detection bit set */
+#define OBSS_DETECTION_IS_11B_AP(_m) ((_m) & OBSS_DETECTION_11B_AP_BIT_MASK)
+/* To check if 11B STA detection bit set */
+#define OBSS_DETECTION_IS_11B_STA(_m) ((_m) & OBSS_DETECTION_11B_STA_BIT_MASK)
+/* To check if 11G AP detection bit set */
+#define OBSS_DETECTION_IS_11G_AP(_m) ((_m) & OBSS_DETECTION_11G_AP_BIT_MASK)
+/* To check if 11A AP detection bit set */
+#define OBSS_DETECTION_IS_11A(_m) ((_m) & OBSS_DETECTION_11A_BIT_MASK)
+/* To check if HT legacy detection bit set */
+#define OBSS_DETECTION_IS_HT_LEGACY(_m) \
+	((_m) & OBSS_DETECTION_HT_LEGACY_BIT_MASK)
+/* To check if HT mixed detection bit set */
+#define OBSS_DETECTION_IS_HT_MIXED(_m) ((_m) & OBSS_DETECTION_HT_MIXED_BIT_MASK)
+/* To check if HT 20mhz detection bit set */
+#define OBSS_DETECTION_IS_HT_20MHZ(_m) ((_m) & OBSS_DETECTION_HT_20MHZ_BIT_MASK)
+
+#ifdef WLAN_FEATURE_11W
+typedef union uPmfSaQueryTimerId {
+	struct {
+		uint8_t sessionId;
+		uint16_t peerIdx;
+	} fields;
+	uint32_t value;
+} tPmfSaQueryTimerId, *tpPmfSaQueryTimerId;
+#endif
+
+typedef struct last_processed_frame {
+	tSirMacAddr sa;
+	uint16_t seq_num;
+} last_processed_msg;
+
+/* LIM utility functions */
+bool lim_is_valid_frame(last_processed_msg *last_processed_frm,
+		uint8_t *pRxPacketInfo);
+void lim_update_last_processed_frame(last_processed_msg *last_processed_frm,
+		uint8_t *pRxPacketInfo);
+void limGetBssidFromPkt(tpAniSirGlobal, uint8_t *, uint8_t *, uint32_t *);
+char *lim_dot11_reason_str(uint16_t reasonCode);
+char *lim_mlm_state_str(tLimMlmStates state);
+char *lim_sme_state_str(tLimSmeStates state);
+char *lim_msg_str(uint32_t msgType);
+char *lim_result_code_str(tSirResultCodes resultCode);
+char *lim_dot11_mode_str(tpAniSirGlobal pMac, uint8_t dot11Mode);
+void lim_print_mlm_state(tpAniSirGlobal pMac, uint16_t logLevel,
+		tLimMlmStates state);
+void lim_print_sme_state(tpAniSirGlobal pMac, uint16_t logLevel,
+		tLimSmeStates state);
+void lim_print_msg_name(tpAniSirGlobal pMac, uint16_t logLevel, uint32_t msgType);
+
+extern QDF_STATUS lim_send_set_max_tx_power_req(tpAniSirGlobal pMac,
+		int8_t txPower,
+		tpPESession pSessionEntry);
+extern uint8_t lim_get_max_tx_power(int8_t regMax, int8_t apTxPower,
+		uint8_t iniTxPower);
+uint8_t lim_is_addr_bc(tSirMacAddr);
+uint8_t lim_is_group_addr(tSirMacAddr);
+
+/* AID pool management functions */
+void lim_init_peer_idxpool(tpAniSirGlobal, tpPESession);
+uint16_t lim_assign_peer_idx(tpAniSirGlobal, tpPESession);
+
+void lim_enable_overlap11g_protection(tpAniSirGlobal pMac,
+		tpUpdateBeaconParams pBeaconParams,
+		tpSirMacMgmtHdr pMh,
+		tpPESession psessionEntry);
+void lim_update_overlap_sta_param(tpAniSirGlobal pMac, tSirMacAddr bssId,
+		tpLimProtStaParams pStaParams);
+void lim_update_short_preamble(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+		tpUpdateBeaconParams pBeaconParams,
+		tpPESession psessionEntry);
+void lim_update_short_slot_time(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+		tpUpdateBeaconParams pBeaconParams,
+		tpPESession psessionEntry);
+
+/*
+ * lim_send_sme_mgmt_frame_ind() - Function to send mgmt frame ind to HDD
+ * @mac_ctx : Pointer to Global MAC structure
+ * @frame_type : Type of mgmt frame
+ * @frame : Frame pointer
+ * @frame_len : Length og mgmt frame
+ * @session_id : session id
+ * @psession_entry : PE Session Entry
+ * @rx_channel : Channel of where packet is received
+ * @rx_rssi : rssi value
+ *
+ * Indicate the Mgmt Frame received to SME to HDD callback
+ * handle Probe_req/Action frame currently
+ *
+ * Return: None
+*/
+void lim_send_sme_mgmt_frame_ind(tpAniSirGlobal mac_ctx, uint8_t frame_type,
+				 uint8_t *frame, uint32_t frame_len,
+				 uint16_t session_id, uint32_t rx_channel,
+				 tpPESession psession_entry, int8_t rx_rssi);
+
+/*
+ * lim_convert_active_channel_to_passive_channel() - Timer callback function
+ * @mac_ctx : Pointer to Global MAC structure
+ *
+ * It check active DFS channels and convert them to passive channels
+ * if there was no beacon/proberesp for MAX_TIME_TO_BE_ACTIVE_CHANNEL time
+ *
+ * Return: None
+*/
+void lim_convert_active_channel_to_passive_channel(tpAniSirGlobal mac_ctx);
+
+/*
+ * lim_deactivate_timers() - Function to deactivate lim timers
+ * @mac_ctx: Pointer to global mac structure
+ *
+ *	This function is used to deactivate lim timers
+ *
+ * Return: None
+ */
+void lim_deactivate_timers(tpAniSirGlobal mac_ctx);
+
+/*
+ * The below 'product' check tobe removed if 'Association' is
+ * allowed in IBSS.
+ */
+void lim_release_peer_idx(tpAniSirGlobal, uint16_t, tpPESession);
+
+void lim_decide_ap_protection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+		tpUpdateBeaconParams pBeaconParams, tpPESession);
+void lim_decide_ap_protection_on_delete(tpAniSirGlobal pMac,
+		tpDphHashNode pStaDs,
+		tpUpdateBeaconParams pBeaconParams,
+		tpPESession psessionEntry);
+
+extern QDF_STATUS lim_update_11a_protection(tpAniSirGlobal pMac,
+		uint8_t enable,
+		uint8_t overlap,
+		tpUpdateBeaconParams pBeaconParams,
+		tpPESession);
+extern QDF_STATUS lim_enable11g_protection(tpAniSirGlobal pMac,
+		uint8_t enable,
+		uint8_t overlap,
+		tpUpdateBeaconParams pBeaconParams,
+		tpPESession psessionEntry);
+extern QDF_STATUS lim_enable_ht_protection_from11g(tpAniSirGlobal pMac,
+		uint8_t enable,
+		uint8_t overlap,
+		tpUpdateBeaconParams
+		pBeaconParams,
+		tpPESession psessionEntry);
+extern QDF_STATUS lim_enable_ht20_protection(tpAniSirGlobal pMac,
+		uint8_t enable, uint8_t overlap,
+		tpUpdateBeaconParams pBeaconParams,
+		tpPESession sessionEntry);
+extern QDF_STATUS lim_enable_ht_non_gf_protection(tpAniSirGlobal pMac,
+		uint8_t enable, uint8_t overlap,
+		tpUpdateBeaconParams
+		pBeaconParams, tpPESession);
+extern QDF_STATUS lim_enable_ht_rifs_protection(tpAniSirGlobal pMac,
+		uint8_t enable, uint8_t overlap,
+		tpUpdateBeaconParams
+		pBeaconParams,
+		tpPESession psessionEntry);
+extern QDF_STATUS lim_enable_ht_lsig_txop_protection(tpAniSirGlobal pMac,
+		uint8_t enable,
+		uint8_t overlap,
+		tpUpdateBeaconParams
+		pBeaconParams, tpPESession);
+extern QDF_STATUS lim_enable_short_preamble(tpAniSirGlobal pMac,
+		uint8_t enable,
+		tpUpdateBeaconParams pBeaconParams,
+		tpPESession psessionEntry);
+extern QDF_STATUS lim_enable_ht_obss_protection(tpAniSirGlobal pMac,
+		uint8_t enable, uint8_t overlap,
+		tpUpdateBeaconParams
+		pBeaconParams, tpPESession);
+void lim_decide_sta_protection(tpAniSirGlobal pMac,
+		tpSchBeaconStruct pBeaconStruct,
+		tpUpdateBeaconParams pBeaconParams,
+		tpPESession psessionEntry);
+void lim_decide_sta_protection_on_assoc(tpAniSirGlobal pMac,
+		tpSchBeaconStruct pBeaconStruct,
+		tpPESession psessionEntry);
+void lim_update_sta_run_time_ht_switch_chnl_params(tpAniSirGlobal pMac,
+		tDot11fIEHTInfo *pHTInfo,
+		uint8_t bssIdx,
+		tpPESession psessionEntry);
+/* Print MAC address utility function */
+void lim_print_mac_addr(tpAniSirGlobal, tSirMacAddr, uint8_t);
+
+/* Deferred Message Queue read/write */
+uint8_t lim_write_deferred_msg_q(tpAniSirGlobal pMac,
+				 struct scheduler_msg *limMsg);
+struct scheduler_msg *lim_read_deferred_msg_q(tpAniSirGlobal pMac);
+void lim_handle_defer_msg_error(tpAniSirGlobal pMac,
+				struct scheduler_msg *pLimMsg);
+
+/* Deferred Message Queue Reset */
+void lim_reset_deferred_msg_q(tpAniSirGlobal pMac);
+
+QDF_STATUS lim_sys_process_mmh_msg_api(tpAniSirGlobal,
+					  struct scheduler_msg *, uint8_t);
+
+void lim_handle_update_olbc_cache(tpAniSirGlobal pMac);
+
+uint8_t lim_is_null_ssid(tSirMacSSid *pSsid);
+
+/* 11h Support */
+void lim_stop_tx_and_switch_channel(tpAniSirGlobal pMac, uint8_t sessionId);
+void lim_process_channel_switch_timeout(tpAniSirGlobal);
+QDF_STATUS lim_start_channel_switch(tpAniSirGlobal pMac,
+		tpPESession psessionEntry);
+void lim_update_channel_switch(tpAniSirGlobal, tpSirProbeRespBeacon,
+		tpPESession psessionEntry);
+void lim_process_quiet_timeout(tpAniSirGlobal);
+void lim_process_quiet_bss_timeout(tpAniSirGlobal);
+
+void lim_start_quiet_timer(tpAniSirGlobal pMac, uint8_t sessionId);
+void lim_switch_primary_channel(tpAniSirGlobal, uint8_t, tpPESession);
+void lim_switch_primary_secondary_channel(tpAniSirGlobal pMac,
+					tpPESession psessionEntry,
+					uint8_t newChannel,
+					uint8_t ch_center_freq_seg0,
+					uint8_t ch_center_freq_seg1,
+					enum phy_ch_width ch_width);
+void limUpdateStaRunTimeHTSwtichChnlParams(tpAniSirGlobal pMac,
+		tDot11fIEHTInfo *pRcvdHTInfo,
+		uint8_t bssIdx);
+void lim_update_sta_run_time_ht_capability(tpAniSirGlobal pMac,
+		tDot11fIEHTCaps *pHTCaps);
+void lim_update_sta_run_time_ht_info(struct mac_context *pMac,
+		tDot11fIEHTInfo *pRcvdHTInfo,
+		tpPESession psessionEntry);
+void lim_cancel_dot11h_channel_switch(tpAniSirGlobal pMac,
+		tpPESession psessionEntry);
+void lim_cancel_dot11h_quiet(tpAniSirGlobal pMac, tpPESession psessionEntry);
+bool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac,
+		uint8_t channel);
+void lim_frame_transmission_control(tpAniSirGlobal pMac, tLimQuietTxMode type,
+		tLimControlTx mode);
+QDF_STATUS lim_restore_pre_channel_switch_state(tpAniSirGlobal pMac,
+		tpPESession psessionEntry);
+QDF_STATUS lim_restore_pre_quiet_state(tpAniSirGlobal pMac,
+		tpPESession psessionEntry);
+
+void lim_prepare_for11h_channel_switch(tpAniSirGlobal pMac,
+		tpPESession psessionEntry);
+void lim_switch_channel_cback(tpAniSirGlobal pMac, QDF_STATUS status,
+		uint32_t *data, tpPESession psessionEntry);
+
+/**
+ * lim_get_session_by_macaddr() - api to find session based on MAC
+ * @mac_ctx: Pointer to global mac structure.
+ * @self_mac: MAC address.
+ *
+ * This function is used to get session for given MAC address.
+ *
+ * Return: session pointer if exists, NULL otherwise.
+ */
+struct csr_roam_session *lim_get_session_by_macaddr(tpAniSirGlobal mac_ctx,
+		tSirMacAddr self_mac);
+
+static inline enum band_info lim_get_rf_band(uint8_t channel)
+{
+	if ((channel >= SIR_11A_CHANNEL_BEGIN) &&
+			(channel <= SIR_11A_CHANNEL_END))
+		return BAND_5G;
+
+	if ((channel >= SIR_11B_CHANNEL_BEGIN) &&
+			(channel <= SIR_11B_CHANNEL_END))
+		return BAND_2G;
+
+	return BAND_UNKNOWN;
+}
+
+static inline QDF_STATUS
+lim_get_mgmt_staid(tpAniSirGlobal pMac, uint16_t *staid,
+		tpPESession psessionEntry)
+{
+	if (LIM_IS_AP_ROLE(psessionEntry))
+		*staid = 1;
+	else if (LIM_IS_STA_ROLE(psessionEntry))
+		*staid = 0;
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline uint8_t lim_is_system_in_set_mimops_state(tpAniSirGlobal pMac)
+{
+	if (pMac->lim.gLimMlmState == eLIM_MLM_WT_SET_MIMOPS_STATE)
+		return true;
+	return false;
+}
+
+static inline uint8_t
+is_entering_mimo_ps(tSirMacHTMIMOPowerSaveState curState,
+		tSirMacHTMIMOPowerSaveState newState)
+{
+	if (curState == eSIR_HT_MIMO_PS_NO_LIMIT &&
+			(newState == eSIR_HT_MIMO_PS_DYNAMIC
+			 || newState == eSIR_HT_MIMO_PS_STATIC))
+		return true;
+	return false;
+}
+
+static inline int lim_select_cb_mode(tDphHashNode *pStaDs,
+		tpPESession psessionEntry, uint8_t channel,
+		uint8_t chan_bw)
+{
+	if (pStaDs->mlmStaContext.vhtCapability && chan_bw) {
+		if (channel == 36 || channel == 52 || channel == 100 ||
+				channel == 116 || channel == 149) {
+			return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
+		} else if (channel == 40 || channel == 56 || channel == 104 ||
+				channel == 120 || channel == 153) {
+			return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
+		} else if (channel == 44 || channel == 60 || channel == 108 ||
+				channel == 124 || channel == 157) {
+			return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH - 1;
+		} else if (channel == 48 || channel == 64 || channel == 112 ||
+				channel == 128 || channel == 161) {
+			return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
+		} else if (channel == 165) {
+			return PHY_SINGLE_CHANNEL_CENTERED;
+		}
+	} else if (pStaDs->mlmStaContext.htCapability) {
+		if (channel == 40 || channel == 48 || channel == 56 ||
+			channel == 64 || channel == 104 || channel == 112 ||
+			channel == 120 || channel == 128 || channel == 136 ||
+			channel == 144 || channel == 153 || channel == 161) {
+			return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+		} else if (channel == 36 || channel == 44 || channel == 52 ||
+				channel == 60 || channel == 100 ||
+				channel == 108 || channel == 116 ||
+				channel == 124 || channel == 132 ||
+				channel == 140 || channel == 149 ||
+				channel == 157) {
+			return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+		} else if (channel == 165) {
+			return PHY_SINGLE_CHANNEL_CENTERED;
+		}
+	}
+	return PHY_SINGLE_CHANNEL_CENTERED;
+}
+
+/* ANI peer station count management and associated actions */
+void lim_util_count_sta_add(tpAniSirGlobal pMac, tpDphHashNode pSta,
+		tpPESession psessionEntry);
+void lim_util_count_sta_del(tpAniSirGlobal pMac, tpDphHashNode pSta,
+		tpPESession psessionEntry);
+
+uint8_t lim_get_ht_capability(tpAniSirGlobal, uint32_t, tpPESession);
+QDF_STATUS lim_tx_complete(void *context, qdf_nbuf_t buf, bool free);
+
+/**
+ * This function will be registered with HAL for callback when TSPEC inactivity
+ * timer fires.
+ */
+
+void lim_process_del_ts_ind(tpAniSirGlobal pMac, struct scheduler_msg *limMsg);
+QDF_STATUS lim_process_hal_ind_messages(tpAniSirGlobal pMac, uint32_t mesgId,
+		void *mesgParam);
+QDF_STATUS lim_validate_delts_req(tpAniSirGlobal pMac,
+		tpSirDeltsReq pDeltsReq,
+		tSirMacAddr peerMacAddr,
+		tpPESession psessionEntry);
+
+/* callback function registration to HAL for any indication. */
+void lim_register_hal_ind_call_back(tpAniSirGlobal pMac);
+void lim_pkt_free(tpAniSirGlobal pMac,
+		eFrameType frmType, uint8_t *pBD, void *body);
+
+void lim_get_b_dfrom_rx_packet(tpAniSirGlobal pMac, void *body, uint32_t **pBD);
+
+/**
+ * utils_power_xy() - calc result of base raised to power
+ * @base: Base value
+ * @power: Base raised to this Power value
+ *
+ * Given a base(X) and power(Y), this API will return
+ * the result of base raised to power - (X ^ Y)
+ *
+ * Return: Result of X^Y
+ *
+ */
+static inline uint32_t utils_power_xy(uint16_t base, uint16_t power)
+{
+	uint32_t result = 1, i;
+
+	for (i = 0; i < power; i++)
+		result *= base;
+
+	return result;
+}
+
+QDF_STATUS lim_post_sm_state_update(tpAniSirGlobal pMac,
+		uint16_t StaIdx,
+		tSirMacHTMIMOPowerSaveState MIMOPSState,
+		uint8_t *pPeerStaMac, uint8_t sessionId);
+
+void lim_delete_sta_context(tpAniSirGlobal pMac, struct scheduler_msg *limMsg);
+void lim_delete_dialogue_token_list(tpAniSirGlobal pMac);
+
+/**
+ * lim_add_channel_status_info() - store
+ * chan status info into Global MAC structure
+ * @p_mac: Pointer to Global MAC structure
+ * @channel_stat: Pointer to chan status info reported by firmware
+ * @channel_id: current channel id
+ *
+ * Return: None
+ */
+void lim_add_channel_status_info(tpAniSirGlobal p_mac,
+				 struct lim_channel_status *channel_stat,
+				 uint8_t channel_id);
+uint8_t lim_get_channel_from_beacon(tpAniSirGlobal pMac,
+		tpSchBeaconStruct pBeacon);
+tSirNwType lim_get_nw_type(tpAniSirGlobal pMac, uint8_t channelNum,
+		uint32_t type, tpSchBeaconStruct pBeacon);
+
+void lim_set_tspec_uapsd_mask_per_session(tpAniSirGlobal pMac,
+		tpPESession psessionEntry,
+		tSirMacTSInfo *pTsInfo, uint32_t action);
+
+void lim_handle_heart_beat_timeout_for_session(tpAniSirGlobal pMac,
+		tpPESession psessionEntry);
+
+void lim_process_add_sta_rsp(tpAniSirGlobal pMac,
+			     struct scheduler_msg *pMsgQ);
+
+void lim_update_beacon(tpAniSirGlobal pMac);
+
+void lim_process_ap_mlm_add_sta_rsp(tpAniSirGlobal pMac,
+				    struct scheduler_msg *limMsgQ,
+				    tpPESession psessionEntry);
+void lim_process_ap_mlm_del_bss_rsp(tpAniSirGlobal pMac,
+		struct scheduler_msg *limMsgQ,
+		tpPESession psessionEntry);
+
+void lim_process_ap_mlm_del_sta_rsp(tpAniSirGlobal pMac,
+		struct scheduler_msg *limMsgQ,
+		tpPESession psessionEntry);
+
+tpPESession lim_is_ibss_session_active(tpAniSirGlobal pMac);
+tpPESession lim_is_ap_session_active(tpAniSirGlobal pMac);
+void lim_handle_heart_beat_failure_timeout(tpAniSirGlobal pMac);
+
+#define limGetWscIEPtr(pMac, ie, ie_len) \
+	wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_WSC_OUI, \
+			SIR_MAC_WSC_OUI_SIZE, ie, ie_len)
+
+#define limGetP2pIEPtr(pMac, ie, ie_len) \
+	wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_P2P_OUI, \
+			SIR_MAC_P2P_OUI_SIZE, ie, ie_len)
+
+uint8_t lim_get_noa_attr_stream_in_mult_p2p_ies(tpAniSirGlobal pMac,
+		uint8_t *noaStream, uint8_t noaLen,
+		uint8_t overFlowLen);
+uint8_t lim_get_noa_attr_stream(tpAniSirGlobal pMac, uint8_t *pNoaStream,
+		tpPESession psessionEntry);
+
+uint8_t lim_build_p2p_ie(tpAniSirGlobal pMac, uint8_t *ie, uint8_t *data,
+		uint8_t ie_len);
+bool lim_is_noa_insert_reqd(tpAniSirGlobal pMac);
+bool lim_isconnected_on_dfs_channel(tpAniSirGlobal mac_ctx,
+		uint8_t currentChannel);
+uint8_t lim_get_current_operating_channel(tpAniSirGlobal pMac);
+uint32_t lim_get_max_rate_flags(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds);
+
+bool lim_check_vht_op_mode_change(tpAniSirGlobal pMac,
+		tpPESession psessionEntry,
+		uint8_t chanWidth, uint8_t staId,
+		uint8_t *peerMac);
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+bool lim_send_he_ie_update(tpAniSirGlobal mac_ctx, tpPESession pe_session);
+#endif
+bool lim_set_nss_change(tpAniSirGlobal pMac, tpPESession psessionEntry,
+		uint8_t rxNss, uint8_t staId, uint8_t *peerMac);
+bool lim_check_membership_user_position(tpAniSirGlobal pMac,
+		tpPESession psessionEntry,
+		uint32_t membership, uint32_t userPosition,
+		uint8_t staId);
+
+/**
+ * enum ack_status - Indicate TX status of ASSOC/AUTH
+ * @ACKED : Ack is received.
+ * @NOT_ACKED : No Ack received.
+ * @SENT_FAIL : Failure while sending.
+ *
+ * Indicate if driver is waiting for ACK status of assoc/auth or ACK received
+ * for ASSOC/AUTH OR NO ACK is received for the assoc/auth sent or assoc/auth
+ * sent failed.
+ */
+enum assoc_ack_status {
+	ACKED,
+	NOT_ACKED,
+	SENT_FAIL,
+};
+
+typedef enum {
+	WLAN_PE_DIAG_SCAN_REQ_EVENT = 0,
+	WLAN_PE_DIAG_SCAN_ABORT_IND_EVENT,
+	WLAN_PE_DIAG_SCAN_RSP_EVENT,
+	WLAN_PE_DIAG_JOIN_REQ_EVENT,
+	WLAN_PE_DIAG_JOIN_RSP_EVENT,
+	WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT,
+	WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT,
+	WLAN_PE_DIAG_REASSOC_REQ_EVENT,
+	WLAN_PE_DIAG_REASSOC_RSP_EVENT,
+	WLAN_PE_DIAG_AUTH_REQ_EVENT,
+	WLAN_PE_DIAG_AUTH_RSP_EVENT = 10,
+	WLAN_PE_DIAG_DISASSOC_REQ_EVENT,
+	WLAN_PE_DIAG_DISASSOC_RSP_EVENT,
+	WLAN_PE_DIAG_DISASSOC_IND_EVENT,
+	WLAN_PE_DIAG_DISASSOC_CNF_EVENT,
+	WLAN_PE_DIAG_DEAUTH_REQ_EVENT,
+	WLAN_PE_DIAG_DEAUTH_RSP_EVENT,
+	WLAN_PE_DIAG_DEAUTH_IND_EVENT,
+	WLAN_PE_DIAG_START_BSS_REQ_EVENT,
+	WLAN_PE_DIAG_START_BSS_RSP_EVENT,
+	WLAN_PE_DIAG_AUTH_IND_EVENT = 20,
+	WLAN_PE_DIAG_ASSOC_IND_EVENT,
+	WLAN_PE_DIAG_ASSOC_CNF_EVENT,
+	WLAN_PE_DIAG_REASSOC_IND_EVENT,
+	WLAN_PE_DIAG_SWITCH_CHL_IND_EVENT,
+	WLAN_PE_DIAG_SWITCH_CHL_RSP_EVENT,
+	WLAN_PE_DIAG_STOP_BSS_REQ_EVENT,
+	WLAN_PE_DIAG_STOP_BSS_RSP_EVENT,
+	WLAN_PE_DIAG_DEAUTH_CNF_EVENT,
+	WLAN_PE_DIAG_ADDTS_REQ_EVENT,
+	WLAN_PE_DIAG_ADDTS_RSP_EVENT = 30,
+	WLAN_PE_DIAG_DELTS_REQ_EVENT,
+	WLAN_PE_DIAG_DELTS_RSP_EVENT,
+	WLAN_PE_DIAG_DELTS_IND_EVENT,
+	WLAN_PE_DIAG_ENTER_BMPS_REQ_EVENT,
+	WLAN_PE_DIAG_ENTER_BMPS_RSP_EVENT,
+	WLAN_PE_DIAG_EXIT_BMPS_REQ_EVENT,
+	WLAN_PE_DIAG_EXIT_BMPS_RSP_EVENT,
+	WLAN_PE_DIAG_EXIT_BMPS_IND_EVENT,
+	WLAN_PE_DIAG_ENTER_IMPS_REQ_EVENT,
+	WLAN_PE_DIAG_ENTER_IMPS_RSP_EVENT = 40,
+	WLAN_PE_DIAG_EXIT_IMPS_REQ_EVENT,
+	WLAN_PE_DIAG_EXIT_IMPS_RSP_EVENT,
+	WLAN_PE_DIAG_ENTER_UAPSD_REQ_EVENT,
+	WLAN_PE_DIAG_ENTER_UAPSD_RSP_EVENT,
+	WLAN_PE_DIAG_EXIT_UAPSD_REQ_EVENT,
+	WLAN_PE_DIAG_EXIT_UAPSD_RSP_EVENT,
+	WLAN_PE_DIAG_WOWL_ADD_BCAST_PTRN_EVENT,
+	WLAN_PE_DIAG_WOWL_DEL_BCAST_PTRN_EVENT,
+	WLAN_PE_DIAG_ENTER_WOWL_REQ_EVENT,
+	WLAN_PE_DIAG_ENTER_WOWL_RSP_EVENT = 50,
+	WLAN_PE_DIAG_EXIT_WOWL_REQ_EVENT,
+	WLAN_PE_DIAG_EXIT_WOWL_RSP_EVENT,
+	WLAN_PE_DIAG_HAL_ADDBA_REQ_EVENT,
+	WLAN_PE_DIAG_HAL_ADDBA_RSP_EVENT,
+	WLAN_PE_DIAG_HAL_DELBA_IND_EVENT,
+	WLAN_PE_DIAG_HB_FAILURE_TIMEOUT,
+	WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT,
+	WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT,
+	WLAN_PE_DIAG_PREAUTH_DONE,
+	WLAN_PE_DIAG_REASSOCIATING = 60,
+	WLAN_PE_DIAG_CONNECTED,
+	WLAN_PE_DIAG_ASSOC_REQ_EVENT,
+	WLAN_PE_DIAG_AUTH_COMP_EVENT,
+	WLAN_PE_DIAG_ASSOC_COMP_EVENT,
+	WLAN_PE_DIAG_AUTH_START_EVENT,
+	WLAN_PE_DIAG_ASSOC_START_EVENT,
+	WLAN_PE_DIAG_REASSOC_START_EVENT,
+	WLAN_PE_DIAG_ROAM_AUTH_START_EVENT,
+	WLAN_PE_DIAG_ROAM_AUTH_COMP_EVENT,
+	WLAN_PE_DIAG_ROAM_ASSOC_START_EVENT = 70,
+	WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT,
+	WLAN_PE_DIAG_SCAN_COMPLETE_EVENT,
+	WLAN_PE_DIAG_SCAN_RESULT_FOUND_EVENT,
+	WLAN_PE_DIAG_ASSOC_TIMEOUT,
+	WLAN_PE_DIAG_AUTH_TIMEOUT,
+	WLAN_PE_DIAG_DEAUTH_FRAME_EVENT,
+	WLAN_PE_DIAG_DISASSOC_FRAME_EVENT,
+	WLAN_PE_DIAG_AUTH_ACK_EVENT,
+	WLAN_PE_DIAG_ASSOC_ACK_EVENT,
+	WLAN_PE_DIAG_AUTH_ALGO_NUM,
+} WLAN_PE_DIAG_EVENT_TYPE;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void lim_diag_event_report(tpAniSirGlobal pMac, uint16_t eventType,
+		tpPESession pSessionEntry, uint16_t status,
+		uint16_t reasonCode);
+/**
+ * lim_diag_mgmt_tx_event_report() - to log TX event to external application
+ * @mac_ctx: mac context
+ * @mgmt_hdr: 802.11 mgmt header of given frame
+ * @session: PE session for given frame
+ * @result_code: result code of to be populated in TX frame
+ * @reason_code: reason code if TX OTA status
+ *
+ * Anytime driver sends some mgmt frame down to firmware for OTA delivery,
+ * log mgmt frame through DIAG utility. Don't log frames which come too
+ * excessively.
+ *
+ * Return: void
+ */
+void lim_diag_mgmt_tx_event_report(tpAniSirGlobal mac_ctx, void *mgmt_hdr,
+		tpPESession session, uint16_t result_code,
+		uint16_t reason_code);
+/**
+ * lim_diag_mgmt_rx_event_report() - to log RX event to external application
+ * @mac_ctx: mac context
+ * @mgmt_hdr: 802.11 mgmt header of given frame
+ * @session: PE session for given frame
+ * @result_code: result code given in RX frame
+ * @reason_code: reason code for RX OTA status
+ *
+ * Anytime driver receives some mgmt frame from firmware OTA,
+ * log mgmt frame through DIAG utility. Don't log frames which come too
+ * excessively.
+ *
+ * Return: void
+ */
+void lim_diag_mgmt_rx_event_report(tpAniSirGlobal mac_ctx, void *mgmt_hdr,
+		tpPESession session, uint16_t result_code,
+		uint16_t reason_code);
+#else
+static inline void lim_diag_event_report(tpAniSirGlobal pMac, uint16_t
+		eventType, tpPESession pSessionEntry, uint16_t status,
+		uint16_t reasonCode) {}
+static inline
+void lim_diag_mgmt_tx_event_report(tpAniSirGlobal mac_ctx, void *mgmt_hdr,
+		tpPESession session, uint16_t result_code,
+		uint16_t reason_code) {}
+static inline
+void lim_diag_mgmt_rx_event_report(tpAniSirGlobal mac_ctx, void *mgmt_hdr,
+		tpPESession session, uint16_t result_code,
+		uint16_t reason_code) {}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+void pe_set_resume_channel(tpAniSirGlobal pMac, uint16_t channel,
+		ePhyChanBondState cbState);
+
+void lim_get_short_slot_from_phy_mode(tpAniSirGlobal pMac,
+		tpPESession psessionEntry,
+		uint32_t phyMode, uint8_t *pShortSlotEnable);
+
+void lim_clean_up_disassoc_deauth_req(tpAniSirGlobal pMac, uint8_t *staMac,
+		bool cleanRxPath);
+
+bool lim_check_disassoc_deauth_ack_pending(tpAniSirGlobal pMac,
+		uint8_t *staMac);
+
+#ifdef WLAN_FEATURE_11W
+void lim_pmf_sa_query_timer_handler(void *pMacGlobal, uint32_t param);
+void lim_pmf_comeback_timer_callback(void *context);
+void lim_set_protected_bit(tpAniSirGlobal pMac,
+	tpPESession psessionEntry,
+	tSirMacAddr peer, tpSirMacMgmtHdr pMacHdr);
+#else
+static inline void lim_set_protected_bit(tpAniSirGlobal pMac,
+	tpPESession psessionEntry,
+	tSirMacAddr peer, tpSirMacMgmtHdr pMacHdr) {}
+#endif /* WLAN_FEATURE_11W */
+
+void lim_set_ht_caps(tpAniSirGlobal p_mac,
+		tpPESession p_session_ntry,
+		uint8_t *p_ie_start,
+		uint32_t num_bytes);
+
+void lim_set_vht_caps(tpAniSirGlobal p_mac,
+		tpPESession p_session_entry,
+		uint8_t *p_ie_start,
+		uint32_t num_bytes);
+bool lim_validate_received_frame_a1_addr(tpAniSirGlobal mac_ctx,
+		tSirMacAddr a1, tpPESession session);
+void lim_set_stads_rtt_cap(tpDphHashNode sta_ds, struct s_ext_cap *ext_cap,
+			   tpAniSirGlobal mac_ctx);
+
+void lim_check_and_reset_protection_params(tpAniSirGlobal mac_ctx);
+
+QDF_STATUS lim_send_ext_cap_ie(tpAniSirGlobal mac_ctx, uint32_t session_id,
+			       tDot11fIEExtCap *extracted_extcap, bool merge);
+
+QDF_STATUS lim_send_ies_per_band(tpAniSirGlobal mac_ctx,
+				 tpPESession session, uint8_t vdev_id);
+
+QDF_STATUS lim_strip_extcap_ie(tpAniSirGlobal mac_ctx, uint8_t *addn_ie,
+			  uint16_t *addn_ielen, uint8_t *extracted_extcap);
+void lim_update_extcap_struct(tpAniSirGlobal mac_ctx, uint8_t *buf,
+			      tDot11fIEExtCap *ext_cap);
+QDF_STATUS lim_strip_extcap_update_struct(tpAniSirGlobal mac_ctx,
+		uint8_t *addn_ie, uint16_t *addn_ielen, tDot11fIEExtCap *dst);
+void lim_merge_extcap_struct(tDot11fIEExtCap *dst, tDot11fIEExtCap *src,
+		bool add);
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * lim_del_pmf_sa_query_timer() - This function deletes SA query timer
+ * @mac_ctx: pointer to mac context
+ * @pe_session: pointer to PE session
+ *
+ * This API is to delete the PMF SA query timer created for each associated STA
+ *
+ * Return: none
+ */
+void lim_del_pmf_sa_query_timer(tpAniSirGlobal mac_ctx, tpPESession pe_session);
+#else
+/**
+ * lim_del_pmf_sa_query_timer() - This function deletes SA query timer
+ * @mac_ctx: pointer to mac context
+ * @pe_session: pointer to PE session
+ *
+ * This API is to delete the PMF SA query timer created for each associated STA
+ *
+ * Return: none
+ */
+static inline void
+lim_del_pmf_sa_query_timer(tpAniSirGlobal mac_ctx, tpPESession pe_session)
+{
+}
+#endif
+
+/**
+ * lim_strip_op_class_update_struct - strip sup op class IE and populate
+ *				  the dot11f structure
+ * @mac_ctx: global MAC context
+ * @addn_ie: Additional IE buffer
+ * @addn_ielen: Length of additional IE
+ * @dst: Supp operating class IE structure to be updated
+ *
+ * This function is used to strip supp op class IE from IE buffer and
+ * update the passed structure.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_strip_supp_op_class_update_struct(tpAniSirGlobal mac_ctx,
+		uint8_t *addn_ie, uint16_t *addn_ielen,
+		tDot11fIESuppOperatingClasses *dst);
+
+uint8_t lim_get_80Mhz_center_channel(uint8_t primary_channel);
+void lim_update_obss_scanparams(tpPESession session,
+			tDot11fIEOBSSScanParameters *scan_params);
+void lim_init_obss_params(tpAniSirGlobal mac_ctx, tpPESession session);
+#ifdef WLAN_FEATURE_HOST_ROAM
+uint32_t lim_create_timers_host_roam(tpAniSirGlobal mac_ctx);
+/**
+ * lim_delete_timers_host_roam() - Delete timers used in host based roaming
+ * @mac_ctx: Global MAC context
+ *
+ * Delete reassoc and preauth timers
+ *
+ * Return: none
+ */
+void lim_delete_timers_host_roam(tpAniSirGlobal mac_ctx);
+/**
+ * lim_deactivate_timers_host_roam() - deactivate timers used in host based
+ * roaming
+ * @mac_ctx: Global MAC context
+ *
+ * Delete reassoc and preauth timers
+ *
+ * Return: none
+ */
+void lim_deactivate_timers_host_roam(tpAniSirGlobal mac_ctx);
+void lim_deactivate_and_change_timer_host_roam(tpAniSirGlobal mac_ctx,
+		uint32_t timer_id);
+#else
+static inline uint32_t lim_create_timers_host_roam(tpAniSirGlobal mac_ctx)
+{
+	return 0;
+}
+static inline void lim_delete_timers_host_roam(tpAniSirGlobal mac_ctx)
+{}
+static inline void lim_deactivate_timers_host_roam(tpAniSirGlobal mac_ctx) {}
+static inline void lim_deactivate_and_change_timer_host_roam(
+		tpAniSirGlobal mac_ctx, uint32_t timer_id)
+{}
+#endif
+
+bool lim_is_robust_mgmt_action_frame(uint8_t action_category);
+uint8_t lim_compute_ext_cap_ie_length(tDot11fIEExtCap *ext_cap);
+
+/**
+ * lim_p2p_action_cnf() - callback to indicate Tx completion
+ * @mac_ctx: pointer to mac structure
+ * @buf: buffer
+ * @tx_complete_success: indicates tx success/failure
+ * @params: tx completion params
+ *
+ * function will be invoked on receiving tx completion indication
+ *
+ * return: success: eHAL_STATUS_SUCCESS failure: eHAL_STATUS_FAILURE
+ */
+QDF_STATUS lim_p2p_action_cnf(void *mac_ctx, qdf_nbuf_t buf,
+			uint32_t tx_complete_success, void *params);
+void lim_update_caps_info_for_bss(tpAniSirGlobal mac_ctx,
+			uint16_t *caps, uint16_t bss_caps);
+void lim_send_set_dtim_period(tpAniSirGlobal mac_ctx, uint8_t dtim_period,
+			      tpPESession session);
+
+QDF_STATUS lim_strip_ie(tpAniSirGlobal mac_ctx,
+		uint8_t *addn_ie, uint16_t *addn_ielen,
+		uint8_t eid, eSizeOfLenField size_of_len_field,
+		uint8_t *oui, uint8_t out_len, uint8_t *extracted_ie,
+		uint32_t eid_max_len);
+
+#define MCSMAPMASK1x1 0x3
+#define MCSMAPMASK2x2 0xC
+
+#ifdef WLAN_FEATURE_11AX
+
+/**
+ * lim_intersect_ap_he_caps() - Intersect AP capability with self STA capability
+ * @session: pointer to PE session
+ * @add_bss: pointer to ADD BSS params
+ * @beacon: pointer to beacon
+ * @assoc_rsp: pointer to assoc response
+ *
+ * Return: None
+ */
+void lim_intersect_ap_he_caps(tpPESession session, tpAddBssParams add_bss,
+		tSchBeaconStruct *pBeaconStruct, tpSirAssocRsp assoc_rsp);
+
+/**
+ * lim_intersect_sta_he_caps() - Intersect STA capability with SAP capability
+ * @assoc_req: pointer to assoc request
+ * @session: pointer to PE session
+ * @sta_ds: pointer to STA dph hash table entry
+ *
+ * Return: None
+ */
+void lim_intersect_sta_he_caps(tpSirAssocReq assoc_req, tpPESession session,
+		tpDphHashNode sta_ds);
+
+/**
+ * lim_add_he_cap() - Copy HE capability into Add sta params
+ * @add_sta_params: pointer to add sta params
+ * @assoc_req: pointer to Assoc request
+ *
+ * Return: None
+ */
+void lim_add_he_cap(tpAddStaParams add_sta_params, tpSirAssocReq assoc_req);
+
+/**
+ * lim_add_self_he_cap() - Copy HE capability into add sta from PE session
+ * @add_sta_params: pointer to add sta params
+ * @session: pointer to PE Session
+ *
+ * Return: None
+ */
+void lim_add_self_he_cap(tpAddStaParams add_sta_params, tpPESession session);
+
+/**
+ * lim_add_bss_he_cap() - Copy HE capability into ADD BSS params
+ * @add_bss: pointer to add bss params
+ * @assoc_rsp: pointer to assoc response
+ *
+ * Return: None
+ */
+void lim_add_bss_he_cap(tpAddBssParams add_bss, tpSirAssocRsp assoc_rsp);
+
+/**
+ * lim_add_bss_he_cfg() - Set HE config to BSS params
+ * @add_bss: pointer to add bss params
+ * @session: Pointer to Session entry struct
+ *
+ * Return: None
+ */
+void lim_add_bss_he_cfg(tpAddBssParams add_bss, tpPESession session);
+
+/**
+ * lim_copy_bss_he_cap() - Copy HE capability into PE session from start bss
+ * @session: pointer to PE session
+ * @sme_start_bss_req: pointer to start BSS request
+ *
+ * Return: None
+ */
+void lim_copy_bss_he_cap(tpPESession session,
+		tpSirSmeStartBssReq sme_start_bss_req);
+
+/**
+ * lim_copy_join_req_he_cap() - Copy HE capability to PE session from Join req
+ * and update as per bandwidth supported
+ * @session: pointer to PE session
+ * @sme_join_req: pointer to SME join request
+ *
+ * Return: None
+ */
+void lim_copy_join_req_he_cap(tpPESession session,
+			tpSirSmeJoinReq sme_join_req);
+
+/**
+ * lim_log_he_op() - Print HE Operation
+ * @mac: pointer to MAC context
+ * @he_op: pointer to HE Operation
+ *
+ * Print HE operation stored as dot11f structure
+ *
+ * Return: None
+ */
+void lim_log_he_op(tpAniSirGlobal mac, tDot11fIEhe_op *he_ops);
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+/**
+ * lim_log_he_bss_color() - Print HE bss color
+ * @mac: pointer to MAC context
+ * @he_bss_color: pointer to HE bss color
+ *
+ * Print HE bss color IE
+ *
+ * Return: None
+ */
+void lim_log_he_bss_color(tpAniSirGlobal mac,
+			tDot11fIEbss_color_change *he_bss_color);
+#endif
+
+/**
+ * lim_log_he_cap() - Print HE capabilities
+ * @mac: pointer to MAC context
+ * @he_cap: pointer to HE Capability
+ *
+ * Received HE capabilities are converted into dot11f structure.
+ * This function will print all the HE capabilities as stored
+ * in the dot11f structure.
+ *
+ * Return: None
+ */
+void lim_log_he_cap(tpAniSirGlobal mac, tDot11fIEhe_cap *he_cap);
+
+/**
+ * lim_update_stads_he_caps() - Copy HE capability into STA DPH hash table entry
+ * @sta_ds: pointer to sta dph hash table entry
+ * @assoc_rsp: pointer to assoc response
+ * @session_entry: pointer to PE session
+ *
+ * Return: None
+ */
+void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
+			      tpPESession session_entry);
+
+/**
+ * lim_update_usr_he_cap() - Update HE capability based on userspace
+ * @mac_ctx: global mac context
+ * @session: PE session entry
+ *
+ * Parse the HE Capability IE and populate the fields to be
+ * sent to FW as part of add bss and update PE session.
+ */
+void lim_update_usr_he_cap(tpAniSirGlobal mac_ctx, tpPESession session);
+
+/**
+ * lim_decide_he_op() - Determine HE operation elements
+ * @mac_ctx: global mac context
+ * @he_ops: pointer to HE operation IE
+ * @session: PE session entry
+ *
+ * Parse the HE Operation IE and populate the fields to be
+ * sent to FW as part of add bss.
+ */
+void lim_decide_he_op(tpAniSirGlobal mac_ctx, tpAddBssParams add_bss,
+		tpPESession session);
+
+/**
+ * lim_update_sta_he_capable(): Update he_capable in add sta params
+ * @mac: pointer to MAC context
+ * @add_sta_params: pointer to add sta params
+ * @sta_ds: pointer to dph hash table entry
+ * @session_entry: pointer to PE session
+ *
+ * Return: None
+ */
+void lim_update_sta_he_capable(tpAniSirGlobal mac,
+	tpAddStaParams add_sta_params, tpDphHashNode sta_ds,
+	tpPESession session_entry);
+
+static inline bool lim_is_session_he_capable(tpPESession session)
+{
+	return session->he_capable;
+}
+
+/**
+ * lim_get_session_he_frag_cap(): Get session HE fragmentation cap
+ * @session: pointer to session
+ *
+ * Return: HE fragmentation value
+ */
+static inline uint8_t lim_get_session_he_frag_cap(tpPESession session)
+{
+	return session->he_config.fragmentation;
+}
+
+static inline bool lim_is_sta_he_capable(tpDphHashNode sta_ds)
+{
+	return sta_ds->mlmStaContext.he_capable;
+}
+
+/**
+ * lim_update_bss_he_capable(): Update he_capable in add BSS params
+ * @mac: pointer to MAC context
+ * @add_bss: pointer to add BSS params
+ *
+ * Return: None
+ */
+void lim_update_bss_he_capable(tpAniSirGlobal mac, tpAddBssParams add_bss);
+
+/**
+ * lim_update_stads_he_capable() - Update he_capable in sta ds context
+ * @sta_ds: pointer to sta ds
+ * @assoc_req: pointer to assoc request
+ *
+ * Return: None
+ */
+void lim_update_stads_he_capable(tpDphHashNode sta_ds, tpSirAssocReq assoc_req);
+
+/**
+ * lim_update_session_he_capable(): Update he_capable in PE session
+ * @mac: pointer to MAC context
+ * @session: pointer to PE session
+ *
+ * Return: None
+ */
+void lim_update_session_he_capable(tpAniSirGlobal mac, tpPESession session);
+
+/**
+ * lim_update_chan_he_capable(): Update he_capable in chan switch params
+ * @mac: pointer to MAC context
+ * @chan: pointer to channel switch params
+ *
+ * Return: None
+ */
+void lim_update_chan_he_capable(tpAniSirGlobal mac, tpSwitchChannelParams chan);
+
+/**
+ * lim_set_he_caps() - update HE caps to be sent to FW as part of scan IE
+ * @mac: pointer to MAC
+ * @session: pointer to PE session
+ * @ie_start: pointer to start of IE buffer
+ * @num_bytes: length of IE buffer
+ *
+ * Return: None
+ */
+void lim_set_he_caps(tpAniSirGlobal mac, tpPESession session,
+		     uint8_t *ie_start, uint32_t num_bytes);
+
+/**
+ * lim_send_he_caps_ie() - gets HE capability and send to firmware via wma
+ * @mac_ctx: global mac context
+ * @session: pe session. This can be NULL. In that case self cap will be sent
+ * @vdev_id: vdev for which IE is targeted
+ *
+ * This function gets HE capability and send to firmware via wma
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_send_he_caps_ie(tpAniSirGlobal mac_ctx, tpPESession session,
+			       uint8_t vdev_id);
+
+/**
+ * lim_populate_he_mcs_set - function to populate HE mcs rate set
+ * @mac_ctx: pointer to global mac structure
+ * @rates: pointer to supported rate set
+ * @peer_vht_caps: pointer to peer HE capabilities
+ * @session_entry: pe session entry
+ *
+ * Populates HE mcs rate set based on peer and self capabilities
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_populate_he_mcs_set(tpAniSirGlobal mac_ctx,
+		tpSirSupportedRates rates, tDot11fIEhe_cap *peer_he_caps,
+		tpPESession session_entry, uint8_t nss);
+
+#else
+static inline void lim_add_he_cap(tpAddStaParams add_sta_params,
+				  tpSirAssocReq assoc_req)
+{
+}
+
+static inline void lim_add_self_he_cap(tpAddStaParams add_sta_params,
+				       tpPESession session)
+{
+}
+
+static inline void lim_add_bss_he_cap(tpAddBssParams add_bss,
+				      tpSirAssocRsp assoc_rsp)
+{
+	return;
+}
+
+static inline void lim_add_bss_he_cfg(tpAddBssParams add_bss,
+					 tpPESession session)
+{
+}
+
+static inline void lim_intersect_ap_he_caps(tpPESession session,
+		tpAddBssParams add_bss,	tSchBeaconStruct *pBeaconStruct,
+		tpSirAssocRsp assoc_rsp)
+{
+	return;
+}
+
+static inline void lim_intersect_sta_he_caps(tpSirAssocReq assoc_req,
+		tpPESession session, tpDphHashNode sta_ds)
+{
+}
+
+static inline void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
+		tpPESession session_entry)
+{
+	return;
+}
+
+static inline void lim_update_usr_he_cap(tpAniSirGlobal mac_ctx,
+			tpPESession session)
+{
+}
+
+static inline void lim_decide_he_op(tpAniSirGlobal mac_ctx,
+			tpAddBssParams add_bss, tpPESession session)
+{
+}
+
+static inline void lim_copy_bss_he_cap(tpPESession session,
+				tpSirSmeStartBssReq sme_start_bss_req)
+{
+}
+
+static inline void lim_copy_join_req_he_cap(tpPESession session,
+			tpSirSmeJoinReq sme_join_req)
+{
+}
+
+static inline void lim_log_he_op(tpAniSirGlobal mac,
+	tDot11fIEhe_op *he_ops)
+{
+}
+
+static inline void lim_log_he_cap(tpAniSirGlobal mac,
+	tDot11fIEhe_cap *he_cap)
+{
+}
+
+static inline void lim_update_sta_he_capable(tpAniSirGlobal mac,
+			tpAddStaParams add_sta_params,
+			tpDphHashNode sta_ds, tpPESession session_entry)
+{
+}
+
+static inline bool lim_is_session_he_capable(tpPESession session)
+{
+	return false;
+}
+
+static inline uint8_t lim_get_session_he_frag_cap(tpPESession session)
+{
+	return 0;
+}
+
+static inline bool lim_is_sta_he_capable(tpDphHashNode sta_ds)
+{
+	return false;
+}
+
+static inline void lim_update_bss_he_capable(tpAniSirGlobal mac,
+			tpAddBssParams add_bss)
+{
+}
+
+static inline void lim_update_stads_he_capable(tpDphHashNode sta_ds,
+		tpSirAssocReq assoc_req)
+{
+}
+
+static inline void lim_update_session_he_capable(tpAniSirGlobal mac,
+			tpPESession session)
+{
+}
+
+static inline void lim_update_chan_he_capable(tpAniSirGlobal mac,
+		tpSwitchChannelParams chan)
+{
+}
+
+static inline void lim_set_he_caps(tpAniSirGlobal mac, tpPESession session,
+				   uint8_t *ie_start, uint32_t num_bytes)
+{
+}
+
+static inline QDF_STATUS lim_send_he_caps_ie(tpAniSirGlobal mac_ctx,
+					     tpPESession session,
+					     uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS lim_populate_he_mcs_set(tpAniSirGlobal mac_ctx,
+				tpSirSupportedRates rates,
+				tDot11fIEhe_cap *peer_he_caps,
+				tpPESession session_entry, uint8_t nss)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif
+
+/**
+ * lim_assoc_rej_add_to_rssi_based_reject_list() - Add BSSID to the rssi based
+ * rejection list
+ * @mac_ctx: mac ctx
+ * @rssi_assoc_rej: rssi assoc reject attribute
+ * @bssid : BSSID of the AP
+ * @rssi : RSSI of the assoc resp
+ *
+ * Add BSSID to the rssi based rejection list. Also if number
+ * of entries is greater than MAX_RSSI_AVOID_BSSID_LIST
+ * remove the entry with lowest time delta
+ *
+ * Return: void
+ */
+void lim_assoc_rej_add_to_rssi_based_reject_list(tpAniSirGlobal mac_ctx,
+	tDot11fTLVrssi_assoc_rej *rssi_assoc_rej,
+	tSirMacAddr bssid, int8_t rssi);
+
+/**
+ * lim_decrement_pending_mgmt_count: Decrement mgmt frame count
+ * @mac_ctx: Pointer to global MAC structure
+ *
+ * This function is used to decrement pe mgmt count once frame
+ * removed from queue
+ *
+ * Return: None
+ */
+void lim_decrement_pending_mgmt_count(tpAniSirGlobal mac_ctx);
+
+/**
+ * lim_check_if_vendor_oui_match() - Check if the given OUI match in IE buffer
+ * @mac_ctx: MAC context
+ * @ie: IE buffer
+ * @ie_len: length of @ie
+ *
+ * This API is used to check if given vendor OUI
+ * matches in given IE buffer
+ *
+ * Return: True, if mataches. False otherwise
+ */
+bool lim_check_if_vendor_oui_match(tpAniSirGlobal mac_ctx,
+					uint8_t *oui, uint8_t oui_len,
+			       uint8_t *ie, uint8_t ie_len);
+
+QDF_STATUS lim_util_get_type_subtype(void *pkt, uint8_t *type,
+					uint8_t *subtype);
+
+/**
+ * lim_get_min_session_txrate() - Get the minimum rate supported in the session
+ * @session: Pointer to PE session
+ *
+ * This API will find the minimum rate supported by the given PE session and
+ * return the enum rateid corresponding to the rate.
+ *
+ * Return: enum rateid
+ */
+enum rateid lim_get_min_session_txrate(tpPESession session);
+
+/**
+ * lim_send_dfs_chan_sw_ie_update() - updates the channel switch IE in beacon
+ * template
+ *
+ * @mac_ctx - pointer to global mac context
+ * @session - A pointer to pesession
+ * Return None
+ */
+void lim_send_dfs_chan_sw_ie_update(tpAniSirGlobal mac_ctx,
+				    tpPESession session);
+
+/**
+ * lim_process_ap_ecsa_timeout() -process ECSA timeout which decrement csa count
+ * in beacon and update beacon template in firmware
+ *
+ * @data - A pointer to pesession
+ * Return None
+ */
+void lim_process_ap_ecsa_timeout(void *session);
+
+/**
+ * lim_send_stop_bss_failure_resp() -send failure delete bss resp to sme
+ * @mac_ctx: mac ctx
+ * @session: session pointer
+ *
+ * Return None
+ */
+void lim_send_stop_bss_failure_resp(tpAniSirGlobal mac_ctx,
+				    tpPESession session);
+
+/**
+ * lim_delete_all_peers() -delete all connected peers
+ * @session: session pointer
+ *
+ * Return None
+ */
+void lim_delete_all_peers(tpPESession session);
+
+/**
+ * lim_send_vdev_stop() -send delete bss/stop vdev req
+ * @session: session pointer
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS lim_send_vdev_stop(tpPESession session);
+
+/**
+ * lim_send_vdev_stop() -send delete bss/stop vdev req for STA
+ * @session: session pointer
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS lim_sta_send_del_bss(tpPESession session);
+
+/**
+ * lim_send_start_bss_confirm() -send start bss confirm req
+ * @mac_ctx: pointer to global mac structure
+ * @start_cnf: start confirm structure pointer
+ *
+ * Return None
+ */
+void lim_send_start_bss_confirm(tpAniSirGlobal mac_ctx,
+				     tLimMlmStartCnf *start_cnf);
+
+/**
+ * lim_send_chan_switch_action_frame()- Send an action frame
+ * containing CSA IE or ECSA IE depending on the connected
+ * sta capability.
+ *
+ * @mac_ctx: pointer to global mac structure
+ * @new_channel: new channel to switch to.
+ * @ch_bandwidth: BW of channel to calculate op_class
+ * @session_entry: pe session
+ *
+ * Return: void
+ */
+void lim_send_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
+				       uint16_t new_channel,
+				       uint8_t ch_bandwidth,
+				       tpPESession session_entry);
+
+/**
+ * lim_process_obss_detection_ind() - Process obss detection indication
+ * @mac_ctx: Pointer to Global MAC structure.
+ * @obss_detection: obss detection info.
+ *
+ * Process obss detection indication and apply necessary protection for
+ * the given AP session.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_process_obss_detection_ind(tpAniSirGlobal mac_ctx,
+					  struct wmi_obss_detect_info
+					  *obss_detection);
+
+/**
+ * lim_obss_send_detection_cfg() - Send obss detection configuration to firmware
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session: Pointer to session
+ * @force: Force to send new configuration even if new cfg same as old
+ *
+ * Generate new cfg based on current protection status and send new cfg to
+ * firmware.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_obss_send_detection_cfg(tpAniSirGlobal mac_ctx,
+				       tpPESession session,
+				       bool force);
+
+/**
+ * lim_obss_generate_detection_config() - get new obss offload detection cfg
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session: Pointer to session
+ * @cfg: Obss detection cfg buffer pointer
+ *
+ * Generate new cfg based on current protection status.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS lim_obss_generate_detection_config(tpAniSirGlobal mac_ctx,
+					      tpPESession session,
+					      struct obss_detection_cfg *cfg);
+
+/**
+ * lim_enable_obss_detection_config() - Enable obss detection
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session: Pointer to session
+ *
+ * This function will enable legacy obss detection (by starting timer)
+ * or also offload based detection based on support.
+ *
+ * Return: None
+ */
+void lim_enable_obss_detection_config(tpAniSirGlobal mac_ctx,
+				      tpPESession session);
+
+#ifdef WLAN_SUPPORT_TWT
+void lim_set_peer_twt_cap(tpPESession session, struct s_ext_cap *ext_cap);
+#else
+static inline void lim_set_peer_twt_cap(tpPESession session,
+					struct s_ext_cap *ext_cap)
+{
+}
+#endif
+
+/**
+ * lim_rx_invalid_peer_process() - process rx invalid peer indication
+ * @mac_ctx: Pointer to Global MAC structure
+ * @lim_msg: Pointer to scheduler message
+ *
+ * This function will process the rx data invalid peer indication,
+ * if the vdev operation mode is SAP, then send the deauth mgmt frame
+ * to STA.
+ *
+ * Return: None
+ */
+void lim_rx_invalid_peer_process(tpAniSirGlobal mac_ctx,
+				 struct scheduler_msg *lim_msg);
+
+/**
+ * lim_send_beacon() - send beacon indication to firmware
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session: session pointer
+ *
+ * Return: None
+ */
+void lim_send_beacon(tpAniSirGlobal mac_ctx, tpPESession session);
+
+/**
+ * lim_ndi_mlme_vdev_up_transition() - Send event to transistion NDI VDEV to UP
+ * @session: session pointer
+ *
+ * Return: None
+ */
+void lim_ndi_mlme_vdev_up_transition(tpPESession session);
+
+#ifdef CONFIG_VDEV_SM
+/**
+ * lim_sta_mlme_vdev_stop_send() - send VDEV stop
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes vdev stop
+ *
+ * Return: SUCCESS on successful completion of vdev stop
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_sta_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
+				       uint16_t data_len, void *data);
+
+/**
+ * lim_ap_mlme_vdev_start_send() - Invokes VDEV start operation
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes VDEV start operation
+ *
+ * Return: SUCCESS on successful completion of start operation
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_ap_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
+				       uint16_t data_len, void *event);
+
+/**
+ * lim_sta_mlme_vdev_start_send() - Invokes VDEV start operation
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes VDEV start operation
+ *
+ * Return: SUCCESS on successful completion of start operation
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_sta_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
+					uint16_t data_len, void *data);
+
+/*
+ * lim_ap_mlme_vdev_update_beacon() - Updates beacon
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @op: beacon update type
+ * @data_len: data size
+ * @data: event data
+ *
+ * API updates/allocates/frees the beacon
+ *
+ * Return: SUCCESS on successful update of beacon
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_ap_mlme_vdev_update_beacon(struct vdev_mlme_obj *vdev_mlme,
+					  enum beacon_update_op op,
+					  uint16_t data_len, void *data);
+
+/**
+ * lim_ap_mlme_vdev_up_send() - VDEV up operation
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes VDEV up operations
+ *
+ * Return: SUCCESS on successful completion of up operation
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_ap_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
+				    uint16_t data_len, void *data);
+
+/**
+ * lim_ap_mlme_vdev_disconnect_peers - Disconnect peers
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API trigger stations disconnection connected with AP
+ *
+ * Return: SUCCESS on successful invocation of station disconnection
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_ap_mlme_vdev_disconnect_peers(struct vdev_mlme_obj *vdev_mlme,
+					     uint16_t data_len, void *data);
+
+/**
+ * lim_ap_mlme_vdev_stop_send - Invokes VDEV stop operation
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes VDEV stop operation
+ *
+ * Return: SUCCESS on successful completion of stop operation
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_ap_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
+				      uint16_t data_len, void *data);
+
+/**
+ * lim_ap_mlme_vdev_restart_send - Invokes VDEV restart operation
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes VDEV restart operation
+ *
+ * Return: SUCCESS on successful completion of restart operation
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
+					 uint16_t data_len, void *data);
+
+/**
+ * lim_ap_mlme_vdev_start_req_failed - handle vdev start req failure
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes on START fail response
+ *
+ * Return: SUCCESS on successful invocation of callback
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme,
+					     uint16_t data_len, void *data);
+
+#endif
+
+#endif /* __LIM_UTILS_H */
diff --git a/core/mac/src/pe/nan/nan_datapath.c b/core/mac/src/pe/nan/nan_datapath.c
new file mode 100644
index 0000000..ab38d14
--- /dev/null
+++ b/core/mac/src/pe/nan/nan_datapath.c
@@ -0,0 +1,532 @@
+/*
+ * Copyright (c) 2016-2018 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: nan_datapath.c
+ *
+ * MAC NAN Data path API implementation
+ */
+
+#include "lim_utils.h"
+#include "lim_api.h"
+#include "lim_assoc_utils.h"
+#include "nan_datapath.h"
+#include "lim_types.h"
+#include "lim_send_messages.h"
+#include "wma_nan_datapath.h"
+#include "os_if_nan.h"
+#include "nan_public_structs.h"
+#include "nan_ucfg_api.h"
+
+/**
+ * lim_add_ndi_peer() - Function to add ndi peer
+ * @mac_ctx: handle to mac structure
+ * @vdev_id: vdev id on which peer is added
+ * @peer_mac_addr: peer to be added
+ *
+ * Return: QDF_STATUS_SUCCESS on success; error number otherwise
+ */
+static QDF_STATUS lim_add_ndi_peer(tpAniSirGlobal mac_ctx,
+	uint32_t vdev_id, struct qdf_mac_addr peer_mac_addr)
+{
+	tpPESession session;
+	tpDphHashNode sta_ds;
+	uint16_t assoc_id, peer_idx;
+	QDF_STATUS status;
+	uint8_t zero_mac_addr[QDF_MAC_ADDR_SIZE] = { 0, 0, 0, 0, 0, 0 };
+
+	if (!qdf_mem_cmp(&zero_mac_addr, &peer_mac_addr.bytes[0],
+			QDF_MAC_ADDR_SIZE)) {
+		pe_err("Failing to add peer with all zero mac addr");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	session = pe_find_session_by_sme_session_id(mac_ctx,
+						vdev_id);
+	if (session == NULL) {
+		/* couldn't find session */
+		pe_err("Session not found for vdev_id: %d", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sta_ds = dph_lookup_hash_entry(mac_ctx,
+				peer_mac_addr.bytes,
+				&assoc_id, &session->dph.dphHashTable);
+	/* peer exists, don't do anything */
+	if (sta_ds != NULL) {
+		pe_err("NDI Peer already exists!!");
+		return QDF_STATUS_SUCCESS;
+	}
+	pe_info("Need to create NDI Peer :" MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(peer_mac_addr.bytes));
+
+	peer_idx = lim_assign_peer_idx(mac_ctx, session);
+	if (!peer_idx) {
+		pe_err("Invalid peer_idx: %d", peer_idx);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	sta_ds = dph_add_hash_entry(mac_ctx, peer_mac_addr.bytes, peer_idx,
+			&session->dph.dphHashTable);
+	if (sta_ds == NULL) {
+		pe_err("Couldn't add dph entry");
+		/* couldn't add dph entry */
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* wma decides NDI mode from wma->inferface struct */
+	sta_ds->staType = STA_ENTRY_NDI_PEER;
+	status = lim_add_sta(mac_ctx, sta_ds, false, session);
+	if (QDF_STATUS_SUCCESS != status) {
+		/* couldn't add peer */
+		pe_err("limAddSta failed status: %d",
+			status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS lim_add_ndi_peer_converged(uint32_t vdev_id,
+				struct qdf_mac_addr peer_mac_addr)
+{
+	tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac_ctx)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	return lim_add_ndi_peer(mac_ctx, vdev_id, peer_mac_addr);
+}
+
+/**
+ * lim_ndp_delete_peer_by_addr() - Delete NAN data peer, given addr and vdev_id
+ * @mac_ctx: handle to mac context
+ * @vdev_id: vdev_id on which peer was added
+ * @peer_ndi_mac_addr: mac addr of peer
+ * This function deletes a peer if there was NDP_Confirm with REJECT
+ *
+ * Return: None
+ */
+static void lim_ndp_delete_peer_by_addr(tpAniSirGlobal mac_ctx, uint8_t vdev_id,
+					struct qdf_mac_addr peer_ndi_mac_addr)
+{
+	tpPESession session;
+	tpDphHashNode sta_ds;
+	uint16_t peer_idx;
+	uint8_t zero_mac_addr[QDF_MAC_ADDR_SIZE] = { 0, 0, 0, 0, 0, 0 };
+
+	if (!qdf_mem_cmp(&zero_mac_addr, &peer_ndi_mac_addr.bytes[0],
+			QDF_MAC_ADDR_SIZE)) {
+		pe_err("Failing to delete the peer with all zero mac addr");
+		return;
+	}
+
+	pe_info("deleting peer: "MAC_ADDRESS_STR" confirm rejected",
+		MAC_ADDR_ARRAY(peer_ndi_mac_addr.bytes));
+
+	session = pe_find_session_by_sme_session_id(mac_ctx, vdev_id);
+	if (!session || (session->bssType != eSIR_NDI_MODE)) {
+		pe_err("PE session is NULL or non-NDI for sme session %d",
+			vdev_id);
+		return;
+	}
+
+	sta_ds = dph_lookup_hash_entry(mac_ctx, peer_ndi_mac_addr.bytes,
+				    &peer_idx, &session->dph.dphHashTable);
+	if (!sta_ds) {
+		pe_err("Unknown NDI Peer");
+		return;
+	}
+	if (sta_ds->staType != STA_ENTRY_NDI_PEER) {
+		pe_err("Non-NDI Peer ignored");
+		return;
+	}
+	/*
+	 * Call lim_del_sta() with response required set true. Hence
+	 * DphHashEntry will be deleted after receiving that response.
+	 */
+
+	lim_del_sta(mac_ctx, sta_ds, true, session);
+}
+
+void lim_ndp_delete_peers_by_addr_converged(uint8_t vdev_id,
+					struct qdf_mac_addr peer_ndi_mac_addr)
+{
+	tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac_ctx)
+		return;
+
+	lim_ndp_delete_peer_by_addr(mac_ctx, vdev_id, peer_ndi_mac_addr);
+}
+
+/**
+ * lim_ndp_delete_peers() - Delete NAN data peers
+ * @mac_ctx: handle to mac context
+ * @ndp_map: NDP instance/peer map
+ * @num_peers: number of peers entries in peer_map
+ * This function deletes a peer if there are no active NDPs left with that peer
+ *
+ * Return: None
+ */
+static void lim_ndp_delete_peers(tpAniSirGlobal mac_ctx,
+				struct peer_ndp_map *ndp_map, uint8_t num_peers)
+{
+	tpDphHashNode sta_ds = NULL;
+	uint16_t deleted_num = 0;
+	int i, j;
+	tpPESession session;
+	struct qdf_mac_addr *deleted_peers;
+	uint16_t peer_idx;
+	bool found;
+
+	deleted_peers = qdf_mem_malloc(num_peers * sizeof(*deleted_peers));
+	if (!deleted_peers)
+		return;
+
+	for (i = 0; i < num_peers; i++) {
+		pe_info("ndp_map[%d]: MAC: " MAC_ADDRESS_STR " num_active %d",
+			i,
+			MAC_ADDR_ARRAY(ndp_map[i].peer_ndi_mac_addr.bytes),
+			ndp_map[i].num_active_ndp_sessions);
+
+		/* Do not delete a peer with active NDPs */
+		if (ndp_map[i].num_active_ndp_sessions > 0)
+			continue;
+
+		session = pe_find_session_by_sme_session_id(mac_ctx,
+						ndp_map[i].vdev_id);
+		if (!session || (session->bssType != eSIR_NDI_MODE)) {
+			pe_err("PE session is NULL or non-NDI for sme session %d",
+				ndp_map[i].vdev_id);
+			continue;
+		}
+
+		/* Check if this peer is already in the deleted list */
+		found = false;
+		for (j = 0; j < deleted_num && !found; j++) {
+			if (!qdf_mem_cmp(
+				&deleted_peers[j].bytes,
+				&ndp_map[i].peer_ndi_mac_addr.bytes,
+				QDF_MAC_ADDR_SIZE)) {
+				found = true;
+				break;
+			}
+		}
+		if (found)
+			continue;
+
+		sta_ds = dph_lookup_hash_entry(mac_ctx,
+				ndp_map[i].peer_ndi_mac_addr.bytes,
+				&peer_idx, &session->dph.dphHashTable);
+		if (!sta_ds) {
+			pe_err("Unknown NDI Peer");
+			continue;
+		}
+		if (sta_ds->staType != STA_ENTRY_NDI_PEER) {
+			pe_err("Non-NDI Peer ignored");
+			continue;
+		}
+		/*
+		 * Call lim_del_sta() with response required set true.
+		 * Hence DphHashEntry will be deleted after receiving
+		 * that response.
+		 */
+		lim_del_sta(mac_ctx, sta_ds, true, session);
+		qdf_copy_macaddr(&deleted_peers[deleted_num++],
+			&ndp_map[i].peer_ndi_mac_addr);
+	}
+	qdf_mem_free(deleted_peers);
+}
+
+void lim_ndp_delete_peers_converged(struct peer_nan_datapath_map *ndp_map,
+				    uint8_t num_peers)
+{
+	tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac_ctx)
+		return;
+
+	lim_ndp_delete_peers(mac_ctx, (struct peer_ndp_map *)ndp_map,
+			     num_peers);
+}
+
+/**
+ * lim_process_ndi_del_sta_rsp() - Handle WDA_DELETE_STA_RSP in eLIM_NDI_ROLE
+ * @mac_ctx: Global MAC context
+ * @lim_msg: LIM message
+ * @pe_session: PE session
+ *
+ * Return: None
+ */
+void lim_process_ndi_del_sta_rsp(tpAniSirGlobal mac_ctx,
+				 struct scheduler_msg *lim_msg,
+				 tpPESession pe_session)
+{
+	tpDphHashNode sta_ds;
+	tpDeleteStaParams del_sta_params = (tpDeleteStaParams) lim_msg->bodyptr;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_psoc *psoc = mac_ctx->psoc;
+	struct nan_datapath_peer_ind peer_ind;
+
+	if (!del_sta_params) {
+		pe_err("del_sta_params is NULL");
+		return;
+	}
+	if (!LIM_IS_NDI_ROLE(pe_session)) {
+		pe_err("Session %d is not NDI role", del_sta_params->assocId);
+		goto skip_event;
+	}
+
+	sta_ds = dph_get_hash_entry(mac_ctx, del_sta_params->assocId,
+			&pe_session->dph.dphHashTable);
+	if (!sta_ds) {
+		pe_err("DPH Entry for STA %X is missing",
+			del_sta_params->assocId);
+		goto skip_event;
+	}
+
+	if (QDF_STATUS_SUCCESS != del_sta_params->status) {
+		pe_err("DEL STA failed!");
+		goto skip_event;
+	}
+	pe_info("Deleted STA AssocID %d staId %d MAC " MAC_ADDRESS_STR,
+		sta_ds->assocId, sta_ds->staIndex,
+		MAC_ADDR_ARRAY(sta_ds->staAddr));
+
+	/*
+	 * Copy peer info in del peer indication before
+	 * lim_delete_dph_hash_entry is called as this will be lost.
+	 */
+	peer_ind.sta_id = sta_ds->staIndex;
+	qdf_mem_copy(&peer_ind.peer_mac_addr.bytes,
+		sta_ds->staAddr, sizeof(tSirMacAddr));
+	lim_release_peer_idx(mac_ctx, sta_ds->assocId, pe_session);
+	lim_delete_dph_hash_entry(mac_ctx, sta_ds->staAddr, sta_ds->assocId,
+			pe_session);
+	pe_session->limMlmState = eLIM_MLM_IDLE_STATE;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+						    pe_session->smeSessionId,
+						    WLAN_NAN_ID);
+	if (!vdev) {
+		pe_err("Failed to get vdev from id");
+		goto skip_event;
+	}
+	ucfg_nan_event_handler(psoc, vdev, NDP_PEER_DEPARTED, &peer_ind);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
+
+skip_event:
+	qdf_mem_free(del_sta_params);
+	lim_msg->bodyptr = NULL;
+}
+
+/**
+ * lim_process_ndi_mlm_add_bss_rsp() - Process ADD_BSS response for NDI
+ * @mac_ctx: Pointer to Global MAC structure
+ * @lim_msgq: The MsgQ header, which contains the response buffer
+ * @session_entry: PE session
+ *
+ * Return: None
+ */
+void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
+				     struct scheduler_msg *lim_msgq,
+				     tpPESession session_entry)
+{
+	tLimMlmStartCnf mlm_start_cnf;
+	tpAddBssParams add_bss_params = (tpAddBssParams) lim_msgq->bodyptr;
+
+	if (NULL == add_bss_params) {
+		pe_err("Invalid body pointer in message");
+		goto end;
+	}
+	pe_debug("Status %d", add_bss_params->status);
+	if (QDF_STATUS_SUCCESS == add_bss_params->status) {
+		pe_debug("WDA_ADD_BSS_RSP returned QDF_STATUS_SUCCESS");
+		session_entry->limMlmState = eLIM_MLM_BSS_STARTED_STATE;
+		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+			session_entry->peSessionId,
+			session_entry->limMlmState));
+		session_entry->bssIdx = (uint8_t) add_bss_params->bssIdx;
+		session_entry->limSystemRole = eLIM_NDI_ROLE;
+		session_entry->statypeForBss = STA_ENTRY_SELF;
+		session_entry->staId = add_bss_params->staContext.staIdx;
+		/* Apply previously set configuration at HW */
+		lim_apply_configuration(mac_ctx, session_entry);
+		mlm_start_cnf.resultCode = eSIR_SME_SUCCESS;
+
+		/* Initialize peer ID pool */
+		lim_init_peer_idxpool(mac_ctx, session_entry);
+	} else {
+		pe_err("WDA_ADD_BSS_REQ failed with status %d",
+			add_bss_params->status);
+		mlm_start_cnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+	}
+	mlm_start_cnf.sessionId = session_entry->peSessionId;
+	lim_send_start_bss_confirm(mac_ctx, &mlm_start_cnf);
+end:
+	qdf_mem_free(lim_msgq->bodyptr);
+	lim_msgq->bodyptr = NULL;
+}
+
+/**
+ * lim_ndi_del_bss_rsp() - Handler for DEL BSS resp for NDI interface
+ * @mac_ctx: handle to mac structure
+ * @msg: pointer to message
+ * @session_entry: session entry
+ *
+ * Return: None
+ */
+void lim_ndi_del_bss_rsp(tpAniSirGlobal  mac_ctx,
+			void *msg, tpPESession session_entry)
+{
+	tSirResultCodes rc = eSIR_SME_SUCCESS;
+	tpDeleteBssParams del_bss = (tpDeleteBssParams) msg;
+
+	SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+	if (del_bss == NULL) {
+		pe_err("NDI: DEL_BSS_RSP with no body!");
+		rc = eSIR_SME_STOP_BSS_FAILURE;
+		goto end;
+	}
+	session_entry =
+		pe_find_session_by_session_id(mac_ctx, del_bss->sessionId);
+	if (!session_entry) {
+		pe_err("Session Does not exist for given sessionID");
+		goto end;
+	}
+
+	if (del_bss->status != QDF_STATUS_SUCCESS) {
+		pe_err("NDI: DEL_BSS_RSP error (%x) Bss %d",
+			del_bss->status, del_bss->bssIdx);
+		rc = eSIR_SME_STOP_BSS_FAILURE;
+		goto end;
+	}
+
+	if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE,
+			session_entry->selfMacAddr,
+			session_entry->selfMacAddr, NULL, NULL)
+			!= QDF_STATUS_SUCCESS) {
+		pe_err("NDI: DEL_BSS_RSP setLinkState failed");
+		goto end;
+	}
+
+	session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
+
+end:
+	if (del_bss)
+		qdf_mem_free(del_bss);
+	/* Delete PE session once BSS is deleted */
+	if (NULL != session_entry) {
+		lim_send_sme_rsp(mac_ctx, eWNI_SME_STOP_BSS_RSP,
+			rc, session_entry->smeSessionId,
+			session_entry->transactionId);
+		pe_delete_session(mac_ctx, session_entry);
+		session_entry = NULL;
+	}
+}
+
+static QDF_STATUS lim_send_sme_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx,
+						tpPESession session,
+						tAddStaParams *add_sta_rsp)
+{
+	struct nan_datapath_peer_ind *new_peer_ind;
+	struct wlan_objmgr_psoc *psoc = mac_ctx->psoc;
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!add_sta_rsp) {
+		pe_debug("Invalid add_sta_rsp");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!psoc) {
+		pe_debug("Invalid psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+						    add_sta_rsp->smesessionId,
+						    WLAN_NAN_ID);
+	if (!vdev) {
+		pe_err("Failed to get vdev from id");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	new_peer_ind = qdf_mem_malloc(sizeof(*new_peer_ind));
+	if (!new_peer_ind) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	qdf_mem_copy(new_peer_ind->peer_mac_addr.bytes, add_sta_rsp->staMac,
+		     sizeof(tSirMacAddr));
+	new_peer_ind->sta_id = add_sta_rsp->staIdx;
+
+	ucfg_nan_event_handler(psoc, vdev, NDP_NEW_PEER, new_peer_ind);
+	qdf_mem_free(new_peer_ind);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_ndp_add_sta_rsp() - handles add sta rsp for NDP from WMA
+ * @mac_ctx: handle to mac structure
+ * @session: session pointer
+ * @add_sta_rsp: add sta response struct
+ *
+ * Return: None
+ */
+void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx, tpPESession session,
+			 tAddStaParams *add_sta_rsp)
+{
+	tpDphHashNode sta_ds;
+	uint16_t peer_idx;
+
+	if (NULL == add_sta_rsp) {
+		pe_err("Invalid add_sta_rsp");
+		qdf_mem_free(add_sta_rsp);
+		return;
+	}
+
+	SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+	sta_ds = dph_lookup_hash_entry(mac_ctx, add_sta_rsp->staMac, &peer_idx,
+				    &session->dph.dphHashTable);
+	if (sta_ds == NULL) {
+		pe_err("NAN: ADD_STA_RSP for unknown MAC addr "
+			MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(add_sta_rsp->staMac));
+		qdf_mem_free(add_sta_rsp);
+		return;
+	}
+
+	if (add_sta_rsp->status != QDF_STATUS_SUCCESS) {
+		pe_err("NAN: ADD_STA_RSP error %x for MAC addr: %pM",
+			add_sta_rsp->status, add_sta_rsp->staMac);
+		/* delete the sta_ds allocated during ADD STA */
+		lim_delete_dph_hash_entry(mac_ctx, add_sta_rsp->staMac,
+				      peer_idx, session);
+		qdf_mem_free(add_sta_rsp);
+		return;
+	}
+	sta_ds->bssId = add_sta_rsp->bssIdx;
+	sta_ds->staIndex = add_sta_rsp->staIdx;
+	sta_ds->valid = 1;
+	sta_ds->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+	lim_send_sme_ndp_add_sta_rsp(mac_ctx, session, add_sta_rsp);
+	qdf_mem_free(add_sta_rsp);
+}
diff --git a/core/mac/src/pe/nan/nan_datapath.h b/core/mac/src/pe/nan/nan_datapath.h
new file mode 100644
index 0000000..b13a4fd
--- /dev/null
+++ b/core/mac/src/pe/nan/nan_datapath.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2016-2018 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: nan_datapath.h
+ *
+ * MAC NAN Data path API specification
+ */
+
+#ifndef __MAC_NAN_DATAPATH_H
+#define __MAC_NAN_DATAPATH_H
+
+#if defined(WLAN_FEATURE_NAN_DATAPATH) || defined(WLAN_FEATURE_NAN_CONVERGENCE)
+
+#include "sir_common.h"
+#include "ani_global.h"
+#include "sir_params.h"
+
+struct peer_nan_datapath_map;
+
+/**
+ * struct ndp_peer_node - structure for holding per-peer context
+ * @next: pointer to the next peer
+ * @peer_mac_addr: peer mac address
+ * @ext_rates_present: extended rates supported
+ * @edca_present: edca supported
+ * @wme_edca_present: WME EDCA supported
+ * @wme_info_present: WME info supported
+ * @ht_capable: HT capable
+ * @vht_capable: VHT capabale
+ * @ht_sec_chan_offset: HT secondary channel offset
+ * @capability_info: Generic capability info
+ * @supported_rates: Supported rates
+ * @extended_rates: Supported extended rates
+ * @supported_mcs_rate: Supported MCS rates
+ * @edca_params: EDCA parameters
+ * @erp_ie_present: ERP IE supported
+ * @ht_green_field: HT green field supported
+ * @ht_shortGI_40Mhz; 40 MHZ short GI support
+ * @ht_shortGI_20Mhz; 20 MHZ short GI support
+ * @ht_mimo_ps_state: MIMO power state
+ * @ht_ampdu_density: AMPDU density
+ * @ht_max_rxampdu_factor: receieve AMPDU factor
+ * @ht_max_amsdu_len: Max AMSDU length supported
+ * @ht_supp_chan_widthset: Supported channel widthset
+ * @ht_ldpc_capable: LDPC capable
+ * @heartbeat_failure: heart beat failure indication flag
+ * @vht_caps: VHT capability
+ * @vht_supp_chanwidth_set: VHT supported channel width
+ * @vht_beamformer_capable: Beam former capable
+ */
+struct ndp_peer_node {
+	struct ndp_peer_node *next;
+	struct qdf_mac_addr peer_mac_addr;
+	uint8_t ext_rates_present;
+	uint8_t edca_present;
+	uint8_t wme_edca_present;
+	uint8_t wme_info_present;
+	uint8_t ht_capable;
+	uint8_t vht_capable;
+	uint8_t ht_sec_chan_offset;
+	tSirMacCapabilityInfo    capability_info;
+	tSirMacRateSet           supported_rates;
+	tSirMacRateSet           extended_rates;
+	uint8_t supported_mcs_rate[SIZE_OF_SUPPORTED_MCS_SET];
+	tSirMacEdcaParamSetIE    edca_params;
+	uint8_t erp_ie_present;
+	uint8_t ht_green_field;
+	uint8_t ht_shortGI_40Mhz;
+	uint8_t ht_shortGI_20Mhz;
+	/* MIMO Power Save */
+	tSirMacHTMIMOPowerSaveState ht_mimo_ps_state;
+	uint8_t ht_ampdu_density;
+	/* Maximum Rx A-MPDU factor */
+	uint8_t ht_max_rxampdu_factor;
+	uint8_t ht_max_amsdu_len;
+	uint8_t ht_supp_chan_widthset;
+	uint8_t ht_ldpc_capable;
+	uint8_t heartbeat_failure;
+
+#ifdef WLAN_FEATURE_11AC
+	tDot11fIEVHTCaps vht_caps;
+	uint8_t vht_supp_chanwidth_set;
+	uint8_t vht_beamformer_capable;
+#endif
+};
+
+void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
+				     struct scheduler_msg *lim_msg_q,
+				     tpPESession session_entry);
+/* Handler for DEL BSS resp for NDI interface */
+void lim_ndi_del_bss_rsp(tpAniSirGlobal  mac_ctx,
+			void *msg, tpPESession session_entry);
+
+void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx, tpPESession session_entry,
+			 tAddStaParams *add_sta_rsp);
+
+void lim_process_ndi_del_sta_rsp(tpAniSirGlobal mac_ctx,
+				 struct scheduler_msg *lim_msg,
+				 tpPESession pe_session);
+
+QDF_STATUS lim_add_ndi_peer_converged(uint32_t vdev_id,
+				struct qdf_mac_addr peer_mac_addr);
+
+void lim_ndp_delete_peers_converged(struct peer_nan_datapath_map *ndp_map,
+				    uint8_t num_peers);
+
+void lim_ndp_delete_peers_by_addr_converged(uint8_t vdev_id,
+					struct qdf_mac_addr peer_ndi_mac_addr);
+
+#else
+static inline void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
+					struct scheduler_msg *lim_msg_q,
+					tpPESession session_entry)
+{
+}
+static inline void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx,
+					void *msg, tpPESession session_entry)
+{
+}
+static inline void lim_process_ndi_del_sta_rsp(tpAniSirGlobal mac_ctx,
+				struct scheduler_msg *lim_msg,
+				tpPESession pe_session)
+{
+}
+
+static inline void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx,
+					tpPESession session_entry,
+					tAddStaParams *add_sta_rsp)
+{
+}
+
+#endif /* WLAN_FEATURE_NAN_DATAPATH || WLAN_FEATURE_NAN_CONVERGENCE */
+
+static inline QDF_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx,
+						      struct scheduler_msg *msg)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif /* __MAC_NAN_DATAPATH_H */
+
diff --git a/core/mac/src/pe/rrm/rrm_api.c b/core/mac/src/pe/rrm/rrm_api.c
new file mode 100644
index 0000000..e15063c
--- /dev/null
+++ b/core/mac/src/pe/rrm/rrm_api.c
@@ -0,0 +1,1334 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/**=========================================================================
+
+   \file  rrm_api.c
+
+   \brief implementation for PE RRM APIs
+
+   ========================================================================*/
+
+/* $Header$ */
+
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include "cds_api.h"
+#include "wni_api.h"
+#include "sir_api.h"
+#include "ani_global.h"
+#include "wni_cfg.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "parser_api.h"
+#include "lim_send_messages.h"
+#include "rrm_global.h"
+#include "rrm_api.h"
+
+#define MAX_RRM_TX_PWR_CAP 22
+
+uint8_t
+rrm_get_min_of_max_tx_power(tpAniSirGlobal pMac,
+			    int8_t regMax, int8_t apTxPower)
+{
+	uint8_t maxTxPower = 0;
+	uint8_t txPower = QDF_MIN(regMax, (apTxPower));
+
+	if ((txPower >= RRM_MIN_TX_PWR_CAP) && (txPower <= RRM_MAX_TX_PWR_CAP))
+		maxTxPower = txPower;
+	else if (txPower < RRM_MIN_TX_PWR_CAP)
+		maxTxPower = RRM_MIN_TX_PWR_CAP;
+	else
+		maxTxPower = RRM_MAX_TX_PWR_CAP;
+
+	pe_debug("regulatoryMax: %d, apTxPwr: %d, maxTxpwr: %d",
+		regMax, apTxPower, maxTxPower);
+	return maxTxPower;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_cache_mgmt_tx_power
+ **
+ * FUNCTION:  Store Tx power for management frames.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+void
+rrm_cache_mgmt_tx_power(tpAniSirGlobal pMac, int8_t txPower,
+			tpPESession pSessionEntry)
+{
+	pe_debug("Cache Mgmt Tx Power: %d", txPower);
+
+	if (pSessionEntry == NULL)
+		pMac->rrm.rrmPEContext.txMgmtPower = txPower;
+	else
+		pSessionEntry->txMgmtPower = txPower;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_get_mgmt_tx_power
+ *
+ * FUNCTION:  Get the Tx power for management frames.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pSessionEntry session entry.
+ * @return txPower
+ */
+int8_t rrm_get_mgmt_tx_power(tpAniSirGlobal pMac, tpPESession pSessionEntry)
+{
+	if (pSessionEntry == NULL)
+		return pMac->rrm.rrmPEContext.txMgmtPower;
+
+	pe_debug("tx mgmt pwr %d", pSessionEntry->txMgmtPower);
+
+	return pSessionEntry->txMgmtPower;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_send_set_max_tx_power_req
+ *
+ * FUNCTION:  Send WMA_SET_MAX_TX_POWER_REQ message to change the max tx power.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param txPower txPower to be set.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+QDF_STATUS
+rrm_send_set_max_tx_power_req(tpAniSirGlobal pMac, int8_t txPower,
+			      tpPESession pSessionEntry)
+{
+	tpMaxTxPowerParams pMaxTxParams;
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msgQ = {0};
+
+	if (pSessionEntry == NULL) {
+		pe_err("Invalid parameters");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pMaxTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams));
+	if (!pMaxTxParams)
+		return QDF_STATUS_E_NOMEM;
+	/* Allocated memory for pMaxTxParams...will be freed in other module */
+	pMaxTxParams->power = txPower;
+	qdf_mem_copy(pMaxTxParams->bssId.bytes, pSessionEntry->bssId,
+		     QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(pMaxTxParams->selfStaMacAddr.bytes,
+			pSessionEntry->selfMacAddr,
+			QDF_MAC_ADDR_SIZE);
+
+	msgQ.type = WMA_SET_MAX_TX_POWER_REQ;
+	msgQ.reserved = 0;
+	msgQ.bodyptr = pMaxTxParams;
+	msgQ.bodyval = 0;
+
+	pe_debug("Sending WMA_SET_MAX_TX_POWER_REQ with power(%d) to HAL",
+		txPower);
+
+	MTRACE(mac_trace_msg_tx(pMac, pSessionEntry->peSessionId, msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode) {
+		pe_err("Posting WMA_SET_MAX_TX_POWER_REQ to HAL failed, reason=%X",
+			retCode);
+		qdf_mem_free(pMaxTxParams);
+		return retCode;
+	}
+	return retCode;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_set_max_tx_power_rsp
+ *
+ * FUNCTION:  Process WMA_SET_MAX_TX_POWER_RSP message.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param txPower txPower to be set.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+QDF_STATUS rrm_set_max_tx_power_rsp(tpAniSirGlobal pMac,
+				    struct scheduler_msg *limMsgQ)
+{
+	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
+	tpMaxTxPowerParams pMaxTxParams = (tpMaxTxPowerParams) limMsgQ->bodyptr;
+	tpPESession pSessionEntry;
+	uint8_t sessionId, i;
+
+	if (qdf_is_macaddr_broadcast(&pMaxTxParams->bssId)) {
+		for (i = 0; i < pMac->lim.maxBssId; i++) {
+			if (pMac->lim.gpSession[i].valid == true) {
+				pSessionEntry = &pMac->lim.gpSession[i];
+				rrm_cache_mgmt_tx_power(pMac, pMaxTxParams->power,
+							pSessionEntry);
+			}
+		}
+	} else {
+		pSessionEntry = pe_find_session_by_bssid(pMac,
+							 pMaxTxParams->bssId.bytes,
+							 &sessionId);
+		if (pSessionEntry == NULL) {
+			retCode = QDF_STATUS_E_FAILURE;
+		} else {
+			rrm_cache_mgmt_tx_power(pMac, pMaxTxParams->power,
+						pSessionEntry);
+		}
+	}
+
+	qdf_mem_free(limMsgQ->bodyptr);
+	limMsgQ->bodyptr = NULL;
+	return retCode;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_link_measurement_request
+ *
+ * FUNCTION:  Processes the Link measurement request and send the report.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pBd pointer to BD to extract RSSI and SNR
+ * @param pLinkReq pointer to the Link request frame structure.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+QDF_STATUS
+rrm_process_link_measurement_request(tpAniSirGlobal pMac,
+				     uint8_t *pRxPacketInfo,
+				     tDot11fLinkMeasurementRequest *pLinkReq,
+				     tpPESession pSessionEntry)
+{
+	tSirMacLinkReport LinkReport;
+	tpSirMacMgmtHdr pHdr;
+	int8_t currentRSSI = 0;
+
+	pe_debug("Received Link measurement request");
+
+	if (pRxPacketInfo == NULL || pLinkReq == NULL || pSessionEntry == NULL) {
+		pe_err("Invalid parameters - Ignoring the request");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+	LinkReport.txPower = lim_get_max_tx_power(pSessionEntry->def_max_tx_pwr,
+						pLinkReq->MaxTxPower.maxTxPower,
+						  pMac->roam.configParam.
+						  nTxPowerCap);
+
+	if ((LinkReport.txPower != (uint8_t) (pSessionEntry->maxTxPower)) &&
+	    (QDF_STATUS_SUCCESS == rrm_send_set_max_tx_power_req(pMac,
+							   LinkReport.txPower,
+							   pSessionEntry))) {
+		pe_warn("maxTx power in link report is not same as local..."
+			" Local: %d Link Request TxPower: %d"
+			" Link Report TxPower: %d",
+			pSessionEntry->maxTxPower, LinkReport.txPower,
+			pLinkReq->MaxTxPower.maxTxPower);
+		pSessionEntry->maxTxPower =
+			LinkReport.txPower;
+	}
+
+	LinkReport.dialogToken = pLinkReq->DialogToken.token;
+	LinkReport.rxAntenna = 0;
+	LinkReport.txAntenna = 0;
+	currentRSSI = WMA_GET_RX_RSSI_RAW(pRxPacketInfo);
+
+	pe_info("Received Link report frame with %d", currentRSSI);
+
+	/* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */
+	if ((currentRSSI) <= RCPI_LOW_RSSI_VALUE)
+		LinkReport.rcpi = 0;
+	else if ((currentRSSI > RCPI_LOW_RSSI_VALUE) && (currentRSSI <= 0))
+		LinkReport.rcpi = CALCULATE_RCPI(currentRSSI);
+	else
+		LinkReport.rcpi = RCPI_MAX_VALUE;
+
+	LinkReport.rsni = WMA_GET_RX_SNR(pRxPacketInfo);
+
+	pe_debug("Sending Link report frame");
+
+	return lim_send_link_report_action_frame(pMac, &LinkReport, pHdr->sa,
+						 pSessionEntry);
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_neighbor_report_response
+ *
+ * FUNCTION:  Processes the Neighbor Report response from the peer AP.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pNeighborRep pointer to the Neighbor report frame structure.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+QDF_STATUS
+rrm_process_neighbor_report_response(tpAniSirGlobal pMac,
+				     tDot11fNeighborReportResponse *pNeighborRep,
+				     tpPESession pSessionEntry)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpSirNeighborReportInd pSmeNeighborRpt = NULL;
+	uint16_t length;
+	uint8_t i;
+	struct scheduler_msg mmhMsg = {0};
+
+	if (pNeighborRep == NULL || pSessionEntry == NULL) {
+		pe_err("Invalid parameters");
+		return status;
+	}
+
+	pe_debug("Neighbor report response received");
+
+	/* Dialog token */
+	if (pMac->rrm.rrmPEContext.DialogToken !=
+	    pNeighborRep->DialogToken.token) {
+		pe_err("Dialog token mismatch in the received Neighbor report");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (pNeighborRep->num_NeighborReport == 0) {
+		pe_err("No neighbor report in the frame...Dropping it");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pe_debug("RRM:received num neighbor reports: %d",
+			pNeighborRep->num_NeighborReport);
+	if (pNeighborRep->num_NeighborReport > MAX_SUPPORTED_NEIGHBOR_RPT)
+		pNeighborRep->num_NeighborReport = MAX_SUPPORTED_NEIGHBOR_RPT;
+	length = (sizeof(tSirNeighborReportInd)) +
+		 (sizeof(tSirNeighborBssDescription) *
+		  (pNeighborRep->num_NeighborReport - 1));
+
+	/* Prepare the request to send to SME. */
+	pSmeNeighborRpt = qdf_mem_malloc(length);
+	if (!pSmeNeighborRpt)
+		return QDF_STATUS_E_NOMEM;
+
+	/* Allocated memory for pSmeNeighborRpt...will be freed by other module */
+
+	for (i = 0; i < pNeighborRep->num_NeighborReport; i++) {
+		pSmeNeighborRpt->sNeighborBssDescription[i].length = sizeof(tSirNeighborBssDescription);        /*+ any optional ies */
+		qdf_mem_copy(pSmeNeighborRpt->sNeighborBssDescription[i].bssId,
+			     pNeighborRep->NeighborReport[i].bssid,
+			     sizeof(tSirMacAddr));
+		pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+		fApPreauthReachable =
+			pNeighborRep->NeighborReport[i].APReachability;
+		pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+		fSameSecurityMode =
+			pNeighborRep->NeighborReport[i].Security;
+		pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+		fSameAuthenticator =
+			pNeighborRep->NeighborReport[i].KeyScope;
+		pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+		fCapSpectrumMeasurement =
+			pNeighborRep->NeighborReport[i].SpecMgmtCap;
+		pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+		fCapQos = pNeighborRep->NeighborReport[i].QosCap;
+		pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+		fCapApsd = pNeighborRep->NeighborReport[i].apsd;
+		pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+		fCapRadioMeasurement = pNeighborRep->NeighborReport[i].rrm;
+		pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+		fCapDelayedBlockAck =
+			pNeighborRep->NeighborReport[i].DelayedBA;
+		pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+		fCapImmediateBlockAck =
+			pNeighborRep->NeighborReport[i].ImmBA;
+		pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+		fMobilityDomain =
+			pNeighborRep->NeighborReport[i].MobilityDomain;
+
+		pSmeNeighborRpt->sNeighborBssDescription[i].regClass =
+			pNeighborRep->NeighborReport[i].regulatoryClass;
+		pSmeNeighborRpt->sNeighborBssDescription[i].channel =
+			pNeighborRep->NeighborReport[i].channel;
+		pSmeNeighborRpt->sNeighborBssDescription[i].phyType =
+			pNeighborRep->NeighborReport[i].PhyType;
+	}
+
+	pSmeNeighborRpt->messageType = eWNI_SME_NEIGHBOR_REPORT_IND;
+	pSmeNeighborRpt->length = length;
+	pSmeNeighborRpt->sessionId = pSessionEntry->smeSessionId;
+	pSmeNeighborRpt->numNeighborReports = pNeighborRep->num_NeighborReport;
+	qdf_mem_copy(pSmeNeighborRpt->bssId, pSessionEntry->bssId,
+		     sizeof(tSirMacAddr));
+
+	/* Send request to SME. */
+	mmhMsg.type = pSmeNeighborRpt->messageType;
+	mmhMsg.bodyptr = pSmeNeighborRpt;
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+			 pSessionEntry->peSessionId, mmhMsg.type));
+	status = lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+	return status;
+
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_neighbor_report_req
+ *
+ * FUNCTION:
+ *
+ * LOGIC: Create a Neighbor report request and send it to peer.
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pNeighborReq Neighbor report request params .
+ * @return None
+ */
+QDF_STATUS
+rrm_process_neighbor_report_req(tpAniSirGlobal pMac,
+				tpSirNeighborReportReqInd pNeighborReq)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirMacNeighborReportReq NeighborReportReq;
+	tpPESession pSessionEntry;
+	uint8_t sessionId;
+
+	if (pNeighborReq == NULL) {
+		pe_err("NeighborReq is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pSessionEntry = pe_find_session_by_bssid(pMac, pNeighborReq->bssId,
+						 &sessionId);
+	if (pSessionEntry == NULL) {
+		pe_err("session does not exist for given bssId");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pe_debug("SSID present: %d", pNeighborReq->noSSID);
+
+	qdf_mem_set(&NeighborReportReq, sizeof(tSirMacNeighborReportReq), 0);
+
+	NeighborReportReq.dialogToken = ++pMac->rrm.rrmPEContext.DialogToken;
+	NeighborReportReq.ssid_present = !pNeighborReq->noSSID;
+	if (NeighborReportReq.ssid_present) {
+		qdf_mem_copy(&NeighborReportReq.ssid, &pNeighborReq->ucSSID,
+			     sizeof(tSirMacSSid));
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+				   QDF_TRACE_LEVEL_DEBUG,
+				   (uint8_t *) NeighborReportReq.ssid.ssId,
+				   NeighborReportReq.ssid.length);
+	}
+
+	status =
+		lim_send_neighbor_report_request_frame(pMac, &NeighborReportReq,
+						       pNeighborReq->bssId,
+						       pSessionEntry);
+
+	return status;
+}
+
+#define ABS(x)      ((x < 0) ? -x : x)
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_beacon_report_req
+ *
+ * FUNCTION:  Processes the Beacon report request from the peer AP.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pCurrentReq pointer to the current Req comtext.
+ * @param pBeaconReq pointer to the beacon report request IE from the peer.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+static tRrmRetStatus
+rrm_process_beacon_report_req(tpAniSirGlobal pMac,
+			      tpRRMReq pCurrentReq,
+			      tDot11fIEMeasurementRequest *pBeaconReq,
+			      tpPESession pSessionEntry)
+{
+	struct scheduler_msg mmhMsg = {0};
+	tpSirBeaconReportReqInd pSmeBcnReportReq;
+	uint8_t num_channels = 0, num_APChanReport;
+	uint16_t measDuration, maxMeasduration;
+	int8_t maxDuration;
+	uint8_t sign;
+
+	if (pBeaconReq->measurement_request.Beacon.BeaconReporting.present &&
+	    (pBeaconReq->measurement_request.Beacon.BeaconReporting.
+	     reportingCondition != 0)) {
+		/* Repeated measurement is not supported. This means number of repetitions should be zero.(Already checked) */
+		/* All test case in VoWifi(as of version 0.36)  use zero for number of repetitions. */
+		/* Beacon reporting should not be included in request if number of repetitons is zero. */
+		/* IEEE Std 802.11k-2008 Table 7-29g and section 11.10.8.1 */
+
+		pe_err("Dropping the request: Reporting condition included in beacon report request and it is not zero");
+		return eRRM_INCAPABLE;
+	}
+
+	/* The logic here is to check the measurement duration passed in the beacon request. Following are the cases handled.
+	   Case 1: If measurement duration received in the beacon request is greater than the max measurement duration advertised
+	   in the RRM capabilities(Assoc Req), and Duration Mandatory bit is set to 1, REFUSE the beacon request
+	   Case 2: If measurement duration received in the beacon request is greater than the max measurement duration advertised
+	   in the RRM capabilities(Assoc Req), and Duration Mandatory bit is set to 0, perform measurement for
+	   the duration advertised in the RRM capabilities
+
+	   maxMeasurementDuration = 2^(nonOperatingChanMax - 4) * BeaconInterval
+	 */
+	maxDuration =
+		pMac->rrm.rrmPEContext.rrmEnabledCaps.nonOperatingChanMax - 4;
+	sign = (maxDuration < 0) ? 1 : 0;
+	maxDuration = (1L << ABS(maxDuration));
+	if (!sign)
+		maxMeasduration =
+			maxDuration * pSessionEntry->beaconParams.beaconInterval;
+	else
+		maxMeasduration =
+			pSessionEntry->beaconParams.beaconInterval / maxDuration;
+
+	measDuration = pBeaconReq->measurement_request.Beacon.meas_duration;
+
+	pe_info("maxDuration = %d sign = %d maxMeasduration = %d measDuration = %d",
+		maxDuration, sign, maxMeasduration, measDuration);
+
+	if (maxMeasduration < measDuration) {
+		if (pBeaconReq->durationMandatory) {
+			pe_err("Dropping the request: duration mandatory and maxduration > measduration");
+			return eRRM_REFUSED;
+		} else
+			measDuration = maxMeasduration;
+	}
+	/* Cache the data required for sending report. */
+	pCurrentReq->request.Beacon.reportingDetail =
+		pBeaconReq->measurement_request.Beacon.BcnReportingDetail.
+		present ? pBeaconReq->measurement_request.Beacon.BcnReportingDetail.
+		reportingDetail : BEACON_REPORTING_DETAIL_ALL_FF_IE;
+
+	if (pBeaconReq->measurement_request.Beacon.
+	    last_beacon_report_indication.present) {
+		pCurrentReq->request.Beacon.last_beacon_report_indication =
+			pBeaconReq->measurement_request.Beacon.
+			last_beacon_report_indication.last_fragment;
+		pe_debug("Last Beacon Report in request = %d",
+			pCurrentReq->request.Beacon.
+			last_beacon_report_indication);
+	} else {
+		pCurrentReq->request.Beacon.last_beacon_report_indication = 0;
+		pe_debug("Last Beacon report not present in request");
+	}
+
+	if (pBeaconReq->measurement_request.Beacon.RequestedInfo.present) {
+		pCurrentReq->request.Beacon.reqIes.pElementIds =
+			qdf_mem_malloc(sizeof(uint8_t) *
+				       pBeaconReq->measurement_request.Beacon.
+				       RequestedInfo.num_requested_eids);
+		if (!pCurrentReq->request.Beacon.reqIes.pElementIds)
+			return eRRM_FAILURE;
+		pCurrentReq->request.Beacon.reqIes.num =
+			pBeaconReq->measurement_request.Beacon.RequestedInfo.
+			num_requested_eids;
+		qdf_mem_copy(pCurrentReq->request.Beacon.reqIes.pElementIds,
+			     pBeaconReq->measurement_request.Beacon.
+			     RequestedInfo.requested_eids,
+			     pCurrentReq->request.Beacon.reqIes.num);
+	}
+
+	if (pBeaconReq->measurement_request.Beacon.num_APChannelReport) {
+		for (num_APChanReport = 0;
+		     num_APChanReport <
+		     pBeaconReq->measurement_request.Beacon.num_APChannelReport;
+		     num_APChanReport++)
+			num_channels +=
+				pBeaconReq->measurement_request.Beacon.
+				APChannelReport[num_APChanReport].num_channelList;
+	}
+	/* Prepare the request to send to SME. */
+	pSmeBcnReportReq = qdf_mem_malloc(sizeof(tSirBeaconReportReqInd));
+	if (!pSmeBcnReportReq)
+		return eRRM_FAILURE;
+
+	/* Allocated memory for pSmeBcnReportReq....will be freed by other modulea */
+	qdf_mem_copy(pSmeBcnReportReq->bssId, pSessionEntry->bssId,
+		     sizeof(tSirMacAddr));
+	pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND;
+	pSmeBcnReportReq->length = sizeof(tSirBeaconReportReqInd);
+	pSmeBcnReportReq->uDialogToken = pBeaconReq->measurement_token;
+	pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_11K;
+	pSmeBcnReportReq->randomizationInterval =
+		SYS_TU_TO_MS(pBeaconReq->measurement_request.Beacon.randomization);
+	pSmeBcnReportReq->channelInfo.regulatoryClass =
+		pBeaconReq->measurement_request.Beacon.regClass;
+	pSmeBcnReportReq->channelInfo.channelNum =
+		pBeaconReq->measurement_request.Beacon.channel;
+	pSmeBcnReportReq->measurementDuration[0] = SYS_TU_TO_MS(measDuration);
+	pSmeBcnReportReq->fMeasurementtype[0] =
+		pBeaconReq->measurement_request.Beacon.meas_mode;
+	qdf_mem_copy(pSmeBcnReportReq->macaddrBssid,
+		     pBeaconReq->measurement_request.Beacon.BSSID,
+		     sizeof(tSirMacAddr));
+
+	if (pBeaconReq->measurement_request.Beacon.SSID.present) {
+		pSmeBcnReportReq->ssId.length =
+			pBeaconReq->measurement_request.Beacon.SSID.num_ssid;
+		qdf_mem_copy(pSmeBcnReportReq->ssId.ssId,
+			     pBeaconReq->measurement_request.Beacon.SSID.ssid,
+			     pSmeBcnReportReq->ssId.length);
+	}
+
+	pCurrentReq->token = pBeaconReq->measurement_token;
+
+	pSmeBcnReportReq->channelList.numChannels = num_channels;
+	if (pBeaconReq->measurement_request.Beacon.num_APChannelReport) {
+		uint8_t *ch_lst = pSmeBcnReportReq->channelList.channelNumber;
+		uint8_t len;
+		uint16_t ch_ctr = 0;
+
+		for (num_APChanReport = 0;
+		     num_APChanReport <
+		     pBeaconReq->measurement_request.Beacon.num_APChannelReport;
+		     num_APChanReport++) {
+			len = pBeaconReq->measurement_request.Beacon.
+			    APChannelReport[num_APChanReport].num_channelList;
+			if (ch_ctr + len >
+			   sizeof(pSmeBcnReportReq->channelList.channelNumber))
+				break;
+
+			qdf_mem_copy(&ch_lst[ch_ctr],
+				     pBeaconReq->measurement_request.Beacon.
+				     APChannelReport[num_APChanReport].
+				     channelList, len);
+
+			ch_ctr += len;
+		}
+	}
+	/* Send request to SME. */
+	mmhMsg.type = eWNI_SME_BEACON_REPORT_REQ_IND;
+	mmhMsg.bodyptr = pSmeBcnReportReq;
+	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
+			 pSessionEntry->peSessionId, mmhMsg.type));
+	if (QDF_STATUS_SUCCESS !=
+	    lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT))
+		return eRRM_FAILURE;
+	return eRRM_SUCCESS;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_fill_beacon_ies
+ *
+ * FUNCTION:
+ *
+ * LOGIC: Fills Fixed fields and Ies in bss description to an array of uint8_t.
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pIes - pointer to the buffer that should be populated with ies.
+ * @param pNumIes - returns the num of ies filled in this param.
+ * @param pIesMaxSize - Max size of the buffer pIes.
+ * @param eids - pointer to array of eids. If NULL, all ies will be populated.
+ * @param numEids - number of elements in array eids.
+ * @param pBssDesc - pointer to Bss Description.
+ * @return None
+ */
+static void
+rrm_fill_beacon_ies(tpAniSirGlobal pMac,
+		    uint8_t *pIes, uint8_t *pNumIes, uint8_t pIesMaxSize,
+		    uint8_t *eids, uint8_t numEids, tpSirBssDescription pBssDesc)
+{
+	uint8_t len, *pBcnIes, count = 0, i;
+	uint16_t BcnNumIes;
+
+	if ((pIes == NULL) || (pNumIes == NULL) || (pBssDesc == NULL)) {
+		pe_err("Invalid parameters");
+		return;
+	}
+	/* Make sure that if eid is null, numEids is set to zero. */
+	numEids = (eids == NULL) ? 0 : numEids;
+
+	pBcnIes = (uint8_t *) &pBssDesc->ieFields[0];
+	BcnNumIes = GET_IE_LEN_IN_BSS(pBssDesc->length);
+
+	*pNumIes = 0;
+
+	*((uint32_t *) pIes) = pBssDesc->timeStamp[0];
+	*pNumIes += sizeof(uint32_t);
+	pIes += sizeof(uint32_t);
+	*((uint32_t *) pIes) = pBssDesc->timeStamp[1];
+	*pNumIes += sizeof(uint32_t);
+	pIes += sizeof(uint32_t);
+	*((uint16_t *) pIes) = pBssDesc->beaconInterval;
+	*pNumIes += sizeof(uint16_t);
+	pIes += sizeof(uint16_t);
+	*((uint16_t *) pIes) = pBssDesc->capabilityInfo;
+	*pNumIes += sizeof(uint16_t);
+	pIes += sizeof(uint16_t);
+
+	while (BcnNumIes > 0) {
+		len = *(pBcnIes + 1) + 2;       /* element id + length. */
+		pe_debug("EID = %d, len = %d total = %d",
+			*pBcnIes, *(pBcnIes + 1), len);
+
+		i = 0;
+		do {
+			if (((eids == NULL) || (*pBcnIes == eids[i])) &&
+			    ((*pNumIes) + len) < pIesMaxSize) {
+				pe_debug("Adding Eid %d, len=%d",
+					*pBcnIes, len);
+
+				qdf_mem_copy(pIes, pBcnIes, len);
+				pIes += len;
+				*pNumIes += len;
+				count++;
+				break;
+			}
+			i++;
+		} while (i < numEids);
+
+		pBcnIes += len;
+		BcnNumIes -= len;
+	}
+	pe_debug("Total length of Ies added = %d", *pNumIes);
+}
+
+/**
+ * rrm_process_beacon_report_xmit() - create a rrm action frame
+ * @mac_ctx: Global pointer to MAC context
+ * @beacon_xmit_ind: Data for beacon report IE from SME.
+ *
+ * Create a Radio measurement report action frame and send it to peer.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+rrm_process_beacon_report_xmit(tpAniSirGlobal mac_ctx,
+			       tpSirBeaconReportXmitInd beacon_xmit_ind)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirMacRadioMeasureReport *report = NULL;
+	tSirMacBeaconReport *beacon_report;
+	tpSirBssDescription bss_desc;
+	tpRRMReq curr_req = mac_ctx->rrm.rrmPEContext.pCurrentReq;
+	tpPESession session_entry;
+	struct rrm_beacon_report_last_beacon_params last_beacon_report_params;
+	uint8_t session_id, counter;
+	uint8_t bss_desc_count = 0;
+	uint8_t report_index = 0;
+
+	pe_debug("Received beacon report xmit indication");
+
+	if (NULL == beacon_xmit_ind) {
+		pe_err("Received beacon_xmit_ind is NULL in PE");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (NULL == curr_req) {
+		pe_err("Received report xmit while there is no request pending in PE");
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	if ((beacon_xmit_ind->numBssDesc) || curr_req->sendEmptyBcnRpt) {
+		beacon_xmit_ind->numBssDesc = (beacon_xmit_ind->numBssDesc ==
+			RRM_BCN_RPT_NO_BSS_INFO) ? RRM_BCN_RPT_MIN_RPT :
+			beacon_xmit_ind->numBssDesc;
+
+		session_entry = pe_find_session_by_bssid(mac_ctx,
+				beacon_xmit_ind->bssId, &session_id);
+		if (NULL == session_entry) {
+			pe_err("session does not exist for given bssId");
+			status = QDF_STATUS_E_FAILURE;
+			goto end;
+		}
+
+		report = qdf_mem_malloc(beacon_xmit_ind->numBssDesc *
+			 sizeof(*report));
+		if (!report) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+
+		for (bss_desc_count = 0; bss_desc_count <
+		     beacon_xmit_ind->numBssDesc; bss_desc_count++) {
+			beacon_report =
+				&report[bss_desc_count].report.beaconReport;
+			/*
+			 * If the scan result is NULL then send report request
+			 * with option subelement as NULL.
+			 */
+			bss_desc = beacon_xmit_ind->
+				   pBssDescription[bss_desc_count];
+			/* Prepare the beacon report and send it to the peer.*/
+			report[bss_desc_count].token =
+				beacon_xmit_ind->uDialogToken;
+			report[bss_desc_count].refused = 0;
+			report[bss_desc_count].incapable = 0;
+			report[bss_desc_count].type = SIR_MAC_RRM_BEACON_TYPE;
+
+			/*
+			 * Valid response is included if the size of
+			 * becon xmit is == size of beacon xmit ind + ies
+			 */
+			if (beacon_xmit_ind->length < sizeof(*beacon_xmit_ind))
+				continue;
+			beacon_report->regClass = beacon_xmit_ind->regClass;
+			if (bss_desc) {
+				beacon_report->channel = bss_desc->channelId;
+				qdf_mem_copy(beacon_report->measStartTime,
+					bss_desc->startTSF,
+					sizeof(bss_desc->startTSF));
+				beacon_report->measDuration =
+					SYS_MS_TO_TU(beacon_xmit_ind->duration);
+				beacon_report->phyType = bss_desc->nwType;
+				beacon_report->bcnProbeRsp = 1;
+				beacon_report->rsni = bss_desc->sinr;
+				beacon_report->rcpi = bss_desc->rssi;
+				beacon_report->antennaId = 0;
+				beacon_report->parentTSF = bss_desc->parentTSF;
+				qdf_mem_copy(beacon_report->bssid,
+					bss_desc->bssId, sizeof(tSirMacAddr));
+			}
+
+			switch (curr_req->request.Beacon.reportingDetail) {
+			case BEACON_REPORTING_DETAIL_NO_FF_IE:
+				/* 0: No need to include any elements. */
+				pe_debug("No reporting detail requested");
+				break;
+			case BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE:
+				/* 1: Include all FFs and Requested Ies. */
+				pe_debug("Only requested IEs in reporting detail requested");
+
+				if (bss_desc) {
+					rrm_fill_beacon_ies(mac_ctx,
+					    (uint8_t *) &beacon_report->Ies[0],
+					    (uint8_t *) &beacon_report->numIes,
+					    BEACON_REPORT_MAX_IES,
+					    curr_req->request.Beacon.reqIes.
+					    pElementIds,
+					    curr_req->request.Beacon.reqIes.num,
+					    bss_desc);
+				}
+				break;
+			case BEACON_REPORTING_DETAIL_ALL_FF_IE:
+				/* 2: default - Include all FFs and all Ies. */
+			default:
+				pe_debug("Default all IEs and FFs");
+				if (bss_desc) {
+					rrm_fill_beacon_ies(mac_ctx,
+					    (uint8_t *) &beacon_report->Ies[0],
+					    (uint8_t *) &beacon_report->numIes,
+					    BEACON_REPORT_MAX_IES,
+					    NULL,
+					    0,
+					    bss_desc);
+				}
+				break;
+			}
+		}
+
+
+		qdf_mem_zero(&last_beacon_report_params,
+			sizeof(last_beacon_report_params));
+		/*
+		 * Each frame can hold RADIO_REPORTS_MAX_IN_A_FRAME reports.
+		 * Multiple frames may be sent if bss_desc_count is larger.
+		 * Count the total number of frames to be sent first
+		 */
+
+
+		last_beacon_report_params.last_beacon_ind =
+			curr_req->request.Beacon.last_beacon_report_indication;
+		last_beacon_report_params.num_frags =
+			(bss_desc_count / RADIO_REPORTS_MAX_IN_A_FRAME);
+		if (bss_desc_count % RADIO_REPORTS_MAX_IN_A_FRAME)
+			last_beacon_report_params.num_frags++;
+
+		pe_debug("last_beacon_report_ind required %d num_frags %d bss_count %d",
+			last_beacon_report_params.last_beacon_ind,
+			last_beacon_report_params.num_frags,
+			bss_desc_count);
+
+		while (report_index < bss_desc_count) {
+			int m_count;
+
+			m_count = QDF_MIN((bss_desc_count - report_index),
+					RADIO_REPORTS_MAX_IN_A_FRAME);
+			pe_info("Sending Action frame with %d bss info frag_id %d",
+				m_count, last_beacon_report_params.frag_id);
+			lim_send_radio_measure_report_action_frame(mac_ctx,
+				curr_req->dialog_token, m_count,
+				&last_beacon_report_params,
+				&report[report_index],
+				beacon_xmit_ind->bssId, session_entry);
+			report_index += m_count;
+			last_beacon_report_params.frag_id++;
+		}
+		curr_req->sendEmptyBcnRpt = false;
+	}
+
+end:
+	for (counter = 0; counter < beacon_xmit_ind->numBssDesc; counter++)
+		qdf_mem_free(beacon_xmit_ind->pBssDescription[counter]);
+
+	if (beacon_xmit_ind->fMeasureDone) {
+		pe_debug("Measurement done....cleanup the context");
+		rrm_cleanup(mac_ctx);
+	}
+
+	if (NULL != report)
+		qdf_mem_free(report);
+
+	return status;
+}
+
+static void rrm_process_beacon_request_failure(tpAniSirGlobal pMac,
+					       tpPESession pSessionEntry,
+					       tSirMacAddr peer,
+					       tRrmRetStatus status)
+{
+	tpSirMacRadioMeasureReport pReport = NULL;
+	tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq;
+
+	pReport = qdf_mem_malloc(sizeof(tSirMacRadioMeasureReport));
+	if (!pReport)
+		return;
+	pReport->token = pCurrentReq->token;
+	pReport->type = SIR_MAC_RRM_BEACON_TYPE;
+
+	pe_debug("status %d token %d", status, pReport->token);
+
+	switch (status) {
+	case eRRM_REFUSED:
+		pReport->refused = 1;
+		break;
+	case eRRM_INCAPABLE:
+		pReport->incapable = 1;
+		break;
+	default:
+		pe_err("Beacon request processing failed no report sent with status %d",
+			       status);
+		qdf_mem_free(pReport);
+		return;
+	}
+
+	lim_send_radio_measure_report_action_frame(pMac,
+						   pCurrentReq->dialog_token,
+						   1, NULL,
+						   pReport, peer,
+						   pSessionEntry);
+
+	qdf_mem_free(pReport);
+	return;
+}
+
+/**
+ * rrm_process_beacon_req() - Update curr_req and report
+ * @mac_ctx: Global pointer to MAC context
+ * @peer: Macaddress of the peer requesting the radio measurement
+ * @session_entry: session entry
+ * @curr_req: Pointer to RRM request
+ * @radiomes_report: Pointer to radio measurement report
+ * @rrm_req: Array of Measurement request IEs
+ * @num_report: No.of reports
+ * @index: Index for Measurement request
+ *
+ * Update structure sRRMReq and sSirMacRadioMeasureReport and pass it to
+ * rrm_process_beacon_report_req().
+ *
+ * Return: QDF_STATUS
+ */
+static
+QDF_STATUS rrm_process_beacon_req(tpAniSirGlobal mac_ctx, tSirMacAddr peer,
+				  tpPESession session_entry, tpRRMReq curr_req,
+				  tpSirMacRadioMeasureReport *radiomes_report,
+				  tDot11fRadioMeasurementRequest *rrm_req,
+				  uint8_t *num_report, int index)
+{
+	tRrmRetStatus rrm_status = eRRM_SUCCESS;
+	tpSirMacRadioMeasureReport report;
+
+	if (curr_req) {
+		if (*radiomes_report == NULL) {
+			/*
+			 * Allocate memory to send reports for
+			 * any subsequent requests.
+			 */
+			*radiomes_report = qdf_mem_malloc(sizeof(*report) *
+				(rrm_req->num_MeasurementRequest - index));
+			if (!*radiomes_report)
+				return QDF_STATUS_E_NOMEM;
+			pe_debug("rrm beacon type refused of %d report in beacon table",
+				*num_report);
+		}
+		report = *radiomes_report;
+		report[*num_report].refused = 1;
+		report[*num_report].type = SIR_MAC_RRM_BEACON_TYPE;
+		report[*num_report].token =
+			rrm_req->MeasurementRequest[index].measurement_token;
+		(*num_report)++;
+		return QDF_STATUS_SUCCESS;
+	} else {
+		curr_req = qdf_mem_malloc(sizeof(*curr_req));
+		if (!curr_req) {
+				qdf_mem_free(*radiomes_report);
+			return QDF_STATUS_E_NOMEM;
+		}
+		pe_debug("Processing Beacon Report request");
+		curr_req->dialog_token = rrm_req->DialogToken.token;
+		curr_req->token = rrm_req->
+				  MeasurementRequest[index].measurement_token;
+		curr_req->sendEmptyBcnRpt = true;
+		mac_ctx->rrm.rrmPEContext.pCurrentReq = curr_req;
+		rrm_status = rrm_process_beacon_report_req(mac_ctx, curr_req,
+			&rrm_req->MeasurementRequest[index], session_entry);
+		if (eRRM_SUCCESS != rrm_status) {
+			rrm_process_beacon_request_failure(mac_ctx,
+				session_entry, peer, rrm_status);
+			rrm_cleanup(mac_ctx);
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * update_rrm_report() - Set incapable bit
+ * @mac_ctx: Global pointer to MAC context
+ * @report: Pointer to radio measurement report
+ * @rrm_req: Array of Measurement request IEs
+ * @num_report: No.of reports
+ * @index: Index for Measurement request
+ *
+ * Send a report with incapabale bit set
+ *
+ * Return: QDF_STATUS
+ */
+static
+QDF_STATUS update_rrm_report(tpAniSirGlobal mac_ctx,
+			     tpSirMacRadioMeasureReport report,
+			     tDot11fRadioMeasurementRequest *rrm_req,
+			     uint8_t *num_report, int index)
+{
+	if (report == NULL) {
+		/*
+		 * Allocate memory to send reports for
+		 * any subsequent requests.
+		 */
+		report = qdf_mem_malloc(sizeof(*report) *
+			 (rrm_req->num_MeasurementRequest - index));
+		if (!report)
+			return QDF_STATUS_E_NOMEM;
+		pe_debug("rrm beacon type incapable of %d report",
+			*num_report);
+	}
+	report[*num_report].incapable = 1;
+	report[*num_report].type =
+		rrm_req->MeasurementRequest[index].measurement_type;
+	report[*num_report].token =
+		 rrm_req->MeasurementRequest[index].measurement_token;
+	(*num_report)++;
+	return QDF_STATUS_SUCCESS;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_radio_measurement_request - Process rrm request
+ * @mac_ctx: Global pointer to MAC context
+ * @peer: Macaddress of the peer requesting the radio measurement.
+ * @rrm_req: Array of Measurement request IEs
+ * @session_entry: session entry.
+ *
+ * Processes the Radio Resource Measurement request.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+rrm_process_radio_measurement_request(tpAniSirGlobal mac_ctx,
+				      tSirMacAddr peer,
+				      tDot11fRadioMeasurementRequest *rrm_req,
+				      tpPESession session_entry)
+{
+	uint8_t i;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpSirMacRadioMeasureReport report = NULL;
+	uint8_t num_report = 0;
+	tpRRMReq curr_req = mac_ctx->rrm.rrmPEContext.pCurrentReq;
+
+	if (!rrm_req->num_MeasurementRequest) {
+		report = qdf_mem_malloc(sizeof(tSirMacRadioMeasureReport));
+		if (!report)
+			return QDF_STATUS_E_NOMEM;
+		pe_err("No requestIes in the measurement request, sending incapable report");
+		report->incapable = 1;
+		num_report = 1;
+		lim_send_radio_measure_report_action_frame(mac_ctx,
+			rrm_req->DialogToken.token, num_report, NULL,
+			report, peer, session_entry);
+		qdf_mem_free(report);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* PF Fix */
+	if (rrm_req->NumOfRepetitions.repetitions > 0) {
+		pe_info("number of repetitions %d",
+			rrm_req->NumOfRepetitions.repetitions);
+		/*
+		 * Send a report with incapable bit set.
+		 * Not supporting repetitions.
+		 */
+		report = qdf_mem_malloc(sizeof(tSirMacRadioMeasureReport));
+		if (!report)
+			return QDF_STATUS_E_NOMEM;
+		report->incapable = 1;
+		report->type = rrm_req->MeasurementRequest[0].measurement_type;
+		num_report = 1;
+		goto end;
+	}
+
+	for (i = 0; i < rrm_req->num_MeasurementRequest; i++) {
+		switch (rrm_req->MeasurementRequest[i].measurement_type) {
+		case SIR_MAC_RRM_BEACON_TYPE:
+			/* Process beacon request. */
+			status = rrm_process_beacon_req(mac_ctx, peer,
+				 session_entry, curr_req, &report, rrm_req,
+				 &num_report, i);
+			if (QDF_STATUS_SUCCESS != status)
+				return status;
+			break;
+		case SIR_MAC_RRM_LCI_TYPE:
+		case SIR_MAC_RRM_LOCATION_CIVIC_TYPE:
+		case SIR_MAC_RRM_FINE_TIME_MEAS_TYPE:
+			pe_debug("RRM with type: %d sent to userspace",
+			    rrm_req->MeasurementRequest[i].measurement_type);
+			break;
+		default:
+			/* Send a report with incapabale bit set. */
+			status = update_rrm_report(mac_ctx, report, rrm_req,
+						   &num_report, i);
+			if (QDF_STATUS_SUCCESS != status)
+				return status;
+			break;
+		}
+	}
+
+end:
+	if (report) {
+		lim_send_radio_measure_report_action_frame(mac_ctx,
+			rrm_req->DialogToken.token, num_report, NULL,
+			report, peer, session_entry);
+		qdf_mem_free(report);
+	}
+	return status;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_update_start_tsf
+ **
+ * FUNCTION:  Store start TSF of measurement.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param startTSF - TSF value at the start of measurement.
+ * @return None
+ */
+void rrm_update_start_tsf(tpAniSirGlobal pMac, uint32_t startTSF[2])
+{
+	pMac->rrm.rrmPEContext.startTSF[0] = startTSF[0];
+	pMac->rrm.rrmPEContext.startTSF[1] = startTSF[1];
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_get_start_tsf
+ *
+ * FUNCTION:  Get the Start TSF.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param startTSF - store star TSF in this buffer.
+ * @return txPower
+ */
+void rrm_get_start_tsf(tpAniSirGlobal pMac, uint32_t *pStartTSF)
+{
+	pStartTSF[0] = pMac->rrm.rrmPEContext.startTSF[0];
+	pStartTSF[1] = pMac->rrm.rrmPEContext.startTSF[1];
+
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_get_capabilities
+ *
+ * FUNCTION:
+ * Returns a pointer to tpRRMCaps with all the caps enabled in RRM
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pSessionEntry
+ * @return pointer to tRRMCaps
+ */
+tpRRMCaps rrm_get_capabilities(tpAniSirGlobal pMac, tpPESession pSessionEntry)
+{
+	return &pMac->rrm.rrmPEContext.rrmEnabledCaps;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_initialize
+ *
+ * FUNCTION:
+ * Initialize RRM module
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @return None
+ */
+
+QDF_STATUS rrm_initialize(tpAniSirGlobal pMac)
+{
+	tpRRMCaps pRRMCaps = &pMac->rrm.rrmPEContext.rrmEnabledCaps;
+
+	pMac->rrm.rrmPEContext.pCurrentReq = NULL;
+	pMac->rrm.rrmPEContext.txMgmtPower = 0;
+	pMac->rrm.rrmPEContext.DialogToken = 0;
+
+	pMac->rrm.rrmPEContext.rrmEnable = 0;
+	pMac->rrm.rrmPEContext.prev_rrm_report_seq_num = 0xFFFF;
+
+	qdf_mem_set(pRRMCaps, sizeof(tRRMCaps), 0);
+	pRRMCaps->LinkMeasurement = 1;
+	pRRMCaps->NeighborRpt = 1;
+	pRRMCaps->BeaconPassive = 1;
+	pRRMCaps->BeaconActive = 1;
+	pRRMCaps->BeaconTable = 1;
+	pRRMCaps->APChanReport = 1;
+	pRRMCaps->fine_time_meas_rpt = 1;
+	pRRMCaps->lci_capability = 1;
+
+	pRRMCaps->operatingChanMax = 3;
+	pRRMCaps->nonOperatingChanMax = 3;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_cleanup
+ *
+ * FUNCTION:
+ * cleanup RRM module
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param mode
+ * @param rate
+ * @return None
+ */
+
+QDF_STATUS rrm_cleanup(tpAniSirGlobal pMac)
+{
+	if (pMac->rrm.rrmPEContext.pCurrentReq) {
+		if (pMac->rrm.rrmPEContext.pCurrentReq->request.Beacon.reqIes.
+		    pElementIds) {
+			qdf_mem_free(pMac->rrm.rrmPEContext.pCurrentReq->
+				     request.Beacon.reqIes.pElementIds);
+		}
+
+		qdf_mem_free(pMac->rrm.rrmPEContext.pCurrentReq);
+	}
+
+	pMac->rrm.rrmPEContext.pCurrentReq = NULL;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_update_rrm_capability() - Update PE context's rrm capability
+ * @mac_ctx: Global pointer to MAC context
+ * @join_req: Pointer to SME join request.
+ *
+ * Update PE context's rrm capability based on SME join request.
+ *
+ * Return: None
+ */
+void lim_update_rrm_capability(tpAniSirGlobal mac_ctx,
+			       tpSirSmeJoinReq join_req)
+{
+	mac_ctx->rrm.rrmPEContext.rrmEnable = join_req->rrm_config.rrm_enabled;
+	qdf_mem_copy(&mac_ctx->rrm.rrmPEContext.rrmEnabledCaps,
+		     &join_req->rrm_config.rm_capability,
+		     RMENABLEDCAP_MAX_LEN);
+
+	return;
+}
diff --git a/core/mac/src/pe/sch/sch_api.c b/core/mac/src/pe/sch/sch_api.c
new file mode 100644
index 0000000..f3185b7
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_api.c
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file sch_api.cc contains functions related to the API exposed
+ * by scheduler module
+ *
+ * Author:      Sandesh Goel
+ * Date:        02/25/02
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "ani_global.h"
+#include "wni_cfg.h"
+
+#include "sir_mac_prot_def.h"
+#include "sir_mac_prop_exts.h"
+#include "sir_common.h"
+
+#include "cfg_api.h"
+
+#include "lim_api.h"
+
+#include "sch_api.h"
+
+#include "lim_trace.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+
+#include "wma_types.h"
+
+/* -------------------------------------------------------------------- */
+/* */
+/*                          Static Variables */
+/* */
+/* -------------------------------------------------------------------- */
+/**
+ * sch_post_message
+ *
+ * FUNCTION:
+ * Post the beacon message to the scheduler message queue
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pMsg pointer to message
+ * @return None
+ */
+
+QDF_STATUS sch_post_message(tpAniSirGlobal pMac, struct scheduler_msg *pMsg)
+{
+	sch_process_message(pMac, pMsg);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sch_send_beacon_req(tpAniSirGlobal pMac, uint8_t *beaconPayload,
+			       uint16_t size, tpPESession psessionEntry,
+			       enum sir_bcn_update_reason reason)
+{
+	struct scheduler_msg msgQ = {0};
+	tpSendbeaconParams beaconParams = NULL;
+	QDF_STATUS retCode;
+
+	pe_debug("Indicating HAL to copy the beacon template [%d bytes] to memory, reason %d",
+		size, reason);
+
+	if (LIM_IS_AP_ROLE(psessionEntry) &&
+	   (pMac->sch.schObject.fBeaconChanged)) {
+		retCode = lim_send_probe_rsp_template_to_hal(pMac,
+				psessionEntry,
+				&psessionEntry->DefProbeRspIeBitmap[0]);
+		if (QDF_STATUS_SUCCESS != retCode)
+			pe_err("FAILED to send probe response template with retCode %d",
+				retCode);
+	}
+
+	beaconParams = qdf_mem_malloc(sizeof(tSendbeaconParams));
+	if (NULL == beaconParams)
+		return QDF_STATUS_E_NOMEM;
+
+	msgQ.type = WMA_SEND_BEACON_REQ;
+
+	/* No Dialog Token reqd, as a response is not solicited */
+	msgQ.reserved = 0;
+
+	/* Fill in tSendbeaconParams members */
+	qdf_mem_copy(beaconParams->bssId, psessionEntry->bssId,
+		     sizeof(psessionEntry->bssId));
+
+	if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+		beaconParams->timIeOffset = 0;
+	} else {
+		beaconParams->timIeOffset = psessionEntry->schBeaconOffsetBegin;
+		if (psessionEntry->dfsIncludeChanSwIe) {
+			beaconParams->csa_count_offset =
+				pMac->sch.schObject.csa_count_offset;
+			beaconParams->ecsa_count_offset =
+				pMac->sch.schObject.ecsa_count_offset;
+			pe_debug("csa_count_offset %d ecsa_count_offset %d",
+				 beaconParams->csa_count_offset,
+				 beaconParams->ecsa_count_offset);
+		}
+	}
+
+	beaconParams->vdev_id = psessionEntry->smeSessionId;
+	beaconParams->reason = reason;
+
+	/* p2pIeOffset should be atleast greater than timIeOffset */
+	if ((pMac->sch.schObject.p2pIeOffset != 0) &&
+	    (pMac->sch.schObject.p2pIeOffset <
+	     psessionEntry->schBeaconOffsetBegin)) {
+		pe_err("Invalid p2pIeOffset:[%d]",
+			pMac->sch.schObject.p2pIeOffset);
+		QDF_ASSERT(0);
+		qdf_mem_free(beaconParams);
+		return QDF_STATUS_E_FAILURE;
+	}
+	beaconParams->p2pIeOffset = pMac->sch.schObject.p2pIeOffset;
+#ifdef WLAN_SOFTAP_FW_BEACON_TX_PRNT_LOG
+	pe_err("TimIeOffset:[%d]", beaconParams->TimIeOffset);
+#endif
+
+	if (size >= SIR_MAX_BEACON_SIZE) {
+		pe_err("beacon size (%d) exceed host limit %d",
+		       size, SIR_MAX_BEACON_SIZE);
+		QDF_ASSERT(0);
+		qdf_mem_free(beaconParams);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_copy(beaconParams->beacon, beaconPayload, size);
+
+	beaconParams->beaconLength = (uint32_t) size;
+	msgQ.bodyptr = beaconParams;
+	msgQ.bodyval = 0;
+
+	/* Keep a copy of recent beacon frame sent */
+
+	/* free previous copy of the beacon */
+	if (psessionEntry->beacon) {
+		qdf_mem_free(psessionEntry->beacon);
+	}
+
+	psessionEntry->bcnLen = 0;
+	psessionEntry->beacon = NULL;
+
+	psessionEntry->beacon = qdf_mem_malloc(size);
+	if (psessionEntry->beacon != NULL) {
+		qdf_mem_copy(psessionEntry->beacon, beaconPayload, size);
+		psessionEntry->bcnLen = size;
+	}
+
+	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+	retCode = wma_post_ctrl_msg(pMac, &msgQ);
+	if (QDF_STATUS_SUCCESS != retCode)
+		pe_err("Posting SEND_BEACON_REQ to HAL failed, reason=%X",
+			retCode);
+	else
+		pe_debug("Successfully posted WMA_SEND_BEACON_REQ to HAL");
+
+	return retCode;
+}
+
+static uint32_t lim_remove_p2p_ie_from_add_ie(tpAniSirGlobal pMac,
+					      tpPESession psessionEntry,
+					      uint8_t *addIeWoP2pIe,
+					      uint32_t *addnIELenWoP2pIe)
+{
+	uint32_t left = psessionEntry->addIeParams.probeRespDataLen;
+	uint8_t *ptr = psessionEntry->addIeParams.probeRespData_buff;
+	uint8_t elem_id, elem_len;
+	uint32_t offset = 0;
+	uint8_t eid = 0xDD;
+
+	qdf_mem_copy(addIeWoP2pIe, ptr, left);
+	*addnIELenWoP2pIe = left;
+
+	if (addIeWoP2pIe != NULL) {
+		while (left >= 2) {
+			elem_id  = ptr[0];
+			elem_len = ptr[1];
+			left -= 2;
+			if (elem_len > left) {
+				pe_err("Invalid IEs");
+				return QDF_STATUS_E_FAILURE;
+			}
+			if ((elem_id == eid) &&
+				(!qdf_mem_cmp(&ptr[2],
+					"\x50\x6f\x9a\x09", 4))) {
+				left -= elem_len;
+				ptr += (elem_len + 2);
+				qdf_mem_copy(&addIeWoP2pIe[offset], ptr, left);
+				*addnIELenWoP2pIe -= (2 + elem_len);
+			} else {
+				left -= elem_len;
+				ptr += (elem_len + 2);
+				offset += 2 + elem_len;
+			}
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal pMac,
+					    tpPESession psessionEntry,
+					    uint32_t *IeBitmap)
+{
+	struct scheduler_msg msgQ = {0};
+	uint8_t *pFrame2Hal = psessionEntry->pSchProbeRspTemplate;
+	tpSendProbeRespParams pprobeRespParams = NULL;
+	uint32_t retCode = QDF_STATUS_E_FAILURE;
+	uint32_t nPayload, nBytes = 0, nStatus;
+	tpSirMacMgmtHdr pMacHdr;
+	uint32_t addnIEPresent = false;
+	uint8_t *addIE = NULL;
+	uint8_t *addIeWoP2pIe = NULL;
+	uint32_t addnIELenWoP2pIe = 0;
+	uint32_t retStatus;
+	tDot11fIEExtCap extracted_extcap;
+	bool extcap_present = false;
+	tDot11fProbeResponse *prb_rsp_frm;
+	QDF_STATUS status;
+	uint16_t addn_ielen = 0;
+
+	/* Check if probe response IE is present or not */
+	addnIEPresent = (psessionEntry->addIeParams.probeRespDataLen != 0);
+	if (addnIEPresent) {
+		/*
+		* probe response template should not have P2P IE.
+		* In case probe request has P2P IE or WPS IE, the
+		* probe request will be forwarded to the Host and
+		* Host will send the probe response. In other cases
+		* FW will send the probe response. So, if the template
+		* has P2P IE, the probe response sent to non P2P devices
+		* by the FW, may also have P2P IE which will fail
+		* P2P cert case 6.1.3
+		*/
+		addIeWoP2pIe = qdf_mem_malloc(psessionEntry->addIeParams.
+						probeRespDataLen);
+		if (NULL == addIeWoP2pIe) {
+			pe_err("FAILED to alloc memory when removing P2P IE");
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		retStatus = lim_remove_p2p_ie_from_add_ie(pMac, psessionEntry,
+					addIeWoP2pIe, &addnIELenWoP2pIe);
+		if (retStatus != QDF_STATUS_SUCCESS) {
+			qdf_mem_free(addIeWoP2pIe);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		/* Probe rsp IE available */
+		/*need to check the data length */
+		addIE = qdf_mem_malloc(addnIELenWoP2pIe);
+		if (NULL == addIE) {
+			pe_err("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length");
+			qdf_mem_free(addIeWoP2pIe);
+			return QDF_STATUS_E_NOMEM;
+		}
+		addn_ielen = addnIELenWoP2pIe;
+
+		if (addn_ielen <= WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN &&
+		    addn_ielen && (nBytes + addn_ielen) <= SIR_MAX_PACKET_SIZE)
+			qdf_mem_copy(addIE, addIeWoP2pIe, addnIELenWoP2pIe);
+
+		qdf_mem_free(addIeWoP2pIe);
+
+		qdf_mem_zero((uint8_t *)&extracted_extcap,
+			     sizeof(tDot11fIEExtCap));
+		status = lim_strip_extcap_update_struct(pMac, addIE,
+				&addn_ielen, &extracted_extcap);
+		if (QDF_STATUS_SUCCESS != status) {
+			pe_debug("extcap not extracted");
+		} else {
+			extcap_present = true;
+		}
+	}
+
+	if (addnIEPresent) {
+		if ((nBytes + addn_ielen) <= SIR_MAX_PACKET_SIZE)
+			nBytes += addn_ielen;
+		else
+			addnIEPresent = false;  /* Dont include the IE. */
+	}
+
+	/*
+	 * Extcap IE now support variable length, merge Extcap IE from addn_ie
+	 * may change the frame size. Therefore, MUST merge ExtCap IE before
+	 * dot11f get packed payload size.
+	 */
+	prb_rsp_frm = &psessionEntry->probeRespFrame;
+	if (extcap_present)
+		lim_merge_extcap_struct(&prb_rsp_frm->ExtCap,
+					&extracted_extcap,
+					true);
+
+	nStatus = dot11f_get_packed_probe_response_size(pMac,
+			&psessionEntry->probeRespFrame, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to calculate the packed size for a Probe Response (0x%08x)",
+			nStatus);
+		/* We'll fall back on the worst case scenario: */
+		nPayload = sizeof(tDot11fProbeResponse);
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_err("There were warnings while calculating the packed size for a Probe Response (0x%08x)",
+			nStatus);
+	}
+
+	nBytes += nPayload + sizeof(tSirMacMgmtHdr);
+
+	/* Make sure we are not exceeding allocated len */
+	if (nBytes > SIR_MAX_PROBE_RESP_SIZE) {
+		pe_err("nBytes %d greater than max size", nBytes);
+		qdf_mem_free(addIE);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Paranoia: */
+	qdf_mem_set(pFrame2Hal, nBytes, 0);
+
+	/* Next, we fill out the buffer descriptor: */
+	lim_populate_mac_header(pMac, pFrame2Hal, SIR_MAC_MGMT_FRAME,
+					     SIR_MAC_MGMT_PROBE_RSP,
+					     psessionEntry->selfMacAddr,
+					     psessionEntry->selfMacAddr);
+
+	pMacHdr = (tpSirMacMgmtHdr) pFrame2Hal;
+
+	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+	/* That done, pack the Probe Response: */
+	nStatus =
+		dot11f_pack_probe_response(pMac, &psessionEntry->probeRespFrame,
+					   pFrame2Hal + sizeof(tSirMacMgmtHdr),
+					   nPayload, &nPayload);
+
+	if (DOT11F_FAILED(nStatus)) {
+		pe_err("Failed to pack a Probe Response (0x%08x)",
+			nStatus);
+
+		qdf_mem_free(addIE);
+		return retCode; /* allocated! */
+	} else if (DOT11F_WARNED(nStatus)) {
+		pe_warn("There were warnings while packing a P"
+			"robe Response (0x%08x)", nStatus);
+	}
+
+	if (addnIEPresent) {
+		qdf_mem_copy(&pFrame2Hal[nBytes - addn_ielen],
+			     &addIE[0], addn_ielen);
+	}
+
+	qdf_mem_free(addIE);
+
+	pprobeRespParams = qdf_mem_malloc(sizeof(tSendProbeRespParams));
+	if (NULL == pprobeRespParams) {
+		pe_err("malloc failed for bytes %d", nBytes);
+	} else {
+		sir_copy_mac_addr(pprobeRespParams->bssId, psessionEntry->bssId);
+		qdf_mem_copy(pprobeRespParams->probeRespTemplate,
+			     pFrame2Hal, nBytes);
+		pprobeRespParams->probeRespTemplateLen = nBytes;
+		qdf_mem_copy(pprobeRespParams->ucProxyProbeReqValidIEBmap,
+			     IeBitmap, (sizeof(uint32_t) * 8));
+		msgQ.type = WMA_SEND_PROBE_RSP_TMPL;
+		msgQ.reserved = 0;
+		msgQ.bodyptr = pprobeRespParams;
+		msgQ.bodyval = 0;
+
+		retCode = wma_post_ctrl_msg(pMac, &msgQ);
+		if (QDF_STATUS_SUCCESS != retCode) {
+			pe_err("FAIL bytes %d retcode[%X]", nBytes, retCode);
+			qdf_mem_free(pprobeRespParams);
+		} else {
+			pe_debug("Probe response template msg posted to HAL of bytes %d",
+				nBytes);
+		}
+	}
+
+	return retCode;
+}
+
+/**
+ * sch_gen_timing_advert_frame() - Generate the TA frame and populate the buffer
+ * @pMac: the global MAC context
+ * @self_addr: the self MAC address
+ * @buf: the buffer that will contain the frame
+ * @timestamp_offset: return for the offset of the timestamp field
+ * @time_value_offset: return for the time_value field in the TA IE
+ *
+ * Return: the length of the buffer.
+ */
+int sch_gen_timing_advert_frame(tpAniSirGlobal mac_ctx, tSirMacAddr self_addr,
+	uint8_t **buf, uint32_t *timestamp_offset, uint32_t *time_value_offset)
+{
+	tDot11fTimingAdvertisementFrame frame;
+	uint32_t payload_size, buf_size;
+	int status;
+	struct qdf_mac_addr wildcard_bssid = {
+		{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+	};
+
+	qdf_mem_zero((uint8_t *)&frame, sizeof(tDot11fTimingAdvertisementFrame));
+
+	/* Populate the TA fields */
+	status = populate_dot11f_timing_advert_frame(mac_ctx, &frame);
+	if (status) {
+		pe_err("Error populating TA frame %x", status);
+		return status;
+	}
+
+	status = dot11f_get_packed_timing_advertisement_frame_size(mac_ctx,
+		&frame, &payload_size);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Error getting packed frame size %x", status);
+		return status;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("Warning getting packed frame size");
+	}
+
+	buf_size = sizeof(tSirMacMgmtHdr) + payload_size;
+	*buf = qdf_mem_malloc(buf_size);
+	if (*buf == NULL) {
+		pe_err("Cannot allocate memory");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	payload_size = 0;
+	status = dot11f_pack_timing_advertisement_frame(mac_ctx, &frame,
+		*buf + sizeof(tSirMacMgmtHdr), buf_size -
+		sizeof(tSirMacMgmtHdr), &payload_size);
+	pe_err("TA payload size2 = %d", payload_size);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Error packing frame %x", status);
+		goto fail;
+	} else if (DOT11F_WARNED(status)) {
+		pe_warn("Warning packing frame");
+	}
+
+	lim_populate_mac_header(mac_ctx, *buf, SIR_MAC_MGMT_FRAME,
+		SIR_MAC_MGMT_TIME_ADVERT, wildcard_bssid.bytes, self_addr);
+
+	/* The timestamp field is right after the header */
+	*timestamp_offset = sizeof(tSirMacMgmtHdr);
+
+	*time_value_offset = sizeof(tSirMacMgmtHdr) +
+		sizeof(tDot11fFfTimeStamp) + sizeof(tDot11fFfCapabilities);
+
+	/* Add the Country IE length */
+	dot11f_get_packed_ie_country(mac_ctx, &frame.Country,
+		time_value_offset);
+	/* Add 2 for Country IE EID and Length fields */
+	*time_value_offset += 2;
+
+	/* Add the PowerConstraint IE size */
+	if (frame.Country.present == 1)
+		*time_value_offset += 3;
+
+	/* Add the offset inside TA IE */
+	*time_value_offset += 3;
+
+	return payload_size + sizeof(tSirMacMgmtHdr);
+
+fail:
+	if (*buf)
+		qdf_mem_free(*buf);
+	return status;
+}
diff --git a/core/mac/src/pe/sch/sch_beacon_gen.c b/core/mac/src/pe/sch/sch_beacon_gen.c
new file mode 100644
index 0000000..537450c
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_beacon_gen.c
@@ -0,0 +1,1065 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file sch_beacon_gen.cc contains beacon generation related
+ * functions
+ *
+ * Author:      Sandesh Goel
+ * Date:        02/25/02
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "cds_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "sir_mac_prot_def.h"
+
+#include "lim_utils.h"
+#include "lim_api.h"
+
+#include "wma_if.h"
+#include "cfg_api.h"
+#include "sch_api.h"
+
+#include "parser_api.h"
+#include "wlan_utility.h"
+
+/* Offset of Channel Switch count field in CSA/ECSA IE */
+#define SCH_CSA_SWITCH_COUNT_OFFSET 2
+#define SCH_ECSA_SWITCH_COUNT_OFFSET 3
+
+const uint8_t p2p_oui[] = { 0x50, 0x6F, 0x9A, 0x9 };
+
+static QDF_STATUS sch_get_p2p_ie_offset(uint8_t *pextra_ie,
+					uint32_t extra_ie_len,
+					uint16_t *pie_offset)
+{
+	uint8_t elem_id;
+	uint8_t elem_len;
+	uint8_t *ie_ptr = pextra_ie;
+	uint8_t oui_size = sizeof(p2p_oui);
+	uint32_t p2p_ie_offset = 0;
+	uint32_t left_len = extra_ie_len;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	*pie_offset = 0;
+	while (left_len > 2) {
+		elem_id  = ie_ptr[0];
+		elem_len = ie_ptr[1];
+		left_len -= 2;
+
+		if (elem_len > left_len)
+			return status;
+
+		if ((elem_id == 0xDD) && (elem_len >= oui_size)) {
+			if (!qdf_mem_cmp(&ie_ptr[2], &p2p_oui, oui_size)) {
+				*pie_offset = p2p_ie_offset;
+				return QDF_STATUS_SUCCESS;
+			}
+		}
+
+		left_len -= elem_len;
+		ie_ptr += (elem_len + 2);
+		p2p_ie_offset += (elem_len + 2);
+	};
+
+	return status;
+}
+
+/**
+ * sch_append_addn_ie() - adds additional IEs to frame
+ * @mac_ctx:       mac global context
+ * @session:       pe session pointer
+ * @frm:           frame where additional IE is to be added
+ * @max_bcn_size:  max beacon size
+ * @num_bytes:     final size
+ * @addn_ie:       pointer to additional IE
+ * @addn_ielen:    length of additional IE
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS
+sch_append_addn_ie(tpAniSirGlobal mac_ctx, tpPESession session,
+		   uint8_t *frm, uint32_t max_bcn_size, uint32_t *num_bytes,
+		   uint8_t *addn_ie, uint16_t addn_ielen)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint8_t add_ie[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN];
+	uint8_t *p2p_ie = NULL;
+	uint8_t noa_len = 0;
+	uint8_t noa_strm[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
+	uint8_t ext_p2p_ie[DOT11F_IE_P2PBEACON_MAX_LEN + 2];
+	bool valid_ie;
+
+	valid_ie = (addn_ielen <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN &&
+		    addn_ielen && ((addn_ielen + *num_bytes) <= max_bcn_size));
+
+	if (!valid_ie)
+		return status;
+
+	qdf_mem_zero(&ext_p2p_ie[0], DOT11F_IE_P2PBEACON_MAX_LEN + 2);
+	/*
+	 * P2P IE extracted in wlan_hdd_add_hostapd_conf_vsie may not
+	 * be at the end of additional IE buffer. The buffer sent to WMA
+	 * expect P2P IE at the end of beacon buffer and will result in
+	 * beacon corruption if P2P IE is not at end of beacon buffer.
+	 */
+	status = lim_strip_ie(mac_ctx, addn_ie, &addn_ielen, SIR_MAC_EID_VENDOR,
+			      ONE_BYTE, SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE,
+			      ext_p2p_ie, DOT11F_IE_P2PBEACON_MAX_LEN);
+
+	qdf_mem_copy(&add_ie[0], addn_ie, addn_ielen);
+
+	if (status == QDF_STATUS_SUCCESS &&
+	    ext_p2p_ie[0] == SIR_MAC_EID_VENDOR &&
+	    !qdf_mem_cmp(&ext_p2p_ie[2], SIR_MAC_P2P_OUI,
+			 SIR_MAC_P2P_OUI_SIZE)) {
+		qdf_mem_copy(&add_ie[addn_ielen], ext_p2p_ie,
+			     ext_p2p_ie[1] + 2);
+		addn_ielen += ext_p2p_ie[1] + 2;
+	}
+
+	p2p_ie = (uint8_t *)limGetP2pIEPtr(mac_ctx, &add_ie[0], addn_ielen);
+	if ((p2p_ie != NULL) && !mac_ctx->beacon_offload) {
+		/* get NoA attribute stream P2P IE */
+		noa_len = lim_get_noa_attr_stream(mac_ctx, noa_strm, session);
+		if (noa_len) {
+			if ((noa_len + addn_ielen) <=
+			    WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) {
+				qdf_mem_copy(&add_ie[addn_ielen], noa_strm,
+					     noa_len);
+				addn_ielen += noa_len;
+				p2p_ie[1] += noa_len;
+			} else {
+				pe_err("Not able to insert NoA because of length constraint");
+			}
+		}
+	}
+	if (addn_ielen <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) {
+		qdf_mem_copy(frm, &add_ie[0], addn_ielen);
+		*num_bytes = *num_bytes + addn_ielen;
+	} else {
+		pe_warn("Not able to insert because of len constraint %d",
+			addn_ielen);
+	}
+	return status;
+}
+
+/**
+ * sch_get_csa_ecsa_count_offset() - get the offset of Switch count field
+ * @ie: pointer to the beggining of IEs in the beacon frame buffer
+ * @ie_len: length of the IEs in the buffer
+ * @csa_count_offset: pointer to the csa_count_offset variable in the caller
+ * @ecsa_count_offset: pointer to the ecsa_count_offset variable in the caller
+ *
+ * Gets the offset of the switch count field in the CSA/ECSA IEs from the start
+ * of the IEs buffer.
+ *
+ * Return: None
+ */
+static void sch_get_csa_ecsa_count_offset(uint8_t *ie, uint32_t ie_len,
+					  uint32_t *csa_count_offset,
+					  uint32_t *ecsa_count_offset)
+{
+	uint8_t *ptr = ie;
+	uint8_t elem_id;
+	uint16_t elem_len;
+	uint32_t offset = 0;
+
+	/* IE is not present */
+	if (!ie_len)
+		return;
+
+	while (ie_len >= 2) {
+		elem_id = ptr[0];
+		elem_len = ptr[1];
+		ie_len -= 2;
+		offset += 2;
+
+		if (elem_id == DOT11F_EID_CHANSWITCHANN &&
+		    elem_len == 3)
+			*csa_count_offset = offset +
+					SCH_CSA_SWITCH_COUNT_OFFSET;
+
+		if (elem_id == DOT11F_EID_EXT_CHAN_SWITCH_ANN &&
+		    elem_len == 4)
+			*ecsa_count_offset = offset +
+					SCH_ECSA_SWITCH_COUNT_OFFSET;
+
+		ie_len -= elem_len;
+		offset += elem_len;
+		ptr += (elem_len + 2);
+	}
+}
+
+/**
+ * sch_set_fixed_beacon_fields() - sets the fixed params in beacon frame
+ * @mac_ctx:       mac global context
+ * @session:       pe session entry
+ * @band:          out param, band caclculated
+ * @opr_ch:        operating channels
+ *
+ * Return: status of operation
+ */
+
+QDF_STATUS
+sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+	tpAniBeaconStruct bcn_struct = (tpAniBeaconStruct)
+						session->pSchBeaconFrameBegin;
+	tpSirMacMgmtHdr mac;
+	uint16_t offset;
+	uint8_t *ptr;
+	tDot11fBeacon1 *bcn_1;
+	tDot11fBeacon2 *bcn_2;
+	uint32_t i, n_status, n_bytes;
+	bool wps_ap_enable = 0;
+	tDot11fIEWscProbeRes *wsc_prb_res;
+	uint8_t *extra_ie = NULL;
+	uint32_t extra_ie_len = 0;
+	uint16_t extra_ie_offset = 0;
+	uint16_t p2p_ie_offset = 0;
+	uint32_t csa_count_offset = 0;
+	uint32_t ecsa_count_offset = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	bool is_vht_enabled = false;
+	uint16_t addn_ielen = 0;
+	uint8_t *addn_ie = NULL;
+	tDot11fIEExtCap extracted_extcap;
+	bool extcap_present = true, addnie_present = false;
+
+	bcn_1 = qdf_mem_malloc(sizeof(tDot11fBeacon1));
+	if (!bcn_1)
+		return QDF_STATUS_E_NOMEM;
+
+	bcn_2 = qdf_mem_malloc(sizeof(tDot11fBeacon2));
+	if (!bcn_2) {
+		qdf_mem_free(bcn_1);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	wsc_prb_res = qdf_mem_malloc(sizeof(tDot11fIEWscProbeRes));
+	if (!wsc_prb_res) {
+		qdf_mem_free(bcn_1);
+		qdf_mem_free(bcn_2);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	pe_debug("Setting fixed beacon fields");
+
+	/*
+	 * First set the fixed fields:
+	 * set the TFP headers, set the mac header
+	 */
+	qdf_mem_set((uint8_t *) &bcn_struct->macHdr, sizeof(tSirMacMgmtHdr), 0);
+	mac = (tpSirMacMgmtHdr) &bcn_struct->macHdr;
+	mac->fc.type = SIR_MAC_MGMT_FRAME;
+	mac->fc.subType = SIR_MAC_MGMT_BEACON;
+
+	for (i = 0; i < 6; i++)
+		mac->da[i] = 0xff;
+
+	qdf_mem_copy(mac->sa, session->selfMacAddr,
+		     sizeof(session->selfMacAddr));
+	qdf_mem_copy(mac->bssId, session->bssId, sizeof(session->bssId));
+
+	mac->fc.fromDS = 0;
+	mac->fc.toDS = 0;
+
+	/* Skip over the timestamp (it'll be updated later). */
+	bcn_1->BeaconInterval.interval =
+		session->beaconParams.beaconInterval;
+	populate_dot11f_capabilities(mac_ctx, &bcn_1->Capabilities, session);
+	if (session->ssidHidden) {
+		bcn_1->SSID.present = 1;
+		/* rest of the fileds are 0 for hidden ssid */
+		if ((session->ssId.length) &&
+		    (session->ssidHidden == eHIDDEN_SSID_ZERO_CONTENTS))
+			bcn_1->SSID.num_ssid = session->ssId.length;
+	} else {
+		populate_dot11f_ssid(mac_ctx, &session->ssId, &bcn_1->SSID);
+	}
+
+	populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
+				   &bcn_1->SuppRates, session);
+	populate_dot11f_ds_params(mac_ctx, &bcn_1->DSParams,
+				  session->currentOperChannel);
+	populate_dot11f_ibss_params(mac_ctx, &bcn_1->IBSSParams, session);
+
+	offset = sizeof(tAniBeaconStruct);
+	ptr = session->pSchBeaconFrameBegin + offset;
+
+	if (LIM_IS_AP_ROLE(session)) {
+		/* Initialize the default IE bitmap to zero */
+		qdf_mem_set((uint8_t *) &(session->DefProbeRspIeBitmap),
+			    (sizeof(uint32_t) * 8), 0);
+
+		/* Initialize the default IE bitmap to zero */
+		qdf_mem_set((uint8_t *) &(session->probeRespFrame),
+			    sizeof(session->probeRespFrame), 0);
+
+		/*
+		 * Can be efficiently updated whenever new IE added in Probe
+		 * response in future
+		 */
+		if (lim_update_probe_rsp_template_ie_bitmap_beacon1(mac_ctx,
+					bcn_1, session) != QDF_STATUS_SUCCESS)
+			pe_err("Failed to build ProbeRsp template");
+	}
+
+	n_status = dot11f_pack_beacon1(mac_ctx, bcn_1, ptr,
+				       SIR_MAX_BEACON_SIZE - offset, &n_bytes);
+	if (DOT11F_FAILED(n_status)) {
+		pe_err("Failed to packed a tDot11fBeacon1 (0x%08x)",
+			n_status);
+		qdf_mem_free(bcn_1);
+		qdf_mem_free(bcn_2);
+		qdf_mem_free(wsc_prb_res);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(n_status)) {
+		pe_warn("Warnings while packing a tDot11fBeacon1(0x%08x)",
+			n_status);
+	}
+	session->schBeaconOffsetBegin = offset + (uint16_t) n_bytes;
+	pe_debug("Initialized beacon begin, offset %d", offset);
+
+	/* Initialize the 'new' fields at the end of the beacon */
+
+	if ((session->limSystemRole == eLIM_AP_ROLE) &&
+	    session->dfsIncludeChanSwIe == true) {
+		if (!CHAN_HOP_ALL_BANDS_ENABLE ||
+		    session->lim_non_ecsa_cap_num == 0) {
+			tDot11fIEext_chan_switch_ann *ext_csa =
+						&bcn_2->ext_chan_switch_ann;
+			populate_dot_11_f_ext_chann_switch_ann(mac_ctx,
+							       ext_csa,
+							       session);
+			pe_debug("ecsa: mode:%d reg:%d chan:%d count:%d",
+				 ext_csa->switch_mode,
+				 ext_csa->new_reg_class,
+				 ext_csa->new_channel,
+				 ext_csa->switch_count);
+		} else {
+			populate_dot11f_chan_switch_ann(mac_ctx,
+							&bcn_2->ChanSwitchAnn,
+							session);
+			pe_debug("csa: mode:%d chan:%d count:%d",
+				 bcn_2->ChanSwitchAnn.switchMode,
+				 bcn_2->ChanSwitchAnn.newChannel,
+				 bcn_2->ChanSwitchAnn.switchCount);
+		}
+	}
+
+	populate_dot11_supp_operating_classes(mac_ctx,
+		&bcn_2->SuppOperatingClasses, session);
+	populate_dot11f_country(mac_ctx, &bcn_2->Country, session);
+	if (bcn_1->Capabilities.qos)
+		populate_dot11f_edca_param_set(mac_ctx, &bcn_2->EDCAParamSet,
+					       session);
+
+	if (session->lim11hEnable) {
+		populate_dot11f_power_constraints(mac_ctx,
+						  &bcn_2->PowerConstraints);
+		populate_dot11f_tpc_report(mac_ctx, &bcn_2->TPCReport, session);
+		/* Need to insert channel switch announcement here */
+		if ((LIM_IS_AP_ROLE(session)
+		    || LIM_IS_P2P_DEVICE_GO(session))
+			&& session->dfsIncludeChanSwIe == true) {
+			/*
+			 * Channel switch announcement only if radar is detected
+			 * and SAP has instructed to announce channel switch IEs
+			 * in beacon and probe responses
+			 */
+			populate_dot11f_chan_switch_ann(mac_ctx,
+						&bcn_2->ChanSwitchAnn, session);
+			pe_debug("csa: mode:%d chan:%d count:%d",
+				 bcn_2->ChanSwitchAnn.switchMode,
+				 bcn_2->ChanSwitchAnn.newChannel,
+				 bcn_2->ChanSwitchAnn.switchCount);
+			/*
+			 * TODO: depending the CB mode, extended channel switch
+			 * announcement need to be called
+			 */
+			/*
+			populate_dot11f_ext_chan_switch_ann(mac_ctx,
+					&bcn_2->ExtChanSwitchAnn, session);
+			*/
+			/*
+			 * TODO: If in 11AC mode, wider bw channel switch
+			 * announcement needs to be called
+			 */
+			/*
+			populate_dot11f_wider_bw_chan_switch_ann(mac_ctx,
+					&bcn_2->WiderBWChanSwitchAnn, session);
+			*/
+			/*
+			 * Populate the Channel Switch Wrapper Element if
+			 * SAP operates in 40/80 Mhz Channel Width.
+			 */
+			if (true == session->dfsIncludeChanWrapperIe) {
+				populate_dot11f_chan_switch_wrapper(mac_ctx,
+					&bcn_2->ChannelSwitchWrapper, session);
+				pe_debug("wrapper: width:%d f0:%d f1:%d",
+				      bcn_2->ChannelSwitchWrapper.
+					WiderBWChanSwitchAnn.newChanWidth,
+				      bcn_2->ChannelSwitchWrapper.
+					WiderBWChanSwitchAnn.newCenterChanFreq0,
+				      bcn_2->ChannelSwitchWrapper.
+					WiderBWChanSwitchAnn.newCenterChanFreq1
+					);
+			}
+		}
+	}
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	/* populate proprietary IE for MDM device operating in AP-MCC */
+	populate_dot11f_avoid_channel_ie(mac_ctx, &bcn_2->QComVendorIE,
+					 session);
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+	if (session->dot11mode != WNI_CFG_DOT11_MODE_11B)
+		populate_dot11f_erp_info(mac_ctx, &bcn_2->ERPInfo, session);
+
+	if (session->htCapability) {
+		populate_dot11f_ht_caps(mac_ctx, session, &bcn_2->HTCaps);
+		populate_dot11f_ht_info(mac_ctx, &bcn_2->HTInfo, session);
+	}
+	if (session->vhtCapability) {
+		pe_debug("Populate VHT IEs in Beacon");
+		populate_dot11f_vht_caps(mac_ctx, session, &bcn_2->VHTCaps);
+		populate_dot11f_vht_operation(mac_ctx, session,
+					      &bcn_2->VHTOperation);
+		is_vht_enabled = true;
+		/* following is for MU MIMO: we do not support it yet */
+		/*
+		populate_dot11f_vht_ext_bss_load( mac_ctx, &bcn2.VHTExtBssLoad);
+		*/
+	}
+
+	if (lim_is_session_he_capable(session)) {
+		pe_warn("Populate HE IEs");
+		populate_dot11f_he_caps(mac_ctx, session,
+					&bcn_2->he_cap);
+		populate_dot11f_he_operation(mac_ctx, session,
+					&bcn_2->he_op);
+		populate_dot11f_he_bss_color_change(mac_ctx, session,
+					&bcn_2->bss_color_change);
+	}
+
+	if (session->limSystemRole != eLIM_STA_IN_IBSS_ROLE)
+		populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &bcn_2->ExtCap,
+					session);
+	populate_dot11f_ext_supp_rates(mac_ctx,
+				POPULATE_DOT11F_RATES_OPERATIONAL,
+				&bcn_2->ExtSuppRates, session);
+
+	if (session->pLimStartBssReq != NULL) {
+		populate_dot11f_wpa(mac_ctx, &session->pLimStartBssReq->rsnIE,
+				    &bcn_2->WPA);
+		populate_dot11f_rsn_opaque(mac_ctx,
+					   &session->pLimStartBssReq->rsnIE,
+					   &bcn_2->RSNOpaque);
+	}
+
+	if (session->limWmeEnabled)
+		populate_dot11f_wmm(mac_ctx, &bcn_2->WMMInfoAp,
+				&bcn_2->WMMParams, &bcn_2->WMMCaps, session);
+	if (LIM_IS_AP_ROLE(session)) {
+		if (session->wps_state != SAP_WPS_DISABLED) {
+			populate_dot11f_beacon_wpsi_es(mac_ctx,
+						&bcn_2->WscBeacon, session);
+		}
+	} else {
+		wps_ap_enable = mac_ctx->mlme_cfg->wps_params.enable_wps &
+					    WNI_CFG_WPS_ENABLE_AP;
+		if (wps_ap_enable)
+			populate_dot11f_wsc(mac_ctx, &bcn_2->WscBeacon);
+
+		if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
+						eLIM_WSC_ENROLL_BEGIN) {
+			populate_dot11f_wsc_registrar_info(mac_ctx,
+						&bcn_2->WscBeacon);
+			mac_ctx->lim.wscIeInfo.wscEnrollmentState =
+						eLIM_WSC_ENROLL_IN_PROGRESS;
+		}
+
+		if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
+						eLIM_WSC_ENROLL_END) {
+			de_populate_dot11f_wsc_registrar_info(mac_ctx,
+							&bcn_2->WscBeacon);
+			mac_ctx->lim.wscIeInfo.wscEnrollmentState =
+							eLIM_WSC_ENROLL_NOOP;
+		}
+	}
+
+	if (LIM_IS_AP_ROLE(session)) {
+		/*
+		 * Can be efficiently updated whenever new IE added  in Probe
+		 * response in future
+		 */
+		lim_update_probe_rsp_template_ie_bitmap_beacon2(mac_ctx, bcn_2,
+					&session->DefProbeRspIeBitmap[0],
+					&session->probeRespFrame);
+
+		/* update probe response WPS IE instead of beacon WPS IE */
+		if (session->wps_state != SAP_WPS_DISABLED) {
+			if (session->APWPSIEs.SirWPSProbeRspIE.FieldPresent)
+				populate_dot11f_probe_res_wpsi_es(mac_ctx,
+							wsc_prb_res, session);
+			else
+				wsc_prb_res->present = 0;
+			if (wsc_prb_res->present) {
+				set_probe_rsp_ie_bitmap(
+					&session->DefProbeRspIeBitmap[0],
+					SIR_MAC_WPA_EID);
+				qdf_mem_copy((void *)
+					&session->probeRespFrame.WscProbeRes,
+					(void *)wsc_prb_res,
+					sizeof(tDot11fIEWscProbeRes));
+			}
+		}
+
+	}
+
+	addnie_present = (session->addIeParams.probeRespBCNDataLen != 0);
+	if (addnie_present) {
+		addn_ielen = session->addIeParams.probeRespBCNDataLen;
+		addn_ie = qdf_mem_malloc(addn_ielen);
+		if (!addn_ie) {
+			qdf_mem_free(bcn_1);
+			qdf_mem_free(bcn_2);
+			qdf_mem_free(wsc_prb_res);
+			return QDF_STATUS_E_NOMEM;
+		}
+		qdf_mem_copy(addn_ie,
+			session->addIeParams.probeRespBCNData_buff,
+			addn_ielen);
+
+		qdf_mem_zero((uint8_t *)&extracted_extcap,
+			     sizeof(tDot11fIEExtCap));
+		status = lim_strip_extcap_update_struct(mac_ctx, addn_ie,
+				&addn_ielen, &extracted_extcap);
+		if (QDF_STATUS_SUCCESS != status) {
+			extcap_present = false;
+			pe_debug("extcap not extracted");
+		}
+		/* merge extcap IE */
+		if (extcap_present &&
+			session->limSystemRole != eLIM_STA_IN_IBSS_ROLE)
+			lim_merge_extcap_struct(&bcn_2->ExtCap,
+						&extracted_extcap,
+						true);
+
+	}
+
+	if (session->vhtCapability && session->gLimOperatingMode.present) {
+		populate_dot11f_operating_mode(mac_ctx, &bcn_2->OperatingMode,
+					       session);
+		lim_strip_ie(mac_ctx, addn_ie, &addn_ielen,
+			     SIR_MAC_VHT_OPMODE_EID, ONE_BYTE, NULL, 0,
+			     NULL, SIR_MAC_VHT_OPMODE_SIZE - 2);
+	}
+
+	n_status = dot11f_pack_beacon2(mac_ctx, bcn_2,
+				       session->pSchBeaconFrameEnd,
+				       SIR_MAX_BEACON_SIZE, &n_bytes);
+	if (DOT11F_FAILED(n_status)) {
+		pe_err("Failed to packed a tDot11fBeacon2 (0x%08x)",
+			n_status);
+		qdf_mem_free(bcn_1);
+		qdf_mem_free(bcn_2);
+		qdf_mem_free(wsc_prb_res);
+		qdf_mem_free(addn_ie);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(n_status)) {
+		pe_err("Warnings while packing a tDot11fBeacon2(0x%08x)",
+			n_status);
+	}
+
+	/* Fill the CSA/ECSA count offsets if the IEs are present */
+	if (session->dfsIncludeChanSwIe)
+		sch_get_csa_ecsa_count_offset(session->pSchBeaconFrameEnd,
+					      n_bytes,
+					      &csa_count_offset,
+					      &ecsa_count_offset);
+
+	if (csa_count_offset)
+		mac_ctx->sch.schObject.csa_count_offset =
+				session->schBeaconOffsetBegin + TIM_IE_SIZE +
+				csa_count_offset;
+	if (ecsa_count_offset)
+		mac_ctx->sch.schObject.ecsa_count_offset =
+				session->schBeaconOffsetBegin + TIM_IE_SIZE +
+				ecsa_count_offset;
+
+	pe_debug("csa_count_offset %d ecsa_count_offset %d",
+		 mac_ctx->sch.schObject.csa_count_offset,
+		 mac_ctx->sch.schObject.ecsa_count_offset);
+
+	extra_ie = session->pSchBeaconFrameEnd + n_bytes;
+	extra_ie_offset = n_bytes;
+
+	/* TODO: Append additional IE here. */
+	if (addn_ielen > 0)
+		sch_append_addn_ie(mac_ctx, session,
+				   session->pSchBeaconFrameEnd + n_bytes,
+				   SIR_MAX_BEACON_SIZE, &n_bytes,
+				   addn_ie, addn_ielen);
+
+	session->schBeaconOffsetEnd = (uint16_t) n_bytes;
+	extra_ie_len = n_bytes - extra_ie_offset;
+	/* Get the p2p Ie Offset */
+	status = sch_get_p2p_ie_offset(extra_ie, extra_ie_len, &p2p_ie_offset);
+	if (QDF_STATUS_SUCCESS == status)
+		/* Update the P2P Ie Offset */
+		mac_ctx->sch.schObject.p2pIeOffset =
+			session->schBeaconOffsetBegin + TIM_IE_SIZE +
+			extra_ie_offset + p2p_ie_offset;
+	else
+		mac_ctx->sch.schObject.p2pIeOffset = 0;
+
+	pe_debug("Initialized beacon end, offset %d",
+		session->schBeaconOffsetEnd);
+	mac_ctx->sch.schObject.fBeaconChanged = 1;
+	qdf_mem_free(bcn_1);
+	qdf_mem_free(bcn_2);
+	qdf_mem_free(wsc_prb_res);
+	qdf_mem_free(addn_ie);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+lim_update_probe_rsp_template_ie_bitmap_beacon1(tpAniSirGlobal pMac,
+						tDot11fBeacon1 *beacon1,
+						tpPESession psessionEntry)
+{
+	uint32_t *DefProbeRspIeBitmap;
+	tDot11fProbeResponse *prb_rsp;
+
+	if (!psessionEntry) {
+		pe_debug("PESession is null!");
+		return QDF_STATUS_E_FAILURE;
+	}
+	DefProbeRspIeBitmap = &psessionEntry->DefProbeRspIeBitmap[0];
+	prb_rsp = &psessionEntry->probeRespFrame;
+	prb_rsp->BeaconInterval = beacon1->BeaconInterval;
+	qdf_mem_copy((void *)&prb_rsp->Capabilities,
+		     (void *)&beacon1->Capabilities,
+		     sizeof(beacon1->Capabilities));
+
+	/* SSID */
+	if (beacon1->SSID.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_SSID_EID);
+		/* populating it, because probe response has to go with SSID even in hidden case */
+		populate_dot11f_ssid(pMac, &psessionEntry->ssId, &prb_rsp->SSID);
+	}
+	/* supported rates */
+	if (beacon1->SuppRates.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_RATESET_EID);
+		qdf_mem_copy((void *)&prb_rsp->SuppRates,
+			     (void *)&beacon1->SuppRates,
+			     sizeof(beacon1->SuppRates));
+
+	}
+	/* DS Parameter set */
+	if (beacon1->DSParams.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					SIR_MAC_DS_PARAM_SET_EID);
+		qdf_mem_copy((void *)&prb_rsp->DSParams,
+			     (void *)&beacon1->DSParams,
+			     sizeof(beacon1->DSParams));
+
+	}
+
+	/* IBSS params will not be present in the Beacons transmitted by AP */
+	return QDF_STATUS_SUCCESS;
+}
+
+void lim_update_probe_rsp_template_ie_bitmap_beacon2(tpAniSirGlobal pMac,
+						     tDot11fBeacon2 *beacon2,
+						     uint32_t *DefProbeRspIeBitmap,
+						     tDot11fProbeResponse *prb_rsp)
+{
+	/* IBSS parameter set - will not be present in probe response tx by AP */
+	/* country */
+	if (beacon2->Country.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_COUNTRY_EID);
+		qdf_mem_copy((void *)&prb_rsp->Country,
+			     (void *)&beacon2->Country,
+			     sizeof(beacon2->Country));
+
+	}
+	/* Power constraint */
+	if (beacon2->PowerConstraints.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					SIR_MAC_PWR_CONSTRAINT_EID);
+		qdf_mem_copy((void *)&prb_rsp->PowerConstraints,
+			     (void *)&beacon2->PowerConstraints,
+			     sizeof(beacon2->PowerConstraints));
+
+	}
+	/* Channel Switch Annoouncement SIR_MAC_CHNL_SWITCH_ANN_EID */
+	if (beacon2->ChanSwitchAnn.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					SIR_MAC_CHNL_SWITCH_ANN_EID);
+		qdf_mem_copy((void *)&prb_rsp->ChanSwitchAnn,
+			     (void *)&beacon2->ChanSwitchAnn,
+			     sizeof(beacon2->ChanSwitchAnn));
+
+	}
+
+	/* EXT Channel Switch Announcement CHNL_EXTENDED_SWITCH_ANN_EID*/
+	if (beacon2->ext_chan_switch_ann.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+			SIR_MAC_CHNL_EXTENDED_SWITCH_ANN_EID);
+		qdf_mem_copy((void *)&prb_rsp->ext_chan_switch_ann,
+			(void *)&beacon2->ext_chan_switch_ann,
+			sizeof(beacon2->ext_chan_switch_ann));
+	}
+
+	/* Supported operating class */
+	if (beacon2->SuppOperatingClasses.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					SIR_MAC_OPERATING_CLASS_EID);
+		qdf_mem_copy((void *)&prb_rsp->SuppOperatingClasses,
+				(void *)&beacon2->SuppOperatingClasses,
+				sizeof(beacon2->SuppOperatingClasses));
+	}
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	if (beacon2->QComVendorIE.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					SIR_MAC_QCOM_VENDOR_EID);
+		qdf_mem_copy((void *)&prb_rsp->QComVendorIE,
+			     (void *)&beacon2->QComVendorIE,
+			     sizeof(beacon2->QComVendorIE));
+	}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+	/* ERP information */
+	if (beacon2->ERPInfo.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_ERP_INFO_EID);
+		qdf_mem_copy((void *)&prb_rsp->ERPInfo,
+			     (void *)&beacon2->ERPInfo,
+			     sizeof(beacon2->ERPInfo));
+
+	}
+	/* Extended supported rates */
+	if (beacon2->ExtSuppRates.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					SIR_MAC_EXTENDED_RATE_EID);
+		qdf_mem_copy((void *)&prb_rsp->ExtSuppRates,
+			     (void *)&beacon2->ExtSuppRates,
+			     sizeof(beacon2->ExtSuppRates));
+
+	}
+
+	/* WPA */
+	if (beacon2->WPA.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_WPA_EID);
+		qdf_mem_copy((void *)&prb_rsp->WPA, (void *)&beacon2->WPA,
+			     sizeof(beacon2->WPA));
+
+	}
+
+	/* RSN */
+	if (beacon2->RSNOpaque.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_RSN_EID);
+		qdf_mem_copy((void *)&prb_rsp->RSNOpaque,
+			     (void *)&beacon2->RSNOpaque,
+			     sizeof(beacon2->RSNOpaque));
+	}
+
+	/* EDCA Parameter set */
+	if (beacon2->EDCAParamSet.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					SIR_MAC_EDCA_PARAM_SET_EID);
+		qdf_mem_copy((void *)&prb_rsp->EDCAParamSet,
+			     (void *)&beacon2->EDCAParamSet,
+			     sizeof(beacon2->EDCAParamSet));
+
+	}
+	/* Vendor specific - currently no vendor specific IEs added */
+	/* Requested IEs - currently we are not processing this will be added later */
+	/* HT capability IE */
+	if (beacon2->HTCaps.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					SIR_MAC_HT_CAPABILITIES_EID);
+		qdf_mem_copy((void *)&prb_rsp->HTCaps, (void *)&beacon2->HTCaps,
+			     sizeof(beacon2->HTCaps));
+	}
+	/* HT Info IE */
+	if (beacon2->HTInfo.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_HT_INFO_EID);
+		qdf_mem_copy((void *)&prb_rsp->HTInfo, (void *)&beacon2->HTInfo,
+			     sizeof(beacon2->HTInfo));
+	}
+	if (beacon2->VHTCaps.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					SIR_MAC_VHT_CAPABILITIES_EID);
+		qdf_mem_copy((void *)&prb_rsp->VHTCaps,
+			     (void *)&beacon2->VHTCaps,
+			     sizeof(beacon2->VHTCaps));
+	}
+	if (beacon2->VHTOperation.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					SIR_MAC_VHT_OPERATION_EID);
+		qdf_mem_copy((void *)&prb_rsp->VHTOperation,
+			     (void *)&beacon2->VHTOperation,
+			     sizeof(beacon2->VHTOperation));
+	}
+	if (beacon2->VHTExtBssLoad.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					SIR_MAC_VHT_EXT_BSS_LOAD_EID);
+		qdf_mem_copy((void *)&prb_rsp->VHTExtBssLoad,
+			     (void *)&beacon2->VHTExtBssLoad,
+			     sizeof(beacon2->VHTExtBssLoad));
+	}
+	/* WMM IE */
+	if (beacon2->WMMParams.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_WPA_EID);
+		qdf_mem_copy((void *)&prb_rsp->WMMParams,
+			     (void *)&beacon2->WMMParams,
+			     sizeof(beacon2->WMMParams));
+	}
+	/* WMM capability - most of the case won't be present */
+	if (beacon2->WMMCaps.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_WPA_EID);
+		qdf_mem_copy((void *)&prb_rsp->WMMCaps,
+			     (void *)&beacon2->WMMCaps,
+			     sizeof(beacon2->WMMCaps));
+	}
+
+	/* Extended Capability */
+	if (beacon2->ExtCap.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, DOT11F_EID_EXTCAP);
+		qdf_mem_copy((void *)&prb_rsp->ExtCap,
+			     (void *)&beacon2->ExtCap,
+			     sizeof(beacon2->ExtCap));
+	}
+
+	if (beacon2->he_cap.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					DOT11F_EID_HE_CAP);
+		qdf_mem_copy((void *)&prb_rsp->he_cap,
+			     (void *)&beacon2->he_cap,
+			     sizeof(beacon2->he_cap));
+	}
+	if (beacon2->he_op.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+					DOT11F_EID_HE_OP);
+		qdf_mem_copy((void *)&prb_rsp->he_op,
+			     (void *)&beacon2->he_op,
+			     sizeof(beacon2->he_op));
+	}
+
+}
+
+void set_probe_rsp_ie_bitmap(uint32_t *IeBitmap, uint32_t pos)
+{
+	uint32_t index, temp;
+
+	index = pos >> 5;
+	if (index >= 8) {
+		return;
+	}
+	temp = IeBitmap[index];
+
+	temp |= 1 << (pos & 0x1F);
+
+	IeBitmap[index] = temp;
+}
+
+/**
+ * write_beacon_to_memory() - send the beacon to the wma
+ * @pMac: pointer to mac structure
+ * @size: Size of the beacon to write to memory
+ * @length: Length field of the beacon to write to memory
+ * @psessionEntry: pe session
+ * @reason: beacon update reason
+ *
+ * return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
+ */
+static QDF_STATUS write_beacon_to_memory(tpAniSirGlobal pMac, uint16_t size,
+					 uint16_t length,
+					 tpPESession psessionEntry,
+					 enum sir_bcn_update_reason reason)
+{
+	uint16_t i;
+	tpAniBeaconStruct pBeacon;
+	QDF_STATUS status;
+
+	/* copy end of beacon only if length > 0 */
+	if (length > 0) {
+		for (i = 0; i < psessionEntry->schBeaconOffsetEnd; i++)
+			psessionEntry->pSchBeaconFrameBegin[size++] =
+				psessionEntry->pSchBeaconFrameEnd[i];
+	}
+	/* Update the beacon length */
+	pBeacon = (tpAniBeaconStruct) psessionEntry->pSchBeaconFrameBegin;
+	/* Do not include the beaconLength indicator itself */
+	if (length == 0) {
+		pBeacon->beaconLength = 0;
+		/* Dont copy entire beacon, Copy length field alone */
+		size = 4;
+	} else
+		pBeacon->beaconLength = (uint32_t) size - sizeof(uint32_t);
+
+	if (!pMac->sch.schObject.fBeaconChanged)
+		return QDF_STATUS_E_FAILURE;
+
+	/*
+	 * Copy beacon data to SoftMAC shared memory...
+	 * Do this by sending a message to HAL
+	 */
+
+	size = (size + 3) & (~3);
+	status = sch_send_beacon_req(pMac, psessionEntry->pSchBeaconFrameBegin,
+				     size, psessionEntry, reason);
+	if (QDF_IS_STATUS_ERROR(status))
+		pe_err("sch_send_beacon_req() returned an error %d, size %d",
+		       status, size);
+	pMac->sch.schObject.fBeaconChanged = 0;
+
+	return status;
+}
+
+/**
+ * sch_generate_tim
+ *
+ * FUNCTION:
+ * Generate TIM
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pMac pointer to global mac structure
+ * @param **pPtr pointer to the buffer, where the TIM bit is to be written.
+ * @param *timLength pointer to limLength, which needs to be returned.
+ * @return None
+ */
+void sch_generate_tim(tpAniSirGlobal pMac, uint8_t **pPtr, uint16_t *timLength,
+		      uint8_t dtimPeriod)
+{
+	uint8_t *ptr = *pPtr;
+	uint32_t val = 0;
+	uint32_t minAid = 1;    /* Always start with AID 1 as minimum */
+	uint32_t maxAid = HAL_NUM_STA;
+	/* Generate partial virtual bitmap */
+	uint8_t N1 = minAid / 8;
+	uint8_t N2 = maxAid / 8;
+
+	if (N1 & 1)
+		N1--;
+
+	*timLength = N2 - N1 + 4;
+	val = dtimPeriod;
+
+	/*
+	 * Write 0xFF to firmware's field to detect firmware's mal-function
+	 * early. DTIM count and bitmap control usually cannot be 0xFF, so it
+	 * is easy to know that firmware never updated DTIM count/bitmap control
+	 * field after host driver downloaded beacon template if end-user complaints
+	 * that DTIM count and bitmapControl is 0xFF.
+	 */
+	*ptr++ = SIR_MAC_TIM_EID;
+	*ptr++ = (uint8_t) (*timLength);
+	/* location for dtimCount. will be filled in by FW. */
+	*ptr++ = 0xFF;
+	*ptr++ = (uint8_t) val;
+	/* location for bitmap control. will be filled in by FW. */
+	*ptr++ = 0xFF;
+	ptr += (N2 - N1 + 1);
+
+	*pPtr = ptr;
+}
+
+QDF_STATUS sch_process_pre_beacon_ind(tpAniSirGlobal pMac,
+				      struct scheduler_msg *limMsg,
+				      enum sir_bcn_update_reason reason)
+{
+	tpBeaconGenParams pMsg = (tpBeaconGenParams) limMsg->bodyptr;
+	uint32_t beaconSize;
+	tpPESession psessionEntry;
+	uint8_t sessionId;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	psessionEntry = pe_find_session_by_bssid(pMac, pMsg->bssId, &sessionId);
+	if (!psessionEntry) {
+		pe_err("session lookup fails");
+		goto end;
+	}
+
+	beaconSize = psessionEntry->schBeaconOffsetBegin;
+
+	/* If SME is not in normal mode, no need to generate beacon */
+	if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) {
+		pe_debug("PreBeaconInd received in invalid state: %d",
+			 psessionEntry->limSmeState);
+		goto end;
+	}
+
+	switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+
+	case eLIM_STA_IN_IBSS_ROLE:
+		/* generate IBSS parameter set */
+		if (psessionEntry->statypeForBss == STA_ENTRY_SELF)
+			status =
+			    write_beacon_to_memory(pMac, (uint16_t) beaconSize,
+						   (uint16_t) beaconSize,
+						   psessionEntry, reason);
+		else
+			pe_err("can not send beacon for PEER session entry");
+		break;
+
+	case eLIM_AP_ROLE: {
+		uint8_t *ptr =
+			&psessionEntry->pSchBeaconFrameBegin[psessionEntry->
+							     schBeaconOffsetBegin];
+		uint16_t timLength = 0;
+
+		if (psessionEntry->statypeForBss == STA_ENTRY_SELF) {
+			sch_generate_tim(pMac, &ptr, &timLength,
+					 psessionEntry->dtimPeriod);
+			beaconSize += 2 + timLength;
+			status =
+			    write_beacon_to_memory(pMac, (uint16_t) beaconSize,
+						   (uint16_t) beaconSize,
+						   psessionEntry, reason);
+		} else
+			pe_err("can not send beacon for PEER session entry");
+			}
+			break;
+
+	default:
+		pe_err("Error-PE has Receive PreBeconGenIndication when System is in %d role",
+		       GET_LIM_SYSTEM_ROLE(psessionEntry));
+	}
+
+end:
+	qdf_mem_free(pMsg);
+
+	return status;
+}
diff --git a/core/mac/src/pe/sch/sch_beacon_process.c b/core/mac/src/pe/sch/sch_beacon_process.c
new file mode 100644
index 0000000..855f949
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_beacon_process.c
@@ -0,0 +1,1655 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file sch_beacon_process.cc contains beacon processing related
+ * functions
+ *
+ * Author:      Sandesh Goel
+ * Date:        02/25/02
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "cds_api.h"
+#include "wni_cfg.h"
+
+#include "cfg_api.h"
+#include "cfg_ucfg_api.h"
+#include "lim_api.h"
+#include "utils_api.h"
+#include "sch_api.h"
+
+#include "lim_utils.h"
+#include "lim_send_messages.h"
+#include "lim_sta_hash_api.h"
+
+#include "rrm_api.h"
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+#include "host_diag_core_log.h"
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+#include "wma.h"
+/**
+ * Number of bytes of variation in beacon length from the last beacon
+ * to trigger reprogramming of rx delay register
+ */
+#define SCH_BEACON_LEN_DELTA       3
+
+/* calculate 2^cw - 1 */
+#define CW_GET(cw) (((cw) == 0) ? 1 : ((1 << (cw)) - 1))
+
+static void
+ap_beacon_process_5_ghz(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+			tpSchBeaconStruct bcn_struct,
+			tpUpdateBeaconParams bcn_prm, tpPESession session,
+			uint32_t phy_mode)
+{
+	tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+
+	if (!session->htCapability)
+		return;
+
+	if (bcn_struct->channelNumber != session->currentOperChannel)
+		return;
+
+	/* 11a (non HT) AP  overlaps or */
+	/* HT AP with HT op mode as mixed overlaps. */
+	/* HT AP with HT op mode as overlap legacy overlaps. */
+	if (!bcn_struct->HTInfo.present
+	    || (eSIR_HT_OP_MODE_MIXED == bcn_struct->HTInfo.opMode)
+	    || (eSIR_HT_OP_MODE_OVERLAP_LEGACY == bcn_struct->HTInfo.opMode)) {
+		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
+					&(session->gLimOverlap11aParams));
+
+		if (session->gLimOverlap11aParams.numSta
+		    && !session->gLimOverlap11aParams.protectionEnabled) {
+			lim_update_11a_protection(mac_ctx, true, true,
+						 bcn_prm, session);
+		}
+		return;
+	}
+	/* HT AP with HT20 op mode overlaps. */
+	if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT != bcn_struct->HTInfo.opMode)
+		return;
+
+	lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
+				     &(session->gLimOverlapHt20Params));
+
+	if (session->gLimOverlapHt20Params.numSta
+	    && !session->gLimOverlapHt20Params.protectionEnabled)
+		lim_enable_ht20_protection(mac_ctx, true, true,
+					   bcn_prm, session);
+}
+
+static void
+ap_beacon_process_24_ghz(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+			 tpSchBeaconStruct bcn_struct,
+			 tpUpdateBeaconParams bcn_prm, tpPESession session,
+			 uint32_t phy_mode)
+{
+	tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	bool tmp_exp = false;
+	/* We are 11G AP. */
+	if ((phy_mode == WNI_CFG_PHY_MODE_11G) &&
+	    (false == session->htCapability)) {
+		if (bcn_struct->channelNumber != session->currentOperChannel)
+			return;
+
+		tmp_exp = (!bcn_struct->erpPresent &&
+			   !bcn_struct->HTInfo.present) ||
+			    /* if erp not present then  11B AP overlapping */
+			  (!mac_ctx->mlme_cfg->sta.ignore_peer_erp_info &&
+			   bcn_struct->erpPresent &&
+			   (bcn_struct->erpIEInfo.useProtection ||
+			    bcn_struct->erpIEInfo.nonErpPresent));
+		if (!tmp_exp)
+			return;
+#ifdef FEATURE_WLAN_ESE
+		if (session->isESEconnection)
+			QDF_TRACE(QDF_MODULE_ID_PE,
+				  QDF_TRACE_LEVEL_INFO,
+				  FL("[INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d"),
+				  bcn_struct->erpPresent,
+				  bcn_struct->erpIEInfo.useProtection,
+				  bcn_struct->erpIEInfo.nonErpPresent);
+#endif
+		lim_enable_overlap11g_protection(mac_ctx, bcn_prm,
+						 mac_hdr, session);
+		return;
+	}
+	/* handling the case when HT AP has overlapping legacy BSS. */
+	if (!session->htCapability)
+		return;
+
+	if (bcn_struct->channelNumber != session->currentOperChannel)
+		return;
+
+	tmp_exp = (!bcn_struct->erpPresent && !bcn_struct->HTInfo.present) ||
+		    /* if erp not present then  11B AP overlapping */
+		   (!mac_ctx->mlme_cfg->sta.ignore_peer_erp_info &&
+		    bcn_struct->erpPresent &&
+		    (bcn_struct->erpIEInfo.useProtection ||
+		     bcn_struct->erpIEInfo.nonErpPresent));
+	if (tmp_exp) {
+#ifdef FEATURE_WLAN_ESE
+		if (session->isESEconnection) {
+			QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
+				  FL("[INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d"),
+				  bcn_struct->erpPresent,
+				  bcn_struct->erpIEInfo.useProtection,
+				  bcn_struct->erpIEInfo.nonErpPresent);
+		}
+#endif
+		lim_enable_overlap11g_protection(mac_ctx, bcn_prm,
+						 mac_hdr, session);
+	}
+	/* 11g device overlaps */
+	tmp_exp = bcn_struct->erpPresent
+		&& !(bcn_struct->erpIEInfo.useProtection
+		     || bcn_struct->erpIEInfo.nonErpPresent)
+		&& !(bcn_struct->HTInfo.present);
+	if (tmp_exp) {
+		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
+					     &(session->gLimOverlap11gParams));
+
+		if (session->gLimOverlap11gParams.numSta
+		    && !session->gLimOverlap11gParams.protectionEnabled)
+			lim_enable_ht_protection_from11g(mac_ctx, true, true,
+							 bcn_prm, session);
+	}
+	/* ht device overlaps.
+	 * here we will check for HT related devices only which might need
+	 * protection. check for 11b and 11g is already done in the previous
+	 * blocks. so we will not check for HT operating mode as MIXED.
+	 */
+	if (!bcn_struct->HTInfo.present)
+		return;
+
+	/*
+	 * if we are not already in mixed mode or legacy mode as HT operating
+	 * mode and received beacon has HT operating mode as legacy then we need
+	 * to enable protection from 11g station. we don't need protection from
+	 * 11b because if that's needed then our operating mode would have
+	 * already been set to legacy in the previous blocks.
+	 */
+	if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY == bcn_struct->HTInfo.opMode) &&
+		!mac_ctx->mlme_cfg->sap_protection_cfg.ignore_peer_ht_opmode) {
+		if (eSIR_HT_OP_MODE_OVERLAP_LEGACY == mac_ctx->lim.gHTOperMode
+		    || eSIR_HT_OP_MODE_MIXED == mac_ctx->lim.gHTOperMode)
+			return;
+		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
+					     &(session->gLimOverlap11gParams));
+		if (session->gLimOverlap11gParams.numSta
+		    && !session->gLimOverlap11gParams.protectionEnabled)
+			lim_enable_ht_protection_from11g(mac_ctx, true, true,
+							 bcn_prm, session);
+		return;
+	}
+
+	if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == bcn_struct->HTInfo.opMode) {
+		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
+					     &(session->gLimOverlapHt20Params));
+		if (session->gLimOverlapHt20Params.numSta
+		    && !session->gLimOverlapHt20Params.protectionEnabled)
+			lim_enable_ht20_protection(mac_ctx, true, true,
+						   bcn_prm, session);
+	}
+}
+
+/**
+ * ap_beacon_process() - processes incoming beacons
+ *
+ * @mac_ctx:         mac global context
+ * @rx_pkt_info:     incoming beacon packet
+ * @bcn_struct:      beacon struct
+ * @bcn_prm:         beacon params
+ * @session:         pe session entry
+ *
+ * Return: void
+ */
+static void
+ap_beacon_process(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+		  tpSchBeaconStruct bcn_struct,
+		  tpUpdateBeaconParams bcn_prm, tpPESession session)
+{
+	uint32_t phy_mode;
+	enum band_info rf_band = BAND_UNKNOWN;
+	/* Get RF band from session */
+	rf_band = session->limRFBand;
+
+	lim_get_phy_mode(mac_ctx, &phy_mode, session);
+
+	if (BAND_5G == rf_band)
+		ap_beacon_process_5_ghz(mac_ctx, rx_pkt_info, bcn_struct,
+					bcn_prm, session, phy_mode);
+	else if (BAND_2G == rf_band)
+		ap_beacon_process_24_ghz(mac_ctx, rx_pkt_info, bcn_struct,
+					 bcn_prm, session, phy_mode);
+}
+
+/* -------------------------------------------------------------------- */
+
+/**
+ * __sch_beacon_process_no_session
+ *
+ * FUNCTION:
+ * Process the received beacon frame when
+ *  -- Station is not scanning
+ *  -- No corresponding session is found
+ *
+ * LOGIC:
+ *        Following scenarios exist when Session Does not exist:
+ *             * IBSS Beacons, when IBSS session already exists with same SSID,
+ *                but from STA which has not yet joined and has a different BSSID.
+ *                - invoke lim_handle_ibs_scoalescing with the session context of existing IBSS session.
+ *
+ *             * IBSS Beacons when IBSS session does not exist, only Infra or BT-AMP session exists,
+ *                then save the beacon in the scan results and throw it away.
+ *
+ *             * Infra Beacons
+ *                - beacons received when no session active
+ *                    should not come here, it should be handled as part of scanning,
+ *                    else they should not be getting received, should update scan results and drop it if that happens.
+ *                - beacons received when IBSS session active:
+ *                    update scan results and drop it.
+ *                - beacons received when Infra session(STA) is active:
+ *                    update scan results and drop it
+ *                - beacons received when BT-STA session is active:
+ *                    update scan results and drop it.
+ *                - beacons received when Infra/BT-STA  or Infra/IBSS is active.
+ *                    update scan results and drop it.
+ *
+
+ */
+static void __sch_beacon_process_no_session(tpAniSirGlobal pMac,
+					    tpSchBeaconStruct pBeacon,
+					    uint8_t *pRxPacketInfo)
+{
+	tpPESession psessionEntry = NULL;
+
+	psessionEntry = lim_is_ibss_session_active(pMac);
+	if (psessionEntry != NULL) {
+		lim_handle_ibss_coalescing(pMac, pBeacon, pRxPacketInfo,
+					   psessionEntry);
+	}
+	return;
+}
+
+/**
+ * get_operating_channel_width() - Get operating channel width
+ * @stads - station entry.
+ *
+ * This function returns the operating channel width based on
+ * the supported channel width entry.
+ *
+ * Return: tSirMacHTChannelWidth on success
+ */
+static tSirMacHTChannelWidth get_operating_channel_width(tpDphHashNode stads)
+{
+	tSirMacHTChannelWidth ch_width = eHT_CHANNEL_WIDTH_20MHZ;
+
+	if (stads->vhtSupportedChannelWidthSet ==
+			WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
+		ch_width = eHT_CHANNEL_WIDTH_160MHZ;
+	else if (stads->vhtSupportedChannelWidthSet ==
+			WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
+		ch_width = eHT_CHANNEL_WIDTH_160MHZ;
+	else if (stads->vhtSupportedChannelWidthSet ==
+			WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
+		ch_width = eHT_CHANNEL_WIDTH_80MHZ;
+	else if (stads->htSupportedChannelWidthSet)
+		ch_width = eHT_CHANNEL_WIDTH_40MHZ;
+	else
+		ch_width = eHT_CHANNEL_WIDTH_20MHZ;
+
+	return ch_width;
+}
+
+/*
+ * sch_bcn_process_sta() - Process the received beacon frame for sta,
+ * bt_amp_sta
+ *
+ * @mac_ctx:        mac_ctx
+ * @bcn:            beacon struct
+ * @rx_pkt_info:    received packet info
+ * @session:        pe session pointer
+ * @bssIdx:         bss index
+ * @beaconParams:   update beacon params
+ * @sendProbeReq:   out flag to indicate if probe rsp is to be sent
+ * @pMh:            mac header
+ *
+ * Process the received beacon frame for sta
+ *
+ * Return: success of failure of operation
+ */
+static bool
+sch_bcn_process_sta(tpAniSirGlobal mac_ctx,
+			       tpSchBeaconStruct bcn,
+			       uint8_t *rx_pkt_info,
+			       tpPESession session, uint8_t *bssIdx,
+			       tUpdateBeaconParams *beaconParams,
+			       uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh)
+{
+	uint32_t bi;
+	tpDphHashNode pStaDs = NULL;
+	QDF_STATUS status;
+
+	/*
+	 *  This handles two cases:
+	 *  -- Infra STA receiving beacons from AP
+	 */
+
+	/**
+	 * This is the Beacon received from the AP  we're currently associated
+	 * with. Check if there are any changes in AP's capabilities
+	 */
+	if ((uint8_t) bcn->channelNumber != session->currentOperChannel) {
+		pe_err("Channel Change from %d --> %d - Ignoring beacon!",
+		       session->currentOperChannel,
+		       bcn->channelNumber);
+		return false;
+	}
+	lim_detect_change_in_ap_capabilities(mac_ctx, bcn, session);
+	if (lim_get_sta_hash_bssidx(mac_ctx, DPH_STA_HASH_INDEX_PEER, bssIdx,
+				    session) != QDF_STATUS_SUCCESS)
+		return false;
+
+	beaconParams->bssIdx = *bssIdx;
+	qdf_mem_copy((uint8_t *) &session->lastBeaconTimeStamp,
+			(uint8_t *) bcn->timeStamp, sizeof(uint64_t));
+	session->currentBssBeaconCnt++;
+	if (session->bcon_dtim_period != bcn->tim.dtimPeriod) {
+		session->bcon_dtim_period = bcn->tim.dtimPeriod;
+		lim_send_set_dtim_period(mac_ctx, bcn->tim.dtimPeriod,
+				session);
+	}
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF,
+	       session->peSessionId, bcn->timeStamp[0]));
+	MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF,
+	       session->peSessionId, bcn->timeStamp[1]));
+
+	/* Read beacon interval session Entry */
+	bi = session->beaconParams.beaconInterval;
+	if (bi != bcn->beaconInterval) {
+		pe_debug("Beacon interval changed from %d to %d",
+		       bcn->beaconInterval, bi);
+
+		bi = bcn->beaconInterval;
+		session->beaconParams.beaconInterval = (uint16_t) bi;
+		beaconParams->paramChangeBitmap |= PARAM_BCN_INTERVAL_CHANGED;
+		beaconParams->beaconInterval = (uint16_t) bi;
+	}
+
+	if (bcn->cfPresent) {
+		if (!cfg_in_range(CFG_CFP_PERIOD, bcn->cfParamSet.cfpPeriod)) {
+			pe_err("Error in setting CFG item CFP Period");
+			return false;
+		}
+		mac_ctx->mlme_cfg->rates.cfp_period = bcn->cfParamSet.cfpPeriod;
+
+		lim_send_cf_params(mac_ctx, *bssIdx,
+				   bcn->cfParamSet.cfpCount,
+				   bcn->cfParamSet.cfpPeriod);
+	}
+
+	/* No need to send DTIM Period and Count to HAL/SMAC */
+	/* SMAC already parses TIM bit. */
+	if (bcn->timPresent) {
+		if (cfg_in_range(CFG_DTIM_PERIOD, bcn->tim.dtimPeriod))
+			mac_ctx->mlme_cfg->sap_cfg.dtim_interval =
+						bcn->tim.dtimPeriod;
+	}
+
+	if (mac_ctx->lim.gLimProtectionControl !=
+	    MLME_FORCE_POLICY_PROTECTION_DISABLE)
+		lim_decide_sta_protection(mac_ctx, bcn, beaconParams, session);
+
+	if (bcn->erpPresent) {
+		if (bcn->erpIEInfo.barkerPreambleMode)
+			lim_enable_short_preamble(mac_ctx, false,
+						  beaconParams, session);
+		else
+			lim_enable_short_preamble(mac_ctx, true,
+						  beaconParams, session);
+	}
+	lim_update_short_slot(mac_ctx, bcn, beaconParams, session);
+
+	pStaDs = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+				    &session->dph.dphHashTable);
+	if ((bcn->wmeEdcaPresent && session->limWmeEnabled) ||
+	    (bcn->edcaPresent && session->limQosEnabled)) {
+		if (bcn->edcaParams.qosInfo.count !=
+		    session->gLimEdcaParamSetCount) {
+			status = sch_beacon_edca_process(mac_ctx,
+							 &bcn->edcaParams,
+							 session);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				pe_err("EDCA parameter processing error");
+			} else if (pStaDs != NULL) {
+				/* If needed, downgrade the EDCA parameters */
+				lim_set_active_edca_params(mac_ctx,
+					session->gLimEdcaParams, session);
+				lim_send_edca_params(mac_ctx,
+					session->gLimEdcaParamsActive,
+					pStaDs->bssId, false);
+			} else {
+				pe_err("Self Entry missing in Hash Table");
+			}
+		}
+		return true;
+	}
+
+	if ((bcn->qosCapabilityPresent && session->limQosEnabled)
+	    && (bcn->qosCapability.qosInfo.count !=
+		session->gLimEdcaParamSetCount))
+		*sendProbeReq = true;
+
+	return true;
+}
+
+/**
+ * update_nss() - Function to update NSS
+ * @mac_ctx: pointer to Global Mac structure
+ * @sta_ds: pointer to tpDphHashNode
+ * @beacon: pointer to tpSchBeaconStruct
+ * @session_entry: pointer to tpPESession
+ * @mgmt_hdr: pointer to tpSirMacMgmtHdr
+ *
+ * function to update NSS
+ *
+ * Return: none
+ */
+static void update_nss(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+		       tpSchBeaconStruct beacon, tpPESession session_entry,
+		       tpSirMacMgmtHdr mgmt_hdr)
+{
+	if (sta_ds->vhtSupportedRxNss != (beacon->OperatingMode.rxNSS + 1)) {
+		if (session_entry->nss_forced_1x1) {
+			pe_debug("Not Updating NSS for special AP");
+			return;
+		}
+		sta_ds->vhtSupportedRxNss =
+			beacon->OperatingMode.rxNSS + 1;
+		lim_set_nss_change(mac_ctx, session_entry,
+			sta_ds->vhtSupportedRxNss, sta_ds->staIndex,
+			mgmt_hdr->sa);
+	}
+}
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+static void
+sch_bcn_update_he_ies(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+				tpPESession session, tpSchBeaconStruct bcn,
+				tpSirMacMgmtHdr mac_hdr)
+{
+	uint8_t session_bss_col_disabled_flag;
+	bool anything_changed = false;
+
+	if (session->is_session_obss_color_collision_det_enabled)
+		return;
+
+	if (session->he_op.present && bcn->he_op.present) {
+		if (bcn->vendor_he_bss_color_change.present &&
+				(session->he_op.bss_color !=
+				 bcn->vendor_he_bss_color_change.new_color)) {
+			pe_debug("bss color changed from [%d] to [%d]",
+				session->he_op.bss_color,
+				bcn->vendor_he_bss_color_change.new_color);
+			session->he_op.bss_color =
+				bcn->vendor_he_bss_color_change.new_color;
+			anything_changed = true;
+		}
+		session_bss_col_disabled_flag = session->he_op.bss_col_disabled;
+		if (session_bss_col_disabled_flag !=
+				bcn->he_op.bss_col_disabled) {
+			pe_debug("color disable flag changed from [%d] to [%d]",
+				session->he_op.bss_col_disabled,
+				bcn->he_op.bss_col_disabled);
+			session->he_op.bss_col_disabled =
+				bcn->he_op.bss_col_disabled;
+			anything_changed = true;
+		}
+	}
+	if (anything_changed)
+		lim_send_he_ie_update(mac_ctx, session);
+}
+#else
+static void
+sch_bcn_update_he_ies(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+				tpPESession session, tpSchBeaconStruct bcn,
+				tpSirMacMgmtHdr mac_hdr)
+{
+	return;
+}
+#endif
+
+static void
+sch_bcn_update_opmode_change(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+				tpPESession session, tpSchBeaconStruct bcn,
+				tpSirMacMgmtHdr mac_hdr, uint8_t cb_mode)
+{
+	bool skip_opmode_update = false;
+	uint8_t oper_mode;
+	uint32_t fw_vht_ch_wd = wma_get_vht_ch_width();
+	uint8_t ch_width = 0;
+
+	if (session->vhtCapability && bcn->OperatingMode.present) {
+		update_nss(mac_ctx, sta_ds, bcn, session, mac_hdr);
+		oper_mode = get_operating_channel_width(sta_ds);
+		if ((oper_mode == eHT_CHANNEL_WIDTH_80MHZ) &&
+		    (bcn->OperatingMode.chanWidth > eHT_CHANNEL_WIDTH_80MHZ))
+			skip_opmode_update = true;
+
+		if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == cb_mode) {
+			/*
+			 * if channel bonding is disabled from INI do not
+			 * update the chan width
+			 */
+			pe_debug_rl("CB disabled skip bw update: old[%d] new[%d]",
+				    oper_mode,
+				    bcn->OperatingMode.chanWidth);
+			return;
+		}
+
+		if (!skip_opmode_update &&
+			((oper_mode != bcn->OperatingMode.chanWidth) ||
+			(sta_ds->vhtSupportedRxNss !=
+			(bcn->OperatingMode.rxNSS + 1)))) {
+			pe_debug("received OpMode Chanwidth %d, staIdx = %d",
+			       bcn->OperatingMode.chanWidth, sta_ds->staIndex);
+			pe_debug("MAC - %0x:%0x:%0x:%0x:%0x:%0x",
+			       mac_hdr->sa[0], mac_hdr->sa[1],
+			       mac_hdr->sa[2], mac_hdr->sa[3],
+			       mac_hdr->sa[4], mac_hdr->sa[5]);
+
+			if ((bcn->OperatingMode.chanWidth >=
+				eHT_CHANNEL_WIDTH_160MHZ) &&
+				(fw_vht_ch_wd > eHT_CHANNEL_WIDTH_80MHZ)) {
+				pe_debug("Updating the CH Width to 160MHz");
+				sta_ds->vhtSupportedChannelWidthSet =
+					WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
+				sta_ds->htSupportedChannelWidthSet =
+					eHT_CHANNEL_WIDTH_40MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_160MHZ;
+			} else if (bcn->OperatingMode.chanWidth >=
+				eHT_CHANNEL_WIDTH_80MHZ) {
+				pe_debug("Updating the CH Width to 80MHz");
+				sta_ds->vhtSupportedChannelWidthSet =
+					WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+				sta_ds->htSupportedChannelWidthSet =
+					eHT_CHANNEL_WIDTH_40MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_80MHZ;
+			} else if (bcn->OperatingMode.chanWidth ==
+				eHT_CHANNEL_WIDTH_40MHZ) {
+				pe_debug("Updating the CH Width to 40MHz");
+				sta_ds->vhtSupportedChannelWidthSet =
+					WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+				sta_ds->htSupportedChannelWidthSet =
+					eHT_CHANNEL_WIDTH_40MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_40MHZ;
+			} else if (bcn->OperatingMode.chanWidth ==
+				eHT_CHANNEL_WIDTH_20MHZ) {
+				pe_debug("Updating the CH Width to 20MHz");
+				sta_ds->vhtSupportedChannelWidthSet =
+					WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+				sta_ds->htSupportedChannelWidthSet =
+					eHT_CHANNEL_WIDTH_20MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_20MHZ;
+			}
+			lim_check_vht_op_mode_change(mac_ctx, session,
+				ch_width, sta_ds->staIndex, mac_hdr->sa);
+			update_nss(mac_ctx, sta_ds, bcn, session, mac_hdr);
+		}
+		return;
+	}
+
+	if (!(session->vhtCapability && bcn->VHTOperation.present))
+		return;
+
+	oper_mode = sta_ds->vhtSupportedChannelWidthSet;
+	if ((oper_mode == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) &&
+	    (oper_mode < bcn->VHTOperation.chanWidth))
+		skip_opmode_update = true;
+
+	if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == cb_mode) {
+		/*
+		 * if channel bonding is disabled from INI do not
+		 * update the chan width
+		 */
+		pe_debug_rl("CB disabled skip bw update: old[%d] new[%d]",
+			    oper_mode, bcn->OperatingMode.chanWidth);
+
+		return;
+	}
+
+	if (!skip_opmode_update &&
+	    (oper_mode != bcn->VHTOperation.chanWidth)) {
+		pe_debug("received VHTOP CHWidth %d staIdx = %d",
+		       bcn->VHTOperation.chanWidth, sta_ds->staIndex);
+		pe_debug("MAC - %0x:%0x:%0x:%0x:%0x:%0x",
+		       mac_hdr->sa[0], mac_hdr->sa[1],
+		       mac_hdr->sa[2], mac_hdr->sa[3],
+		       mac_hdr->sa[4], mac_hdr->sa[5]);
+
+		if ((bcn->VHTOperation.chanWidth >=
+			WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) &&
+			(fw_vht_ch_wd > eHT_CHANNEL_WIDTH_80MHZ)) {
+			pe_debug("Updating the CH Width to 160MHz");
+			sta_ds->vhtSupportedChannelWidthSet =
+				bcn->VHTOperation.chanWidth;
+			sta_ds->htSupportedChannelWidthSet =
+				eHT_CHANNEL_WIDTH_40MHZ;
+			ch_width = eHT_CHANNEL_WIDTH_160MHZ;
+		} else if (bcn->VHTOperation.chanWidth >=
+			WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) {
+			pe_debug("Updating the CH Width to 80MHz");
+			sta_ds->vhtSupportedChannelWidthSet =
+				WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+			sta_ds->htSupportedChannelWidthSet =
+				eHT_CHANNEL_WIDTH_40MHZ;
+			ch_width = eHT_CHANNEL_WIDTH_80MHZ;
+		} else if (bcn->VHTOperation.chanWidth ==
+			WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) {
+			sta_ds->vhtSupportedChannelWidthSet =
+				WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+			if (bcn->HTCaps.supportedChannelWidthSet) {
+				pe_debug("Updating the CH Width to 40MHz");
+				sta_ds->htSupportedChannelWidthSet =
+					eHT_CHANNEL_WIDTH_40MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_40MHZ;
+			} else {
+				pe_debug("Updating the CH Width to 20MHz");
+				sta_ds->htSupportedChannelWidthSet =
+					eHT_CHANNEL_WIDTH_20MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_20MHZ;
+			}
+		}
+		lim_check_vht_op_mode_change(mac_ctx, session, ch_width,
+						sta_ds->staIndex, mac_hdr->sa);
+	}
+}
+
+/*
+ * sch_bcn_process_sta_ibss() - Process the received beacon frame
+ * for sta, bt_amp_sta and ibss
+ *
+ * @mac_ctx:        mac_ctx
+ * @bcn:            beacon struct
+ * @rx_pkt_info:    received packet info
+ * @session:        pe session pointer
+ * @bssIdx:         bss index
+ * @beaconParams:   update beacon params
+ * @sendProbeReq:   out flag to indicate if probe rsp is to be sent
+ * @pMh:            mac header
+ *
+ * Process the received beacon frame for sta and ibss
+ *
+ * Return: void
+ */
+static void
+sch_bcn_process_sta_ibss(tpAniSirGlobal mac_ctx,
+				    tpSchBeaconStruct bcn,
+				    uint8_t *rx_pkt_info,
+				    tpPESession session, uint8_t *bssIdx,
+				    tUpdateBeaconParams *beaconParams,
+				    uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh)
+{
+	tpDphHashNode pStaDs = NULL;
+	uint16_t aid;
+	uint8_t cb_mode;
+
+	if (CHAN_ENUM_14 >= session->currentOperChannel) {
+		if (session->force_24ghz_in_ht20)
+			cb_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+		else
+			cb_mode =
+			   mac_ctx->roam.configParam.channelBondingMode24GHz;
+	} else
+		cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz;
+	/* check for VHT capability */
+	pStaDs = dph_lookup_hash_entry(mac_ctx, pMh->sa, &aid,
+			&session->dph.dphHashTable);
+	if ((NULL == pStaDs) || ((NULL != pStaDs) &&
+					(STA_INVALID_IDX == pStaDs->staIndex)))
+		return;
+	sch_bcn_update_opmode_change(mac_ctx, pStaDs, session, bcn, pMh,
+				     cb_mode);
+	sch_bcn_update_he_ies(mac_ctx, pStaDs, session, bcn, pMh);
+	return;
+}
+
+/**
+ * get_local_power_constraint_beacon() - extracts local constraint
+ * from beacon
+ * @bcn: beacon structure
+ * @local_constraint: local constraint pointer
+ *
+ * Return: None
+ */
+#ifdef FEATURE_WLAN_ESE
+static void get_local_power_constraint_beacon(
+		tpSchBeaconStruct bcn,
+		int8_t *local_constraint)
+{
+	if (bcn->eseTxPwr.present)
+		*local_constraint = bcn->eseTxPwr.power_limit;
+}
+#else
+static void get_local_power_constraint_beacon(
+		tpSchBeaconStruct bcn,
+		int8_t *local_constraint)
+{
+
+}
+#endif
+
+/*
+ * __sch_beacon_process_for_session() - Process the received beacon frame when
+ * station is not scanning and corresponding session is found
+ *
+ *
+ * @mac_ctx:        mac_ctx
+ * @bcn:            beacon struct
+ * @rx_pkt_info:    received packet info
+ * @session:        pe session pointer
+ *
+ * Following scenarios exist when Session exists
+ *   IBSS STA receiving beacons from IBSS Peers, who are part of IBSS.
+ *     - call lim_handle_ibs_scoalescing with that session context.
+ *   Infra STA receiving beacons from AP to which it is connected
+ *     - call sch_beacon_processFromAP with that session's context.
+ *     - call sch_beacon_processFromAP with that session's context.
+ *     (here need to make sure BTAP creates session entry for BT STA)
+ *     - just update the beacon count for heart beat purposes for now,
+ *       for now, don't process the beacon.
+ *   Infra/IBSS both active and receives IBSS beacon:
+ *     - call lim_handle_ibs_scoalescing with that session context.
+ *   Infra/IBSS both active and receives Infra beacon:
+ *     - call sch_beacon_processFromAP with that session's context.
+ *        any updates to EDCA parameters will be effective for IBSS as well,
+ *        even though no WMM for IBSS ?? Need to figure out how to handle
+ *        this scenario.
+ *   Infra/BTSTA both active and receive Infra beacon.
+ *     - change in EDCA parameters on Infra affect the BTSTA link.
+ *        Update the same parameters on BT link
+ *   Infra/BTSTA both active and receive BT-AP beacon.
+ *     - update beacon cnt for heartbeat
+ *   Infra/BTAP both active and receive Infra beacon.
+ *     - BT-AP starts advertising BE parameters from Infra AP, if they get
+ *       changed.
+ *   Infra/BTAP both active and receive BTSTA beacon.
+ *       - update beacon cnt for heartbeat
+ *
+ * Return: void
+ */
+static void __sch_beacon_process_for_session(tpAniSirGlobal mac_ctx,
+					     tpSchBeaconStruct bcn,
+					     uint8_t *rx_pkt_info,
+					     tpPESession session)
+{
+	uint8_t bssIdx = 0;
+	tUpdateBeaconParams beaconParams;
+	uint8_t sendProbeReq = false;
+	tpSirMacMgmtHdr pMh = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	int8_t regMax = 0, maxTxPower = 0, local_constraint;
+
+	qdf_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
+	beaconParams.paramChangeBitmap = 0;
+
+	if (LIM_IS_IBSS_ROLE(session)) {
+		lim_handle_ibss_coalescing(mac_ctx, bcn, rx_pkt_info, session);
+	} else if (LIM_IS_STA_ROLE(session)) {
+		if (false == sch_bcn_process_sta(mac_ctx, bcn,
+				rx_pkt_info, session, &bssIdx,
+				&beaconParams, &sendProbeReq, pMh))
+			return;
+	}
+
+	/*
+	 * For vht session, if opermode ie or vht oper IE is present
+	 * bandwidth change will be taken care using these vht IEs.
+	 */
+	if (!(session->vhtCapability && (bcn->OperatingMode.present ||
+	   bcn->VHTOperation.present)) && session->htCapability &&
+	   bcn->HTInfo.present && !LIM_IS_IBSS_ROLE(session))
+		lim_update_sta_run_time_ht_switch_chnl_params(mac_ctx,
+						&bcn->HTInfo, bssIdx, session);
+
+	if ((LIM_IS_STA_ROLE(session) && !wma_is_csa_offload_enabled())
+	    || LIM_IS_IBSS_ROLE(session)) {
+		/* Channel Switch information element updated */
+		if (bcn->channelSwitchPresent) {
+			/*
+			 * on receiving channel switch announcement from AP,
+			 * delete all TDLS peers before leaving BSS and proceed
+			 * for channel switch
+			 */
+			if (LIM_IS_STA_ROLE(session))
+				lim_delete_tdls_peers(mac_ctx, session);
+
+			lim_update_channel_switch(mac_ctx, bcn, session);
+		} else if (session->gLimSpecMgmt.dot11hChanSwState ==
+				eLIM_11H_CHANSW_RUNNING) {
+			lim_cancel_dot11h_channel_switch(mac_ctx, session);
+		}
+	}
+	if (LIM_IS_STA_ROLE(session)
+	    || LIM_IS_IBSS_ROLE(session))
+		sch_bcn_process_sta_ibss(mac_ctx, bcn,
+					rx_pkt_info, session, &bssIdx,
+					&beaconParams, &sendProbeReq, pMh);
+	/* Obtain the Max Tx power for the current regulatory  */
+	regMax = cfg_get_regulatory_max_transmit_power(mac_ctx,
+					session->currentOperChannel);
+
+	local_constraint = regMax;
+
+	if (mac_ctx->roam.configParam.allow_tpc_from_ap) {
+		get_local_power_constraint_beacon(bcn, &local_constraint);
+		pe_debug("ESE localPowerConstraint = %d,",
+				local_constraint);
+
+		if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
+				bcn->powerConstraintPresent) {
+			local_constraint = regMax;
+			local_constraint -=
+				bcn->localPowerConstraint.localPowerConstraints;
+			pe_debug("localPowerConstraint = %d,",
+				local_constraint);
+			}
+	}
+
+	maxTxPower = lim_get_max_tx_power(regMax, local_constraint,
+					mac_ctx->roam.configParam.nTxPowerCap);
+
+	pe_debug("RegMax = %d, MaxTx pwr = %d",
+			regMax, maxTxPower);
+
+
+	/* If maxTxPower is increased or decreased */
+	if (maxTxPower != session->maxTxPower) {
+		pe_debug(
+			FL("Local power constraint change, Updating new maxTx power %d from old pwr %d"),
+			maxTxPower, session->maxTxPower);
+		if (lim_send_set_max_tx_power_req(mac_ctx, maxTxPower, session)
+		    == QDF_STATUS_SUCCESS)
+			session->maxTxPower = maxTxPower;
+	}
+
+	/* Indicate to LIM that Beacon is received */
+	if (bcn->HTInfo.present)
+		lim_received_hb_handler(mac_ctx,
+				(uint8_t) bcn->HTInfo.primaryChannel, session);
+	else
+		lim_received_hb_handler(mac_ctx, (uint8_t) bcn->channelNumber,
+				session);
+
+	/*
+	 * I don't know if any additional IE is required here. Currently, not
+	 * include addIE.
+	 */
+	if (sendProbeReq)
+		lim_send_probe_req_mgmt_frame(mac_ctx, &session->ssId,
+			session->bssId, session->currentOperChannel,
+			session->selfMacAddr, session->dot11mode, NULL, NULL);
+
+	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
+	    && beaconParams.paramChangeBitmap) {
+		pe_debug("Beacon for session[%d] got changed.",
+			 session->peSessionId);
+		pe_debug("sending beacon param change bitmap: 0x%x",
+			 beaconParams.paramChangeBitmap);
+		lim_send_beacon_params(mac_ctx, &beaconParams, session);
+	}
+
+	if ((session->pePersona == QDF_P2P_CLIENT_MODE) &&
+		session->send_p2p_conf_frame) {
+		lim_p2p_oper_chan_change_confirm_action_frame(mac_ctx,
+				session->bssId, session);
+		session->send_p2p_conf_frame = false;
+	}
+}
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+static void ap_update_bss_color_info(tpAniSirGlobal mac_ctx,
+						tpPESession session,
+						uint8_t bss_color)
+{
+	if (!session)
+		return;
+
+	if (bss_color < 1 || bss_color > 63) {
+		pe_warn("Invalid BSS color");
+		return;
+	}
+
+	session->bss_color_info[bss_color - 1].seen_count++;
+	session->bss_color_info[bss_color - 1].timestamp =
+					qdf_get_system_timestamp();
+}
+
+static uint8_t ap_get_new_bss_color(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+	int i;
+	uint8_t new_bss_color;
+	struct bss_color_info color_info;
+	qdf_time_t cur_timestamp;
+
+	if (!session)
+		return 0;
+
+	color_info = session->bss_color_info[0];
+	new_bss_color = 0;
+	cur_timestamp = qdf_get_system_timestamp();
+	for (i = 1; i < MAX_BSS_COLOR_VALUE; i++) {
+		if (session->bss_color_info[i].seen_count == 0) {
+			new_bss_color = i + 1;
+			return new_bss_color;
+		}
+
+		if (color_info.seen_count >
+				session->bss_color_info[i].seen_count &&
+				(cur_timestamp - session->bss_color_info[i].
+					timestamp) > TIME_BEACON_NOT_UPDATED) {
+			color_info = session->bss_color_info[i];
+			new_bss_color = i + 1;
+		}
+	}
+	pe_debug("new bss color: %d", new_bss_color);
+	return new_bss_color;
+}
+
+static void sch_check_bss_color_ie(tpAniSirGlobal mac_ctx,
+					tpPESession ap_session,
+					tSchBeaconStruct *bcn,
+					tUpdateBeaconParams *bcn_prm)
+{
+	/* check bss color in the beacon */
+	if (ap_session->he_op.present && !ap_session->he_op.bss_color) {
+		if (bcn->he_op.present &&
+			(bcn->he_op.bss_color ==
+					ap_session->he_op.bss_color)) {
+			ap_session->he_op.bss_col_disabled = 1;
+			bcn_prm->paramChangeBitmap |=
+						PARAM_BSS_COLOR_CHANGED;
+			ap_session->he_bss_color_change.countdown =
+						BSS_COLOR_SWITCH_COUNTDOWN;
+			ap_session->he_bss_color_change.new_color =
+					ap_get_new_bss_color(mac_ctx,
+								ap_session);
+			ap_session->he_op.bss_color = ap_session->
+						he_bss_color_change.new_color;
+			bcn_prm->bss_color = ap_session->he_op.bss_color;
+			bcn_prm->bss_color_disabled =
+					ap_session->he_op.bss_col_disabled;
+			ap_session->bss_color_changing = 1;
+		} else {
+			/* update info for the bss color */
+			if (bcn->he_op.present)
+				ap_update_bss_color_info(mac_ctx,
+						ap_session,
+						bcn->he_op.bss_color);
+		}
+	}
+}
+
+#else
+static void  sch_check_bss_color_ie(tpAniSirGlobal mac_ctx,
+					tpPESession ap_session,
+					tSchBeaconStruct *bcn,
+					tUpdateBeaconParams *bcn_prm)
+{
+}
+#endif
+
+void sch_beacon_process_for_ap(tpAniSirGlobal mac_ctx,
+				uint8_t session_id,
+				uint8_t *rx_pkt_info,
+				tSchBeaconStruct *bcn)
+{
+	tpPESession ap_session;
+	tUpdateBeaconParams bcn_prm;
+
+	if (!bcn || !rx_pkt_info) {
+		pe_debug("bcn %pK or rx_pkt_info %pKis NULL",
+			 bcn, rx_pkt_info);
+		return;
+	}
+
+	ap_session = pe_find_session_by_session_id(mac_ctx, session_id);
+	if (!ap_session)
+		return;
+
+	if (!LIM_IS_AP_ROLE(ap_session))
+		return;
+
+	qdf_mem_zero(&bcn_prm, sizeof(tUpdateBeaconParams));
+	bcn_prm.paramChangeBitmap = 0;
+
+	bcn_prm.bssIdx = ap_session->bssIdx;
+
+	if (!ap_session->is_session_obss_color_collision_det_enabled)
+		sch_check_bss_color_ie(mac_ctx, ap_session,
+					bcn, &bcn_prm);
+
+	if ((ap_session->gLimProtectionControl !=
+	     MLME_FORCE_POLICY_PROTECTION_DISABLE) &&
+	    !ap_session->is_session_obss_offload_enabled)
+		ap_beacon_process(mac_ctx, rx_pkt_info,
+					bcn, &bcn_prm, ap_session);
+
+	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
+	    && bcn_prm.paramChangeBitmap) {
+		/* Update the bcn and apply the new settings to HAL */
+		sch_set_fixed_beacon_fields(mac_ctx, ap_session);
+		pe_debug("Beacon for PE session[%d] got changed",
+		       ap_session->peSessionId);
+		pe_debug("sending beacon param change bitmap: 0x%x",
+		       bcn_prm.paramChangeBitmap);
+		lim_send_beacon_params(mac_ctx, &bcn_prm, ap_session);
+	}
+}
+
+/**
+ * sch_beacon_process() - process the beacon frame
+ * @mac_ctx: mac global context
+ * @rx_pkt_info: pointer to buffer descriptor
+ * @session: pointer to the PE session
+ *
+ * Return: None
+ */
+void
+sch_beacon_process(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+		   tpPESession session)
+{
+	static tSchBeaconStruct bcn;
+
+	/* Convert the beacon frame into a structure */
+	if (sir_convert_beacon_frame2_struct(mac_ctx, (uint8_t *) rx_pkt_info,
+		&bcn) != QDF_STATUS_SUCCESS) {
+		pe_err_rl("beacon parsing failed");
+		return;
+	}
+
+	/*
+	 * Now process the beacon in the context of the BSS which is
+	 * transmitting the beacons, if one is found
+	 */
+	if (session == NULL)
+		__sch_beacon_process_no_session(mac_ctx, &bcn, rx_pkt_info);
+	else
+		__sch_beacon_process_for_session(mac_ctx, &bcn, rx_pkt_info,
+						 session);
+}
+
+/**
+ * sch_beacon_edca_process(): Process the EDCA parameter set in the received
+ * beacon frame
+ *
+ * @mac_ctx:    mac global context
+ * @edca:       reference to edca parameters in beacon struct
+ * @session :   pesession entry
+ *
+ * @return status of operation
+ */
+QDF_STATUS
+sch_beacon_edca_process(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca,
+			tpPESession session)
+{
+	uint8_t i;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	host_log_qos_edca_pkt_type *log_ptr = NULL;
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	if (!(pMac->mlme_cfg)) {
+		pe_err("invalid mlme cfg");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pe_debug("Updating parameter set count: Old %d ---> new %d",
+		session->gLimEdcaParamSetCount, edca->qosInfo.count);
+
+	session->gLimEdcaParamSetCount = edca->qosInfo.count;
+	session->gLimEdcaParams[EDCA_AC_BE] = edca->acbe;
+	session->gLimEdcaParams[EDCA_AC_BK] = edca->acbk;
+	session->gLimEdcaParams[EDCA_AC_VI] = edca->acvi;
+	session->gLimEdcaParams[EDCA_AC_VO] = edca->acvo;
+
+	if (pMac->mlme_cfg->edca_params.enable_edca_params) {
+		session->gLimEdcaParams[EDCA_AC_VO].aci.aifsn =
+			pMac->mlme_cfg->edca_params.edca_ac_vo.vo_aifs;
+		session->gLimEdcaParams[EDCA_AC_VI].aci.aifsn =
+			pMac->mlme_cfg->edca_params.edca_ac_vi.vi_aifs;
+		session->gLimEdcaParams[EDCA_AC_BK].aci.aifsn =
+			pMac->mlme_cfg->edca_params.edca_ac_bk.bk_aifs;
+		session->gLimEdcaParams[EDCA_AC_BE].aci.aifsn =
+			pMac->mlme_cfg->edca_params.edca_ac_be.be_aifs;
+
+		session->gLimEdcaParams[EDCA_AC_VO].cw.min =
+			pMac->mlme_cfg->edca_params.edca_ac_vo.vo_cwmin;
+		session->gLimEdcaParams[EDCA_AC_VI].cw.min =
+			pMac->mlme_cfg->edca_params.edca_ac_vi.vi_cwmin;
+		session->gLimEdcaParams[EDCA_AC_BK].cw.min =
+			pMac->mlme_cfg->edca_params.edca_ac_bk.bk_cwmin;
+		session->gLimEdcaParams[EDCA_AC_BE].cw.min =
+			pMac->mlme_cfg->edca_params.edca_ac_be.be_cwmin;
+
+		session->gLimEdcaParams[EDCA_AC_VO].cw.max =
+			pMac->mlme_cfg->edca_params.edca_ac_vo.vo_cwmax;
+		session->gLimEdcaParams[EDCA_AC_VI].cw.max =
+			pMac->mlme_cfg->edca_params.edca_ac_vi.vi_cwmax;
+		session->gLimEdcaParams[EDCA_AC_BK].cw.max =
+			pMac->mlme_cfg->edca_params.edca_ac_bk.bk_cwmax;
+		session->gLimEdcaParams[EDCA_AC_BE].cw.max =
+			pMac->mlme_cfg->edca_params.edca_ac_be.be_cwmax;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_qos_edca_pkt_type,
+				 LOG_WLAN_QOS_EDCA_C);
+	if (log_ptr) {
+		log_ptr->aci_be = session->gLimEdcaParams[EDCA_AC_BE].aci.aci;
+		log_ptr->cw_be =
+			session->gLimEdcaParams[EDCA_AC_BE].cw.max << 4
+				| session->gLimEdcaParams[EDCA_AC_BE].cw.min;
+		log_ptr->txoplimit_be =
+			session->gLimEdcaParams[EDCA_AC_BE].txoplimit;
+		log_ptr->aci_bk =
+			session->gLimEdcaParams[EDCA_AC_BK].aci.aci;
+		log_ptr->cw_bk =
+			session->gLimEdcaParams[EDCA_AC_BK].cw.max << 4
+				| session->gLimEdcaParams[EDCA_AC_BK].cw.min;
+		log_ptr->txoplimit_bk =
+			session->gLimEdcaParams[EDCA_AC_BK].txoplimit;
+		log_ptr->aci_vi =
+			session->gLimEdcaParams[EDCA_AC_VI].aci.aci;
+		log_ptr->cw_vi =
+			session->gLimEdcaParams[EDCA_AC_VI].cw.max << 4
+				| session->gLimEdcaParams[EDCA_AC_VI].cw.min;
+		log_ptr->txoplimit_vi =
+			session->gLimEdcaParams[EDCA_AC_VI].txoplimit;
+		log_ptr->aci_vo =
+			session->gLimEdcaParams[EDCA_AC_VO].aci.aci;
+		log_ptr->cw_vo =
+			session->gLimEdcaParams[EDCA_AC_VO].cw.max << 4
+				| session->gLimEdcaParams[EDCA_AC_VO].cw.min;
+		log_ptr->txoplimit_vo =
+			session->gLimEdcaParams[EDCA_AC_VO].txoplimit;
+	}
+	WLAN_HOST_DIAG_LOG_REPORT(log_ptr);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+	pe_debug("Edca param enabled in ini %d. Updating Local EDCA Params(gLimEdcaParams) to: ",
+		 pMac->mlme_cfg->edca_params.enable_edca_params);
+	for (i = 0; i < MAX_NUM_AC; i++) {
+		pe_debug("AC[%d]:  AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d",
+		       i, session->gLimEdcaParams[i].aci.aifsn,
+		       session->gLimEdcaParams[i].aci.acm,
+		       session->gLimEdcaParams[i].cw.min,
+		       session->gLimEdcaParams[i].cw.max,
+		       session->gLimEdcaParams[i].txoplimit);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+void lim_enable_obss_detection_config(tpAniSirGlobal mac_ctx,
+				      tpPESession session)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!session) {
+		pe_err("Invalid session, protection not enabled");
+		return;
+	}
+
+	if (session->gLimProtectionControl ==
+	    MLME_FORCE_POLICY_PROTECTION_DISABLE) {
+		pe_err("protectiond disabled, force policy, session %d",
+		       session->smeSessionId);
+		return;
+	}
+
+	if (mac_ctx->lim.global_obss_offload_enabled) {
+		status = lim_obss_send_detection_cfg(mac_ctx, session, true);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pe_err("vdev %d: offload enable failed, trying legacy",
+			       session->smeSessionId);
+			session->is_session_obss_offload_enabled = false;
+		} else {
+			pe_debug("vdev %d: offload detection enabled",
+				 session->smeSessionId);
+			session->is_session_obss_offload_enabled = true;
+			lim_obss_send_detection_cfg(mac_ctx, session, true);
+		}
+	}
+
+	if (!mac_ctx->lim.global_obss_offload_enabled ||
+	    QDF_IS_STATUS_ERROR(status)) {
+		status = qdf_mc_timer_start(&session->
+					    protection_fields_reset_timer,
+					    SCH_PROTECTION_RESET_TIME);
+		if (QDF_IS_STATUS_ERROR(status))
+			pe_err("vdev %d: start timer failed",
+			       session->smeSessionId);
+		else
+			pe_debug("vdev %d: legacy detection enabled",
+				 session->smeSessionId);
+	}
+}
+
+QDF_STATUS lim_obss_generate_detection_config(tpAniSirGlobal mac_ctx,
+					      tpPESession session,
+					      struct obss_detection_cfg *cfg)
+{
+	uint32_t phy_mode;
+	enum band_info rf_band = BAND_UNKNOWN;
+	struct obss_detection_cfg *cur_detect;
+
+	if (!mac_ctx || !session || !cfg) {
+		pe_err("Invalid params mac_ctx %pK, session %pK, cfg %pK",
+			mac_ctx, session, cfg);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	lim_get_phy_mode(mac_ctx, &phy_mode, session);
+	rf_band = session->limRFBand;
+	qdf_mem_zero(cfg, sizeof(*cfg));
+	cur_detect = &session->current_obss_detection;
+
+	pe_debug("band:%d, phy_mode:%d, ht_cap:%d, ht_oper_mode:%d",
+		 rf_band, phy_mode, session->htCapability,
+		 mac_ctx->lim.gHTOperMode);
+	pe_debug("assoc_sta: 11b:%d, 11g:%d, 11a:%d, ht20:%d",
+		 session->gLim11bParams.protectionEnabled,
+		 session->gLim11gParams.protectionEnabled,
+		 session->gLim11aParams.protectionEnabled,
+		 session->gLimHt20Params.protectionEnabled);
+	pe_debug("obss: 11b:%d, 11g:%d, 11a:%d, ht20:%d",
+		 session->gLimOlbcParams.protectionEnabled,
+		 session->gLimOverlap11gParams.protectionEnabled,
+		 session->gLimOverlap11aParams.protectionEnabled,
+		 session->gLimOverlapHt20Params.protectionEnabled);
+	pe_debug("detect: b_ap:%d, b_s:%d, g:%d, a:%d, htl:%d, htm:%d, ht20:%d",
+		 cur_detect->obss_11b_ap_detect_mode,
+		 cur_detect->obss_11b_sta_detect_mode,
+		 cur_detect->obss_11g_ap_detect_mode,
+		 cur_detect->obss_11a_detect_mode,
+		 cur_detect->obss_ht_legacy_detect_mode,
+		 cur_detect->obss_ht_mixed_detect_mode,
+		 cur_detect->obss_ht_20mhz_detect_mode);
+
+	if (rf_band == BAND_2G) {
+		if ((phy_mode == WNI_CFG_PHY_MODE_11G ||
+		    session->htCapability) &&
+		    !session->gLim11bParams.protectionEnabled) {
+			if (!session->gLimOlbcParams.protectionEnabled &&
+			    !session->gLimOverlap11gParams.protectionEnabled) {
+				cfg->obss_11b_ap_detect_mode =
+					OBSS_OFFLOAD_DETECTION_PRESENT;
+				cfg->obss_11b_sta_detect_mode =
+					OBSS_OFFLOAD_DETECTION_PRESENT;
+			} else {
+				if (cur_detect->obss_11b_ap_detect_mode ==
+				    OBSS_OFFLOAD_DETECTION_PRESENT)
+					cfg->obss_11b_ap_detect_mode =
+						OBSS_OFFLOAD_DETECTION_ABSENT;
+				if (cur_detect->obss_11b_sta_detect_mode ==
+				    OBSS_OFFLOAD_DETECTION_PRESENT)
+					cfg->obss_11b_sta_detect_mode =
+						OBSS_OFFLOAD_DETECTION_ABSENT;
+			}
+		} else if (session->gLim11bParams.protectionEnabled) {
+			session->gLimOlbcParams.protectionEnabled = false;
+		}
+
+		if (session->htCapability &&
+		    session->cfgProtection.overlapFromllg &&
+		    !session->gLim11gParams.protectionEnabled) {
+			if (!session->gLimOverlap11gParams.protectionEnabled) {
+				cfg->obss_11g_ap_detect_mode =
+					OBSS_OFFLOAD_DETECTION_PRESENT;
+				cfg->obss_ht_legacy_detect_mode =
+					OBSS_OFFLOAD_DETECTION_PRESENT;
+				cfg->obss_ht_mixed_detect_mode =
+					OBSS_OFFLOAD_DETECTION_PRESENT;
+			} else {
+				if (cur_detect->obss_11g_ap_detect_mode ==
+				    OBSS_OFFLOAD_DETECTION_PRESENT)
+					cfg->obss_11g_ap_detect_mode =
+						OBSS_OFFLOAD_DETECTION_ABSENT;
+				if (cur_detect->obss_ht_legacy_detect_mode ==
+				    OBSS_OFFLOAD_DETECTION_PRESENT)
+					cfg->obss_ht_legacy_detect_mode =
+						OBSS_OFFLOAD_DETECTION_ABSENT;
+				if (cur_detect->obss_ht_mixed_detect_mode ==
+				    OBSS_OFFLOAD_DETECTION_PRESENT)
+					cfg->obss_ht_mixed_detect_mode =
+						OBSS_OFFLOAD_DETECTION_ABSENT;
+			}
+		} else if (session->gLim11gParams.protectionEnabled) {
+			session->gLimOverlap11gParams.protectionEnabled = false;
+		}
+
+		/* INI related settings */
+		if (mac_ctx->mlme_cfg->sta.ignore_peer_erp_info)
+			cfg->obss_11b_sta_detect_mode =
+				OBSS_OFFLOAD_DETECTION_DISABLED;
+
+		if (mac_ctx->mlme_cfg->sap_protection_cfg.ignore_peer_ht_opmode)
+			cfg->obss_ht_legacy_detect_mode =
+				OBSS_OFFLOAD_DETECTION_DISABLED;
+	}
+
+	if ((rf_band == BAND_5G) && session->htCapability) {
+		if (!session->gLim11aParams.protectionEnabled) {
+			if (!session->gLimOverlap11aParams.protectionEnabled)
+				cfg->obss_11a_detect_mode =
+					OBSS_OFFLOAD_DETECTION_PRESENT;
+			else if (cur_detect->obss_11a_detect_mode ==
+				 OBSS_OFFLOAD_DETECTION_PRESENT)
+					cfg->obss_11a_detect_mode =
+						OBSS_OFFLOAD_DETECTION_ABSENT;
+		} else {
+			session->gLimOverlap11aParams.protectionEnabled = false;
+		}
+	}
+
+	if (((rf_band == BAND_2G) || (rf_band == BAND_5G)) &&
+	    session->htCapability) {
+
+		if (!session->gLimHt20Params.protectionEnabled) {
+			if (!session->gLimOverlapHt20Params.protectionEnabled) {
+				cfg->obss_ht_20mhz_detect_mode =
+					OBSS_OFFLOAD_DETECTION_PRESENT;
+			} else if (cur_detect->obss_ht_20mhz_detect_mode ==
+				   OBSS_OFFLOAD_DETECTION_PRESENT) {
+					cfg->obss_ht_20mhz_detect_mode =
+					OBSS_OFFLOAD_DETECTION_ABSENT;
+			}
+		} else {
+			session->gLimOverlapHt20Params.protectionEnabled =
+				false;
+		}
+	}
+
+	pe_debug("b_ap:%d, b_s:%d, g:%d, a:%d, ht_le:%d, ht_m:%d, ht_20:%d",
+		 cfg->obss_11b_ap_detect_mode,
+		 cfg->obss_11b_sta_detect_mode,
+		 cfg->obss_11g_ap_detect_mode,
+		 cfg->obss_11a_detect_mode,
+		 cfg->obss_ht_legacy_detect_mode,
+		 cfg->obss_ht_mixed_detect_mode,
+		 cfg->obss_ht_20mhz_detect_mode);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS lim_obss_send_detection_cfg(tpAniSirGlobal mac_ctx,
+				       tpPESession session, bool force)
+{
+	QDF_STATUS status;
+	struct obss_detection_cfg obss_cfg;
+	struct wmi_obss_detection_cfg_param *req_param;
+
+	if (!session) {
+		pe_err("Invalid session");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!session->is_session_obss_offload_enabled) {
+		pe_debug("obss offload protectiond disabled, session %d",
+		       session->smeSessionId);
+		/* Send success */
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (session->gLimProtectionControl ==
+	    MLME_FORCE_POLICY_PROTECTION_DISABLE) {
+		pe_debug("protectiond disabled, force from policy, session %d",
+		       session->smeSessionId);
+		/* Send success */
+		return QDF_STATUS_SUCCESS;
+	}
+
+	status = lim_obss_generate_detection_config(mac_ctx,
+						    session,
+						    &obss_cfg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("Failed to generate obss detection cfg, session %d",
+		       session->smeSessionId);
+		return status;
+	}
+
+	if (qdf_mem_cmp(&session->obss_offload_cfg, &obss_cfg, sizeof(obss_cfg))
+	    || force) {
+		struct scheduler_msg msg = {0};
+		req_param = qdf_mem_malloc(sizeof(*req_param));
+		if (!req_param)
+			return QDF_STATUS_E_NOMEM;
+		qdf_mem_copy(&session->obss_offload_cfg, &obss_cfg,
+				sizeof(obss_cfg));
+		req_param->vdev_id = session->smeSessionId;
+		req_param->obss_detect_period_ms = OBSS_DETECTION_PERIOD_MS;
+		req_param->obss_11b_ap_detect_mode =
+			obss_cfg.obss_11b_ap_detect_mode;
+		req_param->obss_11b_sta_detect_mode =
+			obss_cfg.obss_11b_sta_detect_mode;
+		req_param->obss_11g_ap_detect_mode =
+			obss_cfg.obss_11g_ap_detect_mode;
+		req_param->obss_11a_detect_mode =
+			obss_cfg.obss_11a_detect_mode;
+		req_param->obss_ht_legacy_detect_mode =
+			obss_cfg.obss_ht_legacy_detect_mode;
+		req_param->obss_ht_20mhz_detect_mode =
+			obss_cfg.obss_ht_20mhz_detect_mode;
+		req_param->obss_ht_mixed_detect_mode =
+			obss_cfg.obss_ht_mixed_detect_mode;
+
+		msg.type = WMA_OBSS_DETECTION_REQ;
+		msg.bodyptr = req_param;
+		msg.reserved = 0;
+		status = scheduler_post_message(QDF_MODULE_ID_PE,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &msg);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pe_err("Failed to post WMA_OBSS_DETECTION_REQ to WMA");
+			qdf_mem_free(req_param);
+			return status;
+		}
+	} else {
+		pe_debug("Skiping WMA_OBSS_DETECTION_REQ, force = %d", force);
+	}
+
+	return status;
+}
+
+QDF_STATUS lim_process_obss_detection_ind(tpAniSirGlobal mac_ctx,
+					  struct wmi_obss_detect_info
+					  *obss_detection)
+{
+	QDF_STATUS status;
+	uint32_t detect_masks;
+	uint32_t reason;
+	struct obss_detection_cfg *obss_cfg;
+	bool enable;
+	tpPESession session;
+	tUpdateBeaconParams bcn_prm;
+	enum band_info rf_band = BAND_UNKNOWN;
+	struct obss_detection_cfg *cur_detect;
+
+	pe_debug("obss detect ind id %d, reason %d, msk 0x%x, " MAC_ADDRESS_STR,
+		 obss_detection->vdev_id, obss_detection->reason,
+		 obss_detection->matched_detection_masks,
+		 MAC_ADDR_ARRAY(obss_detection->matched_bssid_addr));
+
+	session = pe_find_session_by_sme_session_id(mac_ctx,
+						    obss_detection->vdev_id);
+	if (!session) {
+		pe_err("Failed to get session for id %d",
+		       obss_detection->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!LIM_IS_AP_ROLE(session)) {
+		pe_err("session %d is not AP", obss_detection->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!session->is_session_obss_offload_enabled) {
+		pe_err("Offload already disabled for session %d",
+		       obss_detection->vdev_id);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	reason = obss_detection->reason;
+	detect_masks = obss_detection->matched_detection_masks;
+
+	if (reason == OBSS_OFFLOAD_DETECTION_PRESENT) {
+		enable = true;
+	} else if (reason == OBSS_OFFLOAD_DETECTION_ABSENT) {
+		enable = false;
+	} else if (reason == OBSS_OFFLOAD_DETECTION_DISABLED) {
+		/*
+		 * Most common reason for this event-type from firmware
+		 * is insufficient memory.
+		 * Disable offload OBSS detection and enable legacy-way
+		 * of detecting OBSS by parsing beacons.
+		 **/
+		session->is_session_obss_offload_enabled = false;
+		pe_err("FW indicated obss offload disabled");
+		pe_err("Enabling host based detection, session %d",
+		       obss_detection->vdev_id);
+
+		status = qdf_mc_timer_start(&session->
+					    protection_fields_reset_timer,
+					    SCH_PROTECTION_RESET_TIME);
+		if (QDF_IS_STATUS_ERROR(status))
+			pe_err("cannot start protection reset timer");
+
+		return QDF_STATUS_SUCCESS;
+	} else {
+		pe_err("Invalid reason %d, session %d",
+		       obss_detection->reason,
+		       obss_detection->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	rf_band = session->limRFBand;
+	qdf_mem_zero(&bcn_prm, sizeof(bcn_prm));
+	obss_cfg = &session->obss_offload_cfg;
+	cur_detect = &session->current_obss_detection;
+
+	if (OBSS_DETECTION_IS_11B_AP(detect_masks)) {
+		if (reason != obss_cfg->obss_11b_ap_detect_mode ||
+		    rf_band != BAND_2G)
+			goto wrong_detection;
+
+		lim_enable11g_protection(mac_ctx, enable, true,
+					 &bcn_prm, session);
+		cur_detect->obss_11b_ap_detect_mode = reason;
+	}
+	if (OBSS_DETECTION_IS_11B_STA(detect_masks)) {
+		if (reason != obss_cfg->obss_11b_sta_detect_mode ||
+		    rf_band != BAND_2G)
+			goto wrong_detection;
+
+		lim_enable11g_protection(mac_ctx, enable, true,
+					 &bcn_prm, session);
+		cur_detect->obss_11b_sta_detect_mode = reason;
+	}
+	if (OBSS_DETECTION_IS_11G_AP(detect_masks)) {
+		if (reason != obss_cfg->obss_11g_ap_detect_mode ||
+		    rf_band != BAND_2G)
+			goto wrong_detection;
+
+		lim_enable_ht_protection_from11g(mac_ctx, enable, true,
+						 &bcn_prm, session);
+		cur_detect->obss_11g_ap_detect_mode = reason;
+	}
+	if (OBSS_DETECTION_IS_11A(detect_masks)) {
+		if (reason != obss_cfg->obss_11a_detect_mode ||
+		    rf_band != BAND_5G)
+			goto wrong_detection;
+
+		lim_update_11a_protection(mac_ctx, enable, true,
+					  &bcn_prm, session);
+		cur_detect->obss_11a_detect_mode = reason;
+	}
+	if (OBSS_DETECTION_IS_HT_LEGACY(detect_masks)) {
+		/* for 5GHz, we have only 11a detection, which covers legacy */
+		if (reason != obss_cfg->obss_ht_legacy_detect_mode ||
+		    rf_band != BAND_2G)
+			goto wrong_detection;
+
+		lim_enable_ht_protection_from11g(mac_ctx, enable, true,
+						 &bcn_prm, session);
+		cur_detect->obss_ht_legacy_detect_mode = reason;
+	}
+	if (OBSS_DETECTION_IS_HT_MIXED(detect_masks)) {
+		/* for 5GHz, we have only 11a detection, which covers ht mix */
+		if (reason != obss_cfg->obss_ht_mixed_detect_mode ||
+		    rf_band != BAND_2G)
+			goto wrong_detection;
+
+		lim_enable_ht_protection_from11g(mac_ctx, enable, true,
+						 &bcn_prm, session);
+		cur_detect->obss_ht_mixed_detect_mode = reason;
+	}
+	if (OBSS_DETECTION_IS_HT_20MHZ(detect_masks)) {
+		if (reason != obss_cfg->obss_ht_20mhz_detect_mode)
+			goto wrong_detection;
+
+		lim_enable_ht20_protection(mac_ctx, enable, true,
+					   &bcn_prm, session);
+		cur_detect->obss_ht_20mhz_detect_mode = reason;
+	}
+
+	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) &&
+	    bcn_prm.paramChangeBitmap) {
+		/* Update the bcn and apply the new settings to HAL */
+		sch_set_fixed_beacon_fields(mac_ctx, session);
+		pe_debug("Beacon for PE session: %d got changed: 0x%x",
+			 session->smeSessionId, bcn_prm.paramChangeBitmap);
+		if (!QDF_IS_STATUS_SUCCESS(lim_send_beacon_params(
+		     mac_ctx, &bcn_prm, session))) {
+			pe_err("Failed to send beacon param, session %d",
+				obss_detection->vdev_id);
+			return QDF_STATUS_E_FAULT;
+		}
+	}
+
+	status = lim_obss_send_detection_cfg(mac_ctx, session, true);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("Failed to send obss detection cfg, session %d",
+			obss_detection->vdev_id);
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+wrong_detection:
+	/*
+	 * We may get this wrong detection before FW can update latest cfg,
+	 * So keeping log level debug
+	 **/
+	pe_debug("Wrong detection, session %d", obss_detection->vdev_id);
+
+	return QDF_STATUS_E_INVAL;
+}
diff --git a/core/mac/src/pe/sch/sch_message.c b/core/mac/src/pe/sch/sch_message.c
new file mode 100644
index 0000000..46c1128
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_message.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#include "cds_api.h"
+#include "sir_common.h"
+
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+#include "lim_api.h"
+#include "lim_send_messages.h"
+
+#include "sch_api.h"
+#include "wlan_mlme_api.h"
+
+/* / Minimum beacon interval allowed (in Kus) */
+#define SCH_BEACON_INTERVAL_MIN  10
+
+/* / Maximum beacon interval allowed (in Kus) */
+#define SCH_BEACON_INTERVAL_MAX  10000
+
+/* / convert the CW values into a uint16_t */
+#define GET_CW(pCw) ((uint16_t) ((*(pCw) << 8) + *((pCw) + 1)))
+
+/* local functions */
+static QDF_STATUS
+get_wmm_local_params(tpAniSirGlobal pMac,
+		     uint32_t params[][CFG_EDCA_DATA_LEN]);
+static void
+set_sch_edca_params(tpAniSirGlobal pMac,
+		    uint32_t params[][CFG_EDCA_DATA_LEN],
+		    tpPESession psessionEntry);
+
+/* -------------------------------------------------------------------- */
+/**
+ * sch_set_beacon_interval
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+void sch_set_beacon_interval(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	uint32_t bi;
+
+	bi = psessionEntry->beaconParams.beaconInterval;
+
+	if (bi < SCH_BEACON_INTERVAL_MIN || bi > SCH_BEACON_INTERVAL_MAX) {
+		pe_debug("Invalid beacon interval %d (should be [%d,%d]", bi,
+			SCH_BEACON_INTERVAL_MIN, SCH_BEACON_INTERVAL_MAX);
+		return;
+	}
+
+	pMac->sch.schObject.gSchBeaconInterval = (uint16_t) bi;
+}
+
+static void sch_edca_profile_update_all(tpAniSirGlobal pmac)
+{
+	uint32_t i;
+	tpPESession psession_entry;
+
+	for (i = 0; i < pmac->lim.maxBssId; i++) {
+		psession_entry = &pmac->lim.gpSession[i];
+		if (psession_entry->valid)
+			sch_edca_profile_update(pmac, psession_entry);
+	}
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * sch_process_message
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+void sch_process_message(tpAniSirGlobal pMac, struct scheduler_msg *pSchMsg)
+{
+	switch (pSchMsg->type) {
+	case SIR_CFG_PARAM_UPDATE_IND:
+		switch (pSchMsg->bodyval) {
+		case WNI_CFG_COUNTRY_CODE:
+			pe_debug("sch: WNI_CFG_COUNTRY_CODE changed");
+			sch_edca_profile_update_all(pMac);
+			break;
+
+		default:
+			pe_err("Cfg param %d indication not handled",
+				pSchMsg->bodyval);
+		}
+		break;
+
+	default:
+		pe_err("Unknown message in schMsgQ type %d", pSchMsg->type);
+	}
+
+}
+
+/**
+ * sch_get_params() - get the local or broadcast parameters based on the profile
+ * sepcified in the config params are delivered in this order: BE, BK, VI, VO
+ */
+static QDF_STATUS
+sch_get_params(tpAniSirGlobal pMac,
+	       uint32_t params[][CFG_EDCA_DATA_LEN],
+	       uint8_t local)
+{
+	uint32_t val;
+	uint32_t i, idx;
+	uint32_t *prf;
+	struct wlan_mlme_edca_params *edca_params;
+	QDF_STATUS status;
+	uint8_t country_code_str[WNI_CFG_COUNTRY_CODE_LEN];
+	uint32_t country_code_len = WNI_CFG_COUNTRY_CODE_LEN;
+	uint32_t ani_l[] = {edca_ani_acbe_local, edca_ani_acbk_local,
+			    edca_ani_acvi_local, edca_ani_acvo_local};
+
+	uint32_t wme_l[] = {edca_wme_acbe_local, edca_wme_acbk_local,
+			    edca_wme_acvi_local, edca_wme_acvo_local};
+
+	uint32_t etsi_l[] = {edca_etsi_acbe_local, edca_etsi_acbk_local,
+			     edca_etsi_acvi_local, edca_etsi_acvo_local};
+
+	uint32_t ani_b[] = {edca_ani_acbe_bcast, edca_ani_acbk_bcast,
+			    edca_ani_acvi_bcast, edca_ani_acvo_bcast};
+
+	uint32_t wme_b[] = {edca_wme_acbe_bcast, edca_wme_acbk_bcast,
+			    edca_wme_acvi_bcast, edca_wme_acvo_bcast};
+
+	uint32_t etsi_b[] = {edca_etsi_acbe_bcast, edca_etsi_acbk_bcast,
+			     edca_etsi_acvi_bcast, edca_etsi_acvo_bcast};
+	edca_params = &pMac->mlme_cfg->edca_params;
+
+	if (wlan_cfg_get_str(pMac, WNI_CFG_COUNTRY_CODE, country_code_str,
+			     &country_code_len) == QDF_STATUS_SUCCESS &&
+	    cds_is_etsi_europe_country(country_code_str)) {
+		val = WNI_CFG_EDCA_PROFILE_ETSI_EUROPE;
+		pe_debug("switch to ETSI EUROPE profile country code %c%c",
+			 country_code_str[0], country_code_str[1]);
+	} else {
+		val = pMac->mlme_cfg->wmm_params.edca_profile;
+	}
+	if (val >= WNI_CFG_EDCA_PROFILE_MAX) {
+		pe_warn("Invalid EDCA_PROFILE %d, using %d instead", val,
+			WNI_CFG_EDCA_PROFILE_ANI);
+		val = WNI_CFG_EDCA_PROFILE_ANI;
+	}
+
+	pe_debug("EdcaProfile: Using %d (%s)", val,
+		((val == WNI_CFG_EDCA_PROFILE_WMM) ? "WMM" : "HiPerf"));
+
+	if (local) {
+		switch (val) {
+		case WNI_CFG_EDCA_PROFILE_WMM:
+			prf = &wme_l[0];
+			break;
+		case WNI_CFG_EDCA_PROFILE_ETSI_EUROPE:
+			prf = &etsi_l[0];
+			break;
+		case WNI_CFG_EDCA_PROFILE_ANI:
+		default:
+			prf = &ani_l[0];
+			break;
+		}
+	} else {
+		switch (val) {
+		case WNI_CFG_EDCA_PROFILE_WMM:
+			prf = &wme_b[0];
+			break;
+		case WNI_CFG_EDCA_PROFILE_ETSI_EUROPE:
+			prf = &etsi_b[0];
+			break;
+		case WNI_CFG_EDCA_PROFILE_ANI:
+		default:
+			prf = &ani_b[0];
+			break;
+		}
+	}
+
+	for (i = 0; i < 4; i++) {
+		uint8_t data[CFG_EDCA_DATA_LEN];
+
+		status = wlan_mlme_get_edca_params(edca_params,
+						   (uint8_t *)&data[0],
+						   (uint8_t)prf[i]);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pe_err("Get failed for ac:%d", i);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		for (idx = 0; idx < CFG_EDCA_DATA_LEN; idx++)
+			params[i][idx] = (uint32_t) data[idx];
+	}
+	pe_debug("GetParams: local=%d, profile = %d Done", local, val);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * broadcast_wmm_of_concurrent_sta_session() - broadcasts wmm info
+ * @mac_ctx:          mac global context
+ * @session:       pesession entry
+ *
+ * Return: true if wmm param updated, false if wmm param not updated
+ */
+static bool
+broadcast_wmm_of_concurrent_sta_session(tpAniSirGlobal mac_ctx,
+					tpPESession session)
+{
+	uint8_t i, j;
+	tpPESession concurrent_session = NULL;
+
+	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+		/*
+		 * Find another INFRA STA AP session on same operating channel.
+		 * The session entry passed to this API is for GO/SoftAP session
+		 * that is getting added currently
+		 */
+		if (!((mac_ctx->lim.gpSession[i].valid == true) &&
+		    (mac_ctx->lim.gpSession[i].peSessionId !=
+		     session->peSessionId)
+		    && (mac_ctx->lim.gpSession[i].currentOperChannel ==
+			session->currentOperChannel)
+		    && (mac_ctx->lim.gpSession[i].limSystemRole
+			== eLIM_STA_ROLE)))
+			continue;
+
+		concurrent_session = &(mac_ctx->lim.gpSession[i]);
+		break;
+	}
+
+	if (concurrent_session == NULL)
+		return false;
+
+	if (!qdf_mem_cmp(session->gLimEdcaParamsBC,
+			 concurrent_session->gLimEdcaParams,
+			 sizeof(concurrent_session->gLimEdcaParams)))
+		return false;
+
+	/*
+	 * Once atleast one concurrent session on same channel is found and WMM
+	 * broadcast params for current SoftAP/GO session updated, return
+	 */
+	for (j = 0; j < MAX_NUM_AC; j++) {
+		session->gLimEdcaParamsBC[j].aci.acm =
+			concurrent_session->gLimEdcaParams[j].aci.acm;
+		session->gLimEdcaParamsBC[j].aci.aifsn =
+			concurrent_session->gLimEdcaParams[j].aci.aifsn;
+		session->gLimEdcaParamsBC[j].cw.min =
+			concurrent_session->gLimEdcaParams[j].cw.min;
+		session->gLimEdcaParamsBC[j].cw.max =
+			concurrent_session->gLimEdcaParams[j].cw.max;
+		session->gLimEdcaParamsBC[j].txoplimit =
+			concurrent_session->gLimEdcaParams[j].txoplimit;
+		pe_debug("QoSUpdateBCast changed again due to concurrent INFRA STA session: AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d",
+		       j, session->gLimEdcaParamsBC[j].aci.aifsn,
+		       session->gLimEdcaParamsBC[j].aci.acm,
+		       session->gLimEdcaParamsBC[j].cw.min,
+		       session->gLimEdcaParamsBC[j].cw.max,
+		       session->gLimEdcaParamsBC[j].txoplimit);
+	}
+	return true;
+}
+
+void sch_qos_update_broadcast(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	uint32_t params[4][CFG_EDCA_DATA_LEN];
+	uint32_t cwminidx, cwmaxidx, txopidx;
+	uint32_t phyMode;
+	uint8_t i;
+	bool updated = false;
+	QDF_STATUS status;
+
+	if (sch_get_params(pMac, params, false) != QDF_STATUS_SUCCESS) {
+		pe_debug("QosUpdateBroadcast: failed");
+		return;
+	}
+	lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+	pe_debug("QosUpdBcast: mode %d", phyMode);
+
+	if (phyMode == WNI_CFG_PHY_MODE_11G) {
+		cwminidx = CFG_EDCA_PROFILE_CWMING_IDX;
+		cwmaxidx = CFG_EDCA_PROFILE_CWMAXG_IDX;
+		txopidx = CFG_EDCA_PROFILE_TXOPG_IDX;
+	} else if (phyMode == WNI_CFG_PHY_MODE_11B) {
+		cwminidx = CFG_EDCA_PROFILE_CWMINB_IDX;
+		cwmaxidx = CFG_EDCA_PROFILE_CWMAXB_IDX;
+		txopidx = CFG_EDCA_PROFILE_TXOPB_IDX;
+	} else {
+		/* This can happen if mode is not set yet, assume 11a mode */
+		cwminidx = CFG_EDCA_PROFILE_CWMINA_IDX;
+		cwmaxidx = CFG_EDCA_PROFILE_CWMAXA_IDX;
+		txopidx = CFG_EDCA_PROFILE_TXOPA_IDX;
+	}
+
+	for (i = 0; i < MAX_NUM_AC; i++) {
+		if (psessionEntry->gLimEdcaParamsBC[i].aci.acm !=
+			(uint8_t)params[i][CFG_EDCA_PROFILE_ACM_IDX]) {
+			psessionEntry->gLimEdcaParamsBC[i].aci.acm =
+			(uint8_t)params[i][CFG_EDCA_PROFILE_ACM_IDX];
+			updated = true;
+		}
+		if (psessionEntry->gLimEdcaParamsBC[i].aci.aifsn !=
+			(uint8_t)params[i][CFG_EDCA_PROFILE_AIFSN_IDX]) {
+			psessionEntry->gLimEdcaParamsBC[i].aci.aifsn =
+			(uint8_t)params[i][CFG_EDCA_PROFILE_AIFSN_IDX];
+			updated = true;
+		}
+		if (psessionEntry->gLimEdcaParamsBC[i].cw.min !=
+			convert_cw(GET_CW(&params[i][cwminidx]))) {
+			psessionEntry->gLimEdcaParamsBC[i].cw.min =
+			convert_cw(GET_CW(&params[i][cwminidx]));
+			updated = true;
+		}
+		if (psessionEntry->gLimEdcaParamsBC[i].cw.max !=
+			convert_cw(GET_CW(&params[i][cwmaxidx]))) {
+			psessionEntry->gLimEdcaParamsBC[i].cw.max =
+			convert_cw(GET_CW(&params[i][cwmaxidx]));
+			updated = true;
+		}
+		if (psessionEntry->gLimEdcaParamsBC[i].txoplimit !=
+			(uint16_t)params[i][txopidx]) {
+			psessionEntry->gLimEdcaParamsBC[i].txoplimit =
+			(uint16_t)params[i][txopidx];
+			updated = true;
+		}
+
+		pe_debug("QoSUpdateBCast: AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d",
+			       i, psessionEntry->gLimEdcaParamsBC[i].aci.aifsn,
+			       psessionEntry->gLimEdcaParamsBC[i].aci.acm,
+			       psessionEntry->gLimEdcaParamsBC[i].cw.min,
+			       psessionEntry->gLimEdcaParamsBC[i].cw.max,
+			       psessionEntry->gLimEdcaParamsBC[i].txoplimit);
+
+	}
+
+	/*
+	 * If there exists a concurrent STA-AP session, use its WMM
+	 * params to broadcast in beacons. WFA Wifi Direct test plan
+	 * 6.1.14 requirement
+	 */
+	if (broadcast_wmm_of_concurrent_sta_session(pMac, psessionEntry))
+		updated = true;
+	if (updated)
+		psessionEntry->gLimEdcaParamSetCount++;
+
+	status = sch_set_fixed_beacon_fields(pMac, psessionEntry);
+	if (QDF_IS_STATUS_ERROR(status))
+		pe_err("Unable to set beacon fields!");
+}
+
+void sch_qos_update_local(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+
+	uint32_t params[4][CFG_EDCA_DATA_LEN];
+	QDF_STATUS status;
+
+	status = sch_get_params(pMac, params, true /*local */);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("sch_get_params(local) failed");
+		return;
+	}
+
+	set_sch_edca_params(pMac, params, psessionEntry);
+
+	/* For AP, the bssID is stored in LIM Global context. */
+	lim_send_edca_params(pMac, psessionEntry->gLimEdcaParams,
+			     psessionEntry->bssIdx, false);
+}
+
+/**
+ * sch_set_default_edca_params() - This function sets the gLimEdcaParams to the
+ * default local wmm profile.
+ * @pMac - Global mac context
+ * @psessionEntry - PE session
+ *
+ * return none
+ */
+void sch_set_default_edca_params(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	uint32_t params[4][CFG_EDCA_DATA_LEN];
+
+	if (get_wmm_local_params(pMac, params) != QDF_STATUS_SUCCESS) {
+		pe_err("get_wmm_local_params() failed");
+		return;
+	}
+
+	set_sch_edca_params(pMac, params, psessionEntry);
+	return;
+}
+
+/**
+ * set_sch_edca_params() - This function fills in the gLimEdcaParams structure
+ * with the given edca params.
+ * @pMac - global mac context
+ * @psessionEntry - PE session
+ * @params - EDCA parameters
+ *
+ * Return  none
+ */
+static void
+set_sch_edca_params(tpAniSirGlobal pMac,
+		    uint32_t params[][CFG_EDCA_DATA_LEN],
+		    tpPESession psessionEntry)
+{
+	uint32_t i;
+	uint32_t cwminidx, cwmaxidx, txopidx;
+	uint32_t phyMode;
+
+	lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+	pe_debug("lim_get_phy_mode() = %d", phyMode);
+	/* if (pMac->lim.gLimPhyMode == WNI_CFG_PHY_MODE_11G) */
+	if (phyMode == WNI_CFG_PHY_MODE_11G) {
+		cwminidx = CFG_EDCA_PROFILE_CWMING_IDX;
+		cwmaxidx = CFG_EDCA_PROFILE_CWMAXG_IDX;
+		txopidx = CFG_EDCA_PROFILE_TXOPG_IDX;
+	}
+	/* else if (pMac->lim.gLimPhyMode == WNI_CFG_PHY_MODE_11B) */
+	else if (phyMode == WNI_CFG_PHY_MODE_11B) {
+		cwminidx = CFG_EDCA_PROFILE_CWMINB_IDX;
+		cwmaxidx = CFG_EDCA_PROFILE_CWMAXB_IDX;
+		txopidx = CFG_EDCA_PROFILE_TXOPB_IDX;
+	} else {
+		/* This can happen if mode is not set yet, assume 11a mode */
+		cwminidx = CFG_EDCA_PROFILE_CWMINA_IDX;
+		cwmaxidx = CFG_EDCA_PROFILE_CWMAXA_IDX;
+		txopidx = CFG_EDCA_PROFILE_TXOPA_IDX;
+	}
+
+	for (i = 0; i < MAX_NUM_AC; i++) {
+		psessionEntry->gLimEdcaParams[i].aci.acm =
+			(uint8_t)params[i][CFG_EDCA_PROFILE_ACM_IDX];
+		psessionEntry->gLimEdcaParams[i].aci.aifsn =
+			(uint8_t)params[i][CFG_EDCA_PROFILE_AIFSN_IDX];
+		psessionEntry->gLimEdcaParams[i].cw.min =
+			convert_cw(GET_CW(&params[i][cwminidx]));
+		psessionEntry->gLimEdcaParams[i].cw.max =
+			convert_cw(GET_CW(&params[i][cwmaxidx]));
+		psessionEntry->gLimEdcaParams[i].txoplimit =
+			(uint16_t)params[i][txopidx];
+
+		pe_debug("AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d",
+			       i, psessionEntry->gLimEdcaParams[i].aci.aifsn,
+			       psessionEntry->gLimEdcaParams[i].aci.acm,
+			       psessionEntry->gLimEdcaParams[i].cw.min,
+			       psessionEntry->gLimEdcaParams[i].cw.max,
+			       psessionEntry->gLimEdcaParams[i].txoplimit);
+
+	}
+	return;
+}
+
+/**
+ * get_wmm_local_params() - This function gets the WMM local edca parameters.
+ * @pMac
+ * @params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]
+ *
+ * Return  none
+ */
+static QDF_STATUS
+get_wmm_local_params(tpAniSirGlobal mac_ctx,
+		     uint32_t params[][CFG_EDCA_DATA_LEN])
+{
+	uint32_t i, idx;
+	QDF_STATUS status;
+	struct wlan_mlme_edca_params *edca_params;
+	uint32_t wme_l[] = {edca_wme_acbe_local, edca_wme_acbk_local,
+			    edca_wme_acvi_local, edca_wme_acvo_local};
+
+	if (!mac_ctx->mlme_cfg) {
+		pe_err("NULL mlme cfg");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	edca_params = &mac_ctx->mlme_cfg->edca_params;
+	for (i = 0; i < 4; i++) {
+		uint8_t data[CFG_EDCA_DATA_LEN];
+
+		status = wlan_mlme_get_edca_params(edca_params,
+						   (uint8_t *)&data[0],
+						   (uint8_t)wme_l[i]);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pe_err("Get failed for ac:[%d]", i);
+			return QDF_STATUS_E_FAILURE;
+		}
+		for (idx = 0; idx < CFG_EDCA_DATA_LEN; idx++)
+			params[i][idx] = (uint32_t) data[idx];
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sch_edca_profile_update() - This function updates the local and broadcast
+ * EDCA params in the gLimEdcaParams structure. It also updates the
+ * edcaParamSetCount.
+ *
+ * @pMac - global mac context
+ *
+ * Return  none
+ */
+void sch_edca_profile_update(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+	if (LIM_IS_AP_ROLE(psessionEntry) ||
+	    LIM_IS_IBSS_ROLE(psessionEntry)) {
+		sch_qos_update_local(pMac, psessionEntry);
+		sch_qos_update_broadcast(pMac, psessionEntry);
+	}
+}
+
+/* -------------------------------------------------------------------- */
diff --git a/core/mac/src/pe/sch/sch_sys_params.h b/core/mac/src/pe/sch/sch_sys_params.h
new file mode 100644
index 0000000..e55fb03
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_sys_params.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011-2012, 2014, 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.
+ */
+
+/*
+ *
+ * This file sch_sys_params.h contains scheduler parameter definitions
+ *
+ * Author:      Sandesh Goel
+ * Date:        02/25/02
+ * History:-
+ * Date            Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __SCH_SYS_PARAMS_H__
+#define __SCH_SYS_PARAMS_H__
+
+#endif
diff --git a/core/mac/src/sys/common/inc/wlan_qct_sys.h b/core/mac/src/sys/common/inc/wlan_qct_sys.h
new file mode 100644
index 0000000..ae6378e
--- /dev/null
+++ b/core/mac/src/sys/common/inc/wlan_qct_sys.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#if !defined(WLAN_QCT_SYS_H__)
+#define WLAN_QCT_SYS_H__
+
+/**===========================================================================
+
+   \file  wlan_qct_sys.h
+
+   \brief System module API
+
+   ==========================================================================*/
+
+/* $HEADER$ */
+
+/*---------------------------------------------------------------------------
+   Include files
+   -------------------------------------------------------------------------*/
+#include <qdf_types.h>
+#include <qdf_status.h>
+#include <scheduler_api.h>
+
+/*---------------------------------------------------------------------------
+   Preprocessor definitions and constants
+   -------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+   Type declarations
+   -------------------------------------------------------------------------*/
+
+/**
+ * sys_rsp_cb() - SYS async resonse callback
+ * @user_data: context data for callback
+ *
+ * This is a protype for the callback function that SYS makes to various
+ * modules in the system.
+ *
+ * Return: None
+ */
+typedef void (*sys_rsp_cb)(void *user_data);
+
+/*---------------------------------------------------------------------------
+   Preprocessor definitions and constants
+   -------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+   Function declarations and documenation
+   -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+
+   \brief sys_build_message_header() - Build / initialize a SYS message header
+
+   This function will initialize the SYS message header with the message type
+   and any internal fields needed for a new SYS message.  This function sets
+   all but the message body, which is up to the caller to setup based on the
+   specific message being built.
+
+   \note There are internal / reserved items in a SYS message that must be
+   set correctly for the message to be recognized as a SYS message by
+   the SYS message handlers.  It is important for every SYS message to
+   be setup / built / initialized through this function.
+
+   \param sysMsgId - a valid message ID for a SYS message.  See the
+   SYS_MSG_ID enum for all the valid SYS message IDs.
+
+   \param pMsg - pointer to the message structure to be setup.
+
+   \return
+
+   \sa
+
+   --------------------------------------------------------------------------*/
+QDF_STATUS sys_build_message_header(SYS_MSG_ID sysMsgId,
+				    struct scheduler_msg *pMsg);
+/**
+ * umac_stop() - send schedule message to mc thread to stop umac (sme and mac)
+ * @p_cds_context: cds context
+ *
+ * Return: status of operation
+ */
+QDF_STATUS umac_stop(void);
+
+QDF_STATUS sys_mc_process_handler(struct scheduler_msg *msg);
+
+#endif /* WLAN_QCT_SYS_H__ */
diff --git a/core/mac/src/sys/common/src/wlan_qct_sys.c b/core/mac/src/sys/common/src/wlan_qct_sys.c
new file mode 100644
index 0000000..d9a16e0
--- /dev/null
+++ b/core/mac/src/sys/common/src/wlan_qct_sys.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#include <wlan_qct_sys.h>
+#include <cds_api.h>
+#include <sir_types.h>
+#include <sir_params.h>          /* needed for tSirMbMsg */
+#include <sir_api.h>             /* needed for SIR_... message types */
+#include <wni_api.h>             /* needed for WNI_... message types */
+#include "ani_global.h"
+#include "wma_types.h"
+#include "sme_api.h"
+#include "mac_init_api.h"
+#include "qdf_trace.h"
+
+/*
+ * Cookie for SYS messages.  Note that anyone posting a SYS Message
+ * has to write the COOKIE in the reserved field of the message.  The
+ * SYS Module relies on this COOKIE
+ */
+#define SYS_MSG_COOKIE      0xFACE
+
+/* SYS stop timeout 30 seconds */
+#define SYS_STOP_TIMEOUT (30000)
+static qdf_event_t g_stop_evt;
+
+/**
+ * sys_build_message_header() - to build the sys message header
+ * @umac_stop_msgId: message id
+ * @pMsg: pointer to message context
+ *
+ * This API is used to build the sys message header.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sys_build_message_header(SYS_MSG_ID umac_stop_msg_id,
+				    struct scheduler_msg *msg)
+{
+	msg->type = umac_stop_msg_id;
+	msg->reserved = SYS_MSG_COOKIE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * umac_stop_complete_cb() - a callback when system stop completes
+ * @user_data: pointer to user provided data context
+ *
+ * this callback is used once system stop is completed.
+ *
+ * Return: none
+ */
+#ifdef QDF_ENABLE_TRACING
+static void umac_stop_complete_cb(void *user_data)
+{
+	qdf_event_t *stop_evt = (qdf_event_t *) user_data;
+	QDF_STATUS qdf_status = qdf_event_set(stop_evt);
+
+	QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+
+}
+#else
+static void umac_stop_complete_cb(void *user_data)
+{
+	return;
+}
+#endif
+
+/**
+ * umac_stop() - To post stop message to system module
+ *
+ * This API is used post a stop message to system module
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS umac_stop(void)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg umac_stop_msg;
+
+	/* Initialize the stop event */
+	qdf_status = qdf_event_create(&g_stop_evt);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		return qdf_status;
+
+	/* post a message to SYS module in MC to stop SME and MAC */
+	sys_build_message_header(SYS_MSG_ID_UMAC_STOP, &umac_stop_msg);
+
+	/* Save the user callback and user data */
+	umac_stop_msg.callback = umac_stop_complete_cb;
+	umac_stop_msg.bodyptr = (void *)&g_stop_evt;
+
+	/* post the message.. */
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_SYS,
+					    QDF_MODULE_ID_SYS,
+					    QDF_MODULE_ID_SYS, &umac_stop_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		qdf_status = QDF_STATUS_E_BADMSG;
+
+	qdf_status = qdf_wait_single_event(&g_stop_evt, SYS_STOP_TIMEOUT);
+	QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+
+	qdf_status = qdf_event_destroy(&g_stop_evt);
+	QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+
+	return qdf_status;
+}
+
+/**
+ * sys_mc_process_msg() - to process system mc thread messages
+ * @p_cds_context: pointer to cds context
+ * @pMsg: message pointer
+ *
+ * This API is used to process the message
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sys_mc_process_msg(struct scheduler_msg *pMsg)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	data_stall_detect_cb data_stall_detect_callback;
+	void *hHal;
+
+	if (NULL == pMsg) {
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+			  "%s: NULL pointer to struct scheduler_msg", __func__);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/*
+	 * All 'new' SYS messages are identified by a cookie in the reserved
+	 * field of the message as well as the message type.  This prevents
+	 * the possibility of overlap in the message types defined for new
+	 * SYS messages with the 'legacy' message types.  The legacy messages
+	 * will not have this cookie in the reserved field
+	 */
+	if (SYS_MSG_COOKIE == pMsg->reserved) {
+		/* Process all the new SYS messages.. */
+		switch (pMsg->type) {
+		case SYS_MSG_ID_UMAC_STOP:
+			QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+				"Processing SYS MC STOP");
+			hHal = cds_get_context(QDF_MODULE_ID_PE);
+			if (NULL == hHal) {
+				QDF_TRACE(QDF_MODULE_ID_SYS,
+					QDF_TRACE_LEVEL_ERROR,
+					"%s: Invalid hHal", __func__);
+				break;
+			}
+			qdf_status = sme_stop(hHal);
+			QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+			qdf_status = mac_stop(hHal);
+			QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+			((sys_rsp_cb) pMsg->callback)(pMsg->bodyptr);
+			qdf_status = QDF_STATUS_SUCCESS;
+			break;
+
+		case SYS_MSG_ID_DATA_STALL_MSG:
+			data_stall_detect_callback = pMsg->callback;
+			if (NULL != data_stall_detect_callback)
+				data_stall_detect_callback(pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+			break;
+		default:
+			QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+				"Unknown message type msgType= %d [0x%08x]",
+				pMsg->type, pMsg->type);
+			break;
+
+		}
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SYS,
+				QDF_TRACE_LEVEL_ERROR,
+				"Rx SYS unknown MC msgtype= %d [0x%08X]",
+				pMsg->type, pMsg->type);
+		QDF_ASSERT(0);
+		qdf_status = QDF_STATUS_E_BADMSG;
+
+		if (pMsg->bodyptr)
+			qdf_mem_free(pMsg->bodyptr);
+	}
+	return qdf_status;
+}
+
+QDF_STATUS sys_mc_process_handler(struct scheduler_msg *msg)
+{
+	return sys_mc_process_msg(msg);
+}
+
+/**
+ * sys_process_mmh_msg() - this api to process mmh message
+ * @pMac: pointer to mac context
+ * @pMsg: pointer to message
+ *
+ * This API is used to process mmh message
+ *
+ * Return: none
+ */
+void sys_process_mmh_msg(tpAniSirGlobal pMac, struct scheduler_msg *pMsg)
+{
+	QDF_MODULE_ID targetMQ = QDF_MODULE_ID_SYS;
+
+	/*
+	 * The body of this pMsg is a tSirMbMsg
+	 * Contrary to previous generation, we cannot free it here!
+	 * It is up to the callee to free it
+	 */
+	if (NULL == pMsg) {
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+				"NULL Message Pointer");
+		QDF_ASSERT(0);
+		return;
+	}
+
+	switch (pMsg->type) {
+	/*
+	 * Following messages are routed to SYS
+	 */
+	case WNI_CFG_DNLD_REQ:
+	case WNI_CFG_DNLD_CNF:
+		/* Forward this message to the SYS module */
+		targetMQ = QDF_MODULE_ID_SYS;
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+			"Handling for the Message ID %d is removed in SYS",
+			pMsg->type);
+		QDF_ASSERT(0);
+		break;
+
+		/*
+		 * Following messages are routed to HAL
+		 */
+	case WNI_CFG_DNLD_RSP:
+		/* Forward this message to the HAL module */
+		targetMQ = QDF_MODULE_ID_WMA;
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+			"Handling for the Message ID %d is removed as no HAL",
+			pMsg->type);
+
+		QDF_ASSERT(0);
+		break;
+
+	case WNI_CFG_GET_REQ:
+	case eWNI_SME_SYS_READY_IND:
+		/* Forward this message to the PE module */
+		targetMQ = QDF_MODULE_ID_PE;
+		break;
+
+	case WNI_CFG_GET_RSP:
+	case WNI_CFG_SET_CNF:
+		/* Forward this message to the SME module */
+		targetMQ = QDF_MODULE_ID_SME;
+		break;
+
+	default:
+		if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
+				&& (pMsg->type <= eWNI_SME_MSG_TYPES_END)) {
+			targetMQ = QDF_MODULE_ID_SME;
+			break;
+		}
+
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+			"Message of ID %d is not yet handled by SYS",
+			pMsg->type);
+		QDF_ASSERT(0);
+	}
+
+	/*
+	 * Post now the message to the appropriate module for handling
+	 */
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SYS,
+							 QDF_MODULE_ID_SYS,
+							 targetMQ,
+							 pMsg)) {
+		/*
+		 * Caller doesn't allocate memory for the pMsg.
+		 * It allocate memory for bodyptr free the mem and return
+		 */
+		if (pMsg->bodyptr)
+			qdf_mem_free(pMsg->bodyptr);
+	}
+
+}
+
diff --git a/core/mac/src/sys/legacy/src/platform/inc/sys_wrapper.h b/core/mac/src/sys/legacy/src/platform/inc/sys_wrapper.h
new file mode 100644
index 0000000..34c444a
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/platform/inc/sys_wrapper.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ * @file VossWrapper.h
+ *
+ * @brief This header file contains the various structure definitions and
+ * function prototypes for the RTOS abstraction layer, implemented for VOSS
+ */
+
+#ifndef __VOSS_WRAPPER_H
+#define __VOSS_WRAPPER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*---------------------------------------------------------------------------
+ * Include Files
+ * ------------------------------------------------------------------------*/
+
+#include "sir_types.h"
+#include "sir_params.h"
+#include "sys_def.h"
+#include "qdf_mc_timer.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "qdf_mem.h"
+
+/* Interlocked Compare Exchange related definitions */
+
+/* Define basic constants for the ThreadX kernel.  */
+
+#define TX_NO_WAIT          0
+#define TX_WAIT_FOREVER     0xFFFFFFFFUL
+#define TX_AUTO_ACTIVATE    1
+#define TX_NO_ACTIVATE      0
+
+/* API return values.  */
+#define TX_SUCCESS          0x00
+#define TX_QUEUE_FULL    0x01
+/* ... */
+#define TX_NO_INSTANCE      0x0D
+/* ... */
+#define TX_TIMER_ERROR      0x15
+#define TX_TICK_ERROR       0x16
+/* ... */
+
+#ifndef true
+#define true                1
+#endif
+
+#ifndef false
+#define false               0
+#endif
+
+/* Following macro specifies the number of milliseconds which constitute 1 ThreadX timer tick. Used
+   for mimicking the ThreadX timer behaviour on VOSS. */
+/* Use the same MACRO used by firmware modules to calculate TICKs from mSec */
+/* Mismatch would cause worng timer value to be programmed */
+#define TX_MSECS_IN_1_TICK  SYS_TICK_DUR_MS
+
+/* Signature with which the TX_TIMER struct is initialized, when the timer is created */
+#define TX_AIRGO_TMR_SIGNATURE   0xDEADBEEF
+
+#ifdef TIMER_MANAGER
+#define  tx_timer_create(a, b, c, d, e, f, g, h)    tx_timer_create_intern_debug((void *)a, b, c, d, e, f, g, h, __FILE__, __LINE__)
+#else
+#define  tx_timer_create(a, b, c, d, e, f, g, h)    tx_timer_create_intern((void *)a, b, c, d, e, f, g, h)
+#endif
+
+/*--------------------------------------------------------------------*/
+/* Timer structure                                                    */
+/* This structure is used to implement ThreadX timer facility.  Just  */
+/* like ThreadX, timer expiration handler executes at the highest     */
+/* possible priority level, i.e. DISPATCH_LEVEL.                      */
+/*--------------------------------------------------------------------*/
+typedef struct TX_TIMER_STRUCT {
+#ifdef WLAN_DEBUG
+#define TIMER_MAX_NAME_LEN 50
+	char timerName[TIMER_MAX_NAME_LEN];
+#endif
+	uint8_t sessionId;
+	uint32_t expireInput;
+	uint64_t tmrSignature;
+	void (*pExpireFunc)(void *, uint32_t);
+	uint64_t initScheduleTimeInMsecs;
+	uint64_t rescheduleTimeInMsecs;
+	qdf_mc_timer_t qdf_timer;
+
+	/* Pointer to the MAC global structure, which stores the context for the NIC, */
+	/* for which this timer is supposed to operate. */
+	void *pMac;
+
+} TX_TIMER;
+
+#define TX_TIMER_VALID(timer) (timer.pMac != 0)
+
+extern uint64_t tx_time_get(void);
+extern uint32_t tx_timer_activate(TX_TIMER *);
+extern uint32_t tx_timer_change(TX_TIMER *, uint64_t, uint64_t);
+extern uint32_t tx_timer_change_context(TX_TIMER *, uint32_t);
+#ifdef TIMER_MANAGER
+extern uint32_t tx_timer_create_intern_debug(void *, TX_TIMER *,
+					     char *, void (*)(void *,
+							      uint32_t),
+					     uint32_t, uint64_t,
+					     uint64_t, uint64_t,
+					     char *fileName,
+					     uint32_t lineNum);
+#else
+extern uint32_t tx_timer_create_intern(void *, TX_TIMER *, char *,
+				       void (*)(void *, uint32_t),
+				       uint32_t, uint64_t, uint64_t,
+				       uint64_t);
+#endif
+extern uint32_t tx_timer_deactivate(TX_TIMER *);
+extern uint32_t tx_timer_delete(TX_TIMER *);
+extern bool tx_timer_running(TX_TIMER *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/core/mac/src/sys/legacy/src/platform/src/sys_wrapper.c b/core/mac/src/sys/legacy/src/platform/src/sys_wrapper.c
new file mode 100644
index 0000000..bbaf725
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/platform/src/sys_wrapper.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*===========================================================================
+   @file VossWrapper.c
+
+   @brief This source file contains the various function definitions for the
+   RTOS abstraction layer, implemented for VOSS
+   ===========================================================================*/
+
+/*===========================================================================
+
+			EDIT HISTORY FOR FILE
+
+   This section contains comments describing changes made to the module.
+   Notice that changes are listed in reverse chronological order.
+
+   $Header:$ $DateTime: $ $Author: $
+
+   when        who    what, where, why
+   --------    ---    --------------------------------------------------------
+   03/31/09    sho    Remove the use of qdf_timerIsActive flag as it is not
+			thread-safe
+   02/17/08    sho    Fix the timer callback function to work when it is called
+			after the timer has stopped due to a race condition.
+   02/10/08    sho    Refactor the TX timer to use VOS timer directly instead
+			of using VOS utility timer
+   12/15/08    sho    Resolved errors and warnings from the AMSS compiler when
+			this is ported from WM
+   11/20/08    sho    Renamed this to VosWrapper.c; remove all dependencies on
+			WM platform and allow this to work on all VOSS enabled
+			platform
+   06/24/08    tbh    Modified the file to remove the dependecy on HDD files as
+			part of Gen6 bring up process.
+   10/29/02 Neelay Das Created file.
+
+   ===========================================================================*/
+
+/*---------------------------------------------------------------------------
+ * Include Files
+ * ------------------------------------------------------------------------*/
+#include "sys_wrapper.h"
+
+#ifdef WLAN_DEBUG
+#define TIMER_NAME (timer_ptr->timerName)
+#else
+#define TIMER_NAME "N/A"
+#endif
+
+/**---------------------------------------------------------------------
+ * tx_time_get()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return current system time in units of miliseconds
+ *
+ */
+uint64_t tx_time_get(void)
+{
+	return qdf_mc_timer_get_system_ticks();
+
+} /* * tx_time_get() */
+
+/**---------------------------------------------------------------------
+ * tx_timer_activate()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return TX_SUCCESS.
+ *
+ */
+uint32_t tx_timer_activate(TX_TIMER *timer_ptr)
+{
+	QDF_STATUS status;
+
+	/* Uncomment the asserts, if the intention is to debug the occurrence of the */
+	/* following anomalous cnditions. */
+
+	/* Assert that the timer structure pointer passed, is not NULL */
+	/* dbgAssert(NULL != timer_ptr); */
+
+	/* If the NIC is halting just spoof a successful timer activation, so that all */
+	/* the timers can be cleaned up. */
+
+	if (NULL == timer_ptr)
+		return TX_TIMER_ERROR;
+
+	/* Put a check for the free builds */
+	if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
+		QDF_ASSERT(timer_ptr->tmrSignature == 0);
+
+		return TX_TIMER_ERROR;
+
+	}
+	/* Check for an uninitialized timer */
+	QDF_ASSERT(0 != strlen(TIMER_NAME));
+
+	status = qdf_mc_timer_start(&timer_ptr->qdf_timer,
+				    timer_ptr->initScheduleTimeInMsecs);
+
+	if (QDF_STATUS_SUCCESS == status) {
+		return TX_SUCCESS;
+	} else if (QDF_STATUS_E_ALREADY == status) {
+		/* starting timer fails because timer is already started; this is okay */
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_DEBUG,
+			  "Timer %s is already running\n", TIMER_NAME);
+		return TX_SUCCESS;
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+			  "Timer %s fails to activate\n", TIMER_NAME);
+		return TX_TIMER_ERROR;
+	}
+} /*** tx_timer_activate() ***/
+
+/**---------------------------------------------------------------------
+ * tx_timer_change()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return TX_SUCCESS.
+ *
+ */
+uint32_t tx_timer_change(TX_TIMER *timer_ptr,
+			 uint64_t initScheduleTimeInTicks,
+			 uint64_t rescheduleTimeInTicks)
+{
+	/* Put a check for the free builds */
+	if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
+		QDF_ASSERT(timer_ptr->tmrSignature == 0);
+		return TX_TIMER_ERROR;
+	}
+	/* changes cannot be applied until timer stops running */
+	if (QDF_TIMER_STATE_STOPPED ==
+	    qdf_mc_timer_get_current_state(&timer_ptr->qdf_timer)) {
+		timer_ptr->initScheduleTimeInMsecs =
+			TX_MSECS_IN_1_TICK * initScheduleTimeInTicks;
+		timer_ptr->rescheduleTimeInMsecs =
+			TX_MSECS_IN_1_TICK * rescheduleTimeInTicks;
+		return TX_SUCCESS;
+	} else {
+		return TX_TIMER_ERROR;
+	}
+} /*** tx_timer_change() ***/
+
+/**---------------------------------------------------------------------
+ * tx_timer_change_context()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return TX_SUCCESS.
+ *
+ */
+uint32_t tx_timer_change_context(TX_TIMER *timer_ptr,
+				 uint32_t expiration_input)
+{
+
+	/* Put a check for the free builds */
+	if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
+		QDF_ASSERT(timer_ptr->tmrSignature == 0);
+
+		return TX_TIMER_ERROR;
+	}
+	/* changes cannot be applied until timer stops running */
+	if (QDF_TIMER_STATE_STOPPED ==
+	    qdf_mc_timer_get_current_state(&timer_ptr->qdf_timer)) {
+		timer_ptr->expireInput = expiration_input;
+		return TX_SUCCESS;
+	} else {
+		return TX_TIMER_ERROR;
+	}
+} /*** tx_timer_change() ***/
+
+/**---------------------------------------------------------------------
+ * tx_main_timer_func()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return None.
+ *
+ */
+static void tx_main_timer_func(void *functionContext)
+{
+	TX_TIMER *timer_ptr = (TX_TIMER *) functionContext;
+
+	if (NULL == timer_ptr) {
+		QDF_ASSERT(0);
+		return;
+	}
+
+	if (NULL == timer_ptr->pExpireFunc) {
+		QDF_ASSERT(0);
+		return;
+	}
+
+	/* Now call the actual timer function, taking the function pointer, */
+	/* from the timer structure. */
+	(*timer_ptr->pExpireFunc)(timer_ptr->pMac, timer_ptr->expireInput);
+
+	/* check if this needs to be rescheduled */
+	if (0 != timer_ptr->rescheduleTimeInMsecs) {
+		QDF_STATUS status;
+
+		status = qdf_mc_timer_start(&timer_ptr->qdf_timer,
+					    timer_ptr->rescheduleTimeInMsecs);
+		timer_ptr->rescheduleTimeInMsecs = 0;
+
+		if (QDF_STATUS_SUCCESS != status) {
+			QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_WARN,
+				  "Unable to reschedule timer %s; status=%d",
+				  TIMER_NAME, status);
+		}
+	}
+} /*** tx_timer_change() ***/
+
+#ifdef TIMER_MANAGER
+uint32_t tx_timer_create_intern_debug(void *pMacGlobal,
+				      TX_TIMER *timer_ptr, char *name_ptr,
+				      void (*expiration_function)(void *,
+								  uint32_t),
+				      uint32_t expiration_input,
+				      uint64_t initScheduleTimeInTicks,
+				      uint64_t rescheduleTimeInTicks,
+				      uint64_t auto_activate, char *fileName,
+				      uint32_t lineNum)
+{
+	QDF_STATUS status;
+
+	if (NULL == expiration_function) {
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+			  "NULL timer expiration");
+		QDF_ASSERT(0);
+		return TX_TIMER_ERROR;
+	}
+
+	if (NULL == name_ptr) {
+
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+			  "NULL name pointer for timer");
+		QDF_ASSERT(0);
+		return TX_TIMER_ERROR;
+	}
+	if (!initScheduleTimeInTicks)
+		return TX_TICK_ERROR;
+
+	if (!timer_ptr)
+		return TX_TIMER_ERROR;
+
+	/* Initialize timer structure */
+	timer_ptr->pExpireFunc = expiration_function;
+	timer_ptr->expireInput = expiration_input;
+	timer_ptr->initScheduleTimeInMsecs =
+		TX_MSECS_IN_1_TICK * initScheduleTimeInTicks;
+	timer_ptr->rescheduleTimeInMsecs =
+		TX_MSECS_IN_1_TICK * rescheduleTimeInTicks;
+	timer_ptr->pMac = pMacGlobal;
+
+	/* Set the flag indicating that the timer was created */
+	timer_ptr->tmrSignature = TX_AIRGO_TMR_SIGNATURE;
+
+#ifdef WLAN_DEBUG
+	/* Store the timer name */
+	strlcpy(timer_ptr->timerName, name_ptr, sizeof(timer_ptr->timerName));
+#endif /* Store the timer name, for Debug build only */
+
+	status =
+		qdf_mc_timer_init_debug(&timer_ptr->qdf_timer, QDF_TIMER_TYPE_SW,
+					tx_main_timer_func, (void *) timer_ptr,
+					fileName, lineNum);
+	if (QDF_STATUS_SUCCESS != status) {
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+			  "Cannot create timer for %s\n", TIMER_NAME);
+		return TX_TIMER_ERROR;
+	}
+
+	if (0 != rescheduleTimeInTicks) {
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_DEBUG,
+			  "Creating periodic timer for %s\n", TIMER_NAME);
+	}
+	/* Activate this timer if required */
+	if (auto_activate) {
+		tx_timer_activate(timer_ptr);
+	}
+
+	return TX_SUCCESS;
+
+} /* ** tx_timer_create() *** / */
+#else
+uint32_t tx_timer_create_intern(void *pMacGlobal, TX_TIMER *timer_ptr,
+				char *name_ptr,
+				void (*expiration_function)(void *,
+							    uint32_t),
+				uint32_t expiration_input,
+				uint64_t initScheduleTimeInTicks,
+				uint64_t rescheduleTimeInTicks,
+				uint64_t auto_activate)
+{
+	QDF_STATUS status;
+
+	if ((NULL == name_ptr) || (NULL == expiration_function))
+		return TX_TIMER_ERROR;
+
+	if (!initScheduleTimeInTicks)
+		return TX_TICK_ERROR;
+
+	if (!timer_ptr)
+		return TX_TIMER_ERROR;
+
+	/* Initialize timer structure */
+	timer_ptr->pExpireFunc = expiration_function;
+	timer_ptr->expireInput = expiration_input;
+	timer_ptr->initScheduleTimeInMsecs =
+		TX_MSECS_IN_1_TICK * initScheduleTimeInTicks;
+	timer_ptr->rescheduleTimeInMsecs =
+		TX_MSECS_IN_1_TICK * rescheduleTimeInTicks;
+	timer_ptr->pMac = pMacGlobal;
+
+	/* Set the flag indicating that the timer was created */
+	timer_ptr->tmrSignature = TX_AIRGO_TMR_SIGNATURE;
+
+#ifdef WLAN_DEBUG
+	/* Store the timer name */
+	strlcpy(timer_ptr->timerName, name_ptr, sizeof(timer_ptr->timerName));
+#endif /* Store the timer name, for Debug build only */
+
+	status = qdf_mc_timer_init(&timer_ptr->qdf_timer, QDF_TIMER_TYPE_SW,
+				   tx_main_timer_func, (void *) timer_ptr);
+	if (QDF_STATUS_SUCCESS != status) {
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR,
+			  "Cannot create timer for %s\n", TIMER_NAME);
+		return TX_TIMER_ERROR;
+	}
+
+	if (0 != rescheduleTimeInTicks) {
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_INFO,
+			  "Creating periodic timer for %s\n", TIMER_NAME);
+	}
+	/* Activate this timer if required */
+	if (auto_activate) {
+		tx_timer_activate(timer_ptr);
+	}
+
+	return TX_SUCCESS;
+
+} /* ** tx_timer_create() *** / */
+#endif
+
+/**---------------------------------------------------------------------
+ * tx_timer_deactivate()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return TX_SUCCESS.
+ *
+ */
+uint32_t tx_timer_deactivate(TX_TIMER *timer_ptr)
+{
+	QDF_STATUS vStatus;
+
+	/* Put a check for the free builds */
+	if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
+		return TX_TIMER_ERROR;
+	}
+	/* if the timer is not running then we do not need to do anything here */
+	vStatus = qdf_mc_timer_stop(&timer_ptr->qdf_timer);
+	if (QDF_STATUS_SUCCESS != vStatus) {
+		QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "Unable to stop timer %s; status =%d\n",
+			  TIMER_NAME, vStatus);
+	}
+
+	return TX_SUCCESS;
+
+} /*** tx_timer_deactivate() ***/
+
+uint32_t tx_timer_delete(TX_TIMER *timer_ptr)
+{
+	/* Put a check for the free builds */
+	if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
+		return TX_TIMER_ERROR;
+	}
+
+	qdf_mc_timer_destroy(&timer_ptr->qdf_timer);
+	return TX_SUCCESS;
+} /*** tx_timer_delete() ***/
+
+/**---------------------------------------------------------------------
+ * tx_timer_running()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return TX_SUCCESS.
+ *
+ */
+bool tx_timer_running(TX_TIMER *timer_ptr)
+{
+	/* Put a check for the free builds */
+	if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature)
+		return false;
+
+	if (QDF_TIMER_STATE_RUNNING ==
+	    qdf_mc_timer_get_current_state(&timer_ptr->qdf_timer)) {
+		return true;
+	}
+	return false;
+
+} /*** tx_timer_running() ***/
diff --git a/core/mac/src/sys/legacy/src/system/inc/sys_def.h b/core/mac/src/sys/legacy/src/system/inc/sys_def.h
new file mode 100644
index 0000000..2de3ae8
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/system/inc/sys_def.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2011-2014 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.
+ */
+
+/*
+ *
+ * This file sys_def.h contains the common definitions used to bring up
+ * Sirius system.
+ * Author:      V. K. Kandarpa
+ * Date:        04/13/2002
+ * History:-
+ * Date         Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#ifndef __SYSDEF_H
+#define __SYSDEF_H
+
+/* / Sirius system level definitions */
+/* NOTE: Do not program system timer tick duration to less than 1msec */
+
+/* / System timer tick duration in nanoseconds */
+#define SYS_TICK_DUR_NS     10000000    /* 10ms */
+#define SYS_TICK_TO_MICRO_SECOND   10000
+
+/* / System timer tick duration in milliseconds */
+#define SYS_TICK_DUR_MS     (SYS_TICK_DUR_NS/1000000)
+
+/* / Clocks in a millisecond */
+#define SYS_CLOCKS_PER_MS   120000      /* 120 MHz */
+
+/* / System timer tick duration in clocks */
+#define SYS_TICK_DUR_CLK    (SYS_TICK_DUR_MS * SYS_CLOCKS_PER_MS)
+
+/* / Number of timer ticks in a second */
+#define SYS_TICKS_PER_SECOND (1000/SYS_TICK_DUR_MS)
+
+/* / Macro to convert MS to Ticks */
+#define SYS_MS_TO_TICKS(x)   ((x) / SYS_TICK_DUR_MS)
+
+/* / Macro to convert Seconds to Ticks */
+#define SYS_SEC_TO_TICKS(x)  ((x) * SYS_TICKS_PER_SECOND)
+
+/* / Macro to convert Minutes to Ticks */
+#define SYS_MIN_TO_TICKS(x)  (((x) * 60) * SYS_TICKS_PER_SECOND)
+
+/* / MNT task processing interval in seconds */
+#define SYS_MNT_INTERVAL     60
+
+/* / MS to Time Units */
+#define SYS_MS_TO_TU(x)      ((x * 1000) >> 10)
+
+/* / TU to MS */
+#define SYS_TU_TO_MS(x)      ((x << 10) / 1000)
+
+/* ---------  End of Windows & RTAI ----------- */
+
+/* / Message queue definitions */
+
+/* / gHalMsgQ */
+#define SYS_HAL_Q_SIZE     200  /* Holds up to 25 messages */
+
+/* / gMMHhiPriorityMsgQ */
+#define SYS_MMH_HI_PRI_Q_SIZE      200  /* Holds up to 25 messages */
+
+/* / gMMHprotocolMsgQ */
+#define SYS_MMH_PROT_Q_SIZE     400     /* Holds up to 50 messages */
+
+/* / gMMHdebugMsgQ */
+#define SYS_MMH_DEBUG_Q_SIZE    800     /* Holds up to 100 messages */
+
+/* / gMAINTmsgQ */
+#define SYS_MNT_Q_SIZE          200     /* Holds up to 25 messages */
+
+/* / LIM Message Queue */
+#define SYS_LIM_Q_SIZE          400     /* Holds up to 50 messages */
+
+/* / Scheduler Message Queue */
+#define SYS_SCH_Q_SIZE          800     /* Holds up to 25 messages */
+
+/* / PMM Message Queue */
+#define SYS_PMM_Q_SIZE          800     /* Holds up to 100 messages */
+
+/* / TX Message Queue */
+#define SYS_TX_Q_SIZE           2048    /* Holds up to 400 messages */
+
+/* / RX Message Queue */
+#define SYS_RX_Q_SIZE           2048    /* Holds up to 400 messages */
+
+/* / PTT  Message Queue */
+#define SYS_NIM_PTT_Q_SIZE   200        /* Holds up to 25 messages */
+
+/* / Thread definitions */
+/* tHAL */
+
+#define SYS_HAL_THREAD_ENTRY_FUNCTION halEntry
+#define SYS_HAL_STACK_SIZE            8192
+#define SYS_HAL_THREAD_PRIORITY       2
+
+/* tDPH */
+
+#define SYS_DPH_THREAD_ENTRY_FUNCTION dphEntry
+#define SYS_DPH_STACK_SIZE            8192
+#define SYS_DPH_THREAD_PRIORITY       15
+
+/* tBBT */
+
+#define SYS_BBT_THREAD_ENTRY_FUNCTION bbtEntry
+#define SYS_BBT_STACK_SIZE            8192
+#define SYS_BBT_THREAD_PRIORITY       16
+
+/* tSCH */
+
+#define SYS_SCH_STACK_SIZE            8192
+#define SYS_SCH_THREAD_PRIORITY       17
+
+/* tPMM */
+
+#define SYS_PMM_STACK_SIZE            8192
+#define SYS_PMM_THREAD_PRIORITY       17
+
+/* tLIM */
+
+#define SYS_LIM_THREAD_ENTRY_FUNCTION limEntry
+#define SYS_LIM_STACK_SIZE            8192
+#define SYS_LIM_THREAD_PRIORITY       18
+
+/* tMAINT */
+
+#define SYS_MNT_THREAD_ENTRY_FUNCTION mntEntry
+#define SYS_MNT_STACK_SIZE            8192
+#define SYS_MNT_THREAD_PRIORITY       25
+
+/* tMMH */
+
+#define SYS_MMH_THREAD_ENTRY_FUNCTION mmhEntry
+#define SYS_MMH_STACK_SIZE            8192
+#define SYS_MMH_THREAD_PRIORITY        10
+
+/* tNIM_MNT_PKT_GEN */
+
+#define SYS_NIM_PTT_THREAD_STACK_SIZE 8192
+#define SYS_NIM_PTT_THREAD_PRIORITY   28
+
+#endif /* __SYSDEF_H */
diff --git a/core/mac/src/sys/legacy/src/system/inc/sys_entry_func.h b/core/mac/src/sys/legacy/src/system/inc/sys_entry_func.h
new file mode 100644
index 0000000..36613b3
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/system/inc/sys_entry_func.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011-2012, 2014, 2017-2018 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.
+ */
+
+/*
+ *
+ * This file sys_entry_func.h contains module entry functions definitions
+ * Author:      V. K. Kandarpa
+ * Date:        04/13/2002
+ * History:-
+ * Date         Modified by    Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __SYS_ENTRY_FUNC_H
+#define __SYS_ENTRY_FUNC_H
+
+#include "ani_global.h"
+
+extern QDF_STATUS sys_init_globals(tpAniSirGlobal);
+extern void sysBbtEntry(uint32_t dummy);
+extern void sysSchEntry(uint32_t dummy);
+extern void sysPmmEntry(uint32_t dummy);
+extern void sysDphEntry(uint32_t dummy);
+extern void sysLimEntry(uint32_t dummy);
+extern void sysMmhEntry(uint32_t dummy);
+extern void sysMntEntry(uint32_t dummy);
+extern void sysHalEntry(uint32_t dummy);
+extern void sysNimPttEntry(uint32_t dummy);
+
+#endif /* __SYS_ENTRY_FUNC_H */
diff --git a/core/mac/src/sys/legacy/src/system/inc/sys_startup.h b/core/mac/src/sys/legacy/src/system/inc/sys_startup.h
new file mode 100644
index 0000000..e587b38
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/system/inc/sys_startup.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011-2014, 2017-2018 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.
+ */
+
+/*
+ *
+ * sys_startup.h: System startup header file.
+ * Author:  V. K. Kandarpa
+ * Date:    01/29/2002
+ *
+ * History:-
+ * Date     Modified by         Modification Information
+ * --------------------------------------------------------------------------
+ *
+ */
+
+#ifndef __SYSSTARTUP_H
+#define __SYSSTARTUP_H
+
+#include "sir_params.h"
+
+/* Defines */
+
+/* Function */
+
+/**
+ * sys_bbt_process_message_core() - to process BBT messages
+ * @mac_ctx: pointer to mac context
+ * @msg: message pointer
+ * @type: type of persona
+ * @subtype: subtype of persona
+ *
+ * This routine is to process some bbt messages
+ *
+ * Return: None
+ */
+QDF_STATUS sys_bbt_process_message_core(struct mac_context *mac_ctx,
+					struct scheduler_msg *msg,
+					uint32_t type, uint32_t subtype);
+
+#endif /* __SYSSTARTUP_H */
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
new file mode 100644
index 0000000..bddb10c
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/system/src/mac_init_api.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * mac_init_api.c - This file has all the mac level init functions
+ *                   for all the defined threads at system level.
+ * Author:    Dinesh Upadhyay
+ * Date:      04/23/2007
+ * History:-
+ * Date: 04/08/2008       Modified by: Santosh Mandiganal
+ * Modification Information: Code to allocate and free the  memory for DumpTable entry.
+ * --------------------------------------------------------------------------
+ *
+ */
+/* Standard include files */
+#include "cfg_api.h"             /* cfg_cleanup */
+#include "lim_api.h"             /* lim_cleanup */
+#include "sir_types.h"
+#include "sys_entry_func.h"
+#include "mac_init_api.h"
+#include "wlan_mlme_main.h"
+
+#ifdef TRACE_RECORD
+#include "mac_trace.h"
+#endif
+
+#ifdef WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY
+static struct mac_context *global_mac_context;
+
+static inline tpAniSirGlobal mac_allocate_context_buffer(void)
+{
+	global_mac_context = qdf_mem_malloc(sizeof(*global_mac_context));
+
+	return global_mac_context;
+}
+
+static inline void mac_free_context_buffer(void)
+{
+	qdf_mem_free(global_mac_context);
+	global_mac_context = NULL;
+}
+#else /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
+static struct mac_context global_mac_context;
+
+static inline tpAniSirGlobal mac_allocate_context_buffer(void)
+{
+	return &global_mac_context;
+}
+
+static inline void mac_free_context_buffer(void)
+{
+}
+#endif /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
+
+QDF_STATUS mac_start(mac_handle_t mac_handle,
+		     struct mac_start_params *params)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	if (!mac || !params) {
+		QDF_ASSERT(0);
+		status = QDF_STATUS_E_FAILURE;
+		return status;
+	}
+
+	mac->gDriverType = params->driver_type;
+
+	if (ANI_DRIVER_TYPE(mac) != QDF_DRIVER_TYPE_MFG)
+		status = pe_start(mac);
+
+	return status;
+}
+
+QDF_STATUS mac_stop(mac_handle_t mac_handle)
+{
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	pe_stop(mac);
+	cfg_cleanup(mac);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS mac_open(struct wlan_objmgr_psoc *psoc, mac_handle_t *mac_handle,
+		    hdd_handle_t hdd_handle, struct cds_config_info *cds_cfg)
+{
+	tpAniSirGlobal mac;
+	QDF_STATUS status;
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	QDF_BUG(mac_handle);
+	if (!mac_handle)
+		return QDF_STATUS_E_FAILURE;
+
+	mac = mac_allocate_context_buffer();
+	if (!mac)
+		return QDF_STATUS_E_NOMEM;
+
+	/*
+	 * Set various global fields of mac here
+	 * (Could be platform dependent as some variables in mac are platform
+	 * dependent)
+	 */
+	mac->hdd_handle = hdd_handle;
+
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_LEGACY_MAC_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("PSOC get ref failure");
+		goto free_mac_context;
+	}
+
+	mac->psoc = psoc;
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj) {
+		pe_err("Failed to get MLME Obj");
+		status = QDF_STATUS_E_FAILURE;
+		goto release_psoc_ref;
+	}
+	mac->mlme_cfg = &mlme_obj->cfg;
+
+	*mac_handle = MAC_HANDLE(mac);
+
+	/* For Non-FTM cases this value will be reset during mac_start */
+	if (cds_cfg->driver_type)
+		mac->gDriverType = QDF_DRIVER_TYPE_MFG;
+
+	status = cfg_init(mac);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("failed to init legacy CFG; status:%u", status);
+		goto release_psoc_ref;
+	}
+
+	sys_init_globals(mac);
+
+	/* FW: 0 to 2047 and Host: 2048 to 4095 */
+	mac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
+	mac->he_sgi_ltf_cfg_bit_mask = DEF_HE_AUTO_SGI_LTF;
+	mac->is_usr_cfg_amsdu_enabled = true;
+
+	status = pe_open(mac, cds_cfg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("failed to open PE; status:%u", status);
+		goto deinit_cfg;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+deinit_cfg:
+	cfg_de_init(mac);
+
+release_psoc_ref:
+	wlan_objmgr_psoc_release_ref(psoc, WLAN_LEGACY_MAC_ID);
+
+free_mac_context:
+	mac_free_context_buffer();
+
+	return status;
+}
+
+QDF_STATUS mac_close(mac_handle_t mac_handle)
+{
+
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	if (!mac)
+		return QDF_STATUS_E_FAILURE;
+
+	pe_close(mac);
+
+	/* Call routine to free-up all CFG data structures */
+	cfg_de_init(mac);
+
+	if (mac->pdev) {
+		wlan_objmgr_pdev_release_ref(mac->pdev, WLAN_LEGACY_MAC_ID);
+		mac->pdev = NULL;
+	}
+	wlan_objmgr_psoc_release_ref(mac->psoc, WLAN_LEGACY_MAC_ID);
+	mac->mlme_cfg = NULL;
+	mac->psoc = NULL;
+	mac_free_context_buffer();
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c b/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c
new file mode 100644
index 0000000..6569b85
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * sys_entry_func.cc - This file has all the system level entry functions
+ *                   for all the defined threads at system level.
+ * Author:    V. K. Kandarpa
+ * Date:      01/16/2002
+ * History:-
+ * Date       Modified by            Modification Information
+ * --------------------------------------------------------------------------
+ *
+ */
+/* Standard include files */
+
+/* Application Specific include files */
+#include "sir_common.h"
+#include "ani_global.h"
+
+#include "lim_api.h"
+#include "sch_api.h"
+#include "utils_api.h"
+
+#include "sys_def.h"
+#include "sys_entry_func.h"
+#include "sys_startup.h"
+#include "lim_trace.h"
+#include "wma_types.h"
+#include "qdf_types.h"
+#include "cds_packet.h"
+
+#define MAX_DEAUTH_ALLOWED 5
+/* --------------------------------------------------------------------------- */
+/**
+ * sys_init_globals
+ *
+ * FUNCTION:
+ *    Initializes system level global parameters
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param tpAniSirGlobal Sirius software parameter struct pointer
+ * @return None
+ */
+
+QDF_STATUS sys_init_globals(tpAniSirGlobal pMac)
+{
+
+	qdf_mem_set((uint8_t *) &pMac->sys, sizeof(pMac->sys), 0);
+
+	pMac->sys.gSysEnableLinkMonitorMode = 0;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sys_bbt_process_message_core(struct mac_context *mac_ctx,
+					struct scheduler_msg *msg,
+					uint32_t type, uint32_t subtype)
+{
+	uint32_t framecount;
+	QDF_STATUS ret;
+	void *bd_ptr;
+	tMgmtFrmDropReason dropreason;
+	cds_pkt_t *vos_pkt = (cds_pkt_t *) msg->bodyptr;
+	QDF_STATUS qdf_status =
+		wma_ds_peek_rx_packet_info(vos_pkt, &bd_ptr, false);
+
+	mac_ctx->sys.gSysBbtReceived++;
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		goto fail;
+
+	mac_ctx->sys.gSysFrameCount[type][subtype]++;
+	framecount = mac_ctx->sys.gSysFrameCount[type][subtype];
+
+	if (type == SIR_MAC_MGMT_FRAME) {
+		tpSirMacMgmtHdr mac_hdr;
+
+		/*
+		 * Drop beacon frames in deferred state to avoid VOSS run out of
+		 * message wrappers.
+		 */
+		if ((subtype == SIR_MAC_MGMT_BEACON) &&
+			(!lim_is_system_in_scan_state(mac_ctx)) &&
+			(GET_LIM_PROCESS_DEFD_MESGS(mac_ctx) != true)) {
+			pe_debug("dropping received beacon in deffered state");
+			goto fail;
+		}
+
+		dropreason = lim_is_pkt_candidate_for_drop(mac_ctx, bd_ptr,
+				subtype);
+		if (eMGMT_DROP_NO_DROP != dropreason) {
+			pe_debug("Mgmt Frame %d being dropped, reason: %d\n",
+				subtype, dropreason);
+				MTRACE(mac_trace(mac_ctx,
+					TRACE_CODE_RX_MGMT_DROP, NO_SESSION,
+					dropreason));
+			goto fail;
+		}
+
+		mac_hdr = WMA_GET_RX_MAC_HEADER(bd_ptr);
+		if (subtype == SIR_MAC_MGMT_ASSOC_REQ) {
+			pe_debug("ASSOC REQ frame allowed: da: " MAC_ADDRESS_STR ", sa: " MAC_ADDRESS_STR ", bssid: " MAC_ADDRESS_STR ", Assoc Req count so far: %d",
+				 MAC_ADDR_ARRAY(mac_hdr->da),
+				 MAC_ADDR_ARRAY(mac_hdr->sa),
+				 MAC_ADDR_ARRAY(mac_hdr->bssId),
+				 mac_ctx->sys.gSysFrameCount[type][subtype]);
+		}
+		if (subtype == SIR_MAC_MGMT_DEAUTH) {
+			pe_debug("DEAUTH frame allowed: da: " MAC_ADDRESS_STR ", sa: " MAC_ADDRESS_STR ", bssid: " MAC_ADDRESS_STR ", DEAUTH count so far: %d",
+				 MAC_ADDR_ARRAY(mac_hdr->da),
+				 MAC_ADDR_ARRAY(mac_hdr->sa),
+				 MAC_ADDR_ARRAY(mac_hdr->bssId),
+				 mac_ctx->sys.gSysFrameCount[type][subtype]);
+		}
+		if (subtype == SIR_MAC_MGMT_DISASSOC) {
+			pe_debug("DISASSOC frame allowed: da: " MAC_ADDRESS_STR ", sa: " MAC_ADDRESS_STR ", bssid: " MAC_ADDRESS_STR ", DISASSOC count so far: %d",
+				 MAC_ADDR_ARRAY(mac_hdr->da),
+				 MAC_ADDR_ARRAY(mac_hdr->sa),
+				 MAC_ADDR_ARRAY(mac_hdr->bssId),
+				 mac_ctx->sys.gSysFrameCount[type][subtype]);
+		}
+
+		/* Post the message to PE Queue */
+		ret = lim_post_msg_api(mac_ctx, msg);
+		if (ret != QDF_STATUS_SUCCESS) {
+			pe_err("posting to LIM2 failed, ret %d\n", ret);
+			goto fail;
+		}
+		mac_ctx->sys.gSysBbtPostedToLim++;
+#ifdef FEATURE_WLAN_ESE
+	} else if (type == SIR_MAC_DATA_FRAME) {
+		pe_debug("IAPP Frame...");
+		/* Post the message to PE Queue */
+		ret = lim_post_msg_api(mac_ctx, msg);
+		if (ret != QDF_STATUS_SUCCESS) {
+			pe_err("posting to LIM2 failed, ret: %d", ret);
+			goto fail;
+		}
+		mac_ctx->sys.gSysBbtPostedToLim++;
+#endif
+	} else {
+		pe_debug("BBT received Invalid type: %d subtype: %d "
+			"LIM state %X", type, subtype,
+			lim_get_sme_state(mac_ctx));
+		goto fail;
+	}
+	return QDF_STATUS_SUCCESS;
+fail:
+	mac_ctx->sys.gSysBbtDropped++;
+	return QDF_STATUS_E_FAILURE;
+}
+
diff --git a/core/mac/src/sys/legacy/src/utils/inc/dot11fdefs.h b/core/mac/src/sys/legacy/src/utils/inc/dot11fdefs.h
new file mode 100644
index 0000000..2e38267
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/inc/dot11fdefs.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011-2012, 2014-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.
+ */
+
+#ifndef DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582
+#define DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582
+/**
+ * \file dot11fdefs.h
+ *
+ * \brief C defines customizing our framesc-generated code
+ *
+ *
+ *
+ *
+ * 'framesc' generates code written in terms of a number of macros
+ * intended for customization.
+ *
+ *
+ */
+
+#include "parser_api.h"
+
+/* This controls how the "dot11f" code copies memory */
+#define DOT11F_MEMCPY(ctx, dst, src, len) \
+	qdf_mem_copy((uint8_t *)(dst), (uint8_t *)(src), (len))
+
+/* This controls how the "dot11f" code compares memory */
+#define DOT11F_MEMCMP(ctx, lhs, rhs, len) \
+	(qdf_mem_cmp((uint8_t *)(lhs), (uint8_t *)(rhs), (len)))
+
+#if defined(DBG) && (DBG != 0)
+
+#                               /* define DOT11F_ENABLE_LOGGING */
+#                               /* define DOT11F_DUMP_FRAMES */
+#define DOT11F_LOG_GATE (4)
+#define FRAMES_SEV_FOR_FRAME(ctx, sig) \
+	(DOT11F_ASSOCREQUEST == (sig) ? 3 : 5)
+
+#if defined(DOT11F_ENABLE_LOGGING)
+
+#define DOT11F_HAVE_LOG_MACROS
+
+#define FRAMES_LOG0(ctx, sev, fmt) \
+	QDF_TRACE(QDF_MODULE_ID_PE, (sev), (fmt));
+
+#define FRAMES_LOG1(ctx, sev, fmt, p1) \
+	QDF_TRACE(QDF_MODULE_ID_PE, (sev), (fmt), (p1));
+
+#define FRAMES_LOG2(ctx, sev, fmt, p1, p2) \
+	QDF_TRACE(QDF_MODULE_ID_PE, (sev), (fmt), (p1), (p2));
+
+#define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) \
+	QDF_TRACE(QDF_MODULE_ID_PE, (sev), (fmt), (p1), (p2), (p3));
+
+#define FRAMES_DUMP(ctx, sev, p, n) \
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, (sev), (p), (n);
+
+#endif /* #if defined( DOT11F_ENABLE_LOGGING ) */
+
+#else
+
+#undef DOT11F_ENABLE_LOGGING
+#undef DOT11F_DUMP_FRAMES
+#define DOT11F_LOG_GATE (1)
+
+#endif
+
+/* #define DOT11F_ENABLE_DBG_BREAK ( 1 ) */
+
+/* Local Variables: */
+/* fill-column: 72 */
+/* indent-tabs-mode: nil */
+/* show-trailing-whitespace: t */
+/* End: */
+
+#endif /* DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582 */
diff --git a/core/mac/src/sys/legacy/src/utils/inc/utils_parser.h b/core/mac/src/sys/legacy/src/utils/inc/utils_parser.h
new file mode 100644
index 0000000..b7f87fa
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/inc/utils_parser.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file utils_parser.h contains the utility function protos
+ * used internally by the parser
+ * Author:        Chandra Modumudi
+ * Date:          02/11/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __UTILS_PARSE_H__
+#define __UTILS_PARSE_H__
+
+#include <stdarg.h>
+#include "sir_api.h"
+#include "dot11f.h"
+#include "utils_api.h"
+
+void convert_ssid(tpAniSirGlobal, tSirMacSSid *, tDot11fIESSID *);
+void convert_supp_rates(tpAniSirGlobal, tSirMacRateSet *, tDot11fIESuppRates *);
+void convert_fh_params(tpAniSirGlobal, tSirMacFHParamSet *,
+		       tDot11fIEFHParamSet *);
+void convert_ext_supp_rates(tpAniSirGlobal, tSirMacRateSet *,
+			    tDot11fIEExtSuppRates *);
+void convert_qos_caps(tpAniSirGlobal, tSirMacQosCapabilityIE *,
+		      tDot11fIEQOSCapsAp *);
+void convert_qos_caps_station(tpAniSirGlobal, tSirMacQosCapabilityStaIE *,
+			      tDot11fIEQOSCapsStation *);
+QDF_STATUS convert_wpa(tpAniSirGlobal, tSirMacWpaInfo *, tDot11fIEWPA *);
+QDF_STATUS convert_wpa_opaque(tpAniSirGlobal, tSirMacWpaInfo *,
+			      tDot11fIEWPAOpaque *);
+QDF_STATUS convert_wapi_opaque(tpAniSirGlobal, tSirMacWapiInfo *,
+			       tDot11fIEWAPIOpaque *);
+QDF_STATUS convert_rsn(tpAniSirGlobal, tSirMacRsnInfo *, tDot11fIERSN *);
+QDF_STATUS convert_rsn_opaque(tpAniSirGlobal, tSirMacRsnInfo *,
+			      tDot11fIERSNOpaque *);
+void convert_power_caps(tpAniSirGlobal, tSirMacPowerCapabilityIE *,
+			tDot11fIEPowerCaps *);
+void convert_supp_channels(tpAniSirGlobal, tSirMacSupportedChannelIE *,
+			   tDot11fIESuppChannels *);
+void convert_cf_params(tpAniSirGlobal, tSirMacCfParamSet *, tDot11fIECFParams *);
+void convert_tim(tpAniSirGlobal, tSirMacTim *, tDot11fIETIM *);
+void convert_country(tpAniSirGlobal, tSirCountryInformation *,
+		     tDot11fIECountry *);
+void convert_wmm_params(tpAniSirGlobal, tSirMacEdcaParamSetIE *,
+			tDot11fIEWMMParams *);
+void convert_erp_info(tpAniSirGlobal, tSirMacErpInfo *, tDot11fIEERPInfo *);
+void convert_edca_param(tpAniSirGlobal, tSirMacEdcaParamSetIE *,
+			tDot11fIEEDCAParamSet *);
+void convert_mu_edca_param(tpAniSirGlobal mac_ctx,
+			tSirMacEdcaParamSetIE *mu_edca,
+			tDot11fIEmu_edca_param_set *ie);
+void convert_tspec(tpAniSirGlobal, tSirMacTspecIE *, tDot11fIETSPEC *);
+QDF_STATUS convert_tclas(tpAniSirGlobal, tSirTclasInfo *, tDot11fIETCLAS *);
+void convert_wmmtspec(tpAniSirGlobal, tSirMacTspecIE *, tDot11fIEWMMTSPEC *);
+QDF_STATUS convert_wmmtclas(tpAniSirGlobal, tSirTclasInfo *,
+			    tDot11fIEWMMTCLAS *);
+void convert_ts_delay(tpAniSirGlobal, tSirMacTsDelayIE *, tDot11fIETSDelay *);
+void convert_schedule(tpAniSirGlobal, tSirMacScheduleIE *, tDot11fIESchedule *);
+void convert_wmm_schedule(tpAniSirGlobal, tSirMacScheduleIE *,
+			  tDot11fIEWMMSchedule *);
+QDF_STATUS convert_wsc_opaque(tpAniSirGlobal, tSirAddie *,
+			      tDot11fIEWscIEOpaque *);
+QDF_STATUS convert_p2p_opaque(tpAniSirGlobal, tSirAddie *,
+			      tDot11fIEP2PIEOpaque *);
+#ifdef WLAN_FEATURE_WFD
+QDF_STATUS convert_wfd_opaque(tpAniSirGlobal, tSirAddie *,
+			      tDot11fIEWFDIEOpaque *);
+#endif
+void convert_qos_mapset_frame(tpAniSirGlobal, tSirQosMapSet *,
+			      tDot11fIEQosMapSet *);
+
+#endif
diff --git a/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
new file mode 100644
index 0000000..528872e
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
@@ -0,0 +1,29348 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * \file dot11f.c
+ *
+ * \brief Structures, functions & definitions for
+ * working with 802.11 Frames
+ *
+ *
+ * This file was automatically generated by 'framesc'
+ * Tue Sep 18 11:47:29 2018 from the following file(s):
+ *
+ * dot11f.frms
+ *
+ * PLEASE DON'T EDIT THIS FILE BY HAND!
+ *
+ */
+
+#if !defined  ANI_OS_TYPE_OSX && !defined ANI_OS_TYPE_LINUX && !defined ANI_OS_TYPE_ANDROID
+#include <memory.h> /* For memcpy */
+#include <stdio.h>  /* For _vsnprintf */
+#include <stddef.h> /* For offsetof */
+#endif
+
+#include <ani_global.h>
+#include <utils_api.h>
+#include "dot11fdefs.h"
+#include "dot11f.h"
+
+#if defined(_MSC_VER)
+#pragma warning (disable:4244)
+#pragma warning (disable:4505)
+#pragma warning (disable:4702)
+#pragma warning (disable:4996)/* ... was declared deprecated */
+#endif /* Microsoft C/C++ */
+
+typedef unsigned char tFRAMES_BOOL;
+typedef void (*pfnGeneric_t)(void);
+
+typedef struct sFFDefn {
+	const char  *name;
+	uint32_t offset;
+	uint16_t sig;
+	uint8_t  size;
+} tFFDefn;
+
+typedef struct sIEDefn {
+	uint32_t  offset;
+	uint32_t  presenceOffset;
+	uint32_t  countOffset;
+	const char   *name;
+	uint16_t  arraybound;
+	uint16_t  minSize;
+	uint16_t  maxSize;
+	uint16_t  sig;
+	unsigned char oui[5];
+	unsigned char noui;
+	uint8_t   eid;
+	uint8_t   extn_eid;
+	tFRAMES_BOOL  fMandatory;
+} tIEDefn;
+
+#if !defined(countof)
+#define countof(x) (sizeof((x)) / sizeof((x)[0]))
+#endif
+
+#if !defined(DOT11F_MEMCPY)
+#define DOT11F_MEMCPY(ctx, dst, src, len) \
+	memcpy((dst), (src), (len))
+#endif
+
+#if !defined(DOT11F_MEMCMP)
+#define DOT11F_MEMCMP(ctx, lhs, rhs, len) \
+	memcmp((lhs), (rhs), (len))
+#endif
+
+#ifndef DOT11F_HAVE_LOG_SEVERITIES
+#define FRLOG_OFF (0)
+#define FRLOGP    (1)
+#define FRLOGE    (2)
+#define FRLOGW    (3)
+#define FRLOG1    (4)
+#define FRLOG2    (5)
+#define FRLOG3    (6)
+#define FRLOG4    (7)
+#endif
+
+#define FRFL(x) x
+
+#define FRAMES_LOG0(ctx, sev, fmt)
+#define FRAMES_LOG1(ctx, sev, fmt, p1)
+#define FRAMES_LOG2(ctx, sev, fmt, p1, p2)
+#define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3)
+#define FRAMES_LOG4(ctx, sev, fmt, p1, p2, p3, p4)
+#define FRAMES_DUMP(ctx, sev, p, n)
+#ifndef FRAMES_SEV_FOR_FRAME
+#define FRAMES_SEV_FOR_FRAME(ctx, sig) FRLOG3
+#endif
+
+#if defined(DOT11F_ENABLE_DBG_BREAK) && defined (WIN32)
+#define FRAMES_DBG_BREAK() { _asm int 3 }
+#else
+#define FRAMES_DBG_BREAK()
+#endif
+
+#if !defined(DOT11F_PARAMETER_CHECK)
+#if defined (DOT11F_HAVE_WIN32_API)
+
+#define DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm) \
+	do { \
+		if (!pBuf || IsBadReadPtr(pBuf, nBuf))\
+			return DOT11F_BAD_INPUT_BUFFER; \
+		if (!pFrm || IsBadWritePtr(pFrm, nFrm))\
+			return DOT11F_BAD_OUTPUT_BUFFER; \
+	} while (0)
+
+#define DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) \
+	do { \
+		if (!pSrc || IsBadReadPtr(pSrc, 4))\
+			eturn DOT11F_BAD_INPUT_BUFFER; \
+		if (!pBuf || IsBadWritePtr(pBuf, nBuf))\
+			return DOT11F_BAD_OUTPUT_BUFFER; \
+		if (!nBuf)\
+			return DOT11F_BAD_OUTPUT_BUFFER; \
+		if (IsBadWritePtr(pnConsumed, 4))\
+			return DOT11F_BAD_OUTPUT_BUFFER; \
+	} while (0)
+
+#else
+
+#define DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm) \
+	if (!pBuf)\
+		return DOT11F_BAD_INPUT_BUFFER; \
+	if (!pFrm)\
+		return DOT11F_BAD_OUTPUT_BUFFER \
+
+#define DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) \
+	if (!pSrc)\
+		return DOT11F_BAD_INPUT_BUFFER; \
+	if (!pBuf)\
+		return DOT11F_BAD_OUTPUT_BUFFER; \
+	if (!nBuf)\
+		return DOT11F_BAD_OUTPUT_BUFFER; \
+	if (!pnConsumed)\
+		return DOT11F_BAD_OUTPUT_BUFFER \
+
+#endif
+#endif
+
+static void framesntohs(tpAniSirGlobal    pCtx,
+			uint16_t *pOut,
+			uint8_t  *pIn,
+			tFRAMES_BOOL  fMsb)
+{
+	(void)pCtx;
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+	if (!fMsb)
+		DOT11F_MEMCPY(pCtx, (uint16_t *)pOut, pIn, 2);
+	else
+		*pOut = (uint16_t)(*pIn << 8) | *(pIn + 1);
+#else
+	if (!fMsb)
+		*pOut = (uint16_t)(*pIn | (*(pIn + 1) << 8));
+	else
+		DOT11F_MEMCPY(pCtx, (uint16_t *)pOut, pIn, 2);
+#endif
+}
+
+static void framesntohl(tpAniSirGlobal    pCtx,
+			uint32_t *pOut,
+			uint8_t  *pIn,
+			tFRAMES_BOOL  fMsb)
+{
+	(void)pCtx;
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+	if (!fMsb)
+		DOT11F_MEMCPY(pCtx, (uint32_t *)pOut, pIn, 4);
+	else
+		*pOut = (uint32_t)(*pIn << 24) |
+			(*(pIn + 1) << 16) |
+			(*(pIn + 2) <<  8) |
+			(*(pIn + 3));
+#else
+	if (!fMsb)
+		*pOut = (uint32_t)(*(pIn + 3) << 24) |
+			(*(pIn + 2) << 16) |
+			(*(pIn + 1) <<  8) |
+			(*(pIn));
+else
+		*pOut = *(uint32_t *)pIn;
+#endif
+}
+
+static void framesntohq(tpAniSirGlobal    pCtx,
+			tDOT11F_U64 *pOut,
+			uint8_t  *pIn,
+			tFRAMES_BOOL  fMsb)
+{
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+	framesntohl(pCtx, &((*pOut)[0]), pIn, fMsb);
+	framesntohl(pCtx, &((*pOut)[1]), pIn + 4, fMsb);
+#else
+	framesntohl(pCtx, &((*pOut)[1]), pIn, fMsb);
+	framesntohl(pCtx, &((*pOut)[0]), pIn + 4, fMsb);
+#endif
+}
+
+static void frameshtons(tpAniSirGlobal    pCtx,
+			uint8_t  *pOut,
+			uint16_t  pIn,
+			tFRAMES_BOOL  fMsb)
+{
+	(void)pCtx;
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+	if (!fMsb) {
+		DOT11F_MEMCPY(pCtx, pOut, &pIn, 2);
+	} else {
+		*pOut       = (pIn & 0xff00) >> 8;
+		*(pOut + 1) = pIn & 0xff;
+	}
+#else
+	if (!fMsb) {
+		*pOut       = pIn & 0xff;
+		*(pOut + 1) = (pIn & 0xff00) >> 8;
+	} else {
+		DOT11F_MEMCPY(pCtx, pOut, &pIn, 2);
+	}
+#endif
+}
+
+static void frameshtonl(tpAniSirGlobal    pCtx,
+			uint8_t  *pOut,
+			uint32_t  pIn,
+			tFRAMES_BOOL  fMsb)
+{
+	(void)pCtx;
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+	if (!fMsb) {
+		DOT11F_MEMCPY(pCtx, pOut, &pIn, 4);
+	} else {
+		*pOut       = (pIn & 0xff000000) >> 24;
+		*(pOut + 1) = (pIn & 0x00ff0000) >> 16;
+		*(pOut + 2) = (pIn & 0x0000ff00) >>  8;
+		*(pOut + 3) = (pIn & 0x000000ff);
+	}
+#else
+	if (!fMsb) {
+		*pOut       = (pIn & 0x000000ff);
+		*(pOut + 1) = (pIn & 0x0000ff00) >>  8;
+		*(pOut + 2) = (pIn & 0x00ff0000) >> 16;
+		*(pOut + 3) = (pIn & 0xff000000) >> 24;
+	} else {
+		DOT11F_MEMCPY(pCtx, pOut, &pIn, 4);
+	}
+#endif
+}
+
+static void frameshtonq(tpAniSirGlobal    pCtx,
+			uint8_t  *pOut,
+			tDOT11F_U64  pIn,
+			tFRAMES_BOOL  fMsb)
+{
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+	frameshtonl(pCtx, pOut, pIn[0], fMsb);
+	frameshtonl(pCtx, pOut + 4, pIn[1], fMsb);
+#else
+	frameshtonl(pCtx, pOut + 4, pIn[1], fMsb);
+	frameshtonl(pCtx, pOut, pIn[0], fMsb);
+#endif
+}
+
+static const tIEDefn *find_ie_defn(tpAniSirGlobal pCtx,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   const tIEDefn  IEs[])
+{
+	const tIEDefn *pIe;
+	(void)pCtx;
+
+	pIe = &(IEs[0]);
+	while (0xff != pIe->eid || pIe->extn_eid) {
+		if (*pBuf == pIe->eid) {
+			if (pIe->eid == 0xff) {
+				if ((nBuf > 2) &&
+				    (*(pBuf + 2)) == pIe->extn_eid)
+					return pIe;
+			} else {
+				if (0 == pIe->noui)
+					return pIe;
+
+				if ((nBuf > (uint32_t)(pIe->noui + 2)) &&
+				    (!DOT11F_MEMCMP(pCtx, pBuf + 2, pIe->oui,
+						      pIe->noui)))
+					return pIe;
+			}
+		}
+
+		++pIe;
+	}
+
+	return NULL;
+}
+
+static uint32_t get_container_ies_len(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint32_t  nBuf,
+				      uint8_t *pnConsumed,
+				      const tIEDefn  IEs[])
+{
+	const tIEDefn *pIe, *pIeFirst;
+	uint8_t *pBufRemaining = pBuf;
+	uint32_t len = 0;
+	(void)pCtx;
+
+	pIeFirst = &(IEs[0]);
+
+	if (*pBufRemaining != pIeFirst->eid)
+		return DOT11F_INTERNAL_ERROR;
+	len += *(pBufRemaining+1);
+	pBufRemaining += len + 2;
+	len += 2;
+	while (len < nBuf) {
+		pIe = find_ie_defn(pCtx, pBufRemaining, nBuf - len, IEs);
+		if (NULL == pIe)
+			break;
+		if (pIe->eid == pIeFirst->eid)
+			break;
+		len += *(pBufRemaining + 1) + 2;
+		pBufRemaining += *(pBufRemaining + 1) + 2;
+	}
+
+	if ((len > 0xFF) || (len > nBuf))
+		return DOT11F_INTERNAL_ERROR;
+	*pnConsumed = len;
+	return DOT11F_PARSE_SUCCESS;
+
+}
+
+
+static uint32_t unpack_core(tpAniSirGlobal pCtx,
+			    uint8_t *pBuf,
+			    uint32_t nBuf,
+			    const tFFDefn  FFs[],
+			    const tIEDefn  IEs[],
+			    uint8_t *pFrm,
+			    size_t nFrm,
+			    bool append_ie);
+static uint32_t pack_core(tpAniSirGlobal pCtx,
+			  uint8_t *pSrc,
+			  uint8_t *pBuf,
+			  uint32_t  nBuf,
+			  uint32_t *pnConsumed,
+			  const tFFDefn  FFs[],
+			  const tIEDefn  IEs[]);
+static uint32_t get_packed_size_core(tpAniSirGlobal pCtx,
+				     uint8_t *pFrm,
+				     uint32_t *pnNeeded,
+				     const tIEDefn  IEs[]);
+
+static uint32_t dot11f_unpack_tlv_common_func(tpAniSirGlobal pCtx,
+			 uint8_t *pBuf, uint16_t tlvlen,
+			 uint8_t *pDstPresent, uint8_t *pDstField)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)tlvlen; /* Shutup the compiler */
+
+	*pDstPresent = 1;
+	*pDstField = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_common_func. */
+
+static uint32_t dot11f_unpack_tlv_common_func2(tpAniSirGlobal  pCtx,
+			 uint8_t *pBuf, uint16_t tlvlen,
+			 uint8_t *pDstPresent, uint16_t *pDstState)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)tlvlen; /* Shutup the compiler */
+
+	*pDstPresent = 1;
+	framesntohs(pCtx, pDstState, pBuf, 1);
+	(void)pCtx;
+	return status;
+
+} /* End dot11f_unpack_tlv_common_func2. */
+
+static void dot11f_unpack_ff_common_func(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf, uint16_t *pDstField)
+{
+	framesntohs(pCtx, pDstField, pBuf, 0);
+	(void)pCtx;
+} /* End dot11f_unpack_ff_common_func. */
+
+static uint32_t dot11f_unpack_ie_common_func(tpAniSirGlobal pCtx, uint8_t *pBuf,
+				      uint8_t ielen, uint8_t *pDstPresent,
+				      uint8_t *pDstField)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)ielen;
+	(void)pBuf;
+	if ((*pDstPresent))
+		status = DOT11F_DUPLICATE_IE;
+	*pDstPresent = 1;
+	*pDstField = *pBuf;
+	(void)pCtx;
+
+	return status;
+} /* End dot11f_unpack_ie_common_func */
+
+typedef struct sTLVDefn {
+	uint32_t   offset;
+	uint32_t   presenceOffset;
+	const char     *name;
+	uint16_t   sig;
+	uint32_t   id;
+	uint32_t   pec;
+	uint32_t   minSize;
+	uint32_t   maxSize;
+	uint8_t    fMandatory;
+	uint8_t    sType;
+	uint8_t    sLen;
+	uint8_t    fMsb;
+} tTLVDefn;
+
+static const tTLVDefn *find_tlv_defn(tpAniSirGlobal    pCtx,
+				     uint8_t  *pBuf,
+				     uint32_t  nBuf,
+				     const tTLVDefn      TLVs[])
+{
+	const tTLVDefn *pTlv;
+	uint32_t   pec;
+	uint16_t   id;
+
+	pTlv = &(TLVs[0]);
+	(void)pCtx;
+	if (pTlv->sType == 2)
+		framesntohs(pCtx, &id, pBuf, 1);
+	else
+		id = *pBuf;
+
+	while (0xffff != pTlv->id) {
+		if (id == pTlv->id) {
+			if (0 == pTlv->pec)
+				return pTlv;
+
+			if (nBuf > 5) {
+				pec = ((*(pBuf + 4)) << 16) |
+				      ((*(pBuf + 5)) <<  8) |
+				      *(pBuf + 6);
+				if (pec == pTlv->pec)
+					return pTlv;
+			}
+		}
+
+		++pTlv;
+	}
+
+	return NULL;
+}
+
+static uint32_t unpack_tlv_core(tpAniSirGlobal   pCtx,
+			uint8_t *pBuf,
+			uint32_t nBuf,
+			const tTLVDefn TLVs[],
+			uint8_t *pFrm,
+			size_t nFrm);
+static uint32_t pack_tlv_core(tpAniSirGlobal pCtx,
+			      uint8_t *pSrc,
+			      uint8_t *pBuf,
+			      uint32_t  nBuf,
+			      uint32_t *pnConsumed,
+			      const tTLVDefn  TLVs[],
+			      uint32_t *pidx);
+static uint32_t get_packed_size_tlv_core(tpAniSirGlobal pCtx,
+					 uint8_t *pFrm,
+					 uint32_t *pnNeeded,
+					 const tTLVDefn  TLVs[]);
+
+#define SigFfAID (0x0001)
+
+void dot11f_unpack_ff_action(tpAniSirGlobal pCtx,
+			     uint8_t *pBuf,
+			     tDot11fFfAction *pDst)
+{
+	pDst->action = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_action. */
+
+#define SigFfAction (0x0002)
+
+#define SigFfAuthAlgo (0x0003)
+
+#define SigFfAuthSeqNo (0x0004)
+
+#define SigFfBeaconInterval (0x0005)
+
+void dot11f_unpack_ff_capabilities(tpAniSirGlobal pCtx,
+				   uint8_t *pBuf,
+				   tDot11fFfCapabilities *pDst)
+{
+	uint16_t tmp0__;
+	framesntohs(pCtx, &tmp0__, pBuf, 0);
+	pDst->ess = tmp0__ >> 0 & 0x1;
+	pDst->ibss = tmp0__ >> 1 & 0x1;
+	pDst->cfPollable = tmp0__ >> 2 & 0x1;
+	pDst->cfPollReq = tmp0__ >> 3 & 0x1;
+	pDst->privacy = tmp0__ >> 4 & 0x1;
+	pDst->shortPreamble = tmp0__ >> 5 & 0x1;
+	pDst->pbcc = tmp0__ >> 6 & 0x1;
+	pDst->channelAgility = tmp0__ >> 7 & 0x1;
+	pDst->spectrumMgt = tmp0__ >> 8 & 0x1;
+	pDst->qos = tmp0__ >> 9 & 0x1;
+	pDst->shortSlotTime = tmp0__ >> 10 & 0x1;
+	pDst->apsd = tmp0__ >> 11 & 0x1;
+	pDst->rrm = tmp0__ >> 12 & 0x1;
+	pDst->dsssOfdm = tmp0__ >> 13 & 0x1;
+	pDst->delayedBA = tmp0__ >> 14 & 0x1;
+	pDst->immediateBA = tmp0__ >> 15 & 0x1;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_capabilities. */
+
+#define SigFfCapabilities (0x0006)
+
+void dot11f_unpack_ff_category(tpAniSirGlobal pCtx,
+			       uint8_t *pBuf,
+			       tDot11fFfCategory *pDst)
+{
+	pDst->category = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_category. */
+
+#define SigFfCategory (0x0007)
+
+void dot11f_unpack_ff_current_ap_address(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       tDot11fFfCurrentAPAddress *pDst)
+{
+	DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6);
+	(void)pCtx;
+} /* End dot11f_unpack_ff_current_ap_address. */
+
+#define SigFfCurrentAPAddress (0x0008)
+
+void dot11f_unpack_ff_dialog_token(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  tDot11fFfDialogToken *pDst)
+{
+	pDst->token = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_dialog_token. */
+
+#define SigFfDialogToken (0x0009)
+
+void dot11f_unpack_ff_link_margin(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 tDot11fFfLinkMargin *pDst)
+{
+	pDst->linkMargin = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_link_margin. */
+
+#define SigFfLinkMargin (0x000a)
+
+#define SigFfListenInterval (0x000b)
+
+void dot11f_unpack_ff_max_tx_power(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 tDot11fFfMaxTxPower *pDst)
+{
+	pDst->maxTxPower = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_max_tx_power. */
+
+#define SigFfMaxTxPower (0x000c)
+
+void dot11f_unpack_ff_num_of_repetitions(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       tDot11fFfNumOfRepetitions *pDst)
+{
+	framesntohs(pCtx, &pDst->repetitions, pBuf, 0);
+	(void)pCtx;
+} /* End dot11f_unpack_ff_num_of_repetitions. */
+
+#define SigFfNumOfRepetitions (0x000d)
+
+void dot11f_unpack_ff_operating_mode(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    tDot11fFfOperatingMode *pDst)
+{
+	uint8_t tmp1__;
+	tmp1__ = *pBuf;
+	pDst->chanWidth = tmp1__ >> 0 & 0x3;
+	pDst->reserved = tmp1__ >> 2 & 0x3;
+	pDst->rxNSS = tmp1__ >> 4 & 0x7;
+	pDst->rxNSSType = tmp1__ >> 7 & 0x1;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_operating_mode. */
+
+#define SigFfOperatingMode (0x000e)
+
+void dot11f_unpack_ff_rcpi(tpAniSirGlobal pCtx,
+			   uint8_t *pBuf,
+			   tDot11fFfRCPI *pDst)
+{
+	pDst->rcpi = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_rcpi. */
+
+#define SigFfRCPI (0x000f)
+
+void dot11f_unpack_ff_rsni(tpAniSirGlobal pCtx,
+			   uint8_t *pBuf,
+			   tDot11fFfRSNI *pDst)
+{
+	pDst->rsni = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_rsni. */
+
+#define SigFfRSNI (0x0010)
+
+#define SigFfReason (0x0011)
+
+void dot11f_unpack_ff_rx_antenna_id(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  tDot11fFfRxAntennaId *pDst)
+{
+	pDst->antennaId = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_rx_antenna_id. */
+
+#define SigFfRxAntennaId (0x0012)
+
+void dot11f_unpack_ff_sm_power_mode_set(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     tDot11fFfSMPowerModeSet *pDst)
+{
+	uint8_t tmp2__;
+	tmp2__ = *pBuf;
+	pDst->PowerSave_En = tmp2__ >> 0 & 0x1;
+	pDst->Mode = tmp2__ >> 1 & 0x1;
+	pDst->reserved = tmp2__ >> 2 & 0x3f;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_sm_power_mode_set. */
+
+#define SigFfSMPowerModeSet (0x0013)
+
+#define SigFfStatus (0x0014)
+
+void dot11f_unpack_ff_status_code(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 tDot11fFfStatusCode *pDst)
+{
+	pDst->statusCode = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_status_code. */
+
+#define SigFfStatusCode (0x0015)
+
+void dot11f_unpack_ff_tpc_ele_id(tpAniSirGlobal pCtx,
+			       uint8_t *pBuf,
+			       tDot11fFfTPCEleID *pDst)
+{
+	pDst->TPCId = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_tpc_ele_id. */
+
+#define SigFfTPCEleID (0x0016)
+
+void dot11f_unpack_ff_tpc_ele_len(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 tDot11fFfTPCEleLen *pDst)
+{
+	pDst->TPCLen = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_tpc_ele_len. */
+
+#define SigFfTPCEleLen (0x0017)
+
+void dot11f_unpack_ff_ts_info(tpAniSirGlobal pCtx,
+			     uint8_t *pBuf,
+			     tDot11fFfTSInfo *pDst)
+{
+	uint32_t tmp3__;
+	framesntohl(pCtx, &tmp3__, pBuf, 0);
+	pDst->traffic_type = tmp3__ >> 0 & 0x1;
+	pDst->tsid = tmp3__ >> 1 & 0xf;
+	pDst->direction = tmp3__ >> 5 & 0x3;
+	pDst->access_policy = tmp3__ >> 7 & 0x3;
+	pDst->aggregation = tmp3__ >> 9 & 0x1;
+	pDst->psb = tmp3__ >> 10 & 0x1;
+	pDst->user_priority = tmp3__ >> 11 & 0x7;
+	pDst->tsinfo_ack_pol = tmp3__ >> 14 & 0x3;
+	pDst->schedule = tmp3__ >> 16 & 0x1;
+	pDst->unused = tmp3__ >> 17 & 0x7fff;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_ts_info. */
+
+#define SigFfTSInfo (0x0018)
+
+void dot11f_unpack_ff_time_stamp(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 tDot11fFfTimeStamp *pDst)
+{
+	framesntohq(pCtx, &pDst->timestamp, pBuf, 0);
+	(void)pCtx;
+} /* End dot11f_unpack_ff_time_stamp. */
+
+#define SigFfTimeStamp (0x0019)
+
+void dot11f_unpack_ff_transaction_id(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    tDot11fFfTransactionId *pDst)
+{
+	DOT11F_MEMCPY(pCtx, pDst->transId, pBuf, 2);
+	(void)pCtx;
+} /* End dot11f_unpack_ff_transaction_id. */
+
+#define SigFfTransactionId (0x001a)
+
+void dot11f_unpack_ff_tx_antenna_id(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  tDot11fFfTxAntennaId *pDst)
+{
+	pDst->antennaId = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_tx_antenna_id. */
+
+#define SigFfTxAntennaId (0x001b)
+
+void dot11f_unpack_ff_tx_power(tpAniSirGlobal pCtx,
+			      uint8_t *pBuf,
+			      tDot11fFfTxPower *pDst)
+{
+	pDst->txPower = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_tx_power. */
+
+#define SigFfTxPower (0x001c)
+
+void dot11f_unpack_ff_vht_membership_status_array(tpAniSirGlobal pCtx,
+					       uint8_t *pBuf,
+					       tDot11fFfVhtMembershipStatusArray *pDst)
+{
+	DOT11F_MEMCPY(pCtx, pDst->membershipStatusArray, pBuf, 8);
+	(void)pCtx;
+} /* End dot11f_unpack_ff_vht_membership_status_array. */
+
+#define SigFfVhtMembershipStatusArray (0x001d)
+
+void dot11f_unpack_ff_vht_user_position_array(tpAniSirGlobal pCtx,
+					   uint8_t *pBuf,
+					   tDot11fFfVhtUserPositionArray *pDst)
+{
+	DOT11F_MEMCPY(pCtx, pDst->userPositionArray, pBuf, 16);
+	(void)pCtx;
+} /* End dot11f_unpack_ff_vht_user_position_array. */
+
+#define SigFfVhtUserPositionArray (0x001e)
+
+void dot11f_unpack_ff_addba_param_set(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      tDot11fFfaddba_param_set *pDst)
+{
+	uint16_t tmp4__;
+	framesntohs(pCtx, &tmp4__, pBuf, 0);
+	pDst->amsdu_supp = tmp4__ >> 0 & 0x1;
+	pDst->policy = tmp4__ >> 1 & 0x1;
+	pDst->tid = tmp4__ >> 2 & 0xf;
+	pDst->buff_size = tmp4__ >> 6 & 0x3ff;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_addba_param_set. */
+
+#define SigFfaddba_param_set (0x001f)
+
+void dot11f_unpack_ff_ba_start_seq_ctrl(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 tDot11fFfba_start_seq_ctrl *pDst)
+{
+	uint16_t tmp5__;
+	framesntohs(pCtx, &tmp5__, pBuf, 0);
+	pDst->frag_number = tmp5__ >> 0 & 0xf;
+	pDst->ssn = tmp5__ >> 4 & 0xfff;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_ba_start_seq_ctrl. */
+
+#define SigFfba_start_seq_ctrl (0x0020)
+
+void dot11f_unpack_ff_ba_timeout(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 tDot11fFfba_timeout *pDst)
+{
+	framesntohs(pCtx, &pDst->timeout, pBuf, 0);
+	(void)pCtx;
+} /* End dot11f_unpack_ff_ba_timeout. */
+
+#define SigFfba_timeout (0x0021)
+
+void dot11f_unpack_ff_delba_param_set(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      tDot11fFfdelba_param_set *pDst)
+{
+	uint16_t tmp6__;
+	framesntohs(pCtx, &tmp6__, pBuf, 0);
+	pDst->reserved = tmp6__ >> 0 & 0x7ff;
+	pDst->initiator = tmp6__ >> 11 & 0x1;
+	pDst->tid = tmp6__ >> 12 & 0xf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_delba_param_set. */
+
+#define SigFfdelba_param_set (0x0022)
+
+void dot11f_unpack_ff_ext_chan_switch_ann_action(tpAniSirGlobal pCtx,
+						 uint8_t *pBuf,
+						 tDot11fFfext_chan_switch_ann_action *pDst)
+{
+	uint32_t tmp7__;
+	framesntohl(pCtx, &tmp7__, pBuf, 0);
+	pDst->switch_mode = tmp7__ >> 0 & 0xff;
+	pDst->op_class = tmp7__ >> 8 & 0xff;
+	pDst->new_channel = tmp7__ >> 16 & 0xff;
+	pDst->switch_count = tmp7__ >> 24 & 0xff;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_ext_chan_switch_ann_action. */
+
+#define SigFfext_chan_switch_ann_action (0x0023)
+
+void dot11f_unpack_ff_p2p_action_oui(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     tDot11fFfp2p_action_oui *pDst)
+{
+	DOT11F_MEMCPY(pCtx, pDst->oui_data, pBuf, 4);
+	(void)pCtx;
+} /* End dot11f_unpack_ff_p2p_action_oui. */
+
+#define SigFfp2p_action_oui (0x0024)
+
+void dot11f_unpack_ff_p2p_action_subtype(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 tDot11fFfp2p_action_subtype *pDst)
+{
+	pDst->subtype = *pBuf;
+	(void)pCtx;
+} /* End dot11f_unpack_ff_p2p_action_subtype. */
+
+#define SigFfp2p_action_subtype (0x0025)
+
+uint32_t dot11f_unpack_tlv_authorized_ma_cs(tpAniSirGlobal pCtx,
+					  uint8_t *pBuf,
+					  uint16_t tlvlen,
+					  tDot11fTLVAuthorizedMACs *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6);
+	pBuf += 6;
+	tlvlen -= (uint8_t)6;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_authorized_ma_cs. */
+
+#define SigTlvAuthorizedMACs (0x0001)
+
+
+#define SigTlvRequestToEnroll (0x0002)
+
+
+uint32_t dot11f_unpack_tlv_version2(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint16_t tlvlen,
+				    tDot11fTLVVersion2 *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp8__;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp8__ = *pBuf;
+	pBuf += 1;
+	tlvlen -= 1;
+	pDst->minor = tmp8__ >> 0 & 0xf;
+	pDst->major = tmp8__ >> 4 & 0xf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_version2. */
+
+#define SigTlvVersion2 (0x0003)
+
+
+#define SigTlvAPSetupLocked (0x0004)
+
+
+#define SigTlvAssociationState (0x0005)
+
+
+#define SigTlvConfigMethods (0x0006)
+
+
+#define SigTlvConfigurationError (0x0007)
+
+
+uint32_t dot11f_unpack_tlv_device_name(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint16_t tlvlen,
+				      tDot11fTLVDeviceName *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	pDst->num_text = (uint8_t)(tlvlen);
+	if (tlvlen > 32) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->text, pBuf, (tlvlen));
+	pBuf += (tlvlen);
+	tlvlen -= (tlvlen);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_device_name. */
+
+#define SigTlvDeviceName (0x0008)
+
+
+#define SigTlvDevicePasswordID (0x0009)
+
+
+uint32_t dot11f_unpack_tlv_extended_listen_timing(tpAniSirGlobal pCtx,
+						 uint8_t *pBuf,
+						 uint16_t tlvlen,
+						 tDot11fTLVExtendedListenTiming *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->availibilityPeriod, pBuf, 0);
+	pBuf += 2;
+	tlvlen -= (uint8_t)2;
+	if (unlikely(tlvlen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->availibilityInterval, pBuf, 0);
+	pBuf += 2;
+	tlvlen -= (uint8_t)2;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_extended_listen_timing. */
+
+#define SigTlvExtendedListenTiming (0x000a)
+
+
+uint32_t dot11f_unpack_tlv_listen_channel(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint16_t tlvlen,
+					 tDot11fTLVListenChannel *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 3)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3);
+	pBuf += 3;
+	tlvlen -= (uint8_t)3;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->regulatoryClass = *pBuf;
+	pBuf += 1;
+	tlvlen -= (uint8_t)1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->channel = *pBuf;
+	pBuf += 1;
+	tlvlen -= (uint8_t)1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_listen_channel. */
+
+#define SigTlvListenChannel (0x000b)
+
+
+uint32_t dot11f_unpack_tlv_manufacturer(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint16_t tlvlen,
+					 tDot11fTLVManufacturer *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	pDst->num_name = (uint8_t)(tlvlen);
+	if (tlvlen > 64) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->name, pBuf, (tlvlen));
+	pBuf += (tlvlen);
+	tlvlen -= (tlvlen);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_manufacturer. */
+
+#define SigTlvManufacturer (0x000c)
+
+
+#define SigTlvMinorReasonCode (0x000d)
+
+
+uint32_t dot11f_unpack_tlv_model_name(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     uint16_t tlvlen,
+				     tDot11fTLVModelName *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	pDst->num_text = (uint8_t)(tlvlen);
+	if (tlvlen > 32) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->text, pBuf, (tlvlen));
+	pBuf += (tlvlen);
+	tlvlen -= (tlvlen);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_model_name. */
+
+#define SigTlvModelName (0x000e)
+
+
+uint32_t dot11f_unpack_tlv_model_number(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint16_t tlvlen,
+				       tDot11fTLVModelNumber *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	pDst->num_text = (uint8_t)(tlvlen);
+	if (tlvlen > 32) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->text, pBuf, (tlvlen));
+	pBuf += (tlvlen);
+	tlvlen -= (tlvlen);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_model_number. */
+
+#define SigTlvModelNumber (0x000f)
+
+
+uint32_t dot11f_unpack_tlv_notice_of_absence(tpAniSirGlobal pCtx,
+					   uint8_t *pBuf,
+					   uint16_t tlvlen,
+					   tDot11fTLVNoticeOfAbsence *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->index = *pBuf;
+	pBuf += 1;
+	tlvlen -= (uint8_t)1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->CTSWindowOppPS = *pBuf;
+	pBuf += 1;
+	tlvlen -= (uint8_t)1;
+	pDst->num_NoADesc = (uint8_t)(tlvlen);
+	if (tlvlen > 36) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->NoADesc, pBuf, (tlvlen));
+	pBuf += (tlvlen);
+	tlvlen -= (tlvlen);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_notice_of_absence. */
+
+#define SigTlvNoticeOfAbsence (0x0010)
+
+
+uint32_t dot11f_unpack_tlv_operating_channel(tpAniSirGlobal pCtx,
+					    uint8_t *pBuf,
+					    uint16_t tlvlen,
+					    tDot11fTLVOperatingChannel *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 3)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3);
+	pBuf += 3;
+	tlvlen -= (uint8_t)3;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->regulatoryClass = *pBuf;
+	pBuf += 1;
+	tlvlen -= (uint8_t)1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->channel = *pBuf;
+	pBuf += 1;
+	tlvlen -= (uint8_t)1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_operating_channel. */
+
+#define SigTlvOperatingChannel (0x0011)
+
+
+uint32_t dot11f_unpack_tlv_p2_p_capability(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint16_t tlvlen,
+					 tDot11fTLVP2PCapability *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->deviceCapability = *pBuf;
+	pBuf += 1;
+	tlvlen -= (uint8_t)1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->groupCapability = *pBuf;
+	pBuf += 1;
+	tlvlen -= (uint8_t)1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_p2_p_capability. */
+
+#define SigTlvP2PCapability (0x0012)
+
+
+uint32_t dot11f_unpack_tlv_p2_p_device_id(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint16_t tlvlen,
+				       tDot11fTLVP2PDeviceId *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6);
+	pBuf += 6;
+	tlvlen -= (uint8_t)6;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_p2_p_device_id. */
+
+#define SigTlvP2PDeviceId (0x0013)
+
+
+static const tTLVDefn TLVS_P2PDeviceInfo[] = {
+	{ offsetof(tDot11fTLVP2PDeviceInfo, DeviceName),
+	offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName,
+	DOT11F_TLV_DEVICENAME, 0, 4, 36, 1, 2, 2, 1, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_tlv_p2_p_device_info(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint16_t tlvlen,
+					 tDot11fTLVP2PDeviceInfo *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6);
+	pBuf += 6;
+	tlvlen -= (uint8_t)6;
+	if (unlikely(tlvlen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->configMethod, pBuf, 0);
+	pBuf += 2;
+	tlvlen -= (uint8_t)2;
+	if (unlikely(tlvlen < 8)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->primaryDeviceType, pBuf, 8);
+	pBuf += 8;
+	tlvlen -= (uint8_t)8;
+	(void)pCtx;
+	status |= unpack_tlv_core(pCtx,
+				  pBuf,
+				  tlvlen,
+				  TLVS_P2PDeviceInfo,
+				  (uint8_t *)pDst,
+				  sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_tlv_p2_p_device_info. */
+
+#define SigTlvP2PDeviceInfo (0x0014)
+
+
+uint32_t dot11f_unpack_tlv_p2_p_group_info(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint16_t tlvlen,
+					 tDot11fTLVP2PGroupInfo *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	pDst->num_P2PClientInfoDesc = (uint8_t)(tlvlen);
+	DOT11F_MEMCPY(pCtx, pDst->P2PClientInfoDesc, pBuf, (tlvlen));
+	pBuf += (tlvlen);
+	tlvlen -= (tlvlen);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_p2_p_group_info. */
+
+#define SigTlvP2PGroupInfo (0x0015)
+
+
+#define SigTlvP2PStatus (0x0016)
+
+
+uint32_t dot11f_unpack_tlv_primary_device_type(tpAniSirGlobal pCtx,
+					     uint8_t *pBuf,
+					     uint16_t tlvlen,
+					     tDot11fTLVPrimaryDeviceType *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)tlvlen; /* Shutup the compiler */
+	pDst->present = 1;
+	if (unlikely(tlvlen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->primary_category, pBuf, 1);
+	pBuf += 2;
+	tlvlen -= (uint8_t)2;
+	if (unlikely(tlvlen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4);
+	pBuf += 4;
+	tlvlen -= (uint8_t)4;
+	if (unlikely(tlvlen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->sub_category, pBuf, 1);
+	pBuf += 2;
+	tlvlen -= (uint8_t)2;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_primary_device_type. */
+
+#define SigTlvPrimaryDeviceType (0x0017)
+
+
+#define SigTlvRFBands (0x0018)
+
+
+uint32_t dot11f_unpack_tlv_request_device_type(tpAniSirGlobal pCtx,
+					     uint8_t *pBuf,
+					     uint16_t tlvlen,
+					     tDot11fTLVRequestDeviceType *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->primary_category, pBuf, 1);
+	pBuf += 2;
+	tlvlen -= (uint8_t)2;
+	if (unlikely(tlvlen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4);
+	pBuf += 4;
+	tlvlen -= (uint8_t)4;
+	if (unlikely(tlvlen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->sub_category, pBuf, 1);
+	pBuf += 2;
+	tlvlen -= (uint8_t)2;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_request_device_type. */
+
+#define SigTlvRequestDeviceType (0x0019)
+
+
+#define SigTlvRequestType (0x001a)
+
+
+#define SigTlvResponseType (0x001b)
+
+
+#define SigTlvSelectedRegistrar (0x001c)
+
+
+#define SigTlvSelectedRegistrarConfigMethods (0x001d)
+
+
+uint32_t dot11f_unpack_tlv_serial_number(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint16_t tlvlen,
+					 tDot11fTLVSerialNumber *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	pDst->num_text = (uint8_t)(tlvlen);
+	if (tlvlen > 32) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->text, pBuf, (tlvlen));
+	pBuf += (tlvlen);
+	tlvlen -= (tlvlen);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_serial_number. */
+
+#define SigTlvSerialNumber (0x001e)
+
+
+uint32_t dot11f_unpack_tlv_uuid_e(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint16_t tlvlen,
+				  tDot11fTLVUUID_E *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 16)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16);
+	pBuf += 16;
+	tlvlen -= (uint8_t)16;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_uuid_e. */
+
+#define SigTlvUUID_E (0x001f)
+
+
+uint32_t dot11f_unpack_tlv_uuid_r(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint16_t tlvlen,
+				  tDot11fTLVUUID_R *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 16)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16);
+	pBuf += 16;
+	tlvlen -= (uint8_t)16;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_uuid_r. */
+
+#define SigTlvUUID_R (0x0020)
+
+
+static const tTLVDefn TLVS_VendorExtension[] = {
+	{ offsetof(tDot11fTLVVendorExtension, Version2),
+	offsetof(tDot11fTLVVersion2, present), "Version2", SigTlvVersion2,
+	DOT11F_TLV_VERSION2, 0, 3, 3, 0, 1, 1, 1, },
+	{ offsetof(tDot11fTLVVendorExtension, AuthorizedMACs),
+	offsetof(tDot11fTLVAuthorizedMACs, present), "AuthorizedMACs",
+	SigTlvAuthorizedMACs, DOT11F_TLV_AUTHORIZEDMACS, 0, 8, 8, 0, 1, 1, 1, },
+	{ offsetof(tDot11fTLVVendorExtension, RequestToEnroll),
+	offsetof(tDot11fTLVRequestToEnroll, present), "RequestToEnroll",
+	SigTlvRequestToEnroll, DOT11F_TLV_REQUESTTOENROLL,
+	0, 3, 3, 0, 1, 1, 1, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_tlv_vendor_extension(tpAniSirGlobal pCtx,
+					   uint8_t *pBuf,
+					   uint16_t tlvlen,
+					   tDot11fTLVVendorExtension *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 3)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->vendorId, pBuf, 3);
+	pBuf += 3;
+	tlvlen -= (uint8_t)3;
+	(void)pCtx;
+	status |= unpack_tlv_core(pCtx,
+				  pBuf,
+				  tlvlen,
+				  TLVS_VendorExtension,
+				  (uint8_t *)pDst,
+				  sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_tlv_vendor_extension. */
+
+#define SigTlvVendorExtension (0x0021)
+
+
+uint32_t dot11f_unpack_tlv_version(tpAniSirGlobal pCtx,
+				   uint8_t *pBuf,
+				   uint16_t tlvlen,
+				   tDot11fTLVVersion *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp9__;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp9__ = *pBuf;
+	pBuf += 1;
+	tlvlen -= 1;
+	pDst->minor = tmp9__ >> 0 & 0xf;
+	pDst->major = tmp9__ >> 4 & 0xf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_version. */
+
+#define SigTlvVersion (0x0022)
+
+
+#define SigTlvWPSState (0x0023)
+
+
+#define SigTlvassoc_disallowed (0x0024)
+
+
+#define SigTlvassoc_retry_delay (0x0025)
+
+
+#define SigTlvcellular_data_cap (0x0026)
+
+
+#define SigTlvcellular_data_con_pref (0x0027)
+
+
+#define SigTlvmbo_ap_cap (0x0028)
+
+
+uint32_t dot11f_unpack_tlv_non_prefferd_chan_rep(tpAniSirGlobal pCtx,
+						 uint8_t *pBuf,
+						 uint16_t tlvlen,
+						 tDot11fTLVnon_prefferd_chan_rep *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->oper_class = *pBuf;
+	pBuf += 1;
+	tlvlen -= (uint8_t)1;
+	pDst->num_channel_report = (uint8_t)(tlvlen);
+	if (tlvlen > 254) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->channel_report, pBuf, (tlvlen));
+	pBuf += (tlvlen);
+	tlvlen -= (tlvlen);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_non_prefferd_chan_rep. */
+
+#define SigTlvnon_prefferd_chan_rep (0x0029)
+
+
+uint32_t dot11f_unpack_tlv_oce_cap(tpAniSirGlobal pCtx,
+				   uint8_t *pBuf,
+				   uint16_t tlvlen,
+				   tDot11fTLVoce_cap *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp10__;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp10__ = *pBuf;
+	pBuf += 1;
+	tlvlen -= 1;
+	pDst->oce_release = tmp10__ >> 0 & 0x7;
+	pDst->is_sta_cfon = tmp10__ >> 3 & 0x1;
+	pDst->non_oce_ap_present = tmp10__ >> 4 & 0x1;
+	pDst->reserved = tmp10__ >> 5 & 0x7;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_oce_cap. */
+
+#define SigTlvoce_cap (0x002a)
+
+
+uint32_t dot11f_unpack_tlv_reduced_wan_metrics(tpAniSirGlobal pCtx,
+					       uint8_t *pBuf,
+					       uint16_t tlvlen,
+					       tDot11fTLVreduced_wan_metrics *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp11__;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp11__ = *pBuf;
+	pBuf += 1;
+	tlvlen -= 1;
+	pDst->downlink_av_cap = tmp11__ >> 0 & 0xf;
+	pDst->uplink_av_cap = tmp11__ >> 4 & 0xf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_reduced_wan_metrics. */
+
+#define SigTlvreduced_wan_metrics (0x002b)
+
+
+uint32_t dot11f_unpack_tlv_rssi_assoc_rej(tpAniSirGlobal pCtx,
+					  uint8_t *pBuf,
+					  uint16_t tlvlen,
+					  tDot11fTLVrssi_assoc_rej *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->delta_rssi = *pBuf;
+	pBuf += 1;
+	tlvlen -= (uint8_t)1;
+	if (unlikely(tlvlen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->retry_delay = *pBuf;
+	pBuf += 1;
+	tlvlen -= (uint8_t)1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_rssi_assoc_rej. */
+
+#define SigTlvrssi_assoc_rej (0x002c)
+
+
+#define SigTlvtransition_reason (0x002d)
+
+
+#define SigTlvtransition_reject_reason (0x002e)
+
+
+uint32_t dot11f_unpack_tlv_p2_p_interface(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint16_t tlvlen,
+					 tDot11fTLVP2PInterface *pDst)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	pDst->present = 1;
+	if (unlikely(tlvlen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6);
+	pBuf += 6;
+	tlvlen -= (uint8_t)6;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_tlv_p2_p_interface. */
+
+#define SigTlvP2PInterface (0x002f)
+
+
+#define SigTlvP2PManageability (0x0030)
+
+
+uint32_t dot11f_unpack_ie_gtk(tpAniSirGlobal pCtx,
+			      uint8_t *pBuf,
+			      uint8_t ielen,
+			      tDot11fIEGTK *pDst,
+			      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint16_t tmp12__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp12__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->keyId = tmp12__ >> 0 & 0x3;
+	pDst->reserved = tmp12__ >> 2 & 0x3feb;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->keyLength = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 8)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->RSC, pBuf, 8);
+	pBuf += 8;
+	ielen -= (uint8_t)8;
+	pDst->num_key = (uint8_t)(ielen);
+	if (ielen > 32) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->key, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_gtk. */
+
+#define SigIeGTK (0x0001)
+
+
+uint32_t dot11f_unpack_ie_igtk(tpAniSirGlobal pCtx,
+			       uint8_t *pBuf,
+			       uint8_t ielen,
+			       tDot11fIEIGTK *pDst,
+			       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->keyID, pBuf, 2);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->IPN, pBuf, 6);
+	pBuf += 6;
+	ielen -= (uint8_t)6;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->keyLength = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 24)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->key, pBuf, 24);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_igtk. */
+
+#define SigIeIGTK (0x0002)
+
+
+uint32_t dot11f_unpack_ie_r0_kh_id(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint8_t ielen,
+				  tDot11fIER0KH_ID *pDst,
+				  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_PMK_R0_ID = (uint8_t)(ielen);
+	if (ielen > 48) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->PMK_R0_ID, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_r0_kh_id. */
+
+#define SigIeR0KH_ID (0x0003)
+
+
+uint32_t dot11f_unpack_ie_r1_kh_id(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint8_t ielen,
+				  tDot11fIER1KH_ID *pDst,
+				  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->PMK_R1_ID, pBuf, 6);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_r1_kh_id. */
+
+#define SigIeR1KH_ID (0x0004)
+
+
+uint32_t dot11f_unpack_ie_ap_channel_report(tpAniSirGlobal pCtx,
+					  uint8_t *pBuf,
+					  uint8_t ielen,
+					  tDot11fIEAPChannelReport *pDst,
+					  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->regulatoryClass = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	pDst->num_channelList = (uint8_t)(ielen);
+	if (ielen > 50) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->channelList, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ap_channel_report. */
+
+#define SigIeAPChannelReport (0x0005)
+
+
+uint32_t dot11f_unpack_ie_bcn_reporting_detail(tpAniSirGlobal pCtx,
+					     uint8_t *pBuf,
+					     uint8_t ielen,
+					     tDot11fIEBcnReportingDetail *pDst,
+					     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->reportingDetail = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_bcn_reporting_detail. */
+
+#define SigIeBcnReportingDetail (0x0006)
+
+
+uint32_t dot11f_unpack_ie_beacon_report_frm_body(tpAniSirGlobal pCtx,
+					      uint8_t *pBuf,
+					      uint8_t ielen,
+					      tDot11fIEBeaconReportFrmBody *pDst,
+					      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_reportedFields = (uint8_t)(ielen);
+	if (ielen > 224) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->reportedFields, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_beacon_report_frm_body. */
+
+#define SigIeBeaconReportFrmBody (0x0007)
+
+
+uint32_t dot11f_unpack_ie_beacon_reporting(tpAniSirGlobal pCtx,
+					  uint8_t *pBuf,
+					  uint8_t ielen,
+					  tDot11fIEBeaconReporting *pDst,
+					  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->reportingCondition = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->threshold = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_beacon_reporting. */
+
+#define SigIeBeaconReporting (0x0008)
+
+
+uint32_t dot11f_unpack_ie_condensed_country_str(tpAniSirGlobal pCtx,
+					      uint8_t *pBuf,
+					      uint8_t ielen,
+					      tDot11fIECondensedCountryStr *pDst,
+					      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->countryStr, pBuf, 2);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_condensed_country_str. */
+
+#define SigIeCondensedCountryStr (0x0009)
+
+
+uint32_t dot11f_unpack_ie_measurement_pilot(tpAniSirGlobal pCtx,
+					   uint8_t *pBuf,
+					   uint8_t ielen,
+					   tDot11fIEMeasurementPilot *pDst,
+					   bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->measurementPilot = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	pDst->num_vendorSpecific = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->vendorSpecific, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_measurement_pilot. */
+
+#define SigIeMeasurementPilot (0x000a)
+
+
+uint32_t dot11f_unpack_ie_multi_bssid(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     uint8_t ielen,
+				     tDot11fIEMultiBssid *pDst,
+				     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->maxBSSIDIndicator = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	pDst->num_vendorSpecific = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->vendorSpecific, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_multi_bssid. */
+
+#define SigIeMultiBssid (0x000b)
+
+
+uint32_t dot11f_unpack_ie_ric_data(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint8_t ielen,
+				  tDot11fIERICData *pDst,
+				  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->Identifier = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->resourceDescCount = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->statusCode, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ric_data. */
+
+#define SigIeRICData (0x000c)
+
+
+uint32_t dot11f_unpack_ie_ric_descriptor(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIERICDescriptor *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->resourceType = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	pDst->num_variableData = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->variableData, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ric_descriptor. */
+
+#define SigIeRICDescriptor (0x000d)
+
+
+uint32_t dot11f_unpack_ie_rrm_enabled_cap(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIERRMEnabledCap *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp13__;
+	uint8_t tmp14__;
+	uint8_t tmp15__;
+	uint8_t tmp16__;
+	uint8_t tmp17__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp13__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->LinkMeasurement = tmp13__ >> 0 & 0x1;
+	pDst->NeighborRpt = tmp13__ >> 1 & 0x1;
+	pDst->parallel = tmp13__ >> 2 & 0x1;
+	pDst->repeated = tmp13__ >> 3 & 0x1;
+	pDst->BeaconPassive = tmp13__ >> 4 & 0x1;
+	pDst->BeaconActive = tmp13__ >> 5 & 0x1;
+	pDst->BeaconTable = tmp13__ >> 6 & 0x1;
+	pDst->BeaconRepCond = tmp13__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp14__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->FrameMeasurement = tmp14__ >> 0 & 0x1;
+	pDst->ChannelLoad = tmp14__ >> 1 & 0x1;
+	pDst->NoiseHistogram = tmp14__ >> 2 & 0x1;
+	pDst->statistics = tmp14__ >> 3 & 0x1;
+	pDst->LCIMeasurement = tmp14__ >> 4 & 0x1;
+	pDst->LCIAzimuth = tmp14__ >> 5 & 0x1;
+	pDst->TCMCapability = tmp14__ >> 6 & 0x1;
+	pDst->triggeredTCM = tmp14__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp15__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->APChanReport = tmp15__ >> 0 & 0x1;
+	pDst->RRMMIBEnabled = tmp15__ >> 1 & 0x1;
+	pDst->operatingChanMax = tmp15__ >> 2 & 0x7;
+	pDst->nonOperatinChanMax = tmp15__ >> 5 & 0x7;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp16__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->MeasurementPilot = tmp16__ >> 0 & 0x7;
+	pDst->MeasurementPilotEnabled = tmp16__ >> 3 & 0x1;
+	pDst->NeighborTSFOffset = tmp16__ >> 4 & 0x1;
+	pDst->RCPIMeasurement = tmp16__ >> 5 & 0x1;
+	pDst->RSNIMeasurement = tmp16__ >> 6 & 0x1;
+	pDst->BssAvgAccessDelay = tmp16__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp17__ = *pBuf;
+	pDst->BSSAvailAdmission = tmp17__ >> 0 & 0x1;
+	pDst->AntennaInformation = tmp17__ >> 1 & 0x1;
+	pDst->fine_time_meas_rpt = tmp17__ >> 2 & 0x1;
+	pDst->lci_capability = tmp17__ >> 3 & 0x1;
+	pDst->reserved = tmp17__ >> 4 & 0xf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_rrm_enabled_cap. */
+
+#define SigIeRRMEnabledCap (0x000e)
+
+
+uint32_t dot11f_unpack_ie_requested_info(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIERequestedInfo *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_requested_eids = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->requested_eids, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_requested_info. */
+
+#define SigIeRequestedInfo (0x000f)
+
+
+uint32_t dot11f_unpack_ie_ssid(tpAniSirGlobal pCtx,
+			       uint8_t *pBuf,
+			       uint8_t ielen,
+			       tDot11fIESSID *pDst,
+			       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present) {
+		status = DOT11F_DUPLICATE_IE;
+		return status;
+	}
+	pDst->present = 1;
+	pDst->num_ssid = (uint8_t)(ielen);
+	if (ielen > 32) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->ssid, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ssid. */
+
+#define SigIeSSID (0x0010)
+
+
+uint32_t dot11f_unpack_ie_schedule(tpAniSirGlobal pCtx,
+				   uint8_t *pBuf,
+				   uint8_t ielen,
+				   tDot11fIESchedule *pDst,
+				   bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint16_t tmp18__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp18__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->aggregation = tmp18__ >> 0 & 0x1;
+	pDst->tsid = tmp18__ >> 1 & 0xf;
+	pDst->direction = tmp18__ >> 5 & 0x3;
+	pDst->reserved = tmp18__ >> 7 & 0x1ff;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->service_interval, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->spec_interval, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_schedule. */
+
+#define SigIeSchedule (0x0011)
+
+
+uint32_t dot11f_unpack_ie_tclas(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIETCLAS *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->user_priority = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->classifier_type = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->classifier_mask = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	switch (pDst->classifier_type) {
+	case 0:
+		if (unlikely(ielen < 6)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6);
+		pBuf += 6;
+		ielen -= (uint8_t)6;
+		if (unlikely(ielen < 6)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6);
+		pBuf += 6;
+		ielen -= (uint8_t)6;
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+		break;
+	case 1:
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->info.IpParams.version = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		switch (pDst->info.IpParams.version) {
+		case 4:
+			if (unlikely(ielen < 4)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4);
+			pBuf += 4;
+			ielen -= (uint8_t)4;
+			if (unlikely(ielen < 4)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4);
+			pBuf += 4;
+			ielen -= (uint8_t)4;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->info.IpParams.params.IpV4Params.proto = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->info.IpParams.params.IpV4Params.reserved = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			break;
+		case 6:
+			if (unlikely(ielen < 16)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16);
+			pBuf += 16;
+			ielen -= (uint8_t)16;
+			if (unlikely(ielen < 16)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16);
+			pBuf += 16;
+			ielen -= (uint8_t)16;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 3)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3);
+			pBuf += 3;
+			ielen -= (uint8_t)3;
+			break;
+		}
+		break;
+	case 2:
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+		break;
+	}
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_tclas. */
+
+#define SigIeTCLAS (0x0012)
+
+
+#define SigIeTCLASSPROC (0x0013)
+
+
+uint32_t dot11f_unpack_ie_ts_delay(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint8_t ielen,
+				  tDot11fIETSDelay *pDst,
+				  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->delay, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ts_delay. */
+
+#define SigIeTSDelay (0x0014)
+
+
+uint32_t dot11f_unpack_ie_tsf_info(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint8_t ielen,
+				  tDot11fIETSFInfo *pDst,
+				  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->TsfOffset, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->BeaconIntvl, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_tsf_info. */
+
+#define SigIeTSFInfo (0x0015)
+
+
+uint32_t dot11f_unpack_ie_tspec(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIETSPEC *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint16_t tmp19__;
+	uint8_t tmp20__;
+	uint16_t tmp21__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp19__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->traffic_type = tmp19__ >> 0 & 0x1;
+	pDst->tsid = tmp19__ >> 1 & 0xf;
+	pDst->direction = tmp19__ >> 5 & 0x3;
+	pDst->access_policy = tmp19__ >> 7 & 0x3;
+	pDst->aggregation = tmp19__ >> 9 & 0x1;
+	pDst->psb = tmp19__ >> 10 & 0x1;
+	pDst->user_priority = tmp19__ >> 11 & 0x7;
+	pDst->tsinfo_ack_pol = tmp19__ >> 14 & 0x3;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp20__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->schedule = tmp20__ >> 0 & 0x1;
+	pDst->unused = tmp20__ >> 1 & 0x7f;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp21__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->size = tmp21__ >> 0 & 0x7fff;
+	pDst->fixed = tmp21__ >> 15 & 0x1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->min_service_int, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->max_service_int, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->suspension_int, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->burst_size, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->delay_bound, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->medium_time, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_tspec. */
+
+#define SigIeTSPEC (0x0016)
+
+
+uint32_t dot11f_unpack_ie_vht_caps(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint8_t ielen,
+				  tDot11fIEVHTCaps *pDst,
+				  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t tmp22__;
+	uint16_t tmp23__;
+	uint16_t tmp24__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &tmp22__, pBuf, 0);
+	pBuf += 4;
+	ielen -= 4;
+	pDst->maxMPDULen = tmp22__ >> 0 & 0x3;
+	pDst->supportedChannelWidthSet = tmp22__ >> 2 & 0x3;
+	pDst->ldpcCodingCap = tmp22__ >> 4 & 0x1;
+	pDst->shortGI80MHz = tmp22__ >> 5 & 0x1;
+	pDst->shortGI160and80plus80MHz = tmp22__ >> 6 & 0x1;
+	pDst->txSTBC = tmp22__ >> 7 & 0x1;
+	pDst->rxSTBC = tmp22__ >> 8 & 0x7;
+	pDst->suBeamFormerCap = tmp22__ >> 11 & 0x1;
+	pDst->suBeamformeeCap = tmp22__ >> 12 & 0x1;
+	pDst->csnofBeamformerAntSup = tmp22__ >> 13 & 0x7;
+	pDst->numSoundingDim = tmp22__ >> 16 & 0x7;
+	pDst->muBeamformerCap = tmp22__ >> 19 & 0x1;
+	pDst->muBeamformeeCap = tmp22__ >> 20 & 0x1;
+	pDst->vhtTXOPPS = tmp22__ >> 21 & 0x1;
+	pDst->htcVHTCap = tmp22__ >> 22 & 0x1;
+	pDst->maxAMPDULenExp = tmp22__ >> 23 & 0x7;
+	pDst->vhtLinkAdaptCap = tmp22__ >> 26 & 0x3;
+	pDst->rxAntPattern = tmp22__ >> 28 & 0x1;
+	pDst->txAntPattern = tmp22__ >> 29 & 0x1;
+	pDst->reserved1 = tmp22__ >> 30 & 0x3;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->rxMCSMap, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp23__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->rxHighSupDataRate = tmp23__ >> 0 & 0x1fff;
+	pDst->reserved2 = tmp23__ >> 13 & 0x7;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->txMCSMap, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp24__, pBuf, 0);
+	pDst->txSupDataRate = tmp24__ >> 0 & 0x1fff;
+	pDst->reserved3 = tmp24__ >> 13 & 0x7;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_vht_caps. */
+
+#define SigIeVHTCaps (0x0017)
+
+
+uint32_t dot11f_unpack_ie_vht_operation(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint8_t ielen,
+				       tDot11fIEVHTOperation *pDst,
+				       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->chanWidth = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->chanCenterFreqSeg1 = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->chanCenterFreqSeg2 = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->basicMCSSet, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_vht_operation. */
+
+#define SigIeVHTOperation (0x0018)
+
+
+uint32_t dot11f_unpack_ie_wmm_schedule(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEWMMSchedule *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint16_t tmp25__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->version = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (pDst->version != 0x1) {
+		pDst->present = 0;
+		return status | DOT11F_BAD_FIXED_VALUE;
+	}
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp25__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->aggregation = tmp25__ >> 0 & 0x1;
+	pDst->tsid = tmp25__ >> 1 & 0xf;
+	pDst->direction = tmp25__ >> 5 & 0x3;
+	pDst->reserved = tmp25__ >> 7 & 0x1ff;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->service_interval, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->spec_interval, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wmm_schedule. */
+
+#define SigIeWMMSchedule (0x0019)
+
+
+uint32_t dot11f_unpack_ie_wmmtclas(tpAniSirGlobal pCtx,
+				   uint8_t *pBuf,
+				   uint8_t ielen,
+				   tDot11fIEWMMTCLAS *pDst,
+				   bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->version = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (pDst->version != 0x1) {
+		pDst->present = 0;
+		return status | DOT11F_BAD_FIXED_VALUE;
+	}
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->user_priority = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->classifier_type = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->classifier_mask = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	switch (pDst->classifier_type) {
+	case 0:
+		if (unlikely(ielen < 6)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6);
+		pBuf += 6;
+		ielen -= (uint8_t)6;
+		if (unlikely(ielen < 6)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6);
+		pBuf += 6;
+		ielen -= (uint8_t)6;
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+		break;
+	case 1:
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->info.IpParams.version = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		switch (pDst->info.IpParams.version) {
+		case 4:
+			if (unlikely(ielen < 4)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4);
+			pBuf += 4;
+			ielen -= (uint8_t)4;
+			if (unlikely(ielen < 4)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4);
+			pBuf += 4;
+			ielen -= (uint8_t)4;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->info.IpParams.params.IpV4Params.proto = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->info.IpParams.params.IpV4Params.reserved = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			break;
+		case 6:
+			if (unlikely(ielen < 16)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16);
+			pBuf += 16;
+			ielen -= (uint8_t)16;
+			if (unlikely(ielen < 16)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16);
+			pBuf += 16;
+			ielen -= (uint8_t)16;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 3)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3);
+			pBuf += 3;
+			ielen -= (uint8_t)3;
+			break;
+		}
+		break;
+	case 2:
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+		break;
+	}
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wmmtclas. */
+
+#define SigIeWMMTCLAS (0x001a)
+
+
+uint32_t dot11f_unpack_ie_wmmtclasproc(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint8_t ielen,
+				       tDot11fIEWMMTCLASPROC *pDst,
+				       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->version = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (pDst->version != 0x1) {
+		pDst->present = 0;
+		return status | DOT11F_BAD_FIXED_VALUE;
+	}
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->processing = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wmmtclasproc. */
+
+#define SigIeWMMTCLASPROC (0x001b)
+
+
+uint32_t dot11f_unpack_ie_wmmts_delay(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     uint8_t ielen,
+				     tDot11fIEWMMTSDelay *pDst,
+				     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->version = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (pDst->version != 0x1) {
+		pDst->present = 0;
+		return status | DOT11F_BAD_FIXED_VALUE;
+	}
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->delay, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wmmts_delay. */
+
+#define SigIeWMMTSDelay (0x001c)
+
+
+uint32_t dot11f_unpack_ie_wmmtspec(tpAniSirGlobal pCtx,
+				   uint8_t *pBuf,
+				   uint8_t ielen,
+				   tDot11fIEWMMTSPEC *pDst,
+				   bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint16_t tmp26__;
+	uint8_t tmp27__;
+	uint16_t tmp28__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->version = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (pDst->version != 0x1) {
+		pDst->present = 0;
+		return status | DOT11F_BAD_FIXED_VALUE;
+	}
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp26__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->traffic_type = tmp26__ >> 0 & 0x1;
+	pDst->tsid = tmp26__ >> 1 & 0xf;
+	pDst->direction = tmp26__ >> 5 & 0x3;
+	pDst->access_policy = tmp26__ >> 7 & 0x3;
+	pDst->aggregation = tmp26__ >> 9 & 0x1;
+	pDst->psb = tmp26__ >> 10 & 0x1;
+	pDst->user_priority = tmp26__ >> 11 & 0x7;
+	pDst->tsinfo_ack_pol = tmp26__ >> 14 & 0x3;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp27__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->tsinfo_rsvd = tmp27__ >> 0 & 0x7f;
+	pDst->burst_size_defn = tmp27__ >> 7 & 0x1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp28__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->size = tmp28__ >> 0 & 0x7fff;
+	pDst->fixed = tmp28__ >> 15 & 0x1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->min_service_int, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->max_service_int, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->suspension_int, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->burst_size, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->delay_bound, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->medium_time, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wmmtspec. */
+
+#define SigIeWMMTSPEC (0x001d)
+
+
+uint32_t dot11f_unpack_ie_wider_bw_chan_switch_ann(tpAniSirGlobal pCtx,
+					       uint8_t *pBuf,
+					       uint8_t ielen,
+					       tDot11fIEWiderBWChanSwitchAnn *pDst,
+					       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->newChanWidth = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->newCenterChanFreq0 = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->newCenterChanFreq1 = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wider_bw_chan_switch_ann. */
+
+#define SigIeWiderBWChanSwitchAnn (0x001e)
+
+
+uint32_t dot11f_unpack_ie_azimuth_req(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEazimuth_req *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->request = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_azimuth_req. */
+
+#define SigIeazimuth_req (0x001f)
+
+
+uint32_t dot11f_unpack_ie_beacon_report_frm_body_fragment_id(tpAniSirGlobal pCtx,
+							     uint8_t *pBuf,
+							     uint8_t ielen,
+							     tDot11fIEbeacon_report_frm_body_fragment_id *pDst,
+							     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint16_t tmp29__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp29__, pBuf, 0);
+	pDst->beacon_report_id = tmp29__ >> 0 & 0xff;
+	pDst->fragment_id_number = tmp29__ >> 8 & 0x7f;
+	pDst->more_fragments = tmp29__ >> 15 & 0x1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_beacon_report_frm_body_fragment_id. */
+
+#define SigIebeacon_report_frm_body_fragment_id (0x0020)
+
+
+uint32_t dot11f_unpack_ie_last_beacon_report_indication(tpAniSirGlobal pCtx,
+							 uint8_t *pBuf,
+							 uint8_t ielen,
+							 tDot11fIElast_beacon_report_indication *pDst,
+							 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->last_fragment = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_last_beacon_report_indication. */
+
+#define SigIelast_beacon_report_indication (0x0021)
+
+
+uint32_t dot11f_unpack_ie_max_age(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint8_t ielen,
+				  tDot11fIEmax_age *pDst,
+				  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->max_age, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_max_age. */
+
+#define SigIemax_age (0x0022)
+
+
+static const tFFDefn FFS_neighbor_rpt[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_neighbor_rpt[] = {
+	{ offsetof(tDot11fIEneighbor_rpt, TSFInfo), offsetof(tDot11fIETSFInfo,
+	present), 0, "TSFInfo", 0, 6, 6, SigIeTSFInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TSFINFO, 0, 0, },
+	{ offsetof(tDot11fIEneighbor_rpt, CondensedCountryStr),
+	offsetof(tDot11fIECondensedCountryStr, present), 0, "CondensedCountryStr",
+	0, 4, 4, SigIeCondensedCountryStr, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_CONDENSEDCOUNTRYSTR, 0, 0, },
+	{ offsetof(tDot11fIEneighbor_rpt, MeasurementPilot),
+	offsetof(tDot11fIEMeasurementPilot, present), 0, "MeasurementPilot",
+	0, 3, 258, SigIeMeasurementPilot, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MEASUREMENTPILOT, 0, 0, },
+	{ offsetof(tDot11fIEneighbor_rpt, RRMEnabledCap),
+	offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+	0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RRMENABLEDCAP, 0, 0, },
+	{ offsetof(tDot11fIEneighbor_rpt, MultiBssid),
+	offsetof(tDot11fIEMultiBssid, present), 0, "MultiBssid",
+	0, 3, 258, SigIeMultiBssid, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MULTIBSSID, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_neighbor_rpt(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint8_t ielen,
+				       tDot11fIEneighbor_rpt *pDst,
+				       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp30__;
+	uint8_t tmp31__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6);
+	pBuf += 6;
+	ielen -= (uint8_t)6;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp30__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->APReachability = tmp30__ >> 0 & 0x3;
+	pDst->Security = tmp30__ >> 2 & 0x1;
+	pDst->KeyScope = tmp30__ >> 3 & 0x1;
+	pDst->SpecMgmtCap = tmp30__ >> 4 & 0x1;
+	pDst->QosCap = tmp30__ >> 5 & 0x1;
+	pDst->apsd = tmp30__ >> 6 & 0x1;
+	pDst->rrm = tmp30__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp31__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->DelayedBA = tmp31__ >> 0 & 0x1;
+	pDst->ImmBA = tmp31__ >> 1 & 0x1;
+	pDst->MobilityDomain = tmp31__ >> 2 & 0x1;
+	pDst->reserved = tmp31__ >> 3 & 0x1f;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->reserved1, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->regulatoryClass = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->channel = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->PhyType = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	(void)pCtx;
+	status |= unpack_core(pCtx,
+				pBuf,
+				ielen,
+				FFS_neighbor_rpt,
+				IES_neighbor_rpt,
+				(uint8_t *)pDst,
+				sizeof(*pDst),
+				append_ie);
+	return status;
+} /* End dot11f_unpack_ie_neighbor_rpt. */
+
+#define SigIeneighbor_rpt (0x0023)
+
+
+uint32_t dot11f_unpack_ie_req_mac_addr(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint8_t ielen,
+				       tDot11fIEreq_mac_addr *pDst,
+				       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->addr, pBuf, 6);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_req_mac_addr. */
+
+#define SigIereq_mac_addr (0x0024)
+
+
+uint32_t dot11f_unpack_ie_tgt_mac_addr(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint8_t ielen,
+				       tDot11fIEtgt_mac_addr *pDst,
+				       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->addr, pBuf, 6);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_tgt_mac_addr. */
+
+#define SigIetgt_mac_addr (0x0025)
+
+
+uint32_t dot11f_unpack_ie_vht_transmit_power_env(tpAniSirGlobal pCtx,
+						 uint8_t *pBuf,
+						 uint8_t ielen,
+						 tDot11fIEvht_transmit_power_env *pDst,
+						 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_bytes = (uint8_t)(ielen);
+	if (ielen > 5) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->bytes, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_vht_transmit_power_env. */
+
+#define SigIevht_transmit_power_env (0x0026)
+
+
+uint32_t dot11f_unpack_ie_aid(tpAniSirGlobal pCtx,
+			      uint8_t *pBuf,
+			      uint8_t ielen,
+			      tDot11fIEAID *pDst,
+			      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->assocId, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_aid. */
+
+#define SigIeAID (0x0027)
+
+
+uint32_t dot11f_unpack_ie_cf_params(tpAniSirGlobal pCtx,
+				   uint8_t *pBuf,
+				   uint8_t ielen,
+				   tDot11fIECFParams *pDst,
+				   bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->cfp_count = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->cfp_period = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->cfp_maxduration, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->cfp_durremaining, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_cf_params. */
+
+#define SigIeCFParams (0x0028)
+
+
+uint32_t dot11f_unpack_ie_challenge_text(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEChallengeText *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_text = (uint8_t)(ielen);
+	if (ielen > 253) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->text, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_challenge_text. */
+
+#define SigIeChallengeText (0x0029)
+
+
+uint32_t dot11f_unpack_ie_chan_switch_ann(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEChanSwitchAnn *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->switchMode = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->newChannel = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->switchCount = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_chan_switch_ann. */
+
+#define SigIeChanSwitchAnn (0x002a)
+
+
+static const tFFDefn FFS_ChannelSwitchWrapper[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ChannelSwitchWrapper[] = {
+	{ offsetof(tDot11fIEChannelSwitchWrapper, WiderBWChanSwitchAnn),
+	offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0,
+	"WiderBWChanSwitchAnn", 0, 5, 5, SigIeWiderBWChanSwitchAnn,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, 0, },
+	{ offsetof(tDot11fIEChannelSwitchWrapper, vht_transmit_power_env),
+	offsetof(tDot11fIEvht_transmit_power_env, present), 0,
+	"vht_transmit_power_env", 0, 4, 7, SigIevht_transmit_power_env,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_VHT_TRANSMIT_POWER_ENV, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_channel_switch_wrapper(tpAniSirGlobal pCtx,
+					       uint8_t *pBuf,
+					       uint8_t ielen,
+					       tDot11fIEChannelSwitchWrapper *pDst,
+					       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	(void)pCtx;
+	status |= unpack_core(pCtx,
+				pBuf,
+				ielen,
+				FFS_ChannelSwitchWrapper,
+				IES_ChannelSwitchWrapper,
+				(uint8_t *)pDst,
+				sizeof(*pDst),
+				append_ie);
+	return status;
+} /* End dot11f_unpack_ie_channel_switch_wrapper. */
+
+#define SigIeChannelSwitchWrapper (0x002b)
+
+
+uint32_t dot11f_unpack_ie_country(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint8_t ielen,
+				  tDot11fIECountry *pDst,
+				  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 3)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->country, pBuf, 3);
+	pBuf += 3;
+	ielen -= (uint8_t)3;
+	if (!ielen) {
+		pDst->num_triplets = 0U;
+		return 0U;
+	} else {
+		pDst->num_triplets = (uint8_t)(ielen / 3);
+		if (ielen > 84 * 3) {
+				pDst->present = 0;
+				return DOT11F_SKIPPED_BAD_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->triplets, pBuf, (ielen));
+	}
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_country. */
+
+#define SigIeCountry (0x002c)
+
+
+#define SigIeDSParams (0x002d)
+
+
+uint32_t dot11f_unpack_ie_edca_param_set(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint8_t ielen,
+				       tDot11fIEEDCAParamSet *pDst,
+				       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp32__;
+	uint8_t tmp33__;
+	uint8_t tmp34__;
+	uint8_t tmp35__;
+	uint8_t tmp36__;
+	uint8_t tmp37__;
+	uint8_t tmp38__;
+	uint8_t tmp39__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->qos = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->reserved = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp32__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbe_aifsn = tmp32__ >> 0 & 0xf;
+	pDst->acbe_acm = tmp32__ >> 4 & 0x1;
+	pDst->acbe_aci = tmp32__ >> 5 & 0x3;
+	pDst->unused1 = tmp32__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp33__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbe_acwmin = tmp33__ >> 0 & 0xf;
+	pDst->acbe_acwmax = tmp33__ >> 4 & 0xf;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp34__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbk_aifsn = tmp34__ >> 0 & 0xf;
+	pDst->acbk_acm = tmp34__ >> 4 & 0x1;
+	pDst->acbk_aci = tmp34__ >> 5 & 0x3;
+	pDst->unused2 = tmp34__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp35__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbk_acwmin = tmp35__ >> 0 & 0xf;
+	pDst->acbk_acwmax = tmp35__ >> 4 & 0xf;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp36__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvi_aifsn = tmp36__ >> 0 & 0xf;
+	pDst->acvi_acm = tmp36__ >> 4 & 0x1;
+	pDst->acvi_aci = tmp36__ >> 5 & 0x3;
+	pDst->unused3 = tmp36__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp37__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvi_acwmin = tmp37__ >> 0 & 0xf;
+	pDst->acvi_acwmax = tmp37__ >> 4 & 0xf;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp38__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvo_aifsn = tmp38__ >> 0 & 0xf;
+	pDst->acvo_acm = tmp38__ >> 4 & 0x1;
+	pDst->acvo_aci = tmp38__ >> 5 & 0x3;
+	pDst->unused4 = tmp38__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp39__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvo_acwmin = tmp39__ >> 0 & 0xf;
+	pDst->acvo_acwmax = tmp39__ >> 4 & 0xf;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_edca_param_set. */
+
+#define SigIeEDCAParamSet (0x002e)
+
+
+uint32_t dot11f_unpack_ie_erp_info(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint8_t ielen,
+				  tDot11fIEERPInfo *pDst,
+				  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp40__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp40__ = *pBuf;
+	pDst->non_erp_present = tmp40__ >> 0 & 0x1;
+	pDst->use_prot = tmp40__ >> 1 & 0x1;
+	pDst->barker_preamble = tmp40__ >> 2 & 0x1;
+	pDst->unused = tmp40__ >> 3 & 0x1f;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_erp_info. */
+
+#define SigIeERPInfo (0x002f)
+
+
+uint32_t dot11f_unpack_ie_ese_cckm_opaque(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEESECckmOpaque *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_data = (uint8_t)(ielen);
+	if (ielen > 20) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ese_cckm_opaque. */
+
+#define SigIeESECckmOpaque (0x0030)
+
+
+uint32_t dot11f_unpack_ie_ese_rad_mgmt_cap(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEESERadMgmtCap *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp41__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->mgmt_state = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp41__ = *pBuf;
+	pDst->mbssid_mask = tmp41__ >> 0 & 0x7;
+	pDst->reserved = tmp41__ >> 3 & 0x1f;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ese_rad_mgmt_cap. */
+
+#define SigIeESERadMgmtCap (0x0031)
+
+
+uint32_t dot11f_unpack_ie_ese_traf_strm_met(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEESETrafStrmMet *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->tsid = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->state = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->msmt_interval, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ese_traf_strm_met. */
+
+#define SigIeESETrafStrmMet (0x0032)
+
+
+uint32_t dot11f_unpack_ie_ese_traf_strm_rate_set(tpAniSirGlobal pCtx,
+					     uint8_t *pBuf,
+					     uint8_t ielen,
+					     tDot11fIEESETrafStrmRateSet *pDst,
+					     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->tsid = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	pDst->num_tsrates = (uint8_t)(ielen);
+	if (ielen > 8) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->tsrates, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ese_traf_strm_rate_set. */
+
+#define SigIeESETrafStrmRateSet (0x0033)
+
+
+uint32_t dot11f_unpack_ie_ese_txmit_power(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEESETxmitPower *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->power_limit = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->reserved = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ese_txmit_power. */
+
+#define SigIeESETxmitPower (0x0034)
+
+
+uint32_t dot11f_unpack_ie_ese_version(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     uint8_t ielen,
+				     tDot11fIEESEVersion *pDst,
+				     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->version = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ese_version. */
+
+#define SigIeESEVersion (0x0035)
+
+
+uint32_t dot11f_unpack_ie_ext_cap(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIEExtCap *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+
+	if (!ielen) /* Check to ensure copying of ielen bytes */
+		goto endUnpackIeExtCap;
+	pDst->num_bytes = (uint8_t)(ielen);
+	if (ielen > 15) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->bytes, pBuf, (ielen));
+
+endUnpackIeExtCap:
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ext_cap. */
+
+#define SigIeExtCap (0x0036)
+
+
+uint32_t dot11f_unpack_ie_ext_supp_rates(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint8_t ielen,
+				       tDot11fIEExtSuppRates *pDst,
+				       bool append_ie)
+{
+	uint8_t i;
+	uint8_t rate_indx = 0;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	for (i = 0; i < ielen; i++) {
+		if ((DOT11F_IS_BG_RATE(pBuf[i] & 0x7F)) &&
+			(rate_indx < 12)) {
+			pDst->rates[rate_indx++] = pBuf[i];
+		}
+	}
+
+	if (rate_indx == 0) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	pDst->num_rates = rate_indx;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ext_supp_rates. */
+
+#define SigIeExtSuppRates (0x0037)
+
+
+uint32_t dot11f_unpack_ie_fh_param_set(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     uint8_t ielen,
+				     tDot11fIEFHParamSet *pDst,
+				     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->dwell_time, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->hop_set = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->hop_pattern = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->hop_index = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fh_param_set. */
+
+#define SigIeFHParamSet (0x0038)
+
+
+uint32_t dot11f_unpack_ie_fh_params(tpAniSirGlobal pCtx,
+				   uint8_t *pBuf,
+				   uint8_t ielen,
+				   tDot11fIEFHParams *pDst,
+				   bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->radix = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->nchannels = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fh_params. */
+
+#define SigIeFHParams (0x0039)
+
+
+uint32_t dot11f_unpack_ie_fh_patt_table(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEFHPattTable *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->flag = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->nsets = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->modulus = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->offset = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	pDst->num_randtable = (uint8_t)(ielen);
+	if (ielen > 251) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->randtable, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fh_patt_table. */
+
+#define SigIeFHPattTable (0x003a)
+
+
+static const tFFDefn FFS_FTInfo[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_FTInfo[] = {
+	{ offsetof(tDot11fIEFTInfo, R1KH_ID), offsetof(tDot11fIER1KH_ID, present),
+	0, "R1KH_ID", 0, 8, 8, SigIeR1KH_ID, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_R1KH_ID, 0, 0, },
+	{ offsetof(tDot11fIEFTInfo, GTK), offsetof(tDot11fIEGTK, present), 0, "GTK",
+	0, 18, 45, SigIeGTK, {0, 0, 0, 0, 0}, 0, DOT11F_EID_GTK, 0, 0, },
+	{ offsetof(tDot11fIEFTInfo, R0KH_ID), offsetof(tDot11fIER0KH_ID, present),
+	0, "R0KH_ID", 0, 3, 50, SigIeR0KH_ID, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_R0KH_ID, 0, 0, },
+	{ offsetof(tDot11fIEFTInfo, IGTK), offsetof(tDot11fIEIGTK, present), 0,
+	"IGTK", 0, 35, 35, SigIeIGTK, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_IGTK, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_ft_info(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIEFTInfo *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint16_t tmp42__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp42__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->reserved = tmp42__ >> 0 & 0xff;
+	pDst->IECount = tmp42__ >> 8 & 0xff;
+	if (unlikely(ielen < 16)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->MIC, pBuf, 16);
+	pBuf += 16;
+	ielen -= (uint8_t)16;
+	if (unlikely(ielen < 32)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->Anonce, pBuf, 32);
+	pBuf += 32;
+	ielen -= (uint8_t)32;
+	if (unlikely(ielen < 32)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->Snonce, pBuf, 32);
+	pBuf += 32;
+	ielen -= (uint8_t)32;
+	(void)pCtx;
+	status |= unpack_core(pCtx,
+				pBuf,
+				ielen,
+				FFS_FTInfo,
+				IES_FTInfo,
+				(uint8_t *)pDst,
+				sizeof(*pDst),
+				append_ie);
+	return status;
+} /* End dot11f_unpack_ie_ft_info. */
+
+#define SigIeFTInfo (0x003b)
+
+
+uint32_t dot11f_unpack_ie_ht_caps(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIEHTCaps *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint16_t tmp43__;
+	uint8_t tmp44__;
+	uint16_t tmp45__;
+	uint32_t tmp46__;
+	uint8_t tmp47__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp43__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->advCodingCap = tmp43__ >> 0 & 0x1;
+	pDst->supportedChannelWidthSet = tmp43__ >> 1 & 0x1;
+	pDst->mimoPowerSave = tmp43__ >> 2 & 0x3;
+	pDst->greenField = tmp43__ >> 4 & 0x1;
+	pDst->shortGI20MHz = tmp43__ >> 5 & 0x1;
+	pDst->shortGI40MHz = tmp43__ >> 6 & 0x1;
+	pDst->txSTBC = tmp43__ >> 7 & 0x1;
+	pDst->rxSTBC = tmp43__ >> 8 & 0x3;
+	pDst->delayedBA = tmp43__ >> 10 & 0x1;
+	pDst->maximalAMSDUsize = tmp43__ >> 11 & 0x1;
+	pDst->dsssCckMode40MHz = tmp43__ >> 12 & 0x1;
+	pDst->psmp = tmp43__ >> 13 & 0x1;
+	pDst->stbcControlFrame = tmp43__ >> 14 & 0x1;
+	pDst->lsigTXOPProtection = tmp43__ >> 15 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp44__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->maxRxAMPDUFactor = tmp44__ >> 0 & 0x3;
+	pDst->mpduDensity = tmp44__ >> 2 & 0x7;
+	pDst->reserved1 = tmp44__ >> 5 & 0x7;
+	if (unlikely(ielen < 16)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->supportedMCSSet, pBuf, 16);
+	pBuf += 16;
+	ielen -= (uint8_t)16;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp45__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->pco = tmp45__ >> 0 & 0x1;
+	pDst->transitionTime = tmp45__ >> 1 & 0x3;
+	pDst->reserved2 = tmp45__ >> 3 & 0x1f;
+	pDst->mcsFeedback = tmp45__ >> 8 & 0x3;
+	pDst->reserved3 = tmp45__ >> 10 & 0x3f;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &tmp46__, pBuf, 0);
+	pBuf += 4;
+	ielen -= 4;
+	pDst->txBF = tmp46__ >> 0 & 0x1;
+	pDst->rxStaggeredSounding = tmp46__ >> 1 & 0x1;
+	pDst->txStaggeredSounding = tmp46__ >> 2 & 0x1;
+	pDst->rxZLF = tmp46__ >> 3 & 0x1;
+	pDst->txZLF = tmp46__ >> 4 & 0x1;
+	pDst->implicitTxBF = tmp46__ >> 5 & 0x1;
+	pDst->calibration = tmp46__ >> 6 & 0x3;
+	pDst->explicitCSITxBF = tmp46__ >> 8 & 0x1;
+	pDst->explicitUncompressedSteeringMatrix = tmp46__ >> 9 & 0x1;
+	pDst->explicitBFCSIFeedback = tmp46__ >> 10 & 0x7;
+	pDst->explicitUncompressedSteeringMatrixFeedback = tmp46__ >> 13 & 0x7;
+	pDst->explicitCompressedSteeringMatrixFeedback = tmp46__ >> 16 & 0x7;
+	pDst->csiNumBFAntennae = tmp46__ >> 19 & 0x3;
+	pDst->uncompressedSteeringMatrixBFAntennae = tmp46__ >> 21 & 0x3;
+	pDst->compressedSteeringMatrixBFAntennae = tmp46__ >> 23 & 0x3;
+	pDst->reserved4 = tmp46__ >> 25 & 0x7f;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp47__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->antennaSelection = tmp47__ >> 0 & 0x1;
+	pDst->explicitCSIFeedbackTx = tmp47__ >> 1 & 0x1;
+	pDst->antennaIndicesFeedbackTx = tmp47__ >> 2 & 0x1;
+	pDst->explicitCSIFeedback = tmp47__ >> 3 & 0x1;
+	pDst->antennaIndicesFeedback = tmp47__ >> 4 & 0x1;
+	pDst->rxAS = tmp47__ >> 5 & 0x1;
+	pDst->txSoundingPPDUs = tmp47__ >> 6 & 0x1;
+	pDst->reserved5 = tmp47__ >> 7 & 0x1;
+	pDst->num_rsvd = (uint8_t)(ielen);
+	if (ielen > 32) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->rsvd, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ht_caps. */
+
+#define SigIeHTCaps (0x003c)
+
+
+uint32_t dot11f_unpack_ie_ht_info(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIEHTInfo *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp48__;
+	uint16_t tmp49__;
+	uint16_t tmp50__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->primaryChannel = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp48__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->secondaryChannelOffset = tmp48__ >> 0 & 0x3;
+	pDst->recommendedTxWidthSet = tmp48__ >> 2 & 0x1;
+	pDst->rifsMode = tmp48__ >> 3 & 0x1;
+	pDst->controlledAccessOnly = tmp48__ >> 4 & 0x1;
+	pDst->serviceIntervalGranularity = tmp48__ >> 5 & 0x7;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp49__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->opMode = tmp49__ >> 0 & 0x3;
+	pDst->nonGFDevicesPresent = tmp49__ >> 2 & 0x1;
+	pDst->transmitBurstLimit = tmp49__ >> 3 & 0x1;
+	pDst->obssNonHTStaPresent = tmp49__ >> 4 & 0x1;
+	pDst->reserved = tmp49__ >> 5 & 0x7ff;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp50__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->basicSTBCMCS = tmp50__ >> 0 & 0x7f;
+	pDst->dualCTSProtection = tmp50__ >> 7 & 0x1;
+	pDst->secondaryBeacon = tmp50__ >> 8 & 0x1;
+	pDst->lsigTXOPProtectionFullSupport = tmp50__ >> 9 & 0x1;
+	pDst->pcoActive = tmp50__ >> 10 & 0x1;
+	pDst->pcoPhase = tmp50__ >> 11 & 0x1;
+	pDst->reserved2 = tmp50__ >> 12 & 0xf;
+	if (unlikely(ielen < 16)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->basicMCSSet, pBuf, 16);
+	pBuf += 16;
+	ielen -= (uint8_t)16;
+	pDst->num_rsvd = (uint8_t)(ielen);
+	if (ielen > 32) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->rsvd, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ht_info. */
+
+#define SigIeHTInfo (0x003d)
+
+
+uint32_t dot11f_unpack_ie_ibss_params(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     uint8_t ielen,
+				     tDot11fIEIBSSParams *pDst,
+				     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->atim, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ibss_params. */
+
+#define SigIeIBSSParams (0x003e)
+
+
+uint32_t dot11f_unpack_ie_link_identifier(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIELinkIdentifier *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6);
+	pBuf += 6;
+	ielen -= (uint8_t)6;
+	if (unlikely(ielen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->InitStaAddr, pBuf, 6);
+	pBuf += 6;
+	ielen -= (uint8_t)6;
+	if (unlikely(ielen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->RespStaAddr, pBuf, 6);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_link_identifier. */
+
+#define SigIeLinkIdentifier (0x003f)
+
+
+static const tTLVDefn TLVS_MBO_IE[] = {
+	{ offsetof(tDot11fIEMBO_IE, mbo_ap_cap), offsetof(tDot11fTLVmbo_ap_cap,
+	present), "mbo_ap_cap", SigTlvmbo_ap_cap, DOT11F_TLV_MBO_AP_CAP,
+	0, 3, 3, 0, 1, 1, 0, },
+	{ offsetof(tDot11fIEMBO_IE, non_prefferd_chan_rep),
+	offsetof(tDot11fTLVnon_prefferd_chan_rep, present),
+	"non_prefferd_chan_rep", SigTlvnon_prefferd_chan_rep,
+	DOT11F_TLV_NON_PREFFERD_CHAN_REP, 0, 6, 257, 0, 1, 1, 0, },
+	{ offsetof(tDot11fIEMBO_IE, cellular_data_cap),
+	offsetof(tDot11fTLVcellular_data_cap, present), "cellular_data_cap",
+	SigTlvcellular_data_cap, DOT11F_TLV_CELLULAR_DATA_CAP,
+	0, 3, 3, 0, 1, 1, 0, },
+	{ offsetof(tDot11fIEMBO_IE, assoc_disallowed),
+	offsetof(tDot11fTLVassoc_disallowed, present), "assoc_disallowed",
+	SigTlvassoc_disallowed, DOT11F_TLV_ASSOC_DISALLOWED,
+	0, 3, 3, 0, 1, 1, 0, },
+	{ offsetof(tDot11fIEMBO_IE, cellular_data_con_pref),
+	offsetof(tDot11fTLVcellular_data_con_pref, present),
+	"cellular_data_con_pref", SigTlvcellular_data_con_pref,
+	DOT11F_TLV_CELLULAR_DATA_CON_PREF, 0, 3, 3, 0, 1, 1, 0, },
+	{ offsetof(tDot11fIEMBO_IE, transition_reason),
+	offsetof(tDot11fTLVtransition_reason, present), "transition_reason",
+	SigTlvtransition_reason, DOT11F_TLV_TRANSITION_REASON,
+	0, 3, 3, 0, 1, 1, 0, },
+	{ offsetof(tDot11fIEMBO_IE, transition_reject_reason),
+	offsetof(tDot11fTLVtransition_reject_reason, present),
+	"transition_reject_reason", SigTlvtransition_reject_reason,
+	DOT11F_TLV_TRANSITION_REJECT_REASON, 0, 3, 3, 0, 1, 1, 0, },
+	{ offsetof(tDot11fIEMBO_IE, assoc_retry_delay),
+	offsetof(tDot11fTLVassoc_retry_delay, present), "assoc_retry_delay",
+	SigTlvassoc_retry_delay, DOT11F_TLV_ASSOC_RETRY_DELAY,
+	0, 4, 4, 0, 1, 1, 0, },
+	{ offsetof(tDot11fIEMBO_IE, oce_cap), offsetof(tDot11fTLVoce_cap,
+	present), "oce_cap", SigTlvoce_cap, DOT11F_TLV_OCE_CAP,
+	0, 3, 3, 0, 1, 1, 0, },
+	{ offsetof(tDot11fIEMBO_IE, rssi_assoc_rej),
+	offsetof(tDot11fTLVrssi_assoc_rej, present), "rssi_assoc_rej",
+	SigTlvrssi_assoc_rej, DOT11F_TLV_RSSI_ASSOC_REJ, 0, 4, 4, 0, 1, 1, 0, },
+	{ offsetof(tDot11fIEMBO_IE, reduced_wan_metrics),
+	offsetof(tDot11fTLVreduced_wan_metrics, present), "reduced_wan_metrics",
+	SigTlvreduced_wan_metrics, DOT11F_TLV_REDUCED_WAN_METRICS,
+	0, 3, 3, 0, 1, 1, 0, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_MBO_IE(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIEMBO_IE *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_MBO_IE,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_MBO_IE. */
+
+#define SigIeMBO_IE (0x0040)
+
+
+static const tFFDefn FFS_reportBeacon[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_reportBeacon[] = {
+	{ offsetof(tDot11fIEMeasurementReport,
+	report.Beacon.BeaconReportFrmBody),
+	offsetof(tDot11fIEBeaconReportFrmBody, present), 0, "BeaconReportFrmBody",
+	0, 2, 226, SigIeBeaconReportFrmBody, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_BEACONREPORTFRMBODY, 0, 0, },
+	{ offsetof(tDot11fIEMeasurementReport,
+	report.Beacon.beacon_report_frm_body_fragment_id),
+	offsetof(tDot11fIEbeacon_report_frm_body_fragment_id, present), 0,
+	"beacon_report_frm_body_fragment_id",
+	0, 4, 4, SigIebeacon_report_frm_body_fragment_id, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_BEACON_REPORT_FRM_BODY_FRAGMENT_ID, 0, 0, },
+	{ offsetof(tDot11fIEMeasurementReport,
+	report.Beacon.last_beacon_report_indication),
+	offsetof(tDot11fIElast_beacon_report_indication, present), 0,
+	"last_beacon_report_indication",
+	0, 3, 3, SigIelast_beacon_report_indication, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_LAST_BEACON_REPORT_INDICATION, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_measurement_report(tpAniSirGlobal pCtx,
+					    uint8_t *pBuf,
+					    uint8_t ielen,
+					    tDot11fIEMeasurementReport *pDst,
+					    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp51__;
+	uint8_t tmp52__;
+	uint8_t tmp53__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->token = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp51__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->late = tmp51__ >> 0 & 0x1;
+	pDst->incapable = tmp51__ >> 1 & 0x1;
+	pDst->refused = tmp51__ >> 2 & 0x1;
+	pDst->unused = tmp51__ >> 3 & 0x1f;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->type = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (!ielen) {
+		return 0U;
+	} else {
+		switch (pDst->type) {
+		case 0:
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.Basic.channel = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 8)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohq(pCtx, &pDst->report.Basic.meas_start_time, pBuf, 0);
+			pBuf += 8;
+			ielen -= (uint8_t)8;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->report.Basic.meas_duration, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			tmp52__ = *pBuf;
+			pBuf += 1;
+			ielen -= 1;
+			pDst->report.Basic.bss = tmp52__ >> 0 & 0x1;
+			pDst->report.Basic.ofdm_preamble = tmp52__ >> 1 & 0x1;
+			pDst->report.Basic.unid_signal = tmp52__ >> 2 & 0x1;
+			pDst->report.Basic.rader = tmp52__ >> 3 & 0x1;
+			pDst->report.Basic.unmeasured = tmp52__ >> 4 & 0x1;
+			pDst->report.Basic.unused = tmp52__ >> 5 & 0x7;
+			break;
+		case 1:
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.CCA.channel = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 8)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohq(pCtx, &pDst->report.CCA.meas_start_time, pBuf, 0);
+			pBuf += 8;
+			ielen -= (uint8_t)8;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->report.CCA.meas_duration, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.CCA.cca_busy_fraction = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			break;
+		case 2:
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.RPIHistogram.channel = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 8)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohq(pCtx, &pDst->report.RPIHistogram.meas_start_time, pBuf, 0);
+			pBuf += 8;
+			ielen -= (uint8_t)8;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->report.RPIHistogram.meas_duration, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.RPIHistogram.rpi0_density = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.RPIHistogram.rpi1_density = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.RPIHistogram.rpi2_density = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.RPIHistogram.rpi3_density = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.RPIHistogram.rpi4_density = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.RPIHistogram.rpi5_density = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.RPIHistogram.rpi6_density = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.RPIHistogram.rpi7_density = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			break;
+		case 5:
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.Beacon.regClass = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.Beacon.channel = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 8)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohq(pCtx, &pDst->report.Beacon.meas_start_time, pBuf, 0);
+			pBuf += 8;
+			ielen -= (uint8_t)8;
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->report.Beacon.meas_duration, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			tmp53__ = *pBuf;
+			pBuf += 1;
+			ielen -= 1;
+			pDst->report.Beacon.condensed_PHY = tmp53__ >> 0 & 0x7f;
+			pDst->report.Beacon.reported_frame_type = tmp53__ >> 7 & 0x1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.Beacon.RCPI = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.Beacon.RSNI = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 6)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			DOT11F_MEMCPY(pCtx, pDst->report.Beacon.BSSID, pBuf, 6);
+			pBuf += 6;
+			ielen -= (uint8_t)6;
+			if (unlikely(ielen < 1)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			pDst->report.Beacon.antenna_id = *pBuf;
+			pBuf += 1;
+			ielen -= (uint8_t)1;
+			if (unlikely(ielen < 4)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohl(pCtx, &pDst->report.Beacon.parent_TSF, pBuf, 0);
+			pBuf += 4;
+			ielen -= (uint8_t)4;
+			status |= unpack_core(pCtx,
+				pBuf,
+				ielen,
+				FFS_reportBeacon,
+				IES_reportBeacon,
+				(uint8_t *)pDst,
+				sizeof(*pDst), append_ie);
+			break;
+		}
+	}
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_measurement_report. */
+
+#define SigIeMeasurementReport (0x0041)
+
+
+static const tFFDefn FFS_measurement_requestBeacon[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_measurement_requestBeacon[] = {
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.Beacon.SSID), offsetof(tDot11fIESSID, present), 0,
+	"SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 0, 0, },
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.Beacon.BeaconReporting),
+	offsetof(tDot11fIEBeaconReporting, present), 0, "BeaconReporting",
+	0, 4, 4, SigIeBeaconReporting, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_BEACONREPORTING, 0, 0, },
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.Beacon.BcnReportingDetail),
+	offsetof(tDot11fIEBcnReportingDetail, present), 0, "BcnReportingDetail",
+	0, 3, 3, SigIeBcnReportingDetail, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_BCNREPORTINGDETAIL, 0, 0, },
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.Beacon.RequestedInfo),
+	offsetof(tDot11fIERequestedInfo, present), 0, "RequestedInfo",
+	0, 2, 257, SigIeRequestedInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_REQUESTEDINFO, 0, 0, },
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.Beacon.APChannelReport),
+	offsetof(tDot11fIEAPChannelReport, present),
+	offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.num_APChannelReport), "APChannelReport", 2, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, 0, },
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.Beacon.last_beacon_report_indication),
+	offsetof(tDot11fIElast_beacon_report_indication, present), 0,
+	"last_beacon_report_indication",
+	0, 3, 3, SigIelast_beacon_report_indication, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_LAST_BEACON_REPORT_INDICATION, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+static const tFFDefn FFS_measurement_requestlci[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_measurement_requestlci[] = {
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.lci.azimuth_req), offsetof(tDot11fIEazimuth_req,
+	present), 0, "azimuth_req", 0, 3, 3, SigIeazimuth_req, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_AZIMUTH_REQ, 0, 0, },
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.lci.req_mac_addr), offsetof(tDot11fIEreq_mac_addr,
+	present), 0, "req_mac_addr", 0, 8, 8, SigIereq_mac_addr, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_REQ_MAC_ADDR, 0, 0, },
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.lci.tgt_mac_addr), offsetof(tDot11fIEtgt_mac_addr,
+	present), 0, "tgt_mac_addr", 0, 8, 8, SigIetgt_mac_addr, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TGT_MAC_ADDR, 0, 0, },
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.lci.max_age), offsetof(tDot11fIEmax_age, present), 0,
+	"max_age", 0, 4, 4, SigIemax_age, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MAX_AGE, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+static const tFFDefn FFS_measurement_requestftmrr[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_measurement_requestftmrr[] = {
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.ftmrr.neighbor_rpt), offsetof(tDot11fIEneighbor_rpt,
+	present), 0, "neighbor_rpt", 0, 15, 548, SigIeneighbor_rpt,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_NEIGHBOR_RPT, 0, 0, },
+	{ offsetof(tDot11fIEMeasurementRequest,
+	measurement_request.ftmrr.max_age), offsetof(tDot11fIEmax_age, present),
+	0, "max_age", 0, 4, 4, SigIemax_age, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MAX_AGE, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_measurement_request(tpAniSirGlobal pCtx,
+					     uint8_t *pBuf,
+					     uint8_t ielen,
+					     tDot11fIEMeasurementRequest *pDst,
+					     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp54__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->measurement_token = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp54__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->parallel = tmp54__ >> 0 & 0x1;
+	pDst->enable = tmp54__ >> 1 & 0x1;
+	pDst->request = tmp54__ >> 2 & 0x1;
+	pDst->report = tmp54__ >> 3 & 0x1;
+	pDst->durationMandatory = tmp54__ >> 4 & 0x1;
+	pDst->unused = tmp54__ >> 5 & 0x7;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->measurement_type = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	switch (pDst->measurement_type) {
+	case 0:
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->measurement_request.Basic.channel_no = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		if (unlikely(ielen < 8)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->measurement_request.Basic.meas_start_time, pBuf, 8);
+		pBuf += 8;
+		ielen -= (uint8_t)8;
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->measurement_request.Basic.meas_duration, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+		break;
+	case 1:
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->measurement_request.CCA.channel_no = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		if (unlikely(ielen < 8)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->measurement_request.CCA.meas_start_time, pBuf, 8);
+		pBuf += 8;
+		ielen -= (uint8_t)8;
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->measurement_request.CCA.meas_duration, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+		break;
+	case 2:
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->measurement_request.RPIHistogram.channel_no = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		if (unlikely(ielen < 8)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->measurement_request.RPIHistogram.meas_start_time, pBuf, 8);
+		pBuf += 8;
+		ielen -= (uint8_t)8;
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->measurement_request.RPIHistogram.meas_duration, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+		break;
+	case 5:
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->measurement_request.Beacon.regClass = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->measurement_request.Beacon.channel = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->measurement_request.Beacon.randomization, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->measurement_request.Beacon.meas_duration, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->measurement_request.Beacon.meas_mode = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		if (unlikely(ielen < 6)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->measurement_request.Beacon.BSSID, pBuf, 6);
+		pBuf += 6;
+		ielen -= (uint8_t)6;
+		status |= unpack_core(pCtx,
+				pBuf,
+				ielen,
+				FFS_measurement_requestBeacon,
+				IES_measurement_requestBeacon,
+				(uint8_t *)pDst,
+				sizeof(*pDst), append_ie);
+		break;
+	case 8:
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->measurement_request.lci.loc_subject = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		status |= unpack_core(pCtx,
+				pBuf,
+				ielen,
+				FFS_measurement_requestlci,
+				IES_measurement_requestlci,
+				(uint8_t *)pDst,
+				sizeof(*pDst), append_ie);
+		break;
+	case 16:
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->measurement_request.ftmrr.random_interval, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->measurement_request.ftmrr.min_ap_count = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		status |= unpack_core(pCtx,
+				pBuf,
+				ielen,
+				FFS_measurement_requestftmrr,
+				IES_measurement_requestftmrr,
+				(uint8_t *)pDst,
+				sizeof(*pDst), append_ie);
+		break;
+	}
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_measurement_request. */
+
+#define SigIeMeasurementRequest (0x0042)
+
+
+uint32_t dot11f_unpack_ie_mobility_domain(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEMobilityDomain *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp55__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->MDID, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp55__ = *pBuf;
+	pDst->overDSCap = tmp55__ >> 0 & 0x1;
+	pDst->resourceReqCap = tmp55__ >> 1 & 0x1;
+	pDst->reserved = tmp55__ >> 2 & 0x3f;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_mobility_domain. */
+
+#define SigIeMobilityDomain (0x0043)
+
+
+static const tFFDefn FFS_NeighborReport[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_NeighborReport[] = {
+	{ offsetof(tDot11fIENeighborReport, TSFInfo), offsetof(tDot11fIETSFInfo,
+	present), 0, "TSFInfo", 0, 6, 6, SigIeTSFInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TSFINFO, 0, 0, },
+	{ offsetof(tDot11fIENeighborReport, CondensedCountryStr),
+	offsetof(tDot11fIECondensedCountryStr, present), 0, "CondensedCountryStr",
+	0, 4, 4, SigIeCondensedCountryStr, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_CONDENSEDCOUNTRYSTR, 0, 0, },
+	{ offsetof(tDot11fIENeighborReport, MeasurementPilot),
+	offsetof(tDot11fIEMeasurementPilot, present), 0, "MeasurementPilot",
+	0, 3, 258, SigIeMeasurementPilot, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MEASUREMENTPILOT, 0, 0, },
+	{ offsetof(tDot11fIENeighborReport, RRMEnabledCap),
+	offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+	0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RRMENABLEDCAP, 0, 0, },
+	{ offsetof(tDot11fIENeighborReport, MultiBssid),
+	offsetof(tDot11fIEMultiBssid, present), 0, "MultiBssid",
+	0, 3, 258, SigIeMultiBssid, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MULTIBSSID, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_neighbor_report(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIENeighborReport *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp56__;
+	uint8_t tmp57__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6);
+	pBuf += 6;
+	ielen -= (uint8_t)6;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp56__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->APReachability = tmp56__ >> 0 & 0x3;
+	pDst->Security = tmp56__ >> 2 & 0x1;
+	pDst->KeyScope = tmp56__ >> 3 & 0x1;
+	pDst->SpecMgmtCap = tmp56__ >> 4 & 0x1;
+	pDst->QosCap = tmp56__ >> 5 & 0x1;
+	pDst->apsd = tmp56__ >> 6 & 0x1;
+	pDst->rrm = tmp56__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp57__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->DelayedBA = tmp57__ >> 0 & 0x1;
+	pDst->ImmBA = tmp57__ >> 1 & 0x1;
+	pDst->MobilityDomain = tmp57__ >> 2 & 0x1;
+	pDst->reserved = tmp57__ >> 3 & 0x1f;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->reserved1, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->regulatoryClass = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->channel = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->PhyType = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	(void)pCtx;
+	status |= unpack_core(pCtx,
+				pBuf,
+				ielen,
+				FFS_NeighborReport,
+				IES_NeighborReport,
+				(uint8_t *)pDst,
+				sizeof(*pDst),
+				append_ie);
+	return status;
+} /* End dot11f_unpack_ie_neighbor_report. */
+
+#define SigIeNeighborReport (0x0044)
+
+
+uint32_t dot11f_unpack_ie_obss_scan_parameters(tpAniSirGlobal pCtx,
+					     uint8_t *pBuf,
+					     uint8_t ielen,
+					     tDot11fIEOBSSScanParameters *pDst,
+					     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->obssScanPassiveDwell, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->obssScanActiveDwell, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->bssChannelWidthTriggerScanInterval, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->obssScanPassiveTotalPerChannel, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->obssScanActiveTotalPerChannel, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->bssWidthChannelTransitionDelayFactor, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->obssScanActivityThreshold, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_obss_scan_parameters. */
+
+#define SigIeOBSSScanParameters (0x0045)
+
+
+uint32_t dot11f_unpack_ie_operating_mode(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEOperatingMode *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp58__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp58__ = *pBuf;
+	pDst->chanWidth = tmp58__ >> 0 & 0x3;
+	pDst->reserved = tmp58__ >> 2 & 0x3;
+	pDst->rxNSS = tmp58__ >> 4 & 0x7;
+	pDst->rxNSSType = tmp58__ >> 7 & 0x1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_operating_mode. */
+
+#define SigIeOperatingMode (0x0046)
+
+
+static const tTLVDefn TLVS_P2PAssocReq[] = {
+	{ offsetof(tDot11fIEP2PAssocReq, P2PCapability),
+	offsetof(tDot11fTLVP2PCapability, present), "P2PCapability",
+	SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PAssocReq, ExtendedListenTiming),
+	offsetof(tDot11fTLVExtendedListenTiming, present),
+	"ExtendedListenTiming", SigTlvExtendedListenTiming,
+	DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PAssocReq, P2PDeviceInfo),
+	offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo",
+	SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_assoc_req(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEP2PAssocReq *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_P2PAssocReq,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_p2_p_assoc_req. */
+
+#define SigIeP2PAssocReq (0x0047)
+
+
+static const tTLVDefn TLVS_P2PAssocRes[] = {
+	{ offsetof(tDot11fIEP2PAssocRes, P2PStatus),
+	offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus,
+	DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PAssocRes, ExtendedListenTiming),
+	offsetof(tDot11fTLVExtendedListenTiming, present),
+	"ExtendedListenTiming", SigTlvExtendedListenTiming,
+	DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_assoc_res(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEP2PAssocRes *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_P2PAssocRes,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_p2_p_assoc_res. */
+
+#define SigIeP2PAssocRes (0x0048)
+
+
+static const tTLVDefn TLVS_P2PBeacon[] = {
+	{ offsetof(tDot11fIEP2PBeacon, P2PCapability),
+	offsetof(tDot11fTLVP2PCapability, present), "P2PCapability",
+	SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PBeacon, P2PDeviceId),
+	offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId",
+	SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 1, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PBeacon, NoticeOfAbsence),
+	offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence",
+	SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE,
+	0, 5, 41, 0, 1, 2, 0, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_beacon(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIEP2PBeacon *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_P2PBeacon,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_p2_p_beacon. */
+
+#define SigIeP2PBeacon (0x0049)
+
+
+static const tTLVDefn TLVS_P2PBeaconProbeRes[] = {
+	{ offsetof(tDot11fIEP2PBeaconProbeRes, P2PCapability),
+	offsetof(tDot11fTLVP2PCapability, present), "P2PCapability",
+	SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 0, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PBeaconProbeRes, P2PDeviceId),
+	offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId",
+	SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 0, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PBeaconProbeRes, ExtendedListenTiming),
+	offsetof(tDot11fTLVExtendedListenTiming, present),
+	"ExtendedListenTiming", SigTlvExtendedListenTiming,
+	DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PBeaconProbeRes, NoticeOfAbsence),
+	offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence",
+	SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE,
+	0, 5, 41, 0, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PBeaconProbeRes, P2PDeviceInfo),
+	offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo",
+	SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 0, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PBeaconProbeRes, P2PGroupInfo),
+	offsetof(tDot11fTLVP2PGroupInfo, present), "P2PGroupInfo",
+	SigTlvP2PGroupInfo, DOT11F_TLV_P2PGROUPINFO, 0, 3, 1027, 0, 1, 2, 0, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_beacon_probe_res(tpAniSirGlobal pCtx,
+					    uint8_t *pBuf,
+					    uint8_t ielen,
+					    tDot11fIEP2PBeaconProbeRes *pDst,
+					    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_P2PBeaconProbeRes,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_p2_p_beacon_probe_res. */
+
+#define SigIeP2PBeaconProbeRes (0x004a)
+
+
+static const tTLVDefn TLVS_P2PDeAuth[] = {
+	{ offsetof(tDot11fIEP2PDeAuth, MinorReasonCode),
+	offsetof(tDot11fTLVMinorReasonCode, present), "MinorReasonCode",
+	SigTlvMinorReasonCode, DOT11F_TLV_MINORREASONCODE,
+	0, 4, 4, 1, 1, 2, 0, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_de_auth(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIEP2PDeAuth *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_P2PDeAuth,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_p2_p_de_auth. */
+
+#define SigIeP2PDeAuth (0x004b)
+
+
+static const tTLVDefn TLVS_P2PDisAssoc[] = {
+	{ offsetof(tDot11fIEP2PDisAssoc, MinorReasonCode),
+	offsetof(tDot11fTLVMinorReasonCode, present), "MinorReasonCode",
+	SigTlvMinorReasonCode, DOT11F_TLV_MINORREASONCODE,
+	0, 4, 4, 1, 1, 2, 0, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_dis_assoc(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEP2PDisAssoc *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_P2PDisAssoc,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_p2_p_dis_assoc. */
+
+#define SigIeP2PDisAssoc (0x004c)
+
+
+uint32_t dot11f_unpack_ie_p2_pie_opaque(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEP2PIEOpaque *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_data = (uint8_t)(ielen);
+	if (ielen > 249) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_p2_pie_opaque. */
+
+#define SigIeP2PIEOpaque (0x004d)
+
+
+static const tTLVDefn TLVS_P2PProbeReq[] = {
+	{ offsetof(tDot11fIEP2PProbeReq, P2PCapability),
+	offsetof(tDot11fTLVP2PCapability, present), "P2PCapability",
+	SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PProbeReq, P2PDeviceId),
+	offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId",
+	SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 0, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PProbeReq, ListenChannel),
+	offsetof(tDot11fTLVListenChannel, present), "ListenChannel",
+	SigTlvListenChannel, DOT11F_TLV_LISTENCHANNEL, 0, 8, 8, 1, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PProbeReq, ExtendedListenTiming),
+	offsetof(tDot11fTLVExtendedListenTiming, present),
+	"ExtendedListenTiming", SigTlvExtendedListenTiming,
+	DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PProbeReq, OperatingChannel),
+	offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel",
+	SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL,
+	0, 8, 8, 0, 1, 2, 0, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_probe_req(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEP2PProbeReq *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_P2PProbeReq,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_p2_p_probe_req. */
+
+#define SigIeP2PProbeReq (0x004e)
+
+
+static const tTLVDefn TLVS_P2PProbeRes[] = {
+	{ offsetof(tDot11fIEP2PProbeRes, P2PCapability),
+	offsetof(tDot11fTLVP2PCapability, present), "P2PCapability",
+	SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PProbeRes, ExtendedListenTiming),
+	offsetof(tDot11fTLVExtendedListenTiming, present),
+	"ExtendedListenTiming", SigTlvExtendedListenTiming,
+	DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PProbeRes, NoticeOfAbsence),
+	offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence",
+	SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE,
+	0, 5, 41, 0, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PProbeRes, P2PDeviceInfo),
+	offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo",
+	SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, },
+	{ offsetof(tDot11fIEP2PProbeRes, P2PGroupInfo),
+	offsetof(tDot11fTLVP2PGroupInfo, present), "P2PGroupInfo",
+	SigTlvP2PGroupInfo, DOT11F_TLV_P2PGROUPINFO, 0, 3, 1027, 0, 1, 2, 0, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_probe_res(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEP2PProbeRes *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_P2PProbeRes,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_p2_p_probe_res. */
+
+#define SigIeP2PProbeRes (0x004f)
+
+
+uint32_t dot11f_unpack_ie_pti_control(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     uint8_t ielen,
+				     tDot11fIEPTIControl *pDst,
+				     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->tid = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->sequence_control, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_pti_control. */
+
+#define SigIePTIControl (0x0050)
+
+
+uint32_t dot11f_unpack_ie_pu_buffer_status(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEPUBufferStatus *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp59__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp59__ = *pBuf;
+	pDst->ac_bk_traffic_aval = tmp59__ >> 0 & 0x1;
+	pDst->ac_be_traffic_aval = tmp59__ >> 1 & 0x1;
+	pDst->ac_vi_traffic_aval = tmp59__ >> 2 & 0x1;
+	pDst->ac_vo_traffic_aval = tmp59__ >> 3 & 0x1;
+	pDst->reserved = tmp59__ >> 4 & 0xf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_pu_buffer_status. */
+
+#define SigIePUBufferStatus (0x0051)
+
+
+uint32_t dot11f_unpack_ie_power_caps(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIEPowerCaps *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->minTxPower = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->maxTxPower = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_power_caps. */
+
+#define SigIePowerCaps (0x0052)
+
+
+uint32_t dot11f_unpack_ie_power_constraints(tpAniSirGlobal pCtx,
+					   uint8_t *pBuf,
+					   uint8_t ielen,
+					   tDot11fIEPowerConstraints *pDst,
+					   bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->localPowerConstraints = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_power_constraints. */
+
+#define SigIePowerConstraints (0x0053)
+
+
+uint32_t dot11f_unpack_ie_qbss_load(tpAniSirGlobal pCtx,
+				   uint8_t *pBuf,
+				   uint8_t ielen,
+				   tDot11fIEQBSSLoad *pDst,
+				   bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->stacount, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->chautil = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->avail, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_qbss_load. */
+
+#define SigIeQBSSLoad (0x0054)
+
+
+uint32_t dot11f_unpack_ie_QCN_IE(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIEQCN_IE *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->version, pBuf, 4);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_QCN_IE. */
+
+#define SigIeQCN_IE (0x0055)
+
+
+uint32_t dot11f_unpack_ie_QComVendorIE(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint8_t ielen,
+				       tDot11fIEQComVendorIE *pDst,
+				       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->type = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->channel = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_QComVendorIE. */
+
+#define SigIeQComVendorIE (0x0056)
+
+
+uint32_t dot11f_unpack_ie_qos_caps_ap(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIEQOSCapsAp *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp60__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp60__ = *pBuf;
+	pDst->count = tmp60__ >> 0 & 0xf;
+	pDst->qack = tmp60__ >> 4 & 0x1;
+	pDst->qreq = tmp60__ >> 5 & 0x1;
+	pDst->txopreq = tmp60__ >> 6 & 0x1;
+	pDst->reserved = tmp60__ >> 7 & 0x1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_qos_caps_ap. */
+
+#define SigIeQOSCapsAp (0x0057)
+
+
+uint32_t dot11f_unpack_ie_qos_caps_station(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEQOSCapsStation *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp61__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp61__ = *pBuf;
+	pDst->acvo_uapsd = tmp61__ >> 0 & 0x1;
+	pDst->acvi_uapsd = tmp61__ >> 1 & 0x1;
+	pDst->acbk_uapsd = tmp61__ >> 2 & 0x1;
+	pDst->acbe_uapsd = tmp61__ >> 3 & 0x1;
+	pDst->qack = tmp61__ >> 4 & 0x1;
+	pDst->max_sp_length = tmp61__ >> 5 & 0x3;
+	pDst->more_data_ack = tmp61__ >> 7 & 0x1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_qos_caps_station. */
+
+#define SigIeQOSCapsStation (0x0058)
+
+
+uint32_t dot11f_unpack_ie_qos_map_set(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIEQosMapSet *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_dscp_exceptions = (uint8_t)(ielen);
+	if (ielen > 60) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->dscp_exceptions, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_qos_map_set. */
+
+#define SigIeQosMapSet (0x0059)
+
+
+uint32_t dot11f_unpack_ie_quiet(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIEQuiet *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->count = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->period = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->duration, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->offset, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_quiet. */
+
+#define SigIeQuiet (0x005a)
+
+
+uint32_t dot11f_unpack_ie_rcpiie(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIERCPIIE *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->rcpi = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_rcpiie. */
+
+#define SigIeRCPIIE (0x005b)
+
+
+static const tFFDefn FFS_RICDataDesc[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_RICDataDesc[] = {
+	{ offsetof(tDot11fIERICDataDesc, RICData), offsetof(tDot11fIERICData,
+	present), 0, "RICData", 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RICDATA, 0, 1, },
+	{ offsetof(tDot11fIERICDataDesc, RICDescriptor),
+	offsetof(tDot11fIERICDescriptor, present), 0, "RICDescriptor",
+	0, 3, 258, SigIeRICDescriptor, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RICDESCRIPTOR, 0, 0, },
+	{ offsetof(tDot11fIERICDataDesc, TSPEC), offsetof(tDot11fIETSPEC,
+	present), 0, "TSPEC", 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TSPEC, 0, 0, },
+	{ offsetof(tDot11fIERICDataDesc, TCLAS), offsetof(tDot11fIETCLAS,
+	present), offsetof(tDot11fIERICDataDesc, num_TCLAS), "TCLAS",
+	2, 7, 45, SigIeTCLAS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, 0, },
+	{ offsetof(tDot11fIERICDataDesc, TCLASSPROC),
+	offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC",
+	0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TCLASSPROC, 0, 0, },
+	{ offsetof(tDot11fIERICDataDesc, TSDelay), offsetof(tDot11fIETSDelay,
+	present), 0, "TSDelay", 0, 6, 6, SigIeTSDelay, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TSDELAY, 0, 0, },
+	{ offsetof(tDot11fIERICDataDesc, Schedule), offsetof(tDot11fIESchedule,
+	present), 0, "Schedule", 0, 16, 16, SigIeSchedule, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SCHEDULE, 0, 0, },
+	{ offsetof(tDot11fIERICDataDesc, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+	present), 0, "WMMTSPEC", 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+	5, DOT11F_EID_WMMTSPEC, 0, 0, },
+	{ offsetof(tDot11fIERICDataDesc, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS,
+	present), offsetof(tDot11fIERICDataDesc, num_WMMTCLAS), "WMMTCLAS",
+	2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6},
+	5, DOT11F_EID_WMMTCLAS, 0, 0, },
+	{ offsetof(tDot11fIERICDataDesc, WMMTCLASPROC),
+	offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC",
+	0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7},
+	5, DOT11F_EID_WMMTCLASPROC, 0, 0, },
+	{ offsetof(tDot11fIERICDataDesc, WMMTSDelay),
+	offsetof(tDot11fIEWMMTSDelay, present), 0, "WMMTSDelay",
+	0, 12, 12, SigIeWMMTSDelay, {0, 80, 242, 2, 8},
+	5, DOT11F_EID_WMMTSDELAY, 0, 0, },
+	{ offsetof(tDot11fIERICDataDesc, WMMSchedule),
+	offsetof(tDot11fIEWMMSchedule, present), 0, "WMMSchedule",
+	0, 22, 22, SigIeWMMSchedule, {0, 80, 242, 2, 9},
+	5, DOT11F_EID_WMMSCHEDULE, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_ric_data_desc(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIERICDataDesc *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	(void)pCtx;
+	status |= unpack_core(pCtx,
+				pBuf,
+				ielen,
+				FFS_RICDataDesc,
+				IES_RICDataDesc,
+				(uint8_t *)pDst,
+				sizeof(*pDst),
+				append_ie);
+	return status;
+} /* End dot11f_unpack_ie_ric_data_desc. */
+
+#define SigIeRICDataDesc (0x005c)
+
+
+uint32_t dot11f_unpack_ie_rsn(tpAniSirGlobal pCtx,
+			      uint8_t *pBuf,
+			      uint8_t ielen,
+			      tDot11fIERSN *pDst,
+			      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t def_cipher_suite[4] = {0x00, 0x0f, 0xac, 0x04};
+	uint8_t def_akm_suite[4] = {0x00, 0x0f, 0xac, 0x01};
+
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->version, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (pDst->version != 0x1) {
+		pDst->present = 0;
+		return status | DOT11F_BAD_FIXED_VALUE;
+	}
+	if (!ielen) {
+		pDst->RSN_Cap_present = 0U;
+		pDst->gp_mgmt_cipher_suite_present = 0U;
+		pDst->gp_cipher_suite_present = 1;
+		DOT11F_MEMCPY(pCtx, pDst->gp_cipher_suite, def_cipher_suite, 4);
+		pDst->pwise_cipher_suite_count = 1;
+		DOT11F_MEMCPY(pCtx,
+				pDst->pwise_cipher_suites, def_cipher_suite, 4);
+		pDst->akm_suite_cnt = 1;
+		DOT11F_MEMCPY(pCtx, pDst->akm_suite, def_akm_suite, 4);
+		pDst->pmkid_count = 0U;
+		return 0U;
+	} else {
+		pDst->gp_cipher_suite_present = 1;
+		if (unlikely(ielen < 4)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->gp_cipher_suite, pBuf, 4);
+		pBuf += 4;
+		ielen -= (uint8_t)4;
+	}
+	if (!ielen) {
+		pDst->RSN_Cap_present = 0U;
+		pDst->gp_mgmt_cipher_suite_present = 0U;
+		pDst->pwise_cipher_suite_count = 1;
+		DOT11F_MEMCPY(pCtx,
+				pDst->pwise_cipher_suites, def_cipher_suite, 4);
+		pDst->akm_suite_cnt = 1;
+		DOT11F_MEMCPY(pCtx, pDst->akm_suite, def_akm_suite, 4);
+		pDst->pmkid_count = 0U;
+		return 0U;
+	} else {
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->pwise_cipher_suite_count, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+	}
+	if (unlikely(ielen < pDst->pwise_cipher_suite_count * 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (!pDst->pwise_cipher_suite_count ||
+		pDst->pwise_cipher_suite_count > 6) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->pwise_cipher_suites, pBuf, (pDst->pwise_cipher_suite_count * 4));
+	pBuf += (pDst->pwise_cipher_suite_count * 4);
+	ielen -= (pDst->pwise_cipher_suite_count * 4);
+	if (!ielen) {
+		pDst->RSN_Cap_present = 0U;
+		pDst->gp_mgmt_cipher_suite_present = 0U;
+		pDst->akm_suite_cnt = 1;
+		DOT11F_MEMCPY(pCtx, pDst->akm_suite, def_akm_suite, 4);
+		pDst->pmkid_count = 0U;
+		return 0U;
+	} else {
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->akm_suite_cnt, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+	}
+	if (unlikely(ielen < pDst->akm_suite_cnt * 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (!pDst->akm_suite_cnt ||
+		pDst->akm_suite_cnt > 6) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->akm_suite, pBuf, (pDst->akm_suite_cnt * 4));
+	pBuf += (pDst->akm_suite_cnt * 4);
+	ielen -= (pDst->akm_suite_cnt * 4);
+	if (!ielen) {
+		pDst->RSN_Cap_present = 0U;
+		pDst->gp_mgmt_cipher_suite_present = 0U;
+		pDst->pmkid_count = 0U;
+		return 0U;
+	} else {
+		pDst->RSN_Cap_present = 1;
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->RSN_Cap, pBuf, 2);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+	}
+	if (!ielen) {
+		pDst->RSN_Cap_present = 0U;
+		pDst->gp_mgmt_cipher_suite_present = 0U;
+		pDst->pmkid_count = 0U;
+		return 0U;
+	} else {
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->pmkid_count, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+	}
+	if (unlikely(ielen < pDst->pmkid_count * 16)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (pDst->pmkid_count > 4) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->pmkid, pBuf, (pDst->pmkid_count * 16));
+	pBuf += (pDst->pmkid_count * 16);
+	ielen -= (pDst->pmkid_count * 16);
+	if (!ielen) {
+		return 0U;
+	} else {
+		pDst->gp_mgmt_cipher_suite_present = 1;
+		if (unlikely(ielen < 4)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->gp_mgmt_cipher_suite, pBuf, 4);
+	}
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_rsn. */
+
+#define SigIeRSN (0x005d)
+
+
+uint32_t dot11f_unpack_ie_rsniie(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIERSNIIE *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->rsni = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_rsniie. */
+
+#define SigIeRSNIIE (0x005e)
+
+
+uint32_t dot11f_unpack_ie_rsn_opaque(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIERSNOpaque *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_data = (uint8_t)(ielen);
+	if (ielen > 253) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_rsn_opaque. */
+
+#define SigIeRSNOpaque (0x005f)
+
+
+uint32_t dot11f_unpack_ie_supp_channels(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint8_t ielen,
+				       tDot11fIESuppChannels *pDst,
+				       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_bands = (uint8_t)(ielen / 2);
+	if (ielen > 48 * 2) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->bands, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_supp_channels. */
+
+#define SigIeSuppChannels (0x0060)
+
+
+uint32_t dot11f_unpack_ie_supp_operating_classes(tpAniSirGlobal pCtx,
+					       uint8_t *pBuf,
+					       uint8_t ielen,
+					       tDot11fIESuppOperatingClasses *pDst,
+					       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_classes = (uint8_t)(ielen);
+	if (ielen > 32) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->classes, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_supp_operating_classes. */
+
+#define SigIeSuppOperatingClasses (0x0061)
+
+
+uint32_t dot11f_unpack_ie_supp_rates(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIESuppRates *pDst,
+				    bool append_ie)
+{
+	uint8_t i;
+	uint8_t rate_indx = 0;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	for (i = 0; i < ielen; i++) {
+		if ((DOT11F_IS_BG_RATE(pBuf[i] & 0x7F)) &&
+			(rate_indx < 12)) {
+			pDst->rates[rate_indx++] = pBuf[i];
+		}
+	}
+
+	if (rate_indx == 0) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	pDst->num_rates = rate_indx;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_supp_rates. */
+
+#define SigIeSuppRates (0x0062)
+
+
+uint32_t dot11f_unpack_ie_tim(tpAniSirGlobal pCtx,
+			      uint8_t *pBuf,
+			      uint8_t ielen,
+			      tDot11fIETIM *pDst,
+			      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->dtim_count = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->dtim_period = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->bmpctl = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	pDst->num_vbmp = (uint8_t)(ielen);
+	if (ielen > 251) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->vbmp, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_tim. */
+
+#define SigIeTIM (0x0063)
+
+
+uint32_t dot11f_unpack_ie_tpc_report(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIETPCReport *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->tx_power = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->link_margin = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_tpc_report. */
+
+#define SigIeTPCReport (0x0064)
+
+
+uint32_t dot11f_unpack_ie_tpc_request(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     uint8_t ielen,
+				     tDot11fIETPCRequest *pDst,
+				     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_tpc_request. */
+
+#define SigIeTPCRequest (0x0065)
+
+
+uint32_t dot11f_unpack_ie_time_advertisement(tpAniSirGlobal pCtx,
+					    uint8_t *pBuf,
+					    uint8_t ielen,
+					    tDot11fIETimeAdvertisement *pDst,
+					    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->timing_capabilities = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 10)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->time_value, pBuf, 10);
+	pBuf += 10;
+	ielen -= (uint8_t)10;
+	if (unlikely(ielen < 5)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->time_error, pBuf, 5);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_time_advertisement. */
+
+#define SigIeTimeAdvertisement (0x0066)
+
+
+uint32_t dot11f_unpack_ie_timeout_interval(tpAniSirGlobal pCtx,
+					  uint8_t *pBuf,
+					  uint8_t ielen,
+					  tDot11fIETimeoutInterval *pDst,
+					  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->timeoutType = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &pDst->timeoutValue, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_timeout_interval. */
+
+#define SigIeTimeoutInterval (0x0067)
+
+
+uint32_t dot11f_unpack_ie_vht_ext_bss_load(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEVHTExtBssLoad *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->muMIMOCapStaCount = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->ssUnderUtil = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->FortyMHzUtil = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->EightyMHzUtil = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->OneSixtyMHzUtil = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_vht_ext_bss_load. */
+
+#define SigIeVHTExtBssLoad (0x0068)
+
+
+uint32_t dot11f_unpack_ie_vendor1_ie(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIEVendor1IE *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_vendor1_ie. */
+
+#define SigIeVendor1IE (0x0069)
+
+
+uint32_t dot11f_unpack_ie_vendor3_ie(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIEVendor3IE *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_vendor3_ie. */
+
+#define SigIeVendor3IE (0x006a)
+
+
+uint32_t dot11f_unpack_ie_wapi(tpAniSirGlobal pCtx,
+			       uint8_t *pBuf,
+			       uint8_t ielen,
+			       tDot11fIEWAPI *pDst,
+			       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint16_t tmp62__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->version, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (pDst->version != 0x1) {
+		pDst->present = 0;
+		return status | DOT11F_BAD_FIXED_VALUE;
+	}
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->akm_suite_count, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < pDst->akm_suite_count * 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (pDst->akm_suite_count > 4) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->akm_suites, pBuf, (pDst->akm_suite_count * 4));
+	pBuf += (pDst->akm_suite_count * 4);
+	ielen -= (pDst->akm_suite_count * 4);
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->unicast_cipher_suite_count, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < pDst->unicast_cipher_suite_count * 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (pDst->unicast_cipher_suite_count > 4) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->unicast_cipher_suites, pBuf, (pDst->unicast_cipher_suite_count * 4));
+	pBuf += (pDst->unicast_cipher_suite_count * 4);
+	ielen -= (pDst->unicast_cipher_suite_count * 4);
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->multicast_cipher_suite, pBuf, 4);
+	pBuf += 4;
+	ielen -= (uint8_t)4;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp62__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->preauth = tmp62__ >> 0 & 0x1;
+	pDst->reserved = tmp62__ >> 1 & 0x7fff;
+	if (!ielen) {
+		pDst->bkid_count = 0U;
+		return 0U;
+	} else {
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->bkid_count, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+	}
+	if (unlikely(ielen < pDst->bkid_count * 16)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (pDst->bkid_count > 4) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->bkid, pBuf, (pDst->bkid_count * 16));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wapi. */
+
+#define SigIeWAPI (0x006b)
+
+
+uint32_t dot11f_unpack_ie_wapi_opaque(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     uint8_t ielen,
+				     tDot11fIEWAPIOpaque *pDst,
+				     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_data = (uint8_t)(ielen);
+	if (ielen > 253) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wapi_opaque. */
+
+#define SigIeWAPIOpaque (0x006c)
+
+
+uint32_t dot11f_unpack_ie_wfatpc(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIEWFATPC *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->txPower = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->linkMargin = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wfatpc. */
+
+#define SigIeWFATPC (0x006d)
+
+
+uint32_t dot11f_unpack_ie_wfdie_opaque(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEWFDIEOpaque *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_data = (uint8_t)(ielen);
+	if (ielen > 249) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wfdie_opaque. */
+
+#define SigIeWFDIEOpaque (0x006e)
+
+
+uint32_t dot11f_unpack_ie_wmm_caps(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint8_t ielen,
+				  tDot11fIEWMMCaps *pDst,
+				  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp63__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->version = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (pDst->version != 0x1) {
+		pDst->present = 0;
+		return status | DOT11F_BAD_FIXED_VALUE;
+	}
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp63__ = *pBuf;
+	pDst->reserved = tmp63__ >> 0 & 0xf;
+	pDst->qack = tmp63__ >> 4 & 0x1;
+	pDst->queue_request = tmp63__ >> 5 & 0x1;
+	pDst->txop_request = tmp63__ >> 6 & 0x1;
+	pDst->more_ack = tmp63__ >> 7 & 0x1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wmm_caps. */
+
+#define SigIeWMMCaps (0x006f)
+
+
+uint32_t dot11f_unpack_ie_wmm_info_ap(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIEWMMInfoAp *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp64__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->version = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp64__ = *pBuf;
+	pDst->param_set_count = tmp64__ >> 0 & 0xf;
+	pDst->reserved = tmp64__ >> 4 & 0x7;
+	pDst->uapsd = tmp64__ >> 7 & 0x1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wmm_info_ap. */
+
+#define SigIeWMMInfoAp (0x0070)
+
+
+uint32_t dot11f_unpack_ie_wmm_info_station(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEWMMInfoStation *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp65__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->version = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp65__ = *pBuf;
+	pDst->acvo_uapsd = tmp65__ >> 0 & 0x1;
+	pDst->acvi_uapsd = tmp65__ >> 1 & 0x1;
+	pDst->acbk_uapsd = tmp65__ >> 2 & 0x1;
+	pDst->acbe_uapsd = tmp65__ >> 3 & 0x1;
+	pDst->reserved1 = tmp65__ >> 4 & 0x1;
+	pDst->max_sp_length = tmp65__ >> 5 & 0x3;
+	pDst->reserved2 = tmp65__ >> 7 & 0x1;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wmm_info_station. */
+
+#define SigIeWMMInfoStation (0x0071)
+
+
+uint32_t dot11f_unpack_ie_wmm_params(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIEWMMParams *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp66__;
+	uint8_t tmp67__;
+	uint8_t tmp68__;
+	uint8_t tmp69__;
+	uint8_t tmp70__;
+	uint8_t tmp71__;
+	uint8_t tmp72__;
+	uint8_t tmp73__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->version = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (pDst->version != 0x1) {
+		pDst->present = 0;
+		return status | DOT11F_BAD_FIXED_VALUE;
+	}
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->qosInfo = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->reserved2 = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp66__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbe_aifsn = tmp66__ >> 0 & 0xf;
+	pDst->acbe_acm = tmp66__ >> 4 & 0x1;
+	pDst->acbe_aci = tmp66__ >> 5 & 0x3;
+	pDst->unused1 = tmp66__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp67__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbe_acwmin = tmp67__ >> 0 & 0xf;
+	pDst->acbe_acwmax = tmp67__ >> 4 & 0xf;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp68__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbk_aifsn = tmp68__ >> 0 & 0xf;
+	pDst->acbk_acm = tmp68__ >> 4 & 0x1;
+	pDst->acbk_aci = tmp68__ >> 5 & 0x3;
+	pDst->unused2 = tmp68__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp69__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbk_acwmin = tmp69__ >> 0 & 0xf;
+	pDst->acbk_acwmax = tmp69__ >> 4 & 0xf;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp70__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvi_aifsn = tmp70__ >> 0 & 0xf;
+	pDst->acvi_acm = tmp70__ >> 4 & 0x1;
+	pDst->acvi_aci = tmp70__ >> 5 & 0x3;
+	pDst->unused3 = tmp70__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp71__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvi_acwmin = tmp71__ >> 0 & 0xf;
+	pDst->acvi_acwmax = tmp71__ >> 4 & 0xf;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp72__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvo_aifsn = tmp72__ >> 0 & 0xf;
+	pDst->acvo_acm = tmp72__ >> 4 & 0x1;
+	pDst->acvo_aci = tmp72__ >> 5 & 0x3;
+	pDst->unused4 = tmp72__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp73__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvo_acwmin = tmp73__ >> 0 & 0xf;
+	pDst->acvo_acwmax = tmp73__ >> 4 & 0xf;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wmm_params. */
+
+#define SigIeWMMParams (0x0072)
+
+
+uint32_t dot11f_unpack_ie_wpa(tpAniSirGlobal pCtx,
+			      uint8_t *pBuf,
+			      uint8_t ielen,
+			      tDot11fIEWPA *pDst,
+			      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->version, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (pDst->version != 0x1) {
+		pDst->present = 0;
+		return status | DOT11F_BAD_FIXED_VALUE;
+	}
+	if (!ielen) {
+		pDst->multicast_cipher_present = 0U;
+		pDst->unicast_cipher_count = 0U;
+		pDst->auth_suite_count = 0U;
+		return 0U;
+	} else {
+		pDst->multicast_cipher_present = 1U;
+		if (unlikely(ielen < 4)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->multicast_cipher, pBuf, 4);
+		pBuf += 4;
+		ielen -= (uint8_t)4;
+	}
+	if (!ielen) {
+		pDst->unicast_cipher_count = 0U;
+		pDst->auth_suite_count = 0U;
+		return 0U;
+	} else {
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->unicast_cipher_count, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+	}
+	if (unlikely(ielen < pDst->unicast_cipher_count * 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (pDst->unicast_cipher_count > 4) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->unicast_ciphers, pBuf, (pDst->unicast_cipher_count * 4));
+	pBuf += (pDst->unicast_cipher_count * 4);
+	ielen -= (pDst->unicast_cipher_count * 4);
+	if (!ielen) {
+		pDst->auth_suite_count = 0U;
+		return 0U;
+	} else {
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->auth_suite_count, pBuf, 0);
+		pBuf += 2;
+		ielen -= (uint8_t)2;
+	}
+	if (unlikely(ielen < pDst->auth_suite_count * 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (pDst->auth_suite_count > 4) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->auth_suites, pBuf, (pDst->auth_suite_count * 4));
+	pBuf += (pDst->auth_suite_count * 4);
+	ielen -= (pDst->auth_suite_count * 4);
+	if (!ielen) {
+		return 0U;
+	} else {
+		if (unlikely(ielen < 2)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		framesntohs(pCtx, &pDst->caps, pBuf, 0);
+	}
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wpa. */
+
+#define SigIeWPA (0x0073)
+
+
+uint32_t dot11f_unpack_ie_wpa_opaque(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIEWPAOpaque *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_data = (uint8_t)(ielen);
+	if (ielen > 249) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wpa_opaque. */
+
+#define SigIeWPAOpaque (0x0074)
+
+
+static const tTLVDefn TLVS_WSC[] = {
+	{ offsetof(tDot11fIEWSC, Version), offsetof(tDot11fTLVVersion, present),
+	"Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, WPSState), offsetof(tDot11fTLVWPSState, present),
+	"WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE, 0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, APSetupLocked),
+	offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked",
+	SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, SelectedRegistrarConfigMethods),
+	offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present),
+	"SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods,
+	DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, UUID_E), offsetof(tDot11fTLVUUID_E, present),
+	"UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, UUID_R), offsetof(tDot11fTLVUUID_R, present),
+	"UUID_R", SigTlvUUID_R, DOT11F_TLV_UUID_R, 0, 20, 20, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, RFBands), offsetof(tDot11fTLVRFBands, present),
+	"RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, SelectedRegistrar),
+	offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar",
+	SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR,
+	0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, ConfigMethods),
+	offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods",
+	SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, AssociationState),
+	offsetof(tDot11fTLVAssociationState, present), "AssociationState",
+	SigTlvAssociationState, DOT11F_TLV_ASSOCIATIONSTATE,
+	0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, ConfigurationError),
+	offsetof(tDot11fTLVConfigurationError, present), "ConfigurationError",
+	SigTlvConfigurationError, DOT11F_TLV_CONFIGURATIONERROR,
+	0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, Manufacturer), offsetof(tDot11fTLVManufacturer,
+	present), "Manufacturer", SigTlvManufacturer, DOT11F_TLV_MANUFACTURER,
+	0, 4, 68, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, ModelName), offsetof(tDot11fTLVModelName,
+	present), "ModelName", SigTlvModelName, DOT11F_TLV_MODELNAME,
+	0, 4, 36, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, ModelNumber), offsetof(tDot11fTLVModelNumber,
+	present), "ModelNumber", SigTlvModelNumber, DOT11F_TLV_MODELNUMBER,
+	0, 4, 36, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, SerialNumber), offsetof(tDot11fTLVSerialNumber,
+	present), "SerialNumber", SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER,
+	0, 4, 36, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, DeviceName), offsetof(tDot11fTLVDeviceName,
+	present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME,
+	0, 4, 36, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, DevicePasswordID),
+	offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID",
+	SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID,
+	0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, PrimaryDeviceType),
+	offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType",
+	SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE,
+	0, 12, 12, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, RequestType), offsetof(tDot11fTLVRequestType,
+	present), "RequestType", SigTlvRequestType, DOT11F_TLV_REQUESTTYPE,
+	0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, ResponseType), offsetof(tDot11fTLVResponseType,
+	present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE,
+	0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, VendorExtension),
+	offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+	SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+	0, 7, 21, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWSC, RequestDeviceType),
+	offsetof(tDot11fTLVRequestDeviceType, present), "RequestDeviceType",
+	SigTlvRequestDeviceType, DOT11F_TLV_REQUESTDEVICETYPE,
+	0, 12, 12, 0, 2, 2, 1, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc(tpAniSirGlobal pCtx,
+			      uint8_t *pBuf,
+			      uint8_t ielen,
+			      tDot11fIEWSC *pDst,
+			      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_WSC,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_wsc. */
+
+#define SigIeWSC (0x0075)
+
+
+static const tTLVDefn TLVS_WscAssocReq[] = {
+	{ offsetof(tDot11fIEWscAssocReq, Version), offsetof(tDot11fTLVVersion,
+	present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+	0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscAssocReq, RequestType),
+	offsetof(tDot11fTLVRequestType, present), "RequestType",
+	SigTlvRequestType, DOT11F_TLV_REQUESTTYPE, 0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscAssocReq, VendorExtension),
+	offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+	SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+	0, 7, 21, 0, 2, 2, 1, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_assoc_req(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEWscAssocReq *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_WscAssocReq,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_wsc_assoc_req. */
+
+#define SigIeWscAssocReq (0x0076)
+
+
+static const tTLVDefn TLVS_WscAssocRes[] = {
+	{ offsetof(tDot11fIEWscAssocRes, Version), offsetof(tDot11fTLVVersion,
+	present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+	0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscAssocRes, ResponseType),
+	offsetof(tDot11fTLVResponseType, present), "ResponseType",
+	SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscAssocRes, VendorExtension),
+	offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+	SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+	0, 7, 21, 0, 2, 2, 1, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_assoc_res(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEWscAssocRes *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_WscAssocRes,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_wsc_assoc_res. */
+
+#define SigIeWscAssocRes (0x0077)
+
+
+static const tTLVDefn TLVS_WscBeacon[] = {
+	{ offsetof(tDot11fIEWscBeacon, Version), offsetof(tDot11fTLVVersion,
+	present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+	0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeacon, WPSState), offsetof(tDot11fTLVWPSState,
+	present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE,
+	0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeacon, APSetupLocked),
+	offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked",
+	SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeacon, SelectedRegistrar),
+	offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar",
+	SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR,
+	0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeacon, DevicePasswordID),
+	offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID",
+	SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID,
+	0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeacon, SelectedRegistrarConfigMethods),
+	offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present),
+	"SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods,
+	DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeacon, UUID_E), offsetof(tDot11fTLVUUID_E,
+	present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E,
+	0, 20, 20, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeacon, RFBands), offsetof(tDot11fTLVRFBands,
+	present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS,
+	0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeacon, VendorExtension),
+	offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+	SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+	0, 7, 21, 0, 2, 2, 1, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_beacon(tpAniSirGlobal pCtx,
+				    uint8_t *pBuf,
+				    uint8_t ielen,
+				    tDot11fIEWscBeacon *pDst,
+				    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_WscBeacon,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_wsc_beacon. */
+
+#define SigIeWscBeacon (0x0078)
+
+
+static const tTLVDefn TLVS_WscBeaconProbeRes[] = {
+	{ offsetof(tDot11fIEWscBeaconProbeRes, Version),
+	offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion,
+	DOT11F_TLV_VERSION, 0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, WPSState),
+	offsetof(tDot11fTLVWPSState, present), "WPSState", SigTlvWPSState,
+	DOT11F_TLV_WPSSTATE, 0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, APSetupLocked),
+	offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked",
+	SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, SelectedRegistrar),
+	offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar",
+	SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR,
+	0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, DevicePasswordID),
+	offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID",
+	SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID,
+	0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, SelectedRegistrarConfigMethods),
+	offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present),
+	"SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods,
+	DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, ResponseType),
+	offsetof(tDot11fTLVResponseType, present), "ResponseType",
+	SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, UUID_E),
+	offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E,
+	DOT11F_TLV_UUID_E, 0, 20, 20, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, Manufacturer),
+	offsetof(tDot11fTLVManufacturer, present), "Manufacturer",
+	SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, ModelName),
+	offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName,
+	DOT11F_TLV_MODELNAME, 0, 4, 36, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, ModelNumber),
+	offsetof(tDot11fTLVModelNumber, present), "ModelNumber",
+	SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, SerialNumber),
+	offsetof(tDot11fTLVSerialNumber, present), "SerialNumber",
+	SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER, 0, 4, 36, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, PrimaryDeviceType),
+	offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType",
+	SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE,
+	0, 12, 12, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, DeviceName),
+	offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName,
+	DOT11F_TLV_DEVICENAME, 0, 4, 36, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, ConfigMethods),
+	offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods",
+	SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, RFBands),
+	offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands,
+	DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscBeaconProbeRes, VendorExtension),
+	offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+	SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+	0, 7, 21, 0, 2, 2, 1, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_beacon_probe_res(tpAniSirGlobal pCtx,
+					    uint8_t *pBuf,
+					    uint8_t ielen,
+					    tDot11fIEWscBeaconProbeRes *pDst,
+					    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_WscBeaconProbeRes,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_wsc_beacon_probe_res. */
+
+#define SigIeWscBeaconProbeRes (0x0079)
+
+
+uint32_t dot11f_unpack_ie_wsc_ie_opaque(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEWscIEOpaque *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_data = (uint8_t)(ielen);
+	if (ielen > 249) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_wsc_ie_opaque. */
+
+#define SigIeWscIEOpaque (0x007a)
+
+
+static const tTLVDefn TLVS_WscProbeReq[] = {
+	{ offsetof(tDot11fIEWscProbeReq, Version), offsetof(tDot11fTLVVersion,
+	present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+	0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, RequestType),
+	offsetof(tDot11fTLVRequestType, present), "RequestType",
+	SigTlvRequestType, DOT11F_TLV_REQUESTTYPE, 0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, ConfigMethods),
+	offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods",
+	SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, UUID_E), offsetof(tDot11fTLVUUID_E,
+	present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E,
+	0, 20, 20, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, PrimaryDeviceType),
+	offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType",
+	SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE,
+	0, 12, 12, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, RFBands), offsetof(tDot11fTLVRFBands,
+	present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS,
+	0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, AssociationState),
+	offsetof(tDot11fTLVAssociationState, present), "AssociationState",
+	SigTlvAssociationState, DOT11F_TLV_ASSOCIATIONSTATE,
+	0, 6, 6, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, ConfigurationError),
+	offsetof(tDot11fTLVConfigurationError, present), "ConfigurationError",
+	SigTlvConfigurationError, DOT11F_TLV_CONFIGURATIONERROR,
+	0, 6, 6, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, DevicePasswordID),
+	offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID",
+	SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID,
+	0, 6, 6, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, Manufacturer),
+	offsetof(tDot11fTLVManufacturer, present), "Manufacturer",
+	SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, ModelName),
+	offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName,
+	DOT11F_TLV_MODELNAME, 0, 4, 36, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, ModelNumber),
+	offsetof(tDot11fTLVModelNumber, present), "ModelNumber",
+	SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, DeviceName),
+	offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName,
+	DOT11F_TLV_DEVICENAME, 0, 4, 36, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, VendorExtension),
+	offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+	SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+	0, 7, 21, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeReq, RequestDeviceType),
+	offsetof(tDot11fTLVRequestDeviceType, present), "RequestDeviceType",
+	SigTlvRequestDeviceType, DOT11F_TLV_REQUESTDEVICETYPE,
+	0, 12, 12, 0, 2, 2, 1, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_probe_req(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEWscProbeReq *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_WscProbeReq,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_wsc_probe_req. */
+
+#define SigIeWscProbeReq (0x007b)
+
+
+static const tTLVDefn TLVS_WscProbeRes[] = {
+	{ offsetof(tDot11fIEWscProbeRes, Version), offsetof(tDot11fTLVVersion,
+	present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+	0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, WPSState), offsetof(tDot11fTLVWPSState,
+	present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE,
+	0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, APSetupLocked),
+	offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked",
+	SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, SelectedRegistrar),
+	offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar",
+	SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR,
+	0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, DevicePasswordID),
+	offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID",
+	SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID,
+	0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, SelectedRegistrarConfigMethods),
+	offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present),
+	"SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods,
+	DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, ResponseType),
+	offsetof(tDot11fTLVResponseType, present), "ResponseType",
+	SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, UUID_E), offsetof(tDot11fTLVUUID_E,
+	present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E,
+	0, 20, 20, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, Manufacturer),
+	offsetof(tDot11fTLVManufacturer, present), "Manufacturer",
+	SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, ModelName),
+	offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName,
+	DOT11F_TLV_MODELNAME, 0, 4, 36, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, ModelNumber),
+	offsetof(tDot11fTLVModelNumber, present), "ModelNumber",
+	SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, SerialNumber),
+	offsetof(tDot11fTLVSerialNumber, present), "SerialNumber",
+	SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER, 0, 4, 36, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, PrimaryDeviceType),
+	offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType",
+	SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE,
+	0, 12, 12, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, DeviceName),
+	offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName,
+	DOT11F_TLV_DEVICENAME, 0, 4, 36, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, ConfigMethods),
+	offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods",
+	SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, RFBands), offsetof(tDot11fTLVRFBands,
+	present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS,
+	0, 5, 5, 0, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscProbeRes, VendorExtension),
+	offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+	SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+	0, 7, 21, 0, 2, 2, 1, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_probe_res(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEWscProbeRes *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_WscProbeRes,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_wsc_probe_res. */
+
+#define SigIeWscProbeRes (0x007c)
+
+
+static const tTLVDefn TLVS_WscReassocRes[] = {
+	{ offsetof(tDot11fIEWscReassocRes, Version), offsetof(tDot11fTLVVersion,
+	present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+	0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscReassocRes, ResponseType),
+	offsetof(tDot11fTLVResponseType, present), "ResponseType",
+	SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, },
+	{ offsetof(tDot11fIEWscReassocRes, VendorExtension),
+	offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+	SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+	0, 7, 21, 0, 2, 2, 1, },
+	{0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_reassoc_res(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEWscReassocRes *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pBuf; (void)ielen; /* Shutup the compiler */
+	pDst->present = 1;
+	status = unpack_tlv_core(pCtx, pBuf, ielen,
+			TLVS_WscReassocRes,
+			(uint8_t *)pDst, sizeof(*pDst));
+	return status;
+} /* End dot11f_unpack_ie_wsc_reassoc_res. */
+
+#define SigIeWscReassocRes (0x007d)
+
+
+uint32_t dot11f_unpack_ie_addba_extn_element(tpAniSirGlobal pCtx,
+					     uint8_t *pBuf,
+					     uint8_t ielen,
+					     tDot11fIEaddba_extn_element *pDst,
+					     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp74__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp74__ = *pBuf;
+	pDst->no_fragmentation = tmp74__ >> 0 & 0x1;
+	pDst->he_frag_operation = tmp74__ >> 1 & 0x3;
+	pDst->reserved = tmp74__ >> 3 & 0x1f;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_addba_extn_element. */
+
+#define SigIeaddba_extn_element (0x007e)
+
+
+uint32_t dot11f_unpack_ie_bss_color_change(tpAniSirGlobal pCtx,
+					   uint8_t *pBuf,
+					   uint8_t ielen,
+					   tDot11fIEbss_color_change *pDst,
+					   bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp75__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->countdown = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp75__ = *pBuf;
+	pDst->new_color = tmp75__ >> 0 & 0x3f;
+	pDst->reserved = tmp75__ >> 6 & 0x3;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_bss_color_change. */
+
+#define SigIebss_color_change (0x007f)
+
+
+uint32_t dot11f_unpack_ie_dh_parameter_element(tpAniSirGlobal pCtx,
+					       uint8_t *pBuf,
+					       uint8_t ielen,
+					       tDot11fIEdh_parameter_element *pDst,
+					       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->group, pBuf, 2);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	pDst->num_public_key = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->public_key, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_dh_parameter_element. */
+
+#define SigIedh_parameter_element (0x0080)
+
+
+uint32_t dot11f_unpack_ie_esp_information(tpAniSirGlobal pCtx,
+					  uint8_t *pBuf,
+					  uint8_t ielen,
+					  tDot11fIEesp_information *pDst,
+					  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_data = (uint8_t)(ielen);
+	if (ielen > 96) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_esp_information. */
+
+#define SigIeesp_information (0x0081)
+
+
+uint32_t dot11f_unpack_ie_ext_chan_switch_ann(tpAniSirGlobal pCtx,
+					      uint8_t *pBuf,
+					      uint8_t ielen,
+					      tDot11fIEext_chan_switch_ann *pDst,
+					      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->switch_mode = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->new_reg_class = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->new_channel = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->switch_count = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ext_chan_switch_ann. */
+
+#define SigIeext_chan_switch_ann (0x0082)
+
+
+uint32_t dot11f_unpack_ie_fils_assoc_delay_info(tpAniSirGlobal pCtx,
+						 uint8_t *pBuf,
+						 uint8_t ielen,
+						 tDot11fIEfils_assoc_delay_info *pDst,
+						 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->assoc_delay_info = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fils_assoc_delay_info. */
+
+#define SigIefils_assoc_delay_info (0x0083)
+
+
+uint32_t dot11f_unpack_ie_fils_hlp_container(tpAniSirGlobal pCtx,
+					     uint8_t *pBuf,
+					     uint8_t ielen,
+					     tDot11fIEfils_hlp_container *pDst,
+					     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->dest_mac, pBuf, 6);
+	pBuf += 6;
+	ielen -= (uint8_t)6;
+	if (unlikely(ielen < 6)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->src_mac, pBuf, 6);
+	pBuf += 6;
+	ielen -= (uint8_t)6;
+	pDst->num_hlp_packet = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->hlp_packet, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fils_hlp_container. */
+
+#define SigIefils_hlp_container (0x0084)
+
+
+uint32_t dot11f_unpack_ie_fils_indication(tpAniSirGlobal pCtx,
+					  uint8_t *pBuf,
+					  uint8_t ielen,
+					  tDot11fIEfils_indication *pDst,
+					  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint16_t tmp76__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp76__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->public_key_identifiers_cnt = tmp76__ >> 0 & 0x7;
+	pDst->realm_identifiers_cnt = tmp76__ >> 3 & 0x7;
+	pDst->is_ip_config_supported = tmp76__ >> 6 & 0x1;
+	pDst->is_cache_id_present = tmp76__ >> 7 & 0x1;
+	pDst->is_hessid_present = tmp76__ >> 8 & 0x1;
+	pDst->is_fils_sk_auth_supported = tmp76__ >> 9 & 0x1;
+	pDst->is_fils_sk_auth_pfs_supported = tmp76__ >> 10 & 0x1;
+	pDst->is_pk_auth_supported = tmp76__ >> 11 & 0x1;
+	pDst->reserved = tmp76__ >> 12 & 0xf;
+	pDst->num_variable_data = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->variable_data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fils_indication. */
+
+#define SigIefils_indication (0x0085)
+
+
+uint32_t dot11f_unpack_ie_fils_kde(tpAniSirGlobal pCtx,
+				   uint8_t *pBuf,
+				   uint8_t ielen,
+				   tDot11fIEfils_kde *pDst,
+				   bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 8)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->key_rsc, pBuf, 8);
+	pBuf += 8;
+	ielen -= (uint8_t)8;
+	pDst->num_kde_list = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->kde_list, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fils_kde. */
+
+#define SigIefils_kde (0x0086)
+
+
+uint32_t dot11f_unpack_ie_fils_key_confirmation(tpAniSirGlobal pCtx,
+						 uint8_t *pBuf,
+						 uint8_t ielen,
+						 tDot11fIEfils_key_confirmation *pDst,
+						 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_key_auth = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->key_auth, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fils_key_confirmation. */
+
+#define SigIefils_key_confirmation (0x0087)
+
+
+uint32_t dot11f_unpack_ie_fils_nonce(tpAniSirGlobal pCtx,
+				     uint8_t *pBuf,
+				     uint8_t ielen,
+				     tDot11fIEfils_nonce *pDst,
+				     bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 16)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->nonce, pBuf, 16);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fils_nonce. */
+
+#define SigIefils_nonce (0x0088)
+
+
+uint32_t dot11f_unpack_ie_fils_public_key(tpAniSirGlobal pCtx,
+					  uint8_t *pBuf,
+					  uint8_t ielen,
+					  tDot11fIEfils_public_key *pDst,
+					  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->key_type = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	pDst->num_public_key = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->public_key, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fils_public_key. */
+
+#define SigIefils_public_key (0x0089)
+
+
+uint32_t dot11f_unpack_ie_fils_session(tpAniSirGlobal pCtx,
+				       uint8_t *pBuf,
+				       uint8_t ielen,
+				       tDot11fIEfils_session *pDst,
+				       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 8)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->session, pBuf, 8);
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fils_session. */
+
+#define SigIefils_session (0x008a)
+
+
+uint32_t dot11f_unpack_ie_fils_wrapped_data(tpAniSirGlobal pCtx,
+					    uint8_t *pBuf,
+					    uint8_t ielen,
+					    tDot11fIEfils_wrapped_data *pDst,
+					    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_wrapped_data = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->wrapped_data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fils_wrapped_data. */
+
+#define SigIefils_wrapped_data (0x008b)
+
+
+uint32_t dot11f_unpack_ie_fragment_ie(tpAniSirGlobal pCtx,
+				      uint8_t *pBuf,
+				      uint8_t ielen,
+				      tDot11fIEfragment_ie *pDst,
+				      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_data = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_fragment_ie. */
+
+#define SigIefragment_ie (0x008c)
+
+
+uint32_t dot11f_unpack_ie_he_cap(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIEhe_cap *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t tmp77__;
+	uint16_t tmp78__;
+	uint32_t tmp79__;
+	uint32_t tmp80__;
+	uint16_t tmp81__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &tmp77__, pBuf, 0);
+	pBuf += 4;
+	ielen -= 4;
+	pDst->htc_he = tmp77__ >> 0 & 0x1;
+	pDst->twt_request = tmp77__ >> 1 & 0x1;
+	pDst->twt_responder = tmp77__ >> 2 & 0x1;
+	pDst->fragmentation = tmp77__ >> 3 & 0x3;
+	pDst->max_num_frag_msdu_amsdu_exp = tmp77__ >> 5 & 0x7;
+	pDst->min_frag_size = tmp77__ >> 8 & 0x3;
+	pDst->trigger_frm_mac_pad = tmp77__ >> 10 & 0x3;
+	pDst->multi_tid_aggr_rx_supp = tmp77__ >> 12 & 0x7;
+	pDst->he_link_adaptation = tmp77__ >> 15 & 0x3;
+	pDst->all_ack = tmp77__ >> 17 & 0x1;
+	pDst->trigd_rsp_sched = tmp77__ >> 18 & 0x1;
+	pDst->a_bsr = tmp77__ >> 19 & 0x1;
+	pDst->broadcast_twt = tmp77__ >> 20 & 0x1;
+	pDst->ba_32bit_bitmap = tmp77__ >> 21 & 0x1;
+	pDst->mu_cascade = tmp77__ >> 22 & 0x1;
+	pDst->ack_enabled_multitid = tmp77__ >> 23 & 0x1;
+	pDst->reserved = tmp77__ >> 24 & 0x1;
+	pDst->omi_a_ctrl = tmp77__ >> 25 & 0x1;
+	pDst->ofdma_ra = tmp77__ >> 26 & 0x1;
+	pDst->max_ampdu_len_exp_ext = tmp77__ >> 27 & 0x3;
+	pDst->amsdu_frag = tmp77__ >> 29 & 0x1;
+	pDst->flex_twt_sched = tmp77__ >> 30 & 0x1;
+	pDst->rx_ctrl_frame = tmp77__ >> 31 & 0x1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp78__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->bsrp_ampdu_aggr = tmp78__ >> 0 & 0x1;
+	pDst->qtp = tmp78__ >> 1 & 0x1;
+	pDst->a_bqr = tmp78__ >> 2 & 0x1;
+	pDst->spatial_reuse_param_rspder = tmp78__ >> 3 & 0x1;
+	pDst->ndp_feedback_supp = tmp78__ >> 4 & 0x1;
+	pDst->ops_supp = tmp78__ >> 5 & 0x1;
+	pDst->amsdu_in_ampdu = tmp78__ >> 6 & 0x1;
+	pDst->multi_tid_aggr_tx_supp = tmp78__ >> 7 & 0x7;
+	pDst->he_sub_ch_sel_tx_supp = tmp78__ >> 10 & 0x1;
+	pDst->ul_2x996_tone_ru_supp = tmp78__ >> 11 & 0x1;
+	pDst->om_ctrl_ul_mu_data_dis_rx = tmp78__ >> 12 & 0x1;
+	pDst->reserved1 = tmp78__ >> 13 & 0x7;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &tmp79__, pBuf, 0);
+	pBuf += 4;
+	ielen -= 4;
+	pDst->reserved2 = tmp79__ >> 0 & 0x1;
+	pDst->chan_width_0 = tmp79__ >> 1 & 0x1;
+	pDst->chan_width_1 = tmp79__ >> 2 & 0x1;
+	pDst->chan_width_2 = tmp79__ >> 3 & 0x1;
+	pDst->chan_width_3 = tmp79__ >> 4 & 0x1;
+	pDst->chan_width_4 = tmp79__ >> 5 & 0x1;
+	pDst->chan_width_5 = tmp79__ >> 6 & 0x1;
+	pDst->chan_width_6 = tmp79__ >> 7 & 0x1;
+	pDst->rx_pream_puncturing = tmp79__ >> 8 & 0xf;
+	pDst->device_class = tmp79__ >> 12 & 0x1;
+	pDst->ldpc_coding = tmp79__ >> 13 & 0x1;
+	pDst->he_1x_ltf_800_gi_ppdu = tmp79__ >> 14 & 0x1;
+	pDst->midamble_tx_rx_max_nsts = tmp79__ >> 15 & 0x3;
+	pDst->he_4x_ltf_3200_gi_ndp = tmp79__ >> 17 & 0x1;
+	pDst->tx_stbc_lt_80mhz = tmp79__ >> 18 & 0x1;
+	pDst->rx_stbc_lt_80mhz = tmp79__ >> 19 & 0x1;
+	pDst->doppler = tmp79__ >> 20 & 0x3;
+	pDst->ul_mu = tmp79__ >> 22 & 0x3;
+	pDst->dcm_enc_tx = tmp79__ >> 24 & 0x7;
+	pDst->dcm_enc_rx = tmp79__ >> 27 & 0x7;
+	pDst->ul_he_mu = tmp79__ >> 30 & 0x1;
+	pDst->su_beamformer = tmp79__ >> 31 & 0x1;
+	if (unlikely(ielen < 4)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohl(pCtx, &tmp80__, pBuf, 0);
+	pBuf += 4;
+	ielen -= 4;
+	pDst->su_beamformee = tmp80__ >> 0 & 0x1;
+	pDst->mu_beamformer = tmp80__ >> 1 & 0x1;
+	pDst->bfee_sts_lt_80 = tmp80__ >> 2 & 0x7;
+	pDst->bfee_sts_gt_80 = tmp80__ >> 5 & 0x7;
+	pDst->num_sounding_lt_80 = tmp80__ >> 8 & 0x7;
+	pDst->num_sounding_gt_80 = tmp80__ >> 11 & 0x7;
+	pDst->su_feedback_tone16 = tmp80__ >> 14 & 0x1;
+	pDst->mu_feedback_tone16 = tmp80__ >> 15 & 0x1;
+	pDst->codebook_su = tmp80__ >> 16 & 0x1;
+	pDst->codebook_mu = tmp80__ >> 17 & 0x1;
+	pDst->beamforming_feedback = tmp80__ >> 18 & 0x7;
+	pDst->he_er_su_ppdu = tmp80__ >> 21 & 0x1;
+	pDst->dl_mu_mimo_part_bw = tmp80__ >> 22 & 0x1;
+	pDst->ppet_present = tmp80__ >> 23 & 0x1;
+	pDst->srp = tmp80__ >> 24 & 0x1;
+	pDst->power_boost = tmp80__ >> 25 & 0x1;
+	pDst->he_ltf_800_gi_4x = tmp80__ >> 26 & 0x1;
+	pDst->max_nc = tmp80__ >> 27 & 0x7;
+	pDst->tx_stbc_gt_80mhz = tmp80__ >> 30 & 0x1;
+	pDst->rx_stbc_gt_80mhz = tmp80__ >> 31 & 0x1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp81__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->er_he_ltf_800_gi_4x = tmp81__ >> 0 & 0x1;
+	pDst->he_ppdu_20_in_40Mhz_2G = tmp81__ >> 1 & 0x1;
+	pDst->he_ppdu_20_in_160_80p80Mhz = tmp81__ >> 2 & 0x1;
+	pDst->he_ppdu_80_in_160_80p80Mhz = tmp81__ >> 3 & 0x1;
+	pDst->er_1x_he_ltf_gi = tmp81__ >> 4 & 0x1;
+	pDst->midamble_tx_rx_1x_he_ltf = tmp81__ >> 5 & 0x1;
+	pDst->dcm_max_bw = tmp81__ >> 6 & 0x3;
+	pDst->longer_than_16_he_sigb_ofdm_sym = tmp81__ >> 8 & 0x1;
+	pDst->non_trig_cqi_feedback = tmp81__ >> 9 & 0x1;
+	pDst->tx_1024_qam_lt_242_tone_ru = tmp81__ >> 10 & 0x1;
+	pDst->rx_1024_qam_lt_242_tone_ru = tmp81__ >> 11 & 0x1;
+	pDst->rx_full_bw_su_he_mu_compress_sigb = tmp81__ >> 12 & 0x1;
+	pDst->rx_full_bw_su_he_mu_non_cmpr_sigb = tmp81__ >> 13 & 0x1;
+	pDst->reserved3 = tmp81__ >> 14 & 0x3;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->reserved4 = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->rx_he_mcs_map_lt_80, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &pDst->tx_he_mcs_map_lt_80, pBuf, 0);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	if (unlikely(ielen < pDst->chan_width_2 * 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (pDst->chan_width_2 > 1) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->rx_he_mcs_map_160, pBuf, (pDst->chan_width_2 * 2));
+	pBuf += (pDst->chan_width_2 * 2);
+	ielen -= (pDst->chan_width_2 * 2);
+	if (unlikely(ielen < pDst->chan_width_2 * 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (pDst->chan_width_2 > 1) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->tx_he_mcs_map_160, pBuf, (pDst->chan_width_2 * 2));
+	pBuf += (pDst->chan_width_2 * 2);
+	ielen -= (pDst->chan_width_2 * 2);
+	if (unlikely(ielen < pDst->chan_width_3 * 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (pDst->chan_width_3 > 1) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->rx_he_mcs_map_80_80, pBuf, (pDst->chan_width_3 * 2));
+	pBuf += (pDst->chan_width_3 * 2);
+	ielen -= (pDst->chan_width_3 * 2);
+	if (unlikely(ielen < pDst->chan_width_3 * 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	if (pDst->chan_width_3 > 1) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->tx_he_mcs_map_80_80, pBuf, (pDst->chan_width_3 * 2));
+	pBuf += (pDst->chan_width_3 * 2);
+	ielen -= (pDst->chan_width_3 * 2);
+	switch (pDst->ppet_present) {
+	case 1:
+		pDst->ppet.ppe_threshold.num_ppe_th = (uint8_t)(ielen);
+		if (ielen > 25) {
+				pDst->present = 0;
+				return DOT11F_SKIPPED_BAD_IE;
+		}
+
+		DOT11F_MEMCPY(pCtx, pDst->ppet.ppe_threshold.ppe_th, pBuf, (ielen));
+		pBuf += (ielen);
+		ielen -= (ielen);
+		break;
+	}
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_he_cap. */
+
+#define SigIehe_cap (0x008d)
+
+
+uint32_t dot11f_unpack_ie_he_op(tpAniSirGlobal pCtx,
+				 uint8_t *pBuf,
+				 uint8_t ielen,
+				 tDot11fIEhe_op *pDst,
+				 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint16_t tmp82__;
+	uint8_t tmp83__;
+	uint8_t tmp84__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	framesntohs(pCtx, &tmp82__, pBuf, 0);
+	pBuf += 2;
+	ielen -= 2;
+	pDst->default_pe = tmp82__ >> 0 & 0x7;
+	pDst->twt_required = tmp82__ >> 3 & 0x1;
+	pDst->txop_rts_threshold = tmp82__ >> 4 & 0x3ff;
+	pDst->vht_oper_present = tmp82__ >> 14 & 0x1;
+	pDst->co_located_bss = tmp82__ >> 15 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp83__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->er_su_disable = tmp83__ >> 0 & 0x1;
+	pDst->reserved2 = tmp83__ >> 1 & 0x7f;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp84__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->bss_color = tmp84__ >> 0 & 0x3f;
+	pDst->partial_bss_col = tmp84__ >> 6 & 0x1;
+	pDst->bss_col_disabled = tmp84__ >> 7 & 0x1;
+	if (unlikely(ielen < 2)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->basic_mcs_nss, pBuf, 2);
+	pBuf += 2;
+	ielen -= (uint8_t)2;
+	switch (pDst->vht_oper_present) {
+	case 1:
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->vht_oper.info.chan_width = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->vht_oper.info.center_freq_seg0 = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->vht_oper.info.center_freq_seg1 = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		break;
+	}
+	switch (pDst->co_located_bss) {
+	case 1:
+		if (unlikely(ielen < 1)) {
+			pDst->present = 0;
+			return DOT11F_INCOMPLETE_IE;
+		}
+
+		pDst->maxbssid_ind.info.data = *pBuf;
+		pBuf += 1;
+		ielen -= (uint8_t)1;
+		break;
+	}
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_he_op. */
+
+#define SigIehe_op (0x008e)
+
+
+uint32_t dot11f_unpack_ie_hs20vendor_ie(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEhs20vendor_ie *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp85__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp85__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->dgaf_dis = tmp85__ >> 0 & 0x1;
+	pDst->hs_id_present = tmp85__ >> 1 & 0x3;
+	pDst->reserved = tmp85__ >> 3 & 0x1;
+	pDst->release_num = tmp85__ >> 4 & 0xf;
+	if (!ielen) {
+		return 0U;
+	} else {
+		switch (pDst->hs_id_present) {
+		case 1:
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->hs_id.pps_mo.pps_mo_id, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			break;
+		case 2:
+			if (unlikely(ielen < 2)) {
+				pDst->present = 0;
+				return DOT11F_INCOMPLETE_IE;
+			}
+
+			framesntohs(pCtx, &pDst->hs_id.anqp_domain.anqp_domain_id, pBuf, 0);
+			pBuf += 2;
+			ielen -= (uint8_t)2;
+			break;
+		}
+	}
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_hs20vendor_ie. */
+
+#define SigIehs20vendor_ie (0x008f)
+
+
+uint32_t dot11f_unpack_ie_ht2040_bss_coexistence(tpAniSirGlobal pCtx,
+						 uint8_t *pBuf,
+						 uint8_t ielen,
+						 tDot11fIEht2040_bss_coexistence *pDst,
+						 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp86__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp86__ = *pBuf;
+	pDst->info_request = tmp86__ >> 0 & 0x1;
+	pDst->forty_mhz_intolerant = tmp86__ >> 1 & 0x1;
+	pDst->twenty_mhz_bsswidth_req = tmp86__ >> 2 & 0x1;
+	pDst->obss_scan_exemption_req = tmp86__ >> 3 & 0x1;
+	pDst->obss_scan_exemption_grant = tmp86__ >> 4 & 0x1;
+	pDst->unused = tmp86__ >> 5 & 0x7;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ht2040_bss_coexistence. */
+
+#define SigIeht2040_bss_coexistence (0x0090)
+
+
+uint32_t dot11f_unpack_ie_ht2040_bss_intolerant_report(tpAniSirGlobal pCtx,
+						       uint8_t *pBuf,
+						       uint8_t ielen,
+						       tDot11fIEht2040_bss_intolerant_report *pDst,
+						       bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->operating_class = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	pDst->num_channel_list = (uint8_t)(ielen);
+	if (ielen > 50) {
+		pDst->present = 0;
+		return DOT11F_SKIPPED_BAD_IE;
+	}
+
+	DOT11F_MEMCPY(pCtx, pDst->channel_list, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_ht2040_bss_intolerant_report. */
+
+#define SigIeht2040_bss_intolerant_report (0x0091)
+
+
+uint32_t dot11f_unpack_ie_mu_edca_param_set(tpAniSirGlobal pCtx,
+					    uint8_t *pBuf,
+					    uint8_t ielen,
+					    tDot11fIEmu_edca_param_set *pDst,
+					    bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint8_t tmp87__;
+	uint8_t tmp88__;
+	uint8_t tmp89__;
+	uint8_t tmp90__;
+	uint8_t tmp91__;
+	uint8_t tmp92__;
+	uint8_t tmp93__;
+	uint8_t tmp94__;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->qos = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp87__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbe_aifsn = tmp87__ >> 0 & 0xf;
+	pDst->acbe_acm = tmp87__ >> 4 & 0x1;
+	pDst->acbe_aci = tmp87__ >> 5 & 0x3;
+	pDst->unused1 = tmp87__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp88__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbe_acwmin = tmp88__ >> 0 & 0xf;
+	pDst->acbe_acwmax = tmp88__ >> 4 & 0xf;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->acbe_muedca_timer = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp89__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbk_aifsn = tmp89__ >> 0 & 0xf;
+	pDst->acbk_acm = tmp89__ >> 4 & 0x1;
+	pDst->acbk_aci = tmp89__ >> 5 & 0x3;
+	pDst->unused2 = tmp89__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp90__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acbk_acwmin = tmp90__ >> 0 & 0xf;
+	pDst->acbk_acwmax = tmp90__ >> 4 & 0xf;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->acbk_muedca_timer = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp91__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvi_aifsn = tmp91__ >> 0 & 0xf;
+	pDst->acvi_acm = tmp91__ >> 4 & 0x1;
+	pDst->acvi_aci = tmp91__ >> 5 & 0x3;
+	pDst->unused3 = tmp91__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp92__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvi_acwmin = tmp92__ >> 0 & 0xf;
+	pDst->acvi_acwmax = tmp92__ >> 4 & 0xf;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->acvi_muedca_timer = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp93__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvo_aifsn = tmp93__ >> 0 & 0xf;
+	pDst->acvo_acm = tmp93__ >> 4 & 0x1;
+	pDst->acvo_aci = tmp93__ >> 5 & 0x3;
+	pDst->unused4 = tmp93__ >> 7 & 0x1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	tmp94__ = *pBuf;
+	pBuf += 1;
+	ielen -= 1;
+	pDst->acvo_acwmin = tmp94__ >> 0 & 0xf;
+	pDst->acvo_acwmax = tmp94__ >> 4 & 0xf;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->acvo_muedca_timer = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_mu_edca_param_set. */
+
+#define SigIemu_edca_param_set (0x0092)
+
+
+uint32_t dot11f_unpack_ie_osen_ie(tpAniSirGlobal pCtx,
+				  uint8_t *pBuf,
+				  uint8_t ielen,
+				  tDot11fIEosen_ie *pDst,
+				  bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	pDst->num_data = (uint8_t)(ielen);
+	DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_osen_ie. */
+
+#define SigIeosen_ie (0x0093)
+
+
+uint32_t dot11f_unpack_ie_sec_chan_offset_ele(tpAniSirGlobal pCtx,
+					      uint8_t *pBuf,
+					      uint8_t ielen,
+					      tDot11fIEsec_chan_offset_ele *pDst,
+					      bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->secondaryChannelOffset = *pBuf;
+	(void)pCtx;
+	return status;
+} /* End dot11f_unpack_ie_sec_chan_offset_ele. */
+
+#define SigIesec_chan_offset_ele (0x0094)
+
+
+static const tFFDefn FFS_vendor_vht_ie[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_vendor_vht_ie[] = {
+	{ offsetof(tDot11fIEvendor_vht_ie, VHTCaps), offsetof(tDot11fIEVHTCaps,
+	present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fIEvendor_vht_ie, VHTOperation),
+	offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+	0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTOPERATION, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_vendor_vht_ie(tpAniSirGlobal pCtx,
+					 uint8_t *pBuf,
+					 uint8_t ielen,
+					 tDot11fIEvendor_vht_ie *pDst,
+					 bool append_ie)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void) pBuf; (void)ielen; /* Shutup the compiler */
+	if (pDst->present)
+		status = DOT11F_DUPLICATE_IE;
+	pDst->present = 1;
+	if (unlikely(ielen < 1)) {
+		pDst->present = 0;
+		return DOT11F_INCOMPLETE_IE;
+	}
+
+	pDst->sub_type = *pBuf;
+	pBuf += 1;
+	ielen -= (uint8_t)1;
+	(void)pCtx;
+	status |= unpack_core(pCtx,
+				pBuf,
+				ielen,
+				FFS_vendor_vht_ie,
+				IES_vendor_vht_ie,
+				(uint8_t *)pDst,
+				sizeof(*pDst),
+				append_ie);
+	return status;
+} /* End dot11f_unpack_ie_vendor_vht_ie. */
+
+#define SigIevendor_vht_ie (0x0095)
+
+
+static const tFFDefn FFS_AddTSRequest[] = {
+	{ "Category", offsetof(tDot11fAddTSRequest, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fAddTSRequest, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fAddTSRequest, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_AddTSRequest[] = {
+	{ offsetof(tDot11fAddTSRequest, TSPEC), offsetof(tDot11fIETSPEC, present),
+	0, "TSPEC", 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TSPEC, 0, 1, },
+	{ offsetof(tDot11fAddTSRequest, TCLAS), offsetof(tDot11fIETCLAS, present),
+	offsetof(tDot11fAddTSRequest, num_TCLAS), "TCLAS", 2, 7, 45, SigIeTCLAS,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, 0, },
+	{ offsetof(tDot11fAddTSRequest, TCLASSPROC),
+	offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC",
+	0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TCLASSPROC, 0, 0, },
+	{ offsetof(tDot11fAddTSRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+	present), 0, "WMMTSPEC", 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+	5, DOT11F_EID_WMMTSPEC, 0, 0, },
+	{ offsetof(tDot11fAddTSRequest, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS,
+	present), offsetof(tDot11fAddTSRequest, num_WMMTCLAS), "WMMTCLAS",
+	2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6},
+	5, DOT11F_EID_WMMTCLAS, 0, 0, },
+	{ offsetof(tDot11fAddTSRequest, WMMTCLASPROC),
+	offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC",
+	0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7},
+	5, DOT11F_EID_WMMTCLASPROC, 0, 0, },
+	{ offsetof(tDot11fAddTSRequest, ESETrafStrmRateSet),
+	offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet",
+	0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0},
+	4, DOT11F_EID_ESETRAFSTRMRATESET, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_add_ts_request(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fAddTSRequest *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_AddTSRequest, IES_AddTSRequest,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_add_ts_request. */
+
+static const tFFDefn FFS_AddTSResponse[] = {
+	{ "Category", offsetof(tDot11fAddTSResponse, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fAddTSResponse, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fAddTSResponse, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "Status", offsetof(tDot11fAddTSResponse, Status), SigFfStatus,
+	DOT11F_FF_STATUS_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_AddTSResponse[] = {
+	{ offsetof(tDot11fAddTSResponse, TSDelay), offsetof(tDot11fIETSDelay,
+	present), 0, "TSDelay", 0, 6, 6, SigIeTSDelay, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TSDELAY, 0, 1, },
+	{ offsetof(tDot11fAddTSResponse, TSPEC), offsetof(tDot11fIETSPEC,
+	present), 0, "TSPEC", 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TSPEC, 0, 1, },
+	{ offsetof(tDot11fAddTSResponse, TCLAS), offsetof(tDot11fIETCLAS,
+	present), offsetof(tDot11fAddTSResponse, num_TCLAS), "TCLAS",
+	2, 7, 45, SigIeTCLAS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, 0, },
+	{ offsetof(tDot11fAddTSResponse, TCLASSPROC),
+	offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC",
+	0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TCLASSPROC, 0, 0, },
+	{ offsetof(tDot11fAddTSResponse, Schedule), offsetof(tDot11fIESchedule,
+	present), 0, "Schedule", 0, 16, 16, SigIeSchedule, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SCHEDULE, 0, 0, },
+	{ offsetof(tDot11fAddTSResponse, WMMTSDelay),
+	offsetof(tDot11fIEWMMTSDelay, present), 0, "WMMTSDelay",
+	0, 12, 12, SigIeWMMTSDelay, {0, 80, 242, 2, 8},
+	5, DOT11F_EID_WMMTSDELAY, 0, 0, },
+	{ offsetof(tDot11fAddTSResponse, WMMSchedule),
+	offsetof(tDot11fIEWMMSchedule, present), 0, "WMMSchedule",
+	0, 22, 22, SigIeWMMSchedule, {0, 80, 242, 2, 9},
+	5, DOT11F_EID_WMMSCHEDULE, 0, 0, },
+	{ offsetof(tDot11fAddTSResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+	present), 0, "WMMTSPEC", 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+	5, DOT11F_EID_WMMTSPEC, 0, 0, },
+	{ offsetof(tDot11fAddTSResponse, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS,
+	present), offsetof(tDot11fAddTSResponse, num_WMMTCLAS), "WMMTCLAS",
+	2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6},
+	5, DOT11F_EID_WMMTCLAS, 0, 0, },
+	{ offsetof(tDot11fAddTSResponse, WMMTCLASPROC),
+	offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC",
+	0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7},
+	5, DOT11F_EID_WMMTCLASPROC, 0, 0, },
+	{ offsetof(tDot11fAddTSResponse, ESETrafStrmMet),
+	offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+	0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+	4, DOT11F_EID_ESETRAFSTRMMET, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_add_ts_response(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fAddTSResponse *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_AddTSResponse, IES_AddTSResponse,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_add_ts_response. */
+
+static const tFFDefn FFS_AssocRequest[] = {
+	{ "Capabilities", offsetof(tDot11fAssocRequest, Capabilities),
+	SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+	{ "ListenInterval", offsetof(tDot11fAssocRequest, ListenInterval),
+	SigFfListenInterval, DOT11F_FF_LISTENINTERVAL_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_AssocRequest[] = {
+	{ offsetof(tDot11fAssocRequest, SSID), offsetof(tDot11fIESSID, present), 0,
+	"SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 0, 1, },
+	{ offsetof(tDot11fAssocRequest, SuppRates), offsetof(tDot11fIESuppRates,
+	present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 1, },
+	{ offsetof(tDot11fAssocRequest, OperatingMode),
+	offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+	0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OPERATINGMODE, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, PowerCaps), offsetof(tDot11fIEPowerCaps,
+	present), 0, "PowerCaps", 0, 4, 4, SigIePowerCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_POWERCAPS, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, SuppChannels),
+	offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels",
+	0, 2, 98, SigIeSuppChannels, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPCHANNELS, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, HTCaps), offsetof(tDot11fIEHTCaps,
+	present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, QOSCapsStation),
+	offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation",
+	0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QOSCAPSSTATION, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, RSNOpaque), offsetof(tDot11fIERSNOpaque,
+	present), 0, "RSNOpaque", 0, 2, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RSNOPAQUE, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, ExtSuppRates),
+	offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+	0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, MobilityDomain),
+	offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+	0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MOBILITYDOMAIN, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, SuppOperatingClasses),
+	offsetof(tDot11fIESuppOperatingClasses, present), 0,
+	"SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, WAPIOpaque),
+	offsetof(tDot11fIEWAPIOpaque, present), 0, "WAPIOpaque",
+	0, 8, 255, SigIeWAPIOpaque, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_WAPIOPAQUE, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, WAPI), offsetof(tDot11fIEWAPI, present), 0,
+	"WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_WAPI, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, RRMEnabledCap),
+	offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+	0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RRMENABLEDCAP, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet,
+	present), 0, "QosMapSet", 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QOSMAPSET, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, ExtCap), offsetof(tDot11fIEExtCap,
+	present), 0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, VHTCaps), offsetof(tDot11fIEVHTCaps,
+	present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, fils_session),
+	offsetof(tDot11fIEfils_session, present), 0, "fils_session",
+	0, 10, 10, SigIefils_session, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_SESSION, 4, 0, },
+	{ offsetof(tDot11fAssocRequest, fils_public_key),
+	offsetof(tDot11fIEfils_public_key, present), 0, "fils_public_key",
+	0, 3, 258, SigIefils_public_key, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_PUBLIC_KEY, 12, 0, },
+	{ offsetof(tDot11fAssocRequest, fils_key_confirmation),
+	offsetof(tDot11fIEfils_key_confirmation, present), 0,
+	"fils_key_confirmation", 0, 2, 257, SigIefils_key_confirmation,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_FILS_KEY_CONFIRMATION, 3, 0, },
+	{ offsetof(tDot11fAssocRequest, fils_hlp_container),
+	offsetof(tDot11fIEfils_hlp_container, present), 0, "fils_hlp_container",
+	0, 14, 269, SigIefils_hlp_container, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_HLP_CONTAINER, 5, 0, },
+	{ offsetof(tDot11fAssocRequest, fragment_ie),
+	offsetof(tDot11fIEfragment_ie, present), 0, "fragment_ie",
+	0, 2, 257, SigIefragment_ie, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FRAGMENT_IE, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, dh_parameter_element),
+	offsetof(tDot11fIEdh_parameter_element, present), 0,
+	"dh_parameter_element", 0, 4, 259, SigIedh_parameter_element,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_DH_PARAMETER_ELEMENT, 32, 0, },
+	{ offsetof(tDot11fAssocRequest, WPAOpaque), offsetof(tDot11fIEWPAOpaque,
+	present), 0, "WPAOpaque", 0, 8, 255, SigIeWPAOpaque, {0, 80, 242, 1, 0},
+	4, DOT11F_EID_WPAOPAQUE, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, WMMCaps), offsetof(tDot11fIEWMMCaps,
+	present), 0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+	5, DOT11F_EID_WMMCAPS, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, WMMInfoStation),
+	offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation",
+	0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0},
+	5, DOT11F_EID_WMMINFOSTATION, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, WscIEOpaque),
+	offsetof(tDot11fIEWscIEOpaque, present), 0, "WscIEOpaque",
+	0, 8, 255, SigIeWscIEOpaque, {0, 80, 242, 4, 0},
+	4, DOT11F_EID_WSCIEOPAQUE, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, ESERadMgmtCap),
+	offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+	0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+	4, DOT11F_EID_ESERADMGMTCAP, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, ESEVersion),
+	offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion",
+	0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+	4, DOT11F_EID_ESEVERSION, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, P2PIEOpaque),
+	offsetof(tDot11fIEP2PIEOpaque, present), 0, "P2PIEOpaque",
+	0, 8, 255, SigIeP2PIEOpaque, {80, 111, 154, 9, 0},
+	4, DOT11F_EID_P2PIEOPAQUE, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, WFDIEOpaque),
+	offsetof(tDot11fIEWFDIEOpaque, present), 0, "WFDIEOpaque",
+	0, 8, 255, SigIeWFDIEOpaque, {80, 111, 154, 10, 0},
+	4, DOT11F_EID_WFDIEOPAQUE, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, vendor_vht_ie),
+	offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie",
+	0, 7, 28, SigIevendor_vht_ie, {0, 144, 76, 4, 0},
+	4, DOT11F_EID_VENDOR_VHT_IE, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, hs20vendor_ie),
+	offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie",
+	0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0},
+	4, DOT11F_EID_HS20VENDOR_IE, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, QCN_IE), offsetof(tDot11fIEQCN_IE,
+	present), 0, "QCN_IE", 0, 10, 10, SigIeQCN_IE, {140, 253, 240, 1, 0},
+	4, DOT11F_EID_QCN_IE, 0, 0, },
+	{ offsetof(tDot11fAssocRequest, he_cap), offsetof(tDot11fIEhe_cap,
+	present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_CAP, 35, 0, },
+	{ offsetof(tDot11fAssocRequest, osen_ie), offsetof(tDot11fIEosen_ie,
+	present), 0, "osen_ie", 0, 6, 261, SigIeosen_ie, {80, 111, 154, 18, 0},
+	4, DOT11F_EID_OSEN_IE, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_assoc_request(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fAssocRequest *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_AssocRequest, IES_AssocRequest,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_assoc_request. */
+
+static const tFFDefn FFS_AssocResponse[] = {
+	{ "Capabilities", offsetof(tDot11fAssocResponse, Capabilities),
+	SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+	{ "Status", offsetof(tDot11fAssocResponse, Status), SigFfStatus,
+	DOT11F_FF_STATUS_LEN, },
+	{ "AID", offsetof(tDot11fAssocResponse, AID), SigFfAID,
+	DOT11F_FF_AID_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_AssocResponse[] = {
+	{ offsetof(tDot11fAssocResponse, SuppRates), offsetof(tDot11fIESuppRates,
+	present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 1, },
+	{ offsetof(tDot11fAssocResponse, ExtSuppRates),
+	offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+	0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, EDCAParamSet),
+	offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet",
+	0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EDCAPARAMSET, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, RCPIIE), offsetof(tDot11fIERCPIIE,
+	present), 0, "RCPIIE", 0, 3, 3, SigIeRCPIIE, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RCPIIE, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, RSNIIE), offsetof(tDot11fIERSNIIE,
+	present), 0, "RSNIIE", 0, 3, 3, SigIeRSNIIE, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RSNIIE, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, RRMEnabledCap),
+	offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+	0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RRMENABLEDCAP, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, MobilityDomain),
+	offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+	0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MOBILITYDOMAIN, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, FTInfo), offsetof(tDot11fIEFTInfo,
+	present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FTINFO, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, RICDataDesc),
+	offsetof(tDot11fIERICDataDesc, present),
+	offsetof(tDot11fAssocResponse, num_RICDataDesc), "RICDataDesc",
+	2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RICDATADESC, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, WPA), offsetof(tDot11fIEWPA, present), 0,
+	"WPA", 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, TimeoutInterval),
+	offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+	0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TIMEOUTINTERVAL, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, HTCaps), offsetof(tDot11fIEHTCaps,
+	present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, HTInfo), offsetof(tDot11fIEHTInfo,
+	present), 0, "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTINFO, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, WMMParams), offsetof(tDot11fIEWMMParams,
+	present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+	5, DOT11F_EID_WMMPARAMS, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, WMMCaps), offsetof(tDot11fIEWMMCaps,
+	present), 0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+	5, DOT11F_EID_WMMCAPS, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, ESERadMgmtCap),
+	offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+	0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+	4, DOT11F_EID_ESERADMGMTCAP, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, ESETrafStrmMet),
+	offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+	0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+	4, DOT11F_EID_ESETRAFSTRMMET, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, ESETxmitPower),
+	offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+	0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+	4, DOT11F_EID_ESETXMITPOWER, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+	present), offsetof(tDot11fAssocResponse, num_WMMTSPEC), "WMMTSPEC",
+	4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+	5, DOT11F_EID_WMMTSPEC, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, WscAssocRes),
+	offsetof(tDot11fIEWscAssocRes, present), 0, "WscAssocRes",
+	0, 6, 37, SigIeWscAssocRes, {0, 80, 242, 4, 0},
+	4, DOT11F_EID_WSCASSOCRES, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, P2PAssocRes),
+	offsetof(tDot11fIEP2PAssocRes, present), 0, "P2PAssocRes",
+	0, 6, 17, SigIeP2PAssocRes, {80, 111, 154, 9, 0},
+	4, DOT11F_EID_P2PASSOCRES, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, VHTCaps), offsetof(tDot11fIEVHTCaps,
+	present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, VHTOperation),
+	offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+	0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTOPERATION, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, ExtCap), offsetof(tDot11fIEExtCap,
+	present), 0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, OBSSScanParameters),
+	offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+	0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OBSSSCANPARAMETERS, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet,
+	present), 0, "QosMapSet", 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QOSMAPSET, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, fils_session),
+	offsetof(tDot11fIEfils_session, present), 0, "fils_session",
+	0, 10, 10, SigIefils_session, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_SESSION, 4, 0, },
+	{ offsetof(tDot11fAssocResponse, fils_public_key),
+	offsetof(tDot11fIEfils_public_key, present), 0, "fils_public_key",
+	0, 3, 258, SigIefils_public_key, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_PUBLIC_KEY, 12, 0, },
+	{ offsetof(tDot11fAssocResponse, fils_key_confirmation),
+	offsetof(tDot11fIEfils_key_confirmation, present), 0,
+	"fils_key_confirmation", 0, 2, 257, SigIefils_key_confirmation,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_FILS_KEY_CONFIRMATION, 3, 0, },
+	{ offsetof(tDot11fAssocResponse, fils_hlp_container),
+	offsetof(tDot11fIEfils_hlp_container, present), 0, "fils_hlp_container",
+	0, 14, 269, SigIefils_hlp_container, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_HLP_CONTAINER, 5, 0, },
+	{ offsetof(tDot11fAssocResponse, fragment_ie),
+	offsetof(tDot11fIEfragment_ie, present), 0, "fragment_ie",
+	0, 2, 257, SigIefragment_ie, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FRAGMENT_IE, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, fils_kde), offsetof(tDot11fIEfils_kde,
+	present), 0, "fils_kde", 0, 10, 265, SigIefils_kde, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_KDE, 7, 0, },
+	{ offsetof(tDot11fAssocResponse, vendor_vht_ie),
+	offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie",
+	0, 7, 28, SigIevendor_vht_ie, {0, 144, 76, 4, 0},
+	4, DOT11F_EID_VENDOR_VHT_IE, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, QCN_IE), offsetof(tDot11fIEQCN_IE,
+	present), 0, "QCN_IE", 0, 10, 10, SigIeQCN_IE, {140, 253, 240, 1, 0},
+	4, DOT11F_EID_QCN_IE, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, he_cap), offsetof(tDot11fIEhe_cap,
+	present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_CAP, 35, 0, },
+	{ offsetof(tDot11fAssocResponse, he_op), offsetof(tDot11fIEhe_op,
+	present), 0, "he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_OP, 36, 0, },
+	{ offsetof(tDot11fAssocResponse, bss_color_change),
+	offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change",
+	0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
+	{ offsetof(tDot11fAssocResponse, mu_edca_param_set),
+	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 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,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fAssocResponse *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_AssocResponse, IES_AssocResponse,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_assoc_response. */
+
+static const tFFDefn FFS_Authentication[] = {
+	{ "AuthAlgo", offsetof(tDot11fAuthentication, AuthAlgo), SigFfAuthAlgo,
+	DOT11F_FF_AUTHALGO_LEN, },
+	{ "AuthSeqNo", offsetof(tDot11fAuthentication, AuthSeqNo), SigFfAuthSeqNo,
+	DOT11F_FF_AUTHSEQNO_LEN, },
+	{ "Status", offsetof(tDot11fAuthentication, Status), SigFfStatus,
+	DOT11F_FF_STATUS_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_Authentication[] = {
+	{ offsetof(tDot11fAuthentication, ChallengeText),
+	offsetof(tDot11fIEChallengeText, present), 0, "ChallengeText",
+	0, 3, 255, SigIeChallengeText, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_CHALLENGETEXT, 0, 0, },
+	{ offsetof(tDot11fAuthentication, RSNOpaque),
+	offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque",
+	0, 2, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RSNOPAQUE, 0, 0, },
+	{ offsetof(tDot11fAuthentication, MobilityDomain),
+	offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+	0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MOBILITYDOMAIN, 0, 0, },
+	{ offsetof(tDot11fAuthentication, FTInfo), offsetof(tDot11fIEFTInfo,
+	present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FTINFO, 0, 0, },
+	{ offsetof(tDot11fAuthentication, TimeoutInterval),
+	offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+	0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TIMEOUTINTERVAL, 0, 0, },
+	{ offsetof(tDot11fAuthentication, RICDataDesc),
+	offsetof(tDot11fIERICDataDesc, present),
+	offsetof(tDot11fAuthentication, num_RICDataDesc), "RICDataDesc",
+	2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RICDATADESC, 0, 0, },
+	{ offsetof(tDot11fAuthentication, fils_nonce),
+	offsetof(tDot11fIEfils_nonce, present), 0, "fils_nonce",
+	0, 18, 18, SigIefils_nonce, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_NONCE, 13, 0, },
+	{ offsetof(tDot11fAuthentication, fils_session),
+	offsetof(tDot11fIEfils_session, present), 0, "fils_session",
+	0, 10, 10, SigIefils_session, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_SESSION, 4, 0, },
+	{ offsetof(tDot11fAuthentication, fils_wrapped_data),
+	offsetof(tDot11fIEfils_wrapped_data, present), 0, "fils_wrapped_data",
+	0, 2, 257, SigIefils_wrapped_data, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_WRAPPED_DATA, 8, 0, },
+	{ offsetof(tDot11fAuthentication, fils_assoc_delay_info),
+	offsetof(tDot11fIEfils_assoc_delay_info, present), 0,
+	"fils_assoc_delay_info", 0, 3, 3, SigIefils_assoc_delay_info,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_FILS_ASSOC_DELAY_INFO, 1, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_authentication(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fAuthentication *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_Authentication, IES_Authentication,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_authentication. */
+
+static const tFFDefn FFS_Beacon[] = {
+	{ "TimeStamp", offsetof(tDot11fBeacon, TimeStamp), SigFfTimeStamp,
+	DOT11F_FF_TIMESTAMP_LEN, },
+	{ "BeaconInterval", offsetof(tDot11fBeacon, BeaconInterval),
+	SigFfBeaconInterval, DOT11F_FF_BEACONINTERVAL_LEN, },
+	{ "Capabilities", offsetof(tDot11fBeacon, Capabilities),
+	SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_Beacon[] = {
+	{ offsetof(tDot11fBeacon, SSID), offsetof(tDot11fIESSID, present), 0,
+	"SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 0, 1, },
+	{ offsetof(tDot11fBeacon, SuppRates), offsetof(tDot11fIESuppRates,
+	present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 1, },
+	{ offsetof(tDot11fBeacon, FHParamSet), offsetof(tDot11fIEFHParamSet,
+	present), 0, "FHParamSet", 0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FHPARAMSET, 0, 0, },
+	{ offsetof(tDot11fBeacon, DSParams), offsetof(tDot11fIEDSParams, present),
+	0, "DSParams", 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_DSPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeacon, CFParams), offsetof(tDot11fIECFParams, present),
+	0, "CFParams", 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_CFPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeacon, IBSSParams), offsetof(tDot11fIEIBSSParams,
+	present), 0, "IBSSParams", 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_IBSSPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeacon, TIM), offsetof(tDot11fIETIM, present), 0, "TIM",
+	0, 6, 256, SigIeTIM, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIM, 0, 0, },
+	{ offsetof(tDot11fBeacon, Country), offsetof(tDot11fIECountry, present), 0,
+	"Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_COUNTRY, 0, 0, },
+	{ offsetof(tDot11fBeacon, FHParams), offsetof(tDot11fIEFHParams, present),
+	0, "FHParams", 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FHPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeacon, FHPattTable), offsetof(tDot11fIEFHPattTable,
+	present), 0, "FHPattTable", 0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FHPATTTABLE, 0, 0, },
+	{ offsetof(tDot11fBeacon, PowerConstraints),
+	offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints",
+	0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_POWERCONSTRAINTS, 0, 0, },
+	{ offsetof(tDot11fBeacon, ChanSwitchAnn),
+	offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn",
+	0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_CHANSWITCHANN, 0, 0, },
+	{ offsetof(tDot11fBeacon, ext_chan_switch_ann),
+	offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann",
+	0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, 0, },
+	{ offsetof(tDot11fBeacon, SuppOperatingClasses),
+	offsetof(tDot11fIESuppOperatingClasses, present), 0,
+	"SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, 0, },
+	{ offsetof(tDot11fBeacon, Quiet), offsetof(tDot11fIEQuiet, present), 0,
+	"Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QUIET, 0, 0, },
+	{ offsetof(tDot11fBeacon, TPCReport), offsetof(tDot11fIETPCReport,
+	present), 0, "TPCReport", 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TPCREPORT, 0, 0, },
+	{ offsetof(tDot11fBeacon, ERPInfo), offsetof(tDot11fIEERPInfo, present), 0,
+	"ERPInfo", 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_ERPINFO, 0, 0, },
+	{ offsetof(tDot11fBeacon, ExtSuppRates), offsetof(tDot11fIEExtSuppRates,
+	present), 0, "ExtSuppRates", 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fBeacon, RSN), offsetof(tDot11fIERSN, present), 0, "RSN",
+	0, 4, 132, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, 0, },
+	{ offsetof(tDot11fBeacon, QBSSLoad), offsetof(tDot11fIEQBSSLoad, present),
+	0, "QBSSLoad", 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QBSSLOAD, 0, 0, },
+	{ offsetof(tDot11fBeacon, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet,
+	present), 0, "EDCAParamSet", 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EDCAPARAMSET, 0, 0, },
+	{ offsetof(tDot11fBeacon, QOSCapsAp), offsetof(tDot11fIEQOSCapsAp,
+	present), 0, "QOSCapsAp", 0, 3, 3, SigIeQOSCapsAp, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QOSCAPSAP, 0, 0, },
+	{ offsetof(tDot11fBeacon, APChannelReport),
+	offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport",
+	0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_APCHANNELREPORT, 0, 0, },
+	{ offsetof(tDot11fBeacon, RRMEnabledCap),
+	offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+	0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RRMENABLEDCAP, 0, 0, },
+	{ offsetof(tDot11fBeacon, MobilityDomain),
+	offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+	0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MOBILITYDOMAIN, 0, 0, },
+	{ offsetof(tDot11fBeacon, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA",
+	0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, 0, },
+	{ offsetof(tDot11fBeacon, HTCaps), offsetof(tDot11fIEHTCaps, present), 0,
+	"HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fBeacon, HTInfo), offsetof(tDot11fIEHTInfo, present), 0,
+	"HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTINFO, 0, 0, },
+	{ offsetof(tDot11fBeacon, sec_chan_offset_ele),
+	offsetof(tDot11fIEsec_chan_offset_ele, present), 0, "sec_chan_offset_ele",
+	0, 3, 3, SigIesec_chan_offset_ele, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SEC_CHAN_OFFSET_ELE, 0, 0, },
+	{ offsetof(tDot11fBeacon, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp,
+	present), 0, "WMMInfoAp", 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0},
+	5, DOT11F_EID_WMMINFOAP, 0, 0, },
+	{ offsetof(tDot11fBeacon, WMMParams), offsetof(tDot11fIEWMMParams,
+	present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+	5, DOT11F_EID_WMMPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeacon, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0,
+	"WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+	5, DOT11F_EID_WMMCAPS, 0, 0, },
+	{ offsetof(tDot11fBeacon, WAPI), offsetof(tDot11fIEWAPI, present), 0,
+	"WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_WAPI, 0, 0, },
+	{ offsetof(tDot11fBeacon, ESERadMgmtCap),
+	offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+	0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+	4, DOT11F_EID_ESERADMGMTCAP, 0, 0, },
+	{ offsetof(tDot11fBeacon, ESETrafStrmMet),
+	offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+	0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+	4, DOT11F_EID_ESETRAFSTRMMET, 0, 0, },
+	{ offsetof(tDot11fBeacon, ESETxmitPower),
+	offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+	0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+	4, DOT11F_EID_ESETXMITPOWER, 0, 0, },
+	{ offsetof(tDot11fBeacon, WscBeacon), offsetof(tDot11fIEWscBeacon,
+	present), 0, "WscBeacon", 0, 6, 84, SigIeWscBeacon, {0, 80, 242, 4, 0},
+	4, DOT11F_EID_WSCBEACON, 0, 0, },
+	{ offsetof(tDot11fBeacon, P2PBeacon), offsetof(tDot11fIEP2PBeacon,
+	present), 0, "P2PBeacon", 0, 6, 61, SigIeP2PBeacon, {80, 111, 154, 9, 0},
+	4, DOT11F_EID_P2PBEACON, 0, 0, },
+	{ offsetof(tDot11fBeacon, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0,
+	"VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fBeacon, VHTOperation), offsetof(tDot11fIEVHTOperation,
+	present), 0, "VHTOperation", 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTOPERATION, 0, 0, },
+	{ offsetof(tDot11fBeacon, VHTExtBssLoad),
+	offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad",
+	0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTEXTBSSLOAD, 0, 0, },
+	{ offsetof(tDot11fBeacon, ExtCap), offsetof(tDot11fIEExtCap, present), 0,
+	"ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fBeacon, OperatingMode),
+	offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+	0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OPERATINGMODE, 0, 0, },
+	{ offsetof(tDot11fBeacon, WiderBWChanSwitchAnn),
+	offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0,
+	"WiderBWChanSwitchAnn", 0, 5, 5, SigIeWiderBWChanSwitchAnn,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, 0, },
+	{ offsetof(tDot11fBeacon, OBSSScanParameters),
+	offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+	0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OBSSSCANPARAMETERS, 0, 0, },
+	{ offsetof(tDot11fBeacon, fils_indication),
+	offsetof(tDot11fIEfils_indication, present), 0, "fils_indication",
+	0, 6, 259, SigIefils_indication, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_INDICATION, 0, 0, },
+	{ offsetof(tDot11fBeacon, Vendor1IE), offsetof(tDot11fIEVendor1IE,
+	present), 0, "Vendor1IE", 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0},
+	3, DOT11F_EID_VENDOR1IE, 0, 0, },
+	{ offsetof(tDot11fBeacon, vendor_vht_ie),
+	offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie",
+	0, 7, 28, SigIevendor_vht_ie, {0, 144, 76, 4, 0},
+	4, DOT11F_EID_VENDOR_VHT_IE, 0, 0, },
+	{ offsetof(tDot11fBeacon, Vendor3IE), offsetof(tDot11fIEVendor3IE,
+	present), 0, "Vendor3IE", 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0},
+	3, DOT11F_EID_VENDOR3IE, 0, 0, },
+	{ offsetof(tDot11fBeacon, hs20vendor_ie),
+	offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie",
+	0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0},
+	4, DOT11F_EID_HS20VENDOR_IE, 0, 0, },
+	{ offsetof(tDot11fBeacon, ChannelSwitchWrapper),
+	offsetof(tDot11fIEChannelSwitchWrapper, present), 0,
+	"ChannelSwitchWrapper", 0, 2, 14, SigIeChannelSwitchWrapper,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, 0, },
+	{ offsetof(tDot11fBeacon, QComVendorIE), offsetof(tDot11fIEQComVendorIE,
+	present), 0, "QComVendorIE", 0, 7, 7, SigIeQComVendorIE,
+	{0, 160, 198, 0, 0}, 3, DOT11F_EID_QCOMVENDORIE, 0, 0, },
+	{ offsetof(tDot11fBeacon, ESEVersion), offsetof(tDot11fIEESEVersion,
+	present), 0, "ESEVersion", 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+	4, DOT11F_EID_ESEVERSION, 0, 0, },
+	{ offsetof(tDot11fBeacon, 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, },
+	{ offsetof(tDot11fBeacon, QCN_IE), offsetof(tDot11fIEQCN_IE, present), 0,
+	"QCN_IE", 0, 10, 10, SigIeQCN_IE, {140, 253, 240, 1, 0},
+	4, DOT11F_EID_QCN_IE, 0, 0, },
+	{ offsetof(tDot11fBeacon, he_cap), offsetof(tDot11fIEhe_cap, present), 0,
+	"he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_CAP, 35, 0, },
+	{ offsetof(tDot11fBeacon, he_op), offsetof(tDot11fIEhe_op, present), 0,
+	"he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_OP, 36, 0, },
+	{ offsetof(tDot11fBeacon, bss_color_change),
+	offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change",
+	0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
+	{ offsetof(tDot11fBeacon, mu_edca_param_set),
+	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 0, },
+	{ offsetof(tDot11fBeacon, esp_information),
+	offsetof(tDot11fIEesp_information, present), 0, "esp_information",
+	0, 2, 98, SigIeesp_information, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_ESP_INFORMATION, 11, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_beacon(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fBeacon *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_Beacon, IES_Beacon,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_beacon. */
+
+static const tFFDefn FFS_Beacon1[] = {
+	{ "TimeStamp", offsetof(tDot11fBeacon1, TimeStamp), SigFfTimeStamp,
+	DOT11F_FF_TIMESTAMP_LEN, },
+	{ "BeaconInterval", offsetof(tDot11fBeacon1, BeaconInterval),
+	SigFfBeaconInterval, DOT11F_FF_BEACONINTERVAL_LEN, },
+	{ "Capabilities", offsetof(tDot11fBeacon1, Capabilities),
+	SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_Beacon1[] = {
+	{ offsetof(tDot11fBeacon1, SSID), offsetof(tDot11fIESSID, present), 0,
+	"SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 0, 1, },
+	{ offsetof(tDot11fBeacon1, SuppRates), offsetof(tDot11fIESuppRates,
+	present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 1, },
+	{ offsetof(tDot11fBeacon1, DSParams), offsetof(tDot11fIEDSParams,
+	present), 0, "DSParams", 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_DSPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeacon1, IBSSParams), offsetof(tDot11fIEIBSSParams,
+	present), 0, "IBSSParams", 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_IBSSPARAMS, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_beacon1(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fBeacon1 *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_Beacon1, IES_Beacon1,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_beacon1. */
+
+static const tFFDefn FFS_Beacon2[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_Beacon2[] = {
+	{ offsetof(tDot11fBeacon2, Country), offsetof(tDot11fIECountry, present),
+	0, "Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_COUNTRY, 0, 0, },
+	{ offsetof(tDot11fBeacon2, PowerConstraints),
+	offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints",
+	0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_POWERCONSTRAINTS, 0, 0, },
+	{ offsetof(tDot11fBeacon2, ChanSwitchAnn),
+	offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn",
+	0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_CHANSWITCHANN, 0, 0, },
+	{ offsetof(tDot11fBeacon2, ext_chan_switch_ann),
+	offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann",
+	0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, 0, },
+	{ offsetof(tDot11fBeacon2, SuppOperatingClasses),
+	offsetof(tDot11fIESuppOperatingClasses, present), 0,
+	"SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, 0, },
+	{ offsetof(tDot11fBeacon2, Quiet), offsetof(tDot11fIEQuiet, present), 0,
+	"Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QUIET, 0, 0, },
+	{ offsetof(tDot11fBeacon2, TPCReport), offsetof(tDot11fIETPCReport,
+	present), 0, "TPCReport", 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TPCREPORT, 0, 0, },
+	{ offsetof(tDot11fBeacon2, ERPInfo), offsetof(tDot11fIEERPInfo, present),
+	0, "ERPInfo", 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_ERPINFO, 0, 0, },
+	{ offsetof(tDot11fBeacon2, ExtSuppRates), offsetof(tDot11fIEExtSuppRates,
+	present), 0, "ExtSuppRates", 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fBeacon2, RSNOpaque), offsetof(tDot11fIERSNOpaque,
+	present), 0, "RSNOpaque", 0, 2, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RSNOPAQUE, 0, 0, },
+	{ offsetof(tDot11fBeacon2, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet,
+	present), 0, "EDCAParamSet", 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EDCAPARAMSET, 0, 0, },
+	{ offsetof(tDot11fBeacon2, APChannelReport),
+	offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport",
+	0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_APCHANNELREPORT, 0, 0, },
+	{ offsetof(tDot11fBeacon2, RRMEnabledCap),
+	offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+	0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RRMENABLEDCAP, 0, 0, },
+	{ offsetof(tDot11fBeacon2, MobilityDomain),
+	offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+	0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MOBILITYDOMAIN, 0, 0, },
+	{ offsetof(tDot11fBeacon2, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA",
+	0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, 0, },
+	{ offsetof(tDot11fBeacon2, HTCaps), offsetof(tDot11fIEHTCaps, present), 0,
+	"HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fBeacon2, HTInfo), offsetof(tDot11fIEHTInfo, present), 0,
+	"HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTINFO, 0, 0, },
+	{ offsetof(tDot11fBeacon2, sec_chan_offset_ele),
+	offsetof(tDot11fIEsec_chan_offset_ele, present), 0, "sec_chan_offset_ele",
+	0, 3, 3, SigIesec_chan_offset_ele, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SEC_CHAN_OFFSET_ELE, 0, 0, },
+	{ offsetof(tDot11fBeacon2, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp,
+	present), 0, "WMMInfoAp", 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0},
+	5, DOT11F_EID_WMMINFOAP, 0, 0, },
+	{ offsetof(tDot11fBeacon2, WMMParams), offsetof(tDot11fIEWMMParams,
+	present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+	5, DOT11F_EID_WMMPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeacon2, WMMCaps), offsetof(tDot11fIEWMMCaps, present),
+	0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+	5, DOT11F_EID_WMMCAPS, 0, 0, },
+	{ offsetof(tDot11fBeacon2, WscBeacon), offsetof(tDot11fIEWscBeacon,
+	present), 0, "WscBeacon", 0, 6, 84, SigIeWscBeacon, {0, 80, 242, 4, 0},
+	4, DOT11F_EID_WSCBEACON, 0, 0, },
+	{ offsetof(tDot11fBeacon2, WAPI), offsetof(tDot11fIEWAPI, present), 0,
+	"WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_WAPI, 0, 0, },
+	{ offsetof(tDot11fBeacon2, ESERadMgmtCap),
+	offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+	0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+	4, DOT11F_EID_ESERADMGMTCAP, 0, 0, },
+	{ offsetof(tDot11fBeacon2, ESETrafStrmMet),
+	offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+	0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+	4, DOT11F_EID_ESETRAFSTRMMET, 0, 0, },
+	{ offsetof(tDot11fBeacon2, ESETxmitPower),
+	offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+	0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+	4, DOT11F_EID_ESETXMITPOWER, 0, 0, },
+	{ offsetof(tDot11fBeacon2, P2PBeacon), offsetof(tDot11fIEP2PBeacon,
+	present), 0, "P2PBeacon", 0, 6, 61, SigIeP2PBeacon, {80, 111, 154, 9, 0},
+	4, DOT11F_EID_P2PBEACON, 0, 0, },
+	{ offsetof(tDot11fBeacon2, VHTCaps), offsetof(tDot11fIEVHTCaps, present),
+	0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fBeacon2, VHTOperation), offsetof(tDot11fIEVHTOperation,
+	present), 0, "VHTOperation", 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTOPERATION, 0, 0, },
+	{ offsetof(tDot11fBeacon2, VHTExtBssLoad),
+	offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad",
+	0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTEXTBSSLOAD, 0, 0, },
+	{ offsetof(tDot11fBeacon2, ExtCap), offsetof(tDot11fIEExtCap, present), 0,
+	"ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fBeacon2, OperatingMode),
+	offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+	0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OPERATINGMODE, 0, 0, },
+	{ offsetof(tDot11fBeacon2, WiderBWChanSwitchAnn),
+	offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0,
+	"WiderBWChanSwitchAnn", 0, 5, 5, SigIeWiderBWChanSwitchAnn,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, 0, },
+	{ offsetof(tDot11fBeacon2, OBSSScanParameters),
+	offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+	0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OBSSSCANPARAMETERS, 0, 0, },
+	{ offsetof(tDot11fBeacon2, fils_indication),
+	offsetof(tDot11fIEfils_indication, present), 0, "fils_indication",
+	0, 6, 259, SigIefils_indication, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_INDICATION, 0, 0, },
+	{ offsetof(tDot11fBeacon2, Vendor1IE), offsetof(tDot11fIEVendor1IE,
+	present), 0, "Vendor1IE", 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0},
+	3, DOT11F_EID_VENDOR1IE, 0, 0, },
+	{ offsetof(tDot11fBeacon2, vendor_vht_ie),
+	offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie",
+	0, 7, 28, SigIevendor_vht_ie, {0, 144, 76, 4, 0},
+	4, DOT11F_EID_VENDOR_VHT_IE, 0, 0, },
+	{ offsetof(tDot11fBeacon2, Vendor3IE), offsetof(tDot11fIEVendor3IE,
+	present), 0, "Vendor3IE", 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0},
+	3, DOT11F_EID_VENDOR3IE, 0, 0, },
+	{ offsetof(tDot11fBeacon2, hs20vendor_ie),
+	offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie",
+	0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0},
+	4, DOT11F_EID_HS20VENDOR_IE, 0, 0, },
+	{ offsetof(tDot11fBeacon2, ChannelSwitchWrapper),
+	offsetof(tDot11fIEChannelSwitchWrapper, present), 0,
+	"ChannelSwitchWrapper", 0, 2, 14, SigIeChannelSwitchWrapper,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, 0, },
+	{ offsetof(tDot11fBeacon2, QComVendorIE), offsetof(tDot11fIEQComVendorIE,
+	present), 0, "QComVendorIE", 0, 7, 7, SigIeQComVendorIE,
+	{0, 160, 198, 0, 0}, 3, DOT11F_EID_QCOMVENDORIE, 0, 0, },
+	{ offsetof(tDot11fBeacon2, ESEVersion), offsetof(tDot11fIEESEVersion,
+	present), 0, "ESEVersion", 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+	4, DOT11F_EID_ESEVERSION, 0, 0, },
+	{ offsetof(tDot11fBeacon2, QCN_IE), offsetof(tDot11fIEQCN_IE, present), 0,
+	"QCN_IE", 0, 10, 10, SigIeQCN_IE, {140, 253, 240, 1, 0},
+	4, DOT11F_EID_QCN_IE, 0, 0, },
+	{ offsetof(tDot11fBeacon2, he_cap), offsetof(tDot11fIEhe_cap, present), 0,
+	"he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_CAP, 35, 0, },
+	{ offsetof(tDot11fBeacon2, he_op), offsetof(tDot11fIEhe_op, present), 0,
+	"he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_OP, 36, 0, },
+	{ offsetof(tDot11fBeacon2, bss_color_change),
+	offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change",
+	0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
+	{ offsetof(tDot11fBeacon2, mu_edca_param_set),
+	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 0, },
+	{ offsetof(tDot11fBeacon2, esp_information),
+	offsetof(tDot11fIEesp_information, present), 0, "esp_information",
+	0, 2, 98, SigIeesp_information, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_ESP_INFORMATION, 11, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_beacon2(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fBeacon2 *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_Beacon2, IES_Beacon2,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_beacon2. */
+
+static const tFFDefn FFS_BeaconIEs[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_BeaconIEs[] = {
+	{ offsetof(tDot11fBeaconIEs, SSID), offsetof(tDot11fIESSID, present), 0,
+	"SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 0, 1, },
+	{ offsetof(tDot11fBeaconIEs, SuppRates), offsetof(tDot11fIESuppRates,
+	present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 1, },
+	{ offsetof(tDot11fBeaconIEs, FHParamSet), offsetof(tDot11fIEFHParamSet,
+	present), 0, "FHParamSet", 0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FHPARAMSET, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, DSParams), offsetof(tDot11fIEDSParams,
+	present), 0, "DSParams", 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_DSPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, CFParams), offsetof(tDot11fIECFParams,
+	present), 0, "CFParams", 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_CFPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, IBSSParams), offsetof(tDot11fIEIBSSParams,
+	present), 0, "IBSSParams", 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_IBSSPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, TIM), offsetof(tDot11fIETIM, present), 0,
+	"TIM", 0, 6, 256, SigIeTIM, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIM, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, Country), offsetof(tDot11fIECountry,
+	present), 0, "Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_COUNTRY, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, FHParams), offsetof(tDot11fIEFHParams,
+	present), 0, "FHParams", 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FHPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, FHPattTable), offsetof(tDot11fIEFHPattTable,
+	present), 0, "FHPattTable", 0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FHPATTTABLE, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, PowerConstraints),
+	offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints",
+	0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_POWERCONSTRAINTS, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, ChanSwitchAnn),
+	offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn",
+	0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_CHANSWITCHANN, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, ext_chan_switch_ann),
+	offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann",
+	0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, SuppOperatingClasses),
+	offsetof(tDot11fIESuppOperatingClasses, present), 0,
+	"SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, Quiet), offsetof(tDot11fIEQuiet, present), 0,
+	"Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QUIET, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, TPCReport), offsetof(tDot11fIETPCReport,
+	present), 0, "TPCReport", 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TPCREPORT, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, ERPInfo), offsetof(tDot11fIEERPInfo,
+	present), 0, "ERPInfo", 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_ERPINFO, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, ExtSuppRates),
+	offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+	0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, RSN), offsetof(tDot11fIERSN, present), 0,
+	"RSN", 0, 4, 132, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, QBSSLoad), offsetof(tDot11fIEQBSSLoad,
+	present), 0, "QBSSLoad", 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QBSSLOAD, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, EDCAParamSet),
+	offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet",
+	0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EDCAPARAMSET, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, QOSCapsAp), offsetof(tDot11fIEQOSCapsAp,
+	present), 0, "QOSCapsAp", 0, 3, 3, SigIeQOSCapsAp, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QOSCAPSAP, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, APChannelReport),
+	offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport",
+	0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_APCHANNELREPORT, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, RRMEnabledCap),
+	offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+	0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RRMENABLEDCAP, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, MobilityDomain),
+	offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+	0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MOBILITYDOMAIN, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, WPA), offsetof(tDot11fIEWPA, present), 0,
+	"WPA", 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, HTCaps), offsetof(tDot11fIEHTCaps, present),
+	0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, HTInfo), offsetof(tDot11fIEHTInfo, present),
+	0, "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTINFO, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, sec_chan_offset_ele),
+	offsetof(tDot11fIEsec_chan_offset_ele, present), 0, "sec_chan_offset_ele",
+	0, 3, 3, SigIesec_chan_offset_ele, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SEC_CHAN_OFFSET_ELE, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp,
+	present), 0, "WMMInfoAp", 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0},
+	5, DOT11F_EID_WMMINFOAP, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, WMMParams), offsetof(tDot11fIEWMMParams,
+	present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+	5, DOT11F_EID_WMMPARAMS, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, WMMCaps), offsetof(tDot11fIEWMMCaps,
+	present), 0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+	5, DOT11F_EID_WMMCAPS, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, WAPI), offsetof(tDot11fIEWAPI, present), 0,
+	"WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_WAPI, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, ESEVersion), offsetof(tDot11fIEESEVersion,
+	present), 0, "ESEVersion", 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+	4, DOT11F_EID_ESEVERSION, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, ESERadMgmtCap),
+	offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+	0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+	4, DOT11F_EID_ESERADMGMTCAP, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, ESETrafStrmMet),
+	offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+	0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+	4, DOT11F_EID_ESETRAFSTRMMET, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, ESETxmitPower),
+	offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+	0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+	4, DOT11F_EID_ESETXMITPOWER, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, WscBeaconProbeRes),
+	offsetof(tDot11fIEWscBeaconProbeRes, present), 0, "WscBeaconProbeRes",
+	0, 6, 319, SigIeWscBeaconProbeRes, {0, 80, 242, 4, 0},
+	4, DOT11F_EID_WSCBEACONPROBERES, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, P2PBeaconProbeRes),
+	offsetof(tDot11fIEP2PBeaconProbeRes, present), 0, "P2PBeaconProbeRes",
+	0, 6, 1150, SigIeP2PBeaconProbeRes, {80, 111, 154, 9, 0},
+	4, DOT11F_EID_P2PBEACONPROBERES, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, VHTCaps), offsetof(tDot11fIEVHTCaps,
+	present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, VHTOperation),
+	offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+	0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTOPERATION, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, VHTExtBssLoad),
+	offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad",
+	0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTEXTBSSLOAD, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, ExtCap), offsetof(tDot11fIEExtCap, present),
+	0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, OperatingMode),
+	offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+	0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OPERATINGMODE, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, WiderBWChanSwitchAnn),
+	offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0,
+	"WiderBWChanSwitchAnn", 0, 5, 5, SigIeWiderBWChanSwitchAnn,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, OBSSScanParameters),
+	offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+	0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OBSSSCANPARAMETERS, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, fils_indication),
+	offsetof(tDot11fIEfils_indication, present), 0, "fils_indication",
+	0, 6, 259, SigIefils_indication, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_INDICATION, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, Vendor1IE), offsetof(tDot11fIEVendor1IE,
+	present), 0, "Vendor1IE", 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0},
+	3, DOT11F_EID_VENDOR1IE, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, vendor_vht_ie),
+	offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie",
+	0, 7, 28, SigIevendor_vht_ie, {0, 144, 76, 4, 0},
+	4, DOT11F_EID_VENDOR_VHT_IE, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, Vendor3IE), offsetof(tDot11fIEVendor3IE,
+	present), 0, "Vendor3IE", 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0},
+	3, DOT11F_EID_VENDOR3IE, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, hs20vendor_ie),
+	offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie",
+	0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0},
+	4, DOT11F_EID_HS20VENDOR_IE, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, ChannelSwitchWrapper),
+	offsetof(tDot11fIEChannelSwitchWrapper, present), 0,
+	"ChannelSwitchWrapper", 0, 2, 14, SigIeChannelSwitchWrapper,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, QComVendorIE),
+	offsetof(tDot11fIEQComVendorIE, present), 0, "QComVendorIE",
+	0, 7, 7, SigIeQComVendorIE, {0, 160, 198, 0, 0},
+	3, DOT11F_EID_QCOMVENDORIE, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, 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, },
+	{ offsetof(tDot11fBeaconIEs, QCN_IE), offsetof(tDot11fIEQCN_IE, present),
+	0, "QCN_IE", 0, 10, 10, SigIeQCN_IE, {140, 253, 240, 1, 0},
+	4, DOT11F_EID_QCN_IE, 0, 0, },
+	{ offsetof(tDot11fBeaconIEs, he_cap), offsetof(tDot11fIEhe_cap, present),
+	0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_CAP, 35, 0, },
+	{ offsetof(tDot11fBeaconIEs, he_op), offsetof(tDot11fIEhe_op, present), 0,
+	"he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_OP, 36, 0, },
+	{ offsetof(tDot11fBeaconIEs, bss_color_change),
+	offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change",
+	0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
+	{ offsetof(tDot11fBeaconIEs, mu_edca_param_set),
+	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 0, },
+	{ offsetof(tDot11fBeaconIEs, esp_information),
+	offsetof(tDot11fIEesp_information, present), 0, "esp_information",
+	0, 2, 98, SigIeesp_information, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_ESP_INFORMATION, 11, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_beacon_i_es(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fBeaconIEs *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_BeaconIEs, IES_BeaconIEs,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_beacon_i_es. */
+
+static const tFFDefn FFS_ChannelSwitch[] = {
+	{ "Category", offsetof(tDot11fChannelSwitch, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fChannelSwitch, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ChannelSwitch[] = {
+	{ offsetof(tDot11fChannelSwitch, ChanSwitchAnn),
+	offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn",
+	0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_CHANSWITCHANN, 0, 1, },
+	{ offsetof(tDot11fChannelSwitch, sec_chan_offset_ele),
+	offsetof(tDot11fIEsec_chan_offset_ele, present), 0, "sec_chan_offset_ele",
+	0, 3, 3, SigIesec_chan_offset_ele, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SEC_CHAN_OFFSET_ELE, 0, 0, },
+	{ offsetof(tDot11fChannelSwitch, WiderBWChanSwitchAnn),
+	offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0,
+	"WiderBWChanSwitchAnn", 0, 5, 5, SigIeWiderBWChanSwitchAnn,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_channel_switch(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fChannelSwitch *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_ChannelSwitch, IES_ChannelSwitch,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_channel_switch. */
+
+static const tFFDefn FFS_DeAuth[] = {
+	{ "Reason", offsetof(tDot11fDeAuth, Reason), SigFfReason,
+	DOT11F_FF_REASON_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_DeAuth[] = {
+	{ offsetof(tDot11fDeAuth, P2PDeAuth), offsetof(tDot11fIEP2PDeAuth,
+	present), 0, "P2PDeAuth", 0, 6, 10, SigIeP2PDeAuth, {80, 111, 154, 9, 0},
+	4, DOT11F_EID_P2PDEAUTH, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_de_auth(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fDeAuth *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_DeAuth, IES_DeAuth,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_de_auth. */
+
+static const tFFDefn FFS_DelTS[] = {
+	{ "Category", offsetof(tDot11fDelTS, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fDelTS, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "TSInfo", offsetof(tDot11fDelTS, TSInfo), SigFfTSInfo,
+	DOT11F_FF_TSINFO_LEN, },
+	{ "Reason", offsetof(tDot11fDelTS, Reason), SigFfReason,
+	DOT11F_FF_REASON_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_DelTS[] = {
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_del_ts(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fDelTS *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_DelTS, IES_DelTS,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_del_ts. */
+
+static const tFFDefn FFS_Disassociation[] = {
+	{ "Reason", offsetof(tDot11fDisassociation, Reason), SigFfReason,
+	DOT11F_FF_REASON_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_Disassociation[] = {
+	{ offsetof(tDot11fDisassociation, P2PDisAssoc),
+	offsetof(tDot11fIEP2PDisAssoc, present), 0, "P2PDisAssoc",
+	0, 6, 10, SigIeP2PDisAssoc, {80, 111, 154, 9, 0},
+	4, DOT11F_EID_P2PDISASSOC, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_disassociation(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fDisassociation *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_Disassociation, IES_Disassociation,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_disassociation. */
+
+static const tFFDefn FFS_LinkMeasurementReport[] = {
+	{ "Category", offsetof(tDot11fLinkMeasurementReport, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fLinkMeasurementReport, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fLinkMeasurementReport, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "TPCEleID", offsetof(tDot11fLinkMeasurementReport, TPCEleID),
+	SigFfTPCEleID, DOT11F_FF_TPCELEID_LEN, },
+	{ "TPCEleLen", offsetof(tDot11fLinkMeasurementReport, TPCEleLen),
+	SigFfTPCEleLen, DOT11F_FF_TPCELELEN_LEN, },
+	{ "TxPower", offsetof(tDot11fLinkMeasurementReport, TxPower),
+	SigFfTxPower, DOT11F_FF_TXPOWER_LEN, },
+	{ "LinkMargin", offsetof(tDot11fLinkMeasurementReport, LinkMargin),
+	SigFfLinkMargin, DOT11F_FF_LINKMARGIN_LEN, },
+	{ "RxAntennaId", offsetof(tDot11fLinkMeasurementReport, RxAntennaId),
+	SigFfRxAntennaId, DOT11F_FF_RXANTENNAID_LEN, },
+	{ "TxAntennaId", offsetof(tDot11fLinkMeasurementReport, TxAntennaId),
+	SigFfTxAntennaId, DOT11F_FF_TXANTENNAID_LEN, },
+	{ "RCPI", offsetof(tDot11fLinkMeasurementReport, RCPI), SigFfRCPI,
+	DOT11F_FF_RCPI_LEN, },
+	{ "RSNI", offsetof(tDot11fLinkMeasurementReport, RSNI), SigFfRSNI,
+	DOT11F_FF_RSNI_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_LinkMeasurementReport[] = {
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_link_measurement_report(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fLinkMeasurementReport *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_LinkMeasurementReport, IES_LinkMeasurementReport,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_link_measurement_report. */
+
+static const tFFDefn FFS_LinkMeasurementRequest[] = {
+	{ "Category", offsetof(tDot11fLinkMeasurementRequest, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fLinkMeasurementRequest, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fLinkMeasurementRequest, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "TxPower", offsetof(tDot11fLinkMeasurementRequest, TxPower),
+	SigFfTxPower, DOT11F_FF_TXPOWER_LEN, },
+	{ "MaxTxPower", offsetof(tDot11fLinkMeasurementRequest, MaxTxPower),
+	SigFfMaxTxPower, DOT11F_FF_MAXTXPOWER_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_LinkMeasurementRequest[] = {
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_link_measurement_request(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fLinkMeasurementRequest *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_LinkMeasurementRequest, IES_LinkMeasurementRequest,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_link_measurement_request. */
+
+static const tFFDefn FFS_MeasurementReport[] = {
+	{ "Category", offsetof(tDot11fMeasurementReport, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fMeasurementReport, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fMeasurementReport, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_MeasurementReport[] = {
+	{ offsetof(tDot11fMeasurementReport, MeasurementReport),
+	offsetof(tDot11fIEMeasurementReport, present), 0, "MeasurementReport",
+	0, 5, 31, SigIeMeasurementReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MEASUREMENTREPORT, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_measurement_report(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fMeasurementReport *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_MeasurementReport, IES_MeasurementReport,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_measurement_report. */
+
+static const tFFDefn FFS_MeasurementRequest[] = {
+	{ "Category", offsetof(tDot11fMeasurementRequest, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fMeasurementRequest, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fMeasurementRequest, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_MeasurementRequest[] = {
+	{ offsetof(tDot11fMeasurementRequest, MeasurementRequest),
+	offsetof(tDot11fIEMeasurementRequest, present),
+	offsetof(tDot11fMeasurementRequest, num_MeasurementRequest),
+	"MeasurementRequest", 4, 6, 18, SigIeMeasurementRequest, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MEASUREMENTREQUEST, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_measurement_request(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fMeasurementRequest *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_MeasurementRequest, IES_MeasurementRequest,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_measurement_request. */
+
+static const tFFDefn FFS_NeighborReportRequest[] = {
+	{ "Category", offsetof(tDot11fNeighborReportRequest, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fNeighborReportRequest, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fNeighborReportRequest, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_NeighborReportRequest[] = {
+	{ offsetof(tDot11fNeighborReportRequest, SSID), offsetof(tDot11fIESSID,
+	present), 0, "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SSID, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_neighbor_report_request(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fNeighborReportRequest *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_NeighborReportRequest, IES_NeighborReportRequest,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_neighbor_report_request. */
+
+static const tFFDefn FFS_NeighborReportResponse[] = {
+	{ "Category", offsetof(tDot11fNeighborReportResponse, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fNeighborReportResponse, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fNeighborReportResponse, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_NeighborReportResponse[] = {
+	{ offsetof(tDot11fNeighborReportResponse, NeighborReport),
+	offsetof(tDot11fIENeighborReport, present),
+	offsetof(tDot11fNeighborReportResponse, num_NeighborReport),
+	"NeighborReport", 15, 15, 548, SigIeNeighborReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_NEIGHBORREPORT, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_neighbor_report_response(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fNeighborReportResponse *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_NeighborReportResponse, IES_NeighborReportResponse,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_neighbor_report_response. */
+
+static const tFFDefn FFS_OperatingMode[] = {
+	{ "Category", offsetof(tDot11fOperatingMode, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fOperatingMode, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "OperatingMode", offsetof(tDot11fOperatingMode, OperatingMode),
+	SigFfOperatingMode, DOT11F_FF_OPERATINGMODE_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_OperatingMode[] = {
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_operating_mode(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fOperatingMode *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_OperatingMode, IES_OperatingMode,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_operating_mode. */
+
+static const tFFDefn FFS_ProbeRequest[] = {
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ProbeRequest[] = {
+	{ offsetof(tDot11fProbeRequest, SSID), offsetof(tDot11fIESSID, present), 0,
+	"SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 0, 1, },
+	{ offsetof(tDot11fProbeRequest, SuppRates), offsetof(tDot11fIESuppRates,
+	present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 1, },
+	{ offsetof(tDot11fProbeRequest, RequestedInfo),
+	offsetof(tDot11fIERequestedInfo, present), 0, "RequestedInfo",
+	0, 2, 257, SigIeRequestedInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_REQUESTEDINFO, 0, 0, },
+	{ offsetof(tDot11fProbeRequest, ExtSuppRates),
+	offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+	0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fProbeRequest, DSParams), offsetof(tDot11fIEDSParams,
+	present), 0, "DSParams", 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_DSPARAMS, 0, 0, },
+	{ offsetof(tDot11fProbeRequest, HTCaps), offsetof(tDot11fIEHTCaps,
+	present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fProbeRequest, WscProbeReq),
+	offsetof(tDot11fIEWscProbeReq, present), 0, "WscProbeReq",
+	0, 6, 286, SigIeWscProbeReq, {0, 80, 242, 4, 0},
+	4, DOT11F_EID_WSCPROBEREQ, 0, 0, },
+	{ offsetof(tDot11fProbeRequest, WFATPC), offsetof(tDot11fIEWFATPC,
+	present), 0, "WFATPC", 0, 9, 9, SigIeWFATPC, {0, 80, 242, 8, 0},
+	5, DOT11F_EID_WFATPC, 0, 0, },
+	{ offsetof(tDot11fProbeRequest, P2PProbeReq),
+	offsetof(tDot11fIEP2PProbeReq, present), 0, "P2PProbeReq",
+	0, 6, 43, SigIeP2PProbeReq, {80, 111, 154, 9, 0},
+	4, DOT11F_EID_P2PPROBEREQ, 0, 0, },
+	{ offsetof(tDot11fProbeRequest, VHTCaps), offsetof(tDot11fIEVHTCaps,
+	present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fProbeRequest, ExtCap), offsetof(tDot11fIEExtCap,
+	present), 0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fProbeRequest, QCN_IE), offsetof(tDot11fIEQCN_IE,
+	present), 0, "QCN_IE", 0, 10, 10, SigIeQCN_IE, {140, 253, 240, 1, 0},
+	4, DOT11F_EID_QCN_IE, 0, 0, },
+	{ offsetof(tDot11fProbeRequest, he_cap), offsetof(tDot11fIEhe_cap,
+	present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_CAP, 35, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_probe_request(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fProbeRequest *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_ProbeRequest, IES_ProbeRequest,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_probe_request. */
+
+static const tFFDefn FFS_ProbeResponse[] = {
+	{ "TimeStamp", offsetof(tDot11fProbeResponse, TimeStamp), SigFfTimeStamp,
+	DOT11F_FF_TIMESTAMP_LEN, },
+	{ "BeaconInterval", offsetof(tDot11fProbeResponse, BeaconInterval),
+	SigFfBeaconInterval, DOT11F_FF_BEACONINTERVAL_LEN, },
+	{ "Capabilities", offsetof(tDot11fProbeResponse, Capabilities),
+	SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ProbeResponse[] = {
+	{ offsetof(tDot11fProbeResponse, SSID), offsetof(tDot11fIESSID, present),
+	0, "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SSID, 0, 1, },
+	{ offsetof(tDot11fProbeResponse, SuppRates), offsetof(tDot11fIESuppRates,
+	present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 1, },
+	{ offsetof(tDot11fProbeResponse, FHParamSet),
+	offsetof(tDot11fIEFHParamSet, present), 0, "FHParamSet",
+	0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FHPARAMSET, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, DSParams), offsetof(tDot11fIEDSParams,
+	present), 0, "DSParams", 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_DSPARAMS, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, CFParams), offsetof(tDot11fIECFParams,
+	present), 0, "CFParams", 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_CFPARAMS, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, IBSSParams),
+	offsetof(tDot11fIEIBSSParams, present), 0, "IBSSParams",
+	0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_IBSSPARAMS, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, Country), offsetof(tDot11fIECountry,
+	present), 0, "Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_COUNTRY, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, FHParams), offsetof(tDot11fIEFHParams,
+	present), 0, "FHParams", 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FHPARAMS, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, FHPattTable),
+	offsetof(tDot11fIEFHPattTable, present), 0, "FHPattTable",
+	0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FHPATTTABLE, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, PowerConstraints),
+	offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints",
+	0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_POWERCONSTRAINTS, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, ChanSwitchAnn),
+	offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn",
+	0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_CHANSWITCHANN, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, ext_chan_switch_ann),
+	offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann",
+	0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, SuppOperatingClasses),
+	offsetof(tDot11fIESuppOperatingClasses, present), 0,
+	"SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, Quiet), offsetof(tDot11fIEQuiet,
+	present), 0, "Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QUIET, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, TPCReport), offsetof(tDot11fIETPCReport,
+	present), 0, "TPCReport", 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TPCREPORT, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, ERPInfo), offsetof(tDot11fIEERPInfo,
+	present), 0, "ERPInfo", 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_ERPINFO, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, ExtSuppRates),
+	offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+	0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, RSNOpaque), offsetof(tDot11fIERSNOpaque,
+	present), 0, "RSNOpaque", 0, 2, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RSNOPAQUE, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, QBSSLoad), offsetof(tDot11fIEQBSSLoad,
+	present), 0, "QBSSLoad", 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QBSSLOAD, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, EDCAParamSet),
+	offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet",
+	0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EDCAPARAMSET, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, RRMEnabledCap),
+	offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+	0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RRMENABLEDCAP, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, APChannelReport),
+	offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport",
+	0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_APCHANNELREPORT, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, MobilityDomain),
+	offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+	0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MOBILITYDOMAIN, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, WPA), offsetof(tDot11fIEWPA, present), 0,
+	"WPA", 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, HTCaps), offsetof(tDot11fIEHTCaps,
+	present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, HTInfo), offsetof(tDot11fIEHTInfo,
+	present), 0, "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTINFO, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, sec_chan_offset_ele),
+	offsetof(tDot11fIEsec_chan_offset_ele, present), 0, "sec_chan_offset_ele",
+	0, 3, 3, SigIesec_chan_offset_ele, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SEC_CHAN_OFFSET_ELE, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp,
+	present), 0, "WMMInfoAp", 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0},
+	5, DOT11F_EID_WMMINFOAP, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, WMMParams), offsetof(tDot11fIEWMMParams,
+	present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+	5, DOT11F_EID_WMMPARAMS, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, WMMCaps), offsetof(tDot11fIEWMMCaps,
+	present), 0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+	5, DOT11F_EID_WMMCAPS, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, WAPI), offsetof(tDot11fIEWAPI, present),
+	0, "WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_WAPI, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, ESERadMgmtCap),
+	offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+	0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+	4, DOT11F_EID_ESERADMGMTCAP, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, ESETrafStrmMet),
+	offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+	0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+	4, DOT11F_EID_ESETRAFSTRMMET, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, ESETxmitPower),
+	offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+	0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+	4, DOT11F_EID_ESETXMITPOWER, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, WscProbeRes),
+	offsetof(tDot11fIEWscProbeRes, present), 0, "WscProbeRes",
+	0, 6, 319, SigIeWscProbeRes, {0, 80, 242, 4, 0},
+	4, DOT11F_EID_WSCPROBERES, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, P2PProbeRes),
+	offsetof(tDot11fIEP2PProbeRes, present), 0, "P2PProbeRes",
+	0, 6, 1141, SigIeP2PProbeRes, {80, 111, 154, 9, 0},
+	4, DOT11F_EID_P2PPROBERES, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, VHTCaps), offsetof(tDot11fIEVHTCaps,
+	present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, VHTOperation),
+	offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+	0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTOPERATION, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, VHTExtBssLoad),
+	offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad",
+	0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTEXTBSSLOAD, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, ExtCap), offsetof(tDot11fIEExtCap,
+	present), 0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, OBSSScanParameters),
+	offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+	0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OBSSSCANPARAMETERS, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, fils_indication),
+	offsetof(tDot11fIEfils_indication, present), 0, "fils_indication",
+	0, 6, 259, SigIefils_indication, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FILS_INDICATION, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, Vendor1IE), offsetof(tDot11fIEVendor1IE,
+	present), 0, "Vendor1IE", 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0},
+	3, DOT11F_EID_VENDOR1IE, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, vendor_vht_ie),
+	offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie",
+	0, 7, 28, SigIevendor_vht_ie, {0, 144, 76, 4, 0},
+	4, DOT11F_EID_VENDOR_VHT_IE, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, Vendor3IE), offsetof(tDot11fIEVendor3IE,
+	present), 0, "Vendor3IE", 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0},
+	3, DOT11F_EID_VENDOR3IE, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, hs20vendor_ie),
+	offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie",
+	0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0},
+	4, DOT11F_EID_HS20VENDOR_IE, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, ChannelSwitchWrapper),
+	offsetof(tDot11fIEChannelSwitchWrapper, present), 0,
+	"ChannelSwitchWrapper", 0, 2, 14, SigIeChannelSwitchWrapper,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, QComVendorIE),
+	offsetof(tDot11fIEQComVendorIE, present), 0, "QComVendorIE",
+	0, 7, 7, SigIeQComVendorIE, {0, 160, 198, 0, 0},
+	3, DOT11F_EID_QCOMVENDORIE, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, ESEVersion),
+	offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion",
+	0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+	4, DOT11F_EID_ESEVERSION, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, 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, },
+	{ offsetof(tDot11fProbeResponse, QCN_IE), offsetof(tDot11fIEQCN_IE,
+	present), 0, "QCN_IE", 0, 10, 10, SigIeQCN_IE, {140, 253, 240, 1, 0},
+	4, DOT11F_EID_QCN_IE, 0, 0, },
+	{ offsetof(tDot11fProbeResponse, he_cap), offsetof(tDot11fIEhe_cap,
+	present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_CAP, 35, 0, },
+	{ offsetof(tDot11fProbeResponse, he_op), offsetof(tDot11fIEhe_op,
+	present), 0, "he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_OP, 36, 0, },
+	{ offsetof(tDot11fProbeResponse, bss_color_change),
+	offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change",
+	0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
+	{ offsetof(tDot11fProbeResponse, mu_edca_param_set),
+	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 0, },
+	{ offsetof(tDot11fProbeResponse, esp_information),
+	offsetof(tDot11fIEesp_information, present), 0, "esp_information",
+	0, 2, 98, SigIeesp_information, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_ESP_INFORMATION, 11, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_probe_response(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fProbeResponse *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_ProbeResponse, IES_ProbeResponse,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_probe_response. */
+
+static const tFFDefn FFS_QosMapConfigure[] = {
+	{ "Category", offsetof(tDot11fQosMapConfigure, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fQosMapConfigure, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_QosMapConfigure[] = {
+	{ offsetof(tDot11fQosMapConfigure, QosMapSet),
+	offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet",
+	0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QOSMAPSET, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_qos_map_configure(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fQosMapConfigure *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_QosMapConfigure, IES_QosMapConfigure,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_qos_map_configure. */
+
+static const tFFDefn FFS_RadioMeasurementReport[] = {
+	{ "Category", offsetof(tDot11fRadioMeasurementReport, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fRadioMeasurementReport, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fRadioMeasurementReport, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_RadioMeasurementReport[] = {
+	{ offsetof(tDot11fRadioMeasurementReport, MeasurementReport),
+	offsetof(tDot11fIEMeasurementReport, present),
+	offsetof(tDot11fRadioMeasurementReport, num_MeasurementReport),
+	"MeasurementReport", 4, 5, 31, SigIeMeasurementReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MEASUREMENTREPORT, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_radio_measurement_report(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fRadioMeasurementReport *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_RadioMeasurementReport, IES_RadioMeasurementReport,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_radio_measurement_report. */
+
+static const tFFDefn FFS_RadioMeasurementRequest[] = {
+	{ "Category", offsetof(tDot11fRadioMeasurementRequest, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fRadioMeasurementRequest, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fRadioMeasurementRequest, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "NumOfRepetitions", offsetof(tDot11fRadioMeasurementRequest,
+	NumOfRepetitions), SigFfNumOfRepetitions,
+	DOT11F_FF_NUMOFREPETITIONS_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_RadioMeasurementRequest[] = {
+	{ offsetof(tDot11fRadioMeasurementRequest, MeasurementRequest),
+	offsetof(tDot11fIEMeasurementRequest, present),
+	offsetof(tDot11fRadioMeasurementRequest, num_MeasurementRequest),
+	"MeasurementRequest", 2, 6, 18, SigIeMeasurementRequest, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MEASUREMENTREQUEST, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_radio_measurement_request(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fRadioMeasurementRequest *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_RadioMeasurementRequest, IES_RadioMeasurementRequest,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_radio_measurement_request. */
+
+static const tFFDefn FFS_ReAssocRequest[] = {
+	{ "Capabilities", offsetof(tDot11fReAssocRequest, Capabilities),
+	SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+	{ "ListenInterval", offsetof(tDot11fReAssocRequest, ListenInterval),
+	SigFfListenInterval, DOT11F_FF_LISTENINTERVAL_LEN, },
+	{ "CurrentAPAddress", offsetof(tDot11fReAssocRequest, CurrentAPAddress),
+	SigFfCurrentAPAddress, DOT11F_FF_CURRENTAPADDRESS_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ReAssocRequest[] = {
+	{ offsetof(tDot11fReAssocRequest, SSID), offsetof(tDot11fIESSID, present),
+	0, "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SSID, 0, 1, },
+	{ offsetof(tDot11fReAssocRequest, SuppRates),
+	offsetof(tDot11fIESuppRates, present), 0, "SuppRates",
+	0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 1, },
+	{ offsetof(tDot11fReAssocRequest, ExtSuppRates),
+	offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+	0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, PowerCaps),
+	offsetof(tDot11fIEPowerCaps, present), 0, "PowerCaps",
+	0, 4, 4, SigIePowerCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_POWERCAPS, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, SuppChannels),
+	offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels",
+	0, 2, 98, SigIeSuppChannels, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPCHANNELS, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, RSNOpaque),
+	offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque",
+	0, 2, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RSNOPAQUE, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, QOSCapsStation),
+	offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation",
+	0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QOSCAPSSTATION, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, RRMEnabledCap),
+	offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+	0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RRMENABLEDCAP, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, MobilityDomain),
+	offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+	0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MOBILITYDOMAIN, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, FTInfo), offsetof(tDot11fIEFTInfo,
+	present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FTINFO, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, RICDataDesc),
+	offsetof(tDot11fIERICDataDesc, present),
+	offsetof(tDot11fReAssocRequest, num_RICDataDesc), "RICDataDesc",
+	2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RICDATADESC, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, WPAOpaque),
+	offsetof(tDot11fIEWPAOpaque, present), 0, "WPAOpaque",
+	0, 8, 255, SigIeWPAOpaque, {0, 80, 242, 1, 0},
+	4, DOT11F_EID_WPAOPAQUE, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, HTCaps), offsetof(tDot11fIEHTCaps,
+	present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, WMMCaps), offsetof(tDot11fIEWMMCaps,
+	present), 0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+	5, DOT11F_EID_WMMCAPS, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, WMMInfoStation),
+	offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation",
+	0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0},
+	5, DOT11F_EID_WMMINFOSTATION, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, WscIEOpaque),
+	offsetof(tDot11fIEWscIEOpaque, present), 0, "WscIEOpaque",
+	0, 8, 255, SigIeWscIEOpaque, {0, 80, 242, 4, 0},
+	4, DOT11F_EID_WSCIEOPAQUE, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, WAPIOpaque),
+	offsetof(tDot11fIEWAPIOpaque, present), 0, "WAPIOpaque",
+	0, 8, 255, SigIeWAPIOpaque, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_WAPIOPAQUE, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, WAPI), offsetof(tDot11fIEWAPI, present),
+	0, "WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_WAPI, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, ESERadMgmtCap),
+	offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+	0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+	4, DOT11F_EID_ESERADMGMTCAP, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, ESEVersion),
+	offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion",
+	0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+	4, DOT11F_EID_ESEVERSION, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, ESECckmOpaque),
+	offsetof(tDot11fIEESECckmOpaque, present), 0, "ESECckmOpaque",
+	0, 12, 26, SigIeESECckmOpaque, {0, 64, 150, 0, 0},
+	4, DOT11F_EID_ESECCKMOPAQUE, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+	present), offsetof(tDot11fReAssocRequest, num_WMMTSPEC), "WMMTSPEC",
+	4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+	5, DOT11F_EID_WMMTSPEC, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, ESETrafStrmRateSet),
+	offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet",
+	0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0},
+	4, DOT11F_EID_ESETRAFSTRMRATESET, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, P2PIEOpaque),
+	offsetof(tDot11fIEP2PIEOpaque, present), 0, "P2PIEOpaque",
+	0, 8, 255, SigIeP2PIEOpaque, {80, 111, 154, 9, 0},
+	4, DOT11F_EID_P2PIEOPAQUE, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, WFDIEOpaque),
+	offsetof(tDot11fIEWFDIEOpaque, present), 0, "WFDIEOpaque",
+	0, 8, 255, SigIeWFDIEOpaque, {80, 111, 154, 10, 0},
+	4, DOT11F_EID_WFDIEOPAQUE, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, VHTCaps), offsetof(tDot11fIEVHTCaps,
+	present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, ExtCap), offsetof(tDot11fIEExtCap,
+	present), 0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, OperatingMode),
+	offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+	0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OPERATINGMODE, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, QosMapSet),
+	offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet",
+	0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QOSMAPSET, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, vendor_vht_ie),
+	offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie",
+	0, 7, 28, SigIevendor_vht_ie, {0, 144, 76, 4, 0},
+	4, DOT11F_EID_VENDOR_VHT_IE, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, hs20vendor_ie),
+	offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie",
+	0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0},
+	4, DOT11F_EID_HS20VENDOR_IE, 0, 0, },
+	{ offsetof(tDot11fReAssocRequest, he_cap), offsetof(tDot11fIEhe_cap,
+	present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_CAP, 35, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_re_assoc_request(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fReAssocRequest *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_ReAssocRequest, IES_ReAssocRequest,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_re_assoc_request. */
+
+static const tFFDefn FFS_ReAssocResponse[] = {
+	{ "Capabilities", offsetof(tDot11fReAssocResponse, Capabilities),
+	SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+	{ "Status", offsetof(tDot11fReAssocResponse, Status), SigFfStatus,
+	DOT11F_FF_STATUS_LEN, },
+	{ "AID", offsetof(tDot11fReAssocResponse, AID), SigFfAID,
+	DOT11F_FF_AID_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ReAssocResponse[] = {
+	{ offsetof(tDot11fReAssocResponse, SuppRates),
+	offsetof(tDot11fIESuppRates, present), 0, "SuppRates",
+	0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 1, },
+	{ offsetof(tDot11fReAssocResponse, ExtSuppRates),
+	offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+	0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, EDCAParamSet),
+	offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet",
+	0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EDCAPARAMSET, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, RCPIIE), offsetof(tDot11fIERCPIIE,
+	present), 0, "RCPIIE", 0, 3, 3, SigIeRCPIIE, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RCPIIE, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, RSNIIE), offsetof(tDot11fIERSNIIE,
+	present), 0, "RSNIIE", 0, 3, 3, SigIeRSNIIE, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RSNIIE, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, RRMEnabledCap),
+	offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+	0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RRMENABLEDCAP, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, RSNOpaque),
+	offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque",
+	0, 2, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RSNOPAQUE, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, MobilityDomain),
+	offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+	0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MOBILITYDOMAIN, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, FTInfo), offsetof(tDot11fIEFTInfo,
+	present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FTINFO, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, RICDataDesc),
+	offsetof(tDot11fIERICDataDesc, present),
+	offsetof(tDot11fReAssocResponse, num_RICDataDesc), "RICDataDesc",
+	2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RICDATADESC, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, WPA), offsetof(tDot11fIEWPA, present),
+	0, "WPA", 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0},
+	4, DOT11F_EID_WPA, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, TimeoutInterval),
+	offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+	0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TIMEOUTINTERVAL, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, HTCaps), offsetof(tDot11fIEHTCaps,
+	present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, HTInfo), offsetof(tDot11fIEHTInfo,
+	present), 0, "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTINFO, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, WMMParams),
+	offsetof(tDot11fIEWMMParams, present), 0, "WMMParams",
+	0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+	5, DOT11F_EID_WMMPARAMS, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, ESERadMgmtCap),
+	offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+	0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+	4, DOT11F_EID_ESERADMGMTCAP, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, ESETrafStrmMet),
+	offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+	0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+	4, DOT11F_EID_ESETRAFSTRMMET, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, ESETxmitPower),
+	offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+	0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+	4, DOT11F_EID_ESETXMITPOWER, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+	present), offsetof(tDot11fReAssocResponse, num_WMMTSPEC), "WMMTSPEC",
+	4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+	5, DOT11F_EID_WMMTSPEC, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, ESETrafStrmRateSet),
+	offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet",
+	0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0},
+	4, DOT11F_EID_ESETRAFSTRMRATESET, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, WscReassocRes),
+	offsetof(tDot11fIEWscReassocRes, present), 0, "WscReassocRes",
+	0, 6, 37, SigIeWscReassocRes, {0, 80, 242, 4, 0},
+	4, DOT11F_EID_WSCREASSOCRES, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, P2PAssocRes),
+	offsetof(tDot11fIEP2PAssocRes, present), 0, "P2PAssocRes",
+	0, 6, 17, SigIeP2PAssocRes, {80, 111, 154, 9, 0},
+	4, DOT11F_EID_P2PASSOCRES, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, VHTCaps), offsetof(tDot11fIEVHTCaps,
+	present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, VHTOperation),
+	offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+	0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTOPERATION, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, ExtCap), offsetof(tDot11fIEExtCap,
+	present), 0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, OBSSScanParameters),
+	offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+	0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OBSSSCANPARAMETERS, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, QosMapSet),
+	offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet",
+	0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QOSMAPSET, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, vendor_vht_ie),
+	offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie",
+	0, 7, 28, SigIevendor_vht_ie, {0, 144, 76, 4, 0},
+	4, DOT11F_EID_VENDOR_VHT_IE, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, he_cap), offsetof(tDot11fIEhe_cap,
+	present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_CAP, 35, 0, },
+	{ offsetof(tDot11fReAssocResponse, he_op), offsetof(tDot11fIEhe_op,
+	present), 0, "he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HE_OP, 36, 0, },
+	{ offsetof(tDot11fReAssocResponse, bss_color_change),
+	offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change",
+	0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_BSS_COLOR_CHANGE, 42, 0, },
+	{ offsetof(tDot11fReAssocResponse, mu_edca_param_set),
+	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
+	0, 15, 15, SigIemu_edca_param_set, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_MU_EDCA_PARAM_SET, 38, 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,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fReAssocResponse *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_ReAssocResponse, IES_ReAssocResponse,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_re_assoc_response. */
+
+static const tFFDefn FFS_SMPowerSave[] = {
+	{ "Category", offsetof(tDot11fSMPowerSave, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fSMPowerSave, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "SMPowerModeSet", offsetof(tDot11fSMPowerSave, SMPowerModeSet),
+	SigFfSMPowerModeSet, DOT11F_FF_SMPOWERMODESET_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_SMPowerSave[] = {
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_sm_power_save(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fSMPowerSave *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_SMPowerSave, IES_SMPowerSave,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_sm_power_save. */
+
+static const tFFDefn FFS_SaQueryReq[] = {
+	{ "Category", offsetof(tDot11fSaQueryReq, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fSaQueryReq, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "TransactionId", offsetof(tDot11fSaQueryReq, TransactionId),
+	SigFfTransactionId, DOT11F_FF_TRANSACTIONID_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_SaQueryReq[] = {
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_sa_query_req(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fSaQueryReq *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_SaQueryReq, IES_SaQueryReq,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_sa_query_req. */
+
+static const tFFDefn FFS_SaQueryRsp[] = {
+	{ "Category", offsetof(tDot11fSaQueryRsp, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fSaQueryRsp, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "TransactionId", offsetof(tDot11fSaQueryRsp, TransactionId),
+	SigFfTransactionId, DOT11F_FF_TRANSACTIONID_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_SaQueryRsp[] = {
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_sa_query_rsp(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fSaQueryRsp *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_SaQueryRsp, IES_SaQueryRsp,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_sa_query_rsp. */
+
+static const tFFDefn FFS_TDLSDisReq[] = {
+	{ "Category", offsetof(tDot11fTDLSDisReq, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fTDLSDisReq, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fTDLSDisReq, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSDisReq[] = {
+	{ offsetof(tDot11fTDLSDisReq, LinkIdentifier),
+	offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+	0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_LINKIDENTIFIER, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_dis_req(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fTDLSDisReq *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_TDLSDisReq, IES_TDLSDisReq,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_tdls_dis_req. */
+
+static const tFFDefn FFS_TDLSDisRsp[] = {
+	{ "Category", offsetof(tDot11fTDLSDisRsp, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fTDLSDisRsp, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fTDLSDisRsp, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "Capabilities", offsetof(tDot11fTDLSDisRsp, Capabilities),
+	SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSDisRsp[] = {
+	{ offsetof(tDot11fTDLSDisRsp, SuppRates), offsetof(tDot11fIESuppRates,
+	present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 1, },
+	{ offsetof(tDot11fTDLSDisRsp, ExtSuppRates),
+	offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+	0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fTDLSDisRsp, SuppChannels),
+	offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels",
+	0, 2, 98, SigIeSuppChannels, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPCHANNELS, 0, 0, },
+	{ offsetof(tDot11fTDLSDisRsp, SuppOperatingClasses),
+	offsetof(tDot11fIESuppOperatingClasses, present), 0,
+	"SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, 0, },
+	{ offsetof(tDot11fTDLSDisRsp, RSN), offsetof(tDot11fIERSN, present), 0,
+	"RSN", 0, 4, 132, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, 0, },
+	{ offsetof(tDot11fTDLSDisRsp, ExtCap), offsetof(tDot11fIEExtCap, present),
+	0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fTDLSDisRsp, FTInfo), offsetof(tDot11fIEFTInfo, present),
+	0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FTINFO, 0, 0, },
+	{ offsetof(tDot11fTDLSDisRsp, TimeoutInterval),
+	offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+	0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TIMEOUTINTERVAL, 0, 0, },
+	{ offsetof(tDot11fTDLSDisRsp, RICData), offsetof(tDot11fIERICData,
+	present), 0, "RICData", 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RICDATA, 0, 0, },
+	{ offsetof(tDot11fTDLSDisRsp, HTCaps), offsetof(tDot11fIEHTCaps, present),
+	0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fTDLSDisRsp, ht2040_bss_coexistence),
+	offsetof(tDot11fIEht2040_bss_coexistence, present), 0,
+	"ht2040_bss_coexistence", 0, 3, 3, SigIeht2040_bss_coexistence,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040_BSS_COEXISTENCE, 0, 0, },
+	{ offsetof(tDot11fTDLSDisRsp, LinkIdentifier),
+	offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+	0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_LINKIDENTIFIER, 0, 1, },
+	{ offsetof(tDot11fTDLSDisRsp, VHTCaps), offsetof(tDot11fIEVHTCaps,
+	present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_dis_rsp(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fTDLSDisRsp *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_TDLSDisRsp, IES_TDLSDisRsp,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_tdls_dis_rsp. */
+
+static const tFFDefn FFS_TDLSPeerTrafficInd[] = {
+	{ "Category", offsetof(tDot11fTDLSPeerTrafficInd, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fTDLSPeerTrafficInd, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fTDLSPeerTrafficInd, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSPeerTrafficInd[] = {
+	{ offsetof(tDot11fTDLSPeerTrafficInd, LinkIdentifier),
+	offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+	0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_LINKIDENTIFIER, 0, 1, },
+	{ offsetof(tDot11fTDLSPeerTrafficInd, PTIControl),
+	offsetof(tDot11fIEPTIControl, present), 0, "PTIControl",
+	0, 5, 5, SigIePTIControl, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_PTICONTROL, 0, 0, },
+	{ offsetof(tDot11fTDLSPeerTrafficInd, PUBufferStatus),
+	offsetof(tDot11fIEPUBufferStatus, present), 0, "PUBufferStatus",
+	0, 3, 3, SigIePUBufferStatus, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_PUBUFFERSTATUS, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_peer_traffic_ind(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fTDLSPeerTrafficInd *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_TDLSPeerTrafficInd, IES_TDLSPeerTrafficInd,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_tdls_peer_traffic_ind. */
+
+static const tFFDefn FFS_TDLSPeerTrafficRsp[] = {
+	{ "Category", offsetof(tDot11fTDLSPeerTrafficRsp, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fTDLSPeerTrafficRsp, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fTDLSPeerTrafficRsp, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSPeerTrafficRsp[] = {
+	{ offsetof(tDot11fTDLSPeerTrafficRsp, LinkIdentifier),
+	offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+	0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_LINKIDENTIFIER, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_peer_traffic_rsp(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fTDLSPeerTrafficRsp *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_TDLSPeerTrafficRsp, IES_TDLSPeerTrafficRsp,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_tdls_peer_traffic_rsp. */
+
+static const tFFDefn FFS_TDLSSetupCnf[] = {
+	{ "Category", offsetof(tDot11fTDLSSetupCnf, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fTDLSSetupCnf, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "Status", offsetof(tDot11fTDLSSetupCnf, Status), SigFfStatus,
+	DOT11F_FF_STATUS_LEN, },
+	{ "DialogToken", offsetof(tDot11fTDLSSetupCnf, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSSetupCnf[] = {
+	{ offsetof(tDot11fTDLSSetupCnf, RSN), offsetof(tDot11fIERSN, present), 0,
+	"RSN", 0, 4, 132, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupCnf, EDCAParamSet),
+	offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet",
+	0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EDCAPARAMSET, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupCnf, FTInfo), offsetof(tDot11fIEFTInfo,
+	present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FTINFO, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupCnf, TimeoutInterval),
+	offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+	0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TIMEOUTINTERVAL, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupCnf, HTInfo), offsetof(tDot11fIEHTInfo,
+	present), 0, "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTINFO, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupCnf, LinkIdentifier),
+	offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+	0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_LINKIDENTIFIER, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupCnf, WMMParams), offsetof(tDot11fIEWMMParams,
+	present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+	5, DOT11F_EID_WMMPARAMS, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupCnf, VHTOperation),
+	offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+	0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTOPERATION, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupCnf, OperatingMode),
+	offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+	0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OPERATINGMODE, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_setup_cnf(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fTDLSSetupCnf *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_TDLSSetupCnf, IES_TDLSSetupCnf,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_tdls_setup_cnf. */
+
+static const tFFDefn FFS_TDLSSetupReq[] = {
+	{ "Category", offsetof(tDot11fTDLSSetupReq, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fTDLSSetupReq, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fTDLSSetupReq, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "Capabilities", offsetof(tDot11fTDLSSetupReq, Capabilities),
+	SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSSetupReq[] = {
+	{ offsetof(tDot11fTDLSSetupReq, SuppRates), offsetof(tDot11fIESuppRates,
+	present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 1, },
+	{ offsetof(tDot11fTDLSSetupReq, Country), offsetof(tDot11fIECountry,
+	present), 0, "Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_COUNTRY, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, ExtSuppRates),
+	offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+	0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, SuppChannels),
+	offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels",
+	0, 2, 98, SigIeSuppChannels, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPCHANNELS, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, RSN), offsetof(tDot11fIERSN, present), 0,
+	"RSN", 0, 4, 132, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, ExtCap), offsetof(tDot11fIEExtCap,
+	present), 0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, SuppOperatingClasses),
+	offsetof(tDot11fIESuppOperatingClasses, present), 0,
+	"SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, QOSCapsStation),
+	offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation",
+	0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QOSCAPSSTATION, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, FTInfo), offsetof(tDot11fIEFTInfo,
+	present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FTINFO, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, TimeoutInterval),
+	offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+	0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TIMEOUTINTERVAL, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, RICData), offsetof(tDot11fIERICData,
+	present), 0, "RICData", 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RICDATA, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, HTCaps), offsetof(tDot11fIEHTCaps,
+	present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, ht2040_bss_coexistence),
+	offsetof(tDot11fIEht2040_bss_coexistence, present), 0,
+	"ht2040_bss_coexistence", 0, 3, 3, SigIeht2040_bss_coexistence,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040_BSS_COEXISTENCE, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, LinkIdentifier),
+	offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+	0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_LINKIDENTIFIER, 0, 1, },
+	{ offsetof(tDot11fTDLSSetupReq, WMMInfoStation),
+	offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation",
+	0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0},
+	5, DOT11F_EID_WMMINFOSTATION, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, AID), offsetof(tDot11fIEAID, present), 0,
+	"AID", 0, 4, 4, SigIeAID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_AID, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupReq, VHTCaps), offsetof(tDot11fIEVHTCaps,
+	present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_setup_req(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fTDLSSetupReq *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_TDLSSetupReq, IES_TDLSSetupReq,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_tdls_setup_req. */
+
+static const tFFDefn FFS_TDLSSetupRsp[] = {
+	{ "Category", offsetof(tDot11fTDLSSetupRsp, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fTDLSSetupRsp, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "Status", offsetof(tDot11fTDLSSetupRsp, Status), SigFfStatus,
+	DOT11F_FF_STATUS_LEN, },
+	{ "DialogToken", offsetof(tDot11fTDLSSetupRsp, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "Capabilities", offsetof(tDot11fTDLSSetupRsp, Capabilities),
+	SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSSetupRsp[] = {
+	{ offsetof(tDot11fTDLSSetupRsp, SuppRates), offsetof(tDot11fIESuppRates,
+	present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPRATES, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, Country), offsetof(tDot11fIECountry,
+	present), 0, "Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_COUNTRY, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, ExtSuppRates),
+	offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+	0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTSUPPRATES, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, SuppChannels),
+	offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels",
+	0, 2, 98, SigIeSuppChannels, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_SUPPCHANNELS, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, RSN), offsetof(tDot11fIERSN, present), 0,
+	"RSN", 0, 4, 132, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, ExtCap), offsetof(tDot11fIEExtCap,
+	present), 0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, SuppOperatingClasses),
+	offsetof(tDot11fIESuppOperatingClasses, present), 0,
+	"SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, QOSCapsStation),
+	offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation",
+	0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_QOSCAPSSTATION, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, FTInfo), offsetof(tDot11fIEFTInfo,
+	present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FTINFO, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, TimeoutInterval),
+	offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+	0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TIMEOUTINTERVAL, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, RICData), offsetof(tDot11fIERICData,
+	present), 0, "RICData", 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_RICDATA, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, HTCaps), offsetof(tDot11fIEHTCaps,
+	present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, ht2040_bss_coexistence),
+	offsetof(tDot11fIEht2040_bss_coexistence, present), 0,
+	"ht2040_bss_coexistence", 0, 3, 3, SigIeht2040_bss_coexistence,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040_BSS_COEXISTENCE, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, LinkIdentifier),
+	offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+	0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_LINKIDENTIFIER, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, WMMInfoStation),
+	offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation",
+	0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0},
+	5, DOT11F_EID_WMMINFOSTATION, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, AID), offsetof(tDot11fIEAID, present), 0,
+	"AID", 0, 4, 4, SigIeAID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_AID, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, VHTCaps), offsetof(tDot11fIEVHTCaps,
+	present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fTDLSSetupRsp, OperatingMode),
+	offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+	0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OPERATINGMODE, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_setup_rsp(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fTDLSSetupRsp *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_TDLSSetupRsp, IES_TDLSSetupRsp,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_tdls_setup_rsp. */
+
+static const tFFDefn FFS_TDLSTeardown[] = {
+	{ "Category", offsetof(tDot11fTDLSTeardown, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fTDLSTeardown, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "Reason", offsetof(tDot11fTDLSTeardown, Reason), SigFfReason,
+	DOT11F_FF_REASON_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSTeardown[] = {
+	{ offsetof(tDot11fTDLSTeardown, FTInfo), offsetof(tDot11fIEFTInfo,
+	present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_FTINFO, 0, 0, },
+	{ offsetof(tDot11fTDLSTeardown, LinkIdentifier),
+	offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+	0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_LINKIDENTIFIER, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_teardown(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fTDLSTeardown *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_TDLSTeardown, IES_TDLSTeardown,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_tdls_teardown. */
+
+static const tFFDefn FFS_TPCReport[] = {
+	{ "Category", offsetof(tDot11fTPCReport, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fTPCReport, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fTPCReport, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TPCReport[] = {
+	{ offsetof(tDot11fTPCReport, TPCReport), offsetof(tDot11fIETPCReport,
+	present), 0, "TPCReport", 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TPCREPORT, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tpc_report(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fTPCReport *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_TPCReport, IES_TPCReport,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_tpc_report. */
+
+static const tFFDefn FFS_TPCRequest[] = {
+	{ "Category", offsetof(tDot11fTPCRequest, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fTPCRequest, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fTPCRequest, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TPCRequest[] = {
+	{ offsetof(tDot11fTPCRequest, TPCRequest), offsetof(tDot11fIETPCRequest,
+	present), 0, "TPCRequest", 0, 2, 2, SigIeTPCRequest, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TPCREQUEST, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tpc_request(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fTPCRequest *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_TPCRequest, IES_TPCRequest,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_tpc_request. */
+
+static const tFFDefn FFS_TimingAdvertisementFrame[] = {
+	{ "TimeStamp", offsetof(tDot11fTimingAdvertisementFrame, TimeStamp),
+	SigFfTimeStamp, DOT11F_FF_TIMESTAMP_LEN, },
+	{ "Capabilities", offsetof(tDot11fTimingAdvertisementFrame,
+	Capabilities), SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TimingAdvertisementFrame[] = {
+	{ offsetof(tDot11fTimingAdvertisementFrame, Country),
+	offsetof(tDot11fIECountry, present), 0, "Country", 0, 5, 257, SigIeCountry,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, 0, },
+	{ offsetof(tDot11fTimingAdvertisementFrame, PowerConstraints),
+	offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints",
+	0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_POWERCONSTRAINTS, 0, 0, },
+	{ offsetof(tDot11fTimingAdvertisementFrame, TimeAdvertisement),
+	offsetof(tDot11fIETimeAdvertisement, present), 0, "TimeAdvertisement",
+	0, 18, 18, SigIeTimeAdvertisement, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_TIMEADVERTISEMENT, 0, 0, },
+	{ offsetof(tDot11fTimingAdvertisementFrame, ExtCap),
+	offsetof(tDot11fIEExtCap, present), 0, "ExtCap", 0, 3, 17, SigIeExtCap,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, 0, },
+	{ offsetof(tDot11fTimingAdvertisementFrame, Vendor1IE),
+	offsetof(tDot11fIEVendor1IE, present), 0, "Vendor1IE",
+	0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0},
+	3, DOT11F_EID_VENDOR1IE, 0, 0, },
+	{ offsetof(tDot11fTimingAdvertisementFrame, Vendor3IE),
+	offsetof(tDot11fIEVendor3IE, present), 0, "Vendor3IE",
+	0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0},
+	3, DOT11F_EID_VENDOR3IE, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_timing_advertisement_frame(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fTimingAdvertisementFrame *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_TimingAdvertisementFrame, IES_TimingAdvertisementFrame,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_timing_advertisement_frame. */
+
+static const tFFDefn FFS_VHTGidManagementActionFrame[] = {
+	{ "Category", offsetof(tDot11fVHTGidManagementActionFrame, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fVHTGidManagementActionFrame, Action),
+	SigFfAction, DOT11F_FF_ACTION_LEN, },
+	{ "VhtMembershipStatusArray",
+	offsetof(tDot11fVHTGidManagementActionFrame, VhtMembershipStatusArray),
+	SigFfVhtMembershipStatusArray,
+	DOT11F_FF_VHTMEMBERSHIPSTATUSARRAY_LEN, },
+	{ "VhtUserPositionArray", offsetof(tDot11fVHTGidManagementActionFrame,
+	VhtUserPositionArray), SigFfVhtUserPositionArray,
+	DOT11F_FF_VHTUSERPOSITIONARRAY_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_VHTGidManagementActionFrame[] = {
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_vht_gid_management_action_frame(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fVHTGidManagementActionFrame *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_VHTGidManagementActionFrame, IES_VHTGidManagementActionFrame,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_vht_gid_management_action_frame. */
+
+static const tFFDefn FFS_WMMAddTSRequest[] = {
+	{ "Category", offsetof(tDot11fWMMAddTSRequest, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fWMMAddTSRequest, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fWMMAddTSRequest, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "StatusCode", offsetof(tDot11fWMMAddTSRequest, StatusCode),
+	SigFfStatusCode, DOT11F_FF_STATUSCODE_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_WMMAddTSRequest[] = {
+	{ offsetof(tDot11fWMMAddTSRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+	present), 0, "WMMTSPEC", 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+	5, DOT11F_EID_WMMTSPEC, 0, 1, },
+	{ offsetof(tDot11fWMMAddTSRequest, ESETrafStrmRateSet),
+	offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet",
+	0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0},
+	4, DOT11F_EID_ESETRAFSTRMRATESET, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_wmm_add_ts_request(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fWMMAddTSRequest *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_WMMAddTSRequest, IES_WMMAddTSRequest,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_wmm_add_ts_request. */
+
+static const tFFDefn FFS_WMMAddTSResponse[] = {
+	{ "Category", offsetof(tDot11fWMMAddTSResponse, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fWMMAddTSResponse, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fWMMAddTSResponse, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "StatusCode", offsetof(tDot11fWMMAddTSResponse, StatusCode),
+	SigFfStatusCode, DOT11F_FF_STATUSCODE_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_WMMAddTSResponse[] = {
+	{ offsetof(tDot11fWMMAddTSResponse, WMMTSPEC),
+	offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC",
+	0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+	5, DOT11F_EID_WMMTSPEC, 0, 0, },
+	{ offsetof(tDot11fWMMAddTSResponse, ESETrafStrmMet),
+	offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+	0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+	4, DOT11F_EID_ESETRAFSTRMMET, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_wmm_add_ts_response(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fWMMAddTSResponse *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_WMMAddTSResponse, IES_WMMAddTSResponse,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_wmm_add_ts_response. */
+
+static const tFFDefn FFS_WMMDelTS[] = {
+	{ "Category", offsetof(tDot11fWMMDelTS, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fWMMDelTS, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11fWMMDelTS, DialogToken), SigFfDialogToken,
+	DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "StatusCode", offsetof(tDot11fWMMDelTS, StatusCode), SigFfStatusCode,
+	DOT11F_FF_STATUSCODE_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_WMMDelTS[] = {
+	{ offsetof(tDot11fWMMDelTS, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+	present), 0, "WMMTSPEC", 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+	5, DOT11F_EID_WMMTSPEC, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_wmm_del_ts(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fWMMDelTS *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_WMMDelTS, IES_WMMDelTS,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_wmm_del_ts. */
+
+static const tFFDefn FFS_addba_req[] = {
+	{ "Category", offsetof(tDot11faddba_req, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11faddba_req, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11faddba_req, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "addba_param_set", offsetof(tDot11faddba_req, addba_param_set),
+	SigFfaddba_param_set, DOT11F_FF_ADDBA_PARAM_SET_LEN, },
+	{ "ba_timeout", offsetof(tDot11faddba_req, ba_timeout), SigFfba_timeout,
+	DOT11F_FF_BA_TIMEOUT_LEN, },
+	{ "ba_start_seq_ctrl", offsetof(tDot11faddba_req, ba_start_seq_ctrl),
+	SigFfba_start_seq_ctrl, DOT11F_FF_BA_START_SEQ_CTRL_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_addba_req[] = {
+	{ offsetof(tDot11faddba_req, addba_extn_element),
+	offsetof(tDot11fIEaddba_extn_element, present), 0, "addba_extn_element",
+	0, 3, 3, SigIeaddba_extn_element, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_ADDBA_EXTN_ELEMENT, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_addba_req(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11faddba_req *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_addba_req, IES_addba_req,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_addba_req. */
+
+static const tFFDefn FFS_addba_rsp[] = {
+	{ "Category", offsetof(tDot11faddba_rsp, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11faddba_rsp, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "DialogToken", offsetof(tDot11faddba_rsp, DialogToken),
+	SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ "Status", offsetof(tDot11faddba_rsp, Status), SigFfStatus,
+	DOT11F_FF_STATUS_LEN, },
+	{ "addba_param_set", offsetof(tDot11faddba_rsp, addba_param_set),
+	SigFfaddba_param_set, DOT11F_FF_ADDBA_PARAM_SET_LEN, },
+	{ "ba_timeout", offsetof(tDot11faddba_rsp, ba_timeout), SigFfba_timeout,
+	DOT11F_FF_BA_TIMEOUT_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_addba_rsp[] = {
+	{ offsetof(tDot11faddba_rsp, addba_extn_element),
+	offsetof(tDot11fIEaddba_extn_element, present), 0, "addba_extn_element",
+	0, 3, 3, SigIeaddba_extn_element, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_ADDBA_EXTN_ELEMENT, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_addba_rsp(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11faddba_rsp *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_addba_rsp, IES_addba_rsp,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_addba_rsp. */
+
+static const tFFDefn FFS_delba_req[] = {
+	{ "Category", offsetof(tDot11fdelba_req, Category), SigFfCategory,
+	DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fdelba_req, Action), SigFfAction,
+	DOT11F_FF_ACTION_LEN, },
+	{ "delba_param_set", offsetof(tDot11fdelba_req, delba_param_set),
+	SigFfdelba_param_set, DOT11F_FF_DELBA_PARAM_SET_LEN, },
+	{ "Reason", offsetof(tDot11fdelba_req, Reason), SigFfReason,
+	DOT11F_FF_REASON_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_delba_req[] = {
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_delba_req(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fdelba_req *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_delba_req, IES_delba_req,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_delba_req. */
+
+static const tFFDefn FFS_ext_channel_switch_action_frame[] = {
+	{ "Category", offsetof(tDot11fext_channel_switch_action_frame, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fext_channel_switch_action_frame, Action),
+	SigFfAction, DOT11F_FF_ACTION_LEN, },
+	{ "ext_chan_switch_ann_action",
+	offsetof(tDot11fext_channel_switch_action_frame,
+	ext_chan_switch_ann_action), SigFfext_chan_switch_ann_action,
+	DOT11F_FF_EXT_CHAN_SWITCH_ANN_ACTION_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ext_channel_switch_action_frame[] = {
+	{ offsetof(tDot11fext_channel_switch_action_frame,
+	WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present),
+	0, "WiderBWChanSwitchAnn", 0, 5, 5, SigIeWiderBWChanSwitchAnn,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_ext_channel_switch_action_frame(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fext_channel_switch_action_frame *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_ext_channel_switch_action_frame, IES_ext_channel_switch_action_frame,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_ext_channel_switch_action_frame. */
+
+static const tFFDefn FFS_ht2040_bss_coexistence_mgmt_action_frame[] = {
+	{ "Category", offsetof(tDot11fht2040_bss_coexistence_mgmt_action_frame,
+	Category), SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "Action", offsetof(tDot11fht2040_bss_coexistence_mgmt_action_frame,
+	Action), SigFfAction, DOT11F_FF_ACTION_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ht2040_bss_coexistence_mgmt_action_frame[] = {
+	{ offsetof(tDot11fht2040_bss_coexistence_mgmt_action_frame,
+	ht2040_bss_coexistence), offsetof(tDot11fIEht2040_bss_coexistence,
+	present), 0, "ht2040_bss_coexistence",
+	0, 3, 3, SigIeht2040_bss_coexistence, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HT2040_BSS_COEXISTENCE, 0, 1, },
+	{ offsetof(tDot11fht2040_bss_coexistence_mgmt_action_frame,
+	ht2040_bss_intolerant_report),
+	offsetof(tDot11fIEht2040_bss_intolerant_report, present), 0,
+	"ht2040_bss_intolerant_report",
+	0, 3, 53, SigIeht2040_bss_intolerant_report, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_HT2040_BSS_INTOLERANT_REPORT, 0, 1, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_ht2040_bss_coexistence_mgmt_action_frame(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fht2040_bss_coexistence_mgmt_action_frame *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_ht2040_bss_coexistence_mgmt_action_frame, IES_ht2040_bss_coexistence_mgmt_action_frame,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_ht2040_bss_coexistence_mgmt_action_frame. */
+
+static const tFFDefn FFS_p2p_oper_chan_change_confirm[] = {
+	{ "Category", offsetof(tDot11fp2p_oper_chan_change_confirm, Category),
+	SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+	{ "p2p_action_oui", offsetof(tDot11fp2p_oper_chan_change_confirm,
+	p2p_action_oui), SigFfp2p_action_oui, DOT11F_FF_P2P_ACTION_OUI_LEN, },
+	{ "p2p_action_subtype", offsetof(tDot11fp2p_oper_chan_change_confirm,
+	p2p_action_subtype), SigFfp2p_action_subtype,
+	DOT11F_FF_P2P_ACTION_SUBTYPE_LEN, },
+	{ "DialogToken", offsetof(tDot11fp2p_oper_chan_change_confirm,
+	DialogToken), SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+	{ NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_p2p_oper_chan_change_confirm[] = {
+	{ offsetof(tDot11fp2p_oper_chan_change_confirm, HTCaps),
+	offsetof(tDot11fIEHTCaps, present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, 0, },
+	{ offsetof(tDot11fp2p_oper_chan_change_confirm, VHTCaps),
+	offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps,
+	{0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, 0, },
+	{ offsetof(tDot11fp2p_oper_chan_change_confirm, OperatingMode),
+	offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+	0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+	0, DOT11F_EID_OPERATINGMODE, 0, 0, },
+	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_p2p_oper_chan_change_confirm(tpAniSirGlobal pCtx,
+		uint8_t *pBuf, uint32_t nBuf,
+		tDot11fp2p_oper_chan_change_confirm *pFrm, bool append_ie)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	status = unpack_core(pCtx, pBuf, nBuf,
+		      FFS_p2p_oper_chan_change_confirm, IES_p2p_oper_chan_change_confirm,
+		      (uint8_t *)pFrm, sizeof(*pFrm), append_ie);
+
+	(void)i;
+	return status;
+
+} /* End dot11f_unpack_p2p_oper_chan_change_confirm. */
+
+/**
+ * Note: If @append_ie is set TRUE, pFrm will not be reset to zero,
+ * but parsed IE's would be populated to pFrm with already
+ * populated IE's in pFrm
+ */
+static uint32_t unpack_core(tpAniSirGlobal pCtx,
+			    uint8_t *pBuf,
+			    uint32_t nBuf,
+			    const tFFDefn  FFs[],
+			    const tIEDefn  IEs[],
+			    uint8_t *pFrm,
+			    size_t nFrm,
+			    bool append_ie)
+{
+	const tFFDefn *pFf;
+	const tIEDefn *pIe;
+	uint8_t   *pBufRemaining;
+	uint32_t  nBufRemaining, status;
+	uint8_t   eid, len, extn_eid;
+	tFRAMES_BOOL  *pfFound;
+	uint32_t  countOffset = 0;
+
+	DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm);
+	(void)nFrm;
+
+	(void)pCtx;
+	status = DOT11F_PARSE_SUCCESS;
+	pBufRemaining = pBuf;
+	nBufRemaining = nBuf;
+
+	pIe = &IEs[0];
+	while (!append_ie && (0xff != pIe->eid || pIe->extn_eid)) {
+		pfFound = (tFRAMES_BOOL *)(pFrm + pIe->offset +
+				   pIe->presenceOffset);
+		*pfFound = 0U;
+		if (pIe->countOffset)
+			*(uint16_t *)(pFrm + pIe->countOffset) = 0U;
+		++pIe;
+	}
+
+	pFf = &FFs[0];
+	while (!append_ie && pFf->size) {
+		if (pFf->size > nBufRemaining) {
+			FRAMES_LOG3(pCtx, FRLOGE, FRFL("Fixed field %s is %d"
+					  "bytes in size, but there are only %d bytes left i"
+					  "n this frame.\n"), pFf->name, pFf->size,
+					  nBufRemaining);
+			FRAMES_DBG_BREAK();
+			return DOT11F_MISSING_FIXED_FIELD;
+		}
+
+		switch (pFf->sig) {
+
+		case SigFfAID:
+			dot11f_unpack_ff_common_func(pCtx,
+			    pBufRemaining, (uint16_t *)&(((tDot11fFfAID *)
+			    (pFrm + pFf->offset))->associd));
+			break;
+		case SigFfAction:
+			dot11f_unpack_ff_action(pCtx,
+			    pBufRemaining, (tDot11fFfAction *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfAuthAlgo:
+			dot11f_unpack_ff_common_func(pCtx,
+			    pBufRemaining, (uint16_t *)&(((tDot11fFfAuthAlgo *)
+			    (pFrm + pFf->offset))->algo));
+			break;
+		case SigFfAuthSeqNo:
+			dot11f_unpack_ff_common_func(pCtx,
+			    pBufRemaining, (uint16_t *)&(((tDot11fFfAuthSeqNo *)
+			    (pFrm + pFf->offset))->no));
+			break;
+		case SigFfBeaconInterval:
+			dot11f_unpack_ff_common_func(pCtx,
+			    pBufRemaining, (uint16_t *)&(((tDot11fFfBeaconInterval *)
+			    (pFrm + pFf->offset))->interval));
+			break;
+		case SigFfCapabilities:
+			dot11f_unpack_ff_capabilities(pCtx,
+			    pBufRemaining, (tDot11fFfCapabilities *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfCategory:
+			dot11f_unpack_ff_category(pCtx,
+			    pBufRemaining, (tDot11fFfCategory *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfCurrentAPAddress:
+			dot11f_unpack_ff_current_ap_address(pCtx,
+			    pBufRemaining, (tDot11fFfCurrentAPAddress *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfDialogToken:
+			dot11f_unpack_ff_dialog_token(pCtx,
+			    pBufRemaining, (tDot11fFfDialogToken *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfLinkMargin:
+			dot11f_unpack_ff_link_margin(pCtx,
+			    pBufRemaining, (tDot11fFfLinkMargin *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfListenInterval:
+			dot11f_unpack_ff_common_func(pCtx,
+			    pBufRemaining, (uint16_t *)&(((tDot11fFfListenInterval *)
+			    (pFrm + pFf->offset))->interval));
+			break;
+		case SigFfMaxTxPower:
+			dot11f_unpack_ff_max_tx_power(pCtx,
+			    pBufRemaining, (tDot11fFfMaxTxPower *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfNumOfRepetitions:
+			dot11f_unpack_ff_num_of_repetitions(pCtx,
+			    pBufRemaining, (tDot11fFfNumOfRepetitions *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfOperatingMode:
+			dot11f_unpack_ff_operating_mode(pCtx,
+			    pBufRemaining, (tDot11fFfOperatingMode *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfRCPI:
+			dot11f_unpack_ff_rcpi(pCtx,
+			    pBufRemaining, (tDot11fFfRCPI *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfRSNI:
+			dot11f_unpack_ff_rsni(pCtx,
+			    pBufRemaining, (tDot11fFfRSNI *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfReason:
+			dot11f_unpack_ff_common_func(pCtx,
+			    pBufRemaining, (uint16_t *)&(((tDot11fFfReason *)
+			    (pFrm + pFf->offset))->code));
+			break;
+		case SigFfRxAntennaId:
+			dot11f_unpack_ff_rx_antenna_id(pCtx,
+			    pBufRemaining, (tDot11fFfRxAntennaId *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfSMPowerModeSet:
+			dot11f_unpack_ff_sm_power_mode_set(pCtx,
+			    pBufRemaining, (tDot11fFfSMPowerModeSet *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfStatus:
+			dot11f_unpack_ff_common_func(pCtx,
+			    pBufRemaining, (uint16_t *)&(((tDot11fFfStatus *)
+			    (pFrm + pFf->offset))->status));
+			break;
+		case SigFfStatusCode:
+			dot11f_unpack_ff_status_code(pCtx,
+			    pBufRemaining, (tDot11fFfStatusCode *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfTPCEleID:
+			dot11f_unpack_ff_tpc_ele_id(pCtx,
+			    pBufRemaining, (tDot11fFfTPCEleID *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfTPCEleLen:
+			dot11f_unpack_ff_tpc_ele_len(pCtx,
+			    pBufRemaining, (tDot11fFfTPCEleLen *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfTSInfo:
+			dot11f_unpack_ff_ts_info(pCtx,
+			    pBufRemaining, (tDot11fFfTSInfo *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfTimeStamp:
+			dot11f_unpack_ff_time_stamp(pCtx,
+			    pBufRemaining, (tDot11fFfTimeStamp *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfTransactionId:
+			dot11f_unpack_ff_transaction_id(pCtx,
+			    pBufRemaining, (tDot11fFfTransactionId *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfTxAntennaId:
+			dot11f_unpack_ff_tx_antenna_id(pCtx,
+			    pBufRemaining, (tDot11fFfTxAntennaId *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfTxPower:
+			dot11f_unpack_ff_tx_power(pCtx,
+			    pBufRemaining, (tDot11fFfTxPower *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfVhtMembershipStatusArray:
+			dot11f_unpack_ff_vht_membership_status_array(pCtx,
+			    pBufRemaining, (tDot11fFfVhtMembershipStatusArray *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfVhtUserPositionArray:
+			dot11f_unpack_ff_vht_user_position_array(pCtx,
+			    pBufRemaining, (tDot11fFfVhtUserPositionArray *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfaddba_param_set:
+			dot11f_unpack_ff_addba_param_set(pCtx,
+			    pBufRemaining, (tDot11fFfaddba_param_set *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfba_start_seq_ctrl:
+			dot11f_unpack_ff_ba_start_seq_ctrl(pCtx,
+			    pBufRemaining, (tDot11fFfba_start_seq_ctrl *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfba_timeout:
+			dot11f_unpack_ff_ba_timeout(pCtx,
+			    pBufRemaining, (tDot11fFfba_timeout *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfdelba_param_set:
+			dot11f_unpack_ff_delba_param_set(pCtx,
+			    pBufRemaining, (tDot11fFfdelba_param_set *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfext_chan_switch_ann_action:
+			dot11f_unpack_ff_ext_chan_switch_ann_action(pCtx,
+			    pBufRemaining, (tDot11fFfext_chan_switch_ann_action *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfp2p_action_oui:
+			dot11f_unpack_ff_p2p_action_oui(pCtx,
+			    pBufRemaining, (tDot11fFfp2p_action_oui *)
+			    (pFrm + pFf->offset));
+			break;
+		case SigFfp2p_action_subtype:
+			dot11f_unpack_ff_p2p_action_subtype(pCtx,
+			    pBufRemaining, (tDot11fFfp2p_action_subtype *)
+			    (pFrm + pFf->offset));
+			break;
+		default:
+			FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR: I don'"
+				   "t know about the FF signature %d-- this is most "
+				   "likely a 'framesc' bug.\n"), pFf->sig);
+			return DOT11F_INTERNAL_ERROR;
+		}
+
+		pBufRemaining += pFf->size;
+		nBufRemaining -= pFf->size;
+		++pFf;
+	}
+
+	while (nBufRemaining) {
+		if (1 == nBufRemaining) {
+			FRAMES_LOG0(pCtx, FRLOGE, FRFL("This frame reports "
+				    "only one byte remaining after it's fixed fields.\n"));
+			status |= DOT11F_INCOMPLETE_IE;
+			FRAMES_DBG_BREAK();
+			goto MandatoryCheck;
+		}
+
+		pIe = find_ie_defn(pCtx, pBufRemaining, nBufRemaining, IEs);
+
+		eid = *pBufRemaining++; --nBufRemaining;
+		len = *pBufRemaining++; --nBufRemaining;
+		if (pIe && pIe->extn_eid) {
+			extn_eid = *pBufRemaining++; --nBufRemaining;
+			len--;
+		}
+
+		if (pIe && pIe->noui) {
+			if (pIe->noui > nBufRemaining) {
+				FRAMES_LOG4(pCtx, FRLOGW, FRFL("IE %d extn id %d reports "
+					"length %d, but it has an OUI of %d bytes.\n"),
+					eid, extn_eid, len, pIe->noui);
+				FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+				FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d by"
+					"tes of this buffer, and show %d left.\n"),
+					pBufRemaining - pBuf, nBufRemaining);
+				status |= DOT11F_INCOMPLETE_IE;
+				FRAMES_DBG_BREAK();
+				goto MandatoryCheck;
+			}
+			pBufRemaining += pIe->noui;
+			nBufRemaining -= pIe->noui;
+			len           -= pIe->noui;
+		}
+
+		if (len > nBufRemaining) {
+			FRAMES_LOG4(pCtx, FRLOGW, FRFL("IE %d extn id %d reports length %"
+				"d, but there are only %d bytes remaining in this"
+				" frame.\n"), eid, extn_eid, len, nBufRemaining);
+			FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+			FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d by"
+				"tes of this buffer, and show %d left.\n"),
+				pBufRemaining - pBuf, nBufRemaining);
+			status |= DOT11F_INCOMPLETE_IE;
+			FRAMES_DBG_BREAK();
+			goto MandatoryCheck;
+		}
+
+		if (pIe) {
+			if ((nBufRemaining < pIe->minSize - pIe->noui - 2U) ||
+			    (len < pIe->minSize - pIe->noui - 2U)) {
+				FRAMES_LOG4(pCtx, FRLOGW, FRFL("The IE %s must "
+					"be at least %d bytes in size, but "
+					"there are only %d bytes remaining in "
+					"this frame or the IE reports a size "
+					"of %d bytes.\n"),
+					pIe->name, pIe->minSize, nBufRemaining,
+					(len + pIe->noui + 2U));
+				FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+				status |= DOT11F_INCOMPLETE_IE;
+				FRAMES_DBG_BREAK();
+				goto MandatoryCheck;
+			} else {
+				if (len > pIe->maxSize - pIe->noui - 2U) {
+				FRAMES_LOG1(pCtx, FRLOGW, FRFL("The IE %s reports "
+					"an unexpectedly large size; it is presumably "
+					"more up-to-date than this parser, but this wa"
+					"rning may also indicate a corrupt frame.\n"),
+					pIe->name);
+					FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+				}
+
+				countOffset = ((0 != pIe->arraybound) *
+						(*(uint16_t *)(pFrm + pIe->countOffset)));
+				if (0 != pIe->arraybound && countOffset >= pIe->arraybound) {
+					status |= DOT11F_DUPLICATE_IE;
+					goto skip_dup_ie;
+				}
+				switch (pIe->sig) {
+				case SigIeGTK:
+					status |=
+						dot11f_unpack_ie_gtk(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEGTK *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEGTK) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeIGTK:
+					status |=
+						dot11f_unpack_ie_igtk(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEIGTK *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEIGTK) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeR0KH_ID:
+					status |=
+						dot11f_unpack_ie_r0_kh_id(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIER0KH_ID *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIER0KH_ID) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeR1KH_ID:
+					status |=
+						dot11f_unpack_ie_r1_kh_id(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIER1KH_ID *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIER1KH_ID) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeAPChannelReport:
+					status |=
+						dot11f_unpack_ie_ap_channel_report(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEAPChannelReport *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEAPChannelReport) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeBcnReportingDetail:
+					status |=
+						dot11f_unpack_ie_bcn_reporting_detail(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEBcnReportingDetail *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEBcnReportingDetail) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeBeaconReportFrmBody:
+					status |=
+						dot11f_unpack_ie_beacon_report_frm_body(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEBeaconReportFrmBody *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEBeaconReportFrmBody) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeBeaconReporting:
+					status |=
+						dot11f_unpack_ie_beacon_reporting(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEBeaconReporting *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEBeaconReporting) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeCondensedCountryStr:
+					status |=
+						dot11f_unpack_ie_condensed_country_str(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIECondensedCountryStr *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIECondensedCountryStr) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeMeasurementPilot:
+					status |=
+						dot11f_unpack_ie_measurement_pilot(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEMeasurementPilot *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEMeasurementPilot) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeMultiBssid:
+					status |=
+						dot11f_unpack_ie_multi_bssid(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEMultiBssid *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEMultiBssid) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeRICData:
+					status |=
+						dot11f_unpack_ie_ric_data(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIERICData *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIERICData) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeRICDescriptor:
+					status |=
+						dot11f_unpack_ie_ric_descriptor(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIERICDescriptor *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIERICDescriptor) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeRRMEnabledCap:
+					status |=
+						dot11f_unpack_ie_rrm_enabled_cap(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIERRMEnabledCap *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIERRMEnabledCap) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeRequestedInfo:
+					status |=
+						dot11f_unpack_ie_requested_info(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIERequestedInfo *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIERequestedInfo) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeSSID:
+					status |=
+						dot11f_unpack_ie_ssid(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIESSID *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIESSID) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeSchedule:
+					status |=
+						dot11f_unpack_ie_schedule(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIESchedule *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIESchedule) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeTCLAS:
+					status |=
+						dot11f_unpack_ie_tclas(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIETCLAS *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIETCLAS) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeTCLASSPROC:
+					status |= dot11f_unpack_ie_common_func(pCtx, pBufRemaining, len,
+										(uint8_t *) &(((tDot11fIETCLASSPROC *)(pFrm + pIe->offset + sizeof(tDot11fIETCLASSPROC)*countOffset))->present),
+										(uint8_t *) &(((tDot11fIETCLASSPROC *)(pFrm + pIe->offset + sizeof(tDot11fIETCLASSPROC)*countOffset))->processing));
+					break;
+				case SigIeTSDelay:
+					status |=
+						dot11f_unpack_ie_ts_delay(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIETSDelay *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIETSDelay) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeTSFInfo:
+					status |=
+						dot11f_unpack_ie_tsf_info(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIETSFInfo *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIETSFInfo) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeTSPEC:
+					status |=
+						dot11f_unpack_ie_tspec(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIETSPEC *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIETSPEC) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeVHTCaps:
+					status |=
+						dot11f_unpack_ie_vht_caps(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEVHTCaps *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEVHTCaps) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeVHTOperation:
+					status |=
+						dot11f_unpack_ie_vht_operation(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEVHTOperation *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEVHTOperation) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWMMSchedule:
+					status |=
+						dot11f_unpack_ie_wmm_schedule(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWMMSchedule *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWMMSchedule) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWMMTCLAS:
+					status |=
+						dot11f_unpack_ie_wmmtclas(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWMMTCLAS *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWMMTCLAS) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWMMTCLASPROC:
+					status |=
+						dot11f_unpack_ie_wmmtclasproc(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWMMTCLASPROC *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWMMTCLASPROC) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWMMTSDelay:
+					status |=
+						dot11f_unpack_ie_wmmts_delay(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWMMTSDelay *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWMMTSDelay) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWMMTSPEC:
+					status |=
+						dot11f_unpack_ie_wmmtspec(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWMMTSPEC *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWMMTSPEC) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWiderBWChanSwitchAnn:
+					status |=
+						dot11f_unpack_ie_wider_bw_chan_switch_ann(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWiderBWChanSwitchAnn *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWiderBWChanSwitchAnn) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeazimuth_req:
+					status |=
+						dot11f_unpack_ie_azimuth_req(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEazimuth_req *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEazimuth_req) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIebeacon_report_frm_body_fragment_id:
+					status |=
+						dot11f_unpack_ie_beacon_report_frm_body_fragment_id(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEbeacon_report_frm_body_fragment_id *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEbeacon_report_frm_body_fragment_id) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIelast_beacon_report_indication:
+					status |=
+						dot11f_unpack_ie_last_beacon_report_indication(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIElast_beacon_report_indication *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIElast_beacon_report_indication) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIemax_age:
+					status |=
+						dot11f_unpack_ie_max_age(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEmax_age *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEmax_age) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeneighbor_rpt:
+					status |=
+						dot11f_unpack_ie_neighbor_rpt(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEneighbor_rpt *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEneighbor_rpt) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIereq_mac_addr:
+					status |=
+						dot11f_unpack_ie_req_mac_addr(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEreq_mac_addr *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEreq_mac_addr) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIetgt_mac_addr:
+					status |=
+						dot11f_unpack_ie_tgt_mac_addr(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEtgt_mac_addr *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEtgt_mac_addr) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIevht_transmit_power_env:
+					status |=
+						dot11f_unpack_ie_vht_transmit_power_env(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEvht_transmit_power_env *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEvht_transmit_power_env) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeAID:
+					status |=
+						dot11f_unpack_ie_aid(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEAID *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEAID) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeCFParams:
+					status |=
+						dot11f_unpack_ie_cf_params(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIECFParams *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIECFParams) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeChallengeText:
+					status |=
+						dot11f_unpack_ie_challenge_text(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEChallengeText *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEChallengeText) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeChanSwitchAnn:
+					status |=
+						dot11f_unpack_ie_chan_switch_ann(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEChanSwitchAnn *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEChanSwitchAnn) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeChannelSwitchWrapper:
+					status |=
+						dot11f_unpack_ie_channel_switch_wrapper(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEChannelSwitchWrapper *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEChannelSwitchWrapper) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeCountry:
+					status |=
+						dot11f_unpack_ie_country(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIECountry *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIECountry) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeDSParams:
+					status |= dot11f_unpack_ie_common_func(pCtx, pBufRemaining, len,
+										(uint8_t *) &(((tDot11fIEDSParams *)(pFrm + pIe->offset + sizeof(tDot11fIEDSParams)*countOffset))->present),
+										(uint8_t *) &(((tDot11fIEDSParams *)(pFrm + pIe->offset + sizeof(tDot11fIEDSParams)*countOffset))->curr_channel));
+					break;
+				case SigIeEDCAParamSet:
+					status |=
+						dot11f_unpack_ie_edca_param_set(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEEDCAParamSet *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEEDCAParamSet) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeERPInfo:
+					status |=
+						dot11f_unpack_ie_erp_info(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEERPInfo *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEERPInfo) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeESECckmOpaque:
+					status |=
+						dot11f_unpack_ie_ese_cckm_opaque(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEESECckmOpaque *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEESECckmOpaque) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeESERadMgmtCap:
+					status |=
+						dot11f_unpack_ie_ese_rad_mgmt_cap(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEESERadMgmtCap *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEESERadMgmtCap) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeESETrafStrmMet:
+					status |=
+						dot11f_unpack_ie_ese_traf_strm_met(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEESETrafStrmMet *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEESETrafStrmMet) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeESETrafStrmRateSet:
+					status |=
+						dot11f_unpack_ie_ese_traf_strm_rate_set(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEESETrafStrmRateSet *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEESETrafStrmRateSet) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeESETxmitPower:
+					status |=
+						dot11f_unpack_ie_ese_txmit_power(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEESETxmitPower *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEESETxmitPower) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeESEVersion:
+					status |=
+						dot11f_unpack_ie_ese_version(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEESEVersion *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEESEVersion) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeExtCap:
+					status |=
+						dot11f_unpack_ie_ext_cap(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEExtCap *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEExtCap) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeExtSuppRates:
+					status |=
+						dot11f_unpack_ie_ext_supp_rates(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEExtSuppRates *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEExtSuppRates) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeFHParamSet:
+					status |=
+						dot11f_unpack_ie_fh_param_set(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEFHParamSet *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEFHParamSet) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeFHParams:
+					status |=
+						dot11f_unpack_ie_fh_params(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEFHParams *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEFHParams) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeFHPattTable:
+					status |=
+						dot11f_unpack_ie_fh_patt_table(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEFHPattTable *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEFHPattTable) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeFTInfo:
+					status |=
+						dot11f_unpack_ie_ft_info(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEFTInfo *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEFTInfo) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeHTCaps:
+					status |=
+						dot11f_unpack_ie_ht_caps(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEHTCaps *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEHTCaps) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeHTInfo:
+					status |=
+						dot11f_unpack_ie_ht_info(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEHTInfo *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEHTInfo) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeIBSSParams:
+					status |=
+						dot11f_unpack_ie_ibss_params(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEIBSSParams *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEIBSSParams) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeLinkIdentifier:
+					status |=
+						dot11f_unpack_ie_link_identifier(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIELinkIdentifier *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIELinkIdentifier) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeMBO_IE:
+					status |=
+						dot11f_unpack_ie_MBO_IE(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEMBO_IE *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEMBO_IE) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeMeasurementReport:
+					status |=
+						dot11f_unpack_ie_measurement_report(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEMeasurementReport *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEMeasurementReport) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeMeasurementRequest:
+					status |=
+						dot11f_unpack_ie_measurement_request(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEMeasurementRequest *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEMeasurementRequest) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeMobilityDomain:
+					status |=
+						dot11f_unpack_ie_mobility_domain(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEMobilityDomain *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEMobilityDomain) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeNeighborReport:
+					status |=
+						dot11f_unpack_ie_neighbor_report(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIENeighborReport *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIENeighborReport) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeOBSSScanParameters:
+					status |=
+						dot11f_unpack_ie_obss_scan_parameters(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEOBSSScanParameters *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEOBSSScanParameters) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeOperatingMode:
+					status |=
+						dot11f_unpack_ie_operating_mode(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEOperatingMode *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEOperatingMode) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeP2PAssocReq:
+					status |=
+						dot11f_unpack_ie_p2_p_assoc_req(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEP2PAssocReq *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEP2PAssocReq) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeP2PAssocRes:
+					status |=
+						dot11f_unpack_ie_p2_p_assoc_res(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEP2PAssocRes *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEP2PAssocRes) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeP2PBeacon:
+					status |=
+						dot11f_unpack_ie_p2_p_beacon(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEP2PBeacon *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEP2PBeacon) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeP2PBeaconProbeRes:
+					status |=
+						dot11f_unpack_ie_p2_p_beacon_probe_res(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEP2PBeaconProbeRes *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEP2PBeaconProbeRes) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeP2PDeAuth:
+					status |=
+						dot11f_unpack_ie_p2_p_de_auth(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEP2PDeAuth *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEP2PDeAuth) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeP2PDisAssoc:
+					status |=
+						dot11f_unpack_ie_p2_p_dis_assoc(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEP2PDisAssoc *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEP2PDisAssoc) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeP2PIEOpaque:
+					status |=
+						dot11f_unpack_ie_p2_pie_opaque(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEP2PIEOpaque *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEP2PIEOpaque) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeP2PProbeReq:
+					status |=
+						dot11f_unpack_ie_p2_p_probe_req(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEP2PProbeReq *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEP2PProbeReq) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeP2PProbeRes:
+					status |=
+						dot11f_unpack_ie_p2_p_probe_res(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEP2PProbeRes *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEP2PProbeRes) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIePTIControl:
+					status |=
+						dot11f_unpack_ie_pti_control(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEPTIControl *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEPTIControl) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIePUBufferStatus:
+					status |=
+						dot11f_unpack_ie_pu_buffer_status(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEPUBufferStatus *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEPUBufferStatus) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIePowerCaps:
+					status |=
+						dot11f_unpack_ie_power_caps(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEPowerCaps *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEPowerCaps) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIePowerConstraints:
+					status |=
+						dot11f_unpack_ie_power_constraints(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEPowerConstraints *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEPowerConstraints) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeQBSSLoad:
+					status |=
+						dot11f_unpack_ie_qbss_load(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEQBSSLoad *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEQBSSLoad) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeQCN_IE:
+					status |=
+						dot11f_unpack_ie_QCN_IE(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEQCN_IE *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEQCN_IE) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeQComVendorIE:
+					status |=
+						dot11f_unpack_ie_QComVendorIE(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEQComVendorIE *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEQComVendorIE) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeQOSCapsAp:
+					status |=
+						dot11f_unpack_ie_qos_caps_ap(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEQOSCapsAp *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEQOSCapsAp) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeQOSCapsStation:
+					status |=
+						dot11f_unpack_ie_qos_caps_station(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEQOSCapsStation *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEQOSCapsStation) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeQosMapSet:
+					status |=
+						dot11f_unpack_ie_qos_map_set(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEQosMapSet *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEQosMapSet) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeQuiet:
+					status |=
+						dot11f_unpack_ie_quiet(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEQuiet *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEQuiet) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeRCPIIE:
+					status |=
+						dot11f_unpack_ie_rcpiie(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIERCPIIE *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIERCPIIE) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeRICDataDesc:
+					/* reset the pointers back since this is a container IE and it doesn't have its own EID and Len. */
+					pBufRemaining -= 2;
+					nBufRemaining += 2;
+					if (pIe && pIe->noui) {
+						pBufRemaining -= pIe->noui;
+						nBufRemaining += pIe->noui;
+						len += pIe->noui;
+					}
+					status |= get_container_ies_len(pCtx, pBufRemaining, nBufRemaining, &len, IES_RICDataDesc);
+					if (status != DOT11F_PARSE_SUCCESS && status != DOT11F_UNKNOWN_IES)
+						 break;
+					status |=
+						dot11f_unpack_ie_ric_data_desc(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIERICDataDesc *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIERICDataDesc) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeRSN:
+					status |=
+						dot11f_unpack_ie_rsn(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIERSN *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIERSN) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeRSNIIE:
+					status |=
+						dot11f_unpack_ie_rsniie(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIERSNIIE *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIERSNIIE) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeRSNOpaque:
+					status |=
+						dot11f_unpack_ie_rsn_opaque(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIERSNOpaque *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIERSNOpaque) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeSuppChannels:
+					status |=
+						dot11f_unpack_ie_supp_channels(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIESuppChannels *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIESuppChannels) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeSuppOperatingClasses:
+					status |=
+						dot11f_unpack_ie_supp_operating_classes(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIESuppOperatingClasses *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIESuppOperatingClasses) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeSuppRates:
+					status |=
+						dot11f_unpack_ie_supp_rates(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIESuppRates *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIESuppRates) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeTIM:
+					status |=
+						dot11f_unpack_ie_tim(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIETIM *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIETIM) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeTPCReport:
+					status |=
+						dot11f_unpack_ie_tpc_report(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIETPCReport *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIETPCReport) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeTPCRequest:
+					status |=
+						dot11f_unpack_ie_tpc_request(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIETPCRequest *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIETPCRequest) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeTimeAdvertisement:
+					status |=
+						dot11f_unpack_ie_time_advertisement(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIETimeAdvertisement *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIETimeAdvertisement) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeTimeoutInterval:
+					status |=
+						dot11f_unpack_ie_timeout_interval(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIETimeoutInterval *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIETimeoutInterval) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeVHTExtBssLoad:
+					status |=
+						dot11f_unpack_ie_vht_ext_bss_load(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEVHTExtBssLoad *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEVHTExtBssLoad) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeVendor1IE:
+					status |=
+						dot11f_unpack_ie_vendor1_ie(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEVendor1IE *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEVendor1IE) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeVendor3IE:
+					status |=
+						dot11f_unpack_ie_vendor3_ie(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEVendor3IE *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEVendor3IE) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWAPI:
+					status |=
+						dot11f_unpack_ie_wapi(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWAPI *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWAPI) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWAPIOpaque:
+					status |=
+						dot11f_unpack_ie_wapi_opaque(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWAPIOpaque *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWAPIOpaque) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWFATPC:
+					status |=
+						dot11f_unpack_ie_wfatpc(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWFATPC *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWFATPC) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWFDIEOpaque:
+					status |=
+						dot11f_unpack_ie_wfdie_opaque(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWFDIEOpaque *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWFDIEOpaque) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWMMCaps:
+					status |=
+						dot11f_unpack_ie_wmm_caps(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWMMCaps *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWMMCaps) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWMMInfoAp:
+					status |=
+						dot11f_unpack_ie_wmm_info_ap(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWMMInfoAp *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWMMInfoAp) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWMMInfoStation:
+					status |=
+						dot11f_unpack_ie_wmm_info_station(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWMMInfoStation *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWMMInfoStation) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWMMParams:
+					status |=
+						dot11f_unpack_ie_wmm_params(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWMMParams *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWMMParams) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWPA:
+					status |=
+						dot11f_unpack_ie_wpa(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWPA *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWPA) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWPAOpaque:
+					status |=
+						dot11f_unpack_ie_wpa_opaque(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWPAOpaque *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWPAOpaque) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWSC:
+					status |=
+						dot11f_unpack_ie_wsc(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWSC *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWSC) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWscAssocReq:
+					status |=
+						dot11f_unpack_ie_wsc_assoc_req(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWscAssocReq *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWscAssocReq) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWscAssocRes:
+					status |=
+						dot11f_unpack_ie_wsc_assoc_res(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWscAssocRes *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWscAssocRes) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWscBeacon:
+					status |=
+						dot11f_unpack_ie_wsc_beacon(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWscBeacon *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWscBeacon) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWscBeaconProbeRes:
+					status |=
+						dot11f_unpack_ie_wsc_beacon_probe_res(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWscBeaconProbeRes *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWscBeaconProbeRes) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWscIEOpaque:
+					status |=
+						dot11f_unpack_ie_wsc_ie_opaque(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWscIEOpaque *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWscIEOpaque) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWscProbeReq:
+					status |=
+						dot11f_unpack_ie_wsc_probe_req(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWscProbeReq *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWscProbeReq) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWscProbeRes:
+					status |=
+						dot11f_unpack_ie_wsc_probe_res(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWscProbeRes *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWscProbeRes) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeWscReassocRes:
+					status |=
+						dot11f_unpack_ie_wsc_reassoc_res(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEWscReassocRes *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEWscReassocRes) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeaddba_extn_element:
+					status |=
+						dot11f_unpack_ie_addba_extn_element(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEaddba_extn_element *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEaddba_extn_element) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIebss_color_change:
+					status |=
+						dot11f_unpack_ie_bss_color_change(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEbss_color_change *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEbss_color_change) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIedh_parameter_element:
+					status |=
+						dot11f_unpack_ie_dh_parameter_element(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEdh_parameter_element *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEdh_parameter_element) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeesp_information:
+					status |=
+						dot11f_unpack_ie_esp_information(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEesp_information *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEesp_information) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeext_chan_switch_ann:
+					status |=
+						dot11f_unpack_ie_ext_chan_switch_ann(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEext_chan_switch_ann *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEext_chan_switch_ann) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIefils_assoc_delay_info:
+					status |=
+						dot11f_unpack_ie_fils_assoc_delay_info(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEfils_assoc_delay_info *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEfils_assoc_delay_info) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIefils_hlp_container:
+					status |=
+						dot11f_unpack_ie_fils_hlp_container(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEfils_hlp_container *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEfils_hlp_container) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIefils_indication:
+					status |=
+						dot11f_unpack_ie_fils_indication(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEfils_indication *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEfils_indication) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIefils_kde:
+					status |=
+						dot11f_unpack_ie_fils_kde(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEfils_kde *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEfils_kde) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIefils_key_confirmation:
+					status |=
+						dot11f_unpack_ie_fils_key_confirmation(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEfils_key_confirmation *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEfils_key_confirmation) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIefils_nonce:
+					status |=
+						dot11f_unpack_ie_fils_nonce(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEfils_nonce *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEfils_nonce) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIefils_public_key:
+					status |=
+						dot11f_unpack_ie_fils_public_key(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEfils_public_key *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEfils_public_key) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIefils_session:
+					status |=
+						dot11f_unpack_ie_fils_session(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEfils_session *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEfils_session) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIefils_wrapped_data:
+					status |=
+						dot11f_unpack_ie_fils_wrapped_data(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEfils_wrapped_data *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEfils_wrapped_data) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIefragment_ie:
+					status |=
+						dot11f_unpack_ie_fragment_ie(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEfragment_ie *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEfragment_ie) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIehe_cap:
+					status |=
+						dot11f_unpack_ie_he_cap(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEhe_cap *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEhe_cap) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIehe_op:
+					status |=
+						dot11f_unpack_ie_he_op(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEhe_op *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEhe_op) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIehs20vendor_ie:
+					status |=
+						dot11f_unpack_ie_hs20vendor_ie(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEhs20vendor_ie *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEhs20vendor_ie) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeht2040_bss_coexistence:
+					status |=
+						dot11f_unpack_ie_ht2040_bss_coexistence(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEht2040_bss_coexistence *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEht2040_bss_coexistence) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeht2040_bss_intolerant_report:
+					status |=
+						dot11f_unpack_ie_ht2040_bss_intolerant_report(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEht2040_bss_intolerant_report *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEht2040_bss_intolerant_report) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIemu_edca_param_set:
+					status |=
+						dot11f_unpack_ie_mu_edca_param_set(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEmu_edca_param_set *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEmu_edca_param_set) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIeosen_ie:
+					status |=
+						dot11f_unpack_ie_osen_ie(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEosen_ie *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEosen_ie) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIesec_chan_offset_ele:
+					status |=
+						dot11f_unpack_ie_sec_chan_offset_ele(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEsec_chan_offset_ele *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEsec_chan_offset_ele) *
+						    countOffset),
+						    append_ie);
+					break;
+				case SigIevendor_vht_ie:
+					status |=
+						dot11f_unpack_ie_vendor_vht_ie(
+						    pCtx, pBufRemaining, len,
+						    (tDot11fIEvendor_vht_ie *)
+						    (pFrm + pIe->offset +
+						    sizeof(tDot11fIEvendor_vht_ie) *
+						    countOffset),
+						    append_ie);
+					break;
+				default:
+					FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR"
+						     ": I don't know about the IE signature %d"
+						     "-- this is most likely a 'framesc' bug.\n"),
+						     pIe->sig);
+					FRAMES_DBG_BREAK();
+					return DOT11F_INTERNAL_ERROR;
+				}
+				if (pIe->arraybound)
+					(++(*(uint16_t *)(pFrm + pIe->countOffset)));
+			}
+		} else {
+			FRAMES_LOG3(pCtx, FRLOG3, FRFL("Skipping unknown IE %d extn ID %d"
+				     " (length %d)\n"), eid, extn_eid, len);
+			FRAMES_DUMP(pCtx, FRLOG3, pBufRemaining - 2, len);
+			status |= DOT11F_UNKNOWN_IES;
+		}
+
+skip_dup_ie:
+		pBufRemaining += len;
+
+		if (len > nBufRemaining) {
+			FRAMES_LOG0(pCtx, FRLOGW, FRFL("This IE extends past "
+				     "the buffer as it was defined to us.  This could"
+				     "mean a corrupt frame, or just an incorrect leng"
+				     "th parameter.\n"));
+			FRAMES_DBG_BREAK();
+			status |= DOT11F_LAST_IE_TOO_LONG;
+			goto MandatoryCheck;
+		}
+
+		nBufRemaining -= len;
+
+	}
+
+MandatoryCheck:
+	pIe = &IEs[0];
+	while (0xff != pIe->eid || pIe->extn_eid) {
+		if (pIe->fMandatory) {
+			pfFound = (tFRAMES_BOOL *)(pFrm + pIe->offset +
+						     pIe->presenceOffset);
+			if (!*pfFound) {
+				FRAMES_LOG1(pCtx, FRLOGW, FRFL("ERROR: The mandato"
+					     "ry IE %s wasn't seen.\n"),
+					     pIe->name);
+				FRAMES_DBG_BREAK();
+				status |= DOT11F_MANDATORY_IE_MISSING;
+			}
+		}
+		++pIe;
+	}
+
+	return status;
+} /* End unpack_core. */
+
+static uint32_t unpack_tlv_core(tpAniSirGlobal   pCtx,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  const tTLVDefn TLVs[],
+				  uint8_t *pFrm,
+				  size_t nFrm)
+{
+	const tTLVDefn *pTlv;
+	uint32_t      nBufRemaining, status, npec;
+	uint16_t      id, len;
+	uint8_t      *pBufRemaining, *pfFound;
+
+	(void)pCtx;                 /* Shutup the compiler */
+	(void)nFrm;
+	status = DOT11F_PARSE_SUCCESS;
+	pBufRemaining = pBuf;
+	nBufRemaining = nBuf;
+
+	/* While we have data... */
+	while (nBufRemaining) {
+		if (3 > nBufRemaining) {
+			FRAMES_LOG0(pCtx, FRLOGE, FRFL("This frame reports "
+				     "fewer three byte(s) remaining.\n"));
+			status |= DOT11F_INCOMPLETE_TLV;
+			FRAMES_DBG_BREAK();
+			goto MandatoryCheck;
+		}
+
+		npec = 0U;
+
+		/* Look for a matching TLV definition, */
+		pTlv = find_tlv_defn(pCtx, pBufRemaining, nBufRemaining, TLVs);
+		/* consume the type, */
+		if (pTlv) {
+			if (pTlv->sType == 2) {
+				framesntohs(pCtx, &id, pBufRemaining, pTlv->fMsb);
+				pBufRemaining += 2;
+				nBufRemaining -= 2;
+			} else {
+				id = *pBufRemaining;
+				pBufRemaining += 1;
+				nBufRemaining -= 1;
+			}
+			/* & length, */
+			if (pTlv->sLen == 2) {
+				framesntohs(pCtx, &len, pBufRemaining, pTlv->fMsb);
+				if (2 > nBufRemaining) {
+					FRAMES_LOG0(pCtx, FRLOGE, FRFL("This frame reports "
+							"fewer two byte(s) remaining.\n"));
+					status |= DOT11F_INCOMPLETE_TLV;
+					FRAMES_DBG_BREAK();
+					goto MandatoryCheck;
+			}
+			pBufRemaining += 2;
+			nBufRemaining -= 2;
+			} else {
+				len = *pBufRemaining;
+				pBufRemaining += 1;
+				nBufRemaining -= 1;
+			}
+		} else {
+			pBufRemaining += TLVs[0].sType;
+			nBufRemaining -= TLVs[0].sType;
+			framesntohs(pCtx, &len, pBufRemaining, (TLVs[0].sType == 2));
+			if (2 > nBufRemaining) {
+				FRAMES_LOG0(pCtx, FRLOGE, FRFL("This frame reports "
+					     "fewer two byte(s) remaining.\n"));
+				status |= DOT11F_INCOMPLETE_TLV;
+				FRAMES_DBG_BREAK();
+				goto MandatoryCheck;
+			}
+			pBufRemaining += 2;
+			nBufRemaining -= 2;
+		}
+
+		if (pTlv && pTlv->pec) {
+		npec = 3U;
+			if (3 > nBufRemaining) {
+				FRAMES_LOG2(pCtx, FRLOGW, FRFL("TLV %d reports length"
+				    "%d, but it has a Private Enterprise Code (3 byte"
+				    "s.\n"), id, len);
+				FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+				FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d bytes"
+				    "of this buffer, and show %d left.\n"),
+				pBufRemaining - pBuf, nBufRemaining);
+				status |= DOT11F_INCOMPLETE_TLV;
+				FRAMES_DBG_BREAK();
+				goto MandatoryCheck;
+			}
+		pBufRemaining += 3;
+		nBufRemaining -= 3;
+		len           -= 3;
+		}
+
+		/* Whether we found a hit or not, we can validate the reported */
+		/* length of this TLV: */
+		if (len > nBufRemaining) {
+			FRAMES_LOG3(pCtx, FRLOGW, FRFL("TLV %d reports length %"
+			    "d, but there are only %d bytes remaining in this f"
+			    "rame.\n"), id, len, nBufRemaining);
+			FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+			FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d bytes"
+			    " of this buffer, and show %d left.\n"),
+			    pBufRemaining - pBuf, nBufRemaining);
+			status |= DOT11F_INCOMPLETE_TLV;
+			FRAMES_DBG_BREAK();
+			goto MandatoryCheck;
+		}
+
+		/* Now, *if* we found a hit... */
+		if (pTlv) {
+			if (len + (pTlv->sType + pTlv->sLen) < pTlv->minSize - npec) {
+				FRAMES_LOG3(pCtx, FRLOGW, FRFL("The IE %s must be "
+				    "at least %d bytes in size, but the size is only "
+				    "%d bytes.\n"),
+				     pTlv->name, pTlv->minSize, len);
+				FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+				status |= DOT11F_INCOMPLETE_TLV;
+				FRAMES_DBG_BREAK();
+				goto MandatoryCheck;
+			}
+			if (nBufRemaining < pTlv->minSize - npec - (pTlv->sType + pTlv->sLen)) {
+				FRAMES_LOG3(pCtx, FRLOGW, FRFL("The IE %s must be "
+				    "at least %d bytes in size, but there are only "
+				    "%d bytes remaining in this frame.\n"),
+				     pTlv->name, pTlv->minSize, nBufRemaining);
+				FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+				status |= DOT11F_INCOMPLETE_TLV;
+				FRAMES_DBG_BREAK();
+				goto MandatoryCheck;
+			} else if (len > pTlv->maxSize - npec - (pTlv->sType + pTlv->sLen)) {
+				FRAMES_LOG1(pCtx, FRLOGW, FRFL("The TLV %s reports "
+				    "an illegally large size; this TLV is presumably"
+				    "corrupt or otherwise invalid & will be skipped "
+				    "ipped.\n"), pTlv->name);
+				FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+				FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d by"
+				    "tes of this buffer, and show %d left.\n"),
+				    pBufRemaining - pBuf, nBufRemaining);
+				FRAMES_DBG_BREAK();
+				status |= DOT11F_SKIPPED_BAD_TLV;
+			} else {
+				switch (pTlv->sig) {
+				case SigTlvAuthorizedMACs:
+					status |=
+						dot11f_unpack_tlv_authorized_ma_cs(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVAuthorizedMACs *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvRequestToEnroll:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVRequestToEnroll *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVRequestToEnroll *)
+						  (pFrm + pTlv->offset))->req));
+					break;
+				case SigTlvVersion2:
+					status |=
+						dot11f_unpack_tlv_version2(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVVersion2 *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvAPSetupLocked:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVAPSetupLocked *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVAPSetupLocked *)
+						  (pFrm + pTlv->offset))->fLocked));
+					break;
+				case SigTlvAssociationState:
+					status |=
+						dot11f_unpack_tlv_common_func2(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVAssociationState *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint16_t *)&(((tDot11fTLVAssociationState *)
+						  (pFrm + pTlv->offset))->state));
+					break;
+				case SigTlvConfigMethods:
+					status |=
+						dot11f_unpack_tlv_common_func2(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVConfigMethods *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint16_t *)&(((tDot11fTLVConfigMethods *)
+						  (pFrm + pTlv->offset))->methods));
+					break;
+				case SigTlvConfigurationError:
+					status |=
+						dot11f_unpack_tlv_common_func2(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVConfigurationError *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint16_t *)&(((tDot11fTLVConfigurationError *)
+						  (pFrm + pTlv->offset))->error));
+					break;
+				case SigTlvDeviceName:
+					status |=
+						dot11f_unpack_tlv_device_name(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVDeviceName *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvDevicePasswordID:
+					status |=
+						dot11f_unpack_tlv_common_func2(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVDevicePasswordID *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint16_t *)&(((tDot11fTLVDevicePasswordID *)
+						  (pFrm + pTlv->offset))->id));
+					break;
+				case SigTlvExtendedListenTiming:
+					status |=
+						dot11f_unpack_tlv_extended_listen_timing(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVExtendedListenTiming *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvListenChannel:
+					status |=
+						dot11f_unpack_tlv_listen_channel(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVListenChannel *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvManufacturer:
+					status |=
+						dot11f_unpack_tlv_manufacturer(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVManufacturer *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvMinorReasonCode:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVMinorReasonCode *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVMinorReasonCode *)
+						  (pFrm + pTlv->offset))->minorReasonCode));
+					break;
+				case SigTlvModelName:
+					status |=
+						dot11f_unpack_tlv_model_name(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVModelName *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvModelNumber:
+					status |=
+						dot11f_unpack_tlv_model_number(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVModelNumber *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvNoticeOfAbsence:
+					status |=
+						dot11f_unpack_tlv_notice_of_absence(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVNoticeOfAbsence *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvOperatingChannel:
+					status |=
+						dot11f_unpack_tlv_operating_channel(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVOperatingChannel *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvP2PCapability:
+					status |=
+						dot11f_unpack_tlv_p2_p_capability(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVP2PCapability *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvP2PDeviceId:
+					status |=
+						dot11f_unpack_tlv_p2_p_device_id(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVP2PDeviceId *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvP2PDeviceInfo:
+					status |=
+						dot11f_unpack_tlv_p2_p_device_info(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVP2PDeviceInfo *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvP2PGroupInfo:
+					status |=
+						dot11f_unpack_tlv_p2_p_group_info(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVP2PGroupInfo *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvP2PStatus:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVP2PStatus *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVP2PStatus *)
+						  (pFrm + pTlv->offset))->status));
+					break;
+				case SigTlvPrimaryDeviceType:
+					status |=
+						dot11f_unpack_tlv_primary_device_type(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVPrimaryDeviceType *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvRFBands:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVRFBands *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVRFBands *)
+						  (pFrm + pTlv->offset))->bands));
+					break;
+				case SigTlvRequestDeviceType:
+					status |=
+						dot11f_unpack_tlv_request_device_type(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVRequestDeviceType *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvRequestType:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVRequestType *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVRequestType *)
+						  (pFrm + pTlv->offset))->reqType));
+					break;
+				case SigTlvResponseType:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVResponseType *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVResponseType *)
+						  (pFrm + pTlv->offset))->resType));
+					break;
+				case SigTlvSelectedRegistrar:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVSelectedRegistrar *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVSelectedRegistrar *)
+						  (pFrm + pTlv->offset))->selected));
+					break;
+				case SigTlvSelectedRegistrarConfigMethods:
+					status |=
+						dot11f_unpack_tlv_common_func2(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVSelectedRegistrarConfigMethods *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint16_t *)&(((tDot11fTLVSelectedRegistrarConfigMethods *)
+						  (pFrm + pTlv->offset))->methods));
+					break;
+				case SigTlvSerialNumber:
+					status |=
+						dot11f_unpack_tlv_serial_number(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVSerialNumber *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvUUID_E:
+					status |=
+						dot11f_unpack_tlv_uuid_e(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVUUID_E *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvUUID_R:
+					status |=
+						dot11f_unpack_tlv_uuid_r(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVUUID_R *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvVendorExtension:
+					status |=
+						dot11f_unpack_tlv_vendor_extension(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVVendorExtension *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvVersion:
+					status |=
+						dot11f_unpack_tlv_version(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVVersion *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvWPSState:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVWPSState *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVWPSState *)
+						  (pFrm + pTlv->offset))->state));
+					break;
+				case SigTlvassoc_disallowed:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVassoc_disallowed *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVassoc_disallowed *)
+						  (pFrm + pTlv->offset))->reason_code));
+					break;
+				case SigTlvassoc_retry_delay:
+					status |=
+						dot11f_unpack_tlv_common_func2(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVassoc_retry_delay *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint16_t *)&(((tDot11fTLVassoc_retry_delay *)
+						  (pFrm + pTlv->offset))->delay));
+					break;
+				case SigTlvcellular_data_cap:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVcellular_data_cap *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVcellular_data_cap *)
+						  (pFrm + pTlv->offset))->cellular_connectivity));
+					break;
+				case SigTlvcellular_data_con_pref:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVcellular_data_con_pref *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVcellular_data_con_pref *)
+						  (pFrm + pTlv->offset))->cellular_preference));
+					break;
+				case SigTlvmbo_ap_cap:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVmbo_ap_cap *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVmbo_ap_cap *)
+						  (pFrm + pTlv->offset))->mbo_cap_ind));
+					break;
+				case SigTlvnon_prefferd_chan_rep:
+					status |=
+						dot11f_unpack_tlv_non_prefferd_chan_rep(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVnon_prefferd_chan_rep *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvoce_cap:
+					status |=
+						dot11f_unpack_tlv_oce_cap(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVoce_cap *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvreduced_wan_metrics:
+					status |=
+						dot11f_unpack_tlv_reduced_wan_metrics(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVreduced_wan_metrics *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvrssi_assoc_rej:
+					status |=
+						dot11f_unpack_tlv_rssi_assoc_rej(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVrssi_assoc_rej *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvtransition_reason:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVtransition_reason *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVtransition_reason *)
+						  (pFrm + pTlv->offset))->transition_reason_code));
+					break;
+				case SigTlvtransition_reject_reason:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVtransition_reject_reason *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVtransition_reject_reason *)
+						  (pFrm + pTlv->offset))->transition_reject_code));
+					break;
+				case SigTlvP2PInterface:
+					status |=
+						dot11f_unpack_tlv_p2_p_interface(pCtx,
+						  pBufRemaining, len,
+						  (tDot11fTLVP2PInterface *)
+						  (pFrm + pTlv->offset));
+					break;
+				case SigTlvP2PManageability:
+					status |=
+						dot11f_unpack_tlv_common_func(pCtx,
+						  pBufRemaining, len,
+						  (uint8_t *)&(((tDot11fTLVP2PManageability *)
+						  (pFrm + pTlv->offset))->present),
+						  (uint8_t *)&(((tDot11fTLVP2PManageability *)
+						  (pFrm + pTlv->offset))->manageability));
+					break;
+				default:
+					FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR: I"
+					    " don't know about the TLV signature %d-- thi"
+					    "s is most likely a 'framesc' bug.\n"),
+					    pTlv->sig);
+					FRAMES_DBG_BREAK();
+					return DOT11F_INTERNAL_ERROR;
+				} /* End switch on sig. */
+			} /* End if on length check. */
+
+		} else {
+			FRAMES_LOG2(pCtx, FRLOG3, FRFL("Skipping unknown TLV %d ("
+			    "length %d)\n"), id, len);
+			FRAMES_DUMP(pCtx, FRLOG3, pBufRemaining - (pTlv->sType + pTlv->sLen), len);
+			status |= DOT11F_UNKNOWN_TLVS;
+		}
+
+		/* Advance to the next TLV */
+		pBufRemaining += len;
+
+		if (len > nBufRemaining) {
+			FRAMES_LOG0(pCtx, FRLOGW, FRFL("This TLV extends past th"
+			    "e buffer as it was defined to us.  This could mean "
+			    "a corrupt frame, or just an incorrect length parame"
+			    "ter.\n"));
+			FRAMES_DBG_BREAK();
+			status |= DOT11F_LAST_TLV_TOO_LONG;
+			goto MandatoryCheck;
+		}
+
+		nBufRemaining -= len;
+
+	} /* End iteration over TLVs.*/
+
+MandatoryCheck:
+	pTlv = &TLVs[0];
+	while (0xffff != pTlv->id) {
+		if (pTlv->fMandatory) {
+			pfFound = (uint8_t *)(pFrm + pTlv->offset +
+					     pTlv->presenceOffset);
+			if (!*pfFound) {
+				FRAMES_LOG1(pCtx, FRLOGW, FRFL("ERROR: The mandatory "
+				    "TLV %s wasn't seen.\n"),
+				    pTlv->name);
+				FRAMES_DBG_BREAK();
+				status |= DOT11F_MANDATORY_TLV_MISSING;
+			}
+
+		}
+		++pTlv;
+	}
+
+	return status;
+} /* End UnpacTlvkCore. */
+uint32_t dot11f_get_packed_ietclas(tpAniSirGlobal pCtx,
+	tDot11fIETCLAS *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		switch (pIe->classifier_type) {
+		case 0:
+			*pnNeeded += 6;
+			*pnNeeded += 6;
+			*pnNeeded += 2;
+			break;
+		case 1:
+			*pnNeeded += 1;
+			switch (pIe->info.IpParams.version) {
+			case 4:
+				*pnNeeded += 4;
+				*pnNeeded += 4;
+				*pnNeeded += 2;
+				*pnNeeded += 2;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				break;
+			case 6:
+				*pnNeeded += 16;
+				*pnNeeded += 16;
+				*pnNeeded += 2;
+				*pnNeeded += 2;
+				*pnNeeded += 3;
+				break;
+			}
+			break;
+		case 2:
+			*pnNeeded += 2;
+			break;
+		}
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ietclas. */
+
+uint32_t dot11f_get_packed_iewmmtclas(tpAniSirGlobal pCtx,
+	tDot11fIEWMMTCLAS *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		switch (pIe->classifier_type) {
+		case 0:
+			*pnNeeded += 6;
+			*pnNeeded += 6;
+			*pnNeeded += 2;
+			break;
+		case 1:
+			*pnNeeded += 1;
+			switch (pIe->info.IpParams.version) {
+			case 4:
+				*pnNeeded += 4;
+				*pnNeeded += 4;
+				*pnNeeded += 2;
+				*pnNeeded += 2;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				break;
+			case 6:
+				*pnNeeded += 16;
+				*pnNeeded += 16;
+				*pnNeeded += 2;
+				*pnNeeded += 2;
+				*pnNeeded += 3;
+				break;
+			}
+			break;
+		case 2:
+			*pnNeeded += 2;
+			break;
+		}
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iewmmtclas. */
+
+uint32_t dot11f_get_packed_ie_neighbor_rpt(tpAniSirGlobal pCtx,
+	tDot11fIEneighbor_rpt *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 6;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		*pnNeeded += 2;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				IES_neighbor_rpt);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_neighbor_rpt. */
+
+uint32_t dot11f_get_packed_ie_channel_switch_wrapper(tpAniSirGlobal pCtx,
+	tDot11fIEChannelSwitchWrapper *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				IES_ChannelSwitchWrapper);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_channel_switch_wrapper. */
+
+uint32_t dot11f_get_packed_ie_country(tpAniSirGlobal pCtx,
+	tDot11fIECountry *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 3;
+		if (pIe->num_triplets) {
+			*pnNeeded += (pIe->num_triplets * 3);
+		} else {
+			break;
+		}
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_country. */
+
+uint32_t dot11f_get_packed_ieft_info(tpAniSirGlobal pCtx,
+	tDot11fIEFTInfo *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 2;
+		*pnNeeded += 16;
+		*pnNeeded += 32;
+		*pnNeeded += 32;
+		status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				IES_FTInfo);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ieft_info. */
+
+uint32_t dot11f_get_packed_ie_MBO_IE(tpAniSirGlobal pCtx,
+	tDot11fIEMBO_IE *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_MBO_IE);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_MBO_IE. */
+
+uint32_t dot11f_get_packed_ie_measurement_report(tpAniSirGlobal pCtx,
+	tDot11fIEMeasurementReport *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		if (pIe->type) {
+			switch (pIe->type) {
+			case 0:
+				*pnNeeded += 1;
+				*pnNeeded += 8;
+				*pnNeeded += 2;
+				*pnNeeded += 1;
+				break;
+			case 1:
+				*pnNeeded += 1;
+				*pnNeeded += 8;
+				*pnNeeded += 2;
+				*pnNeeded += 1;
+				break;
+			case 2:
+				*pnNeeded += 1;
+				*pnNeeded += 8;
+				*pnNeeded += 2;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				break;
+			case 5:
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 8;
+				*pnNeeded += 2;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 6;
+				*pnNeeded += 1;
+				*pnNeeded += 4;
+				status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded, IES_reportBeacon);
+				break;
+			}
+		} else {
+			break;
+		}
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_measurement_report. */
+
+uint32_t dot11f_get_packed_ie_measurement_request(tpAniSirGlobal pCtx,
+	tDot11fIEMeasurementRequest *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		switch (pIe->measurement_type) {
+		case 0:
+			*pnNeeded += 1;
+			*pnNeeded += 8;
+			*pnNeeded += 2;
+			break;
+		case 1:
+			*pnNeeded += 1;
+			*pnNeeded += 8;
+			*pnNeeded += 2;
+			break;
+		case 2:
+			*pnNeeded += 1;
+			*pnNeeded += 8;
+			*pnNeeded += 2;
+			break;
+		case 5:
+			*pnNeeded += 1;
+			*pnNeeded += 1;
+			*pnNeeded += 2;
+			*pnNeeded += 2;
+			*pnNeeded += 1;
+			*pnNeeded += 6;
+			status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded, IES_measurement_requestBeacon);
+			break;
+		case 8:
+			*pnNeeded += 1;
+			status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded, IES_measurement_requestlci);
+			break;
+		case 16:
+			*pnNeeded += 2;
+			*pnNeeded += 1;
+			status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded, IES_measurement_requestftmrr);
+			break;
+		}
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_measurement_request. */
+
+uint32_t dot11f_get_packed_ie_neighbor_report(tpAniSirGlobal pCtx,
+	tDot11fIENeighborReport *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 6;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		*pnNeeded += 2;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				IES_NeighborReport);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_neighbor_report. */
+
+uint32_t dot11f_get_packed_iep2_p_assoc_req(tpAniSirGlobal pCtx,
+	tDot11fIEP2PAssocReq *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_P2PAssocReq);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iep2_p_assoc_req. */
+
+uint32_t dot11f_get_packed_iep2_p_assoc_res(tpAniSirGlobal pCtx,
+	tDot11fIEP2PAssocRes *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_P2PAssocRes);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iep2_p_assoc_res. */
+
+uint32_t dot11f_get_packed_iep2_p_beacon(tpAniSirGlobal pCtx,
+	tDot11fIEP2PBeacon *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_P2PBeacon);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iep2_p_beacon. */
+
+uint32_t dot11f_get_packed_iep2_p_beacon_probe_res(tpAniSirGlobal pCtx,
+	tDot11fIEP2PBeaconProbeRes *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_P2PBeaconProbeRes);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iep2_p_beacon_probe_res. */
+
+uint32_t dot11f_get_packed_iep2_p_de_auth(tpAniSirGlobal pCtx,
+	tDot11fIEP2PDeAuth *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_P2PDeAuth);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iep2_p_de_auth. */
+
+uint32_t dot11f_get_packed_iep2_p_dis_assoc(tpAniSirGlobal pCtx,
+	tDot11fIEP2PDisAssoc *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_P2PDisAssoc);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iep2_p_dis_assoc. */
+
+uint32_t dot11f_get_packed_iep2_p_probe_req(tpAniSirGlobal pCtx,
+	tDot11fIEP2PProbeReq *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_P2PProbeReq);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iep2_p_probe_req. */
+
+uint32_t dot11f_get_packed_iep2_p_probe_res(tpAniSirGlobal pCtx,
+	tDot11fIEP2PProbeRes *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_P2PProbeRes);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iep2_p_probe_res. */
+
+uint32_t dot11f_get_packed_ieric_data_desc(tpAniSirGlobal pCtx,
+	tDot11fIERICDataDesc *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				IES_RICDataDesc);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ieric_data_desc. */
+
+uint32_t dot11f_get_packed_iersn(tpAniSirGlobal pCtx,
+	tDot11fIERSN *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 2;
+		if (pIe->gp_cipher_suite_present) {
+
+			*pnNeeded += 4;
+		} else {
+			break;
+		}
+		if (pIe->pwise_cipher_suite_count) {
+			*pnNeeded += 2;
+		} else {
+			break;
+		}
+		*pnNeeded += (pIe->pwise_cipher_suite_count * 4);
+		if (pIe->akm_suite_cnt) {
+			*pnNeeded += 2;
+		} else {
+			break;
+		}
+		*pnNeeded += (pIe->akm_suite_cnt * 4);
+		if (pIe->RSN_Cap_present) {
+
+			*pnNeeded += 2;
+		} else {
+			break;
+		}
+		if (pIe->pmkid_count) {
+			*pnNeeded += 2;
+		} else {
+			break;
+		}
+		*pnNeeded += (pIe->pmkid_count * 16);
+		if (pIe->gp_mgmt_cipher_suite_present) {
+
+			*pnNeeded += 4;
+		} else {
+			break;
+		}
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iersn. */
+
+uint32_t dot11f_get_packed_iewapi(tpAniSirGlobal pCtx,
+	tDot11fIEWAPI *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 2;
+		*pnNeeded += 2;
+		*pnNeeded += (pIe->akm_suite_count * 4);
+		*pnNeeded += 2;
+		*pnNeeded += (pIe->unicast_cipher_suite_count * 4);
+		*pnNeeded += 4;
+		*pnNeeded += 2;
+		if (pIe->bkid_count) {
+			*pnNeeded += 2;
+		} else {
+			break;
+		}
+		*pnNeeded += (pIe->bkid_count * 16);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iewapi. */
+
+uint32_t dot11f_get_packed_iewpa(tpAniSirGlobal pCtx,
+	tDot11fIEWPA *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 2;
+		if (pIe->multicast_cipher_present) {
+
+			*pnNeeded += 4;
+		} else {
+			break;
+		}
+		if (pIe->unicast_cipher_count) {
+			*pnNeeded += 2;
+		} else {
+			break;
+		}
+		*pnNeeded += (pIe->unicast_cipher_count * 4);
+		if (pIe->auth_suite_count) {
+			*pnNeeded += 2;
+		} else {
+			break;
+		}
+		*pnNeeded += (pIe->auth_suite_count * 4);
+		if (pIe->caps) {
+			*pnNeeded += 2;
+		} else {
+			break;
+		}
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iewpa. */
+
+uint32_t dot11f_get_packed_iewsc(tpAniSirGlobal pCtx,
+	tDot11fIEWSC *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_WSC);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_iewsc. */
+
+uint32_t dot11f_get_packed_ie_wsc_assoc_req(tpAniSirGlobal pCtx,
+	tDot11fIEWscAssocReq *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_WscAssocReq);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_wsc_assoc_req. */
+
+uint32_t dot11f_get_packed_ie_wsc_assoc_res(tpAniSirGlobal pCtx,
+	tDot11fIEWscAssocRes *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_WscAssocRes);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_wsc_assoc_res. */
+
+uint32_t dot11f_get_packed_ie_wsc_beacon(tpAniSirGlobal pCtx,
+	tDot11fIEWscBeacon *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_WscBeacon);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_wsc_beacon. */
+
+uint32_t dot11f_get_packed_ie_wsc_beacon_probe_res(tpAniSirGlobal pCtx,
+	tDot11fIEWscBeaconProbeRes *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_WscBeaconProbeRes);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_wsc_beacon_probe_res. */
+
+uint32_t dot11f_get_packed_ie_wsc_probe_req(tpAniSirGlobal pCtx,
+	tDot11fIEWscProbeReq *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_WscProbeReq);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_wsc_probe_req. */
+
+uint32_t dot11f_get_packed_ie_wsc_probe_res(tpAniSirGlobal pCtx,
+	tDot11fIEWscProbeRes *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_WscProbeRes);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_wsc_probe_res. */
+
+uint32_t dot11f_get_packed_ie_wsc_reassoc_res(tpAniSirGlobal pCtx,
+	tDot11fIEWscReassocRes *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				TLVS_WscReassocRes);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_wsc_reassoc_res. */
+
+uint32_t dot11f_get_packed_ie_he_cap(tpAniSirGlobal pCtx,
+	tDot11fIEhe_cap *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 4;
+		*pnNeeded += 2;
+		*pnNeeded += 4;
+		*pnNeeded += 4;
+		*pnNeeded += 2;
+		*pnNeeded += 1;
+		*pnNeeded += 2;
+		*pnNeeded += 2;
+		*pnNeeded += (pIe->chan_width_2 * 2);
+		*pnNeeded += (pIe->chan_width_2 * 2);
+		*pnNeeded += (pIe->chan_width_3 * 2);
+		*pnNeeded += (pIe->chan_width_3 * 2);
+		if (pIe->ppet_present) {
+			switch (pIe->ppet_present) {
+			case 1:
+				*pnNeeded += pIe->ppet.ppe_threshold.num_ppe_th;
+				break;
+			}
+		} else {
+			break;
+		}
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_he_cap. */
+
+uint32_t dot11f_get_packed_ie_he_op(tpAniSirGlobal pCtx,
+	tDot11fIEhe_op *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 2;
+		*pnNeeded += 1;
+		*pnNeeded += 1;
+		*pnNeeded += 2;
+		if (pIe->vht_oper_present) {
+			switch (pIe->vht_oper_present) {
+			case 1:
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				*pnNeeded += 1;
+				break;
+			}
+		} else {
+			break;
+		}
+		if (pIe->co_located_bss) {
+			switch (pIe->co_located_bss) {
+			case 1:
+				*pnNeeded += 1;
+				break;
+			}
+		} else {
+			break;
+		}
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_he_op. */
+
+uint32_t dot11f_get_packed_ie_hs20vendor_ie(tpAniSirGlobal pCtx,
+	tDot11fIEhs20vendor_ie *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 1;
+		if (pIe->hs_id_present) {
+			switch (pIe->hs_id_present) {
+			case 1:
+				*pnNeeded += 2;
+				break;
+			case 2:
+				*pnNeeded += 2;
+				break;
+			}
+		} else {
+			break;
+		}
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_hs20vendor_ie. */
+
+uint32_t dot11f_get_packed_ie_vendor_vht_ie(tpAniSirGlobal pCtx,
+	tDot11fIEvendor_vht_ie *pIe, uint32_t *pnNeeded)
+{
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	(void)pCtx;
+	while (pIe->present) {
+		*pnNeeded += 1;
+		status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded,
+				IES_vendor_vht_ie);
+		break;
+	}
+	return status;
+} /* End dot11f_get_packed_ie_vendor_vht_ie. */
+
+uint32_t dot11f_get_packed_add_ts_request_size(tpAniSirGlobal pCtx,
+	tDot11fAddTSRequest *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_AddTSRequest);
+	return status;
+} /* End dot11f_get_packed_add_ts_request_size. */
+
+uint32_t dot11f_get_packed_add_ts_response_size(tpAniSirGlobal pCtx,
+	tDot11fAddTSResponse *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 5;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_AddTSResponse);
+	return status;
+} /* End dot11f_get_packed_add_ts_response_size. */
+
+uint32_t dot11f_get_packed_assoc_request_size(tpAniSirGlobal pCtx,
+	tDot11fAssocRequest *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 4;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_AssocRequest);
+	return status;
+} /* End dot11f_get_packed_assoc_request_size. */
+
+uint32_t dot11f_get_packed_assoc_response_size(tpAniSirGlobal pCtx,
+	tDot11fAssocResponse *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 6;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_AssocResponse);
+	return status;
+} /* End dot11f_get_packed_assoc_response_size. */
+
+uint32_t dot11f_get_packed_authentication_size(tpAniSirGlobal pCtx,
+	tDot11fAuthentication *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 6;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_Authentication);
+	return status;
+} /* End dot11f_get_packed_authentication_size. */
+
+uint32_t dot11f_get_packed_beacon_size(tpAniSirGlobal pCtx,
+	tDot11fBeacon *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 12;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_Beacon);
+	return status;
+} /* End dot11f_get_packed_beacon_size. */
+
+uint32_t dot11f_get_packed_beacon1_size(tpAniSirGlobal pCtx,
+	tDot11fBeacon1 *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 12;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_Beacon1);
+	return status;
+} /* End dot11f_get_packed_beacon1_size. */
+
+uint32_t dot11f_get_packed_beacon2_size(tpAniSirGlobal pCtx,
+	tDot11fBeacon2 *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 0;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_Beacon2);
+	return status;
+} /* End dot11f_get_packed_beacon2_size. */
+
+uint32_t dot11f_get_packed_beacon_i_es_size(tpAniSirGlobal pCtx,
+	tDot11fBeaconIEs *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 0;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_BeaconIEs);
+	return status;
+} /* End dot11f_get_packed_beacon_i_es_size. */
+
+uint32_t dot11f_get_packed_channel_switch_size(tpAniSirGlobal pCtx,
+	tDot11fChannelSwitch *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 2;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_ChannelSwitch);
+	return status;
+} /* End dot11f_get_packed_channel_switch_size. */
+
+uint32_t dot11f_get_packed_de_auth_size(tpAniSirGlobal pCtx,
+	tDot11fDeAuth *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 2;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_DeAuth);
+	return status;
+} /* End dot11f_get_packed_de_auth_size. */
+
+uint32_t dot11f_get_packed_del_ts_size(tpAniSirGlobal pCtx,
+	tDot11fDelTS *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 7;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_DelTS);
+	return status;
+} /* End dot11f_get_packed_del_ts_size. */
+
+uint32_t dot11f_get_packed_disassociation_size(tpAniSirGlobal pCtx,
+	tDot11fDisassociation *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 2;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_Disassociation);
+	return status;
+} /* End dot11f_get_packed_disassociation_size. */
+
+uint32_t dot11f_get_packed_link_measurement_report_size(tpAniSirGlobal pCtx,
+	tDot11fLinkMeasurementReport *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 11;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_LinkMeasurementReport);
+	return status;
+} /* End dot11f_get_packed_link_measurement_report_size. */
+
+uint32_t dot11f_get_packed_link_measurement_request_size(tpAniSirGlobal pCtx,
+	tDot11fLinkMeasurementRequest *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 5;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_LinkMeasurementRequest);
+	return status;
+} /* End dot11f_get_packed_link_measurement_request_size. */
+
+uint32_t dot11f_get_packed_measurement_report_size(tpAniSirGlobal pCtx,
+	tDot11fMeasurementReport *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_MeasurementReport);
+	return status;
+} /* End dot11f_get_packed_measurement_report_size. */
+
+uint32_t dot11f_get_packed_measurement_request_size(tpAniSirGlobal pCtx,
+	tDot11fMeasurementRequest *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_MeasurementRequest);
+	return status;
+} /* End dot11f_get_packed_measurement_request_size. */
+
+uint32_t dot11f_get_packed_neighbor_report_request_size(tpAniSirGlobal pCtx,
+	tDot11fNeighborReportRequest *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_NeighborReportRequest);
+	return status;
+} /* End dot11f_get_packed_neighbor_report_request_size. */
+
+uint32_t dot11f_get_packed_neighbor_report_response_size(tpAniSirGlobal pCtx,
+	tDot11fNeighborReportResponse *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_NeighborReportResponse);
+	return status;
+} /* End dot11f_get_packed_neighbor_report_response_size. */
+
+uint32_t dot11f_get_packed_operating_mode_size(tpAniSirGlobal pCtx,
+	tDot11fOperatingMode *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_OperatingMode);
+	return status;
+} /* End dot11f_get_packed_operating_mode_size. */
+
+uint32_t dot11f_get_packed_probe_request_size(tpAniSirGlobal pCtx,
+	tDot11fProbeRequest *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 0;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_ProbeRequest);
+	return status;
+} /* End dot11f_get_packed_probe_request_size. */
+
+uint32_t dot11f_get_packed_probe_response_size(tpAniSirGlobal pCtx,
+	tDot11fProbeResponse *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 12;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_ProbeResponse);
+	return status;
+} /* End dot11f_get_packed_probe_response_size. */
+
+uint32_t dot11f_get_packed_qos_map_configure_size(tpAniSirGlobal pCtx,
+	tDot11fQosMapConfigure *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 2;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_QosMapConfigure);
+	return status;
+} /* End dot11f_get_packed_qos_map_configure_size. */
+
+uint32_t dot11f_get_packed_radio_measurement_report_size(tpAniSirGlobal pCtx,
+	tDot11fRadioMeasurementReport *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_RadioMeasurementReport);
+	return status;
+} /* End dot11f_get_packed_radio_measurement_report_size. */
+
+uint32_t dot11f_get_packed_radio_measurement_request_size(tpAniSirGlobal pCtx,
+	tDot11fRadioMeasurementRequest *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 5;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_RadioMeasurementRequest);
+	return status;
+} /* End dot11f_get_packed_radio_measurement_request_size. */
+
+uint32_t dot11f_get_packed_re_assoc_request_size(tpAniSirGlobal pCtx,
+	tDot11fReAssocRequest *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 10;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_ReAssocRequest);
+	return status;
+} /* End dot11f_get_packed_re_assoc_request_size. */
+
+uint32_t dot11f_get_packed_re_assoc_response_size(tpAniSirGlobal pCtx,
+	tDot11fReAssocResponse *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 6;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_ReAssocResponse);
+	return status;
+} /* End dot11f_get_packed_re_assoc_response_size. */
+
+uint32_t dot11f_get_packed_sm_power_save_size(tpAniSirGlobal pCtx,
+	tDot11fSMPowerSave *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_SMPowerSave);
+	return status;
+} /* End dot11f_get_packed_sm_power_save_size. */
+
+uint32_t dot11f_get_packed_sa_query_req_size(tpAniSirGlobal pCtx,
+	tDot11fSaQueryReq *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 4;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_SaQueryReq);
+	return status;
+} /* End dot11f_get_packed_sa_query_req_size. */
+
+uint32_t dot11f_get_packed_sa_query_rsp_size(tpAniSirGlobal pCtx,
+	tDot11fSaQueryRsp *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 4;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_SaQueryRsp);
+	return status;
+} /* End dot11f_get_packed_sa_query_rsp_size. */
+
+uint32_t dot11f_get_packed_tdls_dis_req_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSDisReq *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_TDLSDisReq);
+	return status;
+} /* End dot11f_get_packed_tdls_dis_req_size. */
+
+uint32_t dot11f_get_packed_tdls_dis_rsp_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSDisRsp *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 5;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_TDLSDisRsp);
+	return status;
+} /* End dot11f_get_packed_tdls_dis_rsp_size. */
+
+uint32_t dot11f_get_packed_tdls_peer_traffic_ind_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSPeerTrafficInd *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_TDLSPeerTrafficInd);
+	return status;
+} /* End dot11f_get_packed_tdls_peer_traffic_ind_size. */
+
+uint32_t dot11f_get_packed_tdls_peer_traffic_rsp_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSPeerTrafficRsp *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_TDLSPeerTrafficRsp);
+	return status;
+} /* End dot11f_get_packed_tdls_peer_traffic_rsp_size. */
+
+uint32_t dot11f_get_packed_tdls_setup_cnf_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupCnf *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 5;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_TDLSSetupCnf);
+	return status;
+} /* End dot11f_get_packed_tdls_setup_cnf_size. */
+
+uint32_t dot11f_get_packed_tdls_setup_req_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupReq *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 5;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_TDLSSetupReq);
+	return status;
+} /* End dot11f_get_packed_tdls_setup_req_size. */
+
+uint32_t dot11f_get_packed_tdls_setup_rsp_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupRsp *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 7;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_TDLSSetupRsp);
+	return status;
+} /* End dot11f_get_packed_tdls_setup_rsp_size. */
+
+uint32_t dot11f_get_packed_tdls_teardown_size(tpAniSirGlobal pCtx,
+	tDot11fTDLSTeardown *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 4;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_TDLSTeardown);
+	return status;
+} /* End dot11f_get_packed_tdls_teardown_size. */
+
+uint32_t dot11f_get_packed_tpc_report_size(tpAniSirGlobal pCtx,
+	tDot11fTPCReport *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_TPCReport);
+	return status;
+} /* End dot11f_get_packed_tpc_report_size. */
+
+uint32_t dot11f_get_packed_tpc_request_size(tpAniSirGlobal pCtx,
+	tDot11fTPCRequest *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 3;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_TPCRequest);
+	return status;
+} /* End dot11f_get_packed_tpc_request_size. */
+
+uint32_t dot11f_get_packed_timing_advertisement_frame_size(tpAniSirGlobal pCtx,
+	tDot11fTimingAdvertisementFrame *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 10;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_TimingAdvertisementFrame);
+	return status;
+} /* End dot11f_get_packed_timing_advertisement_frame_size. */
+
+uint32_t dot11f_get_packed_vht_gid_management_action_frame_size(tpAniSirGlobal pCtx,
+	tDot11fVHTGidManagementActionFrame *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 26;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_VHTGidManagementActionFrame);
+	return status;
+} /* End dot11f_get_packed_vht_gid_management_action_frame_size. */
+
+uint32_t dot11f_get_packed_wmm_add_ts_request_size(tpAniSirGlobal pCtx,
+	tDot11fWMMAddTSRequest *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 4;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_WMMAddTSRequest);
+	return status;
+} /* End dot11f_get_packed_wmm_add_ts_request_size. */
+
+uint32_t dot11f_get_packed_wmm_add_ts_response_size(tpAniSirGlobal pCtx,
+	tDot11fWMMAddTSResponse *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 4;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_WMMAddTSResponse);
+	return status;
+} /* End dot11f_get_packed_wmm_add_ts_response_size. */
+
+uint32_t dot11f_get_packed_wmm_del_ts_size(tpAniSirGlobal pCtx,
+	tDot11fWMMDelTS *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 4;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_WMMDelTS);
+	return status;
+} /* End dot11f_get_packed_wmm_del_ts_size. */
+
+uint32_t dot11f_get_packed_addba_req_size(tpAniSirGlobal pCtx,
+	tDot11faddba_req *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 9;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_addba_req);
+	return status;
+} /* End dot11f_get_packed_addba_req_size. */
+
+uint32_t dot11f_get_packed_addba_rsp_size(tpAniSirGlobal pCtx,
+	tDot11faddba_rsp *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 9;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_addba_rsp);
+	return status;
+} /* End dot11f_get_packed_addba_rsp_size. */
+
+uint32_t dot11f_get_packed_delba_req_size(tpAniSirGlobal pCtx,
+	tDot11fdelba_req *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 6;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_delba_req);
+	return status;
+} /* End dot11f_get_packed_delba_req_size. */
+
+uint32_t dot11f_get_packed_ext_channel_switch_action_frame_size(tpAniSirGlobal pCtx,
+	tDot11fext_channel_switch_action_frame *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 6;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_ext_channel_switch_action_frame);
+	return status;
+} /* End dot11f_get_packed_ext_channel_switch_action_frame_size. */
+
+uint32_t dot11f_get_packed_ht2040_bss_coexistence_mgmt_action_frameSize(tpAniSirGlobal pCtx,
+	tDot11fht2040_bss_coexistence_mgmt_action_frame *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 2;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_ht2040_bss_coexistence_mgmt_action_frame);
+	return status;
+} /* End dot11f_get_packed_ht2040_bss_coexistence_mgmt_action_frameSize. */
+
+uint32_t dot11f_get_packed_p2p_oper_chan_change_confirmSize(tpAniSirGlobal pCtx,
+	tDot11fp2p_oper_chan_change_confirm *pFrm, uint32_t *pnNeeded)
+{
+	uint32_t status = 0;
+	*pnNeeded = 7;
+	status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+				      IES_p2p_oper_chan_change_confirm);
+	return status;
+} /* End dot11f_get_packed_p2p_oper_chan_change_confirmSize. */
+
+static uint32_t get_packed_size_core(tpAniSirGlobal pCtx,
+				      uint8_t *pFrm,
+				      uint32_t *pnNeeded,
+				      const tIEDefn  IEs[])
+{
+	const tIEDefn *pIe;
+	uint16_t  i, n;
+	uint32_t  status;
+	tFRAMES_BOOL *pfFound;
+	uint32_t countOffset = 0;
+	uint32_t byteCount = 0;
+	uint8_t  pIePresent = 0;
+	uint32_t offset = 0;
+
+	status = DOT11F_PARSE_SUCCESS;
+
+	(void)pCtx; /* Shutup the compiler if we have no FFs nor IEs... */
+	i = 0;
+	n = 0;
+	pIe = &(IEs[0]);
+	while (0xff != pIe->eid || pIe->extn_eid) {
+		pfFound = (tFRAMES_BOOL *)(pFrm + pIe->offset +
+					  pIe->presenceOffset);
+		if (*pfFound) {
+			countOffset = ((0 == pIe->arraybound) ? 1 : (*(uint16_t *)(pFrm + pIe->countOffset)));
+			for (i = 0U; i < countOffset; ++i) {
+				*pnNeeded += 2U + pIe->noui;
+				if (pIe->extn_eid)
+						(*pnNeeded)++;
+				byteCount = 0;
+				switch (pIe->sig) {
+				case SigIeGTK:
+					offset = sizeof(tDot11fIEGTK);
+					byteCount = ((tDot11fIEGTK *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_key + 11;
+					pIePresent = ((tDot11fIEGTK *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeIGTK:
+					offset = sizeof(tDot11fIEIGTK);
+					byteCount = 33;
+					pIePresent = ((tDot11fIEIGTK *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeR0KH_ID:
+					offset = sizeof(tDot11fIER0KH_ID);
+					byteCount = ((tDot11fIER0KH_ID *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_PMK_R0_ID;
+					pIePresent = ((tDot11fIER0KH_ID *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeR1KH_ID:
+					offset = sizeof(tDot11fIER1KH_ID);
+					byteCount = 6;
+					pIePresent = ((tDot11fIER1KH_ID *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeAPChannelReport:
+					offset = sizeof(tDot11fIEAPChannelReport);
+					byteCount = ((tDot11fIEAPChannelReport *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_channelList + 1;
+					pIePresent = ((tDot11fIEAPChannelReport *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeBcnReportingDetail:
+					offset = sizeof(tDot11fIEBcnReportingDetail);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEBcnReportingDetail *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeBeaconReportFrmBody:
+					offset = sizeof(tDot11fIEBeaconReportFrmBody);
+					byteCount = ((tDot11fIEBeaconReportFrmBody *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_reportedFields;
+					pIePresent = ((tDot11fIEBeaconReportFrmBody *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeBeaconReporting:
+					offset = sizeof(tDot11fIEBeaconReporting);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEBeaconReporting *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeCondensedCountryStr:
+					offset = sizeof(tDot11fIECondensedCountryStr);
+					byteCount = 2;
+					pIePresent = ((tDot11fIECondensedCountryStr *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeMeasurementPilot:
+					offset = sizeof(tDot11fIEMeasurementPilot);
+					byteCount = ((tDot11fIEMeasurementPilot *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_vendorSpecific + 1;
+					pIePresent = ((tDot11fIEMeasurementPilot *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeMultiBssid:
+					offset = sizeof(tDot11fIEMultiBssid);
+					byteCount = ((tDot11fIEMultiBssid *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_vendorSpecific + 1;
+					pIePresent = ((tDot11fIEMultiBssid *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeRICData:
+					offset = sizeof(tDot11fIERICData);
+					byteCount = 4;
+					pIePresent = ((tDot11fIERICData *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeRICDescriptor:
+					offset = sizeof(tDot11fIERICDescriptor);
+					byteCount = ((tDot11fIERICDescriptor *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_variableData + 1;
+					pIePresent = ((tDot11fIERICDescriptor *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeRRMEnabledCap:
+					offset = sizeof(tDot11fIERRMEnabledCap);
+					byteCount = 5;
+					pIePresent = ((tDot11fIERRMEnabledCap *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeRequestedInfo:
+					offset = sizeof(tDot11fIERequestedInfo);
+					byteCount = ((tDot11fIERequestedInfo *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_requested_eids;
+					pIePresent = ((tDot11fIERequestedInfo *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeSSID:
+					offset = sizeof(tDot11fIESSID);
+					byteCount = ((tDot11fIESSID *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_ssid;
+					pIePresent = ((tDot11fIESSID *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeSchedule:
+					offset = sizeof(tDot11fIESchedule);
+					byteCount = 14;
+					pIePresent = ((tDot11fIESchedule *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeTCLAS:
+					offset = sizeof(tDot11fIETCLAS);
+					status |=
+						dot11f_get_packed_ietclas(
+						pCtx, (tDot11fIETCLAS *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeTCLASSPROC:
+					offset = sizeof(tDot11fIETCLASSPROC);
+					byteCount = 1;
+					pIePresent = ((tDot11fIETCLASSPROC *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeTSDelay:
+					offset = sizeof(tDot11fIETSDelay);
+					byteCount = 4;
+					pIePresent = ((tDot11fIETSDelay *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeTSFInfo:
+					offset = sizeof(tDot11fIETSFInfo);
+					byteCount = 4;
+					pIePresent = ((tDot11fIETSFInfo *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeTSPEC:
+					offset = sizeof(tDot11fIETSPEC);
+					byteCount = 55;
+					pIePresent = ((tDot11fIETSPEC *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeVHTCaps:
+					offset = sizeof(tDot11fIEVHTCaps);
+					byteCount = 12;
+					pIePresent = ((tDot11fIEVHTCaps *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeVHTOperation:
+					offset = sizeof(tDot11fIEVHTOperation);
+					byteCount = 5;
+					pIePresent = ((tDot11fIEVHTOperation *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWMMSchedule:
+					offset = sizeof(tDot11fIEWMMSchedule);
+					byteCount = 15;
+					pIePresent = ((tDot11fIEWMMSchedule *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWMMTCLAS:
+					offset = sizeof(tDot11fIEWMMTCLAS);
+					status |=
+						dot11f_get_packed_iewmmtclas(
+						pCtx, (tDot11fIEWMMTCLAS *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeWMMTCLASPROC:
+					offset = sizeof(tDot11fIEWMMTCLASPROC);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEWMMTCLASPROC *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWMMTSDelay:
+					offset = sizeof(tDot11fIEWMMTSDelay);
+					byteCount = 5;
+					pIePresent = ((tDot11fIEWMMTSDelay *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWMMTSPEC:
+					offset = sizeof(tDot11fIEWMMTSPEC);
+					byteCount = 56;
+					pIePresent = ((tDot11fIEWMMTSPEC *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWiderBWChanSwitchAnn:
+					offset = sizeof(tDot11fIEWiderBWChanSwitchAnn);
+					byteCount = 3;
+					pIePresent = ((tDot11fIEWiderBWChanSwitchAnn *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeazimuth_req:
+					offset = sizeof(tDot11fIEazimuth_req);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEazimuth_req *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIebeacon_report_frm_body_fragment_id:
+					offset = sizeof(tDot11fIEbeacon_report_frm_body_fragment_id);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEbeacon_report_frm_body_fragment_id *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIelast_beacon_report_indication:
+					offset = sizeof(tDot11fIElast_beacon_report_indication);
+					byteCount = 1;
+					pIePresent = ((tDot11fIElast_beacon_report_indication *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIemax_age:
+					offset = sizeof(tDot11fIEmax_age);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEmax_age *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeneighbor_rpt:
+					offset = sizeof(tDot11fIEneighbor_rpt);
+					status |=
+						dot11f_get_packed_ie_neighbor_rpt(
+						pCtx, (tDot11fIEneighbor_rpt *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIereq_mac_addr:
+					offset = sizeof(tDot11fIEreq_mac_addr);
+					byteCount = 6;
+					pIePresent = ((tDot11fIEreq_mac_addr *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIetgt_mac_addr:
+					offset = sizeof(tDot11fIEtgt_mac_addr);
+					byteCount = 6;
+					pIePresent = ((tDot11fIEtgt_mac_addr *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIevht_transmit_power_env:
+					offset = sizeof(tDot11fIEvht_transmit_power_env);
+					byteCount = ((tDot11fIEvht_transmit_power_env *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_bytes;
+					pIePresent = ((tDot11fIEvht_transmit_power_env *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeAID:
+					offset = sizeof(tDot11fIEAID);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEAID *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeCFParams:
+					offset = sizeof(tDot11fIECFParams);
+					byteCount = 6;
+					pIePresent = ((tDot11fIECFParams *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeChallengeText:
+					offset = sizeof(tDot11fIEChallengeText);
+					byteCount = ((tDot11fIEChallengeText *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_text;
+					pIePresent = ((tDot11fIEChallengeText *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeChanSwitchAnn:
+					offset = sizeof(tDot11fIEChanSwitchAnn);
+					byteCount = 3;
+					pIePresent = ((tDot11fIEChanSwitchAnn *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeChannelSwitchWrapper:
+					offset = sizeof(tDot11fIEChannelSwitchWrapper);
+					status |=
+						dot11f_get_packed_ie_channel_switch_wrapper(
+						pCtx, (tDot11fIEChannelSwitchWrapper *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeCountry:
+					offset = sizeof(tDot11fIECountry);
+					status |=
+						dot11f_get_packed_ie_country(
+						pCtx, (tDot11fIECountry *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeDSParams:
+					offset = sizeof(tDot11fIEDSParams);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEDSParams *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeEDCAParamSet:
+					offset = sizeof(tDot11fIEEDCAParamSet);
+					byteCount = 18;
+					pIePresent = ((tDot11fIEEDCAParamSet *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeERPInfo:
+					offset = sizeof(tDot11fIEERPInfo);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEERPInfo *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeESECckmOpaque:
+					offset = sizeof(tDot11fIEESECckmOpaque);
+					byteCount = ((tDot11fIEESECckmOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_data;
+					pIePresent = ((tDot11fIEESECckmOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeESERadMgmtCap:
+					offset = sizeof(tDot11fIEESERadMgmtCap);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEESERadMgmtCap *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeESETrafStrmMet:
+					offset = sizeof(tDot11fIEESETrafStrmMet);
+					byteCount = 4;
+					pIePresent = ((tDot11fIEESETrafStrmMet *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeESETrafStrmRateSet:
+					offset = sizeof(tDot11fIEESETrafStrmRateSet);
+					byteCount = ((tDot11fIEESETrafStrmRateSet *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_tsrates + 1;
+					pIePresent = ((tDot11fIEESETrafStrmRateSet *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeESETxmitPower:
+					offset = sizeof(tDot11fIEESETxmitPower);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEESETxmitPower *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeESEVersion:
+					offset = sizeof(tDot11fIEESEVersion);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEESEVersion *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeExtCap:
+					offset = sizeof(tDot11fIEExtCap);
+					byteCount = ((tDot11fIEExtCap *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_bytes;
+					pIePresent = ((tDot11fIEExtCap *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeExtSuppRates:
+					offset = sizeof(tDot11fIEExtSuppRates);
+					byteCount = ((tDot11fIEExtSuppRates *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_rates;
+					pIePresent = ((tDot11fIEExtSuppRates *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeFHParamSet:
+					offset = sizeof(tDot11fIEFHParamSet);
+					byteCount = 5;
+					pIePresent = ((tDot11fIEFHParamSet *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeFHParams:
+					offset = sizeof(tDot11fIEFHParams);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEFHParams *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeFHPattTable:
+					offset = sizeof(tDot11fIEFHPattTable);
+					byteCount = ((tDot11fIEFHPattTable *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_randtable + 4;
+					pIePresent = ((tDot11fIEFHPattTable *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeFTInfo:
+					offset = sizeof(tDot11fIEFTInfo);
+					status |=
+						dot11f_get_packed_ieft_info(
+						pCtx, (tDot11fIEFTInfo *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeHTCaps:
+					offset = sizeof(tDot11fIEHTCaps);
+					byteCount = ((tDot11fIEHTCaps *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_rsvd + 26;
+					pIePresent = ((tDot11fIEHTCaps *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeHTInfo:
+					offset = sizeof(tDot11fIEHTInfo);
+					byteCount = ((tDot11fIEHTInfo *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_rsvd + 22;
+					pIePresent = ((tDot11fIEHTInfo *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeIBSSParams:
+					offset = sizeof(tDot11fIEIBSSParams);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEIBSSParams *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeLinkIdentifier:
+					offset = sizeof(tDot11fIELinkIdentifier);
+					byteCount = 18;
+					pIePresent = ((tDot11fIELinkIdentifier *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeMBO_IE:
+					offset = sizeof(tDot11fIEMBO_IE);
+					status |=
+						dot11f_get_packed_ie_MBO_IE(
+						pCtx, (tDot11fIEMBO_IE *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeMeasurementReport:
+					offset = sizeof(tDot11fIEMeasurementReport);
+					status |=
+						dot11f_get_packed_ie_measurement_report(
+						pCtx, (tDot11fIEMeasurementReport *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeMeasurementRequest:
+					offset = sizeof(tDot11fIEMeasurementRequest);
+					status |=
+						dot11f_get_packed_ie_measurement_request(
+						pCtx, (tDot11fIEMeasurementRequest *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeMobilityDomain:
+					offset = sizeof(tDot11fIEMobilityDomain);
+					byteCount = 3;
+					pIePresent = ((tDot11fIEMobilityDomain *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeNeighborReport:
+					offset = sizeof(tDot11fIENeighborReport);
+					status |=
+						dot11f_get_packed_ie_neighbor_report(
+						pCtx, (tDot11fIENeighborReport *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeOBSSScanParameters:
+					offset = sizeof(tDot11fIEOBSSScanParameters);
+					byteCount = 14;
+					pIePresent = ((tDot11fIEOBSSScanParameters *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeOperatingMode:
+					offset = sizeof(tDot11fIEOperatingMode);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEOperatingMode *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeP2PAssocReq:
+					offset = sizeof(tDot11fIEP2PAssocReq);
+					status |=
+						dot11f_get_packed_iep2_p_assoc_req(
+						pCtx, (tDot11fIEP2PAssocReq *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeP2PAssocRes:
+					offset = sizeof(tDot11fIEP2PAssocRes);
+					status |=
+						dot11f_get_packed_iep2_p_assoc_res(
+						pCtx, (tDot11fIEP2PAssocRes *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeP2PBeacon:
+					offset = sizeof(tDot11fIEP2PBeacon);
+					status |=
+						dot11f_get_packed_iep2_p_beacon(
+						pCtx, (tDot11fIEP2PBeacon *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeP2PBeaconProbeRes:
+					offset = sizeof(tDot11fIEP2PBeaconProbeRes);
+					status |=
+						dot11f_get_packed_iep2_p_beacon_probe_res(
+						pCtx, (tDot11fIEP2PBeaconProbeRes *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeP2PDeAuth:
+					offset = sizeof(tDot11fIEP2PDeAuth);
+					status |=
+						dot11f_get_packed_iep2_p_de_auth(
+						pCtx, (tDot11fIEP2PDeAuth *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeP2PDisAssoc:
+					offset = sizeof(tDot11fIEP2PDisAssoc);
+					status |=
+						dot11f_get_packed_iep2_p_dis_assoc(
+						pCtx, (tDot11fIEP2PDisAssoc *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeP2PIEOpaque:
+					offset = sizeof(tDot11fIEP2PIEOpaque);
+					byteCount = ((tDot11fIEP2PIEOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_data;
+					pIePresent = ((tDot11fIEP2PIEOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeP2PProbeReq:
+					offset = sizeof(tDot11fIEP2PProbeReq);
+					status |=
+						dot11f_get_packed_iep2_p_probe_req(
+						pCtx, (tDot11fIEP2PProbeReq *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeP2PProbeRes:
+					offset = sizeof(tDot11fIEP2PProbeRes);
+					status |=
+						dot11f_get_packed_iep2_p_probe_res(
+						pCtx, (tDot11fIEP2PProbeRes *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIePTIControl:
+					offset = sizeof(tDot11fIEPTIControl);
+					byteCount = 3;
+					pIePresent = ((tDot11fIEPTIControl *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIePUBufferStatus:
+					offset = sizeof(tDot11fIEPUBufferStatus);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEPUBufferStatus *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIePowerCaps:
+					offset = sizeof(tDot11fIEPowerCaps);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEPowerCaps *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIePowerConstraints:
+					offset = sizeof(tDot11fIEPowerConstraints);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEPowerConstraints *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeQBSSLoad:
+					offset = sizeof(tDot11fIEQBSSLoad);
+					byteCount = 5;
+					pIePresent = ((tDot11fIEQBSSLoad *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeQCN_IE:
+					offset = sizeof(tDot11fIEQCN_IE);
+					byteCount = 4;
+					pIePresent = ((tDot11fIEQCN_IE *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeQComVendorIE:
+					offset = sizeof(tDot11fIEQComVendorIE);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEQComVendorIE *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeQOSCapsAp:
+					offset = sizeof(tDot11fIEQOSCapsAp);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEQOSCapsAp *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeQOSCapsStation:
+					offset = sizeof(tDot11fIEQOSCapsStation);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEQOSCapsStation *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeQosMapSet:
+					offset = sizeof(tDot11fIEQosMapSet);
+					byteCount = ((tDot11fIEQosMapSet *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_dscp_exceptions;
+					pIePresent = ((tDot11fIEQosMapSet *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeQuiet:
+					offset = sizeof(tDot11fIEQuiet);
+					byteCount = 6;
+					pIePresent = ((tDot11fIEQuiet *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeRCPIIE:
+					offset = sizeof(tDot11fIERCPIIE);
+					byteCount = 1;
+					pIePresent = ((tDot11fIERCPIIE *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeRICDataDesc:
+					offset = sizeof(tDot11fIERICDataDesc);
+					pnNeeded -= 2  ; /* Subtract the length and Oui as this is our container IE to group Ies and it doesn't have its own length and OUI. */
+					status |=
+						dot11f_get_packed_ieric_data_desc(
+						pCtx, (tDot11fIERICDataDesc *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeRSN:
+					offset = sizeof(tDot11fIERSN);
+					status |=
+						dot11f_get_packed_iersn(
+						pCtx, (tDot11fIERSN *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeRSNIIE:
+					offset = sizeof(tDot11fIERSNIIE);
+					byteCount = 1;
+					pIePresent = ((tDot11fIERSNIIE *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeRSNOpaque:
+					offset = sizeof(tDot11fIERSNOpaque);
+					byteCount = ((tDot11fIERSNOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_data;
+					pIePresent = ((tDot11fIERSNOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeSuppChannels:
+					offset = sizeof(tDot11fIESuppChannels);
+					byteCount = ((tDot11fIESuppChannels *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_bands * 2;
+					pIePresent = ((tDot11fIESuppChannels *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeSuppOperatingClasses:
+					offset = sizeof(tDot11fIESuppOperatingClasses);
+					byteCount = ((tDot11fIESuppOperatingClasses *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_classes;
+					pIePresent = ((tDot11fIESuppOperatingClasses *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeSuppRates:
+					offset = sizeof(tDot11fIESuppRates);
+					byteCount = ((tDot11fIESuppRates *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_rates;
+					pIePresent = ((tDot11fIESuppRates *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeTIM:
+					offset = sizeof(tDot11fIETIM);
+					byteCount = ((tDot11fIETIM *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_vbmp + 3;
+					pIePresent = ((tDot11fIETIM *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeTPCReport:
+					offset = sizeof(tDot11fIETPCReport);
+					byteCount = 2;
+					pIePresent = ((tDot11fIETPCReport *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeTPCRequest:
+					offset = sizeof(tDot11fIETPCRequest);
+					byteCount = 0;
+					pIePresent = ((tDot11fIETPCRequest *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeTimeAdvertisement:
+					offset = sizeof(tDot11fIETimeAdvertisement);
+					byteCount = 16;
+					pIePresent = ((tDot11fIETimeAdvertisement *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeTimeoutInterval:
+					offset = sizeof(tDot11fIETimeoutInterval);
+					byteCount = 5;
+					pIePresent = ((tDot11fIETimeoutInterval *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeVHTExtBssLoad:
+					offset = sizeof(tDot11fIEVHTExtBssLoad);
+					byteCount = 5;
+					pIePresent = ((tDot11fIEVHTExtBssLoad *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeVendor1IE:
+					offset = sizeof(tDot11fIEVendor1IE);
+					byteCount = 0;
+					pIePresent = ((tDot11fIEVendor1IE *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeVendor3IE:
+					offset = sizeof(tDot11fIEVendor3IE);
+					byteCount = 0;
+					pIePresent = ((tDot11fIEVendor3IE *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWAPI:
+					offset = sizeof(tDot11fIEWAPI);
+					status |=
+						dot11f_get_packed_iewapi(
+						pCtx, (tDot11fIEWAPI *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeWAPIOpaque:
+					offset = sizeof(tDot11fIEWAPIOpaque);
+					byteCount = ((tDot11fIEWAPIOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_data;
+					pIePresent = ((tDot11fIEWAPIOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWFATPC:
+					offset = sizeof(tDot11fIEWFATPC);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEWFATPC *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWFDIEOpaque:
+					offset = sizeof(tDot11fIEWFDIEOpaque);
+					byteCount = ((tDot11fIEWFDIEOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_data;
+					pIePresent = ((tDot11fIEWFDIEOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWMMCaps:
+					offset = sizeof(tDot11fIEWMMCaps);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEWMMCaps *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWMMInfoAp:
+					offset = sizeof(tDot11fIEWMMInfoAp);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEWMMInfoAp *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWMMInfoStation:
+					offset = sizeof(tDot11fIEWMMInfoStation);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEWMMInfoStation *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWMMParams:
+					offset = sizeof(tDot11fIEWMMParams);
+					byteCount = 19;
+					pIePresent = ((tDot11fIEWMMParams *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWPA:
+					offset = sizeof(tDot11fIEWPA);
+					status |=
+						dot11f_get_packed_iewpa(
+						pCtx, (tDot11fIEWPA *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeWPAOpaque:
+					offset = sizeof(tDot11fIEWPAOpaque);
+					byteCount = ((tDot11fIEWPAOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_data;
+					pIePresent = ((tDot11fIEWPAOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWSC:
+					offset = sizeof(tDot11fIEWSC);
+					status |=
+						dot11f_get_packed_iewsc(
+						pCtx, (tDot11fIEWSC *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeWscAssocReq:
+					offset = sizeof(tDot11fIEWscAssocReq);
+					status |=
+						dot11f_get_packed_ie_wsc_assoc_req(
+						pCtx, (tDot11fIEWscAssocReq *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeWscAssocRes:
+					offset = sizeof(tDot11fIEWscAssocRes);
+					status |=
+						dot11f_get_packed_ie_wsc_assoc_res(
+						pCtx, (tDot11fIEWscAssocRes *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeWscBeacon:
+					offset = sizeof(tDot11fIEWscBeacon);
+					status |=
+						dot11f_get_packed_ie_wsc_beacon(
+						pCtx, (tDot11fIEWscBeacon *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeWscBeaconProbeRes:
+					offset = sizeof(tDot11fIEWscBeaconProbeRes);
+					status |=
+						dot11f_get_packed_ie_wsc_beacon_probe_res(
+						pCtx, (tDot11fIEWscBeaconProbeRes *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeWscIEOpaque:
+					offset = sizeof(tDot11fIEWscIEOpaque);
+					byteCount = ((tDot11fIEWscIEOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_data;
+					pIePresent = ((tDot11fIEWscIEOpaque *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeWscProbeReq:
+					offset = sizeof(tDot11fIEWscProbeReq);
+					status |=
+						dot11f_get_packed_ie_wsc_probe_req(
+						pCtx, (tDot11fIEWscProbeReq *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeWscProbeRes:
+					offset = sizeof(tDot11fIEWscProbeRes);
+					status |=
+						dot11f_get_packed_ie_wsc_probe_res(
+						pCtx, (tDot11fIEWscProbeRes *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeWscReassocRes:
+					offset = sizeof(tDot11fIEWscReassocRes);
+					status |=
+						dot11f_get_packed_ie_wsc_reassoc_res(
+						pCtx, (tDot11fIEWscReassocRes *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeaddba_extn_element:
+					offset = sizeof(tDot11fIEaddba_extn_element);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEaddba_extn_element *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIebss_color_change:
+					offset = sizeof(tDot11fIEbss_color_change);
+					byteCount = 2;
+					pIePresent = ((tDot11fIEbss_color_change *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIedh_parameter_element:
+					offset = sizeof(tDot11fIEdh_parameter_element);
+					byteCount = ((tDot11fIEdh_parameter_element *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_public_key + 2;
+					pIePresent = ((tDot11fIEdh_parameter_element *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeesp_information:
+					offset = sizeof(tDot11fIEesp_information);
+					byteCount = ((tDot11fIEesp_information *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_data;
+					pIePresent = ((tDot11fIEesp_information *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeext_chan_switch_ann:
+					offset = sizeof(tDot11fIEext_chan_switch_ann);
+					byteCount = 4;
+					pIePresent = ((tDot11fIEext_chan_switch_ann *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIefils_assoc_delay_info:
+					offset = sizeof(tDot11fIEfils_assoc_delay_info);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEfils_assoc_delay_info *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIefils_hlp_container:
+					offset = sizeof(tDot11fIEfils_hlp_container);
+					byteCount = ((tDot11fIEfils_hlp_container *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_hlp_packet + 12;
+					pIePresent = ((tDot11fIEfils_hlp_container *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIefils_indication:
+					offset = sizeof(tDot11fIEfils_indication);
+					byteCount = ((tDot11fIEfils_indication *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_variable_data + 2;
+					pIePresent = ((tDot11fIEfils_indication *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIefils_kde:
+					offset = sizeof(tDot11fIEfils_kde);
+					byteCount = ((tDot11fIEfils_kde *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_kde_list + 8;
+					pIePresent = ((tDot11fIEfils_kde *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIefils_key_confirmation:
+					offset = sizeof(tDot11fIEfils_key_confirmation);
+					byteCount = ((tDot11fIEfils_key_confirmation *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_key_auth;
+					pIePresent = ((tDot11fIEfils_key_confirmation *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIefils_nonce:
+					offset = sizeof(tDot11fIEfils_nonce);
+					byteCount = 16;
+					pIePresent = ((tDot11fIEfils_nonce *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIefils_public_key:
+					offset = sizeof(tDot11fIEfils_public_key);
+					byteCount = ((tDot11fIEfils_public_key *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_public_key + 1;
+					pIePresent = ((tDot11fIEfils_public_key *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIefils_session:
+					offset = sizeof(tDot11fIEfils_session);
+					byteCount = 8;
+					pIePresent = ((tDot11fIEfils_session *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIefils_wrapped_data:
+					offset = sizeof(tDot11fIEfils_wrapped_data);
+					byteCount = ((tDot11fIEfils_wrapped_data *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_wrapped_data;
+					pIePresent = ((tDot11fIEfils_wrapped_data *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIefragment_ie:
+					offset = sizeof(tDot11fIEfragment_ie);
+					byteCount = ((tDot11fIEfragment_ie *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_data;
+					pIePresent = ((tDot11fIEfragment_ie *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIehe_cap:
+					offset = sizeof(tDot11fIEhe_cap);
+					status |=
+						dot11f_get_packed_ie_he_cap(
+						pCtx, (tDot11fIEhe_cap *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIehe_op:
+					offset = sizeof(tDot11fIEhe_op);
+					status |=
+						dot11f_get_packed_ie_he_op(
+						pCtx, (tDot11fIEhe_op *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIehs20vendor_ie:
+					offset = sizeof(tDot11fIEhs20vendor_ie);
+					status |=
+						dot11f_get_packed_ie_hs20vendor_ie(
+						pCtx, (tDot11fIEhs20vendor_ie *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				case SigIeht2040_bss_coexistence:
+					offset = sizeof(tDot11fIEht2040_bss_coexistence);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEht2040_bss_coexistence *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeht2040_bss_intolerant_report:
+					offset = sizeof(tDot11fIEht2040_bss_intolerant_report);
+					byteCount = ((tDot11fIEht2040_bss_intolerant_report *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_channel_list + 1;
+					pIePresent = ((tDot11fIEht2040_bss_intolerant_report *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIemu_edca_param_set:
+					offset = sizeof(tDot11fIEmu_edca_param_set);
+					byteCount = 13;
+					pIePresent = ((tDot11fIEmu_edca_param_set *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIeosen_ie:
+					offset = sizeof(tDot11fIEosen_ie);
+					byteCount = ((tDot11fIEosen_ie *)
+					  (pFrm + pIe->offset + offset * i))->
+					  num_data;
+					pIePresent = ((tDot11fIEosen_ie *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIesec_chan_offset_ele:
+					offset = sizeof(tDot11fIEsec_chan_offset_ele);
+					byteCount = 1;
+					pIePresent = ((tDot11fIEsec_chan_offset_ele *)
+					  (pFrm + pIe->offset + offset * i))->
+					  present;
+					break;
+				case SigIevendor_vht_ie:
+					offset = sizeof(tDot11fIEvendor_vht_ie);
+					status |=
+						dot11f_get_packed_ie_vendor_vht_ie(
+						pCtx, (tDot11fIEvendor_vht_ie *)
+						(pFrm + pIe->offset + offset * i),
+						pnNeeded);
+					break;
+				default:
+					FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don"
+						"'t know about the IE signature %d; this is most l"
+						"ikely a bug in 'framesc'.\n"), pIe->sig);
+					return DOT11F_INTERNAL_ERROR;
+				} /*End of switch Case*/
+
+				if (byteCount && pIePresent)
+					*pnNeeded += byteCount;
+			} /*End of for loop*/
+		}
+		++pIe;
+	}
+	return status;
+
+}
+
+static uint32_t get_packed_size_tlv_core(tpAniSirGlobal pCtx,
+				uint8_t *pFrm,
+				uint32_t *pnNeeded,
+				const tTLVDefn  TLVs[])
+{
+	const tTLVDefn *pTlv;
+	uint32_t   status;
+	tFRAMES_BOOL   *pfFound;
+	uint32_t   byteCount = 0;
+	uint8_t    pTlvPresent = 0;
+
+	status = DOT11F_PARSE_SUCCESS;
+
+	pTlv = &(TLVs[0]);
+	while (0xffff != pTlv->id) {
+		pfFound = (tFRAMES_BOOL *)(pFrm + pTlv->offset +
+				pTlv->presenceOffset);
+		if (*pfFound) {
+			*pnNeeded += (pTlv->sType + pTlv->sLen);
+			if (pTlv->pec)
+				*pnNeeded += 3U;
+			switch (pTlv->sig) {
+			case SigTlvAuthorizedMACs:
+				byteCount = 6;
+				pTlvPresent = ((tDot11fTLVAuthorizedMACs *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvRequestToEnroll:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVRequestToEnroll *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvVersion2:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVVersion2 *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvAPSetupLocked:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVAPSetupLocked *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvAssociationState:
+				byteCount = 2;
+				pTlvPresent = ((tDot11fTLVAssociationState *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvConfigMethods:
+				byteCount = 2;
+				pTlvPresent = ((tDot11fTLVConfigMethods *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvConfigurationError:
+				byteCount = 2;
+				pTlvPresent = ((tDot11fTLVConfigurationError *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvDeviceName:
+				byteCount = ((tDot11fTLVDeviceName *)(pFrm + pTlv->offset))->num_text;
+				pTlvPresent = ((tDot11fTLVDeviceName *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvDevicePasswordID:
+				byteCount = 2;
+				pTlvPresent = ((tDot11fTLVDevicePasswordID *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvExtendedListenTiming:
+				byteCount = 4;
+				pTlvPresent = ((tDot11fTLVExtendedListenTiming *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvListenChannel:
+				byteCount = 5;
+				pTlvPresent = ((tDot11fTLVListenChannel *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvManufacturer:
+				byteCount = ((tDot11fTLVManufacturer *)(pFrm + pTlv->offset))->num_name;
+				pTlvPresent = ((tDot11fTLVManufacturer *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvMinorReasonCode:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVMinorReasonCode *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvModelName:
+				byteCount = ((tDot11fTLVModelName *)(pFrm + pTlv->offset))->num_text;
+				pTlvPresent = ((tDot11fTLVModelName *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvModelNumber:
+				byteCount = ((tDot11fTLVModelNumber *)(pFrm + pTlv->offset))->num_text;
+				pTlvPresent = ((tDot11fTLVModelNumber *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvNoticeOfAbsence:
+				byteCount = ((tDot11fTLVNoticeOfAbsence *)(pFrm + pTlv->offset))->num_NoADesc+2;
+				pTlvPresent = ((tDot11fTLVNoticeOfAbsence *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvOperatingChannel:
+				byteCount = 5;
+				pTlvPresent = ((tDot11fTLVOperatingChannel *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvP2PCapability:
+				byteCount = 2;
+				pTlvPresent = ((tDot11fTLVP2PCapability *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvP2PDeviceId:
+				byteCount = 6;
+				pTlvPresent = ((tDot11fTLVP2PDeviceId *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvP2PDeviceInfo:
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pFrm + pTlv->offset, pnNeeded, TLVS_P2PDeviceInfo);
+				byteCount = 16;
+				pTlvPresent = ((tDot11fTLVP2PDeviceInfo *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvP2PGroupInfo:
+				byteCount = ((tDot11fTLVP2PGroupInfo *)(pFrm + pTlv->offset))->num_P2PClientInfoDesc;
+				pTlvPresent = ((tDot11fTLVP2PGroupInfo *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvP2PStatus:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVP2PStatus *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvPrimaryDeviceType:
+				byteCount = 8;
+				pTlvPresent = ((tDot11fTLVPrimaryDeviceType *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvRFBands:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVRFBands *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvRequestDeviceType:
+				byteCount = 8;
+				pTlvPresent = ((tDot11fTLVRequestDeviceType *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvRequestType:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVRequestType *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvResponseType:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVResponseType *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvSelectedRegistrar:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVSelectedRegistrar *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvSelectedRegistrarConfigMethods:
+				byteCount = 2;
+				pTlvPresent = ((tDot11fTLVSelectedRegistrarConfigMethods *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvSerialNumber:
+				byteCount = ((tDot11fTLVSerialNumber *)(pFrm + pTlv->offset))->num_text;
+				pTlvPresent = ((tDot11fTLVSerialNumber *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvUUID_E:
+				byteCount = 16;
+				pTlvPresent = ((tDot11fTLVUUID_E *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvUUID_R:
+				byteCount = 16;
+				pTlvPresent = ((tDot11fTLVUUID_R *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvVendorExtension:
+		status = get_packed_size_tlv_core(pCtx, (uint8_t *)pFrm + pTlv->offset, pnNeeded, TLVS_VendorExtension);
+				byteCount = 3;
+				pTlvPresent = ((tDot11fTLVVendorExtension *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvVersion:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVVersion *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvWPSState:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVWPSState *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvassoc_disallowed:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVassoc_disallowed *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvassoc_retry_delay:
+				byteCount = 2;
+				pTlvPresent = ((tDot11fTLVassoc_retry_delay *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvcellular_data_cap:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVcellular_data_cap *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvcellular_data_con_pref:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVcellular_data_con_pref *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvmbo_ap_cap:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVmbo_ap_cap *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvnon_prefferd_chan_rep:
+				byteCount = ((tDot11fTLVnon_prefferd_chan_rep *)(pFrm + pTlv->offset))->num_channel_report+1;
+				pTlvPresent = ((tDot11fTLVnon_prefferd_chan_rep *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvoce_cap:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVoce_cap *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvreduced_wan_metrics:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVreduced_wan_metrics *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvrssi_assoc_rej:
+				byteCount = 2;
+				pTlvPresent = ((tDot11fTLVrssi_assoc_rej *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvtransition_reason:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVtransition_reason *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvtransition_reject_reason:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVtransition_reject_reason *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvP2PInterface:
+				byteCount = 6;
+				pTlvPresent = ((tDot11fTLVP2PInterface *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			case SigTlvP2PManageability:
+				byteCount = 1;
+				pTlvPresent = ((tDot11fTLVP2PManageability *)
+					      (pFrm + pTlv->offset))->present;
+				break;
+			default:
+				FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don"
+				    "'t know about the TLV signature %d; this is most l"
+				    "ikely a bug in 'framesc'.\n"), pTlv->sig);
+				return DOT11F_INTERNAL_ERROR;
+			}
+			if (pTlvPresent) {
+				*pnNeeded += byteCount;
+			}
+		}
+		++pTlv;
+	}
+	return status;
+}
+void dot11f_pack_ff_aid(tpAniSirGlobal pCtx,
+			tDot11fFfAID *pSrc,
+			uint8_t *pBuf)
+{
+	frameshtons(pCtx, pBuf, pSrc->associd, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_aid. */
+
+void dot11f_pack_ff_action(tpAniSirGlobal pCtx,
+			   tDot11fFfAction *pSrc,
+			   uint8_t *pBuf)
+{
+	*pBuf = pSrc->action;
+	(void)pCtx;
+} /* End dot11f_pack_ff_action. */
+
+void dot11f_pack_ff_auth_algo(tpAniSirGlobal pCtx,
+			     tDot11fFfAuthAlgo *pSrc,
+			     uint8_t *pBuf)
+{
+	frameshtons(pCtx, pBuf, pSrc->algo, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_auth_algo. */
+
+void dot11f_pack_ff_auth_seq_no(tpAniSirGlobal pCtx,
+			      tDot11fFfAuthSeqNo *pSrc,
+			      uint8_t *pBuf)
+{
+	frameshtons(pCtx, pBuf, pSrc->no, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_auth_seq_no. */
+
+void dot11f_pack_ff_beacon_interval(tpAniSirGlobal pCtx,
+				   tDot11fFfBeaconInterval *pSrc,
+				   uint8_t *pBuf)
+{
+	frameshtons(pCtx, pBuf, pSrc->interval, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_beacon_interval. */
+
+void dot11f_pack_ff_capabilities(tpAniSirGlobal pCtx,
+				 tDot11fFfCapabilities *pSrc,
+				 uint8_t *pBuf)
+{
+	uint16_t tmp95__;
+	tmp95__ = 0U;
+	tmp95__ |= (pSrc->ess << 0);
+	tmp95__ |= (pSrc->ibss << 1);
+	tmp95__ |= (pSrc->cfPollable << 2);
+	tmp95__ |= (pSrc->cfPollReq << 3);
+	tmp95__ |= (pSrc->privacy << 4);
+	tmp95__ |= (pSrc->shortPreamble << 5);
+	tmp95__ |= (pSrc->pbcc << 6);
+	tmp95__ |= (pSrc->channelAgility << 7);
+	tmp95__ |= (pSrc->spectrumMgt << 8);
+	tmp95__ |= (pSrc->qos << 9);
+	tmp95__ |= (pSrc->shortSlotTime << 10);
+	tmp95__ |= (pSrc->apsd << 11);
+	tmp95__ |= (pSrc->rrm << 12);
+	tmp95__ |= (pSrc->dsssOfdm << 13);
+	tmp95__ |= (pSrc->delayedBA << 14);
+	tmp95__ |= (pSrc->immediateBA << 15);
+	frameshtons(pCtx, pBuf, tmp95__, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_capabilities. */
+
+void dot11f_pack_ff_category(tpAniSirGlobal pCtx,
+			     tDot11fFfCategory *pSrc,
+			     uint8_t *pBuf)
+{
+	*pBuf = pSrc->category;
+	(void)pCtx;
+} /* End dot11f_pack_ff_category. */
+
+void dot11f_pack_ff_current_ap_address(tpAniSirGlobal pCtx,
+				     tDot11fFfCurrentAPAddress *pSrc,
+				     uint8_t *pBuf)
+{
+	DOT11F_MEMCPY(pCtx, pBuf, pSrc->mac, 6);
+	(void)pCtx;
+} /* End dot11f_pack_ff_current_ap_address. */
+
+void dot11f_pack_ff_dialog_token(tpAniSirGlobal pCtx,
+				tDot11fFfDialogToken *pSrc,
+				uint8_t *pBuf)
+{
+	*pBuf = pSrc->token;
+	(void)pCtx;
+} /* End dot11f_pack_ff_dialog_token. */
+
+void dot11f_pack_ff_link_margin(tpAniSirGlobal pCtx,
+			       tDot11fFfLinkMargin *pSrc,
+			       uint8_t *pBuf)
+{
+	*pBuf = pSrc->linkMargin;
+	(void)pCtx;
+} /* End dot11f_pack_ff_link_margin. */
+
+void dot11f_pack_ff_listen_interval(tpAniSirGlobal pCtx,
+				   tDot11fFfListenInterval *pSrc,
+				   uint8_t *pBuf)
+{
+	frameshtons(pCtx, pBuf, pSrc->interval, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_listen_interval. */
+
+void dot11f_pack_ff_max_tx_power(tpAniSirGlobal pCtx,
+			       tDot11fFfMaxTxPower *pSrc,
+			       uint8_t *pBuf)
+{
+	*pBuf = pSrc->maxTxPower;
+	(void)pCtx;
+} /* End dot11f_pack_ff_max_tx_power. */
+
+void dot11f_pack_ff_num_of_repetitions(tpAniSirGlobal pCtx,
+				     tDot11fFfNumOfRepetitions *pSrc,
+				     uint8_t *pBuf)
+{
+	frameshtons(pCtx, pBuf, pSrc->repetitions, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_num_of_repetitions. */
+
+void dot11f_pack_ff_operating_mode(tpAniSirGlobal pCtx,
+				  tDot11fFfOperatingMode *pSrc,
+				  uint8_t *pBuf)
+{
+	uint8_t tmp96__;
+	tmp96__ = 0U;
+	tmp96__ |= (pSrc->chanWidth << 0);
+	tmp96__ |= (pSrc->reserved << 2);
+	tmp96__ |= (pSrc->rxNSS << 4);
+	tmp96__ |= (pSrc->rxNSSType << 7);
+	*pBuf = tmp96__;
+	(void)pCtx;
+} /* End dot11f_pack_ff_operating_mode. */
+
+void dot11f_pack_ff_rcpi(tpAniSirGlobal pCtx,
+			 tDot11fFfRCPI *pSrc,
+			 uint8_t *pBuf)
+{
+	*pBuf = pSrc->rcpi;
+	(void)pCtx;
+} /* End dot11f_pack_ff_rcpi. */
+
+void dot11f_pack_ff_rsni(tpAniSirGlobal pCtx,
+			 tDot11fFfRSNI *pSrc,
+			 uint8_t *pBuf)
+{
+	*pBuf = pSrc->rsni;
+	(void)pCtx;
+} /* End dot11f_pack_ff_rsni. */
+
+void dot11f_pack_ff_reason(tpAniSirGlobal pCtx,
+			   tDot11fFfReason *pSrc,
+			   uint8_t *pBuf)
+{
+	frameshtons(pCtx, pBuf, pSrc->code, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_reason. */
+
+void dot11f_pack_ff_rx_antenna_id(tpAniSirGlobal pCtx,
+				tDot11fFfRxAntennaId *pSrc,
+				uint8_t *pBuf)
+{
+	*pBuf = pSrc->antennaId;
+	(void)pCtx;
+} /* End dot11f_pack_ff_rx_antenna_id. */
+
+void dot11f_pack_ff_sm_power_mode_set(tpAniSirGlobal pCtx,
+				   tDot11fFfSMPowerModeSet *pSrc,
+				   uint8_t *pBuf)
+{
+	uint8_t tmp97__;
+	tmp97__ = 0U;
+	tmp97__ |= (pSrc->PowerSave_En << 0);
+	tmp97__ |= (pSrc->Mode << 1);
+	tmp97__ |= (pSrc->reserved << 2);
+	*pBuf = tmp97__;
+	(void)pCtx;
+} /* End dot11f_pack_ff_sm_power_mode_set. */
+
+void dot11f_pack_ff_status(tpAniSirGlobal pCtx,
+			   tDot11fFfStatus *pSrc,
+			   uint8_t *pBuf)
+{
+	frameshtons(pCtx, pBuf, pSrc->status, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_status. */
+
+void dot11f_pack_ff_status_code(tpAniSirGlobal pCtx,
+			       tDot11fFfStatusCode *pSrc,
+			       uint8_t *pBuf)
+{
+	*pBuf = pSrc->statusCode;
+	(void)pCtx;
+} /* End dot11f_pack_ff_status_code. */
+
+void dot11f_pack_ff_tpc_ele_id(tpAniSirGlobal pCtx,
+			     tDot11fFfTPCEleID *pSrc,
+			     uint8_t *pBuf)
+{
+	*pBuf = pSrc->TPCId;
+	(void)pCtx;
+} /* End dot11f_pack_ff_tpc_ele_id. */
+
+void dot11f_pack_ff_tpc_ele_len(tpAniSirGlobal pCtx,
+			      tDot11fFfTPCEleLen *pSrc,
+			      uint8_t *pBuf)
+{
+	*pBuf = pSrc->TPCLen;
+	(void)pCtx;
+} /* End dot11f_pack_ff_tpc_ele_len. */
+
+void dot11f_pack_ff_ts_info(tpAniSirGlobal pCtx,
+			   tDot11fFfTSInfo *pSrc,
+			   uint8_t *pBuf)
+{
+	uint32_t tmp98__;
+	tmp98__ = 0U;
+	tmp98__ |= (pSrc->traffic_type << 0);
+	tmp98__ |= (pSrc->tsid << 1);
+	tmp98__ |= (pSrc->direction << 5);
+	tmp98__ |= (pSrc->access_policy << 7);
+	tmp98__ |= (pSrc->aggregation << 9);
+	tmp98__ |= (pSrc->psb << 10);
+	tmp98__ |= (pSrc->user_priority << 11);
+	tmp98__ |= (pSrc->tsinfo_ack_pol << 14);
+	tmp98__ |= (pSrc->schedule << 16);
+	tmp98__ |= (pSrc->unused << 17);
+	frameshtonl(pCtx, pBuf, tmp98__, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_ts_info. */
+
+void dot11f_pack_ff_time_stamp(tpAniSirGlobal pCtx,
+			      tDot11fFfTimeStamp *pSrc,
+			      uint8_t *pBuf)
+{
+	frameshtonq(pCtx, pBuf, pSrc->timestamp, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_time_stamp. */
+
+void dot11f_pack_ff_transaction_id(tpAniSirGlobal pCtx,
+				  tDot11fFfTransactionId *pSrc,
+				  uint8_t *pBuf)
+{
+	DOT11F_MEMCPY(pCtx, pBuf, pSrc->transId, 2);
+	(void)pCtx;
+} /* End dot11f_pack_ff_transaction_id. */
+
+void dot11f_pack_ff_tx_antenna_id(tpAniSirGlobal pCtx,
+				tDot11fFfTxAntennaId *pSrc,
+				uint8_t *pBuf)
+{
+	*pBuf = pSrc->antennaId;
+	(void)pCtx;
+} /* End dot11f_pack_ff_tx_antenna_id. */
+
+void dot11f_pack_ff_tx_power(tpAniSirGlobal pCtx,
+			    tDot11fFfTxPower *pSrc,
+			    uint8_t *pBuf)
+{
+	*pBuf = pSrc->txPower;
+	(void)pCtx;
+} /* End dot11f_pack_ff_tx_power. */
+
+void dot11f_pack_ff_vht_membership_status_array(tpAniSirGlobal pCtx,
+					     tDot11fFfVhtMembershipStatusArray *pSrc,
+					     uint8_t *pBuf)
+{
+	DOT11F_MEMCPY(pCtx, pBuf, pSrc->membershipStatusArray, 8);
+	(void)pCtx;
+} /* End dot11f_pack_ff_vht_membership_status_array. */
+
+void dot11f_pack_ff_vht_user_position_array(tpAniSirGlobal pCtx,
+					 tDot11fFfVhtUserPositionArray *pSrc,
+					 uint8_t *pBuf)
+{
+	DOT11F_MEMCPY(pCtx, pBuf, pSrc->userPositionArray, 16);
+	(void)pCtx;
+} /* End dot11f_pack_ff_vht_user_position_array. */
+
+void dot11f_pack_ff_addba_param_set(tpAniSirGlobal pCtx,
+				    tDot11fFfaddba_param_set *pSrc,
+				    uint8_t *pBuf)
+{
+	uint16_t tmp99__;
+	tmp99__ = 0U;
+	tmp99__ |= (pSrc->amsdu_supp << 0);
+	tmp99__ |= (pSrc->policy << 1);
+	tmp99__ |= (pSrc->tid << 2);
+	tmp99__ |= (pSrc->buff_size << 6);
+	frameshtons(pCtx, pBuf, tmp99__, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_addba_param_set. */
+
+void dot11f_pack_ff_ba_start_seq_ctrl(tpAniSirGlobal pCtx,
+				      tDot11fFfba_start_seq_ctrl *pSrc,
+				      uint8_t *pBuf)
+{
+	uint16_t tmp100__;
+	tmp100__ = 0U;
+	tmp100__ |= (pSrc->frag_number << 0);
+	tmp100__ |= (pSrc->ssn << 4);
+	frameshtons(pCtx, pBuf, tmp100__, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_ba_start_seq_ctrl. */
+
+void dot11f_pack_ff_ba_timeout(tpAniSirGlobal pCtx,
+			       tDot11fFfba_timeout *pSrc,
+			       uint8_t *pBuf)
+{
+	frameshtons(pCtx, pBuf, pSrc->timeout, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_ba_timeout. */
+
+void dot11f_pack_ff_delba_param_set(tpAniSirGlobal pCtx,
+				    tDot11fFfdelba_param_set *pSrc,
+				    uint8_t *pBuf)
+{
+	uint16_t tmp101__;
+	tmp101__ = 0U;
+	tmp101__ |= (pSrc->reserved << 0);
+	tmp101__ |= (pSrc->initiator << 11);
+	tmp101__ |= (pSrc->tid << 12);
+	frameshtons(pCtx, pBuf, tmp101__, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_delba_param_set. */
+
+void dot11f_pack_ff_ext_chan_switch_ann_action(tpAniSirGlobal pCtx,
+					       tDot11fFfext_chan_switch_ann_action *pSrc,
+					       uint8_t *pBuf)
+{
+	uint32_t tmp102__;
+	tmp102__ = 0U;
+	tmp102__ |= (pSrc->switch_mode << 0);
+	tmp102__ |= (pSrc->op_class << 8);
+	tmp102__ |= (pSrc->new_channel << 16);
+	tmp102__ |= (pSrc->switch_count << 24);
+	frameshtonl(pCtx, pBuf, tmp102__, 0);
+	(void)pCtx;
+} /* End dot11f_pack_ff_ext_chan_switch_ann_action. */
+
+void dot11f_pack_ff_p2p_action_oui(tpAniSirGlobal pCtx,
+				   tDot11fFfp2p_action_oui *pSrc,
+				   uint8_t *pBuf)
+{
+	DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui_data, 4);
+	(void)pCtx;
+} /* End dot11f_pack_ff_p2p_action_oui. */
+
+void dot11f_pack_ff_p2p_action_subtype(tpAniSirGlobal pCtx,
+				       tDot11fFfp2p_action_subtype *pSrc,
+				       uint8_t *pBuf)
+{
+	*pBuf = pSrc->subtype;
+	(void)pCtx;
+} /* End dot11f_pack_ff_p2p_action_subtype. */
+
+uint32_t dot11f_pack_tlv_authorized_ma_cs(tpAniSirGlobal pCtx,
+					tDot11fTLVAuthorizedMACs *pSrc,
+					uint8_t *pBuf,
+					uint32_t nBuf,
+					uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 8;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 1;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->mac, 6);
+		*pnConsumed += 6;
+		pBuf += 6;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_authorized_ma_cs. */
+
+uint32_t dot11f_pack_tlv_request_to_enroll(tpAniSirGlobal pCtx,
+					 tDot11fTLVRequestToEnroll *pSrc,
+					 uint8_t *pBuf,
+					 uint32_t nBuf,
+					 uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 3;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 3;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		*pBuf = pSrc->req;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_request_to_enroll. */
+
+uint32_t dot11f_pack_tlv_version2(tpAniSirGlobal pCtx,
+				  tDot11fTLVVersion2 *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp103__;
+	nNeeded += 3;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 0;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		tmp103__ = 0U;
+		tmp103__ |= (pSrc->minor << 0);
+		tmp103__ |= (pSrc->major << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp103__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_version2. */
+
+uint32_t dot11f_pack_tlv_ap_setup_locked(tpAniSirGlobal pCtx,
+				       tDot11fTLVAPSetupLocked *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 5;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4183, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		*pBuf = pSrc->fLocked;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_ap_setup_locked. */
+
+uint32_t dot11f_pack_tlv_association_state(tpAniSirGlobal pCtx,
+					  tDot11fTLVAssociationState *pSrc,
+					  uint8_t *pBuf,
+					  uint32_t nBuf,
+					  uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 6;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4098, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		frameshtons(pCtx, pBuf, pSrc->state, 1);
+		*pnConsumed += 2;
+		pBuf += 2;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_association_state. */
+
+uint32_t dot11f_pack_tlv_config_methods(tpAniSirGlobal pCtx,
+				       tDot11fTLVConfigMethods *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 6;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4104, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		frameshtons(pCtx, pBuf, pSrc->methods, 1);
+		*pnConsumed += 2;
+		pBuf += 2;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_config_methods. */
+
+uint32_t dot11f_pack_tlv_configuration_error(tpAniSirGlobal pCtx,
+					    tDot11fTLVConfigurationError *pSrc,
+					    uint8_t *pBuf,
+					    uint32_t nBuf,
+					    uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 6;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4105, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		frameshtons(pCtx, pBuf, pSrc->error, 1);
+		*pnConsumed += 2;
+		pBuf += 2;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_configuration_error. */
+
+uint32_t dot11f_pack_tlv_device_name(tpAniSirGlobal pCtx,
+				    tDot11fTLVDeviceName *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += (pSrc->num_text + 4) ;
+
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4113, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->text), pSrc->num_text);
+		*pnConsumed += pSrc->num_text;
+		pBuf += pSrc->num_text;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_device_name. */
+
+uint32_t dot11f_pack_tlv_device_password_id(tpAniSirGlobal pCtx,
+					  tDot11fTLVDevicePasswordID *pSrc,
+					  uint8_t *pBuf,
+					  uint32_t nBuf,
+					  uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 6;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4114, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		frameshtons(pCtx, pBuf, pSrc->id, 1);
+		*pnConsumed += 2;
+		pBuf += 2;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_device_password_id. */
+
+uint32_t dot11f_pack_tlv_extended_listen_timing(tpAniSirGlobal pCtx,
+					      tDot11fTLVExtendedListenTiming *pSrc,
+					      uint8_t *pBuf,
+					      uint32_t nBuf,
+					      uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 7;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 8;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		frameshtons(pCtx, pBuf, pSrc->availibilityPeriod, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->availibilityInterval, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_extended_listen_timing. */
+
+uint32_t dot11f_pack_tlv_listen_channel(tpAniSirGlobal pCtx,
+				       tDot11fTLVListenChannel *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 8;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 6;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryString, 3);
+		*pnConsumed += 3;
+		pBuf += 3;
+		*pBuf = pSrc->regulatoryClass;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->channel;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_listen_channel. */
+
+uint32_t dot11f_pack_tlv_manufacturer(tpAniSirGlobal pCtx,
+				      tDot11fTLVManufacturer *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += (pSrc->num_name + 4) ;
+
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4129, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->name), pSrc->num_name);
+		*pnConsumed += pSrc->num_name;
+		pBuf += pSrc->num_name;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_manufacturer. */
+
+uint32_t dot11f_pack_tlv_minor_reason_code(tpAniSirGlobal pCtx,
+					 tDot11fTLVMinorReasonCode *pSrc,
+					 uint8_t *pBuf,
+					 uint32_t nBuf,
+					 uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 4;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 1;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		*pBuf = pSrc->minorReasonCode;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_minor_reason_code. */
+
+uint32_t dot11f_pack_tlv_model_name(tpAniSirGlobal pCtx,
+				   tDot11fTLVModelName *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += (pSrc->num_text + 4) ;
+
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4131, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->text), pSrc->num_text);
+		*pnConsumed += pSrc->num_text;
+		pBuf += pSrc->num_text;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_model_name. */
+
+uint32_t dot11f_pack_tlv_model_number(tpAniSirGlobal pCtx,
+				     tDot11fTLVModelNumber *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += (pSrc->num_text + 4) ;
+
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4132, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->text), pSrc->num_text);
+		*pnConsumed += pSrc->num_text;
+		pBuf += pSrc->num_text;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_model_number. */
+
+uint32_t dot11f_pack_tlv_notice_of_absence(tpAniSirGlobal pCtx,
+					 tDot11fTLVNoticeOfAbsence *pSrc,
+					 uint8_t *pBuf,
+					 uint32_t nBuf,
+					 uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += (pSrc->num_NoADesc + 5) ;
+
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 12;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		*pBuf = pSrc->index;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->CTSWindowOppPS;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->NoADesc), pSrc->num_NoADesc);
+		*pnConsumed += pSrc->num_NoADesc;
+		pBuf += pSrc->num_NoADesc;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_notice_of_absence. */
+
+uint32_t dot11f_pack_tlv_operating_channel(tpAniSirGlobal pCtx,
+					  tDot11fTLVOperatingChannel *pSrc,
+					  uint8_t *pBuf,
+					  uint32_t nBuf,
+					  uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 8;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 17;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryString, 3);
+		*pnConsumed += 3;
+		pBuf += 3;
+		*pBuf = pSrc->regulatoryClass;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->channel;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_operating_channel. */
+
+uint32_t dot11f_pack_tlv_p2_p_capability(tpAniSirGlobal pCtx,
+				       tDot11fTLVP2PCapability *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 5;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 2;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		*pBuf = pSrc->deviceCapability;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->groupCapability;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_capability. */
+
+uint32_t dot11f_pack_tlv_p2_p_device_id(tpAniSirGlobal pCtx,
+				     tDot11fTLVP2PDeviceId *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 9;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 3;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6);
+		*pnConsumed += 6;
+		pBuf += 6;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_device_id. */
+
+uint32_t dot11f_pack_tlv_p2_p_device_info(tpAniSirGlobal pCtx,
+				       tDot11fTLVP2PDeviceInfo *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	uint32_t idx = 0;
+	nNeeded += 19;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 13;
+		pBuf += 1; nBuf -= 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; nBuf -= 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6);
+		*pnConsumed += 6;
+		pBuf += 6;
+		frameshtons(pCtx, pBuf, pSrc->configMethod, 1);
+		*pnConsumed += 2;
+		pBuf += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->primaryDeviceType, 8);
+		*pnConsumed += 8;
+		pBuf += 8;
+		status |= pack_tlv_core(pCtx,
+				(uint8_t *)pSrc,
+				pBuf,
+				nBuf,
+				pnConsumed,
+				TLVS_P2PDeviceInfo, &idx);
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return status;
+} /* End dot11f_pack_tlv_p2_p_device_info. */
+
+uint32_t dot11f_pack_tlv_p2_p_group_info(tpAniSirGlobal pCtx,
+				      tDot11fTLVP2PGroupInfo *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += (pSrc->num_P2PClientInfoDesc + 3) ;
+
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 14;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->P2PClientInfoDesc), pSrc->num_P2PClientInfoDesc);
+		*pnConsumed += pSrc->num_P2PClientInfoDesc;
+		pBuf += pSrc->num_P2PClientInfoDesc;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_group_info. */
+
+uint32_t dot11f_pack_tlv_p2_p_status(tpAniSirGlobal pCtx,
+				   tDot11fTLVP2PStatus *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 4;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 0;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		*pBuf = pSrc->status;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_status. */
+
+uint32_t dot11f_pack_tlv_primary_device_type(tpAniSirGlobal pCtx,
+					   tDot11fTLVPrimaryDeviceType *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 12;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4180, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		frameshtons(pCtx, pBuf, pSrc->primary_category, 1);
+		*pnConsumed += 2;
+		pBuf += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui, 4);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtons(pCtx, pBuf, pSrc->sub_category, 1);
+		*pnConsumed += 2;
+		pBuf += 2;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_primary_device_type. */
+
+uint32_t dot11f_pack_tlv_rf_bands(tpAniSirGlobal pCtx,
+				 tDot11fTLVRFBands *pSrc,
+				 uint8_t *pBuf,
+				 uint32_t nBuf,
+				 uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 5;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4156, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		*pBuf = pSrc->bands;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_rf_bands. */
+
+uint32_t dot11f_pack_tlv_request_device_type(tpAniSirGlobal pCtx,
+					   tDot11fTLVRequestDeviceType *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 12;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4202, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		frameshtons(pCtx, pBuf, pSrc->primary_category, 1);
+		*pnConsumed += 2;
+		pBuf += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui, 4);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtons(pCtx, pBuf, pSrc->sub_category, 1);
+		*pnConsumed += 2;
+		pBuf += 2;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_request_device_type. */
+
+uint32_t dot11f_pack_tlv_request_type(tpAniSirGlobal pCtx,
+				     tDot11fTLVRequestType *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 5;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4154, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		*pBuf = pSrc->reqType;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_request_type. */
+
+uint32_t dot11f_pack_tlv_response_type(tpAniSirGlobal pCtx,
+				      tDot11fTLVResponseType *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 5;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4155, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		*pBuf = pSrc->resType;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_response_type. */
+
+uint32_t dot11f_pack_tlv_selected_registrar(tpAniSirGlobal pCtx,
+					   tDot11fTLVSelectedRegistrar *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 5;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4161, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		*pBuf = pSrc->selected;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_selected_registrar. */
+
+uint32_t dot11f_pack_tlv_selected_registrar_config_methods(tpAniSirGlobal pCtx,
+							tDot11fTLVSelectedRegistrarConfigMethods *pSrc,
+							uint8_t *pBuf,
+							uint32_t nBuf,
+							uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 6;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4179, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		frameshtons(pCtx, pBuf, pSrc->methods, 1);
+		*pnConsumed += 2;
+		pBuf += 2;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_selected_registrar_config_methods. */
+
+uint32_t dot11f_pack_tlv_serial_number(tpAniSirGlobal pCtx,
+				      tDot11fTLVSerialNumber *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += (pSrc->num_text + 4) ;
+
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4162, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->text), pSrc->num_text);
+		*pnConsumed += pSrc->num_text;
+		pBuf += pSrc->num_text;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_serial_number. */
+
+uint32_t dot11f_pack_tlv_uuid_e(tpAniSirGlobal pCtx,
+				tDot11fTLVUUID_E *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 20;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4167, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->uuid, 16);
+		*pnConsumed += 16;
+		pBuf += 16;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_uuid_e. */
+
+uint32_t dot11f_pack_tlv_uuid_r(tpAniSirGlobal pCtx,
+				tDot11fTLVUUID_R *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 20;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4168, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->uuid, 16);
+		*pnConsumed += 16;
+		pBuf += 16;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_uuid_r. */
+
+uint32_t dot11f_pack_tlv_vendor_extension(tpAniSirGlobal pCtx,
+					 tDot11fTLVVendorExtension *pSrc,
+					 uint8_t *pBuf,
+					 uint32_t nBuf,
+					 uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	uint32_t idx = 0;
+	nNeeded += 7;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4169, 1);
+		pBuf += 2; nBuf -= 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; nBuf -= 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->vendorId, 3);
+		*pnConsumed += 3;
+		pBuf += 3;
+		status |= pack_tlv_core(pCtx,
+				(uint8_t *)pSrc,
+				pBuf,
+				nBuf,
+				pnConsumed,
+				TLVS_VendorExtension, &idx);
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return status;
+} /* End dot11f_pack_tlv_vendor_extension. */
+
+uint32_t dot11f_pack_tlv_version(tpAniSirGlobal pCtx,
+				 tDot11fTLVVersion *pSrc,
+				 uint8_t *pBuf,
+				 uint32_t nBuf,
+				 uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp104__;
+	nNeeded += 5;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4170, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		tmp104__ = 0U;
+		tmp104__ |= (pSrc->minor << 0);
+		tmp104__ |= (pSrc->major << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp104__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_version. */
+
+uint32_t dot11f_pack_tlv_wps_state(tpAniSirGlobal pCtx,
+				  tDot11fTLVWPSState *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 5;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		frameshtons(pCtx, pBuf, 4164, 1);
+		pBuf += 2; *pnConsumed += 2;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		*pBuf = pSrc->state;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_wps_state. */
+
+uint32_t dot11f_pack_tlv_assoc_disallowed(tpAniSirGlobal pCtx,
+					  tDot11fTLVassoc_disallowed *pSrc,
+					  uint8_t *pBuf,
+					  uint32_t nBuf,
+					  uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 3;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 4;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		*pBuf = pSrc->reason_code;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_assoc_disallowed. */
+
+uint32_t dot11f_pack_tlv_assoc_retry_delay(tpAniSirGlobal pCtx,
+					   tDot11fTLVassoc_retry_delay *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 4;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 8;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		frameshtons(pCtx, pBuf, pSrc->delay, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_assoc_retry_delay. */
+
+uint32_t dot11f_pack_tlv_cellular_data_cap(tpAniSirGlobal pCtx,
+					   tDot11fTLVcellular_data_cap *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 3;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 3;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		*pBuf = pSrc->cellular_connectivity;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_cellular_data_cap. */
+
+uint32_t dot11f_pack_tlv_cellular_data_con_pref(tpAniSirGlobal pCtx,
+						tDot11fTLVcellular_data_con_pref *pSrc,
+						uint8_t *pBuf,
+						uint32_t nBuf,
+						uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 3;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 5;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		*pBuf = pSrc->cellular_preference;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_cellular_data_con_pref. */
+
+uint32_t dot11f_pack_tlv_mbo_ap_cap(tpAniSirGlobal pCtx,
+				    tDot11fTLVmbo_ap_cap *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 3;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 1;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		*pBuf = pSrc->mbo_cap_ind;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_mbo_ap_cap. */
+
+uint32_t dot11f_pack_tlv_non_prefferd_chan_rep(tpAniSirGlobal pCtx,
+					       tDot11fTLVnon_prefferd_chan_rep *pSrc,
+					       uint8_t *pBuf,
+					       uint32_t nBuf,
+					       uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += (pSrc->num_channel_report + 3) ;
+
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 2;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		*pBuf = pSrc->oper_class;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->channel_report), pSrc->num_channel_report);
+		*pnConsumed += pSrc->num_channel_report;
+		pBuf += pSrc->num_channel_report;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_non_prefferd_chan_rep. */
+
+uint32_t dot11f_pack_tlv_oce_cap(tpAniSirGlobal pCtx,
+				 tDot11fTLVoce_cap *pSrc,
+				 uint8_t *pBuf,
+				 uint32_t nBuf,
+				 uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp105__;
+	nNeeded += 3;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 101;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		tmp105__ = 0U;
+		tmp105__ |= (pSrc->oce_release << 0);
+		tmp105__ |= (pSrc->is_sta_cfon << 3);
+		tmp105__ |= (pSrc->non_oce_ap_present << 4);
+		tmp105__ |= (pSrc->reserved << 5);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp105__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_oce_cap. */
+
+uint32_t dot11f_pack_tlv_reduced_wan_metrics(tpAniSirGlobal pCtx,
+					     tDot11fTLVreduced_wan_metrics *pSrc,
+					     uint8_t *pBuf,
+					     uint32_t nBuf,
+					     uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp106__;
+	nNeeded += 3;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 103;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		tmp106__ = 0U;
+		tmp106__ |= (pSrc->downlink_av_cap << 0);
+		tmp106__ |= (pSrc->uplink_av_cap << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp106__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_reduced_wan_metrics. */
+
+uint32_t dot11f_pack_tlv_rssi_assoc_rej(tpAniSirGlobal pCtx,
+					tDot11fTLVrssi_assoc_rej *pSrc,
+					uint8_t *pBuf,
+					uint32_t nBuf,
+					uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 4;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 102;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		*pBuf = pSrc->delta_rssi;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->retry_delay;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_rssi_assoc_rej. */
+
+uint32_t dot11f_pack_tlv_transition_reason(tpAniSirGlobal pCtx,
+					   tDot11fTLVtransition_reason *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 3;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 6;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		*pBuf = pSrc->transition_reason_code;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_transition_reason. */
+
+uint32_t dot11f_pack_tlv_transition_reject_reason(tpAniSirGlobal pCtx,
+						  tDot11fTLVtransition_reject_reason *pSrc,
+						  uint8_t *pBuf,
+						  uint32_t nBuf,
+						  uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 3;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 7;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 1; *pnConsumed += 1;
+		*pBuf = pSrc->transition_reject_code;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		*pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_transition_reject_reason. */
+
+uint32_t dot11f_pack_tlv_p2_p_interface(tpAniSirGlobal pCtx,
+				      tDot11fTLVP2PInterface *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 9;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 16;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6);
+		*pnConsumed += 6;
+		pBuf += 6;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_interface. */
+
+uint32_t dot11f_pack_tlv_p2_p_manageability(tpAniSirGlobal pCtx,
+					  tDot11fTLVP2PManageability *pSrc,
+					  uint8_t *pBuf,
+					  uint32_t nBuf,
+					  uint32_t *pnConsumed)
+{
+	uint8_t *pTlvLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded += 4;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	while (pSrc->present) {
+		*pBuf = 10;
+		pBuf += 1; *pnConsumed += 1;
+		pTlvLen = pBuf;
+		pBuf += 2; *pnConsumed += 2;
+		*pBuf = pSrc->manageability;
+		*pnConsumed += 1;
+		pBuf += 1;
+		break;
+	}
+	(void)pCtx;
+	if (pTlvLen) {
+		frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_manageability. */
+
+uint32_t dot11f_pack_ie_gtk(tpAniSirGlobal pCtx,
+			    tDot11fIEGTK *pSrc,
+			    uint8_t *pBuf,
+			    uint32_t nBuf,
+			    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint16_t tmp107__;
+	nNeeded  +=  (pSrc->num_key + 11);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 2;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp107__ = 0U;
+		tmp107__ |= (pSrc->keyId << 0);
+		tmp107__ |= (pSrc->reserved << 2);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp107__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		*pBuf = pSrc->keyLength;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->RSC, 8);
+		*pnConsumed += 8;
+		pBuf += 8;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->key), pSrc->num_key);
+		*pnConsumed += pSrc->num_key;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_gtk. */
+
+uint32_t dot11f_pack_ie_igtk(tpAniSirGlobal pCtx,
+			     tDot11fIEIGTK *pSrc,
+			     uint8_t *pBuf,
+			     uint32_t nBuf,
+			     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 33;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 4;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->keyID, 2);
+		*pnConsumed += 2;
+		pBuf += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->IPN, 6);
+		*pnConsumed += 6;
+		pBuf += 6;
+		*pBuf = pSrc->keyLength;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->key, 24);
+		*pnConsumed += 24;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_igtk. */
+
+uint32_t dot11f_pack_ie_r0_kh_id(tpAniSirGlobal pCtx,
+				tDot11fIER0KH_ID *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_PMK_R0_ID;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 3;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->PMK_R0_ID), pSrc->num_PMK_R0_ID);
+		*pnConsumed += pSrc->num_PMK_R0_ID;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_r0_kh_id. */
+
+uint32_t dot11f_pack_ie_r1_kh_id(tpAniSirGlobal pCtx,
+				tDot11fIER1KH_ID *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 6;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 1;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->PMK_R1_ID, 6);
+		*pnConsumed += 6;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_r1_kh_id. */
+
+uint32_t dot11f_pack_ie_ap_channel_report(tpAniSirGlobal pCtx,
+					tDot11fIEAPChannelReport *pSrc,
+					uint8_t *pBuf,
+					uint32_t nBuf,
+					uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_channelList + 1);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 51;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->regulatoryClass;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->channelList), pSrc->num_channelList);
+		*pnConsumed += pSrc->num_channelList;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ap_channel_report. */
+
+uint32_t dot11f_pack_ie_bcn_reporting_detail(tpAniSirGlobal pCtx,
+					   tDot11fIEBcnReportingDetail *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 2;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->reportingDetail;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_bcn_reporting_detail. */
+
+uint32_t dot11f_pack_ie_beacon_report_frm_body(tpAniSirGlobal pCtx,
+					    tDot11fIEBeaconReportFrmBody *pSrc,
+					    uint8_t *pBuf,
+					    uint32_t nBuf,
+					    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_reportedFields;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 1;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->reportedFields), pSrc->num_reportedFields);
+		*pnConsumed += pSrc->num_reportedFields;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_beacon_report_frm_body. */
+
+uint32_t dot11f_pack_ie_beacon_reporting(tpAniSirGlobal pCtx,
+					tDot11fIEBeaconReporting *pSrc,
+					uint8_t *pBuf,
+					uint32_t nBuf,
+					uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 1;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->reportingCondition;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->threshold;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_beacon_reporting. */
+
+uint32_t dot11f_pack_ie_condensed_country_str(tpAniSirGlobal pCtx,
+					    tDot11fIECondensedCountryStr *pSrc,
+					    uint8_t *pBuf,
+					    uint32_t nBuf,
+					    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 2;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryStr, 2);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_condensed_country_str. */
+
+uint32_t dot11f_pack_ie_measurement_pilot(tpAniSirGlobal pCtx,
+					 tDot11fIEMeasurementPilot *pSrc,
+					 uint8_t *pBuf,
+					 uint32_t nBuf,
+					 uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_vendorSpecific + 1);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 66;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->measurementPilot;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->vendorSpecific), pSrc->num_vendorSpecific);
+		*pnConsumed += pSrc->num_vendorSpecific;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_measurement_pilot. */
+
+uint32_t dot11f_pack_ie_multi_bssid(tpAniSirGlobal pCtx,
+				   tDot11fIEMultiBssid *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_vendorSpecific + 1);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 71;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->maxBSSIDIndicator;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->vendorSpecific), pSrc->num_vendorSpecific);
+		*pnConsumed += pSrc->num_vendorSpecific;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_multi_bssid. */
+
+uint32_t dot11f_pack_ie_ric_data(tpAniSirGlobal pCtx,
+				tDot11fIERICData *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 4;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 57;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->Identifier;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->resourceDescCount;
+		*pnConsumed += 1;
+		pBuf += 1;
+		frameshtons(pCtx, pBuf, pSrc->statusCode, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ric_data. */
+
+uint32_t dot11f_pack_ie_ric_descriptor(tpAniSirGlobal pCtx,
+				      tDot11fIERICDescriptor *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_variableData + 1);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 75;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->resourceType;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->variableData), pSrc->num_variableData);
+		*pnConsumed += pSrc->num_variableData;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ric_descriptor. */
+
+uint32_t dot11f_pack_ie_rrm_enabled_cap(tpAniSirGlobal pCtx,
+				      tDot11fIERRMEnabledCap *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp108__;
+	uint8_t tmp109__;
+	uint8_t tmp110__;
+	uint8_t tmp111__;
+	uint8_t tmp112__;
+	nNeeded  += 5;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 70;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp108__ = 0U;
+		tmp108__ |= (pSrc->LinkMeasurement << 0);
+		tmp108__ |= (pSrc->NeighborRpt << 1);
+		tmp108__ |= (pSrc->parallel << 2);
+		tmp108__ |= (pSrc->repeated << 3);
+		tmp108__ |= (pSrc->BeaconPassive << 4);
+		tmp108__ |= (pSrc->BeaconActive << 5);
+		tmp108__ |= (pSrc->BeaconTable << 6);
+		tmp108__ |= (pSrc->BeaconRepCond << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp108__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp109__ = 0U;
+		tmp109__ |= (pSrc->FrameMeasurement << 0);
+		tmp109__ |= (pSrc->ChannelLoad << 1);
+		tmp109__ |= (pSrc->NoiseHistogram << 2);
+		tmp109__ |= (pSrc->statistics << 3);
+		tmp109__ |= (pSrc->LCIMeasurement << 4);
+		tmp109__ |= (pSrc->LCIAzimuth << 5);
+		tmp109__ |= (pSrc->TCMCapability << 6);
+		tmp109__ |= (pSrc->triggeredTCM << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp109__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp110__ = 0U;
+		tmp110__ |= (pSrc->APChanReport << 0);
+		tmp110__ |= (pSrc->RRMMIBEnabled << 1);
+		tmp110__ |= (pSrc->operatingChanMax << 2);
+		tmp110__ |= (pSrc->nonOperatinChanMax << 5);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp110__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp111__ = 0U;
+		tmp111__ |= (pSrc->MeasurementPilot << 0);
+		tmp111__ |= (pSrc->MeasurementPilotEnabled << 3);
+		tmp111__ |= (pSrc->NeighborTSFOffset << 4);
+		tmp111__ |= (pSrc->RCPIMeasurement << 5);
+		tmp111__ |= (pSrc->RSNIMeasurement << 6);
+		tmp111__ |= (pSrc->BssAvgAccessDelay << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp111__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp112__ = 0U;
+		tmp112__ |= (pSrc->BSSAvailAdmission << 0);
+		tmp112__ |= (pSrc->AntennaInformation << 1);
+		tmp112__ |= (pSrc->fine_time_meas_rpt << 2);
+		tmp112__ |= (pSrc->lci_capability << 3);
+		tmp112__ |= (pSrc->reserved << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp112__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_rrm_enabled_cap. */
+
+uint32_t dot11f_pack_ie_requested_info(tpAniSirGlobal pCtx,
+				      tDot11fIERequestedInfo *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_requested_eids;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 10;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->requested_eids), pSrc->num_requested_eids);
+		*pnConsumed += pSrc->num_requested_eids;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_requested_info. */
+
+uint32_t dot11f_pack_ie_ssid(tpAniSirGlobal pCtx,
+			     tDot11fIESSID *pSrc,
+			     uint8_t *pBuf,
+			     uint32_t nBuf,
+			     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_ssid;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 0;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->ssid), pSrc->num_ssid);
+		*pnConsumed += pSrc->num_ssid;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ssid. */
+
+uint32_t dot11f_pack_ie_schedule(tpAniSirGlobal pCtx,
+				 tDot11fIESchedule *pSrc,
+				 uint8_t *pBuf,
+				 uint32_t nBuf,
+				 uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint16_t tmp113__;
+	nNeeded  += 14;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 15;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp113__ = 0U;
+		tmp113__ |= (pSrc->aggregation << 0);
+		tmp113__ |= (pSrc->tsid << 1);
+		tmp113__ |= (pSrc->direction << 5);
+		tmp113__ |= (pSrc->reserved << 7);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp113__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->service_interval, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtons(pCtx, pBuf, pSrc->max_service_dur, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->spec_interval, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_schedule. */
+
+uint32_t dot11f_pack_ie_tclas(tpAniSirGlobal pCtx,
+			      tDot11fIETCLAS *pSrc,
+			      uint8_t *pBuf,
+			      uint32_t nBuf,
+			      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ietclas(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 14;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->user_priority;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->classifier_type;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->classifier_mask;
+		*pnConsumed += 1;
+		pBuf += 1;
+		switch (pSrc->classifier_type) {
+		case 0:
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.source, 6);
+			*pnConsumed += 6;
+			pBuf += 6;
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.dest, 6);
+			*pnConsumed += 6;
+			pBuf += 6;
+			frameshtons(pCtx, pBuf, pSrc->info.EthParams.type, 0);
+			*pnConsumed += 2;
+			/* fieldsEndFlag = 1 */
+			break;
+		case 1:
+			*pBuf = pSrc->info.IpParams.version;
+			*pnConsumed += 1;
+			pBuf += 1;
+			switch (pSrc->info.IpParams.version) {
+			case 4:
+				DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.source, 4);
+				*pnConsumed += 4;
+				pBuf += 4;
+				DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest, 4);
+				*pnConsumed += 4;
+				pBuf += 4;
+				frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.src_port, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest_port, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				*pBuf = pSrc->info.IpParams.params.IpV4Params.DSCP;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->info.IpParams.params.IpV4Params.proto;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->info.IpParams.params.IpV4Params.reserved;
+				*pnConsumed += 1;
+				/* fieldsEndFlag = 1 */
+				break;
+			case 6:
+				DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.source, 16);
+				*pnConsumed += 16;
+				pBuf += 16;
+				DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest, 16);
+				*pnConsumed += 16;
+				pBuf += 16;
+				frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.src_port, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest_port, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.flow_label, 3);
+				*pnConsumed += 3;
+				/* fieldsEndFlag = 1 */
+				break;
+			}
+			break;
+		case 2:
+			frameshtons(pCtx, pBuf, pSrc->info.Params8021dq.tag_type, 0);
+			*pnConsumed += 2;
+			/* fieldsEndFlag = 1 */
+			break;
+		}
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_tclas. */
+
+uint32_t dot11f_pack_ie_tclassproc(tpAniSirGlobal pCtx,
+				   tDot11fIETCLASSPROC *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 44;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->processing;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tclassproc. */
+
+uint32_t dot11f_pack_ie_ts_delay(tpAniSirGlobal pCtx,
+				tDot11fIETSDelay *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 4;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 43;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		frameshtonl(pCtx, pBuf, pSrc->delay, 0);
+		*pnConsumed += 4;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ts_delay. */
+
+uint32_t dot11f_pack_ie_tsf_info(tpAniSirGlobal pCtx,
+				tDot11fIETSFInfo *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 4;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 1;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		frameshtons(pCtx, pBuf, pSrc->TsfOffset, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->BeaconIntvl, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tsf_info. */
+
+uint32_t dot11f_pack_ie_tspec(tpAniSirGlobal pCtx,
+			      tDot11fIETSPEC *pSrc,
+			      uint8_t *pBuf,
+			      uint32_t nBuf,
+			      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint16_t tmp114__;
+	uint8_t tmp115__;
+	uint16_t tmp116__;
+	nNeeded  += 55;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 13;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp114__ = 0U;
+		tmp114__ |= (pSrc->traffic_type << 0);
+		tmp114__ |= (pSrc->tsid << 1);
+		tmp114__ |= (pSrc->direction << 5);
+		tmp114__ |= (pSrc->access_policy << 7);
+		tmp114__ |= (pSrc->aggregation << 9);
+		tmp114__ |= (pSrc->psb << 10);
+		tmp114__ |= (pSrc->user_priority << 11);
+		tmp114__ |= (pSrc->tsinfo_ack_pol << 14);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp114__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		tmp115__ = 0U;
+		tmp115__ |= (pSrc->schedule << 0);
+		tmp115__ |= (pSrc->unused << 1);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp115__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp116__ = 0U;
+		tmp116__ |= (pSrc->size << 0);
+		tmp116__ |= (pSrc->fixed << 15);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp116__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		frameshtons(pCtx, pBuf, pSrc->max_msdu_size, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtonl(pCtx, pBuf, pSrc->min_service_int, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->max_service_int, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->inactivity_int, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->suspension_int, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->min_data_rate, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->mean_data_rate, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->peak_data_rate, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->burst_size, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->delay_bound, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->min_phy_rate, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtons(pCtx, pBuf, pSrc->surplus_bw_allowance, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->medium_time, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tspec. */
+
+uint32_t dot11f_pack_ie_vht_caps(tpAniSirGlobal pCtx,
+				tDot11fIEVHTCaps *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint32_t tmp117__;
+	uint16_t tmp118__;
+	uint16_t tmp119__;
+	nNeeded  += 12;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 191;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp117__ = 0U;
+		tmp117__ |= (pSrc->maxMPDULen << 0);
+		tmp117__ |= (pSrc->supportedChannelWidthSet << 2);
+		tmp117__ |= (pSrc->ldpcCodingCap << 4);
+		tmp117__ |= (pSrc->shortGI80MHz << 5);
+		tmp117__ |= (pSrc->shortGI160and80plus80MHz << 6);
+		tmp117__ |= (pSrc->txSTBC << 7);
+		tmp117__ |= (pSrc->rxSTBC << 8);
+		tmp117__ |= (pSrc->suBeamFormerCap << 11);
+		tmp117__ |= (pSrc->suBeamformeeCap << 12);
+		tmp117__ |= (pSrc->csnofBeamformerAntSup << 13);
+		tmp117__ |= (pSrc->numSoundingDim << 16);
+		tmp117__ |= (pSrc->muBeamformerCap << 19);
+		tmp117__ |= (pSrc->muBeamformeeCap << 20);
+		tmp117__ |= (pSrc->vhtTXOPPS << 21);
+		tmp117__ |= (pSrc->htcVHTCap << 22);
+		tmp117__ |= (pSrc->maxAMPDULenExp << 23);
+		tmp117__ |= (pSrc->vhtLinkAdaptCap << 26);
+		tmp117__ |= (pSrc->rxAntPattern << 28);
+		tmp117__ |= (pSrc->txAntPattern << 29);
+		tmp117__ |= (pSrc->reserved1 << 30);
+		if (unlikely(nBuf < 4))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtonl(pCtx, pBuf, tmp117__, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		nBuf -=  4 ;
+		frameshtons(pCtx, pBuf, pSrc->rxMCSMap, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		tmp118__ = 0U;
+		tmp118__ |= (pSrc->rxHighSupDataRate << 0);
+		tmp118__ |= (pSrc->reserved2 << 13);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp118__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		frameshtons(pCtx, pBuf, pSrc->txMCSMap, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		tmp119__ = 0U;
+		tmp119__ |= (pSrc->txSupDataRate << 0);
+		tmp119__ |= (pSrc->reserved3 << 13);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp119__, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  2 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_vht_caps. */
+
+uint32_t dot11f_pack_ie_vht_operation(tpAniSirGlobal pCtx,
+				     tDot11fIEVHTOperation *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 5;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 192;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->chanWidth;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->chanCenterFreqSeg1;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->chanCenterFreqSeg2;
+		*pnConsumed += 1;
+		pBuf += 1;
+		frameshtons(pCtx, pBuf, pSrc->basicMCSSet, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_vht_operation. */
+
+uint32_t dot11f_pack_ie_wmm_schedule(tpAniSirGlobal pCtx,
+				    tDot11fIEWMMSchedule *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint16_t tmp120__;
+	nNeeded  += 15;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x9;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->version;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp120__ = 0U;
+		tmp120__ |= (pSrc->aggregation << 0);
+		tmp120__ |= (pSrc->tsid << 1);
+		tmp120__ |= (pSrc->direction << 5);
+		tmp120__ |= (pSrc->reserved << 7);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp120__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->service_interval, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtons(pCtx, pBuf, pSrc->max_service_dur, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->spec_interval, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmm_schedule. */
+
+uint32_t dot11f_pack_ie_wmmtclas(tpAniSirGlobal pCtx,
+				 tDot11fIEWMMTCLAS *pSrc,
+				 uint8_t *pBuf,
+				 uint32_t nBuf,
+				 uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_iewmmtclas(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x6;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->version;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->user_priority;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->classifier_type;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->classifier_mask;
+		*pnConsumed += 1;
+		pBuf += 1;
+		switch (pSrc->classifier_type) {
+		case 0:
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.source, 6);
+			*pnConsumed += 6;
+			pBuf += 6;
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.dest, 6);
+			*pnConsumed += 6;
+			pBuf += 6;
+			frameshtons(pCtx, pBuf, pSrc->info.EthParams.type, 0);
+			*pnConsumed += 2;
+			/* fieldsEndFlag = 1 */
+			break;
+		case 1:
+			*pBuf = pSrc->info.IpParams.version;
+			*pnConsumed += 1;
+			pBuf += 1;
+			switch (pSrc->info.IpParams.version) {
+			case 4:
+				DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.source, 4);
+				*pnConsumed += 4;
+				pBuf += 4;
+				DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest, 4);
+				*pnConsumed += 4;
+				pBuf += 4;
+				frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.src_port, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest_port, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				*pBuf = pSrc->info.IpParams.params.IpV4Params.DSCP;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->info.IpParams.params.IpV4Params.proto;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->info.IpParams.params.IpV4Params.reserved;
+				*pnConsumed += 1;
+				/* fieldsEndFlag = 1 */
+				break;
+			case 6:
+				DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.source, 10);
+				*pnConsumed += 10;
+				pBuf += 10;
+				DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest, 10);
+				*pnConsumed += 10;
+				pBuf += 10;
+				frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.src_port, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest_port, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.flow_label, 3);
+				*pnConsumed += 3;
+				/* fieldsEndFlag = 1 */
+				break;
+			}
+			break;
+		case 2:
+			frameshtons(pCtx, pBuf, pSrc->info.Params8021dq.tag_type, 0);
+			*pnConsumed += 2;
+			/* fieldsEndFlag = 1 */
+			break;
+		}
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_wmmtclas. */
+
+uint32_t dot11f_pack_ie_wmmtclasproc(tpAniSirGlobal pCtx,
+				     tDot11fIEWMMTCLASPROC *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x7;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->version;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->processing;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmmtclasproc. */
+
+uint32_t dot11f_pack_ie_wmmts_delay(tpAniSirGlobal pCtx,
+				   tDot11fIEWMMTSDelay *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 5;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x8;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->version;
+		*pnConsumed += 1;
+		pBuf += 1;
+		frameshtonl(pCtx, pBuf, pSrc->delay, 0);
+		*pnConsumed += 4;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmmts_delay. */
+
+uint32_t dot11f_pack_ie_wmmtspec(tpAniSirGlobal pCtx,
+				 tDot11fIEWMMTSPEC *pSrc,
+				 uint8_t *pBuf,
+				 uint32_t nBuf,
+				 uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint16_t tmp121__;
+	uint8_t tmp122__;
+	uint16_t tmp123__;
+	nNeeded  += 38;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->version;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp121__ = 0U;
+		tmp121__ |= (pSrc->traffic_type << 0);
+		tmp121__ |= (pSrc->tsid << 1);
+		tmp121__ |= (pSrc->direction << 5);
+		tmp121__ |= (pSrc->access_policy << 7);
+		tmp121__ |= (pSrc->aggregation << 9);
+		tmp121__ |= (pSrc->psb << 10);
+		tmp121__ |= (pSrc->user_priority << 11);
+		tmp121__ |= (pSrc->tsinfo_ack_pol << 14);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp121__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		tmp122__ = 0U;
+		tmp122__ |= (pSrc->tsinfo_rsvd << 0);
+		tmp122__ |= (pSrc->burst_size_defn << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp122__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp123__ = 0U;
+		tmp123__ |= (pSrc->size << 0);
+		tmp123__ |= (pSrc->fixed << 15);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp123__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		frameshtons(pCtx, pBuf, pSrc->max_msdu_size, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtonl(pCtx, pBuf, pSrc->min_service_int, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->max_service_int, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->inactivity_int, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->suspension_int, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->min_data_rate, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->mean_data_rate, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->peak_data_rate, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->burst_size, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->delay_bound, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtonl(pCtx, pBuf, pSrc->min_phy_rate, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		frameshtons(pCtx, pBuf, pSrc->surplus_bw_allowance, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->medium_time, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmmtspec. */
+
+uint32_t dot11f_pack_ie_wider_bw_chan_switch_ann(tpAniSirGlobal pCtx,
+					     tDot11fIEWiderBWChanSwitchAnn *pSrc,
+					     uint8_t *pBuf,
+					     uint32_t nBuf,
+					     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 3;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 194;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->newChanWidth;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->newCenterChanFreq0;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->newCenterChanFreq1;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wider_bw_chan_switch_ann. */
+
+uint32_t dot11f_pack_ie_azimuth_req(tpAniSirGlobal pCtx,
+				    tDot11fIEazimuth_req *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 1;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->request;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_azimuth_req. */
+
+uint32_t dot11f_pack_ie_beacon_report_frm_body_fragment_id(tpAniSirGlobal pCtx,
+							   tDot11fIEbeacon_report_frm_body_fragment_id *pSrc,
+							   uint8_t *pBuf,
+							   uint32_t nBuf,
+							   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint16_t tmp124__;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 2;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp124__ = 0U;
+		tmp124__ |= (pSrc->beacon_report_id << 0);
+		tmp124__ |= (pSrc->fragment_id_number << 8);
+		tmp124__ |= (pSrc->more_fragments << 15);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp124__, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  2 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_beacon_report_frm_body_fragment_id. */
+
+uint32_t dot11f_pack_ie_last_beacon_report_indication(tpAniSirGlobal pCtx,
+						      tDot11fIElast_beacon_report_indication *pSrc,
+						      uint8_t *pBuf,
+						      uint32_t nBuf,
+						      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 164;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->last_fragment;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_last_beacon_report_indication. */
+
+uint32_t dot11f_pack_ie_max_age(tpAniSirGlobal pCtx,
+				tDot11fIEmax_age *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 4;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		frameshtons(pCtx, pBuf, pSrc->max_age, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_max_age. */
+
+uint32_t dot11f_pack_ie_neighbor_rpt(tpAniSirGlobal pCtx,
+				     tDot11fIEneighbor_rpt *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp125__;
+	uint8_t tmp126__;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ie_neighbor_rpt(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 52;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6);
+		*pnConsumed += 6;
+		pBuf += 6;
+		tmp125__ = 0U;
+		tmp125__ |= (pSrc->APReachability << 0);
+		tmp125__ |= (pSrc->Security << 2);
+		tmp125__ |= (pSrc->KeyScope << 3);
+		tmp125__ |= (pSrc->SpecMgmtCap << 4);
+		tmp125__ |= (pSrc->QosCap << 5);
+		tmp125__ |= (pSrc->apsd << 6);
+		tmp125__ |= (pSrc->rrm << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp125__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp126__ = 0U;
+		tmp126__ |= (pSrc->DelayedBA << 0);
+		tmp126__ |= (pSrc->ImmBA << 1);
+		tmp126__ |= (pSrc->MobilityDomain << 2);
+		tmp126__ |= (pSrc->reserved << 3);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp126__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		frameshtons(pCtx, pBuf, pSrc->reserved1, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		*pBuf = pSrc->regulatoryClass;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->channel;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->PhyType;
+		*pnConsumed += 1;
+		pBuf += 1;
+		status = pack_core(pCtx,
+				(uint8_t *)pSrc,
+				pBuf,
+				nBuf,
+				pnConsumed,
+				FFS_neighbor_rpt,
+				IES_neighbor_rpt);
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_neighbor_rpt. */
+
+uint32_t dot11f_pack_ie_req_mac_addr(tpAniSirGlobal pCtx,
+				     tDot11fIEreq_mac_addr *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 6;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 2;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->addr, 6);
+		*pnConsumed += 6;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_req_mac_addr. */
+
+uint32_t dot11f_pack_ie_tgt_mac_addr(tpAniSirGlobal pCtx,
+				     tDot11fIEtgt_mac_addr *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 6;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 3;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->addr, 6);
+		*pnConsumed += 6;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tgt_mac_addr. */
+
+uint32_t dot11f_pack_ie_vht_transmit_power_env(tpAniSirGlobal pCtx,
+					       tDot11fIEvht_transmit_power_env *pSrc,
+					       uint8_t *pBuf,
+					       uint32_t nBuf,
+					       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_bytes;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 195;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->bytes), pSrc->num_bytes);
+		*pnConsumed += pSrc->num_bytes;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_vht_transmit_power_env. */
+
+uint32_t dot11f_pack_ie_aid(tpAniSirGlobal pCtx,
+			    tDot11fIEAID *pSrc,
+			    uint8_t *pBuf,
+			    uint32_t nBuf,
+			    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 197;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		frameshtons(pCtx, pBuf, pSrc->assocId, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_aid. */
+
+uint32_t dot11f_pack_ie_cf_params(tpAniSirGlobal pCtx,
+				 tDot11fIECFParams *pSrc,
+				 uint8_t *pBuf,
+				 uint32_t nBuf,
+				 uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 6;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 4;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->cfp_count;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->cfp_period;
+		*pnConsumed += 1;
+		pBuf += 1;
+		frameshtons(pCtx, pBuf, pSrc->cfp_maxduration, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->cfp_durremaining, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_cf_params. */
+
+uint32_t dot11f_pack_ie_challenge_text(tpAniSirGlobal pCtx,
+				      tDot11fIEChallengeText *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_text;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 16;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->text), pSrc->num_text);
+		*pnConsumed += pSrc->num_text;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_challenge_text. */
+
+uint32_t dot11f_pack_ie_chan_switch_ann(tpAniSirGlobal pCtx,
+				      tDot11fIEChanSwitchAnn *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 3;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 37;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->switchMode;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->newChannel;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->switchCount;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_chan_switch_ann. */
+
+uint32_t dot11f_pack_ie_channel_switch_wrapper(tpAniSirGlobal pCtx,
+					     tDot11fIEChannelSwitchWrapper *pSrc,
+					     uint8_t *pBuf,
+					     uint32_t nBuf,
+					     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ie_channel_switch_wrapper(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 196;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		status = pack_core(pCtx,
+				(uint8_t *)pSrc,
+				pBuf,
+				nBuf,
+				pnConsumed,
+				FFS_ChannelSwitchWrapper,
+				IES_ChannelSwitchWrapper);
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_channel_switch_wrapper. */
+
+uint32_t dot11f_pack_ie_country(tpAniSirGlobal pCtx,
+				tDot11fIECountry *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ie_country(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 7;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->country, 3);
+		*pnConsumed += 3;
+		pBuf += 3;
+		if (pSrc->num_triplets) {
+			DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->triplets), (pSrc->num_triplets * 3));
+			*pnConsumed += (pSrc->num_triplets * 3);
+			/* fieldsEndFlag = 1 */
+		} else {
+			break;
+		}
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_country. */
+
+uint32_t dot11f_pack_ie_ds_params(tpAniSirGlobal pCtx,
+				 tDot11fIEDSParams *pSrc,
+				 uint8_t *pBuf,
+				 uint32_t nBuf,
+				 uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 3;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->curr_channel;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ds_params. */
+
+uint32_t dot11f_pack_ie_edca_param_set(tpAniSirGlobal pCtx,
+				     tDot11fIEEDCAParamSet *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp127__;
+	uint8_t tmp128__;
+	uint8_t tmp129__;
+	uint8_t tmp130__;
+	uint8_t tmp131__;
+	uint8_t tmp132__;
+	uint8_t tmp133__;
+	uint8_t tmp134__;
+	nNeeded  += 18;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 12;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->qos;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->reserved;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp127__ = 0U;
+		tmp127__ |= (pSrc->acbe_aifsn << 0);
+		tmp127__ |= (pSrc->acbe_acm << 4);
+		tmp127__ |= (pSrc->acbe_aci << 5);
+		tmp127__ |= (pSrc->unused1 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp127__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp128__ = 0U;
+		tmp128__ |= (pSrc->acbe_acwmin << 0);
+		tmp128__ |= (pSrc->acbe_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp128__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		tmp129__ = 0U;
+		tmp129__ |= (pSrc->acbk_aifsn << 0);
+		tmp129__ |= (pSrc->acbk_acm << 4);
+		tmp129__ |= (pSrc->acbk_aci << 5);
+		tmp129__ |= (pSrc->unused2 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp129__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp130__ = 0U;
+		tmp130__ |= (pSrc->acbk_acwmin << 0);
+		tmp130__ |= (pSrc->acbk_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp130__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		tmp131__ = 0U;
+		tmp131__ |= (pSrc->acvi_aifsn << 0);
+		tmp131__ |= (pSrc->acvi_acm << 4);
+		tmp131__ |= (pSrc->acvi_aci << 5);
+		tmp131__ |= (pSrc->unused3 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp131__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp132__ = 0U;
+		tmp132__ |= (pSrc->acvi_acwmin << 0);
+		tmp132__ |= (pSrc->acvi_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp132__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		tmp133__ = 0U;
+		tmp133__ |= (pSrc->acvo_aifsn << 0);
+		tmp133__ |= (pSrc->acvo_acm << 4);
+		tmp133__ |= (pSrc->acvo_aci << 5);
+		tmp133__ |= (pSrc->unused4 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp133__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp134__ = 0U;
+		tmp134__ |= (pSrc->acvo_acwmin << 0);
+		tmp134__ |= (pSrc->acvo_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp134__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_edca_param_set. */
+
+uint32_t dot11f_pack_ie_erp_info(tpAniSirGlobal pCtx,
+				tDot11fIEERPInfo *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp135__;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 42;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp135__ = 0U;
+		tmp135__ |= (pSrc->non_erp_present << 0);
+		tmp135__ |= (pSrc->use_prot << 1);
+		tmp135__ |= (pSrc->barker_preamble << 2);
+		tmp135__ |= (pSrc->unused << 3);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp135__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_erp_info. */
+
+uint32_t dot11f_pack_ie_ese_cckm_opaque(tpAniSirGlobal pCtx,
+				      tDot11fIEESECckmOpaque *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_data;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 156;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x40;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x96;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+		*pnConsumed += pSrc->num_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_cckm_opaque. */
+
+uint32_t dot11f_pack_ie_ese_rad_mgmt_cap(tpAniSirGlobal pCtx,
+				      tDot11fIEESERadMgmtCap *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp136__;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x40;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x96;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x1;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->mgmt_state;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp136__ = 0U;
+		tmp136__ |= (pSrc->mbssid_mask << 0);
+		tmp136__ |= (pSrc->reserved << 3);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp136__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_rad_mgmt_cap. */
+
+uint32_t dot11f_pack_ie_ese_traf_strm_met(tpAniSirGlobal pCtx,
+				       tDot11fIEESETrafStrmMet *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 4;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x40;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x96;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x7;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->tsid;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->state;
+		*pnConsumed += 1;
+		pBuf += 1;
+		frameshtons(pCtx, pBuf, pSrc->msmt_interval, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_traf_strm_met. */
+
+uint32_t dot11f_pack_ie_ese_traf_strm_rate_set(tpAniSirGlobal pCtx,
+					   tDot11fIEESETrafStrmRateSet *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_tsrates + 1);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x40;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x96;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x8;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->tsid;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->tsrates), pSrc->num_tsrates);
+		*pnConsumed += pSrc->num_tsrates;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_traf_strm_rate_set. */
+
+uint32_t dot11f_pack_ie_ese_txmit_power(tpAniSirGlobal pCtx,
+				      tDot11fIEESETxmitPower *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 150;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x40;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x96;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->power_limit;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->reserved;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_txmit_power. */
+
+uint32_t dot11f_pack_ie_ese_version(tpAniSirGlobal pCtx,
+				   tDot11fIEESEVersion *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x40;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x96;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x3;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->version;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_version. */
+
+uint32_t dot11f_pack_ie_ext_cap(tpAniSirGlobal pCtx,
+			       tDot11fIEExtCap *pSrc,
+			       uint8_t *pBuf,
+			       uint32_t nBuf,
+			       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_bytes;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 127;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->bytes), pSrc->num_bytes);
+		*pnConsumed += pSrc->num_bytes;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ext_cap. */
+
+uint32_t dot11f_pack_ie_ext_supp_rates(tpAniSirGlobal pCtx,
+				     tDot11fIEExtSuppRates *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_rates;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 50;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->rates), pSrc->num_rates);
+		*pnConsumed += pSrc->num_rates;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ext_supp_rates. */
+
+uint32_t dot11f_pack_ie_fh_param_set(tpAniSirGlobal pCtx,
+				   tDot11fIEFHParamSet *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 5;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 2;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		frameshtons(pCtx, pBuf, pSrc->dwell_time, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		*pBuf = pSrc->hop_set;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->hop_pattern;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->hop_index;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fh_param_set. */
+
+uint32_t dot11f_pack_ie_fh_params(tpAniSirGlobal pCtx,
+				 tDot11fIEFHParams *pSrc,
+				 uint8_t *pBuf,
+				 uint32_t nBuf,
+				 uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 8;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->radix;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->nchannels;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fh_params. */
+
+uint32_t dot11f_pack_ie_fh_patt_table(tpAniSirGlobal pCtx,
+				    tDot11fIEFHPattTable *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_randtable + 4);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 9;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->flag;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->nsets;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->modulus;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->offset;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->randtable), pSrc->num_randtable);
+		*pnConsumed += pSrc->num_randtable;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fh_patt_table. */
+
+uint32_t dot11f_pack_ie_ft_info(tpAniSirGlobal pCtx,
+			       tDot11fIEFTInfo *pSrc,
+			       uint8_t *pBuf,
+			       uint32_t nBuf,
+			       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint16_t tmp137__;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ieft_info(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 55;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		tmp137__ = 0U;
+		tmp137__ |= (pSrc->reserved << 0);
+		tmp137__ |= (pSrc->IECount << 8);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp137__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->MIC, 16);
+		*pnConsumed += 16;
+		pBuf += 16;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->Anonce, 32);
+		*pnConsumed += 32;
+		pBuf += 32;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->Snonce, 32);
+		*pnConsumed += 32;
+		pBuf += 32;
+		status = pack_core(pCtx,
+				(uint8_t *)pSrc,
+				pBuf,
+				nBuf,
+				pnConsumed,
+				FFS_FTInfo,
+				IES_FTInfo);
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_ft_info. */
+
+uint32_t dot11f_pack_ie_ht_caps(tpAniSirGlobal pCtx,
+			       tDot11fIEHTCaps *pSrc,
+			       uint8_t *pBuf,
+			       uint32_t nBuf,
+			       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint16_t tmp138__;
+	uint8_t tmp139__;
+	uint16_t tmp140__;
+	uint32_t tmp141__;
+	uint8_t tmp142__;
+	nNeeded  +=  (pSrc->num_rsvd + 26);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 45;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp138__ = 0U;
+		tmp138__ |= (pSrc->advCodingCap << 0);
+		tmp138__ |= (pSrc->supportedChannelWidthSet << 1);
+		tmp138__ |= (pSrc->mimoPowerSave << 2);
+		tmp138__ |= (pSrc->greenField << 4);
+		tmp138__ |= (pSrc->shortGI20MHz << 5);
+		tmp138__ |= (pSrc->shortGI40MHz << 6);
+		tmp138__ |= (pSrc->txSTBC << 7);
+		tmp138__ |= (pSrc->rxSTBC << 8);
+		tmp138__ |= (pSrc->delayedBA << 10);
+		tmp138__ |= (pSrc->maximalAMSDUsize << 11);
+		tmp138__ |= (pSrc->dsssCckMode40MHz << 12);
+		tmp138__ |= (pSrc->psmp << 13);
+		tmp138__ |= (pSrc->stbcControlFrame << 14);
+		tmp138__ |= (pSrc->lsigTXOPProtection << 15);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp138__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		tmp139__ = 0U;
+		tmp139__ |= (pSrc->maxRxAMPDUFactor << 0);
+		tmp139__ |= (pSrc->mpduDensity << 2);
+		tmp139__ |= (pSrc->reserved1 << 5);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp139__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->supportedMCSSet, 16);
+		*pnConsumed += 16;
+		pBuf += 16;
+		tmp140__ = 0U;
+		tmp140__ |= (pSrc->pco << 0);
+		tmp140__ |= (pSrc->transitionTime << 1);
+		tmp140__ |= (pSrc->reserved2 << 3);
+		tmp140__ |= (pSrc->mcsFeedback << 8);
+		tmp140__ |= (pSrc->reserved3 << 10);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp140__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		tmp141__ = 0U;
+		tmp141__ |= (pSrc->txBF << 0);
+		tmp141__ |= (pSrc->rxStaggeredSounding << 1);
+		tmp141__ |= (pSrc->txStaggeredSounding << 2);
+		tmp141__ |= (pSrc->rxZLF << 3);
+		tmp141__ |= (pSrc->txZLF << 4);
+		tmp141__ |= (pSrc->implicitTxBF << 5);
+		tmp141__ |= (pSrc->calibration << 6);
+		tmp141__ |= (pSrc->explicitCSITxBF << 8);
+		tmp141__ |= (pSrc->explicitUncompressedSteeringMatrix << 9);
+		tmp141__ |= (pSrc->explicitBFCSIFeedback << 10);
+		tmp141__ |= (pSrc->explicitUncompressedSteeringMatrixFeedback << 13);
+		tmp141__ |= (pSrc->explicitCompressedSteeringMatrixFeedback << 16);
+		tmp141__ |= (pSrc->csiNumBFAntennae << 19);
+		tmp141__ |= (pSrc->uncompressedSteeringMatrixBFAntennae << 21);
+		tmp141__ |= (pSrc->compressedSteeringMatrixBFAntennae << 23);
+		tmp141__ |= (pSrc->reserved4 << 25);
+		if (unlikely(nBuf < 4))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtonl(pCtx, pBuf, tmp141__, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		nBuf -=  4 ;
+		tmp142__ = 0U;
+		tmp142__ |= (pSrc->antennaSelection << 0);
+		tmp142__ |= (pSrc->explicitCSIFeedbackTx << 1);
+		tmp142__ |= (pSrc->antennaIndicesFeedbackTx << 2);
+		tmp142__ |= (pSrc->explicitCSIFeedback << 3);
+		tmp142__ |= (pSrc->antennaIndicesFeedback << 4);
+		tmp142__ |= (pSrc->rxAS << 5);
+		tmp142__ |= (pSrc->txSoundingPPDUs << 6);
+		tmp142__ |= (pSrc->reserved5 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp142__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->rsvd), pSrc->num_rsvd);
+		*pnConsumed += pSrc->num_rsvd;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ht_caps. */
+
+uint32_t dot11f_pack_ie_ht_info(tpAniSirGlobal pCtx,
+			       tDot11fIEHTInfo *pSrc,
+			       uint8_t *pBuf,
+			       uint32_t nBuf,
+			       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp143__;
+	uint16_t tmp144__;
+	uint16_t tmp145__;
+	nNeeded  +=  (pSrc->num_rsvd + 22);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 61;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->primaryChannel;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp143__ = 0U;
+		tmp143__ |= (pSrc->secondaryChannelOffset << 0);
+		tmp143__ |= (pSrc->recommendedTxWidthSet << 2);
+		tmp143__ |= (pSrc->rifsMode << 3);
+		tmp143__ |= (pSrc->controlledAccessOnly << 4);
+		tmp143__ |= (pSrc->serviceIntervalGranularity << 5);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp143__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp144__ = 0U;
+		tmp144__ |= (pSrc->opMode << 0);
+		tmp144__ |= (pSrc->nonGFDevicesPresent << 2);
+		tmp144__ |= (pSrc->transmitBurstLimit << 3);
+		tmp144__ |= (pSrc->obssNonHTStaPresent << 4);
+		tmp144__ |= (pSrc->reserved << 5);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp144__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		tmp145__ = 0U;
+		tmp145__ |= (pSrc->basicSTBCMCS << 0);
+		tmp145__ |= (pSrc->dualCTSProtection << 7);
+		tmp145__ |= (pSrc->secondaryBeacon << 8);
+		tmp145__ |= (pSrc->lsigTXOPProtectionFullSupport << 9);
+		tmp145__ |= (pSrc->pcoActive << 10);
+		tmp145__ |= (pSrc->pcoPhase << 11);
+		tmp145__ |= (pSrc->reserved2 << 12);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp145__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->basicMCSSet, 16);
+		*pnConsumed += 16;
+		pBuf += 16;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->rsvd), pSrc->num_rsvd);
+		*pnConsumed += pSrc->num_rsvd;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ht_info. */
+
+uint32_t dot11f_pack_ie_ibss_params(tpAniSirGlobal pCtx,
+				   tDot11fIEIBSSParams *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 6;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		frameshtons(pCtx, pBuf, pSrc->atim, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ibss_params. */
+
+uint32_t dot11f_pack_ie_link_identifier(tpAniSirGlobal pCtx,
+				       tDot11fIELinkIdentifier *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 18;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 101;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6);
+		*pnConsumed += 6;
+		pBuf += 6;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->InitStaAddr, 6);
+		*pnConsumed += 6;
+		pBuf += 6;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->RespStaAddr, 6);
+		*pnConsumed += 6;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_link_identifier. */
+
+uint32_t dot11f_pack_ie_MBO_IE(tpAniSirGlobal pCtx,
+			       tDot11fIEMBO_IE *pSrc,
+			       uint8_t *pBuf,
+			       uint32_t nBuf,
+			       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_ie_MBO_IE(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x6f;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9a;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x16;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_MBO_IE +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_MBO_IE. */
+
+uint32_t dot11f_pack_ie_measurement_report(tpAniSirGlobal pCtx,
+					  tDot11fIEMeasurementReport *pSrc,
+					  uint8_t *pBuf,
+					  uint32_t nBuf,
+					  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp146__;
+	uint8_t tmp147__;
+	uint8_t tmp148__;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ie_measurement_report(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 39;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->token;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp146__ = 0U;
+		tmp146__ |= (pSrc->late << 0);
+		tmp146__ |= (pSrc->incapable << 1);
+		tmp146__ |= (pSrc->refused << 2);
+		tmp146__ |= (pSrc->unused << 3);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp146__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		*pBuf = pSrc->type;
+		*pnConsumed += 1;
+		pBuf += 1;
+		if (pSrc->type) {
+			switch (pSrc->type) {
+			case 0:
+				*pBuf = pSrc->report.Basic.channel;
+				*pnConsumed += 1;
+				pBuf += 1;
+				frameshtonq(pCtx, pBuf, pSrc->report.Basic.meas_start_time, 0);
+				*pnConsumed += 8;
+				pBuf += 8;
+				frameshtons(pCtx, pBuf, pSrc->report.Basic.meas_duration, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				tmp147__ = 0U;
+				tmp147__ |= (pSrc->report.Basic.bss << 0);
+				tmp147__ |= (pSrc->report.Basic.ofdm_preamble << 1);
+				tmp147__ |= (pSrc->report.Basic.unid_signal << 2);
+				tmp147__ |= (pSrc->report.Basic.rader << 3);
+				tmp147__ |= (pSrc->report.Basic.unmeasured << 4);
+				tmp147__ |= (pSrc->report.Basic.unused << 5);
+				if (unlikely(nBuf < 1))
+					return DOT11F_INCOMPLETE_IE;
+
+				*pBuf = tmp147__;
+				*pnConsumed += 1;
+				/* fieldsEndFlag  = 1 */
+				nBuf -=  1 ;
+				break;
+			case 1:
+				*pBuf = pSrc->report.CCA.channel;
+				*pnConsumed += 1;
+				pBuf += 1;
+				frameshtonq(pCtx, pBuf, pSrc->report.CCA.meas_start_time, 0);
+				*pnConsumed += 8;
+				pBuf += 8;
+				frameshtons(pCtx, pBuf, pSrc->report.CCA.meas_duration, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				*pBuf = pSrc->report.CCA.cca_busy_fraction;
+				*pnConsumed += 1;
+				/* fieldsEndFlag = 1 */
+				break;
+			case 2:
+				*pBuf = pSrc->report.RPIHistogram.channel;
+				*pnConsumed += 1;
+				pBuf += 1;
+				frameshtonq(pCtx, pBuf, pSrc->report.RPIHistogram.meas_start_time, 0);
+				*pnConsumed += 8;
+				pBuf += 8;
+				frameshtons(pCtx, pBuf, pSrc->report.RPIHistogram.meas_duration, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				*pBuf = pSrc->report.RPIHistogram.rpi0_density;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->report.RPIHistogram.rpi1_density;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->report.RPIHistogram.rpi2_density;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->report.RPIHistogram.rpi3_density;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->report.RPIHistogram.rpi4_density;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->report.RPIHistogram.rpi5_density;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->report.RPIHistogram.rpi6_density;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->report.RPIHistogram.rpi7_density;
+				*pnConsumed += 1;
+				/* fieldsEndFlag = 1 */
+				break;
+			case 5:
+				*pBuf = pSrc->report.Beacon.regClass;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->report.Beacon.channel;
+				*pnConsumed += 1;
+				pBuf += 1;
+				frameshtonq(pCtx, pBuf, pSrc->report.Beacon.meas_start_time, 0);
+				*pnConsumed += 8;
+				pBuf += 8;
+				frameshtons(pCtx, pBuf, pSrc->report.Beacon.meas_duration, 0);
+				*pnConsumed += 2;
+				pBuf += 2;
+				tmp148__ = 0U;
+				tmp148__ |= (pSrc->report.Beacon.condensed_PHY << 0);
+				tmp148__ |= (pSrc->report.Beacon.reported_frame_type << 7);
+				if (unlikely(nBuf < 1))
+					return DOT11F_INCOMPLETE_IE;
+
+				*pBuf = tmp148__;
+				*pnConsumed += 1;
+				pBuf += 1;
+				nBuf -=  1 ;
+				*pBuf = pSrc->report.Beacon.RCPI;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->report.Beacon.RSNI;
+				*pnConsumed += 1;
+				pBuf += 1;
+				DOT11F_MEMCPY(pCtx, pBuf, pSrc->report.Beacon.BSSID, 6);
+				*pnConsumed += 6;
+				pBuf += 6;
+				*pBuf = pSrc->report.Beacon.antenna_id;
+				*pnConsumed += 1;
+				pBuf += 1;
+				frameshtonl(pCtx, pBuf, pSrc->report.Beacon.parent_TSF, 0);
+				*pnConsumed += 4;
+				pBuf += 4;
+				status = pack_core(pCtx,
+					 (uint8_t *)pSrc,
+					 pBuf,
+					 nBuf,
+					 pnConsumed,
+					 FFS_reportBeacon,
+					 IES_reportBeacon);
+				break;
+			}
+		} else {
+			break;
+		}
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_measurement_report. */
+
+uint32_t dot11f_pack_ie_measurement_request(tpAniSirGlobal pCtx,
+					   tDot11fIEMeasurementRequest *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp149__;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ie_measurement_request(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 38;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->measurement_token;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp149__ = 0U;
+		tmp149__ |= (pSrc->parallel << 0);
+		tmp149__ |= (pSrc->enable << 1);
+		tmp149__ |= (pSrc->request << 2);
+		tmp149__ |= (pSrc->report << 3);
+		tmp149__ |= (pSrc->durationMandatory << 4);
+		tmp149__ |= (pSrc->unused << 5);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp149__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		*pBuf = pSrc->measurement_type;
+		*pnConsumed += 1;
+		pBuf += 1;
+		switch (pSrc->measurement_type) {
+		case 0:
+			*pBuf = pSrc->measurement_request.Basic.channel_no;
+			*pnConsumed += 1;
+			pBuf += 1;
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.Basic.meas_start_time, 8);
+			*pnConsumed += 8;
+			pBuf += 8;
+			frameshtons(pCtx, pBuf, pSrc->measurement_request.Basic.meas_duration, 0);
+			*pnConsumed += 2;
+			/* fieldsEndFlag = 1 */
+			break;
+		case 1:
+			*pBuf = pSrc->measurement_request.CCA.channel_no;
+			*pnConsumed += 1;
+			pBuf += 1;
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.CCA.meas_start_time, 8);
+			*pnConsumed += 8;
+			pBuf += 8;
+			frameshtons(pCtx, pBuf, pSrc->measurement_request.CCA.meas_duration, 0);
+			*pnConsumed += 2;
+			/* fieldsEndFlag = 1 */
+			break;
+		case 2:
+			*pBuf = pSrc->measurement_request.RPIHistogram.channel_no;
+			*pnConsumed += 1;
+			pBuf += 1;
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.RPIHistogram.meas_start_time, 8);
+			*pnConsumed += 8;
+			pBuf += 8;
+			frameshtons(pCtx, pBuf, pSrc->measurement_request.RPIHistogram.meas_duration, 0);
+			*pnConsumed += 2;
+			/* fieldsEndFlag = 1 */
+			break;
+		case 5:
+			*pBuf = pSrc->measurement_request.Beacon.regClass;
+			*pnConsumed += 1;
+			pBuf += 1;
+			*pBuf = pSrc->measurement_request.Beacon.channel;
+			*pnConsumed += 1;
+			pBuf += 1;
+			frameshtons(pCtx, pBuf, pSrc->measurement_request.Beacon.randomization, 0);
+			*pnConsumed += 2;
+			pBuf += 2;
+			frameshtons(pCtx, pBuf, pSrc->measurement_request.Beacon.meas_duration, 0);
+			*pnConsumed += 2;
+			pBuf += 2;
+			*pBuf = pSrc->measurement_request.Beacon.meas_mode;
+			*pnConsumed += 1;
+			pBuf += 1;
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.Beacon.BSSID, 6);
+			*pnConsumed += 6;
+			pBuf += 6;
+			status = pack_core(pCtx,
+				 (uint8_t *)pSrc,
+				 pBuf,
+				 nBuf,
+				 pnConsumed,
+				 FFS_measurement_requestBeacon,
+				 IES_measurement_requestBeacon);
+			break;
+		case 8:
+			*pBuf = pSrc->measurement_request.lci.loc_subject;
+			*pnConsumed += 1;
+			pBuf += 1;
+			status = pack_core(pCtx,
+				 (uint8_t *)pSrc,
+				 pBuf,
+				 nBuf,
+				 pnConsumed,
+				 FFS_measurement_requestlci,
+				 IES_measurement_requestlci);
+			break;
+		case 16:
+			frameshtons(pCtx, pBuf, pSrc->measurement_request.ftmrr.random_interval, 0);
+			*pnConsumed += 2;
+			pBuf += 2;
+			*pBuf = pSrc->measurement_request.ftmrr.min_ap_count;
+			*pnConsumed += 1;
+			pBuf += 1;
+			status = pack_core(pCtx,
+				 (uint8_t *)pSrc,
+				 pBuf,
+				 nBuf,
+				 pnConsumed,
+				 FFS_measurement_requestftmrr,
+				 IES_measurement_requestftmrr);
+			break;
+		}
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_measurement_request. */
+
+uint32_t dot11f_pack_ie_mobility_domain(tpAniSirGlobal pCtx,
+				       tDot11fIEMobilityDomain *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp150__;
+	nNeeded  += 3;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 54;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		frameshtons(pCtx, pBuf, pSrc->MDID, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		tmp150__ = 0U;
+		tmp150__ |= (pSrc->overDSCap << 0);
+		tmp150__ |= (pSrc->resourceReqCap << 1);
+		tmp150__ |= (pSrc->reserved << 2);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp150__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_mobility_domain. */
+
+uint32_t dot11f_pack_ie_neighbor_report(tpAniSirGlobal pCtx,
+				       tDot11fIENeighborReport *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp151__;
+	uint8_t tmp152__;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ie_neighbor_report(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 52;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6);
+		*pnConsumed += 6;
+		pBuf += 6;
+		tmp151__ = 0U;
+		tmp151__ |= (pSrc->APReachability << 0);
+		tmp151__ |= (pSrc->Security << 2);
+		tmp151__ |= (pSrc->KeyScope << 3);
+		tmp151__ |= (pSrc->SpecMgmtCap << 4);
+		tmp151__ |= (pSrc->QosCap << 5);
+		tmp151__ |= (pSrc->apsd << 6);
+		tmp151__ |= (pSrc->rrm << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp151__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp152__ = 0U;
+		tmp152__ |= (pSrc->DelayedBA << 0);
+		tmp152__ |= (pSrc->ImmBA << 1);
+		tmp152__ |= (pSrc->MobilityDomain << 2);
+		tmp152__ |= (pSrc->reserved << 3);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp152__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		frameshtons(pCtx, pBuf, pSrc->reserved1, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		*pBuf = pSrc->regulatoryClass;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->channel;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->PhyType;
+		*pnConsumed += 1;
+		pBuf += 1;
+		status = pack_core(pCtx,
+				(uint8_t *)pSrc,
+				pBuf,
+				nBuf,
+				pnConsumed,
+				FFS_NeighborReport,
+				IES_NeighborReport);
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_neighbor_report. */
+
+uint32_t dot11f_pack_ie_obss_scan_parameters(tpAniSirGlobal pCtx,
+					   tDot11fIEOBSSScanParameters *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 14;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 74;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		frameshtons(pCtx, pBuf, pSrc->obssScanPassiveDwell, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->obssScanActiveDwell, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->bssChannelWidthTriggerScanInterval, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->obssScanPassiveTotalPerChannel, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->obssScanActiveTotalPerChannel, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->bssWidthChannelTransitionDelayFactor, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->obssScanActivityThreshold, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_obss_scan_parameters. */
+
+uint32_t dot11f_pack_ie_operating_mode(tpAniSirGlobal pCtx,
+				      tDot11fIEOperatingMode *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp153__;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 199;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp153__ = 0U;
+		tmp153__ |= (pSrc->chanWidth << 0);
+		tmp153__ |= (pSrc->reserved << 2);
+		tmp153__ |= (pSrc->rxNSS << 4);
+		tmp153__ |= (pSrc->rxNSSType << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp153__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_operating_mode. */
+
+uint32_t dot11f_pack_ie_p2_p_assoc_req(tpAniSirGlobal pCtx,
+				    tDot11fIEP2PAssocReq *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_iep2_p_assoc_req(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x6f;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9a;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_P2PAssocReq +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_p2_p_assoc_req. */
+
+uint32_t dot11f_pack_ie_p2_p_assoc_res(tpAniSirGlobal pCtx,
+				    tDot11fIEP2PAssocRes *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_iep2_p_assoc_res(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x6f;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9a;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_P2PAssocRes +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_p2_p_assoc_res. */
+
+uint32_t dot11f_pack_ie_p2_p_beacon(tpAniSirGlobal pCtx,
+				  tDot11fIEP2PBeacon *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_iep2_p_beacon(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x6f;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9a;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_P2PBeacon +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_p2_p_beacon. */
+
+uint32_t dot11f_pack_ie_p2_p_beacon_probe_res(tpAniSirGlobal pCtx,
+					  tDot11fIEP2PBeaconProbeRes *pSrc,
+					  uint8_t *pBuf,
+					  uint32_t nBuf,
+					  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_iep2_p_beacon_probe_res(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x6f;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9a;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_P2PBeaconProbeRes +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_p2_p_beacon_probe_res. */
+
+uint32_t dot11f_pack_ie_p2_p_de_auth(tpAniSirGlobal pCtx,
+				  tDot11fIEP2PDeAuth *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_iep2_p_de_auth(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x6f;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9a;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_P2PDeAuth +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_p2_p_de_auth. */
+
+uint32_t dot11f_pack_ie_p2_p_dis_assoc(tpAniSirGlobal pCtx,
+				    tDot11fIEP2PDisAssoc *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_iep2_p_dis_assoc(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x6f;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9a;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_P2PDisAssoc +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_p2_p_dis_assoc. */
+
+uint32_t dot11f_pack_ie_p2_pie_opaque(tpAniSirGlobal pCtx,
+				    tDot11fIEP2PIEOpaque *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_data;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x6f;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x9a;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x9;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+		*pnConsumed += pSrc->num_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_p2_pie_opaque. */
+
+uint32_t dot11f_pack_ie_p2_p_probe_req(tpAniSirGlobal pCtx,
+				    tDot11fIEP2PProbeReq *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_iep2_p_probe_req(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x6f;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9a;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_P2PProbeReq +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_p2_p_probe_req. */
+
+uint32_t dot11f_pack_ie_p2_p_probe_res(tpAniSirGlobal pCtx,
+				    tDot11fIEP2PProbeRes *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_iep2_p_probe_res(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x6f;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9a;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x9;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_P2PProbeRes +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_p2_p_probe_res. */
+
+uint32_t dot11f_pack_ie_pti_control(tpAniSirGlobal pCtx,
+				   tDot11fIEPTIControl *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 3;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 105;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->tid;
+		*pnConsumed += 1;
+		pBuf += 1;
+		frameshtons(pCtx, pBuf, pSrc->sequence_control, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_pti_control. */
+
+uint32_t dot11f_pack_ie_pu_buffer_status(tpAniSirGlobal pCtx,
+				       tDot11fIEPUBufferStatus *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp154__;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 106;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp154__ = 0U;
+		tmp154__ |= (pSrc->ac_bk_traffic_aval << 0);
+		tmp154__ |= (pSrc->ac_be_traffic_aval << 1);
+		tmp154__ |= (pSrc->ac_vi_traffic_aval << 2);
+		tmp154__ |= (pSrc->ac_vo_traffic_aval << 3);
+		tmp154__ |= (pSrc->reserved << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp154__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_pu_buffer_status. */
+
+uint32_t dot11f_pack_ie_power_caps(tpAniSirGlobal pCtx,
+				  tDot11fIEPowerCaps *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 33;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->minTxPower;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->maxTxPower;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_power_caps. */
+
+uint32_t dot11f_pack_ie_power_constraints(tpAniSirGlobal pCtx,
+					 tDot11fIEPowerConstraints *pSrc,
+					 uint8_t *pBuf,
+					 uint32_t nBuf,
+					 uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 32;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->localPowerConstraints;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_power_constraints. */
+
+uint32_t dot11f_pack_ie_qbss_load(tpAniSirGlobal pCtx,
+				 tDot11fIEQBSSLoad *pSrc,
+				 uint8_t *pBuf,
+				 uint32_t nBuf,
+				 uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 5;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 11;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		frameshtons(pCtx, pBuf, pSrc->stacount, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		*pBuf = pSrc->chautil;
+		*pnConsumed += 1;
+		pBuf += 1;
+		frameshtons(pCtx, pBuf, pSrc->avail, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_qbss_load. */
+
+uint32_t dot11f_pack_ie_QCN_IE(tpAniSirGlobal pCtx,
+			       tDot11fIEQCN_IE *pSrc,
+			       uint8_t *pBuf,
+			       uint32_t nBuf,
+			       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 4;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x8c;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xfd;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x1;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->version, 4);
+		*pnConsumed += 4;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_QCN_IE. */
+
+uint32_t dot11f_pack_ie_QComVendorIE(tpAniSirGlobal pCtx,
+				     tDot11fIEQComVendorIE *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xa0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xc6;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->type;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->channel;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_QComVendorIE. */
+
+uint32_t dot11f_pack_ie_qos_caps_ap(tpAniSirGlobal pCtx,
+				  tDot11fIEQOSCapsAp *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp155__;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 46;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp155__ = 0U;
+		tmp155__ |= (pSrc->count << 0);
+		tmp155__ |= (pSrc->qack << 4);
+		tmp155__ |= (pSrc->qreq << 5);
+		tmp155__ |= (pSrc->txopreq << 6);
+		tmp155__ |= (pSrc->reserved << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp155__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_qos_caps_ap. */
+
+uint32_t dot11f_pack_ie_qos_caps_station(tpAniSirGlobal pCtx,
+				       tDot11fIEQOSCapsStation *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp156__;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 46;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp156__ = 0U;
+		tmp156__ |= (pSrc->acvo_uapsd << 0);
+		tmp156__ |= (pSrc->acvi_uapsd << 1);
+		tmp156__ |= (pSrc->acbk_uapsd << 2);
+		tmp156__ |= (pSrc->acbe_uapsd << 3);
+		tmp156__ |= (pSrc->qack << 4);
+		tmp156__ |= (pSrc->max_sp_length << 5);
+		tmp156__ |= (pSrc->more_data_ack << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp156__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_qos_caps_station. */
+
+uint32_t dot11f_pack_ie_qos_map_set(tpAniSirGlobal pCtx,
+				  tDot11fIEQosMapSet *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_dscp_exceptions;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 110;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->dscp_exceptions), pSrc->num_dscp_exceptions);
+		*pnConsumed += pSrc->num_dscp_exceptions;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_qos_map_set. */
+
+uint32_t dot11f_pack_ie_quiet(tpAniSirGlobal pCtx,
+			      tDot11fIEQuiet *pSrc,
+			      uint8_t *pBuf,
+			      uint32_t nBuf,
+			      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 6;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 40;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->count;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->period;
+		*pnConsumed += 1;
+		pBuf += 1;
+		frameshtons(pCtx, pBuf, pSrc->duration, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->offset, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_quiet. */
+
+uint32_t dot11f_pack_ie_rcpiie(tpAniSirGlobal pCtx,
+			       tDot11fIERCPIIE *pSrc,
+			       uint8_t *pBuf,
+			       uint32_t nBuf,
+			       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 53;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->rcpi;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_rcpiie. */
+
+uint32_t dot11f_pack_ie_ric_data_desc(tpAniSirGlobal pCtx,
+				    tDot11fIERICDataDesc *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint32_t nNeeded = 0U;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ieric_data_desc(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		status = pack_core(pCtx,
+				(uint8_t *)pSrc,
+				pBuf,
+				nBuf,
+				pnConsumed,
+				FFS_RICDataDesc,
+				IES_RICDataDesc);
+		break;
+	}
+	(void)pCtx;
+	return status;
+} /* End dot11f_pack_ie_ric_data_desc. */
+
+uint32_t dot11f_pack_ie_rsn(tpAniSirGlobal pCtx,
+			    tDot11fIERSN *pSrc,
+			    uint8_t *pBuf,
+			    uint32_t nBuf,
+			    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_iersn(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 48;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		frameshtons(pCtx, pBuf, pSrc->version, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		if (pSrc->gp_cipher_suite_present) {
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->gp_cipher_suite, 4);
+			*pnConsumed += 4;
+			pBuf += 4;
+		} else {
+			break;
+		}
+		if (pSrc->pwise_cipher_suite_count) {
+			frameshtons(pCtx, pBuf, pSrc->pwise_cipher_suite_count, 0);
+			*pnConsumed += 2;
+			pBuf += 2;
+		} else {
+			break;
+		}
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->pwise_cipher_suites), (pSrc->pwise_cipher_suite_count * 4));
+		*pnConsumed += (pSrc->pwise_cipher_suite_count * 4);
+		pBuf += (pSrc->pwise_cipher_suite_count * 4);
+		if (pSrc->akm_suite_cnt) {
+			frameshtons(pCtx, pBuf, pSrc->akm_suite_cnt, 0);
+			*pnConsumed += 2;
+			pBuf += 2;
+		} else {
+			break;
+		}
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->akm_suite), (pSrc->akm_suite_cnt * 4));
+		*pnConsumed += (pSrc->akm_suite_cnt * 4);
+		pBuf += (pSrc->akm_suite_cnt * 4);
+		if (pSrc->RSN_Cap_present) {
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->RSN_Cap, 2);
+			*pnConsumed += 2;
+			pBuf += 2;
+		} else {
+			break;
+		}
+		if (pSrc->pmkid_count) {
+			frameshtons(pCtx, pBuf, pSrc->pmkid_count, 0);
+			*pnConsumed += 2;
+			pBuf += 2;
+		} else {
+			break;
+		}
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->pmkid), (pSrc->pmkid_count * 16));
+		*pnConsumed += (pSrc->pmkid_count * 16);
+		pBuf += (pSrc->pmkid_count * 16);
+		if (pSrc->gp_mgmt_cipher_suite_present) {
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->gp_mgmt_cipher_suite, 4);
+			*pnConsumed += 4;
+			/* fieldsEndFlag = 1 */
+		} else {
+			break;
+		}
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_rsn. */
+
+uint32_t dot11f_pack_ie_rsniie(tpAniSirGlobal pCtx,
+			       tDot11fIERSNIIE *pSrc,
+			       uint8_t *pBuf,
+			       uint32_t nBuf,
+			       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 65;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->rsni;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_rsniie. */
+
+uint32_t dot11f_pack_ie_rsn_opaque(tpAniSirGlobal pCtx,
+				  tDot11fIERSNOpaque *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_data;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 48;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+		*pnConsumed += pSrc->num_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_rsn_opaque. */
+
+uint32_t dot11f_pack_ie_supp_channels(tpAniSirGlobal pCtx,
+				     tDot11fIESuppChannels *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_bands * 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 36;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->bands), (pSrc->num_bands * 2));
+		*pnConsumed += (pSrc->num_bands * 2);
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_supp_channels. */
+
+uint32_t dot11f_pack_ie_supp_operating_classes(tpAniSirGlobal pCtx,
+					     tDot11fIESuppOperatingClasses *pSrc,
+					     uint8_t *pBuf,
+					     uint32_t nBuf,
+					     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_classes;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 59;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->classes), pSrc->num_classes);
+		*pnConsumed += pSrc->num_classes;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_supp_operating_classes. */
+
+uint32_t dot11f_pack_ie_supp_rates(tpAniSirGlobal pCtx,
+				  tDot11fIESuppRates *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_rates;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 1;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->rates), pSrc->num_rates);
+		*pnConsumed += pSrc->num_rates;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_supp_rates. */
+
+uint32_t dot11f_pack_ie_tim(tpAniSirGlobal pCtx,
+			    tDot11fIETIM *pSrc,
+			    uint8_t *pBuf,
+			    uint32_t nBuf,
+			    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_vbmp + 3);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 5;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->dtim_count;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->dtim_period;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->bmpctl;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->vbmp), pSrc->num_vbmp);
+		*pnConsumed += pSrc->num_vbmp;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tim. */
+
+uint32_t dot11f_pack_ie_tpc_report(tpAniSirGlobal pCtx,
+				  tDot11fIETPCReport *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 35;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->tx_power;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->link_margin;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tpc_report. */
+
+uint32_t dot11f_pack_ie_tpc_request(tpAniSirGlobal pCtx,
+				   tDot11fIETPCRequest *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 0;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 34;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tpc_request. */
+
+uint32_t dot11f_pack_ie_time_advertisement(tpAniSirGlobal pCtx,
+					  tDot11fIETimeAdvertisement *pSrc,
+					  uint8_t *pBuf,
+					  uint32_t nBuf,
+					  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 16;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 69;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->timing_capabilities;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->time_value, 10);
+		*pnConsumed += 10;
+		pBuf += 10;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->time_error, 5);
+		*pnConsumed += 5;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_time_advertisement. */
+
+uint32_t dot11f_pack_ie_timeout_interval(tpAniSirGlobal pCtx,
+					tDot11fIETimeoutInterval *pSrc,
+					uint8_t *pBuf,
+					uint32_t nBuf,
+					uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 5;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 56;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->timeoutType;
+		*pnConsumed += 1;
+		pBuf += 1;
+		frameshtonl(pCtx, pBuf, pSrc->timeoutValue, 0);
+		*pnConsumed += 4;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_timeout_interval. */
+
+uint32_t dot11f_pack_ie_vht_ext_bss_load(tpAniSirGlobal pCtx,
+				      tDot11fIEVHTExtBssLoad *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 5;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 193;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->muMIMOCapStaCount;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->ssUnderUtil;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->FortyMHzUtil;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->EightyMHzUtil;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->OneSixtyMHzUtil;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_vht_ext_bss_load. */
+
+uint32_t dot11f_pack_ie_vendor1_ie(tpAniSirGlobal pCtx,
+				  tDot11fIEVendor1IE *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 0;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x10;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x18;
+		++pBuf; ++(*pnConsumed);
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_vendor1_ie. */
+
+uint32_t dot11f_pack_ie_vendor3_ie(tpAniSirGlobal pCtx,
+				  tDot11fIEVendor3IE *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 0;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x16;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x32;
+		++pBuf; ++(*pnConsumed);
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_vendor3_ie. */
+
+uint32_t dot11f_pack_ie_wapi(tpAniSirGlobal pCtx,
+			     tDot11fIEWAPI *pSrc,
+			     uint8_t *pBuf,
+			     uint32_t nBuf,
+			     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint16_t tmp157__;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_iewapi(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 68;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		frameshtons(pCtx, pBuf, pSrc->version, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->akm_suite_count, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->akm_suites), (pSrc->akm_suite_count * 4));
+		*pnConsumed += (pSrc->akm_suite_count * 4);
+		pBuf += (pSrc->akm_suite_count * 4);
+		frameshtons(pCtx, pBuf, pSrc->unicast_cipher_suite_count, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->unicast_cipher_suites), (pSrc->unicast_cipher_suite_count * 4));
+		*pnConsumed += (pSrc->unicast_cipher_suite_count * 4);
+		pBuf += (pSrc->unicast_cipher_suite_count * 4);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->multicast_cipher_suite, 4);
+		*pnConsumed += 4;
+		pBuf += 4;
+		tmp157__ = 0U;
+		tmp157__ |= (pSrc->preauth << 0);
+		tmp157__ |= (pSrc->reserved << 1);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp157__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		if (pSrc->bkid_count) {
+			frameshtons(pCtx, pBuf, pSrc->bkid_count, 0);
+			*pnConsumed += 2;
+			pBuf += 2;
+		} else {
+			break;
+		}
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->bkid), (pSrc->bkid_count * 16));
+		*pnConsumed += (pSrc->bkid_count * 16);
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_wapi. */
+
+uint32_t dot11f_pack_ie_wapi_opaque(tpAniSirGlobal pCtx,
+				   tDot11fIEWAPIOpaque *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_data;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 68;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+		*pnConsumed += pSrc->num_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wapi_opaque. */
+
+uint32_t dot11f_pack_ie_wfatpc(tpAniSirGlobal pCtx,
+			       tDot11fIEWFATPC *pSrc,
+			       uint8_t *pBuf,
+			       uint32_t nBuf,
+			       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x8;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->txPower;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->linkMargin;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wfatpc. */
+
+uint32_t dot11f_pack_ie_wfdie_opaque(tpAniSirGlobal pCtx,
+				    tDot11fIEWFDIEOpaque *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_data;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x6f;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x9a;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xa;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+		*pnConsumed += pSrc->num_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wfdie_opaque. */
+
+uint32_t dot11f_pack_ie_wmm_caps(tpAniSirGlobal pCtx,
+				tDot11fIEWMMCaps *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp158__;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x5;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->version;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp158__ = 0U;
+		tmp158__ |= (pSrc->reserved << 0);
+		tmp158__ |= (pSrc->qack << 4);
+		tmp158__ |= (pSrc->queue_request << 5);
+		tmp158__ |= (pSrc->txop_request << 6);
+		tmp158__ |= (pSrc->more_ack << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp158__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmm_caps. */
+
+uint32_t dot11f_pack_ie_wmm_info_ap(tpAniSirGlobal pCtx,
+				  tDot11fIEWMMInfoAp *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp159__;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->version;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp159__ = 0U;
+		tmp159__ |= (pSrc->param_set_count << 0);
+		tmp159__ |= (pSrc->reserved << 4);
+		tmp159__ |= (pSrc->uapsd << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp159__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmm_info_ap. */
+
+uint32_t dot11f_pack_ie_wmm_info_station(tpAniSirGlobal pCtx,
+				       tDot11fIEWMMInfoStation *pSrc,
+				       uint8_t *pBuf,
+				       uint32_t nBuf,
+				       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp160__;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->version;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp160__ = 0U;
+		tmp160__ |= (pSrc->acvo_uapsd << 0);
+		tmp160__ |= (pSrc->acvi_uapsd << 1);
+		tmp160__ |= (pSrc->acbk_uapsd << 2);
+		tmp160__ |= (pSrc->acbe_uapsd << 3);
+		tmp160__ |= (pSrc->reserved1 << 4);
+		tmp160__ |= (pSrc->max_sp_length << 5);
+		tmp160__ |= (pSrc->reserved2 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp160__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmm_info_station. */
+
+uint32_t dot11f_pack_ie_wmm_params(tpAniSirGlobal pCtx,
+				  tDot11fIEWMMParams *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp161__;
+	uint8_t tmp162__;
+	uint8_t tmp163__;
+	uint8_t tmp164__;
+	uint8_t tmp165__;
+	uint8_t tmp166__;
+	uint8_t tmp167__;
+	uint8_t tmp168__;
+	nNeeded  += 19;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x1;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->version;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->qosInfo;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->reserved2;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp161__ = 0U;
+		tmp161__ |= (pSrc->acbe_aifsn << 0);
+		tmp161__ |= (pSrc->acbe_acm << 4);
+		tmp161__ |= (pSrc->acbe_aci << 5);
+		tmp161__ |= (pSrc->unused1 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp161__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp162__ = 0U;
+		tmp162__ |= (pSrc->acbe_acwmin << 0);
+		tmp162__ |= (pSrc->acbe_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp162__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		tmp163__ = 0U;
+		tmp163__ |= (pSrc->acbk_aifsn << 0);
+		tmp163__ |= (pSrc->acbk_acm << 4);
+		tmp163__ |= (pSrc->acbk_aci << 5);
+		tmp163__ |= (pSrc->unused2 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp163__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp164__ = 0U;
+		tmp164__ |= (pSrc->acbk_acwmin << 0);
+		tmp164__ |= (pSrc->acbk_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp164__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		tmp165__ = 0U;
+		tmp165__ |= (pSrc->acvi_aifsn << 0);
+		tmp165__ |= (pSrc->acvi_acm << 4);
+		tmp165__ |= (pSrc->acvi_aci << 5);
+		tmp165__ |= (pSrc->unused3 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp165__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp166__ = 0U;
+		tmp166__ |= (pSrc->acvi_acwmin << 0);
+		tmp166__ |= (pSrc->acvi_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp166__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		tmp167__ = 0U;
+		tmp167__ |= (pSrc->acvo_aifsn << 0);
+		tmp167__ |= (pSrc->acvo_acm << 4);
+		tmp167__ |= (pSrc->acvo_aci << 5);
+		tmp167__ |= (pSrc->unused4 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp167__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp168__ = 0U;
+		tmp168__ |= (pSrc->acvo_acwmin << 0);
+		tmp168__ |= (pSrc->acvo_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp168__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0);
+		*pnConsumed += 2;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmm_params. */
+
+uint32_t dot11f_pack_ie_wpa(tpAniSirGlobal pCtx,
+			    tDot11fIEWPA *pSrc,
+			    uint8_t *pBuf,
+			    uint32_t nBuf,
+			    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_iewpa(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x1;
+		++pBuf; ++(*pnConsumed);
+		frameshtons(pCtx, pBuf, pSrc->version, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		if (pSrc->multicast_cipher_present) {
+			DOT11F_MEMCPY(pCtx, pBuf, pSrc->multicast_cipher, 4);
+			*pnConsumed += 4;
+			pBuf += 4;
+		} else {
+			break;
+		}
+		if (pSrc->unicast_cipher_count) {
+			frameshtons(pCtx, pBuf, pSrc->unicast_cipher_count, 0);
+			*pnConsumed += 2;
+			pBuf += 2;
+		} else {
+			break;
+		}
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->unicast_ciphers), (pSrc->unicast_cipher_count * 4));
+		*pnConsumed += (pSrc->unicast_cipher_count * 4);
+		pBuf += (pSrc->unicast_cipher_count * 4);
+		if (pSrc->auth_suite_count) {
+			frameshtons(pCtx, pBuf, pSrc->auth_suite_count, 0);
+			*pnConsumed += 2;
+			pBuf += 2;
+		} else {
+			break;
+		}
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->auth_suites), (pSrc->auth_suite_count * 4));
+		*pnConsumed += (pSrc->auth_suite_count * 4);
+		pBuf += (pSrc->auth_suite_count * 4);
+		if (pSrc->caps) {
+			frameshtons(pCtx, pBuf, pSrc->caps, 0);
+			*pnConsumed += 2;
+			/* fieldsEndFlag = 1 */
+		} else {
+			break;
+		}
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_wpa. */
+
+uint32_t dot11f_pack_ie_wpa_opaque(tpAniSirGlobal pCtx,
+				  tDot11fIEWPAOpaque *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_data;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x1;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+		*pnConsumed += pSrc->num_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wpa_opaque. */
+
+uint32_t dot11f_pack_ie_wsc(tpAniSirGlobal pCtx,
+			    tDot11fIEWSC *pSrc,
+			    uint8_t *pBuf,
+			    uint32_t nBuf,
+			    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_iewsc(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x0;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0xf2;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x4;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_WSC +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_wsc. */
+
+uint32_t dot11f_pack_ie_wsc_assoc_req(tpAniSirGlobal pCtx,
+				    tDot11fIEWscAssocReq *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_ie_wsc_assoc_req(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x0;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0xf2;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x4;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_WscAssocReq +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_wsc_assoc_req. */
+
+uint32_t dot11f_pack_ie_wsc_assoc_res(tpAniSirGlobal pCtx,
+				    tDot11fIEWscAssocRes *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_ie_wsc_assoc_res(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x0;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0xf2;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x4;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_WscAssocRes +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_wsc_assoc_res. */
+
+uint32_t dot11f_pack_ie_wsc_beacon(tpAniSirGlobal pCtx,
+				  tDot11fIEWscBeacon *pSrc,
+				  uint8_t *pBuf,
+				  uint32_t nBuf,
+				  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_ie_wsc_beacon(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x0;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0xf2;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x4;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_WscBeacon +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_wsc_beacon. */
+
+uint32_t dot11f_pack_ie_wsc_beacon_probe_res(tpAniSirGlobal pCtx,
+					  tDot11fIEWscBeaconProbeRes *pSrc,
+					  uint8_t *pBuf,
+					  uint32_t nBuf,
+					  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_ie_wsc_beacon_probe_res(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x0;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0xf2;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x4;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_WscBeaconProbeRes +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_wsc_beacon_probe_res. */
+
+uint32_t dot11f_pack_ie_wsc_ie_opaque(tpAniSirGlobal pCtx,
+				    tDot11fIEWscIEOpaque *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_data;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0xf2;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x4;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+		*pnConsumed += pSrc->num_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wsc_ie_opaque. */
+
+uint32_t dot11f_pack_ie_wsc_probe_req(tpAniSirGlobal pCtx,
+				    tDot11fIEWscProbeReq *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_ie_wsc_probe_req(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x0;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0xf2;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x4;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_WscProbeReq +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_wsc_probe_req. */
+
+uint32_t dot11f_pack_ie_wsc_probe_res(tpAniSirGlobal pCtx,
+				    tDot11fIEWscProbeRes *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_ie_wsc_probe_res(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x0;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0xf2;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x4;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_WscProbeRes +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_wsc_probe_res. */
+
+uint32_t dot11f_pack_ie_wsc_reassoc_res(tpAniSirGlobal pCtx,
+				      tDot11fIEWscReassocRes *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t n, idx = 0, idxlast;
+	uint32_t nConsumedSoFar, nConsumedNow;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	uint32_t nNeeded = 0U;
+	status = dot11f_get_packed_ie_wsc_reassoc_res(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	if (nNeeded > nBuf)
+		return DOT11F_BUFFER_OVERFLOW;
+	(void)pCtx;
+	if (pSrc->present) {
+		do {
+			nConsumedSoFar = *pnConsumed;
+			*pBuf = 221;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			pIeLen = pBuf;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x0;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x50;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0xf2;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			*pBuf = 0x4;
+			++pBuf; --nBuf; ++(*pnConsumed);
+			n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+			nConsumedNow = *pnConsumed;
+			idxlast = idx;
+			status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+					       pnConsumed,
+					       TLVS_WscReassocRes +
+					       idx, &idx);
+			nConsumedNow = *pnConsumed - nConsumedNow;
+			*pIeLen = *pnConsumed - nConsumedSoFar - 2;
+			pBuf += nConsumedNow;
+			nBuf -= nConsumedNow;
+		} while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+	}
+	return status;
+} /* End dot11f_pack_ie_wsc_reassoc_res. */
+
+uint32_t dot11f_pack_ie_addba_extn_element(tpAniSirGlobal pCtx,
+					   tDot11fIEaddba_extn_element *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp169__;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 159;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp169__ = 0U;
+		tmp169__ |= (pSrc->no_fragmentation << 0);
+		tmp169__ |= (pSrc->he_frag_operation << 1);
+		tmp169__ |= (pSrc->reserved << 3);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp169__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_addba_extn_element. */
+
+uint32_t dot11f_pack_ie_bss_color_change(tpAniSirGlobal pCtx,
+					 tDot11fIEbss_color_change *pSrc,
+					 uint8_t *pBuf,
+					 uint32_t nBuf,
+					 uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp170__;
+	nNeeded  += 2;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 42;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->countdown;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp170__ = 0U;
+		tmp170__ |= (pSrc->new_color << 0);
+		tmp170__ |= (pSrc->reserved << 6);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp170__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_bss_color_change. */
+
+uint32_t dot11f_pack_ie_dh_parameter_element(tpAniSirGlobal pCtx,
+					     tDot11fIEdh_parameter_element *pSrc,
+					     uint8_t *pBuf,
+					     uint32_t nBuf,
+					     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_public_key + 2);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 32;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->group, 2);
+		*pnConsumed += 2;
+		pBuf += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->public_key), pSrc->num_public_key);
+		*pnConsumed += pSrc->num_public_key;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_dh_parameter_element. */
+
+uint32_t dot11f_pack_ie_esp_information(tpAniSirGlobal pCtx,
+					tDot11fIEesp_information *pSrc,
+					uint8_t *pBuf,
+					uint32_t nBuf,
+					uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_data;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 11;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+		*pnConsumed += pSrc->num_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_esp_information. */
+
+uint32_t dot11f_pack_ie_ext_chan_switch_ann(tpAniSirGlobal pCtx,
+					    tDot11fIEext_chan_switch_ann *pSrc,
+					    uint8_t *pBuf,
+					    uint32_t nBuf,
+					    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 4;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 60;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->switch_mode;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->new_reg_class;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->new_channel;
+		*pnConsumed += 1;
+		pBuf += 1;
+		*pBuf = pSrc->switch_count;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ext_chan_switch_ann. */
+
+uint32_t dot11f_pack_ie_fils_assoc_delay_info(tpAniSirGlobal pCtx,
+					      tDot11fIEfils_assoc_delay_info *pSrc,
+					      uint8_t *pBuf,
+					      uint32_t nBuf,
+					      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 1;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->assoc_delay_info;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fils_assoc_delay_info. */
+
+uint32_t dot11f_pack_ie_fils_hlp_container(tpAniSirGlobal pCtx,
+					   tDot11fIEfils_hlp_container *pSrc,
+					   uint8_t *pBuf,
+					   uint32_t nBuf,
+					   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_hlp_packet + 12);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 5;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->dest_mac, 6);
+		*pnConsumed += 6;
+		pBuf += 6;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->src_mac, 6);
+		*pnConsumed += 6;
+		pBuf += 6;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->hlp_packet), pSrc->num_hlp_packet);
+		*pnConsumed += pSrc->num_hlp_packet;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fils_hlp_container. */
+
+uint32_t dot11f_pack_ie_fils_indication(tpAniSirGlobal pCtx,
+					tDot11fIEfils_indication *pSrc,
+					uint8_t *pBuf,
+					uint32_t nBuf,
+					uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint16_t tmp171__;
+	nNeeded  +=  (pSrc->num_variable_data + 2);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 240;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp171__ = 0U;
+		tmp171__ |= (pSrc->public_key_identifiers_cnt << 0);
+		tmp171__ |= (pSrc->realm_identifiers_cnt << 3);
+		tmp171__ |= (pSrc->is_ip_config_supported << 6);
+		tmp171__ |= (pSrc->is_cache_id_present << 7);
+		tmp171__ |= (pSrc->is_hessid_present << 8);
+		tmp171__ |= (pSrc->is_fils_sk_auth_supported << 9);
+		tmp171__ |= (pSrc->is_fils_sk_auth_pfs_supported << 10);
+		tmp171__ |= (pSrc->is_pk_auth_supported << 11);
+		tmp171__ |= (pSrc->reserved << 12);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp171__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->variable_data), pSrc->num_variable_data);
+		*pnConsumed += pSrc->num_variable_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fils_indication. */
+
+uint32_t dot11f_pack_ie_fils_kde(tpAniSirGlobal pCtx,
+				 tDot11fIEfils_kde *pSrc,
+				 uint8_t *pBuf,
+				 uint32_t nBuf,
+				 uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_kde_list + 8);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 7;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->key_rsc, 8);
+		*pnConsumed += 8;
+		pBuf += 8;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->kde_list), pSrc->num_kde_list);
+		*pnConsumed += pSrc->num_kde_list;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fils_kde. */
+
+uint32_t dot11f_pack_ie_fils_key_confirmation(tpAniSirGlobal pCtx,
+					      tDot11fIEfils_key_confirmation *pSrc,
+					      uint8_t *pBuf,
+					      uint32_t nBuf,
+					      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_key_auth;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 3;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->key_auth), pSrc->num_key_auth);
+		*pnConsumed += pSrc->num_key_auth;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fils_key_confirmation. */
+
+uint32_t dot11f_pack_ie_fils_nonce(tpAniSirGlobal pCtx,
+				   tDot11fIEfils_nonce *pSrc,
+				   uint8_t *pBuf,
+				   uint32_t nBuf,
+				   uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 16;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 13;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->nonce, 16);
+		*pnConsumed += 16;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fils_nonce. */
+
+uint32_t dot11f_pack_ie_fils_public_key(tpAniSirGlobal pCtx,
+					tDot11fIEfils_public_key *pSrc,
+					uint8_t *pBuf,
+					uint32_t nBuf,
+					uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_public_key + 1);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 12;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->key_type;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->public_key), pSrc->num_public_key);
+		*pnConsumed += pSrc->num_public_key;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fils_public_key. */
+
+uint32_t dot11f_pack_ie_fils_session(tpAniSirGlobal pCtx,
+				     tDot11fIEfils_session *pSrc,
+				     uint8_t *pBuf,
+				     uint32_t nBuf,
+				     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 8;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 4;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->session, 8);
+		*pnConsumed += 8;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fils_session. */
+
+uint32_t dot11f_pack_ie_fils_wrapped_data(tpAniSirGlobal pCtx,
+					  tDot11fIEfils_wrapped_data *pSrc,
+					  uint8_t *pBuf,
+					  uint32_t nBuf,
+					  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_wrapped_data;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 8;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->wrapped_data), pSrc->num_wrapped_data);
+		*pnConsumed += pSrc->num_wrapped_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fils_wrapped_data. */
+
+uint32_t dot11f_pack_ie_fragment_ie(tpAniSirGlobal pCtx,
+				    tDot11fIEfragment_ie *pSrc,
+				    uint8_t *pBuf,
+				    uint32_t nBuf,
+				    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_data;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 242;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+		*pnConsumed += pSrc->num_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fragment_ie. */
+
+uint32_t dot11f_pack_ie_he_cap(tpAniSirGlobal pCtx,
+			       tDot11fIEhe_cap *pSrc,
+			       uint8_t *pBuf,
+			       uint32_t nBuf,
+			       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint32_t tmp172__;
+	uint16_t tmp173__;
+	uint32_t tmp174__;
+	uint32_t tmp175__;
+	uint16_t tmp176__;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ie_he_cap(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 35;
+		++pBuf; ++(*pnConsumed);
+		tmp172__ = 0U;
+		tmp172__ |= (pSrc->htc_he << 0);
+		tmp172__ |= (pSrc->twt_request << 1);
+		tmp172__ |= (pSrc->twt_responder << 2);
+		tmp172__ |= (pSrc->fragmentation << 3);
+		tmp172__ |= (pSrc->max_num_frag_msdu_amsdu_exp << 5);
+		tmp172__ |= (pSrc->min_frag_size << 8);
+		tmp172__ |= (pSrc->trigger_frm_mac_pad << 10);
+		tmp172__ |= (pSrc->multi_tid_aggr_rx_supp << 12);
+		tmp172__ |= (pSrc->he_link_adaptation << 15);
+		tmp172__ |= (pSrc->all_ack << 17);
+		tmp172__ |= (pSrc->trigd_rsp_sched << 18);
+		tmp172__ |= (pSrc->a_bsr << 19);
+		tmp172__ |= (pSrc->broadcast_twt << 20);
+		tmp172__ |= (pSrc->ba_32bit_bitmap << 21);
+		tmp172__ |= (pSrc->mu_cascade << 22);
+		tmp172__ |= (pSrc->ack_enabled_multitid << 23);
+		tmp172__ |= (pSrc->reserved << 24);
+		tmp172__ |= (pSrc->omi_a_ctrl << 25);
+		tmp172__ |= (pSrc->ofdma_ra << 26);
+		tmp172__ |= (pSrc->max_ampdu_len_exp_ext << 27);
+		tmp172__ |= (pSrc->amsdu_frag << 29);
+		tmp172__ |= (pSrc->flex_twt_sched << 30);
+		tmp172__ |= (pSrc->rx_ctrl_frame << 31);
+		if (unlikely(nBuf < 4))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtonl(pCtx, pBuf, tmp172__, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		nBuf -=  4 ;
+		tmp173__ = 0U;
+		tmp173__ |= (pSrc->bsrp_ampdu_aggr << 0);
+		tmp173__ |= (pSrc->qtp << 1);
+		tmp173__ |= (pSrc->a_bqr << 2);
+		tmp173__ |= (pSrc->spatial_reuse_param_rspder << 3);
+		tmp173__ |= (pSrc->ndp_feedback_supp << 4);
+		tmp173__ |= (pSrc->ops_supp << 5);
+		tmp173__ |= (pSrc->amsdu_in_ampdu << 6);
+		tmp173__ |= (pSrc->multi_tid_aggr_tx_supp << 7);
+		tmp173__ |= (pSrc->he_sub_ch_sel_tx_supp << 10);
+		tmp173__ |= (pSrc->ul_2x996_tone_ru_supp << 11);
+		tmp173__ |= (pSrc->om_ctrl_ul_mu_data_dis_rx << 12);
+		tmp173__ |= (pSrc->reserved1 << 13);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp173__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		tmp174__ = 0U;
+		tmp174__ |= (pSrc->reserved2 << 0);
+		tmp174__ |= (pSrc->chan_width_0 << 1);
+		tmp174__ |= (pSrc->chan_width_1 << 2);
+		tmp174__ |= (pSrc->chan_width_2 << 3);
+		tmp174__ |= (pSrc->chan_width_3 << 4);
+		tmp174__ |= (pSrc->chan_width_4 << 5);
+		tmp174__ |= (pSrc->chan_width_5 << 6);
+		tmp174__ |= (pSrc->chan_width_6 << 7);
+		tmp174__ |= (pSrc->rx_pream_puncturing << 8);
+		tmp174__ |= (pSrc->device_class << 12);
+		tmp174__ |= (pSrc->ldpc_coding << 13);
+		tmp174__ |= (pSrc->he_1x_ltf_800_gi_ppdu << 14);
+		tmp174__ |= (pSrc->midamble_tx_rx_max_nsts << 15);
+		tmp174__ |= (pSrc->he_4x_ltf_3200_gi_ndp << 17);
+		tmp174__ |= (pSrc->tx_stbc_lt_80mhz << 18);
+		tmp174__ |= (pSrc->rx_stbc_lt_80mhz << 19);
+		tmp174__ |= (pSrc->doppler << 20);
+		tmp174__ |= (pSrc->ul_mu << 22);
+		tmp174__ |= (pSrc->dcm_enc_tx << 24);
+		tmp174__ |= (pSrc->dcm_enc_rx << 27);
+		tmp174__ |= (pSrc->ul_he_mu << 30);
+		tmp174__ |= (pSrc->su_beamformer << 31);
+		if (unlikely(nBuf < 4))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtonl(pCtx, pBuf, tmp174__, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		nBuf -=  4 ;
+		tmp175__ = 0U;
+		tmp175__ |= (pSrc->su_beamformee << 0);
+		tmp175__ |= (pSrc->mu_beamformer << 1);
+		tmp175__ |= (pSrc->bfee_sts_lt_80 << 2);
+		tmp175__ |= (pSrc->bfee_sts_gt_80 << 5);
+		tmp175__ |= (pSrc->num_sounding_lt_80 << 8);
+		tmp175__ |= (pSrc->num_sounding_gt_80 << 11);
+		tmp175__ |= (pSrc->su_feedback_tone16 << 14);
+		tmp175__ |= (pSrc->mu_feedback_tone16 << 15);
+		tmp175__ |= (pSrc->codebook_su << 16);
+		tmp175__ |= (pSrc->codebook_mu << 17);
+		tmp175__ |= (pSrc->beamforming_feedback << 18);
+		tmp175__ |= (pSrc->he_er_su_ppdu << 21);
+		tmp175__ |= (pSrc->dl_mu_mimo_part_bw << 22);
+		tmp175__ |= (pSrc->ppet_present << 23);
+		tmp175__ |= (pSrc->srp << 24);
+		tmp175__ |= (pSrc->power_boost << 25);
+		tmp175__ |= (pSrc->he_ltf_800_gi_4x << 26);
+		tmp175__ |= (pSrc->max_nc << 27);
+		tmp175__ |= (pSrc->tx_stbc_gt_80mhz << 30);
+		tmp175__ |= (pSrc->rx_stbc_gt_80mhz << 31);
+		if (unlikely(nBuf < 4))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtonl(pCtx, pBuf, tmp175__, 0);
+		*pnConsumed += 4;
+		pBuf += 4;
+		nBuf -=  4 ;
+		tmp176__ = 0U;
+		tmp176__ |= (pSrc->er_he_ltf_800_gi_4x << 0);
+		tmp176__ |= (pSrc->he_ppdu_20_in_40Mhz_2G << 1);
+		tmp176__ |= (pSrc->he_ppdu_20_in_160_80p80Mhz << 2);
+		tmp176__ |= (pSrc->he_ppdu_80_in_160_80p80Mhz << 3);
+		tmp176__ |= (pSrc->er_1x_he_ltf_gi << 4);
+		tmp176__ |= (pSrc->midamble_tx_rx_1x_he_ltf << 5);
+		tmp176__ |= (pSrc->dcm_max_bw << 6);
+		tmp176__ |= (pSrc->longer_than_16_he_sigb_ofdm_sym << 8);
+		tmp176__ |= (pSrc->non_trig_cqi_feedback << 9);
+		tmp176__ |= (pSrc->tx_1024_qam_lt_242_tone_ru << 10);
+		tmp176__ |= (pSrc->rx_1024_qam_lt_242_tone_ru << 11);
+		tmp176__ |= (pSrc->rx_full_bw_su_he_mu_compress_sigb << 12);
+		tmp176__ |= (pSrc->rx_full_bw_su_he_mu_non_cmpr_sigb << 13);
+		tmp176__ |= (pSrc->reserved3 << 14);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp176__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		*pBuf = pSrc->reserved4;
+		*pnConsumed += 1;
+		pBuf += 1;
+		frameshtons(pCtx, pBuf, pSrc->rx_he_mcs_map_lt_80, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		frameshtons(pCtx, pBuf, pSrc->tx_he_mcs_map_lt_80, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->rx_he_mcs_map_160), (pSrc->chan_width_2 * 2));
+		*pnConsumed += (pSrc->chan_width_2 * 2);
+		pBuf += (pSrc->chan_width_2 * 2);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->tx_he_mcs_map_160), (pSrc->chan_width_2 * 2));
+		*pnConsumed += (pSrc->chan_width_2 * 2);
+		pBuf += (pSrc->chan_width_2 * 2);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->rx_he_mcs_map_80_80), (pSrc->chan_width_3 * 2));
+		*pnConsumed += (pSrc->chan_width_3 * 2);
+		pBuf += (pSrc->chan_width_3 * 2);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->tx_he_mcs_map_80_80), (pSrc->chan_width_3 * 2));
+		*pnConsumed += (pSrc->chan_width_3 * 2);
+		pBuf += (pSrc->chan_width_3 * 2);
+		if (pSrc->ppet_present) {
+			switch (pSrc->ppet_present) {
+			case 1:
+				DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->ppet.ppe_threshold.ppe_th), pSrc->ppet.ppe_threshold.num_ppe_th);
+				*pnConsumed += pSrc->ppet.ppe_threshold.num_ppe_th;
+				/* fieldsEndFlag = 1 */
+				break;
+			}
+		} else {
+			break;
+		}
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_he_cap. */
+
+uint32_t dot11f_pack_ie_he_op(tpAniSirGlobal pCtx,
+			      tDot11fIEhe_op *pSrc,
+			      uint8_t *pBuf,
+			      uint32_t nBuf,
+			      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint16_t tmp177__;
+	uint8_t tmp178__;
+	uint8_t tmp179__;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ie_he_op(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 36;
+		++pBuf; ++(*pnConsumed);
+		tmp177__ = 0U;
+		tmp177__ |= (pSrc->default_pe << 0);
+		tmp177__ |= (pSrc->twt_required << 3);
+		tmp177__ |= (pSrc->txop_rts_threshold << 4);
+		tmp177__ |= (pSrc->vht_oper_present << 14);
+		tmp177__ |= (pSrc->co_located_bss << 15);
+		if (unlikely(nBuf < 2))
+			return DOT11F_INCOMPLETE_IE;
+
+		frameshtons(pCtx, pBuf, tmp177__, 0);
+		*pnConsumed += 2;
+		pBuf += 2;
+		nBuf -=  2 ;
+		tmp178__ = 0U;
+		tmp178__ |= (pSrc->er_su_disable << 0);
+		tmp178__ |= (pSrc->reserved2 << 1);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp178__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp179__ = 0U;
+		tmp179__ |= (pSrc->bss_color << 0);
+		tmp179__ |= (pSrc->partial_bss_col << 6);
+		tmp179__ |= (pSrc->bss_col_disabled << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp179__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		DOT11F_MEMCPY(pCtx, pBuf, pSrc->basic_mcs_nss, 2);
+		*pnConsumed += 2;
+		pBuf += 2;
+		if (pSrc->vht_oper_present) {
+			switch (pSrc->vht_oper_present) {
+			case 1:
+				*pBuf = pSrc->vht_oper.info.chan_width;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->vht_oper.info.center_freq_seg0;
+				*pnConsumed += 1;
+				pBuf += 1;
+				*pBuf = pSrc->vht_oper.info.center_freq_seg1;
+				*pnConsumed += 1;
+				pBuf += 1;
+				break;
+			}
+		} else {
+			break;
+		}
+		if (pSrc->co_located_bss) {
+			switch (pSrc->co_located_bss) {
+			case 1:
+				*pBuf = pSrc->maxbssid_ind.info.data;
+				*pnConsumed += 1;
+				/* fieldsEndFlag = 1 */
+				break;
+			}
+		} else {
+			break;
+		}
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_he_op. */
+
+uint32_t dot11f_pack_ie_hs20vendor_ie(tpAniSirGlobal pCtx,
+				      tDot11fIEhs20vendor_ie *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp180__;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ie_hs20vendor_ie(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x6f;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x9a;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x10;
+		++pBuf; ++(*pnConsumed);
+		tmp180__ = 0U;
+		tmp180__ |= (pSrc->dgaf_dis << 0);
+		tmp180__ |= (pSrc->hs_id_present << 1);
+		tmp180__ |= (pSrc->reserved << 3);
+		tmp180__ |= (pSrc->release_num << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp180__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		if (pSrc->hs_id_present) {
+			switch (pSrc->hs_id_present) {
+			case 1:
+				frameshtons(pCtx, pBuf, pSrc->hs_id.pps_mo.pps_mo_id, 0);
+				*pnConsumed += 2;
+				/* fieldsEndFlag = 1 */
+				break;
+			case 2:
+				frameshtons(pCtx, pBuf, pSrc->hs_id.anqp_domain.anqp_domain_id, 0);
+				*pnConsumed += 2;
+				/* fieldsEndFlag = 1 */
+				break;
+			}
+		} else {
+			break;
+		}
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_hs20vendor_ie. */
+
+uint32_t dot11f_pack_ie_ht2040_bss_coexistence(tpAniSirGlobal pCtx,
+					       tDot11fIEht2040_bss_coexistence *pSrc,
+					       uint8_t *pBuf,
+					       uint32_t nBuf,
+					       uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp181__;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 72;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		tmp181__ = 0U;
+		tmp181__ |= (pSrc->info_request << 0);
+		tmp181__ |= (pSrc->forty_mhz_intolerant << 1);
+		tmp181__ |= (pSrc->twenty_mhz_bsswidth_req << 2);
+		tmp181__ |= (pSrc->obss_scan_exemption_req << 3);
+		tmp181__ |= (pSrc->obss_scan_exemption_grant << 4);
+		tmp181__ |= (pSrc->unused << 5);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp181__;
+		*pnConsumed += 1;
+		/* fieldsEndFlag  = 1 */
+		nBuf -=  1 ;
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ht2040_bss_coexistence. */
+
+uint32_t dot11f_pack_ie_ht2040_bss_intolerant_report(tpAniSirGlobal pCtx,
+						     tDot11fIEht2040_bss_intolerant_report *pSrc,
+						     uint8_t *pBuf,
+						     uint32_t nBuf,
+						     uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  (pSrc->num_channel_list + 1);
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 73;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->operating_class;
+		*pnConsumed += 1;
+		pBuf += 1;
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->channel_list), pSrc->num_channel_list);
+		*pnConsumed += pSrc->num_channel_list;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ht2040_bss_intolerant_report. */
+
+uint32_t dot11f_pack_ie_mu_edca_param_set(tpAniSirGlobal pCtx,
+					  tDot11fIEmu_edca_param_set *pSrc,
+					  uint8_t *pBuf,
+					  uint32_t nBuf,
+					  uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint8_t tmp182__;
+	uint8_t tmp183__;
+	uint8_t tmp184__;
+	uint8_t tmp185__;
+	uint8_t tmp186__;
+	uint8_t tmp187__;
+	uint8_t tmp188__;
+	uint8_t tmp189__;
+	nNeeded  += 13;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 255;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 38;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->qos;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp182__ = 0U;
+		tmp182__ |= (pSrc->acbe_aifsn << 0);
+		tmp182__ |= (pSrc->acbe_acm << 4);
+		tmp182__ |= (pSrc->acbe_aci << 5);
+		tmp182__ |= (pSrc->unused1 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp182__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp183__ = 0U;
+		tmp183__ |= (pSrc->acbe_acwmin << 0);
+		tmp183__ |= (pSrc->acbe_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp183__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		*pBuf = pSrc->acbe_muedca_timer;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp184__ = 0U;
+		tmp184__ |= (pSrc->acbk_aifsn << 0);
+		tmp184__ |= (pSrc->acbk_acm << 4);
+		tmp184__ |= (pSrc->acbk_aci << 5);
+		tmp184__ |= (pSrc->unused2 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp184__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp185__ = 0U;
+		tmp185__ |= (pSrc->acbk_acwmin << 0);
+		tmp185__ |= (pSrc->acbk_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp185__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		*pBuf = pSrc->acbk_muedca_timer;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp186__ = 0U;
+		tmp186__ |= (pSrc->acvi_aifsn << 0);
+		tmp186__ |= (pSrc->acvi_acm << 4);
+		tmp186__ |= (pSrc->acvi_aci << 5);
+		tmp186__ |= (pSrc->unused3 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp186__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp187__ = 0U;
+		tmp187__ |= (pSrc->acvi_acwmin << 0);
+		tmp187__ |= (pSrc->acvi_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp187__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		*pBuf = pSrc->acvi_muedca_timer;
+		*pnConsumed += 1;
+		pBuf += 1;
+		tmp188__ = 0U;
+		tmp188__ |= (pSrc->acvo_aifsn << 0);
+		tmp188__ |= (pSrc->acvo_acm << 4);
+		tmp188__ |= (pSrc->acvo_aci << 5);
+		tmp188__ |= (pSrc->unused4 << 7);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp188__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		tmp189__ = 0U;
+		tmp189__ |= (pSrc->acvo_acwmin << 0);
+		tmp189__ |= (pSrc->acvo_acwmax << 4);
+		if (unlikely(nBuf < 1))
+			return DOT11F_INCOMPLETE_IE;
+
+		*pBuf = tmp189__;
+		*pnConsumed += 1;
+		pBuf += 1;
+		nBuf -=  1 ;
+		*pBuf = pSrc->acvo_muedca_timer;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_mu_edca_param_set. */
+
+uint32_t dot11f_pack_ie_osen_ie(tpAniSirGlobal pCtx,
+				tDot11fIEosen_ie *pSrc,
+				uint8_t *pBuf,
+				uint32_t nBuf,
+				uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  +=  pSrc->num_data;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x50;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x6f;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x9a;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = 0x12;
+		++pBuf; ++(*pnConsumed);
+		DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+		*pnConsumed += pSrc->num_data;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_osen_ie. */
+
+uint32_t dot11f_pack_ie_sec_chan_offset_ele(tpAniSirGlobal pCtx,
+					    tDot11fIEsec_chan_offset_ele *pSrc,
+					    uint8_t *pBuf,
+					    uint32_t nBuf,
+					    uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	nNeeded  += 1;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 62;
+		++pBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; ++(*pnConsumed);
+		*pBuf = pSrc->secondaryChannelOffset;
+		*pnConsumed += 1;
+		/* fieldsEndFlag = 1 */
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_sec_chan_offset_ele. */
+
+uint32_t dot11f_pack_ie_vendor_vht_ie(tpAniSirGlobal pCtx,
+				      tDot11fIEvendor_vht_ie *pSrc,
+				      uint8_t *pBuf,
+				      uint32_t nBuf,
+				      uint32_t *pnConsumed)
+{
+	uint8_t *pIeLen = 0;
+	uint32_t nConsumedOnEntry = *pnConsumed;
+	uint32_t nNeeded = 0U;
+	uint32_t status = DOT11F_PARSE_SUCCESS;
+	status = dot11f_get_packed_ie_vendor_vht_ie(pCtx, pSrc, &nNeeded);
+	if (!DOT11F_SUCCEEDED(status))
+		return status;
+	while (pSrc->present) {
+		if (nNeeded > nBuf)
+			return DOT11F_BUFFER_OVERFLOW;
+		*pBuf = 221;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		pIeLen = pBuf;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		*pBuf = 0x0;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		*pBuf = 0x90;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		*pBuf = 0x4c;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		*pBuf = 0x4;
+		++pBuf; --nBuf; ++(*pnConsumed);
+		*pBuf = pSrc->sub_type;
+		*pnConsumed += 1;
+		pBuf += 1;
+		status = pack_core(pCtx,
+				(uint8_t *)pSrc,
+				pBuf,
+				nBuf,
+				pnConsumed,
+				FFS_vendor_vht_ie,
+				IES_vendor_vht_ie);
+		break;
+	}
+	(void)pCtx;
+	if (pIeLen) {
+		*pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+	}
+	return status;
+} /* End dot11f_pack_ie_vendor_vht_ie. */
+
+uint32_t dot11f_pack_add_ts_request(tpAniSirGlobal pCtx,
+	tDot11fAddTSRequest *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_AddTSRequest, IES_AddTSRequest);
+
+	return status;
+
+} /* End dot11f_unpack_add_ts_request. */
+
+uint32_t dot11f_pack_add_ts_response(tpAniSirGlobal pCtx,
+	tDot11fAddTSResponse *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_AddTSResponse, IES_AddTSResponse);
+
+	return status;
+
+} /* End dot11f_unpack_add_ts_response. */
+
+uint32_t dot11f_pack_assoc_request(tpAniSirGlobal pCtx,
+	tDot11fAssocRequest *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_AssocRequest, IES_AssocRequest);
+
+	return status;
+
+} /* End dot11f_unpack_assoc_request. */
+
+uint32_t dot11f_pack_assoc_response(tpAniSirGlobal pCtx,
+	tDot11fAssocResponse *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_AssocResponse, IES_AssocResponse);
+
+	return status;
+
+} /* End dot11f_unpack_assoc_response. */
+
+uint32_t dot11f_pack_authentication(tpAniSirGlobal pCtx,
+	tDot11fAuthentication *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_Authentication, IES_Authentication);
+
+	return status;
+
+} /* End dot11f_unpack_authentication. */
+
+uint32_t dot11f_pack_beacon(tpAniSirGlobal pCtx,
+	tDot11fBeacon *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_Beacon, IES_Beacon);
+
+	return status;
+
+} /* End dot11f_unpack_beacon. */
+
+uint32_t dot11f_pack_beacon1(tpAniSirGlobal pCtx,
+	tDot11fBeacon1 *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_Beacon1, IES_Beacon1);
+
+	return status;
+
+} /* End dot11f_unpack_beacon1. */
+
+uint32_t dot11f_pack_beacon2(tpAniSirGlobal pCtx,
+	tDot11fBeacon2 *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_Beacon2, IES_Beacon2);
+
+	return status;
+
+} /* End dot11f_unpack_beacon2. */
+
+uint32_t dot11f_pack_beacon_i_es(tpAniSirGlobal pCtx,
+	tDot11fBeaconIEs *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_BeaconIEs, IES_BeaconIEs);
+
+	return status;
+
+} /* End dot11f_unpack_beacon_i_es. */
+
+uint32_t dot11f_pack_channel_switch(tpAniSirGlobal pCtx,
+	tDot11fChannelSwitch *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_ChannelSwitch, IES_ChannelSwitch);
+
+	return status;
+
+} /* End dot11f_unpack_channel_switch. */
+
+uint32_t dot11f_pack_de_auth(tpAniSirGlobal pCtx,
+	tDot11fDeAuth *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_DeAuth, IES_DeAuth);
+
+	return status;
+
+} /* End dot11f_unpack_de_auth. */
+
+uint32_t dot11f_pack_del_ts(tpAniSirGlobal pCtx,
+	tDot11fDelTS *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_DelTS, IES_DelTS);
+
+	return status;
+
+} /* End dot11f_unpack_del_ts. */
+
+uint32_t dot11f_pack_disassociation(tpAniSirGlobal pCtx,
+	tDot11fDisassociation *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_Disassociation, IES_Disassociation);
+
+	return status;
+
+} /* End dot11f_unpack_disassociation. */
+
+uint32_t dot11f_pack_link_measurement_report(tpAniSirGlobal pCtx,
+	tDot11fLinkMeasurementReport *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_LinkMeasurementReport, IES_LinkMeasurementReport);
+
+	return status;
+
+} /* End dot11f_unpack_link_measurement_report. */
+
+uint32_t dot11f_pack_link_measurement_request(tpAniSirGlobal pCtx,
+	tDot11fLinkMeasurementRequest *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_LinkMeasurementRequest, IES_LinkMeasurementRequest);
+
+	return status;
+
+} /* End dot11f_unpack_link_measurement_request. */
+
+uint32_t dot11f_pack_measurement_report(tpAniSirGlobal pCtx,
+	tDot11fMeasurementReport *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_MeasurementReport, IES_MeasurementReport);
+
+	return status;
+
+} /* End dot11f_unpack_measurement_report. */
+
+uint32_t dot11f_pack_measurement_request(tpAniSirGlobal pCtx,
+	tDot11fMeasurementRequest *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_MeasurementRequest, IES_MeasurementRequest);
+
+	return status;
+
+} /* End dot11f_unpack_measurement_request. */
+
+uint32_t dot11f_pack_neighbor_report_request(tpAniSirGlobal pCtx,
+	tDot11fNeighborReportRequest *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_NeighborReportRequest, IES_NeighborReportRequest);
+
+	return status;
+
+} /* End dot11f_unpack_neighbor_report_request. */
+
+uint32_t dot11f_pack_neighbor_report_response(tpAniSirGlobal pCtx,
+	tDot11fNeighborReportResponse *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_NeighborReportResponse, IES_NeighborReportResponse);
+
+	return status;
+
+} /* End dot11f_unpack_neighbor_report_response. */
+
+uint32_t dot11f_pack_operating_mode(tpAniSirGlobal pCtx,
+	tDot11fOperatingMode *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_OperatingMode, IES_OperatingMode);
+
+	return status;
+
+} /* End dot11f_unpack_operating_mode. */
+
+uint32_t dot11f_pack_probe_request(tpAniSirGlobal pCtx,
+	tDot11fProbeRequest *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_ProbeRequest, IES_ProbeRequest);
+
+	return status;
+
+} /* End dot11f_unpack_probe_request. */
+
+uint32_t dot11f_pack_probe_response(tpAniSirGlobal pCtx,
+	tDot11fProbeResponse *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_ProbeResponse, IES_ProbeResponse);
+
+	return status;
+
+} /* End dot11f_unpack_probe_response. */
+
+uint32_t dot11f_pack_qos_map_configure(tpAniSirGlobal pCtx,
+	tDot11fQosMapConfigure *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_QosMapConfigure, IES_QosMapConfigure);
+
+	return status;
+
+} /* End dot11f_unpack_qos_map_configure. */
+
+uint32_t dot11f_pack_radio_measurement_report(tpAniSirGlobal pCtx,
+	tDot11fRadioMeasurementReport *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_RadioMeasurementReport, IES_RadioMeasurementReport);
+
+	return status;
+
+} /* End dot11f_unpack_radio_measurement_report. */
+
+uint32_t dot11f_pack_radio_measurement_request(tpAniSirGlobal pCtx,
+	tDot11fRadioMeasurementRequest *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_RadioMeasurementRequest, IES_RadioMeasurementRequest);
+
+	return status;
+
+} /* End dot11f_unpack_radio_measurement_request. */
+
+uint32_t dot11f_pack_re_assoc_request(tpAniSirGlobal pCtx,
+	tDot11fReAssocRequest *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_ReAssocRequest, IES_ReAssocRequest);
+
+	return status;
+
+} /* End dot11f_unpack_re_assoc_request. */
+
+uint32_t dot11f_pack_re_assoc_response(tpAniSirGlobal pCtx,
+	tDot11fReAssocResponse *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_ReAssocResponse, IES_ReAssocResponse);
+
+	return status;
+
+} /* End dot11f_unpack_re_assoc_response. */
+
+uint32_t dot11f_pack_sm_power_save(tpAniSirGlobal pCtx,
+	tDot11fSMPowerSave *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_SMPowerSave, IES_SMPowerSave);
+
+	return status;
+
+} /* End dot11f_unpack_sm_power_save. */
+
+uint32_t dot11f_pack_sa_query_req(tpAniSirGlobal pCtx,
+	tDot11fSaQueryReq *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_SaQueryReq, IES_SaQueryReq);
+
+	return status;
+
+} /* End dot11f_unpack_sa_query_req. */
+
+uint32_t dot11f_pack_sa_query_rsp(tpAniSirGlobal pCtx,
+	tDot11fSaQueryRsp *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_SaQueryRsp, IES_SaQueryRsp);
+
+	return status;
+
+} /* End dot11f_unpack_sa_query_rsp. */
+
+uint32_t dot11f_pack_tdls_dis_req(tpAniSirGlobal pCtx,
+	tDot11fTDLSDisReq *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_TDLSDisReq, IES_TDLSDisReq);
+
+	return status;
+
+} /* End dot11f_unpack_tdls_dis_req. */
+
+uint32_t dot11f_pack_tdls_dis_rsp(tpAniSirGlobal pCtx,
+	tDot11fTDLSDisRsp *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_TDLSDisRsp, IES_TDLSDisRsp);
+
+	return status;
+
+} /* End dot11f_unpack_tdls_dis_rsp. */
+
+uint32_t dot11f_pack_tdls_peer_traffic_ind(tpAniSirGlobal pCtx,
+	tDot11fTDLSPeerTrafficInd *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_TDLSPeerTrafficInd, IES_TDLSPeerTrafficInd);
+
+	return status;
+
+} /* End dot11f_unpack_tdls_peer_traffic_ind. */
+
+uint32_t dot11f_pack_tdls_peer_traffic_rsp(tpAniSirGlobal pCtx,
+	tDot11fTDLSPeerTrafficRsp *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_TDLSPeerTrafficRsp, IES_TDLSPeerTrafficRsp);
+
+	return status;
+
+} /* End dot11f_unpack_tdls_peer_traffic_rsp. */
+
+uint32_t dot11f_pack_tdls_setup_cnf(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupCnf *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_TDLSSetupCnf, IES_TDLSSetupCnf);
+
+	return status;
+
+} /* End dot11f_unpack_tdls_setup_cnf. */
+
+uint32_t dot11f_pack_tdls_setup_req(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupReq *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_TDLSSetupReq, IES_TDLSSetupReq);
+
+	return status;
+
+} /* End dot11f_unpack_tdls_setup_req. */
+
+uint32_t dot11f_pack_tdls_setup_rsp(tpAniSirGlobal pCtx,
+	tDot11fTDLSSetupRsp *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_TDLSSetupRsp, IES_TDLSSetupRsp);
+
+	return status;
+
+} /* End dot11f_unpack_tdls_setup_rsp. */
+
+uint32_t dot11f_pack_tdls_teardown(tpAniSirGlobal pCtx,
+	tDot11fTDLSTeardown *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_TDLSTeardown, IES_TDLSTeardown);
+
+	return status;
+
+} /* End dot11f_unpack_tdls_teardown. */
+
+uint32_t dot11f_pack_tpc_report(tpAniSirGlobal pCtx,
+	tDot11fTPCReport *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_TPCReport, IES_TPCReport);
+
+	return status;
+
+} /* End dot11f_unpack_tpc_report. */
+
+uint32_t dot11f_pack_tpc_request(tpAniSirGlobal pCtx,
+	tDot11fTPCRequest *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_TPCRequest, IES_TPCRequest);
+
+	return status;
+
+} /* End dot11f_unpack_tpc_request. */
+
+uint32_t dot11f_pack_timing_advertisement_frame(tpAniSirGlobal pCtx,
+	tDot11fTimingAdvertisementFrame *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_TimingAdvertisementFrame, IES_TimingAdvertisementFrame);
+
+	return status;
+
+} /* End dot11f_unpack_timing_advertisement_frame. */
+
+uint32_t dot11f_pack_vht_gid_management_action_frame(tpAniSirGlobal pCtx,
+	tDot11fVHTGidManagementActionFrame *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_VHTGidManagementActionFrame, IES_VHTGidManagementActionFrame);
+
+	return status;
+
+} /* End dot11f_unpack_vht_gid_management_action_frame. */
+
+uint32_t dot11f_pack_wmm_add_ts_request(tpAniSirGlobal pCtx,
+	tDot11fWMMAddTSRequest *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_WMMAddTSRequest, IES_WMMAddTSRequest);
+
+	return status;
+
+} /* End dot11f_unpack_wmm_add_ts_request. */
+
+uint32_t dot11f_pack_wmm_add_ts_response(tpAniSirGlobal pCtx,
+	tDot11fWMMAddTSResponse *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_WMMAddTSResponse, IES_WMMAddTSResponse);
+
+	return status;
+
+} /* End dot11f_unpack_wmm_add_ts_response. */
+
+uint32_t dot11f_pack_wmm_del_ts(tpAniSirGlobal pCtx,
+	tDot11fWMMDelTS *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_WMMDelTS, IES_WMMDelTS);
+
+	return status;
+
+} /* End dot11f_unpack_wmm_del_ts. */
+
+uint32_t dot11f_pack_addba_req(tpAniSirGlobal pCtx,
+	tDot11faddba_req *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_addba_req, IES_addba_req);
+
+	return status;
+
+} /* End dot11f_unpack_addba_req. */
+
+uint32_t dot11f_pack_addba_rsp(tpAniSirGlobal pCtx,
+	tDot11faddba_rsp *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_addba_rsp, IES_addba_rsp);
+
+	return status;
+
+} /* End dot11f_unpack_addba_rsp. */
+
+uint32_t dot11f_pack_delba_req(tpAniSirGlobal pCtx,
+	tDot11fdelba_req *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_delba_req, IES_delba_req);
+
+	return status;
+
+} /* End dot11f_unpack_delba_req. */
+
+uint32_t dot11f_pack_ext_channel_switch_action_frame(tpAniSirGlobal pCtx,
+	tDot11fext_channel_switch_action_frame *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_ext_channel_switch_action_frame, IES_ext_channel_switch_action_frame);
+
+	return status;
+
+} /* End dot11f_unpack_ext_channel_switch_action_frame. */
+
+uint32_t dot11f_pack_ht2040_bss_coexistence_mgmt_action_frame(tpAniSirGlobal pCtx,
+	tDot11fht2040_bss_coexistence_mgmt_action_frame *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_ht2040_bss_coexistence_mgmt_action_frame, IES_ht2040_bss_coexistence_mgmt_action_frame);
+
+	return status;
+
+} /* End dot11f_unpack_ht2040_bss_coexistence_mgmt_action_frame. */
+
+uint32_t dot11f_pack_p2p_oper_chan_change_confirm(tpAniSirGlobal pCtx,
+	tDot11fp2p_oper_chan_change_confirm *pFrm,
+	uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+	uint32_t i = 0;
+	uint32_t status = 0;
+	(void)i;
+	*pnConsumed = 0U;
+	status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+			   FFS_p2p_oper_chan_change_confirm, IES_p2p_oper_chan_change_confirm);
+
+	return status;
+
+} /* End dot11f_unpack_p2p_oper_chan_change_confirm. */
+
+static uint32_t pack_core(tpAniSirGlobal pCtx,
+			   uint8_t *pSrc,
+			   uint8_t *pBuf,
+			   uint32_t  nBuf,
+			   uint32_t *pnConsumed,
+			   const tFFDefn  FFs[],
+			   const tIEDefn  IEs[])
+{
+	const tFFDefn *pFf;
+	const tIEDefn *pIe;
+	tFRAMES_BOOL  *pfFound;
+	uint8_t   *pBufRemaining;
+	uint16_t  i;
+	uint32_t  nBufRemaining, status, len;
+	uint32_t  countOffset = 0;
+
+	(void)pCtx; /* Shutup the compiler if we have no FFs nor IEs... */
+	i = 0;
+
+	DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed);
+
+	status = DOT11F_PARSE_SUCCESS;
+	pBufRemaining = pBuf;
+	nBufRemaining = nBuf;
+
+	pFf = &(FFs[0]);
+	while (pFf->size) {
+		if (pFf->size > nBufRemaining) {
+			FRAMES_LOG3(pCtx, FRLOGE, FRFL("The Fixed Field %s req"
+				"uires %d bytes, but there are only %d remaining.\n"),
+				pFf->name, pFf->size, nBufRemaining);
+			return DOT11F_BUFFER_OVERFLOW;
+		}
+
+		switch (pFf->sig) {
+		case SigFfAID:
+			dot11f_pack_ff_aid(
+				pCtx, (tDot11fFfAID *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfAction:
+			dot11f_pack_ff_action(
+				pCtx, (tDot11fFfAction *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfAuthAlgo:
+			dot11f_pack_ff_auth_algo(
+				pCtx, (tDot11fFfAuthAlgo *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfAuthSeqNo:
+			dot11f_pack_ff_auth_seq_no(
+				pCtx, (tDot11fFfAuthSeqNo *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfBeaconInterval:
+			dot11f_pack_ff_beacon_interval(
+				pCtx, (tDot11fFfBeaconInterval *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfCapabilities:
+			dot11f_pack_ff_capabilities(
+				pCtx, (tDot11fFfCapabilities *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfCategory:
+			dot11f_pack_ff_category(
+				pCtx, (tDot11fFfCategory *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfCurrentAPAddress:
+			dot11f_pack_ff_current_ap_address(
+				pCtx, (tDot11fFfCurrentAPAddress *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfDialogToken:
+			dot11f_pack_ff_dialog_token(
+				pCtx, (tDot11fFfDialogToken *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfLinkMargin:
+			dot11f_pack_ff_link_margin(
+				pCtx, (tDot11fFfLinkMargin *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfListenInterval:
+			dot11f_pack_ff_listen_interval(
+				pCtx, (tDot11fFfListenInterval *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfMaxTxPower:
+			dot11f_pack_ff_max_tx_power(
+				pCtx, (tDot11fFfMaxTxPower *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfNumOfRepetitions:
+			dot11f_pack_ff_num_of_repetitions(
+				pCtx, (tDot11fFfNumOfRepetitions *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfOperatingMode:
+			dot11f_pack_ff_operating_mode(
+				pCtx, (tDot11fFfOperatingMode *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfRCPI:
+			dot11f_pack_ff_rcpi(
+				pCtx, (tDot11fFfRCPI *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfRSNI:
+			dot11f_pack_ff_rsni(
+				pCtx, (tDot11fFfRSNI *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfReason:
+			dot11f_pack_ff_reason(
+				pCtx, (tDot11fFfReason *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfRxAntennaId:
+			dot11f_pack_ff_rx_antenna_id(
+				pCtx, (tDot11fFfRxAntennaId *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfSMPowerModeSet:
+			dot11f_pack_ff_sm_power_mode_set(
+				pCtx, (tDot11fFfSMPowerModeSet *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfStatus:
+			dot11f_pack_ff_status(
+				pCtx, (tDot11fFfStatus *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfStatusCode:
+			dot11f_pack_ff_status_code(
+				pCtx, (tDot11fFfStatusCode *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfTPCEleID:
+			dot11f_pack_ff_tpc_ele_id(
+				pCtx, (tDot11fFfTPCEleID *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfTPCEleLen:
+			dot11f_pack_ff_tpc_ele_len(
+				pCtx, (tDot11fFfTPCEleLen *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfTSInfo:
+			dot11f_pack_ff_ts_info(
+				pCtx, (tDot11fFfTSInfo *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfTimeStamp:
+			dot11f_pack_ff_time_stamp(
+				pCtx, (tDot11fFfTimeStamp *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfTransactionId:
+			dot11f_pack_ff_transaction_id(
+				pCtx, (tDot11fFfTransactionId *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfTxAntennaId:
+			dot11f_pack_ff_tx_antenna_id(
+				pCtx, (tDot11fFfTxAntennaId *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfTxPower:
+			dot11f_pack_ff_tx_power(
+				pCtx, (tDot11fFfTxPower *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfVhtMembershipStatusArray:
+			dot11f_pack_ff_vht_membership_status_array(
+				pCtx, (tDot11fFfVhtMembershipStatusArray *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfVhtUserPositionArray:
+			dot11f_pack_ff_vht_user_position_array(
+				pCtx, (tDot11fFfVhtUserPositionArray *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfaddba_param_set:
+			dot11f_pack_ff_addba_param_set(
+				pCtx, (tDot11fFfaddba_param_set *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfba_start_seq_ctrl:
+			dot11f_pack_ff_ba_start_seq_ctrl(
+				pCtx, (tDot11fFfba_start_seq_ctrl *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfba_timeout:
+			dot11f_pack_ff_ba_timeout(
+				pCtx, (tDot11fFfba_timeout *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfdelba_param_set:
+			dot11f_pack_ff_delba_param_set(
+				pCtx, (tDot11fFfdelba_param_set *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfext_chan_switch_ann_action:
+			dot11f_pack_ff_ext_chan_switch_ann_action(
+				pCtx, (tDot11fFfext_chan_switch_ann_action *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfp2p_action_oui:
+			dot11f_pack_ff_p2p_action_oui(
+				pCtx, (tDot11fFfp2p_action_oui *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		case SigFfp2p_action_subtype:
+			dot11f_pack_ff_p2p_action_subtype(
+				pCtx, (tDot11fFfp2p_action_subtype *)
+				(pSrc + pFf->offset), pBufRemaining);
+			break;
+		default:
+			FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don"
+				"'t know about the Fixed Field %d; this is most l"
+				"ikely a bug in 'framesg'.\n"), pFf->sig);
+			return DOT11F_INTERNAL_ERROR;
+		}
+
+		pBufRemaining += pFf->size;
+		nBufRemaining -= pFf->size;
+		*pnConsumed   += pFf->size;
+		++pFf;
+
+	}
+
+	pIe = &(IEs[0]);
+	while (0xff != pIe->eid || pIe->extn_eid) {
+		pfFound = (tFRAMES_BOOL *)(pSrc + pIe->offset +
+				pIe->presenceOffset);
+		if (*pfFound && pIe->minSize > nBufRemaining) {
+			FRAMES_LOG3(pCtx, FRLOGE, FRFL("The IE %s takes at le"
+				"ast %d bytes, but there are only %d left in the b"
+				"uffer.\n"), pIe->name, pIe->minSize, nBufRemaining);
+			return DOT11F_BUFFER_OVERFLOW;
+		}
+
+
+		countOffset = ((0 == pIe->arraybound) ?  1 : *(uint16_t *)(pSrc + pIe->countOffset));
+		for (i = 0; i < countOffset; ++i) {
+			len = 0U;
+			switch (pIe->sig) {
+			case SigIeGTK:
+			status |=
+				dot11f_pack_ie_gtk(
+				pCtx, (tDot11fIEGTK *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEGTK) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeIGTK:
+			status |=
+				dot11f_pack_ie_igtk(
+				pCtx, (tDot11fIEIGTK *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEIGTK) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeR0KH_ID:
+			status |=
+				dot11f_pack_ie_r0_kh_id(
+				pCtx, (tDot11fIER0KH_ID *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIER0KH_ID) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeR1KH_ID:
+			status |=
+				dot11f_pack_ie_r1_kh_id(
+				pCtx, (tDot11fIER1KH_ID *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIER1KH_ID) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeAPChannelReport:
+			status |=
+				dot11f_pack_ie_ap_channel_report(
+				pCtx, (tDot11fIEAPChannelReport *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEAPChannelReport) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeBcnReportingDetail:
+			status |=
+				dot11f_pack_ie_bcn_reporting_detail(
+				pCtx, (tDot11fIEBcnReportingDetail *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEBcnReportingDetail) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeBeaconReportFrmBody:
+			status |=
+				dot11f_pack_ie_beacon_report_frm_body(
+				pCtx, (tDot11fIEBeaconReportFrmBody *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEBeaconReportFrmBody) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeBeaconReporting:
+			status |=
+				dot11f_pack_ie_beacon_reporting(
+				pCtx, (tDot11fIEBeaconReporting *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEBeaconReporting) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeCondensedCountryStr:
+			status |=
+				dot11f_pack_ie_condensed_country_str(
+				pCtx, (tDot11fIECondensedCountryStr *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIECondensedCountryStr) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeMeasurementPilot:
+			status |=
+				dot11f_pack_ie_measurement_pilot(
+				pCtx, (tDot11fIEMeasurementPilot *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEMeasurementPilot) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeMultiBssid:
+			status |=
+				dot11f_pack_ie_multi_bssid(
+				pCtx, (tDot11fIEMultiBssid *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEMultiBssid) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeRICData:
+			status |=
+				dot11f_pack_ie_ric_data(
+				pCtx, (tDot11fIERICData *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIERICData) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeRICDescriptor:
+			status |=
+				dot11f_pack_ie_ric_descriptor(
+				pCtx, (tDot11fIERICDescriptor *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIERICDescriptor) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeRRMEnabledCap:
+			status |=
+				dot11f_pack_ie_rrm_enabled_cap(
+				pCtx, (tDot11fIERRMEnabledCap *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIERRMEnabledCap) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeRequestedInfo:
+			status |=
+				dot11f_pack_ie_requested_info(
+				pCtx, (tDot11fIERequestedInfo *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIERequestedInfo) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeSSID:
+			status |=
+				dot11f_pack_ie_ssid(
+				pCtx, (tDot11fIESSID *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIESSID) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeSchedule:
+			status |=
+				dot11f_pack_ie_schedule(
+				pCtx, (tDot11fIESchedule *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIESchedule) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeTCLAS:
+			status |=
+				dot11f_pack_ie_tclas(
+				pCtx, (tDot11fIETCLAS *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIETCLAS) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeTCLASSPROC:
+			status |=
+				dot11f_pack_ie_tclassproc(
+				pCtx, (tDot11fIETCLASSPROC *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIETCLASSPROC) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeTSDelay:
+			status |=
+				dot11f_pack_ie_ts_delay(
+				pCtx, (tDot11fIETSDelay *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIETSDelay) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeTSFInfo:
+			status |=
+				dot11f_pack_ie_tsf_info(
+				pCtx, (tDot11fIETSFInfo *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIETSFInfo) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeTSPEC:
+			status |=
+				dot11f_pack_ie_tspec(
+				pCtx, (tDot11fIETSPEC *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIETSPEC) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeVHTCaps:
+			status |=
+				dot11f_pack_ie_vht_caps(
+				pCtx, (tDot11fIEVHTCaps *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEVHTCaps) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeVHTOperation:
+			status |=
+				dot11f_pack_ie_vht_operation(
+				pCtx, (tDot11fIEVHTOperation *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEVHTOperation) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWMMSchedule:
+			status |=
+				dot11f_pack_ie_wmm_schedule(
+				pCtx, (tDot11fIEWMMSchedule *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWMMSchedule) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWMMTCLAS:
+			status |=
+				dot11f_pack_ie_wmmtclas(
+				pCtx, (tDot11fIEWMMTCLAS *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWMMTCLAS) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWMMTCLASPROC:
+			status |=
+				dot11f_pack_ie_wmmtclasproc(
+				pCtx, (tDot11fIEWMMTCLASPROC *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWMMTCLASPROC) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWMMTSDelay:
+			status |=
+				dot11f_pack_ie_wmmts_delay(
+				pCtx, (tDot11fIEWMMTSDelay *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWMMTSDelay) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWMMTSPEC:
+			status |=
+				dot11f_pack_ie_wmmtspec(
+				pCtx, (tDot11fIEWMMTSPEC *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWMMTSPEC) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWiderBWChanSwitchAnn:
+			status |=
+				dot11f_pack_ie_wider_bw_chan_switch_ann(
+				pCtx, (tDot11fIEWiderBWChanSwitchAnn *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWiderBWChanSwitchAnn) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeazimuth_req:
+			status |=
+				dot11f_pack_ie_azimuth_req(
+				pCtx, (tDot11fIEazimuth_req *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEazimuth_req) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIebeacon_report_frm_body_fragment_id:
+			status |=
+				dot11f_pack_ie_beacon_report_frm_body_fragment_id(
+				pCtx, (tDot11fIEbeacon_report_frm_body_fragment_id *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEbeacon_report_frm_body_fragment_id) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIelast_beacon_report_indication:
+			status |=
+				dot11f_pack_ie_last_beacon_report_indication(
+				pCtx, (tDot11fIElast_beacon_report_indication *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIElast_beacon_report_indication) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIemax_age:
+			status |=
+				dot11f_pack_ie_max_age(
+				pCtx, (tDot11fIEmax_age *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEmax_age) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeneighbor_rpt:
+			status |=
+				dot11f_pack_ie_neighbor_rpt(
+				pCtx, (tDot11fIEneighbor_rpt *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEneighbor_rpt) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIereq_mac_addr:
+			status |=
+				dot11f_pack_ie_req_mac_addr(
+				pCtx, (tDot11fIEreq_mac_addr *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEreq_mac_addr) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIetgt_mac_addr:
+			status |=
+				dot11f_pack_ie_tgt_mac_addr(
+				pCtx, (tDot11fIEtgt_mac_addr *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEtgt_mac_addr) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIevht_transmit_power_env:
+			status |=
+				dot11f_pack_ie_vht_transmit_power_env(
+				pCtx, (tDot11fIEvht_transmit_power_env *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEvht_transmit_power_env) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeAID:
+			status |=
+				dot11f_pack_ie_aid(
+				pCtx, (tDot11fIEAID *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEAID) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeCFParams:
+			status |=
+				dot11f_pack_ie_cf_params(
+				pCtx, (tDot11fIECFParams *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIECFParams) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeChallengeText:
+			status |=
+				dot11f_pack_ie_challenge_text(
+				pCtx, (tDot11fIEChallengeText *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEChallengeText) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeChanSwitchAnn:
+			status |=
+				dot11f_pack_ie_chan_switch_ann(
+				pCtx, (tDot11fIEChanSwitchAnn *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEChanSwitchAnn) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeChannelSwitchWrapper:
+			status |=
+				dot11f_pack_ie_channel_switch_wrapper(
+				pCtx, (tDot11fIEChannelSwitchWrapper *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEChannelSwitchWrapper) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeCountry:
+			status |=
+				dot11f_pack_ie_country(
+				pCtx, (tDot11fIECountry *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIECountry) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeDSParams:
+			status |=
+				dot11f_pack_ie_ds_params(
+				pCtx, (tDot11fIEDSParams *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEDSParams) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeEDCAParamSet:
+			status |=
+				dot11f_pack_ie_edca_param_set(
+				pCtx, (tDot11fIEEDCAParamSet *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEEDCAParamSet) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeERPInfo:
+			status |=
+				dot11f_pack_ie_erp_info(
+				pCtx, (tDot11fIEERPInfo *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEERPInfo) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeESECckmOpaque:
+			status |=
+				dot11f_pack_ie_ese_cckm_opaque(
+				pCtx, (tDot11fIEESECckmOpaque *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEESECckmOpaque) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeESERadMgmtCap:
+			status |=
+				dot11f_pack_ie_ese_rad_mgmt_cap(
+				pCtx, (tDot11fIEESERadMgmtCap *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEESERadMgmtCap) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeESETrafStrmMet:
+			status |=
+				dot11f_pack_ie_ese_traf_strm_met(
+				pCtx, (tDot11fIEESETrafStrmMet *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEESETrafStrmMet) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeESETrafStrmRateSet:
+			status |=
+				dot11f_pack_ie_ese_traf_strm_rate_set(
+				pCtx, (tDot11fIEESETrafStrmRateSet *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEESETrafStrmRateSet) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeESETxmitPower:
+			status |=
+				dot11f_pack_ie_ese_txmit_power(
+				pCtx, (tDot11fIEESETxmitPower *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEESETxmitPower) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeESEVersion:
+			status |=
+				dot11f_pack_ie_ese_version(
+				pCtx, (tDot11fIEESEVersion *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEESEVersion) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeExtCap:
+			status |=
+				dot11f_pack_ie_ext_cap(
+				pCtx, (tDot11fIEExtCap *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEExtCap) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeExtSuppRates:
+			status |=
+				dot11f_pack_ie_ext_supp_rates(
+				pCtx, (tDot11fIEExtSuppRates *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEExtSuppRates) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeFHParamSet:
+			status |=
+				dot11f_pack_ie_fh_param_set(
+				pCtx, (tDot11fIEFHParamSet *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEFHParamSet) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeFHParams:
+			status |=
+				dot11f_pack_ie_fh_params(
+				pCtx, (tDot11fIEFHParams *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEFHParams) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeFHPattTable:
+			status |=
+				dot11f_pack_ie_fh_patt_table(
+				pCtx, (tDot11fIEFHPattTable *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEFHPattTable) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeFTInfo:
+			status |=
+				dot11f_pack_ie_ft_info(
+				pCtx, (tDot11fIEFTInfo *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEFTInfo) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeHTCaps:
+			status |=
+				dot11f_pack_ie_ht_caps(
+				pCtx, (tDot11fIEHTCaps *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEHTCaps) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeHTInfo:
+			status |=
+				dot11f_pack_ie_ht_info(
+				pCtx, (tDot11fIEHTInfo *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEHTInfo) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeIBSSParams:
+			status |=
+				dot11f_pack_ie_ibss_params(
+				pCtx, (tDot11fIEIBSSParams *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEIBSSParams) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeLinkIdentifier:
+			status |=
+				dot11f_pack_ie_link_identifier(
+				pCtx, (tDot11fIELinkIdentifier *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIELinkIdentifier) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeMBO_IE:
+			status |=
+				dot11f_pack_ie_MBO_IE(
+				pCtx, (tDot11fIEMBO_IE *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEMBO_IE) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeMeasurementReport:
+			status |=
+				dot11f_pack_ie_measurement_report(
+				pCtx, (tDot11fIEMeasurementReport *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEMeasurementReport) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeMeasurementRequest:
+			status |=
+				dot11f_pack_ie_measurement_request(
+				pCtx, (tDot11fIEMeasurementRequest *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEMeasurementRequest) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeMobilityDomain:
+			status |=
+				dot11f_pack_ie_mobility_domain(
+				pCtx, (tDot11fIEMobilityDomain *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEMobilityDomain) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeNeighborReport:
+			status |=
+				dot11f_pack_ie_neighbor_report(
+				pCtx, (tDot11fIENeighborReport *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIENeighborReport) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeOBSSScanParameters:
+			status |=
+				dot11f_pack_ie_obss_scan_parameters(
+				pCtx, (tDot11fIEOBSSScanParameters *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEOBSSScanParameters) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeOperatingMode:
+			status |=
+				dot11f_pack_ie_operating_mode(
+				pCtx, (tDot11fIEOperatingMode *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEOperatingMode) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeP2PAssocReq:
+			status |=
+				dot11f_pack_ie_p2_p_assoc_req(
+				pCtx, (tDot11fIEP2PAssocReq *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEP2PAssocReq) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeP2PAssocRes:
+			status |=
+				dot11f_pack_ie_p2_p_assoc_res(
+				pCtx, (tDot11fIEP2PAssocRes *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEP2PAssocRes) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeP2PBeacon:
+			status |=
+				dot11f_pack_ie_p2_p_beacon(
+				pCtx, (tDot11fIEP2PBeacon *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEP2PBeacon) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeP2PBeaconProbeRes:
+			status |=
+				dot11f_pack_ie_p2_p_beacon_probe_res(
+				pCtx, (tDot11fIEP2PBeaconProbeRes *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEP2PBeaconProbeRes) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeP2PDeAuth:
+			status |=
+				dot11f_pack_ie_p2_p_de_auth(
+				pCtx, (tDot11fIEP2PDeAuth *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEP2PDeAuth) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeP2PDisAssoc:
+			status |=
+				dot11f_pack_ie_p2_p_dis_assoc(
+				pCtx, (tDot11fIEP2PDisAssoc *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEP2PDisAssoc) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeP2PIEOpaque:
+			status |=
+				dot11f_pack_ie_p2_pie_opaque(
+				pCtx, (tDot11fIEP2PIEOpaque *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEP2PIEOpaque) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeP2PProbeReq:
+			status |=
+				dot11f_pack_ie_p2_p_probe_req(
+				pCtx, (tDot11fIEP2PProbeReq *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEP2PProbeReq) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeP2PProbeRes:
+			status |=
+				dot11f_pack_ie_p2_p_probe_res(
+				pCtx, (tDot11fIEP2PProbeRes *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEP2PProbeRes) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIePTIControl:
+			status |=
+				dot11f_pack_ie_pti_control(
+				pCtx, (tDot11fIEPTIControl *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEPTIControl) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIePUBufferStatus:
+			status |=
+				dot11f_pack_ie_pu_buffer_status(
+				pCtx, (tDot11fIEPUBufferStatus *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEPUBufferStatus) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIePowerCaps:
+			status |=
+				dot11f_pack_ie_power_caps(
+				pCtx, (tDot11fIEPowerCaps *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEPowerCaps) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIePowerConstraints:
+			status |=
+				dot11f_pack_ie_power_constraints(
+				pCtx, (tDot11fIEPowerConstraints *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEPowerConstraints) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeQBSSLoad:
+			status |=
+				dot11f_pack_ie_qbss_load(
+				pCtx, (tDot11fIEQBSSLoad *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEQBSSLoad) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeQCN_IE:
+			status |=
+				dot11f_pack_ie_QCN_IE(
+				pCtx, (tDot11fIEQCN_IE *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEQCN_IE) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeQComVendorIE:
+			status |=
+				dot11f_pack_ie_QComVendorIE(
+				pCtx, (tDot11fIEQComVendorIE *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEQComVendorIE) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeQOSCapsAp:
+			status |=
+				dot11f_pack_ie_qos_caps_ap(
+				pCtx, (tDot11fIEQOSCapsAp *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEQOSCapsAp) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeQOSCapsStation:
+			status |=
+				dot11f_pack_ie_qos_caps_station(
+				pCtx, (tDot11fIEQOSCapsStation *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEQOSCapsStation) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeQosMapSet:
+			status |=
+				dot11f_pack_ie_qos_map_set(
+				pCtx, (tDot11fIEQosMapSet *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEQosMapSet) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeQuiet:
+			status |=
+				dot11f_pack_ie_quiet(
+				pCtx, (tDot11fIEQuiet *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEQuiet) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeRCPIIE:
+			status |=
+				dot11f_pack_ie_rcpiie(
+				pCtx, (tDot11fIERCPIIE *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIERCPIIE) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeRICDataDesc:
+			status |=
+				dot11f_pack_ie_ric_data_desc(
+				pCtx, (tDot11fIERICDataDesc *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIERICDataDesc) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeRSN:
+			status |=
+				dot11f_pack_ie_rsn(
+				pCtx, (tDot11fIERSN *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIERSN) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeRSNIIE:
+			status |=
+				dot11f_pack_ie_rsniie(
+				pCtx, (tDot11fIERSNIIE *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIERSNIIE) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeRSNOpaque:
+			status |=
+				dot11f_pack_ie_rsn_opaque(
+				pCtx, (tDot11fIERSNOpaque *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIERSNOpaque) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeSuppChannels:
+			status |=
+				dot11f_pack_ie_supp_channels(
+				pCtx, (tDot11fIESuppChannels *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIESuppChannels) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeSuppOperatingClasses:
+			status |=
+				dot11f_pack_ie_supp_operating_classes(
+				pCtx, (tDot11fIESuppOperatingClasses *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIESuppOperatingClasses) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeSuppRates:
+			status |=
+				dot11f_pack_ie_supp_rates(
+				pCtx, (tDot11fIESuppRates *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIESuppRates) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeTIM:
+			status |=
+				dot11f_pack_ie_tim(
+				pCtx, (tDot11fIETIM *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIETIM) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeTPCReport:
+			status |=
+				dot11f_pack_ie_tpc_report(
+				pCtx, (tDot11fIETPCReport *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIETPCReport) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeTPCRequest:
+			status |=
+				dot11f_pack_ie_tpc_request(
+				pCtx, (tDot11fIETPCRequest *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIETPCRequest) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeTimeAdvertisement:
+			status |=
+				dot11f_pack_ie_time_advertisement(
+				pCtx, (tDot11fIETimeAdvertisement *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIETimeAdvertisement) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeTimeoutInterval:
+			status |=
+				dot11f_pack_ie_timeout_interval(
+				pCtx, (tDot11fIETimeoutInterval *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIETimeoutInterval) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeVHTExtBssLoad:
+			status |=
+				dot11f_pack_ie_vht_ext_bss_load(
+				pCtx, (tDot11fIEVHTExtBssLoad *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEVHTExtBssLoad) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeVendor1IE:
+			status |=
+				dot11f_pack_ie_vendor1_ie(
+				pCtx, (tDot11fIEVendor1IE *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEVendor1IE) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeVendor3IE:
+			status |=
+				dot11f_pack_ie_vendor3_ie(
+				pCtx, (tDot11fIEVendor3IE *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEVendor3IE) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWAPI:
+			status |=
+				dot11f_pack_ie_wapi(
+				pCtx, (tDot11fIEWAPI *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWAPI) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWAPIOpaque:
+			status |=
+				dot11f_pack_ie_wapi_opaque(
+				pCtx, (tDot11fIEWAPIOpaque *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWAPIOpaque) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWFATPC:
+			status |=
+				dot11f_pack_ie_wfatpc(
+				pCtx, (tDot11fIEWFATPC *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWFATPC) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWFDIEOpaque:
+			status |=
+				dot11f_pack_ie_wfdie_opaque(
+				pCtx, (tDot11fIEWFDIEOpaque *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWFDIEOpaque) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWMMCaps:
+			status |=
+				dot11f_pack_ie_wmm_caps(
+				pCtx, (tDot11fIEWMMCaps *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWMMCaps) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWMMInfoAp:
+			status |=
+				dot11f_pack_ie_wmm_info_ap(
+				pCtx, (tDot11fIEWMMInfoAp *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWMMInfoAp) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWMMInfoStation:
+			status |=
+				dot11f_pack_ie_wmm_info_station(
+				pCtx, (tDot11fIEWMMInfoStation *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWMMInfoStation) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWMMParams:
+			status |=
+				dot11f_pack_ie_wmm_params(
+				pCtx, (tDot11fIEWMMParams *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWMMParams) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWPA:
+			status |=
+				dot11f_pack_ie_wpa(
+				pCtx, (tDot11fIEWPA *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWPA) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWPAOpaque:
+			status |=
+				dot11f_pack_ie_wpa_opaque(
+				pCtx, (tDot11fIEWPAOpaque *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWPAOpaque) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWSC:
+			status |=
+				dot11f_pack_ie_wsc(
+				pCtx, (tDot11fIEWSC *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWSC) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWscAssocReq:
+			status |=
+				dot11f_pack_ie_wsc_assoc_req(
+				pCtx, (tDot11fIEWscAssocReq *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWscAssocReq) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWscAssocRes:
+			status |=
+				dot11f_pack_ie_wsc_assoc_res(
+				pCtx, (tDot11fIEWscAssocRes *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWscAssocRes) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWscBeacon:
+			status |=
+				dot11f_pack_ie_wsc_beacon(
+				pCtx, (tDot11fIEWscBeacon *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWscBeacon) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWscBeaconProbeRes:
+			status |=
+				dot11f_pack_ie_wsc_beacon_probe_res(
+				pCtx, (tDot11fIEWscBeaconProbeRes *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWscBeaconProbeRes) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWscIEOpaque:
+			status |=
+				dot11f_pack_ie_wsc_ie_opaque(
+				pCtx, (tDot11fIEWscIEOpaque *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWscIEOpaque) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWscProbeReq:
+			status |=
+				dot11f_pack_ie_wsc_probe_req(
+				pCtx, (tDot11fIEWscProbeReq *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWscProbeReq) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWscProbeRes:
+			status |=
+				dot11f_pack_ie_wsc_probe_res(
+				pCtx, (tDot11fIEWscProbeRes *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWscProbeRes) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeWscReassocRes:
+			status |=
+				dot11f_pack_ie_wsc_reassoc_res(
+				pCtx, (tDot11fIEWscReassocRes *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEWscReassocRes) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeaddba_extn_element:
+			status |=
+				dot11f_pack_ie_addba_extn_element(
+				pCtx, (tDot11fIEaddba_extn_element *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEaddba_extn_element) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIebss_color_change:
+			status |=
+				dot11f_pack_ie_bss_color_change(
+				pCtx, (tDot11fIEbss_color_change *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEbss_color_change) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIedh_parameter_element:
+			status |=
+				dot11f_pack_ie_dh_parameter_element(
+				pCtx, (tDot11fIEdh_parameter_element *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEdh_parameter_element) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeesp_information:
+			status |=
+				dot11f_pack_ie_esp_information(
+				pCtx, (tDot11fIEesp_information *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEesp_information) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeext_chan_switch_ann:
+			status |=
+				dot11f_pack_ie_ext_chan_switch_ann(
+				pCtx, (tDot11fIEext_chan_switch_ann *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEext_chan_switch_ann) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIefils_assoc_delay_info:
+			status |=
+				dot11f_pack_ie_fils_assoc_delay_info(
+				pCtx, (tDot11fIEfils_assoc_delay_info *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEfils_assoc_delay_info) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIefils_hlp_container:
+			status |=
+				dot11f_pack_ie_fils_hlp_container(
+				pCtx, (tDot11fIEfils_hlp_container *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEfils_hlp_container) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIefils_indication:
+			status |=
+				dot11f_pack_ie_fils_indication(
+				pCtx, (tDot11fIEfils_indication *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEfils_indication) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIefils_kde:
+			status |=
+				dot11f_pack_ie_fils_kde(
+				pCtx, (tDot11fIEfils_kde *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEfils_kde) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIefils_key_confirmation:
+			status |=
+				dot11f_pack_ie_fils_key_confirmation(
+				pCtx, (tDot11fIEfils_key_confirmation *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEfils_key_confirmation) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIefils_nonce:
+			status |=
+				dot11f_pack_ie_fils_nonce(
+				pCtx, (tDot11fIEfils_nonce *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEfils_nonce) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIefils_public_key:
+			status |=
+				dot11f_pack_ie_fils_public_key(
+				pCtx, (tDot11fIEfils_public_key *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEfils_public_key) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIefils_session:
+			status |=
+				dot11f_pack_ie_fils_session(
+				pCtx, (tDot11fIEfils_session *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEfils_session) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIefils_wrapped_data:
+			status |=
+				dot11f_pack_ie_fils_wrapped_data(
+				pCtx, (tDot11fIEfils_wrapped_data *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEfils_wrapped_data) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIefragment_ie:
+			status |=
+				dot11f_pack_ie_fragment_ie(
+				pCtx, (tDot11fIEfragment_ie *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEfragment_ie) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIehe_cap:
+			status |=
+				dot11f_pack_ie_he_cap(
+				pCtx, (tDot11fIEhe_cap *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEhe_cap) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIehe_op:
+			status |=
+				dot11f_pack_ie_he_op(
+				pCtx, (tDot11fIEhe_op *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEhe_op) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIehs20vendor_ie:
+			status |=
+				dot11f_pack_ie_hs20vendor_ie(
+				pCtx, (tDot11fIEhs20vendor_ie *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEhs20vendor_ie) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeht2040_bss_coexistence:
+			status |=
+				dot11f_pack_ie_ht2040_bss_coexistence(
+				pCtx, (tDot11fIEht2040_bss_coexistence *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEht2040_bss_coexistence) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeht2040_bss_intolerant_report:
+			status |=
+				dot11f_pack_ie_ht2040_bss_intolerant_report(
+				pCtx, (tDot11fIEht2040_bss_intolerant_report *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEht2040_bss_intolerant_report) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIemu_edca_param_set:
+			status |=
+				dot11f_pack_ie_mu_edca_param_set(
+				pCtx, (tDot11fIEmu_edca_param_set *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEmu_edca_param_set) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIeosen_ie:
+			status |=
+				dot11f_pack_ie_osen_ie(
+				pCtx, (tDot11fIEosen_ie *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEosen_ie) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIesec_chan_offset_ele:
+			status |=
+				dot11f_pack_ie_sec_chan_offset_ele(
+				pCtx, (tDot11fIEsec_chan_offset_ele *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEsec_chan_offset_ele) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			case SigIevendor_vht_ie:
+			status |=
+				dot11f_pack_ie_vendor_vht_ie(
+				pCtx, (tDot11fIEvendor_vht_ie *)
+				(pSrc + pIe->offset +
+				sizeof(tDot11fIEvendor_vht_ie) * i),
+				pBufRemaining, nBufRemaining, &len);
+			break;
+			default:
+				FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don"
+				"'t know about the IE %d; this is most likely a b"
+				"ug in 'framesc'.\n"), pFf->sig);
+				return DOT11F_INTERNAL_ERROR;
+			}
+
+			pBufRemaining += len;
+			nBufRemaining -= len;
+			*pnConsumed   += len;
+		}
+
+		++pIe;
+
+	}
+
+	return status;
+
+}
+
+static uint32_t pack_tlv_core(tpAniSirGlobal pCtx,
+				uint8_t *pSrc,
+				uint8_t *pBuf,
+				uint32_t  nBuf,
+				uint32_t *pnConsumed,
+				const tTLVDefn  TLVs[],
+				uint32_t *pidx)
+{
+	const tTLVDefn *pTlv;
+	tFRAMES_BOOL   *pfFound;
+	uint8_t    *pBufRemaining;
+	uint32_t   nBufRemaining, status, len;
+
+	DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed);
+
+	(void)pCtx;
+	status = DOT11F_PARSE_SUCCESS;
+	pBufRemaining = pBuf;
+	nBufRemaining = nBuf;
+
+	pTlv = &(TLVs[0]);
+	while (0xffff != pTlv->id) {
+		pfFound = (tFRAMES_BOOL *)(pSrc + pTlv->offset +
+					pTlv->presenceOffset);
+		if (*pfFound && pTlv->minSize > nBufRemaining) {
+			FRAMES_LOG3(pCtx, FRLOGE, FRFL("The TLV %s takes at least"
+			    " %d bytes, but there are only %d left in the buffer."
+			    "\n"), pTlv->name, pTlv->minSize, nBufRemaining);
+			return DOT11F_BUFFER_OVERFLOW;
+		}
+
+		len = 0U;
+
+		if (*pfFound) {
+			switch (pTlv->sig) {
+			case SigTlvAuthorizedMACs:
+				status |=
+					dot11f_pack_tlv_authorized_ma_cs(
+					pCtx, (tDot11fTLVAuthorizedMACs *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvRequestToEnroll:
+				status |=
+					dot11f_pack_tlv_request_to_enroll(
+					pCtx, (tDot11fTLVRequestToEnroll *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvVersion2:
+				status |=
+					dot11f_pack_tlv_version2(
+					pCtx, (tDot11fTLVVersion2 *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvAPSetupLocked:
+				status |=
+					dot11f_pack_tlv_ap_setup_locked(
+					pCtx, (tDot11fTLVAPSetupLocked *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvAssociationState:
+				status |=
+					dot11f_pack_tlv_association_state(
+					pCtx, (tDot11fTLVAssociationState *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvConfigMethods:
+				status |=
+					dot11f_pack_tlv_config_methods(
+					pCtx, (tDot11fTLVConfigMethods *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvConfigurationError:
+				status |=
+					dot11f_pack_tlv_configuration_error(
+					pCtx, (tDot11fTLVConfigurationError *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvDeviceName:
+				status |=
+					dot11f_pack_tlv_device_name(
+					pCtx, (tDot11fTLVDeviceName *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvDevicePasswordID:
+				status |=
+					dot11f_pack_tlv_device_password_id(
+					pCtx, (tDot11fTLVDevicePasswordID *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvExtendedListenTiming:
+				status |=
+					dot11f_pack_tlv_extended_listen_timing(
+					pCtx, (tDot11fTLVExtendedListenTiming *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvListenChannel:
+				status |=
+					dot11f_pack_tlv_listen_channel(
+					pCtx, (tDot11fTLVListenChannel *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvManufacturer:
+				status |=
+					dot11f_pack_tlv_manufacturer(
+					pCtx, (tDot11fTLVManufacturer *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvMinorReasonCode:
+				status |=
+					dot11f_pack_tlv_minor_reason_code(
+					pCtx, (tDot11fTLVMinorReasonCode *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvModelName:
+				status |=
+					dot11f_pack_tlv_model_name(
+					pCtx, (tDot11fTLVModelName *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvModelNumber:
+				status |=
+					dot11f_pack_tlv_model_number(
+					pCtx, (tDot11fTLVModelNumber *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvNoticeOfAbsence:
+				status |=
+					dot11f_pack_tlv_notice_of_absence(
+					pCtx, (tDot11fTLVNoticeOfAbsence *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvOperatingChannel:
+				status |=
+					dot11f_pack_tlv_operating_channel(
+					pCtx, (tDot11fTLVOperatingChannel *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvP2PCapability:
+				status |=
+					dot11f_pack_tlv_p2_p_capability(
+					pCtx, (tDot11fTLVP2PCapability *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvP2PDeviceId:
+				status |=
+					dot11f_pack_tlv_p2_p_device_id(
+					pCtx, (tDot11fTLVP2PDeviceId *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvP2PDeviceInfo:
+				status |=
+					dot11f_pack_tlv_p2_p_device_info(
+					pCtx, (tDot11fTLVP2PDeviceInfo *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvP2PGroupInfo:
+				status |=
+					dot11f_pack_tlv_p2_p_group_info(
+					pCtx, (tDot11fTLVP2PGroupInfo *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvP2PStatus:
+				status |=
+					dot11f_pack_tlv_p2_p_status(
+					pCtx, (tDot11fTLVP2PStatus *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvPrimaryDeviceType:
+				status |=
+					dot11f_pack_tlv_primary_device_type(
+					pCtx, (tDot11fTLVPrimaryDeviceType *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvRFBands:
+				status |=
+					dot11f_pack_tlv_rf_bands(
+					pCtx, (tDot11fTLVRFBands *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvRequestDeviceType:
+				status |=
+					dot11f_pack_tlv_request_device_type(
+					pCtx, (tDot11fTLVRequestDeviceType *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvRequestType:
+				status |=
+					dot11f_pack_tlv_request_type(
+					pCtx, (tDot11fTLVRequestType *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvResponseType:
+				status |=
+					dot11f_pack_tlv_response_type(
+					pCtx, (tDot11fTLVResponseType *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvSelectedRegistrar:
+				status |=
+					dot11f_pack_tlv_selected_registrar(
+					pCtx, (tDot11fTLVSelectedRegistrar *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvSelectedRegistrarConfigMethods:
+				status |=
+					dot11f_pack_tlv_selected_registrar_config_methods(
+					pCtx, (tDot11fTLVSelectedRegistrarConfigMethods *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvSerialNumber:
+				status |=
+					dot11f_pack_tlv_serial_number(
+					pCtx, (tDot11fTLVSerialNumber *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvUUID_E:
+				status |=
+					dot11f_pack_tlv_uuid_e(
+					pCtx, (tDot11fTLVUUID_E *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvUUID_R:
+				status |=
+					dot11f_pack_tlv_uuid_r(
+					pCtx, (tDot11fTLVUUID_R *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvVendorExtension:
+				status |=
+					dot11f_pack_tlv_vendor_extension(
+					pCtx, (tDot11fTLVVendorExtension *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvVersion:
+				status |=
+					dot11f_pack_tlv_version(
+					pCtx, (tDot11fTLVVersion *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvWPSState:
+				status |=
+					dot11f_pack_tlv_wps_state(
+					pCtx, (tDot11fTLVWPSState *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvassoc_disallowed:
+				status |=
+					dot11f_pack_tlv_assoc_disallowed(
+					pCtx, (tDot11fTLVassoc_disallowed *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvassoc_retry_delay:
+				status |=
+					dot11f_pack_tlv_assoc_retry_delay(
+					pCtx, (tDot11fTLVassoc_retry_delay *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvcellular_data_cap:
+				status |=
+					dot11f_pack_tlv_cellular_data_cap(
+					pCtx, (tDot11fTLVcellular_data_cap *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvcellular_data_con_pref:
+				status |=
+					dot11f_pack_tlv_cellular_data_con_pref(
+					pCtx, (tDot11fTLVcellular_data_con_pref *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvmbo_ap_cap:
+				status |=
+					dot11f_pack_tlv_mbo_ap_cap(
+					pCtx, (tDot11fTLVmbo_ap_cap *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvnon_prefferd_chan_rep:
+				status |=
+					dot11f_pack_tlv_non_prefferd_chan_rep(
+					pCtx, (tDot11fTLVnon_prefferd_chan_rep *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvoce_cap:
+				status |=
+					dot11f_pack_tlv_oce_cap(
+					pCtx, (tDot11fTLVoce_cap *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvreduced_wan_metrics:
+				status |=
+					dot11f_pack_tlv_reduced_wan_metrics(
+					pCtx, (tDot11fTLVreduced_wan_metrics *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvrssi_assoc_rej:
+				status |=
+					dot11f_pack_tlv_rssi_assoc_rej(
+					pCtx, (tDot11fTLVrssi_assoc_rej *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvtransition_reason:
+				status |=
+					dot11f_pack_tlv_transition_reason(
+					pCtx, (tDot11fTLVtransition_reason *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvtransition_reject_reason:
+				status |=
+					dot11f_pack_tlv_transition_reject_reason(
+					pCtx, (tDot11fTLVtransition_reject_reason *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvP2PInterface:
+				status |=
+					dot11f_pack_tlv_p2_p_interface(
+					pCtx, (tDot11fTLVP2PInterface *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			case SigTlvP2PManageability:
+				status |=
+					dot11f_pack_tlv_p2_p_manageability(
+					pCtx, (tDot11fTLVP2PManageability *)
+					(pSrc + pTlv->offset), pBufRemaining,
+					nBufRemaining, &len);
+				break;
+			default:
+				FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don't "
+				    "know about the TLV %d; this is most likely a bug in "
+				    "'framesc'.\n"), pTlv->sig);
+				return DOT11F_INTERNAL_ERROR;
+			}
+
+		} /* End if on *pfFound */
+		pBufRemaining += len;
+		nBufRemaining -= len;
+		*pnConsumed   += len;
+		++pTlv;
+		if (len)
+			++*pidx;
+	}
+
+	return status;
+
+}
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
new file mode 100644
index 0000000..b0e08bb
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
@@ -0,0 +1,824 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/**=========================================================================
+
+   \file  mac_trace.c
+
+   \brief implementation for trace related APIs
+
+   \author Sunit Bhatia
+
+   ========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+
+#include "mac_trace.h"
+#include "wma_types.h"
+#include "csr_neighbor_roam.h"
+#include "csr_internal.h"
+#include "lim_global.h"
+#include "lim_types.h"
+#include "qdf_mem.h"
+#include "qdf_trace.h"
+#include "wma_if.h"
+
+/**
+ * mac_trace_get_neighbour_roam_state() - Get the neighbor roam state
+ * @neighbourroamstate: State in numeric form
+ *
+ * This function will return a string equivalent of the state.
+ *
+ * Return: String equivalent of the state.
+ **/
+uint8_t *mac_trace_get_neighbour_roam_state(uint16_t neighbourroamstate)
+{
+	switch (neighbourroamstate) {
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CLOSED);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_INIT);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
+		CASE_RETURN_STRING(eNEIGHBOR_STATE_MAX);
+
+	default:
+		return (uint8_t *) "UNKNOWN";
+		break;
+	}
+}
+
+/**
+ * mac_trace_getcsr_roam_state() - Get the csr roam state
+ * @csr_roam_state: State in numeric form
+ *
+ * This function will return a string equivalent of the state.
+ *
+ * Return: String equivalent of the state.
+ **/
+uint8_t *mac_trace_getcsr_roam_state(uint16_t csr_roam_state)
+{
+	switch (csr_roam_state) {
+		CASE_RETURN_STRING(eCSR_ROAMING_STATE_STOP);
+		CASE_RETURN_STRING(eCSR_ROAMING_STATE_IDLE);
+		CASE_RETURN_STRING(eCSR_ROAMING_STATE_JOINING);
+		CASE_RETURN_STRING(eCSR_ROAMING_STATE_JOINED);
+
+	default:
+		return (uint8_t *) "UNKNOWN";
+		break;
+	}
+}
+
+/**
+ * mac_trace_getcsr_roam_sub_state() - Get the csr roam sub state
+ * @csr_roam_sub_state: State in numeric form
+ *
+ * This function will return a string equivalent of the state.
+ *
+ * Return: String equivalent of the state.
+ **/
+uint8_t *mac_trace_getcsr_roam_sub_state(uint16_t csr_roam_sub_state)
+{
+	switch (csr_roam_sub_state) {
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_NONE);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_START_BSS_REQ);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOIN_REQ);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_REASSOC_REQ);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_REQ);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
+		CASE_RETURN_STRING
+			(eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_AUTH_REQ);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_CONFIG);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DEAUTH_REQ);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_FORCED);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC);
+		CASE_RETURN_STRING
+			(eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC);
+		CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC);
+
+	default:
+		return (uint8_t *) "UNKNOWN";
+		break;
+	}
+}
+
+/**
+ * mac_trace_get_lim_sme_state() - Get the lim sme state
+ * @lim_state: State in numeric form
+ *
+ * This function will return a string equivalent of the state.
+ *
+ * Return: String equivalent of the state.
+ **/
+uint8_t *mac_trace_get_lim_sme_state(uint16_t lim_state)
+{
+	switch (lim_state) {
+		CASE_RETURN_STRING(eLIM_SME_OFFLINE_STATE);
+		CASE_RETURN_STRING(eLIM_SME_IDLE_STATE);
+		CASE_RETURN_STRING(eLIM_SME_SUSPEND_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_SCAN_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_JOIN_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_AUTH_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_ASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_SME_JOIN_FAILURE_STATE);
+		CASE_RETURN_STRING(eLIM_SME_ASSOCIATED_STATE);
+		CASE_RETURN_STRING(eLIM_SME_REASSOCIATED_STATE);
+		CASE_RETURN_STRING(eLIM_SME_LINK_EST_STATE);
+		CASE_RETURN_STRING(eLIM_SME_LINK_EST_WT_SCAN_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_PRE_AUTH_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_DISASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_DEAUTH_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_START_BSS_STATE);
+		CASE_RETURN_STRING(eLIM_SME_WT_STOP_BSS_STATE);
+		CASE_RETURN_STRING(eLIM_SME_NORMAL_STATE);
+		CASE_RETURN_STRING(eLIM_SME_CHANNEL_SCAN_STATE);
+		CASE_RETURN_STRING(eLIM_SME_NORMAL_CHANNEL_SCAN_STATE);
+
+	default:
+		return (uint8_t *) "UNKNOWN";
+		break;
+	}
+}
+
+/**
+ * mac_trace_get_lim_mlm_state() - Get the lim mlm state
+ * @mlmstate: State in numeric form
+ *
+ * This function will return a string equivalent of the state.
+ *
+ * Return: String equivalent of the state.
+ **/
+uint8_t *mac_trace_get_lim_mlm_state(uint16_t mlm_state)
+{
+	switch (mlm_state) {
+		CASE_RETURN_STRING(eLIM_MLM_OFFLINE_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_IDLE_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_PROBE_RESP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_PASSIVE_SCAN_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_JOIN_BEACON_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_JOINED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_BSS_STARTED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME2_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME3_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME4_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_AUTH_RSP_TIMEOUT_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_AUTHENTICATED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_REASSOC_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_ASSOCIATED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_REASSOCIATED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_LINK_ESTABLISHED_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_CNF_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_LEARN_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_DEL_BSS_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_ADD_STA_RSP_STATE);
+		CASE_RETURN_STRING(eLIM_MLM_WT_DEL_STA_RSP_STATE);
+
+	default:
+		return (uint8_t *) "UNKNOWN";
+		break;
+	}
+}
+
+#ifdef TRACE_RECORD
+/**
+ * mac_trace_get_sme_msg_string() - Get the msg
+ * @sme_msg: message type in numeric form
+ *
+ * This function will return a string equivalent of the message.
+ *
+ * Return: String equivalent of the message type.
+ **/
+uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg)
+{
+	switch (sme_msg) {
+		CASE_RETURN_STRING(eWNI_SME_SYS_READY_IND);
+		CASE_RETURN_STRING(eWNI_SME_JOIN_REQ);
+		CASE_RETURN_STRING(eWNI_SME_JOIN_RSP);
+		CASE_RETURN_STRING(eWNI_SME_SETCONTEXT_REQ);
+		CASE_RETURN_STRING(eWNI_SME_SETCONTEXT_RSP);
+		CASE_RETURN_STRING(eWNI_SME_REASSOC_REQ);
+		CASE_RETURN_STRING(eWNI_SME_REASSOC_RSP);
+		CASE_RETURN_STRING(eWNI_SME_DISASSOC_REQ);
+		CASE_RETURN_STRING(eWNI_SME_DISASSOC_RSP);
+		CASE_RETURN_STRING(eWNI_SME_DISASSOC_IND);
+		CASE_RETURN_STRING(eWNI_SME_DISASSOC_CNF);
+		CASE_RETURN_STRING(eWNI_SME_DEAUTH_REQ);
+		CASE_RETURN_STRING(eWNI_SME_DEAUTH_RSP);
+		CASE_RETURN_STRING(eWNI_SME_DEAUTH_IND);
+		CASE_RETURN_STRING(eWNI_SME_DISCONNECT_DONE_IND);
+		CASE_RETURN_STRING(eWNI_SME_WM_STATUS_CHANGE_NTF);
+		CASE_RETURN_STRING(eWNI_SME_IBSS_NEW_PEER_IND);
+		CASE_RETURN_STRING(eWNI_SME_IBSS_PEER_DEPARTED_IND);
+		CASE_RETURN_STRING(eWNI_SME_START_BSS_REQ);
+		CASE_RETURN_STRING(eWNI_SME_START_BSS_RSP);
+		CASE_RETURN_STRING(eWNI_SME_ASSOC_IND);
+		CASE_RETURN_STRING(eWNI_SME_ASSOC_CNF);
+		CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_IND);
+		CASE_RETURN_STRING(eWNI_SME_STOP_BSS_REQ);
+		CASE_RETURN_STRING(eWNI_SME_STOP_BSS_RSP);
+		CASE_RETURN_STRING(eWNI_SME_DEAUTH_CNF);
+		CASE_RETURN_STRING(eWNI_SME_MIC_FAILURE_IND);
+		CASE_RETURN_STRING(eWNI_SME_ADDTS_REQ);
+		CASE_RETURN_STRING(eWNI_SME_ADDTS_RSP);
+		CASE_RETURN_STRING(eWNI_SME_DELTS_REQ);
+		CASE_RETURN_STRING(eWNI_SME_DELTS_RSP);
+		CASE_RETURN_STRING(eWNI_SME_DELTS_IND);
+		CASE_RETURN_STRING(eWNI_SME_GET_STATISTICS_REQ);
+		CASE_RETURN_STRING(eWNI_SME_GET_STATISTICS_RSP);
+		CASE_RETURN_STRING(eWNI_SME_GET_RSSI_REQ);
+		CASE_RETURN_STRING(eWNI_SME_GET_ASSOC_STAS_REQ);
+		CASE_RETURN_STRING(eWNI_SME_WPS_PBC_PROBE_REQ_IND);
+		CASE_RETURN_STRING(eWNI_SME_UPPER_LAYER_ASSOC_CNF);
+		CASE_RETURN_STRING(eWNI_SME_SESSION_UPDATE_PARAM);
+		CASE_RETURN_STRING(eWNI_SME_CHNG_MCC_BEACON_INTERVAL);
+		CASE_RETURN_STRING(eWNI_SME_CLEAR_DFS_CHANNEL_LIST);
+		CASE_RETURN_STRING(eWNI_SME_GET_SNR_REQ);
+		CASE_RETURN_STRING(eWNI_SME_LINK_STATUS_IND);
+		CASE_RETURN_STRING(eWNI_SME_RRM_MSG_TYPE_BEGIN);
+		CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_REPORT_REQ_IND);
+		CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_REPORT_IND);
+		CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_REQ_IND);
+		CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_RESP_XMIT_IND);
+		CASE_RETURN_STRING(eWNI_SME_ADD_STA_SELF_RSP);
+		CASE_RETURN_STRING(eWNI_SME_DEL_STA_SELF_RSP);
+		CASE_RETURN_STRING(eWNI_SME_FT_PRE_AUTH_REQ);
+		CASE_RETURN_STRING(eWNI_SME_FT_PRE_AUTH_RSP);
+		CASE_RETURN_STRING(eWNI_SME_FT_UPDATE_KEY);
+		CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_REQ);
+		CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_RSP);
+#if defined FEATURE_WLAN_ESE
+		CASE_RETURN_STRING(eWNI_SME_ESE_ADJACENT_AP_REPORT);
+#endif
+		CASE_RETURN_STRING(eWNI_SME_REGISTER_MGMT_FRAME_REQ);
+		CASE_RETURN_STRING(eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE);
+		CASE_RETURN_STRING(eWNI_SME_MAX_ASSOC_EXCEEDED);
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+		CASE_RETURN_STRING(eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP);
+#endif /* WLAN_FEATURE_GTK_OFFLOAD */
+		CASE_RETURN_STRING(eWNI_SME_ROAM_SCAN_OFFLOAD_RSP);
+		CASE_RETURN_STRING(eWNI_SME_IBSS_PEER_INFO_RSP);
+		CASE_RETURN_STRING(eWNI_SME_DFS_RADAR_FOUND);
+		CASE_RETURN_STRING(eWNI_SME_CHANNEL_CHANGE_REQ);
+		CASE_RETURN_STRING(eWNI_SME_CHANNEL_CHANGE_RSP);
+		CASE_RETURN_STRING(eWNI_SME_START_BEACON_REQ);
+		CASE_RETURN_STRING(eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ);
+		CASE_RETURN_STRING(eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND);
+		CASE_RETURN_STRING(eWNI_SME_STATS_EXT_EVENT);
+		CASE_RETURN_STRING(eWNI_SME_CSA_OFFLOAD_EVENT);
+		CASE_RETURN_STRING(eWNI_SME_UPDATE_ADDITIONAL_IES);
+		CASE_RETURN_STRING(eWNI_SME_MODIFY_ADDITIONAL_IES);
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+		CASE_RETURN_STRING(eWNI_SME_AUTO_SHUTDOWN_IND);
+#endif
+		CASE_RETURN_STRING(eWNI_SME_SET_HT_2040_MODE);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		CASE_RETURN_STRING(eWNI_SME_HO_FAIL_IND);
+#endif
+#ifdef FEATURE_WLAN_TDLS
+		CASE_RETURN_STRING(eWNI_SME_TDLS_SEND_MGMT_REQ);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_SEND_MGMT_RSP);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_ADD_STA_REQ);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_ADD_STA_RSP);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_DEL_STA_REQ);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_DEL_STA_RSP);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_DEL_STA_IND);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_DEL_ALL_PEER_IND);
+		CASE_RETURN_STRING(eWNI_SME_MGMT_FRM_TX_COMPLETION_IND);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_LINK_ESTABLISH_REQ);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_LINK_ESTABLISH_RSP);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_SHOULD_DISCOVER);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_SHOULD_TEARDOWN);
+		CASE_RETURN_STRING(eWNI_SME_TDLS_PEER_DISCONNECTED);
+		CASE_RETURN_STRING
+			(eWNI_SME_TDLS_CONNECTION_TRACKER_NOTIFICATION);
+#endif
+		CASE_RETURN_STRING(eWNI_SME_RESET_AP_CAPS_CHANGED);
+#ifdef WLAN_FEATURE_11W
+		CASE_RETURN_STRING(eWNI_SME_UNPROT_MGMT_FRM_IND);
+#endif
+		CASE_RETURN_STRING(eWNI_SME_CANDIDATE_FOUND_IND);
+		CASE_RETURN_STRING(eWNI_SME_HANDOFF_REQ);
+		CASE_RETURN_STRING(eWNI_SME_GET_TSM_STATS_REQ);
+		CASE_RETURN_STRING(eWNI_SME_GET_TSM_STATS_RSP);
+		CASE_RETURN_STRING(eWNI_SME_TSM_IE_IND);
+		CASE_RETURN_STRING(eWNI_SME_READY_TO_SUSPEND_IND);
+		CASE_RETURN_STRING(eWNI_SME_SET_HW_MODE_REQ);
+		CASE_RETURN_STRING(eWNI_SME_SET_HW_MODE_RESP);
+		CASE_RETURN_STRING(eWNI_SME_HW_MODE_TRANS_IND);
+		CASE_RETURN_STRING(eWNI_SME_NSS_UPDATE_REQ);
+		CASE_RETURN_STRING(eWNI_SME_NSS_UPDATE_RSP);
+		CASE_RETURN_STRING(eWNI_SME_REGISTER_MGMT_FRAME_CB);
+		CASE_RETURN_STRING(eWNI_SME_HT40_OBSS_SCAN_IND);
+#ifdef WLAN_FEATURE_NAN
+		CASE_RETURN_STRING(eWNI_SME_NAN_EVENT);
+#endif
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+		CASE_RETURN_STRING(eWNI_SME_READY_TO_EXTWOW_IND);
+#endif
+		CASE_RETURN_STRING(eWNI_SME_MSG_GET_TEMPERATURE_IND);
+		CASE_RETURN_STRING(eWNI_SME_SNR_IND);
+#ifdef FEATURE_WLAN_EXTSCAN
+		CASE_RETURN_STRING(eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND);
+		CASE_RETURN_STRING(eWNI_SME_EPNO_NETWORK_FOUND_IND);
+#endif
+		CASE_RETURN_STRING(eWNI_SME_SET_THERMAL_LEVEL_IND);
+		CASE_RETURN_STRING(eWNI_SME_OCB_SET_CONFIG_RSP);
+		CASE_RETURN_STRING(eWNI_SME_OCB_GET_TSF_TIMER_RSP);
+		CASE_RETURN_STRING(eWNI_SME_DCC_GET_STATS_RSP);
+		CASE_RETURN_STRING(eWNI_SME_DCC_UPDATE_NDL_RSP);
+		CASE_RETURN_STRING(eWNI_SME_DCC_STATS_EVENT);
+		CASE_RETURN_STRING(eWNI_SME_SET_DUAL_MAC_CFG_REQ);
+		CASE_RETURN_STRING(eWNI_SME_SET_DUAL_MAC_CFG_RESP);
+		CASE_RETURN_STRING(eWNI_SME_SET_IE_REQ);
+		CASE_RETURN_STRING(eWNI_SME_EXT_CHANGE_CHANNEL);
+		CASE_RETURN_STRING(eWNI_SME_EXT_CHANGE_CHANNEL_IND);
+		CASE_RETURN_STRING(eWNI_SME_SET_ANTENNA_MODE_REQ);
+		CASE_RETURN_STRING(eWNI_SME_SET_ANTENNA_MODE_RESP);
+		CASE_RETURN_STRING(eWNI_SME_TSF_EVENT);
+		CASE_RETURN_STRING(eWNI_SME_MON_INIT_SESSION);
+		CASE_RETURN_STRING(eWNI_SME_PDEV_SET_HT_VHT_IE);
+		CASE_RETURN_STRING(eWNI_SME_SET_VDEV_IES_PER_BAND);
+		CASE_RETURN_STRING(eWNI_SME_SEND_DISASSOC_FRAME);
+		CASE_RETURN_STRING(eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE);
+		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_TRIGGER_SAE);
+		CASE_RETURN_STRING(eWNI_SME_SEND_MGMT_FRAME_TX);
+		CASE_RETURN_STRING(eWNI_SME_SEND_SAE_MSG);
+		CASE_RETURN_STRING(eWNI_SME_CSA_RESTART_REQ);
+		CASE_RETURN_STRING(eWNI_SME_CSA_RESTART_RSP);
+		CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
+	default:
+		return (uint8_t *) "UNKNOWN";
+		break;
+	}
+}
+#endif
+
+/**
+ * mac_trace_get_wma_msg_string() - Get the msg
+ * @wma_msg: message type in numeric form
+ *
+ * This function will return a string equivalent of the message.
+ *
+ * Return: String equivalent of the message type.
+ **/
+uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg)
+{
+	switch (wma_msg) {
+		CASE_RETURN_STRING(WMA_ADD_STA_REQ);
+		CASE_RETURN_STRING(WMA_ADD_STA_RSP);
+		CASE_RETURN_STRING(WMA_ADD_STA_SELF_RSP);
+		CASE_RETURN_STRING(WMA_DELETE_STA_REQ);
+		CASE_RETURN_STRING(WMA_DELETE_STA_RSP);
+		CASE_RETURN_STRING(WMA_ADD_BSS_REQ);
+		CASE_RETURN_STRING(WMA_ADD_BSS_RSP);
+		CASE_RETURN_STRING(WMA_DELETE_BSS_REQ);
+		CASE_RETURN_STRING(WMA_DELETE_BSS_HO_FAIL_REQ);
+		CASE_RETURN_STRING(WMA_DELETE_BSS_RSP);
+		CASE_RETURN_STRING(WMA_DELETE_BSS_HO_FAIL_RSP);
+		CASE_RETURN_STRING(WMA_SEND_BEACON_REQ);
+		CASE_RETURN_STRING(WMA_SET_BSSKEY_REQ);
+		CASE_RETURN_STRING(WMA_SET_BSSKEY_RSP);
+		CASE_RETURN_STRING(WMA_SET_STAKEY_REQ);
+		CASE_RETURN_STRING(WMA_SET_STAKEY_RSP);
+		CASE_RETURN_STRING(WMA_UPDATE_EDCA_PROFILE_IND);
+
+		CASE_RETURN_STRING(WMA_UPDATE_BEACON_IND);
+		CASE_RETURN_STRING(WMA_UPDATE_CF_IND);
+		CASE_RETURN_STRING(WMA_CHNL_SWITCH_REQ);
+		CASE_RETURN_STRING(WMA_ADD_TS_REQ);
+		CASE_RETURN_STRING(WMA_DEL_TS_REQ);
+		CASE_RETURN_STRING(WMA_EXIT_PS_REQ);
+		CASE_RETURN_STRING(WMA_ENTER_PS_REQ);
+		CASE_RETURN_STRING(WMA_MISSED_BEACON_IND);
+
+		CASE_RETURN_STRING(WMA_SWITCH_CHANNEL_RSP);
+		CASE_RETURN_STRING(WMA_P2P_NOA_ATTR_IND);
+		CASE_RETURN_STRING(WMA_PWR_SAVE_CFG);
+		CASE_RETURN_STRING(WMA_REGISTER_PE_CALLBACK);
+
+		CASE_RETURN_STRING(WMA_IBSS_STA_ADD);
+		CASE_RETURN_STRING(WMA_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND);
+		CASE_RETURN_STRING(WMA_SET_LINK_STATE);
+		CASE_RETURN_STRING(WMA_SET_LINK_STATE_RSP);
+		CASE_RETURN_STRING(WMA_SET_STA_BCASTKEY_REQ);
+		CASE_RETURN_STRING(WMA_SET_STA_BCASTKEY_RSP);
+		CASE_RETURN_STRING(WMA_ADD_TS_RSP);
+		CASE_RETURN_STRING(WMA_DPU_MIC_ERROR);
+
+		CASE_RETURN_STRING(WMA_TIMER_CHIP_MONITOR_TIMEOUT);
+		CASE_RETURN_STRING(WMA_TIMER_TRAFFIC_ACTIVITY_REQ);
+		CASE_RETURN_STRING(WMA_TIMER_ADC_RSSI_STATS);
+#ifdef FEATURE_WLAN_ESE
+		CASE_RETURN_STRING(WMA_TSM_STATS_REQ);
+		CASE_RETURN_STRING(WMA_TSM_STATS_RSP);
+#endif
+		CASE_RETURN_STRING(WMA_HT40_OBSS_SCAN_IND);
+		CASE_RETURN_STRING(WMA_SET_MIMOPS_REQ);
+		CASE_RETURN_STRING(WMA_SET_MIMOPS_RSP);
+		CASE_RETURN_STRING(WMA_SYS_READY_IND);
+		CASE_RETURN_STRING(WMA_SET_TX_POWER_REQ);
+		CASE_RETURN_STRING(WMA_SET_TX_POWER_RSP);
+		CASE_RETURN_STRING(WMA_GET_TX_POWER_REQ);
+
+		CASE_RETURN_STRING(WMA_TRANSMISSION_CONTROL_IND);
+		CASE_RETURN_STRING(WMA_ENABLE_UAPSD_REQ);
+		CASE_RETURN_STRING(WMA_DISABLE_UAPSD_REQ);
+		CASE_RETURN_STRING(WMA_GET_STATISTICS_REQ);
+		CASE_RETURN_STRING(WMA_GET_STATISTICS_RSP);
+		CASE_RETURN_STRING(WMA_SET_KEY_DONE);
+
+		CASE_RETURN_STRING(WMA_BTC_SET_CFG);
+		CASE_RETURN_STRING(WMA_HANDLE_FW_MBOX_RSP);
+		CASE_RETURN_STRING(WMA_SEND_PROBE_RSP_TMPL);
+		CASE_RETURN_STRING(WMA_SET_MAX_TX_POWER_REQ);
+		CASE_RETURN_STRING(WMA_SET_HOST_OFFLOAD);
+		CASE_RETURN_STRING(WMA_SET_KEEP_ALIVE);
+#ifdef WLAN_NS_OFFLOAD
+		CASE_RETURN_STRING(WMA_SET_NS_OFFLOAD);
+#endif /* WLAN_NS_OFFLOAD */
+		CASE_RETURN_STRING(WMA_ADD_STA_SELF_REQ);
+		CASE_RETURN_STRING(WMA_DEL_STA_SELF_REQ);
+		CASE_RETURN_STRING(WMA_WLAN_SUSPEND_IND);
+		CASE_RETURN_STRING(WMA_WLAN_RESUME_REQ);
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+		CASE_RETURN_STRING(WMA_WLAN_EXT_WOW);
+		CASE_RETURN_STRING(WMA_WLAN_SET_APP_TYPE1_PARAMS);
+		CASE_RETURN_STRING(WMA_WLAN_SET_APP_TYPE2_PARAMS);
+#endif
+		CASE_RETURN_STRING(WMA_MSG_TYPES_END);
+		CASE_RETURN_STRING(WMA_AGGR_QOS_REQ);
+		CASE_RETURN_STRING(WMA_AGGR_QOS_RSP);
+		CASE_RETURN_STRING(WMA_ROAM_SCAN_OFFLOAD_REQ);
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+		CASE_RETURN_STRING(WMA_8023_MULTICAST_LIST_REQ);
+		CASE_RETURN_STRING(WMA_RECEIVE_FILTER_SET_FILTER_REQ);
+		CASE_RETURN_STRING
+			(WMA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ);
+		CASE_RETURN_STRING
+			(WMA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP);
+		CASE_RETURN_STRING(WMA_RECEIVE_FILTER_CLEAR_FILTER_REQ);
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+		CASE_RETURN_STRING(WMA_GTK_OFFLOAD_REQ);
+		CASE_RETURN_STRING(WMA_GTK_OFFLOAD_GETINFO_REQ);
+		CASE_RETURN_STRING(WMA_GTK_OFFLOAD_GETINFO_RSP);
+#endif /* WLAN_FEATURE_GTK_OFFLOAD */
+		CASE_RETURN_STRING(WMA_SET_TM_LEVEL_REQ);
+		CASE_RETURN_STRING(WMA_UPDATE_OP_MODE);
+		CASE_RETURN_STRING(WMA_UPDATE_MEMBERSHIP);
+		CASE_RETURN_STRING(WMA_UPDATE_USERPOS);
+		CASE_RETURN_STRING(WMA_UPDATE_CHAN_LIST_REQ);
+		CASE_RETURN_STRING(WMA_CLI_SET_CMD);
+#ifndef REMOVE_PKT_LOG
+		CASE_RETURN_STRING(WMA_PKTLOG_ENABLE_REQ);
+#endif
+#ifdef FEATURE_WLAN_ESE
+		CASE_RETURN_STRING(WMA_SET_PLM_REQ);
+#endif
+		CASE_RETURN_STRING(WMA_CONFIG_PARAM_UPDATE_REQ);
+		CASE_RETURN_STRING(WMA_RATE_UPDATE_IND);
+		CASE_RETURN_STRING(WMA_INIT_BAD_PEER_TX_CTL_INFO_CMD);
+#ifdef FEATURE_WLAN_TDLS
+		CASE_RETURN_STRING(WMA_UPDATE_TDLS_PEER_STATE);
+#endif
+		CASE_RETURN_STRING(WMA_ADD_PERIODIC_TX_PTRN_IND);
+		CASE_RETURN_STRING(WMA_TX_POWER_LIMIT);
+		CASE_RETURN_STRING(WMA_DHCP_START_IND);
+		CASE_RETURN_STRING(WMA_DHCP_STOP_IND);
+#ifdef FEATURE_WLAN_CH_AVOID
+		CASE_RETURN_STRING(WMA_CH_AVOID_UPDATE_REQ);
+#endif
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+		CASE_RETURN_STRING(WMA_SET_AUTO_SHUTDOWN_TIMER_REQ);
+#endif
+		CASE_RETURN_STRING(WMA_IBSS_CESIUM_ENABLE_IND);
+		CASE_RETURN_STRING(WMA_GET_IBSS_PEER_INFO_REQ);
+		CASE_RETURN_STRING(WMA_TX_FAIL_MONITOR_IND);
+#ifdef FEATURE_WLAN_RMC
+		CASE_RETURN_STRING(WMA_RMC_ENABLE_IND);
+		CASE_RETURN_STRING(WMA_RMC_DISABLE_IND);
+		CASE_RETURN_STRING(WMA_RMC_ACTION_PERIOD_IND);
+#endif
+		CASE_RETURN_STRING(WMA_INIT_THERMAL_INFO_CMD);
+		CASE_RETURN_STRING(WMA_SET_THERMAL_LEVEL);
+		CASE_RETURN_STRING(WMA_SET_SAP_INTRABSS_DIS);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		CASE_RETURN_STRING(WMA_ROAM_OFFLOAD_SYNCH_FAIL);
+#endif
+		CASE_RETURN_STRING(SIR_HAL_SET_BASE_MACADDR_IND);
+		CASE_RETURN_STRING(WMA_LINK_STATUS_GET_REQ);
+#ifdef DHCP_SERVER_OFFLOAD
+		CASE_RETURN_STRING(WMA_SET_DHCP_SERVER_OFFLOAD_CMD);
+#endif
+		CASE_RETURN_STRING(WMA_OCB_SET_CONFIG_CMD);
+		CASE_RETURN_STRING(WMA_OCB_SET_UTC_TIME_CMD);
+		CASE_RETURN_STRING(WMA_OCB_START_TIMING_ADVERT_CMD);
+		CASE_RETURN_STRING(WMA_OCB_STOP_TIMING_ADVERT_CMD);
+		CASE_RETURN_STRING(WMA_OCB_GET_TSF_TIMER_CMD);
+		CASE_RETURN_STRING(WMA_DCC_GET_STATS_CMD);
+		CASE_RETURN_STRING(WMA_DCC_CLEAR_STATS_CMD);
+		CASE_RETURN_STRING(WMA_DCC_UPDATE_NDL_CMD);
+		CASE_RETURN_STRING(WMA_SET_IE_INFO);
+		CASE_RETURN_STRING(WMA_LRO_CONFIG_CMD);
+		CASE_RETURN_STRING(WMA_GW_PARAM_UPDATE_REQ);
+		CASE_RETURN_STRING(WMA_ADD_BCN_FILTER_CMDID);
+		CASE_RETURN_STRING(WMA_REMOVE_BCN_FILTER_CMDID);
+		CASE_RETURN_STRING(WMA_SET_ADAPT_DWELLTIME_CONF_PARAMS);
+		CASE_RETURN_STRING(WDA_APF_GET_CAPABILITIES_REQ);
+		CASE_RETURN_STRING(WDA_APF_SET_INSTRUCTIONS_REQ);
+		CASE_RETURN_STRING(WMA_SET_PDEV_IE_REQ);
+		CASE_RETURN_STRING(WMA_UPDATE_WEP_DEFAULT_KEY);
+		CASE_RETURN_STRING(WMA_SEND_FREQ_RANGE_CONTROL_IND);
+		CASE_RETURN_STRING(WMA_POWER_DEBUG_STATS_REQ);
+		CASE_RETURN_STRING(WNI_CFG_DNLD_REQ);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		CASE_RETURN_STRING(SIR_HAL_ROAM_INVOKE);
+#endif
+		CASE_RETURN_STRING(SIR_HAL_SET_MAS);
+		CASE_RETURN_STRING(SIR_HAL_SET_MIRACAST);
+		CASE_RETURN_STRING(SIR_HAL_CONFIG_STATS_FACTOR);
+		CASE_RETURN_STRING(SIR_HAL_CONFIG_GUARD_TIME);
+		CASE_RETURN_STRING(SIR_HAL_START_STOP_LOGGING);
+		CASE_RETURN_STRING(SIR_HAL_FLUSH_LOG_TO_FW);
+		CASE_RETURN_STRING(SIR_HAL_PDEV_SET_PCL_TO_FW);
+		CASE_RETURN_STRING(SIR_HAL_PDEV_SET_HW_MODE);
+		CASE_RETURN_STRING(SIR_HAL_PDEV_DUAL_MAC_CFG_REQ);
+		CASE_RETURN_STRING(WMA_RADAR_DETECTED_IND);
+		CASE_RETURN_STRING(WMA_TIMER_TRAFFIC_STATS_IND);
+#ifdef WLAN_FEATURE_11W
+		CASE_RETURN_STRING(WMA_EXCLUDE_UNENCRYPTED_IND);
+#endif
+		CASE_RETURN_STRING(WMA_SET_MAX_TX_POWER_RSP);
+		CASE_RETURN_STRING(WMA_SET_DTIM_PERIOD);
+		CASE_RETURN_STRING(WMA_SET_MAX_TX_POWER_PER_BAND_REQ);
+#ifdef FEATURE_WLAN_TDLS
+		CASE_RETURN_STRING(WMA_SET_TDLS_LINK_ESTABLISH_REQ);
+		CASE_RETURN_STRING(WMA_SET_TDLS_LINK_ESTABLISH_REQ_RSP);
+#endif
+		CASE_RETURN_STRING(WMA_CSA_OFFLOAD_EVENT);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		CASE_RETURN_STRING(WMA_ROAM_OFFLOAD_SYNCH_IND);
+#endif
+		CASE_RETURN_STRING(WMA_HIDDEN_SSID_VDEV_RESTART);
+		CASE_RETURN_STRING(WMA_UPDATE_RX_NSS);
+#ifdef WLAN_FEATURE_NAN
+		CASE_RETURN_STRING(WMA_NAN_REQUEST);
+#endif
+		CASE_RETURN_STRING(WMA_RX_SCAN_EVENT);
+		CASE_RETURN_STRING(WMA_RX_CHN_STATUS_EVENT);
+		CASE_RETURN_STRING(WMA_IBSS_PEER_INACTIVITY_IND);
+		CASE_RETURN_STRING(WMA_DEL_PERIODIC_TX_PTRN_IND);
+#ifdef FEATURE_WLAN_TDLS
+		CASE_RETURN_STRING(WMA_TDLS_SHOULD_DISCOVER_CMD);
+		CASE_RETURN_STRING(WMA_TDLS_SHOULD_TEARDOWN_CMD);
+		CASE_RETURN_STRING(WMA_TDLS_PEER_DISCONNECTED_CMD);
+		CASE_RETURN_STRING(WMA_TDLS_SET_OFFCHAN_MODE);
+		CASE_RETURN_STRING
+			(WMA_TDLS_CONNECTION_TRACKER_NOTIFICATION_CMD);
+#endif
+		CASE_RETURN_STRING(WMA_DFS_BEACON_TX_SUCCESS_IND);
+		CASE_RETURN_STRING(WMA_DISASSOC_TX_COMP);
+		CASE_RETURN_STRING(WMA_DEAUTH_TX_COMP);
+		CASE_RETURN_STRING(WMA_MODEM_POWER_STATE_IND);
+#ifdef WLAN_FEATURE_STATS_EXT
+		CASE_RETURN_STRING(WMA_STATS_EXT_REQUEST);
+#endif
+		CASE_RETURN_STRING(WMA_GET_TEMPERATURE_REQ);
+#ifdef FEATURE_WLAN_EXTSCAN
+		CASE_RETURN_STRING(WMA_EXTSCAN_GET_CAPABILITIES_REQ);
+		CASE_RETURN_STRING(WMA_EXTSCAN_START_REQ);
+		CASE_RETURN_STRING(WMA_EXTSCAN_STOP_REQ);
+		CASE_RETURN_STRING(WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ);
+		CASE_RETURN_STRING(WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ);
+		CASE_RETURN_STRING(WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ);
+		CASE_RETURN_STRING(WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ);
+		CASE_RETURN_STRING(WMA_EXTSCAN_GET_CACHED_RESULTS_REQ);
+		CASE_RETURN_STRING(WMA_SET_EPNO_LIST_REQ);
+		CASE_RETURN_STRING(WMA_SET_PASSPOINT_LIST_REQ);
+		CASE_RETURN_STRING(WMA_RESET_PASSPOINT_LIST_REQ);
+#endif /* FEATURE_WLAN_EXTSCAN */
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+		CASE_RETURN_STRING(WMA_LINK_LAYER_STATS_CLEAR_REQ);
+		CASE_RETURN_STRING(WMA_LINK_LAYER_STATS_SET_REQ);
+		CASE_RETURN_STRING(WMA_LINK_LAYER_STATS_GET_REQ);
+		CASE_RETURN_STRING(WMA_LINK_LAYER_STATS_RESULTS_RSP);
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+		CASE_RETURN_STRING(WMA_SET_SCAN_MAC_OUI_REQ);
+		CASE_RETURN_STRING(WMA_TSF_GPIO_PIN);
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+		CASE_RETURN_STRING(WMA_LED_FLASHING_REQ);
+#endif
+		CASE_RETURN_STRING(WMA_PROCESS_FW_EVENT);
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+		CASE_RETURN_STRING(WMA_UPDATE_Q2Q_IE_IND);
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+		CASE_RETURN_STRING(WMA_SET_RSSI_MONITOR_REQ);
+		CASE_RETURN_STRING(WMA_SET_WISA_PARAMS);
+		CASE_RETURN_STRING(WMA_SET_WOW_PULSE_CMD);
+		CASE_RETURN_STRING(WMA_SET_PER_ROAM_CONFIG_CMD);
+		CASE_RETURN_STRING(WMA_GET_RCPI_REQ);
+		CASE_RETURN_STRING(WMA_SET_DBS_SCAN_SEL_CONF_PARAMS);
+		CASE_RETURN_STRING(WMA_GET_ROAM_SCAN_STATS);
+	default:
+		return (uint8_t *) "UNKNOWN";
+		break;
+	}
+}
+
+#ifdef TRACE_RECORD
+/**
+ * mac_trace_get_lim_msg_string() - Get the msg
+ * @lim_msg: message type in numeric form
+ *
+ * This function will return a string equivalent of the message.
+ *
+ * Return: String equivalent of the message type.
+ **/
+uint8_t *mac_trace_get_lim_msg_string(uint16_t lim_msg)
+{
+	switch (lim_msg) {
+		CASE_RETURN_STRING(SIR_LIM_RETRY_INTERRUPT_MSG);
+		CASE_RETURN_STRING(SIR_BB_XPORT_MGMT_MSG);
+		CASE_RETURN_STRING(SIR_LIM_INV_KEY_INTERRUPT_MSG);
+		CASE_RETURN_STRING(SIR_LIM_KEY_ID_INTERRUPT_MSG);
+		CASE_RETURN_STRING(SIR_LIM_REPLAY_THRES_INTERRUPT_MSG);
+		CASE_RETURN_STRING(SIR_LIM_TD_DUMMY_CALLBACK_MSG);
+		CASE_RETURN_STRING(SIR_LIM_SCH_CLEAN_MSG);
+		CASE_RETURN_STRING(SIR_LIM_RADAR_DETECT_IND);
+		CASE_RETURN_STRING(SIR_LIM_DEL_TS_IND);
+		CASE_RETURN_STRING(SIR_LIM_DELETE_STA_CONTEXT_IND);
+		CASE_RETURN_STRING(SIR_LIM_UPDATE_BEACON);
+		CASE_RETURN_STRING(SIR_LIM_JOIN_FAIL_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_AUTH_FAIL_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_AUTH_RSP_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_ASSOC_FAIL_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_REASSOC_FAIL_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_HEART_BEAT_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_PROBE_HB_FAILURE_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_ADDTS_RSP_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_LINK_TEST_DURATION_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_CNF_WAIT_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_CHANNEL_SWITCH_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_QUIET_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_QUIET_BSS_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_WPS_OVERLAP_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_FT_PREAUTH_RSP_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE);
+		CASE_RETURN_STRING(SIR_LIM_BEACON_GEN_IND);
+		CASE_RETURN_STRING(SIR_LIM_DISASSOC_ACK_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_DEAUTH_ACK_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_AUTH_RETRY_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_AUTH_SAE_TIMEOUT);
+		CASE_RETURN_STRING(SIR_LIM_MSG_TYPES_END);
+		CASE_RETURN_STRING(LIM_MLM_SCAN_REQ);
+		CASE_RETURN_STRING(LIM_MLM_SCAN_CNF);
+		CASE_RETURN_STRING(LIM_MLM_START_CNF);
+		CASE_RETURN_STRING(LIM_MLM_JOIN_REQ);
+		CASE_RETURN_STRING(LIM_MLM_JOIN_CNF);
+		CASE_RETURN_STRING(LIM_MLM_AUTH_REQ);
+		CASE_RETURN_STRING(LIM_MLM_AUTH_CNF);
+		CASE_RETURN_STRING(LIM_MLM_AUTH_IND);
+		CASE_RETURN_STRING(LIM_MLM_ASSOC_REQ);
+		CASE_RETURN_STRING(LIM_MLM_ASSOC_CNF);
+		CASE_RETURN_STRING(LIM_MLM_ASSOC_IND);
+		CASE_RETURN_STRING(LIM_MLM_DISASSOC_REQ);
+		CASE_RETURN_STRING(LIM_MLM_DISASSOC_CNF);
+		CASE_RETURN_STRING(LIM_MLM_DISASSOC_IND);
+		CASE_RETURN_STRING(LIM_MLM_REASSOC_REQ);
+		CASE_RETURN_STRING(LIM_MLM_REASSOC_CNF);
+		CASE_RETURN_STRING(LIM_MLM_REASSOC_IND);
+		CASE_RETURN_STRING(LIM_MLM_DEAUTH_REQ);
+		CASE_RETURN_STRING(LIM_MLM_DEAUTH_CNF);
+		CASE_RETURN_STRING(LIM_MLM_DEAUTH_IND);
+		CASE_RETURN_STRING(LIM_MLM_TSPEC_REQ);
+		CASE_RETURN_STRING(LIM_MLM_TSPEC_CNF);
+		CASE_RETURN_STRING(LIM_MLM_SETKEYS_REQ);
+		CASE_RETURN_STRING(LIM_MLM_SETKEYS_CNF);
+		CASE_RETURN_STRING(LIM_MLM_LINK_TEST_STOP_REQ);
+		CASE_RETURN_STRING(LIM_MLM_PURGE_STA_IND);
+	default:
+		return (uint8_t *) "UNKNOWN";
+		break;
+	}
+}
+
+/**
+ * mac_trace_get_cfg_msg_string() - Get the msg
+ * @cfg_msg: message type in numeric form
+ *
+ * This function will return a string equivalent of the message.
+ *
+ * Return: String equivalent of the message type.
+ **/
+uint8_t *mac_trace_get_cfg_msg_string(uint16_t cfg_msg)
+{
+	switch (cfg_msg) {
+		CASE_RETURN_STRING(WNI_CFG_PARAM_UPDATE_IND);
+		CASE_RETURN_STRING(WNI_CFG_DNLD_REQ);
+		CASE_RETURN_STRING(WNI_CFG_DNLD_CNF);
+		CASE_RETURN_STRING(WNI_CFG_GET_RSP);
+		CASE_RETURN_STRING(WNI_CFG_SET_CNF);
+		CASE_RETURN_STRING(WNI_CFG_GET_ATTRIB_RSP);
+		CASE_RETURN_STRING(WNI_CFG_ADD_GRP_ADDR_CNF);
+		CASE_RETURN_STRING(WNI_CFG_DEL_GRP_ADDR_CNF);
+		CASE_RETURN_STRING(SIR_CFG_PARAM_UPDATE_IND);
+		CASE_RETURN_STRING(SIR_CFG_DOWNLOAD_COMPLETE_IND);
+		CASE_RETURN_STRING(WNI_CFG_DNLD_RSP);
+		CASE_RETURN_STRING(WNI_CFG_GET_REQ);
+	default:
+		return (uint8_t *) "UNKNOWN";
+		break;
+	}
+}
+
+/**
+ * mac_trace_get_info_log_string() - Get the log info
+ * @info_log: message type in numeric form
+ *
+ * This function will return a string equivalent of the message.
+ *
+ * Return: String equivalent of the message type.
+ **/
+uint8_t *mac_trace_get_info_log_string(uint16_t info_log)
+{
+	switch (info_log) {
+		CASE_RETURN_STRING(eLOG_NODROP_MISSED_BEACON_SCENARIO);
+		CASE_RETURN_STRING(eLOG_PROC_DEAUTH_FRAME_SCENARIO);
+	default:
+		return (uint8_t *) "UNKNOWN";
+		break;
+	}
+}
+
+/**
+ * mac_trace() - Main function used for MAC Trace
+ * @mac_ctx:       Global MAC context
+ * @code:          code
+ * @session:       session id
+ * @data:          data to be traced.
+ *
+ * Return: None
+ **/
+void mac_trace(tpAniSirGlobal mac_ctx, uint8_t code,
+		uint16_t session, uint32_t data)
+{
+	/*
+	 * Today mac_trace is being invoked by PE only, need to remove this
+	 * function once PE is migrated to using new trace API.
+	 */
+	mac_trace_new(mac_ctx, QDF_MODULE_ID_PE, code, session, data);
+}
+
+/**
+ * mac_trace_new() - New function used for MAC Trace
+ * @mac_ctx:       Global MAC context
+ * @code:          code
+ * @session:       session id
+ * @data:          data to be traced.
+ *
+ * Return: None
+ **/
+void mac_trace_new(tpAniSirGlobal mac_ctx, uint8_t module, uint8_t code,
+		   uint16_t session, uint32_t data)
+{
+	qdf_trace(module, code, session, data);
+}
+
+#endif
diff --git a/core/mac/src/sys/legacy/src/utils/src/parse_mac_trace.cmm b/core/mac/src/sys/legacy/src/utils/src/parse_mac_trace.cmm
new file mode 100644
index 0000000..be649ea
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/src/parse_mac_trace.cmm
@@ -0,0 +1,1000 @@
+;Copyright (c) 2013-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.
+
+;parsemactrace.cmm - This script parses MAC trace table in UMAC layer
+;This script relies on message id's placed in interface header file.
+;If some message ID's are changed later, since they do not use enum, this script
+;might show incorrect data. So message ID's should always be in sync
+;Author:
+;Date:          09/09/2013
+;History:-
+;Date           Modified by    Modification Information
+;--------------------------------------------------------------------
+
+
+ENTRY &FILE
+
+IF "&FILE"==""
+(
+DIALOG.file *.txt
+ENTRY &FILE
+)
+
+OPEN #1 "&FILE" /Create /Write /Append
+
+
+Var.NEW  char [406][50] \halmsgtype
+
+Var.SET \halmsgtype[0x20]="SIR_HAL_RADAR_DETECTED_IND"
+Var.SET \halmsgtype[0x21]="SIR_HAL_ADD_STA_REQ"
+Var.SET \halmsgtype[0x22]="SIR_HAL_ADD_STA_RSP"
+Var.SET \halmsgtype[0x23]="SIR_HAL_DELETE_STA_REQ"
+Var.SET \halmsgtype[0x24]="SIR_HAL_DELETE_STA_RSP"
+Var.SET \halmsgtype[0x25]="SIR_HAL_ADD_BSS_REQ"
+Var.SET \halmsgtype[0x26]="SIR_HAL_ADD_BSS_RSP"
+Var.SET \halmsgtype[0x27]="SIR_HAL_DELETE_BSS_REQ"
+Var.SET \halmsgtype[0x28]="SIR_HAL_DELETE_BSS_RSP"
+Var.SET \halmsgtype[0x29]="SIR_HAL_INIT_SCAN_REQ"
+Var.SET \halmsgtype[0x2A]="SIR_HAL_INIT_SCAN_RSP"
+Var.SET \halmsgtype[0x2B]="SIR_HAL_START_SCAN_REQ"
+Var.SET \halmsgtype[0x2C]="SIR_HAL_START_SCAN_RSP"
+Var.SET \halmsgtype[0x2D]="SIR_HAL_END_SCAN_REQ"
+Var.SET \halmsgtype[0x2E]="SIR_HAL_END_SCAN_RSP"
+Var.SET \halmsgtype[0x2F]="SIR_HAL_FINISH_SCAN_REQ"
+Var.SET \halmsgtype[0x30]="SIR_HAL_FINISH_SCAN_RSP"
+Var.SET \halmsgtype[0x31]="SIR_HAL_SEND_BEACON_REQ"
+Var.SET \halmsgtype[0x32]="SIR_HAL_SET_BSSKEY_REQ"
+Var.SET \halmsgtype[0x33]="SIR_HAL_SET_BSSKEY_RSP"
+Var.SET \halmsgtype[0x34]="SIR_HAL_SET_STAKEY_REQ"
+Var.SET \halmsgtype[0x35]="SIR_HAL_SET_STAKEY_RSP"
+Var.SET \halmsgtype[0x36]="SIR_HAL_UPDATE_EDCA_PROFILE_IND"
+Var.SET \halmsgtype[0x37]="SIR_HAL_UPDATE_BEACON_IND"
+Var.SET \halmsgtype[0x38]="SIR_HAL_UPDATE_CF_IND"
+Var.SET \halmsgtype[0x39]="SIR_HAL_CHNL_SWITCH_REQ"
+Var.SET \halmsgtype[0x3A]="SIR_HAL_ADD_TS_REQ"
+Var.SET \halmsgtype[0x3B]="SIR_HAL_DEL_TS_REQ"
+;28 to 33 macros unused
+Var.SET \halmsgtype[0x42]="SIR_HAL_MISSED_BEACON_IND"
+Var.SET \halmsgtype[0x43]="SIR_HAL_SWITCH_CHANNEL_RSP"
+Var.SET \halmsgtype[0x44]="SIR_HAL_PWR_SAVE_CFG"
+Var.SET \halmsgtype[0x45]="SIR_HAL_REGISTER_PE_CALLBACK"
+;38 to 42 unused
+Var.SET \halmsgtype[0x4A]="SIR_HAL_IBSS_STA_ADD"
+Var.SET \halmsgtype[0x4B]="SIR_HAL_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND"
+Var.SET \halmsgtype[0x4C]="SIR_HAL_SET_LINK_STATE"
+Var.SET \halmsgtype[0x4D]="SIR_HAL_DELETE_BSS_HO_FAIL_REQ"
+Var.SET \halmsgtype[0x4E]="SIR_HAL_DELETE_BSS_HO_FAIL_RSP"
+;48 to 57 unused
+Var.SET \halmsgtype[0x59]="SIR_HAL_SET_STA_BCASTKEY_REQ"
+Var.SET \halmsgtype[0x5A]="SIR_HAL_SET_STA_BCASTKEY_RSP"
+Var.SET \halmsgtype[0x5B]="SIR_HAL_ADD_TS_RSP"
+Var.SET \halmsgtype[0x5C]="SIR_HAL_DPU_MIC_ERROR"
+;62 unused
+Var.SET \halmsgtype[0x5E]="SIR_HAL_TIMER_CHIP_MONITOR_TIMEOUT"
+Var.SET \halmsgtype[0x5F]="SIR_HAL_TIMER_TRAFFIC_ACTIVITY_REQ"
+Var.SET \halmsgtype[0x60]="SIR_HAL_TIMER_ADC_RSSI_STATS"
+;66 unused
+Var.SET \halmsgtype[0x62]="SIR_HAL_SET_MIMOPS_REQ"
+Var.SET \halmsgtype[0x63]="SIR_HAL_SET_MIMOPS_RSP"
+Var.SET \halmsgtype[0x64]="SIR_HAL_SYS_READY_IND"
+Var.SET \halmsgtype[0x65]="SIR_HAL_SET_TX_POWER_REQ"
+Var.SET \halmsgtype[0x66]="SIR_HAL_SET_TX_POWER_RSP"
+Var.SET \halmsgtype[0x67]="SIR_HAL_GET_TX_POWER_REQ"
+Var.SET \halmsgtype[0x68]="SIR_HAL_GET_TX_POWER_RSP"
+Var.SET \halmsgtype[0x69]="SIR_HAL_GET_NOISE_RSP"
+Var.SET \halmsgtype[0x6A]="SIR_HAL_TRANSMISSION_CONTROL_IND"
+;76 to 79 unused
+Var.SET \halmsgtype[0x6F]="SIR_HAL_LOW_RSSI_IND"
+Var.SET \halmsgtype[0x70]="SIR_HAL_BEACON_FILTER_IND"
+Var.SET \halmsgtype[0x71]="SIR_HAL_WOW_ADD_PTRN"
+Var.SET \halmsgtype[0x72]="SIR_HAL_WOW_DEL_PTRN"
+Var.SET \halmsgtype[0x73]="SIR_HAL_WOWL_ENTER_REQ"
+Var.SET \halmsgtype[0x74]="SIR_HAL_WOWL_ENTER_RSP"
+Var.SET \halmsgtype[0x75]="SIR_HAL_WOWL_EXIT_REQ"
+Var.SET \halmsgtype[0x76]="SIR_HAL_WOWL_EXIT_RSP"
+Var.SET \halmsgtype[0x77]="SIR_HAL_GET_STATISTICS_REQ"
+Var.SET \halmsgtype[0x78]="SIR_HAL_GET_STATISTICS_RSP"
+Var.SET \halmsgtype[0x79]="SIR_HAL_SET_KEY_DONE"
+Var.SET \halmsgtype[0x7A]="SIR_HAL_BTC_SET_CFG"
+;92 unused
+Var.SET \halmsgtype[0x7C]="SIR_HAL_HANDLE_FW_MBOX_RSP"
+Var.SET \halmsgtype[0x7D]="SIR_HAL_SEND_PROBE_RSP_TMPL"
+Var.SET \halmsgtype[0x7E]="SIR_LIM_ADDR2_MISS_IND"
+Var.SET \halmsgtype[0x7F]="SIR_HAL_START_OEM_DATA_REQ"
+Var.SET \halmsgtype[0x80]="SIR_HAL_START_OEM_DATA_RSP"
+Var.SET \halmsgtype[0x81]="SIR_HAL_SET_MAX_TX_POWER_REQ"
+Var.SET \halmsgtype[0x82]="SIR_HAL_SET_MAX_TX_POWER_RSP"
+Var.SET \halmsgtype[0x83]="SIR_HAL_SET_HOST_OFFLOAD"
+Var.SET \halmsgtype[0x84]="SIR_HAL_ADD_STA_SELF_REQ"
+Var.SET \halmsgtype[0x85]="SIR_HAL_ADD_STA_SELF_RSP"
+Var.SET \halmsgtype[0x86]="SIR_HAL_DEL_STA_SELF_REQ"
+Var.SET \halmsgtype[0x87]="SIR_HAL_DEL_STA_SELF_RSP"
+;105 unused
+Var.SET \halmsgtype[0x88]="SIR_HAL_CFG_RXP_FILTER_REQ"
+Var.SET \halmsgtype[0x89]="SIR_HAL_AGGR_ADD_TS_REQ"
+Var.SET \halmsgtype[0x8A]="SIR_HAL_AGGR_ADD_TS_RSP"
+Var.SET \halmsgtype[0x8B]="SIR_HAL_AGGR_QOS_REQ"
+Var.SET \halmsgtype[0x8C]="SIR_HAL_AGGR_QOS_RSP"
+Var.SET \halmsgtype[0x8D]="SIR_HAL_SET_P2P_GO_NOA_REQ"
+Var.SET \halmsgtype[0x8E]="SIR_HAL_P2P_NOA_ATTR_IND"
+Var.SET \halmsgtype[0x8F]="SIR_HAL_P2P_NOA_START_IND"
+Var.SET \halmsgtype[0x90]="SIR_HAL_SET_LINK_STATE_RSP"
+Var.SET \halmsgtype[0x91]="SIR_HAL_WLAN_SUSPEND_IND"
+Var.SET \halmsgtype[0x92]="SIR_HAL_WLAN_RESUME_REQ"
+Var.SET \halmsgtype[0x93]="SIR_HAL_SET_KEEP_ALIVE"
+Var.SET \halmsgtype[0x94]="SIR_HAL_SET_NS_OFFLOAD"
+Var.SET \halmsgtype[0x95]="SIR_HAL_SET_PNO_REQ"
+Var.SET \halmsgtype[0x96]="SIR_HAL_SOC_ANTENNA_MODE_REQ"
+Var.SET \halmsgtype[0x97]="SIR_HAL_SOC_ANTENNA_MODE_RESP"
+;122 unused
+Var.SET \halmsgtype[0x98]="SIR_HAL_8023_MULTICAST_LIST_REQ"
+Var.SET \halmsgtype[0x99]="SIR_HAL_RECEIVE_FILTER_SET_FILTER_REQ"
+Var.SET \halmsgtype[0x9A]="SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ"
+Var.SET \halmsgtype[0x9B]="SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP"
+Var.SET \halmsgtype[0x9C]="SIR_HAL_RECEIVE_FILTER_CLEAR_FILTER_REQ"
+;128 unused
+Var.SET \halmsgtype[0x9F]="SIR_HAL_GTK_OFFLOAD_REQ"
+Var.SET \halmsgtype[0xA0]="SIR_HAL_GTK_OFFLOAD_GETINFO_REQ"
+Var.SET \halmsgtype[0xA1]="SIR_HAL_GTK_OFFLOAD_GETINFO_RSP"
+Var.SET \halmsgtype[0xA2]="SIR_HAL_TSM_STATS_REQ"
+Var.SET \halmsgtype[0xA3]="SIR_HAL_TSM_STATS_RSP"
+Var.SET \halmsgtype[0xA4]="SIR_HAL_SET_TM_LEVEL_REQ"
+Var.SET \halmsgtype[0xA5]="SIR_HAL_UPDATE_OP_MODE"
+Var.SET \halmsgtype[0xA6]="SIR_HAL_TDLS_LINK_ESTABLISH"
+Var.SET \halmsgtype[0xA7]="SIR_HAL_TDLS_LINK_TEARDOWN"
+Var.SET \halmsgtype[0xA8]="SIR_HAL_ROAM_SCAN_OFFLOAD_REQ"
+;139 and 140 unused
+Var.SET \halmsgtype[0xAB]="SIR_HAL_TRAFFIC_STATS_IND"
+Var.SET \halmsgtype[0xAC]="SIR_HAL_EXCLUDE_UNENCRYPTED_IND"
+Var.SET \halmsgtype[0xAD]="SIR_HAL_TDLS_LINK_ESTABLISH_REQ"
+Var.SET \halmsgtype[0xAE]="SIR_HAL_TDLS_LINK_ESTABLISH_REQ_RSP"
+Var.SET \halmsgtype[0xAF]="SIR_HAL_TDLS_IND"
+Var.SET \halmsgtype[0xB0]="SIR_HAL_STOP_SCAN_OFFLOAD_REQ"
+Var.SET \halmsgtype[0xB1]="SIR_HAL_RX_SCAN_EVENT"
+Var.SET \halmsgtype[0xB2]="SIR_HAL_DHCP_START_IND"
+Var.SET \halmsgtype[0xB3]="SIR_HAL_DHCP_STOP_IND"
+Var.SET \halmsgtype[0xB4]="SIR_HAL_IBSS_PEER_INACTIVITY_IND"
+Var.SET \halmsgtype[0xB5]="SIR_HAL_LPHB_CONF_IND"
+Var.SET \halmsgtype[0xB6]="SIR_HAL_ADD_PERIODIC_TX_PTRN_IND"
+Var.SET \halmsgtype[0xB7]="SIR_HAL_DEL_PERIODIC_TX_PTRN_IND"
+Var.SET \halmsgtype[0xB8]="SIR_HAL_PDEV_DUAL_MAC_CFG_REQ"
+Var.SET \halmsgtype[0xB9]="SIR_HAL_PDEV_MAC_CFG_RESP"
+;156 and 157 unused
+Var.SET \halmsgtype[0xBC]="SIR_HAL_IBSS_PEER_INFO_REQ"
+Var.SET \halmsgtype[0xBD]="SIR_HAL_RATE_UPDATE_IND"
+Var.SET \halmsgtype[0xBE]="SIR_HAL_FLUSH_LOG_TO_FW"
+Var.SET \halmsgtype[0xBF]="SIR_HAL_PDEV_SET_PCL_TO_FW"
+;162 unused
+Var.SET \halmsgtype[0xC1]="SIR_HAL_CLI_SET_CMD"
+Var.SET \halmsgtype[0xC2]="SIR_HAL_PKTLOG_ENABLE_REQ"
+Var.SET \halmsgtype[0xC3]="SIR_HAL_SME_SCAN_CACHE_UPDATED"
+Var.SET \halmsgtype[0xC4]="SIR_HAL_START_SCAN_OFFLOAD_REQ"
+Var.SET \halmsgtype[0xC5]="SIR_HAL_UPDATE_CHAN_LIST_REQ"
+;168 unused
+Var.SET \halmsgtype[0xC7]="SIR_CSA_OFFLOAD_EVENT"
+Var.SET \halmsgtype[0xC8]="SIR_HAL_SET_MAX_TX_POWER_PER_BAND_REQ"
+Var.SET \halmsgtype[0xC9]="SIR_HAL_TX_FAIL_MONITOR_IND"
+Var.SET \halmsgtype[0xCA]="SIR_HAL_UPDATE_MEMBERSHIP"
+Var.SET \halmsgtype[0xCB]="SIR_HAL_UPDATE_USERPOS"
+Var.SET \halmsgtype[0xCC]="SIR_HAL_UPDATE_FW_TDLS_STATE"
+Var.SET \halmsgtype[0xCD]="SIR_HAL_UPDATE_TDLS_PEER_STATE"
+Var.SET \halmsgtype[0xCE]="SIR_HAL_TDLS_SHOULD_DISCOVER"
+Var.SET \halmsgtype[0xCF]="SIR_HAL_TDLS_SHOULD_TEARDOWN"
+Var.SET \halmsgtype[0xD0]="SIR_HAL_TDLS_PEER_DISCONNECTED"
+Var.SET \halmsgtype[0xD1]="SIR_HAL_BEACON_TX_SUCCESS_IND"
+Var.SET \halmsgtype[0xD2]="SIR_HAL_DFS_RADAR_IND"
+Var.SET \halmsgtype[0xD3]="SIR_HAL_IBSS_CESIUM_ENABLE_IND"
+Var.SET \halmsgtype[0xD4]="SIR_HAL_RMC_ENABLE_IND"
+Var.SET \halmsgtype[0xD5]="SIR_HAL_RMC_DISABLE_IND"
+Var.SET \halmsgtype[0xD6]="SIR_HAL_RMC_ACTION_PERIOD_IND"
+Var.SET \halmsgtype[0xD7]="SIR_HAL_INIT_THERMAL_INFO_CMD"
+Var.SET \halmsgtype[0xD8]="SIR_HAL_SET_THERMAL_LEVEL"
+Var.SET \halmsgtype[0xD9]="SIR_HAL_SET_PLM_REQ"
+Var.SET \halmsgtype[0xDA]="SIR_HAL_SET_TX_POWER_LIMIT"
+Var.SET \halmsgtype[0xDB]="SIR_HAL_SET_SAP_INTRABSS_DIS"
+Var.SET \halmsgtype[0xDC]="SIR_HAL_MODEM_POWER_STATE_IND"
+Var.SET \halmsgtype[0xDD]="SIR_HAL_DISASSOC_TX_COMP"
+Var.SET \halmsgtype[0xDE]="SIR_HAL_DEAUTH_TX_COMP"
+Var.SET \halmsgtype[0xDF]="SIR_HAL_UPDATE_RX_NSS"
+Var.SET \halmsgtype[0xE0]="SIR_HAL_STATS_EXT_REQUEST"
+Var.SET \halmsgtype[0xE1]="SIR_HAL_STATS_EXT_EVENT"
+Var.SET \halmsgtype[0xE2]="SIR_HAL_HIDE_SSID_VDEV_RESTART"
+Var.SET \halmsgtype[0xE3]="SIR_HAL_GET_LINK_SPEED"
+Var.SET \halmsgtype[0xE4]="SIR_HAL_EXTSCAN_GET_CAPABILITIES_REQ"
+Var.SET \halmsgtype[0xE5]="SIR_HAL_EXTSCAN_START_REQ"
+Var.SET \halmsgtype[0xE6]="SIR_HAL_EXTSCAN_STOP_REQ"
+Var.SET \halmsgtype[0xE7]="SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_REQ"
+Var.SET \halmsgtype[0xE8]="SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_REQ"
+Var.SET \halmsgtype[0xE9]="SIR_HAL_EXTSCAN_SET_SIGNF_CHANGE_REQ"
+Var.SET \halmsgtype[0xEA]="SIR_HAL_EXTSCAN_RESET_SIGNF_CHANGE_REQ"
+Var.SET \halmsgtype[0xEB]="SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_REQ"
+Var.SET \halmsgtype[0xEC]="SIR_HAL_CH_AVOID_UPDATE_REQ"
+Var.SET \halmsgtype[0xED]="SIR_HAL_LL_STATS_CLEAR_REQ"
+Var.SET \halmsgtype[0xEE]="SIR_HAL_LL_STATS_SET_REQ"
+Var.SET \halmsgtype[0xEF]="SIR_HAL_LL_STATS_GET_REQ"
+Var.SET \halmsgtype[0xF0]="SIR_HAL_LL_STATS_RESULTS_RSP"
+Var.SET \halmsgtype[0xF1]="SIR_HAL_ROAM_OFFLOAD_SYNCH_CNF"
+Var.SET \halmsgtype[0xF2]="SIR_HAL_NAN_REQUEST"
+Var.SET \halmsgtype[0xF3]="SIR_HAL_SET_AUTO_SHUTDOWN_TIMER_REQ"
+Var.SET \halmsgtype[0xF4]="SIR_HAL_SET_BASE_MACADDR_IND"
+Var.SET \halmsgtype[0xF5]="SIR_HAL_SET_BASE_MACADDR_IND"
+Var.SET \halmsgtype[0xF6]="SIR_HAL_LINK_STATUS_GET_REQ"
+Var.SET \halmsgtype[0xF7]="SIR_HAL_CONFIG_EXT_WOW"
+Var.SET \halmsgtype[0xF8]="SIR_HAL_CONFIG_APP_TYPE1_PARAMS"
+Var.SET \halmsgtype[0xF9]="SIR_HAL_CONFIG_APP_TYPE2_PARAMS"
+Var.SET \halmsgtype[0xFA]="SIR_HAL_GET_TEMPERATURE_REQ"
+Var.SET \halmsgtype[0xFB]="SIR_HAL_SET_SCAN_MAC_OUI_REQ"
+Var.SET \halmsgtype[0xFC]="SIR_HAL_SET_DHCP_SERVER_OFFLOAD"
+Var.SET \halmsgtype[0xFD]="SIR_HAL_LED_FLASHING_REQ"
+Var.SET \halmsgtype[0xFE]="SIR_HAL_LED_FLASHING_REQ"
+Var.SET \halmsgtype[0xFF]="SIR_HAL_ROAM_OFFLOAD_SYNCH_IND"
+Var.SET \halmsgtype[0x100]="SIR_HAL_ROAM_OFFLOAD_SYNCH_FAIL"
+Var.SET \halmsgtype[0x101]="SIR_HAL_ROAM_INVOKE"
+Var.SET \halmsgtype[0x102]="SIR_HAL_TDLS_SET_OFFCHAN_MODE"
+Var.SET \halmsgtype[0x103]="SIR_HAL_TDLS_SET_OFFCHAN_MODE"
+Var.SET \halmsgtype[0x104]="SIR_HAL_SET_MIRACAST"
+Var.SET \halmsgtype[0x105]="SIR_HAL_UPDATE_Q2Q_IE_IND"
+Var.SET \halmsgtype[0x106]="SIR_HAL_UPDATE_Q2Q_IE_IND"
+Var.SET \halmsgtype[0x107]="SIR_HAL_CONFIG_GUARD_TIME"
+Var.SET \halmsgtype[0x108]="SIR_HAL_IPA_OFFLOAD_ENABLE_DISABLE"
+Var.SET \halmsgtype[0x109]="SIR_HAL_ENTER_PS_REQ"
+Var.SET \halmsgtype[0x10A]="SIR_HAL_EXIT_PS_REQ"
+Var.SET \halmsgtype[0x10B]="SIR_HAL_ENABLE_UAPSD_REQ"
+Var.SET \halmsgtype[0x10C]="SIR_HAL_DISABLE_UAPSD_REQ"
+Var.SET \halmsgtype[0x10D]="SIR_HAL_GATEWAY_PARAM_UPDATE_REQ"
+;240 to 307 unused
+Var.SET \halmsgtype[0x152]="SIR_HAL_RUNTIME_PM_SUSPEND_IND"
+Var.SET \halmsgtype[0x153]="SIR_HAL_RUNTIME_PM_RESUME_IND"
+;310 to 312 unused
+Var.SET \halmsgtype[0x157]="SIR_HAL_SET_EPNO_LIST_REQ"
+;314 and 315 unused
+Var.SET \halmsgtype[0x15A]="SIR_HAL_SET_PASSPOINT_LIST_REQ"
+Var.SET \halmsgtype[0x15B]="SIR_HAL_RESET_PASSPOINT_LIST_REQ"
+;318 unused
+Var.SET \halmsgtype[0x15D]="SIR_HAL_OCB_SET_CONFIG_CMD"
+Var.SET \halmsgtype[0x15E]="SIR_HAL_OCB_SET_UTC_TIME_CMD"
+Var.SET \halmsgtype[0x15F]="SIR_HAL_OCB_START_TIMING_ADVERT_CMD"
+Var.SET \halmsgtype[0x160]="SIR_HAL_OCB_STOP_TIMING_ADVERT_CMD"
+Var.SET \halmsgtype[0x161]="SIR_HAL_OCB_GET_TSF_TIMER_CMD"
+Var.SET \halmsgtype[0x162]="SIR_HAL_DCC_GET_STATS_CMD"
+Var.SET \halmsgtype[0x163]="SIR_HAL_DCC_CLEAR_STATS_CMD"
+Var.SET \halmsgtype[0x164]="SIR_HAL_DCC_UPDATE_NDL_CMD"
+Var.SET \halmsgtype[0x165]="SIR_HAL_FW_MEM_DUMP_REQ"
+Var.SET \halmsgtype[0x166]="SIR_HAL_START_STOP_LOGGING"
+Var.SET \halmsgtype[0x167]="SIR_HAL_PDEV_SET_HW_MODE"
+Var.SET \halmsgtype[0x168]="SIR_HAL_PDEV_SET_HW_MODE_RESP"
+Var.SET \halmsgtype[0x169]="SIR_HAL_PDEV_HW_MODE_TRANS_IND"
+Var.SET \halmsgtype[0x169]="SIR_HAL_BAD_PEER_TX_CTL_INI_CMD"
+Var.SET \halmsgtype[0x16A]="SIR_HAL_SET_RSSI_MONITOR_REQ"
+Var.SET \halmsgtype[0x16B]="SIR_HAL_SET_IE_INFO"
+Var.SET \halmsgtype[0x16C]="SIR_HAL_LRO_CONFIG_CMD"
+Var.SET \halmsgtype[0x16D]="SIR_HAL_SET_EGAP_CONF_PARAMS"
+Var.SET \halmsgtype[0x16E]="SIR_HAL_HT40_OBSS_SCAN_IND"
+Var.SET \halmsgtype[0x16F]="SIR_HAL_TSF_GPIO_PIN_REQ"
+Var.SET \halmsgtype[0x170]="SIR_HAL_ADD_BCN_FILTER_CMDID"
+Var.SET \halmsgtype[0x171]="SIR_HAL_REMOVE_BCN_FILTER_CMDID"
+Var.SET \halmsgtype[0x172]="SIR_HAL_BPF_GET_CAPABILITIES_REQ"
+Var.SET \halmsgtype[0x173]="SIR_HAL_BPF_SET_INSTRUCTIONS_REQ"
+Var.SET \halmsgtype[0x174]="SIR_HAL_SET_WISA_PARAMS"
+Var.SET \halmsgtype[0x175]="SIR_HAL_SET_ADAPT_DWELLTIME_PARAMS"
+Var.SET \halmsgtype[0x176]="SIR_HAL_SET_PDEV_IE_REQ"
+Var.SET \halmsgtype[0x177]="SIR_HAL_TDLS_CONNECTION_TRACKER_NOTIFICATION"
+Var.SET \halmsgtype[0x178]="SIR_HAL_NDP_GET_CAP_REQ"
+Var.SET \halmsgtype[0x179]="SIR_HAL_NDP_INITIATOR_REQ"
+Var.SET \halmsgtype[0x17A]="SIR_HAL_NDP_RESPONDER_REQ"
+Var.SET \halmsgtype[0x17B]="SIR_HAL_NDP_END_REQ"
+Var.SET \halmsgtype[0x17C]="SIR_HAL_NDI_CAP_RSP"
+Var.SET \halmsgtype[0x17D]="SIR_HAL_IBSS_PEER_INFO_RSP"
+Var.SET \halmsgtype[0x17E]="SIR_HAL_RATE_UPDATE_IND"
+Var.SET \halmsgtype[0x17F]="SIR_HAL_NDP_INITIATOR_RSP"
+Var.SET \halmsgtype[0x180]="SIR_HAL_NDP_RESPONDER_RSP"
+Var.SET \halmsgtype[0x181]="SIR_HAL_NDP_END_RSP"
+Var.SET \halmsgtype[0x182]="SIR_HAL_NDP_INDICATION"
+Var.SET \halmsgtype[0x183]="SIR_HAL_NDP_CONFIRM"
+Var.SET \halmsgtype[0x184]="SIR_HAL_NDP_END_IND"
+Var.SET \halmsgtype[0x185]="SIR_HAL_UPDATE_WEP_DEFAULT_KEY"
+;359 unused
+Var.SET \halmsgtype[0x187]="SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND"
+;361 unused
+Var.SET \halmsgtype[0x189]="SIR_HAL_POWER_DBG_CMD"
+Var.SET \halmsgtype[0x18A]="SIR_HAL_SET_DTIM_PERIOD"
+Var.SET \halmsgtype[0x18B]="SIR_HAL_ENCRYPT_DECRYPT_MSG"
+Var.SET \halmsgtype[0x18C]="SIR_HAL_SHORT_RETRY_LIMIT_CNT"
+Var.SET \halmsgtype[0x18D]="SIR_HAL_LONG_RETRY_LIMIT_CNT"
+Var.SET \halmsgtype[0x18E]="SIR_HAL_UPDATE_TX_FAIL_CNT_TH"
+Var.SET \halmsgtype[0x18F]="SIR_HAL_POWER_DEBUG_STATS_REQ"
+Var.SET \halmsgtype[0x190]="SIR_HAL_SET_WOW_PULSE_CMD"
+Var.SET \halmsgtype[0x191]="SIR_HAL_SET_UDP_RESP_OFFLOAD"
+Var.SET \halmsgtype[0x192]="SIR_HAL_SET_PER_ROAM_CONFIG_CMD"
+Var.SET \halmsgtype[0x193]="SIR_HAL_GET_RCPI_REQ"
+Var.SET \halmsgtype[0x194]="SIR_HAL_ENABLE_BCAST_FILTER"
+Var.SET \halmsgtype[0x195]="SIR_HAL_DISABLE_BCAST_FILTER"
+
+
+Var.NEW  char [256][100] \smecodetype
+
+Var.SET \smecodetype[0x00]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ"
+Var.SET \smecodetype[0x01]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS"
+Var.SET \smecodetype[0x02]="TRACE_CODE_SME_RX_HDD_MSG_CONNECT"
+Var.SET \smecodetype[0x03]="TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO"
+Var.SET \smecodetype[0x04]="TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN"
+Var.SET \smecodetype[0x05]="TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO"
+Var.SET \smecodetype[0x06]="TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG"
+Var.SET \smecodetype[0x07]="TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG"
+Var.SET \smecodetype[0x08]="TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND"
+Var.SET \smecodetype[0x09]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS"
+Var.SET \smecodetype[0x0A]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS"
+Var.SET \smecodetype[0x0B]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST"
+Var.SET \smecodetype[0x0C]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETNEXT"
+Var.SET \smecodetype[0x0D]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE"
+Var.SET \smecodetype[0x0E]="TRACE_CODE_SME_RX_HDD_ROAM_REASSOC"
+Var.SET \smecodetype[0x0F]="TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT"
+Var.SET \smecodetype[0x10]="TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE"
+Var.SET \smecodetype[0x11]="TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE"
+Var.SET \smecodetype[0x12]="TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE"
+Var.SET \smecodetype[0x12]="TRACE_CODE_SME_RX_HDD_ROAM_GET_PMKIDCACHE"
+Var.SET \smecodetype[0x13]="TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM"
+Var.SET \smecodetype[0x14]="TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS"
+Var.SET \smecodetype[0x15]="TRACE_CODE_SME_RX_HDD_SET_CONFIG_PWRSAVE"
+Var.SET \smecodetype[0x16]="TRACE_CODE_SME_RX_HDD_GET_CONFIG_PWRSAVE"
+Var.SET \smecodetype[0x17]="TRACE_CODE_SME_RX_HDD_ENABLE_PWRSAVE"
+Var.SET \smecodetype[0x18]="TRACE_CODE_SME_RX_HDD_DISABLE_PWRSAVE"
+Var.SET \smecodetype[0x19]="TRACE_CODE_SME_RX_HDD_START_AUTO_BMPSTIMER"
+Var.SET \smecodetype[0x1A]="TRACE_CODE_SME_RX_HDD_STOP_AUTO_BMPSTIMER"
+Var.SET \smecodetype[0x1B]="TRACE_CODE_SME_RX_HDD_IS_PWRSAVE_ENABLED"
+Var.SET \smecodetype[0x1C]="TRACE_CODE_SME_RX_HDD_REQUEST_FULLPOWER"
+Var.SET \smecodetype[0x1D]="TRACE_CODE_SME_RX_HDD_REQUEST_BMPS"
+Var.SET \smecodetype[0x1E]="TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG"
+Var.SET \smecodetype[0x1F]="TRACE_CODE_SME_RX_HDD_REQUEST_STANDBY"
+Var.SET \smecodetype[0x20]="TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN"
+Var.SET \smecodetype[0x21]="TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN"
+Var.SET \smecodetype[0x22]="TRACE_CODE_SME_RX_HDD_ENTER_WOWL"
+Var.SET \smecodetype[0x23]="TRACE_CODE_SME_RX_HDD_EXIT_WOWL"
+Var.SET \smecodetype[0x24]="TRACE_CODE_SME_RX_HDD_SET_KEY"
+Var.SET \smecodetype[0x25]="TRACE_CODE_SME_RX_HDD_REMOVE_KEY"
+Var.SET \smecodetype[0x26]="TRACE_CODE_SME_RX_HDD_GET_STATS"
+Var.SET \smecodetype[0x27]="TRACE_CODE_SME_RX_HDD_GET_RSSI"
+Var.SET \smecodetype[0x28]="TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE"
+Var.SET \smecodetype[0x29]="TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE"
+Var.SET \smecodetype[0x2A]="TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE"
+Var.SET \smecodetype[0x2B]="TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY"
+Var.SET \smecodetype[0x2C]="TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ"
+Var.SET \smecodetype[0x2D]="TRACE_CODE_SME_RX_HDD_DBG_READREG"
+Var.SET \smecodetype[0x2E]="TRACE_CODE_SME_RX_HDD_DBG_WRITEREG"
+Var.SET \smecodetype[0x2F]="TRACE_CODE_SME_RX_HDD_DBG_READMEM"
+Var.SET \smecodetype[0x30]="TRACE_CODE_SME_RX_HDD_DBG_WRITEMEM"
+Var.SET \smecodetype[0x31]="TRACE_CODE_SME_RX_HDD_OPEN_SESSION"
+Var.SET \smecodetype[0x32]="TRACE_CODE_SME_RX_HDD_CLOSE_SESSION"
+Var.SET \smecodetype[0x33]="TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD"
+Var.SET \smecodetype[0x34]="TRACE_CODE_SME_RX_HDD_SET_GTKOFFLOAD"
+Var.SET \smecodetype[0x35]="TRACE_CODE_SME_RX_HDD_GET_GTKOFFLOAD"
+Var.SET \smecodetype[0x36]="TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN"
+Var.SET \smecodetype[0x37]="TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR"
+Var.SET \smecodetype[0x38]="TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR"
+Var.SET \smecodetype[0x39]="TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN"
+Var.SET \smecodetype[0x3A]="TRACE_CODE_SME_RX_HDD_SEND_ACTION"
+Var.SET \smecodetype[0x3B]="TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN"
+Var.SET \smecodetype[0x3C]="TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL"
+Var.SET \smecodetype[0x3D]="TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND"
+Var.SET \smecodetype[0x3E]="TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ"
+Var.SET \smecodetype[0x3F]="TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW"
+Var.SET \smecodetype[0x40]="TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1"
+Var.SET \smecodetype[0x41]="TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2"
+Var.SET \smecodetype[0x42]="TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW"
+Var.SET \smecodetype[0x43]="TRACE_CODE_SME_RX_HDD_SET_TXPOW"
+Var.SET \smecodetype[0x44]="TRACE_CODE_SME_RX_HDD_SET_TMLEVEL"
+Var.SET \smecodetype[0x45]="TRACE_CODE_SME_RX_HDD_CAPS_EXCH"
+Var.SET \smecodetype[0x46]="TRACE_CODE_SME_RX_HDD_DISABLE_CAP"
+Var.SET \smecodetype[0x47]="TRACE_CODE_SME_RX_HDD_GET_DEFCCNV"
+Var.SET \smecodetype[0x48]="TRACE_CODE_SME_RX_HDD_GET_CURCC"
+Var.SET \smecodetype[0x49]="TRACE_CODE_SME_RX_HDD_RESET_PW5G"
+Var.SET \smecodetype[0x4A]="TRACE_CODE_SME_RX_HDD_UPDATE_RP5G"
+Var.SET \smecodetype[0x4B]="TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND"
+Var.SET \smecodetype[0x4C]="TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND"
+Var.SET \smecodetype[0x4D]="TRACE_CODE_SME_RX_HDD_UPDATE_RSSIDIFF"
+Var.SET \smecodetype[0x4E]="TRACE_CODE_SME_RX_HDD_UPDATE_IMMRSSIDIFF"
+Var.SET \smecodetype[0x4F]="TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED"
+Var.SET \smecodetype[0x50]="TRACE_CODE_SME_RX_HDD_UPDATE_WESMODE"
+Var.SET \smecodetype[0x51]="TRACE_CODE_SME_RX_HDD_SET_SCANCTRL"
+Var.SET \smecodetype[0x52]="TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE"
+Var.SET \smecodetype[0x53]="TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES"
+Var.SET \smecodetype[0x54]="TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME"
+Var.SET \smecodetype[0x55]="TRACE_CODE_SME_RX_HDD_STORE_JOIN_REQ"
+Var.SET \smecodetype[0x56]="TRACE_CODE_SME_RX_HDD_CLEAR_JOIN_REQ"
+Var.SET \smecodetype[0x57]="TRACE_CODE_SME_RX_HDD_ISSUE_JOIN_REQ"
+Var.SET \smecodetype[0x58]="TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA"
+;#ifdef FEATURE_WLAN_TDLS	//assuming this flag is enabled by default
+Var.SET \smecodetype[0x59]="TRACE_CODE_SME_RX_HDD_TDLS_LINK_ESTABLISH_PARAM"
+Var.SET \smecodetype[0x5A]="TRACE_CODE_SME_RX_HDD_TDLS_CHAN_SWITCH_REQ"
+Var.SET \smecodetype[0x5B]="TRACE_CODE_SME_RX_HDD_TDLS_SEND_MGMT_FRAME"
+Var.SET \smecodetype[0x5C]="TRACE_CODE_SME_RX_HDD_TDLS_CHANGE_PEER_STA"
+Var.SET \smecodetype[0x5D]="TRACE_CODE_SME_RX_HDD_TDLS_ADD_PEER_STA"
+Var.SET \smecodetype[0x5E]="TRACE_CODE_SME_RX_HDD_TDLS_DEL_PEER_STA"
+;#endif
+Var.SET \smecodetype[0x5F]="TRACE_CODE_SME_RX_HDD_PREF_NET_LIST"
+;#ifdef FEATURE_WLAN_LPHB	//assuming this flag is enabled by default
+Var.SET \smecodetype[0x60]="TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ"
+;#endif /* FEATURE_WLAN_LPHB */
+Var.SET \smecodetype[0x61]="TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE"
+;From here hardcoded to 250 in host code
+Var.SET \smecodetype[0xFA]="TRACE_CODE_SME_COMMAND"
+Var.SET \smecodetype[0xFB]="TRACE_CODE_SME_TX_WMA_MSG"
+Var.SET \smecodetype[0xFC]="TRACE_CODE_SME_RX_WMA_MSG"
+
+Var.NEW  char [256][50] \cfgmsgtype
+
+Var.SET \cfgmsgtype[0xB0]="SIR_CFG_PARAM_UPDATE_IND"
+Var.SET \cfgmsgtype[0xB1]="SIR_CFG_DOWNLOAD_COMPLETE_IND"
+
+
+Var.NEW  char [256][50] \limmsgtype
+
+Var.SET \limmsgtype[0xB3]="SIR_LIM_RETRY_INTERRUPT_MSG"
+Var.SET \limmsgtype[0xB4]="SIR_BB_XPORT_MGMT_MSG"
+;5 and 6 unused
+Var.SET \limmsgtype[0xB7]="SIR_LIM_INV_KEY_INTERRUPT_MSG"
+Var.SET \limmsgtype[0xB8]="SIR_LIM_KEY_ID_INTERRUPT_MSG"
+Var.SET \limmsgtype[0xB9]="SIR_LIM_REPLAY_THRES_INTERRUPT_MSG"
+Var.SET \limmsgtype[0xBA]="SIR_LIM_TD_DUMMY_CALLBACK_MSG"
+Var.SET \limmsgtype[0xBB]="SIR_LIM_SCH_CLEAN_MSG"
+Var.SET \limmsgtype[0xBC]="SIR_LIM_RADAR_DETECT_IND"
+;0xD unused
+Var.SET \limmsgtype[0xBE]="SIR_LIM_DEL_TS_IND"
+;0xF and 0x10 unused
+Var.SET \limmsgtype[0xC1]="SIR_LIM_DELETE_STA_CONTEXT_IND"
+;0x12 unused
+Var.SET \limmsgtype[0xC3]="SIR_LIM_UPDATE_BEACON"
+;0 and 1 unused
+Var.SET \limmsgtype[0xD2]="SIR_LIM_JOIN_FAIL_TIMEOUT"
+Var.SET \limmsgtype[0xD3]="SIR_LIM_AUTH_FAIL_TIMEOUT"
+Var.SET \limmsgtype[0xD4]="SIR_LIM_AUTH_RSP_TIMEOUT"
+Var.SET \limmsgtype[0xD5]="SIR_LIM_ASSOC_FAIL_TIMEOUT"
+Var.SET \limmsgtype[0xD6]="SIR_LIM_REASSOC_FAIL_TIMEOUT"
+Var.SET \limmsgtype[0xD7]="SIR_LIM_HEART_BEAT_TIMEOUT"
+;8, 9 and A unused
+Var.SET \limmsgtype[0xDB]="SIR_LIM_PROBE_HB_FAILURE_TIMEOUT"
+Var.SET \limmsgtype[0xDC]="SIR_LIM_ADDTS_RSP_TIMEOUT"
+;0xD to 0x12 unused
+Var.SET \limmsgtype[0xE3]="SIR_LIM_LINK_TEST_DURATION_TIMEOUT"
+;0x14 to 0x16 unused
+Var.SET \limmsgtype[0xE7]="SIR_LIM_CNF_WAIT_TIMEOUT"
+;0x18 unused
+Var.SET \limmsgtype[0xE9]="SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT"
+Var.SET \limmsgtype[0xEA]="SIR_LIM_CHANNEL_SWITCH_TIMEOUT"
+Var.SET \limmsgtype[0xEB]="SIR_LIM_QUIET_TIMEOUT"
+Var.SET \limmsgtype[0xEC]="SIR_LIM_QUIET_BSS_TIMEOUT"
+Var.SET \limmsgtype[0xED]="SIR_LIM_WPS_OVERLAP_TIMEOUT"
+Var.SET \limmsgtype[0xEE]="SIR_LIM_FT_PREAUTH_RSP_TIMEOUT"
+Var.SET \limmsgtype[0xEF]="SIR_LIM_REMAIN_CHN_TIMEOUT"
+Var.SET \limmsgtype[0xF0]="SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT"
+;0x21 and 0x22 unused
+Var.SET \limmsgtype[0xF3]="SIR_LIM_BEACON_GEN_IND"
+Var.SET \limmsgtype[0xF4]="SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT"
+;0x25 unused
+Var.SET \limmsgtype[0xF6]="SIR_LIM_DISASSOC_ACK_TIMEOUT"
+Var.SET \limmsgtype[0xF7]="SIR_LIM_DEAUTH_ACK_TIMEOUT"
+Var.SET \limmsgtype[0xF8]="SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT"
+;0x29, 0x2A and 0x2B unused
+Var.SET \limmsgtype[0xFC]="SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE"
+Var.SET \limmsgtype[0xFD]="SIR_LIM_AUTH_RETRY_TIMEOUT"
+Var.SET \limmsgtype[0xFF]="SIR_LIM_MSG_TYPES_END"
+
+
+Var.NEW  char [256][50] \schmsgtype
+
+Var.SET \schmsgtype[0x0]="SIR_SCH_CHANNEL_SWITCH_REQUEST"
+Var.SET \schmsgtype[0x1]="SIR_SCH_START_SCAN_REQ"
+Var.SET \schmsgtype[0x2]="SIR_SCH_START_SCAN_RSP"
+Var.SET \schmsgtype[0x3]="SIR_SCH_END_SCAN_NTF"
+Var.SET \schmsgtype[0xFF]="SIR_SCH_MSG_TYPES_END"
+
+Var.NEW  char [256][50] \pmmmsgtype
+
+Var.SET \pmmmsgtype[0x0]="SIR_PMM_CHANGE_PM_MODE"
+Var.SET \pmmmsgtype[0xFF]="SIR_PMM_MSG_TYPES_END"
+
+
+Var.NEW  char [256][50] \mntmsgtype
+
+Var.SET \mntmsgtype[0x0]="SIR_MNT_RELEASE_BD"
+Var.SET \mntmsgtype[0xFF]="SIR_MNT_MSG_TYPES_END"
+
+Var.NEW  char [0x301][50] \pttmsgtype
+
+Var.SET \pttmsgtype[0x0]="SIR_PTT_MSG_TYPES_BEGIN"
+Var.SET \pttmsgtype[0x300]="SIR_PTT_MSG_TYPES_END"
+
+
+Var.NEW  char [18][50] \code
+
+Var.SET \code[0]="TRACE_CODE_MLM_STATE"
+Var.SET \code[1]="TRACE_CODE_SME_STATE"
+Var.SET \code[2]="TRACE_CODE_TX_MGMT"
+Var.SET \code[3]="TRACE_CODE_RX_MGMT"
+Var.SET \code[4]="TRACE_CODE_RX_MGMT_TSF"
+Var.SET \code[5]="TRACE_CODE_TX_COMPLETE"
+Var.SET \code[6]="TRACE_CODE_TX_SME_MSG"
+Var.SET \code[7]="TRACE_CODE_RX_SME_MSG"
+Var.SET \code[8]="TRACE_CODE_TX_WMA_MSG"
+Var.SET \code[9]="TRACE_CODE_RX_WMA_MSG"
+Var.SET \code[10]="TRACE_CODE_TX_LIM_MSG"
+Var.SET \code[11]="TRACE_CODE_RX_LIM_MSG"
+Var.SET \code[12]="TRACE_CODE_TX_CFG_MSG"
+Var.SET \code[13]="TRACE_CODE_RX_CFG_MSG"
+Var.SET \code[14]="TRACE_CODE_RX_MGMT_DROP"
+Var.SET \code[15]="TRACE_CODE_TIMER_ACTIVATE"
+Var.SET \code[16]="TRACE_CODE_TIMER_DEACTIVATE"
+Var.SET \code[17]="TRACE_CODE_INFO_LOG"
+
+
+Var.NEW  char [13][50] \module
+
+Var.SET \module[1]="QDF_MODULE_ID_TLSHIM"
+Var.SET \module[2]="QDF_MODULE_ID_WMI"
+Var.SET \module[3]="QDF_MODULE_ID_HTT"
+Var.SET \module[4]="QDF_MODULE_ID_RSV4"
+Var.SET \module[5]="QDF_MODULE_ID_HDD"
+Var.SET \module[6]="QDF_MODULE_ID_SME"
+Var.SET \module[7]="QDF_MODULE_ID_PE"
+Var.SET \module[8]="QDF_MODULE_ID_WMA"
+Var.SET \module[9]="QDF_MODULE_ID_SYS"
+Var.SET \module[10]="QDF_MODULE_ID_QDF"
+Var.SET \module[11]="QDF_MODULE_ID_SAP"
+Var.SET \module[12]="QDF_MODULE_ID_HDD_SOFTAP"
+
+Var.NEW char [16][50] \mgmttype
+
+Var.SET \mgmttype[0]="SIR_MAC_MGMT_ASSOC_REQ"
+Var.SET \mgmttype[1]="SIR_MAC_MGMT_ASSOC_RSP"
+Var.SET \mgmttype[2]="SIR_MAC_MGMT_REASSOC_REQ"
+Var.SET \mgmttype[3]="SIR_MAC_MGMT_REASSOC_RSP"
+Var.SET \mgmttype[4]="SIR_MAC_MGMT_PROBE_REQ"
+Var.SET \mgmttype[5]="SIR_MAC_MGMT_PROBE_RSP"
+Var.SET \mgmttype[6]="SIR_MAC_MGMT_TIME_ADVERT"
+Var.SET \mgmttype[8]="SIR_MAC_MGMT_BEACON"
+Var.SET \mgmttype[9]="SIR_MAC_MGMT_ATIM"
+Var.SET \mgmttype[10]="SIR_MAC_MGMT_DISASSOC"
+Var.SET \mgmttype[11]="SIR_MAC_MGMT_AUTH"
+Var.SET \mgmttype[12]="SIR_MAC_MGMT_DEAUTH"
+Var.SET \mgmttype[13]="SIR_MAC_MGMT_ACTION"
+Var.SET \mgmttype[15]="SIR_MAC_MGMT_RESERVED15"
+
+Var.NEW char [30][50] \limtimertype
+
+Var.SET \limtimertype[0]="eLIM_MIN_CHANNEL_TIMER"
+Var.SET \limtimertype[1]="eLIM_MAX_CHANNEL_TIMER"
+Var.SET \limtimertype[2]="eLIM_JOIN_FAIL_TIMER"
+Var.SET \limtimertype[3]="eLIM_AUTH_FAIL_TIMER"
+Var.SET \limtimertype[4]="eLIM_AUTH_RESP_TIMER"
+Var.SET \limtimertype[5]="eLIM_ASSOC_FAIL_TIMER"
+Var.SET \limtimertype[6]="eLIM_REASSOC_FAIL_TIMER"
+Var.SET \limtimertype[7]="eLIM_PRE_AUTH_CLEANUP_TIMER"
+Var.SET \limtimertype[8]="eLIM_CNF_WAIT_TIMER"
+Var.SET \limtimertype[9]="eLIM_AUTH_RSP_TIMER"
+Var.SET \limtimertype[10]="eLIM_UPDATE_OLBC_CACHE_TIMER"
+Var.SET \limtimertype[11]="eLIM_PROBE_AFTER_HB_TIMER"
+Var.SET \limtimertype[12]="eLIM_ADDTS_RSP_TIMER"
+Var.SET \limtimertype[13]="eLIM_CHANNEL_SWITCH_TIMER"
+Var.SET \limtimertype[14]="eLIM_LEARN_DURATION_TIMER"
+Var.SET \limtimertype[15]="eLIM_QUIET_TIMER"
+Var.SET \limtimertype[16]="eLIM_QUIET_BSS_TIMER"
+Var.SET \limtimertype[17]="eLIM_WPS_OVERLAP_TIMER"
+Var.SET \limtimertype[18]="eLIM_FT_PREAUTH_RSP_TIMER"
+Var.SET \limtimertype[19]="eLIM_REMAIN_CHN_TIMER"
+Var.SET \limtimertype[20]="eLIM_PERIODIC_PROBE_REQ_TIMER"
+;#ifdef FEATURE_WLAN_CCX
+;Var.SET \limtimertype[0]="eLIM_TSM_TIMER"
+;#endif
+Var.SET \limtimertype[22]="eLIM_DISASSOC_ACK_TIMER"
+Var.SET \limtimertype[23]="eLIM_DEAUTH_ACK_TIMER"
+Var.SET \limtimertype[24]="eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER"
+Var.SET \limtimertype[25]="eLIM_INSERT_SINGLESHOT_NOA_TIMER"
+Var.SET \limtimertype[26]="eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE"
+
+
+
+Var.NEW  char [256][100] \hddcodetype
+
+Var.SET \hddcodetype[0x00]="TRACE_CODE_HDD_OPEN_REQUEST"
+Var.SET \hddcodetype[0x01]="TRACE_CODE_HDD_STOP_REQUEST"
+Var.SET \hddcodetype[0x02]="TRACE_CODE_HDD_TX_TIMEOUT"
+Var.SET \hddcodetype[0x03]="TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL"
+Var.SET \hddcodetype[0x04]="TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL"
+Var.SET \hddcodetype[0x05]="TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL"
+Var.SET \hddcodetype[0x06]="TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL"
+Var.SET \hddcodetype[0x07]="TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL"
+Var.SET \hddcodetype[0x08]="TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL"
+Var.SET \hddcodetype[0x09]="TRACE_CODE_HDD_SETROAMDELTA_IOCTL"
+Var.SET \hddcodetype[0x0A]="TRACE_CODE_HDD_GETROAMDELTA_IOCTL"
+Var.SET \hddcodetype[0x0B]="TRACE_CODE_HDD_GETBAND_IOCTL"
+Var.SET \hddcodetype[0x0C]="TRACE_CODE_HDD_GETCOUNTRYREV_IOCTL"
+Var.SET \hddcodetype[0x0D]="TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL"
+Var.SET \hddcodetype[0x0E]="TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL"
+Var.SET \hddcodetype[0x0F]="TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST"
+Var.SET \hddcodetype[0x10]="TRACE_CODE_HDD_HOSTAPD_STOP_REQUEST"
+Var.SET \hddcodetype[0x11]="TRACE_CODE_HDD_HOSTAPD_UNINIT_REQUEST"
+Var.SET \hddcodetype[0x12]="TRACE_CODE_HDD_SOFTAP_TX_TIMEOUT"
+Var.SET \hddcodetype[0x13]="TRACE_CODE_HDD_HOSTAPD_SET_MAC_ADDR"
+Var.SET \hddcodetype[0x14]="TRACE_CODE_HDD_HOSTAPD_P2P_SET_NOA_IOCTL"
+Var.SET \hddcodetype[0x15]="TRACE_CODE_HDD_HOSTAPD_P2P_SET_PS_IOCTL"
+Var.SET \hddcodetype[0x16]="TRACE_CODE_HDD_HOSTAPD_SET_SAP_CHANNEL_LIST_IOCTL"
+Var.SET \hddcodetype[0x17]="TRACE_CODE_HDD_ADD_VIRTUAL_INTF"
+Var.SET \hddcodetype[0x18]="TRACE_CODE_HDD_DEL_VIRTUAL_INTF"
+Var.SET \hddcodetype[0x19]="TRACE_CODE_HDD_CHANGE_VIRTUAL_INTF"
+Var.SET \hddcodetype[0x1A]="TRACE_CODE_HDD_CFG80211_START_AP"
+Var.SET \hddcodetype[0x1B]="TRACE_CODE_HDD_CFG80211_CHANGE_BEACON"
+Var.SET \hddcodetype[0x1C]="TRACE_CODE_HDD_CFG80211_STOP_AP"
+Var.SET \hddcodetype[0x1D]="TRACE_CODE_HDD_CFG80211_CHANGE_BSS"
+Var.SET \hddcodetype[0x1E]="TRACE_CODE_HDD_CFG80211_ADD_KEY"
+Var.SET \hddcodetype[0x1F]="TRACE_CODE_HDD_CFG80211_GET_KEY"
+Var.SET \hddcodetype[0x20]="TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY"
+Var.SET \hddcodetype[0x21]="TRACE_CODE_HDD_CFG80211_CONNECT"
+Var.SET \hddcodetype[0x22]="TRACE_CODE_HDD_CFG80211_DISCONNECT"
+Var.SET \hddcodetype[0x23]="TRACE_CODE_HDD_CFG80211_JOIN_IBSS"
+Var.SET \hddcodetype[0x24]="TRACE_CODE_HDD_CFG80211_LEAVE_IBSS"
+Var.SET \hddcodetype[0x25]="TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS"
+Var.SET \hddcodetype[0x26]="TRACE_CODE_HDD_CFG80211_SET_TXPOWER"
+Var.SET \hddcodetype[0x27]="TRACE_CODE_HDD_CFG80211_GET_TXPOWER"
+Var.SET \hddcodetype[0x28]="TRACE_CODE_HDD_CFG80211_SET_CHANNEL"
+Var.SET \hddcodetype[0x29]="TRACE_CODE_HDD_CFG80211_ADD_BEACON"
+Var.SET \hddcodetype[0x2A]="TRACE_CODE_HDD_CFG80211_SET_BEACON"
+Var.SET \hddcodetype[0x2B]="TRACE_CODE_HDD_CFG80211_CHANGE_IFACE"
+Var.SET \hddcodetype[0x2C]="TRACE_CODE_HDD_CHANGE_STATION"
+Var.SET \hddcodetype[0x2D]="TRACE_CODE_HDD_CFG80211_UPDATE_BSS"
+Var.SET \hddcodetype[0x2E]="TRACE_CODE_HDD_CFG80211_SCAN"
+Var.SET \hddcodetype[0x2F]="TRACE_CODE_HDD_REMAIN_ON_CHANNEL"
+Var.SET \hddcodetype[0x30]="TRACE_CODE_HDD_REMAINCHANREADYHANDLER"
+Var.SET \hddcodetype[0x31]="TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL"
+Var.SET \hddcodetype[0x32]="TRACE_CODE_HDD_ACTION"
+Var.SET \hddcodetype[0x33]="TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT"
+Var.SET \hddcodetype[0x34]="TRACE_CODE_HDD_CFG80211_GET_STA"
+Var.SET \hddcodetype[0x35]="TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT"
+Var.SET \hddcodetype[0x36]="TRACE_CODE_HDD_CFG80211_DEL_STA"
+Var.SET \hddcodetype[0x37]="TRACE_CODE_HDD_CFG80211_ADD_STA"
+Var.SET \hddcodetype[0x38]="TRACE_CODE_HDD_CFG80211_SET_PMKSA"
+Var.SET \hddcodetype[0x39]="TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES"
+Var.SET \hddcodetype[0x3A]="TRACE_CODE_HDD_CFG80211_TDLS_MGMT"
+Var.SET \hddcodetype[0x3B]="TRACE_CODE_HDD_CFG80211_TDLS_OPER"
+Var.SET \hddcodetype[0x3C]="TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA"
+Var.SET \hddcodetype[0x3D]="TRACE_CODE_HDD_UNSUPPORTED_IOCTL"
+Var.SET \hddcodetype[0x3E]="TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL"
+Var.SET \hddcodetype[0x3F]="TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL"
+Var.SET \hddcodetype[0x40]="TRACE_CODE_HDD_STORE_JOIN_REQ"
+Var.SET \hddcodetype[0x41]="TRACE_CODE_HDD_CLEAR_JOIN_REQ"
+Var.SET \hddcodetype[0x42]="TRACE_CODE_HDD_ISSUE_JOIN_REQ"
+Var.SET \hddcodetype[0x43]="TRACE_CODE_HDD_CFG80211_RESUME_WLAN"
+Var.SET \hddcodetype[0x44]="TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN"
+Var.SET \hddcodetype[0x45]="TRACE_CODE_HDD_CFG80211_SET_MAC_ACL"
+Var.SET \hddcodetype[0x46]="TRACE_CODE_HDD_CFG80211_TESTMODE"
+Var.SET \hddcodetype[0x47]="TRACE_CODE_HDD_CFG80211_DUMP_SURVEY"
+Var.SET \hddcodetype[0x48]="TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START"
+Var.SET \hddcodetype[0x49]="TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP"
+Var.SET \hddcodetype[0x4A]="TRACE_CODE_HDD_CFG80211_DEL_PMKSA"
+;New CFG80211 enums to be added before this comment
+;TRACE_CODE_HDD_RX_SME_MSG is used as code for MTRACE commands
+;and also update the below index value
+Var.SET \hddcodetype[0x4B]="TRACE_CODE_HDD_RX_SME_MSG"
+
+&TRACETYPESIZE=v.value(sizeof(qdf_trace_record_t))
+&TRACESIZE=v.value(sizeof(g_qdf_trace_tbl))
+&TRACEMAXINDEX=v.value(&TRACESIZE/&TRACETYPESIZE)
+
+&HEAD=v.value(g_qdf_trace_data.head)
+&TAIL=v.value(g_qdf_trace_data.tail)
+
+IF ((&HEAD>&TRACEMAXINDEX)||(&TAIL>&TRACEMAXINDEX)||(&TAIL==&HEAD))
+(
+  GOTO ENDSCRIPT
+)
+
+&INDEX=&HEAD
+
+TRACESTART:
+
+&TIME=v.value(g_qdf_trace_tbl[&INDEX].time)
+&MODULE=v.value(g_qdf_trace_tbl[&INDEX].module)
+&CODE=v.value(g_qdf_trace_tbl[&INDEX].code)
+&SESSION=v.value(g_qdf_trace_tbl[&INDEX].session)
+&DATA=v.value(g_qdf_trace_tbl[&INDEX].data)
+
+
+  WRITE #1 "TIME: "  &TIME
+  Var.Write #1 %STRING \module[&MODULE]
+
+IF (&MODULE==0x7)
+(
+if (&CODE>=0)&&(&CODE<=0x12)
+(
+    Var.Write #1 %STRING \code[&CODE] " [" %Hex &CODE "]"
+)
+
+   IF (&SESSION==0xFF)
+    (
+      WRITE #1 "NO SESSION"
+    )
+    ELSE
+    (
+      WRITE #1 "SESSION: " &SESSION
+    )
+
+
+;0 TRACE_CODE_MLM_STATE
+IF (&CODE==0x0)
+(
+  Var.NEW  tLimMlmStates \mlmstate
+  Var.Set \mlmstate=&DATA
+  ;Var.Write #1 \mlmstate " [" %Hex &DATA "]"
+)
+
+;1 TRACE_CODE_SME_STATE
+IF (&CODE==0x1)
+(
+  Var.NEW  tLimSmeStates \smestate
+  Var.Set \smestate=&DATA
+  Var.Write #1 \smestate " [" %Hex &DATA "]"
+)
+
+;2 TRACE_CODE_TX_MGMT
+IF (&CODE==0x2)
+(
+  WRITE #1 "DATA: " &DATA
+)
+
+;3 TRACE_CODE_RX_MGMT
+IF (&CODE==0x3)
+(
+  &SERIAL=v.value(&DATA>>16)
+  &SUBTYPE=v.value(&DATA&0xFF)
+  if (&SUBTYPE<=0xF)
+  (
+  Var.Write #1 %STRING \mgmttype[&SUBTYPE]
+  WRITE #1 "SEQ NUM: " &SERIAL
+  )
+  else
+  (
+    WRITE #1 "INCORRECT DATA"
+  )
+)
+
+;4 TRACE_CODE_RX_MGMT_TSF
+IF (&CODE==0x4)
+(
+  WRITE #1 "BEACON TS: " &DATA
+)
+
+;5 TRACE_CODE_TX_COMPLETE
+IF (&CODE==0x5)
+(
+  Var.Write #1 %STRING \mgmttype[&DATA] " [" %Hex &DATA "]"
+)
+
+;14 TRACE_CODE_RX_MGMT_DROP
+IF (&CODE==0xE)
+(
+  Var.NEW  tMgmtFrmDropReason \dropreason
+  Var.Set \dropreason=&DATA
+  Var.Write #1 \dropreason " [" %Hex &DATA "]"
+)
+
+
+;15 TRACE_CODE_TIMER_ACTIVATE/DEACTIVATE
+IF (&CODE==0xF)||(&CODE==0x10)
+(
+  Var.Write #1 %STRING \limtimertype[&DATA] " [" %Hex &DATA "]"
+)
+
+;6 TRACE_CODE_TX_SME_MSG
+IF (&CODE==0x6)
+(
+&MOD=v.value(&DATA>>8)
+&MSG=v.value(&DATA&0xFF)
+IF (&MOD==0x12)&&(&DATA>=0x12B0)
+(
+Var.Write #1 %STRING \limmsgtype[&MSG] " [" %Hex &MSG "]"
+)
+IF (&DATA>=0x1500)
+(
+  Var.NEW  enum eWniMsgTypes \smemsg
+  Var.Set \smemsg=&DATA
+  Var.Write #1 \smemsg " [" %Hex &DATA "]"
+ )
+)
+
+;7 TRACE_CODE_RX_SME_MSG
+IF (&CODE==0x7)
+(
+&MOD=v.value(&DATA>>8)
+&MSG=v.value(&DATA&0xFF)
+IF (&MOD==0x12)&&(&DATA>=0x12B0)
+(
+Var.Write #1 %STRING \limmsgtype[&MSG]  " [" %Hex &MSG "]"
+)
+IF (&DATA>=0x1500)
+(
+  Var.NEW  enum eWniMsgTypes \smemsg
+  Var.Set \smemsg=&DATA
+  Var.Write #1 \smemsg " [" %Hex &DATA "]"
+)
+)
+
+;8 TRACE_CODE_TX_WMA_MSG
+IF (&CODE==0x8)
+(
+&MOD=v.value(&DATA>>8)
+&MSG=v.value(&DATA&0xFF)
+IF (&MOD==0x10)
+(
+Var.Write #1 %STRING \halmsgtype[&MSG] " [" %Hex &MSG "]"
+)
+)
+
+;9 TRACE_CODE_RX_WMA_MSG
+IF (&CODE==0x9)
+(
+&MOD=v.value(&DATA>>8)
+&MSG=v.value(&DATA&0xFF)
+IF (&MOD==0x10)
+(
+Var.Write #1 %STRING \halmsgtype[&MSG] " [" %Hex &MSG "]"
+)
+)
+
+;10 TRACE_CODE_TX_LIM_MSG
+IF (&CODE==0xA)
+(
+&MOD=v.value(&DATA>>8)
+&MSG=v.value(&DATA&0xFF)
+IF (&MOD==0x12)&&(&DATA>=0x12B0)
+(
+Var.Write #1 %STRING \limmsgtype[&MSG] " [" %Hex &MSG "]"
+)
+IF (&DATA>=0x1500)
+(
+  Var.NEW  enum eWniMsgTypes \smemsg
+  Var.Set \smemsg=&DATA
+  Var.Write #1 \smemsg " [" %Hex &DATA "]"
+)
+)
+
+;11 TRACE_CODE_RX_LIM_MSG
+IF (&CODE==0xB)
+(
+&MOD=v.value(&DATA>>8)
+&MSG=v.value(&DATA&0xFF)
+IF (&MOD==0x12)&&(&DATA>=0x12B0)
+(
+Var.Write #1 %STRING \limmsgtype[&MSG]  " [" %Hex &MSG "]"
+)
+IF (&DATA>=0x1500)
+(
+  Var.NEW  enum eWniMsgTypes \smemsg
+  &DATA=v.value(&DATA&0xFFFF)
+  Var.Set \smemsg=&DATA
+  Var.Write #1 \smemsg " [" %Hex &DATA "]"
+)
+)
+
+;12 TRACE_CODE_TX_CFG_MSG
+IF (&CODE==0xC)
+(
+&MOD=v.value(&DATA>>8)
+&MSG=v.value(&DATA&0xFF)
+IF (&MOD==0x11)&&(&DATA>=0x11B0)
+(
+Var.Write #1 %STRING \cfgmsgtype[&MSG] " [" %Hex &MSG "]"
+)
+)
+
+;13 TRACE_CODE_RX_CFG_MSG
+IF (&CODE==0xD)
+(
+&MOD=v.value(&DATA>>8)
+&MSG=v.value(&DATA&0xFF)
+IF (&MOD==0x11)&&(&DATA>=0x11B0)
+(
+Var.Write #1 %STRING \cfgmsgtype[&MSG] " [" %Hex &MSG "]"
+)
+)
+
+IF (&DATA>=0x1500)
+(
+  Var.NEW  enum eWniMsgTypes \smemsg
+  &DATA=v.value(&DATA&0xFFFF)
+  Var.Set \smemsg=&DATA
+  Var.Write #1 \smemsg  " [" %Hex &DATA "]"
+)
+
+)
+
+
+IF (&MODULE==0x6)
+(
+
+  IF ((&CODE>=0x0)&&(&CODE<=0x61))
+  (
+    Var.Write #1 %STRING \smecodetype[&CODE] " [" %Hex &CODE "]"
+  )
+  ELSE
+  (
+    IF ((&CODE>=0xFA)&&(&CODE<=0xFC))
+    (
+      Var.Write #1 %STRING \smecodetype[&CODE] " [" %Hex &CODE "]"
+    )
+    ELSE
+    (
+      WRITE #1 "CODE: " &CODE
+    )
+  )
+  WRITE #1 "DATA: " &DATA
+
+  IF (&SESSION==0xFF)
+  (
+    WRITE #1 "NO SESSION"
+  )
+  ELSE
+  (
+    WRITE #1 "SESSION: " &SESSION
+  )
+)
+
+IF (&MODULE==0x5)
+(
+
+  IF ((&CODE>=0x0)&&(&CODE<=0x4A))
+  (
+    Var.Write #1 %STRING \hddcodetype[&CODE] " [" %Hex &CODE "]"
+    WRITE #1 "DATA: " &DATA
+  )
+  ELSE
+  (
+    IF (&CODE==0x4B)
+    (
+      Var.Write #1 %STRING \hddcodetype[&CODE] " [" %Hex &CODE "]"
+      Var.NEW  eRoamCmdStatus \csrstatus
+      Var.Set \csrstatus=&DATA
+      Var.Write #1 \csrstatus " [" %Hex &DATA "]"
+    )
+    ELSE
+    (
+      WRITE #1 "CODE: " &CODE
+      WRITE #1 "DATA: " &DATA
+    )
+  )
+
+  IF (&SESSION==0xFF)
+  (
+    WRITE #1 "NO SESSION"
+  )
+  ELSE
+  (
+    WRITE #1 "SESSION: " &SESSION
+  )
+)
+
+WRITE #1 " "
+
+&INDEX=v.value((&INDEX+1)%(&TRACEMAXINDEX))
+
+  IF (&INDEX!=&HEAD)
+  (
+    GOTO TRACESTART
+  )
+
+
+
+ENDSCRIPT:
+CLOSE #1
+ENDDO
diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
new file mode 100644
index 0000000..13ade4d
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
@@ -0,0 +1,6264 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*
+ * This file parser_api.cc contains the code for parsing
+ * 802.11 messages.
+ * Author:        Pierre Vandwalle
+ * Date:          03/18/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "sir_api.h"
+#include "ani_global.h"
+#include "parser_api.h"
+#include "cfg_api.h"
+#include "lim_utils.h"
+#include "utils_parser.h"
+#include "lim_ser_des_utils.h"
+#include "sch_api.h"
+#include "wmm_apsd.h"
+#include "rrm_api.h"
+
+#include "cds_regdomain.h"
+#include "qdf_crypto.h"
+#include "lim_process_fils.h"
+#include "wlan_utility.h"
+#include "wifi_pos_api.h"
+#include "wlan_mlme_public_struct.h"
+#include "wlan_mlme_ucfg_api.h"
+#include "wlan_mlme_api.h"
+
+#define RSN_OUI_SIZE 4
+/* ////////////////////////////////////////////////////////////////////// */
+void swap_bit_field16(uint16_t in, uint16_t *out)
+{
+#ifdef ANI_LITTLE_BIT_ENDIAN
+	*out = in;
+#else                           /* Big-Endian... */
+	*out = ((in & 0x8000) >> 15) |
+	       ((in & 0x4000) >> 13) |
+	       ((in & 0x2000) >> 11) |
+	       ((in & 0x1000) >> 9) |
+	       ((in & 0x0800) >> 7) |
+	       ((in & 0x0400) >> 5) |
+	       ((in & 0x0200) >> 3) |
+	       ((in & 0x0100) >> 1) |
+	       ((in & 0x0080) << 1) |
+	       ((in & 0x0040) << 3) |
+	       ((in & 0x0020) << 5) |
+	       ((in & 0x0010) << 7) |
+	       ((in & 0x0008) << 9) |
+	       ((in & 0x0004) << 11) |
+	       ((in & 0x0002) << 13) | ((in & 0x0001) << 15);
+#endif /* ANI_LITTLE_BIT_ENDIAN */
+}
+
+static inline void __print_wmm_params(tpAniSirGlobal pMac,
+				      tDot11fIEWMMParams *pWmm)
+{
+	pe_debug("WMM Parameters Received:");
+	pe_debug("BE: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d",
+		pWmm->acbe_aifsn, pWmm->acbe_acm, pWmm->acbe_aci,
+		pWmm->acbe_acwmin, pWmm->acbe_acwmax, pWmm->acbe_txoplimit);
+
+	pe_debug("BK: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d",
+		pWmm->acbk_aifsn, pWmm->acbk_acm, pWmm->acbk_aci,
+		pWmm->acbk_acwmin, pWmm->acbk_acwmax, pWmm->acbk_txoplimit);
+
+	pe_debug("VI: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d",
+		pWmm->acvi_aifsn, pWmm->acvi_acm, pWmm->acvi_aci,
+		pWmm->acvi_acwmin, pWmm->acvi_acwmax, pWmm->acvi_txoplimit);
+
+	pe_debug("VO: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d",
+		pWmm->acvo_aifsn, pWmm->acvo_acm, pWmm->acvo_aci,
+		pWmm->acvo_acwmin, pWmm->acvo_acwmax, pWmm->acvo_txoplimit);
+
+	return;
+}
+
+/* ////////////////////////////////////////////////////////////////////// */
+/* Functions for populating "dot11f" style IEs */
+
+/* return: >= 0, the starting location of the IE in rsnIEdata inside tSirRSNie */
+/*         < 0, cannot find */
+int find_ie_location(tpAniSirGlobal pMac, tpSirRSNie pRsnIe, uint8_t EID)
+{
+	int idx, ieLen, bytesLeft;
+	int ret_val = -1;
+
+	/* Here's what's going on: 'rsnIe' looks like this: */
+
+	/*     typedef struct sSirRSNie */
+	/*     { */
+	/*         uint16_t       length; */
+	/*         uint8_t        rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; */
+	/*     } tSirRSNie, *tpSirRSNie; */
+
+	/* other code records both the WPA & RSN IEs (including their EIDs & */
+	/* lengths) into the array 'rsnIEdata'.  We may have: */
+
+	/*     With WAPI support, there may be 3 IEs here */
+	/*     It can be only WPA IE, or only RSN IE or only WAPI IE */
+	/*     Or two or all three of them with no particular ordering */
+
+	/* The if/then/else statements that follow are here to figure out */
+	/* whether we have the WPA IE, and where it is if we *do* have it. */
+
+	/* Save the first IE length */
+	ieLen = pRsnIe->rsnIEdata[1] + 2;
+	idx = 0;
+	bytesLeft = pRsnIe->length;
+
+	while (1) {
+		if (EID == pRsnIe->rsnIEdata[idx]) {
+			/* Found it */
+			return idx;
+		} else if (EID != pRsnIe->rsnIEdata[idx] &&
+			/* & if no more IE, */
+			   bytesLeft <= (uint16_t) (ieLen)) {
+			pe_debug("No IE (%d)", EID);
+			return ret_val;
+		}
+		bytesLeft -= ieLen;
+		ieLen = pRsnIe->rsnIEdata[idx + 1] + 2;
+		idx += ieLen;
+	}
+
+	return ret_val;
+}
+
+QDF_STATUS
+populate_dot11f_capabilities(tpAniSirGlobal pMac,
+			     tDot11fFfCapabilities *pDot11f,
+			     tpPESession psessionEntry)
+{
+	uint16_t cfg;
+	QDF_STATUS nSirStatus;
+
+	nSirStatus = cfg_get_capability_info(pMac, &cfg, psessionEntry);
+	if (QDF_STATUS_SUCCESS != nSirStatus) {
+		pe_err("Failed to retrieve the Capabilities bitfield from CFG status: %d",
+			   nSirStatus);
+		return nSirStatus;
+	}
+
+	swap_bit_field16(cfg, (uint16_t *) pDot11f);
+
+	return QDF_STATUS_SUCCESS;
+} /* End populate_dot11f_capabilities. */
+
+/**
+ * populate_dot_11_f_ext_chann_switch_ann() - Function to populate ECS
+ * @mac_ptr:            Pointer to PMAC structure
+ * @dot_11_ptr:         ECS element
+ * @session_entry:      PE session entry
+ *
+ * This function is used to populate the extended channel switch element
+ *
+ * Return: None
+ */
+void populate_dot_11_f_ext_chann_switch_ann(tpAniSirGlobal mac_ptr,
+		tDot11fIEext_chan_switch_ann *dot_11_ptr,
+		tpPESession session_entry)
+{
+	uint8_t ch_offset;
+
+	if (session_entry->gLimChannelSwitch.ch_width == CH_WIDTH_80MHZ)
+		ch_offset = BW80;
+	else
+		ch_offset = session_entry->gLimChannelSwitch.sec_ch_offset;
+
+	dot_11_ptr->switch_mode = session_entry->gLimChannelSwitch.switchMode;
+	dot_11_ptr->new_reg_class = wlan_reg_dmn_get_opclass_from_channel(
+			mac_ptr->scan.countryCodeCurrent,
+			session_entry->gLimChannelSwitch.primaryChannel,
+			ch_offset);
+	dot_11_ptr->new_channel =
+		session_entry->gLimChannelSwitch.primaryChannel;
+	dot_11_ptr->switch_count =
+		session_entry->gLimChannelSwitch.switchCount;
+	dot_11_ptr->present = 1;
+
+	pe_debug("country:%s chan:%d width:%d reg:%d off:%d",
+			mac_ptr->scan.countryCodeCurrent,
+			session_entry->gLimChannelSwitch.primaryChannel,
+			session_entry->gLimChannelSwitch.ch_width,
+			dot_11_ptr->new_reg_class,
+			session_entry->gLimChannelSwitch.sec_ch_offset);
+}
+
+void
+populate_dot11f_chan_switch_ann(tpAniSirGlobal pMac,
+				tDot11fIEChanSwitchAnn *pDot11f,
+				tpPESession psessionEntry)
+{
+	pDot11f->switchMode = psessionEntry->gLimChannelSwitch.switchMode;
+	pDot11f->newChannel = psessionEntry->gLimChannelSwitch.primaryChannel;
+	pDot11f->switchCount =
+		(uint8_t) psessionEntry->gLimChannelSwitch.switchCount;
+
+	pDot11f->present = 1;
+}
+
+/**
+ * populate_dot11_supp_operating_classes() - Function to populate supported
+ *                      operating class IE
+ * @mac_ptr:            Pointer to PMAC structure
+ * @dot_11_ptr:         Operating class element
+ * @session_entry:      PE session entry
+ *
+ * Return: None
+ */
+void
+populate_dot11_supp_operating_classes(tpAniSirGlobal mac_ptr,
+				tDot11fIESuppOperatingClasses *dot_11_ptr,
+				tpPESession session_entry)
+{
+	uint8_t ch_bandwidth;
+
+	if (session_entry->ch_width == CH_WIDTH_80MHZ) {
+		ch_bandwidth = BW80;
+	} else {
+		switch (session_entry->htSecondaryChannelOffset) {
+		case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+			ch_bandwidth = BW40_HIGH_PRIMARY;
+			break;
+		case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+			ch_bandwidth = BW40_LOW_PRIMARY;
+			break;
+		default:
+			ch_bandwidth = BW20;
+			break;
+		}
+	}
+
+	wlan_reg_dmn_get_curr_opclasses(&dot_11_ptr->num_classes,
+					&dot_11_ptr->classes[1]);
+	dot_11_ptr->classes[0] = wlan_reg_dmn_get_opclass_from_channel(
+					mac_ptr->scan.countryCodeCurrent,
+					session_entry->currentOperChannel,
+					ch_bandwidth);
+	dot_11_ptr->num_classes++;
+	dot_11_ptr->present = 1;
+}
+
+void
+populate_dot11f_chan_switch_wrapper(tpAniSirGlobal pMac,
+				    tDot11fIEChannelSwitchWrapper *pDot11f,
+				    tpPESession psessionEntry)
+{
+	const uint8_t *ie_ptr = NULL;
+
+	/*
+	 * The new country subelement is present only when
+	 * 1. AP performs Extended Channel switching to new country.
+	 * 2. New Operating Class table or a changed set of operating
+	 * classes relative to the contents of the country element sent
+	 * in the beacons.
+	 *
+	 * In the current scenario Channel Switch wrapper IE is included
+	 * when we a radar is found and the AP does a channel change in
+	 * the same regulatory domain(No country change or Operating class
+	 * table). So, we do not need to include the New Country IE.
+	 *
+	 * Transmit Power Envlope Subelement is optional
+	 * in Channel Switch Wrapper IE. So, not setting
+	 * the TPE subelement. We include only WiderBWChanSwitchAnn.
+	 */
+	pDot11f->present = 1;
+
+	/*
+	 * Add the Wide Channel Bandwidth Sublement.
+	 */
+	pDot11f->WiderBWChanSwitchAnn.newChanWidth =
+		psessionEntry->gLimWiderBWChannelSwitch.newChanWidth;
+	pDot11f->WiderBWChanSwitchAnn.newCenterChanFreq0 =
+		psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0;
+	pDot11f->WiderBWChanSwitchAnn.newCenterChanFreq1 =
+		psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1;
+	pDot11f->WiderBWChanSwitchAnn.present = 1;
+
+	/*
+	 * Add the VHT Transmit power Envelope Sublement.
+	 */
+	ie_ptr = wlan_get_ie_ptr_from_eid(
+			DOT11F_EID_VHT_TRANSMIT_POWER_ENV,
+			psessionEntry->addIeParams.probeRespBCNData_buff,
+			psessionEntry->addIeParams.probeRespBCNDataLen);
+	if (ie_ptr) {
+		/* Ignore EID field */
+		pDot11f->vht_transmit_power_env.present = 1;
+		pDot11f->vht_transmit_power_env.num_bytes = ie_ptr[1];
+		qdf_mem_copy(pDot11f->vht_transmit_power_env.bytes,
+			&ie_ptr[2], pDot11f->vht_transmit_power_env.num_bytes);
+	}
+
+}
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+void
+populate_dot11f_avoid_channel_ie(tpAniSirGlobal mac_ctx,
+				 tDot11fIEQComVendorIE *dot11f,
+				 tpPESession pe_session)
+{
+	if (!pe_session->sap_advertise_avoid_ch_ie)
+		return;
+
+	dot11f->present = true;
+	dot11f->type = QCOM_VENDOR_IE_MCC_AVOID_CH;
+	dot11f->channel = pe_session->currentOperChannel;
+}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+void
+populate_dot11f_wider_bw_chan_switch_ann(tpAniSirGlobal pMac,
+					 tDot11fIEWiderBWChanSwitchAnn *pDot11f,
+					 tpPESession psessionEntry)
+{
+	pDot11f->present = 1;
+	pDot11f->newChanWidth =
+		psessionEntry->gLimWiderBWChannelSwitch.newChanWidth;
+	pDot11f->newCenterChanFreq0 =
+		psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0;
+	pDot11f->newCenterChanFreq1 =
+		psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1;
+}
+
+QDF_STATUS
+populate_dot11f_country(tpAniSirGlobal pMac,
+			tDot11fIECountry *pDot11f, tpPESession psessionEntry)
+{
+	uint32_t len, maxlen;
+	uint16_t item;
+	QDF_STATUS nSirStatus;
+	enum band_info rfBand;
+	uint8_t temp[CFG_MAX_STR_LEN], code[3];
+
+	if (psessionEntry->lim11dEnabled) {
+		lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
+		if (rfBand == BAND_5G) {
+			item = WNI_CFG_MAX_TX_POWER_5;
+			maxlen = WNI_CFG_MAX_TX_POWER_5_LEN;
+		} else {
+			item = WNI_CFG_MAX_TX_POWER_2_4;
+			maxlen = WNI_CFG_MAX_TX_POWER_2_4_LEN;
+		}
+
+		CFG_GET_STR(nSirStatus, pMac, item, temp, len, maxlen);
+
+		if (3 > len) {
+			/* no limit on tx power, cannot include the IE because at least */
+			/* one (channel,num,tx power) must be present */
+			return QDF_STATUS_SUCCESS;
+		}
+
+		wlan_reg_read_current_country(pMac->psoc, code);
+
+		qdf_mem_copy(pDot11f->country, code, 2);
+
+		if (len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) {
+			pe_err("len:%d is out of bounds, resetting", len);
+			len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE;
+		}
+
+		pDot11f->num_triplets = (uint8_t) (len / 3);
+		qdf_mem_copy((uint8_t *) pDot11f->triplets, temp, len);
+
+		pDot11f->present = 1;
+	}
+
+	return QDF_STATUS_SUCCESS;
+} /* End populate_dot11f_country. */
+
+/**
+ * populate_dot11f_ds_params() - To populate DS IE params
+ * mac_ctx: Pointer to global mac context
+ * dot11f_param: pointer to DS params IE
+ * channel: channel number
+ *
+ * This routine will populate DS param in management frame like
+ * beacon, probe response, and etc.
+ *
+ * Return: Overall success
+ */
+QDF_STATUS
+populate_dot11f_ds_params(tpAniSirGlobal mac_ctx,
+			  tDot11fIEDSParams *dot11f_param, uint8_t channel)
+{
+	if (IS_24G_CH(channel)) {
+		/* .11b/g mode PHY => Include the DS Parameter Set IE: */
+		dot11f_param->curr_channel = channel;
+		dot11f_param->present = 1;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#define SET_AIFSN(aifsn) (((aifsn) < 2) ? 2 : (aifsn))
+
+void
+populate_dot11f_edca_param_set(tpAniSirGlobal pMac,
+			       tDot11fIEEDCAParamSet *pDot11f,
+			       tpPESession psessionEntry)
+{
+
+	if (psessionEntry->limQosEnabled) {
+		/* change to bitwise operation, after this is fixed in frames. */
+		pDot11f->qos =
+			(uint8_t) (0xf0 &
+				   (psessionEntry->gLimEdcaParamSetCount << 4));
+
+		/* Fill each EDCA parameter set in order: be, bk, vi, vo */
+		pDot11f->acbe_aifsn =
+			(0xf &
+			 SET_AIFSN(psessionEntry->gLimEdcaParamsBC[0].aci.aifsn));
+		pDot11f->acbe_acm =
+			(0x1 & psessionEntry->gLimEdcaParamsBC[0].aci.acm);
+		pDot11f->acbe_aci = (0x3 & SIR_MAC_EDCAACI_BESTEFFORT);
+		pDot11f->acbe_acwmin =
+			(0xf & psessionEntry->gLimEdcaParamsBC[0].cw.min);
+		pDot11f->acbe_acwmax =
+			(0xf & psessionEntry->gLimEdcaParamsBC[0].cw.max);
+		pDot11f->acbe_txoplimit =
+			psessionEntry->gLimEdcaParamsBC[0].txoplimit;
+
+		pDot11f->acbk_aifsn =
+			(0xf &
+			 SET_AIFSN(psessionEntry->gLimEdcaParamsBC[1].aci.aifsn));
+		pDot11f->acbk_acm =
+			(0x1 & psessionEntry->gLimEdcaParamsBC[1].aci.acm);
+		pDot11f->acbk_aci = (0x3 & SIR_MAC_EDCAACI_BACKGROUND);
+		pDot11f->acbk_acwmin =
+			(0xf & psessionEntry->gLimEdcaParamsBC[1].cw.min);
+		pDot11f->acbk_acwmax =
+			(0xf & psessionEntry->gLimEdcaParamsBC[1].cw.max);
+		pDot11f->acbk_txoplimit =
+			psessionEntry->gLimEdcaParamsBC[1].txoplimit;
+
+		pDot11f->acvi_aifsn =
+			(0xf &
+			 SET_AIFSN(psessionEntry->gLimEdcaParamsBC[2].aci.aifsn));
+		pDot11f->acvi_acm =
+			(0x1 & psessionEntry->gLimEdcaParamsBC[2].aci.acm);
+		pDot11f->acvi_aci = (0x3 & SIR_MAC_EDCAACI_VIDEO);
+		pDot11f->acvi_acwmin =
+			(0xf & psessionEntry->gLimEdcaParamsBC[2].cw.min);
+		pDot11f->acvi_acwmax =
+			(0xf & psessionEntry->gLimEdcaParamsBC[2].cw.max);
+		pDot11f->acvi_txoplimit =
+			psessionEntry->gLimEdcaParamsBC[2].txoplimit;
+
+		pDot11f->acvo_aifsn =
+			(0xf &
+			 SET_AIFSN(psessionEntry->gLimEdcaParamsBC[3].aci.aifsn));
+		pDot11f->acvo_acm =
+			(0x1 & psessionEntry->gLimEdcaParamsBC[3].aci.acm);
+		pDot11f->acvo_aci = (0x3 & SIR_MAC_EDCAACI_VOICE);
+		pDot11f->acvo_acwmin =
+			(0xf & psessionEntry->gLimEdcaParamsBC[3].cw.min);
+		pDot11f->acvo_acwmax =
+			(0xf & psessionEntry->gLimEdcaParamsBC[3].cw.max);
+		pDot11f->acvo_txoplimit =
+			psessionEntry->gLimEdcaParamsBC[3].txoplimit;
+
+		pDot11f->present = 1;
+	}
+
+} /* End PopluateDot11fEDCAParamSet. */
+
+QDF_STATUS
+populate_dot11f_erp_info(tpAniSirGlobal pMac,
+			 tDot11fIEERPInfo *pDot11f, tpPESession psessionEntry)
+{
+	uint32_t val;
+	enum band_info rfBand = BAND_UNKNOWN;
+
+	lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
+	if (BAND_2G == rfBand) {
+		pDot11f->present = 1;
+
+		val = psessionEntry->cfgProtection.fromllb;
+		if (!val) {
+			pe_err("11B protection not enabled. Not populating ERP IE %d",
+				val);
+			return QDF_STATUS_SUCCESS;
+		}
+
+		if (psessionEntry->gLim11bParams.protectionEnabled) {
+			pDot11f->non_erp_present = 1;
+			pDot11f->use_prot = 1;
+		}
+
+		if (psessionEntry->gLimOlbcParams.protectionEnabled) {
+			/* FIXME_PROTECTION: we should be setting non_erp present also. */
+			/* check the test plan first. */
+			pDot11f->use_prot = 1;
+		}
+
+		if ((psessionEntry->gLimNoShortParams.numNonShortPreambleSta)
+		    || !psessionEntry->beaconParams.fShortPreamble) {
+			pDot11f->barker_preamble = 1;
+
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+} /* End populate_dot11f_erp_info. */
+
+QDF_STATUS
+populate_dot11f_ext_supp_rates(tpAniSirGlobal pMac, uint8_t nChannelNum,
+			       tDot11fIEExtSuppRates *pDot11f,
+			       tpPESession psessionEntry)
+{
+	QDF_STATUS nsir_status;
+	qdf_size_t nRates = 0;
+	uint8_t rates[SIR_MAC_RATESET_EID_MAX];
+
+	/* Use the ext rates present in session entry whenever nChannelNum is set to OPERATIONAL
+	   else use the ext supported rate set from CFG, which is fixed and does not change dynamically and is used for
+	   sending mgmt frames (lile probe req) which need to go out before any session is present.
+	 */
+	if (POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum) {
+		if (psessionEntry != NULL) {
+			nRates = psessionEntry->extRateSet.numRates;
+			qdf_mem_copy(rates, psessionEntry->extRateSet.rate,
+				     nRates);
+		} else {
+			pe_err("no session context exists while populating Operational Rate Set");
+		}
+	} else if (HIGHEST_24GHZ_CHANNEL_NUM >= nChannelNum) {
+		nRates = pMac->mlme_cfg->rates.ext_opr_rate_set.len;
+		nsir_status = wlan_mlme_get_cfg_str(
+			rates,
+			&pMac->mlme_cfg->rates.ext_opr_rate_set, &nRates);
+		if (QDF_IS_STATUS_ERROR(nsir_status)) {
+			nRates = 0;
+			pe_err("Failed to retrieve nItem from CFG status: %d",
+			       (nsir_status));
+			return nsir_status;
+		}
+	}
+
+	if (0 != nRates) {
+		pDot11f->num_rates = (uint8_t) nRates;
+		qdf_mem_copy(pDot11f->rates, rates, nRates);
+		pDot11f->present = 1;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End populate_dot11f_ext_supp_rates. */
+
+QDF_STATUS
+populate_dot11f_ext_supp_rates1(tpAniSirGlobal pMac,
+				uint8_t nChannelNum,
+				tDot11fIEExtSuppRates *pDot11f)
+{
+	qdf_size_t nRates;
+	QDF_STATUS nsir_status;
+	uint8_t rates[SIR_MAC_MAX_NUMBER_OF_RATES];
+
+	if (14 < nChannelNum) {
+		pDot11f->present = 0;
+		return QDF_STATUS_SUCCESS;
+	}
+	/* N.B. I have *no* idea why we're calling 'wlan_cfg_get_str' with an argument */
+	/* of WNI_CFG_SUPPORTED_RATES_11A here, but that's what was done */
+	/* previously & I'm afraid to change it! */
+	nRates = SIR_MAC_MAX_NUMBER_OF_RATES;
+	nsir_status = wlan_mlme_get_cfg_str(
+				rates,
+				&pMac->mlme_cfg->rates.supported_11a,
+				&nRates);
+	if (QDF_IS_STATUS_ERROR(nsir_status)) {
+		pe_err("Failed to retrieve nItem from CFG status: %d",
+		       (nsir_status));
+		return nsir_status;
+	}
+
+	if (0 != nRates) {
+		pDot11f->num_rates = (uint8_t) nRates;
+		qdf_mem_copy(pDot11f->rates, rates, nRates);
+		pDot11f->present = 1;
+	}
+
+	return QDF_STATUS_SUCCESS;
+} /* populate_dot11f_ext_supp_rates1. */
+
+QDF_STATUS
+populate_dot11f_ht_caps(tpAniSirGlobal pMac,
+			tpPESession psessionEntry, tDot11fIEHTCaps *pDot11f)
+{
+	uint32_t nCfgValue;
+	uint8_t nCfgValue8;
+	qdf_size_t ncfglen;
+	QDF_STATUS nSirStatus;
+	uint8_t disable_high_ht_mcs_2x2 = 0;
+
+	tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo;
+	tSirMacASCapabilityInfo *pASCapabilityInfo;
+	struct mlme_ht_capabilities_info *ht_cap_info;
+
+	ht_cap_info = &pMac->mlme_cfg->ht_caps.ht_cap_info;
+
+	pDot11f->mimoPowerSave = ht_cap_info->mimo_power_save;
+	pDot11f->greenField = ht_cap_info->green_field;
+	pDot11f->delayedBA = ht_cap_info->delayed_ba;
+	pDot11f->maximalAMSDUsize = ht_cap_info->maximal_amsdu_size;
+	pDot11f->dsssCckMode40MHz = ht_cap_info->dsss_cck_mode_40_mhz;
+	pDot11f->psmp = ht_cap_info->psmp;
+	pDot11f->stbcControlFrame = ht_cap_info->stbc_control_frame;
+	pDot11f->lsigTXOPProtection = ht_cap_info->l_sig_tx_op_protection;
+
+	/* All sessionized entries will need the check below */
+	if (psessionEntry == NULL) {     /* Only in case of NO session */
+		pDot11f->supportedChannelWidthSet =
+			ht_cap_info->supported_channel_width_set;
+		pDot11f->advCodingCap = ht_cap_info->adv_coding_cap;
+		pDot11f->txSTBC = ht_cap_info->tx_stbc;
+		pDot11f->rxSTBC = ht_cap_info->rx_stbc;
+		pDot11f->shortGI20MHz = ht_cap_info->short_gi_20_mhz;
+		pDot11f->shortGI40MHz = ht_cap_info->short_gi_40_mhz;
+	} else {
+		pDot11f->advCodingCap = psessionEntry->htConfig.ht_rx_ldpc;
+		pDot11f->supportedChannelWidthSet =
+			psessionEntry->htSupportedChannelWidthSet;
+		pDot11f->txSTBC = psessionEntry->htConfig.ht_tx_stbc;
+		pDot11f->rxSTBC = psessionEntry->htConfig.ht_rx_stbc;
+		pDot11f->shortGI20MHz = psessionEntry->htConfig.ht_sgi20;
+		pDot11f->shortGI40MHz = psessionEntry->htConfig.ht_sgi40;
+	}
+
+	/* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is
+	   eHT_CHANNEL_WIDTH_20MHZ */
+	if (pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) {
+		pDot11f->shortGI40MHz = 0;
+	}
+
+	pDot11f->maxRxAMPDUFactor =
+		pMac->mlme_cfg->ht_caps.ampdu_params.max_rx_ampdu_factor;
+	pDot11f->mpduDensity =
+		pMac->mlme_cfg->ht_caps.ampdu_params.mpdu_density;
+	pDot11f->reserved1 = pMac->mlme_cfg->ht_caps.ampdu_params.reserved;
+
+	ncfglen = SIZE_OF_SUPPORTED_MCS_SET;
+	nSirStatus = wlan_mlme_get_cfg_str(
+		pDot11f->supportedMCSSet,
+		&pMac->mlme_cfg->rates.supported_mcs_set,
+		&ncfglen);
+	if (QDF_IS_STATUS_ERROR(nSirStatus)) {
+		pe_err("Failed to retrieve nItem from CFG status: %d",
+		       (nSirStatus));
+			return nSirStatus;
+	}
+
+	if (psessionEntry) {
+		disable_high_ht_mcs_2x2 =
+				pMac->mlme_cfg->rates.disable_high_ht_mcs_2x2;
+		pe_debug("disable HT high MCS INI param[%d]",
+			 disable_high_ht_mcs_2x2);
+		if (psessionEntry->nss == NSS_1x1_MODE) {
+			pDot11f->supportedMCSSet[1] = 0;
+		} else if (IS_24G_CH(psessionEntry->currentOperChannel) &&
+			   disable_high_ht_mcs_2x2 &&
+			   (psessionEntry->pePersona == QDF_STA_MODE)) {
+				pe_debug("Disabling high HT MCS [%d]",
+					 disable_high_ht_mcs_2x2);
+				pDot11f->supportedMCSSet[1] =
+					(pDot11f->supportedMCSSet[1] >>
+						disable_high_ht_mcs_2x2);
+		}
+	}
+
+	/* If STA mode, session supported NSS > 1 and
+	 * SMPS enabled publish HT SMPS IE
+	 */
+	if (psessionEntry &&
+	    LIM_IS_STA_ROLE(psessionEntry) &&
+	    (psessionEntry->enableHtSmps) &&
+	    (!psessionEntry->supported_nss_1x1)) {
+		pe_debug("Add SM power save IE: %d",
+			psessionEntry->htSmpsvalue);
+		pDot11f->mimoPowerSave = psessionEntry->htSmpsvalue;
+	}
+
+	pDot11f->pco = pMac->mlme_cfg->ht_caps.ext_cap_info.pco;
+	pDot11f->transitionTime =
+		pMac->mlme_cfg->ht_caps.ext_cap_info.transition_time;
+	pDot11f->mcsFeedback =
+		pMac->mlme_cfg->ht_caps.ext_cap_info.mcs_feedback;
+
+	CFG_GET_INT(nSirStatus, pMac, WNI_CFG_TX_BF_CAP, nCfgValue);
+
+	pTxBFCapabilityInfo = (tSirMacTxBFCapabilityInfo *) &nCfgValue;
+	pDot11f->txBF = pTxBFCapabilityInfo->txBF;
+	pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding;
+	pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding;
+	pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF;
+	pDot11f->txZLF = pTxBFCapabilityInfo->txZLF;
+	pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF;
+	pDot11f->calibration = pTxBFCapabilityInfo->calibration;
+	pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF;
+	pDot11f->explicitUncompressedSteeringMatrix =
+		pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix;
+	pDot11f->explicitBFCSIFeedback =
+		pTxBFCapabilityInfo->explicitBFCSIFeedback;
+	pDot11f->explicitUncompressedSteeringMatrixFeedback =
+		pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback;
+	pDot11f->explicitCompressedSteeringMatrixFeedback =
+		pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback;
+	pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae;
+	pDot11f->uncompressedSteeringMatrixBFAntennae =
+		pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae;
+	pDot11f->compressedSteeringMatrixBFAntennae =
+		pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae;
+
+	CFG_GET_INT(nSirStatus, pMac, WNI_CFG_AS_CAP, nCfgValue);
+
+	nCfgValue8 = (uint8_t) nCfgValue;
+
+	pASCapabilityInfo = (tSirMacASCapabilityInfo *) &nCfgValue8;
+	pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection;
+	pDot11f->explicitCSIFeedbackTx =
+		pASCapabilityInfo->explicitCSIFeedbackTx;
+	pDot11f->antennaIndicesFeedbackTx =
+		pASCapabilityInfo->antennaIndicesFeedbackTx;
+	pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback;
+	pDot11f->antennaIndicesFeedback =
+		pASCapabilityInfo->antennaIndicesFeedback;
+	pDot11f->rxAS = pASCapabilityInfo->rxAS;
+	pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs;
+
+	pDot11f->present = 1;
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End populate_dot11f_ht_caps. */
+
+void lim_log_vht_cap(tpAniSirGlobal pMac, tDot11fIEVHTCaps *pDot11f)
+{
+#ifdef DUMP_MGMT_CNTNTS
+	pe_debug("maxMPDULen (2): %d", pDot11f->maxMPDULen);
+	pe_debug("supportedChannelWidthSet (2): %d",
+		pDot11f->supportedChannelWidthSet);
+	pe_debug("ldpcCodingCap (1): %d",
+		pDot11f->ldpcCodingCap);
+	pe_debug("shortGI80MHz (1): %d", pDot11f->shortGI80MHz);
+	pe_debug("shortGI160and80plus80MHz (1): %d",
+		pDot11f->shortGI160and80plus80MHz);
+	pe_debug("txSTBC (1): %d", pDot11f->txSTBC);
+	pe_debug("rxSTBC (3): %d", pDot11f->rxSTBC);
+	pe_debug("suBeamFormerCap (1): %d",
+		pDot11f->suBeamFormerCap);
+	pe_debug("suBeamformeeCap (1): %d",
+		pDot11f->suBeamformeeCap);
+	pe_debug("csnofBeamformerAntSup (3): %d",
+		pDot11f->csnofBeamformerAntSup);
+	pe_debug("numSoundingDim (3): %d",
+		pDot11f->numSoundingDim);
+	pe_debug("muBeamformerCap (1): %d",
+		pDot11f->muBeamformerCap);
+	pe_debug("muBeamformeeCap (1): %d",
+		pDot11f->muBeamformeeCap);
+	pe_debug("vhtTXOPPS (1): %d", pDot11f->vhtTXOPPS);
+	pe_debug("htcVHTCap (1): %d", pDot11f->htcVHTCap);
+	pe_debug("maxAMPDULenExp (3): %d",
+		pDot11f->maxAMPDULenExp);
+	pe_debug("vhtLinkAdaptCap (2): %d",
+		pDot11f->vhtLinkAdaptCap);
+	pe_debug("rxAntPattern (1): %d",
+		pDot11f->rxAntPattern;
+	pe_debug("txAntPattern (1): %d",
+		pDot11f->txAntPattern);
+	pe_debug("reserved1 (2): %d", pDot11f->reserved1);
+	pe_debug("rxMCSMap (16): %d", pDot11f->rxMCSMap);
+	pe_debug("rxHighSupDataRate (13): %d",
+		pDot11f->rxHighSupDataRate);
+	pe_debug("reserved2(3): %d", pDot11f->reserved2);
+	pe_debug("txMCSMap (16): %d", pDot11f->txMCSMap);
+	pe_debug("txSupDataRate (13): %d"),
+		pDot11f->txSupDataRate;
+	pe_debug("reserved3 (3): %d", pDot11f->reserved3);
+#endif /* DUMP_MGMT_CNTNTS */
+}
+
+static void lim_log_vht_operation(tpAniSirGlobal pMac,
+				  tDot11fIEVHTOperation *pDot11f)
+{
+#ifdef DUMP_MGMT_CNTNTS
+	pe_debug("chanWidth: %d", pDot11f->chanWidth);
+	pe_debug("chanCenterFreqSeg1: %d",
+		pDot11f->chanCenterFreqSeg1);
+	pe_debug("chanCenterFreqSeg2: %d",
+		pDot11f->chanCenterFreqSeg2);
+	pe_debug("basicMCSSet: %d", pDot11f->basicMCSSet);
+#endif /* DUMP_MGMT_CNTNTS */
+}
+
+static void lim_log_operating_mode(tpAniSirGlobal pMac,
+				   tDot11fIEOperatingMode *pDot11f)
+{
+#ifdef DUMP_MGMT_CNTNTS
+	pe_debug("ChanWidth: %d", pDot11f->chanWidth);
+	pe_debug("reserved: %d", pDot11f->reserved);
+	pe_debug("rxNSS: %d", pDot11f->rxNSS);
+	pe_debug("rxNSS Type: %d", pDot11f->rxNSSType);
+#endif /* DUMP_MGMT_CNTNTS */
+}
+
+static void lim_log_qos_map_set(tpAniSirGlobal pMac, tSirQosMapSet *pQosMapSet)
+{
+	uint8_t i;
+
+	if (pQosMapSet->num_dscp_exceptions > QOS_MAP_MAX_EX)
+		pQosMapSet->num_dscp_exceptions = QOS_MAP_MAX_EX;
+
+	pe_debug("num of dscp exceptions: %d",
+		pQosMapSet->num_dscp_exceptions);
+	for (i = 0; i < pQosMapSet->num_dscp_exceptions; i++) {
+		pe_debug("dscp value: %d",
+			pQosMapSet->dscp_exceptions[i][0]);
+		pe_debug("User priority value: %d",
+			pQosMapSet->dscp_exceptions[i][1]);
+	}
+	for (i = 0; i < 8; i++) {
+		pe_debug("dscp low for up %d: %d", i,
+			pQosMapSet->dscp_range[i][0]);
+		pe_debug("dscp high for up %d: %d", i,
+			pQosMapSet->dscp_range[i][1]);
+	}
+}
+
+QDF_STATUS
+populate_dot11f_vht_caps(tpAniSirGlobal pMac,
+			 tpPESession psessionEntry, tDot11fIEVHTCaps *pDot11f)
+{
+	uint32_t nCfgValue = 0;
+	struct mlme_vht_capabilities_info vht_cap_info;
+
+	if (!(pMac->mlme_cfg)) {
+		pe_err("invalid mlme cfg");
+		return QDF_STATUS_E_FAILURE;
+	}
+	vht_cap_info = pMac->mlme_cfg->vht_caps.vht_cap_info;
+
+	pDot11f->present = 1;
+
+	nCfgValue = vht_cap_info.ampdu_len;
+	pDot11f->maxMPDULen = (nCfgValue & 0x0003);
+
+	nCfgValue = vht_cap_info.supp_chan_width;
+	pDot11f->supportedChannelWidthSet = (nCfgValue & 0x0003);
+
+	nCfgValue = 0;
+	/* With VHT it suffices if we just examine HT */
+	if (psessionEntry) {
+		if (psessionEntry->htConfig.ht_rx_ldpc)
+			pDot11f->ldpcCodingCap =
+				psessionEntry->vht_config.ldpc_coding;
+		if (psessionEntry->ch_width < CH_WIDTH_80MHZ) {
+			 pDot11f->shortGI80MHz = 0;
+		} else {
+			pDot11f->shortGI80MHz =
+				psessionEntry->vht_config.shortgi80;
+		}
+
+		if (psessionEntry->ch_width < CH_WIDTH_160MHZ) {
+			pDot11f->shortGI160and80plus80MHz = 0;
+			pDot11f->supportedChannelWidthSet = 0;
+		} else {
+			pDot11f->shortGI160and80plus80MHz =
+				psessionEntry->vht_config.shortgi160and80plus80;
+		}
+
+		if (psessionEntry->htConfig.ht_tx_stbc)
+			pDot11f->txSTBC = psessionEntry->vht_config.tx_stbc;
+
+		if (psessionEntry->htConfig.ht_rx_stbc)
+			pDot11f->rxSTBC = psessionEntry->vht_config.rx_stbc;
+
+		pDot11f->suBeamformeeCap =
+			psessionEntry->vht_config.su_beam_formee;
+		if (psessionEntry->vht_config.su_beam_formee) {
+			pDot11f->muBeamformeeCap =
+				psessionEntry->vht_config.mu_beam_formee;
+			pDot11f->csnofBeamformerAntSup =
+			      psessionEntry->vht_config.csnof_beamformer_antSup;
+		} else {
+			pDot11f->muBeamformeeCap = 0;
+		}
+		pDot11f->suBeamFormerCap =
+			psessionEntry->vht_config.su_beam_former;
+
+		pDot11f->vhtTXOPPS = psessionEntry->vht_config.vht_txops;
+
+		pDot11f->numSoundingDim =
+				psessionEntry->vht_config.num_soundingdim;
+
+		pDot11f->htcVHTCap = psessionEntry->vht_config.htc_vhtcap;
+
+		pDot11f->rxAntPattern = psessionEntry->vht_config.rx_antpattern;
+
+		pDot11f->txAntPattern = psessionEntry->vht_config.tx_antpattern;
+
+		pDot11f->maxAMPDULenExp =
+				psessionEntry->vht_config.max_ampdu_lenexp;
+
+		pDot11f->vhtLinkAdaptCap =
+				psessionEntry->vht_config.vht_link_adapt;
+	} else {
+		nCfgValue = vht_cap_info.ldpc_coding_cap;
+		pDot11f->ldpcCodingCap = (nCfgValue & 0x0001);
+
+		nCfgValue = vht_cap_info.short_gi_80mhz;
+		pDot11f->shortGI80MHz = (nCfgValue & 0x0001);
+
+		nCfgValue = vht_cap_info.short_gi_160mhz;
+		pDot11f->shortGI160and80plus80MHz = (nCfgValue & 0x0001);
+
+		nCfgValue = vht_cap_info.tx_stbc;
+		pDot11f->txSTBC = (nCfgValue & 0x0001);
+
+		nCfgValue = vht_cap_info.rx_stbc;
+		pDot11f->rxSTBC = (nCfgValue & 0x0007);
+
+		nCfgValue = vht_cap_info.su_bformee;
+		pDot11f->suBeamformeeCap = (nCfgValue & 0x0001);
+
+		nCfgValue = vht_cap_info.enable_mu_bformee;
+		pDot11f->muBeamformeeCap = (nCfgValue & 0x0001);
+
+		nCfgValue = vht_cap_info.su_bformer;
+		pDot11f->suBeamFormerCap = (nCfgValue & 0x0001);
+
+		nCfgValue = vht_cap_info.tx_bfee_ant_supp;
+		pDot11f->csnofBeamformerAntSup = (nCfgValue & 0x0007);
+
+		nCfgValue = vht_cap_info.txop_ps;
+		pDot11f->vhtTXOPPS = (nCfgValue & 0x0001);
+
+		nCfgValue = vht_cap_info.num_soundingdim;
+		pDot11f->numSoundingDim = (nCfgValue & 0x0007);
+
+		nCfgValue = vht_cap_info.htc_vhtc;
+		pDot11f->htcVHTCap = (nCfgValue & 0x0001);
+
+		pDot11f->rxAntPattern = vht_cap_info.rx_antpattern;
+
+		pDot11f->txAntPattern = vht_cap_info.tx_antpattern;
+
+		nCfgValue = vht_cap_info.ampdu_len_exponent;
+		pDot11f->maxAMPDULenExp = (nCfgValue & 0x0007);
+
+		nCfgValue = vht_cap_info.link_adap_cap;
+		pDot11f->vhtLinkAdaptCap = (nCfgValue & 0x0003);
+
+	}
+
+	nCfgValue = vht_cap_info.mu_bformer;
+	pDot11f->muBeamformerCap = (nCfgValue & 0x0001);
+
+	pDot11f->reserved1 = 0;
+
+	nCfgValue = vht_cap_info.rx_mcs_map;
+	pDot11f->rxMCSMap = (nCfgValue & 0x0000FFFF);
+
+	nCfgValue = vht_cap_info.rx_supp_data_rate;
+	pDot11f->rxHighSupDataRate = (nCfgValue & 0x00001FFF);
+
+	pDot11f->reserved2 = 0;
+
+	nCfgValue = vht_cap_info.tx_mcs_map;
+	pDot11f->txMCSMap = (nCfgValue & 0x0000FFFF);
+
+	nCfgValue = vht_cap_info.tx_supp_data_rate;
+	pDot11f->txSupDataRate = (nCfgValue & 0x00001FFF);
+
+	pDot11f->reserved3 = 0;
+	if (psessionEntry) {
+		if (psessionEntry->nss == NSS_1x1_MODE) {
+			pDot11f->txMCSMap |= DISABLE_NSS2_MCS;
+			pDot11f->rxMCSMap |= DISABLE_NSS2_MCS;
+			pDot11f->txSupDataRate =
+				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+			pDot11f->rxHighSupDataRate =
+				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
+			if (!psessionEntry->ch_width &&
+			    !vht_cap_info.enable_vht20_mcs9 &&
+			    ((pDot11f->txMCSMap & VHT_1x1_MCS_MASK) ==
+			     VHT_1x1_MCS9_MAP)) {
+				DISABLE_VHT_MCS_9(pDot11f->txMCSMap,
+						NSS_1x1_MODE);
+				DISABLE_VHT_MCS_9(pDot11f->rxMCSMap,
+						NSS_1x1_MODE);
+			}
+		} else {
+			if (!psessionEntry->ch_width &&
+			    !vht_cap_info.enable_vht20_mcs9 &&
+			    ((pDot11f->txMCSMap & VHT_2x2_MCS_MASK) ==
+			     VHT_2x2_MCS9_MAP)) {
+				DISABLE_VHT_MCS_9(pDot11f->txMCSMap,
+						NSS_2x2_MODE);
+				DISABLE_VHT_MCS_9(pDot11f->rxMCSMap,
+						NSS_2x2_MODE);
+			}
+		}
+	}
+	lim_log_vht_cap(pMac, pDot11f);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+populate_dot11f_vht_operation(tpAniSirGlobal pMac,
+			      tpPESession psessionEntry,
+			      tDot11fIEVHTOperation *pDot11f)
+{
+	pDot11f->present = 1;
+
+	if (psessionEntry->ch_width > CH_WIDTH_40MHZ) {
+		pDot11f->chanWidth = 1;
+		pDot11f->chanCenterFreqSeg1 =
+			psessionEntry->ch_center_freq_seg0;
+		if (psessionEntry->ch_width == CH_WIDTH_80P80MHZ ||
+				psessionEntry->ch_width == CH_WIDTH_160MHZ)
+			pDot11f->chanCenterFreqSeg2 =
+				psessionEntry->ch_center_freq_seg1;
+		else
+			pDot11f->chanCenterFreqSeg2 = 0;
+	} else {
+		pDot11f->chanWidth = 0;
+		pDot11f->chanCenterFreqSeg1 = 0;
+		pDot11f->chanCenterFreqSeg2 = 0;
+	}
+
+	pDot11f->basicMCSSet =
+		(uint16_t)pMac->mlme_cfg->vht_caps.vht_cap_info.basic_mcs_set;
+
+	lim_log_vht_operation(pMac, pDot11f);
+
+	return QDF_STATUS_SUCCESS;
+
+}
+
+QDF_STATUS
+populate_dot11f_ext_cap(tpAniSirGlobal pMac,
+			bool isVHTEnabled, tDot11fIEExtCap *pDot11f,
+			tpPESession psessionEntry)
+{
+	struct s_ext_cap *p_ext_cap;
+
+	pDot11f->present = 1;
+
+	if (!psessionEntry) {
+		pe_debug("11MC - enabled for non-SAP cases");
+		pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
+	} else if (psessionEntry->sap_dot11mc) {
+		pe_debug("11MC support enabled");
+		pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
+	} else {
+		if (eLIM_AP_ROLE != psessionEntry->limSystemRole) {
+			pe_debug("11MC support enabled");
+			pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
+		} else  {
+			pe_debug("11MC support disabled");
+			pDot11f->num_bytes = DOT11F_IE_EXTCAP_MIN_LEN;
+		}
+	}
+
+	p_ext_cap = (struct s_ext_cap *)pDot11f->bytes;
+	if (isVHTEnabled == true)
+		p_ext_cap->oper_mode_notification = 1;
+
+	if (pMac->mlme_cfg->gen.rtt3_enabled) {
+		uint32_t ftm = ucfg_wifi_pos_get_ftm_cap(pMac->psoc);
+		if (!psessionEntry || LIM_IS_STA_ROLE(psessionEntry)) {
+			p_ext_cap->fine_time_meas_initiator =
+				(ftm & WMI_FW_STA_RTT_INITR) ? 1 : 0;
+			p_ext_cap->fine_time_meas_responder =
+				(ftm & WMI_FW_STA_RTT_RESPR) ? 1 : 0;
+		} else if (LIM_IS_AP_ROLE(psessionEntry)) {
+			p_ext_cap->fine_time_meas_initiator =
+				(ftm & WMI_FW_AP_RTT_INITR) ? 1 : 0;
+			p_ext_cap->fine_time_meas_responder =
+				(ftm & WMI_FW_AP_RTT_RESPR) ? 1 : 0;
+		}
+	}
+#ifdef QCA_HT_2040_COEX
+	if (pMac->roam.configParam.obssEnabled)
+		p_ext_cap->bss_coexist_mgmt_support = 1;
+#endif
+	p_ext_cap->ext_chan_switch = 1;
+
+	if (psessionEntry && psessionEntry->enable_bcast_probe_rsp)
+		p_ext_cap->fils_capability = 1;
+
+	/* Need to calculate the num_bytes based on bits set */
+	if (pDot11f->present)
+		pDot11f->num_bytes = lim_compute_ext_cap_ie_length(pDot11f);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void populate_dot11f_qcn_ie(tDot11fIEQCN_IE *pDot11f)
+{
+	pDot11f->present = 1;
+	pDot11f->version[0] = QCN_IE_VERSION_SUBATTR_ID;
+	pDot11f->version[1] = QCN_IE_VERSION_SUBATTR_DATA_LEN;
+	pDot11f->version[2] = QCN_IE_VERSION_SUPPORTED;
+	pDot11f->version[3] = QCN_IE_SUBVERSION_SUPPORTED;
+}
+
+QDF_STATUS
+populate_dot11f_operating_mode(tpAniSirGlobal pMac,
+			       tDot11fIEOperatingMode *pDot11f,
+			       tpPESession psessionEntry)
+{
+	pDot11f->present = 1;
+
+	pDot11f->chanWidth = psessionEntry->gLimOperatingMode.chanWidth;
+	pDot11f->rxNSS = psessionEntry->gLimOperatingMode.rxNSS;
+	pDot11f->rxNSSType = psessionEntry->gLimOperatingMode.rxNSSType;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+populate_dot11f_ht_info(tpAniSirGlobal pMac,
+			tDot11fIEHTInfo *pDot11f, tpPESession psessionEntry)
+{
+	qdf_size_t ncfglen;
+	QDF_STATUS nSirStatus;
+
+	if (NULL == psessionEntry) {
+		pe_err("Invalid session entry");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pDot11f->primaryChannel = psessionEntry->currentOperChannel;
+
+	pDot11f->secondaryChannelOffset =
+		psessionEntry->htSecondaryChannelOffset;
+	pDot11f->recommendedTxWidthSet =
+		psessionEntry->htRecommendedTxWidthSet;
+	pDot11f->rifsMode = psessionEntry->beaconParams.fRIFSMode;
+	pDot11f->controlledAccessOnly =
+		pMac->mlme_cfg->ht_caps.info_field_1.controlled_access_only;
+	pDot11f->serviceIntervalGranularity =
+		pMac->lim.gHTServiceIntervalGranularity;
+
+	if (LIM_IS_AP_ROLE(psessionEntry)) {
+		pDot11f->opMode = psessionEntry->htOperMode;
+		pDot11f->nonGFDevicesPresent =
+			psessionEntry->beaconParams.llnNonGFCoexist;
+		pDot11f->obssNonHTStaPresent =
+			psessionEntry->beaconParams.gHTObssMode;
+		pDot11f->reserved = 0;
+	} else {
+		pDot11f->opMode = 0;
+		pDot11f->nonGFDevicesPresent = 0;
+		pDot11f->obssNonHTStaPresent = 0;
+		pDot11f->reserved = 0;
+	}
+
+	pDot11f->basicSTBCMCS = pMac->lim.gHTSTBCBasicMCS;
+	pDot11f->dualCTSProtection = pMac->lim.gHTDualCTSProtection;
+	pDot11f->secondaryBeacon = pMac->lim.gHTSecondaryBeacon;
+	pDot11f->lsigTXOPProtectionFullSupport =
+		psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport;
+	pDot11f->pcoActive = pMac->lim.gHTPCOActive;
+	pDot11f->pcoPhase = pMac->lim.gHTPCOPhase;
+	pDot11f->reserved2 = 0;
+
+	ncfglen = SIZE_OF_BASIC_MCS_SET;
+	nSirStatus = wlan_mlme_get_cfg_str(pDot11f->basicMCSSet,
+					   &pMac->mlme_cfg->rates.basic_mcs_set,
+					   &ncfglen);
+	if (QDF_IS_STATUS_ERROR(nSirStatus)) {
+		pe_err("Failed to retrieve nItem from CFG status: %d",
+		       (nSirStatus));
+		return nSirStatus;
+	}
+
+	pDot11f->present = 1;
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End populate_dot11f_ht_info. */
+
+void
+populate_dot11f_ibss_params(tpAniSirGlobal pMac,
+			    tDot11fIEIBSSParams *pDot11f,
+			    tpPESession psessionEntry)
+{
+	uint32_t val = 0;
+
+	if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+		if (wlan_cfg_get_int(pMac,
+				     WNI_CFG_IBSS_ATIM_WIN_SIZE,
+				     &val) != QDF_STATUS_SUCCESS) {
+			pe_err("could not retrieve IBSS ATIM WIN size");
+		}
+		pDot11f->present = 1;
+		/* ATIM duration is always set to 0 */
+		pDot11f->atim = val;
+	}
+
+} /* End populate_dot11f_ibss_params. */
+
+#ifdef ANI_SUPPORT_11H
+QDF_STATUS
+populate_dot11f_measurement_report0(tpAniSirGlobal pMac,
+				    tpSirMacMeasReqActionFrame pReq,
+				    tDot11fIEMeasurementReport *pDot11f)
+{
+	pDot11f->token = pReq->measReqIE.measToken;
+	pDot11f->late = 0;
+	pDot11f->incapable = 0;
+	pDot11f->refused = 1;
+	pDot11f->type = SIR_MAC_BASIC_MEASUREMENT_TYPE;
+
+	pDot11f->present = 1;
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End PopulatedDot11fMeasurementReport0. */
+QDF_STATUS
+populate_dot11f_measurement_report1(tpAniSirGlobal pMac,
+				    tpSirMacMeasReqActionFrame pReq,
+				    tDot11fIEMeasurementReport *pDot11f)
+{
+	pDot11f->token = pReq->measReqIE.measToken;
+	pDot11f->late = 0;
+	pDot11f->incapable = 0;
+	pDot11f->refused = 1;
+	pDot11f->type = SIR_MAC_CCA_MEASUREMENT_TYPE;
+	pDot11f->present = 1;
+	return QDF_STATUS_SUCCESS;
+} /* End PopulatedDot11fMeasurementReport1. */
+QDF_STATUS
+populate_dot11f_measurement_report2(tpAniSirGlobal pMac,
+				    tpSirMacMeasReqActionFrame pReq,
+				    tDot11fIEMeasurementReport *pDot11f)
+{
+	pDot11f->token = pReq->measReqIE.measToken;
+	pDot11f->late = 0;
+	pDot11f->incapable = 0;
+	pDot11f->refused = 1;
+	pDot11f->type = SIR_MAC_RPI_MEASUREMENT_TYPE;
+	pDot11f->present = 1;
+	return QDF_STATUS_SUCCESS;
+} /* End PopulatedDot11fMeasurementReport2. */
+#endif
+
+void
+populate_dot11f_power_caps(tpAniSirGlobal pMac,
+			   tDot11fIEPowerCaps *pCaps,
+			   uint8_t nAssocType, tpPESession psessionEntry)
+{
+	if (nAssocType == LIM_REASSOC) {
+		pCaps->minTxPower =
+			psessionEntry->pLimReAssocReq->powerCap.minTxPower;
+		pCaps->maxTxPower =
+			psessionEntry->pLimReAssocReq->powerCap.maxTxPower;
+	} else {
+		pCaps->minTxPower =
+			psessionEntry->pLimJoinReq->powerCap.minTxPower;
+		pCaps->maxTxPower =
+			psessionEntry->pLimJoinReq->powerCap.maxTxPower;
+
+	}
+
+	pCaps->present = 1;
+} /* End populate_dot11f_power_caps. */
+
+QDF_STATUS
+populate_dot11f_power_constraints(tpAniSirGlobal pMac,
+				  tDot11fIEPowerConstraints *pDot11f)
+{
+	uint32_t cfg;
+	QDF_STATUS nSirStatus;
+
+	CFG_GET_INT(nSirStatus, pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, cfg);
+
+	pDot11f->localPowerConstraints = (uint8_t) cfg;
+	pDot11f->present = 1;
+
+	return QDF_STATUS_SUCCESS;
+} /* End populate_dot11f_power_constraints. */
+
+void
+populate_dot11f_qos_caps_ap(tpAniSirGlobal pMac,
+			    tDot11fIEQOSCapsAp *pDot11f, tpPESession psessionEntry)
+{
+	pDot11f->count = psessionEntry->gLimEdcaParamSetCount;
+	pDot11f->reserved = 0;
+	pDot11f->txopreq = 0;
+	pDot11f->qreq = 0;
+	pDot11f->qack = 0;
+	pDot11f->present = 1;
+} /* End PopulatedDot11fQOSCaps. */
+
+void
+populate_dot11f_qos_caps_station(tpAniSirGlobal pMac, tpPESession pe_session,
+				 tDot11fIEQOSCapsStation *pDot11f)
+{
+	uint8_t max_sp_length = 0;
+
+	max_sp_length = pMac->mlme_cfg->wmm_params.max_sp_length;
+
+	pDot11f->more_data_ack = 0;
+	pDot11f->max_sp_length = max_sp_length;
+	pDot11f->qack = 0;
+
+	if (pMac->lim.gUapsdEnable) {
+		pDot11f->acbe_uapsd =
+			LIM_UAPSD_GET(ACBE, pe_session->gUapsdPerAcBitmask);
+		pDot11f->acbk_uapsd =
+			LIM_UAPSD_GET(ACBK, pe_session->gUapsdPerAcBitmask);
+		pDot11f->acvi_uapsd =
+			LIM_UAPSD_GET(ACVI, pe_session->gUapsdPerAcBitmask);
+		pDot11f->acvo_uapsd =
+			LIM_UAPSD_GET(ACVO, pe_session->gUapsdPerAcBitmask);
+	}
+	pDot11f->present = 1;
+} /* End PopulatedDot11fQOSCaps. */
+
+QDF_STATUS
+populate_dot11f_rsn(tpAniSirGlobal pMac,
+		    tpSirRSNie pRsnIe, tDot11fIERSN *pDot11f)
+{
+	uint32_t status;
+	int idx;
+
+	if (pRsnIe->length) {
+		idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_RSN);
+		if (0 <= idx) {
+			status = dot11f_unpack_ie_rsn(pMac, pRsnIe->rsnIEdata + idx + 2,   /* EID, length */
+						      pRsnIe->rsnIEdata[idx + 1],
+						      pDot11f, false);
+			if (DOT11F_FAILED(status)) {
+				pe_err("Parse failure in Populate Dot11fRSN (0x%08x)",
+					status);
+				return QDF_STATUS_E_FAILURE;
+			}
+			pe_debug("status 0x%08x", status);
+		}
+
+	}
+
+	return QDF_STATUS_SUCCESS;
+} /* End populate_dot11f_rsn. */
+
+QDF_STATUS populate_dot11f_rsn_opaque(tpAniSirGlobal pMac,
+					 tpSirRSNie pRsnIe,
+					 tDot11fIERSNOpaque *pDot11f)
+{
+	int idx;
+
+	if (pRsnIe->length) {
+		idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_RSN);
+		if (0 <= idx) {
+			pDot11f->present = 1;
+			pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1];
+			qdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2,        /* EID, len */
+				     pRsnIe->rsnIEdata[idx + 1]);
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End populate_dot11f_rsn_opaque. */
+
+#if defined(FEATURE_WLAN_WAPI)
+
+QDF_STATUS
+populate_dot11f_wapi(tpAniSirGlobal pMac,
+		     tpSirRSNie pRsnIe, tDot11fIEWAPI *pDot11f)
+{
+	uint32_t status;
+	int idx;
+
+	if (pRsnIe->length) {
+		idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WAPI);
+		if (0 <= idx) {
+			status = dot11f_unpack_ie_wapi(pMac, pRsnIe->rsnIEdata + idx + 2,  /* EID, length */
+						       pRsnIe->rsnIEdata[idx + 1],
+						       pDot11f, false);
+			if (DOT11F_FAILED(status)) {
+				pe_err("Parse failure (0x%08x)", status);
+				return QDF_STATUS_E_FAILURE;
+			}
+			pe_debug("status 0x%08x", status);
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+} /* End populate_dot11f_wapi. */
+
+QDF_STATUS populate_dot11f_wapi_opaque(tpAniSirGlobal pMac,
+					  tpSirRSNie pRsnIe,
+					  tDot11fIEWAPIOpaque *pDot11f)
+{
+	int idx;
+
+	if (pRsnIe->length) {
+		idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WAPI);
+		if (0 <= idx) {
+			pDot11f->present = 1;
+			pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1];
+			qdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2,        /* EID, len */
+				     pRsnIe->rsnIEdata[idx + 1]);
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End populate_dot11f_wapi_opaque. */
+
+#endif /* defined(FEATURE_WLAN_WAPI) */
+
+void
+populate_dot11f_ssid(tpAniSirGlobal pMac,
+		     tSirMacSSid *pInternal, tDot11fIESSID *pDot11f)
+{
+	pDot11f->present = 1;
+	pDot11f->num_ssid = pInternal->length;
+	if (pInternal->length) {
+		qdf_mem_copy((uint8_t *) pDot11f->ssid,
+			     (uint8_t *) &pInternal->ssId, pInternal->length);
+	}
+} /* End populate_dot11f_ssid. */
+
+QDF_STATUS populate_dot11f_ssid2(tpAniSirGlobal pMac, tDot11fIESSID *pDot11f)
+{
+	uint32_t nCfg;
+	QDF_STATUS nSirStatus;
+
+	CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SSID, pDot11f->ssid, nCfg, 32);
+	pDot11f->num_ssid = (uint8_t) nCfg;
+	pDot11f->present = 1;
+	return QDF_STATUS_SUCCESS;
+} /* End populate_dot11f_ssid2. */
+
+void
+populate_dot11f_schedule(tSirMacScheduleIE *pSchedule,
+			 tDot11fIESchedule *pDot11f)
+{
+	pDot11f->aggregation = pSchedule->info.aggregation;
+	pDot11f->tsid = pSchedule->info.tsid;
+	pDot11f->direction = pSchedule->info.direction;
+	pDot11f->reserved = pSchedule->info.rsvd;
+	pDot11f->service_start_time = pSchedule->svcStartTime;
+	pDot11f->service_interval = pSchedule->svcInterval;
+	pDot11f->max_service_dur = pSchedule->maxSvcDuration;
+	pDot11f->spec_interval = pSchedule->specInterval;
+
+	pDot11f->present = 1;
+} /* End populate_dot11f_schedule. */
+
+void
+populate_dot11f_supp_channels(tpAniSirGlobal pMac,
+			      tDot11fIESuppChannels *pDot11f,
+			      uint8_t nAssocType, tpPESession psessionEntry)
+{
+	uint8_t i;
+	uint8_t *p;
+
+	if (nAssocType == LIM_REASSOC) {
+		p = (uint8_t *) psessionEntry->pLimReAssocReq->
+		    supportedChannels.channelList;
+		pDot11f->num_bands =
+			psessionEntry->pLimReAssocReq->supportedChannels.numChnl;
+	} else {
+		p = (uint8_t *) psessionEntry->pLimJoinReq->supportedChannels.
+		    channelList;
+		pDot11f->num_bands =
+			psessionEntry->pLimJoinReq->supportedChannels.numChnl;
+	}
+	for (i = 0U; i < pDot11f->num_bands; ++i, ++p) {
+		pDot11f->bands[i][0] = *p;
+		pDot11f->bands[i][1] = 1;
+	}
+
+	pDot11f->present = 1;
+
+} /* End populate_dot11f_supp_channels. */
+
+QDF_STATUS
+populate_dot11f_supp_rates(tpAniSirGlobal pMac,
+			   uint8_t nChannelNum,
+			   tDot11fIESuppRates *pDot11f, tpPESession psessionEntry)
+{
+	QDF_STATUS nsir_status;
+	qdf_size_t nRates;
+	uint8_t rates[SIR_MAC_MAX_NUMBER_OF_RATES];
+
+	/* Use the operational rates present in session entry whenever nChannelNum is set to OPERATIONAL
+	   else use the supported rate set from CFG, which is fixed and does not change dynamically and is used for
+	   sending mgmt frames (lile probe req) which need to go out before any session is present.
+	 */
+	if (POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum) {
+#if 0
+		CFG_GET_STR(nsir_status, pMac, WNI_CFG_OPERATIONAL_RATE_SET,
+			    rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES);
+#endif /* TO SUPPORT BT-AMP */
+		if (psessionEntry != NULL) {
+			nRates = psessionEntry->rateSet.numRates;
+			qdf_mem_copy(rates, psessionEntry->rateSet.rate,
+				     nRates);
+		} else {
+			pe_err("no session context exists while populating Operational Rate Set");
+			nRates = 0;
+		}
+	} else if (14 >= nChannelNum) {
+		nRates = SIR_MAC_MAX_NUMBER_OF_RATES;
+		nsir_status = wlan_mlme_get_cfg_str(
+					rates,
+					&pMac->mlme_cfg->rates.supported_11b,
+					&nRates);
+		if (QDF_IS_STATUS_ERROR(nsir_status)) {
+			pe_err("Failed to retrieve nItem from CFG status: %d",
+			       (nsir_status));
+			return nsir_status;
+		}
+	} else {
+		nRates = SIR_MAC_MAX_NUMBER_OF_RATES;
+		nsir_status = wlan_mlme_get_cfg_str(
+					rates,
+					&pMac->mlme_cfg->rates.supported_11a,
+					&nRates);
+		if (QDF_IS_STATUS_ERROR(nsir_status)) {
+			pe_err("Failed to retrieve nItem from CFG status: %d",
+			       (nsir_status));
+			return nsir_status;
+		}
+	}
+
+	if (0 != nRates) {
+		pDot11f->num_rates = (uint8_t) nRates;
+		qdf_mem_copy(pDot11f->rates, rates, nRates);
+		pDot11f->present = 1;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End populate_dot11f_supp_rates. */
+
+/**
+ * populate_dot11f_rates_tdls() - populate supported rates and
+ *                                extended supported rates IE.
+ * @p_mac gloabl - header.
+ * @p_supp_rates - pointer to supported rates IE
+ * @p_ext_supp_rates - pointer to extended supported rates IE
+ * @curr_oper_channel - current operating channel
+ *
+ * This function populates the supported rates and extended supported
+ * rates IE based in the STA capability. If the number of rates
+ * supported is less than MAX_NUM_SUPPORTED_RATES, only supported rates
+ * IE is populated.
+ *
+ * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
+ *         on failure.
+ */
+
+QDF_STATUS
+populate_dot11f_rates_tdls(tpAniSirGlobal p_mac,
+			   tDot11fIESuppRates *p_supp_rates,
+			   tDot11fIEExtSuppRates *p_ext_supp_rates,
+			   uint8_t curr_oper_channel)
+{
+	tSirMacRateSet temp_rateset;
+	tSirMacRateSet temp_rateset2;
+	uint32_t i;
+	uint32_t self_dot11mode = 0;
+	qdf_size_t num_rates;
+
+	wlan_cfg_get_int(p_mac, WNI_CFG_DOT11_MODE, &self_dot11mode);
+
+	/**
+	 * Include 11b rates only when the device configured in
+	 * auto, 11a/b/g or 11b_only and also if current base
+	 * channel is 5 GHz then no need to advertise the 11b rates.
+	 * If devices move to 2.4GHz off-channel then they can communicate
+	 * in 11g rates i.e. (6, 9, 12, 18, 24, 36 and 54).
+	 */
+	pe_debug("Current operating channel %d self_dot11mode = %d",
+		curr_oper_channel, self_dot11mode);
+
+	if ((curr_oper_channel <= SIR_11B_CHANNEL_END) &&
+	    ((self_dot11mode == WNI_CFG_DOT11_MODE_ALL) ||
+	    (self_dot11mode == WNI_CFG_DOT11_MODE_11A) ||
+	    (self_dot11mode == WNI_CFG_DOT11_MODE_11AC) ||
+	    (self_dot11mode == WNI_CFG_DOT11_MODE_11N) ||
+	    (self_dot11mode == WNI_CFG_DOT11_MODE_11G) ||
+	    (self_dot11mode == WNI_CFG_DOT11_MODE_11B))) {
+		num_rates = p_mac->mlme_cfg->rates.supported_11b.len;
+		wlan_mlme_get_cfg_str((uint8_t *)&temp_rateset.rate,
+				      &p_mac->mlme_cfg->rates.supported_11b,
+				      &num_rates);
+		temp_rateset.numRates = (uint8_t)num_rates;
+	} else {
+	    temp_rateset.numRates = 0;
+	}
+
+	/* Include 11a rates when the device configured in non-11b mode */
+	if (!IS_DOT11_MODE_11B(self_dot11mode)) {
+		num_rates = p_mac->mlme_cfg->rates.supported_11a.len;
+		wlan_mlme_get_cfg_str((uint8_t *)&temp_rateset2.rate,
+				      &p_mac->mlme_cfg->rates.supported_11a,
+				      &num_rates);
+		temp_rateset2.numRates = (uint8_t)num_rates;
+	} else {
+		temp_rateset2.numRates = 0;
+	}
+
+	if ((temp_rateset.numRates + temp_rateset2.numRates) >
+					SIR_MAC_MAX_NUMBER_OF_RATES) {
+		pe_err("more than %d rates in CFG",
+				SIR_MAC_MAX_NUMBER_OF_RATES);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/**
+	 * copy all rates in temp_rateset,
+	 * there are SIR_MAC_MAX_NUMBER_OF_RATES rates max
+	 */
+	for (i = 0; i < temp_rateset2.numRates; i++)
+		temp_rateset.rate[i + temp_rateset.numRates] =
+						temp_rateset2.rate[i];
+
+	temp_rateset.numRates += temp_rateset2.numRates;
+
+	if (temp_rateset.numRates <= MAX_NUM_SUPPORTED_RATES) {
+		p_supp_rates->num_rates = temp_rateset.numRates;
+		qdf_mem_copy(p_supp_rates->rates, temp_rateset.rate,
+			     p_supp_rates->num_rates);
+		p_supp_rates->present = 1;
+	}  else { /* Populate extended capability as well */
+		p_supp_rates->num_rates = MAX_NUM_SUPPORTED_RATES;
+		qdf_mem_copy(p_supp_rates->rates, temp_rateset.rate,
+			     p_supp_rates->num_rates);
+		p_supp_rates->present = 1;
+
+		p_ext_supp_rates->num_rates = temp_rateset.numRates -
+				     MAX_NUM_SUPPORTED_RATES;
+		qdf_mem_copy(p_ext_supp_rates->rates,
+			     (uint8_t *)temp_rateset.rate +
+			     MAX_NUM_SUPPORTED_RATES,
+			     p_ext_supp_rates->num_rates);
+		p_ext_supp_rates->present = 1;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End populate_dot11f_rates_tdls */
+
+
+QDF_STATUS
+populate_dot11f_tpc_report(tpAniSirGlobal pMac,
+			   tDot11fIETPCReport *pDot11f, tpPESession psessionEntry)
+{
+	uint16_t staid;
+	uint8_t tx_power;
+	QDF_STATUS nSirStatus;
+
+	nSirStatus = lim_get_mgmt_staid(pMac, &staid, psessionEntry);
+	if (QDF_STATUS_SUCCESS != nSirStatus) {
+		pe_err("Failed to get the STAID in Populate Dot11fTPCReport; lim_get_mgmt_staid returned status %d",
+			nSirStatus);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* FramesToDo: This function was "misplaced" in the move to Gen4_TVM... */
+	/* txPower = halGetRateToPwrValue( pMac, staid, pMac->lim.gLimCurrentChannelId, isBeacon ); */
+	tx_power = cfg_get_regulatory_max_transmit_power(pMac,
+				psessionEntry->currentOperChannel);
+	pDot11f->tx_power = tx_power;
+	pDot11f->link_margin = 0;
+	pDot11f->present = 1;
+
+	return QDF_STATUS_SUCCESS;
+} /* End populate_dot11f_tpc_report. */
+
+void populate_dot11f_ts_info(tSirMacTSInfo *pInfo, tDot11fFfTSInfo *pDot11f)
+{
+	pDot11f->traffic_type = pInfo->traffic.trafficType;
+	pDot11f->tsid = pInfo->traffic.tsid;
+	pDot11f->direction = pInfo->traffic.direction;
+	pDot11f->access_policy = pInfo->traffic.accessPolicy;
+	pDot11f->aggregation = pInfo->traffic.aggregation;
+	pDot11f->psb = pInfo->traffic.psb;
+	pDot11f->user_priority = pInfo->traffic.userPrio;
+	pDot11f->tsinfo_ack_pol = pInfo->traffic.ackPolicy;
+	pDot11f->schedule = pInfo->schedule.schedule;
+} /* End PopulatedDot11fTSInfo. */
+
+void populate_dot11f_wmm(tpAniSirGlobal pMac,
+			 tDot11fIEWMMInfoAp *pInfo,
+			 tDot11fIEWMMParams *pParams,
+			 tDot11fIEWMMCaps *pCaps, tpPESession psessionEntry)
+{
+	if (psessionEntry->limWmeEnabled) {
+		if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+			/* if ( ! sirIsPropCapabilityEnabled( pMac, SIR_MAC_PROP_CAPABILITY_WME ) ) */
+			{
+				populate_dot11f_wmm_info_ap(pMac, pInfo,
+							    psessionEntry);
+			}
+		} else {
+			{
+				populate_dot11f_wmm_params(pMac, pParams,
+							   psessionEntry);
+			}
+
+			if (psessionEntry->limWsmEnabled) {
+				populate_dot11f_wmm_caps(pCaps);
+			}
+		}
+	}
+} /* End populate_dot11f_wmm. */
+
+void populate_dot11f_wmm_caps(tDot11fIEWMMCaps *pCaps)
+{
+	pCaps->version = SIR_MAC_OUI_VERSION_1;
+	pCaps->qack = 0;
+	pCaps->queue_request = 1;
+	pCaps->txop_request = 0;
+	pCaps->more_ack = 0;
+	pCaps->present = 1;
+} /* End PopulateDot11fWmmCaps. */
+
+#ifdef FEATURE_WLAN_ESE
+void populate_dot11f_re_assoc_tspec(tpAniSirGlobal pMac,
+				    tDot11fReAssocRequest *pReassoc,
+				    tpPESession psessionEntry)
+{
+	uint8_t numTspecs = 0, idx;
+	tTspecInfo *pTspec = NULL;
+
+	numTspecs = psessionEntry->pLimReAssocReq->eseTspecInfo.numTspecs;
+	pTspec = &psessionEntry->pLimReAssocReq->eseTspecInfo.tspec[0];
+	pReassoc->num_WMMTSPEC = numTspecs;
+	if (numTspecs) {
+		for (idx = 0; idx < numTspecs; idx++) {
+			populate_dot11f_wmmtspec(&pTspec->tspec,
+						 &pReassoc->WMMTSPEC[idx]);
+			pTspec->tspec.mediumTime = 0;
+			pTspec++;
+		}
+	}
+}
+
+void ese_populate_wmm_tspec(tSirMacTspecIE *source,
+	ese_wmm_tspec_ie *dest)
+{
+	dest->traffic_type = source->tsinfo.traffic.trafficType;
+	dest->tsid = source->tsinfo.traffic.tsid;
+	dest->direction = source->tsinfo.traffic.direction;
+	dest->access_policy = source->tsinfo.traffic.accessPolicy;
+	dest->aggregation = source->tsinfo.traffic.aggregation;
+	dest->psb = source->tsinfo.traffic.psb;
+	dest->user_priority = source->tsinfo.traffic.userPrio;
+	dest->tsinfo_ack_pol = source->tsinfo.traffic.ackPolicy;
+	dest->burst_size_defn = source->tsinfo.traffic.burstSizeDefn;
+	/* As defined in IEEE 802.11-2007, section 7.3.2.30
+	 * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed
+	 */
+	dest->size = (source->nomMsduSz & SIZE_MASK);
+	dest->fixed = (source->nomMsduSz & FIXED_MASK) ? 1 : 0;
+	dest->max_msdu_size = source->maxMsduSz;
+	dest->min_service_int = source->minSvcInterval;
+	dest->max_service_int = source->maxSvcInterval;
+	dest->inactivity_int = source->inactInterval;
+	dest->suspension_int = source->suspendInterval;
+	dest->service_start_time = source->svcStartTime;
+	dest->min_data_rate = source->minDataRate;
+	dest->mean_data_rate = source->meanDataRate;
+	dest->peak_data_rate = source->peakDataRate;
+	dest->burst_size = source->maxBurstSz;
+	dest->delay_bound = source->delayBound;
+	dest->min_phy_rate = source->minPhyRate;
+	dest->surplus_bw_allowance = source->surplusBw;
+	dest->medium_time = source->mediumTime;
+}
+
+#endif
+
+void populate_dot11f_wmm_info_ap(tpAniSirGlobal pMac, tDot11fIEWMMInfoAp *pInfo,
+				 tpPESession psessionEntry)
+{
+	pInfo->version = SIR_MAC_OUI_VERSION_1;
+
+	/* WMM Specification 3.1.3, 3.2.3
+	 * An IBSS station shall always use its default WMM parameters.
+	 */
+	if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+		pInfo->param_set_count = 0;
+		pInfo->uapsd = 0;
+	} else {
+		pInfo->param_set_count =
+			(0xf & psessionEntry->gLimEdcaParamSetCount);
+		if (LIM_IS_AP_ROLE(psessionEntry)) {
+			pInfo->uapsd = (0x1 & psessionEntry->apUapsdEnable);
+		} else
+			pInfo->uapsd = (0x1 & pMac->lim.gUapsdEnable);
+	}
+	pInfo->present = 1;
+}
+
+void populate_dot11f_wmm_info_station_per_session(tpAniSirGlobal pMac,
+						  tpPESession psessionEntry,
+						  tDot11fIEWMMInfoStation *pInfo)
+{
+	uint8_t max_sp_length = 0;
+
+	max_sp_length = pMac->mlme_cfg->wmm_params.max_sp_length;
+	pInfo->version = SIR_MAC_OUI_VERSION_1;
+	pInfo->acvo_uapsd =
+		LIM_UAPSD_GET(ACVO, psessionEntry->gUapsdPerAcBitmask);
+	pInfo->acvi_uapsd =
+		LIM_UAPSD_GET(ACVI, psessionEntry->gUapsdPerAcBitmask);
+	pInfo->acbk_uapsd =
+		LIM_UAPSD_GET(ACBK, psessionEntry->gUapsdPerAcBitmask);
+	pInfo->acbe_uapsd =
+		LIM_UAPSD_GET(ACBE, psessionEntry->gUapsdPerAcBitmask);
+
+	pInfo->max_sp_length = max_sp_length;
+	pInfo->present = 1;
+}
+
+void populate_dot11f_wmm_params(tpAniSirGlobal pMac,
+				tDot11fIEWMMParams *pParams,
+				tpPESession psessionEntry)
+{
+	pParams->version = SIR_MAC_OUI_VERSION_1;
+
+	if (LIM_IS_AP_ROLE(psessionEntry))
+		pParams->qosInfo =
+			(psessionEntry->
+			 apUapsdEnable << 7) | ((uint8_t) (0x0f & psessionEntry->
+							   gLimEdcaParamSetCount));
+	else
+		pParams->qosInfo =
+			(pMac->lim.
+			 gUapsdEnable << 7) | ((uint8_t) (0x0f & psessionEntry->
+							  gLimEdcaParamSetCount));
+
+	/* Fill each EDCA parameter set in order: be, bk, vi, vo */
+	pParams->acbe_aifsn =
+		(0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[0].aci.aifsn));
+	pParams->acbe_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[0].aci.acm);
+	pParams->acbe_aci = (0x3 & SIR_MAC_EDCAACI_BESTEFFORT);
+	pParams->acbe_acwmin =
+		(0xf & psessionEntry->gLimEdcaParamsBC[0].cw.min);
+	pParams->acbe_acwmax =
+		(0xf & psessionEntry->gLimEdcaParamsBC[0].cw.max);
+	pParams->acbe_txoplimit = psessionEntry->gLimEdcaParamsBC[0].txoplimit;
+
+	pParams->acbk_aifsn =
+		(0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[1].aci.aifsn));
+	pParams->acbk_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[1].aci.acm);
+	pParams->acbk_aci = (0x3 & SIR_MAC_EDCAACI_BACKGROUND);
+	pParams->acbk_acwmin =
+		(0xf & psessionEntry->gLimEdcaParamsBC[1].cw.min);
+	pParams->acbk_acwmax =
+		(0xf & psessionEntry->gLimEdcaParamsBC[1].cw.max);
+	pParams->acbk_txoplimit = psessionEntry->gLimEdcaParamsBC[1].txoplimit;
+
+	if (LIM_IS_AP_ROLE(psessionEntry))
+		pParams->acvi_aifsn =
+			(0xf & psessionEntry->gLimEdcaParamsBC[2].aci.aifsn);
+	else
+		pParams->acvi_aifsn =
+			(0xf &
+			 SET_AIFSN(psessionEntry->gLimEdcaParamsBC[2].aci.aifsn));
+
+	pParams->acvi_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[2].aci.acm);
+	pParams->acvi_aci = (0x3 & SIR_MAC_EDCAACI_VIDEO);
+	pParams->acvi_acwmin =
+		(0xf & psessionEntry->gLimEdcaParamsBC[2].cw.min);
+	pParams->acvi_acwmax =
+		(0xf & psessionEntry->gLimEdcaParamsBC[2].cw.max);
+	pParams->acvi_txoplimit = psessionEntry->gLimEdcaParamsBC[2].txoplimit;
+
+	if (LIM_IS_AP_ROLE(psessionEntry))
+		pParams->acvo_aifsn =
+			(0xf & psessionEntry->gLimEdcaParamsBC[3].aci.aifsn);
+	else
+		pParams->acvo_aifsn =
+			(0xf &
+			 SET_AIFSN(psessionEntry->gLimEdcaParamsBC[3].aci.aifsn));
+
+	pParams->acvo_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[3].aci.acm);
+	pParams->acvo_aci = (0x3 & SIR_MAC_EDCAACI_VOICE);
+	pParams->acvo_acwmin =
+		(0xf & psessionEntry->gLimEdcaParamsBC[3].cw.min);
+	pParams->acvo_acwmax =
+		(0xf & psessionEntry->gLimEdcaParamsBC[3].cw.max);
+	pParams->acvo_txoplimit = psessionEntry->gLimEdcaParamsBC[3].txoplimit;
+
+	pParams->present = 1;
+
+} /* End populate_dot11f_wmm_params. */
+
+void populate_dot11f_wmm_schedule(tSirMacScheduleIE *pSchedule,
+				  tDot11fIEWMMSchedule *pDot11f)
+{
+	pDot11f->version = 1;
+	pDot11f->aggregation = pSchedule->info.aggregation;
+	pDot11f->tsid = pSchedule->info.tsid;
+	pDot11f->direction = pSchedule->info.direction;
+	pDot11f->reserved = pSchedule->info.rsvd;
+	pDot11f->service_start_time = pSchedule->svcStartTime;
+	pDot11f->service_interval = pSchedule->svcInterval;
+	pDot11f->max_service_dur = pSchedule->maxSvcDuration;
+	pDot11f->spec_interval = pSchedule->specInterval;
+
+	pDot11f->present = 1;
+} /* End populate_dot11f_wmm_schedule. */
+
+QDF_STATUS
+populate_dot11f_wpa(tpAniSirGlobal pMac,
+		    tpSirRSNie pRsnIe, tDot11fIEWPA *pDot11f)
+{
+	uint32_t status;
+	int idx;
+
+	if (pRsnIe->length) {
+		idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WPA);
+		if (0 <= idx) {
+			status = dot11f_unpack_ie_wpa(pMac, pRsnIe->rsnIEdata + idx + 2 + 4,       /* EID, length, OUI */
+						      pRsnIe->rsnIEdata[idx + 1] - 4,   /* OUI */
+						      pDot11f, false);
+			if (DOT11F_FAILED(status)) {
+				pe_err("Parse failure in Populate Dot11fWPA (0x%08x)",
+					status);
+				return QDF_STATUS_E_FAILURE;
+			}
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+} /* End populate_dot11f_wpa. */
+
+QDF_STATUS populate_dot11f_wpa_opaque(tpAniSirGlobal pMac,
+					 tpSirRSNie pRsnIe,
+					 tDot11fIEWPAOpaque *pDot11f)
+{
+	int idx;
+
+	if (pRsnIe->length) {
+		idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WPA);
+		if (0 <= idx) {
+			pDot11f->present = 1;
+			pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1] - 4;
+			qdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2 + 4,    /* EID, len, OUI */
+				     pRsnIe->rsnIEdata[idx + 1] - 4);   /* OUI */
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End populate_dot11f_wpa_opaque. */
+
+/* ////////////////////////////////////////////////////////////////////// */
+
+QDF_STATUS
+sir_convert_probe_req_frame2_struct(tpAniSirGlobal pMac,
+				    uint8_t *pFrame,
+				    uint32_t nFrame, tpSirProbeReq pProbeReq)
+{
+	uint32_t status;
+	tDot11fProbeRequest pr;
+
+	/* Ok, zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) pProbeReq, sizeof(tSirProbeReq), 0);
+
+	/* delegate to the framesc-generated code, */
+	status = dot11f_unpack_probe_request(pMac, pFrame, nFrame, &pr, false);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse a Probe Request (0x%08x, %d bytes):",
+			status, nFrame);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pFrame, nFrame);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking a Probe Request (0x%08x, %d bytes):",
+			status, nFrame);
+	}
+	/* & "transliterate" from a 'tDot11fProbeRequestto' a 'tSirProbeReq'... */
+	if (!pr.SSID.present) {
+		pe_debug("Mandatory IE SSID not present!");
+	} else {
+		pProbeReq->ssidPresent = 1;
+		convert_ssid(pMac, &pProbeReq->ssId, &pr.SSID);
+	}
+
+	if (!pr.SuppRates.present) {
+		pe_debug_rl("Mandatory IE Supported Rates not present!");
+		return QDF_STATUS_E_FAILURE;
+	} else {
+		pProbeReq->suppRatesPresent = 1;
+		convert_supp_rates(pMac, &pProbeReq->supportedRates,
+				   &pr.SuppRates);
+	}
+
+	if (pr.ExtSuppRates.present) {
+		pProbeReq->extendedRatesPresent = 1;
+		convert_ext_supp_rates(pMac, &pProbeReq->extendedRates,
+				       &pr.ExtSuppRates);
+	}
+
+	if (pr.HTCaps.present) {
+		qdf_mem_copy(&pProbeReq->HTCaps, &pr.HTCaps,
+			     sizeof(tDot11fIEHTCaps));
+	}
+
+	if (pr.WscProbeReq.present) {
+		pProbeReq->wscIePresent = 1;
+		memcpy(&pProbeReq->probeReqWscIeInfo, &pr.WscProbeReq,
+		       sizeof(tDot11fIEWscProbeReq));
+	}
+	if (pr.VHTCaps.present) {
+		qdf_mem_copy(&pProbeReq->VHTCaps, &pr.VHTCaps,
+			     sizeof(tDot11fIEVHTCaps));
+	}
+	if (pr.P2PProbeReq.present) {
+		pProbeReq->p2pIePresent = 1;
+	}
+	if (pr.he_cap.present) {
+		qdf_mem_copy(&pProbeReq->he_cap, &pr.he_cap,
+			     sizeof(tDot11fIEhe_cap));
+		pe_debug("11AX: HE cap IE present");
+	}
+	return QDF_STATUS_SUCCESS;
+} /* End sir_convert_probe_req_frame2_struct. */
+
+
+/**
+ * sir_validate_and_rectify_ies() - API to check malformed frame
+ * @mac_ctx: mac context
+ * @mgmt_frame: pointer to management frame
+ * @frame_bytes: no of bytes in frame
+ * @missing_rsn_bytes: missing rsn bytes
+ *
+ * The frame would contain fixed IEs of 12 bytes followed by variable IEs
+ * (Tagged elements). Every Tagged IE has tag number, tag length and data.
+ * Tag length indicates the size of data in bytes.
+ * This function checks for size of Frame received with the sum of all IEs.
+ * And also rectifies missing optional fields in IE.
+ *
+ * NOTE : Presently this function rectifies RSN capability in RSN IE, can
+ * be extended to rectify other optional fields in other IEs.
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+QDF_STATUS
+sir_validate_and_rectify_ies(tpAniSirGlobal mac_ctx,
+				uint8_t *mgmt_frame,
+				uint32_t frame_bytes,
+				uint32_t *missing_rsn_bytes)
+{
+	uint32_t length = SIZE_OF_FIXED_PARAM;
+	uint8_t *ref_frame = NULL;
+
+	/* Frame contains atleast one IE */
+	if (frame_bytes > (SIZE_OF_FIXED_PARAM +
+			SIZE_OF_TAG_PARAM_NUM + SIZE_OF_TAG_PARAM_LEN)) {
+		while (length < frame_bytes) {
+			/* ref frame points to next IE */
+			ref_frame = mgmt_frame + length;
+			length += (uint32_t)(SIZE_OF_TAG_PARAM_NUM +
+					SIZE_OF_TAG_PARAM_LEN +
+					(*(ref_frame + SIZE_OF_TAG_PARAM_NUM)));
+		}
+		if (length != frame_bytes) {
+			/*
+			 * Workaround : Some APs may not include RSN
+			 * Capability but the length of which is included in
+			 * RSN IE length. This may cause in updating RSN
+			 * Capability with junk value. To avoid this, add RSN
+			 * Capability value with default value.
+			 */
+			if (ref_frame && (*ref_frame == RSNIEID) &&
+				(length == (frame_bytes +
+					RSNIE_CAPABILITY_LEN))) {
+				/* Assume RSN Capability as 00 */
+				qdf_mem_set((uint8_t *)(mgmt_frame +
+					(frame_bytes)),
+					RSNIE_CAPABILITY_LEN,
+					DEFAULT_RSNIE_CAP_VAL);
+				*missing_rsn_bytes = RSNIE_CAPABILITY_LEN;
+				pe_debug("Added RSN Capability to RSNIE as 0x00 0x00");
+				return QDF_STATUS_SUCCESS;
+			}
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+void sir_copy_caps_info(tpAniSirGlobal mac_ctx, tDot11fFfCapabilities caps,
+					    tpSirProbeRespBeacon pProbeResp)
+{
+	pProbeResp->capabilityInfo.ess = caps.ess;
+	pProbeResp->capabilityInfo.ibss = caps.ibss;
+	pProbeResp->capabilityInfo.cfPollable = caps.cfPollable;
+	pProbeResp->capabilityInfo.cfPollReq = caps.cfPollReq;
+	pProbeResp->capabilityInfo.privacy = caps.privacy;
+	pProbeResp->capabilityInfo.shortPreamble = caps.shortPreamble;
+	pProbeResp->capabilityInfo.pbcc = caps.pbcc;
+	pProbeResp->capabilityInfo.channelAgility =	caps.channelAgility;
+	pProbeResp->capabilityInfo.spectrumMgt = caps.spectrumMgt;
+	pProbeResp->capabilityInfo.qos = caps.qos;
+	pProbeResp->capabilityInfo.shortSlotTime = caps.shortSlotTime;
+	pProbeResp->capabilityInfo.apsd = caps.apsd;
+	pProbeResp->capabilityInfo.rrm = caps.rrm;
+	pProbeResp->capabilityInfo.dsssOfdm = caps.dsssOfdm;
+	pProbeResp->capabilityInfo.delayedBA = caps.delayedBA;
+	pProbeResp->capabilityInfo.immediateBA = caps.immediateBA;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+static void populate_dot11f_fils_rsn(tpAniSirGlobal mac_ctx,
+				     tDot11fIERSNOpaque *p_dot11f,
+				     uint8_t *rsn_ie)
+{
+	pe_debug("FILS RSN IE length %d", rsn_ie[1]);
+	if (rsn_ie[1]) {
+		p_dot11f->present = 1;
+		p_dot11f->num_data = rsn_ie[1];
+		qdf_mem_copy(p_dot11f->data, &rsn_ie[2], rsn_ie[1]);
+	}
+}
+
+void populate_dot11f_fils_params(tpAniSirGlobal mac_ctx,
+		tDot11fAssocRequest *frm,
+		tpPESession pe_session)
+{
+	struct pe_fils_session *fils_info = pe_session->fils_info;
+
+	/* Populate RSN IE with FILS AKM */
+	populate_dot11f_fils_rsn(mac_ctx, &frm->RSNOpaque,
+				 fils_info->rsn_ie);
+
+	/* Populate FILS session IE */
+	frm->fils_session.present = true;
+	qdf_mem_copy(frm->fils_session.session,
+		     fils_info->fils_session, FILS_SESSION_LENGTH);
+
+	/* Populate FILS Key confirmation IE */
+	if (fils_info->key_auth_len) {
+		frm->fils_key_confirmation.present = true;
+		frm->fils_key_confirmation.num_key_auth =
+						fils_info->key_auth_len;
+
+		qdf_mem_copy(frm->fils_key_confirmation.key_auth,
+			     fils_info->key_auth, fils_info->key_auth_len);
+	}
+}
+
+/**
+ * update_fils_data: update fils params from beacon/probe response
+ * @fils_ind: pointer to sir_fils_indication
+ * @fils_indication: pointer to tDot11fIEfils_indication
+ *
+ * Return: None
+ */
+void update_fils_data(struct sir_fils_indication *fils_ind,
+		      tDot11fIEfils_indication *fils_indication)
+{
+	uint8_t *data;
+	uint8_t remaining_data = fils_indication->num_variable_data;
+
+	data = fils_indication->variable_data;
+	fils_ind->is_present = true;
+	fils_ind->is_ip_config_supported =
+			fils_indication->is_ip_config_supported;
+	fils_ind->is_fils_sk_auth_supported =
+			fils_indication->is_fils_sk_auth_supported;
+	fils_ind->is_fils_sk_auth_pfs_supported =
+			fils_indication->is_fils_sk_auth_pfs_supported;
+	fils_ind->is_pk_auth_supported =
+			fils_indication->is_pk_auth_supported;
+	if (fils_indication->is_cache_id_present) {
+		if (remaining_data < SIR_CACHE_IDENTIFIER_LEN) {
+			pe_err("Failed to copy Cache Identifier, Invalid remaining data %d",
+				remaining_data);
+			return;
+		}
+		fils_ind->cache_identifier.is_present = true;
+		qdf_mem_copy(fils_ind->cache_identifier.identifier,
+				data, SIR_CACHE_IDENTIFIER_LEN);
+		data = data + SIR_CACHE_IDENTIFIER_LEN;
+		remaining_data = remaining_data - SIR_CACHE_IDENTIFIER_LEN;
+	}
+	if (fils_indication->is_hessid_present) {
+		if (remaining_data < SIR_HESSID_LEN) {
+			pe_err("Failed to copy HESSID, Invalid remaining data %d",
+				remaining_data);
+			return;
+		}
+		fils_ind->hessid.is_present = true;
+		qdf_mem_copy(fils_ind->hessid.hessid,
+				data, SIR_HESSID_LEN);
+		data = data + SIR_HESSID_LEN;
+		remaining_data = remaining_data - SIR_HESSID_LEN;
+	}
+	if (fils_indication->realm_identifiers_cnt) {
+		if (remaining_data < (fils_indication->realm_identifiers_cnt *
+		    SIR_REALM_LEN)) {
+			pe_err("Failed to copy Realm Identifier, Invalid remaining data %d realm_cnt %d",
+				remaining_data,
+				fils_indication->realm_identifiers_cnt);
+			return;
+		}
+		fils_ind->realm_identifier.is_present = true;
+		fils_ind->realm_identifier.realm_cnt =
+			fils_indication->realm_identifiers_cnt;
+		qdf_mem_copy(fils_ind->realm_identifier.realm,
+			data, fils_ind->realm_identifier.realm_cnt *
+					SIR_REALM_LEN);
+	}
+}
+#endif
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+static void update_bss_color_change_ie_from_probe_rsp(
+		tDot11fProbeResponse *prb_frm,
+		tpSirProbeRespBeacon prb_rsp_struct)
+{
+	if (prb_frm->bss_color_change.present) {
+		pe_debug("11AX: HE BSS color change present");
+		qdf_mem_copy(&prb_rsp_struct->vendor_he_bss_color_change,
+			     &prb_frm->bss_color_change,
+			     sizeof(tDot11fIEbss_color_change));
+	}
+}
+#else
+static inline void update_bss_color_change_ie_from_probe_rsp(
+		tDot11fProbeResponse *prb_frm,
+		tpSirProbeRespBeacon prb_rsp_struct)
+{}
+#endif
+QDF_STATUS sir_convert_probe_frame2_struct(tpAniSirGlobal pMac,
+					      uint8_t *pFrame,
+					      uint32_t nFrame,
+					      tpSirProbeRespBeacon pProbeResp)
+{
+	uint32_t status;
+	tDot11fProbeResponse *pr;
+
+	/* Ok, zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) pProbeResp, sizeof(tSirProbeRespBeacon), 0);
+
+	pr = qdf_mem_malloc(sizeof(tDot11fProbeResponse));
+	if (!pr)
+		return QDF_STATUS_E_NOMEM;
+
+	/* delegate to the framesc-generated code, */
+	status = dot11f_unpack_probe_response(pMac, pFrame, nFrame, pr, false);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse a Probe Response (0x%08x, %d bytes):",
+			status, nFrame);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				   pFrame, nFrame);
+		qdf_mem_free(pr);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* & "transliterate" from a 'tDot11fProbeResponse' to a 'tSirProbeRespBeacon'... */
+
+	/* Timestamp */
+	qdf_mem_copy((uint8_t *) pProbeResp->timeStamp,
+		     (uint8_t *) &pr->TimeStamp, sizeof(tSirMacTimeStamp));
+
+	/* Beacon Interval */
+	pProbeResp->beaconInterval = pr->BeaconInterval.interval;
+
+	sir_copy_caps_info(pMac, pr->Capabilities, pProbeResp);
+
+	if (!pr->SSID.present) {
+		pe_debug("Mandatory IE SSID not present!");
+	} else {
+		pProbeResp->ssidPresent = 1;
+		convert_ssid(pMac, &pProbeResp->ssId, &pr->SSID);
+	}
+
+	if (!pr->SuppRates.present) {
+		pe_debug_rl("Mandatory IE Supported Rates not present!");
+	} else {
+		pProbeResp->suppRatesPresent = 1;
+		convert_supp_rates(pMac, &pProbeResp->supportedRates,
+				   &pr->SuppRates);
+	}
+
+	if (pr->ExtSuppRates.present) {
+		pProbeResp->extendedRatesPresent = 1;
+		convert_ext_supp_rates(pMac, &pProbeResp->extendedRates,
+				       &pr->ExtSuppRates);
+	}
+
+	if (pr->CFParams.present) {
+		pProbeResp->cfPresent = 1;
+		convert_cf_params(pMac, &pProbeResp->cfParamSet, &pr->CFParams);
+	}
+
+	if (pr->Country.present) {
+		pProbeResp->countryInfoPresent = 1;
+		convert_country(pMac, &pProbeResp->countryInfoParam,
+				&pr->Country);
+	}
+
+	if (pr->EDCAParamSet.present) {
+		pProbeResp->edcaPresent = 1;
+		convert_edca_param(pMac, &pProbeResp->edcaParams,
+				   &pr->EDCAParamSet);
+	}
+
+	if (pr->ChanSwitchAnn.present) {
+		pProbeResp->channelSwitchPresent = 1;
+		qdf_mem_copy(&pProbeResp->channelSwitchIE, &pr->ChanSwitchAnn,
+			     sizeof(pProbeResp->channelSwitchIE));
+	}
+
+	if (pr->ext_chan_switch_ann.present) {
+		pProbeResp->ext_chan_switch_present = 1;
+		qdf_mem_copy(&pProbeResp->ext_chan_switch,
+			     &pr->ext_chan_switch_ann,
+			     sizeof(tDot11fIEext_chan_switch_ann));
+	}
+
+	if (pr->SuppOperatingClasses.present) {
+		pProbeResp->supp_operating_class_present = 1;
+		qdf_mem_copy(&pProbeResp->supp_operating_classes,
+			&pr->SuppOperatingClasses,
+			sizeof(tDot11fIESuppOperatingClasses));
+	}
+
+	if (pr->sec_chan_offset_ele.present) {
+		pProbeResp->sec_chan_offset_present = 1;
+		qdf_mem_copy(&pProbeResp->sec_chan_offset,
+			     &pr->sec_chan_offset_ele,
+			     sizeof(pProbeResp->sec_chan_offset));
+	}
+
+	if (pr->TPCReport.present) {
+		pProbeResp->tpcReportPresent = 1;
+		qdf_mem_copy(&pProbeResp->tpcReport, &pr->TPCReport,
+			     sizeof(tDot11fIETPCReport));
+	}
+
+	if (pr->PowerConstraints.present) {
+		pProbeResp->powerConstraintPresent = 1;
+		qdf_mem_copy(&pProbeResp->localPowerConstraint,
+			     &pr->PowerConstraints,
+			     sizeof(tDot11fIEPowerConstraints));
+	}
+
+	if (pr->Quiet.present) {
+		pProbeResp->quietIEPresent = 1;
+		qdf_mem_copy(&pProbeResp->quietIE, &pr->Quiet,
+			     sizeof(tDot11fIEQuiet));
+	}
+
+	if (pr->HTCaps.present) {
+		qdf_mem_copy(&pProbeResp->HTCaps, &pr->HTCaps,
+			     sizeof(tDot11fIEHTCaps));
+	}
+
+	if (pr->HTInfo.present) {
+		qdf_mem_copy(&pProbeResp->HTInfo, &pr->HTInfo,
+			     sizeof(tDot11fIEHTInfo));
+	}
+
+	if (pr->DSParams.present) {
+		pProbeResp->dsParamsPresent = 1;
+		pProbeResp->channelNumber = pr->DSParams.curr_channel;
+	} else if (pr->HTInfo.present) {
+		pProbeResp->channelNumber = pr->HTInfo.primaryChannel;
+	}
+
+	if (pr->RSNOpaque.present) {
+		pProbeResp->rsnPresent = 1;
+		convert_rsn_opaque(pMac, &pProbeResp->rsn, &pr->RSNOpaque);
+	}
+
+	if (pr->WPA.present) {
+		pProbeResp->wpaPresent = 1;
+		convert_wpa(pMac, &pProbeResp->wpa, &pr->WPA);
+	}
+
+	if (pr->WMMParams.present) {
+		pProbeResp->wmeEdcaPresent = 1;
+		convert_wmm_params(pMac, &pProbeResp->edcaParams, &pr->WMMParams);
+	}
+
+	if (pr->WMMInfoAp.present) {
+		pProbeResp->wmeInfoPresent = 1;
+		pe_debug("WMM Information Element present in Probe Response Frame!");
+	}
+
+	if (pr->WMMCaps.present) {
+		pProbeResp->wsmCapablePresent = 1;
+	}
+
+	if (pr->ERPInfo.present) {
+		pProbeResp->erpPresent = 1;
+		convert_erp_info(pMac, &pProbeResp->erpIEInfo, &pr->ERPInfo);
+	}
+	if (pr->MobilityDomain.present) {
+		/* MobilityDomain */
+		pProbeResp->mdiePresent = 1;
+		qdf_mem_copy((uint8_t *) &(pProbeResp->mdie[0]),
+			     (uint8_t *) &(pr->MobilityDomain.MDID),
+			     sizeof(uint16_t));
+		pProbeResp->mdie[2] =
+			((pr->MobilityDomain.overDSCap << 0) | (pr->MobilityDomain.
+								resourceReqCap <<
+								1));
+		pe_debug("mdie=%02x%02x%02x",
+			(unsigned int)pProbeResp->mdie[0],
+			(unsigned int)pProbeResp->mdie[1],
+			(unsigned int)pProbeResp->mdie[2]);
+	}
+
+#if defined FEATURE_WLAN_ESE
+	if (pr->ESEVersion.present)
+		pProbeResp->is_ese_ver_ie_present = 1;
+	if (pr->QBSSLoad.present) {
+		qdf_mem_copy(&pProbeResp->QBSSLoad, &pr->QBSSLoad,
+			     sizeof(tDot11fIEQBSSLoad));
+	}
+#endif
+	if (pr->P2PProbeRes.present) {
+		qdf_mem_copy(&pProbeResp->P2PProbeRes, &pr->P2PProbeRes,
+			     sizeof(tDot11fIEP2PProbeRes));
+	}
+	if (pr->VHTCaps.present) {
+		qdf_mem_copy(&pProbeResp->VHTCaps, &pr->VHTCaps,
+			     sizeof(tDot11fIEVHTCaps));
+	}
+	if (pr->VHTOperation.present) {
+		qdf_mem_copy(&pProbeResp->VHTOperation, &pr->VHTOperation,
+			     sizeof(tDot11fIEVHTOperation));
+	}
+	if (pr->VHTExtBssLoad.present) {
+		qdf_mem_copy(&pProbeResp->VHTExtBssLoad, &pr->VHTExtBssLoad,
+			     sizeof(tDot11fIEVHTExtBssLoad));
+	}
+	pProbeResp->Vendor1IEPresent = pr->Vendor1IE.present;
+	pProbeResp->Vendor3IEPresent = pr->Vendor3IE.present;
+
+	pProbeResp->vendor_vht_ie.present = pr->vendor_vht_ie.present;
+	if (pr->vendor_vht_ie.present)
+		pProbeResp->vendor_vht_ie.sub_type = pr->vendor_vht_ie.sub_type;
+	if (pr->vendor_vht_ie.VHTCaps.present) {
+		qdf_mem_copy(&pProbeResp->vendor_vht_ie.VHTCaps,
+				&pr->vendor_vht_ie.VHTCaps,
+				sizeof(tDot11fIEVHTCaps));
+	}
+	if (pr->vendor_vht_ie.VHTOperation.present) {
+		qdf_mem_copy(&pProbeResp->vendor_vht_ie.VHTOperation,
+				&pr->vendor_vht_ie.VHTOperation,
+				sizeof(tDot11fIEVHTOperation));
+	}
+	/* Update HS 2.0 Information Element */
+	if (pr->hs20vendor_ie.present) {
+		pe_debug("HS20 Indication Element Present, rel#:%u, id:%u",
+			pr->hs20vendor_ie.release_num,
+			pr->hs20vendor_ie.hs_id_present);
+		qdf_mem_copy(&pProbeResp->hs20vendor_ie,
+			&pr->hs20vendor_ie,
+			sizeof(tDot11fIEhs20vendor_ie) -
+			sizeof(pr->hs20vendor_ie.hs_id));
+		if (pr->hs20vendor_ie.hs_id_present)
+			qdf_mem_copy(&pProbeResp->hs20vendor_ie.hs_id,
+				&pr->hs20vendor_ie.hs_id,
+				sizeof(pr->hs20vendor_ie.hs_id));
+	}
+	if (pr->MBO_IE.present) {
+		pProbeResp->MBO_IE_present = true;
+		if (pr->MBO_IE.cellular_data_cap.present)
+			pProbeResp->MBO_capability =
+				pr->MBO_IE.cellular_data_cap.cellular_connectivity;
+
+		if (pr->MBO_IE.assoc_disallowed.present) {
+			pProbeResp->assoc_disallowed = true;
+			pProbeResp->assoc_disallowed_reason =
+				pr->MBO_IE.assoc_disallowed.reason_code;
+		}
+	}
+
+	if (pr->QCN_IE.present) {
+		pProbeResp->QCN_IE.is_present = true;
+
+		if (pr->QCN_IE.version[0] == QCN_IE_VERSION_SUBATTR_ID) {
+			pProbeResp->QCN_IE.version
+					= pr->QCN_IE.version[2];
+			pProbeResp->QCN_IE.sub_version
+					= pr->QCN_IE.version[3];
+		}
+	}
+
+	if (pr->he_cap.present) {
+		pe_debug("11AX: HE cap IE present");
+		qdf_mem_copy(&pProbeResp->he_cap, &pr->he_cap,
+			     sizeof(tDot11fIEhe_cap));
+	}
+	if (pr->he_op.present) {
+		pe_debug("11AX: HE operation IE present");
+		qdf_mem_copy(&pProbeResp->he_op, &pr->he_op,
+			     sizeof(tDot11fIEhe_op));
+	}
+
+	update_bss_color_change_ie_from_probe_rsp(pr, pProbeResp);
+
+	qdf_mem_free(pr);
+	return QDF_STATUS_SUCCESS;
+
+} /* End sir_convert_probe_frame2_struct. */
+
+QDF_STATUS
+sir_convert_assoc_req_frame2_struct(tpAniSirGlobal pMac,
+				    uint8_t *pFrame,
+				    uint32_t nFrame, tpSirAssocReq pAssocReq)
+{
+	tDot11fAssocRequest *ar;
+	uint32_t status;
+
+	ar = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
+	if (!ar)
+		return QDF_STATUS_E_NOMEM;
+	/* Zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) pAssocReq, sizeof(tSirAssocReq), 0);
+
+	/* delegate to the framesc-generated code, */
+	status = dot11f_unpack_assoc_request(pMac, pFrame, nFrame, ar, false);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse an Association Request (0x%08x, %d bytes):",
+			status, nFrame);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pFrame, nFrame);
+		qdf_mem_free(ar);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking an Assoication Request (0x%08x, %d bytes):",
+			status, nFrame);
+	}
+	/* & "transliterate" from a 'tDot11fAssocRequest' to a 'tSirAssocReq'... */
+
+	/* make sure this is seen as an assoc request */
+	pAssocReq->reassocRequest = 0;
+
+	/* Capabilities */
+	pAssocReq->capabilityInfo.ess = ar->Capabilities.ess;
+	pAssocReq->capabilityInfo.ibss = ar->Capabilities.ibss;
+	pAssocReq->capabilityInfo.cfPollable = ar->Capabilities.cfPollable;
+	pAssocReq->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq;
+	pAssocReq->capabilityInfo.privacy = ar->Capabilities.privacy;
+	pAssocReq->capabilityInfo.shortPreamble =
+		ar->Capabilities.shortPreamble;
+	pAssocReq->capabilityInfo.pbcc = ar->Capabilities.pbcc;
+	pAssocReq->capabilityInfo.channelAgility =
+		ar->Capabilities.channelAgility;
+	pAssocReq->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt;
+	pAssocReq->capabilityInfo.qos = ar->Capabilities.qos;
+	pAssocReq->capabilityInfo.shortSlotTime =
+		ar->Capabilities.shortSlotTime;
+	pAssocReq->capabilityInfo.apsd = ar->Capabilities.apsd;
+	pAssocReq->capabilityInfo.rrm = ar->Capabilities.rrm;
+	pAssocReq->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm;
+	pAssocReq->capabilityInfo.delayedBA = ar->Capabilities.delayedBA;
+	pAssocReq->capabilityInfo.immediateBA = ar->Capabilities.immediateBA;
+
+	/* Listen Interval */
+	pAssocReq->listenInterval = ar->ListenInterval.interval;
+
+	/* SSID */
+	if (ar->SSID.present) {
+		pAssocReq->ssidPresent = 1;
+		convert_ssid(pMac, &pAssocReq->ssId, &ar->SSID);
+	}
+	/* Supported Rates */
+	if (ar->SuppRates.present) {
+		pAssocReq->suppRatesPresent = 1;
+		convert_supp_rates(pMac, &pAssocReq->supportedRates,
+				   &ar->SuppRates);
+	}
+	/* Extended Supported Rates */
+	if (ar->ExtSuppRates.present) {
+		pAssocReq->extendedRatesPresent = 1;
+		convert_ext_supp_rates(pMac, &pAssocReq->extendedRates,
+				       &ar->ExtSuppRates);
+	}
+	/* QOS Capabilities: */
+	if (ar->QOSCapsStation.present) {
+		pAssocReq->qosCapabilityPresent = 1;
+		convert_qos_caps_station(pMac, &pAssocReq->qosCapability,
+					 &ar->QOSCapsStation);
+	}
+	/* WPA */
+	if (ar->WPAOpaque.present) {
+		pAssocReq->wpaPresent = 1;
+		convert_wpa_opaque(pMac, &pAssocReq->wpa, &ar->WPAOpaque);
+	}
+#ifdef FEATURE_WLAN_WAPI
+	if (ar->WAPIOpaque.present) {
+		pAssocReq->wapiPresent = 1;
+		convert_wapi_opaque(pMac, &pAssocReq->wapi, &ar->WAPIOpaque);
+	}
+#endif
+	/* RSN */
+	if (ar->RSNOpaque.present) {
+		pAssocReq->rsnPresent = 1;
+		convert_rsn_opaque(pMac, &pAssocReq->rsn, &ar->RSNOpaque);
+	}
+	/* WSC IE */
+	if (ar->WscIEOpaque.present) {
+		pAssocReq->addIEPresent = 1;
+		convert_wsc_opaque(pMac, &pAssocReq->addIE, &ar->WscIEOpaque);
+	}
+
+	if (ar->P2PIEOpaque.present) {
+		pAssocReq->addIEPresent = 1;
+		convert_p2p_opaque(pMac, &pAssocReq->addIE, &ar->P2PIEOpaque);
+	}
+#ifdef WLAN_FEATURE_WFD
+	if (ar->WFDIEOpaque.present) {
+		pAssocReq->addIEPresent = 1;
+		convert_wfd_opaque(pMac, &pAssocReq->addIE, &ar->WFDIEOpaque);
+	}
+#endif
+
+	/* Power Capabilities */
+	if (ar->PowerCaps.present) {
+		pAssocReq->powerCapabilityPresent = 1;
+		convert_power_caps(pMac, &pAssocReq->powerCapability,
+				   &ar->PowerCaps);
+	}
+	/* Supported Channels */
+	if (ar->SuppChannels.present) {
+		pAssocReq->supportedChannelsPresent = 1;
+		convert_supp_channels(pMac, &pAssocReq->supportedChannels,
+				      &ar->SuppChannels);
+	}
+
+	if (ar->HTCaps.present) {
+		qdf_mem_copy(&pAssocReq->HTCaps, &ar->HTCaps,
+			     sizeof(tDot11fIEHTCaps));
+	}
+
+	if (ar->WMMInfoStation.present) {
+		pAssocReq->wmeInfoPresent = 1;
+		qdf_mem_copy(&pAssocReq->WMMInfoStation, &ar->WMMInfoStation,
+			     sizeof(tDot11fIEWMMInfoStation));
+
+	}
+
+	if (ar->WMMCaps.present)
+		pAssocReq->wsmCapablePresent = 1;
+
+	if (!pAssocReq->ssidPresent) {
+		pe_debug("Received Assoc without SSID IE");
+		qdf_mem_free(ar);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!pAssocReq->suppRatesPresent && !pAssocReq->extendedRatesPresent) {
+		pe_debug("Received Assoc without supp rate IE");
+		qdf_mem_free(ar);
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (ar->VHTCaps.present) {
+		qdf_mem_copy(&pAssocReq->VHTCaps, &ar->VHTCaps,
+			     sizeof(tDot11fIEVHTCaps));
+		pe_debug("Received Assoc Req with VHT Cap");
+		lim_log_vht_cap(pMac, &pAssocReq->VHTCaps);
+	}
+	if (ar->OperatingMode.present) {
+		qdf_mem_copy(&pAssocReq->operMode, &ar->OperatingMode,
+			     sizeof(tDot11fIEOperatingMode));
+		pe_debug("Received Assoc Req with Operating Mode IE");
+		lim_log_operating_mode(pMac, &pAssocReq->operMode);
+	}
+	if (ar->ExtCap.present) {
+		struct s_ext_cap *ext_cap;
+
+		qdf_mem_copy(&pAssocReq->ExtCap, &ar->ExtCap,
+			    sizeof(tDot11fIEExtCap));
+		ext_cap = (struct s_ext_cap *)&pAssocReq->ExtCap.bytes;
+		pe_debug("timingMeas: %d, finetimingMeas Init: %d, Resp: %d",
+			ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
+			ext_cap->fine_time_meas_responder);
+	}
+
+	pAssocReq->vendor_vht_ie.present = ar->vendor_vht_ie.present;
+	if (ar->vendor_vht_ie.present) {
+		pAssocReq->vendor_vht_ie.sub_type = ar->vendor_vht_ie.sub_type;
+		if (ar->vendor_vht_ie.VHTCaps.present) {
+			qdf_mem_copy(&pAssocReq->vendor_vht_ie.VHTCaps,
+				     &ar->vendor_vht_ie.VHTCaps,
+				     sizeof(tDot11fIEVHTCaps));
+			pe_debug("Received Assoc Request with Vendor specific VHT Cap");
+			lim_log_vht_cap(pMac, &pAssocReq->VHTCaps);
+		}
+	}
+	if (ar->he_cap.present) {
+		qdf_mem_copy(&pAssocReq->he_cap, &ar->he_cap,
+			     sizeof(tDot11fIEhe_cap));
+		pe_debug("Received Assoc Req with HE Capability IE");
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				   &pAssocReq->he_cap, sizeof(tDot11fIEhe_cap));
+	}
+	qdf_mem_free(ar);
+	return QDF_STATUS_SUCCESS;
+
+} /* End sir_convert_assoc_req_frame2_struct. */
+
+/**
+ * dot11f_parse_assoc_response() - API to parse Assoc IE buffer to struct
+ * @mac_ctx: MAC context
+ * @p_buf: Pointer to the assoc IE buffer
+ * @n_buf: length of the @p_buf
+ * @p_frm: Struct to populate the IE buffer after parsing
+ * @append_ie: Boolean to indicate whether to reset @p_frm or not. If @append_ie
+ *             is true, @p_frm struct is not reset to zeros.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS dot11f_parse_assoc_response(tpAniSirGlobal mac_ctx,
+						 uint8_t *p_buf, uint32_t n_buf,
+						 tDot11fAssocResponse *p_frm,
+						 bool append_ie)
+{
+	uint32_t status;
+
+	status = dot11f_unpack_assoc_response(mac_ctx, p_buf,
+					      n_buf, p_frm, append_ie);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse an Association Response (0x%08x, %d bytes):",
+			status, n_buf);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   p_buf, n_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * fils_convert_assoc_rsp_frame2_struct() - Copy FILS IE's to Assoc rsp struct
+ * @ar: frame parser Assoc response struct
+ * @pAssocRsp: LIM Assoc response
+ *
+ * Return: None
+ */
+static void fils_convert_assoc_rsp_frame2_struct(tDot11fAssocResponse *ar,
+						 tpSirAssocRsp pAssocRsp)
+{
+	if (ar->fils_session.present) {
+		pe_debug("fils session IE present");
+		pAssocRsp->fils_session.present = true;
+		qdf_mem_copy(pAssocRsp->fils_session.session,
+				ar->fils_session.session,
+				DOT11F_IE_FILS_SESSION_MAX_LEN);
+	}
+
+	if (ar->fils_key_confirmation.present) {
+		pe_debug("fils key conf IE present");
+		pAssocRsp->fils_key_auth.num_key_auth =
+			ar->fils_key_confirmation.num_key_auth;
+		qdf_mem_copy(pAssocRsp->fils_key_auth.key_auth,
+				ar->fils_key_confirmation.key_auth,
+				pAssocRsp->fils_key_auth.num_key_auth);
+	}
+
+	if (ar->fils_kde.present) {
+		pe_debug("fils kde IE present %d",
+				ar->fils_kde.num_kde_list);
+		pAssocRsp->fils_kde.num_kde_list =
+			ar->fils_kde.num_kde_list;
+		qdf_mem_copy(pAssocRsp->fils_kde.key_rsc,
+				ar->fils_kde.key_rsc, KEY_RSC_LEN);
+		qdf_mem_copy(&pAssocRsp->fils_kde.kde_list,
+				&ar->fils_kde.kde_list,
+				pAssocRsp->fils_kde.num_kde_list);
+	}
+
+	if (ar->fils_hlp_container.present) {
+		pe_debug("FILS HLP container IE present");
+		sir_copy_mac_addr(pAssocRsp->dst_mac.bytes,
+				ar->fils_hlp_container.dest_mac);
+		sir_copy_mac_addr(pAssocRsp->src_mac.bytes,
+				ar->fils_hlp_container.src_mac);
+		pAssocRsp->hlp_data_len = ar->fils_hlp_container.num_hlp_packet;
+		qdf_mem_copy(pAssocRsp->hlp_data,
+				ar->fils_hlp_container.hlp_packet,
+				pAssocRsp->hlp_data_len);
+
+		if (ar->fragment_ie.present) {
+			pe_debug("FILS fragment ie present");
+			qdf_mem_copy(pAssocRsp->hlp_data +
+					pAssocRsp->hlp_data_len,
+					ar->fragment_ie.data,
+					ar->fragment_ie.num_data);
+			pAssocRsp->hlp_data_len += ar->fragment_ie.num_data;
+		}
+	}
+}
+#else
+static inline void fils_convert_assoc_rsp_frame2_struct(tDot11fAssocResponse
+							*ar, tpSirAssocRsp
+							pAssocRsp)
+{ }
+#endif
+
+QDF_STATUS
+sir_convert_assoc_resp_frame2_struct(tpAniSirGlobal pMac,
+		tpPESession session_entry,
+		uint8_t *pFrame, uint32_t nFrame,
+		tpSirAssocRsp pAssocRsp)
+{
+	tDot11fAssocResponse *ar;
+	uint32_t status;
+	uint8_t cnt = 0;
+
+	ar = qdf_mem_malloc(sizeof(*ar));
+	if (!ar)
+		return QDF_STATUS_E_FAILURE;
+
+	/* decrypt the cipher text using AEAD decryption */
+	if (lim_is_fils_connection(session_entry)) {
+		status = aead_decrypt_assoc_rsp(pMac, session_entry,
+						ar, pFrame, &nFrame);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			pe_err("FILS assoc rsp AEAD decrypt fails");
+			qdf_mem_free(ar);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	status = dot11f_parse_assoc_response(pMac, pFrame, nFrame, ar, false);
+	if (QDF_STATUS_SUCCESS != status) {
+		qdf_mem_free(ar);
+		return status;
+	}
+
+
+	/* Capabilities */
+	pAssocRsp->capabilityInfo.ess = ar->Capabilities.ess;
+	pAssocRsp->capabilityInfo.ibss = ar->Capabilities.ibss;
+	pAssocRsp->capabilityInfo.cfPollable = ar->Capabilities.cfPollable;
+	pAssocRsp->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq;
+	pAssocRsp->capabilityInfo.privacy = ar->Capabilities.privacy;
+	pAssocRsp->capabilityInfo.shortPreamble =
+		ar->Capabilities.shortPreamble;
+	pAssocRsp->capabilityInfo.pbcc = ar->Capabilities.pbcc;
+	pAssocRsp->capabilityInfo.channelAgility =
+		ar->Capabilities.channelAgility;
+	pAssocRsp->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt;
+	pAssocRsp->capabilityInfo.qos = ar->Capabilities.qos;
+	pAssocRsp->capabilityInfo.shortSlotTime =
+		ar->Capabilities.shortSlotTime;
+	pAssocRsp->capabilityInfo.apsd = ar->Capabilities.apsd;
+	pAssocRsp->capabilityInfo.rrm = ar->Capabilities.rrm;
+	pAssocRsp->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm;
+	pAssocRsp->capabilityInfo.delayedBA = ar->Capabilities.delayedBA;
+	pAssocRsp->capabilityInfo.immediateBA = ar->Capabilities.immediateBA;
+
+	pAssocRsp->statusCode = ar->Status.status;
+	pAssocRsp->aid = ar->AID.associd;
+#ifdef WLAN_FEATURE_11W
+	if (ar->TimeoutInterval.present) {
+		pAssocRsp->TimeoutInterval.present = 1;
+		pAssocRsp->TimeoutInterval.timeoutType =
+			ar->TimeoutInterval.timeoutType;
+		pAssocRsp->TimeoutInterval.timeoutValue =
+			ar->TimeoutInterval.timeoutValue;
+	}
+#endif
+
+	if (!ar->SuppRates.present) {
+		pAssocRsp->suppRatesPresent = 0;
+		pe_debug_rl("Mandatory IE Supported Rates not present!");
+	} else {
+		pAssocRsp->suppRatesPresent = 1;
+		convert_supp_rates(pMac, &pAssocRsp->supportedRates,
+				&ar->SuppRates);
+	}
+
+	if (ar->ExtSuppRates.present) {
+		pAssocRsp->extendedRatesPresent = 1;
+		convert_ext_supp_rates(pMac, &pAssocRsp->extendedRates,
+				&ar->ExtSuppRates);
+	}
+
+	if (ar->EDCAParamSet.present) {
+		pAssocRsp->edcaPresent = 1;
+		convert_edca_param(pMac, &pAssocRsp->edca, &ar->EDCAParamSet);
+	}
+	if (ar->WMMParams.present) {
+		pAssocRsp->wmeEdcaPresent = 1;
+		convert_wmm_params(pMac, &pAssocRsp->edca, &ar->WMMParams);
+		pe_debug("Received Assoc Resp with WMM Param");
+		__print_wmm_params(pMac, &ar->WMMParams);
+	}
+
+	if (ar->HTCaps.present) {
+		pe_debug("Received Assoc Resp with HT Cap");
+		qdf_mem_copy(&pAssocRsp->HTCaps, &ar->HTCaps,
+			     sizeof(tDot11fIEHTCaps));
+	}
+
+	if (ar->HTInfo.present) {
+		pe_debug("Received Assoc Resp with HT Info");
+		qdf_mem_copy(&pAssocRsp->HTInfo, &ar->HTInfo,
+			     sizeof(tDot11fIEHTInfo));
+	}
+	if (ar->MobilityDomain.present) {
+		/* MobilityDomain */
+		pAssocRsp->mdiePresent = 1;
+		qdf_mem_copy((uint8_t *) &(pAssocRsp->mdie[0]),
+				(uint8_t *) &(ar->MobilityDomain.MDID),
+				sizeof(uint16_t));
+		pAssocRsp->mdie[2] = ((ar->MobilityDomain.overDSCap << 0) |
+				      (ar->MobilityDomain.resourceReqCap << 1));
+		pe_debug("new mdie=%02x%02x%02x",
+			(unsigned int)pAssocRsp->mdie[0],
+			(unsigned int)pAssocRsp->mdie[1],
+			(unsigned int)pAssocRsp->mdie[2]);
+	}
+
+	if (ar->FTInfo.present) {
+		pe_debug("FT Info present %d %d %d",
+			ar->FTInfo.R0KH_ID.num_PMK_R0_ID,
+			ar->FTInfo.R0KH_ID.present, ar->FTInfo.R1KH_ID.present);
+		pAssocRsp->ftinfoPresent = 1;
+		qdf_mem_copy(&pAssocRsp->FTInfo, &ar->FTInfo,
+				sizeof(tDot11fIEFTInfo));
+	}
+
+	if (ar->num_RICDataDesc && ar->num_RICDataDesc <= 2) {
+		for (cnt = 0; cnt < ar->num_RICDataDesc; cnt++) {
+			if (ar->RICDataDesc[cnt].present) {
+				qdf_mem_copy(&pAssocRsp->RICData[cnt],
+						&ar->RICDataDesc[cnt],
+						sizeof(tDot11fIERICDataDesc));
+			}
+		}
+		pAssocRsp->num_RICData = ar->num_RICDataDesc;
+		pAssocRsp->ricPresent = true;
+	}
+
+#ifdef FEATURE_WLAN_ESE
+	if (ar->num_WMMTSPEC) {
+		pAssocRsp->num_tspecs = ar->num_WMMTSPEC;
+		for (cnt = 0; cnt < ar->num_WMMTSPEC; cnt++) {
+			qdf_mem_copy(&pAssocRsp->TSPECInfo[cnt],
+					&ar->WMMTSPEC[cnt],
+					sizeof(tDot11fIEWMMTSPEC));
+		}
+		pAssocRsp->tspecPresent = true;
+	}
+
+	if (ar->ESETrafStrmMet.present) {
+		pAssocRsp->tsmPresent = 1;
+		qdf_mem_copy(&pAssocRsp->tsmIE.tsid,
+				&ar->ESETrafStrmMet.tsid,
+				sizeof(tSirMacESETSMIE));
+	}
+#endif
+
+	if (ar->VHTCaps.present) {
+		qdf_mem_copy(&pAssocRsp->VHTCaps, &ar->VHTCaps,
+			     sizeof(tDot11fIEVHTCaps));
+		pe_debug("Received Assoc Response with VHT Cap");
+		lim_log_vht_cap(pMac, &pAssocRsp->VHTCaps);
+	}
+	if (ar->VHTOperation.present) {
+		qdf_mem_copy(&pAssocRsp->VHTOperation, &ar->VHTOperation,
+			     sizeof(tDot11fIEVHTOperation));
+		pe_debug("Received Assoc Response with VHT Operation");
+		lim_log_vht_operation(pMac, &pAssocRsp->VHTOperation);
+	}
+
+	if (ar->ExtCap.present) {
+		struct s_ext_cap *ext_cap;
+
+		qdf_mem_copy(&pAssocRsp->ExtCap, &ar->ExtCap,
+				sizeof(tDot11fIEExtCap));
+		ext_cap = (struct s_ext_cap *)&pAssocRsp->ExtCap.bytes;
+		pe_debug("timingMeas: %d, finetimingMeas Init: %d, Resp: %d",
+			ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
+			ext_cap->fine_time_meas_responder);
+	}
+
+	if (ar->QosMapSet.present) {
+		pAssocRsp->QosMapSet.present = 1;
+		convert_qos_mapset_frame(pMac, &pAssocRsp->QosMapSet,
+					 &ar->QosMapSet);
+		pe_debug("Received Assoc Response with Qos Map Set");
+		lim_log_qos_map_set(pMac, &pAssocRsp->QosMapSet);
+	}
+
+	pAssocRsp->vendor_vht_ie.present = ar->vendor_vht_ie.present;
+	if (ar->vendor_vht_ie.present)
+		pAssocRsp->vendor_vht_ie.sub_type = ar->vendor_vht_ie.sub_type;
+	if (ar->OBSSScanParameters.present) {
+		qdf_mem_copy(&pAssocRsp->obss_scanparams,
+				&ar->OBSSScanParameters,
+				sizeof(struct sDot11fIEOBSSScanParameters));
+	}
+	if (ar->vendor_vht_ie.VHTCaps.present) {
+		qdf_mem_copy(&pAssocRsp->vendor_vht_ie.VHTCaps,
+				&ar->vendor_vht_ie.VHTCaps,
+				sizeof(tDot11fIEVHTCaps));
+		pe_debug("Received Assoc Response with Vendor specific VHT Cap");
+		lim_log_vht_cap(pMac, &pAssocRsp->VHTCaps);
+	}
+	if (ar->vendor_vht_ie.VHTOperation.present) {
+		qdf_mem_copy(&pAssocRsp->vendor_vht_ie.VHTOperation,
+				&ar->vendor_vht_ie.VHTOperation,
+				sizeof(tDot11fIEVHTOperation));
+		pe_debug("Received Assoc Response with Vendor specific VHT Oper");
+		lim_log_vht_operation(pMac, &pAssocRsp->VHTOperation);
+	}
+
+	if (ar->he_cap.present) {
+		pe_debug("11AX: HE cap IE present");
+		qdf_mem_copy(&pAssocRsp->he_cap, &ar->he_cap,
+			     sizeof(tDot11fIEhe_cap));
+	}
+	if (ar->he_op.present) {
+		pe_debug("11AX: HE Operation IE present");
+		qdf_mem_copy(&pAssocRsp->he_op, &ar->he_op,
+			     sizeof(tDot11fIEhe_op));
+		pe_debug("bss_clr %d def_pe %d part_bss_clr %d bss_col_dis %d",
+				pAssocRsp->he_op.bss_color,
+				pAssocRsp->he_op.default_pe,
+				pAssocRsp->he_op.partial_bss_col,
+				pAssocRsp->he_op.bss_col_disabled);
+	}
+
+	if (ar->mu_edca_param_set.present) {
+		pe_debug("11AX: HE MU EDCA param IE present");
+		pAssocRsp->mu_edca_present = true;
+		convert_mu_edca_param(pMac, &pAssocRsp->mu_edca,
+				&ar->mu_edca_param_set);
+	}
+
+	if (ar->MBO_IE.present && ar->MBO_IE.rssi_assoc_rej.present) {
+		qdf_mem_copy(&pAssocRsp->rssi_assoc_rej,
+				&ar->MBO_IE.rssi_assoc_rej,
+				sizeof(tDot11fTLVrssi_assoc_rej));
+		pe_debug("Received Assoc Response with rssi based assoc rej");
+	}
+
+	fils_convert_assoc_rsp_frame2_struct(ar, pAssocRsp);
+
+	qdf_mem_free(ar);
+	return QDF_STATUS_SUCCESS;
+
+} /* End sir_convert_assoc_resp_frame2_struct. */
+
+QDF_STATUS
+sir_convert_reassoc_req_frame2_struct(tpAniSirGlobal pMac,
+				      uint8_t *pFrame,
+				      uint32_t nFrame, tpSirAssocReq pAssocReq)
+{
+	tDot11fReAssocRequest *ar;
+	uint32_t status;
+
+	ar = qdf_mem_malloc(sizeof(*ar));
+	if (!ar)
+		return QDF_STATUS_E_NOMEM;
+	/* Zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) pAssocReq, sizeof(tSirAssocReq), 0);
+
+	/* delegate to the framesc-generated code, */
+	status = dot11f_unpack_re_assoc_request(pMac, pFrame, nFrame,
+						ar, false);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse a Re-association Request (0x%08x, %d bytes):",
+			status, nFrame);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pFrame, nFrame);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking a Re-association Request (0x%08x, %d bytes):",
+			status, nFrame);
+	}
+	/* & "transliterate" from a 'tDot11fReAssocRequest' to a 'tSirAssocReq'... */
+
+	/* make sure this is seen as a re-assoc request */
+	pAssocReq->reassocRequest = 1;
+
+	/* Capabilities */
+	pAssocReq->capabilityInfo.ess = ar->Capabilities.ess;
+	pAssocReq->capabilityInfo.ibss = ar->Capabilities.ibss;
+	pAssocReq->capabilityInfo.cfPollable = ar->Capabilities.cfPollable;
+	pAssocReq->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq;
+	pAssocReq->capabilityInfo.privacy = ar->Capabilities.privacy;
+	pAssocReq->capabilityInfo.shortPreamble = ar->Capabilities.shortPreamble;
+	pAssocReq->capabilityInfo.pbcc = ar->Capabilities.pbcc;
+	pAssocReq->capabilityInfo.channelAgility =
+		ar->Capabilities.channelAgility;
+	pAssocReq->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt;
+	pAssocReq->capabilityInfo.qos = ar->Capabilities.qos;
+	pAssocReq->capabilityInfo.shortSlotTime = ar->Capabilities.shortSlotTime;
+	pAssocReq->capabilityInfo.apsd = ar->Capabilities.apsd;
+	pAssocReq->capabilityInfo.rrm = ar->Capabilities.rrm;
+	pAssocReq->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm;
+	pAssocReq->capabilityInfo.delayedBA = ar->Capabilities.delayedBA;
+	pAssocReq->capabilityInfo.immediateBA = ar->Capabilities.immediateBA;
+
+	/* Listen Interval */
+	pAssocReq->listenInterval = ar->ListenInterval.interval;
+
+	/* SSID */
+	if (ar->SSID.present) {
+		pAssocReq->ssidPresent = 1;
+		convert_ssid(pMac, &pAssocReq->ssId, &ar->SSID);
+	}
+	/* Supported Rates */
+	if (ar->SuppRates.present) {
+		pAssocReq->suppRatesPresent = 1;
+		convert_supp_rates(pMac, &pAssocReq->supportedRates,
+				   &ar->SuppRates);
+	}
+	/* Extended Supported Rates */
+	if (ar->ExtSuppRates.present) {
+		pAssocReq->extendedRatesPresent = 1;
+		convert_ext_supp_rates(pMac, &pAssocReq->extendedRates,
+				       &ar->ExtSuppRates);
+	}
+	/* QOS Capabilities: */
+	if (ar->QOSCapsStation.present) {
+		pAssocReq->qosCapabilityPresent = 1;
+		convert_qos_caps_station(pMac, &pAssocReq->qosCapability,
+					 &ar->QOSCapsStation);
+	}
+	/* WPA */
+	if (ar->WPAOpaque.present) {
+		pAssocReq->wpaPresent = 1;
+		convert_wpa_opaque(pMac, &pAssocReq->wpa, &ar->WPAOpaque);
+	}
+	/* RSN */
+	if (ar->RSNOpaque.present) {
+		pAssocReq->rsnPresent = 1;
+		convert_rsn_opaque(pMac, &pAssocReq->rsn, &ar->RSNOpaque);
+	}
+
+	/* Power Capabilities */
+	if (ar->PowerCaps.present) {
+		pAssocReq->powerCapabilityPresent = 1;
+		convert_power_caps(pMac, &pAssocReq->powerCapability,
+				   &ar->PowerCaps);
+	}
+	/* Supported Channels */
+	if (ar->SuppChannels.present) {
+		pAssocReq->supportedChannelsPresent = 1;
+		convert_supp_channels(pMac, &pAssocReq->supportedChannels,
+				      &ar->SuppChannels);
+	}
+
+	if (ar->HTCaps.present) {
+		qdf_mem_copy(&pAssocReq->HTCaps, &ar->HTCaps,
+			     sizeof(tDot11fIEHTCaps));
+	}
+
+	if (ar->WMMInfoStation.present) {
+		pAssocReq->wmeInfoPresent = 1;
+		qdf_mem_copy(&pAssocReq->WMMInfoStation, &ar->WMMInfoStation,
+			     sizeof(tDot11fIEWMMInfoStation));
+
+	}
+
+	if (ar->WMMCaps.present)
+		pAssocReq->wsmCapablePresent = 1;
+
+	if (!pAssocReq->ssidPresent) {
+		pe_debug("Received Assoc without SSID IE");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!pAssocReq->suppRatesPresent && !pAssocReq->extendedRatesPresent) {
+		pe_debug("Received Assoc without supp rate IE");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Why no call to 'updateAssocReqFromPropCapability' here, like */
+	/* there is in 'sir_convert_assoc_req_frame2_struct'? */
+
+	/* WSC IE */
+	if (ar->WscIEOpaque.present) {
+		pAssocReq->addIEPresent = 1;
+		convert_wsc_opaque(pMac, &pAssocReq->addIE, &ar->WscIEOpaque);
+	}
+
+	if (ar->P2PIEOpaque.present) {
+		pAssocReq->addIEPresent = 1;
+		convert_p2p_opaque(pMac, &pAssocReq->addIE, &ar->P2PIEOpaque);
+	}
+#ifdef WLAN_FEATURE_WFD
+	if (ar->WFDIEOpaque.present) {
+		pAssocReq->addIEPresent = 1;
+		convert_wfd_opaque(pMac, &pAssocReq->addIE, &ar->WFDIEOpaque);
+	}
+#endif
+
+	if (ar->VHTCaps.present) {
+		qdf_mem_copy(&pAssocReq->VHTCaps, &ar->VHTCaps,
+			     sizeof(tDot11fIEVHTCaps));
+	}
+	if (ar->OperatingMode.present) {
+		qdf_mem_copy(&pAssocReq->operMode, &ar->OperatingMode,
+			     sizeof(tDot11fIEOperatingMode));
+		pe_warn("Received Assoc Req with Operating Mode IE");
+		lim_log_operating_mode(pMac, &pAssocReq->operMode);
+	}
+	if (ar->ExtCap.present) {
+		struct s_ext_cap *ext_cap;
+
+		qdf_mem_copy(&pAssocReq->ExtCap, &ar->ExtCap,
+			     sizeof(tDot11fIEExtCap));
+		ext_cap = (struct s_ext_cap *)&pAssocReq->ExtCap.bytes;
+		pe_debug("timingMeas: %d, finetimingMeas Init: %d, Resp: %d",
+			ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
+			ext_cap->fine_time_meas_responder);
+	}
+	if (ar->he_cap.present) {
+		qdf_mem_copy(&pAssocReq->he_cap, &ar->he_cap,
+			     sizeof(tDot11fIEhe_cap));
+	}
+	qdf_mem_free(ar);
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End sir_convert_reassoc_req_frame2_struct. */
+
+#ifdef FEATURE_WLAN_ESE
+QDF_STATUS
+sir_beacon_ie_ese_bcn_report(tpAniSirGlobal pMac,
+	uint8_t *pPayload, const uint32_t nPayload,
+	uint8_t **outIeBuf, uint32_t *pOutIeLen)
+{
+	tDot11fBeaconIEs *pBies = NULL;
+	uint32_t status = QDF_STATUS_SUCCESS;
+	QDF_STATUS retStatus = QDF_STATUS_SUCCESS;
+	tSirEseBcnReportMandatoryIe eseBcnReportMandatoryIe;
+
+	/* To store how many bytes are required to be allocated
+	   for Bcn report mandatory Ies */
+	uint16_t numBytes = 0, freeBytes = 0;
+	uint8_t *pos = NULL;
+
+	/* Zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) &eseBcnReportMandatoryIe,
+		    sizeof(eseBcnReportMandatoryIe), 0);
+	pBies = qdf_mem_malloc(sizeof(tDot11fBeaconIEs));
+	if (!pBies)
+		return QDF_STATUS_E_NOMEM;
+	qdf_mem_zero(pBies, sizeof(tDot11fBeaconIEs));
+	/* delegate to the framesc-generated code, */
+	status = dot11f_unpack_beacon_i_es(pMac, pPayload, nPayload,
+					   pBies, false);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse Beacon IEs (0x%08x, %d bytes):",
+			status, nPayload);
+		qdf_mem_free(pBies);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes):",
+			status, nPayload);
+	}
+	/* & "transliterate" from a 'tDot11fBeaconIEs' to a 'eseBcnReportMandatoryIe'... */
+	if (!pBies->SSID.present) {
+		pe_debug("Mandatory IE SSID not present!");
+	} else {
+		eseBcnReportMandatoryIe.ssidPresent = 1;
+		convert_ssid(pMac, &eseBcnReportMandatoryIe.ssId, &pBies->SSID);
+		/* 1 for EID, 1 for length and length bytes */
+		numBytes += 1 + 1 + eseBcnReportMandatoryIe.ssId.length;
+	}
+
+	if (!pBies->SuppRates.present) {
+		pe_debug_rl("Mandatory IE Supported Rates not present!");
+	} else {
+		eseBcnReportMandatoryIe.suppRatesPresent = 1;
+		convert_supp_rates(pMac, &eseBcnReportMandatoryIe.supportedRates,
+				   &pBies->SuppRates);
+		numBytes +=
+			1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates;
+	}
+
+	if (pBies->FHParamSet.present) {
+		eseBcnReportMandatoryIe.fhParamPresent = 1;
+		convert_fh_params(pMac, &eseBcnReportMandatoryIe.fhParamSet,
+				  &pBies->FHParamSet);
+		numBytes += 1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX;
+	}
+
+	if (pBies->DSParams.present) {
+		eseBcnReportMandatoryIe.dsParamsPresent = 1;
+		eseBcnReportMandatoryIe.dsParamSet.channelNumber =
+			pBies->DSParams.curr_channel;
+		numBytes += 1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX;
+	}
+
+	if (pBies->CFParams.present) {
+		eseBcnReportMandatoryIe.cfPresent = 1;
+		convert_cf_params(pMac, &eseBcnReportMandatoryIe.cfParamSet,
+				  &pBies->CFParams);
+		numBytes += 1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX;
+	}
+
+	if (pBies->IBSSParams.present) {
+		eseBcnReportMandatoryIe.ibssParamPresent = 1;
+		eseBcnReportMandatoryIe.ibssParamSet.atim =
+			pBies->IBSSParams.atim;
+		numBytes += 1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX;
+	}
+
+	if (pBies->TIM.present) {
+		eseBcnReportMandatoryIe.timPresent = 1;
+		eseBcnReportMandatoryIe.tim.dtimCount = pBies->TIM.dtim_count;
+		eseBcnReportMandatoryIe.tim.dtimPeriod = pBies->TIM.dtim_period;
+		eseBcnReportMandatoryIe.tim.bitmapControl = pBies->TIM.bmpctl;
+		/* As per the ESE spec, May truncate and report first 4 octets only */
+		numBytes += 1 + 1 + SIR_MAC_TIM_EID_MIN;
+	}
+
+	if (pBies->RRMEnabledCap.present) {
+		eseBcnReportMandatoryIe.rrmPresent = 1;
+		qdf_mem_copy(&eseBcnReportMandatoryIe.rmEnabledCapabilities,
+			     &pBies->RRMEnabledCap,
+			     sizeof(tDot11fIERRMEnabledCap));
+		numBytes += 1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX;
+	}
+
+	*outIeBuf = qdf_mem_malloc(numBytes);
+	if (!*outIeBuf) {
+		qdf_mem_free(pBies);
+		return QDF_STATUS_E_NOMEM;
+	}
+	pos = *outIeBuf;
+	*pOutIeLen = numBytes;
+	freeBytes = numBytes;
+
+	/* Start filling the output Ie with Mandatory IE information */
+	/* Fill SSID IE */
+	if (eseBcnReportMandatoryIe.ssidPresent) {
+		if (freeBytes < (1 + 1 + eseBcnReportMandatoryIe.ssId.length)) {
+			pe_err("Insufficient memory to copy SSID");
+			retStatus = QDF_STATUS_E_FAILURE;
+			goto err_bcnrep;
+		}
+		*pos = SIR_MAC_SSID_EID;
+		pos++;
+		*pos = eseBcnReportMandatoryIe.ssId.length;
+		pos++;
+		qdf_mem_copy(pos,
+			     (uint8_t *) eseBcnReportMandatoryIe.ssId.ssId,
+			     eseBcnReportMandatoryIe.ssId.length);
+		pos += eseBcnReportMandatoryIe.ssId.length;
+		freeBytes -= (1 + 1 + eseBcnReportMandatoryIe.ssId.length);
+	}
+
+	/* Fill Supported Rates IE */
+	if (eseBcnReportMandatoryIe.suppRatesPresent) {
+		if (freeBytes <
+		    (1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates)) {
+			pe_err("Insufficient memory to copy Rates IE");
+			retStatus = QDF_STATUS_E_FAILURE;
+			goto err_bcnrep;
+		}
+		if (eseBcnReportMandatoryIe.supportedRates.numRates <=
+			SIR_MAC_RATESET_EID_MAX) {
+			*pos = SIR_MAC_RATESET_EID;
+			pos++;
+			*pos = eseBcnReportMandatoryIe.supportedRates.numRates;
+			pos++;
+			qdf_mem_copy(pos,
+			     (uint8_t *) eseBcnReportMandatoryIe.supportedRates.
+			     rate,
+			     eseBcnReportMandatoryIe.supportedRates.numRates);
+			pos += eseBcnReportMandatoryIe.supportedRates.numRates;
+			freeBytes -=
+			(1 + 1 +
+			 eseBcnReportMandatoryIe.supportedRates.numRates);
+		}
+	}
+
+	/* Fill FH Parameter set IE */
+	if (eseBcnReportMandatoryIe.fhParamPresent) {
+		if (freeBytes < (1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX)) {
+			pe_err("Insufficient memory to copy FHIE");
+			retStatus = QDF_STATUS_E_FAILURE;
+			goto err_bcnrep;
+		}
+		*pos = SIR_MAC_FH_PARAM_SET_EID;
+		pos++;
+		*pos = SIR_MAC_FH_PARAM_SET_EID_MAX;
+		pos++;
+		qdf_mem_copy(pos,
+			     (uint8_t *) &eseBcnReportMandatoryIe.fhParamSet,
+			     SIR_MAC_FH_PARAM_SET_EID_MAX);
+		pos += SIR_MAC_FH_PARAM_SET_EID_MAX;
+		freeBytes -= (1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX);
+	}
+
+	/* Fill DS Parameter set IE */
+	if (eseBcnReportMandatoryIe.dsParamsPresent) {
+		if (freeBytes < (1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX)) {
+			pe_err("Insufficient memory to copy DS IE");
+			retStatus = QDF_STATUS_E_FAILURE;
+			goto err_bcnrep;
+		}
+		*pos = SIR_MAC_DS_PARAM_SET_EID;
+		pos++;
+		*pos = SIR_MAC_DS_PARAM_SET_EID_MAX;
+		pos++;
+		*pos = eseBcnReportMandatoryIe.dsParamSet.channelNumber;
+		pos += SIR_MAC_DS_PARAM_SET_EID_MAX;
+		freeBytes -= (1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX);
+	}
+
+	/* Fill CF Parameter set */
+	if (eseBcnReportMandatoryIe.cfPresent) {
+		if (freeBytes < (1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX)) {
+			pe_err("Insufficient memory to copy CF IE");
+			retStatus = QDF_STATUS_E_FAILURE;
+			goto err_bcnrep;
+		}
+		*pos = SIR_MAC_CF_PARAM_SET_EID;
+		pos++;
+		*pos = SIR_MAC_CF_PARAM_SET_EID_MAX;
+		pos++;
+		qdf_mem_copy(pos,
+			     (uint8_t *) &eseBcnReportMandatoryIe.cfParamSet,
+			     SIR_MAC_CF_PARAM_SET_EID_MAX);
+		pos += SIR_MAC_CF_PARAM_SET_EID_MAX;
+		freeBytes -= (1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX);
+	}
+
+	/* Fill IBSS Parameter set IE */
+	if (eseBcnReportMandatoryIe.ibssParamPresent) {
+		if (freeBytes < (1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX)) {
+			pe_err("Insufficient memory to copy IBSS IE");
+			retStatus = QDF_STATUS_E_FAILURE;
+			goto err_bcnrep;
+		}
+		*pos = SIR_MAC_IBSS_PARAM_SET_EID;
+		pos++;
+		*pos = SIR_MAC_IBSS_PARAM_SET_EID_MAX;
+		pos++;
+		qdf_mem_copy(pos,
+			     (uint8_t *) &eseBcnReportMandatoryIe.ibssParamSet.
+			     atim, SIR_MAC_IBSS_PARAM_SET_EID_MAX);
+		pos += SIR_MAC_IBSS_PARAM_SET_EID_MAX;
+		freeBytes -= (1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX);
+	}
+
+	/* Fill TIM IE */
+	if (eseBcnReportMandatoryIe.timPresent) {
+		if (freeBytes < (1 + 1 + SIR_MAC_TIM_EID_MIN)) {
+			pe_err("Insufficient memory to copy TIM IE");
+			retStatus = QDF_STATUS_E_FAILURE;
+			goto err_bcnrep;
+		}
+		*pos = SIR_MAC_TIM_EID;
+		pos++;
+		*pos = SIR_MAC_TIM_EID_MIN;
+		pos++;
+		qdf_mem_copy(pos,
+			     (uint8_t *) &eseBcnReportMandatoryIe.tim,
+			     SIR_MAC_TIM_EID_MIN);
+		pos += SIR_MAC_TIM_EID_MIN;
+		freeBytes -= (1 + 1 + SIR_MAC_TIM_EID_MIN);
+	}
+
+	/* Fill RM Capability IE */
+	if (eseBcnReportMandatoryIe.rrmPresent) {
+		if (freeBytes < (1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX)) {
+			pe_err("Insufficient memory to copy RRM IE");
+			retStatus = QDF_STATUS_E_FAILURE;
+			goto err_bcnrep;
+		}
+		*pos = SIR_MAC_RM_ENABLED_CAPABILITY_EID;
+		pos++;
+		*pos = SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX;
+		pos++;
+		qdf_mem_copy(pos,
+			     (uint8_t *) &eseBcnReportMandatoryIe.
+			     rmEnabledCapabilities,
+			     SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX);
+		freeBytes -= (1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX);
+	}
+
+	if (freeBytes != 0) {
+		pe_err("Mismatch in allocation and copying of IE in Bcn Rep");
+		retStatus = QDF_STATUS_E_FAILURE;
+	}
+
+err_bcnrep:
+	/* The message counter would not be incremented in case of
+	 * returning failure and hence next time, this function gets
+	 * called, it would be using the same msg ctr for a different
+	 * BSS.So, it is good to clear the memory allocated for a BSS
+	 * that is returning failure.On success, the caller would take
+	 * care of freeing up the memory*/
+	if (retStatus == QDF_STATUS_E_FAILURE) {
+		qdf_mem_free(*outIeBuf);
+		*outIeBuf = NULL;
+	}
+
+	qdf_mem_free(pBies);
+	return retStatus;
+}
+
+#endif /* FEATURE_WLAN_ESE */
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+static void update_bss_color_change_from_beacon_ies(tDot11fBeaconIEs *bcn_ies,
+		tpSirProbeRespBeacon bcn_struct)
+{
+	if (bcn_ies->bss_color_change.present) {
+		qdf_mem_copy(&bcn_struct->vendor_he_bss_color_change,
+			     &bcn_ies->bss_color_change,
+			     sizeof(tDot11fIEbss_color_change));
+	}
+}
+#else
+static inline void update_bss_color_change_from_beacon_ies(
+		tDot11fBeaconIEs *bcn_ies,
+		tpSirProbeRespBeacon bcn_struct)
+{}
+#endif
+
+QDF_STATUS
+sir_parse_beacon_ie(tpAniSirGlobal pMac,
+		    tpSirProbeRespBeacon pBeaconStruct,
+		    uint8_t *pPayload, uint32_t nPayload)
+{
+	tDot11fBeaconIEs *pBies;
+	uint32_t status;
+
+	/* Zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0);
+
+	pBies = qdf_mem_malloc(sizeof(tDot11fBeaconIEs));
+	if (!pBies)
+		return QDF_STATUS_E_NOMEM;
+	qdf_mem_zero(pBies, sizeof(tDot11fBeaconIEs));
+	/* delegate to the framesc-generated code, */
+	status = dot11f_unpack_beacon_i_es(pMac, pPayload, nPayload,
+					   pBies, false);
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse Beacon IEs (0x%08x, %d bytes):",
+			status, nPayload);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pPayload, nPayload);
+		qdf_mem_free(pBies);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes):",
+			status, nPayload);
+	}
+	/* & "transliterate" from a 'tDot11fBeaconIEs' to a 'tSirProbeRespBeacon'... */
+	if (!pBies->SSID.present) {
+		pe_debug("Mandatory IE SSID not present!");
+	} else {
+		pBeaconStruct->ssidPresent = 1;
+		convert_ssid(pMac, &pBeaconStruct->ssId, &pBies->SSID);
+	}
+
+	if (!pBies->SuppRates.present) {
+		pe_debug_rl("Mandatory IE Supported Rates not present!");
+	} else {
+		pBeaconStruct->suppRatesPresent = 1;
+		convert_supp_rates(pMac, &pBeaconStruct->supportedRates,
+				   &pBies->SuppRates);
+	}
+
+	if (pBies->ExtSuppRates.present) {
+		pBeaconStruct->extendedRatesPresent = 1;
+		convert_ext_supp_rates(pMac, &pBeaconStruct->extendedRates,
+				       &pBies->ExtSuppRates);
+	}
+
+	if (pBies->CFParams.present) {
+		pBeaconStruct->cfPresent = 1;
+		convert_cf_params(pMac, &pBeaconStruct->cfParamSet,
+				  &pBies->CFParams);
+	}
+
+	if (pBies->TIM.present) {
+		pBeaconStruct->timPresent = 1;
+		convert_tim(pMac, &pBeaconStruct->tim, &pBies->TIM);
+	}
+
+	if (pBies->Country.present) {
+		pBeaconStruct->countryInfoPresent = 1;
+		convert_country(pMac, &pBeaconStruct->countryInfoParam,
+				&pBies->Country);
+	}
+	/* 11h IEs */
+	if (pBies->TPCReport.present) {
+		pBeaconStruct->tpcReportPresent = 1;
+		qdf_mem_copy(&pBeaconStruct->tpcReport,
+			     &pBies->TPCReport, sizeof(tDot11fIETPCReport));
+	}
+
+	if (pBies->PowerConstraints.present) {
+		pBeaconStruct->powerConstraintPresent = 1;
+		qdf_mem_copy(&pBeaconStruct->localPowerConstraint,
+			     &pBies->PowerConstraints,
+			     sizeof(tDot11fIEPowerConstraints));
+	}
+#ifdef FEATURE_WLAN_ESE
+	if (pBies->ESEVersion.present)
+		pBeaconStruct->is_ese_ver_ie_present = 1;
+	if (pBies->ESETxmitPower.present) {
+		pBeaconStruct->eseTxPwr.present = 1;
+		pBeaconStruct->eseTxPwr.power_limit =
+			pBies->ESETxmitPower.power_limit;
+	}
+	if (pBies->QBSSLoad.present) {
+		qdf_mem_copy(&pBeaconStruct->QBSSLoad, &pBies->QBSSLoad,
+			     sizeof(tDot11fIEQBSSLoad));
+	}
+#endif
+
+	if (pBies->EDCAParamSet.present) {
+		pBeaconStruct->edcaPresent = 1;
+		convert_edca_param(pMac, &pBeaconStruct->edcaParams,
+				   &pBies->EDCAParamSet);
+	}
+	/* QOS Capabilities: */
+	if (pBies->QOSCapsAp.present) {
+		pBeaconStruct->qosCapabilityPresent = 1;
+		convert_qos_caps(pMac, &pBeaconStruct->qosCapability,
+				 &pBies->QOSCapsAp);
+	}
+
+	if (pBies->ChanSwitchAnn.present) {
+		pBeaconStruct->channelSwitchPresent = 1;
+		qdf_mem_copy(&pBeaconStruct->channelSwitchIE,
+			     &pBies->ChanSwitchAnn,
+			     sizeof(pBeaconStruct->channelSwitchIE));
+	}
+
+	if (pBies->SuppOperatingClasses.present) {
+		pBeaconStruct->supp_operating_class_present = 1;
+		qdf_mem_copy(&pBeaconStruct->supp_operating_classes,
+			&pBies->SuppOperatingClasses,
+			sizeof(tDot11fIESuppOperatingClasses));
+	}
+
+	if (pBies->ext_chan_switch_ann.present) {
+		pBeaconStruct->ext_chan_switch_present = 1;
+		qdf_mem_copy(&pBeaconStruct->ext_chan_switch,
+			     &pBies->ext_chan_switch_ann,
+			     sizeof(tDot11fIEext_chan_switch_ann));
+	}
+
+	if (pBies->sec_chan_offset_ele.present) {
+		pBeaconStruct->sec_chan_offset_present = 1;
+		qdf_mem_copy(&pBeaconStruct->sec_chan_offset,
+			     &pBies->sec_chan_offset_ele,
+			     sizeof(pBeaconStruct->sec_chan_offset));
+	}
+
+	if (pBies->Quiet.present) {
+		pBeaconStruct->quietIEPresent = 1;
+		qdf_mem_copy(&pBeaconStruct->quietIE, &pBies->Quiet,
+			     sizeof(tDot11fIEQuiet));
+	}
+
+	if (pBies->HTCaps.present) {
+		qdf_mem_copy(&pBeaconStruct->HTCaps, &pBies->HTCaps,
+			     sizeof(tDot11fIEHTCaps));
+	}
+
+	if (pBies->HTInfo.present) {
+		qdf_mem_copy(&pBeaconStruct->HTInfo, &pBies->HTInfo,
+			     sizeof(tDot11fIEHTInfo));
+	}
+
+	if (pBies->DSParams.present) {
+		pBeaconStruct->dsParamsPresent = 1;
+		pBeaconStruct->channelNumber = pBies->DSParams.curr_channel;
+	} else if (pBies->HTInfo.present) {
+		pBeaconStruct->channelNumber = pBies->HTInfo.primaryChannel;
+	}
+
+	if (pBies->RSN.present) {
+		pBeaconStruct->rsnPresent = 1;
+		convert_rsn(pMac, &pBeaconStruct->rsn, &pBies->RSN);
+	}
+
+	if (pBies->WPA.present) {
+		pBeaconStruct->wpaPresent = 1;
+		convert_wpa(pMac, &pBeaconStruct->wpa, &pBies->WPA);
+	}
+
+	if (pBies->WMMParams.present) {
+		pBeaconStruct->wmeEdcaPresent = 1;
+		convert_wmm_params(pMac, &pBeaconStruct->edcaParams,
+				   &pBies->WMMParams);
+	}
+
+	if (pBies->WMMInfoAp.present) {
+		pBeaconStruct->wmeInfoPresent = 1;
+	}
+
+	if (pBies->WMMCaps.present) {
+		pBeaconStruct->wsmCapablePresent = 1;
+	}
+
+	if (pBies->ERPInfo.present) {
+		pBeaconStruct->erpPresent = 1;
+		convert_erp_info(pMac, &pBeaconStruct->erpIEInfo,
+				 &pBies->ERPInfo);
+	}
+	if (pBies->VHTCaps.present) {
+		pBeaconStruct->VHTCaps.present = 1;
+		qdf_mem_copy(&pBeaconStruct->VHTCaps, &pBies->VHTCaps,
+			     sizeof(tDot11fIEVHTCaps));
+	}
+	if (pBies->VHTOperation.present) {
+		pBeaconStruct->VHTOperation.present = 1;
+		qdf_mem_copy(&pBeaconStruct->VHTOperation, &pBies->VHTOperation,
+			     sizeof(tDot11fIEVHTOperation));
+	}
+	if (pBies->VHTExtBssLoad.present) {
+		pBeaconStruct->VHTExtBssLoad.present = 1;
+		qdf_mem_copy(&pBeaconStruct->VHTExtBssLoad,
+			     &pBies->VHTExtBssLoad,
+			     sizeof(tDot11fIEVHTExtBssLoad));
+	}
+	if (pBies->OperatingMode.present) {
+		pBeaconStruct->OperatingMode.present = 1;
+		qdf_mem_copy(&pBeaconStruct->OperatingMode,
+			     &pBies->OperatingMode,
+			     sizeof(tDot11fIEOperatingMode));
+	}
+	if (pBies->MobilityDomain.present) {
+		pBeaconStruct->mdiePresent = 1;
+		qdf_mem_copy(pBeaconStruct->mdie, &pBies->MobilityDomain.MDID,
+			     SIR_MDIE_SIZE);
+	}
+
+	pBeaconStruct->Vendor1IEPresent = pBies->Vendor1IE.present;
+	pBeaconStruct->Vendor3IEPresent = pBies->Vendor3IE.present;
+	pBeaconStruct->vendor_vht_ie.present = pBies->vendor_vht_ie.present;
+	if (pBies->vendor_vht_ie.present)
+		pBeaconStruct->vendor_vht_ie.sub_type =
+						pBies->vendor_vht_ie.sub_type;
+
+	if (pBies->vendor_vht_ie.VHTCaps.present) {
+		pBeaconStruct->vendor_vht_ie.VHTCaps.present = 1;
+		qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTCaps,
+				&pBies->vendor_vht_ie.VHTCaps,
+				sizeof(tDot11fIEVHTCaps));
+	}
+	if (pBies->vendor_vht_ie.VHTOperation.present) {
+		pBeaconStruct->vendor_vht_ie.VHTOperation.present = 1;
+		qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTOperation,
+				&pBies->vendor_vht_ie.VHTOperation,
+				sizeof(tDot11fIEVHTOperation));
+	}
+	if (pBies->ExtCap.present) {
+		qdf_mem_copy(&pBeaconStruct->ext_cap, &pBies->ExtCap,
+				sizeof(tDot11fIEExtCap));
+	}
+	/* Update HS 2.0 Information Element */
+	if (pBies->hs20vendor_ie.present) {
+		pe_debug("HS20 Indication Element Present, rel#:%u, id:%u",
+			pBies->hs20vendor_ie.release_num,
+			pBies->hs20vendor_ie.hs_id_present);
+		qdf_mem_copy(&pBeaconStruct->hs20vendor_ie,
+			&pBies->hs20vendor_ie,
+			sizeof(tDot11fIEhs20vendor_ie) -
+			sizeof(pBies->hs20vendor_ie.hs_id));
+		if (pBies->hs20vendor_ie.hs_id_present)
+			qdf_mem_copy(&pBeaconStruct->hs20vendor_ie.hs_id,
+				&pBies->hs20vendor_ie.hs_id,
+				sizeof(pBies->hs20vendor_ie.hs_id));
+	}
+
+	if (pBies->MBO_IE.present) {
+		pBeaconStruct->MBO_IE_present = true;
+		if (pBies->MBO_IE.cellular_data_cap.present)
+			pBeaconStruct->MBO_capability =
+				pBies->MBO_IE.cellular_data_cap.cellular_connectivity;
+
+		if (pBies->MBO_IE.assoc_disallowed.present) {
+			pBeaconStruct->assoc_disallowed = true;
+			pBeaconStruct->assoc_disallowed_reason =
+				pBies->MBO_IE.assoc_disallowed.reason_code;
+		}
+	}
+
+	if (pBies->QCN_IE.present) {
+		pBeaconStruct->QCN_IE.is_present = true;
+		if (pBies->QCN_IE.version[0] == QCN_IE_VERSION_SUBATTR_ID) {
+			pBeaconStruct->QCN_IE.version
+					= pBies->QCN_IE.version[2];
+			pBeaconStruct->QCN_IE.sub_version
+					= pBies->QCN_IE.version[3];
+		}
+	}
+
+	if (pBies->he_cap.present) {
+		qdf_mem_copy(&pBeaconStruct->he_cap, &pBies->he_cap,
+			     sizeof(tDot11fIEhe_cap));
+	}
+	if (pBies->he_op.present) {
+		qdf_mem_copy(&pBeaconStruct->he_op, &pBies->he_op,
+			     sizeof(tDot11fIEhe_op));
+	}
+
+	update_bss_color_change_from_beacon_ies(pBies, pBeaconStruct);
+
+	qdf_mem_free(pBies);
+	return QDF_STATUS_SUCCESS;
+} /* End sir_parse_beacon_ie. */
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+static void convert_bcon_bss_color_change_ie(tDot11fBeacon *bcn_frm,
+		tpSirProbeRespBeacon bcn_struct)
+{
+	if (bcn_frm->bss_color_change.present) {
+		pe_debug("11AX: HE BSS color change present");
+		qdf_mem_copy(&bcn_struct->vendor_he_bss_color_change,
+			     &bcn_frm->bss_color_change,
+			     sizeof(tDot11fIEbss_color_change));
+	}
+}
+#else
+static inline void convert_bcon_bss_color_change_ie(tDot11fBeacon *bcn_frm,
+		tpSirProbeRespBeacon bcn_struct)
+{}
+#endif
+
+QDF_STATUS
+sir_convert_beacon_frame2_struct(tpAniSirGlobal pMac,
+				 uint8_t *pFrame,
+				 tpSirProbeRespBeacon pBeaconStruct)
+{
+	tDot11fBeacon *pBeacon;
+	uint32_t status, nPayload;
+	uint8_t *pPayload;
+	tpSirMacMgmtHdr pHdr;
+	uint8_t mappedRXCh;
+
+	pPayload = WMA_GET_RX_MPDU_DATA(pFrame);
+	nPayload = WMA_GET_RX_PAYLOAD_LEN(pFrame);
+	pHdr = WMA_GET_RX_MAC_HEADER(pFrame);
+	mappedRXCh = WMA_GET_RX_CH(pFrame);
+
+	/* Zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0);
+
+	pBeacon = qdf_mem_malloc(sizeof(tDot11fBeacon));
+	if (!pBeacon)
+		return QDF_STATUS_E_NOMEM;
+
+	/* get the MAC address out of the BD, */
+	qdf_mem_copy(pBeaconStruct->bssid, pHdr->sa, 6);
+
+	/* delegate to the framesc-generated code, */
+	status = dot11f_unpack_beacon(pMac, pPayload, nPayload, pBeacon, false);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse Beacon IEs (0x%08x, %d bytes):",
+			status, nPayload);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				   pPayload, nPayload);
+		qdf_mem_free(pBeacon);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* & "transliterate" from a 'tDot11fBeacon' to a 'tSirProbeRespBeacon'... */
+	/* Timestamp */
+	qdf_mem_copy((uint8_t *) pBeaconStruct->timeStamp,
+		     (uint8_t *) &pBeacon->TimeStamp,
+		     sizeof(tSirMacTimeStamp));
+
+	/* Beacon Interval */
+	pBeaconStruct->beaconInterval = pBeacon->BeaconInterval.interval;
+
+	/* Capabilities */
+	pBeaconStruct->capabilityInfo.ess = pBeacon->Capabilities.ess;
+	pBeaconStruct->capabilityInfo.ibss = pBeacon->Capabilities.ibss;
+	pBeaconStruct->capabilityInfo.cfPollable =
+		pBeacon->Capabilities.cfPollable;
+	pBeaconStruct->capabilityInfo.cfPollReq =
+		pBeacon->Capabilities.cfPollReq;
+	pBeaconStruct->capabilityInfo.privacy = pBeacon->Capabilities.privacy;
+	pBeaconStruct->capabilityInfo.shortPreamble =
+		pBeacon->Capabilities.shortPreamble;
+	pBeaconStruct->capabilityInfo.pbcc = pBeacon->Capabilities.pbcc;
+	pBeaconStruct->capabilityInfo.channelAgility =
+		pBeacon->Capabilities.channelAgility;
+	pBeaconStruct->capabilityInfo.spectrumMgt =
+		pBeacon->Capabilities.spectrumMgt;
+	pBeaconStruct->capabilityInfo.qos = pBeacon->Capabilities.qos;
+	pBeaconStruct->capabilityInfo.shortSlotTime =
+		pBeacon->Capabilities.shortSlotTime;
+	pBeaconStruct->capabilityInfo.apsd = pBeacon->Capabilities.apsd;
+	pBeaconStruct->capabilityInfo.rrm = pBeacon->Capabilities.rrm;
+	pBeaconStruct->capabilityInfo.dsssOfdm = pBeacon->Capabilities.dsssOfdm;
+	pBeaconStruct->capabilityInfo.delayedBA =
+		pBeacon->Capabilities.delayedBA;
+	pBeaconStruct->capabilityInfo.immediateBA =
+		pBeacon->Capabilities.immediateBA;
+
+	if (!pBeacon->SSID.present) {
+		pe_debug("Mandatory IE SSID not present!");
+	} else {
+		pBeaconStruct->ssidPresent = 1;
+		convert_ssid(pMac, &pBeaconStruct->ssId, &pBeacon->SSID);
+	}
+
+	if (!pBeacon->SuppRates.present) {
+		pe_debug_rl("Mandatory IE Supported Rates not present!");
+	} else {
+		pBeaconStruct->suppRatesPresent = 1;
+		convert_supp_rates(pMac, &pBeaconStruct->supportedRates,
+				   &pBeacon->SuppRates);
+	}
+
+	if (pBeacon->ExtSuppRates.present) {
+		pBeaconStruct->extendedRatesPresent = 1;
+		convert_ext_supp_rates(pMac, &pBeaconStruct->extendedRates,
+				       &pBeacon->ExtSuppRates);
+	}
+
+	if (pBeacon->CFParams.present) {
+		pBeaconStruct->cfPresent = 1;
+		convert_cf_params(pMac, &pBeaconStruct->cfParamSet,
+				  &pBeacon->CFParams);
+	}
+
+	if (pBeacon->TIM.present) {
+		pBeaconStruct->timPresent = 1;
+		convert_tim(pMac, &pBeaconStruct->tim, &pBeacon->TIM);
+	}
+
+	if (pBeacon->Country.present) {
+		pBeaconStruct->countryInfoPresent = 1;
+		convert_country(pMac, &pBeaconStruct->countryInfoParam,
+				&pBeacon->Country);
+	}
+	/* QOS Capabilities: */
+	if (pBeacon->QOSCapsAp.present) {
+		pBeaconStruct->qosCapabilityPresent = 1;
+		convert_qos_caps(pMac, &pBeaconStruct->qosCapability,
+				 &pBeacon->QOSCapsAp);
+	}
+
+	if (pBeacon->EDCAParamSet.present) {
+		pBeaconStruct->edcaPresent = 1;
+		convert_edca_param(pMac, &pBeaconStruct->edcaParams,
+				   &pBeacon->EDCAParamSet);
+	}
+
+	if (pBeacon->ChanSwitchAnn.present) {
+		pBeaconStruct->channelSwitchPresent = 1;
+		qdf_mem_copy(&pBeaconStruct->channelSwitchIE,
+			     &pBeacon->ChanSwitchAnn,
+			     sizeof(pBeaconStruct->channelSwitchIE));
+	}
+
+	if (pBeacon->ext_chan_switch_ann.present) {
+		pBeaconStruct->ext_chan_switch_present = 1;
+		qdf_mem_copy(&pBeaconStruct->ext_chan_switch,
+			     &pBeacon->ext_chan_switch_ann,
+			     sizeof(tDot11fIEext_chan_switch_ann));
+	}
+
+	if (pBeacon->sec_chan_offset_ele.present) {
+		pBeaconStruct->sec_chan_offset_present = 1;
+		qdf_mem_copy(&pBeaconStruct->sec_chan_offset,
+			     &pBeacon->sec_chan_offset_ele,
+			     sizeof(pBeaconStruct->sec_chan_offset));
+	}
+
+	if (pBeacon->TPCReport.present) {
+		pBeaconStruct->tpcReportPresent = 1;
+		qdf_mem_copy(&pBeaconStruct->tpcReport, &pBeacon->TPCReport,
+			     sizeof(tDot11fIETPCReport));
+	}
+
+	if (pBeacon->PowerConstraints.present) {
+		pBeaconStruct->powerConstraintPresent = 1;
+		qdf_mem_copy(&pBeaconStruct->localPowerConstraint,
+			     &pBeacon->PowerConstraints,
+			     sizeof(tDot11fIEPowerConstraints));
+	}
+
+	if (pBeacon->Quiet.present) {
+		pBeaconStruct->quietIEPresent = 1;
+		qdf_mem_copy(&pBeaconStruct->quietIE, &pBeacon->Quiet,
+			     sizeof(tDot11fIEQuiet));
+	}
+
+	if (pBeacon->HTCaps.present) {
+		qdf_mem_copy(&pBeaconStruct->HTCaps, &pBeacon->HTCaps,
+			     sizeof(tDot11fIEHTCaps));
+	}
+
+	if (pBeacon->HTInfo.present) {
+		qdf_mem_copy(&pBeaconStruct->HTInfo, &pBeacon->HTInfo,
+			     sizeof(tDot11fIEHTInfo));
+
+	}
+
+	if (pBeacon->DSParams.present) {
+		pBeaconStruct->dsParamsPresent = 1;
+		pBeaconStruct->channelNumber = pBeacon->DSParams.curr_channel;
+	} else if (pBeacon->HTInfo.present) {
+		pBeaconStruct->channelNumber = pBeacon->HTInfo.primaryChannel;
+	} else {
+		pBeaconStruct->channelNumber = mappedRXCh;
+		pe_debug_rl("In Beacon No Channel info");
+	}
+
+	if (pBeacon->RSN.present) {
+		pBeaconStruct->rsnPresent = 1;
+		convert_rsn(pMac, &pBeaconStruct->rsn, &pBeacon->RSN);
+	}
+
+	if (pBeacon->WPA.present) {
+		pBeaconStruct->wpaPresent = 1;
+		convert_wpa(pMac, &pBeaconStruct->wpa, &pBeacon->WPA);
+	}
+
+	if (pBeacon->WMMParams.present) {
+		pBeaconStruct->wmeEdcaPresent = 1;
+		convert_wmm_params(pMac, &pBeaconStruct->edcaParams,
+				   &pBeacon->WMMParams);
+	}
+
+	if (pBeacon->WMMInfoAp.present) {
+		pBeaconStruct->wmeInfoPresent = 1;
+		pe_debug("WMM Info present in Beacon Frame!");
+	}
+
+	if (pBeacon->WMMCaps.present) {
+		pBeaconStruct->wsmCapablePresent = 1;
+	}
+
+	if (pBeacon->ERPInfo.present) {
+		pBeaconStruct->erpPresent = 1;
+		convert_erp_info(pMac, &pBeaconStruct->erpIEInfo,
+				 &pBeacon->ERPInfo);
+	}
+	if (pBeacon->MobilityDomain.present) {
+		/* MobilityDomain */
+		pBeaconStruct->mdiePresent = 1;
+		qdf_mem_copy((uint8_t *) &(pBeaconStruct->mdie[0]),
+			     (uint8_t *) &(pBeacon->MobilityDomain.MDID),
+			     sizeof(uint16_t));
+		pBeaconStruct->mdie[2] =
+			((pBeacon->MobilityDomain.overDSCap << 0) | (pBeacon->
+								     MobilityDomain.
+								     resourceReqCap
+								     << 1));
+
+	}
+
+#ifdef FEATURE_WLAN_ESE
+	if (pBeacon->ESEVersion.present)
+		pBeaconStruct->is_ese_ver_ie_present = 1;
+	if (pBeacon->ESETxmitPower.present) {
+		/* copy ESE TPC info element */
+		pBeaconStruct->eseTxPwr.present = 1;
+		qdf_mem_copy(&pBeaconStruct->eseTxPwr,
+			     &pBeacon->ESETxmitPower,
+			     sizeof(tDot11fIEESETxmitPower));
+	}
+	if (pBeacon->QBSSLoad.present) {
+		qdf_mem_copy(&pBeaconStruct->QBSSLoad,
+			     &pBeacon->QBSSLoad, sizeof(tDot11fIEQBSSLoad));
+	}
+#endif
+	if (pBeacon->VHTCaps.present) {
+		qdf_mem_copy(&pBeaconStruct->VHTCaps, &pBeacon->VHTCaps,
+			     sizeof(tDot11fIEVHTCaps));
+	}
+	if (pBeacon->VHTOperation.present) {
+		qdf_mem_copy(&pBeaconStruct->VHTOperation,
+			     &pBeacon->VHTOperation,
+			     sizeof(tDot11fIEVHTOperation));
+	}
+	if (pBeacon->VHTExtBssLoad.present) {
+		qdf_mem_copy(&pBeaconStruct->VHTExtBssLoad,
+			     &pBeacon->VHTExtBssLoad,
+			     sizeof(tDot11fIEVHTExtBssLoad));
+	}
+	if (pBeacon->OperatingMode.present) {
+		qdf_mem_copy(&pBeaconStruct->OperatingMode,
+			     &pBeacon->OperatingMode,
+			     sizeof(tDot11fIEOperatingMode));
+	}
+	if (pBeacon->WiderBWChanSwitchAnn.present) {
+		pBeaconStruct->WiderBWChanSwitchAnnPresent = 1;
+		qdf_mem_copy(&pBeaconStruct->WiderBWChanSwitchAnn,
+			     &pBeacon->WiderBWChanSwitchAnn,
+			     sizeof(tDot11fIEWiderBWChanSwitchAnn));
+	}
+	/* IBSS Peer Params */
+	if (pBeacon->IBSSParams.present) {
+		pBeaconStruct->IBSSParams.present = 1;
+		qdf_mem_copy(&pBeaconStruct->IBSSParams, &pBeacon->IBSSParams,
+			     sizeof(tDot11fIEIBSSParams));
+	}
+
+	pBeaconStruct->Vendor1IEPresent = pBeacon->Vendor1IE.present;
+	pBeaconStruct->Vendor3IEPresent = pBeacon->Vendor3IE.present;
+
+	pBeaconStruct->vendor_vht_ie.present = pBeacon->vendor_vht_ie.present;
+	if (pBeacon->vendor_vht_ie.present) {
+		pBeaconStruct->vendor_vht_ie.sub_type =
+			pBeacon->vendor_vht_ie.sub_type;
+	}
+
+	if (pBeacon->vendor_vht_ie.VHTCaps.present) {
+		qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTCaps,
+				&pBeacon->vendor_vht_ie.VHTCaps,
+				sizeof(tDot11fIEVHTCaps));
+	}
+	if (pBeacon->vendor_vht_ie.VHTOperation.present) {
+		qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTOperation,
+				&pBeacon->VHTOperation,
+				sizeof(tDot11fIEVHTOperation));
+	}
+	/* Update HS 2.0 Information Element */
+	if (pBeacon->hs20vendor_ie.present) {
+		qdf_mem_copy(&pBeaconStruct->hs20vendor_ie,
+			&pBeacon->hs20vendor_ie,
+			sizeof(tDot11fIEhs20vendor_ie) -
+			sizeof(pBeacon->hs20vendor_ie.hs_id));
+		if (pBeacon->hs20vendor_ie.hs_id_present)
+			qdf_mem_copy(&pBeaconStruct->hs20vendor_ie.hs_id,
+				&pBeacon->hs20vendor_ie.hs_id,
+				sizeof(pBeacon->hs20vendor_ie.hs_id));
+	}
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	if (pBeacon->QComVendorIE.present) {
+		pBeaconStruct->AvoidChannelIE.present =
+			pBeacon->QComVendorIE.present;
+		pBeaconStruct->AvoidChannelIE.type =
+			pBeacon->QComVendorIE.type;
+		pBeaconStruct->AvoidChannelIE.channel =
+			pBeacon->QComVendorIE.channel;
+	}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+	if (pBeacon->OBSSScanParameters.present) {
+		qdf_mem_copy(&pBeaconStruct->obss_scanparams,
+			&pBeacon->OBSSScanParameters,
+			sizeof(struct sDot11fIEOBSSScanParameters));
+	}
+	if (pBeacon->MBO_IE.present) {
+		pBeaconStruct->MBO_IE_present = true;
+		if (pBeacon->MBO_IE.cellular_data_cap.present)
+			pBeaconStruct->MBO_capability =
+				pBeacon->MBO_IE.cellular_data_cap.cellular_connectivity;
+
+		if (pBeacon->MBO_IE.assoc_disallowed.present) {
+			pBeaconStruct->assoc_disallowed = true;
+			pBeaconStruct->assoc_disallowed_reason =
+				pBeacon->MBO_IE.assoc_disallowed.reason_code;
+		}
+	}
+
+	if (pBeacon->QCN_IE.present) {
+		pBeaconStruct->QCN_IE.is_present = true;
+		if (pBeacon->QCN_IE.version[0]
+					== QCN_IE_VERSION_SUBATTR_ID) {
+			pBeaconStruct->QCN_IE.version
+					= pBeacon->QCN_IE.version[2];
+			pBeaconStruct->QCN_IE.sub_version
+					= pBeacon->QCN_IE.version[3];
+		}
+	}
+
+	if (pBeacon->he_cap.present) {
+		pe_debug("11AX: HE cap IE present");
+		qdf_mem_copy(&pBeaconStruct->he_cap,
+			     &pBeacon->he_cap,
+			     sizeof(tDot11fIEhe_cap));
+	}
+	if (pBeacon->he_op.present) {
+		pe_debug("11AX: HE operation IE present");
+		qdf_mem_copy(&pBeaconStruct->he_op,
+			     &pBeacon->he_op,
+			     sizeof(tDot11fIEhe_op));
+	}
+
+	convert_bcon_bss_color_change_ie(pBeacon, pBeaconStruct);
+
+	qdf_mem_free(pBeacon);
+	return QDF_STATUS_SUCCESS;
+
+} /* End sir_convert_beacon_frame2_struct. */
+
+#ifdef WLAN_FEATURE_FILS_SK
+/* sir_update_auth_frame2_struct_fils_conf: API to update fils info from auth
+ * packet type 2
+ * @auth: auth packet pointer received from AP
+ * @auth_frame: data structure needs to be updated
+ *
+ * Return: None
+ */
+static void sir_update_auth_frame2_struct_fils_conf(tDot11fAuthentication *auth,
+				tpSirMacAuthFrameBody auth_frame)
+{
+	if (auth->AuthAlgo.algo != SIR_FILS_SK_WITHOUT_PFS)
+		return;
+
+	if (auth->fils_assoc_delay_info.present)
+		auth_frame->assoc_delay_info =
+			auth->fils_assoc_delay_info.assoc_delay_info;
+
+	if (auth->fils_session.present)
+		qdf_mem_copy(auth_frame->session, auth->fils_session.session,
+			SIR_FILS_SESSION_LENGTH);
+
+	if (auth->fils_nonce.present)
+		qdf_mem_copy(auth_frame->nonce, auth->fils_nonce.nonce,
+			SIR_FILS_NONCE_LENGTH);
+
+	if (auth->fils_wrapped_data.present) {
+		qdf_mem_copy(auth_frame->wrapped_data,
+			auth->fils_wrapped_data.wrapped_data,
+			auth->fils_wrapped_data.num_wrapped_data);
+		auth_frame->wrapped_data_len =
+			auth->fils_wrapped_data.num_wrapped_data;
+	}
+	if (auth->RSNOpaque.present) {
+		qdf_mem_copy(auth_frame->rsn_ie.info, auth->RSNOpaque.data,
+			auth->RSNOpaque.num_data);
+		auth_frame->rsn_ie.length = auth->RSNOpaque.num_data;
+	}
+}
+#else
+static void sir_update_auth_frame2_struct_fils_conf(tDot11fAuthentication *auth,
+				tpSirMacAuthFrameBody auth_frame)
+{ }
+#endif
+
+QDF_STATUS
+sir_convert_auth_frame2_struct(tpAniSirGlobal pMac,
+			       uint8_t *pFrame,
+			       uint32_t nFrame, tpSirMacAuthFrameBody pAuth)
+{
+	static tDot11fAuthentication auth;
+	uint32_t status;
+
+	/* Zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) pAuth, sizeof(tSirMacAuthFrameBody), 0);
+
+	/* delegate to the framesc-generated code, */
+	status = dot11f_unpack_authentication(pMac, pFrame, nFrame,
+					      &auth, false);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse an Authentication frame (0x%08x, %d bytes):",
+			status, nFrame);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pFrame, nFrame);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking an Authentication frame (0x%08x, %d bytes):",
+			status, nFrame);
+	}
+	/* & "transliterate" from a 'tDot11fAuthentication' to a 'tSirMacAuthFrameBody'... */
+	pAuth->authAlgoNumber = auth.AuthAlgo.algo;
+	pAuth->authTransactionSeqNumber = auth.AuthSeqNo.no;
+	pAuth->authStatusCode = auth.Status.status;
+
+	if (auth.ChallengeText.present) {
+		pAuth->type = SIR_MAC_CHALLENGE_TEXT_EID;
+		pAuth->length = auth.ChallengeText.num_text;
+		qdf_mem_copy(pAuth->challengeText, auth.ChallengeText.text,
+			     auth.ChallengeText.num_text);
+	}
+	sir_update_auth_frame2_struct_fils_conf(&auth, pAuth);
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End sir_convert_auth_frame2_struct. */
+
+QDF_STATUS
+sir_convert_addts_req2_struct(tpAniSirGlobal pMac,
+			      uint8_t *pFrame,
+			      uint32_t nFrame, tSirAddtsReqInfo *pAddTs)
+{
+	tDot11fAddTSRequest addts = { {0} };
+	tDot11fWMMAddTSRequest wmmaddts = { {0} };
+	uint8_t j;
+	uint16_t i;
+	uint32_t status;
+
+	if (SIR_MAC_QOS_ADD_TS_REQ != *(pFrame + 1)) {
+		pe_err("Action of %d; this is not supported & is probably an error",
+			*(pFrame + 1));
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) pAddTs, sizeof(tSirAddtsReqInfo), 0);
+
+	/* delegate to the framesc-generated code, */
+	switch (*pFrame) {
+	case SIR_MAC_ACTION_QOS_MGMT:
+		status = dot11f_unpack_add_ts_request(pMac, pFrame, nFrame,
+						      &addts, false);
+		break;
+	case SIR_MAC_ACTION_WME:
+		status =
+			dot11f_unpack_wmm_add_ts_request(pMac, pFrame, nFrame,
+							 &wmmaddts, false);
+		break;
+	default:
+		pe_err("Category of %d; this is not supported & is probably an error",
+			*pFrame);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse an Add TS Request frame (0x%08x, %d bytes):",
+			status, nFrame);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pFrame, nFrame);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking an Add TS Request frame (0x%08x,%d bytes):",
+			status, nFrame);
+	}
+	/* & "transliterate" from a 'tDot11fAddTSRequest' or a */
+	/* 'tDot11WMMAddTSRequest' to a 'tSirMacAddtsReqInfo'... */
+	if (SIR_MAC_ACTION_QOS_MGMT == *pFrame) {
+		pAddTs->dialogToken = addts.DialogToken.token;
+
+		if (addts.TSPEC.present) {
+			convert_tspec(pMac, &pAddTs->tspec, &addts.TSPEC);
+		} else {
+			pe_err("Mandatory TSPEC element missing in Add TS Request");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (addts.num_TCLAS) {
+			pAddTs->numTclas = (uint8_t) addts.num_TCLAS;
+
+			for (i = 0U; i < addts.num_TCLAS; ++i) {
+				if (QDF_STATUS_SUCCESS !=
+				    convert_tclas(pMac, &(pAddTs->tclasInfo[i]),
+						  &(addts.TCLAS[i]))) {
+					pe_err("Failed to convert a TCLAS IE");
+					return QDF_STATUS_E_FAILURE;
+				}
+			}
+		}
+
+		if (addts.TCLASSPROC.present) {
+			pAddTs->tclasProcPresent = 1;
+			pAddTs->tclasProc = addts.TCLASSPROC.processing;
+		}
+
+		if (addts.WMMTSPEC.present) {
+			pAddTs->wsmTspecPresent = 1;
+			convert_wmmtspec(pMac, &pAddTs->tspec, &addts.WMMTSPEC);
+		}
+
+		if (addts.num_WMMTCLAS) {
+			j = (uint8_t) (pAddTs->numTclas + addts.num_WMMTCLAS);
+			if (SIR_MAC_TCLASIE_MAXNUM < j)
+				j = SIR_MAC_TCLASIE_MAXNUM;
+
+			for (i = pAddTs->numTclas; i < j; ++i) {
+				if (QDF_STATUS_SUCCESS !=
+				    convert_wmmtclas(pMac,
+						     &(pAddTs->tclasInfo[i]),
+						     &(addts.WMMTCLAS[i]))) {
+					pe_err("Failed to convert a TCLAS IE");
+					return QDF_STATUS_E_FAILURE;
+				}
+			}
+		}
+
+		if (addts.WMMTCLASPROC.present) {
+			pAddTs->tclasProcPresent = 1;
+			pAddTs->tclasProc = addts.WMMTCLASPROC.processing;
+		}
+
+		if (1 < pAddTs->numTclas && (!pAddTs->tclasProcPresent)) {
+			pe_err("%d TCLAS IE but not TCLASPROC IE",
+				pAddTs->numTclas);
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		pAddTs->dialogToken = wmmaddts.DialogToken.token;
+
+		if (wmmaddts.WMMTSPEC.present) {
+			pAddTs->wmeTspecPresent = 1;
+			convert_wmmtspec(pMac, &pAddTs->tspec,
+					 &wmmaddts.WMMTSPEC);
+		} else {
+			pe_err("Mandatory WME TSPEC element missing!");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End sir_convert_addts_req2_struct. */
+
+QDF_STATUS
+sir_convert_addts_rsp2_struct(tpAniSirGlobal pMac,
+			      uint8_t *pFrame,
+			      uint32_t nFrame, tSirAddtsRspInfo *pAddTs)
+{
+	tDot11fAddTSResponse addts = { {0} };
+	tDot11fWMMAddTSResponse wmmaddts = { {0} };
+	uint8_t j;
+	uint16_t i;
+	uint32_t status;
+
+	if (SIR_MAC_QOS_ADD_TS_RSP != *(pFrame + 1)) {
+		pe_err("Action of %d; this is not supported & is probably an error",
+			*(pFrame + 1));
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) pAddTs, sizeof(tSirAddtsRspInfo), 0);
+	qdf_mem_set((uint8_t *) &addts, sizeof(tDot11fAddTSResponse), 0);
+	qdf_mem_set((uint8_t *) &wmmaddts, sizeof(tDot11fWMMAddTSResponse), 0);
+
+	/* delegate to the framesc-generated code, */
+	switch (*pFrame) {
+	case SIR_MAC_ACTION_QOS_MGMT:
+		status =
+			dot11f_unpack_add_ts_response(pMac, pFrame, nFrame,
+						      &addts, false);
+		break;
+	case SIR_MAC_ACTION_WME:
+		status =
+			dot11f_unpack_wmm_add_ts_response(pMac, pFrame, nFrame,
+							  &wmmaddts, false);
+		break;
+	default:
+		pe_err("Category of %d; this is not supported & is probably an error",
+			*pFrame);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse an Add TS Response frame (0x%08x, %d bytes):",
+			status, nFrame);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pFrame, nFrame);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking an Add TS Response frame (0x%08x,%d bytes):",
+			status, nFrame);
+	}
+	/* & "transliterate" from a 'tDot11fAddTSResponse' or a */
+	/* 'tDot11WMMAddTSResponse' to a 'tSirMacAddtsRspInfo'... */
+	if (SIR_MAC_ACTION_QOS_MGMT == *pFrame) {
+		pAddTs->dialogToken = addts.DialogToken.token;
+		pAddTs->status = (tSirMacStatusCodes) addts.Status.status;
+
+		if (addts.TSDelay.present) {
+			convert_ts_delay(pMac, &pAddTs->delay, &addts.TSDelay);
+		}
+		/* TS Delay is present iff status indicates its presence */
+		if (eSIR_MAC_TS_NOT_CREATED_STATUS == pAddTs->status
+		    && !addts.TSDelay.present) {
+			pe_warn("Missing TSDelay IE");
+		}
+
+		if (addts.TSPEC.present) {
+			convert_tspec(pMac, &pAddTs->tspec, &addts.TSPEC);
+		} else {
+			pe_err("Mandatory TSPEC element missing in Add TS Response");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (addts.num_TCLAS) {
+			pAddTs->numTclas = (uint8_t) addts.num_TCLAS;
+
+			for (i = 0U; i < addts.num_TCLAS; ++i) {
+				if (QDF_STATUS_SUCCESS !=
+				    convert_tclas(pMac, &(pAddTs->tclasInfo[i]),
+						  &(addts.TCLAS[i]))) {
+					pe_err("Failed to convert a TCLAS IE");
+					return QDF_STATUS_E_FAILURE;
+				}
+			}
+		}
+
+		if (addts.TCLASSPROC.present) {
+			pAddTs->tclasProcPresent = 1;
+			pAddTs->tclasProc = addts.TCLASSPROC.processing;
+		}
+#ifdef FEATURE_WLAN_ESE
+		if (addts.ESETrafStrmMet.present) {
+			pAddTs->tsmPresent = 1;
+			qdf_mem_copy(&pAddTs->tsmIE.tsid,
+				     &addts.ESETrafStrmMet.tsid,
+				     sizeof(tSirMacESETSMIE));
+		}
+#endif
+		if (addts.Schedule.present) {
+			pAddTs->schedulePresent = 1;
+			convert_schedule(pMac, &pAddTs->schedule,
+					 &addts.Schedule);
+		}
+
+		if (addts.WMMSchedule.present) {
+			pAddTs->schedulePresent = 1;
+			convert_wmm_schedule(pMac, &pAddTs->schedule,
+					     &addts.WMMSchedule);
+		}
+
+		if (addts.WMMTSPEC.present) {
+			pAddTs->wsmTspecPresent = 1;
+			convert_wmmtspec(pMac, &pAddTs->tspec, &addts.WMMTSPEC);
+		}
+
+		if (addts.num_WMMTCLAS) {
+			j = (uint8_t) (pAddTs->numTclas + addts.num_WMMTCLAS);
+			if (SIR_MAC_TCLASIE_MAXNUM < j)
+				j = SIR_MAC_TCLASIE_MAXNUM;
+
+			for (i = pAddTs->numTclas; i < j; ++i) {
+				if (QDF_STATUS_SUCCESS !=
+				    convert_wmmtclas(pMac,
+						     &(pAddTs->tclasInfo[i]),
+						     &(addts.WMMTCLAS[i]))) {
+					pe_err("Failed to convert a TCLAS IE");
+					return QDF_STATUS_E_FAILURE;
+				}
+			}
+		}
+
+		if (addts.WMMTCLASPROC.present) {
+			pAddTs->tclasProcPresent = 1;
+			pAddTs->tclasProc = addts.WMMTCLASPROC.processing;
+		}
+
+		if (1 < pAddTs->numTclas && (!pAddTs->tclasProcPresent)) {
+			pe_err("%d TCLAS IE but not TCLASPROC IE",
+				pAddTs->numTclas);
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		pAddTs->dialogToken = wmmaddts.DialogToken.token;
+		pAddTs->status =
+			(tSirMacStatusCodes) wmmaddts.StatusCode.statusCode;
+
+		if (wmmaddts.WMMTSPEC.present) {
+			pAddTs->wmeTspecPresent = 1;
+			convert_wmmtspec(pMac, &pAddTs->tspec,
+					 &wmmaddts.WMMTSPEC);
+		} else {
+			pe_err("Mandatory WME TSPEC element missing!");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+#ifdef FEATURE_WLAN_ESE
+		if (wmmaddts.ESETrafStrmMet.present) {
+			pAddTs->tsmPresent = 1;
+			qdf_mem_copy(&pAddTs->tsmIE.tsid,
+				     &wmmaddts.ESETrafStrmMet.tsid,
+				     sizeof(tSirMacESETSMIE));
+		}
+#endif
+
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End sir_convert_addts_rsp2_struct. */
+
+QDF_STATUS
+sir_convert_delts_req2_struct(tpAniSirGlobal pMac,
+			      uint8_t *pFrame,
+			      uint32_t nFrame, tSirDeltsReqInfo *pDelTs)
+{
+	tDot11fDelTS delts = { {0} };
+	tDot11fWMMDelTS wmmdelts = { {0} };
+	uint32_t status;
+
+	if (SIR_MAC_QOS_DEL_TS_REQ != *(pFrame + 1)) {
+		pe_err("sirConvertDeltsRsp2Struct invoked "
+			"with an Action of %d; this is not "
+			"supported & is probably an error",
+			*(pFrame + 1));
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) pDelTs, sizeof(tSirDeltsReqInfo), 0);
+
+	/* delegate to the framesc-generated code, */
+	switch (*pFrame) {
+	case SIR_MAC_ACTION_QOS_MGMT:
+		status = dot11f_unpack_del_ts(pMac, pFrame, nFrame,
+					      &delts, false);
+		break;
+	case SIR_MAC_ACTION_WME:
+		status = dot11f_unpack_wmm_del_ts(pMac, pFrame, nFrame,
+						  &wmmdelts, false);
+		break;
+	default:
+		pe_err("sirConvertDeltsRsp2Struct invoked "
+		       "with a Category of %d; this is not"
+		       " supported & is probably an error",
+			*pFrame);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse an Del TS Request frame (0x%08x, %d bytes):",
+			status, nFrame);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pFrame, nFrame);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking an Del TS Request frame (0x%08x,%d bytes):",
+			   status, nFrame);
+	}
+	/* & "transliterate" from a 'tDot11fDelTSResponse' or a */
+	/* 'tDot11WMMDelTSResponse' to a 'tSirMacDeltsReqInfo'... */
+	if (SIR_MAC_ACTION_QOS_MGMT == *pFrame) {
+		pDelTs->tsinfo.traffic.trafficType =
+			(uint16_t) delts.TSInfo.traffic_type;
+		pDelTs->tsinfo.traffic.tsid = (uint16_t) delts.TSInfo.tsid;
+		pDelTs->tsinfo.traffic.direction =
+			(uint16_t) delts.TSInfo.direction;
+		pDelTs->tsinfo.traffic.accessPolicy =
+			(uint16_t) delts.TSInfo.access_policy;
+		pDelTs->tsinfo.traffic.aggregation =
+			(uint16_t) delts.TSInfo.aggregation;
+		pDelTs->tsinfo.traffic.psb = (uint16_t) delts.TSInfo.psb;
+		pDelTs->tsinfo.traffic.userPrio =
+			(uint16_t) delts.TSInfo.user_priority;
+		pDelTs->tsinfo.traffic.ackPolicy =
+			(uint16_t) delts.TSInfo.tsinfo_ack_pol;
+
+		pDelTs->tsinfo.schedule.schedule =
+			(uint8_t) delts.TSInfo.schedule;
+	} else {
+		if (wmmdelts.WMMTSPEC.present) {
+			pDelTs->wmeTspecPresent = 1;
+			convert_wmmtspec(pMac, &pDelTs->tspec,
+					 &wmmdelts.WMMTSPEC);
+		} else {
+			pe_err("Mandatory WME TSPEC element missing!");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End sir_convert_delts_req2_struct. */
+
+QDF_STATUS
+sir_convert_qos_map_configure_frame2_struct(tpAniSirGlobal pMac,
+					    uint8_t *pFrame,
+					    uint32_t nFrame,
+					    tSirQosMapSet *pQosMapSet)
+{
+	tDot11fQosMapConfigure mapConfigure;
+	uint32_t status;
+
+	status =
+		dot11f_unpack_qos_map_configure(pMac, pFrame, nFrame,
+						&mapConfigure, false);
+	if (DOT11F_FAILED(status) || !mapConfigure.QosMapSet.present) {
+		pe_err("Failed to parse Qos Map Configure frame (0x%08x, %d bytes):",
+			   status, nFrame);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pFrame, nFrame);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking Qos Map Configure frame (0x%08x, %d bytes):",
+			   status, nFrame);
+	}
+	pQosMapSet->present = mapConfigure.QosMapSet.present;
+	convert_qos_mapset_frame(pMac, pQosMapSet, &mapConfigure.QosMapSet);
+	lim_log_qos_map_set(pMac, pQosMapSet);
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef ANI_SUPPORT_11H
+QDF_STATUS
+sir_convert_tpc_req_frame2_struct(tpAniSirGlobal pMac,
+				  uint8_t *pFrame,
+				  tpSirMacTpcReqActionFrame pTpcReqFrame,
+				  uint32_t nFrame)
+{
+	tDot11fTPCRequest req;
+	uint32_t status;
+
+	qdf_mem_set((uint8_t *) pTpcReqFrame, sizeof(tSirMacTpcReqActionFrame),
+		    0);
+	status = dot11f_unpack_tpc_request(pMac, pFrame, nFrame, &req, false);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse a TPC Request frame (0x%08x, %d bytes):",
+			   status, nFrame);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pFrame, nFrame);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking a TPC Request frame (0x%08x, %d bytes):",
+			   status, nFrame);
+	}
+	/* & "transliterate" from a 'tDot11fTPCRequest' to a */
+	/* 'tSirMacTpcReqActionFrame'... */
+	pTpcReqFrame->actionHeader.category = req.Category.category;
+	pTpcReqFrame->actionHeader.actionID = req.Action.action;
+	pTpcReqFrame->actionHeader.dialogToken = req.DialogToken.token;
+	if (req.TPCRequest.present) {
+		pTpcReqFrame->type = DOT11F_EID_TPCREQUEST;
+		pTpcReqFrame->length = 0;
+	} else {
+		pe_warn("!!!Rcv TPC Req of inalid type!");
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+} /* End sir_convert_tpc_req_frame2_struct. */
+QDF_STATUS
+sir_convert_meas_req_frame2_struct(tpAniSirGlobal pMac,
+				   uint8_t *pFrame,
+				   tpSirMacMeasReqActionFrame pMeasReqFrame,
+				   uint32_t nFrame)
+{
+	tDot11fMeasurementRequest mr;
+	uint32_t status;
+
+	/* Zero-init our [out] parameter, */
+	qdf_mem_set((uint8_t *) pMeasReqFrame,
+		    sizeof(tpSirMacMeasReqActionFrame), 0);
+
+	/* delegate to the framesc-generated code, */
+	status = dot11f_unpack_measurement_request(pMac, pFrame,
+						   nFrame, &mr, false);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to parse a Measurement Request frame (0x%08x, %d bytes):",
+			   status, nFrame);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+				   pFrame, nFrame);
+		return QDF_STATUS_E_FAILURE;
+	} else if (DOT11F_WARNED(status)) {
+		pe_debug("There were warnings while unpacking a Measurement Request frame (0x%08x, %d bytes):",
+			   status, nFrame);
+	}
+	/* & "transliterate" from a 'tDot11fMeasurementRequest' to a */
+	/* 'tpSirMacMeasReqActionFrame'... */
+	pMeasReqFrame->actionHeader.category = mr.Category.category;
+	pMeasReqFrame->actionHeader.actionID = mr.Action.action;
+	pMeasReqFrame->actionHeader.dialogToken = mr.DialogToken.token;
+
+	if (0 == mr.num_MeasurementRequest) {
+		pe_err("Missing mandatory IE in Measurement Request Frame");
+		return QDF_STATUS_E_FAILURE;
+	} else if (1 < mr.num_MeasurementRequest) {
+		pe_warn(
+			FL("Warning: dropping extra Measurement Request IEs!"));
+	}
+
+	pMeasReqFrame->measReqIE.type = DOT11F_EID_MEASUREMENTREQUEST;
+	pMeasReqFrame->measReqIE.length = DOT11F_IE_MEASUREMENTREQUEST_MIN_LEN;
+	pMeasReqFrame->measReqIE.measToken =
+		mr.MeasurementRequest[0].measurement_token;
+	pMeasReqFrame->measReqIE.measReqMode =
+		(mr.MeasurementRequest[0].reserved << 3) | (mr.
+							    MeasurementRequest[0].
+							    enable << 2) | (mr.
+									    MeasurementRequest
+									    [0].
+									    request
+									    << 1) |
+		(mr.MeasurementRequest[0].report /*<< 0 */);
+	pMeasReqFrame->measReqIE.measType =
+		mr.MeasurementRequest[0].measurement_type;
+
+	pMeasReqFrame->measReqIE.measReqField.channelNumber =
+		mr.MeasurementRequest[0].channel_no;
+
+	qdf_mem_copy(pMeasReqFrame->measReqIE.measReqField.measStartTime,
+		     mr.MeasurementRequest[0].meas_start_time, 8);
+
+	pMeasReqFrame->measReqIE.measReqField.measDuration =
+		mr.MeasurementRequest[0].meas_duration;
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End sir_convert_meas_req_frame2_struct. */
+#endif
+
+void populate_dot11f_tspec(tSirMacTspecIE *pOld, tDot11fIETSPEC *pDot11f)
+{
+	pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType;
+	pDot11f->tsid = pOld->tsinfo.traffic.tsid;
+	pDot11f->direction = pOld->tsinfo.traffic.direction;
+	pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy;
+	pDot11f->aggregation = pOld->tsinfo.traffic.aggregation;
+	pDot11f->psb = pOld->tsinfo.traffic.psb;
+	pDot11f->user_priority = pOld->tsinfo.traffic.userPrio;
+	pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy;
+	pDot11f->schedule = pOld->tsinfo.schedule.schedule;
+	/* As defined in IEEE 802.11-2007, section 7.3.2.30
+	 * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed
+	 */
+	pDot11f->size = (pOld->nomMsduSz & 0x7fff);
+	pDot11f->fixed = (pOld->nomMsduSz & 0x8000) ? 1 : 0;
+	pDot11f->max_msdu_size = pOld->maxMsduSz;
+	pDot11f->min_service_int = pOld->minSvcInterval;
+	pDot11f->max_service_int = pOld->maxSvcInterval;
+	pDot11f->inactivity_int = pOld->inactInterval;
+	pDot11f->suspension_int = pOld->suspendInterval;
+	pDot11f->service_start_time = pOld->svcStartTime;
+	pDot11f->min_data_rate = pOld->minDataRate;
+	pDot11f->mean_data_rate = pOld->meanDataRate;
+	pDot11f->peak_data_rate = pOld->peakDataRate;
+	pDot11f->burst_size = pOld->maxBurstSz;
+	pDot11f->delay_bound = pOld->delayBound;
+	pDot11f->min_phy_rate = pOld->minPhyRate;
+	pDot11f->surplus_bw_allowance = pOld->surplusBw;
+	pDot11f->medium_time = pOld->mediumTime;
+
+	pDot11f->present = 1;
+
+} /* End populate_dot11f_tspec. */
+
+void populate_dot11f_wmmtspec(tSirMacTspecIE *pOld, tDot11fIEWMMTSPEC *pDot11f)
+{
+	pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType;
+	pDot11f->tsid = pOld->tsinfo.traffic.tsid;
+	pDot11f->direction = pOld->tsinfo.traffic.direction;
+	pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy;
+	pDot11f->aggregation = pOld->tsinfo.traffic.aggregation;
+	pDot11f->psb = pOld->tsinfo.traffic.psb;
+	pDot11f->user_priority = pOld->tsinfo.traffic.userPrio;
+	pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy;
+	pDot11f->burst_size_defn = pOld->tsinfo.traffic.burstSizeDefn;
+	/* As defined in IEEE 802.11-2007, section 7.3.2.30
+	 * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed
+	 */
+	pDot11f->size = (pOld->nomMsduSz & 0x7fff);
+	pDot11f->fixed = (pOld->nomMsduSz & 0x8000) ? 1 : 0;
+	pDot11f->max_msdu_size = pOld->maxMsduSz;
+	pDot11f->min_service_int = pOld->minSvcInterval;
+	pDot11f->max_service_int = pOld->maxSvcInterval;
+	pDot11f->inactivity_int = pOld->inactInterval;
+	pDot11f->suspension_int = pOld->suspendInterval;
+	pDot11f->service_start_time = pOld->svcStartTime;
+	pDot11f->min_data_rate = pOld->minDataRate;
+	pDot11f->mean_data_rate = pOld->meanDataRate;
+	pDot11f->peak_data_rate = pOld->peakDataRate;
+	pDot11f->burst_size = pOld->maxBurstSz;
+	pDot11f->delay_bound = pOld->delayBound;
+	pDot11f->min_phy_rate = pOld->minPhyRate;
+	pDot11f->surplus_bw_allowance = pOld->surplusBw;
+	pDot11f->medium_time = pOld->mediumTime;
+
+	pDot11f->version = 1;
+	pDot11f->present = 1;
+
+} /* End populate_dot11f_wmmtspec. */
+
+#if defined(FEATURE_WLAN_ESE)
+/* Fill the ESE version currently supported */
+void populate_dot11f_ese_version(tDot11fIEESEVersion *pESEVersion)
+{
+	pESEVersion->present = 1;
+	pESEVersion->version = ESE_VERSION_SUPPORTED;
+}
+
+/* Fill the ESE ie for the station. */
+/* The State is Normal (1) */
+/* The MBSSID for station is set to 0. */
+void populate_dot11f_ese_rad_mgmt_cap(tDot11fIEESERadMgmtCap *pESERadMgmtCap)
+{
+	pESERadMgmtCap->present = 1;
+	pESERadMgmtCap->mgmt_state = RM_STATE_NORMAL;
+	pESERadMgmtCap->mbssid_mask = 0;
+	pESERadMgmtCap->reserved = 0;
+}
+
+QDF_STATUS populate_dot11f_ese_cckm_opaque(tpAniSirGlobal pMac,
+					   tpSirCCKMie pCCKMie,
+					   tDot11fIEESECckmOpaque *pDot11f)
+{
+	int idx;
+
+	if (pCCKMie->length) {
+		idx = find_ie_location(pMac, (tpSirRSNie) pCCKMie,
+						 DOT11F_EID_ESECCKMOPAQUE);
+		if (0 <= idx) {
+			pDot11f->present = 1;
+			/* Dont include OUI */
+			pDot11f->num_data = pCCKMie->cckmIEdata[idx + 1] - 4;
+			qdf_mem_copy(pDot11f->data, pCCKMie->cckmIEdata + idx + 2 + 4,  /* EID,len,OUI */
+				     pCCKMie->cckmIEdata[idx + 1] - 4); /* Skip OUI */
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+} /* End populate_dot11f_ese_cckm_opaque. */
+
+void populate_dot11_tsrsie(tpAniSirGlobal pMac,
+			   tSirMacESETSRSIE *pOld,
+			   tDot11fIEESETrafStrmRateSet *pDot11f,
+			   uint8_t rate_length)
+{
+	pDot11f->tsid = pOld->tsid;
+	qdf_mem_copy(pDot11f->tsrates, pOld->rates, rate_length);
+	pDot11f->num_tsrates = rate_length;
+	pDot11f->present = 1;
+}
+#endif
+
+QDF_STATUS
+populate_dot11f_tclas(tpAniSirGlobal pMac,
+		      tSirTclasInfo *pOld, tDot11fIETCLAS *pDot11f)
+{
+	pDot11f->user_priority = pOld->tclas.userPrio;
+	pDot11f->classifier_type = pOld->tclas.classifierType;
+	pDot11f->classifier_mask = pOld->tclas.classifierMask;
+
+	switch (pDot11f->classifier_type) {
+	case SIR_MAC_TCLASTYPE_ETHERNET:
+		qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.source,
+			     (uint8_t *) &pOld->tclasParams.eth.srcAddr, 6);
+		qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.dest,
+			     (uint8_t *) &pOld->tclasParams.eth.dstAddr, 6);
+		pDot11f->info.EthParams.type = pOld->tclasParams.eth.type;
+		break;
+	case SIR_MAC_TCLASTYPE_TCPUDPIP:
+		pDot11f->info.IpParams.version = pOld->version;
+		if (SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version) {
+			qdf_mem_copy(pDot11f->info.IpParams.params.IpV4Params.
+				     source, pOld->tclasParams.ipv4.srcIpAddr,
+				     4);
+			qdf_mem_copy(pDot11f->info.IpParams.params.IpV4Params.
+				     dest, pOld->tclasParams.ipv4.dstIpAddr, 4);
+			pDot11f->info.IpParams.params.IpV4Params.src_port =
+				pOld->tclasParams.ipv4.srcPort;
+			pDot11f->info.IpParams.params.IpV4Params.dest_port =
+				pOld->tclasParams.ipv4.dstPort;
+			pDot11f->info.IpParams.params.IpV4Params.DSCP =
+				pOld->tclasParams.ipv4.dscp;
+			pDot11f->info.IpParams.params.IpV4Params.proto =
+				pOld->tclasParams.ipv4.protocol;
+			pDot11f->info.IpParams.params.IpV4Params.reserved =
+				pOld->tclasParams.ipv4.rsvd;
+		} else {
+			qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+				     params.IpV6Params.source,
+				     (uint8_t *) pOld->tclasParams.ipv6.
+				     srcIpAddr, 16);
+			qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+				     params.IpV6Params.dest,
+				     (uint8_t *) pOld->tclasParams.ipv6.
+				     dstIpAddr, 16);
+			pDot11f->info.IpParams.params.IpV6Params.src_port =
+				pOld->tclasParams.ipv6.srcPort;
+			pDot11f->info.IpParams.params.IpV6Params.dest_port =
+				pOld->tclasParams.ipv6.dstPort;
+			qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+				     params.IpV6Params.flow_label,
+				     (uint8_t *) pOld->tclasParams.ipv6.
+				     flowLabel, 3);
+		}
+		break;
+	case SIR_MAC_TCLASTYPE_8021DQ:
+		pDot11f->info.Params8021dq.tag_type =
+			pOld->tclasParams.t8021dq.tag;
+		break;
+	default:
+		pe_err("Bad TCLAS type %d", pDot11f->classifier_type);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pDot11f->present = 1;
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End populate_dot11f_tclas. */
+
+QDF_STATUS
+populate_dot11f_wmmtclas(tpAniSirGlobal pMac,
+			 tSirTclasInfo *pOld, tDot11fIEWMMTCLAS *pDot11f)
+{
+	pDot11f->version = 1;
+	pDot11f->user_priority = pOld->tclas.userPrio;
+	pDot11f->classifier_type = pOld->tclas.classifierType;
+	pDot11f->classifier_mask = pOld->tclas.classifierMask;
+
+	switch (pDot11f->classifier_type) {
+	case SIR_MAC_TCLASTYPE_ETHERNET:
+		qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.source,
+			     (uint8_t *) &pOld->tclasParams.eth.srcAddr, 6);
+		qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.dest,
+			     (uint8_t *) &pOld->tclasParams.eth.dstAddr, 6);
+		pDot11f->info.EthParams.type = pOld->tclasParams.eth.type;
+		break;
+	case SIR_MAC_TCLASTYPE_TCPUDPIP:
+		pDot11f->info.IpParams.version = pOld->version;
+		if (SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version) {
+			qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+				     params.IpV4Params.source,
+				     (uint8_t *) pOld->tclasParams.ipv4.
+				     srcIpAddr, 4);
+			qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+				     params.IpV4Params.dest,
+				     (uint8_t *) pOld->tclasParams.ipv4.
+				     dstIpAddr, 4);
+			pDot11f->info.IpParams.params.IpV4Params.src_port =
+				pOld->tclasParams.ipv4.srcPort;
+			pDot11f->info.IpParams.params.IpV4Params.dest_port =
+				pOld->tclasParams.ipv4.dstPort;
+			pDot11f->info.IpParams.params.IpV4Params.DSCP =
+				pOld->tclasParams.ipv4.dscp;
+			pDot11f->info.IpParams.params.IpV4Params.proto =
+				pOld->tclasParams.ipv4.protocol;
+			pDot11f->info.IpParams.params.IpV4Params.reserved =
+				pOld->tclasParams.ipv4.rsvd;
+		} else {
+			qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+				     params.IpV6Params.source,
+				     (uint8_t *) pOld->tclasParams.ipv6.
+				     srcIpAddr, 16);
+			qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+				     params.IpV6Params.dest,
+				     (uint8_t *) pOld->tclasParams.ipv6.
+				     dstIpAddr, 16);
+			pDot11f->info.IpParams.params.IpV6Params.src_port =
+				pOld->tclasParams.ipv6.srcPort;
+			pDot11f->info.IpParams.params.IpV6Params.dest_port =
+				pOld->tclasParams.ipv6.dstPort;
+			qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+				     params.IpV6Params.flow_label,
+				     (uint8_t *) pOld->tclasParams.ipv6.
+				     flowLabel, 3);
+		}
+		break;
+	case SIR_MAC_TCLASTYPE_8021DQ:
+		pDot11f->info.Params8021dq.tag_type =
+			pOld->tclasParams.t8021dq.tag;
+		break;
+	default:
+		pe_err("Bad TCLAS type %d in populate_dot11f_tclas",
+			pDot11f->classifier_type);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pDot11f->present = 1;
+
+	return QDF_STATUS_SUCCESS;
+
+} /* End populate_dot11f_wmmtclas. */
+
+QDF_STATUS populate_dot11f_wsc(tpAniSirGlobal pMac,
+			       tDot11fIEWscBeacon *pDot11f)
+{
+
+	uint32_t wpsState;
+
+	pDot11f->Version.present = 1;
+	pDot11f->Version.major = 0x01;
+	pDot11f->Version.minor = 0x00;
+
+	wpsState = pMac->mlme_cfg->wps_params.wps_state;
+
+	pDot11f->WPSState.present = 1;
+	pDot11f->WPSState.state = (uint8_t) wpsState;
+
+	pDot11f->APSetupLocked.present = 0;
+
+	pDot11f->SelectedRegistrar.present = 0;
+
+	pDot11f->DevicePasswordID.present = 0;
+
+	pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+	pDot11f->UUID_E.present = 0;
+
+	pDot11f->RFBands.present = 0;
+
+	pDot11f->present = 1;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS populate_dot11f_wsc_registrar_info(tpAniSirGlobal pMac,
+					      tDot11fIEWscBeacon *pDot11f)
+{
+	const struct sLimWscIeInfo *const pWscIeInfo = &(pMac->lim.wscIeInfo);
+
+	pDot11f->APSetupLocked.present = 1;
+	pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked;
+
+	pDot11f->SelectedRegistrar.present = 1;
+	pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar;
+
+	pDot11f->DevicePasswordID.present = 1;
+	pDot11f->DevicePasswordID.id =
+		(uint16_t)pMac->mlme_cfg->wps_params.wps_device_password_id;
+
+	pDot11f->SelectedRegistrarConfigMethods.present = 1;
+	pDot11f->SelectedRegistrarConfigMethods.methods =
+		pWscIeInfo->selectedRegistrarConfigMethods;
+
+	/* UUID_E and RF Bands are applicable only for dual band AP */
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS de_populate_dot11f_wsc_registrar_info(tpAniSirGlobal pMac,
+						 tDot11fIEWscBeacon *pDot11f)
+{
+	pDot11f->APSetupLocked.present = 0;
+	pDot11f->SelectedRegistrar.present = 0;
+	pDot11f->DevicePasswordID.present = 0;
+	pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS populate_dot11f_probe_res_wpsi_es(tpAniSirGlobal pMac,
+					     tDot11fIEWscProbeRes *pDot11f,
+					     tpPESession psessionEntry)
+{
+
+	tSirWPSProbeRspIE *pSirWPSProbeRspIE;
+
+	pSirWPSProbeRspIE = &psessionEntry->APWPSIEs.SirWPSProbeRspIE;
+
+	if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) {
+		pDot11f->present = 1;
+		pDot11f->Version.present = 1;
+		pDot11f->Version.major =
+			(uint8_t) ((pSirWPSProbeRspIE->Version & 0xF0) >> 4);
+		pDot11f->Version.minor =
+			(uint8_t) (pSirWPSProbeRspIE->Version & 0x0F);
+	} else {
+		pDot11f->present = 0;
+		pDot11f->Version.present = 0;
+	}
+
+	if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_STATE_PRESENT) {
+
+		pDot11f->WPSState.present = 1;
+		pDot11f->WPSState.state = (uint8_t) pSirWPSProbeRspIE->wpsState;
+	} else
+		pDot11f->WPSState.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_APSETUPLOCK_PRESENT) {
+		pDot11f->APSetupLocked.present = 1;
+		pDot11f->APSetupLocked.fLocked =
+			pSirWPSProbeRspIE->APSetupLocked;
+	} else
+		pDot11f->APSetupLocked.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT) {
+		pDot11f->SelectedRegistrar.present = 1;
+		pDot11f->SelectedRegistrar.selected =
+			pSirWPSProbeRspIE->SelectedRegistra;
+	} else
+		pDot11f->SelectedRegistrar.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_DEVICEPASSWORDID_PRESENT) {
+		pDot11f->DevicePasswordID.present = 1;
+		pDot11f->DevicePasswordID.id =
+			pSirWPSProbeRspIE->DevicePasswordID;
+	} else
+		pDot11f->DevicePasswordID.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT) {
+		pDot11f->SelectedRegistrarConfigMethods.present = 1;
+		pDot11f->SelectedRegistrarConfigMethods.methods =
+			pSirWPSProbeRspIE->SelectedRegistraCfgMethod;
+	} else
+		pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT) {
+		pDot11f->ResponseType.present = 1;
+		pDot11f->ResponseType.resType = pSirWPSProbeRspIE->ResponseType;
+	} else
+		pDot11f->ResponseType.present = 0;
+
+	if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_UUIDE_PRESENT) {
+		pDot11f->UUID_E.present = 1;
+		qdf_mem_copy(pDot11f->UUID_E.uuid, pSirWPSProbeRspIE->UUID_E,
+			     WNI_CFG_WPS_UUID_LEN);
+	} else
+		pDot11f->UUID_E.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_MANUFACTURE_PRESENT) {
+		pDot11f->Manufacturer.present = 1;
+		pDot11f->Manufacturer.num_name =
+			pSirWPSProbeRspIE->Manufacture.num_name;
+		qdf_mem_copy(pDot11f->Manufacturer.name,
+			     pSirWPSProbeRspIE->Manufacture.name,
+			     pSirWPSProbeRspIE->Manufacture.num_name);
+	} else
+		pDot11f->Manufacturer.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) {
+		pDot11f->ModelName.present = 1;
+		pDot11f->ModelName.num_text =
+			pSirWPSProbeRspIE->ModelName.num_text;
+		qdf_mem_copy(pDot11f->ModelName.text,
+			     pSirWPSProbeRspIE->ModelName.text,
+			     pDot11f->ModelName.num_text);
+	} else
+		pDot11f->ModelName.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) {
+		pDot11f->ModelNumber.present = 1;
+		pDot11f->ModelNumber.num_text =
+			pSirWPSProbeRspIE->ModelNumber.num_text;
+		qdf_mem_copy(pDot11f->ModelNumber.text,
+			     pSirWPSProbeRspIE->ModelNumber.text,
+			     pDot11f->ModelNumber.num_text);
+	} else
+		pDot11f->ModelNumber.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_SERIALNUMBER_PRESENT) {
+		pDot11f->SerialNumber.present = 1;
+		pDot11f->SerialNumber.num_text =
+			pSirWPSProbeRspIE->SerialNumber.num_text;
+		qdf_mem_copy(pDot11f->SerialNumber.text,
+			     pSirWPSProbeRspIE->SerialNumber.text,
+			     pDot11f->SerialNumber.num_text);
+	} else
+		pDot11f->SerialNumber.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT) {
+		pDot11f->PrimaryDeviceType.present = 1;
+		qdf_mem_copy(pDot11f->PrimaryDeviceType.oui,
+			     pSirWPSProbeRspIE->PrimaryDeviceOUI,
+			     sizeof(pSirWPSProbeRspIE->PrimaryDeviceOUI));
+		pDot11f->PrimaryDeviceType.primary_category =
+			(uint16_t) pSirWPSProbeRspIE->PrimaryDeviceCategory;
+		pDot11f->PrimaryDeviceType.sub_category =
+			(uint16_t) pSirWPSProbeRspIE->DeviceSubCategory;
+	} else
+		pDot11f->PrimaryDeviceType.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_DEVICENAME_PRESENT) {
+		pDot11f->DeviceName.present = 1;
+		pDot11f->DeviceName.num_text =
+			pSirWPSProbeRspIE->DeviceName.num_text;
+		qdf_mem_copy(pDot11f->DeviceName.text,
+			     pSirWPSProbeRspIE->DeviceName.text,
+			     pDot11f->DeviceName.num_text);
+	} else
+		pDot11f->DeviceName.present = 0;
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_CONFIGMETHODS_PRESENT) {
+		pDot11f->ConfigMethods.present = 1;
+		pDot11f->ConfigMethods.methods =
+			pSirWPSProbeRspIE->ConfigMethod;
+	} else
+		pDot11f->ConfigMethods.present = 0;
+
+	if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_RF_BANDS_PRESENT) {
+		pDot11f->RFBands.present = 1;
+		pDot11f->RFBands.bands = pSirWPSProbeRspIE->RFBand;
+	} else
+		pDot11f->RFBands.present = 0;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS populate_dot11f_assoc_res_wpsi_es(tpAniSirGlobal pMac,
+					     tDot11fIEWscAssocRes *pDot11f,
+					     tpPESession psessionEntry)
+{
+	tSirWPSProbeRspIE *pSirWPSProbeRspIE;
+
+	pSirWPSProbeRspIE = &psessionEntry->APWPSIEs.SirWPSProbeRspIE;
+
+	if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) {
+		pDot11f->present = 1;
+		pDot11f->Version.present = 1;
+		pDot11f->Version.major =
+			(uint8_t) ((pSirWPSProbeRspIE->Version & 0xF0) >> 4);
+		pDot11f->Version.minor =
+			(uint8_t) (pSirWPSProbeRspIE->Version & 0x0F);
+	} else {
+		pDot11f->present = 0;
+		pDot11f->Version.present = 0;
+	}
+
+	if (pSirWPSProbeRspIE->
+	    FieldPresent & SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT) {
+		pDot11f->ResponseType.present = 1;
+		pDot11f->ResponseType.resType = pSirWPSProbeRspIE->ResponseType;
+	} else
+		pDot11f->ResponseType.present = 0;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS populate_dot11f_beacon_wpsi_es(tpAniSirGlobal pMac,
+					  tDot11fIEWscBeacon *pDot11f,
+					  tpPESession psessionEntry)
+{
+
+	tSirWPSBeaconIE *pSirWPSBeaconIE;
+
+	pSirWPSBeaconIE = &psessionEntry->APWPSIEs.SirWPSBeaconIE;
+
+	if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) {
+		pDot11f->present = 1;
+		pDot11f->Version.present = 1;
+		pDot11f->Version.major =
+			(uint8_t) ((pSirWPSBeaconIE->Version & 0xF0) >> 4);
+		pDot11f->Version.minor =
+			(uint8_t) (pSirWPSBeaconIE->Version & 0x0F);
+	} else {
+		pDot11f->present = 0;
+		pDot11f->Version.present = 0;
+	}
+
+	if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_STATE_PRESENT) {
+
+		pDot11f->WPSState.present = 1;
+		pDot11f->WPSState.state = (uint8_t) pSirWPSBeaconIE->wpsState;
+	} else
+		pDot11f->WPSState.present = 0;
+
+	if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_APSETUPLOCK_PRESENT) {
+		pDot11f->APSetupLocked.present = 1;
+		pDot11f->APSetupLocked.fLocked = pSirWPSBeaconIE->APSetupLocked;
+	} else
+		pDot11f->APSetupLocked.present = 0;
+
+	if (pSirWPSBeaconIE->
+	    FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRA_PRESENT) {
+		pDot11f->SelectedRegistrar.present = 1;
+		pDot11f->SelectedRegistrar.selected =
+			pSirWPSBeaconIE->SelectedRegistra;
+	} else
+		pDot11f->SelectedRegistrar.present = 0;
+
+	if (pSirWPSBeaconIE->
+	    FieldPresent & SIR_WPS_BEACON_DEVICEPASSWORDID_PRESENT) {
+		pDot11f->DevicePasswordID.present = 1;
+		pDot11f->DevicePasswordID.id =
+			pSirWPSBeaconIE->DevicePasswordID;
+	} else
+		pDot11f->DevicePasswordID.present = 0;
+
+	if (pSirWPSBeaconIE->
+	    FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT) {
+		pDot11f->SelectedRegistrarConfigMethods.present = 1;
+		pDot11f->SelectedRegistrarConfigMethods.methods =
+			pSirWPSBeaconIE->SelectedRegistraCfgMethod;
+	} else
+		pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+	if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_UUIDE_PRESENT) {
+		pDot11f->UUID_E.present = 1;
+		qdf_mem_copy(pDot11f->UUID_E.uuid, pSirWPSBeaconIE->UUID_E,
+			     WNI_CFG_WPS_UUID_LEN);
+	} else
+		pDot11f->UUID_E.present = 0;
+
+	if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_RF_BANDS_PRESENT) {
+		pDot11f->RFBands.present = 1;
+		pDot11f->RFBands.bands = pSirWPSBeaconIE->RFBand;
+	} else
+		pDot11f->RFBands.present = 0;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS populate_dot11f_wsc_in_probe_res(tpAniSirGlobal pMac,
+					    tDot11fIEWscProbeRes *pDot11f)
+{
+	uint32_t cfgStrLen;
+	uint32_t val;
+	uint32_t wpsVersion, wpsState;
+
+	wpsVersion = pMac->mlme_cfg->wps_params.wps_version;
+
+	pDot11f->Version.present = 1;
+	pDot11f->Version.major = (uint8_t) ((wpsVersion & 0xF0) >> 4);
+	pDot11f->Version.minor = (uint8_t) (wpsVersion & 0x0F);
+
+	wpsState = pMac->mlme_cfg->wps_params.wps_state;
+	pDot11f->WPSState.present = 1;
+	pDot11f->WPSState.state = (uint8_t) wpsState;
+
+	pDot11f->APSetupLocked.present = 0;
+
+	pDot11f->SelectedRegistrar.present = 0;
+
+	pDot11f->DevicePasswordID.present = 0;
+
+	pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+	pDot11f->ResponseType.present = 1;
+	if ((pMac->lim.wscIeInfo.reqType == REQ_TYPE_REGISTRAR) ||
+	    (pMac->lim.wscIeInfo.reqType == REQ_TYPE_WLAN_MANAGER_REGISTRAR)) {
+		pDot11f->ResponseType.resType = RESP_TYPE_ENROLLEE_OPEN_8021X;
+	} else {
+		pDot11f->ResponseType.resType = RESP_TYPE_AP;
+	}
+
+	/* UUID is a 16 byte long binary. Still use wlan_cfg_get_str to get it. */
+	pDot11f->UUID_E.present = 1;
+	cfgStrLen = WNI_CFG_WPS_UUID_LEN;
+	if (wlan_cfg_get_str(pMac,
+			     WNI_CFG_WPS_UUID,
+			     pDot11f->UUID_E.uuid, &cfgStrLen) != QDF_STATUS_SUCCESS) {
+		*(pDot11f->UUID_E.uuid) = '\0';
+	}
+
+	pDot11f->Manufacturer.present = 1;
+	cfgStrLen = sizeof(pDot11f->Manufacturer.name);
+	if (wlan_mlme_get_manufacturer_name(pMac->psoc,
+					    pDot11f->Manufacturer.name,
+					    &cfgStrLen) != QDF_STATUS_SUCCESS) {
+		pDot11f->Manufacturer.num_name = 0;
+	} else {
+		pDot11f->Manufacturer.num_name =
+			(uint8_t) (cfgStrLen & 0x000000FF);
+	}
+
+	pDot11f->ModelName.present = 1;
+	cfgStrLen = sizeof(pDot11f->ModelName.text);
+	if (wlan_mlme_get_model_name(pMac->psoc,
+				     pDot11f->ModelName.text,
+				     &cfgStrLen) != QDF_STATUS_SUCCESS) {
+		pDot11f->ModelName.num_text = 0;
+	} else {
+		pDot11f->ModelName.num_text =
+			(uint8_t) (cfgStrLen & 0x000000FF);
+	}
+
+	pDot11f->ModelNumber.present = 1;
+	cfgStrLen = sizeof(pDot11f->ModelNumber.text);
+	if (wlan_mlme_get_model_number(pMac->psoc,
+				       pDot11f->ModelNumber.text,
+				       &cfgStrLen) != QDF_STATUS_SUCCESS) {
+		pDot11f->ModelNumber.num_text = 0;
+	} else {
+		pDot11f->ModelNumber.num_text =
+			(uint8_t) (cfgStrLen & 0x000000FF);
+	}
+
+	pDot11f->SerialNumber.present = 1;
+	cfgStrLen = sizeof(pDot11f->SerialNumber.text);
+	if (wlan_mlme_get_manufacture_product_version
+				(pMac->psoc,
+				 pDot11f->SerialNumber.text,
+				 &cfgStrLen) != QDF_STATUS_SUCCESS) {
+		pDot11f->SerialNumber.num_text = 0;
+	} else {
+		pDot11f->SerialNumber.num_text =
+			(uint8_t) (cfgStrLen & 0x000000FF);
+	}
+
+	pDot11f->PrimaryDeviceType.present = 1;
+
+	pDot11f->PrimaryDeviceType.primary_category =
+	       (uint16_t)pMac->mlme_cfg->wps_params.wps_primary_device_category;
+
+		val = pMac->mlme_cfg->wps_params.wps_primary_device_oui;
+		*(pDot11f->PrimaryDeviceType.oui) =
+			(uint8_t) ((val >> 24) & 0xff);
+		*(pDot11f->PrimaryDeviceType.oui + 1) =
+			(uint8_t) ((val >> 16) & 0xff);
+		*(pDot11f->PrimaryDeviceType.oui + 2) =
+			(uint8_t) ((val >> 8) & 0xff);
+		*(pDot11f->PrimaryDeviceType.oui + 3) =
+			(uint8_t) ((val & 0xff));
+
+	pDot11f->PrimaryDeviceType.sub_category =
+	       (uint16_t)pMac->mlme_cfg->wps_params.wps_device_sub_category;
+
+
+	pDot11f->DeviceName.present = 1;
+	cfgStrLen = sizeof(pDot11f->DeviceName.text);
+	if (wlan_mlme_get_manufacture_product_name(pMac->psoc,
+						   pDot11f->DeviceName.text,
+						   &cfgStrLen) !=
+						   QDF_STATUS_SUCCESS) {
+		pDot11f->DeviceName.num_text = 0;
+	} else {
+		pDot11f->DeviceName.num_text =
+			(uint8_t) (cfgStrLen & 0x000000FF);
+	}
+
+		pDot11f->ConfigMethods.present = 1;
+		pDot11f->ConfigMethods.methods =
+			(uint16_t)(pMac->mlme_cfg->wps_params.wps_cfg_method &
+				   0x0000FFFF);
+
+	pDot11f->RFBands.present = 0;
+
+	pDot11f->present = 1;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+populate_dot11f_wsc_registrar_info_in_probe_res(tpAniSirGlobal pMac,
+						tDot11fIEWscProbeRes *pDot11f)
+{
+	const struct sLimWscIeInfo *const pWscIeInfo = &(pMac->lim.wscIeInfo);
+
+	pDot11f->APSetupLocked.present = 1;
+	pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked;
+
+	pDot11f->SelectedRegistrar.present = 1;
+	pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar;
+
+	pDot11f->DevicePasswordID.present = 1;
+	pDot11f->DevicePasswordID.id =
+		(uint16_t)pMac->mlme_cfg->wps_params.wps_device_password_id;
+
+	pDot11f->SelectedRegistrarConfigMethods.present = 1;
+	pDot11f->SelectedRegistrarConfigMethods.methods =
+		pWscIeInfo->selectedRegistrarConfigMethods;
+
+	/* UUID_E and RF Bands are applicable only for dual band AP */
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+de_populate_dot11f_wsc_registrar_info_in_probe_res(tpAniSirGlobal pMac,
+						   tDot11fIEWscProbeRes *
+								 pDot11f)
+{
+	pDot11f->APSetupLocked.present = 0;
+	pDot11f->SelectedRegistrar.present = 0;
+	pDot11f->DevicePasswordID.present = 0;
+	pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS populate_dot11f_assoc_res_wsc_ie(tpAniSirGlobal pMac,
+					    tDot11fIEWscAssocRes *pDot11f,
+					    tpSirAssocReq pRcvdAssocReq)
+{
+	uint32_t ret;
+	const uint8_t *wscIe;
+	tDot11fIEWscAssocReq parsedWscAssocReq = { 0, };
+
+	wscIe = limGetWscIEPtr(pMac, pRcvdAssocReq->addIE.addIEdata,
+			       pRcvdAssocReq->addIE.length);
+	if (wscIe != NULL) {
+		/* retrieve WSC IE from given AssocReq */
+		ret = dot11f_unpack_ie_wsc_assoc_req(pMac,
+						     /* EID, length, OUI */
+						     (uint8_t *)wscIe + 2 + 4,
+						     /* length without OUI */
+						     wscIe[1] - 4,
+						     &parsedWscAssocReq, false);
+		if (!DOT11F_SUCCEEDED(ret)) {
+			pe_err("unpack failed, ret: %d", ret);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		pDot11f->present = 1;
+		/* version has to be 0x10 */
+		pDot11f->Version.present = 1;
+		pDot11f->Version.major = 0x1;
+		pDot11f->Version.minor = 0x0;
+
+		pDot11f->ResponseType.present = 1;
+
+		if ((parsedWscAssocReq.RequestType.reqType ==
+		     REQ_TYPE_REGISTRAR)
+		    || (parsedWscAssocReq.RequestType.reqType ==
+			REQ_TYPE_WLAN_MANAGER_REGISTRAR)) {
+			pDot11f->ResponseType.resType =
+				RESP_TYPE_ENROLLEE_OPEN_8021X;
+		} else {
+			pDot11f->ResponseType.resType = RESP_TYPE_AP;
+		}
+		/* Version infomration should be taken from our capability as well as peers */
+		/* TODO: currently it takes from peers only */
+		if (parsedWscAssocReq.VendorExtension.present &&
+		    parsedWscAssocReq.VendorExtension.Version2.present) {
+			pDot11f->VendorExtension.present = 1;
+			pDot11f->VendorExtension.vendorId[0] = 0x00;
+			pDot11f->VendorExtension.vendorId[1] = 0x37;
+			pDot11f->VendorExtension.vendorId[2] = 0x2A;
+			pDot11f->VendorExtension.Version2.present = 1;
+			pDot11f->VendorExtension.Version2.major =
+				parsedWscAssocReq.VendorExtension.Version2.major;
+			pDot11f->VendorExtension.Version2.minor =
+				parsedWscAssocReq.VendorExtension.Version2.minor;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS populate_dot11_assoc_res_p2p_ie(tpAniSirGlobal pMac,
+					   tDot11fIEP2PAssocRes *pDot11f,
+					   tpSirAssocReq pRcvdAssocReq)
+{
+	const uint8_t *p2pIe;
+
+	p2pIe = limGetP2pIEPtr(pMac, pRcvdAssocReq->addIE.addIEdata,
+			       pRcvdAssocReq->addIE.length);
+	if (p2pIe != NULL) {
+		pDot11f->present = 1;
+		pDot11f->P2PStatus.present = 1;
+		pDot11f->P2PStatus.status = QDF_STATUS_SUCCESS;
+		pDot11f->ExtendedListenTiming.present = 0;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS populate_dot11f_wfatpc(tpAniSirGlobal pMac,
+				  tDot11fIEWFATPC *pDot11f, uint8_t txPower,
+				  uint8_t linkMargin)
+{
+	pDot11f->txPower = txPower;
+	pDot11f->linkMargin = linkMargin;
+	pDot11f->present = 1;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+populate_dot11f_beacon_report(tpAniSirGlobal pMac,
+			      tDot11fIEMeasurementReport *pDot11f,
+			      tSirMacBeaconReport *pBeaconReport,
+			      struct rrm_beacon_report_last_beacon_params
+			      *last_beacon_report_params)
+{
+
+	pDot11f->report.Beacon.regClass = pBeaconReport->regClass;
+	pDot11f->report.Beacon.channel = pBeaconReport->channel;
+	qdf_mem_copy(pDot11f->report.Beacon.meas_start_time,
+		     pBeaconReport->measStartTime,
+		     sizeof(pDot11f->report.Beacon.meas_start_time));
+	pDot11f->report.Beacon.meas_duration = pBeaconReport->measDuration;
+	pDot11f->report.Beacon.condensed_PHY = pBeaconReport->phyType;
+	pDot11f->report.Beacon.reported_frame_type =
+		!pBeaconReport->bcnProbeRsp;
+	pDot11f->report.Beacon.RCPI = pBeaconReport->rcpi;
+	pDot11f->report.Beacon.RSNI = pBeaconReport->rsni;
+	qdf_mem_copy(pDot11f->report.Beacon.BSSID, pBeaconReport->bssid,
+		     sizeof(tSirMacAddr));
+	pDot11f->report.Beacon.antenna_id = pBeaconReport->antennaId;
+	pDot11f->report.Beacon.parent_TSF = pBeaconReport->parentTSF;
+
+	if (pBeaconReport->numIes) {
+		pDot11f->report.Beacon.BeaconReportFrmBody.present = 1;
+		qdf_mem_copy(pDot11f->report.Beacon.BeaconReportFrmBody.
+			     reportedFields, pBeaconReport->Ies,
+			     pBeaconReport->numIes);
+		pDot11f->report.Beacon.BeaconReportFrmBody.num_reportedFields =
+			pBeaconReport->numIes;
+	}
+
+	if (last_beacon_report_params &&
+	    last_beacon_report_params->last_beacon_ind) {
+		pe_debug("Including Last Beacon Report in RRM Frame, report_id %d, frag_id %d",
+			last_beacon_report_params->report_id,
+			last_beacon_report_params->frag_id);
+		pDot11f->report.Beacon.beacon_report_frm_body_fragment_id.
+			present = 1;
+		pDot11f->report.Beacon.beacon_report_frm_body_fragment_id.
+			beacon_report_id = last_beacon_report_params->report_id;
+		pDot11f->report.Beacon.beacon_report_frm_body_fragment_id.
+			fragment_id_number = last_beacon_report_params->frag_id;
+
+		pDot11f->report.Beacon.last_beacon_report_indication.present = 1;
+
+		if (last_beacon_report_params->frag_id ==
+		    (last_beacon_report_params->num_frags - 1)) {
+			pDot11f->report.Beacon.
+				beacon_report_frm_body_fragment_id.
+				more_fragments = 0;
+			pDot11f->report.Beacon.last_beacon_report_indication.
+				last_fragment = 1;
+			pe_debug("Last Fragment");
+		} else {
+			pDot11f->report.Beacon.
+				beacon_report_frm_body_fragment_id.
+				more_fragments = 1;
+			pDot11f->report.Beacon.last_beacon_report_indication.
+				last_fragment = 0;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+
+}
+
+QDF_STATUS populate_dot11f_rrm_ie(tpAniSirGlobal pMac,
+				  tDot11fIERRMEnabledCap *pDot11f,
+				  tpPESession psessionEntry)
+{
+	tpRRMCaps pRrmCaps;
+	uint8_t *bytes;
+
+	pRrmCaps = rrm_get_capabilities(pMac, psessionEntry);
+
+	pDot11f->LinkMeasurement = pRrmCaps->LinkMeasurement;
+	pDot11f->NeighborRpt = pRrmCaps->NeighborRpt;
+	pDot11f->parallel = pRrmCaps->parallel;
+	pDot11f->repeated = pRrmCaps->repeated;
+	pDot11f->BeaconPassive = pRrmCaps->BeaconPassive;
+	pDot11f->BeaconActive = pRrmCaps->BeaconActive;
+	pDot11f->BeaconTable = pRrmCaps->BeaconTable;
+	pDot11f->BeaconRepCond = pRrmCaps->BeaconRepCond;
+	pDot11f->FrameMeasurement = pRrmCaps->FrameMeasurement;
+	pDot11f->ChannelLoad = pRrmCaps->ChannelLoad;
+	pDot11f->NoiseHistogram = pRrmCaps->NoiseHistogram;
+	pDot11f->statistics = pRrmCaps->statistics;
+	pDot11f->LCIMeasurement = pRrmCaps->LCIMeasurement;
+	pDot11f->LCIAzimuth = pRrmCaps->LCIAzimuth;
+	pDot11f->TCMCapability = pRrmCaps->TCMCapability;
+	pDot11f->triggeredTCM = pRrmCaps->triggeredTCM;
+	pDot11f->APChanReport = pRrmCaps->APChanReport;
+	pDot11f->RRMMIBEnabled = pRrmCaps->RRMMIBEnabled;
+	pDot11f->operatingChanMax = pRrmCaps->operatingChanMax;
+	pDot11f->nonOperatinChanMax = pRrmCaps->nonOperatingChanMax;
+	pDot11f->MeasurementPilot = pRrmCaps->MeasurementPilot;
+	pDot11f->MeasurementPilotEnabled = pRrmCaps->MeasurementPilotEnabled;
+	pDot11f->NeighborTSFOffset = pRrmCaps->NeighborTSFOffset;
+	pDot11f->RCPIMeasurement = pRrmCaps->RCPIMeasurement;
+	pDot11f->RSNIMeasurement = pRrmCaps->RSNIMeasurement;
+	pDot11f->BssAvgAccessDelay = pRrmCaps->BssAvgAccessDelay;
+	pDot11f->BSSAvailAdmission = pRrmCaps->BSSAvailAdmission;
+	pDot11f->AntennaInformation = pRrmCaps->AntennaInformation;
+	pDot11f->fine_time_meas_rpt = pRrmCaps->fine_time_meas_rpt;
+	pDot11f->lci_capability = pRrmCaps->lci_capability;
+	pDot11f->reserved = pRrmCaps->reserved;
+
+	bytes = (uint8_t *) pDot11f + 1; /* ignore present field */
+	pe_debug("RRM Enabled Cap IE: %02x %02x %02x %02x %02x",
+			   bytes[0], bytes[1], bytes[2], bytes[3], bytes[4]);
+
+	pDot11f->present = 1;
+	return QDF_STATUS_SUCCESS;
+}
+
+void populate_mdie(tpAniSirGlobal pMac,
+		   tDot11fIEMobilityDomain *pDot11f,
+		   uint8_t mdie[SIR_MDIE_SIZE])
+{
+	pDot11f->present = 1;
+	pDot11f->MDID = (uint16_t) ((mdie[1] << 8) | (mdie[0]));
+
+	/* Plugfest fix */
+	pDot11f->overDSCap = (mdie[2] & 0x01);
+	pDot11f->resourceReqCap = ((mdie[2] >> 1) & 0x01);
+
+}
+
+void populate_ft_info(tpAniSirGlobal pMac, tDot11fIEFTInfo *pDot11f)
+{
+	pDot11f->present = 1;
+	pDot11f->IECount = 0;   /* TODO: put valid data during reassoc. */
+	/* All other info is zero. */
+
+}
+
+void populate_dot11f_assoc_rsp_rates(tpAniSirGlobal pMac,
+				     tDot11fIESuppRates *pSupp,
+				     tDot11fIEExtSuppRates *pExt,
+				     uint16_t *_11bRates, uint16_t *_11aRates)
+{
+	uint8_t num_supp = 0, num_ext = 0;
+	uint8_t i, j;
+
+	for (i = 0; (i < SIR_NUM_11B_RATES && _11bRates[i]); i++, num_supp++) {
+		pSupp->rates[num_supp] = (uint8_t) _11bRates[i];
+	}
+	for (j = 0; (j < SIR_NUM_11A_RATES && _11aRates[j]); j++) {
+		if (num_supp < 8)
+			pSupp->rates[num_supp++] = (uint8_t) _11aRates[j];
+		else
+			pExt->rates[num_ext++] = (uint8_t) _11aRates[j];
+	}
+
+	if (num_supp) {
+		pSupp->num_rates = num_supp;
+		pSupp->present = 1;
+	}
+	if (num_ext) {
+		pExt->num_rates = num_ext;
+		pExt->present = 1;
+	}
+}
+
+void populate_dot11f_timeout_interval(tpAniSirGlobal pMac,
+				      tDot11fIETimeoutInterval *pDot11f,
+				      uint8_t type, uint32_t value)
+{
+	pDot11f->present = 1;
+	pDot11f->timeoutType = type;
+	pDot11f->timeoutValue = value;
+}
+
+/**
+ * populate_dot11f_timing_advert_frame() - Populate the TA mgmt frame fields
+ * @pMac: the MAC context
+ * @frame: pointer to the TA frame
+ *
+ * Return: The SIR status.
+ */
+QDF_STATUS
+populate_dot11f_timing_advert_frame(tpAniSirGlobal mac_ctx,
+				    tDot11fTimingAdvertisementFrame *frame)
+{
+	uint32_t val, len;
+	uint16_t item;
+	uint8_t temp[CFG_MAX_STR_LEN], code[3];
+	QDF_STATUS nSirStatus;
+
+	/* Capabilities */
+	val = mac_ctx->mlme_cfg->wep_params.is_privacy_enabled;
+	if (val)
+		frame->Capabilities.privacy = 1;
+
+	if (mac_ctx->mlme_cfg->ht_caps.short_preamble)
+		frame->Capabilities.shortPreamble = 1;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_11H_ENABLED, &val);
+	if (val)
+		frame->Capabilities.spectrumMgt = 1;
+
+	if (mac_ctx->mlme_cfg->wmm_params.qos_enabled)
+		frame->Capabilities.qos = 1;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_APSD_ENABLED, &val);
+	if (val)
+		frame->Capabilities.apsd = 1;
+
+	val = mac_ctx->mlme_cfg->feature_flags.enable_block_ack;
+	frame->Capabilities.delayedBA =
+		(uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1);
+	frame->Capabilities.immediateBA =
+		(uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1);
+
+	/* Country */
+	item = WNI_CFG_MAX_TX_POWER_5;
+	CFG_GET_STR(nSirStatus, mac_ctx, item, temp, len,
+		WNI_CFG_MAX_TX_POWER_5_LEN);
+	wlan_reg_read_current_country(mac_ctx->psoc, code);
+	qdf_mem_copy(&frame->Country, code, 2);
+	if (len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE)
+		len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE;
+
+	frame->Country.num_triplets = (uint8_t)(len / 3);
+	qdf_mem_copy((uint8_t *)&frame->Country.triplets, temp, len);
+	frame->Country.present = 1;
+
+	/* PowerConstraints */
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_LOCAL_POWER_CONSTRAINT, &val);
+	frame->PowerConstraints.localPowerConstraints = (uint8_t)val;
+	frame->PowerConstraints.present = 1;
+
+	/* TimeAdvertisement */
+	frame->TimeAdvertisement.present = 1;
+	frame->TimeAdvertisement.timing_capabilities = 1;
+
+	return nSirStatus;
+}
+
+#ifdef WLAN_FEATURE_11AX
+/**
+ * populate_dot11f_he_caps() - pouldate HE Capability IE
+ * @mac_ctx: Global MAC context
+ * @session: PE session
+ * @he_cap: pointer to HE capability IE
+ *
+ * Populdate the HE capability IE based on the session.
+ */
+QDF_STATUS populate_dot11f_he_caps(tpAniSirGlobal mac_ctx, tpPESession session,
+				   tDot11fIEhe_cap *he_cap)
+{
+	uint8_t *ppet;
+	uint32_t value = 0;
+	QDF_STATUS status;
+
+	he_cap->present = 1;
+
+	if (!session) {
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CONTROL, value);
+		he_cap->htc_he = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TWT_REQUESTOR, value);
+		he_cap->twt_request = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TWT_RESPONDER, value);
+		he_cap->twt_responder = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_FRAGMENTATION, value);
+		he_cap->fragmentation = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MAX_FRAG_MSDU, value);
+		he_cap->max_num_frag_msdu_amsdu_exp = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MIN_FRAG_SIZE, value);
+		he_cap->min_frag_size = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TRIG_PAD, value);
+		he_cap->trigger_frm_mac_pad = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MTID_AGGR_RX, value);
+		he_cap->multi_tid_aggr_rx_supp = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_LINK_ADAPTATION, value);
+		he_cap->he_link_adaptation = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_ALL_ACK, value);
+		he_cap->all_ack = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TRIGD_RSP_SCHEDULING,
+			    value);
+		he_cap->trigd_rsp_sched = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BUFFER_STATUS_RPT,
+			    value);
+		he_cap->a_bsr = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BCAST_TWT, value);
+		he_cap->broadcast_twt = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BA_32BIT, value);
+		he_cap->ba_32bit_bitmap = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MU_CASCADING, value);
+		he_cap->mu_cascade = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MULTI_TID, value);
+		he_cap->ack_enabled_multitid = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_OMI, value);
+		he_cap->omi_a_ctrl = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_OFDMA_RA, value);
+		he_cap->ofdma_ra = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MAX_AMPDU_LEN, value);
+		he_cap->max_ampdu_len_exp_ext = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_AMSDU_FRAG, value);
+		he_cap->amsdu_frag = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_FLEX_TWT_SCHED, value);
+		he_cap->flex_twt_sched = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_CTRL, value);
+		he_cap->rx_ctrl_frame = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BSRP_AMPDU_AGGR, value);
+		he_cap->bsrp_ampdu_aggr = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_QTP, value);
+		he_cap->qtp = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_A_BQR, value);
+		he_cap->a_bqr = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_SR_RESPONDER, value);
+		he_cap->spatial_reuse_param_rspder = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_NDP_FEEDBACK_SUPP,
+					     value);
+		he_cap->ndp_feedback_supp = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_OPS_SUPP, value);
+		he_cap->ops_supp = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_AMSDU_IN_AMPDU, value);
+		he_cap->amsdu_in_ampdu = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_SUB_CH_SEL_TX, value);
+		he_cap->he_sub_ch_sel_tx_supp = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_UL_2X996_RU, value);
+		he_cap->ul_2x996_tone_ru_supp = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX,
+			    value);
+		he_cap->om_ctrl_ul_mu_data_dis_rx = value;
+
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CHAN_WIDTH, value);
+		he_cap->chan_width_0 = HE_CH_WIDTH_GET_BIT(value, 0);
+		he_cap->chan_width_1 = HE_CH_WIDTH_GET_BIT(value, 1);
+		he_cap->chan_width_2 = HE_CH_WIDTH_GET_BIT(value, 2);
+		he_cap->chan_width_3 = HE_CH_WIDTH_GET_BIT(value, 3);
+		he_cap->chan_width_4 = HE_CH_WIDTH_GET_BIT(value, 4);
+		he_cap->chan_width_5 = HE_CH_WIDTH_GET_BIT(value, 5);
+		he_cap->chan_width_6 = HE_CH_WIDTH_GET_BIT(value, 6);
+
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_PREAM_PUNC, value);
+		he_cap->rx_pream_puncturing = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CLASS_OF_DEVICE, value);
+		he_cap->device_class = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_LDPC, value);
+		he_cap->ldpc_coding = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_LTF_PPDU, value);
+		he_cap->he_1x_ltf_800_gi_ppdu = value;
+		CFG_GET_INT(status, mac_ctx,
+			    WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS, value);
+		he_cap->midamble_tx_rx_max_nsts = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_LTF_NDP, value);
+		he_cap->he_4x_ltf_3200_gi_ndp = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TX_STBC_LT80, value);
+		he_cap->tx_stbc_lt_80mhz = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_STBC_LT80, value);
+		he_cap->rx_stbc_lt_80mhz = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DOPPLER, value);
+		he_cap->doppler = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_UL_MUMIMO, value);
+		he_cap->ul_mu = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DCM_TX, value);
+		he_cap->dcm_enc_tx = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DCM_RX, value);
+		he_cap->dcm_enc_rx = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MU_PPDU, value);
+		he_cap->ul_he_mu = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_SU_BEAMFORMER, value);
+		he_cap->su_beamformer = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_SU_BEAMFORMEE, value);
+		he_cap->su_beamformee = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MU_BEAMFORMER, value);
+		he_cap->mu_beamformer = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BFEE_STS_LT80, value);
+		he_cap->bfee_sts_lt_80 = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BFEE_STS_GT80, value);
+		he_cap->bfee_sts_gt_80 = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_NUM_SOUND_LT80, value);
+		he_cap->num_sounding_lt_80 = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_NUM_SOUND_GT80, value);
+		he_cap->num_sounding_gt_80 = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_SU_FEED_TONE16, value);
+		he_cap->su_feedback_tone16 = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MU_FEED_TONE16, value);
+		he_cap->mu_feedback_tone16 = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CODEBOOK_SU, value);
+		he_cap->codebook_su = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CODEBOOK_MU, value);
+		he_cap->codebook_mu = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BFRM_FEED, value);
+		he_cap->beamforming_feedback = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_ER_SU_PPDU, value);
+		he_cap->he_er_su_ppdu = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DL_PART_BW, value);
+		he_cap->dl_mu_mimo_part_bw = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_PPET_PRESENT, value);
+		he_cap->ppet_present = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_SRP, value);
+		he_cap->srp = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_POWER_BOOST, value);
+		he_cap->power_boost = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_4x_LTF_GI, value);
+		he_cap->he_ltf_800_gi_4x = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MAX_NC, value);
+		he_cap->max_nc = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TX_STBC_GT80, value);
+		he_cap->tx_stbc_gt_80mhz = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_STBC_GT80, value);
+		he_cap->rx_stbc_gt_80mhz = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_ER_4x_LTF_GI, value);
+		he_cap->er_he_ltf_800_gi_4x = value;
+		CFG_GET_INT(status, mac_ctx,
+			    WNI_CFG_HE_PPDU_20_IN_40MHZ_2G, value);
+		he_cap->he_ppdu_20_in_40Mhz_2G = value;
+		CFG_GET_INT(status, mac_ctx,
+			    WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ, value);
+		he_cap->he_ppdu_20_in_160_80p80Mhz = value;
+		CFG_GET_INT(status, mac_ctx,
+			    WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ, value);
+		he_cap->he_ppdu_80_in_160_80p80Mhz = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_ER_1X_HE_LTF_GI, value);
+		he_cap->er_1x_he_ltf_gi = value;
+		CFG_GET_INT(status, mac_ctx,
+			    WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF, value);
+		he_cap->midamble_tx_rx_1x_he_ltf = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DCM_MAX_BW, value);
+		he_cap->dcm_max_bw = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM,
+			    value);
+		he_cap->longer_than_16_he_sigb_ofdm_sym = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TX_1024_QAM_LT_242_RU,
+			    value);
+		he_cap->tx_1024_qam_lt_242_tone_ru = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_1024_QAM_LT_242_RU,
+			    value);
+		he_cap->rx_1024_qam_lt_242_tone_ru = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_NON_TRIG_CQI_FEEDBACK,
+			    value);
+		he_cap->non_trig_cqi_feedback = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB,
+			    value);
+		he_cap->rx_full_bw_su_he_mu_compress_sigb = value;
+		CFG_GET_INT(status, mac_ctx,
+			    WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB,
+			    value);
+		he_cap->rx_full_bw_su_he_mu_non_cmpr_sigb = value;
+		CFG_GET_INT(status, mac_ctx,
+			WNI_CFG_HE_RX_MCS_MAP_LT_80, value);
+		he_cap->rx_he_mcs_map_lt_80 = value;
+		CFG_GET_INT(status, mac_ctx,
+			WNI_CFG_HE_TX_MCS_MAP_LT_80, value);
+		he_cap->tx_he_mcs_map_lt_80 = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_MCS_MAP_160, value);
+		*((uint16_t *)he_cap->rx_he_mcs_map_160) = value;
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TX_MCS_MAP_160, value);
+		*((uint16_t *)he_cap->tx_he_mcs_map_160) = value;
+		CFG_GET_INT(status, mac_ctx,
+			WNI_CFG_HE_RX_MCS_MAP_80_80, value);
+		*((uint16_t *)he_cap->rx_he_mcs_map_80_80) = value;
+		CFG_GET_INT(status, mac_ctx,
+			WNI_CFG_HE_TX_MCS_MAP_80_80, value);
+		*((uint16_t *)he_cap->tx_he_mcs_map_80_80) = value;
+
+		if (he_cap->ppet_present) {
+			value = WNI_CFG_HE_PPET_LEN;
+			/* if session less then take 5g cap */
+			CFG_GET_STR(status, mac_ctx, WNI_CFG_HE_PPET_5G,
+				    he_cap->ppet.ppe_threshold.ppe_th,
+				    value, value);
+			ppet = he_cap->ppet.ppe_threshold.ppe_th;
+			he_cap->ppet.ppe_threshold.num_ppe_th =
+						lim_truncate_ppet(ppet, value);
+		} else {
+			he_cap->ppet.ppe_threshold.num_ppe_th = 0;
+		}
+
+		return QDF_STATUS_SUCCESS;
+	}
+
+	qdf_mem_copy(he_cap, &session->he_config, sizeof(*he_cap));
+	if (he_cap->ppet_present) {
+		value = WNI_CFG_HE_PPET_LEN;
+		/* if session is present, populate PPET based on band */
+		if (IS_5G_CH(session->currentOperChannel))
+			CFG_GET_STR(status, mac_ctx, WNI_CFG_HE_PPET_5G,
+				    he_cap->ppet.ppe_threshold.ppe_th,
+				    value, value);
+		else
+			CFG_GET_STR(status, mac_ctx, WNI_CFG_HE_PPET_2G,
+				    he_cap->ppet.ppe_threshold.ppe_th,
+				    value, value);
+		ppet = he_cap->ppet.ppe_threshold.ppe_th;
+		he_cap->ppet.ppe_threshold.num_ppe_th =
+						lim_truncate_ppet(ppet, value);
+	} else {
+		he_cap->ppet.ppe_threshold.num_ppe_th = 0;
+	}
+
+	lim_log_he_cap(mac_ctx, he_cap);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * populate_dot11f_he_operation() - pouldate HE Operation IE
+ * @mac_ctx: Global MAC context
+ * @session: PE session
+ * @he_op: pointer to HE Operation IE
+ *
+ * Populdate the HE Operation IE based on the session.
+ */
+QDF_STATUS
+populate_dot11f_he_operation(tpAniSirGlobal mac_ctx,
+			     tpPESession session, tDot11fIEhe_op *he_op)
+{
+	qdf_mem_copy(he_op, &session->he_op, sizeof(*he_op));
+
+	he_op->vht_oper_present = 1;
+	he_op->present = 1;
+	if (session->ch_width > CH_WIDTH_40MHZ) {
+		he_op->vht_oper.info.chan_width = 1;
+		he_op->vht_oper.info.center_freq_seg0 =
+			session->ch_center_freq_seg0;
+		if (session->ch_width == CH_WIDTH_80P80MHZ ||
+				session->ch_width == CH_WIDTH_160MHZ)
+			he_op->vht_oper.info.center_freq_seg1 =
+				session->ch_center_freq_seg1;
+		else
+			he_op->vht_oper.info.center_freq_seg1 = 0;
+	} else {
+		he_op->vht_oper.info.chan_width = 0;
+		he_op->vht_oper.info.center_freq_seg0 = 0;
+		he_op->vht_oper.info.center_freq_seg1 = 0;
+	}
+	lim_log_he_op(mac_ctx, he_op);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+/**
+ * populate_dot11f_he_bss_color_change() - pouldate HE BSS color change IE
+ * @mac_ctx: Global MAC context
+ * @session: PE session
+ * @he_bss_color: pointer to HE BSS color change IE
+ *
+ * Populdate the HE BSS color change IE based on the session.
+ */
+QDF_STATUS
+populate_dot11f_he_bss_color_change(tpAniSirGlobal mac_ctx,
+				    tpPESession session,
+				    tDot11fIEbss_color_change *he_bss_color)
+{
+	if (!session->bss_color_changing) {
+		he_bss_color->present = 0;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	he_bss_color->present = 1;
+	he_bss_color->countdown = session->he_bss_color_change.countdown;
+	he_bss_color->new_color = session->he_bss_color_change.new_color;
+
+	lim_log_he_bss_color(mac_ctx, he_bss_color);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#endif
+
+#ifdef WLAN_SUPPORT_TWT
+QDF_STATUS populate_dot11f_twt_extended_caps(tpAniSirGlobal mac_ctx,
+					     tpPESession pe_session,
+					     tDot11fIEExtCap *dot11f)
+{
+	uint32_t value = 0;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct s_ext_cap *p_ext_cap;
+
+	if (!pe_session->enable_session_twt_support)
+		return QDF_STATUS_SUCCESS;
+
+	dot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
+	p_ext_cap = (struct s_ext_cap *)dot11f->bytes;
+
+	if (pe_session->pePersona == QDF_STA_MODE) {
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_TWT_REQUESTOR, value);
+		p_ext_cap->twt_requestor_support = value;
+	}
+	if (pe_session->pePersona == QDF_SAP_MODE) {
+		CFG_GET_INT(status, mac_ctx, WNI_CFG_TWT_RESPONDER, value);
+		p_ext_cap->twt_responder_support = value;
+	}
+	dot11f->num_bytes = lim_compute_ext_cap_ie_length(dot11f);
+
+	return status;
+}
+#endif
+
+/* parser_api.c ends here. */
diff --git a/core/mac/src/sys/legacy/src/utils/src/utils_parser.c b/core/mac/src/sys/legacy/src/utils/src/utils_parser.c
new file mode 100644
index 0000000..da2f8a2
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/src/utils_parser.c
@@ -0,0 +1,685 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/*
+ *
+ * This file utils_parser.cc contains the code for parsing
+ * 802.11 messages.
+ * Author:        Pierre Vandwalle
+ * Date:          03/18/02
+ * History:-
+ * Date           Modified by    Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "ani_global.h"
+#include "utils_parser.h"
+#include "lim_ser_des_utils.h"
+
+void convert_ssid(tpAniSirGlobal pMac, tSirMacSSid *pOld, tDot11fIESSID *pNew)
+{
+	pOld->length = pNew->num_ssid;
+	qdf_mem_copy(pOld->ssId, pNew->ssid, pNew->num_ssid);
+}
+
+void convert_supp_rates(tpAniSirGlobal pMac,
+			tSirMacRateSet *pOld, tDot11fIESuppRates *pNew)
+{
+	pOld->numRates = pNew->num_rates;
+	qdf_mem_copy(pOld->rate, pNew->rates, pNew->num_rates);
+}
+
+void convert_ext_supp_rates(tpAniSirGlobal pMac,
+			    tSirMacRateSet *pOld, tDot11fIEExtSuppRates *pNew)
+{
+	pOld->numRates = pNew->num_rates;
+	qdf_mem_copy(pOld->rate, pNew->rates, pNew->num_rates);
+}
+
+void convert_qos_caps(tpAniSirGlobal pMac,
+		      tSirMacQosCapabilityIE *pOld, tDot11fIEQOSCapsAp *pNew)
+{
+	pOld->type = 46;
+	pOld->length = 1;
+
+	pOld->qosInfo.count = pNew->count;
+}
+
+void convert_qos_caps_station(tpAniSirGlobal pMac,
+			      tSirMacQosCapabilityStaIE *pOld,
+			      tDot11fIEQOSCapsStation *pNew)
+{
+	pOld->type = 46;
+	pOld->length = 1;
+
+	pOld->qosInfo.moreDataAck = pNew->more_data_ack;
+	pOld->qosInfo.maxSpLen = pNew->max_sp_length;
+	pOld->qosInfo.qack = pNew->qack;
+	pOld->qosInfo.acbe_uapsd = pNew->acbe_uapsd;
+	pOld->qosInfo.acbk_uapsd = pNew->acbk_uapsd;
+	pOld->qosInfo.acvi_uapsd = pNew->acvi_uapsd;
+	pOld->qosInfo.acvo_uapsd = pNew->acvo_uapsd;
+}
+
+QDF_STATUS convert_wpa(tpAniSirGlobal pMac,
+		       tSirMacWpaInfo *pOld, tDot11fIEWPA *pNew)
+{
+	/* This is awful, I know, but the old code just rammed the IE into an */
+	/* array... */
+	uint8_t buffer[257];
+	uint32_t status, written = 0, nbuffer = 257;
+
+	status = dot11f_pack_ie_wpa(pMac, pNew, buffer, nbuffer, &written);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to re-pack the WPA IE (0x%0x8)", status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pOld->length = (uint8_t) written - 2;
+	qdf_mem_copy(pOld->info, buffer + 2, pOld->length);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS convert_wpa_opaque(tpAniSirGlobal pMac,
+			      tSirMacWpaInfo *pOld, tDot11fIEWPAOpaque *pNew)
+{
+	/* This is awful, I know, but the old code just rammed the IE into */
+	/* an opaque array.  Note that we need to explicitly add the OUI! */
+	pOld->length = pNew->num_data + 4;
+	pOld->info[0] = 0x00;
+	pOld->info[1] = 0x50;
+	pOld->info[2] = 0xf2;
+	pOld->info[3] = 0x01;
+	qdf_mem_copy(pOld->info + 4, pNew->data, pNew->num_data);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+QDF_STATUS convert_wapi_opaque(tpAniSirGlobal pMac,
+			       tSirMacWapiInfo *pOld,
+			       tDot11fIEWAPIOpaque *pNew)
+{
+	/* This is awful, I know, but the old code just rammed the IE into */
+	/* an opaque array.  Note that we need to explicitly add the OUI! */
+	pOld->length = pNew->num_data;
+	qdf_mem_copy(pOld->info, pNew->data, pNew->num_data);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+QDF_STATUS convert_wsc_opaque(tpAniSirGlobal pMac,
+			      tSirAddie *pOld, tDot11fIEWscIEOpaque *pNew)
+{
+	/* This is awful, I know, but the old code just rammed the IE into */
+	/* an opaque array.  Note that we need to explicitly add the vendorIE and OUI ! */
+	uint16_t curAddIELen = pOld->length;
+
+	pOld->length = curAddIELen + pNew->num_data + 6;
+	pOld->addIEdata[curAddIELen++] = 0xdd;
+	pOld->addIEdata[curAddIELen++] = pNew->num_data + 4;
+	pOld->addIEdata[curAddIELen++] = 0x00;
+	pOld->addIEdata[curAddIELen++] = 0x50;
+	pOld->addIEdata[curAddIELen++] = 0xf2;
+	pOld->addIEdata[curAddIELen++] = 0x04;
+	qdf_mem_copy(pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS convert_p2p_opaque(tpAniSirGlobal pMac,
+			      tSirAddie *pOld, tDot11fIEP2PIEOpaque *pNew)
+{
+	/* This is awful, I know, but the old code just rammed the IE into */
+	/* an opaque array.  Note that we need to explicitly add the vendorIE and OUI ! */
+	uint16_t curAddIELen = pOld->length;
+
+	pOld->length = curAddIELen + pNew->num_data + 6;
+	pOld->addIEdata[curAddIELen++] = 0xdd;
+	pOld->addIEdata[curAddIELen++] = pNew->num_data + 4;
+	pOld->addIEdata[curAddIELen++] = 0x50;
+	pOld->addIEdata[curAddIELen++] = 0x6f;
+	pOld->addIEdata[curAddIELen++] = 0x9A;
+	pOld->addIEdata[curAddIELen++] = 0x09;
+	qdf_mem_copy(pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_WFD
+QDF_STATUS convert_wfd_opaque(tpAniSirGlobal pMac,
+			      tSirAddie *pOld, tDot11fIEWFDIEOpaque *pNew)
+{
+	/* This is awful, I know, but the old code just rammed the IE into */
+	/* an opaque array.  Note that we need to explicitly add the vendorIE and OUI ! */
+	uint16_t curAddIELen = pOld->length;
+
+	pOld->length = curAddIELen + pNew->num_data + 6;
+	pOld->addIEdata[curAddIELen++] = 0xdd;
+	pOld->addIEdata[curAddIELen++] = pNew->num_data + 4;
+	pOld->addIEdata[curAddIELen++] = 0x50;
+	pOld->addIEdata[curAddIELen++] = 0x6f;
+	pOld->addIEdata[curAddIELen++] = 0x9A;
+	pOld->addIEdata[curAddIELen++] = 0x0a;
+	qdf_mem_copy(pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+QDF_STATUS convert_rsn(tpAniSirGlobal pMac,
+		       tSirMacRsnInfo *pOld, tDot11fIERSN *pNew)
+{
+	uint8_t buffer[257];
+	uint32_t status, written = 0, nbuffer = 257;
+
+	status = dot11f_pack_ie_rsn(pMac, pNew, buffer, nbuffer, &written);
+	if (DOT11F_FAILED(status)) {
+		pe_err("Failed to re-pack the RSN IE (0x%0x8)", status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pOld->length = (uint8_t) written - 2;
+	qdf_mem_copy(pOld->info, buffer + 2, pOld->length);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS convert_rsn_opaque(tpAniSirGlobal pMac,
+			      tSirMacRsnInfo *pOld, tDot11fIERSNOpaque *pNew)
+{
+	/* This is awful, I know, but the old code just rammed the IE into */
+	/* an opaque array. */
+	pOld->length = pNew->num_data;
+	qdf_mem_copy(pOld->info, pNew->data, pOld->length);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void convert_power_caps(tpAniSirGlobal pMac,
+			tSirMacPowerCapabilityIE *pOld,
+			tDot11fIEPowerCaps *pNew)
+{
+	pOld->type = 33;
+	pOld->length = 2;
+	pOld->minTxPower = pNew->minTxPower;
+	pOld->maxTxPower = pNew->maxTxPower;
+}
+
+void convert_supp_channels(tpAniSirGlobal pMac,
+			   tSirMacSupportedChannelIE *pOld,
+			   tDot11fIESuppChannels *pNew)
+{
+	pOld->type = 36;
+	pOld->length = (pNew->num_bands * 2);
+	qdf_mem_copy((uint8_t *) pOld->supportedChannels,
+		     (uint8_t *) pNew->bands, pOld->length);
+}
+
+void convert_cf_params(tpAniSirGlobal pMac,
+		       tSirMacCfParamSet *pOld, tDot11fIECFParams *pNew)
+{
+	pOld->cfpCount = pNew->cfp_count;
+	pOld->cfpPeriod = pNew->cfp_period;
+	pOld->cfpMaxDuration = pNew->cfp_maxduration;
+	pOld->cfpDurRemaining = pNew->cfp_durremaining;
+}
+
+void convert_fh_params(tpAniSirGlobal pMac,
+		       tSirMacFHParamSet *pOld, tDot11fIEFHParamSet *pNew)
+{
+	pOld->dwellTime = pNew->dwell_time;
+	pOld->hopSet = pNew->hop_set;
+	pOld->hopPattern = pNew->hop_pattern;
+	pOld->hopIndex = pNew->hop_index;
+}
+
+void convert_tim(tpAniSirGlobal pMac, tSirMacTim *pOld, tDot11fIETIM *pNew)
+{
+	pOld->dtimCount = pNew->dtim_count;
+	pOld->dtimPeriod = pNew->dtim_period;
+	pOld->bitmapControl = pNew->bmpctl;
+	pOld->bitmapLength = pNew->num_vbmp;
+
+	qdf_mem_copy(pOld->bitmap, pNew->vbmp, pNew->num_vbmp);
+}
+
+void convert_country(tpAniSirGlobal pMac,
+		     tSirCountryInformation *pOld, tDot11fIECountry *pNew)
+{
+	int i;
+
+	qdf_mem_copy(pOld->countryString, pNew->country, COUNTRY_STRING_LENGTH);
+
+	pOld->numIntervals = pNew->num_triplets;
+
+	for (i = 0; i < pNew->num_triplets; ++i) {
+		pOld->channelTransmitPower[i].channelNumber =
+			pNew->triplets[i][0];
+		pOld->channelTransmitPower[i].numChannel = pNew->triplets[i][1];
+		pOld->channelTransmitPower[i].maxTransmitPower =
+			pNew->triplets[i][2];
+	}
+}
+
+void convert_wmm_params(tpAniSirGlobal pMac,
+			tSirMacEdcaParamSetIE *pOld, tDot11fIEWMMParams *pNew)
+{
+	pOld->type = 221;
+	pOld->length = 24;
+
+	qdf_mem_copy((uint8_t *) &pOld->qosInfo, (uint8_t *) &pNew->qosInfo,
+		     1);
+
+	pOld->acbe.aci.aifsn = pNew->acbe_aifsn;
+	pOld->acbe.aci.acm = pNew->acbe_acm;
+	pOld->acbe.aci.aci = pNew->acbe_aci;
+	pOld->acbe.cw.min = pNew->acbe_acwmin;
+	pOld->acbe.cw.max = pNew->acbe_acwmax;
+	pOld->acbe.txoplimit = pNew->acbe_txoplimit;
+
+	pOld->acbk.aci.aifsn = pNew->acbk_aifsn;
+	pOld->acbk.aci.acm = pNew->acbk_acm;
+	pOld->acbk.aci.aci = pNew->acbk_aci;
+	pOld->acbk.cw.min = pNew->acbk_acwmin;
+	pOld->acbk.cw.max = pNew->acbk_acwmax;
+	pOld->acbk.txoplimit = pNew->acbk_txoplimit;
+
+	pOld->acvi.aci.aifsn = pNew->acvi_aifsn;
+	pOld->acvi.aci.acm = pNew->acvi_acm;
+	pOld->acvi.aci.aci = pNew->acvi_aci;
+	pOld->acvi.cw.min = pNew->acvi_acwmin;
+	pOld->acvi.cw.max = pNew->acvi_acwmax;
+	pOld->acvi.txoplimit = pNew->acvi_txoplimit;
+
+	pOld->acvo.aci.aifsn = pNew->acvo_aifsn;
+	pOld->acvo.aci.acm = pNew->acvo_acm;
+	pOld->acvo.aci.aci = pNew->acvo_aci;
+	pOld->acvo.cw.min = pNew->acvo_acwmin;
+	pOld->acvo.cw.max = pNew->acvo_acwmax;
+	pOld->acvo.txoplimit = pNew->acvo_txoplimit;
+}
+
+void convert_erp_info(tpAniSirGlobal pMac,
+		      tSirMacErpInfo *pOld, tDot11fIEERPInfo *pNew)
+{
+	pOld->nonErpPresent = pNew->non_erp_present;
+	pOld->useProtection = pNew->use_prot;
+	pOld->barkerPreambleMode = pNew->barker_preamble;
+}
+
+void convert_edca_param(tpAniSirGlobal pMac,
+			tSirMacEdcaParamSetIE *pOld,
+			tDot11fIEEDCAParamSet *pNew)
+{
+	pOld->type = 12;
+	pOld->length = 20;
+
+	qdf_mem_copy((uint8_t *) &pOld->qosInfo, (uint8_t *) &pNew->qos, 1);
+
+	pOld->acbe.aci.aifsn = pNew->acbe_aifsn;
+	pOld->acbe.aci.acm = pNew->acbe_acm;
+	pOld->acbe.aci.aci = pNew->acbe_aci;
+	pOld->acbe.cw.min = pNew->acbe_acwmin;
+	pOld->acbe.cw.max = pNew->acbe_acwmax;
+	pOld->acbe.txoplimit = pNew->acbe_txoplimit;
+
+	pOld->acbk.aci.aifsn = pNew->acbk_aifsn;
+	pOld->acbk.aci.acm = pNew->acbk_acm;
+	pOld->acbk.aci.aci = pNew->acbk_aci;
+	pOld->acbk.cw.min = pNew->acbk_acwmin;
+	pOld->acbk.cw.max = pNew->acbk_acwmax;
+	pOld->acbk.txoplimit = pNew->acbk_txoplimit;
+
+	pOld->acvi.aci.aifsn = pNew->acvi_aifsn;
+	pOld->acvi.aci.acm = pNew->acvi_acm;
+	pOld->acvi.aci.aci = pNew->acvi_aci;
+	pOld->acvi.cw.min = pNew->acvi_acwmin;
+	pOld->acvi.cw.max = pNew->acvi_acwmax;
+	pOld->acvi.txoplimit = pNew->acvi_txoplimit;
+
+	pOld->acvo.aci.aifsn = pNew->acvo_aifsn;
+	pOld->acvo.aci.acm = pNew->acvo_acm;
+	pOld->acvo.aci.aci = pNew->acvo_aci;
+	pOld->acvo.cw.min = pNew->acvo_acwmin;
+	pOld->acvo.cw.max = pNew->acvo_acwmax;
+	pOld->acvo.txoplimit = pNew->acvo_txoplimit;
+
+}
+
+void convert_mu_edca_param(tpAniSirGlobal mac_ctx,
+			tSirMacEdcaParamSetIE *mu_edca,
+			tDot11fIEmu_edca_param_set *ie)
+{
+	qdf_mem_copy((uint8_t *) &mu_edca->qosInfo, (uint8_t *) &ie->qos, 1);
+
+	mu_edca->acbe.aci.aifsn = ie->acbe_aifsn;
+	mu_edca->acbe.aci.acm = ie->acbe_acm;
+	mu_edca->acbe.aci.aci = ie->acbe_aci;
+	mu_edca->acbe.cw.min = ie->acbe_acwmin;
+	mu_edca->acbe.cw.max = ie->acbe_acwmax;
+	mu_edca->acbe.mu_edca_timer = ie->acbe_muedca_timer;
+
+	mu_edca->acbk.aci.aifsn = ie->acbk_aifsn;
+	mu_edca->acbk.aci.acm = ie->acbk_acm;
+	mu_edca->acbk.aci.aci = ie->acbk_aci;
+	mu_edca->acbk.cw.min = ie->acbk_acwmin;
+	mu_edca->acbk.cw.max = ie->acbk_acwmax;
+	mu_edca->acbk.mu_edca_timer = ie->acbk_muedca_timer;
+
+	mu_edca->acvi.aci.aifsn = ie->acvi_aifsn;
+	mu_edca->acvi.aci.acm = ie->acvi_acm;
+	mu_edca->acvi.aci.aci = ie->acvi_aci;
+	mu_edca->acvi.cw.min = ie->acvi_acwmin;
+	mu_edca->acvi.cw.max = ie->acvi_acwmax;
+	mu_edca->acvi.mu_edca_timer = ie->acvi_muedca_timer;
+
+	mu_edca->acvo.aci.aifsn = ie->acvo_aifsn;
+	mu_edca->acvo.aci.acm = ie->acvo_acm;
+	mu_edca->acvo.aci.aci = ie->acvo_aci;
+	mu_edca->acvo.cw.min = ie->acvo_acwmin;
+	mu_edca->acvo.cw.max = ie->acvo_acwmax;
+	mu_edca->acvo.mu_edca_timer = ie->acvo_muedca_timer;
+
+}
+
+void convert_tspec(tpAniSirGlobal pMac,
+		   tSirMacTspecIE *pOld, tDot11fIETSPEC *pNew)
+{
+	pOld->tsinfo.traffic.trafficType = (uint16_t) pNew->traffic_type;
+	pOld->tsinfo.traffic.tsid = (uint16_t) pNew->tsid;
+	pOld->tsinfo.traffic.direction = (uint16_t) pNew->direction;
+	pOld->tsinfo.traffic.accessPolicy = (uint16_t) pNew->access_policy;
+	pOld->tsinfo.traffic.aggregation = (uint16_t) pNew->aggregation;
+	pOld->tsinfo.traffic.psb = (uint16_t) pNew->psb;
+	pOld->tsinfo.traffic.userPrio = (uint16_t) pNew->user_priority;
+	pOld->tsinfo.traffic.ackPolicy = (uint16_t) pNew->tsinfo_ack_pol;
+
+	pOld->tsinfo.schedule.schedule = (uint8_t) pNew->schedule;
+
+	pOld->nomMsduSz = pNew->size;
+	pOld->maxMsduSz = pNew->max_msdu_size;
+	pOld->minSvcInterval = pNew->min_service_int;
+	pOld->maxSvcInterval = pNew->max_service_int;
+	pOld->inactInterval = pNew->inactivity_int;
+	pOld->suspendInterval = pNew->suspension_int;
+	pOld->svcStartTime = pNew->service_start_time;
+	pOld->minDataRate = pNew->min_data_rate;
+	pOld->meanDataRate = pNew->mean_data_rate;
+	pOld->peakDataRate = pNew->peak_data_rate;
+	pOld->maxBurstSz = pNew->burst_size;
+	pOld->delayBound = pNew->delay_bound;
+	pOld->minPhyRate = pNew->min_phy_rate;
+	pOld->surplusBw = pNew->surplus_bw_allowance;
+	pOld->mediumTime = pNew->medium_time;
+}
+
+QDF_STATUS convert_tclas(tpAniSirGlobal pMac,
+			 tSirTclasInfo *pOld, tDot11fIETCLAS *pNew)
+{
+	uint32_t length = 0;
+
+	if (DOT11F_FAILED(dot11f_get_packed_ietclas(pMac, pNew, &length))) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pOld->tclas.type = DOT11F_EID_TCLAS;
+	pOld->tclas.length = (uint8_t) length;
+	pOld->tclas.userPrio = pNew->user_priority;
+	pOld->tclas.classifierType = pNew->classifier_type;
+	pOld->tclas.classifierMask = pNew->classifier_mask;
+
+	switch (pNew->classifier_type) {
+	case 0:
+		qdf_mem_copy(pOld->tclasParams.eth.srcAddr,
+			     pNew->info.EthParams.source, 6);
+		qdf_mem_copy(pOld->tclasParams.eth.dstAddr,
+			     pNew->info.EthParams.dest, 6);
+		pOld->tclasParams.eth.type = pNew->info.EthParams.type;
+		break;
+	case 1:
+		pOld->version = pNew->info.IpParams.version;
+		if (4 == pNew->info.IpParams.version) {
+			pOld->tclasParams.ipv4.version = 4;
+			qdf_mem_copy(pOld->tclasParams.ipv4.srcIpAddr,
+				     pNew->info.IpParams.params.IpV4Params.
+				     source, 4);
+			qdf_mem_copy(pOld->tclasParams.ipv4.dstIpAddr,
+				     pNew->info.IpParams.params.IpV4Params.dest,
+				     4);
+			pOld->tclasParams.ipv4.srcPort =
+				pNew->info.IpParams.params.IpV4Params.src_port;
+			pOld->tclasParams.ipv4.dstPort =
+				pNew->info.IpParams.params.IpV4Params.dest_port;
+			pOld->tclasParams.ipv4.dscp =
+				pNew->info.IpParams.params.IpV4Params.DSCP;
+			pOld->tclasParams.ipv4.protocol =
+				pNew->info.IpParams.params.IpV4Params.proto;
+			pOld->tclasParams.ipv4.rsvd =
+				pNew->info.IpParams.params.IpV4Params.reserved;
+		} else if (6 == pNew->info.IpParams.version) {
+			pOld->tclasParams.ipv6.version = 6;
+			qdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+				     srcIpAddr,
+				     (uint8_t *) pNew->info.IpParams.params.
+				     IpV6Params.source, 16);
+			qdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+				     dstIpAddr,
+				     (uint8_t *) pNew->info.IpParams.params.
+				     IpV6Params.dest, 16);
+			pOld->tclasParams.ipv6.srcPort =
+				pNew->info.IpParams.params.IpV6Params.src_port;
+			pOld->tclasParams.ipv6.dstPort =
+				pNew->info.IpParams.params.IpV6Params.dest_port;
+			qdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+				     flowLabel,
+				     (uint8_t *) pNew->info.IpParams.params.
+				     IpV6Params.flow_label, 3);
+		} else {
+			return QDF_STATUS_E_FAILURE;
+		}
+		break;
+	case 2:
+		pOld->tclasParams.t8021dq.tag =
+			pNew->info.Params8021dq.tag_type;
+		break;
+	default:
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void convert_wmmtspec(tpAniSirGlobal pMac,
+		      tSirMacTspecIE *pOld, tDot11fIEWMMTSPEC *pNew)
+{
+	pOld->tsinfo.traffic.trafficType = (uint16_t) pNew->traffic_type;
+	pOld->tsinfo.traffic.tsid = (uint16_t) pNew->tsid;
+	pOld->tsinfo.traffic.direction = (uint16_t) pNew->direction;
+	pOld->tsinfo.traffic.accessPolicy = (uint16_t) pNew->access_policy;
+	pOld->tsinfo.traffic.aggregation = (uint16_t) pNew->aggregation;
+	pOld->tsinfo.traffic.psb = (uint16_t) pNew->psb;
+	pOld->tsinfo.traffic.userPrio = (uint16_t) pNew->user_priority;
+	pOld->tsinfo.traffic.ackPolicy = (uint16_t) pNew->tsinfo_ack_pol;
+	pOld->nomMsduSz = (pNew->fixed << 15) | pNew->size;
+	pOld->maxMsduSz = pNew->max_msdu_size;
+	pOld->minSvcInterval = pNew->min_service_int;
+	pOld->maxSvcInterval = pNew->max_service_int;
+	pOld->inactInterval = pNew->inactivity_int;
+	pOld->suspendInterval = pNew->suspension_int;
+	pOld->svcStartTime = pNew->service_start_time;
+	pOld->minDataRate = pNew->min_data_rate;
+	pOld->meanDataRate = pNew->mean_data_rate;
+	pOld->peakDataRate = pNew->peak_data_rate;
+	pOld->maxBurstSz = pNew->burst_size;
+	pOld->delayBound = pNew->delay_bound;
+	pOld->minPhyRate = pNew->min_phy_rate;
+	pOld->surplusBw = pNew->surplus_bw_allowance;
+	pOld->mediumTime = pNew->medium_time;
+}
+
+QDF_STATUS convert_wmmtclas(tpAniSirGlobal pMac,
+			    tSirTclasInfo *pOld, tDot11fIEWMMTCLAS *pNew)
+{
+	uint32_t length = 0;
+
+	if (DOT11F_FAILED(dot11f_get_packed_iewmmtclas(pMac, pNew, &length))) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pOld->tclas.type = DOT11F_EID_WMMTCLAS;
+	pOld->tclas.length = (uint8_t) length;
+	pOld->tclas.userPrio = pNew->user_priority;
+	pOld->tclas.classifierType = pNew->classifier_type;
+	pOld->tclas.classifierMask = pNew->classifier_mask;
+
+	switch (pNew->classifier_type) {
+	case 0:
+		qdf_mem_copy(pOld->tclasParams.eth.srcAddr,
+			     pNew->info.EthParams.source, 6);
+		qdf_mem_copy(pOld->tclasParams.eth.dstAddr,
+			     pNew->info.EthParams.dest, 6);
+		pOld->tclasParams.eth.type = pNew->info.EthParams.type;
+		break;
+	case 1:
+		pOld->version = pNew->info.IpParams.version;
+		if (4 == pNew->info.IpParams.version) {
+			pOld->tclasParams.ipv4.version = 4;
+			qdf_mem_copy(pOld->tclasParams.ipv4.srcIpAddr,
+				     pNew->info.IpParams.params.IpV4Params.
+				     source, 4);
+			qdf_mem_copy(pOld->tclasParams.ipv4.dstIpAddr,
+				     pNew->info.IpParams.params.IpV4Params.dest,
+				     4);
+			pOld->tclasParams.ipv4.srcPort =
+				pNew->info.IpParams.params.IpV4Params.src_port;
+			pOld->tclasParams.ipv4.dstPort =
+				pNew->info.IpParams.params.IpV4Params.dest_port;
+			pOld->tclasParams.ipv4.dscp =
+				pNew->info.IpParams.params.IpV4Params.DSCP;
+			pOld->tclasParams.ipv4.protocol =
+				pNew->info.IpParams.params.IpV4Params.proto;
+			pOld->tclasParams.ipv4.rsvd =
+				pNew->info.IpParams.params.IpV4Params.reserved;
+		} else if (6 == pNew->info.IpParams.version) {
+			pOld->tclasParams.ipv6.version = 6;
+			qdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+				     srcIpAddr,
+				     (uint8_t *) pNew->info.IpParams.params.
+				     IpV6Params.source, 16);
+			qdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+				     dstIpAddr,
+				     (uint8_t *) pNew->info.IpParams.params.
+				     IpV6Params.dest, 16);
+			pOld->tclasParams.ipv6.srcPort =
+				pNew->info.IpParams.params.IpV6Params.src_port;
+			pOld->tclasParams.ipv6.dstPort =
+				pNew->info.IpParams.params.IpV6Params.dest_port;
+			qdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+				     flowLabel,
+				     (uint8_t *) pNew->info.IpParams.params.
+				     IpV6Params.flow_label, 3);
+		} else {
+			return QDF_STATUS_E_FAILURE;
+		}
+		break;
+	case 2:
+		pOld->tclasParams.t8021dq.tag =
+			pNew->info.Params8021dq.tag_type;
+		break;
+	default:
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void convert_ts_delay(tpAniSirGlobal pMac,
+		      tSirMacTsDelayIE *pOld, tDot11fIETSDelay *pNew)
+{
+	pOld->type = DOT11F_EID_TSDELAY;
+	pOld->length = 4U;
+	pOld->delay = pNew->delay;
+}
+
+void convert_schedule(tpAniSirGlobal pMac,
+		      tSirMacScheduleIE *pOld, tDot11fIESchedule *pNew)
+{
+	pOld->type = DOT11F_EID_SCHEDULE;
+	pOld->length = DOT11F_IE_SCHEDULE_MIN_LEN;
+
+	pOld->info.aggregation = pNew->aggregation;
+	pOld->info.tsid = pNew->tsid;
+	pOld->info.direction = pNew->direction;
+
+	pOld->svcStartTime = pNew->service_start_time;
+	pOld->svcInterval = pNew->service_interval;
+	pOld->specInterval = pNew->spec_interval;
+}
+
+void convert_wmm_schedule(tpAniSirGlobal pMac,
+			  tSirMacScheduleIE *pOld, tDot11fIEWMMSchedule *pNew)
+{
+	pOld->type = DOT11F_EID_WMMSCHEDULE;
+	pOld->length = DOT11F_IE_WMMSCHEDULE_MIN_LEN;
+
+	pOld->info.aggregation = pNew->aggregation;
+	pOld->info.tsid = pNew->tsid;
+	pOld->info.direction = pNew->direction;
+
+	pOld->svcStartTime = pNew->service_start_time;
+	pOld->svcInterval = pNew->service_interval;
+	pOld->specInterval = pNew->spec_interval;
+}
+
+void convert_qos_mapset_frame(tpAniSirGlobal pMac, tSirQosMapSet *Qos,
+			      tDot11fIEQosMapSet *dot11fIE)
+{
+	uint8_t i, j = 0;
+	uint8_t qos_dscp_sz, dot11_dscp_sz;
+
+	qos_dscp_sz = (sizeof(Qos->dscp_exceptions)/2);
+	dot11_dscp_sz = sizeof(dot11fIE->dscp_exceptions);
+	if (dot11fIE->num_dscp_exceptions > QOS_MAP_LEN_MAX)
+		dot11fIE->num_dscp_exceptions = QOS_MAP_LEN_MAX;
+	if (dot11fIE->num_dscp_exceptions < QOS_MAP_LEN_MIN)
+		return;
+	Qos->num_dscp_exceptions =
+		(dot11fIE->num_dscp_exceptions - QOS_MAP_LEN_MIN) / 2;
+
+	for (i = 0;
+			i < Qos->num_dscp_exceptions &&
+			i < qos_dscp_sz && j < dot11_dscp_sz;
+			i++) {
+		Qos->dscp_exceptions[i][0] = dot11fIE->dscp_exceptions[j];
+		j++;
+		Qos->dscp_exceptions[i][1] = dot11fIE->dscp_exceptions[j];
+		j++;
+	}
+	for (i = 0; i < 8 && j < dot11_dscp_sz; i++) {
+		Qos->dscp_range[i][0] = dot11fIE->dscp_exceptions[j];
+		j++;
+		Qos->dscp_range[i][1] = dot11fIE->dscp_exceptions[j];
+		j++;
+	}
+}
+
+/* utils_parser.c ends here. */
diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h
new file mode 100644
index 0000000..a359c8b
--- /dev/null
+++ b/core/pld/inc/pld_common.h
@@ -0,0 +1,602 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+#ifndef __PLD_COMMON_H__
+#define __PLD_COMMON_H__
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#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"
+#define PLD_OTP_FILE                 "otp.bin"
+#define PLD_SETUP_FILE               "athsetup.bin"
+#define PLD_EPPING_FILE              "epping.bin"
+#define PLD_EVICTED_FILE             ""
+
+#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
+#include <net/cnss_prealloc.h>
+#endif
+
+/**
+ * enum pld_bus_type - bus type
+ * @PLD_BUS_TYPE_NONE: invalid bus type, only return in error cases
+ * @PLD_BUS_TYPE_PCIE: PCIE bus
+ * @PLD_BUS_TYPE_SNOC: SNOC bus
+ */
+enum pld_bus_type {
+	PLD_BUS_TYPE_NONE = -1,
+	PLD_BUS_TYPE_PCIE = 0,
+	PLD_BUS_TYPE_SNOC,
+	PLD_BUS_TYPE_SDIO,
+	PLD_BUS_TYPE_USB
+};
+
+#define PLD_MAX_FIRMWARE_SIZE (1 * 1024 * 1024)
+
+/**
+ * enum pld_bus_width_type - bus bandwidth
+ * @PLD_BUS_WIDTH_NONE: don't vote for bus bandwidth
+ * @PLD_BUS_WIDTH_LOW: vote for low bus bandwidth
+ * @PLD_BUS_WIDTH_MEDIUM: vote for medium bus bandwidth
+ * @PLD_BUS_WIDTH_HIGH: vote for high bus bandwidth
+ */
+enum pld_bus_width_type {
+	PLD_BUS_WIDTH_NONE,
+	PLD_BUS_WIDTH_LOW,
+	PLD_BUS_WIDTH_MEDIUM,
+	PLD_BUS_WIDTH_HIGH
+};
+
+#define PLD_MAX_FILE_NAME NAME_MAX
+
+/**
+ * struct pld_fw_file - WLAN FW file names
+ * @image_file: WLAN FW image file
+ * @board_data: WLAN FW board data file
+ * @otp_data: WLAN FW OTP file
+ * @utf_file: WLAN FW UTF file
+ * @utf_board_data: WLAN FW UTF board data file
+ * @epping_file: WLAN FW EPPING mode file
+ * @evicted_data: WLAN FW evicted file
+ * @setup_file: WLAN FW setup file
+ *
+ * pld_fw_files is used to store WLAN FW file names
+ */
+struct pld_fw_files {
+	char image_file[PLD_MAX_FILE_NAME];
+	char board_data[PLD_MAX_FILE_NAME];
+	char otp_data[PLD_MAX_FILE_NAME];
+	char utf_file[PLD_MAX_FILE_NAME];
+	char utf_board_data[PLD_MAX_FILE_NAME];
+	char epping_file[PLD_MAX_FILE_NAME];
+	char evicted_data[PLD_MAX_FILE_NAME];
+	char setup_file[PLD_MAX_FILE_NAME];
+	char ibss_image_file[PLD_MAX_FILE_NAME];
+};
+
+/**
+ * enum pld_platform_cap_flag - platform capability flag
+ * @PLD_HAS_EXTERNAL_SWREG: has external regulator
+ * @PLD_HAS_UART_ACCESS: has UART access
+ */
+enum pld_platform_cap_flag {
+	PLD_HAS_EXTERNAL_SWREG = 0x01,
+	PLD_HAS_UART_ACCESS = 0x02,
+};
+
+/**
+ * struct pld_platform_cap - platform capabilities
+ * @cap_flag: capabilities flag
+ *
+ * pld_platform_cap provides platform capabilities which are
+ * extracted from DTS.
+ */
+struct pld_platform_cap {
+	u32 cap_flag;
+};
+
+/**
+ * enum pld_uevent - PLD uevent event types
+ * @PLD_FW_DOWN: firmware is down
+ * @PLD_FW_CRASHED: firmware has crashed
+ * @PLD_FW_RECOVERY_START: firmware is starting recovery
+ */
+enum pld_uevent {
+	PLD_FW_DOWN,
+	PLD_FW_CRASHED,
+	PLD_FW_RECOVERY_START,
+};
+
+/**
+ * struct pld_uevent_data - uevent status received from platform driver
+ * @uevent: uevent type
+ * @fw_down: FW down info
+ */
+struct pld_uevent_data {
+	enum pld_uevent uevent;
+	union {
+		struct {
+			bool crashed;
+		} fw_down;
+	};
+};
+
+/**
+ * struct pld_ce_tgt_pipe_cfg - copy engine target pipe configuration
+ * @pipe_num: pipe number
+ * @pipe_dir: pipe direction
+ * @nentries: number of entries
+ * @nbytes_max: max number of bytes
+ * @flags: flags
+ * @reserved: reserved
+ *
+ * pld_ce_tgt_pipe_cfg is used to store copy engine target pipe
+ * configuration.
+ */
+struct pld_ce_tgt_pipe_cfg {
+	u32 pipe_num;
+	u32 pipe_dir;
+	u32 nentries;
+	u32 nbytes_max;
+	u32 flags;
+	u32 reserved;
+};
+
+/**
+ * struct pld_ce_svc_pipe_cfg - copy engine service pipe configuration
+ * @service_id: service ID
+ * @pipe_dir: pipe direction
+ * @pipe_num: pipe number
+ *
+ * pld_ce_svc_pipe_cfg is used to store copy engine service pipe
+ * configuration.
+ */
+struct pld_ce_svc_pipe_cfg {
+	u32 service_id;
+	u32 pipe_dir;
+	u32 pipe_num;
+};
+
+/**
+ * struct pld_shadow_reg_cfg - shadow register configuration
+ * @ce_id: copy engine ID
+ * @reg_offset: register offset
+ *
+ * pld_shadow_reg_cfg is used to store shadow register configuration.
+ */
+struct pld_shadow_reg_cfg {
+	u16 ce_id;
+	u16 reg_offset;
+};
+
+/**
+ * struct pld_shadow_reg_v2_cfg - shadow register version 2 configuration
+ * @addr: shadow register physical address
+ *
+ * pld_shadow_reg_v2_cfg is used to store shadow register version 2
+ * configuration.
+ */
+struct pld_shadow_reg_v2_cfg {
+	u32 addr;
+};
+
+/**
+ * struct pld_wlan_enable_cfg - WLAN FW configuration
+ * @num_ce_tgt_cfg: number of CE target configuration
+ * @ce_tgt_cfg: CE target configuration
+ * @num_ce_svc_pipe_cfg: number of CE service configuration
+ * @ce_svc_cfg: CE service configuration
+ * @num_shadow_reg_cfg: number of shadow register configuration
+ * @shadow_reg_cfg: shadow register configuration
+ * @num_shadow_reg_v2_cfg: number of shadow register version 2 configuration
+ * @shadow_reg_v2_cfg: shadow register version 2 configuration
+ *
+ * pld_wlan_enable_cfg stores WLAN FW configurations. It will be
+ * passed to WLAN FW when WLAN host driver calls wlan_enable.
+ */
+struct pld_wlan_enable_cfg {
+	u32 num_ce_tgt_cfg;
+	struct pld_ce_tgt_pipe_cfg *ce_tgt_cfg;
+	u32 num_ce_svc_pipe_cfg;
+	struct pld_ce_svc_pipe_cfg *ce_svc_cfg;
+	u32 num_shadow_reg_cfg;
+	struct pld_shadow_reg_cfg *shadow_reg_cfg;
+	u32 num_shadow_reg_v2_cfg;
+	struct pld_shadow_reg_v2_cfg *shadow_reg_v2_cfg;
+};
+
+/**
+ * enum pld_driver_mode - WLAN host driver mode
+ * @PLD_MISSION: mission mode
+ * @PLD_FTM: FTM mode
+ * @PLD_EPPING: EPPING mode
+ * @PLD_WALTEST: WAL test mode, FW standalone test mode
+ * @PLD_OFF: OFF mode
+ */
+enum pld_driver_mode {
+	PLD_MISSION,
+	PLD_FTM,
+	PLD_EPPING,
+	PLD_WALTEST,
+	PLD_OFF,
+	PLD_COLDBOOT_CALIBRATION = 7
+};
+
+#define PLD_MAX_TIMESTAMP_LEN 32
+
+/**
+ * struct pld_soc_info - SOC information
+ * @v_addr: virtual address of preallocated memory
+ * @p_addr: physical address of preallcoated memory
+ * @chip_id: chip ID
+ * @chip_family: chip family
+ * @board_id: board ID
+ * @soc_id: SOC ID
+ * @fw_version: FW version
+ * @fw_build_timestamp: FW build timestamp
+ *
+ * pld_soc_info is used to store WLAN SOC information.
+ */
+struct pld_soc_info {
+	void __iomem *v_addr;
+	phys_addr_t p_addr;
+	u32 chip_id;
+	u32 chip_family;
+	u32 board_id;
+	u32 soc_id;
+	u32 fw_version;
+	char fw_build_timestamp[PLD_MAX_TIMESTAMP_LEN + 1];
+};
+
+/**
+ * enum pld_recovery_reason - WLAN host driver recovery reason
+ * @PLD_REASON_DEFAULT: default
+ * @PLD_REASON_LINK_DOWN: PCIe link down
+ */
+enum pld_recovery_reason {
+	PLD_REASON_DEFAULT,
+	PLD_REASON_LINK_DOWN
+};
+
+/**
+ * struct pld_driver_ops - driver callback functions
+ * @probe: required operation, will be called when device is detected
+ * @remove: required operation, will be called when device is removed
+ * @shutdown: optional operation, will be called during SSR
+ * @reinit: optional operation, will be called during SSR
+ * @crash_shutdown: optional operation, will be called when a crash is
+ *                  detected
+ * @suspend: required operation, will be called for power management
+ *           is enabled
+ * @resume: required operation, will be called for power management
+ *          is enabled
+ * @modem_status: optional operation, will be called when platform driver
+ *                sending modem power status to WLAN FW
+ * @uevent: optional operation, will be called when platform driver
+ *                 updating driver status
+ * @runtime_suspend: optional operation, prepare the device for a condition
+ *                   in which it won't be able to communicate with the CPU(s)
+ *                   and RAM due to power management.
+ * @runtime_resume: optional operation, put the device into the fully
+ *                  active state in response to a wakeup event generated by
+ *                  hardware or at the request of software.
+ * @suspend_noirq: optional operation, complete the actions started by suspend()
+ * @resume_noirq: optional operation, prepare for the execution of resume()
+ */
+struct pld_driver_ops {
+	int (*probe)(struct device *dev,
+		     enum pld_bus_type bus_type,
+		     void *bdev, void *id);
+	void (*remove)(struct device *dev,
+		       enum pld_bus_type bus_type);
+	void (*shutdown)(struct device *dev,
+			 enum pld_bus_type bus_type);
+	int (*reinit)(struct device *dev,
+		      enum pld_bus_type bus_type,
+		      void *bdev, void *id);
+	void (*crash_shutdown)(struct device *dev,
+			       enum pld_bus_type bus_type);
+	int (*suspend)(struct device *dev,
+		       enum pld_bus_type bus_type,
+		       pm_message_t state);
+	int (*resume)(struct device *dev,
+		      enum pld_bus_type bus_type);
+	int (*reset_resume)(struct device *dev,
+		      enum pld_bus_type bus_type);
+	void (*modem_status)(struct device *dev,
+			     enum pld_bus_type bus_type,
+			     int state);
+	void (*uevent)(struct device *dev, struct pld_uevent_data *uevent);
+	int (*runtime_suspend)(struct device *dev,
+			       enum pld_bus_type bus_type);
+	int (*runtime_resume)(struct device *dev,
+			      enum pld_bus_type bus_type);
+	int (*suspend_noirq)(struct device *dev,
+			     enum pld_bus_type bus_type);
+	int (*resume_noirq)(struct device *dev,
+			    enum pld_bus_type bus_type);
+};
+
+int pld_init(void);
+void pld_deinit(void);
+
+int pld_register_driver(struct pld_driver_ops *ops);
+void pld_unregister_driver(void);
+
+int pld_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
+		    enum pld_driver_mode mode, const char *host_version);
+int pld_wlan_disable(struct device *dev, enum pld_driver_mode mode);
+int pld_set_fw_log_mode(struct device *dev, u8 fw_log_mode);
+void pld_get_default_fw_files(struct pld_fw_files *pfw_files);
+int pld_get_fw_files_for_target(struct device *dev,
+				struct pld_fw_files *pfw_files,
+				u32 target_type, u32 target_version);
+void pld_is_pci_link_down(struct device *dev);
+int pld_shadow_control(struct device *dev, bool enable);
+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);
+void pld_device_self_recovery(struct device *dev,
+			      enum pld_recovery_reason reason);
+void pld_intr_notify_q6(struct device *dev);
+void pld_request_pm_qos(struct device *dev, u32 qos_val);
+void pld_remove_pm_qos(struct device *dev);
+int pld_request_bus_bandwidth(struct device *dev, int bandwidth);
+int pld_get_platform_cap(struct device *dev, struct pld_platform_cap *cap);
+int pld_get_sha_hash(struct device *dev, const u8 *data,
+		     u32 data_len, u8 *hash_idx, u8 *out);
+void *pld_get_fw_ptr(struct device *dev);
+int pld_auto_suspend(struct device *dev);
+int pld_auto_resume(struct device *dev);
+int pld_force_wake_request(struct device *dev);
+int pld_is_device_awake(struct device *dev);
+int pld_force_wake_release(struct device *dev);
+int pld_ce_request_irq(struct device *dev, unsigned int ce_id,
+		       irqreturn_t (*handler)(int, void *),
+		       unsigned long flags, const char *name, void *ctx);
+int pld_ce_free_irq(struct device *dev, unsigned int ce_id, void *ctx);
+void pld_enable_irq(struct device *dev, unsigned int ce_id);
+void pld_disable_irq(struct device *dev, unsigned int ce_id);
+int pld_get_soc_info(struct device *dev, struct pld_soc_info *info);
+int pld_get_ce_id(struct device *dev, int irq);
+int pld_get_irq(struct device *dev, int ce_id);
+void pld_lock_pm_sem(struct device *dev);
+void pld_release_pm_sem(struct device *dev);
+int pld_power_on(struct device *dev);
+int pld_power_off(struct device *dev);
+int pld_athdiag_read(struct device *dev, uint32_t offset, uint32_t memtype,
+		     uint32_t datalen, uint8_t *output);
+int pld_athdiag_write(struct device *dev, uint32_t offset, uint32_t memtype,
+		      uint32_t datalen, uint8_t *input);
+void *pld_smmu_get_mapping(struct device *dev);
+int pld_smmu_map(struct device *dev, phys_addr_t paddr,
+		 uint32_t *iova_addr, size_t size);
+int pld_get_user_msi_assignment(struct device *dev, char *user_name,
+				int *num_vectors, uint32_t *user_base_data,
+				uint32_t *base_vector);
+int pld_get_msi_irq(struct device *dev, unsigned int vector);
+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);
+int pld_is_qmi_disable(struct device *dev);
+int pld_is_fw_down(struct device *dev);
+int pld_force_assert_target(struct device *dev);
+bool pld_is_fw_dump_skipped(struct device *dev);
+
+/**
+ * pld_is_fw_rejuvenate() - Check WLAN fw is rejuvenating
+ *
+ * Help the driver decide whether FW down is due to
+ * SSR or FW rejuvenate.
+ *
+ * Return: 1 FW is rejuvenating
+ *         0 FW is not rejuvenating
+ */
+int pld_is_fw_rejuvenate(struct device *dev);
+
+#if defined(CONFIG_WCNSS_MEM_PRE_ALLOC) && defined(FEATURE_SKB_PRE_ALLOC)
+
+/**
+ * pld_nbuf_pre_alloc() - get allocated nbuf from platform driver.
+ * @size: Netbuf requested size
+ *
+ * Return: nbuf or NULL if no memory
+ */
+static inline struct sk_buff *pld_nbuf_pre_alloc(size_t size)
+{
+	struct sk_buff *skb = NULL;
+
+	if (size >= WCNSS_PRE_SKB_ALLOC_GET_THRESHOLD)
+		skb = wcnss_skb_prealloc_get(size);
+
+	return skb;
+}
+
+/**
+ * pld_nbuf_pre_alloc_free() - free the nbuf allocated in platform driver.
+ * @skb: Pointer to network buffer
+ *
+ * Return: TRUE if the nbuf is freed
+ */
+static inline int pld_nbuf_pre_alloc_free(struct sk_buff *skb)
+{
+	return wcnss_skb_prealloc_put(skb);
+}
+#else
+static inline struct sk_buff *pld_nbuf_pre_alloc(size_t size)
+{
+	return NULL;
+}
+static inline int pld_nbuf_pre_alloc_free(struct sk_buff *skb)
+{
+	return 0;
+}
+#endif
+#endif
diff --git a/core/pld/src/pld_common.c b/core/pld/src/pld_common.c
new file mode 100644
index 0000000..a2b2972
--- /dev/null
+++ b/core/pld/src/pld_common.c
@@ -0,0 +1,1662 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+#define pr_fmt(fmt) "wlan_pld:%s:%d:: " fmt, __func__, __LINE__
+
+#include <linux/printk.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+#include <net/cnss.h>
+#endif
+#ifdef CONFIG_PLD_PCIE_CNSS
+#include <net/cnss2.h>
+#endif
+#ifdef CONFIG_PLD_SNOC_ICNSS
+#include <soc/qcom/icnss.h>
+#endif
+
+#include "pld_pcie.h"
+#include "pld_snoc.h"
+#include "pld_sdio.h"
+#include "pld_usb.h"
+
+#define PLD_PCIE_REGISTERED BIT(0)
+#define PLD_SNOC_REGISTERED BIT(1)
+#define PLD_SDIO_REGISTERED BIT(2)
+#define PLD_USB_REGISTERED BIT(3)
+#define PLD_BUS_MASK 0xf
+
+static struct pld_context *pld_ctx;
+
+/**
+ * pld_init() - Initialize PLD module
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_init(void)
+{
+	struct pld_context *pld_context;
+
+	pld_context = kzalloc(sizeof(*pld_context), GFP_KERNEL);
+	if (!pld_context)
+		return -ENOMEM;
+
+	spin_lock_init(&pld_context->pld_lock);
+
+	INIT_LIST_HEAD(&pld_context->dev_list);
+
+	pld_ctx = pld_context;
+
+	return 0;
+}
+
+/**
+ * pld_deinit() - Uninitialize PLD module
+ *
+ * Return: void
+ */
+void pld_deinit(void)
+{
+	struct dev_node *dev_node;
+	struct pld_context *pld_context;
+	unsigned long flags;
+
+	pld_context = pld_ctx;
+	if (!pld_context) {
+		pld_ctx = NULL;
+		return;
+	}
+
+	spin_lock_irqsave(&pld_context->pld_lock, flags);
+	while (!list_empty(&pld_context->dev_list)) {
+		dev_node = list_first_entry(&pld_context->dev_list,
+					    struct dev_node, list);
+		list_del(&dev_node->list);
+		kfree(dev_node);
+	}
+	spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+
+	kfree(pld_context);
+
+	pld_ctx = NULL;
+}
+
+/**
+ * pld_get_global_context() - Get global context of PLD
+ *
+ * Return: PLD global context
+ */
+struct pld_context *pld_get_global_context(void)
+{
+	return pld_ctx;
+}
+
+/**
+ * pld_add_dev() - Add dev node to global context
+ * @pld_context: PLD global context
+ * @dev: device
+ * @type: Bus type
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_add_dev(struct pld_context *pld_context,
+		struct device *dev, enum pld_bus_type type)
+{
+	unsigned long flags;
+	struct dev_node *dev_node;
+
+	dev_node = kzalloc(sizeof(*dev_node), GFP_KERNEL);
+	if (dev_node == NULL)
+		return -ENOMEM;
+
+	dev_node->dev = dev;
+	dev_node->bus_type = type;
+
+	spin_lock_irqsave(&pld_context->pld_lock, flags);
+	list_add_tail(&dev_node->list, &pld_context->dev_list);
+	spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+
+	return 0;
+}
+
+/**
+ * pld_del_dev() - Delete dev node from global context
+ * @pld_context: PLD global context
+ * @dev: device
+ *
+ * Return: void
+ */
+void pld_del_dev(struct pld_context *pld_context,
+		 struct device *dev)
+{
+	unsigned long flags;
+	struct dev_node *dev_node, *tmp;
+
+	spin_lock_irqsave(&pld_context->pld_lock, flags);
+	list_for_each_entry_safe(dev_node, tmp, &pld_context->dev_list, list) {
+		if (dev_node->dev == dev) {
+			list_del(&dev_node->list);
+			kfree(dev_node);
+		}
+	}
+	spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+}
+
+/**
+ * pld_get_bus_type() - Bus type of the device
+ * @dev: device
+ *
+ * Return: PLD bus type
+ */
+static enum pld_bus_type pld_get_bus_type(struct device *dev)
+{
+	struct pld_context *pld_context;
+	struct dev_node *dev_node;
+	unsigned long flags;
+
+	pld_context = pld_get_global_context();
+
+	if (dev == NULL || pld_context == NULL) {
+		pr_err("Invalid info: dev %pK, context %pK\n",
+		       dev, pld_context);
+		return PLD_BUS_TYPE_NONE;
+	}
+
+	spin_lock_irqsave(&pld_context->pld_lock, flags);
+	list_for_each_entry(dev_node, &pld_context->dev_list, list) {
+		if (dev_node->dev == dev) {
+			spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+			return dev_node->bus_type;
+		}
+	}
+	spin_unlock_irqrestore(&pld_context->pld_lock, flags);
+
+	return PLD_BUS_TYPE_NONE;
+}
+
+/**
+ * pld_register_driver() - Register driver to kernel
+ * @ops: Callback functions that will be registered to kernel
+ *
+ * This function should be called when other modules want to
+ * register platform driver callback functions to kernel. The
+ * probe() is expected to be called after registration if the
+ * device is online.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_register_driver(struct pld_driver_ops *ops)
+{
+	int ret = 0;
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+
+	if (pld_context == NULL) {
+		pr_err("global context is NULL\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (pld_context->ops) {
+		pr_err("driver already registered\n");
+		ret = -EEXIST;
+		goto out;
+	}
+
+	if (!ops || !ops->probe || !ops->remove ||
+	    !ops->suspend || !ops->resume) {
+		pr_err("Required callback functions are missing\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	pld_context->ops = ops;
+	pld_context->pld_driver_state = 0;
+
+	ret = pld_pcie_register_driver();
+	if (ret) {
+		pr_err("Fail to register pcie driver\n");
+		goto fail_pcie;
+	}
+	pld_context->pld_driver_state |= PLD_PCIE_REGISTERED;
+
+	ret = pld_snoc_register_driver();
+	if (ret) {
+		pr_err("Fail to register snoc driver\n");
+		goto fail_snoc;
+	}
+	pld_context->pld_driver_state |= PLD_SNOC_REGISTERED;
+
+	ret = pld_sdio_register_driver();
+	if (ret) {
+		pr_err("Fail to register sdio driver\n");
+		goto fail_sdio;
+	}
+	pld_context->pld_driver_state |= PLD_SDIO_REGISTERED;
+
+	ret = pld_usb_register_driver();
+	if (ret) {
+		pr_err("Fail to register usb driver\n");
+		goto fail_usb;
+	}
+	pld_context->pld_driver_state |= PLD_USB_REGISTERED;
+
+	return ret;
+
+fail_usb:
+	pld_sdio_unregister_driver();
+fail_sdio:
+	pld_snoc_unregister_driver();
+fail_snoc:
+	pld_pcie_unregister_driver();
+fail_pcie:
+	pld_context->pld_driver_state = 0;
+	pld_context->ops = NULL;
+out:
+	return ret;
+}
+
+/**
+ * pld_unregister_driver() - Unregister driver to kernel
+ *
+ * This function should be called when other modules want to
+ * unregister callback functions from kernel. The remove() is
+ * expected to be called after registration.
+ *
+ * Return: void
+ */
+void pld_unregister_driver(void)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+
+	if (pld_context == NULL) {
+		pr_err("global context is NULL\n");
+		return;
+	}
+
+	if (pld_context->ops == NULL) {
+		pr_err("driver not registered\n");
+		return;
+	}
+
+	pld_pcie_unregister_driver();
+	pld_snoc_unregister_driver();
+	pld_sdio_unregister_driver();
+	pld_usb_unregister_driver();
+
+	pld_context->pld_driver_state = 0;
+
+	pld_context->ops = NULL;
+}
+
+/**
+ * pld_wlan_enable() - Enable WLAN
+ * @dev: device
+ * @config: WLAN configuration data
+ * @mode: WLAN mode
+ * @host_version: host software version
+ *
+ * This function enables WLAN FW. It passed WLAN configuration data,
+ * WLAN mode and host software version to FW.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
+		    enum pld_driver_mode mode, const char *host_version)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_wlan_enable(dev, config, mode, host_version);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_wlan_enable(dev, config, mode, host_version);
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	case PLD_BUS_TYPE_USB:
+		ret = pld_usb_wlan_enable(dev, config, mode, host_version);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_wlan_disable() - Disable WLAN
+ * @dev: device
+ * @mode: WLAN mode
+ *
+ * This function disables WLAN FW. It passes WLAN mode to FW.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_wlan_disable(struct device *dev, enum pld_driver_mode mode)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_wlan_disable(dev, mode);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_wlan_disable(dev, mode);
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_set_fw_log_mode() - Set FW debug log mode
+ * @dev: device
+ * @fw_log_mode: 0 for No log, 1 for WMI, 2 for DIAG
+ *
+ * Switch Fw debug log mode between DIAG logging and WMI logging.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_set_fw_log_mode(dev, fw_log_mode);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_set_fw_log_mode(dev, fw_log_mode);
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_get_default_fw_files() - Get default FW file names
+ * @pfw_files: buffer for FW file names
+ *
+ * Return default FW file names to the buffer.
+ *
+ * Return: void
+ */
+void pld_get_default_fw_files(struct pld_fw_files *pfw_files)
+{
+	memset(pfw_files, 0, sizeof(*pfw_files));
+
+	strlcpy(pfw_files->image_file, PREFIX PLD_IMAGE_FILE,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->board_data, PREFIX PLD_BOARD_DATA_FILE,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->otp_data, PREFIX PLD_OTP_FILE,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->utf_file, PREFIX PLD_UTF_FIRMWARE_FILE,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->utf_board_data, PREFIX PLD_BOARD_DATA_FILE,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->epping_file, PREFIX PLD_EPPING_FILE,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->setup_file, PREFIX PLD_SETUP_FILE,
+		PLD_MAX_FILE_NAME);
+}
+
+/**
+ * pld_get_fw_files_for_target() - Get FW file names
+ * @dev: device
+ * @pfw_files: buffer for FW file names
+ * @target_type: target type
+ * @target_version: target version
+ *
+ * Return target specific FW file names to the buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_get_fw_files_for_target(struct device *dev,
+				struct pld_fw_files *pfw_files,
+				u32 target_type, u32 target_version)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_get_fw_files_for_target(dev, pfw_files,
+						       target_type,
+						       target_version);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		ret = pld_sdio_get_fw_files_for_target(pfw_files,
+						       target_type,
+						       target_version);
+		break;
+	case PLD_BUS_TYPE_USB:
+	ret = pld_usb_get_fw_files_for_target(pfw_files,
+					      target_type,
+					      target_version);
+	break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_is_pci_link_down() - Notification for pci link down event
+ * @dev: device
+ *
+ * Notify platform that pci link is down.
+ *
+ * Return: void
+ */
+void pld_is_pci_link_down(struct device *dev)
+{
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		pld_pcie_link_down(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+}
+
+/**
+ * pld_schedule_recovery_work() - Schedule recovery work
+ * @dev: device
+ * @reason: recovery reason
+ *
+ * Schedule a system self recovery work.
+ *
+ * Return: void
+ */
+void pld_schedule_recovery_work(struct device *dev,
+				enum pld_recovery_reason reason)
+{
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		pld_pcie_schedule_recovery_work(dev, reason);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+}
+
+/**
+ * pld_wlan_pm_control() - WLAN PM control on PCIE
+ * @dev: device
+ * @vote: 0 for enable PCIE PC, 1 for disable PCIE PC
+ *
+ * This is for PCIE power collaps control during suspend/resume.
+ * When PCIE power collaps is disabled, WLAN FW can access memory
+ * through PCIE when system is suspended.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_wlan_pm_control(struct device *dev, bool vote)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_wlan_pm_control(dev, vote);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_get_virt_ramdump_mem() - Get virtual ramdump memory
+ * @dev: device
+ * @size: buffer to virtual memory size
+ *
+ * Return: virtual ramdump memory address
+ */
+void *pld_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
+{
+	void *mem = NULL;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		mem = pld_pcie_get_virt_ramdump_mem(dev, size);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		mem = pld_sdio_get_virt_ramdump_mem(dev, size);
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+
+	return mem;
+}
+
+/**
+ * pld_device_crashed() - Notification for device crash event
+ * @dev: device
+ *
+ * Notify subsystem a device crashed event. A subsystem restart
+ * is expected to happen after calling this function.
+ *
+ * Return: void
+ */
+void pld_device_crashed(struct device *dev)
+{
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		pld_pcie_device_crashed(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		pld_sdio_device_crashed(dev);
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+}
+
+/**
+ * pld_device_self_recovery() - Device self recovery
+ * @dev: device
+ * @reason: recovery reason
+ *
+ * Return: void
+ */
+void pld_device_self_recovery(struct device *dev,
+			      enum pld_recovery_reason reason)
+{
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		pld_pcie_device_self_recovery(dev, reason);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		pld_sdio_device_self_recovery(dev);
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+}
+
+/**
+ * pld_intr_notify_q6() - Notify Q6 FW interrupts
+ * @dev: device
+ *
+ * Notify Q6 that a FW interrupt is triggered.
+ *
+ * Return: void
+ */
+void pld_intr_notify_q6(struct device *dev)
+{
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		pld_pcie_intr_notify_q6(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+}
+
+/**
+ * pld_request_pm_qos() - Request system PM
+ * @dev: device
+ * @qos_val: request value
+ *
+ * It votes for the value of aggregate QoS expectations.
+ *
+ * Return: void
+ */
+void pld_request_pm_qos(struct device *dev, u32 qos_val)
+{
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		pld_pcie_request_pm_qos(dev, qos_val);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		/* To do Add call cns API */
+		break;
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+}
+
+/**
+ * pld_remove_pm_qos() - Remove system PM
+ * @dev: device
+ *
+ * Remove the vote request for Qos expectations.
+ *
+ * Return: void
+ */
+void pld_remove_pm_qos(struct device *dev)
+{
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		pld_pcie_remove_pm_qos(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		/* To do Add call cns API */
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+}
+
+/**
+ * pld_request_bus_bandwidth() - Request bus bandwidth
+ * @dev: device
+ * @bandwidth: bus bandwidth
+ *
+ * Votes for HIGH/MEDIUM/LOW bus bandwidth.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_request_bus_bandwidth(struct device *dev, int bandwidth)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_request_bus_bandwidth(dev, bandwidth);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		/* To do Add call cns API */
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_get_platform_cap() - Get platform capabilities
+ * @dev: device
+ * @cap: buffer to the capabilities
+ *
+ * Return capabilities to the buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_get_platform_cap(struct device *dev, struct pld_platform_cap *cap)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_get_platform_cap(dev, cap);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_get_sha_hash() - Get sha hash number
+ * @dev: device
+ * @data: input data
+ * @data_len: data length
+ * @hash_idx: hash index
+ * @out:  output buffer
+ *
+ * Return computed hash to the out buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_get_sha_hash(struct device *dev, const u8 *data,
+		     u32 data_len, u8 *hash_idx, u8 *out)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_get_sha_hash(dev, data, data_len,
+					    hash_idx, out);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_get_fw_ptr() - Get secure FW memory address
+ * @dev: device
+ *
+ * Return: secure memory address
+ */
+void *pld_get_fw_ptr(struct device *dev)
+{
+	void *ptr = NULL;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ptr = pld_pcie_get_fw_ptr(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+
+	return ptr;
+}
+
+/**
+ * pld_auto_suspend() - Auto suspend
+ * @dev: device
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_auto_suspend(struct device *dev)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_auto_suspend(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_auto_resume() - Auto resume
+ * @dev: device
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_auto_resume(struct device *dev)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_auto_resume(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_force_wake_request() - Request vote to assert WAKE register
+ * @dev: device
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_force_wake_request(struct device *dev)
+{
+	int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_force_wake_request(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_is_device_awake() - Check if it's ready to access MMIO registers
+ * @dev: device
+ *
+ * Return: True for device awake
+ *         False for device not awake
+ *         Negative failure code for errors
+ */
+int pld_is_device_awake(struct device *dev)
+{
+	int ret = true;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_is_device_awake(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_force_wake_release() - Release vote to assert WAKE register
+ * @dev: device
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_force_wake_release(struct device *dev)
+{
+	int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_force_wake_release(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_ce_request_irq() - Register IRQ for CE
+ * @dev: device
+ * @ce_id: CE number
+ * @handler: IRQ callback function
+ * @flags: IRQ flags
+ * @name: IRQ name
+ * @ctx: IRQ context
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_ce_request_irq(struct device *dev, unsigned int ce_id,
+		       irqreturn_t (*handler)(int, void *),
+		       unsigned long flags, const char *name, void *ctx)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_ce_request_irq(dev, ce_id,
+					      handler, flags, name, ctx);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_ce_free_irq() - Free IRQ for CE
+ * @dev: device
+ * @ce_id: CE number
+ * @ctx: IRQ context
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_ce_free_irq(struct device *dev, unsigned int ce_id, void *ctx)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_ce_free_irq(dev, ce_id, ctx);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_enable_irq() - Enable IRQ for CE
+ * @dev: device
+ * @ce_id: CE number
+ *
+ * Return: void
+ */
+void pld_enable_irq(struct device *dev, unsigned int ce_id)
+{
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_SNOC:
+		pld_snoc_enable_irq(dev, ce_id);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+}
+
+/**
+ * pld_disable_irq() - Disable IRQ for CE
+ * @dev: device
+ * @ce_id: CE number
+ *
+ * Return: void
+ */
+void pld_disable_irq(struct device *dev, unsigned int ce_id)
+{
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_SNOC:
+		pld_snoc_disable_irq(dev, ce_id);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+}
+
+/**
+ * pld_get_soc_info() - Get SOC information
+ * @dev: device
+ * @info: buffer to SOC information
+ *
+ * Return SOC info to the buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_get_soc_info(struct device *dev, struct pld_soc_info *info)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_get_soc_info(dev, info);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_get_soc_info(dev, info);
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_get_ce_id() - Get CE number for the provided IRQ
+ * @dev: device
+ * @irq: IRQ number
+ *
+ * Return: CE number
+ */
+int pld_get_ce_id(struct device *dev, int irq)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_get_ce_id(dev, irq);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_get_ce_id(dev, irq);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_get_irq() - Get IRQ number for given CE ID
+ * @dev: device
+ * @ce_id: CE ID
+ *
+ * Return: IRQ number
+ */
+int pld_get_irq(struct device *dev, int ce_id)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_get_irq(dev, ce_id);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_lock_pm_sem() - Lock PM semaphore
+ * @dev: device
+ *
+ * Return: void
+ */
+void pld_lock_pm_sem(struct device *dev)
+{
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		pld_pcie_lock_pm_sem(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+}
+
+/**
+ * pld_release_pm_sem() - Release PM semaphore
+ * @dev: device
+ *
+ * Return: void
+ */
+void pld_release_pm_sem(struct device *dev)
+{
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		pld_pcie_release_pm_sem(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+}
+
+/**
+ * pld_power_on() - Power on WLAN hardware
+ * @dev: device
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_power_on(struct device *dev)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_power_on(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_power_on(dev);
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_power_off() - Power off WLAN hardware
+ * @dev: device
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_power_off(struct device *dev)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_power_off(dev);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_power_off(dev);
+		break;
+	default:
+		pr_err("Invalid device type\n");
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_athdiag_read() - Read data from WLAN FW
+ * @dev: device
+ * @offset: address offset
+ * @memtype: memory type
+ * @datalen: data length
+ * @output: output buffer
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_athdiag_read(struct device *dev, uint32_t offset,
+		     uint32_t memtype, uint32_t datalen,
+		     uint8_t *output)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_athdiag_read(dev, offset, memtype,
+					    datalen, output);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_athdiag_read(dev, offset, memtype,
+					    datalen, output);
+		break;
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_athdiag_write() - Write data to WLAN FW
+ * @dev: device
+ * @offset: address offset
+ * @memtype: memory type
+ * @datalen: data length
+ * @input: input buffer
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_athdiag_write(struct device *dev, uint32_t offset,
+		      uint32_t memtype, uint32_t datalen,
+		      uint8_t *input)
+{
+	int ret = 0;
+
+	switch (pld_get_bus_type(dev)) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_athdiag_write(dev, offset, memtype,
+					     datalen, input);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_athdiag_write(dev, offset, memtype,
+					     datalen, input);
+		break;
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_smmu_get_mapping() - Get SMMU mapping context
+ * @dev: device
+ *
+ * Return: Pointer to the mapping context
+ */
+void *pld_smmu_get_mapping(struct device *dev)
+{
+	void *ptr = NULL;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_SNOC:
+		ptr = pld_snoc_smmu_get_mapping(dev);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		pr_err("Not supported on type %d\n", type);
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		break;
+	}
+
+	return ptr;
+}
+
+/**
+ * pld_smmu_map() - Map SMMU
+ * @dev: device
+ * @paddr: physical address that needs to map to
+ * @iova_addr: IOVA address
+ * @size: size to be mapped
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_smmu_map(struct device *dev, phys_addr_t paddr,
+		 uint32_t *iova_addr, size_t size)
+{
+	int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_smmu_map(dev, paddr, iova_addr, size);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		pr_err("Not supported on type %d\n", type);
+		ret = -ENODEV;
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_get_user_msi_assignment() - Get MSI assignment information
+ * @dev: device structure
+ * @user_name: name of the user who requests the MSI assignment
+ * @num_vectors: number of the MSI vectors assigned for the user
+ * @user_base_data: MSI base data assigned for the user, this equals to
+ *                  endpoint base data from config space plus base vector
+ * @base_vector: base MSI vector (offset) number assigned for the user
+ *
+ * Return: 0 for success
+ *         Negative failure code for errors
+ */
+int pld_get_user_msi_assignment(struct device *dev, char *user_name,
+				int *num_vectors, uint32_t *user_base_data,
+				uint32_t *base_vector)
+{
+	int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_get_user_msi_assignment(dev, user_name,
+						       num_vectors,
+						       user_base_data,
+						       base_vector);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		pr_err("Not supported on type %d\n", type);
+		ret = -ENODEV;
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_get_msi_irq() - Get MSI IRQ number used for request_irq()
+ * @dev: device structure
+ * @vector: MSI vector (offset) number
+ *
+ * Return: Positive IRQ number for success
+ *         Negative failure code for errors
+ */
+int pld_get_msi_irq(struct device *dev, unsigned int vector)
+{
+	int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_get_msi_irq(dev, vector);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		pr_err("Not supported on type %d\n", type);
+		ret = -ENODEV;
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_get_msi_address() - Get the MSI address
+ * @dev: device structure
+ * @msi_addr_low: lower 32-bit of the address
+ * @msi_addr_high: higher 32-bit of the address
+ *
+ * Return: Void
+ */
+void pld_get_msi_address(struct device *dev, uint32_t *msi_addr_low,
+			 uint32_t *msi_addr_high)
+{
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_PCIE:
+		pld_pcie_get_msi_address(dev, msi_addr_low, msi_addr_high);
+		break;
+	case PLD_BUS_TYPE_SNOC:
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		pr_err("Not supported on type %d\n", type);
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		break;
+	}
+}
+
+/**
+ * pld_socinfo_get_serial_number() - Get SOC serial number
+ * @dev: device
+ *
+ * Return: SOC serial number
+ */
+unsigned int pld_socinfo_get_serial_number(struct device *dev)
+{
+	unsigned int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_socinfo_get_serial_number(dev);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		pr_err("Not supported on type %d\n", type);
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_is_qmi_disable() - Check QMI support is present or not
+ * @dev: device
+ *
+ *  Return: 1 QMI is not supported
+ *          0 QMI is supported
+ *          Non zero failure code for errors
+ */
+int pld_is_qmi_disable(struct device *dev)
+{
+	int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_is_qmi_disable(dev);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+	case PLD_BUS_TYPE_SDIO:
+		pr_err("Not supported on type %d\n", type);
+		ret = -EINVAL;
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_is_fw_down() - Check WLAN fw is down or not
+ *
+ * @dev: device
+ *
+ * This API will be called to check if WLAN FW is down or not.
+ *
+ *  Return: 1 FW is down
+ *          0 FW is not down
+ *          Always return 0 for unsupported bus type
+ */
+int pld_is_fw_down(struct device *dev)
+{
+	int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_is_fw_down(dev);
+		break;
+	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_is_fw_down(dev);
+		break;
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pld_force_assert_target() - Send a force assert to FW.
+ * This can use various sideband requests available at platform to
+ * initiate a FW assert.
+ * @dev: device
+ *
+ *  Return: 0 if force assert of target was triggered successfully
+ *          Non zero failure code for errors
+ */
+int pld_force_assert_target(struct device *dev)
+{
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_SNOC:
+		return pld_snoc_force_assert_target(dev);
+	case PLD_BUS_TYPE_PCIE:
+		return pld_pcie_force_assert_target(dev);
+	case PLD_BUS_TYPE_SDIO:
+		return -EINVAL;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		return -EINVAL;
+	}
+}
+
+/**
+ * pld_is_fw_dump_skipped() - get fw dump skipped status.
+ *  The subsys ssr status help the driver to decide whether to skip
+ *  the FW memory dump when FW assert.
+ *  For SDIO case, the memory dump progress takes 1 minutes to
+ *  complete, which is not acceptable in SSR enabled.
+ *
+ *  Return: true if need to skip FW dump.
+ */
+bool pld_is_fw_dump_skipped(struct device *dev)
+{
+	bool ret = false;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_SDIO:
+		ret = pld_sdio_is_fw_dump_skipped();
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+int pld_is_fw_rejuvenate(struct device *dev)
+{
+	int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_SNOC:
+		ret = pld_snoc_is_fw_rejuvenate();
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
diff --git a/core/pld/src/pld_internal.h b/core/pld/src/pld_internal.h
new file mode 100644
index 0000000..833c163
--- /dev/null
+++ b/core/pld/src/pld_internal.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 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.
+ */
+
+#ifndef __PLD_COMMON_I_H__
+#define __PLD_COMMON_I_H__
+
+#include "pld_common.h"
+
+struct dev_node {
+	struct device *dev;
+	struct list_head list;
+	enum pld_bus_type bus_type;
+};
+
+struct pld_context {
+	struct pld_driver_ops *ops;
+	spinlock_t pld_lock;
+	struct list_head dev_list;
+	uint32_t pld_driver_state;
+};
+
+struct pld_context *pld_get_global_context(void);
+int pld_add_dev(struct pld_context *pld_context,
+		struct device *dev, enum pld_bus_type type);
+void pld_del_dev(struct pld_context *pld_context,
+		 struct device *dev);
+
+#endif
diff --git a/core/pld/src/pld_pcie.c b/core/pld/src/pld_pcie.c
new file mode 100644
index 0000000..c9d658b
--- /dev/null
+++ b/core/pld/src/pld_pcie.c
@@ -0,0 +1,763 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_PLD_PCIE_CNSS
+#include <net/cnss2.h>
+#endif
+
+#include "pld_internal.h"
+#include "pld_pcie.h"
+
+#ifdef CONFIG_PCI
+
+#ifdef QCA_WIFI_3_0_ADRASTEA
+#define CE_COUNT_MAX 12
+#else
+#define CE_COUNT_MAX 8
+#endif
+
+/**
+ * pld_pcie_probe() - Probe function for PCIE platform driver
+ * @pdev: PCIE device
+ * @id: PCIE device ID table
+ *
+ * The probe function will be called when PCIE device provided
+ * in the ID table is detected.
+ *
+ * Return: int
+ */
+static int pld_pcie_probe(struct pci_dev *pdev,
+			  const struct pci_device_id *id)
+{
+	struct pld_context *pld_context;
+	int ret = 0;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	ret = pld_add_dev(pld_context, &pdev->dev, PLD_BUS_TYPE_PCIE);
+	if (ret)
+		goto out;
+
+	return pld_context->ops->probe(&pdev->dev,
+		       PLD_BUS_TYPE_PCIE, pdev, (void *)id);
+
+out:
+	return ret;
+}
+
+
+/**
+ * pld_pcie_remove() - Remove function for PCIE device
+ * @pdev: PCIE device
+ *
+ * The remove function will be called when PCIE device is disconnected
+ *
+ * Return: void
+ */
+static void pld_pcie_remove(struct pci_dev *pdev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+
+	if (!pld_context)
+		return;
+
+	pld_context->ops->remove(&pdev->dev, PLD_BUS_TYPE_PCIE);
+
+	pld_del_dev(pld_context, &pdev->dev);
+}
+
+#ifdef CONFIG_PLD_PCIE_CNSS
+/**
+ * pld_pcie_reinit() - SSR re-initialize function for PCIE device
+ * @pdev: PCIE device
+ * @id: PCIE device ID
+ *
+ * During subsystem restart(SSR), this function will be called to
+ * re-initialize PCIE device.
+ *
+ * Return: int
+ */
+static int pld_pcie_reinit(struct pci_dev *pdev,
+			    const struct pci_device_id *id)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->reinit)
+		return pld_context->ops->reinit(&pdev->dev,
+				PLD_BUS_TYPE_PCIE, pdev, (void *)id);
+
+	return -ENODEV;
+}
+
+/**
+ * pld_pcie_shutdown() - SSR shutdown function for PCIE device
+ * @pdev: PCIE device
+ *
+ * During SSR, this function will be called to shutdown PCIE device.
+ *
+ * Return: void
+ */
+static void pld_pcie_shutdown(struct pci_dev *pdev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->shutdown)
+		pld_context->ops->shutdown(&pdev->dev, PLD_BUS_TYPE_PCIE);
+}
+
+/**
+ * pld_pcie_crash_shutdown() - Crash shutdown function for PCIE device
+ * @pdev: PCIE device
+ *
+ * This function will be called when a crash is detected, it will shutdown
+ * the PCIE device.
+ *
+ * Return: void
+ */
+static void pld_pcie_crash_shutdown(struct pci_dev *pdev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->crash_shutdown)
+		pld_context->ops->crash_shutdown(&pdev->dev, PLD_BUS_TYPE_PCIE);
+}
+
+/**
+ * pld_pcie_notify_handler() - Modem state notification callback function
+ * @pdev: PCIE device
+ * @state: modem power state
+ *
+ * This function will be called when there's a modem power state change.
+ *
+ * Return: void
+ */
+static void pld_pcie_notify_handler(struct pci_dev *pdev, int state)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->modem_status)
+		pld_context->ops->modem_status(&pdev->dev,
+					       PLD_BUS_TYPE_PCIE, state);
+}
+
+/**
+ * pld_pcie_uevent() - update wlan driver status callback function
+ * @pdev: PCIE device
+ * @status driver uevent status
+ *
+ * This function will be called when platform driver wants to update wlan
+ * driver's status.
+ *
+ * Return: void
+ */
+static void pld_pcie_uevent(struct pci_dev *pdev, uint32_t status)
+{
+	struct pld_context *pld_context;
+	struct pld_uevent_data data;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context)
+		return;
+
+	switch (status) {
+	case CNSS_RECOVERY:
+		data.uevent = PLD_FW_RECOVERY_START;
+		break;
+	case CNSS_FW_DOWN:
+		data.uevent = PLD_FW_DOWN;
+		break;
+	default:
+		goto out;
+	}
+
+	if (pld_context->ops->uevent)
+		pld_context->ops->uevent(&pdev->dev, &data);
+
+out:
+	return;
+}
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * pld_pcie_runtime_suspend() - PM runtime suspend
+ * @pdev: PCIE device
+ *
+ * PM runtime suspend callback function.
+ *
+ * Return: int
+ */
+static int pld_pcie_runtime_suspend(struct pci_dev *pdev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->runtime_suspend)
+		return pld_context->ops->runtime_suspend(&pdev->dev,
+							 PLD_BUS_TYPE_PCIE);
+
+	return -ENODEV;
+}
+
+/**
+ * pld_pcie_runtime_resume() - PM runtime resume
+ * @pdev: PCIE device
+ *
+ * PM runtime resume callback function.
+ *
+ * Return: int
+ */
+static int pld_pcie_runtime_resume(struct pci_dev *pdev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->runtime_resume)
+		return pld_context->ops->runtime_resume(&pdev->dev,
+							PLD_BUS_TYPE_PCIE);
+
+	return -ENODEV;
+}
+#endif
+#endif
+
+#ifdef CONFIG_PM
+#ifdef CONFIG_PLD_PCIE_CNSS
+/**
+ * pld_pcie_suspend() - Suspend callback function for power management
+ * @pdev: PCIE device
+ * @state: power state
+ *
+ * This function is to suspend the PCIE device when power management is
+ * enabled.
+ *
+ * Return: void
+ */
+static int pld_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->suspend(&pdev->dev,
+					 PLD_BUS_TYPE_PCIE, state);
+}
+
+/**
+ * pld_pcie_resume() - Resume callback function for power management
+ * @pdev: PCIE device
+ *
+ * This function is to resume the PCIE device when power management is
+ * enabled.
+ *
+ * Return: void
+ */
+static int pld_pcie_resume(struct pci_dev *pdev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->resume(&pdev->dev, PLD_BUS_TYPE_PCIE);
+}
+
+/**
+ * pld_pcie_suspend_noirq() - Complete the actions started by suspend()
+ * @pdev: PCI device
+ *
+ * Complete the actions started by suspend().  Carry out any additional
+ * operations required for suspending the device that might be racing
+ * with its driver's interrupt handler, which is guaranteed not to run
+ * while suspend_noirq() is being executed.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static int pld_pcie_suspend_noirq(struct pci_dev *pdev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context)
+		return -EINVAL;
+
+	if (pld_context->ops->suspend_noirq)
+		return pld_context->ops->
+			suspend_noirq(&pdev->dev, PLD_BUS_TYPE_PCIE);
+	return 0;
+}
+
+/**
+ * pld_pcie_resume_noirq() - Prepare for the execution of resume()
+ * @pdev: PCI device
+ *
+ * Prepare for the execution of resume() by carrying out any additional
+ * operations required for resuming the device that might be racing with
+ * its driver's interrupt handler, which is guaranteed not to run while
+ * resume_noirq() is being executed.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static int pld_pcie_resume_noirq(struct pci_dev *pdev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context)
+		return -EINVAL;
+
+	if (pld_context->ops->resume_noirq)
+		return pld_context->ops->
+			resume_noirq(&pdev->dev, PLD_BUS_TYPE_PCIE);
+	return 0;
+}
+#else
+/**
+ * pld_pcie_pm_suspend() - Suspend callback function for power management
+ * @dev: device
+ *
+ * This function is to suspend the PCIE device when power management is
+ * enabled.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static int pld_pcie_pm_suspend(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pm_message_t state = { .event = PM_EVENT_SUSPEND };
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->suspend(dev, PLD_BUS_TYPE_PCIE, state);
+}
+
+/**
+ * pld_pcie_pm_resume() - Resume callback function for power management
+ * @dev: device
+ *
+ * This function is to resume the PCIE device when power management is
+ * enabled.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static int pld_pcie_pm_resume(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->resume(dev, PLD_BUS_TYPE_PCIE);
+}
+
+/**
+ * pld_pcie_pm_suspend_noirq() - Complete the actions started by suspend()
+ * @dev: device
+ *
+ * Complete the actions started by suspend().  Carry out any additional
+ * operations required for suspending the device that might be racing
+ * with its driver's interrupt handler, which is guaranteed not to run
+ * while suspend_noirq() is being executed.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static int pld_pcie_pm_suspend_noirq(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context)
+		return -EINVAL;
+
+	if (pld_context->ops->suspend_noirq)
+		return pld_context->ops->suspend_noirq(dev, PLD_BUS_TYPE_PCIE);
+	return 0;
+}
+
+/**
+ * pld_pcie_pm_resume_noirq() - Prepare for the execution of resume()
+ * @dev: device
+ *
+ * Prepare for the execution of resume() by carrying out any additional
+ * operations required for resuming the device that might be racing with
+ * its driver's interrupt handler, which is guaranteed not to run while
+ * resume_noirq() is being executed.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static int pld_pcie_pm_resume_noirq(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context)
+		return -EINVAL;
+
+	if (pld_context->ops->resume_noirq)
+		return pld_context->ops->
+			resume_noirq(dev, PLD_BUS_TYPE_PCIE);
+	return 0;
+}
+#endif
+#endif
+
+static struct pci_device_id pld_pcie_id_table[] = {
+	{ 0x168c, 0x003c, PCI_ANY_ID, PCI_ANY_ID },
+	{ 0x168c, 0x003e, PCI_ANY_ID, PCI_ANY_ID },
+	{ 0x168c, 0x0041, PCI_ANY_ID, PCI_ANY_ID },
+	{ 0x168c, 0xabcd, PCI_ANY_ID, PCI_ANY_ID },
+	{ 0x168c, 0x7021, PCI_ANY_ID, PCI_ANY_ID },
+	{ 0 }
+};
+
+#ifdef MULTI_IF_NAME
+#define PLD_PCIE_OPS_NAME "pld_pcie_" MULTI_IF_NAME
+#else
+#define PLD_PCIE_OPS_NAME "pld_pcie"
+#endif
+
+#ifdef CONFIG_PLD_PCIE_CNSS
+#ifdef FEATURE_RUNTIME_PM
+struct cnss_wlan_runtime_ops runtime_pm_ops = {
+	.runtime_suspend = pld_pcie_runtime_suspend,
+	.runtime_resume = pld_pcie_runtime_resume,
+};
+#endif
+
+struct cnss_wlan_driver pld_pcie_ops = {
+	.name       = PLD_PCIE_OPS_NAME,
+	.id_table   = pld_pcie_id_table,
+	.probe      = pld_pcie_probe,
+	.remove     = pld_pcie_remove,
+	.reinit     = pld_pcie_reinit,
+	.shutdown   = pld_pcie_shutdown,
+	.crash_shutdown = pld_pcie_crash_shutdown,
+	.modem_status   = pld_pcie_notify_handler,
+	.update_status  = pld_pcie_uevent,
+#ifdef CONFIG_PM
+	.suspend    = pld_pcie_suspend,
+	.resume     = pld_pcie_resume,
+	.suspend_noirq = pld_pcie_suspend_noirq,
+	.resume_noirq  = pld_pcie_resume_noirq,
+#endif
+#ifdef FEATURE_RUNTIME_PM
+	.runtime_ops = &runtime_pm_ops,
+#endif
+};
+
+/**
+ * pld_pcie_register_driver() - Register PCIE device callback functions
+ *
+ * Return: int
+ */
+int pld_pcie_register_driver(void)
+{
+	return cnss_wlan_register_driver(&pld_pcie_ops);
+}
+
+/**
+ * pld_pcie_unregister_driver() - Unregister PCIE device callback functions
+ *
+ * Return: void
+ */
+void pld_pcie_unregister_driver(void)
+{
+	cnss_wlan_unregister_driver(&pld_pcie_ops);
+}
+#else
+#ifdef CONFIG_PM
+static const struct dev_pm_ops pld_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pld_pcie_pm_suspend, pld_pcie_pm_resume)
+	.suspend_noirq = pld_pcie_pm_suspend_noirq,
+	.resume_noirq = pld_pcie_pm_resume_noirq,
+};
+#endif
+
+struct pci_driver pld_pcie_ops = {
+	.name       = PLD_PCIE_OPS_NAME,
+	.id_table   = pld_pcie_id_table,
+	.probe      = pld_pcie_probe,
+	.remove     = pld_pcie_remove,
+	.driver     = {
+#ifdef CONFIG_PM
+		.pm = &pld_pm_ops,
+#endif
+	},
+};
+
+int pld_pcie_register_driver(void)
+{
+	return pci_register_driver(&pld_pcie_ops);
+}
+
+void pld_pcie_unregister_driver(void)
+{
+	pci_unregister_driver(&pld_pcie_ops);
+}
+#endif
+
+/**
+ * pld_pcie_get_ce_id() - Get CE number for the provided IRQ
+ * @dev: device
+ * @irq: IRQ number
+ *
+ * Return: CE number
+ */
+int pld_pcie_get_ce_id(struct device *dev, int irq)
+{
+	int ce_id = irq - 100;
+
+	if (ce_id < CE_COUNT_MAX && ce_id >= 0)
+		return ce_id;
+
+	return -EINVAL;
+}
+
+#ifdef CONFIG_PLD_PCIE_CNSS
+/**
+ * pld_pcie_wlan_enable() - Enable WLAN
+ * @dev: device
+ * @config: WLAN configuration data
+ * @mode: WLAN mode
+ * @host_version: host software version
+ *
+ * This function enables WLAN FW. It passed WLAN configuration data,
+ * WLAN mode and host software version to FW.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_pcie_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
+			 enum pld_driver_mode mode, const char *host_version)
+{
+	struct cnss_wlan_enable_cfg cfg;
+	enum cnss_driver_mode cnss_mode;
+
+	cfg.num_ce_tgt_cfg = config->num_ce_tgt_cfg;
+	cfg.ce_tgt_cfg = (struct cnss_ce_tgt_pipe_cfg *)
+		config->ce_tgt_cfg;
+	cfg.num_ce_svc_pipe_cfg = config->num_ce_svc_pipe_cfg;
+	cfg.ce_svc_cfg = (struct cnss_ce_svc_pipe_cfg *)
+		config->ce_svc_cfg;
+	cfg.num_shadow_reg_cfg = config->num_shadow_reg_cfg;
+	cfg.shadow_reg_cfg = (struct cnss_shadow_reg_cfg *)
+		config->shadow_reg_cfg;
+	cfg.num_shadow_reg_v2_cfg = config->num_shadow_reg_v2_cfg;
+	cfg.shadow_reg_v2_cfg = (struct cnss_shadow_reg_v2_cfg *)
+		config->shadow_reg_v2_cfg;
+
+	switch (mode) {
+	case PLD_FTM:
+		cnss_mode = CNSS_FTM;
+		break;
+	case PLD_EPPING:
+		cnss_mode = CNSS_EPPING;
+		break;
+	default:
+		cnss_mode = CNSS_MISSION;
+		break;
+	}
+	return cnss_wlan_enable(dev, &cfg, cnss_mode, host_version);
+}
+
+/**
+ * pld_pcie_wlan_disable() - Disable WLAN
+ * @dev: device
+ * @mode: WLAN mode
+ *
+ * This function disables WLAN FW. It passes WLAN mode to FW.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_pcie_wlan_disable(struct device *dev, enum pld_driver_mode mode)
+{
+	return cnss_wlan_disable(dev, CNSS_OFF);
+}
+
+/**
+ * pld_pcie_get_fw_files_for_target() - Get FW file names
+ * @dev: device
+ * @pfw_files: buffer for FW file names
+ * @target_type: target type
+ * @target_version: target version
+ *
+ * Return target specific FW file names to the buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_pcie_get_fw_files_for_target(struct device *dev,
+				     struct pld_fw_files *pfw_files,
+				     u32 target_type, u32 target_version)
+{
+	int ret = 0;
+	struct cnss_fw_files cnss_fw_files;
+
+	if (pfw_files == NULL)
+		return -ENODEV;
+
+	memset(pfw_files, 0, sizeof(*pfw_files));
+
+	ret = cnss_get_fw_files_for_target(dev, &cnss_fw_files,
+					   target_type, target_version);
+	if (ret)
+		return ret;
+
+	scnprintf(pfw_files->image_file, PLD_MAX_FILE_NAME, PREFIX "%s",
+		  cnss_fw_files.image_file);
+	scnprintf(pfw_files->board_data, PLD_MAX_FILE_NAME, PREFIX "%s",
+		  cnss_fw_files.board_data);
+	scnprintf(pfw_files->otp_data, PLD_MAX_FILE_NAME, PREFIX "%s",
+		  cnss_fw_files.otp_data);
+	scnprintf(pfw_files->utf_file, PLD_MAX_FILE_NAME, PREFIX "%s",
+		  cnss_fw_files.utf_file);
+	scnprintf(pfw_files->utf_board_data, PLD_MAX_FILE_NAME, PREFIX "%s",
+		  cnss_fw_files.utf_board_data);
+	scnprintf(pfw_files->epping_file, PLD_MAX_FILE_NAME, PREFIX "%s",
+		  cnss_fw_files.epping_file);
+	scnprintf(pfw_files->evicted_data, PLD_MAX_FILE_NAME, PREFIX "%s",
+		  cnss_fw_files.evicted_data);
+
+	return 0;
+}
+
+/**
+ * pld_pcie_get_platform_cap() - Get platform capabilities
+ * @dev: device
+ * @cap: buffer to the capabilities
+ *
+ * Return capabilities to the buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_pcie_get_platform_cap(struct device *dev, struct pld_platform_cap *cap)
+{
+	int ret = 0;
+	struct cnss_platform_cap cnss_cap;
+
+	if (cap == NULL)
+		return -ENODEV;
+
+	ret = cnss_get_platform_cap(dev, &cnss_cap);
+	if (ret)
+		return ret;
+
+	memcpy(cap, &cnss_cap, sizeof(*cap));
+	return 0;
+}
+
+/**
+ * pld_pcie_get_soc_info() - Get SOC information
+ * @dev: device
+ * @info: buffer to SOC information
+ *
+ * Return SOC info to the buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_pcie_get_soc_info(struct device *dev, struct pld_soc_info *info)
+{
+	int ret = 0;
+	struct cnss_soc_info cnss_info = {0};
+
+	if (info == NULL)
+		return -ENODEV;
+
+	ret = cnss_get_soc_info(dev, &cnss_info);
+	if (ret)
+		return ret;
+
+	info->v_addr = cnss_info.va;
+	info->p_addr = cnss_info.pa;
+	info->chip_id = cnss_info.chip_id;
+	info->chip_family = cnss_info.chip_family;
+	info->board_id = cnss_info.board_id;
+	info->soc_id = cnss_info.soc_id;
+	info->fw_version = cnss_info.fw_version;
+	strlcpy(info->fw_build_timestamp, cnss_info.fw_build_timestamp,
+		sizeof(info->fw_build_timestamp));
+
+	return 0;
+}
+
+/**
+ * pld_pcie_schedule_recovery_work() - schedule recovery work
+ * @dev: device
+ * @reason: recovery reason
+ *
+ * Return: void
+ */
+void pld_pcie_schedule_recovery_work(struct device *dev,
+				     enum pld_recovery_reason reason)
+{
+	enum cnss_recovery_reason cnss_reason;
+
+	switch (reason) {
+	case PLD_REASON_LINK_DOWN:
+		cnss_reason = CNSS_REASON_LINK_DOWN;
+		break;
+	default:
+		cnss_reason = CNSS_REASON_DEFAULT;
+		break;
+	}
+	cnss_schedule_recovery(dev, cnss_reason);
+}
+
+/**
+ * pld_pcie_device_self_recovery() - device self recovery
+ * @dev: device
+ * @reason: recovery reason
+ *
+ * Return: void
+ */
+void pld_pcie_device_self_recovery(struct device *dev,
+				   enum pld_recovery_reason reason)
+{
+	enum cnss_recovery_reason cnss_reason;
+
+	switch (reason) {
+	case PLD_REASON_LINK_DOWN:
+		cnss_reason = CNSS_REASON_LINK_DOWN;
+		break;
+	default:
+		cnss_reason = CNSS_REASON_DEFAULT;
+		break;
+	}
+	cnss_self_recovery(dev, cnss_reason);
+}
+#endif
+#endif
diff --git a/core/pld/src/pld_pcie.h b/core/pld/src/pld_pcie.h
new file mode 100644
index 0000000..6d5a4ab
--- /dev/null
+++ b/core/pld/src/pld_pcie.h
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+#ifndef __PLD_PCIE_H__
+#define __PLD_PCIE_H__
+
+#ifdef CONFIG_PLD_PCIE_CNSS
+#include <net/cnss2.h>
+#endif
+#include "pld_internal.h"
+
+#ifdef MULTI_IF_NAME
+#define PREFIX MULTI_IF_NAME "/"
+#else
+#define PREFIX ""
+#endif
+
+#ifndef HIF_PCI
+static inline int pld_pcie_register_driver(void)
+{
+	return 0;
+}
+
+static inline void pld_pcie_unregister_driver(void)
+{
+}
+
+static inline int pld_pcie_get_ce_id(struct device *dev, int irq)
+{
+	return 0;
+}
+#else
+int pld_pcie_register_driver(void);
+void pld_pcie_unregister_driver(void);
+int pld_pcie_get_ce_id(struct device *dev, int irq);
+#endif
+
+#ifndef CONFIG_PLD_PCIE_CNSS
+static inline int pld_pcie_wlan_enable(struct device *dev,
+				       struct pld_wlan_enable_cfg *config,
+				       enum pld_driver_mode mode,
+				       const char *host_version)
+{
+	return 0;
+}
+
+static inline int pld_pcie_wlan_disable(struct device *dev,
+					enum pld_driver_mode mode)
+{
+	return 0;
+}
+#else
+int pld_pcie_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
+			 enum pld_driver_mode mode, const char *host_version);
+int pld_pcie_wlan_disable(struct device *dev, enum pld_driver_mode mode);
+#endif
+
+#if defined(CONFIG_PLD_PCIE_CNSS)
+static inline int pld_pcie_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
+{
+	return cnss_set_fw_log_mode(dev, fw_log_mode);
+}
+
+static inline void pld_pcie_intr_notify_q6(struct device *dev)
+{
+}
+#else
+static inline int pld_pcie_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
+{
+	return 0;
+}
+
+static inline void pld_pcie_intr_notify_q6(struct device *dev)
+{
+}
+#endif
+
+#if (!defined(CONFIG_PLD_PCIE_CNSS)) || (!defined(CONFIG_CNSS_SECURE_FW))
+static inline int pld_pcie_get_sha_hash(struct device *dev, const u8 *data,
+					u32 data_len, u8 *hash_idx, u8 *out)
+{
+	return 0;
+}
+
+static inline void *pld_pcie_get_fw_ptr(struct device *dev)
+{
+	return NULL;
+}
+#else
+static inline int pld_pcie_get_sha_hash(struct device *dev, const u8 *data,
+					u32 data_len, u8 *hash_idx, u8 *out)
+{
+	return cnss_get_sha_hash(data, data_len, hash_idx, out);
+}
+
+static inline void *pld_pcie_get_fw_ptr(struct device *dev)
+{
+	return cnss_get_fw_ptr();
+}
+#endif
+
+#if (!defined(CONFIG_PLD_PCIE_CNSS)) || (!defined(CONFIG_PCI_MSM))
+static inline int pld_pcie_wlan_pm_control(struct device *dev, bool vote)
+{
+	return 0;
+}
+#else
+static inline int pld_pcie_wlan_pm_control(struct device *dev, bool vote)
+{
+	return cnss_wlan_pm_control(dev, vote);
+}
+#endif
+
+#ifndef CONFIG_PLD_PCIE_CNSS
+static inline int
+pld_pcie_get_fw_files_for_target(struct device *dev,
+				 struct pld_fw_files *pfw_files,
+				 u32 target_type, u32 target_version)
+{
+	pld_get_default_fw_files(pfw_files);
+	return 0;
+}
+
+static inline void pld_pcie_link_down(struct device *dev)
+{
+}
+
+static inline int pld_pcie_is_fw_down(struct device *dev)
+{
+	return 0;
+}
+
+static inline int pld_pcie_athdiag_read(struct device *dev, uint32_t offset,
+					uint32_t memtype, uint32_t datalen,
+					uint8_t *output)
+{
+	return 0;
+}
+
+static inline int pld_pcie_athdiag_write(struct device *dev, uint32_t offset,
+					 uint32_t memtype, uint32_t datalen,
+					 uint8_t *input)
+{
+	return 0;
+}
+
+static inline void
+pld_pcie_schedule_recovery_work(struct device *dev,
+				enum pld_recovery_reason reason)
+{
+}
+
+static inline void *pld_pcie_get_virt_ramdump_mem(struct device *dev,
+						  unsigned long *size)
+{
+	return NULL;
+}
+
+static inline void pld_pcie_device_crashed(struct device *dev)
+{
+}
+
+static inline void pld_pcie_device_self_recovery(struct device *dev,
+					 enum pld_recovery_reason reason)
+{
+}
+
+static inline void pld_pcie_request_pm_qos(struct device *dev, u32 qos_val)
+{
+}
+
+static inline void pld_pcie_remove_pm_qos(struct device *dev)
+{
+}
+
+static inline int pld_pcie_request_bus_bandwidth(struct device *dev,
+						 int bandwidth)
+{
+	return 0;
+}
+
+static inline int pld_pcie_get_platform_cap(struct device *dev,
+					    struct pld_platform_cap *cap)
+{
+	return 0;
+}
+
+static inline int pld_pcie_get_soc_info(struct device *dev,
+					struct pld_soc_info *info)
+{
+	return 0;
+}
+
+static inline int pld_pcie_auto_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static inline int pld_pcie_auto_resume(struct device *dev)
+{
+	return 0;
+}
+
+static inline int pld_pcie_force_wake_request(struct device *dev)
+{
+	return 0;
+}
+
+static inline int pld_pcie_is_device_awake(struct device *dev)
+{
+	return true;
+}
+
+static inline int pld_pcie_force_wake_release(struct device *dev)
+{
+	return 0;
+}
+
+static inline void pld_pcie_lock_pm_sem(struct device *dev)
+{
+}
+
+static inline void pld_pcie_release_pm_sem(struct device *dev)
+{
+}
+
+static inline int pld_pcie_power_on(struct device *dev)
+{
+	return 0;
+}
+
+static inline int pld_pcie_power_off(struct device *dev)
+{
+	return 0;
+}
+
+static inline int pld_pcie_force_assert_target(struct device *dev)
+{
+	return -EINVAL;
+}
+
+static inline int pld_pcie_get_user_msi_assignment(struct device *dev,
+						   char *user_name,
+						   int *num_vectors,
+						   uint32_t *user_base_data,
+						   uint32_t *base_vector)
+{
+	return 0;
+}
+
+static inline int pld_pcie_get_msi_irq(struct device *dev, unsigned int vector)
+{
+	return 0;
+}
+
+static inline void pld_pcie_get_msi_address(struct device *dev,
+					    uint32_t *msi_addr_low,
+					    uint32_t *msi_addr_high)
+{
+	return;
+}
+#else
+int pld_pcie_get_fw_files_for_target(struct device *dev,
+				     struct pld_fw_files *pfw_files,
+				     u32 target_type, u32 target_version);
+int pld_pcie_get_platform_cap(struct device *dev, struct pld_platform_cap *cap);
+int pld_pcie_get_soc_info(struct device *dev, struct pld_soc_info *info);
+void pld_pcie_schedule_recovery_work(struct device *dev,
+				     enum pld_recovery_reason reason);
+void pld_pcie_device_self_recovery(struct device *dev,
+				   enum pld_recovery_reason reason);
+
+static inline void pld_pcie_link_down(struct device *dev)
+{
+	cnss_pci_link_down(dev);
+}
+
+static inline int pld_pcie_is_fw_down(struct device *dev)
+{
+	return cnss_pci_is_device_down(dev);
+}
+
+static inline int pld_pcie_athdiag_read(struct device *dev, uint32_t offset,
+					uint32_t memtype, uint32_t datalen,
+					uint8_t *output)
+{
+	return cnss_athdiag_read(dev, offset, memtype, datalen, output);
+}
+
+static inline int pld_pcie_athdiag_write(struct device *dev, uint32_t offset,
+					 uint32_t memtype, uint32_t datalen,
+					 uint8_t *input)
+{
+	return cnss_athdiag_write(dev, offset, memtype, datalen, input);
+}
+
+static inline void *pld_pcie_get_virt_ramdump_mem(struct device *dev,
+						  unsigned long *size)
+{
+	return cnss_get_virt_ramdump_mem(dev, size);
+}
+
+static inline void pld_pcie_device_crashed(struct device *dev)
+{
+	cnss_device_crashed(dev);
+}
+
+static inline void pld_pcie_request_pm_qos(struct device *dev, u32 qos_val)
+{
+	cnss_request_pm_qos(dev, qos_val);
+}
+
+static inline void pld_pcie_remove_pm_qos(struct device *dev)
+{
+	cnss_remove_pm_qos(dev);
+}
+
+static inline int pld_pcie_request_bus_bandwidth(struct device *dev,
+						 int bandwidth)
+{
+	return cnss_request_bus_bandwidth(dev, bandwidth);
+}
+
+static inline int pld_pcie_auto_suspend(struct device *dev)
+{
+	return cnss_auto_suspend(dev);
+}
+
+static inline int pld_pcie_auto_resume(struct device *dev)
+{
+	return cnss_auto_resume(dev);
+}
+
+static inline int pld_pcie_force_wake_request(struct device *dev)
+{
+	return cnss_pci_force_wake_request(dev);
+}
+
+static inline int pld_pcie_is_device_awake(struct device *dev)
+{
+	return cnss_pci_is_device_awake(dev);
+}
+
+static inline int pld_pcie_force_wake_release(struct device *dev)
+{
+	return cnss_pci_force_wake_release(dev);
+}
+
+static inline void pld_pcie_lock_pm_sem(struct device *dev)
+{
+	cnss_lock_pm_sem(dev);
+}
+
+static inline void pld_pcie_release_pm_sem(struct device *dev)
+{
+	cnss_release_pm_sem(dev);
+}
+
+static inline int pld_pcie_power_on(struct device *dev)
+{
+	return cnss_power_up(dev);
+}
+
+static inline int pld_pcie_power_off(struct device *dev)
+{
+	return cnss_power_down(dev);
+}
+
+static inline int pld_pcie_force_assert_target(struct device *dev)
+{
+	return cnss_force_fw_assert(dev);
+}
+
+static inline int pld_pcie_get_user_msi_assignment(struct device *dev,
+						   char *user_name,
+						   int *num_vectors,
+						   uint32_t *user_base_data,
+						   uint32_t *base_vector)
+{
+	return cnss_get_user_msi_assignment(dev, user_name, num_vectors,
+					    user_base_data, base_vector);
+}
+
+static inline int pld_pcie_get_msi_irq(struct device *dev, unsigned int vector)
+{
+	return cnss_get_msi_irq(dev, vector);
+}
+
+static inline void pld_pcie_get_msi_address(struct device *dev,
+					    uint32_t *msi_addr_low,
+					    uint32_t *msi_addr_high)
+{
+	cnss_get_msi_address(dev, msi_addr_low, msi_addr_high);
+}
+#endif
+#endif
diff --git a/core/pld/src/pld_sdio.c b/core/pld/src/pld_sdio.c
new file mode 100644
index 0000000..004743b
--- /dev/null
+++ b/core/pld/src/pld_sdio.c
@@ -0,0 +1,454 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+#include <net/cnss.h>
+#endif
+
+#include "pld_common.h"
+#include "pld_internal.h"
+#include "pld_sdio.h"
+
+
+#ifdef CONFIG_SDIO
+/* SDIO manufacturer ID and Codes */
+#define MANUFACTURER_ID_AR6320_BASE        0x500
+#define MANUFACTURER_ID_QCA9377_BASE       0x700
+#define MANUFACTURER_ID_QCA9379_BASE       0x800
+#define MANUFACTURER_CODE                  0x271
+
+#ifndef CONFIG_CNSS
+static const struct pld_fw_files fw_files_qca6174_fw_1_1 = {
+	PREFIX "qwlan11.bin", PREFIX  "bdwlan11.bin", PREFIX "otp11.bin",
+	PREFIX  "utf11.bin", PREFIX "utfbd11.bin", PREFIX "qsetup11.bin",
+	PREFIX "epping11.bin", ""};
+static const struct pld_fw_files fw_files_qca6174_fw_2_0 = {
+	PREFIX "qwlan20.bin", PREFIX "bdwlan20.bin", PREFIX "otp20.bin",
+	PREFIX "utf20.bin", PREFIX "utfbd20.bin", PREFIX "qsetup20.bin",
+	PREFIX "epping20.bin", ""};
+static const struct pld_fw_files fw_files_qca6174_fw_1_3 = {
+	PREFIX "qwlan13.bin", PREFIX "bdwlan13.bin", PREFIX "otp13.bin",
+	PREFIX "utf13.bin", PREFIX "utfbd13.bin", PREFIX "qsetup13.bin",
+	PREFIX "epping13.bin", ""};
+static const struct pld_fw_files fw_files_qca6174_fw_3_0 = {
+	PREFIX "qwlan30.bin", PREFIX "bdwlan30.bin", PREFIX "otp30.bin",
+	PREFIX "utf30.bin", PREFIX "utfbd30.bin", PREFIX "qsetup30.bin",
+	PREFIX "epping30.bin", PREFIX "qwlan30i.bin"};
+static const struct pld_fw_files fw_files_default = {
+	PREFIX "qwlan.bin", PREFIX "bdwlan.bin", PREFIX "otp.bin",
+	PREFIX "utf.bin", PREFIX "utfbd.bin", PREFIX "qsetup.bin",
+	PREFIX "epping.bin", ""};
+#endif
+
+/**
+ * pld_sdio_probe() - Probe function for SDIO platform driver
+ * sdio_func: pointer to sdio device function
+ * @id: SDIO device ID table
+ *
+ * The probe function will be called when SDIO device provided
+ * in the ID table is detected.
+ *
+ * Return: int
+ */
+static int pld_sdio_probe(struct sdio_func *sdio_func,
+			  const struct sdio_device_id *id)
+{
+	struct pld_context *pld_context;
+	struct device *dev;
+	int ret;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context || !sdio_func) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	dev = &sdio_func->dev;
+	ret = pld_add_dev(pld_context, dev, PLD_BUS_TYPE_SDIO);
+	if (ret)
+		goto out;
+
+	return pld_context->ops->probe(dev, PLD_BUS_TYPE_SDIO,
+		       sdio_func, (void *)id);
+
+out:
+	return ret;
+}
+
+
+/**
+ * pld_sdio_remove() - Remove function for SDIO device
+ * @sdio_func: pointer to sdio device function
+ *
+ * The remove function will be called when SDIO device is disconnected
+ *
+ * Return: void
+ */
+static void pld_sdio_remove(struct sdio_func *sdio_func)
+{
+	struct pld_context *pld_context;
+	struct device *dev = &sdio_func->dev;
+
+	pld_context = pld_get_global_context();
+
+	if (!pld_context)
+		return;
+
+	pld_context->ops->remove(dev, PLD_BUS_TYPE_SDIO);
+	pld_del_dev(pld_context, dev);
+}
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+/**
+ * pld_sdio_reinit() - SSR re-initialize function for SDIO device
+ * @sdio_func: pointer to sdio device function
+ * @id: SDIO device ID
+ *
+ * During subsystem restart(SSR), this function will be called to
+ * re-initialize SDIO device.
+ *
+ * Return: int
+ */
+static int pld_sdio_reinit(struct sdio_func *sdio_func,
+			  const struct sdio_device_id *id)
+{
+	struct pld_context *pld_context;
+	struct device *dev = &sdio_func->dev;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->reinit)
+		return pld_context->ops->reinit(dev, PLD_BUS_TYPE_SDIO,
+		       sdio_func, (void *)id);
+
+	return -ENODEV;
+}
+
+/**
+ * pld_sdio_shutdown() - SSR shutdown function for SDIO device
+ * @sdio_func: pointer to sdio device function
+ *
+ * During SSR, this function will be called to shutdown SDIO device.
+ *
+ * Return: void
+ */
+static void pld_sdio_shutdown(struct sdio_func *sdio_func)
+{
+	struct pld_context *pld_context;
+	struct device *dev = &sdio_func->dev;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->shutdown)
+		pld_context->ops->shutdown(dev, PLD_BUS_TYPE_SDIO);
+}
+
+/**
+ * pld_sdio_crash_shutdown() - Crash shutdown function for SDIO device
+ * @sdio_func: pointer to sdio device function
+ *
+ * This function will be called when a crash is detected, it will shutdown
+ * the SDIO device.
+ *
+ * Return: void
+ */
+static void pld_sdio_crash_shutdown(struct sdio_func *sdio_func)
+{
+	struct pld_context *pld_context;
+	struct device *dev = &sdio_func->dev;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->crash_shutdown)
+		pld_context->ops->crash_shutdown(dev, PLD_BUS_TYPE_SDIO);
+}
+
+#endif
+
+#ifdef CONFIG_PM
+/**
+ * pld_sdio_suspend() - Suspend callback function for power management
+ * @dev: SDIO device
+ *
+ * This function is to suspend the SDIO device when power management is
+ * enabled.
+ *
+ * Return: void
+ */
+static int pld_sdio_suspend(struct device *dev)
+{
+	struct pld_context *pld_context;
+	pm_message_t state = { .event = PM_EVENT_SUSPEND };
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->suspend(dev,
+					 PLD_BUS_TYPE_SDIO, state);
+}
+
+/**
+ * pld_sdio_resume() - Resume callback function for power management
+ * @dev: SDIO device
+ *
+ * This function is to resume the SDIO device when power management is
+ * enabled.
+ *
+ * Return: void
+ */
+static int pld_sdio_resume(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->resume(dev, PLD_BUS_TYPE_SDIO);
+}
+#endif
+
+static struct sdio_device_id pld_sdio_id_table[] = {
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x0))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x1))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x2))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x3))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x4))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x5))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x6))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x7))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x8))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x9))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xA))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xB))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xC))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xD))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xE))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xF))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x0))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x1))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x2))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x3))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x4))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x5))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x6))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x7))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x8))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x9))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xA))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xB))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xC))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xD))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xE))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xF))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x0))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x1))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x2))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x3))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x4))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x5))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x6))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x7))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x8))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0x9))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xA))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xB))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xC))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xD))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xE))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9379_BASE | 0xF))},
+	{},
+};
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+struct cnss_sdio_wlan_driver pld_sdio_ops = {
+	.name       = "pld_sdio",
+	.id_table   = pld_sdio_id_table,
+	.probe      = pld_sdio_probe,
+	.remove     = pld_sdio_remove,
+	.reinit     = pld_sdio_reinit,
+	.shutdown   = pld_sdio_shutdown,
+	.crash_shutdown = pld_sdio_crash_shutdown,
+#ifdef CONFIG_PM
+	.suspend    = pld_sdio_suspend,
+	.resume     = pld_sdio_resume,
+#endif
+};
+
+/**
+ * pld_sdio_register_driver() - Register SDIO device callback functions
+ *
+ * Return: int
+ */
+int pld_sdio_register_driver(void)
+{
+	return cnss_sdio_wlan_register_driver(&pld_sdio_ops);
+}
+
+/**
+ * pld_sdio_unregister_driver() - Unregister SDIO device callback functions
+ *
+ * Return: void
+ */
+void pld_sdio_unregister_driver(void)
+{
+	cnss_sdio_wlan_unregister_driver(&pld_sdio_ops);
+}
+#else
+
+#ifdef CONFIG_PM
+static const struct dev_pm_ops pld_device_pm_ops = {
+	.suspend = pld_sdio_suspend,
+	.resume = pld_sdio_resume,
+};
+#endif
+
+struct sdio_driver pld_sdio_ops = {
+	.name       = "pld_sdio",
+	.id_table   = pld_sdio_id_table,
+	.probe      = pld_sdio_probe,
+	.remove     = pld_sdio_remove,
+#if defined(CONFIG_PM)
+	.drv = {
+		.pm = &pld_device_pm_ops,
+	}
+#endif
+};
+
+int pld_sdio_register_driver(void)
+{
+	return sdio_register_driver(&pld_sdio_ops);
+}
+
+void pld_sdio_unregister_driver(void)
+{
+	sdio_unregister_driver(&pld_sdio_ops);
+}
+#endif
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+#ifdef CONFIG_TUFELLO_DUAL_FW_SUPPORT
+static inline int pld_sdio_is_tufello_dual_fw_supported(void)
+{
+	return 1;
+}
+#else
+static inline int pld_sdio_is_tufello_dual_fw_supported(void)
+{
+	return 0;
+#endif
+}
+
+/**
+ * pld_sdio_get_fw_files_for_target() - Get FW file names
+ * @pfw_files: buffer for FW file names
+ * @target_type: target type
+ * @target_version: target version
+ *
+ * Return target specific FW file names to the buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_sdio_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+				     u32 target_type, u32 target_version)
+{
+	int ret = 0;
+	struct cnss_fw_files cnss_fw_files;
+
+	if (pfw_files == NULL)
+		return -ENODEV;
+
+	memset(pfw_files, 0, sizeof(*pfw_files));
+
+	if (target_version == PLD_QCA9377_REV1_1_VERSION) {
+		cnss_get_qca9377_fw_files(&cnss_fw_files, PLD_MAX_FILE_NAME,
+			pld_sdio_is_tufello_dual_fw_supported());
+	} else {
+		ret = cnss_get_fw_files_for_target(&cnss_fw_files,
+					   target_type, target_version);
+	}
+	if (0 != ret)
+		return ret;
+
+	snprintf(pfw_files->image_file, PLD_MAX_FILE_NAME, PREFIX "%s",
+		cnss_fw_files.image_file);
+	snprintf(pfw_files->board_data, PLD_MAX_FILE_NAME, PREFIX "%s",
+		cnss_fw_files.board_data);
+	snprintf(pfw_files->otp_data, PLD_MAX_FILE_NAME, PREFIX "%s",
+		cnss_fw_files.otp_data);
+	snprintf(pfw_files->utf_file, PLD_MAX_FILE_NAME, PREFIX "%s",
+		cnss_fw_files.utf_file);
+	snprintf(pfw_files->utf_board_data, PLD_MAX_FILE_NAME, PREFIX "%s",
+		cnss_fw_files.utf_board_data);
+	snprintf(pfw_files->epping_file, PLD_MAX_FILE_NAME, PREFIX "%s",
+		cnss_fw_files.epping_file);
+	snprintf(pfw_files->evicted_data, PLD_MAX_FILE_NAME, PREFIX "%s",
+		cnss_fw_files.evicted_data);
+
+	return ret;
+}
+#else
+#ifdef CONFIG_TUFELLO_DUAL_FW_SUPPORT
+static inline void get_qca9377_fw_files(struct pld_fw_files *pfw_files,
+					u32 size)
+{
+		memcpy(pfw_files, &fw_files_default, sizeof(*pfw_files));
+}
+#else
+static inline void get_qca9377_fw_files(struct pld_fw_files *pfw_files,
+					u32 size)
+{
+		memcpy(pfw_files, &fw_files_qca6174_fw_3_0, sizeof(*pfw_files));
+}
+#endif
+
+int pld_sdio_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+				     u32 target_type, u32 target_version)
+{
+	if (!pfw_files)
+		return -ENODEV;
+
+	switch (target_version) {
+	case PLD_AR6320_REV1_VERSION:
+	case PLD_AR6320_REV1_1_VERSION:
+		memcpy(pfw_files, &fw_files_qca6174_fw_1_1, sizeof(*pfw_files));
+		break;
+	case PLD_AR6320_REV1_3_VERSION:
+		memcpy(pfw_files, &fw_files_qca6174_fw_1_3, sizeof(*pfw_files));
+		break;
+	case PLD_AR6320_REV2_1_VERSION:
+		memcpy(pfw_files, &fw_files_qca6174_fw_2_0, sizeof(*pfw_files));
+		break;
+	case PLD_AR6320_REV3_VERSION:
+	case PLD_AR6320_REV3_2_VERSION:
+		memcpy(pfw_files, &fw_files_qca6174_fw_3_0, sizeof(*pfw_files));
+		break;
+	case PLD_QCA9377_REV1_1_VERSION:
+	case PLD_QCA9379_REV1_VERSION:
+		get_qca9377_fw_files(pfw_files, sizeof(*pfw_files));
+		break;
+	default:
+		memcpy(pfw_files, &fw_files_default, sizeof(*pfw_files));
+		pr_err("%s version mismatch 0x%X ",
+				__func__, target_version);
+		break;
+	}
+
+	return 0;
+}
+#endif
+#endif
diff --git a/core/pld/src/pld_sdio.h b/core/pld/src/pld_sdio.h
new file mode 100644
index 0000000..66bbb22
--- /dev/null
+++ b/core/pld/src/pld_sdio.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+#ifndef __PLD_SDIO_H__
+#define __PLD_SDIO_H__
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+#include <net/cnss.h>
+#endif
+#include "pld_common.h"
+
+#ifdef MULTI_IF_NAME
+#define PREFIX MULTI_IF_NAME "/"
+#else
+#define PREFIX ""
+#endif
+
+#define PLD_QCA9377_REV1_1_VERSION          0x5020001
+#define PLD_QCA9379_REV1_VERSION            0x5040000
+#define TOTAL_DUMP_SIZE         0x00200000
+
+#ifndef CONFIG_CNSS
+#define PLD_AR6004_VERSION_REV1_3           0x31c8088a
+#define PLD_AR9888_REV2_VERSION             0x4100016c
+#define PLD_AR6320_REV1_VERSION             0x5000000
+#define PLD_AR6320_REV1_1_VERSION           0x5000001
+#define PLD_AR6320_REV1_3_VERSION           0x5000003
+#define PLD_AR6320_REV2_1_VERSION           0x5010000
+#define PLD_AR6320_REV3_VERSION             0x5020000
+#define PLD_AR6320_REV3_2_VERSION           0x5030000
+#define PLD_AR6320_DEV_VERSION              0x1000000
+
+
+#endif
+
+#ifndef CONFIG_SDIO
+static inline int pld_sdio_register_driver(void)
+{
+	return 0;
+}
+
+static inline void pld_sdio_unregister_driver(void)
+{
+}
+
+static inline
+int pld_sdio_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+				     u32 target_type, u32 target_version)
+{
+	return 0;
+}
+static inline uint8_t *pld_sdio_get_wlan_mac_address(struct device *dev,
+						     uint32_t *num)
+{
+	*num = 0;
+	return NULL;
+}
+#else
+int pld_sdio_register_driver(void);
+void pld_sdio_unregister_driver(void);
+int pld_sdio_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+				     u32 target_type, u32 target_version);
+#ifdef CONFIG_CNSS
+static inline uint8_t *pld_sdio_get_wlan_mac_address(struct device *dev,
+						     uint32_t *num)
+{
+	return cnss_common_get_wlan_mac_address(dev, num);
+}
+#else
+static inline uint8_t *pld_sdio_get_wlan_mac_address(struct device *dev,
+						     uint32_t *num)
+{
+	*num = 0;
+	return NULL;
+}
+#endif
+#endif
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+static inline void *pld_sdio_get_virt_ramdump_mem(struct device *dev,
+		unsigned long *size)
+{
+	return cnss_common_get_virt_ramdump_mem(dev, size);
+}
+
+static inline void pld_sdio_device_crashed(struct device *dev)
+{
+	cnss_common_device_crashed(dev);
+}
+static inline bool pld_sdio_is_fw_dump_skipped(void)
+{
+	return cnss_get_restart_level() == CNSS_RESET_SUBSYS_COUPLED;
+}
+
+static inline void pld_sdio_device_self_recovery(struct device *dev)
+{
+	cnss_common_device_self_recovery(dev);
+}
+#else
+static inline void *pld_sdio_get_virt_ramdump_mem(struct device *dev,
+		unsigned long *size)
+{
+	return NULL;
+}
+
+static inline void pld_sdio_device_crashed(struct device *dev)
+{
+}
+static inline bool pld_sdio_is_fw_dump_skipped(void)
+{
+	return false;
+}
+
+static inline void pld_sdio_device_self_recovery(struct device *dev)
+{
+}
+#endif
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+/**
+ * pld_hif_sdio_get_virt_ramdump_mem() - Get virtual ramdump memory
+ * @dev: device
+ * @size: buffer to virtual memory size
+ *
+ * Return: virtual ramdump memory address
+ */
+static inline void *pld_hif_sdio_get_virt_ramdump_mem(struct device *dev,
+						unsigned long *size)
+{
+	return cnss_common_get_virt_ramdump_mem(dev, size);
+}
+
+/**
+ * pld_hif_sdio_release_ramdump_mem() - Release virtual ramdump memory
+ * @address: virtual ramdump memory address
+ *
+ * Return: void
+ */
+static inline void pld_hif_sdio_release_ramdump_mem(unsigned long *address)
+{
+}
+#else
+/**
+ * pld_hif_sdio_get_virt_ramdump_mem() - Get virtual ramdump memory
+ * @dev: device
+ * @size: buffer to virtual memory size
+ *
+ * Return: virtual ramdump memory address
+ */
+static inline void *pld_hif_sdio_get_virt_ramdump_mem(struct device *dev,
+						unsigned long *size)
+{
+	size_t length = 0;
+	int flags = GFP_KERNEL;
+
+	length = TOTAL_DUMP_SIZE;
+
+	if (size != NULL)
+		*size = (unsigned long)length;
+
+	if (in_interrupt() || irqs_disabled() || in_atomic())
+		flags = GFP_ATOMIC;
+
+	return kzalloc(length, flags);
+}
+
+/**
+ * pld_hif_sdio_release_ramdump_mem() - Release virtual ramdump memory
+ * @address: virtual ramdump memory address
+ *
+ * Return: void
+ */
+static inline void pld_hif_sdio_release_ramdump_mem(unsigned long *address)
+{
+	if (address != NULL)
+		kfree(address);
+}
+#endif
+#endif
diff --git a/core/pld/src/pld_snoc.c b/core/pld/src/pld_snoc.c
new file mode 100644
index 0000000..8a4aed5
--- /dev/null
+++ b/core/pld/src/pld_snoc.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_PLD_SNOC_ICNSS
+#include <soc/qcom/icnss.h>
+#endif
+
+#include "pld_internal.h"
+#include "pld_snoc.h"
+
+#ifdef CONFIG_PLD_SNOC_ICNSS
+/**
+ * pld_snoc_probe() - Probe function for platform driver
+ * @dev: device
+ *
+ * The probe function will be called when platform device
+ * is detected.
+ *
+ * Return: int
+ */
+static int pld_snoc_probe(struct device *dev)
+{
+	struct pld_context *pld_context;
+	int ret = 0;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	ret = pld_add_dev(pld_context, dev, PLD_BUS_TYPE_SNOC);
+	if (ret)
+		goto out;
+
+	return pld_context->ops->probe(dev, PLD_BUS_TYPE_SNOC,
+				       NULL, NULL);
+
+out:
+	return ret;
+}
+
+/**
+ * pld_snoc_remove() - Remove function for platform device
+ * @dev: device
+ *
+ * The remove function will be called when platform device
+ * is disconnected
+ *
+ * Return: void
+ */
+static void pld_snoc_remove(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+
+	if (!pld_context)
+		return;
+
+	pld_context->ops->remove(dev, PLD_BUS_TYPE_SNOC);
+
+	pld_del_dev(pld_context, dev);
+}
+
+/**
+ * pld_snoc_reinit() - SSR re-initialize function for platform device
+ * @dev: device
+ *
+ * During subsystem restart(SSR), this function will be called to
+ * re-initialize platform device.
+ *
+ * Return: int
+ */
+static int pld_snoc_reinit(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->reinit)
+		return pld_context->ops->reinit(dev, PLD_BUS_TYPE_SNOC,
+						NULL, NULL);
+
+	return -ENODEV;
+}
+
+/**
+ * pld_snoc_shutdown() - SSR shutdown function for platform device
+ * @dev: device
+ *
+ * During SSR, this function will be called to shutdown platform device.
+ *
+ * Return: void
+ */
+static void pld_snoc_shutdown(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->shutdown)
+		pld_context->ops->shutdown(dev, PLD_BUS_TYPE_SNOC);
+}
+
+/**
+ * pld_snoc_crash_shutdown() - Crash shutdown function for platform device
+ * @dev: device
+ *
+ * This function will be called when a crash is detected, it will shutdown
+ * platform device.
+ *
+ * Return: void
+ */
+static void pld_snoc_crash_shutdown(void *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->crash_shutdown)
+		pld_context->ops->crash_shutdown(dev, PLD_BUS_TYPE_SNOC);
+}
+
+/**
+ * pld_snoc_pm_suspend() - PM suspend callback function for power management
+ * @dev: device
+ *
+ * This function is to suspend the platform device when power management
+ * is enabled.
+ *
+ * Return: void
+ */
+static int pld_snoc_pm_suspend(struct device *dev)
+{
+	struct pld_context *pld_context;
+	pm_message_t state;
+
+	state.event = PM_EVENT_SUSPEND;
+	pld_context = pld_get_global_context();
+	return pld_context->ops->suspend(dev, PLD_BUS_TYPE_SNOC, state);
+}
+
+/**
+ * pld_snoc_pm_resume() - PM resume callback function for power management
+ * @pdev: device
+ *
+ * This function is to resume the platform device when power management
+ * is enabled.
+ *
+ * Return: void
+ */
+static int pld_snoc_pm_resume(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->resume(dev, PLD_BUS_TYPE_SNOC);
+}
+
+/**
+ * pld_snoc_suspend_noirq() - Complete the actions started by suspend()
+ * @dev: device
+ *
+ * Complete the actions started by suspend().  Carry out any
+ * additional operations required for suspending the device that might be
+ * racing with its driver's interrupt handler, which is guaranteed not to
+ * run while suspend_noirq() is being executed.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static int pld_snoc_suspend_noirq(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context)
+		return -EINVAL;
+
+	if (pld_context->ops->suspend_noirq)
+		return pld_context->ops->suspend_noirq(dev, PLD_BUS_TYPE_SNOC);
+	return 0;
+}
+
+/**
+ * pld_snoc_resume_noirq() - Prepare for the execution of resume()
+ * @pdev: device
+ *
+ * Prepare for the execution of resume() by carrying out any
+ * operations required for resuming the device that might be racing with
+ * its driver's interrupt handler, which is guaranteed not to run while
+ * resume_noirq() is being executed.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static int pld_snoc_resume_noirq(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context)
+		return -EINVAL;
+
+	if (pld_context->ops->resume_noirq)
+		return pld_context->ops->resume_noirq(dev, PLD_BUS_TYPE_SNOC);
+
+	return 0;
+}
+
+static int pld_snoc_uevent(struct device *dev,
+			   struct icnss_uevent_data *uevent)
+{
+	struct pld_context *pld_context;
+	struct icnss_uevent_fw_down_data *uevent_data = NULL;
+	struct pld_uevent_data data;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context)
+		return -EINVAL;
+
+	if (!pld_context->ops->uevent)
+		goto out;
+
+	if (!uevent)
+		return -EINVAL;
+
+	switch (uevent->uevent) {
+	case ICNSS_UEVENT_FW_CRASHED:
+		data.uevent = PLD_FW_CRASHED;
+		break;
+	case ICNSS_UEVENT_FW_DOWN:
+		if (uevent->data == NULL)
+			return -EINVAL;
+		uevent_data = (struct icnss_uevent_fw_down_data *)uevent->data;
+		data.uevent = PLD_FW_DOWN;
+		data.fw_down.crashed = uevent_data->crashed;
+		break;
+	default:
+		goto out;
+	}
+
+	pld_context->ops->uevent(dev, &data);
+out:
+	return 0;
+}
+
+#ifdef MULTI_IF_NAME
+#define PLD_SNOC_OPS_NAME "pld_snoc_" MULTI_IF_NAME
+#else
+#define PLD_SNOC_OPS_NAME "pld_snoc"
+#endif
+
+struct icnss_driver_ops pld_snoc_ops = {
+	.name       = PLD_SNOC_OPS_NAME,
+	.probe      = pld_snoc_probe,
+	.remove     = pld_snoc_remove,
+	.shutdown   = pld_snoc_shutdown,
+	.reinit     = pld_snoc_reinit,
+	.crash_shutdown = pld_snoc_crash_shutdown,
+	.pm_suspend = pld_snoc_pm_suspend,
+	.pm_resume  = pld_snoc_pm_resume,
+	.suspend_noirq = pld_snoc_suspend_noirq,
+	.resume_noirq = pld_snoc_resume_noirq,
+	.uevent = pld_snoc_uevent,
+};
+
+/**
+ * pld_snoc_register_driver() - Register platform device callback functions
+ *
+ * Return: int
+ */
+int pld_snoc_register_driver(void)
+{
+	return icnss_register_driver(&pld_snoc_ops);
+}
+
+/**
+ * pld_snoc_unregister_driver() - Unregister platform device callback functions
+ *
+ * Return: void
+ */
+void pld_snoc_unregister_driver(void)
+{
+	icnss_unregister_driver(&pld_snoc_ops);
+}
+
+/**
+ * pld_snoc_wlan_enable() - Enable WLAN
+ * @dev: device
+ * @config: WLAN configuration data
+ * @mode: WLAN mode
+ * @host_version: host software version
+ *
+ * This function enables WLAN FW. It passed WLAN configuration data,
+ * WLAN mode and host software version to FW.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+
+int pld_snoc_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
+			 enum pld_driver_mode mode, const char *host_version)
+{
+	struct icnss_wlan_enable_cfg cfg;
+	enum icnss_driver_mode icnss_mode;
+
+	if (!dev)
+		return -ENODEV;
+
+	cfg.num_ce_tgt_cfg = config->num_ce_tgt_cfg;
+	cfg.ce_tgt_cfg = (struct ce_tgt_pipe_cfg *)
+		config->ce_tgt_cfg;
+	cfg.num_ce_svc_pipe_cfg = config->num_ce_svc_pipe_cfg;
+	cfg.ce_svc_cfg = (struct ce_svc_pipe_cfg *)
+		config->ce_svc_cfg;
+	cfg.num_shadow_reg_cfg = config->num_shadow_reg_cfg;
+	cfg.shadow_reg_cfg = (struct icnss_shadow_reg_cfg *)
+		config->shadow_reg_cfg;
+
+	switch (mode) {
+	case PLD_FTM:
+		icnss_mode = ICNSS_FTM;
+		break;
+	case PLD_EPPING:
+		icnss_mode = ICNSS_EPPING;
+		break;
+	default:
+		icnss_mode = ICNSS_MISSION;
+		break;
+	}
+
+	return icnss_wlan_enable(dev, &cfg, icnss_mode, host_version);
+}
+
+/**
+ * pld_snoc_wlan_disable() - Disable WLAN
+ * @dev: device
+ * @mode: WLAN mode
+ *
+ * This function disables WLAN FW. It passes WLAN mode to FW.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_snoc_wlan_disable(struct device *dev, enum pld_driver_mode mode)
+{
+	if (!dev)
+		return -ENODEV;
+
+	return icnss_wlan_disable(dev, ICNSS_OFF);
+}
+
+/**
+ * pld_snoc_get_soc_info() - Get SOC information
+ * @dev: device
+ * @info: buffer to SOC information
+ *
+ * Return SOC info to the buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_snoc_get_soc_info(struct device *dev, struct pld_soc_info *info)
+{
+	int ret = 0;
+	struct icnss_soc_info icnss_info;
+
+	if (info == NULL || !dev)
+		return -ENODEV;
+
+	ret = icnss_get_soc_info(dev, &icnss_info);
+	if (0 != ret)
+		return ret;
+
+	info->v_addr = icnss_info.v_addr;
+	info->p_addr = icnss_info.p_addr;
+	info->chip_id = icnss_info.chip_id;
+	info->chip_family = icnss_info.chip_family;
+	info->board_id = icnss_info.board_id;
+	info->soc_id = icnss_info.soc_id;
+	info->fw_version = icnss_info.fw_version;
+	strlcpy(info->fw_build_timestamp, icnss_info.fw_build_timestamp,
+		sizeof(info->fw_build_timestamp));
+
+	return 0;
+}
+#endif
diff --git a/core/pld/src/pld_snoc.h b/core/pld/src/pld_snoc.h
new file mode 100644
index 0000000..fdc5506
--- /dev/null
+++ b/core/pld/src/pld_snoc.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+#ifndef __PLD_SNOC_H__
+#define __PLD_SNOC_H__
+
+#ifdef CONFIG_PLD_SNOC_ICNSS
+#include <soc/qcom/icnss.h>
+#endif
+#include "pld_internal.h"
+
+#ifndef CONFIG_PLD_SNOC_ICNSS
+static inline int pld_snoc_register_driver(void)
+{
+	return 0;
+}
+
+static inline void pld_snoc_unregister_driver(void)
+{
+}
+static inline int pld_snoc_wlan_enable(struct device *dev,
+			struct pld_wlan_enable_cfg *config,
+			enum pld_driver_mode mode, const char *host_version)
+{
+	return 0;
+}
+static inline int pld_snoc_wlan_disable(struct device *dev,
+					enum pld_driver_mode mode)
+{
+	return 0;
+}
+static inline int pld_snoc_ce_request_irq(struct device *dev,
+					  unsigned int ce_id,
+					  irqreturn_t (*handler)(int, void *),
+					  unsigned long flags,
+					  const char *name, void *ctx)
+{
+	return 0;
+}
+static inline int pld_snoc_ce_free_irq(struct device *dev,
+				       unsigned int ce_id, void *ctx)
+{
+	return 0;
+}
+static inline void pld_snoc_enable_irq(struct device *dev, unsigned int ce_id)
+{
+}
+static inline void pld_snoc_disable_irq(struct device *dev, unsigned int ce_id)
+{
+}
+static inline int pld_snoc_get_soc_info(struct device *dev, struct pld_soc_info *info)
+{
+	return 0;
+}
+static inline int pld_snoc_get_ce_id(struct device *dev, int irq)
+{
+	return 0;
+}
+static inline int pld_snoc_power_on(struct device *dev)
+{
+	return 0;
+}
+static inline int pld_snoc_power_off(struct device *dev)
+{
+	return 0;
+}
+static inline int pld_snoc_get_irq(struct device *dev, int ce_id)
+{
+	return 0;
+}
+static inline int pld_snoc_athdiag_read(struct device *dev, uint32_t offset,
+					uint32_t memtype, uint32_t datalen,
+					uint8_t *output)
+{
+	return 0;
+}
+static inline int pld_snoc_athdiag_write(struct device *dev, uint32_t offset,
+					 uint32_t memtype, uint32_t datalen,
+					 uint8_t *input)
+{
+	return 0;
+}
+static inline void *pld_snoc_smmu_get_mapping(struct device *dev)
+{
+	return NULL;
+}
+static inline int pld_snoc_smmu_map(struct device *dev, phys_addr_t paddr,
+				    uint32_t *iova_addr, size_t size)
+{
+	return 0;
+}
+static inline
+unsigned int pld_snoc_socinfo_get_serial_number(struct device *dev)
+{
+	return 0;
+}
+static inline int pld_snoc_is_qmi_disable(struct device *dev)
+{
+	return 0;
+}
+
+static inline int pld_snoc_is_fw_down(struct device *dev)
+{
+	return 0;
+}
+static inline int pld_snoc_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
+{
+	return 0;
+}
+static inline int pld_snoc_force_assert_target(struct device *dev)
+{
+	return 0;
+}
+
+static inline int pld_snoc_is_fw_rejuvenate(void)
+{
+	return 0;
+}
+
+#else
+int pld_snoc_register_driver(void);
+void pld_snoc_unregister_driver(void);
+int pld_snoc_wlan_enable(struct device *dev,
+			 struct pld_wlan_enable_cfg *config,
+			 enum pld_driver_mode mode, const char *host_version);
+int pld_snoc_wlan_disable(struct device *dev, enum pld_driver_mode mode);
+int pld_snoc_get_soc_info(struct device *dev, struct pld_soc_info *info);
+
+static inline int pld_snoc_ce_request_irq(struct device *dev,
+					  unsigned int ce_id,
+					  irqreturn_t (*handler)(int, void *),
+					  unsigned long flags,
+					  const char *name, void *ctx)
+{
+	if (!dev)
+		return -ENODEV;
+
+	return icnss_ce_request_irq(dev, ce_id, handler, flags, name, ctx);
+}
+
+static inline int pld_snoc_ce_free_irq(struct device *dev,
+				       unsigned int ce_id, void *ctx)
+{
+	if (!dev)
+		return -ENODEV;
+
+	return icnss_ce_free_irq(dev, ce_id, ctx);
+}
+
+static inline void pld_snoc_enable_irq(struct device *dev, unsigned int ce_id)
+{
+	if (dev)
+		icnss_enable_irq(dev, ce_id);
+}
+
+static inline void pld_snoc_disable_irq(struct device *dev, unsigned int ce_id)
+{
+	if (dev)
+		icnss_disable_irq(dev, ce_id);
+}
+
+static inline int pld_snoc_get_ce_id(struct device *dev, int irq)
+{
+	if (!dev)
+		return -ENODEV;
+
+	return icnss_get_ce_id(dev, irq);
+}
+
+static inline int pld_snoc_get_irq(struct device *dev, int ce_id)
+{
+	if (!dev)
+		return -ENODEV;
+
+	return icnss_get_irq(dev, ce_id);
+}
+
+static inline int pld_snoc_power_on(struct device *dev)
+{
+	return icnss_power_on(dev);
+}
+static inline int pld_snoc_power_off(struct device *dev)
+{
+	return icnss_power_off(dev);
+}
+static inline int pld_snoc_athdiag_read(struct device *dev, uint32_t offset,
+					uint32_t memtype, uint32_t datalen,
+					uint8_t *output)
+{
+	return icnss_athdiag_read(dev, offset, memtype, datalen, output);
+}
+static inline int pld_snoc_athdiag_write(struct device *dev, uint32_t offset,
+					 uint32_t memtype, uint32_t datalen,
+					 uint8_t *input)
+{
+	return icnss_athdiag_write(dev, offset, memtype, datalen, input);
+}
+static inline void *pld_snoc_smmu_get_mapping(struct device *dev)
+{
+	return icnss_smmu_get_mapping(dev);
+}
+static inline int pld_snoc_smmu_map(struct device *dev, phys_addr_t paddr,
+				    uint32_t *iova_addr, size_t size)
+{
+	return icnss_smmu_map(dev, paddr, iova_addr, size);
+}
+static inline
+unsigned int pld_snoc_socinfo_get_serial_number(struct device *dev)
+{
+	return icnss_socinfo_get_serial_number(dev);
+}
+
+static inline int pld_snoc_is_fw_down(struct device *dev)
+{
+	return icnss_is_fw_down();
+}
+
+static inline int pld_snoc_is_qmi_disable(struct device *dev)
+{
+	if (!dev)
+		return -ENODEV;
+
+	return icnss_is_qmi_disable(dev);
+}
+
+static inline int pld_snoc_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
+{
+	if (!dev)
+		return -ENODEV;
+
+	return icnss_set_fw_log_mode(dev, fw_log_mode);
+}
+
+static inline int pld_snoc_force_assert_target(struct device *dev)
+{
+	return icnss_trigger_recovery(dev);
+}
+
+static inline int pld_snoc_is_fw_rejuvenate(void)
+{
+	return icnss_is_rejuvenate();
+}
+
+#endif
+#endif
diff --git a/core/pld/src/pld_usb.c b/core/pld/src/pld_usb.c
new file mode 100644
index 0000000..7c8e237
--- /dev/null
+++ b/core/pld/src/pld_usb.c
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+#include "pld_usb.h"
+#include "pld_internal.h"
+
+#include <linux/atomic.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#ifdef CONFIG_PLD_USB_CNSS
+#include <net/cnss2.h>
+#endif
+
+
+#define VENDOR_ATHR             0x0CF3
+static struct usb_device_id pld_usb_id_table[] = {
+	{USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ATHR, 0x9378, 0xFF, 0xFF, 0xFF)},
+	{USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ATHR, 0x9379, 0xFF, 0xFF, 0xFF)},
+	{}			/* Terminating entry */
+};
+
+atomic_t pld_usb_reg_done;
+
+/**
+ * pld_usb_probe() - pld_usb_probe
+ * @interface: pointer to usb_interface structure
+ * @id: pointer to usb_device_id obtained from the enumerated device
+
+ * Return: int 0 on success and errno on failure.
+ */
+static int pld_usb_probe(struct usb_interface *interface,
+					const struct usb_device_id *id)
+{
+	struct usb_device *pdev = interface_to_usbdev(interface);
+	struct pld_context *pld_context;
+	int ret = 0;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	ret = pld_add_dev(pld_context, &pdev->dev, PLD_BUS_TYPE_USB);
+	if (ret)
+		goto out;
+
+	ret = pld_context->ops->probe(&pdev->dev,
+				      PLD_BUS_TYPE_USB, interface, (void *)id);
+	if (ret != 0) {
+		pr_err("%s, probe returned %d", __func__, ret);
+		atomic_set(&pld_usb_reg_done, false);
+	} else {
+		atomic_set(&pld_usb_reg_done, true);
+	}
+
+out:
+	return ret;
+}
+
+/**
+ * pld_usb_remove() - Remove function for USB device
+ * @interface: pointer to usb_interface for the usb device being removed
+ *
+ * Return: void
+ */
+static void pld_usb_remove(struct usb_interface *interface)
+{
+	struct usb_device *pdev = interface_to_usbdev(interface);
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+
+	if (!pld_context)
+		return;
+
+	if (atomic_read(&pld_usb_reg_done) != true) {
+		pr_info("%s: already de-registered!\n", __func__);
+		return;
+	}
+
+	pld_context->ops->remove(&pdev->dev, PLD_BUS_TYPE_USB);
+
+	pld_del_dev(pld_context, &pdev->dev);
+
+	atomic_set(&pld_usb_reg_done, false);
+	pr_info("%s: done!\n", __func__);
+}
+
+/**
+ * pld_usb_suspend() - Suspend callback function for power management
+ * @interface: pointer to usb_interface for the usb device
+ * @state: power state
+ *
+ * This function is to suspend the PCIE device when power management is
+ * enabled.
+ *
+ * Return: void
+ */
+static int pld_usb_suspend(struct usb_interface *interface,
+						pm_message_t state)
+{
+	struct usb_device *pdev = interface_to_usbdev(interface);
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->suspend(&pdev->dev, PLD_BUS_TYPE_USB, state);
+}
+
+/**
+ * pld_usb_resume() - Resume callback function for power management
+ * @interface: pointer to usb_interface for the usb device
+ *
+ * This function is to resume the USB device when power management is
+ * enabled.
+ *
+ * Return: void
+ */
+static int pld_usb_resume(struct usb_interface *interface)
+{
+	struct pld_context *pld_context;
+	struct usb_device *pdev = interface_to_usbdev(interface);
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->resume(&pdev->dev, PLD_BUS_TYPE_USB);
+}
+
+/**
+ * pld_usb_reset_resume() - pld_usb_reset_resume
+ * @interface: pointer to usb_interface for the usb device
+ *
+ * Return: void
+ */
+static int pld_usb_reset_resume(struct usb_interface *interface)
+{
+	struct pld_context *pld_context;
+	struct usb_device *pdev = interface_to_usbdev(interface);
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->reset_resume(&pdev->dev, PLD_BUS_TYPE_USB);
+}
+
+#ifdef CONFIG_PLD_USB_CNSS
+/**
+ * pld_usb_reinit() - SSR re-initialize function for USB device
+ * @interface: Pointer to struct usb_interface
+ * @id: Pointer to USB device ID
+ *
+ * Return: int
+ */
+static int pld_usb_reinit(struct usb_interface *interface,
+			  const struct usb_device_id *id)
+{
+	struct pld_context *pld_context;
+	struct usb_device *pdev = interface_to_usbdev(interface);
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->reinit)
+		return pld_context->ops->reinit(&pdev->dev, PLD_BUS_TYPE_USB,
+						interface, (void *)id);
+
+	return -ENODEV;
+}
+
+/**
+ * pld_usb_shutdown() - SSR shutdown function for USB device
+ * @interface: Pointer to struct usb_interface
+ *
+ * Return: void
+ */
+static void pld_usb_shutdown(struct usb_interface *interface)
+{
+	struct pld_context *pld_context;
+	struct usb_device *pdev = interface_to_usbdev(interface);
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->shutdown)
+		pld_context->ops->shutdown(&pdev->dev, PLD_BUS_TYPE_USB);
+}
+
+struct cnss_usb_wlan_driver pld_usb_ops = {
+	.name = "pld_usb_cnss",
+	.id_table = pld_usb_id_table,
+	.probe = pld_usb_probe,
+	.remove = pld_usb_remove,
+	.shutdown = pld_usb_shutdown,
+	.reinit = pld_usb_reinit,
+#ifdef CONFIG_PM
+	.suspend = pld_usb_suspend,
+	.resume = pld_usb_resume,
+	.reset_resume = pld_usb_reset_resume,
+#endif
+};
+
+/**
+ * pld_usb_register_driver() - registration routine for wlan usb drive
+ *
+ * Return: int negative error code on failure and 0 on success
+ */
+int pld_usb_register_driver(void)
+{
+	pr_info("%s usb_register\n", __func__);
+	return cnss_usb_wlan_register_driver(&pld_usb_ops);
+}
+
+/**
+ * pld_usb_unregister_driver() - de-registration routine for wlan usb driver
+ *
+ * Return: void
+ */
+void pld_usb_unregister_driver(void)
+{
+	cnss_usb_wlan_unregister_driver(&pld_usb_ops);
+	pr_info("%s usb_deregister done!\n", __func__);
+}
+
+int pld_usb_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
+			enum pld_driver_mode mode, const char *host_version)
+{
+	struct cnss_wlan_enable_cfg cfg;
+	enum cnss_driver_mode cnss_mode;
+
+	switch (mode) {
+	case PLD_FTM:
+		cnss_mode = CNSS_FTM;
+		break;
+	case PLD_EPPING:
+		cnss_mode = CNSS_EPPING;
+		break;
+	default:
+		cnss_mode = CNSS_MISSION;
+		break;
+	}
+	return cnss_wlan_enable(dev, &cfg, cnss_mode, host_version);
+}
+
+#else /* CONFIG_PLD_USB_CNSS */
+
+struct usb_driver pld_usb_ops = {
+	.name = "pld_usb",
+	.id_table = pld_usb_id_table,
+	.probe = pld_usb_probe,
+	.disconnect = pld_usb_remove,
+#ifdef CONFIG_PM
+	.suspend = pld_usb_suspend,
+	.resume = pld_usb_resume,
+	.reset_resume = pld_usb_reset_resume,
+#endif
+	.supports_autosuspend = true,
+};
+
+/**
+ * pld_usb_register_driver() - registration routine for wlan usb driver
+ *
+ * Return: int negative error code on failure and 0 on success
+ */
+int pld_usb_register_driver(void)
+{
+	int status;
+
+	usb_register(&pld_usb_ops);
+
+	if (atomic_read(&pld_usb_reg_done) == true) {
+		status = 0;
+	} else {
+		usb_deregister(&pld_usb_ops);
+		status = -1;
+	}
+
+	pr_info("%s usb_register %s, status %d\n", __func__,
+		(status == 0) ? "done" : "failed", status);
+
+	return status;
+}
+
+/**
+ * pld_usb_unregister_driver() - de-registration routine for wlan usb driver
+ *
+ * Return: void
+ */
+void pld_usb_unregister_driver(void)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	if (atomic_read(&pld_usb_reg_done) == false)
+		return;
+
+	pld_context->ops->remove(NULL, PLD_BUS_TYPE_USB);
+
+	atomic_set(&pld_usb_reg_done, false);
+	usb_deregister(&pld_usb_ops);
+	pr_info("%s usb_deregister done!\n", __func__);
+}
+
+int pld_usb_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
+			enum pld_driver_mode mode, const char *host_version)
+{
+	return 0;
+}
+#endif /* CONFIG_PLD_USB_CNSS */
diff --git a/core/pld/src/pld_usb.h b/core/pld/src/pld_usb.h
new file mode 100644
index 0000000..13fddf1
--- /dev/null
+++ b/core/pld/src/pld_usb.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+#ifndef __PLD_USB_H__
+#define __PLD_USB_H__
+
+#include "pld_common.h"
+
+#ifdef HIF_USB
+int pld_usb_register_driver(void);
+void pld_usb_unregister_driver(void);
+int pld_usb_get_ce_id(int irq);
+int pld_usb_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
+			enum pld_driver_mode mode, const char *host_version);
+#else
+static inline int pld_usb_register_driver(void)
+{
+	return 0;
+}
+
+static inline void pld_usb_unregister_driver(void)
+{}
+
+static inline int pld_usb_wlan_enable(struct device *dev,
+				      struct pld_wlan_enable_cfg *config,
+				      enum pld_driver_mode mode,
+				      const char *host_version)
+{
+	return 0;
+}
+#endif
+
+static inline int
+pld_usb_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+				 u32 target_type, u32 target_version)
+{
+	pld_get_default_fw_files(pfw_files);
+	return 0;
+}
+
+#endif /*__PLD_USB_H__*/
diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h
new file mode 100644
index 0000000..f33f674
--- /dev/null
+++ b/core/sap/inc/sap_api.h
@@ -0,0 +1,1455 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef WLAN_QCT_WLANSAP_H
+#define WLAN_QCT_WLANSAP_H
+
+/**
+ * W L A N   S O F T A P  P A L   L A Y E R
+ * E X T E R N A L  A P I
+ *
+ * DESCRIPTION
+ * This file contains the external API exposed by the wlan SAP PAL layer
+ *  module.
+ */
+
+/*----------------------------------------------------------------------------
+ * Include Files
+ * -------------------------------------------------------------------------*/
+#include "cds_api.h"
+#include "cds_packet.h"
+#include "qdf_types.h"
+
+#include "sme_api.h"
+/*----------------------------------------------------------------------------
+ * Preprocessor Definitions and Constants
+ * -------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------
+ * defines and enum
+ *--------------------------------------------------------------------------*/
+#define       MAX_SSID_LEN                 32
+#define       MAX_ACL_MAC_ADDRESS          32
+#define       AUTO_CHANNEL_SELECT          0
+#define       MAX_ASSOC_IND_IE_LEN         255
+
+/* defines for WPS config states */
+#define       SAP_WPS_DISABLED             0
+#define       SAP_WPS_ENABLED_UNCONFIGURED 1
+#define       SAP_WPS_ENABLED_CONFIGURED   2
+
+#define       MAX_CHANNEL_LIST_LEN         256
+#define       QDF_MAX_NO_OF_SAP_MODE       2    /* max # of SAP */
+#define       SAP_MAX_NUM_SESSION          5
+#define       SAP_MAX_OBSS_STA_CNT         1    /* max # of OBSS STA */
+#define       SAP_ACS_WEIGHT_MAX           (26664)
+
+#define SAP_DEFAULT_24GHZ_CHANNEL     (6)
+#define SAP_DEFAULT_5GHZ_CHANNEL      (40)
+#define SAP_CHANNEL_NOT_SELECTED (0)
+
+/*--------------------------------------------------------------------------
+ * reasonCode taken from 802.11 standard.
+ * ------------------------------------------------------------------------*/
+
+typedef enum {
+	eSAP_RC_RESERVED0,              /*0 */
+	eSAP_RC_UNSPECIFIED,            /*1 */
+	eSAP_RC_PREV_AUTH_INVALID,      /*2 */
+	eSAP_RC_STA_LEFT_DEAUTH,        /*3 */
+	eSAP_RC_INACTIVITY_DISASSOC,    /*4 */
+	eSAP_RC_AP_CAPACITY_FULL,       /*5 */
+	eSAP_RC_CLS2_FROM_NON_AUTH_STA, /*6 */
+	eSAP_RC_CLS3_FROM_NON_AUTH_STA, /*7 */
+	eSAP_RC_STA_LEFT_DISASSOC,      /*8 */
+	eSAP_RC_STA_NOT_AUTH,           /*9 */
+	eSAP_RC_PC_UNACCEPTABLE,        /*10 */
+	eSAP_RC_SC_UNACCEPTABLE,        /*11 */
+	eSAP_RC_RESERVED1,              /*12 */
+	eSAP_RC_INVALID_IE,             /*13 */
+	eSAP_RC_MIC_FAIL,               /*14 */
+	eSAP_RC_4_WAY_HANDSHAKE_TO,     /*15 */
+	eSAP_RC_GO_KEY_HANDSHAKE_TO,    /*16 */
+	eSAP_RC_IE_MISMATCH,            /*17 */
+	eSAP_RC_INVALID_GRP_CHIPHER,    /*18 */
+	eSAP_RC_INVALID_PAIR_CHIPHER,   /*19 */
+	eSAP_RC_INVALID_AKMP,           /*20 */
+	eSAP_RC_UNSUPPORTED_RSN,        /*21 */
+	eSAP_RC_INVALID_RSN,            /*22 */
+	eSAP_RC_1X_AUTH_FAILED,         /*23 */
+	eSAP_RC_CHIPER_SUITE_REJECTED,  /*24 */
+} eSapReasonCode;
+
+typedef enum {
+	eSAP_ACCEPT_UNLESS_DENIED = 0,
+	eSAP_DENY_UNLESS_ACCEPTED = 1,
+	/* this type is added to support accept & deny list at the same time */
+	eSAP_SUPPORT_ACCEPT_AND_DENY = 2,
+	/*In this mode all MAC addresses are allowed to connect */
+	eSAP_ALLOW_ALL = 3,
+} eSapMacAddrACL;
+
+typedef enum {
+	eSAP_BLACK_LIST = 0,   /* List of mac addresses NOT allowed to assoc */
+	eSAP_WHITE_LIST = 1,   /* List of mac addresses allowed to assoc */
+} eSapACLType;
+
+typedef enum {
+	ADD_STA_TO_ACL = 0,       /* cmd to add STA to access control list */
+	DELETE_STA_FROM_ACL = 1,  /* cmd to del STA from access control list */
+} eSapACLCmdType;
+
+typedef enum {
+	eSAP_START_BSS_EVENT = 0,     /* Event sent when BSS is started */
+	eSAP_STOP_BSS_EVENT,          /* Event sent when BSS is stopped */
+	eSAP_STA_ASSOC_IND,           /* Indicate assoc req to upper layers */
+	/*
+	 * Event sent when we have successfully associated a station and
+	 * upper layer neeeds to allocate a context
+	 */
+	eSAP_STA_ASSOC_EVENT,
+	/*
+	 * Event sent when we have successfully reassociated a station and
+	 * upper layer neeeds to allocate a context
+	 */
+	eSAP_STA_REASSOC_EVENT,
+	/*
+	 * Event sent when associated a station has disassociated as a
+	 * result of various conditions
+	 */
+	eSAP_STA_DISASSOC_EVENT,
+	/* Event sent when user called wlansap_set_key_sta */
+	eSAP_STA_SET_KEY_EVENT,
+	/* Event sent whenever there is MIC failure detected */
+	eSAP_STA_MIC_FAILURE_EVENT,
+	/* Event sent when user called wlansap_get_assoc_stations */
+	eSAP_ASSOC_STA_CALLBACK_EVENT,
+	/* Event send on WPS PBC probe request is received */
+	eSAP_WPS_PBC_PROBE_REQ_EVENT,
+	eSAP_DISCONNECT_ALL_P2P_CLIENT,
+	eSAP_MAC_TRIG_STOP_BSS_EVENT,
+	/*
+	 * Event send when a STA in neither white list or black list tries to
+	 * associate in softap mode
+	 */
+	eSAP_UNKNOWN_STA_JOIN,
+	/* Event send when a new STA is rejected association since softAP
+	 * max assoc limit has reached
+	 */
+	eSAP_MAX_ASSOC_EXCEEDED,
+	eSAP_CHANNEL_CHANGE_EVENT,
+	eSAP_DFS_CAC_START,
+	eSAP_DFS_CAC_INTERRUPTED,
+	eSAP_DFS_CAC_END,
+	eSAP_DFS_PRE_CAC_END,
+	eSAP_DFS_RADAR_DETECT,
+	eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC,
+	/* No ch available after DFS RADAR detect */
+	eSAP_DFS_NO_AVAILABLE_CHANNEL,
+	eSAP_STOP_BSS_DUE_TO_NO_CHNL,
+	eSAP_ACS_SCAN_SUCCESS_EVENT,
+	eSAP_ACS_CHANNEL_SELECTED,
+	eSAP_ECSA_CHANGE_CHAN_IND,
+	eSAP_DFS_NEXT_CHANNEL_REQ,
+} eSapHddEvent;
+
+typedef enum {
+	eSAP_OPEN_SYSTEM,
+	eSAP_SHARED_KEY,
+	eSAP_AUTO_SWITCH
+} eSapAuthType;
+
+typedef enum {
+	/* Disassociation was internally initated from CORE stack */
+	eSAP_MAC_INITATED_DISASSOC = 0x10000,
+	/*
+	 * Disassociation was internally initated from host by
+	 * invoking wlansap_disassoc_sta call
+	 */
+	eSAP_USR_INITATED_DISASSOC
+} eSapDisassocReason;
+
+typedef enum {
+	eSAP_DFS_NOL_CLEAR,
+	eSAP_DFS_NOL_RANDOMIZE,
+} eSapDfsNolType;
+
+/*---------------------------------------------------------------------------
+  SAP PAL "status" and "reason" error code defines
+  ---------------------------------------------------------------------------*/
+typedef enum {
+	eSAP_STATUS_SUCCESS,            /* Success.  */
+	eSAP_STATUS_FAILURE,            /* General Failure.  */
+	/* Channel not selected during initial scan.  */
+	eSAP_START_BSS_CHANNEL_NOT_SELECTED,
+	eSAP_ERROR_MAC_START_FAIL,     /* Failed to start Infra BSS */
+} eSapStatus;
+
+/*---------------------------------------------------------------------------
+  SAP PAL "status" and "reason" error code defines
+  ---------------------------------------------------------------------------*/
+typedef enum {
+	eSAP_WPSPBC_OVERLAP_IN120S,  /* Overlap */
+	/* no WPS probe request in 120 second */
+	eSAP_WPSPBC_NO_WPSPBC_PROBE_REQ_IN120S,
+	/* One WPS probe request in 120 second  */
+	eSAP_WPSPBC_ONE_WPSPBC_PROBE_REQ_IN120S,
+} eWPSPBCOverlap;
+
+/*---------------------------------------------------------------------------
+  SAP Associated station types
+  ---------------------------------------------------------------------------*/
+typedef enum {
+	eSTA_TYPE_NONE    = 0x00000000,  /* No station type */
+	eSTA_TYPE_INFRA   = 0x00000001,  /* legacy station */
+	eSTA_TYPE_P2P_CLI = 0x00000002,  /* p2p client */
+} eStationType;
+
+/*----------------------------------------------------------------------------
+ *  Typedefs
+ * -------------------------------------------------------------------------*/
+typedef struct sap_StartBssCompleteEvent_s {
+	uint8_t status;
+	uint8_t operatingChannel;
+	enum phy_ch_width ch_width;
+	uint16_t staId;         /* self StaID */
+	uint8_t sessionId;      /* SoftAP SME session ID */
+} tSap_StartBssCompleteEvent;
+
+typedef struct sap_StopBssCompleteEvent_s {
+	uint8_t status;
+} tSap_StopBssCompleteEvent;
+
+typedef struct sap_StationAssocIndication_s {
+	struct qdf_mac_addr staMac;
+	uint8_t assoId;
+	uint8_t staId;
+	uint8_t status;
+	/* Required for indicating the frames to upper layer */
+	uint32_t beaconLength;
+	uint8_t *beaconPtr;
+	uint32_t assocReqLength;
+	uint8_t *assocReqPtr;
+	bool fWmmEnabled;
+	eCsrAuthType negotiatedAuthType;
+	eCsrEncryptionType negotiatedUCEncryptionType;
+	eCsrEncryptionType negotiatedMCEncryptionType;
+	bool fAuthRequired;
+	uint8_t ecsa_capable;
+} tSap_StationAssocIndication;
+
+typedef struct sap_StationAssocReassocCompleteEvent_s {
+	struct qdf_mac_addr staMac;
+	eStationType staType;
+	uint8_t staId;
+	uint8_t status;
+	uint8_t ies[MAX_ASSOC_IND_IE_LEN];
+	uint16_t iesLen;
+	uint32_t statusCode;
+	eSapAuthType SapAuthType;
+	bool wmmEnabled;
+	/* Required for indicating the frames to upper layer */
+	uint32_t beaconLength;
+	uint8_t *beaconPtr;
+	uint32_t assocReqLength;
+	uint8_t *assocReqPtr;
+	uint32_t assocRespLength;
+	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;
+	uint8_t ecsa_capable;
+	tDot11fIEHTCaps ht_caps;
+	tDot11fIEVHTCaps vht_caps;
+} tSap_StationAssocReassocCompleteEvent;
+
+typedef struct sap_StationDisassocCompleteEvent_s {
+	struct qdf_mac_addr staMac;
+	uint8_t staId;          /* STAID should not be used */
+	uint8_t status;
+	uint32_t statusCode;
+	uint32_t reason_code;
+	eSapDisassocReason reason;
+	int rssi;
+	int tx_rate;
+	int rx_rate;
+} tSap_StationDisassocCompleteEvent;
+
+typedef struct sap_StationSetKeyCompleteEvent_s {
+	uint8_t status;
+	struct qdf_mac_addr peerMacAddr;
+} tSap_StationSetKeyCompleteEvent;
+
+/*struct corresponding to SAP_STA_MIC_FAILURE_EVENT */
+typedef struct sap_StationMICFailureEvent_s {
+	struct qdf_mac_addr srcMacAddr;    /* address used to compute MIC */
+	struct qdf_mac_addr staMac;        /* taMacAddr transmitter address */
+	struct qdf_mac_addr dstMacAddr;
+	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 */
+
+} tSap_StationMICFailureEvent;
+/*Structure to return MAC address of associated stations */
+typedef struct sap_AssocMacAddr_s {
+	struct qdf_mac_addr staMac; /* Associated station's MAC address */
+	uint8_t assocId;            /* Associated station's Association ID */
+	uint8_t staId;              /* Allocated station Id */
+	uint8_t ShortGI40Mhz;
+	uint8_t ShortGI20Mhz;
+	uint8_t Support40Mhz;
+	uint32_t requestedMCRate;
+	tSirSupportedRates supportedRates;
+} tSap_AssocMacAddr, *tpSap_AssocMacAddr;
+
+/*struct corresponding to SAP_ASSOC_STA_CALLBACK_EVENT */
+typedef struct sap_AssocStaListEvent_s {
+	QDF_MODULE_ID module;
+	/* module id that was passed in wlansap_get_assoc_stations API */
+	uint8_t noOfAssocSta;           /* Number of associated stations */
+	tpSap_AssocMacAddr pAssocStas;
+	/*
+	 * Pointer to pre allocated memory to obtain list of
+	 * associated stations passed in wlansap_get_assoc_stations API
+	 */
+} tSap_AssocStaListEvent;
+
+typedef struct sap_GetWPSPBCSessionEvent_s {
+	uint8_t status;
+	/* module id that was passed in wlansap_get_assoc_stations API */
+	QDF_MODULE_ID module;
+	uint8_t UUID_E[16];             /* Unique identifier of the AP. */
+	struct qdf_mac_addr addr;
+	eWPSPBCOverlap wpsPBCOverlap;
+} tSap_GetWPSPBCSessionEvent;
+
+typedef struct sap_WPSPBCProbeReqEvent_s {
+	uint8_t status;
+	/* module id that was passed in wlansap_get_assoc_stations API */
+	QDF_MODULE_ID module;
+	tSirWPSPBCProbeReq WPSPBCProbeReq;
+} tSap_WPSPBCProbeReqEvent;
+
+typedef struct sap_ManagementFrameInfo_s {
+	uint32_t nFrameLength;
+	uint8_t frameType;
+	uint32_t rxChan;           /* Channel of where packet is received */
+	/*
+	 * Point to a buffer contain the beacon, assoc req, assoc rsp frame,
+	 * in that order user needs to use nBeaconLength, nAssocReqLength,
+	 * nAssocRspLength to desice where each frame starts and ends.
+	 */
+	uint8_t *pbFrames;
+} tSap_ManagementFrameInfo;
+
+typedef struct sap_SendActionCnf_s {
+	eSapStatus actionSendSuccess;
+} tSap_SendActionCnf;
+
+typedef struct sap_UnknownSTAJoinEvent_s {
+	struct qdf_mac_addr macaddr;
+} tSap_UnknownSTAJoinEvent;
+
+typedef struct sap_MaxAssocExceededEvent_s {
+	struct qdf_mac_addr macaddr;
+} tSap_MaxAssocExceededEvent;
+
+typedef struct sap_DfsNolInfo_s {
+	uint16_t sDfsList;              /* size of pDfsList in byte */
+	void *pDfsList;             /* pointer to pDfsList buffer */
+} tSap_DfsNolInfo;
+
+/**
+ * sap_acs_ch_selected_s - the structure to hold the selected channels
+ * @pri_channel:	   Holds the ACS selected primary channel
+ * @sec_channel:	   Holds the ACS selected secondary channel
+ *
+ * Holds the primary and secondary channel selected by ACS and is
+ * used to send it to the HDD.
+ */
+struct sap_ch_selected_s {
+	uint16_t pri_ch;
+	uint16_t ht_sec_ch;
+	uint16_t vht_seg0_center_ch;
+	uint16_t vht_seg1_center_ch;
+	uint16_t ch_width;
+};
+
+/**
+ * sap_roc_ready_ind_s - the structure to hold the scan id
+ * @scan_id: scan identifier
+ *
+ * Holds scan identifier
+ */
+struct sap_roc_ready_ind_s {
+	uint32_t scan_id;
+};
+
+/**
+ * struct sap_acs_scan_complete_event - acs scan complete event
+ * @status: status of acs scan
+ * @channellist: acs scan channels
+ * @num_of_channels: number of channels
+ */
+struct sap_acs_scan_complete_event {
+	uint8_t status;
+	uint8_t *channellist;
+	uint8_t num_of_channels;
+};
+
+/**
+ * struct sap_ch_change_ind - channel change indication
+ * @new_chan: channel to change
+ */
+struct sap_ch_change_ind {
+	uint16_t new_chan;
+};
+
+/*
+ * This struct will be filled in and passed to tpWLAN_SAPEventCB that is
+ * provided during wlansap_start_bss call The event id corresponding to
+ * structure  in the union is defined in comment next to the structure
+ */
+
+typedef struct sap_Event_s {
+	eSapHddEvent sapHddEventCode;
+	union {
+		/*SAP_START_BSS_EVENT */
+		tSap_StartBssCompleteEvent sapStartBssCompleteEvent;
+		/*SAP_STOP_BSS_EVENT */
+		tSap_StopBssCompleteEvent sapStopBssCompleteEvent;
+		/*SAP_ASSOC_INDICATION */
+		tSap_StationAssocIndication sapAssocIndication;
+		/*SAP_STA_ASSOC_EVENT, SAP_STA_REASSOC_EVENT */
+		tSap_StationAssocReassocCompleteEvent
+				sapStationAssocReassocCompleteEvent;
+		/*SAP_STA_DISASSOC_EVENT */
+		tSap_StationDisassocCompleteEvent
+				sapStationDisassocCompleteEvent;
+		/*SAP_STA_SET_KEY_EVENT */
+		tSap_StationSetKeyCompleteEvent sapStationSetKeyCompleteEvent;
+		/*SAP_STA_MIC_FAILURE_EVENT */
+		tSap_StationMICFailureEvent sapStationMICFailureEvent;
+		/*SAP_ASSOC_STA_CALLBACK_EVENT */
+		tSap_AssocStaListEvent sapAssocStaListEvent;
+		/*SAP_GET_WPSPBC_SESSION_EVENT */
+		tSap_GetWPSPBCSessionEvent sapGetWPSPBCSessionEvent;
+		/*eSAP_WPS_PBC_PROBE_REQ_EVENT */
+		tSap_WPSPBCProbeReqEvent sapPBCProbeReqEvent;
+		tSap_SendActionCnf sapActionCnf;
+		/* eSAP_UNKNOWN_STA_JOIN */
+		tSap_UnknownSTAJoinEvent sapUnknownSTAJoin;
+		/* eSAP_MAX_ASSOC_EXCEEDED */
+		tSap_MaxAssocExceededEvent sapMaxAssocExceeded;
+		/*eSAP_DFS_NOL_XXX */
+		tSap_DfsNolInfo sapDfsNolInfo;
+		struct sap_ch_selected_s sap_ch_selected;
+		struct sap_roc_ready_ind_s sap_roc_ind;
+		struct sap_ch_change_ind sap_chan_cng_ind;
+		struct sap_acs_scan_complete_event sap_acs_scan_comp;
+	} sapevt;
+} tSap_Event, *tpSap_Event;
+
+typedef struct sap_SSID {
+	uint8_t length;
+	uint8_t ssId[MAX_SSID_LEN];
+} qdf_packed tSap_SSID_t;
+
+typedef struct sap_SSIDInfo {
+	tSap_SSID_t ssid;     /* SSID of the AP */
+	/* SSID should/shouldn't be bcast in probe RSP & beacon */
+	uint8_t ssidHidden;
+} qdf_packed tSap_SSIDInfo_t;
+
+struct sap_acs_cfg {
+	/* ACS Algo Input */
+	uint8_t    acs_mode;
+	eCsrPhyMode hw_mode;
+	uint8_t    start_ch;
+	uint8_t    end_ch;
+	uint8_t    *ch_list;
+	uint8_t    ch_list_count;
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+	uint8_t    skip_scan_status;
+	uint8_t    skip_scan_range1_stch;
+	uint8_t    skip_scan_range1_endch;
+	uint8_t    skip_scan_range2_stch;
+	uint8_t    skip_scan_range2_endch;
+#endif
+
+	uint16_t   ch_width;
+	uint8_t    pcl_channels[QDF_MAX_NUM_CHAN];
+	uint8_t    pcl_channels_weight_list[QDF_MAX_NUM_CHAN];
+	uint32_t   pcl_ch_count;
+	uint8_t    is_ht_enabled;
+	uint8_t    is_vht_enabled;
+	/* ACS Algo Output */
+	uint8_t    pri_ch;
+	uint8_t    ht_sec_ch;
+	uint8_t    vht_seg0_center_ch;
+	uint8_t    vht_seg1_center_ch;
+	uint32_t   band;
+};
+
+/*
+ * enum vendor_ie_access_policy- access policy
+ * @ACCESS_POLICY_NONE: access policy attribute is not valid
+ * @ACCESS_POLICY_RESPOND_IF_IE_IS_PRESENT: respond to probe req/assoc req
+ *  only if ie is present
+ * @ACCESS_POLICY_DONOT_RESPOND_IF_IE_IS_PRESENT: do not respond to probe req/
+ *  assoc req if ie is present
+*/
+enum vendor_ie_access_policy {
+	ACCESS_POLICY_NONE,
+	ACCESS_POLICY_RESPOND_IF_IE_IS_PRESENT,
+	ACCESS_POLICY_DONOT_RESPOND_IF_IE_IS_PRESENT,
+};
+
+/*
+ * enum sap_acs_dfs_mode- state of DFS mode
+ * @ACS_DFS_MODE_NONE: DFS mode attribute is not valid
+ * @ACS_DFS_MODE_ENABLE:  DFS mode is enabled
+ * @ACS_DFS_MODE_DISABLE: DFS mode is disabled
+ * @ACS_DFS_MODE_DEPRIORITIZE: Deprioritize DFS channels in scanning
+ */
+enum  sap_acs_dfs_mode {
+	ACS_DFS_MODE_NONE,
+	ACS_DFS_MODE_ENABLE,
+	ACS_DFS_MODE_DISABLE,
+	ACS_DFS_MODE_DEPRIORITIZE
+};
+
+typedef struct sap_config {
+	tSap_SSIDInfo_t SSIDinfo;
+	eCsrPhyMode SapHw_mode;         /* Wireless Mode */
+	eSapMacAddrACL SapMacaddr_acl;
+	struct qdf_mac_addr accept_mac[MAX_ACL_MAC_ADDRESS]; /* MAC filtering */
+	bool ieee80211d;      /* Specify if 11D is enabled or disabled */
+	bool protEnabled;     /* Specify if protection is enabled or disabled */
+	/* Specify if OBSS protection is enabled or disabled */
+	bool obssProtEnabled;
+	struct qdf_mac_addr deny_mac[MAX_ACL_MAC_ADDRESS];  /* MAC filtering */
+	struct qdf_mac_addr self_macaddr;       /* self macaddress or BSSID */
+	uint8_t channel;          /* Operation channel */
+	uint8_t sec_ch;
+	struct ch_params ch_params;
+	uint32_t ch_width_orig;
+	uint8_t max_num_sta;      /* maximum number of STAs in station table */
+	uint8_t dtim_period;      /* dtim interval */
+	uint8_t num_accept_mac;
+	uint8_t num_deny_mac;
+	/* Max ie length 255 * 2(WPA+RSN) + 2 bytes(vendor specific ID) * 2 */
+	uint8_t RSNWPAReqIE[(SIR_MAC_MAX_IE_LENGTH * 2) + 4];
+	/* it is ignored if [0] is 0. */
+	uint8_t countryCode[WNI_CFG_COUNTRY_CODE_LEN];
+	uint8_t RSNAuthType;
+	uint8_t RSNEncryptType;
+	uint8_t mcRSNEncryptType;
+	eSapAuthType authType;
+	bool privacy;
+	bool UapsdEnable;
+	bool fwdWPSPBCProbeReq;
+	/* 0 - disabled, 1 - not configured , 2 - configured */
+	uint8_t wps_state;
+	uint16_t ht_capab;
+	uint16_t RSNWPAReqIELength;     /* The byte count in the pWPAReqIE */
+	uint32_t beacon_int;            /* Beacon Interval */
+	uint32_t ap_table_max_size;
+	uint32_t ap_table_expiration_time;
+	uint32_t ht_op_mode_fixed;
+	enum QDF_OPMODE persona; /* Tells us which persona, GO or AP */
+	uint8_t disableDFSChSwitch;
+	bool enOverLapCh;
+#ifdef WLAN_FEATURE_11W
+	bool mfpRequired;
+	bool mfpCapable;
+#endif
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	uint8_t cc_switch_mode;
+#endif
+	uint32_t auto_channel_select_weight;
+	struct sap_acs_cfg acs_cfg;
+	uint16_t probeRespIEsBufferLen;
+	/* buffer for addn ies comes from hostapd */
+	void *pProbeRespIEsBuffer;
+	uint16_t assocRespIEsLen;
+	/* buffer for addn ies comes from hostapd */
+	void *pAssocRespIEsBuffer;
+	uint16_t probeRespBcnIEsLen;
+	/* buffer for addn ies comes from hostapd */
+	void *pProbeRespBcnIEsBuffer;
+	uint16_t beacon_tx_rate;
+	uint8_t *vendor_ie;
+	enum vendor_ie_access_policy vendor_ie_access_policy;
+	uint16_t sta_inactivity_timeout;
+	uint16_t tx_pkt_fail_cnt_threshold;
+	uint8_t short_retry_limit;
+	uint8_t long_retry_limit;
+	uint8_t ampdu_size;
+	tSirMacRateSet supported_rates;
+	tSirMacRateSet extended_rates;
+	enum sap_acs_dfs_mode acs_dfs_mode;
+	struct hdd_channel_info *channel_info;
+	uint32_t channel_info_count;
+	bool dfs_cac_offload;
+	/* beacon count before channel switch */
+	uint8_t sap_chanswitch_beacon_cnt;
+	uint8_t sap_chanswitch_mode;
+	bool chan_switch_hostapd_rate_enabled;
+	bool dfs_beacon_tx_enhanced;
+	uint16_t reduced_beacon_interval;
+} tsap_config_t;
+
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+typedef enum {
+	eSAP_DO_NEW_ACS_SCAN,
+	eSAP_DO_PAR_ACS_SCAN,
+	eSAP_SKIP_ACS_SCAN
+} tSap_skip_acs_scan;
+#endif
+
+typedef enum {
+	eSAP_DFS_DO_NOT_SKIP_CAC,
+	eSAP_DFS_SKIP_CAC
+} eSapDfsCACState_t;
+
+typedef enum {
+	eSAP_DFS_CHANNEL_USABLE,
+	eSAP_DFS_CHANNEL_AVAILABLE,
+	eSAP_DFS_CHANNEL_UNAVAILABLE
+} eSapDfsChanStatus_t;
+
+typedef struct sSapDfsNolInfo {
+	uint8_t dfs_channel_number;
+	eSapDfsChanStatus_t radar_status_flag;
+	uint64_t radar_found_timestamp;
+} tSapDfsNolInfo;
+
+typedef struct sSapDfsInfo {
+	qdf_mc_timer_t sap_dfs_cac_timer;
+	uint8_t sap_radar_found_status;
+	/*
+	 * New channel to move to when a  Radar is
+	 * detected on current Channel
+	 */
+	uint8_t target_channel;
+	uint8_t last_radar_found_channel;
+	uint8_t ignore_cac;
+	eSapDfsCACState_t cac_state;
+	uint8_t user_provided_target_channel;
+
+	/*
+	 * Requests for Channel Switch Announcement IE
+	 * generation and transmission
+	 */
+	uint8_t csaIERequired;
+	uint8_t numCurrentRegDomainDfsChannels;
+	tSapDfsNolInfo sapDfsChannelNolList[NUM_5GHZ_CHANNELS];
+	uint8_t is_dfs_cac_timer_running;
+	/*
+	 * New channel width and new channel bonding mode
+	 * will only be updated via channel fallback mechanism
+	 */
+	enum phy_ch_width orig_chanWidth;
+	enum phy_ch_width new_chanWidth;
+	struct ch_params new_ch_params;
+
+	/*
+	 * INI param to enable/disable SAP W53
+	 * channel operation.
+	 */
+	uint8_t is_dfs_w53_disabled;
+
+	/*
+	 * sap_operating_channel_location holds SAP indoor,
+	 * outdoor location information. Currently, if this
+	 * param is  set this Indoor/outdoor channel interop
+	 * restriction will only be implemented for JAPAN
+	 * regulatory domain.
+	 *
+	 * 0 - Indicates that location unknown
+	 * (or) SAP Indoor/outdoor interop is allowed
+	 *
+	 * 1 - Indicates device is operating on Indoor channels
+	 * and SAP cannot pick next random channel from outdoor
+	 * list of channels when a radar is found on current operating
+	 * DFS channel.
+	 *
+	 * 2 - Indicates device is operating on Outdoor Channels
+	 * and SAP cannot pick next random channel from indoor
+	 * list of channels when a radar is found on current
+	 * operating DFS channel.
+	 */
+	uint8_t sap_operating_chan_preferred_location;
+
+	/*
+	 * Flag to indicate if DFS test mode is enabled and
+	 * channel switch is disabled.
+	 */
+	uint8_t disable_dfs_ch_switch;
+	uint16_t tx_leakage_threshold;
+	/* beacon count before channel switch */
+	uint8_t sap_ch_switch_beacon_cnt;
+	uint8_t sap_ch_switch_mode;
+	bool dfs_beacon_tx_enhanced;
+	uint16_t reduced_beacon_interval;
+} tSapDfsInfo;
+
+typedef struct tagSapCtxList {
+	uint8_t sessionID;
+	void *sap_context;
+	enum QDF_OPMODE sapPersona;
+} tSapCtxList, tpSapCtxList;
+
+typedef struct tagSapStruct {
+	/* Information Required for SAP DFS Master mode */
+	tSapDfsInfo SapDfsInfo;
+	tSapCtxList sapCtxList[SAP_MAX_NUM_SESSION];
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	bool sap_channel_avoidance;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+	bool acs_with_more_param;
+	bool enable_dfs_phy_error_logs;
+	bool enable_etsi13_srd_chan_support;
+} tSapStruct, *tpSapStruct;
+
+typedef struct sap_SoftapStats_s {
+	uint32_t txUCFcnt;
+	uint32_t txMCFcnt;
+	uint32_t txBCFcnt;
+	uint32_t txUCBcnt;
+	uint32_t txMCBcnt;
+	uint32_t txBCBcnt;
+	uint32_t rxUCFcnt;
+	uint32_t rxMCFcnt;
+	uint32_t rxBCFcnt;
+	uint32_t rxUCBcnt;
+	uint32_t rxMCBcnt;
+	uint32_t rxBCBcnt;
+	uint32_t rxBcnt;
+	uint32_t rxBcntCRCok;
+	uint32_t rxRate;
+} tSap_SoftapStats, *tpSap_SoftapStats;
+
+#ifdef FEATURE_WLAN_CH_AVOID
+/* Store channel safety information */
+typedef struct {
+	uint16_t channelNumber;
+	bool isSafe;
+} sapSafeChannelType;
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+/**
+ * struct sap_context - per-BSS Context for SAP
+ *
+ * struct sap_context is used to share per-BSS context between SAP and
+ * its clients. A context is generated by sap_create_ctx() and is
+ * destroyed by sap_destroy_ctx(). During the lifetime of the BSS the
+ * SAP context is passed as the primary parameter to SAP APIs. Note
+ * that by design the contents of the structure are opaque to the
+ * clients and a SAP context pointer must only be dereferenced by SAP.
+ */
+struct sap_context;
+
+/**
+ * wlansap_roam_callback() - API to get the events for SAP persona
+ * @pContext: sap context
+ * @pCsrRoamInfo: pointer to SME CSR roam info structure
+ * @roamId: roam id being used
+ * @roamStatus: status of the event reported by SME to SAP
+ * @roamResult: result of the event reported by SME to SAP
+ *
+ * Any activity like start_bss, stop_bss, and etc for SAP persona
+ * happens, SME reports the result of those events to SAP through this
+ * callback.
+ *
+ * Return: QDF_STATUS based on overall result
+ */
+QDF_STATUS wlansap_roam_callback(void *pContext,
+				 struct csr_roam_info *pCsrRoamInfo,
+				 uint32_t roamId,
+				 eRoamCmdStatus roamStatus,
+				 eCsrRoamResult roamResult);
+
+/**
+ * sap_create_ctx() - API to create the sap context
+ *
+ * This API assigns the sap context from global sap context pool
+ * stored in gp_sap_ctx[i] array.
+ *
+ * Return: Pointer to the SAP context, or NULL if a context could not
+ * be allocated
+ */
+struct sap_context *sap_create_ctx(void);
+
+/**
+ * sap_destroy_ctx - API to destroy the sap context
+ * @sap_ctx: Pointer to the SAP context
+ *
+ * This API puts back the given sap context to global sap context pool which
+ * makes current sap session's sap context invalid.
+ *
+ * Return: The result code associated with performing the operation
+ *         QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL;
+ *                             access would cause a page fault
+ *         QDF_STATUS_SUCCESS: Success
+ */
+QDF_STATUS sap_destroy_ctx(struct sap_context *sap_ctx);
+
+/**
+ * sap_init_ctx - Initialize the sap context
+ * @sap_ctx: Pointer to the SAP context
+ * @mode: Device mode
+ * @addr: MAC address of the SAP
+ * @session_id: Pointer to the session id
+ * @reinit: if called as part of reinit
+ *
+ * sap_create_ctx() allocates the sap context which is uninitialized.
+ * This API needs to be called to properly initialize the sap context
+ * which is just created.
+ *
+ * Return: The result code associated with performing the operation
+ *         QDF_STATUS_E_FAULT: BSS could not be started
+ *         QDF_STATUS_SUCCESS: Success
+ */
+QDF_STATUS sap_init_ctx(struct sap_context *sap_ctx,
+			 enum QDF_OPMODE mode,
+			 uint8_t *addr, uint32_t session_id, bool reinit);
+
+/**
+ * sap_deinit_ctx() - De-initialize the sap context
+ * @sap_ctx: Pointer to the SAP context
+ *
+ * When SAP session is about to close, this API needs to be called
+ * to de-initialize all the members of sap context structure, so that
+ * nobody can accidently start using the sap context.
+ *
+ * Return: The result code associated with performing the operation
+ *         QDF_STATUS_E_FAULT: BSS could not be stopped
+ *         QDF_STATUS_SUCCESS: Success
+ */
+QDF_STATUS sap_deinit_ctx(struct sap_context *sap_ctx);
+
+/**
+ * sap_is_auto_channel_select() - is channel AUTO_CHANNEL_SELECT
+ * @sapcontext: Pointer to the SAP context
+ *
+ * Return: true on AUTO_CHANNEL_SELECT, false otherwise
+ */
+bool sap_is_auto_channel_select(struct sap_context *sapcontext);
+
+QDF_STATUS wlansap_global_init(void);
+QDF_STATUS wlansap_global_deinit(void);
+typedef QDF_STATUS (*tpWLAN_SAPEventCB)(tpSap_Event pSapEvent,
+					void *pUsrContext);
+
+/**
+ * wlansap_is_channel_in_nol_list() - This API checks if channel is
+ * in nol list
+ * @sap_ctx: SAP context pointer
+ * @channelNumber: channel number
+ * @chanBondState: channel bonding state
+ *
+ * Return: True if the channel is in the NOL list, false otherwise
+ */
+bool wlansap_is_channel_in_nol_list(struct sap_context *sap_ctx,
+				    uint8_t channelNumber,
+				    ePhyChanBondState chanBondState);
+
+/**
+ * wlansap_is_channel_leaking_in_nol() - This API checks if channel is leaking
+ * in nol list
+ * @sap_ctx: SAP context pointer
+ * @channel: channel
+ * @chan_bw: channel bandwidth
+ *
+ * Return: True/False
+ */
+bool wlansap_is_channel_leaking_in_nol(struct sap_context *sap_ctx,
+				       uint8_t channel,
+				       uint8_t chan_bw);
+
+/**
+ * wlansap_start_bss() - start BSS
+ * @sap_ctx: Pointer to the SAP context
+ * @pSapEventCallback: Callback function in HDD called by SAP to inform HDD
+ *                        about SAP results
+ * @pConfig: Pointer to configuration structure passed down from
+ *                    HDD(HostApd for Android)
+ * @pUsrContext: Parameter that will be passed back in all the SAP callback
+ *               events.
+ *
+ * This api function provides SAP FSM event eWLAN_SAP_PHYSICAL_LINK_CREATE for
+ * starting AP BSS
+ *
+ * Return: The result code associated with performing the operation
+ *         QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL;
+ *                             access would cause a page fault
+ *         QDF_STATUS_SUCCESS: Success
+ */
+QDF_STATUS wlansap_start_bss(struct sap_context *sap_ctx,
+			     tpWLAN_SAPEventCB pSapEventCallback,
+			     tsap_config_t *pConfig, void *pUsrContext);
+
+/**
+ * wlansap_stop_bss() - stop BSS.
+ * @sap_ctx: Pointer to SAP context
+ *
+ * This api function provides SAP FSM event eSAP_HDD_STOP_INFRA_BSS for
+ * stopping AP BSS
+ *
+ * Return: The result code associated with performing the operation
+ *         QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL;
+ *                             access would cause a page fault
+ *         QDF_STATUS_SUCCESS: Success
+ */
+QDF_STATUS wlansap_stop_bss(struct sap_context *sap_ctx);
+
+/**
+ * wlan_sap_update_next_channel() - Update next channel configured using vendor
+ * command in SAP context
+ * @sap_ctx: SAP context
+ * @channel: channel number
+ * @chan_bw: channel width
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_sap_update_next_channel(struct sap_context *sap_ctx,
+					uint8_t channel,
+					enum phy_ch_width chan_bw);
+
+/**
+ * wlan_sap_set_pre_cac_status() - Set the pre cac status
+ * @sap_ctx: SAP context
+ * @status: Status of pre cac
+ *
+ * Updates the state of pre cac in the SAP context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_sap_set_pre_cac_status(struct sap_context *sap_ctx,
+				       bool status);
+
+/**
+ * wlan_sap_set_chan_before_pre_cac() - Save the channel before pre cac
+ * @sap_ctx: SAP context
+ * @chan_before_pre_cac: Channel before pre cac
+ *
+ * Saves the channel that was in use before pre cac operation
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_sap_set_chan_before_pre_cac(struct sap_context *sap_ctx,
+					    uint8_t chan_before_pre_cac);
+
+/**
+ * wlan_sap_set_pre_cac_complete_status() - Sets pre cac complete status
+ * @sap_ctx: SAP context
+ * @status: Status of pre cac complete
+ *
+ * Sets the status of pre cac i.e., whether pre cac is complete or not
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_sap_set_pre_cac_complete_status(struct sap_context *sap_ctx,
+						bool status);
+
+bool wlan_sap_is_pre_cac_active(tHalHandle handle);
+QDF_STATUS wlan_sap_get_pre_cac_vdev_id(tHalHandle handle, uint8_t *vdev_id);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * wlansap_check_cc_intf() - Get interfering concurrent channel
+ * @sap_ctx: SAP context pointer
+ *
+ * Determine if a Concurrent Channel is interfering.
+ *
+ * Return: Channel number of the interfering channel, or 0 if none.
+ */
+uint16_t wlansap_check_cc_intf(struct sap_context *sap_ctx);
+#endif
+
+/**
+ * wlansap_set_mac_acl() - set MAC list entry in ACL.
+ * @sap_ctx: Pointer to the SAP context
+ * @pConfig: Pointer to SAP config.
+ *
+ * This api function provides SAP to set mac list entry in accept list as well
+ * as deny list
+ *
+ * Return: The result code associated with performing the operation
+ *         QDF_STATUS_E_FAULT: Pointer to SAP cb is NULL;
+ *                             access would cause a page fault
+ *         QDF_STATUS_SUCCESS: Success
+ */
+QDF_STATUS wlansap_set_mac_acl(struct sap_context *sap_ctx,
+			       tsap_config_t *pConfig);
+
+/**
+ * wlansap_disassoc_sta() - initiate disassociation of station.
+ * @sap_ctx: Pointer to the SAP context
+ * @p_del_sta_params: pointer to station deletion parameters
+ *
+ * This api function provides for Ap App/HDD initiated disassociation of station
+ *
+ * Return: The QDF_STATUS code associated with performing the operation
+ *         QDF_STATUS_SUCCESS:  Success
+ */
+QDF_STATUS wlansap_disassoc_sta(struct sap_context *sap_ctx,
+				struct csr_del_sta_params *p_del_sta_params);
+
+/**
+ * wlansap_deauth_sta() - Ap App/HDD initiated deauthentication of station
+ * @pStaCtx : Pointer to the SAP context
+ * @pDelStaParams : Pointer to parameters of the station to deauthenticate
+ *
+ * This api function provides for Ap App/HDD initiated deauthentication of
+ * station
+ *
+ * Return: The QDF_STATUS code associated with performing the operation
+ */
+QDF_STATUS wlansap_deauth_sta(struct sap_context *sap_ctx,
+			      struct csr_del_sta_params *pDelStaParams);
+
+/**
+ * wlansap_set_channel_change_with_csa() - Set channel change with CSA
+ * @sapContext: Pointer to SAP context
+ * @targetChannel: Target channel
+ * @target_bw: Target bandwidth
+ * @strict: if true switch to the requested channel always, fail
+ *        otherwise
+ *
+ * This api function does a channel change to the target channel specified.
+ * CSA IE is included in the beacons before doing a channel change.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sapContext,
+					       uint32_t targetChannel,
+					       enum phy_ch_width target_bw,
+					       bool strict);
+
+/**
+ * wlansap_set_key_sta() - set keys for a stations.
+ * @sap_ctx: Pointer to the SAP context
+ * @key_info : tCsrRoamSetKey structure for the station
+ *
+ * This api function provides for Ap App/HDD to set key for a station.
+ *
+ * Return: The QDF_STATUS code associated with performing the operation
+ *         QDF_STATUS_SUCCESS:  Success
+ */
+QDF_STATUS wlansap_set_key_sta(struct sap_context *sap_ctx,
+			       tCsrRoamSetKey *key_info);
+
+/**
+ * wlan_sap_getstation_ie_information() - RSNIE Population
+ * @sap_ctx: Pointer to the SAP context
+ * @len: Length of @buf
+ * @buf: RSNIE IE data
+ *
+ *  Populate RSN IE from CSR to HDD context
+ *
+ * Return: QDF_STATUS enumeration
+ */
+
+QDF_STATUS wlan_sap_getstation_ie_information(struct sap_context *sap_ctx,
+					      uint32_t *len, uint8_t *buf);
+
+/**
+ * wlansap_clear_acl() - Clear all ACLs
+ * @sap_ctx: Pointer to the SAP context
+ *
+ * Return: QDF_STATUS. If success the ACLs were cleared, otherwise an
+ *    error occurred.
+ */
+QDF_STATUS wlansap_clear_acl(struct sap_context *sap_ctx);
+
+/**
+ * wlansap_get_acl_accept_list() - Get ACL accept list
+ * @sap_ctx: Pointer to the SAP context
+ * @pAcceptList: Pointer to the buffer to store the ACL accept list
+ * @nAcceptList: Pointer to the location to store the number of
+ *    entries in the ACL accept list.
+ *
+ * Return: QDF_STATUS. If success the data was returned, otherwise an
+ *    error occurred.
+ */
+QDF_STATUS wlansap_get_acl_accept_list(struct sap_context *sap_ctx,
+				       struct qdf_mac_addr *pAcceptList,
+				       uint8_t *nAcceptList);
+
+/**
+ * wlansap_get_acl_deny_list() - Get ACL deny list
+ * @sap_ctx: Pointer to the SAP context
+ * @pDenyList: Pointer to the buffer to store the ACL deny list
+ * @nDenyList: Pointer to the location to store the number of
+ *    entries in the ACL deny list.
+ *
+ * Return: QDF_STATUS. If success the data was returned, otherwise an
+ *    error occurred.
+ */
+QDF_STATUS wlansap_get_acl_deny_list(struct sap_context *sap_ctx,
+				     struct qdf_mac_addr *pDenyList,
+				     uint8_t *nDenyList);
+
+/**
+ * wlansap_set_acl_mode() - Set the SAP ACL mode
+ * @sap_ctx: The SAP context pointer
+ * @mode: the desired ACL mode
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlansap_set_acl_mode(struct sap_context *sap_ctx,
+				eSapMacAddrACL mode);
+
+/**
+ * wlansap_get_acl_mode() - Get the SAP ACL mode
+ * @sap_ctx: The SAP context pointer
+ * @mode: Pointer where to return the current ACL mode
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlansap_get_acl_mode(struct sap_context *sap_ctx,
+				eSapMacAddrACL *mode);
+
+/**
+ * wlansap_modify_acl() - Update ACL entries
+ * @sap_ctx: Pointer to the SAP context
+ * @peer_sta_mac: peer sta mac to be updated.
+ * @list_type: white/Black list type.
+ * @cmd: command to be executed on ACL.
+ *
+ * This function is called when a peer needs to be added or deleted from the
+ * white/black ACL
+ *
+ * Return: Status
+ */
+QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx,
+			      uint8_t *peer_sta_mac,
+			      eSapACLType list_type, eSapACLCmdType cmd);
+
+/**
+ * wlansap_register_mgmt_frame() - register management frame
+ * @sap_ctx: Pointer to SAP context
+ * @frame_type: frame type that needs to be registered with PE.
+ * @match_data: pointer to data which should be matched after @frame_type
+ *              is matched.
+ * @match_len: Length of the @match_data
+ *
+ * HDD use this API to register specified type of frame with CORE stack.
+ * On receiving such kind of frame CORE stack should pass this frame to HDD
+ *
+ * Return: The QDF_STATUS code associated with performing the operation
+ *         QDF_STATUS_SUCCESS:  Success and error code otherwise
+ */
+QDF_STATUS wlansap_register_mgmt_frame(struct sap_context *sap_ctx,
+				       uint16_t frame_type,
+				       uint8_t *match_data,
+				       uint16_t match_len);
+
+/**
+ * wlansap_de_register_mgmt_frame() - de register management frame
+ * @sap_ctx: Pointer to SAP context
+ * @frame_type: frame type that needs to be de-registered with PE.
+ * @match_data: pointer to data which should be matched after @frame_type
+ *              is matched.
+ * @match_len: Length of the @match_data
+ *
+ * HDD use this API to deregister a previously registered frame
+ *
+ * Return: The QDF_STATUS code associated with performing the operation
+ *         QDF_STATUS_SUCCESS:  Success and error code otherwise
+ */
+QDF_STATUS wlansap_de_register_mgmt_frame(struct sap_context *sap_ctx,
+					  uint16_t frame_type,
+					  uint8_t *match_data,
+					  uint16_t match_len);
+
+/**
+ * wlansap_channel_change_request() - Send channel change request
+ * @sapContext: Pointer to the SAP context
+ * @target_channel: Target channel
+ *
+ * This API is used to send an Indication to SME/PE to change the
+ * current operating channel to a different target channel.
+ *
+ * The Channel change will be issued by SAP under the following
+ * scenarios.
+ * 1. A radar indication is received  during SAP CAC WAIT STATE and
+ *    channel change is required.
+ * 2. A radar indication is received during SAP STARTED STATE and
+ *    channel change is required.
+ *
+ * Return: The QDF_STATUS code associated with performing the operation
+ *   QDF_STATUS_SUCCESS:  Success
+ *
+ */
+QDF_STATUS wlansap_channel_change_request(struct sap_context *sapContext,
+					  uint8_t target_channel);
+
+/**
+ * wlansap_start_beacon_req() - Send Start Beaconing Request
+ * @sap_ctx: Pointer to the SAP context
+ *
+ * This API is used to send an Indication to SME/PE to start
+ * beaconing on the current operating channel.
+ *
+ * When SAP is started on DFS channel and when ADD BSS RESP is received
+ * LIM temporarily holds off Beaconing for SAP to do CAC WAIT. When
+ * CAC WAIT is done SAP resumes the Beacon Tx by sending a start beacon
+ * request to LIM.
+ *
+ * Return: The QDF_STATUS code associated with performing the operation
+ *   QDF_STATUS_SUCCESS:  Success
+ */
+QDF_STATUS wlansap_start_beacon_req(struct sap_context *sap_ctx);
+
+/**
+ * wlansap_dfs_send_csa_ie_request() - Send CSA IE
+ * @sap_ctx: Pointer to the SAP context
+ *
+ * This API is used to send channel switch announcement request to PE
+ *
+ * Return: The QDF_STATUS code associated with performing the operation
+ *    QDF_STATUS_SUCCESS:  Success
+ */
+QDF_STATUS wlansap_dfs_send_csa_ie_request(struct sap_context *sap_ctx);
+
+QDF_STATUS wlansap_get_dfs_ignore_cac(tHalHandle hHal, uint8_t *pIgnore_cac);
+QDF_STATUS wlansap_set_dfs_ignore_cac(tHalHandle hHal, uint8_t ignore_cac);
+QDF_STATUS wlansap_set_dfs_restrict_japan_w53(tHalHandle hHal,
+			uint8_t disable_Dfs_JapanW3);
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+QDF_STATUS
+wlan_sap_set_channel_avoidance(tHalHandle hal, bool sap_channel_avoidance);
+#endif
+
+QDF_STATUS wlansap_set_dfs_preferred_channel_location(tHalHandle hHal,
+		uint8_t dfs_Preferred_Channels_location);
+QDF_STATUS wlansap_set_dfs_target_chnl(tHalHandle hHal,
+			uint8_t target_channel);
+
+/**
+ * wlan_sap_get_roam_profile() - Returns sap roam profile.
+ * @sap_ctx:	Pointer to Sap Context.
+ *
+ * This function provides the SAP roam profile.
+ *
+ * Return: SAP RoamProfile
+ */
+struct csr_roam_profile *wlan_sap_get_roam_profile(struct sap_context *sap_ctx);
+
+/**
+ * wlan_sap_get_phymode() - Returns sap phymode.
+ * @sap_ctx:	Pointer to Sap Context.
+ *
+ * This function provides the SAP current phymode.
+ *
+ * Return: phymode
+ */
+eCsrPhyMode wlan_sap_get_phymode(struct sap_context *sap_ctx);
+
+/**
+ * wlan_sap_get_vht_ch_width() - Returns SAP VHT channel width.
+ * @sap_ctx:	Pointer to Sap Context
+ *
+ * This function provides the SAP current VHT channel with.
+ *
+ * Return: VHT channel width
+ */
+uint32_t wlan_sap_get_vht_ch_width(struct sap_context *sap_ctx);
+
+/**
+ * wlan_sap_set_vht_ch_width() - Sets SAP VHT channel width.
+ * @sap_ctx:		Pointer to Sap Context
+ * @vht_channel_width:	SAP VHT channel width value.
+ *
+ * This function sets the SAP current VHT channel width.
+ *
+ * Return: None
+ */
+void wlan_sap_set_vht_ch_width(struct sap_context *sap_ctx,
+			       uint32_t vht_channel_width);
+
+/**
+ * wlan_sap_set_sap_ctx_acs_cfg() - Sets acs cfg
+ * @sap_ctx:  Pointer to Sap Context
+ * @sap_config:  Pointer to sap config
+ *
+ * This function sets the acs cfg in sap context.
+ *
+ * Return: None
+ */
+void wlan_sap_set_sap_ctx_acs_cfg(struct sap_context *sap_ctx,
+				  tsap_config_t *sap_config);
+
+void sap_config_acs_result(tHalHandle hal, struct sap_context *sap_ctx,
+			   uint32_t sec_ch);
+
+QDF_STATUS wlansap_update_sap_config_add_ie(tsap_config_t *pConfig,
+		const uint8_t *
+		pAdditionIEBuffer,
+		uint16_t additionIELength,
+		eUpdateIEsType updateType);
+QDF_STATUS wlansap_reset_sap_config_add_ie(tsap_config_t *pConfig,
+			eUpdateIEsType updateType);
+void wlansap_extend_to_acs_range(tHalHandle hal, uint8_t *startChannelNum,
+		uint8_t *endChannelNum, uint8_t *bandStartChannel,
+		uint8_t *bandEndChannel);
+
+/**
+ * wlansap_set_dfs_nol() - Set dfs nol
+ * @sap_ctx: SAP context
+ * @conf: set type
+ *
+ * Return: QDF_STATUS
+ */
+#ifdef DFS_COMPONENT_ENABLE
+QDF_STATUS wlansap_set_dfs_nol(struct sap_context *sap_ctx,
+			       eSapDfsNolType conf);
+#else
+static inline QDF_STATUS wlansap_set_dfs_nol(struct sap_context *sap_ctx,
+			       eSapDfsNolType conf)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * wlan_sap_set_vendor_acs() - Set vendor specific acs in sap context
+ * @sap_context: SAP context
+ * @is_vendor_acs: if vendor specific acs is enabled
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_sap_set_vendor_acs(struct sap_context *sap_context,
+				   bool is_vendor_acs);
+
+void wlansap_populate_del_sta_params(const uint8_t *mac,
+		uint16_t reason_code,
+		uint8_t subtype,
+		struct csr_del_sta_params *pDelStaParams);
+
+/**
+ * wlansap_acs_chselect() - Initiates acs channel selection
+ * @sap_context:               Pointer to SAP context structure
+ * @pacs_event_callback:       Callback function in hdd called by sap
+ *                             to inform hdd about channel selection result
+ * @pconfig:                   Pointer to configuration structure
+ *                             passed down from hdd
+ * @pusr_context:              Parameter that will be passed back in all
+ *                             the sap callback events.
+ *
+ * This function serves as an api for hdd to initiate acs scan pre
+ * start bss.
+ *
+ * Return: The QDF_STATUS code associated with performing the operation.
+ */
+QDF_STATUS wlansap_acs_chselect(struct sap_context *sap_context,
+				tpWLAN_SAPEventCB pacs_event_callback,
+				tsap_config_t *pconfig,
+				void *pusr_context);
+
+/**
+ * wlansap_get_chan_width() - get sap channel width.
+ * @sap_ctx: pointer to the SAP context
+ *
+ * This function get channel width of sap.
+ *
+ * Return: sap channel width
+ */
+uint32_t wlansap_get_chan_width(struct sap_context *sap_ctx);
+
+/**
+ * wlansap_set_tx_leakage_threshold() - set sap tx leakage threshold.
+ * @hal: HAL pointer
+ * @tx_leakage_threshold: sap tx leakage threshold
+ *
+ * This function set sap tx leakage threshold.
+ *
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS wlansap_set_tx_leakage_threshold(tHalHandle hal,
+			uint16_t tx_leakage_threshold);
+
+/*
+ * wlansap_set_invalid_session() - set session ID to invalid
+ * @sap_ctx: pointer to the SAP context
+ *
+ * This function sets session ID to invalid
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlansap_set_invalid_session(struct sap_context *sap_ctx);
+
+/**
+ * sap_get_cac_dur_dfs_region() - get cac duration and dfs region.
+ * @sap_ctxt: sap context
+ * @cac_duration_ms: pointer to cac duration
+ * @dfs_region: pointer to dfs region
+ *
+ * Get cac duration and dfs region.
+ *
+ * Return: None
+ */
+void sap_get_cac_dur_dfs_region(struct sap_context *sap_ctx,
+				uint32_t *cac_duration_ms,
+				uint32_t *dfs_region);
+
+
+/**
+ * sap_dfs_set_current_channel() - Set current channel params in dfs component
+ * @sap_ctx: sap context
+ *
+ * Set current channel params in dfs component, this info will be used to mark
+ * the channels in nol when radar is detected.
+ *
+ * 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(struct sap_context *sap_ctx);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* #ifndef WLAN_QCT_WLANSAP_H */
diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c
new file mode 100644
index 0000000..1e9e1bf
--- /dev/null
+++ b/core/sap/src/sap_api_link_cntl.c
@@ -0,0 +1,1262 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*===========================================================================
+
+			s a p A p i L i n k C n t l . C
+
+   OVERVIEW:
+
+   This software unit holds the implementation of the WLAN SAP modules
+   Link Control functions.
+
+   The functions externalized by this module are to be called ONLY by other
+   WLAN modules (HDD)
+
+   DEPENDENCIES:
+
+   Are listed for each API below.
+   ===========================================================================*/
+
+/*----------------------------------------------------------------------------
+ * Include Files
+ * -------------------------------------------------------------------------*/
+#include "qdf_trace.h"
+/* Pick up the CSR callback definition */
+#include "csr_api.h"
+#include "ani_global.h"
+#include "csr_inside_api.h"
+#include "sme_api.h"
+/* SAP Internal API header file */
+#include "sap_internal.h"
+#include "wlan_policy_mgr_api.h"
+#include "wma.h"
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include "wlan_reg_services_api.h"
+#include <wlan_scan_utils_api.h>
+
+/*----------------------------------------------------------------------------
+ * Preprocessor Definitions and Constants
+ * -------------------------------------------------------------------------*/
+#define SAP_DEBUG
+
+/*----------------------------------------------------------------------------
+ * Type Declarations
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Global Data Definitions
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Static Variable Definitions
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Static Function Declarations and Definitions
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Externalized Function Definitions
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Function Declarations and Documentation
+ * -------------------------------------------------------------------------*/
+
+/**
+ * sap_config_acs_result : Generate ACS result params based on ch constraints
+ * @sap_ctx: pointer to SAP context data struct
+ * @hal: HAL Handle pointer
+ *
+ * This function calculates the ACS result params: ht sec channel, vht channel
+ * information and channel bonding based on selected ACS channel.
+ *
+ * Return: None
+ */
+
+void sap_config_acs_result(tHalHandle hal, struct sap_context *sap_ctx,
+							uint32_t sec_ch)
+{
+	uint32_t channel = sap_ctx->acs_cfg->pri_ch;
+	struct ch_params ch_params = {0};
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	ch_params.ch_width = sap_ctx->acs_cfg->ch_width;
+	wlan_reg_set_channel_params(mac_ctx->pdev, channel, sec_ch,
+			&ch_params);
+	sap_ctx->acs_cfg->ch_width = ch_params.ch_width;
+	if (sap_ctx->acs_cfg->ch_width > CH_WIDTH_40MHZ)
+		sap_ctx->acs_cfg->vht_seg0_center_ch =
+						ch_params.center_freq_seg0;
+	else
+		sap_ctx->acs_cfg->vht_seg0_center_ch = 0;
+
+	if (sap_ctx->acs_cfg->ch_width == CH_WIDTH_80P80MHZ)
+		sap_ctx->acs_cfg->vht_seg1_center_ch =
+						ch_params.center_freq_seg1;
+	else
+		sap_ctx->acs_cfg->vht_seg1_center_ch = 0;
+
+	if (ch_params.sec_ch_offset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+		sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
+	else if (ch_params.sec_ch_offset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+		sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
+	else
+		sap_ctx->acs_cfg->ht_sec_ch = 0;
+}
+
+/**
+ * sap_hdd_signal_event_handler() - routine to inform hostapd via callback
+ *
+ * ctx: pointer to sap context which was passed to callback
+ *
+ * this routine will be registered as callback to sme_close_session, so upon
+ * closure of sap session it notifies the hostapd
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sap_hdd_signal_event_handler(void *ctx)
+{
+	struct sap_context *sap_ctx = ctx;
+	QDF_STATUS status;
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				FL("sap context is not valid"));
+		return QDF_STATUS_E_FAILURE;
+	}
+	status = sap_signal_hdd_event(sap_ctx, NULL,
+			sap_ctx->sap_state,
+			(void *) sap_ctx->sap_status);
+	return status;
+}
+
+/**
+ * acs_scan_done_status_str() - parse scan status to string
+ * @status: scan status
+ *
+ * This function parse scan status to string
+ *
+ * Return: status string
+ *
+ */
+static const char *acs_scan_done_status_str(eCsrScanStatus status)
+{
+	switch (status) {
+	case eCSR_SCAN_SUCCESS:
+		return "Success";
+	case eCSR_SCAN_FAILURE:
+		return "Failure";
+	case eCSR_SCAN_ABORT:
+		return "Abort";
+	case eCSR_SCAN_FOUND_PEER:
+		return "Found peer";
+	default:
+		return "Unknown";
+	}
+}
+
+QDF_STATUS wlansap_pre_start_bss_acs_scan_callback(tHalHandle hal_handle,
+						   struct sap_context *sap_ctx,
+						   uint8_t sessionid,
+						   uint32_t scanid,
+						   eCsrScanStatus scan_status)
+{
+	tScanResultHandle presult = NULL;
+	QDF_STATUS scan_get_result_status = QDF_STATUS_E_FAILURE;
+	uint8_t oper_channel = 0;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	host_log_acs_scan_done(acs_scan_done_status_str(scan_status),
+			  sessionid, scanid);
+	if (eCSR_SCAN_SUCCESS != scan_status) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("CSR scan_status = eCSR_SCAN_ABORT/FAILURE (%d), choose default channel"),
+			scan_status);
+		oper_channel =
+			sap_select_default_oper_chan(sap_ctx->acs_cfg);
+		sap_ctx->channel = oper_channel;
+		sap_ctx->acs_cfg->pri_ch = oper_channel;
+		sap_config_acs_result(hal_handle, sap_ctx,
+				      sap_ctx->acs_cfg->ht_sec_ch);
+		sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED;
+		sap_ctx->sap_status = eSAP_STATUS_SUCCESS;
+		goto close_session;
+	}
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		FL("CSR scan_status = eCSR_SCAN_SUCCESS (%d)"), scan_status);
+	/*
+	* Now do
+	* 1. Get scan results
+	* 2. Run channel selection algorithm
+	* select channel and store in sap_context->Channel
+	*/
+	scan_get_result_status = sme_scan_get_result(hal_handle,
+					sap_ctx->sessionId,
+					NULL, &presult);
+	if ((scan_get_result_status != QDF_STATUS_SUCCESS) &&
+		(scan_get_result_status != QDF_STATUS_E_NULL_VALUE)) {
+		/*
+		* No scan results So, set the operation channel not selected
+		* to allow the default channel to be set when reporting to HDD
+		*/
+		oper_channel = SAP_CHANNEL_NOT_SELECTED;
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("Get scan result failed! ret = %d"),
+		scan_get_result_status);
+	} else {
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+		if (scanid != 0) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				  FL("Sending ACS Scan skip event"));
+			sap_signal_hdd_event(sap_ctx, NULL,
+					     eSAP_ACS_SCAN_SUCCESS_EVENT,
+					     (void *) eSAP_STATUS_SUCCESS);
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				  FL("ACS scanid: %d (skipped ACS SCAN)"),
+				  scanid);
+		}
+#endif
+		oper_channel = sap_select_channel(hal_handle, sap_ctx, presult);
+		sme_scan_result_purge(presult);
+	}
+
+	if (oper_channel == SAP_CHANNEL_NOT_SELECTED) {
+#ifdef SOFTAP_CHANNEL_RANGE
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			  FL("No suitable channel selected"));
+
+		sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED;
+		sap_ctx->sap_status = eSAP_STATUS_FAILURE;
+		goto close_session;
+	} else {
+#else
+		sap_ctx->channel =
+			sap_select_default_oper_chan(sap_ctx->acs_cfg);
+	} else {
+#endif
+		/* Valid Channel Found from scan results. */
+		sap_ctx->acs_cfg->pri_ch = oper_channel;
+		sap_ctx->channel = oper_channel;
+	}
+	sap_config_acs_result(hal_handle, sap_ctx,
+			sap_ctx->acs_cfg->ht_sec_ch);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("Channel selected = %d"), sap_ctx->channel);
+	sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED;
+	sap_ctx->sap_status = eSAP_STATUS_SUCCESS;
+close_session:
+#ifdef SOFTAP_CHANNEL_RANGE
+	if (sap_ctx->channelList != NULL) {
+		/*
+		* Always free up the memory for
+		* channel selection whatever
+		* the result
+		*/
+		qdf_mem_free(sap_ctx->channelList);
+		sap_ctx->channelList = NULL;
+		sap_ctx->num_of_channel = 0;
+	}
+#endif
+	sap_hdd_signal_event_handler(sap_ctx);
+	return status;
+}
+
+/**
+ * wlansap_roam_process_ch_change_success() - handles the case for
+ * eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS in function wlansap_roam_callback()
+ *
+ * @mac_ctx:        mac global context
+ * @sap_ctx:        sap context
+ * @csr_roam_info:  raom info struct
+ * @ret_status:     update return status
+ *
+ * Return: void
+ */
+static void
+wlansap_roam_process_ch_change_success(tpAniSirGlobal mac_ctx,
+				      struct sap_context *sap_ctx,
+				      struct csr_roam_info *csr_roam_info,
+				      QDF_STATUS *ret_status)
+{
+	tWLAN_SAPEvent sap_event;
+	QDF_STATUS qdf_status;
+	bool is_ch_dfs = false;
+	/*
+	 * Channel change is successful. If the new channel is a DFS channel,
+	 * then we will to perform channel availability check for 60 seconds
+	 */
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+		  FL("sapdfs: changing target channel to [%d] state %d"),
+		  mac_ctx->sap.SapDfsInfo.target_channel, sap_ctx->fsm_state);
+	sap_ctx->channel = mac_ctx->sap.SapDfsInfo.target_channel;
+
+	/* If SAP is not in starting or started state don't proceed further */
+	if (sap_ctx->fsm_state == SAP_INIT ||
+	    sap_ctx->fsm_state == SAP_STOPPING) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			  FL("sapdfs: state [%d] not starting SAP after channel change"),
+			  sap_ctx->fsm_state);
+		return;
+	}
+
+	if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) {
+		is_ch_dfs = true;
+	} else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) {
+		if (wlan_reg_get_channel_state(mac_ctx->pdev,
+					sap_ctx->channel) ==
+						CHANNEL_STATE_DFS ||
+		    wlan_reg_get_channel_state(mac_ctx->pdev,
+			    sap_ctx->ch_params.center_freq_seg1 -
+					  SIR_80MHZ_START_CENTER_CH_DIFF) ==
+							CHANNEL_STATE_DFS)
+			is_ch_dfs = true;
+	} else {
+		if (wlan_reg_get_channel_state(mac_ctx->pdev,
+					sap_ctx->channel) ==
+						CHANNEL_STATE_DFS)
+			is_ch_dfs = true;
+	}
+
+	/* check if currently selected channel is a DFS channel */
+	if (is_ch_dfs && sap_ctx->pre_cac_complete) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, FL(
+		    "sapdfs: => SAP_STARTING, on pre cac"));
+		/* Start beaconing on the new pre cac channel */
+		wlansap_start_beacon_req(sap_ctx);
+		sap_ctx->fsm_state = SAP_STARTING;
+		mac_ctx->sap.SapDfsInfo.sap_radar_found_status = false;
+		sap_event.event = eSAP_MAC_START_BSS_SUCCESS;
+		sap_event.params = csr_roam_info;
+		sap_event.u1 = eCSR_ROAM_INFRA_IND;
+		sap_event.u2 = eCSR_ROAM_RESULT_INFRA_STARTED;
+	} else if (is_ch_dfs) {
+		if ((false == mac_ctx->sap.SapDfsInfo.ignore_cac)
+		    && (eSAP_DFS_DO_NOT_SKIP_CAC ==
+			mac_ctx->sap.SapDfsInfo.cac_state)) {
+			sap_ctx->fsm_state = SAP_INIT;
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+				  "%s: %d: sapdfs: => SAP_INIT with ignore cac false on sapctx[%pK]",
+				  __func__, __LINE__, sap_ctx);
+			/* DFS Channel */
+			sap_event.event = eSAP_DFS_CHANNEL_CAC_START;
+			sap_event.params = csr_roam_info;
+			sap_event.u1 = 0;
+			sap_event.u2 = 0;
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_INFO_MED,
+				  "%s: %d: sapdfs: SAP_STARTING with ignore cac true on sapctx[%pK]",
+				  __func__, __LINE__, sap_ctx);
+
+			/* Start beaconing on the new channel */
+			wlansap_start_beacon_req(sap_ctx);
+			sap_ctx->fsm_state = SAP_STARTING;
+			mac_ctx->sap.SapDfsInfo.sap_radar_found_status = false;
+			sap_event.event = eSAP_MAC_START_BSS_SUCCESS;
+			sap_event.params = csr_roam_info;
+			sap_event.u1 = eCSR_ROAM_INFRA_IND;
+			sap_event.u2 = eCSR_ROAM_RESULT_INFRA_STARTED;
+		}
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+			  "%s: %d: sapdfs: => SAP_STARTING on sapctx[%pK]",
+			  __func__, __LINE__, sap_ctx);
+		/* non-DFS channel */
+		sap_ctx->fsm_state = SAP_STARTING;
+		mac_ctx->sap.SapDfsInfo.sap_radar_found_status = false;
+		sap_event.event = eSAP_MAC_START_BSS_SUCCESS;
+		sap_event.params = csr_roam_info;
+		sap_event.u1 = eCSR_ROAM_INFRA_IND;
+		sap_event.u2 = eCSR_ROAM_RESULT_INFRA_STARTED;
+	}
+
+	/* Handle the event */
+	qdf_status = sap_fsm(sap_ctx, &sap_event);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		*ret_status = QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * wlansap_roam_process_dfs_chansw_update() - handles the case for
+ * eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS in wlansap_roam_callback()
+ *
+ * @hal:           hal global context
+ * @sap_ctx:       sap context
+ * @ret_status:    update return status
+ *
+ * Return: void
+ */
+static void
+wlansap_roam_process_dfs_chansw_update(tHalHandle hHal,
+					    struct sap_context *sap_ctx,
+					    QDF_STATUS *ret_status)
+{
+	uint8_t intf;
+	QDF_STATUS qdf_status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hHal);
+	uint8_t dfs_beacon_start_req = 0;
+	bool sap_scc_dfs;
+
+	if (sap_ctx->csr_roamProfile.disableDFSChSwitch) {
+		QDF_TRACE(QDF_MODULE_ID_SAP,
+			  QDF_TRACE_LEVEL_ERROR,
+			  FL("sapdfs: DFS channel switch disabled"));
+		/*
+		 * Send a beacon start request to PE. CSA IE required flag from
+		 * beacon template will be cleared by now. A new beacon template
+		 * with no CSA IE will be sent to firmware.
+		 */
+		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);
+		return;
+	}
+	/*
+	 * Irrespective of whether the channel switch IE was sent out
+	 * successfully or not, SAP should still vacate the channel immediately
+	 */
+	if (sap_ctx->fsm_state != SAP_STARTED) {
+		/* Further actions to be taken here */
+		QDF_TRACE(QDF_MODULE_ID_SAP,
+			  QDF_TRACE_LEVEL_WARN,
+			  FL("eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND received in (%d) state"),
+			  sap_ctx->fsm_state);
+		return;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+		  FL("sapdfs: from state SAP_STARTED => SAP_STOPPING"));
+	sap_ctx->is_chan_change_inprogress = true;
+	/*
+	 * The associated stations have been informed to move to a different
+	 * channel. However, the AP may not always select the advertised channel
+	 * for operation if the radar is seen. In that case, the stations will
+	 * experience link-loss and return back through scanning if they wish to
+	 */
+
+	/*
+	 * Send channel change request. From spec it is required that the AP
+	 * should continue to operate in the same mode as it is operating
+	 * currently. For e.g. 20/40/80 MHz operation
+	 */
+	if (mac_ctx->sap.SapDfsInfo.target_channel)
+		wlan_reg_set_channel_params(mac_ctx->pdev,
+				mac_ctx->sap.SapDfsInfo.target_channel,
+				0, &sap_ctx->ch_params);
+
+	/*
+	 * Fetch the number of SAP interfaces. If the number of sap Interface
+	 * more than one then we will make is_sap_ready_for_chnl_chng to true
+	 * for that sapctx. If there is only one SAP interface then process
+	 * immediately. If Dual BAND SAP is enabled then also process
+	 * immediately, as in this case the both SAP will be in different band
+	 * and channel change on one SAP doesn't mean channel change on
+	 * other interface.
+	 *
+	 * For example,
+	 * Let's say SAP(2G) + SAP(5G-DFS) is initial connection which triggered
+	 * DualBand HW mode and if SAP(5G-DFS) is moving to some channel then
+	 * SAP(2G) doesn't need to move.
+	 *
+	 * If both SAPs are not doing SCC DFS then each of them can change the
+	 * channel independently. Channel change of one SAP became dependent
+	 * second SAP's channel change due to some previous platform's single
+	 * radio limitation.
+	 *
+	 */
+	sap_scc_dfs = sap_is_conc_sap_doing_scc_dfs(hHal, sap_ctx);
+	if (sap_get_total_number_sap_intf(hHal) <= 1 ||
+	    policy_mgr_is_current_hwmode_dbs(mac_ctx->psoc) ||
+	    !sap_scc_dfs) {
+		sap_get_cac_dur_dfs_region(sap_ctx,
+			&sap_ctx->csr_roamProfile.cac_duration_ms,
+			&sap_ctx->csr_roamProfile.dfs_regdomain);
+		/*
+		 * Most likely, radar has been detected and SAP wants to
+		 * change the channel
+		 */
+		qdf_status = wlansap_channel_change_request(sap_ctx,
+			mac_ctx->sap.SapDfsInfo.target_channel);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			*ret_status = QDF_STATUS_E_FAILURE;
+		return;
+	}
+
+	sap_ctx->is_sap_ready_for_chnl_chng = true;
+	/*
+	 * now check if the con-current sap interface is ready
+	 * for channel change. If yes then we issue channel change for
+	 * both the SAPs. If no then simply return success & we will
+	 * issue channel change when second AP's 5 CSA beacon Tx is
+	 * completed.
+	 *
+	 * This check is added to take care of following scenario:
+	 * if SAP1 + SAP2 is doing DFS SCC and radar is detected on that channel
+	 * then SAP1 sends 5 beacons with CSA/ECSA IE and wait for SAP2 to
+	 * finish sending 5 beacons. if SAP1 changes channel before SAP2 finish
+	 * sending beacons then it ends up in
+	 * (SAP1 new channel + SAP2 old channel) MCC with DFS scenario
+	 * which causes some of the stability issues in old platforms.
+	 */
+	if (false ==
+	    is_concurrent_sap_ready_for_channel_change(hHal, sap_ctx)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+			  FL("sapdfs: sapctx[%pK] ready but not concurrent sap"),
+			  sap_ctx);
+		*ret_status = QDF_STATUS_SUCCESS;
+		return;
+	}
+
+	/* Issue channel change req for each sapctx */
+	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+		struct sap_context *sap_context;
+
+		if (!((QDF_SAP_MODE == mac_ctx->sap.sapCtxList[intf].sapPersona)
+		    && (mac_ctx->sap.sapCtxList[intf].sap_context != NULL)))
+			continue;
+		sap_context = mac_ctx->sap.sapCtxList[intf].sap_context;
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+			  FL("sapdfs:issue chnl change for sapctx[%pK]"),
+			  sap_context);
+		sap_get_cac_dur_dfs_region(sap_context,
+			&sap_context->csr_roamProfile.cac_duration_ms,
+			&sap_context->csr_roamProfile.dfs_regdomain);
+		/*
+		 * Most likely, radar has been detected and SAP wants to
+		 * change the channel
+		 */
+		qdf_status = wlansap_channel_change_request(sap_context,
+				mac_ctx->sap.SapDfsInfo.target_channel);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("post chnl chng req failed, sap[%pK]"),
+				  sap_ctx);
+			*ret_status = QDF_STATUS_E_FAILURE;
+		} else {
+			sap_context->is_sap_ready_for_chnl_chng = false;
+		}
+	}
+	return;
+}
+
+/**
+ * wlansap_roam_process_dfs_radar_found() - handles the case for
+ * eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND in wlansap_roam_callback()
+ *
+ * @mac_ctx:       mac global context
+ * @sap_ctx:       sap context
+ * @ret_status:    update return status
+ *
+ * Return: result of operation
+ */
+static void
+wlansap_roam_process_dfs_radar_found(tpAniSirGlobal mac_ctx,
+				     struct sap_context *sap_ctx,
+				     QDF_STATUS *ret_status)
+{
+	QDF_STATUS qdf_status;
+	tWLAN_SAPEvent sap_event;
+
+	if (sap_is_dfs_cac_wait_state(sap_ctx)) {
+		if (sap_ctx->csr_roamProfile.disableDFSChSwitch) {
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				QDF_TRACE_LEVEL_ERROR,
+				"sapdfs: DFS channel switch disabled");
+			return;
+		}
+		if (false == mac_ctx->sap.SapDfsInfo.sap_radar_found_status) {
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				QDF_TRACE_LEVEL_ERROR,
+				"sapdfs: sap_radar_found_status is false");
+			return;
+		}
+		QDF_TRACE(QDF_MODULE_ID_SAP,
+			  QDF_TRACE_LEVEL_INFO_MED,
+			  FL("sapdfs:Posting event eSAP_DFS_CHANNEL_CAC_RADAR_FOUND"));
+		/*
+		 * If Radar is found, while in DFS CAC WAIT State then post stop
+		 * and destroy the CAC timer and post a
+		 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND  to sapFsm.
+		 */
+		if (!sap_ctx->dfs_cac_offload) {
+			qdf_mc_timer_stop(&mac_ctx->
+					sap.SapDfsInfo.sap_dfs_cac_timer);
+			qdf_mc_timer_destroy(&mac_ctx->
+					sap.SapDfsInfo.sap_dfs_cac_timer);
+		}
+		mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
+
+		/*
+		 * User space is already indicated the CAC start and if
+		 * CAC end on this channel is not indicated, the user
+		 * space will be in some undefined state (e.g., UI frozen)
+		 */
+		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
+				eSAP_DFS_CAC_INTERRUPTED,
+				(void *) eSAP_STATUS_SUCCESS);
+		if (QDF_STATUS_SUCCESS != qdf_status) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				FL("Failed to send CAC end"));
+			/* Want to still proceed and try to switch channel.
+			 * Lets try not to be on the DFS channel
+			 */
+		}
+
+		sap_event.event = eSAP_DFS_CHANNEL_CAC_RADAR_FOUND;
+		sap_event.params = 0;
+		sap_event.u1 = 0;
+		sap_event.u2 = 0;
+		qdf_status = sap_fsm(sap_ctx, &sap_event);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			*ret_status = QDF_STATUS_E_FAILURE;
+		return;
+	}
+	if (sap_ctx->fsm_state == SAP_STARTED) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+			  FL("sapdfs:Posting event eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START"));
+
+		/*
+		 * Radar found on the operating channel in STARTED state,
+		 * new operating channel has already been selected. Send
+		 * request to SME-->PE for sending CSA IE
+		 */
+		sap_event.event = eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START;
+		sap_event.params = 0;
+		sap_event.u1 = 0;
+		sap_event.u2 = 0;
+		qdf_status = sap_fsm(sap_ctx, &sap_event);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			*ret_status = QDF_STATUS_E_FAILURE;
+		return;
+	}
+	/* Further actions to be taken here */
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+		  FL("eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND received in (%d) state"),
+		  sap_ctx->fsm_state);
+
+	return;
+}
+
+/**
+ * wlansap_roam_process_infra_assoc_ind() - handles the case for
+ * eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND in wlansap_roam_callback()
+ *
+ * @sap_ctx:       sap context
+ * @roam_result:   roam result
+ * @csr_roam_info: roam info struct
+ * @ret_status:    update return status
+ *
+ * Return: result of operation
+ */
+static void
+wlansap_roam_process_infra_assoc_ind(struct sap_context *sap_ctx,
+				     eCsrRoamResult roam_result,
+				     struct csr_roam_info *csr_roam_info,
+				     QDF_STATUS *ret_status)
+{
+	QDF_STATUS qdf_status;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("CSR roam_result = eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND (%d)"),
+		  roam_result);
+	sap_ctx->nStaWPARSnReqIeLength = csr_roam_info->rsnIELen;
+	if (sap_ctx->nStaWPARSnReqIeLength)
+		qdf_mem_copy(sap_ctx->pStaWpaRsnReqIE, csr_roam_info->prsnIE,
+			     sap_ctx->nStaWPARSnReqIeLength);
+	sap_ctx->SapQosCfg.WmmIsEnabled = csr_roam_info->wmmEnabledSta;
+	/* MAC filtering */
+	qdf_status = sap_is_peer_mac_allowed(sap_ctx,
+				     (uint8_t *) csr_roam_info->peerMac.bytes);
+
+	if (QDF_STATUS_SUCCESS == qdf_status) {
+		qdf_status = sap_signal_hdd_event(sap_ctx,
+				csr_roam_info, eSAP_STA_ASSOC_IND,
+				(void *) eSAP_STATUS_SUCCESS);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("CSR roam_result = (%d) MAC ("MAC_ADDRESS_STR") fail"),
+				  roam_result, MAC_ADDR_ARRAY(
+					csr_roam_info->peerMac.bytes));
+		*ret_status = QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
+			  FL("CSR roam_result = (%d) MAC ("MAC_ADDRESS_STR") not allowed"),
+			  roam_result,
+			  MAC_ADDR_ARRAY(csr_roam_info->peerMac.bytes));
+		*ret_status = QDF_STATUS_E_FAILURE;
+	}
+	return;
+}
+
+static void wlansap_update_vendor_acs_chan(tpAniSirGlobal mac_ctx,
+				struct sap_context *sap_ctx)
+{
+	int intf;
+
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return;
+	}
+
+	mac_ctx->sap.SapDfsInfo.target_channel =
+				sap_ctx->dfs_vendor_channel;
+
+	mac_ctx->sap.SapDfsInfo.new_chanWidth =
+				sap_ctx->dfs_vendor_chan_bw;
+	mac_ctx->sap.SapDfsInfo.new_ch_params.ch_width =
+				sap_ctx->dfs_vendor_chan_bw;
+
+	if (mac_ctx->sap.SapDfsInfo.target_channel != 0) {
+		mac_ctx->sap.SapDfsInfo.cac_state =
+			eSAP_DFS_DO_NOT_SKIP_CAC;
+		sap_cac_reset_notify(MAC_HANDLE(mac_ctx));
+		return;
+	}
+	/* App failed to provide new channel, try random channel algo */
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("failed to get channel from userspace"));
+
+	/* Issue stopbss for each sapctx */
+	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+		struct sap_context *sap_context;
+
+		if (((QDF_SAP_MODE ==
+		    mac_ctx->sap.sapCtxList[intf].sapPersona) ||
+		    (QDF_P2P_GO_MODE ==
+		    mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
+		    mac_ctx->sap.sapCtxList[intf].sap_context !=
+		    NULL) {
+			sap_context =
+			    mac_ctx->sap.sapCtxList[intf].sap_context;
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_ERROR,
+				  FL("sapdfs: no available channel for sapctx[%pK], StopBss"),
+				  sap_context);
+			wlansap_stop_bss(sap_context);
+		}
+	}
+}
+
+QDF_STATUS
+wlansap_roam_callback(void *ctx, struct csr_roam_info *csr_roam_info,
+		      uint32_t roamId,
+		      eRoamCmdStatus roam_status, eCsrRoamResult roam_result)
+{
+	/* sap_ctx value */
+	struct sap_context *sap_ctx = ctx;
+	/* State machine event */
+	tWLAN_SAPEvent sap_event;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
+	mac_handle_t mac_handle;
+	struct mac_context *mac_ctx;
+	uint8_t intf;
+	bool sta_sap_scc_on_dfs_chan;
+
+	if (QDF_IS_STATUS_ERROR(wlansap_context_get(sap_ctx)))
+		return QDF_STATUS_E_FAILURE;
+
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		wlansap_context_put(sap_ctx);
+		return QDF_STATUS_E_NOMEM;
+	}
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			FL("roam_status = %d, roam_result = %d"),
+			roam_status, roam_result);
+
+	sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac_ctx->psoc);
+
+	mac_handle = MAC_HANDLE(mac_ctx);
+
+	switch (roam_status) {
+	case eCSR_ROAM_INFRA_IND:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_status = eCSR_ROAM_INFRA_IND (%d)"),
+			  roam_status);
+		if (roam_result == eCSR_ROAM_RESULT_INFRA_START_FAILED) {
+			/* Fill in the event structure */
+			sap_event.event = eSAP_MAC_START_FAILS;
+			sap_event.params = csr_roam_info;
+			sap_event.u1 = roam_status;
+			sap_event.u2 = roam_result;
+			/* Handle event */
+			qdf_status = sap_fsm(sap_ctx, &sap_event);
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+				qdf_ret_status = QDF_STATUS_E_FAILURE;
+		}
+		break;
+	case eCSR_ROAM_LOSTLINK:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_status = eCSR_ROAM_LOSTLINK (%d)"),
+			  roam_status);
+		break;
+	case eCSR_ROAM_MIC_ERROR_IND:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_status = eCSR_ROAM_MIC_ERROR_IND (%d)"),
+			  roam_status);
+		break;
+	case eCSR_ROAM_SET_KEY_COMPLETE:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_status = eCSR_ROAM_SET_KEY_COMPLETE (%d)"),
+			  roam_status);
+		if (roam_result == eCSR_ROAM_RESULT_FAILURE)
+			sap_signal_hdd_event(sap_ctx, csr_roam_info,
+					     eSAP_STA_SET_KEY_EVENT,
+					     (void *) eSAP_STATUS_FAILURE);
+		break;
+	case eCSR_ROAM_ASSOCIATION_COMPLETION:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_status = eCSR_ROAM_ASSOCIATION_COMPLETION (%d)"),
+			  roam_status);
+		if (roam_result == eCSR_ROAM_RESULT_FAILURE)
+			sap_signal_hdd_event(sap_ctx, csr_roam_info,
+					     eSAP_STA_REASSOC_EVENT,
+					     (void *) eSAP_STATUS_FAILURE);
+		break;
+	case eCSR_ROAM_DISASSOCIATED:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_status = eCSR_ROAM_DISASSOCIATED (%d)"),
+			  roam_status);
+		if (roam_result == eCSR_ROAM_RESULT_MIC_FAILURE)
+			sap_signal_hdd_event(sap_ctx, csr_roam_info,
+					     eSAP_STA_MIC_FAILURE_EVENT,
+					     (void *) eSAP_STATUS_FAILURE);
+		break;
+	case eCSR_ROAM_WPS_PBC_PROBE_REQ_IND:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_status = eCSR_ROAM_WPS_PBC_PROBE_REQ_IND (%d)"),
+			  roam_status);
+		break;
+	case eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS:
+		sap_signal_hdd_event(sap_ctx, csr_roam_info,
+				     eSAP_DISCONNECT_ALL_P2P_CLIENT,
+				     (void *) eSAP_STATUS_SUCCESS);
+		break;
+	case eCSR_ROAM_SEND_P2P_STOP_BSS:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("Received stopbss"));
+		sap_signal_hdd_event(sap_ctx, csr_roam_info,
+				     eSAP_MAC_TRIG_STOP_BSS_EVENT,
+				     (void *) eSAP_STATUS_SUCCESS);
+		break;
+	case eCSR_ROAM_CHANNEL_COMPLETE_IND:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("Received new channel from app"));
+		wlansap_update_vendor_acs_chan(mac_ctx, sap_ctx);
+		break;
+
+	case eCSR_ROAM_DFS_RADAR_IND:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			  "Received Radar Indication on sap ch %d, session %d",
+			  sap_ctx->channel, sap_ctx->sessionId);
+
+		if (sta_sap_scc_on_dfs_chan) {
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_DEBUG,
+				  FL("Ignore the Radar indication"));
+			goto EXIT;
+		}
+
+		if (sap_ctx->fsm_state != SAP_STARTED &&
+		    !sap_is_dfs_cac_wait_state(sap_ctx)) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+				  FL("Ignore Radar event in sap state %d cac wait state %d"),
+				  sap_ctx->fsm_state,
+				  sap_is_dfs_cac_wait_state(sap_ctx));
+			goto EXIT;
+		}
+
+		if (!sap_chan_bond_dfs_sub_chan(
+			sap_ctx, sap_ctx->channel,
+			PHY_CHANNEL_BONDING_STATE_MAX))  {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+				  "Ignore Radar event for sap ch %d",
+				  sap_ctx->channel);
+			goto EXIT;
+		}
+
+		if (sap_ctx->is_pre_cac_on) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+				  FL("sapdfs: Radar detect on pre cac:%d"),
+				  sap_ctx->sessionId);
+			if (!sap_ctx->dfs_cac_offload) {
+				qdf_mc_timer_stop(
+				&mac_ctx->sap.SapDfsInfo.sap_dfs_cac_timer);
+				qdf_mc_timer_destroy(
+				&mac_ctx->sap.SapDfsInfo.sap_dfs_cac_timer);
+			}
+			mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running =
+				false;
+			sap_signal_hdd_event(sap_ctx, NULL,
+					eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC,
+					(void *) eSAP_STATUS_SUCCESS);
+			break;
+		}
+
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+			  FL("sapdfs: Indicate eSAP_DFS_RADAR_DETECT to HDD"));
+		sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_RADAR_DETECT,
+				     (void *) eSAP_STATUS_SUCCESS);
+		mac_ctx->sap.SapDfsInfo.target_channel =
+			sap_indicate_radar(sap_ctx);
+		/* if there is an assigned next channel hopping */
+		if (0 < mac_ctx->sap.SapDfsInfo.user_provided_target_channel) {
+			mac_ctx->sap.SapDfsInfo.target_channel =
+			   mac_ctx->sap.SapDfsInfo.user_provided_target_channel;
+			mac_ctx->sap.SapDfsInfo.user_provided_target_channel =
+			   0;
+		}
+		/* if external acs enabled */
+		if (sap_ctx->vendor_acs_dfs_lte_enabled &&
+		    !mac_ctx->sap.SapDfsInfo.target_channel) {
+			/* Return from here, processing will be done later */
+			goto EXIT;
+		}
+		if (mac_ctx->sap.SapDfsInfo.target_channel != 0) {
+			mac_ctx->sap.SapDfsInfo.cac_state =
+				eSAP_DFS_DO_NOT_SKIP_CAC;
+			sap_cac_reset_notify(mac_handle);
+			break;
+		}
+		/* Issue stopbss for each sapctx */
+		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+			struct sap_context *sap_context;
+			struct csr_roam_profile *profile;
+
+			if (((QDF_SAP_MODE ==
+			    mac_ctx->sap.sapCtxList[intf].sapPersona) ||
+			    (QDF_P2P_GO_MODE ==
+			    mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
+			    mac_ctx->sap.sapCtxList[intf].sap_context !=
+			    NULL) {
+				sap_context =
+				    mac_ctx->sap.sapCtxList[intf].sap_context;
+				profile = &sap_context->csr_roamProfile;
+				if (!wlan_reg_is_passive_or_disable_ch(
+						mac_ctx->pdev,
+						profile->operationChannel))
+					continue;
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  FL("sapdfs: no available channel for sapctx[%pK], StopBss"),
+					  sap_context);
+				sap_signal_hdd_event(sap_context, NULL,
+					eSAP_STOP_BSS_DUE_TO_NO_CHNL,
+					(void *) eSAP_STATUS_SUCCESS);
+			}
+		}
+		break;
+	case eCSR_ROAM_DFS_CHAN_SW_NOTIFY:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("Received Chan Sw Update Notification"));
+		break;
+	case eCSR_ROAM_SET_CHANNEL_RSP:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("Received set channel response"));
+		/* SAP channel change request processing is completed */
+		sap_ctx->is_chan_change_inprogress = false;
+		break;
+	case eCSR_ROAM_CAC_COMPLETE_IND:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("Received cac complete indication"));
+		break;
+	case eCSR_ROAM_EXT_CHG_CHNL_IND:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				FL("Received set channel Indication"));
+		break;
+	default:
+		break;
+	}
+
+	switch (roam_result) {
+	case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND:
+		if (csr_roam_info)
+			wlansap_roam_process_infra_assoc_ind(sap_ctx,
+						roam_result,
+						csr_roam_info, &qdf_ret_status);
+		break;
+	case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF:
+		if (!csr_roam_info) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  "csr_roam_info is NULL");
+			qdf_ret_status = QDF_STATUS_E_NULL_VALUE;
+			break;
+		}
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF (%d)"),
+			  roam_result);
+		sap_ctx->nStaWPARSnReqIeLength = csr_roam_info->rsnIELen;
+		if (sap_ctx->nStaWPARSnReqIeLength)
+			qdf_mem_copy(sap_ctx->pStaWpaRsnReqIE,
+				     csr_roam_info->prsnIE,
+				     sap_ctx->nStaWPARSnReqIeLength);
+
+		sap_ctx->SapQosCfg.WmmIsEnabled =
+			csr_roam_info->wmmEnabledSta;
+		/* Fill in the event structure */
+		qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info,
+					eSAP_STA_ASSOC_EVENT,
+					(void *) eSAP_STATUS_SUCCESS);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		break;
+	case eCSR_ROAM_RESULT_DEAUTH_IND:
+	case eCSR_ROAM_RESULT_DISASSOC_IND:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_DEAUTH/DISASSOC_IND (%d)"),
+			  roam_result);
+		/* Fill in the event structure */
+		qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info,
+					eSAP_STA_DISASSOC_EVENT,
+					(void *) eSAP_STATUS_SUCCESS);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		break;
+	case eCSR_ROAM_RESULT_MIC_ERROR_GROUP:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_MIC_ERROR_GROUP (%d)"),
+			  roam_result);
+		/*
+		 * Fill in the event structure
+		 * TODO: support for group key MIC failure event to be handled
+		 */
+		qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info,
+						eSAP_STA_MIC_FAILURE_EVENT,
+						(void *) NULL);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		break;
+	case eCSR_ROAM_RESULT_MIC_ERROR_UNICAST:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST (%d)"),
+			  roam_result);
+		/*
+		 * Fill in the event structure
+		 * TODO: support for unicast key MIC failure event to be handled
+		 */
+		qdf_status =
+			sap_signal_hdd_event(sap_ctx, csr_roam_info,
+					  eSAP_STA_MIC_FAILURE_EVENT,
+					  (void *) NULL);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		}
+		break;
+	case eCSR_ROAM_RESULT_AUTHENTICATED:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_AUTHENTICATED (%d)"),
+			  roam_result);
+		/* Fill in the event structure */
+		sap_signal_hdd_event(sap_ctx, csr_roam_info,
+				  eSAP_STA_SET_KEY_EVENT,
+				  (void *) eSAP_STATUS_SUCCESS);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		break;
+	case eCSR_ROAM_RESULT_ASSOCIATED:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_ASSOCIATED (%d)"),
+			  roam_result);
+		/* Fill in the event structure */
+		sap_signal_hdd_event(sap_ctx, csr_roam_info,
+				     eSAP_STA_REASSOC_EVENT,
+				     (void *) eSAP_STATUS_SUCCESS);
+		break;
+	case eCSR_ROAM_RESULT_INFRA_STARTED:
+		if (!csr_roam_info) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  "csr_roam_info is NULL");
+			qdf_ret_status = QDF_STATUS_E_NULL_VALUE;
+			break;
+		}
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_INFRA_STARTED (%d)"),
+			  roam_result);
+		/*
+		 * In the current implementation, hostapd is not aware that
+		 * drive will support DFS. Hence, driver should inform
+		 * eSAP_MAC_START_BSS_SUCCESS to upper layers and then perform
+		 * CAC underneath
+		 */
+		sap_event.event = eSAP_MAC_START_BSS_SUCCESS;
+		sap_event.params = csr_roam_info;
+		sap_ctx->sap_sta_id = csr_roam_info->staId;
+		sap_event.u1 = roam_status;
+		sap_event.u2 = roam_result;
+		qdf_status = sap_fsm(sap_ctx, &sap_event);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		break;
+	case eCSR_ROAM_RESULT_INFRA_STOPPED:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_INFRA_STOPPED (%d)"),
+			  roam_result);
+		/* Fill in the event structure */
+		sap_event.event = eSAP_MAC_READY_FOR_CONNECTIONS;
+		sap_event.params = csr_roam_info;
+		sap_event.u1 = roam_status;
+		sap_event.u2 = roam_result;
+		/* Handle event */
+		qdf_status = sap_fsm(sap_ctx, &sap_event);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		break;
+	case eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND (%d)"),
+			  roam_result);
+		/*
+		 * Fill in the event structure
+		 * TODO: support for group key MIC failure event to be handled
+		 */
+		qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info,
+						eSAP_WPS_PBC_PROBE_REQ_EVENT,
+						(void *) NULL);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		break;
+	case eCSR_ROAM_RESULT_FORCED:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_FORCED (%d)"),
+			  roam_result);
+		/*
+		 * This event can be used to inform hdd about user triggered
+		 * disassoc event
+		 * Fill in the event structure
+		 */
+		sap_signal_hdd_event(sap_ctx, csr_roam_info,
+				     eSAP_STA_DISASSOC_EVENT,
+				     (void *) eSAP_STATUS_SUCCESS);
+		break;
+	case eCSR_ROAM_RESULT_NONE:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_NONE (%d)"),
+			  roam_result);
+		/*
+		 * This event can be used to inform hdd about user triggered
+		 * disassoc event
+		 * Fill in the event structure
+		 */
+		if (roam_status == eCSR_ROAM_SET_KEY_COMPLETE)
+			sap_signal_hdd_event(sap_ctx, csr_roam_info,
+					     eSAP_STA_SET_KEY_EVENT,
+					     (void *) eSAP_STATUS_SUCCESS);
+		break;
+	case eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("CSR roam_result = eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED (%d)"),
+			  roam_result);
+		/* Fill in the event structure */
+		qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info,
+						  eSAP_MAX_ASSOC_EXCEEDED,
+						  NULL);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+
+		break;
+	case eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND:
+		if (sta_sap_scc_on_dfs_chan)
+			break;
+		wlansap_roam_process_dfs_radar_found(mac_ctx, sap_ctx,
+						&qdf_ret_status);
+		break;
+	case eCSR_ROAM_RESULT_CSA_RESTART_RSP:
+		qdf_ret_status = wlansap_dfs_send_csa_ie_request(sap_ctx);
+
+		if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status))
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				  FL("CSR roam_result = eCSR_ROAM_RESULT_CSA_RESTART_RSP %d"),
+				  roam_result);
+		break;
+	case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS:
+		wlansap_roam_process_dfs_chansw_update(mac_handle, sap_ctx,
+						       &qdf_ret_status);
+		break;
+	case eCSR_ROAM_RESULT_CAC_END_IND:
+		sap_dfs_cac_timer_callback(mac_handle);
+		break;
+	case eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS:
+		wlansap_roam_process_ch_change_success(mac_ctx, sap_ctx,
+						csr_roam_info, &qdf_ret_status);
+		break;
+	case eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE:
+		/* This is much more serious issue, we have to vacate the
+		 * channel due to the presence of radar but our channel change
+		 * failed, stop the BSS operation completely and inform hostapd
+		 */
+		qdf_ret_status = wlansap_stop_bss(sap_ctx);
+		break;
+	case eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND:
+		qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info,
+				   eSAP_ECSA_CHANGE_CHAN_IND, NULL);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			qdf_ret_status = QDF_STATUS_E_FAILURE;
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("CSR roam_result = %s (%d) not handled"),
+			  get_e_csr_roam_result_str(roam_result),
+			  roam_result);
+		break;
+	}
+EXIT:
+	wlansap_context_put(sap_ctx);
+	return qdf_ret_status;
+}
+
+void sap_scan_event_callback(struct wlan_objmgr_vdev *vdev,
+			struct scan_event *event, void *arg)
+{
+	uint32_t scan_id;
+	uint8_t session_id;
+	bool success = false;
+	eCsrScanStatus scan_status = eCSR_SCAN_FAILURE;
+	tHalHandle hal_handle;
+
+	session_id = wlan_vdev_get_id(vdev);
+	scan_id = event->scan_id;
+	hal_handle = cds_get_context(QDF_MODULE_ID_SME);
+	if (!hal_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
+			  FL("invalid h_hal"));
+		return;
+	}
+
+	qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SAP, event->type,
+		   event->vdev_id, event->scan_id);
+
+	if (!util_is_scan_completed(event, &success))
+		return;
+
+	if (success)
+		scan_status = eCSR_SCAN_SUCCESS;
+
+	wlansap_pre_start_bss_acs_scan_callback(hal_handle,
+						arg, session_id,
+						scan_id, scan_status);
+}
diff --git a/core/sap/src/sap_ch_select.c b/core/sap/src/sap_ch_select.c
new file mode 100644
index 0000000..4a9bfbe
--- /dev/null
+++ b/core/sap/src/sap_ch_select.c
@@ -0,0 +1,2869 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*===========================================================================
+
+			s a p C h S e l e c t . C
+   OVERVIEW:
+
+   This software unit holds the implementation of the WLAN SAP modules
+   functions for channel selection.
+
+   DEPENDENCIES:
+
+   Are listed for each API below.
+   ===========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include "qdf_trace.h"
+#include "csr_api.h"
+#include "sme_api.h"
+#include "sap_ch_select.h"
+#include "sap_internal.h"
+#ifdef ANI_OS_TYPE_QNX
+#include "stdio.h"
+#endif
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+#include "lim_utils.h"
+#include "parser_api.h"
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+#include "cds_utils.h"
+#include "pld_common.h"
+#include "wlan_reg_services_api.h"
+
+/*--------------------------------------------------------------------------
+   Function definitions
+   --------------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------------
+   Defines
+   --------------------------------------------------------------------------*/
+#define SAP_DEBUG
+
+#define IS_RSSI_VALID(extRssi, rssi) \
+	( \
+		((extRssi < rssi) ? true : false) \
+	)
+
+#define SET_ACS_BAND(acs_band, sap_ctx) \
+{ \
+	if (sap_ctx->acs_cfg->start_ch <= 14 && \
+		sap_ctx->acs_cfg->end_ch <= 14) \
+		acs_band = eCSR_DOT11_MODE_11g; \
+	else if (sap_ctx->acs_cfg->start_ch >= 14)\
+		acs_band = eCSR_DOT11_MODE_11a; \
+	else \
+		acs_band = eCSR_DOT11_MODE_abg; \
+}
+
+#define ACS_WEIGHT_AMOUNT_LOCAL    240
+
+#define ACS_WEIGHT_AMOUNT_CONFIG(weights) \
+	(((weights) & 0xf) + \
+	(((weights) & 0xf0) >> 4) + \
+	(((weights) & 0xf00) >> 8) + \
+	(((weights) & 0xf000) >> 12) + \
+	(((weights) & 0xf0000) >> 16) + \
+	(((weights) & 0xf00000) >> 20))
+
+/*
+ * LSH/RSH 4 to enhance the accurate since
+ * need to do modulation to ACS_WEIGHT_AMOUNT_LOCAL.
+ */
+#define ACS_WEIGHT_COMPUTE(weights, weight, factor, base) \
+	(((((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL * (factor)) + \
+	(ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
+	ACS_WEIGHT_AMOUNT_CONFIG((weights))) + \
+	((base) >> 1)) / (base)) + 8) >> 4)
+
+#define ACS_WEIGHT_CFG_TO_LOCAL(weights, weight) \
+	(((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL) + \
+	(ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
+	ACS_WEIGHT_AMOUNT_CONFIG((weights))) + 8) >> 4)
+
+#define ACS_WEIGHT_SOFTAP_RSSI_CFG(weights) \
+	((weights) & 0xf)
+
+#define ACS_WEIGHT_SOFTAP_COUNT_CFG(weights) \
+	(((weights) & 0xf0) >> 4)
+
+#define ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG(weights) \
+	(((weights) & 0xf00) >> 8)
+
+#define ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG(weights) \
+	(((weights) & 0xf000) >> 12)
+
+#define ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG(weights) \
+	(((weights) & 0xf0000) >> 16)
+
+#define ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG(weights) \
+	(((weights) & 0xf00000) >> 20)
+
+#ifdef FEATURE_WLAN_CH_AVOID
+sapSafeChannelType safe_channels[NUM_CHANNELS] = {
+	{1, true},
+	{2, true},
+	{3, true},
+	{4, true},
+	{5, true},
+	{6, true},
+	{7, true},
+	{8, true},
+	{9, true},
+	{10, true},
+	{11, true},
+	{12, true},
+	{13, true},
+	{14, true},
+	{36, true},
+	{40, true},
+	{44, true},
+	{48, true},
+	{52, true},
+	{56, true},
+	{60, true},
+	{64, true},
+	{100, true},
+	{104, true},
+	{108, true},
+	{112, true},
+	{116, true},
+	{120, true},
+	{124, true},
+	{128, true},
+	{132, true},
+	{136, true},
+	{140, true},
+	{144, true},
+	{149, true},
+	{153, true},
+	{157, true},
+	{161, true},
+	{165, true},
+	{169, true},
+	{173, true},
+};
+#endif
+
+typedef struct {
+	uint16_t chStartNum;
+	uint32_t weight;
+} sapAcsChannelInfo;
+
+sapAcsChannelInfo acs_ht40_channels5_g[] = {
+	{36, SAP_ACS_WEIGHT_MAX},
+	{44, SAP_ACS_WEIGHT_MAX},
+	{52, SAP_ACS_WEIGHT_MAX},
+	{60, SAP_ACS_WEIGHT_MAX},
+	{100, SAP_ACS_WEIGHT_MAX},
+	{108, SAP_ACS_WEIGHT_MAX},
+	{116, SAP_ACS_WEIGHT_MAX},
+	{124, SAP_ACS_WEIGHT_MAX},
+	{132, SAP_ACS_WEIGHT_MAX},
+	{140, SAP_ACS_WEIGHT_MAX},
+	{149, SAP_ACS_WEIGHT_MAX},
+	{157, SAP_ACS_WEIGHT_MAX},
+};
+
+sapAcsChannelInfo acs_ht80_channels[] = {
+	{36, SAP_ACS_WEIGHT_MAX},
+	{52, SAP_ACS_WEIGHT_MAX},
+	{100, SAP_ACS_WEIGHT_MAX},
+	{116, SAP_ACS_WEIGHT_MAX},
+	{132, SAP_ACS_WEIGHT_MAX},
+	{149, SAP_ACS_WEIGHT_MAX},
+};
+
+sapAcsChannelInfo acs_vht160_channels[] = {
+	{36, SAP_ACS_WEIGHT_MAX},
+	{100, SAP_ACS_WEIGHT_MAX},
+};
+
+sapAcsChannelInfo acs_ht40_channels24_g[] = {
+	{1, SAP_ACS_WEIGHT_MAX},
+	{2, SAP_ACS_WEIGHT_MAX},
+	{3, SAP_ACS_WEIGHT_MAX},
+	{4, SAP_ACS_WEIGHT_MAX},
+	{9, SAP_ACS_WEIGHT_MAX},
+};
+
+#define CHANNEL_165  165
+
+/* rssi discount for channels in PCL */
+#define PCL_RSSI_DISCOUNT 10
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+/**
+ * sap_check_n_add_channel() - checks and add given channel in sap context's
+ * avoid_channels_info struct
+ * @sap_ctx:           sap context.
+ * @new_channel:       channel to be added to sap_ctx's avoid ch info
+ *
+ * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
+ * which MDM device's AP with MCC was detected. This function will add channels
+ * to that list after checking for duplicates.
+ *
+ * Return: true: if channel was added or already present
+ *   else false: if channel list was already full.
+ */
+static bool
+sap_check_n_add_channel(struct sap_context *sap_ctx,
+			uint8_t new_channel)
+{
+	uint8_t i = 0;
+	struct sap_avoid_channels_info *ie_info =
+		&sap_ctx->sap_detected_avoid_ch_ie;
+
+	for (i = 0; i < sizeof(ie_info->channels); i++) {
+		if (ie_info->channels[i] == new_channel)
+			break;
+
+		if (ie_info->channels[i] == 0) {
+			ie_info->channels[i] = new_channel;
+			break;
+		}
+	}
+	if (i == sizeof(ie_info->channels))
+		return false;
+	else
+		return true;
+}
+/**
+ * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
+ *                                      to primary channel in 2.4Ghz band.
+ * @sap_ctx:           sap context.
+ * @primary_chnl:      primary channel to be avoided.
+ *
+ * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
+ * which MDM device's AP with MCC was detected. This function will add channels
+ * to that list after checking for duplicates.
+ *
+ * Return: true: if channel was added or already present
+ *   else false: if channel list was already full.
+ */
+static bool
+sap_check_n_add_overlapped_chnls(struct sap_context *sap_ctx,
+				 uint8_t primary_channel)
+{
+	uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
+	struct sap_avoid_channels_info *ie_info =
+		&sap_ctx->sap_detected_avoid_ch_ie;
+	/*
+	 * if primary channel less than channel 1 or out of 2g band then
+	 * no further process is required. return true in this case.
+	 */
+	if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
+		return true;
+
+	/* lower channel is one channel right before primary channel */
+	lower_chnl = primary_channel - 1;
+	/* upper channel is one channel right after primary channel */
+	upper_chnl = primary_channel + 1;
+
+	/* lower channel needs to be non-zero, zero is not valid channel */
+	if (lower_chnl > (CHANNEL_1 - 1)) {
+		for (i = 0; i < sizeof(ie_info->channels); i++) {
+			if (ie_info->channels[i] == lower_chnl)
+				break;
+			if (ie_info->channels[i] == 0) {
+				ie_info->channels[i] = lower_chnl;
+				break;
+			}
+		}
+	}
+	/* upper channel needs to be atleast last channel in 2.4Ghz band */
+	if (upper_chnl < (CHANNEL_14 + 1)) {
+		for (j = 0; j < sizeof(ie_info->channels); j++) {
+			if (ie_info->channels[j] == upper_chnl)
+				break;
+			if (ie_info->channels[j] == 0) {
+				ie_info->channels[j] = upper_chnl;
+				break;
+			}
+		}
+	}
+	if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
+		return false;
+	else
+		return true;
+}
+
+/**
+ * sap_process_avoid_ie() - processes the detected Q2Q IE
+ * context's avoid_channels_info struct
+ * @hal:                hal handle
+ * @sap_ctx:            sap context.
+ * @scan_result:        scan results for ACS scan.
+ * @spect_info:         spectrum weights array to update
+ *
+ * Detection of Q2Q IE indicates presence of another MDM device with its AP
+ * operating in MCC mode. This function parses the scan results and processes
+ * the Q2Q IE if found. It then extracts the channels and populates them in
+ * sap_ctx struct. It also increases the weights of those channels so that
+ * ACS logic will avoid those channels in its selection algorithm.
+ *
+ * Return: void
+ */
+static void sap_process_avoid_ie(tHalHandle hal,
+			  struct sap_context *sap_ctx,
+			  tScanResultHandle scan_result,
+			  tSapChSelSpectInfo *spect_info)
+{
+	uint32_t total_ie_len = 0;
+	uint8_t *temp_ptr = NULL;
+	uint8_t i = 0;
+	struct sAvoidChannelIE *avoid_ch_ie;
+	tCsrScanResultInfo *node = NULL;
+	tpAniSirGlobal mac_ctx = NULL;
+	tSapSpectChInfo *spect_ch = NULL;
+
+	mac_ctx = PMAC_STRUCT(hal);
+	spect_ch = spect_info->pSpectCh;
+	node = sme_scan_result_get_first(hal, scan_result);
+
+	while (node) {
+		total_ie_len =
+			GET_IE_LEN_IN_BSS(node->BssDescriptor.length);
+		temp_ptr = wlan_get_vendor_ie_ptr_from_oui(
+				SIR_MAC_QCOM_VENDOR_OUI,
+				SIR_MAC_QCOM_VENDOR_SIZE,
+				((uint8_t *)&node->BssDescriptor.ieFields),
+				total_ie_len);
+
+		if (temp_ptr) {
+			avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
+			if (avoid_ch_ie->type !=
+					QCOM_VENDOR_IE_MCC_AVOID_CH) {
+				node = sme_scan_result_get_next(hal,
+					scan_result);
+				continue;
+			}
+
+			sap_ctx->sap_detected_avoid_ch_ie.present = 1;
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_DEBUG,
+				  "Q2Q IE - avoid ch %d",
+				  avoid_ch_ie->channel);
+			/* add this channel to to_avoid channel list */
+			sap_check_n_add_channel(sap_ctx,
+					avoid_ch_ie->channel);
+			sap_check_n_add_overlapped_chnls(sap_ctx,
+					avoid_ch_ie->channel);
+			/*
+			 * Mark weight of these channel present in IE to MAX
+			 * so that ACS logic will to avoid thse channels
+			 */
+			for (i = 0; i < spect_info->numSpectChans; i++)
+				if (spect_ch[i].chNum == avoid_ch_ie->channel) {
+					/*
+					 * weight is set more than max so that,
+					 * in the case of other channels being
+					 * assigned max weight due to noise,
+					 * they may be preferred over channels
+					 * with Q2Q IE.
+					 */
+					spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
+					spect_ch[i].weight_copy =
+						SAP_ACS_WEIGHT_MAX + 1;
+					break;
+				}
+		} /* if (temp_ptr) */
+		node = sme_scan_result_get_next(hal, scan_result);
+	}
+}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+#ifdef FEATURE_WLAN_CH_AVOID
+/*==========================================================================
+   FUNCTION    sap_update_unsafe_channel_list
+
+   DESCRIPTION
+    Function  Undate unsafe channel list table
+
+   DEPENDENCIES
+    NA.
+
+   IN
+    SapContext pointer
+
+   RETURN VALUE
+    NULL
+   ============================================================================*/
+void sap_update_unsafe_channel_list(tHalHandle hal, struct sap_context *sap_ctx)
+{
+	uint16_t i, j;
+	uint16_t unsafe_channel_list[NUM_CHANNELS];
+	uint16_t unsafe_channel_count = 0;
+	tpAniSirGlobal mac_ctx = NULL;
+
+	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	if (!qdf_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
+			  "qdf_ctx is NULL");
+		return;
+	}
+	mac_ctx = PMAC_STRUCT(hal);
+
+	/* Flush, default set all channel safe */
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		safe_channels[i].isSafe = true;
+	}
+
+	/* Try to find unsafe channel */
+#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		if (sap_ctx->dfs_ch_disable == true) {
+			if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
+					safe_channels[i].channelNumber)) {
+				safe_channels[i].isSafe = false;
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					QDF_TRACE_LEVEL_INFO_HIGH,
+					"%s: DFS Ch %d is not safe in"
+					" Concurrent mode",
+					__func__,
+					safe_channels[i].channelNumber);
+			}
+		}
+	}
+#endif
+	pld_get_wlan_unsafe_channel(qdf_ctx->dev,
+				    unsafe_channel_list,
+				     &unsafe_channel_count,
+				     sizeof(unsafe_channel_list));
+
+	for (i = 0; i < unsafe_channel_count; i++) {
+		for (j = 0; j < NUM_CHANNELS; j++) {
+			if (safe_channels[j].channelNumber ==
+			    unsafe_channel_list[i]) {
+				/* Found unsafe channel, update it */
+				safe_channels[j].isSafe = false;
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  FL("CH %d is not safe"),
+					  unsafe_channel_list[i]);
+				break;
+			}
+		}
+	}
+
+	return;
+}
+
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+/**
+ * sap_channel_in_acs_channel_list() - check if channel in acs channel list
+ * @channel_num: channel to check
+ * @sap_ctx: struct ptSapContext
+ * @spect_info_params: strcut tSapChSelSpectInfo
+ *
+ * This function checks if specified channel is in the configured ACS channel
+ * list.
+ *
+ * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
+ */
+uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
+					struct sap_context *sap_ctx,
+					tSapChSelSpectInfo *spect_info_params)
+{
+	uint8_t i = 0;
+
+	if ((NULL == sap_ctx->acs_cfg->ch_list) ||
+	    (NULL == spect_info_params))
+		return channel_num;
+
+	if (channel_num > 0 && channel_num <= 252) {
+		for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
+			if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
+				return channel_num;
+		}
+		return SAP_CHANNEL_NOT_SELECTED;
+	} else {
+		return SAP_CHANNEL_NOT_SELECTED;
+	}
+}
+
+/**
+ * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
+ * @best_chnl: best channel already calculated among all the chanels
+ * @sap_ctx: sap context
+ * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
+ *
+ * This function calculates the best channel among the configured channel list.
+ * If channel list not configured then returns the best channel calculated
+ * among all the channel list.
+ *
+ * Return: uint8_t best channel
+ */
+static
+uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
+				struct sap_context *sap_ctx,
+				tSapChSelSpectInfo *spectinfo_param)
+{
+	uint8_t i = 0;
+	tpAniSirGlobal mac_ctx = sme_get_mac_context();
+
+	if (NULL == mac_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"pmac Global Context is NULL");
+		return SAP_CHANNEL_NOT_SELECTED;
+	}
+
+	/*
+	 * If Channel List is not Configured don't do anything
+	 * Else return the Best Channel from the Channel List
+	 */
+	if ((NULL == sap_ctx->acs_cfg->ch_list) ||
+		(NULL == spectinfo_param) ||
+		(0 == sap_ctx->acs_cfg->ch_list_count))
+		return best_chnl;
+
+	if (best_chnl <= 0 || best_chnl > 252)
+		return SAP_CHANNEL_NOT_SELECTED;
+
+	/* Select the best channel from allowed list */
+	for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
+		if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) &&
+			!(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) &&
+			policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) {
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				QDF_TRACE_LEVEL_INFO,
+				"Best channel so far is: %d",
+				best_chnl);
+			return best_chnl;
+		}
+	}
+
+	return SAP_CHANNEL_NOT_SELECTED;
+}
+
+/*==========================================================================
+   FUNCTION    sap_chan_sel_init
+
+   DESCRIPTION
+    Function sap_chan_sel_init allocates the memory, initializes the
+    structures used by the channel selection algorithm
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    halHandle          : Pointer to tHalHandle
+   *pSpectInfoParams  : Pointer to tSapChSelSpectInfo structure
+     sap_ctx           : Pointer to SAP Context
+
+   RETURN VALUE
+    bool:  Success or FAIL
+
+   SIDE EFFECTS
+   ============================================================================*/
+static bool sap_chan_sel_init(tHalHandle halHandle,
+			      tSapChSelSpectInfo *pSpectInfoParams,
+			      struct sap_context *sap_ctx)
+{
+	tSapSpectChInfo *pSpectCh = NULL;
+	uint8_t *pChans = NULL;
+	uint16_t channelnum = 0;
+	tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
+	bool chSafe = true;
+#ifdef FEATURE_WLAN_CH_AVOID
+	uint16_t i;
+#endif
+	bool include_dfs_ch = true;
+	uint8_t chan_num;
+	bool sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(pMac->psoc);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
+		  __func__);
+
+	pSpectInfoParams->numSpectChans =
+		pMac->scan.base_channels.numChannels;
+
+	/* Allocate memory for weight computation of 2.4GHz */
+	pSpectCh = qdf_mem_malloc((pSpectInfoParams->numSpectChans) *
+			sizeof(*pSpectCh));
+	if (!pSpectCh)
+		return false;
+
+	/* Initialize the pointers in the DfsParams to the allocated memory */
+	pSpectInfoParams->pSpectCh = pSpectCh;
+
+	pChans = pMac->scan.base_channels.channelList;
+
+#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
+	if (sap_ctx->dfs_ch_disable == true)
+		include_dfs_ch = false;
+#endif
+	if (!pMac->mlme_cfg->dfs_cfg.dfs_master_capable ||
+	    ACS_DFS_MODE_DISABLE == sap_ctx->dfs_mode)
+		include_dfs_ch = false;
+
+	/* Fill the channel number in the spectrum in the operating freq band */
+	for (channelnum = 0;
+	     channelnum < pSpectInfoParams->numSpectChans;
+	     channelnum++, pChans++, pSpectCh++) {
+		chSafe = true;
+
+		pSpectCh->chNum = *pChans;
+		/* Initialise for all channels */
+		pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+		/* Initialise 20MHz for all the Channels */
+		pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH;
+		/* Initialise max ACS weight for all channels */
+		pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
+
+		/* check if the channel is in NOL blacklist */
+		if (sap_dfs_is_channel_in_nol_list(
+					sap_ctx, *pChans,
+					PHY_SINGLE_CHANNEL_CENTERED)) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				  "In %s, Ch %d is in NOL list", __func__,
+				  *pChans);
+			chSafe = false;
+			continue;
+		}
+
+		if (!include_dfs_ch || sta_sap_scc_on_dfs_chan) {
+			if (wlan_reg_is_dfs_ch(pMac->pdev, *pChans)) {
+				chSafe = false;
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO_HIGH,
+					  "In %s, DFS Ch %d not considered for ACS. include_dfs_ch %u, sta_sap_scc_on_dfs_chan %d",
+					  __func__, *pChans, include_dfs_ch,
+					  sta_sap_scc_on_dfs_chan);
+				continue;
+			}
+		}
+
+#ifdef FEATURE_WLAN_CH_AVOID
+		for (i = 0; i < NUM_CHANNELS; i++) {
+			if ((safe_channels[i].channelNumber == *pChans) &&
+			    (false == safe_channels[i].isSafe)) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO_HIGH,
+					  "In %s, Ch %d is not safe", __func__,
+					  *pChans);
+				chSafe = false;
+				break;
+			}
+		}
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+		/* OFDM rates are not supported on channel 14 */
+		if (*pChans == 14 &&
+		    eCSR_DOT11_MODE_11b != sap_ctx->csr_roamProfile.phyMode) {
+			continue;
+		}
+
+		/* Skip DSRC channels */
+		if (wlan_reg_is_dsrc_chan(pMac->pdev, *pChans))
+			continue;
+
+		if (!pMac->sap.enable_etsi13_srd_chan_support &&
+		    wlan_reg_is_etsi13_srd_chan(pMac->pdev, *pChans))
+			continue;
+
+		if (true == chSafe) {
+			pSpectCh->valid = true;
+			for (chan_num = 0; chan_num < sap_ctx->num_of_channel;
+			     chan_num++) {
+				if (pSpectCh->chNum !=
+				    sap_ctx->channelList[chan_num])
+					continue;
+
+				/*
+				 * Initialize ACS weight to 0 for channels
+				 * present in sap context scan channel list
+				 */
+				pSpectCh->weight = 0;
+				break;
+			}
+		}
+	}
+	return true;
+}
+
+/**
+ * sapweight_rssi_count() - calculates the channel weight due to rssi
+    and data count(here number of BSS observed)
+ * @sap_ctx     : Softap context
+ * @rssi        : Max signal strength receieved from a BSS for the channel
+ * @count       : Number of BSS observed in the channel
+ *
+ * Return: uint32_t Calculated channel weight based on above two
+ */
+static
+uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
+			      uint16_t count)
+{
+	int32_t rssiWeight = 0;
+	int32_t countWeight = 0;
+	uint32_t rssicountWeight = 0;
+	uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
+	uint8_t softap_rssi_weight_local, softap_count_weight_local;
+
+	softap_rssi_weight_cfg =
+	    ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
+
+	softap_count_weight_cfg =
+	    ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
+
+	softap_rssi_weight_local =
+	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
+				    softap_rssi_weight_cfg);
+
+	softap_count_weight_local =
+	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
+				    softap_count_weight_cfg);
+
+	/* Weight from RSSI */
+	rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
+					softap_rssi_weight_cfg,
+					rssi - SOFTAP_MIN_RSSI,
+					SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
+
+	if (rssiWeight > softap_rssi_weight_local)
+		rssiWeight = softap_rssi_weight_local;
+
+	else if (rssiWeight < 0)
+		rssiWeight = 0;
+
+	/* Weight from data count */
+	countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
+					 softap_count_weight_cfg,
+					 count - SOFTAP_MIN_COUNT,
+					 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
+
+	if (countWeight > softap_count_weight_local)
+		countWeight = softap_count_weight_local;
+
+	rssicountWeight = rssiWeight + countWeight;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
+		  __func__, rssiWeight, countWeight, rssicountWeight);
+
+	return rssicountWeight;
+}
+
+/**
+ * sap_get_channel_status() - get channel info via channel number
+ * @p_mac: Pointer to Global MAC structure
+ * @channel_id: channel id
+ *
+ * Return: chan status info
+ */
+static struct lim_channel_status *sap_get_channel_status
+	(tpAniSirGlobal p_mac, uint32_t channel_id)
+{
+	return csr_get_channel_status(p_mac, channel_id);
+}
+
+/**
+ * sap_clear_channel_status() - clear chan info
+ * @p_mac: Pointer to Global MAC structure
+ *
+ * Return: none
+ */
+static void sap_clear_channel_status(tpAniSirGlobal p_mac)
+{
+	csr_clear_channel_status(p_mac);
+}
+
+/**
+ * sap_weight_channel_noise_floor() - compute noise floor weight
+ * @sap_ctx:  sap context
+ * @chn_stat: Pointer to chan status info
+ *
+ * Return: channel noise floor weight
+ */
+static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
+					       struct lim_channel_status
+						*channel_stat)
+{
+	uint32_t    noise_floor_weight;
+	uint8_t     softap_nf_weight_cfg;
+	uint8_t     softap_nf_weight_local;
+
+	softap_nf_weight_cfg =
+	    ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
+	    (sap_ctx->auto_channel_select_weight);
+
+	softap_nf_weight_local =
+	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
+				    softap_nf_weight_cfg);
+
+	if (channel_stat == NULL || channel_stat->channelfreq == 0) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			  "In %s, sanity check failed return max weight",
+			  __func__);
+		return softap_nf_weight_local;
+	}
+
+	noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
+			    (ACS_WEIGHT_COMPUTE(
+			     sap_ctx->auto_channel_select_weight,
+			     softap_nf_weight_cfg,
+			     channel_stat->noise_floor -
+			     SOFTAP_MIN_NF,
+			     SOFTAP_MAX_NF - SOFTAP_MIN_NF));
+
+	if (noise_floor_weight > softap_nf_weight_local)
+		noise_floor_weight = softap_nf_weight_local;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
+		  __func__, channel_stat->noise_floor,
+		  softap_nf_weight_cfg, softap_nf_weight_local,
+		  noise_floor_weight);
+
+	return noise_floor_weight;
+}
+
+/**
+ * sap_weight_channel_free() - compute channel free weight
+ * @sap_ctx:  sap context
+ * @chn_stat: Pointer to chan status info
+ *
+ * Return: channel free weight
+ */
+static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
+					struct lim_channel_status
+					*channel_stat)
+{
+	uint32_t     channel_free_weight;
+	uint8_t      softap_channel_free_weight_cfg;
+	uint8_t      softap_channel_free_weight_local;
+	uint32_t     rx_clear_count = 0;
+	uint32_t     cycle_count = 0;
+
+	softap_channel_free_weight_cfg =
+	    ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
+	    (sap_ctx->auto_channel_select_weight);
+
+	softap_channel_free_weight_local =
+	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
+				    softap_channel_free_weight_cfg);
+
+	if (channel_stat == NULL || channel_stat->channelfreq == 0) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			  "In %s, sanity check failed return max weight",
+			  __func__);
+		return softap_channel_free_weight_local;
+	}
+
+	rx_clear_count = channel_stat->rx_clear_count -
+			channel_stat->tx_frame_count -
+			channel_stat->rx_frame_count;
+	cycle_count = channel_stat->cycle_count;
+
+	/* LSH 4, otherwise it is always 0. */
+	channel_free_weight = (cycle_count == 0) ? 0 :
+			 (ACS_WEIGHT_COMPUTE(
+			  sap_ctx->auto_channel_select_weight,
+			  softap_channel_free_weight_cfg,
+			 ((rx_clear_count << 8) +
+			 (cycle_count >> 1))/cycle_count -
+			 (SOFTAP_MIN_CHNFREE << 8),
+			 (SOFTAP_MAX_CHNFREE -
+			 SOFTAP_MIN_CHNFREE) << 8));
+
+	if (channel_free_weight > softap_channel_free_weight_local)
+		channel_free_weight = softap_channel_free_weight_local;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
+		  __func__, rx_clear_count, cycle_count,
+		 channel_stat->tx_frame_count,
+		 channel_stat->rx_frame_count,
+		  softap_channel_free_weight_cfg,
+		  softap_channel_free_weight_local,
+		  channel_free_weight);
+
+	return channel_free_weight;
+}
+
+/**
+ * sap_weight_channel_txpwr_range() - compute channel tx power range weight
+ * @sap_ctx:  sap context
+ * @chn_stat: Pointer to chan status info
+ *
+ * Return: tx power range weight
+ */
+static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
+					       struct lim_channel_status
+					       *channel_stat)
+{
+	uint32_t     txpwr_weight_low_speed;
+	uint8_t      softap_txpwr_range_weight_cfg;
+	uint8_t      softap_txpwr_range_weight_local;
+
+	softap_txpwr_range_weight_cfg =
+	    ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
+	    (sap_ctx->auto_channel_select_weight);
+
+	softap_txpwr_range_weight_local =
+	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
+				    softap_txpwr_range_weight_cfg);
+
+	if (channel_stat == NULL || channel_stat->channelfreq == 0) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			  "In %s, sanity check failed return max weight",
+			  __func__);
+		return softap_txpwr_range_weight_local;
+	}
+
+	txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
+				(ACS_WEIGHT_COMPUTE(
+				 sap_ctx->auto_channel_select_weight,
+				 softap_txpwr_range_weight_cfg,
+				 SOFTAP_MAX_TXPWR -
+				 channel_stat->chan_tx_pwr_range,
+				 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
+
+	if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
+		txpwr_weight_low_speed = softap_txpwr_range_weight_local;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
+		  __func__, channel_stat->chan_tx_pwr_range,
+		  softap_txpwr_range_weight_cfg,
+		  softap_txpwr_range_weight_local,
+		  txpwr_weight_low_speed);
+
+	return txpwr_weight_low_speed;
+}
+
+/**
+ * sap_weight_channel_txpwr_tput() - compute channel tx power
+ * throughput weight
+ * @sap_ctx:  sap context
+ * @chn_stat: Pointer to chan status info
+ *
+ * Return: tx power throughput weight
+ */
+static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
+					      struct lim_channel_status
+					      *channel_stat)
+{
+	uint32_t     txpwr_weight_high_speed;
+	uint8_t      softap_txpwr_tput_weight_cfg;
+	uint8_t      softap_txpwr_tput_weight_local;
+
+	softap_txpwr_tput_weight_cfg =
+	    ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
+	    (sap_ctx->auto_channel_select_weight);
+
+	softap_txpwr_tput_weight_local =
+	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
+				    softap_txpwr_tput_weight_cfg);
+
+	if (channel_stat == NULL || channel_stat->channelfreq == 0) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			  "In %s, sanity check failed return max weight",
+			  __func__);
+		return softap_txpwr_tput_weight_local;
+	}
+
+	txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
+				  ? 0 : (ACS_WEIGHT_COMPUTE(
+				  sap_ctx->auto_channel_select_weight,
+				  softap_txpwr_tput_weight_cfg,
+				  SOFTAP_MAX_TXPWR -
+				  channel_stat->chan_tx_pwr_throughput,
+				  SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
+
+	if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
+		txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
+		  __func__, channel_stat->chan_tx_pwr_throughput,
+		  softap_txpwr_tput_weight_cfg,
+		  softap_txpwr_tput_weight_local,
+		  txpwr_weight_high_speed);
+
+	return txpwr_weight_high_speed;
+}
+
+/**
+ * sap_weight_channel_status() - compute chan status weight
+ * @sap_ctx:  sap context
+ * @chn_stat: Pointer to chan status info
+ *
+ * Return: chan status weight
+ */
+static
+uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
+				   struct lim_channel_status *channel_stat)
+{
+	return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
+	       sap_weight_channel_free(sap_ctx, channel_stat) +
+	       sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
+	       sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
+}
+
+/**
+ * sap_check_channels_same_band() - Check if two channels belong to same band
+ * @ch_num1: channel number
+ * @ch_num2: channel number
+ *
+ * Return: true if both channels belong to same band else false
+ */
+static bool sap_check_channels_same_band(uint16_t ch_num1, uint16_t ch_num2)
+{
+	if ((ch_num1 <= SIR_11B_CHANNEL_END &&
+	     ch_num2 <= SIR_11B_CHANNEL_END) ||
+	    (ch_num1 >= SIR_11A_CHANNEL_BEGIN &&
+	     ch_num2 >= SIR_11A_CHANNEL_BEGIN))
+		return true;
+
+	return false;
+}
+
+/**
+ * sap_update_rssi_bsscount() - updates bss count and rssi effect.
+ *
+ * @pSpectCh:     Channel Information
+ * @offset:       Channel Offset
+ * @sap_24g:      Channel is in 2.4G or 5G
+ * @spectch_start: the start of spect ch array
+ * @spectch_end: the end of spect ch array
+ *
+ * sap_update_rssi_bsscount updates bss count and rssi effect based
+ * on the channel offset.
+ *
+ * Return: None.
+ */
+
+static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
+	bool sap_24g, tSapSpectChInfo *spectch_start,
+	tSapSpectChInfo *spectch_end)
+{
+	tSapSpectChInfo *pExtSpectCh = NULL;
+	int32_t rssi, rsssi_effect;
+
+	pExtSpectCh = (pSpectCh + offset);
+	if (pExtSpectCh != NULL &&
+	    pExtSpectCh >= spectch_start &&
+	    pExtSpectCh < spectch_end) {
+		if (!sap_check_channels_same_band(pSpectCh->chNum,
+		    pExtSpectCh->chNum))
+			return;
+		++pExtSpectCh->bssCount;
+		switch (offset) {
+		case -1:
+		case 1:
+			rsssi_effect = sap_24g ?
+			    SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
+			    SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
+			break;
+		case -2:
+		case 2:
+			rsssi_effect = sap_24g ?
+			    SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
+			    SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
+			break;
+		case -3:
+		case 3:
+			rsssi_effect = sap_24g ?
+			    SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
+			    SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
+			break;
+		case -4:
+		case 4:
+			rsssi_effect = sap_24g ?
+			    SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
+			    SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
+			break;
+		case -5:
+		case 5:
+			rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
+			break;
+		case -6:
+		case 6:
+			rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
+			break;
+		case -7:
+		case 7:
+			rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
+			break;
+		default:
+			rsssi_effect = 0;
+			break;
+		}
+
+		rssi = pSpectCh->rssiAgr + rsssi_effect;
+		if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
+			pExtSpectCh->rssiAgr = rssi;
+		if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+			pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+	}
+}
+
+/**
+ * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
+ *                              updates channel parameters obtained from Beacon
+ * @pBeaconStruct Beacon strucutre populated by parse_beacon function
+ * @channelWidth Channel width
+ * @secondaryChannelOffset Secondary Channel Offset
+ * @vhtSupport If channel supports VHT
+ * @centerFreq Central frequency for the given channel.
+ *
+ * sap_upd_chan_spec_params updates the spectrum channels based on the
+ * pBeaconStruct obtained from Beacon IE
+ *
+ * Return: NA.
+ */
+
+static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
+				     uint16_t *channelWidth,
+				     uint16_t *secondaryChannelOffset,
+				     uint16_t *vhtSupport,
+				     uint16_t *centerFreq,
+				     uint16_t *centerFreq_2)
+{
+	if (NULL == pBeaconStruct) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("pBeaconStruct is NULL"));
+		return;
+	}
+
+	if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
+		*channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
+		*secondaryChannelOffset =
+			pBeaconStruct->HTInfo.secondaryChannelOffset;
+		if (!pBeaconStruct->VHTOperation.present)
+			return;
+		*vhtSupport = pBeaconStruct->VHTOperation.present;
+		if (pBeaconStruct->VHTOperation.chanWidth) {
+			*centerFreq =
+				pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
+			*centerFreq_2 =
+				pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
+			 /*
+			  * LHS follows tSirMacHTChannelWidth, while RHS follows
+			  * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
+			  * adjustment
+			  */
+			*channelWidth =
+				pBeaconStruct->VHTOperation.chanWidth + 1;
+
+		}
+	}
+}
+
+/**
+ * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
+ *
+ * @spect_ch:     Channel Information
+ * @offset:       Channel Offset
+ * @num_ch:       no.of channels
+ * @spectch_start: the start of spect ch array
+ * @spectch_end: the end of spect ch array
+ *
+ * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
+ * on the channel offset.
+ *
+ * Return: None.
+ */
+
+static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
+					    int32_t offset,
+					    uint16_t num_ch,
+					    tSapSpectChInfo *spectch_start,
+					    tSapSpectChInfo *spectch_end)
+{
+	int32_t ch_offset;
+	uint16_t i, cnt;
+
+	if (!offset)
+		return;
+	if (offset > 0)
+		cnt = num_ch;
+	else
+		cnt = num_ch + 1;
+	for (i = 0; i < cnt; i++) {
+		ch_offset = offset + i;
+		if (ch_offset == 0)
+			continue;
+		sap_update_rssi_bsscount(spect_ch, ch_offset, false,
+			spectch_start, spectch_end);
+	}
+}
+/**
+ * sap_interference_rssi_count_5G() - sap_interference_rssi_count
+ *                                    considers the Adjacent channel rssi and
+ *                                    data count(here number of BSS observed)
+ * @spect_ch:        Channel Information
+ * @chan_width:      Channel width parsed from beacon IE
+ * @sec_chan_offset: Secondary Channel Offset
+ * @center_freq:     Central frequency for the given channel.
+ * @channel_id:      channel_id
+ * @spectch_start: the start of spect ch array
+ * @spectch_end: the end of spect ch array
+ *
+ * sap_interference_rssi_count_5G considers the Adjacent channel rssi
+ * and data count(here number of BSS observed)
+ *
+ * Return: NA.
+ */
+
+static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
+					   uint16_t chan_width,
+					   uint16_t sec_chan_offset,
+					   uint16_t center_freq,
+					   uint16_t center_freq_2,
+					   uint8_t channel_id,
+					   tSapSpectChInfo *spectch_start,
+					   tSapSpectChInfo *spectch_end)
+{
+	uint16_t num_ch;
+	int32_t offset = 0;
+
+	if (NULL == spect_ch) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("spect_ch is NULL"));
+		return;
+	}
+
+	/* Updating the received ChannelWidth */
+	if (spect_ch->channelWidth != chan_width)
+		spect_ch->channelWidth = chan_width;
+	/* If received ChannelWidth is other than HT20,
+	 * we need to update the extension channel Params as well
+	 * chan_width == 0, HT20
+	 * chan_width == 1, HT40
+	 * chan_width == 2, VHT80
+	 * chan_width == 3, VHT160
+	 */
+
+	switch (spect_ch->channelWidth) {
+	case eHT_CHANNEL_WIDTH_40MHZ:   /* HT40 */
+		switch (sec_chan_offset) {
+		/* Above the Primary Channel */
+		case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+			sap_update_rssi_bsscount(spect_ch, 1, false,
+				spectch_start, spectch_end);
+			return;
+
+		/* Below the Primary channel */
+		case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+			sap_update_rssi_bsscount(spect_ch, -1, false,
+				spectch_start, spectch_end);
+			return;
+		}
+		return;
+	case eHT_CHANNEL_WIDTH_80MHZ:   /* VHT80 */
+		num_ch = 3;
+		if ((center_freq - channel_id) == 6) {
+			offset = 1;
+		} else if ((center_freq - channel_id) == 2) {
+			offset = -1;
+		} else if ((center_freq - channel_id) == -2) {
+			offset = -2;
+		} else if ((center_freq - channel_id) == -6) {
+			offset = -3;
+		}
+		break;
+	case eHT_CHANNEL_WIDTH_160MHZ:   /* VHT160 */
+		num_ch = 7;
+		if ((center_freq - channel_id) == 14)
+			offset = 1;
+		else if ((center_freq - channel_id) == 10)
+			offset = -1;
+		else if ((center_freq - channel_id) == 6)
+			offset = -2;
+		else if ((center_freq - channel_id) == 2)
+			offset = -3;
+		else if ((center_freq - channel_id) == -2)
+			offset = -4;
+		else if ((center_freq - channel_id) == -6)
+			offset = -5;
+		else if ((center_freq - channel_id) == -10)
+			offset = -6;
+		else if ((center_freq - channel_id) == -14)
+			offset = -7;
+		break;
+	default:
+		return;
+	}
+	sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
+		spectch_start, spectch_end);
+}
+
+/**
+ * sap_interference_rssi_count() - sap_interference_rssi_count
+ *                                 considers the Adjacent channel rssi
+ *                                 and data count(here number of BSS observed)
+ * @spect_ch    Channel Information
+ * @spectch_start: the start of spect ch array
+ * @spectch_end: the end of spect ch array
+ *
+ * sap_interference_rssi_count considers the Adjacent channel rssi
+ * and data count(here number of BSS observed)
+ *
+ * Return: None.
+ */
+
+static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
+	tSapSpectChInfo *spectch_start,
+	tSapSpectChInfo *spectch_end)
+{
+	if (NULL == spect_ch) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: spect_ch is NULL", __func__);
+		return;
+	}
+
+	switch (spect_ch->chNum) {
+	case CHANNEL_1:
+		sap_update_rssi_bsscount(spect_ch, 1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 3, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 4, true,
+			spectch_start, spectch_end);
+		break;
+
+	case CHANNEL_2:
+		sap_update_rssi_bsscount(spect_ch, -1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 3, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 4, true,
+			spectch_start, spectch_end);
+		break;
+	case CHANNEL_3:
+		sap_update_rssi_bsscount(spect_ch, -2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 3, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 4, true,
+			spectch_start, spectch_end);
+		break;
+	case CHANNEL_4:
+		sap_update_rssi_bsscount(spect_ch, -3, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 3, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 4, true,
+			spectch_start, spectch_end);
+		break;
+
+	case CHANNEL_5:
+	case CHANNEL_6:
+	case CHANNEL_7:
+	case CHANNEL_8:
+	case CHANNEL_9:
+	case CHANNEL_10:
+		sap_update_rssi_bsscount(spect_ch, -4, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -3, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 3, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 4, true,
+			spectch_start, spectch_end);
+		break;
+
+	case CHANNEL_11:
+		sap_update_rssi_bsscount(spect_ch, -4, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -3, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 3, true,
+			spectch_start, spectch_end);
+		break;
+
+	case CHANNEL_12:
+		sap_update_rssi_bsscount(spect_ch, -4, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -3, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 2, true,
+			spectch_start, spectch_end);
+		break;
+
+	case CHANNEL_13:
+		sap_update_rssi_bsscount(spect_ch, -4, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -3, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -1, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, 1, true,
+			spectch_start, spectch_end);
+		break;
+
+	case CHANNEL_14:
+		sap_update_rssi_bsscount(spect_ch, -4, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -3, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -2, true,
+			spectch_start, spectch_end);
+		sap_update_rssi_bsscount(spect_ch, -1, true,
+			spectch_start, spectch_end);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/**
+ * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
+ * @sap_ctx: SAP context which contains the current PCL
+ * @channel: Input channel number to be checked
+ *
+ * Check if a channel is in the preferred channel list
+ *
+ * Return:
+ *   true:    channel is in PCL,
+ *   false:   channel is not in PCL
+ */
+static bool ch_in_pcl(struct sap_context *sap_ctx, uint8_t channel)
+{
+	uint32_t i;
+
+	for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
+		if (channel == sap_ctx->acs_cfg->pcl_channels[i])
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * sap_compute_spect_weight() - Compute spectrum weight
+ * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
+ * @halHandle: Pointer to HAL handle
+ * @pResult: Pointer to tScanResultHandle
+ * @sap_ctx: Context of the SAP
+ *
+ * Main function for computing the weight of each channel in the
+ * spectrum based on the RSSI value of the BSSes on the channel
+ * and number of BSS
+ */
+static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
+				     tHalHandle halHandle,
+				     tScanResultHandle pResult,
+				     struct sap_context *sap_ctx)
+{
+	int8_t rssi = 0;
+	uint8_t chn_num = 0;
+	uint8_t channel_id = 0;
+	tCsrScanResultInfo *pScanResult;
+	tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
+	uint32_t operatingBand;
+	uint16_t channelWidth;
+	uint16_t secondaryChannelOffset;
+	uint16_t centerFreq;
+	uint8_t i;
+	bool found;
+	uint16_t centerFreq_2 = 0;
+	uint16_t vhtSupport;
+	uint32_t ieLen = 0;
+	tSirProbeRespBeacon *pBeaconStruct;
+	tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
+	tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
+	tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
+		pSpectInfoParams->numSpectChans;
+
+	pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
+	if (!pBeaconStruct)
+		return;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, Computing spectral weight", __func__);
+
+	/**
+	 * Soft AP specific channel weight calculation using DFS formula
+	 */
+	SET_ACS_BAND(operatingBand, sap_ctx);
+
+	pScanResult = sme_scan_result_get_first(halHandle, pResult);
+
+	while (pScanResult) {
+		pSpectCh = pSpectInfoParams->pSpectCh;
+		/* Defining the default values, so that any value will hold the default values */
+		channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
+		secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
+		vhtSupport = 0;
+		centerFreq = 0;
+
+
+		ieLen = GET_IE_LEN_IN_BSS(
+				pScanResult->BssDescriptor.length);
+		qdf_mem_set((uint8_t *) pBeaconStruct,
+				   sizeof(tSirProbeRespBeacon), 0);
+
+
+		if ((sir_parse_beacon_ie
+		     (pMac, pBeaconStruct, (uint8_t *)
+		      (pScanResult->BssDescriptor.ieFields),
+		      ieLen)) == QDF_STATUS_SUCCESS)
+			sap_upd_chan_spec_params(
+				pBeaconStruct,
+				&channelWidth,
+				&secondaryChannelOffset,
+				&vhtSupport, &centerFreq,
+				&centerFreq_2);
+
+		/* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
+		for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
+		     chn_num++) {
+
+			/*
+			 * If the Beacon has channel ID, use it other wise we
+			 * will rely on the channelIdSelf
+			 */
+			if (pScanResult->BssDescriptor.channelId == 0)
+				channel_id =
+				      pScanResult->BssDescriptor.channelIdSelf;
+			else
+				channel_id =
+				      pScanResult->BssDescriptor.channelId;
+
+			if (pSpectCh && (channel_id == pSpectCh->chNum)) {
+				if (pSpectCh->rssiAgr <
+				    pScanResult->BssDescriptor.rssi)
+					pSpectCh->rssiAgr =
+						pScanResult->BssDescriptor.rssi;
+
+				++pSpectCh->bssCount;   /* Increment the count of BSS */
+
+				/*
+				 * Connsidering the Extension Channel
+				 * only in a channels
+				 */
+				switch (operatingBand) {
+				case eCSR_DOT11_MODE_11a:
+					sap_interference_rssi_count_5G(
+					    pSpectCh, channelWidth,
+					    secondaryChannelOffset,
+					    centerFreq,
+					    centerFreq_2,
+					    channel_id,
+					    spectch_start,
+					    spectch_end);
+					break;
+
+				case eCSR_DOT11_MODE_11g:
+					sap_interference_rssi_count(pSpectCh,
+						spectch_start, spectch_end);
+					break;
+
+				case eCSR_DOT11_MODE_abg:
+					if (pSpectCh->chNum >=
+					    SIR_11A_CHANNEL_BEGIN)
+						sap_interference_rssi_count_5G(
+						    pSpectCh, channelWidth,
+						    secondaryChannelOffset,
+						    centerFreq,
+						    centerFreq_2,
+						    channel_id,
+						    spectch_start,
+						    spectch_end);
+					else
+						sap_interference_rssi_count(
+						    pSpectCh,
+						    spectch_start,
+						    spectch_end);
+					break;
+				}
+
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO_HIGH,
+					  "In %s, bssdes.ch_self=%d, bssdes.ch_ID=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, pScanResult=%pK, ChannelWidth %d, secondaryChanOffset %d, center frequency %d",
+					  __func__,
+					  pScanResult->BssDescriptor.
+					  channelIdSelf,
+					  pScanResult->BssDescriptor.channelId,
+					  pScanResult->BssDescriptor.rssi,
+					  pSpectCh->bssCount, pScanResult,
+					  pSpectCh->channelWidth,
+					  secondaryChannelOffset, centerFreq);
+				pSpectCh++;
+				break;
+			} else {
+				pSpectCh++;
+			}
+		}
+
+		pScanResult = sme_scan_result_get_next(halHandle, pResult);
+	}
+
+	/* Calculate the weights for all channels in the spectrum pSpectCh */
+	pSpectCh = pSpectInfoParams->pSpectCh;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, Spectrum Channels Weight", __func__);
+
+	for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
+	     chn_num++) {
+
+		/*
+		   rssi : Maximum received signal strength among all BSS on that channel
+		   bssCount : Number of BSS on that channel
+		 */
+
+		rssi = (int8_t) pSpectCh->rssiAgr;
+		if (ch_in_pcl(sap_ctx, pSpectCh->chNum))
+			rssi -= PCL_RSSI_DISCOUNT;
+
+		if (rssi < SOFTAP_MIN_RSSI)
+			rssi = SOFTAP_MIN_RSSI;
+
+		if (pSpectCh->weight == SAP_ACS_WEIGHT_MAX) {
+			pSpectCh->weight_copy = pSpectCh->weight;
+			goto debug_info;
+		}
+
+		/* There may be channels in scanlist, which were not sent to
+		 * FW for scanning as part of ACS scan list, but they do have an
+		 * effect on the neighbouring channels, so they help to find a
+		 * suitable channel, but there weight should be max as they were
+		 * and not meant to be included in the ACS scan results.
+		 * So just assign RSSI as -100, bsscount as 0, and weight as max
+		 * to them, so that they always stay low in sorting of best
+		 * channles which were included in ACS scan list
+		 */
+		found = false;
+		for (i = 0; i < sap_ctx->num_of_channel; i++) {
+			if (pSpectCh->chNum == sap_ctx->channelList[i]) {
+			/* Scan channel was included in ACS scan list */
+				found = true;
+				break;
+			}
+		}
+
+		if (found)
+			pSpectCh->weight =
+				SAPDFS_NORMALISE_1000 *
+				(sapweight_rssi_count(sap_ctx, rssi,
+				pSpectCh->bssCount) + sap_weight_channel_status(
+				sap_ctx, sap_get_channel_status(pMac,
+							 pSpectCh->chNum)));
+		else {
+			pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
+			pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+			rssi = SOFTAP_MIN_RSSI;
+			pSpectCh->bssCount = SOFTAP_MIN_COUNT;
+		}
+
+		if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX)
+			pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
+		pSpectCh->weight_copy = pSpectCh->weight;
+
+debug_info:
+		/* ------ Debug Info ------ */
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "In %s, Chan=%d Weight= %d rssiAgr=%d rssi_pcl_discount: %d bssCount=%d",
+			  __func__, pSpectCh->chNum, pSpectCh->weight,
+			  pSpectCh->rssiAgr, rssi, pSpectCh->bssCount);
+		host_log_acs_chan_spect_weight(pSpectCh->chNum,
+					  (uint16_t)pSpectCh->weight,
+					  pSpectCh->rssiAgr,
+					  pSpectCh->bssCount);
+		/* ------ Debug Info ------ */
+		pSpectCh++;
+	}
+	sap_clear_channel_status(pMac);
+	qdf_mem_free(pBeaconStruct);
+}
+
+/*==========================================================================
+   FUNCTION    sap_chan_sel_exit
+
+   DESCRIPTION
+    Exit function for free out the allocated memory, to be called
+    at the end of the dfsSelectChannel function
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    pSpectInfoParams       : Pointer to the tSapChSelSpectInfo structure
+
+   RETURN VALUE
+    void     : NULL
+
+   SIDE EFFECTS
+   ============================================================================*/
+static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
+{
+	/* Free all the allocated memory */
+	qdf_mem_free(pSpectInfoParams->pSpectCh);
+}
+
+/*==========================================================================
+   FUNCTION    sap_sort_chl_weight
+
+   DESCRIPTION
+    Function to sort the channels with the least weight first for 20MHz channels
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    pSpectInfoParams       : Pointer to the tSapChSelSpectInfo structure
+
+   RETURN VALUE
+    void     : NULL
+
+   SIDE EFFECTS
+   ============================================================================*/
+static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
+{
+	tSapSpectChInfo temp;
+
+	tSapSpectChInfo *pSpectCh = NULL;
+	uint32_t i = 0, j = 0, minWeightIndex = 0;
+
+	pSpectCh = pSpectInfoParams->pSpectCh;
+	for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
+		minWeightIndex = i;
+		for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
+			if (pSpectCh[j].weight <
+			    pSpectCh[minWeightIndex].weight) {
+				minWeightIndex = j;
+			} else if (pSpectCh[j].weight ==
+				   pSpectCh[minWeightIndex].weight) {
+				if (pSpectCh[j].bssCount <
+				    pSpectCh[minWeightIndex].bssCount)
+					minWeightIndex = j;
+			}
+		}
+		if (minWeightIndex != i) {
+			qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
+				     sizeof(*pSpectCh));
+			qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
+				     sizeof(*pSpectCh));
+			qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
+		}
+	}
+}
+
+/**
+ * set_ht80_chl_bit() - to set available channel to ht80 channel bitmap
+ * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
+ * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
+ *
+ * Return: none
+ */
+static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
+			tSapChSelSpectInfo *spec_info_params)
+{
+	uint8_t i, j;
+	tSapSpectChInfo *spec_info;
+	int start_channel = 0;
+
+	channel_bitmap->chanBondingSet[0].startChannel =
+			acs_ht80_channels[0].chStartNum;
+	channel_bitmap->chanBondingSet[1].startChannel =
+			acs_ht80_channels[1].chStartNum;
+	channel_bitmap->chanBondingSet[2].startChannel =
+			acs_ht80_channels[2].chStartNum;
+	channel_bitmap->chanBondingSet[3].startChannel =
+			acs_ht80_channels[3].chStartNum;
+	channel_bitmap->chanBondingSet[4].startChannel =
+			acs_ht80_channels[4].chStartNum;
+	channel_bitmap->chanBondingSet[5].startChannel =
+			acs_ht80_channels[5].chStartNum;
+
+	spec_info = spec_info_params->pSpectCh;
+	for (j = 0; j < spec_info_params->numSpectChans; j++) {
+		for (i = 0; i < MAX_80MHZ_BANDS; i++) {
+			start_channel =
+				channel_bitmap->chanBondingSet[i].startChannel;
+			if (spec_info[j].chNum >= start_channel &&
+				(spec_info[j].chNum <= start_channel + 12)) {
+				channel_bitmap->chanBondingSet[i].channelMap |=
+					1 << ((spec_info[j].chNum -
+						start_channel)/4);
+				break;
+			}
+		}
+	}
+}
+
+/**
+ * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
+ * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
+ *
+ * Function to sort the channels with the least weight first for HT80 channels
+ *
+ * Return: none
+ */
+static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
+{
+	uint8_t i, j, n;
+	tSapSpectChInfo *pSpectInfo;
+	uint8_t minIdx;
+	int start_channel = 0;
+	chan_bonding_bitmap *channel_bitmap;
+
+	channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
+	if (!channel_bitmap)
+		return;
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	/* for each HT80 channel, calculate the combined weight of the
+	   four 20MHz weight */
+	for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
+		for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+			if (pSpectInfo[j].chNum ==
+					acs_ht80_channels[i].chStartNum)
+				break;
+		}
+		if (j == pSpectInfoParams->numSpectChans)
+			continue;
+
+		if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
+			((pSpectInfo[j].chNum + 8) ==
+				 pSpectInfo[j + 2].chNum) &&
+			((pSpectInfo[j].chNum + 12) ==
+				 pSpectInfo[j + 3].chNum))) {
+			/*
+			 * some channels does not exist in pSectInfo array,
+			 * skip this channel and those in the same HT80 width
+			 */
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
+			if ((pSpectInfo[j].chNum + 4) ==
+					pSpectInfo[j + 1].chNum)
+				pSpectInfo[j + 1].weight =
+					SAP_ACS_WEIGHT_MAX * 4;
+			if ((pSpectInfo[j].chNum + 8) ==
+					pSpectInfo[j + 2].chNum)
+				pSpectInfo[j + 2].weight =
+					SAP_ACS_WEIGHT_MAX * 4;
+			if ((pSpectInfo[j].chNum + 12) ==
+					pSpectInfo[j + 3].chNum)
+				pSpectInfo[j + 3].weight =
+					SAP_ACS_WEIGHT_MAX * 4;
+			continue;
+		}
+		/*found the channel, add the 4 adjacent channels' weight */
+		acs_ht80_channels[i].weight = pSpectInfo[j].weight +
+			pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
+			pSpectInfo[j + 3].weight;
+		/* find best channel among 4 channels as the primary channel */
+		if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
+			(pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
+			/* lower 2 channels are better choice */
+			if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
+				minIdx = 0;
+			else
+				minIdx = 1;
+		} else if (pSpectInfo[j + 2].weight <=
+				pSpectInfo[j + 3].weight) {
+			/* upper 2 channels are better choice */
+			minIdx = 2;
+		} else {
+			minIdx = 3;
+		}
+
+		/*
+		 * set all 4 channels to max value first, then reset the
+		 * best channel as the selected primary channel, update its
+		 * weightage with the combined weight value
+		 */
+		for (n = 0; n < 4; n++)
+			pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
+
+		pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
+	}
+
+	/*
+	 * mark the weight of the channel that can't satisfy 80MHZ
+	 * as max value, so that it will be sorted to the bottom
+	 */
+	set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
+	for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+		for (i = 0; i < MAX_80MHZ_BANDS; i++) {
+			start_channel =
+				channel_bitmap->chanBondingSet[i].startChannel;
+			if (pSpectInfo[j].chNum >= start_channel &&
+				(pSpectInfo[j].chNum <=
+					start_channel + 12) &&
+				channel_bitmap->chanBondingSet[i].channelMap !=
+					SAP_80MHZ_MASK)
+				pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
+		}
+	}
+
+	/*
+	 * Assign max weight(SAP_ACS_WEIGHT_MAX * 4) to 2.4 Ghz channels
+	 * and channel 165 as they cannot be part of a 80Mhz channel bonding.
+	 */
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+		if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
+		     pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
+		    (CHANNEL_165 == pSpectInfo[j].chNum))
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
+	}
+
+	sap_sort_chl_weight(pSpectInfoParams);
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
+			pSpectInfo->chNum, pSpectInfo->weight,
+			pSpectInfo->rssiAgr, pSpectInfo->bssCount);
+		pSpectInfo++;
+	}
+	qdf_mem_free(channel_bitmap);
+}
+
+/**
+ * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
+ * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
+ *
+ * Function to sort the channels with the least weight first for VHT160 channels
+ *
+ * Return: none
+ */
+static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
+{
+	uint8_t i, j, n, idx;
+	tSapSpectChInfo *pSpectInfo;
+	uint8_t minIdx;
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	/* for each VHT160 channel, calculate the combined weight of the
+	   8 20MHz weight */
+	for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
+		for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+			if (pSpectInfo[j].chNum ==
+					acs_vht160_channels[i].chStartNum)
+				break;
+		}
+		if (j == pSpectInfoParams->numSpectChans)
+			continue;
+
+		if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
+			((pSpectInfo[j].chNum + 8) ==
+				 pSpectInfo[j + 2].chNum) &&
+			((pSpectInfo[j].chNum + 12) ==
+				 pSpectInfo[j + 3].chNum) &&
+			((pSpectInfo[j].chNum + 16) ==
+				 pSpectInfo[j + 4].chNum) &&
+			((pSpectInfo[j].chNum + 20) ==
+				 pSpectInfo[j + 5].chNum) &&
+			((pSpectInfo[j].chNum + 24) ==
+				 pSpectInfo[j + 6].chNum) &&
+			((pSpectInfo[j].chNum + 28) ==
+				 pSpectInfo[j + 7].chNum))) {
+			/*
+			 * some channels does not exist in pSectInfo array,
+			 * skip this channel and those in the same VHT160 width
+			 */
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
+			if ((pSpectInfo[j].chNum + 4) ==
+					pSpectInfo[j + 1].chNum)
+				pSpectInfo[j + 1].weight =
+					SAP_ACS_WEIGHT_MAX * 8;
+			if ((pSpectInfo[j].chNum + 8) ==
+					pSpectInfo[j + 2].chNum)
+				pSpectInfo[j + 2].weight =
+					SAP_ACS_WEIGHT_MAX * 8;
+			if ((pSpectInfo[j].chNum + 12) ==
+					pSpectInfo[j + 3].chNum)
+				pSpectInfo[j + 3].weight =
+					SAP_ACS_WEIGHT_MAX * 8;
+			if ((pSpectInfo[j].chNum + 16) ==
+					pSpectInfo[j + 4].chNum)
+				pSpectInfo[j + 4].weight =
+					SAP_ACS_WEIGHT_MAX * 8;
+			if ((pSpectInfo[j].chNum + 20) ==
+					pSpectInfo[j + 5].chNum)
+				pSpectInfo[j + 5].weight =
+					SAP_ACS_WEIGHT_MAX * 8;
+			if ((pSpectInfo[j].chNum + 24) ==
+					pSpectInfo[j + 6].chNum)
+				pSpectInfo[j + 6].weight =
+					SAP_ACS_WEIGHT_MAX * 8;
+			if ((pSpectInfo[j].chNum + 28) ==
+					pSpectInfo[j + 7].chNum)
+				pSpectInfo[j + 7].weight =
+					SAP_ACS_WEIGHT_MAX * 8;
+			continue;
+		}
+		/*found the channel, add the 7 adjacent channels' weight */
+		acs_vht160_channels[i].weight = pSpectInfo[j].weight +
+			pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
+			pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
+			pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
+			pSpectInfo[j + 7].weight;
+
+		/* find best channel among 8 channels as the primary channel */
+		if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
+			pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
+			(pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
+			pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
+			idx = 4;
+		else
+			idx = 0;
+		/* find best channel among 4 channels as the primary channel */
+		if ((pSpectInfo[j + idx].weight +
+					pSpectInfo[j + idx + 1].weight) <
+			(pSpectInfo[j + idx + 2].weight +
+			 pSpectInfo[j + idx + 3].weight)) {
+			/* lower 2 channels are better choice */
+			if (pSpectInfo[j + idx].weight <
+					pSpectInfo[j + idx + 1].weight)
+				minIdx = 0 + idx;
+			else
+				minIdx = 1 + idx;
+		} else if (pSpectInfo[j + idx + 2].weight <=
+				pSpectInfo[j + idx + 3].weight) {
+			/* upper 2 channels are better choice */
+			minIdx = 2 + idx;
+		} else {
+			minIdx = 3 + idx;
+		}
+
+		/*
+		 * set all 8 channels to max value first, then reset the
+		 * best channel as the selected primary channel, update its
+		 * weightage with the combined weight value
+		 */
+		for (n = 0; n < 8; n++)
+			pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
+
+		pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
+	}
+
+	/*
+	 * Assign max weight(SAP_ACS_WEIGHT_MAX * 8) to 2.4 Ghz channels
+	 * and channel 132-173 as they cannot be part of a 160Mhz channel
+	 * bonding.
+	 */
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+		if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
+		     pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
+		    (pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_132) &&
+		     pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
+	}
+
+	sap_sort_chl_weight(pSpectInfoParams);
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
+			pSpectInfo->chNum, pSpectInfo->weight,
+			pSpectInfo->rssiAgr, pSpectInfo->bssCount);
+		pSpectInfo++;
+	}
+}
+
+/**
+ * sap_allocate_max_weight_ht40_24_g() - allocate max weight for 40Mhz
+ *                                       to all 2.4Ghz channels
+ * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
+ *
+ * Return: none
+ */
+static void sap_allocate_max_weight_ht40_24_g(
+			tSapChSelSpectInfo *spect_info_params)
+{
+	tSapSpectChInfo *spect_info;
+	uint8_t j;
+
+	/*
+	 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
+	 * 2.4 Ghz channels
+	 */
+	spect_info = spect_info_params->pSpectCh;
+	for (j = 0; j < spect_info_params->numSpectChans; j++) {
+		if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
+		     spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)))
+			spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+	}
+}
+
+/**
+ * sap_allocate_max_weight_ht40_5_g() - allocate max weight for 40Mhz
+ *                                      to all 5Ghz channels
+ * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
+ *
+ * Return: none
+ */
+static void sap_allocate_max_weight_ht40_5_g(
+			tSapChSelSpectInfo *spect_info_params)
+{
+	tSapSpectChInfo *spect_info;
+	uint8_t j;
+
+	/*
+	 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
+	 * 5 Ghz channels
+	 */
+	spect_info = spect_info_params->pSpectCh;
+	for (j = 0; j < spect_info_params->numSpectChans; j++) {
+		if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
+		     spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
+			spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+	}
+}
+
+/**
+ * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
+ * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
+ *
+ * Function to sort the channels with the least weight first for HT40 channels
+ *
+ * Return: none
+ */
+static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
+		v_REGDOMAIN_t domain)
+{
+	uint8_t i, j;
+	tSapSpectChInfo *pSpectInfo;
+	uint32_t tmpWeight1, tmpWeight2;
+	uint32_t ht40plus2gendch = 0;
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	/*
+	 * for each HT40 channel, calculate the combined weight of the
+	 * two 20MHz weight
+	 */
+	for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
+		for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+			if (pSpectInfo[j].chNum ==
+				acs_ht40_channels24_g[i].chStartNum)
+				break;
+		}
+		if (j == pSpectInfoParams->numSpectChans)
+			continue;
+
+		if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+			continue;
+		}
+		/*
+		 * check if there is another channel combination possiblity
+		 * e.g., {1, 5} & {5, 9}
+		 */
+		if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
+			/* need to compare two channel pairs */
+			tmpWeight1 = pSpectInfo[j].weight +
+						pSpectInfo[j + 4].weight;
+			tmpWeight2 = pSpectInfo[j + 4].weight +
+						pSpectInfo[j + 8].weight;
+			if (tmpWeight1 <= tmpWeight2) {
+				if (pSpectInfo[j].weight <=
+						pSpectInfo[j + 4].weight) {
+					pSpectInfo[j].weight =
+						tmpWeight1;
+					pSpectInfo[j + 4].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+					pSpectInfo[j + 8].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+				} else {
+					pSpectInfo[j + 4].weight =
+						tmpWeight1;
+					/* for secondary channel selection */
+					pSpectInfo[j].weight =
+						SAP_ACS_WEIGHT_MAX * 2
+						- 1;
+					pSpectInfo[j + 8].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+				}
+			} else {
+				if (pSpectInfo[j + 4].weight <=
+						pSpectInfo[j + 8].weight) {
+					pSpectInfo[j + 4].weight =
+						tmpWeight2;
+					pSpectInfo[j].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+					/* for secondary channel selection */
+					pSpectInfo[j + 8].weight =
+						SAP_ACS_WEIGHT_MAX * 2
+						- 1;
+				} else {
+					pSpectInfo[j + 8].weight =
+						tmpWeight2;
+					pSpectInfo[j].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+					pSpectInfo[j + 4].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+				}
+			}
+		} else {
+			tmpWeight1 = pSpectInfo[j].weight_copy +
+						pSpectInfo[j + 4].weight_copy;
+			if (pSpectInfo[j].weight_copy <=
+					pSpectInfo[j + 4].weight_copy) {
+				pSpectInfo[j].weight = tmpWeight1;
+				pSpectInfo[j + 4].weight =
+					SAP_ACS_WEIGHT_MAX * 2;
+			} else {
+				pSpectInfo[j + 4].weight = tmpWeight1;
+				pSpectInfo[j].weight =
+					SAP_ACS_WEIGHT_MAX * 2;
+			}
+		}
+	}
+	/*
+	 * Every channel should be checked. Add the check for the omissive
+	 * channel. Mark the channel whose combination can't satisfy 40MHZ
+	 * as max value, so that it will be sorted to the bottom.
+	 */
+	if (REGDOMAIN_FCC == domain)
+		ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
+	else
+		ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
+	for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
+		for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+			if (pSpectInfo[j].chNum == i &&
+				((pSpectInfo[j].chNum + 4) !=
+					pSpectInfo[j+4].chNum) &&
+				((pSpectInfo[j].chNum - 4) !=
+					pSpectInfo[j-4].chNum))
+				pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+		}
+	}
+	for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
+		for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+			if (pSpectInfo[j].chNum == i &&
+				(pSpectInfo[j].chNum - 4) !=
+					pSpectInfo[j-4].chNum)
+				pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+		}
+	}
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
+			  __func__, pSpectInfo->chNum, pSpectInfo->weight,
+			  pSpectInfo->rssiAgr, pSpectInfo->bssCount);
+		pSpectInfo++;
+	}
+
+	sap_sort_chl_weight(pSpectInfoParams);
+}
+
+/*==========================================================================
+   FUNCTION    sap_sort_chl_weight_ht40_5_g
+
+   DESCRIPTION
+    Function to sort the channels with the least weight first for HT40 channels
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    pSpectInfoParams       : Pointer to the tSapChSelSpectInfo structure
+
+   RETURN VALUE
+    void     : NULL
+
+   SIDE EFFECTS
+   ============================================================================*/
+static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
+{
+	uint8_t i, j;
+	tSapSpectChInfo *pSpectInfo;
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	/*for each HT40 channel, calculate the combined weight of the
+	   two 20MHz weight */
+	for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
+		for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+			if (pSpectInfo[j].chNum ==
+			    acs_ht40_channels5_g[i].chStartNum)
+				break;
+		}
+		if (j == pSpectInfoParams->numSpectChans)
+			continue;
+
+		/* found the channel, add the two adjacent channels' weight */
+		if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
+			acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
+						      pSpectInfo[j + 1].weight;
+			/* select better of the adjact channel as the primary channel */
+			if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
+				pSpectInfo[j].weight =
+					acs_ht40_channels5_g[i].weight;
+				/* mark the adjacent channel's weight as max value so
+				   that it will be sorted to the bottom */
+				pSpectInfo[j + 1].weight =
+					SAP_ACS_WEIGHT_MAX * 2;
+			} else {
+				pSpectInfo[j + 1].weight =
+					acs_ht40_channels5_g[i].weight;
+				/* mark the adjacent channel's weight as max value so
+				   that it will be sorted to the bottom */
+				pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+			}
+
+		} else
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+	}
+
+	/*
+	 *Every channel should be checked. Add the check for the omissive
+	 * channel. Mark the channel whose combination can't satisfy 40MHZ
+	 * as max value, so that it will be sorted to the bottom
+	 */
+	for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
+		for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
+			if (pSpectInfo[j].chNum ==
+					(acs_ht40_channels5_g[i].chStartNum +
+						4) &&
+				pSpectInfo[j - 1].chNum !=
+					acs_ht40_channels5_g[i].chStartNum) {
+				pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+				break;
+			}
+		}
+	}
+	/* avoid channel 165 by setting its weight to max */
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+		if (CHANNEL_165 == pSpectInfo[j].chNum) {
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+			break;
+		}
+	}
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
+			  __func__, pSpectInfo->chNum, pSpectInfo->weight,
+			  pSpectInfo->rssiAgr, pSpectInfo->bssCount);
+		pSpectInfo++;
+	}
+
+	sap_sort_chl_weight(pSpectInfoParams);
+}
+
+/*==========================================================================
+   FUNCTION    sap_sort_chl_weight_all
+
+   DESCRIPTION
+    Function to sort the channels with the least weight first
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    sap_ctx                : Pointer to the struct sap_context *structure
+    pSpectInfoParams       : Pointer to the tSapChSelSpectInfo structure
+
+   RETURN VALUE
+    void     : NULL
+
+   SIDE EFFECTS
+   ============================================================================*/
+static void sap_sort_chl_weight_all(struct sap_context *sap_ctx,
+				    tSapChSelSpectInfo *pSpectInfoParams,
+				    uint32_t operatingBand,
+				    v_REGDOMAIN_t domain)
+{
+	tSapSpectChInfo *pSpectCh = NULL;
+	uint32_t j = 0;
+#ifndef SOFTAP_CHANNEL_RANGE
+	uint32_t i = 0;
+#endif
+
+	pSpectCh = pSpectInfoParams->pSpectCh;
+#ifdef SOFTAP_CHANNEL_RANGE
+
+	switch (sap_ctx->acs_cfg->ch_width) {
+	case CH_WIDTH_40MHZ:
+		/*
+		 * Assign max weight to all 5Ghz channels when operating band
+		 * is 11g and to all 2.4Ghz channels when operating band is 11a
+		 * or 11abg to avoid selection in ACS algorithm for starting SAP
+		 */
+		if (eCSR_DOT11_MODE_11g == operatingBand) {
+			sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
+			sap_allocate_max_weight_ht40_5_g(pSpectInfoParams);
+		} else {
+			sap_allocate_max_weight_ht40_24_g(pSpectInfoParams);
+			sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
+		}
+		break;
+	case CH_WIDTH_80MHZ:
+	case CH_WIDTH_80P80MHZ:
+		sap_sort_chl_weight_ht80(pSpectInfoParams);
+		break;
+	case CH_WIDTH_160MHZ:
+		sap_sort_chl_weight_vht160(pSpectInfoParams);
+		break;
+	case CH_WIDTH_20MHZ:
+	default:
+		/* Sorting the channels as per weights as 20MHz channels */
+		sap_sort_chl_weight(pSpectInfoParams);
+	}
+
+#else
+	/* Sorting the channels as per weights */
+	for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
+		minWeightIndex = i;
+		for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
+			if (pSpectCh[j].weight <
+			    pSpectCh[minWeightIndex].weight) {
+				minWeightIndex = j;
+			}
+		}
+		if (minWeightIndex != i) {
+			qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
+				     sizeof(*pSpectCh));
+			qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
+				     sizeof(*pSpectCh));
+			qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
+		}
+	}
+#endif
+
+	/* For testing */
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+		  "In %s, Sorted Spectrum Channels Weight", __func__);
+	pSpectCh = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			  "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
+			  __func__, pSpectCh->chNum, pSpectCh->weight,
+			  pSpectCh->rssiAgr, pSpectCh->bssCount);
+		pSpectCh++;
+	}
+
+}
+
+/**
+ * sap_is_ch_non_overlap() - returns true if non-overlapping channel
+ * @sap_ctx: Sap context
+ * @ch: channel number
+ *
+ * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
+ */
+static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
+{
+	if (sap_ctx->enableOverLapCh)
+		return true;
+
+	if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
+		return true;
+
+	return false;
+}
+
+#ifdef FEATURE_WLAN_CH_AVOID
+/**
+ * sap_select_channel_no_scan_result() - select SAP channel when no scan results
+ * are available.
+ * @sap_ctx: Sap context
+ *
+ * Returns: channel number if success, 0 otherwise
+ */
+static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
+						 struct sap_context *sap_ctx)
+{
+	enum channel_state ch_type;
+	uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
+	uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
+	uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
+	tpAniSirGlobal mac_ctx = NULL;
+
+	mac_ctx = PMAC_STRUCT(hal);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("start - end: %d - %d"), start_ch_num, end_ch_num);
+
+	/* get a channel in PCL and within the range */
+	for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
+		if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
+		    (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
+			continue;
+
+		first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
+		break;
+	}
+
+	if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
+		return first_safe_ch_in_range;
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		if ((safe_channels[i].channelNumber < start_ch_num) ||
+		    (safe_channels[i].channelNumber > end_ch_num))
+			continue;
+
+		ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
+				safe_channels[i].channelNumber);
+
+		if ((ch_type == CHANNEL_STATE_DISABLE) ||
+			(ch_type == CHANNEL_STATE_INVALID))
+			continue;
+		if ((!mac_ctx->mlme_cfg->dfs_cfg.dfs_master_capable) &&
+		    (CHANNEL_STATE_DFS == ch_type)) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				"%s: DFS master mode disabled. Skip DFS channel %d",
+				__func__, safe_channels[i].channelNumber);
+			continue;
+		}
+		if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
+		    (CHANNEL_STATE_DFS == ch_type))
+			continue;
+
+		if (safe_channels[i].isSafe == true) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				FL("channel %d in the configuration is safe"),
+				safe_channels[i].channelNumber);
+			first_safe_ch_in_range = safe_channels[i].channelNumber;
+			break;
+		}
+
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			FL("channel %d in the configuration is unsafe"),
+			safe_channels[i].channelNumber);
+	}
+
+	/* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
+	return first_safe_ch_in_range;
+}
+#else
+static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
+						 struct sap_context *sap_ctx)
+{
+	uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("start - end: %d - %d"),
+		  start_ch_num,
+		  sap_ctx->acs_cfg->end_ch);
+
+	sap_ctx->acs_cfg->pri_ch = start_ch_num;
+	sap_ctx->acs_cfg->ht_sec_ch = 0;
+
+	/* pick the first channel in configured range */
+	return start_ch_num;
+}
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+/**
+ * sap_select_channel() - select SAP channel
+ * @hal: Pointer to HAL handle
+ * @sap_ctx: Sap context
+ * @scan_result: Pointer to tScanResultHandle
+ *
+ * Runs a algorithm to select the best channel to operate in based on BSS
+ * rssi and bss count on each channel
+ *
+ * Returns: channel number if success, 0 otherwise
+ */
+uint8_t sap_select_channel(tHalHandle hal, struct sap_context *sap_ctx,
+			   tScanResultHandle scan_result)
+{
+	/* DFS param object holding all the data req by the algo */
+	tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
+	tSapChSelSpectInfo *spect_info = &spect_info_obj;
+	uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
+	uint32_t ht40plus2gendch = 0;
+	v_REGDOMAIN_t domain;
+	uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
+#ifdef SOFTAP_CHANNEL_RANGE
+	uint8_t count;
+	uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
+#endif
+	tpAniSirGlobal mac_ctx;
+
+	mac_ctx = PMAC_STRUCT(hal);
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, Running SAP Ch Select", __func__);
+
+#ifdef FEATURE_WLAN_CH_AVOID
+	sap_update_unsafe_channel_list(hal, sap_ctx);
+#endif
+
+	/*
+	 * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
+	 * then skip acs process if no bss found.
+	 */
+	if (NULL == scan_result &&
+	    !(sap_ctx->auto_channel_select_weight & 0xffff00)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("No external AP present"));
+
+#ifndef SOFTAP_CHANNEL_RANGE
+		return SAP_CHANNEL_NOT_SELECTED;
+#else
+		return sap_select_channel_no_scan_result(hal, sap_ctx);
+#endif
+	}
+
+	/* Initialize the structure pointed by spect_info */
+	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;
+	}
+	/* Compute the weight of the entire spectrum in the operating band */
+	sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	/* process avoid channel IE to collect all channels to avoid */
+	sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+	wlan_reg_read_current_country(mac_ctx->psoc, country);
+	wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
+#ifdef SOFTAP_CHANNEL_RANGE
+	start_ch_num = sap_ctx->acs_cfg->start_ch;
+	end_ch_num = sap_ctx->acs_cfg->end_ch;
+	SET_ACS_BAND(operating_band, sap_ctx);
+
+	sap_ctx->acsBestChannelInfo.channelNum = 0;
+	sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
+
+	/* Sort the ch lst as per the computed weights, lesser weight first. */
+	sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain);
+
+	/*Loop till get the best channel in the given range */
+	for (count = 0; count < spect_info->numSpectChans; count++) {
+		if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
+		    (end_ch_num < spect_info->pSpectCh[count].chNum))
+			continue;
+
+		if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
+			best_ch_num = spect_info->pSpectCh[count].chNum;
+			/* check if best_ch_num is in preferred channel list */
+			best_ch_num =
+				sap_select_preferred_channel_from_channel_list(
+					best_ch_num, sap_ctx, spect_info);
+			/* if not in preferred ch lst, go to nxt best ch */
+			if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
+				continue;
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+			/*
+			 * Weight of the channels(device's AP is operating)
+			 * increased to MAX+1 so that they will be chosen only
+			 * when there is no other best channel to choose
+			 */
+			if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
+				best_ch_num = SAP_CHANNEL_NOT_SELECTED;
+				continue;
+			}
+#endif
+
+			sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
+			sap_ctx->acsBestChannelInfo.weight =
+					spect_info->pSpectCh[count].weight_copy;
+		}
+
+		if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
+			continue;
+
+		if (operating_band != eCSR_DOT11_MODE_11g) {
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				QDF_TRACE_LEVEL_INFO_HIGH,
+				"operating_band %d", operating_band);
+			continue;
+		}
+
+		/* Give preference to Non-overlap channels */
+		if (false == sap_is_ch_non_overlap(sap_ctx,
+				spect_info->pSpectCh[count].chNum)) {
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				QDF_TRACE_LEVEL_INFO_HIGH,
+				FL("ch: %d skipped as its overlapping ch"),
+				spect_info->pSpectCh[count].chNum);
+			continue;
+		}
+
+		if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
+				spect_info->pSpectCh[count].chNum) &&
+			policy_mgr_disallow_mcc(mac_ctx->psoc,
+				spect_info->pSpectCh[count].chNum)) {
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				QDF_TRACE_LEVEL_INFO_HIGH,
+				"No DFS MCC");
+			continue;
+		}
+
+		if (spect_info->pSpectCh[count].weight_copy >
+				sap_ctx->acsBestChannelInfo.weight)
+			continue;
+
+		tmp_ch_num = spect_info->pSpectCh[count].chNum;
+		tmp_ch_num = sap_channel_in_acs_channel_list(
+					tmp_ch_num, sap_ctx, spect_info);
+		if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
+			continue;
+
+		best_ch_num = tmp_ch_num;
+		break;
+	}
+#else
+	/* Sort the ch lst as per the computed weights, lesser weight first. */
+	sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
+	/* Get the first channel in sorted array as best 20M Channel */
+	best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
+	/* Select Best Channel from Channel List if Configured */
+	best_ch_num = sap_select_preferred_channel_from_channel_list(
+					best_ch_num, sap_ctx, spect_info);
+#endif
+
+	/*
+	 * in case the best channel seleted is not in PCL and there is another
+	 * channel which has same weightage and is in PCL, choose the one in
+	 * PCL
+	 */
+	for (count = 0; count < spect_info->numSpectChans; count++) {
+		if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
+		    (spect_info->pSpectCh[count].weight !=
+				sap_ctx->acsBestChannelInfo.weight))
+			continue;
+
+		if (sap_select_preferred_channel_from_channel_list(
+			spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
+			== SAP_CHANNEL_NOT_SELECTED)
+			continue;
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+		if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
+			continue;
+#endif
+		best_ch_num = spect_info->pSpectCh[count].chNum;
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			FL("change best channel to %d in PCL"), best_ch_num);
+		break;
+	}
+
+	sap_ctx->acs_cfg->pri_ch = best_ch_num;
+	/* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
+	if ((operating_band != eCSR_DOT11_MODE_11g) ||
+	    (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
+		goto sap_ch_sel_end;
+	if (REGDOMAIN_FCC == domain)
+		ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
+	else
+		ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
+	if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
+			(best_ch_num <= ht40plus2gendch)) {
+		int weight_below, weight_above, i;
+		tSapSpectChInfo *pspect_info;
+
+		weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
+		pspect_info = spect_info->pSpectCh;
+		for (i = 0; i < spect_info->numSpectChans; i++) {
+			if (pspect_info[i].chNum == (best_ch_num - 4))
+				weight_below = pspect_info[i].weight;
+			if (pspect_info[i].chNum == (best_ch_num + 4))
+				weight_above = pspect_info[i].weight;
+		}
+
+		if (weight_below < weight_above)
+			sap_ctx->acs_cfg->ht_sec_ch =
+					sap_ctx->acs_cfg->pri_ch - 4;
+		else
+			sap_ctx->acs_cfg->ht_sec_ch =
+					sap_ctx->acs_cfg->pri_ch + 4;
+	} else if (best_ch_num >= 1 && best_ch_num <= 4) {
+		sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
+	} else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
+			HT40MINUS_2G_CH_END) {
+		sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
+	} else if (best_ch_num == 14) {
+		sap_ctx->acs_cfg->ht_sec_ch = 0;
+	}
+	sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
+
+sap_ch_sel_end:
+	/* Free all the allocated memory */
+	sap_chan_sel_exit(spect_info);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
+	host_log_acs_best_chan(best_ch_num, sap_ctx->acsBestChannelInfo.weight);
+
+	if (best_ch_num > 0 && best_ch_num <= 252)
+		return best_ch_num;
+	else
+		return SAP_CHANNEL_NOT_SELECTED;
+}
diff --git a/core/sap/src/sap_ch_select.h b/core/sap/src/sap_ch_select.h
new file mode 100644
index 0000000..35d2a6c
--- /dev/null
+++ b/core/sap/src/sap_ch_select.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2012-2015, 2017-2018 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.
+ */
+
+#if !defined(__SAP_CH_SELECT_H)
+#define __SAP_CH_SELECT_H
+
+/*===========================================================================
+
+				sapChSelect.h
+
+   OVERVIEW:
+
+   This software unit holds the implementation of the WLAN SAP modules
+   functions for channel selection.
+
+   DEPENDENCIES:
+
+   Are listed for each API below.
+   ===========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include "ani_global.h"
+/*--------------------------------------------------------------------------
+   defines and enum
+   --------------------------------------------------------------------------*/
+
+#define SPECT_24GHZ_CH_COUNT    (11)    /* USA regulatory domain */
+#define SAPDFS_NORMALISE_1000      (1000/9)     /* Case of spec20 with channel diff = 0 */
+/* Gen 5 values
+   #define SOFTAP_MIN_RSSI         (-85)
+   #define SOFTAP_MAX_RSSI         (-45)
+ */
+#define SOFTAP_MIN_RSSI         (-100)
+#define SOFTAP_MAX_RSSI         (0)
+#define SOFTAP_MIN_COUNT        (0)
+#define SOFTAP_MAX_COUNT        (60)
+
+#define SOFTAP_MIN_NF           (-120)
+#define SOFTAP_MAX_NF           (-60)
+#define SOFTAP_MIN_CHNFREE      (0)
+#define SOFTAP_MAX_CHNFREE      (1)
+#define SOFTAP_MIN_TXPWR        (0)
+#define SOFTAP_MAX_TXPWR        (63)
+
+#define SOFTAP_HT20_CHANNELWIDTH 0
+/* In HT40/VHT80, Effect of primary Channel RSSi on Subband1 */
+#define SAP_SUBBAND1_RSSI_EFFECT_PRIMARY  (-20)
+/* In VHT80, Effect of primary Channel RSSI on Subband2 */
+#define SAP_SUBBAND2_RSSI_EFFECT_PRIMARY  (-30)
+/* In VHT80, Effect of Primary Channel RSSI on Subband3 */
+#define SAP_SUBBAND3_RSSI_EFFECT_PRIMARY  (-40)
+/* In VHT80, Effect of Primary Channel RSSI on Subband4 */
+#define SAP_SUBBAND4_RSSI_EFFECT_PRIMARY  (-50)
+/* In VHT80, Effect of Primary Channel RSSI on Subband5 */
+#define SAP_SUBBAND5_RSSI_EFFECT_PRIMARY  (-60)
+/* In VHT80, Effect of Primary Channel RSSI on Subband6 */
+#define SAP_SUBBAND6_RSSI_EFFECT_PRIMARY  (-70)
+/* In VHT80, Effect of Primary Channel RSSI on Subband7 */
+#define SAP_SUBBAND7_RSSI_EFFECT_PRIMARY  (-80)
+
+#define SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY      (-10)     /* In 2.4GHZ, Effect of Primary  Channel RSSI on First Overlapping Channel */
+#define SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY        (-20)     /* In 2.4GHZ, Effect of Primary  Channel RSSI on Second Overlapping Channel */
+#define SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY      (-30)     /* In 2.4GHZ, Effect of Primary  Channel RSSI on Third Overlapping Channel */
+#define SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY     (-40)     /* In 2.4GHZ, Effect of Primary  Channel RSSI on Fourth Overlapping Channel */
+
+typedef enum {
+	CHANNEL_1 = 1,
+	CHANNEL_2,
+	CHANNEL_3,
+	CHANNEL_4,
+	CHANNEL_5,
+	CHANNEL_6,
+	CHANNEL_7,
+	CHANNEL_8,
+	CHANNEL_9,
+	CHANNEL_10,
+	CHANNEL_11,
+	CHANNEL_12,
+	CHANNEL_13,
+	CHANNEL_14
+} tSapChannel;
+
+#define MAX_80MHZ_BANDS 6
+#define SAP_80MHZ_MASK     0x0F
+#define SAP_40MHZ_MASK_L   0x03
+#define SAP_40MHZ_MASK_H   0x0C
+
+/*
+ * structs for holding channel bonding bitmap
+ * used for finding new channel when SAP is on
+ * DFS channel and radar is detected.
+ */
+typedef struct sChannelBondingInfo {
+	uint8_t channelMap:4;
+	uint8_t rsvd:4;
+	uint8_t startChannel;
+} tChannelBondingInfo;
+
+typedef struct __chan_bonding_bitmap {
+	tChannelBondingInfo chanBondingSet[MAX_80MHZ_BANDS];
+} chan_bonding_bitmap;
+
+/**
+ * Structure holding information of each channel in the spectrum,
+ * it contains the channel number, the computed weight
+ */
+typedef struct sChannelInfo {
+	uint8_t channel;
+	bool valid;             /* if the channel is valid to be picked as new channel */
+} tChannelInfo;
+
+typedef struct sAll5GChannelList {
+	uint8_t numChannel;
+	tChannelInfo *channelList;
+} tAll5GChannelList;
+
+typedef struct sSapChannelListInfo {
+	uint8_t numChannel;
+	uint8_t *channelList;
+} tSapChannelListInfo;
+
+typedef struct {
+	uint16_t chNum;         /* Channel Number */
+	uint16_t channelWidth;  /* Channel Width */
+	uint16_t bssCount;      /* bss found in scanresult for this channel */
+	int32_t rssiAgr;        /* Max value of rssi among all BSS(es) from scanresult for this channel */
+	uint32_t weight;        /* Weightage of this channel */
+	uint32_t weight_copy;   /* copy of the orignal weight */
+	bool valid;             /* Is this a valid center frequency for regulatory domain */
+} tSapSpectChInfo;              /* tDfsSpectChInfo; */
+
+/**
+ * Structure holding all the information required to make a
+ * decision for the best operating channel based on dfs formula
+ */
+
+typedef struct {
+	tSapSpectChInfo *pSpectCh;      /* tDfsSpectChInfo *pSpectCh;  // Ptr to the channels in the entire spectrum band */
+	uint8_t numSpectChans;  /* Total num of channels in the spectrum */
+} tSapChSelSpectInfo;           /* tDfsChSelParams; */
+
+/**
+ * Structure for channel weight calculation parameters
+ */
+typedef struct sSapChSelParams {
+	void *pSpectInfoParams; /**pDfsParams;   // Filled with tSapChSelSpectInfo */
+	uint16_t numChannels;
+} tSapChSelParams;
+
+#endif /* if !defined __SAP_CH_SELECT_H */
diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c
new file mode 100644
index 0000000..e3704a2
--- /dev/null
+++ b/core/sap/src/sap_fsm.c
@@ -0,0 +1,3851 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/*===========================================================================
+
+			s a p F s m . C
+
+   OVERVIEW:
+
+   This software unit holds the implementation of the WLAN SAP Finite
+   State Machine modules
+
+   DEPENDENCIES:
+
+   Are listed for each API below.
+   ===========================================================================*/
+
+/*----------------------------------------------------------------------------
+ * Include Files
+ * -------------------------------------------------------------------------*/
+#include "sap_internal.h"
+#include <wlan_dfs_tgt_api.h>
+#include <wlan_dfs_utils_api.h>
+#include <wlan_dfs_public_struct.h>
+#include <wlan_reg_services_api.h>
+/* Pick up the SME API definitions */
+#include "sme_api.h"
+/* Pick up the PMC API definitions */
+#include "cds_utils.h"
+#include "cds_ieee80211_common_i.h"
+#include "cds_reg_service.h"
+#include "qdf_util.h"
+#include "wlan_policy_mgr_api.h"
+#include "cfg_api.h"
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_utility.h>
+#include <linux/netdevice.h>
+#include <net/cfg80211.h>
+#include <qca_vendor.h>
+#include <wlan_scan_ucfg_api.h>
+#include "wlan_reg_services_api.h"
+
+/*----------------------------------------------------------------------------
+ * Preprocessor Definitions and Constants
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Type Declarations
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Global Data Definitions
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ *  External declarations for global context
+ * -------------------------------------------------------------------------*/
+#ifdef FEATURE_WLAN_CH_AVOID
+extern sapSafeChannelType safe_channels[];
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+/*----------------------------------------------------------------------------
+ * Static Variable Definitions
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Static Function Declarations and Definitions
+ * -------------------------------------------------------------------------*/
+#ifdef SOFTAP_CHANNEL_RANGE
+static QDF_STATUS sap_get_channel_list(struct sap_context *sapContext,
+				    uint8_t **channelList,
+				    uint8_t *numberOfChannels);
+#endif
+
+/*==========================================================================
+   FUNCTION    sapStopDfsCacTimer
+
+   DESCRIPTION
+    Function to sttop the DFS CAC timer when SAP is stopped
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    sapContext: SAP Context
+   RETURN VALUE
+    DFS Timer start status
+   SIDE EFFECTS
+   ============================================================================*/
+
+static int sap_stop_dfs_cac_timer(struct sap_context *sapContext);
+
+/*==========================================================================
+   FUNCTION    sapStartDfsCacTimer
+
+   DESCRIPTION
+    Function to start the DFS CAC timer when SAP is started on DFS Channel
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    sapContext: SAP Context
+   RETURN VALUE
+    DFS Timer start status
+   SIDE EFFECTS
+   ============================================================================*/
+
+static int sap_start_dfs_cac_timer(struct sap_context *sapContext);
+
+/** sap_hdd_event_to_string() - convert hdd event to string
+ * @event: eSapHddEvent event type
+ *
+ * This function converts eSapHddEvent into string
+ *
+ * Return: string for the @event.
+ */
+static uint8_t *sap_hdd_event_to_string(eSapHddEvent event)
+{
+	switch (event) {
+	CASE_RETURN_STRING(eSAP_START_BSS_EVENT);
+	CASE_RETURN_STRING(eSAP_STOP_BSS_EVENT);
+	CASE_RETURN_STRING(eSAP_STA_ASSOC_IND);
+	CASE_RETURN_STRING(eSAP_STA_ASSOC_EVENT);
+	CASE_RETURN_STRING(eSAP_STA_REASSOC_EVENT);
+	CASE_RETURN_STRING(eSAP_STA_DISASSOC_EVENT);
+	CASE_RETURN_STRING(eSAP_STA_SET_KEY_EVENT);
+	CASE_RETURN_STRING(eSAP_STA_MIC_FAILURE_EVENT);
+	CASE_RETURN_STRING(eSAP_ASSOC_STA_CALLBACK_EVENT);
+	CASE_RETURN_STRING(eSAP_WPS_PBC_PROBE_REQ_EVENT);
+	CASE_RETURN_STRING(eSAP_DISCONNECT_ALL_P2P_CLIENT);
+	CASE_RETURN_STRING(eSAP_MAC_TRIG_STOP_BSS_EVENT);
+	CASE_RETURN_STRING(eSAP_UNKNOWN_STA_JOIN);
+	CASE_RETURN_STRING(eSAP_MAX_ASSOC_EXCEEDED);
+	CASE_RETURN_STRING(eSAP_CHANNEL_CHANGE_EVENT);
+	CASE_RETURN_STRING(eSAP_DFS_CAC_START);
+	CASE_RETURN_STRING(eSAP_DFS_CAC_INTERRUPTED);
+	CASE_RETURN_STRING(eSAP_DFS_CAC_END);
+	CASE_RETURN_STRING(eSAP_DFS_PRE_CAC_END);
+	CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT);
+	CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC);
+	CASE_RETURN_STRING(eSAP_DFS_NO_AVAILABLE_CHANNEL);
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+	CASE_RETURN_STRING(eSAP_ACS_SCAN_SUCCESS_EVENT);
+#endif
+	CASE_RETURN_STRING(eSAP_ACS_CHANNEL_SELECTED);
+	CASE_RETURN_STRING(eSAP_ECSA_CHANGE_CHAN_IND);
+	default:
+		return "eSAP_HDD_EVENT_UNKNOWN";
+	}
+}
+
+/*----------------------------------------------------------------------------
+ * Externalized Function Definitions
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Function Declarations and Documentation
+ * -------------------------------------------------------------------------*/
+
+#ifdef DFS_COMPONENT_ENABLE
+/**
+ * sap_random_channel_sel() - This function randomly pick up an available
+ * channel
+ * @sap_ctx: sap context.
+ *
+ * This function first eliminates invalid channel, then selects random channel
+ * using following algorithm:
+ *
+ * Return: channel number picked
+ */
+static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx)
+{
+	uint8_t ch;
+	uint8_t ch_wd;
+	struct wlan_objmgr_pdev *pdev = NULL;
+	struct ch_params *ch_params;
+	uint32_t hw_mode;
+	struct mac_context *mac_ctx;
+	struct dfs_acs_info acs_info = {0};
+
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return 0;
+	}
+
+	pdev = mac_ctx->pdev;
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("null pdev"));
+		return 0;
+	}
+
+	ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
+	if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) {
+		ch_wd = sap_ctx->ch_width_orig;
+		mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd;
+	} else {
+		ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth;
+	}
+
+	ch_params->ch_width = ch_wd;
+	if (sap_ctx->acs_cfg) {
+		acs_info.acs_mode = sap_ctx->acs_cfg->acs_mode;
+		acs_info.start_ch = sap_ctx->acs_cfg->start_ch;
+		acs_info.end_ch = sap_ctx->acs_cfg->end_ch;
+	} else {
+		acs_info.acs_mode = false;
+	}
+	if (QDF_IS_STATUS_ERROR(utils_dfs_get_random_channel(
+	    pdev, 0, ch_params, &hw_mode, &ch, &acs_info))) {
+		/* No available channel found */
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("No available channel found!!!"));
+		sap_signal_hdd_event(sap_ctx, NULL,
+				eSAP_DFS_NO_AVAILABLE_CHANNEL,
+				(void *)eSAP_STATUS_SUCCESS);
+		return 0;
+	}
+	mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_params->ch_width;
+	sap_ctx->ch_params.ch_width = ch_params->ch_width;
+	sap_ctx->ch_params.sec_ch_offset = ch_params->sec_ch_offset;
+	sap_ctx->ch_params.center_freq_seg0 = ch_params->center_freq_seg0;
+	sap_ctx->ch_params.center_freq_seg1 = ch_params->center_freq_seg1;
+	return ch;
+}
+#else
+static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx)
+{
+	return 0;
+}
+#endif
+
+/**
+ * sap_is_channel_bonding_etsi_weather_channel() - check weather chan bonding.
+ * @sap_ctx: sap context
+ *
+ * Check if the current SAP operating channel is bonded to weather radar
+ * channel in ETSI domain.
+ *
+ * Return: True if bonded to weather channel in ETSI
+ */
+static bool
+sap_is_channel_bonding_etsi_weather_channel(struct sap_context *sap_ctx)
+{
+	if (IS_CH_BONDING_WITH_WEATHER_CH(sap_ctx->channel) &&
+	    (sap_ctx->ch_params.ch_width != CH_WIDTH_20MHZ))
+		return true;
+
+	return false;
+}
+
+/*
+ * sap_get_bonding_channels() - get bonding channels from primary channel.
+ * @sapContext: Handle to SAP context.
+ * @channel: Channel to get bonded channels.
+ * @channels: Bonded channel list
+ * @size: Max bonded channels
+ * @chanBondState: The channel bonding mode of the passed channel.
+ *
+ * Return: Number of sub channels
+ */
+static uint8_t sap_get_bonding_channels(struct sap_context *sapContext,
+					uint8_t channel,
+					uint8_t *channels, uint8_t size,
+					ePhyChanBondState chanBondState)
+{
+	uint8_t numChannel;
+
+	if (channels == NULL)
+		return 0;
+
+	if (size < MAX_BONDED_CHANNELS)
+		return 0;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+		  FL("cbmode: %d, channel: %d"), chanBondState, channel);
+
+	switch (chanBondState) {
+	case PHY_SINGLE_CHANNEL_CENTERED:
+		numChannel = 1;
+		channels[0] = channel;
+		break;
+	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+		numChannel = 2;
+		channels[0] = channel - 4;
+		channels[1] = channel;
+		break;
+	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+		numChannel = 2;
+		channels[0] = channel;
+		channels[1] = channel + 4;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+		numChannel = 4;
+		channels[0] = channel;
+		channels[1] = channel + 4;
+		channels[2] = channel + 8;
+		channels[3] = channel + 12;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+		numChannel = 4;
+		channels[0] = channel - 4;
+		channels[1] = channel;
+		channels[2] = channel + 4;
+		channels[3] = channel + 8;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+		numChannel = 4;
+		channels[0] = channel - 8;
+		channels[1] = channel - 4;
+		channels[2] = channel;
+		channels[3] = channel + 4;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+		numChannel = 4;
+		channels[0] = channel - 12;
+		channels[1] = channel - 8;
+		channels[2] = channel - 4;
+		channels[3] = channel;
+		break;
+	default:
+		numChannel = 1;
+		channels[0] = channel;
+		break;
+	}
+
+	return numChannel;
+}
+
+/**
+ * sap_ch_params_to_bonding_channels() - get bonding channels from channel param
+ * @ch_params: channel params ( bw, pri and sec channel info)
+ * @channels: bonded channel list
+ *
+ * Return: Number of sub channels
+ */
+static uint8_t sap_ch_params_to_bonding_channels(
+		struct ch_params *ch_params,
+		uint8_t *channels)
+{
+	uint8_t center_chan = ch_params->center_freq_seg0;
+	uint8_t nchannels = 0;
+
+	switch (ch_params->ch_width) {
+	case CH_WIDTH_160MHZ:
+		nchannels = 8;
+		center_chan = ch_params->center_freq_seg1;
+		channels[0] = center_chan - 14;
+		channels[1] = center_chan - 10;
+		channels[2] = center_chan - 6;
+		channels[3] = center_chan - 2;
+		channels[4] = center_chan + 2;
+		channels[5] = center_chan + 6;
+		channels[6] = center_chan + 10;
+		channels[7] = center_chan + 14;
+		break;
+	case CH_WIDTH_80P80MHZ:
+		nchannels = 8;
+		channels[0] = center_chan - 6;
+		channels[1] = center_chan - 2;
+		channels[2] = center_chan + 2;
+		channels[3] = center_chan + 6;
+
+		center_chan = ch_params->center_freq_seg1;
+		channels[4] = center_chan - 6;
+		channels[5] = center_chan - 2;
+		channels[6] = center_chan + 2;
+		channels[7] = center_chan + 6;
+		break;
+	case CH_WIDTH_80MHZ:
+		nchannels = 4;
+		channels[0] = center_chan - 6;
+		channels[1] = center_chan - 2;
+		channels[2] = center_chan + 2;
+		channels[3] = center_chan + 6;
+		break;
+	case CH_WIDTH_40MHZ:
+		nchannels = 2;
+		channels[0] = center_chan - 2;
+		channels[1] = center_chan + 2;
+		break;
+	default:
+		nchannels = 1;
+		channels[0] = center_chan;
+		break;
+	}
+
+	return nchannels;
+}
+
+void sap_get_cac_dur_dfs_region(struct sap_context *sap_ctx,
+		uint32_t *cac_duration_ms,
+		uint32_t *dfs_region)
+{
+	int i;
+	uint8_t channels[MAX_BONDED_CHANNELS];
+	uint8_t num_channels;
+	struct ch_params *ch_params = &sap_ctx->ch_params;
+	struct mac_context *mac;
+
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: null sap_ctx", __func__);
+		return;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return;
+	}
+
+	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,
+			  "%s: ignore_cac is set", __func__);
+		return;
+	}
+	*cac_duration_ms = DEFAULT_CAC_TIMEOUT;
+
+	if (*dfs_region != DFS_ETSI_REGION) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			 FL("sapdfs: default 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,
+			  FL("sapdfs: bonding_etsi_weather_channel"));
+		return;
+	}
+
+	qdf_mem_zero(channels, sizeof(channels));
+	num_channels = sap_ch_params_to_bonding_channels(ch_params, channels);
+	for (i = 0; i < num_channels; i++) {
+		if (IS_ETSI_WEATHER_CH(channels[i])) {
+			*cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT;
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+				  FL("sapdfs: ch=%d is etsi weather channel"),
+				  channels[i]);
+			return;
+		}
+	}
+
+}
+
+void sap_dfs_set_current_channel(void *ctx)
+{
+	struct sap_context *sap_ctx = ctx;
+	uint32_t ic_flags = 0;
+	uint16_t ic_flagext = 0;
+	uint8_t ic_ieee = sap_ctx->channel;
+	uint16_t ic_freq = utils_dfs_chan_to_freq(sap_ctx->channel);
+	uint8_t vht_seg0 = sap_ctx->csr_roamProfile.ch_params.center_freq_seg0;
+	uint8_t vht_seg1 = sap_ctx->csr_roamProfile.ch_params.center_freq_seg1;
+	struct wlan_objmgr_pdev *pdev;
+	struct mac_context *mac_ctx;
+	uint32_t use_nol = 0;
+	int error;
+
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return;
+	}
+
+	pdev = mac_ctx->pdev;
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("null pdev"));
+		return;
+	}
+
+	switch (sap_ctx->csr_roamProfile.ch_params.ch_width) {
+	case CH_WIDTH_20MHZ:
+		ic_flags |= IEEE80211_CHAN_VHT20;
+		break;
+	case CH_WIDTH_40MHZ:
+		ic_flags |= IEEE80211_CHAN_VHT40PLUS;
+		break;
+	case CH_WIDTH_80MHZ:
+		ic_flags |= IEEE80211_CHAN_VHT80;
+		break;
+	case CH_WIDTH_80P80MHZ:
+		ic_flags |= IEEE80211_CHAN_VHT80_80;
+		break;
+	case CH_WIDTH_160MHZ:
+		ic_flags |= IEEE80211_CHAN_VHT160;
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid channel width=%d"),
+			  sap_ctx->csr_roamProfile.ch_params.ch_width);
+		return;
+	}
+
+	if (WLAN_REG_IS_24GHZ_CH(sap_ctx->channel))
+		ic_flags |= IEEE80211_CHAN_2GHZ;
+	else
+		ic_flags |= IEEE80211_CHAN_5GHZ;
+
+	if (wlan_reg_is_dfs_ch(pdev, sap_ctx->channel))
+		ic_flagext |= IEEE80211_CHAN_DFS;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+		  FL("freq=%d, channel=%d, seg0=%d, seg1=%d, flags=0x%x, ext flags=0x%x"),
+		  ic_freq, ic_ieee, vht_seg0, vht_seg1, ic_flags, ic_flagext);
+
+	tgt_dfs_set_current_channel(pdev, ic_freq, ic_flags,
+			ic_flagext, ic_ieee, vht_seg0, vht_seg1);
+
+	if (wlan_reg_is_dfs_ch(pdev, sap_ctx->channel)) {
+		if (policy_mgr_concurrent_beaconing_sessions_running(
+		    mac_ctx->psoc)) {
+			uint16_t con_ch;
+			mac_handle_t handle = MAC_HANDLE(mac_ctx);
+
+			con_ch = sme_get_concurrent_operation_channel(handle);
+			if (!con_ch || !wlan_reg_is_dfs_ch(pdev, con_ch))
+				tgt_dfs_get_radars(pdev);
+		} else {
+			tgt_dfs_get_radars(pdev);
+		}
+		tgt_dfs_set_phyerr_filter_offload(pdev);
+		if (sap_ctx->csr_roamProfile.disableDFSChSwitch)
+			tgt_dfs_control(pdev, DFS_SET_USENOL, &use_nol,
+					sizeof(uint32_t), NULL, NULL, &error);
+	}
+}
+
+/*
+ * FUNCTION  sap_dfs_is_w53_invalid
+ *
+ * DESCRIPTION Checks if the passed channel is W53 and returns if
+ *             SAP W53 opearation is allowed.
+ *
+ * DEPENDENCIES PARAMETERS
+ * IN hHAL : HAL pointer
+ * channelID: Channel Number to be verified
+ *
+ * RETURN VALUE  : bool
+ *                 true: If W53 operation is disabled
+ *                 false: If W53 operation is enabled
+ *
+ * SIDE EFFECTS
+ */
+bool sap_dfs_is_w53_invalid(tHalHandle hHal, uint8_t channelID)
+{
+	tpAniSirGlobal pMac;
+
+	pMac = PMAC_STRUCT(hHal);
+	if (NULL == pMac) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("invalid pMac"));
+		return false;
+	}
+
+	/*
+	 * Check for JAPAN W53 Channel operation capability
+	 */
+	if (true == pMac->sap.SapDfsInfo.is_dfs_w53_disabled &&
+	    true == IS_CHAN_JAPAN_W53(channelID)) {
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ * FUNCTION  sap_dfs_is_channel_in_preferred_location
+ *
+ * DESCRIPTION Checks if the passed channel is in accordance with preferred
+ *          Channel location settings.
+ *
+ * DEPENDENCIES PARAMETERS
+ * IN hHAL : HAL pointer
+ * channelID: Channel Number to be verified
+ *
+ * RETURN VALUE  :bool
+ *        true:If Channel location is same as the preferred location
+ *        false:If Channel location is not same as the preferred location
+ *
+ * SIDE EFFECTS
+ */
+bool sap_dfs_is_channel_in_preferred_location(tHalHandle hHal, uint8_t channelID)
+{
+	tpAniSirGlobal pMac;
+
+	pMac = PMAC_STRUCT(hHal);
+	if (NULL == pMac) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("invalid pMac"));
+		return true;
+	}
+	if ((SAP_CHAN_PREFERRED_INDOOR ==
+	     pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) &&
+	    (true == IS_CHAN_JAPAN_OUTDOOR(channelID))) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
+			  FL
+				  ("CHAN=%d is Outdoor so invalid,preferred Indoor only"),
+			  channelID);
+		return false;
+	} else if ((SAP_CHAN_PREFERRED_OUTDOOR ==
+		    pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location)
+		   && (true == IS_CHAN_JAPAN_INDOOR(channelID))) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
+			  FL
+				  ("CHAN=%d is Indoor so invalid,preferred Outdoor only"),
+			  channelID);
+		return false;
+	}
+
+	return true;
+}
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+/**
+ * sap_check_in_avoid_ch_list() - checks if given channel present is channel
+ * avoidance list
+ *
+ * @sap_ctx:        sap context.
+ * @channel:        channel to be checked in sap_ctx's avoid ch list
+ *
+ * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
+ * which MDM device's AP with MCC was detected. This function checks if given
+ * channel is present in that list.
+ *
+ * Return: true, if channel was present, false othersie.
+ */
+bool sap_check_in_avoid_ch_list(struct sap_context *sap_ctx, uint8_t channel)
+{
+	uint8_t i = 0;
+	struct sap_avoid_channels_info *ie_info =
+		&sap_ctx->sap_detected_avoid_ch_ie;
+	for (i = 0; i < sizeof(ie_info->channels); i++)
+		if (ie_info->channels[i] == channel)
+			return true;
+	return false;
+}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+/**
+ * sap_dfs_is_channel_in_nol_list() - given bonded channel is available
+ * @sap_context: Handle to SAP context.
+ * @channel_number: Channel on which availability should be checked.
+ * @chan_bondState: The channel bonding mode of the passed channel.
+ *
+ * This function Checks if a given bonded channel is available or
+ * usable for DFS operation.
+ *
+ * Return: false if channel is available, true if channel is in NOL.
+ */
+bool
+sap_dfs_is_channel_in_nol_list(struct sap_context *sap_context,
+			       uint8_t channel_number,
+			       ePhyChanBondState chan_bondState)
+{
+	int i;
+	struct mac_context *mac_ctx;
+	uint8_t channels[MAX_BONDED_CHANNELS];
+	uint8_t num_channels;
+	struct wlan_objmgr_pdev *pdev = NULL;
+	enum channel_state ch_state;
+
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return false;
+	}
+
+	/* get the bonded channels */
+	if (channel_number == sap_context->channel && chan_bondState >=
+						PHY_CHANNEL_BONDING_STATE_MAX)
+		num_channels = sap_ch_params_to_bonding_channels(
+					&sap_context->ch_params, channels);
+	else
+		num_channels = sap_get_bonding_channels(sap_context,
+					channel_number, channels,
+					MAX_BONDED_CHANNELS, chan_bondState);
+
+	pdev = mac_ctx->pdev;
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("null pdev"));
+		return false;
+	}
+
+	/* check for NOL, first on will break the loop */
+	for (i = 0; i < num_channels; i++) {
+		ch_state = wlan_reg_get_channel_state(pdev, channels[i]);
+		if (CHANNEL_STATE_ENABLE != ch_state &&
+		    CHANNEL_STATE_DFS != ch_state) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid ch num=%d, ch state=%d"),
+				  channels[i], ch_state);
+			return true;
+		}
+	} /* loop for bonded channels */
+
+	return false;
+}
+
+bool
+sap_chan_bond_dfs_sub_chan(struct sap_context *sap_context,
+			   uint8_t channel_number,
+			   ePhyChanBondState bond_state)
+{
+	int i;
+	struct mac_context *mac_ctx;
+	uint8_t channels[MAX_BONDED_CHANNELS];
+	uint8_t num_channels;
+	struct wlan_objmgr_pdev *pdev;
+
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return false;
+	}
+
+	pdev = mac_ctx->pdev;
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("null pdev"));
+		return false;
+	}
+
+	if (wlan_reg_chan_has_dfs_attribute(pdev, channel_number))
+		return true;
+
+	/* get the bonded channels */
+	if (channel_number == sap_context->channel && bond_state >=
+						PHY_CHANNEL_BONDING_STATE_MAX)
+		num_channels = sap_ch_params_to_bonding_channels(
+					&sap_context->ch_params, channels);
+	else
+		num_channels = sap_get_bonding_channels(
+					sap_context, channel_number, channels,
+					MAX_BONDED_CHANNELS, bond_state);
+
+	for (i = 0; i < num_channels; i++) {
+		if (wlan_reg_chan_has_dfs_attribute(pdev, channels[i])) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+				  FL("sub ch num=%d is dfs in %d"),
+				  channels[i], channel_number);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+uint8_t sap_select_default_oper_chan(struct sap_acs_cfg *acs_cfg)
+{
+	uint8_t channel;
+
+	if (NULL == acs_cfg) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"ACS config invalid!");
+		QDF_BUG(0);
+		return 0;
+	}
+
+	if (acs_cfg->hw_mode == eCSR_DOT11_MODE_11a) {
+		channel = SAP_DEFAULT_5GHZ_CHANNEL;
+	} else if ((acs_cfg->hw_mode == eCSR_DOT11_MODE_11n) ||
+		   (acs_cfg->hw_mode == eCSR_DOT11_MODE_11n_ONLY) ||
+		   (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ac) ||
+		   (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ac_ONLY) ||
+		   (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ax) ||
+		   (acs_cfg->hw_mode == eCSR_DOT11_MODE_11ax_ONLY)) {
+		if (WLAN_REG_IS_5GHZ_CH(acs_cfg->start_ch))
+			channel = SAP_DEFAULT_5GHZ_CHANNEL;
+		else
+			channel = SAP_DEFAULT_24GHZ_CHANNEL;
+	} else {
+		channel = SAP_DEFAULT_24GHZ_CHANNEL;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			FL("channel selected to start bss %d"), channel);
+	return channel;
+}
+
+QDF_STATUS
+sap_validate_chan(struct sap_context *sap_context,
+		  bool pre_start_bss,
+		  bool check_for_connection_update)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac_ctx;
+	bool is_dfs;
+	bool is_safe;
+	tHalHandle h_hal;
+	uint8_t con_ch;
+	bool sta_sap_scc_on_dfs_chan;
+
+	h_hal = cds_get_context(QDF_MODULE_ID_SME);
+	if (NULL == h_hal) {
+		/* we have a serious problem */
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
+			  FL("invalid h_hal"));
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac_ctx = PMAC_STRUCT(h_hal);
+	if (!sap_context->channel) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid channel"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) ||
+	   ((sap_context->cc_switch_mode ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
+	   (policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
+		PM_SAP_MODE, NULL) ||
+	     policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
+		PM_P2P_GO_MODE, NULL)))) {
+		con_ch =
+			sme_get_concurrent_operation_channel(h_hal);
+#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
+		if (con_ch && sap_context->channel != con_ch &&
+		    wlan_reg_is_dfs_ch(mac_ctx->pdev,
+				       sap_context->channel)) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
+				  FL("MCC DFS not supported in AP_AP Mode"));
+			return QDF_STATUS_E_ABORTED;
+		}
+#endif
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+		if (sap_context->cc_switch_mode !=
+					QDF_MCC_TO_SCC_SWITCH_DISABLE) {
+			/*
+			 * For ACS request ,the sapContext->channel is 0,
+			 * we skip below overlap checking. When the ACS
+			 * finish and SAPBSS start, the sapContext->channel
+			 * will not be 0. Then the overlap checking will be
+			 * reactivated.If we use sapContext->channel = 0
+			 * to perform the overlap checking, an invalid overlap
+			 * channel con_ch could becreated. That may cause
+			 * SAP start failed.
+			 */
+			con_ch = sme_check_concurrent_channel_overlap(h_hal,
+					sap_context->channel,
+					sap_context->csr_roamProfile.phyMode,
+					sap_context->cc_switch_mode);
+
+			sta_sap_scc_on_dfs_chan =
+				policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
+								mac_ctx->psoc);
+
+			if (sap_context->cc_switch_mode ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION)
+				sta_sap_scc_on_dfs_chan = false;
+
+			is_dfs = wlan_reg_is_dfs_ch(mac_ctx->pdev, con_ch);
+			is_safe = policy_mgr_is_safe_channel(
+							mac_ctx->psoc, con_ch);
+
+			if (con_ch && is_safe &&
+			    (!is_dfs || (is_dfs && sta_sap_scc_on_dfs_chan))) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					QDF_TRACE_LEVEL_ERROR,
+					"%s: Override ch %d to %d due to CC Intf",
+					__func__, sap_context->channel, con_ch);
+				sap_context->channel = con_ch;
+				wlan_reg_set_channel_params(mac_ctx->pdev,
+						sap_context->channel, 0,
+						&sap_context->ch_params);
+			}
+		}
+#endif
+	}
+
+	if ((policy_mgr_get_concurrency_mode(mac_ctx->psoc) ==
+		(QDF_STA_MASK | QDF_SAP_MASK)) ||
+		((sap_context->cc_switch_mode ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
+		(policy_mgr_get_concurrency_mode(mac_ctx->psoc) ==
+		(QDF_STA_MASK | QDF_P2P_GO_MASK)))) {
+#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
+		if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
+				       sap_context->channel)) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
+				  FL("DFS not supported in STA_AP Mode"));
+			return QDF_STATUS_E_ABORTED;
+		}
+#endif
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+		if (sap_context->cc_switch_mode !=
+					QDF_MCC_TO_SCC_SWITCH_DISABLE) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+				FL("check for overlap: chan:%d mode:%d"),
+				sap_context->channel,
+				sap_context->csr_roamProfile.phyMode);
+			con_ch = sme_check_concurrent_channel_overlap(h_hal,
+					sap_context->channel,
+					sap_context->csr_roamProfile.phyMode,
+					sap_context->cc_switch_mode);
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+				  FL("After check overlap: con_ch:%d"),
+				  con_ch);
+			if (sap_context->cc_switch_mode !=
+		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) {
+				if (QDF_IS_STATUS_ERROR(
+					policy_mgr_valid_sap_conc_channel_check(
+						mac_ctx->psoc, &con_ch,
+						sap_context->channel)))	{
+					QDF_TRACE(QDF_MODULE_ID_SAP,
+						QDF_TRACE_LEVEL_WARN,
+						FL("SAP can't start (no MCC)"));
+					return QDF_STATUS_E_ABORTED;
+				}
+			}
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+				  FL("After check concurrency: con_ch:%d"),
+				  con_ch);
+			sta_sap_scc_on_dfs_chan =
+				policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
+						mac_ctx->psoc);
+			if (con_ch &&
+			    (policy_mgr_sta_sap_scc_on_lte_coex_chan(
+						mac_ctx->psoc) ||
+			     policy_mgr_is_safe_channel(mac_ctx->psoc,
+							con_ch)) &&
+			     (!wlan_reg_is_dfs_ch(mac_ctx->pdev, con_ch) ||
+			      sta_sap_scc_on_dfs_chan)) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					QDF_TRACE_LEVEL_ERROR,
+					"%s: Override ch %d to %d due to CC Intf",
+					__func__, sap_context->channel, con_ch);
+				sap_context->channel = con_ch;
+				wlan_reg_set_channel_params(mac_ctx->pdev,
+						sap_context->channel, 0,
+						&sap_context->ch_params);
+			}
+		}
+#endif
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("for configured channel, Ch= %d"),
+		  sap_context->channel);
+	if (check_for_connection_update) {
+		/* This wait happens in the hostapd context. The event
+		 * is set in the MC thread context.
+		 */
+		qdf_status =
+		policy_mgr_update_and_wait_for_connection_update(
+				mac_ctx->psoc,
+				sap_context->sessionId,
+				sap_context->channel,
+				POLICY_MGR_UPDATE_REASON_START_AP);
+		if (QDF_IS_STATUS_ERROR(qdf_status))
+			return qdf_status;
+	}
+
+	if (pre_start_bss) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			  FL("ACS end due to Ch override. Sel Ch = %d"),
+			  sap_context->channel);
+		sap_context->acs_cfg->pri_ch = sap_context->channel;
+		sap_context->acs_cfg->ch_width =
+					 sap_context->ch_width_orig;
+		sap_config_acs_result(h_hal, sap_context, 0);
+		return QDF_STATUS_E_CANCELED;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sap_channel_sel(struct sap_context *sap_context)
+{
+	QDF_STATUS qdf_ret_status;
+	tpAniSirGlobal mac_ctx;
+	struct scan_start_request *req;
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t i;
+	uint8_t pdev_id;
+
+#ifdef SOFTAP_CHANNEL_RANGE
+	uint8_t *channel_list = NULL;
+	uint8_t num_of_channels = 0;
+#endif
+	tHalHandle h_hal;
+	uint8_t con_ch;
+	uint8_t vdev_id;
+	uint32_t scan_id;
+	uint8_t *self_mac;
+
+	h_hal = cds_get_context(QDF_MODULE_ID_SME);
+	if (!h_hal) {
+		/* we have a serious problem */
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
+			  FL("invalid h_hal"));
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac_ctx = PMAC_STRUCT(h_hal);
+	if (!mac_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid MAC context"));
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (sap_context->channel)
+		return sap_validate_chan(sap_context, true, false);
+
+	if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) ||
+	    ((sap_context->cc_switch_mode ==
+	      QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
+	     (policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
+							PM_SAP_MODE, NULL) ||
+	     policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
+						       PM_P2P_GO_MODE,
+						       NULL)))) {
+		con_ch = sme_get_concurrent_operation_channel(h_hal);
+#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
+		if (con_ch)
+			sap_context->dfs_ch_disable = true;
+#endif
+	}
+
+	if ((policy_mgr_get_concurrency_mode(mac_ctx->psoc) ==
+		(QDF_STA_MASK | QDF_SAP_MASK)) ||
+		((sap_context->cc_switch_mode ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
+		(policy_mgr_get_concurrency_mode(mac_ctx->psoc) ==
+		(QDF_STA_MASK | QDF_P2P_GO_MASK)))) {
+#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
+		sap_context->dfs_ch_disable = true;
+#endif
+	}
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("%s skip_acs_status = %d "), __func__,
+		  sap_context->acs_cfg->skip_scan_status);
+	if (sap_context->acs_cfg->skip_scan_status !=
+					eSAP_SKIP_ACS_SCAN) {
+#endif
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return QDF_STATUS_E_NOMEM;
+
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(mac_ctx->pdev);
+	self_mac = sap_context->self_mac_addr;
+	vdev = wlan_objmgr_get_vdev_by_macaddr_from_psoc(mac_ctx->psoc,
+							 pdev_id,
+							 self_mac,
+							 WLAN_LEGACY_SME_ID);
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid vdev objmgr"));
+		qdf_mem_free(req);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* Initiate a SCAN request */
+	ucfg_scan_init_default_params(vdev, req);
+	req->scan_req.dwell_time_active = 0;
+	scan_id = ucfg_scan_get_scan_id(mac_ctx->psoc);
+	req->scan_req.scan_id = scan_id;
+	vdev_id = wlan_vdev_get_id(vdev);
+	req->scan_req.vdev_id = vdev_id;
+	req->scan_req.scan_req_id = sap_context->req_id;
+	req->scan_req.scan_priority = SCAN_PRIORITY_HIGH;
+	sap_get_channel_list(sap_context, &channel_list, &num_of_channels);
+
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+	if (num_of_channels != 0) {
+#endif
+
+		req->scan_req.chan_list.num_chan = num_of_channels;
+		for (i = 0; i < num_of_channels; i++)
+			req->scan_req.chan_list.chan[i].freq =
+				wlan_chan_to_freq(channel_list[i]);
+		if (sap_context->channelList) {
+			qdf_mem_free(sap_context->channelList);
+			sap_context->channelList = NULL;
+			sap_context->num_of_channel = 0;
+		}
+		sap_context->channelList = channel_list;
+		sap_context->num_of_channel = num_of_channels;
+		/* Set requestType to Full scan */
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("calling ucfg_scan_start"));
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+		if (sap_context->acs_cfg->skip_scan_status ==
+		    eSAP_DO_NEW_ACS_SCAN)
+#endif
+			sme_scan_flush_result(h_hal);
+		qdf_ret_status = ucfg_scan_start(req);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+			if (qdf_ret_status != QDF_STATUS_SUCCESS) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("scan request  fail %d!!!"),
+				  qdf_ret_status);
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				  FL("SAP Configuring default channel, Ch=%d"),
+				  sap_context->channel);
+			sap_context->channel = sap_select_default_oper_chan(
+					sap_context->acs_cfg);
+
+#ifdef SOFTAP_CHANNEL_RANGE
+			if (sap_context->channelList != NULL) {
+				sap_context->channel =
+					sap_context->channelList[0];
+				qdf_mem_free(sap_context->
+					channelList);
+				sap_context->channelList = NULL;
+				sap_context->num_of_channel = 0;
+			}
+#endif
+			/*
+			* In case of ACS req before start Bss,
+			* return failure so that the calling
+			* function can use the default channel.
+			*/
+			return QDF_STATUS_E_FAILURE;
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				 FL("return sme_ScanReq, scanID=%d, Ch=%d"),
+				 scan_id,
+				 sap_context->channel);
+			host_log_acs_scan_start(scan_id, vdev_id);
+		}
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+		}
+	} else {
+		sap_context->acs_cfg->skip_scan_status = eSAP_SKIP_ACS_SCAN;
+	}
+
+	if (sap_context->acs_cfg->skip_scan_status == eSAP_SKIP_ACS_SCAN) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("## %s SKIPPED ACS SCAN"), __func__);
+			wlansap_pre_start_bss_acs_scan_callback(h_hal,
+				sap_context, sap_context->sessionId, 0,
+				eCSR_SCAN_SUCCESS);
+	}
+#endif
+
+	/*
+	 * If scan failed, get default channel and advance state
+	 * machine as success with default channel
+	 *
+	 * Have to wait for the call back to be called to get the
+	 * channel cannot advance state machine here as said above
+	 */
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("Channel: %d"),
+		  sap_context->channel);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sap_find_valid_concurrent_session() - to find valid concurrent session
+ * @hal: pointer to hal abstration layer
+ *
+ * This API will check if any valid concurrent SAP session is present
+ *
+ * Return: pointer to sap context of valid concurrent session
+ */
+static struct sap_context *sap_find_valid_concurrent_session(tHalHandle hal)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint8_t intf = 0;
+	struct sap_context *sap_ctx;
+
+	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+		if (((QDF_SAP_MODE ==
+				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
+		     (QDF_P2P_GO_MODE ==
+				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
+		    mac_ctx->sap.sapCtxList[intf].sap_context != NULL) {
+			sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context;
+			if (sap_ctx->fsm_state != SAP_INIT)
+				return sap_ctx;
+		}
+	}
+
+	return NULL;
+}
+
+static QDF_STATUS sap_clear_global_dfs_param(tHalHandle hal)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	if (NULL != sap_find_valid_concurrent_session(hal)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			  "conc session exists, no need to clear dfs struct");
+		return QDF_STATUS_SUCCESS;
+	}
+	/*
+	 * CAC timer will be initiated and started only when SAP starts
+	 * on DFS channel and it will be stopped and destroyed
+	 * immediately once the radar detected or timedout. So
+	 * as per design CAC timer should be destroyed after stop
+	 */
+	if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+		qdf_mc_timer_stop(&mac_ctx->sap.SapDfsInfo.sap_dfs_cac_timer);
+		mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
+		qdf_mc_timer_destroy(
+			&mac_ctx->sap.SapDfsInfo.sap_dfs_cac_timer);
+	}
+	mac_ctx->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC;
+	sap_cac_reset_notify(hal);
+	qdf_mem_zero(&mac_ctx->sap, sizeof(mac_ctx->sap));
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sap_acquire_vdev_ref(tpAniSirGlobal mac,
+				struct sap_context *sap_ctx,
+				uint8_t session_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	if (sap_ctx->vdev) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid vdev obj in sap context"));
+		return QDF_STATUS_E_FAULT;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc,
+						    session_id,
+						    WLAN_LEGACY_SAP_ID);
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("vdev is NULL for vdev_id: %u"), session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sap_ctx->vdev = vdev;
+	return QDF_STATUS_SUCCESS;
+}
+
+void sap_release_vdev_ref(struct sap_context *sap_ctx)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = sap_ctx->vdev;
+	sap_ctx->vdev = NULL;
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SAP_ID);
+}
+
+QDF_STATUS sap_set_session_param(tHalHandle hal, struct sap_context *sapctx,
+				uint32_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	int i;
+	QDF_STATUS status;
+
+	sapctx->sessionId = session_id;
+	sapctx->is_pre_cac_on = false;
+	sapctx->pre_cac_complete = false;
+	sapctx->chan_before_pre_cac = 0;
+
+	/* When SSR, SAP will restart, clear the old context,sessionId */
+	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
+		if (mac_ctx->sap.sapCtxList[i].sap_context == sapctx)
+			mac_ctx->sap.sapCtxList[i].sap_context = NULL;
+	}
+
+	status = sap_acquire_vdev_ref(mac_ctx, sapctx, session_id);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("sap context init failed for session_id: %u"),
+			  session_id);
+		return status;
+	}
+
+	mac_ctx->sap.sapCtxList[sapctx->sessionId].sessionID =
+				sapctx->sessionId;
+	mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = sapctx;
+	mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona =
+				sapctx->csr_roamProfile.csrPersona;
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+		"%s: Initializing sapContext = %pK with session = %d", __func__,
+		sapctx, session_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sap_clear_session_param(tHalHandle hal, struct sap_context *sapctx,
+				uint32_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	if (sapctx->sessionId >= SAP_MAX_NUM_SESSION)
+		return QDF_STATUS_E_FAILURE;
+
+	sap_release_vdev_ref(sapctx);
+
+	mac_ctx->sap.sapCtxList[sapctx->sessionId].sessionID =
+		CSR_SESSION_ID_INVALID;
+	mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = NULL;
+	mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona =
+		QDF_MAX_NO_OF_MODE;
+	sap_clear_global_dfs_param(hal);
+	sap_free_roam_profile(&sapctx->csr_roamProfile);
+	qdf_mem_zero(sapctx, sizeof(*sapctx));
+	sapctx->sessionId = CSR_SESSION_ID_INVALID;
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+		"%s: Initializing State: %d, sapContext value = %pK", __func__,
+		sapctx->fsm_state, sapctx);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sap_goto_stopping() - Processing of SAP FSM stopping state
+ * @sap_ctx: pointer to sap Context
+ *
+ * Return: QDF_STATUS code associated with performing the operation
+ */
+static QDF_STATUS sap_goto_stopping(struct sap_context *sap_ctx)
+{
+	QDF_STATUS status;
+	struct mac_context *mac_ctx;
+
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		/* we have a serious problem */
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	sap_free_roam_profile(&sap_ctx->csr_roamProfile);
+	status = sme_roam_stop_bss(MAC_HANDLE(mac_ctx), sap_ctx->sessionId);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "Error: In %s calling sme_roam_stop_bss status = %d",
+			  __func__, status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sap_goto_init() - Function for setting the SAP FSM to init state
+ * @sap_ctx: pointer to sap context
+ *
+ * Return: QDF_STATUS code associated with performing the operation
+ */
+static QDF_STATUS sap_goto_init(struct sap_context *sap_ctx)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	tWLAN_SAPEvent sap_event;
+	/* Processing has to be coded */
+
+	/*
+	 * Clean up stations from TL etc as AP BSS is shut down
+	 * then set event
+	 */
+
+	/* hardcoded event */
+	sap_event.event = eSAP_MAC_READY_FOR_CONNECTIONS;
+	sap_event.params = 0;
+	sap_event.u1 = 0;
+	sap_event.u2 = 0;
+	/* Handle event */
+	qdf_status = sap_fsm(sap_ctx, &sap_event);
+
+	return qdf_status;
+}
+
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+/**
+ * sap_handle_acs_scan_event() - handle acs scan event for SAP
+ * @sap_context: ptSapContext
+ * @sap_event: tSap_Event
+ * @status: status of acs scan
+ *
+ * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event.
+ *
+ * Return: void
+ */
+static void sap_handle_acs_scan_event(struct sap_context *sap_context,
+		tSap_Event *sap_event, eSapStatus status)
+{
+	sap_event->sapHddEventCode = eSAP_ACS_SCAN_SUCCESS_EVENT;
+	sap_event->sapevt.sap_acs_scan_comp.status = status;
+	sap_event->sapevt.sap_acs_scan_comp.num_of_channels =
+			sap_context->num_of_channel;
+	sap_event->sapevt.sap_acs_scan_comp.channellist =
+			sap_context->channelList;
+}
+#else
+static void sap_handle_acs_scan_event(struct sap_context *sap_context,
+		tSap_Event *sap_event, eSapStatus status)
+{
+}
+#endif
+
+/**
+ * sap_signal_hdd_event() - send event notification
+ * @sap_ctx: Sap Context
+ * @csr_roaminfo: Pointer to CSR roam information
+ * @sap_hddevent: SAP HDD event
+ * @context: to pass the element for future support
+ *
+ * Function for HDD to send the event notification using callback
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx,
+		struct csr_roam_info *csr_roaminfo, eSapHddEvent sap_hddevent,
+		void *context)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tSap_Event sap_ap_event = {0};
+	struct mac_context *mac_ctx;
+	tSirSmeChanInfo *chaninfo;
+	tSap_StationAssocIndication *assoc_ind;
+	tSap_StartBssCompleteEvent *bss_complete;
+	struct sap_ch_selected_s *acs_selected;
+	tSap_StationAssocReassocCompleteEvent *reassoc_complete;
+	tSap_StationDisassocCompleteEvent *disassoc_comp;
+	tSap_StationSetKeyCompleteEvent *key_complete;
+	tSap_StationMICFailureEvent *mic_failure;
+
+	/* Format the Start BSS Complete event to return... */
+	if (NULL == sap_ctx->pfnSapEventCallback) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("SAP event callback event = %s"),
+		  sap_hdd_event_to_string(sap_hddevent));
+
+	switch (sap_hddevent) {
+	case eSAP_STA_ASSOC_IND:
+		if (!csr_roaminfo) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid CSR Roam Info"));
+			return QDF_STATUS_E_INVAL;
+		}
+		/*  TODO - Indicate the assoc request indication to OS */
+		sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_IND;
+		assoc_ind = &sap_ap_event.sapevt.sapAssocIndication;
+
+		qdf_copy_macaddr(&assoc_ind->staMac, &csr_roaminfo->peerMac);
+		assoc_ind->staId = csr_roaminfo->staId;
+		assoc_ind->status = 0;
+		/* Required for indicating the frames to upper layer */
+		assoc_ind->beaconLength = csr_roaminfo->beaconLength;
+		assoc_ind->beaconPtr = csr_roaminfo->beaconPtr;
+		assoc_ind->assocReqLength = csr_roaminfo->assocReqLength;
+		assoc_ind->assocReqPtr = csr_roaminfo->assocReqPtr;
+		assoc_ind->fWmmEnabled = csr_roaminfo->wmmEnabledSta;
+		assoc_ind->ecsa_capable = csr_roaminfo->ecsa_capable;
+		if (csr_roaminfo->u.pConnectedProfile != NULL) {
+			assoc_ind->negotiatedAuthType =
+				csr_roaminfo->u.pConnectedProfile->AuthType;
+			assoc_ind->negotiatedUCEncryptionType =
+			    csr_roaminfo->u.pConnectedProfile->EncryptionType;
+			assoc_ind->negotiatedMCEncryptionType =
+			    csr_roaminfo->u.pConnectedProfile->mcEncryptionType;
+			assoc_ind->fAuthRequired = csr_roaminfo->fAuthRequired;
+		}
+		break;
+	case eSAP_START_BSS_EVENT:
+		sap_ap_event.sapHddEventCode = eSAP_START_BSS_EVENT;
+		bss_complete = &sap_ap_event.sapevt.sapStartBssCompleteEvent;
+
+		bss_complete->sessionId = sap_ctx->sessionId;
+		if (bss_complete->sessionId == CSR_SESSION_ID_INVALID) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid sessionId"));
+			return QDF_STATUS_E_INVAL;
+		}
+
+		bss_complete->status = (eSapStatus) context;
+		bss_complete->staId = sap_ctx->sap_sta_id;
+
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("(eSAP_START_BSS_EVENT): staId = %d"),
+			  bss_complete->staId);
+
+		bss_complete->operatingChannel = (uint8_t) sap_ctx->channel;
+		bss_complete->ch_width = sap_ctx->ch_params.ch_width;
+		break;
+	case eSAP_DFS_CAC_START:
+	case eSAP_DFS_CAC_INTERRUPTED:
+	case eSAP_DFS_CAC_END:
+	case eSAP_DFS_PRE_CAC_END:
+	case eSAP_DFS_RADAR_DETECT:
+	case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC:
+	case eSAP_DFS_NO_AVAILABLE_CHANNEL:
+		sap_ap_event.sapHddEventCode = sap_hddevent;
+		sap_ap_event.sapevt.sapStopBssCompleteEvent.status =
+			(eSapStatus) context;
+		break;
+	case eSAP_ACS_SCAN_SUCCESS_EVENT:
+		sap_handle_acs_scan_event(sap_ctx, &sap_ap_event,
+			(eSapStatus)context);
+		break;
+	case eSAP_ACS_CHANNEL_SELECTED:
+		sap_ap_event.sapHddEventCode = sap_hddevent;
+		acs_selected = &sap_ap_event.sapevt.sap_ch_selected;
+		if (eSAP_STATUS_SUCCESS == (eSapStatus)context) {
+			acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch;
+			acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch;
+			acs_selected->ch_width = sap_ctx->acs_cfg->ch_width;
+			acs_selected->vht_seg0_center_ch =
+				sap_ctx->acs_cfg->vht_seg0_center_ch;
+			acs_selected->vht_seg1_center_ch =
+				sap_ctx->acs_cfg->vht_seg1_center_ch;
+		} else if (eSAP_STATUS_FAILURE == (eSapStatus)context) {
+			acs_selected->pri_ch = 0;
+		}
+		break;
+
+	case eSAP_STOP_BSS_EVENT:
+		sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_EVENT;
+		sap_ap_event.sapevt.sapStopBssCompleteEvent.status =
+			(eSapStatus) context;
+		break;
+
+	case eSAP_STA_ASSOC_EVENT:
+	case eSAP_STA_REASSOC_EVENT:
+
+		if (!csr_roaminfo) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid CSR Roam Info"));
+			return QDF_STATUS_E_INVAL;
+		}
+		if (sap_ctx->fsm_state == SAP_STOPPING) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  "SAP is stopping, not able to handle any incoming (re)assoc req");
+			return QDF_STATUS_E_ABORTED;
+		}
+
+		reassoc_complete =
+		    &sap_ap_event.sapevt.sapStationAssocReassocCompleteEvent;
+
+		if (csr_roaminfo->fReassocReq)
+			sap_ap_event.sapHddEventCode = eSAP_STA_REASSOC_EVENT;
+		else
+			sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_EVENT;
+
+		qdf_copy_macaddr(&reassoc_complete->staMac,
+				 &csr_roaminfo->peerMac);
+		reassoc_complete->staId = csr_roaminfo->staId;
+		reassoc_complete->statusCode = csr_roaminfo->statusCode;
+		reassoc_complete->iesLen = csr_roaminfo->rsnIELen;
+		qdf_mem_copy(reassoc_complete->ies, csr_roaminfo->prsnIE,
+			     csr_roaminfo->rsnIELen);
+
+#ifdef FEATURE_WLAN_WAPI
+		if (csr_roaminfo->wapiIELen) {
+			uint8_t len = reassoc_complete->iesLen;
+
+			reassoc_complete->iesLen += csr_roaminfo->wapiIELen;
+			qdf_mem_copy(&reassoc_complete->ies[len],
+				     csr_roaminfo->pwapiIE,
+				     csr_roaminfo->wapiIELen);
+		}
+#endif
+		if (csr_roaminfo->addIELen) {
+			uint8_t len = reassoc_complete->iesLen;
+
+			reassoc_complete->iesLen += csr_roaminfo->addIELen;
+			qdf_mem_copy(&reassoc_complete->ies[len],
+				     csr_roaminfo->paddIE,
+				     csr_roaminfo->addIELen);
+			if (wlan_get_vendor_ie_ptr_from_oui(
+			    SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE,
+			    csr_roaminfo->paddIE, csr_roaminfo->addIELen)) {
+				reassoc_complete->staType = eSTA_TYPE_P2P_CLI;
+			} else {
+				reassoc_complete->staType = eSTA_TYPE_INFRA;
+			}
+		}
+
+		/* also fill up the channel info from the csr_roamInfo */
+		chaninfo = &reassoc_complete->chan_info;
+
+		chaninfo->chan_id = csr_roaminfo->chan_info.chan_id;
+		chaninfo->mhz = csr_roaminfo->chan_info.mhz;
+		chaninfo->info = csr_roaminfo->chan_info.info;
+		chaninfo->band_center_freq1 =
+			csr_roaminfo->chan_info.band_center_freq1;
+		chaninfo->band_center_freq2 =
+			csr_roaminfo->chan_info.band_center_freq2;
+		chaninfo->reg_info_1 =
+			csr_roaminfo->chan_info.reg_info_1;
+		chaninfo->reg_info_2 =
+			csr_roaminfo->chan_info.reg_info_2;
+		chaninfo->nss = csr_roaminfo->chan_info.nss;
+		chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags;
+
+		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;
+		reassoc_complete->ecsa_capable = csr_roaminfo->ecsa_capable;
+		if (csr_roaminfo->ht_caps.present)
+			reassoc_complete->ht_caps = csr_roaminfo->ht_caps;
+		if (csr_roaminfo->vht_caps.present)
+			reassoc_complete->vht_caps = csr_roaminfo->vht_caps;
+
+		break;
+
+	case eSAP_STA_DISASSOC_EVENT:
+		if (!csr_roaminfo) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid CSR Roam Info"));
+			return QDF_STATUS_E_INVAL;
+		}
+		sap_ap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
+		disassoc_comp =
+			&sap_ap_event.sapevt.sapStationDisassocCompleteEvent;
+
+		qdf_copy_macaddr(&disassoc_comp->staMac,
+				 &csr_roaminfo->peerMac);
+		disassoc_comp->staId = csr_roaminfo->staId;
+		if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED)
+			disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC;
+		else
+			disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC;
+
+		disassoc_comp->statusCode = csr_roaminfo->statusCode;
+		disassoc_comp->status = (eSapStatus) context;
+		disassoc_comp->rssi = csr_roaminfo->rssi;
+		disassoc_comp->rx_rate = csr_roaminfo->rx_rate;
+		disassoc_comp->tx_rate = csr_roaminfo->tx_rate;
+		disassoc_comp->reason_code = csr_roaminfo->disassoc_reason;
+		break;
+
+	case eSAP_STA_SET_KEY_EVENT:
+
+		if (!csr_roaminfo) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid CSR Roam Info"));
+			return QDF_STATUS_E_INVAL;
+		}
+		sap_ap_event.sapHddEventCode = eSAP_STA_SET_KEY_EVENT;
+		key_complete =
+			&sap_ap_event.sapevt.sapStationSetKeyCompleteEvent;
+		key_complete->status = (eSapStatus) context;
+		qdf_copy_macaddr(&key_complete->peerMacAddr,
+				 &csr_roaminfo->peerMac);
+		break;
+
+	case eSAP_STA_MIC_FAILURE_EVENT:
+
+		if (!csr_roaminfo) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid CSR Roam Info"));
+			return QDF_STATUS_E_INVAL;
+		}
+		sap_ap_event.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT;
+		mic_failure = &sap_ap_event.sapevt.sapStationMICFailureEvent;
+
+		qdf_mem_copy(&mic_failure->srcMacAddr,
+			     csr_roaminfo->u.pMICFailureInfo->srcMacAddr,
+			     sizeof(tSirMacAddr));
+		qdf_mem_copy(&mic_failure->staMac.bytes,
+			     csr_roaminfo->u.pMICFailureInfo->taMacAddr,
+			     sizeof(tSirMacAddr));
+		qdf_mem_copy(&mic_failure->dstMacAddr.bytes,
+			     csr_roaminfo->u.pMICFailureInfo->dstMacAddr,
+			     sizeof(tSirMacAddr));
+		mic_failure->multicast =
+			csr_roaminfo->u.pMICFailureInfo->multicast;
+		mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1;
+		mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId;
+		qdf_mem_copy(mic_failure->TSC,
+			     csr_roaminfo->u.pMICFailureInfo->TSC,
+			     SIR_CIPHER_SEQ_CTR_SIZE);
+		break;
+
+	case eSAP_ASSOC_STA_CALLBACK_EVENT:
+		break;
+
+	case eSAP_WPS_PBC_PROBE_REQ_EVENT:
+
+		if (!csr_roaminfo) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid CSR Roam Info"));
+			return QDF_STATUS_E_INVAL;
+		}
+		sap_ap_event.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT;
+
+		qdf_mem_copy(&sap_ap_event.sapevt.sapPBCProbeReqEvent.
+			     WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq,
+			     sizeof(tSirWPSPBCProbeReq));
+		break;
+
+	case eSAP_DISCONNECT_ALL_P2P_CLIENT:
+		sap_ap_event.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT;
+		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
+			(eSapStatus) context;
+		break;
+
+	case eSAP_MAC_TRIG_STOP_BSS_EVENT:
+		sap_ap_event.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT;
+		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
+			(eSapStatus) context;
+		break;
+
+	case eSAP_UNKNOWN_STA_JOIN:
+		sap_ap_event.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN;
+		qdf_mem_copy((void *) sap_ap_event.sapevt.sapUnknownSTAJoin.
+			     macaddr.bytes, (void *) context,
+			     QDF_MAC_ADDR_SIZE);
+		break;
+
+	case eSAP_MAX_ASSOC_EXCEEDED:
+
+		if (!csr_roaminfo) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid CSR Roam Info"));
+			return QDF_STATUS_E_INVAL;
+		}
+		sap_ap_event.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED;
+		qdf_copy_macaddr(&sap_ap_event.sapevt.
+				 sapMaxAssocExceeded.macaddr,
+				 &csr_roaminfo->peerMac);
+		break;
+
+	case eSAP_CHANNEL_CHANGE_EVENT:
+		/*
+		 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS
+		 * follows pri AP
+		 */
+		sap_ctx->acs_cfg->pri_ch = sap_ctx->channel;
+		sap_ctx->acs_cfg->ch_width =
+				sap_ctx->csr_roamProfile.ch_params.ch_width;
+		sap_config_acs_result(MAC_HANDLE(mac_ctx), sap_ctx,
+				      sap_ctx->secondary_ch);
+
+		sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT;
+
+		acs_selected = &sap_ap_event.sapevt.sap_ch_selected;
+		acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch;
+		acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch;
+		acs_selected->ch_width =
+			sap_ctx->csr_roamProfile.ch_params.ch_width;
+		acs_selected->vht_seg0_center_ch =
+			sap_ctx->csr_roamProfile.ch_params.center_freq_seg0;
+		acs_selected->vht_seg1_center_ch =
+			sap_ctx->csr_roamProfile.ch_params.center_freq_seg1;
+		break;
+
+	case eSAP_ECSA_CHANGE_CHAN_IND:
+
+		if (!csr_roaminfo) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid CSR Roam Info"));
+			return QDF_STATUS_E_INVAL;
+		}
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				"In %s, SAP event callback event = %s",
+				__func__, "eSAP_ECSA_CHANGE_CHAN_IND");
+		sap_ap_event.sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND;
+		sap_ap_event.sapevt.sap_chan_cng_ind.new_chan =
+					   csr_roaminfo->target_channel;
+		break;
+	case eSAP_DFS_NEXT_CHANNEL_REQ:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				"In %s, SAP event callback event = %s",
+				__func__, "eSAP_DFS_NEXT_CHANNEL_REQ");
+		sap_ap_event.sapHddEventCode = eSAP_DFS_NEXT_CHANNEL_REQ;
+		break;
+	case eSAP_STOP_BSS_DUE_TO_NO_CHNL:
+		sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_DUE_TO_NO_CHNL;
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			  FL("stopping session_id:%d, bssid:%pM, channel:%d"),
+			     sap_ctx->sessionId, sap_ctx->self_mac_addr,
+			     sap_ctx->channel);
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("SAP Unknown callback event = %d"),
+			  sap_hddevent);
+		break;
+	}
+	qdf_status = (*sap_ctx->pfnSapEventCallback)
+			(&sap_ap_event, sap_ctx->pUsrContext);
+
+	return qdf_status;
+
+}
+
+/**
+ * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state
+ * @handle: Global MAC handle
+ *
+ * Finds and gets the context of a SAP session in CAC wait state.
+ *
+ * Return: Valid SAP context on success, else NULL
+ */
+static struct sap_context *sap_find_cac_wait_session(tHalHandle handle)
+{
+	tpAniSirGlobal mac = PMAC_STRUCT(handle);
+	uint8_t i = 0;
+	struct sap_context *sap_ctx;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+			"%s", __func__);
+
+	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
+		sap_ctx = mac->sap.sapCtxList[i].sap_context;
+		if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona)
+		    ||
+		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) &&
+		    (sap_is_dfs_cac_wait_state(sap_ctx))) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+				"%s: found SAP in cac wait state", __func__);
+			return sap_ctx;
+		}
+		if (sap_ctx) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+				  "sapdfs: mode:%d intf:%d state:%d",
+				  mac->sap.sapCtxList[i].sapPersona, i,
+				  sap_ctx->fsm_state);
+		}
+	}
+
+	return NULL;
+}
+
+/*==========================================================================
+   FUNCTION  sap_cac_reset_notify
+
+   DESCRIPTION Function will be called up on stop bss indication to clean up
+   DFS global structure.
+
+   DEPENDENCIES PARAMETERS
+     IN hHAL : HAL pointer
+
+   RETURN VALUE  : void.
+
+   SIDE EFFECTS
+   ============================================================================*/
+void sap_cac_reset_notify(tHalHandle hHal)
+{
+	uint8_t intf = 0;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+		struct sap_context *sap_context =
+			pMac->sap.sapCtxList[intf].sap_context;
+		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
+		    ||
+		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
+		    && pMac->sap.sapCtxList[intf].sap_context != NULL) {
+			sap_context->isCacStartNotified = false;
+			sap_context->isCacEndNotified = false;
+		}
+	}
+}
+
+/*==========================================================================
+   FUNCTION  sap_cac_start_notify
+
+   DESCRIPTION Function will be called to notify eSAP_DFS_CAC_START event
+   to HDD
+
+   DEPENDENCIES PARAMETERS
+     IN hHAL : HAL pointer
+
+   RETURN VALUE  : QDF_STATUS.
+
+   SIDE EFFECTS
+   ============================================================================*/
+static QDF_STATUS sap_cac_start_notify(tHalHandle hHal)
+{
+	uint8_t intf = 0;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+
+	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+		struct sap_context *sap_context =
+			pMac->sap.sapCtxList[intf].sap_context;
+		struct csr_roam_profile *profile;
+
+		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
+		    ||
+		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
+		    && pMac->sap.sapCtxList[intf].sap_context != NULL &&
+		    (false == sap_context->isCacStartNotified)) {
+			/* Don't start CAC for non-dfs channel, its violation */
+			profile = &sap_context->csr_roamProfile;
+			if (!wlan_reg_is_dfs_ch(pMac->pdev,
+						profile->operationChannel))
+				continue;
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+				  "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%pK]",
+				  sap_context);
+
+			qdf_status = sap_signal_hdd_event(sap_context, NULL,
+							  eSAP_DFS_CAC_START,
+							  (void *)
+							  eSAP_STATUS_SUCCESS);
+			if (QDF_STATUS_SUCCESS != qdf_status) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "In %s, failed setting isCacStartNotified on interface[%d]",
+					  __func__, intf);
+				return qdf_status;
+			}
+			sap_context->isCacStartNotified = true;
+		}
+	}
+	return qdf_status;
+}
+
+/**
+ * wlansap_update_pre_cac_end() - Update pre cac end to upper layer
+ * @sap_context: SAP context
+ * @mac: Global MAC structure
+ * @intf: Interface number
+ *
+ * Notifies pre cac end to upper layer
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS wlansap_update_pre_cac_end(struct sap_context *sap_context,
+		tpAniSirGlobal mac, uint8_t intf)
+{
+	QDF_STATUS qdf_status;
+
+	sap_context->isCacEndNotified = true;
+	mac->sap.SapDfsInfo.sap_radar_found_status = false;
+	sap_context->fsm_state = SAP_STARTED;
+
+#ifndef CONFIG_VDEV_SM
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+		  "In %s, pre cac end notify on %d: from state %s => %s",
+		  __func__, intf, "SAP_DFS_CAC_WAIT", "SAP_STARTED");
+#else
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+		  "In %s, pre cac end notify on %d: from state %s => %s",
+		  __func__, intf, "SAP_STARTING", "SAP_STARTED");
+#endif
+
+	qdf_status = sap_signal_hdd_event(sap_context,
+			NULL, eSAP_DFS_PRE_CAC_END,
+			(void *)eSAP_STATUS_SUCCESS);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP,
+				QDF_TRACE_LEVEL_ERROR,
+				"In %s, pre cac notify failed on intf %d",
+				__func__, intf);
+		return qdf_status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*==========================================================================
+   FUNCTION  sap_cac_end_notify
+
+   DESCRIPTION Function will be called to notify eSAP_DFS_CAC_END event
+   to HDD
+
+   DEPENDENCIES PARAMETERS
+     IN hHAL : HAL pointer
+
+   RETURN VALUE  : QDF_STATUS.
+
+   SIDE EFFECTS
+   ============================================================================*/
+static QDF_STATUS sap_cac_end_notify(tHalHandle hHal,
+				     struct csr_roam_info *roamInfo)
+{
+	uint8_t intf;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+
+	/*
+	 * eSAP_DFS_CHANNEL_CAC_END:
+	 * CAC Period elapsed and there was no radar
+	 * found so, SAP can continue beaconing.
+	 * sap_radar_found_status is set to 0
+	 */
+	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+		struct sap_context *sap_context =
+			pMac->sap.sapCtxList[intf].sap_context;
+		struct csr_roam_profile *profile;
+
+		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
+		    ||
+		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
+		    && pMac->sap.sapCtxList[intf].sap_context != NULL &&
+		    (false == sap_context->isCacEndNotified) &&
+		    sap_is_dfs_cac_wait_state(sap_context)) {
+			sap_context = pMac->sap.sapCtxList[intf].sap_context;
+			/* Don't check CAC for non-dfs channel */
+			profile = &sap_context->csr_roamProfile;
+			if (!wlan_reg_is_dfs_ch(pMac->pdev,
+						profile->operationChannel))
+				continue;
+
+			/* If this is an end notification of a pre cac, the
+			 * SAP must not start beaconing and must delete the
+			 * temporary interface created for pre cac and switch
+			 * the original SAP to the pre CAC channel.
+			 */
+			if (sap_context->is_pre_cac_on) {
+				qdf_status = wlansap_update_pre_cac_end(
+						sap_context, pMac, intf);
+				if (QDF_IS_STATUS_ERROR(qdf_status))
+					return qdf_status;
+				/* pre CAC is not allowed with any concurrency.
+				 * So, we can break from here.
+				 */
+				break;
+			}
+
+			qdf_status = sap_signal_hdd_event(sap_context, NULL,
+							  eSAP_DFS_CAC_END,
+							  (void *)
+							  eSAP_STATUS_SUCCESS);
+			if (QDF_STATUS_SUCCESS != qdf_status) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "In %s, failed setting isCacEndNotified on interface[%d]",
+					  __func__, intf);
+				return qdf_status;
+			}
+			sap_context->isCacEndNotified = true;
+			pMac->sap.SapDfsInfo.sap_radar_found_status = false;
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+				  "sapdfs: Start beacon request on sapctx[%pK]",
+				  sap_context);
+
+			/* Start beaconing on the new channel */
+			wlansap_start_beacon_req(sap_context);
+
+			/* Transition from SAP_STARTING to SAP_STARTED
+			 * (both without substates)
+			 */
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+				  "sapdfs: channel[%d] from state %s => %s",
+				  sap_context->channel, "SAP_STARTING",
+				  "SAP_STARTED");
+
+			sap_context->fsm_state = SAP_STARTED;
+
+			/*Action code for transition */
+			qdf_status = sap_signal_hdd_event(sap_context, roamInfo,
+							  eSAP_START_BSS_EVENT,
+							  (void *)
+							  eSAP_STATUS_SUCCESS);
+			if (QDF_STATUS_SUCCESS != qdf_status) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "In %s, failed setting isCacEndNotified on interface[%d]",
+					  __func__, intf);
+				return qdf_status;
+			}
+		}
+	}
+	/*
+	 * All APs are done with CAC timer, all APs should start beaconing.
+	 * Lets assume AP1 and AP2 started beaconing on DFS channel, Now lets
+	 * say AP1 goes down and comes back on same DFS channel. In this case
+	 * AP1 shouldn't start CAC timer and start beacon immediately beacause
+	 * AP2 is already beaconing on this channel. This case will be handled
+	 * by checking against eSAP_DFS_SKIP_CAC while starting the timer.
+	 */
+	pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_SKIP_CAC;
+	return qdf_status;
+}
+
+/**
+ * sap_goto_starting() - Trigger softap start
+ * @sap_ctx: SAP context
+ * @sap_event: SAP event buffer
+ * @mac_ctx: global MAC context
+ * @hal: HAL handle
+ *
+ * This function triggers start of softap. Before starting, it can select
+ * new channel if given channel has leakage or if given channel in DFS_NOL.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+sap_goto_starting(struct sap_context *sap_ctx,
+		  ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
+		  tHalHandle hal)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	bool b_leak_chan = false;
+	uint8_t temp_chan;
+
+	temp_chan = sap_ctx->channel;
+	utils_dfs_mark_leaking_ch(mac_ctx->pdev,
+				  sap_ctx->ch_params.ch_width,
+				  1, &temp_chan);
+
+	/*
+	 * if selelcted channel has leakage to channels
+	 * in NOL, the temp_chan will be reset
+	 */
+	b_leak_chan = (temp_chan != sap_ctx->channel);
+	/*
+	 * check if channel is in DFS_NOL or if the channel
+	 * has leakage to the channels in NOL
+	 */
+	if (sap_dfs_is_channel_in_nol_list(sap_ctx, sap_ctx->channel,
+					   PHY_CHANNEL_BONDING_STATE_MAX) ||
+	    b_leak_chan) {
+		uint8_t ch;
+
+		/* find a new available channel */
+		ch = sap_random_channel_sel(sap_ctx);
+		if (!ch) {
+			/* No available channel found */
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_ERROR,
+				  FL("No available channel found!!!"));
+			sap_signal_hdd_event(sap_ctx, NULL,
+					     eSAP_DFS_NO_AVAILABLE_CHANNEL,
+					     (void *)eSAP_STATUS_SUCCESS);
+			return QDF_STATUS_E_FAULT;
+		}
+
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("channel %d is in NOL, Start Bss on new chan %d"),
+			  sap_ctx->channel, ch);
+
+		sap_ctx->channel = ch;
+		wlan_reg_set_channel_params(mac_ctx->pdev,
+					    sap_ctx->channel,
+					    sap_ctx->secondary_ch,
+					    &sap_ctx->ch_params);
+	}
+	if (sap_ctx->channel > 14 &&
+	    (sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11g ||
+	     sap_ctx->csr_roamProfile.phyMode ==
+					eCSR_DOT11_MODE_11g_ONLY))
+		sap_ctx->csr_roamProfile.phyMode = eCSR_DOT11_MODE_11a;
+
+	/*
+	 * when AP2 is started while AP1 is performing ACS, we may not
+	 * have the AP1 channel yet.So here after the completion of AP2
+	 * ACS check if AP1 ACS resulting channel is DFS and if yes
+	 * override AP2 ACS scan result with AP1 DFS channel
+	 */
+	if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc)) {
+		uint16_t con_ch;
+
+		con_ch = sme_get_concurrent_operation_channel(hal);
+		if (con_ch && wlan_reg_is_dfs_ch(mac_ctx->pdev, con_ch)) {
+			sap_ctx->channel = con_ch;
+			wlan_reg_set_channel_params(mac_ctx->pdev,
+						    sap_ctx->channel, 0,
+						    &sap_ctx->ch_params);
+		}
+	}
+
+	/*
+	 * Transition from SAP_INIT to SAP_STARTING
+	 * (both without substates)
+	 */
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("from state %s => %s"),
+		  "SAP_INIT", "SAP_STARTING");
+	/* Channel selected. Now can sap_goto_starting */
+	sap_ctx->fsm_state = SAP_STARTING;
+	/* Specify the channel */
+	sap_ctx->csr_roamProfile.ChannelInfo.numOfChannels =
+					1;
+	sap_ctx->csr_roamProfile.ChannelInfo.ChannelList =
+		&sap_ctx->csr_roamProfile.operationChannel;
+	sap_ctx->csr_roamProfile.operationChannel =
+		(uint8_t)sap_ctx->channel;
+	sap_ctx->csr_roamProfile.ch_params.ch_width =
+				sap_ctx->ch_params.ch_width;
+	sap_ctx->csr_roamProfile.ch_params.center_freq_seg0 =
+			sap_ctx->ch_params.center_freq_seg0;
+	sap_ctx->csr_roamProfile.ch_params.center_freq_seg1 =
+			sap_ctx->ch_params.center_freq_seg1;
+	sap_ctx->csr_roamProfile.ch_params.sec_ch_offset =
+			sap_ctx->ch_params.sec_ch_offset;
+	sap_get_cac_dur_dfs_region(sap_ctx,
+				   &sap_ctx->csr_roamProfile.cac_duration_ms,
+				   &sap_ctx->csr_roamProfile.dfs_regdomain);
+	sap_ctx->csr_roamProfile.beacon_tx_rate =
+			sap_ctx->beacon_tx_rate;
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("notify hostapd about channel selection: %d"),
+		  sap_ctx->channel);
+	sap_signal_hdd_event(sap_ctx, NULL,
+			     eSAP_CHANNEL_CHANGE_EVENT,
+			     (void *)eSAP_STATUS_SUCCESS);
+	sap_dfs_set_current_channel(sap_ctx);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, "%s: session: %d",
+		  __func__, sap_ctx->sessionId);
+
+	qdf_status = sme_roam_connect(hal, sap_ctx->sessionId,
+				      &sap_ctx->csr_roamProfile,
+				      &sap_ctx->csr_roamId);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Failed to issue sme_roam_connect", __func__);
+
+	return qdf_status;
+}
+
+/**
+ * sap_fsm_state_init() - utility function called from sap fsm
+ * @sap_ctx: SAP context
+ * @sap_event: SAP event buffer
+ * @mac_ctx: global MAC context
+ * @hal: HAL handle
+ *
+ * This function is called for state transition from "SAP_INIT"
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+sap_fsm_state_init(struct sap_context *sap_ctx,
+		   ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
+		   tHalHandle hal)
+{
+	uint32_t msg = sap_event->event;
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+
+	if (msg == eSAP_HDD_START_INFRA_BSS) {
+		/* init dfs channel nol */
+		sap_init_dfs_channel_nol_list(sap_ctx);
+
+		/*
+		 * Perform sme_ScanRequest. This scan request is post start bss
+		 * request so, set the third to false.
+		 */
+		qdf_status = sap_validate_chan(sap_ctx, false, true);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_ERROR,
+				  FL("channel is not valid!"));
+			goto exit;
+		}
+
+		/* Transition from SAP_INIT to SAP_STARTING */
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("new from state %s => %s: session:%d"),
+			  "SAP_INIT", "SAP_STARTING",
+			  sap_ctx->sessionId);
+
+		qdf_status = sap_goto_starting(sap_ctx, sap_event,
+					       mac_ctx, hal);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_ERROR,
+				  FL("sap_goto_starting failed"));
+	} else if (msg == eSAP_DFS_CHANNEL_CAC_START) {
+#ifdef CONFIG_VDEV_SM
+		sap_ctx->fsm_state = SAP_STARTING;
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+			  FL("from state SAP_INIT => SAP_STARTING"));
+#else
+		/*
+		 * No need of state check here, caller is expected to perform
+		 * the checks before sending the event
+		 */
+		sap_ctx->fsm_state = SAP_DFS_CAC_WAIT;
+
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+			FL("from state SAP_INIT => SAP_DFS_CAC_WAIT"));
+#endif
+		if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+			    FL("sapdfs: starting dfs cac timer on sapctx[%pK]"),
+			    sap_ctx);
+			sap_start_dfs_cac_timer(sap_ctx);
+		}
+
+		qdf_status = sap_cac_start_notify(hal);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("in state %s, event msg %d"),
+			  "SAP_INIT", msg);
+	}
+
+exit:
+	return qdf_status;
+}
+
+#ifndef CONFIG_VDEV_SM
+/**
+ * sap_fsm_state_dfs_cac_wait() - utility function called from sap fsm
+ * @sap_ctx: SAP context
+ * @sap_event: SAP event buffer
+ * @mac_ctx: global MAC context
+ * @hal: HAL handle
+ *
+ * This function is called for state transition from "SAP_DFS_CAC_WAIT"
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sap_fsm_state_dfs_cac_wait(struct sap_context *sap_ctx,
+			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
+			tHalHandle hal)
+{
+	uint32_t msg = sap_event->event;
+	struct csr_roam_info *roam_info =
+		(struct csr_roam_info *) (sap_event->params);
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+
+	if (msg == eSAP_DFS_CHANNEL_CAC_START) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("from state %s => %s"),
+			  "SAP_STARTING", "SAP_DFS_CAC_WAIT");
+		if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true)
+			sap_start_dfs_cac_timer(sap_ctx);
+		qdf_status = sap_cac_start_notify(hal);
+	} else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) {
+		uint8_t intf;
+
+		if (mac_ctx->sap.SapDfsInfo.target_channel) {
+			wlan_reg_set_channel_params(mac_ctx->pdev,
+				mac_ctx->sap.SapDfsInfo.target_channel, 0,
+				&sap_ctx->ch_params);
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				FL("Invalid target channel %d"),
+				mac_ctx->sap.SapDfsInfo.target_channel);
+			return qdf_status;
+		}
+
+		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+			struct sap_context *t_sap_ctx;
+			struct csr_roam_profile *profile;
+
+			t_sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context;
+			if (((QDF_SAP_MODE ==
+				 mac_ctx->sap.sapCtxList[intf].sapPersona) ||
+			     (QDF_P2P_GO_MODE ==
+				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
+			    t_sap_ctx != NULL &&
+			    t_sap_ctx->fsm_state != SAP_INIT) {
+				profile = &t_sap_ctx->csr_roamProfile;
+				if (!wlan_reg_is_passive_or_disable_ch(
+						mac_ctx->pdev,
+						profile->operationChannel))
+					continue;
+				t_sap_ctx->is_chan_change_inprogress = true;
+				/*
+				 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND:
+				 * A Radar is found on current DFS Channel
+				 * while in CAC WAIT period So, do a channel
+				 * switch to randomly selected  target channel.
+				 * Send the Channel change message to SME/PE.
+				 * sap_radar_found_status is set to 1
+				 */
+				wlansap_channel_change_request(
+					t_sap_ctx,
+					mac_ctx->sap.SapDfsInfo.target_channel);
+			}
+		}
+	} else if (msg == eSAP_DFS_CHANNEL_CAC_END) {
+		qdf_status = sap_cac_end_notify(hal, roam_info);
+	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
+		/* Transition from SAP_DFS_CAC_WAIT to SAP_STOPPING */
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("from state %s => %s"),
+			  "SAP_DFS_CAC_WAIT", "SAP_STOPPING");
+
+		/*
+		 * Stop the CAC timer only in following conditions
+		 * single AP: if there is a single AP then stop the timer
+		 * mulitple APs: incase of multiple APs, make sure that
+		 *               all APs are down.
+		 */
+		if (NULL == sap_find_valid_concurrent_session(hal)) {
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_INFO_MED,
+				  FL("sapdfs: no sessions are valid, stopping timer"));
+			sap_stop_dfs_cac_timer(sap_ctx);
+		}
+
+		sap_ctx->fsm_state = SAP_STOPPING;
+		qdf_status = sap_goto_stopping(sap_ctx);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("in state %s, invalid event msg %d"),
+			  "SAP_DFS_CAC_WAIT", msg);
+	}
+
+	return qdf_status;
+}
+#endif
+
+/**
+ * sap_fsm_state_starting() - utility function called from sap fsm
+ * @sap_ctx: SAP context
+ * @sap_event: SAP event buffer
+ * @mac_ctx: global MAC context
+ * @hal: HAL handle
+ *
+ * This function is called for state transition from "SAP_STARTING"
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx,
+			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
+			tHalHandle hal)
+{
+	uint32_t msg = sap_event->event;
+	struct csr_roam_info *roam_info =
+		(struct csr_roam_info *) (sap_event->params);
+	tSapDfsInfo *sap_dfs_info;
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	uint8_t is_dfs = false;
+
+	if (msg == eSAP_MAC_START_BSS_SUCCESS) {
+		/*
+		 * Transition from SAP_STARTING to SAP_STARTED
+		 * (both without substates)
+		 */
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("from state channel = %d %s => %s ch_width %d"),
+			  sap_ctx->channel, "SAP_STARTING", "SAP_STARTED",
+			  sap_ctx->ch_params.ch_width);
+		sap_ctx->fsm_state = SAP_STARTED;
+
+		/* Action code for transition */
+		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
+				eSAP_START_BSS_EVENT,
+				(void *) eSAP_STATUS_SUCCESS);
+
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("ap_ctx->ch_params.ch_width %d, channel %d"),
+			     sap_ctx->ch_params.ch_width,
+			     reg_get_channel_state(mac_ctx->pdev,
+						   sap_ctx->channel));
+
+		/*
+		 * The upper layers have been informed that AP is up and
+		 * running, however, the AP is still not beaconing, until
+		 * CAC is done if the operating channel is DFS
+		 */
+		if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) {
+			is_dfs = true;
+		} else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) {
+			if (wlan_reg_get_channel_state(mac_ctx->pdev,
+						sap_ctx->channel) ==
+			    CHANNEL_STATE_DFS ||
+			    wlan_reg_get_channel_state(mac_ctx->pdev,
+				    sap_ctx->ch_params.center_freq_seg1 -
+				SIR_80MHZ_START_CENTER_CH_DIFF) ==
+					CHANNEL_STATE_DFS)
+				is_dfs = true;
+		} else {
+			if (wlan_reg_get_channel_state(mac_ctx->pdev,
+						sap_ctx->channel) ==
+							CHANNEL_STATE_DFS)
+				is_dfs = true;
+		}
+
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("is_dfs %d"), is_dfs);
+		if (is_dfs) {
+			sap_dfs_info = &mac_ctx->sap.SapDfsInfo;
+			if ((false == sap_dfs_info->ignore_cac) &&
+			    (eSAP_DFS_DO_NOT_SKIP_CAC ==
+			    sap_dfs_info->cac_state) &&
+			    !sap_ctx->pre_cac_complete) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO_HIGH,
+					  FL("start cac timer"));
+#ifdef CONFIG_VDEV_SM
+				sap_ctx->fsm_state = SAP_STARTING;
+#else
+				/* Move the device in CAC_WAIT_STATE */
+				sap_ctx->fsm_state = SAP_DFS_CAC_WAIT;
+#endif
+				/*
+				 * Need to stop the OS transmit queues,
+				 * so that no traffic can flow down the stack
+				 */
+
+				/* Start CAC wait timer */
+				if (sap_dfs_info->is_dfs_cac_timer_running !=
+									true)
+					sap_start_dfs_cac_timer(sap_ctx);
+				qdf_status = sap_cac_start_notify(hal);
+
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO_HIGH,
+					FL("skip cac timer"));
+				wlansap_start_beacon_req(sap_ctx);
+			}
+		}
+	} else if (msg == eSAP_MAC_START_FAILS ||
+			msg == eSAP_HDD_STOP_INFRA_BSS) {
+
+#ifdef CONFIG_VDEV_SM
+		if (msg == eSAP_HDD_STOP_INFRA_BSS &&
+		    ((wlan_vdev_mlme_get_state(sap_ctx->vdev) ==
+		      WLAN_VDEV_S_DFS_CAC_WAIT) ||
+		     (wlan_vdev_mlme_get_substate(sap_ctx->vdev) ==
+		      WLAN_VDEV_SS_START_RESTART_PROGRESS))) {
+
+			/* Transition from SAP_STARTING to SAP_STOPPING */
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				  FL("In cac wait state from state %s => %s"),
+				  "SAP_STARTING", "SAP_STOPPING");
+			/*
+			 * Stop the CAC timer only in following conditions
+			 * single AP: if there is a single AP then stop timer
+			 * mulitple APs: incase of multiple APs, make sure that
+			 *               all APs are down.
+			 */
+			if (!sap_find_valid_concurrent_session(hal)) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO_MED,
+					  FL("sapdfs: no sessions are valid, stopping timer"));
+				sap_stop_dfs_cac_timer(sap_ctx);
+			}
+
+			sap_ctx->fsm_state = SAP_STOPPING;
+			qdf_status = sap_goto_stopping(sap_ctx);
+		} else
+#endif
+		{
+			/*
+			 * Transition from SAP_STARTING to SAP_INIT
+			 * (both without substates)
+			 */
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				  FL("from state %s => %s"),
+				  "SAP_STARTING", "SAP_INIT");
+
+			/* Advance outer statevar */
+			sap_ctx->fsm_state = SAP_INIT;
+			qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
+							  eSAP_START_BSS_EVENT,
+							  (void *)
+							  eSAP_STATUS_FAILURE);
+			qdf_status = sap_goto_init(sap_ctx);
+		}
+		/* Close the SME session */
+	} else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) {
+		/* The operating channel has changed, update hostapd */
+		sap_ctx->channel =
+			(uint8_t) mac_ctx->sap.SapDfsInfo.target_channel;
+
+		sap_ctx->fsm_state = SAP_STARTED;
+
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("from state %s => %s"),
+			  "SAP_STARTING", "SAP_STARTED");
+
+		/* Indicate change in the state to upper layers */
+		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
+				  eSAP_START_BSS_EVENT,
+				  (void *)eSAP_STATUS_SUCCESS);
+	} else
+#ifdef CONFIG_VDEV_SM
+	if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) {
+		uint8_t intf;
+
+		if (mac_ctx->sap.SapDfsInfo.target_channel) {
+			wlan_reg_set_channel_params(mac_ctx->pdev,
+						    mac_ctx->sap.SapDfsInfo.
+						    target_channel, 0,
+						    &sap_ctx->ch_params);
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid target channel %d"),
+				  mac_ctx->sap.SapDfsInfo.target_channel);
+			return qdf_status;
+		}
+
+		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+			struct sap_context *t_sap_ctx;
+			struct csr_roam_profile *profile;
+
+			t_sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context;
+			if (((QDF_SAP_MODE ==
+				 mac_ctx->sap.sapCtxList[intf].sapPersona) ||
+			     (QDF_P2P_GO_MODE ==
+				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
+			    t_sap_ctx && t_sap_ctx->fsm_state != SAP_INIT) {
+				profile = &t_sap_ctx->csr_roamProfile;
+				if (!wlan_reg_is_passive_or_disable_ch(
+						mac_ctx->pdev,
+						profile->operationChannel))
+					continue;
+				t_sap_ctx->is_chan_change_inprogress = true;
+				/*
+				 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND:
+				 * A Radar is found on current DFS Channel
+				 * while in CAC WAIT period So, do a channel
+				 * switch to randomly selected  target channel.
+				 * Send the Channel change message to SME/PE.
+				 * sap_radar_found_status is set to 1
+				 */
+				wlansap_channel_change_request(
+					t_sap_ctx,
+					mac_ctx->sap.SapDfsInfo.target_channel);
+			}
+		}
+	} else if (msg == eSAP_DFS_CHANNEL_CAC_END) {
+		qdf_status = sap_cac_end_notify(hal, roam_info);
+	} else
+#endif
+	{
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("in state %s, invalid event msg %d"),
+			  "SAP_STARTING", msg);
+	}
+
+	return qdf_status;
+}
+
+/**
+ * sap_fsm_state_started() - utility function called from sap fsm
+ * @sap_ctx: SAP context
+ * @sap_event: SAP event buffer
+ * @mac_ctx: global MAC context
+ *
+ * This function is called for state transition from "SAP_STARTED"
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx,
+			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx)
+{
+	uint32_t msg = sap_event->event;
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+
+	if (msg == eSAP_HDD_STOP_INFRA_BSS) {
+		/*
+		 * Transition from SAP_STARTED to SAP_STOPPING
+		 * (both without substates)
+		 */
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("from state %s => %s"),
+			  "SAP_STARTED", "SAP_STOPPING");
+		sap_ctx->fsm_state = SAP_STOPPING;
+		qdf_status = sap_goto_stopping(sap_ctx);
+	} else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) {
+		uint8_t intf;
+		if (!mac_ctx->sap.SapDfsInfo.target_channel) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				FL("Invalid target channel %d"),
+				mac_ctx->sap.SapDfsInfo.target_channel);
+			return qdf_status;
+		}
+
+		/*
+		 * Radar is seen on the current operating channel
+		 * send CSA IE for all associated stations
+		 * Request for CSA IE transmission
+		 */
+		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+			struct sap_context *temp_sap_ctx;
+			struct csr_roam_profile *profile;
+
+			if (((QDF_SAP_MODE ==
+				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
+			    (QDF_P2P_GO_MODE ==
+				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
+			    mac_ctx->sap.sapCtxList[intf].sap_context != NULL) {
+				temp_sap_ctx =
+				    mac_ctx->sap.sapCtxList[intf].sap_context;
+				/*
+				 * Radar won't come on non-dfs channel, so
+				 * no need to move them
+				 */
+				profile = &temp_sap_ctx->csr_roamProfile;
+				if (!wlan_reg_is_passive_or_disable_ch(
+						mac_ctx->pdev,
+						profile->operationChannel))
+					continue;
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO_MED,
+					  FL("sapdfs: Sending CSAIE for sapctx[%pK]"),
+					  temp_sap_ctx);
+#ifdef CONFIG_VDEV_SM
+				qdf_status = sme_csa_restart(mac_ctx,
+						       temp_sap_ctx->sessionId);
+#else
+
+				qdf_status =
+					wlansap_dfs_send_csa_ie_request(temp_sap_ctx);
+#endif
+			}
+		}
+	}
+#ifndef CONFIG_VDEV_SM
+	else if (eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START == msg) {
+		enum QDF_OPMODE persona;
+
+		if (!sap_ctx) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+					FL("Invalid sap_ctx"));
+			return qdf_status;
+		}
+
+		persona = mac_ctx->sap.sapCtxList[sap_ctx->sessionId].
+								sapPersona;
+
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+				FL("app trigger chan switch: mode:%d vdev:%d"),
+				persona, sap_ctx->sessionId);
+
+		if ((QDF_SAP_MODE == persona) || (QDF_P2P_GO_MODE == persona))
+			qdf_status = wlansap_dfs_send_csa_ie_request(sap_ctx);
+	}
+#endif
+	else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("in state %s, invalid event msg %d"),
+			  "SAP_STARTED", msg);
+	}
+
+	return qdf_status;
+}
+
+/**
+ * sap_fsm_state_stopping() - utility function called from sap fsm
+ * @sap_ctx: SAP context
+ * @sap_event: SAP event buffer
+ * @mac_ctx: global MAC context
+ *
+ * This function is called for state transition from "SAP_STOPPING"
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+sap_fsm_state_stopping(struct sap_context *sap_ctx,
+		       ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
+		       tHalHandle hal)
+{
+	uint32_t msg = sap_event->event;
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+
+	if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) {
+		/*
+		 * Transition from SAP_STOPPING to SAP_INIT
+		 * (both without substates)
+		 */
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("from state %s => %s"),
+			  "SAP_STOPPING", "SAP_INIT");
+		sap_ctx->fsm_state = SAP_INIT;
+
+		/* Close the SME session */
+		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
+					eSAP_STOP_BSS_EVENT,
+					(void *)eSAP_STATUS_SUCCESS);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL("in state %s, invalid event msg %d"),
+			  "SAP_STOPPING", msg);
+	}
+
+	return qdf_status;
+}
+
+/**
+ * sap_fsm() - SAP statem machine entry function
+ * @sap_ctx: SAP context
+ * @sap_event: SAP event
+ *
+ * SAP state machine entry function
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sap_fsm(struct sap_context *sap_ctx, ptWLAN_SAPEvent sap_event)
+{
+	/*
+	 * Retrieve the phy link state machine structure
+	 * from the sap_ctx value
+	 * state var that keeps track of state machine
+	 */
+	enum sap_fsm_state state_var = sap_ctx->fsm_state;
+	uint32_t msg = sap_event->event; /* State machine input event message */
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	struct mac_context *mac_ctx;
+	mac_handle_t mac_handle;
+
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAILURE;
+	}
+	mac_handle = MAC_HANDLE(mac_ctx);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+		  FL("sap_ctx=%pK, state_var=%d, msg=0x%x"),
+		  sap_ctx, state_var, msg);
+
+	switch (state_var) {
+	case SAP_INIT:
+		qdf_status = sap_fsm_state_init(sap_ctx, sap_event,
+						mac_ctx, mac_handle);
+		break;
+
+#ifndef CONFIG_VDEV_SM
+	case SAP_DFS_CAC_WAIT:
+		qdf_status = sap_fsm_state_dfs_cac_wait(sap_ctx, sap_event,
+							mac_ctx, mac_handle);
+		break;
+#endif
+
+	case SAP_STARTING:
+		qdf_status = sap_fsm_state_starting(sap_ctx, sap_event,
+						    mac_ctx, mac_handle);
+		break;
+
+	case SAP_STARTED:
+		qdf_status = sap_fsm_state_started(sap_ctx, sap_event,
+						   mac_ctx);
+		break;
+
+	case SAP_STOPPING:
+		qdf_status = sap_fsm_state_stopping(sap_ctx, sap_event,
+						    mac_ctx, mac_handle);
+		break;
+	}
+	return qdf_status;
+}
+
+eSapStatus
+sapconvert_to_csr_profile(tsap_config_t *pconfig_params, eCsrRoamBssType bssType,
+			  struct csr_roam_profile *profile)
+{
+	/* Create Roam profile for SoftAP to connect */
+	profile->BSSType = eCSR_BSS_TYPE_INFRA_AP;
+	profile->SSIDs.numOfSSIDs = 1;
+	profile->csrPersona = pconfig_params->persona;
+	profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch;
+
+	qdf_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId,
+		     sizeof(profile->SSIDs.SSIDList[0].SSID.ssId));
+
+	/* Flag to not broadcast the SSID information */
+	profile->SSIDs.SSIDList[0].ssidHidden =
+		pconfig_params->SSIDinfo.ssidHidden;
+
+	profile->SSIDs.SSIDList[0].SSID.length =
+		pconfig_params->SSIDinfo.ssid.length;
+	qdf_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId,
+		     pconfig_params->SSIDinfo.ssid.ssId,
+		     sizeof(pconfig_params->SSIDinfo.ssid.ssId));
+
+	profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+
+	if (pconfig_params->authType == eSAP_OPEN_SYSTEM) {
+		profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+	} else if (pconfig_params->authType == eSAP_SHARED_KEY) {
+		profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY;
+	} else {
+		profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH;
+	}
+
+	profile->AuthType.numEntries = 1;
+	profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+
+	/* Always set the Encryption Type */
+	profile->EncryptionType.numEntries = 1;
+	profile->EncryptionType.encryptionType[0] =
+		pconfig_params->RSNEncryptType;
+
+	profile->mcEncryptionType.numEntries = 1;
+	profile->mcEncryptionType.encryptionType[0] =
+		pconfig_params->mcRSNEncryptType;
+
+	if (pconfig_params->privacy & eSAP_SHARED_KEY) {
+		profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
+	}
+
+	profile->privacy = pconfig_params->privacy;
+	profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq;
+
+	if (pconfig_params->authType == eSAP_SHARED_KEY) {
+		profile->csr80211AuthType = eSIR_SHARED_KEY;
+	} else if (pconfig_params->authType == eSAP_OPEN_SYSTEM) {
+		profile->csr80211AuthType = eSIR_OPEN_SYSTEM;
+	} else {
+		profile->csr80211AuthType = eSIR_AUTO_SWITCH;
+	}
+
+	/* Initialize we are not going to use it */
+	profile->pWPAReqIE = NULL;
+	profile->nWPAReqIELength = 0;
+
+	if (profile->pRSNReqIE) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			  FL("pRSNReqIE already allocated."));
+		qdf_mem_free(profile->pRSNReqIE);
+		profile->pRSNReqIE = NULL;
+	}
+
+	/* set the RSN/WPA IE */
+	profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
+	if (pconfig_params->RSNWPAReqIELength) {
+		profile->pRSNReqIE =
+			qdf_mem_malloc(pconfig_params->RSNWPAReqIELength);
+		if (!profile->pRSNReqIE)
+			return eSAP_STATUS_FAILURE;
+
+		qdf_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE,
+			     pconfig_params->RSNWPAReqIELength);
+		profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
+	}
+
+	/* set the phyMode to accept anything */
+	/* Best means everything because it covers all the things we support */
+	/* eCSR_DOT11_MODE_BEST */
+	profile->phyMode = pconfig_params->SapHw_mode;
+
+	/* Configure beaconInterval */
+	profile->beaconInterval = (uint16_t) pconfig_params->beacon_int;
+
+	/* set DTIM period */
+	profile->dtimPeriod = pconfig_params->dtim_period;
+
+	/* set Uapsd enable bit */
+	profile->ApUapsdEnable = pconfig_params->UapsdEnable;
+
+	/* Enable protection parameters */
+	profile->protEnabled = pconfig_params->protEnabled;
+	profile->obssProtEnabled = pconfig_params->obssProtEnabled;
+	profile->cfg_protection = pconfig_params->ht_capab;
+
+	/* country code */
+	if (pconfig_params->countryCode[0])
+		qdf_mem_copy(profile->countryCode, pconfig_params->countryCode,
+			     WNI_CFG_COUNTRY_CODE_LEN);
+	profile->ieee80211d = pconfig_params->ieee80211d;
+	/* wps config info */
+	profile->wps_state = pconfig_params->wps_state;
+
+#ifdef WLAN_FEATURE_11W
+	/* MFP capable/required */
+	profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0;
+	profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0;
+#endif
+
+	if (pconfig_params->probeRespIEsBufferLen > 0 &&
+	    pconfig_params->pProbeRespIEsBuffer != NULL) {
+		profile->addIeParams.probeRespDataLen =
+			pconfig_params->probeRespIEsBufferLen;
+		profile->addIeParams.probeRespData_buff =
+			pconfig_params->pProbeRespIEsBuffer;
+	} else {
+		profile->addIeParams.probeRespDataLen = 0;
+		profile->addIeParams.probeRespData_buff = NULL;
+	}
+	/*assoc resp IE */
+	if (pconfig_params->assocRespIEsLen > 0 &&
+	    pconfig_params->pAssocRespIEsBuffer != NULL) {
+		profile->addIeParams.assocRespDataLen =
+			pconfig_params->assocRespIEsLen;
+		profile->addIeParams.assocRespData_buff =
+			pconfig_params->pAssocRespIEsBuffer;
+	} else {
+		profile->addIeParams.assocRespDataLen = 0;
+		profile->addIeParams.assocRespData_buff = NULL;
+	}
+
+	if (pconfig_params->probeRespBcnIEsLen > 0 &&
+	    pconfig_params->pProbeRespBcnIEsBuffer != NULL) {
+		profile->addIeParams.probeRespBCNDataLen =
+			pconfig_params->probeRespBcnIEsLen;
+		profile->addIeParams.probeRespBCNData_buff =
+			pconfig_params->pProbeRespBcnIEsBuffer;
+	} else {
+		profile->addIeParams.probeRespBCNDataLen = 0;
+		profile->addIeParams.probeRespBCNData_buff = NULL;
+	}
+
+	if (pconfig_params->supported_rates.numRates) {
+		qdf_mem_copy(profile->supported_rates.rate,
+				pconfig_params->supported_rates.rate,
+				pconfig_params->supported_rates.numRates);
+		profile->supported_rates.numRates =
+			pconfig_params->supported_rates.numRates;
+	}
+
+	if (pconfig_params->extended_rates.numRates) {
+		qdf_mem_copy(profile->extended_rates.rate,
+				pconfig_params->extended_rates.rate,
+				pconfig_params->extended_rates.numRates);
+		profile->extended_rates.numRates =
+			pconfig_params->extended_rates.numRates;
+	}
+
+	profile->chan_switch_hostapd_rate_enabled =
+		pconfig_params->chan_switch_hostapd_rate_enabled;
+
+	return eSAP_STATUS_SUCCESS;     /* Success. */
+}
+
+void sap_free_roam_profile(struct csr_roam_profile *profile)
+{
+	if (profile->pRSNReqIE) {
+		qdf_mem_free(profile->pRSNReqIE);
+		profile->pRSNReqIE = NULL;
+	}
+}
+
+void sap_sort_mac_list(struct qdf_mac_addr *macList, uint8_t size)
+{
+	uint8_t outer, inner;
+	struct qdf_mac_addr temp;
+	int32_t nRes = -1;
+
+	if ((NULL == macList) || (size > 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"), size);
+		return;
+	}
+
+	for (outer = 0; outer < size; outer++) {
+		for (inner = 0; inner < size - 1; inner++) {
+			nRes =
+				qdf_mem_cmp((macList + inner)->bytes,
+						 (macList + inner + 1)->bytes,
+						 QDF_MAC_ADDR_SIZE);
+			if (nRes > 0) {
+				qdf_mem_copy(temp.bytes,
+					     (macList + inner + 1)->bytes,
+					     QDF_MAC_ADDR_SIZE);
+				qdf_mem_copy((macList + inner + 1)->bytes,
+					     (macList + inner)->bytes,
+					     QDF_MAC_ADDR_SIZE);
+				qdf_mem_copy((macList + inner)->bytes,
+					     temp.bytes, QDF_MAC_ADDR_SIZE);
+			}
+		}
+	}
+}
+
+bool
+sap_search_mac_list(struct qdf_mac_addr *macList,
+		    uint8_t num_mac, uint8_t *peerMac,
+		    uint8_t *index)
+{
+	int32_t nRes = -1;
+	int8_t nStart = 0, nEnd, nMiddle;
+
+	nEnd = num_mac - 1;
+
+	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 false;
+	}
+
+	while (nStart <= nEnd) {
+		nMiddle = (nStart + nEnd) / 2;
+		nRes =
+			qdf_mem_cmp(&macList[nMiddle], peerMac,
+					 QDF_MAC_ADDR_SIZE);
+
+		if (0 == nRes) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+				  "search SUCC");
+			/* "index equals NULL" means the caller does not need the */
+			/* index value of the peerMac being searched */
+			if (index != NULL) {
+				*index = (uint8_t) nMiddle;
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO_HIGH, "index %d",
+					  *index);
+			}
+			return true;
+		}
+		if (nRes < 0)
+			nStart = nMiddle + 1;
+		else
+			nEnd = nMiddle - 1;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "search not succ");
+	return false;
+}
+
+void sap_add_mac_to_acl(struct qdf_mac_addr *macList,
+			uint8_t *size, uint8_t *peerMac)
+{
+	int32_t nRes = -1;
+	int i;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "add acl entered");
+
+	if (NULL == macList || *size > MAX_ACL_MAC_ADDRESS) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			FL("either buffer is NULL or size = %d is incorrect."),
+			*size);
+		return;
+	}
+
+	for (i = ((*size) - 1); i >= 0; i--) {
+		nRes =
+			qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE);
+		if (nRes > 0) {
+			/* Move alphabetically greater mac addresses one index down to allow for insertion
+			   of new mac in sorted order */
+			qdf_mem_copy((macList + i + 1)->bytes,
+				     (macList + i)->bytes, QDF_MAC_ADDR_SIZE);
+		} else {
+			break;
+		}
+	}
+	/* This should also take care of if the element is the first to be added in the list */
+	qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE);
+	/* increment the list size */
+	(*size)++;
+}
+
+void sap_remove_mac_from_acl(struct qdf_mac_addr *macList,
+			     uint8_t *size, uint8_t index)
+{
+	int i;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "remove acl entered");
+	/*
+	 * Return if the list passed is empty. Ideally this should never happen
+	 * since this funcn is always called after sap_search_mac_list to get
+	 * the index of the mac addr to be removed and this will only get
+	 * called if the search is successful. Still no harm in having the check
+	 */
+	if ((macList == NULL) || (*size == 0) ||
+					(*size > MAX_ACL_MAC_ADDRESS)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			FL("either buffer is NULL or size %d is incorrect."),
+			*size);
+		return;
+	}
+	for (i = index; i < ((*size) - 1); i++) {
+		/* Move mac addresses starting from "index" passed one index up to delete the void
+		   created by deletion of a mac address in ACL */
+		qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes,
+			     QDF_MAC_ADDR_SIZE);
+	}
+	/* The last space should be made empty since all mac addesses moved one step up */
+	qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE);
+	/* reduce the list size by 1 */
+	(*size)--;
+}
+
+void sap_print_acl(struct qdf_mac_addr *macList, uint8_t size)
+{
+	int i;
+	uint8_t *macArray;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "print acl entered");
+
+	if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "In %s, either buffer is NULL or size %d is incorrect.",
+			  __func__, size);
+		return;
+	}
+
+	for (i = 0; i < size; i++) {
+		macArray = (macList + i)->bytes;
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "** ACL entry %i - " MAC_ADDRESS_STR, i,
+			  MAC_ADDR_ARRAY(macArray));
+	}
+	return;
+}
+
+QDF_STATUS sap_is_peer_mac_allowed(struct sap_context *sapContext,
+				   uint8_t *peerMac)
+{
+	if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode)
+		return QDF_STATUS_SUCCESS;
+
+	if (sap_search_mac_list
+		    (sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL))
+		return QDF_STATUS_SUCCESS;
+
+	if (sap_search_mac_list
+		    (sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "In %s, Peer " MAC_ADDRESS_STR " in deny list",
+			  __func__, MAC_ADDR_ARRAY(peerMac));
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* A new station CAN associate, unless in deny list. Less stringent mode */
+	if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode)
+		return QDF_STATUS_SUCCESS;
+
+	/* A new station CANNOT associate, unless in accept list. More stringent mode */
+	if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "In %s, Peer " MAC_ADDRESS_STR
+			  " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED",
+			  __func__, MAC_ADDR_ARRAY(peerMac));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* The new STA is neither in accept list nor in deny list. In this case, deny the association
+	 * but send a wifi event notification indicating the mac address being denied
+	 */
+	if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode) {
+		sap_signal_hdd_event(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN,
+				     (void *) peerMac);
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "In %s, Peer " MAC_ADDRESS_STR
+			  " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY",
+			  __func__, MAC_ADDR_ARRAY(peerMac));
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef SOFTAP_CHANNEL_RANGE
+/**
+ * sap_get_channel_list() - get the list of channels
+ * @sap_ctx: sap context
+ * @ch_list: pointer to channel list array
+ * @num_ch: pointer to number of channels.
+ *
+ * This function populates the list of channels for scanning.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sap_get_channel_list(struct sap_context *sap_ctx,
+				       uint8_t **ch_list,
+				       uint8_t *num_ch)
+{
+	uint8_t loop_count;
+	uint8_t *list;
+	uint8_t ch_count;
+	uint8_t start_ch_num, band_start_ch;
+	uint8_t end_ch_num, band_end_ch;
+	uint32_t en_lte_coex;
+#ifdef FEATURE_WLAN_CH_AVOID
+	uint8_t i;
+#endif
+	struct mac_context *mac_ctx;
+	tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
+	uint16_t ch_width;
+
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		*num_ch = 0;
+		*ch_list = NULL;
+		return QDF_STATUS_E_FAULT;
+	}
+
+	start_ch_num = sap_ctx->acs_cfg->start_ch;
+	end_ch_num = sap_ctx->acs_cfg->end_ch;
+	ch_width = sap_ctx->acs_cfg->ch_width;
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+		  FL("startChannel %d, EndChannel %d, ch_width %d, HW:%d"),
+		     start_ch_num, end_ch_num, ch_width,
+		     sap_ctx->acs_cfg->hw_mode);
+
+	wlansap_extend_to_acs_range(MAC_HANDLE(mac_ctx),
+				    &start_ch_num, &end_ch_num,
+				    &band_start_ch, &band_end_ch);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			  FL("expanded startChannel %d,EndChannel %d"),
+			  start_ch_num, end_ch_num);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			  FL("band_start_ch %d, band_end_ch %d"),
+			  band_start_ch, band_end_ch);
+
+	en_lte_coex = mac_ctx->mlme_cfg->sap_cfg.enable_lte_coex;
+
+	/* Check if LTE coex is enabled and 2.4GHz is selected */
+	if (en_lte_coex && (band_start_ch == CHAN_ENUM_1) &&
+	    (band_end_ch == CHAN_ENUM_14)) {
+		/* Set 2.4GHz upper limit to channel 9 for LTE COEX */
+		band_end_ch = CHAN_ENUM_9;
+	}
+
+	/* Allocate the max number of channel supported */
+	list = qdf_mem_malloc(NUM_5GHZ_CHANNELS + NUM_24GHZ_CHANNELS);
+	if (!list) {
+		*num_ch = 0;
+		*ch_list = NULL;
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	/* Search for the Active channels in the given range */
+	ch_count = 0;
+	for (loop_count = band_start_ch; loop_count <= band_end_ch;
+	     loop_count++) {
+		/* go to next channel if rf_channel is out of range */
+		if ((start_ch_num > WLAN_REG_CH_NUM(loop_count)) ||
+		    (end_ch_num < WLAN_REG_CH_NUM(loop_count)))
+			continue;
+		/*
+		 * go to next channel if none of these condition pass
+		 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE
+		 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE
+		 */
+		if (!(((true == mac_ctx->scan.fEnableDFSChnlScan) &&
+		      wlan_reg_get_channel_state(mac_ctx->pdev,
+						 WLAN_REG_CH_NUM(loop_count)))
+		      ||
+		    ((false == mac_ctx->scan.fEnableDFSChnlScan) &&
+		     (CHANNEL_STATE_ENABLE ==
+		      wlan_reg_get_channel_state(mac_ctx->pdev,
+						 WLAN_REG_CH_NUM(loop_count)))
+		     )))
+			continue;
+
+		/*
+		 * Skip the channels which are not in ACS config from user
+		 * space
+		 */
+		if (SAP_CHANNEL_NOT_SELECTED ==
+			sap_channel_in_acs_channel_list(
+				WLAN_REG_CH_NUM(loop_count),
+				sap_ctx, &spect_info_obj))
+			continue;
+		/* Dont scan DFS channels in case of MCC disallowed
+		 * As it can result in SAP starting on DFS channel
+		 * resulting  MCC on DFS channel
+		 */
+		if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
+		    WLAN_REG_CH_NUM(loop_count)) &&
+		    policy_mgr_disallow_mcc(mac_ctx->psoc,
+		    WLAN_REG_CH_NUM(loop_count)))
+			continue;
+
+		/* Dont scan ETSI13 SRD channels if the ETSI13 SRD channels
+		 * are not enabled in master mode
+		 */
+		if (!wlan_reg_is_etsi13_srd_chan_allowed_master_mode(mac_ctx->
+								     pdev) &&
+		    wlan_reg_is_etsi13_srd_chan(mac_ctx->pdev,
+						WLAN_REG_CH_NUM(loop_count)))
+			continue;
+		/*
+		 * If we have any 5Ghz channel in the channel list
+		 * and bw is 40/80/160 Mhz then we don't want SAP to
+		 * come up in 2.4Ghz as for 40Mhz, 2.4Ghz channel is
+		 * not preferred and 80/160Mhz is not allowed for 2.4Ghz
+		 * band. So, don't even scan on 2.4Ghz channels if bw is
+		 * 40/80/160Mhz and channel list has any 5Ghz channel.
+		 */
+		if (end_ch_num >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
+		    ((ch_width == CH_WIDTH_40MHZ) ||
+		     (ch_width == CH_WIDTH_80MHZ) ||
+		     (ch_width == CH_WIDTH_80P80MHZ) ||
+		     (ch_width == CH_WIDTH_160MHZ))) {
+			if (WLAN_REG_CH_NUM(loop_count) >=
+			    WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
+			    WLAN_REG_CH_NUM(loop_count) <=
+			    WLAN_REG_CH_NUM(CHAN_ENUM_14))
+				continue;
+		}
+
+#ifdef FEATURE_WLAN_CH_AVOID
+		for (i = 0; i < NUM_CHANNELS; i++) {
+			if (safe_channels[i].channelNumber ==
+			     WLAN_REG_CH_NUM(loop_count)) {
+				/* Check if channel is safe */
+				if (true == safe_channels[i].isSafe) {
+#endif
+#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
+		uint8_t ch;
+
+		ch = WLAN_REG_CH_NUM(loop_count);
+		if ((sap_ctx->acs_cfg->skip_scan_status ==
+			eSAP_DO_PAR_ACS_SCAN)) {
+		    if ((ch >= sap_ctx->acs_cfg->skip_scan_range1_stch &&
+			 ch <= sap_ctx->acs_cfg->skip_scan_range1_endch) ||
+			(ch >= sap_ctx->acs_cfg->skip_scan_range2_stch &&
+			 ch <= sap_ctx->acs_cfg->skip_scan_range2_endch)) {
+			list[ch_count] =
+				WLAN_REG_CH_NUM(loop_count);
+			ch_count++;
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				QDF_TRACE_LEVEL_INFO,
+				FL("%d %d added to ACS ch range"),
+				ch_count, ch);
+		    } else {
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				QDF_TRACE_LEVEL_INFO_HIGH,
+				FL("%d %d skipped from ACS ch range"),
+				ch_count, ch);
+		    }
+		} else {
+			list[ch_count] =
+				WLAN_REG_CH_NUM(loop_count);
+			ch_count++;
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				QDF_TRACE_LEVEL_INFO,
+				FL("%d %d added to ACS ch range"),
+				ch_count, ch);
+		}
+#else
+		list[ch_count] = WLAN_REG_CH_NUM(loop_count);
+		ch_count++;
+#endif
+#ifdef FEATURE_WLAN_CH_AVOID
+				}
+				break;
+			}
+		}
+#endif
+	}
+	if (0 == ch_count) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+		    FL("No active channels present for the current region"));
+		/*
+		 * LTE COEX: channel range outside the restricted 2.4GHz
+		 * band limits
+		 */
+		if (en_lte_coex && (start_ch_num > band_end_ch))
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
+				FL("SAP can't be started as due to LTE COEX"));
+	}
+
+	/* return the channel list and number of channels to scan */
+	*num_ch = ch_count;
+	if (ch_count != 0) {
+		*ch_list = list;
+	} else {
+		*ch_list = NULL;
+		qdf_mem_free(list);
+	}
+
+	for (loop_count = 0; loop_count < ch_count; loop_count++) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			FL("channel number: %d"), list[loop_count]);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef DFS_COMPONENT_ENABLE
+uint8_t sap_indicate_radar(struct sap_context *sap_ctx)
+{
+	uint8_t target_channel = 0;
+	struct mac_context *mac;
+
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("null sap_ctx"));
+		return 0;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return 0;
+	}
+
+	/*
+	 * SAP needs to generate Channel Switch IE
+	 * if the radar is found in the STARTED state
+	 */
+	if (sap_ctx->fsm_state == SAP_STARTED)
+		mac->sap.SapDfsInfo.csaIERequired = true;
+
+	if (sap_ctx->csr_roamProfile.disableDFSChSwitch)
+		return sap_ctx->channel;
+
+	/* set the Radar Found flag in SapDfsInfo */
+	mac->sap.SapDfsInfo.sap_radar_found_status = true;
+
+	if (sap_ctx->chan_before_pre_cac) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			FL("sapdfs: set chan before pre cac %d as target chan"),
+			sap_ctx->chan_before_pre_cac);
+		return sap_ctx->chan_before_pre_cac;
+	}
+
+	if (sap_ctx->vendor_acs_dfs_lte_enabled && (QDF_STATUS_SUCCESS ==
+	    sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_NEXT_CHANNEL_REQ,
+	    (void *) eSAP_STATUS_SUCCESS)))
+		return 0;
+
+	target_channel = sap_random_channel_sel(sap_ctx);
+	if (!target_channel)
+		sap_signal_hdd_event(sap_ctx, NULL,
+		eSAP_DFS_NO_AVAILABLE_CHANNEL, (void *) eSAP_STATUS_SUCCESS);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
+		  FL("sapdfs: New selected target channel is [%d]"),
+		  target_channel);
+
+	return target_channel;
+}
+#endif
+
+/*
+ * CAC timer callback function.
+ * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm().
+ */
+void sap_dfs_cac_timer_callback(void *data)
+{
+	struct sap_context *sapContext;
+	tWLAN_SAPEvent sapEvent;
+	tHalHandle hHal = (tHalHandle) data;
+	tpAniSirGlobal pMac;
+
+	if (NULL == hHal) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "In %s invalid hHal", __func__);
+		return;
+	}
+	pMac = PMAC_STRUCT(hHal);
+	sapContext = sap_find_cac_wait_session(hHal);
+	if (NULL == sapContext) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"%s: no SAP contexts in wait state", __func__);
+		return;
+	}
+
+	/*
+	 * SAP may not be in CAC wait state, when the timer runs out.
+	 * if following flag is set, then timer is in initialized state,
+	 * destroy timer here.
+	 */
+	if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) {
+		if (!sapContext->dfs_cac_offload)
+			qdf_mc_timer_destroy(
+				&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
+		pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
+	}
+
+	/*
+	 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm
+	 */
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+			"sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%pK]",
+			sapContext->channel, sapContext);
+
+	sapEvent.event = eSAP_DFS_CHANNEL_CAC_END;
+	sapEvent.params = 0;
+	sapEvent.u1 = 0;
+	sapEvent.u2 = 0;
+
+	sap_fsm(sapContext, &sapEvent);
+}
+
+/*
+ * Function to stop the DFS CAC Timer
+ */
+static int sap_stop_dfs_cac_timer(struct sap_context *sap_ctx)
+{
+	struct mac_context *mac;
+
+	if (!sap_ctx)
+		return 0;
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return 0;
+	}
+
+	if (sap_ctx->dfs_cac_offload) {
+		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
+		return 0;
+	}
+
+	if (QDF_TIMER_STATE_RUNNING !=
+	    qdf_mc_timer_get_current_state(&mac->sap.SapDfsInfo.
+					   sap_dfs_cac_timer)) {
+		return 0;
+	}
+
+	qdf_mc_timer_stop(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
+	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
+	qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
+
+	return 0;
+}
+
+/*
+ * Function to start the DFS CAC Timer
+ * when SAP is started on a DFS channel
+ */
+static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx)
+{
+	QDF_STATUS status;
+	uint32_t cac_dur;
+	struct mac_context *mac;
+	enum dfs_reg dfs_region;
+
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: null sap_ctx", __func__);
+		return 0;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return 0;
+	}
+
+	if (sap_ctx->dfs_cac_offload) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: cac timer offloaded to firmware", __func__);
+		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
+#ifdef CONFIG_VDEV_SM
+		status =
+		     wlan_vdev_mlme_sm_deliver_evt(sap_ctx->vdev,
+						   WLAN_VDEV_SM_EV_DFS_CAC_WAIT,
+						   0, NULL);
+		if (QDF_IS_STATUS_ERROR(status))
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  "%s: failed to post WLAN_VDEV_SM_EV_DFS_CAC_WAIT",
+				  __func__);
+#endif
+		return 1;
+	}
+
+	sap_get_cac_dur_dfs_region(sap_ctx, &cac_dur, &dfs_region);
+	if (0 == cac_dur)
+		return 0;
+
+#ifdef QCA_WIFI_NAPIER_EMULATION
+	cac_dur = cac_dur / 100;
+#endif
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
+		  "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH-%d, CAC_DUR-%d sec",
+		  sap_ctx->channel, cac_dur / 1000);
+
+	qdf_mc_timer_init(&mac->sap.SapDfsInfo.sap_dfs_cac_timer,
+			  QDF_TIMER_TYPE_SW,
+			  sap_dfs_cac_timer_callback, MAC_HANDLE(mac));
+
+	/* Start the CAC timer */
+	status = qdf_mc_timer_start(&mac->sap.SapDfsInfo.sap_dfs_cac_timer,
+			cac_dur);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: failed to start cac timer", __func__);
+		goto destroy_timer;
+	}
+
+	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
+#ifdef CONFIG_VDEV_SM
+	status = wlan_vdev_mlme_sm_deliver_evt(sap_ctx->vdev,
+					       WLAN_VDEV_SM_EV_DFS_CAC_WAIT,
+					       0, NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: failed to post WLAN_VDEV_SM_EV_DFS_CAC_WAIT",
+			  __func__);
+		qdf_mc_timer_stop(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
+		goto destroy_timer;
+	}
+#endif
+	return 0;
+
+destroy_timer:
+	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
+	qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
+
+	return 1;
+}
+
+/*
+ * This function initializes the NOL list
+ * parameters required to track the radar
+ * found DFS channels in the current Reg. Domain .
+ */
+QDF_STATUS sap_init_dfs_channel_nol_list(struct sap_context *sap_ctx)
+{
+	struct mac_context *mac;
+
+	if (!sap_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid SAP context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	utils_dfs_init_nol(mac->pdev);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * This function will calculate how many interfaces
+ * have sap persona and returns total number of sap persona.
+ */
+uint8_t sap_get_total_number_sap_intf(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint8_t intf = 0;
+	uint8_t intf_count = 0;
+
+	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
+		    ||
+		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
+		    && pMac->sap.sapCtxList[intf].sap_context != NULL) {
+			intf_count++;
+		}
+	}
+	return intf_count;
+}
+
+/**
+ * is_concurrent_sap_ready_for_channel_change() - to check all saps are ready
+ *						  for channel change
+ * @hHal: HAL pointer
+ * @sapContext: sap context for which this function has been called
+ *
+ * This function will find the concurrent sap context apart from
+ * passed sap context and return its channel change ready status
+ *
+ *
+ * Return: true if other SAP personas are ready to channel switch else false
+ */
+bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal,
+						struct sap_context *sapContext)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct sap_context *sap_context;
+	uint8_t intf = 0;
+
+	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
+		    ||
+		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
+		    && pMac->sap.sapCtxList[intf].sap_context != NULL) {
+			sap_context =
+				pMac->sap.sapCtxList[intf].sap_context;
+			if (sap_context == sapContext) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  FL("sapCtx matched [%pK]"),
+					  sapContext);
+				continue;
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  FL
+						  ("concurrent sapCtx[%pK] didn't matche with [%pK]"),
+					  sap_context, sapContext);
+				return sap_context->is_sap_ready_for_chnl_chng;
+			}
+		}
+	}
+	return false;
+}
+
+/**
+ * sap_is_conc_sap_doing_scc_dfs() - check if conc SAPs are doing SCC DFS
+ * @hal: pointer to hal
+ * @sap_context: current SAP persona's channel
+ *
+ * If provided SAP's channel is DFS then Loop through each SAP or GO persona and
+ * check if other beaconing entity's channel is same DFS channel. If they are
+ * same then concurrent sap is doing SCC DFS.
+ *
+ * Return: true if two or more beaconing entitity doing SCC DFS else false
+ */
+bool sap_is_conc_sap_doing_scc_dfs(tHalHandle hal,
+				   struct sap_context *given_sapctx)
+{
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct sap_context *sap_ctx;
+	uint8_t intf = 0, scc_dfs_counter = 0;
+
+	/*
+	 * current SAP persona's channel itself is not DFS, so no need to check
+	 * what other persona's channel is
+	 */
+	if (!wlan_reg_is_dfs_ch(mac->pdev,
+			given_sapctx->csr_roamProfile.operationChannel)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			  FL("skip this loop as provided channel is non-dfs"));
+		return false;
+	}
+
+	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+		if ((QDF_SAP_MODE != mac->sap.sapCtxList[intf].sapPersona) &&
+		    (QDF_P2P_GO_MODE != mac->sap.sapCtxList[intf].sapPersona))
+			continue;
+		if (!mac->sap.sapCtxList[intf].sap_context)
+			continue;
+		sap_ctx = mac->sap.sapCtxList[intf].sap_context;
+		/* if same SAP contexts then skip to next context */
+		if (sap_ctx == given_sapctx)
+			continue;
+		if (given_sapctx->csr_roamProfile.operationChannel ==
+				sap_ctx->csr_roamProfile.operationChannel)
+			scc_dfs_counter++;
+	}
+
+	/* Found atleast two of the beaconing entities doing SCC DFS */
+	if (scc_dfs_counter)
+		return true;
+
+	return false;
+}
diff --git a/core/sap/src/sap_fsm_ext.h b/core/sap/src/sap_fsm_ext.h
new file mode 100644
index 0000000..e3a37ab
--- /dev/null
+++ b/core/sap/src/sap_fsm_ext.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014, 2018 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.
+ */
+
+/* This file is generated from btampFsm.cdd - do not edit manually*/
+/* Generated on: Thu Oct 16 15:40:39 PDT 2008 */
+
+#ifndef __SAPFSM_EXT_H__
+#define __SAPFSM_EXT_H__
+
+/* Events that can be sent to the SAP state-machine */
+typedef enum {
+	eSAP_TIMER_CONNECT_ACCEPT_TIMEOUT = 0U,
+	eSAP_MAC_CONNECT_COMPLETED,
+	eSAP_MAC_CONNECT_INDICATION,
+	eSAP_MAC_KEY_SET_SUCCESS,
+	eSAP_RSN_FAILURE,
+	eSAP_HDD_START_INFRA_BSS,
+	eSAP_MAC_READY_FOR_CONNECTIONS,
+	eSAP_MAC_START_BSS_SUCCESS,
+	eSAP_MAC_START_BSS_FAILURE,
+	eSAP_RSN_SUCCESS,
+	eSAP_MAC_START_FAILS,
+	eSAP_HDD_STOP_INFRA_BSS,
+	eSAP_WRITE_REMOTE_AMP_ASSOC,
+	eSAP_DFS_CHANNEL_CAC_START,
+	eSAP_DFS_CHANNEL_CAC_RADAR_FOUND,
+	eSAP_DFS_CHANNEL_CAC_END,
+	eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START,
+	eSAP_OPERATING_CHANNEL_CHANGED,
+#ifndef CONFIG_VDEV_SM
+	eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START,
+#endif
+	eSAP_NO_MSG
+} eSapMsg_t;
+
+#endif
diff --git a/core/sap/src/sap_internal.h b/core/sap/src/sap_internal.h
new file mode 100644
index 0000000..3c1bb83
--- /dev/null
+++ b/core/sap/src/sap_internal.h
@@ -0,0 +1,566 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef WLAN_QCT_WLANSAP_INTERNAL_H
+#define WLAN_QCT_WLANSAP_INTERNAL_H
+
+/*
+ * This file contains the internal API exposed by the wlan SAP PAL layer
+ * module.
+ */
+
+#include "cds_api.h"
+#include "cds_packet.h"
+
+/* Pick up the CSR API definitions */
+#include "csr_api.h"
+#include "sap_api.h"
+#include "sap_fsm_ext.h"
+#include "sap_ch_select.h"
+#include <wlan_scan_public_structs.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include "wlan_vdev_mlme_api.h"
+
+/*----------------------------------------------------------------------------
+ * Preprocessor Definitions and Constants
+ * -------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------------------------------
+ *  Defines
+ * -------------------------------------------------------------------------*/
+/* DFS Non Occupancy Period =30 minutes, in microseconds */
+#define SAP_DFS_NON_OCCUPANCY_PERIOD      (30 * 60 * 1000 * 1000)
+
+#define SAP_DEBUG
+/* Used to enable or disable security on the BT-AMP link */
+#define WLANSAP_SECURITY_ENABLED_STATE true
+
+/* MAC Address length */
+#define ANI_EAPOL_KEY_RSN_NONCE_SIZE      32
+
+#define IS_ETSI_WEATHER_CH(_ch)   ((_ch >= 120) && (_ch <= 130))
+#define IS_CH_BONDING_WITH_WEATHER_CH(_ch)   (_ch == 116)
+#define IS_CHAN_JAPAN_W53(_ch)    ((_ch >= 52)  && (_ch <= 64))
+#define IS_CHAN_JAPAN_INDOOR(_ch) ((_ch >= 36)  && (_ch <= 64))
+#define IS_CHAN_JAPAN_OUTDOOR(_ch)((_ch >= 100) && (_ch <= 140))
+#define DEFAULT_CAC_TIMEOUT (60 * 1000) /* msecs - 1 min */
+#define ETSI_WEATHER_CH_CAC_TIMEOUT (10 * 60 * 1000)    /* msecs - 10 min */
+#define SAP_CHAN_PREFERRED_INDOOR  1
+#define SAP_CHAN_PREFERRED_OUTDOOR 2
+
+/*----------------------------------------------------------------------------
+ *  Typedefs
+ * -------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------
+ *  Type Declarations - For internal SAP context information
+ * -------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------
+ *  Opaque SAP context Type Declaration
+ * -------------------------------------------------------------------------*/
+/* We were only using this syntax, when this was truly opaque. */
+/* (I.E., it was defined in a different file.) */
+
+/**
+ * enum sap_fsm_state - SAP FSM states for Access Point role
+ * @SAP_INIT: init state
+ * @SAP_DFS_CAC_WAIT: cac wait
+ * @SAP_STARTING: starting phase
+ * @SAP_STARTED: up and running
+ * @SAP_STOPPING: about to stop and transitions to init
+ */
+enum sap_fsm_state {
+	SAP_INIT,
+#ifndef CONFIG_VDEV_SM
+	SAP_DFS_CAC_WAIT,
+#endif
+	SAP_STARTING,
+	SAP_STARTED,
+	SAP_STOPPING
+};
+
+/*----------------------------------------------------------------------------
+ *  SAP context Data Type Declaration
+ * -------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------
+ *  Type Declarations - QOS related
+ * -------------------------------------------------------------------------*/
+/* SAP QOS config */
+typedef struct sSapQosCfg {
+	uint8_t WmmIsEnabled;
+} tSapQosCfg;
+
+typedef struct sSapAcsChannelInfo {
+	uint32_t channelNum;
+	uint32_t weight;
+} tSapAcsChannelInfo;
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+/*
+ * In a setup having two MDM both operating in AP+AP MCC scenario
+ * if both the AP decides to use same or close channel set, CTS to
+ * self, mechanism is causing issues with connectivity. For this, its
+ * proposed that 2nd MDM devices which comes up later should detect
+ * presence of first MDM device via special Q2Q IE present in becon
+ * and avoid those channels mentioned in IE.
+ *
+ * Following struct will keep this info in sapCtx struct, and will be used
+ * to avoid such channels in Random Channel Select in case of radar ind.
+ */
+struct sap_avoid_channels_info {
+	bool       present;
+	uint8_t    channels[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+};
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+struct sap_context {
+
+	/* Include the current channel of AP */
+	uint32_t channel;
+	uint32_t secondary_ch;
+
+	/* Include the SME(CSR) sessionId here */
+	uint8_t sessionId;
+
+	/* vdev object corresponding to sessionId */
+	struct wlan_objmgr_vdev *vdev;
+
+	/* Include the associations MAC addresses */
+	uint8_t self_mac_addr[CDS_MAC_ADDRESS_LEN];
+
+	/* Own SSID */
+	uint8_t ownSsid[MAX_SSID_LEN];
+	uint32_t ownSsidLen;
+
+	/* Flag for signaling if security is enabled */
+	uint8_t ucSecEnabled;
+
+	/* Include the SME(CSR) context here */
+	struct csr_roam_profile csr_roamProfile;
+	uint32_t csr_roamId;
+
+	/* SAP event Callback to hdd */
+	tpWLAN_SAPEventCB pfnSapEventCallback;
+
+	/*
+	 * Include the state machine structure here, state var that keeps
+	 * track of state machine
+	 */
+	enum sap_fsm_state fsm_state;
+
+	/* Actual storage for AP and self (STA) SSID */
+	tCsrSSIDInfo SSIDList[2];
+
+	/* Actual storage for AP bssid */
+	struct qdf_mac_addr bssid;
+
+	/* Mac filtering settings */
+	eSapMacAddrACL eSapMacAddrAclMode;
+	struct qdf_mac_addr acceptMacList[MAX_ACL_MAC_ADDRESS];
+	uint8_t nAcceptMac;
+	struct qdf_mac_addr denyMacList[MAX_ACL_MAC_ADDRESS];
+	uint8_t nDenyMac;
+
+	/* QOS config */
+	tSapQosCfg SapQosCfg;
+
+	void *pUsrContext;
+
+	uint32_t nStaWPARSnReqIeLength;
+	uint8_t pStaWpaRsnReqIE[MAX_ASSOC_IND_IE_LEN];
+
+	uint8_t *channelList;
+	uint8_t num_of_channel;
+	uint16_t ch_width_orig;
+	struct ch_params ch_params;
+
+	/* session to scan */
+	bool isScanSessionOpen;
+	/*
+	 * This list of channels will hold 5Ghz enabled,DFS in the
+	 * Current RegDomain.This list will be used to select a channel,
+	 * for SAP to start including any DFS channel and also to select
+	 * any random channel[5Ghz-(NON-DFS/DFS)],if SAP is operating
+	 * on a DFS channel and a RADAR is detected on the channel.
+	 */
+	tAll5GChannelList SapAllChnlList;
+	uint32_t auto_channel_select_weight;
+	tSapAcsChannelInfo acsBestChannelInfo;
+	bool enableOverLapCh;
+	struct sap_acs_cfg *acs_cfg;
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	uint8_t cc_switch_mode;
+#endif
+
+#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
+	bool dfs_ch_disable;
+#endif
+	bool isCacEndNotified;
+	bool isCacStartNotified;
+	bool is_sap_ready_for_chnl_chng;
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	/*
+	 * In a setup having two MDM both operating in AP+AP MCC scenario
+	 * if both the AP decides to use same or close channel set, CTS to
+	 * self, mechanism is causing issues with connectivity. For this, its
+	 * proposed that 2nd MDM devices which comes up later should detect
+	 * presence of first MDM device via special Q2Q IE present in becon
+	 * and avoid those channels mentioned in IE.
+	 *
+	 * this struct contains the list of channels on which another MDM AP
+	 * in MCC mode were detected.
+	 */
+	struct sap_avoid_channels_info sap_detected_avoid_ch_ie;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+	/*
+	 * sap_state, sap_status are created
+	 * to inform upper layers about ACS scan status.
+	 * Don't use these members for anyother purposes.
+	 */
+	eSapHddEvent sap_state;
+	eSapStatus sap_status;
+	uint32_t roc_ind_scan_id;
+	bool is_pre_cac_on;
+	bool pre_cac_complete;
+	bool vendor_acs_dfs_lte_enabled;
+	uint8_t dfs_vendor_channel;
+	uint8_t dfs_vendor_chan_bw;
+	uint8_t chan_before_pre_cac;
+	uint16_t beacon_tx_rate;
+	tSirMacRateSet supp_rate_set;
+	tSirMacRateSet extended_rate_set;
+	enum sap_acs_dfs_mode dfs_mode;
+	wlan_scan_requester req_id;
+	uint8_t sap_sta_id;
+	bool dfs_cac_offload;
+	bool is_chan_change_inprogress;
+	bool stop_bss_in_progress;
+};
+
+/*----------------------------------------------------------------------------
+ *  External declarations for global context
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ *  SAP state machine event definition
+ * -------------------------------------------------------------------------*/
+/* The event structure */
+typedef struct sWLAN_SAPEvent {
+	/* A VOID pointer type for all possible inputs */
+	void *params;
+	/* State machine input event message */
+	uint32_t event;
+	/* introduced to handle csr_roam_complete_cb roamStatus */
+	uint32_t u1;
+	/* introduced to handle csr_roam_complete_cb roamResult */
+	uint32_t u2;
+} tWLAN_SAPEvent, *ptWLAN_SAPEvent;
+
+/*----------------------------------------------------------------------------
+ * Function Declarations and Documentation
+ * -------------------------------------------------------------------------*/
+
+/**
+ * sap_get_mac_context() - Get a pointer to the global MAC context
+ *
+ * Return: pointer to the global MAC context, or NULL if the MAC
+ *         context is no longer registered
+ */
+static inline struct mac_context *sap_get_mac_context(void)
+{
+	return cds_get_context(QDF_MODULE_ID_PE);
+}
+
+QDF_STATUS wlansap_context_get(struct sap_context *ctx);
+void wlansap_context_put(struct sap_context *ctx);
+
+/**
+ * wlansap_pre_start_bss_acs_scan_callback() - callback for scan results
+ * @hal_handle:    the hal_handle passed in with the scan request
+ * @sap_ctx:       the SAP context pointer.
+ * @scanid:        scan id passed
+ * @sessionid:     session identifier
+ * @scan_status:        status of scan -success, failure or abort
+ *
+ * Api for scan callback. This function is invoked as a result of scan
+ * completion and reports the scan results.
+ *
+ * Return: The QDF_STATUS code associated with performing the operation
+ */
+QDF_STATUS wlansap_pre_start_bss_acs_scan_callback(tHalHandle hal_handle,
+						   struct sap_context *sap_ctx,
+						   uint8_t sessionid,
+						   uint32_t scanid,
+						   eCsrScanStatus scan_status);
+
+QDF_STATUS SapFsm(struct sap_context *sapContext, ptWLAN_SAPEvent sapEvent,
+			 uint8_t *status);
+
+uint8_t sap_select_channel(tHalHandle halHandle, struct sap_context *sap_ctx,
+			   tScanResultHandle pScanResult);
+
+QDF_STATUS
+sap_signal_hdd_event(struct sap_context *sapContext,
+		  struct csr_roam_info *pCsrRoamInfo,
+		  eSapHddEvent sapHddevent, void *);
+
+QDF_STATUS sap_fsm(struct sap_context *sapContext, ptWLAN_SAPEvent sapEvent);
+
+eSapStatus
+sapconvert_to_csr_profile(tsap_config_t *pconfig_params,
+		       eCsrRoamBssType bssType,
+		       struct csr_roam_profile *profile);
+
+void sap_free_roam_profile(struct csr_roam_profile *profile);
+
+QDF_STATUS
+sap_is_peer_mac_allowed(struct sap_context *sapContext, uint8_t *peerMac);
+
+void
+sap_sort_mac_list(struct qdf_mac_addr *macList, uint8_t size);
+
+void
+sap_add_mac_to_acl(struct qdf_mac_addr *macList, uint8_t *size,
+	       uint8_t *peerMac);
+
+void
+sap_remove_mac_from_acl(struct qdf_mac_addr *macList, uint8_t *size,
+		    uint8_t index);
+
+void
+sap_print_acl(struct qdf_mac_addr *macList, uint8_t size);
+
+bool
+sap_search_mac_list(struct qdf_mac_addr *macList, uint8_t num_mac,
+		 uint8_t *peerMac, uint8_t *index);
+
+#ifdef FEATURE_WLAN_CH_AVOID
+void sap_update_unsafe_channel_list(tHalHandle hal,
+				    struct sap_context *sap_ctx);
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+QDF_STATUS sap_init_dfs_channel_nol_list(struct sap_context *sapContext);
+
+bool sap_dfs_is_channel_in_nol_list(struct sap_context *sapContext,
+				    uint8_t channelNumber,
+				    ePhyChanBondState chanBondState);
+void sap_dfs_cac_timer_callback(void *data);
+
+void sap_cac_reset_notify(tHalHandle hHal);
+
+bool
+sap_channel_matrix_check(struct sap_context *sapContext,
+			 ePhyChanBondState cbMode,
+			 uint8_t target_channel);
+
+bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal,
+						struct sap_context *sapContext);
+bool sap_is_conc_sap_doing_scc_dfs(tHalHandle hal,
+				   struct sap_context *given_sapctx);
+uint8_t sap_get_total_number_sap_intf(tHalHandle hHal);
+
+bool sap_dfs_is_w53_invalid(tHalHandle hHal, uint8_t channelID);
+
+bool sap_dfs_is_channel_in_preferred_location(tHalHandle hHal,
+					      uint8_t channelID);
+
+/**
+ * sap_channel_sel - Function for initiating scan request for ACS
+ * @sap_context: Sap Context value.
+ *
+ * Initiates Scan for ACS to pick a channel.
+ *
+ * Return: The QDF_STATUS code associated with performing the operation.
+ */
+QDF_STATUS sap_channel_sel(struct sap_context *sapContext);
+
+/**
+ * sap_validate_chan - Function validate the channel and forces SCC
+ * @sap_context: Sap Context value.
+ * @pre_start_bss: if its called pre start BSS with valid channel.
+ * @check_for_connection_update: true, check and wait for connection update
+ *				 false, do not perform connection update
+ *
+ * validate and update the channel in case of force SCC.
+ *
+ * Return: The QDF_STATUS code associated with performing the operation.
+ */
+QDF_STATUS
+sap_validate_chan(struct sap_context *sap_context,
+		  bool pre_start_bss,
+		  bool check_for_connection_update);
+
+/**
+ * sap_check_in_avoid_ch_list() - checks if given channel present is channel
+ * avoidance list
+ * avoid_channels_info struct
+ * @sap_ctx:        sap context.
+ * @channel:        channel to be checked in sap_ctx's avoid ch list
+ *
+ * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
+ * which MDM device's AP with MCC was detected. This function checks if given
+ * channel is present in that list.
+ *
+ * Return: true, if channel was present, false othersie.
+ */
+bool
+sap_check_in_avoid_ch_list(struct sap_context *sap_ctx, uint8_t channel);
+/**
+ * sap_set_session_param() - set sap related param to sap context and global var
+ * @hal: pointer to hardware abstraction layer
+ * @sapctx: pointer to sapctx
+ * @session_id: session id for sap
+ *
+ * This API will set appropriate softap parameters to sap context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sap_set_session_param(tHalHandle hal, struct sap_context *sapctx,
+				uint32_t session_id);
+/**
+ * sap_clear_session_param() - clear sap related param from sap context
+ * @hal: pointer to hardware abstraction layer
+ * @sapctx: pointer to sapctx
+ * @session_id: session id for sap
+ *
+ * This API will clear appropriate softap parameters from sap context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sap_clear_session_param(tHalHandle hal, struct sap_context *sapctx,
+				uint32_t session_id);
+
+void sap_scan_event_callback(struct wlan_objmgr_vdev *vdev,
+			struct scan_event *event, void *arg);
+
+#ifdef DFS_COMPONENT_ENABLE
+/**
+ * sap_indicate_radar() - Process radar indication
+ * @sap_ctx: pointer to sap context
+ *
+ * process radar indication.
+ *
+ * Return: channel to which sap wishes to switch.
+ */
+uint8_t sap_indicate_radar(struct sap_context *sap_ctx);
+#else
+static inline uint8_t sap_indicate_radar(struct sap_context *sap_ctx)
+{
+	return 0;
+}
+#endif
+
+/**
+ * sap_select_default_oper_chan() - Select AP mode default operating channel
+ * @acs_cfg: pointer to ACS config info
+ *
+ * Select AP mode default operating channel based on ACS hw mode and channel
+ * range configuration when ACS scan fails due to some reasons, such as scan
+ * timeout, etc.
+ *
+ * Return: Selected operating channel number
+ */
+uint8_t sap_select_default_oper_chan(struct sap_acs_cfg *acs_cfg);
+
+/*
+ * sap_is_dfs_cac_wait_state() - check if sap is in cac wait state
+ * @sap_ctx: sap context to check
+ *
+ * Return: true if sap is in cac wait state
+ */
+#ifdef CONFIG_VDEV_SM
+static inline bool sap_is_dfs_cac_wait_state(struct sap_context *sap_ctx)
+{
+	if (!sap_ctx)
+		return false;
+
+	return (wlan_vdev_mlme_get_state(sap_ctx->vdev) ==
+		WLAN_VDEV_S_DFS_CAC_WAIT);
+}
+#else
+static inline bool sap_is_dfs_cac_wait_state(struct sap_context *sap_ctx)
+{
+	if (!sap_ctx)
+		return false;
+
+	return (sap_ctx->fsm_state == SAP_DFS_CAC_WAIT);
+}
+#endif
+
+/**
+ * sap_channel_in_acs_channel_list() - check if channel in acs channel list
+ * @channel_num: channel to check
+ * @sap_ctx: struct ptSapContext
+ * @spect_info_params: strcut tSapChSelSpectInfo
+ *
+ * This function checks if specified channel is in the configured ACS channel
+ * list.
+ *
+ * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
+ */
+uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
+					struct sap_context *sap_ctx,
+					tSapChSelSpectInfo *spect_info_params);
+
+/**
+ * sap_chan_bond_dfs_sub_chan - check bonded channel includes dfs sub chan
+ * @sap_context: Handle to SAP context.
+ * @channel_number: chan whose bonded chan will be checked
+ * @bond_state: The channel bonding mode of the passed channel.
+ *
+ * This function checks if a given bonded channel includes dfs sub chan.
+ *
+ * Return: true if at least one dfs sub chan is bonded, otherwise false
+ */
+bool
+sap_chan_bond_dfs_sub_chan(struct sap_context *sap_context,
+			   uint8_t channel_number,
+			   ePhyChanBondState bond_state);
+
+/**
+ * sap_acquire_vdev_ref() - Increment reference count for vdev object
+ * @mac: mac handle
+ * @sap_ctx: to store vdev object pointer
+ * @session_id: used to get vdev object
+ *
+ * This function is used to increment vdev object reference count and store
+ * vdev pointer in sap_ctx.
+ *
+ * Return: QDF_STATUS_SUCCESS - If able to get vdev object reference
+ *				else qdf status failure codes
+ */
+QDF_STATUS sap_acquire_vdev_ref(tpAniSirGlobal mac,
+				struct sap_context *sap_ctx,
+				uint8_t session_id);
+
+/**
+ * sap_release_vdev_ref() - Decrement reference count for vdev object
+ * @sap_ctx: for which vdev reference is to be decremented
+ *
+ * Return: None
+ */
+void sap_release_vdev_ref(struct sap_context *sap_ctx);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c
new file mode 100644
index 0000000..948ebf2
--- /dev/null
+++ b/core/sap/src/sap_module.c
@@ -0,0 +1,2574 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+/**
+ * ===========================================================================
+ *                     sap_module.c
+ *  OVERVIEW:
+ *  This software unit holds the implementation of the WLAN SAP modules
+ *  functions providing EXTERNAL APIs. It is also where the global SAP module
+ *  context gets initialised
+ *  DEPENDENCIES:
+ *  Are listed for each API below.
+ * ===========================================================================
+ */
+
+/* $Header$ */
+
+/*----------------------------------------------------------------------------
+ * Include Files
+ * -------------------------------------------------------------------------*/
+#include "qdf_trace.h"
+#include "qdf_util.h"
+#include "qdf_atomic.h"
+/* Pick up the sme callback registration API */
+#include "sme_api.h"
+
+/* SAP API header file */
+
+#include "sap_internal.h"
+#include "sme_inside.h"
+#include "cds_ieee80211_common_i.h"
+#include "cds_regdomain.h"
+#include "wlan_policy_mgr_api.h"
+#include <wlan_scan_ucfg_api.h>
+#include "wlan_reg_services_api.h"
+#include <wlan_dfs_utils_api.h>
+#include <wlan_reg_ucfg_api.h>
+
+/*----------------------------------------------------------------------------
+ * Preprocessor Definitions and Constants
+ * -------------------------------------------------------------------------*/
+#define SAP_DEBUG
+
+/*----------------------------------------------------------------------------
+ * Type Declarations
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Global Data Definitions
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ *  External declarations for global context
+ * -------------------------------------------------------------------------*/
+/*  No!  Get this from CDS. */
+/*  The main per-Physical Link (per WLAN association) context. */
+static struct sap_context *gp_sap_ctx[SAP_MAX_NUM_SESSION];
+static qdf_atomic_t sap_ctx_ref_count[SAP_MAX_NUM_SESSION];
+
+/*----------------------------------------------------------------------------
+ * Static Variable Definitions
+ * -------------------------------------------------------------------------*/
+static qdf_mutex_t sap_context_lock;
+
+/*----------------------------------------------------------------------------
+ * Static Function Declarations and Definitions
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Externalized Function Definitions
+ * -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Function Declarations and Documentation
+ * -------------------------------------------------------------------------*/
+
+/**
+ * wlansap_global_init() - Initialize SAP globals
+ *
+ * Initializes the SAP global data structures
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlansap_global_init(void)
+{
+	uint32_t i;
+
+	if (QDF_IS_STATUS_ERROR(qdf_mutex_create(&sap_context_lock))) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "failed to init sap_context_lock");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
+		gp_sap_ctx[i] = NULL;
+		qdf_atomic_init(&sap_ctx_ref_count[i]);
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			"%s: sap global context initialized", __func__);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlansap_global_deinit() - De-initialize SAP globals
+ *
+ * De-initializes the SAP global data structures
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlansap_global_deinit(void)
+{
+	uint32_t i;
+
+	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
+		if (gp_sap_ctx[i]) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				"we could be leaking context:%d", i);
+		}
+		gp_sap_ctx[i] = NULL;
+		qdf_atomic_init(&sap_ctx_ref_count[i]);
+	}
+
+	if (QDF_IS_STATUS_ERROR(qdf_mutex_destroy(&sap_context_lock))) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				"failed to destroy sap_context_lock");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			"%s: sap global context deinitialized", __func__);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlansap_save_context() - Save the context in global SAP context
+ * @ctx: SAP context to be stored
+ *
+ * Stores the given SAP context in the global SAP context array
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS wlansap_save_context(struct sap_context *ctx)
+{
+	uint32_t i;
+
+	qdf_mutex_acquire(&sap_context_lock);
+	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
+		if (gp_sap_ctx[i] == NULL) {
+			gp_sap_ctx[i] = ctx;
+			qdf_atomic_inc(&sap_ctx_ref_count[i]);
+			qdf_mutex_release(&sap_context_lock);
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+				"%s: sap context saved at index: %d",
+				__func__, i);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	qdf_mutex_release(&sap_context_lock);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+		"%s: failed to save sap context", __func__);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * wlansap_context_get() - Verify SAP context and increment ref count
+ * @ctx: Context to be checked
+ *
+ * Verifies the SAP context and increments the reference count maintained for
+ * the corresponding SAP context.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlansap_context_get(struct sap_context *ctx)
+{
+	uint32_t i;
+
+	qdf_mutex_acquire(&sap_context_lock);
+	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
+		if (ctx && (gp_sap_ctx[i] == ctx)) {
+			qdf_atomic_inc(&sap_ctx_ref_count[i]);
+			qdf_mutex_release(&sap_context_lock);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	qdf_mutex_release(&sap_context_lock);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			"%s: sap session is not valid", __func__);
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * wlansap_context_put() - Check the reference count and free SAP context
+ * @ctx: SAP context to be checked and freed
+ *
+ * Checks the reference count and frees the SAP context
+ *
+ * Return: None
+ */
+void wlansap_context_put(struct sap_context *ctx)
+{
+	uint32_t i;
+
+	if (!ctx)
+		return;
+
+	qdf_mutex_acquire(&sap_context_lock);
+	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
+		if (gp_sap_ctx[i] == ctx) {
+			if (qdf_atomic_dec_and_test(&sap_ctx_ref_count[i])) {
+				if (ctx->channelList) {
+					qdf_mem_free(ctx->channelList);
+					ctx->channelList = NULL;
+					ctx->num_of_channel = 0;
+				}
+				qdf_mem_free(ctx);
+				gp_sap_ctx[i] = NULL;
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					QDF_TRACE_LEVEL_DEBUG,
+					"%s: sap session freed: %d",
+					__func__, i);
+			}
+			qdf_mutex_release(&sap_context_lock);
+			return;
+		}
+	}
+	qdf_mutex_release(&sap_context_lock);
+}
+
+struct sap_context *sap_create_ctx(void)
+{
+	struct sap_context *sap_ctx;
+	QDF_STATUS status;
+
+	/* dynamically allocate the sapContext */
+	sap_ctx = qdf_mem_malloc(sizeof(*sap_ctx));
+	if (!sap_ctx)
+		return NULL;
+
+	/* Clean up SAP control block, initialize all values */
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, FL("Enter"));
+
+	/* Save the SAP context pointer */
+	status = wlansap_save_context(sap_ctx);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"%s: failed to save SAP context", __func__);
+		qdf_mem_free(sap_ctx);
+		return NULL;
+	}
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, FL("Exit"));
+
+	return sap_ctx;
+} /* sap_create_ctx */
+
+QDF_STATUS sap_init_ctx(struct sap_context *sap_ctx,
+			 enum QDF_OPMODE mode,
+			 uint8_t *addr, uint32_t session_id, bool reinit)
+{
+	QDF_STATUS status;
+	struct mac_context *mac;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "wlansap_start invoked successfully");
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	/*------------------------------------------------------------------------
+	    For now, presume security is not enabled.
+	   -----------------------------------------------------------------------*/
+	sap_ctx->ucSecEnabled = WLANSAP_SECURITY_ENABLED_STATE;
+
+	/*------------------------------------------------------------------------
+	    Now configure the roaming profile links. To SSID and bssid.
+	   ------------------------------------------------------------------------*/
+	/* We have room for two SSIDs. */
+	sap_ctx->csr_roamProfile.SSIDs.numOfSSIDs = 1;   /* This is true for now. */
+	sap_ctx->csr_roamProfile.SSIDs.SSIDList = sap_ctx->SSIDList;     /* Array of two */
+	sap_ctx->csr_roamProfile.SSIDs.SSIDList[0].SSID.length = 0;
+	sap_ctx->csr_roamProfile.SSIDs.SSIDList[0].handoffPermitted = false;
+	sap_ctx->csr_roamProfile.SSIDs.SSIDList[0].ssidHidden =
+		sap_ctx->SSIDList[0].ssidHidden;
+
+	sap_ctx->csr_roamProfile.BSSIDs.numOfBSSIDs = 1; /* This is true for now. */
+	sap_ctx->csr_roamProfile.BSSIDs.bssid = &sap_ctx->bssid;
+	sap_ctx->csr_roamProfile.csrPersona = mode;
+	qdf_mem_copy(sap_ctx->self_mac_addr, addr, QDF_MAC_ADDR_SIZE);
+
+	/* Now configure the auth type in the roaming profile. To open. */
+	sap_ctx->csr_roamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;        /* open is the default */
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sap_set_session_param(MAC_HANDLE(mac), sap_ctx, session_id);
+	if (QDF_STATUS_SUCCESS != status) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"In %s calling sap_set_session_param status = %d",
+			__func__, status);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Register with scan component only during init */
+	if (!reinit)
+		sap_ctx->req_id =
+			ucfg_scan_register_requester(mac->psoc, "SAP",
+					sap_scan_event_callback, sap_ctx);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sap_deinit_ctx(struct sap_context *sap_ctx)
+{
+	struct mac_context *mac;
+
+	/* Sanity check - Extract SAP control block */
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+		  "wlansap_stop invoked successfully ");
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+	ucfg_scan_unregister_requester(mac->psoc, sap_ctx->req_id);
+
+	if (sap_ctx->channelList) {
+		qdf_mem_free(sap_ctx->channelList);
+		sap_ctx->channelList = NULL;
+		sap_ctx->num_of_channel = 0;
+	}
+	sap_free_roam_profile(&sap_ctx->csr_roamProfile);
+	if (sap_ctx->sessionId != CSR_SESSION_ID_INVALID) {
+		/* empty queues/lists/pkts if any */
+		sap_clear_session_param(MAC_HANDLE(mac), sap_ctx,
+					sap_ctx->sessionId);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sap_destroy_ctx(struct sap_context *sap_ctx)
+{
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("Enter"));
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+	/* Cleanup SAP control block */
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, FL("Enter"));
+	/*
+	 * wlansap_context_put will release actual sap_ctx memory
+	 * allocated during sap_create_ctx
+	 */
+	wlansap_context_put(sap_ctx);
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, FL("Exit"));
+
+	return QDF_STATUS_SUCCESS;
+} /* sap_destroy_ctx */
+
+bool wlansap_is_channel_in_nol_list(struct sap_context *sap_ctx,
+				    uint8_t channelNumber,
+				    ePhyChanBondState chanBondState)
+{
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: Invalid SAP pointer from pCtx", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	return sap_dfs_is_channel_in_nol_list(sap_ctx, channelNumber,
+					      chanBondState);
+}
+
+static QDF_STATUS wlansap_mark_leaking_channel(struct wlan_objmgr_pdev *pdev,
+		uint8_t *leakage_adjusted_lst,
+		uint8_t chan_bw)
+{
+
+	return utils_dfs_mark_leaking_ch(pdev, chan_bw, 1,
+			leakage_adjusted_lst);
+}
+
+bool wlansap_is_channel_leaking_in_nol(struct sap_context *sap_ctx,
+				       uint8_t channel,
+				       uint8_t chan_bw)
+{
+	struct mac_context *mac_ctx;
+	uint8_t leakage_adjusted_lst[1];
+
+	leakage_adjusted_lst[0] = channel;
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+	if (QDF_IS_STATUS_ERROR(wlansap_mark_leaking_channel(mac_ctx->pdev,
+			leakage_adjusted_lst, chan_bw)))
+		return true;
+
+	if (!leakage_adjusted_lst[0])
+		return true;
+
+	return false;
+}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+uint16_t wlansap_check_cc_intf(struct sap_context *sap_ctx)
+{
+	struct mac_context *mac;
+	uint16_t intf_ch;
+	eCsrPhyMode phy_mode;
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return 0;
+	}
+	phy_mode = sap_ctx->csr_roamProfile.phyMode;
+	intf_ch = sme_check_concurrent_channel_overlap(MAC_HANDLE(mac),
+						       sap_ctx->channel,
+						       phy_mode,
+						       sap_ctx->cc_switch_mode);
+	return intf_ch;
+}
+#endif
+
+ /**
+  * wlansap_set_scan_acs_channel_params() - Config scan and channel parameters.
+  * pconfig:                                Pointer to the SAP config
+  * psap_ctx:                               Pointer to the SAP Context.
+  * pusr_context:                           Parameter that will be passed
+  *                                         back in all the SAP callback events.
+  *
+  * This api function is used to copy Scan and Channel parameters from sap
+  * config to sap context.
+  *
+  * Return:                                 The result code associated with
+  *                                         performing the operation
+  */
+static QDF_STATUS
+wlansap_set_scan_acs_channel_params(tsap_config_t *pconfig,
+				    struct sap_context *psap_ctx,
+				    void *pusr_context)
+{
+	struct mac_context *mac;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (NULL == pconfig) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"%s: Invalid pconfig passed ", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	if (NULL == psap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"%s: Invalid pconfig passed ", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	/* Channel selection is auto or configured */
+	psap_ctx->channel = pconfig->channel;
+	psap_ctx->dfs_mode = pconfig->acs_dfs_mode;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	psap_ctx->cc_switch_mode = pconfig->cc_switch_mode;
+#endif
+	psap_ctx->auto_channel_select_weight =
+		 pconfig->auto_channel_select_weight;
+	psap_ctx->pUsrContext = pusr_context;
+	psap_ctx->enableOverLapCh = pconfig->enOverLapCh;
+	psap_ctx->acs_cfg = &pconfig->acs_cfg;
+	psap_ctx->ch_width_orig = pconfig->acs_cfg.ch_width;
+	psap_ctx->secondary_ch = pconfig->sec_ch;
+
+	/*
+	 * Set the BSSID to your "self MAC Addr" read
+	 * the mac address from Configuation ITEM received
+	 * from HDD
+	 */
+	psap_ctx->csr_roamProfile.BSSIDs.numOfBSSIDs = 1;
+
+	/* Save a copy to SAP context */
+	qdf_mem_copy(psap_ctx->csr_roamProfile.BSSIDs.bssid,
+		pconfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(psap_ctx->self_mac_addr,
+		pconfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE);
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+	/*
+	 * If concurrent session is running that is already associated
+	 * then we just follow that sessions country info (whether
+	 * present or not doesn't matter as we have to follow whatever
+	 * STA session does)
+	 */
+	if ((0 == sme_get_concurrent_operation_channel(MAC_HANDLE(mac))) &&
+	    pconfig->ieee80211d) {
+		/* Setting the region/country  information */
+		status = ucfg_reg_set_country(mac->pdev,
+					      pconfig->countryCode);
+		if (QDF_IS_STATUS_ERROR(status))
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				FL("Failed to set country"));
+	}
+
+	return status;
+}
+
+/**
+ * wlan_sap_get_roam_profile() - Returns sap roam profile.
+ * @sap_ctx:	Pointer to Sap Context.
+ *
+ * This function provides the SAP roam profile.
+ *
+ * Return: SAP RoamProfile
+ */
+struct csr_roam_profile *wlan_sap_get_roam_profile(struct sap_context *sap_ctx)
+{
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("Invalid SAP pointer from ctx"));
+		return NULL;
+	}
+	return &sap_ctx->csr_roamProfile;
+}
+
+eCsrPhyMode wlan_sap_get_phymode(struct sap_context *sap_ctx)
+{
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("Invalid SAP pointer from ctx"));
+		return 0;
+	}
+	return sap_ctx->csr_roamProfile.phyMode;
+}
+
+uint32_t wlan_sap_get_vht_ch_width(struct sap_context *sap_ctx)
+{
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("Invalid SAP pointer"));
+		return 0;
+	}
+
+	return sap_ctx->ch_params.ch_width;
+}
+
+void wlan_sap_set_vht_ch_width(struct sap_context *sap_ctx,
+			       uint32_t vht_channel_width)
+{
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("Invalid SAP pointer"));
+		return;
+	}
+
+	sap_ctx->ch_params.ch_width = vht_channel_width;
+}
+
+/**
+ * wlan_sap_validate_channel_switch() - validate target channel switch w.r.t
+ *      concurreny rules set to avoid channel interference.
+ * @hal - Hal context
+ * @sap_ch - channel to switch
+ * @sap_context - sap session context
+ *
+ * Return: true if there is no channel interference else return false
+ */
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+static bool wlan_sap_validate_channel_switch(tHalHandle hal, uint16_t sap_ch,
+		struct sap_context *sap_context)
+{
+	return sme_validate_sap_channel_switch(
+			hal,
+			sap_ch,
+			sap_context->csr_roamProfile.phyMode,
+			sap_context->cc_switch_mode,
+			sap_context->sessionId);
+}
+#else
+static inline bool wlan_sap_validate_channel_switch(tHalHandle hal,
+		uint16_t sap_ch, struct sap_context *sap_context)
+{
+	return true;
+}
+#endif
+
+void wlan_sap_set_sap_ctx_acs_cfg(struct sap_context *sap_ctx,
+				  tsap_config_t *sap_config)
+{
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: Invalid SAP pointer",
+			  __func__);
+		return;
+	}
+
+	sap_ctx->acs_cfg = &sap_config->acs_cfg;
+}
+
+QDF_STATUS wlansap_start_bss(struct sap_context *sap_ctx,
+			     tpWLAN_SAPEventCB pSapEventCallback,
+			     tsap_config_t *pConfig, void *pUsrContext)
+{
+	tWLAN_SAPEvent sapEvent;        /* State machine event */
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct mac_context *pmac = NULL;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  FL("sapContext=%pK"), sap_ctx);
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: Invalid SAP pointer",
+			  __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+	sap_ctx->fsm_state = SAP_INIT;
+
+	/* Channel selection is auto or configured */
+	sap_ctx->channel = pConfig->channel;
+	sap_ctx->dfs_mode = pConfig->acs_dfs_mode;
+	sap_ctx->ch_params.ch_width = pConfig->ch_params.ch_width;
+	sap_ctx->ch_params.center_freq_seg0 =
+		pConfig->ch_params.center_freq_seg0;
+	sap_ctx->ch_params.center_freq_seg1 =
+		pConfig->ch_params.center_freq_seg1;
+	sap_ctx->ch_params.sec_ch_offset =
+		pConfig->ch_params.sec_ch_offset;
+	sap_ctx->ch_width_orig = pConfig->ch_width_orig;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	sap_ctx->cc_switch_mode = pConfig->cc_switch_mode;
+#endif
+	sap_ctx->auto_channel_select_weight =
+		 pConfig->auto_channel_select_weight;
+	sap_ctx->pUsrContext = pUsrContext;
+	sap_ctx->enableOverLapCh = pConfig->enOverLapCh;
+	sap_ctx->acs_cfg = &pConfig->acs_cfg;
+	sap_ctx->secondary_ch = pConfig->sec_ch;
+	sap_ctx->dfs_cac_offload = pConfig->dfs_cac_offload;
+	sap_ctx->isCacEndNotified = false;
+	sap_ctx->is_chan_change_inprogress = false;
+
+	/* Set the BSSID to your "self MAC Addr" read the mac address
+		from Configuation ITEM received from HDD */
+	sap_ctx->csr_roamProfile.BSSIDs.numOfBSSIDs = 1;
+	qdf_mem_copy(sap_ctx->csr_roamProfile.BSSIDs.bssid,
+		     sap_ctx->self_mac_addr, sizeof(struct qdf_mac_addr));
+
+	/* Save a copy to SAP context */
+	qdf_mem_copy(sap_ctx->csr_roamProfile.BSSIDs.bssid,
+		     pConfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(sap_ctx->self_mac_addr,
+		     pConfig->self_macaddr.bytes, QDF_MAC_ADDR_SIZE);
+
+	/* copy the configuration items to csrProfile */
+	sapconvert_to_csr_profile(pConfig, eCSR_BSS_TYPE_INFRA_AP,
+			       &sap_ctx->csr_roamProfile);
+	pmac = sap_get_mac_context();
+	if (!pmac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto fail;
+	}
+
+	/* If concurrent session is running that is already associated
+	 * then we just follow that sessions country info (whether
+	 * present or not doesn't matter as we have to follow whatever
+	 * STA session does) */
+	if ((0 == sme_get_concurrent_operation_channel(MAC_HANDLE(pmac))) &&
+	    pConfig->ieee80211d) {
+		/* Setting the region/country  information */
+		qdf_status = ucfg_reg_set_country(pmac->pdev,
+					pConfig->countryCode);
+		if (QDF_IS_STATUS_ERROR(qdf_status))
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				FL("Failed to set country"));
+	}
+
+	/*
+	 * Copy the DFS Test Mode setting to pmac for
+	 * access in lower layers
+	 */
+	pmac->sap.SapDfsInfo.disable_dfs_ch_switch =
+				pConfig->disableDFSChSwitch;
+	pmac->sap.SapDfsInfo.sap_ch_switch_beacon_cnt =
+				pConfig->sap_chanswitch_beacon_cnt;
+	pmac->sap.SapDfsInfo.sap_ch_switch_mode =
+			pConfig->sap_chanswitch_mode;
+
+	pmac->sap.sapCtxList[sap_ctx->sessionId].sap_context = sap_ctx;
+	pmac->sap.sapCtxList[sap_ctx->sessionId].sapPersona =
+		sap_ctx->csr_roamProfile.csrPersona;
+	pmac->sap.sapCtxList[sap_ctx->sessionId].sessionID =
+		sap_ctx->sessionId;
+	pmac->sap.SapDfsInfo.dfs_beacon_tx_enhanced =
+		pConfig->dfs_beacon_tx_enhanced;
+	pmac->sap.SapDfsInfo.reduced_beacon_interval =
+				pConfig->reduced_beacon_interval;
+
+	/* Copy MAC filtering settings to sap context */
+	sap_ctx->eSapMacAddrAclMode = pConfig->SapMacaddr_acl;
+	qdf_mem_copy(sap_ctx->acceptMacList, pConfig->accept_mac,
+		     sizeof(pConfig->accept_mac));
+	sap_ctx->nAcceptMac = pConfig->num_accept_mac;
+	sap_sort_mac_list(sap_ctx->acceptMacList, sap_ctx->nAcceptMac);
+	qdf_mem_copy(sap_ctx->denyMacList, pConfig->deny_mac,
+		     sizeof(pConfig->deny_mac));
+	sap_ctx->nDenyMac = pConfig->num_deny_mac;
+	sap_sort_mac_list(sap_ctx->denyMacList, sap_ctx->nDenyMac);
+	sap_ctx->beacon_tx_rate = pConfig->beacon_tx_rate;
+
+	/* Fill in the event structure for FSM */
+	sapEvent.event = eSAP_HDD_START_INFRA_BSS;
+	sapEvent.params = 0;    /* pSapPhysLinkCreate */
+
+	/* Store the HDD callback in SAP context */
+	sap_ctx->pfnSapEventCallback = pSapEventCallback;
+
+	/* Handle event */
+	qdf_status = sap_fsm(sap_ctx, &sapEvent);
+fail:
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		sap_free_roam_profile(&sap_ctx->csr_roamProfile);
+
+	return qdf_status;
+} /* wlansap_start_bss */
+
+QDF_STATUS wlansap_set_mac_acl(struct sap_context *sap_ctx,
+			       tsap_config_t *pConfig)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "wlansap_set_mac_acl");
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+	/* Copy MAC filtering settings to sap context */
+	sap_ctx->eSapMacAddrAclMode = pConfig->SapMacaddr_acl;
+
+	if (eSAP_DENY_UNLESS_ACCEPTED == sap_ctx->eSapMacAddrAclMode) {
+		qdf_mem_copy(sap_ctx->acceptMacList,
+			     pConfig->accept_mac,
+			     sizeof(pConfig->accept_mac));
+		sap_ctx->nAcceptMac = pConfig->num_accept_mac;
+		sap_sort_mac_list(sap_ctx->acceptMacList,
+			       sap_ctx->nAcceptMac);
+	} else if (eSAP_ACCEPT_UNLESS_DENIED == sap_ctx->eSapMacAddrAclMode) {
+		qdf_mem_copy(sap_ctx->denyMacList, pConfig->deny_mac,
+			     sizeof(pConfig->deny_mac));
+		sap_ctx->nDenyMac = pConfig->num_deny_mac;
+		sap_sort_mac_list(sap_ctx->denyMacList, sap_ctx->nDenyMac);
+	}
+
+	return qdf_status;
+} /* wlansap_set_mac_acl */
+
+QDF_STATUS wlansap_stop_bss(struct sap_context *sap_ctx)
+{
+	tWLAN_SAPEvent sapEvent;        /* State machine event */
+	QDF_STATUS qdf_status;
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	/* Fill in the event structure for FSM */
+	sapEvent.event = eSAP_HDD_STOP_INFRA_BSS;
+	sapEvent.params = 0;
+
+	/* Handle event */
+	qdf_status = sap_fsm(sap_ctx, &sapEvent);
+
+	return qdf_status;
+}
+
+/* This routine will set the mode of operation for ACL dynamically*/
+QDF_STATUS wlansap_set_acl_mode(struct sap_context *sap_ctx,
+				eSapMacAddrACL mode)
+{
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	sap_ctx->eSapMacAddrAclMode = mode;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlansap_get_acl_mode(struct sap_context *sap_ctx,
+				eSapMacAddrACL *mode)
+{
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	*mode = sap_ctx->eSapMacAddrAclMode;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlansap_get_acl_accept_list(struct sap_context *sap_ctx,
+				       struct qdf_mac_addr *pAcceptList,
+				       uint8_t *nAcceptList)
+{
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	memcpy(pAcceptList, sap_ctx->acceptMacList,
+	       (sap_ctx->nAcceptMac * QDF_MAC_ADDR_SIZE));
+	*nAcceptList = sap_ctx->nAcceptMac;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlansap_get_acl_deny_list(struct sap_context *sap_ctx,
+				     struct qdf_mac_addr *pDenyList,
+				     uint8_t *nDenyList)
+{
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer from p_cds_gctx", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	memcpy(pDenyList, sap_ctx->denyMacList,
+	       (sap_ctx->nDenyMac * QDF_MAC_ADDR_SIZE));
+	*nDenyList = sap_ctx->nDenyMac;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlansap_clear_acl(struct sap_context *sap_ctx)
+{
+	uint8_t i;
+
+	if (NULL == sap_ctx) {
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	for (i = 0; i < (sap_ctx->nDenyMac - 1); i++) {
+		qdf_mem_zero((sap_ctx->denyMacList + i)->bytes,
+			     QDF_MAC_ADDR_SIZE);
+	}
+
+	sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac);
+	sap_ctx->nDenyMac = 0;
+
+	for (i = 0; i < (sap_ctx->nAcceptMac - 1); i++) {
+		qdf_mem_zero((sap_ctx->acceptMacList + i)->bytes,
+			     QDF_MAC_ADDR_SIZE);
+	}
+
+	sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac);
+	sap_ctx->nAcceptMac = 0;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx,
+			      uint8_t *peer_sta_mac,
+			      eSapACLType list_type, eSapACLCmdType cmd)
+{
+	bool sta_white_list = false, sta_black_list = false;
+	uint8_t staWLIndex, staBLIndex;
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP Context", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
+		  "Modify ACL entered\n" "Before modification of ACL\n"
+		  "size of accept and deny lists %d %d", sap_ctx->nAcceptMac,
+		  sap_ctx->nDenyMac);
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "*** WHITE LIST ***");
+	sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac);
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "*** BLACK LIST ***");
+	sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac);
+
+	/* the expectation is a mac addr will not be in both the lists
+	 * at the same time. It is the responsiblity of userspace to
+	 * ensure this
+	 */
+	sta_white_list =
+		sap_search_mac_list(sap_ctx->acceptMacList, sap_ctx->nAcceptMac,
+				 peer_sta_mac, &staWLIndex);
+	sta_black_list =
+		sap_search_mac_list(sap_ctx->denyMacList, sap_ctx->nDenyMac,
+				 peer_sta_mac, &staBLIndex);
+
+	if (sta_white_list && sta_black_list) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "Peer mac " MAC_ADDRESS_STR
+			  " found in white and black lists."
+			  "Initial lists passed incorrect. Cannot execute this command.",
+			  MAC_ADDR_ARRAY(peer_sta_mac));
+		return QDF_STATUS_E_FAILURE;
+
+	}
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
+		  "cmd %d", cmd);
+
+	switch (list_type) {
+	case eSAP_WHITE_LIST:
+		if (cmd == ADD_STA_TO_ACL) {
+			/* error check */
+			/* if list is already at max, return failure */
+			if (sap_ctx->nAcceptMac == MAX_ACL_MAC_ADDRESS) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "White list is already maxed out. Cannot accept "
+					  MAC_ADDRESS_STR,
+					  MAC_ADDR_ARRAY(peer_sta_mac));
+				return QDF_STATUS_E_FAILURE;
+			}
+			if (sta_white_list) {
+				/* Do nothing if already present in white list. Just print a warning */
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_WARN,
+					  "MAC address already present in white list "
+					  MAC_ADDRESS_STR,
+					  MAC_ADDR_ARRAY(peer_sta_mac));
+				return QDF_STATUS_SUCCESS;
+			}
+			if (sta_black_list) {
+				/* remove it from black list before adding to the white list */
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_WARN,
+					  "STA present in black list so first remove from it");
+				sap_remove_mac_from_acl(sap_ctx->denyMacList,
+						    &sap_ctx->nDenyMac,
+						    staBLIndex);
+			}
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_INFO,
+				  "... Now add to the white list");
+			sap_add_mac_to_acl(sap_ctx->acceptMacList,
+					       &sap_ctx->nAcceptMac,
+			       peer_sta_mac);
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_INFO_LOW,
+				  "size of accept and deny lists %d %d",
+				  sap_ctx->nAcceptMac,
+				  sap_ctx->nDenyMac);
+		} else if (cmd == DELETE_STA_FROM_ACL) {
+			if (sta_white_list) {
+
+				struct csr_del_sta_params delStaParams;
+
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO,
+					  "Delete from white list");
+				sap_remove_mac_from_acl(sap_ctx->acceptMacList,
+						    &sap_ctx->nAcceptMac,
+						    staWLIndex);
+				/* If a client is deleted from white list and it is connected, send deauth */
+				wlansap_populate_del_sta_params(peer_sta_mac,
+					eCsrForcedDeauthSta,
+					(SIR_MAC_MGMT_DEAUTH >> 4),
+					&delStaParams);
+				wlansap_deauth_sta(sap_ctx, &delStaParams);
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO_LOW,
+					  "size of accept and deny lists %d %d",
+					  sap_ctx->nAcceptMac,
+					  sap_ctx->nDenyMac);
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_WARN,
+					  "MAC address to be deleted is not present in the white list "
+					  MAC_ADDRESS_STR,
+					  MAC_ADDR_ARRAY(peer_sta_mac));
+				return QDF_STATUS_E_FAILURE;
+			}
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  "Invalid cmd type passed");
+			return QDF_STATUS_E_FAILURE;
+		}
+		break;
+
+	case eSAP_BLACK_LIST:
+
+		if (cmd == ADD_STA_TO_ACL) {
+			struct csr_del_sta_params delStaParams;
+			/* error check */
+			/* if list is already at max, return failure */
+			if (sap_ctx->nDenyMac == MAX_ACL_MAC_ADDRESS) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "Black list is already maxed out. Cannot accept "
+					  MAC_ADDRESS_STR,
+					  MAC_ADDR_ARRAY(peer_sta_mac));
+				return QDF_STATUS_E_FAILURE;
+			}
+			if (sta_black_list) {
+				/* Do nothing if already present in white list */
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_WARN,
+					  "MAC address already present in black list "
+					  MAC_ADDRESS_STR,
+					  MAC_ADDR_ARRAY(peer_sta_mac));
+				return QDF_STATUS_SUCCESS;
+			}
+			if (sta_white_list) {
+				/* remove it from white list before adding to the black list */
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_WARN,
+					  "Present in white list so first remove from it");
+				sap_remove_mac_from_acl(sap_ctx->acceptMacList,
+						    &sap_ctx->nAcceptMac,
+						    staWLIndex);
+			}
+			/* If we are adding a client to the black list; if its connected, send deauth */
+			wlansap_populate_del_sta_params(peer_sta_mac,
+				eCsrForcedDeauthSta,
+				(SIR_MAC_MGMT_DEAUTH >> 4),
+				&delStaParams);
+			wlansap_deauth_sta(sap_ctx, &delStaParams);
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_INFO,
+				  "... Now add to black list");
+			sap_add_mac_to_acl(sap_ctx->denyMacList,
+				       &sap_ctx->nDenyMac, peer_sta_mac);
+			QDF_TRACE(QDF_MODULE_ID_SAP,
+				  QDF_TRACE_LEVEL_INFO_LOW,
+				  "size of accept and deny lists %d %d",
+				  sap_ctx->nAcceptMac,
+				  sap_ctx->nDenyMac);
+		} else if (cmd == DELETE_STA_FROM_ACL) {
+			if (sta_black_list) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO,
+					  "Delete from black list");
+				sap_remove_mac_from_acl(sap_ctx->denyMacList,
+						    &sap_ctx->nDenyMac,
+						    staBLIndex);
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_INFO_LOW,
+					  "no accept and deny mac %d %d",
+					  sap_ctx->nAcceptMac,
+					  sap_ctx->nDenyMac);
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_WARN,
+					  "MAC address to be deleted is not present in the black list "
+					  MAC_ADDRESS_STR,
+					  MAC_ADDR_ARRAY(peer_sta_mac));
+				return QDF_STATUS_E_FAILURE;
+			}
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  "Invalid cmd type passed");
+			return QDF_STATUS_E_FAILURE;
+		}
+		break;
+
+	default:
+	{
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "Invalid list type passed %d", list_type);
+		return QDF_STATUS_E_FAILURE;
+	}
+	}
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
+		  "After modification of ACL");
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "*** WHITE LIST ***");
+	sap_print_acl(sap_ctx->acceptMacList, sap_ctx->nAcceptMac);
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "*** BLACK LIST ***");
+	sap_print_acl(sap_ctx->denyMacList, sap_ctx->nDenyMac);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlansap_disassoc_sta(struct sap_context *sap_ctx,
+				struct csr_del_sta_params *params)
+{
+	tpAniSirGlobal mac;
+
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	return sme_roam_disconnect_sta(MAC_HANDLE(mac), sap_ctx->sessionId,
+				       params);
+}
+
+QDF_STATUS wlansap_deauth_sta(struct sap_context *sap_ctx,
+			      struct csr_del_sta_params *params)
+{
+	struct mac_context *mac;
+
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	return sme_roam_deauth_sta(MAC_HANDLE(mac), sap_ctx->sessionId,
+				   params);
+}
+
+/**
+ * wlansap_update_csa_channel_params() - function to populate channel width and
+ *                                        bonding modes.
+ * @sap_context: sap adapter context
+ * @channel: target channel
+ *
+ * Return: The QDF_STATUS code associated with performing the operation
+ */
+static QDF_STATUS
+wlansap_update_csa_channel_params(struct sap_context *sap_context,
+				  uint32_t channel)
+{
+	struct mac_context *mac_ctx;
+	uint8_t bw;
+
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	if (channel <= CHAN_ENUM_14) {
+		/*
+		 * currently OBSS scan is done in hostapd, so to avoid
+		 * SAP coming up in HT40 on channel switch we are
+		 * disabling channel bonding in 2.4Ghz.
+		 */
+		mac_ctx->sap.SapDfsInfo.new_chanWidth = 0;
+
+	} else {
+		if (sap_context->csr_roamProfile.phyMode ==
+		    eCSR_DOT11_MODE_11ac ||
+		    sap_context->csr_roamProfile.phyMode ==
+		    eCSR_DOT11_MODE_11ac_ONLY)
+			bw = BW80;
+		else
+			bw = BW40_HIGH_PRIMARY;
+
+		for (; bw >= BW20; bw--) {
+			uint16_t op_class;
+
+			op_class = wlan_reg_dmn_get_opclass_from_channel(
+					mac_ctx->scan.countryCodeCurrent,
+					channel, bw);
+			if (!op_class)
+				continue;
+
+			if (bw == BW80) {
+				mac_ctx->sap.SapDfsInfo.new_chanWidth =
+					CH_WIDTH_80MHZ;
+			} else if (bw == BW40_HIGH_PRIMARY) {
+				mac_ctx->sap.SapDfsInfo.new_chanWidth =
+					CH_WIDTH_40MHZ;
+			} else if (bw == BW40_LOW_PRIMARY) {
+				mac_ctx->sap.SapDfsInfo.new_chanWidth =
+				   CH_WIDTH_40MHZ;
+			} else {
+				mac_ctx->sap.SapDfsInfo.new_chanWidth =
+				   CH_WIDTH_20MHZ;
+			}
+			break;
+		}
+
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlansap_set_channel_change_with_csa() - Set channel change with CSA
+ * @sapContext: Pointer to SAP context
+ * @targetChannel: Target channel
+ * @target_bw: Target bandwidth
+ * @strict: if true switch to the requested channel always,
+ *        SCC/MCC check will be ignored,
+ *        fail otherwise
+ *
+ * This api function does a channel change to the target channel specified.
+ * CSA IE is included in the beacons before doing a channel change.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sapContext,
+					       uint32_t targetChannel,
+					       enum phy_ch_width target_bw,
+					       bool strict)
+{
+#ifndef CONFIG_VDEV_SM
+	tWLAN_SAPEvent sapEvent;
+#endif
+	struct mac_context *mac;
+	mac_handle_t mac_handle;
+	bool valid;
+	QDF_STATUS status;
+	bool sta_sap_scc_on_dfs_chan;
+
+	if (NULL == sapContext) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+	mac_handle = MAC_HANDLE(mac);
+
+	if (strict && !policy_mgr_is_safe_channel(mac->psoc, targetChannel)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"%u is unsafe channel", targetChannel);
+		return QDF_STATUS_E_FAULT;
+	}
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+		"%s: sap chan:%d target:%d conn on 5GHz:%d",
+		__func__, sapContext->channel, targetChannel,
+		policy_mgr_is_any_mode_active_on_band_along_with_session(
+			mac->psoc, sapContext->sessionId, POLICY_MGR_BAND_5));
+
+	sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac->psoc);
+	/*
+	 * Now, validate if the passed channel is valid in the
+	 * current regulatory domain.
+	 */
+	if (sapContext->channel != targetChannel &&
+		((wlan_reg_get_channel_state(mac->pdev, targetChannel) ==
+			CHANNEL_STATE_ENABLE) ||
+		(wlan_reg_get_channel_state(mac->pdev, targetChannel) ==
+			CHANNEL_STATE_DFS &&
+		(!policy_mgr_is_any_mode_active_on_band_along_with_session(
+			mac->psoc, sapContext->sessionId,
+			POLICY_MGR_BAND_5) ||
+			sta_sap_scc_on_dfs_chan)))) {
+		/*
+		 * validate target channel switch w.r.t various concurrency
+		 * rules set.
+		 */
+		if (!strict) {
+			valid = wlan_sap_validate_channel_switch(mac_handle,
+								 targetChannel,
+								 sapContext);
+			if (!valid) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  FL("Channel switch to %u is not allowed due to concurrent channel interference"),
+					  targetChannel);
+				return QDF_STATUS_E_FAULT;
+			}
+		}
+		/*
+		 * Post a CSA IE request to SAP state machine with
+		 * target channel information and also CSA IE required
+		 * flag set in sapContext only, if SAP is in SAP_STARTED
+		 * state.
+		 */
+		if (sapContext->fsm_state == SAP_STARTED) {
+			status = wlansap_update_csa_channel_params(sapContext,
+					targetChannel);
+			if (status != QDF_STATUS_SUCCESS)
+				return status;
+
+			/*
+			 * Copy the requested target channel
+			 * to sap context.
+			 */
+			mac->sap.SapDfsInfo.target_channel = targetChannel;
+			mac->sap.SapDfsInfo.new_ch_params.ch_width =
+				mac->sap.SapDfsInfo.new_chanWidth;
+
+			/* By this time, the best bandwidth is calculated for
+			 * the given target channel. Now, if there was a
+			 * request from user to move to a selected bandwidth,
+			 * we can see if it can be honored.
+			 *
+			 * Ex1: BW80 was selected for the target channel and
+			 * user wants BW40, it can be allowed
+			 * Ex2: BW40 was selected for the target channel and
+			 * user wants BW80, it cannot be allowed for the given
+			 * target channel.
+			 *
+			 * So, the MIN of the selected channel bandwidth and
+			 * user input is used for the bandwidth
+			 */
+			if (target_bw != CH_WIDTH_MAX) {
+				QDF_TRACE(QDF_MODULE_ID_SAP,
+					QDF_TRACE_LEVEL_INFO,
+					"%s: target bw:%d new width:%d",
+					__func__, target_bw,
+					mac->sap.SapDfsInfo.
+					new_ch_params.ch_width);
+				mac->sap.SapDfsInfo.new_ch_params.ch_width =
+					mac->sap.SapDfsInfo.new_chanWidth =
+					QDF_MIN(mac->sap.SapDfsInfo.
+							new_ch_params.ch_width,
+							target_bw);
+			}
+			wlan_reg_set_channel_params(mac->pdev, targetChannel,
+				0, &mac->sap.SapDfsInfo.new_ch_params);
+			/*
+			 * Set the CSA IE required flag.
+			 */
+			mac->sap.SapDfsInfo.csaIERequired = true;
+
+			/*
+			 * Set the radar found status to allow the channel
+			 * change to happen same as in the case of a radar
+			 * detection. Since, this will allow SAP to be in
+			 * correct state and also resume the netif queues
+			 * that were suspended in HDD before the channel
+			 * request was issued.
+			 */
+			mac->sap.SapDfsInfo.sap_radar_found_status = true;
+			mac->sap.SapDfsInfo.cac_state =
+					eSAP_DFS_DO_NOT_SKIP_CAC;
+			sap_cac_reset_notify(mac_handle);
+#ifdef CONFIG_VDEV_SM
+			sme_csa_restart(mac, sapContext->sessionId);
+#else
+			/*
+			 * Post the eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START
+			 * to SAP state machine to process the channel
+			 * request with CSA IE set in the beacons.
+			 */
+			sapEvent.event =
+				eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START;
+			sapEvent.params = 0;
+			sapEvent.u1 = 0;
+			sapEvent.u2 = 0;
+
+			sap_fsm(sapContext, &sapEvent);
+#endif
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Failed to request Channel Change, since SAP is not in SAP_STARTED state",
+				  __func__);
+			return QDF_STATUS_E_FAULT;
+		}
+
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Channel = %d is not valid in the current"
+			  "regulatory domain", __func__, targetChannel);
+
+		return QDF_STATUS_E_FAULT;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "%s: Posted eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START successfully to sap_fsm for Channel = %d",
+		  __func__, targetChannel);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlansap_set_key_sta(struct sap_context *sap_ctx,
+			       tCsrRoamSetKey *key_info)
+{
+	uint32_t roam_id = INVALID_ROAM_ID;
+	struct mac_context *mac;
+
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer",
+			  __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	return sme_roam_set_key(MAC_HANDLE(mac), sap_ctx->sessionId,
+				key_info, &roam_id);
+}
+
+QDF_STATUS wlan_sap_getstation_ie_information(struct sap_context *sap_ctx,
+					      uint32_t *len, uint8_t *buf)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	uint32_t ie_len = 0;
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("Invalid SAP pointer"));
+		return QDF_STATUS_E_FAULT;
+	}
+
+	if (len) {
+		ie_len = *len;
+		*len = sap_ctx->nStaWPARSnReqIeLength;
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			FL("WPAIE len : %x"), *len);
+		if ((buf) && (ie_len >= sap_ctx->nStaWPARSnReqIeLength)) {
+			qdf_mem_copy(buf,
+				sap_ctx->pStaWpaRsnReqIE,
+				sap_ctx->nStaWPARSnReqIeLength);
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+				FL("WPAIE: %02x:%02x:%02x:%02x:%02x:%02x"),
+				buf[0], buf[1], buf[2], buf[3], buf[4],
+				buf[5]);
+			qdf_status = QDF_STATUS_SUCCESS;
+		}
+	}
+	return qdf_status;
+}
+
+QDF_STATUS wlan_sap_update_next_channel(struct sap_context *sap_ctx,
+					uint8_t channel,
+					enum phy_ch_width chan_bw)
+{
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	sap_ctx->dfs_vendor_channel = channel;
+	sap_ctx->dfs_vendor_chan_bw = chan_bw;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_SAP_COND_CHAN_SWITCH
+QDF_STATUS wlan_sap_set_pre_cac_status(struct sap_context *sap_ctx,
+				       bool status)
+{
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	sap_ctx->is_pre_cac_on = status;
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+		"%s: is_pre_cac_on:%d", __func__, sap_ctx->is_pre_cac_on);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_sap_set_chan_before_pre_cac(struct sap_context *sap_ctx,
+					    uint8_t chan_before_pre_cac)
+{
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	sap_ctx->chan_before_pre_cac = chan_before_pre_cac;
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_SAP_COND_CHAN_SWITCH */
+
+QDF_STATUS wlan_sap_set_pre_cac_complete_status(struct sap_context *sap_ctx,
+						bool status)
+{
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	sap_ctx->pre_cac_complete = status;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			"%s: pre cac complete status:%d session:%d",
+			__func__, status, sap_ctx->sessionId);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_sap_is_pre_cac_active() - Checks if pre cac in in progress
+ * @handle: Global MAC handle
+ *
+ * Checks if pre cac is in progress in any of the SAP contexts
+ *
+ * Return: True is pre cac is active, false otherwise
+ */
+bool wlan_sap_is_pre_cac_active(tHalHandle handle)
+{
+	tpAniSirGlobal mac = NULL;
+	int i;
+
+	mac = PMAC_STRUCT(handle);
+	if (!mac) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			"%s: Invalid mac context", __func__);
+		return false;
+	}
+
+	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
+		struct sap_context *context =
+			mac->sap.sapCtxList[i].sap_context;
+		if (context && context->is_pre_cac_on)
+			return true;
+	}
+	return false;
+}
+
+/**
+ * wlan_sap_get_pre_cac_vdev_id() - Get vdev id of the pre cac interface
+ * @handle: Global handle
+ * @vdev_id: vdev id
+ *
+ * Fetches the vdev id of the pre cac interface
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_sap_get_pre_cac_vdev_id(tHalHandle handle, uint8_t *vdev_id)
+{
+	tpAniSirGlobal mac = NULL;
+	uint8_t i;
+
+	mac = PMAC_STRUCT(handle);
+	if (!mac) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			"%s: Invalid mac context", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
+		struct sap_context *context =
+			mac->sap.sapCtxList[i].sap_context;
+		if (context && context->is_pre_cac_on) {
+			*vdev_id = i;
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wlansap_register_mgmt_frame(struct sap_context *sap_ctx,
+				       uint16_t frameType,
+				       uint8_t *matchData,
+				       uint16_t matchLen)
+{
+	struct mac_context *mac;
+	QDF_STATUS status;
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer from pCtx",
+			  __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	status = sme_register_mgmt_frame(MAC_HANDLE(mac), sap_ctx->sessionId,
+					 frameType, matchData, matchLen);
+	if (QDF_IS_STATUS_ERROR(status))
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "Failed to Register MGMT frame");
+
+	return status;
+}
+
+QDF_STATUS wlansap_de_register_mgmt_frame(struct sap_context *sap_ctx,
+					  uint16_t frameType,
+					  uint8_t *matchData,
+					  uint16_t matchLen)
+{
+	struct mac_context *mac;
+	QDF_STATUS status;
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer from pCtx",
+			  __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	status = sme_deregister_mgmt_frame(MAC_HANDLE(mac), sap_ctx->sessionId,
+					   frameType, matchData, matchLen);
+	if (QDF_IS_STATUS_ERROR(status))
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "Failed to Deregister MGMT frame");
+
+	return status;
+}
+
+QDF_STATUS wlansap_channel_change_request(struct sap_context *sapContext,
+					  uint8_t target_channel)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct mac_context *mac_ctx;
+	eCsrPhyMode phy_mode;
+	struct ch_params *ch_params;
+
+	if (!target_channel) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: channel 0 requested", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	if (NULL == sapContext) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	phy_mode = sapContext->csr_roamProfile.phyMode;
+
+	/* Update phy_mode if the target channel is in the other band */
+	if (WLAN_CHAN_IS_5GHZ(target_channel) &&
+	    ((phy_mode == eCSR_DOT11_MODE_11g) ||
+	    (phy_mode == eCSR_DOT11_MODE_11g_ONLY)))
+		phy_mode = eCSR_DOT11_MODE_11a;
+	else if (WLAN_CHAN_IS_2GHZ(target_channel) &&
+		 (phy_mode == eCSR_DOT11_MODE_11a))
+		phy_mode = eCSR_DOT11_MODE_11g;
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: phy_mode: %d, target_channel: %d new phy_mode: %d",
+		  __func__, sapContext->csr_roamProfile.phyMode,
+		  target_channel, phy_mode);
+	sapContext->csr_roamProfile.phyMode = phy_mode;
+
+	if (sapContext->csr_roamProfile.ChannelInfo.numOfChannels == 0 ||
+	    sapContext->csr_roamProfile.ChannelInfo.ChannelList == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("Invalid channel list"));
+		return QDF_STATUS_E_FAULT;
+	}
+	sapContext->csr_roamProfile.ChannelInfo.ChannelList[0] = target_channel;
+	/*
+	 * We are getting channel bonding mode from sapDfsInfor structure
+	 * because we've implemented channel width fallback mechanism for DFS
+	 * which will result in channel width changing dynamically.
+	 */
+	ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
+	wlan_reg_set_channel_params(mac_ctx->pdev, target_channel,
+			0, ch_params);
+	sapContext->ch_params.ch_width = ch_params->ch_width;
+	/* Update the channel as this will be used to
+	 * send event to supplicant
+	 */
+	sapContext->channel = target_channel;
+	sapContext->csr_roamProfile.ch_params.ch_width = ch_params->ch_width;
+	sapContext->csr_roamProfile.ch_params.sec_ch_offset =
+						ch_params->sec_ch_offset;
+	sapContext->csr_roamProfile.ch_params.center_freq_seg0 =
+						ch_params->center_freq_seg0;
+	sapContext->csr_roamProfile.ch_params.center_freq_seg1 =
+						ch_params->center_freq_seg1;
+	sap_dfs_set_current_channel(sapContext);
+
+	status = sme_roam_channel_change_req(MAC_HANDLE(mac_ctx),
+					     sapContext->bssid,
+					     ch_params,
+					     &sapContext->csr_roamProfile);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+		"%s: chan:%d phy_mode %d width:%d offset:%d seg0:%d seg1:%d",
+		__func__, sapContext->channel, phy_mode, ch_params->ch_width,
+		ch_params->sec_ch_offset, ch_params->center_freq_seg0,
+		ch_params->center_freq_seg1);
+
+	if (QDF_IS_STATUS_SUCCESS(status))
+		sap_signal_hdd_event(sapContext, NULL,
+				     eSAP_CHANNEL_CHANGE_EVENT,
+				     (void *) eSAP_STATUS_SUCCESS);
+
+	return status;
+}
+
+QDF_STATUS wlansap_start_beacon_req(struct sap_context *sap_ctx)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t dfs_cac_wait_status;
+	struct mac_context *mac;
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	/* No Radar was found during CAC WAIT, So start Beaconing */
+	if (mac->sap.SapDfsInfo.sap_radar_found_status == false) {
+		/* CAC Wait done without any Radar Detection */
+		dfs_cac_wait_status = true;
+		sap_ctx->pre_cac_complete = false;
+		status = sme_roam_start_beacon_req(MAC_HANDLE(mac),
+						   sap_ctx->bssid,
+						   dfs_cac_wait_status);
+	}
+
+	return status;
+}
+
+QDF_STATUS wlansap_dfs_send_csa_ie_request(struct sap_context *sap_ctx)
+{
+	struct mac_context *pMac;
+
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	pMac = sap_get_mac_context();
+	if (!pMac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	pMac->sap.SapDfsInfo.new_ch_params.ch_width =
+				pMac->sap.SapDfsInfo.new_chanWidth;
+	wlan_reg_set_channel_params(pMac->pdev,
+			pMac->sap.SapDfsInfo.target_channel,
+			0, &pMac->sap.SapDfsInfo.new_ch_params);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			"%s: chan:%d req:%d width:%d off:%d",
+			__func__, pMac->sap.SapDfsInfo.target_channel,
+			pMac->sap.SapDfsInfo.csaIERequired,
+			pMac->sap.SapDfsInfo.new_ch_params.ch_width,
+			pMac->sap.SapDfsInfo.new_ch_params.sec_ch_offset);
+
+	return sme_roam_csa_ie_request(MAC_HANDLE(pMac),
+				       sap_ctx->bssid,
+				       pMac->sap.SapDfsInfo.target_channel,
+				       pMac->sap.SapDfsInfo.csaIERequired,
+				       &pMac->sap.SapDfsInfo.new_ch_params);
+}
+
+/*==========================================================================
+   FUNCTION    wlansap_get_dfs_ignore_cac
+
+   DESCRIPTION
+   This API is used to get the value of ignore_cac value
+
+   DEPENDENCIES
+   NA.
+
+   PARAMETERS
+   IN
+   hHal : HAL pointer
+   pIgnore_cac : pointer to ignore_cac variable
+
+   RETURN VALUE
+   The QDF_STATUS code associated with performing the operation
+
+   QDF_STATUS_SUCCESS:  Success
+
+   SIDE EFFECTS
+   ============================================================================*/
+QDF_STATUS wlansap_get_dfs_ignore_cac(tHalHandle hHal, uint8_t *pIgnore_cac)
+{
+	tpAniSirGlobal pMac = NULL;
+
+	if (NULL != hHal) {
+		pMac = PMAC_STRUCT(hHal);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid hHal pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	*pIgnore_cac = pMac->sap.SapDfsInfo.ignore_cac;
+	return QDF_STATUS_SUCCESS;
+}
+
+/*==========================================================================
+   FUNCTION    wlansap_set_dfs_ignore_cac
+
+   DESCRIPTION
+   This API is used to Set the value of ignore_cac value
+
+   DEPENDENCIES
+   NA.
+
+   PARAMETERS
+   IN
+   hHal : HAL pointer
+   ignore_cac : value to set for ignore_cac variable in DFS global structure.
+
+   RETURN VALUE
+   The QDF_STATUS code associated with performing the operation
+
+   QDF_STATUS_SUCCESS:  Success
+
+   SIDE EFFECTS
+   ============================================================================*/
+QDF_STATUS wlansap_set_dfs_ignore_cac(tHalHandle hHal, uint8_t ignore_cac)
+{
+	tpAniSirGlobal pMac = NULL;
+
+	if (NULL != hHal) {
+		pMac = PMAC_STRUCT(hHal);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid hHal pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	pMac->sap.SapDfsInfo.ignore_cac = (ignore_cac >= true) ?
+					  true : false;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlansap_set_dfs_restrict_japan_w53() - enable/disable dfS for japan
+ * @hHal : HAL pointer
+ * @disable_Dfs_JapanW3 :Indicates if Japan W53 is disabled when set to 1
+ *                       Indicates if Japan W53 is enabled when set to 0
+ *
+ * This API is used to enable or disable Japan W53 Band
+ * Return: The QDF_STATUS code associated with performing the operation
+ *         QDF_STATUS_SUCCESS:  Success
+ */
+QDF_STATUS
+wlansap_set_dfs_restrict_japan_w53(tHalHandle hHal, uint8_t disable_Dfs_W53)
+{
+	tpAniSirGlobal pMac = NULL;
+	QDF_STATUS status;
+	enum dfs_reg dfs_region;
+
+	if (NULL != hHal) {
+		pMac = PMAC_STRUCT(hHal);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid hHal pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	wlan_reg_get_dfs_region(pMac->pdev, &dfs_region);
+
+	/*
+	 * Set the JAPAN W53 restriction only if the current
+	 * regulatory domain is JAPAN.
+	 */
+	if (DFS_MKK_REGION == dfs_region) {
+		pMac->sap.SapDfsInfo.is_dfs_w53_disabled = disable_Dfs_W53;
+		QDF_TRACE(QDF_MODULE_ID_SAP,
+			  QDF_TRACE_LEVEL_INFO_LOW,
+			  FL("sapdfs: SET DFS JAPAN W53 DISABLED = %d"),
+			  pMac->sap.SapDfsInfo.is_dfs_w53_disabled);
+
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL
+			 ("Regdomain not japan, set disable JP W53 not valid"));
+
+		status = QDF_STATUS_E_FAULT;
+	}
+
+	return status;
+}
+
+bool sap_is_auto_channel_select(struct sap_context *sapcontext)
+{
+	if (NULL == sapcontext) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"%s: Invalid SAP pointer", __func__);
+		return false;
+	}
+	return sapcontext->channel == AUTO_CHANNEL_SELECT;
+}
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+/**
+ * wlan_sap_set_channel_avoidance() - sets sap mcc channel avoidance ini param
+ * @hal:                        hal handle
+ * @sap_channel_avoidance:      ini parameter value
+ *
+ * sets sap mcc channel avoidance ini param, to be called in sap_start
+ *
+ * Return: success of failure of operation
+ */
+QDF_STATUS
+wlan_sap_set_channel_avoidance(tHalHandle hal, bool sap_channel_avoidance)
+{
+	tpAniSirGlobal mac_ctx = NULL;
+
+	if (NULL != hal) {
+		mac_ctx = PMAC_STRUCT(hal);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP,
+			  QDF_TRACE_LEVEL_ERROR,
+			  FL("hal or mac_ctx pointer NULL"));
+		return QDF_STATUS_E_FAULT;
+	}
+	mac_ctx->sap.sap_channel_avoidance = sap_channel_avoidance;
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+/**
+ * wlansap_set_dfs_preferred_channel_location() - set dfs preferred channel
+ * @hHal : HAL pointer
+ * @dfs_Preferred_Channels_location :
+ *       0 - Indicates No preferred channel location restrictions
+ *       1 - Indicates SAP Indoor Channels operation only.
+ *       2 - Indicates SAP Outdoor Channels operation only.
+ *
+ * This API is used to set sap preferred channels location
+ * to resetrict the DFS random channel selection algorithm
+ * either Indoor/Outdoor channels only.
+ *
+ * Return: The QDF_STATUS code associated with performing the operation
+ *         QDF_STATUS_SUCCESS:  Success and error code otherwise.
+ */
+QDF_STATUS
+wlansap_set_dfs_preferred_channel_location(tHalHandle hHal,
+					   uint8_t
+					   dfs_Preferred_Channels_location)
+{
+	tpAniSirGlobal pMac = NULL;
+	QDF_STATUS status;
+	enum dfs_reg dfs_region;
+
+	if (NULL != hHal) {
+		pMac = PMAC_STRUCT(hHal);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid hHal pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	wlan_reg_get_dfs_region(pMac->pdev, &dfs_region);
+
+	/*
+	 * The Indoor/Outdoor only random channel selection
+	 * restriction is currently enforeced only for
+	 * JAPAN regulatory domain.
+	 */
+	if (DFS_MKK_REGION == dfs_region) {
+		pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location =
+			dfs_Preferred_Channels_location;
+		QDF_TRACE(QDF_MODULE_ID_SAP,
+			  QDF_TRACE_LEVEL_INFO_LOW,
+			  FL
+				  ("sapdfs:Set Preferred Operating Channel location=%d"),
+			  pMac->sap.SapDfsInfo.
+			  sap_operating_chan_preferred_location);
+
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  FL
+				  ("sapdfs:NOT JAPAN REG, Invalid Set preferred chans location"));
+
+		status = QDF_STATUS_E_FAULT;
+	}
+
+	return status;
+}
+
+/*==========================================================================
+   FUNCTION    wlansap_set_dfs_target_chnl
+
+   DESCRIPTION
+   This API is used to set next target chnl as provided channel.
+   you can provide any valid channel to this API.
+
+   DEPENDENCIES
+   NA.
+
+   PARAMETERS
+   IN
+   hHal : HAL pointer
+   target_channel : target channel to be set
+
+   RETURN VALUE
+   The QDF_STATUS code associated with performing the operation
+
+   QDF_STATUS_SUCCESS:  Success
+
+   SIDE EFFECTS
+   ============================================================================*/
+QDF_STATUS wlansap_set_dfs_target_chnl(tHalHandle hHal, uint8_t target_channel)
+{
+	tpAniSirGlobal pMac = NULL;
+
+	if (NULL != hHal) {
+		pMac = PMAC_STRUCT(hHal);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid hHal pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+	if (target_channel > 0) {
+		pMac->sap.SapDfsInfo.user_provided_target_channel =
+			target_channel;
+	} else {
+		pMac->sap.SapDfsInfo.user_provided_target_channel = 0;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlansap_update_sap_config_add_ie(tsap_config_t *pConfig,
+				 const uint8_t *pAdditionIEBuffer,
+				 uint16_t additionIELength,
+				 eUpdateIEsType updateType)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t bufferValid = false;
+	uint16_t bufferLength = 0;
+	uint8_t *pBuffer = NULL;
+
+	if (NULL == pConfig) {
+		return QDF_STATUS_E_FAULT;
+	}
+
+	if ((pAdditionIEBuffer != NULL) && (additionIELength != 0)) {
+		/* initialize the buffer pointer so that pe can copy */
+		if (additionIELength > 0) {
+			bufferLength = additionIELength;
+			pBuffer = qdf_mem_malloc(bufferLength);
+			if (!pBuffer)
+				return QDF_STATUS_E_NOMEM;
+
+			qdf_mem_copy(pBuffer, pAdditionIEBuffer, bufferLength);
+			bufferValid = true;
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+				  FL("update_type: %d"), updateType);
+			qdf_trace_hex_dump(QDF_MODULE_ID_SAP,
+				QDF_TRACE_LEVEL_INFO, pBuffer, bufferLength);
+		}
+	}
+
+	switch (updateType) {
+	case eUPDATE_IE_PROBE_BCN:
+		if (pConfig->pProbeRespBcnIEsBuffer)
+			qdf_mem_free(pConfig->pProbeRespBcnIEsBuffer);
+		if (bufferValid) {
+			pConfig->probeRespBcnIEsLen = bufferLength;
+			pConfig->pProbeRespBcnIEsBuffer = pBuffer;
+		} else {
+			pConfig->probeRespBcnIEsLen = 0;
+			pConfig->pProbeRespBcnIEsBuffer = NULL;
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+				  FL("No Probe Resp beacone IE received in set beacon"));
+		}
+		break;
+	case eUPDATE_IE_PROBE_RESP:
+		if (pConfig->pProbeRespIEsBuffer)
+			qdf_mem_free(pConfig->pProbeRespIEsBuffer);
+		if (bufferValid) {
+			pConfig->probeRespIEsBufferLen = bufferLength;
+			pConfig->pProbeRespIEsBuffer = pBuffer;
+		} else {
+			pConfig->probeRespIEsBufferLen = 0;
+			pConfig->pProbeRespIEsBuffer = NULL;
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+				  FL("No Probe Response IE received in set beacon"));
+		}
+		break;
+	case eUPDATE_IE_ASSOC_RESP:
+		if (pConfig->pAssocRespIEsBuffer)
+			qdf_mem_free(pConfig->pAssocRespIEsBuffer);
+		if (bufferValid) {
+			pConfig->assocRespIEsLen = bufferLength;
+			pConfig->pAssocRespIEsBuffer = pBuffer;
+		} else {
+			pConfig->assocRespIEsLen = 0;
+			pConfig->pAssocRespIEsBuffer = NULL;
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+				  FL("No Assoc Response IE received in set beacon"));
+		}
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
+			  FL("No matching buffer type %d"), updateType);
+		if (pBuffer != NULL)
+			qdf_mem_free(pBuffer);
+		break;
+	}
+
+	return status;
+}
+
+QDF_STATUS
+wlansap_reset_sap_config_add_ie(tsap_config_t *pConfig, eUpdateIEsType updateType)
+{
+	if (NULL == pConfig) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid Config pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	switch (updateType) {
+	case eUPDATE_IE_ALL:    /*only used to reset */
+	case eUPDATE_IE_PROBE_RESP:
+		if (pConfig->pProbeRespIEsBuffer) {
+			qdf_mem_free(pConfig->pProbeRespIEsBuffer);
+			pConfig->probeRespIEsBufferLen = 0;
+			pConfig->pProbeRespIEsBuffer = NULL;
+		}
+		if (eUPDATE_IE_ALL != updateType)
+			break;
+
+	case eUPDATE_IE_ASSOC_RESP:
+		if (pConfig->pAssocRespIEsBuffer) {
+			qdf_mem_free(pConfig->pAssocRespIEsBuffer);
+			pConfig->assocRespIEsLen = 0;
+			pConfig->pAssocRespIEsBuffer = NULL;
+		}
+		if (eUPDATE_IE_ALL != updateType)
+			break;
+
+	case eUPDATE_IE_PROBE_BCN:
+		if (pConfig->pProbeRespBcnIEsBuffer) {
+			qdf_mem_free(pConfig->pProbeRespBcnIEsBuffer);
+			pConfig->probeRespBcnIEsLen = 0;
+			pConfig->pProbeRespBcnIEsBuffer = NULL;
+		}
+		if (eUPDATE_IE_ALL != updateType)
+			break;
+
+	default:
+		if (eUPDATE_IE_ALL != updateType)
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid buffer type %d"), updateType);
+		break;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/*==========================================================================
+   FUNCTION  wlansap_extend_to_acs_range
+
+   DESCRIPTION Function extends give channel range to consider ACS chan bonding
+
+   DEPENDENCIES PARAMETERS
+
+   IN /OUT
+   *startChannelNum : ACS extend start ch
+   *endChannelNum   : ACS extended End ch
+   *bandStartChannel: Band start ch
+   *bandEndChannel  : Band end ch
+
+   RETURN VALUE NONE
+
+   SIDE EFFECTS
+   ============================================================================*/
+void wlansap_extend_to_acs_range(tHalHandle hal, uint8_t *startChannelNum,
+		uint8_t *endChannelNum, uint8_t *bandStartChannel,
+		uint8_t *bandEndChannel)
+{
+#define ACS_WLAN_20M_CH_INC 4
+#define ACS_2G_EXTEND ACS_WLAN_20M_CH_INC
+#define ACS_5G_EXTEND (ACS_WLAN_20M_CH_INC * 3)
+
+	uint8_t tmp_startChannelNum = 0, tmp_endChannelNum = 0;
+	tpAniSirGlobal mac_ctx;
+
+	mac_ctx = PMAC_STRUCT(hal);
+	if (!mac_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"%s: Invalid mac_ctx", __func__);
+		return;
+	}
+	if (*startChannelNum <= 14 && *endChannelNum <= 14) {
+		*bandStartChannel = CHAN_ENUM_1;
+		*bandEndChannel = CHAN_ENUM_14;
+		tmp_startChannelNum = *startChannelNum > 5 ?
+				   (*startChannelNum - ACS_2G_EXTEND) : 1;
+		tmp_endChannelNum = (*endChannelNum + ACS_2G_EXTEND) <= 14 ?
+				 (*endChannelNum + ACS_2G_EXTEND) : 14;
+	} else if (*startChannelNum >= 36 && *endChannelNum >= 36) {
+		*bandStartChannel = CHAN_ENUM_36;
+		*bandEndChannel = CHAN_ENUM_173;
+		tmp_startChannelNum = (*startChannelNum - ACS_5G_EXTEND) > 36 ?
+				   (*startChannelNum - ACS_5G_EXTEND) : 36;
+		tmp_endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <=
+				     WNI_CFG_CURRENT_CHANNEL_STAMAX ?
+				     (*endChannelNum + ACS_5G_EXTEND) :
+				     WNI_CFG_CURRENT_CHANNEL_STAMAX;
+	} else {
+		*bandStartChannel = CHAN_ENUM_1;
+		*bandEndChannel = CHAN_ENUM_173;
+		tmp_startChannelNum = *startChannelNum > 5 ?
+			(*startChannelNum - ACS_2G_EXTEND) : 1;
+		tmp_endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <=
+				     WNI_CFG_CURRENT_CHANNEL_STAMAX ?
+				     (*endChannelNum + ACS_5G_EXTEND) :
+				     WNI_CFG_CURRENT_CHANNEL_STAMAX;
+	}
+
+	/* Note if the ACS range include only DFS channels, do not cross range
+	* Active scanning in adjacent non DFS channels results in transmission
+	* spikes in DFS specturm channels which is due to emission spill.
+	* Remove the active channels from extend ACS range for DFS only range
+	*/
+	if (wlan_reg_is_dfs_ch(mac_ctx->pdev, *startChannelNum)) {
+		while (!wlan_reg_is_dfs_ch(mac_ctx->pdev,
+					tmp_startChannelNum) &&
+			tmp_startChannelNum < *startChannelNum)
+			tmp_startChannelNum += ACS_WLAN_20M_CH_INC;
+
+		*startChannelNum = tmp_startChannelNum;
+	}
+	if (wlan_reg_is_dfs_ch(mac_ctx->pdev, *endChannelNum)) {
+		while (!wlan_reg_is_dfs_ch(mac_ctx->pdev,
+					tmp_endChannelNum) &&
+				 tmp_endChannelNum > *endChannelNum)
+			tmp_endChannelNum -= ACS_WLAN_20M_CH_INC;
+
+		*endChannelNum = tmp_endChannelNum;
+	}
+}
+
+QDF_STATUS wlan_sap_set_vendor_acs(struct sap_context *sap_context,
+				   bool is_vendor_acs)
+{
+	if (!sap_context) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+	sap_context->vendor_acs_dfs_lte_enabled = is_vendor_acs;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef DFS_COMPONENT_ENABLE
+QDF_STATUS wlansap_set_dfs_nol(struct sap_context *sap_ctx,
+			       eSapDfsNolType conf)
+{
+	struct mac_context *mac;
+
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	if (conf == eSAP_DFS_NOL_CLEAR) {
+		struct wlan_objmgr_pdev *pdev;
+
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: clear the DFS NOL", __func__);
+
+		pdev = mac->pdev;
+		if (!pdev) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  "%s: null pdev", __func__);
+			return QDF_STATUS_E_FAULT;
+		}
+		utils_dfs_clear_nol_channels(pdev);
+	} else if (conf == eSAP_DFS_NOL_RANDOMIZE) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Randomize the DFS NOL", __func__);
+
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: unsupport type %d", __func__, conf);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * wlansap_populate_del_sta_params() - populate delete station parameter
+ * @mac:           Pointer to peer mac address.
+ * @reason_code:   Reason code for the disassoc/deauth.
+ * @subtype:       Subtype points to either disassoc/deauth frame.
+ * @pDelStaParams: Address where parameters to be populated.
+ *
+ * This API is used to populate delete station parameter structure
+ *
+ * Return: none
+ */
+
+void wlansap_populate_del_sta_params(const uint8_t *mac,
+				     uint16_t reason_code,
+				     uint8_t subtype,
+				     struct csr_del_sta_params *pDelStaParams)
+{
+	if (NULL == mac)
+		qdf_set_macaddr_broadcast(&pDelStaParams->peerMacAddr);
+	else
+		qdf_mem_copy(pDelStaParams->peerMacAddr.bytes, mac,
+			     QDF_MAC_ADDR_SIZE);
+
+	if (reason_code == 0)
+		pDelStaParams->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
+	else
+		pDelStaParams->reason_code = reason_code;
+
+	if (subtype == (SIR_MAC_MGMT_DEAUTH >> 4) ||
+	    subtype == (SIR_MAC_MGMT_DISASSOC >> 4))
+		pDelStaParams->subtype = subtype;
+	else
+		pDelStaParams->subtype = (SIR_MAC_MGMT_DEAUTH >> 4);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+		  FL(
+		     "Delete STA with RC:%hu subtype:%hhu MAC::"
+		     MAC_ADDRESS_STR),
+		  pDelStaParams->reason_code, pDelStaParams->subtype,
+		  MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr.bytes));
+}
+
+QDF_STATUS wlansap_acs_chselect(struct sap_context *sap_context,
+				tpWLAN_SAPEventCB pacs_event_callback,
+				tsap_config_t *pconfig,
+				void *pusr_context)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	struct mac_context *mac;
+
+	if (NULL == sap_context) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"%s: Invalid SAP pointer", __func__);
+
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	sap_context->acs_cfg = &pconfig->acs_cfg;
+	sap_context->ch_width_orig = pconfig->acs_cfg.ch_width;
+	sap_context->csr_roamProfile.phyMode = pconfig->acs_cfg.hw_mode;
+
+	/*
+	 * Now, configure the scan and ACS channel params
+	 * to issue a scan request.
+	 */
+	wlansap_set_scan_acs_channel_params(pconfig, sap_context,
+						pusr_context);
+
+	/*
+	 * Copy the HDD callback function to report the
+	 * ACS result after scan in SAP context callback function.
+	 */
+	sap_context->pfnSapEventCallback = pacs_event_callback;
+	/*
+	 * init dfs channel nol
+	 */
+	sap_init_dfs_channel_nol_list(sap_context);
+
+	/*
+	 * Issue the scan request. This scan request is
+	 * issued before the start BSS is done so
+	 *
+	 * 1. No need to pass the second parameter
+	 * as the SAP state machine is not started yet
+	 * and there is no need for any event posting.
+	 *
+	 * 2. Set third parameter to TRUE to indicate the
+	 * channel selection function to register a
+	 * different scan callback function to process
+	 * the results pre start BSS.
+	 */
+	qdf_status = sap_channel_sel(sap_context);
+
+	if (QDF_STATUS_E_ABORTED == qdf_status) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"In %s,DFS not supported in the current operating mode",
+			__func__);
+		return QDF_STATUS_E_FAILURE;
+	} else if (QDF_STATUS_E_CANCELED == qdf_status) {
+		/*
+		* ERROR is returned when either the SME scan request
+		* failed or ACS is overridden due to other constrainst
+		* So send selected channel to HDD
+		*/
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("Scan Req Failed/ACS Overridden"));
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("Selected channel = %d"),
+			sap_context->channel);
+
+		return sap_signal_hdd_event(sap_context, NULL,
+				eSAP_ACS_CHANNEL_SELECTED,
+				(void *) eSAP_STATUS_SUCCESS);
+	} else if (QDF_STATUS_SUCCESS == qdf_status) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+			FL("Successfully Issued a Pre Start Bss Scan Request"));
+	}
+	return qdf_status;
+}
+
+/**
+ * wlan_sap_enable_phy_error_logs() - Enable DFS phy error logs
+ * @hal:        global hal handle
+ * @enable_log: value to set
+ *
+ * Since the frequency of DFS phy error is very high, enabling logs for them
+ * all the times can cause crash and will also create lot of useless logs
+ * causing difficulties in debugging other issue. This function will be called
+ * from iwpriv cmd to eanble such logs temporarily.
+ *
+ * Return: void
+ */
+void wlan_sap_enable_phy_error_logs(tHalHandle hal, uint32_t enable_log)
+{
+	int error;
+
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	mac_ctx->sap.enable_dfs_phy_error_logs = !!enable_log;
+	tgt_dfs_control(mac_ctx->pdev, DFS_SET_DEBUG_LEVEL, &enable_log,
+			sizeof(uint32_t), NULL, NULL, &error);
+}
+
+uint32_t wlansap_get_chan_width(struct sap_context *sap_ctx)
+{
+	return wlan_sap_get_vht_ch_width(sap_ctx);
+}
+
+QDF_STATUS wlansap_set_tx_leakage_threshold(tHalHandle hal,
+			uint16_t tx_leakage_threshold)
+{
+	tpAniSirGlobal mac;
+
+	if (NULL == hal) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			"%s: Invalid hal pointer", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	mac = PMAC_STRUCT(hal);
+	tgt_dfs_set_tx_leakage_threshold(mac->pdev, tx_leakage_threshold);
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: leakage_threshold %d", __func__,
+		  tx_leakage_threshold);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlansap_set_invalid_session(struct sap_context *sap_ctx)
+{
+	if (NULL == sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("Invalid SAP pointer"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sap_release_vdev_ref(sap_ctx);
+
+	sap_ctx->sessionId = CSR_SESSION_ID_INVALID;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wlansap_cleanup_cac_timer(struct sap_context *sap_ctx)
+{
+	struct mac_context *mac;
+
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("Invalid SAP context"));
+		return;
+	}
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
+		return;
+	}
+
+	if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+		qdf_mc_timer_stop(&mac->sap.SapDfsInfo.
+				  sap_dfs_cac_timer);
+		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
+		qdf_mc_timer_destroy(
+			&mac->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
new file mode 100644
index 0000000..4680199
--- /dev/null
+++ b/core/sme/inc/csr_api.h
@@ -0,0 +1,1673 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ *   \file csr_api.h
+ *
+ *   Exports and types for the Common Scan and Roaming Module interfaces.
+ */
+
+#ifndef CSRAPI_H__
+#define CSRAPI_H__
+
+#include "sir_api.h"
+#include "sir_mac_prot_def.h"
+#include "csr_link_list.h"
+#include "wlan_scan_public_structs.h"
+
+#define CSR_INVALID_SCANRESULT_HANDLE       (NULL)
+#define CSR_NUM_WLM_LATENCY_LEVEL   4
+
+typedef enum {
+	/* never used */
+	eCSR_AUTH_TYPE_NONE,
+	/* MAC layer authentication types */
+	eCSR_AUTH_TYPE_OPEN_SYSTEM,
+	eCSR_AUTH_TYPE_SHARED_KEY,
+	eCSR_AUTH_TYPE_SAE,
+	eCSR_AUTH_TYPE_AUTOSWITCH,
+
+	/* Upper layer authentication types */
+	eCSR_AUTH_TYPE_WPA,
+	eCSR_AUTH_TYPE_WPA_PSK,
+	eCSR_AUTH_TYPE_WPA_NONE,
+
+	eCSR_AUTH_TYPE_RSN,
+	eCSR_AUTH_TYPE_RSN_PSK,
+	eCSR_AUTH_TYPE_FT_RSN,
+	eCSR_AUTH_TYPE_FT_RSN_PSK,
+#ifdef FEATURE_WLAN_WAPI
+	eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE,
+	eCSR_AUTH_TYPE_WAPI_WAI_PSK,
+#endif /* FEATURE_WLAN_WAPI */
+	eCSR_AUTH_TYPE_CCKM_WPA,
+	eCSR_AUTH_TYPE_CCKM_RSN,
+	eCSR_AUTH_TYPE_RSN_PSK_SHA256,
+	eCSR_AUTH_TYPE_RSN_8021X_SHA256,
+	eCSR_AUTH_TYPE_FILS_SHA256,
+	eCSR_AUTH_TYPE_FILS_SHA384,
+	eCSR_AUTH_TYPE_FT_FILS_SHA256,
+	eCSR_AUTH_TYPE_FT_FILS_SHA384,
+	eCSR_AUTH_TYPE_DPP_RSN,
+	eCSR_AUTH_TYPE_OWE,
+	eCSR_AUTH_TYPE_SUITEB_EAP_SHA256,
+	eCSR_AUTH_TYPE_SUITEB_EAP_SHA384,
+	eCSR_NUM_OF_SUPPORT_AUTH_TYPE,
+	eCSR_AUTH_TYPE_FAILED = 0xff,
+	eCSR_AUTH_TYPE_UNKNOWN = eCSR_AUTH_TYPE_FAILED,
+
+} eCsrAuthType;
+
+typedef enum {
+	eCSR_ENCRYPT_TYPE_NONE,
+	eCSR_ENCRYPT_TYPE_WEP40_STATICKEY,
+	eCSR_ENCRYPT_TYPE_WEP104_STATICKEY,
+	eCSR_ENCRYPT_TYPE_WEP40,
+	eCSR_ENCRYPT_TYPE_WEP104,
+	eCSR_ENCRYPT_TYPE_TKIP,
+	eCSR_ENCRYPT_TYPE_AES,/* CCMP */
+#ifdef FEATURE_WLAN_WAPI
+	/* WAPI */
+	eCSR_ENCRYPT_TYPE_WPI,
+#endif  /* FEATURE_WLAN_WAPI */
+	eCSR_ENCRYPT_TYPE_KRK,
+	eCSR_ENCRYPT_TYPE_BTK,
+	eCSR_ENCRYPT_TYPE_AES_CMAC,
+	eCSR_ENCRYPT_TYPE_AES_GMAC_128,
+	eCSR_ENCRYPT_TYPE_AES_GMAC_256,
+	eCSR_ENCRYPT_TYPE_AES_GCMP,
+	eCSR_ENCRYPT_TYPE_AES_GCMP_256,
+	eCSR_ENCRYPT_TYPE_ANY,
+	eCSR_NUM_OF_ENCRYPT_TYPE = eCSR_ENCRYPT_TYPE_ANY,
+
+	eCSR_ENCRYPT_TYPE_FAILED = 0xff,
+	eCSR_ENCRYPT_TYPE_UNKNOWN = eCSR_ENCRYPT_TYPE_FAILED,
+
+} eCsrEncryptionType;
+
+/*---------------------------------------------------------------------------
+   Enumeration of the various Security types
+   ---------------------------------------------------------------------------*/
+typedef enum {
+	eCSR_SECURITY_TYPE_WPA,
+	eCSR_SECURITY_TYPE_RSN,
+#ifdef FEATURE_WLAN_WAPI
+	eCSR_SECURITY_TYPE_WAPI,
+#endif /* FEATURE_WLAN_WAPI */
+	eCSR_SECURITY_TYPE_UNKNOWN,
+
+} eCsrSecurityType;
+
+typedef enum {
+	/* 11a/b/g only, no HT, no proprietary */
+	eCSR_DOT11_MODE_abg = 0x0001,
+	eCSR_DOT11_MODE_11a = 0x0002,
+	eCSR_DOT11_MODE_11b = 0x0004,
+	eCSR_DOT11_MODE_11g = 0x0008,
+	eCSR_DOT11_MODE_11n = 0x0010,
+	eCSR_DOT11_MODE_11g_ONLY = 0x0020,
+	eCSR_DOT11_MODE_11n_ONLY = 0x0040,
+	eCSR_DOT11_MODE_11b_ONLY = 0x0080,
+	eCSR_DOT11_MODE_11ac = 0x0100,
+	eCSR_DOT11_MODE_11ac_ONLY = 0x0200,
+	/*
+	 * This is for WIFI test. It is same as eWNIAPI_MAC_PROTOCOL_ALL
+	 * except when it starts IBSS in 11B of 2.4GHz
+	 * It is for CSR internal use
+	 */
+	eCSR_DOT11_MODE_AUTO = 0x0400,
+	eCSR_DOT11_MODE_11ax = 0x0800,
+	eCSR_DOT11_MODE_11ax_ONLY = 0x1000,
+
+	/* specify the number of maximum bits for phyMode */
+	eCSR_NUM_PHY_MODE = 16,
+} eCsrPhyMode;
+
+/**
+ * enum eCsrRoamBssType - BSS type in CSR operations
+ * @eCSR_BSS_TYPE_INFRASTRUCTURE: Infrastructure station
+ * @eCSR_BSS_TYPE_INFRA_AP: SoftAP
+ * @eCSR_BSS_TYPE_IBSS: IBSS network we'll not start
+ * @eCSR_BSS_TYPE_START_IBSS: IBSS network we'll start if no partners found
+ * @eCSR_BSS_TYPE_NDI: NAN datapath interface
+ * @eCSR_BSS_TYPE_ANY: any BSS type (IBSS or Infrastructure)
+ */
+typedef enum {
+	eCSR_BSS_TYPE_INFRASTRUCTURE,
+	eCSR_BSS_TYPE_INFRA_AP,
+	eCSR_BSS_TYPE_IBSS,
+	eCSR_BSS_TYPE_START_IBSS,
+	eCSR_BSS_TYPE_NDI,
+	eCSR_BSS_TYPE_ANY,
+} eCsrRoamBssType;
+
+typedef enum {
+	eCSR_SCAN_SUCCESS,
+	eCSR_SCAN_FAILURE,
+	eCSR_SCAN_ABORT,
+	eCSR_SCAN_FOUND_PEER,
+} eCsrScanStatus;
+
+typedef enum {
+	eCSR_BW_20MHz_VAL = 20,
+	eCSR_BW_40MHz_VAL = 40,
+	eCSR_BW_80MHz_VAL = 80,
+	eCSR_BW_160MHz_VAL = 160
+} eCSR_BW_Val;
+
+typedef enum {
+	eCSR_INI_SINGLE_CHANNEL_CENTERED = 0,
+	eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY,
+	eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY,
+	eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED,
+	eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED,
+	eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED,
+	eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW,
+	eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW,
+	eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH,
+	eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH,
+	eCSR_INI_CHANNEL_BONDING_STATE_MAX
+} eIniChanBondState;
+
+#define CSR_RSN_PMKID_SIZE          16
+#define CSR_RSN_MAX_PMK_LEN         48
+#define CSR_MAX_PMKID_ALLOWED       32
+#define CSR_WEP40_KEY_LEN           5
+#define CSR_WEP104_KEY_LEN          13
+#define CSR_TKIP_KEY_LEN            32
+#define CSR_AES_KEY_LEN             16
+#define CSR_AES_GCMP_KEY_LEN        16
+#define CSR_AES_GCMP_256_KEY_LEN    32
+#define CSR_AES_GMAC_128_KEY_LEN    16
+#define CSR_AES_GMAC_256_KEY_LEN    32
+#define CSR_MAX_TX_POWER        (WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX)
+#define CSR_MAX_RSC_LEN             16
+#ifdef FEATURE_WLAN_WAPI
+#define CSR_WAPI_BKID_SIZE          16
+#define CSR_MAX_BKID_ALLOWED        16
+#define CSR_WAPI_KEY_LEN            32
+#define CSR_MAX_KEY_LEN         (CSR_WAPI_KEY_LEN) /* longest one is for WAPI */
+#else
+#define CSR_MAX_KEY_LEN         (CSR_TKIP_KEY_LEN) /* longest one is for TKIP */
+#endif /* FEATURE_WLAN_WAPI */
+#ifdef FEATURE_WLAN_ESE
+#define CSR_KRK_KEY_LEN             16
+#endif
+
+typedef struct tagCsrChannelInfo {
+	uint8_t numOfChannels;
+	uint8_t *ChannelList;   /* it will be an array of channels */
+} tCsrChannelInfo, *tpCsrChannelInfo;
+
+typedef enum {
+	eHIDDEN_SSID_NOT_IN_USE,
+	eHIDDEN_SSID_ZERO_LEN,
+	eHIDDEN_SSID_ZERO_CONTENTS
+} tHiddenssId;
+
+typedef struct tagCsrSSIDInfo {
+	tSirMacSSid SSID;
+	bool handoffPermitted;
+	tHiddenssId ssidHidden;
+} tCsrSSIDInfo;
+
+typedef struct tagCsrSSIDs {
+	uint32_t numOfSSIDs;
+	tCsrSSIDInfo *SSIDList; /* To be allocated for array of SSIDs */
+} tCsrSSIDs;
+
+typedef struct tagCsrBSSIDs {
+	uint32_t numOfBSSIDs;
+	struct qdf_mac_addr *bssid;
+} tCsrBSSIDs;
+
+typedef struct tagCsrStaParams {
+	uint16_t capability;
+	uint8_t extn_capability[SIR_MAC_MAX_EXTN_CAP];
+	uint8_t supported_rates_len;
+	uint8_t supported_rates[SIR_MAC_MAX_SUPP_RATES];
+	uint8_t htcap_present;
+	tSirHTCap HTCap;
+	uint8_t vhtcap_present;
+	tSirVHTCap VHTCap;
+	uint8_t uapsd_queues;
+	uint8_t max_sp;
+	uint8_t supported_channels_len;
+	uint8_t supported_channels[SIR_MAC_MAX_SUPP_CHANNELS];
+	uint8_t supported_oper_classes_len;
+	uint8_t supported_oper_classes[REG_MAX_SUPP_OPER_CLASSES];
+} tCsrStaParams;
+
+typedef struct tagCsrScanResultInfo {
+	/*
+	 * Carry the IEs for the current BSSDescription.
+	 * A pointer to tDot11fBeaconIEs. Maybe NULL for start BSS.
+	 */
+	void *pvIes;
+	tAniSSID ssId;
+	unsigned long timer;           /* timer is variable for hidden SSID timer */
+	/*
+	 * This member must be the last in the structure because the
+	 * end of tSirBssDescription is an
+	 * array with nonknown size at this time */
+	tSirBssDescription BssDescriptor;
+} tCsrScanResultInfo;
+
+typedef struct tagCsrEncryptionList {
+
+	uint32_t numEntries;
+	eCsrEncryptionType encryptionType[eCSR_NUM_OF_ENCRYPT_TYPE];
+
+} tCsrEncryptionList, *tpCsrEncryptionList;
+
+typedef struct tagCsrAuthList {
+	uint32_t numEntries;
+	eCsrAuthType authType[eCSR_NUM_OF_SUPPORT_AUTH_TYPE];
+} tCsrAuthList, *tpCsrAuthList;
+
+typedef struct tagCsrMobilityDomainInfo {
+	uint8_t mdiePresent;
+	uint16_t mobilityDomain;
+} tCsrMobilityDomainInfo;
+
+#ifdef FEATURE_WLAN_ESE
+typedef struct tagCsrEseCckmInfo {
+	uint32_t reassoc_req_num;
+	bool krk_plumbed;
+	uint8_t krk[SIR_KRK_KEY_LEN];
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	uint8_t btk[SIR_BTK_KEY_LEN];
+#endif
+} tCsrEseCckmInfo;
+
+typedef struct tagCsrEseCckmIe {
+	uint8_t cckmIe[DOT11F_IE_RSN_MAX_LEN];
+	uint8_t cckmIeLen;
+} tCsrEseCckmIe;
+#endif /* FEATURE_WLAN_ESE */
+
+typedef struct sCsrChannel_ {
+	uint8_t numChannels;
+	uint8_t channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+} sCsrChannel;
+
+typedef struct tagCsrScanResultFilter {
+	tCsrBSSIDs BSSIDs;
+	tCsrSSIDs SSIDs;
+	tCsrChannelInfo ChannelInfo;
+	tCsrAuthList authType;
+	tCsrEncryptionList EncryptionType;
+	/*
+	 * eCSR_ENCRYPT_TYPE_ANY cannot be set in multicast encryption type.
+	 * If caller doesn't case, put all supported encryption types in here
+	 */
+	tCsrEncryptionList mcEncryptionType;
+	eCsrRoamBssType BSSType;
+	/* its a bit mask of all the needed phy mode defined in eCsrPhyMode */
+	eCsrPhyMode phyMode;
+	/*
+	 * If countryCode[0] is not 0, countryCode is checked
+	 * independent of fCheckUnknownCountryCode
+	 */
+	uint8_t countryCode[WNI_CFG_COUNTRY_CODE_LEN];
+	uint8_t uapsd_mask;
+	/* For WPS filtering if true => auth and ecryption should be ignored */
+	bool bWPSAssociation;
+	bool bOSENAssociation;
+	/*
+	 * For measurement reports --> if set, only SSID,
+	 * BSSID and channel is considered for filtering.
+	 */
+	bool fMeasurement;
+	tCsrMobilityDomainInfo MDID;
+	bool p2pResult;
+#ifdef WLAN_FEATURE_11W
+	/* Management Frame Protection */
+	bool MFPEnabled;
+	uint8_t MFPRequired;
+	uint8_t MFPCapable;
+#endif
+	/* The following flag is used to distinguish the
+	 * roaming case while building the scan filter and
+	 * applying it on to the scan results. This is mainly
+	 * used to support whitelist ssid feature.
+	 */
+	uint8_t scan_filter_for_roam;
+	struct sCsrChannel_ pcl_channels;
+	struct qdf_mac_addr bssid_hint;
+	enum QDF_OPMODE csrPersona;
+	bool realm_check;
+	uint8_t fils_realm[2];
+	bool force_rsne_override;
+} tCsrScanResultFilter;
+
+typedef struct sCsrChnPower_ {
+	uint8_t firstChannel;
+	uint8_t numChannels;
+	uint8_t maxtxPower;
+} sCsrChnPower;
+
+typedef struct tagCsr11dinfo {
+	sCsrChannel Channels;
+	uint8_t countryCode[WNI_CFG_COUNTRY_CODE_LEN + 1];
+	/* max power channel list */
+	sCsrChnPower ChnPower[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+} tCsr11dinfo;
+
+typedef enum {
+	eCSR_ROAM_CANCELLED = 1,
+	/* it means error happens before assoc_start/roaming_start is called. */
+	eCSR_ROAM_FAILED,
+	/*
+	 * a CSR trigger roaming operation starts,
+	 * callback may get a pointer to tCsrConnectedProfile
+	 */
+	eCSR_ROAM_ROAMING_START,
+	/* a CSR trigger roaming operation is completed */
+	eCSR_ROAM_ROAMING_COMPLETION,
+	/* Connection completed status. */
+	eCSR_ROAM_CONNECT_COMPLETION,
+	/*
+	 * an association or start_IBSS operation starts,
+	 * callback may get a pointer to struct csr_roam_profile and
+	 * a pointer to tSirBssDescription
+	 */
+	eCSR_ROAM_ASSOCIATION_START,
+	/*
+	 * a roaming operation is finish, see eCsrRoamResult for
+	 * possible data passed back
+	 */
+	eCSR_ROAM_ASSOCIATION_COMPLETION,
+	eCSR_ROAM_DISASSOCIATED,
+	eCSR_ROAM_ASSOCIATION_FAILURE,
+	/* when callback with this flag. it gets a pointer to the BSS desc. */
+	eCSR_ROAM_SHOULD_ROAM,
+	/* A new candidate for PMKID is found */
+	eCSR_ROAM_SCAN_FOUND_NEW_BSS,
+	/* CSR is done lostlink roaming and still cannot reconnect */
+	eCSR_ROAM_LOSTLINK,
+	/* a link lost is detected. CSR starts roaming. */
+	eCSR_ROAM_LOSTLINK_DETECTED,
+	/*
+	 * TKIP MIC error detected, callback gets a pointer
+	 * to tpSirSmeMicFailureInd
+	 */
+	eCSR_ROAM_MIC_ERROR_IND,
+	/* IBSS indications. */
+	eCSR_ROAM_IBSS_IND,
+	/*
+	 * Update the connection status, useful for IBSS: new peer added,
+	 * network is active etc.
+	 */
+	eCSR_ROAM_CONNECT_STATUS_UPDATE,
+	eCSR_ROAM_GEN_INFO,
+	eCSR_ROAM_SET_KEY_COMPLETE,
+	eCSR_ROAM_IBSS_LEAVE,   /* IBSS indications. */
+	/* BSS in SoftAP mode status indication */
+	eCSR_ROAM_INFRA_IND,
+	eCSR_ROAM_WPS_PBC_PROBE_REQ_IND,
+	eCSR_ROAM_FT_RESPONSE,
+	eCSR_ROAM_FT_START,
+	/* this mean error happens before assoc_start/roam_start is called. */
+	eCSR_ROAM_SESSION_OPENED,
+	eCSR_ROAM_FT_REASSOC_FAILED,
+	eCSR_ROAM_PMK_NOTIFY,
+	/*
+	 * Following 4 enums are used by FEATURE_WLAN_LFR_METRICS
+	 * but they are needed for compilation even when
+	 * FEATURE_WLAN_LFR_METRICS is not defined.
+	 */
+	eCSR_ROAM_PREAUTH_INIT_NOTIFY,
+	eCSR_ROAM_PREAUTH_STATUS_SUCCESS,
+	eCSR_ROAM_PREAUTH_STATUS_FAILURE,
+	eCSR_ROAM_HANDOVER_SUCCESS,
+	/*
+	 * TDLS callback events
+	 */
+	eCSR_ROAM_TDLS_STATUS_UPDATE,
+	eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND,
+
+	/* Disaconnect all the clients */
+	eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS,
+	/* Stopbss triggered from SME due to different */
+	eCSR_ROAM_SEND_P2P_STOP_BSS,
+	/* beacon interval */
+#ifdef WLAN_FEATURE_11W
+	eCSR_ROAM_UNPROT_MGMT_FRAME_IND,
+#endif
+
+	eCSR_ROAM_IBSS_PEER_INFO_COMPLETE,
+
+#ifdef FEATURE_WLAN_ESE
+	eCSR_ROAM_TSM_IE_IND,
+	eCSR_ROAM_CCKM_PREAUTH_NOTIFY,
+	eCSR_ROAM_ESE_ADJ_AP_REPORT_IND,
+	eCSR_ROAM_ESE_BCN_REPORT_IND,
+#endif /* FEATURE_WLAN_ESE */
+
+	/* Radar indication from lower layers */
+	eCSR_ROAM_DFS_RADAR_IND,
+	eCSR_ROAM_SET_CHANNEL_RSP,
+
+	/* Channel sw update notification */
+	eCSR_ROAM_DFS_CHAN_SW_NOTIFY,
+	eCSR_ROAM_EXT_CHG_CHNL_IND,
+	eCSR_ROAM_STA_CHANNEL_SWITCH,
+	eCSR_ROAM_NDP_STATUS_UPDATE,
+	eCSR_ROAM_UPDATE_SCAN_RESULT,
+	eCSR_ROAM_START,
+	eCSR_ROAM_ABORT,
+	eCSR_ROAM_NAPI_OFF,
+	eCSR_ROAM_CHANNEL_COMPLETE_IND,
+	eCSR_ROAM_CAC_COMPLETE_IND,
+	eCSR_ROAM_SAE_COMPUTE,
+} eRoamCmdStatus;
+
+/* 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,
+	 * struct csr_roam_info's pBssDesc may pass back
+	 */
+	eCSR_ROAM_RESULT_FAILURE,
+	/* Pass back pointer to struct csr_roam_info */
+	eCSR_ROAM_RESULT_ASSOCIATED,
+	eCSR_ROAM_RESULT_NOT_ASSOCIATED,
+	eCSR_ROAM_RESULT_MIC_FAILURE,
+	eCSR_ROAM_RESULT_FORCED,
+	eCSR_ROAM_RESULT_DISASSOC_IND,
+	eCSR_ROAM_RESULT_DEAUTH_IND,
+	eCSR_ROAM_RESULT_CAP_CHANGED,
+	/*
+	 * This means we starts an IBSS struct csr_roam_info's
+	 * pBssDesc may pass back
+	 */
+	eCSR_ROAM_RESULT_IBSS_STARTED,
+	eCSR_ROAM_RESULT_IBSS_START_FAILED,
+	eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS,
+	eCSR_ROAM_RESULT_IBSS_JOIN_FAILED,
+	eCSR_ROAM_RESULT_IBSS_CONNECT,
+	eCSR_ROAM_RESULT_IBSS_INACTIVE,
+	/*
+	 * If roamStatus is eCSR_ROAM_ASSOCIATION_COMPLETION struct
+	 * csr_roam_info's pBssDesc may pass back and the peer's MAC
+	 * address in peerMacOrBssid. If roamStatus is
+	 * eCSR_ROAM_IBSS_IND, the peer's MAC address in
+	 * peerMacOrBssid and a beacon frame of the IBSS in pbFrames
+	 */
+	eCSR_ROAM_RESULT_IBSS_NEW_PEER,
+	/*
+	 * Peer departed from IBSS, Callback may get a pointer tSmeIbssPeerInd
+	 * in pIbssPeerInd
+	 */
+	eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED,
+	/*
+	 * Coalescing in the IBSS network (joined an IBSS network)
+	 * Callback pass a BSSID in peerMacOrBssid
+	 */
+	eCSR_ROAM_RESULT_IBSS_COALESCED,
+	/*
+	 * If roamStatus is eCSR_ROAM_ROAMING_START, callback may get a pointer
+	 * to tCsrConnectedProfile used to connect.
+	 */
+	eCSR_ROAM_RESULT_IBSS_STOP,
+	eCSR_ROAM_RESULT_LOSTLINK,
+	eCSR_ROAM_RESULT_MIC_ERROR_UNICAST,
+	eCSR_ROAM_RESULT_MIC_ERROR_GROUP,
+	eCSR_ROAM_RESULT_AUTHENTICATED,
+	eCSR_ROAM_RESULT_NEW_RSN_BSS,
+#ifdef FEATURE_WLAN_WAPI
+	eCSR_ROAM_RESULT_NEW_WAPI_BSS,
+#endif /* FEATURE_WLAN_WAPI */
+	/* INFRA started successfully */
+	eCSR_ROAM_RESULT_INFRA_STARTED,
+	/* INFRA start failed */
+	eCSR_ROAM_RESULT_INFRA_START_FAILED,
+	/* INFRA stopped */
+	eCSR_ROAM_RESULT_INFRA_STOPPED,
+	/* A station joining INFRA AP */
+	eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND,
+	/* A station joined INFRA AP */
+	eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF,
+	/* INFRA disassociated */
+	eCSR_ROAM_RESULT_INFRA_DISASSOCIATED,
+	eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND,
+	eCSR_ROAM_RESULT_SEND_ACTION_FAIL,
+	/* peer rejected assoc because max assoc limit reached */
+	eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED,
+	/* Assoc rejected due to concurrent session running on a diff channel */
+	eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL,
+	/* TDLS events */
+	eCSR_ROAM_RESULT_ADD_TDLS_PEER,
+	eCSR_ROAM_RESULT_UPDATE_TDLS_PEER,
+	eCSR_ROAM_RESULT_DELETE_TDLS_PEER,
+	eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND,
+	eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND,
+	eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP,
+	eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER,
+	eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN,
+	eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED,
+	eCSR_ROAM_RESULT_TDLS_CONNECTION_TRACKER_NOTIFICATION,
+
+	eCSR_ROAM_RESULT_IBSS_PEER_INFO_SUCCESS,
+	eCSR_ROAM_RESULT_IBSS_PEER_INFO_FAILED,
+	eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND,
+	eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS,
+	eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE,
+	eCSR_ROAM_RESULT_CSA_RESTART_RSP,
+	eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS,
+	eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND,
+
+	eCSR_ROAM_RESULT_NDI_CREATE_RSP,
+	eCSR_ROAM_RESULT_NDI_DELETE_RSP,
+	eCSR_ROAM_RESULT_NDP_INITIATOR_RSP,
+	eCSR_ROAM_RESULT_NDP_NEW_PEER_IND,
+	eCSR_ROAM_RESULT_NDP_CONFIRM_IND,
+	eCSR_ROAM_RESULT_NDP_INDICATION,
+	eCSR_ROAM_RESULT_NDP_SCHED_UPDATE_RSP,
+	eCSR_ROAM_RESULT_NDP_RESPONDER_RSP,
+	eCSR_ROAM_RESULT_NDP_END_RSP,
+	eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND,
+	eCSR_ROAM_RESULT_NDP_END_IND,
+	eCSR_ROAM_RESULT_CAC_END_IND,
+	/* If Scan for SSID failed to found proper BSS */
+	eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE,
+	eCSR_ROAM_RESULT_INVOKE_FAILED,
+} eCsrRoamResult;
+
+typedef enum {
+	eCSR_DISCONNECT_REASON_UNSPECIFIED = 0,
+	eCSR_DISCONNECT_REASON_MIC_ERROR,
+	eCSR_DISCONNECT_REASON_DISASSOC,
+	eCSR_DISCONNECT_REASON_DEAUTH,
+	eCSR_DISCONNECT_REASON_HANDOFF,
+	eCSR_DISCONNECT_REASON_IBSS_LEAVE,
+	eCSR_DISCONNECT_REASON_STA_HAS_LEFT,
+	eCSR_DISCONNECT_REASON_NDI_DELETE,
+	eCSR_DISCONNECT_REASON_ROAM_HO_FAIL,
+} eCsrRoamDisconnectReason;
+
+typedef enum {
+	/* Not associated in Infra or participating in an IBSS/Ad-hoc */
+	eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED,
+	/* Associated in an Infrastructure network. */
+	eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED,
+	/* Participating in IBSS network though disconnection */
+	eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED,
+	/* Participating in IBSS network with partner stations also present */
+	eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED,
+	/* Participating in WDS network in AP/STA mode but not connected yet */
+	eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED,
+	/* Participating in a WDS network and connected peer to peer */
+	eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED,
+	/* Participating in a Infra network in AP not yet in connected state */
+	eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED,
+	/* Participating in a Infra network and connected to a peer */
+	eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED,
+	/* Disconnecting with AP or stop connecting process */
+	eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING,
+	/* NAN Data interface not started */
+	eCSR_CONNECT_STATE_TYPE_NDI_NOT_STARTED,
+	/* NAN Data interface started */
+	eCSR_CONNECT_STATE_TYPE_NDI_STARTED,
+
+} eCsrConnectState;
+
+/*
+ * This parameter is no longer supported in the Profile.
+ * Need to set this in the global properties for the adapter.
+ */
+typedef enum eCSR_MEDIUM_ACCESS {
+	eCSR_MEDIUM_ACCESS_AUTO = 0,
+	eCSR_MEDIUM_ACCESS_DCF,
+	eCSR_MEDIUM_ACCESS_eDCF,
+	eCSR_MEDIUM_ACCESS_HCF,
+
+	eCSR_MEDIUM_ACCESS_WMM_eDCF_802dot1p,
+	eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP,
+	eCSR_MEDIUM_ACCESS_WMM_eDCF_NoClassify,
+	eCSR_MEDIUM_ACCESS_11e_eDCF = eCSR_MEDIUM_ACCESS_eDCF,
+	eCSR_MEDIUM_ACCESS_11e_HCF = eCSR_MEDIUM_ACCESS_HCF,
+} eCsrMediaAccessType;
+
+typedef enum {
+	eCSR_OPERATING_CHANNEL_ALL = 0,
+	eCSR_OPERATING_CHANNEL_AUTO = eCSR_OPERATING_CHANNEL_ALL,
+	eCSR_OPERATING_CHANNEL_ANY = eCSR_OPERATING_CHANNEL_ALL,
+} eOperationChannel;
+
+typedef enum {
+	eCSR_DOT11_FRAG_THRESH_AUTO = -1,
+	eCSR_DOT11_FRAG_THRESH_MIN = 256,
+	eCSR_DOT11_FRAG_THRESH_MAX = 2346,
+	eCSR_DOT11_FRAG_THRESH_DEFAULT = 2000
+} eCsrDot11FragThresh;
+
+/*
+ * For channel bonding, the channel number gap is 4, either up or down.
+ * For both 11a and 11g mode.
+ */
+#define CSR_CB_CHANNEL_GAP 4
+#define CSR_CB_CENTER_CHANNEL_OFFSET    2
+#define CSR_SEC_CHANNEL_OFFSET    4
+
+
+/* WEP keysize (in bits) */
+typedef enum {
+	/* 40 bit key + 24bit IV = 64bit WEP */
+	eCSR_SECURITY_WEP_KEYSIZE_40 = 40,
+	/* 104bit key + 24bit IV = 128bit WEP */
+	eCSR_SECURITY_WEP_KEYSIZE_104 = 104,
+	eCSR_SECURITY_WEP_KEYSIZE_MIN = eCSR_SECURITY_WEP_KEYSIZE_40,
+	eCSR_SECURITY_WEP_KEYSIZE_MAX = eCSR_SECURITY_WEP_KEYSIZE_104,
+	eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES =
+		(eCSR_SECURITY_WEP_KEYSIZE_MAX / 8),
+} eCsrWEPKeySize;
+
+/* Possible values for the WEP static key ID */
+typedef enum {
+
+	eCSR_SECURITY_WEP_STATIC_KEY_ID_MIN = 0,
+	eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX = 3,
+	eCSR_SECURITY_WEP_STATIC_KEY_ID_DEFAULT = 0,
+
+	eCSR_SECURITY_WEP_STATIC_KEY_ID_INVALID = -1,
+
+} eCsrWEPStaticKeyID;
+
+/* Two extra key indicies are used for the IGTK (which is used by BIP) */
+#define CSR_MAX_NUM_KEY     (eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX + 2 + 1)
+
+typedef enum {
+	eCSR_SECURITY_SET_KEY_ACTION_NO_CHANGE,
+	eCSR_SECURITY_SET_KEY_ACTION_SET_KEY,
+	eCSR_SECURITY_SET_KEY_ACTION_DELETE_KEY,
+} eCsrSetKeyAction;
+
+typedef enum {
+	/*
+	 * Roaming because HDD requested for reassoc by changing one of the
+	 * fields in tCsrRoamModifyProfileFields. OR Roaming because SME
+	 * requested for reassoc by changing one of the fields in
+	 * tCsrRoamModifyProfileFields.
+	 */
+	eCsrRoamReasonStaCapabilityChanged,
+	/*
+	 * Roaming because SME requested for reassoc to a different AP,
+	 * as part of inter AP handoff.
+	 */
+	eCsrRoamReasonBetterAP,
+	/*
+	 * Roaming because SME requested it as the link is lost - placeholder,
+	 * will clean it up once handoff code gets in
+	 */
+	eCsrRoamReasonSmeIssuedForLostLink,
+
+} eCsrRoamReasonCodes;
+
+typedef enum {
+	eCsrRoamWmmAuto = 0,
+	eCsrRoamWmmQbssOnly = 1,
+	eCsrRoamWmmNoQos = 2,
+
+} eCsrRoamWmmUserModeType;
+
+typedef enum {
+	eCSR_REQUESTER_MIN = 0,
+	eCSR_DIAG,
+	eCSR_UMA_GAN,
+	eCSR_HDD
+} eCsrStatsRequesterType;
+
+/**
+ * enum csr_hi_rssi_scan_id - Parameter ids for hi rssi scan feature
+ *
+ * @eCSR_HI_RSSI_SCAN_MAXCOUNT_ID: how many times scan can be performed
+ * @eCSR_HI_RSSI_SCAN_RSSI_DELTA_ID: rssi difference to trigger scan
+ * @eCSR_HI_RSSI_SCAN_DELAY_ID: delay in millseconds between scans
+ * @eCSR_HI_RSSI_SCAN_RSSI_UB_ID: rssi upper bound for scan trigger
+ */
+enum csr_hi_rssi_scan_id {
+	eCSR_HI_RSSI_SCAN_MAXCOUNT_ID,
+	eCSR_HI_RSSI_SCAN_RSSI_DELTA_ID,
+	eCSR_HI_RSSI_SCAN_DELAY_ID,
+	eCSR_HI_RSSI_SCAN_RSSI_UB_ID
+};
+
+typedef struct tagPmkidCandidateInfo {
+	struct qdf_mac_addr BSSID;
+	bool preAuthSupported;
+} tPmkidCandidateInfo;
+
+typedef struct tagPmkidCacheInfo {
+	struct qdf_mac_addr BSSID;
+	uint8_t PMKID[CSR_RSN_PMKID_SIZE];
+	uint8_t pmk[CSR_RSN_MAX_PMK_LEN];
+	uint8_t pmk_len;
+	uint8_t ssid_len;
+	uint8_t ssid[SIR_MAC_MAX_SSID_LENGTH];
+	uint8_t cache_id[CACHE_ID_LEN];
+} tPmkidCacheInfo;
+
+#ifdef FEATURE_WLAN_WAPI
+typedef struct tagBkidCandidateInfo {
+	struct qdf_mac_addr BSSID;
+	bool preAuthSupported;
+} tBkidCandidateInfo;
+
+typedef struct tagBkidCacheInfo {
+	struct qdf_mac_addr BSSID;
+	uint8_t BKID[CSR_WAPI_BKID_SIZE];
+} tBkidCacheInfo;
+#endif /* FEATURE_WLAN_WAPI */
+
+typedef struct tagCsrKeys {
+	/* Also use to indicate whether the key index is set */
+	uint8_t KeyLength[CSR_MAX_NUM_KEY];
+	uint8_t KeyMaterial[CSR_MAX_NUM_KEY][CSR_MAX_KEY_LEN];
+	uint8_t defaultIndex;
+} tCsrKeys;
+
+/*
+ * Following fields which're part of tCsrRoamConnectedProfile might need
+ * modification dynamically once STA is up & running & this'd trigger reassoc
+ */
+typedef struct tagCsrRoamModifyProfileFields {
+	/*
+	 * during connect this specifies ACs U-APSD is to be setup
+	 * for (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored).
+	 * During assoc response this COULD carry confirmation of what
+	 * ACs U-APSD got setup for. Later if an APP looking for APSD,
+	 * SME-QoS might need to modify this field
+	 */
+	uint8_t uapsd_mask;
+	/* HDD might ask to modify this field */
+	uint16_t listen_interval;
+} tCsrRoamModifyProfileFields;
+
+struct csr_roam_profile {
+	tCsrSSIDs SSIDs;
+	tCsrBSSIDs BSSIDs;
+	/* this is bit mask of all the needed phy mode defined in eCsrPhyMode */
+	uint32_t phyMode;
+	eCsrRoamBssType BSSType;
+	tCsrAuthList AuthType;
+	eCsrAuthType negotiatedAuthType;
+	tCsrEncryptionList EncryptionType;
+	/* This field is for output only, not for input */
+	eCsrEncryptionType negotiatedUCEncryptionType;
+	/*
+	 * eCSR_ENCRYPT_TYPE_ANY cannot be set in multicast encryption type.
+	 * If caller doesn't case, put all supported encryption types in here
+	 */
+	tCsrEncryptionList mcEncryptionType;
+	/* This field is for output only, not for input */
+	eCsrEncryptionType negotiatedMCEncryptionType;
+#ifdef WLAN_FEATURE_11W
+	/* Management Frame Protection */
+	bool MFPEnabled;
+	uint8_t MFPRequired;
+	uint8_t MFPCapable;
+#endif
+	tAniEdType mgmt_encryption_type;
+	tCsrKeys Keys;
+	tCsrChannelInfo ChannelInfo;
+	uint8_t operationChannel;
+	struct ch_params ch_params;
+	/* If this is 0, SME will fill in for caller. */
+	uint16_t beaconInterval;
+	/*
+	 * during connect this specifies ACs U-APSD is to be setup
+	 * for (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored).
+	 * During assoc resp this'd carry cnf of what ACs U-APSD got setup for
+	 */
+	uint8_t uapsd_mask;
+	uint32_t nWPAReqIELength; /* The byte count in the pWPAReqIE */
+	uint8_t *pWPAReqIE;       /* If not null,it's IE byte stream for WPA */
+	uint32_t nRSNReqIELength; /* The byte count in the pRSNReqIE */
+	uint8_t *pRSNReqIE;       /* If not null,it's IE byte stream for RSN */
+#ifdef FEATURE_WLAN_WAPI
+	uint32_t nWAPIReqIELength;/* The byte count in the pWAPIReqIE */
+	uint8_t *pWAPIReqIE;      /* If not null,it's IE byte stream for WAPI */
+#endif /* FEATURE_WLAN_WAPI */
+
+	uint32_t nAddIEScanLength;/* pAddIE for scan (at the time of join) */
+	/*
+	 * If not null,it's the IE byte stream for additional IE,
+	 * which can be WSC IE and/or P2P IE
+	 */
+	uint8_t *pAddIEScan;
+	uint32_t nAddIEAssocLength; /* The byte count in the pAddIE for assoc */
+	/*
+	 * If not null, it has the IE byte stream for additional IE,
+	 * which can be WSC IE and/or P2P IE
+	 */
+	uint8_t *pAddIEAssoc;
+	/* it is ignored if [0] is 0. */
+	uint8_t countryCode[WNI_CFG_COUNTRY_CODE_LEN];
+	/* WPS Association if true => auth and ecryption should be ignored */
+	bool bWPSAssociation;
+	bool bOSENAssociation;
+	uint32_t nWSCReqIELength; /* The byte count in the pWSCReqIE */
+	uint8_t *pWSCReqIE;       /* If not null,it's IE byte stream for WSC */
+	uint8_t ieee80211d;
+	uint8_t privacy;
+	bool fwdWPSPBCProbeReq;
+	tAniAuthType csr80211AuthType;
+	uint32_t dtimPeriod;
+	bool ApUapsdEnable;
+	bool protEnabled;
+	bool obssProtEnabled;
+	bool chan_switch_hostapd_rate_enabled;
+	uint16_t cfg_protection;
+	uint8_t wps_state;
+	tCsrMobilityDomainInfo MDID;
+	enum QDF_OPMODE csrPersona;
+	uint8_t disableDFSChSwitch;
+	/* addIe params */
+	tSirAddIeParams addIeParams;
+	uint16_t beacon_tx_rate;
+	tSirMacRateSet  supported_rates;
+	tSirMacRateSet  extended_rates;
+	struct qdf_mac_addr bssid_hint;
+	bool force_24ghz_in_ht20;
+	uint32_t cac_duration_ms;
+	uint32_t dfs_regdomain;
+	bool supplicant_disabled_roaming;
+	bool driver_disabled_roaming;
+#ifdef WLAN_FEATURE_FILS_SK
+	bool fils_connection;
+	uint8_t *hlp_ie;
+	uint32_t hlp_ie_len;
+	struct cds_fils_connection_info *fils_con_info;
+#endif
+	bool force_rsne_override;
+};
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+typedef struct tagCsrRoamHTProfile {
+	uint8_t phymode;
+	uint8_t htCapability;
+	uint8_t htSupportedChannelWidthSet;
+	uint8_t htRecommendedTxWidthSet;
+	ePhyChanBondState htSecondaryChannelOffset;
+	uint8_t vhtCapability;
+	uint8_t apCenterChan;
+	uint8_t apChanWidth;
+} tCsrRoamHTProfile;
+#endif
+typedef struct tagCsrRoamConnectedProfile {
+	tSirMacSSid SSID;
+	bool handoffPermitted;
+	bool ssidHidden;
+	uint8_t operationChannel;
+	struct qdf_mac_addr bssid;
+	uint16_t beaconInterval;
+	eCsrRoamBssType BSSType;
+	eCsrAuthType AuthType;
+	tCsrAuthList AuthInfo;
+	eCsrEncryptionType EncryptionType;
+	tCsrEncryptionList EncryptionInfo;
+	eCsrEncryptionType mcEncryptionType;
+	tCsrEncryptionList mcEncryptionInfo;
+	uint32_t vht_channel_width;
+	tCsrKeys Keys;
+	/*
+	 * meaningless on connect. It's an OUT param from CSR's point of view
+	 * During assoc response carries the ACM bit-mask i.e. what
+	 * ACs have ACM=1 (if any),(Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE
+	 * all other bits are ignored)
+	 */
+	uint8_t acm_mask;
+	tCsrRoamModifyProfileFields modifyProfileFields;
+	bool qosConnection;     /* A connection is QoS enabled */
+	uint32_t nAddIEAssocLength;
+	/*
+	 * If not null,it's IE byte stream for additional IE,
+	 * which can be WSC IE and/or P2P IE
+	 */
+	uint8_t *pAddIEAssoc;
+	tSirBssDescription *pBssDesc;
+	bool qap;               /* AP supports QoS */
+	tCsrMobilityDomainInfo MDID;
+#ifdef FEATURE_WLAN_ESE
+	tCsrEseCckmInfo eseCckmInfo;
+	bool isESEAssoc;
+#endif
+	uint32_t dot11Mode;
+	uint8_t proxyARPService;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	tCsrRoamHTProfile HTProfile;
+#endif
+#ifdef WLAN_FEATURE_11W
+	/* Management Frame Protection */
+	bool MFPEnabled;
+	uint8_t MFPRequired;
+	uint8_t MFPCapable;
+#endif
+} tCsrRoamConnectedProfile;
+
+typedef struct tagCsrNeighborRoamConfigParams {
+
+	uint32_t nNeighborScanTimerPeriod;
+	uint32_t neighbor_scan_min_timer_period;
+	uint8_t nNeighborLookupRssiThreshold;
+	int8_t rssi_thresh_offset_5g;
+	uint16_t nNeighborScanMinChanTime;
+	uint16_t nNeighborScanMaxChanTime;
+	sCsrChannel neighborScanChanList;
+	uint8_t nMaxNeighborRetries;
+	uint16_t nNeighborResultsRefreshPeriod;
+	uint16_t nEmptyScanRefreshPeriod;
+	uint8_t nOpportunisticThresholdDiff;
+	uint8_t nRoamRescanRssiDiff;
+	uint8_t nRoamBmissFirstBcnt;
+	uint8_t nRoamBmissFinalBcnt;
+	uint8_t nRoamBeaconRssiWeight;
+	uint8_t delay_before_vdev_stop;
+	uint32_t nhi_rssi_scan_max_count;
+	uint32_t nhi_rssi_scan_rssi_delta;
+	uint32_t nhi_rssi_scan_delay;
+	int32_t nhi_rssi_scan_rssi_ub;
+} tCsrNeighborRoamConfigParams;
+
+/**
+ * enum sta_roam_policy_dfs_mode - state of DFS mode for STA ROME policy
+ * @CSR_STA_ROAM_POLICY_NONE: DFS mode attribute is not valid
+ * @CSR_STA_ROAM_POLICY_DFS_ENABLED:  DFS mode is enabled
+ * @CSR_STA_ROAM_POLICY_DFS_DISABLED: DFS mode is disabled
+ * @CSR_STA_ROAM_POLICY_DFS_DEPRIORITIZE: Deprioritize DFS channels in scanning
+ */
+enum sta_roam_policy_dfs_mode {
+	CSR_STA_ROAM_POLICY_NONE,
+	CSR_STA_ROAM_POLICY_DFS_ENABLED,
+	CSR_STA_ROAM_POLICY_DFS_DISABLED,
+	CSR_STA_ROAM_POLICY_DFS_DEPRIORITIZE
+};
+
+/**
+ * struct csr_sta_roam_policy_params - sta roam policy params for station
+ * @dfs_mode: tell is DFS channels needs to be skipped while scanning
+ * @skip_unsafe_channels: tells if unsafe channels needs to be skip in scanning
+ * @sap_operating_band: Opearting band for SAP
+ */
+struct csr_sta_roam_policy_params {
+	enum sta_roam_policy_dfs_mode dfs_mode;
+	bool skip_unsafe_channels;
+	uint8_t sap_operating_band;
+};
+
+/**
+ * struct csr_neighbor_report_offload_params - neighbor report offload params
+ * @params_bitmask: bitmask to specify which of the below are enabled
+ * @time_offset: time offset after 11k offload command to trigger a neighbor
+ *		report request (in seconds)
+ * @low_rssi_offset: Offset from rssi threshold to trigger neighbor
+ *	report request (in dBm)
+ * @bmiss_count_trigger: Number of beacon miss events to trigger neighbor
+ *		report request
+ * @per_threshold_offset: offset from PER threshold to trigger neighbor
+ *		report request (in %)
+ * @neighbor_report_cache_timeout: timeout after which new trigger can enable
+ *		sending of a neighbor report request (in seconds)
+ * @max_neighbor_report_req_cap: max number of neighbor report requests that
+ *		can be sent to the peer in the current session
+ */
+struct csr_neighbor_report_offload_params {
+	uint8_t params_bitmask;
+	uint32_t time_offset;
+	uint32_t low_rssi_offset;
+	uint32_t bmiss_count_trigger;
+	uint32_t per_threshold_offset;
+	uint32_t neighbor_report_cache_timeout;
+	uint32_t max_neighbor_report_req_cap;
+};
+
+typedef struct tagCsrConfigParam {
+	/* keep this uint32_t. This gets converted to ePhyChannelBondState */
+	uint32_t channelBondingMode24GHz;
+	uint32_t channelBondingMode5GHz;
+	eCsrPhyMode phyMode;
+	uint32_t HeartbeatThresh50;
+	eCsrRoamWmmUserModeType WMMSupportMode;
+	bool Is11eSupportEnabled;
+	bool Is11dSupportEnabled;
+	bool Is11hSupportEnabled;
+	bool shortSlotTime;
+	bool ProprietaryRatesEnabled;
+	uint8_t AdHocChannel24;
+	uint8_t AdHocChannel5G;
+	/*
+	 * this number minus one is the number of times a scan doesn't find it
+	 * before it is removed
+	 */
+	uint32_t nScanResultAgeCount;
+	/* to set the RSSI difference for each category */
+	uint8_t bCatRssiOffset;
+	/* to set MCC Enable/Disable mode */
+	uint8_t fEnableMCCMode;
+	bool mcc_rts_cts_prot_enable;
+	bool mcc_bcast_prob_resp_enable;
+	/*
+	 * To allow MCC GO different B.I than STA's.
+	 * NOTE: make sure if RIVA firmware can handle this combination before
+	 * enabling this at the moment, this flag is provided only to pass
+	 * Wi-Fi Cert. 5.1.12
+	 */
+	uint8_t fAllowMCCGODiffBI;
+	tCsr11dinfo Csr11dinfo;
+
+	/* Country Code Priority */
+	bool fSupplicantCountryCodeHasPriority;
+	uint16_t vccRssiThreshold;
+	uint32_t vccUlMacLossThreshold;
+	uint32_t nPassiveMaxChnTime;        /* in units of milliseconds */
+	uint32_t nActiveMaxChnTime;         /* in units of milliseconds */
+	uint32_t nInitialDwellTime;         /* in units of milliseconds */
+	bool initial_scan_no_dfs_chnl;
+	uint32_t nPassiveMinChnTimeConc;    /* in units of milliseconds */
+	uint32_t nPassiveMaxChnTimeConc;    /* in units of milliseconds */
+	uint32_t nActiveMinChnTimeConc;     /* in units of milliseconds */
+	uint32_t nActiveMaxChnTimeConc;     /* in units of milliseconds */
+	uint32_t nRestTimeConc;             /* in units of milliseconds */
+	/*In units of milliseconds*/
+	uint32_t       min_rest_time_conc;
+	/*In units of milliseconds*/
+	uint32_t       idle_time_conc;
+
+	/*
+	 * in dBm, the maximum TX power The actual TX power is the lesser of
+	 * this value and 11d. If 11d is disable, the lesser of this and
+	 * default setting.
+	 */
+	uint8_t nTxPowerCap;
+	bool allow_tpc_from_ap;
+	/* stats request frequency from PE while in full power */
+	uint32_t statsReqPeriodicity;
+	/* stats request frequency from PE while in power save */
+	uint32_t statsReqPeriodicityInPS;
+#ifdef FEATURE_WLAN_ESE
+	uint8_t isEseIniFeatureEnabled;
+#endif
+	uint8_t isFastRoamIniFeatureEnabled;
+	struct mawc_params csr_mawc_config;
+	uint8_t isFastTransitionEnabled;
+	uint8_t RoamRssiDiff;
+	bool isWESModeEnabled;
+	tCsrNeighborRoamConfigParams neighborRoamConfig;
+	/*
+	 * Instead of Reassoc, send ADDTS/DELTS even when ACM is off for that AC
+	 * This is mandated by WMM-AC certification
+	 */
+	bool addTSWhenACMIsOff;
+	/*
+	 * Customer wants to start with an active scan based on the default
+	 * country code. This optimization will minimize the driver load to
+	 * association time. Based on this flag we will bypass the initial
+	 * passive scan needed for 11d to determine the country code & domain
+	 */
+	bool fEnableBypass11d;
+	/*
+	 * Customer wants to optimize the scan time. Avoiding scans(passive)
+	 * on DFS channels while swipping through both bands can save some time
+	 * (apprx 1.3 sec)
+	 */
+	uint8_t fEnableDFSChnlScan;
+	/*
+	 * To enable/disable scanning 2.4Ghz channels twice on a single scan
+	 * request from HDD
+	 */
+	bool fScanTwice;
+	bool enableVhtFor24GHz;
+	bool vendor_vht_sap;
+	bool send_smps_action;
+	/*
+	 * To enable/disable scanning only 2.4Ghz channels on first scan
+	 */
+	bool fFirstScanOnly2GChnl;
+	bool nRoamPrefer5GHz;
+	bool nRoamIntraBand;
+	uint8_t nProbes;
+	uint16_t nRoamScanHomeAwayTime;
+
+	bool isRoamOffloadScanEnabled;
+	bool bFastRoamInConIniFeatureEnabled;
+	uint8_t scanCfgAgingTime;
+	uint8_t enable_tx_ldpc;
+	uint8_t enable_rx_ldpc;
+	uint8_t disable_high_ht_mcs_2x2;
+	uint32_t ho_delay_for_rx;
+	uint32_t min_delay_btw_roam_scans;
+	uint32_t roam_trigger_reason_bitmask;
+	uint8_t isCoalesingInIBSSAllowed;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	uint8_t cc_switch_mode;
+#endif
+	uint8_t allowDFSChannelRoam;
+	bool obssEnabled;
+	uint8_t conc_custom_rule1;
+	uint8_t conc_custom_rule2;
+	uint8_t is_sta_connection_in_5gz_enabled;
+
+	uint8_t max_scan_count;
+	int8_t first_scan_bucket_threshold;
+	uint8_t max_intf_count;
+	uint32_t f_sta_miracast_mcc_rest_time_val;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	bool sap_channel_avoidance;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+	uint8_t f_prefer_non_dfs_on_radar;
+	bool is_ps_enabled;
+	uint32_t auto_bmps_timer_val;
+	uint32_t dual_mac_feature_disable;
+	uint32_t sta_sap_scc_on_dfs_chan;
+	uint32_t roam_dense_rssi_thresh_offset;
+	uint32_t roam_dense_min_aps;
+	int8_t roam_bg_scan_bad_rssi_thresh;
+	uint8_t roam_bad_rssi_thresh_offset_2g;
+	uint32_t roam_bg_scan_client_bitmap;
+	enum scan_dwelltime_adaptive_mode scan_adaptive_dwell_mode;
+	enum scan_dwelltime_adaptive_mode scan_adaptive_dwell_mode_nc;
+	struct csr_sta_roam_policy_params sta_roam_policy_params;
+	bool enable_bcast_probe_rsp;
+	bool is_fils_enabled;
+#ifdef WLAN_FEATURE_11AX
+	bool enable_ul_ofdma;
+	bool enable_ul_mimo;
+#endif
+	uint16_t wlm_latency_enable;
+	uint16_t wlm_latency_level;
+	uint32_t wlm_latency_flags[CSR_NUM_WLM_LATENCY_LEVEL];
+	bool is_force_1x1;
+	uint8_t oce_feature_bitmap;
+	uint32_t btm_offload_config;
+	uint32_t btm_solicited_timeout;
+	uint32_t btm_max_attempt_cnt;
+	uint32_t btm_sticky_time;
+	uint32_t offload_11k_enable_bitmask;
+	bool wep_tkip_in_he;
+	struct csr_neighbor_report_offload_params neighbor_report_offload;
+	bool enable_ftopen;
+	bool roam_force_rssi_trigger;
+} tCsrConfigParam;
+
+/* Tush */
+typedef struct tagCsrUpdateConfigParam {
+	tCsr11dinfo Csr11dinfo;
+} tCsrUpdateConfigParam;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+#define csr_roamIsRoamOffloadEnabled(pMac) \
+	(pMac->mlme_cfg->lfr.lfr3_roaming_offload)
+#define DEFAULT_REASSOC_FAILURE_TIMEOUT 1000
+#else
+#define csr_roamIsRoamOffloadEnabled(pMac)  false
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/* connected but not authenticated */
+#define CSR_ROAM_AUTH_STATUS_CONNECTED      0x1
+/* connected and authenticated */
+#define CSR_ROAM_AUTH_STATUS_AUTHENTICATED  0x2
+#endif
+
+struct csr_roam_info {
+	struct csr_roam_profile *pProfile;
+	tSirBssDescription *pBssDesc;
+	uint32_t nBeaconLength;
+	uint32_t nAssocReqLength;
+	uint32_t nAssocRspLength;
+	uint32_t nFrameLength;
+	uint8_t frameType;
+	/*
+	 * Point to a buffer contain the beacon, assoc req, assoc rsp frame,
+	 * in that order user needs to use nBeaconLength, nAssocReqLength,
+	 * nAssocRspLength to desice where each frame starts and ends.
+	 */
+	uint8_t *pbFrames;
+	bool fReassocReq;       /* set to true if for re-association */
+	bool fReassocRsp;       /* set to true if for re-association */
+	struct qdf_mac_addr bssid;
+	/*
+	 * Only valid in IBSS. this is the peers MAC address for
+	 * eCSR_ROAM_RESULT_IBSS_NEW_PEER or PEER_DEPARTED
+	 */
+	struct qdf_mac_addr peerMac;
+	tSirResultCodes statusCode;
+	/* this'd be our own defined or sent from otherBSS(per 802.11spec) */
+	uint32_t reasonCode;
+
+	uint8_t disassoc_reason;
+
+	uint8_t staId;         /* Peer stationId when connected */
+	/* false means auth needed from supplicant. true means authenticated */
+	bool fAuthRequired;
+	uint8_t sessionId;
+	uint8_t rsnIELen;
+	uint8_t *prsnIE;
+	uint8_t wapiIELen;
+	uint8_t *pwapiIE;
+	uint8_t addIELen;
+	uint8_t *paddIE;
+	union {
+		tSirMicFailureInfo *pMICFailureInfo;
+		tCsrRoamConnectedProfile *pConnectedProfile;
+		tSirWPSPBCProbeReq *pWPSPBCProbeReq;
+	} u;
+	bool wmmEnabledSta;  /* set to true if WMM enabled STA */
+	uint32_t dtimPeriod;
+#ifdef FEATURE_WLAN_ESE
+	bool isESEAssoc;
+	tSirTsmIE tsmIe;
+	uint32_t timestamp[2];
+	uint16_t tsmRoamDelay;
+	tSirEseBcnReportRsp *pEseBcnReportRsp;
+#endif
+	void *pRemainCtx;
+	uint32_t roc_scan_id;
+	uint32_t rxChan;
+#ifdef FEATURE_WLAN_TDLS
+	/*
+	 * TDLS parameters to check whether TDLS
+	 * and TDLS channel switch is allowed in the
+	 * AP network
+	 */
+	uint8_t staType;
+	bool tdls_prohibited;           /* per ExtCap in Assoc/Reassoc resp */
+	bool tdls_chan_swit_prohibited; /* per ExtCap in Assoc/Reassoc resp */
+#endif
+	/* Required for indicating the frames to upper layer */
+	uint32_t beaconLength;
+	uint8_t *beaconPtr;
+	uint32_t assocReqLength;
+	uint8_t *assocReqPtr;
+	int8_t rxRssi;
+	tSirSmeDfsEventInd dfs_event;
+	tSirChanChangeResponse *channelChangeRespEvent;
+	/* Timing and fine Timing measurement capability clubbed together */
+	uint8_t timingMeasCap;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	uint8_t roamSynchInProgress;
+	uint8_t synchAuthStatus;
+	uint8_t kck[SIR_KCK_KEY_LEN];
+	uint8_t kek[SIR_KEK_KEY_LEN_FILS];
+	uint8_t kek_len;
+	uint32_t pmk_len;
+	uint8_t pmk[SIR_PMK_LEN];
+	uint8_t pmkid[SIR_PMKID_LEN];
+	bool update_erp_next_seq_num;
+	uint16_t next_erp_seq_num;
+	uint8_t replay_ctr[SIR_REPLAY_CTR_LEN];
+	uint8_t subnet_change_status;
+#endif
+	tSirSmeChanInfo chan_info;
+	uint8_t target_channel;
+
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+	union {
+		struct ndi_create_rsp ndi_create_params;
+		struct ndi_delete_rsp ndi_delete_params;
+	} ndp;
+#endif
+	tDot11fIEHTCaps ht_caps;
+	tDot11fIEVHTCaps vht_caps;
+	tDot11fIEhs20vendor_ie hs20vendor_ie;
+	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;
+	/* Extended capabilities of STA */
+	uint8_t ecsa_capable;
+	bool is_fils_connection;
+#ifdef WLAN_FEATURE_FILS_SK
+	uint16_t fils_seq_num;
+	struct fils_join_rsp_params *fils_join_rsp;
+#endif
+	int rssi;
+	int tx_rate;
+	int rx_rate;
+#ifdef WLAN_FEATURE_SAE
+	struct sir_sae_info *sae_info;
+#endif
+};
+
+typedef struct tagCsrFreqScanInfo {
+	uint32_t nStartFreq;    /* in unit of MHz */
+	uint32_t nEndFreq;      /* in unit of MHz */
+	tSirScanType scanType;
+} tCsrFreqScanInfo;
+
+typedef struct sSirSmeAssocIndToUpperLayerCnf {
+	uint16_t messageType;   /* eWNI_SME_ASSOC_CNF */
+	uint16_t length;
+	uint8_t sessionId;
+	tSirResultCodes statusCode;
+	tSirMacAddr bssId;      /* Self BSSID */
+	tSirMacAddr peerMacAddr;
+	uint16_t aid;
+	tSirMacAddr alternateBssId;
+	uint8_t alternateChannelId;
+	uint8_t wmmEnabledSta;  /* set to true if WMM enabled STA */
+	tSirRSNie rsnIE;        /* RSN IE received from peer */
+	tSirWAPIie wapiIE;      /* WAPI IE received from peer */
+	tSirAddie addIE;        /* this can be WSC and/or P2P IE */
+	uint8_t reassocReq;     /* set to true if reassoc */
+	/* Timing and fine Timing measurement capability clubbed together */
+	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;
+	/* Extended capabilities of STA */
+	uint8_t              ecsa_capable;
+
+	tDot11fIEHTCaps ht_caps;
+	tDot11fIEVHTCaps vht_caps;
+} tSirSmeAssocIndToUpperLayerCnf, *tpSirSmeAssocIndToUpperLayerCnf;
+
+typedef struct tagCsrSummaryStatsInfo {
+	uint32_t snr;
+	uint32_t rssi;
+	uint32_t retry_cnt[4];
+	uint32_t multiple_retry_cnt[4];
+	uint32_t tx_frm_cnt[4];
+	/* uint32_t num_rx_frm_crc_err; same as rx_error_cnt */
+	/* uint32_t num_rx_frm_crc_ok; same as rx_frm_cnt */
+	uint32_t rx_frm_cnt;
+	uint32_t frm_dup_cnt;
+	uint32_t fail_cnt[4];
+	uint32_t rts_fail_cnt;
+	uint32_t ack_fail_cnt;
+	uint32_t rts_succ_cnt;
+	uint32_t rx_discard_cnt;
+	uint32_t rx_error_cnt;
+	uint32_t tx_byte_cnt;
+
+} tCsrSummaryStatsInfo;
+
+typedef struct tagCsrGlobalClassAStatsInfo {
+	uint8_t tx_nss;
+	uint8_t rx_nss;
+	uint32_t max_pwr;
+	uint32_t tx_rate;
+	uint32_t rx_rate;
+	/* mcs index for HT20 and HT40 rates */
+	uint32_t tx_mcs_index;
+	uint32_t rx_mcs_index;
+	uint32_t tx_mcs_rate_flags;
+	uint32_t rx_mcs_rate_flags;
+	/* to diff between HT20 & HT40 rates;short & long guard interval */
+	uint32_t tx_rx_rate_flags;
+
+} tCsrGlobalClassAStatsInfo;
+
+typedef struct tagCsrGlobalClassDStatsInfo {
+	uint32_t tx_uc_frm_cnt;
+	uint32_t tx_mc_frm_cnt;
+	uint32_t tx_bc_frm_cnt;
+	uint32_t rx_uc_frm_cnt;
+	uint32_t rx_mc_frm_cnt;
+	uint32_t rx_bc_frm_cnt;
+	uint32_t tx_uc_byte_cnt[4];
+	uint32_t tx_mc_byte_cnt;
+	uint32_t tx_bc_byte_cnt;
+	uint32_t rx_uc_byte_cnt[4];
+	uint32_t rx_mc_byte_cnt;
+	uint32_t rx_bc_byte_cnt;
+	uint32_t rx_byte_cnt;
+	uint32_t num_rx_bytes_crc_ok;
+	uint32_t rx_rate;
+
+} tCsrGlobalClassDStatsInfo;
+
+/**
+ * struct csr_per_chain_rssi_stats_info - stores chain rssi
+ * @rssi: array containing rssi for all chains
+ * @peer_mac_addr: peer mac address
+ */
+struct csr_per_chain_rssi_stats_info {
+	int8_t rssi[NUM_CHAINS_MAX];
+	tSirMacAddr peer_mac_addr;
+};
+
+typedef struct tagCsrRoamSetKey {
+	eCsrEncryptionType encType;
+	tAniKeyDirection keyDirection;  /* Tx, Rx or Tx-and-Rx */
+	struct qdf_mac_addr peerMac;    /* Peer MAC. ALL 1's for group key */
+	uint8_t paeRole;        /* 0 for supplicant */
+	uint8_t keyId;          /* Key index */
+	uint16_t keyLength;     /* Number of bytes containing the key in pKey */
+	uint8_t Key[CSR_MAX_KEY_LEN];
+	uint8_t keyRsc[CSR_MAX_RSC_LEN];
+} tCsrRoamSetKey;
+
+typedef struct tagCsrRoamRemoveKey {
+	eCsrEncryptionType encType;
+	struct qdf_mac_addr peerMac; /* Peer MAC. ALL 1's for group key */
+	uint8_t keyId;          /* key index */
+} tCsrRoamRemoveKey;
+
+#ifdef FEATURE_WLAN_TDLS
+
+typedef struct tagCsrLinkEstablishParams {
+	tSirMacAddr peerMac;
+	uint8_t uapsdQueues;
+	uint8_t maxSp;
+	uint8_t isBufSta;
+	uint8_t isOffChannelSupported;
+	uint8_t isResponder;
+	uint8_t supportedChannelsLen;
+	uint8_t supportedChannels[SIR_MAC_MAX_SUPP_CHANNELS];
+	uint8_t supportedOperClassesLen;
+	uint8_t supportedOperClasses[REG_MAX_SUPP_OPER_CLASSES];
+	uint8_t qos;
+} tCsrTdlsLinkEstablishParams;
+
+typedef struct tagCsrTdlsSendMgmt {
+	tSirMacAddr peerMac;
+	uint8_t frameType;
+	uint8_t dialog;
+	uint16_t statusCode;
+	uint8_t responder;
+	uint32_t peerCapability;
+	uint8_t *buf;
+	uint8_t len;
+	enum wifi_traffic_ac ac;
+} tCsrTdlsSendMgmt;
+#endif
+
+typedef void *tScanResultHandle;
+
+typedef enum {
+	REASSOC = 0,
+	FASTREASSOC = 1,
+	CONNECT_CMD_USERSPACE = 2,
+} handoff_src;
+
+typedef struct tagCsrHandoffRequest {
+	struct qdf_mac_addr bssid;
+	uint8_t channel;
+	uint8_t src;   /* To check if its a REASSOC or a FASTREASSOC IOCTL */
+} tCsrHandoffRequest;
+
+#ifdef FEATURE_WLAN_ESE
+typedef struct tagCsrEseBeaconReqParams {
+	uint16_t measurementToken;
+	uint8_t channel;
+	uint8_t scanMode;
+	uint16_t measurementDuration;
+} tCsrEseBeaconReqParams, *tpCsrEseBeaconReqParams;
+
+typedef struct tagCsrEseBeaconReq {
+	uint8_t numBcnReqIe;
+	tCsrEseBeaconReqParams bcnReq[SIR_ESE_MAX_MEAS_IE_REQS];
+} tCsrEseBeaconReq, *tpCsrEseBeaconReq;
+#endif /* FEATURE_WLAN_ESE */
+
+struct csr_del_sta_params {
+	struct qdf_mac_addr peerMacAddr;
+	uint16_t reason_code;
+	uint8_t subtype;
+};
+
+/**
+ * struct wep_update_default_key_idx: wep default key index structure
+ * @session_id: session ID for the connection session
+ * @default_idx: default key index for wep
+ *
+ * structure includes sesssion id for connection and default key
+ * index used for wep
+ */
+struct wep_update_default_key_idx {
+	uint8_t session_id;
+	uint8_t default_idx;
+};
+
+typedef QDF_STATUS (*csr_roam_complete_cb)(void *context,
+					   struct csr_roam_info *param,
+					   uint32_t roam_id,
+					   eRoamCmdStatus roam_status,
+					   eCsrRoamResult roam_result);
+typedef QDF_STATUS (*csr_session_open_cb)(uint8_t session_id,
+					  QDF_STATUS qdf_status);
+typedef QDF_STATUS (*csr_session_close_cb)(uint8_t session_id);
+
+#define CSR_IS_START_IBSS(pProfile) (eCSR_BSS_TYPE_START_IBSS == \
+				     (pProfile)->BSSType)
+#define CSR_IS_JOIN_TO_IBSS(pProfile) (eCSR_BSS_TYPE_IBSS == \
+				       (pProfile)->BSSType)
+#define CSR_IS_IBSS(pProfile) (CSR_IS_START_IBSS(pProfile) || \
+			       CSR_IS_JOIN_TO_IBSS(pProfile))
+#define CSR_IS_INFRASTRUCTURE(pProfile) (eCSR_BSS_TYPE_INFRASTRUCTURE == \
+					 (pProfile)->BSSType)
+#define CSR_IS_ANY_BSS_TYPE(pProfile) (eCSR_BSS_TYPE_ANY == \
+				       (pProfile)->BSSType)
+#define CSR_IS_INFRA_AP(pProfile) (eCSR_BSS_TYPE_INFRA_AP ==  \
+				   (pProfile)->BSSType)
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+#define CSR_IS_NDI(profile)  (eCSR_BSS_TYPE_NDI == (profile)->BSSType)
+#else
+#define CSR_IS_NDI(profile)  (false)
+#endif
+#define CSR_IS_CONN_INFRA_AP(pProfile)  (eCSR_BSS_TYPE_INFRA_AP == \
+					 (pProfile)->BSSType)
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+#define CSR_IS_CONN_NDI(profile)  (eCSR_BSS_TYPE_NDI == (profile)->BSSType)
+#else
+#define CSR_IS_CONN_NDI(profile)  (false)
+#endif
+
+#ifdef WLAN_FEATURE_SAE
+#define CSR_IS_AUTH_TYPE_SAE(auth_type) \
+	(eCSR_AUTH_TYPE_SAE == auth_type)
+#else
+#define CSR_IS_AUTH_TYPE_SAE(auth_type) (false)
+#endif
+
+QDF_STATUS csr_set_channels(tpAniSirGlobal pMac, tCsrConfigParam *pParam);
+
+/* enum to string conversion for debug output */
+const char *get_e_roam_cmd_status_str(eRoamCmdStatus val);
+const char *get_e_csr_roam_result_str(eCsrRoamResult val);
+const char *csr_phy_mode_str(eCsrPhyMode phy_mode);
+typedef void (*tCsrStatsCallback)(void *stats, void *pContext);
+typedef void (*tCsrRssiCallback)(int8_t rssi, uint32_t staId, void *pContext);
+
+#ifdef FEATURE_WLAN_ESE
+typedef void (*tCsrTsmStatsCallback)(tAniTrafStrmMetrics tsmMetrics,
+				     uint32_t staId, void *pContext);
+#endif /* FEATURE_WLAN_ESE */
+typedef void (*tCsrSnrCallback)(int8_t snr, uint32_t staId, void *pContext);
+
+/**
+ * csr_roam_issue_ft_preauth_req() - Initiate Preauthentication request
+ * @max_ctx: Global MAC context
+ * @session_id: SME Session ID
+ * @bss_desc: BSS descriptor
+ *
+ * Return: Success or Failure
+ */
+#ifdef WLAN_FEATURE_HOST_ROAM
+QDF_STATUS csr_roam_issue_ft_preauth_req(tpAniSirGlobal mac_ctx,
+					 uint32_t session_id,
+					 tpSirBssDescription bss_desc);
+#else
+static inline
+QDF_STATUS csr_roam_issue_ft_preauth_req(tpAniSirGlobal mac_ctx,
+					 uint32_t session_id,
+					 tpSirBssDescription bss_desc)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+enum band_info csr_get_current_band(struct mac_context *mac);
+typedef void (*csr_readyToSuspendCallback)(void *pContext, bool suspended);
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+typedef void (*csr_readyToExtWoWCallback)(void *pContext, bool status);
+#endif
+typedef void (*csr_link_status_callback)(uint8_t status, void *context);
+#ifdef FEATURE_WLAN_TDLS
+void csr_roam_fill_tdls_info(tpAniSirGlobal mac_ctx,
+			     struct csr_roam_info *roam_info,
+			     tpSirSmeJoinRsp join_rsp);
+#else
+static inline void csr_roam_fill_tdls_info(tpAniSirGlobal mac_ctx,
+					   struct csr_roam_info *roam_info,
+					   tpSirSmeJoinRsp join_rsp)
+{}
+#endif
+void csr_packetdump_timer_stop(void);
+
+/**
+ * csr_get_channel_status() - get chan info via channel number
+ * @mac: Pointer to Global MAC structure
+ * @channel_id: channel id
+ *
+ * Return: chan status info
+ */
+struct lim_channel_status *
+csr_get_channel_status(tpAniSirGlobal mac, uint32_t channel_id);
+
+/**
+ * csr_clear_channel_status() - clear chan info
+ * @mac: Pointer to Global MAC structure
+ *
+ * Return: none
+ */
+void csr_clear_channel_status(tpAniSirGlobal mac);
+#endif
diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h
new file mode 100644
index 0000000..8275937
--- /dev/null
+++ b/core/sme/inc/csr_internal.h
@@ -0,0 +1,1391 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ *   \file csr_internal.h
+ *
+ *   Define internal data structure for MAC.
+ */
+#ifndef CSRINTERNAL_H__
+#define CSRINTERNAL_H__
+
+#include "qdf_status.h"
+#include "qdf_lock.h"
+
+#include "qdf_mc_timer.h"
+#include "csr_support.h"
+#include "cds_reg_service.h"
+#include "wlan_scan_public_structs.h"
+#include "csr_neighbor_roam.h"
+
+#include "sir_types.h"
+
+/* define scan return criteria. LIM should use these define as well */
+#define CSR_SCAN_RETURN_AFTER_ALL_CHANNELS          (0)
+#define CSR_SCAN_RETURN_AFTER_FIRST_MATCH           (0x01)
+#define CSR_NUM_RSSI_CAT        15
+#define CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME        3
+
+/* session ID invalid */
+#define CSR_SESSION_ID_INVALID    0xFF
+/* No of sessions to be supported, and a session is for Infra, IBSS or BT-AMP */
+#define CSR_ROAM_SESSION_MAX      SIR_MAX_SUPPORTED_BSS
+#define CSR_IS_SESSION_VALID(pMac, sessionId) \
+	(((sessionId) < CSR_ROAM_SESSION_MAX) && \
+	 ((pMac)->roam.roamSession[(sessionId)].sessionActive))
+
+#define CSR_GET_SESSION(pMac, sessionId) \
+	( \
+	  (sessionId < CSR_ROAM_SESSION_MAX) ? \
+	  (&(pMac)->roam.roamSession[(sessionId)]) : NULL \
+	)
+
+#define CSR_IS_SESSION_ANY(sessionId) (sessionId == SME_SESSION_ID_ANY)
+#define CSR_MAX_NUM_COUNTRY_CODE  100
+#define CSR_IS_DFS_CH_ROAM_ALLOWED(mac_ctx) \
+	( \
+	  (((mac_ctx)->roam.configParam.allowDFSChannelRoam) ? true : false) \
+	)
+#define CSR_IS_SELECT_5GHZ_MARGIN(pMac) \
+	( \
+	  (((pMac)->roam.configParam.nSelect5GHzMargin) ? true : false) \
+	)
+#define CSR_IS_ROAM_PREFER_5GHZ(pMac)	\
+	( \
+	  (((pMac)->roam.configParam.nRoamPrefer5GHz) ? true : false) \
+	)
+#define CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac) \
+	( \
+	  (((pMac)->roam.configParam.nRoamIntraBand) ? true : false) \
+	)
+#define CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED(pMac) \
+	( \
+	  (((pMac)->roam.configParam.bFastRoamInConIniFeatureEnabled) ? \
+		true : false) \
+	)
+#define CSR_IS_CHANNEL_24GHZ(chnNum) \
+	(((chnNum) > 0) && ((chnNum) <= 14))
+/* Support for "Fast roaming" (i.e., ESE, LFR, or 802.11r.) */
+#define CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN 15
+
+/* Used to determine what to set to the WNI_CFG_DOT11_MODE */
+enum csr_cfgdot11mode {
+	eCSR_CFG_DOT11_MODE_ABG,
+	eCSR_CFG_DOT11_MODE_11A,
+	eCSR_CFG_DOT11_MODE_11B,
+	eCSR_CFG_DOT11_MODE_11G,
+	eCSR_CFG_DOT11_MODE_11N,
+	eCSR_CFG_DOT11_MODE_11AC,
+	eCSR_CFG_DOT11_MODE_11G_ONLY,
+	eCSR_CFG_DOT11_MODE_11N_ONLY,
+	eCSR_CFG_DOT11_MODE_11AC_ONLY,
+	/* This value can never set to CFG. Its for CSR's internal use */
+	eCSR_CFG_DOT11_MODE_AUTO,
+	eCSR_CFG_DOT11_MODE_11AX,
+	eCSR_CFG_DOT11_MODE_11AX_ONLY,
+};
+
+enum csr_scan_reason {
+	eCsrScanForSsid,
+};
+
+enum csr_roam_reason {
+	/* Roaming because we've not established the initial connection. */
+	eCsrNoConnection,
+	/* roaming because LIM reported a cap change in the associated AP. */
+	eCsrCapsChange,
+	/* roaming because someone asked us to Disassoc & stay disassociated. */
+	eCsrForcedDisassoc,
+	/* roaming because an 802.11 request was issued to the driver. */
+	eCsrHddIssued,
+	/* roaming because we need to force a Disassoc due to MIC failure */
+	eCsrForcedDisassocMICFailure,
+	eCsrHddIssuedReassocToSameAP,
+	eCsrSmeIssuedReassocToSameAP,
+	/* roaming because someone asked us to deauth and stay disassociated. */
+	eCsrForcedDeauth,
+	/* will be issued by Handoff logic to disconect from current AP */
+	eCsrSmeIssuedDisassocForHandoff,
+	/* will be issued by Handoff logic to join a new AP with same profile */
+	eCsrSmeIssuedAssocToSimilarAP,
+	eCsrForcedIbssLeave,
+	eCsrStopBss,
+	eCsrSmeIssuedFTReassoc,
+	eCsrForcedDisassocSta,
+	eCsrForcedDeauthSta,
+	eCsrPerformPreauth,
+	/* Roaming disabled from driver during connect/start BSS */
+	ecsr_driver_disabled,
+};
+
+enum csr_roam_substate {
+	eCSR_ROAM_SUBSTATE_NONE = 0,
+	eCSR_ROAM_SUBSTATE_START_BSS_REQ,
+	eCSR_ROAM_SUBSTATE_JOIN_REQ,
+	eCSR_ROAM_SUBSTATE_REASSOC_REQ,
+	eCSR_ROAM_SUBSTATE_DISASSOC_REQ,
+	eCSR_ROAM_SUBSTATE_STOP_BSS_REQ,
+	/* Continue the current roam command after disconnect */
+	eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
+	eCSR_ROAM_SUBSTATE_AUTH_REQ,
+	eCSR_ROAM_SUBSTATE_CONFIG,
+	eCSR_ROAM_SUBSTATE_DEAUTH_REQ,
+	eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN,
+	eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE,
+	eCSR_ROAM_SUBSTATE_DISASSOC_FORCED,
+	eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY,
+	eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF,
+	eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC,
+	eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC,
+	eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC,
+	eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT,
+	/*  max is 15 unless the bitfield is expanded... */
+};
+
+enum csr_roam_state {
+	eCSR_ROAMING_STATE_STOP = 0,
+	eCSR_ROAMING_STATE_IDLE,
+	eCSR_ROAMING_STATE_JOINING,
+	eCSR_ROAMING_STATE_JOINED,
+};
+
+enum csr_join_state {
+	eCsrContinueRoaming,
+	eCsrStopRoaming,
+	eCsrStartIbss,
+	eCsrStartIbssSameIbss,
+	eCsrReassocToSelfNoCapChange,
+	eCsrStopRoamingDueToConcurrency,
+
+};
+
+enum csr_roaming_reason {
+	eCsrNotRoaming,
+	eCsrLostlinkRoamingDisassoc,
+	eCsrLostlinkRoamingDeauth,
+	eCsrDynamicRoaming,
+	eCsrReassocRoaming,
+};
+
+enum csr_roam_wmstatus_changetypes {
+	eCsrDisassociated,
+	eCsrDeauthenticated
+};
+
+enum csr_roam_stats_classtypes {
+	eCsrSummaryStats = 0,
+	eCsrGlobalClassAStats,
+	eCsrGlobalClassDStats,
+	csr_per_chain_rssi_stats,
+	eCsrMaxStats
+};
+
+enum csr_diagwlan_status_eventsubtype {
+	eCSR_WLAN_STATUS_CONNECT = 0,
+	eCSR_WLAN_STATUS_DISCONNECT
+};
+
+enum csr_diagwlan_status_eventreason {
+	eCSR_REASON_UNSPECIFIED = 0,
+	eCSR_REASON_USER_REQUESTED,
+	eCSR_REASON_MIC_ERROR,
+	eCSR_REASON_DISASSOC,
+	eCSR_REASON_DEAUTH,
+	eCSR_REASON_HANDOFF,
+	eCSR_REASON_ROAM_SYNCH_IND,
+	eCSR_REASON_ROAM_SYNCH_CNF,
+	eCSR_REASON_ROAM_HO_FAIL,
+};
+
+struct csr_channel {
+	uint8_t numChannels;
+	uint8_t channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+};
+
+struct scan_profile       {
+	uint32_t minChnTime;
+	uint32_t maxChnTime;
+	/* In units of milliseconds, ignored when not connected */
+	uint32_t restTime;
+	/* In units of milliseconds, ignored when not connected */
+	uint32_t min_rest_time;
+	/* In units of milliseconds, ignored when not connected */
+	uint32_t idle_time;
+	uint32_t numOfChannels;
+	uint8_t *pChannelList;
+	tSirScanType scanType;
+	eCsrRoamBssType bssType;
+	uint8_t ssid[WNI_CFG_SSID_LEN];
+	uint8_t bReturnAfter1stMatch;
+	uint8_t fUniqueResult;
+	uint8_t freshScan;
+	struct qdf_mac_addr bssid;
+};
+
+struct bss_config_param {
+	eCsrMediaAccessType qosType;
+	tSirMacSSid SSID;
+	uint32_t uRTSThresh;
+	uint32_t uDeferThresh;
+	enum csr_cfgdot11mode uCfgDot11Mode;
+	enum band_info eBand;
+	tAniAuthType authType;
+	eCsrEncryptionType encType;
+	uint32_t uShortSlotTime;
+	uint32_t uHTSupport;
+	uint32_t uPowerLimit;
+	uint32_t uHeartBeatThresh;
+	uint32_t uJoinTimeOut;
+	tSirMacCapabilityInfo BssCap;
+	bool f11hSupport;
+	ePhyChanBondState cbMode;
+};
+
+struct csr_roamstart_bssparams {
+	tSirMacSSid ssId;
+
+	/*
+	 * This is the BSSID for the party we want to
+	 * join (only use for IBSS or WDS).
+	 */
+	struct qdf_mac_addr bssid;
+	tSirNwType sirNwType;
+	ePhyChanBondState cbMode;
+	tSirMacRateSet operationalRateSet;
+	tSirMacRateSet extendedRateSet;
+	uint8_t operationChn;
+	struct ch_params ch_params;
+	enum csr_cfgdot11mode uCfgDot11Mode;
+	uint8_t privacy;
+	bool fwdWPSPBCProbeReq;
+	bool protEnabled;
+	bool obssProtEnabled;
+	tAniAuthType authType;
+	uint16_t beaconInterval; /* If this is 0, SME'll fill in for caller */
+	uint16_t ht_protection;
+	uint32_t dtimPeriod;
+	uint8_t ApUapsdEnable;
+	uint8_t ssidHidden;
+	uint8_t wps_state;
+	enum QDF_OPMODE bssPersona;
+	uint16_t nRSNIELength;  /* If 0, pRSNIE is ignored. */
+	uint8_t *pRSNIE;        /* If not null, it has IE byte stream for RSN */
+	/* Flag used to indicate update beaconInterval */
+	bool updatebeaconInterval;
+#ifdef WLAN_FEATURE_11W
+	bool mfpCapable;
+	bool mfpRequired;
+#endif
+	tSirAddIeParams addIeParams;
+	uint8_t sap_dot11mc;
+	uint16_t beacon_tx_rate;
+	uint32_t cac_duration_ms;
+	uint32_t dfs_regdomain;
+};
+
+struct roam_cmd {
+	uint32_t roamId;
+	enum csr_roam_reason roamReason;
+	struct csr_roam_profile roamProfile;
+	tScanResultHandle hBSSList;       /* BSS list fits the profile */
+	/*
+	 * point to the current BSS in the list that is roaming.
+	 * It starts from head to tail
+	 * */
+	tListElem *pRoamBssEntry;
+	tSirBssDescription *pLastRoamBss; /* the last BSS we try and failed */
+	bool fReleaseBssList;             /* whether to free hBSSList */
+	bool fReleaseProfile;             /* whether to free roamProfile */
+	bool fReassoc;                    /* whether this cmd is for reassoc */
+	/* whether pMac->roam.pCurRoamProfile needs to be updated */
+	bool fUpdateCurRoamProfile;
+	/*
+	 * this is for CSR internal used only. And it should not be assigned
+	 * when creating the command. This causes the roam cmd not todo anything
+	 */
+	bool fReassocToSelfNoCapChange;
+
+	bool fStopWds;
+	tSirMacAddr peerMac;
+	tSirMacReasonCodes reason;
+	eCsrRoamDisconnectReason disconnect_reason;
+};
+
+struct setkey_cmd {
+	uint32_t roamId;
+	eCsrEncryptionType encType;
+	eCsrAuthType authType;
+	tAniKeyDirection keyDirection;  /* Tx, Rx or Tx-and-Rx */
+	struct qdf_mac_addr peermac;    /* Peer's MAC address. ALL 1's for group key */
+	uint8_t paeRole;        /* 0 for supplicant */
+	uint8_t keyId;          /* Kye index */
+	uint8_t keyLength;      /* Number of bytes containing the key in pKey */
+	uint8_t Key[CSR_MAX_KEY_LEN];
+	uint8_t keyRsc[CSR_MAX_RSC_LEN];
+};
+
+struct wmstatus_changecmd {
+	enum csr_roam_wmstatus_changetypes Type;
+	union {
+		tSirSmeDeauthInd DeauthIndMsg;
+		tSirSmeDisassocInd DisassocIndMsg;
+	} u;
+
+};
+
+struct addstafor_sessioncmd {
+	/* Session self mac addr */
+	tSirMacAddr selfMacAddr;
+	enum QDF_OPMODE currDeviceMode;
+	uint32_t type;
+	uint32_t subType;
+	uint8_t sessionId;
+};
+
+struct delstafor_sessionCmd {
+	/* Session self mac addr */
+	tSirMacAddr selfMacAddr;
+	csr_session_close_cb session_close_cb;
+	void *context;
+};
+
+struct csr_neighbor_roamconfig {
+	uint32_t nNeighborScanTimerPeriod;
+	uint32_t neighbor_scan_min_timer_period;
+	uint8_t nNeighborLookupRssiThreshold;
+	int8_t rssi_thresh_offset_5g;
+	uint16_t nNeighborScanMinChanTime;
+	uint16_t nNeighborScanMaxChanTime;
+	sCsrChannel neighborScanChanList;
+	uint8_t nMaxNeighborRetries;
+	uint16_t nNeighborResultsRefreshPeriod;
+	uint16_t nEmptyScanRefreshPeriod;
+	uint8_t nOpportunisticThresholdDiff;
+	uint8_t nRoamRescanRssiDiff;
+	uint8_t nRoamBmissFirstBcnt;
+	uint8_t nRoamBmissFinalBcnt;
+	uint8_t nRoamBeaconRssiWeight;
+	uint8_t delay_before_vdev_stop;
+	uint32_t nhi_rssi_scan_max_count;
+	uint32_t nhi_rssi_scan_rssi_delta;
+	uint32_t nhi_rssi_scan_delay;
+	int32_t nhi_rssi_scan_rssi_ub;
+};
+
+/*
+ * Neighbor Report Params Bitmask
+ */
+#define NEIGHBOR_REPORT_PARAMS_TIME_OFFSET            0x01
+#define NEIGHBOR_REPORT_PARAMS_LOW_RSSI_OFFSET        0x02
+#define NEIGHBOR_REPORT_PARAMS_BMISS_COUNT_TRIGGER    0x04
+#define NEIGHBOR_REPORT_PARAMS_PER_THRESHOLD_OFFSET   0x08
+#define NEIGHBOR_REPORT_PARAMS_CACHE_TIMEOUT          0x10
+#define NEIGHBOR_REPORT_PARAMS_MAX_REQ_CAP            0x20
+#define NEIGHBOR_REPORT_PARAMS_ALL                    0x3F
+
+struct csr_config {
+	uint32_t agingCount;
+	uint32_t channelBondingMode24GHz;
+	uint32_t channelBondingMode5GHz;
+	eCsrPhyMode phyMode;
+	enum csr_cfgdot11mode uCfgDot11Mode;
+	uint32_t HeartbeatThresh50;
+	uint32_t HeartbeatThresh24;
+	eCsrRoamWmmUserModeType WMMSupportMode;
+	bool Is11eSupportEnabled;
+	bool Is11dSupportEnabled;
+	bool Is11hSupportEnabled;
+	bool shortSlotTime;
+	bool ProprietaryRatesEnabled;
+	bool fenableMCCMode;
+	bool mcc_rts_cts_prot_enable;
+	bool mcc_bcast_prob_resp_enable;
+	uint8_t fAllowMCCGODiffBI;
+	uint8_t AdHocChannel24;
+	uint8_t AdHocChannel5G;
+	/* each RSSI category has one value */
+	uint32_t BssPreferValue[CSR_NUM_RSSI_CAT];
+	int RSSICat[CSR_NUM_RSSI_CAT];
+	uint8_t bCatRssiOffset; /* to set RSSI difference for each category */
+	/*
+	 * Whether to limit the channels to the ones set in Csr11dInfo.
+	 * If true, the opertaional channels are limited to the default channel
+	 * list. It is an "AND" operation between the default channels and
+	 * the channels in the 802.11d IE.
+	 */
+	/* Country Code Priority */
+	bool fSupplicantCountryCodeHasPriority;
+
+	uint16_t vccRssiThreshold;
+	uint32_t vccUlMacLossThreshold;
+	uint32_t nPassiveMaxChnTime;    /* in units of milliseconds */
+	uint32_t nActiveMaxChnTime;     /* in units of milliseconds */
+
+	uint32_t nInitialDwellTime;     /* in units of milliseconds */
+	bool initial_scan_no_dfs_chnl;
+	uint32_t nPassiveMinChnTimeConc;/* in units of milliseconds */
+	uint32_t nPassiveMaxChnTimeConc;/* in units of milliseconds */
+	uint32_t nActiveMinChnTimeConc; /* in units of milliseconds */
+	uint32_t nActiveMaxChnTimeConc; /* in units of milliseconds */
+	uint32_t nRestTimeConc;         /* in units of milliseconds */
+	/* In units of milliseconds */
+	uint32_t  min_rest_time_conc;
+	/* In units of milliseconds */
+	uint32_t  idle_time_conc;
+	/*
+	 * in dBm, the max TX power. The actual TX power is the lesser of this
+	 * value & 11d. If 11d is disable, the lesser of this & default setting.
+	 */
+	uint8_t nTxPowerCap;
+	bool allow_tpc_from_ap;
+	uint32_t statsReqPeriodicity;    /* stats req freq while in fullpower */
+	uint32_t statsReqPeriodicityInPS;/* stats req freq while in powersave */
+	uint32_t dtimPeriod;
+	bool ssidHidden;
+	uint8_t isFastRoamIniFeatureEnabled;
+	struct mawc_params csr_mawc_config;
+	uint8_t isRoamOffloadScanEnabled;
+	bool bFastRoamInConIniFeatureEnabled;
+#ifdef FEATURE_WLAN_ESE
+	uint8_t isEseIniFeatureEnabled;
+#endif
+	uint8_t isFastTransitionEnabled;
+	uint8_t RoamRssiDiff;
+	bool nRoamPrefer5GHz;
+	bool nRoamIntraBand;
+	bool isWESModeEnabled;
+	bool nRoamScanControl;
+	uint8_t nProbes;
+	uint16_t nRoamScanHomeAwayTime;
+
+	struct csr_neighbor_roamconfig neighborRoamConfig;
+
+	/*
+	 * Instead of Reassoc, send ADDTS/DELTS even when ACM is off for
+	 * that AC This is mandated by WMM-AC certification
+	 */
+	bool addTSWhenACMIsOff;
+	/*
+	 * Remove this code once SLM_Sessionization is supported
+	 * BMPS_WORKAROUND_NOT_NEEDED
+	 */
+	bool doBMPSWorkaround;
+	/* To enable scanning 2g channels twice on single scan req from HDD */
+	bool fScanTwice;
+	uint32_t nVhtChannelWidth;
+	bool send_smps_action;
+	uint8_t tx_ldpc_enable;
+	uint8_t rx_ldpc_enable;
+	uint8_t disable_high_ht_mcs_2x2;
+	/*
+	 * Enable/Disable heartbeat offload
+	 */
+	bool enableHeartBeatOffload;
+	uint32_t ho_delay_for_rx;
+	uint32_t min_delay_btw_roam_scans;
+	uint32_t roam_trigger_reason_bitmask;
+	uint8_t isCoalesingInIBSSAllowed;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	uint8_t cc_switch_mode;
+#endif
+	uint8_t allowDFSChannelRoam;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	bool isRoamOffloadEnabled;
+#endif
+	bool obssEnabled;
+	uint8_t conc_custom_rule1;
+	uint8_t conc_custom_rule2;
+	uint8_t is_sta_connection_in_5gz_enabled;
+	struct roam_ext_params roam_params;
+	bool vendor_vht_sap;
+	enum scan_dwelltime_adaptive_mode scan_adaptive_dwell_mode;
+	enum scan_dwelltime_adaptive_mode scan_adaptive_dwell_mode_nc;
+	struct csr_sta_roam_policy_params sta_roam_policy;
+	bool enable_bcast_probe_rsp;
+	bool is_fils_enabled;
+#ifdef WLAN_FEATURE_11AX
+	bool enable_ul_ofdma;
+	bool enable_ul_mimo;
+#endif
+	bool is_force_1x1;
+	uint16_t wlm_latency_enable;
+	uint16_t wlm_latency_level;
+	uint32_t wlm_latency_flags[CSR_NUM_WLM_LATENCY_LEVEL];
+	uint8_t oce_feature_bitmap;
+	uint32_t btm_offload_config;
+	uint32_t btm_solicited_timeout;
+	uint32_t btm_max_attempt_cnt;
+	uint32_t btm_sticky_time;
+	uint32_t offload_11k_enable_bitmask;
+	bool wep_tkip_in_he;
+	struct csr_neighbor_report_offload_params neighbor_report_offload;
+	bool enable_ftopen;
+	bool roam_force_rssi_trigger;
+};
+
+struct csr_channel_powerinfo {
+	tListElem link;
+	uint8_t firstChannel;
+	uint8_t numChannels;
+	uint8_t txPower;
+	uint8_t interChannelOffset;
+};
+
+struct csr_roam_joinstatus {
+	tSirResultCodes statusCode;
+	/*
+	 * this is set to unspecified if statusCode indicates timeout.
+	 * Or it is the failed reason from the other BSS(per 802.11 spec)
+	 */
+	uint32_t reasonCode;
+	tSirMacAddr bssId;
+};
+
+struct csr_votes11d {
+	uint8_t votes;
+	uint8_t countryCode[WNI_CFG_COUNTRY_CODE_LEN];
+};
+
+struct csr_scanstruct {
+	struct scan_profile scanProfile;
+	uint8_t scanResultCfgAgingTime;
+	tSirScanType curScanType;
+	struct csr_channel channels11d;
+	struct channel_power defaultPowerTable[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	uint32_t numChannelsDefault;
+	struct csr_channel base_channels;  /* The channel base to work on */
+	tDblLinkList channelPowerInfoList24;
+	tDblLinkList channelPowerInfoList5G;
+	uint32_t nLastAgeTimeOut;
+	uint32_t nAgingCountDown;
+	uint8_t countryCodeDefault[WNI_CFG_COUNTRY_CODE_LEN];
+	uint8_t countryCodeCurrent[WNI_CFG_COUNTRY_CODE_LEN];
+	uint8_t countryCode11d[WNI_CFG_COUNTRY_CODE_LEN];
+	v_REGDOMAIN_t domainIdDefault;  /* default regulatory domain */
+	v_REGDOMAIN_t domainIdCurrent;  /* current regulatory domain */
+
+	uint8_t countryCodeCount;
+	/* counts for various advertized country codes */
+	struct csr_votes11d votes11d[CSR_MAX_NUM_COUNTRY_CODE];
+	/*
+	 * in 11d IE from probe rsp or beacons of neighboring APs
+	 * will use the most popular one (max count)
+	 */
+	uint8_t countryCodeElected[WNI_CFG_COUNTRY_CODE_LEN];
+	/*
+	 * Customer wants to start with an active scan based on the default
+	 * country code. This optimization will minimize the driver load to
+	 * association time. Based on this flag we will bypass the initial
+	 * passive scan needed for 11d to determine the country code & domain
+	 */
+	bool fEnableBypass11d;
+	/*
+	 * Customer wants to optimize the scan time. Avoiding scans(passive)
+	 * on DFS channels while swipping through both bands can save some time
+	 * (apprx 1.3 sec)
+	 */
+	uint8_t fEnableDFSChnlScan;
+	/*
+	 * To enable/disable scanning only 2.4Ghz channels on first scan
+	 */
+	bool fFirstScanOnly2GChnl;
+	bool fDropScanCmd;      /* true means we don't accept scan commands */
+
+	/* This includes all channels on which candidate APs are found */
+	struct csr_channel occupiedChannels[CSR_ROAM_SESSION_MAX];
+	int8_t roam_candidate_count[CSR_ROAM_SESSION_MAX];
+	int8_t inScanResultBestAPRssi;
+	bool fcc_constraint;
+	uint8_t max_scan_count;
+	bool defer_update_channel_list;
+	wlan_scan_requester requester_id;
+};
+
+/*
+ * Save the connected information. This structure + connectedProfile
+ * should contain all information about the connection
+ */
+struct csr_roam_connectedinfo {
+	uint32_t nBeaconLength;
+	uint32_t nAssocReqLength;
+	uint32_t nAssocRspLength;
+	/* len of the parsed RIC resp IEs received in reassoc response */
+	uint32_t nRICRspLength;
+#ifdef FEATURE_WLAN_ESE
+	uint32_t nTspecIeLength;
+#endif
+	/*
+	 * Point to a buffer contain the beacon, assoc req, assoc rsp frame, in
+	 * that order user needs to use nBeaconLength, nAssocReqLength,
+	 * nAssocRspLength to desice where each frame starts and ends.
+	 */
+	uint8_t *pbFrames;
+	uint8_t staId;
+};
+
+#ifndef QCA_SUPPORT_CP_STATS
+struct csr_pestats_reqinfo {
+	tListElem link;         /* list links */
+	uint32_t statsMask;
+	bool rspPending;
+	uint8_t staId;
+	uint8_t numClient;
+	tpAniSirGlobal pMac;
+	uint8_t sessionId;
+};
+
+struct csr_statsclient_reqinfo {
+	tListElem link;         /* list links */
+	eCsrStatsRequesterType requesterId;
+	tCsrStatsCallback callback;
+	void *pContext;
+	uint32_t statsMask;
+	struct csr_pestats_reqinfo *pPeStaEntry;
+	uint8_t staId;
+	qdf_mc_timer_t timer;
+	bool timerExpired;
+	tpAniSirGlobal pMac;    /* TODO: Confirm this change BTAMP */
+	uint8_t sessionId;
+};
+
+struct csr_tlstats_reqinfo {
+	uint8_t numClient;
+};
+#endif /* QCA_SUPPORT_CP_STATS */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+enum csr_roamoffload_authstatus {
+	/* reassociation is done but couldn't finish security handshake */
+	eSIR_ROAM_AUTH_STATUS_CONNECTED = 1,
+	/* roam successfully completed by firmware */
+	eSIR_ROAM_AUTH_STATUS_AUTHENTICATED = 2,
+	/* unknown error */
+	eSIR_ROAM_AUTH_STATUS_UNKNOWN = 0xff
+};
+struct csr_roam_offload_synch_params {
+	uint8_t roamedVdevId;   /* vdevId after roaming */
+	int8_t txMgmtPower;     /* HAL fills in the tx power used for */
+	uint8_t rssi;           /* RSSI */
+	uint8_t roamReason;     /* Roam reason */
+	uint8_t nss;            /* no of spatial streams */
+	uint16_t chainMask;     /* chainmask */
+	uint16_t smpsMode;      /* smps.mode */
+	struct qdf_mac_addr bssid;      /* MAC address of roamed AP */
+	enum csr_roamoffload_authstatus authStatus;   /* auth status */
+	uint8_t kck[SIR_KCK_KEY_LEN];
+	uint8_t kek[SIR_KEK_KEY_LEN_FILS];
+	uint32_t kek_len;
+	uint32_t pmk_len;
+	uint8_t pmk[SIR_PMK_LEN];
+	uint8_t pmkid[SIR_PMKID_LEN];
+	bool update_erp_next_seq_num;
+	uint16_t next_erp_seq_num;
+	uint8_t replay_ctr[SIR_REPLAY_CTR_LEN];
+	tpSirBssDescription  bss_desc_ptr;      /*BSS descriptor*/
+};
+#endif
+
+struct csr_roam_stored_profile {
+	uint32_t session_id;
+	struct csr_roam_profile profile;
+	tScanResultHandle bsslist_handle;
+	enum csr_roam_reason reason;
+	uint32_t roam_id;
+	bool imediate_flag;
+	bool clear_flag;
+};
+
+/**
+ * struct scan_cmd_info - Scan cache entry node
+ * @scan_id: scan id
+ * @scan_reason: scan reason
+ * @profile: roam profile
+ * @roam_id: Roam id
+ * @roambssentry: scan entries
+ */
+struct scan_cmd_info {
+	wlan_scan_id scan_id;
+	enum csr_scan_reason scan_reason;
+	struct csr_roam_profile *profile;
+	uint32_t roam_id;
+	tListElem *roambssentry;
+};
+
+/**
+ * struct csr_disconnect_stats - Disconnect Stats per session
+ * @disconnection_cnt: total no. of disconnections
+ * @disconnection_by_app: diconnections triggered by application
+ * @disassoc_by_peer: disassoc sent by peer
+ * @deauth_by_peer: deauth sent by peer
+ * @bmiss: disconnect triggered by beacon miss
+ * @peer_kickout: disconnect triggered by peer kickout
+ */
+struct csr_disconnect_stats {
+	uint32_t disconnection_cnt;
+	uint32_t disconnection_by_app;
+	uint32_t disassoc_by_peer;
+	uint32_t deauth_by_peer;
+	uint32_t bmiss;
+	uint32_t peer_kickout;
+};
+
+struct csr_roam_session {
+	uint8_t sessionId;      /* Session ID */
+	bool sessionActive;     /* true if it is used */
+
+	/* For BT-AMP station, this serve as BSSID for self-BSS. */
+	struct qdf_mac_addr selfMacAddr;
+
+	csr_session_open_cb  session_open_cb;
+	csr_session_close_cb session_close_cb;
+	csr_roam_complete_cb callback;
+	void *pContext;
+	eCsrConnectState connectState;
+	struct rsn_caps rsn_caps;
+	tCsrRoamConnectedProfile connectedProfile;
+	struct csr_roam_connectedinfo connectedInfo;
+	struct csr_roam_profile *pCurRoamProfile;
+	tSirBssDescription *pConnectBssDesc;
+	uint16_t NumPmkidCache; /* valid number of pmkid in the cache*/
+	uint16_t curr_cache_idx; /* the index in pmkidcache to write next to */
+	tPmkidCacheInfo PmkidCacheInfo[CSR_MAX_PMKID_ALLOWED];
+	uint8_t cJoinAttemps;
+	/*
+	 * This may or may not have the up-to-date valid channel list. It is
+	 * used to get WNI_CFG_VALID_CHANNEL_LIST and not alloc memory all time
+	 */
+	tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	int32_t sPendingCommands;   /* 0 means CSR is ok to low power */
+#ifdef FEATURE_WLAN_WAPI
+	uint16_t NumBkidCache;
+	tBkidCacheInfo BkidCacheInfo[CSR_MAX_BKID_ALLOWED];
+#endif /* FEATURE_WLAN_WAPI */
+	/*
+	 * indicate whether CSR is roaming
+	 * (either via lostlink or dynamic roaming)
+	 */
+	bool fRoaming;
+	/*
+	 * to remember some parameters needed for START_BSS.
+	 * All member must be set every time we try to join or start an IBSS
+	 */
+	struct csr_roamstart_bssparams bssParams;
+	/* the byte count of pWpaRsnIE; */
+	uint32_t nWpaRsnReqIeLength;
+	/* contain the WPA/RSN IE in assoc req or one sent in beacon(IBSS) */
+	uint8_t *pWpaRsnReqIE;
+	/* the byte count for pWpaRsnRspIE */
+	uint32_t nWpaRsnRspIeLength;
+	/* this contain the WPA/RSN IE in beacon/probe rsp */
+	uint8_t *pWpaRsnRspIE;
+#ifdef FEATURE_WLAN_WAPI
+	/* the byte count of pWapiReqIE; */
+	uint32_t nWapiReqIeLength;
+	/* this contain the WAPI IE in assoc req or one sent in beacon (IBSS) */
+	uint8_t *pWapiReqIE;
+	/* the byte count for pWapiRspIE */
+	uint32_t nWapiRspIeLength;
+	/* this contain the WAPI IE in beacon/probe rsp */
+	uint8_t *pWapiRspIE;
+#endif /* FEATURE_WLAN_WAPI */
+	uint32_t nAddIEScanLength;      /* the byte count of pAddIeScanIE; */
+	/* contains the additional IE in (unicast) probe req at time of join */
+	uint8_t *pAddIEScan;
+	uint32_t nAddIEAssocLength;     /* the byte count for pAddIeAssocIE */
+	uint8_t *pAddIEAssoc;
+	tCsrTimerInfo roamingTimerInfo;
+	enum csr_roaming_reason roamingReason;
+	bool fCancelRoaming;
+	qdf_mc_timer_t hTimerRoaming;
+	/* the roamResult that is used when the roaming timer fires */
+	eCsrRoamResult roamResult;
+	/* This is the reason code for join(assoc) failure */
+	struct csr_roam_joinstatus joinFailStatusCode;
+	/* status from PE for deauth/disassoc(lostlink) or our own dyn roam */
+	uint32_t roamingStatusCode;
+	uint16_t NumPmkidCandidate;
+	tPmkidCandidateInfo PmkidCandidateInfo[CSR_MAX_PMKID_ALLOWED];
+#ifdef FEATURE_WLAN_WAPI
+	uint16_t NumBkidCandidate;
+	tBkidCandidateInfo BkidCandidateInfo[CSR_MAX_BKID_ALLOWED];
+#endif
+	bool fWMMConnection;
+	bool fQOSConnection;
+#ifdef FEATURE_WLAN_ESE
+	tCsrEseCckmInfo eseCckmInfo;
+	bool isPrevApInfoValid;
+	tSirMacSSid prevApSSID;
+	struct qdf_mac_addr prevApBssid;
+	uint8_t prevOpChannel;
+	uint16_t clientDissSecs;
+	uint32_t roamTS1;
+	tCsrEseCckmIe suppCckmIeInfo;
+#endif
+	uint8_t bRefAssocStartCnt;      /* Tracking assoc start indication */
+	tSirHTConfig htConfig;
+	struct sir_vht_config vht_config;
+#ifdef WLAN_FEATURE_11AX
+	tDot11fIEhe_cap he_config;
+	uint32_t he_sta_obsspd;
+#endif
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	struct csr_roam_offload_synch_params roamOffloadSynchParams;
+	uint8_t psk_pmk[SIR_ROAM_SCAN_PSK_SIZE];
+	size_t pmk_len;
+	uint8_t RoamKeyMgmtOffloadEnabled;
+	roam_offload_synch_ind *roam_synch_data;
+	struct pmkid_mode_bits pmkid_modes;
+#endif
+	tftSMEContext ftSmeContext;
+	/* This count represents the number of bssid's we try to join. */
+	uint8_t join_bssid_count;
+	struct csr_roam_stored_profile stored_roam_profile;
+	bool ch_switch_in_progress;
+	bool roam_synch_in_progress;
+	bool supported_nss_1x1;
+	uint8_t vdev_nss;
+	uint8_t nss;
+	bool nss_forced_1x1;
+	bool disable_hi_rssi;
+	bool dhcp_done;
+	uint8_t disconnect_reason;
+	uint8_t uapsd_mask;
+	struct scan_cmd_info scan_info;
+	qdf_mc_timer_t roaming_offload_timer;
+	bool is_fils_connection;
+	uint16_t fils_seq_num;
+	bool discon_in_progress;
+	struct csr_disconnect_stats disconnect_stats;
+};
+
+struct csr_roamstruct {
+	uint32_t nextRoamId;
+	tDblLinkList channelList5G;
+	tDblLinkList channelList24;
+	struct csr_config configParam;
+	uint32_t numChannelsEeprom;     /* total channels of eeprom */
+	struct csr_channel baseChannels;  /* The channel base to work on */
+	enum csr_roam_state curState[CSR_ROAM_SESSION_MAX];
+	enum csr_roam_substate curSubState[CSR_ROAM_SESSION_MAX];
+	/*
+	 * This may or may not have the up-to-date valid channel list. It is
+	 * used to get WNI_CFG_VALID_CHANNEL_LIST and not alloc mem all time
+	 */
+	tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	uint32_t numValidChannels;       /* total number of channels in CFG */
+	int32_t sPendingCommands;
+	qdf_mc_timer_t hTimerWaitForKey; /* support timeout for WaitForKey */
+#ifndef QCA_SUPPORT_CP_STATS
+	tCsrSummaryStatsInfo summaryStatsInfo;
+	tCsrGlobalClassAStatsInfo classAStatsInfo;
+	tCsrGlobalClassDStatsInfo classDStatsInfo;
+	struct csr_per_chain_rssi_stats_info  per_chain_rssi_stats;
+	tDblLinkList statsClientReqList;
+	tDblLinkList peStatsReqList;
+	struct csr_tlstats_reqinfo tlStatsReqInfo;
+#endif
+	tCsrTimerInfo WaitForKeyTimerInfo;
+	struct csr_roam_session *roamSession;
+	uint32_t transactionId;  /* Current transaction ID for internal use. */
+	tCsrNeighborRoamControlInfo neighborRoamInfo[CSR_ROAM_SESSION_MAX];
+	uint8_t isFastRoamIniFeatureEnabled;
+#ifdef FEATURE_WLAN_ESE
+	uint8_t isEseIniFeatureEnabled;
+#endif
+	uint8_t RoamRssiDiff;
+	bool isWESModeEnabled;
+	uint32_t deauthRspStatus;
+	uint8_t *pReassocResp;          /* reassociation response from new AP */
+	uint16_t reassocRespLen;        /* length of reassociation response */
+	qdf_mc_timer_t packetdump_timer;
+	qdf_list_t rssi_disallow_bssid;
+	spinlock_t roam_state_lock;
+};
+
+#define GET_NEXT_ROAM_ID(pRoamStruct)  (((pRoamStruct)->nextRoamId + 1 == 0) ? \
+			1 : (pRoamStruct)->nextRoamId)
+#define CSR_IS_ROAM_STATE(pMac, state, sessionId) \
+			((state) == (pMac)->roam.curState[sessionId])
+#define CSR_IS_ROAM_STOP(pMac, sessionId) \
+		CSR_IS_ROAM_STATE((pMac), eCSR_ROAMING_STATE_STOP, sessionId)
+#define CSR_IS_ROAM_INIT(pMac, sessionId) \
+		 CSR_IS_ROAM_STATE((pMac), eCSR_ROAMING_STATE_INIT, sessionId)
+#define CSR_IS_ROAM_JOINING(pMac, sessionId)  \
+		CSR_IS_ROAM_STATE(pMac, eCSR_ROAMING_STATE_JOINING, sessionId)
+#define CSR_IS_ROAM_IDLE(pMac, sessionId) \
+		CSR_IS_ROAM_STATE(pMac, eCSR_ROAMING_STATE_IDLE, sessionId)
+#define CSR_IS_ROAM_JOINED(pMac, sessionId) \
+		CSR_IS_ROAM_STATE(pMac, eCSR_ROAMING_STATE_JOINED, sessionId)
+#define CSR_IS_ROAM_SUBSTATE(pMac, subState, sessionId) \
+		((subState) == (pMac)->roam.curSubState[sessionId])
+#define CSR_IS_ROAM_SUBSTATE_JOIN_REQ(pMac, sessionId) \
+	CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_JOIN_REQ, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_AUTH_REQ(pMac, sessionId) \
+	CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_AUTH_REQ, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_REASSOC_REQ(pMac, sessionId) \
+	CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_REASSOC_REQ, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(pMac, sessionId) \
+	CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISASSOC_REQ, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN(pMac, sessionId) \
+	CSR_IS_ROAM_SUBSTATE((pMac), \
+		eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL(pMac, sessionId) \
+		CSR_IS_ROAM_SUBSTATE((pMac), \
+			eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED(pMac, sessionId) \
+		CSR_IS_ROAM_SUBSTATE((pMac), \
+			eCSR_ROAM_SUBSTATE_DISASSOC_FORCED, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(pMac, sessionId) \
+		CSR_IS_ROAM_SUBSTATE((pMac), \
+			eCSR_ROAM_SUBSTATE_DEAUTH_REQ, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_START_BSS_REQ(pMac, sessionId) \
+		CSR_IS_ROAM_SUBSTATE((pMac), \
+			eCSR_ROAM_SUBSTATE_START_BSS_REQ, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(pMac, sessionId) \
+		CSR_IS_ROAM_SUBSTATE((pMac), \
+			eCSR_ROAM_SUBSTATE_STOP_BSS_REQ, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE(pMac, sessionId) \
+		CSR_IS_ROAM_SUBSTATE((pMac), \
+		eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId) \
+		CSR_IS_ROAM_SUBSTATE((pMac), \
+		eCSR_ROAM_SUBSTATE_CONFIG, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_WAITFORKEY(pMac, sessionId) \
+		CSR_IS_ROAM_SUBSTATE((pMac), \
+			eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId) \
+		CSR_IS_ROAM_SUBSTATE((pMac), \
+			eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_HO_NT(pMac, sessionId) \
+		CSR_IS_ROAM_SUBSTATE((pMac), \
+			eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC, sessionId)
+#define CSR_IS_ROAM_SUBSTATE_HO_NRT(pMac, sessionId)  \
+			CSR_IS_ROAM_SUBSTATE((pMac), \
+				eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC,\
+					sessionId)
+#define CSR_IS_ROAM_SUBSTATE_HO_RT(pMac, sessionId) \
+			CSR_IS_ROAM_SUBSTATE((pMac),\
+			eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC, sessionId)
+#define CSR_IS_PHY_MODE_B_ONLY(pMac) \
+	((eCSR_DOT11_MODE_11b == (pMac)->roam.configParam.phyMode) || \
+	 (eCSR_DOT11_MODE_11b_ONLY == (pMac)->roam.configParam.phyMode))
+
+#define CSR_IS_PHY_MODE_G_ONLY(pMac) \
+	(eCSR_DOT11_MODE_11g == (pMac)->roam.configParam.phyMode \
+		|| eCSR_DOT11_MODE_11g_ONLY == (pMac)->roam.configParam.phyMode)
+
+#define CSR_IS_PHY_MODE_A_ONLY(pMac) \
+	(eCSR_DOT11_MODE_11a == (pMac)->roam.configParam.phyMode)
+
+#define CSR_IS_PHY_MODE_DUAL_BAND(phyMode) \
+	((eCSR_DOT11_MODE_abg & (phyMode)) || \
+	 (eCSR_DOT11_MODE_11n & (phyMode)) || \
+	 (eCSR_DOT11_MODE_11ac & (phyMode)) || \
+	 (eCSR_DOT11_MODE_11ax & (phyMode)) || \
+	 (eCSR_DOT11_MODE_AUTO & (phyMode)))
+
+#define CSR_IS_PHY_MODE_11n(phy_mode) \
+	((eCSR_DOT11_MODE_11n == phy_mode) || \
+	 (eCSR_DOT11_MODE_11n_ONLY == phy_mode) || \
+	 (eCSR_DOT11_MODE_11ac == phy_mode) || \
+	 (eCSR_DOT11_MODE_11ac_ONLY == phy_mode))
+
+#define CSR_IS_PHY_MODE_11ac(phy_mode) \
+	((eCSR_DOT11_MODE_11ac == phy_mode) || \
+	 (eCSR_DOT11_MODE_11ac_ONLY == phy_mode))
+
+/*
+ * this function returns true if the NIC is operating exclusively in
+ * the 2.4 GHz band, meaning. it is NOT operating in the 5.0 GHz band.
+ */
+#define CSR_IS_24_BAND_ONLY(pMac) \
+	(BAND_2G == (pMac)->mlme_cfg->gen.band)
+
+#define CSR_IS_5G_BAND_ONLY(pMac) \
+	(BAND_5G == (pMac)->mlme_cfg->gen.band)
+
+#define CSR_IS_RADIO_DUAL_BAND(pMac) \
+	(BAND_ALL == (pMac)->mlme_cfg->gen.band_capability)
+
+#define CSR_IS_RADIO_BG_ONLY(pMac) \
+	(BAND_2G == (pMac)->mlme_cfg->gen.band_capability)
+
+/*
+ * this function returns true if the NIC is operating exclusively in the 5.0 GHz
+ * band, meaning. it is NOT operating in the 2.4 GHz band
+ */
+#define CSR_IS_RADIO_A_ONLY(pMac) \
+	(BAND_5G == (pMac)->mlme_cfg->gen.band_capability)
+/* this function returns true if the NIC is operating in both bands. */
+#define CSR_IS_OPEARTING_DUAL_BAND(pMac) \
+	((BAND_ALL == (pMac)->mlme_cfg->gen.band_capability) && \
+		(BAND_ALL == (pMac)->mlme_cfg->gen.band))
+/*
+ * this function returns true if the NIC can operate in the 5.0 GHz band
+ * (could operate in the 2.4 GHz band also)
+ */
+#define CSR_IS_OPERATING_A_BAND(pMac) \
+	(CSR_IS_OPEARTING_DUAL_BAND((pMac)) || \
+		CSR_IS_RADIO_A_ONLY((pMac)) || CSR_IS_5G_BAND_ONLY((pMac)))
+
+/*
+ * this function returns true if the NIC can operate in the 2.4 GHz band
+ * (could operate in the 5.0 GHz band also).
+ */
+#define CSR_IS_OPERATING_BG_BAND(pMac) \
+	(CSR_IS_OPEARTING_DUAL_BAND((pMac)) || \
+		CSR_IS_RADIO_BG_ONLY((pMac)) || CSR_IS_24_BAND_ONLY((pMac)))
+#define CSR_GET_BAND(ch_num) \
+	((WLAN_REG_IS_24GHZ_CH(ch_num)) ? BAND_2G : BAND_5G)
+#define CSR_IS_11D_INFO_FOUND(pMac) \
+	(0 != (pMac)->scan.channelOf11dInfo)
+#define CSR_IS_ROAMING(pSession) \
+	((CSR_IS_LOSTLINK_ROAMING((pSession)->roamingReason)) || \
+		(eCsrDynamicRoaming == (pSession)->roamingReason)  ||	\
+		(eCsrReassocRoaming == (pSession)->roamingReason))
+#define CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) \
+	(pMac->roam.configParam.addTSWhenACMIsOff)
+#define CSR_IS_LOSTLINK_ROAMING(reason) \
+	((eCsrLostlinkRoamingDisassoc == (reason)) || \
+		(eCsrLostlinkRoamingDeauth == (reason)))
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+/* bit-4 and bit-5 indicate the subnet status */
+#define CSR_GET_SUBNET_STATUS(roam_reason) (((roam_reason) & 0x30) >> 4)
+#else
+#define CSR_GET_SUBNET_STATUS(roam_reason) (0)
+#endif
+
+QDF_STATUS csr_get_channel_and_power_list(tpAniSirGlobal pMac);
+
+QDF_STATUS csr_scan_filter_results(tpAniSirGlobal pMac);
+
+QDF_STATUS csr_set_modify_profile_fields(tpAniSirGlobal pMac,
+		uint32_t sessionId, tCsrRoamModifyProfileFields *
+		pModifyProfileFields);
+QDF_STATUS csr_get_modify_profile_fields(tpAniSirGlobal pMac,
+		uint32_t sessionId, tCsrRoamModifyProfileFields *
+		pModifyProfileFields);
+void csr_set_global_cfgs(tpAniSirGlobal pMac);
+void csr_set_default_dot11_mode(tpAniSirGlobal pMac);
+bool csr_is_conn_state_disconnected(tpAniSirGlobal pMac,
+						   uint32_t sessionId);
+bool csr_is_conn_state_connected_ibss(tpAniSirGlobal pMac,
+						      uint32_t sessionId);
+bool csr_is_conn_state_disconnected_ibss(tpAniSirGlobal pMac,
+							   uint32_t sessionId);
+bool csr_is_conn_state_connected_infra(tpAniSirGlobal pMac,
+							uint32_t sessionId);
+bool csr_is_conn_state_connected(tpAniSirGlobal pMac,
+					       uint32_t sessionId);
+bool csr_is_conn_state_infra(tpAniSirGlobal pMac,
+					uint32_t sessionId);
+bool csr_is_conn_state_ibss(tpAniSirGlobal pMac, uint32_t sessionId);
+bool csr_is_conn_state_wds(tpAniSirGlobal pMac, uint32_t sessionId);
+bool csr_is_conn_state_connected_wds(tpAniSirGlobal pMac,
+						    uint32_t sessionId);
+bool csr_is_conn_state_disconnected_wds(tpAniSirGlobal pMac,
+		uint32_t sessionId);
+bool csr_is_any_session_in_connect_state(tpAniSirGlobal pMac);
+bool csr_is_all_session_disconnected(tpAniSirGlobal pMac);
+bool csr_is_sta_session_connected(tpAniSirGlobal pMac);
+bool csr_is_p2p_session_connected(tpAniSirGlobal pMac);
+bool csr_is_any_session_connected(tpAniSirGlobal pMac);
+bool csr_is_infra_connected(tpAniSirGlobal pMac);
+
+/**
+ * csr_get_connected_infra() - get the session id of the connected infra
+ * @mac_ctx:  pointer to global mac structure
+ *
+ * The function check if any infra is present in connected state and if present
+ * return the session id of the connected infra else if no infra is in connected
+ * state return CSR_SESSION_ID_INVALID
+ *
+ * Return: session id of the connected infra
+ */
+uint8_t csr_get_connected_infra(tpAniSirGlobal mac_ctx);
+bool csr_is_concurrent_infra_connected(tpAniSirGlobal pMac);
+bool csr_is_concurrent_session_running(tpAniSirGlobal pMac);
+bool csr_is_infra_ap_started(tpAniSirGlobal pMac);
+bool csr_is_ibss_started(tpAniSirGlobal pMac);
+bool csr_is_valid_mc_concurrent_session(tpAniSirGlobal pMac,
+							 uint32_t sessionId,
+						tSirBssDescription *pBssDesc);
+bool csr_is_conn_state_connected_infra_ap(tpAniSirGlobal pMac,
+		uint32_t sessionId);
+QDF_STATUS csr_get_statistics(tpAniSirGlobal pMac,
+		eCsrStatsRequesterType requesterId,
+		uint32_t statsMask, tCsrStatsCallback callback,
+		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);
+QDF_STATUS csr_get_snr(tpAniSirGlobal pMac, tCsrSnrCallback callback,
+		uint8_t staId, struct qdf_mac_addr bssId, void *pContext);
+QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac,
+					  tCsrConfigParam *pParam);
+QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
+		tCsrConfigParam *pParam);
+QDF_STATUS csr_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf);
+QDF_STATUS csr_open(tpAniSirGlobal pMac);
+QDF_STATUS csr_init_chan_list(tpAniSirGlobal mac, uint8_t *alpha2);
+QDF_STATUS csr_close(tpAniSirGlobal pMac);
+QDF_STATUS csr_start(tpAniSirGlobal pMac);
+QDF_STATUS csr_stop(tpAniSirGlobal pMac);
+QDF_STATUS csr_ready(tpAniSirGlobal pMac);
+
+#ifdef FEATURE_WLAN_WAPI
+QDF_STATUS csr_roam_get_wapi_req_ie(tpAniSirGlobal pMac,
+		uint32_t sessionId, uint32_t *pLen, uint8_t *pBuf);
+QDF_STATUS csr_roam_get_wapi_rsp_ie(tpAniSirGlobal pMac,
+						uint32_t sessionId,
+		uint32_t *pLen, uint8_t *pBuf);
+uint8_t csr_construct_wapi_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+		struct csr_roam_profile *pProfile,
+		tSirBssDescription *pSirBssDesc,
+		tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe);
+#endif /* FEATURE_WLAN_WAPI */
+
+void csr_set_cfg_privacy(tpAniSirGlobal pMac,
+			 struct csr_roam_profile *pProfile,
+			 bool fPrivacy);
+int8_t csr_get_infra_session_id(tpAniSirGlobal pMac);
+uint8_t csr_get_infra_operation_channel(tpAniSirGlobal pMac,
+							uint8_t sessionId);
+bool csr_is_session_client_and_connected(tpAniSirGlobal pMac,
+		uint8_t sessionId);
+uint8_t csr_get_concurrent_operation_channel(
+	tpAniSirGlobal pMac);
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+uint16_t csr_check_concurrent_channel_overlap(
+		tpAniSirGlobal pMac,
+		uint16_t sap_ch, eCsrPhyMode sap_phymode,
+		uint8_t cc_switch_mode);
+#endif
+QDF_STATUS csr_roam_copy_connect_profile(tpAniSirGlobal pMac,
+		uint32_t sessionId, tCsrRoamConnectedProfile *pProfile);
+bool csr_is_set_key_allowed(tpAniSirGlobal pMac, uint32_t sessionId);
+
+/* Returns whether the current association is a 11r assoc or not */
+bool csr_roam_is11r_assoc(tpAniSirGlobal pMac, uint8_t sessionId);
+
+#ifdef FEATURE_WLAN_ESE
+/* Returns whether the current association is a ESE assoc or not */
+bool csr_roam_is_ese_assoc(tpAniSirGlobal pMac, uint32_t sessionId);
+bool csr_roam_is_ese_ini_feature_enabled(tpAniSirGlobal pMac);
+QDF_STATUS csr_get_tsm_stats(tpAniSirGlobal pMac,
+		tCsrTsmStatsCallback callback,
+		uint8_t staId,
+		struct qdf_mac_addr bssId,
+		void *pContext, uint8_t tid);
+#endif
+
+/* Returns whether "Legacy Fast Roaming" is enabled...or not */
+bool csr_roam_is_fast_roam_enabled(tpAniSirGlobal pMac,
+						uint32_t sessionId);
+bool csr_roam_is_roam_offload_scan_enabled(
+	tpAniSirGlobal pMac);
+bool csr_is_channel_present_in_list(uint8_t *pChannelList,
+						   int numChannels,
+						   uint8_t channel);
+QDF_STATUS csr_add_to_channel_list_front(uint8_t *pChannelList,
+							int numChannels,
+		uint8_t channel);
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+QDF_STATUS csr_roam_offload_scan_rsp_hdlr(tpAniSirGlobal pMac,
+		tpSirRoamOffloadScanRsp scanOffloadRsp);
+#else
+static inline QDF_STATUS csr_roam_offload_scan_rsp_hdlr(
+		tpAniSirGlobal pMac,
+		tpSirRoamOffloadScanRsp scanOffloadRsp)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+QDF_STATUS csr_handoff_request(tpAniSirGlobal pMac, uint8_t sessionId,
+		tCsrHandoffRequest
+		*pHandoffInfo);
+bool csr_roam_is_sta_mode(tpAniSirGlobal pMac, uint32_t sessionId);
+
+/* Post Channel Change Indication */
+QDF_STATUS csr_roam_channel_change_req(tpAniSirGlobal pMac,
+					struct qdf_mac_addr
+				       bssid, struct ch_params *ch_params,
+				       struct csr_roam_profile *profile);
+
+/* Post Beacon Tx Start Indication */
+QDF_STATUS csr_roam_start_beacon_req(tpAniSirGlobal pMac,
+		struct qdf_mac_addr bssid, uint8_t dfsCacWaitStatus);
+
+QDF_STATUS csr_roam_send_chan_sw_ie_request(tpAniSirGlobal pMac,
+					    struct qdf_mac_addr bssid,
+					    uint8_t targetChannel,
+					    uint8_t csaIeReqd,
+					    struct ch_params *ch_params);
+QDF_STATUS csr_roam_modify_add_ies(tpAniSirGlobal pMac,
+					tSirModifyIE *pModifyIE,
+				   eUpdateIEsType updateType);
+QDF_STATUS
+csr_roam_update_add_ies(tpAniSirGlobal pMac,
+		tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS csr_scan_save_roam_offload_ap_to_scan_cache(
+		tpAniSirGlobal pMac,
+		struct sSirSmeRoamOffloadSynchInd *roam_synch_ind_ptr,
+		tpSirBssDescription  bss_desc_ptr);
+void csr_process_ho_fail_ind(tpAniSirGlobal pMac, void *pMsgBuf);
+#endif
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+void csr_roaming_report_diag_event(tpAniSirGlobal mac_ctx,
+		roam_offload_synch_ind *roam_synch_ind_ptr,
+		enum csr_diagwlan_status_eventreason reason);
+#else
+static inline void csr_roaming_report_diag_event(
+		tpAniSirGlobal mac_ctx,
+		roam_offload_synch_ind *roam_synch_ind_ptr,
+		enum csr_diagwlan_status_eventreason reason)
+{}
+#endif
+
+bool csr_store_joinreq_param(tpAniSirGlobal mac_ctx,
+		struct csr_roam_profile *profile,
+		tScanResultHandle scan_cache,
+		uint32_t *roam_id,
+		uint32_t session_id);
+bool csr_find_session_by_bssid(tpAniSirGlobal mac_ctx, uint8_t *bssid);
+bool csr_clear_joinreq_param(tpAniSirGlobal mac_ctx,
+		uint32_t session_id);
+QDF_STATUS csr_issue_stored_joinreq(tpAniSirGlobal mac_ctx,
+		uint32_t *roam_id,
+		uint32_t session_id);
+QDF_STATUS csr_get_channels_and_power(tpAniSirGlobal pMac);
+
+void csr_nonscan_pending_ll_unlock(struct mac_context *mac_ctx);
+void csr_nonscan_active_ll_unlock(struct mac_context *mac_ctx);
+void csr_nonscan_pending_ll_lock(struct mac_context *mac_ctx);
+void csr_nonscan_active_ll_lock(struct mac_context *mac_ctx);
+bool csr_nonscan_active_ll_is_list_empty(
+			struct mac_context *mac_ctx,
+			bool inter_locked);
+bool csr_nonscan_pending_ll_is_list_empty(
+			struct mac_context *mac_ctx,
+			bool inter_locked);
+bool csr_nonscan_active_ll_remove_entry(
+			struct mac_context *mac_ctx,
+			tListElem *pEntryToRemove, bool inter_locked);
+tListElem *csr_nonscan_active_ll_peek_head(
+			struct mac_context *mac_ctx,
+			bool inter_locked);
+tListElem *csr_nonscan_pending_ll_peek_head(
+			struct mac_context *mac_ctx,
+			bool inter_locked);
+tListElem *csr_nonscan_active_ll_remove_head(
+			struct mac_context *mac_ctx,
+			bool inter_locked);
+tListElem *csr_nonscan_pending_ll_remove_head(
+			struct mac_context *mac_ctx,
+			bool inter_locked);
+uint32_t csr_nonscan_pending_ll_count(
+			struct mac_context *mac_ctx);
+void csr_nonscan_pending_ll_insert_head(
+			struct mac_context *mac_ctx,
+		tListElem *entry, bool inter_locked);
+void csr_nonscan_pending_ll_insert_tail(
+			struct mac_context *mac_ctx,
+		tListElem *entry, bool inter_locked);
+uint32_t csr_nonscan_active_ll_count(
+			struct mac_context *mac_ctx);
+void csr_nonscan_active_ll_insert_head(
+			struct mac_context *mac_ctx,
+		tListElem *entry, bool inter_locked);
+tListElem *csr_nonscan_pending_ll_next(
+			struct mac_context *mac_ctx,
+		tListElem *entry, bool inter_locked);
+
+/**
+ * csr_purge_vdev_pending_ser_cmd_list() - purge all scan and non-scan
+ * pending cmds for the vdev id
+ * @mac_ctx: pointer to global MAC context
+ * @vdev_id : vdev id for which the pending cmds need to be purged
+ *
+ * Return : none
+ */
+void csr_purge_vdev_pending_ser_cmd_list(struct mac_context *mac_ctx,
+					 uint32_t vdev_id);
+
+/**
+ * csr_purge_vdev_all_ser_cmd_list() - purge all scan and non-scan
+ * active and pending cmds for the vdev id
+ * @mac_ctx: pointer to global MAC context
+ * @vdev_id : vdev id for which cmds need to be purged
+ *
+ * Return : none
+ */
+void csr_purge_vdev_all_ser_cmd_list(struct mac_context *mac_ctx,
+				     uint32_t vdev_id);
+
+/**
+ * csr_purge_vdev_all_scan_ser_cmd_list() - purge all scan active and pending
+ * cmds for the vdev id
+ * @mac_ctx: pointer to global MAC context
+ * @vdev_id : vdev id for which cmds need to be purged
+ *
+ * Return : none
+ */
+void csr_purge_vdev_all_scan_ser_cmd_list(struct mac_context *mac_ctx,
+					  uint32_t vdev_id);
+
+/**
+ * csr_purge_pdev_all_ser_cmd_list() - purge all scan and non-scan
+ * active and pending cmds for all vdevs in pdev
+ * @mac_ctx: pointer to global MAC context
+ *
+ * Return : none
+ */
+void csr_purge_pdev_all_ser_cmd_list(struct mac_context *mac_ctx);
+
+bool csr_wait_for_connection_update(tpAniSirGlobal mac,
+		bool do_release_reacquire_lock);
+enum QDF_OPMODE csr_get_session_persona(tpAniSirGlobal pmac,
+					uint32_t session_id);
+void csr_roam_substate_change(
+			tpAniSirGlobal pMac, enum csr_roam_substate
+					NewSubstate, uint32_t sessionId);
+
+void csr_neighbor_roam_process_scan_results(
+		tpAniSirGlobal mac_ctx,
+		uint8_t sessionid, tScanResultHandle *scan_results_list);
+
+void csr_neighbor_roam_trigger_handoff(tpAniSirGlobal mac_ctx,
+					uint8_t session_id);
+bool csr_is_ndi_started(tpAniSirGlobal mac_ctx, uint32_t session_id);
+
+QDF_STATUS csr_roam_update_config(
+			tpAniSirGlobal mac_ctx, uint8_t session_id,
+				  uint16_t capab, uint32_t value);
+
+/**
+ * csr_is_mcc_channel() - check if using the channel results into MCC
+ * @mac_ctx: pointer to global MAC context
+ * @channel : channel number to check for MCC scenario
+ *
+ * Return : true if channel causes MCC, else false
+ */
+bool csr_is_mcc_channel(tpAniSirGlobal mac_ctx, uint8_t channel);
+#endif
diff --git a/core/sme/inc/csr_link_list.h b/core/sme/inc/csr_link_list.h
new file mode 100644
index 0000000..bed6936
--- /dev/null
+++ b/core/sme/inc/csr_link_list.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2016, 2018 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.
+ */
+
+/**
+ * \file csr_link_list.h
+ *
+ * Exports and types for the Common link list interfaces.
+ */
+
+#ifndef CSR_LINK_LIST_H__
+#define CSR_LINK_LIST_H__
+
+#include "qdf_lock.h"
+#include "qdf_mc_timer.h"
+#include "cds_api.h"
+#include "sir_types.h"
+
+#define LL_ACCESS_LOCK          true
+#define LL_ACCESS_NOLOCK        false
+
+typedef struct tagListElem {
+	struct tagListElem *last;
+	struct tagListElem *next;
+} tListElem;
+
+typedef enum {
+	LIST_FLAG_CLOSE = 0,
+	LIST_FLAG_OPEN = 0xa1b2c4d7,
+} tListFlag;
+
+/* This is a circular double link list */
+typedef struct tagDblLinkList {
+	tListElem ListHead;
+	qdf_mutex_t Lock;
+	uint32_t Count;
+	tListFlag Flag;
+} tDblLinkList;
+
+/*
+ * To get the address of an object of (type) base on the (address)
+ * of one of its (field)
+ */
+#define GET_BASE_ADDR(address, type, field) ((type *)( \
+			(uint8_t *)(address) - \
+			(uint8_t *)(&((type *)0)->field)))
+/* To get the offset of (field) inside structure (type) */
+#define GET_FIELD_OFFSET(type, field)  ((uintptr_t)(&(((type *)0)->field)))
+#define GET_ROUND_UP(_Field, _Boundary) \
+	(((_Field) + ((_Boundary) - 1))  & ~((_Boundary) - 1))
+#define BITS_ON(_Field, _Bitmask)  ((_Field) |=  (_Bitmask))
+#define BITS_OFF(_Field, _Bitmask) ((_Field) &= ~(_Bitmask))
+#define CSR_MAX(a, b)  ((a) > (b) ? (a) : (b))
+#define CSR_MIN(a, b)  ((a) < (b) ? (a) : (b))
+#define csrIsListEmpty(pHead) ((pHead)->next == (pHead))
+
+uint32_t csr_ll_count(tDblLinkList *pList);
+QDF_STATUS csr_ll_open(tDblLinkList *pList);
+void csr_ll_close(tDblLinkList *pList);
+void csr_ll_lock(tDblLinkList *pList);
+void csr_ll_unlock(tDblLinkList *pList);
+bool csr_ll_is_list_empty(tDblLinkList *pList, bool fInterlocked);
+void csr_ll_insert_head(tDblLinkList *pList, tListElem *pEntry,
+		bool fInterlocked);
+void csr_ll_insert_tail(tDblLinkList *pList, tListElem *pEntry,
+		bool fInterlocked);
+/* This function put pNewEntry before pEntry. Caller should have found pEntry */
+void csr_ll_insert_entry(tDblLinkList *pList, tListElem *pEntry,
+		tListElem *pNewEntry, bool fInterlocked);
+tListElem *csr_ll_peek_head(tDblLinkList *pList, bool fInterlocked);
+tListElem *csr_ll_peek_tail(tDblLinkList *pList, bool fInterlocked);
+tListElem *csr_ll_remove_head(tDblLinkList *pList, bool fInterlocked);
+tListElem *csr_ll_remove_tail(tDblLinkList *pList, bool fInterlocked);
+bool csr_ll_remove_entry(tDblLinkList *pList, tListElem *pEntryToRemove,
+		bool fInterlocked);
+void csr_ll_purge(tDblLinkList *pList, bool fInterlocked);
+/* csr_ll_next return NULL if reaching the end or list is empty */
+tListElem *csr_ll_next(tDblLinkList *pList, tListElem *pEntry,
+		bool fInterlocked);
+tListElem *csr_ll_previous(tDblLinkList *pList, tListElem *pEntry,
+		bool fInterlocked);
+bool csr_ll_find_entry(tDblLinkList *pList, tListElem *pEntryToFind);
+#endif
diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h
new file mode 100644
index 0000000..e933159
--- /dev/null
+++ b/core/sme/inc/csr_neighbor_roam.h
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ * \file csr_neighbor_roam.h
+ *
+ * Exports and types for the neighbor roaming algorithm which is sepcifically
+ * designed for Android.
+ */
+
+#ifndef CSR_NEIGHBOR_ROAM_H
+#define CSR_NEIGHBOR_ROAM_H
+
+#include "sme_api.h"
+
+#define ROAM_AP_AGE_LIMIT_MS                     10000
+
+/* Enumeration of various states in neighbor roam algorithm */
+typedef enum {
+	eCSR_NEIGHBOR_ROAM_STATE_CLOSED,
+	eCSR_NEIGHBOR_ROAM_STATE_INIT,
+	eCSR_NEIGHBOR_ROAM_STATE_CONNECTED,
+	eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING,
+	eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING,
+	eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE,
+	eNEIGHBOR_STATE_MAX
+} eCsrNeighborRoamState;
+
+/* Parameters that are obtained from CFG */
+typedef struct sCsrNeighborRoamCfgParams {
+	uint32_t neighborScanPeriod;
+	uint32_t neighbor_scan_min_period;
+	tCsrChannelInfo channelInfo;
+	uint8_t neighborLookupThreshold;
+	int8_t rssi_thresh_offset_5g;
+	uint8_t neighborReassocThreshold;
+	uint32_t minChannelScanTime;
+	uint32_t maxChannelScanTime;
+	uint16_t neighborResultsRefreshPeriod;
+	uint16_t emptyScanRefreshPeriod;
+	uint8_t nOpportunisticThresholdDiff;
+	uint8_t nRoamRescanRssiDiff;
+	uint8_t nRoamBmissFirstBcnt;
+	uint8_t nRoamBmissFinalBcnt;
+	uint8_t nRoamBeaconRssiWeight;
+	uint8_t delay_before_vdev_stop;
+	uint32_t hi_rssi_scan_max_count;
+	uint32_t hi_rssi_scan_rssi_delta;
+	uint32_t hi_rssi_scan_delay;
+	int32_t hi_rssi_scan_rssi_ub;
+} tCsrNeighborRoamCfgParams, *tpCsrNeighborRoamCfgParams;
+
+#define CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX    255
+typedef struct sCsrNeighborRoamChannelInfo {
+	/* Flag to mark reception of IAPP Neighbor list */
+	bool IAPPNeighborListReceived;
+	/* Current channel index that is being scanned */
+	uint8_t currentChanIndex;
+	/* Max number of channels in channel list and the list of channels */
+	tCsrChannelInfo currentChannelListInfo;
+} tCsrNeighborRoamChannelInfo, *tpCsrNeighborRoamChannelInfo;
+
+typedef struct sCsrNeighborRoamBSSInfo {
+	tListElem List;
+	uint8_t apPreferenceVal;
+	tpSirBssDescription pBssDescription;
+} tCsrNeighborRoamBSSInfo, *tpCsrNeighborRoamBSSInfo;
+
+#define CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT  1000       /* in milliseconds */
+#define CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER   10 /* in milliseconds */
+/* Max number of MAC addresses with which the pre-auth was failed */
+#define MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS          10
+#define MAX_BSS_IN_NEIGHBOR_RPT                    15
+#define CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES  3
+
+/* Black listed APs. List of MAC Addresses with which the Preauth was failed */
+typedef struct sCsrPreauthFailListInfo {
+	uint8_t numMACAddress;
+	tSirMacAddr macAddress[MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS];
+} tCsrPreauthFailListInfo, *tpCsrPreauthFailListInfo;
+
+typedef struct sCsrNeighborReportBssInfo {
+	uint8_t channelNum;
+	uint8_t neighborScore;
+	tSirMacAddr neighborBssId;
+} tCsrNeighborReportBssInfo, *tpCsrNeighborReportBssInfo;
+
+typedef struct sCsr11rAssocNeighborInfo {
+	bool preauthRspPending;
+	bool neighborRptPending;
+	uint8_t currentNeighborRptRetryNum;
+	tCsrPreauthFailListInfo preAuthFailList;
+	uint32_t neighborReportTimeout;
+	uint32_t PEPreauthRespTimeout;
+	uint8_t numPreAuthRetries;
+	tDblLinkList preAuthDoneList;   /* llist which consists/preauth nodes */
+	uint8_t numBssFromNeighborReport;
+	/* Contains info needed during REPORT_SCAN State */
+	tCsrNeighborReportBssInfo neighboReportBssInfo[MAX_BSS_IN_NEIGHBOR_RPT];
+} tCsr11rAssocNeighborInfo, *tpCsr11rAssocNeighborInfo;
+
+typedef enum {
+	eFirstEmptyScan = 1,
+	eSecondEmptyScan,
+	eThirdEmptyScan,
+	eFourthEmptyScan,
+	eFifthEmptyScan,
+	eMaxEmptyScan = eFifthEmptyScan,
+} eNeighborRoamEmptyScanCount;
+
+typedef enum {
+	DEFAULT_SCAN = 0,
+	SPLIT_SCAN_OCCUPIED_LIST = 1,
+} eNeighborRoamScanMode;
+
+/* Complete control information for neighbor roam algorithm */
+typedef struct sCsrNeighborRoamControlInfo {
+	eCsrNeighborRoamState neighborRoamState;
+	eCsrNeighborRoamState prevNeighborRoamState;
+	tCsrNeighborRoamCfgParams cfgParams;
+	struct qdf_mac_addr currAPbssid;  /* current assoc AP */
+	uint8_t currAPoperationChannel; /* current assoc AP */
+	tCsrNeighborRoamChannelInfo roamChannelInfo;
+	uint8_t currentNeighborLookupThreshold;
+	uint8_t currentOpportunisticThresholdDiff;
+	uint8_t currentRoamRescanRssiDiff;
+	tDblLinkList roamableAPList;    /* List of current FT candidates */
+	struct csr_roam_profile csrNeighborRoamProfile;
+	bool is11rAssoc;
+	tCsr11rAssocNeighborInfo FTRoamInfo;
+#ifdef FEATURE_WLAN_ESE
+	bool isESEAssoc;
+	bool isVOAdmitted;
+	uint16_t MinQBssLoadRequired;
+#endif
+	/*
+	 * Previous connected profile.
+	 * If the new profile does not match previous we re-initialize
+	 * occupied channel list
+	 */
+	tCsrRoamConnectedProfile prevConnProfile;
+	/* upper layer requested a reassoc */
+	uint8_t uOsRequestedHandoff;
+	/* handoff related info came with upper layer's req for reassoc */
+	tCsrHandoffRequest handoffReqInfo;
+	uint8_t currentRoamBmissFirstBcnt;
+	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 */
+QDF_STATUS csr_neighbor_roam_indicate_connect(tpAniSirGlobal pMac,
+		uint8_t sessionId, QDF_STATUS status);
+QDF_STATUS csr_neighbor_roam_indicate_disconnect(tpAniSirGlobal pMac,
+		uint8_t sessionId);
+QDF_STATUS csr_neighbor_roam_init(tpAniSirGlobal pMac, uint8_t sessionId);
+void csr_neighbor_roam_close(tpAniSirGlobal pMac, uint8_t sessionId);
+QDF_STATUS csr_neighbor_roam_transit_to_cfg_chan_scan(tpAniSirGlobal pMac,
+		uint8_t sessionId);
+QDF_STATUS csrNeighborRoamTransitionToPreauthDone(tpAniSirGlobal pMac);
+QDF_STATUS csr_neighbor_roam_prepare_scan_profile_filter(tpAniSirGlobal pMac,
+		tCsrScanResultFilter *pScanFilter, uint8_t sessionId);
+QDF_STATUS csr_neighbor_roam_preauth_rsp_handler(tpAniSirGlobal pMac,
+		uint8_t sessionId, QDF_STATUS limStatus);
+bool csr_neighbor_roam_is11r_assoc(tpAniSirGlobal pMac, uint8_t sessionId);
+#ifdef WLAN_FEATURE_HOST_ROAM
+void csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+		tpAniSirGlobal pMac, uint8_t sessionId);
+bool csr_neighbor_roam_state_preauth_done(tpAniSirGlobal pMac,
+		uint8_t sessionId);
+QDF_STATUS csr_roam_issue_reassociate_cmd(tpAniSirGlobal pMac,
+		uint32_t sessionId);
+void csr_neighbor_roam_free_roamable_bss_list(tpAniSirGlobal mac_ctx,
+		tDblLinkList *llist);
+bool csr_neighbor_roam_get_handoff_ap_info(tpAniSirGlobal pMac,
+		tpCsrNeighborRoamBSSInfo pHandoffNode, uint8_t sessionId);
+QDF_STATUS csr_roam_issue_reassociate(tpAniSirGlobal pMac,
+		uint32_t sessionId, tSirBssDescription *pSirBssDesc,
+		tDot11fBeaconIEs *pIes, struct csr_roam_profile *pProfile);
+void csr_neighbor_roam_request_handoff(tpAniSirGlobal pMac, uint8_t sessionId);
+QDF_STATUS csr_neighbor_roam_candidate_found_ind_hdlr(tpAniSirGlobal pMac,
+		void *pMsg);
+QDF_STATUS csr_neighbor_roam_process_scan_complete(tpAniSirGlobal pMac,
+		uint8_t sessionId);
+bool csr_neighbor_roam_is_handoff_in_progress(tpAniSirGlobal pMac,
+		uint8_t sessionId);
+void csr_neighbor_roam_reset_preauth_control_info(
+		tpAniSirGlobal mac_ctx, uint8_t session_id);
+void csr_neighbor_roam_purge_preauth_failed_list(tpAniSirGlobal pMac);
+#else
+static inline bool csr_neighbor_roam_state_preauth_done(tpAniSirGlobal pMac,
+		uint8_t sessionId)
+{
+	return false;
+}
+static inline QDF_STATUS csr_roam_issue_reassociate_cmd(tpAniSirGlobal pMac,
+		uint32_t sessionId)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+static inline QDF_STATUS csr_roam_issue_reassociate(tpAniSirGlobal pMac,
+		uint32_t sessionId, tSirBssDescription *pSirBssDesc,
+		tDot11fBeaconIEs *pIes, struct csr_roam_profile *pProfile)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+static inline QDF_STATUS csr_neighbor_roam_candidate_found_ind_hdlr(
+		tpAniSirGlobal pMac, void *pMsg)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+static inline QDF_STATUS csr_neighbor_roam_process_scan_complete(
+		tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+static inline void csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+		tpAniSirGlobal pMac, uint8_t sessionId)
+{}
+static inline void csr_neighbor_roam_free_roamable_bss_list(
+		tpAniSirGlobal mac_ctx, tDblLinkList *llist)
+{}
+static inline void csr_neighbor_roam_request_handoff(tpAniSirGlobal pMac,
+		uint8_t sessionId)
+{}
+static inline void csr_neighbor_roam_reset_preauth_control_info(
+		tpAniSirGlobal mac_ctx, uint8_t session_id)
+{}
+static inline void csr_neighbor_roam_purge_preauth_failed_list(
+		tpAniSirGlobal pMac)
+{}
+static inline bool csr_neighbor_roam_get_handoff_ap_info(tpAniSirGlobal pMac,
+		tpCsrNeighborRoamBSSInfo pHandoffNode, uint8_t sessionId)
+{
+	return false;
+}
+static inline bool csr_neighbor_roam_is_handoff_in_progress(tpAniSirGlobal pMac,
+		uint8_t sessionId)
+{
+	return false;
+}
+#endif
+bool csr_neighbor_middle_of_roaming(tpAniSirGlobal pMac, uint8_t sessionId);
+QDF_STATUS csr_neighbor_roam_update_config(tpAniSirGlobal mac_ctx,
+		uint8_t session_id, uint8_t value, uint8_t reason);
+QDF_STATUS csr_neighbor_roam_update_fast_roaming_enabled(tpAniSirGlobal pMac,
+		uint8_t sessionId, const bool fastRoamEnabled);
+QDF_STATUS csr_neighbor_roam_channels_filter_by_current_band(
+		tpAniSirGlobal pMac, uint8_t sessionId,
+		uint8_t *pInputChannelList,
+		uint8_t inputNumOfChannels,
+		uint8_t *pOutputChannelList,
+		uint8_t *pMergedOutputNumOfChannels);
+QDF_STATUS csr_neighbor_roam_merge_channel_lists(tpAniSirGlobal pMac,
+		uint8_t *pInputChannelList,
+		uint8_t inputNumOfChannels,
+		uint8_t *pOutputChannelList,
+		uint8_t outputNumOfChannels,
+		uint8_t *pMergedOutputNumOfChannels);
+void csr_roam_reset_roam_params(tpAniSirGlobal mac_ptr);
+#define ROAM_SCAN_OFFLOAD_START                     1
+#define ROAM_SCAN_OFFLOAD_STOP                      2
+#define ROAM_SCAN_OFFLOAD_RESTART                   3
+#define ROAM_SCAN_OFFLOAD_UPDATE_CFG                4
+#define ROAM_SCAN_OFFLOAD_ABORT_SCAN                5
+
+#define REASON_CONNECT                              1
+#define REASON_CHANNEL_LIST_CHANGED                 2
+#define REASON_LOOKUP_THRESH_CHANGED                3
+#define REASON_DISCONNECTED                         4
+#define REASON_RSSI_DIFF_CHANGED                    5
+#define REASON_ESE_INI_CFG_CHANGED                  6
+#define REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED 7
+#define REASON_VALID_CHANNEL_LIST_CHANGED           8
+#define REASON_FLUSH_CHANNEL_LIST                   9
+#define REASON_EMPTY_SCAN_REF_PERIOD_CHANGED        10
+#define REASON_PREAUTH_FAILED_FOR_ALL               11
+#define REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW     12
+#define REASON_NPROBES_CHANGED                      13
+#define REASON_HOME_AWAY_TIME_CHANGED               14
+#define REASON_OS_REQUESTED_ROAMING_NOW             15
+#define REASON_SCAN_CH_TIME_CHANGED                 16
+#define REASON_SCAN_HOME_TIME_CHANGED               17
+#define REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED    18
+#define REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED        19
+#define REASON_ROAM_BMISS_FIRST_BCNT_CHANGED        20
+#define REASON_ROAM_BMISS_FINAL_BCNT_CHANGED        21
+#define REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED      22
+#define REASON_ROAM_DFS_SCAN_MODE_CHANGED           23
+#define REASON_ROAM_ABORT_ROAM_SCAN                 24
+#define REASON_ROAM_EXT_SCAN_PARAMS_CHANGED         25
+#define REASON_ROAM_SET_SSID_ALLOWED                26
+#define REASON_ROAM_SET_FAVORED_BSSID               27
+#define REASON_ROAM_GOOD_RSSI_CHANGED               28
+#define REASON_ROAM_SET_BLACKLIST_BSSID             29
+#define REASON_ROAM_SCAN_HI_RSSI_MAXCOUNT_CHANGED   30
+#define REASON_ROAM_SCAN_HI_RSSI_DELTA_CHANGED      31
+#define REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED      32
+#define REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED         33
+#define REASON_CONNECT_IES_CHANGED                  34
+#define REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED    35
+#define REASON_ROAM_SYNCH_FAILED                    36
+#define REASON_ROAM_PSK_PMK_CHANGED                 37
+#define REASON_ROAM_STOP_ALL                        38
+#define REASON_SUPPLICANT_DISABLED_ROAMING          39
+#define REASON_CTX_INIT                             40
+#define REASON_FILS_PARAMS_CHANGED                  41
+#define REASON_SME_ISSUED                           42
+#define REASON_DRIVER_ENABLED                       43
+
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+QDF_STATUS csr_roam_offload_scan(tpAniSirGlobal pMac, uint8_t sessionId,
+		uint8_t command, uint8_t reason);
+#else
+static inline QDF_STATUS csr_roam_offload_scan(tpAniSirGlobal pMac,
+		uint8_t sessionId, uint8_t command, uint8_t reason)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+
+/**
+ * csr_get_roam_enabled_sta_sessionid() - get the session id of the sta on which
+ * roaming is enabled.
+ * @mac_ctx:  pointer to global mac structure
+ *
+ * The function check if any sta is present and has roaming enabled and return
+ * the session id of the sta with roaming enabled else if roaming is not enabled
+ * on any STA return CSR_SESSION_ID_INVALID
+ *
+ * Return: session id of STA on which roaming is enabled
+ */
+uint8_t csr_get_roam_enabled_sta_sessionid(
+	tpAniSirGlobal mac_ctx);
+
+#if defined(WLAN_FEATURE_FILS_SK)
+/**
+ * csr_update_fils_config - Update FILS config to CSR roam session
+ * @mac: MAC context
+ * @session_id: session id
+ * @src_profile: Source profile having latest FILS config
+ *
+ * API to update FILS config to roam csr session
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS csr_update_fils_config(tpAniSirGlobal mac, uint8_t session_id,
+				  struct csr_roam_profile *src_profile);
+#endif
+
+QDF_STATUS csr_neighbor_roam_handoff_req_hdlr(tpAniSirGlobal pMac, void *pMsg);
+QDF_STATUS csr_neighbor_roam_proceed_with_handoff_req(tpAniSirGlobal pMac,
+		uint8_t sessionId);
+QDF_STATUS csr_neighbor_roam_sssid_scan_done(tpAniSirGlobal pMac,
+		uint8_t sessionId, QDF_STATUS status);
+QDF_STATUS csr_neighbor_roam_start_lfr_scan(tpAniSirGlobal pMac,
+		uint8_t sessionId);
+
+#ifdef FEATURE_WLAN_ESE
+QDF_STATUS csr_set_cckm_ie(tpAniSirGlobal pMac, const uint8_t sessionId,
+		const uint8_t *pCckmIe, const uint8_t ccKmIeLen);
+QDF_STATUS csr_roam_read_tsf(tpAniSirGlobal pMac, uint8_t *pTimestamp,
+		const uint8_t sessionId);
+#endif /* FEATURE_WLAN_ESE */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS csr_roam_synch_callback(tpAniSirGlobal mac,
+	roam_offload_synch_ind *roam_synch_data,
+	tpSirBssDescription  bss_desc_ptr, enum sir_roam_op_code reason);
+#else
+static inline QDF_STATUS csr_roam_synch_callback(tpAniSirGlobal mac,
+	roam_offload_synch_ind *roam_synch_data,
+	tpSirBssDescription  bss_desc_ptr, enum sir_roam_op_code reason)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+void csr_neighbor_roam_state_transition(tpAniSirGlobal mac_ctx,
+		uint8_t newstate, uint8_t session);
+uint8_t *csr_neighbor_roam_state_to_string(uint8_t state);
+tpCsrNeighborRoamBSSInfo csr_neighbor_roam_next_roamable_ap(
+		tpAniSirGlobal mac_ctx, tDblLinkList *llist,
+		tpCsrNeighborRoamBSSInfo neighbor_entry);
+bool csr_neighbor_roam_remove_roamable_ap_list_entry(tpAniSirGlobal pMac,
+		tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry);
+void csr_neighbor_roam_free_neighbor_roam_bss_node(tpAniSirGlobal pMac,
+		tpCsrNeighborRoamBSSInfo neighborRoamBSSNode);
+QDF_STATUS csr_neighbor_roam_issue_preauth_req(tpAniSirGlobal pMac,
+		uint8_t sessionId);
+bool csr_neighbor_roam_is_preauth_candidate(tpAniSirGlobal pMac,
+		    uint8_t sessionId, tSirMacAddr bssId);
+#ifdef FEATURE_WLAN_LFR_METRICS
+void csr_neighbor_roam_send_lfr_metric_event(tpAniSirGlobal mac_ctx,
+		uint8_t session_id, tSirMacAddr bssid, eRoamCmdStatus status);
+#else
+static inline void csr_neighbor_roam_send_lfr_metric_event(
+		tpAniSirGlobal mac_ctx, uint8_t session_id,
+		tSirMacAddr bssid, eRoamCmdStatus status)
+{}
+#endif
+QDF_STATUS csr_roam_stop_wait_for_key_timer(tpAniSirGlobal pMac);
+QDF_STATUS csr_roam_copy_connected_profile(tpAniSirGlobal pMac,
+		uint32_t sessionId, struct csr_roam_profile *pDstProfile);
+
+/**
+ * csr_invoke_neighbor_report_request - Send neighbor report invoke command to
+ *					WMA
+ * @mac_ctx: MAC context
+ * @session_id: session id
+ *
+ * API called from IW to invoke neighbor report request to WMA then to FW
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS csr_invoke_neighbor_report_request(uint8_t session_id,
+				struct sRrmNeighborReq *neighbor_report_req,
+				bool send_resp_to_host);
+
+#endif /* CSR_NEIGHBOR_ROAM_H */
diff --git a/core/sme/inc/csr_support.h b/core/sme/inc/csr_support.h
new file mode 100644
index 0000000..a076aa1
--- /dev/null
+++ b/core/sme/inc/csr_support.h
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+/**
+ * \file csr_support.h
+ *
+ * Exports and types for the Common Scan and Roaming supporting interfaces.
+ */
+#ifndef CSR_SUPPORT_H__
+#define CSR_SUPPORT_H__
+
+#include "csr_link_list.h"
+#include "csr_api.h"
+#include "cds_reg_service.h"
+
+#ifdef FEATURE_WLAN_WAPI
+#define CSR_WAPI_OUI_SIZE              (4)
+#define CSR_WAPI_VERSION_SUPPORTED     (1)
+#define CSR_WAPI_MAX_AUTH_SUITES       (2)
+#define CSR_WAPI_MAX_CYPHERS           (5)
+#define CSR_WAPI_MAX_UNICAST_CYPHERS   (5)
+#define CSR_WAPI_MAX_MULTICAST_CYPHERS (1)
+#endif /* FEATURE_WLAN_WAPI */
+
+#define CSR_RSN_OUI_SIZE              (4)
+#define CSR_RSN_VERSION_SUPPORTED     (1)
+#define CSR_RSN_MAX_AUTH_SUITES       (4)
+#define CSR_RSN_MAX_CYPHERS           (5)
+#define CSR_RSN_MAX_UNICAST_CYPHERS   (5)
+#define CSR_RSN_MAX_MULTICAST_CYPHERS (1)
+
+#define CSR_WPA_OUI_SIZE              (4)
+#define CSR_WPA_VERSION_SUPPORTED     (1)
+#define CSR_WME_OUI_SIZE (4)
+#define CSR_WPA_MAX_AUTH_SUITES       (2)
+#define CSR_WPA_MAX_CYPHERS           (5)
+#define CSR_WPA_MAX_UNICAST_CYPHERS   (5)
+#define CSR_WPA_MAX_MULTICAST_CYPHERS (1)
+/* minimum size of the IE->length is the size of the Oui + Version. */
+#define CSR_WPA_IE_MIN_SIZE           (6)
+#define CSR_WPA_IE_MIN_SIZE_W_MULTICAST (HDD_WPA_IE_MIN_SIZE + HDD_WPA_OUI_SIZE)
+#define CSR_WPA_IE_MIN_SIZE_W_UNICAST   (HDD_WPA_IE_MIN_SIZE + \
+		HDD_WPA_OUI_SIZE + sizeof(pWpaIe->cUnicastCyphers))
+
+#define CSR_DOT11_SUPPORTED_RATES_MAX (12)
+#define CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX (8)
+
+#define CSR_DOT11_BASIC_RATE_MASK (0x80)
+
+/* NOTE these index are use as array index for csr_rsn_oui */
+#define CSR_OUI_USE_GROUP_CIPHER_INDEX 0x00
+#define CSR_OUI_WEP40_OR_1X_INDEX      0x01
+#define CSR_OUI_TKIP_OR_PSK_INDEX      0x02
+#define CSR_OUI_RESERVED_INDEX         0x03
+#define CSR_OUI_AES_INDEX              0x04
+#define CSR_OUI_WEP104_INDEX           0x05
+/* ENUM_FILS_SHA384 9 */
+/* ENUM_FILS_SHA384 10 */
+/* ENUM_FT_FILS_SHA256 11 */
+/* ENUM_FT_FILS_SHA384 12 */
+#define CSR_OUI_AES_GCMP_INDEX         0x0D
+#define CSR_OUI_AES_GCMP_256_INDEX     0x0E
+
+#ifdef FEATURE_WLAN_WAPI
+#define CSR_OUI_WAPI_RESERVED_INDEX    0x00
+#define CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX    0x01
+#define CSR_OUI_WAPI_WAI_PSK_INDEX     0x02
+/* max idx, should be last & highest */
+#define CSR_OUI_WAPI_WAI_MAX_INDEX     0x03
+#endif /* FEATURE_WLAN_WAPI */
+
+typedef enum {
+	/* 11b rates */
+	eCsrSuppRate_1Mbps   = 1 * 2,
+	eCsrSuppRate_2Mbps   = 2 * 2,
+	eCsrSuppRate_5_5Mbps = 11,      /* 5.5 * 2 */
+	eCsrSuppRate_11Mbps  = 11 * 2,
+
+	/* 11a / 11g rates */
+	eCsrSuppRate_6Mbps   = 6 * 2,
+	eCsrSuppRate_9Mbps   = 9 * 2,
+	eCsrSuppRate_12Mbps  = 12 * 2,
+	eCsrSuppRate_18Mbps  = 18 * 2,
+	eCsrSuppRate_24Mbps  = 24 * 2,
+	eCsrSuppRate_36Mbps  = 36 * 2,
+	eCsrSuppRate_48Mbps  = 48 * 2,
+	eCsrSuppRate_54Mbps  = 54 * 2,
+
+	/* airgo proprietary rates */
+	eCsrSuppRate_10Mbps   = 10 * 2,
+	eCsrSuppRate_10_5Mbps = 21,     /* 10.5 * 2 */
+	eCsrSuppRate_20Mbps   = 20 * 2,
+	eCsrSuppRate_21Mbps   = 21 * 2,
+	eCsrSuppRate_40Mbps   = 40 * 2,
+	eCsrSuppRate_42Mbps   = 42 * 2,
+	eCsrSuppRate_60Mbps   = 60 * 2,
+	eCsrSuppRate_63Mbps   = 63 * 2,
+	eCsrSuppRate_72Mbps   = 72 * 2,
+	eCsrSuppRate_80Mbps   = 80 * 2,
+	eCsrSuppRate_84Mbps   = 84 * 2,
+	eCsrSuppRate_96Mbps   = 96 * 2,
+	eCsrSuppRate_108Mbps  = 108 * 2,
+	eCsrSuppRate_120Mbps  = 120 * 2,
+	eCsrSuppRate_126Mbps  = 126 * 2,
+	eCsrSuppRate_144Mbps  = 144 * 2,
+	eCsrSuppRate_160Mbps  = 160 * 2,
+	eCsrSuppRate_168Mbps  = 168 * 2,
+	eCsrSuppRate_192Mbps  = 192 * 2,
+	eCsrSuppRate_216Mbps  = 216 * 2,
+	eCsrSuppRate_240Mbps  = 240 * 2
+} eCsrSupportedRates;
+
+/* Generic Information Element Structure */
+typedef struct sDot11IEHeader {
+	uint8_t ElementID;
+	uint8_t Length;
+} qdf_packed tDot11IEHeader;
+
+typedef struct tagCsrWpaIe {
+	tDot11IEHeader IeHeader;
+	uint8_t Oui[CSR_WPA_OUI_SIZE];
+	uint16_t Version;
+	uint8_t MulticastOui[CSR_WPA_OUI_SIZE];
+	uint16_t cUnicastCyphers;
+	struct {
+		uint8_t Oui[CSR_WPA_OUI_SIZE];
+	} qdf_packed UnicastOui[1];
+} qdf_packed tCsrWpaIe;
+
+typedef struct tagCsrWpaAuthIe {
+	uint16_t cAuthenticationSuites;
+	struct {
+		uint8_t Oui[CSR_WPA_OUI_SIZE];
+	} qdf_packed AuthOui[1];
+} qdf_packed tCsrWpaAuthIe;
+
+typedef struct tagCsrRSNIe {
+	tDot11IEHeader IeHeader;
+	uint16_t Version;
+	uint8_t MulticastOui[CSR_RSN_OUI_SIZE];
+	uint16_t cUnicastCyphers;
+	struct {
+		uint8_t Oui[CSR_RSN_OUI_SIZE];
+	} qdf_packed UnicastOui[1];
+} qdf_packed tCsrRSNIe;
+
+typedef struct tagCsrRSNAuthIe {
+	uint16_t cAuthenticationSuites;
+	struct {
+		uint8_t Oui[CSR_RSN_OUI_SIZE];
+	} qdf_packed AuthOui[1];
+} qdf_packed tCsrRSNAuthIe;
+
+typedef struct tagCsrRSNPMKIe {
+	uint16_t cPMKIDs;
+	struct {
+		uint8_t PMKID[CSR_RSN_PMKID_SIZE];
+	} qdf_packed PMKIDList[1];
+} qdf_packed tCsrRSNPMKIe;
+
+typedef struct tCsrIELenInfo {
+	uint8_t min;
+	uint8_t max;
+} qdf_packed tCsrIELenInfo;
+
+#ifdef FEATURE_WLAN_WAPI
+typedef struct tagCsrWapiIe {
+	tDot11IEHeader IeHeader;
+	uint16_t Version;
+	uint16_t cAuthenticationSuites;
+	struct {
+		uint8_t Oui[CSR_WAPI_OUI_SIZE];
+	} qdf_packed AuthOui[1];
+	uint16_t cUnicastCyphers;
+	struct {
+		uint8_t Oui[CSR_WAPI_OUI_SIZE];
+	} qdf_packed UnicastOui[1];
+	uint8_t MulticastOui[CSR_WAPI_OUI_SIZE];
+	struct {
+		uint16_t PreAuthSupported:1;
+		uint16_t Reserved:15;
+	} qdf_packed tCsrWapiCapabilities;
+} qdf_packed tCsrWapiIe;
+#endif /* FEATURE_WLAN_WAPI */
+
+typedef struct tagRoamingTimerInfo {
+	tpAniSirGlobal pMac;
+	uint8_t sessionId;
+} tCsrTimerInfo;
+
+#define CSR_IS_11A_BSS(pBssDesc)    (eSIR_11A_NW_TYPE == (pBssDesc)->nwType)
+#define CSR_IS_BASIC_RATE(rate)     ((rate) & CSR_DOT11_BASIC_RATE_MASK)
+#define CSR_IS_QOS_BSS(pIes)  \
+		((pIes)->WMMParams.present || (pIes)->WMMInfoAp.present)
+#define CSR_IS_UAPSD_BSS(pIes) \
+	(((pIes)->WMMParams.present && \
+	 ((pIes)->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD)) || \
+	 ((pIes)->WMMInfoAp.present && (pIes)->WMMInfoAp.uapsd))
+
+bool csr_get_bss_id_bss_desc(tSirBssDescription *pSirBssDesc,
+			     struct qdf_mac_addr *pBssId);
+bool csr_is_bss_id_equal(tSirBssDescription *pSirBssDesc1,
+			 tSirBssDescription *pSirBssDesc2);
+eCsrMediaAccessType csr_get_qos_from_bss_desc(tpAniSirGlobal mac_ctx,
+					      tSirBssDescription *pSirBssDesc,
+					      tDot11fBeaconIEs *pIes);
+bool csr_is_nullssid(uint8_t *pBssSsid, uint8_t len);
+bool csr_is_infra_bss_desc(tSirBssDescription *pSirBssDesc);
+bool csr_is_ibss_bss_desc(tSirBssDescription *pSirBssDesc);
+bool csr_is_privacy(tSirBssDescription *pSirBssDesc);
+tSirResultCodes csr_get_disassoc_rsp_status_code(tSirSmeDisassocRsp *
+		pSmeDisassocRsp);
+tSirResultCodes csr_get_de_auth_rsp_status_code(tSirSmeDeauthRsp *pSmeRsp);
+uint32_t csr_get_frag_thresh(tpAniSirGlobal mac_ctx);
+uint32_t csr_get_rts_thresh(tpAniSirGlobal mac_ctx);
+eCsrPhyMode csr_get_phy_mode_from_bssDesc(tSirBssDescription *pSirBssDesc);
+uint32_t csr_get11h_power_constraint(tpAniSirGlobal mac_ctx,
+				     tDot11fIEPowerConstraints *constraints);
+uint8_t csr_construct_rsn_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+			     struct csr_roam_profile *pProfile,
+			     tSirBssDescription *pSirBssDesc,
+			     tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe);
+
+uint8_t csr_construct_wpa_ie(tpAniSirGlobal pMac,
+			     struct csr_roam_profile *pProfile,
+			     tSirBssDescription *pSirBssDesc,
+			     tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe);
+
+#ifdef FEATURE_WLAN_WAPI
+bool csr_is_profile_wapi(struct csr_roam_profile *pProfile);
+#endif /* FEATURE_WLAN_WAPI */
+/*
+ * If a WPAIE exists in the profile, just use it.
+ * Or else construct one from the BSS Caller allocated memory for pWpaIe and
+ * guarrantee it can contain a max length WPA IE
+ */
+uint8_t csr_retrieve_wpa_ie(tpAniSirGlobal pMac,
+			    struct csr_roam_profile *pProfile,
+			    tSirBssDescription *pSirBssDesc,
+			    tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe);
+
+bool csr_is_ssid_equal(tpAniSirGlobal pMac,
+		       tSirBssDescription *pSirBssDesc1,
+		       tSirBssDescription *pSirBssDesc2,
+		       tDot11fBeaconIEs *pIes2);
+
+/* Null ssid means match */
+bool csr_is_ssid_in_list(tSirMacSSid *pSsid, tCsrSSIDs *pSsidList);
+bool csr_is_profile_wpa(struct csr_roam_profile *pProfile);
+bool csr_is_profile_rsn(struct csr_roam_profile *pProfile);
+/*
+ * If a RSNIE exists in the profile, just use it. Or
+ * else construct one from the BSS Caller allocated memory for pWpaIe and
+ * guarantee it can contain a max length WPA IE
+ */
+uint8_t csr_retrieve_rsn_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+			    struct csr_roam_profile *pProfile,
+			    tSirBssDescription *pSirBssDesc,
+			    tDot11fBeaconIEs *pIes, tCsrRSNIe *pRsnIe);
+#ifdef FEATURE_WLAN_WAPI
+/*
+ * If a WAPI IE exists in the profile, just use it.
+ * Or else construct one from the BSS. Caller allocated memory for pWapiIe and
+ * guarrantee it can contain a max length WAPI IE
+ */
+uint8_t csr_retrieve_wapi_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+			     struct csr_roam_profile *pProfile,
+			     tSirBssDescription *pSirBssDesc,
+			     tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe);
+#endif /* FEATURE_WLAN_WAPI */
+bool csr_rates_is_dot11_rate11b_supported_rate(uint8_t dot11Rate);
+bool csr_rates_is_dot11_rate11a_supported_rate(uint8_t dot11Rate);
+tAniEdType csr_translate_encrypt_type_to_ed_type(
+		eCsrEncryptionType EncryptType);
+/*
+ * pIes shall contain IEs from pSirBssDesc.
+ * It shall be returned from function csr_get_parsed_bss_description_ies
+ */
+bool csr_is_security_match(tpAniSirGlobal mac_ctx, tCsrAuthList *authType,
+		tCsrEncryptionList *pUCEncryptionType,
+		tCsrEncryptionList *pMCEncryptionType, bool *pMFPEnabled,
+		uint8_t *pMFPRequired, uint8_t *pMFPCapable,
+		tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes,
+		eCsrAuthType *negotiatedAuthtype,
+		eCsrEncryptionType *negotiatedUCCipher,
+		eCsrEncryptionType *negotiatedMCCipher);
+bool csr_is_bss_type_match(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2);
+bool csr_is_bss_type_ibss(eCsrRoamBssType bssType);
+bool csr_is_bssid_match(struct qdf_mac_addr *pProfBssid,
+			struct qdf_mac_addr *BssBssid);
+void csr_add_rate_bitmap(uint8_t rate, uint16_t *pRateBitmap);
+bool csr_check_rate_bitmap(uint8_t rate, uint16_t RateBitmap);
+bool csr_rates_is_dot11_rate_supported(tpAniSirGlobal mac_ctx, uint8_t rate);
+uint16_t csr_rates_find_best_rate(tSirMacRateSet *pSuppRates,
+		tSirMacRateSet *pExtRates, tSirMacPropRateSet *pPropRates);
+tSirBssType csr_translate_bsstype_to_mac_type(eCsrRoamBssType csrtype);
+/* Caller allocates memory for pIEStruct */
+QDF_STATUS csr_parse_bss_description_ies(tpAniSirGlobal mac_ctx,
+					 tSirBssDescription *pBssDesc,
+					 tDot11fBeaconIEs *pIEStruct);
+/*
+ * This function will allocate memory for the parsed IEs to the caller.
+ * Caller must free the memory. after it is done with the data only if
+ * this function succeeds
+ */
+QDF_STATUS csr_get_parsed_bss_description_ies(tpAniSirGlobal mac_ctx,
+					      tSirBssDescription *pBssDesc,
+					      tDot11fBeaconIEs **ppIEStruct);
+
+tSirScanType csr_get_scan_type(tpAniSirGlobal pMac, uint8_t chnId);
+uint8_t csr_to_upper(uint8_t ch);
+QDF_STATUS csr_get_phy_mode_from_bss(tpAniSirGlobal pMac,
+		tSirBssDescription *pBSSDescription,
+		eCsrPhyMode *pPhyMode, tDot11fBeaconIEs *pIes);
+/*
+ * fForce -- force reassoc regardless of whether there is any change.
+ * The reason is that for UAPSD-bypass, the code underneath this call determine
+ * whether to allow UAPSD. The information in pModProfileFields reflects what
+ * the user wants. There may be discrepency in it. UAPSD-bypass logic should
+ * decide if it needs to reassoc
+ */
+QDF_STATUS csr_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
+		tCsrRoamModifyProfileFields *pModProfileFields,
+		uint32_t *pRoamId, bool fForce);
+
+/* BeaconInterval validation for MCC support */
+QDF_STATUS csr_validate_mcc_beacon_interval(tpAniSirGlobal pMac, uint8_t channelId,
+		uint16_t *beaconInterval, uint32_t cursessionId,
+		enum QDF_OPMODE currBssPersona);
+bool csr_is_profile11r(tpAniSirGlobal mac, struct csr_roam_profile *pProfile);
+bool csr_is_auth_type11r(tpAniSirGlobal mac, eCsrAuthType AuthType,
+			 uint8_t mdiePresent);
+#ifdef FEATURE_WLAN_ESE
+bool csr_is_profile_ese(struct csr_roam_profile *pProfile);
+#endif
+
+/**
+ * csr_is_auth_type_ese() - Checks whether Auth type is ESE or not
+ * @AuthType: Authentication type
+ *
+ * Return: true, if auth type is ese, false otherwise
+ */
+bool csr_is_auth_type_ese(eCsrAuthType AuthType);
+
+#endif
diff --git a/core/sme/inc/nan_api.h b/core/sme/inc/nan_api.h
new file mode 100644
index 0000000..5abba03
--- /dev/null
+++ b/core/sme/inc/nan_api.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014-2016, 2018 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.
+ */
+
+/**
+ *
+ * Name:  nan_api.h
+ *
+ * Description: NAN FSM defines.
+ *
+ */
+
+#ifndef __NAN_API_H__
+#define __NAN_API_H__
+
+#include "qdf_types.h"
+#include "sir_types.h"
+
+typedef void (*nan_callback)(hdd_handle_t hdd_handle, tSirNanEvent *event);
+
+#ifdef WLAN_FEATURE_NAN
+typedef struct sNanRequestReq {
+	uint16_t request_data_len;
+	const uint8_t *request_data;
+} tNanRequestReq, *tpNanRequestReq;
+
+/**
+ * sme_nan_register_callback() - Register NAN Callback function
+ * @mac_handle: Opaque handle to the MAC context
+ * @callback: Callback function to be registered
+ *
+ * Function to be called by HDD to register the NAN Response callback
+ * function with the sme layer.
+ *
+ * Return: void
+ */
+void sme_nan_register_callback(mac_handle_t mac_handle, nan_callback callback);
+
+/**
+ * sme_nan_deregister_callback() - NAN De-register cb function
+ * @mac_handle: Opaque handle to the MAC context
+ *
+ * Function to be called by HDD to deregister the NAN Response
+ * callback function with the sme layer.
+ *
+ * Return: void
+ */
+void sme_nan_deregister_callback(mac_handle_t mac_handle);
+
+/**
+ * sme_nan_request() - Process a NAN request
+ * @input: Nan Request structure ptr
+ *
+ * This function gets called when HDD receives NAN vendor command
+ * from userspace
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_nan_request(tpNanRequestReq input);
+
+/**
+ * sme_nan_event() - Process a NAN event
+ * @mac_handle: Opaque handle to the MAC context
+ * @event: NAN event received from firmware
+ *
+ * This callback function will be called when SME received eWNI_SME_NAN_EVENT
+ * event from WMA
+ *
+ * Return: void
+ */
+void sme_nan_event(mac_handle_t mac_handle, tSirNanEvent *event);
+
+#else /* WLAN_FEATURE_NAN */
+
+static inline void sme_nan_register_callback(mac_handle_t mac_handle,
+					     nan_callback callback)
+{
+}
+
+static inline void sme_nan_deregister_callback(mac_handle_t mac_handle)
+{
+}
+
+#endif /* WLAN_FEATURE_NAN */
+
+#endif /* __NAN_API_H__ */
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
new file mode 100644
index 0000000..118aae2
--- /dev/null
+++ b/core/sme/inc/sme_api.h
@@ -0,0 +1,2952 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#if !defined(__SME_API_H)
+#define __SME_API_H
+
+/**
+ * file  smeApi.h
+ *
+ * brief prototype for SME APIs
+ */
+
+/*--------------------------------------------------------------------------
+  Include Files
+  ------------------------------------------------------------------------*/
+#include "csr_api.h"
+#include "qdf_lock.h"
+#include "qdf_types.h"
+#include "sir_api.h"
+#include "cds_regdomain.h"
+#include "sme_internal.h"
+#include "wma_tgt_cfg.h"
+#include "wma_fips_public_structs.h"
+#include "wma_sar_public_structs.h"
+
+#include "sme_rrm_internal.h"
+#include "sir_types.h"
+#include "scheduler_api.h"
+#include "wlan_serialization_legacy_api.h"
+
+/*--------------------------------------------------------------------------
+  Preprocessor definitions and constants
+  ------------------------------------------------------------------------*/
+
+#define SME_SUMMARY_STATS         (1 << eCsrSummaryStats)
+#define SME_GLOBAL_CLASSA_STATS   (1 << eCsrGlobalClassAStats)
+#define SME_GLOBAL_CLASSD_STATS   (1 << eCsrGlobalClassDStats)
+#define SME_PER_CHAIN_RSSI_STATS  (1 << csr_per_chain_rssi_stats)
+
+#define sme_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_SME, params)
+#define sme_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_SME, params)
+#define sme_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_SME, params)
+#define sme_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_SME, params)
+#define sme_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_SME, params)
+
+#define sme_nofl_alert(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_SME, params)
+#define sme_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_SME, params)
+#define sme_nofl_warn(params...) \
+	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_SME, params)
+#define sme_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_SME, params)
+#define sme_nofl_debug(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_SME, params)
+
+#define sme_alert_rl(params...) QDF_TRACE_FATAL_RL(QDF_MODULE_ID_SME, params)
+#define sme_err_rl(params...) QDF_TRACE_ERROR_RL(QDF_MODULE_ID_SME, params)
+#define sme_warn_rl(params...) QDF_TRACE_WARN_RL(QDF_MODULE_ID_SME, params)
+#define sme_info_rl(params...) QDF_TRACE_INFO_RL(QDF_MODULE_ID_SME, params)
+#define sme_debug_rl(params...) QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_SME, params)
+
+#define SME_ENTER() QDF_TRACE_ENTER(QDF_MODULE_ID_SME, "enter")
+#define SME_EXIT() QDF_TRACE_EXIT(QDF_MODULE_ID_SME, "exit")
+
+#define SME_SESSION_ID_ANY        50
+#define SME_SESSION_ID_BROADCAST  0xFF
+
+#define SME_INVALID_COUNTRY_CODE "XX"
+#define INVALID_ROAM_ID 0
+
+#define SME_SET_CHANNEL_REG_POWER(reg_info_1, val) do {	\
+	reg_info_1 &= 0xff00ffff;	      \
+	reg_info_1 |= ((val & 0xff) << 16);   \
+} while (0)
+
+#define SME_SET_CHANNEL_MAX_TX_POWER(reg_info_2, val) do { \
+	reg_info_2 &= 0xffff00ff;	      \
+	reg_info_2 |= ((val & 0xff) << 8);   \
+} while (0)
+
+#define SME_CONFIG_TO_ROAM_CONFIG 1
+#define ROAM_CONFIG_TO_SME_CONFIG 2
+
+#define NUM_OF_BANDS 2
+
+#define SME_ACTIVE_LIST_CMD_TIMEOUT_VALUE (30*1000)
+#define SME_CMD_TIMEOUT_VALUE (SME_ACTIVE_LIST_CMD_TIMEOUT_VALUE + 1000)
+
+/* SME timeout for Start/Stop BSS commands is set to 10 secs */
+#define SME_START_STOP_BSS_CMD_TIMEOUT (10 * 1000)
+#define SME_CMD_START_STOP_BSS_TIMEOUT (SME_START_STOP_BSS_CMD_TIMEOUT + 1000)
+
+/* SME timeout for vdev delete is set to 10 secs */
+#define SME_VDEV_DELETE_CMD_TIMEOUT (10 * 1000)
+#define SME_CMD_VDEV_CREATE_DELETE_TIMEOUT (SME_VDEV_DELETE_CMD_TIMEOUT + 1000)
+
+/*--------------------------------------------------------------------------
+  Type declarations
+  ------------------------------------------------------------------------*/
+typedef struct _smeConfigParams {
+	tCsrConfigParam csrConfig;
+	struct rrm_config_param rrmConfig;
+	bool snr_monitor_enabled;
+} tSmeConfigParams, *tpSmeConfigParams;
+
+#ifdef FEATURE_WLAN_TDLS
+#define SME_TDLS_MAX_SUPP_CHANNELS       128
+#define SME_TDLS_MAX_SUPP_OPER_CLASSES   32
+
+typedef struct _smeTdlsPeerCapParams {
+	uint8_t isPeerResponder;
+	uint8_t peerUapsdQueue;
+	uint8_t peerMaxSp;
+	uint8_t peerBuffStaSupport;
+	uint8_t peerOffChanSupport;
+	uint8_t peerCurrOperClass;
+	uint8_t selfCurrOperClass;
+	uint8_t peerChanLen;
+	uint8_t peerChan[SME_TDLS_MAX_SUPP_CHANNELS];
+	uint8_t peerOperClassLen;
+	uint8_t peerOperClass[SME_TDLS_MAX_SUPP_OPER_CLASSES];
+	uint8_t prefOffChanNum;
+	uint8_t prefOffChanBandwidth;
+	uint8_t opClassForPrefOffChan;
+} tSmeTdlsPeerCapParams;
+
+/**
+ * eSmeTdlsPeerState - tdls peer state
+ * @eSME_TDLS_PEER_STATE_PEERING: tdls connection in progress
+ * @eSME_TDLS_PEER_STATE_CONNECTED: tdls peer is connected
+ * @eSME_TDLS_PEER_STATE_TEARDOWN: tdls peer is tear down
+ * @eSME_TDLS_PEER_ADD_MAC_ADDR: add peer mac into connection table
+ * @eSME_TDLS_PEER_REMOVE_MAC_ADDR: remove peer mac from connection table
+ */
+typedef enum {
+	eSME_TDLS_PEER_STATE_PEERING,
+	eSME_TDLS_PEER_STATE_CONNECTED,
+	eSME_TDLS_PEER_STATE_TEARDOWN,
+	eSME_TDLS_PEER_ADD_MAC_ADDR,
+	eSME_TDLS_PEER_REMOVE_MAC_ADDR,
+} eSmeTdlsPeerState;
+
+typedef struct _smeTdlsPeerStateParams {
+	uint32_t vdevId;
+	tSirMacAddr peerMacAddr;
+	uint32_t peerState;
+	tSmeTdlsPeerCapParams peerCap;
+} tSmeTdlsPeerStateParams;
+
+#define ENABLE_CHANSWITCH  1
+#define DISABLE_CHANSWITCH 2
+#define BW_20_OFFSET_BIT   0
+#define BW_40_OFFSET_BIT   1
+#define BW_80_OFFSET_BIT   2
+#define BW_160_OFFSET_BIT  3
+typedef struct sme_tdls_chan_switch_param_struct {
+	uint32_t vdev_id;
+	tSirMacAddr peer_mac_addr;
+	uint16_t tdls_off_ch_bw_offset;/* Target Off Channel Bandwidth offset */
+	uint8_t tdls_off_channel;      /* Target Off Channel */
+	uint8_t tdls_off_ch_mode;      /* TDLS Off Channel Mode */
+	uint8_t is_responder;          /* is peer responder or initiator */
+	uint8_t opclass;           /* tdls operating class */
+} sme_tdls_chan_switch_params;
+#endif /* FEATURE_WLAN_TDLS */
+
+/* Thermal Mitigation*/
+typedef struct {
+	uint16_t smeMinTempThreshold;
+	uint16_t smeMaxTempThreshold;
+} tSmeThermalLevelInfo;
+
+#define SME_MAX_THERMAL_LEVELS (4)
+#define SME_MAX_THROTTLE_LEVELS (4)
+
+typedef struct {
+	/* Array of thermal levels */
+	tSmeThermalLevelInfo smeThermalLevels[SME_MAX_THERMAL_LEVELS];
+	uint8_t smeThermalMgmtEnabled;
+	uint32_t smeThrottlePeriod;
+	uint8_t sme_throttle_duty_cycle_tbl[SME_MAX_THROTTLE_LEVELS];
+} tSmeThermalParams;
+
+typedef enum {
+	SME_AC_BK = 0,
+	SME_AC_BE = 1,
+	SME_AC_VI = 2,
+	SME_AC_VO = 3
+} sme_ac_enum_type;
+
+/*
+ * Enumeration of the various TSPEC directions
+ * From 802.11e/WMM specifications
+ */
+enum sme_qos_wmm_dir_type {
+	SME_QOS_WMM_TS_DIR_UPLINK = 0,
+	SME_QOS_WMM_TS_DIR_DOWNLINK = 1,
+	SME_QOS_WMM_TS_DIR_RESV = 2,    /* Reserved */
+	SME_QOS_WMM_TS_DIR_BOTH = 3,
+};
+
+/**
+ * struct sme_oem_capability - OEM capability to be exchanged between host
+ *                             and userspace
+ * @ftm_rr: FTM range report capability bit
+ * @lci_capability: LCI capability bit
+ * @reserved1: reserved
+ * @reserved2: reserved
+ */
+struct sme_oem_capability {
+	uint32_t ftm_rr:1;
+	uint32_t lci_capability:1;
+	uint32_t reserved1:30;
+	uint32_t reserved2;
+};
+
+/**
+ * struct sme_5g_pref_params : 5G preference params to be read from ini
+ * @rssi_boost_threshold_5g: RSSI threshold above which 5 GHz is favored
+ * @rssi_boost_factor_5g: Factor by which 5GHz RSSI is boosted
+ * @max_rssi_boost_5g: Maximum boost that can be applied to 5GHz RSSI
+ * @rssi_penalize_threshold_5g: RSSI threshold below which 5G is not favored
+ * @rssi_penalize_factor_5g: Factor by which 5GHz RSSI is penalized
+ * @max_rssi_penalize_5g: Maximum penalty that can be applied to 5G RSSI
+ */
+struct sme_5g_band_pref_params {
+	int8_t      rssi_boost_threshold_5g;
+	uint8_t     rssi_boost_factor_5g;
+	uint8_t     max_rssi_boost_5g;
+	int8_t      rssi_penalize_threshold_5g;
+	uint8_t     rssi_penalize_factor_5g;
+	uint8_t     max_rssi_penalize_5g;
+};
+
+/**
+ * struct sme_session_params: Session creation params passed by HDD layer
+ * @session_open_cb: callback to be registered with SME for opening the session
+ * @session_close_cb: callback to be registered with SME for closing the session
+ * @callback: callback to be invoked for roaming events
+ * @callback_ctx: user-supplied context to be passed back on roaming events
+ * @self_mac_addr: Self mac address
+ * @sme_session_id: SME session id
+ * @type_of_persona: person type
+ * @subtype_of_persona: sub type of persona
+ */
+struct sme_session_params {
+	csr_session_open_cb  session_open_cb;
+	csr_session_close_cb session_close_cb;
+	csr_roam_complete_cb callback;
+	void *callback_ctx;
+	uint8_t *self_mac_addr;
+	uint8_t sme_session_id;
+	uint32_t type_of_persona;
+	uint32_t subtype_of_persona;
+};
+
+#define MAX_CANDIDATE_INFO 10
+
+/**
+ * struct bss_candidate_info - Candidate bss information
+ *
+ * @bssid : BSSID of candidate bss
+ * @status : status code for candidate bss
+ */
+struct bss_candidate_info {
+	struct qdf_mac_addr bssid;
+	uint32_t status;
+};
+
+/*
+ * MBO transition reason codes
+ */
+enum {
+	MBO_TRANSITION_REASON_UNSPECIFIED,
+	MBO_TRANSITION_REASON_EXCESSIVE_FRAME_LOSS_RATE,
+	MBO_TRANSITION_REASON_EXCESSIVE_DELAY_FOR_CURRENT_TRAFFIC,
+	MBO_TRANSITION_REASON_INSUFFICIENT_BANDWIDTH_FOR_CURRENT_TRAFFIC,
+	MBO_TRANSITION_REASON_LOAD_BALANCING,
+	MBO_TRANSITION_REASON_LOW_RSSI,
+	MBO_TRANSITION_REASON_RECEIVED_EXCESSIVE_RETRANSMISSIONS,
+	MBO_TRANSITION_REASON_HIGH_INTERFERENCE,
+	MBO_TRANSITION_REASON_GRAY_ZONE,
+	MBO_TRANSITION_REASON_TRANSITIONING_TO_PREMIUM_AP,
+};
+
+/*-------------------------------------------------------------------------
+  Function declarations and documenation
+  ------------------------------------------------------------------------*/
+QDF_STATUS sme_open(tHalHandle hHal);
+QDF_STATUS sme_init_chan_list(tHalHandle hal, uint8_t *alpha2,
+		enum country_src cc_src);
+QDF_STATUS sme_close(tHalHandle hHal);
+QDF_STATUS sme_start(tHalHandle hHal);
+
+/**
+ * sme_stop() - Stop all SME modules and put them at idle state
+ * @mac_handle: Opaque handle to the MAC context
+ *
+ * The function stops each module in SME. Upon return, all modules are
+ * at idle state ready to start.
+ *
+ * This is a synchronous call
+ *
+ * Return: QDF_STATUS_SUCCESS if SME is stopped.  Other status means
+ *         SME failed to stop one or more modules but caller should
+ *         still consider SME is stopped.
+ */
+QDF_STATUS sme_stop(mac_handle_t mac_handle);
+
+/*
+ * sme_open_session() - Open a session for given persona
+ *
+ * This is a synchronous API. For any protocol stack related activity
+ * requires session to be opened. This API needs to be called to open
+ * the session in SME module.
+ *
+ * hal: The handle returned by mac_open.
+ * params: to initialize the session open params
+ *
+ * Return:
+ * QDF_STATUS_SUCCESS - session is opened.
+ * Other status means SME is failed to open the session.
+ */
+QDF_STATUS sme_open_session(tHalHandle hal, struct sme_session_params *params);
+
+/*
+ * sme_close_session() - Close a session for given persona
+ *
+ * This is a synchronous API. This API needs to be called to close the session
+ * in SME module before terminating the session completely.
+ *
+ * hal: The handle returned by mac_open.
+ * session_id: A previous opened session's ID.
+ *
+ * Return:
+ * QDF_STATUS_SUCCESS - session is closed.
+ * Other status means SME is failed to open the session.
+ */
+QDF_STATUS sme_close_session(tHalHandle hal, uint8_t sessionId);
+void sme_set_curr_device_mode(tHalHandle hHal,
+		enum QDF_OPMODE currDeviceMode);
+QDF_STATUS sme_update_roam_params(tHalHandle hHal, uint8_t session_id,
+		struct roam_ext_params *roam_params_src, int update_param);
+QDF_STATUS sme_update_config(tHalHandle hHal,
+		tpSmeConfigParams pSmeConfigParams);
+
+QDF_STATUS sme_set11dinfo(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams);
+QDF_STATUS sme_get_soft_ap_domain(tHalHandle hHal,
+		v_REGDOMAIN_t *domainIdSoftAp);
+QDF_STATUS sme_hdd_ready_ind(tHalHandle hHal);
+/**
+ * sme_ser_cmd_callback() - callback from serialization module
+ * @buf: serialization command buffer
+ * @reason: reason why serialization module has given this callback
+ *
+ * Serialization module will give callback to SME for why it triggered
+ * the callback
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS sme_ser_cmd_callback(void *buf,
+				enum wlan_serialization_cb_reason reason);
+
+/*
+ * sme_process_msg() - The main message processor for SME.
+ * @mac: The global mac context
+ * @msg: The message to be processed.
+ *
+ * This function is called by a message dispatcher when to process a message
+ * targeted for SME.
+ * This is a synchronous call
+ *
+ * Return: QDF_STATUS_SUCCESS - SME successfully processed the message.
+ * Other status means SME failed to process the message to HAL.
+ */
+QDF_STATUS sme_process_msg(tpAniSirGlobal pMac, struct scheduler_msg *pMsg);
+
+QDF_STATUS sme_mc_process_handler(struct scheduler_msg *msg);
+QDF_STATUS sme_scan_get_result(tHalHandle hHal, uint8_t sessionId,
+		tCsrScanResultFilter *pFilter,
+		tScanResultHandle *phResult);
+QDF_STATUS sme_get_ap_channel_from_scan_cache(
+		struct csr_roam_profile *profile,
+		tScanResultHandle *scan_cache,
+		uint8_t *ap_chnl_id);
+QDF_STATUS sme_get_ap_channel_from_scan(void *profile,
+		tScanResultHandle *scan_cache,
+		uint8_t *ap_chnl_id);
+bool sme_store_joinreq_param(tHalHandle hal_handle,
+		struct csr_roam_profile *profile,
+		tScanResultHandle scan_cache,
+		uint32_t *roam_id,
+		uint32_t session_id);
+bool sme_clear_joinreq_param(tHalHandle hal_handle,
+		uint32_t session_id);
+QDF_STATUS sme_issue_stored_joinreq(tHalHandle hal_handle,
+		uint32_t *roam_id,
+		uint32_t session_id);
+QDF_STATUS sme_scan_flush_result(tHalHandle hHal);
+QDF_STATUS sme_filter_scan_results(tHalHandle hHal, uint8_t sessionId);
+QDF_STATUS sme_scan_flush_p2p_result(tHalHandle hHal, uint8_t sessionId);
+tCsrScanResultInfo *sme_scan_result_get_first(tHalHandle,
+		tScanResultHandle hScanResult);
+tCsrScanResultInfo *sme_scan_result_get_next(tHalHandle,
+		tScanResultHandle hScanResult);
+QDF_STATUS sme_scan_result_purge(tScanResultHandle hScanResult);
+QDF_STATUS sme_roam_connect(tHalHandle hHal, uint8_t sessionId,
+		struct csr_roam_profile *pProfile, uint32_t *pRoamId);
+QDF_STATUS sme_roam_reassoc(tHalHandle hHal, uint8_t sessionId,
+		struct csr_roam_profile *pProfile,
+		tCsrRoamModifyProfileFields modProfileFields,
+		uint32_t *pRoamId, bool fForce);
+QDF_STATUS sme_roam_connect_to_last_profile(tHalHandle hHal, uint8_t sessionId);
+
+/**
+ * sme_roam_disconnect() - API to request CSR to disconnect
+ * @hal: HAL context
+ * @session: SME session identifier
+ * @reason: Reason to disconnect
+ *
+ * Return: QDF Status success or failure
+ */
+QDF_STATUS sme_roam_disconnect(tHalHandle hal, uint8_t session,
+			       eCsrRoamDisconnectReason reason);
+
+void sme_dhcp_done_ind(tHalHandle hal, uint8_t session_id);
+QDF_STATUS sme_roam_stop_bss(tHalHandle hHal, uint8_t sessionId);
+QDF_STATUS sme_roam_get_associated_stas(tHalHandle hHal, uint8_t sessionId,
+		QDF_MODULE_ID modId, void *pUsrContext,
+		void *pfnSapEventCallback,
+		uint8_t *pAssocStasBuf);
+QDF_STATUS sme_roam_disconnect_sta(tHalHandle hHal, uint8_t sessionId,
+		struct csr_del_sta_params *p_del_sta_params);
+QDF_STATUS sme_roam_deauth_sta(tHalHandle hHal, uint8_t sessionId,
+		struct csr_del_sta_params *pDelStaParams);
+QDF_STATUS sme_roam_get_connect_state(tHalHandle hHal, uint8_t sessionId,
+		eCsrConnectState *pState);
+QDF_STATUS sme_roam_get_connect_profile(tHalHandle hHal, uint8_t sessionId,
+		tCsrRoamConnectedProfile *pProfile);
+void sme_roam_free_connect_profile(tCsrRoamConnectedProfile *profile);
+QDF_STATUS sme_roam_set_pmkid_cache(tHalHandle hHal, uint8_t sessionId,
+		tPmkidCacheInfo *pPMKIDCache,
+		uint32_t numItems,
+		bool update_entire_cache);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * sme_get_pmk_info(): A wrapper function to request CSR to save PMK
+ * @hal: Global structure
+ * @session_id: SME session_id
+ * @pmk_cache: pointer to a structure of pmk
+ *
+ * Return: none
+ */
+void sme_get_pmk_info(tHalHandle hal, uint8_t session_id,
+		      tPmkidCacheInfo *pmk_cache);
+
+QDF_STATUS sme_roam_set_psk_pmk(tHalHandle hHal, uint8_t sessionId,
+		uint8_t *pPSK_PMK, size_t pmk_len);
+#endif
+
+/**
+ * sme_roam_get_wpa_rsn_req_ie() - Retrieve WPA/RSN Request IE
+ * @hal: HAL handle
+ * @session_id: ID of the specific session
+ * @len: Caller allocated memory that has the length of @buf as input.
+ *	Upon returned, @len has the length of the IE store in @buf
+ * @buf: Caller allocated memory that contain the IE field, if any,
+ *	upon return
+ *
+ * A wrapper function to request CSR to return the WPA or RSN IE CSR
+ * passes to PE to JOIN request or START_BSS request
+ * This is a synchronous call.
+ *
+ * Return: QDF_STATUS - when fail, it usually means the buffer allocated is not
+ *			 big enough
+ */
+QDF_STATUS sme_roam_get_wpa_rsn_req_ie(tHalHandle hal, uint8_t session_id,
+				       uint32_t *len, uint8_t *buf);
+
+/**
+ * sme_roam_get_wpa_rsn_rsp_ie() - Retrieve WPA/RSN Response IE
+ * @hal: HAL handle
+ * @session_id: ID of the specific session
+ * @len: Caller allocated memory that has the length of @buf as input.
+ *	Upon returned, @len has the length of the IE store in @buf
+ * @buf: Caller allocated memory that contain the IE field, if any,
+ *	upon return
+ *
+ * A wrapper function to request CSR to return the WPA or RSN IE CSR
+ * passes to PE to JOIN request or START_BSS request
+ * This is a synchronous call.
+ *
+ * Return: QDF_STATUS - when fail, it usually means the buffer allocated is not
+ *			 big enough
+ */
+QDF_STATUS sme_roam_get_wpa_rsn_rsp_ie(tHalHandle hal, uint8_t session_id,
+				       uint32_t *len, uint8_t *buf);
+
+uint32_t sme_roam_get_num_pmkid_cache(tHalHandle hHal, uint8_t sessionId);
+QDF_STATUS sme_roam_get_pmkid_cache(tHalHandle hHal, uint8_t sessionId,
+		uint32_t *pNum,
+		tPmkidCacheInfo *pPmkidCache);
+QDF_STATUS sme_get_config_param(tHalHandle hHal, tSmeConfigParams *pParam);
+#ifndef QCA_SUPPORT_CP_STATS
+QDF_STATUS sme_get_statistics(tHalHandle hHal,
+		eCsrStatsRequesterType requesterId,
+		uint32_t statsMask, tCsrStatsCallback callback,
+		uint8_t staId, void *pContext, uint8_t sessionId);
+#endif
+QDF_STATUS sme_get_rssi(tHalHandle hHal,
+		tCsrRssiCallback callback,
+		uint8_t staId, struct qdf_mac_addr bssId, int8_t lastRSSI,
+		void *pContext);
+QDF_STATUS sme_get_snr(tHalHandle hHal,
+		tCsrSnrCallback callback,
+		uint8_t staId, struct qdf_mac_addr bssId, void *pContext);
+#ifdef FEATURE_WLAN_ESE
+QDF_STATUS sme_get_tsm_stats(tHalHandle hHal,
+		tCsrTsmStatsCallback callback,
+		uint8_t staId, struct qdf_mac_addr bssId,
+		void *pContext, uint8_t tid);
+QDF_STATUS sme_set_cckm_ie(tHalHandle hHal,
+		uint8_t sessionId,
+		uint8_t *pCckmIe, uint8_t cckmIeLen);
+QDF_STATUS sme_set_ese_beacon_request(tHalHandle hHal, const uint8_t sessionId,
+		const tCsrEseBeaconReq *pEseBcnReq);
+QDF_STATUS sme_set_plm_request(tHalHandle hHal, tpSirPlmReq pPlm);
+#endif /*FEATURE_WLAN_ESE */
+QDF_STATUS sme_cfg_set_int(tHalHandle hal, uint16_t cfg_id, uint32_t value);
+QDF_STATUS sme_cfg_set_str(tHalHandle hal, uint16_t cfg_id, uint8_t *str,
+		uint32_t length);
+QDF_STATUS sme_cfg_get_int(tHalHandle hal, uint16_t cfg_id,
+		uint32_t *cfg_value);
+QDF_STATUS sme_cfg_get_str(tHalHandle hal, uint16_t cfg_id, uint8_t *str,
+		uint32_t *length);
+QDF_STATUS sme_get_modify_profile_fields(tHalHandle hHal, uint8_t sessionId,
+					 tCsrRoamModifyProfileFields *
+					 pModifyProfileFields);
+
+extern QDF_STATUS sme_set_host_power_save(tHalHandle hHal, bool psMode);
+
+void sme_set_dhcp_till_power_active_flag(tHalHandle hHal, uint8_t flag);
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+extern QDF_STATUS sme_register_oem_data_rsp_callback(tHalHandle h_hal,
+		sme_send_oem_data_rsp_msg callback);
+void sme_deregister_oem_data_rsp_callback(tHalHandle h_hal);
+
+#else
+static inline QDF_STATUS sme_register_oem_data_rsp_callback(tHalHandle hal,
+		void *callback)
+{
+	return QDF_STATUS_SUCCESS;
+}
+static inline void sme_deregister_oem_data_rsp_callback(tHalHandle h_hal)
+{
+}
+
+#endif
+
+QDF_STATUS sme_roam_set_key(tHalHandle, uint8_t sessionId,
+		tCsrRoamSetKey *pSetKey, uint32_t *pRoamId);
+QDF_STATUS sme_get_country_code(tHalHandle hHal, uint8_t *pBuf, uint8_t *pbLen);
+
+
+/* some support functions */
+bool sme_is11d_supported(tHalHandle hHal);
+bool sme_is11h_supported(tHalHandle hHal);
+bool sme_is_wmm_supported(tHalHandle hHal);
+
+QDF_STATUS sme_generic_change_country_code(tHalHandle hHal,
+					   uint8_t *pCountry);
+
+
+/**
+ * sme_update_channel_list() - Update configured channel list to fwr
+ * This is a synchronous API.
+ * @hal: HAL handle returned by mac_open.
+ *
+ * Return: QDF_STATUS  SUCCESS.
+ * FAILURE or RESOURCES  The API finished and failed.
+ */
+QDF_STATUS sme_update_channel_list(tHalHandle hal);
+
+QDF_STATUS sme_tx_fail_monitor_start_stop_ind(tHalHandle hHal,
+		uint8_t tx_fail_count,
+		void *txFailIndCallback);
+QDF_STATUS sme_dhcp_start_ind(tHalHandle hHal,
+		uint8_t device_mode,
+		uint8_t *macAddr, uint8_t sessionId);
+QDF_STATUS sme_dhcp_stop_ind(tHalHandle hHal,
+		uint8_t device_mode,
+		uint8_t *macAddr, uint8_t sessionId);
+void sme_get_recovery_stats(tHalHandle hHal);
+QDF_STATUS sme_neighbor_report_request(tHalHandle hHal, uint8_t sessionId,
+		tpRrmNeighborReq pRrmNeighborReq,
+		tpRrmNeighborRspCallbackInfo callbackInfo);
+QDF_STATUS sme_get_wcnss_wlan_compiled_version(tHalHandle hHal,
+		tSirVersionType * pVersion);
+QDF_STATUS sme_get_wcnss_wlan_reported_version(tHalHandle hHal,
+		tSirVersionType *pVersion);
+QDF_STATUS sme_get_wcnss_software_version(tHalHandle hHal,
+		uint8_t *pVersion, uint32_t versionBufferSize);
+QDF_STATUS sme_get_wcnss_hardware_version(tHalHandle hHal,
+		uint8_t *pVersion, uint32_t versionBufferSize);
+#ifdef FEATURE_OEM_DATA_SUPPORT
+QDF_STATUS sme_oem_data_req(tHalHandle hHal, struct oem_data_req *);
+QDF_STATUS sme_oem_update_capability(tHalHandle hHal,
+				     struct sme_oem_capability *cap);
+QDF_STATUS sme_oem_get_capability(tHalHandle hHal,
+				  struct sme_oem_capability *cap);
+#endif /*FEATURE_OEM_DATA_SUPPORT */
+QDF_STATUS sme_change_mcc_beacon_interval(uint8_t sessionId);
+QDF_STATUS sme_set_host_offload(tHalHandle hHal, uint8_t sessionId,
+		tpSirHostOffloadReq pRequest);
+QDF_STATUS sme_set_keep_alive(tHalHandle hHal, uint8_t sessionId,
+		tpSirKeepAliveReq pRequest);
+QDF_STATUS sme_get_operation_channel(tHalHandle hHal, uint32_t *pChannel,
+		uint8_t sessionId);
+QDF_STATUS sme_register_mgmt_frame(tHalHandle hHal, uint8_t sessionId,
+		uint16_t frameType, uint8_t *matchData,
+		uint16_t matchLen);
+QDF_STATUS sme_deregister_mgmt_frame(tHalHandle hHal, uint8_t sessionId,
+		uint16_t frameType, uint8_t *matchData,
+		uint16_t matchLen);
+QDF_STATUS sme_ConfigureAppsCpuWakeupState(tHalHandle hHal, bool isAppsAwake);
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+QDF_STATUS sme_configure_ext_wow(tHalHandle hHal,
+		tpSirExtWoWParams wlanExtParams,
+		csr_readyToSuspendCallback callback,
+		void *callbackContext);
+QDF_STATUS sme_configure_app_type1_params(tHalHandle hHal,
+		tpSirAppType1Params wlanAppType1Params);
+QDF_STATUS sme_configure_app_type2_params(tHalHandle hHal,
+		tpSirAppType2Params wlanAppType2Params);
+#endif
+int8_t sme_get_infra_session_id(tHalHandle hHal);
+uint8_t sme_get_infra_operation_channel(tHalHandle hHal, uint8_t sessionId);
+uint8_t sme_get_concurrent_operation_channel(tHalHandle hHal);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+uint16_t sme_check_concurrent_channel_overlap(tHalHandle hHal, uint16_t sap_ch,
+		eCsrPhyMode sapPhyMode,
+		uint8_t cc_switch_mode);
+#endif
+QDF_STATUS sme_get_cfg_valid_channels(uint8_t *aValidChannels,
+		uint32_t *len);
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+QDF_STATUS sme_8023_multicast_list(tHalHandle hHal, uint8_t sessionId,
+		tpSirRcvFltMcAddrList pMulticastAddrs);
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+bool sme_is_channel_valid(tHalHandle hHal, uint8_t channel);
+QDF_STATUS sme_get_freq_band(tHalHandle hHal, enum band_info *pBand);
+uint16_t sme_chn_to_freq(uint8_t chanNum);
+bool sme_is_channel_valid(tHalHandle hHal, uint8_t channel);
+QDF_STATUS sme_set_max_tx_power(tHalHandle hHal, struct qdf_mac_addr pBssid,
+		struct qdf_mac_addr pSelfMacAddress, int8_t dB);
+QDF_STATUS sme_set_max_tx_power_per_band(enum band_info band, int8_t db);
+QDF_STATUS sme_set_tx_power(tHalHandle hHal, uint8_t sessionId,
+		struct qdf_mac_addr bssid,
+		enum QDF_OPMODE dev_mode, int power);
+QDF_STATUS sme_set_custom_mac_addr(tSirMacAddr customMacAddr);
+QDF_STATUS sme_hide_ssid(tHalHandle hHal, uint8_t sessionId,
+		uint8_t ssidHidden);
+QDF_STATUS sme_set_tm_level(tHalHandle hHal, uint16_t newTMLevel,
+		uint16_t tmMode);
+void sme_feature_caps_exchange(tHalHandle hHal);
+void sme_disable_feature_capablity(uint8_t feature_index);
+void sme_reset_power_values_for5_g(tHalHandle hHal);
+QDF_STATUS sme_update_roam_prefer5_g_hz(tHalHandle hHal, bool nRoamPrefer5GHz);
+QDF_STATUS sme_set_roam_intra_band(tHalHandle hHal, const bool nRoamIntraBand);
+QDF_STATUS sme_update_roam_scan_n_probes(tHalHandle hHal, uint8_t sessionId,
+		const uint8_t nProbes);
+QDF_STATUS sme_update_roam_scan_home_away_time(tHalHandle hHal,
+		uint8_t sessionId,
+		const uint16_t nRoamScanHomeAwayTime,
+		const bool bSendOffloadCmd);
+
+bool sme_get_roam_intra_band(tHalHandle hHal);
+uint8_t sme_get_roam_scan_n_probes(tHalHandle hHal);
+uint16_t sme_get_roam_scan_home_away_time(tHalHandle hHal);
+QDF_STATUS sme_update_roam_rssi_diff(tHalHandle hHal, uint8_t sessionId,
+		uint8_t RoamRssiDiff);
+QDF_STATUS sme_update_fast_transition_enabled(tHalHandle hHal,
+		bool isFastTransitionEnabled);
+QDF_STATUS sme_update_wes_mode(tHalHandle hHal, bool isWESModeEnabled,
+		uint8_t sessionId);
+QDF_STATUS sme_set_roam_scan_control(tHalHandle hHal, uint8_t sessionId,
+		bool roamScanControl);
+
+QDF_STATUS sme_update_is_fast_roam_ini_feature_enabled(tHalHandle hHal,
+		uint8_t sessionId,
+		const bool
+		isFastRoamIniFeatureEnabled);
+
+QDF_STATUS sme_config_fast_roaming(tHalHandle hal, uint8_t session_id,
+		const bool is_fast_roam_enabled);
+
+QDF_STATUS sme_update_is_mawc_ini_feature_enabled(tHalHandle hHal,
+		const bool MAWCEnabled);
+QDF_STATUS sme_stop_roaming(tHalHandle hHal, uint8_t sessionId, uint8_t reason);
+
+QDF_STATUS sme_start_roaming(tHalHandle hHal, uint8_t sessionId,
+		uint8_t reason);
+QDF_STATUS sme_update_enable_fast_roam_in_concurrency(tHalHandle hHal,
+		bool bFastRoamInConIniFeatureEnabled);
+#ifdef FEATURE_WLAN_ESE
+QDF_STATUS sme_update_is_ese_feature_enabled(tHalHandle hHal, uint8_t sessionId,
+		const bool isEseIniFeatureEnabled);
+#endif /* FEATURE_WLAN_ESE */
+QDF_STATUS sme_set_roam_rescan_rssi_diff(tHalHandle hHal,
+		uint8_t sessionId,
+		const uint8_t nRoamRescanRssiDiff);
+uint8_t sme_get_roam_rescan_rssi_diff(tHalHandle hHal);
+
+QDF_STATUS sme_set_roam_opportunistic_scan_threshold_diff(tHalHandle hHal,
+		uint8_t sessionId,
+		const uint8_t nOpportunisticThresholdDiff);
+uint8_t sme_get_roam_opportunistic_scan_threshold_diff(tHalHandle hHal);
+QDF_STATUS sme_set_neighbor_lookup_rssi_threshold(tHalHandle hHal,
+		uint8_t sessionId, uint8_t neighborLookupRssiThreshold);
+QDF_STATUS sme_set_delay_before_vdev_stop(tHalHandle hHal,
+		uint8_t sessionId, uint8_t delay_before_vdev_stop);
+uint8_t sme_get_neighbor_lookup_rssi_threshold(tHalHandle hHal);
+QDF_STATUS sme_set_neighbor_scan_refresh_period(tHalHandle hHal,
+		uint8_t sessionId, uint16_t neighborScanResultsRefreshPeriod);
+uint16_t sme_get_neighbor_scan_refresh_period(tHalHandle hHal);
+uint16_t sme_get_empty_scan_refresh_period(tHalHandle hHal);
+QDF_STATUS sme_update_empty_scan_refresh_period(tHalHandle hHal,
+		uint8_t sessionId, uint16_t nEmptyScanRefreshPeriod);
+QDF_STATUS sme_set_neighbor_scan_min_chan_time(tHalHandle hHal,
+		const uint16_t nNeighborScanMinChanTime,
+		uint8_t sessionId);
+QDF_STATUS sme_set_neighbor_scan_max_chan_time(tHalHandle hHal,
+		uint8_t sessionId, const uint16_t nNeighborScanMaxChanTime);
+uint16_t sme_get_neighbor_scan_min_chan_time(tHalHandle hHal,
+		uint8_t sessionId);
+uint32_t sme_get_neighbor_roam_state(tHalHandle hHal, uint8_t sessionId);
+uint32_t sme_get_current_roam_state(tHalHandle hHal, uint8_t sessionId);
+uint32_t sme_get_current_roam_sub_state(tHalHandle hHal, uint8_t sessionId);
+uint32_t sme_get_lim_sme_state(tHalHandle hHal);
+uint32_t sme_get_lim_mlm_state(tHalHandle hHal);
+bool sme_is_lim_session_valid(tHalHandle hHal, uint8_t sessionId);
+uint32_t sme_get_lim_sme_session_state(tHalHandle hHal, uint8_t sessionId);
+uint32_t sme_get_lim_mlm_session_state(tHalHandle hHal, uint8_t sessionId);
+uint16_t sme_get_neighbor_scan_max_chan_time(tHalHandle hHal,
+		uint8_t sessionId);
+QDF_STATUS sme_set_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId,
+		const uint16_t nNeighborScanPeriod);
+uint16_t sme_get_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId);
+QDF_STATUS sme_set_neighbor_scan_min_period(tHalHandle h_hal,
+		uint8_t session_id, const uint16_t neighbor_scan_min_period);
+QDF_STATUS sme_set_roam_bmiss_first_bcnt(tHalHandle hHal,
+		uint8_t sessionId, const uint8_t nRoamBmissFirstBcnt);
+uint8_t sme_get_roam_bmiss_first_bcnt(tHalHandle hHal);
+QDF_STATUS sme_set_roam_bmiss_final_bcnt(tHalHandle hHal, uint8_t sessionId,
+		const uint8_t nRoamBmissFinalBcnt);
+uint8_t sme_get_roam_bmiss_final_bcnt(tHalHandle hHal);
+QDF_STATUS sme_set_roam_beacon_rssi_weight(tHalHandle hHal, uint8_t sessionId,
+		const uint8_t nRoamBeaconRssiWeight);
+uint8_t sme_get_roam_beacon_rssi_weight(tHalHandle hHal);
+uint8_t sme_get_roam_rssi_diff(tHalHandle hHal);
+QDF_STATUS sme_change_roam_scan_channel_list(tHalHandle hHal, uint8_t sessionId,
+		uint8_t *pChannelList,
+		uint8_t numChannels);
+QDF_STATUS sme_set_ese_roam_scan_channel_list(tHalHandle hHal,
+		uint8_t sessionId, uint8_t *pChannelList,
+		uint8_t numChannels);
+QDF_STATUS sme_get_roam_scan_channel_list(tHalHandle hHal,
+		uint8_t *pChannelList, uint8_t *pNumChannels,
+		uint8_t sessionId);
+bool sme_get_is_ese_feature_enabled(tHalHandle hHal);
+bool sme_get_wes_mode(tHalHandle hHal);
+bool sme_get_roam_scan_control(tHalHandle hHal);
+bool sme_get_is_lfr_feature_enabled(tHalHandle hHal);
+bool sme_get_is_ft_feature_enabled(tHalHandle hHal);
+QDF_STATUS sme_update_roam_scan_offload_enabled(tHalHandle hHal,
+		bool nRoamScanOffloadEnabled);
+bool sme_is_feature_supported_by_fw(enum cap_bitmap feature);
+
+/*
+ * SME API to enable/disable WLAN driver initiated SSR
+ */
+void sme_update_enable_ssr(tHalHandle hHal, bool enableSSR);
+QDF_STATUS sme_set_phy_mode(tHalHandle hHal, eCsrPhyMode phyMode);
+eCsrPhyMode sme_get_phy_mode(tHalHandle hHal);
+QDF_STATUS sme_handoff_request(tHalHandle hHal, uint8_t sessionId,
+			       tCsrHandoffRequest *pHandoffInfo);
+QDF_STATUS sme_is_sta_p2p_client_connected(tHalHandle hHal);
+QDF_STATUS sme_add_periodic_tx_ptrn(tHalHandle hHal, tSirAddPeriodicTxPtrn
+		*addPeriodicTxPtrnParams);
+QDF_STATUS sme_del_periodic_tx_ptrn(tHalHandle hHal, tSirDelPeriodicTxPtrn
+		*delPeriodicTxPtrnParams);
+QDF_STATUS sme_send_rate_update_ind(tHalHandle hHal,
+		tSirRateUpdateInd *rateUpdateParams);
+QDF_STATUS sme_roam_del_pmkid_from_cache(tHalHandle hHal, uint8_t sessionId,
+		tPmkidCacheInfo *pmksa, bool flush_cache);
+void sme_get_command_q_status(tHalHandle hHal);
+
+#ifdef FEATURE_WLAN_RMC
+QDF_STATUS sme_enable_rmc(tHalHandle hHal, uint32_t sessionId);
+QDF_STATUS sme_disable_rmc(tHalHandle hHal, uint32_t sessionId);
+QDF_STATUS sme_send_rmc_action_period(tHalHandle hHal, uint32_t sessionId);
+#endif
+QDF_STATUS sme_request_ibss_peer_info(tHalHandle hHal, void *pUserData,
+	pIbssPeerInfoCb peerInfoCbk, bool allPeerInfoReqd, uint8_t staIdx);
+QDF_STATUS sme_send_cesium_enable_ind(tHalHandle hHal, uint32_t sessionId);
+
+/**
+ * sme_set_wlm_latency_level_ind() - Used to set the latency level to fw
+ * @hal
+ * @session_id
+ * @latency_level
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_wlm_latency_level(tHalHandle hal,
+				     uint16_t session_id,
+				     uint16_t latency_level);
+/*
+ * SME API to enable/disable idle mode powersave
+ * This should be called only if powersave offload
+ * is enabled
+ */
+QDF_STATUS sme_set_idle_powersave_config(bool value);
+QDF_STATUS sme_notify_modem_power_state(tHalHandle hHal, uint32_t value);
+
+/*SME API to convert convert the ini value to the ENUM used in csr and MAC*/
+ePhyChanBondState sme_get_cb_phy_state_from_cb_ini_value(uint32_t cb_ini_value);
+int sme_update_ht_config(tHalHandle hHal, uint8_t sessionId, uint16_t htCapab,
+		int value);
+int16_t sme_get_ht_config(tHalHandle hHal, uint8_t session_id,
+		uint16_t ht_capab);
+#ifdef QCA_HT_2040_COEX
+QDF_STATUS sme_notify_ht2040_mode(tHalHandle hHal, uint16_t staId,
+		struct qdf_mac_addr macAddrSTA,
+		uint8_t sessionId,
+		uint8_t channel_type);
+QDF_STATUS sme_set_ht2040_mode(tHalHandle hHal, uint8_t sessionId,
+		uint8_t channel_type, bool obssEnabled);
+#endif
+QDF_STATUS sme_get_reg_info(tHalHandle hHal, uint8_t chanId,
+		uint32_t *regInfo1, uint32_t *regInfo2);
+#ifdef FEATURE_WLAN_TDLS
+QDF_STATUS sme_update_fw_tdls_state(tHalHandle hHal, void *psmeTdlsParams,
+		bool useSmeLock);
+#endif /* FEATURE_WLAN_TDLS */
+
+#ifdef FEATURE_WLAN_CH_AVOID
+QDF_STATUS sme_ch_avoid_update_req(tHalHandle hal_handle);
+#else
+static inline
+QDF_STATUS sme_ch_avoid_update_req(tHalHandle hal_handle)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+QDF_STATUS sme_set_auto_shutdown_cb(tHalHandle hHal, void (*pCallbackfn)(void));
+QDF_STATUS sme_set_auto_shutdown_timer(tHalHandle hHal, uint32_t timer_value);
+#endif
+QDF_STATUS sme_roam_channel_change_req(tHalHandle hHal,
+				       struct qdf_mac_addr bssid,
+				       struct ch_params *ch_params,
+				       struct csr_roam_profile *profile);
+
+QDF_STATUS sme_roam_start_beacon_req(tHalHandle hHal,
+		struct qdf_mac_addr bssid, uint8_t dfsCacWaitStatus);
+
+#ifdef CONFIG_VDEV_SM
+/**
+ * sme_csa_restart() - request CSA IE transmission from PE
+ * @mac_ctx: mac context
+ * @session_id: SAP session id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_csa_restart(tpAniSirGlobal mac_ctx, uint8_t session_id);
+#endif
+
+QDF_STATUS sme_roam_csa_ie_request(tHalHandle hHal, struct qdf_mac_addr bssid,
+				   uint8_t targetChannel, uint8_t csaIeReqd,
+				   struct ch_params *ch_params);
+
+/**
+ * sme_set_addba_accept() - Allow/Reject the ADDBA req session
+ * @hal: handle returned by mac_open
+ * @session_id: sme session id
+ * @value: Allow/Reject AddBA session
+ *
+ * Allows/Rejects the ADDBA req session
+ *
+ * Return: 0 on success else errno
+ */
+int sme_set_addba_accept(tHalHandle hal, uint8_t session_id, int value);
+
+QDF_STATUS sme_init_thermal_info(tHalHandle hHal,
+				 tSmeThermalParams thermalParam);
+
+QDF_STATUS sme_set_thermal_level(tHalHandle hHal, uint8_t level);
+QDF_STATUS sme_txpower_limit(tHalHandle hHal, tSirTxPowerLimit *psmetx);
+QDF_STATUS sme_get_link_speed(tHalHandle hHal, tSirLinkSpeedInfo *lsReq,
+		void *plsContext,
+		void (*pCallbackfn)(tSirLinkSpeedInfo *indParam,
+		void *pContext));
+QDF_STATUS sme_modify_add_ie(tHalHandle hHal,
+		tSirModifyIE *pModifyIE, eUpdateIEsType updateType);
+QDF_STATUS sme_update_add_ie(tHalHandle hHal,
+		tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType);
+QDF_STATUS sme_update_connect_debug(tHalHandle hHal, uint32_t set_value);
+const char *sme_bss_type_to_string(const uint8_t bss_type);
+QDF_STATUS sme_ap_disable_intra_bss_fwd(tHalHandle hHal, uint8_t sessionId,
+		bool disablefwd);
+QDF_STATUS sme_get_channel_bonding_mode5_g(tHalHandle hHal, uint32_t *mode);
+QDF_STATUS sme_get_channel_bonding_mode24_g(tHalHandle hHal, uint32_t *mode);
+
+/**
+ * sme_send_unit_test_cmd() - send unit test command to lower layer
+ * @session_id: sme session id to be filled while forming the command
+ * @module_id: module id given by user to be filled in the command
+ * @arg_count: number of argument count
+ * @arg: pointer to argument list
+ *
+ * This API exposed to HDD layer which takes the argument from user and sends
+ * down to lower layer for further processing
+ *
+ * Return: QDF_STATUS based on overall success
+ */
+QDF_STATUS sme_send_unit_test_cmd(uint32_t vdev_id, uint32_t module_id,
+				  uint32_t arg_count, uint32_t *arg);
+
+typedef struct sStatsExtRequestReq {
+	uint32_t request_data_len;
+	uint8_t *request_data;
+} tStatsExtRequestReq, *tpStatsExtRequestReq;
+
+#ifdef WLAN_FEATURE_STATS_EXT
+/**
+ * sme_stats_ext_register_callback() - Register stats ext callback
+ * @mac_handle: Opaque handle to the MAC context
+ * @callback: Function to be invoked for stats ext events
+ *
+ * This function is called to register the callback that send vendor
+ * event for stats ext
+ */
+void sme_stats_ext_register_callback(mac_handle_t mac_handle,
+				     stats_ext_cb callback);
+
+/**
+ * sme_stats_ext_deregister_callback() - Deregister stats ext callback
+ * @mac_handle: Opaque handle to the MAC context
+ *
+ * This function is called to deregister the callback that send vendor
+ * event for stats ext
+ */
+void sme_stats_ext_deregister_callback(mac_handle_t mac_handle);
+
+/**
+ * sme_stats_ext2_register_callback() - Register stats ext2 callback
+ * @mac_handle: Opaque handle to the MAC context
+ * @callback: Function to be invoked for stats ext2 events
+ *
+ * This function will register a callback for frame aggregation failure
+ * indications processing.
+ *
+ * Return: void
+ */
+void sme_stats_ext2_register_callback(tHalHandle hal_handle,
+				      stats_ext2_cb callback);
+
+QDF_STATUS sme_stats_ext_request(uint8_t session_id,
+				 tpStatsExtRequestReq input);
+#else
+static inline void
+sme_stats_ext_register_callback(mac_handle_t mac_handle,
+				stats_ext_cb callback)
+{
+}
+
+static inline void
+sme_stats_ext2_register_callback(tHalHandle hal_handle,
+				 stats_ext2_cb callback)
+{
+}
+#endif /* WLAN_FEATURE_STATS_EXT */
+QDF_STATUS sme_update_dfs_scan_mode(tHalHandle hHal,
+		uint8_t sessionId,
+		uint8_t allowDFSChannelRoam);
+uint8_t sme_get_dfs_scan_mode(tHalHandle hHal);
+
+#ifdef FEATURE_WLAN_EXTSCAN
+QDF_STATUS sme_get_valid_channels_by_band(tHalHandle hHal, uint8_t wifiBand,
+		uint32_t *aValidChannels,
+		uint8_t *pNumChannels);
+
+/**
+ * sme_ext_scan_get_capabilities() - SME API to fetch extscan capabilities
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: extscan capabilities request structure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+sme_ext_scan_get_capabilities(mac_handle_t mac_handle,
+			      struct extscan_capabilities_params *params);
+
+/**
+ * sme_ext_scan_start() - SME API to issue extscan start
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: extscan start structure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+sme_ext_scan_start(mac_handle_t mac_handle,
+		   struct wifi_scan_cmd_req_params *params);
+
+/**
+ * sme_ext_scan_stop() - SME API to issue extscan stop
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: extscan stop structure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_ext_scan_stop(mac_handle_t mac_handle,
+			     struct extscan_stop_req_params *params);
+
+/**
+ * sme_set_bss_hotlist() - SME API to set BSSID hotlist
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: extscan set hotlist structure
+ *
+ * Handles the request to set the BSSID hotlist in firmware.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+sme_set_bss_hotlist(mac_handle_t mac_handle,
+		    struct extscan_bssid_hotlist_set_params *params);
+
+/**
+ * sme_reset_bss_hotlist() - SME API to reset BSSID hotlist
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: extscan reset hotlist structure
+ *
+ * Handles the request to reset the BSSID hotlist in firmware.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+sme_reset_bss_hotlist(mac_handle_t mac_handle,
+		      struct extscan_bssid_hotlist_reset_params *params);
+
+/**
+ * sme_set_significant_change() - SME API to set significant change
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: extscan set significant change structure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+sme_set_significant_change(mac_handle_t mac_handle,
+			   struct extscan_set_sig_changereq_params *params);
+
+/**
+ * sme_reset_significant_change() -  SME API to reset significant change
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: extscan reset significant change structure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+sme_reset_significant_change(mac_handle_t mac_handle,
+			     struct extscan_capabilities_reset_params *params);
+
+/**
+ * sme_get_cached_results() - SME API to get cached results
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: extscan get cached results structure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+sme_get_cached_results(mac_handle_t mac_handle,
+		       struct extscan_cached_result_params *params);
+
+/**
+ * sme_set_epno_list() - set epno network list
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: request message
+ *
+ * This function sends an Enhanced PNO configuration to firmware.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_set_epno_list(mac_handle_t mac_handle,
+			     struct wifi_enhanced_pno_params *params);
+
+/**
+ * sme_set_passpoint_list() - set passpoint network list
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: set passpoint list request parameters
+ *
+ * This function constructs the cds message and fill in message type,
+ * bodyptr with @params and posts it to WDA queue.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_set_passpoint_list(mac_handle_t mac_handle,
+				  struct wifi_passpoint_req_param *params);
+
+/**
+ * sme_reset_passpoint_list() - reset passpoint network list
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: reset passpoint list request parameters
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_reset_passpoint_list(mac_handle_t mac_handle,
+				    struct wifi_passpoint_req_param *params);
+
+QDF_STATUS sme_ext_scan_register_callback(mac_handle_t mac_handle,
+					  ext_scan_ind_cb ext_scan_ind_cb);
+#else
+static inline
+QDF_STATUS sme_ext_scan_register_callback(mac_handle_t mac_handle,
+					  ext_scan_ind_cb ext_scan_ind_cb)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_EXTSCAN */
+QDF_STATUS sme_abort_roam_scan(tHalHandle hHal, uint8_t sessionId);
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+QDF_STATUS sme_ll_stats_clear_req(tHalHandle hHal,
+		tSirLLStatsClearReq * pclearStatsReq);
+QDF_STATUS sme_ll_stats_set_req(tHalHandle hHal,
+		tSirLLStatsSetReq *psetStatsReq);
+
+/**
+ * sme_ll_stats_get_req() - SME API to get the Link Layer Statistics
+ * @mac_handle: Global MAC handle
+ * @get_stats_req: Link Layer get stats request params structure
+ * @context: Callback context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_ll_stats_get_req(mac_handle_t mac_handle,
+				tSirLLStatsGetReq *get_stats_req,
+				void *context);
+
+/**
+ * sme_set_link_layer_stats_ind_cb() -
+ * SME API to trigger the stats are available after get request
+ * @mac_handle: MAC handle
+ * @callback: HDD callback which needs to be invoked after
+ *    getting status notification from FW
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_link_layer_stats_ind_cb(mac_handle_t mac_handle,
+					   link_layer_stats_cb callback);
+
+QDF_STATUS sme_set_link_layer_ext_cb(tHalHandle hal,
+		     void (*ll_stats_ext_cb)(hdd_handle_t callback_ctx,
+					     tSirLLStatsResults * rsp));
+QDF_STATUS sme_reset_link_layer_stats_ind_cb(tHalHandle hhal);
+QDF_STATUS sme_ll_stats_set_thresh(tHalHandle hal,
+				struct sir_ll_ext_stats_threshold *threshold);
+#else /* WLAN_FEATURE_LINK_LAYER_STATS */
+static inline QDF_STATUS
+sme_set_link_layer_ext_cb(tHalHandle hal, void (*ll_stats_ext_cb)
+			  (hdd_handle_t callback_ctx, tSirLLStatsResults
+			  *rsp))
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+sme_set_link_layer_stats_ind_cb(mac_handle_t mac_handle,
+				link_layer_stats_cb callback)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+sme_reset_link_layer_stats_ind_cb(tHalHandle hhal)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+QDF_STATUS sme_set_wisa_params(tHalHandle hal,
+				struct sir_wisa_params *wisa_params);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS sme_update_roam_offload_enabled(tHalHandle hHal,
+		bool nRoamOffloadEnabled);
+QDF_STATUS sme_update_roam_key_mgmt_offload_enabled(tHalHandle hal_ctx,
+		uint8_t session_id,
+		bool key_mgmt_offload_enabled,
+		struct pmkid_mode_bits *pmkid_modes);
+#endif
+QDF_STATUS sme_get_link_status(mac_handle_t mac_handle,
+			       csr_link_status_callback callback,
+			       void *context, uint8_t session_id);
+QDF_STATUS sme_get_temperature(tHalHandle hHal,
+		void *tempContext,
+		void (*pCallbackfn)(int temperature,
+			void *pContext));
+QDF_STATUS sme_set_scanning_mac_oui(tHalHandle hHal,
+		tSirScanMacOui *pScanMacOui);
+
+#ifdef DHCP_SERVER_OFFLOAD
+QDF_STATUS sme_set_dhcp_srv_offload(tHalHandle hHal,
+		tSirDhcpSrvOffloadInfo * pDhcpSrvInfo);
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+QDF_STATUS sme_set_led_flashing(tHalHandle hHal, uint8_t type,
+		uint32_t x0, uint32_t x1);
+#endif
+QDF_STATUS sme_handle_dfs_chan_scan(tHalHandle hHal, uint8_t dfs_flag);
+QDF_STATUS sme_enable_dfs_chan_scan(tHalHandle hHal, uint8_t dfs_flag);
+QDF_STATUS sme_set_mas(uint32_t val);
+QDF_STATUS sme_set_miracast(tHalHandle hal, uint8_t filter_type);
+QDF_STATUS sme_ext_change_channel(tHalHandle hHal, uint32_t channel,
+					  uint8_t session_id);
+
+QDF_STATUS sme_configure_stats_avg_factor(tHalHandle hal, uint8_t session_id,
+					  uint16_t stats_avg_factor);
+
+QDF_STATUS sme_configure_guard_time(tHalHandle hal, uint8_t session_id,
+				    uint32_t guard_time);
+
+QDF_STATUS sme_wifi_start_logger(tHalHandle hal,
+		struct sir_wifi_start_log start_log);
+
+bool sme_neighbor_middle_of_roaming(tHalHandle hHal,
+						uint8_t sessionId);
+
+/*
+ * sme_is_any_session_in_middle_of_roaming() - check if roaming is in progress
+ * @hal: MAC Handle
+ *
+ * Checks if any SME session is in middle of roaming
+ *
+ * Return : true if roaming is in progress else false
+ */
+bool sme_is_any_session_in_middle_of_roaming(mac_handle_t hal);
+
+/**
+ * sme_enable_uapsd_for_ac() - enable uapsd for access category request to WMA
+ * @sta_id: station id
+ * @ac: access category
+ * @tid: tid value
+ * @pri: user priority
+ * @srvc_int: service interval
+ * @sus_int: suspend interval
+ * @dir: tspec direction
+ * @psb: PSB value
+ * @sessionId: session id
+ * @delay_interval: delay interval
+ *
+ * Return: QDF status
+ */
+QDF_STATUS sme_enable_uapsd_for_ac(uint8_t sta_id,
+				      sme_ac_enum_type ac, uint8_t tid,
+				      uint8_t pri, uint32_t srvc_int,
+				      uint32_t sus_int,
+				      enum sme_qos_wmm_dir_type dir,
+				      uint8_t psb, uint32_t sessionId,
+				      uint32_t delay_interval);
+
+/**
+ * sme_disable_uapsd_for_ac() - disable uapsd access category request to WMA
+ * @sta_id: station id
+ * @ac: access category
+ * @sessionId: session id
+ *
+ * Return: QDF status
+ */
+QDF_STATUS sme_disable_uapsd_for_ac(uint8_t sta_id,
+				       sme_ac_enum_type ac,
+				       uint32_t sessionId);
+
+#ifdef FEATURE_RSSI_MONITOR
+QDF_STATUS sme_set_rssi_monitoring(tHalHandle hal,
+					struct rssi_monitor_req *input);
+
+/**
+ * sme_set_rssi_threshold_breached_cb() - Set RSSI threshold breached callback
+ * @mac_handle: global MAC handle
+ * @cb: callback function pointer
+ *
+ * This function registers the RSSI threshold breached callback function.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_set_rssi_threshold_breached_cb(mac_handle_t mac_handle,
+					      rssi_threshold_breached_cb cb);
+#else /* FEATURE_RSSI_MONITOR */
+static inline
+QDF_STATUS sme_set_rssi_threshold_breached_cb(mac_handle_t mac_handle,
+					      rssi_threshold_breached_cb cb)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+/**
+ * sme_reset_rssi_threshold_breached_cb() - Reset RSSI threshold breached
+ *                                          callback
+ * @mac_handle: global MAC handle
+ *
+ * This function de-registers the RSSI threshold breached callback function.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_reset_rssi_threshold_breached_cb(mac_handle_t mac_handle);
+
+QDF_STATUS sme_register_mgmt_frame_ind_callback(tHalHandle hal,
+			sir_mgmt_frame_ind_callback callback);
+
+QDF_STATUS sme_update_nss(tHalHandle h_hal, uint8_t nss);
+void sme_update_user_configured_nss(tHalHandle hal, uint8_t nss);
+
+bool sme_is_any_session_in_connected_state(tHalHandle h_hal);
+
+QDF_STATUS sme_pdev_set_pcl(struct policy_mgr_pcl_list *msg);
+QDF_STATUS sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg);
+void sme_register_hw_mode_trans_cb(tHalHandle hal,
+		hw_mode_transition_cb callback);
+QDF_STATUS sme_nss_update_request(uint32_t vdev_id,
+				uint8_t  new_nss, policy_mgr_nss_update_cback cback,
+				uint8_t next_action, struct wlan_objmgr_psoc *psoc,
+				enum policy_mgr_conn_update_reason reason,
+				uint32_t original_vdev_id);
+
+typedef void (*sme_peer_authorized_fp) (uint32_t vdev_id);
+QDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr,
+				   sme_peer_authorized_fp auth_fp,
+				   uint32_t vdev_id);
+QDF_STATUS sme_soc_set_dual_mac_config(struct policy_mgr_dual_mac_config msg);
+QDF_STATUS sme_soc_set_antenna_mode(tHalHandle hal,
+		struct sir_antenna_mode_param *msg);
+
+void sme_set_scan_disable(tHalHandle h_hal, int value);
+void sme_setdef_dot11mode(tHalHandle hal);
+
+QDF_STATUS sme_handle_set_fcc_channel(tHalHandle hHal,
+				      bool fcc_constraint,
+				      bool scan_pending);
+
+QDF_STATUS sme_update_roam_scan_hi_rssi_scan_params(tHalHandle hal_handle,
+	uint8_t session_id,
+	uint32_t notify_id,
+	int32_t val);
+
+/**
+ * sme_update_tx_bfee_supp() - sets the Tx Bfee support
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @cfg_val: Tx Bfee config value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_tx_bfee_supp(tHalHandle hal, uint8_t session_id,
+		uint8_t cfg_val);
+
+/**
+ * sme_update_tx_bfee_nsts() - sets the Tx Bfee nsts
+ * @hal: MAC handle
+ * @session_id: SME session id
+ * @usr_cfg_val: user config value
+ * @nsts_val: Tx Bfee nsts config value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_tx_bfee_nsts(mac_handle_t hal, uint8_t session_id,
+			    uint8_t usr_cfg_val, uint8_t nsts_val);
+
+void wlan_sap_enable_phy_error_logs(tHalHandle hal, uint32_t enable_log);
+#ifdef WLAN_FEATURE_DSRC
+QDF_STATUS sme_ocb_set_config(tHalHandle hHal, void *context,
+			      ocb_callback callback,
+			      struct sir_ocb_config *config);
+
+QDF_STATUS sme_ocb_set_utc_time(tHalHandle hHal, struct sir_ocb_utc *utc);
+
+QDF_STATUS sme_ocb_start_timing_advert(tHalHandle hHal,
+	struct sir_ocb_timing_advert *timing_advert);
+
+QDF_STATUS sme_ocb_stop_timing_advert(tHalHandle hHal,
+	struct sir_ocb_timing_advert *timing_advert);
+
+int sme_ocb_gen_timing_advert_frame(tHalHandle hHal, tSirMacAddr self_addr,
+				    uint8_t **buf, uint32_t *timestamp_offset,
+				    uint32_t *time_value_offset);
+
+QDF_STATUS sme_ocb_get_tsf_timer(tHalHandle hHal, void *context,
+				 ocb_callback callback,
+				 struct sir_ocb_get_tsf_timer *request);
+
+QDF_STATUS sme_dcc_get_stats(tHalHandle hHal, void *context,
+			     ocb_callback callback,
+			     struct sir_dcc_get_stats *request);
+
+QDF_STATUS sme_dcc_clear_stats(tHalHandle hHal, uint32_t vdev_id,
+			       uint32_t dcc_stats_bitmap);
+
+QDF_STATUS sme_dcc_update_ndl(tHalHandle hHal, void *context,
+			      ocb_callback callback,
+			      struct sir_dcc_update_ndl *request);
+
+QDF_STATUS sme_register_for_dcc_stats_event(tHalHandle hHal, void *context,
+					    ocb_callback callback);
+QDF_STATUS sme_deregister_for_dcc_stats_event(tHalHandle hHal);
+
+static inline void
+sme_set_etsi13_srd_ch_in_master_mode(tHalHandle hal,
+				     bool etsi13_srd_chan_support)
+{
+}
+#else
+static inline QDF_STATUS sme_ocb_set_config(tHalHandle hHal, void *context,
+		ocb_callback callback,
+		struct sir_ocb_config *config)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS sme_ocb_set_utc_time(struct sir_ocb_utc *utc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS sme_ocb_start_timing_advert(
+		struct sir_ocb_timing_advert *timing_advert)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS sme_ocb_stop_timing_advert(struct sir_ocb_timing_advert
+		*timing_advert)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline int sme_ocb_gen_timing_advert_frame(tHalHandle hHal,
+		tSirMacAddr self_addr, uint8_t **buf,
+		uint32_t *timestamp_offset,
+		uint32_t *time_value_offset)
+{
+	return 0;
+}
+
+static inline QDF_STATUS sme_ocb_get_tsf_timer(tHalHandle hHal, void *context,
+		ocb_callback callback,
+		struct sir_ocb_get_tsf_timer *request)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS sme_dcc_get_stats(tHalHandle hHal, void *context,
+		ocb_callback callback,
+		struct sir_dcc_get_stats *request)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS sme_dcc_clear_stats(uint32_t vdev_id,
+		uint32_t dcc_stats_bitmap)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS sme_dcc_update_ndl(tHalHandle hHal, void *context,
+		ocb_callback callback,
+		struct sir_dcc_update_ndl *request)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS sme_register_for_dcc_stats_event(tHalHandle hHal,
+		void *context, ocb_callback callback)
+{
+	return QDF_STATUS_SUCCESS;
+}
+static inline QDF_STATUS sme_deregister_for_dcc_stats_event(tHalHandle hHal)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_set_etsi13_srd_ch_in_master_mode() - master mode UNI-III band ch support
+ * @hal: HAL pointer
+ * @srd_chan_support: ETSI SRD channel support
+ *
+ * This function set master ETSI SRD channel support
+ *
+ * Return: None
+ */
+void sme_set_etsi13_srd_ch_in_master_mode(tHalHandle hal,
+					  bool etsi13_srd_chan_support);
+#endif
+
+void sme_add_set_thermal_level_callback(tHalHandle hal,
+		sme_set_thermal_level_callback callback);
+
+void sme_update_tgt_services(tHalHandle hal, struct wma_tgt_services *cfg);
+bool sme_validate_sap_channel_switch(tHalHandle hal,
+		uint16_t sap_ch, eCsrPhyMode sap_phy_mode,
+		uint8_t cc_switch_mode, uint8_t session_id);
+
+bool sme_is_session_id_valid(tHalHandle hal, uint32_t session_id);
+
+#ifdef FEATURE_WLAN_TDLS
+void sme_get_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset,
+		uint8_t *opclass);
+#else
+static inline void
+sme_get_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset,
+		uint8_t *opclass)
+{
+}
+#endif
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+QDF_STATUS sme_gateway_param_update(tHalHandle hHal,
+				struct gateway_param_update_req *request);
+#endif
+
+void sme_update_fine_time_measurement_capab(tHalHandle hal, uint8_t session_id,
+								uint32_t val);
+QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hHal, uint32_t vdev_id);
+QDF_STATUS sme_set_fw_test(struct set_fwtest_params *fw_test);
+QDF_STATUS sme_set_tsfcb(tHalHandle hHal,
+	int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx);
+
+QDF_STATUS sme_reset_tsfcb(tHalHandle h_hal);
+
+#if defined(WLAN_FEATURE_TSF) && !defined(WLAN_FEATURE_TSF_PLUS_NOIRQ)
+QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue);
+#endif
+
+QDF_STATUS sme_update_mimo_power_save(tHalHandle hHal,
+				      uint8_t is_ht_smps_enabled,
+				      uint8_t ht_smps_mode,
+				      bool send_smps_action);
+
+bool sme_is_sta_smps_allowed(tHalHandle hHal, uint8_t session_id);
+QDF_STATUS sme_add_beacon_filter(tHalHandle hal,
+				uint32_t session_id, uint32_t *ie_map);
+QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id);
+
+#ifdef FEATURE_WLAN_APF
+/**
+ * sme_get_apf_capabilities() - Get APF capabilities
+ * @hal: Global HAL handle
+ * @callback: Callback function to be called with the result
+ * @context: Opaque context to be used by the caller to associate the
+ *   request with the response
+ *
+ * This function constructs the cds message and fill in message type,
+ * post the same to WDA.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_get_apf_capabilities(tHalHandle hal,
+				    apf_get_offload_cb callback,
+				    void *context);
+
+/**
+ * sme_set_apf_instructions() - Set APF apf filter instructions.
+ * @hal: HAL handle
+ * @apf_set_offload: struct to set apf filter instructions.
+ *
+ * APFv2 (Legacy APF) API to set the APF packet filter.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_set_apf_instructions(tHalHandle hal,
+				    struct sir_apf_set_offload
+							*apf_set_offload);
+
+/**
+ * sme_set_apf_enable_disable - Send apf enable/disable cmd
+ * @hal: global hal handle
+ * @vdev_id: vdev id
+ * @apf_enable: true: Enable APF Int., false: Disable APF Int.
+ *
+ * API to either enable or disable the APF interpreter.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_set_apf_enable_disable(tHalHandle hal, uint8_t vdev_id,
+				      bool apf_enable);
+
+/**
+ * sme_apf_write_work_memory - Write into the apf work memory
+ * @hal: global hal handle
+ * @write_params: APF parameters for the write operation
+ *
+ * API for writing into the APF work memory.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_apf_write_work_memory(tHalHandle hal,
+				    struct wmi_apf_write_memory_params
+								*write_params);
+
+/**
+ * sme_apf_read_work_memory - Read part of apf work memory
+ * @hal: global hal handle
+ * @read_params: APF parameters for the get operation
+ * @callback: callback to handle the the read response
+ *
+ * API for issuing a APF read memory request.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS
+sme_apf_read_work_memory(tHalHandle hal,
+			 struct wmi_apf_read_memory_params *read_params,
+			 apf_read_mem_cb callback);
+
+#endif /* FEATURE_WLAN_APF */
+
+uint32_t sme_get_wni_dot11_mode(tHalHandle hal);
+QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, uint8_t *bssid,
+				  uint8_t vdev_id);
+QDF_STATUS sme_set_adaptive_dwelltime_config(tHalHandle hal,
+			struct adaptive_dwelltime_params *dwelltime_params);
+
+void sme_set_vdev_ies_per_band(tHalHandle hal, uint8_t vdev_id);
+void sme_set_pdev_ht_vht_ies(tHalHandle hHal, bool enable2x2);
+
+void sme_update_vdev_type_nss(tHalHandle hal, uint8_t max_supp_nss,
+		uint32_t vdev_type_nss, enum band_info band);
+void sme_update_hw_dbs_capable(tHalHandle hal, uint8_t hw_dbs_capable);
+#ifdef FEATURE_P2P_LISTEN_OFFLOAD
+void sme_register_p2p_lo_event(tHalHandle hHal, void *context,
+					p2p_lo_callback callback);
+#else
+static inline void sme_register_p2p_lo_event(tHalHandle hHal,
+					     void *context,
+					     p2p_lo_callback callback)
+{
+}
+#endif
+
+QDF_STATUS sme_remove_bssid_from_scan_list(tHalHandle hal,
+	tSirMacAddr bssid);
+
+QDF_STATUS sme_process_mac_pwr_dbg_cmd(tHalHandle hal, uint32_t session_id,
+				       struct sir_mac_pwr_dbg_cmd*
+				       dbg_args);
+
+void sme_get_vdev_type_nss(enum QDF_OPMODE dev_mode,
+			   uint8_t *nss_2g, uint8_t *nss_5g);
+QDF_STATUS sme_roam_set_default_key_index(tHalHandle hal, uint8_t session_id,
+					  uint8_t default_idx);
+void sme_send_disassoc_req_frame(tHalHandle hal, uint8_t session_id, uint8_t
+				*peer_mac, uint16_t reason, uint8_t
+				wait_for_ack);
+QDF_STATUS sme_update_access_policy_vendor_ie(tHalHandle hal,
+					uint8_t session_id, uint8_t *vendor_ie,
+					int access_policy);
+
+/**
+ * sme_set_peer_param() - set peer param
+ * @vdev_id: vdev ID
+ * @peer_addr: peer MAC address
+ * @param_id: param ID to be updated
+ * @param_Value: paraam value
+ *
+ * This SME API is used to send the peer param to WMA to be sent to FW.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_peer_param(uint8_t *peer_addr, uint32_t param_id,
+			      uint32_t param_value, uint32_t vdev_id);
+
+QDF_STATUS sme_update_sta_roam_policy(tHalHandle hal,
+		enum sta_roam_policy_dfs_mode dfs_mode,
+		bool skip_unsafe_channels,
+		uint8_t session_id, uint8_t sap_operating_band);
+QDF_STATUS sme_enable_disable_chanavoidind_event(tHalHandle hal,
+					uint8_t set_value);
+QDF_STATUS sme_set_default_scan_ie(tHalHandle hal, uint16_t session_id,
+				uint8_t *ie_data, uint16_t ie_len);
+/**
+ * sme_update_session_param() - API to update PE session param
+ * @hal: HAL handle for device
+ * @session_id: Session ID
+ * @param_type: Param type to be updated
+ * @param_val: Param value to be update
+ *
+ * Note: this setting will not persist over reboots.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_update_session_param(tHalHandle hal, uint8_t session_id,
+		uint32_t param_type, uint32_t param_val);
+#ifdef WLAN_FEATURE_FIPS
+/**
+ * sme_fips_request() - Perform a FIPS certification operation
+ * @hal: Hal handle for the object being certified
+ * @param: The FIPS certification parameters
+ * @callback: Callback function to invoke with the results
+ * @context: Opaque context to pass back to caller in the callback
+ *
+ * Return: QDF_STATUS_SUCCESS if the request is successfully sent
+ * to firmware for processing, otherwise an error status.
+ */
+QDF_STATUS sme_fips_request(tHalHandle hal, struct fips_params *param,
+			    wma_fips_cb callback, void *context);
+#else
+static inline
+QDF_STATUS sme_fips_request(tHalHandle hal, struct fips_params *param,
+			    wma_fips_cb callback, void *context)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif /* WLAN_FEATURE_FIPS */
+
+/**
+ * sme_set_cts2self_for_p2p_go() - sme function to set ini parms to FW.
+ * @hal:                    reference to the HAL
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_cts2self_for_p2p_go(tHalHandle hal);
+void sme_set_prefer_80MHz_over_160MHz(tHalHandle hal,
+		bool sta_prefer_80MHz_over_160MHz);
+QDF_STATUS sme_update_tx_fail_cnt_threshold(tHalHandle hal_handle,
+		uint8_t session_id, uint32_t tx_fail_count);
+QDF_STATUS sme_update_short_retry_limit_threshold(tHalHandle hal_handle,
+		struct sme_short_retry_limit *short_retry_limit_th);
+QDF_STATUS sme_update_long_retry_limit_threshold(tHalHandle hal_handle,
+		struct sme_long_retry_limit  *long_retry_limit_th);
+/**
+ * sme_roam_is_ese_assoc() - Check if association type is ESE
+ * @roam_info: Pointer to roam info
+ *
+ * Return: true if ESE Association, false otherwise.
+ */
+#ifdef FEATURE_WLAN_ESE
+bool sme_roam_is_ese_assoc(struct csr_roam_info *roam_info);
+#else
+static inline bool sme_roam_is_ese_assoc(struct csr_roam_info *roam_info)
+{
+	return false;
+}
+#endif
+/**
+ * sme_neighbor_roam_is11r_assoc() - Check if association type is 11R
+ * @hal_ctx: HAL handle
+ * @session_id: session id
+ *
+ * Return: true if 11r Association, false otherwise.
+ */
+bool sme_neighbor_roam_is11r_assoc(tHalHandle hal_ctx, uint8_t session_id);
+
+/**
+ * sme_update_sta_inactivity_timeout(): Update sta_inactivity_timeout to FW
+ * @hal: Handle returned by mac_open
+ * @sta_inactivity_timer:  struct for sta inactivity timer
+ *
+ * If a station does not send anything in sta_inactivity_timeout seconds, an
+ * empty data frame is sent to it in order to verify whether it is
+ * still in range. If this frame is not ACKed, the station will be
+ * disassociated and then deauthenticated.
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure.
+*/
+QDF_STATUS sme_update_sta_inactivity_timeout(tHalHandle hal_handle,
+		struct sme_sta_inactivity_timeout  *sta_inactivity_timer);
+
+/**
+ * sme_set_lost_link_info_cb() - plug in callback function for receiving
+ * @mac_handle: Opaque handle to the MAC context
+ * @cb: callback function
+ *
+ * Return: HAL status
+ */
+QDF_STATUS sme_set_lost_link_info_cb(mac_handle_t mac_handle,
+				     lost_link_info_cb cb);
+
+/**
+ * sme_update_new_channel_event() - update new channel event for sapFsm
+ * @hal: HAL handle
+ * @session_id: session id
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure.
+ */
+QDF_STATUS sme_update_new_channel_event(tHalHandle hal, uint8_t session_id);
+#ifdef WLAN_POWER_DEBUGFS
+QDF_STATUS sme_power_debug_stats_req(tHalHandle hal, void (*callback_fn)
+				(struct  power_stats_response *response,
+				void *context), void *power_stats_context);
+#endif
+
+/**
+ * sme_get_sar_power_limits() - get SAR limits
+ * @hal: HAL handle
+ * @callback: Callback function to invoke with the results
+ * @context: Opaque context to pass back to caller in the callback
+ *
+ * Return: QDF_STATUS_SUCCESS if the request is successfully sent
+ * to firmware for processing, otherwise an error status.
+ */
+QDF_STATUS sme_get_sar_power_limits(tHalHandle hal,
+				    wma_sar_cb callback, void *context);
+
+/**
+ * sme_set_sar_power_limits() - set sar limits
+ * @hal: HAL handle
+ * @sar_limit_cmd: struct to send sar limit cmd.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_set_sar_power_limits(tHalHandle hal,
+		struct sar_limit_cmd_params *sar_limit_cmd);
+
+/**
+ * sme_send_coex_config_cmd() - Send COEX config params
+ * @coex_cfg_params: struct to coex config params
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_send_coex_config_cmd(struct coex_config_params *coex_cfg_params);
+
+void sme_set_cc_src(tHalHandle hal_handle, enum country_src);
+
+
+#ifdef WLAN_FEATURE_WOW_PULSE
+QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info);
+#endif
+
+/* ARP DEBUG STATS */
+QDF_STATUS sme_set_nud_debug_stats(tHalHandle hal,
+				   struct set_arp_stats_params
+				   *set_stats_param);
+QDF_STATUS sme_get_nud_debug_stats(tHalHandle hal,
+				   struct get_arp_stats_params
+				   *get_stats_param);
+QDF_STATUS sme_set_nud_debug_stats_cb(tHalHandle hal,
+			void (*cb)(void *, struct rsp_stats *, void *context),
+			void *context);
+
+/**
+ * sme_set_chan_info_callback() - Register chan info callback
+ * @hal - MAC global handle
+ * @callback_routine - callback routine from HDD
+ *
+ * This API is invoked by HDD to register its callback to mac
+ *
+ * Return: QDF_STATUS
+ */
+void sme_set_chan_info_callback(tHalHandle hal_handle,
+			void (*callback)(struct scan_chan_info *chan_info));
+
+/**
+ * sme_get_rssi_snr_by_bssid() - gets the rssi and snr by bssid from scan cache
+ * @hal: handle returned by mac_open
+ * @profile: current connected profile
+ * @bssid: bssid to look for in scan cache
+ * @rssi: rssi value found
+ * @snr: snr value found
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_get_rssi_snr_by_bssid(tHalHandle hal,
+				     struct csr_roam_profile *profile,
+				     const uint8_t *bssid, int8_t *rssi,
+				     int8_t *snr);
+
+/**
+ * sme_get_beacon_frm() - gets the bss descriptor from scan cache and prepares
+ * beacon frame
+ * @hal: handle returned by mac_open
+ * @profile: current connected profile
+ * @bssid: bssid to look for in scan cache
+ * @frame_buf: frame buffer to populate
+ * @frame_len: length of constructed frame
+ * @channel: Pointer to channel info to be filled
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_get_beacon_frm(tHalHandle hal, struct csr_roam_profile *profile,
+			      const tSirMacAddr bssid,
+			      uint8_t **frame_buf, uint32_t *frame_len,
+			      int *channel);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * sme_fast_reassoc() - invokes FAST REASSOC command
+ * @hal: handle returned by mac_open
+ * @profile: current connected profile
+ * @bssid: bssid to look for in scan cache
+ * @channel: channel on which reassoc should be send
+ * @vdev_id: vdev id
+ * @connected_bssid: bssid of currently connected profile
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_fast_reassoc(tHalHandle hal, struct csr_roam_profile *profile,
+			    const tSirMacAddr bssid, int channel,
+			    uint8_t vdev_id, const tSirMacAddr connected_bssid);
+#endif
+/**
+ * sme_congestion_register_callback() - registers congestion callback
+ * @hal: handler for HAL
+ * @congestion_cb: congestion callback
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_congestion_register_callback(tHalHandle hal,
+					    congestion_cb congestion_cb);
+
+/**
+ * sme_register_tx_queue_cb(): Register tx queue callback
+ * @mac_handle: Opaque handle for MAC context
+ * @tx_queue_cb: Transmit Queues callback
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_register_tx_queue_cb(mac_handle_t mac_handle,
+				    tx_queue_cb tx_queue_cb);
+
+/**
+ * sme_deregister_tx_queue_cb() - Deregister the tx queue callback
+ * @mac_handle: Opaque handle for MAC context
+ *
+ * Return: QDF status
+ */
+QDF_STATUS sme_deregister_tx_queue_cb(mac_handle_t mac_handle);
+
+/**
+ * sme_rso_cmd_status_cb() - Set RSO cmd status callback
+ * @mac_handle: Opaque handle for the MAC context
+ * @cb: HDD Callback to rso command status read
+ *
+ * This function is used to save HDD RSO Command status callback in MAC
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_rso_cmd_status_cb(mac_handle_t mac_handle,
+				 rso_cmd_status_cb cb);
+
+/**
+ * sme_register_set_connection_info_cb() - Register connection
+ * info callback
+ * @hal - MAC global handle
+ * @set_connection_info_cb - callback routine from HDD to set
+ *                   connection info flag
+ * @get_connection_info_cb - callback routine from HDD to get
+ *                         connection info
+ *
+ * This API is invoked by HDD to register its callback to mac
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_register_set_connection_info_cb(tHalHandle hHal,
+				bool (*set_connection_info_cb)(bool),
+				bool (*get_connection_info_cb)(uint8_t *session_id,
+				enum scan_reject_states *reason));
+
+/**
+ * sme_set_dbs_scan_selection_config() - Update DBS scan selection
+ * configuration
+ * @hal: The handle returned by macOpen
+ * @params: wmi_dbs_scan_sel_params config
+ *
+ * Return: QDF_STATUS if DBS scan selection update
+ * configuration success else failure status
+ */
+QDF_STATUS sme_set_dbs_scan_selection_config(tHalHandle hal,
+		struct wmi_dbs_scan_sel_params *params);
+
+/**
+ * sme_store_pdev() - store pdev
+ * @hal - MAC global handle
+ * @pdev - pdev ptr
+ *
+ * Return: QDF_STATUS
+ */
+void sme_store_pdev(tHalHandle hal, struct wlan_objmgr_pdev *pdev);
+
+/**
+ * sme_ipa_uc_stat_request() - set ipa config parameters
+ * @vdev_id: virtual device for the command
+ * @param_id: parameter id
+ * @param_val: parameter value
+ * @req_cat: parameter category
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS sme_ipa_uc_stat_request(tHalHandle hal,
+			uint32_t vdev_id, uint32_t param_id,
+			uint32_t param_val, uint32_t req_cat);
+
+/**
+ * sme_set_reorder_timeout() - set reorder timeout value
+ * including Voice,Video,Besteffort,Background parameters
+ * @hal: hal handle for getting global mac struct
+ * @reg: struct sir_set_rx_reorder_timeout_val
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure.
+ */
+QDF_STATUS sme_set_reorder_timeout(tHalHandle hal,
+		struct sir_set_rx_reorder_timeout_val *req);
+
+/**
+ * sme_set_rx_set_blocksize() - set blocksize value
+ * including mac_addr and win_limit parameters
+ * @hal: hal handle for getting global mac struct
+ * @reg: struct sir_peer_set_rx_blocksize
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure.
+ */
+
+QDF_STATUS sme_set_rx_set_blocksize(tHalHandle hal,
+		struct sir_peer_set_rx_blocksize *req);
+
+/**
+ * sme_get_rcpi() - gets the rcpi value for peer mac addr
+ * @hal: handle returned by mac_open
+ * @rcpi: rcpi request containing peer mac addr, callback and related info
+ *
+ * This function posts the rcpi measurement request message to wma queue
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_get_rcpi(tHalHandle hal, struct sme_rcpi_req *rcpi);
+
+/**
+ * sme_set_chip_pwr_save_fail_cb() - set chip power save failure callback
+ * @mac_handle: opaque handle to the MAC context
+ * @cb: callback function pointer
+ *
+ * This function stores the chip power save failure callback function.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+
+QDF_STATUS sme_set_chip_pwr_save_fail_cb(mac_handle_t mac_handle,
+					 pwr_save_fail_cb cb);
+/**
+ * sme_cli_set_command() - SME wrapper API over WMA "set" command
+ * processor cmd
+ * @vdev_id: virtual device for the command
+ * @param_id: parameter id
+ * @sval: parameter value
+ * @vpdev: parameter category
+ *
+ * Command handler for set operations
+ *
+ * Return: 0 on success, errno on failure
+ */
+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
+ * @mac_handle: handle returned by mac_open
+ * @cb: callback handler
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_bt_activity_info_cb(mac_handle_t mac_handle,
+				       bt_activity_info_cb cb);
+
+/**
+ * sme_set_enable_mem_deep_sleep - set the mem deep sleep config to FW
+ * @mac_handle: handle returned by mac_open
+ * @vdev_id: vdev id
+ *
+ * Return: 0 for success else failure code
+ */
+int sme_set_enable_mem_deep_sleep(mac_handle_t mac_handle, int vdev_id);
+
+/**
+ * sme_set_cck_tx_fir_override - set the CCK TX FIR Override to FW
+ * @mac_handle: handle returned by mac_open
+ * @vdev_id: vdev id
+ *
+ * Return: 0 for success else failure code
+ */
+int sme_set_cck_tx_fir_override(mac_handle_t mac_handle, int vdev_id);
+
+/**
+ * sme_set_smps_cfg() - set SMPS config params
+ * @vdev_id: virtual device for the command
+ * @param_id: parameter id
+ * @param_val: parameter value
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+
+QDF_STATUS sme_set_smps_cfg(uint32_t vdev_id, uint32_t param_id,
+				uint32_t param_val);
+
+/**
+ * sme_get_peer_stats() - sme api to post peer info request
+ * @mac: mac handle
+ * @req: peer info request struct send to wma
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+
+QDF_STATUS sme_get_peer_stats(tpAniSirGlobal mac,
+			      struct sir_peer_info_req req);
+
+/**
+ * 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));
+
+/**
+ * sme_get_chain_rssi() - Get chain rssi
+ * @hal: Global HAL handle
+ * @input: get chain rssi req params
+ * @callback: Callback function to be called with the result
+ * @context: Opaque context to be used by the caller to associate the
+ *   request with the response
+ *
+ * This function constructs the cds message and fill in message type,
+ * post the same to WDA.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_get_chain_rssi(tHalHandle hal,
+			      struct get_chain_rssi_req_params *input,
+			      get_chain_rssi_callback callback,
+			      void *context);
+
+/**
+ * sme_get_valid_channels() - sme api to get valid channels for
+ * current regulatory domain
+ * @chan_list: list of the valid channels
+ * @list_len: length of the channel list
+ *
+ * This function will get valid channels for current regulatory
+ * domain
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS sme_get_valid_channels(uint8_t *chan_list, uint32_t *list_len);
+
+/**
+ * sme_get_mac_context() - sme api to get the pmac context
+ *
+ * This function will return the pmac context
+ *
+ * Return: pointer to pmac context
+ */
+tpAniSirGlobal sme_get_mac_context(void);
+
+/**
+ * sme_display_disconnect_stats() - Display per session Disconnect stats
+ * @hal: hal global context
+ * session_id: SME session id
+ *
+ * Return: None
+ */
+void sme_display_disconnect_stats(tHalHandle hal, uint8_t session_id);
+
+/**
+ * sme_process_msg_callback() - process callback message from LIM
+ * @mac: global mac context
+ * @msg: scheduler message
+ *
+ * This function process the callback messages from LIM.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_process_msg_callback(tpAniSirGlobal mac,
+				    struct scheduler_msg *msg);
+
+/**
+ * sme_set_bmiss_bcnt() - set bmiss config parameters
+ * @vdev_id: virtual device for the command
+ * @first_cnt: bmiss first value
+ * @final_cnt: bmiss final value
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS sme_set_bmiss_bcnt(uint32_t vdev_id, uint32_t first_cnt,
+		uint32_t final_cnt);
+
+/**
+ * sme_send_limit_off_channel_params() - send limit off channel parameters
+ * @hal: global hal handle
+ * @vdev_id: vdev id
+ * @is_tos_active: tos active or inactive
+ * @max_off_chan_time: max off channel time
+ * @rest_time: rest time
+ * @skip_dfs_chan: skip dfs channel
+ *
+ * This function sends command to WMA for setting limit off channel command
+ * parameters.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_send_limit_off_channel_params(tHalHandle hal, uint8_t vdev_id,
+		bool is_tos_active, uint32_t max_off_chan_time,
+		uint32_t rest_time, bool skip_dfs_chan);
+
+#ifdef FEATURE_WLAN_DYNAMIC_CVM
+/**
+ * sme_set_vc_mode_config() - Set voltage corner config to FW.
+ * @bitmap:	Bitmap that refers to voltage corner config with
+ * different phymode and bw configuration
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_vc_mode_config(uint32_t vc_bitmap);
+#endif
+
+/**
+ * sme_set_del_pmkid_cache() - API to update PMKID cache
+ * @hal: HAL handle for device
+ * @session_id: Session id
+ * @pmk_cache_info: Pointer to PMK cache info
+ * @is_add: boolean that implies whether to add or delete PMKID entry
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_del_pmkid_cache(tHalHandle hal, uint8_t session_id,
+				   tPmkidCacheInfo *pmk_cache_info,
+				   bool is_add);
+
+/**
+ * sme_send_hlp_ie_info() - API to send HLP IE info to fw
+ * @hal: HAL handle for device
+ * @session_id: Session id
+ * @profile: CSR Roam profile
+ * @if_addr: IP address
+ *
+ * This API is used to send HLP IE info along with IP address
+ * to fw if LFR3 is enabled.
+ *
+ * Return: QDF_STATUS
+ */
+void sme_send_hlp_ie_info(tHalHandle hal, uint8_t session_id,
+			  struct csr_roam_profile *profile, uint32_t if_addr);
+
+#if defined(WLAN_FEATURE_FILS_SK)
+/**
+ * sme_update_fils_config - Update FILS config to CSR roam session
+ * @hal: HAL handle for device
+ * @session_id: session id
+ * @src_profile: Source profile having latest FILS config
+ *
+ * API to update FILS config to roam csr session and update the same
+ * to fw if LFR3 is enabled.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_update_fils_config(tHalHandle hal, uint8_t session_id,
+				struct csr_roam_profile *src_profile);
+
+/**
+ * sme_free_join_rsp_fils_params - free fils params
+ * @roam_info: roam info
+ *
+ * Return: void
+ */
+void sme_free_join_rsp_fils_params(struct csr_roam_info *roam_info);
+#else
+static inline QDF_STATUS sme_update_fils_config(tHalHandle hal,
+				uint8_t session_id,
+				struct csr_roam_profile *src_profile)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+void sme_free_join_rsp_fils_params(struct csr_roam_info *roam_info)
+{}
+
+#endif
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+/**
+ * sme_set_he_bss_color() - Sets the HE BSS color
+ *
+ * @hal: The handle returned by mac_open
+ * @session_id: session_id of the request
+ * @bss_color: HE BSS color value to set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_he_bss_color(tHalHandle hal, uint8_t session_id,
+		uint8_t bss_color);
+#else
+static inline QDF_STATUS sme_set_he_bss_color(tHalHandle hal,
+		uint8_t session_id, uint8_t bss_color)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * sme_is_conn_state_connected() -- check if SME connection state is connected
+ * @hal: global hal handle
+ * @session_id: current Session Id
+ *
+ * This API checks if the current SME connection state is connected for the
+ * given session id.
+ *
+ * Return: True if connected, false if any other state.
+ */
+bool sme_is_conn_state_connected(mac_handle_t hal, uint8_t session_id);
+
+/**
+ * sme_scan_get_result_for_bssid - gets the scan result from scan cache for the
+ * bssid specified
+ * @hal: handle returned by mac_open
+ * @bssid: bssid to get the scan result for
+ * @res: pointer to tCsrScanResultInfo allocated from caller
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_scan_get_result_for_bssid(tHalHandle hal_handle,
+					 struct qdf_mac_addr *bssid,
+					 tCsrScanResultInfo *res);
+
+/**
+ * sme_get_bss_transition_status() - get bss transition status all cadidates
+ * @hal: handle returned by mac_open
+ * @transition_reason : Transition reason
+ * @bssid: bssid to get BSS transition status
+ * @info : bss candidate information
+ * @n_candidates : number of candidates
+ * @is_bt_in_progress: bt activity indicator
+ *
+ * Return : 0 on success otherwise errno
+ */
+int sme_get_bss_transition_status(tHalHandle hal,
+		uint8_t transition_reason,
+		struct qdf_mac_addr *bssid,
+		struct bss_candidate_info *info,
+		uint16_t n_candidates,
+		bool is_bt_in_progress);
+
+/**
+ * sme_unpack_rsn_ie: wrapper to unpack RSN IE and update def RSN params
+ * if optional fields are not present.
+ * @hal: handle returned by mac_open
+ * @buf: rsn ie buffer pointer
+ * @buf_len: rsn ie buffer length
+ * @rsn_ie: outframe rsn ie structure
+ * @append_ie: flag to indicate if the rsn_ie need to be appended from buf
+ *
+ * Return: parse status
+ */
+uint32_t sme_unpack_rsn_ie(tHalHandle hal, uint8_t *buf,
+				  uint8_t buf_len, tDot11fIERSN *rsn_ie,
+				  bool append_ie);
+/**
+ * sme_get_oper_chan_freq - gets the operating channel freq
+ * @vdev: vdev handle
+ *
+ * Return: operating channel frequency
+ */
+int16_t sme_get_oper_chan_freq(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * sme_get_oper_ch_width - gets the operating channel width
+ * @vdev: vdev handle
+ *
+ * Return: operating channel width
+ */
+enum phy_ch_width sme_get_oper_ch_width(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * sme_get_oper_ch_width - gets the secondary channel frequency
+ * @vdev: vdev handle
+ * @sec20chan_freq: secondary channel frequency
+ *
+ * Return: secondary channel frequency
+ */
+int sme_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev,
+						uint16_t *sec20chan_freq);
+
+/**
+ * sme_enable_roaming_on_connected_sta() - Enable roaming on an connected sta
+ * @hal: handle returned by mac_open
+ *
+ * The function check if any connected STA is present on which roaming is not
+ * enabled and if present enabled roaming on that STA.
+ *
+ * Return: none
+ */
+void sme_enable_roaming_on_connected_sta(tHalHandle hal);
+
+/**
+ * sme_send_mgmt_tx() - Sends mgmt frame from CSR to LIM
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @buf: pointer to frame
+ * @len: frame length
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
+			   const uint8_t *buf, uint32_t len);
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * sme_handle_sae_msg() - Sends SAE message received from supplicant
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @sae_status: status of SAE authentication
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
+		uint8_t sae_status);
+#else
+static inline QDF_STATUS sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
+		uint8_t sae_status)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * sme_set_ba_buff_size() - sets BA buffer size
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @buff_size: BA buffer size
+ *
+ * Return: 0 on success else err code
+ */
+int sme_set_ba_buff_size(tHalHandle hal, uint8_t session_id,
+		uint16_t buff_size);
+
+/**
+ * sme_send_addba_req() - send ADDBA request with user config
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @tid: tid val for BA session
+ * @buff_size: BA buffer size
+ *
+ * Return: 0 on success else err code
+ */
+int sme_send_addba_req(tHalHandle hal, uint8_t session_id, uint8_t tid,
+		uint16_t buff_size);
+
+/**
+ * sme_set_no_ack_policy() - Sets no ack policy for AC
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @val: no ack policy value
+ * @ac: access category
+ *
+ * Return: 0 on success else err code
+ */
+int sme_set_no_ack_policy(tHalHandle hal, uint8_t session_id,
+		uint8_t val, uint8_t ac);
+
+/**
+ * sme_set_auto_rate_he_sgi() - Sets SGI for auto rate
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @cfg_val: SGI configuration value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_set_auto_rate_he_sgi(tHalHandle hal, uint8_t session_id,
+		uint8_t cfg_val);
+
+/**
+ * sme_set_auto_rate_he_ltf() - Sets HE LTF for auto rate
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @cfg_val: LTF configuration value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_set_auto_rate_he_ltf(tHalHandle hal, uint8_t session_id,
+		uint8_t cfg_val);
+
+#ifdef WLAN_FEATURE_11AX
+/**
+ * sme_update_tgt_he_cap() - sets the HE caps to pmac
+ * @mac_handle: Pointer to MAC handle
+ * @cfg: Pointer to WMA target CFG
+ * @he_cap_ini: Pointer to HE CAP configured by INI
+ *
+ * Return: None
+ */
+void sme_update_tgt_he_cap(mac_handle_t mac_handle,
+			   struct wma_tgt_cfg *cfg,
+			   tDot11fIEhe_cap *he_cap_ini);
+
+/**
+ * sme_update_he_cap_nss() - sets the nss based on user request
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @nss: no.of spatial streams value
+ *
+ * Return: None
+ */
+void sme_update_he_cap_nss(tHalHandle hal, uint8_t session_id,
+		uint8_t nss);
+
+/**
+ * sme_update_he_tx_bfee_supp() - sets the HE Tx Bfee support
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @cfg_val: Tx Bfee config value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_he_tx_bfee_supp(tHalHandle hal, uint8_t session_id,
+		uint8_t cfg_val);
+
+/**
+ * sme_update_he_tx_bfee_nsts() - sets the HE Tx Bfee NSTS
+ * @hal: MAC handle
+ * @session_id: SME session id
+ * @cfg_val: Tx Bfee NSTS value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_he_tx_bfee_nsts(mac_handle_t hal, uint8_t session_id,
+			       uint8_t cfg_val);
+
+/**
+ * sme_set_he_tx_bf_cbf_rates() - sets the HE Tx Bfee CBF frame rates to FW
+ * @session_id: SME session id
+ *
+ * Return: None
+ */
+void sme_set_he_tx_bf_cbf_rates(uint8_t session_id);
+
+/**
+ * sme_config_su_ppdu_queue() - Configures SU PPDU queue enable/disable in FW
+ * @session_id: SME session id
+ * @enable: Enable/Disable config
+ *
+ * Return: None
+ */
+void sme_config_su_ppdu_queue(uint8_t session_id, bool enable);
+
+/**
+ * sme_update_he_mcs() - sets the HE MCS based on user request
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @he_mcs: HE MCS value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_he_mcs(tHalHandle hal, uint8_t session_id, uint16_t he_mcs);
+
+/**
+ * sme_update_he_trigger_frm_mac_pad() - sets the HE MAC padding capability
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @cfg_val: HE MAC padding duration value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_he_trigger_frm_mac_pad(mac_handle_t hal, uint8_t session_id,
+				      uint8_t cfg_val);
+
+/**
+ * sme_update_he_om_ctrl_supp() - sets the HE OM control capability
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @cfg_val: HE OM control config
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_he_om_ctrl_supp(mac_handle_t hal, uint8_t session_id,
+			       uint8_t cfg_val);
+
+#define NUM_OM_CTRL_UPDATE_CFG_PARAMS 7
+#define OM_CTRL_CMD_MAC_BITS31 1
+#define OM_CTRL_CMD_MAC_BITS47 2
+#define OM_CTRL_CMD_RX_NSS 3
+#define OM_CTRL_CMD_BW 4
+#define OM_CTRL_CMD_ULMU 5
+#define OM_CTRL_CMD_TX_NSS 6
+int sme_send_he_om_ctrl_bw_update(mac_handle_t hal, uint8_t session_id,
+				  uint8_t cfg_val);
+
+int sme_send_he_om_ctrl_nss_update(mac_handle_t hal, uint8_t session_id,
+				   uint8_t cfg_val);
+
+void sme_reset_he_om_ctrl(mac_handle_t hal);
+
+/**
+ * sme_set_usr_cfg_mu_edca() - sets the user cfg MU EDCA params flag
+ * @hal: Pointer to HAL
+ * @val: value to be set
+ *
+ * Return: none
+ */
+void sme_set_usr_cfg_mu_edca(mac_handle_t hal, bool val);
+
+/**
+ * sme_set_he_mu_edca_def_cfg() - sets the default MU EDCA params values
+ * @hal: Pointer to HAL
+ *
+ * Return: none
+ */
+void sme_set_he_mu_edca_def_cfg(mac_handle_t hal);
+
+/**
+ * sme_update_mu_edca_params() - updates MU EDCA params values
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_mu_edca_params(mac_handle_t hal, uint8_t session_id);
+
+/**
+ * sme_update_he_tx_stbc_cap() - Sets the HE Tx STBC capability
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @value: set value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_he_tx_stbc_cap(tHalHandle hal, uint8_t session_id, int value);
+
+/**
+ * sme_update_he_rx_stbc_cap() - Sets the HE Rx STBC capability
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @value: set value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_he_rx_stbc_cap(tHalHandle hal, uint8_t session_id, int value);
+
+/**
+ * sme_update_he_frag_supp() - sets the HE fragmentation support
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @he_frag: HE fragmention support value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_he_frag_supp(tHalHandle hal, uint8_t session_id,
+		uint16_t he_frag);
+
+/**
+ * sme_update_he_ldpc_supp() - sets the HE LDPC support
+ * @hal: Pointer to HAL
+ * @session_id: SME session id
+ * @he_ldpc: HE LDPC support value
+ *
+ * Return: 0 on success else err code
+ */
+int sme_update_he_ldpc_supp(tHalHandle hal, uint8_t session_id,
+			    uint16_t he_ldpc);
+#else
+static inline void sme_update_tgt_he_cap(mac_handle_t mac_handle,
+					 struct wma_tgt_cfg *cfg,
+					 tDot11fIEhe_cap *he_cap_ini)
+{}
+static inline void sme_update_he_cap_nss(tHalHandle hal, uint8_t session_id,
+		uint8_t nss)
+{}
+static inline int sme_update_he_mcs(tHalHandle hal, uint8_t session_id,
+				    uint16_t he_mcs)
+{
+	return 0;
+}
+
+static inline void sme_set_he_mu_edca_def_cfg(mac_handle_t hal)
+{
+}
+
+static inline int sme_update_mu_edca_params(mac_handle_t hal,
+					    uint8_t session_id)
+{
+	return 0;
+}
+static inline int sme_update_he_trigger_frm_mac_pad(mac_handle_t hal,
+						    uint8_t session_id,
+						    uint8_t cfg_val)
+{
+	return 0;
+}
+
+static inline int sme_update_he_om_ctrl_supp(mac_handle_t hal,
+					     uint8_t session_id,
+					     uint8_t cfg_val)
+{
+	return 0;
+}
+
+static inline int sme_send_he_om_ctrl_bw_update(mac_handle_t hal,
+						uint8_t session_id,
+						uint8_t cfg_val)
+{
+	return 0;
+}
+
+static inline int sme_send_he_om_ctrl_nss_update(mac_handle_t hal,
+						 uint8_t session_id,
+						 uint8_t cfg_val)
+{
+	return 0;
+}
+
+static inline void sme_reset_he_om_ctrl(mac_handle_t hal)
+{
+}
+
+static inline void sme_set_usr_cfg_mu_edca(mac_handle_t hal, bool val)
+{
+}
+
+static inline int sme_update_he_tx_stbc_cap(tHalHandle hal, uint8_t session_id,
+					    int value)
+{
+	return 0;
+}
+
+static inline int sme_update_he_rx_stbc_cap(tHalHandle hal, uint8_t session_id,
+					    int value)
+{
+	return 0;
+}
+
+static inline int sme_update_he_frag_supp(tHalHandle hal, uint8_t session_id,
+		uint16_t he_frag)
+{
+	return 0;
+}
+
+static inline int sme_update_he_ldpc_supp(tHalHandle hal, uint8_t session_id,
+					  uint16_t he_ldpc)
+{
+	return 0;
+}
+
+static inline int sme_update_he_tx_bfee_supp(tHalHandle hal, uint8_t session_id,
+		uint8_t cfg_val)
+{
+	return 0;
+}
+static inline int sme_update_he_tx_bfee_nsts(mac_handle_t hal, uint8_t session_id,
+					     uint8_t cfg_val)
+{
+	return 0;
+}
+
+static inline void sme_set_he_tx_bf_cbf_rates(uint8_t session_id)
+{
+}
+
+static inline void sme_config_su_ppdu_queue(uint8_t session_id, bool enable)
+{
+}
+#endif
+
+/**
+ * sme_is_sta_key_exchange_in_progress() - checks whether the STA/P2P client
+ * session has key exchange in progress
+ *
+ * @hal: global hal handle
+ * @session_id: session id
+ *
+ * Return: true - if key exchange in progress
+ *         false - if not in progress
+ */
+bool sme_is_sta_key_exchange_in_progress(tHalHandle hal, uint8_t session_id);
+
+/*
+ * sme_validate_channel_list() - Validate the given channel list
+ * @hal: handle to global hal context
+ * @chan_list: Pointer to the channel list
+ * @num_channels: number of channels present in the chan_list
+ *
+ * Validates the given channel list with base channels in mac context
+ *
+ * Return: True if all channels in the list are valid, false otherwise
+ */
+bool sme_validate_channel_list(tHalHandle hal,
+				      uint8_t *chan_list,
+				      uint8_t num_channels);
+/**
+ * sme_set_amsdu() - set amsdu enable/disable based on user cfg
+ * @hal: Pointer to HAL
+ * @enable: enable or disable
+ *
+ * Return: None
+ */
+void sme_set_amsdu(tHalHandle hal, bool enable);
+
+/**
+ * sme_get_mcs_idx() - gets mcs index
+ * @max_rate: max rate
+ * @rate_flags: rate flags
+ * @nss: number of nss
+ * @mcs_rate_flags: mcs rate flag
+ *
+ * Return: return mcs index
+ */
+uint8_t sme_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
+			uint8_t *nss, uint8_t *mcs_rate_flags);
+
+#ifdef WLAN_SUPPORT_TWT
+/**
+ * sme_register_twt_enable_complete_cb() - TWT enable registrar
+ * @mac_handle: MAC handle
+ * @twt_enable_cb: Function callback to handle enable event
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS sme_register_twt_enable_complete_cb(mac_handle_t mac_handle,
+					       twt_enable_cb twt_enable_cb);
+
+/**
+ * sme_register_twt_disable_complete_cb - TWT disable registrar
+ * @mac_handle: MAC handle
+ * @twt_disable_cb: Function callback to handle disable event
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS sme_register_twt_disable_complete_cb(mac_handle_t mac_handle,
+						twt_disable_cb twt_disable_cb);
+
+/**
+ * sme_deregister_twt_enable_complete_cb() - TWT enable deregistrar
+ * @hal: HAL handle
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS sme_deregister_twt_enable_complete_cb(mac_handle_t mac_handle);
+
+/**
+ * sme_deregister_twt_disable_complete_cb - TWT disable deregistrar
+ * @hal: HAL handle
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS sme_deregister_twt_disable_complete_cb(mac_handle_t mac_handle);
+
+#else
+static inline
+QDF_STATUS sme_register_twt_enable_complete_cb(mac_handle_t mac_handle,
+					       twt_enable_cb twt_enable_cb)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS sme_register_twt_disable_complete_cb(mac_handle_t mac_handle,
+						twt_disable_cb twt_disable_cb)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS sme_deregister_twt_enable_complete_cb(mac_handle_t mac_handle)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS sme_deregister_twt_disable_complete_cb(mac_handle_t mac_handle)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * sme_find_session_by_bssid() - checks whether has session
+ * with given bssid
+ * @hal: global hal handle
+ * @bssid: bssid
+ * Return: true - if has the session
+ *         false - if not has the session
+ */
+bool sme_find_session_by_bssid(tHalHandle hal, uint8_t *bssid);
+
+/**
+ * sme_get_roam_scan_stats() - Send roam scan stats cmd to wma
+ * @hal: handle returned by mac_open
+ * @cb: call-back invoked for roam scan stats response
+ * @context: context of callback
+ * @vdev_id: vdev id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+sme_get_roam_scan_stats(tHalHandle hal, roam_scan_stats_cb cb, void *context,
+			uint32_t vdev_id);
+
+/**
+ * sme_update_score_config() - Update the Scoring Config from MLME
+ * @hal: Mac Handle
+ * @score_config: Pointer to the scoring config structure to be populated
+ *
+ * Return: None
+ */
+void sme_update_score_config(tHalHandle hal,
+			     struct scoring_config *score_config);
+#endif /* #if !defined( __SME_API_H ) */
diff --git a/core/sme/inc/sme_ft_api.h b/core/sme/inc/sme_ft_api.h
new file mode 100644
index 0000000..b063c83
--- /dev/null
+++ b/core/sme/inc/sme_ft_api.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2013-2016 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.
+ */
+
+#if !defined(__SME_FTAPI_H)
+#define __SME_FTAPI_H
+
+typedef enum eFTIEState {
+	eFT_START_READY,        /* Start before and after 11r assoc */
+	eFT_AUTH_REQ_READY,     /* When we have recvd the 1st or nth auth req */
+	/*
+	 * Sent auth1 and waiting auth2 We are now ready for FT phase,
+	 * send auth1, recd auth2
+	 */
+	eFT_WAIT_AUTH2,
+	eFT_AUTH_COMPLETE,
+	/* Now we have sent Auth Rsp to the supplicant and waiting */
+	/* Reassoc Req from the supplicant. */
+	eFT_REASSOC_REQ_WAIT,
+	/*
+	 * We have received the Reassoc request from supplicant.
+	 * Waiting for the keys.
+	 */
+	eFT_SET_KEY_WAIT,
+} tFTIEStates;
+
+/* FT neighbor roam callback user context */
+typedef struct sFTRoamCallbackUsrCtx {
+	tpAniSirGlobal pMac;
+	uint8_t sessionId;
+} tFTRoamCallbackUsrCtx, *tpFTRoamCallbackUsrCtx;
+
+typedef struct sFTSMEContext {
+	/* Received and processed during pre-auth */
+	uint8_t *auth_ft_ies;
+	uint32_t auth_ft_ies_length;
+	/* Received and processed during re-assoc */
+	uint8_t *reassoc_ft_ies;
+	uint16_t reassoc_ft_ies_length;
+	/* Pre-Auth info */
+	tFTIEStates FTState;    /* The state of FT in the current 11rAssoc */
+	tSirMacAddr preAuthbssId;       /* BSSID to preauth to */
+	uint32_t smeSessionId;
+	/* Saved pFTPreAuthRsp */
+	tpSirFTPreAuthRsp psavedFTPreAuthRsp;
+	bool setFTPreAuthState;
+	bool setFTPTKState;
+	/* Time to trigger reassoc once pre-auth is successful */
+	qdf_mc_timer_t preAuthReassocIntvlTimer;
+	bool addMDIE;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	uint32_t r0kh_id_len;
+	uint8_t r0kh_id[SIR_ROAM_R0KH_ID_MAX_LEN];
+#endif
+	/* User context for the timer callback */
+	tpFTRoamCallbackUsrCtx pUsrCtx;
+} tftSMEContext, *tpftSMEContext;
+
+/*--------------------------------------------------------------------------
+  Prototype functions
+  ------------------------------------------------------------------------*/
+void sme_ft_open(tHalHandle hHal, uint32_t sessionId);
+void sme_ft_close(tHalHandle hHal, uint32_t sessionId);
+void sme_ft_reset(tHalHandle hHal, uint32_t sessionId);
+void sme_set_ft_ies(tHalHandle hHal, uint32_t sessionId, const uint8_t *ft_ies,
+		uint16_t ft_ies_length);
+QDF_STATUS sme_ft_update_key(tHalHandle hHal, uint32_t sessionId,
+		tCsrRoamSetKey *pFTKeyInfo);
+void sme_get_ft_pre_auth_response(tHalHandle hHal, uint32_t sessionId,
+		uint8_t *ft_ies, uint32_t ft_ies_ip_len,
+		uint16_t *ft_ies_length);
+void sme_get_rici_es(tHalHandle hHal, uint32_t sessionId, uint8_t *ric_ies,
+		uint32_t ric_ies_ip_len, uint32_t *ric_ies_length);
+void sme_preauth_reassoc_intvl_timer_callback(void *context);
+void sme_set_ft_pre_auth_state(tHalHandle hHal, uint32_t sessionId, bool state);
+bool sme_get_ft_pre_auth_state(tHalHandle hHal, uint32_t sessionId);
+bool sme_get_ftptk_state(tHalHandle hHal, uint32_t sessionId);
+void sme_set_ftptk_state(tHalHandle hHal, uint32_t sessionId, bool state);
+#endif
diff --git a/core/sme/inc/sme_inside.h b/core/sme/inc/sme_inside.h
new file mode 100644
index 0000000..34875e6
--- /dev/null
+++ b/core/sme/inc/sme_inside.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#if !defined(__SMEINSIDE_H)
+#define __SMEINSIDE_H
+
+/**
+ * \file  sme_inside.h
+ *
+ * \brief prototype for SME structures and APIs used insside SME
+ */
+
+/*--------------------------------------------------------------------------
+  Include Files
+  ------------------------------------------------------------------------*/
+#include "qdf_status.h"
+#include "qdf_lock.h"
+#include "qdf_trace.h"
+#include "qdf_mem.h"
+#include "qdf_types.h"
+#include "sir_api.h"
+#include "csr_internal.h"
+#include "sme_qos_api.h"
+#include "sme_qos_internal.h"
+
+#include "sme_rrm_api.h"
+#include "wlan_serialization_legacy_api.h"
+ePhyChanBondState csr_convert_cb_ini_value_to_phy_cb_state(uint32_t cbIniValue);
+
+/*--------------------------------------------------------------------------
+  Type declarations
+  ------------------------------------------------------------------------*/
+/*
+ * In case MAX num of STA are connected to SAP, switching off SAP causes
+ * two SME cmd to be enqueued for each STA. Keeping SME total cmds as following
+ * to make sure we have space for these cmds + some additional cmds.
+ */
+#define SME_TOTAL_COMMAND                (HAL_NUM_STA * 3)
+/* default sme timeout is set to 30 secs */
+#define SME_DEFAULT_CMD_TIMEOUT  30000
+
+typedef struct sGenericQosCmd {
+	struct sme_qos_wmmtspecinfo tspecInfo;
+	sme_QosEdcaAcType ac;
+	uint8_t tspec_mask;
+} tGenericQosCmd;
+
+typedef struct sRemainChlCmd {
+	uint8_t chn;
+	uint8_t phyMode;
+	uint32_t duration;
+	uint8_t isP2PProbeReqAllowed;
+	uint32_t scan_id;
+	void *callback;
+	void *callbackCtx;
+} tRemainChlCmd;
+
+#ifdef FEATURE_WLAN_TDLS
+typedef struct TdlsSendMgmtInfo {
+	tSirMacAddr peerMac;
+	uint8_t frameType;
+	uint8_t dialog;
+	uint16_t statusCode;
+	uint8_t responder;
+	uint32_t peerCapability;
+	uint8_t *buf;
+	uint8_t len;
+	enum wifi_traffic_ac ac;
+} tTdlsSendMgmtCmdInfo;
+
+typedef struct TdlsLinkEstablishInfo {
+	struct qdf_mac_addr peermac;
+	uint8_t uapsdQueues;
+	uint8_t maxSp;
+	uint8_t isBufSta;
+	uint8_t isOffChannelSupported;
+	uint8_t isResponder;
+	uint8_t supportedChannelsLen;
+	uint8_t supportedChannels[SIR_MAC_MAX_SUPP_CHANNELS];
+	uint8_t supportedOperClassesLen;
+	uint8_t supportedOperClasses[REG_MAX_SUPP_OPER_CLASSES];
+} tTdlsLinkEstablishCmdInfo;
+
+typedef struct TdlsAddStaInfo {
+	eTdlsAddOper tdlsAddOper;
+	struct qdf_mac_addr peermac;
+	uint16_t capability;
+	uint8_t extnCapability[SIR_MAC_MAX_EXTN_CAP];
+	uint8_t supportedRatesLen;
+	uint8_t supportedRates[SIR_MAC_MAX_SUPP_RATES];
+	uint8_t htcap_present;
+	tSirHTCap HTCap;
+	uint8_t vhtcap_present;
+	tSirVHTCap VHTCap;
+	uint8_t uapsdQueues;
+	uint8_t maxSp;
+} tTdlsAddStaCmdInfo;
+
+typedef struct TdlsDelStaInfo {
+	struct qdf_mac_addr peermac;
+} tTdlsDelStaCmdInfo;
+/*
+ * TDLS cmd info, CMD from SME to PE.
+ */
+typedef struct s_tdls_cmd {
+	uint32_t size;
+	union {
+		tTdlsLinkEstablishCmdInfo tdlsLinkEstablishCmdInfo;
+		tTdlsSendMgmtCmdInfo tdlsSendMgmtCmdInfo;
+		tTdlsAddStaCmdInfo tdlsAddStaCmdInfo;
+		tTdlsDelStaCmdInfo tdlsDelStaCmdInfo;
+	} u;
+} tTdlsCmd;
+#endif /* FEATURE_WLAN_TDLS */
+
+/**
+ * struct s_nss_update_cmd - Format of nss update request
+ * @new_nss: new nss value
+ * @session_id: Session ID
+ * @set_hw_mode_cb: HDD nss update callback
+ * @context: Adapter context
+ * @next_action: Action to be taken after nss update
+ * @reason: reason for nss update
+ * @original_vdev_id: original request hwmode change vdev id
+ */
+struct s_nss_update_cmd {
+	uint32_t new_nss;
+	uint32_t session_id;
+	void *nss_update_cb;
+	void *context;
+	uint8_t next_action;
+	enum policy_mgr_conn_update_reason reason;
+	uint32_t original_vdev_id;
+};
+
+typedef struct tagSmeCmd {
+	tListElem Link;
+	eSmeCommandType command;
+	uint32_t cmd_id;
+	uint32_t sessionId;
+	union {
+		struct roam_cmd roamCmd;
+		struct wmstatus_changecmd wmStatusChangeCmd;
+		tGenericQosCmd qosCmd;
+		tRemainChlCmd remainChlCmd;
+		struct addstafor_sessioncmd addStaSessionCmd;
+		struct delstafor_sessionCmd delStaSessionCmd;
+#ifdef FEATURE_WLAN_TDLS
+		tTdlsCmd tdlsCmd;
+#endif
+		struct policy_mgr_hw_mode set_hw_mode_cmd;
+		struct s_nss_update_cmd nss_update_cmd;
+		struct policy_mgr_dual_mac_config set_dual_mac_cmd;
+		struct sir_antenna_mode_param set_antenna_mode_cmd;
+	} u;
+} tSmeCmd;
+
+/*--------------------------------------------------------------------------
+  Internal to SME
+  ------------------------------------------------------------------------*/
+/**
+ * csr_get_cmd_type() - to convert sme command type to serialization cmd type
+ * @sme_cmd: sme command pointer
+ *
+ * This API will convert SME command type to serialization command type which
+ * new serialization module understands
+ *
+ * Return: serialization cmd type based on sme command type
+ */
+enum wlan_serialization_cmd_type csr_get_cmd_type(tSmeCmd *sme_cmd);
+/**
+ * csr_set_serialization_params_to_cmd() - take sme params and create new
+ *						serialization command
+ * @mac_ctx: pointer to mac context
+ * @sme_cmd: sme command pointer
+ * @cmd: serialization command pointer
+ * @high_priority: if command is high priority
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS csr_set_serialization_params_to_cmd(tpAniSirGlobal mac_ctx,
+		tSmeCmd *sme_cmd, struct wlan_serialization_command *cmd,
+		uint8_t high_priority);
+tSmeCmd *sme_get_command_buffer(tpAniSirGlobal pMac);
+void sme_release_command(tpAniSirGlobal pMac, tSmeCmd *pCmd);
+bool qos_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+void qos_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+QDF_STATUS csr_process_scan_command(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+QDF_STATUS csr_roam_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+
+/**
+ * csr_roam_wm_status_change_complete() - Remove WM status change command
+ *                                        from SME active command list
+ * @mac_ctx: global mac context
+ * @session_id: session id
+ *
+ * This API removes WM status change command from SME active command list
+ * if present.
+ *
+ * Return: void
+ */
+void csr_roam_wm_status_change_complete(tpAniSirGlobal mac_ctx,
+					uint8_t session_id);
+void csr_roam_process_wm_status_change_command(tpAniSirGlobal pMac,
+		tSmeCmd *pCommand);
+/**
+ * csr_process_del_sta_session_command() - Post WMA_DEL_STA_SELF_REQ to wma
+ *
+ * @mac_ctx: global mac context
+ * @sme_command: received Delete Self station request command
+ *
+ * This API sends the WMA_DEL_STA_SELF_REQ msg to WMA.
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS csr_process_del_sta_session_command(tpAniSirGlobal mac_ctx,
+					       tSmeCmd *sme_command);
+void csr_reinit_roam_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+void csr_reinit_wm_status_change_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+QDF_STATUS csr_roam_send_set_key_cmd(tpAniSirGlobal mac_ctx,
+		uint32_t session_id, struct setkey_cmd *set_key_cmd);
+QDF_STATUS csr_is_valid_channel(tpAniSirGlobal pMac, uint8_t chnNum);
+
+QDF_STATUS sme_acquire_global_lock(tSmeStruct *psSme);
+QDF_STATUS sme_release_global_lock(tSmeStruct *psSme);
+
+QDF_STATUS csr_process_add_sta_session_rsp(tpAniSirGlobal pMac, uint8_t *pMsg);
+QDF_STATUS csr_process_del_sta_session_rsp(tpAniSirGlobal pMac, uint8_t *pMsg);
+
+bool csr_roamGetConcurrencyConnectStatusForBmps(tpAniSirGlobal pMac);
+
+QDF_STATUS csr_flush_cfg_bg_scan_roam_channel_list(tpAniSirGlobal pMac,
+		uint8_t sessionId);
+QDF_STATUS csr_create_bg_scan_roam_channel_list(tpAniSirGlobal pMac,
+		uint8_t sessionId, const uint8_t *pChannelList,
+		const uint8_t numChannels);
+
+#ifdef FEATURE_WLAN_ESE
+QDF_STATUS csr_create_roam_scan_channel_list(tpAniSirGlobal pMac,
+		uint8_t sessionId,
+		uint8_t *pChannelList,
+		uint8_t numChannels,
+		const enum band_info eBand);
+#endif
+
+QDF_STATUS p2p_process_remain_on_channel_cmd(tpAniSirGlobal pMac,
+					     tSmeCmd *p2pRemainonChn);
+ePhyChanBondState csr_convert_cb_ini_value_to_phy_cb_state(uint32_t cbIniValue);
+void csr_process_set_dual_mac_config(tpAniSirGlobal mac, tSmeCmd *command);
+void csr_process_set_antenna_mode(tpAniSirGlobal mac, tSmeCmd *command);
+void csr_process_set_hw_mode(tpAniSirGlobal mac, tSmeCmd *command);
+void csr_process_nss_update_req(tpAniSirGlobal mac, tSmeCmd *command);
+#endif /* #if !defined( __SMEINSIDE_H ) */
diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h
new file mode 100644
index 0000000..9855191
--- /dev/null
+++ b/core/sme/inc/sme_internal.h
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#if !defined(__SMEINTERNAL_H)
+#define __SMEINTERNAL_H
+
+/**
+ * \file  sme_internal.h
+ *
+ * \brief prototype for SME internal structures and APIs used for SME and MAC
+ */
+
+/*--------------------------------------------------------------------------
+  Include Files
+  ------------------------------------------------------------------------*/
+#include "qdf_status.h"
+#include "qdf_lock.h"
+#include "qdf_trace.h"
+#include "qdf_mem.h"
+#include "qdf_types.h"
+#include "host_diag_core_event.h"
+#include "csr_link_list.h"
+#include "sme_power_save.h"
+#include "nan_api.h"
+
+struct wmi_twt_enable_complete_event_param;
+/*--------------------------------------------------------------------------
+  Type declarations
+  ------------------------------------------------------------------------*/
+
+/* Mask can be only have one bit set */
+typedef enum eSmeCommandType {
+	eSmeNoCommand = 0,
+	/* this is not a command, it is to identify this is a CSR command */
+	eSmeCsrCommandMask = 0x10000,
+	eSmeCommandRoam,
+	eSmeCommandWmStatusChange,
+	e_sme_command_del_sta_session,
+	/* QOS */
+	eSmeQosCommandMask = 0x40000,   /* To identify Qos commands */
+	eSmeCommandAddTs,
+	eSmeCommandDelTs,
+	e_sme_command_set_hw_mode,
+	e_sme_command_nss_update,
+	e_sme_command_set_dual_mac_config,
+	e_sme_command_set_antenna_mode,
+} eSmeCommandType;
+
+typedef enum eSmeState {
+	SME_STATE_STOP,
+	SME_STATE_START,
+	SME_STATE_READY,
+} eSmeState;
+
+#define SME_IS_START(pMac)  (SME_STATE_STOP != (pMac)->sme.state)
+#define SME_IS_READY(pMac)  (SME_STATE_READY == (pMac)->sme.state)
+
+/* HDD Callback function */
+typedef void (*pIbssPeerInfoCb)(void *pUserData,
+					tSirPeerInfoRspParams *infoParam);
+
+/* Peer info */
+typedef struct tagSmePeerInfoHddCbkInfo {
+	void *pUserData;
+	pIbssPeerInfoCb peerInfoCbk;
+} tSmePeerInfoHddCbkInfo;
+
+/**
+ * struct stats_ext_event - stats_ext_event payload
+ * @vdev_id: ID of the vdev for the stats
+ * @event_data_len: length of the @event_data
+ * @event_data: actual ext stats
+ */
+struct stats_ext_event {
+	uint32_t vdev_id;
+	uint32_t event_data_len;
+	uint8_t event_data[];
+};
+
+/**
+ * typedef stats_ext_cb - stats ext callback
+ * @hdd_handle: Opaque handle to the HDD context
+ * @data: stats ext payload from firmware
+ */
+typedef void (*stats_ext_cb)(hdd_handle_t hdd_handle,
+			     struct stats_ext_event *data);
+
+/**
+ * typedef stats_ext2_cb - stats ext2 callback
+ * @hdd_handle: Opaque handle to the HDD context
+ * @data: stats ext2 payload from firmware
+ */
+typedef void (*stats_ext2_cb)(hdd_handle_t hdd_handle,
+			      struct sir_sme_rx_aggr_hole_ind *data);
+
+#define MAX_ACTIVE_CMD_STATS    16
+
+typedef struct sActiveCmdStats {
+	eSmeCommandType command;
+	uint32_t reason;
+	uint32_t sessionId;
+	uint64_t timestamp;
+} tActiveCmdStats;
+
+typedef struct sSelfRecoveryStats {
+	tActiveCmdStats activeCmdStats[MAX_ACTIVE_CMD_STATS];
+	uint8_t cmdStatsIndx;
+} tSelfRecoveryStats;
+
+typedef void (*link_layer_stats_cb)(hdd_handle_t hdd_handle,
+				    int indication_type,
+				    tSirLLStatsResults *results,
+				    void *cookie);
+
+typedef void (*ext_scan_ind_cb)(hdd_handle_t hdd_handle,
+				const uint16_t, void *);
+
+typedef void (*ocb_callback)(void *context, void *response);
+typedef void (*sme_set_thermal_level_callback)(hdd_handle_t hdd_handle,
+					       u_int8_t level);
+typedef void (*p2p_lo_callback)(void *context,
+				struct sir_p2p_lo_event *event);
+#ifdef FEATURE_OEM_DATA_SUPPORT
+typedef void (*sme_send_oem_data_rsp_msg)(struct oem_data_rsp *);
+#endif
+
+typedef void (*twt_enable_cb)(hdd_handle_t hdd_handle,
+			      struct wmi_twt_enable_complete_event_param *params);
+typedef void (*twt_disable_cb)(hdd_handle_t hdd_handle);
+
+#ifdef FEATURE_WLAN_APF
+/**
+ * typedef apf_get_offload_cb - APF offload callback signature
+ * @context: Opaque context that the client can use to associate the
+ *    callback with the request
+ * @caps: APF offload capabilities as reported by firmware
+ */
+struct sir_apf_get_offload;
+typedef void (*apf_get_offload_cb)(void *context,
+				   struct sir_apf_get_offload *caps);
+
+/**
+ * typedef apf_read_mem_cb - APF read memory response callback
+ * @context: Opaque context that the client can use to associate the
+ *    callback with the request
+ * @evt: APF read memory response event parameters
+ */
+typedef void (*apf_read_mem_cb)(void *context,
+				struct wmi_apf_read_memory_resp_event_params
+									  *evt);
+#endif /* FEATURE_WLAN_APF */
+
+/**
+ * typedef rssi_threshold_breached_cb - RSSI threshold breach callback
+ * @hdd_handle: Opaque handle to the HDD context
+ * @event: The RSSI breach event
+ */
+typedef void (*rssi_threshold_breached_cb)(hdd_handle_t hdd_handle,
+					   struct rssi_breach_event *event);
+
+/**
+ * typedef sme_encrypt_decrypt_callback - encrypt/decrypt callback
+ *    signature
+ * @context: Opaque context that the client can use to associate the
+ *    callback with the request
+ * @response: Encrypt/Decrypt response from firmware
+ */
+struct sir_encrypt_decrypt_rsp_params;
+typedef void (*sme_encrypt_decrypt_callback)(
+			void *context,
+			struct sir_encrypt_decrypt_rsp_params *response);
+
+/**
+ * typedef get_chain_rssi_callback - get chain rssi callback
+ * @context: Opaque context that the client can use to associate the
+ *    callback with the request
+ * @data: chain rssi result reported by firmware
+ */
+struct chain_rssi_result;
+typedef void (*get_chain_rssi_callback)(void *context,
+					struct chain_rssi_result *data);
+
+typedef void (*tx_queue_cb)(hdd_handle_t hdd_handle, uint32_t vdev_id,
+			    enum netif_action_type action,
+			    enum netif_reason_type reason);
+
+/**
+ * typedef pwr_save_fail_cb - power save fail callback function
+ * @hdd_handle: HDD handle registered with SME
+ * @params: failure parameters
+ */
+struct chip_pwr_save_fail_detected_params;
+typedef void (*pwr_save_fail_cb)(hdd_handle_t hdd_handle,
+			struct chip_pwr_save_fail_detected_params *params);
+
+/**
+ * typedef bt_activity_info_cb - bluetooth activity callback function
+ * @hdd_handle: HDD handle registered with SME
+ * @bt_activity: bluetooth activity information
+ */
+typedef void (*bt_activity_info_cb)(hdd_handle_t hdd_handle,
+				    uint32_t bt_activity);
+
+/**
+ * typedef congestion_cb - congestion callback function
+ * @hdd_handle: HDD handle registered with SME
+ * @congestion: Current congestion value
+ * @vdev_id: ID of the vdev for which congestion is being reported
+ */
+typedef void (*congestion_cb)(hdd_handle_t hdd_handle, uint32_t congestion,
+			      uint32_t vdev_id);
+
+/**
+ * typedef rso_cmd_status_cb - RSO command status  callback function
+ * @hdd_handle: HDD handle registered with SME
+ * @rso_status: Status of the operation
+ */
+typedef void (*rso_cmd_status_cb)(hdd_handle_t hdd_handle,
+				  struct rso_cmd_status *rso_status);
+
+/**
+ * typedef lost_link_info_cb - lost link indication callback function
+ * @hdd_handle: HDD handle registered with SME
+ * @lost_link_info: Information about the lost link
+ */
+typedef void (*lost_link_info_cb)(hdd_handle_t hdd_handle,
+				  struct sir_lost_link_info *lost_link_info);
+
+typedef struct tagSmeStruct {
+	eSmeState state;
+	qdf_mutex_t lkSmeGlobalLock;
+	uint32_t totalSmeCmd;
+	/* following pointer contains array of pointers for tSmeCmd* */
+	void **pSmeCmdBufAddr;
+	tDblLinkList smeCmdFreeList;    /* preallocated roam cmd list */
+	enum QDF_OPMODE currDeviceMode;
+	tSmePeerInfoHddCbkInfo peerInfoParams;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	host_event_wlan_status_payload_type eventPayload;
+#endif
+	void *ll_stats_context;
+	link_layer_stats_cb link_layer_stats_cb;
+	void (*link_layer_stats_ext_cb)(hdd_handle_t callback_ctx,
+					tSirLLStatsResults *rsp);
+#ifdef WLAN_POWER_DEBUGFS
+	void *power_debug_stats_context;
+	void (*power_stats_resp_callback)(struct power_stats_response *rsp,
+						void *callback_context);
+#endif
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+	void (*pAutoShutdownNotificationCb)(void);
+#endif
+	/* Maximum interfaces allowed by the host */
+	uint8_t max_intf_count;
+	stats_ext_cb stats_ext_cb;
+	stats_ext2_cb stats_ext2_cb;
+	/* linkspeed callback */
+	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
+	ext_scan_ind_cb ext_scan_ind_cb;
+#endif /* FEATURE_WLAN_EXTSCAN */
+#ifdef WLAN_FEATURE_NAN
+	nan_callback nan_callback;
+#endif
+	csr_link_status_callback link_status_callback;
+	void *link_status_context;
+	int (*get_tsf_cb)(void *pcb_cxt, struct stsf *ptsf);
+	void *get_tsf_cxt;
+	/* get temperature event context and callback */
+	void *pTemperatureCbContext;
+	void (*pGetTemperatureCb)(int temperature, void *context);
+	uint8_t miracast_value;
+	struct ps_global_info  ps_global_info;
+	rssi_threshold_breached_cb rssi_threshold_breached_cb;
+	hw_mode_transition_cb sme_hw_mode_trans_cb;
+	/* OCB callbacks */
+	void *ocb_set_config_context;
+	ocb_callback ocb_set_config_callback;
+	void *ocb_get_tsf_timer_context;
+	ocb_callback ocb_get_tsf_timer_callback;
+	void *dcc_get_stats_context;
+	ocb_callback dcc_get_stats_callback;
+	void *dcc_update_ndl_context;
+	ocb_callback dcc_update_ndl_callback;
+	void *dcc_stats_event_context;
+	ocb_callback dcc_stats_event_callback;
+	sme_set_thermal_level_callback set_thermal_level_cb;
+	void *apf_get_offload_context;
+#ifdef FEATURE_P2P_LISTEN_OFFLOAD
+	p2p_lo_callback p2p_lo_event_callback;
+	void *p2p_lo_event_context;
+#endif
+#ifdef FEATURE_OEM_DATA_SUPPORT
+	sme_send_oem_data_rsp_msg oem_data_rsp_callback;
+#endif
+	sme_encrypt_decrypt_callback encrypt_decrypt_cb;
+	void *encrypt_decrypt_context;
+	lost_link_info_cb lost_link_info_cb;
+
+	bool (*set_connection_info_cb)(bool);
+	bool (*get_connection_info_cb)(uint8_t *session_id,
+			enum scan_reject_states *reason);
+	rso_cmd_status_cb rso_cmd_status_cb;
+	congestion_cb congestion_cb;
+	pwr_save_fail_cb chip_power_save_fail_cb;
+	bt_activity_info_cb bt_activity_info_cb;
+	void *get_arp_stats_context;
+	void (*get_arp_stats_cb)(void *, struct rsp_stats *, void *);
+	get_chain_rssi_callback get_chain_rssi_cb;
+	void *get_chain_rssi_context;
+	tx_queue_cb tx_queue_cb;
+	twt_enable_cb twt_enable_cb;
+	twt_disable_cb twt_disable_cb;
+#ifdef FEATURE_WLAN_APF
+	apf_get_offload_cb apf_get_offload_cb;
+	apf_read_mem_cb apf_read_mem_cb;
+#endif
+} tSmeStruct, *tpSmeStruct;
+
+#endif /* #if !defined( __SMEINTERNAL_H ) */
diff --git a/core/sme/inc/sme_nan_datapath.h b/core/sme/inc/sme_nan_datapath.h
new file mode 100644
index 0000000..817055b
--- /dev/null
+++ b/core/sme/inc/sme_nan_datapath.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016-2018 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: sme_nan_datapath.h
+ *
+ * SME NAN Data path API specification
+ */
+
+#ifndef __SME_NAN_DATAPATH_H
+#define __SME_NAN_DATAPATH_H
+
+#include "csr_inside_api.h"
+
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+/* Start NDI BSS */
+QDF_STATUS csr_roam_start_ndi(tpAniSirGlobal mac_ctx, uint32_t session_id,
+			      struct csr_roam_profile *profile);
+
+void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx,
+				      uint32_t session_id,
+				      struct csr_roam_profile *roam_profile,
+				      tSirBssDescription *bss_desc);
+
+void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx,
+					uint32_t result,
+					uint32_t *roam_status,
+					uint32_t *roam_result,
+					struct csr_roam_info *roam_info);
+
+#else
+/* Start NDI BSS */
+static inline QDF_STATUS csr_roam_start_ndi(tpAniSirGlobal mac_ctx,
+					uint32_t session_id,
+					struct csr_roam_profile *profile)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx,
+					uint32_t session_id,
+					struct csr_roam_profile *roam_profile,
+					tSirBssDescription *bss_desc)
+{
+}
+
+static inline void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx,
+					uint32_t result,
+					uint32_t *roam_status,
+					uint32_t *roam_result,
+					struct csr_roam_info *roam_info)
+{
+}
+
+#endif /* WLAN_FEATURE_NAN_DATAPATH */
+
+#endif /* __SME_NAN_DATAPATH_H */
diff --git a/core/sme/inc/sme_power_save.h b/core/sme/inc/sme_power_save.h
new file mode 100644
index 0000000..cea67ab
--- /dev/null
+++ b/core/sme/inc/sme_power_save.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015-2018 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.
+ */
+
+#if !defined(__SME_POWER_SAVE_H)
+#define __SME_POWER_SAVE_H
+#include "qdf_lock.h"
+#include "qdf_trace.h"
+#include "qdf_mem.h"
+#include "qdf_types.h"
+#include "ani_system_defs.h"
+#include "sir_api.h"
+
+/*
+ * Auto Ps Entry User default timeout value, used instead of negative timeouts
+ * from user space - 5000ms
+ */
+#define AUTO_PS_ENTRY_USER_TIMER_DEFAULT_VALUE 5000
+#define AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE 1000
+#define AUTO_PS_DEFER_TIMEOUT_MS 1500
+
+/**
+ * enum ps_state - State of the power save
+ * @FULL_POWER_MODE: for Full power mode
+ * @LEGACY_POWER_SAVE_MODE: For Legacy Power Save mode
+ * @UAPSD_MODE: for UAPSD power save
+ */
+
+enum ps_state {
+	FULL_POWER_MODE,
+	LEGACY_POWER_SAVE_MODE,
+	UAPSD_MODE
+};
+
+/**
+ * struct ps_params - maintain power save state and USAPD params
+ * @mac_ctx: mac_ctx
+ * @session_id: Session Id.
+ * @ps_state : State of the power save
+ * @uapsd_per_ac_trigger_enable_mask: dynamic UPASD mask setting
+ *		derived from AddTS Rsp and DelTS frame.
+ *		If a particular AC bit is set, it means AC is trigger  enabled.
+ * @uapsd_per_ac_delivery_enable_mask: dynamic UPASD mask setting
+ *		derived from AddTS Rsp and DelTs frame.
+ *		If a particular AC bit is set, it means AC is delivery enabled.
+ * @ac_admit_mask: used for AC downgrade. This is a dynamic mask
+ *		setting which keep tracks of ACs being admitted.
+ *		If bit is set to 0: That particular AC is not admitted
+ *		If bit is set to 1: That particular AC is admitted
+ * @uapsd_per_ac_bit_mask: This is a static UAPSD mask setting
+ *		derived from SME_JOIN_REQ and SME_REASSOC_REQ.
+ *		If a particular AC bit is set, it means the AC is both
+ *		trigger enabled and delivery enabled.
+ * @auto_ps_enable_timer: Upon expiration of this timer	Power Save Offload
+ *		module will try to enable sta mode ps
+ */
+
+struct ps_params {
+	void *mac_ctx;
+	uint32_t     session_id;
+	enum    ps_state ps_state;
+	uint8_t uapsd_per_ac_trigger_enable_mask;
+	uint8_t uapsd_per_ac_delivery_enable_mask;
+	uint8_t ac_admit_mask[SIR_MAC_DIRECTION_DIRECT];
+	uint8_t uapsd_per_ac_bit_mask;
+	qdf_mc_timer_t auto_ps_enable_timer;
+
+};
+
+/**
+ * struct ps_global_info - global struct for Power save information
+ * @ps_enabled: Power Save is enabled or not in ini
+ * @ps_params:  maintain power save state and USAPD params
+ */
+struct ps_global_info {
+	bool ps_enabled;
+	uint32_t auto_bmps_timer_val;
+	struct ps_params ps_params[SIR_MAX_SUPPORTED_BSS];
+	/* Remain in Power active till DHCP completes */
+	bool remain_in_power_active_till_dhcp;
+};
+
+/**
+ * enum sme_ps_cmd: power save message to send WMA
+ * @SME_PS_ENABLE: For power save enable.
+ * @SME_PS_DISABLE: for Power save disable.
+ * @SME_PS_UAPSD_ENABLE; for UAPSD enable.
+ * @SME_PS_UAPSD_DISABLE: for UAPSD disable.
+ * @SME_PS_WOWL_ENTER: for WOWL Enter.
+ * @SME_PS_WOWL_EXIT: for WOWL Exit.
+ * @SME_PS_WOWL_ADD_BCAST_PTRN: Add bcst WOWL pattern.
+ * @SME_PS_WOWL_DEL_BCAST_PTRN: Del Bcsr Wowl Pattern.
+ */
+enum sme_ps_cmd {
+	SME_PS_ENABLE = 0,
+	SME_PS_DISABLE,
+	SME_PS_UAPSD_ENABLE,
+	SME_PS_UAPSD_DISABLE,
+	SME_PS_WOWL_ENTER,
+	SME_PS_WOWL_EXIT,
+	SME_PS_WOWL_ADD_BCAST_PTRN,
+	SME_PS_WOWL_DEL_BCAST_PTRN,
+};
+
+#endif
diff --git a/core/sme/inc/sme_power_save_api.h b/core/sme/inc/sme_power_save_api.h
new file mode 100644
index 0000000..5340dca
--- /dev/null
+++ b/core/sme/inc/sme_power_save_api.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015-2018 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.
+ */
+
+#if !defined(__SME_POWER_SAVE_API_H)
+#define __SME_POWER_SAVE_API_H
+
+#include "sme_power_save.h"
+#include "ani_global.h"
+#include "sme_inside.h"
+
+QDF_STATUS sme_ps_enable_disable(tHalHandle hal_ctx, uint32_t session_id,
+		enum sme_ps_cmd command);
+
+QDF_STATUS sme_ps_timer_flush_sync(tHalHandle hal, uint8_t session_id);
+
+QDF_STATUS sme_ps_uapsd_enable(tHalHandle hal_ctx, uint32_t session_id);
+
+QDF_STATUS sme_ps_uapsd_disable(tHalHandle hal_ctx, uint32_t session_id);
+
+/* Condition check if driver is ready to enter in PS */
+QDF_STATUS sme_enable_sta_ps_check(tpAniSirGlobal mac_ctx, uint32_t session_id);
+
+QDF_STATUS sme_ps_process_command(tpAniSirGlobal mac_ctx,
+		uint32_t session_id,
+		enum sme_ps_cmd command);
+
+void sme_set_tspec_uapsd_mask_per_session(tpAniSirGlobal mac_ctx,
+		tSirMacTSInfo *ts_info,
+		uint8_t session_id);
+/* Full Power Req Callback */
+typedef void (*uapsd_start_indication_cb)(void *callback_context,
+		uint32_t session_id, QDF_STATUS status);
+
+QDF_STATUS sme_ps_start_uapsd(tHalHandle hal_ctx, uint32_t session_id);
+QDF_STATUS sme_set_ps_host_offload(tHalHandle hal_ctx,
+		tpSirHostOffloadReq request,
+		uint8_t session_id);
+
+#ifdef WLAN_NS_OFFLOAD
+QDF_STATUS sme_set_ps_ns_offload(tHalHandle hal_ctx,
+		tpSirHostOffloadReq request,
+		uint8_t session_id);
+
+#endif /* WLAN_NS_OFFLOAD */
+/* / Post a message to PE module */
+QDF_STATUS sme_post_pe_message(tpAniSirGlobal mac_ctx,
+			       struct scheduler_msg *pMsg);
+
+/**
+ * sme_ps_enable_auto_ps_timer(): Enable power-save auto timer with timeout
+ * @hal_ctx:       HAL context
+ * @session_id:    adapter session Id
+ * @timeout:       timeout period in ms
+ *
+ * Returns: QDF_STATUS
+ */
+QDF_STATUS sme_ps_enable_auto_ps_timer(tHalHandle hal_ctx,
+		uint32_t sessionId, uint32_t timeout);
+QDF_STATUS sme_ps_disable_auto_ps_timer(tHalHandle hal_ctx,
+		uint32_t sessionId);
+
+QDF_STATUS sme_ps_open(tHalHandle hal_ctx);
+
+QDF_STATUS sme_ps_open_per_session(tHalHandle hal_ctx, uint32_t session_id);
+
+void sme_auto_ps_entry_timer_expired(void *ps_param);
+QDF_STATUS sme_ps_close(tHalHandle hal_ctx);
+QDF_STATUS sme_ps_close_per_session(tHalHandle hal_ctx, uint32_t sessionId);
+
+bool sme_is_auto_ps_timer_running(tHalHandle hal_ctx,
+		uint32_t session_id);
+
+#endif /* #if !defined(__SME_POWER_SAVE_API_H) */
+
diff --git a/core/sme/inc/sme_qos_api.h b/core/sme/inc/sme_qos_api.h
new file mode 100644
index 0000000..de71f94
--- /dev/null
+++ b/core/sme/inc/sme_qos_api.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#if !defined(__SME_QOSAPI_H)
+#define __SME_QOSAPI_H
+
+/**
+ * \file  sme_qos_api.h
+ *
+ * \brief prototype for SME QoS APIs
+ */
+
+/* Include Files */
+#include "qdf_lock.h"
+#include "qdf_trace.h"
+#include "qdf_mem.h"
+#include "qdf_types.h"
+#include "ani_global.h"
+#include "sir_api.h"
+
+/* Pre-processor Definitions */
+#define SME_QOS_UAPSD_VO      0x01
+#define SME_QOS_UAPSD_VI      0x02
+#define SME_QOS_UAPSD_BE      0x08
+#define SME_QOS_UAPSD_BK      0x04
+
+/* Enumeration of the various QoS status types that would be reported to HDD */
+enum sme_qos_statustype {
+	/*
+	 * async: once PE notifies successful TSPEC negotiation, or CSR notifies
+	 * for successful reassoc, notifies HDD with current QoS Params
+	 */
+	SME_QOS_STATUS_SETUP_SUCCESS_IND = 0,
+	/* sync: only when App asked for APSD & it's already set with ACM = 0 */
+	SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY,
+	/* sync or async: in case of async notify HDD with current QoS Params */
+	SME_QOS_STATUS_SETUP_FAILURE_RSP,
+	/* sync */
+	SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP,
+	/* sync: AP doesn't support QoS (WMM) */
+	SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP,
+	/* sync: either req has been sent down to PE or just buffered in SME */
+	SME_QOS_STATUS_SETUP_REQ_PENDING_RSP,
+	/*
+	 * async: in case of flow aggregation, if the new TSPEC negotiation
+	 * is successful, OR, notify existing flows that TSPEC is modified with
+	 * current QoS Params
+	 */
+	SME_QOS_STATUS_SETUP_MODIFIED_IND,
+	/* sync: no APSD asked for & ACM = 0 */
+	SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP,
+	/*
+	 * async: In case of UAPSD, once PE notifies successful TSPEC
+	 * negotiation, or CSR notifies for successful reassoc to SME-QoS,
+	 * notify HDD if PMC can't put the module in UAPSD mode right away
+	 * (QDF_STATUS_PMC_PENDING)
+	 */
+	SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING,
+	/*
+	 * async: In case of UAPSD, once PE notifies successful TSPEC
+	 * negotiation, or CSR notifies for successful reassoc to SME-QoS,
+	 * notify HDD if PMC can't put the module in UAPSD mode at all
+	 * (QDF_STATUS_E_FAILURE)
+	 */
+	SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED,
+	/*
+	 * sync: req has been sent down to PE in case of delts or addts
+	 * for remain flows, OR if the AC doesn't have APSD or ACM
+	 * async: once the downgrade req for QoS params is successful
+	 */
+	SME_QOS_STATUS_RELEASE_SUCCESS_RSP = 100,
+	/* sync or async: in case of async notify HDD with current QoS Param */
+	SME_QOS_STATUS_RELEASE_FAILURE_RSP,
+	/* async: AP sent DELTS indication */
+	SME_QOS_STATUS_RELEASE_QOS_LOST_IND,
+	/*
+	 * sync: an addts req has been sent down to PE to downgrade the
+	 * QoS params or just buffered in SME
+	 */
+	SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP,
+	/* sync */
+	SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP,
+	/*
+	 * async: for QoS modify request if modification is successful,
+	 * notifies HDD with current QoS Params
+	 */
+	SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND = 200,
+	/* sync: only when App asked for APSD & it's already set with ACM = 0 */
+	SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY,
+	/* sync or async: in case of async notify HDD with current QoS Param */
+	SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP,
+	/* sync: either req has been sent down to PE or just buffered in SME */
+	SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP,
+	/* sync: no APSD asked for & ACM = 0 */
+	SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP,
+	/* sync */
+	SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP,
+	/*
+	 * async: In case of UAPSD, once PE notifies successful TSPEC
+	 * negotiation or CSR notifies for successful reassoc to SME-QoS,
+	 * notify HDD if PMC can't put the module in UAPSD mode right away
+	 * (QDF_STATUS_PMC_PENDING)
+	 */
+	SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING,
+	/*
+	 * async: In case of UAPSD, once PE notifies successful TSPEC
+	 * negotiation, or CSR notifies for successful reassoc to SME-QoS,
+	 * notify HDD if PMC can't put the module in UAPSD mode at all
+	 * (QDF_STATUS_E_FAILURE)
+	 */
+	SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED,
+	/* sync: STA is handing off to a new AP */
+	SME_QOS_STATUS_HANDING_OFF = 300,
+	/* async:powersave mode changed by PMC from UAPSD to Full power */
+	SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND = 400,
+	/* async:powersave mode changed by PMC from Full power to UAPSD */
+	SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND,
+
+};
+
+/*
+ * Enumeration of the various User priority (UP) types
+ * From 802.1D/802.11e/WMM specifications (all refer to same table)
+ */
+enum sme_qos_wmmuptype {
+	SME_QOS_WMM_UP_BE = 0,
+	SME_QOS_WMM_UP_BK = 1,
+	SME_QOS_WMM_UP_RESV = 2,        /* Reserved */
+	SME_QOS_WMM_UP_EE = 3,
+	SME_QOS_WMM_UP_CL = 4,
+	SME_QOS_WMM_UP_VI = 5,
+	SME_QOS_WMM_UP_VO = 6,
+	SME_QOS_WMM_UP_NC = 7,
+	SME_QOS_WMM_UP_MAX
+};
+
+/*
+ * Enumeration of the various TSPEC ack policies.
+ * From 802.11 WMM specification
+ */
+enum sme_qos_wmmack_policytype {
+	SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK = 0,
+	SME_QOS_WMM_TS_ACK_POLICY_RESV1 = 1,
+	SME_QOS_WMM_TS_ACK_POLICY_RESV2 = 2,    /* Reserved */
+	SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK = 3,
+
+};
+
+/*
+ * TS Info field in the WMM TSPEC
+ * See suggestive values above
+ */
+struct sme_qos_wmmts_infotype {
+	uint8_t burst_size_defn;
+	enum sme_qos_wmmack_policytype ack_policy;
+	enum sme_qos_wmmuptype up;    /* User priority */
+	uint8_t psb;            /* power-save bit */
+	enum sme_qos_wmm_dir_type direction;    /* Direction */
+	uint8_t tid;            /* TID : To be filled up by SME-QoS */
+};
+
+/* The WMM TSPEC Element (from the WMM spec)*/
+struct sme_qos_wmmtspecinfo {
+	struct sme_qos_wmmts_infotype ts_info;
+	uint16_t nominal_msdu_size;
+	uint16_t maximum_msdu_size;
+	uint32_t min_service_interval;
+	uint32_t max_service_interval;
+	uint32_t inactivity_interval;
+	uint32_t suspension_interval;
+	uint32_t svc_start_time;
+	uint32_t min_data_rate;
+	uint32_t mean_data_rate;
+	uint32_t peak_data_rate;
+	uint32_t max_burst_size;
+	uint32_t delay_bound;
+	uint32_t min_phy_rate;
+	uint16_t surplus_bw_allowance;
+	uint16_t medium_time;
+};
+
+/* External APIs */
+typedef QDF_STATUS (*sme_QosCallback)(tHalHandle hHal, void *HDDcontext,
+		struct sme_qos_wmmtspecinfo *pCurrentQoSInfo,
+		enum sme_qos_statustype status, uint32_t QosFlowID);
+enum sme_qos_statustype sme_qos_setup_req(tHalHandle hHal, uint32_t sessionId,
+		struct sme_qos_wmmtspecinfo *pQoSInfo,
+		sme_QosCallback QoSCallback, void *HDDcontext,
+		enum sme_qos_wmmuptype UPType, uint32_t *pQosFlowID);
+enum sme_qos_statustype sme_qos_modify_req(tHalHandle hHal,
+		struct sme_qos_wmmtspecinfo *pQoSInfo, uint32_t QosFlowID);
+enum sme_qos_statustype sme_qos_release_req(tHalHandle hHal, uint8_t session_id,
+				      uint32_t QosFlowID);
+bool sme_qos_is_ts_info_ack_policy_valid(mac_handle_t mac_handle,
+					 struct sme_qos_wmmtspecinfo *pQoSInfo,
+					 uint8_t sessionId);
+void sme_qos_update_hand_off(uint8_t sessionId, bool updateHandOff);
+QDF_STATUS sme_update_dsc_pto_up_mapping(tHalHandle hHal,
+		enum sme_qos_wmmuptype *dscpmapping, uint8_t sessionId);
+
+QDF_STATUS sme_offload_qos_process_out_of_uapsd_mode(tpAniSirGlobal mac_ctx,
+		uint32_t session_id);
+QDF_STATUS sme_offload_qos_process_into_uapsd_mode(tpAniSirGlobal mac_ctx,
+		uint32_t session_id);
+
+
+#endif /* #if !defined( __SME_QOSAPI_H ) */
diff --git a/core/sme/inc/sme_qos_internal.h b/core/sme/inc/sme_qos_internal.h
new file mode 100644
index 0000000..4592abf
--- /dev/null
+++ b/core/sme/inc/sme_qos_internal.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#if !defined(__SMEQOSINTERNAL_H)
+#define __SMEQOSINTERNAL_H
+
+/**
+ * \file  sme_qos_internal.h
+ *
+ * \brief prototype for SME QoS APIs
+ */
+
+/*--------------------------------------------------------------------------
+  Include Files
+  ------------------------------------------------------------------------*/
+#include "qdf_lock.h"
+#include "qdf_trace.h"
+#include "qdf_mem.h"
+#include "qdf_types.h"
+#include "ani_global.h"
+#include "sir_api.h"
+#include "sme_qos_api.h"
+#include "sme_internal.h"
+
+/*--------------------------------------------------------------------------
+  Type declarations
+  ------------------------------------------------------------------------*/
+#define SME_QOS_AP_SUPPORTS_APSD         0x80
+
+/*---------------------------------------------------------------------------
+  Enumeration of the various EDCA Access Categories:
+  Based on AC to ACI mapping in 802.11e spec (identical to WMM)
+  ---------------------------------------------------------------------------*/
+typedef enum {
+	SME_QOS_EDCA_AC_BE = 0, /* Best effort access category */
+	SME_QOS_EDCA_AC_BK = 1, /* Background access category  */
+	SME_QOS_EDCA_AC_VI = 2, /* Video access category       */
+	SME_QOS_EDCA_AC_VO = 3, /* Voice access category       */
+
+	SME_QOS_EDCA_AC_MAX
+} sme_QosEdcaAcType;
+
+/*---------------------------------------------------------------------------
+  Enumeration of the various CSR event indication types that would be reported
+  by CSR
+  ---------------------------------------------------------------------------*/
+typedef enum {
+	SME_QOS_CSR_JOIN_REQ = 0,
+	SME_QOS_CSR_ASSOC_COMPLETE,
+	SME_QOS_CSR_REASSOC_REQ,
+	SME_QOS_CSR_REASSOC_COMPLETE,
+	SME_QOS_CSR_REASSOC_FAILURE,
+	SME_QOS_CSR_DISCONNECT_REQ,
+	SME_QOS_CSR_DISCONNECT_IND,
+	SME_QOS_CSR_HANDOFF_ASSOC_REQ,
+	SME_QOS_CSR_HANDOFF_COMPLETE,
+	SME_QOS_CSR_PREAUTH_SUCCESS_IND,
+	SME_QOS_CSR_SET_KEY_SUCCESS_IND,
+} sme_qos_csr_event_indType;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+typedef enum {
+	SME_QOS_DIAG_ADDTS_REQ = 0,
+	SME_QOS_DIAG_ADDTS_RSP,
+	SME_QOS_DIAG_DELTS
+} sme_QosDiagQosEventSubtype;
+
+typedef enum {
+	SME_QOS_DIAG_ADDTS_ADMISSION_ACCEPTED = 0,
+	SME_QOS_DIAG_ADDTS_INVALID_PARAMS,
+	SME_QOS_DIAG_ADDTS_RESERVED,
+	SME_QOS_DIAG_ADDTS_REFUSED,
+	SME_QOS_DIAG_USER_REQUESTED,
+	SME_QOS_DIAG_DELTS_IND_FROM_AP,
+
+} sme_QosDiagQosEventReasonCode;
+
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+/*---------------------------------------------------------------------------
+  The association information structure to be passed by CSR after assoc or
+  reassoc is done
+  ---------------------------------------------------------------------------*/
+typedef struct {
+	tSirBssDescription *pBssDesc;
+	struct csr_roam_profile *pProfile;
+} sme_QosAssocInfo;
+
+/*--------------------------------------------------------------------------
+  External APIs for CSR - Internal to SME
+  ------------------------------------------------------------------------*/
+QDF_STATUS sme_qos_open(tpAniSirGlobal pMac);
+QDF_STATUS sme_qos_close(tpAniSirGlobal pMac);
+QDF_STATUS sme_qos_msg_processor(tpAniSirGlobal pMac, uint16_t msg_type,
+		void *pMsgBuf);
+
+/*--------------------------------------------------------------------------
+  Internal APIs for CSR
+  ------------------------------------------------------------------------*/
+QDF_STATUS sme_qos_validate_params(tpAniSirGlobal pMac,
+		tSirBssDescription *pBssDesc);
+QDF_STATUS sme_qos_csr_event_ind(tpAniSirGlobal pMac,
+		uint8_t sessionId,
+		sme_qos_csr_event_indType ind, void *pEvent_info);
+uint8_t sme_qos_get_acm_mask(tpAniSirGlobal pMac,
+		tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes);
+#ifdef FEATURE_WLAN_ESE
+uint8_t sme_qos_ese_retrieve_tspec_info(tpAniSirGlobal pMac, uint8_t sessionId,
+		tTspecInfo * pTspecInfo);
+#endif
+
+#endif /* #if !defined( __SMEQOSINTERNAL_H ) */
diff --git a/core/sme/inc/sme_rrm_api.h b/core/sme/inc/sme_rrm_api.h
new file mode 100644
index 0000000..5898023
--- /dev/null
+++ b/core/sme/inc/sme_rrm_api.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014-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.
+ */
+
+#if !defined(__SMERRMAPI_H)
+#define __SMERRMAPI_H
+
+/**
+ * \file  sme_rrm_api.h
+ *
+ * \brief prototype for SME RRM APIs
+ */
+
+/*--------------------------------------------------------------------------
+  Include Files
+  ------------------------------------------------------------------------*/
+#include "qdf_lock.h"
+#include "qdf_trace.h"
+#include "qdf_mem.h"
+#include "qdf_types.h"
+#include "ani_global.h"
+#include "sir_api.h"
+#include "sme_internal.h"
+#include "sme_rrm_internal.h"
+
+QDF_STATUS sme_rrm_msg_processor(tpAniSirGlobal pMac, uint16_t msg_type,
+		void *pMsgBuf);
+QDF_STATUS rrm_close(tpAniSirGlobal pMac);
+QDF_STATUS rrm_open(tpAniSirGlobal pMac);
+QDF_STATUS rrm_change_default_config_param(tpAniSirGlobal pMac,
+		struct rrm_config_param *rrm_config);
+QDF_STATUS sme_rrm_neighbor_report_request(tpAniSirGlobal pMac,
+		uint8_t sessionId, tpRrmNeighborReq pNeighborReq,
+		tpRrmNeighborRspCallbackInfo callbackInfo);
+QDF_STATUS sme_rrm_process_beacon_report_req_ind(tpAniSirGlobal pMac,
+		void *pMsgBuf);
+
+/**
+ * rrm_start() - start the RRM module
+ * @mac_ctx: The handle returned by mac_open.
+ *
+ * Return: QDF_STATUS
+ *           QDF_STATUS_SUCCESS  success
+ */
+QDF_STATUS rrm_start(tpAniSirGlobal mac_ctx);
+
+/**
+ * rrm_stop() - stop the RRM module
+ * @mac_ctx: The handle returned by mac_open.
+ *
+ * Return: QDF_STATUS
+ *           QDF_STATUS_SUCCESS  success
+ */
+QDF_STATUS rrm_stop(tpAniSirGlobal mac_ctx);
+
+#endif
diff --git a/core/sme/inc/sme_rrm_internal.h b/core/sme/inc/sme_rrm_internal.h
new file mode 100644
index 0000000..90528bd
--- /dev/null
+++ b/core/sme/inc/sme_rrm_internal.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2018 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.
+ */
+
+#if !defined(__SMERRMINTERNAL_H)
+#define __SMERRMINTERNAL_H
+
+/**
+ * \file  sme_rrm_internal.h
+ *
+ * \brief prototype for SME RRM APIs
+ */
+
+/*--------------------------------------------------------------------------
+  Include Files
+  ------------------------------------------------------------------------*/
+#include "qdf_lock.h"
+#include "qdf_trace.h"
+#include "qdf_mem.h"
+#include "qdf_types.h"
+#include "rrm_global.h"
+
+/*--------------------------------------------------------------------------
+  Type declarations
+  ------------------------------------------------------------------------*/
+typedef struct sRrmNeighborReportDesc {
+	tListElem List;
+	tSirNeighborBssDescription *pNeighborBssDescription;
+	uint32_t roamScore;
+	uint8_t sessionId;
+} tRrmNeighborReportDesc, *tpRrmNeighborReportDesc;
+
+typedef void (*NeighborReportRspCallback)(void *context,
+		QDF_STATUS qdf_status);
+
+typedef struct sRrmNeighborRspCallbackInfo {
+	uint32_t timeout;       /* in ms.. min value is 10 (10ms) */
+	NeighborReportRspCallback neighborRspCallback;
+	void *neighborRspCallbackContext;
+} tRrmNeighborRspCallbackInfo, *tpRrmNeighborRspCallbackInfo;
+
+typedef struct sRrmNeighborRequestControlInfo {
+	/* To check whether a neighbor req is already sent & response pending */
+	bool isNeighborRspPending;
+	qdf_mc_timer_t neighborRspWaitTimer;
+	tRrmNeighborRspCallbackInfo neighborRspCallbackInfo;
+} tRrmNeighborRequestControlInfo, *tpRrmNeighborRequestControlInfo;
+
+typedef struct sRrmSMEContext {
+	uint16_t token;
+	struct qdf_mac_addr sessionBssId;
+	uint8_t regClass;
+	/* list of all channels to be measured. */
+	tCsrChannelInfo channelList;
+	uint8_t currentIndex;
+	/* SSID used in the measuring beacon report. */
+	tAniSSID ssId;
+	tSirMacAddr bssId;      /* bssid used for beacon report measurement. */
+	/* Randomization interval to be used in subsequent measurements. */
+	uint16_t randnIntvl;
+	uint16_t duration[SIR_ESE_MAX_MEAS_IE_REQS];
+	uint8_t measMode[SIR_ESE_MAX_MEAS_IE_REQS];
+	struct rrm_config_param rrmConfig;
+	qdf_mc_timer_t IterMeasTimer;
+	tDblLinkList neighborReportCache;
+	tRrmNeighborRequestControlInfo neighborReqControlInfo;
+
+#ifdef FEATURE_WLAN_ESE
+	tCsrEseBeaconReq eseBcnReqInfo;
+	bool eseBcnReqInProgress;
+#endif /* FEATURE_WLAN_ESE */
+	tRrmMsgReqSource msgSource;
+	wlan_scan_requester req_id;
+	qdf_wake_lock_t scan_wake_lock;
+} tRrmSMEContext, *tpRrmSMEContext;
+
+typedef struct sRrmNeighborReq {
+	uint8_t no_ssid;
+	tSirMacSSid ssid;
+	bool neighbor_report_offload;
+} tRrmNeighborReq, *tpRrmNeighborReq;
+
+#endif /* #if !defined( __SMERRMINTERNAL_H ) */
diff --git a/core/sme/inc/sme_trace.h b/core/sme/inc/sme_trace.h
new file mode 100644
index 0000000..241282d
--- /dev/null
+++ b/core/sme/inc/sme_trace.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/**
+ * \sme_trace.h
+ *
+ * \brief definition for trace related APIs
+ */
+
+#ifndef __SME_TRACE_H__
+#define __SME_TRACE_H__
+
+#include "mac_trace.h"
+
+#define NO_SESSION 0xFF
+enum {
+	TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ,
+	TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS,
+	TRACE_CODE_SME_RX_HDD_MSG_CONNECT,
+	TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO,
+	TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN,
+	TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO,
+	TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG,
+	TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG,
+	TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND,
+	TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS,
+	TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS,
+	TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST,
+	TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETNEXT,
+	TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE,
+	TRACE_CODE_SME_RX_HDD_ROAM_REASSOC,
+	TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT,
+	TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE,
+	TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE,
+	TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE,
+	TRACE_CODE_SME_RX_HDD_ROAM_GET_PMKIDCACHE,
+	TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM,
+	TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS,
+	TRACE_CODE_SME_RX_HDD_SET_CONFIG_PWRSAVE,
+	TRACE_CODE_SME_RX_HDD_GET_CONFIG_PWRSAVE,
+	TRACE_CODE_SME_RX_HDD_ENABLE_PWRSAVE,
+	TRACE_CODE_SME_RX_HDD_DISABLE_PWRSAVE,
+	TRACE_CODE_SME_RX_HDD_SIGNAL_POWER_EVENT,
+	TRACE_CODE_SME_RX_HDD_START_AUTO_BMPSTIMER,
+	TRACE_CODE_SME_RX_HDD_STOP_AUTO_BMPSTIMER,
+	TRACE_CODE_SME_RX_HDD_IS_PWRSAVE_ENABLED,
+	TRACE_CODE_SME_RX_HDD_REQUEST_FULLPOWER,
+	TRACE_CODE_SME_RX_HDD_REQUEST_BMPS,
+	TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG,
+	TRACE_CODE_SME_RX_HDD_REQUEST_STANDBY,
+	TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN,
+	TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN,
+	TRACE_CODE_SME_RX_HDD_ENTER_WOWL,
+	TRACE_CODE_SME_RX_HDD_EXIT_WOWL,
+	TRACE_CODE_SME_RX_HDD_SET_KEY,
+	TRACE_CODE_SME_RX_HDD_REMOVE_KEY,
+	TRACE_CODE_SME_RX_HDD_GET_STATS,
+	TRACE_CODE_SME_RX_HDD_GET_RSSI,
+	TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE,
+	TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE,
+	TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY,
+	TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ,
+	TRACE_CODE_SME_RX_HDD_DBG_READREG,
+	TRACE_CODE_SME_RX_HDD_DBG_WRITEREG,
+	TRACE_CODE_SME_RX_HDD_DBG_READMEM,
+	TRACE_CODE_SME_RX_HDD_DBG_WRITEMEM,
+	TRACE_CODE_SME_RX_HDD_OPEN_SESSION,
+	TRACE_CODE_SME_RX_HDD_CLOSE_SESSION,
+	TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD,
+	TRACE_CODE_SME_RX_HDD_SET_GTKOFFLOAD,
+	TRACE_CODE_SME_RX_HDD_GET_GTKOFFLOAD,
+	TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN,
+	TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR,
+	TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR,
+	TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN,
+	TRACE_CODE_SME_RX_HDD_SEND_ACTION,
+	TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN,
+	TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL,
+	TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND,
+	TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ,
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+	TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW,
+	TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1,
+	TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2,
+#endif
+	TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW,
+	TRACE_CODE_SME_RX_HDD_SET_TXPOW,
+	TRACE_CODE_SME_RX_HDD_SET_TMLEVEL,
+	TRACE_CODE_SME_RX_HDD_CAPS_EXCH,
+	TRACE_CODE_SME_RX_HDD_DISABLE_CAP,
+	TRACE_CODE_SME_RX_HDD_GET_DEFCCNV,
+	TRACE_CODE_SME_RX_HDD_GET_CURCC,
+	TRACE_CODE_SME_RX_HDD_RESET_PW5G,
+	TRACE_CODE_SME_RX_HDD_UPDATE_RP5G,
+	TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND,
+	TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND,
+	TRACE_CODE_SME_RX_HDD_UPDATE_RSSIDIFF,
+	TRACE_CODE_SME_RX_HDD_UPDATE_IMMRSSIDIFF,
+	TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED,
+	TRACE_CODE_SME_RX_HDD_UPDATE_WESMODE,
+	TRACE_CODE_SME_RX_HDD_SET_SCANCTRL,
+	TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE,
+	TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES,
+	TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME,
+	TRACE_CODE_SME_RX_HDD_STORE_JOIN_REQ,
+	TRACE_CODE_SME_RX_HDD_CLEAR_JOIN_REQ,
+	TRACE_CODE_SME_RX_HDD_ISSUE_JOIN_REQ,
+	TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA,
+#ifdef FEATURE_WLAN_TDLS
+	TRACE_CODE_SME_RX_HDD_TDLS_LINK_ESTABLISH_PARAM,
+	TRACE_CODE_SME_RX_HDD_TDLS_CHAN_SWITCH_REQ,
+	TRACE_CODE_SME_RX_HDD_TDLS_SEND_MGMT_FRAME,
+	TRACE_CODE_SME_RX_HDD_TDLS_CHANGE_PEER_STA,
+	TRACE_CODE_SME_RX_HDD_TDLS_ADD_PEER_STA,
+	TRACE_CODE_SME_RX_HDD_TDLS_DEL_PEER_STA,
+#endif
+	TRACE_CODE_SME_RX_HDD_PREF_NET_LIST,
+	TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE,
+	TRACE_CODE_SME_RX_HDD_SEND_MGMT_TX,
+	/*
+	 * New trace commands to be added before this comment not at the end
+	 * Trace codes for SME commands
+	 */
+	TRACE_CODE_SME_COMMAND = 250,
+	TRACE_CODE_SME_TX_WMA_MSG,
+	TRACE_CODE_SME_RX_WMA_MSG,
+};
+
+void sme_trace_init(tpAniSirGlobal pMac);
+#endif /* __SME_TRACE_H__ */
diff --git a/core/sme/inc/wlan_ps_wow_diag.h b/core/sme/inc/wlan_ps_wow_diag.h
new file mode 100644
index 0000000..4702eb2
--- /dev/null
+++ b/core/sme/inc/wlan_ps_wow_diag.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2013-2014 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.
+ */
+
+#ifndef _WLAN_PS_WOW_DIAG_H_
+#define _WLAN_PS_WOW_DIAG_H_
+
+#include "host_diag_core_event.h"
+#include "host_diag_core_log.h"
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+
+typedef enum {
+	WLAN_BMPS_ENTER_REQ = 0,
+	WLAN_UAPSD_START_REQ = 1,
+	WLAN_UAPSD_STOP_REQ = 2,
+	WLAN_ENTER_STANDBY_REQ = 3,
+	WLAN_ENTER_DEEP_SLEEP_REQ = 4,
+	WLAN_START_BMPS_AUTO_TIMER_REQ = 5,
+	WLAN_STOP_BMPS_AUTO_TIMER_REQ = 6,
+	WLAN_ENTER_FULL_POWER_REQ = 7,
+	WLAN_PMC_CURRENT_STATE = 8,
+	WLAN_PS_MODE_ENABLE_REQ = 9,
+	WLAN_PS_MODE_DISABLE_REQ = 10,
+	WLAN_WINMOB_D_POWER_STATE = 11,
+	WLAN_BMPS_DTIM_PERIOD = 12,
+	WLAN_BMPS_FINAL_LI = 13,
+	WLAN_BMPS_SET_CONFIG = 14,
+
+} wlan_ps_evt_subtype_t;
+
+/* maps directly to eRequestFullPowerReason */
+typedef enum {
+	/* PE received a MAX_MISSED_BEACON_IND */
+	WLAN_MISSED_BEACON_IND_RCVD,
+	/* PE received a SIR_HAL_BMPS_STATUS_IND */
+	WLAN_BMPS_STATUS_IND_RCVD,
+	/* BMPS mode was disabled by HDD in SME */
+	WLAN_BMPS_MODE_DISABLED,
+	/* Link has been disconnected requested by HDD */
+	WLAN_LINK_DISCONNECTED_BY_HDD,
+	/* Disconnect due to linklost or requested by peer */
+	WLAN_LINK_DISCONNECTED_BY_OTHER,
+	/* HDD request full power for some reason */
+	WLAN_FULL_PWR_NEEDED_BY_HDD,
+	/* BAP request full power for BT_AMP */
+	WLAN_FULL_PWR_NEEDED_BY_BAP,
+	/* CSR requests full power */
+	WLAN_FULL_PWR_NEEDED_BY_CSR,
+	/* QOS requests full power */
+	WLAN_FULL_PWR_NEEDED_BY_QOS,
+	/* No specific reason. General reason code */
+	WLAN_REASON_OTHER
+} wlan_ps_full_power_request_reason_t;
+
+/* maps directly to ePmcState */
+typedef enum {
+	WLAN_PMC_STOPPED,       /* PMC is stopped */
+	WLAN_PMC_FULL_POWER,    /* full power */
+	WLAN_PMC_LOW_POWER,     /* low power */
+	WLAN_PMC_REQUEST_BMPS,  /* requesting BMPS */
+	WLAN_PMC_BMPS,          /* in BMPS */
+	WLAN_PMC_REQUEST_FULL_POWER,    /* requesting full power */
+	WLAN_PMC_REQUEST_START_UAPSD,   /* requesting Start UAPSD */
+	WLAN_PMC_REQUEST_STOP_UAPSD,    /* requesting Stop UAPSD */
+	WLAN_PMC_UAPSD,                 /* in UAPSD */
+	WLAN_PMC_REQUEST_STANDBY,       /* requesting standby mode */
+	WLAN_PMC_STANDBY,               /* in standby mode */
+	WLAN_PMC_REQUEST_ENTER_WOWL,    /* requesting enter WOWL */
+	WLAN_PMC_REQUEST_EXIT_WOWL,     /* requesting exit WOWL */
+	WLAN_PMC_WOWL                   /* Chip in WOWL mode */
+} wlan_ps_pmc_current_state_t;
+
+/* maps directly to ePmcPowerSavingMode */
+typedef enum {
+	WLAN_IDLE_MODE_POWER_SAVE,      /* Idle Mode Power Save (IMPS) */
+	WLAN_BEACON_MODE_POWER_SAVE,    /* Beacon Mode Power Save (BMPS) */
+	WLAN_SPATIAL_MULTIPLEX_POWER_SAVE, /* Spatial Multiplexing Power Save */
+	WLAN_UAPSD_MODE_POWER_SAVE,     /* Unscheduled Auto PS Delivery Mode */
+	WLAN_STANDBY_MODE_POWER_SAVE,   /* Standby Power Save Mode */
+	WLAN_WOWL_MODE_POWER_SAVE       /* Wake-on-Wireless Power Save Mode */
+} wlan_ps_enable_disable_ps_mode_t;
+
+typedef enum {
+	WLAN_D0,
+	WLAN_D1,
+	WLAN_D2,
+	WLAN_D3,
+	WLAN_D4
+} wlan_ps_winmob_d_power_state_t;
+
+typedef enum {
+	WLAN_WOW_ENTER_REQ = 0,
+	WLAN_WOW_EXIT_REQ = 1,
+	WLAN_WOW_DEL_PTRN_REQ = 2,
+	WLAN_WOW_WAKEUP = 3
+} wlan_ps_wow_evt_subtype_t;
+
+typedef enum {
+	WLAN_WOW_TYPE_NONE,
+	WLAN_WOW_TYPE_MAGIC_PKT_ONLY,
+	WLAN_WOW_TYPE_PTRN_BYTE_MATCH_ONLY,
+	WLAN_WOW_TYPE_MAGIC_PKT_PTRN_BYTE_MATCH,
+} wlan_ps_wow_type_t;
+
+typedef enum {
+	WLAN_WOW_MAGIC_PKT_MATCH,
+	WLAN_WOW_PTRN_BYTE_MATCH
+} wlan_ps_wos_wakeup_cause_t;
+
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+#endif /* _WLAN_PS_WOW_DIAG_H_ */
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
new file mode 100644
index 0000000..476d6ca
--- /dev/null
+++ b/core/sme/src/common/sme_api.c
@@ -0,0 +1,16261 @@
+/*
+ * Copyright (c) 2012-2018 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: sme_api.c
+ *
+ * Definitions for SME APIs
+ */
+
+/* Include Files */
+#include <sir_common.h>
+#include <ani_global.h>
+#include "sme_api.h"
+#include "csr_inside_api.h"
+#include "sme_inside.h"
+#include "csr_internal.h"
+#include "wma_types.h"
+#include "wma_if.h"
+#include "wma_fips_api.h"
+#include "qdf_trace.h"
+#include "sme_trace.h"
+#include "qdf_types.h"
+#include "qdf_trace.h"
+#include "cds_utils.h"
+#include "sap_api.h"
+#include "mac_trace.h"
+#ifdef WLAN_FEATURE_NAN
+#include "nan_api.h"
+#endif
+#include "cds_regdomain.h"
+#include "cfg_api.h"
+#include "sme_power_save_api.h"
+#include "wma.h"
+#include "sch_api.h"
+#include "sme_nan_datapath.h"
+#include "csr_api.h"
+#include "wlan_reg_services_api.h"
+#include <wlan_scan_ucfg_api.h>
+#include "wlan_reg_ucfg_api.h"
+#include "ol_txrx.h"
+#include "wifi_pos_api.h"
+#include "net/cfg80211.h"
+#include <qca_vendor.h>
+#include <wlan_spectral_utils_api.h>
+#include "wlan_mlme_public_struct.h"
+
+static tSelfRecoveryStats g_self_recovery_stats;
+
+static QDF_STATUS init_sme_cmd_list(tpAniSirGlobal pMac);
+
+static void sme_disconnect_connected_sessions(tpAniSirGlobal pMac);
+
+static QDF_STATUS sme_handle_generic_change_country_code(tpAniSirGlobal pMac,
+						  void *pMsgBuf);
+
+static QDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg);
+
+/* Channel Change Response Indication Handler */
+static QDF_STATUS sme_process_channel_change_resp(tpAniSirGlobal pMac,
+					   uint16_t msg_type, void *pMsgBuf);
+
+static QDF_STATUS sme_stats_ext_event(tpAniSirGlobal mac,
+				      struct stats_ext_event *msg);
+
+/* Internal SME APIs */
+QDF_STATUS sme_acquire_global_lock(tSmeStruct *psSme)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	if (psSme) {
+		if (QDF_IS_STATUS_SUCCESS
+			    (qdf_mutex_acquire(&psSme->lkSmeGlobalLock)))
+			status = QDF_STATUS_SUCCESS;
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_release_global_lock(tSmeStruct *psSme)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	if (psSme) {
+		if (QDF_IS_STATUS_SUCCESS
+			    (qdf_mutex_release(&psSme->lkSmeGlobalLock)))
+			status = QDF_STATUS_SUCCESS;
+	}
+
+	return status;
+}
+
+tpAniSirGlobal sme_get_mac_context(void)
+{
+	tpAniSirGlobal mac_ctx;
+	tHalHandle h_hal;
+
+	h_hal = cds_get_context(QDF_MODULE_ID_SME);
+	if (NULL == h_hal) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
+		FL("invalid h_hal"));
+		return NULL;
+	}
+
+	mac_ctx = PMAC_STRUCT(h_hal);
+
+	return mac_ctx;
+}
+
+/**
+ * sme_process_set_hw_mode_resp() - Process set HW mode response
+ * @mac: Global MAC pointer
+ * @msg: HW mode response
+ *
+ * Processes the HW mode response and invokes the HDD callback
+ * to process further
+ */
+static QDF_STATUS sme_process_set_hw_mode_resp(tpAniSirGlobal mac, uint8_t *msg)
+{
+	tListElem *entry;
+	tSmeCmd *command = NULL;
+	bool found;
+	policy_mgr_pdev_set_hw_mode_cback callback = NULL;
+	struct sir_set_hw_mode_resp *param;
+	enum policy_mgr_conn_update_reason reason;
+	struct csr_roam_session *session;
+	uint32_t session_id;
+
+	param = (struct sir_set_hw_mode_resp *)msg;
+	if (!param) {
+		sme_err("HW mode resp param is NULL");
+		/* Not returning. Need to check if active command list
+		 * needs to be freed
+		 */
+	}
+
+	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
+	if (!entry) {
+		sme_err("No cmd found in active list");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+	if (!command) {
+		sme_err("Base address is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (e_sme_command_set_hw_mode != command->command) {
+		sme_err("Command mismatch!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	callback = command->u.set_hw_mode_cmd.set_hw_mode_cb;
+	reason = command->u.set_hw_mode_cmd.reason;
+	session_id = command->u.set_hw_mode_cmd.session_id;
+
+	sme_debug("reason: %d session: %d",
+		command->u.set_hw_mode_cmd.reason,
+		command->u.set_hw_mode_cmd.session_id);
+
+	if (!callback) {
+		sme_err("Callback does not exist");
+		goto end;
+	}
+
+	if (!param) {
+		sme_err("Callback failed since HW mode params is NULL");
+		goto end;
+	}
+
+	/* Irrespective of the reason for which the hw mode change request
+	 * was issued, the policy manager connection table needs to be updated
+	 * with the new vdev-mac id mapping, tx/rx spatial streams etc., if the
+	 * set hw mode was successful.
+	 */
+	callback(param->status,
+			param->cfgd_hw_mode_index,
+			param->num_vdev_mac_entries,
+			param->vdev_mac_map,
+			command->u.set_hw_mode_cmd.next_action,
+			command->u.set_hw_mode_cmd.reason,
+			command->u.set_hw_mode_cmd.session_id,
+			command->u.set_hw_mode_cmd.context);
+	if (!CSR_IS_SESSION_VALID(mac, session_id)) {
+		sme_err("session %d is invalid", session_id);
+		goto end;
+	}
+	session = CSR_GET_SESSION(mac, session_id);
+	if (reason == POLICY_MGR_UPDATE_REASON_HIDDEN_STA) {
+		/* In the case of hidden SSID, connection update
+		 * (set hw mode) is done after the scan with reason
+		 * code eCsrScanForSsid completes. The connect/failure
+		 * needs to be handled after the response of set hw
+		 * mode
+		 */
+		if (param->status == SET_HW_MODE_STATUS_OK) {
+			sme_debug("search for ssid success");
+			csr_scan_handle_search_for_ssid(mac,
+					session_id);
+		} else {
+			sme_debug("search for ssid failure");
+			csr_scan_handle_search_for_ssid_failure(mac,
+					session_id);
+		}
+		csr_saved_scan_cmd_free_fields(mac, session);
+	}
+
+end:
+	found = csr_nonscan_active_ll_remove_entry(mac, entry,
+			LL_ACCESS_LOCK);
+	if (found)
+		/* Now put this command back on the avilable command list */
+		csr_release_command(mac, command);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_process_hw_mode_trans_ind() - Process HW mode transition indication
+ * @mac: Global MAC pointer
+ * @msg: HW mode transition response
+ *
+ * Processes the HW mode transition indication and invoke the HDD callback
+ * to process further
+ */
+static QDF_STATUS sme_process_hw_mode_trans_ind(tpAniSirGlobal mac,
+						uint8_t *msg)
+{
+	struct sir_hw_mode_trans_ind *param;
+
+	param = (struct sir_hw_mode_trans_ind *)msg;
+	if (!param) {
+		sme_err("HW mode trans ind param is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	policy_mgr_hw_mode_transition_cb(param->old_hw_mode_index,
+		param->new_hw_mode_index,
+		param->num_vdev_mac_entries,
+		param->vdev_mac_map, mac->psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * free_sme_cmds() - This function frees memory allocated for SME commands
+ * @mac_ctx:      Pointer to Global MAC structure
+ *
+ * This function frees memory allocated for SME commands
+ *
+ * @Return: void
+ */
+static void free_sme_cmds(tpAniSirGlobal mac_ctx)
+{
+	uint32_t idx;
+
+	if (NULL == mac_ctx->sme.pSmeCmdBufAddr)
+		return;
+
+	for (idx = 0; idx < mac_ctx->sme.totalSmeCmd; idx++)
+		qdf_mem_free(mac_ctx->sme.pSmeCmdBufAddr[idx]);
+
+	qdf_mem_free(mac_ctx->sme.pSmeCmdBufAddr);
+	mac_ctx->sme.pSmeCmdBufAddr = NULL;
+}
+
+static QDF_STATUS init_sme_cmd_list(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status;
+	tSmeCmd *pCmd;
+	uint32_t cmd_idx;
+	uint32_t sme_cmd_ptr_ary_sz;
+
+	pMac->sme.totalSmeCmd = SME_TOTAL_COMMAND;
+
+
+	status = csr_ll_open(&pMac->sme.smeCmdFreeList);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		goto end;
+
+	/* following pointer contains array of pointers for tSmeCmd* */
+	sme_cmd_ptr_ary_sz = sizeof(void *) * pMac->sme.totalSmeCmd;
+	pMac->sme.pSmeCmdBufAddr = qdf_mem_malloc(sme_cmd_ptr_ary_sz);
+	if (!pMac->sme.pSmeCmdBufAddr) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+
+	status = QDF_STATUS_SUCCESS;
+	for (cmd_idx = 0; cmd_idx < pMac->sme.totalSmeCmd; cmd_idx++) {
+		/*
+		 * Since total size of all commands together can be huge chunk
+		 * of memory, allocate SME cmd individually. These SME CMDs are
+		 * moved between pending and active queues. And these freeing of
+		 * these queues just manipulates the list but does not actually
+		 * frees SME CMD pointers. Hence store each SME CMD address in
+		 * the array, sme.pSmeCmdBufAddr. This will later facilitate
+		 * freeing up of all SME CMDs with just a for loop.
+		 */
+		pMac->sme.pSmeCmdBufAddr[cmd_idx] =
+						qdf_mem_malloc(sizeof(tSmeCmd));
+		if (NULL == pMac->sme.pSmeCmdBufAddr[cmd_idx]) {
+			status = QDF_STATUS_E_NOMEM;
+			free_sme_cmds(pMac);
+			goto end;
+		}
+		pCmd = (tSmeCmd *)pMac->sme.pSmeCmdBufAddr[cmd_idx];
+		csr_ll_insert_tail(&pMac->sme.smeCmdFreeList,
+				&pCmd->Link, LL_ACCESS_LOCK);
+	}
+
+end:
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		sme_err("Failed to initialize sme command list: %d", status);
+
+	return status;
+}
+
+void sme_release_command(tpAniSirGlobal mac_ctx, tSmeCmd *sme_cmd)
+{
+	sme_cmd->command = eSmeNoCommand;
+	csr_ll_insert_tail(&mac_ctx->sme.smeCmdFreeList, &sme_cmd->Link,
+			   LL_ACCESS_LOCK);
+}
+
+static QDF_STATUS free_sme_cmd_list(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	csr_ll_close(&pMac->sme.smeCmdFreeList);
+
+	status = qdf_mutex_acquire(&pMac->sme.lkSmeGlobalLock);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("Failed to acquire the lock status: %d", status);
+		goto done;
+	}
+
+	free_sme_cmds(pMac);
+
+	status = qdf_mutex_release(&pMac->sme.lkSmeGlobalLock);
+	if (status != QDF_STATUS_SUCCESS)
+		sme_err("Failed to release the lock status: %d", status);
+done:
+	return status;
+}
+
+static void dump_csr_command_info(tpAniSirGlobal pMac, tSmeCmd *pCmd)
+{
+	switch (pCmd->command) {
+	case eSmeCommandRoam:
+		sme_debug("roam command reason is %d",
+			pCmd->u.roamCmd.roamReason);
+		break;
+
+	case eSmeCommandWmStatusChange:
+		sme_debug("WMStatusChange command type is %d",
+			pCmd->u.wmStatusChangeCmd.Type);
+		break;
+
+	case e_sme_command_del_sta_session:
+		sme_debug("Issue del STA command for session:%d",
+			   pCmd->sessionId);
+		break;
+
+	default:
+		sme_debug("default: Unhandled command %d",
+			pCmd->command);
+		break;
+	}
+}
+
+tSmeCmd *sme_get_command_buffer(tpAniSirGlobal pMac)
+{
+	tSmeCmd *pRetCmd = NULL, *pTempCmd = NULL;
+	tListElem *pEntry;
+	static int sme_command_queue_full;
+
+	pEntry = csr_ll_remove_head(&pMac->sme.smeCmdFreeList, LL_ACCESS_LOCK);
+
+	/* If we can get another MS Msg buffer, then we are ok.  Just link */
+	/* the entry onto the linked list.  (We are using the linked list */
+	/* to keep track of tfhe message buffers). */
+	if (pEntry) {
+		pRetCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		/* reset when free list is available */
+		sme_command_queue_full = 0;
+	} else {
+		int idx = 1;
+
+		/* Cannot change pRetCmd here since it needs to return later. */
+		pEntry = csr_nonscan_active_ll_peek_head(pMac, LL_ACCESS_LOCK);
+		if (pEntry)
+			pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+
+		sme_err("Out of command buffer.... command (0x%X) stuck",
+			(pTempCmd) ? pTempCmd->command : eSmeNoCommand);
+		if (pTempCmd) {
+			if (eSmeCsrCommandMask & pTempCmd->command)
+				/* CSR command is stuck. See what the reason
+				 * code is for that command
+				 */
+				dump_csr_command_info(pMac, pTempCmd);
+		} /* if(pTempCmd) */
+
+		/* dump what is in the pending queue */
+		csr_nonscan_pending_ll_lock(pMac);
+		pEntry =
+			csr_nonscan_pending_ll_peek_head(pMac,
+					 LL_ACCESS_NOLOCK);
+		while (pEntry && !sme_command_queue_full) {
+			pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+			/* Print only 1st five commands from pending queue. */
+			if (idx <= 5)
+				sme_err("Out of command buffer.... SME pending command #%d (0x%X)",
+					idx, pTempCmd->command);
+			idx++;
+			if (eSmeCsrCommandMask & pTempCmd->command)
+				/* CSR command is stuck. See what the reason
+				 * code is for that command
+				 */
+				dump_csr_command_info(pMac, pTempCmd);
+			pEntry = csr_nonscan_pending_ll_next(pMac, pEntry,
+					    LL_ACCESS_NOLOCK);
+		}
+		csr_nonscan_pending_ll_unlock(pMac);
+
+		if (pMac->mlme_cfg->gen.fatal_event_trigger)
+			cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+				WLAN_LOG_INDICATOR_HOST_DRIVER,
+				WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF,
+				false,
+				pMac->mlme_cfg->gen.self_recovery);
+		else
+			cds_trigger_recovery(QDF_GET_MSG_BUFF_FAILURE);
+	}
+
+	/* memset to zero */
+	if (pRetCmd) {
+		qdf_mem_set((uint8_t *)&pRetCmd->command,
+			    sizeof(pRetCmd->command), 0);
+		qdf_mem_set((uint8_t *)&pRetCmd->sessionId,
+			    sizeof(pRetCmd->sessionId), 0);
+		qdf_mem_set((uint8_t *)&pRetCmd->u, sizeof(pRetCmd->u), 0);
+	}
+
+	return pRetCmd;
+}
+
+/**
+ * sme_ser_handle_active_cmd() - handle command activation callback from
+ *					new serialization module
+ * @cmd: pointer to new serialization command
+ *
+ * This API is to handle command activation callback from new serialization
+ * callback
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+static
+QDF_STATUS sme_ser_handle_active_cmd(struct wlan_serialization_command *cmd)
+{
+	tSmeCmd *sme_cmd;
+	tHalHandle hal;
+	tpAniSirGlobal mac_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	bool do_continue;
+
+	if (!cmd) {
+		sme_err("No serialization command found");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hal = cds_get_context(QDF_MODULE_ID_SME);
+	if (NULL != hal) {
+		mac_ctx = PMAC_STRUCT(hal);
+	} else {
+		sme_err("No hal found");
+		return QDF_STATUS_E_FAILURE;
+	}
+	sme_cmd = cmd->umac_cmd;
+	if (!sme_cmd) {
+		sme_err("No SME command found");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	switch (sme_cmd->command) {
+	case eSmeCommandRoam:
+		status = csr_roam_process_command(mac_ctx, sme_cmd);
+		break;
+	case eSmeCommandWmStatusChange:
+		csr_roam_process_wm_status_change_command(mac_ctx,
+					sme_cmd);
+		break;
+	case e_sme_command_del_sta_session:
+		csr_process_del_sta_session_command(mac_ctx, sme_cmd);
+		break;
+	case eSmeCommandAddTs:
+	case eSmeCommandDelTs:
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		do_continue = qos_process_command(mac_ctx, sme_cmd);
+		if (do_continue)
+			status = QDF_STATUS_E_FAILURE;
+#endif
+		break;
+	case e_sme_command_set_hw_mode:
+		csr_process_set_hw_mode(mac_ctx, sme_cmd);
+		break;
+	case e_sme_command_nss_update:
+		csr_process_nss_update_req(mac_ctx, sme_cmd);
+		break;
+	case e_sme_command_set_dual_mac_config:
+		csr_process_set_dual_mac_config(mac_ctx, sme_cmd);
+		break;
+	case e_sme_command_set_antenna_mode:
+		csr_process_set_antenna_mode(mac_ctx, sme_cmd);
+		break;
+	default:
+		/* something is wrong */
+		sme_err("unknown command %d", sme_cmd->command);
+		status = QDF_STATUS_E_FAILURE;
+		break;
+	}
+	return status;
+}
+
+QDF_STATUS sme_ser_cmd_callback(void *buf,
+				enum wlan_serialization_cb_reason reason)
+{
+	struct wlan_serialization_command *cmd = buf;
+	tHalHandle hal;
+	tpAniSirGlobal mac_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeCmd *sme_cmd;
+
+	hal = cds_get_context(QDF_MODULE_ID_SME);
+	if (hal != NULL) {
+		mac_ctx = PMAC_STRUCT(hal);
+	} else {
+		sme_err("hal is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/*
+	 * Do not acquire lock here as sme global lock is already acquired in
+	 * caller or MC thread context
+	 */
+	if (!cmd) {
+		sme_err("serialization command is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	switch (reason) {
+	case WLAN_SER_CB_ACTIVATE_CMD:
+		sme_debug("WLAN_SER_CB_ACTIVATE_CMD callback");
+		status = sme_ser_handle_active_cmd(cmd);
+		break;
+	case WLAN_SER_CB_CANCEL_CMD:
+		sme_debug("WLAN_SER_CB_CANCEL_CMD callback");
+		break;
+	case WLAN_SER_CB_RELEASE_MEM_CMD:
+		sme_debug("WLAN_SER_CB_RELEASE_MEM_CMD callback");
+		if (cmd->vdev)
+			wlan_objmgr_vdev_release_ref(cmd->vdev,
+						     WLAN_LEGACY_SME_ID);
+		sme_cmd = cmd->umac_cmd;
+		csr_release_command_buffer(mac_ctx, sme_cmd);
+		break;
+	case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
+		sme_debug("WLAN_SER_CB_ACTIVE_CMD_TIMEOUT callback");
+		break;
+	default:
+		sme_debug("STOP: unknown reason code");
+		return QDF_STATUS_E_FAILURE;
+	}
+	return status;
+}
+
+#ifdef WLAN_FEATURE_MEMDUMP_ENABLE
+/**
+ * sme_get_sessionid_from_activelist() - gets session id
+ * @mac: mac context
+ *
+ * This function is used to get session id from sme command
+ * active list
+ *
+ * Return: returns session id
+ */
+static uint32_t sme_get_sessionid_from_activelist(tpAniSirGlobal mac)
+{
+	tListElem *entry;
+	tSmeCmd *command;
+	uint32_t session_id = CSR_SESSION_ID_INVALID;
+
+	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
+	if (entry) {
+		command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+		session_id = command->sessionId;
+	}
+
+	return session_id;
+}
+
+/**
+ * sme_state_info_dump() - prints state information of sme layer
+ * @buf: buffer pointer
+ * @size: size of buffer to be filled
+ *
+ * This function is used to dump state information of sme layer
+ *
+ * Return: None
+ */
+static void sme_state_info_dump(char **buf_ptr, uint16_t *size)
+{
+	uint32_t session_id, active_session_id;
+	tHalHandle hal;
+	tpAniSirGlobal mac;
+	uint16_t len = 0;
+	char *buf = *buf_ptr;
+	eCsrConnectState connect_state;
+
+	hal = cds_get_context(QDF_MODULE_ID_SME);
+	if (hal == NULL) {
+		QDF_ASSERT(0);
+		return;
+	}
+
+	mac = PMAC_STRUCT(hal);
+
+	active_session_id = sme_get_sessionid_from_activelist(mac);
+	if (active_session_id != CSR_SESSION_ID_INVALID) {
+		len += qdf_scnprintf(buf + len, *size - len,
+			"\n active command sessionid %d", active_session_id);
+	}
+
+	for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
+		if (CSR_IS_SESSION_VALID(mac, session_id)) {
+			connect_state =
+				mac->roam.roamSession[session_id].connectState;
+			if ((eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED ==
+			     connect_state)
+			    || (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED ==
+				connect_state)) {
+				len += qdf_scnprintf(buf + len, *size - len,
+					"\n NeighborRoamState: %d",
+					mac->roam.neighborRoamInfo[session_id].
+						neighborRoamState);
+				len += qdf_scnprintf(buf + len, *size - len,
+					"\n RoamState: %d", mac->roam.
+						curState[session_id]);
+				len += qdf_scnprintf(buf + len, *size - len,
+					"\n RoamSubState: %d", mac->roam.
+						curSubState[session_id]);
+				len += qdf_scnprintf(buf + len, *size - len,
+					"\n ConnectState: %d",
+					connect_state);
+			}
+		}
+	}
+
+	*size -= len;
+	*buf_ptr += len;
+}
+
+/**
+ * sme_register_debug_callback() - registration function sme layer
+ * to print sme state information
+ *
+ * Return: None
+ */
+static void sme_register_debug_callback(void)
+{
+	qdf_register_debug_callback(QDF_MODULE_ID_SME, &sme_state_info_dump);
+}
+#else /* WLAN_FEATURE_MEMDUMP_ENABLE */
+static void sme_register_debug_callback(void)
+{
+}
+#endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
+
+/* Global APIs */
+
+/**
+ * sme_open() - Initialze all SME modules and put them at idle state
+ * @hHal:       The handle returned by mac_open
+ *
+ * The function initializes each module inside SME, PMC, CSR, etc. Upon
+ * successfully return, all modules are at idle state ready to start.
+ * smeOpen must be called before any other SME APIs can be involved.
+ * smeOpen must be called after mac_open.
+ *
+ * Return: QDF_STATUS_SUCCESS - SME is successfully initialized.
+ *         Other status means SME is failed to be initialized
+ */
+QDF_STATUS sme_open(tHalHandle hHal)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	pMac->sme.state = SME_STATE_STOP;
+	pMac->sme.currDeviceMode = QDF_STA_MODE;
+	if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create(
+					&pMac->sme.lkSmeGlobalLock))) {
+		sme_err("Init lock failed");
+		return  QDF_STATUS_E_FAILURE;
+	}
+	status = csr_open(pMac);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("csr_open failed, status: %d", status);
+		return status;
+	}
+
+	status = sme_ps_open(hHal);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("sme_ps_open failed with status: %d", status);
+		return status;
+	}
+
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	status = sme_qos_open(pMac);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Qos open, status: %d", status);
+		return status;
+	}
+#endif
+	status = init_sme_cmd_list(pMac);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	status = rrm_open(pMac);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("rrm_open failed, status: %d", status);
+		return status;
+	}
+	sme_trace_init(pMac);
+	sme_register_debug_callback();
+	wlan_serialization_legacy_init_callback();
+
+	return status;
+}
+
+/*
+ * sme_init_chan_list, triggers channel setup based on country code.
+ */
+QDF_STATUS sme_init_chan_list(tHalHandle hal, uint8_t *alpha2,
+			      enum country_src cc_src)
+{
+	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
+
+	if ((cc_src == SOURCE_USERSPACE) &&
+	    (pmac->roam.configParam.fSupplicantCountryCodeHasPriority)) {
+		pmac->roam.configParam.Is11dSupportEnabled = false;
+	}
+
+	return csr_init_chan_list(pmac, alpha2);
+}
+
+/*
+ * sme_set11dinfo() - Set the 11d information about valid channels
+ *  and there power using information from nvRAM
+ *  This function is called only for AP.
+ *
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * pSmeConfigParams - a pointer to a caller allocated object of
+ *  typedef struct _smeConfigParams.
+ *
+ * Return QDF_STATUS_SUCCESS - SME update the config parameters successfully.
+ *
+ *  Other status means SME is failed to update the config parameters.
+ */
+
+QDF_STATUS sme_set11dinfo(tHalHandle hal, tpSmeConfigParams pSmeConfigParams)
+{
+	tpAniSirGlobal mac_ctx = MAC_CONTEXT(hal);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, NO_SESSION, 0));
+	if (NULL == pSmeConfigParams) {
+		sme_err("SME config params empty");
+		return status;
+	}
+
+	status = csr_set_channels(mac_ctx, &pSmeConfigParams->csrConfig);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		sme_err("csr_set_channels failed with status: %d", status);
+
+	return status;
+}
+
+/**
+ * sme_set_scan_disable() - Dynamically enable/disable scan
+ * @h_hal: Handle to HAL
+ *
+ * This command gives the user an option to dynamically
+ * enable or disable scans.
+ *
+ * Return: None
+ */
+void sme_set_scan_disable(tHalHandle h_hal, int value)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal);
+
+	sme_info("scan disable %d", value);
+	ucfg_scan_set_enable(mac_ctx->psoc, !value);
+}
+/*
+ * sme_get_soft_ap_domain() - Get the current regulatory domain of softAp.
+ * This is a synchronous call
+ *
+ * hHal - The handle returned by HostapdAdapter.
+ * v_REGDOMAIN_t - The current Regulatory Domain requested for SoftAp.
+ * Return QDF_STATUS_SUCCESS - SME successfully completed the request.
+ *  Other status means, failed to get the current regulatory domain.
+ */
+
+QDF_STATUS sme_get_soft_ap_domain(tHalHandle hHal, v_REGDOMAIN_t
+				*domainIdSoftAp)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN,
+			 NO_SESSION, 0));
+	if (NULL == domainIdSoftAp) {
+		sme_err("Uninitialized domain Id");
+		return status;
+	}
+
+	*domainIdSoftAp = pMac->scan.domainIdCurrent;
+	status = QDF_STATUS_SUCCESS;
+
+	return status;
+}
+
+/**
+ * sme_update_fine_time_measurement_capab() - Update the FTM capabitlies from
+ * incoming val
+ * @hal: Handle for Hal layer
+ * @val: New FTM capability value
+ *
+ * Return: None
+ */
+void sme_update_fine_time_measurement_capab(tHalHandle hal, uint8_t session_id,
+						uint32_t val)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	QDF_STATUS status;
+
+	ucfg_wifi_pos_set_ftm_cap(mac_ctx->psoc, val);
+
+	if (!val) {
+		mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 0;
+		((tpRRMCaps)mac_ctx->rrm.rrmSmeContext.
+			rrmConfig.rm_capability)->fine_time_meas_rpt = 0;
+	} else {
+		mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 1;
+		((tpRRMCaps)mac_ctx->rrm.rrmSmeContext.
+			rrmConfig.rm_capability)->fine_time_meas_rpt = 1;
+	}
+
+	/* Inform this RRM IE change to FW */
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		csr_roam_offload_scan(mac_ctx, session_id,
+			ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+			REASON_CONNECT_IES_CHANGED);
+		sme_release_global_lock(&mac_ctx->sme);
+	} else {
+		sme_err("Failed to acquire SME lock");
+	}
+}
+
+/*
+ * sme_update_config() - Change configurations for all SME moduels
+ * The function updates some configuration for modules in SME, CSR, etc
+ *  during SMEs close open sequence.
+ * Modules inside SME apply the new configuration at the next transaction.
+ * This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * pSmeConfigParams - a pointer to a caller allocated object of
+ *  typedef struct _smeConfigParams.
+ * Return QDF_STATUS_SUCCESS - SME update the config parameters successfully.
+ *  Other status means SME is failed to update the config parameters.
+ */
+QDF_STATUS sme_update_config(tHalHandle hHal, tpSmeConfigParams
+				pSmeConfigParams)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, NO_SESSION,
+			 0));
+	if (NULL == pSmeConfigParams) {
+		sme_err("SME config params empty");
+		return status;
+	}
+
+	status = csr_change_default_config_param(pMac, &pSmeConfigParams->
+						csrConfig);
+
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		sme_err("csr_change_default_config_param failed status: %d",
+			status);
+
+	status = rrm_change_default_config_param(pMac, &pSmeConfigParams->
+						rrmConfig);
+
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		sme_err("rrm_change_default_config_param failed status: %d",
+			status);
+
+	/* For SOC, CFG is set before start We don't want to apply global CFG
+	 * in connect state because that may cause some side affect
+	 */
+	if (csr_is_all_session_disconnected(pMac))
+		csr_set_global_cfgs(pMac);
+
+	/*
+	 * If scan offload is enabled then lim has allow the sending of
+	 * scan request to firmware even in powersave mode. The firmware has
+	 * to take care of exiting from power save mode
+	 */
+	status = sme_cfg_set_int(hHal, WNI_CFG_SCAN_IN_POWERSAVE, true);
+
+	if (QDF_STATUS_SUCCESS != status)
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "Could not pass on WNI_CFG_SCAN_IN_POWERSAVE to CFG");
+
+	pMac->snr_monitor_enabled = pSmeConfigParams->snr_monitor_enabled;
+
+	return status;
+}
+
+/**
+ * sme_update_scan_roam_params() - Update the scan roaming params
+ * @mac_ctx: mac ctx
+ *
+ * Return: void.
+ */
+static void sme_update_scan_roam_params(tpAniSirGlobal mac_ctx)
+{
+	struct roam_filter_params scan_params = {0};
+	struct roam_ext_params *roam_params_src;
+	uint8_t i;
+	QDF_STATUS status;
+
+	roam_params_src = &mac_ctx->roam.configParam.roam_params;
+
+	scan_params.num_bssid_avoid_list =
+		roam_params_src->num_bssid_avoid_list;
+
+	if (scan_params.num_bssid_avoid_list >
+	   MAX_AVOID_LIST_BSSID)
+		scan_params.num_bssid_avoid_list =
+			MAX_AVOID_LIST_BSSID;
+
+	for (i = 0; i < scan_params.num_bssid_avoid_list; i++) {
+		qdf_copy_macaddr(&scan_params.bssid_avoid_list[i],
+				&roam_params_src->bssid_avoid_list[i]);
+	}
+
+	status = ucfg_scan_update_roam_params(mac_ctx->psoc, &scan_params);
+	if (QDF_IS_STATUS_ERROR(status))
+		sme_err("ailed to update scan roam params with status=%d",
+			status);
+}
+
+/**
+ * sme_update_roam_params() - Store/Update the roaming params
+ * @hal:                      Handle for Hal layer
+ * @session_id:               SME Session ID
+ * @roam_params_src:          The source buffer to copy
+ * @update_param:             Type of parameter to be updated
+ *
+ * Return: Return the status of the updation.
+ */
+QDF_STATUS sme_update_roam_params(tHalHandle hal,
+	uint8_t session_id, struct roam_ext_params *roam_params_src,
+	int update_param)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct roam_ext_params *roam_params_dst;
+	QDF_STATUS status;
+	uint8_t i;
+
+	roam_params_dst = &mac_ctx->roam.configParam.roam_params;
+	switch (update_param) {
+	case REASON_ROAM_EXT_SCAN_PARAMS_CHANGED:
+		mac_ctx->mlme_cfg->lfr.rssi_boost_threshold_5g =
+			roam_params_src->raise_rssi_thresh_5g;
+		mac_ctx->mlme_cfg->lfr.rssi_penalize_threshold_5g =
+			roam_params_src->drop_rssi_thresh_5g;
+		mac_ctx->mlme_cfg->lfr.rssi_boost_factor_5g =
+			roam_params_src->raise_factor_5g;
+		mac_ctx->mlme_cfg->lfr.rssi_penalize_factor_5g =
+			roam_params_src->drop_factor_5g;
+		mac_ctx->mlme_cfg->lfr.max_rssi_boost_5g =
+			roam_params_src->max_raise_rssi_5g;
+		mac_ctx->mlme_cfg->lfr.max_rssi_penalize_5g =
+			roam_params_src->max_drop_rssi_5g;
+		roam_params_dst->alert_rssi_threshold =
+			roam_params_src->alert_rssi_threshold;
+		mac_ctx->mlme_cfg->lfr.enable_5g_band_pref = true;
+		break;
+	case REASON_ROAM_SET_SSID_ALLOWED:
+		qdf_mem_set(&roam_params_dst->ssid_allowed_list, 0,
+				sizeof(tSirMacSSid) * MAX_SSID_ALLOWED_LIST);
+		roam_params_dst->num_ssid_allowed_list =
+			roam_params_src->num_ssid_allowed_list;
+		for (i = 0; i < roam_params_dst->num_ssid_allowed_list; i++) {
+			roam_params_dst->ssid_allowed_list[i].length =
+				roam_params_src->ssid_allowed_list[i].length;
+			qdf_mem_copy(roam_params_dst->ssid_allowed_list[i].ssId,
+				roam_params_src->ssid_allowed_list[i].ssId,
+				roam_params_dst->ssid_allowed_list[i].length);
+		}
+		break;
+	case REASON_ROAM_SET_FAVORED_BSSID:
+		qdf_mem_set(&roam_params_dst->bssid_favored, 0,
+			sizeof(tSirMacAddr) * MAX_BSSID_FAVORED);
+		roam_params_dst->num_bssid_favored =
+			roam_params_src->num_bssid_favored;
+		for (i = 0; i < roam_params_dst->num_bssid_favored; i++) {
+			qdf_mem_copy(&roam_params_dst->bssid_favored[i],
+				&roam_params_src->bssid_favored[i],
+				sizeof(tSirMacAddr));
+			roam_params_dst->bssid_favored_factor[i] =
+				roam_params_src->bssid_favored_factor[i];
+		}
+		break;
+	case REASON_ROAM_SET_BLACKLIST_BSSID:
+		qdf_mem_set(&roam_params_dst->bssid_avoid_list, 0,
+			QDF_MAC_ADDR_SIZE * MAX_BSSID_AVOID_LIST);
+		roam_params_dst->num_bssid_avoid_list =
+			roam_params_src->num_bssid_avoid_list;
+		for (i = 0; i < roam_params_dst->num_bssid_avoid_list; i++) {
+			qdf_copy_macaddr(&roam_params_dst->bssid_avoid_list[i],
+					&roam_params_src->bssid_avoid_list[i]);
+		}
+		break;
+	case REASON_ROAM_GOOD_RSSI_CHANGED:
+		roam_params_dst->good_rssi_roam =
+			roam_params_src->good_rssi_roam;
+		break;
+	default:
+		break;
+	}
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		csr_roam_offload_scan(mac_ctx, session_id,
+				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				      update_param);
+		sme_release_global_lock(&mac_ctx->sme);
+	} else {
+		sme_err("Failed to acquire SME lock");
+	}
+
+	sme_update_scan_roam_params(mac_ctx);
+
+	return 0;
+}
+
+/**
+ * sme_process_ready_to_suspend() -
+ * @mac: Global MAC context
+ * @pReadyToSuspend: Parameter received along with ready to suspend
+ *			    indication from WMA.
+ *
+ * On getting ready to suspend indication, this function calls
+ * callback registered (HDD callbacks) with SME to inform ready
+ * to suspend indication.
+ *
+ * Return: None
+ */
+static void sme_process_ready_to_suspend(tpAniSirGlobal mac,
+					 tpSirReadyToSuspendInd pReadyToSuspend)
+{
+	if (NULL == mac) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
+			  "%s: mac is null", __func__);
+		return;
+	}
+
+	if (NULL != mac->readyToSuspendCallback) {
+		mac->readyToSuspendCallback(mac->readyToSuspendContext,
+					    pReadyToSuspend->suspended);
+		mac->readyToSuspendCallback = NULL;
+	}
+}
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+
+/**
+ * sme_process_ready_to_ext_wow() - inform ready to ExtWoW indication.
+ * @mac: Global MAC context
+ * @indication: ready to Ext WoW indication from lower layer
+ *
+ * On getting ready to Ext WoW indication, this function calls callback
+ * registered (HDD callback) with SME to inform ready to ExtWoW indication.
+ *
+ * Return: None
+ */
+static void sme_process_ready_to_ext_wow(tpAniSirGlobal mac,
+					 tpSirReadyToExtWoWInd indication)
+{
+	if (!mac) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
+			  "%s: mac is null", __func__);
+		return;
+	}
+
+	if (NULL != mac->readyToExtWoWCallback) {
+		mac->readyToExtWoWCallback(mac->readyToExtWoWContext,
+					   indication->status);
+		mac->readyToExtWoWCallback = NULL;
+		mac->readyToExtWoWContext = NULL;
+	}
+
+}
+#endif
+
+/*
+ * sme_hdd_ready_ind() - SME sends eWNI_SME_SYS_READY_IND to PE to inform
+ *  that the NIC is ready tio run.
+ * The function is called by HDD at the end of initialization stage so PE/HAL
+ * can enable the NIC to running state.
+ * This is a synchronous call
+ *
+ * @hHal - The handle returned by mac_open.
+ * Return QDF_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE
+ *				successfully.
+ * Other status means SME failed to send the message to PE.
+ */
+QDF_STATUS sme_hdd_ready_ind(tHalHandle hHal)
+{
+	tSirSmeReadyReq *msg;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND, NO_SESSION, 0));
+	do {
+
+		msg = qdf_mem_malloc(sizeof(*msg));
+		if (!msg)
+			return QDF_STATUS_E_NOMEM;
+
+		msg->messageType = eWNI_SME_SYS_READY_IND;
+		msg->length = sizeof(*msg);
+		msg->csr_roam_synch_cb = csr_roam_synch_callback;
+		msg->sme_msg_cb = sme_process_msg_callback;
+		msg->stop_roaming_cb = sme_stop_roaming;
+
+		status = u_mac_post_ctrl_msg(hHal, (tSirMbMsg *)msg);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			sme_err("u_mac_post_ctrl_msg failed to send eWNI_SME_SYS_READY_IND");
+			break;
+		}
+
+		status = csr_ready(pMac);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			sme_err("csr_ready failed with status: %d", status);
+			break;
+		}
+
+		pMac->sme.state = SME_STATE_READY;
+	} while (0);
+
+	return status;
+}
+
+QDF_STATUS sme_get_valid_channels(uint8_t *chan_list, uint32_t *list_len)
+{
+	tpAniSirGlobal mac_ctx = sme_get_mac_context();
+
+	if (NULL == mac_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("Invalid MAC context"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wlan_cfg_get_str(mac_ctx, WNI_CFG_VALID_CHANNEL_LIST,
+				chan_list, list_len);
+}
+
+#ifdef WLAN_CONV_SPECTRAL_ENABLE
+static QDF_STATUS sme_register_spectral_cb(tpAniSirGlobal mac_ctx)
+{
+	struct spectral_legacy_cbacks spectral_cb;
+	QDF_STATUS status;
+
+	spectral_cb.vdev_get_chan_freq = sme_get_oper_chan_freq;
+	spectral_cb.vdev_get_ch_width = sme_get_oper_ch_width;
+	spectral_cb.vdev_get_sec20chan_freq_mhz = sme_get_sec20chan_freq_mhz;
+	status = spectral_register_legacy_cb(mac_ctx->psoc, &spectral_cb);
+
+	return status;
+}
+#else
+static QDF_STATUS sme_register_spectral_cb(tpAniSirGlobal mac_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+/*
+ * sme_start() - Put all SME modules at ready state.
+ *  The function starts each module in SME, PMC, CSR, etc. . Upon
+ *  successfully return, all modules are ready to run.
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return QDF_STATUS_SUCCESS - SME is ready.
+ * Other status means SME is failed to start
+ */
+QDF_STATUS sme_start(tHalHandle hHal)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct policy_mgr_sme_cbacks sme_cbacks;
+
+	do {
+		status = csr_start(pMac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("csr_start failed status: %d", status);
+			break;
+		}
+		sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss;
+		sme_cbacks.sme_get_valid_channels = sme_get_valid_channels;
+		sme_cbacks.sme_nss_update_request = sme_nss_update_request;
+		sme_cbacks.sme_pdev_set_hw_mode = sme_pdev_set_hw_mode;
+		sme_cbacks.sme_pdev_set_pcl = sme_pdev_set_pcl;
+		sme_cbacks.sme_soc_set_dual_mac_config =
+			sme_soc_set_dual_mac_config;
+		sme_cbacks.sme_change_mcc_beacon_interval =
+			sme_change_mcc_beacon_interval;
+		sme_cbacks.sme_get_ap_channel_from_scan =
+			sme_get_ap_channel_from_scan;
+		sme_cbacks.sme_scan_result_purge = sme_scan_result_purge;
+		status = policy_mgr_register_sme_cb(pMac->psoc, &sme_cbacks);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("Failed to register sme cb with Policy Manager: %d",
+				status);
+			break;
+		}
+		sme_register_spectral_cb(pMac);
+		pMac->sme.state = SME_STATE_START;
+
+		/* START RRM */
+		status = rrm_start(pMac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("Failed to start RRM");
+			break;
+		}
+	} while (0);
+	return status;
+}
+
+static QDF_STATUS dfs_msg_processor(tpAniSirGlobal mac,
+		struct scheduler_msg *msg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_info roam_info = { 0 };
+	tSirSmeCSAIeTxCompleteRsp *csa_ie_tx_complete_rsp;
+	uint32_t session_id = 0;
+	eRoamCmdStatus roam_status;
+	eCsrRoamResult roam_result;
+
+	switch (msg->type) {
+	case eWNI_SME_DFS_RADAR_FOUND:
+	{
+		session_id = msg->bodyval;
+		roam_status = eCSR_ROAM_DFS_RADAR_IND;
+		roam_result = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "sapdfs: Radar indication event occurred");
+		break;
+	}
+	case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
+	{
+		csa_ie_tx_complete_rsp =
+			(tSirSmeCSAIeTxCompleteRsp *) msg->bodyptr;
+		if (!csa_ie_tx_complete_rsp) {
+			sme_err("eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND null msg");
+			return QDF_STATUS_E_FAILURE;
+		}
+		session_id = csa_ie_tx_complete_rsp->sessionId;
+		roam_status = eCSR_ROAM_DFS_CHAN_SW_NOTIFY;
+		roam_result = eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND session=%d",
+			  session_id);
+		break;
+	}
+	case eWNI_SME_DFS_CAC_COMPLETE:
+	{
+		session_id = msg->bodyval;
+		roam_status = eCSR_ROAM_CAC_COMPLETE_IND;
+		roam_result = eCSR_ROAM_RESULT_CAC_END_IND;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "sapdfs: Received eWNI_SME_DFS_CAC_COMPLETE vdevid%d",
+			  session_id);
+		break;
+	}
+	case eWNI_SME_CSA_RESTART_RSP:
+	{
+		session_id = msg->bodyval;
+		roam_status = 0;
+		roam_result = eCSR_ROAM_RESULT_CSA_RESTART_RSP;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "sapdfs: Received eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_REQ vdevid%d",
+			  session_id);
+		break;
+	}
+	default:
+	{
+		sme_err("Invalid DFS message: 0x%x", msg->type);
+		status = QDF_STATUS_E_FAILURE;
+		return status;
+	}
+	}
+
+	/* Indicate Radar Event to SAP */
+	csr_roam_call_callback(mac, session_id, &roam_info, 0,
+			       roam_status, roam_result);
+	return status;
+}
+
+
+#ifdef WLAN_FEATURE_11W
+/*
+ * Handle the unprotected management frame indication from LIM and
+ * forward it to HDD.
+ */
+static QDF_STATUS
+sme_unprotected_mgmt_frm_ind(tpAniSirGlobal mac,
+			     tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_info roam_info = { 0 };
+	uint32_t SessionId = pSmeMgmtFrm->sessionId;
+
+	roam_info.nFrameLength = pSmeMgmtFrm->frameLen;
+	roam_info.pbFrames = pSmeMgmtFrm->frameBuf;
+	roam_info.frameType = pSmeMgmtFrm->frameType;
+
+	/* forward the mgmt frame to HDD */
+	csr_roam_call_callback(mac, SessionId, &roam_info, 0,
+			       eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0);
+
+	return status;
+}
+#endif
+
+QDF_STATUS sme_update_new_channel_event(tHalHandle hal, uint8_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct csr_roam_info *roamInfo;
+	eRoamCmdStatus roamStatus;
+	eCsrRoamResult roamResult;
+
+	roamInfo = qdf_mem_malloc(sizeof(*roamInfo));
+	if (!roamInfo)
+		return QDF_STATUS_E_FAILURE;
+
+	roamInfo->dfs_event.sessionId = session_id;
+	roamStatus = eCSR_ROAM_CHANNEL_COMPLETE_IND;
+	roamResult = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "sapdfs: Updated new channel event");
+
+	/* Indicate channel Event to SAP */
+	csr_roam_call_callback(mac, session_id, roamInfo, 0,
+			       roamStatus, roamResult);
+
+	qdf_mem_free(roamInfo);
+	return status;
+}
+
+
+/**
+ * sme_extended_change_channel_ind()- function to indicate ECSA
+ * action frame is received in lim to SAP
+ * @mac_ctx:  pointer to global mac structure
+ * @msg_buf: contain new channel and session id.
+ *
+ * This function is called to post ECSA action frame
+ * receive event to SAP.
+ *
+ * Return: success if msg indicated to SAP else return failure
+ */
+static QDF_STATUS sme_extended_change_channel_ind(tpAniSirGlobal mac_ctx,
+						void *msg_buf)
+{
+	struct sir_sme_ext_cng_chan_ind *ext_chan_ind;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t session_id = 0;
+	struct csr_roam_info roamInfo = {0};
+	eRoamCmdStatus roam_status;
+	eCsrRoamResult roam_result;
+
+	ext_chan_ind = msg_buf;
+	if (NULL == ext_chan_ind) {
+		sme_err("ext_chan_ind is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	session_id = ext_chan_ind->session_id;
+	roamInfo.target_channel = ext_chan_ind->new_channel;
+	roam_status = eCSR_ROAM_EXT_CHG_CHNL_IND;
+	roam_result = eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND;
+	sme_debug("sapdfs: Received eWNI_SME_EXT_CHANGE_CHANNEL_IND for session id [%d]",
+		 session_id);
+
+	/* Indicate Ext Channel Change event to SAP */
+	csr_roam_call_callback(mac_ctx, session_id, &roamInfo, 0,
+					roam_status, roam_result);
+	return status;
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * sme_update_is_ese_feature_enabled() - enable/disable ESE support at runtime
+ * @hHal: HAL handle
+ * @sessionId: session id
+ * @isEseIniFeatureEnabled: ese ini enabled
+ *
+ * It is used at in the REG_DYNAMIC_VARIABLE macro definition of
+ * isEseIniFeatureEnabled. This is a synchronous call
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_update_is_ese_feature_enabled(tHalHandle hHal,
+			uint8_t sessionId, const bool isEseIniFeatureEnabled)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status;
+
+	if (pMac->roam.configParam.isEseIniFeatureEnabled ==
+	    isEseIniFeatureEnabled) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: ESE Mode is already enabled or disabled, nothing to do (returning) old(%d) new(%d)",
+			  __func__,
+			  pMac->roam.configParam.isEseIniFeatureEnabled,
+			  isEseIniFeatureEnabled);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: EseEnabled is changed from %d to %d", __func__,
+		  pMac->roam.configParam.isEseIniFeatureEnabled,
+		  isEseIniFeatureEnabled);
+	pMac->roam.configParam.isEseIniFeatureEnabled = isEseIniFeatureEnabled;
+	csr_neighbor_roam_update_fast_roaming_enabled(
+			pMac, sessionId, isEseIniFeatureEnabled);
+
+	if (true == isEseIniFeatureEnabled)
+		sme_update_fast_transition_enabled(hHal, true);
+
+	if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
+		status = sme_acquire_global_lock(&pMac->sme);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+					      REASON_ESE_INI_CFG_CHANGED);
+			sme_release_global_lock(&pMac->sme);
+		} else {
+			sme_err("Failed to acquire SME lock");
+			return status;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_set_plm_request() - set plm request
+ * @hHal: HAL handle
+ * @pPlmReq: Pointer to input plm request
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_set_plm_request(tHalHandle hHal, tpSirPlmReq pPlmReq)
+{
+	QDF_STATUS status;
+	bool ret = false;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint8_t ch_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
+	uint8_t count, valid_count = 0;
+	struct scheduler_msg msg = {0};
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac,
+					pPlmReq->sessionId);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	if (!pSession) {
+		sme_err("session %d not found",	pPlmReq->sessionId);
+		sme_release_global_lock(&pMac->sme);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!pSession->sessionActive) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid Sessionid"));
+		sme_release_global_lock(&pMac->sme);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!pPlmReq->enable)
+		goto send_plm_start;
+	/* validating channel numbers */
+	for (count = 0; count < pPlmReq->plmNumCh; count++) {
+		ret = csr_is_supported_channel(pMac, pPlmReq->plmChList[count]);
+		if (ret && pPlmReq->plmChList[count] > 14) {
+			if (CHANNEL_STATE_DFS == wlan_reg_get_channel_state(
+						pMac->pdev,
+						pPlmReq->plmChList[count])) {
+				/* DFS channel is provided, no PLM bursts can be
+				 * transmitted. Ignoring these channels.
+				 */
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  FL("DFS channel %d ignored for PLM"),
+					  pPlmReq->plmChList[count]);
+				continue;
+			}
+		} else if (!ret) {
+			/* Not supported, ignore the channel */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  FL("Unsupported channel %d ignored for PLM"),
+				  pPlmReq->plmChList[count]);
+			continue;
+		}
+		ch_list[valid_count] = pPlmReq->plmChList[count];
+		valid_count++;
+	} /* End of for () */
+
+	/* Copying back the valid channel list to plm struct */
+	qdf_mem_set((void *)pPlmReq->plmChList,
+		    pPlmReq->plmNumCh, 0);
+	if (valid_count)
+		qdf_mem_copy(pPlmReq->plmChList, ch_list,
+			     valid_count);
+	/* All are invalid channels, FW need to send the PLM
+	 *  report with "incapable" bit set.
+	 */
+	pPlmReq->plmNumCh = valid_count;
+
+send_plm_start:
+	/* PLM START */
+	msg.type = WMA_SET_PLM_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = pPlmReq;
+
+	if (!QDF_IS_STATUS_SUCCESS(scheduler_post_message(QDF_MODULE_ID_SME,
+							  QDF_MODULE_ID_WMA,
+							  QDF_MODULE_ID_WMA,
+							  &msg))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Not able to post WMA_SET_PLM_REQ to WMA"));
+		sme_release_global_lock(&pMac->sme);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_release_global_lock(&pMac->sme);
+	return status;
+}
+
+/**
+ * sme_tsm_ie_ind() - sme tsm ie indication
+ * @mac: Global mac context
+ * @pSmeTsmIeInd: Pointer to tsm ie indication
+ *
+ * Handle the tsm ie indication from  LIM and forward it to HDD.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static QDF_STATUS sme_tsm_ie_ind(tpAniSirGlobal mac,
+				 tSirSmeTsmIEInd *pSmeTsmIeInd)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_info roam_info = { 0 };
+	uint32_t SessionId = pSmeTsmIeInd->sessionId;
+
+	roam_info.tsmIe.tsid = pSmeTsmIeInd->tsmIe.tsid;
+	roam_info.tsmIe.state = pSmeTsmIeInd->tsmIe.state;
+	roam_info.tsmIe.msmt_interval = pSmeTsmIeInd->tsmIe.msmt_interval;
+	/* forward the tsm ie information to HDD */
+	csr_roam_call_callback(mac, SessionId, &roam_info, 0,
+			       eCSR_ROAM_TSM_IE_IND, 0);
+	return status;
+}
+
+/**
+ * sme_set_cckm_ie() - set cckm ie
+ * @hHal: HAL handle
+ * @sessionId: session id
+ * @pCckmIe: Pointer to CCKM Ie
+ * @cckmIeLen: Length of @pCckmIe
+ *
+ * Function to store the CCKM IE passed from supplicant and use
+ * it while packing reassociation request.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_set_cckm_ie(tHalHandle hHal, uint8_t sessionId,
+			   uint8_t *pCckmIe, uint8_t cckmIeLen)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		csr_set_cckm_ie(pMac, sessionId, pCckmIe, cckmIeLen);
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/**
+ * sme_set_ese_beacon_request() - set ese beacon request
+ * @hHal: HAL handle
+ * @sessionId: session id
+ * @pEseBcnReq: Ese beacon report
+ *
+ * function to set ESE beacon request parameters
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_set_ese_beacon_request(tHalHandle hHal, const uint8_t sessionId,
+				      const tCsrEseBeaconReq *pEseBcnReq)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tpSirBeaconReportReqInd pSmeBcnReportReq = NULL;
+	tCsrEseBeaconReqParams *pBeaconReq = NULL;
+	uint8_t counter = 0;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
+
+	if (pSmeRrmContext->eseBcnReqInProgress == true) {
+		sme_err("A Beacon Report Req is already in progress");
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	/* Store the info in RRM context */
+	qdf_mem_copy(&pSmeRrmContext->eseBcnReqInfo, pEseBcnReq,
+		     sizeof(tCsrEseBeaconReq));
+
+	/* Prepare the request to send to SME. */
+	pSmeBcnReportReq = qdf_mem_malloc(sizeof(tSirBeaconReportReqInd));
+	if (!pSmeBcnReportReq)
+		return QDF_STATUS_E_NOMEM;
+
+	pSmeRrmContext->eseBcnReqInProgress = true;
+
+	sme_debug("Sending Beacon Report Req to SME");
+
+	pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND;
+	pSmeBcnReportReq->length = sizeof(tSirBeaconReportReqInd);
+	qdf_mem_copy(pSmeBcnReportReq->bssId,
+		     pSession->connectedProfile.bssid.bytes,
+		     sizeof(tSirMacAddr));
+	pSmeBcnReportReq->channelInfo.channelNum = 255;
+	pSmeBcnReportReq->channelList.numChannels = pEseBcnReq->numBcnReqIe;
+	pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD;
+
+	for (counter = 0; counter < pEseBcnReq->numBcnReqIe; counter++) {
+		pBeaconReq =
+			(tCsrEseBeaconReqParams *) &pEseBcnReq->bcnReq[counter];
+		pSmeBcnReportReq->fMeasurementtype[counter] =
+			pBeaconReq->scanMode;
+		pSmeBcnReportReq->measurementDuration[counter] =
+			SYS_TU_TO_MS(pBeaconReq->measurementDuration);
+		pSmeBcnReportReq->channelList.channelNumber[counter] =
+			pBeaconReq->channel;
+	}
+
+	status = sme_rrm_process_beacon_report_req_ind(pMac, pSmeBcnReportReq);
+
+	if (status != QDF_STATUS_SUCCESS)
+		pSmeRrmContext->eseBcnReqInProgress = false;
+
+	qdf_mem_free(pSmeBcnReportReq);
+
+	return status;
+}
+
+/**
+ * sme_get_tsm_stats() - SME get tsm stats
+ * @hHal: HAL handle
+ * @callback: SME sends back the requested stats using the callback
+ * @staId: The station ID for which the stats is requested for
+ * @bssId: bssid
+ * @pContext: user context to be passed back along with the callback
+ * @tid: Traffic id
+ *
+ * API register a callback to get TSM Stats.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_get_tsm_stats(tHalHandle hHal,
+			     tCsrTsmStatsCallback callback,
+			     uint8_t staId, struct qdf_mac_addr bssId,
+			     void *pContext, uint8_t tid)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_get_tsm_stats(pMac, callback,
+					   staId, bssId, pContext,
+					   tid);
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/**
+ * sme_set_ese_roam_scan_channel_list() - To set ese roam scan channel list
+ * @hHal: pointer HAL handle returned by mac_open
+ * @sessionId: sme session id
+ * @pChannelList: Output channel list
+ * @numChannels: Output number of channels
+ *
+ * This routine is called to set ese roam scan channel list.
+ * This is a synchronous call
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_ese_roam_scan_channel_list(tHalHandle hHal,
+					      uint8_t sessionId,
+					      uint8_t *pChannelList,
+					      uint8_t numChannels)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+	tpCsrChannelInfo curchnl_list_info = NULL;
+	uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
+	uint8_t newChannelList[128] = { 0 };
+	uint8_t i = 0, j = 0;
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
+	curchnl_list_info =
+		&pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Failed to acquire SME lock");
+		return status;
+	}
+	if (NULL != curchnl_list_info->ChannelList) {
+		for (i = 0; i < curchnl_list_info->numOfChannels; i++) {
+			j += snprintf(oldChannelList + j,
+				sizeof(oldChannelList) - j, "%d",
+				curchnl_list_info->ChannelList[i]);
+		}
+	}
+	status = csr_create_roam_scan_channel_list(pMac, sessionId,
+				pChannelList, numChannels,
+				csr_get_current_band(pMac));
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (NULL != curchnl_list_info->ChannelList) {
+			j = 0;
+			for (i = 0; i < curchnl_list_info->numOfChannels; i++) {
+				j += snprintf(newChannelList + j,
+					sizeof(newChannelList) - j, "%d",
+					curchnl_list_info->ChannelList[i]);
+			}
+		}
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"ESE roam scan chnl list successfully set to %s-old value is %s-roam state is %d",
+			newChannelList, oldChannelList,
+			pNeighborRoamInfo->neighborRoamState);
+	}
+
+	if (pMac->roam.configParam.isRoamOffloadScanEnabled)
+		csr_roam_offload_scan(pMac, sessionId,
+				ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				REASON_CHANNEL_LIST_CHANGED);
+
+	sme_release_global_lock(&pMac->sme);
+	return status;
+}
+
+#endif /* FEATURE_WLAN_ESE */
+
+static
+QDF_STATUS sme_ibss_peer_info_response_handler(tpAniSirGlobal pMac,
+					       tpSirIbssGetPeerInfoRspParams
+					       pIbssPeerInfoParams)
+{
+	if (NULL == pMac) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
+			  "%s: pMac is null", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (pMac->sme.peerInfoParams.peerInfoCbk == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: HDD callback is null", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pMac->sme.peerInfoParams.peerInfoCbk(pMac->sme.peerInfoParams.pUserData,
+					     &pIbssPeerInfoParams->
+					     ibssPeerInfoRspParams);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_process_dual_mac_config_resp() - Process set Dual mac config response
+ * @mac: Global MAC pointer
+ * @msg: Dual mac config response
+ *
+ * Processes the dual mac configuration response and invokes the HDD callback
+ * to process further
+ */
+static QDF_STATUS sme_process_dual_mac_config_resp(tpAniSirGlobal mac,
+		uint8_t *msg)
+{
+	tListElem *entry = NULL;
+	tSmeCmd *command = NULL;
+	bool found;
+	dual_mac_cb callback = NULL;
+	struct sir_dual_mac_config_resp *param;
+
+	param = (struct sir_dual_mac_config_resp *)msg;
+	if (!param) {
+		sme_err("Dual mac config resp param is NULL");
+		/* Not returning. Need to check if active command list
+		 * needs to be freed
+		 */
+	}
+
+	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
+	if (!entry) {
+		sme_err("No cmd found in active list");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+	if (!command) {
+		sme_err("Base address is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (e_sme_command_set_dual_mac_config != command->command) {
+		sme_err("Command mismatch!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	callback = command->u.set_dual_mac_cmd.set_dual_mac_cb;
+	if (callback) {
+		if (!param) {
+			sme_err("Callback failed-Dual mac config is NULL");
+		} else {
+			sme_debug("Calling HDD callback for Dual mac config");
+			callback(param->status,
+				command->u.set_dual_mac_cmd.scan_config,
+				command->u.set_dual_mac_cmd.fw_mode_config);
+		}
+	} else {
+		sme_err("Callback does not exist");
+	}
+
+	found = csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK);
+	if (found)
+		/* Now put this command back on the available command list */
+		csr_release_command(mac, command);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_process_antenna_mode_resp() - Process set antenna mode
+ * response
+ * @mac: Global MAC pointer
+ * @msg: antenna mode response
+ *
+ * Processes the antenna mode response and invokes the HDD
+ * callback to process further
+ */
+static QDF_STATUS sme_process_antenna_mode_resp(tpAniSirGlobal mac,
+		uint8_t *msg)
+{
+	tListElem *entry;
+	tSmeCmd *command;
+	bool found;
+	void *context = NULL;
+	antenna_mode_cb callback;
+	struct sir_antenna_mode_resp *param;
+
+	param = (struct sir_antenna_mode_resp *)msg;
+	if (!param)
+		sme_err("set antenna mode resp is NULL");
+		/* Not returning. Need to check if active command list
+		 * needs to be freed
+		 */
+
+	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
+	if (!entry) {
+		sme_err("No cmd found in active list");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+	if (!command) {
+		sme_err("Base address is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (e_sme_command_set_antenna_mode != command->command) {
+		sme_err("Command mismatch!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	context = command->u.set_antenna_mode_cmd.set_antenna_mode_ctx;
+	callback = command->u.set_antenna_mode_cmd.set_antenna_mode_resp;
+	if (callback) {
+		if (!param)
+			sme_err("Set antenna mode call back is NULL");
+		else
+			callback(param->status, context);
+	} else {
+		sme_err("Callback does not exist");
+	}
+
+	found = csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK);
+	if (found)
+		/* Now put this command back on the available command list */
+		csr_release_command(mac, command);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sme_process_msg(tpAniSirGlobal pMac, struct scheduler_msg *pMsg)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct sir_peer_info *peer_stats;
+	struct sir_peer_info_resp *peer_info_rsp;
+
+	if (pMsg == NULL) {
+		sme_err("Empty message for SME");
+		return status;
+	}
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_warn("Locking failed, bailing out");
+		if (pMsg->bodyptr)
+			qdf_mem_free(pMsg->bodyptr);
+		return status;
+	}
+	if (!SME_IS_START(pMac)) {
+		sme_debug("message type %d in stop state ignored", pMsg->type);
+		if (pMsg->bodyptr)
+			qdf_mem_free(pMsg->bodyptr);
+		goto release_lock;
+	}
+	switch (pMsg->type) {
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	case eWNI_SME_HO_FAIL_IND:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("LFR3: Rcvd eWNI_SME_HO_FAIL_IND"));
+		csr_process_ho_fail_ind(pMac, pMsg->bodyptr);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+#endif
+	case WNI_CFG_SET_CNF:
+	case WNI_CFG_DNLD_CNF:
+	case WNI_CFG_GET_RSP:
+	case WNI_CFG_ADD_GRP_ADDR_CNF:
+	case WNI_CFG_DEL_GRP_ADDR_CNF:
+		break;
+	case eWNI_SME_ADDTS_RSP:
+	case eWNI_SME_DELTS_RSP:
+	case eWNI_SME_DELTS_IND:
+	case eWNI_SME_FT_AGGR_QOS_RSP:
+		/* QoS */
+		if (pMsg->bodyptr) {
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+			status = sme_qos_msg_processor(pMac, pMsg->type,
+						       pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+#endif
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+	case eWNI_SME_NEIGHBOR_REPORT_IND:
+	case eWNI_SME_BEACON_REPORT_REQ_IND:
+		if (pMsg->bodyptr) {
+			status = sme_rrm_msg_processor(pMac, pMsg->type,
+						       pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+	case eWNI_SME_ADD_STA_SELF_RSP:
+		if (pMsg->bodyptr) {
+			status = csr_process_add_sta_session_rsp(pMac,
+								pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+	case eWNI_SME_DEL_STA_SELF_RSP:
+		if (pMsg->bodyptr) {
+			status = csr_process_del_sta_session_rsp(pMac,
+								pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+	case eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE:
+		if (pMsg->bodyptr) {
+			status = sme_handle_generic_change_country_code(
+						(void *)pMac, pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+
+#ifdef WLAN_FEATURE_11W
+	case eWNI_SME_UNPROT_MGMT_FRM_IND:
+		if (pMsg->bodyptr) {
+			sme_unprotected_mgmt_frm_ind(pMac, pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+#endif
+#ifdef FEATURE_WLAN_ESE
+	case eWNI_SME_TSM_IE_IND:
+		if (pMsg->bodyptr) {
+			sme_tsm_ie_ind(pMac, pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+#endif /* FEATURE_WLAN_ESE */
+	case eWNI_SME_ROAM_SCAN_OFFLOAD_RSP:
+		status = csr_roam_offload_scan_rsp_hdlr((void *)pMac,
+							pMsg->bodyptr);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_IBSS_PEER_INFO_RSP:
+		if (pMsg->bodyptr) {
+			sme_ibss_peer_info_response_handler(pMac,
+							    pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+	case eWNI_SME_READY_TO_SUSPEND_IND:
+		if (pMsg->bodyptr) {
+			sme_process_ready_to_suspend(pMac, pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+	case eWNI_SME_READY_TO_EXTWOW_IND:
+		if (pMsg->bodyptr) {
+			sme_process_ready_to_ext_wow(pMac, pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+#endif
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+	case eWNI_SME_AUTO_SHUTDOWN_IND:
+		if (pMac->sme.pAutoShutdownNotificationCb) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  FL("Auto shutdown notification"));
+			pMac->sme.pAutoShutdownNotificationCb();
+		}
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+#endif
+	case eWNI_SME_DFS_RADAR_FOUND:
+	case eWNI_SME_DFS_CAC_COMPLETE:
+	case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
+	case eWNI_SME_CSA_RESTART_RSP:
+		status = dfs_msg_processor(pMac, pMsg);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_CHANNEL_CHANGE_RSP:
+		if (pMsg->bodyptr) {
+			status = sme_process_channel_change_resp(pMac,
+								 pMsg->type,
+								 pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+	case eWNI_SME_STATS_EXT_EVENT:
+		status = sme_stats_ext_event(pMac, pMsg->bodyptr);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	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);
+		if (pMsg->bodyptr) {
+			peer_info_rsp = (struct sir_peer_info_resp *)
+							(pMsg->bodyptr);
+			peer_stats = (struct sir_peer_info *)
+							(peer_info_rsp->info);
+			if (peer_stats) {
+				pMac->peer_rssi = peer_stats[0].rssi;
+				pMac->peer_txrate = peer_stats[0].tx_rate;
+				pMac->peer_rxrate = peer_stats[0].rx_rate;
+			}
+		}
+		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);
+			qdf_mem_free(pMsg->bodyptr);
+		}
+		break;
+	case eWNI_SME_TSF_EVENT:
+		if (pMac->sme.get_tsf_cb) {
+			pMac->sme.get_tsf_cb(pMac->sme.get_tsf_cxt,
+					(struct stsf *)pMsg->bodyptr);
+		}
+		if (pMsg->bodyptr)
+			qdf_mem_free(pMsg->bodyptr);
+		break;
+#ifdef WLAN_FEATURE_NAN
+	case eWNI_SME_NAN_EVENT:
+		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_WMA_MSG,
+				 NO_SESSION, pMsg->type));
+		if (pMsg->bodyptr) {
+			sme_nan_event(MAC_HANDLE(pMac), pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		}
+		break;
+#endif /* WLAN_FEATURE_NAN */
+	case eWNI_SME_LINK_STATUS_IND:
+	{
+		tAniGetLinkStatus *pLinkStatus =
+			(tAniGetLinkStatus *) pMsg->bodyptr;
+		if (pLinkStatus) {
+			if (pMac->sme.link_status_callback)
+				pMac->sme.link_status_callback(
+					pLinkStatus->linkStatus,
+					pMac->sme.link_status_context);
+
+			pMac->sme.link_status_callback = NULL;
+			pMac->sme.link_status_context = NULL;
+			qdf_mem_free(pLinkStatus);
+		}
+		break;
+	}
+	case eWNI_SME_MSG_GET_TEMPERATURE_IND:
+		if (pMac->sme.pGetTemperatureCb)
+			pMac->sme.pGetTemperatureCb(pMsg->bodyval,
+					pMac->sme.pTemperatureCbContext);
+		break;
+	case eWNI_SME_SNR_IND:
+	{
+		tAniGetSnrReq *pSnrReq = (tAniGetSnrReq *) pMsg->bodyptr;
+
+		if (pSnrReq) {
+			if (pSnrReq->snrCallback) {
+				((tCsrSnrCallback)
+				 (pSnrReq->snrCallback))
+					(pSnrReq->snr, pSnrReq->staId,
+					pSnrReq->pDevContext);
+			}
+			qdf_mem_free(pSnrReq);
+		}
+		break;
+	}
+#ifdef FEATURE_WLAN_EXTSCAN
+	case eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND:
+		if (pMac->sme.ext_scan_ind_cb)
+			pMac->sme.ext_scan_ind_cb(pMac->hdd_handle,
+					eSIR_EXTSCAN_FULL_SCAN_RESULT_IND,
+					pMsg->bodyptr);
+		else
+			sme_err("callback not registered to process: %d",
+				pMsg->type);
+
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_EPNO_NETWORK_FOUND_IND:
+		if (pMac->sme.ext_scan_ind_cb)
+			pMac->sme.ext_scan_ind_cb(pMac->hdd_handle,
+					eSIR_EPNO_NETWORK_FOUND_IND,
+					pMsg->bodyptr);
+		else
+			sme_err("callback not registered to process: %d",
+				pMsg->type);
+
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+#endif
+	case eWNI_SME_SET_HW_MODE_RESP:
+		if (pMsg->bodyptr) {
+			status = sme_process_set_hw_mode_resp(pMac,
+								pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+	case eWNI_SME_HW_MODE_TRANS_IND:
+		if (pMsg->bodyptr) {
+			status = sme_process_hw_mode_trans_ind(pMac,
+								pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+	case eWNI_SME_NSS_UPDATE_RSP:
+		if (pMsg->bodyptr) {
+			status = sme_process_nss_update_resp(pMac,
+								pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+#ifdef WLAN_FEATURE_DSRC
+	case eWNI_SME_OCB_SET_CONFIG_RSP:
+		if (pMac->sme.ocb_set_config_callback)
+			pMac->sme.ocb_set_config_callback(
+				pMac->sme.ocb_set_config_context,
+				pMsg->bodyptr);
+		else
+			sme_err("No callback for Msg type: %d", pMsg->type);
+		pMac->sme.ocb_set_config_callback = NULL;
+		pMac->sme.ocb_set_config_context = NULL;
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_OCB_GET_TSF_TIMER_RSP:
+		if (pMac->sme.ocb_get_tsf_timer_callback)
+			pMac->sme.ocb_get_tsf_timer_callback(
+				pMac->sme.ocb_get_tsf_timer_context,
+				pMsg->bodyptr);
+		else
+			sme_err("No callback for Msg type: %d", pMsg->type);
+		pMac->sme.ocb_get_tsf_timer_callback = NULL;
+		pMac->sme.ocb_get_tsf_timer_context = NULL;
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_DCC_GET_STATS_RSP:
+		if (pMac->sme.dcc_get_stats_callback)
+			pMac->sme.dcc_get_stats_callback(
+				pMac->sme.dcc_get_stats_context,
+				pMsg->bodyptr);
+		else
+			sme_err("No callback for Msg type: %d", pMsg->type);
+		pMac->sme.dcc_get_stats_callback = NULL;
+		pMac->sme.dcc_get_stats_context = NULL;
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_DCC_UPDATE_NDL_RSP:
+		if (pMac->sme.dcc_update_ndl_callback)
+			pMac->sme.dcc_update_ndl_callback(
+				pMac->sme.dcc_update_ndl_context,
+				pMsg->bodyptr);
+		else
+			sme_err("No callback for Msg type: %d", pMsg->type);
+		pMac->sme.dcc_update_ndl_callback = NULL;
+		pMac->sme.dcc_update_ndl_context = NULL;
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_DCC_STATS_EVENT:
+		if (pMac->sme.dcc_stats_event_callback)
+			pMac->sme.dcc_stats_event_callback(
+				pMac->sme.dcc_stats_event_context,
+				pMsg->bodyptr);
+		else
+			sme_err("No callback for Msg type: %d", pMsg->type);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+#endif
+	case eWNI_SME_SET_DUAL_MAC_CFG_RESP:
+		if (pMsg->bodyptr) {
+			status = sme_process_dual_mac_config_resp(pMac,
+					pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+	case eWNI_SME_SET_THERMAL_LEVEL_IND:
+		if (pMac->sme.set_thermal_level_cb)
+			pMac->sme.set_thermal_level_cb(pMac->hdd_handle,
+						       pMsg->bodyval);
+		break;
+	case eWNI_SME_EXT_CHANGE_CHANNEL_IND:
+		 status = sme_extended_change_channel_ind(pMac, pMsg->bodyptr);
+		 qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_SET_ANTENNA_MODE_RESP:
+		if (pMsg->bodyptr) {
+			status = sme_process_antenna_mode_resp(pMac,
+					pMsg->bodyptr);
+			qdf_mem_free(pMsg->bodyptr);
+		} else {
+			sme_err("Empty message for: %d", pMsg->type);
+		}
+		break;
+	case eWNI_SME_LOST_LINK_INFO_IND:
+		if (pMac->sme.lost_link_info_cb)
+			pMac->sme.lost_link_info_cb(pMac->hdd_handle,
+				(struct sir_lost_link_info *)pMsg->bodyptr);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_RSO_CMD_STATUS_IND:
+		if (pMac->sme.rso_cmd_status_cb)
+			pMac->sme.rso_cmd_status_cb(pMac->hdd_handle,
+						    pMsg->bodyptr);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWMI_SME_LL_STATS_IND:
+		if (pMac->sme.link_layer_stats_ext_cb)
+			pMac->sme.link_layer_stats_ext_cb(pMac->hdd_handle,
+							  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->hdd_handle,
+						      pMsg->bodyval);
+		break;
+	default:
+
+		if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
+		    && (pMsg->type <= eWNI_SME_MSG_TYPES_END)) {
+			/* CSR */
+			if (pMsg->bodyptr) {
+				status = csr_msg_processor(pMac, pMsg->bodyptr);
+				qdf_mem_free(pMsg->bodyptr);
+			} else
+				sme_err("Empty message for: %d", pMsg->type);
+		} else {
+			sme_warn("Unknown message type: %d", pMsg->type);
+			if (pMsg->bodyptr)
+				qdf_mem_free(pMsg->bodyptr);
+		}
+	} /* switch */
+release_lock:
+	sme_release_global_lock(&pMac->sme);
+	return status;
+}
+
+QDF_STATUS sme_mc_process_handler(struct scheduler_msg *msg)
+{
+	tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
+
+	if (mac_ctx == NULL) {
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return sme_process_msg(mac_ctx, msg);
+}
+
+/**
+ * sme_process_nss_update_resp() - Process nss update response
+ * @mac: Global MAC pointer
+ * @msg: nss update response
+ *
+ * Processes the nss update response and invokes the HDD
+ * callback to process further
+ */
+static QDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg)
+{
+	tListElem *entry = NULL;
+	tSmeCmd *command = NULL;
+	bool found;
+	policy_mgr_nss_update_cback callback = NULL;
+	struct sir_bcn_update_rsp *param;
+
+	param = (struct sir_bcn_update_rsp *)msg;
+	if (!param)
+		sme_err("nss update resp param is NULL");
+		/* Not returning. Need to check if active command list
+		 * needs to be freed
+		 */
+
+	if (param && param->reason != REASON_NSS_UPDATE) {
+		sme_err("reason not NSS update");
+		return QDF_STATUS_E_INVAL;
+	}
+	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
+	if (!entry) {
+		sme_err("No cmd found in active list");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+	if (!command) {
+		sme_err("Base address is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (e_sme_command_nss_update != command->command) {
+		sme_err("Command mismatch!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	callback = command->u.nss_update_cmd.nss_update_cb;
+	if (callback) {
+		if (!param)
+			sme_err("Callback failed since nss update params is NULL");
+		else
+			callback(command->u.nss_update_cmd.context,
+				param->status,
+				param->vdev_id,
+				command->u.nss_update_cmd.next_action,
+				command->u.nss_update_cmd.reason,
+				command->u.nss_update_cmd.original_vdev_id);
+	} else {
+		sme_err("Callback does not exisit");
+	}
+
+	found = csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK);
+	if (found) {
+		/* Now put this command back on the avilable command list */
+		csr_release_command(mac, command);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sme_stop(mac_handle_t mac_handle)
+{
+	QDF_STATUS status;
+	QDF_STATUS ret_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	status = rrm_stop(mac);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ret_status = status;
+		sme_err("rrm_stop failed with status: %d", status);
+	}
+
+	status = csr_stop(mac);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		ret_status = status;
+		sme_err("csr_stop failed with status: %d", status);
+	}
+
+	mac->sme.state = SME_STATE_STOP;
+
+	return ret_status;
+}
+
+/*
+ * sme_close() - Release all SME modules and their resources.
+ * The function release each module in SME, PMC, CSR, etc. . Upon
+ *  return, all modules are at closed state.
+ *
+ *  No SME APIs can be involved after smeClose except smeOpen.
+ *  smeClose must be called before mac_close.
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open
+ * Return QDF_STATUS_SUCCESS - SME is successfully close.
+ *
+ *  Other status means SME is failed to be closed but caller still cannot
+ *  call any other SME functions except smeOpen.
+ */
+QDF_STATUS sme_close(tHalHandle hHal)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	QDF_STATUS fail_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (!pMac)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Note: pSession will be invalid from here on, do not access */
+	status = csr_close(pMac);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("csr_close failed with status: %d", status);
+		fail_status = status;
+	}
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	status = sme_qos_close(pMac);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Qos close failed with status: %d", status);
+		fail_status = status;
+	}
+#endif
+	status = sme_ps_close(hHal);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("sme_ps_close failed status: %d", status);
+		fail_status = status;
+	}
+
+	status = rrm_close(pMac);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("RRM close failed with status: %d", status);
+		fail_status = status;
+	}
+
+	free_sme_cmd_list(pMac);
+
+	if (!QDF_IS_STATUS_SUCCESS
+		    (qdf_mutex_destroy(&pMac->sme.lkSmeGlobalLock)))
+		fail_status = QDF_STATUS_E_FAILURE;
+
+	if (!QDF_IS_STATUS_SUCCESS(fail_status))
+		status = fail_status;
+
+	pMac->sme.state = SME_STATE_STOP;
+
+	return status;
+}
+
+/**
+ * sme_remove_bssid_from_scan_list() - wrapper to remove the bssid from
+ * scan list
+ * @hal: hal context.
+ * @bssid: bssid to be removed
+ *
+ * This function remove the given bssid from scan list.
+ *
+ * Return: QDF status.
+ */
+QDF_STATUS sme_remove_bssid_from_scan_list(tHalHandle hal,
+	tSirMacAddr bssid)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		csr_remove_bssid_from_scan_list(mac_ctx, bssid);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+
+	return status;
+}
+
+
+/*
+ * sme_scan_get_result
+ * A wrapper function to request scan results from CSR.
+ * This is a synchronous call
+ *
+ * pFilter - If pFilter is NULL, all cached results are returned
+ * phResult - an object for the result.
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_scan_get_result(tHalHandle hHal, uint8_t sessionId,
+			       tCsrScanResultFilter *pFilter,
+			       tScanResultHandle *phResult)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS, sessionId,
+			 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_scan_get_result(pMac, pFilter, phResult);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_scan_get_result_for_bssid(tHalHandle hal_handle,
+					 struct qdf_mac_addr *bssid,
+					 tCsrScanResultInfo *res)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
+	QDF_STATUS status;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_scan_get_result_for_bssid(mac_ctx, bssid, res);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+
+	return status;
+}
+
+/**
+ * sme_get_ap_channel_from_scan() - a wrapper function to get
+ *				  AP's channel id from
+ *				  CSR by filtering the
+ *				  result which matches
+ *				  our roam profile.
+ * @profile: SAP profile
+ * @ap_chnl_id: pointer to channel id of SAP. Fill the value after finding the
+ *              best ap from scan cache.
+ *
+ * This function is written to get AP's channel id from CSR by filtering
+ * the result which matches our roam profile. This is a synchronous call.
+ *
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS sme_get_ap_channel_from_scan(void *profile,
+					tScanResultHandle *scan_cache,
+					uint8_t *ap_chnl_id)
+{
+	return sme_get_ap_channel_from_scan_cache((struct csr_roam_profile *)
+						  profile,
+						  scan_cache,
+						  ap_chnl_id);
+}
+
+/**
+ * sme_get_ap_channel_from_scan_cache() - a wrapper function to get AP's
+ *                                        channel id from CSR by filtering the
+ *                                        result which matches our roam profile.
+ * @profile: SAP adapter
+ * @ap_chnl_id: pointer to channel id of SAP. Fill the value after finding the
+ *              best ap from scan cache.
+ *
+ * This function is written to get AP's channel id from CSR by filtering
+ * the result which matches our roam profile. This is a synchronous call.
+ *
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS sme_get_ap_channel_from_scan_cache(
+	struct csr_roam_profile *profile, tScanResultHandle *scan_cache,
+	uint8_t *ap_chnl_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac_ctx = sme_get_mac_context();
+	tCsrScanResultFilter *scan_filter = NULL;
+	tScanResultHandle filtered_scan_result = NULL;
+	tSirBssDescription first_ap_profile;
+
+	if (NULL == mac_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("mac_ctx is NULL"));
+		return QDF_STATUS_E_FAILURE;
+	}
+	scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (!scan_filter)
+		return QDF_STATUS_E_FAILURE;
+
+	qdf_mem_set(&first_ap_profile, sizeof(tSirBssDescription), 0);
+	if (NULL == profile) {
+		scan_filter->EncryptionType.numEntries = 1;
+		scan_filter->EncryptionType.encryptionType[0]
+				= eCSR_ENCRYPT_TYPE_NONE;
+	} else {
+		/* Here is the profile we need to connect to */
+		status = csr_roam_prepare_filter_from_profile(mac_ctx,
+					profile,
+					scan_filter);
+	}
+
+	if (QDF_STATUS_SUCCESS == status) {
+		/* Save the WPS info */
+		if (NULL != profile) {
+			scan_filter->bWPSAssociation =
+						 profile->bWPSAssociation;
+			scan_filter->bOSENAssociation =
+						 profile->bOSENAssociation;
+		} else {
+			scan_filter->bWPSAssociation = 0;
+			scan_filter->bOSENAssociation = 0;
+		}
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("Preparing the profile filter failed"));
+		qdf_mem_free(scan_filter);
+		return QDF_STATUS_E_FAILURE;
+	}
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		status = csr_scan_get_result(mac_ctx, scan_filter,
+					  &filtered_scan_result);
+		if (QDF_STATUS_SUCCESS == status) {
+			csr_get_bssdescr_from_scan_handle(filtered_scan_result,
+					&first_ap_profile);
+			*scan_cache = filtered_scan_result;
+			if (0 != first_ap_profile.channelId) {
+				*ap_chnl_id = first_ap_profile.channelId;
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  FL("Found best AP & its on chnl[%d]"),
+					  first_ap_profile.channelId);
+			} else {
+				/*
+				 * This means scan result is empty
+				 * so set the channel to zero, caller should
+				 * take of zero channel id case.
+				 */
+				*ap_chnl_id = 0;
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					  FL("Scan is empty, set chnl to 0"));
+				status = QDF_STATUS_E_FAILURE;
+			}
+		} else {
+			sme_err("Failed to get scan get result");
+			status = QDF_STATUS_E_FAILURE;
+		}
+		csr_free_scan_filter(mac_ctx, scan_filter);
+		sme_release_global_lock(&mac_ctx->sme);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("Aquiring lock failed"));
+		csr_free_scan_filter(mac_ctx, scan_filter);
+		status = QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_free(scan_filter);
+	return status;
+}
+
+/**
+ * sme_store_joinreq_param() - This function will pass station's join
+ * request to store to csr.
+ * @hal_handle: pointer to hal context.
+ * @profile: pointer to station's roam profile.
+ * @scan_cache: pointer to station's scan cache.
+ * @roam_id: reference to roam_id variable being passed.
+ * @session_id: station's session id.
+ *
+ * This function will pass station's join request further down to csr
+ * to store it. this stored parameter will be used later.
+ *
+ * Return: true or false based on function's overall success.
+ **/
+bool sme_store_joinreq_param(tHalHandle hal_handle,
+		struct csr_roam_profile *profile,
+		tScanResultHandle scan_cache,
+		uint32_t *roam_id,
+		uint32_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	bool ret_status = true;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			TRACE_CODE_SME_RX_HDD_STORE_JOIN_REQ,
+			session_id, 0));
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		if (false == csr_store_joinreq_param(mac_ctx, profile,
+					scan_cache, roam_id, session_id))
+			ret_status = false;
+		sme_release_global_lock(&mac_ctx->sme);
+	} else {
+		ret_status = false;
+	}
+
+	return ret_status;
+}
+
+/**
+ * sme_clear_joinreq_param() - This function will pass station's clear
+ * the join request to csr.
+ * @hal_handle: pointer to hal context.
+ * @session_id: station's session id.
+ *
+ * This function will pass station's clear join request further down to csr
+ * to cleanup.
+ *
+ * Return: true or false based on function's overall success.
+ **/
+bool sme_clear_joinreq_param(tHalHandle hal_handle,
+		uint32_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	bool ret_status = true;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+				TRACE_CODE_SME_RX_HDD_CLEAR_JOIN_REQ,
+				session_id, 0));
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		if (false == csr_clear_joinreq_param(mac_ctx,
+					session_id))
+			ret_status = false;
+		sme_release_global_lock(&mac_ctx->sme);
+	} else {
+		ret_status = false;
+	}
+
+	return ret_status;
+}
+
+/**
+ * sme_issue_stored_joinreq() - This function will issues station's stored
+ * the join request to csr.
+ * @hal_handle: pointer to hal context.
+ * @roam_id: reference to roam_id variable being passed.
+ * @session_id: station's session id.
+ *
+ * This function will issue station's stored join request further down to csr
+ * to proceed forward.
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
+ **/
+QDF_STATUS sme_issue_stored_joinreq(tHalHandle hal_handle,
+		uint32_t *roam_id,
+		uint32_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	QDF_STATUS ret_status = QDF_STATUS_SUCCESS;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+				TRACE_CODE_SME_RX_HDD_ISSUE_JOIN_REQ,
+				session_id, 0));
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		if (QDF_STATUS_SUCCESS != csr_issue_stored_joinreq(mac_ctx,
+					roam_id,
+					session_id)) {
+			ret_status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&mac_ctx->sme);
+	} else {
+		csr_clear_joinreq_param(mac_ctx, session_id);
+		ret_status = QDF_STATUS_E_FAILURE;
+	}
+	return ret_status;
+}
+
+/*
+ * sme_scan_flush_result() -
+ * A wrapper function to request CSR to clear scan results.
+ * This is a synchronous call
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_scan_flush_result(tHalHandle hHal)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS,
+			 0, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_scan_flush_result(pMac);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_filter_scan_results() -
+ * A wrapper function to request CSR to clear scan results.
+ *   This is a synchronous call
+ *
+ * tHalHandle - HAL context handle
+ * sessionId - session id
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_filter_scan_results(tHalHandle hHal, uint8_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS,
+			 sessionId, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		csr_scan_filter_results(pMac);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_scan_flush_p2p_result(tHalHandle hHal, 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_MSG_SCAN_FLUSH_P2PRESULTS,
+			 sessionId, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_scan_flush_selective_result(pMac, true);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_scan_result_get_first() -
+ * A wrapper function to request CSR to returns the first element of
+ * scan result.
+ * This is a synchronous call
+ *
+ * hScanResult - returned from csr_scan_get_result
+ * Return tCsrScanResultInfo * - NULL if no result
+ */
+tCsrScanResultInfo *sme_scan_result_get_first(tHalHandle hHal,
+					      tScanResultHandle hScanResult)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tCsrScanResultInfo *pRet = NULL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST,
+			 NO_SESSION, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pRet = csr_scan_result_get_first(pMac, hScanResult);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return pRet;
+}
+
+/*
+ * sme_scan_result_get_next() -
+ * A wrapper function to request CSR to returns the next element of
+ * scan result. It can be called without calling csr_scan_result_get_first first
+ *   This is a synchronous call
+ *
+ * hScanResult - returned from csr_scan_get_result
+ * Return Null if no result or reach the end
+ */
+tCsrScanResultInfo *sme_scan_result_get_next(tHalHandle hHal,
+					     tScanResultHandle hScanResult)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tCsrScanResultInfo *pRet = NULL;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pRet = csr_scan_result_get_next(pMac, hScanResult);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return pRet;
+}
+
+/*
+ * sme_scan_result_purge() -
+ * A wrapper function to request CSR to remove all items(tCsrScanResult)
+ * in the list and free memory for each item
+ *   This is a synchronous call
+ *
+ * hScanResult - returned from csr_scan_get_result. hScanResult is
+ *	considered gone by
+ *  calling this function and even before this function reutrns.
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_scan_result_purge(tScanResultHandle hScanResult)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac_ctx = sme_get_mac_context();
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE,
+			 NO_SESSION, 0));
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_scan_result_purge(mac_ctx, hScanResult);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+
+	return status;
+}
+
+eCsrPhyMode sme_get_phy_mode(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.phyMode;
+}
+
+/*
+ * sme_get_channel_bonding_mode5_g() - get the channel bonding mode for 5G band
+ *
+ * hHal - HAL handle
+ * mode - channel bonding mode
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_get_channel_bonding_mode5_g(tHalHandle hHal, uint32_t *mode)
+{
+	tSmeConfigParams *smeConfig;
+
+	if (!mode) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: invalid mode", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	smeConfig = qdf_mem_malloc(sizeof(*smeConfig));
+	if (!smeConfig)
+		return QDF_STATUS_E_NOMEM;
+
+	if (sme_get_config_param(hHal, smeConfig) != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: sme_get_config_param failed", __func__);
+		qdf_mem_free(smeConfig);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*mode = smeConfig->csrConfig.channelBondingMode5GHz;
+	qdf_mem_free(smeConfig);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_get_channel_bonding_mode24_g() - get the channel bonding mode for 2.4G
+ * band
+ *
+ * hHal - HAL handle
+ * mode - channel bonding mode
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_get_channel_bonding_mode24_g(tHalHandle hHal, uint32_t *mode)
+{
+	tSmeConfigParams *smeConfig;
+
+	if (!mode) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: invalid mode", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	smeConfig = qdf_mem_malloc(sizeof(*smeConfig));
+	if (!smeConfig)
+		return QDF_STATUS_E_NOMEM;
+
+	if (sme_get_config_param(hHal, smeConfig) != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: sme_get_config_param failed", __func__);
+		qdf_mem_free(smeConfig);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*mode = smeConfig->csrConfig.channelBondingMode24GHz;
+	qdf_mem_free(smeConfig);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_roam_connect() -
+ * A wrapper function to request CSR to inititiate an association
+ *   This is an asynchronous call.
+ *
+ * sessionId - the sessionId returned by sme_open_session.
+ * pProfile - description of the network to which to connect
+ * hBssListIn - a list of BSS descriptor to roam to. It is returned
+ *			from csr_scan_get_result
+ * pRoamId - to get back the request ID
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_roam_connect(tHalHandle hHal, uint8_t sessionId,
+			    struct csr_roam_profile *pProfile,
+			    uint32_t *pRoamId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (!pMac)
+		return QDF_STATUS_E_FAILURE;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_MSG_CONNECT, sessionId, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+			status =
+				csr_roam_connect(pMac, sessionId, pProfile,
+						 pRoamId);
+		} else {
+			sme_err("Invalid sessionID: %d", sessionId);
+			status = QDF_STATUS_E_INVAL;
+		}
+		sme_release_global_lock(&pMac->sme);
+	} else {
+		sme_err("sme_acquire_global_lock failed");
+	}
+
+	return status;
+}
+
+/*
+ * sme_set_phy_mode() -
+ * Changes the PhyMode.
+ *
+ * hHal - The handle returned by mac_open.
+ * phyMode new phyMode which is to set
+ * Return QDF_STATUS  SUCCESS.
+ */
+QDF_STATUS sme_set_phy_mode(tHalHandle hHal, eCsrPhyMode phyMode)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	pMac->roam.configParam.phyMode = phyMode;
+	pMac->roam.configParam.uCfgDot11Mode =
+		csr_get_cfg_dot11_mode_from_csr_phy_mode(NULL,
+						pMac->roam.configParam.phyMode,
+						pMac->roam.configParam.
+						ProprietaryRatesEnabled);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_roam_reassoc() -
+ * A wrapper function to request CSR to inititiate a re-association
+ *
+ * pProfile - can be NULL to join the currently connected AP. In that
+ * case modProfileFields should carry the modified field(s) which could trigger
+ * reassoc
+ * modProfileFields - fields which are part of tCsrRoamConnectedProfile
+ *   that might need modification dynamically once STA is up & running and this
+ *   could trigger a reassoc
+ * pRoamId - to get back the request ID
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_roam_reassoc(tHalHandle hHal, uint8_t sessionId,
+			    struct csr_roam_profile *pProfile,
+			    tCsrRoamModifyProfileFields modProfileFields,
+			    uint32_t *pRoamId, bool fForce)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_ROAM_REASSOC, sessionId, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+			if ((NULL == pProfile) && (fForce == 1))
+				status = csr_reassoc(pMac, sessionId,
+						     &modProfileFields, pRoamId,
+						     fForce);
+			else
+				status = csr_roam_reassoc(pMac, sessionId,
+						pProfile,
+						modProfileFields, pRoamId);
+		} else {
+			status = QDF_STATUS_E_INVAL;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_roam_connect_to_last_profile() -
+ * A wrapper function to request CSR to disconnect and reconnect with
+ *	the same profile
+ *   This is an asynchronous call.
+ *
+ * Return QDF_STATUS. It returns fail if currently connected
+ */
+QDF_STATUS sme_roam_connect_to_last_profile(tHalHandle hHal, 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_ROAM_GET_CONNECTPROFILE,
+			 sessionId, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status = csr_roam_connect_to_last_profile(pMac,
+								sessionId);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_roam_disconnect(tHalHandle hal, uint8_t session_id,
+			       eCsrRoamDisconnectReason reason)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT, session_id,
+			 reason));
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(mac_ctx, session_id))
+			status = csr_roam_disconnect(mac_ctx, session_id,
+						     reason);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+
+	return status;
+}
+
+/* sme_dhcp_done_ind() - send dhcp done ind
+ * @hal: hal context
+ * @session_id: session id
+ *
+ * Return: void.
+ */
+void sme_dhcp_done_ind(tHalHandle hal, uint8_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct csr_roam_session *session;
+
+	if (!mac_ctx)
+		return;
+
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (!session) {
+		sme_err("Session: %d not found", session_id);
+		return;
+	}
+	session->dhcp_done = true;
+}
+
+/*
+ * sme_roam_stop_bss() -
+ * To stop BSS for Soft AP. This is an asynchronous API.
+ *
+ * hHal - Global structure
+ * sessionId - sessionId of SoftAP
+ * Return QDF_STATUS  SUCCESS  Roam callback will be called to indicate
+ * actual results
+ */
+QDF_STATUS sme_roam_stop_bss(tHalHandle hHal, uint8_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status = csr_roam_issue_stop_bss_cmd(pMac, sessionId,
+							false);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/**
+ * sme_roam_disconnect_sta() - disassociate a station
+ * @hHal:          Global structure
+ * @sessionId:     SessionId of SoftAP
+ * @p_del_sta_params: Pointer to parameters of the station to disassoc
+ *
+ * To disassociate a station. This is an asynchronous API.
+ *
+ * Return: QDF_STATUS_SUCCESS on success.Roam callback will
+ *         be called to indicate actual result.
+ */
+QDF_STATUS sme_roam_disconnect_sta(tHalHandle hHal, uint8_t sessionId,
+				   struct csr_del_sta_params *p_del_sta_params)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (NULL == pMac) {
+		QDF_ASSERT(0);
+		return status;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status = csr_roam_issue_disassociate_sta_cmd(pMac,
+					sessionId, p_del_sta_params);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/**
+ * sme_roam_deauth_sta() - deauthenticate a station
+ * @hHal:          Global structure
+ * @sessionId:     SessionId of SoftAP
+ * @pDelStaParams: Pointer to parameters of the station to deauthenticate
+ *
+ * To disassociate a station. This is an asynchronous API.
+ *
+ * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS error
+ *         code on error. Roam callback will be called to indicate actual
+ *         result
+ */
+QDF_STATUS sme_roam_deauth_sta(tHalHandle hHal, uint8_t sessionId,
+			       struct csr_del_sta_params *pDelStaParams)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (NULL == pMac) {
+		QDF_ASSERT(0);
+		return status;
+	}
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA,
+			 sessionId, pDelStaParams->reason_code));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status =
+				csr_roam_issue_deauth_sta_cmd(pMac, sessionId,
+							      pDelStaParams);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_roam_get_associated_stas() -
+ * To probe the list of associated stations from various modules
+ *	 of CORE stack.
+ * This is an asynchronous API.
+ *
+ * sessionId    - sessionId of SoftAP
+ * modId        - Module from whom list of associtated stations is
+ *			  to be probed. If an invalid module is passed then
+ *			  by default QDF_MODULE_ID_PE will be probed.
+ * pUsrContext  - Opaque HDD context
+ * pfnSapEventCallback  - Sap event callback in HDD
+ * pAssocBuf    - Caller allocated memory to be filled with associatd
+ *			  stations info
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_roam_get_associated_stas(tHalHandle hHal, uint8_t sessionId,
+					QDF_MODULE_ID modId, void *pUsrContext,
+					void *pfnSapEventCallback,
+					uint8_t *pAssocStasBuf)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (NULL == pMac) {
+		QDF_ASSERT(0);
+		return status;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status =
+				csr_roam_get_associated_stas(pMac, sessionId,
+							modId,
+							pUsrContext,
+							pfnSapEventCallback,
+							pAssocStasBuf);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_roam_get_connect_state() -
+ * A wrapper function to request CSR to return the current connect state
+ *	of Roaming
+ * This is a synchronous call.
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_roam_get_connect_state(tHalHandle hHal, uint8_t sessionId,
+				      eCsrConnectState *pState)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status = csr_roam_get_connect_state(pMac, sessionId,
+							pState);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_roam_get_connect_profile() -
+ * A wrapper function to request CSR to return the current connect
+ * profile. Caller must call csr_roam_free_connect_profile after it is done
+ * and before reuse for another csr_roam_get_connect_profile call.
+ * This is a synchronous call.
+ *
+ * pProfile - pointer to a caller allocated structure
+ *		      tCsrRoamConnectedProfile
+ * eturn QDF_STATUS. Failure if not connected
+ */
+QDF_STATUS sme_roam_get_connect_profile(tHalHandle hHal, uint8_t sessionId,
+					tCsrRoamConnectedProfile *pProfile)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE,
+			 sessionId, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status = csr_roam_get_connect_profile(pMac, sessionId,
+							pProfile);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/**
+ * sme_roam_free_connect_profile - a wrapper function to request CSR to free and
+ * reinitialize the profile returned previously by csr_roam_get_connect_profile.
+ *
+ * @profile - pointer to a caller allocated structure tCsrRoamConnectedProfile
+ *
+ * Return: none
+ */
+void sme_roam_free_connect_profile(tCsrRoamConnectedProfile *profile)
+{
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE,
+			 NO_SESSION, 0));
+	csr_roam_free_connect_profile(profile);
+}
+
+/*
+ * sme_roam_set_pmkid_cache() -
+ * A wrapper function to request CSR to return the PMKID candidate list
+ * This is a synchronous call.
+
+ * pPMKIDCache - caller allocated buffer point to an array of
+ *			 tPmkidCacheInfo
+ * numItems - a variable that has the number of tPmkidCacheInfo
+ *		      allocated when retruning, this is either the number needed
+ *		      or number of items put into pPMKIDCache
+ * update_entire_cache - this bool value specifies if the entire pmkid
+ *				 cache should be overwritten or should it be
+ *				 updated entry by entry.
+ * Return QDF_STATUS - when fail, it usually means the buffer allocated is not
+ *			 big enough and pNumItems has the number of
+ *			 tPmkidCacheInfo.
+ *   \Note: pNumItems is a number of tPmkidCacheInfo,
+ *	   not sizeof(tPmkidCacheInfo) * something
+ */
+QDF_STATUS sme_roam_set_pmkid_cache(tHalHandle hHal, uint8_t sessionId,
+				    tPmkidCacheInfo *pPMKIDCache,
+				    uint32_t numItems, bool update_entire_cache)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE, sessionId,
+			 numItems));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status = csr_roam_set_pmkid_cache(pMac, sessionId,
+						pPMKIDCache,
+						numItems, update_entire_cache);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_roam_del_pmkid_from_cache(tHalHandle hHal, uint8_t sessionId,
+					 tPmkidCacheInfo *pmksa,
+					 bool flush_cache)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE,
+			 sessionId, flush_cache));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status = csr_roam_del_pmkid_from_cache(pMac, sessionId,
+						       pmksa, flush_cache);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+void sme_get_pmk_info(tHalHandle hal, uint8_t session_id,
+			   tPmkidCacheInfo *pmk_cache)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	QDF_STATUS status = sme_acquire_global_lock(&mac_ctx->sme);
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(mac_ctx, session_id))
+			csr_get_pmk_info(mac_ctx, session_id, pmk_cache);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+}
+#else
+static inline
+void sme_get_pmk_info(tHalHandle hal, uint8_t session_id,
+			tPmkidCacheInfo *pmk_cache)
+{}
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/*
+ * \fn sme_roam_set_psk_pmk
+ * \brief a wrapper function to request CSR to save PSK/PMK
+ *  This is a synchronous call.
+ * \param hHal - Global structure
+ * \param sessionId - SME sessionId
+ * \param pPSK_PMK - pointer to an array of Psk[]/Pmk
+ * \param pmk_len - Length could be only 16 bytes in case if LEAP
+ *                  connections. Need to pass this information to
+ *                  firmware.
+ * \return QDF_STATUS -status whether PSK/PMK is set or not
+ */
+QDF_STATUS sme_roam_set_psk_pmk(tHalHandle hHal, uint8_t sessionId,
+				uint8_t *pPSK_PMK, size_t pmk_len)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status = csr_roam_set_psk_pmk(pMac, sessionId, pPSK_PMK,
+						     pmk_len);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+#endif
+
+QDF_STATUS sme_roam_get_wpa_rsn_req_ie(tHalHandle hal, uint8_t session_id,
+				       uint32_t *len, uint8_t *buf)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(mac, session_id))
+			status = csr_roam_get_wpa_rsn_req_ie(mac, session_id,
+							     len, buf);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&mac->sme);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_roam_get_wpa_rsn_rsp_ie(tHalHandle hal, uint8_t session_id,
+				       uint32_t *len, uint8_t *buf)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(mac, session_id))
+			status = csr_roam_get_wpa_rsn_rsp_ie(mac, session_id,
+							     len, buf);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&mac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_roam_get_num_pmkid_cache() -
+ * A wrapper function to request CSR to return number of PMKID cache
+ *	entries
+ *   This is a synchronous call.
+ *
+ * Return uint32_t - the number of PMKID cache entries
+ */
+uint32_t sme_roam_get_num_pmkid_cache(tHalHandle hHal, uint8_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint32_t numPmkidCache = 0;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+			numPmkidCache =
+				csr_roam_get_num_pmkid_cache(pMac, sessionId);
+			status = QDF_STATUS_SUCCESS;
+		} else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return numPmkidCache;
+}
+
+/*
+ * sme_roam_get_pmkid_cache() -
+ * A wrapper function to request CSR to return PMKID cache from CSR
+ * This is a synchronous call.
+ *
+ * pNum - caller allocated memory that has the space of the number of
+ *		  pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the
+ *		  needed or actually number in tPmkidCacheInfo.
+ * pPmkidCache - Caller allocated memory that contains PMKID cache, if
+ *			 any, upon return
+ * Return QDF_STATUS - when fail, it usually means the buffer allocated is not
+ *			 big enough
+ */
+QDF_STATUS sme_roam_get_pmkid_cache(tHalHandle hHal, uint8_t sessionId,
+				   uint32_t *pNum, tPmkidCacheInfo *pPmkidCache)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_ROAM_GET_PMKIDCACHE, sessionId,
+			 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status = csr_roam_get_pmkid_cache(pMac, sessionId, pNum,
+							 pPmkidCache);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_get_config_param() -
+ * A wrapper function that HDD calls to get the global settings
+ *	currently maintained by CSR.
+ * This is a synchronous call.
+ *
+ * pParam - caller allocated memory
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_get_config_param(tHalHandle hHal, tSmeConfigParams *pParam)
+{
+	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_CONFIGPARAM, NO_SESSION, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_get_config_param(pMac, &pParam->csrConfig);
+		if (status != QDF_STATUS_SUCCESS) {
+			sme_err("csr_get_config_param failed");
+			sme_release_global_lock(&pMac->sme);
+			return status;
+		}
+		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);
+	}
+
+	return status;
+}
+
+/**
+ * sme_cfg_set_int() - Sets the cfg parameter value.
+ * @hal:	Handle to hal.
+ * @cfg_id:	Configuration parameter ID.
+ * @value:	value to be saved in the cfg parameter.
+ *
+ * This function sets the string value in cfg parameter.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_cfg_set_int(tHalHandle hal, uint16_t cfg_id, uint32_t value)
+{
+	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (QDF_STATUS_SUCCESS != cfg_set_int(pmac, cfg_id, value))
+		status = QDF_STATUS_E_FAILURE;
+
+	return status;
+}
+
+/**
+ * sme_cfg_set_str() - Sets the cfg parameter string.
+ * @hal:	Handle to hal.
+ * @cfg_id:	Configuration parameter ID.
+ * @str:	Pointer to the string buffer.
+ * @length:	Length of the string.
+ *
+ * This function sets the string value in cfg parameter.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_cfg_set_str(tHalHandle hal, uint16_t cfg_id, uint8_t *str,
+			   uint32_t length)
+{
+	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (QDF_STATUS_SUCCESS != cfg_set_str(pmac, cfg_id, str, length))
+		status = QDF_STATUS_E_FAILURE;
+
+	return status;
+}
+
+/**
+ * sme_cfg_get_int() -  Gets the cfg parameter value.
+ * @hal:	Handle to hal.
+ * @cfg_id:	Configuration parameter ID.
+ * @cfg_value:	Pointer to variable in which cfg value
+ *		will be saved.
+ *
+ * This function gets the value of the cfg parameter.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_cfg_get_int(tHalHandle hal, uint16_t cfg_id, uint32_t *cfg_value)
+{
+	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (QDF_STATUS_SUCCESS != wlan_cfg_get_int(pmac, cfg_id, cfg_value))
+		status = QDF_STATUS_E_FAILURE;
+
+	return status;
+}
+
+/**
+ * sme_cfg_get_str() - Gets the cfg parameter string.
+ * @hal:	Handle to hal.
+ * @cfg_id:	Configuration parameter ID.
+ * @str:	Pointer to the string buffer.
+ * @length:	Pointer to length of the string.
+ *
+ * This function gets the string value of the cfg parameter.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_cfg_get_str(tHalHandle hal, uint16_t cfg_id, uint8_t *str,
+			   uint32_t *length)
+{
+	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (QDF_STATUS_SUCCESS != wlan_cfg_get_str(pmac, cfg_id, str, length))
+		status = QDF_STATUS_E_INVAL;
+
+	return status;
+}
+
+/*
+ * sme_get_modify_profile_fields() -
+ * HDD or SME - QOS calls this function to get the current values of
+ * connected profile fields, changing which can cause reassoc.
+ * This function must be called after CFG is downloaded and STA is in connected
+ * state. Also, make sure to call this function to get the current profile
+ * fields before calling the reassoc. So that pModifyProfileFields will have
+ * all the latest values plus the one(s) has been updated as part of reassoc
+ * request.
+ *
+ * pModifyProfileFields - pointer to the connected profile fields
+ *   changing which can cause reassoc
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_get_modify_profile_fields(tHalHandle hHal, uint8_t sessionId,
+					 tCsrRoamModifyProfileFields *
+					 pModifyProfileFields)
+{
+	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_MODPROFFIELDS, sessionId,
+			 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			status = csr_get_modify_profile_fields(pMac, sessionId,
+							  pModifyProfileFields);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_set_dhcp_till_power_active_flag() -
+ * Sets/Clears DHCP related flag to disable/enable auto PS
+ *
+ * hal - The handle returned by mac_open.
+ */
+void sme_set_dhcp_till_power_active_flag(tHalHandle hal, uint8_t flag)
+{
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct ps_global_info *ps_global_info = &mac->sme.ps_global_info;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+				TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG, NO_SESSION,
+				flag));
+	/* Set/Clear the DHCP flag which will disable/enable auto PS */
+	ps_global_info->remain_in_power_active_till_dhcp = flag;
+}
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+/**
+ * sme_register_oem_data_rsp_callback() - Register a routine of
+ *                                        type send_oem_data_rsp_msg
+ * @h_hal:                                Handle returned by mac_open.
+ * @callback:                             Callback to send response
+ *                                        to oem application.
+ *
+ * sme_oem_data_rsp_callback is used to register sme_send_oem_data_rsp_msg
+ * callback function.
+ *
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS sme_register_oem_data_rsp_callback(tHalHandle h_hal,
+				sme_send_oem_data_rsp_msg callback)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pmac = PMAC_STRUCT(h_hal);
+
+	pmac->sme.oem_data_rsp_callback = callback;
+
+	return status;
+
+}
+
+/**
+ * sme_deregister_oem_data_rsp_callback() - De-register OEM datarsp callback
+ * @h_hal: Handler return by mac_open
+ * This function De-registers the OEM data response callback  to SME
+ *
+ * Return: None
+ */
+void  sme_deregister_oem_data_rsp_callback(tHalHandle h_hal)
+{
+	tpAniSirGlobal pmac;
+
+	if (!h_hal) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("hHal is not valid"));
+		return;
+	}
+	pmac = PMAC_STRUCT(h_hal);
+
+	pmac->sme.oem_data_rsp_callback = NULL;
+}
+
+/**
+ * sme_oem_update_capability() - update UMAC's oem related capability.
+ * @hal: Handle returned by mac_open
+ * @oem_cap: pointer to oem_capability
+ *
+ * This function updates OEM capability to UMAC. Currently RTT
+ * related capabilities are updated. More capabilities can be
+ * added in future.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_oem_update_capability(tHalHandle hal,
+				     struct sme_oem_capability *cap)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
+	uint8_t *bytes;
+
+	bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability;
+
+	if (cap->ftm_rr)
+		bytes[4] |= RM_CAP_FTM_RANGE_REPORT;
+	if (cap->lci_capability)
+		bytes[4] |= RM_CAP_CIVIC_LOC_MEASUREMENT;
+
+	return status;
+}
+
+/**
+ * sme_oem_get_capability() - get oem capability
+ * @hal: Handle returned by mac_open
+ * @oem_cap: pointer to oem_capability
+ *
+ * This function is used to get the OEM capability from UMAC.
+ * Currently RTT related capabilities are received. More
+ * capabilities can be added in future.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_oem_get_capability(tHalHandle hal,
+				  struct sme_oem_capability *cap)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
+	uint8_t *bytes;
+
+	bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability;
+
+	cap->ftm_rr = bytes[4] & RM_CAP_FTM_RANGE_REPORT;
+	cap->lci_capability = bytes[4] & RM_CAP_CIVIC_LOC_MEASUREMENT;
+
+	return status;
+}
+#endif
+
+/**
+ * sme_roam_set_key() - To set encryption key.
+ * @hal:           hal global context
+ * @session_id:    session id
+ * @set_key:       pointer to a caller allocated object of tCsrSetContextInfo
+ * @ptr_roam_id:       Upon success return, this is the id caller can use to
+ *                 identify the request in roamcallback
+ *
+ * This function should be called only when connected. This is an asynchronous
+ * API.
+ *
+ * Return: Status of operation
+ */
+QDF_STATUS sme_roam_set_key(tHalHandle hal,  uint8_t session_id,
+			    tCsrRoamSetKey *set_key, uint32_t *ptr_roam_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint32_t roam_id;
+	struct csr_roam_session *session = NULL;
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_SET_KEY,
+			 session_id, 0));
+	if (set_key->keyLength > CSR_MAX_KEY_LEN) {
+		sme_err("Invalid key length: %d", set_key->keyLength);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/*Once Setkey is done, we can go in BMPS */
+	if (set_key->keyLength)
+		ps_global_info->remain_in_power_active_till_dhcp = false;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam);
+	if (ptr_roam_id)
+		*ptr_roam_id = roam_id;
+
+	sme_debug("keyLength: %d", set_key->keyLength);
+
+	sme_debug("Session_id: %d roam_id: %d", session_id, roam_id);
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (!session) {
+		sme_err("session %d not found", session_id);
+		sme_release_global_lock(&mac_ctx->sme);
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (CSR_IS_INFRA_AP(&session->connectedProfile)
+	    && set_key->keyDirection == eSIR_TX_DEFAULT) {
+		if ((eCSR_ENCRYPT_TYPE_WEP40 == set_key->encType)
+		    || (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
+			set_key->encType)) {
+			session->pCurRoamProfile->negotiatedUCEncryptionType =
+				eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
+		}
+		if ((eCSR_ENCRYPT_TYPE_WEP104 == set_key->encType)
+		    || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
+			set_key->encType)) {
+			session->pCurRoamProfile->negotiatedUCEncryptionType =
+				eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
+		}
+	}
+	status = csr_roam_set_key(mac_ctx, session_id, set_key, roam_id);
+	sme_release_global_lock(&mac_ctx->sme);
+	return status;
+}
+
+/**
+ * sme_roam_set_default_key_index - To set default wep key idx
+ * @hal: pointer to hal handler
+ * @session_id: session id
+ * @default_idx: default wep key index
+ *
+ * This function prepares a message and post to WMA to set wep default
+ * key index
+ *
+ * Return: Success:QDF_STATUS_SUCCESS Failure: Error value
+ */
+QDF_STATUS sme_roam_set_default_key_index(tHalHandle hal, uint8_t session_id,
+					  uint8_t default_idx)
+{
+	struct scheduler_msg msg = {0};
+	struct wep_update_default_key_idx *update_key;
+
+	update_key = qdf_mem_malloc(sizeof(*update_key));
+	if (!update_key)
+		return QDF_STATUS_E_NOMEM;
+
+	update_key->session_id = session_id;
+	update_key->default_idx = default_idx;
+
+	msg.type = WMA_UPDATE_WEP_DEFAULT_KEY;
+	msg.reserved = 0;
+	msg.bodyptr = (void *)update_key;
+
+	if (QDF_STATUS_SUCCESS !=
+	    scheduler_post_message(QDF_MODULE_ID_SME,
+				   QDF_MODULE_ID_WMA,
+				   QDF_MODULE_ID_WMA, &msg)) {
+		sme_err("Failed to post WMA_UPDATE_WEP_DEFAULT_KEY to WMA");
+		qdf_mem_free(update_key);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
+/**
+ * sme_get_rssi() - API to retrieve current RSSI
+ * @hHal: HAL handle for device
+ * @callback: SME sends back the requested stats using the callback
+ * @staId: The station ID for which the RSSI is requested for
+ * @bssid: The bssid of the connected session
+ * @lastRSSI: RSSI value at time of request. In case fw cannot provide
+ *		      RSSI, do not hold up but return this value.
+ * @pContext: user context to be passed back along with the callback
+ *
+ * A wrapper function that client calls to register a callback to get RSSI
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_get_rssi(tHalHandle hHal,
+			tCsrRssiCallback callback, uint8_t staId,
+			struct qdf_mac_addr bssId, int8_t lastRSSI,
+			void *pContext)
+{
+	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_RSSI, NO_SESSION, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_get_rssi(pMac, callback,
+				      staId, bssId, lastRSSI,
+				      pContext);
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_get_snr() -
+ * A wrapper function that client calls to register a callback to get SNR
+ *
+ * callback - SME sends back the requested stats using the callback
+ * staId - The station ID for which the stats is requested for
+ * pContext - user context to be passed back along with the callback
+ * p_cds_context - cds context
+ *   \return QDF_STATUS
+ */
+QDF_STATUS sme_get_snr(tHalHandle hHal,
+		       tCsrSnrCallback callback,
+		       uint8_t staId, struct qdf_mac_addr bssId, void *pContext)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_get_snr(pMac, callback, staId, bssId, pContext);
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+#ifndef QCA_SUPPORT_CP_STATS
+/*
+ * sme_get_statistics() -
+ * A wrapper function that client calls to register a callback to get
+ *   different PHY level statistics from CSR.
+ *
+ * requesterId - different client requesting for statistics,
+ *	HDD, UMA/GAN etc
+ * statsMask - The different category/categories of stats requester
+ *	is looking for
+ * callback - SME sends back the requested stats using the callback
+ * periodicity - If requester needs periodic update in millisec, 0 means
+ *			 it's an one time request
+ * cache - If requester is happy with cached stats
+ * staId - The station ID for which the stats is requested for
+ * pContext - user context to be passed back along with the callback
+ * sessionId - sme session interface
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_get_statistics(tHalHandle hHal,
+			      eCsrStatsRequesterType requesterId,
+			      uint32_t statsMask, tCsrStatsCallback callback,
+			      uint8_t staId, void *pContext, uint8_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_get_statistics(pMac, requesterId, statsMask,
+					    callback, staId, pContext,
+					    sessionId);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+
+}
+#endif
+
+QDF_STATUS sme_get_link_status(mac_handle_t mac_handle,
+			       csr_link_status_callback callback,
+			       void *context, uint8_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	tAniGetLinkStatus *msg;
+	struct scheduler_msg message = {0};
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		msg = qdf_mem_malloc(sizeof(*msg));
+		if (!msg) {
+			sme_release_global_lock(&mac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		msg->msgType = WMA_LINK_STATUS_GET_REQ;
+		msg->msgLen = sizeof(*msg);
+		msg->sessionId = session_id;
+		mac->sme.link_status_context = context;
+		mac->sme.link_status_callback = callback;
+
+		message.type = WMA_LINK_STATUS_GET_REQ;
+		message.bodyptr = msg;
+		message.reserved = 0;
+
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &message);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			sme_err("post msg failed, %d", status);
+			qdf_mem_free(msg);
+			mac->sme.link_status_context = NULL;
+			mac->sme.link_status_callback = NULL;
+		}
+
+		sme_release_global_lock(&mac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_get_country_code() -
+ * To return the current country code. If no country code is applied,
+ * default country code is used to fill the buffer.
+ * If 11d supported is turned off, an error is return and the last
+ * applied/default country code is used.
+ * This is a synchronous API.
+ *
+ * pBuf - pointer to a caller allocated buffer for returned country code.
+ * pbLen  For input, this parameter indicates how big is the buffer.
+ *		  Upon return, this parameter has the number of bytes for
+ *		  country. If pBuf doesn't have enough space, this function
+ *		  returns fail status and this parameter contains the number
+ *		  that is needed.
+ *
+ * Return QDF_STATUS  SUCCESS.
+ *
+ * FAILURE or RESOURCES  The API finished and failed.
+ */
+QDF_STATUS sme_get_country_code(tHalHandle hHal, uint8_t *pBuf, uint8_t *pbLen)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE, NO_SESSION, 0));
+
+	return csr_get_country_code(pMac, pBuf, pbLen);
+}
+
+/* some support functions */
+bool sme_is11d_supported(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return wlan_reg_11d_enabled_on_host(pMac->psoc);
+}
+
+bool sme_is11h_supported(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return csr_is11h_supported(pMac);
+}
+
+bool sme_is_wmm_supported(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return csr_is_wmm_supported(pMac);
+}
+
+/*
+ * sme_generic_change_country_code() -
+ * Change Country code from upperlayer during WLAN driver operation.
+ * This is a synchronous API.
+ *
+ * hHal - The handle returned by mac_open.
+ * pCountry New Country Code String
+ * reg_domain regulatory domain
+ * Return QDF_STATUS  SUCCESS.
+ * FAILURE or RESOURCES  The API finished and failed.
+ */
+QDF_STATUS sme_generic_change_country_code(tHalHandle hHal,
+					   uint8_t *pCountry)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg msg = {0};
+	tAniGenericChangeCountryCodeReq *pMsg;
+
+	if (NULL == pMac) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
+			  "%s: pMac is null", __func__);
+		return status;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pMsg = qdf_mem_malloc(sizeof(tAniGenericChangeCountryCodeReq));
+		if (!pMsg) {
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		pMsg->msgType = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE;
+		pMsg->msgLen =
+			(uint16_t) sizeof(tAniGenericChangeCountryCodeReq);
+		qdf_mem_copy(pMsg->countryCode, pCountry, 2);
+		pMsg->countryCode[2] = ' ';
+
+		msg.type = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE;
+		msg.bodyptr = pMsg;
+		msg.reserved = 0;
+
+		if (QDF_STATUS_SUCCESS !=
+		    scheduler_post_message(QDF_MODULE_ID_SME,
+					   QDF_MODULE_ID_SME,
+					   QDF_MODULE_ID_SME, &msg)) {
+			sme_err("sme_generic_change_country_code failed to post msg to self");
+			qdf_mem_free(pMsg);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_dhcp_start_ind() -
+ * API to signal the FW about the DHCP Start event.
+ *
+ * hHal - HAL handle for device.
+ * device_mode - mode(AP,SAP etc) of the device.
+ * macAddr - MAC address of the adapter.
+ * sessionId - session ID.
+ * Return QDF_STATUS  SUCCESS.
+ * FAILURE or RESOURCES  The API finished and failed.
+ */
+QDF_STATUS sme_dhcp_start_ind(tHalHandle hHal,
+			      uint8_t device_mode,
+			      uint8_t *macAddr, uint8_t sessionId)
+{
+	QDF_STATUS status;
+	QDF_STATUS qdf_status;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	tAniDHCPInd *pMsg;
+	struct csr_roam_session *pSession;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		pSession = CSR_GET_SESSION(pMac, sessionId);
+
+		if (!pSession) {
+			sme_err("Session: %d not found", sessionId);
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+		pSession->dhcp_done = false;
+
+		pMsg = qdf_mem_malloc(sizeof(tAniDHCPInd));
+		if (!pMsg) {
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+		pMsg->msgType = WMA_DHCP_START_IND;
+		pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd);
+		pMsg->device_mode = device_mode;
+		qdf_mem_copy(pMsg->adapterMacAddr.bytes, macAddr,
+			     QDF_MAC_ADDR_SIZE);
+		qdf_copy_macaddr(&pMsg->peerMacAddr,
+				 &pSession->connectedProfile.bssid);
+
+		message.type = WMA_DHCP_START_IND;
+		message.bodyptr = pMsg;
+		message.reserved = 0;
+		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+				 sessionId, message.type));
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Post DHCP Start MSG fail", __func__);
+			qdf_mem_free(pMsg);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_dhcp_stop_ind() -
+ * API to signal the FW about the DHCP complete event.
+ *
+ * hHal - HAL handle for device.
+ * device_mode - mode(AP, SAP etc) of the device.
+ * macAddr - MAC address of the adapter.
+ * sessionId - session ID.
+ * Return QDF_STATUS  SUCCESS.
+ *			FAILURE or RESOURCES  The API finished and failed.
+ */
+QDF_STATUS sme_dhcp_stop_ind(tHalHandle hHal,
+			     uint8_t device_mode,
+			     uint8_t *macAddr, uint8_t sessionId)
+{
+	QDF_STATUS status;
+	QDF_STATUS qdf_status;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	tAniDHCPInd *pMsg;
+	struct csr_roam_session *pSession;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		pSession = CSR_GET_SESSION(pMac, sessionId);
+
+		if (!pSession) {
+			sme_err("Session: %d not found", sessionId);
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+		pSession->dhcp_done = true;
+
+		pMsg = qdf_mem_malloc(sizeof(tAniDHCPInd));
+		if (!pMsg) {
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		pMsg->msgType = WMA_DHCP_STOP_IND;
+		pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd);
+		pMsg->device_mode = device_mode;
+		qdf_mem_copy(pMsg->adapterMacAddr.bytes, macAddr,
+			     QDF_MAC_ADDR_SIZE);
+		qdf_copy_macaddr(&pMsg->peerMacAddr,
+				 &pSession->connectedProfile.bssid);
+
+		message.type = WMA_DHCP_STOP_IND;
+		message.bodyptr = pMsg;
+		message.reserved = 0;
+		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+				 sessionId, message.type));
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Post DHCP Stop MSG fail", __func__);
+			qdf_mem_free(pMsg);
+			status = QDF_STATUS_E_FAILURE;
+		}
+
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_TXFailMonitorStopInd() -
+ * API to signal the FW to start monitoring TX failures
+ *
+ * Return QDF_STATUS  SUCCESS.
+ * FAILURE or RESOURCES  The API finished and failed.
+ */
+QDF_STATUS sme_tx_fail_monitor_start_stop_ind(tHalHandle hHal, uint8_t
+						tx_fail_count,
+					      void *txFailIndCallback)
+{
+	QDF_STATUS status;
+	QDF_STATUS qdf_status;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	tAniTXFailMonitorInd *pMsg;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		pMsg = qdf_mem_malloc(sizeof(tAniTXFailMonitorInd));
+		if (!pMsg) {
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		pMsg->msgType = WMA_TX_FAIL_MONITOR_IND;
+		pMsg->msgLen = (uint16_t) sizeof(tAniTXFailMonitorInd);
+
+		/* tx_fail_count = 0 should disable the Monitoring in FW */
+		pMsg->tx_fail_count = tx_fail_count;
+		pMsg->txFailIndCallback = txFailIndCallback;
+
+		message.type = WMA_TX_FAIL_MONITOR_IND;
+		message.bodyptr = pMsg;
+		message.reserved = 0;
+
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Post TX Fail monitor Start MSG fail",
+				  __func__);
+			qdf_mem_free(pMsg);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_neighbor_report_request() -
+ * API to request neighbor report.
+ *
+ * hHal - The handle returned by mac_open.
+ * pRrmNeighborReq - Pointer to a caller allocated object of type
+ *			      tRrmNeighborReq. Caller owns the memory and is
+ *			      responsible for freeing it.
+ * Return QDF_STATUS
+ *	    QDF_STATUS_E_FAILURE - failure
+ *	    QDF_STATUS_SUCCESS  success
+ */
+QDF_STATUS sme_neighbor_report_request(tHalHandle hHal, uint8_t sessionId,
+				       tpRrmNeighborReq pRrmNeighborReq,
+				      tpRrmNeighborRspCallbackInfo callbackInfo)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ, NO_SESSION,
+			 0));
+
+	if (pRrmNeighborReq->neighbor_report_offload) {
+		status = csr_invoke_neighbor_report_request(sessionId,
+							    pRrmNeighborReq,
+							    false);
+		return status;
+	}
+
+	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
+		status =
+			sme_rrm_neighbor_report_request(pMac, sessionId,
+						pRrmNeighborReq, callbackInfo);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_get_wcnss_wlan_compiled_version() -
+ * This API returns the version of the WCNSS WLAN API with
+ *	which the HOST driver was built
+ *
+ * hHal - The handle returned by mac_open.
+ * pVersion - Points to the Version structure to be filled
+ * Return QDF_STATUS
+ *	    QDF_STATUS_E_INVAL - failure
+ *	    QDF_STATUS_SUCCESS  success
+ */
+QDF_STATUS sme_get_wcnss_wlan_compiled_version(tHalHandle hHal,
+					       tSirVersionType *pVersion)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
+		if (pVersion != NULL)
+			status = QDF_STATUS_SUCCESS;
+		else
+			status = QDF_STATUS_E_INVAL;
+
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_get_wcnss_wlan_reported_version() -
+ * This API returns the version of the WCNSS WLAN API with
+ *	which the WCNSS driver reports it was built
+ * hHal - The handle returned by mac_open.
+ * pVersion - Points to the Version structure to be filled
+ * Return QDF_STATUS
+ *	    QDF_STATUS_E_INVAL - failure
+ *	    QDF_STATUS_SUCCESS  success
+ */
+QDF_STATUS sme_get_wcnss_wlan_reported_version(tHalHandle hHal,
+					       tSirVersionType *pVersion)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
+		if (pVersion != NULL)
+			status = QDF_STATUS_SUCCESS;
+		else
+			status = QDF_STATUS_E_INVAL;
+
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_get_wcnss_software_version() -
+ * This API returns the version string of the WCNSS driver
+ *
+ * hHal - The handle returned by mac_open.
+ * pVersion - Points to the Version string buffer to be filled
+ * versionBufferSize - THe size of the Version string buffer
+ * Return QDF_STATUS
+ *	    QDF_STATUS_E_INVAL - failure
+ *	    QDF_STATUS_SUCCESS  success
+ */
+QDF_STATUS sme_get_wcnss_software_version(tHalHandle hHal,
+					  uint8_t *pVersion,
+					  uint32_t versionBufferSize)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
+		if (pVersion != NULL)
+			status =
+				wma_get_wcnss_software_version(
+							    pVersion,
+							    versionBufferSize);
+		else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_get_wcnss_hardware_version() -
+ * This API returns the version string of the WCNSS hardware
+ *
+ * hHal - The handle returned by mac_open.
+ * pVersion - Points to the Version string buffer to be filled
+ * versionBufferSize - THe size of the Version string buffer
+ * Return QDF_STATUS
+ *	    QDF_STATUS_E_INVAL - failure
+ *	    QDF_STATUS_SUCCESS  success
+ */
+QDF_STATUS sme_get_wcnss_hardware_version(tHalHandle hHal,
+					  uint8_t *pVersion,
+					  uint32_t versionBufferSize)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
+		if (pVersion != NULL)
+			status = QDF_STATUS_SUCCESS;
+		else
+			status = QDF_STATUS_E_INVAL;
+
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+/**
+ * sme_oem_data_req() - send oem data request to WMA
+ * @hal: HAL handle
+ * @hdd_oem_req: OEM data request from HDD
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_oem_data_req(tHalHandle hal, struct oem_data_req *hdd_oem_req)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct oem_data_req *oem_data_req;
+	void *wma_handle;
+
+	SME_ENTER();
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		sme_err("wma_handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	oem_data_req = qdf_mem_malloc(sizeof(*oem_data_req));
+	if (!oem_data_req)
+		return QDF_STATUS_E_NOMEM;
+
+	oem_data_req->data_len = hdd_oem_req->data_len;
+	oem_data_req->data = qdf_mem_malloc(oem_data_req->data_len);
+	if (!oem_data_req->data)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(oem_data_req->data, hdd_oem_req->data,
+		     oem_data_req->data_len);
+
+	status = wma_start_oem_data_req(wma_handle, oem_data_req);
+
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		sme_err("Post oem data request msg fail");
+	else
+		sme_debug("OEM request(length: %d) sent to WMA",
+			  oem_data_req->data_len);
+
+	if (oem_data_req->data_len)
+		qdf_mem_free(oem_data_req->data);
+	qdf_mem_free(oem_data_req);
+
+	SME_EXIT();
+	return status;
+}
+#endif /*FEATURE_OEM_DATA_SUPPORT */
+
+QDF_STATUS sme_open_session(tHalHandle hal, struct sme_session_params *params)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct cdp_pdev *pdev;
+	ol_txrx_peer_handle peer;
+	uint8_t peer_id;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: type=%d, session_id %d subType=%d addr:%pM",
+		  __func__, params->type_of_persona,
+		  params->sme_session_id, params->subtype_of_persona,
+		  params->self_mac_addr);
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Failed to get pdev handler", __func__);
+		return status;
+	}
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	peer = cdp_peer_find_by_addr(soc, pdev, params->self_mac_addr,
+				     &peer_id);
+	if (peer) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Peer=%d exist with same MAC",
+			  __func__, peer_id);
+		status = QDF_STATUS_E_INVAL;
+	} else {
+		status = csr_roam_open_session(mac_ctx, params);
+	}
+	sme_release_global_lock(&mac_ctx->sme);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_OPEN_SESSION,
+			 params->sme_session_id, 0));
+
+	return status;
+}
+
+QDF_STATUS sme_close_session(tHalHandle hal, uint8_t session_id)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, session_id, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_roam_close_session(pMac, session_id, false);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_change_mcc_beacon_interval() -
+ * To update P2P-GO beaconInterval. This function should be called after
+ *    disassociating all the station is done
+ *   This is an asynchronous API.
+ *
+ * @sessionId: Session Identifier
+ * Return QDF_STATUS  SUCCESS
+ *			FAILURE or RESOURCES
+ *			The API finished and failed.
+ */
+QDF_STATUS sme_change_mcc_beacon_interval(uint8_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac_ctx = sme_get_mac_context();
+
+	if (!mac_ctx) {
+		sme_err("mac_ctx is NULL");
+		return status;
+	}
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_send_chng_mcc_beacon_interval(mac_ctx,
+							   sessionId);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+	return status;
+}
+
+/**
+ * sme_set_host_offload(): API to set the host offload feature.
+ * @hHal: The handle returned by mac_open.
+ * @sessionId: Session Identifier
+ * @request: Pointer to the offload request.
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_host_offload(tHalHandle hHal, uint8_t sessionId,
+				tpSirHostOffloadReq request)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD, sessionId, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+#ifdef WLAN_NS_OFFLOAD
+		if (SIR_IPV6_NS_OFFLOAD == request->offloadType) {
+			status = sme_set_ps_ns_offload(hHal, request,
+					sessionId);
+		} else
+#endif /* WLAN_NS_OFFLOAD */
+		{
+			status = sme_set_ps_host_offload(hHal, request,
+					sessionId);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_set_keep_alive() -
+ * API to set the Keep Alive feature.
+ *
+ * hHal - The handle returned by mac_open.
+ * request -  Pointer to the Keep Alive request.
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_keep_alive(tHalHandle hHal, uint8_t session_id,
+			      tpSirKeepAliveReq request)
+{
+	tpSirKeepAliveReq request_buf;
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, session_id);
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("WMA_SET_KEEP_ALIVE message"));
+
+	if (pSession == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("Session not Found"));
+		return QDF_STATUS_E_FAILURE;
+	}
+	request_buf = qdf_mem_malloc(sizeof(tSirKeepAliveReq));
+	if (!request_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_copy_macaddr(&request->bssid, &pSession->connectedProfile.bssid);
+	qdf_mem_copy(request_buf, request, sizeof(tSirKeepAliveReq));
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"buff TP %d input TP %d ", request_buf->timePeriod,
+		  request->timePeriod);
+	request_buf->sessionId = session_id;
+
+	msg.type = WMA_SET_KEEP_ALIVE;
+	msg.reserved = 0;
+	msg.bodyptr = request_buf;
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			 session_id, msg.type));
+	if (QDF_STATUS_SUCCESS !=
+			scheduler_post_message(QDF_MODULE_ID_SME,
+					       QDF_MODULE_ID_WMA,
+					       QDF_MODULE_ID_WMA, &msg)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"Not able to post WMA_SET_KEEP_ALIVE message to WMA");
+		qdf_mem_free(request_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_get_operation_channel() -
+ * API to get current channel on which STA is parked his function gives
+ * channel information only of infra station or IBSS station
+ *
+ * hHal, pointer to memory location and sessionId
+ * Returns QDF_STATUS_SUCCESS
+ *	     QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS sme_get_operation_channel(tHalHandle hHal, uint32_t *pChannel,
+				     uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession;
+
+	if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		pSession = CSR_GET_SESSION(pMac, sessionId);
+
+		if ((pSession->connectedProfile.BSSType ==
+		     eCSR_BSS_TYPE_INFRASTRUCTURE)
+		    || (pSession->connectedProfile.BSSType ==
+			eCSR_BSS_TYPE_IBSS)
+		    || (pSession->connectedProfile.BSSType ==
+			eCSR_BSS_TYPE_INFRA_AP)
+		    || (pSession->connectedProfile.BSSType ==
+			eCSR_BSS_TYPE_START_IBSS)) {
+			*pChannel = pSession->connectedProfile.operationChannel;
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	return QDF_STATUS_E_FAILURE;
+} /* sme_get_operation_channel ends here */
+
+/**
+ * sme_register_mgmt_frame_ind_callback() - Register a callback for
+ * management frame indication to PE.
+ *
+ * @hal: hal pointer
+ * @callback: callback pointer to be registered
+ *
+ * This function is used to register a callback for management
+ * frame indication to PE.
+ *
+ * Return: Success if msg is posted to PE else Failure.
+ */
+QDF_STATUS sme_register_mgmt_frame_ind_callback(tHalHandle hal,
+				sir_mgmt_frame_ind_callback callback)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct sir_sme_mgmt_frame_cb_req *msg;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (QDF_STATUS_SUCCESS ==
+			sme_acquire_global_lock(&mac_ctx->sme)) {
+		msg = qdf_mem_malloc(sizeof(*msg));
+		if (!msg) {
+			sme_release_global_lock(&mac_ctx->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+		msg->message_type = eWNI_SME_REGISTER_MGMT_FRAME_CB;
+		msg->length          = sizeof(*msg);
+
+		msg->callback = callback;
+		status = umac_send_mb_message_to_mac(msg);
+		sme_release_global_lock(&mac_ctx->sme);
+		return status;
+	}
+	return QDF_STATUS_E_FAILURE;
+}
+
+/*
+ * sme_RegisterMgtFrame() -
+ * To register management frame of specified type and subtype.
+ *
+ * frameType - type of the frame that needs to be passed to HDD.
+ * matchData - data which needs to be matched before passing frame
+ *		       to HDD.
+ * matchDataLen - Length of matched data.
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_register_mgmt_frame(tHalHandle hHal, uint8_t sessionId,
+				   uint16_t frameType, uint8_t *matchData,
+				   uint16_t matchLen)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		tSirRegisterMgmtFrame *pMsg;
+		uint16_t len;
+		struct csr_roam_session *pSession = CSR_GET_SESSION(pMac,
+							sessionId);
+
+		if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) {
+			sme_err("Session %d not found",	sessionId);
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (!CSR_IS_SESSION_ANY(sessionId) &&
+						!pSession->sessionActive) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s Invalid Sessionid", __func__);
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		len = sizeof(tSirRegisterMgmtFrame) + matchLen;
+
+		pMsg = qdf_mem_malloc(len);
+		if (NULL == pMsg)
+			status = QDF_STATUS_E_NOMEM;
+		else {
+			pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ;
+			pMsg->length = len;
+			pMsg->sessionId = sessionId;
+			pMsg->registerFrame = true;
+			pMsg->frameType = frameType;
+			pMsg->matchLen = matchLen;
+			qdf_mem_copy(pMsg->matchData, matchData, matchLen);
+			status = umac_send_mb_message_to_mac(pMsg);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_DeregisterMgtFrame() -
+ * To De-register management frame of specified type and subtype.
+ *
+ * frameType - type of the frame that needs to be passed to HDD.
+ * matchData - data which needs to be matched before passing frame
+ *		       to HDD.
+ * matchDataLen - Length of matched data.
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_deregister_mgmt_frame(tHalHandle hHal, uint8_t sessionId,
+				     uint16_t frameType, uint8_t *matchData,
+				     uint16_t matchLen)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR, sessionId,
+			 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		tSirRegisterMgmtFrame *pMsg;
+		uint16_t len;
+		struct csr_roam_session *pSession = CSR_GET_SESSION(pMac,
+							sessionId);
+
+		if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) {
+			sme_err("Session %d not found",	sessionId);
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (!CSR_IS_SESSION_ANY(sessionId) &&
+						!pSession->sessionActive) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s Invalid Sessionid", __func__);
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		len = sizeof(tSirRegisterMgmtFrame) + matchLen;
+
+		pMsg = qdf_mem_malloc(len);
+		if (NULL == pMsg)
+			status = QDF_STATUS_E_NOMEM;
+		else {
+			pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ;
+			pMsg->length = len;
+			pMsg->registerFrame = false;
+			pMsg->frameType = frameType;
+			pMsg->matchLen = matchLen;
+			qdf_mem_copy(pMsg->matchData, matchData, matchLen);
+			status = umac_send_mb_message_to_mac(pMsg);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/**
+ * sme_prepare_mgmt_tx() - Prepares mgmt frame
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @buf: pointer to frame
+ * @len: frame length
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_prepare_mgmt_tx(tHalHandle hal, uint8_t session_id,
+			   const uint8_t *buf, uint32_t len)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct sir_mgmt_msg *msg;
+	uint16_t msg_len;
+	struct scheduler_msg sch_msg = {0};
+
+	sme_debug("prepares auth frame");
+
+	msg_len = sizeof(*msg) + len;
+	msg = qdf_mem_malloc(msg_len);
+	if (msg == NULL) {
+		status = QDF_STATUS_E_NOMEM;
+	} else {
+		msg->type = eWNI_SME_SEND_MGMT_FRAME_TX;
+		msg->msg_len = msg_len;
+		msg->session_id = session_id;
+		msg->data = (uint8_t *)msg + sizeof(*msg);
+		qdf_mem_copy(msg->data, buf, len);
+
+		sch_msg.type = eWNI_SME_SEND_MGMT_FRAME_TX;
+		sch_msg.bodyptr = msg;
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_PE,
+						QDF_MODULE_ID_PE, &sch_msg);
+	}
+	return status;
+}
+
+QDF_STATUS sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
+			   const uint8_t *buf, uint32_t len)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = sme_prepare_mgmt_tx(hal, session_id, buf, len);
+		sme_release_global_lock(&mac->sme);
+	}
+
+	return status;
+}
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+/**
+ * sme_configure_ext_wow() - configure Extr WoW
+ * @hHal - The handle returned by mac_open.
+ * @wlanExtParams - Depicts the wlan Ext params.
+ * @callback - ext_wow callback to be registered.
+ * @callback_context - ext_wow callback context
+ *
+ * SME will pass this request to lower mac to configure Extr WoW
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_configure_ext_wow(tHalHandle hHal,
+				  tpSirExtWoWParams wlanExtParams,
+				  csr_readyToExtWoWCallback callback,
+				  void *callback_context)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	tpSirExtWoWParams MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr));
+
+	if (!MsgPtr)
+		return QDF_STATUS_E_NOMEM;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW, NO_SESSION, 0));
+
+	pMac->readyToExtWoWCallback = callback;
+	pMac->readyToExtWoWContext = callback_context;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+
+		/* serialize the req through MC thread */
+		qdf_mem_copy(MsgPtr, wlanExtParams, sizeof(*MsgPtr));
+		message.bodyptr = MsgPtr;
+		message.type = WMA_WLAN_EXT_WOW;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			pMac->readyToExtWoWCallback = NULL;
+			pMac->readyToExtWoWContext = NULL;
+			qdf_mem_free(MsgPtr);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	} else {
+		pMac->readyToExtWoWCallback = NULL;
+		pMac->readyToExtWoWContext = NULL;
+		qdf_mem_free(MsgPtr);
+	}
+
+	return status;
+}
+
+/*
+ * sme_configure_app_type1_params() -
+ * SME will pass this request to lower mac to configure Indoor WoW parameters.
+ *
+ * hHal - The handle returned by mac_open.
+ * wlanAppType1Params- Depicts the wlan App Type 1(Indoor) params
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_configure_app_type1_params(tHalHandle hHal,
+					  tpSirAppType1Params wlanAppType1Params)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	tpSirAppType1Params MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr));
+
+	if (!MsgPtr)
+		return QDF_STATUS_E_NOMEM;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1, NO_SESSION,
+			 0));
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* serialize the req through MC thread */
+		qdf_mem_copy(MsgPtr, wlanAppType1Params, sizeof(*MsgPtr));
+		message.bodyptr = MsgPtr;
+		message.type = WMA_WLAN_SET_APP_TYPE1_PARAMS;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			qdf_mem_free(MsgPtr);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	} else {
+		qdf_mem_free(MsgPtr);
+	}
+
+	return status;
+}
+
+/*
+ * sme_configure_app_type2_params() -
+ * SME will pass this request to lower mac to configure Indoor WoW parameters.
+ *
+ * hHal - The handle returned by mac_open.
+ * wlanAppType2Params- Depicts the wlan App Type 2 (Outdoor) params
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_configure_app_type2_params(tHalHandle hHal,
+					 tpSirAppType2Params wlanAppType2Params)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	tpSirAppType2Params MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr));
+
+	if (!MsgPtr)
+		return QDF_STATUS_E_NOMEM;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2, NO_SESSION,
+			 0));
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* serialize the req through MC thread */
+		qdf_mem_copy(MsgPtr, wlanAppType2Params, sizeof(*MsgPtr));
+		message.bodyptr = MsgPtr;
+		message.type = WMA_WLAN_SET_APP_TYPE2_PARAMS;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			qdf_mem_free(MsgPtr);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	} else {
+		qdf_mem_free(MsgPtr);
+	}
+
+	return status;
+}
+#endif
+
+/*
+ * sme_get_infra_session_id
+ * To get the session ID for infra session, if connected
+ *   This is a synchronous API.
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionid, -1 if infra session is not connected
+ */
+int8_t sme_get_infra_session_id(tHalHandle hHal)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	int8_t sessionid = -1;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+
+		sessionid = csr_get_infra_session_id(pMac);
+
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return sessionid;
+}
+
+/*
+ * sme_get_infra_operation_channel() -
+ * To get the operating channel for infra session, if connected
+ *   This is a synchronous API.
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - the sessionId returned by sme_open_session.
+ * Return operating channel, 0 if infra session is not connected
+ */
+uint8_t sme_get_infra_operation_channel(tHalHandle hHal, uint8_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint8_t channel = 0;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+
+		channel = csr_get_infra_operation_channel(pMac, sessionId);
+
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return channel;
+}
+
+/* This routine will return poerating channel on which other BSS is operating
+ * to be used for concurrency mode. If other BSS is not up or not connected it
+ * will return 0
+ */
+uint8_t sme_get_concurrent_operation_channel(tHalHandle hHal)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint8_t channel = 0;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+
+		channel = csr_get_concurrent_operation_channel(pMac);
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
+			"%s: Other Concurrent Channel: %d", __func__, channel);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return channel;
+}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+uint16_t sme_check_concurrent_channel_overlap(tHalHandle hHal, uint16_t sap_ch,
+					      eCsrPhyMode sapPhyMode,
+					      uint8_t cc_switch_mode)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint16_t channel = 0;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		channel =
+			csr_check_concurrent_channel_overlap(pMac, sap_ch,
+								sapPhyMode,
+							     cc_switch_mode);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return channel;
+}
+#endif
+
+/**
+ * sme_set_tsfcb() - Set callback for TSF capture
+ * @h_hal: Handler return by mac_open
+ * @cb_fn: Callback function pointer
+ * @db_ctx: Callback data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_tsfcb(tHalHandle h_hal,
+	int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx)
+{
+	tpAniSirGlobal mac = PMAC_STRUCT(h_hal);
+	QDF_STATUS status;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.get_tsf_cb = cb_fn;
+		mac->sme.get_tsf_cxt = cb_ctx;
+		sme_release_global_lock(&mac->sme);
+	}
+	return status;
+}
+
+/**
+ * sme_reset_tsfcb() - Reset callback for TSF capture
+ * @h_hal: Handler return by mac_open
+ *
+ * This function reset the tsf capture callback to SME
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_reset_tsfcb(tHalHandle h_hal)
+{
+	tpAniSirGlobal mac;
+	QDF_STATUS status;
+
+	if (!h_hal) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("h_hal is not valid"));
+		return QDF_STATUS_E_INVAL;
+	}
+	mac = PMAC_STRUCT(h_hal);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.get_tsf_cb = NULL;
+		mac->sme.get_tsf_cxt = NULL;
+		sme_release_global_lock(&mac->sme);
+	}
+	return status;
+}
+
+#if defined(WLAN_FEATURE_TSF) && !defined(WLAN_FEATURE_TSF_PLUS_NOIRQ)
+/*
+ * sme_set_tsf_gpio() - set gpio pin that be toggled when capture tsf
+ * @h_hal: Handler return by mac_open
+ * @pinvalue: gpio pin id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue)
+{
+	QDF_STATUS status;
+	struct scheduler_msg tsf_msg = {0};
+	tpAniSirGlobal mac = PMAC_STRUCT(h_hal);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		tsf_msg.type = WMA_TSF_GPIO_PIN;
+		tsf_msg.reserved = 0;
+		tsf_msg.bodyval = pinvalue;
+
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &tsf_msg);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("Unable to post WMA_TSF_GPIO_PIN");
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&mac->sme);
+	}
+	return status;
+}
+#endif
+
+QDF_STATUS sme_get_cfg_valid_channels(uint8_t *aValidChannels,
+				      uint32_t *len)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac_ctx = sme_get_mac_context();
+
+	if (NULL == mac_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+		FL("Invalid MAC context"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_get_cfg_valid_channels(mac_ctx,
+			aValidChannels, len);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+
+	return status;
+}
+
+static uint8_t *sme_reg_hint_to_str(const enum country_src src)
+{
+	switch (src) {
+	case SOURCE_CORE:
+		return "WORLD MODE";
+
+	case SOURCE_DRIVER:
+		return "BDF file";
+
+	case SOURCE_USERSPACE:
+		return "user-space";
+
+	case SOURCE_11D:
+		return "802.11D IEs in beacons";
+
+	default:
+		return "unknown";
+	}
+}
+
+void sme_set_cc_src(tHalHandle hHal, enum country_src cc_src)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hHal);
+
+	mac_ctx->reg_hint_src = cc_src;
+
+	sme_debug("Country source is %s",
+		  sme_reg_hint_to_str(cc_src));
+}
+
+/**
+ * sme_handle_generic_change_country_code() - handles country ch req
+ * @mac_ctx:    mac global context
+ * @msg:        request msg packet
+ *
+ * If Supplicant country code is priority than 11d is disabled.
+ * If 11D is enabled, we update the country code after every scan.
+ * Hence when Supplicant country code is priority, we don't need 11D info.
+ * Country code from Supplicant is set as current country code.
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS
+sme_handle_generic_change_country_code(tpAniSirGlobal mac_ctx,
+				       void *pMsgBuf)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	v_REGDOMAIN_t reg_domain_id = 0;
+	bool user_ctry_priority =
+		mac_ctx->roam.configParam.fSupplicantCountryCodeHasPriority;
+	tAniGenericChangeCountryCodeReq *msg = pMsgBuf;
+
+	if (SOURCE_11D != mac_ctx->reg_hint_src) {
+		if (SOURCE_DRIVER != mac_ctx->reg_hint_src) {
+			if (user_ctry_priority)
+				mac_ctx->roam.configParam.Is11dSupportEnabled =
+					false;
+			else {
+				if (mac_ctx->roam.configParam.
+					Is11dSupportEnabled &&
+					mac_ctx->scan.countryCode11d[0] != 0) {
+
+					sme_debug("restore 11d");
+
+					status =
+					csr_get_regulatory_domain_for_country(
+						mac_ctx,
+						mac_ctx->scan.countryCode11d,
+						&reg_domain_id,
+						SOURCE_11D);
+					return QDF_STATUS_E_FAILURE;
+				}
+			}
+		}
+	} else {
+		/* if kernel gets invalid country code; it
+		 *  resets the country code to world
+		 */
+		if (('0' != msg->countryCode[0]) ||
+		    ('0' != msg->countryCode[1]))
+			qdf_mem_copy(mac_ctx->scan.countryCode11d,
+				     msg->countryCode,
+				     WNI_CFG_COUNTRY_CODE_LEN);
+	}
+
+	qdf_mem_copy(mac_ctx->scan.countryCodeCurrent,
+		     msg->countryCode,
+		     WNI_CFG_COUNTRY_CODE_LEN);
+
+	/* get the channels based on new cc */
+	status = csr_get_channel_and_power_list(mac_ctx);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("fail to get Channels");
+		return status;
+	}
+
+	/* reset info based on new cc, and we are done */
+	csr_apply_channel_power_info_wrapper(mac_ctx);
+
+	csr_scan_filter_results(mac_ctx);
+
+	/* scans after the country is set by User hints or
+	 * Country IE
+	 */
+	mac_ctx->scan.curScanType = eSIR_ACTIVE_SCAN;
+
+	mac_ctx->reg_hint_src = SOURCE_UNKNOWN;
+
+	sme_disconnect_connected_sessions(mac_ctx);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sme_update_channel_list(tHalHandle hal)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	QDF_STATUS status;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Update umac channel (enable/disable) from cds channels */
+		status = csr_get_channel_and_power_list(mac_ctx);
+		if (status != QDF_STATUS_SUCCESS) {
+			sme_err("fail to get Channels");
+			sme_release_global_lock(&mac_ctx->sme);
+			return status;
+		}
+
+		csr_apply_channel_power_info_wrapper(mac_ctx);
+		csr_scan_filter_results(mac_ctx);
+		sme_disconnect_connected_sessions(mac_ctx);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+
+	return status;
+}
+
+static bool
+sme_search_in_base_ch_lst(tpAniSirGlobal mac_ctx, uint8_t curr_ch)
+{
+	uint8_t i;
+	struct csr_channel *ch_lst_info;
+
+	ch_lst_info = &mac_ctx->scan.base_channels;
+	for (i = 0; i < ch_lst_info->numChannels; i++) {
+		if (ch_lst_info->channelList[i] == curr_ch)
+			return true;
+	}
+
+	return false;
+}
+/**
+ * sme_disconnect_connected_sessions() - Disconnect STA and P2P client session
+ * if channel is not supported
+ * @mac_ctx:          mac global context
+ *
+ * If new country code does not support the channel on which STA/P2P client
+ * is connetced, it sends the disconnect to the AP/P2P GO
+ *
+ * Return: void
+ */
+static void sme_disconnect_connected_sessions(tpAniSirGlobal mac_ctx)
+{
+	uint8_t session_id, found = false;
+	uint8_t curr_ch;
+
+	for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
+		if (!csr_is_session_client_and_connected(mac_ctx, session_id))
+			continue;
+		found = false;
+		/* Session is connected.Check the channel */
+		curr_ch = csr_get_infra_operation_channel(mac_ctx,
+							  session_id);
+		sme_debug("Current Operating channel : %d, session :%d",
+			  curr_ch, session_id);
+		found = sme_search_in_base_ch_lst(mac_ctx, curr_ch);
+		if (!found) {
+			sme_debug("Disconnect Session: %d", session_id);
+			csr_roam_disconnect(mac_ctx, session_id,
+					    eCSR_DISCONNECT_REASON_UNSPECIFIED);
+		}
+	}
+}
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+QDF_STATUS sme_8023_multicast_list(tHalHandle hHal, uint8_t sessionId,
+				   tpSirRcvFltMcAddrList pMulticastAddrs)
+{
+	tpSirRcvFltMcAddrList request_buf;
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = NULL;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		"%s: ulMulticastAddrCnt: %d, multicastAddr[0]: %pK", __func__,
+		  pMulticastAddrs->ulMulticastAddrCnt,
+		  pMulticastAddrs->multicastAddr[0].bytes);
+
+	/* Find the connected Infra / P2P_client connected session */
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId) ||
+			(!csr_is_conn_state_infra(pMac, sessionId) &&
+			 !csr_is_ndi_started(pMac, sessionId))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Unable to find the session Id: %d", __func__,
+			  sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	request_buf = qdf_mem_malloc(sizeof(tSirRcvFltMcAddrList));
+	if (!request_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	if (!csr_is_conn_state_connected_infra(pMac, sessionId) &&
+			!csr_is_ndi_started(pMac, sessionId)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: Request ignored, session %d is not connected or started",
+			__func__, sessionId);
+		qdf_mem_free(request_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_copy(request_buf, pMulticastAddrs,
+		     sizeof(tSirRcvFltMcAddrList));
+
+	qdf_copy_macaddr(&request_buf->self_macaddr, &pSession->selfMacAddr);
+	qdf_copy_macaddr(&request_buf->bssid,
+			 &pSession->connectedProfile.bssid);
+
+	msg.type = WMA_8023_MULTICAST_LIST_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = request_buf;
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			 sessionId, msg.type));
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_WMA,
+							 QDF_MODULE_ID_WMA,
+							 &msg)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Not able to post WMA_8023_MULTICAST_LIST message to WMA",
+			  __func__);
+		qdf_mem_free(request_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+
+/*
+ * sme_is_channel_valid() -
+ * To check if the channel is valid for currently established domain
+ *   This is a synchronous API.
+ *
+ * hHal - The handle returned by mac_open.
+ * channel - channel to verify
+ * Return true/false, true if channel is valid
+ */
+bool sme_is_channel_valid(tHalHandle hHal, uint8_t channel)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	bool valid = false;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+
+		valid = csr_roam_is_channel_valid(pMac, channel);
+
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return valid;
+}
+
+/*
+ * sme_get_freq_band() -
+ * Used to get the current band settings.
+ *
+ * hHal
+ * pBand  pointer to hold band value
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_get_freq_band(tHalHandle hHal, enum band_info *pBand)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		*pBand = csr_get_current_band(pMac);
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_set_max_tx_power_per_band() -
+ * Set the Maximum Transmit Power specific to band dynamically.
+ *   Note: this setting will not persist over reboots.
+ *
+ * band
+ * power to set in dB
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_max_tx_power_per_band(enum band_info band, int8_t dB)
+{
+	struct scheduler_msg msg = {0};
+	tpMaxTxPowerPerBandParams pMaxTxPowerPerBandParams = NULL;
+
+	pMaxTxPowerPerBandParams =
+		qdf_mem_malloc(sizeof(tMaxTxPowerPerBandParams));
+	if (!pMaxTxPowerPerBandParams)
+		return QDF_STATUS_E_NOMEM;
+
+	pMaxTxPowerPerBandParams->power = dB;
+	pMaxTxPowerPerBandParams->bandInfo = band;
+
+	msg.type = WMA_SET_MAX_TX_POWER_PER_BAND_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = pMaxTxPowerPerBandParams;
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			 NO_SESSION, msg.type));
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_WMA,
+							 QDF_MODULE_ID_WMA,
+							 &msg)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s:Not able to post WMA_SET_MAX_TX_POWER_PER_BAND_REQ",
+			  __func__);
+		qdf_mem_free(pMaxTxPowerPerBandParams);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_set_max_tx_power() -
+ * Set the Maximum Transmit Power dynamically. Note: this setting will
+ *   not persist over reboots.
+ *
+ * hHal
+ * pBssid  BSSID to set the power cap for
+ * pBssid  pSelfMacAddress self MAC Address
+ * pBssid  power to set in dB
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_max_tx_power(tHalHandle hHal, struct qdf_mac_addr pBssid,
+				struct qdf_mac_addr pSelfMacAddress, int8_t dB)
+{
+	struct scheduler_msg msg = {0};
+	tpMaxTxPowerParams pMaxTxParams = NULL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW, NO_SESSION, 0));
+	pMaxTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams));
+	if (!pMaxTxParams)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_copy_macaddr(&pMaxTxParams->bssId, &pBssid);
+	qdf_copy_macaddr(&pMaxTxParams->selfStaMacAddr, &pSelfMacAddress);
+	pMaxTxParams->power = dB;
+
+	msg.type = WMA_SET_MAX_TX_POWER_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = pMaxTxParams;
+
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_WMA,
+							 QDF_MODULE_ID_WMA,
+							 &msg)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Not able to post WMA_SET_MAX_TX_POWER_REQ message to WMA",
+			  __func__);
+		qdf_mem_free(pMaxTxParams);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_set_custom_mac_addr() -
+ * Set the customer Mac Address.
+ *
+ * customMacAddr  customer MAC Address
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_custom_mac_addr(tSirMacAddr customMacAddr)
+{
+	struct scheduler_msg msg = {0};
+	tSirMacAddr *pBaseMacAddr;
+
+	pBaseMacAddr = qdf_mem_malloc(sizeof(tSirMacAddr));
+	if (!pBaseMacAddr)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(*pBaseMacAddr, customMacAddr, sizeof(tSirMacAddr));
+
+	msg.type = SIR_HAL_SET_BASE_MACADDR_IND;
+	msg.reserved = 0;
+	msg.bodyptr = pBaseMacAddr;
+
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_WMA,
+							 QDF_MODULE_ID_WMA,
+							 &msg)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"Not able to post SIR_HAL_SET_BASE_MACADDR_IND message to WMA");
+		qdf_mem_free(pBaseMacAddr);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_set_tx_power() -
+ * Set Transmit Power dynamically.
+ *
+ * hHal
+ * sessionId  Target Session ID
+ * BSSID
+ * dev_mode dev_mode such as station, P2PGO, SAP
+ * dBm  power to set
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_tx_power(tHalHandle hHal, uint8_t sessionId,
+			   struct qdf_mac_addr pBSSId,
+			   enum QDF_OPMODE dev_mode, int dBm)
+{
+	struct scheduler_msg msg = {0};
+	tpMaxTxPowerParams pTxParams = NULL;
+	int8_t power = (int8_t) dBm;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_SET_TXPOW, sessionId, 0));
+
+	/* make sure there is no overflow */
+	if ((int)power != dBm) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: error, invalid power = %d", __func__, dBm);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams));
+	if (!pTxParams)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_copy_macaddr(&pTxParams->bssId, &pBSSId);
+	pTxParams->power = power;       /* unit is dBm */
+	pTxParams->dev_mode = dev_mode;
+	msg.type = WMA_SET_TX_POWER_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = pTxParams;
+
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_WMA,
+							 QDF_MODULE_ID_WMA,
+							 &msg)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: failed to post WMA_SET_TX_POWER_REQ to WMA",
+			  __func__);
+		qdf_mem_free(pTxParams);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sme_update_session_param(tHalHandle hal, uint8_t session_id,
+			uint32_t param_type, uint32_t param_val)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint16_t len;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		struct sir_update_session_param *msg;
+		struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx,
+							session_id);
+
+		if (!session) {
+			sme_err("Session: %d not found", session_id);
+			sme_release_global_lock(&mac_ctx->sme);
+			return status;
+		}
+
+		if (param_type == SIR_PARAM_IGNORE_ASSOC_DISALLOWED)
+			mac_ctx->ignore_assoc_disallowed = param_val;
+
+		if (!session->sessionActive)
+			QDF_ASSERT(0);
+
+		len = sizeof(*msg);
+		msg = qdf_mem_malloc(len);
+		if (!msg)
+			status = QDF_STATUS_E_NOMEM;
+		else {
+			msg->message_type = eWNI_SME_SESSION_UPDATE_PARAM;
+			msg->length = len;
+			msg->session_id = session_id;
+			msg->param_type = param_type;
+			msg->param_val = param_val;
+			status = umac_send_mb_message_to_mac(msg);
+		}
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_set_tm_level() -
+ * Set Thermal Mitigation Level to RIVA
+ *
+ * hHal - The handle returned by mac_open.
+ * newTMLevel - new Thermal Mitigation Level
+ * tmMode - Thermal Mitigation handle mode, default 0
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_tm_level(tHalHandle hHal, uint16_t newTMLevel, uint16_t
+			tmMode)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	tAniSetTmLevelReq *setTmLevelReq = NULL;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_SET_TMLEVEL, NO_SESSION, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		setTmLevelReq =
+			(tAniSetTmLevelReq *)
+			qdf_mem_malloc(sizeof(tAniSetTmLevelReq));
+		if (NULL == setTmLevelReq) {
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		setTmLevelReq->tmMode = tmMode;
+		setTmLevelReq->newTmLevel = newTMLevel;
+
+		/* serialize the req through MC thread */
+		message.bodyptr = setTmLevelReq;
+		message.type = WMA_SET_TM_LEVEL_REQ;
+		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+				 NO_SESSION, message.type));
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Post Set TM Level MSG fail", __func__);
+			qdf_mem_free(setTmLevelReq);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_feature_caps_exchange() - SME interface to exchange capabilities between
+ *  Host and FW.
+ *
+ * hHal - HAL handle for device
+ * Return NONE
+ */
+void sme_feature_caps_exchange(tHalHandle hHal)
+{
+	MTRACE(qdf_trace
+		       (QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_CAPS_EXCH,
+			NO_SESSION, 0));
+}
+
+/*
+ * sme_disable_feature_capablity() - SME interface to disable Active mode
+ * offload capablity in Host.
+ *
+ * hHal - HAL handle for device
+ * Return NONE
+ */
+void sme_disable_feature_capablity(uint8_t feature_index)
+{
+}
+
+/*
+ * sme_reset_power_values_for5_g
+ * Reset the power values for 5G band with default power values.
+ *
+ * hHal - HAL handle for device
+ * Return NONE
+ */
+void sme_reset_power_values_for5_g(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_RESET_PW5G, NO_SESSION, 0));
+	csr_save_channel_power_for_band(pMac, true);
+	/* Store the channel+power info in the global place: Cfg */
+	csr_apply_power2_current(pMac);
+}
+
+/*
+ * sme_update_roam_prefer5_g_hz() -
+ *  Enable/disable Roam prefer 5G runtime option
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure the Roam prefer 5G runtime option
+ *
+ * hHal - HAL handle for device
+ * nRoamPrefer5GHz Enable/Disable Roam prefer 5G runtime option
+ * Return Success or failure
+ */
+
+QDF_STATUS sme_update_roam_prefer5_g_hz(tHalHandle hHal,
+					bool nRoamPrefer5GHz)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_UPDATE_RP5G, NO_SESSION, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: gRoamPrefer5GHz is changed from %d to %d",
+			  __func__, pMac->roam.configParam.nRoamPrefer5GHz,
+			  nRoamPrefer5GHz);
+		pMac->roam.configParam.nRoamPrefer5GHz = nRoamPrefer5GHz;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_set_roam_intra_band() -
+ * enable/disable Intra band roaming
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure the intra band roaming
+ * hHal - HAL handle for device
+ * nRoamIntraBand Enable/Disable Intra band roaming
+ * Return Success or failure
+ */
+QDF_STATUS sme_set_roam_intra_band(tHalHandle hHal, const bool nRoamIntraBand)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND, NO_SESSION, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: gRoamIntraBand is changed from %d to %d",
+			  __func__, pMac->roam.configParam.nRoamIntraBand,
+			  nRoamIntraBand);
+		pMac->roam.configParam.nRoamIntraBand = nRoamIntraBand;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_update_roam_scan_n_probes() -
+ * Function to update roam scan N probes
+ *	    This function is called through dynamic setConfig callback function
+ *	    to update roam scan N probes
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * nProbes number of probe requests to be sent out
+ * Return Success or failure
+ */
+QDF_STATUS sme_update_roam_scan_n_probes(tHalHandle hHal, uint8_t sessionId,
+					 const uint8_t nProbes)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES,
+			 NO_SESSION, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: gRoamScanNProbes is changed from %d to %d",
+			  __func__, pMac->roam.configParam.nProbes, nProbes);
+		pMac->roam.configParam.nProbes = nProbes;
+
+		if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+					      REASON_NPROBES_CHANGED);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_update_roam_scan_home_away_time() -
+ *  Function to update roam scan Home away time
+ *	    This function is called through dynamic setConfig callback function
+ *	    to update roam scan home away time
+ *
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * nRoamScanAwayTime Scan home away time
+ * bSendOffloadCmd If true then send offload command to firmware
+ *			    If false then command is not sent to firmware
+ * Return Success or failure
+ */
+QDF_STATUS sme_update_roam_scan_home_away_time(tHalHandle hHal,
+					       uint8_t sessionId,
+					   const uint16_t nRoamScanHomeAwayTime,
+					       const bool bSendOffloadCmd)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME,
+			 NO_SESSION, 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: gRoamScanHomeAwayTime is changed from %d to %d",
+			  __func__,
+			  pMac->roam.configParam.nRoamScanHomeAwayTime,
+			  nRoamScanHomeAwayTime);
+		pMac->roam.configParam.nRoamScanHomeAwayTime =
+			nRoamScanHomeAwayTime;
+
+		if (pMac->roam.configParam.isRoamOffloadScanEnabled &&
+						bSendOffloadCmd) {
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+					      REASON_HOME_AWAY_TIME_CHANGED);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/**
+ * sme_ext_change_channel()- function to post send ECSA
+ * action frame to csr.
+ * @hHal: Hal context
+ * @channel: new channel to switch
+ * @session_id: senssion it should be sent on.
+ *
+ * This function is called to post ECSA frame to csr.
+ *
+ * Return: success if msg is sent else return failure
+ */
+QDF_STATUS sme_ext_change_channel(tHalHandle h_hal, uint32_t channel,
+						uint8_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac_ctx  = PMAC_STRUCT(h_hal);
+	uint8_t channel_state;
+
+	sme_err("Set Channel: %d", channel);
+	channel_state =
+		wlan_reg_get_channel_state(mac_ctx->pdev, channel);
+
+	if (CHANNEL_STATE_DISABLE == channel_state) {
+		sme_err("Invalid channel: %d", channel);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+
+	if (QDF_STATUS_SUCCESS == status) {
+		/* update the channel list to the firmware */
+		status = csr_send_ext_change_channel(mac_ctx,
+						channel, session_id);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_get_roam_intra_band() -
+ * get Intra band roaming
+ *
+ * hHal - HAL handle for device
+ * Return Success or failure
+ */
+bool sme_get_roam_intra_band(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND, NO_SESSION, 0));
+	return pMac->roam.configParam.nRoamIntraBand;
+}
+
+/*
+ * sme_get_roam_scan_n_probes() -
+ * get N Probes
+ *
+ * hHal - HAL handle for device
+ * Return Success or failure
+ */
+uint8_t sme_get_roam_scan_n_probes(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.nProbes;
+}
+
+/*
+ * sme_get_roam_scan_home_away_time() -
+ * get Roam scan home away time
+ *
+ * hHal - HAL handle for device
+ * Return Success or failure
+ */
+uint16_t sme_get_roam_scan_home_away_time(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.nRoamScanHomeAwayTime;
+}
+
+/*
+ * sme_update_roam_rssi_diff() -
+ * Update RoamRssiDiff
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure RoamRssiDiff
+ *	    Usage: adb shell iwpriv wlan0 setConfig RoamRssiDiff=[0 .. 125]
+ *
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * RoamRssiDiff - minimum rssi difference between potential
+ *	    candidate and current AP.
+ * Return Success or failure
+ */
+
+QDF_STATUS sme_update_roam_rssi_diff(tHalHandle hHal, uint8_t sessionId,
+				     uint8_t RoamRssiDiff)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "LFR runtime successfully set roam rssi diff to %d - old value is %d - roam state is %s",
+			  RoamRssiDiff,
+			  pMac->roam.configParam.RoamRssiDiff,
+			  mac_trace_get_neighbour_roam_state(pMac->roam.
+							     neighborRoamInfo
+							     [sessionId].
+							    neighborRoamState));
+		pMac->roam.configParam.RoamRssiDiff = RoamRssiDiff;
+
+		if (pMac->roam.configParam.isRoamOffloadScanEnabled)
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+					      REASON_RSSI_DIFF_CHANGED);
+
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+QDF_STATUS sme_update_fils_config(tHalHandle hal, uint8_t session_id,
+				  struct csr_roam_profile *src_profile)
+{
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+			&mac->roam.neighborRoamInfo[session_id];
+
+	if (session_id >= CSR_ROAM_SESSION_MAX) {
+		sme_err("Invalid sme session id: %d", session_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!src_profile) {
+		sme_err("src roam profile NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!mac->roam.configParam.isFastRoamIniFeatureEnabled ||
+	    (neighbor_roam_info->neighborRoamState !=
+	     eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)) {
+		sme_info("Fast roam is disabled or not connected(%d)",
+				neighbor_roam_info->neighborRoamState);
+		return QDF_STATUS_E_PERM;
+	}
+
+	csr_update_fils_config(mac, session_id, src_profile);
+	if (csr_roamIsRoamOffloadEnabled(mac)) {
+		status = sme_acquire_global_lock(&mac->sme);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			sme_debug("Updating fils config to fw");
+			csr_roam_offload_scan(mac, session_id,
+					      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+					      REASON_FILS_PARAMS_CHANGED);
+			sme_release_global_lock(&mac->sme);
+		} else {
+			sme_err("Failed to acquire SME lock");
+		}
+	} else {
+		sme_info("LFR3 not enabled");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return status;
+}
+
+void sme_send_hlp_ie_info(tHalHandle hal, uint8_t session_id,
+			  struct csr_roam_profile *profile, uint32_t if_addr)
+{
+	int i;
+	struct scheduler_msg msg;
+	QDF_STATUS status;
+	struct hlp_params *params;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct csr_roam_session *session = CSR_GET_SESSION(mac, session_id);
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+				&mac->roam.neighborRoamInfo[session_id];
+
+	if (!session) {
+		sme_err("session NULL");
+		return;
+	}
+
+	if (!mac->roam.configParam.isFastRoamIniFeatureEnabled ||
+	    (neighbor_roam_info->neighborRoamState !=
+	     eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)) {
+		sme_debug("Fast roam is disabled or not connected(%d)",
+				neighbor_roam_info->neighborRoamState);
+		return;
+	}
+
+	params = qdf_mem_malloc(sizeof(*params));
+	if (!params)
+		return;
+
+	if ((profile->hlp_ie_len +
+	     SIR_IPV4_ADDR_LEN) > FILS_MAX_HLP_DATA_LEN) {
+		sme_err("HLP IE len exceeds %d",
+				profile->hlp_ie_len);
+		qdf_mem_free(params);
+		return;
+	}
+
+	params->vdev_id = session_id;
+	params->hlp_ie_len = profile->hlp_ie_len + SIR_IPV4_ADDR_LEN;
+
+	for (i = 0; i < SIR_IPV4_ADDR_LEN; i++)
+		params->hlp_ie[i] = (if_addr >> (i * 8)) & 0xFF;
+
+	qdf_mem_copy(params->hlp_ie + SIR_IPV4_ADDR_LEN,
+		     profile->hlp_ie, profile->hlp_ie_len);
+
+	msg.type = SIR_HAL_HLP_IE_INFO;
+	msg.reserved = 0;
+	msg.bodyptr = params;
+	status = sme_acquire_global_lock(&mac->sme);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("sme lock acquire fails");
+		qdf_mem_free(params);
+		return;
+	}
+
+	if (!QDF_IS_STATUS_SUCCESS
+			(scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &msg))) {
+		sme_err("Not able to post WMA_HLP_IE_INFO message to HAL");
+		sme_release_global_lock(&mac->sme);
+		qdf_mem_free(params);
+		return;
+	}
+
+	sme_release_global_lock(&mac->sme);
+}
+
+void sme_free_join_rsp_fils_params(struct csr_roam_info *roam_info)
+{
+	struct fils_join_rsp_params *roam_fils_params;
+
+	if (!roam_info) {
+		sme_err("FILS Roam Info NULL");
+		return;
+	}
+
+	roam_fils_params = roam_info->fils_join_rsp;
+	if (!roam_fils_params) {
+		sme_err("FILS Roam Param NULL");
+		return;
+	}
+
+	if (roam_fils_params->fils_pmk)
+		qdf_mem_free(roam_fils_params->fils_pmk);
+
+	qdf_mem_free(roam_fils_params);
+
+	roam_info->fils_join_rsp = NULL;
+}
+
+#else
+inline void sme_send_hlp_ie_info(tHalHandle hal, uint8_t session_id,
+			  struct csr_roam_profile *profile, uint32_t if_addr)
+{}
+#endif
+
+/*
+ * sme_update_fast_transition_enabled() - enable/disable Fast Transition
+ *	support at runtime
+ *  It is used at in the REG_DYNAMIC_VARIABLE macro definition of
+ *  isFastTransitionEnabled.
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return QDF_STATUS_SUCCESS - SME update isFastTransitionEnabled config
+ *	successfully.
+ *	Other status means SME is failed to update isFastTransitionEnabled.
+ */
+QDF_STATUS sme_update_fast_transition_enabled(tHalHandle hHal,
+					      bool isFastTransitionEnabled)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED, NO_SESSION,
+			 0));
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: FastTransitionEnabled is changed from %d to %d",
+			  __func__,
+			  pMac->roam.configParam.isFastTransitionEnabled,
+			  isFastTransitionEnabled);
+		pMac->roam.configParam.isFastTransitionEnabled =
+			isFastTransitionEnabled;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_update_wes_mode() -
+ * Update WES Mode
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure isWESModeEnabled
+ *
+ * hHal - HAL handle for device
+ * isWESModeEnabled - WES mode
+ * sessionId - Session Identifier
+ * Return QDF_STATUS_SUCCESS - SME update isWESModeEnabled config successfully.
+ *	    Other status means SME is failed to update isWESModeEnabled.
+ */
+
+QDF_STATUS sme_update_wes_mode(tHalHandle hHal, bool isWESModeEnabled,
+			       uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "LFR runtime successfully set WES Mode to %d - old value is %d - roam state is %s",
+			  isWESModeEnabled,
+			  pMac->roam.configParam.isWESModeEnabled,
+			  mac_trace_get_neighbour_roam_state(pMac->roam.
+							     neighborRoamInfo
+							     [sessionId].
+							    neighborRoamState));
+		pMac->roam.configParam.isWESModeEnabled = isWESModeEnabled;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_set_roam_scan_control() -
+ * Set roam scan control
+ *	    This function is called to set roam scan control
+ *	    if roam scan control is set to 0, roaming scan cache is cleared
+ *	    any value other than 0 is treated as invalid value
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * Return QDF_STATUS_SUCCESS - SME update config successfully.
+ *	    Other status means SME failure to update
+ */
+QDF_STATUS sme_set_roam_scan_control(tHalHandle hHal, uint8_t sessionId,
+				     bool roamScanControl)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+			 TRACE_CODE_SME_RX_HDD_SET_SCANCTRL, NO_SESSION, 0));
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "LFR runtime successfully set roam scan control to %d - old value is %d - roam state is %s",
+			  roamScanControl,
+			  pMac->roam.configParam.nRoamScanControl,
+			  mac_trace_get_neighbour_roam_state(pMac->roam.
+							     neighborRoamInfo
+							     [sessionId].
+							    neighborRoamState));
+		pMac->roam.configParam.nRoamScanControl = roamScanControl;
+		if (0 == roamScanControl) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "LFR runtime successfully cleared roam scan cache");
+			csr_flush_cfg_bg_scan_roam_channel_list(pMac,
+								sessionId);
+			if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
+				csr_roam_offload_scan(pMac, sessionId,
+						   ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+						     REASON_FLUSH_CHANNEL_LIST);
+			}
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_update_is_fast_roam_ini_feature_enabled() - enable/disable LFR
+ *	support at runtime
+ * It is used at in the REG_DYNAMIC_VARIABLE macro definition of
+ * isFastRoamIniFeatureEnabled.
+ * This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return QDF_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config
+ *	successfully.
+ * Other status means SME is failed to update isFastRoamIniFeatureEnabled.
+ */
+QDF_STATUS sme_update_is_fast_roam_ini_feature_enabled(tHalHandle hHal,
+		uint8_t sessionId, const bool isFastRoamIniFeatureEnabled)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (pMac->roam.configParam.isFastRoamIniFeatureEnabled ==
+	    isFastRoamIniFeatureEnabled) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: FastRoam is already enabled or disabled, nothing to do (returning) old(%d) new(%d)",
+			  __func__,
+			  pMac->roam.configParam.isFastRoamIniFeatureEnabled,
+			  isFastRoamIniFeatureEnabled);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: FastRoamEnabled is changed from %d to %d", __func__,
+		  pMac->roam.configParam.isFastRoamIniFeatureEnabled,
+		  isFastRoamIniFeatureEnabled);
+	pMac->roam.configParam.isFastRoamIniFeatureEnabled =
+		isFastRoamIniFeatureEnabled;
+	csr_neighbor_roam_update_fast_roaming_enabled(pMac, sessionId,
+						   isFastRoamIniFeatureEnabled);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_config_fast_roaming() - enable/disable LFR support at runtime
+ * @hal - The handle returned by macOpen.
+ * @session_id - Session Identifier
+ * @is_fast_roam_enabled - flag to enable/disable roaming
+ *
+ * When Supplicant issues enabled/disable fast roaming on the basis
+ * of the Bssid modification in network block (e.g. AutoJoin mode N/W block)
+ *
+ * Return: QDF_STATUS
+ */
+
+QDF_STATUS sme_config_fast_roaming(tHalHandle hal, uint8_t session_id,
+				   const bool is_fast_roam_enabled)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+	QDF_STATUS status;
+
+	/*
+	 * supplicant_disabled_roaming flag is set to true in
+	 * wlan_hdd_cfg80211_connect_start when supplicant initiate connect
+	 * request with BSSID. This flag is reset when supplicant sends
+	 * vendor command to enable roaming after association.
+	 *
+	 * This request from wpa_supplicant will be skipped in this function
+	 * if roaming is disabled using driver command or INI and
+	 * supplicant_disabled_roaming flag remains set. So make sure to set
+	 * supplicant_disabled_roaming flag as per wpa_supplicant even if roam
+	 * request from wpa_supplicant ignored.
+	 */
+	if (session && session->pCurRoamProfile)
+		session->pCurRoamProfile->supplicant_disabled_roaming =
+			!is_fast_roam_enabled;
+
+	if (!mac_ctx->roam.configParam.isFastRoamIniFeatureEnabled) {
+		sme_debug("Fast roam is disabled through ini");
+		if (!is_fast_roam_enabled)
+			return QDF_STATUS_SUCCESS;
+		return  QDF_STATUS_E_FAILURE;
+	}
+
+	status = csr_neighbor_roam_update_fast_roaming_enabled(mac_ctx,
+					 session_id, is_fast_roam_enabled);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("update fast roaming failed. status: %d", status);
+		return  QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_update_is_mawc_ini_feature_enabled() -
+ *  Enable/disable LFR MAWC support at runtime
+ *  It is used at in the REG_DYNAMIC_VARIABLE macro definition of
+ *  isMAWCIniFeatureEnabled.
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return QDF_STATUS_SUCCESS - SME update MAWCEnabled config successfully.
+ *	Other status means SME is failed to update MAWCEnabled.
+ */
+QDF_STATUS sme_update_is_mawc_ini_feature_enabled(tHalHandle hHal,
+						  const bool MAWCEnabled)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: MAWCEnabled is changed from %d to %d", __func__,
+			  pMac->roam.configParam.csr_mawc_config.mawc_enabled,
+			  MAWCEnabled);
+		pMac->roam.configParam.csr_mawc_config.mawc_enabled =
+			MAWCEnabled;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+
+}
+
+/**
+ * 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};
+	QDF_STATUS status;
+	tSirRoamOffloadScanReq *req;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	tpCsrNeighborRoamControlInfo roam_info;
+	struct csr_roam_session *session;
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("incorrect session/vdev ID");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	/*
+	 * set the driver_disabled_roaming flag to true even if roaming
+	 * is not enabled on this session so that roam start requests for
+	 * this session can be blocked until driver enables roaming
+	 */
+	if (reason == ecsr_driver_disabled && session->pCurRoamProfile &&
+	    session->pCurRoamProfile->csrPersona == QDF_STA_MODE) {
+		session->pCurRoamProfile->driver_disabled_roaming = true;
+		sme_debug("driver_disabled_roaming set for session %d",
+			  session_id);
+	}
+
+	roam_info = &mac_ctx->roam.neighborRoamInfo[session_id];
+	if (!roam_info->b_roam_scan_offload_started) {
+		sme_debug("Roaming already disabled for session %d", session_id);
+		return QDF_STATUS_SUCCESS;
+	}
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return QDF_STATUS_E_NOMEM;
+
+	req->Command = ROAM_SCAN_OFFLOAD_STOP;
+	if ((reason == eCsrForcedDisassoc) || reason == ecsr_driver_disabled)
+		req->reason = REASON_ROAM_STOP_ALL;
+	else
+		req->reason = REASON_SME_ISSUED;
+	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);
+
+	wma_msg.type = WMA_ROAM_SCAN_OFFLOAD_REQ;
+	wma_msg.bodyptr = req;
+
+	status = wma_post_ctrl_msg(mac_ctx, &wma_msg);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("WMA_ROAM_SCAN_OFFLOAD_REQ failed, session_id: %d",
+			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;
+}
+
+/*
+ * sme_start_roaming() - Start 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_start_roaming(tHalHandle hHal, uint8_t sessionId, uint8_t reason)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START,
+				      reason);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_update_enable_fast_roam_in_concurrency() - enable/disable LFR if
+ *	Concurrent session exists
+ *  This is a synchronuous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return QDF_STATUS_SUCCESS
+ *	Other status means SME is failed
+ */
+QDF_STATUS sme_update_enable_fast_roam_in_concurrency(tHalHandle hHal,
+						      bool
+						bFastRoamInConIniFeatureEnabled)
+{
+
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pMac->roam.configParam.bFastRoamInConIniFeatureEnabled =
+			bFastRoamInConIniFeatureEnabled;
+		if (0 == pMac->roam.configParam.isRoamOffloadScanEnabled) {
+			pMac->roam.configParam.bFastRoamInConIniFeatureEnabled =
+				0;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_set_roam_opportunistic_scan_threshold_diff() -
+ * Update Opportunistic Scan threshold diff
+ *	This function is called through dynamic setConfig callback function
+ *	to configure  nOpportunisticThresholdDiff
+ *
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * nOpportunisticThresholdDiff - Opportunistic Scan threshold diff
+ * Return QDF_STATUS_SUCCESS - SME update nOpportunisticThresholdDiff config
+ *	    successfully.
+ *	    else SME is failed to update nOpportunisticThresholdDiff.
+ */
+QDF_STATUS sme_set_roam_opportunistic_scan_threshold_diff(tHalHandle hHal,
+							  uint8_t sessionId,
+							  const uint8_t
+						nOpportunisticThresholdDiff)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_neighbor_roam_update_config(pMac, sessionId,
+				nOpportunisticThresholdDiff,
+				REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			pMac->roam.configParam.neighborRoamConfig.
+			nOpportunisticThresholdDiff =
+				nOpportunisticThresholdDiff;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_get_roam_opportunistic_scan_threshold_diff()
+ * gets Opportunistic Scan threshold diff
+ * This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open
+ * Return uint8_t - nOpportunisticThresholdDiff
+ */
+uint8_t sme_get_roam_opportunistic_scan_threshold_diff(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.neighborRoamConfig.
+	       nOpportunisticThresholdDiff;
+}
+
+/*
+ * sme_set_roam_rescan_rssi_diff() - Update roam rescan rssi diff
+ * This function is called through dynamic setConfig callback function
+ * to configure  nRoamRescanRssiDiff
+ *
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * nRoamRescanRssiDiff - roam rescan rssi diff
+ * Return QDF_STATUS_SUCCESS - SME update nRoamRescanRssiDiff config
+ *	    successfully.
+ * else SME is failed to update nRoamRescanRssiDiff.
+ */
+QDF_STATUS sme_set_roam_rescan_rssi_diff(tHalHandle hHal,
+					 uint8_t sessionId,
+					 const uint8_t nRoamRescanRssiDiff)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_neighbor_roam_update_config(pMac, sessionId,
+				nRoamRescanRssiDiff,
+				REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamRescanRssiDiff = nRoamRescanRssiDiff;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_get_roam_rescan_rssi_diff()
+ * gets roam rescan rssi diff
+ *	  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open
+ * Return int8_t - nRoamRescanRssiDiff
+ */
+uint8_t sme_get_roam_rescan_rssi_diff(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff;
+}
+
+/*
+ * sme_set_roam_bmiss_first_bcnt() -
+ * Update Roam count for first beacon miss
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure nRoamBmissFirstBcnt
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * nRoamBmissFirstBcnt - Roam first bmiss count
+ * Return QDF_STATUS_SUCCESS - SME update nRoamBmissFirstBcnt
+ *	    successfully.
+ * else SME is failed to update nRoamBmissFirstBcnt
+ */
+QDF_STATUS sme_set_roam_bmiss_first_bcnt(tHalHandle hHal,
+					 uint8_t sessionId,
+					 const uint8_t nRoamBmissFirstBcnt)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_neighbor_roam_update_config(pMac, sessionId,
+				nRoamBmissFirstBcnt,
+				REASON_ROAM_BMISS_FIRST_BCNT_CHANGED);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamBmissFirstBcnt = nRoamBmissFirstBcnt;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_get_roam_bmiss_first_bcnt() -
+ * get neighbor roam beacon miss first count
+ *
+ * hHal - The handle returned by mac_open.
+ * Return uint8_t - neighbor roam beacon miss first count
+ */
+uint8_t sme_get_roam_bmiss_first_bcnt(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt;
+}
+
+/*
+ * sme_set_roam_bmiss_final_bcnt() -
+ * Update Roam count for final beacon miss
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure nRoamBmissFinalBcnt
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * nRoamBmissFinalBcnt - Roam final bmiss count
+ * Return QDF_STATUS_SUCCESS - SME update nRoamBmissFinalBcnt
+ *	    successfully.
+ * else SME is failed to update nRoamBmissFinalBcnt
+ */
+QDF_STATUS sme_set_roam_bmiss_final_bcnt(tHalHandle hHal,
+					 uint8_t sessionId,
+					 const uint8_t nRoamBmissFinalBcnt)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_neighbor_roam_update_config(pMac, sessionId,
+				nRoamBmissFinalBcnt,
+				REASON_ROAM_BMISS_FINAL_BCNT_CHANGED);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamBmissFinalBcnt = nRoamBmissFinalBcnt;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_get_roam_bmiss_final_bcnt() -
+ * gets Roam count for final beacon miss
+ *	  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open
+ * Return uint8_t - nRoamBmissFinalBcnt
+ */
+uint8_t sme_get_roam_bmiss_final_bcnt(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt;
+}
+
+/*
+ * sme_set_roam_beacon_rssi_weight() -
+ * Update Roam beacon rssi weight
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure nRoamBeaconRssiWeight
+ *
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * nRoamBeaconRssiWeight - Roam beacon rssi weight
+ * Return QDF_STATUS_SUCCESS - SME update nRoamBeaconRssiWeight config
+ *	    successfully.
+ * else SME is failed to update nRoamBeaconRssiWeight
+ */
+QDF_STATUS sme_set_roam_beacon_rssi_weight(tHalHandle hHal,
+					   uint8_t sessionId,
+					   const uint8_t nRoamBeaconRssiWeight)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_neighbor_roam_update_config(pMac, sessionId,
+				nRoamBeaconRssiWeight,
+				REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamBeaconRssiWeight = nRoamBeaconRssiWeight;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_get_roam_beacon_rssi_weight() -
+ * gets Roam beacon rssi weight
+ *	  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open
+ * Return uint8_t - nRoamBeaconRssiWeight
+ */
+uint8_t sme_get_roam_beacon_rssi_weight(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight;
+}
+
+/*
+ * sme_set_neighbor_lookup_rssi_threshold() - update neighbor lookup
+ *	rssi threshold
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return QDF_STATUS_SUCCESS - SME update config successful.
+ *	   Other status means SME is failed to update
+ */
+QDF_STATUS sme_set_neighbor_lookup_rssi_threshold(tHalHandle hHal,
+			uint8_t sessionId, uint8_t neighborLookupRssiThreshold)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_neighbor_roam_update_config(pMac,
+				sessionId, neighborLookupRssiThreshold,
+				REASON_LOOKUP_THRESH_CHANGED);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			pMac->roam.configParam.neighborRoamConfig.
+			nNeighborLookupRssiThreshold =
+				neighborLookupRssiThreshold;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_set_delay_before_vdev_stop() - update delay before VDEV_STOP
+ *  This is a synchronous call
+ *
+ * hal - The handle returned by macOpen.
+ * session_id - Session Identifier
+ * delay_before_vdev_stop - value to be set
+ * Return QDF_STATUS_SUCCESS - SME update config successful.
+ *	  Other status means SME is failed to update
+ */
+QDF_STATUS sme_set_delay_before_vdev_stop(tHalHandle hal,
+					  uint8_t session_id,
+					  uint8_t delay_before_vdev_stop)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (session_id >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), session_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"LFR param delay_before_vdev_stop changed from %d to %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			delay_before_vdev_stop,
+			delay_before_vdev_stop);
+		pMac->roam.neighborRoamInfo[session_id].cfgParams.
+			delay_before_vdev_stop = delay_before_vdev_stop;
+		pMac->roam.configParam.neighborRoamConfig.
+			delay_before_vdev_stop = delay_before_vdev_stop;
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_get_neighbor_lookup_rssi_threshold() - get neighbor lookup
+ *	rssi threshold
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return QDF_STATUS_SUCCESS - SME update config successful.
+ *	   Other status means SME is failed to update
+ */
+uint8_t sme_get_neighbor_lookup_rssi_threshold(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.neighborRoamConfig.
+	       nNeighborLookupRssiThreshold;
+}
+
+/*
+ * sme_set_neighbor_scan_refresh_period() - set neighbor scan results
+ *	refresh period
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return QDF_STATUS_SUCCESS - SME update config successful.
+ *	   Other status means SME is failed to update
+ */
+QDF_STATUS sme_set_neighbor_scan_refresh_period(tHalHandle hHal,
+		uint8_t sessionId, uint16_t neighborScanResultsRefreshPeriod)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_neighbor_roamconfig *pNeighborRoamConfig = NULL;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pNeighborRoamConfig =
+			&pMac->roam.configParam.neighborRoamConfig;
+		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "LFR runtime successfully set roam scan refresh period to %d- old value is %d - roam state is %s",
+			  neighborScanResultsRefreshPeriod,
+			  pMac->roam.configParam.neighborRoamConfig.
+			  nNeighborResultsRefreshPeriod,
+			  mac_trace_get_neighbour_roam_state(pMac->roam.
+							     neighborRoamInfo
+							     [sessionId].
+							    neighborRoamState));
+		pNeighborRoamConfig->nNeighborResultsRefreshPeriod =
+			neighborScanResultsRefreshPeriod;
+		pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod =
+			neighborScanResultsRefreshPeriod;
+
+		if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
+			csr_roam_offload_scan(pMac, sessionId,
+				ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_update_roam_scan_offload_enabled() - enable/disable roam scan
+ *	offload feaure
+ *  It is used at in the REG_DYNAMIC_VARIABLE macro definition of
+ *  gRoamScanOffloadEnabled.
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return QDF_STATUS_SUCCESS - SME update config successfully.
+ *	   Other status means SME is failed to update.
+ */
+QDF_STATUS sme_update_roam_scan_offload_enabled(tHalHandle hHal,
+						bool nRoamScanOffloadEnabled)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "gRoamScanOffloadEnabled is changed from %d to %d",
+			  pMac->roam.configParam.isRoamOffloadScanEnabled,
+			  nRoamScanOffloadEnabled);
+		pMac->roam.configParam.isRoamOffloadScanEnabled =
+			nRoamScanOffloadEnabled;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_get_neighbor_scan_refresh_period() - get neighbor scan results
+ *	refresh period
+ *  This is a synchronous call
+ *
+ *  \param hHal - The handle returned by mac_open.
+ *  \return uint16_t - Neighbor scan results refresh period value
+ */
+uint16_t sme_get_neighbor_scan_refresh_period(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.neighborRoamConfig.
+	       nNeighborResultsRefreshPeriod;
+}
+
+/*
+ * sme_get_empty_scan_refresh_period() - get empty scan refresh period
+ * This is a synchronuous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return QDF_STATUS_SUCCESS - SME update config successful.
+ *	   Other status means SME is failed to update
+ */
+uint16_t sme_get_empty_scan_refresh_period(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.neighborRoamConfig.
+	       nEmptyScanRefreshPeriod;
+}
+
+/*
+ * sme_update_empty_scan_refresh_period
+ * Update nEmptyScanRefreshPeriod
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure nEmptyScanRefreshPeriod
+ *	    Usage: adb shell iwpriv wlan0 setConfig
+ *			nEmptyScanRefreshPeriod=[0 .. 60]
+ *
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * nEmptyScanRefreshPeriod - scan period following empty scan results.
+ * Return Success or failure
+ */
+
+QDF_STATUS sme_update_empty_scan_refresh_period(tHalHandle hHal, uint8_t
+						sessionId, uint16_t
+						nEmptyScanRefreshPeriod)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_neighbor_roamconfig *pNeighborRoamConfig = NULL;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pNeighborRoamConfig =
+			&pMac->roam.configParam.neighborRoamConfig;
+		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "LFR runtime successfully set roam scan period to %d -old value is %d - roam state is %s",
+			  nEmptyScanRefreshPeriod,
+			  pMac->roam.configParam.neighborRoamConfig.
+			  nEmptyScanRefreshPeriod,
+			  mac_trace_get_neighbour_roam_state(pMac->roam.
+							     neighborRoamInfo
+							     [sessionId].
+							    neighborRoamState));
+		pNeighborRoamConfig->nEmptyScanRefreshPeriod =
+			nEmptyScanRefreshPeriod;
+		pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod =
+			nEmptyScanRefreshPeriod;
+
+		if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
+			csr_roam_offload_scan(pMac, sessionId,
+				ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				REASON_EMPTY_SCAN_REF_PERIOD_CHANGED);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_set_neighbor_scan_min_chan_time() -
+ * Update nNeighborScanMinChanTime
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure gNeighborScanChannelMinTime
+ *	    Usage: adb shell iwpriv wlan0 setConfig
+ *			gNeighborScanChannelMinTime=[0 .. 60]
+ *
+ * hHal - HAL handle for device
+ * nNeighborScanMinChanTime - Channel minimum dwell time
+ * sessionId - Session Identifier
+ * Return Success or failure
+ */
+QDF_STATUS sme_set_neighbor_scan_min_chan_time(tHalHandle hHal,
+					       const uint16_t
+					       nNeighborScanMinChanTime,
+					       uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "LFR runtime successfully set channel min dwell time to %d - old value is %d - roam state is %s",
+			  nNeighborScanMinChanTime,
+			  pMac->roam.configParam.neighborRoamConfig.
+			  nNeighborScanMinChanTime,
+			  mac_trace_get_neighbour_roam_state(pMac->roam.
+							     neighborRoamInfo
+							     [sessionId].
+							    neighborRoamState));
+
+		pMac->roam.configParam.neighborRoamConfig.
+		nNeighborScanMinChanTime = nNeighborScanMinChanTime;
+		pMac->roam.neighborRoamInfo[sessionId].cfgParams.
+		minChannelScanTime = nNeighborScanMinChanTime;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_set_neighbor_scan_max_chan_time() -
+ * Update nNeighborScanMaxChanTime
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure gNeighborScanChannelMaxTime
+ *	    Usage: adb shell iwpriv wlan0 setConfig
+ *			gNeighborScanChannelMaxTime=[0 .. 60]
+ *
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * nNeighborScanMinChanTime - Channel maximum dwell time
+ * Return Success or failure
+ */
+QDF_STATUS sme_set_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t
+						sessionId,
+					       const uint16_t
+					       nNeighborScanMaxChanTime)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_neighbor_roamconfig *pNeighborRoamConfig = NULL;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pNeighborRoamConfig =
+			&pMac->roam.configParam.neighborRoamConfig;
+		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "LFR runtime successfully set channel max dwell time to %d - old value is %d - roam state is %s",
+			  nNeighborScanMaxChanTime,
+			  pMac->roam.configParam.neighborRoamConfig.
+			  nNeighborScanMaxChanTime,
+			  mac_trace_get_neighbour_roam_state(pMac->roam.
+							     neighborRoamInfo
+							     [sessionId].
+							    neighborRoamState));
+		pNeighborRoamConfig->nNeighborScanMaxChanTime =
+			nNeighborScanMaxChanTime;
+		pNeighborRoamInfo->cfgParams.maxChannelScanTime =
+			nNeighborScanMaxChanTime;
+		if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+					      REASON_SCAN_CH_TIME_CHANGED);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+
+	return status;
+}
+
+/*
+ * sme_get_neighbor_scan_min_chan_time() -
+ * get neighbor scan min channel time
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return uint16_t - channel min time value
+ */
+uint16_t sme_get_neighbor_scan_min_chan_time(tHalHandle hHal, uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return 0;
+	}
+
+	return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
+	       minChannelScanTime;
+}
+
+/*
+ * sme_get_neighbor_roam_state() -
+ * get neighbor roam state
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return uint32_t - neighbor roam state
+ */
+uint32_t sme_get_neighbor_roam_state(tHalHandle hHal, uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return 0;
+	}
+
+	return pMac->roam.neighborRoamInfo[sessionId].neighborRoamState;
+}
+
+/*
+ * sme_get_current_roam_state() -
+ * get current roam state
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return uint32_t - current roam state
+ */
+uint32_t sme_get_current_roam_state(tHalHandle hHal, uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.curState[sessionId];
+}
+
+/*
+ * sme_get_current_roam_sub_state() -
+ *   \brief  get neighbor roam sub state
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return uint32_t - current roam sub state
+ */
+uint32_t sme_get_current_roam_sub_state(tHalHandle hHal, uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.curSubState[sessionId];
+}
+
+/*
+ * sme_get_lim_sme_state() -
+ *   get Lim Sme state
+ *
+ * hHal - The handle returned by mac_open.
+ * Return uint32_t - Lim Sme state
+ */
+uint32_t sme_get_lim_sme_state(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->lim.gLimSmeState;
+}
+
+/*
+ * sme_get_lim_mlm_state() -
+ *   get Lim Mlm state
+ *
+ * hHal - The handle returned by mac_open.
+ * Return uint32_t - Lim Mlm state
+ */
+uint32_t sme_get_lim_mlm_state(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->lim.gLimMlmState;
+}
+
+/*
+ * sme_is_lim_session_valid() -
+ *  is Lim session valid
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return bool - true or false
+ */
+bool sme_is_lim_session_valid(tHalHandle hHal, uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (sessionId > pMac->lim.maxBssId)
+		return false;
+
+	return pMac->lim.gpSession[sessionId].valid;
+}
+
+/*
+ * sme_get_lim_sme_session_state() -
+ *   get Lim Sme session state
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return uint32_t - Lim Sme session state
+ */
+uint32_t sme_get_lim_sme_session_state(tHalHandle hHal, uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->lim.gpSession[sessionId].limSmeState;
+}
+
+/*
+ * sme_get_lim_mlm_session_state() -
+ *   \brief  get Lim Mlm session state
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return uint32_t - Lim Mlm session state
+ */
+uint32_t sme_get_lim_mlm_session_state(tHalHandle hHal, uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->lim.gpSession[sessionId].limMlmState;
+}
+
+/*
+ * sme_get_neighbor_scan_max_chan_time() -
+ *   get neighbor scan max channel time
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return uint16_t - channel max time value
+ */
+uint16_t sme_get_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return 0;
+	}
+
+	return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
+	       maxChannelScanTime;
+}
+
+/*
+ * sme_set_neighbor_scan_period() -
+ *  Update nNeighborScanPeriod
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure nNeighborScanPeriod
+ *	    Usage: adb shell iwpriv wlan0 setConfig
+ *			nNeighborScanPeriod=[0 .. 1000]
+ *
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * nNeighborScanPeriod - neighbor scan period
+ * Return Success or failure
+ */
+QDF_STATUS sme_set_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId,
+					const uint16_t nNeighborScanPeriod)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_neighbor_roamconfig *pNeighborRoamConfig = NULL;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pNeighborRoamConfig =
+			&pMac->roam.configParam.neighborRoamConfig;
+		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "LFR runtime successfully set neighbor scan period to %d - old value is %d - roam state is %s",
+			  nNeighborScanPeriod,
+			  pMac->roam.configParam.neighborRoamConfig.
+			  nNeighborScanTimerPeriod,
+			  mac_trace_get_neighbour_roam_state(pMac->roam.
+							     neighborRoamInfo
+							     [sessionId].
+							    neighborRoamState));
+		pNeighborRoamConfig->nNeighborScanTimerPeriod =
+			nNeighborScanPeriod;
+		pNeighborRoamInfo->cfgParams.neighborScanPeriod =
+			nNeighborScanPeriod;
+
+		if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+					      REASON_SCAN_HOME_TIME_CHANGED);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_get_neighbor_scan_period() -
+ *   get neighbor scan period
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return uint16_t - neighbor scan period
+ */
+uint16_t sme_get_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return 0;
+	}
+
+	return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
+	       neighborScanPeriod;
+}
+
+/**
+ * sme_set_neighbor_scan_min_period() - Update neighbor_scan_min_period
+ *          This function is called through dynamic setConfig callback function
+ *          to configure neighbor_scan_min_period
+ *
+ * @hal - HAL handle for device
+ * @session_id - Session Identifier
+ * @neighbor_scan_min_period - neighbor scan min period
+ *
+ * Return - QDF_STATUS
+ */
+QDF_STATUS sme_set_neighbor_scan_min_period(tHalHandle hal,
+					    uint8_t session_id,
+					    const uint16_t
+					    neighbor_scan_min_period)
+{
+	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_neighbor_roamconfig *p_neighbor_roam_config = NULL;
+	tpCsrNeighborRoamControlInfo p_neighbor_roam_info = NULL;
+
+	if (session_id >= CSR_ROAM_SESSION_MAX) {
+		sme_err("Invalid sme session id: %d", session_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&pmac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		p_neighbor_roam_config =
+				&pmac->roam.configParam.neighborRoamConfig;
+		p_neighbor_roam_info = &pmac->
+				roam.neighborRoamInfo[session_id];
+		sme_debug("LFR:set neighbor scan min period, old:%d, "
+				"new: %d, state: %s",
+				pmac->roam.configParam.neighborRoamConfig.
+				neighbor_scan_min_timer_period,
+				neighbor_scan_min_period,
+				mac_trace_get_neighbour_roam_state(pmac->roam.
+				neighborRoamInfo[session_id].
+				neighborRoamState));
+		p_neighbor_roam_config->neighbor_scan_min_timer_period =
+				neighbor_scan_min_period;
+		p_neighbor_roam_info->cfgParams.neighbor_scan_min_period =
+				neighbor_scan_min_period;
+		sme_release_global_lock(&pmac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_get_roam_rssi_diff() - get Roam rssi diff
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return uint16_t - Rssi diff value
+ */
+uint8_t sme_get_roam_rssi_diff(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.RoamRssiDiff;
+}
+
+/**
+ * sme_change_roam_scan_channel_list() - to change scan channel list
+ * @hHal: pointer HAL handle returned by mac_open
+ * @sessionId: sme session id
+ * @pChannelList: Output channel list
+ * @numChannels: Output number of channels
+ *
+ * This routine is called to Change roam scan channel list.
+ * This is a synchronous call
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_change_roam_scan_channel_list(tHalHandle hHal, uint8_t sessionId,
+					     uint8_t *pChannelList,
+					     uint8_t numChannels)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+	uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
+	uint8_t newChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
+	uint8_t i = 0, j = 0;
+	tCsrChannelInfo *chan_info;
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Failed to acquire SME lock");
+		return status;
+	}
+	chan_info = &pNeighborRoamInfo->cfgParams.channelInfo;
+
+	if (NULL != chan_info->ChannelList) {
+		for (i = 0; i < chan_info->numOfChannels; i++) {
+			if (j < sizeof(oldChannelList))
+				j += snprintf(oldChannelList + j,
+					sizeof(oldChannelList) -
+					j, "%d",
+					chan_info->ChannelList[i]);
+			else
+				break;
+		}
+	}
+	csr_flush_cfg_bg_scan_roam_channel_list(pMac, sessionId);
+	csr_create_bg_scan_roam_channel_list(pMac, sessionId, pChannelList,
+			numChannels);
+	sme_set_roam_scan_control(hHal, sessionId, 1);
+	if (NULL != chan_info->ChannelList) {
+		j = 0;
+		for (i = 0; i < chan_info->numOfChannels; i++) {
+			if (j < sizeof(newChannelList))
+				j += snprintf(newChannelList + j,
+					sizeof(newChannelList) -
+					j, " %d",
+					chan_info->ChannelList[i]);
+			else
+				break;
+		}
+	}
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		"LFR runtime successfully set roam scan channels to %s - old value is %s - roam state is %d",
+			newChannelList, oldChannelList,
+		pMac->roam.neighborRoamInfo[sessionId].neighborRoamState);
+
+	if (pMac->roam.configParam.isRoamOffloadScanEnabled)
+		csr_roam_offload_scan(pMac, sessionId,
+				ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				REASON_CHANNEL_LIST_CHANGED);
+
+	sme_release_global_lock(&pMac->sme);
+	return status;
+}
+
+/**
+ * sme_get_roam_scan_channel_list() - To get roam scan channel list
+ * @hHal: HAL pointer
+ * @pChannelList: Output channel list
+ * @pNumChannels: Output number of channels
+ * @sessionId: Session Identifier
+ *
+ * To get roam scan channel list This is a synchronous call
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_get_roam_scan_channel_list(tHalHandle hHal,
+			uint8_t *pChannelList, uint8_t *pNumChannels,
+			uint8_t sessionId)
+{
+	int i = 0;
+	uint8_t *pOutPtr = pChannelList;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+	if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN,
+			FL("Roam Scan channel list is NOT yet initialized"));
+		*pNumChannels = 0;
+		sme_release_global_lock(&pMac->sme);
+		return status;
+	}
+
+	*pNumChannels = pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels;
+	for (i = 0; i < (*pNumChannels); i++)
+		pOutPtr[i] =
+			pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i];
+
+	pOutPtr[i] = '\0';
+	sme_release_global_lock(&pMac->sme);
+	return status;
+}
+
+/*
+ * sme_get_is_ese_feature_enabled() - get ESE feature enabled or not
+ *  This is a synchronuous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return true (1) - if the ESE feature is enabled
+ *	  false (0) - if feature is disabled (compile or runtime)
+ */
+bool sme_get_is_ese_feature_enabled(tHalHandle hHal)
+{
+#ifdef FEATURE_WLAN_ESE
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return csr_roam_is_ese_ini_feature_enabled(pMac);
+#else
+	return false;
+#endif
+}
+
+/*
+ * sme_get_wes_mode() - get WES Mode
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open
+ * Return uint8_t - WES Mode Enabled(1)/Disabled(0)
+ */
+bool sme_get_wes_mode(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.isWESModeEnabled;
+}
+
+/*
+ * sme_get_roam_scan_control() - get scan control
+ *  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return bool - Enabled(1)/Disabled(0)
+ */
+bool sme_get_roam_scan_control(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.nRoamScanControl;
+}
+
+/*
+ * sme_get_is_lfr_feature_enabled() - get LFR feature enabled or not
+ *  This is a synchronuous call
+ * hHal - The handle returned by mac_open.
+ * Return true (1) - if the feature is enabled
+ *	  false (0) - if feature is disabled (compile or runtime)
+ */
+bool sme_get_is_lfr_feature_enabled(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.isFastRoamIniFeatureEnabled;
+}
+
+/*
+ * sme_get_is_ft_feature_enabled() - get FT feature enabled or not
+ *  This is a synchronuous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return true (1) - if the feature is enabled
+ *	   false (0) - if feature is disabled (compile or runtime)
+ */
+bool sme_get_is_ft_feature_enabled(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.isFastTransitionEnabled;
+}
+
+/**
+ * sme_is_feature_supported_by_fw() - check if feature is supported by FW
+ * @feature: enum value of requested feature.
+ *
+ * Retrun: 1 if supported; 0 otherwise
+ */
+bool sme_is_feature_supported_by_fw(enum cap_bitmap feature)
+{
+	return IS_FEATURE_SUPPORTED_BY_FW(feature);
+}
+
+QDF_STATUS sme_get_link_speed(tHalHandle hHal, tSirLinkSpeedInfo *lsReq,
+			      void *plsContext,
+			      void (*pCallbackfn)(tSirLinkSpeedInfo *indParam,
+						  void *pContext))
+{
+
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac;
+	void *wma_handle;
+
+	if (!hHal || !pCallbackfn || !lsReq) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid parameter"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pMac = PMAC_STRUCT(hHal);
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("Failed to acquire global lock");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pMac->sme.pLinkSpeedCbContext = plsContext;
+	pMac->sme.pLinkSpeedIndCb = pCallbackfn;
+	status = wma_get_link_speed(wma_handle, lsReq);
+	sme_release_global_lock(&pMac->sme);
+	return status;
+}
+
+QDF_STATUS sme_get_peer_stats(tpAniSirGlobal mac,
+			      struct sir_peer_info_req req)
+{
+	QDF_STATUS qdf_status;
+	struct scheduler_msg message = {0};
+
+	qdf_status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		sme_debug("Failed to get Lock");
+		return qdf_status;
+	}
+	/* serialize the req through MC thread */
+	message.bodyptr = qdf_mem_malloc(sizeof(req));
+	if (!message.bodyptr) {
+		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;
+	message.reserved = 0;
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_WMA,
+					    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);
+		qdf_status = QDF_STATUS_E_FAILURE;
+	}
+	sme_release_global_lock(&mac->sme);
+	return qdf_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 = {0};
+
+	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 (!message.bodyptr) {
+			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;
+		message.reserved = 0;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    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 = {0};
+
+	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 (!message.bodyptr) {
+			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_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    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
+ */
+void sme_update_enable_ssr(tHalHandle hHal, bool enableSSR)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		sme_debug("SSR level is changed %d", enableSSR);
+		/* not serializing this message, as this is only going
+		 * to set a variable in WMA/WDI
+		 */
+		WMA_SetEnableSSR(enableSSR);
+		sme_release_global_lock(&pMac->sme);
+	}
+}
+
+/*convert the ini value to the ENUM used in csr and MAC for CB state*/
+ePhyChanBondState sme_get_cb_phy_state_from_cb_ini_value(uint32_t cb_ini_value)
+{
+	return csr_convert_cb_ini_value_to_phy_cb_state(cb_ini_value);
+}
+
+/*
+ * sme_set_curr_device_mode() - Sets the current operating device mode.
+ *
+ * hHal - The handle returned by mac_open.
+ * currDeviceMode - Current operating device mode.
+ */
+void sme_set_curr_device_mode(tHalHandle hHal,
+				enum QDF_OPMODE currDeviceMode)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	pMac->sme.currDeviceMode = currDeviceMode;
+}
+
+/*
+ * sme_handoff_request() - a wrapper function to Request a handoff from CSR.
+ *   This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open
+ * sessionId - Session Identifier
+ * pHandoffInfo - info provided by HDD with the handoff request (namely:
+ * BSSID, channel etc.)
+ * Return QDF_STATUS_SUCCESS - SME passed the request to CSR successfully.
+ *	   Other status means SME is failed to send the request.
+ */
+
+QDF_STATUS sme_handoff_request(tHalHandle hHal,
+			       uint8_t sessionId,
+			       tCsrHandoffRequest *pHandoffInfo)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: invoked", __func__);
+		status = csr_handoff_request(pMac, sessionId, pHandoffInfo);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * SME API to check if there is any infra station or
+ * P2P client is connected
+ */
+QDF_STATUS sme_is_sta_p2p_client_connected(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (csr_is_infra_connected(pMac))
+		return QDF_STATUS_SUCCESS;
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * sme_add_periodic_tx_ptrn() - Add Periodic TX Pattern
+ * @hal: global hal handle
+ * @addPeriodicTxPtrnParams: request message
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS
+sme_add_periodic_tx_ptrn(tHalHandle hal,
+			 struct sSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams)
+{
+	QDF_STATUS status   = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac  = PMAC_STRUCT(hal);
+	struct sSirAddPeriodicTxPtrn *req_msg;
+	struct scheduler_msg msg = {0};
+
+	SME_ENTER();
+
+	req_msg = qdf_mem_malloc(sizeof(*req_msg));
+	if (!req_msg)
+		return QDF_STATUS_E_NOMEM;
+
+	*req_msg = *addPeriodicTxPtrnParams;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("sme_acquire_global_lock failed!(status=%d)",
+			status);
+		qdf_mem_free(req_msg);
+		return status;
+	}
+
+	/* Serialize the req through MC thread */
+	msg.bodyptr = req_msg;
+	msg.type    = WMA_ADD_PERIODIC_TX_PTRN_IND;
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			 NO_SESSION, msg.type));
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("scheduler_post_msg failed!(err=%d)",
+			status);
+		qdf_mem_free(req_msg);
+	}
+	sme_release_global_lock(&mac->sme);
+	return status;
+}
+
+/**
+ * sme_del_periodic_tx_ptrn() - Delete Periodic TX Pattern
+ * @hal: global hal handle
+ * @delPeriodicTxPtrnParams: request message
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS
+sme_del_periodic_tx_ptrn(tHalHandle hal,
+			 struct sSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams)
+{
+	QDF_STATUS status    = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
+	struct sSirDelPeriodicTxPtrn *req_msg;
+	struct scheduler_msg msg = {0};
+
+	SME_ENTER();
+
+	req_msg = qdf_mem_malloc(sizeof(*req_msg));
+	if (!req_msg)
+		return QDF_STATUS_E_NOMEM;
+
+	*req_msg = *delPeriodicTxPtrnParams;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("sme_acquire_global_lock failed!(status=%d)",
+			status);
+		qdf_mem_free(req_msg);
+		return status;
+	}
+
+	/* Serialize the req through MC thread */
+	msg.bodyptr = req_msg;
+	msg.type    = WMA_DEL_PERIODIC_TX_PTRN_IND;
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			 NO_SESSION, msg.type));
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("scheduler_post_msg failed!(err=%d)",
+			status);
+		qdf_mem_free(req_msg);
+	}
+	sme_release_global_lock(&mac->sme);
+	return status;
+}
+
+#ifdef FEATURE_WLAN_RMC
+/*
+ * sme_enable_rmc() - enables RMC
+ * @hHal : Pointer to global HAL handle
+ * @sessionId : Session ID
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_enable_rmc(tHalHandle hHal, uint32_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	SME_ENTER();
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		message.bodyptr = NULL;
+		message.type = WMA_RMC_ENABLE_IND;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: failed to post message to WMA",
+				  __func__);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_disable_rmc() - disables RMC
+ * @hHal : Pointer to global HAL handle
+ * @sessionId : Session ID
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_disable_rmc(tHalHandle hHal, uint32_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	SME_ENTER();
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		message.bodyptr = NULL;
+		message.type = WMA_RMC_DISABLE_IND;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: failed to post message to WMA",
+				  __func__);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_send_rmc_action_period() - sends RMC action period param to target
+ * @hHal : Pointer to global HAL handle
+ * @sessionId : Session ID
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_send_rmc_action_period(tHalHandle hHal, uint32_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		message.bodyptr = NULL;
+		message.type = WMA_RMC_ACTION_PERIOD_IND;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: failed to post message to WMA",
+				  __func__);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+#endif /* FEATURE_WLAN_RMC */
+
+/*
+ * sme_request_ibss_peer_info() -  request ibss peer info
+ * @hHal : Pointer to global HAL handle
+ * @pUserData : Pointer to user data
+ * @peerInfoCbk : Peer info callback
+ * @allPeerInfoReqd : All peer info required or not
+ * @staIdx : sta index
+ *
+ * Return:  QDF_STATUS
+ */
+QDF_STATUS sme_request_ibss_peer_info(tHalHandle hHal, void *pUserData,
+				      pIbssPeerInfoCb peerInfoCbk,
+				      bool allPeerInfoReqd, uint8_t staIdx)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	tSirIbssGetPeerInfoReqParams *pIbssInfoReqParams;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		pMac->sme.peerInfoParams.peerInfoCbk = peerInfoCbk;
+		pMac->sme.peerInfoParams.pUserData = pUserData;
+
+		pIbssInfoReqParams = (tSirIbssGetPeerInfoReqParams *)
+			qdf_mem_malloc(sizeof(tSirIbssGetPeerInfoReqParams));
+		if (!pIbssInfoReqParams) {
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+		pIbssInfoReqParams->allPeerInfoReqd = allPeerInfoReqd;
+		pIbssInfoReqParams->staIdx = staIdx;
+
+		message.type = WMA_GET_IBSS_PEER_INFO_REQ;
+		message.bodyptr = pIbssInfoReqParams;
+		message.reserved = 0;
+
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (QDF_STATUS_SUCCESS != qdf_status) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Post WMA_GET_IBSS_PEER_INFO_REQ MSG failed",
+				  __func__);
+			qdf_mem_free(pIbssInfoReqParams);
+			qdf_status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return qdf_status;
+}
+
+/*
+ * sme_send_cesium_enable_ind() -
+ *  Used to send proprietary cesium enable indication to fw
+ *
+ * hHal
+ * sessionId
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_send_cesium_enable_ind(tHalHandle hHal, uint32_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		message.bodyptr = NULL;
+		message.type = WMA_IBSS_CESIUM_ENABLE_IND;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: failed to post message to WMA",
+				  __func__);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_set_wlm_latency_level(tHalHandle hal, uint16_t session_id,
+				     uint16_t latency_level)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct wlm_latency_level_param params;
+	void *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma)
+		return QDF_STATUS_E_FAILURE;
+
+	if (!mac_ctx->roam.configParam.wlm_latency_enable) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: WLM latency level setting is disabled",
+			   __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (!wma) {
+		sme_err("wma is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	params.wlm_latency_level = latency_level;
+	params.wlm_latency_flags =
+		mac_ctx->roam.configParam.wlm_latency_flags[latency_level];
+	params.vdev_id = session_id;
+
+	status = wma_set_wlm_latency_level(wma, &params);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: failed to set latency level",
+			  __func__);
+
+	return status;
+}
+
+void sme_get_command_q_status(tHalHandle hHal)
+{
+	tSmeCmd *pTempCmd = NULL;
+	tListElem *pEntry;
+	tpAniSirGlobal pMac;
+
+	if (NULL != hHal) {
+		pMac = PMAC_STRUCT(hHal);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid hHal pointer", __func__);
+		return;
+	}
+	pEntry = csr_nonscan_active_ll_peek_head(pMac, LL_ACCESS_LOCK);
+	if (pEntry)
+		pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+
+	sme_err("WLAN_BUG_RCA: Currently smeCmdActiveList has command (0x%X)",
+		(pTempCmd) ? pTempCmd->command : eSmeNoCommand);
+	if (pTempCmd) {
+		if (eSmeCsrCommandMask & pTempCmd->command)
+			/* CSR command is stuck. See what the reason code is
+			 * for that command
+			 */
+			dump_csr_command_info(pMac, pTempCmd);
+	} /* if(pTempCmd) */
+
+	sme_err("Currently smeCmdPendingList has %d commands",
+		csr_nonscan_pending_ll_count(pMac));
+
+}
+
+#ifdef WLAN_FEATURE_DSRC
+/**
+ * copy_sir_ocb_config() - Performs deep copy of an OCB configuration
+ * @src: the source configuration
+ *
+ * Return: pointer to the copied OCB configuration
+ */
+static struct sir_ocb_config *sme_copy_sir_ocb_config(
+	struct sir_ocb_config *src)
+{
+	struct sir_ocb_config *dst;
+	uint32_t length;
+	void *cursor;
+
+	length = sizeof(*src) +
+		src->channel_count * sizeof(*src->channels) +
+		src->schedule_size * sizeof(*src->schedule) +
+		src->dcc_ndl_chan_list_len +
+		src->dcc_ndl_active_state_list_len;
+
+	dst = qdf_mem_malloc(length);
+	if (!dst)
+		return NULL;
+
+	*dst = *src;
+
+	cursor = dst;
+	cursor += sizeof(*dst);
+	dst->channels = cursor;
+	cursor += src->channel_count * sizeof(*src->channels);
+	qdf_mem_copy(dst->channels, src->channels,
+		     src->channel_count * sizeof(*src->channels));
+	dst->schedule = cursor;
+	cursor += src->schedule_size * sizeof(*src->schedule);
+	qdf_mem_copy(dst->schedule, src->schedule,
+		     src->schedule_size * sizeof(*src->schedule));
+	dst->dcc_ndl_chan_list = cursor;
+	cursor += src->dcc_ndl_chan_list_len;
+	qdf_mem_copy(dst->dcc_ndl_chan_list, src->dcc_ndl_chan_list,
+		     src->dcc_ndl_chan_list_len);
+	dst->dcc_ndl_active_state_list = cursor;
+	cursor += src->dcc_ndl_active_state_list_len;
+	qdf_mem_copy(dst->dcc_ndl_active_state_list,
+		     src->dcc_ndl_active_state_list,
+		     src->dcc_ndl_active_state_list_len);
+	return dst;
+}
+
+/**
+ * sme_ocb_set_config() - Set the OCB configuration
+ * @hHal: reference to the HAL
+ * @context: the context of the call
+ * @callback: the callback to hdd
+ * @config: the OCB configuration
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS sme_ocb_set_config(tHalHandle hHal, void *context,
+			      ocb_callback callback,
+			      struct sir_ocb_config *config)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg msg = {0};
+	struct sir_ocb_config *msg_body;
+
+	/* Lock the SME structure */
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	/*
+	 * Check if there is a pending request and return an error if one
+	 * exists
+	 */
+	if (pMac->sme.ocb_set_config_callback) {
+		status = QDF_STATUS_E_BUSY;
+		goto end;
+	}
+
+	msg_body = sme_copy_sir_ocb_config(config);
+
+	if (!msg_body) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+
+	msg.type = WMA_OCB_SET_CONFIG_CMD;
+	msg.bodyptr = msg_body;
+
+	/* Set the request callback and context */
+	pMac->sme.ocb_set_config_callback = callback;
+	pMac->sme.ocb_set_config_context = context;
+
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+		      FL("Error posting message to WDA: %d"), status);
+		pMac->sme.ocb_set_config_callback = callback;
+		pMac->sme.ocb_set_config_context = context;
+		qdf_mem_free(msg_body);
+		goto end;
+	}
+
+end:
+	sme_release_global_lock(&pMac->sme);
+
+	return status;
+}
+
+/**
+ * sme_ocb_set_utc_time() - Set the OCB UTC time
+ * @hHal: reference to the HAL
+ * @utc: the UTC time struct
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS sme_ocb_set_utc_time(tHalHandle hHal, struct sir_ocb_utc *utc)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg msg = {0};
+	struct sir_ocb_utc *sme_utc;
+
+	/* Lock the SME structure */
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	sme_utc = qdf_mem_malloc(sizeof(*sme_utc));
+	if (!sme_utc) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+	*sme_utc = *utc;
+
+	msg.type = WMA_OCB_SET_UTC_TIME_CMD;
+	msg.reserved = 0;
+	msg.bodyptr = sme_utc;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Not able to post message to WDA"));
+		qdf_mem_free(utc);
+		goto end;
+	}
+
+end:
+	sme_release_global_lock(&pMac->sme);
+
+	return status;
+}
+
+/**
+ * sme_ocb_start_timing_advert() - Start sending timing advert frames
+ * @hHal: reference to the HAL
+ * @timing_advert: the timing advertisement struct
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS sme_ocb_start_timing_advert(tHalHandle hHal,
+	struct sir_ocb_timing_advert *timing_advert)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg msg = {0};
+	void *buf;
+	struct sir_ocb_timing_advert *sme_timing_advert;
+
+	/* Lock the SME structure */
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	buf = qdf_mem_malloc(sizeof(*sme_timing_advert) +
+			     timing_advert->template_length);
+	if (!buf) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+
+	sme_timing_advert = (struct sir_ocb_timing_advert *)buf;
+	*sme_timing_advert = *timing_advert;
+	sme_timing_advert->template_value = buf + sizeof(*sme_timing_advert);
+	qdf_mem_copy(sme_timing_advert->template_value,
+	timing_advert->template_value, timing_advert->template_length);
+
+	msg.type = WMA_OCB_START_TIMING_ADVERT_CMD;
+	msg.reserved = 0;
+	msg.bodyptr = buf;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Not able to post msg to WDA"));
+		goto end;
+	}
+
+end:
+	sme_release_global_lock(&pMac->sme);
+
+	return status;
+}
+
+/**
+ * sme_ocb_stop_timing_advert() - Stop sending timing advert frames on a channel
+ * @hHal: reference to the HAL
+ * @timing_advert: the timing advertisement struct
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS sme_ocb_stop_timing_advert(tHalHandle hHal,
+	struct sir_ocb_timing_advert *timing_advert)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg msg = {0};
+	struct sir_ocb_timing_advert *sme_timing_advert;
+
+	/* Lock the SME structure */
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	sme_timing_advert = qdf_mem_malloc(sizeof(*timing_advert));
+	if (!sme_timing_advert) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+	*sme_timing_advert = *timing_advert;
+
+	msg.type = WMA_OCB_STOP_TIMING_ADVERT_CMD;
+	msg.reserved = 0;
+	msg.bodyptr = sme_timing_advert;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Not able to post msg to WDA"));
+		goto end;
+	}
+
+end:
+	sme_release_global_lock(&pMac->sme);
+
+	return status;
+}
+
+/**
+ * sme_ocb_gen_timing_advert_frame() - generate TA frame and populate the buffer
+ * @hal_handle: reference to the HAL
+ * @self_addr: the self MAC address
+ * @buf: the buffer that will contain the frame
+ * @timestamp_offset: return for the offset of the timestamp field
+ * @time_value_offset: return for the time_value field in the TA IE
+ *
+ * Return: the length of the buffer.
+ */
+int sme_ocb_gen_timing_advert_frame(tHalHandle hal_handle,
+				    tSirMacAddr self_addr, uint8_t **buf,
+				    uint32_t *timestamp_offset,
+				    uint32_t *time_value_offset)
+{
+	int template_length;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
+
+	template_length = sch_gen_timing_advert_frame(mac_ctx, self_addr, buf,
+						  timestamp_offset,
+						  time_value_offset);
+	return template_length;
+}
+/**
+ * sme_ocb_get_tsf_timer() - Get the TSF timer value
+ * @hHal: reference to the HAL
+ * @context: the context of the call
+ * @callback: the callback to hdd
+ * @request: the TSF timer request
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS sme_ocb_get_tsf_timer(tHalHandle hHal, void *context,
+				 ocb_callback callback,
+				 struct sir_ocb_get_tsf_timer *request)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg msg = {0};
+	struct sir_ocb_get_tsf_timer *msg_body;
+
+	/* Lock the SME structure */
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	/* Allocate memory for the WMI request, and copy the parameter */
+	msg_body = qdf_mem_malloc(sizeof(*msg_body));
+	if (!msg_body) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+	*msg_body = *request;
+
+	msg.type = WMA_OCB_GET_TSF_TIMER_CMD;
+	msg.bodyptr = msg_body;
+
+	/* Set the request callback and the context */
+	pMac->sme.ocb_get_tsf_timer_callback = callback;
+	pMac->sme.ocb_get_tsf_timer_context = context;
+
+	/* Post the message to WDA */
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Error posting message to WDA: %d"), status);
+		pMac->sme.ocb_get_tsf_timer_callback = NULL;
+		pMac->sme.ocb_get_tsf_timer_context = NULL;
+		qdf_mem_free(msg_body);
+		goto end;
+	}
+
+end:
+	sme_release_global_lock(&pMac->sme);
+
+	return status;
+}
+
+/**
+ * sme_dcc_get_stats() - Get the DCC stats
+ * @hHal: reference to the HAL
+ * @context: the context of the call
+ * @callback: the callback to hdd
+ * @request: the get DCC stats request
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS sme_dcc_get_stats(tHalHandle hHal, void *context,
+			     ocb_callback callback,
+			     struct sir_dcc_get_stats *request)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg msg = {0};
+	struct sir_dcc_get_stats *msg_body;
+
+	/* Lock the SME structure */
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	/* Allocate memory for the WMI request, and copy the parameter */
+	msg_body = qdf_mem_malloc(sizeof(*msg_body) +
+				  request->request_array_len);
+	if (!msg_body) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+	*msg_body = *request;
+	msg_body->request_array = (void *)msg_body + sizeof(*msg_body);
+	qdf_mem_copy(msg_body->request_array, request->request_array,
+		     request->request_array_len);
+
+	msg.type = WMA_DCC_GET_STATS_CMD;
+	msg.bodyptr = msg_body;
+
+	/* Set the request callback and context */
+	pMac->sme.dcc_get_stats_callback = callback;
+	pMac->sme.dcc_get_stats_context = context;
+
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Error posting message to WDA: %d"), status);
+		pMac->sme.dcc_get_stats_callback = callback;
+		pMac->sme.dcc_get_stats_context = context;
+		qdf_mem_free(msg_body);
+		goto end;
+	}
+
+end:
+	sme_release_global_lock(&pMac->sme);
+
+	return status;
+}
+
+/**
+ * sme_dcc_clear_stats() - Clear the DCC stats
+ * @hHal: reference to the HAL
+ * @vdev_id: vdev id for OCB interface
+ * @dcc_stats_bitmap: the entries in the stats to clear
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS sme_dcc_clear_stats(tHalHandle hHal, uint32_t vdev_id,
+			       uint32_t dcc_stats_bitmap)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg msg = {0};
+	struct sir_dcc_clear_stats *request;
+
+	/* Lock the SME structure */
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	request = qdf_mem_malloc(sizeof(struct sir_dcc_clear_stats));
+	if (!request) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+
+	request->vdev_id = vdev_id;
+	request->dcc_stats_bitmap = dcc_stats_bitmap;
+
+	msg.type = WMA_DCC_CLEAR_STATS_CMD;
+	msg.bodyptr = request;
+
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Not able to post msg to WDA"));
+		qdf_mem_free(request);
+		goto end;
+	}
+
+end:
+	sme_release_global_lock(&pMac->sme);
+
+	return status;
+}
+
+/**
+ * sme_dcc_update_ndl() - Update the DCC settings
+ * @hHal: reference to the HAL
+ * @context: the context of the call
+ * @callback: the callback to hdd
+ * @request: the update DCC request
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS sme_dcc_update_ndl(tHalHandle hHal, void *context,
+			      ocb_callback callback,
+			      struct sir_dcc_update_ndl *request)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg msg = {0};
+	struct sir_dcc_update_ndl *msg_body;
+
+	/* Lock the SME structure */
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	/* Allocate memory for the WMI request, and copy the parameter */
+	msg_body = qdf_mem_malloc(sizeof(*msg_body) +
+				  request->dcc_ndl_chan_list_len +
+				  request->dcc_ndl_active_state_list_len);
+	if (!msg_body) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+
+	*msg_body = *request;
+
+	msg_body->dcc_ndl_chan_list = (void *)msg_body + sizeof(*msg_body);
+	msg_body->dcc_ndl_active_state_list = msg_body->dcc_ndl_chan_list +
+		request->dcc_ndl_chan_list_len;
+	qdf_mem_copy(msg_body->dcc_ndl_chan_list, request->dcc_ndl_chan_list,
+		     request->dcc_ndl_active_state_list_len);
+	qdf_mem_copy(msg_body->dcc_ndl_active_state_list,
+		     request->dcc_ndl_active_state_list,
+		     request->dcc_ndl_active_state_list_len);
+
+	msg.type = WMA_DCC_UPDATE_NDL_CMD;
+	msg.bodyptr = msg_body;
+
+	/* Set the request callback and the context */
+	pMac->sme.dcc_update_ndl_callback = callback;
+	pMac->sme.dcc_update_ndl_context = context;
+
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Error posting message to WDA: %d"), status);
+		pMac->sme.dcc_update_ndl_callback = NULL;
+		pMac->sme.dcc_update_ndl_context = NULL;
+		qdf_mem_free(msg_body);
+		goto end;
+	}
+
+end:
+	sme_release_global_lock(&pMac->sme);
+
+	return status;
+}
+
+/**
+ * sme_register_for_dcc_stats_event() - Register for the periodic DCC stats
+ *                                      event
+ * @hHal: reference to the HAL
+ * @context: the context of the call
+ * @callback: the callback to hdd
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS sme_register_for_dcc_stats_event(tHalHandle hHal, void *context,
+					    ocb_callback callback)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	pMac->sme.dcc_stats_event_callback = callback;
+	pMac->sme.dcc_stats_event_context = context;
+	sme_release_global_lock(&pMac->sme);
+
+	return 0;
+}
+
+/**
+ * sme_deregister_for_dcc_stats_event() - De-Register for the periodic DCC stats
+ *					  event
+ * @h_hal: Hal Handle
+ *
+ * This function de-registers the DCC perioc stats callback
+ *
+ * Return: QDF_STATUS Enumeration
+ */
+QDF_STATUS sme_deregister_for_dcc_stats_event(tHalHandle h_hal)
+{
+	tpAniSirGlobal mac;
+	QDF_STATUS status;
+
+	if (!h_hal) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("h_hal is not valid"));
+		return QDF_STATUS_E_INVAL;
+	}
+	mac = PMAC_STRUCT(h_hal);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Failed to acquire global lock"));
+		return status;
+	}
+	mac->sme.dcc_stats_event_callback = NULL;
+	mac->sme.dcc_stats_event_context = NULL;
+	sme_release_global_lock(&mac->sme);
+
+	return status;
+}
+#else
+void sme_set_etsi13_srd_ch_in_master_mode(tHalHandle hal,
+					  bool etsi13_srd_chan_support)
+{
+	tpAniSirGlobal mac;
+
+	mac = PMAC_STRUCT(hal);
+	mac->sap.enable_etsi13_srd_chan_support = etsi13_srd_chan_support;
+	sme_debug("srd_ch_support %d", mac->sap.enable_etsi13_srd_chan_support);
+}
+#endif
+
+void sme_get_recovery_stats(tHalHandle hHal)
+{
+	uint8_t i;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+		  "Self Recovery Stats");
+	for (i = 0; i < MAX_ACTIVE_CMD_STATS; i++) {
+		if (eSmeNoCommand !=
+		    g_self_recovery_stats.activeCmdStats[i].command) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "timestamp %llu: command 0x%0X: reason %d: session %d",
+				  g_self_recovery_stats.activeCmdStats[i].
+				  timestamp,
+				g_self_recovery_stats.activeCmdStats[i].command,
+				 g_self_recovery_stats.activeCmdStats[i].reason,
+				  g_self_recovery_stats.activeCmdStats[i].
+				  sessionId);
+		}
+	}
+}
+
+QDF_STATUS sme_notify_modem_power_state(tHalHandle hHal, uint32_t value)
+{
+	struct scheduler_msg msg = {0};
+	tpSirModemPowerStateInd request_buf;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (NULL == pMac)
+		return QDF_STATUS_E_FAILURE;
+
+	request_buf = qdf_mem_malloc(sizeof(tSirModemPowerStateInd));
+	if (!request_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	request_buf->param = value;
+
+	msg.type = WMA_MODEM_POWER_STATE_IND;
+	msg.reserved = 0;
+	msg.bodyptr = request_buf;
+	if (!QDF_IS_STATUS_SUCCESS
+		    (scheduler_post_message(QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_WMA, &msg))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Not able to post WMA_MODEM_POWER_STATE_IND message to WMA",
+			__func__);
+		qdf_mem_free(request_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef QCA_HT_2040_COEX
+QDF_STATUS sme_notify_ht2040_mode(tHalHandle hHal, uint16_t staId,
+				  struct qdf_mac_addr macAddrSTA,
+				  uint8_t sessionId,
+				  uint8_t channel_type)
+{
+	struct scheduler_msg msg = {0};
+	tUpdateVHTOpMode *pHtOpMode = NULL;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (NULL == pMac)
+		return QDF_STATUS_E_FAILURE;
+
+	pHtOpMode = qdf_mem_malloc(sizeof(tUpdateVHTOpMode));
+	if (!pHtOpMode)
+		return QDF_STATUS_E_NOMEM;
+
+	switch (channel_type) {
+	case eHT_CHAN_HT20:
+		pHtOpMode->opMode = eHT_CHANNEL_WIDTH_20MHZ;
+		break;
+
+	case eHT_CHAN_HT40MINUS:
+	case eHT_CHAN_HT40PLUS:
+		pHtOpMode->opMode = eHT_CHANNEL_WIDTH_40MHZ;
+		break;
+
+	default:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid OP mode", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pHtOpMode->staId = staId,
+	qdf_mem_copy(pHtOpMode->peer_mac, macAddrSTA.bytes,
+		     sizeof(tSirMacAddr));
+	pHtOpMode->smesessionId = sessionId;
+
+	msg.type = WMA_UPDATE_OP_MODE;
+	msg.reserved = 0;
+	msg.bodyptr = pHtOpMode;
+	if (!QDF_IS_STATUS_SUCCESS
+		    (scheduler_post_message(QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_WMA, &msg))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Not able to post WMA_UPDATE_OP_MODE message to WMA",
+			__func__);
+		qdf_mem_free(pHtOpMode);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: Notified FW about OP mode: %d for staId=%d",
+		  __func__, pHtOpMode->opMode, staId);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_set_ht2040_mode() -
+ *  To update HT Operation beacon IE.
+ *
+ * Return QDF_STATUS  SUCCESS
+ *			FAILURE or RESOURCES
+ *			The API finished and failed.
+ */
+QDF_STATUS sme_set_ht2040_mode(tHalHandle hHal, uint8_t sessionId,
+			       uint8_t channel_type, bool obssEnabled)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	ePhyChanBondState cbMode;
+	struct csr_roam_session *session = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		sme_err("Session not valid for session id %d", sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+	session = CSR_GET_SESSION(pMac, sessionId);
+	sme_debug("Update HT operation beacon IE, channel_type=%d cur cbmode %d",
+		channel_type, session->bssParams.cbMode);
+
+	switch (channel_type) {
+	case eHT_CHAN_HT20:
+		if (!session->bssParams.cbMode)
+			return QDF_STATUS_SUCCESS;
+		cbMode = PHY_SINGLE_CHANNEL_CENTERED;
+		break;
+	case eHT_CHAN_HT40MINUS:
+		if (session->bssParams.cbMode)
+			return QDF_STATUS_SUCCESS;
+		cbMode = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+		break;
+	case eHT_CHAN_HT40PLUS:
+		if (session->bssParams.cbMode)
+			return QDF_STATUS_SUCCESS;
+		cbMode = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+		break;
+	default:
+		sme_err("Error!!! Invalid HT20/40 mode !");
+		return QDF_STATUS_E_FAILURE;
+	}
+	session->bssParams.cbMode = cbMode;
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_set_ht2040_mode(pMac, sessionId,
+					     cbMode, obssEnabled);
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+#endif
+
+/*
+ * SME API to enable/disable idle mode powersave
+ * This should be called only if powersave offload
+ * is enabled
+ */
+QDF_STATUS sme_set_idle_powersave_config(bool value)
+{
+	void *wmaContext = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wmaContext) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: wmaContext is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  " Idle Ps Set Value %d", value);
+
+	if (QDF_STATUS_SUCCESS != wma_set_idle_ps_config(wmaContext, value)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  " Failed to Set Idle Ps Value %d", value);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+int16_t sme_get_ht_config(tHalHandle hHal, uint8_t session_id,
+			uint16_t ht_capab)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, session_id);
+
+	if (NULL == pSession) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: pSession is NULL", __func__);
+		return -EIO;
+	}
+	switch (ht_capab) {
+	case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
+		return pSession->htConfig.ht_rx_ldpc;
+	case WNI_CFG_HT_CAP_INFO_TX_STBC:
+		return pSession->htConfig.ht_tx_stbc;
+	case WNI_CFG_HT_CAP_INFO_RX_STBC:
+		return pSession->htConfig.ht_rx_stbc;
+	case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
+		return pSession->htConfig.ht_sgi20;
+	case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
+		return pSession->htConfig.ht_sgi40;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "invalid ht capability");
+		return -EIO;
+	}
+}
+
+int sme_update_ht_config(tHalHandle hHal, uint8_t sessionId, uint16_t htCapab,
+			 int value)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (NULL == pSession) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: pSession is NULL", __func__);
+		return -EIO;
+	}
+
+	if (QDF_STATUS_SUCCESS != wma_set_htconfig(sessionId, htCapab, value)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "Failed to set ht capability in target");
+		return -EIO;
+	}
+
+	switch (htCapab) {
+	case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
+		pSession->htConfig.ht_rx_ldpc = value;
+		pMac->roam.configParam.rx_ldpc_enable = value;
+		break;
+	case WNI_CFG_HT_CAP_INFO_TX_STBC:
+		pSession->htConfig.ht_tx_stbc = value;
+		break;
+	case WNI_CFG_HT_CAP_INFO_RX_STBC:
+		pSession->htConfig.ht_rx_stbc = value;
+		break;
+	case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
+		value = value ? 1 : 0; /* HT SGI can be only 1 or 0 */
+		pSession->htConfig.ht_sgi20 = value;
+		break;
+	case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
+		value = value ? 1 : 0; /* HT SGI can be only 1 or 0 */
+		pSession->htConfig.ht_sgi40 = value;
+		break;
+	}
+
+	csr_roam_update_config(pMac, sessionId, htCapab, value);
+	return 0;
+}
+
+int sme_set_addba_accept(tHalHandle hal, uint8_t session_id, int value)
+{
+	struct sme_addba_accept *addba_accept;
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+
+	addba_accept = qdf_mem_malloc(sizeof(*addba_accept));
+	if (!addba_accept)
+		return -EIO;
+
+	addba_accept->session_id = session_id;
+	addba_accept->addba_accept = value;
+	qdf_mem_zero(&msg, sizeof(msg));
+	msg.type = eWNI_SME_SET_ADDBA_ACCEPT;
+	msg.reserved = 0;
+	msg.bodyptr = addba_accept;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_PE, &msg);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("Not able to post addba reject");
+		qdf_mem_free(addba_accept);
+		return -EIO;
+	}
+	return 0;
+}
+
+int sme_set_ba_buff_size(tHalHandle hal, uint8_t session_id,
+		uint16_t buff_size)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	if (!buff_size) {
+		sme_err("invalid buff size %d", buff_size);
+		return -EINVAL;
+	}
+	mac_ctx->usr_cfg_ba_buff_size = buff_size;
+	sme_debug("addba buff size is set to %d",
+			mac_ctx->usr_cfg_ba_buff_size);
+
+	return 0;
+}
+
+#define DEFAULT_BA_BUFF_SIZE 64
+int sme_send_addba_req(tHalHandle hal, uint8_t session_id, uint8_t tid,
+		uint16_t buff_size)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint16_t ba_buff = 0;
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+	struct send_add_ba_req *send_ba_req;
+	struct csr_roam_session *csr_session = NULL;
+
+	if (!csr_is_conn_state_connected_infra(mac_ctx, session_id)) {
+		sme_err("STA not infra/connected state session_id: %d",
+				session_id);
+		return -EINVAL;
+	}
+	csr_session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (!csr_session) {
+		sme_err("CSR session is NULL");
+		return -EINVAL;
+	}
+	send_ba_req = qdf_mem_malloc(sizeof(*send_ba_req));
+	if (!send_ba_req)
+		return -EIO;
+
+	qdf_mem_copy(send_ba_req->mac_addr,
+			csr_session->connectedProfile.bssid.bytes,
+			QDF_MAC_ADDR_SIZE);
+	ba_buff = buff_size;
+	if (!buff_size) {
+		if (mac_ctx->usr_cfg_ba_buff_size)
+			ba_buff = mac_ctx->usr_cfg_ba_buff_size;
+		else
+			ba_buff = DEFAULT_BA_BUFF_SIZE;
+	}
+	send_ba_req->param.vdev_id = session_id;
+	send_ba_req->param.tidno = tid;
+	send_ba_req->param.buffersize = ba_buff;
+	msg.type = WMA_SEND_ADDBA_REQ;
+	msg.bodyptr = send_ba_req;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("Failed to post WMA_SEND_ADDBA_REQ");
+		qdf_mem_free(send_ba_req);
+		return -EIO;
+	}
+	sme_debug("ADDBA_REQ sent to FW: tid %d buff_size %d", tid, ba_buff);
+
+	return 0;
+}
+
+int sme_set_no_ack_policy(tHalHandle hal, uint8_t session_id,
+		uint8_t val, uint8_t ac)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint8_t i, set_val;
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+
+	if (ac > MAX_NUM_AC) {
+		sme_err("invalid ac val %d", ac);
+		return -EINVAL;
+	}
+	if (val)
+		set_val = 1;
+	else
+		set_val = 0;
+	if (ac == MAX_NUM_AC) {
+		for (i = 0; i < ac; i++)
+			mac_ctx->no_ack_policy_cfg[i] = set_val;
+	} else {
+		mac_ctx->no_ack_policy_cfg[ac] = set_val;
+	}
+	sme_debug("no ack is set to %d for ac %d", set_val, ac);
+	qdf_mem_zero(&msg, sizeof(msg));
+	msg.type = eWNI_SME_UPDATE_EDCA_PROFILE;
+	msg.reserved = 0;
+	msg.bodyval = session_id;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_PE, &msg);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("Not able to post update edca profile");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int sme_set_auto_rate_he_ltf(tHalHandle hal, uint8_t session_id,
+		uint8_t cfg_val)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint32_t set_val;
+	uint32_t bit_mask = 0;
+	int status;
+
+	if (cfg_val > QCA_WLAN_HE_LTF_4X) {
+		sme_err("invalid HE LTF cfg %d", cfg_val);
+		return -EINVAL;
+	}
+
+	/*set the corresponding HE LTF cfg BIT*/
+	if (cfg_val == QCA_WLAN_HE_LTF_AUTO)
+		bit_mask = HE_LTF_ALL;
+	else
+		bit_mask = (1 << (cfg_val - 1));
+
+	set_val = mac_ctx->he_sgi_ltf_cfg_bit_mask;
+
+	SET_AUTO_RATE_HE_LTF_VAL(set_val, bit_mask);
+
+	mac_ctx->he_sgi_ltf_cfg_bit_mask = set_val;
+	status = wma_cli_set_command(session_id,
+			WMI_VDEV_PARAM_AUTORATE_MISC_CFG,
+			set_val, VDEV_CMD);
+	if (status) {
+		sme_err("failed to set he_ltf_sgi");
+		return status;
+	}
+
+	sme_debug("HE SGI_LTF is set to 0x%08X",
+			mac_ctx->he_sgi_ltf_cfg_bit_mask);
+
+	return 0;
+}
+
+int sme_set_auto_rate_he_sgi(tHalHandle hal, uint8_t session_id,
+		uint8_t cfg_val)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint32_t set_val;
+	uint32_t sgi_bit_mask = 0;
+	int status;
+
+	if ((cfg_val > AUTO_RATE_GI_3200NS) ||
+			(cfg_val < AUTO_RATE_GI_400NS)) {
+		sme_err("invalid auto rate GI cfg %d", cfg_val);
+		return -EINVAL;
+	}
+
+	sgi_bit_mask = (1 << cfg_val);
+
+	set_val = mac_ctx->he_sgi_ltf_cfg_bit_mask;
+	SET_AUTO_RATE_SGI_VAL(set_val, sgi_bit_mask);
+
+	mac_ctx->he_sgi_ltf_cfg_bit_mask = set_val;
+	status = wma_cli_set_command(session_id,
+				     WMI_VDEV_PARAM_AUTORATE_MISC_CFG,
+				     set_val, VDEV_CMD);
+	if (status) {
+		sme_err("failed to set he_ltf_sgi");
+		return status;
+	}
+
+	sme_debug("auto rate HE SGI_LTF is set to 0x%08X",
+			mac_ctx->he_sgi_ltf_cfg_bit_mask);
+
+	return 0;
+}
+
+#define HT20_SHORT_GI_MCS7_RATE 722
+/*
+ * sme_send_rate_update_ind() -
+ *  API to Update rate
+ *
+ * hHal - The handle returned by mac_open
+ * rateUpdateParams - Pointer to rate update params
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_send_rate_update_ind(tHalHandle hHal,
+				    tSirRateUpdateInd *rateUpdateParams)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+	tSirRateUpdateInd *rate_upd = qdf_mem_malloc(sizeof(tSirRateUpdateInd));
+
+	if (!rate_upd)
+		return QDF_STATUS_E_FAILURE;
+
+	*rate_upd = *rateUpdateParams;
+
+	if (rate_upd->mcastDataRate24GHz == HT20_SHORT_GI_MCS7_RATE)
+		rate_upd->mcastDataRate24GHzTxFlag =
+			TX_RATE_HT20 | TX_RATE_SGI;
+	else if (rate_upd->reliableMcastDataRate ==
+		 HT20_SHORT_GI_MCS7_RATE)
+		rate_upd->reliableMcastDataRateTxFlag =
+			TX_RATE_HT20 | TX_RATE_SGI;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		msg.type = WMA_RATE_UPDATE_IND;
+		msg.bodyptr = rate_upd;
+		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+				 NO_SESSION, msg.type));
+		if (!QDF_IS_STATUS_SUCCESS
+			    (scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &msg))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Not able to post WMA_RATE_UPDATE_IND to WMA!",
+				  __func__);
+
+			sme_release_global_lock(&pMac->sme);
+			qdf_mem_free(rate_upd);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		sme_release_global_lock(&pMac->sme);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	return status;
+}
+
+/**
+ * sme_update_access_policy_vendor_ie() - update vendor ie and access policy.
+ * @hal: Pointer to the mac context
+ * @session_id: sme session id
+ * @vendor_ie: vendor ie
+ * @access_policy: vendor ie access policy
+ *
+ * This function updates the vendor ie and access policy to lim.
+ *
+ * Return: success or failure.
+ */
+QDF_STATUS sme_update_access_policy_vendor_ie(tHalHandle hal,
+		uint8_t session_id, uint8_t *vendor_ie, int access_policy)
+{
+	struct sme_update_access_policy_vendor_ie *msg;
+	uint16_t msg_len;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	msg_len  = sizeof(*msg);
+
+	msg = qdf_mem_malloc(msg_len);
+	if (!msg) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	msg->msg_type = (uint16_t)eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE;
+	msg->length = (uint16_t)msg_len;
+
+	qdf_mem_copy(&msg->ie[0], vendor_ie, sizeof(msg->ie));
+
+	msg->sme_session_id = session_id;
+	msg->access_policy = access_policy;
+
+	sme_debug("sme_session_id: %hu, access_policy: %d", session_id,
+		  access_policy);
+
+	status = umac_send_mb_message_to_mac(msg);
+
+	return status;
+}
+
+/**
+ * sme_update_short_retry_limit_threshold() - update short frame retry limit TH
+ * @hal: Handle returned by mac_open
+ * @session_id: Session ID on which short frame retry limit needs to be
+ * updated to FW
+ * @short_limit_count_th: Retry count TH to retry short frame.
+ *
+ * This function is used to configure count to retry short frame.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_update_short_retry_limit_threshold(tHalHandle hal_handle,
+		struct sme_short_retry_limit *short_retry_limit_th)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct sme_short_retry_limit *srl;
+	struct scheduler_msg msg = {0};
+
+	srl = qdf_mem_malloc(sizeof(*srl));
+	if (!srl)
+		return QDF_STATUS_E_FAILURE;
+
+	sme_debug("session_id %d short retry limit count: %d",
+		short_retry_limit_th->session_id,
+		short_retry_limit_th->short_retry_limit);
+
+	srl->session_id = short_retry_limit_th->session_id;
+	srl->short_retry_limit = short_retry_limit_th->short_retry_limit;
+
+	qdf_mem_zero(&msg, sizeof(msg));
+	msg.type = SIR_HAL_SHORT_RETRY_LIMIT_CNT;
+	msg.reserved = 0;
+	msg.bodyptr = srl;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("Not able to post short retry limit count to WDA"));
+			qdf_mem_free(srl);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+/**
+ * sme_update_long_retry_limit_threshold() - update long retry limit TH
+ * @hal: Handle returned by mac_open
+ * @session_id: Session ID on which long frames retry TH needs to be updated
+ * to FW
+ * @long_limit_count_th: Retry count to retry long frame.
+ *
+ * This function is used to configure TH to retry long frame.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_update_long_retry_limit_threshold(tHalHandle hal_handle,
+		struct sme_long_retry_limit  *long_retry_limit_th)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct sme_long_retry_limit *lrl;
+	struct scheduler_msg msg = {0};
+
+	lrl = qdf_mem_malloc(sizeof(*lrl));
+	if (!lrl)
+		return QDF_STATUS_E_FAILURE;
+
+	sme_debug("session_id %d long retry limit count: %d",
+		long_retry_limit_th->session_id,
+		long_retry_limit_th->long_retry_limit);
+
+	lrl->session_id = long_retry_limit_th->session_id;
+	lrl->long_retry_limit = long_retry_limit_th->long_retry_limit;
+
+	qdf_mem_zero(&msg, sizeof(msg));
+	msg.type = SIR_HAL_LONG_RETRY_LIMIT_CNT;
+	msg.reserved = 0;
+	msg.bodyptr = lrl;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("Not able to post long retry limit count to WDA"));
+		qdf_mem_free(lrl);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+/**
+ * sme_update_sta_inactivity_timeout(): Update sta_inactivity_timeout to FW
+ * @hal: Handle returned by mac_open
+ * @session_id: Session ID on which sta_inactivity_timeout needs
+ * to be updated to FW
+ * @sta_inactivity_timeout: sta inactivity timeout.
+ *
+ * If a station does not send anything in sta_inactivity_timeout seconds, an
+ * empty data frame is sent to it in order to verify whether it is
+ * still in range. If this frame is not ACKed, the station will be
+ * disassociated and then deauthenticated.
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure.
+ */
+QDF_STATUS sme_update_sta_inactivity_timeout(tHalHandle hal_handle,
+		 struct sme_sta_inactivity_timeout  *sta_inactivity_timer)
+{
+	struct sme_sta_inactivity_timeout *inactivity_time;
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	inactivity_time = qdf_mem_malloc(sizeof(*inactivity_time));
+	if (!inactivity_time)
+		return QDF_STATUS_E_FAILURE;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("sta_inactivity_timeout: %d"),
+			sta_inactivity_timer->sta_inactivity_timeout);
+	inactivity_time->session_id = sta_inactivity_timer->session_id;
+	inactivity_time->sta_inactivity_timeout =
+		sta_inactivity_timer->sta_inactivity_timeout;
+
+	wma_update_sta_inactivity_timeout(wma_handle,
+				inactivity_time);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_get_reg_info() - To get registration info
+ * @hHal: HAL context
+ * @chanId: channel id
+ * @regInfo1: first reg info to fill
+ * @regInfo2: second reg info to fill
+ *
+ * This routine will give you reg info
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_get_reg_info(tHalHandle hHal, uint8_t chanId,
+			    uint32_t *regInfo1, uint32_t *regInfo2)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status;
+	uint8_t i;
+	bool found = false;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	*regInfo1 = 0;
+	*regInfo2 = 0;
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+
+	for (i = 0; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) {
+		if (pMac->scan.defaultPowerTable[i].chan_num == chanId) {
+			SME_SET_CHANNEL_REG_POWER(*regInfo1,
+				pMac->scan.defaultPowerTable[i].tx_power);
+
+			SME_SET_CHANNEL_MAX_TX_POWER(*regInfo2,
+				pMac->scan.defaultPowerTable[i].tx_power);
+			found = true;
+			break;
+		}
+	}
+	if (!found)
+		status = QDF_STATUS_E_FAILURE;
+
+	sme_release_global_lock(&pMac->sme);
+	return status;
+}
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+/*
+ * sme_auto_shutdown_cb() -
+ *   Used to plug in callback function for receiving auto shutdown evt
+ *
+ * hHal
+ * pCallbackfn : callback function pointer should be plugged in
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_auto_shutdown_cb(tHalHandle hHal, void (*pCallbackfn)(void)
+				    ) {
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+		  "%s: Plug in Auto shutdown event callback", __func__);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		if (NULL != pCallbackfn)
+			pMac->sme.pAutoShutdownNotificationCb = pCallbackfn;
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+
+/*
+ * sme_set_auto_shutdown_timer() -
+ *  API to set auto shutdown timer value in FW.
+ *
+ * hHal - The handle returned by mac_open
+ * timer_val - The auto shutdown timer value to be set
+ * Return Configuration message posting status, SUCCESS or Fail
+ */
+QDF_STATUS sme_set_auto_shutdown_timer(tHalHandle hHal, uint32_t timer_val)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tSirAutoShutdownCmdParams *auto_sh_cmd;
+	struct scheduler_msg message = {0};
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		auto_sh_cmd = qdf_mem_malloc(sizeof(tSirAutoShutdownCmdParams));
+		if (!auto_sh_cmd) {
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		auto_sh_cmd->timer_val = timer_val;
+
+		/* serialize the req through MC thread */
+		message.bodyptr = auto_sh_cmd;
+		message.type = WMA_SET_AUTO_SHUTDOWN_TIMER_REQ;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Post Auto shutdown MSG fail", __func__);
+			qdf_mem_free(auto_sh_cmd);
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: Posted Auto shutdown MSG", __func__);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+#endif
+
+#ifdef FEATURE_WLAN_CH_AVOID
+/*
+ * sme_ch_avoid_update_req() -
+ *   API to request channel avoidance update from FW.
+ *
+ * hHal - The handle returned by mac_open
+ * update_type - The update_type parameter of this request call
+ * Return Configuration message posting status, SUCCESS or Fail
+ */
+QDF_STATUS sme_ch_avoid_update_req(tHalHandle hHal)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tSirChAvoidUpdateReq *cauReq;
+	struct scheduler_msg message = {0};
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		cauReq = qdf_mem_malloc(sizeof(tSirChAvoidUpdateReq));
+		if (!cauReq) {
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		cauReq->reserved_param = 0;
+
+		/* serialize the req through MC thread */
+		message.bodyptr = cauReq;
+		message.type = WMA_CH_AVOID_UPDATE_REQ;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Post Ch Avoid Update MSG fail",
+				  __func__);
+			qdf_mem_free(cauReq);
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: Posted Ch Avoid Update MSG", __func__);
+		sme_release_global_lock(&pMac->sme);
+	}
+
+	return status;
+}
+#endif
+
+/**
+ * sme_set_miracast() - Function to set miracast value to UMAC
+ * @hal:                Handle returned by macOpen
+ * @filter_type:        0-Disabled, 1-Source, 2-sink
+ *
+ * This function passes down the value of miracast set by
+ * framework to UMAC
+ *
+ * Return: Configuration message posting status, SUCCESS or Fail
+ *
+ */
+QDF_STATUS sme_set_miracast(tHalHandle hal, uint8_t filter_type)
+{
+	struct scheduler_msg msg = {0};
+	uint32_t *val;
+	tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal);
+
+	if (!mac_ptr) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Invalid pointer", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	val = qdf_mem_malloc(sizeof(*val));
+	if (!val)
+		return QDF_STATUS_E_NOMEM;
+
+	*val = filter_type;
+
+	msg.type = SIR_HAL_SET_MIRACAST;
+	msg.reserved = 0;
+	msg.bodyptr = val;
+
+	if (!QDF_IS_STATUS_SUCCESS(
+				scheduler_post_message(QDF_MODULE_ID_SME,
+						       QDF_MODULE_ID_WMA,
+						       QDF_MODULE_ID_WMA,
+						       &msg))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+		    "%s: Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!",
+		    __func__);
+		qdf_mem_free(val);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mac_ptr->sme.miracast_value = filter_type;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_set_mas() - Function to set MAS value to UMAC
+ * @val:	1-Enable, 0-Disable
+ *
+ * This function passes down the value of MAS to the UMAC. A
+ * value of 1 will enable MAS and a value of 0 will disable MAS
+ *
+ * Return: Configuration message posting status, SUCCESS or Fail
+ *
+ */
+QDF_STATUS sme_set_mas(uint32_t val)
+{
+	struct scheduler_msg msg = {0};
+	uint32_t *ptr_val;
+
+	ptr_val = qdf_mem_malloc(sizeof(*ptr_val));
+	if (!ptr_val)
+		return QDF_STATUS_E_NOMEM;
+
+	*ptr_val = val;
+
+	msg.type = SIR_HAL_SET_MAS;
+	msg.reserved = 0;
+	msg.bodyptr = ptr_val;
+
+	if (!QDF_IS_STATUS_SUCCESS(
+				scheduler_post_message(QDF_MODULE_ID_SME,
+						       QDF_MODULE_ID_WMA,
+						       QDF_MODULE_ID_WMA,
+						       &msg))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+		    "%s: Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!",
+		    __func__);
+		qdf_mem_free(ptr_val);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_roam_channel_change_req() - Channel change to new target channel
+ * @hHal: handle returned by mac_open
+ * @bssid: mac address of BSS
+ * @ch_params: target channel information
+ * @profile: CSR profile
+ *
+ * API to Indicate Channel change to new target channel
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_roam_channel_change_req(tHalHandle hHal,
+				       struct qdf_mac_addr bssid,
+				       struct ch_params *ch_params,
+				       struct csr_roam_profile *profile)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+
+		status = csr_roam_channel_change_req(pMac, bssid, ch_params,
+				profile);
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_process_channel_change_resp() -
+ * API to Indicate Channel change response message to SAP.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_process_channel_change_resp(tpAniSirGlobal pMac,
+					   uint16_t msg_type, void *pMsgBuf)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_info proam_info = { 0 };
+	eCsrRoamResult roamResult;
+	tpSwitchChannelParams pChnlParams = (tpSwitchChannelParams) pMsgBuf;
+	uint32_t SessionId = pChnlParams->peSessionId;
+
+	proam_info.channelChangeRespEvent =
+		qdf_mem_malloc(sizeof(tSirChanChangeResponse));
+	if (!proam_info.channelChangeRespEvent) {
+		status = QDF_STATUS_E_NOMEM;
+		return status;
+	}
+	if (msg_type == eWNI_SME_CHANNEL_CHANGE_RSP) {
+		proam_info.channelChangeRespEvent->sessionId = SessionId;
+		proam_info.channelChangeRespEvent->newChannelNumber =
+			pChnlParams->channelNumber;
+
+		if (pChnlParams->status == QDF_STATUS_SUCCESS) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "sapdfs: Received success eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]",
+				  SessionId);
+			proam_info.channelChangeRespEvent->channelChangeStatus =
+				1;
+			roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS;
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "sapdfs: Received failure eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]",
+				  SessionId);
+			proam_info.channelChangeRespEvent->channelChangeStatus =
+				0;
+			roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE;
+		}
+
+		csr_roam_call_callback(pMac, SessionId, &proam_info, 0,
+				       eCSR_ROAM_SET_CHANNEL_RSP, roamResult);
+
+	} else {
+		status = QDF_STATUS_E_FAILURE;
+		sme_err("Invalid Channel Change Resp Message: %d",
+			status);
+	}
+	qdf_mem_free(proam_info.channelChangeRespEvent);
+
+	return status;
+}
+
+/*
+ * sme_roam_start_beacon_req() -
+ * API to Indicate LIM to start Beacon Tx after SAP CAC Wait is completed.
+ *
+ * hHal - The handle returned by mac_open
+ * sessionId - session ID
+ * dfsCacWaitStatus - CAC WAIT status flag
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_roam_start_beacon_req(tHalHandle hHal, struct qdf_mac_addr bssid,
+				     uint8_t dfsCacWaitStatus)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_roam_start_beacon_req(pMac, bssid,
+						dfsCacWaitStatus);
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+#ifdef CONFIG_VDEV_SM
+QDF_STATUS sme_csa_restart(tpAniSirGlobal mac_ctx, uint8_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_csa_restart(mac_ctx, session_id);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+
+	return status;
+}
+#endif
+
+/**
+ * sme_roam_csa_ie_request() - request CSA IE transmission from PE
+ * @hHal: handle returned by mac_open
+ * @bssid: SAP bssid
+ * @targetChannel: target channel information
+ * @csaIeReqd: CSA IE Request
+ * @ch_params: channel information
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_roam_csa_ie_request(tHalHandle hHal, struct qdf_mac_addr bssid,
+				uint8_t targetChannel, uint8_t csaIeReqd,
+				struct ch_params *ch_params)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_roam_send_chan_sw_ie_request(pMac, bssid,
+				targetChannel, csaIeReqd, ch_params);
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_init_thermal_info() -
+ * SME API to initialize the thermal mitigation parameters
+ *
+ * hHal
+ * thermalParam : thermal mitigation parameters
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_init_thermal_info(tHalHandle hHal, tSmeThermalParams
+				thermalParam)
+{
+	t_thermal_mgmt *pWmaParam;
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	pWmaParam = qdf_mem_malloc(sizeof(t_thermal_mgmt));
+	if (!pWmaParam)
+		return QDF_STATUS_E_NOMEM;
+
+	pWmaParam->thermalMgmtEnabled = thermalParam.smeThermalMgmtEnabled;
+	pWmaParam->throttlePeriod = thermalParam.smeThrottlePeriod;
+
+	pWmaParam->throttle_duty_cycle_tbl[0] =
+		thermalParam.sme_throttle_duty_cycle_tbl[0];
+	pWmaParam->throttle_duty_cycle_tbl[1] =
+		thermalParam.sme_throttle_duty_cycle_tbl[1];
+	pWmaParam->throttle_duty_cycle_tbl[2] =
+		thermalParam.sme_throttle_duty_cycle_tbl[2];
+	pWmaParam->throttle_duty_cycle_tbl[3] =
+		thermalParam.sme_throttle_duty_cycle_tbl[3];
+
+	pWmaParam->thermalLevels[0].minTempThreshold =
+		thermalParam.smeThermalLevels[0].smeMinTempThreshold;
+	pWmaParam->thermalLevels[0].maxTempThreshold =
+		thermalParam.smeThermalLevels[0].smeMaxTempThreshold;
+	pWmaParam->thermalLevels[1].minTempThreshold =
+		thermalParam.smeThermalLevels[1].smeMinTempThreshold;
+	pWmaParam->thermalLevels[1].maxTempThreshold =
+		thermalParam.smeThermalLevels[1].smeMaxTempThreshold;
+	pWmaParam->thermalLevels[2].minTempThreshold =
+		thermalParam.smeThermalLevels[2].smeMinTempThreshold;
+	pWmaParam->thermalLevels[2].maxTempThreshold =
+		thermalParam.smeThermalLevels[2].smeMaxTempThreshold;
+	pWmaParam->thermalLevels[3].minTempThreshold =
+		thermalParam.smeThermalLevels[3].smeMinTempThreshold;
+	pWmaParam->thermalLevels[3].maxTempThreshold =
+		thermalParam.smeThermalLevels[3].smeMaxTempThreshold;
+
+	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
+		msg.type = WMA_INIT_THERMAL_INFO_CMD;
+		msg.bodyptr = pWmaParam;
+
+		if (!QDF_IS_STATUS_SUCCESS
+			    (scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &msg))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Not able to post WMA_SET_THERMAL_INFO_CMD to WMA!",
+				  __func__);
+			qdf_mem_free(pWmaParam);
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+		return QDF_STATUS_SUCCESS;
+	}
+	qdf_mem_free(pWmaParam);
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * sme_add_set_thermal_level_callback() - Plug in set thermal level callback
+ * @hal:	Handle returned by macOpen
+ * @callback:	sme_set_thermal_level_callback
+ *
+ * Plug in set thermal level callback
+ *
+ * Return: none
+ */
+void sme_add_set_thermal_level_callback(tHalHandle hal,
+		sme_set_thermal_level_callback callback)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hal);
+
+	pMac->sme.set_thermal_level_cb = callback;
+}
+
+/**
+ * sme_set_thermal_level() - SME API to set the thermal mitigation level
+ * @hal:         Handler to HAL
+ * @level:       Thermal mitigation level
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_thermal_level(tHalHandle hal, uint8_t level)
+{
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal pMac = PMAC_STRUCT(hal);
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
+		qdf_mem_set(&msg, sizeof(msg), 0);
+		msg.type = WMA_SET_THERMAL_LEVEL;
+		msg.bodyval = level;
+
+		qdf_status =  scheduler_post_message(QDF_MODULE_ID_SME,
+						     QDF_MODULE_ID_WMA,
+						     QDF_MODULE_ID_WMA, &msg);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				   "%s: Not able to post WMA_SET_THERMAL_LEVEL to WMA!",
+				   __func__);
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+		return QDF_STATUS_SUCCESS;
+	}
+	return QDF_STATUS_E_FAILURE;
+}
+
+/*
+ * sme_txpower_limit() -
+ * SME API to set txpower limits
+ *
+ * hHal
+ * psmetx : power limits for 2g/5g
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_txpower_limit(tHalHandle hHal, tSirTxPowerLimit *psmetx)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg message = {0};
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tSirTxPowerLimit *tx_power_limit;
+
+	tx_power_limit = qdf_mem_malloc(sizeof(*tx_power_limit));
+	if (!tx_power_limit)
+		return QDF_STATUS_E_FAILURE;
+
+	*tx_power_limit = *psmetx;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		message.type = WMA_TX_POWER_LIMIT;
+		message.reserved = 0;
+		message.bodyptr = tx_power_limit;
+
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: not able to post WMA_TX_POWER_LIMIT",
+				  __func__);
+			status = QDF_STATUS_E_FAILURE;
+			qdf_mem_free(tx_power_limit);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+QDF_STATUS sme_update_connect_debug(tHalHandle hHal, uint32_t set_value)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	pMac->mlme_cfg->gen.debug_packet_log = set_value;
+	return status;
+}
+
+/*
+ * sme_ap_disable_intra_bss_fwd() -
+ * SME will send message to WMA to set Intra BSS in txrx
+ *
+ * hHal - The handle returned by mac_open
+ * sessionId - session id ( vdev id)
+ * disablefwd - bool value that indicate disable intrabss fwd disable
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_ap_disable_intra_bss_fwd(tHalHandle hHal, uint8_t sessionId,
+					bool disablefwd)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	int status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg message = {0};
+	tpDisableIntraBssFwd pSapDisableIntraFwd = NULL;
+
+	/* Prepare the request to send to SME. */
+	pSapDisableIntraFwd = qdf_mem_malloc(sizeof(tDisableIntraBssFwd));
+	if (NULL == pSapDisableIntraFwd) {
+		sme_err("Memory Allocation Failure!!!");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	pSapDisableIntraFwd->sessionId = sessionId;
+	pSapDisableIntraFwd->disableintrabssfwd = disablefwd;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* serialize the req through MC thread */
+		message.bodyptr = pSapDisableIntraFwd;
+		message.type = WMA_SET_SAP_INTRABSS_DIS;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			status = QDF_STATUS_E_FAILURE;
+			qdf_mem_free(pSapDisableIntraFwd);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+#ifdef WLAN_FEATURE_STATS_EXT
+
+void sme_stats_ext_register_callback(mac_handle_t mac_handle,
+				     stats_ext_cb callback)
+{
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	if (!mac) {
+		sme_err("Invalid mac context");
+		return;
+	}
+
+	mac->sme.stats_ext_cb = callback;
+}
+
+void sme_stats_ext_deregister_callback(mac_handle_t mac_handle)
+{
+	sme_stats_ext_register_callback(mac_handle, NULL);
+}
+
+void sme_stats_ext2_register_callback(mac_handle_t mac_handle,
+				      stats_ext2_cb callback)
+{
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	if (!mac) {
+		sme_err("Invalid mac context");
+		return;
+	}
+
+	mac->sme.stats_ext2_cb = callback;
+}
+
+/*
+ * sme_stats_ext_request() -
+ * Function called when HDD receives STATS EXT vendor command from userspace
+ *
+ * sessionID - vdevID for the stats ext request
+ * input - Stats Ext Request structure ptr
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_stats_ext_request(uint8_t session_id, tpStatsExtRequestReq input)
+{
+	struct scheduler_msg msg = {0};
+	tpStatsExtRequest data;
+	size_t data_len;
+
+	data_len = sizeof(tStatsExtRequest) + input->request_data_len;
+	data = qdf_mem_malloc(data_len);
+	if (!data)
+		return QDF_STATUS_E_NOMEM;
+
+	data->vdev_id = session_id;
+	data->request_data_len = input->request_data_len;
+	if (input->request_data_len)
+		qdf_mem_copy(data->request_data,
+			     input->request_data, input->request_data_len);
+
+	msg.type = WMA_STATS_EXT_REQUEST;
+	msg.reserved = 0;
+	msg.bodyptr = data;
+
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_WMA,
+							 QDF_MODULE_ID_WMA,
+							 &msg)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Not able to post WMA_STATS_EXT_REQUEST message to WMA",
+			  __func__);
+		qdf_mem_free(data);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_stats_ext_event() - eWNI_SME_STATS_EXT_EVENT processor
+ * @mac: Global MAC context
+ * @msg: "stats ext" message
+
+ * This callback function called when SME received eWNI_SME_STATS_EXT_EVENT
+ * response from WMA
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_stats_ext_event(tpAniSirGlobal mac,
+				      struct stats_ext_event *msg)
+{
+	if (!msg) {
+		sme_err("Null msg");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (mac->sme.stats_ext_cb)
+		mac->sme.stats_ext_cb(mac->hdd_handle, msg);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#else
+
+static QDF_STATUS sme_stats_ext_event(tpAniSirGlobal mac,
+				      struct stats_ext_event *msg)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif
+
+/*
+ * sme_update_dfs_scan_mode() -
+ * Update DFS roam scan mode
+ *	    This function is called through dynamic setConfig callback function
+ *	    to configure allowDFSChannelRoam.
+ * hHal - HAL handle for device
+ * sessionId - Session Identifier
+ * allowDFSChannelRoam - DFS roaming scan mode 0 (disable),
+ *	    1 (passive), 2 (active)
+ * Return QDF_STATUS_SUCCESS - SME update DFS roaming scan config
+ *	    successfully.
+ *	  Other status means SME failed to update DFS roaming scan config.
+ */
+QDF_STATUS sme_update_dfs_scan_mode(tHalHandle hHal, uint8_t sessionId,
+				    uint8_t allowDFSChannelRoam)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "LFR runtime successfully set AllowDFSChannelRoam Mode to %d - old value is %d - roam state is %s",
+			  allowDFSChannelRoam,
+			  pMac->roam.configParam.allowDFSChannelRoam,
+			  mac_trace_get_neighbour_roam_state(pMac->roam.
+							     neighborRoamInfo
+							     [sessionId].
+							    neighborRoamState));
+		pMac->roam.configParam.allowDFSChannelRoam =
+			allowDFSChannelRoam;
+		if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
+			csr_roam_offload_scan(pMac, sessionId,
+					ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+					REASON_ROAM_DFS_SCAN_MODE_CHANGED);
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+
+
+	return status;
+}
+
+/*
+ * sme_get_dfs_scan_mode() - get DFS roam scan mode
+ *	  This is a synchronous call
+ *
+ * hHal - The handle returned by mac_open.
+ * Return DFS roaming scan mode 0 (disable), 1 (passive), 2 (active)
+ */
+uint8_t sme_get_dfs_scan_mode(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.allowDFSChannelRoam;
+}
+
+/*
+ * sme_modify_add_ie() -
+ * This function sends msg to updates the additional IE buffers in PE
+ *
+ * hHal - global structure
+ * pModifyIE - pointer to tModifyIE structure
+ * updateType - type of buffer
+ * Return Success or failure
+ */
+QDF_STATUS sme_modify_add_ie(tHalHandle hHal,
+			     tSirModifyIE *pModifyIE, eUpdateIEsType updateType)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_roam_modify_add_ies(pMac, pModifyIE, updateType);
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_update_add_ie() -
+ * This function sends msg to updates the additional IE buffers in PE
+ *
+ * hHal - global structure
+ * pUpdateIE - pointer to structure tUpdateIE
+ * updateType - type of buffer
+ * Return Success or failure
+ */
+QDF_STATUS sme_update_add_ie(tHalHandle hHal,
+			     tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		status = csr_roam_update_add_ies(pMac, pUpdateIE, updateType);
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/**
+ * sme_update_dsc_pto_up_mapping()
+ * @hHal: HAL context
+ * @dscpmapping: pointer to DSCP mapping structure
+ * @sessionId: SME session id
+ *
+ * This routine is called to update dscp mapping
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_update_dsc_pto_up_mapping(tHalHandle hHal,
+					 enum sme_qos_wmmuptype *dscpmapping,
+					 uint8_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t i, j, peSessionId;
+	struct csr_roam_session *pCsrSession = NULL;
+	tpPESession pSession = NULL;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
+	pCsrSession = CSR_GET_SESSION(pMac, sessionId);
+	if (pCsrSession == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("Session lookup fails for CSR session"));
+		sme_release_global_lock(&pMac->sme);
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("Invalid session Id %u"), sessionId);
+		sme_release_global_lock(&pMac->sme);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pSession = pe_find_session_by_bssid(pMac,
+				pCsrSession->connectedProfile.bssid.bytes,
+				&peSessionId);
+
+	if (pSession == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL(" Session lookup fails for BSSID"));
+		sme_release_global_lock(&pMac->sme);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!pSession->QosMapSet.present) {
+		sme_debug("QOS Mapping IE not present");
+		sme_release_global_lock(&pMac->sme);
+		return QDF_STATUS_E_FAILURE;
+	}
+	for (i = 0; i < SME_QOS_WMM_UP_MAX; i++) {
+		for (j = pSession->QosMapSet.dscp_range[i][0];
+			j <= pSession->QosMapSet.dscp_range[i][1];
+			j++) {
+			if ((pSession->QosMapSet.dscp_range[i][0] == 255)
+				&& (pSession->QosMapSet.dscp_range[i][1] ==
+							255)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_DEBUG,
+					FL("User Priority %d isn't used"), i);
+				break;
+			} else {
+				dscpmapping[j] = i;
+			}
+		}
+	}
+	for (i = 0; i < pSession->QosMapSet.num_dscp_exceptions; i++)
+		if (pSession->QosMapSet.dscp_exceptions[i][0] != 255)
+			dscpmapping[pSession->QosMapSet.dscp_exceptions[i][0]] =
+				pSession->QosMapSet.dscp_exceptions[i][1];
+
+	sme_release_global_lock(&pMac->sme);
+	return status;
+}
+
+/*
+ * sme_abort_roam_scan() -
+ * API to abort current roam scan cycle by roam scan offload module.
+ *
+ * hHal - The handle returned by mac_open.
+ * sessionId - Session Identifier
+ * Return QDF_STATUS
+ */
+
+QDF_STATUS sme_abort_roam_scan(tHalHandle hHal, uint8_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
+		/* acquire the lock for the sme object */
+		status = sme_acquire_global_lock(&pMac->sme);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_ABORT_SCAN,
+					      REASON_ROAM_ABORT_ROAM_SCAN);
+			/* release the lock for the sme object */
+			sme_release_global_lock(&pMac->sme);
+		}
+	}
+
+	return status;
+}
+
+#ifdef FEATURE_WLAN_EXTSCAN
+/**
+ * sme_get_valid_channels_by_band() - to fetch valid channels filtered by band
+ * @hHal: HAL context
+ * @wifiBand: RF band information
+ * @aValidChannels: output array to store channel info
+ * @pNumChannels: output number of channels
+ *
+ *  SME API to fetch all valid channels filtered by band
+ *
+ *  Return: QDF_STATUS
+ */
+QDF_STATUS sme_get_valid_channels_by_band(tHalHandle hHal,
+					  uint8_t wifiBand,
+					  uint32_t *aValidChannels,
+					  uint8_t *pNumChannels)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
+	uint8_t numChannels = 0;
+	uint8_t i = 0;
+	uint32_t totValidChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hHal);
+
+	if (!aValidChannels || !pNumChannels) {
+		sme_err("Output channel list/NumChannels is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (wifiBand >= WIFI_BAND_MAX) {
+		sme_err("Invalid wifiBand: %d", wifiBand);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_get_cfg_valid_channels(&chanList[0],
+			&totValidChannels);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Fail to get valid channel list (err=%d)", status);
+		return status;
+	}
+
+	switch (wifiBand) {
+	case WIFI_BAND_UNSPECIFIED:
+		sme_debug("Unspec Band, return all %d valid channels",
+			  totValidChannels);
+		numChannels = totValidChannels;
+		for (i = 0; i < totValidChannels; i++)
+			aValidChannels[i] = cds_chan_to_freq(chanList[i]);
+		break;
+
+	case WIFI_BAND_BG:
+		sme_debug("WIFI_BAND_BG (2.4 GHz)");
+		for (i = 0; i < totValidChannels; i++) {
+			if (WLAN_REG_IS_24GHZ_CH(chanList[i]))
+				aValidChannels[numChannels++] =
+					cds_chan_to_freq(chanList[i]);
+		}
+		break;
+
+	case WIFI_BAND_A:
+		sme_debug("WIFI_BAND_A (5 GHz without DFS)");
+		for (i = 0; i < totValidChannels; i++) {
+			if (WLAN_REG_IS_5GHZ_CH(chanList[i]) &&
+			    !wlan_reg_is_dfs_ch(mac_ctx->pdev, chanList[i]))
+				aValidChannels[numChannels++] =
+					cds_chan_to_freq(chanList[i]);
+		}
+		break;
+
+	case WIFI_BAND_ABG:
+		sme_debug("WIFI_BAND_ABG (2.4 GHz + 5 GHz; no DFS)");
+		for (i = 0; i < totValidChannels; i++) {
+			if ((WLAN_REG_IS_24GHZ_CH(chanList[i]) ||
+			     WLAN_REG_IS_5GHZ_CH(chanList[i])) &&
+			    !wlan_reg_is_dfs_ch(mac_ctx->pdev, chanList[i]))
+				aValidChannels[numChannels++] =
+					cds_chan_to_freq(chanList[i]);
+		}
+		break;
+
+	case WIFI_BAND_A_DFS_ONLY:
+		sme_debug("WIFI_BAND_A_DFS (5 GHz DFS only)");
+		for (i = 0; i < totValidChannels; i++) {
+			if (WLAN_REG_IS_5GHZ_CH(chanList[i]) &&
+			    wlan_reg_is_dfs_ch(mac_ctx->pdev, chanList[i]))
+				aValidChannels[numChannels++] =
+					cds_chan_to_freq(chanList[i]);
+		}
+		break;
+
+	case WIFI_BAND_A_WITH_DFS:
+		sme_debug("WIFI_BAND_A_WITH_DFS (5 GHz with DFS)");
+		for (i = 0; i < totValidChannels; i++) {
+			if (WLAN_REG_IS_5GHZ_CH(chanList[i]))
+				aValidChannels[numChannels++] =
+					cds_chan_to_freq(chanList[i]);
+		}
+		break;
+
+	case WIFI_BAND_ABG_WITH_DFS:
+		sme_debug("WIFI_BAND_ABG_WITH_DFS (2.4 GHz+5 GHz with DFS)");
+		for (i = 0; i < totValidChannels; i++) {
+			if (WLAN_REG_IS_24GHZ_CH(chanList[i]) ||
+			    WLAN_REG_IS_5GHZ_CH(chanList[i]))
+				aValidChannels[numChannels++] =
+					cds_chan_to_freq(chanList[i]);
+		}
+		break;
+
+	default:
+		sme_err("Unknown wifiBand: %d", wifiBand);
+		return QDF_STATUS_E_INVAL;
+	}
+	*pNumChannels = numChannels;
+
+	return status;
+}
+
+QDF_STATUS
+sme_ext_scan_get_capabilities(mac_handle_t mac_handle,
+			      struct extscan_capabilities_params *params)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	struct extscan_capabilities_params *bodyptr;
+
+	/* per contract must make a copy of the params when messaging */
+	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
+	if (!bodyptr)
+		return QDF_STATUS_E_NOMEM;
+	*bodyptr = *params;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = bodyptr;
+		message.type = WMA_EXTSCAN_GET_CAPABILITIES_REQ;
+		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			  NO_SESSION, message.type);
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA,
+						&message);
+		sme_release_global_lock(&mac->sme);
+	}
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failure: %d", status);
+		qdf_mem_free(bodyptr);
+	}
+	return status;
+}
+
+QDF_STATUS
+sme_ext_scan_start(mac_handle_t mac_handle,
+		   struct wifi_scan_cmd_req_params *params)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	struct wifi_scan_cmd_req_params *bodyptr;
+
+	/* per contract must make a copy of the params when messaging */
+	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
+	if (!bodyptr)
+		return QDF_STATUS_E_NOMEM;
+	*bodyptr = *params;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = bodyptr;
+		message.type = WMA_EXTSCAN_START_REQ;
+		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			  NO_SESSION, message.type);
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA,
+						&message);
+		sme_release_global_lock(&mac->sme);
+	}
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failure: %d", status);
+		qdf_mem_free(bodyptr);
+	}
+	return status;
+}
+
+QDF_STATUS sme_ext_scan_stop(mac_handle_t mac_handle,
+			     struct extscan_stop_req_params *params)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	struct extscan_stop_req_params *bodyptr;
+
+	/* per contract must make a copy of the params when messaging */
+	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
+	if (!bodyptr)
+		return QDF_STATUS_E_NOMEM;
+	*bodyptr = *params;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = bodyptr;
+		message.type = WMA_EXTSCAN_STOP_REQ;
+		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			  NO_SESSION, message.type);
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA,
+						&message);
+		sme_release_global_lock(&mac->sme);
+	}
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failure: %d", status);
+		qdf_mem_free(bodyptr);
+	}
+	return status;
+}
+
+QDF_STATUS
+sme_set_bss_hotlist(mac_handle_t mac_handle,
+		    struct extscan_bssid_hotlist_set_params *params)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	struct extscan_bssid_hotlist_set_params *bodyptr;
+
+	/* per contract must make a copy of the params when messaging */
+	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
+	if (!bodyptr)
+		return QDF_STATUS_E_NOMEM;
+
+	*bodyptr = *params;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = bodyptr;
+		message.type = WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ;
+		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			  NO_SESSION, message.type);
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &message);
+		sme_release_global_lock(&mac->sme);
+	}
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failure: %d", status);
+		qdf_mem_free(bodyptr);
+	}
+	return status;
+}
+
+QDF_STATUS
+sme_reset_bss_hotlist(mac_handle_t mac_handle,
+		      struct extscan_bssid_hotlist_reset_params *params)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	struct extscan_bssid_hotlist_reset_params *bodyptr;
+
+	/* per contract must make a copy of the params when messaging */
+	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
+	if (!bodyptr)
+		return QDF_STATUS_E_NOMEM;
+
+	*bodyptr = *params;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = bodyptr;
+		message.type = WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ;
+		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+				 NO_SESSION, message.type));
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &message);
+		sme_release_global_lock(&mac->sme);
+	}
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failure: %d", status);
+		qdf_mem_free(bodyptr);
+	}
+	return status;
+}
+
+QDF_STATUS
+sme_set_significant_change(mac_handle_t mac_handle,
+			   struct extscan_set_sig_changereq_params *params)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	struct extscan_set_sig_changereq_params *bodyptr;
+
+	/* per contract must make a copy of the params when messaging */
+	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
+	if (!bodyptr)
+		return QDF_STATUS_E_NOMEM;
+
+	*bodyptr = *params;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = bodyptr;
+		message.type = WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ;
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA,
+						&message);
+		sme_release_global_lock(&mac->sme);
+	}
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failure: %d", status);
+		qdf_mem_free(bodyptr);
+	}
+	return status;
+}
+
+QDF_STATUS
+sme_reset_significant_change(mac_handle_t mac_handle,
+			     struct extscan_capabilities_reset_params *params)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	struct extscan_capabilities_reset_params *bodyptr;
+
+	/* per contract must make a copy of the params when messaging */
+	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
+	if (!bodyptr)
+		return QDF_STATUS_E_NOMEM;
+
+	*bodyptr = *params;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = bodyptr;
+		message.type = WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ;
+		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+				 NO_SESSION, message.type));
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA,
+						&message);
+		sme_release_global_lock(&mac->sme);
+	}
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failure: %d", status);
+		qdf_mem_free(bodyptr);
+	}
+
+	return status;
+}
+
+QDF_STATUS
+sme_get_cached_results(mac_handle_t mac_handle,
+		       struct extscan_cached_result_params *params)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	struct extscan_cached_result_params *bodyptr;
+
+	/* per contract must make a copy of the params when messaging */
+	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
+	if (!bodyptr)
+		return QDF_STATUS_E_NOMEM;
+	*bodyptr = *params;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = bodyptr;
+		message.type = WMA_EXTSCAN_GET_CACHED_RESULTS_REQ;
+		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			  NO_SESSION, message.type);
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA,
+						&message);
+		sme_release_global_lock(&mac->sme);
+	}
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failure: %d", status);
+		qdf_mem_free(bodyptr);
+	}
+	return status;
+}
+
+QDF_STATUS sme_set_epno_list(mac_handle_t mac_handle,
+			     struct wifi_enhanced_pno_params *params)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	struct wifi_enhanced_pno_params *req_msg;
+	int len;
+
+	SME_ENTER();
+
+	/* per contract must make a copy of the params when messaging */
+	len = sizeof(*req_msg) +
+		(params->num_networks * sizeof(req_msg->networks[0]));
+
+	req_msg = qdf_mem_malloc(len);
+	if (!req_msg)
+		return QDF_STATUS_E_NOMEM;
+	qdf_mem_copy(req_msg, params, len);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("sme_acquire_global_lock failed!(status=%d)",
+			status);
+		qdf_mem_free(req_msg);
+		return status;
+	}
+
+	/* Serialize the req through MC thread */
+	message.bodyptr = req_msg;
+	message.type    = WMA_SET_EPNO_LIST_REQ;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("scheduler_post_msg failed!(err=%d)", status);
+		qdf_mem_free(req_msg);
+	}
+	sme_release_global_lock(&mac->sme);
+
+	return status;
+}
+
+QDF_STATUS sme_set_passpoint_list(mac_handle_t mac_handle,
+				  struct wifi_passpoint_req_param *params)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	struct wifi_passpoint_req_param *req_msg;
+	int len;
+
+	SME_ENTER();
+
+	len = sizeof(*req_msg) +
+		(params->num_networks * sizeof(params->networks[0]));
+	req_msg = qdf_mem_malloc(len);
+	if (!req_msg)
+		return QDF_STATUS_E_NOMEM;
+	qdf_mem_copy(req_msg, params, len);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("sme_acquire_global_lock failed!(status=%d)",
+			status);
+		qdf_mem_free(req_msg);
+		return status;
+	}
+
+	/* Serialize the req through MC thread */
+	message.bodyptr = req_msg;
+	message.type    = WMA_SET_PASSPOINT_LIST_REQ;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("scheduler_post_msg failed!(err=%d)",
+			status);
+		qdf_mem_free(req_msg);
+	}
+	sme_release_global_lock(&mac->sme);
+	return status;
+}
+
+QDF_STATUS sme_reset_passpoint_list(mac_handle_t mac_handle,
+				    struct wifi_passpoint_req_param *params)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	struct wifi_passpoint_req_param *req_msg;
+
+	SME_ENTER();
+
+	req_msg = qdf_mem_malloc(sizeof(*req_msg));
+	if (!req_msg)
+		return QDF_STATUS_E_NOMEM;
+	*req_msg = *params;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("sme_acquire_global_lock failed!(status=%d)",
+			status);
+		qdf_mem_free(req_msg);
+		return status;
+	}
+
+	/* Serialize the req through MC thread */
+	message.bodyptr = req_msg;
+	message.type    = WMA_RESET_PASSPOINT_LIST_REQ;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("scheduler_post_msg failed!(err=%d)",
+			status);
+		qdf_mem_free(req_msg);
+	}
+	sme_release_global_lock(&mac->sme);
+	return status;
+}
+
+QDF_STATUS sme_ext_scan_register_callback(mac_handle_t mac_handle,
+					  ext_scan_ind_cb ext_scan_ind_cb)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.ext_scan_ind_cb = ext_scan_ind_cb;
+		sme_release_global_lock(&mac->sme);
+	}
+	return status;
+}
+#endif /* FEATURE_WLAN_EXTSCAN */
+
+/**
+ * sme_send_wisa_params(): Pass WISA mode to WMA
+ * @hal: HAL context
+ * @wisa_params: pointer to WISA params struct
+ * @sessionId: SME session id
+ *
+ * Pass WISA params to WMA
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_wisa_params(tHalHandle hal,
+				struct sir_wisa_params *wisa_params)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct scheduler_msg message = {0};
+	struct sir_wisa_params *cds_msg_wisa_params;
+
+	cds_msg_wisa_params = qdf_mem_malloc(sizeof(struct sir_wisa_params));
+	if (!cds_msg_wisa_params)
+		return QDF_STATUS_E_NOMEM;
+
+	*cds_msg_wisa_params = *wisa_params;
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		message.bodyptr = cds_msg_wisa_params;
+		message.type = WMA_SET_WISA_PARAMS;
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &message);
+		sme_release_global_lock(&mac->sme);
+	}
+	return status;
+}
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+
+/*
+ * sme_ll_stats_clear_req() -
+ * SME API to clear Link Layer Statistics
+ *
+ * hHal
+ * pclearStatsReq: Link Layer clear stats request params structure
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_ll_stats_clear_req(tHalHandle hHal,
+				  tSirLLStatsClearReq *pclearStatsReq)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	tSirLLStatsClearReq *clear_stats_req;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "staId = %u", pclearStatsReq->staId);
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "statsClearReqMask = 0x%X",
+		  pclearStatsReq->statsClearReqMask);
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "stopReq = %u", pclearStatsReq->stopReq);
+	if (!sme_is_session_id_valid(hHal, pclearStatsReq->staId)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: invalid staId %d",
+			  __func__, pclearStatsReq->staId);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	clear_stats_req = qdf_mem_malloc(sizeof(*clear_stats_req));
+	if (!clear_stats_req)
+		return QDF_STATUS_E_NOMEM;
+
+	*clear_stats_req = *pclearStatsReq;
+
+	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = clear_stats_req;
+		message.type = WMA_LINK_LAYER_STATS_CLEAR_REQ;
+		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+				 NO_SESSION, message.type));
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: not able to post WMA_LL_STATS_CLEAR_REQ",
+				  __func__);
+			qdf_mem_free(clear_stats_req);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: sme_acquire_global_lock error", __func__);
+		qdf_mem_free(clear_stats_req);
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+/*
+ * sme_ll_stats_set_req() -
+ * SME API to set the Link Layer Statistics
+ *
+ * hHal
+ * psetStatsReq: Link Layer set stats request params structure
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_ll_stats_set_req(tHalHandle hHal, tSirLLStatsSetReq
+				*psetStatsReq)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	tSirLLStatsSetReq *set_stats_req;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s:  MPDU Size = %u", __func__,
+		  psetStatsReq->mpduSizeThreshold);
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  " Aggressive Stats Collections = %u",
+		  psetStatsReq->aggressiveStatisticsGathering);
+
+	set_stats_req = qdf_mem_malloc(sizeof(*set_stats_req));
+	if (!set_stats_req)
+		return QDF_STATUS_E_NOMEM;
+
+	*set_stats_req = *psetStatsReq;
+
+	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = set_stats_req;
+		message.type = WMA_LINK_LAYER_STATS_SET_REQ;
+		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+				 NO_SESSION, message.type));
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: not able to post WMA_LL_STATS_SET_REQ",
+				  __func__);
+			qdf_mem_free(set_stats_req);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: sme_acquire_global_lock error", __func__);
+		qdf_mem_free(set_stats_req);
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_ll_stats_get_req(mac_handle_t mac_handle,
+				tSirLLStatsGetReq *get_stats_req,
+				void *context)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg message = {0};
+	tSirLLStatsGetReq *ll_stats_get_req;
+
+	ll_stats_get_req = qdf_mem_malloc(sizeof(*ll_stats_get_req));
+	if (!ll_stats_get_req)
+		return QDF_STATUS_E_NOMEM;
+
+	*ll_stats_get_req = *get_stats_req;
+
+	mac->sme.ll_stats_context = context;
+	if (sme_acquire_global_lock(&mac->sme) == QDF_STATUS_SUCCESS) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = ll_stats_get_req;
+		message.type = WMA_LINK_LAYER_STATS_GET_REQ;
+		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			  NO_SESSION, message.type);
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &message);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("Not able to post WMA_LL_STATS_GET_REQ");
+			qdf_mem_free(ll_stats_get_req);
+		}
+		sme_release_global_lock(&mac->sme);
+	} else {
+		sme_err("sme_acquire_global_lock error");
+		qdf_mem_free(ll_stats_get_req);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_set_link_layer_stats_ind_cb(mac_handle_t mac_handle,
+					   link_layer_stats_cb callback)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.link_layer_stats_cb = callback;
+		sme_release_global_lock(&mac->sme);
+	} else {
+		sme_err("sme_acquire_global_lock error");
+	}
+
+	return status;
+}
+
+/**
+ * sme_set_link_layer_ext_cb() - Register callback for link layer statistics
+ * @hal: Mac global handle
+ * @ll_stats_ext_cb: HDD callback which needs to be invoked after getting
+ *                   status notification from FW
+ *
+ * Return: eHalStatus
+ */
+QDF_STATUS sme_set_link_layer_ext_cb(tHalHandle hal, void (*ll_stats_ext_cb)
+				(hdd_handle_t callback_ctx, tSirLLStatsResults
+				*rsp))
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (status == QDF_STATUS_SUCCESS) {
+		mac->sme.link_layer_stats_ext_cb = ll_stats_ext_cb;
+		sme_release_global_lock(&mac->sme);
+	} else
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: sme_qcquire_global_lock error", __func__);
+	return status;
+}
+
+/**
+ * sme_reset_link_layer_stats_ind_cb() - SME API to reset link layer stats
+ *					 indication
+ * @h_hal: Hal Handle
+ *
+ * This function reset's the link layer stats indication
+ *
+ * Return: QDF_STATUS Enumeration
+ */
+
+QDF_STATUS sme_reset_link_layer_stats_ind_cb(tHalHandle h_hal)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal pmac;
+
+	if (!h_hal) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("hHal is not valid"));
+		return QDF_STATUS_E_INVAL;
+	}
+	pmac = PMAC_STRUCT(h_hal);
+
+	status = sme_acquire_global_lock(&pmac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pmac->sme.link_layer_stats_cb = NULL;
+		sme_release_global_lock(&pmac->sme);
+	} else
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: sme_acquire_global_lock error", __func__);
+
+	return status;
+}
+
+/**
+ * sme_ll_stats_set_thresh - set threshold for mac counters
+ * @hal, hal layer handle
+ * @threshold, threshold for mac counters
+ *
+ * Return: QDF_STATUS Enumeration
+ */
+QDF_STATUS sme_ll_stats_set_thresh(tHalHandle hal,
+				   struct sir_ll_ext_stats_threshold *threshold)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac;
+	struct scheduler_msg message = {0};
+	struct sir_ll_ext_stats_threshold *thresh;
+
+	if (!threshold) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("threshold is not valid"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!hal) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("hal is not valid"));
+		return QDF_STATUS_E_INVAL;
+	}
+	mac = PMAC_STRUCT(hal);
+
+	thresh = qdf_mem_malloc(sizeof(*thresh));
+	if (!thresh)
+		return QDF_STATUS_E_NOMEM;
+
+	*thresh = *threshold;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = thresh;
+		message.type    = WDA_LINK_LAYER_STATS_SET_THRESHOLD;
+		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+				 NO_SESSION, message.type));
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &message);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: not able to post WDA_LL_STATS_GET_REQ",
+				  __func__);
+			qdf_mem_free(thresh);
+		}
+		sme_release_global_lock(&mac->sme);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("sme_acquire_global_lock error"));
+		qdf_mem_free(thresh);
+	}
+	return status;
+}
+
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+#ifdef WLAN_POWER_DEBUGFS
+/**
+ * sme_power_debug_stats_req() - SME API to collect Power debug stats
+ * @callback_fn: Pointer to the callback function for Power stats event
+ * @power_stats_context: Pointer to context
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_power_debug_stats_req(tHalHandle hal, void (*callback_fn)
+				(struct power_stats_response *response,
+				void *context), void *power_stats_context)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct scheduler_msg msg = {0};
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (!callback_fn) {
+			sme_err("Indication callback did not registered");
+			sme_release_global_lock(&mac_ctx->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		mac_ctx->sme.power_debug_stats_context = power_stats_context;
+		mac_ctx->sme.power_stats_resp_callback = callback_fn;
+		msg.bodyptr = NULL;
+		msg.type = WMA_POWER_DEBUG_STATS_REQ;
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &msg);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			sme_err("not able to post WDA_POWER_DEBUG_STATS_REQ");
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+	return status;
+}
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * sme_update_roam_key_mgmt_offload_enabled() - enable/disable key mgmt offload
+ * This is a synchronous call
+ * @hal_ctx: The handle returned by mac_open.
+ * @session_id: Session Identifier
+ * @key_mgmt_offload_enabled: key mgmt enable/disable flag
+ * @pmkid_modes: PMKID modes of PMKSA caching and OKC
+ * Return: QDF_STATUS_SUCCESS - SME updated config successfully.
+ * Other status means SME is failed to update.
+ */
+
+QDF_STATUS sme_update_roam_key_mgmt_offload_enabled(tHalHandle hal_ctx,
+					uint8_t session_id,
+					bool key_mgmt_offload_enabled,
+					struct pmkid_mode_bits *pmkid_modes)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"%s: LFR3: key_mgmt_offload_enabled changed to %d",
+				  __func__, key_mgmt_offload_enabled);
+			status = csr_roam_set_key_mgmt_offload(mac_ctx,
+						session_id,
+						key_mgmt_offload_enabled,
+						pmkid_modes);
+		} else
+			status = QDF_STATUS_E_INVAL;
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+
+	return status;
+}
+#endif
+
+/*
+ * sme_get_temperature() -
+ * SME API to get the pdev temperature
+ *
+ * hHal
+ * temperature context
+ * pCallbackfn: callback fn with response (temperature)
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_get_temperature(tHalHandle hHal,
+			       void *tempContext,
+			       void (*pCallbackfn)(int temperature,
+						   void *pContext))
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		if ((NULL == pCallbackfn) &&
+		    (NULL == pMac->sme.pGetTemperatureCb)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"Indication Call back did not registered");
+			sme_release_global_lock(&pMac->sme);
+			return QDF_STATUS_E_FAILURE;
+		} else if (NULL != pCallbackfn) {
+			pMac->sme.pTemperatureCbContext = tempContext;
+			pMac->sme.pGetTemperatureCb = pCallbackfn;
+		}
+		/* serialize the req through MC thread */
+		message.bodyptr = NULL;
+		message.type = WMA_GET_TEMPERATURE_REQ;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("Post Get Temperature msg fail"));
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+/*
+ * sme_set_scanning_mac_oui() -
+ * SME API to set scanning mac oui
+ *
+ * hHal
+ * pScanMacOui: Scanning Mac Oui (input 3 bytes)
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_scanning_mac_oui(tHalHandle hHal, tSirScanMacOui
+					*pScanMacOui)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = pScanMacOui;
+		message.type = WMA_SET_SCAN_MAC_OUI_REQ;
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("Msg post Set Scan Mac OUI failed"));
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+#ifdef DHCP_SERVER_OFFLOAD
+/*
+ * sme_set_dhcp_srv_offload() -
+ * SME API to set DHCP server offload info
+ *
+ * hHal
+ * pDhcpSrvInfo : DHCP server offload info struct
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_dhcp_srv_offload(tHalHandle hHal,
+				    tSirDhcpSrvOffloadInfo *pDhcpSrvInfo)
+{
+	struct scheduler_msg message = {0};
+	tSirDhcpSrvOffloadInfo *pSmeDhcpSrvInfo;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	pSmeDhcpSrvInfo = qdf_mem_malloc(sizeof(*pSmeDhcpSrvInfo));
+	if (!pSmeDhcpSrvInfo)
+		return QDF_STATUS_E_NOMEM;
+
+	*pSmeDhcpSrvInfo = *pDhcpSrvInfo;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		/* serialize the req through MC thread */
+		message.type = WMA_SET_DHCP_SERVER_OFFLOAD_CMD;
+		message.bodyptr = pSmeDhcpSrvInfo;
+
+		if (!QDF_IS_STATUS_SUCCESS
+			    (scheduler_post_message(QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_WMA,
+						    &message))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s:WMA_SET_DHCP_SERVER_OFFLOAD_CMD failed",
+				  __func__);
+			qdf_mem_free(pSmeDhcpSrvInfo);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&pMac->sme);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: sme_acquire_global_lock error!", __func__);
+		qdf_mem_free(pSmeDhcpSrvInfo);
+	}
+
+	return status;
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
+QDF_STATUS sme_send_unit_test_cmd(uint32_t vdev_id, uint32_t module_id,
+				  uint32_t arg_count, uint32_t *arg)
+{
+	return wma_form_unit_test_cmd_and_send(vdev_id, module_id,
+					       arg_count, arg);
+}
+
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+/*
+ * sme_set_led_flashing() -
+ * API to set the Led flashing parameters.
+ *
+ * hHal - The handle returned by mac_open.
+ * x0, x1 -  led flashing parameters
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_set_led_flashing(tHalHandle hHal, uint8_t type,
+				uint32_t x0, uint32_t x1)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct scheduler_msg message = {0};
+	struct flashing_req_params *ledflashing;
+
+	ledflashing = qdf_mem_malloc(sizeof(*ledflashing));
+	if (!ledflashing)
+		return QDF_STATUS_E_NOMEM;
+
+	ledflashing->req_id = 0;
+	ledflashing->pattern_id = type;
+	ledflashing->led_x0 = x0;
+	ledflashing->led_x1 = x1;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Serialize the req through MC thread */
+		message.bodyptr = ledflashing;
+		message.type = WMA_LED_FLASHING_REQ;
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &message);
+		sme_release_global_lock(&pMac->sme);
+	}
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		qdf_mem_free(ledflashing);
+
+	return status;
+}
+#endif
+
+/**
+ *  sme_handle_dfS_chan_scan() - handle DFS channel configuration
+ *  @h_hal:         corestack handler
+ *  @dfs_flag:      flag indicating dfs channel enable/disable
+ *  Return:         QDF_STATUS
+ */
+QDF_STATUS sme_handle_dfs_chan_scan(tHalHandle h_hal, uint8_t dfs_flag)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac  = PMAC_STRUCT(h_hal);
+
+	status = sme_acquire_global_lock(&mac->sme);
+
+	if (QDF_STATUS_SUCCESS == status) {
+
+		mac->scan.fEnableDFSChnlScan = dfs_flag;
+
+		/* update the channel list to the firmware */
+		status = csr_update_channel_list(mac);
+
+		sme_release_global_lock(&mac->sme);
+	}
+
+	return status;
+}
+
+/**
+ *  sme_enable_dfS_chan_scan() - set DFS channel scan enable/disable
+ *  @h_hal:         corestack handler
+ *  @dfs_flag:      flag indicating dfs channel enable/disable
+ *  Return:         QDF_STATUS
+ */
+QDF_STATUS sme_enable_dfs_chan_scan(tHalHandle h_hal, uint8_t dfs_flag)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac;
+
+	if (!h_hal) {
+		sme_err("hal is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mac = PMAC_STRUCT(h_hal);
+
+	mac->scan.fEnableDFSChnlScan = dfs_flag;
+
+	return status;
+}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * sme_validate_sap_channel_switch() - validate target channel switch w.r.t
+ *      concurreny rules set to avoid channel interference.
+ * @hal - Hal context
+ * @sap_ch - channel to switch
+ * @sap_phy_mode - phy mode of SAP
+ * @cc_switch_mode - concurreny switch mode
+ * @session_id - sme session id.
+ *
+ * Return: true if there is no channel interference else return false
+ */
+bool sme_validate_sap_channel_switch(tHalHandle hal,
+	uint16_t sap_ch, eCsrPhyMode sap_phy_mode, uint8_t cc_switch_mode,
+	uint8_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct csr_roam_session *session = CSR_GET_SESSION(mac, session_id);
+	uint16_t intf_channel = 0;
+
+	if (!session)
+		return false;
+
+	session->ch_switch_in_progress = true;
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		intf_channel = csr_check_concurrent_channel_overlap(mac, sap_ch,
+						sap_phy_mode,
+						cc_switch_mode);
+		sme_release_global_lock(&mac->sme);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("sme_acquire_global_lock error!"));
+		session->ch_switch_in_progress = false;
+		return false;
+	}
+
+	session->ch_switch_in_progress = false;
+	return (intf_channel == 0) ? true : false;
+}
+#endif
+
+/**
+ * sme_configure_stats_avg_factor() - function to config avg. stats factor
+ * @hal: hal
+ * @session_id: session ID
+ * @stats_avg_factor: average stats factor
+ *
+ * This function configures the stats avg factor in firmware
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_configure_stats_avg_factor(tHalHandle hal, uint8_t session_id,
+					  uint16_t stats_avg_factor)
+{
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac  = PMAC_STRUCT(hal);
+	struct sir_stats_avg_factor *stats_factor;
+
+	stats_factor = qdf_mem_malloc(sizeof(*stats_factor));
+	if (!stats_factor)
+		return QDF_STATUS_E_NOMEM;
+
+	status = sme_acquire_global_lock(&mac->sme);
+
+	if (QDF_STATUS_SUCCESS == status) {
+
+		stats_factor->vdev_id = session_id;
+		stats_factor->stats_avg_factor = stats_avg_factor;
+
+		/* serialize the req through MC thread */
+		msg.type     = SIR_HAL_CONFIG_STATS_FACTOR;
+		msg.bodyptr  = stats_factor;
+
+		if (!QDF_IS_STATUS_SUCCESS(
+			    scheduler_post_message(QDF_MODULE_ID_SME,
+						   QDF_MODULE_ID_WMA,
+						   QDF_MODULE_ID_WMA, &msg))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Not able to post SIR_HAL_CONFIG_STATS_FACTOR to WMA!",
+				  __func__);
+			qdf_mem_free(stats_factor);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&mac->sme);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: sme_acquire_global_lock error!",
+			  __func__);
+		qdf_mem_free(stats_factor);
+	}
+
+	return status;
+}
+
+/**
+ * sme_configure_guard_time() - function to configure guard time
+ * @hal: hal
+ * @session_id: session id
+ * @guard_time: guard time
+ *
+ * This function configures the guard time in firmware
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_configure_guard_time(tHalHandle hal, uint8_t session_id,
+				    uint32_t guard_time)
+{
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac  = PMAC_STRUCT(hal);
+	struct sir_guard_time_request *g_time;
+
+	g_time = qdf_mem_malloc(sizeof(*g_time));
+	if (!g_time)
+		return QDF_STATUS_E_NOMEM;
+
+	status = sme_acquire_global_lock(&mac->sme);
+
+	if (QDF_STATUS_SUCCESS == status) {
+
+		g_time->vdev_id = session_id;
+		g_time->guard_time = guard_time;
+
+		/* serialize the req through MC thread */
+		msg.type     = SIR_HAL_CONFIG_GUARD_TIME;
+		msg.bodyptr  = g_time;
+
+		if (!QDF_IS_STATUS_SUCCESS(
+			    scheduler_post_message(QDF_MODULE_ID_SME,
+						   QDF_MODULE_ID_WMA,
+						   QDF_MODULE_ID_WMA, &msg))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: Not able to post SIR_HAL_CONFIG_GUARD_TIME to WMA!",
+				  __func__);
+			qdf_mem_free(g_time);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&mac->sme);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: sme_acquire_global_lock error!",
+			  __func__);
+		qdf_mem_free(g_time);
+	}
+
+	return status;
+}
+
+/*
+ * sme_wifi_start_logger() - Send the start/stop logging command to WMA
+ * to either start/stop logging
+ * @hal: HAL context
+ * @start_log: Structure containing the wifi start logger params
+ *
+ * This function sends the start/stop logging command to WMA
+ *
+ * Return: QDF_STATUS_SUCCESS on successful posting
+ */
+QDF_STATUS sme_wifi_start_logger(tHalHandle hal,
+		struct sir_wifi_start_log start_log)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
+	struct scheduler_msg message = {0};
+	struct sir_wifi_start_log *req_msg;
+	uint32_t len;
+
+	len = sizeof(*req_msg);
+	req_msg = qdf_mem_malloc(len);
+	if (!req_msg)
+		return QDF_STATUS_E_NOMEM;
+
+	req_msg->verbose_level = start_log.verbose_level;
+	req_msg->is_iwpriv_command = start_log.is_iwpriv_command;
+	req_msg->ring_id = start_log.ring_id;
+	req_msg->ini_triggered = start_log.ini_triggered;
+	req_msg->user_triggered = start_log.user_triggered;
+	req_msg->size = start_log.size;
+	req_msg->is_pktlog_buff_clear = start_log.is_pktlog_buff_clear;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("sme_acquire_global_lock failed(status=%d)", status);
+		qdf_mem_free(req_msg);
+		return status;
+	}
+
+	/* Serialize the req through MC thread */
+	message.bodyptr = req_msg;
+	message.type    = SIR_HAL_START_STOP_LOGGING;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("scheduler_post_msg failed!(err=%d)", status);
+		qdf_mem_free(req_msg);
+		status = QDF_STATUS_E_FAILURE;
+	}
+	sme_release_global_lock(&mac->sme);
+
+	return status;
+}
+
+/**
+ * sme_neighbor_middle_of_roaming() - Function to know if
+ * STA is in the middle of roaming states
+ * @hal:                Handle returned by macOpen
+ * @sessionId: sessionId of the STA session
+ *
+ * This function is a wrapper to call
+ * csr_neighbor_middle_of_roaming to know STA is in the
+ * middle of roaming states
+ *
+ * Return: True or False
+ *
+ */
+bool sme_neighbor_middle_of_roaming(tHalHandle hHal, uint8_t sessionId)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hHal);
+	bool val = false;
+
+	if (CSR_IS_SESSION_VALID(mac_ctx, sessionId))
+		val = csr_neighbor_middle_of_roaming(mac_ctx, sessionId);
+	else
+		sme_debug("Invalid Session: %d", sessionId);
+
+	return val;
+}
+
+bool sme_is_any_session_in_middle_of_roaming(mac_handle_t hal)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint8_t session_id;
+
+	for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
+		if (CSR_IS_SESSION_VALID(mac_ctx, session_id) &&
+		    csr_neighbor_middle_of_roaming(mac_ctx, session_id))
+			return true;
+	}
+
+	return false;
+}
+
+/*
+ * sme_send_flush_logs_cmd_to_fw() - Flush FW logs
+ * @mac: MAC handle
+ *
+ * This function is used to send the command that will
+ * be used to flush the logs in the firmware
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_send_flush_logs_cmd_to_fw(tpAniSirGlobal mac)
+{
+	QDF_STATUS status;
+	struct scheduler_msg message = {0};
+
+	/* Serialize the req through MC thread */
+	message.bodyptr = NULL;
+	message.type    = SIR_HAL_FLUSH_LOG_TO_FW;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("scheduler_post_msg failed!(err=%d)", status);
+		status = QDF_STATUS_E_FAILURE;
+	}
+	return status;
+}
+
+QDF_STATUS sme_enable_uapsd_for_ac(uint8_t sta_id,
+				   sme_ac_enum_type ac, uint8_t tid,
+				   uint8_t pri, uint32_t srvc_int,
+				   uint32_t sus_int,
+				   enum sme_qos_wmm_dir_type dir,
+				   uint8_t psb, uint32_t sessionId,
+				   uint32_t delay_interval)
+{
+	void *wma_handle;
+	t_wma_trigger_uapsd_params uapsd_params;
+	enum uapsd_ac access_category;
+
+	if (!psb) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"No need to configure auto trigger:psb is 0");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+					"wma_handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	switch (ac) {
+	case SME_AC_BK:
+		access_category = UAPSD_BK;
+		break;
+	case SME_AC_BE:
+		access_category = UAPSD_BE;
+		break;
+	case SME_AC_VI:
+		access_category = UAPSD_VI;
+		break;
+	case SME_AC_VO:
+		access_category = UAPSD_VO;
+		break;
+	default:
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	uapsd_params.wmm_ac = access_category;
+	uapsd_params.user_priority = pri;
+	uapsd_params.service_interval = srvc_int;
+	uapsd_params.delay_interval = delay_interval;
+	uapsd_params.suspend_interval = sus_int;
+
+	if (QDF_STATUS_SUCCESS !=
+	    wma_trigger_uapsd_params(wma_handle, sessionId, &uapsd_params)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"Failed to Trigger Uapsd params for sessionId %d",
+			    sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sme_disable_uapsd_for_ac(uint8_t sta_id,
+				       sme_ac_enum_type ac,
+				       uint32_t sessionId)
+{
+	void *wma_handle;
+	enum uapsd_ac access_category;
+
+	switch (ac) {
+	case SME_AC_BK:
+		access_category = UAPSD_BK;
+		break;
+	case SME_AC_BE:
+		access_category = UAPSD_BE;
+		break;
+	case SME_AC_VI:
+		access_category = UAPSD_VI;
+		break;
+	case SME_AC_VO:
+		access_category = UAPSD_VO;
+		break;
+	default:
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (QDF_STATUS_SUCCESS !=
+	    wma_disable_uapsd_per_ac(wma_handle, sessionId, access_category)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"Failed to disable uapsd for ac %d for sessionId %d",
+			    ac, sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_update_nss() - SME API to change the number for spatial streams
+ * (1 or 2)
+ * @hal: Handle returned by mac open
+ * @nss: Number of spatial streams
+ *
+ * This function is used to update the number of spatial streams supported.
+ *
+ * Return: Success upon successfully changing nss else failure
+ *
+ */
+QDF_STATUS sme_update_nss(tHalHandle h_hal, uint8_t nss)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal);
+	uint32_t i;
+	struct mlme_ht_capabilities_info *ht_cap_info;
+	struct csr_roam_session *csr_session;
+	struct mlme_vht_capabilities_info vht_cap_info;
+
+	vht_cap_info = mac_ctx->mlme_cfg->vht_caps.vht_cap_info;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+
+	if (QDF_STATUS_SUCCESS == status) {
+		vht_cap_info.enable2x2 = (nss == 1) ? 0 : 1;
+
+		/* get the HT capability info*/
+		ht_cap_info = &mac_ctx->mlme_cfg->ht_caps.ht_cap_info;
+
+		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+			if (CSR_IS_SESSION_VALID(mac_ctx, i)) {
+				csr_session = &mac_ctx->roam.roamSession[i];
+				csr_session->htConfig.ht_tx_stbc =
+					ht_cap_info->tx_stbc;
+			}
+		}
+
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+	return status;
+}
+
+/**
+ * sme_update_user_configured_nss() - sets the nss based on user request
+ * @hal: Pointer to HAL
+ * @nss: number of streams
+ *
+ * Return: None
+ */
+void sme_update_user_configured_nss(tHalHandle hal, uint8_t nss)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	mac_ctx->user_configured_nss = nss;
+}
+
+int sme_update_tx_bfee_supp(tHalHandle hal, uint8_t session_id,
+			    uint8_t cfg_val)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	mac_ctx->mlme_cfg->vht_caps.vht_cap_info.su_bformee = cfg_val;
+
+	return sme_update_he_tx_bfee_supp(hal, session_id, cfg_val);
+}
+
+int sme_update_tx_bfee_nsts(mac_handle_t hal, uint8_t session_id,
+			    uint8_t usr_cfg_val, uint8_t nsts_val)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint8_t nsts_set_val;
+
+	mac_ctx->usr_cfg_tx_bfee_nsts = usr_cfg_val;
+	if (usr_cfg_val)
+		nsts_set_val = usr_cfg_val;
+	else
+		nsts_set_val = nsts_val;
+
+	mac_ctx->mlme_cfg->vht_caps.vht_cap_info.tx_bfee_ant_supp =
+		nsts_set_val;
+
+	if (usr_cfg_val)
+		sme_set_he_tx_bf_cbf_rates(session_id);
+
+	return sme_update_he_tx_bfee_nsts(hal, session_id, nsts_set_val);
+}
+#ifdef WLAN_FEATURE_11AX
+void sme_update_tgt_he_cap(mac_handle_t mac_handle,
+			   struct wma_tgt_cfg *cfg,
+			   tDot11fIEhe_cap *he_cap_ini)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(mac_handle);
+
+	qdf_mem_copy(&mac_ctx->he_cap_2g,
+		     &cfg->he_cap_2g,
+		     sizeof(tDot11fIEhe_cap));
+
+	qdf_mem_copy(&mac_ctx->he_cap_5g,
+		     &cfg->he_cap_5g,
+		     sizeof(tDot11fIEhe_cap));
+
+	/* modify HE Caps field according to INI setting */
+	mac_ctx->he_cap_2g.bfee_sts_lt_80 =
+			QDF_MIN(cfg->he_cap_2g.bfee_sts_lt_80,
+				he_cap_ini->bfee_sts_lt_80);
+
+	mac_ctx->he_cap_5g.bfee_sts_lt_80 =
+			QDF_MIN(cfg->he_cap_5g.bfee_sts_lt_80,
+				he_cap_ini->bfee_sts_lt_80);
+}
+
+void sme_update_he_cap_nss(tHalHandle hal, uint8_t session_id,
+		uint8_t nss)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct csr_roam_session *csr_session;
+	uint32_t tx_mcs_map = 0;
+	uint32_t rx_mcs_map = 0;
+	uint32_t mcs_map = 0;
+
+	if (!nss || (nss > 2)) {
+		sme_err("invalid Nss value %d", nss);
+	}
+	csr_session = CSR_GET_SESSION(mac_ctx, session_id);
+	sme_cfg_get_int(hal, WNI_CFG_HE_RX_MCS_MAP_LT_80, &rx_mcs_map);
+	sme_cfg_get_int(hal, WNI_CFG_HE_TX_MCS_MAP_LT_80, &tx_mcs_map);
+	mcs_map = rx_mcs_map & 0x3;
+	if (nss == 1) {
+		tx_mcs_map = HE_SET_MCS_4_NSS(tx_mcs_map, HE_MCS_DISABLE, 2);
+		rx_mcs_map = HE_SET_MCS_4_NSS(rx_mcs_map, HE_MCS_DISABLE, 2);
+	} else {
+		tx_mcs_map = HE_SET_MCS_4_NSS(tx_mcs_map, mcs_map, 2);
+		rx_mcs_map = HE_SET_MCS_4_NSS(rx_mcs_map, mcs_map, 2);
+	}
+	sme_info("new HE Nss MCS MAP: Rx 0x%0X, Tx: 0x%0X",
+			rx_mcs_map, tx_mcs_map);
+	sme_cfg_set_int(hal, WNI_CFG_HE_RX_MCS_MAP_LT_80, rx_mcs_map);
+	sme_cfg_set_int(hal, WNI_CFG_HE_TX_MCS_MAP_LT_80, tx_mcs_map);
+	csr_update_session_he_cap(mac_ctx, csr_session);
+
+}
+
+int sme_update_he_mcs(tHalHandle hal, uint8_t session_id, uint16_t he_mcs)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct csr_roam_session *csr_session;
+	uint16_t mcs_val = 0;
+	uint16_t mcs_map = HE_MCS_ALL_DISABLED;
+	uint32_t wni_cfg_tx_param = 0;
+	uint32_t wni_cfg_rx_param = 0;
+
+	csr_session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (!csr_session) {
+		sme_err("No session for id %d", session_id);
+		return -EINVAL;
+	}
+	if ((he_mcs & 0x3) == HE_MCS_DISABLE) {
+		sme_err("Invalid HE MCS 0x%0x, can't disable 0-7 for 1ss",
+				he_mcs);
+		return -EINVAL;
+	}
+	mcs_val = he_mcs & 0x3;
+	switch (he_mcs) {
+	case HE_80_MCS0_7:
+	case HE_80_MCS0_9:
+	case HE_80_MCS0_11:
+		if (mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2) {
+			mcs_map = HE_SET_MCS_4_NSS(mcs_map, mcs_val, 1);
+			mcs_map = HE_SET_MCS_4_NSS(mcs_map, mcs_val, 2);
+		} else {
+			mcs_map = HE_SET_MCS_4_NSS(mcs_map, mcs_val, 1);
+		}
+		wni_cfg_tx_param = WNI_CFG_HE_TX_MCS_MAP_LT_80;
+		wni_cfg_rx_param = WNI_CFG_HE_RX_MCS_MAP_LT_80;
+		break;
+
+	case HE_160_MCS0_7:
+	case HE_160_MCS0_9:
+	case HE_160_MCS0_11:
+		mcs_map = HE_SET_MCS_4_NSS(mcs_map, mcs_val, 1);
+		wni_cfg_tx_param = WNI_CFG_HE_TX_MCS_MAP_160;
+		wni_cfg_rx_param = WNI_CFG_HE_RX_MCS_MAP_160;
+		break;
+
+	case HE_80p80_MCS0_7:
+	case HE_80p80_MCS0_9:
+	case HE_80p80_MCS0_11:
+		mcs_map = HE_SET_MCS_4_NSS(mcs_map, mcs_val, 1);
+		wni_cfg_tx_param = WNI_CFG_HE_TX_MCS_MAP_80_80;
+		wni_cfg_rx_param = WNI_CFG_HE_RX_MCS_MAP_80_80;
+		break;
+
+	default:
+		sme_err("Invalid HE MCS 0x%0x", he_mcs);
+		return -EINVAL;
+	}
+	sme_info("new HE MCS 0x%0x", mcs_map);
+	sme_cfg_set_int(hal, wni_cfg_tx_param, mcs_map);
+	sme_cfg_set_int(hal, wni_cfg_rx_param, mcs_map);
+	csr_update_session_he_cap(mac_ctx, csr_session);
+
+	return 0;
+}
+
+static int sme_update_he_cap(tHalHandle hal, uint8_t session_id,
+		uint16_t he_cap, int value)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct csr_roam_session *session;
+
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (!session) {
+		sme_err("No session for id %d", session_id);
+		return -EINVAL;
+	}
+	sme_cfg_set_int(hal, he_cap, value);
+	csr_update_session_he_cap(mac_ctx, session);
+
+	return 0;
+}
+
+void sme_set_usr_cfg_mu_edca(mac_handle_t hal, bool val)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	mac_ctx->usr_cfg_mu_edca_params = val;
+}
+
+int sme_update_mu_edca_params(mac_handle_t hal, uint8_t session_id)
+{
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+
+	qdf_mem_zero(&msg, sizeof(msg));
+	msg.type = WNI_SME_UPDATE_MU_EDCA_PARAMS;
+	msg.reserved = 0;
+	msg.bodyval = session_id;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_PE, &msg);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("Not able to post update edca profile");
+		return -EIO;
+	}
+
+	return 0;
+}
+void sme_set_he_mu_edca_def_cfg(mac_handle_t hal)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint8_t i;
+
+	sme_debug("Set MU EDCA params to default");
+	for (i = 0; i < MAX_NUM_AC; i++) {
+		mac_ctx->usr_mu_edca_params[i].aci.aifsn = MU_EDCA_DEF_AIFSN;
+		mac_ctx->usr_mu_edca_params[i].aci.aci = i;
+		mac_ctx->usr_mu_edca_params[i].cw.max = MU_EDCA_DEF_CW_MAX;
+		mac_ctx->usr_mu_edca_params[i].cw.min = MU_EDCA_DEF_CW_MIN;
+		mac_ctx->usr_mu_edca_params[i].mu_edca_timer =
+							MU_EDCA_DEF_TIMER;
+	}
+}
+
+int sme_update_he_tx_bfee_supp(tHalHandle hal, uint8_t session_id,
+			       uint8_t cfg_val)
+{
+	return sme_update_he_cap(hal, session_id, WNI_CFG_HE_SU_BEAMFORMEE,
+				 cfg_val);
+}
+
+int sme_update_he_trigger_frm_mac_pad(mac_handle_t hal, uint8_t session_id,
+				      uint8_t cfg_val)
+{
+	return sme_update_he_cap(hal, session_id, WNI_CFG_HE_TRIG_PAD,
+				 cfg_val);
+}
+
+int sme_update_he_om_ctrl_supp(mac_handle_t hal, uint8_t session_id,
+			       uint8_t cfg_val)
+{
+	return sme_update_he_cap(hal, session_id, WNI_CFG_HE_OMI,
+				 cfg_val);
+}
+
+int sme_send_he_om_ctrl_bw_update(mac_handle_t hal, uint8_t session_id,
+				  uint8_t cfg_val)
+{
+	uint32_t om_ctrl_cmd[NUM_OM_CTRL_UPDATE_CFG_PARAMS] = {0};
+	QDF_STATUS status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (!session) {
+		sme_err("Session does not exist, Session_id: %d", session_id);
+		return -EINVAL;
+	}
+	if (!csr_is_conn_state_connected_infra(mac_ctx, session_id)) {
+		sme_info("STA is not connected, Session_id: %d", session_id);
+		return -EINVAL;
+	}
+	if (cfg_val > session->connectedProfile.vht_channel_width) {
+		sme_info("OM ctrl BW %d is greater than connected BW %d",
+			  cfg_val, session->connectedProfile.vht_channel_width);
+		return -EINVAL;
+	}
+	mac_ctx->he_om_ctrl_cfg_bw_set = true;
+	mac_ctx->he_om_ctrl_cfg_bw = cfg_val;
+	om_ctrl_cmd[0] = 1;
+	qdf_mem_copy((void *)&om_ctrl_cmd[OM_CTRL_CMD_MAC_BITS31],
+		     (void *)session->connectedProfile.bssid.bytes,
+		     sizeof(uint32_t));
+	qdf_mem_copy((void *)&om_ctrl_cmd[OM_CTRL_CMD_MAC_BITS47],
+		     (void *)&session->connectedProfile.bssid.bytes[4],
+		     sizeof(uint16_t));
+	if (mac_ctx->he_om_ctrl_cfg_nss_set) {
+		om_ctrl_cmd[OM_CTRL_CMD_RX_NSS] =
+			mac_ctx->he_om_ctrl_cfg_nss - 1;
+		om_ctrl_cmd[OM_CTRL_CMD_TX_NSS] =
+			mac_ctx->he_om_ctrl_cfg_nss - 1;
+	} else {
+		om_ctrl_cmd[OM_CTRL_CMD_RX_NSS] = session->nss - 1;
+		om_ctrl_cmd[OM_CTRL_CMD_TX_NSS] = session->nss - 1;
+	}
+	om_ctrl_cmd[OM_CTRL_CMD_BW] = cfg_val;
+	om_ctrl_cmd[OM_CTRL_CMD_ULMU] = 1;
+	status = wma_form_unit_test_cmd_and_send(session_id, 13, 7,
+						 om_ctrl_cmd);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("send_unit_test_cmd returned %d", status);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int sme_send_he_om_ctrl_nss_update(mac_handle_t hal, uint8_t session_id,
+				  uint8_t cfg_val)
+{
+	uint32_t om_ctrl_cmd[NUM_OM_CTRL_UPDATE_CFG_PARAMS] = {0};
+	QDF_STATUS status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (!session) {
+		sme_err("Session does not exist, Session_id: %d", session_id);
+		return -EINVAL;
+	}
+	if (!csr_is_conn_state_connected_infra(mac_ctx, session_id)) {
+		sme_info("STA not in connected state Session_id: %d",
+			 session_id);
+		return -EINVAL;
+	}
+	if (cfg_val > session->nss) {
+		sme_info("OM ctrl Nss %d is greater than connected Nss %d",
+			 cfg_val, session->nss);
+		return -EINVAL;
+	}
+	mac_ctx->he_om_ctrl_cfg_nss_set = true;
+	mac_ctx->he_om_ctrl_cfg_nss = cfg_val;
+	om_ctrl_cmd[0] = 1;
+	qdf_mem_copy((void *)&om_ctrl_cmd[OM_CTRL_CMD_MAC_BITS31],
+		     (void *)session->connectedProfile.bssid.bytes,
+		     sizeof(uint32_t));
+	qdf_mem_copy((void *)&om_ctrl_cmd[OM_CTRL_CMD_MAC_BITS47],
+		     (void *)&session->connectedProfile.bssid.bytes[4],
+		     sizeof(uint16_t));
+
+	if (mac_ctx->he_om_ctrl_cfg_bw_set)
+		om_ctrl_cmd[OM_CTRL_CMD_BW] = mac_ctx->he_om_ctrl_cfg_bw;
+	else
+		om_ctrl_cmd[OM_CTRL_CMD_BW] =
+			session->connectedProfile.vht_channel_width;
+
+	om_ctrl_cmd[OM_CTRL_CMD_RX_NSS] = cfg_val - 1;
+	om_ctrl_cmd[OM_CTRL_CMD_TX_NSS] = cfg_val - 1;
+	om_ctrl_cmd[OM_CTRL_CMD_ULMU] = 1;
+	status = wma_form_unit_test_cmd_and_send(session_id, 13, 7,
+						 om_ctrl_cmd);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("send_unit_test_cmd returned %d", status);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+void sme_reset_he_om_ctrl(mac_handle_t hal)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	mac_ctx->he_om_ctrl_cfg_bw_set = false;
+	mac_ctx->he_om_ctrl_cfg_nss_set = false;
+	mac_ctx->he_om_ctrl_cfg_bw = 0;
+	mac_ctx->he_om_ctrl_cfg_nss = 0;
+}
+
+int sme_update_he_tx_bfee_nsts(mac_handle_t hal, uint8_t session_id,
+			       uint8_t cfg_val)
+{
+	return sme_update_he_cap(hal, session_id, WNI_CFG_HE_BFEE_STS_LT80,
+				 cfg_val);
+}
+
+void sme_set_he_tx_bf_cbf_rates(uint8_t session_id)
+{
+	uint32_t tx_bf_cbf_rates_5g[] = {91, 1, 0, 3, 2, 4, 0};
+	uint32_t tx_bf_cbf_rates_2g[] = {91, 1, 1, 3, 1, 3, 0};
+	QDF_STATUS status;
+
+	status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 7,
+						 tx_bf_cbf_rates_5g);
+	if (QDF_STATUS_SUCCESS != status)
+		sme_err("send_unit_test_cmd returned %d", status);
+
+	status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 7,
+						 tx_bf_cbf_rates_2g);
+	if (QDF_STATUS_SUCCESS != status)
+		sme_err("send_unit_test_cmd returned %d", status);
+}
+
+void sme_config_su_ppdu_queue(uint8_t session_id, bool enable)
+{
+	uint32_t su_ppdu_enable[] = {69, 1, 1, 1};
+	uint32_t su_ppdu_disable[] = {69, 1, 1, 0};
+	QDF_STATUS status;
+
+	if (enable) {
+		sme_debug("Send Tx SU PPDU queue ENABLE cmd to FW");
+		status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 4,
+							 su_ppdu_enable);
+	} else {
+		sme_debug("Send Tx SU PPDU queue DISABLE cmd to FW");
+		status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 4,
+							 su_ppdu_disable);
+	}
+	if (QDF_STATUS_SUCCESS != status)
+		sme_err("send_unit_test_cmd returned %d", status);
+}
+
+int sme_update_he_tx_stbc_cap(tHalHandle hal, uint8_t session_id, int value)
+{
+	int ret;
+	uint32_t he_cap_val = 0;
+
+	he_cap_val = value ? 1 : 0;
+
+	ret = sme_update_he_cap(hal, session_id,
+			 WNI_CFG_HE_TX_STBC_LT80, he_cap_val);
+	if (ret)
+		return ret;
+
+	return sme_update_he_cap(hal, session_id,
+			 WNI_CFG_HE_TX_STBC_GT80, he_cap_val);
+}
+
+int sme_update_he_rx_stbc_cap(tHalHandle hal, uint8_t session_id, int value)
+{
+	int ret;
+	uint32_t he_cap_val = 0;
+
+	he_cap_val = value ? 1 : 0;
+
+	ret = sme_update_he_cap(hal, session_id,
+			 WNI_CFG_HE_RX_STBC_LT80, he_cap_val);
+	if (ret)
+		return ret;
+
+	return sme_update_he_cap(hal, session_id,
+			 WNI_CFG_HE_RX_STBC_GT80, he_cap_val);
+}
+
+int sme_update_he_frag_supp(tHalHandle hal, uint8_t session_id,
+		uint16_t he_frag)
+{
+	return sme_update_he_cap(hal, session_id,
+			 WNI_CFG_HE_FRAGMENTATION, he_frag);
+}
+
+int sme_update_he_ldpc_supp(tHalHandle hal, uint8_t session_id,
+			    uint16_t he_ldpc)
+{
+	return sme_update_he_cap(hal, session_id, WNI_CFG_HE_LDPC, he_ldpc);
+}
+#endif
+
+/**
+ * sme_set_nud_debug_stats_cb() - set nud debug stats callback
+ * @hal: global hal handle
+ * @cb: callback function pointer
+ * @context: callback context
+ *
+ * This function stores nud debug stats callback function.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_set_nud_debug_stats_cb(tHalHandle hal,
+				void (*cb)(void *, struct rsp_stats *, void *),
+				void *context)
+{
+	QDF_STATUS status  = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac;
+
+	if (!hal) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("hal is not valid"));
+		return QDF_STATUS_E_INVAL;
+	}
+	mac = PMAC_STRUCT(hal);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("sme_acquire_global_lock failed!(status=%d)"),
+			status);
+		return status;
+	}
+
+	mac->sme.get_arp_stats_cb = cb;
+	mac->sme.get_arp_stats_context = context;
+	sme_release_global_lock(&mac->sme);
+	return status;
+}
+
+/**
+ * sme_is_any_session_in_connected_state() - SME wrapper API to
+ * check if any session is in connected state or not.
+ *
+ * @hal: Handle returned by mac open
+ *
+ * This function is used to check if any valid sme session is in
+ * connected state or not.
+ *
+ * Return: true if any session is connected, else false.
+ *
+ */
+bool sme_is_any_session_in_connected_state(tHalHandle h_hal)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal);
+	QDF_STATUS status;
+	bool ret = false;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		ret = csr_is_any_session_in_connect_state(mac_ctx);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+	return ret;
+}
+
+QDF_STATUS sme_set_chip_pwr_save_fail_cb(mac_handle_t mac_handle,
+					 pwr_save_fail_cb cb)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("sme_AcquireGlobalLock failed!(status=%d)", status);
+		return status;
+	}
+	mac->sme.chip_power_save_fail_cb = cb;
+	sme_release_global_lock(&mac->sme);
+	return status;
+}
+
+#ifdef FEATURE_RSSI_MONITOR
+/**
+ * sme_set_rssi_monitoring() - set rssi monitoring
+ * @hal: global hal handle
+ * @input: request message
+ *
+ * This function constructs the vos message and fill in message type,
+ * bodyptr with @input and posts it to WDA queue.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS sme_set_rssi_monitoring(tHalHandle hal,
+				struct rssi_monitor_req *input)
+{
+	QDF_STATUS status     = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac    = PMAC_STRUCT(hal);
+	struct scheduler_msg message = {0};
+	struct rssi_monitor_req *req_msg;
+
+	SME_ENTER();
+	req_msg = qdf_mem_malloc(sizeof(*req_msg));
+	if (!req_msg)
+		return QDF_STATUS_E_NOMEM;
+
+	*req_msg = *input;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("sme_acquire_global_lock failed!(status=%d)", status);
+		qdf_mem_free(req_msg);
+		return status;
+	}
+
+	/* Serialize the req through MC thread */
+	message.bodyptr = req_msg;
+	message.type    = WMA_SET_RSSI_MONITOR_REQ;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("scheduler_post_msg failed!(err=%d)", status);
+		qdf_mem_free(req_msg);
+	}
+	sme_release_global_lock(&mac->sme);
+
+	return status;
+}
+
+QDF_STATUS sme_set_rssi_threshold_breached_cb(mac_handle_t mac_handle,
+					      rssi_threshold_breached_cb cb)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac;
+
+	mac = MAC_CONTEXT(mac_handle);
+	if (!mac) {
+		sme_err("Invalid mac context");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("sme_acquire_global_lock failed!(status=%d)",
+			status);
+		return status;
+	}
+
+	mac->sme.rssi_threshold_breached_cb = cb;
+	sme_release_global_lock(&mac->sme);
+	return status;
+}
+#endif /* FEATURE_RSSI_MONITOR */
+
+QDF_STATUS sme_reset_rssi_threshold_breached_cb(mac_handle_t mac_handle)
+{
+	return sme_set_rssi_threshold_breached_cb(mac_handle, NULL);
+}
+
+static enum band_info sme_get_connected_roaming_vdev_band(void)
+{
+	enum band_info band = BAND_ALL;
+	tpAniSirGlobal mac = sme_get_mac_context();
+	struct csr_roam_session *session;
+	uint8_t session_id, channel;
+
+	if (!mac) {
+		sme_debug("MAC Context is NULL");
+		return band;
+	}
+	session_id = csr_get_roam_enabled_sta_sessionid(mac);
+	if (session_id != CSR_SESSION_ID_INVALID) {
+		session = CSR_GET_SESSION(mac, session_id);
+		channel = session->connectedProfile.operationChannel;
+		band = csr_get_rf_band(channel);
+		return band;
+	}
+
+	return band;
+}
+
+/*
+ * sme_pdev_set_pcl() - Send WMI_PDEV_SET_PCL_CMDID to the WMA
+ * @hal: Handle returned by macOpen
+ * @msg: PCL channel list and length structure
+ *
+ * Sends the command to WMA to send WMI_PDEV_SET_PCL_CMDID to FW
+ * Return: QDF_STATUS_SUCCESS on successful posting
+ */
+QDF_STATUS sme_pdev_set_pcl(struct policy_mgr_pcl_list *msg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac   = sme_get_mac_context();
+	struct scheduler_msg message = {0};
+	struct set_pcl_req *req_msg;
+	uint32_t i;
+
+	if (!mac) {
+		sme_err("mac is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!msg) {
+		sme_err("msg is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	req_msg = qdf_mem_malloc(sizeof(*req_msg));
+	if (!req_msg)
+		return QDF_STATUS_E_NOMEM;
+
+	req_msg->band = BAND_ALL;
+	if (CSR_IS_ROAM_INTRA_BAND_ENABLED(mac)) {
+		req_msg->band = sme_get_connected_roaming_vdev_band();
+		sme_debug("Connected STA band %d", req_msg->band);
+	}
+	for (i = 0; i < msg->pcl_len; i++) {
+		req_msg->chan_weights.pcl_list[i] =  msg->pcl_list[i];
+		req_msg->chan_weights.weight_list[i] =  msg->weight_list[i];
+	}
+
+	req_msg->chan_weights.pcl_len = msg->pcl_len;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("sme_acquire_global_lock failed!(status=%d)", status);
+		qdf_mem_free(req_msg);
+		return status;
+	}
+
+	/* Serialize the req through MC thread */
+	message.bodyptr = req_msg;
+	message.type    = SIR_HAL_PDEV_SET_PCL_TO_FW;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("scheduler_post_msg failed!(err=%d)", status);
+		qdf_mem_free(req_msg);
+		status = QDF_STATUS_E_FAILURE;
+	}
+	sme_release_global_lock(&mac->sme);
+
+	return status;
+}
+
+/*
+ * sme_pdev_set_hw_mode() - Send WMI_PDEV_SET_HW_MODE_CMDID to the WMA
+ * @hal: Handle returned by macOpen
+ * @msg: HW mode structure containing hw mode and callback details
+ *
+ * Sends the command to CSR to send WMI_PDEV_SET_HW_MODE_CMDID to FW
+ * Return: QDF_STATUS_SUCCESS on successful posting
+ */
+QDF_STATUS sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = sme_get_mac_context();
+	tSmeCmd *cmd = NULL;
+
+	if (!mac) {
+		sme_err("mac is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Failed to acquire lock");
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	cmd = csr_get_command_buffer(mac);
+	if (!cmd) {
+		sme_err("Get command buffer failed");
+		sme_release_global_lock(&mac->sme);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	cmd->command = e_sme_command_set_hw_mode;
+	cmd->sessionId = msg.session_id;
+	cmd->u.set_hw_mode_cmd.hw_mode_index = msg.hw_mode_index;
+	cmd->u.set_hw_mode_cmd.set_hw_mode_cb = msg.set_hw_mode_cb;
+	cmd->u.set_hw_mode_cmd.reason = msg.reason;
+	cmd->u.set_hw_mode_cmd.session_id = msg.session_id;
+	cmd->u.set_hw_mode_cmd.next_action = msg.next_action;
+	cmd->u.set_hw_mode_cmd.context = msg.context;
+
+	sme_debug("Queuing set hw mode to CSR, session: %d reason: %d",
+		cmd->u.set_hw_mode_cmd.session_id,
+		cmd->u.set_hw_mode_cmd.reason);
+	csr_queue_sme_command(mac, cmd, false);
+
+	sme_release_global_lock(&mac->sme);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_register_hw_mode_trans_cb() - HW mode transition callback registration
+ * @hal: Handle returned by macOpen
+ * @callback: HDD callback to be registered
+ *
+ * Registers the HDD callback with SME. This callback will be invoked when
+ * HW mode transition event is received from the FW
+ *
+ * Return: None
+ */
+void sme_register_hw_mode_trans_cb(tHalHandle hal,
+			hw_mode_transition_cb callback)
+{
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+	mac->sme.sme_hw_mode_trans_cb = callback;
+}
+
+/**
+ * sme_nss_update_request() - Send beacon templete update to FW with new
+ * nss value
+ * @hal: Handle returned by macOpen
+ * @vdev_id: the session id
+ * @new_nss: the new nss value
+ * @cback: hdd callback
+ * @next_action: next action to happen at policy mgr after beacon update
+ * @original_vdev_id: original request hwmode change vdev id
+ *
+ * Sends the command to CSR to send to PE
+ * Return: QDF_STATUS_SUCCESS on successful posting
+ */
+QDF_STATUS sme_nss_update_request(uint32_t vdev_id,
+				uint8_t  new_nss, policy_mgr_nss_update_cback cback,
+				uint8_t next_action, struct wlan_objmgr_psoc *psoc,
+				enum policy_mgr_conn_update_reason reason,
+				uint32_t original_vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac = sme_get_mac_context();
+	tSmeCmd *cmd = NULL;
+
+	if (!mac) {
+		sme_err("mac is null");
+		return status;
+	}
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		cmd = csr_get_command_buffer(mac);
+		if (!cmd) {
+			sme_err("Get command buffer failed");
+			sme_release_global_lock(&mac->sme);
+			return QDF_STATUS_E_NULL_VALUE;
+		}
+		cmd->command = e_sme_command_nss_update;
+		/* Sessionized modules may require this info */
+		cmd->sessionId = vdev_id;
+		cmd->u.nss_update_cmd.new_nss = new_nss;
+		cmd->u.nss_update_cmd.session_id = vdev_id;
+		cmd->u.nss_update_cmd.nss_update_cb = cback;
+		cmd->u.nss_update_cmd.context = psoc;
+		cmd->u.nss_update_cmd.next_action = next_action;
+		cmd->u.nss_update_cmd.reason = reason;
+		cmd->u.nss_update_cmd.original_vdev_id = original_vdev_id;
+
+		sme_debug("Queuing e_sme_command_nss_update to CSR:vdev (%d %d) ss %d r %d",
+			  vdev_id, original_vdev_id, new_nss, reason);
+		csr_queue_sme_command(mac, cmd, false);
+		sme_release_global_lock(&mac->sme);
+	}
+	return status;
+}
+
+/**
+ * sme_soc_set_dual_mac_config() - Set dual mac configurations
+ * @hal: Handle returned by macOpen
+ * @msg: Structure containing the dual mac config parameters
+ *
+ * Queues configuration information to CSR to configure
+ * WLAN firmware for the dual MAC features
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_soc_set_dual_mac_config(struct policy_mgr_dual_mac_config msg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = sme_get_mac_context();
+	tSmeCmd *cmd;
+
+	if (!mac) {
+		sme_err("mac is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Failed to acquire lock");
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	cmd = csr_get_command_buffer(mac);
+	if (!cmd) {
+		sme_err("Get command buffer failed");
+		sme_release_global_lock(&mac->sme);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	cmd->command = e_sme_command_set_dual_mac_config;
+	cmd->u.set_dual_mac_cmd.scan_config = msg.scan_config;
+	cmd->u.set_dual_mac_cmd.fw_mode_config = msg.fw_mode_config;
+	cmd->u.set_dual_mac_cmd.set_dual_mac_cb = msg.set_dual_mac_cb;
+
+	sme_debug("set_dual_mac_config scan_config: %x fw_mode_config: %x",
+		cmd->u.set_dual_mac_cmd.scan_config,
+		cmd->u.set_dual_mac_cmd.fw_mode_config);
+	csr_queue_sme_command(mac, cmd, false);
+
+	sme_release_global_lock(&mac->sme);
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+/**
+ * sme_gateway_param_update() - to update gateway parameters with WMA
+ * @Hal: hal handle
+ * @gw_params: request parameters from HDD
+ *
+ * Return: QDF_STATUS
+ *
+ * This routine will update gateway parameters to WMA
+ */
+QDF_STATUS sme_gateway_param_update(tHalHandle Hal,
+			      struct gateway_param_update_req *gw_params)
+{
+	QDF_STATUS qdf_status;
+	struct scheduler_msg message = {0};
+	struct gateway_param_update_req *request_buf;
+
+	request_buf = qdf_mem_malloc(sizeof(*request_buf));
+	if (!request_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	*request_buf = *gw_params;
+
+	message.type = WMA_GW_PARAM_UPDATE_REQ;
+	message.reserved = 0;
+	message.bodyptr = request_buf;
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"Not able to post WMA_GW_PARAM_UPDATE_REQ message to HAL");
+		qdf_mem_free(request_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+
+/**
+ * sme_soc_set_antenna_mode() - set antenna mode
+ * @hal: Handle returned by macOpen
+ * @msg: Structure containing the antenna mode parameters
+ *
+ * Send the command to CSR to send
+ * WMI_SOC_SET_ANTENNA_MODE_CMDID to FW
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_soc_set_antenna_mode(tHalHandle hal,
+				struct sir_antenna_mode_param *msg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	tSmeCmd *cmd;
+
+	if (NULL == msg) {
+		sme_err("antenna mode mesg is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Failed to acquire lock");
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	cmd = csr_get_command_buffer(mac);
+	if (!cmd) {
+		sme_release_global_lock(&mac->sme);
+		sme_err("Get command buffer failed");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	cmd->command = e_sme_command_set_antenna_mode;
+	cmd->u.set_antenna_mode_cmd = *msg;
+
+	sme_debug("Antenna mode rx_chains: %d tx_chains: %d",
+		cmd->u.set_antenna_mode_cmd.num_rx_chains,
+		cmd->u.set_antenna_mode_cmd.num_tx_chains);
+
+	csr_queue_sme_command(mac, cmd, false);
+	sme_release_global_lock(&mac->sme);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_set_peer_authorized() - call peer authorized callback
+ * @peer_addr: peer mac address
+ * @auth_cb: auth callback
+ * @vdev_id: vdev id
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr,
+				   sme_peer_authorized_fp auth_cb,
+				   uint32_t vdev_id)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wma_set_peer_authorized_cb(wma_handle, auth_cb);
+	return wma_set_peer_param(wma_handle, peer_addr, WMI_PEER_AUTHORIZE,
+				  1, vdev_id);
+}
+
+/*
+ * sme_handle_set_fcc_channel() - set spec. tx power for non-fcc channel
+ * @hal: HAL pointer
+ * @fcc_constraint: flag to enable/disable the constraint
+ * @scan_pending: whether there is pending scan
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_handle_set_fcc_channel(tHalHandle hal, bool fcc_constraint,
+				      bool scan_pending)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac_ptr  = PMAC_STRUCT(hal);
+
+	status = sme_acquire_global_lock(&mac_ptr->sme);
+
+	if (QDF_STATUS_SUCCESS == status) {
+
+		if (fcc_constraint != mac_ptr->scan.fcc_constraint) {
+			mac_ptr->scan.fcc_constraint = fcc_constraint;
+			if (scan_pending)
+				mac_ptr->scan.defer_update_channel_list = true;
+			else
+				status = csr_update_channel_list(mac_ptr);
+		}
+
+		sme_release_global_lock(&mac_ptr->sme);
+	}
+
+	return status;
+}
+/**
+ * sme_setdef_dot11mode() - Updates pMac with default dot11mode
+ * @hal: Global MAC pointer
+ *
+ * Return: NULL.
+ */
+void sme_setdef_dot11mode(tHalHandle hal)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	csr_set_default_dot11_mode(mac_ctx);
+}
+
+/**
+ * sme_update_roam_scan_hi_rssi_scan_params() - update high rssi scan
+ *         params
+ * @hal_handle - The handle returned by macOpen.
+ * @session_id - Session Identifier
+ * @notify_id - Identifies 1 of the 4 parameters to be modified
+ * @val New value of the parameter
+ *
+ * Return: QDF_STATUS - SME update config successful.
+ *         Other status means SME failed to update
+ */
+
+QDF_STATUS sme_update_roam_scan_hi_rssi_scan_params(tHalHandle hal_handle,
+	uint8_t session_id,
+	uint32_t notify_id,
+	int32_t val)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
+	QDF_STATUS status  = QDF_STATUS_SUCCESS;
+	struct csr_neighbor_roamconfig *nr_config = NULL;
+	tpCsrNeighborRoamControlInfo nr_info = NULL;
+	uint32_t reason = 0;
+
+	if (session_id >= CSR_ROAM_SESSION_MAX) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid sme session id: %d"), session_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		nr_config = &mac_ctx->roam.configParam.neighborRoamConfig;
+		nr_info   = &mac_ctx->roam.neighborRoamInfo[session_id];
+		switch (notify_id) {
+		case eCSR_HI_RSSI_SCAN_MAXCOUNT_ID:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"%s: gRoamScanHirssiMaxCount %d => %d",
+				__func__, nr_config->nhi_rssi_scan_max_count,
+				val);
+			nr_config->nhi_rssi_scan_max_count = val;
+			nr_info->cfgParams.hi_rssi_scan_max_count = val;
+			reason = REASON_ROAM_SCAN_HI_RSSI_MAXCOUNT_CHANGED;
+		break;
+
+		case eCSR_HI_RSSI_SCAN_RSSI_DELTA_ID:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				FL("gRoamScanHiRssiDelta %d => %d"),
+				nr_config->nhi_rssi_scan_rssi_delta,
+				val);
+			nr_config->nhi_rssi_scan_rssi_delta = val;
+			nr_info->cfgParams.hi_rssi_scan_rssi_delta = val;
+			reason = REASON_ROAM_SCAN_HI_RSSI_DELTA_CHANGED;
+			break;
+
+		case eCSR_HI_RSSI_SCAN_DELAY_ID:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				FL("gRoamScanHiRssiDelay %d => %d"),
+				nr_config->nhi_rssi_scan_delay,
+				val);
+			nr_config->nhi_rssi_scan_delay = val;
+			nr_info->cfgParams.hi_rssi_scan_delay = val;
+			reason = REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED;
+			break;
+
+		case eCSR_HI_RSSI_SCAN_RSSI_UB_ID:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				FL("gRoamScanHiRssiUpperBound %d => %d"),
+				nr_config->nhi_rssi_scan_rssi_ub,
+				val);
+			nr_config->nhi_rssi_scan_rssi_ub = val;
+			nr_info->cfgParams.hi_rssi_scan_rssi_ub = val;
+			reason = REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED;
+			break;
+
+		default:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				FL("invalid parameter notify_id %d"),
+				notify_id);
+			status = QDF_STATUS_E_INVAL;
+			break;
+		}
+
+		if (mac_ctx->roam.configParam.isRoamOffloadScanEnabled &&
+		    status == QDF_STATUS_SUCCESS) {
+			csr_roam_offload_scan(mac_ctx, session_id,
+				ROAM_SCAN_OFFLOAD_UPDATE_CFG, reason);
+		}
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+
+	return status;
+}
+
+/**
+ * sme_update_tgt_services() - update the target services config.
+ * @hal: HAL pointer.
+ * @cfg: wma_tgt_services parameters.
+ *
+ * update the target services config.
+ *
+ * Return: None.
+ */
+void sme_update_tgt_services(tHalHandle hal, struct wma_tgt_services *cfg)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	mac_ctx->obss_scan_offload = cfg->obss_scan_offload;
+	sme_debug("obss_scan_offload: %d", mac_ctx->obss_scan_offload);
+	mac_ctx->lteCoexAntShare = cfg->lte_coex_ant_share;
+	mac_ctx->beacon_offload = cfg->beacon_offload;
+	mac_ctx->pmf_offload = cfg->pmf_offload;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL("mac_ctx->pmf_offload: %d"), mac_ctx->pmf_offload);
+	mac_ctx->is_fils_roaming_supported =
+				cfg->is_fils_roaming_supported;
+	mac_ctx->is_11k_offload_supported =
+				cfg->is_11k_offload_supported;
+	sme_debug("pmf_offload: %d fils_roam support %d 11k_offload %d",
+		  mac_ctx->pmf_offload, mac_ctx->is_fils_roaming_supported,
+		  mac_ctx->is_11k_offload_supported);
+}
+
+/**
+ * sme_is_session_id_valid() - Check if the session id is valid
+ * @hal: Pointer to HAL
+ * @session_id: Session id
+ *
+ * Checks if the session id is valid or not
+ *
+ * Return: True is the session id is valid, false otherwise
+ */
+bool sme_is_session_id_valid(tHalHandle hal, uint32_t session_id)
+{
+	tpAniSirGlobal mac;
+
+	if (NULL != hal) {
+		mac = PMAC_STRUCT(hal);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: null mac pointer", __func__);
+		return false;
+	}
+
+	if (CSR_IS_SESSION_VALID(mac, session_id))
+		return true;
+
+	return false;
+}
+
+#ifdef FEATURE_WLAN_TDLS
+
+/**
+ * sme_get_opclass() - determine operating class
+ * @hal: Pointer to HAL
+ * @channel: channel id
+ * @bw_offset: bandwidth offset
+ * @opclass: pointer to operating class
+ *
+ * Function will determine operating class from regdm_get_opclass_from_channel
+ *
+ * Return: none
+ */
+void sme_get_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset,
+		uint8_t *opclass)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	/* redgm opclass table contains opclass for 40MHz low primary,
+	 * 40MHz high primary and 20MHz. No support for 80MHz yet. So
+	 * first we will check if bit for 40MHz is set and if so find
+	 * matching opclass either with low primary or high primary
+	 * (a channel would never be in both) and then search for opclass
+	 * matching 20MHz, else for any BW.
+	 */
+	if (bw_offset & (1 << BW_40_OFFSET_BIT)) {
+		*opclass = wlan_reg_dmn_get_opclass_from_channel(
+				mac_ctx->scan.countryCodeCurrent,
+				channel, BW40_LOW_PRIMARY);
+		if (!(*opclass)) {
+			*opclass = wlan_reg_dmn_get_opclass_from_channel(
+					mac_ctx->scan.countryCodeCurrent,
+					channel, BW40_HIGH_PRIMARY);
+		}
+	} else if (bw_offset & (1 << BW_20_OFFSET_BIT)) {
+		*opclass = wlan_reg_dmn_get_opclass_from_channel(
+				mac_ctx->scan.countryCodeCurrent,
+				channel, BW20);
+	} else {
+		*opclass = wlan_reg_dmn_get_opclass_from_channel(
+				mac_ctx->scan.countryCodeCurrent,
+				channel, BWALL);
+	}
+}
+#endif
+
+/**
+ * sme_set_fw_test() - set fw test
+ * @fw_test: fw test param
+ *
+ * Return: Return QDF_STATUS, otherwise appropriate failure code
+ */
+QDF_STATUS sme_set_fw_test(struct set_fwtest_params *fw_test)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	wma_process_fw_test_cmd(wma_handle, fw_test);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_ht40_stop_obss_scan() - ht40 obss stop scan
+ * @hal: mac handel
+ * @vdev_id: vdev identifier
+ *
+ * Return: Return QDF_STATUS, otherwise appropriate failure code
+ */
+QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hal, uint32_t vdev_id)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	wma_ht40_stop_obss_scan(wma_handle, vdev_id);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_update_mimo_power_save() - Update MIMO power save
+ * configuration
+ * @hal: The handle returned by macOpen
+ * @is_ht_smps_enabled: enable/disable ht smps
+ * @ht_smps_mode: smps mode disabled/static/dynamic
+ * @send_smps_action: flag to send smps force mode command
+ * to FW
+ *
+ * Return: QDF_STATUS if SME update mimo power save
+ * configuration success else failure status
+ */
+QDF_STATUS sme_update_mimo_power_save(tHalHandle hal,
+				      uint8_t is_ht_smps_enabled,
+				      uint8_t ht_smps_mode,
+				      bool send_smps_action)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	sme_debug("SMPS enable: %d mode: %d send action: %d",
+		is_ht_smps_enabled, ht_smps_mode,
+		send_smps_action);
+	mac_ctx->mlme_cfg->ht_caps.enable_smps =
+		is_ht_smps_enabled;
+	mac_ctx->mlme_cfg->ht_caps.smps = ht_smps_mode;
+	mac_ctx->roam.configParam.send_smps_action =
+		send_smps_action;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_is_sta_smps_allowed() - check if the supported nss for
+ * the session is greater than 1x1 to enable sta SMPS
+ * @hal: The handle returned by macOpen
+ * @session_id: session id
+ *
+ * Return: bool returns true if supported nss is greater than
+ * 1x1 else false
+ */
+bool sme_is_sta_smps_allowed(tHalHandle hal, uint8_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct csr_roam_session *csr_session;
+
+	csr_session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (NULL == csr_session) {
+		sme_err("SME session not valid: %d", session_id);
+		return false;
+	}
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("CSR session not valid: %d", session_id);
+		return false;
+	}
+
+	return (csr_session->supported_nss_1x1 == true) ? false : true;
+}
+
+/**
+ * sme_add_beacon_filter() - set the beacon filter configuration
+ * @hal: The handle returned by macOpen
+ * @session_id: session id
+ * @ie_map: bitwise array of IEs
+ *
+ * Return: Return QDF_STATUS, otherwise appropriate failure code
+ */
+QDF_STATUS sme_add_beacon_filter(tHalHandle hal,
+				 uint32_t session_id,
+				 uint32_t *ie_map)
+{
+	struct scheduler_msg message = {0};
+	QDF_STATUS qdf_status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct beacon_filter_param *filter_param;
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("CSR session not valid: %d", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	filter_param = qdf_mem_malloc(sizeof(*filter_param));
+	if (!filter_param)
+		return QDF_STATUS_E_FAILURE;
+
+	filter_param->vdev_id = session_id;
+
+	qdf_mem_copy(filter_param->ie_map, ie_map,
+			BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(uint32_t));
+
+	message.type = WMA_ADD_BCN_FILTER_CMDID;
+	message.bodyptr = filter_param;
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_WMA,
+					    &message);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: Not able to post msg to WDA!",
+			__func__);
+
+		qdf_mem_free(filter_param);
+	}
+	return qdf_status;
+}
+
+/**
+ * sme_remove_beacon_filter() - set the beacon filter configuration
+ * @hal: The handle returned by macOpen
+ * @session_id: session id
+ *
+ * Return: Return QDF_STATUS, otherwise appropriate failure code
+ */
+QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id)
+{
+	struct scheduler_msg message = {0};
+	QDF_STATUS qdf_status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct beacon_filter_param *filter_param;
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("CSR session not valid: %d", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	filter_param = qdf_mem_malloc(sizeof(*filter_param));
+	if (!filter_param)
+		return QDF_STATUS_E_FAILURE;
+
+	filter_param->vdev_id = session_id;
+
+	message.type = WMA_REMOVE_BCN_FILTER_CMDID;
+	message.bodyptr = filter_param;
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_WMA,
+					    &message);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: Not able to post msg to WDA!",
+			__func__);
+
+		qdf_mem_free(filter_param);
+	}
+	return qdf_status;
+}
+
+/**
+ * sme_send_disassoc_req_frame - send disassoc req
+ * @hal: handler to hal
+ * @session_id: session id
+ * @peer_mac: peer mac address
+ * @reason: reason for disassociation
+ * wait_for_ack: wait for acknowledgment
+ *
+ * function to send disassoc request to lim
+ *
+ * return: none
+ */
+void sme_send_disassoc_req_frame(tHalHandle hal, uint8_t session_id,
+		uint8_t *peer_mac, uint16_t reason, uint8_t wait_for_ack)
+{
+	struct sme_send_disassoc_frm_req *msg;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	A_UINT8  *buf;
+	A_UINT16 tmp;
+
+	msg = qdf_mem_malloc(sizeof(struct sme_send_disassoc_frm_req));
+	if (!msg)
+		return;
+
+	msg->msg_type = (uint16_t) eWNI_SME_SEND_DISASSOC_FRAME;
+
+	msg->length = (uint16_t) sizeof(struct sme_send_disassoc_frm_req);
+
+	buf = &msg->session_id;
+
+	/* session id */
+	*buf = (A_UINT8) session_id;
+	buf += sizeof(A_UINT8);
+
+	/* transaction id */
+	*buf = 0;
+	*(buf + 1) = 0;
+	buf += sizeof(A_UINT16);
+
+	/* Set the peer MAC address before sending the message to LIM */
+	qdf_mem_copy(buf, peer_mac, QDF_MAC_ADDR_SIZE);
+
+	buf += QDF_MAC_ADDR_SIZE;
+
+	/* reasoncode */
+	tmp = (uint16_t) reason;
+	qdf_mem_copy(buf, &tmp, sizeof(uint16_t));
+	buf += sizeof(uint16_t);
+
+	*buf =  wait_for_ack;
+	buf += sizeof(uint8_t);
+
+	qdf_status = umac_send_mb_message_to_mac(msg);
+
+	if (qdf_status != QDF_STATUS_SUCCESS)
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("cds_send_mb_message Failed"));
+}
+
+#ifdef FEATURE_WLAN_APF
+QDF_STATUS sme_get_apf_capabilities(tHalHandle hal,
+				    apf_get_offload_cb callback,
+				    void *context)
+{
+	QDF_STATUS          status     = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal      mac_ctx      = PMAC_STRUCT(hal);
+	struct scheduler_msg           cds_msg = {0};
+
+	SME_ENTER();
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		/* Serialize the req through MC thread */
+		mac_ctx->sme.apf_get_offload_cb = callback;
+		mac_ctx->sme.apf_get_offload_context = context;
+		cds_msg.bodyptr = NULL;
+		cds_msg.type = WDA_APF_GET_CAPABILITIES_REQ;
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &cds_msg);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+					FL("Post apf get offload msg fail"));
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&mac_ctx->sme);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("sme_acquire_global_lock error"));
+	}
+	SME_EXIT();
+	return status;
+}
+
+QDF_STATUS sme_set_apf_instructions(tHalHandle hal,
+				    struct sir_apf_set_offload *req)
+{
+	QDF_STATUS          status     = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal      mac_ctx    = PMAC_STRUCT(hal);
+	struct scheduler_msg           cds_msg = {0};
+	struct sir_apf_set_offload *set_offload;
+
+	set_offload = qdf_mem_malloc(sizeof(*set_offload) +
+					req->current_length);
+	if (!set_offload)
+		return QDF_STATUS_E_NOMEM;
+
+	set_offload->session_id = req->session_id;
+	set_offload->filter_id = req->filter_id;
+	set_offload->current_offset = req->current_offset;
+	set_offload->total_length = req->total_length;
+	set_offload->current_length = req->current_length;
+	if (set_offload->total_length) {
+		set_offload->program = ((uint8_t *)set_offload) +
+					sizeof(*set_offload);
+		qdf_mem_copy(set_offload->program, req->program,
+				set_offload->current_length);
+	}
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		/* Serialize the req through MC thread */
+		cds_msg.bodyptr = set_offload;
+		cds_msg.type = WDA_APF_SET_INSTRUCTIONS_REQ;
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &cds_msg);
+
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("Post APF set offload msg fail"));
+			status = QDF_STATUS_E_FAILURE;
+			qdf_mem_free(set_offload);
+		}
+		sme_release_global_lock(&mac_ctx->sme);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("sme_acquire_global_lock failed"));
+		qdf_mem_free(set_offload);
+	}
+	return status;
+}
+
+QDF_STATUS sme_set_apf_enable_disable(tHalHandle hal, uint8_t vdev_id,
+				      bool apf_enable)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wma_send_apf_enable_cmd(wma_handle, vdev_id, apf_enable);
+}
+
+QDF_STATUS
+sme_apf_write_work_memory(tHalHandle hal,
+			struct wmi_apf_write_memory_params *write_params)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wma_send_apf_write_work_memory_cmd(wma_handle, write_params);
+}
+
+QDF_STATUS
+sme_apf_read_work_memory(tHalHandle hal,
+			 struct wmi_apf_read_memory_params *read_params,
+			 apf_read_mem_cb callback)
+{
+	QDF_STATUS status   = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac  = PMAC_STRUCT(hal);
+	void *wma_handle;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.apf_read_mem_cb = callback;
+		sme_release_global_lock(&mac->sme);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("sme_acquire_global_lock failed"));
+	}
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wma_send_apf_read_work_memory_cmd(wma_handle, read_params);
+}
+#endif /* FEATURE_WLAN_APF */
+
+/**
+ * sme_get_wni_dot11_mode() - return configured wni dot11mode
+ * @hal: hal pointer
+ *
+ * Return: wni dot11 mode.
+ */
+uint32_t sme_get_wni_dot11_mode(tHalHandle hal)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	return csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
+		mac_ctx->roam.configParam.uCfgDot11Mode);
+}
+
+/**
+ * sme_create_mon_session() - post message to create PE session for monitormode
+ * operation
+ * @hal_handle: Handle to the HAL
+ * @bssid: pointer to bssid
+ * @vdev_id: sme session id
+ *
+ * Return: QDF_STATUS_SUCCESS on success, non-zero error code on failure.
+ */
+QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, tSirMacAddr bss_id,
+				  uint8_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct sir_create_session *msg;
+
+	msg = qdf_mem_malloc(sizeof(*msg));
+	if (msg) {
+		msg->type = eWNI_SME_MON_INIT_SESSION;
+		msg->vdev_id = vdev_id;
+		msg->msg_len = sizeof(*msg);
+		qdf_mem_copy(msg->bss_id.bytes, bss_id, QDF_MAC_ADDR_SIZE);
+		status = umac_send_mb_message_to_mac(msg);
+	}
+	return status;
+}
+
+void sme_set_chan_info_callback(tHalHandle hal_handle,
+			void (*callback)(struct scan_chan_info *chan_info))
+{
+	tpAniSirGlobal mac;
+
+	if (hal_handle == NULL) {
+		QDF_ASSERT(0);
+		return;
+	}
+	mac = PMAC_STRUCT(hal_handle);
+	mac->chan_info_cb = callback;
+}
+
+/**
+ * sme_set_adaptive_dwelltime_config() - Update Adaptive dwelltime configuration
+ * @hal: The handle returned by macOpen
+ * @params: adaptive_dwelltime_params config
+ *
+ * Return: QDF_STATUS if adaptive dwell time update
+ * configuration success else failure status
+ */
+QDF_STATUS sme_set_adaptive_dwelltime_config(tHalHandle hal,
+			struct adaptive_dwelltime_params *params)
+{
+	struct scheduler_msg message = {0};
+	QDF_STATUS status;
+	struct adaptive_dwelltime_params *dwelltime_params;
+
+	dwelltime_params = qdf_mem_malloc(sizeof(*dwelltime_params));
+	if (!dwelltime_params)
+		return QDF_STATUS_E_NOMEM;
+
+	dwelltime_params->is_enabled = params->is_enabled;
+	dwelltime_params->dwelltime_mode = params->dwelltime_mode;
+	dwelltime_params->lpf_weight = params->lpf_weight;
+	dwelltime_params->passive_mon_intval = params->passive_mon_intval;
+	dwelltime_params->wifi_act_threshold = params->wifi_act_threshold;
+
+	message.type = WMA_SET_ADAPT_DWELLTIME_CONF_PARAMS;
+	message.bodyptr = dwelltime_params;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: Not able to post msg to WMA!", __func__);
+
+		qdf_mem_free(dwelltime_params);
+	}
+	return status;
+}
+
+/**
+ * sme_set_vdev_ies_per_band() - sends the per band IEs to vdev
+ * @hal: Pointer to HAL
+ * @vdev_id: vdev_id for which IE is targeted
+ *
+ * Return: None
+ */
+void sme_set_vdev_ies_per_band(tHalHandle hal, uint8_t vdev_id)
+{
+	struct sir_set_vdev_ies_per_band *p_msg;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	p_msg = qdf_mem_malloc(sizeof(*p_msg));
+	if (!p_msg)
+		return;
+
+	p_msg->vdev_id = vdev_id;
+	p_msg->msg_type = eWNI_SME_SET_VDEV_IES_PER_BAND;
+	p_msg->len = sizeof(*p_msg);
+	sme_debug("sending eWNI_SME_SET_VDEV_IES_PER_BAND: vdev_id: %d",
+		vdev_id);
+	status = umac_send_mb_message_to_mac(p_msg);
+	if (QDF_STATUS_SUCCESS != status)
+		sme_err("Send eWNI_SME_SET_VDEV_IES_PER_BAND fail");
+}
+
+/**
+ * sme_set_pdev_ht_vht_ies() - sends the set pdev IE req
+ * @hal: Pointer to HAL
+ * @enable2x2: 1x1 or 2x2 mode.
+ *
+ * Sends the set pdev IE req with Nss value.
+ *
+ * Return: None
+ */
+void sme_set_pdev_ht_vht_ies(tHalHandle hal, bool enable2x2)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct sir_set_ht_vht_cfg *ht_vht_cfg;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!((mac_ctx->roam.configParam.uCfgDot11Mode ==
+					eCSR_CFG_DOT11_MODE_AUTO) ||
+				(mac_ctx->roam.configParam.uCfgDot11Mode ==
+				 eCSR_CFG_DOT11_MODE_11N) ||
+				(mac_ctx->roam.configParam.uCfgDot11Mode ==
+				 eCSR_CFG_DOT11_MODE_11N_ONLY) ||
+				(mac_ctx->roam.configParam.uCfgDot11Mode ==
+				 eCSR_CFG_DOT11_MODE_11AC) ||
+				(mac_ctx->roam.configParam.uCfgDot11Mode ==
+				 eCSR_CFG_DOT11_MODE_11AC_ONLY)))
+		return;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		ht_vht_cfg = qdf_mem_malloc(sizeof(*ht_vht_cfg));
+		if (!ht_vht_cfg) {
+			sme_release_global_lock(&mac_ctx->sme);
+			return;
+		}
+
+		ht_vht_cfg->pdev_id = 0;
+		if (enable2x2)
+			ht_vht_cfg->nss = 2;
+		else
+			ht_vht_cfg->nss = 1;
+		ht_vht_cfg->dot11mode =
+			(uint8_t)csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
+				mac_ctx->roam.configParam.uCfgDot11Mode);
+
+		ht_vht_cfg->msg_type = eWNI_SME_PDEV_SET_HT_VHT_IE;
+		ht_vht_cfg->len = sizeof(*ht_vht_cfg);
+		sme_debug("SET_HT_VHT_IE with nss: %d, dot11mode: %d",
+			  ht_vht_cfg->nss,
+			  ht_vht_cfg->dot11mode);
+		status = umac_send_mb_message_to_mac(ht_vht_cfg);
+		if (QDF_STATUS_SUCCESS != status)
+			sme_err("Send SME_PDEV_SET_HT_VHT_IE fail");
+
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+}
+
+/**
+ * sme_update_vdev_type_nss() - sets the nss per vdev type
+ * @hal: Pointer to HAL
+ * @max_supp_nss: max_supported Nss
+ * @band: 5G or 2.4G band
+ *
+ * Sets the per band Nss for each vdev type based on INI and configured
+ * chain mask value.
+ *
+ * Return: None
+ */
+void sme_update_vdev_type_nss(tHalHandle hal, uint8_t max_supp_nss,
+		uint32_t vdev_type_nss, enum band_info band)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct vdev_type_nss *vdev_nss;
+
+	if (BAND_5G == band)
+		vdev_nss = &mac_ctx->vdev_type_nss_5g;
+	else
+		vdev_nss = &mac_ctx->vdev_type_nss_2g;
+
+	vdev_nss->sta = QDF_MIN(max_supp_nss, CFG_STA_NSS(vdev_type_nss));
+	vdev_nss->sap = QDF_MIN(max_supp_nss, CFG_SAP_NSS(vdev_type_nss));
+	vdev_nss->p2p_go = QDF_MIN(max_supp_nss,
+				CFG_P2P_GO_NSS(vdev_type_nss));
+	vdev_nss->p2p_cli = QDF_MIN(max_supp_nss,
+				CFG_P2P_CLI_NSS(vdev_type_nss));
+	vdev_nss->p2p_dev = QDF_MIN(max_supp_nss,
+				CFG_P2P_DEV_NSS(vdev_type_nss));
+	vdev_nss->ibss = QDF_MIN(max_supp_nss, CFG_IBSS_NSS(vdev_type_nss));
+	vdev_nss->tdls = QDF_MIN(max_supp_nss, CFG_TDLS_NSS(vdev_type_nss));
+	vdev_nss->ocb = QDF_MIN(max_supp_nss, CFG_OCB_NSS(vdev_type_nss));
+
+	sme_debug("band %d NSS:sta %d sap %d cli %d go %d dev %d ibss %d tdls %d ocb %d",
+		band, vdev_nss->sta, vdev_nss->sap, vdev_nss->p2p_cli,
+		vdev_nss->p2p_go, vdev_nss->p2p_dev, vdev_nss->ibss,
+		vdev_nss->tdls, vdev_nss->ocb);
+}
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+#define MAX_BSS_COLOR_VAL 63
+#define MIN_BSS_COLOR_VAL 1
+
+QDF_STATUS sme_set_he_bss_color(tHalHandle hal, uint8_t session_id,
+		uint8_t bss_color)
+
+{
+	struct sir_set_he_bss_color *bss_color_msg;
+	uint8_t len;
+
+	if (!hal) {
+		sme_err("Invalid hal pointer");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	sme_debug("Set HE bss_color  %d", bss_color);
+
+	if (bss_color < MIN_BSS_COLOR_VAL || bss_color > MAX_BSS_COLOR_VAL) {
+		sme_debug("Invalid HE bss_color  %d", bss_color);
+		return QDF_STATUS_E_INVAL;
+	}
+	len = sizeof(*bss_color_msg);
+	bss_color_msg = qdf_mem_malloc(len);
+	if (!bss_color_msg)
+		return QDF_STATUS_E_NOMEM;
+
+	bss_color_msg->message_type = eWNI_SME_SET_HE_BSS_COLOR;
+	bss_color_msg->length = len;
+	bss_color_msg->session_id = session_id;
+	bss_color_msg->bss_color = bss_color;
+	return umac_send_mb_message_to_mac(bss_color_msg);
+}
+#endif
+
+/**
+ * sme_update_hw_dbs_capable() - sets the HW DBS capability
+ * @hal: Pointer to HAL
+ * @hw_dbs_capable: HW DBS capability
+ *
+ * Sets HW DBS capability based on INI and fw capability.
+ *
+ * Return: None
+ */
+void sme_update_hw_dbs_capable(tHalHandle hal, uint8_t hw_dbs_capable)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	mac_ctx->hw_dbs_capable = hw_dbs_capable;
+}
+
+#ifdef FEATURE_P2P_LISTEN_OFFLOAD
+/**
+ * sme_register_p2p_lo_event() - Register for the p2p lo event
+ * @hHal: reference to the HAL
+ * @context: the context of the call
+ * @callback: the callback to hdd
+ *
+ * This function registers the callback function for P2P listen
+ * offload stop event.
+ *
+ * Return: none
+ */
+void sme_register_p2p_lo_event(tHalHandle hHal, void *context,
+			       p2p_lo_callback callback)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	pMac->sme.p2p_lo_event_callback = callback;
+	pMac->sme.p2p_lo_event_context = context;
+	sme_release_global_lock(&pMac->sme);
+}
+#endif
+
+/**
+ * sme_process_mac_pwr_dbg_cmd() - enable mac pwr debugging
+ * @hal: The handle returned by macOpen
+ * @session_id: session id
+ * @dbg_args: args for mac pwr debug command
+ * Return: Return QDF_STATUS, otherwise appropriate failure code
+ */
+QDF_STATUS sme_process_mac_pwr_dbg_cmd(tHalHandle hal, uint32_t session_id,
+				       struct sir_mac_pwr_dbg_cmd*
+				       dbg_args)
+{
+	struct scheduler_msg message = {0};
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct sir_mac_pwr_dbg_cmd *req;
+	int i;
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("CSR session not valid: %d", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return QDF_STATUS_E_FAILURE;
+
+	req->module_id = dbg_args->module_id;
+	req->pdev_id = dbg_args->pdev_id;
+	req->num_args = dbg_args->num_args;
+	for (i = 0; i < req->num_args; i++)
+		req->args[i] = dbg_args->args[i];
+
+	message.type = SIR_HAL_POWER_DBG_CMD;
+	message.bodyptr = req;
+
+	if (!QDF_IS_STATUS_SUCCESS(scheduler_post_message(QDF_MODULE_ID_SME,
+							  QDF_MODULE_ID_WMA,
+							  QDF_MODULE_ID_WMA,
+							  &message))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Not able to post msg to WDA!",
+			  __func__);
+		qdf_mem_free(req);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+/**
+ * sme_get_vdev_type_nss() - gets the nss per vdev type
+ * @dev_mode: connection type.
+ * @nss2g: Pointer to the 2G Nss parameter.
+ * @nss5g: Pointer to the 5G Nss parameter.
+ *
+ * Fills the 2G and 5G Nss values based on connection type.
+ *
+ * Return: None
+ */
+void sme_get_vdev_type_nss(enum QDF_OPMODE dev_mode,
+			   uint8_t *nss_2g, uint8_t *nss_5g)
+{
+	tpAniSirGlobal mac_ctx = sme_get_mac_context();
+
+	if (NULL == mac_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+		FL("Invalid MAC context"));
+		return;
+	}
+	csr_get_vdev_type_nss(mac_ctx, dev_mode, nss_2g, nss_5g);
+}
+
+/**
+ * sme_update_sta_roam_policy() - update sta roam policy for
+ * unsafe and DFS channels.
+ * @hal_handle: hal handle for getting global mac struct
+ * @dfs_mode: dfs mode which tell if dfs channel needs to be
+ * skipped or not
+ * @skip_unsafe_channels: Param to tell if driver needs to
+ * skip unsafe channels or not.
+ * @param session_id: sme_session_id
+ * @sap_operating_band: Band on which SAP is operating
+ *
+ * sme_update_sta_roam_policy update sta rome policies to csr
+ * this function will call csrUpdateChannelList as well
+ * to include/exclude DFS channels and unsafe channels.
+ *
+ * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
+ */
+QDF_STATUS sme_update_sta_roam_policy(tHalHandle hal_handle,
+		enum sta_roam_policy_dfs_mode dfs_mode,
+		bool skip_unsafe_channels,
+		uint8_t session_id, uint8_t sap_operating_band)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeConfigParams *sme_config;
+
+	if (!mac_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
+				"%s: mac_ctx is null", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_config = qdf_mem_malloc(sizeof(*sme_config));
+	if (!sme_config)
+		return QDF_STATUS_E_FAILURE;
+
+	qdf_mem_zero(sme_config, sizeof(*sme_config));
+	sme_get_config_param(hal_handle, sme_config);
+
+	sme_config->csrConfig.sta_roam_policy_params.dfs_mode =
+		dfs_mode;
+	sme_config->csrConfig.sta_roam_policy_params.skip_unsafe_channels =
+		skip_unsafe_channels;
+	sme_config->csrConfig.sta_roam_policy_params.sap_operating_band =
+		sap_operating_band;
+
+	sme_update_config(hal_handle, sme_config);
+
+	status = csr_update_channel_list(mac_ctx);
+	if (QDF_STATUS_SUCCESS != status) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("failed to update the supported channel list"));
+	}
+
+	if (mac_ctx->roam.configParam.isRoamOffloadScanEnabled) {
+		status = sme_acquire_global_lock(&mac_ctx->sme);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			csr_roam_offload_scan(mac_ctx, session_id,
+				ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED);
+			sme_release_global_lock(&mac_ctx->sme);
+		} else {
+			sme_err("Failed to acquire SME lock");
+		}
+	}
+	qdf_mem_free(sme_config);
+	return status;
+}
+
+/**
+ * sme_enable_disable_chanavoidind_event - configure ca event ind
+ * @hal: handler to hal
+ * @set_value: enable/disable
+ *
+ * function to enable/disable chan avoidance indication
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_enable_disable_chanavoidind_event(tHalHandle hal,
+		uint8_t set_value)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct scheduler_msg msg = {0};
+
+	if (!mac_ctx->mlme_cfg->gen.optimize_ca_event) {
+		sme_err("optimize_ca_event not enabled in ini");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	sme_debug("set_value: %d", set_value);
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		qdf_mem_zero(&msg, sizeof(struct scheduler_msg));
+		msg.type = WMA_SEND_FREQ_RANGE_CONTROL_IND;
+		msg.bodyval = set_value;
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &msg);
+		sme_release_global_lock(&mac_ctx->sme);
+		return status;
+	}
+	return status;
+}
+
+/*
+ * sme_set_default_scan_ie() - API to send default scan IE to LIM
+ * @hal: reference to the HAL
+ * @session_id: current session ID
+ * @ie_data: Pointer to Scan IE data
+ * @ie_len: Length of @ie_data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_default_scan_ie(tHalHandle hal, uint16_t session_id,
+					uint8_t *ie_data, uint16_t ie_len)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct hdd_default_scan_ie *set_ie_params;
+
+	if (!ie_data)
+		return QDF_STATUS_E_INVAL;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		set_ie_params = qdf_mem_malloc(sizeof(*set_ie_params));
+		if (!set_ie_params)
+			status = QDF_STATUS_E_NOMEM;
+		else {
+			set_ie_params->message_type = eWNI_SME_DEFAULT_SCAN_IE;
+			set_ie_params->length = sizeof(*set_ie_params);
+			set_ie_params->session_id = session_id;
+			set_ie_params->ie_len = ie_len;
+			qdf_mem_copy(set_ie_params->ie_data, ie_data, ie_len);
+			status = umac_send_mb_message_to_mac(set_ie_params);
+		}
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+	return status;
+}
+
+QDF_STATUS sme_get_sar_power_limits(tHalHandle hal,
+				    wma_sar_cb callback, void *context)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wma_get_sar_limit(wma_handle, callback, context);
+}
+
+QDF_STATUS sme_set_sar_power_limits(tHalHandle hal,
+				    struct sar_limit_cmd_params *sar_limit_cmd)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wma_set_sar_limit(wma_handle, sar_limit_cmd);
+}
+
+QDF_STATUS sme_send_coex_config_cmd(struct coex_config_params *coex_cfg_params)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		sme_err("wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	return wma_send_coex_config_cmd(wma_handle, coex_cfg_params);
+}
+
+#ifdef WLAN_FEATURE_FIPS
+QDF_STATUS sme_fips_request(tHalHandle hal, struct fips_params *param,
+			    wma_fips_cb callback, void *context)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		sme_err("wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wma_fips_request(wma_handle, param, callback, context);
+}
+#endif
+
+QDF_STATUS sme_set_cts2self_for_p2p_go(tHalHandle hal_handle)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma_handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (QDF_STATUS_SUCCESS !=
+		wma_set_cts2self_for_p2p_go(wma_handle, true)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: Failed to set cts2self for p2p GO to firmware",
+			__func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_update_tx_fail_cnt_threshold() - update tx fail count Threshold
+ * @hal: Handle returned by mac_open
+ * @session_id: Session ID on which tx fail count needs to be updated to FW
+ * @tx_fail_count: Count for tx fail threshold after which FW will disconnect
+ *
+ * This function is used to set tx fail count threshold to firmware.
+ * firmware will issue disocnnect with peer device once this threshold is
+ * reached.
+ *
+ * Return: Return QDF_STATUS, otherwise appropriate failure code
+ */
+QDF_STATUS sme_update_tx_fail_cnt_threshold(tHalHandle hal_handle,
+				uint8_t session_id, uint32_t tx_fail_count)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct sme_tx_fail_cnt_threshold *tx_fail_cnt;
+	struct scheduler_msg msg = {0};
+
+	tx_fail_cnt = qdf_mem_malloc(sizeof(*tx_fail_cnt));
+	if (!tx_fail_cnt)
+		return QDF_STATUS_E_FAILURE;
+
+	sme_debug("session_id: %d tx_fail_count: %d",
+		  session_id, tx_fail_count);
+	tx_fail_cnt->session_id = session_id;
+	tx_fail_cnt->tx_fail_cnt_threshold = tx_fail_count;
+
+	qdf_mem_zero(&msg, sizeof(struct scheduler_msg));
+	msg.type = SIR_HAL_UPDATE_TX_FAIL_CNT_TH;
+	msg.reserved = 0;
+	msg.bodyptr = tx_fail_cnt;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("Not able to post Tx fail count message to WDA"));
+		qdf_mem_free(tx_fail_cnt);
+	}
+	return status;
+}
+
+QDF_STATUS sme_set_lost_link_info_cb(mac_handle_t mac_handle,
+				     lost_link_info_cb cb)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.lost_link_info_cb = cb;
+		sme_release_global_lock(&mac->sme);
+	} else {
+		sme_err("sme_acquire_global_lock error status: %d", status);
+	}
+
+	return status;
+}
+
+#ifdef FEATURE_WLAN_ESE
+bool sme_roam_is_ese_assoc(struct csr_roam_info *roam_info)
+{
+	return roam_info->isESEAssoc;
+}
+#endif
+
+bool sme_neighbor_roam_is11r_assoc(tHalHandle hal_ctx, uint8_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+
+	return csr_neighbor_roam_is11r_assoc(mac_ctx, session_id);
+}
+
+#ifdef WLAN_FEATURE_WOW_PULSE
+/**
+ * sme_set_wow_pulse() - set wow pulse info
+ * @wow_pulse_set_info: wow_pulse_mode structure pointer
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info)
+{
+	struct scheduler_msg message = {0};
+	QDF_STATUS status;
+	struct wow_pulse_mode *wow_pulse_set_cmd;
+
+	if (!wow_pulse_set_info) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: invalid wow_pulse_set_info pointer", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wow_pulse_set_cmd = qdf_mem_malloc(sizeof(*wow_pulse_set_cmd));
+	if (!wow_pulse_set_cmd)
+		return QDF_STATUS_E_NOMEM;
+
+	*wow_pulse_set_cmd = *wow_pulse_set_info;
+
+	message.type = WMA_SET_WOW_PULSE_CMD;
+	message.bodyptr = wow_pulse_set_cmd;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA,
+					&message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: Not able to post msg to WDA!",
+			__func__);
+		qdf_mem_free(wow_pulse_set_cmd);
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+#endif
+
+/**
+ * sme_prepare_beacon_from_bss_descp() - prepares beacon frame by populating
+ * different fields and IEs from bss descriptor.
+ * @frame_buf: frame buffer to populate
+ * @bss_descp: bss descriptor
+ * @bssid: bssid of the beacon frame to populate
+ * @ie_len: length of IE fields
+ *
+ * Return: None
+ */
+static void sme_prepare_beacon_from_bss_descp(uint8_t *frame_buf,
+					      tSirBssDescription *bss_descp,
+					      const tSirMacAddr bssid,
+					      uint32_t ie_len)
+{
+	tDot11fBeacon1 *bcn_fixed;
+	tpSirMacMgmtHdr mac_hdr = (tpSirMacMgmtHdr)frame_buf;
+
+	/* populate mac header first to indicate beacon */
+	mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
+	mac_hdr->fc.type = SIR_MAC_MGMT_FRAME;
+	mac_hdr->fc.subType = SIR_MAC_MGMT_BEACON;
+	qdf_mem_copy((uint8_t *) mac_hdr->da,
+		     (uint8_t *) "\xFF\xFF\xFF\xFF\xFF\xFF",
+		     sizeof(struct qdf_mac_addr));
+	qdf_mem_copy((uint8_t *) mac_hdr->sa, bssid,
+		     sizeof(struct qdf_mac_addr));
+	qdf_mem_copy((uint8_t *) mac_hdr->bssId, bssid,
+		     sizeof(struct qdf_mac_addr));
+
+	/* now populate fixed params */
+	bcn_fixed = (tDot11fBeacon1 *)(frame_buf + SIR_MAC_HDR_LEN_3A);
+	/* populate timestamp */
+	qdf_mem_copy(&bcn_fixed->TimeStamp.timestamp, &bss_descp->timeStamp,
+			sizeof(bss_descp->timeStamp));
+	/* populate beacon interval */
+	bcn_fixed->BeaconInterval.interval = bss_descp->beaconInterval;
+	/* populate capability */
+	qdf_mem_copy(&bcn_fixed->Capabilities, &bss_descp->capabilityInfo,
+			sizeof(bss_descp->capabilityInfo));
+
+	/* copy IEs now */
+	qdf_mem_copy(frame_buf + SIR_MAC_HDR_LEN_3A
+		     + SIR_MAC_B_PR_SSID_OFFSET,
+		     &bss_descp->ieFields, ie_len);
+}
+
+QDF_STATUS sme_get_rssi_snr_by_bssid(tHalHandle hal,
+				struct csr_roam_profile *profile,
+				const uint8_t *bssid,
+				int8_t *rssi, int8_t *snr)
+{
+	tSirBssDescription *bss_descp;
+	tCsrScanResultFilter *scan_filter;
+	struct scan_result_list *bss_list;
+	tScanResultHandle result_handle = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (!scan_filter) {
+		status = QDF_STATUS_E_NOMEM;
+		goto free_scan_flter;
+	}
+
+	status = csr_roam_prepare_filter_from_profile(mac_ctx,
+						profile, scan_filter);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("prepare_filter failed");
+		goto free_scan_flter;
+	}
+
+	/* update filter to get scan result with just target BSSID */
+	if (NULL == scan_filter->BSSIDs.bssid) {
+		scan_filter->BSSIDs.bssid =
+			qdf_mem_malloc(sizeof(struct qdf_mac_addr));
+		if (!scan_filter->BSSIDs.bssid) {
+			status = QDF_STATUS_E_NOMEM;
+			goto free_scan_flter;
+		}
+	}
+
+	scan_filter->BSSIDs.numOfBSSIDs = 1;
+	qdf_mem_copy(scan_filter->BSSIDs.bssid[0].bytes,
+		     bssid, sizeof(struct qdf_mac_addr));
+
+	status = csr_scan_get_result(mac_ctx, scan_filter, &result_handle);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("parse_scan_result failed");
+		goto free_scan_flter;
+	}
+
+	bss_list = (struct scan_result_list *)result_handle;
+	bss_descp = csr_get_fst_bssdescr_ptr(bss_list);
+	if (!bss_descp) {
+		sme_err("unable to fetch bss descriptor");
+		status = QDF_STATUS_E_FAULT;
+		goto free_scan_flter;
+	}
+
+	sme_debug("snr: %d, rssi: %d, raw_rssi: %d",
+		bss_descp->sinr, bss_descp->rssi, bss_descp->rssi_raw);
+
+	if (rssi)
+		*rssi = bss_descp->rssi;
+	if (snr)
+		*snr = bss_descp->sinr;
+
+free_scan_flter:
+	/* free scan filter and exit */
+	if (scan_filter) {
+		csr_free_scan_filter(mac_ctx, scan_filter);
+		qdf_mem_free(scan_filter);
+	}
+
+	if (result_handle)
+		csr_scan_result_purge(mac_ctx, result_handle);
+
+	return status;
+}
+
+QDF_STATUS sme_get_beacon_frm(tHalHandle hal, struct csr_roam_profile *profile,
+			      const tSirMacAddr bssid,
+			      uint8_t **frame_buf, uint32_t *frame_len,
+			      int *channel)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tScanResultHandle result_handle = NULL;
+	tCsrScanResultFilter *scan_filter;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	tSirBssDescription *bss_descp;
+	struct scan_result_list *bss_list;
+	uint32_t ie_len;
+
+	scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (!scan_filter) {
+		status = QDF_STATUS_E_NOMEM;
+		goto free_scan_flter;
+	}
+	status = csr_roam_prepare_filter_from_profile(mac_ctx,
+						profile, scan_filter);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("prepare_filter failed");
+		status = QDF_STATUS_E_FAULT;
+		goto free_scan_flter;
+	}
+
+	/* update filter to get scan result with just target BSSID */
+	if (NULL == scan_filter->BSSIDs.bssid) {
+		scan_filter->BSSIDs.bssid =
+			qdf_mem_malloc(sizeof(struct qdf_mac_addr));
+		if (!scan_filter->BSSIDs.bssid) {
+			status = QDF_STATUS_E_NOMEM;
+			goto free_scan_flter;
+		}
+	}
+	scan_filter->BSSIDs.numOfBSSIDs = 1;
+	qdf_mem_copy(scan_filter->BSSIDs.bssid[0].bytes,
+		     bssid, sizeof(struct qdf_mac_addr));
+
+	status = csr_scan_get_result(mac_ctx, scan_filter, &result_handle);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("parse_scan_result failed");
+		status = QDF_STATUS_E_FAULT;
+		goto free_scan_flter;
+	}
+
+	bss_list = (struct scan_result_list *)result_handle;
+	bss_descp = csr_get_fst_bssdescr_ptr(bss_list);
+	if (!bss_descp) {
+		sme_err("unable to fetch bss descriptor");
+		status = QDF_STATUS_E_FAULT;
+		goto free_scan_flter;
+	}
+
+	/**
+	 * Length of BSS descriptor is without length of
+	 * length itself and length of pointer that holds ieFields.
+	 *
+	 * tSirBssDescription
+	 * +--------+---------------------------------+---------------+
+	 * | length | other fields                    | pointer to IEs|
+	 * +--------+---------------------------------+---------------+
+	 *                                            ^
+	 *                                            ieFields
+	 */
+	ie_len = bss_descp->length + sizeof(bss_descp->length)
+		- (uint16_t)(offsetof(tSirBssDescription, ieFields[0]));
+	sme_debug("found bss_descriptor ie_len: %d channel %d",
+					ie_len, bss_descp->channelId);
+
+	/* include mac header and fixed params along with IEs in frame */
+	*frame_len = SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET + ie_len;
+	*frame_buf = qdf_mem_malloc(*frame_len);
+	if (!*frame_buf) {
+		status = QDF_STATUS_E_NOMEM;
+		goto free_scan_flter;
+	}
+
+	sme_prepare_beacon_from_bss_descp(*frame_buf, bss_descp, bssid, ie_len);
+
+	if (!*channel)
+		*channel = bss_descp->channelId;
+free_scan_flter:
+	/* free scan filter and exit */
+	if (scan_filter) {
+		csr_free_scan_filter(mac_ctx, scan_filter);
+		qdf_mem_free(scan_filter);
+	}
+	if (result_handle)
+		csr_scan_result_purge(mac_ctx, result_handle);
+
+	return status;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS sme_fast_reassoc(tHalHandle hal, struct csr_roam_profile *profile,
+			    const tSirMacAddr bssid, int channel,
+			    uint8_t vdev_id, const tSirMacAddr connected_bssid)
+{
+	QDF_STATUS status;
+	struct wma_roam_invoke_cmd *fastreassoc;
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct csr_roam_session *session;
+	struct csr_roam_profile *roam_profile;
+
+	session = CSR_GET_SESSION(mac_ctx, vdev_id);
+	if (!session || !session->pCurRoamProfile) {
+		sme_err("session %d not found", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	roam_profile = session->pCurRoamProfile;
+	if (roam_profile->supplicant_disabled_roaming ||
+	    roam_profile->driver_disabled_roaming) {
+		sme_debug("roaming status in Supplicant %d and in driver %d",
+			  roam_profile->supplicant_disabled_roaming,
+			  roam_profile->driver_disabled_roaming);
+		return QDF_STATUS_E_FAILURE;
+	}
+	fastreassoc = qdf_mem_malloc(sizeof(*fastreassoc));
+	if (!fastreassoc)
+		return QDF_STATUS_E_NOMEM;
+
+	/* if both are same then set the flag */
+	if (!qdf_mem_cmp(connected_bssid, bssid, ETH_ALEN)) {
+		fastreassoc->is_same_bssid = true;
+		sme_debug("bssid same, bssid[%pM]", bssid);
+	}
+	fastreassoc->vdev_id = vdev_id;
+	fastreassoc->bssid[0] = bssid[0];
+	fastreassoc->bssid[1] = bssid[1];
+	fastreassoc->bssid[2] = bssid[2];
+	fastreassoc->bssid[3] = bssid[3];
+	fastreassoc->bssid[4] = bssid[4];
+	fastreassoc->bssid[5] = bssid[5];
+
+	status = sme_get_beacon_frm(hal, profile, bssid,
+				    &fastreassoc->frame_buf,
+				    &fastreassoc->frame_len,
+				    &channel);
+
+	if (!channel) {
+		sme_err("channel retrieval from BSS desc fails!");
+		qdf_mem_free(fastreassoc);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	fastreassoc->channel = channel;
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_warn("sme_get_beacon_frm failed");
+		fastreassoc->frame_buf = NULL;
+		fastreassoc->frame_len = 0;
+	}
+
+	if (csr_is_auth_type_ese(mac_ctx->roam.roamSession[vdev_id].
+				connectedProfile.AuthType)) {
+		sme_debug("Beacon is not required for ESE");
+		if (fastreassoc->frame_len) {
+			qdf_mem_free(fastreassoc->frame_buf);
+			fastreassoc->frame_buf = NULL;
+			fastreassoc->frame_len = 0;
+		}
+	}
+
+	msg.type = eWNI_SME_ROAM_INVOKE;
+	msg.reserved = 0;
+	msg.bodyptr = fastreassoc;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_PE, &msg);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("Not able to post ROAM_INVOKE_CMD message to PE");
+		qdf_mem_free(fastreassoc);
+	}
+
+	return status;
+}
+#endif
+
+QDF_STATUS sme_set_del_pmkid_cache(tHalHandle hal, uint8_t session_id,
+				   tPmkidCacheInfo *pmk_cache_info,
+				   bool is_add)
+{
+	struct wmi_unified_pmk_cache *pmk_cache;
+	struct scheduler_msg msg;
+
+	pmk_cache = qdf_mem_malloc(sizeof(*pmk_cache));
+	if (!pmk_cache)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_set(pmk_cache, sizeof(*pmk_cache), 0);
+
+	pmk_cache->session_id = session_id;
+
+	if (!pmk_cache_info)
+		goto send_flush_cmd;
+
+	if (!pmk_cache_info->ssid_len) {
+		pmk_cache->cat_flag = WMI_PMK_CACHE_CAT_FLAG_BSSID;
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(pmk_cache_info->BSSID.bytes,
+				&pmk_cache->bssid);
+	} else {
+		pmk_cache->cat_flag = WMI_PMK_CACHE_CAT_FLAG_SSID_CACHE_ID;
+		pmk_cache->ssid.length = pmk_cache_info->ssid_len;
+		qdf_mem_copy(pmk_cache->ssid.mac_ssid,
+			     pmk_cache_info->ssid,
+			     pmk_cache->ssid.length);
+	}
+	pmk_cache->cache_id = (uint32_t) (pmk_cache_info->cache_id[0] << 8 |
+					pmk_cache_info->cache_id[1]);
+
+	if (is_add)
+		pmk_cache->action_flag = WMI_PMK_CACHE_ACTION_FLAG_ADD_ENTRY;
+	else
+		pmk_cache->action_flag = WMI_PMK_CACHE_ACTION_FLAG_DEL_ENTRY;
+
+	pmk_cache->pmkid_len = CSR_RSN_PMKID_SIZE;
+	qdf_mem_copy(pmk_cache->pmkid, pmk_cache_info->PMKID,
+		     CSR_RSN_PMKID_SIZE);
+
+	pmk_cache->pmk_len = pmk_cache_info->pmk_len;
+	qdf_mem_copy(pmk_cache->pmk, pmk_cache_info->pmk,
+		     pmk_cache->pmk_len);
+
+send_flush_cmd:
+	msg.type = SIR_HAL_SET_DEL_PMKID_CACHE;
+	msg.reserved = 0;
+	msg.bodyptr = pmk_cache;
+	if (QDF_STATUS_SUCCESS !=
+	    scheduler_post_message(QDF_MODULE_ID_SME,
+				   QDF_MODULE_ID_WMA,
+				   QDF_MODULE_ID_WMA, &msg)) {
+		sme_err("Not able to post message to WDA");
+		qdf_mem_free(pmk_cache);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/* ARP DEBUG STATS */
+
+/**
+ * sme_set_nud_debug_stats() - sme api to set nud debug stats
+ * @hal: handle to hal
+ * @set_stats_param: pointer to set stats param
+ *
+ * Return: Return QDF_STATUS.
+ */
+QDF_STATUS sme_set_nud_debug_stats(tHalHandle hal,
+				   struct set_arp_stats_params
+				   *set_stats_param)
+{
+	struct set_arp_stats_params *arp_set_param;
+	struct scheduler_msg msg;
+
+	arp_set_param = qdf_mem_malloc(sizeof(*arp_set_param));
+	if (!arp_set_param)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(arp_set_param, set_stats_param, sizeof(*arp_set_param));
+
+	msg.type = WMA_SET_ARP_STATS_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = arp_set_param;
+
+	if (QDF_STATUS_SUCCESS !=
+	    scheduler_post_message(QDF_MODULE_ID_SME,
+				   QDF_MODULE_ID_WMA,
+				   QDF_MODULE_ID_WMA, &msg)) {
+		sme_err("Not able to post message to WDA");
+		qdf_mem_free(arp_set_param);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_get_nud_debug_stats() - sme api to get nud debug stats
+ * @hal: handle to hal
+ * @get_stats_param: pointer to set stats param
+ *
+ * Return: Return QDF_STATUS.
+ */
+QDF_STATUS sme_get_nud_debug_stats(tHalHandle hal,
+				   struct get_arp_stats_params
+				   *get_stats_param)
+{
+	struct get_arp_stats_params *arp_get_param;
+	struct scheduler_msg msg;
+
+	arp_get_param = qdf_mem_malloc(sizeof(*arp_get_param));
+	if (!arp_get_param)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(arp_get_param, get_stats_param, sizeof(*arp_get_param));
+
+	msg.type = WMA_GET_ARP_STATS_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = arp_get_param;
+
+	if (QDF_STATUS_SUCCESS !=
+	    scheduler_post_message(QDF_MODULE_ID_SME,
+				   QDF_MODULE_ID_WMA,
+				   QDF_MODULE_ID_WMA, &msg)) {
+		sme_err("Not able to post message to WDA");
+		qdf_mem_free(arp_get_param);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sme_set_peer_param(uint8_t *peer_addr, uint32_t param_id,
+			      uint32_t param_value, uint32_t vdev_id)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		sme_err("wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wma_set_peer_param(wma_handle, peer_addr, param_id,
+				  param_value, vdev_id);
+}
+
+QDF_STATUS sme_register_set_connection_info_cb(tHalHandle hHal,
+				bool (*set_connection_info_cb)(bool),
+				bool (*get_connection_info_cb)(uint8_t *session_id,
+				enum scan_reject_states *reason))
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pMac->sme.set_connection_info_cb = set_connection_info_cb;
+		pMac->sme.get_connection_info_cb = get_connection_info_cb;
+		sme_release_global_lock(&pMac->sme);
+	}
+	return status;
+}
+
+QDF_STATUS sme_rso_cmd_status_cb(mac_handle_t mac_handle,
+				 rso_cmd_status_cb cb)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	mac->sme.rso_cmd_status_cb = cb;
+	sme_debug("Registered RSO command status callback");
+	return status;
+}
+
+QDF_STATUS sme_set_dbs_scan_selection_config(tHalHandle hal,
+		struct wmi_dbs_scan_sel_params *params)
+{
+	struct scheduler_msg message = {0};
+	QDF_STATUS status;
+	struct wmi_dbs_scan_sel_params *dbs_scan_params;
+	uint32_t i;
+
+	if (0 == params->num_clients) {
+		sme_err("Num of clients is 0");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dbs_scan_params = qdf_mem_malloc(sizeof(*dbs_scan_params));
+	if (!dbs_scan_params)
+		return QDF_STATUS_E_NOMEM;
+
+	dbs_scan_params->num_clients = params->num_clients;
+	dbs_scan_params->pdev_id = params->pdev_id;
+	for (i = 0; i < params->num_clients; i++) {
+		dbs_scan_params->module_id[i] = params->module_id[i];
+		dbs_scan_params->num_dbs_scans[i] = params->num_dbs_scans[i];
+		dbs_scan_params->num_non_dbs_scans[i] =
+			params->num_non_dbs_scans[i];
+	}
+	message.type = WMA_SET_DBS_SCAN_SEL_CONF_PARAMS;
+	message.bodyptr = dbs_scan_params;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Not able to post msg to WMA!");
+		qdf_mem_free(dbs_scan_params);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_get_rcpi(tHalHandle hal, struct sme_rcpi_req *rcpi)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hal);
+	struct scheduler_msg msg = {0};
+	struct sme_rcpi_req *rcpi_req;
+
+	rcpi_req = qdf_mem_malloc(sizeof(*rcpi_req));
+	if (!rcpi_req)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(rcpi_req, rcpi, sizeof(*rcpi_req));
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		msg.bodyptr = rcpi_req;
+		msg.type = WMA_GET_RCPI_REQ;
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA, &msg);
+		sme_release_global_lock(&pMac->sme);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("post get rcpi req failed"));
+			status = QDF_STATUS_E_FAILURE;
+			qdf_mem_free(rcpi_req);
+		}
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("sme_acquire_global_lock failed"));
+		qdf_mem_free(rcpi_req);
+	}
+
+	return status;
+}
+
+void sme_store_pdev(tHalHandle hal, struct wlan_objmgr_pdev *pdev)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	void *wma_handle;
+	QDF_STATUS status;
+
+	status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_LEGACY_MAC_ID);
+	if (QDF_STATUS_SUCCESS != status) {
+		mac_ctx->pdev = NULL;
+		return;
+	}
+	mac_ctx->pdev = pdev;
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("wma handle is NULL"));
+		return;
+	}
+	wma_store_pdev(wma_handle, pdev);
+}
+
+QDF_STATUS sme_congestion_register_callback(tHalHandle hal,
+					    congestion_cb congestion_cb)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.congestion_cb = congestion_cb;
+		sme_release_global_lock(&mac->sme);
+		sme_debug("congestion callback set");
+	} else {
+		sme_err("Aquiring lock failed %d", status);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_register_tx_queue_cb(mac_handle_t mac_handle,
+				    tx_queue_cb tx_queue_cb)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.tx_queue_cb = tx_queue_cb;
+		sme_release_global_lock(&mac->sme);
+		sme_debug("Tx queue callback set");
+	} else {
+		sme_err("Aquiring lock failed %d", status);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_deregister_tx_queue_cb(mac_handle_t mac_handle)
+{
+	return sme_register_tx_queue_cb(mac_handle, NULL);
+}
+
+#ifdef WLAN_SUPPORT_TWT
+QDF_STATUS sme_register_twt_enable_complete_cb(mac_handle_t mac_handle,
+					       twt_enable_cb twt_enable_cb)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.twt_enable_cb = twt_enable_cb;
+		sme_release_global_lock(&mac->sme);
+		sme_debug("TWT: enable callback set");
+	} else {
+		sme_err("Aquiring lock failed %d", status);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_register_twt_disable_complete_cb(mac_handle_t mac_handle,
+						twt_disable_cb twt_disable_cb)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.twt_disable_cb = twt_disable_cb;
+		sme_release_global_lock(&mac->sme);
+		sme_debug("TWT: disable callback set");
+	} else {
+		sme_err("Aquiring lock failed %d", status);
+	}
+
+	return status;
+}
+
+QDF_STATUS sme_deregister_twt_enable_complete_cb(mac_handle_t mac_handle)
+{
+	return sme_register_twt_enable_complete_cb(mac_handle, NULL);
+}
+
+QDF_STATUS sme_deregister_twt_disable_complete_cb(mac_handle_t mac_handle)
+{
+	return sme_register_twt_disable_complete_cb(mac_handle, NULL);
+}
+#endif
+
+QDF_STATUS sme_set_smps_cfg(uint32_t vdev_id, uint32_t param_id,
+						uint32_t param_val)
+{
+	return wma_configure_smps_params(vdev_id, param_id, param_val);
+}
+
+QDF_STATUS sme_ipa_uc_stat_request(tHalHandle hal, uint32_t vdev_id,
+			uint32_t param_id, uint32_t param_val, uint32_t req_cat)
+{
+	wma_cli_set_cmd_t *iwcmd;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	iwcmd = qdf_mem_malloc(sizeof(*iwcmd));
+	if (!iwcmd)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_zero(iwcmd, sizeof(*iwcmd));
+	iwcmd->param_sec_value = 0;
+	iwcmd->param_vdev_id = vdev_id;
+	iwcmd->param_id = param_id;
+	iwcmd->param_vp_dev = req_cat;
+	iwcmd->param_value =  param_val;
+	wma_ipa_uc_stat_request(iwcmd);
+	qdf_mem_free(iwcmd);
+
+	return status;
+}
+
+QDF_STATUS sme_set_reorder_timeout(tHalHandle hal,
+	struct sir_set_rx_reorder_timeout_val *req)
+{
+	QDF_STATUS status;
+	tp_wma_handle wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	status = wma_set_rx_reorder_timeout_val(wma_handle, req);
+
+	return status;
+}
+
+QDF_STATUS sme_set_rx_set_blocksize(tHalHandle hal,
+	struct sir_peer_set_rx_blocksize *req)
+{
+	QDF_STATUS status;
+	tp_wma_handle wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	status = wma_set_rx_blocksize(wma_handle, req);
+
+	return status;
+}
+
+int sme_cli_set_command(int vdev_id, int param_id, int sval, int vpdev)
+{
+	return wma_cli_set_command(vdev_id, param_id, sval, vpdev);
+}
+
+int sme_set_enable_mem_deep_sleep(mac_handle_t mac_handle, int vdev_id)
+{
+	tpAniSirGlobal mac_ctx = MAC_CONTEXT(mac_handle);
+
+	return wma_cli_set_command(vdev_id, WMI_PDEV_PARAM_HYST_EN,
+				   mac_ctx->mlme_cfg->gen.memory_deep_sleep,
+				   PDEV_CMD);
+}
+
+int sme_set_cck_tx_fir_override(mac_handle_t mac_handle, int vdev_id)
+{
+	tpAniSirGlobal mac_ctx = MAC_CONTEXT(mac_handle);
+
+	return wma_cli_set_command(vdev_id,
+				   WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE,
+				   mac_ctx->mlme_cfg->gen.cck_tx_fir_override,
+				   PDEV_CMD);
+}
+
+QDF_STATUS sme_set_bt_activity_info_cb(mac_handle_t mac_handle,
+				       bt_activity_info_cb cb)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	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;
+}
+
+QDF_STATUS sme_get_chain_rssi(tHalHandle hal,
+			      struct get_chain_rssi_req_params *input,
+			      get_chain_rssi_callback callback,
+			      void *context)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	tp_wma_handle wma_handle;
+
+	SME_ENTER();
+
+	if (NULL == input) {
+		sme_err("Invalid req params");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mac_ctx->sme.get_chain_rssi_cb = callback;
+	mac_ctx->sme.get_chain_rssi_context = context;
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	wma_get_chain_rssi(wma_handle, input);
+
+	SME_EXIT();
+	return status;
+}
+
+QDF_STATUS sme_process_msg_callback(tpAniSirGlobal mac,
+				    struct scheduler_msg *msg)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (msg == NULL) {
+		sme_err("Empty message for SME Msg callback");
+		return status;
+	}
+	status = sme_process_msg(mac, msg);
+	return status;
+}
+
+void sme_display_disconnect_stats(tHalHandle hal, uint8_t session_id)
+{
+	struct csr_roam_session *session;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("%s Invalid session id: %d", __func__, session_id);
+		return;
+	}
+
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (!session) {
+		sme_err("%s Failed to get session for id: %d",
+			__func__, session_id);
+		return;
+	}
+
+	sme_nofl_info("Total No. of Disconnections: %d",
+		      session->disconnect_stats.disconnection_cnt);
+
+	sme_nofl_info("No. of Diconnects Triggered by Application: %d",
+		      session->disconnect_stats.disconnection_by_app);
+
+	sme_nofl_info("No. of Disassoc Sent by Peer: %d",
+		      session->disconnect_stats.disassoc_by_peer);
+
+	sme_nofl_info("No. of Deauth Sent by Peer: %d",
+		      session->disconnect_stats.deauth_by_peer);
+
+	sme_nofl_info("No. of Disconnections due to Beacon Miss: %d",
+		      session->disconnect_stats.bmiss);
+
+	sme_nofl_info("No. of Disconnections due to Peer Kickout: %d",
+		      session->disconnect_stats.peer_kickout);
+}
+
+#ifdef FEATURE_WLAN_DYNAMIC_CVM
+ /**
+ * sme_set_vc_mode_config() - Set voltage corner config to FW
+ * @bitmap:	Bitmap that referes to voltage corner config with
+ * different phymode and bw configuration
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_vc_mode_config(uint32_t vc_bitmap)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma_handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (QDF_STATUS_SUCCESS !=
+		wma_set_vc_mode_config(wma_handle, vc_bitmap)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: Failed to set Voltage Control config to FW",
+			__func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * sme_set_bmiss_bcnt() - set bmiss config parameters
+ * @vdev_id: virtual device for the command
+ * @first_cnt: bmiss first value
+ * @final_cnt: bmiss final value
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS sme_set_bmiss_bcnt(uint32_t vdev_id, uint32_t first_cnt,
+		uint32_t final_cnt)
+{
+	return wma_config_bmiss_bcnt_params(vdev_id, first_cnt, final_cnt);
+}
+
+QDF_STATUS sme_send_limit_off_channel_params(tHalHandle hal, uint8_t vdev_id,
+		bool is_tos_active, uint32_t max_off_chan_time,
+		uint32_t rest_time, bool skip_dfs_chan)
+{
+	struct sir_limit_off_chan *cmd;
+	struct scheduler_msg msg = {0};
+
+	cmd = qdf_mem_malloc(sizeof(*cmd));
+	if (!cmd)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd->vdev_id = vdev_id;
+	cmd->is_tos_active = is_tos_active;
+	cmd->max_off_chan_time = max_off_chan_time;
+	cmd->rest_time = rest_time;
+	cmd->skip_dfs_chans = skip_dfs_chan;
+
+	msg.type = WMA_SET_LIMIT_OFF_CHAN;
+	msg.reserved = 0;
+	msg.bodyptr = cmd;
+
+	if (!QDF_IS_STATUS_SUCCESS(scheduler_post_message(QDF_MODULE_ID_SME,
+							  QDF_MODULE_ID_WMA,
+							  QDF_MODULE_ID_WMA,
+							  &msg))) {
+		sme_err("Not able to post WMA_SET_LIMIT_OFF_CHAN to WMA");
+		qdf_mem_free(cmd);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+uint32_t sme_unpack_rsn_ie(tHalHandle hal, uint8_t *buf,
+			   uint8_t buf_len, tDot11fIERSN *rsn_ie,
+			   bool append_ie)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	return dot11f_unpack_ie_rsn(mac_ctx, buf, buf_len, rsn_ie, append_ie);
+}
+
+#ifdef FEATURE_BSS_TRANSITION
+/**
+ * sme_get_status_for_candidate() - Get bss transition status for candidate
+ * @hal: Handle for HAL
+ * @conn_bss_desc: connected bss descriptor
+ * @bss_desc: candidate bss descriptor
+ * @info: candiadate bss information
+ * @trans_reason: transition reason code
+ * @is_bt_in_progress: bt activity indicator
+ *
+ * Return : true if candidate is rejected and reject reason is filled
+ * @info->status. Otherwise returns false.
+ */
+static bool sme_get_status_for_candidate(tHalHandle hal,
+					tSirBssDescription *conn_bss_desc,
+					tSirBssDescription *bss_desc,
+					struct bss_candidate_info *info,
+					uint8_t trans_reason,
+					bool is_bt_in_progress)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct wlan_mlme_mbo *mbo_cfg;
+	int8_t current_rssi_mcc_thres;
+
+	if (!(mac_ctx->mlme_cfg)) {
+		pe_err("mlme cfg is NULL");
+		return false;
+	}
+	mbo_cfg = &mac_ctx->mlme_cfg->mbo_cfg;
+
+	/*
+	 * Low RSSI based rejection
+	 * If candidate rssi is less than mbo_candidate_rssi_thres and connected
+	 * bss rssi is greater than mbo_current_rssi_thres, then reject the
+	 * candidate with MBO reason code 4.
+	 */
+	if ((bss_desc->rssi < mbo_cfg->mbo_candidate_rssi_thres) &&
+	    (conn_bss_desc->rssi > mbo_cfg->mbo_current_rssi_thres)) {
+		sme_err("Candidate BSS "MAC_ADDRESS_STR" has LOW RSSI(%d), hence reject",
+			MAC_ADDR_ARRAY(bss_desc->bssId), bss_desc->rssi);
+		info->status = QCA_STATUS_REJECT_LOW_RSSI;
+		return true;
+	}
+
+	if (trans_reason == MBO_TRANSITION_REASON_LOAD_BALANCING ||
+	    trans_reason == MBO_TRANSITION_REASON_TRANSITIONING_TO_PREMIUM_AP) {
+		/*
+		 * MCC rejection
+		 * If moving to candidate's channel will result in MCC scenario
+		 * and the rssi of connected bss is greater than
+		 * mbo_current_rssi_mss_thres, then reject the candidate with
+		 * MBO reason code 3.
+		 */
+		current_rssi_mcc_thres = mbo_cfg->mbo_current_rssi_mcc_thres;
+		if ((conn_bss_desc->rssi > current_rssi_mcc_thres) &&
+		    csr_is_mcc_channel(mac_ctx, bss_desc->channelId)) {
+			sme_err("Candidate BSS "MAC_ADDRESS_STR" causes MCC, hence reject",
+				MAC_ADDR_ARRAY(bss_desc->bssId));
+			info->status =
+				QCA_STATUS_REJECT_INSUFFICIENT_QOS_CAPACITY;
+			return true;
+		}
+
+		/*
+		 * BT coex rejection
+		 * If AP is trying to move the client from 5G to 2.4G and moving
+		 * to 2.4G will result in BT coex and candidate channel rssi is
+		 * less than mbo_candidate_rssi_btc_thres, then reject the
+		 * candidate with MBO reason code 2.
+		 */
+		if (WLAN_REG_IS_5GHZ_CH(conn_bss_desc->channelId) &&
+		    WLAN_REG_IS_24GHZ_CH(bss_desc->channelId) &&
+		    is_bt_in_progress &&
+		    (bss_desc->rssi < mbo_cfg->mbo_candidate_rssi_btc_thres)) {
+			sme_err("Candidate BSS "MAC_ADDRESS_STR" causes BT coex, hence reject",
+				MAC_ADDR_ARRAY(bss_desc->bssId));
+			info->status =
+				QCA_STATUS_REJECT_EXCESSIVE_DELAY_EXPECTED;
+			return true;
+		}
+
+		/*
+		 * LTE coex rejection
+		 * If moving to candidate's channel can cause LTE coex, then
+		 * reject the candidate with MBO reason code 5.
+		 */
+		if (policy_mgr_is_safe_channel(mac_ctx->psoc,
+		    conn_bss_desc->channelId) &&
+		    !(policy_mgr_is_safe_channel(mac_ctx->psoc,
+		    bss_desc->channelId))) {
+			sme_err("High interference expected if transitioned to BSS "
+				MAC_ADDRESS_STR" hence reject",
+				MAC_ADDR_ARRAY(bss_desc->bssId));
+			info->status =
+				QCA_STATUS_REJECT_HIGH_INTERFERENCE;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * wlan_hdd_get_bss_transition_status() - get bss transition status all cadidates
+ * @adapter : Pointer to adapter
+ * @transition_reason : Transition reason
+ * @info : bss candidate information
+ * @n_candidates : number of candidates
+ *
+ * Return : 0 on success otherwise errno
+ */
+int sme_get_bss_transition_status(tHalHandle hal,
+					uint8_t transition_reason,
+					struct qdf_mac_addr *bssid,
+					struct bss_candidate_info *info,
+					uint16_t n_candidates,
+					bool is_bt_in_progress)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirBssDescription *bss_desc, *conn_bss_desc;
+	tCsrScanResultInfo *res, *conn_res;
+	uint16_t i;
+
+	if (!n_candidates || !info) {
+		sme_err("No candidate info available");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	conn_res = qdf_mem_malloc(sizeof(tCsrScanResultInfo));
+	if (!conn_res)
+		return QDF_STATUS_E_NOMEM;
+
+	res = qdf_mem_malloc(sizeof(tCsrScanResultInfo));
+	if (!res) {
+		status = QDF_STATUS_E_NOMEM;
+		goto free;
+	}
+
+	/* Get the connected BSS descriptor */
+	status = sme_scan_get_result_for_bssid(hal, bssid, conn_res);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Failed to find connected BSS in scan list");
+		goto free;
+	}
+	conn_bss_desc = &conn_res->BssDescriptor;
+
+	for (i = 0; i < n_candidates; i++) {
+		/* Get candidate BSS descriptors */
+		status = sme_scan_get_result_for_bssid(hal, &info[i].bssid,
+						       res);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("BSS "MAC_ADDRESS_STR" not present in scan list",
+				MAC_ADDR_ARRAY(info[i].bssid.bytes));
+			info[i].status = QCA_STATUS_REJECT_UNKNOWN;
+			continue;
+		}
+
+		bss_desc = &res->BssDescriptor;
+		if (!sme_get_status_for_candidate(hal, conn_bss_desc, bss_desc,
+		    &info[i], transition_reason, is_bt_in_progress)) {
+			/*
+			 * If status is not over written, it means it is a
+			 * candidate for accept.
+			 */
+			info[i].status = QCA_STATUS_ACCEPT;
+		}
+	}
+
+	/* success */
+	status = QDF_STATUS_SUCCESS;
+
+free:
+	/* free allocated memory */
+	if (conn_res)
+		qdf_mem_free(conn_res);
+	if (res)
+		qdf_mem_free(res);
+
+	return status;
+}
+#endif /* FEATURE_BSS_TRANSITION */
+
+bool sme_is_conn_state_connected(mac_handle_t hal, uint8_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	return csr_is_conn_state_connected(mac_ctx, session_id);
+}
+
+void sme_enable_roaming_on_connected_sta(tHalHandle hal)
+{
+	uint8_t session_id;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	QDF_STATUS status;
+
+	session_id = csr_get_roam_enabled_sta_sessionid(mac_ctx);
+	if (session_id != CSR_SESSION_ID_INVALID)
+		return;
+
+	session_id = csr_get_connected_infra(mac_ctx);
+	if (session_id == CSR_SESSION_ID_INVALID) {
+		sme_debug("No STA in conencted state");
+		return;
+	}
+
+	sme_debug("Roaming not enabled on any STA, enable roaming on session %d",
+		  session_id);
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		csr_roam_offload_scan(mac_ctx, session_id,
+				      ROAM_SCAN_OFFLOAD_START,
+				      REASON_CTX_INIT);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+}
+
+int16_t sme_get_oper_chan_freq(struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t vdev_id, chan;
+	struct csr_roam_session *session;
+	tpAniSirGlobal mac_ctx;
+	tHalHandle h_hal;
+	int16_t freq = 0;
+
+	if (vdev == NULL) {
+		sme_err("Invalid vdev id is passed");
+		return 0;
+	}
+
+	h_hal = cds_get_context(QDF_MODULE_ID_SME);
+	if (!h_hal) {
+		sme_err("h_hal is null");
+		return 0;
+	}
+	mac_ctx = PMAC_STRUCT(h_hal);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
+		sme_err("Invalid vdev id is passed");
+		return 0;
+	}
+
+	session = CSR_GET_SESSION(mac_ctx, vdev_id);
+	chan = csr_get_infra_operation_channel(mac_ctx, vdev_id);
+	if (chan)
+		freq = cds_chan_to_freq(chan);
+
+	return freq;
+}
+
+enum phy_ch_width sme_get_oper_ch_width(struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t vdev_id;
+	struct csr_roam_session *session;
+	tpAniSirGlobal mac_ctx;
+	tHalHandle h_hal;
+	enum phy_ch_width ch_width = CH_WIDTH_20MHZ;
+
+	if (vdev == NULL) {
+		sme_err("Invalid vdev id is passed");
+		return CH_WIDTH_INVALID;
+	}
+
+	h_hal = cds_get_context(QDF_MODULE_ID_SME);
+	if (!h_hal) {
+		sme_err("h_hal is null");
+		return CH_WIDTH_INVALID;
+	}
+	mac_ctx = PMAC_STRUCT(h_hal);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
+		sme_err("Invalid vdev id is passed");
+		return CH_WIDTH_INVALID;
+	}
+
+	session = CSR_GET_SESSION(mac_ctx, vdev_id);
+
+	if (csr_is_conn_state_connected(mac_ctx, vdev_id))
+		ch_width = session->connectedProfile.vht_channel_width;
+
+	return ch_width;
+}
+
+int sme_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev,
+						uint16_t *sec20chan_freq)
+{
+	uint8_t vdev_id;
+
+	vdev_id = wlan_vdev_get_id(vdev);
+	/* Need to extend */
+	return 0;
+}
+
+#ifdef WLAN_FEATURE_SAE
+QDF_STATUS sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
+		uint8_t sae_status)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct sir_sae_msg *sae_msg;
+	struct scheduler_msg sch_msg = {0};
+
+	qdf_status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		sae_msg = qdf_mem_malloc(sizeof(*sae_msg));
+		if (!sae_msg) {
+			qdf_status = QDF_STATUS_E_NOMEM;
+		} else {
+			sae_msg->message_type = eWNI_SME_SEND_SAE_MSG;
+			sae_msg->length = sizeof(*sae_msg);
+			sae_msg->session_id = session_id;
+			sae_msg->sae_status = sae_status;
+			sme_debug("SAE: sae_status %d session_id %d",
+				sae_msg->sae_status,
+				sae_msg->session_id);
+
+			sch_msg.type = eWNI_SME_SEND_SAE_MSG;
+			sch_msg.bodyptr = sae_msg;
+
+			qdf_status =
+				scheduler_post_message(QDF_MODULE_ID_SME,
+						       QDF_MODULE_ID_PE,
+						       QDF_MODULE_ID_PE,
+						      &sch_msg);
+		}
+		sme_release_global_lock(&mac->sme);
+	}
+
+	return qdf_status;
+}
+#endif
+
+bool sme_is_sta_key_exchange_in_progress(tHalHandle hal, uint8_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("Invalid session id: %d", session_id);
+		return false;
+	}
+
+	return CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id);
+}
+
+bool sme_validate_channel_list(tHalHandle hal,
+				      uint8_t *chan_list,
+				      uint8_t num_channels)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint8_t i = 0;
+	uint8_t j;
+	bool found;
+	struct csr_channel *ch_lst_info = &mac_ctx->scan.base_channels;
+
+	if (!chan_list || !num_channels) {
+		sme_err("Chan list empty %pK or num_channels is 0", chan_list);
+		return false;
+	}
+
+	while (i < num_channels) {
+		found = false;
+		for (j = 0; j < ch_lst_info->numChannels; j++) {
+			if (ch_lst_info->channelList[j] == chan_list[i]) {
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			sme_debug("Invalid channel %d", chan_list[i]);
+			return false;
+		}
+
+		i++;
+	}
+
+	return true;
+}
+
+void sme_set_amsdu(tHalHandle hal, bool enable)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	mac_ctx->is_usr_cfg_amsdu_enabled = enable;
+}
+
+uint8_t sme_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
+			uint8_t *nss, uint8_t *mcs_rate_flags)
+{
+	return wma_get_mcs_idx(max_rate, rate_flags, nss, mcs_rate_flags);
+}
+
+bool sme_find_session_by_bssid(tHalHandle hal, uint8_t *bssid)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	bool ret;
+
+	ret = csr_find_session_by_bssid(mac_ctx, bssid);
+
+	return ret;
+}
+
+QDF_STATUS
+sme_get_roam_scan_stats(tHalHandle hal, roam_scan_stats_cb cb, void *context,
+			uint32_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct scheduler_msg msg = {0};
+	struct sir_roam_scan_stats *req;
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return QDF_STATUS_E_NOMEM;
+
+	req->vdev_id = vdev_id;
+	req->cb = cb;
+	req->context = context;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		msg.bodyptr = req;
+		msg.type = WMA_GET_ROAM_SCAN_STATS;
+		msg.reserved = 0;
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_WMA,
+						&msg);
+		sme_release_global_lock(&mac->sme);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("post roam scan stats req failed"));
+			status = QDF_STATUS_E_FAILURE;
+			qdf_mem_free(req);
+		}
+	} else {
+		sme_err("sme_acquire_global_lock failed");
+		qdf_mem_free(req);
+	}
+
+	return status;
+}
+
+void sme_update_score_config(tHalHandle hal,
+			     struct scoring_config *score_config)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct wlan_mlme_scoring_cfg *mlme_scoring_cfg;
+
+	mlme_scoring_cfg = &mac_ctx->mlme_cfg->scoring;
+
+	score_config->weight_cfg.rssi_weightage =
+		mlme_scoring_cfg->weight_cfg.rssi_weightage;
+	score_config->weight_cfg.ht_caps_weightage =
+		mlme_scoring_cfg->weight_cfg.ht_caps_weightage;
+	score_config->weight_cfg.vht_caps_weightage =
+		mlme_scoring_cfg->weight_cfg.vht_caps_weightage;
+	score_config->weight_cfg.he_caps_weightage =
+		mlme_scoring_cfg->weight_cfg.he_caps_weightage;
+	score_config->weight_cfg.chan_width_weightage =
+		mlme_scoring_cfg->weight_cfg.chan_width_weightage;
+	score_config->weight_cfg.chan_band_weightage =
+		mlme_scoring_cfg->weight_cfg.chan_band_weightage;
+	score_config->weight_cfg.nss_weightage =
+		mlme_scoring_cfg->weight_cfg.nss_weightage;
+	score_config->weight_cfg.beamforming_cap_weightage =
+		mlme_scoring_cfg->weight_cfg.beamforming_cap_weightage;
+	score_config->weight_cfg.pcl_weightage =
+		mlme_scoring_cfg->weight_cfg.pcl_weightage;
+	score_config->weight_cfg.channel_congestion_weightage =
+		mlme_scoring_cfg->weight_cfg.channel_congestion_weightage;
+	score_config->weight_cfg.oce_wan_weightage =
+		mlme_scoring_cfg->weight_cfg.oce_wan_weightage;
+
+	score_config->bandwidth_weight_per_index =
+		mlme_scoring_cfg->bandwidth_weight_per_index;
+	score_config->nss_weight_per_index =
+		mlme_scoring_cfg->nss_weight_per_index;
+	score_config->band_weight_per_index =
+		mlme_scoring_cfg->band_weight_per_index;
+
+	score_config->rssi_score.best_rssi_threshold =
+		mlme_scoring_cfg->rssi_score.best_rssi_threshold;
+	score_config->rssi_score.good_rssi_threshold =
+		mlme_scoring_cfg->rssi_score.good_rssi_threshold;
+	score_config->rssi_score.bad_rssi_threshold =
+		mlme_scoring_cfg->rssi_score.bad_rssi_threshold;
+	score_config->rssi_score.good_rssi_pcnt =
+		mlme_scoring_cfg->rssi_score.good_rssi_pcnt;
+	score_config->rssi_score.bad_rssi_pcnt =
+		mlme_scoring_cfg->rssi_score.bad_rssi_pcnt;
+	score_config->rssi_score.good_rssi_bucket_size =
+		mlme_scoring_cfg->rssi_score.good_rssi_bucket_size;
+	score_config->rssi_score.bad_rssi_bucket_size =
+		mlme_scoring_cfg->rssi_score.bad_rssi_bucket_size;
+	score_config->rssi_score.rssi_pref_5g_rssi_thresh =
+		mlme_scoring_cfg->rssi_score.rssi_pref_5g_rssi_thresh;
+
+	score_config->esp_qbss_scoring.num_slot =
+		mlme_scoring_cfg->esp_qbss_scoring.num_slot;
+	score_config->esp_qbss_scoring.score_pcnt3_to_0 =
+		mlme_scoring_cfg->esp_qbss_scoring.score_pcnt3_to_0;
+	score_config->esp_qbss_scoring.score_pcnt7_to_4 =
+		mlme_scoring_cfg->esp_qbss_scoring.score_pcnt7_to_4;
+	score_config->esp_qbss_scoring.score_pcnt11_to_8 =
+		mlme_scoring_cfg->esp_qbss_scoring.score_pcnt11_to_8;
+	score_config->esp_qbss_scoring.score_pcnt15_to_12 =
+		mlme_scoring_cfg->esp_qbss_scoring.score_pcnt15_to_12;
+
+	score_config->oce_wan_scoring.num_slot =
+		mlme_scoring_cfg->oce_wan_scoring.num_slot;
+	score_config->oce_wan_scoring.score_pcnt3_to_0 =
+		mlme_scoring_cfg->oce_wan_scoring.score_pcnt3_to_0;
+	score_config->oce_wan_scoring.score_pcnt7_to_4 =
+		mlme_scoring_cfg->oce_wan_scoring.score_pcnt7_to_4;
+	score_config->oce_wan_scoring.score_pcnt11_to_8 =
+		mlme_scoring_cfg->oce_wan_scoring.score_pcnt11_to_8;
+	score_config->oce_wan_scoring.score_pcnt15_to_12 =
+		mlme_scoring_cfg->oce_wan_scoring.score_pcnt15_to_12;
+}
diff --git a/core/sme/src/common/sme_ft_api.c b/core/sme/src/common/sme_ft_api.c
new file mode 100644
index 0000000..da367cf
--- /dev/null
+++ b/core/sme/src/common/sme_ft_api.c
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#include <sir_common.h>
+#include <ani_global.h>
+#include <csr_inside_api.h>
+#include <csr_neighbor_roam.h>
+#include <sir_api.h>
+
+/* Initialize the FT context. */
+void sme_ft_open(tHalHandle hHal, uint32_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (NULL != pSession) {
+		/* Clean up the context */
+		qdf_mem_set(&pSession->ftSmeContext, sizeof(tftSMEContext), 0);
+
+		pSession->ftSmeContext.pUsrCtx =
+			qdf_mem_malloc(sizeof(tFTRoamCallbackUsrCtx));
+		if (!pSession->ftSmeContext.pUsrCtx)
+			return;
+
+		pSession->ftSmeContext.pUsrCtx->pMac = pMac;
+		pSession->ftSmeContext.pUsrCtx->sessionId = sessionId;
+
+		status =
+			qdf_mc_timer_init(&pSession->ftSmeContext.
+					  preAuthReassocIntvlTimer,
+					  QDF_TIMER_TYPE_SW,
+				sme_preauth_reassoc_intvl_timer_callback,
+					(void *)pSession->ftSmeContext.pUsrCtx);
+
+		if (QDF_STATUS_SUCCESS != status) {
+			sme_err("Preauth Reassoc interval Timer allocation failed");
+			qdf_mem_free(pSession->ftSmeContext.pUsrCtx);
+			pSession->ftSmeContext.pUsrCtx = NULL;
+			return;
+		}
+	}
+}
+
+/* Cleanup the SME FT Global context. */
+void sme_ft_close(tHalHandle hHal, uint32_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = NULL;
+
+	/* Clear the FT Context */
+	sme_ft_reset(hHal, sessionId);
+
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (NULL != pSession) {
+		/* check if the timer is running */
+		if (QDF_TIMER_STATE_RUNNING ==
+		    qdf_mc_timer_get_current_state(&pSession->ftSmeContext.
+						   preAuthReassocIntvlTimer)) {
+			qdf_mc_timer_stop(&pSession->ftSmeContext.
+					  preAuthReassocIntvlTimer);
+		}
+
+		qdf_mc_timer_destroy(&pSession->ftSmeContext.
+					preAuthReassocIntvlTimer);
+
+		if (pSession->ftSmeContext.pUsrCtx != NULL) {
+			qdf_mem_free(pSession->ftSmeContext.pUsrCtx);
+			pSession->ftSmeContext.pUsrCtx = NULL;
+		}
+	}
+}
+
+void sme_set_ft_pre_auth_state(tHalHandle hHal, uint32_t sessionId, bool state)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (pSession)
+		pSession->ftSmeContext.setFTPreAuthState = state;
+}
+
+bool sme_get_ft_pre_auth_state(tHalHandle hHal, uint32_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (pSession)
+		return pSession->ftSmeContext.setFTPreAuthState;
+
+	return false;
+}
+
+/**
+ * sme_set_ft_ies() - to set FT IEs
+ * @hal_ptr: pointer to HAL
+ * @session_id: sme session id
+ * @ft_ies: pointer to FT IEs
+ * @ft_ies_length: length of FT IEs
+ *
+ * Each time the supplicant sends down the FT IEs to the driver. This function
+ * is called in SME. This function packages and sends the FT IEs to PE.
+ *
+ * Return: none
+ */
+void sme_set_ft_ies(tHalHandle hal_ptr, uint32_t session_id,
+		const uint8_t *ft_ies, uint16_t ft_ies_length)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ptr);
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (NULL == session || NULL == ft_ies) {
+		sme_err("ft ies or session is NULL");
+		return;
+	}
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (!(QDF_IS_STATUS_SUCCESS(status)))
+		return;
+
+	sme_debug("FT IEs Req is received in state %d",
+		  session->ftSmeContext.FTState);
+
+	/* Global Station FT State */
+	switch (session->ftSmeContext.FTState) {
+	case eFT_START_READY:
+	case eFT_AUTH_REQ_READY:
+		sme_debug("ft_ies_length: %d", ft_ies_length);
+		if ((session->ftSmeContext.auth_ft_ies) &&
+			(session->ftSmeContext.auth_ft_ies_length)) {
+			/* Free the one we recvd last from supplicant */
+			qdf_mem_free(session->ftSmeContext.auth_ft_ies);
+			session->ftSmeContext.auth_ft_ies_length = 0;
+			session->ftSmeContext.auth_ft_ies = NULL;
+		}
+		ft_ies_length = QDF_MIN(ft_ies_length, MAX_FTIE_SIZE);
+		/* Save the FT IEs */
+		session->ftSmeContext.auth_ft_ies =
+					qdf_mem_malloc(ft_ies_length);
+		if (!session->ftSmeContext.auth_ft_ies) {
+			sme_release_global_lock(&mac_ctx->sme);
+			return;
+		}
+		session->ftSmeContext.auth_ft_ies_length = ft_ies_length;
+		qdf_mem_copy((uint8_t *)session->ftSmeContext.auth_ft_ies,
+				ft_ies, ft_ies_length);
+		session->ftSmeContext.FTState = eFT_AUTH_REQ_READY;
+		break;
+
+	case eFT_AUTH_COMPLETE:
+		/*
+		 * We will need to re-start preauth. If we received FT
+		 * IEs in eFT_PRE_AUTH_DONE state, it implies there was
+		 * a rekey in our pre-auth state. Hence this implies we
+		 * need Pre-auth again. OK now inform SME we have no
+		 * pre-auth list. Delete the pre-auth node locally. Set
+		 * your self back to restart pre-auth
+		 */
+		sme_debug("Preauth done & rcving AUTHREQ in state %d",
+			  session->ftSmeContext.FTState);
+		sme_debug("Unhandled reception of FT IES in state %d",
+			  session->ftSmeContext.FTState);
+		break;
+
+	case eFT_REASSOC_REQ_WAIT:
+		/*
+		 * We are done with pre-auth, hence now waiting for
+		 * reassoc req. This is the new FT Roaming in place At
+		 * this juncture we'r ready to start sending Reassoc req
+		 */
+
+		ft_ies_length = QDF_MIN(ft_ies_length, MAX_FTIE_SIZE);
+
+		sme_debug("New Reassoc Req: %pK in state %d",
+			ft_ies, session->ftSmeContext.FTState);
+		if ((session->ftSmeContext.reassoc_ft_ies) &&
+			(session->ftSmeContext.reassoc_ft_ies_length)) {
+			/* Free the one we recvd last from supplicant */
+			qdf_mem_free(session->ftSmeContext.reassoc_ft_ies);
+			session->ftSmeContext.reassoc_ft_ies_length = 0;
+		}
+		/* Save the FT IEs */
+		session->ftSmeContext.reassoc_ft_ies =
+					qdf_mem_malloc(ft_ies_length);
+		if (!session->ftSmeContext.reassoc_ft_ies) {
+			sme_release_global_lock(&mac_ctx->sme);
+			return;
+		}
+		session->ftSmeContext.reassoc_ft_ies_length =
+							ft_ies_length;
+		qdf_mem_copy((uint8_t *)session->ftSmeContext.reassoc_ft_ies,
+				ft_ies, ft_ies_length);
+
+		session->ftSmeContext.FTState = eFT_SET_KEY_WAIT;
+		sme_debug("ft_ies_length: %d state: %d", ft_ies_length,
+			  session->ftSmeContext.FTState);
+
+		break;
+
+	default:
+		sme_warn("Unhandled state: %d", session->ftSmeContext.FTState);
+		break;
+	}
+	sme_release_global_lock(&mac_ctx->sme);
+}
+
+/**
+ * sme_ft_send_update_key_ind() - To send key update indication for FT session
+ * @mac: pointer to MAC context
+ * @session_id: sme session id
+ * @ftkey_info: FT key information
+ *
+ * To send key update indication for FT session
+ *
+ * Return: QDF_STATUS
+ */
+static
+QDF_STATUS sme_ft_send_update_key_ind(tpAniSirGlobal mac, uint32_t session_id,
+				      tCsrRoamSetKey *ftkey_info)
+{
+	tSirFTUpdateKeyInfo *msg;
+	uint16_t msglen;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tSirKeyMaterial *keymaterial = NULL;
+	tAniEdType ed_type;
+
+	sme_debug("keyLength: %d", ftkey_info->keyLength);
+
+	if (ftkey_info->keyLength > CSR_MAX_KEY_LEN) {
+		sme_err("invalid keyLength: %d", ftkey_info->keyLength);
+		return QDF_STATUS_E_FAILURE;
+	}
+	msglen  = sizeof(tSirFTUpdateKeyInfo);
+
+	msg = qdf_mem_malloc(msglen);
+	if (!msg)
+		return QDF_STATUS_E_NOMEM;
+
+	msg->messageType = eWNI_SME_FT_UPDATE_KEY;
+	msg->length = msglen;
+
+	keymaterial = &msg->keyMaterial;
+	keymaterial->length = ftkey_info->keyLength;
+	ed_type = csr_translate_encrypt_type_to_ed_type(ftkey_info->encType);
+	keymaterial->edType = ed_type;
+	keymaterial->numKeys = 1;
+	keymaterial->key[0].keyId = ftkey_info->keyId;
+	keymaterial->key[0].unicast = (uint8_t) true;
+	keymaterial->key[0].keyDirection = ftkey_info->keyDirection;
+
+	qdf_mem_copy(&keymaterial->key[0].keyRsc,
+			ftkey_info->keyRsc, CSR_MAX_RSC_LEN);
+	keymaterial->key[0].paeRole = ftkey_info->paeRole;
+	keymaterial->key[0].keyLength = ftkey_info->keyLength;
+
+	if (ftkey_info->keyLength)
+		qdf_mem_copy(&keymaterial->key[0].key, ftkey_info->Key,
+				ftkey_info->keyLength);
+
+	qdf_copy_macaddr(&msg->bssid, &ftkey_info->peerMac);
+	msg->smeSessionId = session_id;
+	sme_debug("BSSID = " MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg->bssid.bytes));
+	status = umac_send_mb_message_to_mac(msg);
+
+	return status;
+}
+
+bool sme_get_ftptk_state(tHalHandle hHal, uint32_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("pSession is NULL");
+		return false;
+	}
+	return pSession->ftSmeContext.setFTPTKState;
+}
+
+void sme_set_ftptk_state(tHalHandle hHal, uint32_t sessionId, bool state)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("pSession is NULL");
+		return;
+	}
+	pSession->ftSmeContext.setFTPTKState = state;
+}
+
+QDF_STATUS sme_ft_update_key(tHalHandle hHal, uint32_t sessionId,
+			     tCsrRoamSetKey *pFTKeyInfo)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!pSession) {
+		sme_err("pSession is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pFTKeyInfo == NULL) {
+		sme_err("pFTKeyInfo is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!(QDF_IS_STATUS_SUCCESS(status)))
+		return QDF_STATUS_E_FAILURE;
+
+	sme_debug("FT update key is received in state %d",
+		  pSession->ftSmeContext.FTState);
+
+	/* Global Station FT State */
+	switch (pSession->ftSmeContext.FTState) {
+	case eFT_SET_KEY_WAIT:
+		if (sme_get_ft_pre_auth_state(hHal, sessionId) == true) {
+			status = sme_ft_send_update_key_ind(pMac, sessionId,
+								pFTKeyInfo);
+			if (status != 0) {
+				sme_err("Key set failure: %d", status);
+				pSession->ftSmeContext.setFTPTKState = false;
+				status = QDF_STATUS_FT_PREAUTH_KEY_FAILED;
+			} else {
+				pSession->ftSmeContext.setFTPTKState = true;
+				status = QDF_STATUS_FT_PREAUTH_KEY_SUCCESS;
+				sme_debug("Key set success");
+			}
+			sme_set_ft_pre_auth_state(hHal, sessionId, false);
+		}
+
+		pSession->ftSmeContext.FTState = eFT_START_READY;
+		sme_debug("state changed to %d status %d",
+			  pSession->ftSmeContext.FTState, status);
+		break;
+
+	default:
+		sme_debug("Unhandled state:%d", pSession->ftSmeContext.FTState);
+		status = QDF_STATUS_E_FAILURE;
+		break;
+	}
+	sme_release_global_lock(&pMac->sme);
+
+	return status;
+}
+
+/*
+ * HDD Interface to SME. SME now sends the Auth 2 and RIC IEs up to the
+ * supplicant. The supplicant will then proceed to send down the
+ * Reassoc Req.
+ */
+void sme_get_ft_pre_auth_response(tHalHandle hHal, uint32_t sessionId,
+				  uint8_t *ft_ies, uint32_t ft_ies_ip_len,
+				  uint16_t *ft_ies_length)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!pSession) {
+		sme_err("pSession is NULL");
+		return;
+	}
+
+	*ft_ies_length = 0;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!(QDF_IS_STATUS_SUCCESS(status)))
+		return;
+
+	/* All or nothing - proceed only if both BSSID and FT IE fit */
+	if ((QDF_MAC_ADDR_SIZE +
+	     pSession->ftSmeContext.psavedFTPreAuthRsp->ft_ies_length) >
+	    ft_ies_ip_len) {
+		sme_release_global_lock(&pMac->sme);
+		return;
+	}
+	/* hdd needs to pack the bssid also along with the */
+	/* auth response to supplicant */
+	qdf_mem_copy(ft_ies, pSession->ftSmeContext.preAuthbssId,
+		     QDF_MAC_ADDR_SIZE);
+
+	/* Copy the auth resp FTIEs */
+	qdf_mem_copy(&(ft_ies[QDF_MAC_ADDR_SIZE]),
+		     pSession->ftSmeContext.psavedFTPreAuthRsp->ft_ies,
+		     pSession->ftSmeContext.psavedFTPreAuthRsp->ft_ies_length);
+
+	*ft_ies_length = QDF_MAC_ADDR_SIZE +
+		pSession->ftSmeContext.psavedFTPreAuthRsp->ft_ies_length;
+
+	pSession->ftSmeContext.FTState = eFT_REASSOC_REQ_WAIT;
+
+	sme_debug("Filled auth resp: %d", *ft_ies_length);
+	sme_release_global_lock(&pMac->sme);
+}
+
+/*
+ * SME now sends the RIC IEs up to the supplicant.
+ * The supplicant will then proceed to send down the
+ * Reassoc Req.
+ */
+void sme_get_rici_es(tHalHandle hHal, uint32_t sessionId, uint8_t *ric_ies,
+		     uint32_t ric_ies_ip_len, uint32_t *ric_ies_length)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!pSession) {
+		sme_err("pSession is NULL");
+		return;
+	}
+
+	*ric_ies_length = 0;
+
+	status = sme_acquire_global_lock(&pMac->sme);
+	if (!(QDF_IS_STATUS_SUCCESS(status)))
+		return;
+
+	/* All or nothing */
+	if (pSession->ftSmeContext.psavedFTPreAuthRsp->ric_ies_length >
+	    ric_ies_ip_len) {
+		sme_release_global_lock(&pMac->sme);
+		return;
+	}
+
+	qdf_mem_copy(ric_ies,
+		     pSession->ftSmeContext.psavedFTPreAuthRsp->ric_ies,
+		     pSession->ftSmeContext.psavedFTPreAuthRsp->ric_ies_length);
+
+	*ric_ies_length =
+		pSession->ftSmeContext.psavedFTPreAuthRsp->ric_ies_length;
+
+	sme_debug("Filled ric ies: %d", *ric_ies_length);
+
+	sme_release_global_lock(&pMac->sme);
+}
+
+/*
+ * Timer callback for the timer that is started between the preauth completion
+ * and reassoc request to the PE. In this interval, it is expected that the
+ * pre-auth response and RIC IEs are passed up to the WPA supplicant and
+ * received back the necessary FTIEs required to be sent in the reassoc request
+ */
+void sme_preauth_reassoc_intvl_timer_callback(void *context)
+{
+	tFTRoamCallbackUsrCtx *pUsrCtx = (tFTRoamCallbackUsrCtx *) context;
+
+	if (pUsrCtx)
+		csr_neighbor_roam_request_handoff(pUsrCtx->pMac,
+						  pUsrCtx->sessionId);
+}
+
+/* Reset the FT context. */
+void sme_ft_reset(tHalHandle hHal, uint32_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	struct csr_roam_session *pSession = NULL;
+
+	if (pMac == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("pMac is NULL"));
+		return;
+	}
+
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (NULL != pSession) {
+		if (pSession->ftSmeContext.auth_ft_ies != NULL) {
+			qdf_mem_free(pSession->ftSmeContext.auth_ft_ies);
+			pSession->ftSmeContext.auth_ft_ies = NULL;
+		}
+		pSession->ftSmeContext.auth_ft_ies_length = 0;
+
+		if (pSession->ftSmeContext.reassoc_ft_ies != NULL) {
+			qdf_mem_free(pSession->ftSmeContext.reassoc_ft_ies);
+			pSession->ftSmeContext.reassoc_ft_ies = NULL;
+		}
+		pSession->ftSmeContext.reassoc_ft_ies_length = 0;
+
+		if (pSession->ftSmeContext.psavedFTPreAuthRsp != NULL) {
+			qdf_mem_free(pSession->ftSmeContext.psavedFTPreAuthRsp);
+			pSession->ftSmeContext.psavedFTPreAuthRsp = NULL;
+		}
+		pSession->ftSmeContext.setFTPreAuthState = false;
+		pSession->ftSmeContext.setFTPTKState = false;
+
+		qdf_mem_zero(pSession->ftSmeContext.preAuthbssId,
+			     QDF_MAC_ADDR_SIZE);
+		pSession->ftSmeContext.FTState = eFT_START_READY;
+	}
+}
+
+/* End of File */
diff --git a/core/sme/src/common/sme_power_save.c b/core/sme/src/common/sme_power_save.c
new file mode 100644
index 0000000..91e0e7c
--- /dev/null
+++ b/core/sme/src/common/sme_power_save.c
@@ -0,0 +1,901 @@
+/*
+ * Copyright (c) 2015-2018 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.
+ */
+
+#include "sme_power_save.h"
+#include "sme_power_save_api.h"
+#include <sir_common.h>
+#include <ani_global.h>
+#include <utils_api.h>
+#include "sme_trace.h"
+#include "qdf_mem.h"
+#include "qdf_types.h"
+#include "wma.h"
+#include "wma_internal.h"
+#include "wmm_apsd.h"
+#include "cfg_api.h"
+#include "csr_inside_api.h"
+
+/**
+ * sme_post_ps_msg_to_wma(): post message to WMA.
+ * @type: type
+ * @body: body pointer
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_post_ps_msg_to_wma(uint16_t type, void *body)
+{
+	struct scheduler_msg msg = {0};
+
+	msg.type = type;
+	msg.reserved = 0;
+	msg.bodyptr = body;
+	msg.bodyval = 0;
+
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_WMA,
+							 QDF_MODULE_ID_WMA,
+							 &msg)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Posting message %d failed",
+				__func__, type);
+		qdf_mem_free(body);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_ps_enable_uapsd_req_params(): enables UASPD req params
+ * @mac_ctx: global mac context
+ * @session_id: session id
+ *
+ * Return: QDF_STATUS
+ */
+static void sme_ps_fill_uapsd_req_params(tpAniSirGlobal mac_ctx,
+		tUapsd_Params *uapsdParams, uint32_t session_id,
+		enum ps_state *ps_state)
+{
+
+	uint8_t uapsd_delivery_mask = 0;
+	uint8_t uapsd_trigger_mask = 0;
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
+
+	uapsd_delivery_mask =
+		ps_param->uapsd_per_ac_bit_mask |
+		ps_param->uapsd_per_ac_delivery_enable_mask;
+
+	uapsd_trigger_mask =
+		ps_param->uapsd_per_ac_bit_mask |
+		ps_param->uapsd_per_ac_trigger_enable_mask;
+
+	uapsdParams->bkDeliveryEnabled =
+		LIM_UAPSD_GET(ACBK, uapsd_delivery_mask);
+
+	uapsdParams->beDeliveryEnabled =
+		LIM_UAPSD_GET(ACBE, uapsd_delivery_mask);
+
+	uapsdParams->viDeliveryEnabled =
+		LIM_UAPSD_GET(ACVI, uapsd_delivery_mask);
+
+	uapsdParams->voDeliveryEnabled =
+		LIM_UAPSD_GET(ACVO, uapsd_delivery_mask);
+
+	uapsdParams->bkTriggerEnabled =
+		LIM_UAPSD_GET(ACBK, uapsd_trigger_mask);
+
+	uapsdParams->beTriggerEnabled =
+		LIM_UAPSD_GET(ACBE, uapsd_trigger_mask);
+
+	uapsdParams->viTriggerEnabled =
+		LIM_UAPSD_GET(ACVI, uapsd_trigger_mask);
+
+	uapsdParams->voTriggerEnabled =
+		LIM_UAPSD_GET(ACVO, uapsd_trigger_mask);
+	if (ps_param->ps_state != FULL_POWER_MODE) {
+		uapsdParams->enable_ps = true;
+		*ps_state = UAPSD_MODE;
+	} else {
+		uapsdParams->enable_ps = false;
+		*ps_state = FULL_POWER_MODE;
+	}
+}
+
+static void sme_set_ps_state(tpAniSirGlobal mac_ctx,
+		uint32_t session_id, enum ps_state ps_state)
+{
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
+
+	ps_param->ps_state = ps_state;
+}
+
+static void sme_get_ps_state(tpAniSirGlobal mac_ctx,
+		uint32_t session_id, enum ps_state *ps_state)
+{
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
+	*ps_state = ps_param->ps_state;
+}
+/**
+ * sme_ps_enable_ps_req_params(): enables power save req params
+ * @mac_ctx: global mac context
+ * @session_id: session id
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_ps_enable_ps_req_params(tpAniSirGlobal mac_ctx,
+		uint32_t session_id)
+{
+	struct sEnablePsParams *enable_ps_req_params;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
+	enum ps_state ps_state;
+
+	enable_ps_req_params =  qdf_mem_malloc(sizeof(*enable_ps_req_params));
+	if (!enable_ps_req_params)
+		return QDF_STATUS_E_NOMEM;
+
+	if (ps_param->uapsd_per_ac_bit_mask) {
+		enable_ps_req_params->psSetting = eSIR_ADDON_ENABLE_UAPSD;
+		sme_ps_fill_uapsd_req_params(mac_ctx,
+				&enable_ps_req_params->uapsdParams,
+				session_id, &ps_state);
+		ps_state = UAPSD_MODE;
+		enable_ps_req_params->uapsdParams.enable_ps = true;
+	} else {
+		enable_ps_req_params->psSetting = eSIR_ADDON_NOTHING;
+		ps_state = LEGACY_POWER_SAVE_MODE;
+	}
+	enable_ps_req_params->sessionid = session_id;
+
+	status = sme_post_ps_msg_to_wma(WMA_ENTER_PS_REQ, enable_ps_req_params);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_E_FAILURE;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL("Message WMA_ENTER_PS_REQ Successfully sent to WMA"));
+	ps_param->ps_state = ps_state;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_ps_disable_ps_req_params(): Disable power save req params
+ * @mac_ctx: global mac context
+ * @session_id: session id
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_ps_disable_ps_req_params(tpAniSirGlobal mac_ctx,
+		uint32_t session_id)
+{
+	struct  sDisablePsParams *disable_ps_req_params;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	disable_ps_req_params = qdf_mem_malloc(sizeof(*disable_ps_req_params));
+	if (!disable_ps_req_params)
+		return QDF_STATUS_E_NOMEM;
+
+	disable_ps_req_params->psSetting = eSIR_ADDON_NOTHING;
+	disable_ps_req_params->sessionid = session_id;
+
+	status = sme_post_ps_msg_to_wma(WMA_EXIT_PS_REQ, disable_ps_req_params);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_E_FAILURE;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("Message WMA_EXIT_PS_REQ Successfully sent to WMA"));
+	sme_set_ps_state(mac_ctx, session_id, FULL_POWER_MODE);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_ps_enable_uapsd_req_params(): enables UASPD req params
+ * @mac_ctx: global mac context
+ * @session_id: session id
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_ps_enable_uapsd_req_params(tpAniSirGlobal mac_ctx,
+		uint32_t session_id)
+{
+
+	struct sEnableUapsdParams *enable_uapsd_req_params;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	enum ps_state ps_state;
+
+	enable_uapsd_req_params =
+		qdf_mem_malloc(sizeof(*enable_uapsd_req_params));
+	if (!enable_uapsd_req_params)
+		return QDF_STATUS_E_NOMEM;
+
+	sme_ps_fill_uapsd_req_params(mac_ctx,
+			&enable_uapsd_req_params->uapsdParams,
+			session_id, &ps_state);
+	enable_uapsd_req_params->sessionid = session_id;
+
+	status = sme_post_ps_msg_to_wma(WMA_ENABLE_UAPSD_REQ,
+					enable_uapsd_req_params);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_E_FAILURE;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		    FL("Msg WMA_ENABLE_UAPSD_REQ Successfully sent to WMA"));
+	sme_set_ps_state(mac_ctx, session_id, ps_state);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_ps_disable_uapsd_req_params(): disables UASPD req params
+ * @mac_ctx: global mac context
+ * @session_id: session id
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_ps_disable_uapsd_req_params(tpAniSirGlobal mac_ctx,
+		uint32_t session_id)
+{
+	struct sDisableUapsdParams *disable_uapsd_req_params;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	enum ps_state ps_state;
+
+	sme_get_ps_state(mac_ctx, session_id, &ps_state);
+	if (ps_state != UAPSD_MODE) {
+		sme_err("UAPSD is already disabled");
+		return QDF_STATUS_SUCCESS;
+	}
+	disable_uapsd_req_params =
+		qdf_mem_malloc(sizeof(*disable_uapsd_req_params));
+	if (!disable_uapsd_req_params)
+		return QDF_STATUS_E_NOMEM;
+
+	disable_uapsd_req_params->sessionid = session_id;
+	status = sme_post_ps_msg_to_wma(WMA_DISABLE_UAPSD_REQ,
+					disable_uapsd_req_params);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_E_FAILURE;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL("Message WMA_DISABLE_UAPSD_REQ Successfully sent to WMA"));
+	sme_set_ps_state(mac_ctx, session_id, LEGACY_POWER_SAVE_MODE);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_ps_process_command(): Sme process power save messages
+ *			and pass messages to WMA.
+ * @mac_ctx: global mac context
+ * @session_id: session id
+ * sme_ps_cmd: power save message
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_ps_process_command(tpAniSirGlobal mac_ctx, uint32_t session_id,
+		enum sme_ps_cmd command)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("Invalid Session_id: %d", session_id);
+		return QDF_STATUS_E_INVAL;
+	}
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("Power Save command %d"), command);
+	switch (command) {
+	case SME_PS_ENABLE:
+		status = sme_ps_enable_ps_req_params(mac_ctx, session_id);
+		break;
+	case SME_PS_DISABLE:
+		status = sme_ps_disable_ps_req_params(mac_ctx, session_id);
+		break;
+	case SME_PS_UAPSD_ENABLE:
+		status = sme_ps_enable_uapsd_req_params(mac_ctx, session_id);
+		break;
+	case SME_PS_UAPSD_DISABLE:
+		status = sme_ps_disable_uapsd_req_params(mac_ctx, session_id);
+		break;
+	default:
+		sme_err("Invalid command type: %d", command);
+		status = QDF_STATUS_E_FAILURE;
+		break;
+	}
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("Not able to enter in PS, Command: %d"), command);
+	}
+	return status;
+}
+
+/**
+ * sme_enable_sta_ps_check(): Checks if it is ok to enable power save or not.
+ * @mac_ctx: global mac context
+ * @session_id: session id
+ * @command: power save cmd of type enum sme_ps_cmd
+ *
+ *Pre Condition for enabling sta mode power save
+ *1) Sta Mode Ps should be enabled in ini file.
+ *2) Session should be in infra mode and in connected state.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_enable_sta_ps_check(tpAniSirGlobal mac_ctx, uint32_t session_id)
+{
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+
+	QDF_BUG(session_id < CSR_ROAM_SESSION_MAX);
+	if (session_id >= CSR_ROAM_SESSION_MAX)
+		return QDF_STATUS_E_INVAL;
+
+	/* Check if Sta Ps is enabled. */
+	if (!ps_global_info->ps_enabled) {
+		sme_debug("Cannot initiate PS. PS is disabled in ini");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Check whether the given session is Infra and in Connected State
+	 * also if command is power save disable  there is not need to check
+	 * for connected state as firmware can handle this
+	 */
+	if (!csr_is_conn_state_connected_infra(mac_ctx, session_id)) {
+		sme_debug("STA not infra/connected state Session_id: %d",
+			  session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_ps_enable_disable(): function to enable/disable PS.
+ * @hal_ctx: global hal_handle
+ * @session_id: session id
+ * sme_ps_cmd: power save message
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_ps_enable_disable(tHalHandle hal_ctx, uint32_t session_id,
+		enum sme_ps_cmd command)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+
+	status =  sme_enable_sta_ps_check(mac_ctx, session_id);
+	if (status != QDF_STATUS_SUCCESS) {
+		/*
+		 * In non associated state driver wont handle the power save
+		 * But kernel expects return status success even
+		 * in the disconnected state.
+		 * TODO: If driver to remember the ps state to further use
+		 * after connection.
+		 */
+		if (!csr_is_conn_state_connected_infra(mac_ctx, session_id))
+			status = QDF_STATUS_SUCCESS;
+		return status;
+	}
+	status = sme_ps_process_command(mac_ctx, session_id, command);
+	return status;
+}
+
+QDF_STATUS sme_ps_timer_flush_sync(tHalHandle hal, uint8_t session_id)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct ps_params *ps_parm;
+	enum ps_state ps_state;
+	QDF_TIMER_STATE tstate;
+	struct sEnablePsParams *req;
+	t_wma_handle *wma;
+
+	QDF_BUG(session_id < CSR_ROAM_SESSION_MAX);
+	if (session_id >= CSR_ROAM_SESSION_MAX)
+		return QDF_STATUS_E_INVAL;
+
+	status = sme_enable_sta_ps_check(mac_ctx, session_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_debug("Power save not allowed for vdev id %d", session_id);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	ps_parm = &mac_ctx->sme.ps_global_info.ps_params[session_id];
+	tstate = qdf_mc_timer_get_current_state(&ps_parm->auto_ps_enable_timer);
+	if (tstate != QDF_TIMER_STATE_RUNNING)
+		return QDF_STATUS_SUCCESS;
+
+	sme_debug("flushing powersave enable for vdev %u", session_id);
+
+	qdf_mc_timer_stop(&ps_parm->auto_ps_enable_timer);
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		sme_err("wma is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return QDF_STATUS_E_NOMEM;
+
+	if (ps_parm->uapsd_per_ac_bit_mask) {
+		req->psSetting = eSIR_ADDON_ENABLE_UAPSD;
+		sme_ps_fill_uapsd_req_params(mac_ctx, &req->uapsdParams,
+					     session_id, &ps_state);
+		ps_state = UAPSD_MODE;
+		req->uapsdParams.enable_ps = true;
+	} else {
+		req->psSetting = eSIR_ADDON_NOTHING;
+		ps_state = LEGACY_POWER_SAVE_MODE;
+	}
+	req->sessionid = session_id;
+
+	wma_enable_sta_ps_mode(wma, req);
+	qdf_mem_free(req);
+
+	ps_parm->ps_state = ps_state;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_ps_uapsd_enable(): function to enable UAPSD.
+ * @hal_ctx: global hal_handle
+ * @session_id: session id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_ps_uapsd_enable(tHalHandle hal_ctx, uint32_t session_id)
+{
+
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+
+	status =  sme_enable_sta_ps_check(mac_ctx, session_id);
+	if (status != QDF_STATUS_SUCCESS)
+		return status;
+	status = sme_ps_process_command(mac_ctx, session_id,
+			SME_PS_UAPSD_ENABLE);
+	if (status == QDF_STATUS_SUCCESS)
+		sme_offload_qos_process_into_uapsd_mode(mac_ctx, session_id);
+
+	return status;
+}
+
+/**
+ * sme_ps_uapsd_disable(): function to disable UAPSD.
+ * @hal_ctx: global hal_handle
+ * @session_id: session id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_ps_uapsd_disable(tHalHandle hal_ctx, uint32_t session_id)
+{
+
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+
+	status = sme_enable_sta_ps_check(mac_ctx, session_id);
+	if (status != QDF_STATUS_SUCCESS)
+		return status;
+	status = sme_ps_process_command(mac_ctx, session_id,
+			SME_PS_UAPSD_DISABLE);
+	if (status == QDF_STATUS_SUCCESS)
+		sme_offload_qos_process_out_of_uapsd_mode(mac_ctx, session_id);
+
+	return status;
+}
+
+/**
+ * sme_set_tspec_uapsd_mask_per_session(): set tspec UAPSD mask per session
+ * @mac_ctx: global mac context
+ * @ts_info: tspec info.
+ * @session_id: session id
+ *
+ * Return: QDF_STATUS
+ */
+void sme_set_tspec_uapsd_mask_per_session(tpAniSirGlobal mac_ctx,
+		tSirMacTSInfo *ts_info,
+		uint8_t session_id)
+{
+	uint8_t user_prio = (uint8_t) ts_info->traffic.userPrio;
+	uint16_t direction = ts_info->traffic.direction;
+	uint8_t ac = upToAc(user_prio);
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
+
+	sme_err("Set UAPSD mask for AC: %d dir: %d action: %d",
+		ac, direction, ts_info->traffic.psb);
+
+	/* Converting AC to appropriate Uapsd Bit Mask
+	 * AC_BE(0) --> UAPSD_BITOFFSET_ACVO(3)
+	 * AC_BK(1) --> UAPSD_BITOFFSET_ACVO(2)
+	 * AC_VI(2) --> UAPSD_BITOFFSET_ACVO(1)
+	 * AC_VO(3) --> UAPSD_BITOFFSET_ACVO(0)
+	 */
+	ac = ((~ac) & 0x3);
+	if (ts_info->traffic.psb) {
+		ps_param->uapsd_per_ac_bit_mask |= (1 << ac);
+		if (direction == SIR_MAC_DIRECTION_UPLINK)
+			ps_param->uapsd_per_ac_trigger_enable_mask |=
+				(1 << ac);
+		else if (direction == SIR_MAC_DIRECTION_DNLINK)
+			ps_param->uapsd_per_ac_delivery_enable_mask |=
+				(1 << ac);
+		else if (direction == SIR_MAC_DIRECTION_BIDIR) {
+			ps_param->uapsd_per_ac_trigger_enable_mask |=
+				(1 << ac);
+			ps_param->uapsd_per_ac_delivery_enable_mask |=
+				(1 << ac);
+		}
+	} else {
+		ps_param->uapsd_per_ac_bit_mask &= ~(1 << ac);
+		if (direction == SIR_MAC_DIRECTION_UPLINK)
+			ps_param->uapsd_per_ac_trigger_enable_mask &=
+				~(1 << ac);
+		else if (direction == SIR_MAC_DIRECTION_DNLINK)
+			ps_param->uapsd_per_ac_delivery_enable_mask &=
+				~(1 << ac);
+		else if (direction == SIR_MAC_DIRECTION_BIDIR) {
+			ps_param->uapsd_per_ac_trigger_enable_mask &=
+				~(1 << ac);
+			ps_param->uapsd_per_ac_delivery_enable_mask &=
+				~(1 << ac);
+		}
+	}
+
+	/*
+	 * ADDTS success, so AC is now admitted. We shall now use the default
+	 * EDCA parameters as advertised by AP and send the updated EDCA params
+	 * to HAL.
+	 */
+	if (direction == SIR_MAC_DIRECTION_UPLINK) {
+		ps_param->ac_admit_mask[SIR_MAC_DIRECTION_UPLINK] |=
+			(1 << ac);
+	} else if (direction == SIR_MAC_DIRECTION_DNLINK) {
+		ps_param->ac_admit_mask[SIR_MAC_DIRECTION_DNLINK] |=
+			(1 << ac);
+	} else if (direction == SIR_MAC_DIRECTION_BIDIR) {
+		ps_param->ac_admit_mask[SIR_MAC_DIRECTION_UPLINK] |=
+			(1 << ac);
+		ps_param->ac_admit_mask[SIR_MAC_DIRECTION_DNLINK] |=
+			(1 << ac);
+	}
+
+	sme_debug("New ps_param->uapsd_per_ac_trigger_enable_mask: 0x%x",
+		ps_param->uapsd_per_ac_trigger_enable_mask);
+	sme_debug("New  ps_param->uapsd_per_ac_delivery_enable_mask: 0x%x",
+		ps_param->uapsd_per_ac_delivery_enable_mask);
+	sme_debug("New ps_param->ac_admit_mask[SIR_MAC_DIRECTION_UPLINK]: 0x%x",
+		ps_param->ac_admit_mask[SIR_MAC_DIRECTION_UPLINK]);
+}
+
+/**
+ * sme_ps_start_uapsd(): function to start UAPSD.
+ * @hal_ctx: global hal_handle
+ * @session_id: session id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_ps_start_uapsd(tHalHandle hal_ctx, uint32_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	status = sme_ps_uapsd_enable(hal_ctx, session_id);
+	return status;
+}
+
+/**
+ * sme_set_ps_host_offload(): Set the host offload feature.
+ * @hal_ctx - The handle returned by mac_open.
+ * @request - Pointer to the offload request.
+ *
+ * Return QDF_STATUS
+ *            QDF_STATUS_E_FAILURE  Cannot set the offload.
+ *            QDF_STATUS_SUCCESS  Request accepted.
+ */
+QDF_STATUS sme_set_ps_host_offload(tHalHandle hal_ctx,
+		tpSirHostOffloadReq request,
+		uint8_t session_id)
+{
+	tpSirHostOffloadReq request_buf;
+	struct scheduler_msg msg = {0};
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"%s: IP address = %d.%d.%d.%d", __func__,
+			request->params.hostIpv4Addr[0],
+			request->params.hostIpv4Addr[1],
+			request->params.hostIpv4Addr[2],
+			request->params.hostIpv4Addr[3]);
+
+	if (NULL == session) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: SESSION not Found", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	request_buf = qdf_mem_malloc(sizeof(tSirHostOffloadReq));
+	if (!request_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_copy_macaddr(&request->bssid, &session->connectedProfile.bssid);
+
+	qdf_mem_copy(request_buf, request, sizeof(tSirHostOffloadReq));
+
+	msg.type = WMA_SET_HOST_OFFLOAD;
+	msg.reserved = 0;
+	msg.bodyptr = request_buf;
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			 session_id, msg.type));
+	if (QDF_STATUS_SUCCESS !=
+			scheduler_post_message(QDF_MODULE_ID_SME,
+					       QDF_MODULE_ID_WMA,
+					       QDF_MODULE_ID_WMA, &msg)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+		      FL("Not able to post WMA_SET_HOST_OFFLOAD msg to WMA"));
+		qdf_mem_free(request_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_NS_OFFLOAD
+/**
+ * sme_set_ps_ns_offload(): Set the host offload feature.
+ * @hal_ctx - The handle returned by mac_open.
+ * @request - Pointer to the offload request.
+ *
+ * Return QDF_STATUS
+ *		QDF_STATUS_E_FAILURE  Cannot set the offload.
+ *		QDF_STATUS_SUCCESS  Request accepted.
+ */
+QDF_STATUS sme_set_ps_ns_offload(tHalHandle hal_ctx,
+		tpSirHostOffloadReq request,
+		uint8_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+	tpSirHostOffloadReq request_buf;
+	struct scheduler_msg msg = {0};
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (NULL == session) {
+		sme_err("Session not found");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_copy_macaddr(&request->bssid, &session->connectedProfile.bssid);
+
+	request_buf = qdf_mem_malloc(sizeof(*request_buf));
+	if (!request_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	*request_buf = *request;
+
+	msg.type = WMA_SET_NS_OFFLOAD;
+	msg.reserved = 0;
+	msg.bodyptr = request_buf;
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			 session_id, msg.type));
+	if (QDF_STATUS_SUCCESS !=
+			scheduler_post_message(QDF_MODULE_ID_SME,
+					       QDF_MODULE_ID_WMA,
+					       QDF_MODULE_ID_WMA, &msg)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"Not able to post SIR_HAL_SET_HOST_OFFLOAD message to HAL");
+		qdf_mem_free(request_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif /* WLAN_NS_OFFLOAD */
+/**
+ * sme_post_pe_message
+ *
+ * FUNCTION:
+ * Post a message to the pmm message queue
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param msg pointer to message
+ * @return None
+ */
+
+QDF_STATUS sme_post_pe_message(tpAniSirGlobal mac_ctx,
+			       struct scheduler_msg *msg)
+{
+	QDF_STATUS qdf_status;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_PE,
+					    QDF_MODULE_ID_PE,
+					    msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		sme_err("scheduler_post_msg failed with status: %d",
+			qdf_status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sme_ps_enable_auto_ps_timer(tHalHandle hal_ctx,
+	uint32_t session_id, uint32_t timeout)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
+	QDF_STATUS qdf_status;
+
+	if (!timeout) {
+		sme_debug("auto_ps_timer called with timeout 0; ignore");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	sme_debug("Start auto_ps_timer for %d ms", timeout);
+
+	qdf_status = qdf_mc_timer_start(&ps_param->auto_ps_enable_timer,
+		timeout);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		if (QDF_STATUS_E_ALREADY == qdf_status) {
+			/* Consider this ok since the timer is already started*/
+			sme_debug("auto_ps_timer is already started");
+		} else {
+			sme_err("Cannot start auto_ps_timer");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sme_ps_disable_auto_ps_timer(tHalHandle hal_ctx,
+		uint32_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
+	/*
+	 * Stop the auto ps entry timer if runnin
+	 */
+	if (QDF_TIMER_STATE_RUNNING ==
+			qdf_mc_timer_get_current_state(
+				&ps_param->auto_ps_enable_timer)) {
+		sme_info("Stop auto_ps_enable_timer Timer for session ID: %d",
+				session_id);
+		qdf_mc_timer_stop(&ps_param->auto_ps_enable_timer);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS sme_ps_open(tHalHandle hal_ctx)
+{
+
+	uint32_t i;
+
+	for (i = 0; i < SIR_MAX_SUPPORTED_BSS; i++) {
+		if (QDF_STATUS_SUCCESS != sme_ps_open_per_session(hal_ctx, i)) {
+			sme_err("PMC Init Failed for session: %d", i);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS sme_ps_open_per_session(tHalHandle hal_ctx, uint32_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
+
+	ps_param->session_id = session_id;
+	ps_param->mac_ctx = mac_ctx;
+	/* Allocate a timer to enable ps automatically */
+	if (!QDF_IS_STATUS_SUCCESS(qdf_mc_timer_init(
+					&ps_param->auto_ps_enable_timer,
+					QDF_TIMER_TYPE_SW,
+					sme_auto_ps_entry_timer_expired,
+					ps_param)))     {
+		sme_err("Cannot allocate timer for auto ps entry");
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+
+}
+
+void sme_auto_ps_entry_timer_expired(void *data)
+{
+	struct ps_params *ps_params = (struct ps_params *)data;
+	tpAniSirGlobal mac_ctx;
+	uint32_t session_id;
+	QDF_STATUS status;
+
+	if (!ps_params) {
+		sme_err("ps_params is NULL");
+		return;
+	}
+	mac_ctx = (tpAniSirGlobal)ps_params->mac_ctx;
+	if (!mac_ctx) {
+		sme_err("mac_ctx is NULL");
+		return;
+	}
+	session_id = ps_params->session_id;
+	sme_debug("auto_ps_timer expired, enabling powersave");
+
+	status = sme_enable_sta_ps_check(mac_ctx, session_id);
+	if (QDF_STATUS_SUCCESS == status)
+		sme_ps_enable_disable((tHalHandle)mac_ctx, session_id,
+				SME_PS_ENABLE);
+}
+
+QDF_STATUS sme_ps_close(tHalHandle hal_ctx)
+{
+	uint32_t i;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
+		sme_ps_close_per_session(hal_ctx, i);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sme_ps_close_per_session(tHalHandle hal_ctx, uint32_t session_id)
+{
+
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	/*
+	 * Stop the auto ps entry timer if running
+	 */
+	if (QDF_TIMER_STATE_RUNNING ==
+			qdf_mc_timer_get_current_state(
+				&ps_param->auto_ps_enable_timer))
+		qdf_mc_timer_stop(&ps_param->auto_ps_enable_timer);
+
+	qdf_status =
+		qdf_mc_timer_destroy(&ps_param->auto_ps_enable_timer);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		sme_err("Cannot deallocate suto PS timer");
+	return qdf_status;
+}
+
+bool sme_is_auto_ps_timer_running(tHalHandle hal_ctx,
+		uint32_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
+	bool status = false;
+	/*
+	 * Check if the auto ps entry timer if running
+	 */
+	if (QDF_TIMER_STATE_RUNNING ==
+			qdf_mc_timer_get_current_state(
+				&ps_param->auto_ps_enable_timer))
+		status = true;
+
+	return status;
+}
+
diff --git a/core/sme/src/common/sme_trace.c b/core/sme/src/common/sme_trace.c
new file mode 100644
index 0000000..b5200a6
--- /dev/null
+++ b/core/sme/src/common/sme_trace.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2013-2018 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: smeTrace.c
+ *  Implementation for trace related APIs
+ *
+ * Author Kiran Kumar Reddy CH L V
+ */
+#include "ani_global.h"          /* for tpAniSirGlobal */
+#include "mac_trace.h"
+#include "sme_trace.h"
+#include "sme_internal.h"
+#ifndef SME_TRACE_RECORD
+void sme_trace_init(tpAniSirGlobal pMac)
+{
+
+}
+#endif
+#ifdef SME_TRACE_RECORD
+
+static uint8_t *sme_trace_get_rx_msg_string(uint32_t code)
+{
+	switch (code) {
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_CONNECT);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO);
+		CASE_RETURN_STRING
+			(TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND);
+		CASE_RETURN_STRING
+			(TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS);
+		CASE_RETURN_STRING
+			(TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS);
+		CASE_RETURN_STRING
+			(TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST);
+		CASE_RETURN_STRING
+			(TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETNEXT);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_REASSOC);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT);
+		CASE_RETURN_STRING
+			(TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE);
+		CASE_RETURN_STRING
+			(TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_GET_PMKIDCACHE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_CONFIG_PWRSAVE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CONFIG_PWRSAVE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ENABLE_PWRSAVE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DISABLE_PWRSAVE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SIGNAL_POWER_EVENT);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_START_AUTO_BMPSTIMER);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_STOP_AUTO_BMPSTIMER);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_IS_PWRSAVE_ENABLED);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REQUEST_FULLPOWER);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REQUEST_BMPS);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REQUEST_STANDBY);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ENTER_WOWL);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_EXIT_WOWL);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_KEY);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REMOVE_KEY);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_STATS);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_RSSI);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_READREG);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_WRITEREG);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_READMEM);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_WRITEMEM);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_OPEN_SESSION);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CLOSE_SESSION);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_GTKOFFLOAD);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_GTKOFFLOAD);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SEND_ACTION);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ);
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2);
+#endif
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_TXPOW);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_TMLEVEL);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CAPS_EXCH);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DISABLE_CAP);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_DEFCCNV);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CURCC);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_RESET_PW5G);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_RP5G);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_RSSIDIFF);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_IMMRSSIDIFF);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_WESMODE);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_SCANCTRL);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE);
+		CASE_RETURN_STRING
+			(TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES);
+		CASE_RETURN_STRING
+			(TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_STORE_JOIN_REQ);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CLEAR_JOIN_REQ);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ISSUE_JOIN_REQ);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA);
+#ifdef FEATURE_WLAN_TDLS
+		CASE_RETURN_STRING
+			(TRACE_CODE_SME_RX_HDD_TDLS_LINK_ESTABLISH_PARAM);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_TDLS_CHAN_SWITCH_REQ);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_TDLS_SEND_MGMT_FRAME);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_TDLS_CHANGE_PEER_STA);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_TDLS_ADD_PEER_STA);
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_TDLS_DEL_PEER_STA);
+#endif
+		CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_PREF_NET_LIST);
+	default:
+		return "UNKNOWN";
+	}
+}
+
+static uint8_t *sme_trace_get_command_string(uint32_t command)
+{
+	switch (command) {
+		CASE_RETURN_STRING(eSmeNoCommand);
+		CASE_RETURN_STRING(eSmeCsrCommandMask);
+		CASE_RETURN_STRING(eSmeCommandRoam);
+		CASE_RETURN_STRING(eSmeCommandWmStatusChange);
+		CASE_RETURN_STRING(e_sme_command_del_sta_session);
+		CASE_RETURN_STRING(eSmeQosCommandMask);
+		CASE_RETURN_STRING(eSmeCommandAddTs);
+		CASE_RETURN_STRING(eSmeCommandDelTs);
+		CASE_RETURN_STRING(e_sme_command_set_hw_mode);
+		CASE_RETURN_STRING(e_sme_command_nss_update);
+		CASE_RETURN_STRING(e_sme_command_set_dual_mac_config);
+		CASE_RETURN_STRING(e_sme_command_set_antenna_mode);
+	default:
+		return "UNKNOWN";
+	}
+}
+
+static void sme_trace_dump(void *mac_ctx, tp_qdf_trace_record record,
+			   uint16_t rec_index)
+{
+	switch (record->code) {
+	case TRACE_CODE_SME_COMMAND:
+		sme_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)",
+			rec_index, record->qtime, record->time, record->session,
+			"SME COMMAND:",
+			sme_trace_get_command_string(record->data),
+			record->data);
+		break;
+	case TRACE_CODE_SME_TX_WMA_MSG:
+		sme_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)",
+			rec_index, record->qtime, record->time, record->session,
+			"TX WMA Msg:",
+			mac_trace_get_wma_msg_string((uint16_t)record->data),
+			record->data);
+		break;
+	case TRACE_CODE_SME_RX_WMA_MSG:
+		sme_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)",
+			rec_index, record->qtime, record->time, record->session,
+			"RX WMA Msg:",
+			mac_trace_get_sme_msg_string((uint16_t)record->data),
+			record->data);
+		break;
+	default:
+		sme_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)",
+			rec_index, record->qtime, record->time, record->session,
+			"RX HDD MSG:",
+			sme_trace_get_rx_msg_string(record->code),
+			record->data);
+		break;
+	}
+}
+
+void sme_trace_init(tpAniSirGlobal pMac)
+{
+	qdf_trace_register(QDF_MODULE_ID_SME, &sme_trace_dump);
+}
+#endif
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
new file mode 100644
index 0000000..d3495b6
--- /dev/null
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -0,0 +1,21896 @@
+/*
+ * Copyright (c) 2012-2018 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: csr_api_roam.c
+ *
+ * Implementation for the Common Roaming interfaces.
+ */
+#include "ani_global.h"          /* for tpAniSirGlobal */
+#include "wma_types.h"
+#include "wma_if.h"          /* for STA_INVALID_IDX. */
+#include "csr_inside_api.h"
+#include "sme_trace.h"
+#include "sme_qos_internal.h"
+#include "sme_inside.h"
+#include "host_diag_core_event.h"
+#include "host_diag_core_log.h"
+#include "csr_api.h"
+#include "csr_internal.h"
+#include "cds_reg_service.h"
+#include "mac_trace.h"
+#include "csr_neighbor_roam.h"
+#include "cds_regdomain.h"
+#include "cds_utils.h"
+#include "sir_types.h"
+#include "cfg_api.h"
+#include "cfg_ucfg_api.h"
+#include "sme_power_save_api.h"
+#include "wma.h"
+#include "wlan_policy_mgr_api.h"
+#include "sme_nan_datapath.h"
+#include "pld_common.h"
+#include "wlan_reg_services_api.h"
+#include "qdf_crypto.h"
+#include <wlan_logging_sock_svc.h>
+#include "wlan_objmgr_psoc_obj.h"
+#include <wlan_scan_ucfg_api.h>
+#include <wlan_tdls_tgt_api.h>
+#include <wlan_cfg80211_scan.h>
+#include <wlan_scan_public_structs.h>
+#include <wlan_action_oui_public_struct.h>
+#include <wlan_action_oui_ucfg_api.h>
+#include "wlan_mlme_api.h"
+#include <wlan_utility.h>
+#include "cfg_mlme.h"
+#include "cfg_ucfg_api.h"
+#include "wlan_mlme_api.h"
+
+#define MAX_PWR_FCC_CHAN_12 8
+#define MAX_PWR_FCC_CHAN_13 2
+
+#define CSR_NUM_IBSS_START_CHAN_50      5
+#define CSR_NUM_IBSS_START_CHANNELS_24      3
+/* 70 seconds, for WPA, WPA2, CCKM */
+#define CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD     \
+	(SIR_INSTALL_KEY_TIMEOUT_SEC * QDF_MC_TIMER_TO_SEC_UNIT)
+/* 120 seconds, for WPS */
+#define CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD (120 * QDF_MC_TIMER_TO_SEC_UNIT)
+
+/* OBIWAN recommends [8 10]% : pick 9% */
+#define CSR_VCC_UL_MAC_LOSS_THRESHOLD 9
+/* OBIWAN recommends -85dBm */
+#define CSR_VCC_RSSI_THRESHOLD 80
+#define CSR_MIN_GLOBAL_STAT_QUERY_PERIOD   500  /* ms */
+#define CSR_MIN_GLOBAL_STAT_QUERY_PERIOD_IN_BMPS 2000   /* ms */
+#define CSR_MIN_TL_STAT_QUERY_PERIOD       500  /* ms */
+/* Flag to send/do not send disassoc frame over the air */
+#define CSR_DONT_SEND_DISASSOC_OVER_THE_AIR 1
+#define RSSI_HACK_BMPS (-40)
+#define MAX_CB_VALUE_IN_INI (2)
+
+#define MAX_SOCIAL_CHANNELS  3
+
+/* packet dump timer duration of 60 secs */
+#define PKT_DUMP_TIMER_DURATION 60
+
+/* Choose the largest possible value that can be accommodated in 8 bit signed */
+/* variable. */
+#define SNR_HACK_BMPS                         (127)
+
+/*
+ * ROAMING_OFFLOAD_TIMER_START - Indicates the action to start the timer
+ * ROAMING_OFFLOAD_TIMER_STOP - Indicates the action to stop the timer
+ * CSR_ROAMING_OFFLOAD_TIMEOUT_PERIOD - Timeout value for roaming offload timer
+ */
+#define ROAMING_OFFLOAD_TIMER_START	1
+#define ROAMING_OFFLOAD_TIMER_STOP	2
+#define CSR_ROAMING_OFFLOAD_TIMEOUT_PERIOD    (5 * QDF_MC_TIMER_TO_SEC_UNIT)
+
+/*
+ * MAWC_ROAM_TRAFFIC_THRESHOLD_DEFAULT - Indicates the traffic thresold in kBps
+ * MAWC_ROAM_AP_RSSI_THRESHOLD_DEFAULT - indicates the AP RSSI threshold
+ * MAWC_ROAM_RSSI_HIGH_ADJUST_DEFAULT - Adjustable high value to suppress scan
+ * MAWC_ROAM_RSSI_LOW_ADJUST_DEFAULT - Adjustable low value to suppress scan
+ */
+#define MAWC_ROAM_TRAFFIC_THRESHOLD_DEFAULT  300
+#define MAWC_ROAM_AP_RSSI_THRESHOLD_DEFAULT  (-66)
+#define MAWC_ROAM_RSSI_HIGH_ADJUST_DEFAULT   5
+#define MAWC_ROAM_RSSI_LOW_ADJUST_DEFAULT    5
+
+/*
+ * Neighbor report offload needs to send 0xFFFFFFFF if a particular
+ * parameter is disabled from the ini
+ */
+#define NEIGHBOR_REPORT_PARAM_INVALID (0xFFFFFFFFU)
+
+/**
+ * csr_get_ielen_from_bss_description() - to get IE length
+ *             from tSirBssDescription structure
+ * @pBssDescr: pBssDescr
+ *
+ * This function is called in various places to get IE length
+ * from tSirBssDescription structure
+ *
+ * @Return: total IE length
+ */
+static inline uint16_t
+csr_get_ielen_from_bss_description(tpSirBssDescription pBssDescr)
+{
+	uint16_t ielen;
+
+	if (!pBssDescr)
+		return 0;
+
+	/*
+	 * Length of BSS desription is without length of
+	 * length itself and length of pointer
+	 * that holds ieFields
+	 *
+	 * <------------sizeof(tSirBssDescription)-------------------->
+	 * +--------+---------------------------------+---------------+
+	 * | length | other fields                    | pointer to IEs|
+	 * +--------+---------------------------------+---------------+
+	 *                                            ^
+	 *                                            ieFields
+	 */
+
+	ielen = (uint16_t)(pBssDescr->length + sizeof(pBssDescr->length) -
+			   GET_FIELD_OFFSET(tSirBssDescription, ieFields));
+
+	return ielen;
+}
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * csr_sae_callback - Update SAE info to CSR roam session
+ * @mac_ctx: MAC context
+ * @msg_ptr: pointer to SAE message
+ *
+ * API to update SAE info to roam csr session
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS csr_sae_callback(tpAniSirGlobal mac_ctx,
+		tSirSmeRsp *msg_ptr)
+{
+	struct csr_roam_info *roam_info;
+	uint32_t session_id;
+	struct sir_sae_info *sae_info;
+
+	sae_info = (struct sir_sae_info *) msg_ptr;
+	if (!sae_info) {
+		sme_err("SAE info is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_debug("vdev_id %d "MAC_ADDRESS_STR"",
+		sae_info->vdev_id,
+		MAC_ADDR_ARRAY(sae_info->peer_mac_addr.bytes));
+
+	session_id = sae_info->vdev_id;
+	if (session_id == CSR_SESSION_ID_INVALID)
+		return QDF_STATUS_E_INVAL;
+
+	roam_info = qdf_mem_malloc(sizeof(*roam_info));
+	if (!roam_info)
+		return QDF_STATUS_E_FAILURE;
+
+	roam_info->sae_info = sae_info;
+
+	csr_roam_call_callback(mac_ctx, session_id, roam_info,
+				   0, eCSR_ROAM_SAE_COMPUTE,
+				   eCSR_ROAM_RESULT_NONE);
+	qdf_mem_free(roam_info);
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS csr_sae_callback(tpAniSirGlobal mac_ctx,
+		tSirSmeRsp *msg_ptr)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+enum mgmt_auth_type diag_auth_type_from_csr_type(eCsrAuthType authtype)
+{
+	int n = AUTH_OPEN;
+
+	switch (authtype) {
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		n = AUTH_SHARED;
+		break;
+	case eCSR_AUTH_TYPE_WPA:
+		n = AUTH_WPA_EAP;
+		break;
+	case eCSR_AUTH_TYPE_WPA_PSK:
+		n = AUTH_WPA_PSK;
+		break;
+	case eCSR_AUTH_TYPE_RSN:
+#ifdef WLAN_FEATURE_11W
+	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
+#endif
+		n = AUTH_WPA2_EAP;
+		break;
+	case eCSR_AUTH_TYPE_RSN_PSK:
+#ifdef WLAN_FEATURE_11W
+	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+#endif
+		n = AUTH_WPA2_PSK;
+		break;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
+		n = AUTH_WAPI_CERT;
+		break;
+	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
+		n = AUTH_WAPI_PSK;
+		break;
+#endif /* FEATURE_WLAN_WAPI */
+	default:
+		break;
+	}
+	return n;
+}
+
+enum mgmt_encrypt_type diag_enc_type_from_csr_type(eCsrEncryptionType enctype)
+{
+	int n = ENC_MODE_OPEN;
+
+	switch (enctype) {
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP40:
+		n = ENC_MODE_WEP40;
+		break;
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP104:
+		n = ENC_MODE_WEP104;
+		break;
+	case eCSR_ENCRYPT_TYPE_TKIP:
+		n = ENC_MODE_TKIP;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES:
+		n = ENC_MODE_AES;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP:
+		n = ENC_MODE_AES_GCMP;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
+		n = ENC_MODE_AES_GCMP_256;
+		break;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_ENCRYPT_TYPE_WPI:
+		n = ENC_MODE_SMS4;
+		break;
+#endif /* FEATURE_WLAN_WAPI */
+	default:
+		break;
+	}
+	return n;
+}
+
+enum mgmt_dot11_mode
+diag_dot11_mode_from_csr_type(enum csr_cfgdot11mode dot11mode)
+{
+	switch (dot11mode) {
+	case eCSR_CFG_DOT11_MODE_ABG:
+		return DOT11_MODE_ABG;
+	case eCSR_CFG_DOT11_MODE_11A:
+		return DOT11_MODE_11A;
+	case eCSR_CFG_DOT11_MODE_11B:
+		return DOT11_MODE_11B;
+	case eCSR_CFG_DOT11_MODE_11G:
+		return DOT11_MODE_11G;
+	case eCSR_CFG_DOT11_MODE_11N:
+		return DOT11_MODE_11N;
+	case eCSR_CFG_DOT11_MODE_11AC:
+		return DOT11_MODE_11AC;
+	case eCSR_CFG_DOT11_MODE_11G_ONLY:
+		return DOT11_MODE_11G_ONLY;
+	case eCSR_CFG_DOT11_MODE_11N_ONLY:
+		return DOT11_MODE_11N_ONLY;
+	case eCSR_CFG_DOT11_MODE_11AC_ONLY:
+		return DOT11_MODE_11AC_ONLY;
+	case eCSR_CFG_DOT11_MODE_AUTO:
+		return DOT11_MODE_AUTO;
+	case eCSR_CFG_DOT11_MODE_11AX:
+		return DOT11_MODE_11AX;
+	case eCSR_CFG_DOT11_MODE_11AX_ONLY:
+		return DOT11_MODE_11AX_ONLY;
+	default:
+		return DOT11_MODE_MAX;
+	}
+}
+
+enum mgmt_ch_width diag_ch_width_from_csr_type(enum phy_ch_width ch_width)
+{
+	switch (ch_width) {
+	case CH_WIDTH_20MHZ:
+		return BW_20MHZ;
+	case CH_WIDTH_40MHZ:
+		return BW_40MHZ;
+	case CH_WIDTH_80MHZ:
+		return BW_80MHZ;
+	case CH_WIDTH_160MHZ:
+		return BW_160MHZ;
+	case CH_WIDTH_80P80MHZ:
+		return BW_80P80MHZ;
+	case CH_WIDTH_5MHZ:
+		return BW_5MHZ;
+	case CH_WIDTH_10MHZ:
+		return BW_10MHZ;
+	default:
+		return BW_MAX;
+	}
+}
+
+enum mgmt_bss_type diag_persona_from_csr_type(enum QDF_OPMODE persona)
+{
+	switch (persona) {
+	case QDF_STA_MODE:
+		return STA_PERSONA;
+	case QDF_SAP_MODE:
+		return SAP_PERSONA;
+	case QDF_P2P_CLIENT_MODE:
+		return P2P_CLIENT_PERSONA;
+	case QDF_P2P_GO_MODE:
+		return P2P_GO_PERSONA;
+	case QDF_FTM_MODE:
+		return FTM_PERSONA;
+	case QDF_IBSS_MODE:
+		return IBSS_PERSONA;
+	case QDF_MONITOR_MODE:
+		return MONITOR_PERSONA;
+	case QDF_P2P_DEVICE_MODE:
+		return P2P_DEVICE_PERSONA;
+	case QDF_OCB_MODE:
+		return OCB_PERSONA;
+	case QDF_EPPING_MODE:
+		return EPPING_PERSONA;
+	case QDF_QVIT_MODE:
+		return QVIT_PERSONA;
+	case QDF_NDI_MODE:
+		return NDI_PERSONA;
+	case QDF_WDS_MODE:
+		return WDS_PERSONA;
+	case QDF_BTAMP_MODE:
+		return BTAMP_PERSONA;
+	case QDF_AHDEMO_MODE:
+		return AHDEMO_PERSONA;
+	default:
+		return MAX_PERSONA;
+	}
+}
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+static const uint8_t
+csr_start_ibss_channels50[CSR_NUM_IBSS_START_CHAN_50] = { 36, 44, 52, 56, 140 };
+static const uint8_t
+csr_start_ibss_channels24[CSR_NUM_IBSS_START_CHANNELS_24] = { 1, 6, 11 };
+
+static const uint8_t
+social_channel[MAX_SOCIAL_CHANNELS] = { 1, 6, 11 };
+
+static void init_config_param(tpAniSirGlobal pMac);
+static bool csr_roam_process_results(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+				     enum csr_roamcomplete_result Result,
+				     void *Context);
+static QDF_STATUS csr_roam_start_ibss(tpAniSirGlobal pMac, uint32_t sessionId,
+				      struct csr_roam_profile *pProfile,
+				      bool *pfSameIbss);
+static void csr_roam_update_connected_profile_from_new_bss(tpAniSirGlobal pMac,
+							   uint32_t sessionId,
+							   tSirSmeNewBssInfo *
+							   pNewBss);
+static ePhyChanBondState csr_get_cb_mode_from_ies(tpAniSirGlobal pMac,
+						  uint8_t primaryChn,
+						  tDot11fBeaconIEs *pIes);
+
+static void csr_roaming_state_config_cnf_processor(tpAniSirGlobal pMac,
+			tSmeCmd *pCommand, uint8_t session_id);
+static QDF_STATUS csr_roam_open(tpAniSirGlobal pMac);
+static QDF_STATUS csr_roam_close(tpAniSirGlobal pMac);
+static bool csr_roam_is_same_profile_keys(tpAniSirGlobal pMac,
+				   tCsrRoamConnectedProfile *pConnProfile,
+				   struct csr_roam_profile *pProfile2);
+
+static QDF_STATUS csr_roam_start_roaming_timer(tpAniSirGlobal pMac,
+					       uint32_t sessionId,
+					       uint32_t interval);
+static QDF_STATUS csr_roam_stop_roaming_timer(tpAniSirGlobal pMac,
+					      uint32_t sessionId);
+static void csr_roam_roaming_timer_handler(void *pv);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static void csr_roam_roaming_offload_timer_action(tpAniSirGlobal mac_ctx,
+		uint32_t interval, uint8_t session_id, uint8_t action);
+#endif
+static void csr_roam_roaming_offload_timeout_handler(void *timer_data);
+static QDF_STATUS csr_roam_start_wait_for_key_timer(tpAniSirGlobal pMac,
+						uint32_t interval);
+static void csr_roam_wait_for_key_time_out_handler(void *pv);
+static QDF_STATUS csr_init11d_info(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo);
+static QDF_STATUS csr_init_channel_power_list(tpAniSirGlobal pMac,
+					      tCsr11dinfo *ps11dinfo);
+static QDF_STATUS csr_roam_free_connected_info(tpAniSirGlobal pMac,
+					       struct csr_roam_connectedinfo *
+					       pConnectedInfo);
+static QDF_STATUS csr_send_mb_set_context_req_msg(tpAniSirGlobal pMac,
+						uint32_t sessionId,
+					   struct qdf_mac_addr peer_macaddr,
+					    uint8_t numKeys,
+					   tAniEdType edType, bool fUnicast,
+					   tAniKeyDirection aniKeyDirection,
+					   uint8_t keyId, uint8_t keyLength,
+					   uint8_t *pKey, uint8_t paeRole,
+					   uint8_t *pKeyRsc);
+static void csr_roam_link_up(tpAniSirGlobal pMac, struct qdf_mac_addr bssid);
+static void csr_roam_link_down(tpAniSirGlobal pMac, uint32_t sessionId);
+#ifndef QCA_SUPPORT_CP_STATS
+static QDF_STATUS csr_send_mb_stats_req_msg(tpAniSirGlobal pMac,
+					uint32_t statsMask, uint8_t staId,
+					uint8_t sessionId);
+/* pStaEntry is no longer invalid upon the return of this function. */
+static void csr_roam_remove_stat_list_entry(tpAniSirGlobal pMac,
+							tListElem *pEntry);
+struct csr_statsclient_reqinfo *csr_roam_insert_entry_into_list(
+			tpAniSirGlobal pMac, tDblLinkList *pStaList,
+				struct csr_statsclient_reqinfo *
+				pStaEntry);
+static void csr_roam_report_statistics(tpAniSirGlobal pMac,
+	uint32_t statsMask, tCsrStatsCallback callback, uint8_t staId,
+	void *pContext);
+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, struct csr_pestats_reqinfo *pPeStaEntry);
+tListElem *csr_roam_find_in_pe_stats_req_list(
+	tpAniSirGlobal pMac,
+						uint32_t statsMask);
+static QDF_STATUS csr_roam_dereg_statistics_req(tpAniSirGlobal pMac);
+#else
+static QDF_STATUS csr_roam_dereg_statistics_req(tpAniSirGlobal pMac)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+static enum csr_cfgdot11mode
+csr_roam_get_phy_mode_band_for_bss(tpAniSirGlobal pMac,
+				   struct csr_roam_profile *pProfile,
+				   uint8_t operationChn,
+				   enum band_info *pBand);
+static QDF_STATUS csr_roam_get_qos_info_from_bss(
+tpAniSirGlobal pMac, tSirBssDescription *pBssDesc);
+static uint32_t csr_find_ibss_session(tpAniSirGlobal pMac);
+static uint32_t csr_find_session_by_type(tpAniSirGlobal,
+					enum QDF_OPMODE);
+static bool csr_is_conn_allow_2g_band(tpAniSirGlobal pMac,
+						uint32_t chnl);
+static bool csr_is_conn_allow_5g_band(tpAniSirGlobal pMac,
+						uint32_t chnl);
+static QDF_STATUS csr_roam_start_wds(tpAniSirGlobal pMac,
+						uint32_t sessionId,
+				     struct csr_roam_profile *pProfile,
+				     tSirBssDescription *pBssDesc);
+static void csr_init_session(tpAniSirGlobal pMac, uint32_t sessionId);
+static QDF_STATUS csr_roam_issue_set_key_command(tpAniSirGlobal pMac,
+						 uint32_t sessionId,
+						 tCsrRoamSetKey *pSetKey,
+						 uint32_t roamId);
+static QDF_STATUS csr_roam_get_qos_info_from_bss(tpAniSirGlobal pMac,
+						 tSirBssDescription *pBssDesc);
+static void csr_ser_des_unpack_diassoc_rsp(uint8_t *pBuf,
+					   tSirSmeDisassocRsp *pRsp);
+static void csr_init_operating_classes(struct mac_context *mac);
+
+static void csr_add_len_of_social_channels(tpAniSirGlobal mac,
+		uint8_t *num_chan);
+static void csr_add_social_channels(tpAniSirGlobal mac,
+		tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan,
+		uint8_t *num_chan);
+
+#ifdef WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY
+static struct csr_roam_session *csr_roam_roam_session;
+
+/* Allocate and initialize global variables */
+static QDF_STATUS csr_roam_init_globals(tpAniSirGlobal pMac)
+{
+	uint32_t buf_size;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	buf_size = CSR_ROAM_SESSION_MAX
+		   * sizeof(struct csr_roam_session);
+
+	csr_roam_roam_session = qdf_mem_malloc(buf_size);
+	if (csr_roam_roam_session) {
+		pMac->roam.roamSession = csr_roam_roam_session;
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		status = QDF_STATUS_E_NOMEM;
+	}
+
+	return status;
+}
+
+/* Free memory allocated dynamically */
+static inline void csr_roam_free_globals(void)
+{
+	qdf_mem_free(csr_roam_roam_session);
+	csr_roam_roam_session = NULL;
+}
+
+#else /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
+static struct csr_roam_session csr_roam_roam_session[CSR_ROAM_SESSION_MAX];
+
+/* Initialize global variables */
+static QDF_STATUS csr_roam_init_globals(tpAniSirGlobal pMac)
+{
+	qdf_mem_zero(&csr_roam_roam_session,
+		     sizeof(csr_roam_roam_session));
+	pMac->roam.roamSession = csr_roam_roam_session;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void csr_roam_free_globals(void)
+{
+}
+#endif /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
+
+static void csr_roam_de_init_globals(tpAniSirGlobal pMac)
+{
+	uint8_t i;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (pMac->roam.roamSession[i].pCurRoamProfile)
+			csr_release_profile(pMac,
+					    pMac->roam.roamSession[i].
+					    pCurRoamProfile);
+		csr_release_profile(pMac,
+				    &pMac->roam.roamSession[i].
+				    stored_roam_profile.profile);
+	}
+	csr_roam_free_globals();
+	pMac->roam.roamSession = NULL;
+}
+
+#ifdef QCA_SUPPORT_CP_STATS
+static QDF_STATUS csr_open_stats_ll(struct mac_context *mac_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static void csr_close_stats_ll(struct mac_context *mac_ctx) {}
+#else
+static QDF_STATUS csr_open_stats_ll(struct mac_context *mac_ctx)
+{
+	QDF_STATUS status;
+
+	status = csr_ll_open(&mac_ctx->roam.statsClientReqList);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	return csr_ll_open(&mac_ctx->roam.peStatsReqList);
+}
+
+static void csr_close_stats_ll(struct mac_context *mac_ctx)
+{
+	csr_ll_close(&mac_ctx->roam.statsClientReqList);
+	csr_ll_close(&mac_ctx->roam.peStatsReqList);
+}
+#endif
+
+QDF_STATUS csr_open(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t i;
+
+	do {
+		/* Initialize CSR Roam Globals */
+		status = csr_roam_init_globals(pMac);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+
+		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
+			csr_roam_state_change(pMac, eCSR_ROAMING_STATE_STOP, i);
+
+		init_config_param(pMac);
+		status = csr_scan_open(pMac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			csr_roam_free_globals();
+			break;
+		}
+		status = csr_roam_open(pMac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			csr_roam_free_globals();
+			break;
+		}
+		pMac->roam.nextRoamId = 1;      /* Must not be 0 */
+		status = csr_open_stats_ll(pMac);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			csr_roam_free_globals();
+			break;
+		}
+		qdf_list_create(&pMac->roam.rssi_disallow_bssid,
+			MAX_RSSI_AVOID_BSSID_LIST);
+	} while (0);
+
+	return status;
+}
+
+QDF_STATUS csr_init_chan_list(tpAniSirGlobal mac, uint8_t *alpha2)
+{
+	QDF_STATUS status;
+
+	mac->scan.countryCodeDefault[0] = alpha2[0];
+	mac->scan.countryCodeDefault[1] = alpha2[1];
+	mac->scan.countryCodeDefault[2] = alpha2[2];
+
+	sme_debug("init time country code %.2s", mac->scan.countryCodeDefault);
+
+	mac->scan.domainIdDefault = 0;
+	mac->scan.domainIdCurrent = 0;
+
+	qdf_mem_copy(mac->scan.countryCodeCurrent,
+		     mac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN);
+	qdf_mem_copy(mac->scan.countryCodeElected,
+		     mac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN);
+	status = csr_get_channel_and_power_list(mac);
+	csr_clear_votes_for_country_info(mac);
+	return status;
+}
+
+QDF_STATUS csr_set_channels(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t index = 0;
+
+	qdf_mem_copy(pParam->Csr11dinfo.countryCode,
+		     pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
+	for (index = 0; index < pMac->scan.base_channels.numChannels;
+	     index++) {
+		pParam->Csr11dinfo.Channels.channelList[index] =
+			pMac->scan.base_channels.channelList[index];
+		pParam->Csr11dinfo.ChnPower[index].firstChannel =
+			pMac->scan.base_channels.channelList[index];
+		pParam->Csr11dinfo.ChnPower[index].numChannels = 1;
+		pParam->Csr11dinfo.ChnPower[index].maxtxPower =
+			pMac->scan.defaultPowerTable[index].tx_power;
+	}
+	pParam->Csr11dinfo.Channels.numChannels =
+		pMac->scan.base_channels.numChannels;
+
+	return status;
+}
+
+/**
+ * csr_assoc_rej_free_rssi_disallow_list() - Free the rssi diallowed
+ * BSSID entries and destroy the list
+ * @list: rssi based disallowed list entry
+ *
+ * Return: void
+ */
+static void csr_assoc_rej_free_rssi_disallow_list(qdf_list_t *list)
+{
+	QDF_STATUS status;
+	struct sir_rssi_disallow_lst *cur_node;
+	qdf_list_node_t *cur_lst = NULL, *next_lst = NULL;
+
+	qdf_list_peek_front(list, &cur_lst);
+	while (cur_lst) {
+		qdf_list_peek_next(list, cur_lst, &next_lst);
+		cur_node = qdf_container_of(cur_lst,
+			struct sir_rssi_disallow_lst, node);
+		status = qdf_list_remove_node(list, cur_lst);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			qdf_mem_free(cur_node);
+		cur_lst = next_lst;
+		next_lst = NULL;
+	}
+	qdf_list_destroy(list);
+}
+
+QDF_STATUS csr_close(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	csr_roam_close(pMac);
+	csr_assoc_rej_free_rssi_disallow_list(
+		&pMac->roam.rssi_disallow_bssid);
+	csr_scan_close(pMac);
+	csr_close_stats_ll(pMac);
+	/* DeInit Globals */
+	csr_roam_de_init_globals(pMac);
+	return status;
+}
+
+static int8_t csr_find_channel_pwr(struct channel_power *
+					     pdefaultPowerTable,
+					     uint8_t ChannelNum)
+{
+	uint8_t i;
+	/* TODO: if defaultPowerTable is guaranteed to be in ascending */
+	/* order of channel numbers, we can employ binary search */
+	for (i = 0; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) {
+		if (pdefaultPowerTable[i].chan_num == ChannelNum)
+			return pdefaultPowerTable[i].tx_power;
+	}
+	/* could not find the channel list in default list */
+	/* this should not have occurred */
+	QDF_ASSERT(0);
+	return 0;
+}
+
+/**
+ * csr_roam_arrange_ch_list() - Updates the channel list modified with greedy
+ * order for 5 Ghz preference and DFS channels.
+ * @mac_ctx: pointer to mac context.
+ * @chan_list:    channel list updated with greedy channel order.
+ * @num_channel:  Number of channels in list
+ *
+ * To allow Early Stop Roaming Scan feature to co-exist with 5G preference,
+ * this function moves 5G channels ahead of 2G channels. This function can
+ * also move 2G channels, ahead of DFS channel or vice versa. Order is
+ * maintained among same category channels
+ *
+ * Return: None
+ */
+static void csr_roam_arrange_ch_list(tpAniSirGlobal mac_ctx,
+			tSirUpdateChanParam *chan_list, uint8_t num_channel)
+{
+	bool prefer_5g = CSR_IS_ROAM_PREFER_5GHZ(mac_ctx);
+	bool prefer_dfs = CSR_IS_DFS_CH_ROAM_ALLOWED(mac_ctx);
+	int i, j = 0;
+	tSirUpdateChanParam *tmp_list = NULL;
+
+	if (!prefer_5g)
+		return;
+
+	tmp_list = qdf_mem_malloc(sizeof(tSirUpdateChanParam) * num_channel);
+	if (!tmp_list)
+		return;
+
+	/* Fist copy Non-DFS 5g channels */
+	for (i = 0; i < num_channel; i++) {
+		if (WLAN_REG_IS_5GHZ_CH(chan_list[i].chanId) &&
+			!wlan_reg_is_dfs_ch(mac_ctx->pdev,
+				chan_list[i].chanId)) {
+			qdf_mem_copy(&tmp_list[j++],
+				&chan_list[i], sizeof(tSirUpdateChanParam));
+			chan_list[i].chanId = INVALID_CHANNEL_ID;
+		}
+	}
+	if (prefer_dfs) {
+		/* next copy DFS channels (remaining channels in 5G) */
+		for (i = 0; i < num_channel; i++) {
+			if (WLAN_REG_IS_5GHZ_CH(chan_list[i].chanId)) {
+				qdf_mem_copy(&tmp_list[j++], &chan_list[i],
+					sizeof(tSirUpdateChanParam));
+				chan_list[i].chanId = INVALID_CHANNEL_ID;
+			}
+		}
+	} else {
+		/* next copy 2G channels */
+		for (i = 0; i < num_channel; i++) {
+			if (WLAN_REG_IS_24GHZ_CH(chan_list[i].chanId)) {
+				qdf_mem_copy(&tmp_list[j++], &chan_list[i],
+					sizeof(tSirUpdateChanParam));
+				chan_list[i].chanId = INVALID_CHANNEL_ID;
+			}
+		}
+	}
+	/* copy rest of the channels in same order to tmp list */
+	for (i = 0; i < num_channel; i++) {
+		if (chan_list[i].chanId != INVALID_CHANNEL_ID) {
+			qdf_mem_copy(&tmp_list[j++], &chan_list[i],
+				sizeof(tSirUpdateChanParam));
+			chan_list[i].chanId = INVALID_CHANNEL_ID;
+		}
+	}
+	/* copy tmp list to original channel list buffer */
+	qdf_mem_copy(chan_list, tmp_list,
+				 sizeof(tSirUpdateChanParam) * num_channel);
+	qdf_mem_free(tmp_list);
+}
+
+/**
+ * csr_roam_sort_channel_for_early_stop() - Sort the channels
+ * @mac_ctx:        mac global context
+ * @chan_list:      Original channel list from the upper layers
+ * @num_channel:    Number of original channels
+ *
+ * For Early stop scan feature, the channel list should be in an order,
+ * where-in there is a maximum chance to detect an AP in the initial
+ * channels in the list so that the scanning can be stopped early as the
+ * feature demands.
+ * Below fixed greedy channel list has been provided
+ * based on most of the enterprise wifi installations across the globe.
+ *
+ * Identify all the greedy channels within the channel list from user space.
+ * Identify all the non-greedy channels in the user space channel list.
+ * Merge greedy channels followed by non-greedy channels back into the
+ * chan_list.
+ *
+ * Return: None
+ */
+static void csr_roam_sort_channel_for_early_stop(tpAniSirGlobal mac_ctx,
+			tSirUpdateChanList *chan_list, uint8_t num_channel)
+{
+	tSirUpdateChanList *chan_list_greedy, *chan_list_non_greedy;
+	uint8_t i, j;
+	static const uint8_t fixed_greedy_chan_list[] = {1, 6, 11, 36, 48, 40,
+		44, 10, 2, 9, 149, 157, 161, 3, 4, 8, 153, 165, 7, 5, 136, 140,
+		52, 116, 56, 104, 64, 60, 100, 120, 13, 14, 112, 132, 151, 155};
+	uint8_t num_fixed_greedy_chan;
+	uint8_t num_greedy_chan = 0;
+	uint8_t num_non_greedy_chan = 0;
+	uint8_t match_found = false;
+	uint32_t buf_size;
+
+	buf_size = sizeof(tSirUpdateChanList) +
+		(sizeof(tSirUpdateChanParam) * num_channel);
+	chan_list_greedy = qdf_mem_malloc(buf_size);
+	chan_list_non_greedy = qdf_mem_malloc(buf_size);
+	if (!chan_list_greedy || !chan_list_non_greedy)
+		goto scan_list_sort_error;
+	/*
+	 * fixed_greedy_chan_list is an evaluated channel list based on most of
+	 * the enterprise wifi deployments and the order of the channels
+	 * determines the highest possibility of finding an AP.
+	 * chan_list is the channel list provided by upper layers based on the
+	 * regulatory domain.
+	 */
+	num_fixed_greedy_chan = sizeof(fixed_greedy_chan_list)/sizeof(uint8_t);
+	/*
+	 * Browse through the chan_list and put all the non-greedy channels
+	 * into a separate list by name chan_list_non_greedy
+	 */
+	for (i = 0; i < num_channel; i++) {
+		for (j = 0; j < num_fixed_greedy_chan; j++) {
+			if (chan_list->chanParam[i].chanId ==
+					fixed_greedy_chan_list[j]) {
+				match_found = true;
+				break;
+			}
+		}
+		if (!match_found) {
+			qdf_mem_copy(
+			  &chan_list_non_greedy->chanParam[num_non_greedy_chan],
+			  &chan_list->chanParam[i],
+			  sizeof(tSirUpdateChanParam));
+			num_non_greedy_chan++;
+		} else {
+			match_found = false;
+		}
+	}
+	/*
+	 * Browse through the fixed_greedy_chan_list and put all the greedy
+	 * channels in the chan_list into a separate list by name
+	 * chan_list_greedy
+	 */
+	for (i = 0; i < num_fixed_greedy_chan; i++) {
+		for (j = 0; j < num_channel; j++) {
+			if (fixed_greedy_chan_list[i] ==
+					chan_list->chanParam[j].chanId) {
+				qdf_mem_copy(
+				  &chan_list_greedy->chanParam[num_greedy_chan],
+				  &chan_list->chanParam[j],
+				  sizeof(tSirUpdateChanParam));
+				num_greedy_chan++;
+				break;
+			}
+		}
+	}
+	QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
+		"greedy=%d, non-greedy=%d, tot=%d",
+		num_greedy_chan, num_non_greedy_chan, num_channel);
+	if ((num_greedy_chan + num_non_greedy_chan) != num_channel) {
+		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+			"incorrect sorting of channels");
+		goto scan_list_sort_error;
+	}
+	/* Copy the Greedy channels first */
+	i = 0;
+	qdf_mem_copy(&chan_list->chanParam[i],
+		&chan_list_greedy->chanParam[i],
+		num_greedy_chan * sizeof(tSirUpdateChanParam));
+	/* Copy the remaining Non Greedy channels */
+	i = num_greedy_chan;
+	j = 0;
+	qdf_mem_copy(&chan_list->chanParam[i],
+		&chan_list_non_greedy->chanParam[j],
+		num_non_greedy_chan * sizeof(tSirUpdateChanParam));
+
+	/* Update channel list for 5g preference and allow DFS roam */
+	csr_roam_arrange_ch_list(mac_ctx, chan_list->chanParam, num_channel);
+scan_list_sort_error:
+	qdf_mem_free(chan_list_greedy);
+	qdf_mem_free(chan_list_non_greedy);
+}
+
+/**
+ * csr_emu_chan_req() - update the required channel list for emulation
+ * @channel: channel number to check
+ *
+ * To reduce scan time during emulation platforms, this function
+ * restricts the scanning to be done on selected channels
+ *
+ * Return: QDF_STATUS enumeration
+ */
+#ifdef QCA_WIFI_NAPIER_EMULATION
+#define SCAN_CHAN_LIST_5G_LEN 6
+#define SCAN_CHAN_LIST_2G_LEN 3
+static const uint8_t
+csr_scan_chan_list_5g[SCAN_CHAN_LIST_5G_LEN] = { 36, 44, 52, 56, 140, 149 };
+static const uint8_t
+csr_scan_chan_list_2g[SCAN_CHAN_LIST_2G_LEN] = { 1, 6, 11 };
+static QDF_STATUS csr_emu_chan_req(uint32_t channel)
+{
+	int i;
+
+	if (WLAN_REG_IS_24GHZ_CH(channel)) {
+		for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_2g); i++) {
+			if (csr_scan_chan_list_2g[i] == channel)
+				return QDF_STATUS_SUCCESS;
+		}
+	} else if (WLAN_REG_IS_5GHZ_CH(channel)) {
+		for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_5g); i++) {
+			if (csr_scan_chan_list_5g[i] == channel)
+				return QDF_STATUS_SUCCESS;
+		}
+	}
+	return QDF_STATUS_E_FAILURE;
+}
+#else
+static QDF_STATUS csr_emu_chan_req(uint32_t channel_num)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
+static void csr_add_len_of_social_channels(tpAniSirGlobal mac,
+		uint8_t *num_chan)
+{
+	uint8_t i;
+	uint8_t no_chan = *num_chan;
+
+	sme_debug("add len of social channels, before adding - num_chan:%hu",
+			*num_chan);
+	if (CSR_IS_5G_BAND_ONLY(mac)) {
+		for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) {
+			if (wlan_reg_get_channel_state(
+				mac->pdev, social_channel[i]) ==
+					CHANNEL_STATE_ENABLE)
+				no_chan++;
+		}
+	}
+	*num_chan = no_chan;
+	sme_debug("after adding - num_chan:%hu", *num_chan);
+}
+
+static void csr_add_social_channels(tpAniSirGlobal mac,
+		tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan,
+		uint8_t *num_chan)
+{
+	uint8_t i;
+	uint8_t no_chan = *num_chan;
+
+	sme_debug("add social channels chan_list %pK, num_chan %hu", chan_list,
+			*num_chan);
+	if (CSR_IS_5G_BAND_ONLY(mac)) {
+		for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) {
+			if (wlan_reg_get_channel_state(mac->pdev,
+				social_channel[i]) != CHANNEL_STATE_ENABLE)
+				continue;
+			chan_list->chanParam[no_chan].chanId =
+				social_channel[i];
+			chan_list->chanParam[no_chan].pwr =
+				csr_find_channel_pwr(pScan->defaultPowerTable,
+						social_channel[i]);
+			chan_list->chanParam[no_chan].dfsSet = false;
+			if (cds_is_5_mhz_enabled())
+				chan_list->chanParam[no_chan].quarter_rate
+					= 1;
+			else if (cds_is_10_mhz_enabled())
+				chan_list->chanParam[no_chan].half_rate = 1;
+			no_chan++;
+		}
+		sme_debug("after adding -num_chan %hu", no_chan);
+	}
+	*num_chan = no_chan;
+}
+#else
+static void csr_add_len_of_social_channels(tpAniSirGlobal mac,
+		uint8_t *num_chan)
+{
+	sme_debug("skip adding len of social channels");
+}
+static void csr_add_social_channels(tpAniSirGlobal mac,
+		tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan,
+		uint8_t *num_chan)
+{
+	sme_debug("skip social channels");
+}
+#endif
+
+QDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac)
+{
+	tSirUpdateChanList *pChanList;
+	struct csr_scanstruct *pScan = &pMac->scan;
+	uint8_t numChan = pScan->base_channels.numChannels;
+	uint8_t num_channel = 0;
+	uint32_t bufLen;
+	struct scheduler_msg msg = {0};
+	uint8_t i;
+	uint8_t channel_state;
+	uint16_t unsafe_chan[NUM_CHANNELS];
+	uint16_t unsafe_chan_cnt = 0;
+	uint16_t cnt = 0;
+	uint8_t  channel;
+	bool is_unsafe_chan;
+	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	if (!qdf_ctx) {
+		sme_err("qdf_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
+		    &unsafe_chan_cnt,
+		    sizeof(unsafe_chan));
+
+	csr_add_len_of_social_channels(pMac, &numChan);
+
+	bufLen = sizeof(tSirUpdateChanList) +
+		 (sizeof(tSirUpdateChanParam) * (numChan));
+
+	csr_init_operating_classes(pMac);
+	pChanList = qdf_mem_malloc(bufLen);
+	if (!pChanList)
+		return QDF_STATUS_E_NOMEM;
+
+	for (i = 0; i < pScan->base_channels.numChannels; i++) {
+		struct csr_sta_roam_policy_params *roam_policy =
+			&pMac->roam.configParam.sta_roam_policy;
+		if (QDF_STATUS_SUCCESS !=
+			csr_emu_chan_req(pScan->base_channels.channelList[i]))
+			continue;
+
+		/* Scan is not performed on DSRC channels*/
+		if (wlan_reg_is_dsrc_chan(pMac->pdev,
+					  pScan->base_channels.channelList[i]))
+			continue;
+
+		channel = pScan->base_channels.channelList[i];
+
+		channel_state = wlan_reg_get_channel_state(pMac->pdev,
+				pScan->base_channels.channelList[i]);
+		if ((CHANNEL_STATE_ENABLE == channel_state) ||
+		    pMac->scan.fEnableDFSChnlScan) {
+			if ((pMac->roam.configParam.sta_roam_policy.dfs_mode ==
+				CSR_STA_ROAM_POLICY_DFS_DISABLED) &&
+				(channel_state == CHANNEL_STATE_DFS)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_DEBUG,
+					FL("skip dfs channel %d"),
+					channel);
+				continue;
+			}
+			if (pMac->roam.configParam.sta_roam_policy.
+					skip_unsafe_channels &&
+					unsafe_chan_cnt) {
+				is_unsafe_chan = false;
+				for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
+					if (unsafe_chan[cnt] == channel) {
+						is_unsafe_chan = true;
+						break;
+					}
+				}
+				if ((is_unsafe_chan) &&
+				    ((WLAN_REG_IS_24GHZ_CH(channel) &&
+				      roam_policy->sap_operating_band ==
+					BAND_2G) ||
+					(WLAN_REG_IS_5GHZ_CH(channel) &&
+					 roam_policy->sap_operating_band ==
+					BAND_5G))) {
+					QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_DEBUG,
+					FL("ignoring unsafe channel %d"),
+					channel);
+					continue;
+				}
+			}
+			pChanList->chanParam[num_channel].chanId =
+				pScan->base_channels.channelList[i];
+			pChanList->chanParam[num_channel].pwr =
+				csr_find_channel_pwr(pScan->defaultPowerTable,
+				  pChanList->chanParam[num_channel].chanId);
+
+			if (pScan->fcc_constraint) {
+				if (12 == pChanList->chanParam[num_channel].
+								chanId) {
+					pChanList->chanParam[num_channel].pwr =
+						MAX_PWR_FCC_CHAN_12;
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_DEBUG,
+						  "txpow for channel 12 is %d",
+						  MAX_PWR_FCC_CHAN_12);
+				}
+				if (13 == pChanList->chanParam[num_channel].
+								chanId) {
+					pChanList->chanParam[num_channel].pwr =
+						MAX_PWR_FCC_CHAN_13;
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_DEBUG,
+						  "txpow for channel 13 is %d",
+						  MAX_PWR_FCC_CHAN_13);
+				}
+			}
+
+
+			if (CHANNEL_STATE_ENABLE == channel_state)
+				pChanList->chanParam[num_channel].dfsSet =
+					false;
+			else
+				pChanList->chanParam[num_channel].dfsSet =
+					true;
+			if (cds_is_5_mhz_enabled())
+				pChanList->chanParam[num_channel].quarter_rate
+					= 1;
+			else if (cds_is_10_mhz_enabled())
+				pChanList->chanParam[num_channel].half_rate = 1;
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"channel:%d, pwr=%d, DFS=%d qrate %d hrate %d ",
+				pChanList->chanParam[num_channel].chanId,
+				pChanList->chanParam[num_channel].pwr,
+				pChanList->chanParam[num_channel].dfsSet,
+				pChanList->chanParam[num_channel].quarter_rate,
+				pChanList->chanParam[num_channel].half_rate);
+			num_channel++;
+		}
+	}
+
+	csr_add_social_channels(pMac, pChanList, pScan, &num_channel);
+
+	if (pMac->mlme_cfg->lfr.early_stop_scan_enable)
+		csr_roam_sort_channel_for_early_stop(pMac, pChanList,
+						     num_channel);
+	else
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("Early Stop Scan Feature not supported"));
+
+	if ((pMac->roam.configParam.uCfgDot11Mode ==
+				eCSR_CFG_DOT11_MODE_AUTO) ||
+			(pMac->roam.configParam.uCfgDot11Mode ==
+			 eCSR_CFG_DOT11_MODE_11AC) ||
+			(pMac->roam.configParam.uCfgDot11Mode ==
+			 eCSR_CFG_DOT11_MODE_11AC_ONLY)) {
+		pChanList->vht_en = true;
+		if (pMac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band)
+			pChanList->vht_24_en = true;
+	}
+	if ((pMac->roam.configParam.uCfgDot11Mode ==
+				eCSR_CFG_DOT11_MODE_AUTO) ||
+			(pMac->roam.configParam.uCfgDot11Mode ==
+			 eCSR_CFG_DOT11_MODE_11N) ||
+			(pMac->roam.configParam.uCfgDot11Mode ==
+			 eCSR_CFG_DOT11_MODE_11N_ONLY)) {
+		pChanList->ht_en = true;
+	}
+	msg.type = WMA_UPDATE_CHAN_LIST_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = pChanList;
+	pChanList->numChan = num_channel;
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			 NO_SESSION, msg.type));
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_WMA,
+							 QDF_MODULE_ID_WMA,
+							 &msg)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
+			  "%s: Failed to post msg to WMA", __func__);
+		qdf_mem_free(pChanList);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef QCA_SUPPORT_CP_STATS
+static void csr_init_tl_stats(struct mac_context *mac_ctx) {}
+#else
+static void csr_init_tl_stats(struct mac_context *mac_ctx)
+{
+	mac_ctx->roam.tlStatsReqInfo.numClient = 0;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+QDF_STATUS csr_start(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t i;
+
+	do {
+		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
+			csr_roam_state_change(pMac, eCSR_ROAMING_STATE_IDLE, i);
+
+		status = csr_roam_start(pMac);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+
+		pMac->roam.sPendingCommands = 0;
+		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
+			status = csr_neighbor_roam_init(pMac, i);
+		csr_init_tl_stats(pMac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_warn("Couldn't Init HO control blk");
+			break;
+		}
+		/* Register with scan component */
+		pMac->scan.requester_id = ucfg_scan_register_requester(
+						pMac->psoc,
+						"CSR", csr_scan_callback, pMac);
+		ucfg_scan_set_enable(pMac->psoc, true);
+	} while (0);
+	return status;
+}
+
+QDF_STATUS csr_stop(tpAniSirGlobal pMac)
+{
+	uint32_t sessionId;
+
+	ucfg_scan_set_enable(pMac->psoc, false);
+	ucfg_scan_unregister_requester(pMac->psoc, pMac->scan.requester_id);
+
+	/*
+	 * purge all serialization commnad if there are any pending to make
+	 * sure memory and vdev ref are freed.
+	 */
+	csr_purge_pdev_all_ser_cmd_list(pMac);
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
+		csr_roam_close_session(pMac, sessionId, true);
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
+		csr_neighbor_roam_close(pMac, sessionId);
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			csr_scan_flush_result(pMac);
+
+	/* Reset the domain back to the deault */
+	pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault;
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_STOP, sessionId);
+		csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+					 sessionId);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS csr_ready(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	/* If the gScanAgingTime is set to '0' then scan results aging timeout
+	 * based  on timer feature is not enabled
+	 */
+	status = csr_apply_channel_and_power_list(pMac);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		sme_err("csr_apply_channel_and_power_list failed status: %d",
+			status);
+
+	return status;
+}
+
+void csr_set_default_dot11_mode(tpAniSirGlobal pMac)
+{
+	uint32_t wniDot11mode = 0;
+
+	wniDot11mode = csr_translate_to_wni_cfg_dot11_mode(pMac,
+					pMac->roam.configParam.uCfgDot11Mode);
+	cfg_set_int(pMac, WNI_CFG_DOT11_MODE, wniDot11mode);
+}
+
+void csr_set_global_cfgs(tpAniSirGlobal pMac)
+{
+	wlan_mlme_set_frag_threshold(pMac->psoc, csr_get_frag_thresh(pMac));
+	wlan_mlme_set_rts_threshold(pMac->psoc, csr_get_rts_thresh(pMac));
+	cfg_set_int(pMac, WNI_CFG_11D_ENABLED,
+			((pMac->roam.configParam.Is11hSupportEnabled) ?
+			pMac->roam.configParam.Is11dSupportEnabled :
+			pMac->roam.configParam.Is11dSupportEnabled));
+	cfg_set_int(pMac, WNI_CFG_11H_ENABLED,
+			pMac->roam.configParam.Is11hSupportEnabled);
+	/* For now we will just use the 5GHz CB mode ini parameter to decide
+	 * whether CB supported or not in Probes when there is no session
+	 * Once session is established we will use the session related params
+	 * stored in PE session for CB mode
+	 */
+	if (cfg_in_range(CFG_CHANNEL_BONDING_MODE,
+			 pMac->roam.configParam.channelBondingMode5GHz))
+		pMac->mlme_cfg->feature_flags.channel_bonding_mode =
+				pMac->roam.configParam.channelBondingMode5GHz;
+
+	if (cfg_in_range(CFG_HEART_BEAT_THRESHOLD,
+			 pMac->roam.configParam.HeartbeatThresh24))
+		pMac->mlme_cfg->timeouts.heart_beat_threshold =
+			pMac->roam.configParam.HeartbeatThresh24;
+	else
+		pMac->mlme_cfg->timeouts.heart_beat_threshold =
+			cfg_default(CFG_HEART_BEAT_THRESHOLD);
+
+	/* Update the operating mode to configured value during
+	 *  initialization, So that client can advertise full
+	 *  capabilities in Probe request frame.
+	 */
+	csr_set_default_dot11_mode(pMac);
+}
+
+/**
+ * csr_packetdump_timer_handler() - packet dump timer
+ * handler
+ * @pv: user data
+ *
+ * This function is used to handle packet dump timer
+ *
+ * Return: None
+ *
+ */
+static void csr_packetdump_timer_handler(void *pv)
+{
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"%s Invoking packetdump deregistration API", __func__);
+	wlan_deregister_txrx_packetdump();
+}
+
+/**
+ * csr_packetdump_timer_stop() - stops packet dump timer
+ *
+ * This function is used to stop packet dump timer
+ *
+ * Return: None
+ *
+ */
+void csr_packetdump_timer_stop(void)
+{
+	QDF_STATUS status;
+	tHalHandle hal;
+	tpAniSirGlobal mac;
+
+	hal = cds_get_context(QDF_MODULE_ID_SME);
+	if (hal == NULL) {
+		QDF_ASSERT(0);
+		return;
+	}
+
+	mac = PMAC_STRUCT(hal);
+	status = qdf_mc_timer_stop(&mac->roam.packetdump_timer);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		sme_err("cannot stop packetdump timer");
+}
+
+static QDF_STATUS csr_roam_open(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t i;
+	struct csr_roam_session *pSession;
+
+	do {
+		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+			pSession = CSR_GET_SESSION(pMac, i);
+			pSession->roamingTimerInfo.pMac = pMac;
+			pSession->roamingTimerInfo.sessionId =
+				CSR_SESSION_ID_INVALID;
+		}
+		pMac->roam.WaitForKeyTimerInfo.pMac = pMac;
+		pMac->roam.WaitForKeyTimerInfo.sessionId =
+			CSR_SESSION_ID_INVALID;
+		status = qdf_mc_timer_init(&pMac->roam.hTimerWaitForKey,
+					  QDF_TIMER_TYPE_SW,
+					 csr_roam_wait_for_key_time_out_handler,
+					  &pMac->roam.WaitForKeyTimerInfo);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("cannot allocate memory for WaitForKey time out timer");
+			break;
+		}
+		status = qdf_mc_timer_init(&pMac->roam.packetdump_timer,
+				QDF_TIMER_TYPE_SW, csr_packetdump_timer_handler,
+				pMac);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("cannot allocate memory for packetdump timer");
+			break;
+		}
+		spin_lock_init(&pMac->roam.roam_state_lock);
+	} while (0);
+	return status;
+}
+
+static QDF_STATUS csr_roam_close(tpAniSirGlobal pMac)
+{
+	uint32_t sessionId;
+
+	/*
+	 * purge all serialization commnad if there are any pending to make
+	 * sure memory and vdev ref are freed.
+	 */
+	csr_purge_pdev_all_ser_cmd_list(pMac);
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
+		csr_roam_close_session(pMac, sessionId, true);
+
+	qdf_mc_timer_stop(&pMac->roam.hTimerWaitForKey);
+	qdf_mc_timer_destroy(&pMac->roam.hTimerWaitForKey);
+	qdf_mc_timer_stop(&pMac->roam.packetdump_timer);
+	qdf_mc_timer_destroy(&pMac->roam.packetdump_timer);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS csr_roam_start(tpAniSirGlobal pMac)
+{
+	(void)pMac;
+	return QDF_STATUS_SUCCESS;
+}
+
+void csr_roam_stop(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	csr_roam_stop_roaming_timer(pMac, sessionId);
+	/* deregister the clients requesting stats from PE/TL & also stop
+	 * the corresponding timers
+	 */
+	csr_roam_dereg_statistics_req(pMac);
+}
+
+QDF_STATUS csr_roam_get_connect_state(tpAniSirGlobal pMac, uint32_t sessionId,
+				      eCsrConnectState *pState)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	if (CSR_IS_SESSION_VALID(pMac, sessionId) && (NULL != pState)) {
+		status = QDF_STATUS_SUCCESS;
+		*pState = pMac->roam.roamSession[sessionId].connectState;
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_copy_connect_profile(tpAniSirGlobal pMac,
+			uint32_t sessionId, tCsrRoamConnectedProfile *pProfile)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t size = 0;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tCsrRoamConnectedProfile *connected_prof;
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (!pProfile) {
+		sme_err("profile not found");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pSession->pConnectBssDesc) {
+		size = pSession->pConnectBssDesc->length +
+			sizeof(pSession->pConnectBssDesc->length);
+		if (size) {
+			pProfile->pBssDesc = qdf_mem_malloc(size);
+			if (NULL != pProfile->pBssDesc) {
+				qdf_mem_copy(pProfile->pBssDesc,
+					pSession->pConnectBssDesc,
+					size);
+				status = QDF_STATUS_SUCCESS;
+			} else {
+				return QDF_STATUS_E_FAILURE;
+			}
+		} else {
+			pProfile->pBssDesc = NULL;
+		}
+		connected_prof = &(pSession->connectedProfile);
+		pProfile->AuthType = connected_prof->AuthType;
+		pProfile->EncryptionType = connected_prof->EncryptionType;
+		pProfile->mcEncryptionType = connected_prof->mcEncryptionType;
+		pProfile->BSSType = connected_prof->BSSType;
+		pProfile->operationChannel = connected_prof->operationChannel;
+		qdf_mem_copy(&pProfile->bssid, &connected_prof->bssid,
+			sizeof(struct qdf_mac_addr));
+		qdf_mem_copy(&pProfile->SSID, &connected_prof->SSID,
+			sizeof(tSirMacSSid));
+		if (connected_prof->MDID.mdiePresent) {
+			pProfile->MDID.mdiePresent = 1;
+			pProfile->MDID.mobilityDomain =
+				connected_prof->MDID.mobilityDomain;
+		} else {
+			pProfile->MDID.mdiePresent = 0;
+			pProfile->MDID.mobilityDomain = 0;
+		}
+#ifdef FEATURE_WLAN_ESE
+		pProfile->isESEAssoc = connected_prof->isESEAssoc;
+		if (csr_is_auth_type_ese(connected_prof->AuthType)) {
+			qdf_mem_copy(pProfile->eseCckmInfo.krk,
+				connected_prof->eseCckmInfo.krk,
+				SIR_KRK_KEY_LEN);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+			qdf_mem_copy(pProfile->eseCckmInfo.btk,
+				connected_prof->eseCckmInfo.btk,
+				SIR_BTK_KEY_LEN);
+#endif
+			pProfile->eseCckmInfo.reassoc_req_num =
+				connected_prof->eseCckmInfo.reassoc_req_num;
+			pProfile->eseCckmInfo.krk_plumbed =
+				connected_prof->eseCckmInfo.krk_plumbed;
+		}
+#endif
+#ifdef WLAN_FEATURE_11W
+		pProfile->MFPEnabled = connected_prof->MFPEnabled;
+		pProfile->MFPRequired = connected_prof->MFPRequired;
+		pProfile->MFPCapable = connected_prof->MFPCapable;
+#endif
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_get_connect_profile(tpAniSirGlobal pMac, uint32_t sessionId,
+					tCsrRoamConnectedProfile *pProfile)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if ((csr_is_conn_state_connected(pMac, sessionId)) ||
+	    (csr_is_conn_state_ibss(pMac, sessionId))) {
+		if (pProfile) {
+			status =
+				csr_roam_copy_connect_profile(pMac, sessionId,
+							      pProfile);
+		}
+	}
+	return status;
+}
+
+void csr_roam_free_connect_profile(tCsrRoamConnectedProfile *profile)
+{
+	if (profile->pBssDesc)
+		qdf_mem_free(profile->pBssDesc);
+	if (profile->pAddIEAssoc)
+		qdf_mem_free(profile->pAddIEAssoc);
+	qdf_mem_set(profile, sizeof(tCsrRoamConnectedProfile), 0);
+	profile->AuthType = eCSR_AUTH_TYPE_UNKNOWN;
+}
+
+static QDF_STATUS csr_roam_free_connected_info(tpAniSirGlobal pMac,
+					       struct csr_roam_connectedinfo *
+					       pConnectedInfo)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (pConnectedInfo->pbFrames) {
+		qdf_mem_free(pConnectedInfo->pbFrames);
+		pConnectedInfo->pbFrames = NULL;
+	}
+	pConnectedInfo->nBeaconLength = 0;
+	pConnectedInfo->nAssocReqLength = 0;
+	pConnectedInfo->nAssocRspLength = 0;
+	pConnectedInfo->staId = 0;
+	pConnectedInfo->nRICRspLength = 0;
+#ifdef FEATURE_WLAN_ESE
+	pConnectedInfo->nTspecIeLength = 0;
+#endif
+	return status;
+}
+
+void csr_release_command_roam(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	csr_reinit_roam_cmd(pMac, pCommand);
+}
+
+void csr_release_command_wm_status_change(tpAniSirGlobal pMac,
+					tSmeCmd *pCommand)
+{
+	csr_reinit_wm_status_change_cmd(pMac, pCommand);
+}
+
+void csr_roam_substate_change(tpAniSirGlobal pMac,
+		enum csr_roam_substate NewSubstate, uint32_t sessionId)
+{
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		sme_err("Invalid no of concurrent sessions %d",
+			  sessionId);
+		return;
+	}
+	sme_debug("CSR RoamSubstate: [ %s <== %s ]",
+		mac_trace_getcsr_roam_sub_state(NewSubstate),
+		mac_trace_getcsr_roam_sub_state(pMac->roam.
+		curSubState[sessionId]));
+	if (pMac->roam.curSubState[sessionId] == NewSubstate)
+		return;
+	spin_lock(&pMac->roam.roam_state_lock);
+	pMac->roam.curSubState[sessionId] = NewSubstate;
+	spin_unlock(&pMac->roam.roam_state_lock);
+}
+
+enum csr_roam_state csr_roam_state_change(tpAniSirGlobal pMac,
+				    enum csr_roam_state NewRoamState,
+				uint8_t sessionId)
+{
+	enum csr_roam_state PreviousState;
+
+	sme_debug("CSR RoamState[%hu]: [ %s <== %s ]", sessionId,
+		mac_trace_getcsr_roam_state(NewRoamState),
+		mac_trace_getcsr_roam_state(pMac->roam.curState[sessionId]));
+	PreviousState = pMac->roam.curState[sessionId];
+
+	if (NewRoamState != pMac->roam.curState[sessionId]) {
+		/* Whenever we transition OUT of the Roaming state,
+		 * clear the Roaming substate.
+		 */
+		if (CSR_IS_ROAM_JOINING(pMac, sessionId)) {
+			csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+						 sessionId);
+		}
+
+		pMac->roam.curState[sessionId] = NewRoamState;
+	}
+	return PreviousState;
+}
+
+void csr_assign_rssi_for_category(tpAniSirGlobal pMac, int8_t bestApRssi,
+				  uint8_t catOffset)
+{
+	int i;
+
+	sme_debug("best AP RSSI: %d cat offset: %d", bestApRssi, catOffset);
+	if (catOffset) {
+		pMac->roam.configParam.bCatRssiOffset = catOffset;
+		for (i = 0; i < CSR_NUM_RSSI_CAT; i++) {
+			pMac->roam.configParam.RSSICat[CSR_NUM_RSSI_CAT - i -
+						       1] =
+				(int)bestApRssi -
+				pMac->mlme_cfg->gen.select_5ghz_margin -
+				(int)(i * catOffset);
+		}
+	}
+}
+
+static void init_config_param(tpAniSirGlobal pMac)
+{
+	int i;
+
+	pMac->roam.configParam.agingCount = CSR_AGING_COUNT;
+	pMac->roam.configParam.channelBondingMode24GHz =
+		WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+	pMac->roam.configParam.channelBondingMode5GHz =
+		WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
+
+	pMac->roam.configParam.phyMode = eCSR_DOT11_MODE_AUTO;
+	pMac->roam.configParam.uCfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
+	pMac->roam.configParam.HeartbeatThresh24 = 40;
+	pMac->roam.configParam.HeartbeatThresh50 = 40;
+	pMac->roam.configParam.Is11dSupportEnabled = false;
+	pMac->roam.configParam.Is11eSupportEnabled = true;
+	pMac->roam.configParam.Is11hSupportEnabled = true;
+	pMac->roam.configParam.shortSlotTime = true;
+	pMac->roam.configParam.WMMSupportMode = eCsrRoamWmmAuto;
+	pMac->roam.configParam.ProprietaryRatesEnabled = true;
+	for (i = 0; i < CSR_NUM_RSSI_CAT; i++)
+		pMac->roam.configParam.BssPreferValue[i] = i;
+	csr_assign_rssi_for_category(pMac, CSR_BEST_RSSI_VALUE,
+			CSR_DEFAULT_RSSI_DB_GAP);
+	pMac->roam.configParam.fSupplicantCountryCodeHasPriority = false;
+	pMac->roam.configParam.nActiveMaxChnTime = CSR_ACTIVE_MAX_CHANNEL_TIME;
+	pMac->roam.configParam.nPassiveMaxChnTime =
+		CSR_PASSIVE_MAX_CHANNEL_TIME;
+	pMac->roam.configParam.nActiveMaxChnTimeConc =
+		CSR_ACTIVE_MAX_CHANNEL_TIME_CONC;
+	pMac->roam.configParam.nActiveMinChnTimeConc =
+		CSR_ACTIVE_MIN_CHANNEL_TIME_CONC;
+	pMac->roam.configParam.nPassiveMaxChnTimeConc =
+		CSR_PASSIVE_MAX_CHANNEL_TIME_CONC;
+	pMac->roam.configParam.nPassiveMinChnTimeConc =
+		CSR_PASSIVE_MIN_CHANNEL_TIME_CONC;
+	pMac->roam.configParam.nRestTimeConc = CSR_REST_TIME_CONC;
+	pMac->roam.configParam.min_rest_time_conc =  CSR_MIN_REST_TIME_CONC;
+	pMac->roam.configParam.idle_time_conc = CSR_IDLE_TIME_CONC;
+	pMac->roam.configParam.nTxPowerCap = CSR_MAX_TX_POWER;
+	pMac->roam.configParam.allow_tpc_from_ap = true;
+	pMac->roam.configParam.statsReqPeriodicity =
+		CSR_MIN_GLOBAL_STAT_QUERY_PERIOD;
+	pMac->roam.configParam.statsReqPeriodicityInPS =
+		CSR_MIN_GLOBAL_STAT_QUERY_PERIOD_IN_BMPS;
+	pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries = 3;
+	pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold =
+		120;
+	pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff =
+		30;
+	pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff = 5;
+	pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime = 20;
+	pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime = 40;
+	pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod =
+		200;
+	pMac->roam.configParam.neighborRoamConfig.
+		neighbor_scan_min_timer_period = 200;
+	pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
+	numChannels = 3;
+	pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
+	channelList[0] = 1;
+	pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
+	channelList[1] = 6;
+	pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
+	channelList[2] = 11;
+	pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod
+						= 20000;        /* 20 seconds */
+	pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod = 0;
+	pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt = 10;
+	pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt = 10;
+	pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight = 14;
+	pMac->roam.configParam.nVhtChannelWidth =
+		WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1;
+
+	pMac->roam.configParam.addTSWhenACMIsOff = 0;
+	pMac->roam.configParam.fScanTwice = false;
+
+	/* Remove this code once SLM_Sessionization is supported */
+	/* BMPS_WORKAROUND_NOT_NEEDED */
+	pMac->roam.configParam.doBMPSWorkaround = 0;
+
+	pMac->roam.configParam.nInitialDwellTime = 0;
+	pMac->roam.configParam.initial_scan_no_dfs_chnl = 0;
+	pMac->roam.configParam.csr_mawc_config.mawc_enabled = true;
+}
+
+enum band_info csr_get_current_band(struct mac_context *mac)
+{
+	return mac->mlme_cfg->gen.band_capability;
+}
+
+/* This function flushes the roam scan cache */
+QDF_STATUS csr_flush_cfg_bg_scan_roam_channel_list(tpAniSirGlobal pMac,
+						   uint8_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	/* Free up the memory first (if required) */
+	if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) {
+		qdf_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.
+			     ChannelList);
+		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
+		pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = 0;
+	}
+	return status;
+}
+
+/*
+ * This function flushes the roam scan cache and creates fresh cache
+ * based on the input channel list
+ */
+QDF_STATUS csr_create_bg_scan_roam_channel_list(tpAniSirGlobal pMac,
+						uint8_t sessionId,
+						const uint8_t *pChannelList,
+						const uint8_t numChannels)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = numChannels;
+
+	pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
+		qdf_mem_malloc(pNeighborRoamInfo->cfgParams.channelInfo.
+			       numOfChannels);
+
+	if (!pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) {
+		pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = 0;
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	/* Update the roam global structure */
+	qdf_mem_copy(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
+		     pChannelList,
+		     pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels);
+	return status;
+}
+
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * csr_create_roam_scan_channel_list() - create roam scan channel list
+ * @pMac: Global mac pointer
+ * @sessionId: session id
+ * @pChannelList: pointer to channel list
+ * @numChannels: number of channels
+ * @eBand: band enumeration
+ *
+ * This function modifies the roam scan channel list as per AP neighbor
+ * report; AP neighbor report may be empty or may include only other AP
+ * channels; in any case, we merge the channel list with the learned occupied
+ * channels list.
+ * if the band is 2.4G, then make sure channel list contains only 2.4G
+ * valid channels if the band is 5G, then make sure channel list contains
+ * only 5G valid channels
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS csr_create_roam_scan_channel_list(tpAniSirGlobal pMac,
+					     uint8_t sessionId,
+					     uint8_t *pChannelList,
+					     uint8_t numChannels,
+					     const enum band_info eBand)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo
+		= &pMac->roam.neighborRoamInfo[sessionId];
+	uint8_t outNumChannels = 0;
+	uint8_t inNumChannels = numChannels;
+	uint8_t *inPtr = pChannelList;
+	uint8_t i = 0;
+	uint8_t ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
+	uint8_t tmpChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
+	uint8_t mergedOutputNumOfChannels = 0;
+
+	tpCsrChannelInfo currChannelListInfo
+		= &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
+	/*
+	 * Create a Union of occupied channel list learnt by the DUT along
+	 * with the Neighbor report Channels. This increases the chances of
+	 * the DUT to get a candidate AP while roaming even if the Neighbor
+	 * Report is not able to provide sufficient information.
+	 */
+	if (pMac->scan.occupiedChannels[sessionId].numChannels) {
+		csr_neighbor_roam_merge_channel_lists(pMac, &pMac->scan.
+						occupiedChannels[sessionId].
+						channelList[0], pMac->scan.
+						occupiedChannels[sessionId].
+						numChannels, inPtr,
+						inNumChannels,
+						&mergedOutputNumOfChannels);
+		inNumChannels = mergedOutputNumOfChannels;
+	}
+	if (BAND_2G == eBand) {
+		for (i = 0; i < inNumChannels; i++) {
+			if (WLAN_REG_IS_24GHZ_CH(inPtr[i])
+			    && csr_roam_is_channel_valid(pMac, inPtr[i])) {
+				ChannelList[outNumChannels++] = inPtr[i];
+			}
+		}
+	} else if (BAND_5G == eBand) {
+		for (i = 0; i < inNumChannels; i++) {
+			/* Add 5G Non-DFS channel */
+			if (WLAN_REG_IS_5GHZ_CH(inPtr[i]) &&
+			    csr_roam_is_channel_valid(pMac, inPtr[i]) &&
+			    !wlan_reg_is_dfs_ch(pMac->pdev, inPtr[i])) {
+				ChannelList[outNumChannels++] = inPtr[i];
+			}
+		}
+	} else if (BAND_ALL == eBand) {
+		for (i = 0; i < inNumChannels; i++) {
+			if (csr_roam_is_channel_valid(pMac, inPtr[i]) &&
+			    !wlan_reg_is_dfs_ch(pMac->pdev, inPtr[i])) {
+				ChannelList[outNumChannels++] = inPtr[i];
+			}
+		}
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN,
+			  "Invalid band, No operation carried out (Band %d)",
+			  eBand);
+		return QDF_STATUS_E_INVAL;
+	}
+	/*
+	 * if roaming within band is enabled, then select only the
+	 * in band channels .
+	 * This is required only if the band capability is set to ALL,
+	 * E.g., if band capability is only 2.4G then all the channels in the
+	 * list are already filtered for 2.4G channels, hence ignore this check
+	 */
+	if ((BAND_ALL == eBand) && CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) {
+		csr_neighbor_roam_channels_filter_by_current_band(pMac,
+								sessionId,
+								ChannelList,
+								outNumChannels,
+								tmpChannelList,
+							&outNumChannels);
+		qdf_mem_copy(ChannelList, tmpChannelList, outNumChannels);
+	}
+	/* Prepare final roam scan channel list */
+	if (outNumChannels) {
+		/* Clear the channel list first */
+		if (NULL != currChannelListInfo->ChannelList) {
+			qdf_mem_free(currChannelListInfo->ChannelList);
+			currChannelListInfo->ChannelList = NULL;
+			currChannelListInfo->numOfChannels = 0;
+		}
+		currChannelListInfo->ChannelList
+			= qdf_mem_malloc(outNumChannels * sizeof(uint8_t));
+		if (!currChannelListInfo->ChannelList) {
+			currChannelListInfo->numOfChannels = 0;
+			return QDF_STATUS_E_NOMEM;
+		}
+		qdf_mem_copy(currChannelListInfo->ChannelList,
+			     ChannelList, outNumChannels);
+	}
+	return status;
+}
+
+/**
+ * csr_roam_is_ese_assoc() - is this ese association
+ * @mac_ctx: Global MAC context
+ * @session_id: session identifier
+ *
+ * Returns whether the current association is a ESE assoc or not.
+ *
+ * Return: true if ese association; false otherwise
+ */
+bool csr_roam_is_ese_assoc(tpAniSirGlobal mac_ctx, uint32_t session_id)
+{
+	return mac_ctx->roam.neighborRoamInfo[session_id].isESEAssoc;
+}
+
+
+/**
+ * csr_roam_is_ese_ini_feature_enabled() - is ese feature enabled
+ * @mac_ctx: Global MAC context
+ *
+ * Return: true if ese feature is enabled; false otherwise
+ */
+bool csr_roam_is_ese_ini_feature_enabled(tpAniSirGlobal pMac)
+{
+	return pMac->roam.configParam.isEseIniFeatureEnabled;
+}
+
+/**
+ * csr_tsm_stats_rsp_processor() - tsm stats response processor
+ * @pMac: Global MAC context
+ * @pMsg: Message pointer
+ *
+ * Return: None
+ */
+static void csr_tsm_stats_rsp_processor(tpAniSirGlobal pMac, void *pMsg)
+{
+	tAniGetTsmStatsRsp *pTsmStatsRsp = (tAniGetTsmStatsRsp *) pMsg;
+
+	if (NULL != pTsmStatsRsp) {
+		/*
+		 * Get roam Rssi request is backed up and passed back
+		 * to the response, Extract the request message
+		 * to fetch callback.
+		 */
+		tpAniGetTsmStatsReq reqBkp
+			= (tAniGetTsmStatsReq *) pTsmStatsRsp->tsmStatsReq;
+
+		if (NULL != reqBkp) {
+			if (NULL != reqBkp->tsmStatsCallback) {
+				((tCsrTsmStatsCallback)
+				 (reqBkp->tsmStatsCallback))(pTsmStatsRsp->
+							     tsmMetrics,
+							     pTsmStatsRsp->
+							     staId,
+							     reqBkp->
+							     pDevContext);
+				reqBkp->tsmStatsCallback = NULL;
+			}
+			qdf_mem_free(reqBkp);
+			pTsmStatsRsp->tsmStatsReq = NULL;
+		} else {
+			if (NULL != reqBkp) {
+				qdf_mem_free(reqBkp);
+				pTsmStatsRsp->tsmStatsReq = NULL;
+			}
+		}
+	} else {
+		sme_err("pTsmStatsRsp is NULL");
+	}
+}
+
+/**
+ * csr_send_ese_adjacent_ap_rep_ind() - ese send adjacent ap report
+ * @pMac: Global MAC context
+ * @pSession: Session pointer
+ *
+ * Return: None
+ */
+static void csr_send_ese_adjacent_ap_rep_ind(tpAniSirGlobal pMac,
+					struct csr_roam_session *pSession)
+{
+	uint32_t roamTS2 = 0;
+	struct csr_roam_info roamInfo;
+	tpPESession pSessionEntry = NULL;
+	uint8_t sessionId = CSR_SESSION_ID_INVALID;
+
+	if (NULL == pSession) {
+		sme_err("pSession is NULL");
+		return;
+	}
+
+	roamTS2 = qdf_mc_timer_get_system_time();
+	roamInfo.tsmRoamDelay = roamTS2 - pSession->roamTS1;
+	sme_debug("Bssid(" MAC_ADDRESS_STR ") Roaming Delay(%u ms)",
+		MAC_ADDR_ARRAY(pSession->connectedProfile.bssid.bytes),
+		roamInfo.tsmRoamDelay);
+
+	pSessionEntry = pe_find_session_by_bssid(pMac,
+					 pSession->connectedProfile.bssid.bytes,
+					 &sessionId);
+	if (NULL == pSessionEntry) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+
+	pSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly
+		= roamInfo.tsmRoamDelay;
+
+	csr_roam_call_callback(pMac, pSession->sessionId, &roamInfo,
+			       0, eCSR_ROAM_ESE_ADJ_AP_REPORT_IND, 0);
+}
+
+/**
+ * csr_get_tsm_stats() - get tsm stats
+ * @pMac: Global MAC context
+ * @callback: TSM stats callback
+ * @staId: Station id
+ * @bssId: bssid
+ * @pContext: pointer to context
+ * @tid: traffic id
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS csr_get_tsm_stats(tpAniSirGlobal pMac,
+			     tCsrTsmStatsCallback callback,
+			     uint8_t staId,
+			     struct qdf_mac_addr bssId,
+			     void *pContext, uint8_t tid)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tAniGetTsmStatsReq *pMsg = NULL;
+
+	pMsg = qdf_mem_malloc(sizeof(tAniGetTsmStatsReq));
+	if (!pMsg) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	/* need to initiate a stats request to PE */
+	pMsg->msgType = eWNI_SME_GET_TSM_STATS_REQ;
+	pMsg->msgLen = (uint16_t) sizeof(tAniGetTsmStatsReq);
+	pMsg->staId = staId;
+	pMsg->tid = tid;
+	qdf_copy_macaddr(&pMsg->bssId, &bssId);
+	pMsg->tsmStatsCallback = callback;
+	pMsg->pDevContext = pContext;
+	status = umac_send_mb_message_to_mac(pMsg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_debug("Failed to send down the TSM req (status=%d)", status);
+		/* pMsg is freed by cds_send_mb_message_to_mac */
+		status = QDF_STATUS_E_FAILURE;
+	}
+	return status;
+}
+
+
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * csr_fetch_ch_lst_from_received_list() - fetch channel list from received list
+ * and update req msg
+ * parameters
+ * @mac_ctx:            global mac ctx
+ * @roam_info:          roam info struct
+ * @curr_ch_lst_info:   current channel list info
+ * @req_buf:            out param, roam offload scan request packet
+ *
+ * Return: void
+ */
+static void
+csr_fetch_ch_lst_from_received_list(tpAniSirGlobal mac_ctx,
+				    tpCsrNeighborRoamControlInfo roam_info,
+				    tpCsrChannelInfo curr_ch_lst_info,
+				    tSirRoamOffloadScanReq *req_buf)
+{
+	uint8_t i = 0;
+	uint8_t num_channels = 0;
+	uint8_t *ch_lst = NULL;
+	uint16_t  unsafe_chan[NUM_CHANNELS];
+	uint16_t  unsafe_chan_cnt = 0;
+	uint16_t  cnt = 0;
+	bool      is_unsafe_chan;
+	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	if (!qdf_ctx) {
+		cds_err("qdf_ctx is NULL");
+		return;
+	}
+	pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
+			&unsafe_chan_cnt,
+			sizeof(unsafe_chan));
+
+	if (curr_ch_lst_info->numOfChannels == 0)
+		return;
+
+	ch_lst = curr_ch_lst_info->ChannelList;
+	for (i = 0; i < curr_ch_lst_info->numOfChannels; i++) {
+		if ((!mac_ctx->roam.configParam.allowDFSChannelRoam ||
+		    (mac_ctx->roam.configParam.sta_roam_policy.dfs_mode ==
+			 CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
+		     (wlan_reg_is_dfs_ch(mac_ctx->pdev, *ch_lst))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				("ignoring dfs channel %d"), *ch_lst);
+			ch_lst++;
+			continue;
+		}
+
+		if (mac_ctx->roam.configParam.sta_roam_policy.
+				skip_unsafe_channels &&
+				unsafe_chan_cnt) {
+			is_unsafe_chan = false;
+			for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
+				if (unsafe_chan[cnt] == *ch_lst) {
+					is_unsafe_chan = true;
+					break;
+				}
+			}
+			if (is_unsafe_chan) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+						QDF_TRACE_LEVEL_DEBUG,
+					("ignoring unsafe channel %d"),
+					*ch_lst);
+				ch_lst++;
+				continue;
+			}
+		}
+		req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
+			*ch_lst;
+		ch_lst++;
+	}
+	req_buf->ConnectedNetwork.ChannelCount = num_channels;
+	req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC;
+}
+#endif
+
+/**
+ * csr_set_cckm_ie() - set CCKM IE
+ * @pMac: Global MAC context
+ * @sessionId: session identifier
+ * @pCckmIe: Pointer to input CCKM IE data
+ * @ccKmIeLen: Length of @pCckmIe
+ *
+ * This function stores the CCKM IE passed by the supplicant
+ * in a place holder data structure and this IE will be packed inside
+ * reassociation request
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS csr_set_cckm_ie(tpAniSirGlobal pMac, const uint8_t sessionId,
+			   const uint8_t *pCckmIe, const uint8_t ccKmIeLen)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_copy(pSession->suppCckmIeInfo.cckmIe, pCckmIe, ccKmIeLen);
+	pSession->suppCckmIeInfo.cckmIeLen = ccKmIeLen;
+	return status;
+}
+
+/**
+ * csr_roam_read_tsf() - read TSF
+ * @pMac: Global MAC context
+ * @sessionId: session identifier
+ * @pTimestamp: output TSF timestamp
+ *
+ * This function reads the TSF; and also add the time elapsed since
+ * last beacon or probe response reception from the hand off AP to arrive at
+ * the latest TSF value.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS csr_roam_read_tsf(tpAniSirGlobal pMac, uint8_t *pTimestamp,
+			     uint8_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tCsrNeighborRoamBSSInfo handoffNode = {{0} };
+	uint64_t timer_diff = 0;
+	uint32_t timeStamp[2];
+	tpSirBssDescription pBssDescription = NULL;
+
+	csr_neighbor_roam_get_handoff_ap_info(pMac, &handoffNode, sessionId);
+	if (!handoffNode.pBssDescription) {
+		sme_err("Invalid BSS Description");
+		return QDF_STATUS_E_INVAL;
+	}
+	pBssDescription = handoffNode.pBssDescription;
+	/* Get the time diff in nano seconds */
+	timer_diff = (qdf_get_monotonic_boottime_ns()  -
+				pBssDescription->scansystimensec);
+	/* Convert msec to micro sec timer */
+	timer_diff = do_div(timer_diff, SYSTEM_TIME_NSEC_TO_USEC);
+	timeStamp[0] = pBssDescription->timeStamp[0];
+	timeStamp[1] = pBssDescription->timeStamp[1];
+	update_cckmtsf(&(timeStamp[0]), &(timeStamp[1]), &timer_diff);
+	qdf_mem_copy(pTimestamp, (void *)&timeStamp[0], sizeof(uint32_t) * 2);
+	return status;
+}
+
+#endif /* FEATURE_WLAN_ESE */
+
+/**
+ * csr_roam_is_roam_offload_scan_enabled() - is roam offload enabled
+ * @mac_ctx: Global MAC context
+ *
+ * Returns whether firmware based background scan is currently enabled or not.
+ *
+ * Return: true if roam offload scan enabled; false otherwise
+ */
+bool csr_roam_is_roam_offload_scan_enabled(tpAniSirGlobal mac_ctx)
+{
+	return mac_ctx->roam.configParam.isRoamOffloadScanEnabled;
+}
+
+/* The funcns csr_convert_cb_ini_value_to_phy_cb_state and
+ * csr_convert_phy_cb_state_to_ini_value have been introduced
+ * to convert the ini value to the ENUM used in csr and MAC for CB state
+ * Ideally we should have kept the ini value and enum value same and
+ * representing the same cb values as in 11n standard i.e.
+ * Set to 1 (SCA) if the secondary channel is above the primary channel
+ * Set to 3 (SCB) if the secondary channel is below the primary channel
+ * Set to 0 (SCN) if no secondary channel is present
+ * However, since our driver is already distributed we will keep the ini
+ * definition as it is which is:
+ * 0 - secondary none
+ * 1 - secondary LOW
+ * 2 - secondary HIGH
+ * and convert to enum value used within the driver in
+ * csr_change_default_config_param using this funcn
+ * The enum values are as follows:
+ * PHY_SINGLE_CHANNEL_CENTERED          = 0
+ * PHY_DOUBLE_CHANNEL_LOW_PRIMARY   = 1
+ * PHY_DOUBLE_CHANNEL_HIGH_PRIMARY  = 3
+ */
+ePhyChanBondState csr_convert_cb_ini_value_to_phy_cb_state(uint32_t cbIniValue)
+{
+
+	ePhyChanBondState phyCbState;
+
+	switch (cbIniValue) {
+	/* secondary none */
+	case eCSR_INI_SINGLE_CHANNEL_CENTERED:
+		phyCbState = PHY_SINGLE_CHANNEL_CENTERED;
+		break;
+	/* secondary LOW */
+	case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY:
+		phyCbState = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+		break;
+	/* secondary HIGH */
+	case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY:
+		phyCbState = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
+		phyCbState =
+			PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
+		break;
+	default:
+		/* If an invalid value is passed, disable CHANNEL BONDING */
+		phyCbState = PHY_SINGLE_CHANNEL_CENTERED;
+		break;
+	}
+	return phyCbState;
+}
+
+static
+uint32_t csr_convert_phy_cb_state_to_ini_value(ePhyChanBondState phyCbState)
+{
+	uint32_t cbIniValue;
+
+	switch (phyCbState) {
+	/* secondary none */
+	case PHY_SINGLE_CHANNEL_CENTERED:
+		cbIniValue = eCSR_INI_SINGLE_CHANNEL_CENTERED;
+		break;
+	/* secondary LOW */
+	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+		cbIniValue = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
+		break;
+	/* secondary HIGH */
+	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+		cbIniValue = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+		cbIniValue =
+			eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
+		cbIniValue =
+		eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+		cbIniValue =
+			eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
+		break;
+	default:
+		/* return some invalid value */
+		cbIniValue = eCSR_INI_CHANNEL_BONDING_STATE_MAX;
+		break;
+	}
+	return cbIniValue;
+}
+
+#ifdef WLAN_FEATURE_11AX
+#define CSR_REVISE_REQ_HE_CAP_PER_BAND(_req, _pmac, _channelid)              \
+	(_req)->he_config.bfee_sts_lt_80 = WLAN_CHAN_IS_2GHZ((_channelid)) ? \
+					(_pmac)->he_cap_2g.bfee_sts_lt_80 :  \
+					(_pmac)->he_cap_5g.bfee_sts_lt_80
+
+/**
+ * csr_update_he_config_param() - Update MAC context with HE config param
+ * @mac_ctx: pointer to MAC context
+ * @param: pointer to CSR config params
+ *
+ * Return: None
+ */
+static void csr_update_he_config_param(tpAniSirGlobal mac_ctx,
+				       tCsrConfigParam *param)
+{
+	mac_ctx->roam.configParam.enable_ul_ofdma = param->enable_ul_ofdma;
+	mac_ctx->roam.configParam.enable_ul_mimo = param->enable_ul_mimo;
+}
+
+/**
+ * csr_get_he_config_param() - Get HE config param from MAC context
+ * @param: pointer to CSR config params
+ * @mac_ctx: pointer to MAC context
+ *
+ * Return: None
+ */
+static void csr_get_he_config_param(tCsrConfigParam *param,
+				    tpAniSirGlobal mac_ctx)
+{
+	param->enable_ul_ofdma = mac_ctx->roam.configParam.enable_ul_ofdma;
+	param->enable_ul_mimo = mac_ctx->roam.configParam.enable_ul_mimo;
+}
+
+
+/**
+ * csr_join_req_copy_he_cap() - Copy HE cap into CSR Join Req
+ * @csr_join_req: pointer to CSR Join Req
+ * @session: pointer to CSR session
+ *
+ * Return: None
+ */
+static void csr_join_req_copy_he_cap(tSirSmeJoinReq *csr_join_req,
+		struct csr_roam_session *session)
+{
+	qdf_mem_copy(&csr_join_req->he_config, &session->he_config,
+		     sizeof(session->he_config));
+}
+
+/**
+ * csr_start_bss_copy_he_cap() - Copy HE cap into CSR Join Req
+ * @req: pointer to START BSS Req
+ * @session: pointer to CSR session
+ *
+ * Return: None
+ */
+static void csr_start_bss_copy_he_cap(tSirSmeStartBssReq *req,
+			struct csr_roam_session *session)
+{
+	qdf_mem_copy(&req->he_config, &session->he_config,
+		     sizeof(session->he_config));
+}
+
+void csr_update_session_he_cap(tpAniSirGlobal mac_ctx,
+			struct csr_roam_session *session)
+{
+	mac_handle_t mac_hdl = MAC_HANDLE(mac_ctx);
+	uint32_t value = 0;
+	tDot11fIEhe_cap *he_cap = &session->he_config;
+	he_cap->present = true;
+
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_CONTROL, &value);
+	he_cap->htc_he = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_TWT_REQUESTOR, &value);
+	he_cap->twt_request = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_TWT_RESPONDER, &value);
+	he_cap->twt_responder = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_FRAGMENTATION, &value);
+	he_cap->fragmentation = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MAX_FRAG_MSDU, &value);
+	he_cap->max_num_frag_msdu_amsdu_exp = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MIN_FRAG_SIZE, &value);
+	he_cap->min_frag_size = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_TRIG_PAD, &value);
+	he_cap->trigger_frm_mac_pad = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MTID_AGGR_RX, &value);
+	he_cap->multi_tid_aggr_rx_supp = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_LINK_ADAPTATION, &value);
+	he_cap->he_link_adaptation = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_ALL_ACK, &value);
+	he_cap->all_ack = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_TRIGD_RSP_SCHEDULING, &value);
+	he_cap->trigd_rsp_sched = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_BUFFER_STATUS_RPT, &value);
+	he_cap->a_bsr = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_BCAST_TWT, &value);
+	he_cap->broadcast_twt = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_BA_32BIT, &value);
+	he_cap->ba_32bit_bitmap = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MU_CASCADING, &value);
+	he_cap->mu_cascade = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MULTI_TID, &value);
+	he_cap->ack_enabled_multitid = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_OMI, &value);
+	he_cap->omi_a_ctrl = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_OFDMA_RA, &value);
+	he_cap->ofdma_ra = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MAX_AMPDU_LEN, &value);
+	he_cap->max_ampdu_len_exp_ext = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_AMSDU_FRAG, &value);
+	he_cap->amsdu_frag = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_FLEX_TWT_SCHED, &value);
+	he_cap->flex_twt_sched = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_RX_CTRL, &value);
+	he_cap->rx_ctrl_frame = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_BSRP_AMPDU_AGGR, &value);
+	he_cap->bsrp_ampdu_aggr = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_QTP, &value);
+	he_cap->qtp = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_A_BQR, &value);
+	he_cap->a_bqr = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_SR_RESPONDER, &value);
+	he_cap->spatial_reuse_param_rspder = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_NDP_FEEDBACK_SUPP, &value);
+	he_cap->ndp_feedback_supp = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_OPS_SUPP, &value);
+	he_cap->ops_supp = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_AMSDU_IN_AMPDU, &value);
+	he_cap->amsdu_in_ampdu = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_SUB_CH_SEL_TX, &value);
+	he_cap->he_sub_ch_sel_tx_supp = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_UL_2X996_RU, &value);
+	he_cap->ul_2x996_tone_ru_supp = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_OM_CTRL_UL_MU_DIS_RX, &value);
+	he_cap->om_ctrl_ul_mu_data_dis_rx = value;
+
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_CHAN_WIDTH, &value);
+	he_cap->chan_width_0 = HE_CH_WIDTH_GET_BIT(value, 0);
+	he_cap->chan_width_1 = HE_CH_WIDTH_GET_BIT(value, 1);
+	he_cap->chan_width_2 = HE_CH_WIDTH_GET_BIT(value, 2);
+	he_cap->chan_width_3 = HE_CH_WIDTH_GET_BIT(value, 3);
+	he_cap->chan_width_4 = HE_CH_WIDTH_GET_BIT(value, 4);
+	he_cap->chan_width_5 = HE_CH_WIDTH_GET_BIT(value, 5);
+	he_cap->chan_width_6 = HE_CH_WIDTH_GET_BIT(value, 6);
+
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_RX_PREAM_PUNC, &value);
+	he_cap->rx_pream_puncturing = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_CLASS_OF_DEVICE, &value);
+	he_cap->device_class = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_LDPC, &value);
+	he_cap->ldpc_coding = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_LTF_PPDU, &value);
+	he_cap->he_1x_ltf_800_gi_ppdu = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS, &value);
+	he_cap->midamble_tx_rx_max_nsts = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_LTF_NDP, &value);
+	he_cap->he_4x_ltf_3200_gi_ndp = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_TX_STBC_LT80, &value);
+	he_cap->tx_stbc_lt_80mhz = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_RX_STBC_LT80, &value);
+	he_cap->rx_stbc_lt_80mhz = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_DOPPLER, &value);
+	he_cap->doppler = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_UL_MUMIMO, &value);
+	he_cap->ul_mu = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_DCM_TX, &value);
+	he_cap->dcm_enc_tx = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_DCM_RX, &value);
+	he_cap->dcm_enc_rx = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MU_PPDU, &value);
+	he_cap->ul_he_mu = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_SU_BEAMFORMEE, &value);
+	he_cap->su_beamformee = value;
+	if (he_cap->su_beamformee) {
+		sme_cfg_get_int(mac_hdl, WNI_CFG_HE_BFEE_STS_LT80, &value);
+		he_cap->bfee_sts_lt_80 = value;
+		sme_cfg_get_int(mac_hdl, WNI_CFG_HE_BFEE_STS_GT80, &value);
+		he_cap->bfee_sts_gt_80 = value;
+	} else {
+		he_cap->bfee_sts_lt_80 = 0;
+		he_cap->bfee_sts_gt_80 = 0;
+	}
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_SU_BEAMFORMER, &value);
+	he_cap->su_beamformer = value;
+	if (he_cap->su_beamformer) {
+		sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MU_BEAMFORMER, &value);
+		he_cap->mu_beamformer = value;
+		sme_cfg_get_int(mac_hdl, WNI_CFG_HE_NUM_SOUND_LT80, &value);
+		he_cap->num_sounding_lt_80 = value;
+		sme_cfg_get_int(mac_hdl, WNI_CFG_HE_NUM_SOUND_GT80, &value);
+		he_cap->num_sounding_gt_80 = value;
+	} else {
+		he_cap->mu_beamformer = 0;
+		he_cap->num_sounding_lt_80 = 0;
+		he_cap->num_sounding_gt_80 = 0;
+	}
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_SU_FEED_TONE16, &value);
+	he_cap->su_feedback_tone16 = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MU_FEED_TONE16, &value);
+	he_cap->mu_feedback_tone16 = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_CODEBOOK_SU, &value);
+	he_cap->codebook_su = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_CODEBOOK_MU, &value);
+	he_cap->codebook_mu = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_BFRM_FEED, &value);
+	he_cap->beamforming_feedback = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_ER_SU_PPDU, &value);
+	he_cap->he_er_su_ppdu = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_DL_PART_BW, &value);
+	he_cap->dl_mu_mimo_part_bw = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_PPET_PRESENT, &value);
+	he_cap->ppet_present = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_SRP, &value);
+	he_cap->srp = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_POWER_BOOST, &value);
+	he_cap->power_boost = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_4x_LTF_GI, &value);
+	he_cap->he_ltf_800_gi_4x = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MAX_NC, &value);
+	he_cap->max_nc = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_TX_STBC_GT80, &value);
+	he_cap->tx_stbc_gt_80mhz = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_RX_STBC_GT80, &value);
+	he_cap->rx_stbc_gt_80mhz = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_ER_4x_LTF_GI, &value);
+	he_cap->er_he_ltf_800_gi_4x = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_PPDU_20_IN_40MHZ_2G, &value);
+	he_cap->he_ppdu_20_in_40Mhz_2G = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ, &value);
+	he_cap->he_ppdu_20_in_160_80p80Mhz = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ, &value);
+	he_cap->he_ppdu_80_in_160_80p80Mhz = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_ER_1X_HE_LTF_GI, &value);
+	he_cap->er_1x_he_ltf_gi = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_MIDAMBLE_TXRX_1X_HE_LTF, &value);
+	he_cap->midamble_tx_rx_1x_he_ltf = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_DCM_MAX_BW, &value);
+	he_cap->dcm_max_bw = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_LONGER_16_SIGB_OFDM_SYM, &value);
+	he_cap->longer_than_16_he_sigb_ofdm_sym = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_TX_1024_QAM_LT_242_RU, &value);
+	he_cap->tx_1024_qam_lt_242_tone_ru = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_RX_1024_QAM_LT_242_RU, &value);
+	he_cap->rx_1024_qam_lt_242_tone_ru = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_NON_TRIG_CQI_FEEDBACK, &value);
+	he_cap->non_trig_cqi_feedback = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_RX_FULL_BW_MU_CMPR_SIGB, &value);
+	he_cap->rx_full_bw_su_he_mu_compress_sigb = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB,
+			&value);
+	he_cap->rx_full_bw_su_he_mu_non_cmpr_sigb = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_RX_MCS_MAP_LT_80, &value);
+	he_cap->rx_he_mcs_map_lt_80 = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_TX_MCS_MAP_LT_80, &value);
+	he_cap->tx_he_mcs_map_lt_80 = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_RX_MCS_MAP_160, &value);
+	*((uint16_t *)he_cap->rx_he_mcs_map_160) = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_TX_MCS_MAP_160, &value);
+	*((uint16_t *)he_cap->tx_he_mcs_map_160) = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_RX_MCS_MAP_80_80, &value);
+	*((uint16_t *)he_cap->rx_he_mcs_map_80_80) = value;
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_TX_MCS_MAP_80_80, &value);
+	*((uint16_t *)he_cap->tx_he_mcs_map_80_80) = value;
+
+	if (he_cap->ppet_present) {
+		value = WNI_CFG_HE_PPET_LEN;
+		/* till now operating channel is not decided yet, use 5g cap */
+		sme_cfg_get_str(mac_hdl, WNI_CFG_HE_PPET_5G,
+				he_cap->ppet.ppe_threshold.ppe_th, &value);
+		he_cap->ppet.ppe_threshold.num_ppe_th =
+			lim_truncate_ppet(he_cap->ppet.ppe_threshold.ppe_th,
+					  value);
+	} else {
+		he_cap->ppet.ppe_threshold.num_ppe_th = 0;
+	}
+	sme_cfg_get_int(mac_hdl, WNI_CFG_HE_STA_OBSSPD, &value);
+	session->he_sta_obsspd = value;
+}
+
+#else
+#define CSR_REVISE_REQ_HE_CAP_PER_BAND(_req, _pmac, _channelid)   /* no op */
+
+static inline void csr_update_he_config_param(tpAniSirGlobal mac_ctx,
+					      tCsrConfigParam *param)
+{
+}
+
+static inline void csr_get_he_config_param(tCsrConfigParam *param,
+					   tpAniSirGlobal mac_ctx)
+{
+}
+
+static inline void csr_join_req_copy_he_cap(tSirSmeJoinReq *csr_join_req,
+			struct csr_roam_session *session)
+{
+}
+
+static inline void csr_start_bss_copy_he_cap(tSirSmeStartBssReq *req,
+			struct csr_roam_session *session)
+{
+}
+
+#endif
+
+/**
+ * csr_set_11k_offload_config_param() - Update 11k neighbor report config
+ *
+ * @csr_config: pointer to csr_config in MAC context
+ * @pParam: pointer to config params from HDD
+ *
+ * Return: none
+ */
+static
+void csr_set_11k_offload_config_param(struct csr_config *csr_config,
+					tCsrConfigParam *param)
+{
+	csr_config->offload_11k_enable_bitmask =
+		param->offload_11k_enable_bitmask;
+	csr_config->neighbor_report_offload.params_bitmask =
+		param->neighbor_report_offload.params_bitmask;
+	csr_config->neighbor_report_offload.time_offset =
+		param->neighbor_report_offload.time_offset;
+	csr_config->neighbor_report_offload.low_rssi_offset =
+		param->neighbor_report_offload.low_rssi_offset;
+	csr_config->neighbor_report_offload.bmiss_count_trigger =
+		param->neighbor_report_offload.bmiss_count_trigger;
+	csr_config->neighbor_report_offload.per_threshold_offset =
+		param->neighbor_report_offload.per_threshold_offset;
+	csr_config->neighbor_report_offload.
+		neighbor_report_cache_timeout =
+		param->neighbor_report_offload.
+		neighbor_report_cache_timeout;
+	csr_config->neighbor_report_offload.
+		max_neighbor_report_req_cap =
+		param->neighbor_report_offload.
+		max_neighbor_report_req_cap;
+}
+
+static void
+csr_copy_mawc_config(tpAniSirGlobal pMac,
+		     struct mawc_params *mawc_config)
+{
+	mawc_config->mawc_enabled =
+		pMac->roam.configParam.csr_mawc_config.mawc_enabled;
+	mawc_config->mawc_roam_enabled =
+		pMac->mlme_cfg->lfr.mawc_roam_enabled;
+	mawc_config->mawc_roam_traffic_threshold =
+		pMac->mlme_cfg->lfr.mawc_roam_traffic_threshold;
+	mawc_config->mawc_roam_ap_rssi_threshold =
+		pMac->mlme_cfg->lfr.mawc_roam_ap_rssi_threshold;
+	mawc_config->mawc_roam_rssi_high_adjust =
+		pMac->mlme_cfg->lfr.mawc_roam_rssi_high_adjust;
+	mawc_config->mawc_roam_rssi_low_adjust =
+		pMac->mlme_cfg->lfr.mawc_roam_rssi_low_adjust;
+}
+
+QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
+					   tCsrConfigParam *pParam)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	int i;
+
+	if (pParam) {
+		pMac->roam.configParam.is_force_1x1 =
+			pParam->is_force_1x1;
+		pMac->roam.configParam.WMMSupportMode = pParam->WMMSupportMode;
+		pMac->mlme_cfg->wmm_params.wme_enabled =
+			(pParam->WMMSupportMode == eCsrRoamWmmNoQos) ? 0 : 1;
+		pMac->roam.configParam.Is11eSupportEnabled =
+			pParam->Is11eSupportEnabled;
+		pMac->roam.configParam.Is11dSupportEnabled =
+			pParam->Is11dSupportEnabled;
+
+		if (pMac->mlme_cfg->gen.band_capability == BAND_2G)
+			pMac->roam.configParam.Is11hSupportEnabled = 0;
+		else
+			pMac->roam.configParam.Is11hSupportEnabled =
+				pParam->Is11hSupportEnabled;
+
+		pMac->roam.configParam.fenableMCCMode = pParam->fEnableMCCMode;
+		pMac->roam.configParam.mcc_rts_cts_prot_enable =
+						pParam->mcc_rts_cts_prot_enable;
+		pMac->roam.configParam.mcc_bcast_prob_resp_enable =
+					pParam->mcc_bcast_prob_resp_enable;
+		pMac->roam.configParam.fAllowMCCGODiffBI =
+			pParam->fAllowMCCGODiffBI;
+
+		/* channelBondingMode5GHz plays a dual role right now
+		 * INFRA STA will use this non zero value as CB enabled
+		 * and SOFTAP will use this non-zero value to determine
+		 * the secondary channel offset. This is how
+		 * channelBondingMode5GHz works now and this is kept intact
+		 * to avoid any cfg.ini change.
+		 */
+		if (pParam->channelBondingMode24GHz > MAX_CB_VALUE_IN_INI)
+			sme_warn("Invalid CB value from ini in 2.4GHz band %d, CB DISABLED",
+				pParam->channelBondingMode24GHz);
+		pMac->roam.configParam.channelBondingMode24GHz =
+			csr_convert_cb_ini_value_to_phy_cb_state(pParam->
+						channelBondingMode24GHz);
+		if (pParam->channelBondingMode5GHz > MAX_CB_VALUE_IN_INI)
+			sme_warn("Invalid CB value from ini in 5GHz band %d, CB DISABLED",
+				pParam->channelBondingMode5GHz);
+		pMac->roam.configParam.channelBondingMode5GHz =
+			csr_convert_cb_ini_value_to_phy_cb_state(pParam->
+							channelBondingMode5GHz);
+		pMac->roam.configParam.phyMode = pParam->phyMode;
+		pMac->roam.configParam.shortSlotTime = pParam->shortSlotTime;
+		pMac->roam.configParam.HeartbeatThresh24 =
+			pMac->mlme_cfg->timeouts.heart_beat_threshold;
+		pMac->roam.configParam.HeartbeatThresh50 =
+			pParam->HeartbeatThresh50;
+		pMac->roam.configParam.ProprietaryRatesEnabled =
+			pParam->ProprietaryRatesEnabled;
+		pMac->roam.configParam.AdHocChannel24 = pParam->AdHocChannel24;
+		pMac->roam.configParam.AdHocChannel5G = pParam->AdHocChannel5G;
+		pMac->roam.configParam.wep_tkip_in_he = pParam->wep_tkip_in_he;
+		pMac->roam.configParam.neighborRoamConfig.
+			delay_before_vdev_stop =
+			pParam->neighborRoamConfig.delay_before_vdev_stop;
+
+		/* if HDD passed down non zero values then only update, */
+		/* otherwise keep using the defaults */
+		if (pParam->initial_scan_no_dfs_chnl) {
+			pMac->roam.configParam.initial_scan_no_dfs_chnl =
+				pParam->initial_scan_no_dfs_chnl;
+		}
+		if (pParam->nInitialDwellTime) {
+			pMac->roam.configParam.nInitialDwellTime =
+				pParam->nInitialDwellTime;
+		}
+		if (pParam->nActiveMaxChnTime) {
+			pMac->roam.configParam.nActiveMaxChnTime =
+				pParam->nActiveMaxChnTime;
+			cfg_set_int(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
+				    pParam->nActiveMaxChnTime);
+		}
+		if (pParam->nPassiveMaxChnTime) {
+			pMac->roam.configParam.nPassiveMaxChnTime =
+				pParam->nPassiveMaxChnTime;
+			cfg_set_int(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
+				    pParam->nPassiveMaxChnTime);
+		}
+		if (pParam->nActiveMaxChnTimeConc) {
+			pMac->roam.configParam.nActiveMaxChnTimeConc =
+				pParam->nActiveMaxChnTimeConc;
+		}
+		if (pParam->nActiveMinChnTimeConc) {
+			pMac->roam.configParam.nActiveMinChnTimeConc =
+				pParam->nActiveMinChnTimeConc;
+		}
+		if (pParam->nPassiveMaxChnTimeConc) {
+			pMac->roam.configParam.nPassiveMaxChnTimeConc =
+				pParam->nPassiveMaxChnTimeConc;
+		}
+		if (pParam->nPassiveMinChnTimeConc) {
+			pMac->roam.configParam.nPassiveMinChnTimeConc =
+				pParam->nPassiveMinChnTimeConc;
+		}
+		pMac->roam.configParam.nRestTimeConc = pParam->nRestTimeConc;
+		pMac->roam.configParam.min_rest_time_conc =
+			pParam->min_rest_time_conc;
+		pMac->roam.configParam.idle_time_conc = pParam->idle_time_conc;
+
+		pMac->roam.configParam.uCfgDot11Mode =
+			csr_get_cfg_dot11_mode_from_csr_phy_mode(NULL,
+							pMac->roam.configParam.
+							phyMode,
+							pMac->roam.configParam.
+						ProprietaryRatesEnabled);
+		/* if HDD passed down non zero values for age params,
+		 * then only update, otherwise keep using the defaults
+		 */
+		if (pParam->nScanResultAgeCount) {
+			pMac->roam.configParam.agingCount =
+				pParam->nScanResultAgeCount;
+		}
+
+		csr_assign_rssi_for_category(pMac,
+			pMac->mlme_cfg->lfr.first_scan_bucket_threshold,
+			pParam->bCatRssiOffset);
+		pMac->roam.configParam.fSupplicantCountryCodeHasPriority =
+			pParam->fSupplicantCountryCodeHasPriority;
+		pMac->roam.configParam.vccRssiThreshold =
+			pParam->vccRssiThreshold;
+		pMac->roam.configParam.vccUlMacLossThreshold =
+			pParam->vccUlMacLossThreshold;
+		pMac->roam.configParam.statsReqPeriodicity =
+			pParam->statsReqPeriodicity;
+		pMac->roam.configParam.statsReqPeriodicityInPS =
+			pParam->statsReqPeriodicityInPS;
+		/* Assign this before calling csr_init11d_info */
+		pMac->roam.configParam.nTxPowerCap = pParam->nTxPowerCap;
+		pMac->roam.configParam.allow_tpc_from_ap =
+				pParam->allow_tpc_from_ap;
+		if (wlan_reg_11d_enabled_on_host(pMac->psoc))
+			status = csr_init11d_info(pMac, &pParam->Csr11dinfo);
+		else
+			pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
+
+		/* Initialize the power + channel information if 11h is
+		 * enabled. If 11d is enabled this information has already
+		 * been initialized
+		 */
+		if (csr_is11h_supported(pMac) &&
+				!wlan_reg_11d_enabled_on_host(pMac->psoc))
+			csr_init_channel_power_list(pMac, &pParam->Csr11dinfo);
+
+		pMac->roam.configParam.isFastTransitionEnabled =
+			pParam->isFastTransitionEnabled;
+		pMac->roam.configParam.RoamRssiDiff = pParam->RoamRssiDiff;
+		pMac->roam.configParam.nRoamPrefer5GHz =
+			pParam->nRoamPrefer5GHz;
+		pMac->roam.configParam.nRoamIntraBand = pParam->nRoamIntraBand;
+		pMac->roam.configParam.isWESModeEnabled =
+			pParam->isWESModeEnabled;
+		pMac->roam.configParam.nProbes = pParam->nProbes;
+		pMac->roam.configParam.nRoamScanHomeAwayTime =
+			pParam->nRoamScanHomeAwayTime;
+		pMac->roam.configParam.isRoamOffloadScanEnabled =
+			pParam->isRoamOffloadScanEnabled;
+		pMac->roam.configParam.bFastRoamInConIniFeatureEnabled =
+			pParam->bFastRoamInConIniFeatureEnabled;
+		pMac->roam.configParam.isFastRoamIniFeatureEnabled =
+			pParam->isFastRoamIniFeatureEnabled;
+		pMac->roam.configParam.csr_mawc_config.mawc_enabled =
+			pParam->csr_mawc_config.mawc_enabled;
+#ifdef FEATURE_WLAN_ESE
+		pMac->roam.configParam.isEseIniFeatureEnabled =
+			pParam->isEseIniFeatureEnabled;
+#endif
+		qdf_mem_copy(&pMac->roam.configParam.neighborRoamConfig,
+			     &pParam->neighborRoamConfig,
+			     sizeof(tCsrNeighborRoamConfigParams));
+		sme_debug("nNeighborScanTimerPerioid: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nNeighborScanTimerPeriod);
+		sme_debug("neighbor_scan_min_timer_period: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			neighbor_scan_min_timer_period);
+		sme_debug("nNeighborLookupRssiThreshold: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nNeighborLookupRssiThreshold);
+		sme_debug("nOpportunisticThresholdDiff: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nOpportunisticThresholdDiff);
+		sme_debug("nRoamRescanRssiDiff: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamRescanRssiDiff);
+		sme_debug("nNeighborScanMinChanTime: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nNeighborScanMinChanTime);
+		sme_debug("nNeighborScanMaxChanTime: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nNeighborScanMaxChanTime);
+		sme_debug("nNeighborResultsRefreshPeriod: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nNeighborResultsRefreshPeriod);
+		sme_debug("nEmptyScanRefreshPeriod: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nEmptyScanRefreshPeriod);
+		{
+			int i;
+
+			sme_debug("Num of Channels in CFG Channel List: %d",
+				pMac->roam.configParam.neighborRoamConfig.
+				neighborScanChanList.numChannels);
+			for (i = 0;
+			     i <
+			     pMac->roam.configParam.neighborRoamConfig.
+			     neighborScanChanList.numChannels; i++) {
+				sme_debug("%d ",
+					pMac->roam.configParam.
+					neighborRoamConfig.neighborScanChanList.
+					channelList[i]);
+			}
+		}
+		sme_debug("nRoamBmissFirstBcnt: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamBmissFirstBcnt);
+		sme_debug("nRoamBmissFinalBcnt: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamBmissFinalBcnt);
+		sme_debug("nRoamBeaconRssiWeight: %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamBeaconRssiWeight);
+		pMac->roam.configParam.addTSWhenACMIsOff =
+			pParam->addTSWhenACMIsOff;
+		pMac->scan.fEnableBypass11d = pParam->fEnableBypass11d;
+		pMac->scan.fEnableDFSChnlScan = pParam->fEnableDFSChnlScan;
+		pMac->scan.scanResultCfgAgingTime = pParam->scanCfgAgingTime;
+		pMac->roam.configParam.fScanTwice = pParam->fScanTwice;
+		pMac->scan.fFirstScanOnly2GChnl = pParam->fFirstScanOnly2GChnl;
+		pMac->scan.max_scan_count = pParam->max_scan_count;
+		/* This parameter is not available in cfg and not passed from
+		 * upper layers. Instead it is initialized here This parametere
+		 * is used in concurrency to determine if there are concurrent
+		 * active sessions. Is used as a temporary fix to disconnect
+		 * all active sessions when BMPS enabled so the active session
+		 * if Infra STA will automatically connect back and resume BMPS
+		 * since resume BMPS is not working when moving from concurrent
+		 * to single session
+		 */
+		/* Remove this code once SLM_Sessionization is supported */
+		/* BMPS_WORKAROUND_NOT_NEEDED */
+		pMac->roam.configParam.doBMPSWorkaround = 0;
+		pMac->roam.configParam.send_smps_action =
+			pParam->send_smps_action;
+		pMac->roam.configParam.tx_ldpc_enable = pParam->enable_tx_ldpc;
+		pMac->roam.configParam.rx_ldpc_enable = pParam->enable_rx_ldpc;
+		pMac->roam.configParam.disable_high_ht_mcs_2x2 =
+					pParam->disable_high_ht_mcs_2x2;
+		pMac->roam.configParam.ho_delay_for_rx =
+			pParam->ho_delay_for_rx;
+		pMac->roam.configParam.min_delay_btw_roam_scans =
+			pParam->min_delay_btw_roam_scans;
+		pMac->roam.configParam.roam_trigger_reason_bitmask =
+			pParam->roam_trigger_reason_bitmask;
+		pMac->roam.configParam.isCoalesingInIBSSAllowed =
+			pParam->isCoalesingInIBSSAllowed;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+		pMac->roam.configParam.cc_switch_mode = pParam->cc_switch_mode;
+#endif
+		pMac->roam.configParam.allowDFSChannelRoam =
+			pParam->allowDFSChannelRoam;
+		pMac->roam.configParam.obssEnabled = pParam->obssEnabled;
+		pMac->roam.configParam.vendor_vht_sap =
+			pParam->vendor_vht_sap;
+		pMac->roam.configParam.conc_custom_rule1 =
+			pParam->conc_custom_rule1;
+		pMac->roam.configParam.conc_custom_rule2 =
+			pParam->conc_custom_rule2;
+		pMac->roam.configParam.is_sta_connection_in_5gz_enabled =
+			pParam->is_sta_connection_in_5gz_enabled;
+
+		pMac->isCoalesingInIBSSAllowed =
+			pParam->isCoalesingInIBSSAllowed;
+
+		pMac->roam.configParam.enable_ftopen =
+			pParam->enable_ftopen;
+		pMac->roam.configParam.scan_adaptive_dwell_mode =
+			pParam->scan_adaptive_dwell_mode;
+		pMac->roam.configParam.scan_adaptive_dwell_mode_nc =
+			pParam->scan_adaptive_dwell_mode_nc;
+
+		/* update interface configuration */
+		pMac->sme.max_intf_count = pParam->max_intf_count;
+
+		pMac->f_sta_miracast_mcc_rest_time_val =
+			pParam->f_sta_miracast_mcc_rest_time_val;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+		pMac->sap.sap_channel_avoidance =
+			pParam->sap_channel_avoidance;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+		pMac->f_prefer_non_dfs_on_radar =
+			pParam->f_prefer_non_dfs_on_radar;
+
+		pMac->sme.ps_global_info.ps_enabled =
+			pParam->is_ps_enabled;
+		pMac->sme.ps_global_info.auto_bmps_timer_val =
+			pParam->auto_bmps_timer_val;
+		pMac->dual_mac_feature_disable =
+			pParam->dual_mac_feature_disable;
+		pMac->sta_sap_scc_on_dfs_chan =
+			pParam->sta_sap_scc_on_dfs_chan;
+		pMac->roam.configParam.sta_roam_policy.dfs_mode =
+			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.enable_bcast_probe_rsp =
+			pParam->enable_bcast_probe_rsp;
+		pMac->roam.configParam.is_fils_enabled =
+			pParam->is_fils_enabled;
+		pMac->roam.configParam.wlm_latency_enable =
+			pParam->wlm_latency_enable;
+		pMac->roam.configParam.wlm_latency_level =
+			pParam->wlm_latency_level;
+		for (i = 0; i < CSR_NUM_WLM_LATENCY_LEVEL; i++) {
+			pMac->roam.configParam.wlm_latency_flags[i] =
+				pParam->wlm_latency_flags[i];
+		}
+		pMac->roam.configParam.oce_feature_bitmap =
+			pParam->oce_feature_bitmap;
+		pMac->roam.configParam.roam_force_rssi_trigger =
+			pParam->roam_force_rssi_trigger;
+
+		pMac->roam.configParam.btm_offload_config =
+						     pParam->btm_offload_config;
+		pMac->roam.configParam.btm_solicited_timeout =
+			pParam->btm_solicited_timeout;
+		pMac->roam.configParam.btm_max_attempt_cnt =
+			pParam->btm_max_attempt_cnt;
+		pMac->roam.configParam.btm_sticky_time =
+			pParam->btm_sticky_time;
+
+		csr_update_he_config_param(pMac, pParam);
+		csr_set_11k_offload_config_param(&pMac->roam.configParam,
+						 pParam);
+	}
+	return status;
+}
+
+/**
+ * csr_get_11k_offload_config_param() - Get 11k neighbor report config
+ *
+ * @csr_config: pointer to csr_config in MAC context
+ * @pParam: pointer to config params from HDD
+ *
+ * Return: none
+ */
+static
+void csr_get_11k_offload_config_param(struct csr_config *csr_config,
+					tCsrConfigParam *param)
+{
+	param->offload_11k_enable_bitmask =
+		csr_config->offload_11k_enable_bitmask;
+	param->neighbor_report_offload.params_bitmask =
+		csr_config->neighbor_report_offload.params_bitmask;
+	param->neighbor_report_offload.time_offset =
+		csr_config->neighbor_report_offload.time_offset;
+	param->neighbor_report_offload.low_rssi_offset =
+		csr_config->neighbor_report_offload.low_rssi_offset;
+	param->neighbor_report_offload.bmiss_count_trigger =
+		csr_config->neighbor_report_offload.bmiss_count_trigger;
+	param->neighbor_report_offload.per_threshold_offset =
+		csr_config->neighbor_report_offload.per_threshold_offset;
+	param->neighbor_report_offload.neighbor_report_cache_timeout =
+		csr_config->neighbor_report_offload.
+		neighbor_report_cache_timeout;
+	param->neighbor_report_offload.max_neighbor_report_req_cap =
+		csr_config->neighbor_report_offload.
+		max_neighbor_report_req_cap;
+}
+
+QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
+{
+	int i;
+	struct csr_config *cfg_params = &pMac->roam.configParam;
+
+	if (!pParam)
+		return QDF_STATUS_E_INVAL;
+
+	pParam->is_force_1x1 = cfg_params->is_force_1x1;
+	pParam->WMMSupportMode = cfg_params->WMMSupportMode;
+	pParam->Is11eSupportEnabled = cfg_params->Is11eSupportEnabled;
+	pParam->Is11dSupportEnabled = cfg_params->Is11dSupportEnabled;
+	pParam->Is11hSupportEnabled = cfg_params->Is11hSupportEnabled;
+	pParam->channelBondingMode24GHz = csr_convert_phy_cb_state_to_ini_value(
+					cfg_params->channelBondingMode24GHz);
+	pParam->channelBondingMode5GHz = csr_convert_phy_cb_state_to_ini_value(
+					cfg_params->channelBondingMode5GHz);
+	pParam->phyMode = cfg_params->phyMode;
+	pParam->shortSlotTime = cfg_params->shortSlotTime;
+	pParam->HeartbeatThresh50 = cfg_params->HeartbeatThresh50;
+	pParam->ProprietaryRatesEnabled = cfg_params->ProprietaryRatesEnabled;
+	pParam->AdHocChannel24 = cfg_params->AdHocChannel24;
+	pParam->AdHocChannel5G = cfg_params->AdHocChannel5G;
+	pParam->nActiveMaxChnTime = cfg_params->nActiveMaxChnTime;
+	pParam->nPassiveMaxChnTime = cfg_params->nPassiveMaxChnTime;
+	pParam->nActiveMaxChnTimeConc = cfg_params->nActiveMaxChnTimeConc;
+	pParam->nActiveMinChnTimeConc = cfg_params->nActiveMinChnTimeConc;
+	pParam->nPassiveMaxChnTimeConc = cfg_params->nPassiveMaxChnTimeConc;
+	pParam->nPassiveMinChnTimeConc = cfg_params->nPassiveMinChnTimeConc;
+	pParam->nRestTimeConc = cfg_params->nRestTimeConc;
+	pParam->min_rest_time_conc = cfg_params->min_rest_time_conc;
+	pParam->idle_time_conc = cfg_params->idle_time_conc;
+	pParam->nScanResultAgeCount = cfg_params->agingCount;
+	pParam->bCatRssiOffset = cfg_params->bCatRssiOffset;
+	pParam->fSupplicantCountryCodeHasPriority =
+		cfg_params->fSupplicantCountryCodeHasPriority;
+	pParam->vccRssiThreshold = cfg_params->vccRssiThreshold;
+	pParam->vccUlMacLossThreshold = cfg_params->vccUlMacLossThreshold;
+	pParam->nTxPowerCap = cfg_params->nTxPowerCap;
+	pParam->allow_tpc_from_ap = cfg_params->allow_tpc_from_ap;
+	pParam->statsReqPeriodicity = cfg_params->statsReqPeriodicity;
+	pParam->statsReqPeriodicityInPS = cfg_params->statsReqPeriodicityInPS;
+	pParam->addTSWhenACMIsOff = cfg_params->addTSWhenACMIsOff;
+	pParam->fEnableBypass11d = pMac->scan.fEnableBypass11d;
+	pParam->fEnableDFSChnlScan = pMac->scan.fEnableDFSChnlScan;
+	pParam->fScanTwice = cfg_params->fScanTwice;
+	pParam->fFirstScanOnly2GChnl = pMac->scan.fFirstScanOnly2GChnl;
+	pParam->fEnableMCCMode = cfg_params->fenableMCCMode;
+	pParam->fAllowMCCGODiffBI = cfg_params->fAllowMCCGODiffBI;
+	pParam->scanCfgAgingTime = pMac->scan.scanResultCfgAgingTime;
+	qdf_mem_copy(&pParam->neighborRoamConfig,
+		     &cfg_params->neighborRoamConfig,
+		     sizeof(tCsrNeighborRoamConfigParams));
+	pParam->isFastTransitionEnabled = cfg_params->isFastTransitionEnabled;
+	pParam->RoamRssiDiff = cfg_params->RoamRssiDiff;
+	pParam->nRoamPrefer5GHz = cfg_params->nRoamPrefer5GHz;
+	pParam->nRoamIntraBand = cfg_params->nRoamIntraBand;
+	pParam->isWESModeEnabled = cfg_params->isWESModeEnabled;
+	pParam->nProbes = cfg_params->nProbes;
+	pParam->nRoamScanHomeAwayTime = cfg_params->nRoamScanHomeAwayTime;
+	pParam->isRoamOffloadScanEnabled = cfg_params->isRoamOffloadScanEnabled;
+	pParam->bFastRoamInConIniFeatureEnabled =
+		cfg_params->bFastRoamInConIniFeatureEnabled;
+	pParam->isFastRoamIniFeatureEnabled =
+		cfg_params->isFastRoamIniFeatureEnabled;
+#ifdef FEATURE_WLAN_ESE
+	pParam->isEseIniFeatureEnabled = cfg_params->isEseIniFeatureEnabled;
+#endif
+	qdf_mem_copy(&pParam->neighborRoamConfig,
+		     &cfg_params->neighborRoamConfig,
+		     sizeof(tCsrNeighborRoamConfigParams));
+	sme_debug("Num of Channels in CFG Channel List: %d",
+		cfg_params->neighborRoamConfig.
+		neighborScanChanList.numChannels);
+	for (i = 0; i < cfg_params->neighborRoamConfig.
+	     neighborScanChanList.numChannels; i++) {
+		sme_debug("%d ",
+			cfg_params->neighborRoamConfig.
+			neighborScanChanList.channelList[i]);
+	}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	pParam->cc_switch_mode = cfg_params->cc_switch_mode;
+#endif
+	pParam->enable_tx_ldpc = cfg_params->tx_ldpc_enable;
+	pParam->enable_rx_ldpc = cfg_params->rx_ldpc_enable;
+	pParam->wep_tkip_in_he = cfg_params->wep_tkip_in_he;
+	pParam->disable_high_ht_mcs_2x2 = cfg_params->disable_high_ht_mcs_2x2;
+	pParam->ho_delay_for_rx = cfg_params->ho_delay_for_rx;
+	pParam->min_delay_btw_roam_scans = cfg_params->min_delay_btw_roam_scans;
+	pParam->roam_trigger_reason_bitmask =
+			cfg_params->roam_trigger_reason_bitmask;
+	pParam->isCoalesingInIBSSAllowed = cfg_params->isCoalesingInIBSSAllowed;
+	pParam->allowDFSChannelRoam = cfg_params->allowDFSChannelRoam;
+	pParam->nInitialDwellTime = cfg_params->nInitialDwellTime;
+	pParam->initial_scan_no_dfs_chnl = cfg_params->initial_scan_no_dfs_chnl;
+	csr_set_channels(pMac, pParam);
+	pParam->obssEnabled = cfg_params->obssEnabled;
+	pParam->vendor_vht_sap =
+		pMac->roam.configParam.vendor_vht_sap;
+	pParam->roam_dense_min_aps =
+			cfg_params->roam_params.dense_min_aps_cnt;
+
+	pParam->roam_bg_scan_bad_rssi_thresh =
+		cfg_params->roam_params.bg_scan_bad_rssi_thresh;
+	pParam->roam_bg_scan_client_bitmap =
+		cfg_params->roam_params.bg_scan_client_bitmap;
+	pParam->roam_bad_rssi_thresh_offset_2g =
+		cfg_params->roam_params.roam_bad_rssi_thresh_offset_2g;
+
+	pParam->enable_ftopen = cfg_params->enable_ftopen;
+	pParam->scan_adaptive_dwell_mode =
+			cfg_params->scan_adaptive_dwell_mode;
+	pParam->scan_adaptive_dwell_mode_nc =
+			cfg_params->scan_adaptive_dwell_mode_nc;
+
+	pParam->conc_custom_rule1 = cfg_params->conc_custom_rule1;
+	pParam->conc_custom_rule2 = cfg_params->conc_custom_rule2;
+	pParam->is_sta_connection_in_5gz_enabled =
+		cfg_params->is_sta_connection_in_5gz_enabled;
+	pParam->max_scan_count = pMac->scan.max_scan_count;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	pParam->sap_channel_avoidance = pMac->sap.sap_channel_avoidance;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+	pParam->max_intf_count = pMac->sme.max_intf_count;
+	pParam->f_prefer_non_dfs_on_radar =
+		pMac->f_prefer_non_dfs_on_radar;
+	pParam->dual_mac_feature_disable =
+		pMac->dual_mac_feature_disable;
+	pParam->sta_sap_scc_on_dfs_chan =
+		pMac->sta_sap_scc_on_dfs_chan;
+	pParam->is_ps_enabled = pMac->sme.ps_global_info.ps_enabled;
+	pParam->auto_bmps_timer_val =
+		pMac->sme.ps_global_info.auto_bmps_timer_val;
+	pParam->f_sta_miracast_mcc_rest_time_val =
+		pMac->f_sta_miracast_mcc_rest_time_val;
+	pParam->send_smps_action = pMac->roam.configParam.send_smps_action;
+	pParam->sta_roam_policy_params.dfs_mode =
+		pMac->roam.configParam.sta_roam_policy.dfs_mode;
+	pParam->sta_roam_policy_params.skip_unsafe_channels =
+		pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels;
+	pParam->enable_bcast_probe_rsp =
+		pMac->roam.configParam.enable_bcast_probe_rsp;
+	pParam->is_fils_enabled =
+		pMac->roam.configParam.is_fils_enabled;
+	pParam->oce_feature_bitmap =
+		pMac->roam.configParam.oce_feature_bitmap;
+	pParam->roam_force_rssi_trigger = cfg_params->roam_force_rssi_trigger;
+	pParam->btm_offload_config = pMac->roam.configParam.btm_offload_config;
+	pParam->btm_solicited_timeout =
+		pMac->roam.configParam.btm_solicited_timeout;
+	pParam->btm_max_attempt_cnt =
+		pMac->roam.configParam.btm_max_attempt_cnt;
+	pParam->btm_sticky_time = pMac->roam.configParam.btm_sticky_time;
+
+	csr_get_he_config_param(pParam, pMac);
+
+	csr_get_11k_offload_config_param(&pMac->roam.configParam, pParam);
+
+	pParam->wlm_latency_enable = pMac->roam.configParam.wlm_latency_enable;
+	pParam->wlm_latency_level = pMac->roam.configParam.wlm_latency_level;
+	for (i = 0; i < CSR_NUM_WLM_LATENCY_LEVEL; i++) {
+		pParam->wlm_latency_flags[i] =
+			pMac->roam.configParam.wlm_latency_flags[i];
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_prune_ch_list() - prunes the channel list to keep only a type of channels
+ * @ch_lst:        existing channel list
+ * @is_24_GHz:     indicates if 2.5 GHz or 5 GHz channels are required
+ *
+ * Return: void
+ */
+static void csr_prune_ch_list(struct csr_channel *ch_lst, bool is_24_GHz)
+{
+	uint8_t idx = 0, num_channels = 0;
+
+	for ( ; idx < ch_lst->numChannels; idx++) {
+		if (is_24_GHz) {
+			if (WLAN_REG_IS_24GHZ_CH(ch_lst->channelList[idx])) {
+				ch_lst->channelList[num_channels] =
+					ch_lst->channelList[idx];
+				num_channels++;
+			}
+		} else {
+			if (WLAN_REG_IS_5GHZ_CH(ch_lst->channelList[idx])) {
+				ch_lst->channelList[num_channels] =
+					ch_lst->channelList[idx];
+				num_channels++;
+			}
+		}
+	}
+	/*
+	 * Cleanup the rest of channels. Note we only need to clean up the
+	 * channels if we had to trim the list. Calling qdf_mem_set() with a 0
+	 * size is going to throw asserts on the debug builds so let's be a bit
+	 * smarter about that. Zero out the reset of the channels only if we
+	 * need to. The amount of memory to clear is the number of channesl that
+	 * we trimmed (ch_lst->numChannels - num_channels) times the size of a
+	 * channel in the structure.
+	 */
+	if (ch_lst->numChannels > num_channels) {
+		qdf_mem_set(&ch_lst->channelList[num_channels],
+			    sizeof(ch_lst->channelList[0]) *
+			    (ch_lst->numChannels - num_channels), 0);
+	}
+	ch_lst->numChannels = num_channels;
+}
+
+/**
+ * csr_prune_channel_list_for_mode() - prunes the channel list
+ * @mac_ctx:       global mac context
+ * @ch_lst:        existing channel list
+ *
+ * Prunes the channel list according to band stored in mac_ctx
+ *
+ * Return: void
+ */
+void csr_prune_channel_list_for_mode(tpAniSirGlobal mac_ctx,
+				     struct csr_channel *ch_lst)
+{
+	/* for dual band NICs, don't need to trim the channel list.... */
+	if (CSR_IS_OPEARTING_DUAL_BAND(mac_ctx))
+		return;
+	/*
+	 * 2.4 GHz band operation requires the channel list to be trimmed to
+	 * the 2.4 GHz channels only
+	 */
+	if (CSR_IS_24_BAND_ONLY(mac_ctx))
+		csr_prune_ch_list(ch_lst, true);
+	else if (CSR_IS_5G_BAND_ONLY(mac_ctx))
+		csr_prune_ch_list(ch_lst, false);
+}
+
+#define INFRA_AP_DEFAULT_CHANNEL 6
+QDF_STATUS csr_is_valid_channel(tpAniSirGlobal pMac, uint8_t chnNum)
+{
+	uint8_t index = 0;
+	QDF_STATUS status = QDF_STATUS_E_NOSUPPORT;
+
+	/* regulatory check */
+	for (index = 0; index < pMac->scan.base_channels.numChannels;
+	     index++) {
+		if (pMac->scan.base_channels.channelList[index] == chnNum) {
+			status = QDF_STATUS_SUCCESS;
+			break;
+		}
+	}
+
+	if (status == QDF_STATUS_SUCCESS) {
+		/* dfs nol */
+		for (index = 0;
+		     index <
+		     pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels;
+		     index++) {
+			tSapDfsNolInfo *dfsChan = &pMac->sap.SapDfsInfo.
+						sapDfsChannelNolList[index];
+			if ((dfsChan->dfs_channel_number == chnNum)
+			    && (dfsChan->radar_status_flag ==
+				eSAP_DFS_CHANNEL_UNAVAILABLE)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					 FL("channel %d is in dfs nol"),
+					  chnNum);
+				status = QDF_STATUS_E_FAILURE;
+				break;
+			}
+		}
+	}
+
+	if (QDF_STATUS_SUCCESS != status) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			 FL("channel %d is not available"), chnNum);
+	}
+
+	return status;
+}
+
+QDF_STATUS csr_get_channel_and_power_list(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t num20MHzChannelsFound = 0;
+	QDF_STATUS qdf_status;
+	uint8_t Index = 0;
+
+	qdf_status = wlan_reg_get_channel_list_with_power(pMac->pdev,
+				pMac->scan.defaultPowerTable,
+				&num20MHzChannelsFound);
+
+	if ((QDF_STATUS_SUCCESS != qdf_status) ||
+	    (num20MHzChannelsFound == 0)) {
+		sme_err("failed to get channels");
+		status = QDF_STATUS_E_FAILURE;
+	} else {
+		if (num20MHzChannelsFound > WNI_CFG_VALID_CHANNEL_LIST_LEN)
+			num20MHzChannelsFound = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+		pMac->scan.numChannelsDefault = num20MHzChannelsFound;
+		/* Move the channel list to the global data */
+		/* structure -- this will be used as the scan list */
+		for (Index = 0; Index < num20MHzChannelsFound; Index++)
+			pMac->scan.base_channels.channelList[Index] =
+				pMac->scan.defaultPowerTable[Index].chan_num;
+		pMac->scan.base_channels.numChannels =
+			num20MHzChannelsFound;
+	}
+	return status;
+}
+
+QDF_STATUS csr_apply_channel_and_power_list(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	csr_prune_channel_list_for_mode(pMac, &pMac->scan.base_channels);
+	csr_save_channel_power_for_band(pMac, false);
+	csr_save_channel_power_for_band(pMac, true);
+	csr_apply_channel_power_info_to_fw(pMac,
+					   &pMac->scan.base_channels,
+					   pMac->scan.countryCodeCurrent);
+
+	csr_init_operating_classes(pMac);
+	return status;
+}
+
+static QDF_STATUS csr_init11d_info(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint8_t index;
+	uint32_t count = 0;
+	tSirMacChanInfo *pChanInfo;
+	tSirMacChanInfo *pChanInfoStart;
+	bool applyConfig = true;
+
+	if (!ps11dinfo)
+		return status;
+
+	if (ps11dinfo->Channels.numChannels
+	    && (WNI_CFG_VALID_CHANNEL_LIST_LEN >=
+		ps11dinfo->Channels.numChannels)) {
+		pMac->scan.base_channels.numChannels =
+			ps11dinfo->Channels.numChannels;
+		qdf_mem_copy(pMac->scan.base_channels.channelList,
+			     ps11dinfo->Channels.channelList,
+			     ps11dinfo->Channels.numChannels);
+	} else {
+		/* No change */
+		return QDF_STATUS_SUCCESS;
+	}
+	/* legacy maintenance */
+
+	qdf_mem_copy(pMac->scan.countryCodeDefault, ps11dinfo->countryCode,
+		     WNI_CFG_COUNTRY_CODE_LEN);
+
+	/* Tush: at csropen get this initialized with default,
+	 * during csr reset if this already set with some value
+	 * no need initilaize with default again
+	 */
+	if (0 == pMac->scan.countryCodeCurrent[0]) {
+		qdf_mem_copy(pMac->scan.countryCodeCurrent,
+			     ps11dinfo->countryCode, WNI_CFG_COUNTRY_CODE_LEN);
+	}
+	/* need to add the max power channel list */
+	pChanInfo =
+		qdf_mem_malloc(sizeof(tSirMacChanInfo) *
+			       WNI_CFG_VALID_CHANNEL_LIST_LEN);
+	if (pChanInfo != NULL) {
+		pChanInfoStart = pChanInfo;
+		for (index = 0; index < ps11dinfo->Channels.numChannels;
+		     index++) {
+			pChanInfo->firstChanNum =
+				ps11dinfo->ChnPower[index].firstChannel;
+			pChanInfo->numChannels =
+				ps11dinfo->ChnPower[index].numChannels;
+			pChanInfo->maxTxPower =
+				QDF_MIN(ps11dinfo->ChnPower[index].maxtxPower,
+					pMac->roam.configParam.nTxPowerCap);
+			pChanInfo++;
+			count++;
+		}
+		if (count) {
+			status = csr_save_to_channel_power2_g_5_g(pMac,
+							 count *
+							sizeof(tSirMacChanInfo),
+							 pChanInfoStart);
+		}
+		qdf_mem_free(pChanInfoStart);
+	}
+	/* Only apply them to CFG when not in STOP state.
+	 * Otherwise they will be applied later
+	 */
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		for (index = 0; index < CSR_ROAM_SESSION_MAX; index++) {
+			if ((CSR_IS_SESSION_VALID(pMac, index))
+			    && CSR_IS_ROAM_STOP(pMac, index)) {
+				applyConfig = false;
+			}
+		}
+
+		if (true == applyConfig) {
+			/* Apply the base channel list, power info,
+			 * and set the Country code.
+			 */
+			csr_apply_channel_power_info_to_fw(pMac,
+							   &pMac->scan.
+							   base_channels,
+							   pMac->scan.
+							   countryCodeCurrent);
+		}
+	}
+	return status;
+}
+
+/* Initialize the Channel + Power List in the local cache and in the CFG */
+QDF_STATUS csr_init_channel_power_list(tpAniSirGlobal pMac,
+					tCsr11dinfo *ps11dinfo)
+{
+	uint8_t index;
+	uint32_t count = 0;
+	tSirMacChanInfo *pChanInfo;
+	tSirMacChanInfo *pChanInfoStart;
+
+	if (!ps11dinfo || !pMac)
+		return QDF_STATUS_E_FAILURE;
+
+	pChanInfo =
+		qdf_mem_malloc(sizeof(tSirMacChanInfo) *
+			       WNI_CFG_VALID_CHANNEL_LIST_LEN);
+	if (pChanInfo != NULL) {
+		pChanInfoStart = pChanInfo;
+
+		for (index = 0; index < ps11dinfo->Channels.numChannels;
+		     index++) {
+			pChanInfo->firstChanNum =
+				ps11dinfo->ChnPower[index].firstChannel;
+			pChanInfo->numChannels =
+				ps11dinfo->ChnPower[index].numChannels;
+			pChanInfo->maxTxPower =
+				QDF_MIN(ps11dinfo->ChnPower[index].maxtxPower,
+					pMac->roam.configParam.nTxPowerCap);
+			pChanInfo++;
+			count++;
+		}
+		if (count) {
+			csr_save_to_channel_power2_g_5_g(pMac,
+							 count *
+							sizeof(tSirMacChanInfo),
+							 pChanInfoStart);
+		}
+		qdf_mem_free(pChanInfoStart);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_roam_remove_duplicate_cmd_from_list()- Remove duplicate roam cmd from
+ * list
+ *
+ * @mac_ctx: pointer to global mac
+ * @session_id: session id for the cmd
+ * @list: pending list from which cmd needs to be removed
+ * @command: cmd to be removed, can be NULL
+ * @roam_reason: cmd with reason to be removed
+ *
+ * Remove duplicate command from the pending list.
+ *
+ * Return: void
+ */
+static void csr_roam_remove_duplicate_pending_cmd_from_list(
+			tpAniSirGlobal mac_ctx,
+			uint32_t session_id,
+			tSmeCmd *command, enum csr_roam_reason roam_reason)
+{
+	tListElem *entry, *next_entry;
+	tSmeCmd *dup_cmd;
+	tDblLinkList local_list;
+
+	qdf_mem_zero(&local_list, sizeof(tDblLinkList));
+	if (!QDF_IS_STATUS_SUCCESS(csr_ll_open(&local_list))) {
+		sme_err("failed to open list");
+		return;
+	}
+	csr_nonscan_pending_ll_lock(mac_ctx);
+	entry = csr_nonscan_pending_ll_peek_head(mac_ctx, LL_ACCESS_NOLOCK);
+	while (entry) {
+		next_entry = csr_nonscan_pending_ll_next(mac_ctx, entry,
+						LL_ACCESS_NOLOCK);
+		dup_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
+		/*
+		 * If command is not NULL remove the similar duplicate cmd for
+		 * same reason as command. If command is NULL then check if
+		 * roam_reason is eCsrForcedDisassoc (disconnect) and remove
+		 * all roam command for the sessionId, else if roam_reason is
+		 * eCsrHddIssued (connect) remove all connect (non disconenct)
+		 * commands.
+		 */
+		if ((command && (command->sessionId == dup_cmd->sessionId) &&
+			((command->command == dup_cmd->command) &&
+			/*
+			 * This peermac check is required for Softap/GO
+			 * scenarios. for STA scenario below OR check will
+			 * suffice as command will always be NULL for
+			 * STA scenarios
+			 */
+			(!qdf_mem_cmp(dup_cmd->u.roamCmd.peerMac,
+				command->u.roamCmd.peerMac,
+					sizeof(QDF_MAC_ADDR_SIZE))) &&
+				((command->u.roamCmd.roamReason ==
+					dup_cmd->u.roamCmd.roamReason) ||
+				(eCsrForcedDisassoc ==
+					command->u.roamCmd.roamReason) ||
+				(eCsrHddIssued ==
+					command->u.roamCmd.roamReason)))) ||
+			/* OR if pCommand is NULL */
+			((session_id == dup_cmd->sessionId) &&
+			(eSmeCommandRoam == dup_cmd->command) &&
+			((eCsrForcedDisassoc == roam_reason) ||
+			(eCsrHddIssued == roam_reason &&
+			!CSR_IS_DISCONNECT_COMMAND(dup_cmd))))) {
+			sme_debug("RoamReason: %d",
+					dup_cmd->u.roamCmd.roamReason);
+			/* Insert to local_list and remove later */
+			csr_ll_insert_tail(&local_list, entry,
+					   LL_ACCESS_NOLOCK);
+		}
+		entry = next_entry;
+	}
+	csr_nonscan_pending_ll_unlock(mac_ctx);
+
+	while ((entry = csr_ll_remove_head(&local_list, LL_ACCESS_NOLOCK))) {
+		dup_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
+		/* Tell caller that the command is cancelled */
+		csr_roam_call_callback(mac_ctx, dup_cmd->sessionId, NULL,
+				dup_cmd->u.roamCmd.roamId,
+				eCSR_ROAM_CANCELLED, eCSR_ROAM_RESULT_NONE);
+		csr_release_command(mac_ctx, dup_cmd);
+	}
+	csr_ll_close(&local_list);
+}
+
+/**
+ * csr_roam_remove_duplicate_command()- Remove duplicate roam cmd
+ * from pending lists.
+ *
+ * @mac_ctx: pointer to global mac
+ * @session_id: session id for the cmd
+ * @command: cmd to be removed, can be null
+ * @roam_reason: cmd with reason to be removed
+ *
+ * Remove duplicate command from the sme and roam pending list.
+ *
+ * Return: void
+ */
+void csr_roam_remove_duplicate_command(tpAniSirGlobal mac_ctx,
+			uint32_t session_id, tSmeCmd *command,
+			enum csr_roam_reason roam_reason)
+{
+	/* Always lock active list before locking pending lists */
+	csr_nonscan_active_ll_lock(mac_ctx);
+	csr_roam_remove_duplicate_pending_cmd_from_list(mac_ctx,
+		session_id, command, roam_reason);
+	csr_nonscan_active_ll_unlock(mac_ctx);
+}
+
+/**
+ * csr_roam_populate_channels() - Helper function to populate channels
+ * @beacon_ies: pointer to beacon ie
+ * @roam_info: Roaming related information
+ * @chan1: center freq 1
+ * @chan2: center freq2
+ *
+ * This function will issue populate chan1 and chan2 based on beacon ie
+ *
+ * Return: none.
+ */
+static void csr_roam_populate_channels(tDot11fBeaconIEs *beacon_ies,
+			struct csr_roam_info *roam_info,
+			uint8_t *chan1, uint8_t *chan2)
+{
+	ePhyChanBondState phy_state;
+
+	if (beacon_ies->VHTOperation.present) {
+		*chan1 = beacon_ies->VHTOperation.chanCenterFreqSeg1;
+		*chan2 = beacon_ies->VHTOperation.chanCenterFreqSeg2;
+		roam_info->chan_info.info = MODE_11AC_VHT80;
+	} else if (beacon_ies->HTInfo.present) {
+		if (beacon_ies->HTInfo.recommendedTxWidthSet ==
+			eHT_CHANNEL_WIDTH_40MHZ) {
+			phy_state = beacon_ies->HTInfo.secondaryChannelOffset;
+			if (phy_state == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+				*chan1 = beacon_ies->HTInfo.primaryChannel +
+						CSR_CB_CENTER_CHANNEL_OFFSET;
+			else if (phy_state == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+				*chan1 = beacon_ies->HTInfo.primaryChannel -
+						CSR_CB_CENTER_CHANNEL_OFFSET;
+			else
+				*chan1 = beacon_ies->HTInfo.primaryChannel;
+
+			roam_info->chan_info.info = MODE_11NA_HT40;
+		} else {
+			*chan1 = beacon_ies->HTInfo.primaryChannel;
+			roam_info->chan_info.info = MODE_11NA_HT20;
+		}
+		*chan2 = 0;
+	} else {
+		*chan1 = 0;
+		*chan2 = 0;
+		roam_info->chan_info.info = MODE_11A;
+	}
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static const char *csr_get_ch_width_str(uint8_t ch_width)
+{
+	switch (ch_width) {
+	CASE_RETURN_STRING(BW_20MHZ);
+	CASE_RETURN_STRING(BW_40MHZ);
+	CASE_RETURN_STRING(BW_80MHZ);
+	CASE_RETURN_STRING(BW_160MHZ);
+	CASE_RETURN_STRING(BW_80P80MHZ);
+	CASE_RETURN_STRING(BW_5MHZ);
+	CASE_RETURN_STRING(BW_10MHZ);
+	default:
+		return "Unknown";
+	}
+}
+
+static const char *csr_get_dot11_mode_str(enum csr_cfgdot11mode dot11mode)
+{
+	switch (dot11mode) {
+	CASE_RETURN_STRING(DOT11_MODE_AUTO);
+	CASE_RETURN_STRING(DOT11_MODE_ABG);
+	CASE_RETURN_STRING(DOT11_MODE_11A);
+	CASE_RETURN_STRING(DOT11_MODE_11B);
+	CASE_RETURN_STRING(DOT11_MODE_11G);
+	CASE_RETURN_STRING(DOT11_MODE_11N);
+	CASE_RETURN_STRING(DOT11_MODE_11AC);
+	CASE_RETURN_STRING(DOT11_MODE_11G_ONLY);
+	CASE_RETURN_STRING(DOT11_MODE_11N_ONLY);
+	CASE_RETURN_STRING(DOT11_MODE_11AC_ONLY);
+	CASE_RETURN_STRING(DOT11_MODE_11AX);
+	CASE_RETURN_STRING(DOT11_MODE_11AX_ONLY);
+	default:
+		return "Unknown";
+	}
+}
+
+static const char *csr_get_auth_type_str(uint8_t auth_type)
+{
+	switch (auth_type) {
+	CASE_RETURN_STRING(AUTH_OPEN);
+	CASE_RETURN_STRING(AUTH_SHARED);
+	CASE_RETURN_STRING(AUTH_WPA_EAP);
+	CASE_RETURN_STRING(AUTH_WPA_PSK);
+	CASE_RETURN_STRING(AUTH_WPA2_EAP);
+	CASE_RETURN_STRING(AUTH_WPA2_PSK);
+	CASE_RETURN_STRING(AUTH_WAPI_CERT);
+	CASE_RETURN_STRING(AUTH_WAPI_PSK);
+	default:
+		return "Unknown";
+	}
+}
+
+static const char *csr_get_encr_type_str(uint8_t encr_type)
+{
+	switch (encr_type) {
+	CASE_RETURN_STRING(ENC_MODE_OPEN);
+	CASE_RETURN_STRING(ENC_MODE_WEP40);
+	CASE_RETURN_STRING(ENC_MODE_WEP104);
+	CASE_RETURN_STRING(ENC_MODE_TKIP);
+	CASE_RETURN_STRING(ENC_MODE_AES);
+	CASE_RETURN_STRING(ENC_MODE_AES_GCMP);
+	CASE_RETURN_STRING(ENC_MODE_AES_GCMP_256);
+	CASE_RETURN_STRING(ENC_MODE_SMS4);
+	default:
+		return "Unknown";
+	}
+}
+
+static void csr_dump_connection_stats(tpAniSirGlobal mac_ctx,
+		struct csr_roam_session *session,
+		struct csr_roam_info *roam_info,
+		eRoamCmdStatus u1, eCsrRoamResult u2)
+{
+	struct tagCsrRoamConnectedProfile *conn_profile;
+	struct csr_roam_profile *profile;
+	WLAN_HOST_DIAG_EVENT_DEF(conn_stats,
+				 struct host_event_wlan_connection_stats);
+
+	if (!session || !session->pCurRoamProfile || !roam_info)
+		return;
+
+	conn_profile = roam_info->u.pConnectedProfile;
+	if (!conn_profile)
+		return;
+	profile = session->pCurRoamProfile;
+	qdf_mem_set(&conn_stats,
+		    sizeof(struct host_event_wlan_connection_stats), 0);
+	qdf_mem_copy(conn_stats.bssid, conn_profile->bssid.bytes,
+		     QDF_MAC_ADDR_SIZE);
+	conn_stats.ssid_len = conn_profile->SSID.length;
+	if (conn_stats.ssid_len > SIR_MAC_MAX_SSID_LENGTH)
+		conn_stats.ssid_len = SIR_MAC_MAX_SSID_LENGTH;
+	qdf_mem_copy(conn_stats.ssid, conn_profile->SSID.ssId,
+		     conn_stats.ssid_len);
+	sme_get_rssi_snr_by_bssid(MAC_HANDLE(mac_ctx),
+				  session->pCurRoamProfile,
+				  &conn_stats.bssid[0],
+				  &conn_stats.rssi, NULL);
+	conn_stats.est_link_speed = 0;
+	conn_stats.chnl_bw =
+		diag_ch_width_from_csr_type(conn_profile->vht_channel_width);
+	conn_stats.dot11mode =
+		diag_dot11_mode_from_csr_type(conn_profile->dot11Mode);
+	conn_stats.bss_type =
+	     diag_persona_from_csr_type(session->pCurRoamProfile->csrPersona);
+	conn_stats.operating_channel = conn_profile->operationChannel;
+	conn_stats.qos_capability = conn_profile->qosConnection;
+	conn_stats.auth_type =
+	     diag_auth_type_from_csr_type(conn_profile->AuthType);
+	conn_stats.encryption_type =
+	     diag_enc_type_from_csr_type(conn_profile->EncryptionType);
+	conn_stats.result_code = (u2 == eCSR_ROAM_RESULT_ASSOCIATED) ? 1 : 0;
+	conn_stats.reason_code = 0;
+	sme_debug("+---------CONNECTION INFO START------------+");
+	sme_debug("connection stats for session-id: %d", session->sessionId);
+	sme_debug("ssid: %.*s", conn_stats.ssid_len, conn_stats.ssid);
+	sme_debug("bssid: %pM", conn_stats.bssid);
+	sme_debug("rssi: %d dBm", conn_stats.rssi);
+	sme_debug("channel: %d", conn_stats.operating_channel);
+	sme_debug("dot11Mode: %s",
+		  csr_get_dot11_mode_str(conn_stats.dot11mode));
+	sme_debug("channel bw: %s",
+		  csr_get_ch_width_str(conn_stats.chnl_bw));
+	sme_debug("Qos enable: %d", conn_stats.qos_capability);
+	sme_debug("Auth-type: %s",
+		  csr_get_auth_type_str(conn_stats.auth_type));
+	sme_debug("Encry-type: %s",
+		  csr_get_encr_type_str(conn_stats.encryption_type));
+	sme_debug("is associated?: %s",
+		  (conn_stats.result_code ? "yes" : "no"));
+	sme_debug("+---------CONNECTION INFO END------------+");
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&conn_stats, EVENT_WLAN_CONN_STATS_V2);
+}
+#else
+static void csr_dump_connection_stats(tpAniSirGlobal mac_ctx,
+		struct csr_roam_session *session,
+		struct csr_roam_info *roam_info,
+		eRoamCmdStatus u1, eCsrRoamResult u2)
+{}
+
+#endif
+
+QDF_STATUS csr_roam_call_callback(tpAniSirGlobal pMac, uint32_t sessionId,
+				  struct csr_roam_info *roam_info,
+				  uint32_t roamId,
+				  eRoamCmdStatus u1, eCsrRoamResult u2)
+{
+	QDF_STATUS ret, status = QDF_STATUS_SUCCESS;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+
+	WLAN_HOST_DIAG_EVENT_DEF(connectionStatus,
+			host_event_wlan_status_payload_type);
+#endif
+	struct csr_roam_session *pSession;
+	tDot11fBeaconIEs *beacon_ies = NULL;
+	uint8_t chan1, chan2;
+
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		sme_err("Session ID: %d is not valid", sessionId);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (false == pSession->sessionActive) {
+		sme_debug("Session is not Active");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (eCSR_ROAM_ASSOCIATION_COMPLETION == u1 &&
+			eCSR_ROAM_RESULT_ASSOCIATED == u2 && roam_info) {
+		sme_debug("Assoc complete result: %d status: %d reason: %d",
+			u2, roam_info->statusCode, roam_info->reasonCode);
+		beacon_ies = qdf_mem_malloc(sizeof(tDot11fBeaconIEs));
+		if ((NULL != beacon_ies) && (NULL != roam_info->pBssDesc)) {
+			status = csr_parse_bss_description_ies(
+					pMac, roam_info->pBssDesc,
+					beacon_ies);
+			csr_roam_populate_channels(beacon_ies, roam_info,
+					&chan1, &chan2);
+			if (0 != chan1)
+				roam_info->chan_info.band_center_freq1 =
+					cds_chan_to_freq(chan1);
+			else
+				roam_info->chan_info.band_center_freq1 = 0;
+			if (0 != chan2)
+				roam_info->chan_info.band_center_freq2 =
+					cds_chan_to_freq(chan2);
+			else
+				roam_info->chan_info.band_center_freq2 = 0;
+		} else {
+			roam_info->chan_info.band_center_freq1 = 0;
+			roam_info->chan_info.band_center_freq2 = 0;
+			roam_info->chan_info.info = 0;
+		}
+		roam_info->chan_info.chan_id =
+			roam_info->u.pConnectedProfile->operationChannel;
+		roam_info->chan_info.mhz =
+			cds_chan_to_freq(roam_info->chan_info.chan_id);
+		roam_info->chan_info.reg_info_1 =
+			(csr_get_cfg_max_tx_power(pMac,
+				roam_info->chan_info.chan_id) << 16);
+		roam_info->chan_info.reg_info_2 =
+			(csr_get_cfg_max_tx_power(pMac,
+				roam_info->chan_info.chan_id) << 8);
+		qdf_mem_free(beacon_ies);
+	} else if ((u1 == eCSR_ROAM_FT_REASSOC_FAILED)
+			&& (pSession->bRefAssocStartCnt)) {
+		/*
+		 * Decrement bRefAssocStartCnt for FT reassoc failure.
+		 * Reason: For FT reassoc failures, we first call
+		 * csr_roam_call_callback before notifying a failed roam
+		 * completion through csr_roam_complete. The latter in
+		 * turn calls csr_roam_process_results which tries to
+		 * once again call csr_roam_call_callback if bRefAssocStartCnt
+		 * is non-zero. Since this is redundant for FT reassoc
+		 * failure, decrement bRefAssocStartCnt.
+		 */
+		pSession->bRefAssocStartCnt--;
+	} else if (roam_info && (u1 == eCSR_ROAM_SET_CHANNEL_RSP)
+		   && (u2 == eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS)) {
+		pSession->connectedProfile.operationChannel =
+			roam_info->channelChangeRespEvent->newChannelNumber;
+	} else if (u1 == eCSR_ROAM_SESSION_OPENED) {
+		ret = (u2 == eCSR_ROAM_RESULT_SUCCESS) ?
+		      QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE;
+
+		if (pSession->session_open_cb)
+			pSession->session_open_cb(sessionId, ret);
+		else
+			sme_err("session_open_cb is not registered");
+	}
+	if (eCSR_ROAM_ASSOCIATION_COMPLETION == u1)
+		csr_dump_connection_stats(pMac, pSession, roam_info, u1, u2);
+
+	if (NULL != pSession->callback) {
+		if (roam_info) {
+			roam_info->sessionId = (uint8_t) sessionId;
+			/*
+			 * the reasonCode will be passed to supplicant by
+			 * cfg80211_disconnected. Based on the document,
+			 * the reason code passed to supplicant needs to set
+			 * to 0 if unknown. eSIR_BEACON_MISSED reason code is
+			 * not recognizable so that we set to 0 instead.
+			 */
+			roam_info->reasonCode =
+				(roam_info->reasonCode == eSIR_BEACON_MISSED) ?
+				0 : roam_info->reasonCode;
+		}
+		status = pSession->callback(pSession->pContext, roam_info,
+					roamId, u1, u2);
+	}
+	/*
+	 * EVENT_WLAN_STATUS_V2: eCSR_ROAM_ASSOCIATION_COMPLETION,
+	 *                    eCSR_ROAM_LOSTLINK,
+	 *                    eCSR_ROAM_DISASSOCIATED,
+	 */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	qdf_mem_set(&connectionStatus,
+			sizeof(host_event_wlan_status_payload_type), 0);
+
+	if ((eCSR_ROAM_ASSOCIATION_COMPLETION == u1)
+			&& (eCSR_ROAM_RESULT_ASSOCIATED == u2) && roam_info) {
+		connectionStatus.eventId = eCSR_WLAN_STATUS_CONNECT;
+		connectionStatus.bssType =
+			roam_info->u.pConnectedProfile->BSSType;
+
+		if (NULL != roam_info->pBssDesc) {
+			connectionStatus.rssi =
+				roam_info->pBssDesc->rssi * (-1);
+			connectionStatus.channel =
+				roam_info->pBssDesc->channelId;
+		}
+		pMac->mlme_cfg->sta.current_rssi = connectionStatus.rssi;
+
+		connectionStatus.qosCapability =
+			roam_info->u.pConnectedProfile->qosConnection;
+		connectionStatus.authType =
+			(uint8_t) diag_auth_type_from_csr_type(
+				roam_info->u.pConnectedProfile->AuthType);
+		connectionStatus.encryptionType =
+			(uint8_t) diag_enc_type_from_csr_type(
+				roam_info->u.pConnectedProfile->EncryptionType);
+		qdf_mem_copy(connectionStatus.ssid,
+				roam_info->u.pConnectedProfile->SSID.ssId,
+				roam_info->u.pConnectedProfile->SSID.length);
+
+		connectionStatus.reason = eCSR_REASON_UNSPECIFIED;
+		qdf_mem_copy(&pMac->sme.eventPayload, &connectionStatus,
+				sizeof(host_event_wlan_status_payload_type));
+		WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
+				EVENT_WLAN_STATUS_V2);
+	}
+	if ((eCSR_ROAM_MIC_ERROR_IND == u1)
+			|| (eCSR_ROAM_RESULT_MIC_FAILURE == u2)) {
+		qdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
+				sizeof(host_event_wlan_status_payload_type));
+		connectionStatus.rssi = pMac->mlme_cfg->sta.current_rssi;
+		connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
+		connectionStatus.reason = eCSR_REASON_MIC_ERROR;
+		WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
+				EVENT_WLAN_STATUS_V2);
+	}
+	if (eCSR_ROAM_RESULT_FORCED == u2) {
+		qdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
+				sizeof(host_event_wlan_status_payload_type));
+		connectionStatus.rssi = pMac->mlme_cfg->sta.current_rssi;
+		connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
+		connectionStatus.reason = eCSR_REASON_USER_REQUESTED;
+		WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
+				EVENT_WLAN_STATUS_V2);
+	}
+	if (eCSR_ROAM_RESULT_DISASSOC_IND == u2) {
+		qdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
+				sizeof(host_event_wlan_status_payload_type));
+		connectionStatus.rssi = pMac->mlme_cfg->sta.current_rssi;
+		connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
+		connectionStatus.reason = eCSR_REASON_DISASSOC;
+		if (roam_info)
+			connectionStatus.reasonDisconnect =
+				roam_info->reasonCode;
+
+		WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
+				EVENT_WLAN_STATUS_V2);
+	}
+	if (eCSR_ROAM_RESULT_DEAUTH_IND == u2) {
+		qdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
+				sizeof(host_event_wlan_status_payload_type));
+		connectionStatus.rssi = pMac->mlme_cfg->sta.current_rssi;
+		connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
+		connectionStatus.reason = eCSR_REASON_DEAUTH;
+		if (roam_info)
+			connectionStatus.reasonDisconnect =
+				roam_info->reasonCode;
+		WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
+				EVENT_WLAN_STATUS_V2);
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+	return status;
+}
+
+/* Returns whether handoff is currently in progress or not */
+static
+bool csr_roam_is_handoff_in_progress(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	return csr_neighbor_roam_is_handoff_in_progress(pMac, sessionId);
+}
+
+static
+QDF_STATUS csr_roam_issue_disassociate(tpAniSirGlobal pMac, uint32_t sessionId,
+				       enum csr_roam_substate NewSubstate,
+				       bool fMICFailure)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct qdf_mac_addr bssId = QDF_MAC_ADDR_BCAST_INIT;
+	uint16_t reasonCode;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (fMICFailure) {
+		reasonCode = eSIR_MAC_MIC_FAILURE_REASON;
+	} else if (NewSubstate == eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF) {
+		reasonCode = eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON;
+	} else if (eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT == NewSubstate) {
+		reasonCode = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
+		NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_FORCED;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"set to reason code eSIR_MAC_DISASSOC_LEAVING_BSS_REASON and set back NewSubstate");
+	} else {
+		reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
+	}
+	if ((csr_roam_is_handoff_in_progress(pMac, sessionId)) &&
+	    (NewSubstate != eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF)) {
+		tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+			&pMac->roam.neighborRoamInfo[sessionId];
+		qdf_copy_macaddr(&bssId,
+			      pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.
+			      bssid);
+	} else if (pSession->pConnectBssDesc) {
+		qdf_mem_copy(&bssId.bytes, pSession->pConnectBssDesc->bssId,
+			     sizeof(struct qdf_mac_addr));
+	}
+
+	sme_debug("CSR Attempting to Disassociate Bssid=" MAC_ADDRESS_STR
+		   " subState: %s reason: %d", MAC_ADDR_ARRAY(bssId.bytes),
+		mac_trace_getcsr_roam_sub_state(NewSubstate), reasonCode);
+
+	csr_roam_substate_change(pMac, NewSubstate, sessionId);
+
+	status = csr_send_mb_disassoc_req_msg(pMac, sessionId, bssId.bytes,
+						reasonCode);
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		csr_roam_link_down(pMac, sessionId);
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		/* no need to tell QoS that we are disassociating, it will be
+		 * taken care off in assoc req for HO
+		 */
+		if (eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF != NewSubstate) {
+			/* notify QoS module that disassoc happening */
+			sme_qos_csr_event_ind(pMac, (uint8_t) sessionId,
+					      SME_QOS_CSR_DISCONNECT_REQ, NULL);
+		}
+#endif
+	} else {
+		sme_warn("csr_send_mb_disassoc_req_msg failed status: %d",
+			status);
+	}
+
+	return status;
+}
+
+/**
+ * csr_roam_issue_disassociate_sta_cmd() - disassociate a associated station
+ * @sessionId:     Session Id for Soft AP
+ * @p_del_sta_params: Pointer to parameters of the station to disassoc
+ *
+ * CSR function that HDD calls to delete a associated station
+ *
+ * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_* on error
+ */
+QDF_STATUS csr_roam_issue_disassociate_sta_cmd(tpAniSirGlobal pMac,
+					       uint32_t sessionId,
+					       struct csr_del_sta_params
+					       *p_del_sta_params)
+
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+
+	do {
+		pCommand = csr_get_command_buffer(pMac);
+		if (!pCommand) {
+			sme_err("fail to get command buffer");
+			status = QDF_STATUS_E_RESOURCES;
+			break;
+		}
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.roamReason = eCsrForcedDisassocSta;
+		qdf_mem_copy(pCommand->u.roamCmd.peerMac,
+				p_del_sta_params->peerMacAddr.bytes,
+				sizeof(pCommand->u.roamCmd.peerMac));
+		pCommand->u.roamCmd.reason =
+			(tSirMacReasonCodes)p_del_sta_params->reason_code;
+		status = csr_queue_sme_command(pMac, pCommand, false);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			sme_err("fail to send message status: %d", status);
+	} while (0);
+
+	return status;
+}
+
+/**
+ * csr_roam_issue_deauthSta() - delete a associated station
+ * @sessionId:     Session Id for Soft AP
+ * @pDelStaParams: Pointer to parameters of the station to deauthenticate
+ *
+ * CSR function that HDD calls to delete a associated station
+ *
+ * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_** on error
+ */
+QDF_STATUS csr_roam_issue_deauth_sta_cmd(tpAniSirGlobal pMac,
+		uint32_t sessionId,
+		struct csr_del_sta_params *pDelStaParams)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+
+	do {
+		pCommand = csr_get_command_buffer(pMac);
+		if (!pCommand) {
+			sme_err("fail to get command buffer");
+			status = QDF_STATUS_E_RESOURCES;
+			break;
+		}
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.roamReason = eCsrForcedDeauthSta;
+		qdf_mem_copy(pCommand->u.roamCmd.peerMac,
+			     pDelStaParams->peerMacAddr.bytes,
+			     sizeof(tSirMacAddr));
+		pCommand->u.roamCmd.reason =
+			(tSirMacReasonCodes)pDelStaParams->reason_code;
+		status = csr_queue_sme_command(pMac, pCommand, false);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			sme_err("fail to send message status: %d", status);
+	} while (0);
+
+	return status;
+}
+
+QDF_STATUS
+csr_roam_get_associated_stas(tpAniSirGlobal pMac, uint32_t sessionId,
+			     QDF_MODULE_ID modId, void *pUsrContext,
+			     void *pfnSapEventCallback, uint8_t *pAssocStasBuf)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct qdf_mac_addr bssId = QDF_MAC_ADDR_BCAST_INIT;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("CSR Session not found");
+		return status;
+	}
+	if (pSession->pConnectBssDesc) {
+		qdf_mem_copy(bssId.bytes, pSession->pConnectBssDesc->bssId,
+			     sizeof(struct qdf_mac_addr));
+	} else {
+		sme_err("Connected BSS Description in CSR Session not found");
+		return status;
+	}
+	sme_debug("CSR getting associated stations for Bssid: " MAC_ADDRESS_STR,
+		  MAC_ADDR_ARRAY(bssId.bytes));
+	status =
+		csr_send_mb_get_associated_stas_req_msg(pMac, sessionId, modId,
+							bssId,
+							pUsrContext,
+							pfnSapEventCallback,
+							pAssocStasBuf);
+	return status;
+}
+
+static
+QDF_STATUS csr_roam_issue_deauth(tpAniSirGlobal pMac, uint32_t sessionId,
+				 enum csr_roam_substate NewSubstate)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct qdf_mac_addr bssId = QDF_MAC_ADDR_BCAST_INIT;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pSession->pConnectBssDesc) {
+		qdf_mem_copy(bssId.bytes, pSession->pConnectBssDesc->bssId,
+			     sizeof(struct qdf_mac_addr));
+	}
+	sme_debug("CSR Attempting to Deauth Bssid= " MAC_ADDRESS_STR,
+		  MAC_ADDR_ARRAY(bssId.bytes));
+	csr_roam_substate_change(pMac, NewSubstate, sessionId);
+
+	status =
+		csr_send_mb_deauth_req_msg(pMac, sessionId, bssId.bytes,
+					   eSIR_MAC_DEAUTH_LEAVING_BSS_REASON);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		csr_roam_link_down(pMac, sessionId);
+	else {
+		sme_err("csr_send_mb_deauth_req_msg failed with status %d Session ID: %d"
+			MAC_ADDRESS_STR, status, sessionId,
+			MAC_ADDR_ARRAY(bssId.bytes));
+	}
+
+	return status;
+}
+
+QDF_STATUS csr_roam_save_connected_bss_desc(tpAniSirGlobal pMac,
+						uint32_t sessionId,
+						tSirBssDescription *pBssDesc)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	uint32_t size;
+
+	if (!pSession) {
+		sme_err("  session %d not found ", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* If no BSS description was found in this connection
+	 * (happens with start IBSS), then nix the BSS description
+	 * that we keep around for the connected BSS) and get out.
+	 */
+	if (NULL == pBssDesc) {
+		csr_free_connect_bss_desc(pMac, sessionId);
+	} else {
+		size = pBssDesc->length + sizeof(pBssDesc->length);
+		if (NULL != pSession->pConnectBssDesc) {
+			if (((pSession->pConnectBssDesc->length) +
+			     sizeof(pSession->pConnectBssDesc->length)) <
+			    size) {
+				/* not enough room for the new BSS,
+				 * pMac->roam.pConnectBssDesc is freed inside
+				 */
+				csr_free_connect_bss_desc(pMac, sessionId);
+			}
+		}
+		if (NULL == pSession->pConnectBssDesc)
+			pSession->pConnectBssDesc = qdf_mem_malloc(size);
+
+		if (NULL == pSession->pConnectBssDesc)
+			status = QDF_STATUS_E_NOMEM;
+		else
+			qdf_mem_copy(pSession->pConnectBssDesc, pBssDesc, size);
+	}
+	return status;
+}
+
+static
+QDF_STATUS csr_roam_prepare_bss_config(tpAniSirGlobal pMac,
+				       struct csr_roam_profile *pProfile,
+				       tSirBssDescription *pBssDesc,
+				       struct bss_config_param *pBssConfig,
+				       tDot11fBeaconIEs *pIes)
+{
+	enum csr_cfgdot11mode cfgDot11Mode;
+	uint32_t join_timeout;
+
+	QDF_ASSERT(pIes != NULL);
+	if (pIes == NULL)
+		return QDF_STATUS_E_FAILURE;
+
+	qdf_mem_copy(&pBssConfig->BssCap, &pBssDesc->capabilityInfo,
+		     sizeof(tSirMacCapabilityInfo));
+	/* get qos */
+	pBssConfig->qosType = csr_get_qos_from_bss_desc(pMac, pBssDesc, pIes);
+	/* Take SSID always from profile */
+	qdf_mem_copy(&pBssConfig->SSID.ssId,
+		     pProfile->SSIDs.SSIDList->SSID.ssId,
+		     pProfile->SSIDs.SSIDList->SSID.length);
+	pBssConfig->SSID.length = pProfile->SSIDs.SSIDList->SSID.length;
+
+	if (csr_is_nullssid(pBssConfig->SSID.ssId, pBssConfig->SSID.length)) {
+		sme_warn("BSS desc SSID is a wild card");
+		/* Return failed if profile doesn't have an SSID either. */
+		if (pProfile->SSIDs.numOfSSIDs == 0) {
+			sme_warn("BSS desc and profile doesn't have SSID");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	if (WLAN_REG_IS_5GHZ_CH(pBssDesc->channelId))
+		pBssConfig->eBand = BAND_5G;
+	else
+		pBssConfig->eBand = BAND_2G;
+		/* phymode */
+	if (csr_is_phy_mode_match(pMac, pProfile->phyMode, pBssDesc,
+				  pProfile, &cfgDot11Mode, pIes)) {
+		pBssConfig->uCfgDot11Mode = cfgDot11Mode;
+	} else {
+		/*
+		 * No matching phy mode found, force to 11b/g based on INI for
+		 * 2.4Ghz and to 11a mode for 5Ghz
+		 */
+		sme_warn("Can not find match phy mode");
+		if (BAND_2G == pBssConfig->eBand) {
+			if (pMac->roam.configParam.phyMode &
+			    (eCSR_DOT11_MODE_11b | eCSR_DOT11_MODE_11b_ONLY)) {
+				pBssConfig->uCfgDot11Mode =
+						eCSR_CFG_DOT11_MODE_11B;
+			} else {
+				pBssConfig->uCfgDot11Mode =
+						eCSR_CFG_DOT11_MODE_11G;
+			}
+		} else {
+			pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+		}
+	}
+
+	sme_debug("phyMode=%d, uCfgDot11Mode=%d negotiatedAuthType %d",
+		   pProfile->phyMode, pBssConfig->uCfgDot11Mode,
+		   pProfile->negotiatedAuthType);
+
+	/* Qos */
+	if ((pBssConfig->uCfgDot11Mode != eCSR_CFG_DOT11_MODE_11N) &&
+	    (pMac->roam.configParam.WMMSupportMode == eCsrRoamWmmNoQos)) {
+		/*
+		 * Joining BSS is not 11n capable and WMM is disabled on client.
+		 * Disable QoS and WMM
+		 */
+		pBssConfig->qosType = eCSR_MEDIUM_ACCESS_DCF;
+	}
+
+	if (((pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11N)
+	    || (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC))
+		&& ((pBssConfig->qosType != eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP)
+		    || (pBssConfig->qosType != eCSR_MEDIUM_ACCESS_11e_HCF)
+		    || (pBssConfig->qosType != eCSR_MEDIUM_ACCESS_11e_eDCF))) {
+		/* Joining BSS is 11n capable and WMM is disabled on AP. */
+		/* Assume all HT AP's are QOS AP's and enable WMM */
+		pBssConfig->qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP;
+	}
+	/* auth type */
+	switch (pProfile->negotiatedAuthType) {
+	default:
+	case eCSR_AUTH_TYPE_WPA:
+	case eCSR_AUTH_TYPE_WPA_PSK:
+	case eCSR_AUTH_TYPE_WPA_NONE:
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		pBssConfig->authType = eSIR_OPEN_SYSTEM;
+		break;
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		pBssConfig->authType = eSIR_SHARED_KEY;
+		break;
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+		pBssConfig->authType = eSIR_AUTO_SWITCH;
+		break;
+	case eCSR_AUTH_TYPE_SAE:
+		pBssConfig->authType = eSIR_AUTH_TYPE_SAE;
+		break;
+	}
+	/* short slot time */
+	if (eCSR_CFG_DOT11_MODE_11B != cfgDot11Mode)
+		pBssConfig->uShortSlotTime =
+			pMac->roam.configParam.shortSlotTime;
+	else
+		pBssConfig->uShortSlotTime = 0;
+
+	if (pBssConfig->BssCap.ibss)
+		/* We don't support 11h on IBSS */
+		pBssConfig->f11hSupport = false;
+	else
+		pBssConfig->f11hSupport =
+			pMac->roam.configParam.Is11hSupportEnabled;
+	/* power constraint */
+	pBssConfig->uPowerLimit =
+		csr_get11h_power_constraint(pMac, &pIes->PowerConstraints);
+	/* heartbeat */
+	if (CSR_IS_11A_BSS(pBssDesc))
+		pBssConfig->uHeartBeatThresh =
+			pMac->roam.configParam.HeartbeatThresh50;
+	else
+		pBssConfig->uHeartBeatThresh =
+			pMac->roam.configParam.HeartbeatThresh24;
+
+	/*
+	 * Join timeout: if we find a BeaconInterval in the BssDescription,
+	 * then set the Join Timeout to be 10 x the BeaconInterval.
+	 */
+	pBssConfig->uJoinTimeOut = cfg_default(CFG_JOIN_FAILURE_TIMEOUT);
+	if (pBssDesc->beaconInterval) {
+		/* Make sure it is bigger than the minimal */
+		join_timeout = QDF_MAX(10 * pBssDesc->beaconInterval,
+				       cfg_min(CFG_JOIN_FAILURE_TIMEOUT));
+		if (join_timeout < pBssConfig->uJoinTimeOut)
+			pBssConfig->uJoinTimeOut = join_timeout;
+	}
+
+	/* validate CB */
+	if ((pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11N) ||
+	    (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11N_ONLY) ||
+	    (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC) ||
+	    (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC_ONLY) ||
+	    (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AX) ||
+	    (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AX_ONLY))
+		pBssConfig->cbMode = csr_get_cb_mode_from_ies(pMac,
+				pBssDesc->channelId, pIes);
+	else
+		pBssConfig->cbMode = PHY_SINGLE_CHANNEL_CENTERED;
+
+	if (WLAN_REG_IS_24GHZ_CH(pBssDesc->channelId) &&
+	    pProfile->force_24ghz_in_ht20) {
+		pBssConfig->cbMode = PHY_SINGLE_CHANNEL_CENTERED;
+		sme_debug("force_24ghz_in_ht20 is set so set cbmode to 0");
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS csr_roam_prepare_bss_config_from_profile(
+	tpAniSirGlobal pMac, struct csr_roam_profile *pProfile,
+					struct bss_config_param *pBssConfig,
+					tSirBssDescription *pBssDesc)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t operationChannel = 0;
+	uint8_t qAPisEnabled = false;
+	/* SSID */
+	pBssConfig->SSID.length = 0;
+	if (pProfile->SSIDs.numOfSSIDs) {
+		/* only use the first one */
+		qdf_mem_copy(&pBssConfig->SSID,
+			     &pProfile->SSIDs.SSIDList[0].SSID,
+			     sizeof(tSirMacSSid));
+	} else {
+		/* SSID must present */
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Settomg up the capabilities */
+	if (csr_is_bss_type_ibss(pProfile->BSSType))
+		pBssConfig->BssCap.ibss = 1;
+	else
+		pBssConfig->BssCap.ess = 1;
+
+	if (eCSR_ENCRYPT_TYPE_NONE !=
+	    pProfile->EncryptionType.encryptionType[0])
+		pBssConfig->BssCap.privacy = 1;
+
+	pBssConfig->eBand = pMac->mlme_cfg->gen.band;
+	/* phymode */
+	if (pProfile->ChannelInfo.ChannelList)
+		operationChannel = pProfile->ChannelInfo.ChannelList[0];
+	pBssConfig->uCfgDot11Mode = csr_roam_get_phy_mode_band_for_bss(pMac,
+						pProfile, operationChannel,
+						   &pBssConfig->eBand);
+	/* QOS */
+	/* Is this correct to always set to this // *** */
+	if (pBssConfig->BssCap.ess == 1) {
+		/*For Softap case enable WMM */
+		if (CSR_IS_INFRA_AP(pProfile)
+		    && (eCsrRoamWmmNoQos !=
+			pMac->roam.configParam.WMMSupportMode)) {
+			qAPisEnabled = true;
+		} else
+		if (csr_roam_get_qos_info_from_bss(pMac, pBssDesc) ==
+		    QDF_STATUS_SUCCESS) {
+			qAPisEnabled = true;
+		} else {
+			qAPisEnabled = false;
+		}
+	} else {
+		qAPisEnabled = true;
+	}
+	if ((eCsrRoamWmmNoQos != pMac->roam.configParam.WMMSupportMode &&
+	     qAPisEnabled) ||
+	    ((eCSR_CFG_DOT11_MODE_11N == pBssConfig->uCfgDot11Mode &&
+	      qAPisEnabled))) {
+		pBssConfig->qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP;
+	} else {
+		pBssConfig->qosType = eCSR_MEDIUM_ACCESS_DCF;
+	}
+
+	/* auth type */
+	/* Take the preferred Auth type. */
+	switch (pProfile->AuthType.authType[0]) {
+	default:
+	case eCSR_AUTH_TYPE_WPA:
+	case eCSR_AUTH_TYPE_WPA_PSK:
+	case eCSR_AUTH_TYPE_WPA_NONE:
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		pBssConfig->authType = eSIR_OPEN_SYSTEM;
+		break;
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		pBssConfig->authType = eSIR_SHARED_KEY;
+		break;
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+		pBssConfig->authType = eSIR_AUTO_SWITCH;
+		break;
+	case eCSR_AUTH_TYPE_SAE:
+		pBssConfig->authType = eSIR_AUTH_TYPE_SAE;
+		break;
+	}
+	/* short slot time */
+	if (WNI_CFG_PHY_MODE_11B != pBssConfig->uCfgDot11Mode) {
+		pBssConfig->uShortSlotTime =
+			pMac->roam.configParam.shortSlotTime;
+	} else {
+		pBssConfig->uShortSlotTime = 0;
+	}
+	/* power constraint. We don't support 11h on IBSS */
+	pBssConfig->f11hSupport = false;
+	pBssConfig->uPowerLimit = 0;
+	/* heartbeat */
+	if (BAND_5G == pBssConfig->eBand) {
+		pBssConfig->uHeartBeatThresh =
+			pMac->roam.configParam.HeartbeatThresh50;
+	} else {
+		pBssConfig->uHeartBeatThresh =
+			pMac->roam.configParam.HeartbeatThresh24;
+	}
+	/* Join timeout */
+	pBssConfig->uJoinTimeOut = cfg_default(CFG_JOIN_FAILURE_TIMEOUT);
+
+	return status;
+}
+
+static QDF_STATUS csr_roam_get_qos_info_from_bss(tpAniSirGlobal pMac,
+						 tSirBssDescription *pBssDesc)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tDot11fBeaconIEs *pIes = NULL;
+
+	do {
+		if (!QDF_IS_STATUS_SUCCESS(
+			csr_get_parsed_bss_description_ies(
+				pMac, pBssDesc, &pIes))) {
+			sme_err("csr_get_parsed_bss_description_ies() failed");
+			break;
+		}
+		/* check if the AP is QAP & it supports APSD */
+		if (CSR_IS_QOS_BSS(pIes))
+			status = QDF_STATUS_SUCCESS;
+	} while (0);
+
+	if (NULL != pIes)
+		qdf_mem_free(pIes);
+
+	return status;
+}
+
+void csr_set_cfg_privacy(tpAniSirGlobal pMac, struct csr_roam_profile *pProfile,
+			 bool fPrivacy)
+{
+	/*
+	 * the only difference between this function and
+	 * the csr_set_cfg_privacyFromProfile() is the setting of the privacy
+	 * CFG based on the advertised privacy setting from the AP for WPA
+	 * associations. See note below in this function...
+	 */
+	uint32_t privacy_enabled = 0, rsn_enabled = 0, wep_default_key_id = 0;
+	uint32_t WepKeyLength = MLME_WEP_KEY_LENGTH_5;
+	uint32_t Key0Length = 0, Key1Length = 0, Key2Length = 0, Key3Length = 0;
+
+	/* Reserve for the biggest key */
+	uint8_t Key0[MLME_WEP_KEY_LEN_13];
+	uint8_t Key1[MLME_WEP_KEY_LEN_13];
+	uint8_t Key2[MLME_WEP_KEY_LEN_13];
+	uint8_t Key3[MLME_WEP_KEY_LEN_13];
+
+	struct wlan_mlme_wep_cfg *wep_params = &pMac->mlme_cfg->wep_params;
+
+	switch (pProfile->negotiatedUCEncryptionType) {
+	case eCSR_ENCRYPT_TYPE_NONE:
+		/* for NO encryption, turn off Privacy and Rsn. */
+		privacy_enabled = 0;
+		rsn_enabled = 0;
+		/* clear out the WEP keys that may be hanging around. */
+		Key0Length = 0;
+		Key1Length = 0;
+		Key2Length = 0;
+		Key3Length = 0;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP40:
+
+		/* Privacy is ON.  NO RSN for Wep40 static key. */
+		privacy_enabled = 1;
+		rsn_enabled = 0;
+		/* Set the Wep default key ID. */
+		wep_default_key_id = pProfile->Keys.defaultIndex;
+		/* Wep key size if 5 bytes (40 bits). */
+		WepKeyLength = MLME_WEP_KEY_LENGTH_5;
+		/*
+		 * set encryption keys in the CFG database or
+		 * clear those that are not present in this profile.
+		 */
+		if (pProfile->Keys.KeyLength[0]) {
+			qdf_mem_copy(Key0,
+				pProfile->Keys.KeyMaterial[0],
+				MLME_WEP_KEY_LENGTH_5);
+			Key0Length = MLME_WEP_KEY_LENGTH_5;
+		} else {
+			Key0Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[1]) {
+			qdf_mem_copy(Key1,
+				pProfile->Keys.KeyMaterial[1],
+				MLME_WEP_KEY_LENGTH_5);
+			Key1Length = MLME_WEP_KEY_LENGTH_5;
+		} else {
+			Key1Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[2]) {
+			qdf_mem_copy(Key2,
+				pProfile->Keys.KeyMaterial[2],
+				MLME_WEP_KEY_LENGTH_5);
+			Key2Length = MLME_WEP_KEY_LENGTH_5;
+		} else {
+			Key2Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[3]) {
+			qdf_mem_copy(Key3,
+				pProfile->Keys.KeyMaterial[3],
+				MLME_WEP_KEY_LENGTH_5);
+			Key3Length = MLME_WEP_KEY_LENGTH_5;
+		} else {
+			Key3Length = 0;
+		}
+		break;
+
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP104:
+
+		/* Privacy is ON.  NO RSN for Wep40 static key. */
+		privacy_enabled = 1;
+		rsn_enabled = 0;
+		/* Set the Wep default key ID. */
+		wep_default_key_id = pProfile->Keys.defaultIndex;
+		/* Wep key size if 13 bytes (104 bits). */
+		WepKeyLength = MLME_WEP_KEY_LEN_13;
+		/*
+		 * set encryption keys in the CFG database or clear
+		 * those that are not present in this profile.
+		 */
+		if (pProfile->Keys.KeyLength[0]) {
+			qdf_mem_copy(Key0,
+				pProfile->Keys.KeyMaterial[0],
+				MLME_WEP_KEY_LEN_13);
+			Key0Length = MLME_WEP_KEY_LEN_13;
+		} else {
+			Key0Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[1]) {
+			qdf_mem_copy(Key1,
+				pProfile->Keys.KeyMaterial[1],
+				MLME_WEP_KEY_LEN_13);
+			Key1Length = MLME_WEP_KEY_LEN_13;
+		} else {
+			Key1Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[2]) {
+			qdf_mem_copy(Key2,
+				pProfile->Keys.KeyMaterial[2],
+				MLME_WEP_KEY_LEN_13);
+			Key2Length = MLME_WEP_KEY_LEN_13;
+		} else {
+			Key2Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[3]) {
+			qdf_mem_copy(Key3,
+				pProfile->Keys.KeyMaterial[3],
+				MLME_WEP_KEY_LEN_13);
+			Key3Length = MLME_WEP_KEY_LEN_13;
+		} else {
+			Key3Length = 0;
+		}
+		break;
+
+	case eCSR_ENCRYPT_TYPE_TKIP:
+	case eCSR_ENCRYPT_TYPE_AES:
+	case eCSR_ENCRYPT_TYPE_AES_GCMP:
+	case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_ENCRYPT_TYPE_WPI:
+#endif /* FEATURE_WLAN_WAPI */
+		/*
+		 * this is the only difference between this function and
+		 * the csr_set_cfg_privacyFromProfile().
+		 * (setting of the privacy CFG based on the advertised
+		 *  privacy setting from AP for WPA/WAPI associations).
+		 */
+		privacy_enabled = (0 != fPrivacy);
+		/* turn on RSN enabled for WPA associations */
+		rsn_enabled = 1;
+		/* clear static WEP keys that may be hanging around. */
+		Key0Length = 0;
+		Key1Length = 0;
+		Key2Length = 0;
+		Key3Length = 0;
+		break;
+	default:
+		privacy_enabled = 0;
+		rsn_enabled = 0;
+		break;
+	}
+
+	pMac->mlme_cfg->wep_params.is_privacy_enabled = privacy_enabled;
+	pMac->mlme_cfg->feature_flags.enable_rsn = rsn_enabled;
+	mlme_set_wep_key(wep_params, MLME_WEP_DEFAULT_KEY_1, Key0, Key0Length);
+	mlme_set_wep_key(wep_params, MLME_WEP_DEFAULT_KEY_2, Key1, Key1Length);
+	mlme_set_wep_key(wep_params, MLME_WEP_DEFAULT_KEY_3, Key2, Key2Length);
+	mlme_set_wep_key(wep_params, MLME_WEP_DEFAULT_KEY_4, Key3, Key3Length);
+	pMac->mlme_cfg->wep_params.wep_default_key_id = wep_default_key_id;
+}
+
+static void csr_set_cfg_ssid(tpAniSirGlobal pMac, tSirMacSSid *pSSID)
+{
+	uint32_t len = 0;
+
+	if (pSSID->length <= WNI_CFG_SSID_LEN)
+		len = pSSID->length;
+	cfg_set_str(pMac, WNI_CFG_SSID, (uint8_t *) pSSID->ssId, len);
+}
+
+static QDF_STATUS csr_set_qos_to_cfg(tpAniSirGlobal pMac, uint32_t sessionId,
+				     eCsrMediaAccessType qosType)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t QoSEnabled;
+	uint32_t WmeEnabled;
+	/* set the CFG enable/disable variables based on the
+	 * qosType being configured.
+	 */
+	switch (qosType) {
+	case eCSR_MEDIUM_ACCESS_WMM_eDCF_802dot1p:
+		QoSEnabled = false;
+		WmeEnabled = true;
+		break;
+	case eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP:
+		QoSEnabled = false;
+		WmeEnabled = true;
+		break;
+	case eCSR_MEDIUM_ACCESS_WMM_eDCF_NoClassify:
+		QoSEnabled = false;
+		WmeEnabled = true;
+		break;
+	case eCSR_MEDIUM_ACCESS_11e_eDCF:
+		QoSEnabled = true;
+		WmeEnabled = false;
+		break;
+	case eCSR_MEDIUM_ACCESS_11e_HCF:
+		QoSEnabled = true;
+		WmeEnabled = false;
+		break;
+	default:
+	case eCSR_MEDIUM_ACCESS_DCF:
+		QoSEnabled = false;
+		WmeEnabled = false;
+		break;
+	}
+	/* save the WMM setting for later use */
+	pMac->roam.roamSession[sessionId].fWMMConnection = (bool) WmeEnabled;
+	pMac->roam.roamSession[sessionId].fQOSConnection = (bool) QoSEnabled;
+	return status;
+}
+
+static QDF_STATUS csr_get_rate_set(tpAniSirGlobal pMac,
+				   struct csr_roam_profile *pProfile,
+				   eCsrPhyMode phyMode,
+				   tSirBssDescription *pBssDesc,
+				   tDot11fBeaconIEs *pIes,
+				   tSirMacRateSet *pOpRateSet,
+				   tSirMacRateSet *pExRateSet)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	int i;
+	enum csr_cfgdot11mode cfgDot11Mode;
+	uint8_t *pDstRate;
+	uint16_t rateBitmap = 0;
+
+	qdf_mem_set(pOpRateSet, sizeof(tSirMacRateSet), 0);
+	qdf_mem_set(pExRateSet, sizeof(tSirMacRateSet), 0);
+	QDF_ASSERT(pIes != NULL);
+
+	if (NULL == pIes) {
+		sme_err("failed to parse BssDesc");
+		return status;
+	}
+
+	csr_is_phy_mode_match(pMac, phyMode, pBssDesc, pProfile,
+			      &cfgDot11Mode, pIes);
+	/*
+	 * Originally, we thought that for 11a networks, the 11a rates
+	 * are always in the Operational Rate set & for 11b and 11g
+	 * networks, the 11b rates appear in the Operational Rate set.
+	 * Consequently, in either case, we would blindly put the rates
+	 * we support into our Operational Rate set.
+	 * (including the basic rates, which we've already verified are
+	 * supported earlier in the roaming decision).
+	 * However, it turns out that this is not always the case.
+	 * Some AP's (e.g. D-Link DI-784) ram 11g rates into the
+	 * Operational Rate set too.  Now, we're a little more careful.
+	 */
+	pDstRate = pOpRateSet->rate;
+	if (pIes->SuppRates.present) {
+		for (i = 0; i < pIes->SuppRates.num_rates; i++) {
+			if (csr_rates_is_dot11_rate_supported(pMac,
+				pIes->SuppRates.rates[i]) &&
+				!csr_check_rate_bitmap(
+					pIes->SuppRates.rates[i],
+					rateBitmap)) {
+				csr_add_rate_bitmap(pIes->SuppRates.
+						    rates[i], &rateBitmap);
+				*pDstRate++ = pIes->SuppRates.rates[i];
+				pOpRateSet->numRates++;
+			}
+		}
+	}
+	/*
+	 * If there are Extended Rates in the beacon, we will reflect the
+	 * extended rates that we support in our Extended Operational Rate
+	 * set.
+	 */
+	if (pIes->ExtSuppRates.present) {
+		pDstRate = pExRateSet->rate;
+		for (i = 0; i < pIes->ExtSuppRates.num_rates; i++) {
+			if (csr_rates_is_dot11_rate_supported(pMac,
+				pIes->ExtSuppRates.rates[i]) &&
+				!csr_check_rate_bitmap(
+					pIes->ExtSuppRates.rates[i],
+					rateBitmap)) {
+				*pDstRate++ = pIes->ExtSuppRates.rates[i];
+				pExRateSet->numRates++;
+			}
+		}
+	}
+	if (pOpRateSet->numRates > 0 || pExRateSet->numRates > 0)
+		status = QDF_STATUS_SUCCESS;
+	return status;
+}
+
+static void csr_set_cfg_rate_set(tpAniSirGlobal pMac, eCsrPhyMode phyMode,
+				 struct csr_roam_profile *pProfile,
+				 tSirBssDescription *pBssDesc,
+				 tDot11fBeaconIEs *pIes)
+{
+	int i;
+	uint8_t *pDstRate;
+	enum csr_cfgdot11mode cfgDot11Mode;
+	/* leave enough room for the max number of rates */
+	uint8_t OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
+	qdf_size_t OperationalRatesLength = 0;
+	/* leave enough room for the max number of rates */
+	uint8_t ExtendedOperationalRates
+				[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
+	qdf_size_t ExtendedOperationalRatesLength = 0;
+	uint8_t MCSRateIdxSet[SIZE_OF_SUPPORTED_MCS_SET];
+	qdf_size_t MCSRateLength = 0;
+
+	QDF_ASSERT(pIes != NULL);
+	if (NULL != pIes) {
+		csr_is_phy_mode_match(pMac, phyMode, pBssDesc, pProfile,
+				      &cfgDot11Mode, pIes);
+		/* Originally, we thought that for 11a networks, the 11a rates
+		 * are always in the Operational Rate set & for 11b and 11g
+		 * networks, the 11b rates appear in the Operational Rate set.
+		 * Consequently, in either case, we would blindly put the rates
+		 * we support into our Operational Rate set (including the basic
+		 * rates, which we have already verified are supported earlier
+		 * in the roaming decision). However, it turns out that this is
+		 * not always the case.  Some AP's (e.g. D-Link DI-784) ram 11g
+		 * rates into the Operational Rate set, too.  Now, we're a
+		 * little more careful:
+		 */
+		pDstRate = OperationalRates;
+		if (pIes->SuppRates.present) {
+			for (i = 0; i < pIes->SuppRates.num_rates; i++) {
+				if (csr_rates_is_dot11_rate_supported
+					    (pMac, pIes->SuppRates.rates[i])
+				    && (OperationalRatesLength <
+					CSR_DOT11_SUPPORTED_RATES_MAX)) {
+					*pDstRate++ = pIes->SuppRates.rates[i];
+					OperationalRatesLength++;
+				}
+			}
+		}
+		if (eCSR_CFG_DOT11_MODE_11G == cfgDot11Mode ||
+		    eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode ||
+		    eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode) {
+			/* If there are Extended Rates in the beacon, we will
+			 * reflect those extended rates that we support in out
+			 * Extended Operational Rate set:
+			 */
+			pDstRate = ExtendedOperationalRates;
+			if (pIes->ExtSuppRates.present) {
+				for (i = 0; i < pIes->ExtSuppRates.num_rates;
+				     i++) {
+					if (csr_rates_is_dot11_rate_supported
+						    (pMac, pIes->ExtSuppRates.
+							rates[i])
+					    && (ExtendedOperationalRatesLength <
+						CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX)) {
+						*pDstRate++ =
+							pIes->ExtSuppRates.
+							rates[i];
+						ExtendedOperationalRatesLength++;
+					}
+				}
+			}
+		}
+		/* Enable proprietary MAC features if peer node is Airgo node
+		 * and STA user wants to use them For ANI network companions,
+		 * we need to populate the proprietary rate set with any
+		 * proprietary rates we found in the beacon, only if user allows
+		 * them.
+		 */
+		/* No proprietary modes... */
+		/* Get MCS Rate */
+		pDstRate = MCSRateIdxSet;
+		if (pIes->HTCaps.present) {
+			for (i = 0; i < VALID_MAX_MCS_INDEX; i++) {
+				if ((unsigned int)pIes->HTCaps.
+				    supportedMCSSet[0] & (1 << i)) {
+					MCSRateLength++;
+					*pDstRate++ = i;
+				}
+			}
+		}
+		/* Set the operational rate set CFG variables... */
+		wlan_mlme_set_cfg_str(OperationalRates,
+				      &pMac->mlme_cfg->rates.opr_rate_set,
+				      OperationalRatesLength);
+		wlan_mlme_set_cfg_str(ExtendedOperationalRates,
+				      &pMac->mlme_cfg->rates.ext_opr_rate_set,
+				      ExtendedOperationalRatesLength);
+		wlan_mlme_set_cfg_str(MCSRateIdxSet,
+				      &pMac->mlme_cfg->rates.current_mcs_set,
+				      MCSRateLength);
+	} /* Parsing BSSDesc */
+	else
+		sme_err("failed to parse BssDesc");
+}
+
+static void csr_set_cfg_rate_set_from_profile(tpAniSirGlobal pMac,
+					      struct csr_roam_profile *pProfile)
+{
+	tSirMacRateSetIE DefaultSupportedRates11a = { SIR_MAC_RATESET_EID,
+						      {8,
+						       {SIR_MAC_RATE_6,
+							SIR_MAC_RATE_9,
+							SIR_MAC_RATE_12,
+							SIR_MAC_RATE_18,
+							SIR_MAC_RATE_24,
+							SIR_MAC_RATE_36,
+							SIR_MAC_RATE_48,
+							SIR_MAC_RATE_54} } };
+	tSirMacRateSetIE DefaultSupportedRates11b = { SIR_MAC_RATESET_EID,
+						      {4,
+						       {SIR_MAC_RATE_1,
+							SIR_MAC_RATE_2,
+							SIR_MAC_RATE_5_5,
+							SIR_MAC_RATE_11} } };
+	enum csr_cfgdot11mode cfgDot11Mode;
+	enum band_info eBand;
+	/* leave enough room for the max number of rates */
+	uint8_t OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
+	qdf_size_t OperationalRatesLength = 0;
+	/* leave enough room for the max number of rates */
+	uint8_t ExtendedOperationalRates
+				[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
+	qdf_size_t ExtendedOperationalRatesLength = 0;
+	uint8_t operationChannel = 0;
+
+	if (pProfile->ChannelInfo.ChannelList)
+		operationChannel = pProfile->ChannelInfo.ChannelList[0];
+	cfgDot11Mode = csr_roam_get_phy_mode_band_for_bss(pMac, pProfile,
+							operationChannel,
+							&eBand);
+	/* For 11a networks, the 11a rates go into the Operational Rate set.
+	 * For 11b and 11g networks, the 11b rates appear in the Operational
+	 * Rate set. In either case, we can blindly put the rates we support
+	 * into our Operational Rate set (including the basic rates, which we
+	 * have already verified are supported earlier in the roaming decision).
+	 */
+	if (BAND_5G == eBand) {
+		/* 11a rates into the Operational Rate Set. */
+		OperationalRatesLength =
+			DefaultSupportedRates11a.supportedRateSet.numRates *
+			sizeof(*DefaultSupportedRates11a.supportedRateSet.rate);
+		qdf_mem_copy(OperationalRates,
+			     DefaultSupportedRates11a.supportedRateSet.rate,
+			     OperationalRatesLength);
+
+		/* Nothing in the Extended rate set. */
+		ExtendedOperationalRatesLength = 0;
+	} else if (eCSR_CFG_DOT11_MODE_11B == cfgDot11Mode) {
+		/* 11b rates into the Operational Rate Set. */
+		OperationalRatesLength =
+			DefaultSupportedRates11b.supportedRateSet.numRates *
+			sizeof(*DefaultSupportedRates11b.supportedRateSet.rate);
+		qdf_mem_copy(OperationalRates,
+			     DefaultSupportedRates11b.supportedRateSet.rate,
+			     OperationalRatesLength);
+		/* Nothing in the Extended rate set. */
+		ExtendedOperationalRatesLength = 0;
+	} else {
+		/* 11G */
+
+		/* 11b rates into the Operational Rate Set. */
+		OperationalRatesLength =
+			DefaultSupportedRates11b.supportedRateSet.numRates *
+			sizeof(*DefaultSupportedRates11b.supportedRateSet.rate);
+		qdf_mem_copy(OperationalRates,
+			     DefaultSupportedRates11b.supportedRateSet.rate,
+			     OperationalRatesLength);
+
+		/* 11a rates go in the Extended rate set. */
+		ExtendedOperationalRatesLength =
+			DefaultSupportedRates11a.supportedRateSet.numRates *
+			sizeof(*DefaultSupportedRates11a.supportedRateSet.rate);
+		qdf_mem_copy(ExtendedOperationalRates,
+			     DefaultSupportedRates11a.supportedRateSet.rate,
+			     ExtendedOperationalRatesLength);
+	}
+
+	/* Set the operational rate set CFG variables... */
+	wlan_mlme_set_cfg_str(OperationalRates,
+			      &pMac->mlme_cfg->rates.opr_rate_set,
+			      OperationalRatesLength);
+	wlan_mlme_set_cfg_str(ExtendedOperationalRates,
+			      &pMac->mlme_cfg->rates.ext_opr_rate_set,
+			      ExtendedOperationalRatesLength);
+}
+
+static void csr_roam_ccm_cfg_set_callback(tpAniSirGlobal pMac,
+					  uint8_t session_id)
+{
+	tListElem *pEntry =
+		csr_nonscan_active_ll_peek_head(pMac, LL_ACCESS_LOCK);
+	uint32_t sessionId;
+	tSmeCmd *pCommand = NULL;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	struct csr_roam_session *pSession = NULL;
+#endif
+	if (NULL == pEntry) {
+		sme_err("CFG_CNF with active list empty");
+		return;
+	}
+	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+	sessionId = pCommand->sessionId;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	pSession = &pMac->roam.roamSession[sessionId];
+	if (pSession->roam_synch_in_progress) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "LFR3:csr_roam_cfg_set_callback");
+	}
+#endif
+
+	if (CSR_IS_ROAM_JOINING(pMac, sessionId)
+	    && CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId)) {
+		csr_roaming_state_config_cnf_processor(pMac, pCommand,
+						       session_id);
+	}
+}
+
+/* pIes may be NULL */
+QDF_STATUS csr_roam_set_bss_config_cfg(tpAniSirGlobal pMac, uint32_t sessionId,
+				       struct csr_roam_profile *pProfile,
+				       tSirBssDescription *pBssDesc,
+				       struct bss_config_param *pBssConfig,
+				       struct sDot11fBeaconIEs *pIes,
+				       bool resetCountry)
+{
+	uint32_t cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+	uint8_t channel = 0;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Make sure we have the domain info for the BSS we try to connect to.
+	 * Do we need to worry about sequence for OSs that are not Windows??
+	 */
+	if (pBssDesc) {
+		if ((QDF_SAP_MODE !=
+			csr_get_session_persona(pMac, sessionId)) &&
+			csr_learn_11dcountry_information(
+					pMac, pBssDesc, pIes, true)) {
+			csr_apply_country_information(pMac);
+		}
+		if ((wlan_reg_11d_enabled_on_host(pMac->psoc)) && pIes) {
+			if (!pIes->Country.present)
+				csr_apply_channel_power_info_wrapper(pMac);
+		}
+	}
+	/* Qos */
+	csr_set_qos_to_cfg(pMac, sessionId, pBssConfig->qosType);
+	/* SSID */
+	csr_set_cfg_ssid(pMac, &pBssConfig->SSID);
+
+	/* Auth type */
+	pMac->mlme_cfg->wep_params.auth_type = pBssConfig->authType;
+
+	/* encryption type */
+	csr_set_cfg_privacy(pMac, pProfile, (bool) pBssConfig->BssCap.privacy);
+	/* short slot time */
+	pMac->mlme_cfg->feature_flags.enable_short_slot_time_11g =
+						pBssConfig->uShortSlotTime;
+	/* 11d */
+	cfg_set_int(pMac, WNI_CFG_11D_ENABLED,
+			((pBssConfig->f11hSupport) ? pBssConfig->f11hSupport :
+			 pProfile->ieee80211d));
+	cfg_set_int(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT,
+			pBssConfig->uPowerLimit);
+	/* CB */
+
+	if (CSR_IS_INFRA_AP(pProfile) || CSR_IS_IBSS(pProfile))
+		channel = pProfile->operationChannel;
+	else if (pBssDesc)
+		channel = pBssDesc->channelId;
+	if (0 != channel) {
+		/* for now if we are on 2.4 Ghz, CB will be always disabled */
+		if (WLAN_REG_IS_24GHZ_CH(channel))
+			cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+		else
+			cfgCb = pBssConfig->cbMode;
+	}
+	/* Rate */
+	/* Fixed Rate */
+	if (pBssDesc)
+		csr_set_cfg_rate_set(pMac, (eCsrPhyMode) pProfile->phyMode,
+				     pProfile, pBssDesc, pIes);
+	else
+		csr_set_cfg_rate_set_from_profile(pMac, pProfile);
+
+	pMac->mlme_cfg->timeouts.join_failure_timeout =
+		pBssConfig->uJoinTimeOut;
+	/* Any roaming related changes should be above this line */
+	if (pSession && pSession->roam_synch_in_progress) {
+		sme_debug("Roam synch is in progress Session_id: %d",
+			  sessionId);
+		return QDF_STATUS_SUCCESS;
+	}
+	/* Make this the last CFG to set. The callback will trigger a
+	 * join_req Join time out
+	 */
+	csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_CONFIG, sessionId);
+
+	csr_roam_ccm_cfg_set_callback(pMac, sessionId);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static
+QDF_STATUS csr_roam_stop_network(tpAniSirGlobal pMac, uint32_t sessionId,
+				 struct csr_roam_profile *pProfile,
+				 tSirBssDescription *pBssDesc,
+				 tDot11fBeaconIEs *pIes)
+{
+	QDF_STATUS status;
+	struct bss_config_param *pBssConfig;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pBssConfig = qdf_mem_malloc(sizeof(struct bss_config_param));
+	if (NULL == pBssConfig)
+		return QDF_STATUS_E_NOMEM;
+
+	sme_debug("session id: %d", sessionId);
+
+	status = csr_roam_prepare_bss_config(pMac, pProfile, pBssDesc,
+			pBssConfig, pIes);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		enum csr_roam_substate substate;
+
+		substate = eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING;
+		pSession->bssParams.uCfgDot11Mode = pBssConfig->uCfgDot11Mode;
+		/* This will allow to pass cbMode during join req */
+		pSession->bssParams.cbMode = pBssConfig->cbMode;
+		/* For IBSS, we need to prepare some more information */
+		if (csr_is_bss_type_ibss(pProfile->BSSType) ||
+				CSR_IS_INFRA_AP(pProfile))
+			csr_roam_prepare_bss_params(pMac, sessionId, pProfile,
+				pBssDesc, pBssConfig, pIes);
+
+		/*
+		 * If we are in an IBSS, then stop the IBSS...
+		 * Not worry about WDS connection for now
+		 */
+		if (csr_is_conn_state_ibss(pMac, sessionId)) {
+			status = csr_roam_issue_stop_bss(pMac, sessionId,
+					substate);
+		} else if (csr_is_conn_state_infra(pMac, sessionId)) {
+			/*
+			 * the new Bss is an Ibss OR we are roaming from
+			 * Infra to Infra across SSIDs
+			 * (roaming to a new SSID)...
+			 * Not worry about WDS connection for now
+			 */
+			if (pBssDesc && (csr_is_ibss_bss_desc(pBssDesc) ||
+				!csr_is_ssid_equal(pMac,
+					pSession->pConnectBssDesc,
+					pBssDesc, pIes)))
+				status = csr_roam_issue_disassociate(pMac,
+						sessionId, substate, false);
+			else if (pBssDesc)
+				/*
+				 * In an infra & going to an infra network with
+				 * the same SSID.  This calls for a reassoc seq.
+				 * So issue the CFG sets for this new AP. Set
+				 * parameters for this Bss.
+				 */
+				status = csr_roam_set_bss_config_cfg(pMac,
+						sessionId, pProfile, pBssDesc,
+						pBssConfig, pIes, false);
+		} else if (pBssDesc ||
+					CSR_IS_INFRA_AP(pProfile)) {
+			/*
+			 * Neither in IBSS nor in Infra. We can go ahead and set
+			 * the cfg for tne new network... nothing to stop.
+			 */
+			bool is11rRoamingFlag = false;
+
+			is11rRoamingFlag = csr_roam_is11r_assoc(pMac,
+							sessionId);
+			/* Set parameters for this Bss. */
+			status = csr_roam_set_bss_config_cfg(pMac, sessionId,
+					pProfile, pBssDesc, pBssConfig, pIes,
+					is11rRoamingFlag);
+		}
+	} /* Success getting BSS config info */
+	qdf_mem_free(pBssConfig);
+	return status;
+}
+
+/**
+ * csr_roam_state_for_same_profile() - Determine roam state for same profile
+ * @mac_ctx: pointer to mac context
+ * @profile: Roam profile
+ * @session: Roam session
+ * @session_id: session id
+ * @ies_local: local ies
+ * @bss_descr: bss description
+ *
+ * This function will determine the roam state for same profile
+ *
+ * Return: Roaming state.
+ */
+static enum csr_join_state csr_roam_state_for_same_profile(
+	tpAniSirGlobal mac_ctx, struct csr_roam_profile *profile,
+			struct csr_roam_session *session,
+			uint32_t session_id, tDot11fBeaconIEs *ies_local,
+			tSirBssDescription *bss_descr)
+{
+	QDF_STATUS status;
+	struct bss_config_param bssConfig;
+
+	if (csr_roam_is_same_profile_keys(mac_ctx, &session->connectedProfile,
+				profile))
+		return eCsrReassocToSelfNoCapChange;
+	/* The key changes */
+	qdf_mem_set(&bssConfig, sizeof(bssConfig), 0);
+	status = csr_roam_prepare_bss_config(mac_ctx, profile, bss_descr,
+				&bssConfig, ies_local);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		session->bssParams.uCfgDot11Mode =
+				bssConfig.uCfgDot11Mode;
+		session->bssParams.cbMode =
+				bssConfig.cbMode;
+		/* reapply the cfg including keys so reassoc happens. */
+		status = csr_roam_set_bss_config_cfg(mac_ctx, session_id,
+				profile, bss_descr, &bssConfig,
+				ies_local, false);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			return eCsrContinueRoaming;
+	}
+
+	return eCsrStopRoaming;
+
+}
+
+static enum csr_join_state csr_roam_join(tpAniSirGlobal pMac,
+	uint32_t sessionId, tCsrScanResultInfo *pScanResult,
+				   struct csr_roam_profile *pProfile)
+{
+	enum csr_join_state eRoamState = eCsrContinueRoaming;
+	tSirBssDescription *pBssDesc = &pScanResult->BssDescriptor;
+	tDot11fBeaconIEs *pIesLocal = (tDot11fBeaconIEs *) (pScanResult->pvIes);
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return eCsrStopRoaming;
+	}
+
+	if (!pIesLocal &&
+		!QDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies(pMac,
+				pBssDesc, &pIesLocal))) {
+		sme_err("fail to parse IEs");
+		return eCsrStopRoaming;
+	}
+	if (csr_is_infra_bss_desc(pBssDesc)) {
+		/*
+		 * If we are connected in infra mode and the join bss descr is
+		 * for the same BssID, then we are attempting to join the AP we
+		 * are already connected with.  In that case, see if the Bss or
+		 * sta capabilities have changed and handle the changes
+		 * without disturbing the current association
+		 */
+
+		if (csr_is_conn_state_connected_infra(pMac, sessionId) &&
+			csr_is_bss_id_equal(pBssDesc,
+					    pSession->pConnectBssDesc) &&
+			csr_is_ssid_equal(pMac, pSession->pConnectBssDesc,
+				pBssDesc, pIesLocal)) {
+			/*
+			 * Check to see if the Auth type has changed in the
+			 * profile.  If so, we don't want to reassociate with
+			 * authenticating first.  To force this, stop the
+			 * current association (Disassociate) and then re 'Join'
+			 * the AP, wihch will force an Authentication (with the
+			 * new Auth type) followed by a new Association.
+			 */
+			if (csr_is_same_profile(pMac,
+				&pSession->connectedProfile, pProfile)) {
+				sme_warn("detect same profile");
+				eRoamState =
+					csr_roam_state_for_same_profile(pMac,
+						pProfile, pSession, sessionId,
+						pIesLocal, pBssDesc);
+			} else if (!QDF_IS_STATUS_SUCCESS(
+						csr_roam_issue_disassociate(
+						pMac,
+						sessionId,
+						eCSR_ROAM_SUBSTATE_DISASSOC_REQ,
+						false))) {
+				sme_err("fail disassoc session %d",
+						sessionId);
+				eRoamState = eCsrStopRoaming;
+			}
+		} else if (!QDF_IS_STATUS_SUCCESS(csr_roam_stop_network(pMac,
+				sessionId, pProfile, pBssDesc, pIesLocal)))
+			/* we used to pre-auth here with open auth
+			 * networks but that wasn't working so well.
+			 * stop the existing network before attempting
+			 * to join the new network.
+			 */
+			eRoamState = eCsrStopRoaming;
+	} else if (!QDF_IS_STATUS_SUCCESS(csr_roam_stop_network(pMac, sessionId,
+						pProfile, pBssDesc,
+						pIesLocal)))
+		eRoamState = eCsrStopRoaming;
+
+	if (pIesLocal && !pScanResult->pvIes)
+		qdf_mem_free(pIesLocal);
+	return eRoamState;
+}
+
+static
+QDF_STATUS csr_roam_should_roam(tpAniSirGlobal pMac, uint32_t sessionId,
+				tSirBssDescription *pBssDesc, uint32_t roamId)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_info roamInfo;
+
+	qdf_mem_set(&roamInfo, sizeof(struct csr_roam_info), 0);
+	roamInfo.pBssDesc = pBssDesc;
+	status = csr_roam_call_callback(pMac, sessionId, &roamInfo, roamId,
+				eCSR_ROAM_SHOULD_ROAM, eCSR_ROAM_RESULT_NONE);
+	return status;
+}
+
+/* In case no matching BSS is found, use whatever default we can find */
+static void csr_roam_assign_default_param(tpAniSirGlobal pMac,
+					tSmeCmd *pCommand)
+{
+	/* Need to get all negotiated types in place first */
+	/* auth type */
+	/* Take the preferred Auth type. */
+	switch (pCommand->u.roamCmd.roamProfile.AuthType.authType[0]) {
+	default:
+	case eCSR_AUTH_TYPE_WPA:
+	case eCSR_AUTH_TYPE_WPA_PSK:
+	case eCSR_AUTH_TYPE_WPA_NONE:
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
+			eCSR_AUTH_TYPE_OPEN_SYSTEM;
+		break;
+
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
+			eCSR_AUTH_TYPE_SHARED_KEY;
+		break;
+
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+		pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
+			eCSR_AUTH_TYPE_AUTOSWITCH;
+		break;
+
+	case eCSR_AUTH_TYPE_SAE:
+		pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
+			eCSR_AUTH_TYPE_SAE;
+		break;
+	}
+	pCommand->u.roamCmd.roamProfile.negotiatedUCEncryptionType =
+		pCommand->u.roamCmd.roamProfile.EncryptionType.
+		encryptionType[0];
+	/* In this case, the multicast encryption needs to follow the
+	 * uncast ones.
+	 */
+	pCommand->u.roamCmd.roamProfile.negotiatedMCEncryptionType =
+		pCommand->u.roamCmd.roamProfile.EncryptionType.
+		encryptionType[0];
+}
+
+/**
+ * csr_roam_select_bss() - Handle join scenario based on profile
+ * @mac_ctx:             Global MAC Context
+ * @roam_bss_entry:      The next BSS to join
+ * @csr_result_info:     Result of join
+ * @csr_scan_result:     Global scan result
+ * @session_id:          SME Session ID
+ * @roam_id:             Roaming ID
+ * @roam_state:          Current roaming state
+ * @bss_list:            BSS List
+ *
+ * Return: true if the entire BSS list is done, false otherwise.
+ */
+static bool csr_roam_select_bss(tpAniSirGlobal mac_ctx,
+		tListElem *roam_bss_entry, tCsrScanResultInfo **csr_result_info,
+		struct tag_csrscan_result **csr_scan_result,
+		uint32_t session_id, uint32_t roam_id,
+		enum csr_join_state *roam_state,
+		struct scan_result_list *bss_list)
+{
+	uint8_t conc_channel = 0;
+	bool status = false;
+	struct tag_csrscan_result *scan_result = NULL;
+	tCsrScanResultInfo *result = NULL;
+
+	while (roam_bss_entry) {
+		scan_result = GET_BASE_ADDR(roam_bss_entry, struct
+				tag_csrscan_result, Link);
+		/*
+		 * If concurrency enabled take the
+		 * concurrent connected channel first.
+		 * Valid multichannel concurrent
+		 * sessions exempted
+		 */
+		result = &scan_result->Result;
+		if (policy_mgr_concurrent_open_sessions_running(mac_ctx->psoc)
+			&& !csr_is_valid_mc_concurrent_session(mac_ctx,
+					session_id, &result->BssDescriptor)) {
+			conc_channel = csr_get_concurrent_operation_channel(
+					mac_ctx);
+			sme_debug("csr Conc Channel: %d", conc_channel);
+			if ((conc_channel) && (conc_channel ==
+				result->BssDescriptor.channelId)) {
+				/*
+				 * make this 0 because we do not want the below
+				 * check to pass as we don't want to connect on
+				 * other channel
+				 */
+				sme_debug("Conc chnl match: %d", conc_channel);
+				conc_channel = 0;
+			}
+		}
+
+		/* Ok to roam this */
+		if (!conc_channel &&
+			QDF_IS_STATUS_SUCCESS(csr_roam_should_roam(mac_ctx,
+				session_id, &result->BssDescriptor, roam_id))) {
+			status = false;
+			break;
+		}
+		*roam_state = eCsrStopRoamingDueToConcurrency;
+		status = true;
+		roam_bss_entry = csr_ll_next(&bss_list->List, roam_bss_entry,
+					LL_ACCESS_LOCK);
+	}
+	*csr_result_info = result;
+	*csr_scan_result = scan_result;
+	return status;
+}
+
+/**
+ * csr_roam_join_handle_profile() - Handle join scenario based on profile
+ * @mac_ctx:             Global MAC Context
+ * @session_id:          SME Session ID
+ * @cmd:                 Command
+ * @roam_info_ptr:       Pointed to the roaming info for join
+ * @roam_state:          Current roaming state
+ * @result:              Result of join
+ * @scan_result:         Global scan result
+ *
+ * Return: None
+ */
+static void csr_roam_join_handle_profile(tpAniSirGlobal mac_ctx,
+		uint32_t session_id, tSmeCmd *cmd,
+		struct csr_roam_info *roam_info_ptr,
+		enum csr_join_state *roam_state, tCsrScanResultInfo *result,
+		struct tag_csrscan_result *scan_result)
+{
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	uint8_t acm_mask = 0;
+#endif
+	QDF_STATUS status;
+	struct csr_roam_session *session;
+	struct csr_roam_profile *profile = &cmd->u.roamCmd.roamProfile;
+	tDot11fBeaconIEs *ies_local = NULL;
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("Invalid session id %d", session_id);
+		return;
+	}
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	/*
+	 * We have something to roam, tell HDD when it is infra.
+	 * For IBSS, the indication goes back to HDD via eCSR_ROAM_IBSS_IND
+	 */
+	if (CSR_IS_INFRASTRUCTURE(profile) && roam_info_ptr) {
+		if (session->bRefAssocStartCnt) {
+			session->bRefAssocStartCnt--;
+			roam_info_ptr->pProfile = profile;
+			/*
+			 * Complete the last assoc attempt as a
+			 * new one is about to be tried
+			 */
+			csr_roam_call_callback(mac_ctx, session_id,
+				roam_info_ptr, cmd->u.roamCmd.roamId,
+				eCSR_ROAM_ASSOCIATION_COMPLETION,
+				eCSR_ROAM_RESULT_NOT_ASSOCIATED);
+		}
+
+		qdf_mem_set(roam_info_ptr, sizeof(struct csr_roam_info), 0);
+		if (!scan_result)
+			cmd->u.roamCmd.roamProfile.uapsd_mask = 0;
+		else
+			ies_local = scan_result->Result.pvIes;
+
+		if (!result) {
+			sme_err(" cannot parse IEs");
+			*roam_state = eCsrStopRoaming;
+			return;
+		} else if (scan_result && !ies_local &&
+				(!QDF_IS_STATUS_SUCCESS(
+					csr_get_parsed_bss_description_ies(
+						mac_ctx, &result->BssDescriptor,
+						&ies_local)))) {
+			sme_err(" cannot parse IEs");
+			*roam_state = eCsrStopRoaming;
+			return;
+		}
+		roam_info_ptr->pBssDesc = &result->BssDescriptor;
+		cmd->u.roamCmd.pLastRoamBss = roam_info_ptr->pBssDesc;
+		/* dont put uapsd_mask if BSS doesn't support uAPSD */
+		if (scan_result && cmd->u.roamCmd.roamProfile.uapsd_mask
+				&& CSR_IS_QOS_BSS(ies_local)
+				&& CSR_IS_UAPSD_BSS(ies_local)) {
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+			acm_mask = sme_qos_get_acm_mask(mac_ctx,
+					&result->BssDescriptor, ies_local);
+#endif /* WLAN_MDM_CODE_REDUCTION_OPT */
+		} else {
+			cmd->u.roamCmd.roamProfile.uapsd_mask = 0;
+		}
+		if (ies_local && !scan_result->Result.pvIes)
+			qdf_mem_free(ies_local);
+		roam_info_ptr->pProfile = profile;
+		session->bRefAssocStartCnt++;
+		csr_roam_call_callback(mac_ctx, session_id, roam_info_ptr,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_ASSOCIATION_START,
+			eCSR_ROAM_RESULT_NONE);
+	}
+	if (NULL != cmd->u.roamCmd.pRoamBssEntry) {
+		/*
+		 * We have BSS
+		 * Need to assign these value because
+		 * they are used in csr_is_same_profile
+		 */
+		scan_result = GET_BASE_ADDR(cmd->u.roamCmd.pRoamBssEntry,
+				struct tag_csrscan_result, Link);
+		/*
+		 * The OSEN IE doesn't provide the cipher suite.Therefore set
+		 * to constant value of AES
+		 */
+		if (cmd->u.roamCmd.roamProfile.bOSENAssociation) {
+			cmd->u.roamCmd.roamProfile.negotiatedUCEncryptionType =
+				eCSR_ENCRYPT_TYPE_AES;
+			cmd->u.roamCmd.roamProfile.negotiatedMCEncryptionType =
+				eCSR_ENCRYPT_TYPE_AES;
+		} else {
+			/* Negotiated while building scan result. */
+			cmd->u.roamCmd.roamProfile.negotiatedUCEncryptionType =
+				scan_result->ucEncryptionType;
+			cmd->u.roamCmd.roamProfile.negotiatedMCEncryptionType =
+				scan_result->mcEncryptionType;
+		}
+		cmd->u.roamCmd.roamProfile.negotiatedAuthType =
+			scan_result->authType;
+		if (CSR_IS_START_IBSS(&cmd->u.roamCmd.roamProfile)) {
+			if (csr_is_same_profile(mac_ctx,
+				&session->connectedProfile, profile)) {
+				*roam_state = eCsrStartIbssSameIbss;
+				return;
+			}
+		}
+		if (cmd->u.roamCmd.fReassocToSelfNoCapChange) {
+			/* trying to connect to the one already connected */
+			cmd->u.roamCmd.fReassocToSelfNoCapChange = false;
+			*roam_state = eCsrReassocToSelfNoCapChange;
+			return;
+		}
+		/* Attempt to Join this Bss... */
+		*roam_state = csr_roam_join(mac_ctx, session_id,
+				&scan_result->Result, profile);
+		return;
+	}
+
+	/* For an IBSS profile, then we need to start the IBSS. */
+	if (CSR_IS_START_IBSS(profile)) {
+		bool same_ibss = false;
+		/* Attempt to start this IBSS... */
+		csr_roam_assign_default_param(mac_ctx, cmd);
+		status = csr_roam_start_ibss(mac_ctx, session_id,
+				profile, &same_ibss);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			if (same_ibss)
+				*roam_state = eCsrStartIbssSameIbss;
+			else
+				*roam_state = eCsrContinueRoaming;
+		} else {
+			/* it somehow fail need to stop */
+			*roam_state = eCsrStopRoaming;
+		}
+		return;
+	} else if (CSR_IS_INFRA_AP(profile)) {
+		/* Attempt to start this WDS... */
+		csr_roam_assign_default_param(mac_ctx, cmd);
+		/* For AP WDS, we dont have any BSSDescription */
+		status = csr_roam_start_wds(mac_ctx, session_id, profile, NULL);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			*roam_state = eCsrContinueRoaming;
+		else
+			*roam_state = eCsrStopRoaming;
+	} else if (CSR_IS_NDI(profile)) {
+		csr_roam_assign_default_param(mac_ctx, cmd);
+		status = csr_roam_start_ndi(mac_ctx, session_id, profile);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			*roam_state = eCsrContinueRoaming;
+		else
+			*roam_state = eCsrStopRoaming;
+	} else {
+		/* Nothing we can do */
+		sme_warn("cannot continue without BSS list");
+		*roam_state = eCsrStopRoaming;
+		return;
+	}
+
+}
+/**
+ * csr_roam_join_next_bss() - Pick the next BSS for join
+ * @mac_ctx:             Global MAC Context
+ * @cmd:                 Command
+ * @use_same_bss:        Use Same BSS to Join
+ *
+ * Return: The Join State
+ */
+static enum csr_join_state csr_roam_join_next_bss(tpAniSirGlobal mac_ctx,
+		tSmeCmd *cmd, bool use_same_bss)
+{
+	struct tag_csrscan_result *scan_result = NULL;
+	enum csr_join_state roam_state = eCsrStopRoaming;
+	struct scan_result_list *bss_list =
+		(struct scan_result_list *) cmd->u.roamCmd.hBSSList;
+	bool done = false;
+	struct csr_roam_info *roam_info = NULL;
+	uint32_t session_id = cmd->sessionId;
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+	struct csr_roam_profile *profile = &cmd->u.roamCmd.roamProfile;
+	struct csr_roam_joinstatus *join_status;
+	tCsrScanResultInfo *result = NULL;
+
+	if (!session) {
+		sme_err("session %d not found", session_id);
+		return eCsrStopRoaming;
+	}
+
+	roam_info = qdf_mem_malloc(sizeof(*roam_info));
+	if (!roam_info)
+		return eCsrStopRoaming;
+
+	qdf_mem_copy(&roam_info->bssid, &session->joinFailStatusCode.bssId,
+			sizeof(tSirMacAddr));
+	/*
+	 * When handling AP's capability change, continue to associate
+	 * to same BSS and make sure pRoamBssEntry is not Null.
+	 */
+	if ((NULL != bss_list) &&
+		((false == use_same_bss) ||
+		 (cmd->u.roamCmd.pRoamBssEntry == NULL))) {
+		if (cmd->u.roamCmd.pRoamBssEntry == NULL) {
+			/* Try the first BSS */
+			cmd->u.roamCmd.pLastRoamBss = NULL;
+			cmd->u.roamCmd.pRoamBssEntry =
+				csr_ll_peek_head(&bss_list->List,
+					LL_ACCESS_LOCK);
+		} else {
+			cmd->u.roamCmd.pRoamBssEntry =
+				csr_ll_next(&bss_list->List,
+					cmd->u.roamCmd.pRoamBssEntry,
+					LL_ACCESS_LOCK);
+			/*
+			 * Done with all the BSSs.
+			 * In this case, will tell HDD the
+			 * completion
+			 */
+			if (NULL == cmd->u.roamCmd.pRoamBssEntry)
+				goto end;
+			/*
+			 * We need to indicate to HDD that we
+			 * are done with this one.
+			 */
+			roam_info->pBssDesc = cmd->u.roamCmd.pLastRoamBss;
+			join_status = &session->joinFailStatusCode;
+			roam_info->statusCode = join_status->statusCode;
+			roam_info->reasonCode = join_status->reasonCode;
+		}
+		done = csr_roam_select_bss(mac_ctx,
+				cmd->u.roamCmd.pRoamBssEntry, &result,
+				&scan_result, session_id, cmd->u.roamCmd.roamId,
+				&roam_state, bss_list);
+		if (done)
+			goto end;
+	}
+	roam_info->u.pConnectedProfile = &session->connectedProfile;
+
+	csr_roam_join_handle_profile(mac_ctx, session_id, cmd, roam_info,
+		&roam_state, result, scan_result);
+end:
+	if ((eCsrStopRoaming == roam_state) && CSR_IS_INFRASTRUCTURE(profile) &&
+		(session->bRefAssocStartCnt > 0)) {
+		/*
+		 * Need to indicate association_completion if association_start
+		 * has been done
+		 */
+		session->bRefAssocStartCnt--;
+		/*
+		 * Complete the last assoc attempte as a
+		 * new one is about to be tried
+		 */
+		roam_info->pProfile = profile;
+		csr_roam_call_callback(mac_ctx, session_id,
+			roam_info, cmd->u.roamCmd.roamId,
+			eCSR_ROAM_ASSOCIATION_COMPLETION,
+			eCSR_ROAM_RESULT_NOT_ASSOCIATED);
+	}
+	qdf_mem_free(roam_info);
+
+	return roam_state;
+}
+
+static QDF_STATUS csr_roam(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	enum csr_join_state RoamState;
+	enum csr_roam_substate substate;
+	uint32_t sessionId = pCommand->sessionId;
+
+	/* Attept to join a Bss... */
+	RoamState = csr_roam_join_next_bss(pMac, pCommand, false);
+
+	/* if nothing to join.. */
+	if ((eCsrStopRoaming == RoamState) ||
+		(eCsrStopRoamingDueToConcurrency == RoamState)) {
+		bool fComplete = false;
+		/* and if connected in Infrastructure mode... */
+		if (csr_is_conn_state_infra(pMac, sessionId)) {
+			/* ... then we need to issue a disassociation */
+			substate = eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN;
+			status = csr_roam_issue_disassociate(pMac, sessionId,
+					substate, false);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				sme_warn("fail issuing disassoc status = %d",
+					status);
+				/*
+				 * roam command is completed by caller in the
+				 * failed case
+				 */
+				fComplete = true;
+			}
+		} else if (csr_is_conn_state_ibss(pMac, sessionId)) {
+			status = csr_roam_issue_stop_bss(pMac, sessionId,
+					eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				sme_warn("fail issuing stop bss status = %d",
+					status);
+				/*
+				 * roam command is completed by caller in the
+				 * failed case
+				 */
+				fComplete = true;
+			}
+		} else if (csr_is_conn_state_connected_infra_ap(pMac,
+					sessionId)) {
+			substate = eCSR_ROAM_SUBSTATE_STOP_BSS_REQ;
+			status = csr_roam_issue_stop_bss(pMac, sessionId,
+						substate);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				sme_warn("fail issuing stop bss status = %d",
+					status);
+				/*
+				 * roam command is completed by caller in the
+				 * failed case
+				 */
+				fComplete = true;
+			}
+		} else {
+			fComplete = true;
+		}
+
+		if (fComplete) {
+			/* otherwise, we can complete the Roam command here. */
+			if (eCsrStopRoamingDueToConcurrency == RoamState)
+				csr_roam_complete(pMac,
+					eCsrJoinFailureDueToConcurrency, NULL,
+					sessionId);
+			else
+				csr_roam_complete(pMac,
+					eCsrNothingToJoin, NULL, sessionId);
+		}
+	} else if (eCsrReassocToSelfNoCapChange == RoamState) {
+		csr_roam_complete(pMac, eCsrSilentlyStopRoamingSaveState,
+				NULL, sessionId);
+	} else if (eCsrStartIbssSameIbss == RoamState) {
+		csr_roam_complete(pMac, eCsrSilentlyStopRoaming, NULL,
+				sessionId);
+	}
+
+	return status;
+}
+
+static
+QDF_STATUS csr_process_ft_reassoc_roam_command(tpAniSirGlobal pMac,
+					       tSmeCmd *pCommand)
+{
+	uint32_t sessionId;
+	struct csr_roam_session *pSession;
+	struct tag_csrscan_result *pScanResult = NULL;
+	tSirBssDescription *pBssDesc = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	sessionId = pCommand->sessionId;
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (CSR_IS_ROAMING(pSession) && pSession->fCancelRoaming) {
+		/* the roaming is cancelled. Simply complete the command */
+		sme_debug("Roam command canceled");
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL, sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (pCommand->u.roamCmd.pRoamBssEntry) {
+		pScanResult =
+			GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry,
+				      struct tag_csrscan_result, Link);
+		pBssDesc = &pScanResult->Result.BssDescriptor;
+	} else {
+		/* the roaming is cancelled. Simply complete the command */
+		sme_debug("Roam command canceled");
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL, sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	status = csr_roam_issue_reassociate(pMac, sessionId, pBssDesc,
+					    (tDot11fBeaconIEs *) (pScanResult->
+								  Result.pvIes),
+					    &pCommand->u.roamCmd.roamProfile);
+	return status;
+}
+
+/**
+ * csr_roam_trigger_reassociate() - Helper function to trigger reassociate
+ * @mac_ctx: pointer to mac context
+ * @cmd: sme command
+ * @roam_info: Roaming infor structure
+ * @session_ptr: session pointer
+ * @session_id: session id
+ *
+ * This function will trigger reassociate.
+ *
+ * Return: QDF_STATUS for success or failure.
+ */
+static QDF_STATUS csr_roam_trigger_reassociate(
+tpAniSirGlobal mac_ctx, tSmeCmd *cmd, struct csr_roam_info *roam_info,
+			struct csr_roam_session *session_ptr,
+				uint32_t session_id)
+{
+	tDot11fBeaconIEs *pIes = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (session_ptr->pConnectBssDesc) {
+		status = csr_get_parsed_bss_description_ies(mac_ctx,
+				session_ptr->pConnectBssDesc, &pIes);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("fail to parse IEs");
+		} else {
+			roam_info->reasonCode =
+					eCsrRoamReasonStaCapabilityChanged;
+			csr_roam_call_callback(mac_ctx, session_ptr->sessionId,
+					roam_info, 0, eCSR_ROAM_ROAMING_START,
+					eCSR_ROAM_RESULT_NONE);
+			session_ptr->roamingReason = eCsrReassocRoaming;
+			roam_info->pBssDesc = session_ptr->pConnectBssDesc;
+			roam_info->pProfile = &cmd->u.roamCmd.roamProfile;
+			session_ptr->bRefAssocStartCnt++;
+			csr_roam_call_callback(mac_ctx, session_id, roam_info,
+				cmd->u.roamCmd.roamId,
+				eCSR_ROAM_ASSOCIATION_START,
+				eCSR_ROAM_RESULT_NONE);
+
+			sme_debug("calling csr_roam_issue_reassociate");
+			status = csr_roam_issue_reassociate(mac_ctx, session_id,
+					session_ptr->pConnectBssDesc, pIes,
+					&cmd->u.roamCmd.roamProfile);
+			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;
+		}
+	} else {
+		sme_err("reassoc to same AP failed as connected BSS is NULL");
+		status = QDF_STATUS_E_FAILURE;
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	struct csr_roam_info roamInfo;
+	QDF_STATUS lock_status, status = QDF_STATUS_SUCCESS;
+	uint32_t sessionId = pCommand->sessionId;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	sme_debug("Roam Reason: %d sessionId: %d",
+		pCommand->u.roamCmd.roamReason, sessionId);
+
+	pSession->disconnect_reason = pCommand->u.roamCmd.disconnect_reason;
+
+	switch (pCommand->u.roamCmd.roamReason) {
+	case eCsrForcedDisassoc:
+		status = csr_roam_process_disassoc_deauth(pMac, pCommand,
+				true, false);
+		lock_status = sme_acquire_global_lock(&pMac->sme);
+		if (!QDF_IS_STATUS_SUCCESS(lock_status)) {
+			csr_roam_complete(pMac, eCsrNothingToJoin, NULL,
+					  sessionId);
+			return lock_status;
+		}
+		csr_free_roam_profile(pMac, sessionId);
+		sme_release_global_lock(&pMac->sme);
+		break;
+	case eCsrSmeIssuedDisassocForHandoff:
+		/* Not to free pMac->roam.pCurRoamProfile (via
+		 * csr_free_roam_profile) because its needed after disconnect
+		 */
+		status = csr_roam_process_disassoc_deauth(pMac, pCommand,
+				true, false);
+
+		break;
+	case eCsrForcedDisassocMICFailure:
+		status = csr_roam_process_disassoc_deauth(pMac, pCommand,
+				true, true);
+		lock_status = sme_acquire_global_lock(&pMac->sme);
+		if (!QDF_IS_STATUS_SUCCESS(lock_status)) {
+			csr_roam_complete(pMac, eCsrNothingToJoin, NULL,
+					  sessionId);
+			return lock_status;
+		}
+		csr_free_roam_profile(pMac, sessionId);
+		sme_release_global_lock(&pMac->sme);
+		break;
+	case eCsrForcedDeauth:
+		status = csr_roam_process_disassoc_deauth(pMac, pCommand,
+				false, false);
+		lock_status = sme_acquire_global_lock(&pMac->sme);
+		if (!QDF_IS_STATUS_SUCCESS(lock_status)) {
+			csr_roam_complete(pMac, eCsrNothingToJoin, NULL,
+					  sessionId);
+			return lock_status;
+		}
+		csr_free_roam_profile(pMac, sessionId);
+		sme_release_global_lock(&pMac->sme);
+		break;
+	case eCsrHddIssuedReassocToSameAP:
+	case eCsrSmeIssuedReassocToSameAP:
+		status = csr_roam_trigger_reassociate(pMac, pCommand, &roamInfo,
+				pSession, sessionId);
+		break;
+	case eCsrCapsChange:
+		sme_err("received eCsrCapsChange ");
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
+				sessionId);
+		status = csr_roam_issue_disassociate(pMac, sessionId,
+				eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
+				false);
+		break;
+	case eCsrSmeIssuedFTReassoc:
+		sme_debug("received FT Reassoc Req");
+		status = csr_process_ft_reassoc_roam_command(pMac, pCommand);
+		break;
+
+	case eCsrStopBss:
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
+				sessionId);
+		status = csr_roam_issue_stop_bss(pMac, sessionId,
+				eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
+		break;
+
+	case eCsrForcedDisassocSta:
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
+				sessionId);
+		csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_DISASSOC_REQ,
+				sessionId);
+		sme_debug("Disassociate issued with reason: %d",
+			pCommand->u.roamCmd.reason);
+		status = csr_send_mb_disassoc_req_msg(pMac, sessionId,
+				pCommand->u.roamCmd.peerMac,
+				pCommand->u.roamCmd.reason);
+		break;
+
+	case eCsrForcedDeauthSta:
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
+				sessionId);
+		csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_DEAUTH_REQ,
+				sessionId);
+		status = csr_send_mb_deauth_req_msg(pMac, sessionId,
+				pCommand->u.roamCmd.peerMac,
+				pCommand->u.roamCmd.reason);
+		break;
+
+	case eCsrPerformPreauth:
+		sme_debug("Attempting FT PreAuth Req");
+		status = csr_roam_issue_ft_preauth_req(pMac, sessionId,
+				pCommand->u.roamCmd.pLastRoamBss);
+		break;
+	default:
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
+				sessionId);
+
+		if (pCommand->u.roamCmd.fUpdateCurRoamProfile) {
+			/* Remember the roaming profile */
+			lock_status = sme_acquire_global_lock(&pMac->sme);
+			if (!QDF_IS_STATUS_SUCCESS(lock_status)) {
+				csr_roam_complete(pMac, eCsrNothingToJoin, NULL,
+						  sessionId);
+				return lock_status;
+			}
+			csr_free_roam_profile(pMac, sessionId);
+			pSession->pCurRoamProfile =
+				qdf_mem_malloc(sizeof(struct csr_roam_profile));
+			if (NULL != pSession->pCurRoamProfile) {
+				csr_roam_copy_profile(pMac,
+					pSession->pCurRoamProfile,
+					&pCommand->u.roamCmd.roamProfile);
+			}
+			sme_release_global_lock(&pMac->sme);
+		}
+		/*
+		 * At this point original uapsd_mask is saved in
+		 * pCurRoamProfile. uapsd_mask in the pCommand may change from
+		 * this point on. Attempt to roam with the new scan results
+		 * (if we need to..)
+		 */
+		status = csr_roam(pMac, pCommand);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			sme_warn("csr_roam() failed with status = 0x%08X",
+				status);
+		break;
+	}
+	return status;
+}
+
+void csr_reinit_roam_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	if (pCommand->u.roamCmd.fReleaseBssList) {
+		csr_scan_result_purge(pMac, pCommand->u.roamCmd.hBSSList);
+		pCommand->u.roamCmd.fReleaseBssList = false;
+		pCommand->u.roamCmd.hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
+	}
+	if (pCommand->u.roamCmd.fReleaseProfile) {
+		csr_release_profile(pMac, &pCommand->u.roamCmd.roamProfile);
+		pCommand->u.roamCmd.fReleaseProfile = false;
+	}
+	pCommand->u.roamCmd.pLastRoamBss = NULL;
+	pCommand->u.roamCmd.pRoamBssEntry = NULL;
+	/* Because u.roamCmd is union and share with scanCmd and StatusChange */
+	qdf_mem_set(&pCommand->u.roamCmd, sizeof(struct roam_cmd), 0);
+}
+
+void csr_reinit_wm_status_change_cmd(tpAniSirGlobal pMac,
+			tSmeCmd *pCommand)
+{
+	qdf_mem_set(&pCommand->u.wmStatusChangeCmd, sizeof(
+		struct wmstatus_changecmd),
+		    0);
+}
+
+void csr_roam_complete(tpAniSirGlobal mac_ctx,
+		       enum csr_roamcomplete_result Result,
+		       void *Context, uint8_t session_id)
+{
+	tSmeCmd *sme_cmd;
+	struct wlan_serialization_command *cmd;
+
+	cmd = wlan_serialization_peek_head_active_cmd_using_psoc(
+				mac_ctx->psoc, false);
+	if (!cmd) {
+		sme_err("Roam completion called but cmd is not active");
+		return;
+	}
+	sme_cmd = cmd->umac_cmd;
+	if (!sme_cmd) {
+		sme_err("sme_cmd is NULL");
+		return;
+	}
+	if (eSmeCommandRoam == sme_cmd->command) {
+		csr_roam_process_results(mac_ctx, sme_cmd, Result, Context);
+		csr_release_command(mac_ctx, sme_cmd);
+	}
+}
+
+
+void csr_reset_pmkid_candidate_list(tpAniSirGlobal pMac,
+						uint32_t sessionId)
+{
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session: %d not found", sessionId);
+		return;
+	}
+	qdf_mem_set(&(pSession->PmkidCandidateInfo[0]),
+		    sizeof(tPmkidCandidateInfo) * CSR_MAX_PMKID_ALLOWED, 0);
+	pSession->NumPmkidCandidate = 0;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+void csr_reset_bkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session: %d not found", sessionId);
+		return;
+	}
+	qdf_mem_set(&(pSession->BkidCandidateInfo[0]),
+		    sizeof(tBkidCandidateInfo) * CSR_MAX_BKID_ALLOWED, 0);
+	pSession->NumBkidCandidate = 0;
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+/**
+ * csr_roam_save_params() - Helper function to save params
+ * @mac_ctx: pointer to mac context
+ * @session_ptr: Session pointer
+ * @auth_type: auth type
+ * @ie_ptr: pointer to ie
+ * @ie_local: pointr to local ie
+ *
+ * This function will save params to session
+ *
+ * Return: none.
+ */
+static QDF_STATUS csr_roam_save_params(tpAniSirGlobal mac_ctx,
+				struct csr_roam_session *session_ptr,
+				eCsrAuthType auth_type,
+				tDot11fBeaconIEs *ie_ptr,
+				tDot11fBeaconIEs *ie_local)
+{
+	uint32_t nIeLen;
+	uint8_t *pIeBuf;
+
+	if ((eCSR_AUTH_TYPE_RSN == auth_type) ||
+		(eCSR_AUTH_TYPE_FT_RSN == auth_type) ||
+		(eCSR_AUTH_TYPE_FT_RSN_PSK == auth_type) ||
+#if defined WLAN_FEATURE_11W
+		(eCSR_AUTH_TYPE_RSN_PSK_SHA256 == auth_type) ||
+		(eCSR_AUTH_TYPE_RSN_8021X_SHA256 == auth_type) ||
+#endif
+		(eCSR_AUTH_TYPE_RSN_PSK == auth_type)) {
+		if (ie_local->RSN.present) {
+			tDot11fIERSN *rsnie = &ie_local->RSN;
+			/*
+			 * Calculate the actual length
+			 * version + gp_cipher_suite + pwise_cipher_suite_count
+			 * + akm_suite_cnt + reserved + pwise_cipher_suites
+			 */
+			nIeLen = 8 + 2 + 2
+				+ (rsnie->pwise_cipher_suite_count * 4)
+				+ (rsnie->akm_suite_cnt * 4);
+			if (rsnie->pmkid_count)
+				/* pmkid */
+				nIeLen += 2 + rsnie->pmkid_count * 4;
+
+			/* nIeLen doesn't count EID and length fields */
+			session_ptr->pWpaRsnRspIE = qdf_mem_malloc(nIeLen + 2);
+			if (NULL == session_ptr->pWpaRsnRspIE)
+				return QDF_STATUS_E_NOMEM;
+
+			session_ptr->pWpaRsnRspIE[0] = DOT11F_EID_RSN;
+			session_ptr->pWpaRsnRspIE[1] = (uint8_t) nIeLen;
+			/* copy upto akm_suite */
+			pIeBuf = session_ptr->pWpaRsnRspIE + 2;
+			qdf_mem_copy(pIeBuf, &rsnie->version,
+					sizeof(rsnie->version));
+			pIeBuf += sizeof(rsnie->version);
+			qdf_mem_copy(pIeBuf, &rsnie->gp_cipher_suite,
+				sizeof(rsnie->gp_cipher_suite));
+			pIeBuf += sizeof(rsnie->gp_cipher_suite);
+			qdf_mem_copy(pIeBuf, &rsnie->pwise_cipher_suite_count,
+				sizeof(rsnie->pwise_cipher_suite_count));
+			pIeBuf += sizeof(rsnie->pwise_cipher_suite_count);
+			if (rsnie->pwise_cipher_suite_count) {
+				/* copy pwise_cipher_suites */
+				qdf_mem_copy(pIeBuf, rsnie->pwise_cipher_suites,
+					rsnie->pwise_cipher_suite_count * 4);
+				pIeBuf += rsnie->pwise_cipher_suite_count * 4;
+			}
+			qdf_mem_copy(pIeBuf, &rsnie->akm_suite_cnt, 2);
+			pIeBuf += 2;
+			if (rsnie->akm_suite_cnt) {
+				/* copy akm_suite */
+				qdf_mem_copy(pIeBuf, rsnie->akm_suite,
+					rsnie->akm_suite_cnt * 4);
+				pIeBuf += rsnie->akm_suite_cnt * 4;
+			}
+			/* copy the rest */
+			qdf_mem_copy(pIeBuf, rsnie->akm_suite +
+				rsnie->akm_suite_cnt * 4,
+				2 + rsnie->pmkid_count * 4);
+			session_ptr->nWpaRsnRspIeLength = nIeLen + 2;
+		}
+	} else if ((eCSR_AUTH_TYPE_WPA == auth_type) ||
+			(eCSR_AUTH_TYPE_WPA_PSK == auth_type)) {
+		if (ie_local->WPA.present) {
+			tDot11fIEWPA *wpaie = &ie_local->WPA;
+			/* Calculate the actual length wpaie */
+			nIeLen = 12 + 2 /* auth_suite_count */
+				+ wpaie->unicast_cipher_count * 4
+				+ wpaie->auth_suite_count * 4;
+
+			/* The WPA capabilities follows the Auth Suite
+			 * (two octects)-- this field is optional, and
+			 * we always "send" zero, so just remove it.  This is
+			 * consistent with our assumptions in the frames
+			 * compiler; nIeLen doesn't count EID & length fields
+			 */
+			session_ptr->pWpaRsnRspIE = qdf_mem_malloc(nIeLen + 2);
+			if (NULL == session_ptr->pWpaRsnRspIE)
+				return QDF_STATUS_E_NOMEM;
+			session_ptr->pWpaRsnRspIE[0] = DOT11F_EID_WPA;
+			session_ptr->pWpaRsnRspIE[1] = (uint8_t) nIeLen;
+			pIeBuf = session_ptr->pWpaRsnRspIE + 2;
+			/* Copy WPA OUI */
+			qdf_mem_copy(pIeBuf, &csr_wpa_oui[1], 4);
+			pIeBuf += 4;
+			qdf_mem_copy(pIeBuf, &wpaie->version,
+				8 + wpaie->unicast_cipher_count * 4);
+			pIeBuf += 8 + wpaie->unicast_cipher_count * 4;
+			qdf_mem_copy(pIeBuf, &wpaie->auth_suite_count,
+				2 + wpaie->auth_suite_count * 4);
+			pIeBuf += wpaie->auth_suite_count * 4;
+			session_ptr->nWpaRsnRspIeLength = nIeLen + 2;
+		}
+	}
+#ifdef FEATURE_WLAN_WAPI
+	else if ((eCSR_AUTH_TYPE_WAPI_WAI_PSK == auth_type) ||
+			(eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE ==
+			 auth_type)) {
+		if (ie_local->WAPI.present) {
+			tDot11fIEWAPI *wapi_ie = &ie_local->WAPI;
+			/* Calculate the actual length of wapi ie*/
+			nIeLen = 4 + 2 /* pwise_cipher_suite_count */
+				+ wapi_ie->akm_suite_count * 4
+				+ wapi_ie->unicast_cipher_suite_count * 4
+				+ 6;  /* gp_cipher_suite + preauth + reserved */
+
+			if (wapi_ie->bkid_count)
+				nIeLen += 2 + wapi_ie->bkid_count * 4;
+
+			/* nIeLen doesn't count EID and length fields */
+			session_ptr->pWapiRspIE =
+				qdf_mem_malloc(nIeLen + 2);
+			if (NULL == session_ptr->pWapiRspIE)
+				return QDF_STATUS_E_NOMEM;
+			session_ptr->pWapiRspIE[0] = DOT11F_EID_WAPI;
+			session_ptr->pWapiRspIE[1] = (uint8_t) nIeLen;
+			pIeBuf = session_ptr->pWapiRspIE + 2;
+			/* copy upto akm_suite_count */
+			qdf_mem_copy(pIeBuf, &wapi_ie->version, 2);
+			pIeBuf += 4;
+			if (wapi_ie->akm_suite_count) {
+				/* copy akm_suites */
+				qdf_mem_copy(pIeBuf,
+					wapi_ie->akm_suites,
+					wapi_ie->akm_suite_count * 4);
+				pIeBuf += wapi_ie->akm_suite_count * 4;
+			}
+			qdf_mem_copy(pIeBuf,
+				&wapi_ie->unicast_cipher_suite_count, 2);
+			pIeBuf += 2;
+			if (wapi_ie->unicast_cipher_suite_count) {
+				uint16_t suite_size =
+					wapi_ie->unicast_cipher_suite_count * 4;
+				/* copy pwise_cipher_suites */
+				qdf_mem_copy(pIeBuf,
+					wapi_ie->unicast_cipher_suites,
+					suite_size);
+				pIeBuf += suite_size;
+			}
+			/* gp_cipher_suite */
+			qdf_mem_copy(pIeBuf,
+				wapi_ie->multicast_cipher_suite, 4);
+			pIeBuf += 4;
+			/* preauth + reserved */
+			qdf_mem_copy(pIeBuf,
+				wapi_ie->multicast_cipher_suite + 4, 2);
+			pIeBuf += 2;
+			if (wapi_ie->bkid_count) {
+				/* bkid_count */
+				qdf_mem_copy(pIeBuf, &wapi_ie->bkid_count, 2);
+				pIeBuf += 2;
+				/* copy akm_suites */
+				qdf_mem_copy(pIeBuf, wapi_ie->bkid,
+					wapi_ie->bkid_count * 4);
+				pIeBuf += wapi_ie->bkid_count * 4;
+			}
+			session_ptr->nWapiRspIeLength = nIeLen + 2;
+		}
+	}
+#endif /* FEATURE_WLAN_WAPI */
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS csr_roam_save_security_rsp_ie(tpAniSirGlobal pMac,
+						uint32_t sessionId,
+						eCsrAuthType authType,
+						tSirBssDescription *pSirBssDesc,
+						tDot11fBeaconIEs *pIes)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tDot11fBeaconIEs *pIesLocal = pIes;
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_debug("authType %d session %d", authType, sessionId);
+	if ((eCSR_AUTH_TYPE_WPA == authType) ||
+		(eCSR_AUTH_TYPE_WPA_PSK == authType) ||
+		(eCSR_AUTH_TYPE_RSN == authType) ||
+		(eCSR_AUTH_TYPE_RSN_PSK == authType)
+		|| (eCSR_AUTH_TYPE_FT_RSN == authType) ||
+		(eCSR_AUTH_TYPE_FT_RSN_PSK == authType)
+#ifdef FEATURE_WLAN_WAPI
+		|| (eCSR_AUTH_TYPE_WAPI_WAI_PSK == authType) ||
+		(eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == authType)
+#endif /* FEATURE_WLAN_WAPI */
+#ifdef WLAN_FEATURE_11W
+		|| (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType) ||
+		(eCSR_AUTH_TYPE_RSN_8021X_SHA256 == authType)
+#endif /* FEATURE_WLAN_WAPI */
+		|| (eCSR_AUTH_TYPE_SAE == authType)) {
+		if (!pIesLocal && !QDF_IS_STATUS_SUCCESS
+				(csr_get_parsed_bss_description_ies(pMac,
+				pSirBssDesc, &pIesLocal)))
+			sme_err(" cannot parse IEs");
+		if (pIesLocal) {
+			status = csr_roam_save_params(pMac, pSession, authType,
+					pIes, pIesLocal);
+			if (!pIes)
+				/* locally allocated */
+				qdf_mem_free(pIesLocal);
+		}
+	}
+	return status;
+}
+
+/* Returns whether the current association is a 11r assoc or not */
+bool csr_roam_is11r_assoc(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	return csr_neighbor_roam_is11r_assoc(pMac, sessionId);
+}
+
+/* Returns whether "Legacy Fast Roaming" is currently enabled...or not */
+bool csr_roam_is_fast_roam_enabled(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	struct csr_roam_session *pSession = NULL;
+
+	if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		pSession = CSR_GET_SESSION(pMac, sessionId);
+		if (NULL != pSession->pCurRoamProfile) {
+			if (pSession->pCurRoamProfile->csrPersona !=
+			    QDF_STA_MODE) {
+				return false;
+			}
+		}
+	}
+	if (true == CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED(pMac)) {
+		return pMac->roam.configParam.isFastRoamIniFeatureEnabled;
+	} else {
+		return pMac->roam.configParam.isFastRoamIniFeatureEnabled &&
+			(!csr_is_concurrent_session_running(pMac));
+	}
+}
+
+static void csr_update_scan_entry_associnfo(tpAniSirGlobal mac_ctx,
+			struct bss_info *bss, enum scan_entry_connection_state state)
+{
+	QDF_STATUS status;
+	struct mlme_info mlme;
+
+	sme_debug("Update MLME info in scan database. bssid %pM state: %d",
+				bss->bssid.bytes, state);
+	mlme.assoc_state = state;
+	status = ucfg_scan_update_mlme_by_bssinfo(mac_ctx->pdev, bss, &mlme);
+	if (QDF_IS_STATUS_ERROR(status))
+		sme_debug("Failed to update the MLME info in scan entry");
+}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+static eCsrPhyMode csr_roamdot11mode_to_phymode(uint8_t dot11mode)
+{
+	eCsrPhyMode phymode = eCSR_DOT11_MODE_abg;
+
+	switch (dot11mode) {
+	case WNI_CFG_DOT11_MODE_ALL:
+		phymode = eCSR_DOT11_MODE_abg;
+		break;
+	case WNI_CFG_DOT11_MODE_11A:
+		phymode = eCSR_DOT11_MODE_11a;
+		break;
+	case WNI_CFG_DOT11_MODE_11B:
+		phymode = eCSR_DOT11_MODE_11b;
+		break;
+	case WNI_CFG_DOT11_MODE_11G:
+		phymode = eCSR_DOT11_MODE_11g;
+		break;
+	case WNI_CFG_DOT11_MODE_11N:
+		phymode = eCSR_DOT11_MODE_11n;
+		break;
+	case WNI_CFG_DOT11_MODE_11G_ONLY:
+		phymode = eCSR_DOT11_MODE_11g_ONLY;
+		break;
+	case WNI_CFG_DOT11_MODE_11N_ONLY:
+		phymode = eCSR_DOT11_MODE_11n_ONLY;
+		break;
+	case WNI_CFG_DOT11_MODE_11AC:
+		phymode = eCSR_DOT11_MODE_11ac;
+		break;
+	case WNI_CFG_DOT11_MODE_11AC_ONLY:
+		phymode = eCSR_DOT11_MODE_11ac_ONLY;
+		break;
+	case WNI_CFG_DOT11_MODE_11AX:
+		phymode = eCSR_DOT11_MODE_11ax;
+		break;
+	case WNI_CFG_DOT11_MODE_11AX_ONLY:
+		phymode = eCSR_DOT11_MODE_11ax_ONLY;
+		break;
+	default:
+		break;
+	}
+
+	return phymode;
+}
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static void csr_roam_synch_clean_up(tpAniSirGlobal mac, uint8_t session_id)
+{
+	struct scheduler_msg msg = {0};
+	struct roam_offload_synch_fail *roam_offload_failed = NULL;
+	struct csr_roam_session *session = &mac->roam.roamSession[session_id];
+
+	/* Clean up the roam synch in progress for LFR3 */
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+		  "%s: Roam Synch Failed, Clean Up", __func__);
+	session->roam_synch_in_progress = false;
+
+	roam_offload_failed = qdf_mem_malloc(
+				sizeof(struct roam_offload_synch_fail));
+	if (!roam_offload_failed)
+		return;
+
+	roam_offload_failed->session_id = session_id;
+	msg.type     = WMA_ROAM_OFFLOAD_SYNCH_FAIL;
+	msg.reserved = 0;
+	msg.bodyptr  = roam_offload_failed;
+	if (!QDF_IS_STATUS_SUCCESS(scheduler_post_message(QDF_MODULE_ID_SME,
+							  QDF_MODULE_ID_WMA,
+							  QDF_MODULE_ID_WMA,
+							  &msg))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"%s: Unable to post WMA_ROAM_OFFLOAD_SYNCH_FAIL to WMA",
+			__func__);
+		qdf_mem_free(roam_offload_failed);
+	}
+}
+#endif
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * csr_roam_copy_ht_profile() - Copy from src to dst
+ * @dst_profile:          Destination HT profile
+ * @src_profile:          Source HT profile
+ *
+ * Copy the HT profile from the given source to destination
+ *
+ * Return: None
+ */
+static void csr_roam_copy_ht_profile(tCsrRoamHTProfile *dst_profile,
+		tSirSmeHTProfile *src_profile)
+{
+	dst_profile->phymode =
+		csr_roamdot11mode_to_phymode(src_profile->dot11mode);
+	dst_profile->htCapability = src_profile->htCapability;
+	dst_profile->htSupportedChannelWidthSet =
+		src_profile->htSupportedChannelWidthSet;
+	dst_profile->htRecommendedTxWidthSet =
+		src_profile->htRecommendedTxWidthSet;
+	dst_profile->htSecondaryChannelOffset =
+		src_profile->htSecondaryChannelOffset;
+	dst_profile->vhtCapability = src_profile->vhtCapability;
+	dst_profile->apCenterChan = src_profile->apCenterChan;
+	dst_profile->apChanWidth = src_profile->apChanWidth;
+}
+#endif
+
+#if defined(WLAN_FEATURE_FILS_SK)
+/**
+ * csr_update_fils_seq_number() - Copy FILS sequence number to roam info
+ * @session: CSR Roam Session
+ * @roam_info: Roam info
+ *
+ * Return: None
+ */
+static void csr_update_fils_seq_number(struct csr_roam_session *session,
+					 struct csr_roam_info *roam_info)
+{
+	roam_info->is_fils_connection = true;
+	roam_info->fils_seq_num = session->fils_seq_num;
+	pe_debug("FILS sequence number %x", session->fils_seq_num);
+}
+#else
+static inline void csr_update_fils_seq_number(struct csr_roam_session *session,
+						struct csr_roam_info *roam_info)
+{}
+#endif
+
+/**
+ * csr_roam_process_results_default() - Process the result for start bss
+ * @mac_ctx:          Global MAC Context
+ * @cmd:              Command to be processed
+ * @context:          Additional data in context of the cmd
+ *
+ * Return: None
+ */
+static void csr_roam_process_results_default(tpAniSirGlobal mac_ctx,
+		     tSmeCmd *cmd, void *context, enum csr_roamcomplete_result
+			res)
+{
+	uint32_t session_id = cmd->sessionId;
+	struct csr_roam_session *session;
+	struct csr_roam_info roam_info;
+	QDF_STATUS status;
+	struct bss_info bss_info;
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("Invalid session id %d", session_id);
+		return;
+	}
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	sme_debug("receives no association indication; FILS %d",
+		  session->is_fils_connection);
+	sme_debug("Assoc ref count: %d", session->bRefAssocStartCnt);
+
+	if (CSR_IS_INFRASTRUCTURE(&session->connectedProfile)) {
+		qdf_copy_macaddr(&bss_info.bssid,
+				&session->connectedProfile.bssid);
+		bss_info.chan = session->connectedProfile.operationChannel;
+		bss_info.ssid.length = session->connectedProfile.SSID.length;
+		qdf_mem_copy(&bss_info.ssid.ssid,
+				&session->connectedProfile.SSID.ssId,
+				bss_info.ssid.length);
+	}
+	if (CSR_IS_INFRASTRUCTURE(&session->connectedProfile)
+		|| CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac_ctx, session_id)) {
+		/*
+		 * do not free for the other profiles as we need
+		 * to send down stop BSS later
+		 */
+		csr_free_connect_bss_desc(mac_ctx, session_id);
+		csr_roam_free_connect_profile(&session->connectedProfile);
+		csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
+		csr_set_default_dot11_mode(mac_ctx);
+	}
+
+	qdf_mem_set(&roam_info, sizeof(struct csr_roam_info), 0);
+	/* Copy FILS sequence number used to be updated to userspace */
+	if (session->is_fils_connection)
+		csr_update_fils_seq_number(session, &roam_info);
+
+	switch (cmd->u.roamCmd.roamReason) {
+	/*
+	 * If this transition is because of an 802.11 OID, then we
+	 * transition back to INIT state so we sit waiting for more
+	 * OIDs to be issued and we don't start the IDLE timer.
+	 */
+	case eCsrSmeIssuedFTReassoc:
+	case eCsrSmeIssuedAssocToSimilarAP:
+	case eCsrHddIssued:
+	case eCsrSmeIssuedDisassocForHandoff:
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
+			session_id);
+		roam_info.pBssDesc = cmd->u.roamCmd.pLastRoamBss;
+		roam_info.pProfile = &cmd->u.roamCmd.roamProfile;
+		roam_info.statusCode = session->joinFailStatusCode.statusCode;
+		roam_info.reasonCode = session->joinFailStatusCode.reasonCode;
+		qdf_mem_copy(&roam_info.bssid,
+			&session->joinFailStatusCode.bssId,
+			sizeof(struct qdf_mac_addr));
+
+		/*
+		 * If Join fails while Handoff is in progress, indicate
+		 * disassociated event to supplicant to reconnect
+		 */
+		if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)) {
+			csr_neighbor_roam_indicate_connect(mac_ctx,
+				(uint8_t)session_id, QDF_STATUS_E_FAILURE);
+		}
+		if (session->bRefAssocStartCnt > 0) {
+			session->bRefAssocStartCnt--;
+			if (eCsrJoinFailureDueToConcurrency == res)
+				csr_roam_call_callback(mac_ctx, session_id,
+					&roam_info, cmd->u.roamCmd.roamId,
+					eCSR_ROAM_ASSOCIATION_COMPLETION,
+				eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL);
+			else
+				csr_roam_call_callback(mac_ctx, session_id,
+					&roam_info, cmd->u.roamCmd.roamId,
+					eCSR_ROAM_ASSOCIATION_COMPLETION,
+					eCSR_ROAM_RESULT_FAILURE);
+		} else {
+			/*
+			 * bRefAssocStartCnt is not incremented when
+			 * eRoamState == eCsrStopRoamingDueToConcurrency
+			 * in csr_roam_join_next_bss API. so handle this in
+			 * else case by sending assoc failure
+			 */
+			csr_roam_call_callback(mac_ctx, session_id,
+				&roam_info, cmd->u.roamCmd.roamId,
+				eCSR_ROAM_ASSOCIATION_FAILURE,
+				eCSR_ROAM_RESULT_FAILURE);
+		}
+		sme_debug("roam(reason %d) failed", cmd->u.roamCmd.roamReason);
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		sme_qos_update_hand_off((uint8_t) session_id, false);
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
+			SME_QOS_CSR_DISCONNECT_IND, NULL);
+#endif
+		csr_roam_completion(mac_ctx, session_id, NULL, cmd,
+			eCSR_ROAM_RESULT_FAILURE, false);
+		break;
+	case eCsrHddIssuedReassocToSameAP:
+	case eCsrSmeIssuedReassocToSameAP:
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
+			session_id);
+
+		csr_roam_call_callback(mac_ctx, session_id, NULL,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED,
+			eCSR_ROAM_RESULT_FORCED);
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
+			SME_QOS_CSR_DISCONNECT_IND, NULL);
+#endif
+		csr_roam_completion(mac_ctx, session_id, NULL, cmd,
+			eCSR_ROAM_RESULT_FAILURE, false);
+		break;
+	case eCsrForcedDisassoc:
+	case eCsrForcedDeauth:
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
+			session_id);
+		csr_roam_call_callback(
+			mac_ctx, session_id, NULL,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED,
+			eCSR_ROAM_RESULT_FORCED);
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
+				SME_QOS_CSR_DISCONNECT_IND,
+				NULL);
+#endif
+		csr_update_scan_entry_associnfo(mac_ctx, &bss_info,
+						SCAN_ENTRY_CON_STATE_NONE);
+		csr_roam_link_down(mac_ctx, session_id);
+
+		if (mac_ctx->roam.deauthRspStatus == eSIR_SME_DEAUTH_STATUS) {
+			sme_warn("FW still in connected state");
+			break;
+		}
+		break;
+	case eCsrForcedIbssLeave:
+		csr_roam_call_callback(mac_ctx, session_id, NULL,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_IBSS_LEAVE,
+			eCSR_ROAM_RESULT_IBSS_STOP);
+		session->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED;
+		break;
+	case eCsrForcedDisassocMICFailure:
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
+			session_id);
+
+		csr_roam_call_callback(mac_ctx, session_id, NULL,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED,
+			eCSR_ROAM_RESULT_MIC_FAILURE);
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
+			SME_QOS_CSR_DISCONNECT_REQ, NULL);
+#endif
+		break;
+	case eCsrStopBss:
+		csr_roam_call_callback(mac_ctx, session_id, NULL,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_INFRA_IND,
+			eCSR_ROAM_RESULT_INFRA_STOPPED);
+		break;
+	case eCsrForcedDisassocSta:
+	case eCsrForcedDeauthSta:
+		roam_info.rssi = mac_ctx->peer_rssi;
+		roam_info.tx_rate = mac_ctx->peer_txrate;
+		roam_info.rx_rate = mac_ctx->peer_rxrate;
+
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
+			session_id);
+		session = CSR_GET_SESSION(mac_ctx, session_id);
+		if (CSR_IS_SESSION_VALID(mac_ctx, session_id) &&
+			CSR_IS_INFRA_AP(&session->connectedProfile)) {
+			roam_info.u.pConnectedProfile =
+				&session->connectedProfile;
+			qdf_mem_copy(roam_info.peerMac.bytes,
+					cmd->u.roamCmd.peerMac,
+					sizeof(tSirMacAddr));
+			roam_info.reasonCode = eCSR_ROAM_RESULT_FORCED;
+			/* Update the MAC reason code */
+			roam_info.disassoc_reason = cmd->u.roamCmd.reason;
+			roam_info.statusCode = eSIR_SME_SUCCESS;
+			status = csr_roam_call_callback(mac_ctx, session_id,
+					&roam_info, cmd->u.roamCmd.roamId,
+					eCSR_ROAM_LOSTLINK,
+					eCSR_ROAM_RESULT_FORCED);
+		}
+		break;
+	default:
+		csr_roam_state_change(mac_ctx,
+			eCSR_ROAMING_STATE_IDLE, session_id);
+		break;
+	}
+}
+
+/**
+ * csr_roam_process_start_bss_success() - Process the result for start bss
+ * @mac_ctx:          Global MAC Context
+ * @cmd:              Command to be processed
+ * @context:          Additional data in context of the cmd
+ *
+ * Return: None
+ */
+static void csr_roam_process_start_bss_success(tpAniSirGlobal mac_ctx,
+		     tSmeCmd *cmd, void *context)
+{
+	uint32_t session_id = cmd->sessionId;
+	struct csr_roam_profile *profile = &cmd->u.roamCmd.roamProfile;
+	struct csr_roam_session *session;
+	tSirBssDescription *bss_desc = NULL;
+	struct csr_roam_info roam_info;
+	tSirSmeStartBssRsp *start_bss_rsp = NULL;
+	eRoamCmdStatus roam_status;
+	eCsrRoamResult roam_result;
+	tDot11fBeaconIEs *ies_ptr = NULL;
+	tSirMacAddr bcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+	QDF_STATUS status;
+	host_log_ibss_pkt_type *ibss_log;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	tSirSmeHTProfile *src_profile = NULL;
+	tCsrRoamHTProfile *dst_profile = NULL;
+#endif
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("Invalid session id %d", session_id);
+		return;
+	}
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	/*
+	 * on the StartBss Response, LIM is returning the Bss Description that
+	 * we are beaconing.  Add this Bss Description to our scan results and
+	 * chain the Profile to this Bss Description.  On a Start BSS, there was
+	 * no detected Bss description (no partner) so we issued the Start Bss
+	 * to start the Ibss without any Bss description.  Lim was kind enough
+	 * to return the Bss Description that we start beaconing for the newly
+	 * started Ibss.
+	 */
+	sme_debug("receives start BSS ok indication");
+	status = QDF_STATUS_E_FAILURE;
+	start_bss_rsp = (tSirSmeStartBssRsp *) context;
+	qdf_mem_set(&roam_info, sizeof(struct csr_roam_info), 0);
+	if (CSR_IS_IBSS(profile))
+		session->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED;
+	else if (CSR_IS_INFRA_AP(profile))
+		session->connectState =
+			eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED;
+	else if (CSR_IS_NDI(profile))
+		session->connectState = eCSR_CONNECT_STATE_TYPE_NDI_STARTED;
+	else
+		session->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED;
+
+	bss_desc = &start_bss_rsp->bssDescription;
+	if (CSR_IS_NDI(profile)) {
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
+			session_id);
+		csr_roam_save_ndi_connected_info(mac_ctx, session_id, profile,
+						bss_desc);
+		roam_info.u.pConnectedProfile = &session->connectedProfile;
+		qdf_mem_copy(&roam_info.bssid, &bss_desc->bssId,
+			    sizeof(struct qdf_mac_addr));
+	} else {
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
+				session_id);
+		if (!QDF_IS_STATUS_SUCCESS
+			(csr_get_parsed_bss_description_ies(mac_ctx, bss_desc,
+							    &ies_ptr))) {
+			sme_warn("cannot parse IBSS IEs");
+			roam_info.pBssDesc = bss_desc;
+			csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId, eCSR_ROAM_IBSS_IND,
+				eCSR_ROAM_RESULT_IBSS_START_FAILED);
+			return;
+		}
+	}
+	if (!CSR_IS_INFRA_AP(profile) && !CSR_IS_NDI(profile)) {
+		csr_scan_append_bss_description(mac_ctx, bss_desc);
+	}
+	csr_roam_save_connected_bss_desc(mac_ctx, session_id, bss_desc);
+	csr_roam_free_connect_profile(&session->connectedProfile);
+	csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
+	csr_roam_save_connected_information(mac_ctx, session_id,
+			profile, bss_desc, ies_ptr);
+	qdf_mem_copy(&roam_info.bssid, &bss_desc->bssId,
+			sizeof(struct qdf_mac_addr));
+	/* We are done with the IEs so free it */
+	qdf_mem_free(ies_ptr);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	WLAN_HOST_DIAG_LOG_ALLOC(ibss_log,
+		host_log_ibss_pkt_type, LOG_WLAN_IBSS_C);
+	if (ibss_log) {
+		uint32_t bi;
+		if (CSR_INVALID_SCANRESULT_HANDLE ==
+				cmd->u.roamCmd.hBSSList) {
+			/*
+			 * We start the IBSS (didn't find any
+			 * matched IBSS out there)
+			 */
+			ibss_log->eventId =
+				WLAN_IBSS_EVENT_START_IBSS_RSP;
+		} else {
+			ibss_log->eventId =
+				WLAN_IBSS_EVENT_JOIN_IBSS_RSP;
+		}
+		if (bss_desc) {
+			qdf_mem_copy(ibss_log->bssid.bytes,
+				bss_desc->bssId, QDF_MAC_ADDR_SIZE);
+			ibss_log->operatingChannel =
+				bss_desc->channelId;
+		}
+		bi = mac_ctx->mlme_cfg->sap_cfg.beacon_interval;
+			/* U8 is not enough for BI */
+			ibss_log->beaconInterval = (uint8_t) bi;
+		WLAN_HOST_DIAG_LOG_REPORT(ibss_log);
+	}
+#endif
+	ibss_log = NULL;
+	/*
+	 * Only set context for non-WDS_STA. We don't even need it for
+	 * WDS_AP. But since the encryption.
+	 * is WPA2-PSK so it won't matter.
+	 */
+	if (session->pCurRoamProfile &&
+	    !CSR_IS_INFRA_AP(session->pCurRoamProfile)) {
+		if (CSR_IS_ENC_TYPE_STATIC(
+				profile->negotiatedUCEncryptionType)) {
+			/*
+			 * Issue the set Context request to LIM to establish
+			 * the Broadcast STA context for the Ibss. In Rome IBSS
+			 * case, dummy key installation will break proper BSS
+			 * key installation, so skip it.
+			 */
+			if (!CSR_IS_IBSS(session->pCurRoamProfile)) {
+				/* NO keys. these key parameters don't matter */
+				csr_roam_issue_set_context_req(mac_ctx,
+					session_id,
+					profile->negotiatedMCEncryptionType,
+					bss_desc, &bcast_mac, false,
+					false, eSIR_TX_RX, 0, 0, NULL, 0);
+			}
+		}
+		if (CSR_IS_IBSS(session->pCurRoamProfile) &&
+		    (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
+				profile->negotiatedUCEncryptionType ||
+		    eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
+				profile->negotiatedUCEncryptionType ||
+		    eCSR_ENCRYPT_TYPE_TKIP ==
+				profile->negotiatedUCEncryptionType ||
+		    eCSR_ENCRYPT_TYPE_AES ==
+				profile->negotiatedUCEncryptionType)) {
+			roam_info.fAuthRequired = true;
+		}
+	}
+	/*
+	 * Only tell upper layer is we start the BSS because Vista doesn't like
+	 * multiple connection indications. If we don't start the BSS ourself,
+	 * handler of eSIR_SME_JOINED_NEW_BSS will trigger the connection start
+	 * indication in Vista
+	 */
+	if (!CSR_IS_JOIN_TO_IBSS(profile)) {
+		roam_status = eCSR_ROAM_IBSS_IND;
+		roam_result = eCSR_ROAM_RESULT_IBSS_STARTED;
+		if (CSR_IS_INFRA_AP(profile)) {
+			roam_status = eCSR_ROAM_INFRA_IND;
+			roam_result = eCSR_ROAM_RESULT_INFRA_STARTED;
+		}
+		roam_info.staId = (uint8_t) start_bss_rsp->staId;
+		if (CSR_IS_NDI(profile)) {
+			csr_roam_update_ndp_return_params(mac_ctx,
+							eCsrStartBssSuccess,
+							&roam_status,
+							&roam_result,
+							&roam_info);
+		}
+		/*
+		 * Only tell upper layer is we start the BSS because Vista
+		 * doesn't like multiple connection indications. If we don't
+		 * start the BSS ourself, handler of eSIR_SME_JOINED_NEW_BSS
+		 * will trigger the connection start indication in Vista
+		 */
+		roam_info.statusCode = session->joinFailStatusCode.statusCode;
+		roam_info.reasonCode = session->joinFailStatusCode.reasonCode;
+		/* We start the IBSS (didn't find any matched IBSS out there) */
+		roam_info.pBssDesc = bss_desc;
+		if (bss_desc)
+			qdf_mem_copy(roam_info.bssid.bytes, bss_desc->bssId,
+				sizeof(struct qdf_mac_addr));
+		if (!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) &&
+				(csr_is_concurrent_session_running(mac_ctx))) {
+			mac_ctx->roam.configParam.doBMPSWorkaround = 1;
+		}
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+		dst_profile = &session->connectedProfile.HTProfile;
+		src_profile = &start_bss_rsp->HTProfile;
+		if (mac_ctx->roam.configParam.cc_switch_mode
+				!= QDF_MCC_TO_SCC_SWITCH_DISABLE)
+			csr_roam_copy_ht_profile(dst_profile, src_profile);
+#endif
+		csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				roam_status, roam_result);
+	}
+
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * populate_fils_params_join_rsp() - Copy FILS params from JOIN rsp
+ * @mac_ctx: Global MAC Context
+ * @roam_info: CSR Roam Info
+ * @join_rsp: SME Join response
+ *
+ * Copy the FILS params from the join results
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS populate_fils_params_join_rsp(tpAniSirGlobal mac_ctx,
+						struct csr_roam_info *roam_info,
+						tSirSmeJoinRsp *join_rsp)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct fils_join_rsp_params *roam_fils_info,
+				    *fils_join_rsp = join_rsp->fils_join_rsp;
+
+	if (!fils_join_rsp->fils_pmk_len ||
+			!fils_join_rsp->fils_pmk || !fils_join_rsp->tk_len ||
+			!fils_join_rsp->kek_len || !fils_join_rsp->gtk_len) {
+		sme_err("fils join rsp err: pmk len %d tk len %d kek len %d gtk len %d",
+			fils_join_rsp->fils_pmk_len,
+			fils_join_rsp->tk_len,
+			fils_join_rsp->kek_len,
+			fils_join_rsp->gtk_len);
+		status = QDF_STATUS_E_FAILURE;
+		goto free_fils_join_rsp;
+	}
+
+	roam_info->fils_join_rsp = qdf_mem_malloc(sizeof(*fils_join_rsp));
+	if (!roam_info->fils_join_rsp) {
+		status = QDF_STATUS_E_FAILURE;
+		goto free_fils_join_rsp;
+	}
+
+	roam_fils_info = roam_info->fils_join_rsp;
+	roam_fils_info->fils_pmk = qdf_mem_malloc(fils_join_rsp->fils_pmk_len);
+	if (!roam_fils_info->fils_pmk) {
+		qdf_mem_free(roam_info->fils_join_rsp);
+		roam_info->fils_join_rsp = NULL;
+		status = QDF_STATUS_E_FAILURE;
+		goto free_fils_join_rsp;
+	}
+
+	roam_info->fils_seq_num = join_rsp->fils_seq_num;
+	roam_fils_info->fils_pmk_len = fils_join_rsp->fils_pmk_len;
+	qdf_mem_copy(roam_fils_info->fils_pmk,
+		     fils_join_rsp->fils_pmk, roam_fils_info->fils_pmk_len);
+
+	qdf_mem_copy(roam_fils_info->fils_pmkid,
+		     fils_join_rsp->fils_pmkid, PMKID_LEN);
+
+	roam_fils_info->kek_len = fils_join_rsp->kek_len;
+	qdf_mem_copy(roam_fils_info->kek,
+		     fils_join_rsp->kek, roam_fils_info->kek_len);
+
+	roam_fils_info->tk_len = fils_join_rsp->tk_len;
+	qdf_mem_copy(roam_fils_info->tk,
+		     fils_join_rsp->tk, fils_join_rsp->tk_len);
+
+	roam_fils_info->gtk_len = fils_join_rsp->gtk_len;
+	qdf_mem_copy(roam_fils_info->gtk,
+		     fils_join_rsp->gtk, roam_fils_info->gtk_len);
+
+	cds_copy_hlp_info(&fils_join_rsp->dst_mac, &fils_join_rsp->src_mac,
+			  fils_join_rsp->hlp_data_len, fils_join_rsp->hlp_data,
+			  &roam_fils_info->dst_mac, &roam_fils_info->src_mac,
+			  &roam_fils_info->hlp_data_len,
+			  roam_fils_info->hlp_data);
+	sme_debug("FILS connect params copied to CSR!");
+
+free_fils_join_rsp:
+	qdf_mem_free(fils_join_rsp->fils_pmk);
+	qdf_mem_free(fils_join_rsp);
+	return status;
+}
+
+/**
+ * csr_process_fils_join_rsp() - Process join rsp for FILS connection
+ * @mac_ctx: Global MAC Context
+ * @profile: CSR Roam Profile
+ * @session_id: Session ID
+ * @roam_info: CSR Roam Info
+ * @bss_desc: BSS description
+ * @join_rsp: SME Join rsp
+ *
+ * Process SME join response for FILS connection
+ *
+ * Return: None
+ */
+static void csr_process_fils_join_rsp(tpAniSirGlobal mac_ctx,
+					struct csr_roam_profile *profile,
+					uint32_t session_id,
+					struct csr_roam_info *roam_info,
+					tSirBssDescription *bss_desc,
+					tSirSmeJoinRsp *join_rsp)
+{
+	tSirMacAddr bcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+	QDF_STATUS status;
+
+	if (!join_rsp || !join_rsp->fils_join_rsp) {
+		sme_err("Join rsp doesn't have FILS info");
+		goto process_fils_join_rsp_fail;
+	}
+
+	/* Copy FILS params */
+	status = populate_fils_params_join_rsp(mac_ctx, roam_info, join_rsp);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Copy FILS params join rsp fails");
+		goto process_fils_join_rsp_fail;
+	}
+
+	status = csr_roam_issue_set_context_req(mac_ctx, session_id,
+					profile->negotiatedMCEncryptionType,
+					bss_desc, &bcast_mac, true, false,
+					eSIR_RX_ONLY, 2,
+					roam_info->fils_join_rsp->gtk_len,
+					roam_info->fils_join_rsp->gtk, 0);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Set context for bcast fail");
+		goto process_fils_join_rsp_fail;
+	}
+
+	status = csr_roam_issue_set_context_req(mac_ctx, session_id,
+					profile->negotiatedUCEncryptionType,
+					bss_desc, &(bss_desc->bssId), true,
+					true, eSIR_TX_RX, 0,
+					roam_info->fils_join_rsp->tk_len,
+					roam_info->fils_join_rsp->tk, 0);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Set context for unicast fail");
+		goto process_fils_join_rsp_fail;
+	}
+	return;
+
+process_fils_join_rsp_fail:
+	csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE, session_id);
+}
+#else
+
+static inline void csr_process_fils_join_rsp(tpAniSirGlobal mac_ctx,
+					     struct csr_roam_profile *profile,
+					     uint32_t session_id,
+					     struct csr_roam_info *roam_info,
+					     tSirBssDescription *bss_desc,
+					     tSirSmeJoinRsp *join_rsp)
+{}
+#endif
+
+/**
+ * csr_roam_process_join_res() - Process the Join results
+ * @mac_ctx:          Global MAC Context
+ * @result:           Result after the command was processed
+ * @cmd:              Command to be processed
+ * @context:          Additional data in context of the cmd
+ *
+ * Process the join results which are obtained in a successful join
+ *
+ * Return: None
+ */
+static void csr_roam_process_join_res(tpAniSirGlobal mac_ctx,
+	enum csr_roamcomplete_result res, tSmeCmd *cmd, void *context)
+{
+	tSirMacAddr bcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+	sme_QosAssocInfo assoc_info;
+	uint32_t key_timeout_interval = 0;
+	uint8_t acm_mask = 0;   /* HDD needs ACM mask in assoc rsp callback */
+	uint32_t session_id = cmd->sessionId;
+	struct csr_roam_profile *profile = &cmd->u.roamCmd.roamProfile;
+	struct csr_roam_session *session;
+	tSirBssDescription *bss_desc = NULL;
+	struct tag_csrscan_result *scan_res = NULL;
+	sme_qos_csr_event_indType ind_qos;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	tSirSmeHTProfile *src_profile = NULL;
+	tCsrRoamHTProfile *dst_profile = NULL;
+#endif
+	tCsrRoamConnectedProfile *conn_profile = NULL;
+	tDot11fBeaconIEs *ies_ptr = NULL;
+	struct csr_roam_info roam_info;
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	tSirSmeJoinRsp *join_rsp = (tSirSmeJoinRsp *) context;
+	uint32_t len;
+	struct bss_info bss_info;
+
+	if (!join_rsp) {
+		sme_err("join_rsp is NULL");
+		return;
+	}
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("Invalid session id %d", session_id);
+		return;
+	}
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	conn_profile = &session->connectedProfile;
+	if (eCsrReassocSuccess == res) {
+		roam_info.reassoc = true;
+		ind_qos = SME_QOS_CSR_REASSOC_COMPLETE;
+	} else {
+		roam_info.reassoc = false;
+		ind_qos = SME_QOS_CSR_ASSOC_COMPLETE;
+	}
+	sme_debug("receives association indication");
+	/* always free the memory here */
+	if (session->pWpaRsnRspIE) {
+		session->nWpaRsnRspIeLength = 0;
+		qdf_mem_free(session->pWpaRsnRspIE);
+		session->pWpaRsnRspIE = NULL;
+	}
+#ifdef FEATURE_WLAN_WAPI
+	if (session->pWapiRspIE) {
+		session->nWapiRspIeLength = 0;
+		qdf_mem_free(session->pWapiRspIE);
+		session->pWapiRspIE = NULL;
+	}
+#endif /* FEATURE_WLAN_WAPI */
+#ifdef FEATURE_WLAN_BTAMP_UT_RF
+	session->maxRetryCount = 0;
+	csr_roam_stop_join_retry_timer(mac_ctx, session_id);
+#endif
+	/*
+	 * Reset remain_in_power_active_till_dhcp as
+	 * it might have been set by last failed secured connection.
+	 * It should be set only for secured connection.
+	 */
+	ps_global_info->remain_in_power_active_till_dhcp = false;
+	if (CSR_IS_INFRASTRUCTURE(profile))
+		session->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+	else
+		session->connectState = eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED;
+	/*
+	 * Use the last connected bssdesc for reassoc-ing to the same AP.
+	 * NOTE: What to do when reassoc to a different AP???
+	 */
+	if ((eCsrHddIssuedReassocToSameAP == cmd->u.roamCmd.roamReason)
+		|| (eCsrSmeIssuedReassocToSameAP ==
+			cmd->u.roamCmd.roamReason)) {
+		bss_desc = session->pConnectBssDesc;
+		if (bss_desc)
+			qdf_mem_copy(&roam_info.bssid, &bss_desc->bssId,
+					sizeof(struct qdf_mac_addr));
+	} else {
+		if (cmd->u.roamCmd.pRoamBssEntry) {
+			scan_res = GET_BASE_ADDR(cmd->u.roamCmd.pRoamBssEntry,
+					struct tag_csrscan_result, Link);
+			if (scan_res != NULL) {
+				bss_desc = &scan_res->Result.BssDescriptor;
+				ies_ptr = (tDot11fBeaconIEs *)
+					(scan_res->Result.pvIes);
+				qdf_mem_copy(&roam_info.bssid, &bss_desc->bssId,
+					sizeof(struct qdf_mac_addr));
+			}
+		}
+	}
+	if (bss_desc) {
+		roam_info.staId = STA_INVALID_IDX;
+		csr_roam_save_connected_information(mac_ctx, session_id,
+			profile, bss_desc, ies_ptr);
+		/* Save WPA/RSN IE */
+		csr_roam_save_security_rsp_ie(mac_ctx, session_id,
+			profile->negotiatedAuthType, bss_desc, ies_ptr);
+#ifdef FEATURE_WLAN_ESE
+		roam_info.isESEAssoc = conn_profile->isESEAssoc;
+#endif
+
+		/*
+		 * csr_roam_state_change also affects sub-state.
+		 * Hence, csr_roam_state_change happens first and then
+		 * substate change.
+		 * Moving even save profile above so that below
+		 * mentioned conditon is also met.
+		 * JEZ100225: Moved to after saving the profile.
+		 * Fix needed in main/latest
+		 */
+		csr_roam_state_change(mac_ctx,
+			eCSR_ROAMING_STATE_JOINED, session_id);
+
+		/*
+		 * Make sure the Set Context is issued before link
+		 * indication to NDIS.  After link indication is
+		 * made to NDIS, frames could start flowing.
+		 * If we have not set context with LIM, the frames
+		 * will be dropped for the security context may not
+		 * be set properly.
+		 *
+		 * this was causing issues in the 2c_wlan_wep WHQL test
+		 * when the SetContext was issued after the link
+		 * indication. (Link Indication happens in the
+		 * profFSMSetConnectedInfra call).
+		 *
+		 * this reordering was done on titan_prod_usb branch
+		 * and is being replicated here.
+		 */
+
+		if (CSR_IS_ENC_TYPE_STATIC
+			(profile->negotiatedUCEncryptionType) &&
+			!profile->bWPSAssociation) {
+			/*
+			 * Issue the set Context request to LIM to establish
+			 * the Unicast STA context
+			 */
+			if (!QDF_IS_STATUS_SUCCESS(
+				csr_roam_issue_set_context_req(mac_ctx,
+					session_id,
+					profile->negotiatedUCEncryptionType,
+					bss_desc, &(bss_desc->bssId),
+					false, true,
+					eSIR_TX_RX, 0, 0, NULL, 0))) {
+				/* NO keys. these key parameters don't matter */
+				sme_err("Set context for unicast fail");
+				csr_roam_substate_change(mac_ctx,
+					eCSR_ROAM_SUBSTATE_NONE, session_id);
+			}
+			/*
+			 * Issue the set Context request to LIM
+			 * to establish the Broadcast STA context
+			 * NO keys. these key parameters don't matter
+			 */
+			csr_roam_issue_set_context_req(mac_ctx, session_id,
+				profile->negotiatedMCEncryptionType,
+				bss_desc, &bcast_mac, false, false,
+				eSIR_TX_RX, 0, 0, NULL, 0);
+		} else if (CSR_IS_AUTH_TYPE_FILS(profile->negotiatedAuthType)
+				&& join_rsp->is_fils_connection) {
+			roam_info.is_fils_connection = true;
+			csr_process_fils_join_rsp(mac_ctx, profile, session_id,
+				&roam_info, bss_desc, join_rsp);
+		} else {
+			/* Need to wait for supplicant authtication */
+			roam_info.fAuthRequired = true;
+			/*
+			 * Set the substate to WaitForKey in case
+			 * authentiation is needed
+			 */
+			csr_roam_substate_change(mac_ctx,
+					eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY,
+					session_id);
+
+			/*
+			 * Set remain_in_power_active_till_dhcp to make
+			 * sure we wait for until keys are set before
+			 * going into BMPS.
+			 */
+			ps_global_info->remain_in_power_active_till_dhcp
+				= true;
+
+			if (profile->bWPSAssociation)
+				key_timeout_interval =
+					CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD;
+			else
+				key_timeout_interval =
+					CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD;
+
+			/* Save session_id in case of timeout */
+			mac_ctx->roam.WaitForKeyTimerInfo.sessionId =
+				(uint8_t) session_id;
+			/*
+			 * This time should be long enough for the rest
+			 * of the process plus setting key
+			 */
+			if (!QDF_IS_STATUS_SUCCESS
+					(csr_roam_start_wait_for_key_timer(
+					   mac_ctx, key_timeout_interval))
+			   ) {
+				/* Reset state so nothing is blocked. */
+				sme_err("Failed preauth timer start");
+				csr_roam_substate_change(mac_ctx,
+						eCSR_ROAM_SUBSTATE_NONE,
+						session_id);
+			}
+		}
+
+		assoc_info.pBssDesc = bss_desc;       /* could be NULL */
+		assoc_info.pProfile = profile;
+		if (context) {
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+			if (session->roam_synch_in_progress)
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_DEBUG,
+					FL("LFR3:Clear Connected info"));
+#endif
+			csr_roam_free_connected_info(mac_ctx,
+				&session->connectedInfo);
+			len = join_rsp->assocReqLength +
+				join_rsp->assocRspLength +
+				join_rsp->beaconLength;
+			len += join_rsp->parsedRicRspLen;
+#ifdef FEATURE_WLAN_ESE
+			len += join_rsp->tspecIeLen;
+#endif
+			if (len) {
+				session->connectedInfo.pbFrames =
+					qdf_mem_malloc(len);
+				if (session->connectedInfo.pbFrames !=
+						NULL) {
+					qdf_mem_copy(
+						session->connectedInfo.pbFrames,
+						join_rsp->frames, len);
+					session->connectedInfo.nAssocReqLength =
+						join_rsp->assocReqLength;
+					session->connectedInfo.nAssocRspLength =
+						join_rsp->assocRspLength;
+					session->connectedInfo.nBeaconLength =
+						join_rsp->beaconLength;
+					session->connectedInfo.nRICRspLength =
+						join_rsp->parsedRicRspLen;
+#ifdef FEATURE_WLAN_ESE
+					session->connectedInfo.nTspecIeLength =
+						join_rsp->tspecIeLen;
+#endif
+					roam_info.nAssocReqLength =
+						join_rsp->assocReqLength;
+					roam_info.nAssocRspLength =
+						join_rsp->assocRspLength;
+					roam_info.nBeaconLength =
+						join_rsp->beaconLength;
+					roam_info.pbFrames =
+						session->connectedInfo.pbFrames;
+				}
+			}
+			if (cmd->u.roamCmd.fReassoc)
+				roam_info.fReassocReq =
+					roam_info.fReassocRsp = true;
+			conn_profile->vht_channel_width =
+				join_rsp->vht_channel_width;
+			session->connectedInfo.staId =
+				(uint8_t) join_rsp->staId;
+			roam_info.staId = (uint8_t) join_rsp->staId;
+			roam_info.timingMeasCap = join_rsp->timingMeasCap;
+			roam_info.chan_info.nss = join_rsp->nss;
+			roam_info.chan_info.rate_flags =
+				join_rsp->max_rate_flags;
+			roam_info.chan_info.ch_width =
+				join_rsp->vht_channel_width;
+#ifdef FEATURE_WLAN_TDLS
+			roam_info.tdls_prohibited = join_rsp->tdls_prohibited;
+			roam_info.tdls_chan_swit_prohibited =
+				join_rsp->tdls_chan_swit_prohibited;
+			sme_debug("tdls:prohibit: %d chan_swit_prohibit: %d",
+				roam_info.tdls_prohibited,
+				roam_info.tdls_chan_swit_prohibited);
+#endif
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+			src_profile = &join_rsp->HTProfile;
+			dst_profile = &conn_profile->HTProfile;
+			if (mac_ctx->roam.configParam.cc_switch_mode
+				!= QDF_MCC_TO_SCC_SWITCH_DISABLE)
+				csr_roam_copy_ht_profile(dst_profile,
+						src_profile);
+#endif
+			roam_info.vht_caps = join_rsp->vht_caps;
+			roam_info.ht_caps = join_rsp->ht_caps;
+			roam_info.hs20vendor_ie = join_rsp->hs20vendor_ie;
+			roam_info.ht_operation = join_rsp->ht_operation;
+			roam_info.vht_operation = join_rsp->vht_operation;
+		} else {
+			if (cmd->u.roamCmd.fReassoc) {
+				roam_info.fReassocReq =
+					roam_info.fReassocRsp = true;
+				roam_info.nAssocReqLength =
+					session->connectedInfo.nAssocReqLength;
+				roam_info.nAssocRspLength =
+					session->connectedInfo.nAssocRspLength;
+				roam_info.nBeaconLength =
+					session->connectedInfo.nBeaconLength;
+				roam_info.pbFrames =
+					session->connectedInfo.pbFrames;
+			}
+		}
+		/*
+		 * Update the staId from the previous connected profile info
+		 * as the reassociation is triggred at SME/HDD
+		 */
+
+		if ((eCsrHddIssuedReassocToSameAP ==
+				cmd->u.roamCmd.roamReason) ||
+			(eCsrSmeIssuedReassocToSameAP ==
+				cmd->u.roamCmd.roamReason))
+			roam_info.staId = session->connectedInfo.staId;
+
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		/*
+		 * Indicate SME-QOS with reassoc success event,
+		 * only after copying the frames
+		 */
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id, ind_qos,
+				&assoc_info);
+#endif
+		roam_info.pBssDesc = bss_desc;
+		roam_info.statusCode =
+			session->joinFailStatusCode.statusCode;
+		roam_info.reasonCode =
+			session->joinFailStatusCode.reasonCode;
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		acm_mask = sme_qos_get_acm_mask(mac_ctx, bss_desc, NULL);
+#endif
+		conn_profile->acm_mask = acm_mask;
+		/*
+		 * start UAPSD if uapsd_mask is not 0 because HDD will
+		 * configure for trigger frame It may be better to let QoS do
+		 * this????
+		 */
+		if (conn_profile->modifyProfileFields.uapsd_mask) {
+			sme_err(
+				" uapsd_mask (0x%X) set, request UAPSD now",
+				conn_profile->modifyProfileFields.uapsd_mask);
+			sme_ps_start_uapsd(MAC_HANDLE(mac_ctx), session_id);
+		}
+		conn_profile->dot11Mode = session->bssParams.uCfgDot11Mode;
+		roam_info.u.pConnectedProfile = conn_profile;
+
+		if (session->bRefAssocStartCnt > 0) {
+			session->bRefAssocStartCnt--;
+			if (!IS_FEATURE_SUPPORTED_BY_FW
+				(SLM_SESSIONIZATION) &&
+				(csr_is_concurrent_session_running(mac_ctx))) {
+				mac_ctx->roam.configParam.doBMPSWorkaround = 1;
+			}
+			csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				eCSR_ROAM_ASSOCIATION_COMPLETION,
+				eCSR_ROAM_RESULT_ASSOCIATED);
+		}
+
+		qdf_copy_macaddr(&bss_info.bssid, &conn_profile->bssid);
+		bss_info.chan = conn_profile->operationChannel;
+		bss_info.ssid.length =
+			conn_profile->SSID.length;
+		qdf_mem_copy(&bss_info.ssid.ssid,
+			&conn_profile->SSID.ssId,
+			bss_info.ssid.length);
+		csr_update_scan_entry_associnfo(mac_ctx,
+					&bss_info, SCAN_ENTRY_CON_STATE_ASSOC);
+		csr_roam_completion(mac_ctx, session_id, NULL, cmd,
+				eCSR_ROAM_RESULT_NONE, true);
+		csr_reset_pmkid_candidate_list(mac_ctx, session_id);
+#ifdef FEATURE_WLAN_WAPI
+		csr_reset_bkid_candidate_list(mac_ctx, session_id);
+#endif
+	} else {
+		sme_warn("Roam command doesn't have a BSS desc");
+	}
+	/* Not to signal link up because keys are yet to be set.
+	 * The linkup function will overwrite the sub-state that
+	 * we need to keep at this point.
+	 */
+	if (!CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id)) {
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		if (session->roam_synch_in_progress) {
+			QDF_TRACE(QDF_MODULE_ID_SME,
+				QDF_TRACE_LEVEL_DEBUG,
+				FL
+				("NO CSR_IS_WAIT_FOR_KEY -> csr_roam_link_up"));
+		}
+#endif
+		csr_roam_link_up(mac_ctx, conn_profile->bssid);
+	}
+	sme_free_join_rsp_fils_params(&roam_info);
+}
+
+/**
+ * csr_roam_process_results() - Process the Roam Results
+ * @mac_ctx:      Global MAC Context
+ * @cmd:          Command that has been processed
+ * @res:          Results available after processing the command
+ * @context:      Context
+ *
+ * Process the available results and make an appropriate decision
+ *
+ * Return: true if the command can be released, else not.
+ */
+static bool csr_roam_process_results(tpAniSirGlobal mac_ctx, tSmeCmd *cmd,
+				     enum csr_roamcomplete_result res,
+					void *context)
+{
+	bool release_cmd = true;
+	tSirBssDescription *bss_desc = NULL;
+	struct csr_roam_info roam_info;
+	uint32_t session_id = cmd->sessionId;
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+	struct csr_roam_profile *profile = &cmd->u.roamCmd.roamProfile;
+	eRoamCmdStatus roam_status;
+	eCsrRoamResult roam_result;
+	host_log_ibss_pkt_type *ibss_log;
+	tSirSmeStartBssRsp  *start_bss_rsp = NULL;
+
+	if (!session) {
+		sme_err("session %d not found ", session_id);
+		return false;
+	}
+
+	sme_debug("Processing ROAM results...");
+	switch (res) {
+	case eCsrJoinSuccess:
+	case eCsrReassocSuccess:
+		csr_roam_process_join_res(mac_ctx, res, cmd, context);
+		break;
+	case eCsrStartBssSuccess:
+		csr_roam_process_start_bss_success(mac_ctx, cmd, context);
+		break;
+	case eCsrStartBssFailure:
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+		WLAN_HOST_DIAG_LOG_ALLOC(ibss_log,
+			host_log_ibss_pkt_type, LOG_WLAN_IBSS_C);
+		if (ibss_log) {
+			ibss_log->status = WLAN_IBSS_STATUS_FAILURE;
+			WLAN_HOST_DIAG_LOG_REPORT(ibss_log);
+		}
+#endif
+		ibss_log = NULL;
+		start_bss_rsp = (tSirSmeStartBssRsp *)context;
+		qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+		roam_status = eCSR_ROAM_IBSS_IND;
+		roam_result = eCSR_ROAM_RESULT_IBSS_STARTED;
+		if (CSR_IS_INFRA_AP(profile)) {
+			roam_status = eCSR_ROAM_INFRA_IND;
+			roam_result = eCSR_ROAM_RESULT_INFRA_START_FAILED;
+		}
+		if (CSR_IS_NDI(profile)) {
+			csr_roam_update_ndp_return_params(mac_ctx,
+				eCsrStartBssFailure,
+				&roam_status, &roam_result, &roam_info);
+		}
+
+		if (context)
+			bss_desc = (tSirBssDescription *) context;
+		else
+			bss_desc = NULL;
+		roam_info.pBssDesc = bss_desc;
+		csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId, roam_status,
+				roam_result);
+		csr_set_default_dot11_mode(mac_ctx);
+		break;
+	case eCsrSilentlyStopRoaming:
+		/*
+		 * We are here because we try to start the same IBSS.
+		 * No message to PE. return the roaming state to Joined.
+		 */
+		sme_debug("receives silently stop roam ind");
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
+			session_id);
+		csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE,
+			session_id);
+		qdf_mem_set(&roam_info, sizeof(struct csr_roam_info), 0);
+		roam_info.pBssDesc = session->pConnectBssDesc;
+		if (roam_info.pBssDesc)
+			qdf_mem_copy(&roam_info.bssid,
+				&roam_info.pBssDesc->bssId,
+				sizeof(struct qdf_mac_addr));
+		/*
+		 * Since there is no change in the current state, simply pass
+		 * back no result otherwise HDD may be mistakenly mark to
+		 * disconnected state.
+		 */
+		csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				eCSR_ROAM_IBSS_IND, eCSR_ROAM_RESULT_NONE);
+		break;
+	case eCsrSilentlyStopRoamingSaveState:
+		/* We are here because we try to connect to the same AP */
+		/* No message to PE */
+		sme_debug("receives silently stop roaming indication");
+		qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+
+		/* to aviod resetting the substate to NONE */
+		mac_ctx->roam.curState[session_id] = eCSR_ROAMING_STATE_JOINED;
+		/*
+		 * No need to change substate to wai_for_key because there
+		 * is no state change
+		 */
+		roam_info.pBssDesc = session->pConnectBssDesc;
+		if (roam_info.pBssDesc)
+			qdf_mem_copy(&roam_info.bssid,
+				&roam_info.pBssDesc->bssId,
+				sizeof(struct qdf_mac_addr));
+		roam_info.statusCode = session->joinFailStatusCode.statusCode;
+		roam_info.reasonCode = session->joinFailStatusCode.reasonCode;
+		roam_info.nBeaconLength = session->connectedInfo.nBeaconLength;
+		roam_info.nAssocReqLength =
+			session->connectedInfo.nAssocReqLength;
+		roam_info.nAssocRspLength =
+			session->connectedInfo.nAssocRspLength;
+		roam_info.pbFrames = session->connectedInfo.pbFrames;
+		roam_info.staId = session->connectedInfo.staId;
+		roam_info.u.pConnectedProfile = &session->connectedProfile;
+		if (0 == roam_info.staId)
+			QDF_ASSERT(0);
+
+		session->bRefAssocStartCnt--;
+		csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				eCSR_ROAM_ASSOCIATION_COMPLETION,
+				eCSR_ROAM_RESULT_ASSOCIATED);
+		csr_roam_completion(mac_ctx, session_id, NULL, cmd,
+				eCSR_ROAM_RESULT_ASSOCIATED, true);
+		break;
+	case eCsrReassocFailure:
+		/*
+		 * Currently Reassoc failure is handled through eCsrJoinFailure
+		 * Need to revisit for eCsrReassocFailure handling
+		 */
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
+				SME_QOS_CSR_REASSOC_FAILURE, NULL);
+#endif
+		break;
+	case eCsrStopBssSuccess:
+		if (CSR_IS_NDI(profile)) {
+			qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+			csr_roam_update_ndp_return_params(mac_ctx, res,
+				&roam_status, &roam_result, &roam_info);
+			csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				roam_status, roam_result);
+		}
+		break;
+	case eCsrStopBssFailure:
+		if (CSR_IS_NDI(profile)) {
+			qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+			csr_roam_update_ndp_return_params(mac_ctx, res,
+				&roam_status, &roam_result, &roam_info);
+			csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				roam_status, roam_result);
+		}
+		break;
+	case eCsrJoinFailure:
+	case eCsrNothingToJoin:
+	case eCsrJoinFailureDueToConcurrency:
+	default:
+		csr_roam_process_results_default(mac_ctx, cmd, context, res);
+		break;
+	}
+	return release_cmd;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/*
+ * update_profile_fils_info: API to update FILS info from
+ * source profile to destination profile.
+ * @des_profile: pointer to destination profile
+ * @src_profile: pointer to souce profile
+ *
+ * Return: None
+ */
+static void update_profile_fils_info(struct csr_roam_profile *des_profile,
+				     struct csr_roam_profile *src_profile)
+{
+	if (!src_profile || !src_profile->fils_con_info)
+		return;
+
+	sme_debug("is fils %d", src_profile->fils_con_info->is_fils_connection);
+
+	if (!src_profile->fils_con_info->is_fils_connection)
+		return;
+
+	des_profile->fils_con_info =
+		qdf_mem_malloc(sizeof(struct cds_fils_connection_info));
+	if (!des_profile->fils_con_info)
+		return;
+
+	qdf_mem_copy(des_profile->fils_con_info,
+			src_profile->fils_con_info,
+			sizeof(struct cds_fils_connection_info));
+
+	des_profile->hlp_ie =
+		qdf_mem_malloc(src_profile->hlp_ie_len);
+	if (!des_profile->hlp_ie)
+		return;
+
+	qdf_mem_copy(des_profile->hlp_ie, src_profile->hlp_ie,
+		     src_profile->hlp_ie_len);
+	des_profile->hlp_ie_len = src_profile->hlp_ie_len;
+}
+#else
+static inline
+void update_profile_fils_info(struct csr_roam_profile *des_profile,
+			      struct csr_roam_profile *src_profile)
+{ }
+#endif
+QDF_STATUS csr_roam_copy_profile(tpAniSirGlobal pMac,
+				 struct csr_roam_profile *pDstProfile,
+				 struct csr_roam_profile *pSrcProfile)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t size = 0;
+
+	qdf_mem_set(pDstProfile, sizeof(struct csr_roam_profile), 0);
+	if (pSrcProfile->BSSIDs.numOfBSSIDs) {
+		size = sizeof(struct qdf_mac_addr) * pSrcProfile->BSSIDs.
+								numOfBSSIDs;
+		pDstProfile->BSSIDs.bssid = qdf_mem_malloc(size);
+		if (NULL == pDstProfile->BSSIDs.bssid) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->BSSIDs.numOfBSSIDs =
+			pSrcProfile->BSSIDs.numOfBSSIDs;
+		qdf_mem_copy(pDstProfile->BSSIDs.bssid,
+			pSrcProfile->BSSIDs.bssid, size);
+	}
+	if (pSrcProfile->SSIDs.numOfSSIDs) {
+		size = sizeof(tCsrSSIDInfo) * pSrcProfile->SSIDs.numOfSSIDs;
+		pDstProfile->SSIDs.SSIDList = qdf_mem_malloc(size);
+		if (NULL == pDstProfile->SSIDs.SSIDList) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->SSIDs.numOfSSIDs =
+			pSrcProfile->SSIDs.numOfSSIDs;
+		qdf_mem_copy(pDstProfile->SSIDs.SSIDList,
+			pSrcProfile->SSIDs.SSIDList, size);
+	}
+	if (pSrcProfile->nWPAReqIELength) {
+		pDstProfile->pWPAReqIE =
+			qdf_mem_malloc(pSrcProfile->nWPAReqIELength);
+		if (NULL == pDstProfile->pWPAReqIE) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->nWPAReqIELength =
+			pSrcProfile->nWPAReqIELength;
+		qdf_mem_copy(pDstProfile->pWPAReqIE, pSrcProfile->pWPAReqIE,
+			pSrcProfile->nWPAReqIELength);
+	}
+	if (pSrcProfile->nRSNReqIELength) {
+		pDstProfile->pRSNReqIE =
+			qdf_mem_malloc(pSrcProfile->nRSNReqIELength);
+		if (NULL == pDstProfile->pRSNReqIE) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->nRSNReqIELength =
+			pSrcProfile->nRSNReqIELength;
+		qdf_mem_copy(pDstProfile->pRSNReqIE, pSrcProfile->pRSNReqIE,
+			pSrcProfile->nRSNReqIELength);
+	}
+#ifdef FEATURE_WLAN_WAPI
+	if (pSrcProfile->nWAPIReqIELength) {
+		pDstProfile->pWAPIReqIE =
+			qdf_mem_malloc(pSrcProfile->nWAPIReqIELength);
+		if (NULL == pDstProfile->pWAPIReqIE) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->nWAPIReqIELength =
+			pSrcProfile->nWAPIReqIELength;
+		qdf_mem_copy(pDstProfile->pWAPIReqIE, pSrcProfile->pWAPIReqIE,
+			pSrcProfile->nWAPIReqIELength);
+	}
+#endif /* FEATURE_WLAN_WAPI */
+	if (pSrcProfile->nAddIEScanLength) {
+		pDstProfile->pAddIEScan =
+			qdf_mem_malloc(pSrcProfile->nAddIEScanLength);
+		if (NULL == pDstProfile->pAddIEScan) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->nAddIEScanLength =
+			pSrcProfile->nAddIEScanLength;
+		qdf_mem_copy(pDstProfile->pAddIEScan, pSrcProfile->pAddIEScan,
+			pSrcProfile->nAddIEScanLength);
+	}
+	if (pSrcProfile->nAddIEAssocLength) {
+		pDstProfile->pAddIEAssoc =
+			qdf_mem_malloc(pSrcProfile->nAddIEAssocLength);
+		if (NULL == pDstProfile->pAddIEAssoc) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->nAddIEAssocLength =
+			pSrcProfile->nAddIEAssocLength;
+		qdf_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc,
+			pSrcProfile->nAddIEAssocLength);
+	}
+	if (pSrcProfile->ChannelInfo.ChannelList) {
+		pDstProfile->ChannelInfo.ChannelList =
+			qdf_mem_malloc(pSrcProfile->ChannelInfo.
+					numOfChannels);
+		if (NULL == pDstProfile->ChannelInfo.ChannelList) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->ChannelInfo.numOfChannels =
+			pSrcProfile->ChannelInfo.numOfChannels;
+		qdf_mem_copy(pDstProfile->ChannelInfo.ChannelList,
+			pSrcProfile->ChannelInfo.ChannelList,
+			pSrcProfile->ChannelInfo.numOfChannels);
+	}
+	pDstProfile->AuthType = pSrcProfile->AuthType;
+	pDstProfile->EncryptionType = pSrcProfile->EncryptionType;
+	pDstProfile->mcEncryptionType = pSrcProfile->mcEncryptionType;
+	pDstProfile->negotiatedUCEncryptionType =
+		pSrcProfile->negotiatedUCEncryptionType;
+	pDstProfile->negotiatedMCEncryptionType =
+		pSrcProfile->negotiatedMCEncryptionType;
+	pDstProfile->negotiatedAuthType = pSrcProfile->negotiatedAuthType;
+#ifdef WLAN_FEATURE_11W
+	pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled;
+	pDstProfile->MFPRequired = pSrcProfile->MFPRequired;
+	pDstProfile->MFPCapable = pSrcProfile->MFPCapable;
+#endif
+	pDstProfile->BSSType = pSrcProfile->BSSType;
+	pDstProfile->phyMode = pSrcProfile->phyMode;
+	pDstProfile->csrPersona = pSrcProfile->csrPersona;
+
+#ifdef FEATURE_WLAN_WAPI
+	if (csr_is_profile_wapi(pSrcProfile))
+		if (pDstProfile->phyMode & eCSR_DOT11_MODE_11n)
+			pDstProfile->phyMode &= ~eCSR_DOT11_MODE_11n;
+#endif /* FEATURE_WLAN_WAPI */
+	pDstProfile->ch_params.ch_width = pSrcProfile->ch_params.ch_width;
+	pDstProfile->ch_params.center_freq_seg0 =
+		pSrcProfile->ch_params.center_freq_seg0;
+	pDstProfile->ch_params.center_freq_seg1 =
+		pSrcProfile->ch_params.center_freq_seg1;
+	pDstProfile->ch_params.sec_ch_offset =
+		pSrcProfile->ch_params.sec_ch_offset;
+	/*Save the WPS info */
+	pDstProfile->bWPSAssociation = pSrcProfile->bWPSAssociation;
+	pDstProfile->bOSENAssociation = pSrcProfile->bOSENAssociation;
+	pDstProfile->force_24ghz_in_ht20 = pSrcProfile->force_24ghz_in_ht20;
+	pDstProfile->uapsd_mask = pSrcProfile->uapsd_mask;
+	pDstProfile->beaconInterval = pSrcProfile->beaconInterval;
+	pDstProfile->privacy = pSrcProfile->privacy;
+	pDstProfile->fwdWPSPBCProbeReq = pSrcProfile->fwdWPSPBCProbeReq;
+	pDstProfile->csr80211AuthType = pSrcProfile->csr80211AuthType;
+	pDstProfile->dtimPeriod = pSrcProfile->dtimPeriod;
+	pDstProfile->ApUapsdEnable = pSrcProfile->ApUapsdEnable;
+	pDstProfile->SSIDs.SSIDList[0].ssidHidden =
+		pSrcProfile->SSIDs.SSIDList[0].ssidHidden;
+	pDstProfile->protEnabled = pSrcProfile->protEnabled;
+	pDstProfile->obssProtEnabled = pSrcProfile->obssProtEnabled;
+	pDstProfile->cfg_protection = pSrcProfile->cfg_protection;
+	pDstProfile->wps_state = pSrcProfile->wps_state;
+	pDstProfile->ieee80211d = pSrcProfile->ieee80211d;
+	pDstProfile->supplicant_disabled_roaming =
+		pSrcProfile->supplicant_disabled_roaming;
+	qdf_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys,
+		sizeof(pDstProfile->Keys));
+#ifdef WLAN_FEATURE_11W
+	pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled;
+	pDstProfile->MFPRequired = pSrcProfile->MFPRequired;
+	pDstProfile->MFPCapable = pSrcProfile->MFPCapable;
+#endif
+	if (pSrcProfile->MDID.mdiePresent) {
+		pDstProfile->MDID.mdiePresent = 1;
+		pDstProfile->MDID.mobilityDomain =
+			pSrcProfile->MDID.mobilityDomain;
+	}
+	qdf_mem_copy(&pDstProfile->addIeParams, &pSrcProfile->addIeParams,
+			sizeof(tSirAddIeParams));
+
+	update_profile_fils_info(pDstProfile, pSrcProfile);
+
+	pDstProfile->beacon_tx_rate = pSrcProfile->beacon_tx_rate;
+
+	if (pSrcProfile->supported_rates.numRates) {
+		qdf_mem_copy(pDstProfile->supported_rates.rate,
+				pSrcProfile->supported_rates.rate,
+				pSrcProfile->supported_rates.numRates);
+		pDstProfile->supported_rates.numRates =
+			pSrcProfile->supported_rates.numRates;
+	}
+	if (pSrcProfile->extended_rates.numRates) {
+		qdf_mem_copy(pDstProfile->extended_rates.rate,
+				pSrcProfile->extended_rates.rate,
+				pSrcProfile->extended_rates.numRates);
+		pDstProfile->extended_rates.numRates =
+			pSrcProfile->extended_rates.numRates;
+	}
+	pDstProfile->cac_duration_ms = pSrcProfile->cac_duration_ms;
+	pDstProfile->dfs_regdomain   = pSrcProfile->dfs_regdomain;
+	pDstProfile->chan_switch_hostapd_rate_enabled  =
+		pSrcProfile->chan_switch_hostapd_rate_enabled;
+	pDstProfile->force_rsne_override = pSrcProfile->force_rsne_override;
+end:
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		csr_release_profile(pMac, pDstProfile);
+		pDstProfile = NULL;
+	}
+
+	return status;
+}
+
+QDF_STATUS csr_roam_copy_connected_profile(tpAniSirGlobal pMac,
+					   uint32_t sessionId,
+					   struct csr_roam_profile *pDstProfile)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tCsrRoamConnectedProfile *pSrcProfile =
+		&pMac->roam.roamSession[sessionId].connectedProfile;
+
+	qdf_mem_set(pDstProfile, sizeof(struct csr_roam_profile), 0);
+
+	pDstProfile->BSSIDs.bssid = qdf_mem_malloc(sizeof(struct qdf_mac_addr));
+	if (!pDstProfile->BSSIDs.bssid) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+	pDstProfile->BSSIDs.numOfBSSIDs = 1;
+	qdf_copy_macaddr(pDstProfile->BSSIDs.bssid, &pSrcProfile->bssid);
+
+	if (pSrcProfile->SSID.length > 0) {
+		pDstProfile->SSIDs.SSIDList =
+			qdf_mem_malloc(sizeof(tCsrSSIDInfo));
+		if (!pDstProfile->SSIDs.SSIDList) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->SSIDs.numOfSSIDs = 1;
+		pDstProfile->SSIDs.SSIDList[0].handoffPermitted =
+			pSrcProfile->handoffPermitted;
+		pDstProfile->SSIDs.SSIDList[0].ssidHidden =
+			pSrcProfile->ssidHidden;
+		qdf_mem_copy(&pDstProfile->SSIDs.SSIDList[0].SSID,
+			&pSrcProfile->SSID, sizeof(tSirMacSSid));
+	}
+	if (pSrcProfile->nAddIEAssocLength) {
+		pDstProfile->pAddIEAssoc =
+			qdf_mem_malloc(pSrcProfile->nAddIEAssocLength);
+		if (!pDstProfile->pAddIEAssoc) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->nAddIEAssocLength = pSrcProfile->nAddIEAssocLength;
+		qdf_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc,
+			pSrcProfile->nAddIEAssocLength);
+	}
+	pDstProfile->ChannelInfo.ChannelList = qdf_mem_malloc(1);
+	if (NULL == pDstProfile->ChannelInfo.ChannelList) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+	pDstProfile->ChannelInfo.numOfChannels = 1;
+	pDstProfile->ChannelInfo.ChannelList[0] = pSrcProfile->operationChannel;
+	pDstProfile->AuthType.numEntries = 1;
+	pDstProfile->AuthType.authType[0] = pSrcProfile->AuthType;
+	pDstProfile->negotiatedAuthType = pSrcProfile->AuthType;
+	pDstProfile->EncryptionType.numEntries = 1;
+	pDstProfile->EncryptionType.encryptionType[0] =
+		pSrcProfile->EncryptionType;
+	pDstProfile->negotiatedUCEncryptionType =
+		pSrcProfile->EncryptionType;
+	pDstProfile->mcEncryptionType.numEntries = 1;
+	pDstProfile->mcEncryptionType.encryptionType[0] =
+		pSrcProfile->mcEncryptionType;
+	pDstProfile->negotiatedMCEncryptionType =
+		pSrcProfile->mcEncryptionType;
+	pDstProfile->BSSType = pSrcProfile->BSSType;
+	qdf_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys,
+		sizeof(pDstProfile->Keys));
+	if (pSrcProfile->MDID.mdiePresent) {
+		pDstProfile->MDID.mdiePresent = 1;
+		pDstProfile->MDID.mobilityDomain =
+			pSrcProfile->MDID.mobilityDomain;
+	}
+#ifdef WLAN_FEATURE_11W
+	pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled;
+	pDstProfile->MFPRequired = pSrcProfile->MFPRequired;
+	pDstProfile->MFPCapable = pSrcProfile->MFPCapable;
+#endif
+
+end:
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		csr_release_profile(pMac, pDstProfile);
+		pDstProfile = NULL;
+	}
+
+	return status;
+}
+
+QDF_STATUS csr_roam_issue_connect(tpAniSirGlobal pMac, uint32_t sessionId,
+				  struct csr_roam_profile *pProfile,
+				  tScanResultHandle hBSSList,
+				  enum csr_roam_reason reason, uint32_t roamId,
+				  bool fImediate, bool fClearScan)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+
+	pCommand = csr_get_command_buffer(pMac);
+	if (NULL == pCommand) {
+		csr_scan_result_purge(pMac, hBSSList);
+		sme_err(" fail to get command buffer");
+		status = QDF_STATUS_E_RESOURCES;
+	} else {
+		if (fClearScan)
+			csr_scan_abort_mac_scan(pMac, sessionId, INVAL_SCAN_ID);
+
+		pCommand->u.roamCmd.fReleaseProfile = false;
+		if (NULL == pProfile) {
+			/* We can roam now
+			 * Since pProfile is NULL, we need to build our own
+			 * profile, set everything to default We can only
+			 * support open and no encryption
+			 */
+			pCommand->u.roamCmd.roamProfile.AuthType.numEntries = 1;
+			pCommand->u.roamCmd.roamProfile.AuthType.authType[0] =
+				eCSR_AUTH_TYPE_OPEN_SYSTEM;
+			pCommand->u.roamCmd.roamProfile.EncryptionType.
+			numEntries = 1;
+			pCommand->u.roamCmd.roamProfile.EncryptionType.
+			encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
+			pCommand->u.roamCmd.roamProfile.csrPersona =
+				QDF_STA_MODE;
+		} else {
+			/* make a copy of the profile */
+			status = csr_roam_copy_profile(pMac, &pCommand->u.
+							roamCmd.roamProfile,
+						      pProfile);
+			if (QDF_IS_STATUS_SUCCESS(status))
+				pCommand->u.roamCmd.fReleaseProfile = true;
+		}
+
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.hBSSList = hBSSList;
+		pCommand->u.roamCmd.roamId = roamId;
+		pCommand->u.roamCmd.roamReason = reason;
+		/* We need to free the BssList when the command is done */
+		pCommand->u.roamCmd.fReleaseBssList = true;
+		pCommand->u.roamCmd.fUpdateCurRoamProfile = true;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			 FL("CSR PERSONA=%d"),
+			  pCommand->u.roamCmd.roamProfile.csrPersona);
+		status = csr_queue_sme_command(pMac, pCommand, fImediate);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("fail to send message status: %d", status);
+		}
+	}
+
+	return status;
+}
+
+QDF_STATUS csr_roam_issue_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
+				  struct csr_roam_profile *pProfile,
+				  tCsrRoamModifyProfileFields
+				*pMmodProfileFields,
+				  enum csr_roam_reason reason, uint32_t roamId,
+				  bool fImediate)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+
+	pCommand = csr_get_command_buffer(pMac);
+	if (NULL == pCommand) {
+		sme_err("fail to get command buffer");
+		status = QDF_STATUS_E_RESOURCES;
+	} else {
+		csr_scan_abort_mac_scan(pMac, sessionId, INVAL_SCAN_ID);
+		if (pProfile) {
+			/* This is likely trying to reassoc to
+			 * different profile
+			 */
+			pCommand->u.roamCmd.fReleaseProfile = false;
+			/* make a copy of the profile */
+			status = csr_roam_copy_profile(pMac, &pCommand->u.
+							roamCmd.roamProfile,
+						      pProfile);
+			pCommand->u.roamCmd.fUpdateCurRoamProfile = true;
+		} else {
+			status = csr_roam_copy_connected_profile(pMac,
+							sessionId,
+							&pCommand->u.roamCmd.
+							roamProfile);
+			/* how to update WPA/WPA2 info in roamProfile?? */
+			pCommand->u.roamCmd.roamProfile.uapsd_mask =
+				pMmodProfileFields->uapsd_mask;
+		}
+		if (QDF_IS_STATUS_SUCCESS(status))
+			pCommand->u.roamCmd.fReleaseProfile = true;
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.roamId = roamId;
+		pCommand->u.roamCmd.roamReason = reason;
+		/* We need to free the BssList when the command is done */
+		/* For reassoc there is no BSS list, so the bool set to false */
+		pCommand->u.roamCmd.hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
+		pCommand->u.roamCmd.fReleaseBssList = false;
+		pCommand->u.roamCmd.fReassoc = true;
+		csr_roam_remove_duplicate_command(pMac, sessionId, pCommand,
+						  reason);
+		status = csr_queue_sme_command(pMac, pCommand, fImediate);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("fail to send message status = %d", status);
+			csr_roam_completion(pMac, sessionId, NULL, NULL,
+					    eCSR_ROAM_RESULT_FAILURE, false);
+		}
+	}
+	return status;
+}
+
+QDF_STATUS csr_dequeue_roam_command(tpAniSirGlobal pMac,
+			enum csr_roam_reason reason,
+					uint8_t session_id)
+{
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+
+	pEntry = csr_nonscan_active_ll_peek_head(pMac, LL_ACCESS_LOCK);
+
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if ((eSmeCommandRoam == pCommand->command) &&
+		    (eCsrPerformPreauth == reason)) {
+			sme_debug("DQ-Command = %d, Reason = %d",
+				pCommand->command,
+				pCommand->u.roamCmd.roamReason);
+			if (csr_nonscan_active_ll_remove_entry(pMac, pEntry,
+				    LL_ACCESS_LOCK)) {
+				csr_release_command(pMac, pCommand);
+			}
+		} else if ((eSmeCommandRoam == pCommand->command) &&
+			   (eCsrSmeIssuedFTReassoc == reason)) {
+			sme_debug("DQ-Command = %d, Reason = %d",
+				pCommand->command,
+				pCommand->u.roamCmd.roamReason);
+			if (csr_nonscan_active_ll_remove_entry(pMac, pEntry,
+				    LL_ACCESS_LOCK)) {
+				csr_release_command(pMac, pCommand);
+			}
+		} else {
+			sme_err("Command = %d, Reason = %d ",
+				pCommand->command,
+				pCommand->u.roamCmd.roamReason);
+		}
+	} else {
+		sme_err("pEntry NULL for eWNI_SME_FT_PRE_AUTH_RSP");
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * csr_is_fils_connection() - API to check if FILS connection
+ * @profile: CSR Roam Profile
+ *
+ * Return: true, if fils connection, false otherwise
+ */
+static bool csr_is_fils_connection(struct csr_roam_profile *profile)
+{
+	if (!profile->fils_con_info)
+		return false;
+
+	return profile->fils_con_info->is_fils_connection;
+}
+#else
+static bool csr_is_fils_connection(struct csr_roam_profile *pProfile)
+{
+	return false;
+}
+#endif
+
+/**
+ * csr_roam_print_candidate_aps() - print all candidate AP in sorted
+ * score.
+ * @results: scan result
+ *
+ * Return : void
+ */
+static void csr_roam_print_candidate_aps(tScanResultHandle results)
+{
+	tListElem *entry;
+	struct tag_csrscan_result *bss_desc = NULL;
+	struct scan_result_list *bss_list = NULL;
+
+	if (!results)
+		return;
+	bss_list = (struct scan_result_list *)results;
+	entry = csr_ll_peek_head(&bss_list->List, LL_ACCESS_NOLOCK);
+	while (entry) {
+		bss_desc = GET_BASE_ADDR(entry,
+				struct tag_csrscan_result, Link);
+		sme_debug("BSSID" MAC_ADDRESS_STR "score is %d",
+			  MAC_ADDR_ARRAY(bss_desc->Result.BssDescriptor.bssId),
+			  bss_desc->bss_score);
+
+		entry = csr_ll_next(&bss_list->List, entry,
+				LL_ACCESS_NOLOCK);
+	}
+}
+
+QDF_STATUS csr_roam_connect(tpAniSirGlobal pMac, uint32_t sessionId,
+		struct csr_roam_profile *pProfile,
+		uint32_t *pRoamId)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tScanResultHandle hBSSList;
+	tCsrScanResultFilter *pScanFilter;
+	uint32_t roamId = 0;
+	bool fCallCallback = false;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tSirBssDescription *first_ap_profile;
+	uint8_t channel_id = 0;
+
+	if (NULL == pSession) {
+		sme_err("session does not exist for given sessionId: %d",
+			sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (NULL == pProfile) {
+		sme_err("No profile specified");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	first_ap_profile = qdf_mem_malloc(sizeof(*first_ap_profile));
+	if (!first_ap_profile)
+		return QDF_STATUS_E_NOMEM;
+
+	/* Initialize the count before proceeding with the Join requests */
+	pSession->join_bssid_count = 0;
+	pSession->discon_in_progress = false;
+	pSession->is_fils_connection = csr_is_fils_connection(pProfile);
+	sme_debug(
+		"called  BSSType = %s (%d) authtype = %d  encryType = %d",
+		sme_bss_type_to_string(pProfile->BSSType),
+		pProfile->BSSType, pProfile->AuthType.authType[0],
+		pProfile->EncryptionType.encryptionType[0]);
+	csr_roam_cancel_roaming(pMac, sessionId);
+	csr_scan_abort_mac_scan(pMac, sessionId, INVAL_SCAN_ID);
+	csr_roam_remove_duplicate_command(pMac, sessionId, NULL, eCsrHddIssued);
+	/* Check whether ssid changes */
+	if (csr_is_conn_state_connected(pMac, sessionId) &&
+	    pProfile->SSIDs.numOfSSIDs &&
+	    !csr_is_ssid_in_list(&pSession->connectedProfile.SSID,
+				 &pProfile->SSIDs))
+		csr_roam_issue_disassociate_cmd(pMac, sessionId,
+					eCSR_DISCONNECT_REASON_UNSPECIFIED);
+	/*
+	 * If roamSession.connectState is disconnecting that mean
+	 * disconnect was received with scan for ssid in progress
+	 * and dropped. This state will ensure that connect will
+	 * not be issued from scan for ssid completion. Thus
+	 * if this fresh connect also issue scan for ssid the connect
+	 * command will be dropped assuming disconnect is in progress.
+	 * Thus reset connectState here
+	 */
+	if (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING ==
+			pMac->roam.roamSession[sessionId].connectState)
+		pMac->roam.roamSession[sessionId].connectState =
+			eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+#ifdef FEATURE_WLAN_BTAMP_UT_RF
+	pSession->maxRetryCount = CSR_JOIN_MAX_RETRY_COUNT;
+#endif
+	pScanFilter = qdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (NULL == pScanFilter) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+
+	/* Try to connect to any BSS */
+	if (NULL == pProfile) {
+		/* No encryption */
+		pScanFilter->EncryptionType.numEntries = 1;
+		pScanFilter->EncryptionType.encryptionType[0] =
+			eCSR_ENCRYPT_TYPE_NONE;
+	} else {
+		/* Here is the profile we need to connect to */
+		status = csr_roam_prepare_filter_from_profile(pMac,
+				pProfile, pScanFilter);
+	}
+	roamId = GET_NEXT_ROAM_ID(&pMac->roam);
+	if (pRoamId)
+		*pRoamId = roamId;
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		qdf_mem_free(pScanFilter);
+		goto end;
+	}
+
+	/*Save the WPS info */
+	if (NULL != pProfile) {
+		pScanFilter->bWPSAssociation =
+			pProfile->bWPSAssociation;
+		pScanFilter->bOSENAssociation =
+			pProfile->bOSENAssociation;
+	} else {
+		pScanFilter->bWPSAssociation = 0;
+		pScanFilter->bOSENAssociation = 0;
+	}
+	if (pProfile && CSR_IS_INFRA_AP(pProfile)) {
+		/* This can be started right away */
+		status = csr_roam_issue_connect(pMac, sessionId, pProfile, NULL,
+				 eCsrHddIssued, roamId, false, false);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("CSR failed to issue start BSS cmd with status: 0x%08X",
+				status);
+			fCallCallback = true;
+		} else
+			sme_debug("Connect request to proceed for sap mode");
+
+		csr_free_scan_filter(pMac, pScanFilter);
+		qdf_mem_free(pScanFilter);
+		goto end;
+	}
+	status = csr_scan_get_result(pMac, pScanFilter, &hBSSList);
+	sme_debug("csr_scan_get_result Status: %d", status);
+	csr_roam_print_candidate_aps(hBSSList);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* check if set hw mode needs to be done */
+		if ((pScanFilter->csrPersona == QDF_STA_MODE) ||
+			 (pScanFilter->csrPersona == QDF_P2P_CLIENT_MODE)) {
+			bool ok;
+
+			csr_get_bssdescr_from_scan_handle(hBSSList,
+					first_ap_profile);
+			status = policy_mgr_is_chan_ok_for_dnbs(pMac->psoc,
+					first_ap_profile->channelId, &ok);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				sme_debug("policy_mgr_is_chan_ok_for_dnbs():error:%d",
+					  status);
+				csr_scan_result_purge(pMac, hBSSList);
+				fCallCallback = true;
+				goto error;
+			}
+			if (!ok) {
+				sme_debug("chan:%d not ok for DNBS",
+						first_ap_profile->channelId);
+				csr_scan_result_purge(pMac, hBSSList);
+				fCallCallback = true;
+				status = QDF_STATUS_E_INVAL;
+				goto error;
+			}
+
+			channel_id = csr_get_channel_for_hw_mode_change
+					(pMac, hBSSList, sessionId);
+			if (!channel_id)
+				channel_id = first_ap_profile->channelId;
+
+			status = policy_mgr_handle_conc_multiport(pMac->psoc,
+					sessionId, channel_id);
+			if ((QDF_IS_STATUS_SUCCESS(status)) &&
+				(!csr_wait_for_connection_update(pMac, true))) {
+					sme_debug("conn update error");
+					csr_scan_result_purge(pMac, hBSSList);
+					fCallCallback = true;
+					status = QDF_STATUS_E_TIMEOUT;
+					goto error;
+			} else if (status == QDF_STATUS_E_FAILURE) {
+				sme_debug("conn update error");
+				csr_scan_result_purge(pMac, hBSSList);
+				fCallCallback = true;
+				goto error;
+			}
+		}
+
+		status = csr_roam_issue_connect(pMac, sessionId, pProfile,
+				hBSSList, eCsrHddIssued, roamId, false, false);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("CSR failed to issue connect cmd with status: 0x%08X",
+				status);
+			fCallCallback = true;
+		}
+	} else if (NULL != pProfile) {
+		/* Check whether it is for start ibss */
+		if (CSR_IS_START_IBSS(pProfile) ||
+		    CSR_IS_NDI(pProfile)) {
+			status = csr_roam_issue_connect(pMac, sessionId,
+					pProfile, NULL, eCsrHddIssued,
+					roamId, false, false);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				sme_err("Failed with status = 0x%08X",
+					status);
+				fCallCallback = true;
+			}
+		} else {
+			/* scan for this SSID */
+			status = csr_scan_for_ssid(pMac, sessionId, pProfile,
+						roamId, true);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				sme_err("CSR failed to issue SSID scan cmd with status: 0x%08X",
+					status);
+				fCallCallback = true;
+			} else {
+				sme_debug("SSID scan requested");
+			}
+		}
+	} else {
+		fCallCallback = true;
+	}
+
+error:
+	if (NULL != pProfile)
+		/*
+		 * we need to free memory for filter
+		 * if profile exists
+		 */
+		csr_free_scan_filter(pMac, pScanFilter);
+
+	qdf_mem_free(pScanFilter);
+end:
+	/* tell the caller if we fail to trigger a join request */
+	if (fCallCallback) {
+		csr_roam_call_callback(pMac, sessionId, NULL, roamId,
+				eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE);
+	}
+	qdf_mem_free(first_ap_profile);
+
+	return status;
+}
+
+/**
+ * csr_roam_reassoc() - process reassoc command
+ * @mac_ctx:       mac global context
+ * @session_id:    session id
+ * @profile:       roam profile
+ * @mod_fields:    AC info being modified in reassoc
+ * @roam_id:       roam id to be populated
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+csr_roam_reassoc(tpAniSirGlobal mac_ctx, uint32_t session_id,
+		 struct csr_roam_profile *profile,
+		 tCsrRoamModifyProfileFields mod_fields,
+		 uint32_t *roam_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	bool fCallCallback = true;
+	uint32_t roamId = 0;
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (NULL == profile) {
+		sme_err("No profile specified");
+		return QDF_STATUS_E_FAILURE;
+	}
+	sme_debug(
+		"called  BSSType = %s (%d) authtype = %d  encryType = %d",
+		sme_bss_type_to_string(profile->BSSType),
+		profile->BSSType, profile->AuthType.authType[0],
+		profile->EncryptionType.encryptionType[0]);
+	csr_roam_cancel_roaming(mac_ctx, session_id);
+	csr_scan_abort_mac_scan(mac_ctx, session_id, INVAL_SCAN_ID);
+	csr_roam_remove_duplicate_command(mac_ctx, session_id, NULL,
+					  eCsrHddIssuedReassocToSameAP);
+	if (csr_is_conn_state_connected(mac_ctx, session_id)) {
+		if (profile) {
+			if (profile->SSIDs.numOfSSIDs &&
+			    csr_is_ssid_in_list(&session->connectedProfile.SSID,
+						&profile->SSIDs)) {
+				fCallCallback = false;
+			} else {
+				/*
+				 * Connected SSID did not match with what is
+				 * asked in profile
+				 */
+				sme_debug("SSID mismatch");
+			}
+		} else if (qdf_mem_cmp(&mod_fields,
+				&session->connectedProfile.modifyProfileFields,
+				sizeof(tCsrRoamModifyProfileFields))) {
+			fCallCallback = false;
+		} else {
+			sme_debug(
+				/*
+				 * Either the profile is NULL or none of the
+				 * fields in tCsrRoamModifyProfileFields got
+				 * modified
+				 */
+				"Profile NULL or nothing to modify");
+		}
+	} else {
+		sme_debug("Not connected! No need to reassoc");
+	}
+	if (!fCallCallback) {
+		roamId = GET_NEXT_ROAM_ID(&mac_ctx->roam);
+		if (roam_id)
+			*roam_id = roamId;
+		status = csr_roam_issue_reassoc(mac_ctx, session_id, profile,
+				&mod_fields, eCsrHddIssuedReassocToSameAP,
+				roamId, false);
+	} else {
+		status = csr_roam_call_callback(mac_ctx, session_id, NULL,
+						roamId, eCSR_ROAM_FAILED,
+						eCSR_ROAM_RESULT_FAILURE);
+	}
+	return status;
+}
+
+static QDF_STATUS csr_roam_join_last_profile(tpAniSirGlobal pMac,
+					     uint32_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tScanResultHandle hBSSList = NULL;
+	tCsrScanResultFilter *pScanFilter = NULL;
+	uint32_t roamId;
+	struct csr_roam_profile *pProfile = NULL;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found ", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pSession->pCurRoamProfile) {
+		csr_scan_abort_mac_scan(pMac, sessionId, INVAL_SCAN_ID);
+		/* We have to make a copy of pCurRoamProfile because it
+		 * will be free inside csr_roam_issue_connect
+		 */
+		pProfile = qdf_mem_malloc(sizeof(struct csr_roam_profile));
+		if (NULL == pProfile) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		status = csr_roam_copy_profile(pMac, pProfile,
+			pSession->pCurRoamProfile);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			goto end;
+		pScanFilter = qdf_mem_malloc(sizeof(tCsrScanResultFilter));
+		if (NULL == pScanFilter) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		status = csr_roam_prepare_filter_from_profile(pMac, pProfile,
+					pScanFilter);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			goto end;
+		roamId = GET_NEXT_ROAM_ID(&pMac->roam);
+		status = csr_scan_get_result(pMac, pScanFilter, &hBSSList);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			/* we want to put the last connected BSS to the
+			 * very beginning, if possible
+			 */
+			csr_move_bss_to_head_from_bssid(pMac,
+				&pSession->connectedProfile.bssid, hBSSList);
+			status = csr_roam_issue_connect(pMac, sessionId,
+					pProfile, hBSSList, eCsrHddIssued,
+					roamId, false, false);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				goto end;
+			}
+		} else {
+			/* scan for this SSID only incase AP suppresses SSID */
+			status = csr_scan_for_ssid(pMac, sessionId, pProfile,
+					roamId, true);
+			if (!QDF_IS_STATUS_SUCCESS(status))
+				goto end;
+		}
+	} /* We have a profile */
+	else {
+		sme_warn("cannot find a roaming profile");
+		goto end;
+	}
+end:
+	if (pScanFilter) {
+		csr_free_scan_filter(pMac, pScanFilter);
+		qdf_mem_free(pScanFilter);
+	}
+	if (NULL != pProfile) {
+		csr_release_profile(pMac, pProfile);
+		qdf_mem_free(pProfile);
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_reconnect(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (csr_is_conn_state_connected(pMac, sessionId)) {
+		status = csr_roam_issue_disassociate_cmd(pMac, sessionId,
+					eCSR_DISCONNECT_REASON_UNSPECIFIED);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			status = csr_roam_join_last_profile(pMac, sessionId);
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_connect_to_last_profile(tpAniSirGlobal pMac,
+						uint32_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	csr_roam_cancel_roaming(pMac, sessionId);
+	csr_roam_remove_duplicate_command(pMac, sessionId, NULL, eCsrHddIssued);
+	if (csr_is_conn_state_disconnected(pMac, sessionId))
+		status = csr_roam_join_last_profile(pMac, sessionId);
+
+	return status;
+}
+
+QDF_STATUS csr_roam_process_disassoc_deauth(tpAniSirGlobal pMac,
+						tSmeCmd *pCommand,
+					    bool fDisassoc, bool fMICFailure)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	bool fComplete = false;
+	enum csr_roam_substate NewSubstate;
+	uint32_t sessionId = pCommand->sessionId;
+
+	if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
+		sme_debug("Stop Wait for key timer and change substate to eCSR_ROAM_SUBSTATE_NONE");
+		csr_roam_stop_wait_for_key_timer(pMac);
+		csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+					sessionId);
+	}
+	/* change state to 'Roaming'... */
+	csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING, sessionId);
+
+	if (csr_is_conn_state_ibss(pMac, sessionId)) {
+		/* If we are in an IBSS, then stop the IBSS... */
+		status =
+			csr_roam_issue_stop_bss(pMac, sessionId,
+					eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
+		fComplete = (!QDF_IS_STATUS_SUCCESS(status));
+	} else if (csr_is_conn_state_infra(pMac, sessionId)) {
+		/*
+		 * in Infrastructure, we need to disassociate from the
+		 * Infrastructure network...
+		 */
+		NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_FORCED;
+		if (eCsrSmeIssuedDisassocForHandoff ==
+		    pCommand->u.roamCmd.roamReason) {
+			NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF;
+		} else
+		if ((eCsrForcedDisassoc == pCommand->u.roamCmd.roamReason)
+		    && (eSIR_MAC_DISASSOC_LEAVING_BSS_REASON ==
+			pCommand->u.roamCmd.reason)) {
+			NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT;
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+					 "set to substate eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT");
+		}
+		if (eCsrSmeIssuedDisassocForHandoff !=
+				pCommand->u.roamCmd.roamReason) {
+			/*
+			 * If we are in neighbor preauth done state then
+			 * on receiving disassoc or deauth we dont roam
+			 * instead we just disassoc from current ap and
+			 * then go to disconnected state.
+			 * This happens for ESE and 11r FT connections ONLY.
+			 */
+			if (csr_roam_is11r_assoc(pMac, sessionId) &&
+				(csr_neighbor_roam_state_preauth_done(pMac,
+							sessionId)))
+				csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							pMac, sessionId);
+#ifdef FEATURE_WLAN_ESE
+			if (csr_roam_is_ese_assoc(pMac, sessionId) &&
+				(csr_neighbor_roam_state_preauth_done(pMac,
+							sessionId)))
+				csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							pMac, sessionId);
+#endif
+			if (csr_roam_is_fast_roam_enabled(pMac, sessionId) &&
+				(csr_neighbor_roam_state_preauth_done(pMac,
+							sessionId)))
+				csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							pMac, sessionId);
+		}
+		if (fDisassoc)
+			status = csr_roam_issue_disassociate(pMac, sessionId,
+								NewSubstate,
+								fMICFailure);
+		else
+			status = csr_roam_issue_deauth(pMac, sessionId,
+						eCSR_ROAM_SUBSTATE_DEAUTH_REQ);
+		fComplete = (!QDF_IS_STATUS_SUCCESS(status));
+	} else {
+		/* we got a dis-assoc request while not connected to any peer */
+		/* just complete the command */
+		fComplete = true;
+		status = QDF_STATUS_E_FAILURE;
+	}
+	if (fComplete)
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL, sessionId);
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (csr_is_conn_state_infra(pMac, sessionId)) {
+			/* Set the state to disconnect here */
+			pMac->roam.roamSession[sessionId].connectState =
+				eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+		}
+	} else
+		sme_warn(" failed with status %d", status);
+	return status;
+}
+
+/**
+ * csr_prepare_disconnect_command() - function to prepare disconnect command
+ * @mac: pointer to global mac structure
+ * @session_id: sme session index
+ * @sme_cmd: pointer to sme command being prepared
+ *
+ * Function to prepare internal sme disconnect command
+ * Return: QDF_STATUS_SUCCESS on success else QDF_STATUS_E_RESOURCES on failure
+ */
+
+QDF_STATUS csr_prepare_disconnect_command(tpAniSirGlobal mac,
+			uint32_t session_id, tSmeCmd **sme_cmd)
+{
+	tSmeCmd *command;
+
+	command = csr_get_command_buffer(mac);
+	if (!command) {
+		sme_err("fail to get command buffer");
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	command->command = eSmeCommandRoam;
+	command->sessionId = (uint8_t)session_id;
+	command->u.roamCmd.roamReason = eCsrForcedDisassoc;
+
+	*sme_cmd = command;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS csr_roam_issue_disassociate_cmd(tpAniSirGlobal pMac,
+					uint32_t sessionId,
+					eCsrRoamDisconnectReason reason)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+
+	do {
+		pCommand = csr_get_command_buffer(pMac);
+		if (!pCommand) {
+			sme_err(" fail to get command buffer");
+			status = QDF_STATUS_E_RESOURCES;
+			break;
+		}
+		/* Change the substate in case it is wait-for-key */
+		if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
+			csr_roam_stop_wait_for_key_timer(pMac);
+			csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+						 sessionId);
+		}
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		sme_debug(
+			"Disassociate reason: %d, sessionId: %d",
+			reason, sessionId);
+		switch (reason) {
+		case eCSR_DISCONNECT_REASON_MIC_ERROR:
+			pCommand->u.roamCmd.roamReason =
+				eCsrForcedDisassocMICFailure;
+			break;
+		case eCSR_DISCONNECT_REASON_DEAUTH:
+			pCommand->u.roamCmd.roamReason = eCsrForcedDeauth;
+			break;
+		case eCSR_DISCONNECT_REASON_HANDOFF:
+			pCommand->u.roamCmd.roamReason =
+				eCsrSmeIssuedDisassocForHandoff;
+			break;
+		case eCSR_DISCONNECT_REASON_UNSPECIFIED:
+		case eCSR_DISCONNECT_REASON_DISASSOC:
+			pCommand->u.roamCmd.roamReason = eCsrForcedDisassoc;
+			break;
+		case eCSR_DISCONNECT_REASON_ROAM_HO_FAIL:
+			pCommand->u.roamCmd.roamReason = eCsrForcedDisassoc;
+			break;
+		case eCSR_DISCONNECT_REASON_IBSS_LEAVE:
+			pCommand->u.roamCmd.roamReason = eCsrForcedIbssLeave;
+			break;
+		case eCSR_DISCONNECT_REASON_STA_HAS_LEFT:
+			pCommand->u.roamCmd.roamReason = eCsrForcedDisassoc;
+			pCommand->u.roamCmd.reason =
+				eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				 "SME convert to internal reason code eCsrStaHasLeft");
+			break;
+		case eCSR_DISCONNECT_REASON_NDI_DELETE:
+			pCommand->u.roamCmd.roamReason = eCsrStopBss;
+			pCommand->u.roamCmd.roamProfile.BSSType =
+				eCSR_BSS_TYPE_NDI;
+		default:
+			break;
+		}
+		pCommand->u.roamCmd.disconnect_reason = reason;
+		status = csr_queue_sme_command(pMac, pCommand, true);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			sme_err("fail to send message status: %d", status);
+	} while (0);
+	return status;
+}
+
+QDF_STATUS csr_roam_issue_stop_bss_cmd(tpAniSirGlobal pMac, uint32_t sessionId,
+				       bool fHighPriority)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+
+	pCommand = csr_get_command_buffer(pMac);
+	if (NULL != pCommand) {
+		/* Change the substate in case it is wait-for-key */
+		if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
+			csr_roam_stop_wait_for_key_timer(pMac);
+			csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+						 sessionId);
+		}
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.roamReason = eCsrStopBss;
+		status = csr_queue_sme_command(pMac, pCommand, fHighPriority);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			sme_err("fail to send message status: %d", status);
+	} else {
+		sme_err("fail to get command buffer");
+		status = QDF_STATUS_E_RESOURCES;
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_disconnect_internal(tpAniSirGlobal pMac, uint32_t sessionId,
+					eCsrRoamDisconnectReason reason)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session: %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+#ifdef FEATURE_WLAN_BTAMP_UT_RF
+	/* Stop the retry */
+	pSession->maxRetryCount = 0;
+	csr_roam_stop_join_retry_timer(pMac, sessionId);
+#endif
+	/* Not to call cancel roaming here */
+	/* Only issue disconnect when necessary */
+	if (csr_is_conn_state_connected(pMac, sessionId)
+	    || csr_is_bss_type_ibss(pSession->connectedProfile.BSSType)
+	    || csr_is_roam_command_waiting_for_session(pMac, sessionId)
+	    || CSR_IS_CONN_NDI(&pSession->connectedProfile)) {
+		sme_debug("called");
+		status = csr_roam_issue_disassociate_cmd(pMac, sessionId,
+							 reason);
+	} else {
+		pMac->roam.roamSession[sessionId].connectState =
+			eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING;
+		csr_scan_abort_mac_scan(pMac, sessionId, INVAL_SCAN_ID);
+		status = QDF_STATUS_CMD_NOT_QUEUED;
+		sme_debug("Disconnect cmd not queued, Roam command is not present return with status: %d",
+			status);
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_disconnect(tpAniSirGlobal mac_ctx, uint32_t session_id,
+			       eCsrRoamDisconnectReason reason)
+{
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (!session) {
+		sme_err("session: %d not found ", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	session->discon_in_progress = true;
+	csr_roam_cancel_roaming(mac_ctx, session_id);
+	csr_roam_remove_duplicate_command(mac_ctx, session_id, NULL,
+					  eCsrForcedDisassoc);
+
+	return csr_roam_disconnect_internal(mac_ctx, session_id, reason);
+}
+
+QDF_STATUS csr_roam_save_connected_information(tpAniSirGlobal pMac,
+					      uint32_t sessionId,
+					      struct csr_roam_profile *pProfile,
+					      tSirBssDescription *pSirBssDesc,
+					      tDot11fBeaconIEs *pIes)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tDot11fBeaconIEs *pIesTemp = pIes;
+	uint8_t index;
+	struct csr_roam_session *pSession = NULL;
+	tCsrRoamConnectedProfile *pConnectProfile = NULL;
+
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (NULL == pSession) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			 "session: %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_debug("session id: %d", sessionId);
+	pConnectProfile = &pSession->connectedProfile;
+	if (pConnectProfile->pAddIEAssoc) {
+		qdf_mem_free(pConnectProfile->pAddIEAssoc);
+		pConnectProfile->pAddIEAssoc = NULL;
+	}
+	/*
+	 * In case of LFR2.0, the connected profile is copied into a temporary
+	 * profile and cleared and then is copied back. This is not needed for
+	 * LFR3.0, since the profile is not cleared.
+	 */
+	if (!pSession->roam_synch_in_progress) {
+		qdf_mem_set(&pSession->connectedProfile,
+				sizeof(tCsrRoamConnectedProfile), 0);
+		pConnectProfile->AuthType = pProfile->negotiatedAuthType;
+		pConnectProfile->AuthInfo = pProfile->AuthType;
+		pConnectProfile->EncryptionType =
+			pProfile->negotiatedUCEncryptionType;
+		pConnectProfile->EncryptionInfo = pProfile->EncryptionType;
+		pConnectProfile->mcEncryptionType =
+			pProfile->negotiatedMCEncryptionType;
+		pConnectProfile->mcEncryptionInfo = pProfile->mcEncryptionType;
+		pConnectProfile->BSSType = pProfile->BSSType;
+		pConnectProfile->modifyProfileFields.uapsd_mask =
+			pProfile->uapsd_mask;
+		qdf_mem_copy(&pConnectProfile->Keys, &pProfile->Keys,
+				sizeof(tCsrKeys));
+		if (pProfile->nAddIEAssocLength) {
+			pConnectProfile->pAddIEAssoc =
+				qdf_mem_malloc(pProfile->nAddIEAssocLength);
+			if (!pConnectProfile->pAddIEAssoc)
+				return QDF_STATUS_E_FAILURE;
+
+			pConnectProfile->nAddIEAssocLength =
+				pProfile->nAddIEAssocLength;
+			qdf_mem_copy(pConnectProfile->pAddIEAssoc,
+					pProfile->pAddIEAssoc,
+					pProfile->nAddIEAssocLength);
+		}
+#ifdef WLAN_FEATURE_11W
+		pConnectProfile->MFPEnabled = pProfile->MFPEnabled;
+		pConnectProfile->MFPRequired = pProfile->MFPRequired;
+		pConnectProfile->MFPCapable = pProfile->MFPCapable;
+#endif
+	}
+	/* Save bssid */
+	pConnectProfile->operationChannel = pSirBssDesc->channelId;
+	pConnectProfile->beaconInterval = pSirBssDesc->beaconInterval;
+	if (!pConnectProfile->beaconInterval)
+		sme_err("ERROR: Beacon interval is ZERO");
+	csr_get_bss_id_bss_desc(pSirBssDesc, &pConnectProfile->bssid);
+	if (pSirBssDesc->mdiePresent) {
+		pConnectProfile->MDID.mdiePresent = 1;
+		pConnectProfile->MDID.mobilityDomain =
+			(pSirBssDesc->mdie[1] << 8) | (pSirBssDesc->mdie[0]);
+	}
+	if (NULL == pIesTemp)
+		status = csr_get_parsed_bss_description_ies(pMac, pSirBssDesc,
+							   &pIesTemp);
+#ifdef FEATURE_WLAN_ESE
+	if ((csr_is_profile_ese(pProfile) ||
+	     (QDF_IS_STATUS_SUCCESS(status) && (pIesTemp->ESEVersion.present)
+	      && (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM)))
+	    && (pMac->roam.configParam.isEseIniFeatureEnabled)) {
+		pConnectProfile->isESEAssoc = 1;
+	}
+#endif
+	/* save ssid */
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (pIesTemp->SSID.present) {
+			pConnectProfile->SSID.length = pIesTemp->SSID.num_ssid;
+			qdf_mem_copy(pConnectProfile->SSID.ssId,
+				     pIesTemp->SSID.ssid,
+				     pIesTemp->SSID.num_ssid);
+		}
+		/* Save the bss desc */
+		status = csr_roam_save_connected_bss_desc(pMac, sessionId,
+								pSirBssDesc);
+
+		if (CSR_IS_QOS_BSS(pIesTemp) || pIesTemp->HTCaps.present)
+			/* Some HT AP's dont send WMM IE so in that case we
+			 * assume all HT Ap's are Qos Enabled AP's
+			 */
+			pConnectProfile->qap = true;
+		else
+			pConnectProfile->qap = false;
+
+		if (pIesTemp->ExtCap.present) {
+			struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
+							pIesTemp->ExtCap.bytes;
+			pConnectProfile->proxyARPService = p_ext_cap->
+							    proxy_arp_service;
+		}
+
+		if (NULL == pIes)
+			/* Free memory if it allocated locally */
+			qdf_mem_free(pIesTemp);
+	}
+	/* Save Qos connection */
+	pConnectProfile->qosConnection =
+		pMac->roam.roamSession[sessionId].fWMMConnection;
+
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		csr_free_connect_bss_desc(pMac, sessionId);
+
+	for (index = 0; index < pProfile->SSIDs.numOfSSIDs; index++) {
+		if ((pProfile->SSIDs.SSIDList[index].SSID.length ==
+		     pConnectProfile->SSID.length)
+		    && (!qdf_mem_cmp(pProfile->SSIDs.SSIDList[index].SSID.
+				       ssId, pConnectProfile->SSID.ssId,
+				       pConnectProfile->SSID.length))) {
+			pConnectProfile->handoffPermitted = pProfile->SSIDs.
+					SSIDList[index].handoffPermitted;
+			break;
+		}
+		pConnectProfile->handoffPermitted = false;
+	}
+
+	return status;
+}
+
+
+bool is_disconnect_pending(tpAniSirGlobal pmac,
+				uint8_t sessionid)
+{
+	tListElem *entry = NULL;
+	tListElem *next_entry = NULL;
+	tSmeCmd *command = NULL;
+	bool disconnect_cmd_exist = false;
+
+	csr_nonscan_pending_ll_lock(pmac);
+	entry = csr_nonscan_pending_ll_peek_head(pmac, LL_ACCESS_NOLOCK);
+	while (entry) {
+		next_entry = csr_nonscan_pending_ll_next(pmac,
+					entry, LL_ACCESS_NOLOCK);
+
+		command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+		if (command && CSR_IS_DISCONNECT_COMMAND(command) &&
+				command->sessionId == sessionid){
+			disconnect_cmd_exist = true;
+			break;
+		}
+		entry = next_entry;
+	}
+	csr_nonscan_pending_ll_unlock(pmac);
+	return disconnect_cmd_exist;
+}
+
+static void csr_roam_join_rsp_processor(tpAniSirGlobal pMac,
+					tSirSmeJoinRsp *pSmeJoinRsp)
+{
+	tListElem *pEntry = NULL;
+	tSmeCmd *pCommand = NULL;
+	struct csr_roam_session *session_ptr;
+
+	if (pSmeJoinRsp) {
+		session_ptr = CSR_GET_SESSION(pMac, pSmeJoinRsp->sessionId);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("Sme Join Response is NULL"));
+		return;
+	}
+	if (!session_ptr) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			("session %d not found"), pSmeJoinRsp->sessionId);
+		return;
+	}
+	/* The head of the active list is the request we sent */
+	pEntry = csr_nonscan_active_ll_peek_head(pMac, LL_ACCESS_LOCK);
+	if (pEntry)
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+
+	sme_debug("is_fils_connection %d", pSmeJoinRsp->is_fils_connection);
+	/* Copy Sequence Number last used for FILS assoc failure case */
+	if (session_ptr->is_fils_connection)
+		session_ptr->fils_seq_num = pSmeJoinRsp->fils_seq_num;
+
+	if (eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode) {
+		if (pCommand
+		    && eCsrSmeIssuedAssocToSimilarAP ==
+		    pCommand->u.roamCmd.roamReason) {
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+			sme_qos_csr_event_ind(pMac, pSmeJoinRsp->sessionId,
+					    SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
+#endif
+		}
+
+		session_ptr->supported_nss_1x1 =
+			pSmeJoinRsp->supported_nss_1x1;
+		sme_debug("SME session supported nss: %d",
+			session_ptr->supported_nss_1x1);
+
+		/*
+		 * The join bssid count can be reset as soon as
+		 * we are done with the join requests and returning
+		 * the response to upper layers
+		 */
+		session_ptr->join_bssid_count = 0;
+		csr_roam_complete(pMac, eCsrJoinSuccess, (void *)pSmeJoinRsp,
+				pSmeJoinRsp->sessionId);
+	} else {
+		uint32_t roamId = 0;
+		bool is_dis_pending;
+
+		/* The head of the active list is the request we sent
+		 * Try to get back the same profile and roam again
+		 */
+		if (pCommand)
+			roamId = pCommand->u.roamCmd.roamId;
+		session_ptr->joinFailStatusCode.statusCode =
+			pSmeJoinRsp->statusCode;
+		session_ptr->joinFailStatusCode.reasonCode =
+			pSmeJoinRsp->protStatusCode;
+		sme_warn("SmeJoinReq failed with statusCode= 0x%08X [%d]",
+			pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode);
+		/* If Join fails while Handoff is in progress, indicate
+		 * disassociated event to supplicant to reconnect
+		 */
+		if (csr_roam_is_handoff_in_progress(pMac,
+						pSmeJoinRsp->sessionId)) {
+			csr_roam_call_callback(pMac, pSmeJoinRsp->sessionId,
+						NULL, roamId,
+						eCSR_ROAM_DISASSOCIATED,
+					       eCSR_ROAM_RESULT_FORCED);
+			/* Should indicate neighbor roam algorithm about the
+			 * connect failure here
+			 */
+			csr_neighbor_roam_indicate_connect(pMac,
+							 pSmeJoinRsp->sessionId,
+							 QDF_STATUS_E_FAILURE);
+		}
+		/*
+		 * if userspace has issued disconnection,
+		 * driver should not continue connecting
+		 */
+		is_dis_pending = is_disconnect_pending(pMac,
+							session_ptr->sessionId);
+		if (pCommand && (session_ptr->join_bssid_count <
+				CSR_MAX_BSSID_COUNT) && !is_dis_pending)
+			csr_roam(pMac, pCommand);
+		else {
+			/*
+			 * When the upper layers issue a connect command, there
+			 * is a roam command with reason eCsrHddIssued that
+			 * gets enqueued and an associated timer for the SME
+			 * command timeout is started which is currently 120
+			 * seconds. This command would be dequeued only upon
+			 * successful connections. In case of join failures, if
+			 * there are too many BSS in the cache, and if we fail
+			 * Join requests with all of them, there is a chance of
+			 * timing out the above timer.
+			 */
+			if (session_ptr->join_bssid_count >=
+					CSR_MAX_BSSID_COUNT)
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					 "Excessive Join Req Failures");
+
+			if (is_dis_pending)
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_ERROR,
+					"disconnect is pending, complete roam");
+
+			if (session_ptr->bRefAssocStartCnt)
+				session_ptr->bRefAssocStartCnt--;
+
+			session_ptr->join_bssid_count = 0;
+
+			csr_roam_call_callback(pMac, session_ptr->sessionId,
+				NULL, roamId,
+				eCSR_ROAM_ASSOCIATION_COMPLETION,
+				eCSR_ROAM_RESULT_NOT_ASSOCIATED);
+
+			csr_roam_complete(pMac, eCsrNothingToJoin, NULL,
+					pSmeJoinRsp->sessionId);
+		}
+	} /*else: ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode ) */
+}
+
+static QDF_STATUS csr_roam_issue_join(tpAniSirGlobal pMac, uint32_t sessionId,
+				      tSirBssDescription *pSirBssDesc,
+				      tDot11fBeaconIEs *pIes,
+				      struct csr_roam_profile *pProfile,
+				      uint32_t roamId)
+{
+	QDF_STATUS status;
+
+	sme_debug("Attempting to Join Bssid= " MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(pSirBssDesc->bssId));
+
+	/* Set the roaming substate to 'join attempt'... */
+	csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_JOIN_REQ, sessionId);
+	/* attempt to Join this BSS... */
+	status = csr_send_join_req_msg(pMac, sessionId, pSirBssDesc, pProfile,
+					pIes, eWNI_SME_JOIN_REQ);
+	return status;
+}
+
+static void
+csr_roam_reissue_roam_command(tpAniSirGlobal pMac, uint8_t session_id)
+{
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+	struct csr_roam_info roamInfo;
+	uint32_t sessionId;
+	struct csr_roam_session *pSession;
+
+	pEntry = csr_nonscan_active_ll_peek_head(pMac, LL_ACCESS_LOCK);
+	if (NULL == pEntry) {
+		sme_err("Disassoc rsp can't continue, no active CMD");
+		return;
+	}
+	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+	if (eSmeCommandRoam != pCommand->command) {
+		sme_err("Active cmd, is not a roaming CMD");
+		return;
+	}
+	sessionId = pCommand->sessionId;
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+
+	if (!pCommand->u.roamCmd.fStopWds) {
+		if (pSession->bRefAssocStartCnt > 0) {
+			/*
+			 * bRefAssocStartCnt was incremented in
+			 * csr_roam_join_next_bss when the roam command issued
+			 * previously. As part of reissuing the roam command
+			 * again csr_roam_join_next_bss is going increment
+			 * RefAssocStartCnt. So make sure to decrement the
+			 * bRefAssocStartCnt
+			 */
+			pSession->bRefAssocStartCnt--;
+		}
+		if (eCsrStopRoaming == csr_roam_join_next_bss(pMac, pCommand,
+							      true)) {
+			sme_warn("Failed to reissue join command");
+			csr_roam_complete(pMac, eCsrNothingToJoin, NULL,
+					session_id);
+		}
+		return;
+	}
+	qdf_mem_set(&roamInfo, sizeof(struct csr_roam_info), 0);
+	roamInfo.pBssDesc = pCommand->u.roamCmd.pLastRoamBss;
+	roamInfo.statusCode = pSession->joinFailStatusCode.statusCode;
+	roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode;
+	pSession->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED;
+	csr_roam_call_callback(pMac, sessionId, &roamInfo,
+			       pCommand->u.roamCmd.roamId,
+			       eCSR_ROAM_INFRA_IND,
+			       eCSR_ROAM_RESULT_INFRA_DISASSOCIATED);
+
+	if (!QDF_IS_STATUS_SUCCESS(csr_roam_issue_stop_bss(pMac, sessionId,
+					eCSR_ROAM_SUBSTATE_STOP_BSS_REQ))) {
+		sme_err("Failed to reissue stop_bss command for WDS");
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL, session_id);
+	}
+}
+
+bool csr_is_roam_command_waiting_for_session(tpAniSirGlobal pMac,
+						uint32_t sessionId)
+{
+	bool fRet = false;
+	tListElem *pEntry;
+	tSmeCmd *pCommand = NULL;
+
+	/* alwasy lock active list before locking pending list */
+	csr_nonscan_active_ll_lock(pMac);
+	pEntry = csr_nonscan_active_ll_peek_head(pMac, LL_ACCESS_NOLOCK);
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if ((eSmeCommandRoam == pCommand->command)
+		    && (sessionId == pCommand->sessionId)) {
+			fRet = true;
+		}
+	}
+	if (false == fRet) {
+		csr_nonscan_pending_ll_lock(pMac);
+		pEntry = csr_nonscan_pending_ll_peek_head(pMac,
+					 LL_ACCESS_NOLOCK);
+		while (pEntry) {
+			pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+			if ((eSmeCommandRoam == pCommand->command)
+			    && (sessionId == pCommand->sessionId)) {
+				fRet = true;
+				break;
+			}
+			pEntry = csr_nonscan_pending_ll_next(pMac, pEntry,
+							LL_ACCESS_NOLOCK);
+		}
+		csr_nonscan_pending_ll_unlock(pMac);
+	}
+	csr_nonscan_active_ll_unlock(pMac);
+
+	return fRet;
+}
+
+static void
+csr_roaming_state_config_cnf_processor(tpAniSirGlobal mac_ctx,
+				       tSmeCmd *cmd,
+				       uint8_t sme_session_id)
+{
+	struct tag_csrscan_result *scan_result = NULL;
+	tSirBssDescription *bss_desc = NULL;
+	uint32_t session_id;
+	struct csr_roam_session *session;
+	tDot11fBeaconIEs *local_ies = NULL;
+	bool is_ies_malloced = false;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (NULL == cmd) {
+		sme_err("given sme cmd is null");
+		return;
+	}
+	session_id = cmd->sessionId;
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (!session) {
+		sme_err("session %d not found", session_id);
+		return;
+	}
+
+	if (CSR_IS_ROAMING(session) && session->fCancelRoaming) {
+		/* the roaming is cancelled. Simply complete the command */
+		sme_warn("Roam command canceled");
+		csr_roam_complete(mac_ctx, eCsrNothingToJoin, NULL,
+					sme_session_id);
+		return;
+	}
+
+	/* we have active entry */
+	sme_debug("Cfg sequence complete");
+	/*
+	 * Successfully set the configuration parameters for the new Bss.
+	 * Attempt to join the roaming Bss
+	 */
+	if (cmd->u.roamCmd.pRoamBssEntry) {
+		scan_result = GET_BASE_ADDR(cmd->u.roamCmd.pRoamBssEntry,
+					    struct tag_csrscan_result,
+					    Link);
+		bss_desc = &scan_result->Result.BssDescriptor;
+	}
+	if (csr_is_bss_type_ibss(cmd->u.roamCmd.roamProfile.BSSType)
+	    || CSR_IS_INFRA_AP(&cmd->u.roamCmd.roamProfile)
+	    || CSR_IS_NDI(&cmd->u.roamCmd.roamProfile)) {
+		if (!QDF_IS_STATUS_SUCCESS(csr_roam_issue_start_bss(mac_ctx,
+						session_id, &session->bssParams,
+						&cmd->u.roamCmd.roamProfile,
+						bss_desc,
+						cmd->u.roamCmd.roamId))) {
+			sme_err("CSR start BSS failed");
+			/* We need to complete the command */
+			csr_roam_complete(mac_ctx, eCsrStartBssFailure, NULL,
+					sme_session_id);
+		}
+		return;
+	}
+
+	if (!cmd->u.roamCmd.pRoamBssEntry) {
+		sme_err("pRoamBssEntry is NULL");
+		/* We need to complete the command */
+		csr_roam_complete(mac_ctx, eCsrJoinFailure, NULL,
+				sme_session_id);
+		return;
+	}
+
+	if (NULL == scan_result) {
+		/* If we are roaming TO an Infrastructure BSS... */
+		QDF_ASSERT(scan_result != NULL);
+		return;
+	}
+
+	if (!csr_is_infra_bss_desc(bss_desc)) {
+		sme_warn("found BSSType mismatching the one in BSS descp");
+		return;
+	}
+
+	local_ies = (tDot11fBeaconIEs *) scan_result->Result.pvIes;
+	if (!local_ies) {
+		status = csr_get_parsed_bss_description_ies(mac_ctx, bss_desc,
+							    &local_ies);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			return;
+		is_ies_malloced = true;
+	}
+
+	if (csr_is_conn_state_connected_infra(mac_ctx, session_id)) {
+		if (csr_is_ssid_equal(mac_ctx, session->pConnectBssDesc,
+				      bss_desc, local_ies)) {
+			cmd->u.roamCmd.fReassoc = true;
+			csr_roam_issue_reassociate(mac_ctx, session_id,
+						   bss_desc, local_ies,
+						   &cmd->u.roamCmd.roamProfile);
+		} else {
+			/*
+			 * otherwise, we have to issue a new Join request to LIM
+			 * because we disassociated from the previously
+			 * associated AP.
+			 */
+			status = csr_roam_issue_join(mac_ctx, session_id,
+					bss_desc, local_ies,
+					&cmd->u.roamCmd.roamProfile,
+					cmd->u.roamCmd.roamId);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				/* try something else */
+				csr_roam(mac_ctx, cmd);
+			}
+		}
+	} else {
+		status = QDF_STATUS_SUCCESS;
+		/*
+		 * We need to come with other way to figure out that this is
+		 * because of HO in BMP The below API will be only available for
+		 * Android as it uses a different HO algorithm. Reassoc request
+		 * will be used only for ESE and 11r handoff whereas other
+		 * legacy roaming should use join request
+		 */
+		if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)
+		    && csr_roam_is11r_assoc(mac_ctx, session_id)) {
+			status = csr_roam_issue_reassociate(mac_ctx,
+					session_id, bss_desc,
+					local_ies,
+					&cmd->u.roamCmd.roamProfile);
+		} else
+#ifdef FEATURE_WLAN_ESE
+		if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)
+		   && csr_roam_is_ese_assoc(mac_ctx, session_id)) {
+			/* Now serialize the reassoc command. */
+			status = csr_roam_issue_reassociate_cmd(mac_ctx,
+								session_id);
+		} else
+#endif
+		if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)
+		   && csr_roam_is_fast_roam_enabled(mac_ctx, session_id)) {
+			/* Now serialize the reassoc command. */
+			status = csr_roam_issue_reassociate_cmd(mac_ctx,
+								session_id);
+		} else {
+			/*
+			 * else we are not connected and attempting to Join.
+			 * Issue the Join request.
+			 */
+			status = csr_roam_issue_join(mac_ctx, session_id,
+						    bss_desc,
+						    local_ies,
+						    &cmd->u.roamCmd.roamProfile,
+						    cmd->u.roamCmd.roamId);
+		}
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			/* try something else */
+			csr_roam(mac_ctx, cmd);
+		}
+	}
+	if (is_ies_malloced) {
+		/* Locally allocated */
+		qdf_mem_free(local_ies);
+	}
+}
+
+static void csr_roam_roaming_state_reassoc_rsp_processor(tpAniSirGlobal pMac,
+						tpSirSmeJoinRsp pSmeJoinRsp)
+{
+	enum csr_roamcomplete_result result;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+	struct csr_roam_info roamInfo;
+	uint32_t roamId = 0;
+	struct csr_roam_session *csr_session;
+
+	if (pSmeJoinRsp->sessionId >= CSR_ROAM_SESSION_MAX) {
+		sme_err("Invalid session ID received %d",
+			 pSmeJoinRsp->sessionId);
+		return;
+	}
+
+	pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[pSmeJoinRsp->sessionId];
+	if (eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			 "CSR SmeReassocReq Successful");
+		result = eCsrReassocSuccess;
+		csr_session = CSR_GET_SESSION(pMac, pSmeJoinRsp->sessionId);
+		if (NULL != csr_session) {
+			csr_session->supported_nss_1x1 =
+				pSmeJoinRsp->supported_nss_1x1;
+			sme_debug("SME session supported nss: %d",
+				csr_session->supported_nss_1x1);
+		}
+		/*
+		 * Since the neighbor roam algorithm uses reassoc req for
+		 * handoff instead of join, we need the response contents while
+		 * processing the result in csr_roam_process_results()
+		 */
+		if (csr_roam_is_handoff_in_progress(pMac,
+						pSmeJoinRsp->sessionId)) {
+			/* Need to dig more on indicating events to
+			 * SME QoS module
+			 */
+			sme_qos_csr_event_ind(pMac, pSmeJoinRsp->sessionId,
+					    SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
+			csr_roam_complete(pMac, result, pSmeJoinRsp,
+					pSmeJoinRsp->sessionId);
+		} else {
+			csr_roam_complete(pMac, result, NULL,
+					pSmeJoinRsp->sessionId);
+		}
+	}
+	/* Should we handle this similar to handling the join failure? Is it ok
+	 * to call csr_roam_complete() with state as CsrJoinFailure
+	 */
+	else {
+		sme_warn(
+			"CSR SmeReassocReq failed with statusCode= 0x%08X [%d]",
+			pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode);
+		result = eCsrReassocFailure;
+		cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+			WLAN_LOG_INDICATOR_HOST_DRIVER,
+			WLAN_LOG_REASON_ROAM_FAIL,
+			true, false);
+		if ((eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE ==
+		     pSmeJoinRsp->statusCode)
+		    || (eSIR_SME_FT_REASSOC_FAILURE ==
+			pSmeJoinRsp->statusCode)
+		    || (eSIR_SME_INVALID_PARAMETERS ==
+			pSmeJoinRsp->statusCode)) {
+			/* Inform HDD to turn off FT flag in HDD */
+			if (pNeighborRoamInfo) {
+				qdf_mem_zero(&roamInfo, sizeof(roamInfo));
+				csr_roam_call_callback(pMac,
+						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
+				 * machine as well to be in sync with the upper
+				 * layers. There is no need to send a disassoc
+				 * since: 1) we will never reassoc to the
+				 * current AP in LFR, and 2) there is no need
+				 * to issue a disassoc to the AP with which we
+				 * were trying to reassoc.
+				 */
+				csr_roam_complete(pMac, eCsrJoinFailure, NULL,
+						pSmeJoinRsp->sessionId);
+				return;
+			}
+		}
+		/* In the event that the Reassociation fails, then we need to
+		 * Disassociate the current association and keep roaming. Note
+		 * that we will attempt to Join the AP instead of a Reassoc
+		 * since we may have attempted a 'Reassoc to self', which AP's
+		 * that don't support Reassoc will force a Disassoc. The
+		 * isassoc rsp message will remove the command from active list
+		 */
+		if (!QDF_IS_STATUS_SUCCESS
+			    (csr_roam_issue_disassociate
+				    (pMac, pSmeJoinRsp->sessionId,
+				    eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE,
+				false))) {
+			csr_roam_complete(pMac, eCsrJoinFailure, NULL,
+					pSmeJoinRsp->sessionId);
+		}
+	}
+}
+
+static void csr_roam_roaming_state_stop_bss_rsp_processor(tpAniSirGlobal pMac,
+							  tSirSmeRsp *pSmeRsp)
+{
+	enum csr_roamcomplete_result result_code = eCsrNothingToJoin;
+	struct csr_roam_profile *profile;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	{
+		host_log_ibss_pkt_type *pIbssLog;
+
+		WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+					 LOG_WLAN_IBSS_C);
+		if (pIbssLog) {
+			pIbssLog->eventId = WLAN_IBSS_EVENT_STOP_RSP;
+			if (eSIR_SME_SUCCESS != pSmeRsp->statusCode)
+				pIbssLog->status = WLAN_IBSS_STATUS_FAILURE;
+			WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+		}
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	pMac->roam.roamSession[pSmeRsp->sessionId].connectState =
+		eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+	if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(pMac, pSmeRsp->sessionId)) {
+		profile =
+		    pMac->roam.roamSession[pSmeRsp->sessionId].pCurRoamProfile;
+		if (profile && CSR_IS_CONN_NDI(profile)) {
+			result_code = eCsrStopBssSuccess;
+			if (pSmeRsp->statusCode != eSIR_SME_SUCCESS)
+				result_code = eCsrStopBssFailure;
+		}
+		csr_roam_complete(pMac, result_code, NULL, pSmeRsp->sessionId);
+	} else if (CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE(pMac,
+			pSmeRsp->sessionId)) {
+		csr_roam_reissue_roam_command(pMac, pSmeRsp->sessionId);
+	}
+}
+
+/**
+ * csr_dequeue_command() - removes a command from active cmd list
+ * @pMac:          mac global context
+ *
+ * Return: void
+ */
+static void
+csr_dequeue_command(tpAniSirGlobal mac_ctx)
+{
+	bool fRemoveCmd;
+	tSmeCmd *cmd = NULL;
+	tListElem *entry = csr_nonscan_active_ll_peek_head(mac_ctx,
+					    LL_ACCESS_LOCK);
+	if (!entry) {
+		sme_err("NO commands are active");
+		return;
+	}
+
+	cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
+	/*
+	 * If the head of the queue is Active and it is a given cmd type, remove
+	 * and put this on the Free queue.
+	 */
+	if (eSmeCommandRoam != cmd->command) {
+		sme_err("Roam command not active");
+		return;
+	}
+	/*
+	 * we need to process the result first before removing it from active
+	 * list because state changes still happening insides
+	 * roamQProcessRoamResults so no other roam command should be issued.
+	 */
+	fRemoveCmd = csr_nonscan_active_ll_remove_entry(mac_ctx, entry,
+					 LL_ACCESS_LOCK);
+	if (cmd->u.roamCmd.fReleaseProfile) {
+		csr_release_profile(mac_ctx, &cmd->u.roamCmd.roamProfile);
+		cmd->u.roamCmd.fReleaseProfile = false;
+	}
+	if (fRemoveCmd)
+		csr_release_command(mac_ctx, cmd);
+	else
+		sme_err("fail to remove cmd reason %d",
+			cmd->u.roamCmd.roamReason);
+}
+
+/**
+ * csr_post_roam_failure() - post roam failure back to csr and issues a disassoc
+ * @pMac:               mac global context
+ * @session_id:         session id
+ * @roam_info:          roam info struct
+ * @scan_filter:        scan filter to free
+ * @cur_roam_profile:   current csr roam profile
+ *
+ * Return: void
+ */
+static void
+csr_post_roam_failure(tpAniSirGlobal mac_ctx,
+		      uint32_t session_id,
+		      struct csr_roam_info *roam_info,
+		      tCsrScanResultFilter *scan_filter,
+		      struct csr_roam_profile *cur_roam_profile)
+{
+	QDF_STATUS status;
+
+	if (scan_filter) {
+		csr_free_scan_filter(mac_ctx, scan_filter);
+		qdf_mem_free(scan_filter);
+	}
+	if (cur_roam_profile)
+		qdf_mem_free(cur_roam_profile);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		csr_roam_synch_clean_up(mac_ctx, session_id);
+#endif
+	/* Inform the upper layers that the reassoc failed */
+	qdf_mem_zero(roam_info, sizeof(struct csr_roam_info));
+	csr_roam_call_callback(mac_ctx, session_id, roam_info, 0,
+			       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
+	 * the disassoc response and will fall into the reassoc fail sub-state.
+	 * And, eventually call csr_roam_complete which would remove the roam
+	 * command from SME active queue.
+	 */
+	status = csr_roam_issue_disassociate(mac_ctx, session_id,
+			eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, false);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err(
+			"csr_roam_issue_disassociate failed, status %d",
+			status);
+		csr_roam_complete(mac_ctx, eCsrJoinFailure, NULL, session_id);
+	}
+}
+
+/**
+ * csr_check_profile_in_scan_cache() - finds if roam profile is present in scan
+ * cache or not
+ * @pMac:                  mac global context
+ * @scan_filter:           out param, scan filter
+ * @neighbor_roam_info:    roam info struct
+ * @hBSSList:              scan result
+ *
+ * Return: true if found else false.
+ */
+static bool
+csr_check_profile_in_scan_cache(tpAniSirGlobal mac_ctx,
+				tCsrScanResultFilter **scan_filter,
+				tpCsrNeighborRoamControlInfo neighbor_roam_info,
+				tScanResultHandle *hBSSList)
+{
+	QDF_STATUS status;
+	*scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (!*scan_filter)
+		return false;
+
+	(*scan_filter)->scan_filter_for_roam = 1;
+	status = csr_roam_prepare_filter_from_profile(mac_ctx,
+			&neighbor_roam_info->csrNeighborRoamProfile,
+			*scan_filter);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err(
+			"failed to prepare scan filter, status %d",
+			status);
+		return false;
+	}
+	status = csr_scan_get_result(mac_ctx, *scan_filter, hBSSList);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err(
+			"csr_scan_get_result failed, status %d",
+			status);
+		return false;
+	}
+	return true;
+}
+
+static
+void csr_roam_roaming_state_disassoc_rsp_processor(tpAniSirGlobal pMac,
+						   tSirSmeDisassocRsp *pSmeRsp)
+{
+	tScanResultHandle hBSSList;
+	struct csr_roam_info *roamInfo;
+	tCsrScanResultFilter *pScanFilter = NULL;
+	uint32_t roamId = 0;
+	struct csr_roam_profile *pCurRoamProfile = NULL;
+	QDF_STATUS status;
+	uint32_t sessionId;
+	struct csr_roam_session *pSession;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+	tSirSmeDisassocRsp SmeDisassocRsp;
+
+	csr_ser_des_unpack_diassoc_rsp((uint8_t *) pSmeRsp, &SmeDisassocRsp);
+	sessionId = SmeDisassocRsp.sessionId;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "sessionId %d",
+		  sessionId);
+
+	if (csr_is_conn_state_infra(pMac, sessionId)) {
+		pMac->roam.roamSession[sessionId].connectState =
+			eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+	}
+
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+
+	roamInfo = qdf_mem_malloc(sizeof(*roamInfo));
+	if (!roamInfo)
+		return;
+
+	if (CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN(pMac, sessionId)) {
+		sme_debug("***eCsrNothingToJoin***");
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL, sessionId);
+	} else if (CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED(pMac, sessionId) ||
+		   CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(pMac, sessionId)) {
+		if (eSIR_SME_SUCCESS == SmeDisassocRsp.statusCode) {
+			sme_debug("CSR force disassociated successful");
+			/*
+			 * A callback to HDD will be issued from
+			 * csr_roam_complete so no need to do anything here
+			 */
+		}
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL, sessionId);
+	} else if (CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			 "CSR SmeDisassocReq due to HO on session %d",
+			  sessionId);
+		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
+		/*
+		 * First ensure if the roam profile is in the scan cache.
+		 * If not, post a reassoc failure and disconnect.
+		 */
+		if (!csr_check_profile_in_scan_cache(pMac, &pScanFilter,
+						pNeighborRoamInfo, &hBSSList))
+			goto POST_ROAM_FAILURE;
+
+		/* notify HDD about handoff and provide the BSSID too */
+		roamInfo->reasonCode = eCsrRoamReasonBetterAP;
+
+		qdf_copy_macaddr(&roamInfo->bssid,
+			pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid);
+
+		/*
+		 * For LFR2, removal of policy mgr entry for disassociated
+		 * AP is handled in eCSR_ROAM_ROAMING_START.
+		 * eCSR_ROAM_RESULT_NOT_ASSOCIATED is sent to differentiate
+		 * eCSR_ROAM_ROAMING_START sent after FT preauth success
+		 */
+		csr_roam_call_callback(pMac, sessionId, roamInfo, 0,
+				       eCSR_ROAM_ROAMING_START,
+				       eCSR_ROAM_RESULT_NOT_ASSOCIATED);
+
+		/*
+		 * Copy the connected profile to apply the same for this
+		 * connection as well
+		 */
+		pCurRoamProfile = qdf_mem_malloc(sizeof(*pCurRoamProfile));
+		if (pCurRoamProfile != NULL) {
+			/*
+			 * notify sub-modules like QoS etc. that handoff
+			 * happening
+			 */
+			sme_qos_csr_event_ind(pMac, sessionId,
+					      SME_QOS_CSR_HANDOFF_ASSOC_REQ,
+					      NULL);
+			csr_roam_copy_profile(pMac, pCurRoamProfile,
+					      pSession->pCurRoamProfile);
+			/*
+			 * After ensuring that the roam profile is in the scan
+			 * result list, and pSession->pCurRoamProfile is saved,
+			 * dequeue the command from the active list.
+			 */
+			csr_dequeue_command(pMac);
+			/* make sure to put it at the head of the cmd queue */
+			status = csr_roam_issue_connect(pMac, sessionId,
+					pCurRoamProfile, hBSSList,
+					eCsrSmeIssuedAssocToSimilarAP,
+					roamId, true, false);
+			if (!QDF_IS_STATUS_SUCCESS(status))
+				sme_err(
+					"issue_connect failed. status %d",
+					status);
+
+			csr_release_profile(pMac, pCurRoamProfile);
+			qdf_mem_free(pCurRoamProfile);
+			csr_free_scan_filter(pMac, pScanFilter);
+			qdf_mem_free(pScanFilter);
+			qdf_mem_free(roamInfo);
+			return;
+		} else {
+			QDF_ASSERT(0);
+			csr_dequeue_command(pMac);
+		}
+		csr_scan_result_purge(pMac, hBSSList);
+
+POST_ROAM_FAILURE:
+		csr_post_roam_failure(pMac, sessionId, roamInfo,
+			      pScanFilter, pCurRoamProfile);
+	} /* else if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac ) ) */
+	else if (CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL(pMac, sessionId)) {
+		/* Disassoc due to Reassoc failure falls into this codepath */
+		csr_roam_complete(pMac, eCsrJoinFailure, NULL, sessionId);
+	} else {
+		if (eSIR_SME_SUCCESS == SmeDisassocRsp.statusCode) {
+			/*
+			 * Successfully disassociated from the 'old' Bss.
+			 * We get Disassociate response in three conditions.
+			 * 1) The case where we are disasociating from an Infra
+			 *    Bss to start an IBSS.
+			 * 2) When we are disassociating from an Infra Bss to
+			 *    join an IBSS or a new infra network.
+			 * 3) Where we are doing an Infra to Infra roam between
+			 *    networks with different SSIDs.
+			 * In all cases, we set the new Bss configuration here
+			 * and attempt to join
+			 */
+			sme_debug("Disassociated successfully");
+		} else {
+			sme_err(
+				"DisassocReq failed, statusCode= 0x%08X",
+				SmeDisassocRsp.statusCode);
+		}
+		/* We are not done yet. Get the data and continue roaming */
+		csr_roam_reissue_roam_command(pMac, sessionId);
+	}
+	qdf_mem_free(roamInfo);
+}
+
+static void csr_roam_roaming_state_deauth_rsp_processor(tpAniSirGlobal pMac,
+						tSirSmeDeauthRsp *pSmeRsp)
+{
+	tSirResultCodes statusCode;
+	/* No one is sending eWNI_SME_DEAUTH_REQ to PE. */
+	sme_debug("is no-op");
+	statusCode = csr_get_de_auth_rsp_status_code(pSmeRsp);
+	pMac->roam.deauthRspStatus = statusCode;
+	if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(pMac, pSmeRsp->sessionId)) {
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL,
+				pSmeRsp->sessionId);
+	} else {
+		if (eSIR_SME_SUCCESS == statusCode) {
+			/* Successfully deauth from the 'old' Bss... */
+			/* */
+			sme_debug(
+				"CSR SmeDeauthReq disassociated Successfully");
+		} else {
+			sme_warn(
+				"SmeDeauthReq failed with statusCode= 0x%08X",
+				statusCode);
+		}
+		/* We are not done yet. Get the data and continue roaming */
+		csr_roam_reissue_roam_command(pMac, pSmeRsp->sessionId);
+	}
+}
+
+static void csr_roam_roaming_state_start_bss_rsp_processor(tpAniSirGlobal pMac,
+							   tSirSmeStartBssRsp *
+							   pSmeStartBssRsp)
+{
+	enum csr_roamcomplete_result result;
+
+	if (eSIR_SME_SUCCESS == pSmeStartBssRsp->statusCode) {
+		sme_debug("SmeStartBssReq Successful");
+		result = eCsrStartBssSuccess;
+	} else {
+		sme_warn("SmeStartBssReq failed with statusCode= 0x%08X",
+			pSmeStartBssRsp->statusCode);
+		/* Let csr_roam_complete decide what to do */
+		result = eCsrStartBssFailure;
+	}
+	csr_roam_complete(pMac, result, pSmeStartBssRsp,
+				pSmeStartBssRsp->sessionId);
+}
+
+/**
+ * csr_roaming_state_msg_processor() - process roaming messages
+ * @pMac:       mac global context
+ * @pMsgBuf:    message buffer
+ *
+ * We need to be careful on whether to cast pMsgBuf (pSmeRsp) to other type of
+ * strucutres. It depends on how the message is constructed. If the message is
+ * sent by lim_send_sme_rsp, the pMsgBuf is only a generic response and can only
+ * be used as pointer to tSirSmeRsp. For the messages where sender allocates
+ * memory for specific structures, then it can be cast accordingly.
+ *
+ * Return: status of operation
+ */
+void csr_roaming_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf)
+{
+	tSirSmeRsp *pSmeRsp;
+	tSmeIbssPeerInd *pIbssPeerInd;
+	struct csr_roam_info *roam_info;
+
+	pSmeRsp = (tSirSmeRsp *) pMsgBuf;
+	sme_debug("Message %d[0x%04X] received in substate %s",
+		pSmeRsp->messageType, pSmeRsp->messageType,
+		mac_trace_getcsr_roam_sub_state(
+			pMac->roam.curSubState[pSmeRsp->sessionId]));
+
+	switch (pSmeRsp->messageType) {
+
+	case eWNI_SME_JOIN_RSP:
+		/* in Roaming state, process the Join response message... */
+		if (CSR_IS_ROAM_SUBSTATE_JOIN_REQ(pMac, pSmeRsp->sessionId))
+			/* We sent a JOIN_REQ */
+			csr_roam_join_rsp_processor(pMac,
+						    (tSirSmeJoinRsp *) pSmeRsp);
+		break;
+	case eWNI_SME_REASSOC_RSP:
+		/* or the Reassociation response message... */
+		if (CSR_IS_ROAM_SUBSTATE_REASSOC_REQ(pMac, pSmeRsp->sessionId))
+			csr_roam_roaming_state_reassoc_rsp_processor(pMac,
+						(tpSirSmeJoinRsp) pSmeRsp);
+		break;
+	case eWNI_SME_STOP_BSS_RSP:
+		/* or the Stop Bss response message... */
+		csr_roam_roaming_state_stop_bss_rsp_processor(pMac, pSmeRsp);
+		break;
+	case eWNI_SME_DISASSOC_RSP:
+		/* or the Disassociate response message... */
+		if (CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(pMac, pSmeRsp->sessionId)
+		    || CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN(pMac,
+							pSmeRsp->sessionId)
+		    || CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL(pMac,
+							pSmeRsp->sessionId)
+		    || CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED(pMac,
+							pSmeRsp->sessionId)
+		    || CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE(pMac,
+							pSmeRsp->sessionId)
+		    || CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac,
+							pSmeRsp->sessionId)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				 "eWNI_SME_DISASSOC_RSP subState = %s",
+				  mac_trace_getcsr_roam_sub_state(
+				  pMac->roam.curSubState[pSmeRsp->sessionId]));
+			csr_roam_roaming_state_disassoc_rsp_processor(pMac,
+						(tSirSmeDisassocRsp *) pSmeRsp);
+		}
+		break;
+	case eWNI_SME_DEAUTH_RSP:
+		/* or the Deauthentication response message... */
+		if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(pMac, pSmeRsp->sessionId)) {
+			csr_remove_nonscan_cmd_from_pending_list(pMac,
+					pSmeRsp->sessionId,
+					eSmeCommandWmStatusChange);
+			csr_roam_roaming_state_deauth_rsp_processor(pMac,
+						(tSirSmeDeauthRsp *) pSmeRsp);
+		}
+		break;
+	case eWNI_SME_START_BSS_RSP:
+		/* or the Start BSS response message... */
+		if (CSR_IS_ROAM_SUBSTATE_START_BSS_REQ(pMac,
+						       pSmeRsp->sessionId))
+			csr_roam_roaming_state_start_bss_rsp_processor(pMac,
+						(tSirSmeStartBssRsp *) pSmeRsp);
+		break;
+	/* In case CSR issues STOP_BSS, we need to tell HDD about peer departed
+	 * because PE is removing them
+	 */
+	case eWNI_SME_IBSS_PEER_DEPARTED_IND:
+		pIbssPeerInd = (tSmeIbssPeerInd *) pSmeRsp;
+		sme_err("Peer departed ntf from LIM in joining state");
+		roam_info = qdf_mem_malloc(sizeof(*roam_info));
+		if (!roam_info)
+			break;
+
+		roam_info->staId = (uint8_t) pIbssPeerInd->staId;
+		qdf_copy_macaddr(&roam_info->peerMac, &pIbssPeerInd->peer_addr);
+		csr_roam_call_callback(pMac, pSmeRsp->sessionId, roam_info, 0,
+				       eCSR_ROAM_CONNECT_STATUS_UPDATE,
+				       eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED);
+		qdf_mem_free(roam_info);
+		roam_info = NULL;
+		break;
+	case eWNI_SME_GET_RSSI_REQ:
+	{
+		tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq *) pMsgBuf;
+
+		if (NULL != pGetRssiReq->rssiCallback)
+			((tCsrRssiCallback) pGetRssiReq->rssiCallback)
+				(pGetRssiReq->lastRSSI, pGetRssiReq->staId,
+				pGetRssiReq->pDevContext);
+		else
+			sme_err("pGetRssiReq->rssiCallback is NULL");
+	}
+	break;
+	case eWNI_SME_TRIGGER_SAE:
+		sme_debug("Invoke SAE callback");
+		csr_sae_callback(pMac, pSmeRsp);
+		break;
+
+	case eWNI_SME_SETCONTEXT_RSP:
+		csr_roam_check_for_link_status_change(pMac, pSmeRsp);
+		break;
+
+	default:
+		sme_debug("Unexpected message type: %d[0x%X] received in substate %s",
+			pSmeRsp->messageType, pSmeRsp->messageType,
+			mac_trace_getcsr_roam_sub_state(
+				pMac->roam.curSubState[pSmeRsp->sessionId]));
+		/* If we are connected, check the link status change */
+		if (!csr_is_conn_state_disconnected(pMac, pSmeRsp->sessionId))
+			csr_roam_check_for_link_status_change(pMac, pSmeRsp);
+		break;
+	}
+}
+
+void csr_roam_joined_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf)
+{
+	tSirSmeRsp *pSirMsg = (tSirSmeRsp *) pMsgBuf;
+
+	switch (pSirMsg->messageType) {
+	case eWNI_SME_GET_STATISTICS_RSP:
+		sme_debug("Stats rsp from PE");
+		csr_roam_stats_rsp_processor(pMac, pSirMsg);
+		break;
+	case eWNI_SME_UPPER_LAYER_ASSOC_CNF:
+	{
+		struct csr_roam_session *pSession;
+		tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf;
+		struct csr_roam_info roamInfo;
+		struct csr_roam_info *roam_info = NULL;
+		uint32_t sessionId;
+		QDF_STATUS status;
+
+		sme_debug("ASSOCIATION confirmation can be given to upper layer ");
+		qdf_mem_set(&roamInfo, sizeof(struct csr_roam_info), 0);
+		roam_info = &roamInfo;
+		pUpperLayerAssocCnf =
+			(tSirSmeAssocIndToUpperLayerCnf *) pMsgBuf;
+		status = csr_roam_get_session_id_from_bssid(pMac,
+							(struct qdf_mac_addr *)
+							   pUpperLayerAssocCnf->
+							   bssId, &sessionId);
+		pSession = CSR_GET_SESSION(pMac, sessionId);
+
+		if (!pSession) {
+			sme_err("session %d not found", sessionId);
+			return;
+		}
+		/* send the status code as Success */
+		roam_info->statusCode = eSIR_SME_SUCCESS;
+		roam_info->u.pConnectedProfile =
+			&pSession->connectedProfile;
+		roam_info->staId = (uint8_t) pUpperLayerAssocCnf->aid;
+		roam_info->rsnIELen =
+			(uint8_t) pUpperLayerAssocCnf->rsnIE.length;
+		roam_info->prsnIE =
+			pUpperLayerAssocCnf->rsnIE.rsnIEdata;
+#ifdef FEATURE_WLAN_WAPI
+		roam_info->wapiIELen =
+			(uint8_t) pUpperLayerAssocCnf->wapiIE.length;
+		roam_info->pwapiIE =
+			pUpperLayerAssocCnf->wapiIE.wapiIEdata;
+#endif
+		roam_info->addIELen =
+			(uint8_t) pUpperLayerAssocCnf->addIE.length;
+		roam_info->paddIE =
+			pUpperLayerAssocCnf->addIE.addIEdata;
+		qdf_mem_copy(roam_info->peerMac.bytes,
+			     pUpperLayerAssocCnf->peerMacAddr,
+			     sizeof(tSirMacAddr));
+		qdf_mem_copy(&roam_info->bssid,
+			     pUpperLayerAssocCnf->bssId,
+			     sizeof(struct qdf_mac_addr));
+		roam_info->wmmEnabledSta =
+			pUpperLayerAssocCnf->wmmEnabledSta;
+		roam_info->timingMeasCap =
+			pUpperLayerAssocCnf->timingMeasCap;
+		qdf_mem_copy(&roam_info->chan_info,
+			     &pUpperLayerAssocCnf->chan_info,
+			     sizeof(tSirSmeChanInfo));
+		roam_info->ampdu = pUpperLayerAssocCnf->ampdu;
+		roam_info->sgi_enable = pUpperLayerAssocCnf->sgi_enable;
+		roam_info->tx_stbc = pUpperLayerAssocCnf->tx_stbc;
+		roam_info->tx_stbc = pUpperLayerAssocCnf->rx_stbc;
+		roam_info->ch_width = pUpperLayerAssocCnf->ch_width;
+		roam_info->mode = pUpperLayerAssocCnf->mode;
+		roam_info->max_supp_idx = pUpperLayerAssocCnf->max_supp_idx;
+		roam_info->max_ext_idx = pUpperLayerAssocCnf->max_ext_idx;
+		roam_info->max_mcs_idx = pUpperLayerAssocCnf->max_mcs_idx;
+		roam_info->rx_mcs_map = pUpperLayerAssocCnf->rx_mcs_map;
+		roam_info->tx_mcs_map = pUpperLayerAssocCnf->tx_mcs_map;
+		roam_info->ecsa_capable = pUpperLayerAssocCnf->ecsa_capable;
+		if (pUpperLayerAssocCnf->ht_caps.present)
+			roam_info->ht_caps = pUpperLayerAssocCnf->ht_caps;
+		if (pUpperLayerAssocCnf->vht_caps.present)
+			roam_info->vht_caps = pUpperLayerAssocCnf->vht_caps;
+		if (CSR_IS_INFRA_AP(roam_info->u.pConnectedProfile)) {
+			pMac->roam.roamSession[sessionId].connectState =
+				eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED;
+			roam_info->fReassocReq =
+				pUpperLayerAssocCnf->reassocReq;
+			status = csr_roam_call_callback(pMac, sessionId,
+						       roam_info, 0,
+						       eCSR_ROAM_INFRA_IND,
+					eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF);
+		}
+	}
+	break;
+	default:
+		csr_roam_check_for_link_status_change(pMac, pSirMsg);
+		break;
+	}
+}
+
+QDF_STATUS csr_roam_issue_set_context_req(tpAniSirGlobal pMac,
+					  uint32_t sessionId,
+					  eCsrEncryptionType EncryptType,
+					  tSirBssDescription *pBssDescription,
+					  tSirMacAddr *bssId, bool addKey,
+					  bool fUnicast,
+					  tAniKeyDirection aniKeyDirection,
+					  uint8_t keyId, uint16_t keyLength,
+					  uint8_t *pKey, uint8_t paeRole)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tAniEdType edType;
+
+	sme_debug("sessionId: %d EncryptType: %d", sessionId, EncryptType);
+
+	if (eCSR_ENCRYPT_TYPE_UNKNOWN == EncryptType)
+		EncryptType = eCSR_ENCRYPT_TYPE_NONE;
+
+	edType = csr_translate_encrypt_type_to_ed_type(EncryptType);
+
+	/*
+	 * Allow 0 keys to be set for the non-WPA encrypt types. For WPA encrypt
+	 * types, the num keys must be non-zero or LIM will reject the set
+	 * context (assumes the SET_CONTEXT does not occur until the keys are
+	 * distrubuted).
+	 */
+	if (CSR_IS_ENC_TYPE_STATIC(EncryptType) || addKey) {
+		tCsrRoamSetKey setKey;
+
+		setKey.encType = EncryptType;
+		setKey.keyDirection = aniKeyDirection;
+		qdf_mem_copy(&setKey.peerMac, bssId, sizeof(struct
+							qdf_mac_addr));
+		/* 0 for supplicant */
+		setKey.paeRole = paeRole;
+		/* Key index */
+		setKey.keyId = keyId;
+		setKey.keyLength = keyLength;
+		if (keyLength)
+			qdf_mem_copy(setKey.Key, pKey, keyLength);
+		status = csr_roam_issue_set_key_command(pMac, sessionId,
+							&setKey, 0);
+	}
+	return status;
+}
+
+/**
+ * csr_update_key_cmd() - update key info in set key command
+ * @mac_ctx:         mac global context
+ * @session:         roam session
+ * @set_key:         input set key command
+ * @set_key_cmd:     set key command to update
+ * @is_key_valid:    indicates if key is valid
+ *
+ * This function will validate the key length, adjust if too long. It will
+ * update is_key_valid flag to false if some error has occurred key are local.
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS
+csr_update_key_cmd(tpAniSirGlobal mac_ctx, struct csr_roam_session *session,
+		   tCsrRoamSetKey *set_key, struct setkey_cmd *set_key_cmd,
+		   bool *is_key_valid)
+{
+	switch (set_key->encType) {
+	case eCSR_ENCRYPT_TYPE_WEP40:
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+		/* KeyLength maybe 0 for static WEP */
+		if (set_key->keyLength) {
+			if (set_key->keyLength < CSR_WEP40_KEY_LEN) {
+				sme_warn("Invalid WEP40 keylength [= %d]",
+					set_key->keyLength);
+				*is_key_valid = false;
+				return QDF_STATUS_E_INVAL;
+			}
+
+			set_key_cmd->keyLength = CSR_WEP40_KEY_LEN;
+			qdf_mem_copy(set_key_cmd->Key, set_key->Key,
+				     CSR_WEP40_KEY_LEN);
+		}
+		*is_key_valid = true;
+		break;
+	case eCSR_ENCRYPT_TYPE_WEP104:
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+		/* KeyLength maybe 0 for static WEP */
+		if (set_key->keyLength) {
+			if (set_key->keyLength < CSR_WEP104_KEY_LEN) {
+				sme_warn("Invalid WEP104 keylength [= %d]",
+					set_key->keyLength);
+				*is_key_valid = false;
+				return QDF_STATUS_E_INVAL;
+			}
+
+			set_key_cmd->keyLength = CSR_WEP104_KEY_LEN;
+			qdf_mem_copy(set_key_cmd->Key, set_key->Key,
+				     CSR_WEP104_KEY_LEN);
+		}
+		*is_key_valid = true;
+		break;
+	case eCSR_ENCRYPT_TYPE_TKIP:
+		if (set_key->keyLength < CSR_TKIP_KEY_LEN) {
+			sme_warn("Invalid TKIP keylength [= %d]",
+				set_key->keyLength);
+			*is_key_valid = false;
+			return QDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->keyLength = CSR_TKIP_KEY_LEN;
+		qdf_mem_copy(set_key_cmd->Key, set_key->Key,
+			     CSR_TKIP_KEY_LEN);
+		*is_key_valid = true;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES:
+		if (set_key->keyLength < CSR_AES_KEY_LEN) {
+			sme_warn("Invalid AES/CCMP keylength [= %d]",
+				set_key->keyLength);
+			*is_key_valid = false;
+			return QDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->keyLength = CSR_AES_KEY_LEN;
+		qdf_mem_copy(set_key_cmd->Key, set_key->Key,
+			     CSR_AES_KEY_LEN);
+		*is_key_valid = true;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP:
+		if (set_key->keyLength < CSR_AES_GCMP_KEY_LEN) {
+			sme_warn(
+				"Invalid AES_GCMP keylength [= %d]",
+				set_key->keyLength);
+			*is_key_valid = false;
+			return QDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->keyLength = CSR_AES_GCMP_KEY_LEN;
+		qdf_mem_copy(set_key_cmd->Key, set_key->Key,
+			     CSR_AES_GCMP_KEY_LEN);
+		*is_key_valid = true;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
+		if (set_key->keyLength < CSR_AES_GCMP_256_KEY_LEN) {
+			sme_warn(
+				"Invalid AES_GCMP_256 keylength [= %d]",
+				set_key->keyLength);
+			*is_key_valid = false;
+			return QDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->keyLength = CSR_AES_GCMP_256_KEY_LEN;
+		qdf_mem_copy(set_key_cmd->Key, set_key->Key,
+			     CSR_AES_GCMP_256_KEY_LEN);
+		*is_key_valid = true;
+		break;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_ENCRYPT_TYPE_WPI:
+		if (set_key->keyLength < CSR_WAPI_KEY_LEN) {
+			sme_warn("Invalid WAPI keylength [= %d]",
+				set_key->keyLength);
+			*is_key_valid = false;
+			return QDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->keyLength = CSR_WAPI_KEY_LEN;
+		qdf_mem_copy(set_key_cmd->Key, set_key->Key,
+			     CSR_WAPI_KEY_LEN);
+		if (session->pCurRoamProfile) {
+			session->pCurRoamProfile->negotiatedUCEncryptionType =
+				eCSR_ENCRYPT_TYPE_WPI;
+		} else {
+			sme_err("pCurRoamProfile is NULL");
+			*is_key_valid = false;
+			return QDF_STATUS_E_INVAL;
+		}
+		*is_key_valid = true;
+		break;
+#endif /* FEATURE_WLAN_WAPI */
+#ifdef FEATURE_WLAN_ESE
+	case eCSR_ENCRYPT_TYPE_KRK:
+		/* no need to enqueue KRK key request, since they are local */
+		*is_key_valid = false;
+		if (set_key->keyLength < CSR_KRK_KEY_LEN) {
+			sme_warn("Invalid KRK keylength [= %d]",
+				set_key->keyLength);
+			return QDF_STATUS_E_INVAL;
+		}
+		qdf_mem_copy(session->eseCckmInfo.krk, set_key->Key,
+			     CSR_KRK_KEY_LEN);
+		session->eseCckmInfo.reassoc_req_num = 1;
+		session->eseCckmInfo.krk_plumbed = true;
+		break;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	case eCSR_ENCRYPT_TYPE_BTK:
+		/* no need to enqueue KRK key request, since they are local */
+		*is_key_valid = false;
+		if (set_key->keyLength < SIR_BTK_KEY_LEN) {
+			sme_warn("LFR3:Invalid BTK keylength [= %d]",
+				set_key->keyLength);
+			return QDF_STATUS_E_INVAL;
+		}
+		qdf_mem_copy(session->eseCckmInfo.btk, set_key->Key,
+			     SIR_BTK_KEY_LEN);
+		/*
+		 * KRK and BTK are updated by upper layer back to back. Send
+		 * updated KRK and BTK together to FW here.
+		 */
+		csr_roam_offload_scan(mac_ctx, session->sessionId,
+				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				      REASON_ROAM_PSK_PMK_CHANGED);
+		break;
+#endif
+#endif /* FEATURE_WLAN_ESE */
+#ifdef WLAN_FEATURE_11W
+	/* Check for 11w BIP */
+	case eCSR_ENCRYPT_TYPE_AES_CMAC:
+		if (set_key->keyLength < CSR_AES_KEY_LEN) {
+			sme_warn("Invalid AES/CCMP keylength [= %d]",
+				set_key->keyLength);
+			*is_key_valid = false;
+			return QDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->keyLength = CSR_AES_KEY_LEN;
+		qdf_mem_copy(set_key_cmd->Key, set_key->Key,
+			     CSR_AES_KEY_LEN);
+		*is_key_valid = true;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_AES_GMAC_128:
+		if (set_key->keyLength < CSR_AES_GMAC_128_KEY_LEN) {
+			sme_warn("Invalid AES GMAC 128 keylength [= %d]",
+				set_key->keyLength);
+			*is_key_valid = false;
+			return QDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->keyLength = CSR_AES_GMAC_128_KEY_LEN;
+		qdf_mem_copy(set_key_cmd->Key, set_key->Key,
+			     CSR_AES_GMAC_128_KEY_LEN);
+		*is_key_valid = true;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_AES_GMAC_256:
+		if (set_key->keyLength < CSR_AES_GMAC_256_KEY_LEN) {
+			sme_warn("Invalid AES GMAC 256 keylength [= %d]",
+				set_key->keyLength);
+			*is_key_valid = false;
+			return QDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->keyLength = CSR_AES_GMAC_256_KEY_LEN;
+		qdf_mem_copy(set_key_cmd->Key, set_key->Key,
+			     CSR_AES_GMAC_256_KEY_LEN);
+		*is_key_valid = true;
+		break;
+
+#endif /* WLAN_FEATURE_11W */
+	default:
+		/* for open security also we want to enqueue command */
+		*is_key_valid = true;
+		return QDF_STATUS_SUCCESS;
+	} /* end of switch */
+	return QDF_STATUS_SUCCESS;
+}
+
+
+static QDF_STATUS csr_roam_issue_set_key_command(
+tpAniSirGlobal mac_ctx, uint32_t session_id,
+		 tCsrRoamSetKey *set_key,
+		 uint32_t roam_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	bool is_key_valid = true;
+	struct setkey_cmd set_key_cmd;
+#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_WAPI)
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (NULL == session) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			 "session %d not found", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+#endif /* FEATURE_WLAN_ESE */
+
+	qdf_mem_zero(&set_key_cmd, sizeof(struct setkey_cmd));
+	/*
+	 * following function will validate the key length, Adjust if too long.
+	 * for static WEP the keys are not set thru' SetContextReq
+	 *
+	 * it will update bool is_key_valid, to false if some error has occurred
+	 * key are local. enqueue sme command only if is_key_valid is true
+	 * status is indication of success or failure and will be returned to
+	 * called of current function if command is not enqueued due to key req
+	 * being local
+	 */
+	status = csr_update_key_cmd(mac_ctx, session, set_key,
+				    &set_key_cmd, &is_key_valid);
+	if (is_key_valid) {
+		set_key_cmd.roamId = roam_id;
+		set_key_cmd.encType = set_key->encType;
+		set_key_cmd.keyDirection = set_key->keyDirection;
+		qdf_copy_macaddr(&set_key_cmd.peermac,
+				 &set_key->peerMac);
+		/* 0 for supplicant */
+		set_key_cmd.paeRole = set_key->paeRole;
+		set_key_cmd.keyId = set_key->keyId;
+		qdf_mem_copy(set_key_cmd.keyRsc, set_key->keyRsc,
+			     CSR_MAX_RSC_LEN);
+		/*
+		 * Always put set key to the head of the Q because it is the
+		 * only thing to get executed in case of WT_KEY state
+		 */
+		sme_debug("set key req for session-%d authtype-%d",
+			session_id, set_key->encType);
+		status = csr_roam_send_set_key_cmd(mac_ctx, session_id,
+						&set_key_cmd);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			sme_err("fail to send message status = %d", status);
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_send_set_key_cmd(tpAniSirGlobal mac_ctx,
+				uint32_t session_id,
+				struct setkey_cmd *set_key_cmd)
+{
+	QDF_STATUS status;
+	uint8_t num_keys = (set_key_cmd->keyLength) ? 1 : 0;
+	tAniEdType ed_type = csr_translate_encrypt_type_to_ed_type(
+						set_key_cmd->encType);
+	bool unicast = (set_key_cmd->peermac.bytes[0] == 0xFF) ? false : true;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	struct wlan_mlme_wep_cfg *wep_params = &mac_ctx->mlme_cfg->wep_params;
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent,
+				 host_event_wlan_security_payload_type);
+
+	if (NULL == session) {
+		sme_err("session %d not found", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (eSIR_ED_NONE != ed_type) {
+		qdf_mem_set(&setKeyEvent,
+			sizeof(host_event_wlan_security_payload_type), 0);
+		if (qdf_is_macaddr_group(&set_key_cmd->peermac)) {
+			setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_BCAST_REQ;
+			setKeyEvent.encryptionModeMulticast =
+				(uint8_t) diag_enc_type_from_csr_type(
+					set_key_cmd->encType);
+			setKeyEvent.encryptionModeUnicast =
+				(uint8_t) diag_enc_type_from_csr_type(session->
+							connectedProfile.
+							EncryptionType);
+		} else {
+			setKeyEvent.eventId =
+				WLAN_SECURITY_EVENT_SET_UNICAST_REQ;
+			setKeyEvent.encryptionModeUnicast =
+				(uint8_t) diag_enc_type_from_csr_type(
+					set_key_cmd->encType);
+			setKeyEvent.encryptionModeMulticast =
+				(uint8_t) diag_enc_type_from_csr_type(session->
+							connectedProfile.
+							mcEncryptionType);
+		}
+		qdf_mem_copy(setKeyEvent.bssid,
+			     session->connectedProfile.bssid.bytes,
+			     QDF_MAC_ADDR_SIZE);
+		if (CSR_IS_ENC_TYPE_STATIC(set_key_cmd->encType)) {
+			/* It has to be static WEP here */
+			setKeyEvent.keyId = wep_params->wep_default_key_id;
+		} else {
+			setKeyEvent.keyId = set_key_cmd->keyId;
+		}
+		setKeyEvent.authMode =
+			(uint8_t) diag_auth_type_from_csr_type(session->
+							       connectedProfile.
+							       AuthType);
+		WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY);
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	if (csr_is_set_key_allowed(mac_ctx, session_id)) {
+		status = csr_send_mb_set_context_req_msg(mac_ctx, session_id,
+					set_key_cmd->peermac,
+					num_keys, ed_type, unicast,
+					set_key_cmd->keyDirection,
+					set_key_cmd->keyId,
+					set_key_cmd->keyLength,
+					set_key_cmd->Key,
+					set_key_cmd->paeRole,
+					set_key_cmd->keyRsc);
+	} else {
+		sme_warn(" cannot process not connected");
+		/* Set this status so the error handling take
+		 * care of the case.
+		 */
+		status = QDF_STATUS_CSR_WRONG_STATE;
+	}
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("  error status %d", status);
+		csr_roam_call_callback(mac_ctx, session_id, NULL,
+				       set_key_cmd->roamId,
+				       eCSR_ROAM_SET_KEY_COMPLETE,
+				       eCSR_ROAM_RESULT_FAILURE);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+		if (eSIR_ED_NONE != ed_type) {
+			if (qdf_is_macaddr_group(&set_key_cmd->peermac))
+				setKeyEvent.eventId =
+					WLAN_SECURITY_EVENT_SET_BCAST_RSP;
+			else
+				setKeyEvent.eventId =
+					WLAN_SECURITY_EVENT_SET_UNICAST_RSP;
+			setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE;
+			WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent,
+						    EVENT_WLAN_SECURITY);
+		}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_set_key(tpAniSirGlobal pMac, uint32_t sessionId,
+			    tCsrRoamSetKey *pSetKey, uint32_t roamId)
+{
+	QDF_STATUS status;
+
+	if (!csr_is_set_key_allowed(pMac, sessionId)) {
+		status = QDF_STATUS_CSR_WRONG_STATE;
+	} else {
+		status = csr_roam_issue_set_key_command(pMac, sessionId,
+							pSetKey, roamId);
+	}
+	return status;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/*
+ * csr_create_fils_realm_hash: API to create hash using realm
+ * @fils_con_info: fils connection info obtained from supplicant
+ * @tmp_hash: pointer to new hash
+ *
+ * Return: None
+ */
+static bool
+csr_create_fils_realm_hash(struct cds_fils_connection_info *fils_con_info,
+			   uint8_t *tmp_hash)
+{
+	uint8_t *hash;
+	uint8_t *data[1];
+
+	if (!fils_con_info->realm_len)
+		return false;
+
+	hash = qdf_mem_malloc(SHA256_DIGEST_SIZE);
+	if (!hash)
+		return false;
+
+	data[0] = fils_con_info->realm;
+	qdf_get_hash(SHA256_CRYPTO_TYPE, 1, data,
+			&fils_con_info->realm_len, hash);
+	qdf_trace_hex_dump(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
+				   hash, SHA256_DIGEST_SIZE);
+	qdf_mem_copy(tmp_hash, hash, 2);
+	qdf_mem_free(hash);
+	return true;
+}
+
+/*
+ * csr_update_fils_scan_filter: update scan filter in case of fils session
+ * @scan_fltr: pointer to scan filer
+ * @profile: csr profile pointer
+ *
+ * Return: None
+ */
+static void csr_update_fils_scan_filter(tCsrScanResultFilter *scan_fltr,
+				struct csr_roam_profile *profile)
+{
+	if (profile->fils_con_info &&
+	    profile->fils_con_info->is_fils_connection) {
+		uint8_t realm_hash[2];
+
+		sme_debug("creating realm based on fils info %d",
+			profile->fils_con_info->is_fils_connection);
+		scan_fltr->realm_check =  csr_create_fils_realm_hash(
+				profile->fils_con_info, realm_hash);
+		memcpy(scan_fltr->fils_realm, realm_hash,
+			sizeof(uint8_t) * 2);
+	}
+
+}
+#else
+static void csr_update_fils_scan_filter(tCsrScanResultFilter *scan_fltr,
+				struct csr_roam_profile *profile)
+{ }
+#endif
+
+/*
+ * Prepare a filter base on a profile for parsing the scan results.
+ * Upon successful return, caller MUST call csr_free_scan_filter on
+ *pScanFilter when it is done with the filter.
+ */
+QDF_STATUS
+csr_roam_prepare_filter_from_profile(tpAniSirGlobal mac_ctx,
+				     struct csr_roam_profile *profile,
+				     tCsrScanResultFilter *scan_fltr)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t size = 0;
+	uint8_t idx = 0;
+	tCsrChannelInfo *fltr_ch_info = &scan_fltr->ChannelInfo;
+	tCsrChannelInfo *profile_ch_info = &profile->ChannelInfo;
+	struct roam_ext_params *roam_params;
+	uint8_t i;
+
+	roam_params = &mac_ctx->roam.configParam.roam_params;
+
+	if (profile->BSSIDs.numOfBSSIDs) {
+		size = sizeof(struct qdf_mac_addr) * profile->BSSIDs.
+							numOfBSSIDs;
+		scan_fltr->BSSIDs.bssid = qdf_mem_malloc(size);
+		if (NULL == scan_fltr->BSSIDs.bssid) {
+			status = QDF_STATUS_E_NOMEM;
+			goto free_filter;
+		}
+		scan_fltr->BSSIDs.numOfBSSIDs = profile->BSSIDs.numOfBSSIDs;
+		qdf_mem_copy(scan_fltr->BSSIDs.bssid,
+			     profile->BSSIDs.bssid, size);
+	}
+
+	if (profile->SSIDs.numOfSSIDs) {
+		scan_fltr->SSIDs.numOfSSIDs = profile->SSIDs.numOfSSIDs;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			("No of Allowed List:%d"),
+			roam_params->num_ssid_allowed_list);
+		if (scan_fltr->scan_filter_for_roam
+			&& roam_params->num_ssid_allowed_list) {
+			scan_fltr->SSIDs.numOfSSIDs =
+				roam_params->num_ssid_allowed_list;
+			size = sizeof(tCsrSSIDInfo) *
+				scan_fltr->SSIDs.numOfSSIDs;
+			scan_fltr->SSIDs.SSIDList = qdf_mem_malloc(size);
+			if (NULL == scan_fltr->SSIDs.SSIDList)
+				status = QDF_STATUS_E_FAILURE;
+			else
+				status = QDF_STATUS_SUCCESS;
+			if (!QDF_IS_STATUS_SUCCESS(status))
+				goto free_filter;
+			for  (i = 0;
+				i < roam_params->num_ssid_allowed_list;
+				i++) {
+				qdf_mem_copy((void *)
+				    scan_fltr->SSIDs.SSIDList[i].SSID.ssId,
+				    roam_params->ssid_allowed_list[i].ssId,
+				    roam_params->ssid_allowed_list[i].length);
+				scan_fltr->SSIDs.SSIDList[i].SSID.length =
+				    roam_params->ssid_allowed_list[i].length;
+				scan_fltr->SSIDs.SSIDList[i].handoffPermitted =
+					1;
+				scan_fltr->SSIDs.SSIDList[i].ssidHidden = 0;
+			}
+		} else {
+			size = sizeof(tCsrSSIDInfo) *
+				profile->SSIDs.numOfSSIDs;
+			scan_fltr->SSIDs.SSIDList = qdf_mem_malloc(size);
+			if (NULL == scan_fltr->SSIDs.SSIDList) {
+				status = QDF_STATUS_E_NOMEM;
+				goto free_filter;
+			}
+			qdf_mem_copy(scan_fltr->SSIDs.SSIDList,
+					profile->SSIDs.SSIDList, size);
+		}
+	}
+
+	if (!profile_ch_info->ChannelList
+	    || (profile_ch_info->ChannelList[0] == 0)) {
+		fltr_ch_info->numOfChannels = 0;
+		fltr_ch_info->ChannelList = NULL;
+	} else if (profile_ch_info->numOfChannels) {
+		fltr_ch_info->numOfChannels = 0;
+		fltr_ch_info->ChannelList =
+			qdf_mem_malloc(sizeof(*(fltr_ch_info->ChannelList)) *
+				       profile_ch_info->numOfChannels);
+		if (NULL == fltr_ch_info->ChannelList) {
+			status = QDF_STATUS_E_NOMEM;
+			goto free_filter;
+		}
+
+		for (idx = 0; idx < profile_ch_info->numOfChannels; idx++) {
+			if (csr_roam_is_channel_valid(mac_ctx,
+				profile_ch_info->ChannelList[idx])) {
+				fltr_ch_info->
+				ChannelList[fltr_ch_info->numOfChannels]
+					= profile_ch_info->ChannelList[idx];
+				fltr_ch_info->numOfChannels++;
+			} else {
+				sme_debug(
+					"Channel (%d) is invalid",
+					profile_ch_info->ChannelList[idx]);
+			}
+		}
+	} else {
+		sme_err("Channel list empty");
+		status = QDF_STATUS_E_FAILURE;
+		goto free_filter;
+	}
+	scan_fltr->uapsd_mask = profile->uapsd_mask;
+	scan_fltr->authType = profile->AuthType;
+	scan_fltr->EncryptionType = profile->EncryptionType;
+	scan_fltr->mcEncryptionType = profile->mcEncryptionType;
+	scan_fltr->BSSType = profile->BSSType;
+	scan_fltr->phyMode = profile->phyMode;
+#ifdef FEATURE_WLAN_WAPI
+	/*
+	 * check if user asked for WAPI with 11n or auto mode, in that
+	 * case modify the phymode to 11g
+	 */
+	if (csr_is_profile_wapi(profile)) {
+		if (scan_fltr->phyMode & eCSR_DOT11_MODE_11n)
+			scan_fltr->phyMode &= ~eCSR_DOT11_MODE_11n;
+		if (scan_fltr->phyMode & eCSR_DOT11_MODE_AUTO)
+			scan_fltr->phyMode &= ~eCSR_DOT11_MODE_AUTO;
+		if (!scan_fltr->phyMode)
+			scan_fltr->phyMode = eCSR_DOT11_MODE_11g;
+	}
+#endif /* FEATURE_WLAN_WAPI */
+	/*Save the WPS info */
+	scan_fltr->bWPSAssociation = profile->bWPSAssociation;
+	scan_fltr->bOSENAssociation = profile->bOSENAssociation;
+	if (profile->countryCode[0]) {
+		/*
+		 * This causes the matching function to use countryCode as one
+		 * of the criteria.
+		 */
+		qdf_mem_copy(scan_fltr->countryCode, profile->countryCode,
+			     WNI_CFG_COUNTRY_CODE_LEN);
+	}
+	if (profile->MDID.mdiePresent) {
+		scan_fltr->MDID.mdiePresent = 1;
+		scan_fltr->MDID.mobilityDomain = profile->MDID.mobilityDomain;
+	}
+	qdf_mem_copy(scan_fltr->bssid_hint.bytes,
+		profile->bssid_hint.bytes, QDF_MAC_ADDR_SIZE);
+
+#ifdef WLAN_FEATURE_11W
+	/* Management Frame Protection */
+	scan_fltr->MFPEnabled = profile->MFPEnabled;
+	scan_fltr->MFPRequired = profile->MFPRequired;
+	scan_fltr->MFPCapable = profile->MFPCapable;
+#endif
+	scan_fltr->csrPersona = profile->csrPersona;
+	csr_update_fils_scan_filter(scan_fltr, profile);
+	scan_fltr->force_rsne_override = profile->force_rsne_override;
+
+free_filter:
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		csr_free_scan_filter(mac_ctx, scan_fltr);
+
+	return status;
+}
+
+static
+bool csr_roam_issue_wm_status_change(tpAniSirGlobal pMac, uint32_t sessionId,
+				     enum csr_roam_wmstatus_changetypes Type,
+				     tSirSmeRsp *pSmeRsp)
+{
+	bool fCommandQueued = false;
+	tSmeCmd *pCommand;
+
+	do {
+		/* Validate the type is ok... */
+		if ((eCsrDisassociated != Type)
+		    && (eCsrDeauthenticated != Type))
+			break;
+		pCommand = csr_get_command_buffer(pMac);
+		if (!pCommand) {
+			sme_err(" fail to get command buffer");
+			break;
+		}
+		/* Change the substate in case it is waiting for key */
+		if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
+			csr_roam_stop_wait_for_key_timer(pMac);
+			csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+						 sessionId);
+		}
+		pCommand->command = eSmeCommandWmStatusChange;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.wmStatusChangeCmd.Type = Type;
+		if (eCsrDisassociated == Type) {
+			qdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u.
+				     DisassocIndMsg, pSmeRsp,
+				     sizeof(pCommand->u.wmStatusChangeCmd.u.
+					    DisassocIndMsg));
+		} else {
+			qdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u.
+				     DeauthIndMsg, pSmeRsp,
+				     sizeof(pCommand->u.wmStatusChangeCmd.u.
+					    DeauthIndMsg));
+		}
+		if (QDF_IS_STATUS_SUCCESS
+			    (csr_queue_sme_command(pMac, pCommand, false)))
+			fCommandQueued = true;
+		else
+			sme_err("fail to send message");
+
+		/* AP has issued Dissac/Deauth, Set the operating mode
+		 * value to configured value
+		 */
+		csr_set_default_dot11_mode(pMac);
+	} while (0);
+	return fCommandQueued;
+}
+
+static QDF_STATUS csr_send_snr_request(void *pGetRssiReq)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma_handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (QDF_STATUS_SUCCESS !=
+		wma_send_snr_request(wma_handle, pGetRssiReq)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"Failed to Trigger wma stats request");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* dont send success, otherwise call back
+	 * will released with out values
+	 */
+	return QDF_STATUS_E_BUSY;
+}
+
+static void csr_update_rssi(tpAniSirGlobal pMac, void *pMsg)
+{
+	int8_t rssi = 0;
+	tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq *) pMsg;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	if (pGetRssiReq) {
+		qdf_status = csr_send_snr_request(pGetRssiReq);
+
+		if (NULL != pGetRssiReq->rssiCallback) {
+			if (qdf_status != QDF_STATUS_E_BUSY)
+				((tCsrRssiCallback) (pGetRssiReq->rssiCallback))
+					(rssi, pGetRssiReq->staId,
+					pGetRssiReq->pDevContext);
+			else
+				sme_debug("rssi request is posted. waiting for reply");
+		} else {
+			sme_err("GetRssiReq->rssiCallback is NULL");
+			return;
+		}
+	} else
+		sme_err("pGetRssiReq is NULL");
+
+}
+
+static void csr_update_snr(tpAniSirGlobal pMac, void *pMsg)
+{
+	tAniGetSnrReq *pGetSnrReq = (tAniGetSnrReq *) pMsg;
+
+	if (pGetSnrReq) {
+		if (QDF_STATUS_SUCCESS != wma_get_snr(pGetSnrReq)) {
+			sme_err("Error in wma_get_snr");
+			return;
+		}
+
+	} else
+		sme_err("pGetSnrReq is NULL");
+}
+
+static QDF_STATUS csr_send_reset_ap_caps_changed(tpAniSirGlobal pMac,
+				struct qdf_mac_addr *bssId)
+{
+	tpSirResetAPCapsChange pMsg;
+	uint16_t len;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	/* Create the message and send to lim */
+	len = sizeof(tSirResetAPCapsChange);
+	pMsg = qdf_mem_malloc(len);
+	if (NULL == pMsg)
+		status = QDF_STATUS_E_NOMEM;
+	else
+		status = QDF_STATUS_SUCCESS;
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pMsg->messageType = eWNI_SME_RESET_AP_CAPS_CHANGED;
+		pMsg->length = len;
+		qdf_copy_macaddr(&pMsg->bssId, bssId);
+		sme_debug(
+			"CSR reset caps change for Bssid= " MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(pMsg->bssId.bytes));
+		status = umac_send_mb_message_to_mac(pMsg);
+	} else {
+		sme_err("Memory allocation failed");
+	}
+	return status;
+}
+
+static void
+csr_roam_chk_lnk_assoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	struct csr_roam_session *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	QDF_STATUS status;
+	struct csr_roam_info *roam_info_ptr = NULL;
+	tSirSmeAssocInd *pAssocInd;
+	struct csr_roam_info roam_info;
+
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sme_debug("Receive WNI_SME_ASSOC_IND from SME");
+	pAssocInd = (tSirSmeAssocInd *) msg_ptr;
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+				(struct qdf_mac_addr *) pAssocInd->bssId,
+				&sessionId);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_debug("Couldn't find session_id for given BSSID");
+		return;
+	}
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+	roam_info_ptr = &roam_info;
+	/* Required for indicating the frames to upper layer */
+	roam_info_ptr->assocReqLength = pAssocInd->assocReqLength;
+	roam_info_ptr->assocReqPtr = pAssocInd->assocReqPtr;
+	roam_info_ptr->beaconPtr = pAssocInd->beaconPtr;
+	roam_info_ptr->beaconLength = pAssocInd->beaconLength;
+	roam_info_ptr->statusCode = eSIR_SME_SUCCESS;
+	roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
+	roam_info_ptr->staId = (uint8_t) pAssocInd->staId;
+	roam_info_ptr->rsnIELen = (uint8_t) pAssocInd->rsnIE.length;
+	roam_info_ptr->prsnIE = pAssocInd->rsnIE.rsnIEdata;
+#ifdef FEATURE_WLAN_WAPI
+	roam_info_ptr->wapiIELen = (uint8_t) pAssocInd->wapiIE.length;
+	roam_info_ptr->pwapiIE = pAssocInd->wapiIE.wapiIEdata;
+#endif
+	roam_info_ptr->addIELen = (uint8_t) pAssocInd->addIE.length;
+	roam_info_ptr->paddIE = pAssocInd->addIE.addIEdata;
+	qdf_mem_copy(roam_info_ptr->peerMac.bytes,
+		     pAssocInd->peerMacAddr,
+		     sizeof(tSirMacAddr));
+	qdf_mem_copy(roam_info_ptr->bssid.bytes,
+		     pAssocInd->bssId,
+		     sizeof(struct qdf_mac_addr));
+	roam_info_ptr->wmmEnabledSta = pAssocInd->wmmEnabledSta;
+	roam_info_ptr->timingMeasCap = pAssocInd->timingMeasCap;
+	roam_info_ptr->ecsa_capable = pAssocInd->ecsa_capable;
+	qdf_mem_copy(&roam_info_ptr->chan_info,
+		     &pAssocInd->chan_info,
+		     sizeof(tSirSmeChanInfo));
+
+	if (pAssocInd->HTCaps.present)
+		qdf_mem_copy(&roam_info_ptr->ht_caps,
+			     &pAssocInd->HTCaps,
+			     sizeof(tDot11fIEHTCaps));
+	if (pAssocInd->VHTCaps.present)
+		qdf_mem_copy(&roam_info_ptr->vht_caps,
+			     &pAssocInd->VHTCaps,
+			     sizeof(tDot11fIEVHTCaps));
+
+	if (CSR_IS_INFRA_AP(roam_info_ptr->u.pConnectedProfile)) {
+		if (session->pCurRoamProfile &&
+		    CSR_IS_ENC_TYPE_STATIC(
+			session->pCurRoamProfile->negotiatedUCEncryptionType)) {
+			/* NO keys... these key parameters don't matter. */
+			csr_roam_issue_set_context_req(mac_ctx, sessionId,
+			session->pCurRoamProfile->negotiatedUCEncryptionType,
+			session->pConnectBssDesc,
+			&(roam_info_ptr->peerMac.bytes),
+			false, true, eSIR_TX_RX, 0, 0, NULL, 0);
+			roam_info_ptr->fAuthRequired = false;
+		} else {
+			roam_info_ptr->fAuthRequired = true;
+		}
+		status = csr_roam_call_callback(mac_ctx, sessionId,
+					roam_info_ptr, 0, eCSR_ROAM_INFRA_IND,
+					eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			/* Refused due to Mac filtering */
+			roam_info_ptr->statusCode = eSIR_SME_ASSOC_REFUSED;
+	}
+
+	/* Send Association completion message to PE */
+	status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status);
+	/*
+	 * send a message to CSR itself just to avoid the EAPOL frames going
+	 * OTA before association response
+	 */
+	if (CSR_IS_INFRA_AP(roam_info_ptr->u.pConnectedProfile)
+	    && (roam_info_ptr->statusCode != eSIR_SME_ASSOC_REFUSED)) {
+		roam_info_ptr->fReassocReq = pAssocInd->reassocReq;
+		status = csr_send_assoc_ind_to_upper_layer_cnf_msg(mac_ctx,
+						pAssocInd, status, sessionId);
+	}
+}
+
+/*
+ * csr_is_deauth_disassoc_already_active() - Function to check if deauth or
+ *  disassoc is already in progress.
+ * @mac_ctx: Global MAC context
+ * @session_id: session id
+ * @peer_macaddr: Peer MAC address
+ *
+ * Return: True if deauth/disassoc indication can be dropped
+ *  else false
+ */
+static bool csr_is_deauth_disassoc_already_active(tpAniSirGlobal mac_ctx,
+					       uint8_t session_id,
+					       struct qdf_mac_addr peer_macaddr)
+{
+	bool ret = false;
+	tSmeCmd *sme_cmd;
+
+	sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, session_id,
+						 WLAN_SER_CMD_FORCE_DEAUTH_STA);
+	if (!sme_cmd) {
+		sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc,
+					       session_id,
+					       WLAN_SER_CMD_FORCE_DISASSOC_STA);
+		if (!sme_cmd)
+			return ret;
+	}
+
+	if ((mac_ctx->roam.curSubState[session_id] ==
+	     eCSR_ROAM_SUBSTATE_DEAUTH_REQ ||
+	     mac_ctx->roam.curSubState[session_id] ==
+	     eCSR_ROAM_SUBSTATE_DISASSOC_REQ) &&
+	    !qdf_mem_cmp(peer_macaddr.bytes, sme_cmd->u.roamCmd.peerMac,
+			 QDF_MAC_ADDR_SIZE)) {
+		sme_debug("Ignore DEAUTH_IND/DIASSOC_IND as Deauth/Disassoc already in progress");
+		ret = true;
+	}
+
+	return ret;
+}
+
+static void
+csr_roam_chk_lnk_disassoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	struct csr_roam_session *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	QDF_STATUS status;
+	tSirSmeDisassocInd *pDisassocInd;
+	tSmeCmd *cmd;
+
+	cmd = qdf_mem_malloc(sizeof(*cmd));
+	if (!cmd)
+		return;
+
+	/*
+	 * Check if AP dis-associated us because of MIC failure. If so,
+	 * then we need to take action immediately and not wait till the
+	 * the WmStatusChange requests is pushed and processed
+	 */
+	pDisassocInd = (tSirSmeDisassocInd *) msg_ptr;
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+				&pDisassocInd->bssid, &sessionId);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Session Id not found for BSSID "MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(pDisassocInd->bssid.bytes));
+		qdf_mem_free(cmd);
+		return;
+	}
+
+	if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
+	    pDisassocInd->peer_macaddr)) {
+		qdf_mem_free(cmd);
+		return;
+	}
+
+	sme_err("DISASSOCIATION from peer =" MAC_ADDRESS_STR "reason: %d status: %d session: %d",
+		MAC_ADDR_ARRAY(pDisassocInd->peer_macaddr.bytes),
+		pDisassocInd->reasonCode,
+		pDisassocInd->statusCode, sessionId);
+	/*
+	 * If we are in neighbor preauth done state then on receiving
+	 * disassoc or deauth we dont roam instead we just disassoc
+	 * from current ap and then go to disconnected state
+	 * This happens for ESE and 11r FT connections ONLY.
+	 */
+	if (csr_roam_is11r_assoc(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+#ifdef FEATURE_WLAN_ESE
+	if (csr_roam_is_ese_assoc(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+#endif
+	if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sme_err("session: %d not found", sessionId);
+		qdf_mem_free(cmd);
+		return;
+	}
+
+	/* Update the disconnect stats */
+	session->disconnect_stats.disconnection_cnt++;
+	session->disconnect_stats.disassoc_by_peer++;
+
+	if (csr_is_conn_state_infra(mac_ctx, sessionId))
+		session->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId,
+			      SME_QOS_CSR_DISCONNECT_IND, NULL);
+#endif
+	csr_roam_link_down(mac_ctx, sessionId);
+	csr_roam_issue_wm_status_change(mac_ctx, sessionId,
+					eCsrDisassociated, msg_ptr);
+	if (CSR_IS_INFRA_AP(&session->connectedProfile)) {
+		/*
+		 * STA/P2P client got  disassociated so remove any pending
+		 * deauth commands in sme pending list
+		 */
+		cmd->command = eSmeCommandRoam;
+		cmd->sessionId = (uint8_t) sessionId;
+		cmd->u.roamCmd.roamReason = eCsrForcedDeauthSta;
+		qdf_mem_copy(cmd->u.roamCmd.peerMac,
+			     pDisassocInd->peer_macaddr.bytes,
+			     QDF_MAC_ADDR_SIZE);
+		csr_roam_remove_duplicate_command(mac_ctx, sessionId, cmd,
+						  eCsrForcedDeauthSta);
+	}
+	qdf_mem_free(cmd);
+}
+
+/**
+ * csr_roam_send_disconnect_done_indication() - Send disconnect ind to HDD.
+ *
+ * @mac_ctx: mac global context
+ * @msg_ptr: incoming message
+ *
+ * This function gives final disconnect event to HDD after all cleanup in
+ * lower layers is done.
+ *
+ * Return: None
+ */
+static void
+csr_roam_send_disconnect_done_indication(tpAniSirGlobal mac_ctx, tSirSmeRsp
+				     *msg_ptr)
+{
+	struct sir_sme_discon_done_ind *discon_ind =
+				(struct sir_sme_discon_done_ind *)(msg_ptr);
+	struct csr_roam_info roam_info;
+	struct csr_roam_session *session;
+
+	sme_debug("eWNI_SME_DISCONNECT_DONE_IND RC:%d",
+		discon_ind->reason_code);
+
+	if (CSR_IS_SESSION_VALID(mac_ctx, discon_ind->session_id)) {
+		roam_info.reasonCode = discon_ind->reason_code;
+		roam_info.statusCode = eSIR_SME_STA_NOT_ASSOCIATED;
+		qdf_mem_copy(roam_info.peerMac.bytes, discon_ind->peer_mac,
+			     ETH_ALEN);
+
+		roam_info.rssi = mac_ctx->peer_rssi;
+		roam_info.tx_rate = mac_ctx->peer_txrate;
+		roam_info.rx_rate = mac_ctx->peer_rxrate;
+		roam_info.disassoc_reason = discon_ind->reason_code;
+
+		csr_roam_call_callback(mac_ctx, discon_ind->session_id,
+				       &roam_info, 0, eCSR_ROAM_LOSTLINK,
+				       eCSR_ROAM_RESULT_DISASSOC_IND);
+		session = CSR_GET_SESSION(mac_ctx, discon_ind->session_id);
+		if (session &&
+		   !CSR_IS_INFRA_AP(&session->connectedProfile))
+			csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
+				discon_ind->session_id);
+
+	} else
+		sme_err("Inactive session %d",
+			discon_ind->session_id);
+
+	/*
+	 * Release WM status change command as eWNI_SME_DISCONNECT_DONE_IND
+	 * has been sent to HDD and there is nothing else left to do.
+	 */
+	csr_roam_wm_status_change_complete(mac_ctx, discon_ind->session_id);
+}
+
+static void
+csr_roam_chk_lnk_deauth_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	struct csr_roam_session *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	QDF_STATUS status;
+	tSirSmeDeauthInd *pDeauthInd;
+	struct csr_roam_info roam_info;
+
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sme_debug("DEAUTHENTICATION Indication from MAC");
+	pDeauthInd = (tpSirSmeDeauthInd) msg_ptr;
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+						   &pDeauthInd->bssid,
+						   &sessionId);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return;
+
+	if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
+	    pDeauthInd->peer_macaddr))
+		return;
+	/* If we are in neighbor preauth done state then on receiving
+	 * disassoc or deauth we dont roam instead we just disassoc
+	 * from current ap and then go to disconnected state
+	 * This happens for ESE and 11r FT connections ONLY.
+	 */
+	if (csr_roam_is11r_assoc(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+#ifdef FEATURE_WLAN_ESE
+	if (csr_roam_is_ese_assoc(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+#endif
+	if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+
+	/* Update the disconnect stats */
+	switch (pDeauthInd->reasonCode) {
+	case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
+		session->disconnect_stats.disconnection_cnt++;
+		session->disconnect_stats.peer_kickout++;
+		break;
+	case eSIR_MAC_UNSPEC_FAILURE_REASON:
+	case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON:
+	case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
+	case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON:
+	case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON:
+	case eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON:
+		session->disconnect_stats.disconnection_cnt++;
+		session->disconnect_stats.deauth_by_peer++;
+		break;
+	case eSIR_BEACON_MISSED:
+		session->disconnect_stats.disconnection_cnt++;
+		session->disconnect_stats.bmiss++;
+		break;
+	default:
+		/* Unknown reason code */
+		break;
+	}
+
+	if (csr_is_conn_state_infra(mac_ctx, sessionId))
+		session->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId,
+			      SME_QOS_CSR_DISCONNECT_IND, NULL);
+#endif
+	csr_roam_link_down(mac_ctx, sessionId);
+	csr_roam_issue_wm_status_change(mac_ctx, sessionId,
+					eCsrDeauthenticated,
+					msg_ptr);
+}
+
+static void
+csr_roam_chk_lnk_swt_ch_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	struct csr_roam_session *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	uint16_t ie_len;
+	QDF_STATUS status;
+	tpSirSmeSwitchChannelInd pSwitchChnInd;
+	struct csr_roam_info roamInfo;
+	tSirMacDsParamSetIE *ds_params_ie;
+	tDot11fIEHTInfo *ht_info_ie;
+
+	/* in case of STA, the SWITCH_CHANNEL originates from its AP */
+	sme_debug("eWNI_SME_SWITCH_CHL_IND from SME");
+	pSwitchChnInd = (tpSirSmeSwitchChannelInd) msg_ptr;
+	/* Update with the new channel id. The channel id is hidden in the
+	 * statusCode.
+	 */
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+			&pSwitchChnInd->bssid, &sessionId);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+	session->connectedProfile.operationChannel =
+			(uint8_t) pSwitchChnInd->newChannelId;
+	if (session->pConnectBssDesc) {
+		session->pConnectBssDesc->channelId =
+				(uint8_t) pSwitchChnInd->newChannelId;
+
+		ie_len = csr_get_ielen_from_bss_description(
+						session->pConnectBssDesc);
+		ds_params_ie = (tSirMacDsParamSetIE *)wlan_get_ie_ptr_from_eid(
+				DOT11F_EID_DSPARAMS,
+				(uint8_t *)session->pConnectBssDesc->ieFields,
+				ie_len);
+		if (ds_params_ie)
+			ds_params_ie->channelNumber =
+				(uint8_t)pSwitchChnInd->newChannelId;
+
+		ht_info_ie = (tDot11fIEHTInfo *)wlan_get_ie_ptr_from_eid(
+				DOT11F_EID_HTINFO,
+				(uint8_t *)session->pConnectBssDesc->ieFields,
+				ie_len);
+		if (ht_info_ie) {
+			ht_info_ie->primaryChannel =
+				(uint8_t)pSwitchChnInd->newChannelId;
+			ht_info_ie->secondaryChannelOffset =
+				pSwitchChnInd->chan_params.sec_ch_offset;
+		}
+	}
+
+	qdf_mem_set(&roamInfo, sizeof(struct csr_roam_info), 0);
+	roamInfo.chan_info.chan_id = pSwitchChnInd->newChannelId;
+	roamInfo.chan_info.ch_width = pSwitchChnInd->chan_params.ch_width;
+	roamInfo.chan_info.sec_ch_offset =
+				pSwitchChnInd->chan_params.sec_ch_offset;
+	roamInfo.chan_info.band_center_freq1 =
+				pSwitchChnInd->chan_params.center_freq_seg0;
+	roamInfo.chan_info.band_center_freq2 =
+				pSwitchChnInd->chan_params.center_freq_seg1;
+
+	if (CSR_IS_PHY_MODE_11ac(mac_ctx->roam.configParam.phyMode))
+		roamInfo.mode = SIR_SME_PHY_MODE_VHT;
+	else if (CSR_IS_PHY_MODE_11n(mac_ctx->roam.configParam.phyMode))
+		roamInfo.mode = SIR_SME_PHY_MODE_HT;
+	else
+		roamInfo.mode = SIR_SME_PHY_MODE_LEGACY;
+
+	status = csr_roam_call_callback(mac_ctx, sessionId, &roamInfo, 0,
+					eCSR_ROAM_STA_CHANNEL_SWITCH,
+					eCSR_ROAM_RESULT_NONE);
+}
+
+static void
+csr_roam_chk_lnk_deauth_rsp(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	struct csr_roam_session *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	QDF_STATUS status;
+	struct csr_roam_info *roam_info_ptr = NULL;
+	tSirSmeDeauthRsp *pDeauthRsp = (tSirSmeDeauthRsp *) msg_ptr;
+	struct csr_roam_info roam_info;
+
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sme_debug("eWNI_SME_DEAUTH_RSP from SME");
+	sessionId = pDeauthRsp->sessionId;
+	if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId))
+		return;
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (CSR_IS_INFRA_AP(&session->connectedProfile)) {
+		roam_info_ptr = &roam_info;
+		roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
+		qdf_copy_macaddr(&roam_info_ptr->peerMac,
+				 &pDeauthRsp->peer_macaddr);
+		roam_info_ptr->reasonCode = eCSR_ROAM_RESULT_FORCED;
+		roam_info_ptr->statusCode = pDeauthRsp->statusCode;
+		status = csr_roam_call_callback(mac_ctx, sessionId,
+						roam_info_ptr, 0,
+						eCSR_ROAM_LOSTLINK,
+						eCSR_ROAM_RESULT_FORCED);
+	}
+}
+
+static void
+csr_roam_chk_lnk_disassoc_rsp(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	struct csr_roam_session *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	QDF_STATUS status;
+	struct csr_roam_info *roam_info_ptr = NULL;
+	struct csr_roam_info roam_info;
+	/*
+	 * session id is invalid here so cant use it to access the array
+	 * curSubstate as index
+	 */
+	tSirSmeDisassocRsp *pDisassocRsp = (tSirSmeDisassocRsp *) msg_ptr;
+
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sme_debug("eWNI_SME_DISASSOC_RSP from SME ");
+	sessionId = pDisassocRsp->sessionId;
+	if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId))
+		return;
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (CSR_IS_INFRA_AP(&session->connectedProfile)) {
+		roam_info_ptr = &roam_info;
+		roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
+		qdf_copy_macaddr(&roam_info_ptr->peerMac,
+				 &pDisassocRsp->peer_macaddr);
+		roam_info_ptr->reasonCode = eCSR_ROAM_RESULT_FORCED;
+		roam_info_ptr->statusCode = pDisassocRsp->statusCode;
+		status = csr_roam_call_callback(mac_ctx, sessionId,
+						roam_info_ptr, 0,
+						eCSR_ROAM_LOSTLINK,
+						eCSR_ROAM_RESULT_FORCED);
+	}
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void
+csr_roam_diag_mic_fail(tpAniSirGlobal mac_ctx, uint32_t sessionId)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(secEvent,
+				 host_event_wlan_security_payload_type);
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, sessionId);
+
+	if (!session) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+	qdf_mem_set(&secEvent, sizeof(host_event_wlan_security_payload_type),
+		    0);
+	secEvent.eventId = WLAN_SECURITY_EVENT_MIC_ERROR;
+	secEvent.encryptionModeMulticast =
+		(uint8_t) diag_enc_type_from_csr_type(
+				session->connectedProfile.mcEncryptionType);
+	secEvent.encryptionModeUnicast =
+		(uint8_t) diag_enc_type_from_csr_type(
+				session->connectedProfile.EncryptionType);
+	secEvent.authMode =
+		(uint8_t) diag_auth_type_from_csr_type(
+				session->connectedProfile.AuthType);
+	qdf_mem_copy(secEvent.bssid, session->connectedProfile.bssid.bytes,
+			QDF_MAC_ADDR_SIZE);
+	WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+static void
+csr_roam_chk_lnk_mic_fail_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	QDF_STATUS status;
+	struct csr_roam_info *roam_info_ptr = NULL;
+	struct csr_roam_info roam_info;
+	tpSirSmeMicFailureInd pMicInd = (tpSirSmeMicFailureInd) msg_ptr;
+	eCsrRoamResult result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST;
+
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+				&pMicInd->bssId, &sessionId);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		qdf_mem_set(&roam_info, sizeof(struct csr_roam_info), 0);
+		roam_info.u.pMICFailureInfo = &pMicInd->info;
+		roam_info_ptr = &roam_info;
+		if (pMicInd->info.multicast)
+			result = eCSR_ROAM_RESULT_MIC_ERROR_GROUP;
+		else
+			result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST;
+		csr_roam_call_callback(mac_ctx, sessionId, roam_info_ptr, 0,
+				       eCSR_ROAM_MIC_ERROR_IND, result);
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_roam_diag_mic_fail(mac_ctx, sessionId);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+}
+
+static void
+csr_roam_chk_lnk_pbs_probe_req_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	QDF_STATUS status;
+	struct csr_roam_info roam_info;
+	tpSirSmeProbeReqInd pProbeReqInd = (tpSirSmeProbeReqInd) msg_ptr;
+
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sme_debug("WPS PBC Probe request Indication from SME");
+
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+			&pProbeReqInd->bssid, &sessionId);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		qdf_mem_set(&roam_info, sizeof(struct csr_roam_info), 0);
+		roam_info.u.pWPSPBCProbeReq = &pProbeReqInd->WPSPBCProbeReq;
+		csr_roam_call_callback(mac_ctx, sessionId, &roam_info,
+				       0, eCSR_ROAM_WPS_PBC_PROBE_REQ_IND,
+				       eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND);
+	}
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void
+csr_roam_diag_joined_new_bss(tpAniSirGlobal mac_ctx,
+				     tSirSmeNewBssInfo *pNewBss)
+{
+	host_log_ibss_pkt_type *pIbssLog;
+	uint32_t bi;
+
+	WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+				 LOG_WLAN_IBSS_C);
+	if (!pIbssLog)
+		return;
+	pIbssLog->eventId = WLAN_IBSS_EVENT_COALESCING;
+	if (pNewBss) {
+		qdf_copy_macaddr(&pIbssLog->bssid, &pNewBss->bssId);
+		if (pNewBss->ssId.length > HOST_LOG_MAX_SSID_SIZE)
+			pNewBss->ssId.length = HOST_LOG_MAX_SSID_SIZE;
+		qdf_mem_copy(pIbssLog->ssid, pNewBss->ssId.ssId,
+			     pNewBss->ssId.length);
+		pIbssLog->operatingChannel = pNewBss->channelNumber;
+	}
+	bi = mac_ctx->mlme_cfg->sap_cfg.beacon_interval;
+		/* U8 is not enough for beacon interval */
+		pIbssLog->beaconInterval = (uint8_t) bi;
+	WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+static void
+csr_roam_chk_lnk_wm_status_change_ntf(tpAniSirGlobal mac_ctx,
+				      tSirSmeRsp *msg_ptr)
+{
+	struct csr_roam_session *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	QDF_STATUS status;
+	struct csr_roam_info *roam_info_ptr = NULL;
+	tSirSmeWmStatusChangeNtf *pStatusChangeMsg;
+	struct csr_roam_info roam_info;
+	tSirSmeApNewCaps *pApNewCaps;
+	eCsrRoamResult result = eCSR_ROAM_RESULT_NONE;
+	tSirMacAddr Broadcastaddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+	tSirSmeNewBssInfo *pNewBss;
+	eRoamCmdStatus roamStatus = eCSR_ROAM_FAILED;
+
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	pStatusChangeMsg = (tSirSmeWmStatusChangeNtf *) msg_ptr;
+	switch (pStatusChangeMsg->statusChangeCode) {
+	case eSIR_SME_IBSS_ACTIVE:
+		sessionId = csr_find_ibss_session(mac_ctx);
+		if (CSR_SESSION_ID_INVALID == sessionId)
+			break;
+		session = CSR_GET_SESSION(mac_ctx, sessionId);
+		if (!session) {
+			sme_err("session %d not found",
+				sessionId);
+			return;
+		}
+		session->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED;
+		if (session->pConnectBssDesc) {
+			qdf_mem_copy(&roam_info.bssid,
+				     session->pConnectBssDesc->bssId,
+				     sizeof(struct qdf_mac_addr));
+			roam_info.u.pConnectedProfile =
+				&session->connectedProfile;
+			roam_info_ptr = &roam_info;
+		} else {
+			sme_err("CSR: connected BSS is empty");
+		}
+		result = eCSR_ROAM_RESULT_IBSS_CONNECT;
+		roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE;
+		break;
+
+	case eSIR_SME_IBSS_INACTIVE:
+		sessionId = csr_find_ibss_session(mac_ctx);
+		if (CSR_SESSION_ID_INVALID != sessionId) {
+			session = CSR_GET_SESSION(mac_ctx, sessionId);
+			if (!session) {
+				sme_err("session %d not found", sessionId);
+				return;
+			}
+			session->connectState =
+				eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED;
+			result = eCSR_ROAM_RESULT_IBSS_INACTIVE;
+			roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE;
+		}
+		break;
+
+	case eSIR_SME_JOINED_NEW_BSS:
+		/* IBSS coalescing. */
+		sme_debug("CSR: eSIR_SME_JOINED_NEW_BSS received from PE");
+		sessionId = csr_find_ibss_session(mac_ctx);
+		if (CSR_SESSION_ID_INVALID == sessionId)
+			break;
+		session = CSR_GET_SESSION(mac_ctx, sessionId);
+		if (!session) {
+			sme_err("session %d not found",
+				sessionId);
+			return;
+		}
+		/* update the connection state information */
+		pNewBss = &pStatusChangeMsg->statusChangeInfo.newBssInfo;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+		csr_roam_diag_joined_new_bss(mac_ctx, pNewBss);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+		csr_roam_update_connected_profile_from_new_bss(mac_ctx,
+							       sessionId,
+							       pNewBss);
+
+		if ((eCSR_ENCRYPT_TYPE_NONE ==
+		     session->connectedProfile.EncryptionType)) {
+			csr_roam_issue_set_context_req(mac_ctx,
+			    sessionId,
+			    session->connectedProfile.EncryptionType,
+			    session->pConnectBssDesc,
+			    &Broadcastaddr, false, false,
+			    eSIR_TX_RX, 0, 0, NULL, 0);
+		}
+		result = eCSR_ROAM_RESULT_IBSS_COALESCED;
+		roamStatus = eCSR_ROAM_IBSS_IND;
+		qdf_mem_copy(&roam_info.bssid, &pNewBss->bssId,
+			     sizeof(struct qdf_mac_addr));
+		roam_info_ptr = &roam_info;
+		/* This BSSID is the real BSSID, save it */
+		if (session->pConnectBssDesc)
+			qdf_mem_copy(session->pConnectBssDesc->bssId,
+				&pNewBss->bssId, sizeof(struct qdf_mac_addr));
+		break;
+
+	/*
+	 * detection by LIM that the capabilities of the associated
+	 * AP have changed.
+	 */
+	case eSIR_SME_AP_CAPS_CHANGED:
+		pApNewCaps = &pStatusChangeMsg->statusChangeInfo.apNewCaps;
+		sme_debug("CSR handling eSIR_SME_AP_CAPS_CHANGED");
+		status = csr_roam_get_session_id_from_bssid(mac_ctx,
+					&pApNewCaps->bssId, &sessionId);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+		if (eCSR_ROAMING_STATE_JOINED ==
+		    sme_get_current_roam_state(MAC_HANDLE(mac_ctx), sessionId)
+		    && ((eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC
+			== mac_ctx->roam.curSubState[sessionId])
+		    || (eCSR_ROAM_SUBSTATE_NONE ==
+			mac_ctx->roam.curSubState[sessionId])
+		    || (eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC
+			== mac_ctx->roam.curSubState[sessionId])
+		    || (eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC ==
+			 mac_ctx->roam.curSubState[sessionId]))) {
+			sme_warn("Calling csr_roam_disconnect_internal");
+			csr_roam_disconnect_internal(mac_ctx, sessionId,
+					eCSR_DISCONNECT_REASON_UNSPECIFIED);
+		} else {
+			sme_warn("Skipping the new scan as CSR is in state: %s and sub-state: %s",
+				mac_trace_getcsr_roam_state(
+					mac_ctx->roam.curState[sessionId]),
+				mac_trace_getcsr_roam_sub_state(
+					mac_ctx->roam.curSubState[sessionId]));
+			/* We ignore the caps change event if CSR is not in full
+			 * connected state. Send one event to PE to reset
+			 * limSentCapsChangeNtf Once limSentCapsChangeNtf set
+			 * 0, lim can send sub sequent CAPS change event
+			 * otherwise lim cannot send any CAPS change events to
+			 * SME
+			 */
+			csr_send_reset_ap_caps_changed(mac_ctx,
+						       &pApNewCaps->bssId);
+		}
+		break;
+
+	default:
+		roamStatus = eCSR_ROAM_FAILED;
+		result = eCSR_ROAM_RESULT_NONE;
+		break;
+	} /* end switch on statusChangeCode */
+	if (eCSR_ROAM_RESULT_NONE != result) {
+		csr_roam_call_callback(mac_ctx, sessionId, roam_info_ptr, 0,
+				       roamStatus, result);
+	}
+}
+
+static void
+csr_roam_chk_lnk_ibss_new_peer_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	struct csr_roam_session *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	QDF_STATUS status;
+	struct csr_roam_info *roam_info_ptr = NULL;
+	tSmeIbssPeerInd *pIbssPeerInd = (tSmeIbssPeerInd *) msg_ptr;
+	struct csr_roam_info roam_info;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	host_log_ibss_pkt_type *pIbssLog;
+
+	WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+				 LOG_WLAN_IBSS_C);
+	if (pIbssLog) {
+		pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_JOIN;
+		qdf_copy_macaddr(&pIbssLog->peer_macaddr,
+				 &pIbssPeerInd->peer_addr);
+		WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sessionId = csr_find_ibss_session(mac_ctx);
+	if (CSR_SESSION_ID_INVALID == sessionId)
+		return;
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+	/*
+	 * Issue the set Context request to LIM to establish the Unicast STA
+	 * context for the new peer...
+	 */
+	if (!session->pConnectBssDesc) {
+		sme_warn("CSR: connected BSS is empty");
+		goto callback_and_free;
+	}
+	qdf_copy_macaddr(&roam_info.peerMac, &pIbssPeerInd->peer_addr);
+	qdf_mem_copy(&roam_info.bssid, session->pConnectBssDesc->bssId,
+		     sizeof(struct qdf_mac_addr));
+	if (pIbssPeerInd->mesgLen > sizeof(tSmeIbssPeerInd)) {
+		roam_info.pbFrames = qdf_mem_malloc((pIbssPeerInd->mesgLen -
+					sizeof(tSmeIbssPeerInd)));
+		if (NULL == roam_info.pbFrames) {
+			status = QDF_STATUS_E_NOMEM;
+		} else {
+			status = QDF_STATUS_SUCCESS;
+			roam_info.nBeaconLength = pIbssPeerInd->mesgLen -
+							sizeof(tSmeIbssPeerInd);
+			qdf_mem_copy(roam_info.pbFrames,
+				((uint8_t *) pIbssPeerInd) +
+				sizeof(tSmeIbssPeerInd),
+				roam_info.nBeaconLength);
+		}
+		roam_info.staId = (uint8_t) pIbssPeerInd->staId;
+		roam_info.pBssDesc = qdf_mem_malloc(
+					session->pConnectBssDesc->length);
+		if (NULL == roam_info.pBssDesc) {
+			status = QDF_STATUS_E_NOMEM;
+			if (roam_info.pbFrames)
+				qdf_mem_free(roam_info.pbFrames);
+			if (roam_info.pBssDesc)
+				qdf_mem_free(roam_info.pBssDesc);
+		} else {
+			status = QDF_STATUS_SUCCESS;
+			qdf_mem_copy(roam_info.pBssDesc,
+				     session->pConnectBssDesc,
+				     session->pConnectBssDesc->length);
+			roam_info_ptr = &roam_info;
+		}
+	} else {
+		roam_info_ptr = &roam_info;
+	}
+	if ((eCSR_ENCRYPT_TYPE_NONE ==
+		session->connectedProfile.EncryptionType)) {
+		/* NO keys. these key parameters don't matter */
+		csr_roam_issue_set_context_req(mac_ctx, sessionId,
+			session->connectedProfile.EncryptionType,
+			session->pConnectBssDesc,
+			&pIbssPeerInd->peer_addr.bytes,
+			false, true, eSIR_TX_RX, 0, 0, NULL, 0);
+	}
+
+callback_and_free:
+	/* send up the sec type for the new peer */
+	if (roam_info_ptr)
+		roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
+	csr_roam_call_callback(mac_ctx, sessionId, roam_info_ptr, 0,
+			       eCSR_ROAM_CONNECT_STATUS_UPDATE,
+			       eCSR_ROAM_RESULT_IBSS_NEW_PEER);
+	if (roam_info_ptr) {
+		if (roam_info.pbFrames)
+			qdf_mem_free(roam_info.pbFrames);
+		if (roam_info.pBssDesc)
+			qdf_mem_free(roam_info.pBssDesc);
+	}
+}
+
+static void
+csr_roam_chk_lnk_ibss_peer_departed_ind(tpAniSirGlobal mac_ctx,
+					tSirSmeRsp *msg_ptr)
+{
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	struct csr_roam_info roam_info;
+	tSmeIbssPeerInd *pIbssPeerInd;
+
+	if (NULL == msg_ptr) {
+		sme_err("IBSS peer ind. message is NULL");
+		return;
+	}
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	pIbssPeerInd = (tSmeIbssPeerInd *) msg_ptr;
+	sessionId = csr_find_ibss_session(mac_ctx);
+	if (CSR_SESSION_ID_INVALID != sessionId) {
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+		host_log_ibss_pkt_type *pIbssLog;
+
+		WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+					 LOG_WLAN_IBSS_C);
+		if (pIbssLog) {
+			pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_LEAVE;
+			if (pIbssPeerInd) {
+				qdf_copy_macaddr(&pIbssLog->peer_macaddr,
+						 &pIbssPeerInd->peer_addr);
+			}
+			WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+		}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+		sme_debug("CSR: Peer departed notification from LIM");
+		roam_info.staId = (uint8_t) pIbssPeerInd->staId;
+		qdf_copy_macaddr(&roam_info.peerMac, &pIbssPeerInd->peer_addr);
+		csr_roam_call_callback(mac_ctx, sessionId, &roam_info, 0,
+				       eCSR_ROAM_CONNECT_STATUS_UPDATE,
+				       eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED);
+	}
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void
+csr_roam_diag_set_ctx_rsp(tpAniSirGlobal mac_ctx,
+			  struct csr_roam_session *session,
+			  tSirSmeSetContextRsp *pRsp)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent,
+				 host_event_wlan_security_payload_type);
+	if (eCSR_ENCRYPT_TYPE_NONE ==
+		session->connectedProfile.EncryptionType)
+		return;
+	qdf_mem_set(&setKeyEvent,
+		    sizeof(host_event_wlan_security_payload_type), 0);
+	if (qdf_is_macaddr_group(&pRsp->peer_macaddr))
+		setKeyEvent.eventId =
+			WLAN_SECURITY_EVENT_SET_BCAST_RSP;
+	else
+		setKeyEvent.eventId =
+			WLAN_SECURITY_EVENT_SET_UNICAST_RSP;
+	setKeyEvent.encryptionModeMulticast =
+		(uint8_t) diag_enc_type_from_csr_type(
+				session->connectedProfile.mcEncryptionType);
+	setKeyEvent.encryptionModeUnicast =
+		(uint8_t) diag_enc_type_from_csr_type(
+				session->connectedProfile.EncryptionType);
+	qdf_mem_copy(setKeyEvent.bssid, session->connectedProfile.bssid.bytes,
+			QDF_MAC_ADDR_SIZE);
+	setKeyEvent.authMode =
+		(uint8_t) diag_auth_type_from_csr_type(
+					session->connectedProfile.AuthType);
+	if (eSIR_SME_SUCCESS != pRsp->statusCode)
+		setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE;
+	WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+static void
+csr_roam_chk_lnk_set_ctx_rsp(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	struct csr_roam_session *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	QDF_STATUS status;
+	struct csr_roam_info *roam_info_ptr = NULL;
+	struct csr_roam_info roam_info;
+	eCsrRoamResult result = eCSR_ROAM_RESULT_NONE;
+	tSirSmeSetContextRsp *pRsp = (tSirSmeSetContextRsp *) msg_ptr;
+
+
+	if (!pRsp) {
+		sme_err("set key response is NULL");
+		return;
+	}
+
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sessionId = pRsp->sessionId;
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_roam_diag_set_ctx_rsp(mac_ctx, session, pRsp);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	if (CSR_IS_WAIT_FOR_KEY(mac_ctx, sessionId)) {
+		csr_roam_stop_wait_for_key_timer(mac_ctx);
+		/* We are done with authentication, whethere succeed or not */
+		csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE,
+					 sessionId);
+		/* We do it here because this linkup function is not called
+		 * after association  when a key needs to be set.
+		 */
+		if (csr_is_conn_state_connected_infra(mac_ctx, sessionId))
+			csr_roam_link_up(mac_ctx,
+					 session->connectedProfile.bssid);
+	}
+	if (eSIR_SME_SUCCESS == pRsp->statusCode) {
+		qdf_copy_macaddr(&roam_info.peerMac, &pRsp->peer_macaddr);
+		/* Make sure we install the GTK before indicating to HDD as
+		 * authenticated. This is to prevent broadcast packets go out
+		 * after PTK and before GTK.
+		 */
+		if (qdf_is_macaddr_broadcast(&pRsp->peer_macaddr)) {
+			/*
+			 * OBSS SCAN Indication will be sent to Firmware
+			 * to start OBSS Scan
+			 */
+			if (mac_ctx->obss_scan_offload &&
+			    CSR_IS_CHANNEL_24GHZ(
+				session->connectedProfile.operationChannel)
+				&& (session->connectState ==
+					eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)
+				&& session->pCurRoamProfile
+				&& ((QDF_P2P_CLIENT_MODE ==
+				     session->pCurRoamProfile->csrPersona)
+				|| (QDF_STA_MODE ==
+				     session->pCurRoamProfile->csrPersona))) {
+				struct sme_obss_ht40_scanind_msg *msg;
+
+				msg = qdf_mem_malloc(sizeof(
+					struct sme_obss_ht40_scanind_msg));
+				if (!msg)
+					return;
+
+				msg->msg_type = eWNI_SME_HT40_OBSS_SCAN_IND;
+				msg->length =
+				      sizeof(struct sme_obss_ht40_scanind_msg);
+				qdf_copy_macaddr(&msg->mac_addr,
+					&session->connectedProfile.bssid);
+				status = umac_send_mb_message_to_mac(msg);
+			}
+			result = eCSR_ROAM_RESULT_AUTHENTICATED;
+		} else {
+			result = eCSR_ROAM_RESULT_NONE;
+		}
+		roam_info_ptr = &roam_info;
+	} else {
+		result = eCSR_ROAM_RESULT_FAILURE;
+		sme_err(
+			"CSR: setkey command failed(err=%d) PeerMac "
+			MAC_ADDRESS_STR,
+			pRsp->statusCode,
+			MAC_ADDR_ARRAY(pRsp->peer_macaddr.bytes));
+	}
+	/* keeping roam_id = 0 as nobody is using roam_id for set_key */
+	csr_roam_call_callback(mac_ctx, sessionId, &roam_info,
+			       0, eCSR_ROAM_SET_KEY_COMPLETE, result);
+	/* Indicate SME_QOS that the SET_KEY is completed, so that SME_QOS
+	 * can go ahead and initiate the TSPEC if any are pending
+	 */
+	sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId,
+			      SME_QOS_CSR_SET_KEY_SUCCESS_IND, NULL);
+#ifdef FEATURE_WLAN_ESE
+	/* Send Adjacent AP repot to new AP. */
+	if (result == eCSR_ROAM_RESULT_AUTHENTICATED
+	    && session->isPrevApInfoValid
+	    && session->connectedProfile.isESEAssoc) {
+		csr_send_ese_adjacent_ap_rep_ind(mac_ctx, session);
+		session->isPrevApInfoValid = false;
+	}
+#endif
+	return;
+}
+
+
+static void
+csr_roam_chk_lnk_max_assoc_exceeded(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	tSmeMaxAssocInd *pSmeMaxAssocInd;
+	struct csr_roam_info roam_info;
+
+	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	pSmeMaxAssocInd = (tSmeMaxAssocInd *) msg_ptr;
+	sme_debug(
+		"max assoc have been reached, new peer cannot be accepted");
+	sessionId = pSmeMaxAssocInd->sessionId;
+	roam_info.sessionId = sessionId;
+	qdf_copy_macaddr(&roam_info.peerMac, &pSmeMaxAssocInd->peer_mac);
+	csr_roam_call_callback(mac_ctx, sessionId, &roam_info, 0,
+			       eCSR_ROAM_INFRA_IND,
+			       eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED);
+}
+
+void csr_roam_check_for_link_status_change(tpAniSirGlobal pMac,
+						tSirSmeRsp *pSirMsg)
+{
+	if (NULL == pSirMsg) {
+		sme_err("pSirMsg is NULL");
+		return;
+	}
+	switch (pSirMsg->messageType) {
+	case eWNI_SME_ASSOC_IND:
+		csr_roam_chk_lnk_assoc_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_DISASSOC_IND:
+		csr_roam_chk_lnk_disassoc_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_DISCONNECT_DONE_IND:
+		csr_roam_send_disconnect_done_indication(pMac, pSirMsg);
+		break;
+	case eWNI_SME_DEAUTH_IND:
+		csr_roam_chk_lnk_deauth_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_SWITCH_CHL_IND:
+		csr_roam_chk_lnk_swt_ch_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_DEAUTH_RSP:
+		csr_roam_chk_lnk_deauth_rsp(pMac, pSirMsg);
+		break;
+	case eWNI_SME_DISASSOC_RSP:
+		csr_roam_chk_lnk_disassoc_rsp(pMac, pSirMsg);
+		break;
+	case eWNI_SME_MIC_FAILURE_IND:
+		csr_roam_chk_lnk_mic_fail_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_WPS_PBC_PROBE_REQ_IND:
+		csr_roam_chk_lnk_pbs_probe_req_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_WM_STATUS_CHANGE_NTF:
+		csr_roam_chk_lnk_wm_status_change_ntf(pMac, pSirMsg);
+		break;
+	case eWNI_SME_IBSS_NEW_PEER_IND:
+		csr_roam_chk_lnk_ibss_new_peer_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_IBSS_PEER_DEPARTED_IND:
+		csr_roam_chk_lnk_ibss_peer_departed_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_SETCONTEXT_RSP:
+		csr_roam_chk_lnk_set_ctx_rsp(pMac, pSirMsg);
+		break;
+	case eWNI_SME_GET_STATISTICS_RSP:
+		sme_debug("Stats rsp from PE");
+		csr_roam_stats_rsp_processor(pMac, pSirMsg);
+		break;
+#ifdef FEATURE_WLAN_ESE
+	case eWNI_SME_GET_TSM_STATS_RSP:
+		sme_debug("TSM Stats rsp from PE");
+		csr_tsm_stats_rsp_processor(pMac, pSirMsg);
+		break;
+#endif /* FEATURE_WLAN_ESE */
+	case eWNI_SME_GET_RSSI_REQ:
+		sme_debug("GetRssiReq from self");
+		csr_update_rssi(pMac, pSirMsg);
+		break;
+	case eWNI_SME_GET_SNR_REQ:
+		sme_debug("GetSnrReq from self");
+		csr_update_snr(pMac, pSirMsg);
+		break;
+	case eWNI_SME_FT_PRE_AUTH_RSP:
+		csr_roam_ft_pre_auth_rsp_processor(pMac,
+						(tpSirFTPreAuthRsp) pSirMsg);
+		break;
+	case eWNI_SME_MAX_ASSOC_EXCEEDED:
+		csr_roam_chk_lnk_max_assoc_exceeded(pMac, pSirMsg);
+		break;
+	case eWNI_SME_CANDIDATE_FOUND_IND:
+		sme_debug("Candidate found indication from PE");
+		csr_neighbor_roam_candidate_found_ind_hdlr(pMac, pSirMsg);
+		break;
+	case eWNI_SME_HANDOFF_REQ:
+		sme_debug("Handoff Req from self");
+		csr_neighbor_roam_handoff_req_hdlr(pMac, pSirMsg);
+		break;
+
+	default:
+		break;
+	} /* end switch on message type */
+}
+
+void csr_call_roaming_completion_callback(tpAniSirGlobal pMac,
+					  struct csr_roam_session *pSession,
+					  struct csr_roam_info *roam_info,
+					  uint32_t roamId,
+					  eCsrRoamResult roamResult)
+{
+	if (pSession) {
+		if (pSession->bRefAssocStartCnt) {
+			pSession->bRefAssocStartCnt--;
+
+			if (0 != pSession->bRefAssocStartCnt) {
+				QDF_ASSERT(pSession->bRefAssocStartCnt == 0);
+				return;
+			}
+			/* Need to call association_completion because there
+			 * is an assoc_start pending.
+			 */
+			csr_roam_call_callback(pMac, pSession->sessionId, NULL,
+					       roamId,
+					       eCSR_ROAM_ASSOCIATION_COMPLETION,
+					       eCSR_ROAM_RESULT_FAILURE);
+		}
+		csr_roam_call_callback(pMac, pSession->sessionId, roam_info,
+				       roamId, eCSR_ROAM_ROAMING_COMPLETION,
+				       roamResult);
+	} else
+		sme_err("pSession is NULL");
+}
+
+/* return a bool to indicate whether roaming completed or continue. */
+bool csr_roam_complete_roaming(tpAniSirGlobal pMac, uint32_t sessionId,
+			       bool fForce, eCsrRoamResult roamResult)
+{
+	bool fCompleted = true;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found ", sessionId);
+		return false;
+	}
+	/* Check whether time is up */
+	if (pSession->fCancelRoaming || fForce ||
+	    eCsrReassocRoaming == pSession->roamingReason ||
+	    eCsrDynamicRoaming == pSession->roamingReason) {
+		sme_debug("indicates roaming completion");
+		if (pSession->fCancelRoaming
+		    && CSR_IS_LOSTLINK_ROAMING(pSession->roamingReason)) {
+			/* roaming is cancelled, tell HDD to indicate disconnect
+			 * Because LIM overload deauth_ind for both deauth frame
+			 * and missed beacon we need to use this logic to
+			 * detinguish it. For missed beacon, LIM set reason to
+			 * be eSIR_BEACON_MISSED
+			 */
+			if (eSIR_BEACON_MISSED == pSession->roamingStatusCode) {
+				roamResult = eCSR_ROAM_RESULT_LOSTLINK;
+			} else if (eCsrLostlinkRoamingDisassoc ==
+				   pSession->roamingReason) {
+				roamResult = eCSR_ROAM_RESULT_DISASSOC_IND;
+			} else if (eCsrLostlinkRoamingDeauth ==
+				   pSession->roamingReason) {
+				roamResult = eCSR_ROAM_RESULT_DEAUTH_IND;
+			} else {
+				roamResult = eCSR_ROAM_RESULT_LOSTLINK;
+			}
+		}
+		csr_call_roaming_completion_callback(pMac, pSession, NULL, 0,
+						     roamResult);
+		pSession->roamingReason = eCsrNotRoaming;
+	} else {
+		pSession->roamResult = roamResult;
+		if (!QDF_IS_STATUS_SUCCESS(csr_roam_start_roaming_timer(pMac,
+					sessionId, QDF_MC_TIMER_TO_SEC_UNIT))) {
+			csr_call_roaming_completion_callback(pMac, pSession,
+							NULL, 0, roamResult);
+			pSession->roamingReason = eCsrNotRoaming;
+		} else {
+			fCompleted = false;
+		}
+	}
+	return fCompleted;
+}
+
+void csr_roam_cancel_roaming(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session: %d not found", sessionId);
+		return;
+	}
+
+	if (CSR_IS_ROAMING(pSession)) {
+		sme_debug("Cancel roaming");
+		pSession->fCancelRoaming = true;
+		if (CSR_IS_ROAM_JOINING(pMac, sessionId)
+		    && CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId)) {
+			/* No need to do anything in here because the handler
+			 * takes care of it
+			 */
+		} else {
+			eCsrRoamResult roamResult =
+				CSR_IS_LOSTLINK_ROAMING(pSession->
+							roamingReason) ?
+				eCSR_ROAM_RESULT_LOSTLINK :
+							eCSR_ROAM_RESULT_NONE;
+			/* Roaming is stopped after here */
+			csr_roam_complete_roaming(pMac, sessionId, true,
+						  roamResult);
+			/* Since CSR may be in lostlink roaming situation,
+			 * abort all roaming related activities
+			 */
+			csr_scan_abort_mac_scan(pMac, sessionId, INVAL_SCAN_ID);
+			csr_roam_stop_roaming_timer(pMac, sessionId);
+		}
+	}
+}
+
+void csr_roam_roaming_timer_handler(void *pv)
+{
+	tCsrTimerInfo *pInfo = (tCsrTimerInfo *) pv;
+	tpAniSirGlobal pMac = pInfo->pMac;
+	uint32_t sessionId = pInfo->sessionId;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("  session %d not found ", sessionId);
+		return;
+	}
+
+	if (false == pSession->fCancelRoaming) {
+		csr_call_roaming_completion_callback(pMac, pSession,
+						NULL, 0,
+						pSession->roamResult);
+		pSession->roamingReason = eCsrNotRoaming;
+	}
+}
+
+/**
+ * csr_roam_roaming_offload_timeout_handler() - Handler for roaming failure
+ * @timer_data: Carries the mac_ctx and session info
+ *
+ * This function would be invoked when the roaming_offload_timer expires.
+ * The timer is waiting in anticipation of a related roaming event from
+ * the firmware after receiving the ROAM_START event.
+ *
+ * Return: None
+ */
+void csr_roam_roaming_offload_timeout_handler(void *timer_data)
+{
+	tCsrTimerInfo *timer_info = (tCsrTimerInfo *) timer_data;
+
+	if (timer_info) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			 "LFR3:roaming offload timer expired, session: %d",
+			  timer_info->sessionId);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			 "Invalid Session");
+		return;
+	}
+	csr_roam_disconnect(timer_info->pMac, timer_info->sessionId,
+			eCSR_DISCONNECT_REASON_UNSPECIFIED);
+}
+
+QDF_STATUS csr_roam_start_roaming_timer(tpAniSirGlobal pMac, uint32_t sessionId,
+					uint32_t interval)
+{
+	QDF_STATUS status;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_debug("csrScanStartRoamingTimer");
+	pSession->roamingTimerInfo.sessionId = (uint8_t) sessionId;
+	status = qdf_mc_timer_start(&pSession->hTimerRoaming,
+				    interval / QDF_MC_TIMER_TO_MS_UNIT);
+
+	return status;
+}
+
+QDF_STATUS csr_roam_stop_roaming_timer(tpAniSirGlobal pMac,
+		uint32_t sessionId)
+{
+	return qdf_mc_timer_stop
+			(&pMac->roam.roamSession[sessionId].hTimerRoaming);
+}
+
+void csr_roam_wait_for_key_time_out_handler(void *pv)
+{
+	tCsrTimerInfo *pInfo = (tCsrTimerInfo *) pv;
+	tpAniSirGlobal pMac = pInfo->pMac;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac,
+				pInfo->sessionId);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (pSession == NULL) {
+		sme_err("session not found");
+		return;
+	}
+
+	sme_debug("WaitForKey timer expired in state: %s sub-state: %s",
+		mac_trace_get_neighbour_roam_state(pMac->roam.
+					neighborRoamInfo[pInfo->sessionId].
+						   neighborRoamState),
+		mac_trace_getcsr_roam_sub_state(pMac->roam.
+						curSubState[pInfo->sessionId]));
+	spin_lock(&pMac->roam.roam_state_lock);
+	if (CSR_IS_WAIT_FOR_KEY(pMac, pInfo->sessionId)) {
+		/* Change the substate so command queue is unblocked. */
+		if (CSR_ROAM_SESSION_MAX > pInfo->sessionId)
+			pMac->roam.curSubState[pInfo->sessionId] =
+						eCSR_ROAM_SUBSTATE_NONE;
+		spin_unlock(&pMac->roam.roam_state_lock);
+
+		if (csr_neighbor_roam_is_handoff_in_progress(pMac,
+						pInfo->sessionId)) {
+			/*
+			 * Enable heartbeat timer when hand-off is in progress
+			 * and Key Wait timer expired.
+			 */
+			sme_debug("Enabling HB timer after WaitKey expiry nHBCount: %d)",
+				pMac->roam.configParam.HeartbeatThresh24);
+			if (cfg_in_range(CFG_HEART_BEAT_THRESHOLD,
+					 pMac->roam.configParam.
+					 HeartbeatThresh24))
+				pMac->mlme_cfg->timeouts.heart_beat_threshold =
+				pMac->roam.configParam.HeartbeatThresh24;
+			else
+				pMac->mlme_cfg->timeouts.heart_beat_threshold =
+					cfg_default(CFG_HEART_BEAT_THRESHOLD);
+		}
+		sme_debug("SME pre-auth state timeout");
+
+		if (csr_is_conn_state_connected_infra(pMac, pInfo->sessionId)) {
+			csr_roam_link_up(pMac,
+					 pSession->connectedProfile.bssid);
+			status = sme_acquire_global_lock(&pMac->sme);
+			if (QDF_IS_STATUS_SUCCESS(status)) {
+				csr_roam_disconnect(pMac, pInfo->sessionId,
+					eCSR_DISCONNECT_REASON_UNSPECIFIED);
+				sme_release_global_lock(&pMac->sme);
+			}
+		} else {
+			sme_err("session not found");
+		}
+	} else {
+		spin_unlock(&pMac->roam.roam_state_lock);
+	}
+
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * csr_roam_roaming_offload_timer_action() - API to start/stop the timer
+ * @mac_ctx: MAC Context
+ * @interval: Value to be set for the timer
+ * @session_id: Session on which the timer should be operated
+ * @action: Start/Stop action for the timer
+ *
+ * API to start/stop the roaming offload timer
+ *
+ * Return: None
+ */
+void csr_roam_roaming_offload_timer_action(
+		tpAniSirGlobal mac_ctx, uint32_t interval, uint8_t session_id,
+		uint8_t action)
+{
+	struct csr_roam_session *csr_session = CSR_GET_SESSION(mac_ctx,
+				session_id);
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			("LFR3: timer action %d, session %d, intvl %d"),
+			action, session_id, interval);
+	if (mac_ctx) {
+		csr_session = CSR_GET_SESSION(mac_ctx, session_id);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				("LFR3: Invalid MAC Context"));
+		return;
+	}
+	if (!csr_session) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				("LFR3: session %d not found"), session_id);
+		return;
+	}
+	csr_session->roamingTimerInfo.sessionId = (uint8_t) session_id;
+	if (action == ROAMING_OFFLOAD_TIMER_START)
+		qdf_mc_timer_start(&csr_session->roaming_offload_timer,
+				interval / QDF_MC_TIMER_TO_MS_UNIT);
+	if (action == ROAMING_OFFLOAD_TIMER_STOP)
+		qdf_mc_timer_stop(&csr_session->roaming_offload_timer);
+
+}
+#endif
+
+static QDF_STATUS csr_roam_start_wait_for_key_timer(
+		tpAniSirGlobal pMac, uint32_t interval)
+{
+	QDF_STATUS status;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[pMac->roam.WaitForKeyTimerInfo.
+					     sessionId];
+	if (csr_neighbor_roam_is_handoff_in_progress(pMac,
+				     pMac->roam.WaitForKeyTimerInfo.
+				     sessionId)) {
+		/* Disable heartbeat timer when hand-off is in progress */
+		sme_debug("disabling HB timer in state: %s sub-state: %s",
+			mac_trace_get_neighbour_roam_state(
+				pNeighborRoamInfo->neighborRoamState),
+			mac_trace_getcsr_roam_sub_state(
+				pMac->roam.curSubState[pMac->roam.
+					WaitForKeyTimerInfo.sessionId]));
+		pMac->mlme_cfg->timeouts.heart_beat_threshold = 0;
+	}
+	sme_debug("csrScanStartWaitForKeyTimer");
+	status = qdf_mc_timer_start(&pMac->roam.hTimerWaitForKey,
+				    interval / QDF_MC_TIMER_TO_MS_UNIT);
+
+	return status;
+}
+
+QDF_STATUS csr_roam_stop_wait_for_key_timer(tpAniSirGlobal pMac)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[pMac->roam.WaitForKeyTimerInfo.
+					     sessionId];
+
+	sme_debug("WaitForKey timer stopped in state: %s sub-state: %s",
+		mac_trace_get_neighbour_roam_state(pNeighborRoamInfo->
+						   neighborRoamState),
+		mac_trace_getcsr_roam_sub_state(pMac->roam.
+						curSubState[pMac->roam.
+							    WaitForKeyTimerInfo.
+							    sessionId]));
+	if (csr_neighbor_roam_is_handoff_in_progress(pMac,
+					pMac->roam.WaitForKeyTimerInfo.
+						     sessionId)) {
+		/*
+		 * Enable heartbeat timer when hand-off is in progress
+		 * and Key Wait timer got stopped for some reason
+		 */
+		sme_debug("Enabling HB timer after WaitKey stop nHBCount: %d",
+			pMac->roam.configParam.HeartbeatThresh24);
+		if (cfg_in_range(CFG_HEART_BEAT_THRESHOLD,
+				 pMac->roam.configParam.HeartbeatThresh24))
+			pMac->mlme_cfg->timeouts.heart_beat_threshold =
+				pMac->roam.configParam.HeartbeatThresh24;
+		else
+			pMac->mlme_cfg->timeouts.heart_beat_threshold =
+				cfg_default(CFG_HEART_BEAT_THRESHOLD);
+	}
+	return qdf_mc_timer_stop(&pMac->roam.hTimerWaitForKey);
+}
+
+void csr_roam_completion(tpAniSirGlobal pMac, uint32_t sessionId,
+			 struct csr_roam_info *roam_info, tSmeCmd *pCommand,
+			 eCsrRoamResult roamResult, bool fSuccess)
+{
+	eRoamCmdStatus roamStatus = csr_get_roam_complete_status(pMac,
+								sessionId);
+	uint32_t roamId = 0;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session: %d not found ", sessionId);
+		return;
+	}
+
+	if (pCommand) {
+		roamId = pCommand->u.roamCmd.roamId;
+		if (sessionId != pCommand->sessionId) {
+			QDF_ASSERT(sessionId == pCommand->sessionId);
+			return;
+		}
+	}
+	if (eCSR_ROAM_ROAMING_COMPLETION == roamStatus)
+		/* if success, force roaming completion */
+		csr_roam_complete_roaming(pMac, sessionId, fSuccess,
+								roamResult);
+	else {
+		if (pSession->bRefAssocStartCnt != 0) {
+			QDF_ASSERT(pSession->bRefAssocStartCnt == 0);
+			return;
+		}
+		sme_debug("indicates association completion roamResult: %d",
+			roamResult);
+		csr_roam_call_callback(pMac, sessionId, roam_info, roamId,
+				       roamStatus, roamResult);
+	}
+}
+
+static
+QDF_STATUS csr_roam_lost_link(tpAniSirGlobal pMac, uint32_t sessionId,
+			      uint32_t type, tSirSmeRsp *pSirMsg)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirSmeDeauthInd *pDeauthIndMsg = NULL;
+	tSirSmeDisassocInd *pDisassocIndMsg = NULL;
+	eCsrRoamResult result = eCSR_ROAM_RESULT_LOSTLINK;
+	struct csr_roam_info roamInfo;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session: %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_set(&roamInfo, sizeof(struct csr_roam_info), 0);
+	if (eWNI_SME_DISASSOC_IND == type) {
+		result = eCSR_ROAM_RESULT_DISASSOC_IND;
+		pDisassocIndMsg = (tSirSmeDisassocInd *) pSirMsg;
+		pSession->roamingStatusCode = pDisassocIndMsg->statusCode;
+		pSession->joinFailStatusCode.reasonCode =
+			pDisassocIndMsg->reasonCode;
+
+		qdf_copy_macaddr(&roamInfo.peerMac,
+				 &pDisassocIndMsg->peer_macaddr);
+	} else if (eWNI_SME_DEAUTH_IND == type) {
+		result = eCSR_ROAM_RESULT_DEAUTH_IND;
+		pDeauthIndMsg = (tSirSmeDeauthInd *) pSirMsg;
+		pSession->roamingStatusCode = pDeauthIndMsg->statusCode;
+		pSession->joinFailStatusCode.reasonCode =
+			pDeauthIndMsg->reasonCode;
+
+		qdf_copy_macaddr(&roamInfo.peerMac,
+				 &pDeauthIndMsg->peer_macaddr);
+
+	} else {
+		sme_warn("gets an unknown type (%d)", type);
+		result = eCSR_ROAM_RESULT_NONE;
+		pSession->joinFailStatusCode.reasonCode = 1;
+	}
+
+	if (type == eWNI_SME_DISASSOC_IND || type == eWNI_SME_DEAUTH_IND) {
+		struct	sir_peer_info_req req;
+
+		req.sessionid = sessionId;
+		req.peer_macaddr = roamInfo.peerMac;
+		sme_get_peer_stats(pMac, req);
+	}
+	csr_roam_call_callback(pMac, sessionId, NULL, 0,
+			       eCSR_ROAM_LOSTLINK_DETECTED, result);
+
+	if (eWNI_SME_DISASSOC_IND == type)
+		status = csr_send_mb_disassoc_cnf_msg(pMac, pDisassocIndMsg);
+	else if (eWNI_SME_DEAUTH_IND == type)
+		status = csr_send_mb_deauth_cnf_msg(pMac, pDeauthIndMsg);
+
+	/* prepare to tell HDD to disconnect */
+	qdf_mem_set(&roamInfo, sizeof(struct csr_roam_info), 0);
+	roamInfo.statusCode = (tSirResultCodes) pSession->roamingStatusCode;
+	roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode;
+	if (eWNI_SME_DISASSOC_IND == type) {
+		/* staMacAddr */
+		qdf_copy_macaddr(&roamInfo.peerMac,
+				 &pDisassocIndMsg->peer_macaddr);
+		roamInfo.staId = (uint8_t) pDisassocIndMsg->staId;
+		roamInfo.reasonCode = pDisassocIndMsg->reasonCode;
+	} else if (eWNI_SME_DEAUTH_IND == type) {
+		/* staMacAddr */
+		qdf_copy_macaddr(&roamInfo.peerMac,
+				 &pDeauthIndMsg->peer_macaddr);
+		roamInfo.staId = (uint8_t) pDeauthIndMsg->staId;
+		roamInfo.reasonCode = pDeauthIndMsg->reasonCode;
+		roamInfo.rxRssi = pDeauthIndMsg->rssi;
+	}
+	sme_debug("roamInfo.staId: %d", roamInfo.staId);
+/* Dont initiate internal driver based roaming after disconnection*/
+	return status;
+}
+
+
+void csr_roam_wm_status_change_complete(tpAniSirGlobal pMac,
+					uint8_t session_id)
+{
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+
+	pEntry = csr_nonscan_active_ll_peek_head(pMac, LL_ACCESS_LOCK);
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if (eSmeCommandWmStatusChange == pCommand->command) {
+			/* Nothing to process in a Lost Link completion....  It just kicks off a */
+			/* roaming sequence. */
+			if (csr_nonscan_active_ll_remove_entry(pMac, pEntry,
+				    LL_ACCESS_LOCK)) {
+				csr_release_command(pMac, pCommand);
+			} else {
+				sme_err("Failed to release command");
+			}
+		} else {
+			sme_warn("CSR: LOST LINK command is not ACTIVE ...");
+		}
+	} else {
+		sme_warn("CSR: NO commands are ACTIVE ...");
+	}
+}
+
+void csr_roam_process_wm_status_change_command(
+		tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tSirSmeRsp *pSirSmeMsg;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac,
+						pCommand->sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", pCommand->sessionId);
+		goto end;
+	}
+	sme_debug("session:%d, CmdType : %d",
+		pCommand->sessionId, pCommand->u.wmStatusChangeCmd.Type);
+
+	switch (pCommand->u.wmStatusChangeCmd.Type) {
+	case eCsrDisassociated:
+		pSirSmeMsg =
+			(tSirSmeRsp *) &pCommand->u.wmStatusChangeCmd.u.
+			DisassocIndMsg;
+		status =
+			csr_roam_lost_link(pMac, pCommand->sessionId,
+					   eWNI_SME_DISASSOC_IND, pSirSmeMsg);
+		break;
+	case eCsrDeauthenticated:
+		pSirSmeMsg =
+			(tSirSmeRsp *) &pCommand->u.wmStatusChangeCmd.u.
+			DeauthIndMsg;
+		status =
+			csr_roam_lost_link(pMac, pCommand->sessionId,
+					   eWNI_SME_DEAUTH_IND, pSirSmeMsg);
+		break;
+	default:
+		sme_warn("gets an unknown command %d",
+			pCommand->u.wmStatusChangeCmd.Type);
+		break;
+	}
+
+end:
+	if (status != QDF_STATUS_SUCCESS) {
+		/*
+		 * As status returned is not success, there is nothing else
+		 * left to do so release WM status change command here.
+		 */
+		csr_roam_wm_status_change_complete(pMac, pCommand->sessionId);
+	}
+}
+
+QDF_STATUS csr_process_del_sta_session_command(tpAniSirGlobal mac_ctx,
+					       tSmeCmd *sme_command)
+{
+	struct del_sta_self_params *del_sta_self_req;
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+
+	del_sta_self_req = qdf_mem_malloc(sizeof(struct del_sta_self_params));
+	if (!del_sta_self_req)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(del_sta_self_req->self_mac_addr,
+		     sme_command->u.delStaSessionCmd.selfMacAddr,
+		     sizeof(tSirMacAddr));
+
+	del_sta_self_req->session_id = sme_command->sessionId;
+	del_sta_self_req->sme_callback =
+		sme_command->u.delStaSessionCmd.session_close_cb;
+	del_sta_self_req->sme_ctx = sme_command->u.delStaSessionCmd.context;
+	msg.type = WMA_DEL_STA_SELF_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = del_sta_self_req;
+	msg.bodyval = 0;
+
+	sme_debug("sending WMA_DEL_STA_SELF_REQ");
+	status = wma_post_ctrl_msg(mac_ctx, &msg);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("wma_post_ctrl_msg failed");
+		qdf_mem_free(del_sta_self_req);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_compute_mode_and_band() - computes dot11mode
+ * @pMac:          mac global context
+ * @dot11_mode:    out param, do11 mode calculated
+ * @band:          out param, band caclculated
+ * @opr_ch:        operating channels
+ *
+ * This function finds dot11 mode based on current mode, operating channel and
+ * fw supported modes.
+ *
+ * Return: void
+ */
+static void
+csr_compute_mode_and_band(tpAniSirGlobal mac_ctx,
+			  enum csr_cfgdot11mode *dot11_mode,
+			  enum band_info *band,
+			  uint8_t opr_ch)
+{
+	bool vht_24_ghz = mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band;
+
+	switch (mac_ctx->roam.configParam.uCfgDot11Mode) {
+	case eCSR_CFG_DOT11_MODE_11A:
+		*dot11_mode = eCSR_CFG_DOT11_MODE_11A;
+		*band = BAND_5G;
+		break;
+	case eCSR_CFG_DOT11_MODE_11B:
+		*dot11_mode = eCSR_CFG_DOT11_MODE_11B;
+		*band = BAND_2G;
+		break;
+	case eCSR_CFG_DOT11_MODE_11G:
+		*dot11_mode = eCSR_CFG_DOT11_MODE_11G;
+		*band = BAND_2G;
+		break;
+	case eCSR_CFG_DOT11_MODE_11N:
+		*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+		*band = CSR_GET_BAND(opr_ch);
+		break;
+	case eCSR_CFG_DOT11_MODE_11AC:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			/*
+			 * If the operating channel is in 2.4 GHz band, check
+			 * for INI item to disable VHT operation in 2.4 GHz band
+			 */
+			if (WLAN_REG_IS_24GHZ_CH(opr_ch) && !vht_24_ghz)
+				/* Disable 11AC operation */
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+			else
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
+		} else {
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+		}
+		*band = CSR_GET_BAND(opr_ch);
+		break;
+	case eCSR_CFG_DOT11_MODE_11AC_ONLY:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			/*
+			 * If the operating channel is in 2.4 GHz band, check
+			 * for INI item to disable VHT operation in 2.4 GHz band
+			 */
+			if (WLAN_REG_IS_24GHZ_CH(opr_ch) && !vht_24_ghz)
+				/* Disable 11AC operation */
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+			else
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC_ONLY;
+		} else {
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+		}
+		*band = CSR_GET_BAND(opr_ch);
+		break;
+	case eCSR_CFG_DOT11_MODE_11AX:
+	case eCSR_CFG_DOT11_MODE_11AX_ONLY:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) {
+			*dot11_mode = mac_ctx->roam.configParam.uCfgDot11Mode;
+		} else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			/*
+			 * If the operating channel is in 2.4 GHz band, check
+			 * for INI item to disable VHT operation in 2.4 GHz band
+			 */
+			if (WLAN_REG_IS_24GHZ_CH(opr_ch) && !vht_24_ghz)
+				/* Disable 11AC operation */
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+			else
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
+		} else {
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+		}
+		*band = CSR_GET_BAND(opr_ch);
+		break;
+	case eCSR_CFG_DOT11_MODE_AUTO:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) {
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11AX;
+		} else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			/*
+			 * If the operating channel is in 2.4 GHz band,
+			 * check for INI item to disable VHT operation
+			 * in 2.4 GHz band
+			 */
+			if (WLAN_REG_IS_24GHZ_CH(opr_ch)
+				&& !vht_24_ghz)
+				/* Disable 11AC operation */
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+			else
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
+		} else {
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+		}
+		*band = CSR_GET_BAND(opr_ch);
+		break;
+	default:
+		/*
+		 * Global dot11 Mode setting is 11a/b/g. use the channel number
+		 * to determine the Mode setting.
+		 */
+		if (eCSR_OPERATING_CHANNEL_AUTO == opr_ch) {
+			*band = mac_ctx->mlme_cfg->gen.band;
+			if (BAND_2G == *band) {
+				/*
+				 * See reason in else if ( WLAN_REG_IS_24GHZ_CH
+				 * (opr_ch) ) to pick 11B
+				 */
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11B;
+			} else {
+				/* prefer 5GHz */
+				*band = BAND_5G;
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11A;
+			}
+		} else if (WLAN_REG_IS_24GHZ_CH(opr_ch)) {
+			/*
+			 * WiFi tests require IBSS networks to start in 11b mode
+			 * without any change to the default parameter settings
+			 * on the adapter. We use ACU to start an IBSS through
+			 * creation of a startIBSS profile. This startIBSS
+			 * profile has Auto MACProtocol and the adapter property
+			 * setting for dot11Mode is also AUTO. So in this case,
+			 * let's start the IBSS network in 11b mode instead of
+			 * 11g mode. So this is for Auto=profile->MacProtocol &&
+			 * Auto=Global. dot11Mode && profile->channel is < 14,
+			 * then start the IBSS in b mode.
+			 *
+			 * Note: we used to have this start as an 11g IBSS for
+			 * best performance. now to specify that the user will
+			 * have to set the do11Mode in the property page to 11g
+			 * to force it.
+			 */
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11B;
+			*band = BAND_2G;
+		} else {
+			/* else, it's a 5.0GHz channel.  Set mode to 11a. */
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11A;
+			*band = BAND_5G;
+		}
+		break;
+	} /* switch */
+}
+
+/**
+ * csr_roam_get_phy_mode_band_for_bss() - This function returns band and mode
+ * information.
+ * @mac_ctx:       mac global context
+ * @profile:       bss profile
+ * @band:          out param, band caclculated
+ * @opr_ch:        operating channels
+ *
+ * This function finds dot11 mode based on current mode, operating channel and
+ * fw supported modes. The only tricky part is that if phyMode is set to 11abg,
+ * this function may return eCSR_CFG_DOT11_MODE_11B instead of
+ * eCSR_CFG_DOT11_MODE_11G if everything is set to auto-pick.
+ *
+ * Return: dot11mode
+ */
+static enum csr_cfgdot11mode
+csr_roam_get_phy_mode_band_for_bss(tpAniSirGlobal mac_ctx,
+				   struct csr_roam_profile *profile,
+				   uint8_t opr_chn,
+				   enum band_info *p_band)
+{
+	enum band_info band;
+enum csr_cfgdot11mode curr_mode = mac_ctx->roam.configParam.uCfgDot11Mode;
+	enum csr_cfgdot11mode cfg_dot11_mode =
+		csr_get_cfg_dot11_mode_from_csr_phy_mode(profile,
+			(eCsrPhyMode) profile->phyMode,
+			mac_ctx->roam.configParam.ProprietaryRatesEnabled);
+
+	/*
+	 * If the global setting for dot11Mode is set to auto/abg, we overwrite
+	 * the setting in the profile.
+	 */
+	if ((!CSR_IS_INFRA_AP(profile)
+	    && ((eCSR_CFG_DOT11_MODE_AUTO == curr_mode)
+	    || (eCSR_CFG_DOT11_MODE_ABG == curr_mode)))
+	    || (eCSR_CFG_DOT11_MODE_AUTO == cfg_dot11_mode)
+	    || (eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode)) {
+		csr_compute_mode_and_band(mac_ctx, &cfg_dot11_mode,
+					  &band, opr_chn);
+	} /* if( eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode ) */
+	else {
+		/* dot11 mode is set, lets pick the band */
+		if (eCSR_OPERATING_CHANNEL_AUTO == opr_chn) {
+			/* channel is Auto also. */
+			band = mac_ctx->mlme_cfg->gen.band;
+			if (BAND_ALL == band) {
+				/* prefer 5GHz */
+				band = BAND_5G;
+			}
+		} else{
+			band = CSR_GET_BAND(opr_chn);
+		}
+	}
+	if (p_band)
+		*p_band = band;
+
+	if (opr_chn == 14) {
+		sme_err("Switching to Dot11B mode");
+		cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11B;
+	}
+
+	if (IS_24G_CH(opr_chn) &&
+	    !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band &&
+	    (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode ||
+	    eCSR_CFG_DOT11_MODE_11AC_ONLY == cfg_dot11_mode))
+		cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+	/*
+	 * Incase of WEP Security encryption type is coming as part of add key.
+	 * So while STart BSS dont have information
+	 */
+	if ((!CSR_IS_11n_ALLOWED(profile->EncryptionType.encryptionType[0])
+	    || ((profile->privacy == 1)
+		&& (profile->EncryptionType.encryptionType[0] ==
+		eCSR_ENCRYPT_TYPE_NONE)))
+		&& ((eCSR_CFG_DOT11_MODE_11N == cfg_dot11_mode) ||
+		    (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode) ||
+		    (eCSR_CFG_DOT11_MODE_11AX == cfg_dot11_mode))) {
+		/* We cannot do 11n here */
+		if (WLAN_REG_IS_24GHZ_CH(opr_chn))
+			cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11G;
+		else
+			cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11A;
+	}
+	sme_debug("dot11mode: %d", cfg_dot11_mode);
+	return cfg_dot11_mode;
+}
+
+QDF_STATUS csr_roam_issue_stop_bss(tpAniSirGlobal pMac,
+		uint32_t sessionId, enum csr_roam_substate NewSubstate)
+{
+	QDF_STATUS status;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	{
+		host_log_ibss_pkt_type *pIbssLog;
+
+		WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+					 LOG_WLAN_IBSS_C);
+		if (pIbssLog) {
+			pIbssLog->eventId = WLAN_IBSS_EVENT_STOP_REQ;
+			WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+		}
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	/* Set the roaming substate to 'stop Bss request'... */
+	csr_roam_substate_change(pMac, NewSubstate, sessionId);
+
+	/* attempt to stop the Bss (reason code is ignored...) */
+	status = csr_send_mb_stop_bss_req_msg(pMac, sessionId);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_warn(
+			"csr_send_mb_stop_bss_req_msg failed with status %d",
+			status);
+	}
+	return status;
+}
+
+/* pNumChan is a caller allocated space with the sizeof pChannels */
+QDF_STATUS csr_get_cfg_valid_channels(tpAniSirGlobal pMac, uint8_t *pChannels,
+				      uint32_t *pNumChan)
+{
+	uint8_t num_chan_temp = 0;
+	int i;
+
+	if (!QDF_IS_STATUS_SUCCESS(wlan_cfg_get_str(pMac,
+					WNI_CFG_VALID_CHANNEL_LIST,
+					(uint8_t *) pChannels, pNumChan)))
+		return QDF_STATUS_E_FAILURE;
+
+	for (i = 0; i < *pNumChan; i++) {
+		if (!wlan_reg_is_dsrc_chan(pMac->pdev, pChannels[i])) {
+			pChannels[num_chan_temp] = pChannels[i];
+			num_chan_temp++;
+		}
+	}
+
+	*pNumChan = num_chan_temp;
+	return QDF_STATUS_SUCCESS;
+}
+
+int8_t csr_get_cfg_max_tx_power(tpAniSirGlobal pMac, uint8_t channel)
+{
+	uint32_t cfgLength = 0;
+	uint16_t cfgId = 0;
+	int8_t maxTxPwr = 0;
+	uint8_t *pCountryInfo = NULL;
+	uint8_t count = 0;
+	uint8_t firstChannel;
+	uint8_t maxChannels;
+
+	if (WLAN_REG_IS_5GHZ_CH(channel)) {
+		cfgId = WNI_CFG_MAX_TX_POWER_5;
+		cfgLength = WNI_CFG_MAX_TX_POWER_5_LEN;
+	} else if (WLAN_REG_IS_24GHZ_CH(channel)) {
+		cfgId = WNI_CFG_MAX_TX_POWER_2_4;
+		cfgLength = WNI_CFG_MAX_TX_POWER_2_4_LEN;
+	} else
+		return maxTxPwr;
+
+	pCountryInfo = qdf_mem_malloc(cfgLength);
+	if (!pCountryInfo)
+		goto error;
+
+	if (wlan_cfg_get_str(pMac, cfgId, (uint8_t *)pCountryInfo,
+			&cfgLength) != QDF_STATUS_SUCCESS) {
+		goto error;
+	}
+	/* Identify the channel and maxtxpower */
+	while (count <= (cfgLength - (sizeof(tSirMacChanInfo)))) {
+		firstChannel = pCountryInfo[count++];
+		maxChannels = pCountryInfo[count++];
+		maxTxPwr = pCountryInfo[count++];
+
+		if ((channel >= firstChannel) &&
+		    (channel < (firstChannel + maxChannels))) {
+			break;
+		}
+	}
+
+error:
+	if (NULL != pCountryInfo)
+		qdf_mem_free(pCountryInfo);
+
+	return maxTxPwr;
+}
+
+bool csr_roam_is_channel_valid(tpAniSirGlobal pMac, uint8_t channel)
+{
+	bool fValid = false;
+	uint32_t idxValidChannels;
+	uint32_t len = sizeof(pMac->roam.validChannelList);
+
+	if (QDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels(pMac,
+					pMac->roam.validChannelList, &len))) {
+		for (idxValidChannels = 0; (idxValidChannels < len);
+		     idxValidChannels++) {
+			if (channel ==
+			    pMac->roam.validChannelList[idxValidChannels]) {
+				fValid = true;
+				break;
+			}
+		}
+	}
+	pMac->roam.numValidChannels = len;
+	return fValid;
+}
+
+/* This function check and validate whether the NIC can do CB (40MHz) */
+static ePhyChanBondState csr_get_cb_mode_from_ies(tpAniSirGlobal pMac,
+						  uint8_t chan,
+						  tDot11fBeaconIEs *pIes)
+{
+	ePhyChanBondState eRet = PHY_SINGLE_CHANNEL_CENTERED;
+	uint8_t sec_ch = 0;
+	uint32_t ChannelBondingMode;
+	struct ch_params ch_params = {0};
+
+	if (WLAN_REG_IS_24GHZ_CH(chan)) {
+		ChannelBondingMode =
+			pMac->roam.configParam.channelBondingMode24GHz;
+	} else {
+		ChannelBondingMode =
+			pMac->roam.configParam.channelBondingMode5GHz;
+	}
+
+	if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == ChannelBondingMode)
+		return PHY_SINGLE_CHANNEL_CENTERED;
+
+	/* Figure what the other side's CB mode */
+	if (!(pIes->HTCaps.present && (eHT_CHANNEL_WIDTH_40MHZ ==
+		pIes->HTCaps.supportedChannelWidthSet))) {
+		return PHY_SINGLE_CHANNEL_CENTERED;
+	}
+
+	/* In Case WPA2 and TKIP is the only one cipher suite in Pairwise */
+	if ((pIes->RSN.present && (pIes->RSN.pwise_cipher_suite_count == 1) &&
+		!memcmp(&(pIes->RSN.pwise_cipher_suites[0][0]),
+					"\x00\x0f\xac\x02", 4))
+		/* In Case only WPA1 is supported and TKIP is
+		 * the only one cipher suite in Unicast.
+		 */
+		|| (!pIes->RSN.present && (pIes->WPA.present &&
+			(pIes->WPA.unicast_cipher_count == 1) &&
+			!memcmp(&(pIes->WPA.unicast_ciphers[0][0]),
+					"\x00\x50\xf2\x02", 4)))) {
+		sme_debug("No channel bonding in TKIP mode");
+		return PHY_SINGLE_CHANNEL_CENTERED;
+	}
+
+	if (!pIes->HTInfo.present)
+		return PHY_SINGLE_CHANNEL_CENTERED;
+
+	/*
+	 * This is called during INFRA STA/CLIENT and should use the merged
+	 * value of supported channel width and recommended tx width as per
+	 * standard
+	 */
+	sme_debug("chan %d scws %u rtws %u sco %u", chan,
+		pIes->HTCaps.supportedChannelWidthSet,
+		pIes->HTInfo.recommendedTxWidthSet,
+		pIes->HTInfo.secondaryChannelOffset);
+
+	if (pIes->HTInfo.recommendedTxWidthSet == eHT_CHANNEL_WIDTH_40MHZ)
+		eRet = (ePhyChanBondState)pIes->HTInfo.secondaryChannelOffset;
+	else
+		eRet = PHY_SINGLE_CHANNEL_CENTERED;
+
+	switch (eRet) {
+	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+		sec_ch = chan + CSR_SEC_CHANNEL_OFFSET;
+		break;
+	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+		sec_ch = chan - CSR_SEC_CHANNEL_OFFSET;
+		break;
+	default:
+		break;
+	}
+
+	if (eRet != PHY_SINGLE_CHANNEL_CENTERED) {
+		ch_params.ch_width = CH_WIDTH_40MHZ;
+		wlan_reg_set_channel_params(pMac->pdev, chan,
+					    sec_ch, &ch_params);
+		if (ch_params.ch_width == CH_WIDTH_20MHZ ||
+		    ch_params.sec_ch_offset != eRet) {
+			sme_err("chan %d :: Supported HT BW %d and cbmode %d, APs HT BW %d and cbmode %d, so switch to 20Mhz",
+				chan, ch_params.ch_width,
+				ch_params.sec_ch_offset,
+				pIes->HTInfo.recommendedTxWidthSet, eRet);
+			eRet = PHY_SINGLE_CHANNEL_CENTERED;
+		}
+	}
+
+	return eRet;
+}
+
+static bool csr_is_encryption_in_list(tpAniSirGlobal pMac,
+				      tCsrEncryptionList *pCipherList,
+				      eCsrEncryptionType encryptionType)
+{
+	bool fFound = false;
+	uint32_t idx;
+
+	for (idx = 0; idx < pCipherList->numEntries; idx++) {
+		if (pCipherList->encryptionType[idx] == encryptionType) {
+			fFound = true;
+			break;
+		}
+	}
+	return fFound;
+}
+
+static bool csr_is_auth_in_list(tpAniSirGlobal pMac, tCsrAuthList *pAuthList,
+				eCsrAuthType authType)
+{
+	bool fFound = false;
+	uint32_t idx;
+
+	for (idx = 0; idx < pAuthList->numEntries; idx++) {
+		if (pAuthList->authType[idx] == authType) {
+			fFound = true;
+			break;
+		}
+	}
+	return fFound;
+}
+
+bool csr_is_same_profile(tpAniSirGlobal pMac,
+			 tCsrRoamConnectedProfile *pProfile1,
+			 struct csr_roam_profile *pProfile2)
+{
+	uint32_t i;
+	bool fCheck = false;
+	tCsrScanResultFilter *pScanFilter = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!(pProfile1 && pProfile2))
+		return fCheck;
+	pScanFilter = qdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (NULL == pScanFilter)
+		return fCheck;
+
+	status = csr_roam_prepare_filter_from_profile(pMac, pProfile2,
+						      pScanFilter);
+	if (!(QDF_IS_STATUS_SUCCESS(status)))
+		goto free_scan_filter;
+
+	for (i = 0; i < pScanFilter->SSIDs.numOfSSIDs; i++) {
+		fCheck = csr_is_ssid_match(pMac,
+				pScanFilter->SSIDs.SSIDList[i].SSID.ssId,
+				pScanFilter->SSIDs.SSIDList[i].SSID.length,
+				pProfile1->SSID.ssId,
+				pProfile1->SSID.length,
+				false);
+		if (fCheck)
+			break;
+	}
+	if (!fCheck)
+		goto free_scan_filter;
+
+	if (!csr_is_auth_in_list(pMac, &pProfile2->AuthType,
+				 pProfile1->AuthType)
+	    || (pProfile2->BSSType != pProfile1->BSSType)
+	    || !csr_is_encryption_in_list(pMac, &pProfile2->EncryptionType,
+					  pProfile1->EncryptionType)) {
+		fCheck = false;
+		goto free_scan_filter;
+	}
+	if (pProfile1->MDID.mdiePresent || pProfile2->MDID.mdiePresent) {
+		if (pProfile1->MDID.mobilityDomain
+			!= pProfile2->MDID.mobilityDomain) {
+			fCheck = false;
+			goto free_scan_filter;
+		}
+	}
+	/* Match found */
+	fCheck = true;
+free_scan_filter:
+	csr_free_scan_filter(pMac, pScanFilter);
+	qdf_mem_free(pScanFilter);
+	return fCheck;
+}
+
+static bool csr_roam_is_same_profile_keys(tpAniSirGlobal pMac,
+				   tCsrRoamConnectedProfile *pConnProfile,
+				   struct csr_roam_profile *pProfile2)
+{
+	bool fCheck = false;
+	int i;
+
+	do {
+		/* Only check for static WEP */
+		if (!csr_is_encryption_in_list
+			    (pMac, &pProfile2->EncryptionType,
+			    eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
+		    && !csr_is_encryption_in_list(pMac,
+				&pProfile2->EncryptionType,
+				eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
+			fCheck = true;
+			break;
+		}
+		if (!csr_is_encryption_in_list
+			    (pMac, &pProfile2->EncryptionType,
+			    pConnProfile->EncryptionType))
+			break;
+		if (pConnProfile->Keys.defaultIndex !=
+		    pProfile2->Keys.defaultIndex)
+			break;
+		for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
+			if (pConnProfile->Keys.KeyLength[i] !=
+			    pProfile2->Keys.KeyLength[i])
+				break;
+			if (qdf_mem_cmp(&pConnProfile->Keys.KeyMaterial[i],
+					     &pProfile2->Keys.KeyMaterial[i],
+					     pProfile2->Keys.KeyLength[i])) {
+				break;
+			}
+		}
+		if (i == CSR_MAX_NUM_KEY)
+			fCheck = true;
+	} while (0);
+	return fCheck;
+}
+
+/* IBSS */
+
+static uint8_t csr_roam_get_ibss_start_channel_number50(tpAniSirGlobal pMac)
+{
+	uint8_t channel = 0;
+	uint32_t idx;
+	uint32_t idxValidChannels;
+	bool fFound = false;
+	uint32_t len = sizeof(pMac->roam.validChannelList);
+
+	if (eCSR_OPERATING_CHANNEL_ANY != pMac->roam.configParam.
+							AdHocChannel5G) {
+		channel = pMac->roam.configParam.AdHocChannel5G;
+		if (!csr_roam_is_channel_valid(pMac, channel))
+			channel = 0;
+	}
+	if (0 == channel
+	    &&
+	    QDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels
+					  (pMac, (uint8_t *) pMac->roam.
+					validChannelList, &len))) {
+		for (idx = 0; (idx < CSR_NUM_IBSS_START_CHAN_50) && !fFound;
+		     idx++) {
+			for (idxValidChannels = 0;
+			     (idxValidChannels < len) && !fFound;
+			     idxValidChannels++) {
+				if (csr_start_ibss_channels50[idx] ==
+				    pMac->roam.
+				    validChannelList[idxValidChannels]) {
+					fFound = true;
+					channel =
+						csr_start_ibss_channels50[idx];
+				}
+			}
+		}
+		/*
+		 * this is rare, but if it does happen,
+		 * we find anyone in 11a bandwidth and
+		 * return the first 11a channel found!
+		 */
+		if (!fFound) {
+			for (idxValidChannels = 0; idxValidChannels < len;
+			     idxValidChannels++) {
+				if (WLAN_REG_IS_5GHZ_CH(pMac->roam.
+					validChannelList[idxValidChannels])) {
+					/* the max channel# in 11g is 14 */
+					if (idxValidChannels <
+					    CSR_NUM_IBSS_START_CHAN_50) {
+						channel =
+						pMac->roam.validChannelList
+						[idxValidChannels];
+					}
+					break;
+				}
+			}
+		}
+	} /* if */
+
+	return channel;
+}
+
+static uint8_t csr_roam_get_ibss_start_channel_number24(tpAniSirGlobal pMac)
+{
+	uint8_t channel = 1;
+	uint32_t idx;
+	uint32_t idxValidChannels;
+	bool fFound = false;
+	uint32_t len = sizeof(pMac->roam.validChannelList);
+
+	if (eCSR_OPERATING_CHANNEL_ANY != pMac->roam.configParam.
+							AdHocChannel24) {
+		channel = pMac->roam.configParam.AdHocChannel24;
+		if (!csr_roam_is_channel_valid(pMac, channel))
+			channel = 0;
+	}
+
+	if (0 == channel
+	    &&
+	    QDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels(pMac,
+					(uint8_t *) pMac->roam.validChannelList,
+					  &len))) {
+		for (idx = 0; (idx < CSR_NUM_IBSS_START_CHANNELS_24) && !fFound;
+		     idx++) {
+			for (idxValidChannels = 0;
+			     (idxValidChannels < len) && !fFound;
+			     idxValidChannels++) {
+				if (csr_start_ibss_channels24[idx] ==
+				    pMac->roam.
+				    validChannelList[idxValidChannels]) {
+					fFound = true;
+					channel =
+						csr_start_ibss_channels24[idx];
+				}
+			}
+		}
+	}
+
+	return channel;
+}
+/**
+ * csr_populate_basic_rates() - populates OFDM or CCK rates
+ * @rates:         rate struct to populate
+ * @is_ofdm_rates:          true: ofdm rates, false: cck rates
+ * @is_basic_rates:        indicates if rates are to be masked with
+ *                 CSR_DOT11_BASIC_RATE_MASK
+ *
+ * This function will populate OFDM or CCK rates
+ *
+ * Return: void
+ */
+static void
+csr_populate_basic_rates(tSirMacRateSet *rate_set, bool is_ofdm_rates,
+		bool is_basic_rates)
+{
+	int i = 0;
+	uint8_t ofdm_rates[8] = {
+		SIR_MAC_RATE_6,
+		SIR_MAC_RATE_9,
+		SIR_MAC_RATE_12,
+		SIR_MAC_RATE_18,
+		SIR_MAC_RATE_24,
+		SIR_MAC_RATE_36,
+		SIR_MAC_RATE_48,
+		SIR_MAC_RATE_54
+	};
+	uint8_t cck_rates[4] = {
+		SIR_MAC_RATE_1,
+		SIR_MAC_RATE_2,
+		SIR_MAC_RATE_5_5,
+		SIR_MAC_RATE_11
+	};
+
+	if (is_ofdm_rates == true) {
+		rate_set->numRates = 8;
+		qdf_mem_copy(rate_set->rate, ofdm_rates, sizeof(ofdm_rates));
+		if (is_basic_rates) {
+			rate_set->rate[0] |= CSR_DOT11_BASIC_RATE_MASK;
+			rate_set->rate[2] |= CSR_DOT11_BASIC_RATE_MASK;
+			rate_set->rate[4] |= CSR_DOT11_BASIC_RATE_MASK;
+		}
+		for (i = 0; i < rate_set->numRates; i++)
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			("Default OFDM rate is %2x"), rate_set->rate[i]);
+	} else {
+		rate_set->numRates = 4;
+		qdf_mem_copy(rate_set->rate, cck_rates, sizeof(cck_rates));
+		if (is_basic_rates) {
+			rate_set->rate[0] |= CSR_DOT11_BASIC_RATE_MASK;
+			rate_set->rate[1] |= CSR_DOT11_BASIC_RATE_MASK;
+			rate_set->rate[2] |= CSR_DOT11_BASIC_RATE_MASK;
+			rate_set->rate[3] |= CSR_DOT11_BASIC_RATE_MASK;
+		}
+		for (i = 0; i < rate_set->numRates; i++)
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			("Default CCK rate is %2x"), rate_set->rate[i]);
+
+	}
+}
+
+/**
+ * csr_convert_mode_to_nw_type() - convert mode into network type
+ * @dot11_mode:    dot11_mode
+ * @band:          2.4 or 5 GHz
+ *
+ * Return: tSirNwType
+ */
+static tSirNwType
+csr_convert_mode_to_nw_type(enum csr_cfgdot11mode dot11_mode,
+			    enum band_info band)
+{
+	switch (dot11_mode) {
+	case eCSR_CFG_DOT11_MODE_11G:
+		return eSIR_11G_NW_TYPE;
+	case eCSR_CFG_DOT11_MODE_11B:
+		return eSIR_11B_NW_TYPE;
+	case eCSR_CFG_DOT11_MODE_11A:
+		return eSIR_11A_NW_TYPE;
+	case eCSR_CFG_DOT11_MODE_11N:
+	default:
+		/*
+		 * Because LIM only verifies it against 11a, 11b or 11g, set
+		 * only 11g or 11a here
+		 */
+		if (BAND_2G == band)
+			return eSIR_11G_NW_TYPE;
+		else
+			return eSIR_11A_NW_TYPE;
+	}
+	return eSIR_DONOT_USE_NW_TYPE;
+}
+
+/**
+ * csr_populate_supported_rates_from_hostapd() - populates operational
+ * and extended rates.
+ * from hostapd.conf file
+ * @opr_rates:		rate struct to populate operational rates
+ * @ext_rates:		rate struct to populate extended rates
+ * @profile:		bss profile
+ *
+ * Return: void
+ */
+static void csr_populate_supported_rates_from_hostapd(tSirMacRateSet *opr_rates,
+		tSirMacRateSet *ext_rates,
+		struct csr_roam_profile *profile)
+{
+	int i = 0;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("supported_rates: %d extended_rates: %d"),
+			profile->supported_rates.numRates,
+			profile->extended_rates.numRates);
+
+	if (profile->supported_rates.numRates > SIR_MAC_RATESET_EID_MAX)
+		profile->supported_rates.numRates = SIR_MAC_RATESET_EID_MAX;
+
+	if (profile->extended_rates.numRates > SIR_MAC_RATESET_EID_MAX)
+		profile->extended_rates.numRates = SIR_MAC_RATESET_EID_MAX;
+
+	if (profile->supported_rates.numRates) {
+		opr_rates->numRates = profile->supported_rates.numRates;
+		qdf_mem_copy(opr_rates->rate,
+				profile->supported_rates.rate,
+				profile->supported_rates.numRates);
+		for (i = 0; i < opr_rates->numRates; i++)
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("Supported Rate is %2x"), opr_rates->rate[i]);
+	}
+	if (profile->extended_rates.numRates) {
+		ext_rates->numRates =
+			profile->extended_rates.numRates;
+		qdf_mem_copy(ext_rates->rate,
+				profile->extended_rates.rate,
+				profile->extended_rates.numRates);
+		for (i = 0; i < ext_rates->numRates; i++)
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("Extended Rate is %2x"), ext_rates->rate[i]);
+	}
+}
+
+/**
+ * csr_roam_get_bss_start_parms() - get bss start param from profile
+ * @pMac:          mac global context
+ * @pProfile:      roam profile
+ * @pParam:        out param, start bss params
+ * @skip_hostapd_rate: to skip given hostapd's rate
+ *
+ * This function populates start bss param from roam profile
+ *
+ * Return: void
+ */
+static QDF_STATUS
+csr_roam_get_bss_start_parms(tpAniSirGlobal pMac,
+			     struct csr_roam_profile *pProfile,
+			     struct csr_roamstart_bssparams *pParam,
+			     bool skip_hostapd_rate)
+{
+	enum band_info band;
+	uint8_t opr_ch = 0;
+	tSirNwType nw_type;
+	uint8_t tmp_opr_ch = 0;
+	tSirMacRateSet *opr_rates = &pParam->operationalRateSet;
+	tSirMacRateSet *ext_rates = &pParam->extendedRateSet;
+
+	if (pProfile->ChannelInfo.numOfChannels
+	    && pProfile->ChannelInfo.ChannelList)
+		tmp_opr_ch = pProfile->ChannelInfo.ChannelList[0];
+
+	pParam->uCfgDot11Mode = csr_roam_get_phy_mode_band_for_bss(pMac,
+					 pProfile, tmp_opr_ch, &band);
+
+	if (((pProfile->csrPersona == QDF_P2P_CLIENT_MODE)
+	    || (pProfile->csrPersona == QDF_P2P_GO_MODE))
+	    && (pParam->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11B)) {
+		/* This should never happen */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
+			 "For P2P (persona %d) dot11_mode is 11B",
+			  pProfile->csrPersona);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	nw_type = csr_convert_mode_to_nw_type(pParam->uCfgDot11Mode, band);
+	ext_rates->numRates = 0;
+	/*
+	 * hostapd.conf will populate its basic and extended rates
+	 * as per hw_mode, but if acs in ini is enabled driver should
+	 * ignore basic and extended rates from hostapd.conf and should
+	 * populate default rates.
+	 */
+	if (!cds_is_sub_20_mhz_enabled() && !skip_hostapd_rate &&
+			(pProfile->supported_rates.numRates ||
+			pProfile->extended_rates.numRates)) {
+		csr_populate_supported_rates_from_hostapd(opr_rates,
+				ext_rates, pProfile);
+		pParam->operationChn = tmp_opr_ch;
+	} else {
+		switch (nw_type) {
+		default:
+			sme_err(
+				"sees an unknown pSirNwType (%d)",
+				nw_type);
+			return QDF_STATUS_E_INVAL;
+		case eSIR_11A_NW_TYPE:
+			csr_populate_basic_rates(opr_rates, true, true);
+			if (eCSR_OPERATING_CHANNEL_ANY != tmp_opr_ch) {
+				opr_ch = tmp_opr_ch;
+				break;
+			}
+			opr_ch = csr_roam_get_ibss_start_channel_number50(pMac);
+			if (0 == opr_ch &&
+				CSR_IS_PHY_MODE_DUAL_BAND(pProfile->phyMode) &&
+				CSR_IS_PHY_MODE_DUAL_BAND(
+					pMac->roam.configParam.phyMode)) {
+				/*
+				 * We could not find a 5G channel by auto pick,
+				 * let's try 2.4G channels. We only do this here
+				 * because csr_roam_get_phy_mode_band_for_bss
+				 * always picks 11a  for AUTO
+				 */
+				nw_type = eSIR_11B_NW_TYPE;
+				opr_ch =
+				csr_roam_get_ibss_start_channel_number24(pMac);
+				csr_populate_basic_rates(opr_rates, false,
+								true);
+			}
+			break;
+		case eSIR_11B_NW_TYPE:
+			csr_populate_basic_rates(opr_rates, false, true);
+			if (eCSR_OPERATING_CHANNEL_ANY == tmp_opr_ch)
+				opr_ch =
+				csr_roam_get_ibss_start_channel_number24(pMac);
+			else
+				opr_ch = tmp_opr_ch;
+			break;
+		case eSIR_11G_NW_TYPE:
+			/* For P2P Client and P2P GO, disable 11b rates */
+			if ((pProfile->csrPersona == QDF_P2P_CLIENT_MODE) ||
+				(pProfile->csrPersona == QDF_P2P_GO_MODE) ||
+				(eCSR_CFG_DOT11_MODE_11G_ONLY ==
+					pParam->uCfgDot11Mode)) {
+				csr_populate_basic_rates(opr_rates, true, true);
+			} else {
+				csr_populate_basic_rates(opr_rates, false,
+								true);
+				csr_populate_basic_rates(ext_rates, true,
+								false);
+			}
+			if (eCSR_OPERATING_CHANNEL_ANY == tmp_opr_ch)
+				opr_ch =
+				csr_roam_get_ibss_start_channel_number24(pMac);
+			else
+				opr_ch = tmp_opr_ch;
+			break;
+		}
+		pParam->operationChn = opr_ch;
+	}
+
+	pParam->sirNwType = nw_type;
+	pParam->ch_params.ch_width = pProfile->ch_params.ch_width;
+	pParam->ch_params.center_freq_seg0 =
+		pProfile->ch_params.center_freq_seg0;
+	pParam->ch_params.center_freq_seg1 =
+		pProfile->ch_params.center_freq_seg1;
+	pParam->ch_params.sec_ch_offset =
+		pProfile->ch_params.sec_ch_offset;
+	return QDF_STATUS_SUCCESS;
+}
+
+static void
+csr_roam_get_bss_start_parms_from_bss_desc(
+					tpAniSirGlobal pMac,
+					tSirBssDescription *pBssDesc,
+					tDot11fBeaconIEs *pIes,
+					struct csr_roamstart_bssparams *pParam)
+{
+	if (!pParam) {
+		sme_err("BSS param's pointer is NULL");
+		return;
+	}
+
+	pParam->sirNwType = pBssDesc->nwType;
+	pParam->cbMode = PHY_SINGLE_CHANNEL_CENTERED;
+	pParam->operationChn = pBssDesc->channelId;
+	qdf_mem_copy(&pParam->bssid, pBssDesc->bssId,
+						sizeof(struct qdf_mac_addr));
+
+	if (!pIes) {
+		pParam->ssId.length = 0;
+		pParam->operationalRateSet.numRates = 0;
+		sme_err("IEs struct pointer is NULL");
+		return;
+	}
+
+	if (pIes->SuppRates.present) {
+		pParam->operationalRateSet.numRates = pIes->SuppRates.num_rates;
+		if (pIes->SuppRates.num_rates > SIR_MAC_RATESET_EID_MAX) {
+			sme_err(
+				"num_rates: %d > max val, resetting",
+				pIes->SuppRates.num_rates);
+			pIes->SuppRates.num_rates = SIR_MAC_RATESET_EID_MAX;
+		}
+		qdf_mem_copy(pParam->operationalRateSet.rate,
+			     pIes->SuppRates.rates,
+			     sizeof(*pIes->SuppRates.rates) *
+			     pIes->SuppRates.num_rates);
+	}
+	if (pIes->ExtSuppRates.present) {
+		pParam->extendedRateSet.numRates = pIes->ExtSuppRates.num_rates;
+		if (pIes->ExtSuppRates.num_rates > SIR_MAC_RATESET_EID_MAX) {
+			sme_err(
+				"num_rates: %d > max val, resetting",
+				pIes->ExtSuppRates.num_rates);
+			pIes->ExtSuppRates.num_rates = SIR_MAC_RATESET_EID_MAX;
+		}
+		qdf_mem_copy(pParam->extendedRateSet.rate,
+			     pIes->ExtSuppRates.rates,
+			     sizeof(*pIes->ExtSuppRates.rates) *
+			     pIes->ExtSuppRates.num_rates);
+	}
+	if (pIes->SSID.present) {
+		pParam->ssId.length = pIes->SSID.num_ssid;
+		qdf_mem_copy(pParam->ssId.ssId, pIes->SSID.ssid,
+			     pParam->ssId.length);
+	}
+	pParam->cbMode = csr_get_cb_mode_from_ies(pMac, pParam->operationChn,
+						  pIes);
+}
+
+static void csr_roam_determine_max_rate_for_ad_hoc(tpAniSirGlobal pMac,
+						   tSirMacRateSet *pSirRateSet)
+{
+	uint8_t MaxRate = 0;
+	uint32_t i;
+	uint8_t *pRate;
+
+	pRate = pSirRateSet->rate;
+	for (i = 0; i < pSirRateSet->numRates; i++) {
+		MaxRate = CSR_MAX(MaxRate, (pRate[i] &
+						(~CSR_DOT11_BASIC_RATE_MASK)));
+	}
+
+	/* Save the max rate in the connected state information.
+	 * modify LastRates variable as well
+	 */
+
+}
+
+QDF_STATUS csr_roam_issue_start_bss(tpAniSirGlobal pMac, uint32_t sessionId,
+				    struct csr_roamstart_bssparams *pParam,
+				    struct csr_roam_profile *pProfile,
+				    tSirBssDescription *pBssDesc,
+					uint32_t roamId)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	enum band_info eBand;
+	/* Set the roaming substate to 'Start BSS attempt'... */
+	csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_START_BSS_REQ,
+				 sessionId);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	/* Need to figure out whether we need to log WDS??? */
+	if (CSR_IS_IBSS(pProfile)) {
+		host_log_ibss_pkt_type *pIbssLog;
+
+		WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+					 LOG_WLAN_IBSS_C);
+		if (pIbssLog) {
+			if (pBssDesc) {
+				pIbssLog->eventId =
+					WLAN_IBSS_EVENT_JOIN_IBSS_REQ;
+				qdf_mem_copy(pIbssLog->bssid.bytes,
+					pBssDesc->bssId, QDF_MAC_ADDR_SIZE);
+			} else
+				pIbssLog->eventId =
+					WLAN_IBSS_EVENT_START_IBSS_REQ;
+
+			qdf_mem_copy(pIbssLog->ssid, pParam->ssId.ssId,
+				     pParam->ssId.length);
+			if (pProfile->ChannelInfo.numOfChannels == 0)
+				pIbssLog->channelSetting = AUTO_PICK;
+			else
+				pIbssLog->channelSetting = SPECIFIED;
+
+			pIbssLog->operatingChannel = pParam->operationChn;
+			WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+		}
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	/* Put RSN information in for Starting BSS */
+	pParam->nRSNIELength = (uint16_t) pProfile->nRSNReqIELength;
+	pParam->pRSNIE = pProfile->pRSNReqIE;
+
+	pParam->privacy = pProfile->privacy;
+	pParam->fwdWPSPBCProbeReq = pProfile->fwdWPSPBCProbeReq;
+	pParam->authType = pProfile->csr80211AuthType;
+	pParam->beaconInterval = pProfile->beaconInterval;
+	pParam->dtimPeriod = pProfile->dtimPeriod;
+	pParam->ApUapsdEnable = pProfile->ApUapsdEnable;
+	pParam->ssidHidden = pProfile->SSIDs.SSIDList[0].ssidHidden;
+	if (CSR_IS_INFRA_AP(pProfile) && (pParam->operationChn != 0)) {
+		if (csr_is_valid_channel(pMac, pParam->operationChn) !=
+		    QDF_STATUS_SUCCESS) {
+			pParam->operationChn = INFRA_AP_DEFAULT_CHANNEL;
+			pParam->ch_params.ch_width = CH_WIDTH_20MHZ;
+		}
+	}
+	pParam->protEnabled = pProfile->protEnabled;
+	pParam->obssProtEnabled = pProfile->obssProtEnabled;
+	pParam->ht_protection = pProfile->cfg_protection;
+	pParam->wps_state = pProfile->wps_state;
+
+	pParam->uCfgDot11Mode =
+		csr_roam_get_phy_mode_band_for_bss(pMac, pProfile,
+						   pParam->
+						   operationChn,
+						   &eBand);
+	pParam->bssPersona = pProfile->csrPersona;
+
+#ifdef WLAN_FEATURE_11W
+	pParam->mfpCapable = (0 != pProfile->MFPCapable);
+	pParam->mfpRequired = (0 != pProfile->MFPRequired);
+#endif
+
+	pParam->addIeParams.probeRespDataLen =
+		pProfile->addIeParams.probeRespDataLen;
+	pParam->addIeParams.probeRespData_buff =
+		pProfile->addIeParams.probeRespData_buff;
+
+	pParam->addIeParams.assocRespDataLen =
+		pProfile->addIeParams.assocRespDataLen;
+	pParam->addIeParams.assocRespData_buff =
+		pProfile->addIeParams.assocRespData_buff;
+
+	if (CSR_IS_IBSS(pProfile)) {
+		pParam->addIeParams.probeRespBCNDataLen =
+			pProfile->nWPAReqIELength;
+		pParam->addIeParams.probeRespBCNData_buff = pProfile->pWPAReqIE;
+	} else {
+		pParam->addIeParams.probeRespBCNDataLen =
+			pProfile->addIeParams.probeRespBCNDataLen;
+		pParam->addIeParams.probeRespBCNData_buff =
+			pProfile->addIeParams.probeRespBCNData_buff;
+	}
+
+	if (pProfile->csrPersona == QDF_SAP_MODE)
+		pParam->sap_dot11mc = pMac->mlme_cfg->gen.sap_dot11mc;
+	else
+		pParam->sap_dot11mc = 1;
+
+	sme_debug("11MC Support Enabled : %d", pParam->sap_dot11mc);
+
+	pParam->cac_duration_ms = pProfile->cac_duration_ms;
+	pParam->dfs_regdomain = pProfile->dfs_regdomain;
+	pParam->beacon_tx_rate = pProfile->beacon_tx_rate;
+
+	/* When starting an IBSS, start on the channel from the Profile. */
+	status = csr_send_mb_start_bss_req_msg(pMac, sessionId,
+						pProfile->BSSType, pParam,
+					      pBssDesc);
+	return status;
+}
+
+void csr_roam_prepare_bss_params(tpAniSirGlobal pMac, uint32_t sessionId,
+					struct csr_roam_profile *pProfile,
+					tSirBssDescription *pBssDesc,
+					struct bss_config_param *pBssConfig,
+					tDot11fBeaconIEs *pIes)
+{
+	uint8_t Channel;
+	ePhyChanBondState cbMode = PHY_SINGLE_CHANNEL_CENTERED;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	bool skip_hostapd_rate = !pProfile->chan_switch_hostapd_rate_enabled;
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+
+	if (pBssDesc) {
+		csr_roam_get_bss_start_parms_from_bss_desc(pMac, pBssDesc, pIes,
+							&pSession->bssParams);
+		if (CSR_IS_NDI(pProfile)) {
+			qdf_copy_macaddr(&pSession->bssParams.bssid,
+				&pSession->selfMacAddr);
+		}
+	} else {
+		csr_roam_get_bss_start_parms(pMac, pProfile,
+					     &pSession->bssParams,
+					     skip_hostapd_rate);
+		/* Use the first SSID */
+		if (pProfile->SSIDs.numOfSSIDs)
+			qdf_mem_copy(&pSession->bssParams.ssId,
+				     pProfile->SSIDs.SSIDList,
+				     sizeof(tSirMacSSid));
+		if (pProfile->BSSIDs.numOfBSSIDs)
+			/* Use the first BSSID */
+			qdf_mem_copy(&pSession->bssParams.bssid,
+				     pProfile->BSSIDs.bssid,
+				     sizeof(struct qdf_mac_addr));
+		else
+			qdf_mem_set(&pSession->bssParams.bssid,
+				    sizeof(struct qdf_mac_addr), 0);
+	}
+	Channel = pSession->bssParams.operationChn;
+	/* Set operating channel in pProfile which will be used */
+	/* in csr_roam_set_bss_config_cfg() to determine channel bonding */
+	/* mode and will be configured in CFG later */
+	pProfile->operationChannel = Channel;
+
+	if (Channel == 0)
+		sme_err("CSR cannot find a channel to start IBSS");
+	else {
+		csr_roam_determine_max_rate_for_ad_hoc(pMac,
+						       &pSession->bssParams.
+						       operationalRateSet);
+		if (CSR_IS_INFRA_AP(pProfile) || CSR_IS_START_IBSS(pProfile)) {
+			if (WLAN_REG_IS_24GHZ_CH(Channel)) {
+				cbMode =
+					pMac->roam.configParam.
+					channelBondingMode24GHz;
+			} else {
+				cbMode =
+					pMac->roam.configParam.
+					channelBondingMode5GHz;
+			}
+			sme_debug("## cbMode %d", cbMode);
+			pBssConfig->cbMode = cbMode;
+			pSession->bssParams.cbMode = cbMode;
+		}
+	}
+}
+
+static QDF_STATUS csr_roam_start_ibss(tpAniSirGlobal pMac, uint32_t sessionId,
+				      struct csr_roam_profile *pProfile,
+				      bool *pfSameIbss)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	bool fSameIbss = false;
+
+	if (csr_is_conn_state_ibss(pMac, sessionId)) {
+		/* Check if any profile parameter has changed ? If any profile
+		 * parameter has changed then stop old BSS and start a new one
+		 * with new parameters
+		 */
+		if (csr_is_same_profile(pMac,
+				&pMac->roam.roamSession[sessionId].
+				connectedProfile, pProfile))
+			fSameIbss = true;
+		else
+			status = csr_roam_issue_stop_bss(pMac, sessionId,
+				eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING);
+
+	} else if (csr_is_conn_state_connected_infra(pMac, sessionId))
+		/* Disassociate from the connected Infrastructure network... */
+		status = csr_roam_issue_disassociate(pMac, sessionId,
+				eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
+						    false);
+	else {
+		struct bss_config_param *pBssConfig;
+
+		pBssConfig = qdf_mem_malloc(sizeof(struct bss_config_param));
+		if (NULL == pBssConfig)
+			status = QDF_STATUS_E_NOMEM;
+		else
+			status = QDF_STATUS_SUCCESS;
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			/* there is no Bss description before we start an IBSS
+			 * so we need to adopt all Bss configuration parameters
+			 * from the Profile.
+			 */
+			status = csr_roam_prepare_bss_config_from_profile(pMac,
+								pProfile,
+								pBssConfig,
+								NULL);
+			if (QDF_IS_STATUS_SUCCESS(status)) {
+				/* save dotMode */
+				pMac->roam.roamSession[sessionId].bssParams.
+				uCfgDot11Mode = pBssConfig->uCfgDot11Mode;
+				/* Prepare some more parameters for this IBSS */
+				csr_roam_prepare_bss_params(pMac, sessionId,
+							    pProfile, NULL,
+							    pBssConfig, NULL);
+				status = csr_roam_set_bss_config_cfg(pMac,
+								sessionId,
+								pProfile, NULL,
+								pBssConfig,
+								NULL, false);
+			}
+
+			qdf_mem_free(pBssConfig);
+		} /* Allocate memory */
+	}
+
+	if (pfSameIbss)
+		*pfSameIbss = fSameIbss;
+	return status;
+}
+
+static void csr_roam_update_connected_profile_from_new_bss(tpAniSirGlobal pMac,
+							   uint32_t sessionId,
+						tSirSmeNewBssInfo *pNewBss)
+{
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+
+	if (pNewBss) {
+		/* Set the operating channel. */
+		pSession->connectedProfile.operationChannel =
+			pNewBss->channelNumber;
+		/* move the BSSId from the BSS description into the connected
+		 * state information.
+		 */
+		qdf_mem_copy(&pSession->connectedProfile.bssid.bytes,
+			     &(pNewBss->bssId), sizeof(struct qdf_mac_addr));
+	}
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+void csr_get_pmk_info(tpAniSirGlobal mac_ctx, uint8_t session_id,
+			  tPmkidCacheInfo *pmk_cache)
+{
+	struct csr_roam_session *session = NULL;
+
+	if (!mac_ctx) {
+		sme_err("Mac_ctx is NULL");
+		return;
+	}
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (!session) {
+		sme_err("session %d not found", session_id);
+		return;
+	}
+	qdf_mem_copy(pmk_cache->pmk, session->psk_pmk,
+					sizeof(session->psk_pmk));
+	pmk_cache->pmk_len = session->pmk_len;
+}
+
+QDF_STATUS csr_roam_set_psk_pmk(tpAniSirGlobal pMac, uint32_t sessionId,
+				uint8_t *pPSK_PMK, size_t pmk_len)
+{
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_copy(pSession->psk_pmk, pPSK_PMK, sizeof(pSession->psk_pmk));
+	pSession->pmk_len = pmk_len;
+
+	if (csr_is_auth_type_ese(pMac->roam.roamSession[sessionId].
+				connectedProfile.AuthType)) {
+		sme_debug("PMK update is not required for ESE");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	csr_roam_offload_scan(pMac, sessionId,
+			      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+			      REASON_ROAM_PSK_PMK_CHANGED);
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void
+csr_roam_diag_set_pmkid(struct csr_roam_session *pSession)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(secEvent,
+				 host_event_wlan_security_payload_type);
+	qdf_mem_set(&secEvent,
+	    sizeof(host_event_wlan_security_payload_type), 0);
+	secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_UPDATE;
+	secEvent.encryptionModeMulticast =
+		(uint8_t) diag_enc_type_from_csr_type(
+			pSession->connectedProfile.mcEncryptionType);
+	secEvent.encryptionModeUnicast =
+		(uint8_t) diag_enc_type_from_csr_type(
+			pSession->connectedProfile.EncryptionType);
+	qdf_mem_copy(secEvent.bssid,
+		     pSession->connectedProfile.bssid.bytes,
+			QDF_MAC_ADDR_SIZE);
+	secEvent.authMode = (uint8_t) diag_auth_type_from_csr_type(
+				pSession->connectedProfile.AuthType);
+	WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+/**
+ * csr_update_pmk_cache - API to update PMK cache
+ * @pSession: pointer to session
+ * @pmksa: pointer to PMKSA struct
+ *
+ * Return : None
+ */
+static void csr_update_pmk_cache(struct csr_roam_session *session,
+			tPmkidCacheInfo *pmksa)
+{
+	uint16_t cache_idx = session->curr_cache_idx;
+
+	/* Add entry to the cache */
+	if (!pmksa->ssid_len) {
+		qdf_copy_macaddr(
+		    &session->PmkidCacheInfo[cache_idx].BSSID,
+		    &pmksa->BSSID);
+		session->PmkidCacheInfo[cache_idx].ssid_len = 0;
+	} else {
+		qdf_mem_copy(session->PmkidCacheInfo[cache_idx].ssid,
+			pmksa->ssid, pmksa->ssid_len);
+		session->PmkidCacheInfo[cache_idx].ssid_len =
+			pmksa->ssid_len;
+		qdf_mem_copy(session->PmkidCacheInfo[cache_idx].cache_id,
+			pmksa->cache_id, CACHE_ID_LEN);
+
+	}
+	qdf_mem_copy(
+	    session->PmkidCacheInfo[cache_idx].PMKID,
+	    pmksa->PMKID, CSR_RSN_PMKID_SIZE);
+
+	if (pmksa->pmk_len)
+		qdf_mem_copy(session->PmkidCacheInfo[cache_idx].pmk,
+				pmksa->pmk, pmksa->pmk_len);
+
+	session->PmkidCacheInfo[cache_idx].pmk_len = pmksa->pmk_len;
+
+	/* Increment the CSR local cache index */
+	if (cache_idx < (CSR_MAX_PMKID_ALLOWED - 1))
+		session->curr_cache_idx++;
+	else {
+		sme_debug("max value reached, setting current index as 0");
+		session->curr_cache_idx = 0;
+	}
+
+	session->NumPmkidCache++;
+	if (session->NumPmkidCache > CSR_MAX_PMKID_ALLOWED) {
+		sme_debug("setting num pmkid cache to %d",
+			CSR_MAX_PMKID_ALLOWED);
+		session->NumPmkidCache = CSR_MAX_PMKID_ALLOWED;
+	}
+}
+
+QDF_STATUS
+csr_roam_set_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
+			 tPmkidCacheInfo *pPMKIDCache, uint32_t numItems,
+			 bool update_entire_cache)
+{
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	uint32_t i = 0;
+	tPmkidCacheInfo *pmksa;
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_debug("numItems = %d", numItems);
+
+	if (numItems > CSR_MAX_PMKID_ALLOWED)
+		return QDF_STATUS_E_INVAL;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_roam_diag_set_pmkid(pSession);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+	if (update_entire_cache) {
+		if (numItems && pPMKIDCache) {
+			pSession->NumPmkidCache = (uint16_t) numItems;
+			qdf_mem_copy(pSession->PmkidCacheInfo, pPMKIDCache,
+				sizeof(tPmkidCacheInfo) * numItems);
+			pSession->curr_cache_idx = (uint16_t)numItems;
+		}
+		return QDF_STATUS_SUCCESS;
+	}
+
+	for (i = 0; i < numItems; i++) {
+		pmksa = &pPMKIDCache[i];
+
+		/* Delete the entry if present */
+		csr_roam_del_pmkid_from_cache(pMac, sessionId,
+				pmksa, false);
+		/* Update new entry */
+		csr_update_pmk_cache(pSession, pmksa);
+
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS csr_roam_del_pmkid_from_cache(tpAniSirGlobal pMac,
+					 uint32_t sessionId,
+					 tPmkidCacheInfo *pmksa,
+					 bool flush_cache)
+{
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	bool fMatchFound = false;
+	uint32_t Index;
+	uint32_t curr_idx;
+	tPmkidCacheInfo *cached_pmksa;
+	uint32_t i;
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Check if there are no entries to delete */
+	if (0 == pSession->NumPmkidCache) {
+		sme_debug("No entries to delete/Flush");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (flush_cache) {
+		/* Flush the entire cache */
+		qdf_mem_zero(pSession->PmkidCacheInfo,
+			     sizeof(tPmkidCacheInfo) * CSR_MAX_PMKID_ALLOWED);
+		pSession->NumPmkidCache = 0;
+		pSession->curr_cache_idx = 0;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* !flush_cache - so look up in the cache */
+	for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) {
+		cached_pmksa = &pSession->PmkidCacheInfo[Index];
+		if ((!cached_pmksa->ssid_len) &&
+			qdf_is_macaddr_equal(&cached_pmksa->BSSID,
+				&pmksa->BSSID))
+			fMatchFound = 1;
+
+		else if (cached_pmksa->ssid_len &&
+			(!qdf_mem_cmp(cached_pmksa->ssid,
+			pmksa->ssid, pmksa->ssid_len)) &&
+			(!qdf_mem_cmp(cached_pmksa->cache_id,
+				pmksa->cache_id, CACHE_ID_LEN)))
+			fMatchFound = 1;
+
+		if (fMatchFound) {
+			/* Clear this - matched entry */
+			qdf_mem_zero(cached_pmksa,
+				     sizeof(tPmkidCacheInfo));
+			break;
+		}
+	}
+
+	if (Index == CSR_MAX_PMKID_ALLOWED && !fMatchFound) {
+		sme_debug("No such PMKSA entry exists");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* Match Found, Readjust the other entries */
+	curr_idx = pSession->curr_cache_idx;
+	if (Index < curr_idx) {
+		for (i = Index; i < (curr_idx - 1); i++) {
+			qdf_mem_copy(&pSession->PmkidCacheInfo[i],
+				     &pSession->PmkidCacheInfo[i + 1],
+				     sizeof(tPmkidCacheInfo));
+		}
+
+		pSession->curr_cache_idx--;
+		qdf_mem_zero(&pSession->PmkidCacheInfo
+			     [pSession->curr_cache_idx],
+			     sizeof(tPmkidCacheInfo));
+	} else if (Index > curr_idx) {
+		for (i = Index; i > (curr_idx); i--) {
+			qdf_mem_copy(&pSession->PmkidCacheInfo[i],
+				     &pSession->PmkidCacheInfo[i - 1],
+				     sizeof(tPmkidCacheInfo));
+		}
+
+		qdf_mem_zero(&pSession->PmkidCacheInfo
+			     [pSession->curr_cache_idx],
+			     sizeof(tPmkidCacheInfo));
+	}
+
+	/* Decrement the count since an entry has been deleted */
+	pSession->NumPmkidCache--;
+	sme_debug("PMKID at index=%d deleted, current index=%d cache count=%d",
+		Index, pSession->curr_cache_idx, pSession->NumPmkidCache);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+uint32_t csr_roam_get_num_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return pMac->roam.roamSession[sessionId].NumPmkidCache;
+}
+
+QDF_STATUS csr_roam_get_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
+				   uint32_t *pNum, tPmkidCacheInfo *pPmkidCache)
+{
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tPmkidCacheInfo *pmksa;
+	uint16_t i, j;
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!pNum || !pPmkidCache) {
+		sme_err("Either pNum or pPmkidCache is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pSession->NumPmkidCache == 0) {
+		*pNum = 0;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (*pNum < pSession->NumPmkidCache)
+		return QDF_STATUS_E_FAILURE;
+
+	if (pSession->NumPmkidCache > CSR_MAX_PMKID_ALLOWED) {
+		sme_err("NumPmkidCache :%d is more than CSR_MAX_PMKID_ALLOWED, resetting to CSR_MAX_PMKID_ALLOWED",
+			pSession->NumPmkidCache);
+		pSession->NumPmkidCache = CSR_MAX_PMKID_ALLOWED;
+	}
+
+	for (i = 0, j = 0; ((j < pSession->NumPmkidCache) &&
+		(i < CSR_MAX_PMKID_ALLOWED)); i++) {
+		/* Fill the valid entries */
+		pmksa = &pSession->PmkidCacheInfo[i];
+		if (!qdf_is_macaddr_zero(&pmksa->BSSID)) {
+			qdf_mem_copy(pPmkidCache, pmksa,
+				     sizeof(tPmkidCacheInfo));
+			pPmkidCache++;
+			j++;
+		}
+	}
+
+	*pNum = pSession->NumPmkidCache;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS csr_roam_get_wpa_rsn_req_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				       uint32_t *pLen, uint8_t *pBuf)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint32_t len;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pLen) {
+		len = *pLen;
+		*pLen = pSession->nWpaRsnReqIeLength;
+		if (pBuf) {
+			if (len >= pSession->nWpaRsnReqIeLength) {
+				qdf_mem_copy(pBuf, pSession->pWpaRsnReqIE,
+					     pSession->nWpaRsnReqIeLength);
+				status = QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_get_wpa_rsn_rsp_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				       uint32_t *pLen, uint8_t *pBuf)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint32_t len;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pLen) {
+		len = *pLen;
+		*pLen = pSession->nWpaRsnRspIeLength;
+		if (pBuf) {
+			if (len >= pSession->nWpaRsnRspIeLength) {
+				qdf_mem_copy(pBuf, pSession->pWpaRsnRspIE,
+					     pSession->nWpaRsnRspIeLength);
+				status = QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+	return status;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+QDF_STATUS csr_roam_get_wapi_req_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				    uint32_t *pLen, uint8_t *pBuf)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint32_t len;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pLen) {
+		len = *pLen;
+		*pLen = pSession->nWapiReqIeLength;
+		if (pBuf) {
+			if (len >= pSession->nWapiReqIeLength) {
+				qdf_mem_copy(pBuf, pSession->pWapiReqIE,
+					     pSession->nWapiReqIeLength);
+				status = QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_get_wapi_rsp_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				    uint32_t *pLen, uint8_t *pBuf)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint32_t len;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (pLen) {
+		len = *pLen;
+		*pLen = pSession->nWapiRspIeLength;
+		if (pBuf) {
+			if (len >= pSession->nWapiRspIeLength) {
+				qdf_mem_copy(pBuf, pSession->pWapiRspIE,
+					     pSession->nWapiRspIeLength);
+				status = QDF_STATUS_SUCCESS;
+			}
+		}
+	}
+	return status;
+}
+#endif /* FEATURE_WLAN_WAPI */
+eRoamCmdStatus csr_get_roam_complete_status(tpAniSirGlobal pMac,
+						uint32_t sessionId)
+{
+	eRoamCmdStatus retStatus = eCSR_ROAM_CONNECT_COMPLETION;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return retStatus;
+	}
+
+	if (CSR_IS_ROAMING(pSession)) {
+		retStatus = eCSR_ROAM_ROAMING_COMPLETION;
+		pSession->fRoaming = false;
+	}
+	return retStatus;
+}
+
+static QDF_STATUS csr_roam_start_wds(tpAniSirGlobal pMac, uint32_t sessionId,
+				     struct csr_roam_profile *pProfile,
+				     tSirBssDescription *pBssDesc)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	struct bss_config_param bssConfig;
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (csr_is_conn_state_ibss(pMac, sessionId)) {
+		status = csr_roam_issue_stop_bss(pMac, sessionId,
+				eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING);
+	} else if (csr_is_conn_state_connected_infra(pMac, sessionId)) {
+		/* Disassociate from the connected Infrastructure network.*/
+		status = csr_roam_issue_disassociate(pMac, sessionId,
+				eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
+						    false);
+	} else {
+		/* We don't expect Bt-AMP HDD not to disconnect the last
+		 * connection first at this time. Otherwise we need to add
+		 * code to handle the situation just like IBSS. Though for
+		 * WDS station, we need to send disassoc to PE first then
+		 * send stop_bss to PE, before we can continue.
+		 */
+
+		if (csr_is_conn_state_wds(pMac, sessionId)) {
+			QDF_ASSERT(0);
+			return QDF_STATUS_E_FAILURE;
+		}
+		qdf_mem_set(&bssConfig, sizeof(struct bss_config_param), 0);
+		/* Assume HDD provide bssid in profile */
+		qdf_copy_macaddr(&pSession->bssParams.bssid,
+				 pProfile->BSSIDs.bssid);
+		/* there is no Bss description before we start an WDS so we
+		 * need to adopt all Bss configuration parameters from the
+		 * Profile.
+		 */
+		status = csr_roam_prepare_bss_config_from_profile(pMac,
+								pProfile,
+								&bssConfig,
+								pBssDesc);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			/* Save profile for late use */
+			csr_free_roam_profile(pMac, sessionId);
+			pSession->pCurRoamProfile =
+				qdf_mem_malloc(sizeof(struct csr_roam_profile));
+			if (pSession->pCurRoamProfile != NULL) {
+				csr_roam_copy_profile(pMac,
+						      pSession->pCurRoamProfile,
+						      pProfile);
+			}
+			/* Prepare some more parameters for this WDS */
+			csr_roam_prepare_bss_params(pMac, sessionId, pProfile,
+						NULL, &bssConfig, NULL);
+			status = csr_roam_set_bss_config_cfg(pMac, sessionId,
+							pProfile, NULL,
+							&bssConfig, NULL,
+							false);
+		}
+	}
+
+	return status;
+}
+
+/**
+ * csr_add_supported_5Ghz_channels()- Add valid 5Ghz channels
+ * in Join req.
+ * @mac_ctx: pointer to global mac structure
+ * @chan_list: Pointer to channel list buffer to populate
+ * @num_chan: Pointer to number of channels value to update
+ * @supp_chan_ie: Boolean to check if we need to populate as IE
+ *
+ * This function is called to update valid 5Ghz channels
+ * in Join req. If @supp_chan_ie is true, supported channels IE
+ * format[chan num 1, num of channels 1, chan num 2, num of
+ * channels 2, ..] is populated. Else, @chan_list would be a list
+ * of supported channels[chan num 1, chan num 2..]
+ *
+ * Return: void
+ */
+static void csr_add_supported_5Ghz_channels(tpAniSirGlobal mac_ctx,
+						uint8_t *chan_list,
+						uint8_t *num_chnl,
+						bool supp_chan_ie)
+{
+	uint16_t i, j;
+	uint32_t size = 0;
+
+	if (!chan_list) {
+		sme_err("chan_list buffer NULL");
+		return;
+	}
+
+	size = sizeof(mac_ctx->roam.validChannelList);
+	if (QDF_IS_STATUS_SUCCESS
+		(csr_get_cfg_valid_channels(mac_ctx,
+		(uint8_t *) mac_ctx->roam.validChannelList,
+				&size))) {
+		for (i = 0, j = 0; i < size; i++) {
+			/* Only add 5ghz channels.*/
+			if (WLAN_REG_IS_5GHZ_CH
+					(mac_ctx->roam.validChannelList[i])) {
+				chan_list[j]
+					= mac_ctx->roam.validChannelList[i];
+				j++;
+
+				if (supp_chan_ie) {
+					chan_list[j] = 1;
+					j++;
+				}
+			}
+		}
+		*num_chnl = (uint8_t)j;
+	} else {
+		sme_err("can not find any valid channel");
+		*num_chnl = 0;
+	}
+}
+
+/**
+ * csr_set_ldpc_exception() - to set allow any LDPC exception permitted
+ * @mac_ctx: Pointer to mac context
+ * @session: Pointer to SME/CSR session
+ * @channel: Given channel number where connection will go
+ * @usr_cfg_rx_ldpc: User provided RX LDPC setting
+ *
+ * This API will check if hardware allows LDPC to be enabled for provided
+ * channel and user has enabled the RX LDPC selection
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS csr_set_ldpc_exception(tpAniSirGlobal mac_ctx,
+			struct csr_roam_session *session, uint8_t channel,
+			bool usr_cfg_rx_ldpc)
+{
+	if (!mac_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"mac_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (!session) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"session is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (usr_cfg_rx_ldpc && wma_is_rx_ldpc_supported_for_channel(channel)) {
+		session->htConfig.ht_rx_ldpc = 1;
+		session->vht_config.ldpc_coding = 1;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"LDPC enable for chnl[%d]", channel);
+	} else {
+		session->htConfig.ht_rx_ldpc = 0;
+		session->vht_config.ldpc_coding = 0;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"LDPC disable for chnl[%d]", channel);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * csr_is_mfpc_capable() - is MFPC capable
+ * @ies: AP information element
+ *
+ * Return: true if MFPC capable, false otherwise
+ */
+bool csr_is_mfpc_capable(struct sDot11fIERSN *rsn)
+{
+	bool mfpc_capable = false;
+
+	if (rsn && rsn->present &&
+	    ((rsn->RSN_Cap[0] >> 7) & 0x01))
+		mfpc_capable = true;
+
+	return mfpc_capable;
+}
+
+/**
+ * csr_set_mgmt_enc_type() - set mgmt enc type for PMF
+ * @profile: roam profile
+ * @ies: AP ie
+ * @csr_join_req: csr join req
+ *
+ * Return: void
+ */
+static void csr_set_mgmt_enc_type(struct csr_roam_profile *profile,
+				  tDot11fBeaconIEs *ies,
+				  tSirSmeJoinReq *csr_join_req)
+{
+	sme_debug("mgmt encryption type %d MFPe %d MFPr %d",
+		 profile->mgmt_encryption_type,
+		 profile->MFPEnabled, profile->MFPRequired);
+
+	if (profile->MFPEnabled)
+		csr_join_req->MgmtEncryptionType =
+					profile->mgmt_encryption_type;
+	else
+		csr_join_req->MgmtEncryptionType = eSIR_ED_NONE;
+
+	if (profile->MFPEnabled &&
+	   !(profile->MFPRequired) &&
+	   !csr_is_mfpc_capable(&ies->RSN))
+		csr_join_req->MgmtEncryptionType = eSIR_ED_NONE;
+}
+#else
+static inline void csr_set_mgmt_enc_type(struct csr_roam_profile *profile,
+					 tDot11fBeaconIEs *pIes,
+					 tSirSmeJoinReq *csr_join_req)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_FILS_SK
+/*
+ * csr_update_fils_connection_info: Copy fils connection info to join request
+ * @profile: pointer to profile
+ * @csr_join_req: csr join request
+ *
+ * Return: None
+ */
+static void csr_update_fils_connection_info(struct csr_roam_profile *profile,
+					    tSirSmeJoinReq *csr_join_req)
+{
+	if (!profile->fils_con_info)
+		return;
+
+	if (profile->fils_con_info->is_fils_connection) {
+		qdf_mem_copy(&csr_join_req->fils_con_info,
+			     profile->fils_con_info,
+			     sizeof(struct cds_fils_connection_info));
+	} else {
+		qdf_mem_zero(&csr_join_req->fils_con_info,
+			     sizeof(struct cds_fils_connection_info));
+	}
+}
+#else
+static void csr_update_fils_connection_info(struct csr_roam_profile *profile,
+					    tSirSmeJoinReq *csr_join_req)
+{ }
+#endif
+
+#ifdef WLAN_FEATURE_SAE
+/*
+ * csr_update_sae_config: Copy SAE info to join request
+ * @profile: pointer to profile
+ * @csr_join_req: csr join request
+ *
+ * Return: None
+ */
+static void csr_update_sae_config(tSirSmeJoinReq *csr_join_req,
+	tpAniSirGlobal mac, struct csr_roam_session *session)
+{
+	tPmkidCacheInfo pmkid_cache;
+	uint32_t index;
+
+	qdf_mem_copy(pmkid_cache.BSSID.bytes,
+		csr_join_req->bssDescription.bssId, QDF_MAC_ADDR_SIZE);
+
+	csr_join_req->sae_pmk_cached =
+	       csr_lookup_pmkid_using_bssid(mac, session, &pmkid_cache, &index);
+
+	sme_debug("pmk_cached %d for BSSID=" MAC_ADDRESS_STR,
+		csr_join_req->sae_pmk_cached,
+		MAC_ADDR_ARRAY(csr_join_req->bssDescription.bssId));
+}
+#else
+static void csr_update_sae_config(tSirSmeJoinReq *csr_join_req,
+	tpAniSirGlobal mac, struct csr_roam_session *session)
+{ }
+#endif
+
+/**
+ * csr_get_nss_supported_by_sta_and_ap() - finds out nss from session
+ * and beacon from AP
+ * @vht_caps: VHT capabilities
+ * @ht_caps: HT capabilities
+ * @dot11_mode: dot11 mode
+ *
+ * Return: number of nss advertised by beacon
+ */
+static uint8_t csr_get_nss_supported_by_sta_and_ap(tDot11fIEVHTCaps *vht_caps,
+						   tDot11fIEHTCaps *ht_caps,
+						   uint32_t dot11_mode)
+{
+	bool vht_capability, ht_capability;
+
+	vht_capability = IS_DOT11_MODE_VHT(dot11_mode);
+	ht_capability = IS_DOT11_MODE_HT(dot11_mode);
+
+	if (vht_capability && vht_caps->present) {
+		if ((vht_caps->rxMCSMap & 0xC0) != 0xC0)
+			return 4;
+
+		if ((vht_caps->rxMCSMap & 0x30) != 0x30)
+			return 3;
+
+		if ((vht_caps->rxMCSMap & 0x0C) != 0x0C)
+			return 2;
+	} else if (ht_capability && ht_caps->present) {
+		if (ht_caps->supportedMCSSet[3])
+			return 4;
+
+		if (ht_caps->supportedMCSSet[2])
+			return 3;
+
+		if (ht_caps->supportedMCSSet[1])
+			return 2;
+	}
+
+	return 1;
+}
+
+/**
+ * csr_dump_vendor_ies() - Dumps all the vendor IEs
+ * @ie:         ie buffer
+ * @ie_len:     length of ie buffer
+ *
+ * This function dumps the vendor IEs present in the AP's IE buffer
+ *
+ * Return: none
+ */
+static
+void csr_dump_vendor_ies(uint8_t *ie, uint16_t ie_len)
+{
+	int32_t left = ie_len;
+	uint8_t *ptr = ie;
+	uint8_t elem_id, elem_len;
+
+	while (left >= 2) {
+		elem_id  = ptr[0];
+		elem_len = ptr[1];
+		left -= 2;
+		if (elem_len > left) {
+			sme_err("Invalid IEs eid: %d elem_len: %d left: %d",
+				elem_id, elem_len, left);
+			return;
+		}
+		if (elem_id == SIR_MAC_EID_VENDOR) {
+			sme_debug("Dumping Vendor IE of len %d", elem_len);
+			QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+					   QDF_TRACE_LEVEL_DEBUG,
+					   &ptr[2], elem_len);
+		}
+		left -= elem_len;
+		ptr += (elem_len + 2);
+	}
+}
+
+/**
+ * csr_check_vendor_ap_3_present() - Check if Vendor AP 3 is present
+ * @mac_ctx: Pointer to Global MAC structure
+ * @ie: Pointer to starting IE in Beacon/Probe Response
+ * @ie_len: Length of all IEs combined
+ *
+ * For Vendor AP 3, the condition is that Vendor AP 3 IE should be present
+ * and Vendor AP 4 IE should not be present.
+ * If Vendor AP 3 IE is present and Vendor AP 4 IE is also present,
+ * return false, else return true.
+ *
+ * Return: true or false
+ */
+static bool
+csr_check_vendor_ap_3_present(tpAniSirGlobal mac_ctx, uint8_t *ie,
+			      uint16_t ie_len)
+{
+	bool ret = true;
+
+	if ((wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_VENDOR_AP_3_OUI,
+	    SIR_MAC_VENDOR_AP_3_OUI_LEN, ie, ie_len)) &&
+	    (wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_VENDOR_AP_4_OUI,
+	    SIR_MAC_VENDOR_AP_4_OUI_LEN, ie, ie_len))) {
+		sme_debug("Vendor OUI 3 and Vendor OUI 4 found");
+		ret = false;
+	}
+
+	return ret;
+}
+
+/**
+ * csr_enable_twt() - Check if its allowed to enable twt for this session
+ * @ie: pointer to beacon/probe resp ie's
+ *
+ * TWT is allowed only if device is in 11ax mode or if QCN ie present.
+ *
+ * Return: true or flase
+ */
+static bool csr_enable_twt(tDot11fBeaconIEs *ie)
+{
+	if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX))
+		return true;
+
+	if (!ie) {
+		sme_debug("Beacon ie buffer is null");
+		return false;
+	}
+
+	return ie->QCN_IE.present;
+}
+
+/**
+ * csr_enable_uapsd() - Used to disable uapsd if both twt and uapsd is enabled
+ * @mac_ctx: pointer to global mac structure
+ * @ie: pointer to beacon/probe resp ie's
+ *
+ * Return: true or flase
+ */
+static bool csr_enable_uapsd(tpAniSirGlobal mac_ctx, tDot11fBeaconIEs *ie)
+{
+	uint32_t value = 0;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	/* In non-HE case, TWT is enabled only for Q2Q.
+	 * So keed uAPSD enabled for non-Q2Q in this non-HE case.
+	 */
+	if (!csr_enable_twt(ie))
+		return true;
+
+	if (!ie) {
+		sme_debug("Beacon ie buffer is null");
+		return true;
+	}
+
+	CFG_GET_INT(status, mac_ctx, WNI_CFG_TWT_REQUESTOR, value);
+	if ((value || IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) &&
+	    ie->he_cap.twt_responder) {
+		sme_debug("twt supported, disable uapsd");
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * The communication between HDD and LIM is thru mailbox (MB).
+ * Both sides will access the data structure "tSirSmeJoinReq".
+ * The rule is, while the components of "tSirSmeJoinReq" can be accessed in the
+ * regular way like tSirSmeJoinReq.assocType, this guideline stops at component
+ * tSirRSNie;
+ * any acces to the components after tSirRSNie is forbidden because the space
+ * from tSirRSNie is squeezed with the component "tSirBssDescription" and since
+ * the size of actual 'tSirBssDescription' varies, the receiving side should
+ * keep in mind not to access the components DIRECTLY after tSirRSNie.
+ */
+QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+				 tSirBssDescription *pBssDescription,
+				 struct csr_roam_profile *pProfile,
+				 tDot11fBeaconIEs *pIes, uint16_t messageType)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t acm_mask = 0, uapsd_mask;
+	uint16_t msgLen, ieLen;
+	tSirMacRateSet OpRateSet;
+	tSirMacRateSet ExRateSet;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	uint32_t dwTmp, ucDot11Mode = 0;
+	uint8_t *wpaRsnIE = NULL;
+	uint8_t txBFCsnValue = 0;
+	tSirSmeJoinReq *csr_join_req;
+	tSirMacCapabilityInfo *pAP_capabilityInfo;
+	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];
+	uint8_t ese_config = 0, channel_id;
+	tpCsrNeighborRoamControlInfo neigh_roam_info;
+	uint32_t value = 0, value1 = 0;
+	QDF_STATUS packetdump_timer_status;
+	bool is_vendor_ap_present;
+	struct vdev_type_nss *vdev_type_nss;
+	struct action_oui_search_attr vendor_ap_search_attr;
+	tDot11fIEVHTCaps *vht_caps = NULL;
+	bool bvalue = 0;
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* To satisfy klockworks */
+	if (NULL == pBssDescription) {
+		sme_err(" pBssDescription is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	neigh_roam_info = &pMac->roam.neighborRoamInfo[sessionId];
+	if ((eWNI_SME_REASSOC_REQ == messageType) ||
+		WLAN_REG_IS_5GHZ_CH(pBssDescription->channelId) ||
+		(abs(pBssDescription->rssi) <
+		 (neigh_roam_info->cfgParams.neighborLookupThreshold -
+		  neigh_roam_info->cfgParams.hi_rssi_scan_rssi_delta))) {
+		pSession->disable_hi_rssi = true;
+		sme_debug(
+			"Disabling HI_RSSI feature, AP channel=%d, rssi=%d",
+			pBssDescription->channelId, pBssDescription->rssi);
+	} else {
+		pSession->disable_hi_rssi = false;
+	}
+
+	/*
+	 * When STA's join req times out on current BSS, SME issues next BSS
+	 * internally without checking HW mode for new channel.
+	 *
+	 * For example, STA tries to connect SSID="abc",
+	 * BSSID="a1:a2:a3:a4:a5:a6", channel=36 and lets say it fails. It
+	 * should try few more times to same BSSID and after that it will try
+	 * next bss. Lets say next BSS it found has, SSID="abc",
+	 * BSSID="b1:b2:b3:b4:b5:b6", channel=1 then it needs to check whether
+	 * hardware mode change is required for channel=1. If driver fails in
+	 * checking hardware mode then following check will prevent the bad
+	 * situation.
+	 */
+	channel_id = pBssDescription->channelId;
+	if (!policy_mgr_is_hwmode_set_for_given_chnl(pMac->psoc, channel_id)) {
+		sme_err("HW mode is not properly set for channel %d",
+			channel_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	do {
+		pSession->joinFailStatusCode.statusCode = eSIR_SME_SUCCESS;
+		pSession->joinFailStatusCode.reasonCode = 0;
+		qdf_mem_copy(&pSession->joinFailStatusCode.bssId,
+		       &pBssDescription->bssId, sizeof(tSirMacAddr));
+		/*
+		 * the tSirSmeJoinReq which includes a single
+		 * bssDescription. it includes a single uint32_t for the
+		 * IE fields, but the length field in the bssDescription
+		 * needs to be interpreted to determine length of IE fields
+		 * So, take the size of the tSirSmeJoinReq, subtract  size of
+		 * bssDescription, add the number of bytes indicated by the
+		 * length field of the bssDescription, add the size of length
+		 * field because it not included in the length field.
+		 */
+		msgLen = sizeof(tSirSmeJoinReq) - sizeof(*pBssDescription) +
+				pBssDescription->length +
+				sizeof(pBssDescription->length) +
+				/*
+				 * add in the size of the WPA IE that
+				 * we may build.
+				 */
+				sizeof(tCsrWpaIe) + sizeof(tCsrWpaAuthIe) +
+				sizeof(uint16_t);
+		csr_join_req = qdf_mem_malloc(msgLen);
+		if (NULL == csr_join_req)
+			status = QDF_STATUS_E_NOMEM;
+		else
+			status = QDF_STATUS_SUCCESS;
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+
+		wpaRsnIE = qdf_mem_malloc(DOT11F_IE_RSN_MAX_LEN);
+		if (NULL == wpaRsnIE)
+			status = QDF_STATUS_E_NOMEM;
+
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+
+		csr_join_req->messageType = messageType;
+		csr_join_req->length = msgLen;
+		csr_join_req->sessionId = (uint8_t) sessionId;
+		csr_join_req->transactionId = 0;
+		if (pIes->SSID.present && pIes->SSID.num_ssid) {
+			csr_join_req->ssId.length = pIes->SSID.num_ssid;
+			qdf_mem_copy(&csr_join_req->ssId.ssId, pIes->SSID.ssid,
+				     pIes->SSID.num_ssid);
+		} else
+			csr_join_req->ssId.length = 0;
+		qdf_mem_copy(&csr_join_req->selfMacAddr, &pSession->selfMacAddr,
+			     sizeof(tSirMacAddr));
+		sme_err("Connecting to ssid:%.*s bssid: "MAC_ADDRESS_STR" rssi: %d channel: %d country_code: %c%c",
+			pIes->SSID.num_ssid, pIes->SSID.ssid,
+			MAC_ADDR_ARRAY(pBssDescription->bssId),
+			pBssDescription->rssi, pBssDescription->channelId,
+			pMac->scan.countryCodeCurrent[0],
+			pMac->scan.countryCodeCurrent[1]);
+		/* bsstype */
+		dwTmp = csr_translate_bsstype_to_mac_type
+						(pProfile->BSSType);
+		csr_join_req->bsstype = dwTmp;
+		/* dot11mode */
+		ucDot11Mode =
+			csr_translate_to_wni_cfg_dot11_mode(pMac,
+							    pSession->bssParams.
+							    uCfgDot11Mode);
+		if (pBssDescription->channelId <= 14 &&
+		    !pMac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band &&
+		    WNI_CFG_DOT11_MODE_11AC == ucDot11Mode) {
+			/* Need to disable VHT operation in 2.4 GHz band */
+			ucDot11Mode = WNI_CFG_DOT11_MODE_11N;
+		}
+
+		if (IS_5G_CH(pBssDescription->channelId))
+			vdev_type_nss = &pMac->vdev_type_nss_5g;
+		else
+			vdev_type_nss = &pMac->vdev_type_nss_2g;
+		if (pSession->pCurRoamProfile->csrPersona ==
+		    QDF_P2P_CLIENT_MODE)
+			pSession->vdev_nss = vdev_type_nss->p2p_cli;
+		else
+			pSession->vdev_nss = vdev_type_nss->sta;
+		pSession->nss = pSession->vdev_nss;
+
+		if (pSession->nss > csr_get_nss_supported_by_sta_and_ap(
+						&pIes->VHTCaps,
+						&pIes->HTCaps, ucDot11Mode)) {
+			pSession->nss = csr_get_nss_supported_by_sta_and_ap(
+						&pIes->VHTCaps, &pIes->HTCaps,
+						ucDot11Mode);
+			pSession->vdev_nss = pSession->nss;
+		}
+
+		if (!pMac->mlme_cfg->vht_caps.vht_cap_info.enable2x2)
+			pSession->nss = 1;
+
+		if (pSession->nss == 1)
+			pSession->supported_nss_1x1 = true;
+
+		ieLen = csr_get_ielen_from_bss_description(pBssDescription);
+
+		/* Dump the Vendor Specific IEs*/
+		csr_dump_vendor_ies((uint8_t *)&pBssDescription->ieFields[0],
+				    ieLen);
+
+		/* Fill the Vendor AP search params */
+		vendor_ap_search_attr.ie_data =
+				(uint8_t *)&pBssDescription->ieFields[0];
+		vendor_ap_search_attr.ie_length = ieLen;
+		vendor_ap_search_attr.mac_addr = &pBssDescription->bssId[0];
+		vendor_ap_search_attr.nss = csr_get_nss_supported_by_sta_and_ap(
+						&pIes->VHTCaps, &pIes->HTCaps,
+						ucDot11Mode);
+		vendor_ap_search_attr.ht_cap = pIes->HTCaps.present;
+		vendor_ap_search_attr.vht_cap = pIes->VHTCaps.present;
+		vendor_ap_search_attr.enable_2g =
+					IS_24G_CH(pBssDescription->channelId);
+		vendor_ap_search_attr.enable_5g =
+					IS_5G_CH(pBssDescription->channelId);
+
+		is_vendor_ap_present =
+				ucfg_action_oui_search(pMac->psoc,
+						       &vendor_ap_search_attr,
+						       ACTION_OUI_CONNECT_1X1);
+
+		if (is_vendor_ap_present) {
+			is_vendor_ap_present = csr_check_vendor_ap_3_present(
+						pMac, (uint8_t *)pIes, ieLen);
+		}
+
+		/*
+		 * For WMI_ACTION_OUI_CONNECT_1x1_WITH_1_CHAIN, the host
+		 * sends the NSS as 1 to the FW and the FW then decides
+		 * after receiving the first beacon after connection to
+		 * switch to 1 Tx/Rx Chain.
+		 */
+
+		if (!is_vendor_ap_present) {
+			is_vendor_ap_present =
+				ucfg_action_oui_search(pMac->psoc,
+					&vendor_ap_search_attr,
+					ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN);
+			if (is_vendor_ap_present)
+				sme_debug("1x1 with 1 Chain AP");
+		}
+
+		if (pMac->roam.configParam.is_force_1x1 &&
+		    pMac->lteCoexAntShare &&
+		    is_vendor_ap_present) {
+			pSession->supported_nss_1x1 = true;
+			pSession->vdev_nss = 1;
+			pSession->nss = 1;
+			pSession->nss_forced_1x1 = true;
+			sme_debug("For special ap, NSS: %d", pSession->nss);
+		}
+
+		/*
+		 * If CCK WAR is set for current AP, update to firmware via
+		 * WMI_VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM
+		 */
+		is_vendor_ap_present =
+				ucfg_action_oui_search(pMac->psoc,
+						       &vendor_ap_search_attr,
+						       ACTION_OUI_CCKM_1X1);
+		if (is_vendor_ap_present) {
+			sme_debug("vdev: %d WMI_VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM 1",
+				 pSession->sessionId);
+			wma_cli_set_command(
+				pSession->sessionId,
+				(int)WMI_VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM, 1,
+				VDEV_CMD);
+		}
+
+		/*
+		 * If Switch to 11N WAR is set for current AP, change dot11
+		 * mode to 11N.
+		 */
+		is_vendor_ap_present =
+			ucfg_action_oui_search(pMac->psoc,
+					       &vendor_ap_search_attr,
+					       ACTION_OUI_SWITCH_TO_11N_MODE);
+		if (pMac->roam.configParam.is_force_1x1 &&
+		    pMac->lteCoexAntShare &&
+		    is_vendor_ap_present &&
+		    (ucDot11Mode == WNI_CFG_DOT11_MODE_ALL ||
+		     ucDot11Mode == WNI_CFG_DOT11_MODE_11AC ||
+		     ucDot11Mode == WNI_CFG_DOT11_MODE_11AC_ONLY))
+			ucDot11Mode = WNI_CFG_DOT11_MODE_11N;
+
+		csr_join_req->supported_nss_1x1 = pSession->supported_nss_1x1;
+		csr_join_req->vdev_nss = pSession->vdev_nss;
+		csr_join_req->nss = pSession->nss;
+		csr_join_req->nss_forced_1x1 = pSession->nss_forced_1x1;
+		csr_join_req->dot11mode = (uint8_t) ucDot11Mode;
+		sme_debug("dot11mode=%d, uCfgDot11Mode=%d nss=%d",
+			  csr_join_req->dot11mode,
+			  pSession->bssParams.uCfgDot11Mode,
+			  csr_join_req->nss);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+		csr_join_req->cc_switch_mode =
+			pMac->roam.configParam.cc_switch_mode;
+#endif
+		csr_join_req->staPersona = (uint8_t) pProfile->csrPersona;
+		csr_join_req->wps_registration = pProfile->bWPSAssociation;
+		csr_join_req->cbMode = (uint8_t) pSession->bssParams.cbMode;
+		csr_join_req->force_24ghz_in_ht20 =
+			pProfile->force_24ghz_in_ht20;
+		sme_debug("CSR PERSONA: %d CSR CbMode: %d force 24gh ht20 %d",
+			  pProfile->csrPersona, pSession->bssParams.cbMode,
+			  csr_join_req->force_24ghz_in_ht20);
+		pSession->uapsd_mask = pProfile->uapsd_mask;
+		status =
+			csr_get_rate_set(pMac, pProfile,
+					 (eCsrPhyMode) pProfile->phyMode,
+					 pBssDescription, pIes, &OpRateSet,
+					 &ExRateSet);
+		ps_param->uapsd_per_ac_bit_mask =
+			pProfile->uapsd_mask;
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			/* OperationalRateSet */
+			if (OpRateSet.numRates) {
+				csr_join_req->operationalRateSet.numRates =
+					OpRateSet.numRates;
+				qdf_mem_copy(&csr_join_req->operationalRateSet.
+						rate, OpRateSet.rate,
+						OpRateSet.numRates);
+			} else
+				csr_join_req->operationalRateSet.numRates = 0;
+
+			/* ExtendedRateSet */
+			if (ExRateSet.numRates) {
+				csr_join_req->extendedRateSet.numRates =
+					ExRateSet.numRates;
+				qdf_mem_copy(&csr_join_req->extendedRateSet.
+						rate, ExRateSet.rate,
+						ExRateSet.numRates);
+			} else
+				csr_join_req->extendedRateSet.numRates = 0;
+		} else {
+			csr_join_req->operationalRateSet.numRates = 0;
+			csr_join_req->extendedRateSet.numRates = 0;
+		}
+		/* rsnIE */
+		if (csr_is_profile_wpa(pProfile)) {
+			/* Insert the Wpa IE into the join request */
+			ieLen =
+				csr_retrieve_wpa_ie(pMac, pProfile,
+						pBssDescription, pIes,
+						(tCsrWpaIe *) (wpaRsnIE));
+		} else if (csr_is_profile_rsn(pProfile)) {
+			/* Insert the RSN IE into the join request */
+			ieLen =
+				csr_retrieve_rsn_ie(pMac, sessionId, pProfile,
+						    pBssDescription, pIes,
+						    (tCsrRSNIe *) (wpaRsnIE));
+			csr_join_req->force_rsne_override =
+						pProfile->force_rsne_override;
+		}
+#ifdef FEATURE_WLAN_WAPI
+		else if (csr_is_profile_wapi(pProfile)) {
+			/* Insert the WAPI IE into the join request */
+			ieLen =
+				csr_retrieve_wapi_ie(pMac, sessionId, pProfile,
+						     pBssDescription, pIes,
+						     (tCsrWapiIe *) (wpaRsnIE));
+		}
+#endif /* FEATURE_WLAN_WAPI */
+		else
+			ieLen = 0;
+		/* remember the IE for future use */
+		if (ieLen) {
+			if (ieLen > DOT11F_IE_RSN_MAX_LEN) {
+				sme_err("WPA RSN IE length :%d is more than DOT11F_IE_RSN_MAX_LEN, resetting to %d",
+					ieLen, DOT11F_IE_RSN_MAX_LEN);
+				ieLen = DOT11F_IE_RSN_MAX_LEN;
+			}
+#ifdef FEATURE_WLAN_WAPI
+			if (csr_is_profile_wapi(pProfile)) {
+				/* Check whether we need to allocate more mem */
+				if (ieLen > pSession->nWapiReqIeLength) {
+					if (pSession->pWapiReqIE
+					    && pSession->nWapiReqIeLength) {
+						qdf_mem_free(pSession->
+							     pWapiReqIE);
+					}
+					pSession->pWapiReqIE =
+						qdf_mem_malloc(ieLen);
+					if (NULL == pSession->pWapiReqIE)
+						status = QDF_STATUS_E_NOMEM;
+					else
+						status = QDF_STATUS_SUCCESS;
+					if (!QDF_IS_STATUS_SUCCESS(status))
+						break;
+				}
+				pSession->nWapiReqIeLength = ieLen;
+				qdf_mem_copy(pSession->pWapiReqIE, wpaRsnIE,
+					     ieLen);
+				csr_join_req->rsnIE.length = ieLen;
+				qdf_mem_copy(&csr_join_req->rsnIE.rsnIEdata,
+						 wpaRsnIE, ieLen);
+			} else  /* should be WPA/WPA2 otherwise */
+#endif /* FEATURE_WLAN_WAPI */
+			{
+				/* Check whether we need to allocate more mem */
+				if (ieLen > pSession->nWpaRsnReqIeLength) {
+					if (pSession->pWpaRsnReqIE
+					    && pSession->nWpaRsnReqIeLength) {
+						qdf_mem_free(pSession->
+							     pWpaRsnReqIE);
+					}
+					pSession->pWpaRsnReqIE =
+						qdf_mem_malloc(ieLen);
+					if (NULL == pSession->pWpaRsnReqIE)
+						status = QDF_STATUS_E_NOMEM;
+					else
+						status = QDF_STATUS_SUCCESS;
+					if (!QDF_IS_STATUS_SUCCESS(status))
+						break;
+				}
+				pSession->nWpaRsnReqIeLength = ieLen;
+				qdf_mem_copy(pSession->pWpaRsnReqIE, wpaRsnIE,
+					     ieLen);
+				csr_join_req->rsnIE.length = ieLen;
+				qdf_mem_copy(&csr_join_req->rsnIE.rsnIEdata,
+						 wpaRsnIE, ieLen);
+			}
+		} else {
+			/* free whatever old info */
+			pSession->nWpaRsnReqIeLength = 0;
+			if (pSession->pWpaRsnReqIE) {
+				qdf_mem_free(pSession->pWpaRsnReqIE);
+				pSession->pWpaRsnReqIE = NULL;
+			}
+#ifdef FEATURE_WLAN_WAPI
+			pSession->nWapiReqIeLength = 0;
+			if (pSession->pWapiReqIE) {
+				qdf_mem_free(pSession->pWapiReqIE);
+				pSession->pWapiReqIE = NULL;
+			}
+#endif /* FEATURE_WLAN_WAPI */
+			csr_join_req->rsnIE.length = 0;
+		}
+#ifdef FEATURE_WLAN_ESE
+		if (eWNI_SME_JOIN_REQ == messageType)
+			csr_join_req->cckmIE.length = 0;
+		else if (eWNI_SME_REASSOC_REQ == messageType) {
+			/* cckmIE */
+			if (csr_is_profile_ese(pProfile)) {
+				/* Insert the CCKM IE into the join request */
+				ieLen = pSession->suppCckmIeInfo.cckmIeLen;
+				qdf_mem_copy((void *)(wpaRsnIE),
+						pSession->suppCckmIeInfo.cckmIe,
+						ieLen);
+			} else
+				ieLen = 0;
+			/*
+			 * If present, copy the IE into the
+			 * eWNI_SME_REASSOC_REQ message buffer
+			 */
+			if (ieLen) {
+				/*
+				 * Copy the CCKM IE over from the temp
+				 * buffer (wpaRsnIE)
+				 */
+				csr_join_req->cckmIE.length = ieLen;
+				qdf_mem_copy(&csr_join_req->cckmIE.cckmIEdata,
+						wpaRsnIE, ieLen);
+			} else
+				csr_join_req->cckmIE.length = 0;
+		}
+#endif /* FEATURE_WLAN_ESE */
+		/* addIEScan */
+		if (pProfile->nAddIEScanLength && pProfile->pAddIEScan) {
+			ieLen = pProfile->nAddIEScanLength;
+			if (ieLen > pSession->nAddIEScanLength) {
+				if (pSession->pAddIEScan
+					&& pSession->nAddIEScanLength) {
+					qdf_mem_free(pSession->pAddIEScan);
+				}
+				pSession->pAddIEScan = qdf_mem_malloc(ieLen);
+				if (NULL == pSession->pAddIEScan)
+					status = QDF_STATUS_E_NOMEM;
+				else
+					status = QDF_STATUS_SUCCESS;
+				if (!QDF_IS_STATUS_SUCCESS(status))
+					break;
+			}
+			pSession->nAddIEScanLength = ieLen;
+			qdf_mem_copy(pSession->pAddIEScan, pProfile->pAddIEScan,
+					ieLen);
+			csr_join_req->addIEScan.length = ieLen;
+			qdf_mem_copy(&csr_join_req->addIEScan.addIEdata,
+					pProfile->pAddIEScan, ieLen);
+		} else {
+			pSession->nAddIEScanLength = 0;
+			if (pSession->pAddIEScan) {
+				qdf_mem_free(pSession->pAddIEScan);
+				pSession->pAddIEScan = NULL;
+			}
+			csr_join_req->addIEScan.length = 0;
+		}
+		/* addIEAssoc */
+		if (pProfile->nAddIEAssocLength && pProfile->pAddIEAssoc) {
+			ieLen = pProfile->nAddIEAssocLength;
+			if (ieLen > pSession->nAddIEAssocLength) {
+				if (pSession->pAddIEAssoc
+				    && pSession->nAddIEAssocLength) {
+					qdf_mem_free(pSession->pAddIEAssoc);
+				}
+				pSession->pAddIEAssoc = qdf_mem_malloc(ieLen);
+				if (NULL == pSession->pAddIEAssoc)
+					status = QDF_STATUS_E_NOMEM;
+				else
+					status = QDF_STATUS_SUCCESS;
+				if (!QDF_IS_STATUS_SUCCESS(status))
+					break;
+			}
+			pSession->nAddIEAssocLength = ieLen;
+			qdf_mem_copy(pSession->pAddIEAssoc,
+				     pProfile->pAddIEAssoc, ieLen);
+			csr_join_req->addIEAssoc.length = ieLen;
+			qdf_mem_copy(&csr_join_req->addIEAssoc.addIEdata,
+					 pProfile->pAddIEAssoc, ieLen);
+		} else {
+			pSession->nAddIEAssocLength = 0;
+			if (pSession->pAddIEAssoc) {
+				qdf_mem_free(pSession->pAddIEAssoc);
+				pSession->pAddIEAssoc = NULL;
+			}
+			csr_join_req->addIEAssoc.length = 0;
+		}
+
+		if (eWNI_SME_REASSOC_REQ == messageType) {
+			/* Unmask any AC in reassoc that is ACM-set */
+			uapsd_mask = (uint8_t) pProfile->uapsd_mask;
+			if (uapsd_mask && (NULL != pBssDescription)) {
+				if (CSR_IS_QOS_BSS(pIes)
+						&& CSR_IS_UAPSD_BSS(pIes))
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+					acm_mask =
+						sme_qos_get_acm_mask(pMac,
+								pBssDescription,
+								pIes);
+#endif /* WLAN_MDM_CODE_REDUCTION_OPT */
+				else
+					uapsd_mask = 0;
+			}
+		}
+
+		if (!CSR_IS_11n_ALLOWED(pProfile->negotiatedUCEncryptionType))
+			csr_join_req->he_with_wep_tkip =
+				pMac->roam.configParam.wep_tkip_in_he;
+
+		csr_join_req->UCEncryptionType =
+				csr_translate_encrypt_type_to_ed_type
+					(pProfile->negotiatedUCEncryptionType);
+
+		csr_join_req->MCEncryptionType =
+				csr_translate_encrypt_type_to_ed_type
+					(pProfile->negotiatedMCEncryptionType);
+	csr_set_mgmt_enc_type(pProfile, pIes, csr_join_req);
+#ifdef FEATURE_WLAN_ESE
+		ese_config =  pMac->roam.configParam.isEseIniFeatureEnabled;
+#endif
+		pProfile->MDID.mdiePresent = pBssDescription->mdiePresent;
+		if (csr_is_profile11r(pMac, pProfile)
+#ifdef FEATURE_WLAN_ESE
+		    &&
+		    !((pProfile->negotiatedAuthType ==
+		       eCSR_AUTH_TYPE_OPEN_SYSTEM) && (pIes->ESEVersion.present)
+		      && (ese_config))
+#endif
+			)
+			csr_join_req->is11Rconnection = true;
+		else
+			csr_join_req->is11Rconnection = false;
+#ifdef FEATURE_WLAN_ESE
+		if (true == ese_config)
+			csr_join_req->isESEFeatureIniEnabled = true;
+		else
+			csr_join_req->isESEFeatureIniEnabled = false;
+
+		/* A profile can not be both ESE and 11R. But an 802.11R AP
+		 * may be advertising support for ESE as well. So if we are
+		 * associating Open or explicitly ESE then we will get ESE.
+		 * If we are associating explicitly 11R only then we will get
+		 * 11R.
+		 */
+		if ((csr_is_profile_ese(pProfile) ||
+			((pIes->ESEVersion.present) &&
+			(pProfile->negotiatedAuthType ==
+				eCSR_AUTH_TYPE_OPEN_SYSTEM)))
+			&& (ese_config))
+			csr_join_req->isESEconnection = true;
+		else
+			csr_join_req->isESEconnection = false;
+
+		if (eWNI_SME_JOIN_REQ == messageType) {
+			tESETspecInfo eseTspec;
+			/*
+			 * ESE-Tspec IEs in the ASSOC request is presently not
+			 * supported. so nullify the TSPEC parameters
+			 */
+			qdf_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
+			qdf_mem_copy(&csr_join_req->eseTspecInfo,
+					&eseTspec, sizeof(tESETspecInfo));
+		} else if (eWNI_SME_REASSOC_REQ == messageType) {
+			if ((csr_is_profile_ese(pProfile) ||
+				((pIes->ESEVersion.present)
+				&& (pProfile->negotiatedAuthType ==
+					eCSR_AUTH_TYPE_OPEN_SYSTEM))) &&
+				(ese_config)) {
+				tESETspecInfo eseTspec;
+
+				qdf_mem_set(&eseTspec, sizeof(tESETspecInfo),
+						0);
+				eseTspec.numTspecs =
+					sme_qos_ese_retrieve_tspec_info(pMac,
+						sessionId,
+						(tTspecInfo *) &eseTspec.
+							tspec[0]);
+				csr_join_req->eseTspecInfo.numTspecs =
+					eseTspec.numTspecs;
+				if (eseTspec.numTspecs) {
+					qdf_mem_copy(&csr_join_req->eseTspecInfo
+						.tspec[0],
+						&eseTspec.tspec[0],
+						(eseTspec.numTspecs *
+							sizeof(tTspecInfo)));
+				}
+			} else {
+				tESETspecInfo eseTspec;
+				/*
+				 * ESE-Tspec IEs in the ASSOC request is
+				 * presently not supported. so nullify the TSPEC
+				 * parameters
+				 */
+				qdf_mem_set(&eseTspec, sizeof(tESETspecInfo),
+						0);
+				qdf_mem_copy(&csr_join_req->eseTspecInfo,
+						&eseTspec,
+						sizeof(tESETspecInfo));
+			}
+		}
+#endif /* FEATURE_WLAN_ESE */
+		if (ese_config
+		    || csr_roam_is_fast_roam_enabled(pMac, sessionId))
+			csr_join_req->isFastTransitionEnabled = true;
+		else
+			csr_join_req->isFastTransitionEnabled = false;
+
+		if (csr_roam_is_fast_roam_enabled(pMac, sessionId))
+			csr_join_req->isFastRoamIniFeatureEnabled = true;
+		else
+			csr_join_req->isFastRoamIniFeatureEnabled = false;
+
+		csr_join_req->txLdpcIniFeatureEnabled =
+			(uint8_t) pMac->roam.configParam.tx_ldpc_enable;
+
+		if ((csr_is11h_supported(pMac)) &&
+			(WLAN_REG_IS_5GHZ_CH(pBssDescription->channelId)) &&
+			(pIes->Country.present) &&
+			(!pMac->roam.configParam.
+			 fSupplicantCountryCodeHasPriority)) {
+			csr_save_to_channel_power2_g_5_g(pMac,
+				pIes->Country.num_triplets *
+				sizeof(tSirMacChanInfo),
+				(tSirMacChanInfo *)
+				(&pIes->Country.triplets[0]));
+			csr_apply_power2_current(pMac);
+		}
+		/*
+		 * If RX LDPC has been disabled for 2.4GHz channels and enabled
+		 * for 5Ghz for STA like persona then here is how to handle
+		 * those cases (by now channel has been decided).
+		 */
+		if (eSIR_INFRASTRUCTURE_MODE == csr_join_req->bsstype ||
+		    !policy_mgr_is_dbs_enable(pMac->psoc))
+			csr_set_ldpc_exception(pMac, pSession,
+					pBssDescription->channelId,
+					pMac->roam.configParam.rx_ldpc_enable);
+		qdf_mem_copy(&csr_join_req->htConfig,
+				&pSession->htConfig, sizeof(tSirHTConfig));
+		qdf_mem_copy(&csr_join_req->vht_config, &pSession->vht_config,
+				sizeof(pSession->vht_config));
+		sme_debug("ht capability 0x%x VHT capability 0x%x",
+			(unsigned int)(*(uint32_t *) &csr_join_req->htConfig),
+			(unsigned int)(*(uint32_t *) &csr_join_req->
+			vht_config));
+
+		if (IS_DOT11_MODE_HE(csr_join_req->dot11mode)) {
+			csr_join_req_copy_he_cap(csr_join_req, pSession);
+			/* change the HE caps like sts per band */
+			if (!pMac->usr_cfg_tx_bfee_nsts)
+				CSR_REVISE_REQ_HE_CAP_PER_BAND(csr_join_req,
+							       pMac,
+							       pBssDescription->
+							       channelId);
+		}
+
+		value = pMac->mlme_cfg->vht_caps.vht_cap_info.su_bformee;
+		value1 = pMac->mlme_cfg->vht_caps.vht_cap_info.tx_bfee_ant_supp;
+
+		csr_join_req->vht_config.su_beam_formee = value;
+
+		if (pIes->VHTCaps.present)
+			vht_caps = &pIes->VHTCaps;
+		else if (pIes->vendor_vht_ie.VHTCaps.present)
+			vht_caps = &pIes->vendor_vht_ie.VHTCaps;
+		/* Set BF CSN value only if SU Bformee is enabled */
+		if (vht_caps && csr_join_req->vht_config.su_beam_formee) {
+			txBFCsnValue = (uint8_t)value1;
+			/*
+			 * Certain commercial AP display a bad behavior when
+			 * CSN value in  assoc request is more than AP's CSN.
+			 * Sending absolute self CSN value with such AP leads to
+			 * IOT issues. However this issue is observed only with
+			 * CSN cap of less than 4. To avoid such issues, take a
+			 * min of self and peer CSN while sending ASSOC request.
+			 */
+			if (pIes->Vendor1IE.present &&
+					vht_caps->csnofBeamformerAntSup < 4) {
+				if (vht_caps->csnofBeamformerAntSup)
+					txBFCsnValue = QDF_MIN(txBFCsnValue,
+					  vht_caps->csnofBeamformerAntSup);
+			}
+		}
+		csr_join_req->vht_config.csnof_beamformer_antSup = txBFCsnValue;
+
+		bvalue = pMac->mlme_cfg->vht_caps.vht_cap_info.su_bformer;
+		/*
+		 * Set SU Bformer only if SU Bformer is enabled in INI
+		 * and AP is SU Bformee capable
+		 */
+		if (bvalue && !((IS_BSS_VHT_CAPABLE(pIes->VHTCaps) &&
+		    pIes->VHTCaps.suBeamformeeCap) ||
+		    (IS_BSS_VHT_CAPABLE(pIes->vendor_vht_ie.VHTCaps) &&
+		     pIes->vendor_vht_ie.VHTCaps.suBeamformeeCap)))
+			bvalue = 0;
+
+		csr_join_req->vht_config.su_beam_former = bvalue;
+
+		/* Set num soundingdim value to 0 if SU Bformer is disabled */
+		if (!csr_join_req->vht_config.su_beam_former)
+			csr_join_req->vht_config.num_soundingdim = 0;
+
+		value =
+			pMac->mlme_cfg->vht_caps.vht_cap_info.enable_mu_bformee;
+		/*
+		 * Set MU Bformee only if SU Bformee is enabled and
+		 * MU Bformee is enabled in INI
+		 */
+		if (value && csr_join_req->vht_config.su_beam_formee &&
+				pIes->VHTCaps.muBeamformerCap)
+			csr_join_req->vht_config.mu_beam_formee = 1;
+		else
+			csr_join_req->vht_config.mu_beam_formee = 0;
+
+		csr_join_req->enableVhtpAid =
+			pMac->mlme_cfg->vht_caps.vht_cap_info.enable_gid;
+
+		csr_join_req->enableVhtGid =
+			pMac->mlme_cfg->vht_caps.vht_cap_info.enable_gid;
+
+		csr_join_req->enableAmpduPs =
+			(uint8_t)pMac->mlme_cfg->ht_caps.enable_ampdu_ps;
+
+		csr_join_req->enableHtSmps =
+			(uint8_t)pMac->mlme_cfg->ht_caps.enable_smps;
+
+		csr_join_req->htSmps = (uint8_t)pMac->mlme_cfg->ht_caps.smps;
+		csr_join_req->send_smps_action =
+			pMac->roam.configParam.send_smps_action;
+
+		csr_join_req->max_amsdu_num =
+			(uint8_t)pMac->mlme_cfg->ht_caps.max_num_amsdu;
+
+		if (pMac->roam.roamSession[sessionId].fWMMConnection)
+			csr_join_req->isWMEenabled = true;
+		else
+			csr_join_req->isWMEenabled = false;
+
+		if (pMac->roam.roamSession[sessionId].fQOSConnection)
+			csr_join_req->isQosEnabled = true;
+		else
+			csr_join_req->isQosEnabled = false;
+
+		if (pProfile->bOSENAssociation)
+			csr_join_req->isOSENConnection = true;
+		else
+			csr_join_req->isOSENConnection = false;
+
+		/* Fill rrm config parameters */
+		qdf_mem_copy(&csr_join_req->rrm_config,
+			     &pMac->rrm.rrmSmeContext.rrmConfig,
+			     sizeof(struct rrm_config_param));
+
+		pAP_capabilityInfo =
+			(tSirMacCapabilityInfo *)
+				&pBssDescription->capabilityInfo;
+		/*
+		 * tell the target AP my 11H capability only if both AP and STA
+		 * support
+		 * 11H and the channel being used is 11a
+		 */
+		if (csr_is11h_supported(pMac) && pAP_capabilityInfo->spectrumMgt
+			&& eSIR_11A_NW_TYPE == pBssDescription->nwType) {
+			fTmp = true;
+		} else
+			fTmp = false;
+
+		csr_join_req->spectrumMgtIndicator = fTmp;
+		csr_join_req->powerCap.minTxPower = MIN_TX_PWR_CAP;
+		/*
+		 * This is required for 11k test VoWiFi Ent: Test 2.
+		 * We need the power capabilities for Assoc Req.
+		 * This macro is provided by the halPhyCfg.h. We pick our
+		 * max and min capability by the halPhy provided macros
+		 * Any change in this power cap IE should also be done
+		 * in csr_update_driver_assoc_ies() which would send
+		 * assoc IE's to FW which is used for LFR3 roaming
+		 * ie. used in reassociation requests from FW.
+		 */
+		pwrLimit = csr_get_cfg_max_tx_power(pMac,
+					pBssDescription->channelId);
+		if (0 != pwrLimit && pwrLimit < MAX_TX_PWR_CAP)
+			csr_join_req->powerCap.maxTxPower = pwrLimit;
+		else
+			csr_join_req->powerCap.maxTxPower = MAX_TX_PWR_CAP;
+
+		csr_add_supported_5Ghz_channels(pMac,
+				csr_join_req->supportedChannels.channelList,
+				&csr_join_req->supportedChannels.numChnl,
+				false);
+
+		if (csr_enable_uapsd(pMac, pIes))
+			csr_join_req->uapsdPerAcBitmask = pProfile->uapsd_mask;
+		/* Move the entire BssDescription into the join request. */
+		qdf_mem_copy(&csr_join_req->bssDescription, pBssDescription,
+				pBssDescription->length +
+				sizeof(pBssDescription->length));
+		csr_update_fils_connection_info(pProfile, csr_join_req);
+		csr_update_sae_config(csr_join_req, pMac, pSession);
+		/*
+		 * conc_custom_rule1:
+		 * If SAP comes up first and STA comes up later then SAP
+		 * need to follow STA's channel in 2.4Ghz. In following if
+		 * condition we are adding sanity check, just to make sure that
+		 * if this rule is enabled then don't allow STA to connect on
+		 * 5gz channel and also by this time SAP's channel should be the
+		 * same as STA's channel.
+		 */
+		if (pMac->roam.configParam.conc_custom_rule1) {
+			if ((0 == pMac->roam.configParam.
+				is_sta_connection_in_5gz_enabled) &&
+				WLAN_REG_IS_5GHZ_CH(pBssDescription->
+					channelId)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					 "STA-conn on 5G isn't allowed");
+				status = QDF_STATUS_E_FAILURE;
+				break;
+			}
+			if (!WLAN_REG_IS_5GHZ_CH(pBssDescription->channelId) &&
+				(false == csr_is_conn_allow_2g_band(pMac,
+						pBssDescription->channelId))) {
+				status = QDF_STATUS_E_FAILURE;
+				break;
+			}
+		}
+
+		/*
+		 * conc_custom_rule2:
+		 * If P2PGO comes up first and STA comes up later then P2PGO
+		 * need to follow STA's channel in 5Ghz. In following if
+		 * condition we are just adding sanity check to make sure that
+		 * by this time P2PGO's channel is same as STA's channel.
+		 */
+		if (pMac->roam.configParam.conc_custom_rule2 &&
+			!WLAN_REG_IS_24GHZ_CH(pBssDescription->channelId) &&
+			(!csr_is_conn_allow_5g_band(pMac,
+						pBssDescription->channelId))) {
+			status = QDF_STATUS_E_FAILURE;
+			break;
+		}
+
+		if (pSession->pCurRoamProfile->csrPersona == QDF_STA_MODE)
+			csr_join_req->enable_bcast_probe_rsp =
+				pMac->mlme_cfg->oce.enable_bcast_probe_rsp;
+
+		csr_join_req->enable_session_twt_support = csr_enable_twt(pIes);
+		status = umac_send_mb_message_to_mac(csr_join_req);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			/*
+			 * umac_send_mb_message_to_mac would've released the mem
+			 * allocated by csr_join_req. Let's make it defensive by
+			 * assigning NULL to the pointer.
+			 */
+			csr_join_req = NULL;
+			break;
+		}
+
+		if (pProfile->csrPersona == QDF_STA_MODE) {
+			sme_debug("Invoking packetdump register API");
+			wlan_register_txrx_packetdump();
+			packetdump_timer_status = qdf_mc_timer_start(
+						&pMac->roam.packetdump_timer,
+						(PKT_DUMP_TIMER_DURATION *
+						QDF_MC_TIMER_TO_SEC_UNIT)/
+						QDF_MC_TIMER_TO_MS_UNIT);
+			if (!QDF_IS_STATUS_SUCCESS(packetdump_timer_status))
+				sme_err("cannot start packetdump timer status: %d",
+					packetdump_timer_status);
+		}
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		if (eWNI_SME_JOIN_REQ == messageType) {
+			/* Notify QoS module that join happening */
+			pSession->join_bssid_count++;
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"BSSID Count: %d", pSession->join_bssid_count);
+			sme_qos_csr_event_ind(pMac, (uint8_t) sessionId,
+						SME_QOS_CSR_JOIN_REQ, NULL);
+		} else if (eWNI_SME_REASSOC_REQ == messageType)
+			/* Notify QoS module that reassoc happening */
+			sme_qos_csr_event_ind(pMac, (uint8_t) sessionId,
+						SME_QOS_CSR_REASSOC_REQ,
+						NULL);
+#endif
+	} while (0);
+
+	/* Clean up the memory in case of any failure */
+	if (!QDF_IS_STATUS_SUCCESS(status) && (NULL != csr_join_req))
+		qdf_mem_free(csr_join_req);
+
+	if (wpaRsnIE)
+		qdf_mem_free(wpaRsnIE);
+
+	return status;
+}
+
+/* */
+QDF_STATUS csr_send_mb_disassoc_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+					tSirMacAddr bssId, uint16_t reasonCode)
+{
+	tSirSmeDisassocReq *pMsg;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId))
+		return QDF_STATUS_E_FAILURE;
+
+	pMsg = qdf_mem_malloc(sizeof(tSirSmeDisassocReq));
+	if (NULL == pMsg)
+		return QDF_STATUS_E_NOMEM;
+
+	pMsg->messageType = eWNI_SME_DISASSOC_REQ;
+	pMsg->length = sizeof(tSirSmeDisassocReq);
+	pMsg->sessionId = sessionId;
+	pMsg->transactionId = 0;
+	if ((pSession->pCurRoamProfile != NULL)
+		&& (CSR_IS_INFRA_AP(pSession->pCurRoamProfile))) {
+		qdf_mem_copy(&pMsg->bssid.bytes,
+			     &pSession->selfMacAddr,
+			     QDF_MAC_ADDR_SIZE);
+		qdf_mem_copy(&pMsg->peer_macaddr.bytes,
+			     bssId,
+			     QDF_MAC_ADDR_SIZE);
+	} else {
+		qdf_mem_copy(&pMsg->bssid.bytes,
+			     bssId, QDF_MAC_ADDR_SIZE);
+		qdf_mem_copy(&pMsg->peer_macaddr.bytes,
+			     bssId, QDF_MAC_ADDR_SIZE);
+	}
+	pMsg->reasonCode = reasonCode;
+	pMsg->process_ho_fail = (pSession->disconnect_reason ==
+		eCSR_DISCONNECT_REASON_ROAM_HO_FAIL) ? true : false;
+
+	/* Update the disconnect stats */
+	pSession->disconnect_stats.disconnection_cnt++;
+	pSession->disconnect_stats.disconnection_by_app++;
+
+	/*
+	 * The state will be DISASSOC_HANDOFF only when we are doing
+	 * handoff. Here we should not send the disassoc over the air
+	 * to the AP
+	 */
+	if ((CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId)
+			&& csr_roam_is11r_assoc(pMac, sessionId)) ||
+						pMsg->process_ho_fail) {
+		/* Set DoNotSendOverTheAir flag to 1 only for handoff case */
+		pMsg->doNotSendOverTheAir = CSR_DONT_SEND_DISASSOC_OVER_THE_AIR;
+	}
+	return umac_send_mb_message_to_mac(pMsg);
+}
+
+QDF_STATUS
+csr_send_mb_get_associated_stas_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+					QDF_MODULE_ID modId,
+					struct qdf_mac_addr bssid,
+					void *pUsrContext,
+					void *pfnSapEventCallback,
+					uint8_t *pAssocStasBuf)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirSmeGetAssocSTAsReq *pMsg;
+
+	pMsg = qdf_mem_malloc(sizeof(*pMsg));
+	if (NULL == pMsg)
+		return QDF_STATUS_E_NOMEM;
+
+	pMsg->messageType = eWNI_SME_GET_ASSOC_STAS_REQ;
+	qdf_copy_macaddr(&pMsg->bssid, &bssid);
+	pMsg->modId = modId;
+	qdf_mem_copy(pMsg->pUsrContext, pUsrContext, sizeof(void *));
+	qdf_mem_copy(pMsg->pSapEventCallback,
+			pfnSapEventCallback, sizeof(void *));
+	qdf_mem_copy(pMsg->pAssocStasArray, pAssocStasBuf, sizeof(void *));
+	pMsg->length = sizeof(*pMsg);
+	status = umac_send_mb_message_to_mac(pMsg);
+
+	return status;
+}
+
+QDF_STATUS csr_send_chng_mcc_beacon_interval(tpAniSirGlobal pMac,
+						uint32_t sessionId)
+{
+	tpSirChangeBIParams pMsg;
+	uint16_t len = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* NO need to update the Beacon Params if update beacon parameter flag
+	 * is not set
+	 */
+	if (!pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval)
+		return QDF_STATUS_SUCCESS;
+
+	pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval =
+		false;
+
+	/* Create the message and send to lim */
+	len = sizeof(tSirChangeBIParams);
+	pMsg = qdf_mem_malloc(len);
+	if (NULL == pMsg)
+		status = QDF_STATUS_E_NOMEM;
+	else
+		status = QDF_STATUS_SUCCESS;
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		pMsg->messageType = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
+		pMsg->length = len;
+
+		qdf_copy_macaddr(&pMsg->bssid, &pSession->selfMacAddr);
+		sme_debug(
+			"CSR Attempting to change BI for Bssid= "
+			   MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pMsg->bssid.bytes));
+		pMsg->sessionId = sessionId;
+		sme_debug("session %d BeaconInterval %d",
+			sessionId,
+			pMac->roam.roamSession[sessionId].bssParams.
+			beaconInterval);
+		pMsg->beaconInterval =
+			pMac->roam.roamSession[sessionId].bssParams.beaconInterval;
+		status = umac_send_mb_message_to_mac(pMsg);
+	}
+	return status;
+}
+
+#ifdef QCA_HT_2040_COEX
+QDF_STATUS csr_set_ht2040_mode(tpAniSirGlobal pMac, uint32_t sessionId,
+			       ePhyChanBondState cbMode, bool obssEnabled)
+{
+	tpSirSetHT2040Mode pMsg;
+	uint16_t len = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Create the message and send to lim */
+	len = sizeof(tSirSetHT2040Mode);
+	pMsg = qdf_mem_malloc(len);
+	if (NULL == pMsg)
+		status = QDF_STATUS_E_NOMEM;
+	else
+		status = QDF_STATUS_SUCCESS;
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		qdf_mem_set(pMsg, sizeof(tSirSetHT2040Mode), 0);
+		pMsg->messageType = eWNI_SME_SET_HT_2040_MODE;
+		pMsg->length = len;
+
+		qdf_copy_macaddr(&pMsg->bssid, &pSession->selfMacAddr);
+		sme_debug(
+			"CSR Attempting to set HT20/40 mode for Bssid= "
+			   MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pMsg->bssid.bytes));
+		pMsg->sessionId = sessionId;
+		sme_debug("  session %d HT20/40 mode %d",
+			sessionId, cbMode);
+		pMsg->cbMode = cbMode;
+		pMsg->obssEnabled = obssEnabled;
+		status = umac_send_mb_message_to_mac(pMsg);
+	}
+	return status;
+}
+#endif
+
+QDF_STATUS csr_send_mb_deauth_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+				      tSirMacAddr bssId, uint16_t reasonCode)
+{
+	tSirSmeDeauthReq *pMsg;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId))
+		return QDF_STATUS_E_FAILURE;
+
+	pMsg = qdf_mem_malloc(sizeof(tSirSmeDeauthReq));
+	if (NULL == pMsg)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_set(pMsg, sizeof(tSirSmeDeauthReq), 0);
+	pMsg->messageType = eWNI_SME_DEAUTH_REQ;
+	pMsg->length = sizeof(tSirSmeDeauthReq);
+	pMsg->sessionId = sessionId;
+	pMsg->transactionId = 0;
+
+	if ((pSession->pCurRoamProfile != NULL)
+	     && (CSR_IS_INFRA_AP(pSession->pCurRoamProfile))) {
+		qdf_mem_copy(&pMsg->bssid,
+			     &pSession->selfMacAddr,
+			     QDF_MAC_ADDR_SIZE);
+	} else {
+		qdf_mem_copy(&pMsg->bssid,
+			     bssId, QDF_MAC_ADDR_SIZE);
+	}
+
+	/* Set the peer MAC address before sending the message to LIM */
+	qdf_mem_copy(&pMsg->peer_macaddr.bytes, bssId, QDF_MAC_ADDR_SIZE);
+	pMsg->reasonCode = reasonCode;
+
+	/* Update the disconnect stats */
+	pSession->disconnect_stats.disconnection_cnt++;
+	pSession->disconnect_stats.disconnection_by_app++;
+
+	return umac_send_mb_message_to_mac(pMsg);
+}
+
+QDF_STATUS csr_send_mb_disassoc_cnf_msg(tpAniSirGlobal pMac,
+					tpSirSmeDisassocInd pDisassocInd)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirSmeDisassocCnf *pMsg;
+
+	do {
+		pMsg = qdf_mem_malloc(sizeof(tSirSmeDisassocCnf));
+		if (NULL == pMsg)
+			status = QDF_STATUS_E_NOMEM;
+		else
+			status = QDF_STATUS_SUCCESS;
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+		pMsg->messageType = eWNI_SME_DISASSOC_CNF;
+		pMsg->statusCode = eSIR_SME_SUCCESS;
+		pMsg->length = sizeof(tSirSmeDisassocCnf);
+		pMsg->sme_session_id = pDisassocInd->sessionId;
+		qdf_copy_macaddr(&pMsg->peer_macaddr,
+				 &pDisassocInd->peer_macaddr);
+		status = QDF_STATUS_SUCCESS;
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			qdf_mem_free(pMsg);
+			break;
+		}
+
+		qdf_copy_macaddr(&pMsg->bssid, &pDisassocInd->bssid);
+		status = QDF_STATUS_SUCCESS;
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			qdf_mem_free(pMsg);
+			break;
+		}
+
+		status = umac_send_mb_message_to_mac(pMsg);
+	} while (0);
+	return status;
+}
+
+QDF_STATUS csr_send_mb_deauth_cnf_msg(tpAniSirGlobal pMac,
+				      tpSirSmeDeauthInd pDeauthInd)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirSmeDeauthCnf *pMsg;
+
+	do {
+		pMsg = qdf_mem_malloc(sizeof(tSirSmeDeauthCnf));
+		if (NULL == pMsg)
+			status = QDF_STATUS_E_NOMEM;
+		else
+			status = QDF_STATUS_SUCCESS;
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+		pMsg->messageType = eWNI_SME_DEAUTH_CNF;
+		pMsg->statusCode = eSIR_SME_SUCCESS;
+		pMsg->length = sizeof(tSirSmeDeauthCnf);
+		pMsg->sme_session_id = pDeauthInd->sessionId;
+		qdf_copy_macaddr(&pMsg->bssid, &pDeauthInd->bssid);
+		status = QDF_STATUS_SUCCESS;
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			qdf_mem_free(pMsg);
+			break;
+		}
+		qdf_copy_macaddr(&pMsg->peer_macaddr,
+				 &pDeauthInd->peer_macaddr);
+		status = QDF_STATUS_SUCCESS;
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			qdf_mem_free(pMsg);
+			break;
+		}
+		status = umac_send_mb_message_to_mac(pMsg);
+	} while (0);
+	return status;
+}
+
+QDF_STATUS csr_send_assoc_cnf_msg(tpAniSirGlobal pMac, tpSirSmeAssocInd
+				pAssocInd, QDF_STATUS Halstatus)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirSmeAssocCnf *pMsg;
+	struct scheduler_msg msg = { 0 };
+
+	sme_debug("Posting eWNI_SME_ASSOC_CNF to LIM.HalStatus: %d", Halstatus);
+	do {
+		pMsg = qdf_mem_malloc(sizeof(tSirSmeAssocCnf));
+		if (NULL == pMsg)
+			return QDF_STATUS_E_NOMEM;
+		pMsg->messageType = eWNI_SME_ASSOC_CNF;
+		pMsg->length = sizeof(tSirSmeAssocCnf);
+		if (QDF_IS_STATUS_SUCCESS(Halstatus))
+			pMsg->statusCode = eSIR_SME_SUCCESS;
+		else
+			pMsg->statusCode = eSIR_SME_ASSOC_REFUSED;
+		/* bssId */
+		qdf_mem_copy(pMsg->bssid.bytes, pAssocInd->bssId,
+			     QDF_MAC_ADDR_SIZE);
+		/* peerMacAddr */
+		qdf_mem_copy(pMsg->peer_macaddr.bytes, pAssocInd->peerMacAddr,
+			     QDF_MAC_ADDR_SIZE);
+		/* aid */
+		pMsg->aid = pAssocInd->aid;
+		/* alternateBssId */
+		qdf_mem_copy(pMsg->alternate_bssid.bytes, pAssocInd->bssId,
+			     QDF_MAC_ADDR_SIZE);
+		/* alternateChannelId */
+		pMsg->alternateChannelId = 11;
+
+		msg.type = pMsg->messageType;
+		msg.bodyval = 0;
+		msg.bodyptr = pMsg;
+		/* pMsg is freed by umac_send_mb_message_to_mac in anycase*/
+		status = scheduler_post_msg_by_priority(QDF_MODULE_ID_PE, &msg,
+							true);
+	} while (0);
+	return status;
+}
+
+QDF_STATUS csr_send_assoc_ind_to_upper_layer_cnf_msg(tpAniSirGlobal pMac,
+						     tpSirSmeAssocInd pAssocInd,
+						     QDF_STATUS Halstatus,
+						     uint8_t sessionId)
+{
+	struct scheduler_msg msgQ = {0};
+	tSirSmeAssocIndToUpperLayerCnf *pMsg;
+	uint8_t *pBuf;
+	tSirResultCodes statusCode;
+	uint16_t wTmp;
+
+	do {
+		pMsg = qdf_mem_malloc(sizeof(tSirSmeAssocIndToUpperLayerCnf));
+		if (NULL == pMsg)
+			return QDF_STATUS_E_NOMEM;
+
+		pMsg->messageType = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
+		pMsg->length = sizeof(tSirSmeAssocIndToUpperLayerCnf);
+
+		pMsg->sessionId = sessionId;
+
+		pBuf = (uint8_t *) &pMsg->statusCode;
+		if (QDF_IS_STATUS_SUCCESS(Halstatus))
+			statusCode = eSIR_SME_SUCCESS;
+		else
+			statusCode = eSIR_SME_ASSOC_REFUSED;
+		qdf_mem_copy(pBuf, &statusCode, sizeof(tSirResultCodes));
+		/* bssId */
+		pBuf = (uint8_t *)&pMsg->bssId;
+		qdf_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId,
+			sizeof(tSirMacAddr));
+		/* peerMacAddr */
+		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));
+		/* alternateBssId */
+		pBuf = (uint8_t *)&pMsg->alternateBssId;
+		qdf_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId,
+			sizeof(tSirMacAddr));
+		/* alternateChannelId */
+		pBuf = (uint8_t *)&pMsg->alternateChannelId;
+		*pBuf = 11;
+		/*
+		 * Instead of copying roam Info,just copy WmmEnabled,
+		 * RsnIE information.
+		 * Wmm
+		 */
+		pBuf = (uint8_t *)&pMsg->wmmEnabledSta;
+		*pBuf = pAssocInd->wmmEnabledSta;
+		/* RSN IE */
+		pBuf = (uint8_t *)&pMsg->rsnIE;
+		qdf_mem_copy((tSirRSNie *)pBuf, &pAssocInd->rsnIE,
+			sizeof(tSirRSNie));
+#ifdef FEATURE_WLAN_WAPI
+		/* WAPI IE */
+		pBuf = (uint8_t *)&pMsg->wapiIE;
+		qdf_mem_copy((tSirWAPIie *)pBuf, &pAssocInd->wapiIE,
+			sizeof(tSirWAPIie));
+#endif
+		/* Additional IE */
+		pBuf = (uint8_t *)&pMsg->addIE;
+		qdf_mem_copy((tSirAddie *)pBuf, &pAssocInd->addIE,
+			sizeof(tSirAddie));
+		/* reassocReq */
+		pBuf = (uint8_t *)&pMsg->reassocReq;
+		*pBuf = pAssocInd->reassocReq;
+		/* timingMeasCap */
+		pBuf = (uint8_t *)&pMsg->timingMeasCap;
+		*pBuf = pAssocInd->timingMeasCap;
+		/* chan_info */
+		pBuf = (uint8_t *)&pMsg->chan_info;
+		qdf_mem_copy((void *)pBuf, &pAssocInd->chan_info,
+			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;
+
+		pBuf = (uint8_t *)&pMsg->ecsa_capable;
+		*pBuf = pAssocInd->ecsa_capable;
+
+		if (pAssocInd->HTCaps.present)
+			pMsg->ht_caps = pAssocInd->HTCaps;
+		if (pAssocInd->VHTCaps.present)
+			pMsg->vht_caps = pAssocInd->VHTCaps;
+
+		msgQ.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
+		msgQ.bodyptr = pMsg;
+		msgQ.bodyval = 0;
+		sys_process_mmh_msg(pMac, &msgQ);
+	} while (0);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS csr_send_mb_set_context_req_msg(tpAniSirGlobal pMac,
+					   uint32_t sessionId,
+					   struct qdf_mac_addr peer_macaddr,
+					   uint8_t numKeys,
+					   tAniEdType edType, bool fUnicast,
+					   tAniKeyDirection aniKeyDirection,
+					   uint8_t keyId, uint8_t keyLength,
+					   uint8_t *pKey, uint8_t paeRole,
+					   uint8_t *pKeyRsc)
+{
+	tSirSmeSetContextReq *pMsg;
+	struct scheduler_msg msg = {0};
+	uint16_t msgLen;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	sme_debug("keylength: %d Encry type: %d", keyLength, edType);
+	do {
+		if ((1 != numKeys) && (0 != numKeys))
+			break;
+		/*
+		 * All of these fields appear in every SET_CONTEXT message.
+		 * Below we'll add in the size for each key set. Since we only
+		 * support up to one key, we always allocate memory for 1 key.
+		 */
+		msgLen = sizeof(struct sSirSmeSetContextReq);
+
+		pMsg = qdf_mem_malloc(msgLen);
+		if (NULL == pMsg)
+			return QDF_STATUS_E_NOMEM;
+		pMsg->messageType = eWNI_SME_SETCONTEXT_REQ;
+		pMsg->length = msgLen;
+		pMsg->sessionId = (uint8_t) sessionId;
+		pMsg->transactionId = 0;
+		qdf_copy_macaddr(&pMsg->peer_macaddr, &peer_macaddr);
+		qdf_copy_macaddr(&pMsg->bssid,
+				 &pSession->connectedProfile.bssid);
+
+		/**
+		 * Set the pMsg->keyMaterial.length field
+		 * (this length is defined as all data that follows the
+		 * edType field in the tSirKeyMaterial keyMaterial; field).
+		 *
+		 * NOTE:  This keyMaterial.length contains the length of a
+		 * MAX size key, though the keyLength can be shorter than this
+		 * max size.  Is LIM interpreting this ok ?
+		 */
+		pMsg->keyMaterial.length =
+				sizeof(pMsg->keyMaterial.numKeys) +
+				(numKeys * sizeof(pMsg->keyMaterial.key));
+		pMsg->keyMaterial.edType = edType;
+		pMsg->keyMaterial.numKeys = numKeys;
+		pMsg->keyMaterial.key[0].keyId = keyId;
+		pMsg->keyMaterial.key[0].unicast = fUnicast;
+		pMsg->keyMaterial.key[0].keyDirection = aniKeyDirection;
+		qdf_mem_copy(pMsg->keyMaterial.key[0].keyRsc,
+				pKeyRsc, CSR_MAX_RSC_LEN);
+		/* 0 is Supplicant */
+		pMsg->keyMaterial.key[0].paeRole = paeRole;
+		pMsg->keyMaterial.key[0].keyLength = keyLength;
+		if (keyLength && pKey)
+			qdf_mem_copy(pMsg->keyMaterial.key[0].key,
+					pKey, keyLength);
+
+		msg.type = eWNI_SME_SETCONTEXT_REQ;
+		msg.bodyptr = pMsg;
+		status = scheduler_post_message(QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_PE,
+						QDF_MODULE_ID_PE, &msg);
+		if (QDF_IS_STATUS_ERROR(status))
+			qdf_mem_free(pMsg);
+	} while (0);
+	return status;
+}
+
+QDF_STATUS csr_send_mb_start_bss_req_msg(tpAniSirGlobal pMac, uint32_t
+					sessionId, eCsrRoamBssType bssType,
+					 struct csr_roamstart_bssparams *pParam,
+					 tSirBssDescription *pBssDesc)
+{
+	tSirSmeStartBssReq *pMsg;
+	uint16_t wTmp;
+	uint32_t value = 0;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pSession->joinFailStatusCode.statusCode = eSIR_SME_SUCCESS;
+	pSession->joinFailStatusCode.reasonCode = 0;
+	pMsg = qdf_mem_malloc(sizeof(tSirSmeStartBssReq));
+	if (NULL == pMsg)
+		return QDF_STATUS_E_NOMEM;
+
+	pMsg->messageType = eWNI_SME_START_BSS_REQ;
+	pMsg->sessionId = sessionId;
+	pMsg->length = sizeof(tSirSmeStartBssReq);
+	pMsg->transactionId = 0;
+	qdf_copy_macaddr(&pMsg->bssid, &pParam->bssid);
+	/* selfMacAddr */
+	qdf_copy_macaddr(&pMsg->self_macaddr, &pSession->selfMacAddr);
+	/* beaconInterval */
+	if (pBssDesc && pBssDesc->beaconInterval)
+		wTmp = pBssDesc->beaconInterval;
+	else if (pParam->beaconInterval)
+		wTmp = pParam->beaconInterval;
+	else
+		wTmp = MLME_CFG_BEACON_INTERVAL_DEF;
+
+	csr_validate_mcc_beacon_interval(pMac, pParam->operationChn,
+					 &wTmp, sessionId, pParam->bssPersona);
+	/* Update the beacon Interval */
+	pParam->beaconInterval = wTmp;
+	pMsg->beaconInterval = wTmp;
+	pMsg->dot11mode =
+		csr_translate_to_wni_cfg_dot11_mode(pMac,
+						    pParam->uCfgDot11Mode);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	pMsg->cc_switch_mode = pMac->roam.configParam.cc_switch_mode;
+#endif
+	pMsg->bssType = csr_translate_bsstype_to_mac_type(bssType);
+	qdf_mem_copy(&pMsg->ssId, &pParam->ssId, sizeof(pParam->ssId));
+	pMsg->channelId = pParam->operationChn;
+	/* What should we really do for the cbmode. */
+	pMsg->cbMode = (ePhyChanBondState) pParam->cbMode;
+	pMsg->vht_channel_width = pParam->ch_params.ch_width;
+	pMsg->center_freq_seg0 = pParam->ch_params.center_freq_seg0;
+	pMsg->center_freq_seg1 = pParam->ch_params.center_freq_seg1;
+	pMsg->sec_ch_offset = pParam->ch_params.sec_ch_offset;
+	pMsg->privacy = pParam->privacy;
+	pMsg->apUapsdEnable = pParam->ApUapsdEnable;
+	pMsg->ssidHidden = pParam->ssidHidden;
+	pMsg->fwdWPSPBCProbeReq = (uint8_t) pParam->fwdWPSPBCProbeReq;
+	pMsg->protEnabled = (uint8_t) pParam->protEnabled;
+	pMsg->obssProtEnabled = (uint8_t) pParam->obssProtEnabled;
+	/* set cfg related to protection */
+	pMsg->ht_capab = pParam->ht_protection;
+	pMsg->authType = pParam->authType;
+	pMsg->dtimPeriod = pParam->dtimPeriod;
+	pMsg->wps_state = pParam->wps_state;
+	pMsg->isCoalesingInIBSSAllowed = pMac->isCoalesingInIBSSAllowed;
+	pMsg->bssPersona = pParam->bssPersona;
+	pMsg->txLdpcIniFeatureEnabled = pMac->roam.configParam.tx_ldpc_enable;
+
+	/*
+	 * If RX LDPC has been disabled for 2.4GHz channels and enabled
+	 * for 5Ghz for STA like persona then here is how to handle
+	 * those cases (by now channel has been decided).
+	 */
+	if (eSIR_IBSS_MODE == pMsg->bssType ||
+		!policy_mgr_is_dbs_enable(pMac->psoc))
+		csr_set_ldpc_exception(pMac, pSession,
+				pMsg->channelId,
+				pMac->roam.configParam.rx_ldpc_enable);
+
+	qdf_mem_copy(&pMsg->vht_config,
+		     &pSession->vht_config,
+		     sizeof(pSession->vht_config));
+	qdf_mem_copy(&pMsg->htConfig,
+		     &pSession->htConfig,
+		     sizeof(tSirHTConfig));
+
+	value = pMac->mlme_cfg->vht_caps.vht_cap_info.su_bformee;
+	pMsg->vht_config.su_beam_formee =
+		(uint8_t)value &&
+		(uint8_t)pMac->mlme_cfg->vht_caps.vht_cap_info.tx_bfee_sap;
+	value = pMac->mlme_cfg->vht_caps.vht_cap_info.tx_bfee_ant_supp;
+	pMsg->vht_config.csnof_beamformer_antSup = (uint8_t)value;
+	pMsg->vht_config.mu_beam_formee = 0;
+
+	sme_debug("ht capability 0x%x VHT capability 0x%x",
+			 (uint32_t)(*(uint32_t *) &pMsg->htConfig),
+			 (uint32_t)(*(uint32_t *) &pMsg->vht_config));
+#ifdef WLAN_FEATURE_11W
+	pMsg->pmfCapable = pParam->mfpCapable;
+	pMsg->pmfRequired = pParam->mfpRequired;
+#endif
+
+	if (pParam->nRSNIELength > sizeof(pMsg->rsnIE.rsnIEdata)) {
+		qdf_mem_free(pMsg);
+		return QDF_STATUS_E_INVAL;
+	}
+	pMsg->rsnIE.length = pParam->nRSNIELength;
+	qdf_mem_copy(pMsg->rsnIE.rsnIEdata,
+		     pParam->pRSNIE,
+		     pParam->nRSNIELength);
+	pMsg->nwType = (tSirNwType)pParam->sirNwType;
+	qdf_mem_copy(&pMsg->operationalRateSet,
+		     &pParam->operationalRateSet,
+		     sizeof(tSirMacRateSet));
+	qdf_mem_copy(&pMsg->extendedRateSet,
+		     &pParam->extendedRateSet,
+		     sizeof(tSirMacRateSet));
+
+	if (IS_DOT11_MODE_HE(pMsg->dot11mode)) {
+		csr_start_bss_copy_he_cap(pMsg, pSession);
+		/* change the HE caps like sts per band */
+		CSR_REVISE_REQ_HE_CAP_PER_BAND(pMsg, pMac,
+					       pParam->operationChn);
+	}
+
+	qdf_mem_copy(&pMsg->addIeParams,
+		     &pParam->addIeParams,
+		     sizeof(pParam->addIeParams));
+	pMsg->obssEnabled = pMac->roam.configParam.obssEnabled;
+	pMsg->sap_dot11mc = pParam->sap_dot11mc;
+	pMsg->vendor_vht_sap =
+			pMac->roam.configParam.vendor_vht_sap;
+	pMsg->cac_duration_ms = pParam->cac_duration_ms;
+	pMsg->dfs_regdomain = pParam->dfs_regdomain;
+	pMsg->beacon_tx_rate = pParam->beacon_tx_rate;
+
+	return umac_send_mb_message_to_mac(pMsg);
+}
+
+QDF_STATUS csr_send_mb_stop_bss_req_msg(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tSirSmeStopBssReq *pMsg;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pMsg = qdf_mem_malloc(sizeof(tSirSmeStopBssReq));
+	if (NULL == pMsg)
+		return QDF_STATUS_E_NOMEM;
+	pMsg->messageType = eWNI_SME_STOP_BSS_REQ;
+	pMsg->sessionId = sessionId;
+	pMsg->length = sizeof(tSirSmeStopBssReq);
+	pMsg->transactionId = 0;
+	pMsg->reasonCode = 0;
+	qdf_copy_macaddr(&pMsg->bssid, &pSession->connectedProfile.bssid);
+	return umac_send_mb_message_to_mac(pMsg);
+}
+
+QDF_STATUS csr_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
+		       tCsrRoamModifyProfileFields *pModProfileFields,
+		       uint32_t *pRoamId, bool fForce)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t roamId = 0;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if ((csr_is_conn_state_connected(pMac, sessionId)) &&
+	    (fForce || (qdf_mem_cmp(&pModProfileFields,
+				     &pSession->connectedProfile.
+				     modifyProfileFields,
+				     sizeof(tCsrRoamModifyProfileFields))))) {
+		roamId = GET_NEXT_ROAM_ID(&pMac->roam);
+		if (pRoamId)
+			*pRoamId = roamId;
+
+		status =
+			csr_roam_issue_reassoc(pMac, sessionId, NULL,
+					       pModProfileFields,
+					       eCsrSmeIssuedReassocToSameAP,
+					       roamId, false);
+	}
+	return status;
+}
+
+static QDF_STATUS csr_roam_session_opened(tpAniSirGlobal pMac,
+					  QDF_STATUS qdf_status,
+					  uint32_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_info roam_info;
+
+	qdf_mem_set(&roam_info, sizeof(struct csr_roam_info), 0);
+
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		status = csr_roam_call_callback(pMac, sessionId, &roam_info, 0,
+						eCSR_ROAM_SESSION_OPENED,
+						eCSR_ROAM_RESULT_FAILURE);
+	} else {
+		status = csr_roam_call_callback(pMac, sessionId, &roam_info, 0,
+						eCSR_ROAM_SESSION_OPENED,
+						eCSR_ROAM_RESULT_SUCCESS);
+	}
+	return status;
+}
+
+QDF_STATUS csr_process_add_sta_session_rsp(tpAniSirGlobal pMac, uint8_t *pMsg)
+{
+	struct add_sta_self_params *rsp;
+	struct send_extcap_ie *msg;
+	QDF_STATUS status;
+
+	if (pMsg == NULL) {
+		sme_err("in %s msg ptr is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	rsp = (struct add_sta_self_params *) pMsg;
+	sme_debug("Add Sta self rsp status = %d", rsp->status);
+
+	if (QDF_IS_STATUS_SUCCESS(rsp->status)) {
+		if ((WMI_VDEV_TYPE_STA == rsp->type ||
+		    (WMI_VDEV_TYPE_AP == rsp->type &&
+		     WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE == rsp->sub_type))) {
+			sme_debug("send SET IE msg to PE");
+			msg = qdf_mem_malloc(sizeof(*msg));
+			if (!msg)
+				return QDF_STATUS_E_NOMEM;
+
+			msg->msg_type = eWNI_SME_SET_IE_REQ;
+			msg->session_id = rsp->session_id;
+			msg->length = sizeof(*msg);
+			status = umac_send_mb_message_to_mac(msg);
+			if (!QDF_IS_STATUS_SUCCESS(status))
+				sme_err("Failed to send down the set IE req ");
+		}
+	}
+
+	csr_roam_session_opened(pMac, rsp->status, rsp->session_id);
+
+	if (QDF_IS_STATUS_ERROR(rsp->status))
+		csr_cleanup_session(pMac, rsp->session_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_get_vdev_type_nss() - gets the nss value based on vdev type
+ * @mac_ctx: Pointer to Global MAC structure
+ * @dev_mode: current device operating mode.
+ * @nss2g: Pointer to the 2G Nss parameter.
+ * @nss5g: Pointer to the 5G Nss parameter.
+ *
+ * Fills the 2G and 5G Nss values based on device mode.
+ *
+ * Return: None
+ */
+void csr_get_vdev_type_nss(tpAniSirGlobal mac_ctx,
+		enum QDF_OPMODE dev_mode,
+		uint8_t *nss_2g, uint8_t *nss_5g)
+{
+	switch (dev_mode) {
+	case QDF_STA_MODE:
+		*nss_2g = mac_ctx->vdev_type_nss_2g.sta;
+		*nss_5g = mac_ctx->vdev_type_nss_5g.sta;
+		break;
+	case QDF_SAP_MODE:
+		*nss_2g = mac_ctx->vdev_type_nss_2g.sap;
+		*nss_5g = mac_ctx->vdev_type_nss_5g.sap;
+		break;
+	case QDF_P2P_CLIENT_MODE:
+		*nss_2g = mac_ctx->vdev_type_nss_2g.p2p_cli;
+		*nss_5g = mac_ctx->vdev_type_nss_5g.p2p_cli;
+		break;
+	case QDF_P2P_GO_MODE:
+		*nss_2g = mac_ctx->vdev_type_nss_2g.p2p_go;
+		*nss_5g = mac_ctx->vdev_type_nss_5g.p2p_go;
+		break;
+	case QDF_P2P_DEVICE_MODE:
+		*nss_2g = mac_ctx->vdev_type_nss_2g.p2p_dev;
+		*nss_5g = mac_ctx->vdev_type_nss_5g.p2p_dev;
+		break;
+	case QDF_IBSS_MODE:
+		*nss_2g = mac_ctx->vdev_type_nss_2g.ibss;
+		*nss_5g = mac_ctx->vdev_type_nss_5g.ibss;
+		break;
+	case QDF_OCB_MODE:
+		*nss_2g = mac_ctx->vdev_type_nss_2g.ocb;
+		*nss_5g = mac_ctx->vdev_type_nss_5g.ocb;
+		break;
+	default:
+		*nss_2g = 1;
+		*nss_5g = 1;
+		sme_err("Unknown device mode");
+		break;
+	}
+	sme_debug("mode - %d: nss_2g - %d, 5g - %d",
+			dev_mode, *nss_2g, *nss_5g);
+}
+
+static
+QDF_STATUS csr_issue_add_sta_for_session_req(tpAniSirGlobal pMac,
+					     uint32_t sessionId,
+					     tSirMacAddr sessionMacAddr,
+					     uint32_t type, uint32_t subType)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct add_sta_self_params *add_sta_self_req;
+	struct wlan_mlme_qos *qos_aggr = &pMac->mlme_cfg->qos_mlme_params;
+	uint8_t nss_2g;
+	uint8_t nss_5g;
+	struct scheduler_msg msg = {0};
+
+	add_sta_self_req = qdf_mem_malloc(sizeof(struct add_sta_self_params));
+	if (!add_sta_self_req)
+		return QDF_STATUS_E_NOMEM;
+
+	if (!(pMac->mlme_cfg)) {
+		pe_err("Mlme cfg NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	csr_get_vdev_type_nss(pMac, pMac->sme.currDeviceMode,
+			&nss_2g, &nss_5g);
+	qdf_mem_copy(add_sta_self_req->self_mac_addr, sessionMacAddr,
+			sizeof(tSirMacAddr));
+	add_sta_self_req->curr_device_mode = pMac->sme.currDeviceMode;
+	add_sta_self_req->session_id = sessionId;
+	add_sta_self_req->type = type;
+	add_sta_self_req->sub_type = subType;
+	add_sta_self_req->nss_2g = nss_2g;
+	add_sta_self_req->nss_5g = nss_5g;
+
+	add_sta_self_req->tx_aggregation_size = qos_aggr->tx_aggregation_size;
+	add_sta_self_req->tx_aggregation_size_be =
+			qos_aggr->tx_aggregation_size_be;
+	add_sta_self_req->tx_aggregation_size_bk =
+			qos_aggr->tx_aggregation_size_bk;
+	add_sta_self_req->tx_aggregation_size_vi =
+			qos_aggr->tx_aggregation_size_vi;
+	add_sta_self_req->tx_aggregation_size_vo =
+			qos_aggr->tx_aggregation_size_vo;
+
+	add_sta_self_req->rx_aggregation_size = qos_aggr->rx_aggregation_size;
+	add_sta_self_req->tx_aggr_sw_retry_threshold_be =
+			qos_aggr->tx_aggr_sw_retry_threshold_be;
+	add_sta_self_req->tx_aggr_sw_retry_threshold_bk =
+			qos_aggr->tx_aggr_sw_retry_threshold_bk;
+	add_sta_self_req->tx_aggr_sw_retry_threshold_vi =
+			qos_aggr->tx_aggr_sw_retry_threshold_vi;
+	add_sta_self_req->tx_aggr_sw_retry_threshold_vo =
+			qos_aggr->tx_aggr_sw_retry_threshold_vo;
+	add_sta_self_req->tx_non_aggr_sw_retry_threshold_be =
+			qos_aggr->tx_non_aggr_sw_retry_threshold_be;
+	add_sta_self_req->tx_non_aggr_sw_retry_threshold_bk =
+			qos_aggr->tx_non_aggr_sw_retry_threshold_bk;
+	add_sta_self_req->tx_non_aggr_sw_retry_threshold_vi =
+			qos_aggr->tx_non_aggr_sw_retry_threshold_vi;
+	add_sta_self_req->tx_non_aggr_sw_retry_threshold_vo =
+			qos_aggr->tx_non_aggr_sw_retry_threshold_vo;
+
+	add_sta_self_req->enable_bcast_probe_rsp =
+			pMac->mlme_cfg->oce.enable_bcast_probe_rsp;
+	add_sta_self_req->fils_max_chan_guard_time =
+			pMac->mlme_cfg->sta.fils_max_chan_guard_time;
+	add_sta_self_req->pkt_err_disconn_th =
+			pMac->mlme_cfg->gen.dropped_pkt_disconnect_thresh;
+	add_sta_self_req->oce_feature_bitmap =
+			pMac->mlme_cfg->oce.feature_bitmap;
+
+	msg.type = WMA_ADD_STA_SELF_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = add_sta_self_req;
+	msg.bodyval = 0;
+
+	sme_debug(
+		"Send WMA_ADD_STA_SELF_REQ for selfMac=" MAC_ADDRESS_STR,
+		 MAC_ADDR_ARRAY(add_sta_self_req->self_mac_addr));
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &msg);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("wma_post_ctrl_msg failed");
+		qdf_mem_free(add_sta_self_req);
+		add_sta_self_req = NULL;
+	}
+	return status;
+}
+
+QDF_STATUS csr_roam_open_session(tpAniSirGlobal mac_ctx,
+				 struct sme_session_params *session_param)
+{
+	QDF_STATUS status;
+	uint32_t existing_session_id;
+	struct mlme_ht_capabilities_info *ht_cap_info;
+	struct csr_roam_session *session;
+	struct mlme_vht_capabilities_info vht_cap_info;
+
+	if (!(mac_ctx->mlme_cfg)) {
+		pe_err("invalid mlme cfg");
+		return QDF_STATUS_E_FAILURE;
+	}
+	vht_cap_info = mac_ctx->mlme_cfg->vht_caps.vht_cap_info;
+
+	/* check to see if the mac address already belongs to a session */
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+			(struct qdf_mac_addr *)session_param->self_mac_addr,
+			&existing_session_id);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Session %d exists with mac address " MAC_ADDRESS_STR,
+			existing_session_id,
+			MAC_ADDR_ARRAY(session_param->self_mac_addr));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* attempt to retrieve session for Id */
+	session = CSR_GET_SESSION(mac_ctx, session_param->sme_session_id);
+	if (!session) {
+		sme_err("Session does not exist for interface %d",
+			session_param->sme_session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* check to see if the session is already active */
+	if (session->sessionActive) {
+		sme_err("Cannot re-open active session with Id %d",
+			session_param->sme_session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	session->sessionActive = true;
+	session->sessionId = session_param->sme_session_id;
+
+	/* Initialize FT related data structures only in STA mode */
+	sme_ft_open(MAC_HANDLE(mac_ctx), session->sessionId);
+
+	session->session_open_cb = session_param->session_open_cb;
+	session->session_close_cb = session_param->session_close_cb;
+	session->callback = session_param->callback;
+	session->pContext = session_param->callback_ctx;
+
+	qdf_mem_copy(&session->selfMacAddr, session_param->self_mac_addr,
+		     sizeof(struct qdf_mac_addr));
+	status = qdf_mc_timer_init(&session->hTimerRoaming,
+				   QDF_TIMER_TYPE_SW,
+				   csr_roam_roaming_timer_handler,
+				   &session->roamingTimerInfo);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("cannot allocate memory for Roaming timer");
+		return status;
+	}
+
+	status = qdf_mc_timer_init(&session->roaming_offload_timer,
+				   QDF_TIMER_TYPE_SW,
+				   csr_roam_roaming_offload_timeout_handler,
+				   &session->roamingTimerInfo);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("mem fail for roaming timer");
+		return status;
+	}
+
+	ht_cap_info = &mac_ctx->mlme_cfg->ht_caps.ht_cap_info;
+	session->htConfig.ht_rx_ldpc = ht_cap_info->adv_coding_cap;
+	session->htConfig.ht_tx_stbc = ht_cap_info->tx_stbc;
+	session->htConfig.ht_rx_stbc = ht_cap_info->rx_stbc;
+	session->htConfig.ht_sgi20 = ht_cap_info->short_gi_20_mhz;
+	session->htConfig.ht_sgi40 = ht_cap_info->short_gi_40_mhz;
+
+#ifdef FEATURE_WLAN_BTAMP_UT_RF
+	status = qdf_mc_timer_init(&session->hTimerJoinRetry, QDF_TIMER_TYPE_SW,
+				   csr_roam_join_retry_timer_handler,
+				   &session->joinRetryTimerInfo);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("cannot allocate memory for join retry timer");
+		return status;
+	}
+#endif /* FEATURE_WLAN_BTAMP_UT_RF */
+
+	session->vht_config.max_mpdu_len = vht_cap_info.ampdu_len;
+	session->vht_config.supported_channel_widthset =
+			vht_cap_info.supp_chan_width;
+	session->vht_config.ldpc_coding = vht_cap_info.ldpc_coding_cap;
+	session->vht_config.shortgi80 = vht_cap_info.short_gi_80mhz;
+	session->vht_config.shortgi160and80plus80 =
+			vht_cap_info.short_gi_160mhz;
+	session->vht_config.tx_stbc = vht_cap_info.tx_stbc;
+	session->vht_config.rx_stbc = vht_cap_info.rx_stbc;
+	session->vht_config.su_beam_former = vht_cap_info.su_bformer;
+	session->vht_config.su_beam_formee = vht_cap_info.su_bformee;
+	session->vht_config.csnof_beamformer_antSup =
+		vht_cap_info.tx_bfee_ant_supp;
+	session->vht_config.num_soundingdim = vht_cap_info.num_soundingdim;
+	session->vht_config.mu_beam_former = vht_cap_info.mu_bformer;
+	session->vht_config.mu_beam_formee = vht_cap_info.enable_mu_bformee;
+	session->vht_config.vht_txops = vht_cap_info.txop_ps;
+	session->vht_config.htc_vhtcap = vht_cap_info.htc_vhtc;
+	session->vht_config.rx_antpattern = vht_cap_info.rx_antpattern;
+	session->vht_config.tx_antpattern = vht_cap_info.tx_antpattern;
+
+	session->vht_config.max_ampdu_lenexp = vht_cap_info.ampdu_len_exponent;
+
+	csr_update_session_he_cap(mac_ctx, session);
+
+	return csr_issue_add_sta_for_session_req(mac_ctx,
+				session_param->sme_session_id,
+				session_param->self_mac_addr,
+				session_param->type_of_persona,
+				session_param->subtype_of_persona);
+}
+
+QDF_STATUS csr_process_del_sta_session_rsp(tpAniSirGlobal mac_ctx,
+					   uint8_t *pMsg)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct del_sta_self_params *rsp;
+	uint8_t sessionId;
+	tListElem *entry;
+	tSmeCmd *sme_command;
+
+	if (pMsg == NULL) {
+		sme_err("msg ptr is NULL");
+		return status;
+	}
+
+	entry = csr_nonscan_active_ll_peek_head(mac_ctx, LL_ACCESS_LOCK);
+	if (!entry) {
+		sme_err("NO commands are ACTIVE");
+		return status;
+	}
+
+	sme_command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+	if (e_sme_command_del_sta_session != sme_command->command) {
+		sme_err("No Del sta session command ACTIVE");
+		return status;
+	}
+
+	rsp = (struct del_sta_self_params *) pMsg;
+	sessionId = rsp->session_id;
+	sme_debug("Del Sta rsp status = %d", rsp->status);
+
+	/*
+	 * This session is done. This will also flush all the pending command
+	 * for this vdev, as vdev is deleted and no command should be sent
+	 * for this vdev. Active cmnd is e_sme_command_del_sta_session and will
+	 * be removed anyway next.
+	 */
+	csr_cleanup_session(mac_ctx, sessionId);
+
+	/* Remove this command out of the non scan active list */
+	if (csr_nonscan_active_ll_remove_entry(mac_ctx, entry,
+					       LL_ACCESS_LOCK)) {
+		csr_release_command(mac_ctx, sme_command);
+	}
+
+	if (rsp->sme_callback) {
+		status = sme_release_global_lock(&mac_ctx->sme);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			sme_debug("Failed to Release Lock");
+		else {
+			rsp->sme_callback(rsp->session_id);
+			status = sme_acquire_global_lock(&mac_ctx->sme);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				sme_debug("Failed to get Lock");
+				return status;
+			}
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
+static QDF_STATUS
+csr_issue_del_sta_for_session_req(tpAniSirGlobal mac_ctx, uint32_t session_id,
+				  tSirMacAddr session_mac_addr,
+				  csr_session_close_cb callback,
+				  void *context)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeCmd *sme_command;
+
+	sme_command = csr_get_command_buffer(mac_ctx);
+	if (NULL == sme_command) {
+		status = QDF_STATUS_E_RESOURCES;
+	} else {
+		sme_command->command = e_sme_command_del_sta_session;
+		sme_command->sessionId = (uint8_t)session_id;
+		sme_command->u.delStaSessionCmd.session_close_cb = callback;
+		sme_command->u.delStaSessionCmd.context = context;
+		qdf_mem_copy(sme_command->u.delStaSessionCmd.selfMacAddr,
+			     session_mac_addr, sizeof(tSirMacAddr));
+		status = csr_queue_sme_command(mac_ctx, sme_command, false);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			sme_err("fail to send message status = %d", status);
+	}
+	return status;
+}
+
+void csr_cleanup_session(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		struct csr_roam_session *pSession = CSR_GET_SESSION(pMac,
+								sessionId);
+
+		csr_roam_stop(pMac, sessionId);
+
+		/* Clean up FT related data structures */
+		sme_ft_close(MAC_HANDLE(pMac), sessionId);
+		csr_free_connect_bss_desc(pMac, sessionId);
+		csr_roam_free_connect_profile(&pSession->connectedProfile);
+		csr_roam_free_connected_info(pMac, &pSession->connectedInfo);
+		qdf_mc_timer_destroy(&pSession->hTimerRoaming);
+		qdf_mc_timer_destroy(&pSession->roaming_offload_timer);
+#ifdef FEATURE_WLAN_BTAMP_UT_RF
+		qdf_mc_timer_destroy(&pSession->hTimerJoinRetry);
+#endif
+		csr_purge_vdev_pending_ser_cmd_list(pMac, sessionId);
+		csr_init_session(pMac, sessionId);
+	}
+}
+
+QDF_STATUS csr_roam_close_session(tpAniSirGlobal mac_ctx,
+				  uint32_t session_id, bool sync)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *session;
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_debug("session %d not found", session_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+	/* Vdev going down stop roaming */
+	session->fCancelRoaming = true;
+	if (sync) {
+		csr_cleanup_session(mac_ctx, session_id);
+		return status;
+	}
+
+	if (CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id)) {
+		sme_debug("Stop Wait for key timer and change substate to eCSR_ROAM_SUBSTATE_NONE");
+		csr_roam_stop_wait_for_key_timer(mac_ctx);
+		csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE,
+					 session_id);
+	}
+
+	/*
+	 * Flush only scan commands. Non scan commands should go in sequence
+	 * as expected by firmware and should not be flushed.
+	 */
+	csr_purge_vdev_all_scan_ser_cmd_list(mac_ctx, session_id);
+	if (!session->session_close_cb) {
+		sme_err("no close session callback registered");
+		return QDF_STATUS_E_FAILURE;
+	}
+	status = csr_issue_del_sta_for_session_req(mac_ctx,
+			session_id, session->selfMacAddr.bytes,
+			session->session_close_cb, NULL);
+	return status;
+}
+
+static void csr_init_session(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+
+	pSession->sessionActive = false;
+	pSession->sessionId = CSR_SESSION_ID_INVALID;
+	pSession->callback = NULL;
+	pSession->pContext = NULL;
+	pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+	csr_saved_scan_cmd_free_fields(pMac, pSession);
+	csr_free_roam_profile(pMac, sessionId);
+	csr_roam_free_connect_profile(&pSession->connectedProfile);
+	csr_roam_free_connected_info(pMac, &pSession->connectedInfo);
+	csr_free_connect_bss_desc(pMac, sessionId);
+	qdf_mem_set(&pSession->selfMacAddr, sizeof(struct qdf_mac_addr), 0);
+	if (pSession->pWpaRsnReqIE) {
+		qdf_mem_free(pSession->pWpaRsnReqIE);
+		pSession->pWpaRsnReqIE = NULL;
+	}
+	pSession->nWpaRsnReqIeLength = 0;
+	if (pSession->pWpaRsnRspIE) {
+		qdf_mem_free(pSession->pWpaRsnRspIE);
+		pSession->pWpaRsnRspIE = NULL;
+	}
+	pSession->nWpaRsnRspIeLength = 0;
+#ifdef FEATURE_WLAN_WAPI
+	if (pSession->pWapiReqIE) {
+		qdf_mem_free(pSession->pWapiReqIE);
+		pSession->pWapiReqIE = NULL;
+	}
+	pSession->nWapiReqIeLength = 0;
+	if (pSession->pWapiRspIE) {
+		qdf_mem_free(pSession->pWapiRspIE);
+		pSession->pWapiRspIE = NULL;
+	}
+	pSession->nWapiRspIeLength = 0;
+#endif /* FEATURE_WLAN_WAPI */
+	if (pSession->pAddIEScan) {
+		qdf_mem_free(pSession->pAddIEScan);
+		pSession->pAddIEScan = NULL;
+	}
+	pSession->nAddIEScanLength = 0;
+	if (pSession->pAddIEAssoc) {
+		qdf_mem_free(pSession->pAddIEAssoc);
+		pSession->pAddIEAssoc = NULL;
+	}
+	pSession->nAddIEAssocLength = 0;
+}
+
+QDF_STATUS csr_roam_get_session_id_from_bssid(tpAniSirGlobal pMac,
+					      struct qdf_mac_addr *bssid,
+					      uint32_t *pSessionId)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint32_t i;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)) {
+			if (qdf_is_macaddr_equal(bssid,
+				    &pMac->roam.roamSession[i].connectedProfile.
+				    bssid)) {
+				/* Found it */
+				status = QDF_STATUS_SUCCESS;
+				*pSessionId = i;
+				break;
+			}
+		}
+	}
+	return status;
+}
+
+/* This function assumes that we only support one IBSS session.
+ * We cannot use BSSID to identify session because for IBSS,
+ * the bssid changes.
+ */
+static uint32_t csr_find_ibss_session(tpAniSirGlobal pMac)
+{
+	uint32_t i, nRet = CSR_SESSION_ID_INVALID;
+	struct csr_roam_session *pSession;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)) {
+			pSession = CSR_GET_SESSION(pMac, i);
+			if (pSession->pCurRoamProfile
+			    &&
+			    (csr_is_bss_type_ibss
+				     (pSession->connectedProfile.BSSType))) {
+				/* Found it */
+				nRet = i;
+				break;
+			}
+		}
+	}
+	return nRet;
+}
+
+static void csr_roam_link_up(tpAniSirGlobal pMac, struct qdf_mac_addr bssid)
+{
+	uint32_t sessionId = 0;
+
+	/*
+	 * Update the current BSS info in ho control block based on connected
+	 * profile info from pmac global structure
+	 */
+
+	sme_debug("WLAN link UP with AP= " MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(bssid.bytes));
+	/* Check for user misconfig of RSSI trigger threshold */
+	pMac->roam.configParam.vccRssiThreshold =
+		(0 == pMac->roam.configParam.vccRssiThreshold) ?
+		CSR_VCC_RSSI_THRESHOLD :
+		pMac->roam.configParam.vccRssiThreshold;
+	/* Check for user misconfig of UL MAC Loss trigger threshold */
+	pMac->roam.configParam.vccUlMacLossThreshold =
+		(0 == pMac->roam.configParam.vccUlMacLossThreshold) ?
+		CSR_VCC_UL_MAC_LOSS_THRESHOLD : pMac->roam.configParam.
+		vccUlMacLossThreshold;
+	/* Indicate the neighbor roal algorithm about the connect indication */
+	csr_roam_get_session_id_from_bssid(pMac, &bssid,
+					   &sessionId);
+	csr_neighbor_roam_indicate_connect(pMac, sessionId,
+					   QDF_STATUS_SUCCESS);
+}
+
+static void csr_roam_link_down(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return;
+	}
+	/* Only to handle the case for Handover on infra link */
+	if (eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType)
+		return;
+	/*
+	 * Incase of station mode, immediately stop data transmission whenever
+	 * link down is detected.
+	 */
+	if (csr_roam_is_sta_mode(pMac, sessionId)
+	    && !CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId)
+	    && !csr_roam_is11r_assoc(pMac, sessionId)) {
+		sme_debug("Inform Link lost for session %d",
+			sessionId);
+		csr_roam_call_callback(pMac, sessionId, NULL, 0,
+				       eCSR_ROAM_LOSTLINK,
+				       eCSR_ROAM_RESULT_LOSTLINK);
+	}
+	/* deregister the clients requesting stats from PE/TL & also stop the
+	 * corresponding timers
+	 */
+	csr_roam_dereg_statistics_req(pMac);
+	/* Indicate the neighbor roal algorithm about the disconnect
+	 * indication
+	 */
+	csr_neighbor_roam_indicate_disconnect(pMac, sessionId);
+
+	/* Remove this code once SLM_Sessionization is supported */
+	/* BMPS_WORKAROUND_NOT_NEEDED */
+	if (!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) &&
+	    csr_is_infra_ap_started(pMac) &&
+	    pMac->roam.configParam.doBMPSWorkaround) {
+		pMac->roam.configParam.doBMPSWorkaround = 0;
+	}
+
+}
+
+#ifndef QCA_SUPPORT_CP_STATS
+QDF_STATUS csr_send_mb_stats_req_msg(tpAniSirGlobal pMac, uint32_t statsMask,
+				     uint8_t staId, uint8_t sessionId)
+{
+	tAniGetPEStatsReq *pMsg;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	pMsg = qdf_mem_malloc(sizeof(tAniGetPEStatsReq));
+	if (!pMsg)
+		return QDF_STATUS_E_NOMEM;
+
+	/* need to initiate a stats request to PE */
+	pMsg->msgType = eWNI_SME_GET_STATISTICS_REQ;
+	pMsg->msgLen = (uint16_t) sizeof(tAniGetPEStatsReq);
+	pMsg->staId = staId;
+	pMsg->statsMask = statsMask;
+	pMsg->sessionId = sessionId;
+	status = umac_send_mb_message_to_mac(pMsg);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		sme_debug("Failed to send down the stats req ");
+
+	return status;
+}
+
+/**
+ * csr_update_stats() - updates correct stats struct in mac_ctx
+ * @mac:             mac global context
+ * @stats_type:      stats type
+ * @sme_stats_rsp:   stats rsp msg packet
+ * @stats:           input stats data buffer to fill in mac_ctx struct
+ * @length:          out param - stats length
+ *
+ * This function fills corresponding stats struct in mac_cts based on stats type
+ * passed
+ *
+ * Return: void
+ */
+static void
+csr_update_stats(tpAniSirGlobal mac, uint8_t stats_type,
+		 tAniGetPEStatsRsp *sme_stats_rsp,
+		 uint8_t **stats, uint32_t *length)
+{
+	switch (stats_type) {
+	case eCsrSummaryStats:
+		sme_debug("summary stats");
+		qdf_mem_copy((uint8_t *) &mac->roam.summaryStatsInfo, *stats,
+			     sizeof(tCsrSummaryStatsInfo));
+		*stats += sizeof(tCsrSummaryStatsInfo);
+		*length -= sizeof(tCsrSummaryStatsInfo);
+		break;
+	case eCsrGlobalClassAStats:
+		sme_debug("ClassA stats");
+		qdf_mem_copy((uint8_t *) &mac->roam.classAStatsInfo, *stats,
+			     sizeof(tCsrGlobalClassAStatsInfo));
+		*stats += sizeof(tCsrGlobalClassAStatsInfo);
+		*length -= sizeof(tCsrGlobalClassAStatsInfo);
+		break;
+	case csr_per_chain_rssi_stats:
+		sme_debug("csrRoamStatsRspProcessor:Per Chain RSSI stats");
+		qdf_mem_copy((uint8_t *)&mac->roam.per_chain_rssi_stats,
+			*stats, sizeof(struct csr_per_chain_rssi_stats_info));
+		*stats += sizeof(struct csr_per_chain_rssi_stats_info);
+		*length -= sizeof(struct csr_per_chain_rssi_stats_info);
+		break;
+	default:
+		sme_warn("unknown stats type");
+		break;
+	}
+}
+
+/**
+ * csr_roam_stats_rsp_processor() - processes stats rsp msg
+ * @pMac             mac global context
+ * @pSirMsg:         incoming message
+ *
+ * Return: void
+ */
+void csr_roam_stats_rsp_processor(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg)
+{
+	tAniGetPEStatsRsp *pSmeStatsRsp;
+	tListElem *pEntry = NULL;
+	struct csr_statsclient_reqinfo *pTempStaEntry = NULL;
+	struct csr_pestats_reqinfo *pPeStaEntry = NULL;
+	uint32_t tempMask = 0;
+	uint8_t counter = 0;
+	uint8_t *pStats = NULL;
+	uint32_t length = 0;
+	int8_t rssi = 0, snr = 0;
+	uint32_t *pRssi = NULL, *pSnr = NULL;
+	uint32_t linkCapacity;
+
+	pSmeStatsRsp = (tAniGetPEStatsRsp *) pSirMsg;
+	if (pSmeStatsRsp->rc) {
+		sme_warn("stats rsp from PE shows failure");
+		goto post_update;
+	}
+	tempMask = pSmeStatsRsp->statsMask;
+	pStats = ((uint8_t *) &pSmeStatsRsp->statsMask) +
+		sizeof(pSmeStatsRsp->statsMask);
+	/*
+	 * subtract all statistics from this length, and after processing the
+	 * entire 'stat' part of the message, if the length is not zero, then
+	 * rssi is piggy packed in this 'stats' message.
+	 */
+	length = pSmeStatsRsp->msgLen - sizeof(tAniGetPEStatsRsp);
+	/* new stats info from PE, fill up the stats strucutres in PMAC */
+	while (tempMask) {
+		if (tempMask & 1)
+			csr_update_stats(pMac, counter, pSmeStatsRsp,
+					 &pStats, &length);
+		tempMask >>= 1;
+		counter++;
+	}
+	if (length != 0) {
+		pRssi = (uint32_t *) pStats;
+		rssi = (int8_t) *pRssi;
+		pStats += sizeof(uint32_t);
+		length -= sizeof(uint32_t);
+	} else
+		/* If riva is not sending rssi, continue to use the hack */
+		rssi = RSSI_HACK_BMPS;
+
+	if (length != 0) {
+		linkCapacity = *(uint32_t *) pStats;
+		pStats += sizeof(uint32_t);
+		length -= sizeof(uint32_t);
+	} else
+		linkCapacity = 0;
+
+	if (length != 0) {
+		pSnr = (uint32_t *) pStats;
+		snr = (int8_t) *pSnr;
+	} else
+		snr = SNR_HACK_BMPS;
+
+post_update:
+	/* make sure to update the pe stats req list */
+	pEntry = csr_roam_find_in_pe_stats_req_list(pMac,
+						pSmeStatsRsp->statsMask);
+	if (pEntry) {
+		pPeStaEntry = GET_BASE_ADDR(pEntry,
+					struct csr_pestats_reqinfo, link);
+		pPeStaEntry->rspPending = false;
+
+	}
+	/* check the one timer cases */
+	pEntry = csr_roam_check_client_req_list(pMac, pSmeStatsRsp->statsMask);
+	if (pEntry) {
+		pTempStaEntry =
+			GET_BASE_ADDR(pEntry,
+					struct csr_statsclient_reqinfo, link);
+		if (pTempStaEntry->timerExpired) {
+			/* send up the stats report */
+			csr_roam_report_statistics(pMac,
+						pTempStaEntry->statsMask,
+						   pTempStaEntry->callback,
+						   pTempStaEntry->staId,
+						   pTempStaEntry->pContext);
+			/* also remove from the client list */
+			csr_roam_remove_stat_list_entry(pMac, pEntry);
+			pTempStaEntry = NULL;
+		}
+	}
+}
+
+tListElem *csr_roam_find_in_pe_stats_req_list(
+	tpAniSirGlobal pMac, uint32_t statsMask)
+{
+	tListElem *pEntry = NULL;
+	struct csr_pestats_reqinfo *pTempStaEntry = NULL;
+
+	pEntry = csr_ll_peek_head(&pMac->roam.peStatsReqList, LL_ACCESS_LOCK);
+	if (!pEntry) {
+		sme_debug("List empty, no request to PE");
+		return NULL;
+	}
+	while (pEntry) {
+	pTempStaEntry = GET_BASE_ADDR(pEntry, struct csr_pestats_reqinfo, link);
+		if (pTempStaEntry->statsMask == statsMask)
+			break;
+		pEntry =
+			csr_ll_next(&pMac->roam.peStatsReqList, pEntry,
+				    LL_ACCESS_NOLOCK);
+	}
+	return pEntry;
+}
+
+static
+tListElem *csr_roam_checkn_update_client_req_list(
+tpAniSirGlobal pMac, struct csr_statsclient_reqinfo *pStaEntry,
+						  bool update)
+{
+	tListElem *pEntry;
+	struct csr_statsclient_reqinfo *pTempStaEntry;
+
+	pEntry = csr_ll_peek_head(&pMac->roam.statsClientReqList,
+				LL_ACCESS_LOCK);
+	if (!pEntry) {
+		/* list empty */
+		sme_debug("List empty, no request from upper layer client(s)");
+		return NULL;
+	}
+	while (pEntry) {
+		pTempStaEntry =
+			GET_BASE_ADDR(pEntry,
+				struct csr_statsclient_reqinfo, link);
+		if ((pTempStaEntry->requesterId == pStaEntry->requesterId)
+		    && (pTempStaEntry->statsMask == pStaEntry->statsMask)) {
+			if (update) {
+				pTempStaEntry->callback = pStaEntry->callback;
+				pTempStaEntry->pContext = pStaEntry->pContext;
+			}
+			break;
+		}
+		pEntry =
+			csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
+				    LL_ACCESS_NOLOCK);
+	}
+	return pEntry;
+}
+
+tListElem *csr_roam_check_client_req_list(tpAniSirGlobal pMac,
+					uint32_t statsMask)
+{
+	tListElem *pEntry;
+	struct csr_statsclient_reqinfo *pTempStaEntry;
+
+	pEntry = csr_ll_peek_head(&pMac->roam.statsClientReqList,
+						LL_ACCESS_LOCK);
+	if (!pEntry) {
+		/* list empty */
+		sme_debug("List empty, no request from upper layer client(s)");
+		return NULL;
+	}
+	while (pEntry) {
+		pTempStaEntry =
+			GET_BASE_ADDR(pEntry,
+				      struct csr_statsclient_reqinfo, link);
+		if ((pTempStaEntry->
+		     statsMask & ~(1 << eCsrGlobalClassDStats)) == statsMask) {
+			break;
+		}
+		pEntry =
+			csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
+				    LL_ACCESS_NOLOCK);
+	}
+	return pEntry;
+}
+
+struct csr_statsclient_reqinfo *csr_roam_insert_entry_into_list(
+	tpAniSirGlobal pMac, tDblLinkList *pStaList,
+	struct csr_statsclient_reqinfo *
+	pStaEntry)
+{
+	struct csr_statsclient_reqinfo *pNewStaEntry = NULL;
+	/*
+	 * 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)) {
+
+	pNewStaEntry = qdf_mem_malloc(sizeof(struct csr_statsclient_reqinfo));
+		if (!pNewStaEntry)
+			return NULL;
+
+		pNewStaEntry->callback = pStaEntry->callback;
+		pNewStaEntry->pContext = pStaEntry->pContext;
+		pNewStaEntry->requesterId = pStaEntry->requesterId;
+		pNewStaEntry->statsMask = pStaEntry->statsMask;
+		pNewStaEntry->pPeStaEntry = pStaEntry->pPeStaEntry;
+		pNewStaEntry->pMac = pStaEntry->pMac;
+		pNewStaEntry->staId = pStaEntry->staId;
+		pNewStaEntry->timerExpired = pStaEntry->timerExpired;
+
+		csr_ll_insert_tail(pStaList, &pNewStaEntry->link,
+							LL_ACCESS_LOCK);
+	}
+	return pNewStaEntry;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+QDF_STATUS csr_get_rssi(tpAniSirGlobal pMac,
+			tCsrRssiCallback callback,
+			uint8_t staId,
+			struct qdf_mac_addr bssId,
+			int8_t lastRSSI, void *pContext)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msg = {0};
+	uint32_t sessionId;
+	tAniGetRssiReq *pMsg;
+
+	status = csr_roam_get_session_id_from_bssid(pMac, &bssId, &sessionId);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		callback(lastRSSI, staId, pContext);
+		sme_err("Failed to get SessionId");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pMsg = qdf_mem_malloc(sizeof(tAniGetRssiReq));
+	if (NULL == pMsg) {
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	pMsg->msgType = eWNI_SME_GET_RSSI_REQ;
+	pMsg->msgLen = (uint16_t) sizeof(tAniGetRssiReq);
+	pMsg->sessionId = sessionId;
+	pMsg->staId = staId;
+	pMsg->rssiCallback = callback;
+	pMsg->pDevContext = pContext;
+	/*
+	 * store RSSI at time of calling, so that if RSSI request cannot
+	 * be sent to firmware, this value can be used to return immediately
+	 */
+	pMsg->lastRSSI = lastRSSI;
+	msg.type = eWNI_SME_GET_RSSI_REQ;
+	msg.bodyptr = pMsg;
+	msg.reserved = 0;
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_SME,
+							 &msg)) {
+		sme_err("scheduler_post_msg failed to post msg to self");
+		qdf_mem_free((void *)pMsg);
+		status = QDF_STATUS_E_FAILURE;
+	}
+	return status;
+}
+
+QDF_STATUS csr_get_snr(tpAniSirGlobal pMac,
+		       tCsrSnrCallback callback,
+		       uint8_t staId, struct qdf_mac_addr bssId, void *pContext)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msg = {0};
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	tAniGetSnrReq *pMsg;
+
+	pMsg = qdf_mem_malloc(sizeof(tAniGetSnrReq));
+	if (!pMsg)
+		return QDF_STATUS_E_NOMEM;
+
+	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;
+	}
+
+	pMsg->msgType = eWNI_SME_GET_SNR_REQ;
+	pMsg->msgLen = (uint16_t) sizeof(tAniGetSnrReq);
+	pMsg->sessionId = sessionId;
+	pMsg->staId = staId;
+	pMsg->snrCallback = callback;
+	pMsg->pDevContext = pContext;
+	msg.type = eWNI_SME_GET_SNR_REQ;
+	msg.bodyptr = pMsg;
+	msg.reserved = 0;
+
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_SME,
+							 &msg)) {
+		sme_err("failed to post msg to self");
+		qdf_mem_free((void *)pMsg);
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * csr_deregister_client_request() - deregisters a get stats request
+ * @mac_ctx:       mac global context
+ * @sta_entry:     stats request entry
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS
+csr_deregister_client_request(tpAniSirGlobal mac_ctx,
+			      struct csr_statsclient_reqinfo *sta_entry)
+{
+	QDF_STATUS status;
+	tListElem *entry = NULL;
+	struct csr_statsclient_reqinfo *ptr_sta_entry = NULL;
+
+	entry = csr_roam_checkn_update_client_req_list(mac_ctx, sta_entry,
+						      false);
+	if (!entry) {
+	sme_err("callback is empty in the request & couldn't find any existing request in statsClientReqList");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* clean up & return */
+	ptr_sta_entry = GET_BASE_ADDR(entry,
+				      struct csr_statsclient_reqinfo, link);
+	if (NULL != ptr_sta_entry->pPeStaEntry) {
+		ptr_sta_entry->pPeStaEntry->numClient--;
+		/* check if we need to delete the entry from peStatsReqList */
+		if (!ptr_sta_entry->pPeStaEntry->numClient)
+			csr_roam_remove_entry_from_pe_stats_req_list(mac_ctx,
+						ptr_sta_entry->pPeStaEntry);
+	}
+	/* check if we need to stop the tl stats timer too */
+	mac_ctx->roam.tlStatsReqInfo.numClient--;
+	qdf_mc_timer_stop(&ptr_sta_entry->timer);
+	/* Destroy the qdf timer... */
+	status = qdf_mc_timer_destroy(&ptr_sta_entry->timer);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		sme_err(
+			"failed to destroy Client req timer");
+
+	csr_roam_remove_stat_list_entry(mac_ctx, entry);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_insert_stats_request_to_list() - inserts request to existing list
+ * @mac_ctx:       mac global context
+ * @sta_entry:     stats request entry
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS
+csr_insert_stats_request_to_list(tpAniSirGlobal mac_ctx,
+				 struct csr_statsclient_reqinfo *sta_entry)
+{
+struct csr_statsclient_reqinfo *ptr_sta_entry = csr_roam_insert_entry_into_list(
+				mac_ctx, &mac_ctx->roam.statsClientReqList,
+				sta_entry);
+	if (!ptr_sta_entry) {
+		sme_err("Failed to insert req in statsClientReqList");
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS csr_get_statistics(tpAniSirGlobal pMac,
+			      eCsrStatsRequesterType requesterId,
+			      uint32_t statsMask,
+			      tCsrStatsCallback callback,
+			      uint8_t staId,
+			      void *pContext,
+			      uint8_t sessionId)
+{
+	struct csr_statsclient_reqinfo staEntry;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	bool insertInClientList = false;
+	uint32_t temp_mask = 0;
+
+	if (csr_is_all_session_disconnected(pMac))
+		return QDF_STATUS_E_FAILURE;
+
+	if (csr_neighbor_middle_of_roaming(pMac, sessionId)) {
+		sme_debug("in the middle of roaming states");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if ((!statsMask) && (!callback)) {
+		sme_err("statsMask & callback empty in the request");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* for the search list method for deregister */
+	staEntry.requesterId = requesterId;
+	staEntry.statsMask = statsMask;
+	/* requester wants to deregister or just an error */
+	if ((statsMask) && (!callback))
+		return csr_deregister_client_request(pMac, &staEntry);
+
+	/* add the request in the client req list */
+	staEntry.callback = callback;
+	staEntry.pContext = pContext;
+	staEntry.pPeStaEntry = NULL;
+	staEntry.staId = staId;
+	staEntry.pMac = pMac;
+	staEntry.timerExpired = false;
+	staEntry.sessionId = sessionId;
+
+	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 (insertInClientList)
+		return csr_insert_stats_request_to_list(pMac, &staEntry);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * csr_roam_set_key_mgmt_offload() - enable/disable key mgmt offload
+ * @mac_ctx: mac context.
+ * @session_id: Session Identifier
+ * @roam_key_mgmt_offload_enabled: key mgmt enable/disable flag
+ * @pmkid_modes: PMKID modes of PMKSA caching and OKC
+ *
+ * Return: QDF_STATUS_SUCCESS - CSR updated config successfully.
+ * Other status means CSR is failed to update.
+ */
+
+QDF_STATUS csr_roam_set_key_mgmt_offload(tpAniSirGlobal mac_ctx,
+					 uint32_t session_id,
+					 bool roam_key_mgmt_offload_enabled,
+					 struct pmkid_mode_bits *pmkid_modes)
+{
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (!session) {
+		sme_err("session %d not found", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	session->RoamKeyMgmtOffloadEnabled = roam_key_mgmt_offload_enabled;
+	session->pmkid_modes.fw_okc = pmkid_modes->fw_okc;
+	session->pmkid_modes.fw_pmksa_cache = pmkid_modes->fw_pmksa_cache;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_update_roam_scan_ese_params() - Update ESE related params in RSO request
+ * @req_buf: Roam Scan Offload Request buffer
+ * @session: Current Roam Session
+ *
+ * This API will set the KRK and BTK required in case of Auth Type is CCKM.
+ * It will also clear the PMK Len as CCKM PMK Caching is not supported
+ *
+ * Return: None
+ */
+#ifdef FEATURE_WLAN_ESE
+static
+void csr_update_roam_scan_ese_params(tSirRoamOffloadScanReq *req_buf,
+				     struct csr_roam_session *session)
+{
+	if (csr_is_auth_type_ese(req_buf->ConnectedNetwork.authentication)) {
+		qdf_mem_copy(req_buf->KRK, session->eseCckmInfo.krk,
+			     SIR_KRK_KEY_LEN);
+		qdf_mem_copy(req_buf->BTK, session->eseCckmInfo.btk,
+			     SIR_BTK_KEY_LEN);
+		req_buf->pmkid_modes.fw_okc = 0;
+		req_buf->pmkid_modes.fw_pmksa_cache = 0;
+		req_buf->pmk_len = 0;
+		qdf_mem_zero(&req_buf->PSK_PMK[0], sizeof(req_buf->PSK_PMK));
+	}
+}
+#else
+static inline
+void csr_update_roam_scan_ese_params(tSirRoamOffloadScanReq *req_buf,
+				     struct csr_roam_session *session)
+{
+}
+#endif
+
+/**
+ * csr_update_roam_scan_offload_request() - updates req msg with roam offload
+ * parameters
+ * @pMac:          mac global context
+ * @req_buf:       out param, roam offload scan request packet
+ * @session:       roam session
+ *
+ * Return: void
+ */
+static void
+csr_update_roam_scan_offload_request(tpAniSirGlobal mac_ctx,
+				     tSirRoamOffloadScanReq *req_buf,
+				     struct csr_roam_session *session)
+{
+	qdf_mem_copy(req_buf->PSK_PMK, session->psk_pmk,
+		     sizeof(req_buf->PSK_PMK));
+	req_buf->pmk_len = session->pmk_len;
+	req_buf->R0KH_ID_Length = session->ftSmeContext.r0kh_id_len;
+	qdf_mem_copy(req_buf->R0KH_ID,
+		     session->ftSmeContext.r0kh_id,
+		     req_buf->R0KH_ID_Length);
+	req_buf->Prefer5GHz = mac_ctx->roam.configParam.nRoamPrefer5GHz;
+	req_buf->RoamRssiCatGap = mac_ctx->roam.configParam.bCatRssiOffset;
+	req_buf->Select5GHzMargin = mac_ctx->mlme_cfg->gen.select_5ghz_margin;
+	req_buf->ho_delay_for_rx = mac_ctx->roam.configParam.ho_delay_for_rx;
+	req_buf->roam_preauth_retry_count =
+			mac_ctx->mlme_cfg->lfr.roam_preauth_retry_count;
+	req_buf->roam_preauth_no_ack_timeout =
+			mac_ctx->mlme_cfg->lfr.roam_preauth_no_ack_timeout;
+	req_buf->min_delay_btw_roam_scans =
+			mac_ctx->roam.configParam.min_delay_btw_roam_scans;
+	req_buf->roam_trigger_reason_bitmask =
+			mac_ctx->roam.configParam.roam_trigger_reason_bitmask;
+	req_buf->roam_force_rssi_trigger =
+			mac_ctx->roam.configParam.roam_force_rssi_trigger;
+	req_buf->ReassocFailureTimeout =
+		mac_ctx->mlme_cfg->timeouts.reassoc_failure_timeout;
+	csr_update_roam_scan_ese_params(req_buf, session);
+
+	req_buf->AcUapsd.acbe_uapsd = SIR_UAPSD_GET(ACBE, session->uapsd_mask);
+	req_buf->AcUapsd.acbk_uapsd = SIR_UAPSD_GET(ACBK, session->uapsd_mask);
+	req_buf->AcUapsd.acvi_uapsd = SIR_UAPSD_GET(ACVI, session->uapsd_mask);
+	req_buf->AcUapsd.acvo_uapsd = SIR_UAPSD_GET(ACVO, session->uapsd_mask);
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * csr_check_band_channel_match() - check if passed band and channel match
+ * parameters
+ * @band:       band to match with channel
+ * @channel:    channel to match with band
+ *
+ * Return: bool if match else false
+ */
+static bool
+csr_check_band_channel_match(enum band_info band, uint8_t channel)
+{
+	if (BAND_ALL == band)
+		return true;
+
+	if (BAND_2G == band && WLAN_REG_IS_24GHZ_CH(channel))
+		return true;
+
+	if (BAND_5G == band && WLAN_REG_IS_5GHZ_CH(channel))
+		return true;
+
+	return false;
+}
+
+/**
+ * csr_fetch_ch_lst_from_ini() - fetch channel list from ini and update req msg
+ * parameters
+ * @mac_ctx:      global mac ctx
+ * @roam_info:    roam info struct
+ * @req_buf:      out param, roam offload scan request packet
+ *
+ * Return: result of operation
+ */
+static QDF_STATUS
+csr_fetch_ch_lst_from_ini(tpAniSirGlobal mac_ctx,
+			  tpCsrNeighborRoamControlInfo roam_info,
+			  tSirRoamOffloadScanReq *req_buf)
+{
+	enum band_info band;
+	uint8_t i = 0;
+	uint8_t num_channels = 0;
+	uint8_t *ch_lst = roam_info->cfgParams.channelInfo.ChannelList;
+	uint16_t  unsafe_chan[NUM_CHANNELS];
+	uint16_t  unsafe_chan_cnt = 0;
+	uint16_t  cnt = 0;
+	bool      is_unsafe_chan;
+	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	if (!qdf_ctx) {
+		cds_err("qdf_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
+			&unsafe_chan_cnt,
+			 sizeof(unsafe_chan));
+
+	/*
+	 * The INI channels need to be filtered with respect to the current band
+	 * that is supported.
+	 */
+	band = mac_ctx->mlme_cfg->gen.band_capability;
+	if ((BAND_2G != band) && (BAND_5G != band)
+	    && (BAND_ALL != band)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			 "Invalid band(%d), roam scan offload req aborted",
+			  band);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (i = 0; i < roam_info->cfgParams.channelInfo.numOfChannels; i++) {
+		if (!csr_check_band_channel_match(band, *ch_lst))
+			continue;
+		/* Allow DFS channels only if the DFS roaming is enabled */
+		if ((!mac_ctx->roam.configParam.allowDFSChannelRoam ||
+		    (mac_ctx->roam.configParam.sta_roam_policy.dfs_mode ==
+			 CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
+		     (wlan_reg_is_dfs_ch(mac_ctx->pdev, *ch_lst))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				("ignoring dfs channel %d"), *ch_lst);
+			ch_lst++;
+			continue;
+		}
+
+		if (mac_ctx->roam.configParam.sta_roam_policy.
+				skip_unsafe_channels &&
+				unsafe_chan_cnt) {
+			is_unsafe_chan = false;
+			for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
+				if (unsafe_chan[cnt] == *ch_lst) {
+					is_unsafe_chan = true;
+					break;
+				}
+			}
+			if (is_unsafe_chan) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+						QDF_TRACE_LEVEL_DEBUG,
+					("ignoring unsafe channel %d"),
+					*ch_lst);
+				ch_lst++;
+				continue;
+			}
+		}
+		req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
+			*ch_lst;
+		ch_lst++;
+
+	}
+	req_buf->ConnectedNetwork.ChannelCount = num_channels;
+	req_buf->ChannelCacheType = CHANNEL_LIST_STATIC;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_fetch_ch_lst_from_occupied_lst() - fetch channel list from occupied list
+ * and update req msg
+ * parameters
+ * @mac_ctx:      global mac ctx
+ * @session_id:   session id
+ * @reason:       reason to roam
+ * @req_buf:      out param, roam offload scan request packet
+ * @roam_info:    roam info struct
+ *
+ * Return: void
+ */
+static void
+csr_fetch_ch_lst_from_occupied_lst(tpAniSirGlobal mac_ctx,
+				   uint8_t session_id,
+				   uint8_t reason,
+				   tSirRoamOffloadScanReq *req_buf,
+				   tpCsrNeighborRoamControlInfo roam_info)
+{
+	uint8_t i = 0;
+	uint8_t num_channels = 0;
+	uint8_t *ch_lst =
+		mac_ctx->scan.occupiedChannels[session_id].channelList;
+	uint16_t  unsafe_chan[NUM_CHANNELS];
+	uint16_t  unsafe_chan_cnt = 0;
+	uint16_t  cnt = 0;
+	bool      is_unsafe_chan;
+	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+
+	if (!qdf_ctx) {
+		cds_err("qdf_ctx is NULL");
+		return;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		"Num of channels before filtering=%d",
+		mac_ctx->scan.occupiedChannels[session_id].numChannels);
+	pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
+			&unsafe_chan_cnt,
+			 sizeof(unsafe_chan));
+	for (i = 0; i < mac_ctx->scan.occupiedChannels[session_id].numChannels;
+	     i++) {
+		if ((!mac_ctx->roam.configParam.allowDFSChannelRoam ||
+		    (mac_ctx->roam.configParam.sta_roam_policy.dfs_mode ==
+			 CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
+		     (wlan_reg_is_dfs_ch(mac_ctx->pdev, *ch_lst))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				("ignoring dfs channel %d"), *ch_lst);
+			ch_lst++;
+			continue;
+		}
+
+		if (mac_ctx->roam.configParam.sta_roam_policy.
+				skip_unsafe_channels &&
+				unsafe_chan_cnt) {
+			is_unsafe_chan = false;
+			for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
+				if (unsafe_chan[cnt] == *ch_lst) {
+					is_unsafe_chan = true;
+					break;
+				}
+			}
+			if (is_unsafe_chan) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+						QDF_TRACE_LEVEL_DEBUG,
+					("ignoring unsafe channel %d"),
+					*ch_lst);
+				ch_lst++;
+				continue;
+			}
+		}
+		req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
+			*ch_lst;
+		if (*ch_lst)
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"DFSRoam=%d, ChnlState=%d, Chnl=%d, num_ch=%d",
+				mac_ctx->roam.configParam.allowDFSChannelRoam,
+				wlan_reg_get_channel_state(mac_ctx->pdev,
+					*ch_lst),
+				*ch_lst,
+				num_channels);
+		ch_lst++;
+	}
+	req_buf->ConnectedNetwork.ChannelCount = num_channels;
+	req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC;
+}
+
+/**
+ * csr_fetch_valid_ch_lst() - fetch channel list from valid channel list and
+ * update req msg
+ * parameters
+ * @mac_ctx:            global mac ctx
+ * @req_buf:            out param, roam offload scan request packet
+ *
+ * Return: void
+ */
+static QDF_STATUS
+csr_fetch_valid_ch_lst(tpAniSirGlobal mac_ctx,
+		       tSirRoamOffloadScanReq *req_buf,
+		       uint8_t session_id)
+{
+	QDF_STATUS status;
+	uint32_t host_channels = 0;
+	uint8_t *ch_lst = NULL;
+	uint8_t i = 0, num_channels = 0;
+	uint16_t  unsafe_chan[NUM_CHANNELS];
+	uint16_t  unsafe_chan_cnt = 0;
+	uint16_t  cnt = 0;
+	bool      is_unsafe_chan;
+	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	enum band_info band = BAND_ALL;
+
+	if (!qdf_ctx) {
+		cds_err("qdf_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
+			&unsafe_chan_cnt,
+			sizeof(unsafe_chan));
+
+	host_channels = sizeof(mac_ctx->roam.validChannelList);
+	status = csr_get_cfg_valid_channels(mac_ctx,
+					    mac_ctx->roam.validChannelList,
+					    &host_channels);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			 "Failed to get the valid channel list");
+		return status;
+	}
+
+	if (CSR_IS_ROAM_INTRA_BAND_ENABLED(mac_ctx)) {
+		band = csr_get_rf_band(mac_ctx->roam.roamSession[session_id].
+				connectedProfile.operationChannel);
+		sme_debug("updated band %d operational ch %d", band,
+				mac_ctx->roam.roamSession[session_id].
+				connectedProfile.operationChannel);
+	}
+
+	ch_lst = mac_ctx->roam.validChannelList;
+	mac_ctx->roam.numValidChannels = host_channels;
+
+	for (i = 0; i < mac_ctx->roam.numValidChannels; i++) {
+		if (!csr_check_band_channel_match(band, *ch_lst)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				("ignoring non-intra band channel %d"),
+				*ch_lst);
+			ch_lst++;
+			continue;
+		}
+
+		if ((!mac_ctx->roam.configParam.allowDFSChannelRoam ||
+		    (mac_ctx->roam.configParam.sta_roam_policy.dfs_mode ==
+			 CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
+		     (wlan_reg_is_dfs_ch(mac_ctx->pdev, *ch_lst))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				("ignoring dfs channel %d"), *ch_lst);
+			ch_lst++;
+			continue;
+		}
+
+		if (mac_ctx->roam.configParam.
+				sta_roam_policy.skip_unsafe_channels &&
+				unsafe_chan_cnt) {
+			is_unsafe_chan = false;
+			for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
+				if (unsafe_chan[cnt] == *ch_lst) {
+					is_unsafe_chan = true;
+					break;
+				}
+			}
+			if (is_unsafe_chan) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+						QDF_TRACE_LEVEL_DEBUG,
+					("ignoring unsafe channel %d"),
+					*ch_lst);
+				ch_lst++;
+				continue;
+			}
+		}
+		req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
+			*ch_lst;
+		ch_lst++;
+	}
+	req_buf->ValidChannelCount = num_channels;
+
+	req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC;
+	req_buf->ConnectedNetwork.ChannelCount = num_channels;
+	return status;
+}
+
+/**
+ * csr_create_roam_scan_offload_request() - init roam offload scan request
+ *
+ * parameters
+ * @mac_ctx:      global mac ctx
+ * @command:      roam scan offload command input
+ * @session_id:   session id
+ * @reason:       reason to roam
+ * @session:      roam session
+ * @roam_info:    roam info struct
+ *
+ * Return: roam offload scan request packet buffer
+ */
+static tSirRoamOffloadScanReq *
+csr_create_roam_scan_offload_request(tpAniSirGlobal mac_ctx,
+				     uint8_t command,
+				     uint8_t session_id,
+				     uint8_t reason,
+				     struct csr_roam_session *session,
+				     tpCsrNeighborRoamControlInfo roam_info)
+{
+	QDF_STATUS status;
+	uint8_t i, j, dot11_mode;
+	bool ese_neighbor_list_recvd = false;
+	uint8_t ch_cache_str[128] = { 0 };
+	tSirRoamOffloadScanReq *req_buf = NULL;
+	tpCsrChannelInfo curr_ch_lst_info =
+		&roam_info->roamChannelInfo.currentChannelListInfo;
+#ifdef FEATURE_WLAN_ESE
+	/*
+	 * this flag will be true if connection is ESE and no neighbor
+	 * list received or if the connection is not ESE
+	 */
+	ese_neighbor_list_recvd = ((roam_info->isESEAssoc)
+		&& (roam_info->roamChannelInfo.IAPPNeighborListReceived
+		    == false))
+		|| (roam_info->isESEAssoc == false);
+#endif /* FEATURE_WLAN_ESE */
+
+	req_buf = qdf_mem_malloc(sizeof(tSirRoamOffloadScanReq));
+	if (!req_buf)
+		return NULL;
+
+	req_buf->Command = command;
+	/*
+	 * If command is STOP, then pass down ScanOffloadEnabled as Zero. This
+	 * will handle the case of host driver reloads, but Riva still up and
+	 * running
+	 */
+	if (command == ROAM_SCAN_OFFLOAD_STOP) {
+		/*
+		 * clear the roaming parameters that are per connection.
+		 * For a new connection, they have to be programmed again.
+		 */
+		if (csr_neighbor_middle_of_roaming(mac_ctx,
+						   session_id))
+			req_buf->middle_of_roaming = 1;
+		else
+			csr_roam_reset_roam_params(mac_ctx);
+		req_buf->RoamScanOffloadEnabled = 0;
+	} else if (command == ROAM_SCAN_OFFLOAD_UPDATE_CFG) {
+		req_buf->RoamScanOffloadEnabled =
+			roam_info->b_roam_scan_offload_started;
+	} else {
+		req_buf->RoamScanOffloadEnabled =
+			mac_ctx->roam.configParam.isRoamOffloadScanEnabled;
+	}
+	qdf_mem_copy(req_buf->ConnectedNetwork.currAPbssid,
+		     roam_info->currAPbssid.bytes, sizeof(struct qdf_mac_addr));
+	req_buf->ConnectedNetwork.ssId.length =
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.SSID.length;
+	qdf_mem_copy(req_buf->ConnectedNetwork.ssId.ssId,
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.SSID.ssId,
+		req_buf->ConnectedNetwork.ssId.length);
+	req_buf->ConnectedNetwork.authentication =
+		mac_ctx->roam.roamSession[session_id].connectedProfile.AuthType;
+	req_buf->ConnectedNetwork.encryption =
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.EncryptionType;
+	req_buf->ConnectedNetwork.mcencryption =
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.mcEncryptionType;
+	/* Copy the RSN capabilities in roam offload request from session*/
+	req_buf->rsn_caps = session->rsn_caps;
+#ifdef WLAN_FEATURE_11W
+	req_buf->ConnectedNetwork.mfp_enabled =
+	    mac_ctx->roam.roamSession[session_id].connectedProfile.MFPEnabled;
+#endif
+	req_buf->delay_before_vdev_stop =
+		roam_info->cfgParams.delay_before_vdev_stop;
+	req_buf->OpportunisticScanThresholdDiff =
+		roam_info->cfgParams.nOpportunisticThresholdDiff;
+	req_buf->RoamRescanRssiDiff =
+		roam_info->cfgParams.nRoamRescanRssiDiff;
+	req_buf->RoamRssiDiff = mac_ctx->roam.configParam.RoamRssiDiff;
+	req_buf->rssi_abs_thresh =
+		mac_ctx->mlme_cfg->lfr.roam_rssi_abs_threshold;
+	req_buf->reason = reason;
+	req_buf->NeighborScanTimerPeriod =
+		roam_info->cfgParams.neighborScanPeriod;
+	req_buf->neighbor_scan_min_timer_period =
+		roam_info->cfgParams.neighbor_scan_min_period;
+	req_buf->NeighborRoamScanRefreshPeriod =
+		roam_info->cfgParams.neighborResultsRefreshPeriod;
+	req_buf->NeighborScanChannelMinTime =
+		roam_info->cfgParams.minChannelScanTime;
+	req_buf->NeighborScanChannelMaxTime =
+		roam_info->cfgParams.maxChannelScanTime;
+	req_buf->EmptyRefreshScanPeriod =
+		roam_info->cfgParams.emptyScanRefreshPeriod;
+	req_buf->RoamBmissFirstBcnt =
+		roam_info->cfgParams.nRoamBmissFirstBcnt;
+	req_buf->RoamBmissFinalBcnt =
+		roam_info->cfgParams.nRoamBmissFinalBcnt;
+	req_buf->RoamBeaconRssiWeight =
+		roam_info->cfgParams.nRoamBeaconRssiWeight;
+	csr_copy_mawc_config(mac_ctx, &req_buf->mawc_roam_params);
+	sme_debug("MAWC:global=%d,roam=%d,traffic=%d,ap_rssi=%d,high=%d,low=%d",
+			req_buf->mawc_roam_params.mawc_enabled,
+			req_buf->mawc_roam_params.mawc_roam_enabled,
+			req_buf->mawc_roam_params.mawc_roam_traffic_threshold,
+			req_buf->mawc_roam_params.mawc_roam_ap_rssi_threshold,
+			req_buf->mawc_roam_params.mawc_roam_rssi_high_adjust,
+			req_buf->mawc_roam_params.mawc_roam_rssi_low_adjust);
+#ifdef FEATURE_WLAN_ESE
+	req_buf->IsESEAssoc =
+		csr_roam_is_ese_assoc(mac_ctx, session_id) &&
+		((req_buf->ConnectedNetwork.authentication ==
+			eCSR_AUTH_TYPE_OPEN_SYSTEM)  ||
+		(csr_is_auth_type_ese(req_buf->
+			ConnectedNetwork.authentication)));
+	req_buf->is_11r_assoc = roam_info->is11rAssoc;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"IsEseAssoc: %d is_11r_assoc: %d middle of roaming: %d ese_neighbor_list_recvd: %d cur no of chan: %d",
+			req_buf->IsESEAssoc, req_buf->is_11r_assoc,
+			req_buf->middle_of_roaming,
+			ese_neighbor_list_recvd,
+			curr_ch_lst_info->numOfChannels);
+#endif
+
+	if (!CSR_IS_ROAM_INTRA_BAND_ENABLED(mac_ctx)) {
+		if (ese_neighbor_list_recvd ||
+		    curr_ch_lst_info->numOfChannels == 0) {
+			/*
+			 * Retrieve the Channel Cache either from ini or from
+			 * the occupied channels list.
+			 * Give Preference to INI Channels
+			 */
+			if (roam_info->cfgParams.channelInfo.numOfChannels) {
+				status = csr_fetch_ch_lst_from_ini(mac_ctx,
+								   roam_info,
+								   req_buf);
+				if (!QDF_IS_STATUS_SUCCESS(status)) {
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_DEBUG,
+						  "Fetch channel list from ini failed");
+					qdf_mem_free(req_buf);
+					return NULL;
+				}
+			} else {
+				csr_fetch_ch_lst_from_occupied_lst(mac_ctx,
+						session_id, reason, req_buf,
+						roam_info);
+			}
+		}
+#ifdef FEATURE_WLAN_ESE
+		else {
+			/*
+			 * If ESE is enabled, and a neighbor Report is received,
+			 * then Ignore the INI Channels or the Occupied Channel
+			 * List. Consider the channels in the neighbor list sent
+			 * by the ESE AP
+			 */
+			csr_fetch_ch_lst_from_received_list(mac_ctx, roam_info,
+					curr_ch_lst_info, req_buf);
+		}
+#endif
+	}
+	if (req_buf->ConnectedNetwork.ChannelCount == 0) {
+		/* Maintain the Valid Channels List */
+		status = csr_fetch_valid_ch_lst(mac_ctx, req_buf, session_id);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+					"Fetch channel list fail");
+			qdf_mem_free(req_buf);
+			return NULL;
+		}
+	}
+
+	for (i = 0, j = 0; i < req_buf->ConnectedNetwork.ChannelCount; i++) {
+		if (j < sizeof(ch_cache_str)) {
+			j += snprintf(ch_cache_str + j,
+				      sizeof(ch_cache_str) - j, " %d",
+				      req_buf->ConnectedNetwork.
+				      ChannelCache[i]);
+		} else
+			break;
+	}
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		 FL("ChnlCacheType:%d, No of Chnls:%d,Channels: %s"),
+		  req_buf->ChannelCacheType,
+		  req_buf->ConnectedNetwork.ChannelCount, ch_cache_str);
+
+	req_buf->MDID.mdiePresent =
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.MDID.mdiePresent;
+	req_buf->MDID.mobilityDomain =
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.MDID.mobilityDomain;
+	req_buf->sessionId = session_id;
+	req_buf->nProbes = mac_ctx->roam.configParam.nProbes;
+	req_buf->HomeAwayTime = mac_ctx->roam.configParam.nRoamScanHomeAwayTime;
+
+	/*
+	 * Home Away Time should be at least equal to (MaxDwell time + (2*RFS)),
+	 * where RFS is the RF Switching time. It is twice RFS to consider the
+	 * time to go off channel and return to the home channel.
+	 */
+	if (req_buf->HomeAwayTime < (req_buf->NeighborScanChannelMaxTime +
+	     (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			 "Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d). Hence enforcing home away time to disable (0)",
+			  req_buf->HomeAwayTime,
+			  (req_buf->NeighborScanChannelMaxTime +
+			   (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME)));
+		req_buf->HomeAwayTime = 0;
+	}
+
+	/*Prepare a probe request for 2.4GHz band and one for 5GHz band */
+	dot11_mode = (uint8_t) csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
+				csr_find_best_phy_mode(mac_ctx,
+					mac_ctx->roam.configParam.phyMode));
+	req_buf->allowDFSChannelRoam =
+	mac_ctx->roam.configParam.allowDFSChannelRoam;
+	req_buf->early_stop_scan_enable =
+		mac_ctx->mlme_cfg->lfr.early_stop_scan_enable;
+	req_buf->early_stop_scan_min_threshold =
+		mac_ctx->mlme_cfg->lfr.early_stop_scan_min_threshold;
+	req_buf->early_stop_scan_max_threshold =
+		mac_ctx->mlme_cfg->lfr.early_stop_scan_max_threshold;
+	req_buf->roamscan_adaptive_dwell_mode =
+		mac_ctx->mlme_cfg->lfr.adaptive_roamscan_dwell_mode;
+	req_buf->lca_config_params.disallow_duration =
+		mac_ctx->mlme_cfg->lfr.lfr3_disallow_duration;
+	req_buf->lca_config_params.rssi_channel_penalization =
+		mac_ctx->mlme_cfg->lfr.lfr3_rssi_channel_penalization;
+	req_buf->lca_config_params.num_disallowed_aps =
+		mac_ctx->mlme_cfg->lfr.lfr3_num_disallowed_aps;
+
+	/* For RSO Stop, we need to notify FW to deinit BTM */
+	if (command == ROAM_SCAN_OFFLOAD_STOP)
+		req_buf->btm_offload_config = 0;
+	else
+		req_buf->btm_offload_config =
+			mac_ctx->roam.configParam.btm_offload_config;
+
+	req_buf->btm_solicited_timeout =
+		mac_ctx->roam.configParam.btm_solicited_timeout;
+	req_buf->btm_max_attempt_cnt =
+		mac_ctx->roam.configParam.btm_max_attempt_cnt;
+	req_buf->btm_sticky_time =
+		mac_ctx->roam.configParam.btm_sticky_time;
+
+#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;
+	/* Roam Offload piggybacks upon the Roam Scan offload command. */
+	if (req_buf->RoamOffloadEnabled)
+		csr_update_roam_scan_offload_request(mac_ctx, req_buf, session);
+	qdf_mem_copy(&req_buf->roam_params,
+		&mac_ctx->roam.configParam.roam_params,
+		sizeof(req_buf->roam_params));
+#endif
+	return req_buf;
+}
+
+/**
+ * csr_update_11k_offload_params - Update 11K offload params
+ * @mac_ctx: MAC context
+ * @session: Pointer to the CSR Roam Session
+ * @req_buffer: Pointer to the RSO Request buffer
+ * @enabled: 11k offload enabled/disabled.
+ *
+ * API to update 11k offload params to Roam Scan Offload request buffer
+ *
+ * Return: none
+ */
+static void csr_update_11k_offload_params(tpAniSirGlobal mac_ctx,
+					  struct csr_roam_session *session,
+					  tSirRoamOffloadScanReq *req_buffer,
+					  bool enabled)
+{
+	struct wmi_11k_offload_params *params = &req_buffer->offload_11k_params;
+	struct csr_config *csr_config = &mac_ctx->roam.configParam;
+	struct csr_neighbor_report_offload_params *neighbor_report_offload =
+		&csr_config->neighbor_report_offload;
+
+	params->vdev_id = session->sessionId;
+
+	if (enabled) {
+		params->offload_11k_bitmask =
+				csr_config->offload_11k_enable_bitmask;
+	} else {
+		params->offload_11k_bitmask = 0;
+		sme_debug("11k offload disabled in RSO");
+		return;
+	}
+
+	/*
+	 * If none of the parameters are enabled, then set the
+	 * offload_11k_bitmask to 0, so that we don't send the command
+	 * to the FW and drop it in WMA
+	 */
+	if ((neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_ALL) == 0) {
+		sme_err("No valid neighbor report offload params %x",
+			neighbor_report_offload->params_bitmask);
+		params->offload_11k_bitmask = 0;
+		return;
+	}
+
+	/*
+	 * First initialize all params to NEIGHBOR_REPORT_PARAM_INVALID
+	 * Then set the values that are enabled
+	 */
+	params->neighbor_report_params.time_offset =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+	params->neighbor_report_params.low_rssi_offset =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+	params->neighbor_report_params.bmiss_count_trigger =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+	params->neighbor_report_params.per_threshold_offset =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+	params->neighbor_report_params.neighbor_report_cache_timeout =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+	params->neighbor_report_params.max_neighbor_report_req_cap =
+		NEIGHBOR_REPORT_PARAM_INVALID;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_TIME_OFFSET)
+		params->neighbor_report_params.time_offset =
+			neighbor_report_offload->time_offset;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_LOW_RSSI_OFFSET)
+		params->neighbor_report_params.low_rssi_offset =
+			neighbor_report_offload->low_rssi_offset;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_BMISS_COUNT_TRIGGER)
+		params->neighbor_report_params.bmiss_count_trigger =
+			neighbor_report_offload->bmiss_count_trigger;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_PER_THRESHOLD_OFFSET)
+		params->neighbor_report_params.per_threshold_offset =
+			neighbor_report_offload->per_threshold_offset;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_CACHE_TIMEOUT)
+		params->neighbor_report_params.neighbor_report_cache_timeout =
+			neighbor_report_offload->neighbor_report_cache_timeout;
+
+	if (neighbor_report_offload->params_bitmask &
+	    NEIGHBOR_REPORT_PARAMS_MAX_REQ_CAP)
+		params->neighbor_report_params.max_neighbor_report_req_cap =
+			neighbor_report_offload->max_neighbor_report_req_cap;
+
+	params->neighbor_report_params.ssid.length =
+		session->connectedProfile.SSID.length;
+	qdf_mem_copy(params->neighbor_report_params.ssid.mac_ssid,
+			session->connectedProfile.SSID.ssId,
+			session->connectedProfile.SSID.length);
+
+	sme_debug("Updated 11k offload params to RSO");
+}
+
+QDF_STATUS csr_invoke_neighbor_report_request(uint8_t session_id,
+				struct sRrmNeighborReq *neighbor_report_req,
+				bool send_resp_to_host)
+{
+	struct wmi_invoke_neighbor_report_params *invoke_params;
+	struct scheduler_msg msg = {0};
+
+	if (!neighbor_report_req) {
+		sme_err("Invalid params");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	invoke_params = qdf_mem_malloc(sizeof(*invoke_params));
+	if (!invoke_params)
+		return QDF_STATUS_E_NOMEM;
+
+	invoke_params->vdev_id = session_id;
+	invoke_params->send_resp_to_host = send_resp_to_host;
+
+	if (!neighbor_report_req->no_ssid) {
+		invoke_params->ssid.length = neighbor_report_req->ssid.length;
+		qdf_mem_copy(invoke_params->ssid.mac_ssid,
+				neighbor_report_req->ssid.ssId,
+				neighbor_report_req->ssid.length);
+	} else {
+		invoke_params->ssid.length = 0;
+	}
+
+	sme_debug("Sending SIR_HAL_INVOKE_NEIGHBOR_REPORT");
+
+	msg.type = SIR_HAL_INVOKE_NEIGHBOR_REPORT;
+	msg.reserved = 0;
+	msg.bodyptr = invoke_params;
+
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_WMA,
+							 QDF_MODULE_ID_WMA,
+							 &msg)) {
+		sme_err("Not able to post message to WMA");
+		qdf_mem_free(invoke_params);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * check_allowed_ssid_list() - Check the WhiteList
+ * @req_buffer:      Buffer which contains the connected profile SSID.
+ * @roam_params:     Buffer which contains the whitelist SSID's.
+ *
+ * Check if the connected profile SSID exists in the whitelist.
+ * It is assumed that the framework provides this also in the whitelist.
+ * If it exists there is no issue. Otherwise add it to the list.
+ *
+ * Return: None
+ */
+static void check_allowed_ssid_list(tSirRoamOffloadScanReq *req_buffer,
+		struct roam_ext_params *roam_params)
+{
+	int i = 0;
+	bool match = false;
+
+	for (i = 0; i < roam_params->num_ssid_allowed_list; i++) {
+		if ((roam_params->ssid_allowed_list[i].length ==
+			req_buffer->ConnectedNetwork.ssId.length) &&
+			(!qdf_mem_cmp(roam_params->ssid_allowed_list[i].ssId,
+				req_buffer->ConnectedNetwork.ssId.ssId,
+				roam_params->ssid_allowed_list[i].length))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"Whitelist contains connected profile SSID");
+			match = true;
+			break;
+		}
+	}
+	if (!match) {
+		if (roam_params->num_ssid_allowed_list >=
+				MAX_SSID_ALLOWED_LIST) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"Whitelist is FULL. Cannot Add another entry");
+			return;
+		}
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"Adding Connected profile SSID to whitelist");
+		/* i is the next available index to add the entry.*/
+		i = roam_params->num_ssid_allowed_list;
+		qdf_mem_copy(roam_params->ssid_allowed_list[i].ssId,
+				req_buffer->ConnectedNetwork.ssId.ssId,
+				req_buffer->ConnectedNetwork.ssId.length);
+		roam_params->ssid_allowed_list[i].length =
+			req_buffer->ConnectedNetwork.ssId.length;
+		roam_params->num_ssid_allowed_list++;
+	}
+}
+
+/**
+ * csr_add_rssi_reject_ap_list() - add rssi reject AP list to the
+ * roam params
+ * @mac_ctx: mac ctx.
+ * @roam_params: roam params in which reject AP list needs
+ * to be populated.
+ *
+ * Return: None
+ */
+static void csr_add_rssi_reject_ap_list(tpAniSirGlobal mac_ctx,
+	struct roam_ext_params *roam_params)
+{
+	int i = 0;
+	struct sir_rssi_disallow_lst *cur_node;
+	qdf_list_node_t *cur_list = NULL;
+	qdf_list_node_t *next_list = NULL;
+	struct rssi_disallow_bssid *rssi_rejection_ap;
+	qdf_list_t *list = &mac_ctx->roam.rssi_disallow_bssid;
+	qdf_time_t cur_time =
+		qdf_do_div(qdf_get_monotonic_boottime(),
+		QDF_MC_TIMER_TO_MS_UNIT);
+
+	roam_params->num_rssi_rejection_ap = qdf_list_size(list);
+
+	if (!qdf_list_size(list))
+		return;
+
+	if (roam_params->num_rssi_rejection_ap > MAX_RSSI_AVOID_BSSID_LIST)
+		roam_params->num_rssi_rejection_ap = MAX_RSSI_AVOID_BSSID_LIST;
+
+	qdf_list_peek_front(list, &cur_list);
+	while (cur_list) {
+		int32_t rem_time;
+
+		rssi_rejection_ap = &roam_params->rssi_rejection_ap[i];
+		cur_node = qdf_container_of(cur_list,
+				struct sir_rssi_disallow_lst, node);
+		rem_time = cur_node->retry_delay -
+			(cur_time - cur_node->time_during_rejection);
+
+		if (rem_time > 0) {
+			qdf_copy_macaddr(&rssi_rejection_ap->bssid,
+					&cur_node->bssid);
+			rssi_rejection_ap->expected_rssi =
+					cur_node->expected_rssi;
+			rssi_rejection_ap->remaining_duration = rem_time;
+			i++;
+		}
+		qdf_list_peek_next(list, cur_list, &next_list);
+		cur_list = next_list;
+		next_list = NULL;
+
+		if (i >= MAX_RSSI_AVOID_BSSID_LIST)
+			break;
+	}
+	for (i = 0; i < roam_params->num_rssi_rejection_ap; i++) {
+		sme_debug("BSSID %pM expected rssi %d remaining duration %d",
+			roam_params->rssi_rejection_ap[i].bssid.bytes,
+			roam_params->rssi_rejection_ap[i].expected_rssi,
+			roam_params->rssi_rejection_ap[i].remaining_duration);
+	}
+}
+
+/*
+ * 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     | 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 | 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 | \
+		RSO_ABORT_SCAN_BIT | RSO_RESTART_BIT)
+#define RSO_UPDATE_CFG_ALLOW_MASK  (RSO_UPDATE_CFG_BIT | RSO_STOP_BIT | \
+		RSO_START_BIT | RSO_ABORT_SCAN_BIT)
+#define RSO_ABORT_SCAN_ALLOW_MASK (RSO_START_BIT | RSO_RESTART_BIT | \
+		RSO_UPDATE_CFG_BIT | RSO_ABORT_SCAN_BIT)
+
+static bool csr_is_RSO_cmd_allowed(tpAniSirGlobal mac_ctx,
+	uint8_t command, uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo neigh_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	uint8_t desiredMask = 0;
+	bool ret_val;
+
+	switch (command) {
+	case ROAM_SCAN_OFFLOAD_START:
+		desiredMask = RSO_START_ALLOW_MASK;
+		break;
+	case ROAM_SCAN_OFFLOAD_STOP:
+		desiredMask = RSO_STOP_ALLOW_MASK;
+		break;
+	case ROAM_SCAN_OFFLOAD_RESTART:
+		desiredMask = RSO_RESTART_ALLOW_MASK;
+		break;
+	case ROAM_SCAN_OFFLOAD_UPDATE_CFG:
+		desiredMask = RSO_UPDATE_CFG_ALLOW_MASK;
+		break;
+	case ROAM_SCAN_OFFLOAD_ABORT_SCAN:
+		desiredMask = RSO_ABORT_SCAN_ALLOW_MASK;
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			("Wrong RSO command %d, not allowed"), command);
+		return 0;/*Cmd Not allowed*/
+	}
+	ret_val = desiredMask & (1 << neigh_roam_info->last_sent_cmd);
+	return ret_val;
+}
+
+/*
+ * csr_roam_send_rso_cmd() - API to send RSO command to PE
+ * @mac_ctx: Pointer to global MAC structure
+ * @session_id: Session ID
+ * @request_buf: Pointer to tSirRoamOffloadScanReq
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS csr_roam_send_rso_cmd(tpAniSirGlobal mac_ctx,
+					uint8_t session_id,
+					tSirRoamOffloadScanReq *request_buf)
+{
+	QDF_STATUS status;
+
+	request_buf->message_type = eWNI_SME_ROAM_SCAN_OFFLOAD_REQ;
+	request_buf->length = sizeof(*request_buf);
+
+	status = umac_send_mb_message_to_mac(request_buf);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("Send RSO from CSR failed");
+		return status;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_append_assoc_ies() - Append specific IE to assoc IE's buffer
+ * @mac_ctx: Pointer to global mac context
+ * @req_buf: Pointer to Roam offload scan request
+ * @ie_id: IE ID to be appended
+ * @ie_len: IE length to be appended
+ * @ie_data: IE data to be appended
+ *
+ * Return: None
+ */
+static void csr_append_assoc_ies(tpAniSirGlobal mac_ctx,
+				tSirRoamOffloadScanReq *req_buf, uint8_t ie_id,
+				uint8_t ie_len, uint8_t *ie_data)
+{
+	tSirAddie *assoc_ie = &req_buf->assoc_ie;
+
+	if ((SIR_MAC_MAX_ADD_IE_LENGTH - assoc_ie->length) < ie_len) {
+		sme_err("Appending IE id: %d fails", ie_id);
+		return;
+	}
+	assoc_ie->addIEdata[assoc_ie->length] = ie_id;
+	assoc_ie->addIEdata[assoc_ie->length + 1] = ie_len;
+	qdf_mem_copy(&assoc_ie->addIEdata[assoc_ie->length + 2],
+						ie_data, ie_len);
+	assoc_ie->length += (ie_len + 2);
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * ese_populate_addtional_ies() - add IEs to reassoc frame
+ * @mac_ctx: Pointer to global mac structure
+ * @session: pointer to CSR session
+ * @req_buf: Pointer to Roam offload scan request
+ *
+ * This function populates the TSPEC ie and appends the info
+ * to assoc buffer.
+ *
+ * Return: None
+ */
+static void ese_populate_addtional_ies(tpAniSirGlobal mac_ctx,
+				struct csr_roam_session *session,
+				tSirRoamOffloadScanReq *req_buf) {
+
+	uint8_t tspec_ie_hdr[SIR_MAC_OUI_WME_HDR_MIN]
+			= { 0x00, 0x50, 0xf2, 0x02, 0x02, 0x01 };
+	uint8_t tspec_ie_buf[DOT11F_IE_WMMTSPEC_MAX_LEN], j;
+	ese_wmm_tspec_ie *tspec_ie;
+	tESETspecInfo ese_tspec;
+
+	tspec_ie = (ese_wmm_tspec_ie *)(tspec_ie_buf + SIR_MAC_OUI_WME_HDR_MIN);
+	if (csr_is_wmm_supported(mac_ctx) &&
+		mac_ctx->roam.configParam.isEseIniFeatureEnabled &&
+		csr_roam_is_ese_assoc(mac_ctx, session->sessionId)) {
+		ese_tspec.numTspecs = sme_qos_ese_retrieve_tspec_info(mac_ctx,
+					session->sessionId,
+					(tTspecInfo *) &ese_tspec.tspec[0]);
+		qdf_mem_copy(tspec_ie_buf, tspec_ie_hdr,
+			SIR_MAC_OUI_WME_HDR_MIN);
+		for (j = 0; j < ese_tspec.numTspecs; j++) {
+			/* Populate the tspec_ie */
+			ese_populate_wmm_tspec(&ese_tspec.tspec[j].tspec,
+				tspec_ie);
+			csr_append_assoc_ies(mac_ctx, req_buf,
+					IEEE80211_ELEMID_VENDOR,
+					DOT11F_IE_WMMTSPEC_MAX_LEN,
+					tspec_ie_buf);
+		}
+	}
+
+}
+#else
+static inline void ese_populate_addtional_ies(
+	tpAniSirGlobal mac_ctx,
+	struct csr_roam_session *session, tSirRoamOffloadScanReq *req_buf) {
+}
+#endif
+/**
+ * csr_update_driver_assoc_ies() - Append driver built IE's to assoc IE's
+ * @mac_ctx: Pointer to global mac structure
+ * @session: pointer to CSR session
+ * @req_buf: Pointer to Roam offload scan request
+ *
+ * Return: None
+ */
+static void csr_update_driver_assoc_ies(tpAniSirGlobal mac_ctx,
+					struct csr_roam_session *session,
+					tSirRoamOffloadScanReq *req_buf)
+{
+	bool power_caps_populated = false;
+	uint32_t csr_11henable = WNI_CFG_11H_ENABLED_STADEF;
+
+	uint8_t *rrm_cap_ie_data
+			= (uint8_t *) &mac_ctx->rrm.rrmPEContext.rrmEnabledCaps;
+	uint8_t power_cap_ie_data[DOT11F_IE_POWERCAPS_MAX_LEN]
+			= {MIN_TX_PWR_CAP, MAX_TX_PWR_CAP};
+	uint8_t max_tx_pwr_cap = 0;
+	uint8_t supp_chan_ie[DOT11F_IE_SUPPCHANNELS_MAX_LEN], supp_chan_ie_len;
+
+#ifdef FEATURE_WLAN_ESE
+	uint8_t ese_ie[DOT11F_IE_ESEVERSION_MAX_LEN]
+			= { 0x0, 0x40, 0x96, 0x3, ESE_VERSION_SUPPORTED};
+#endif
+	uint8_t qcn_ie[DOT11F_IE_QCN_IE_MAX_LEN]
+			= {0x8C, 0xFD, 0xF0, 0x1, QCN_IE_VERSION_SUBATTR_ID,
+				QCN_IE_VERSION_SUBATTR_DATA_LEN,
+				QCN_IE_VERSION_SUPPORTED,
+				QCN_IE_SUBVERSION_SUPPORTED};
+
+	if (session->pConnectBssDesc)
+		max_tx_pwr_cap = csr_get_cfg_max_tx_power(mac_ctx,
+				session->pConnectBssDesc->channelId);
+
+	if (max_tx_pwr_cap && max_tx_pwr_cap < MAX_TX_PWR_CAP)
+		power_cap_ie_data[1] = max_tx_pwr_cap;
+	else
+		power_cap_ie_data[1] = MAX_TX_PWR_CAP;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_11H_ENABLED, &csr_11henable);
+
+	if (csr_11henable && csr_is11h_supported(mac_ctx)) {
+		/* Append power cap IE */
+		csr_append_assoc_ies(mac_ctx, req_buf, IEEE80211_ELEMID_PWRCAP,
+					DOT11F_IE_POWERCAPS_MAX_LEN,
+					power_cap_ie_data);
+		power_caps_populated = true;
+
+		/* Append Supported channels IE */
+		csr_add_supported_5Ghz_channels(mac_ctx, supp_chan_ie,
+					&supp_chan_ie_len, true);
+
+		csr_append_assoc_ies(mac_ctx, req_buf,
+					IEEE80211_ELEMID_SUPPCHAN,
+					supp_chan_ie_len, supp_chan_ie);
+	}
+
+#ifdef FEATURE_WLAN_ESE
+	/* Append ESE version IE if isEseIniFeatureEnabled INI is enabled */
+	if (mac_ctx->roam.configParam.isEseIniFeatureEnabled)
+		csr_append_assoc_ies(mac_ctx, req_buf, IEEE80211_ELEMID_VENDOR,
+					DOT11F_IE_ESEVERSION_MAX_LEN,
+					ese_ie);
+#endif
+
+	if (mac_ctx->rrm.rrmPEContext.rrmEnable) {
+		/* Append RRM IE */
+		csr_append_assoc_ies(mac_ctx, req_buf, IEEE80211_ELEMID_RRM,
+					DOT11F_IE_RRMENABLEDCAP_MAX_LEN,
+					rrm_cap_ie_data);
+		if (!power_caps_populated)
+			/* Append Power cap IE if not appended already */
+			csr_append_assoc_ies(mac_ctx, req_buf,
+					IEEE80211_ELEMID_PWRCAP,
+					DOT11F_IE_POWERCAPS_MAX_LEN,
+					power_cap_ie_data);
+	}
+	ese_populate_addtional_ies(mac_ctx, session, req_buf);
+
+	/* Append QCN IE if g_support_qcn_ie INI is enabled */
+	if (mac_ctx->mlme_cfg->sta.qcn_ie_support)
+		csr_append_assoc_ies(mac_ctx, req_buf, IEEE80211_ELEMID_VENDOR,
+					DOT11F_IE_QCN_IE_MAX_LEN,
+					qcn_ie);
+}
+
+/**
+ * csr_create_per_roam_request() - create PER roam offload scan request
+ *
+ * parameters
+ * @mac_ctx: global mac ctx
+ * @session_id: session id
+ *
+ * Return: per roam config request packet buffer
+ */
+static struct wmi_per_roam_config_req *
+csr_create_per_roam_request(tpAniSirGlobal mac_ctx,
+		uint8_t session_id)
+{
+	struct wmi_per_roam_config_req *req_buf = NULL;
+
+	req_buf = qdf_mem_malloc(sizeof(struct wmi_per_roam_config_req));
+	if (!req_buf)
+		return NULL;
+
+	req_buf->vdev_id = session_id;
+	req_buf->per_config.enable =
+		mac_ctx->mlme_cfg->lfr.per_roam_enable;
+	req_buf->per_config.tx_high_rate_thresh =
+		mac_ctx->mlme_cfg->lfr.per_roam_config_high_rate_th;
+	req_buf->per_config.rx_high_rate_thresh =
+		mac_ctx->mlme_cfg->lfr.per_roam_config_high_rate_th;
+	req_buf->per_config.tx_low_rate_thresh =
+		mac_ctx->mlme_cfg->lfr.per_roam_config_low_rate_th;
+	req_buf->per_config.rx_low_rate_thresh =
+		mac_ctx->mlme_cfg->lfr.per_roam_config_low_rate_th;
+	req_buf->per_config.per_rest_time =
+		mac_ctx->mlme_cfg->lfr.per_roam_rest_time;
+	req_buf->per_config.tx_per_mon_time =
+		mac_ctx->mlme_cfg->lfr.per_roam_monitor_time;
+	req_buf->per_config.rx_per_mon_time =
+		mac_ctx->mlme_cfg->lfr.per_roam_monitor_time;
+	req_buf->per_config.tx_rate_thresh_percnt =
+		mac_ctx->mlme_cfg->lfr.per_roam_config_rate_th_percent;
+	req_buf->per_config.rx_rate_thresh_percnt =
+		mac_ctx->mlme_cfg->lfr.per_roam_config_rate_th_percent;
+	req_buf->per_config.min_candidate_rssi =
+		mac_ctx->mlme_cfg->lfr.per_roam_min_candidate_rssi;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		"PER based roaming configuaration enable: %d vdev: %d high_rate_thresh: %d low_rate_thresh: %d rate_thresh_percnt: %d per_rest_time: %d monitor_time: %d min cand rssi: %d",
+			  req_buf->per_config.enable, session_id,
+			  req_buf->per_config.tx_high_rate_thresh,
+			  req_buf->per_config.tx_low_rate_thresh,
+			  req_buf->per_config.tx_rate_thresh_percnt,
+			  req_buf->per_config.per_rest_time,
+			  req_buf->per_config.tx_per_mon_time,
+			  req_buf->per_config.min_candidate_rssi);
+	return req_buf;
+}
+
+/**
+ * csr_roam_offload_per_scan() - populates roam offload scan request and sends
+ * to WMA
+ *
+ * parameters
+ * @mac_ctx:      global mac ctx
+ * @session_id:   session id
+ *
+ * Return: result of operation
+ */
+static QDF_STATUS
+csr_roam_offload_per_scan(tpAniSirGlobal mac_ctx, uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	struct wmi_per_roam_config_req *req_buf;
+	struct scheduler_msg msg = {0};
+
+	/*
+	 * No need to update in case of stop command, FW takes care of stopping
+	 * this internally
+	 */
+	if (roam_info->last_sent_cmd == ROAM_SCAN_OFFLOAD_STOP)
+		return QDF_STATUS_SUCCESS;
+
+	if (!mac_ctx->mlme_cfg->lfr.per_roam_enable) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			 "PER based roaming is disabled in configuration");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	req_buf = csr_create_per_roam_request(mac_ctx, session_id);
+	if (!req_buf) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			 "Failed to create req packet");
+		return QDF_STATUS_E_FAILURE;
+	}
+	msg.type = WMA_SET_PER_ROAM_CONFIG_CMD;
+	msg.reserved = 0;
+	msg.bodyptr = req_buf;
+	if (!QDF_IS_STATUS_SUCCESS(scheduler_post_message(QDF_MODULE_ID_SME,
+							  QDF_MODULE_ID_WMA,
+							  QDF_MODULE_ID_WMA,
+							  &msg))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"%s: Unable to post WMA_SET_PER_ROAM_CONFIG_CMD to WMA",
+			__func__);
+		qdf_mem_free(req_buf);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+#if defined(WLAN_FEATURE_FILS_SK)
+QDF_STATUS csr_update_fils_config(tpAniSirGlobal mac, uint8_t session_id,
+				  struct csr_roam_profile *src_profile)
+{
+	struct csr_roam_session *session = CSR_GET_SESSION(mac, session_id);
+	struct csr_roam_profile *dst_profile = NULL;
+
+	if (!session) {
+		sme_err("session NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	dst_profile = session->pCurRoamProfile;
+
+	if (!dst_profile) {
+		sme_err("Current Roam profile of SME session NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	update_profile_fils_info(dst_profile, src_profile);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * copy_all_before_char() - API to copy all character before a particular char
+ * @str: Source string
+ * @str_len: Source string legnth
+ * @dst: Destination string
+ * @dst_len: Destination string legnth
+ * @c: Character before which all characters need to be copied
+ *
+ * Return: length of the copied string, if success. zero otherwise.
+ */
+static uint32_t copy_all_before_char(char *str, uint32_t str_len,
+				     char *dst, uint32_t dst_len, char c)
+{
+	uint32_t len = 0;
+
+	if (!str)
+		return len;
+
+	while ((len < str_len) && (len < dst_len) &&
+	       (*str != '\0') && (*str != c)) {
+		*dst++ = *str++;
+		len++;
+	}
+
+	return len;
+}
+
+/**
+ * csr_update_fils_params_rso() - API to update FILS params in RSO
+ * @mac: Mac context
+ * @session: CSR Roam Session
+ * @req_buffer: RSO request buffer
+ *
+ * Return: None
+ */
+static void csr_update_fils_params_rso(tpAniSirGlobal mac,
+		struct csr_roam_session *session,
+		tSirRoamOffloadScanReq *req_buffer)
+{
+	struct roam_fils_params *roam_fils_params;
+	struct cds_fils_connection_info *fils_info;
+	uint32_t usr_name_len;
+
+	if (!session->pCurRoamProfile)
+		return;
+
+	fils_info = session->pCurRoamProfile->fils_con_info;
+	if (!fils_info || !req_buffer)
+		return;
+
+	if (!fils_info->key_nai_length) {
+		sme_debug("key_nai_length is NULL");
+		return;
+	}
+
+	roam_fils_params = &req_buffer->roam_fils_params;
+	if ((fils_info->key_nai_length > FILS_MAX_KEYNAME_NAI_LENGTH) ||
+			(fils_info->r_rk_length > FILS_MAX_RRK_LENGTH)) {
+		sme_err("Fils info len error: keyname nai len(%d) rrk len(%d)",
+			fils_info->key_nai_length, fils_info->r_rk_length);
+		return;
+	}
+
+	usr_name_len = copy_all_before_char(fils_info->keyname_nai,
+					    sizeof(fils_info->keyname_nai),
+					    roam_fils_params->username,
+					    sizeof(roam_fils_params->username),
+					    '@');
+	if (fils_info->key_nai_length <= usr_name_len) {
+		sme_err("Fils info len error: key nai len %d, user name len %d",
+			fils_info->key_nai_length, usr_name_len);
+		return;
+	}
+
+	roam_fils_params->username_length = usr_name_len;
+	req_buffer->is_fils_connection = true;
+
+	roam_fils_params->next_erp_seq_num =
+			(fils_info->sequence_number + 1);
+
+	roam_fils_params->rrk_length = fils_info->r_rk_length;
+	qdf_mem_copy(roam_fils_params->rrk, fils_info->r_rk,
+			roam_fils_params->rrk_length);
+
+	/* REALM info */
+	roam_fils_params->realm_len = fils_info->key_nai_length
+			- roam_fils_params->username_length - 1;
+	qdf_mem_copy(roam_fils_params->realm, fils_info->keyname_nai
+			+ roam_fils_params->username_length + 1,
+			roam_fils_params->realm_len);
+}
+#else
+static inline void csr_update_fils_params_rso(tpAniSirGlobal mac,
+		struct csr_roam_session *session,
+		tSirRoamOffloadScanReq *req_buffer)
+{}
+#endif
+
+/**
+ * csr_update_score_params() - API to update Score params in RSO
+ * @mac_ctx: Mac context
+ * @req_buffer: RSO request buffer
+ *
+ * Return: None
+ */
+static void csr_update_score_params(tpAniSirGlobal mac_ctx,
+				    tSirRoamOffloadScanReq *req_buffer)
+{
+	struct scoring_param *req_score_params;
+	struct rssi_scoring *req_rssi_score;
+	struct wlan_mlme_scoring_cfg *bss_score_params;
+	struct wlan_mlme_weight_config *weight_config;
+	struct wlan_mlme_rssi_cfg_score *rssi_score;
+
+	req_score_params = &req_buffer->score_params;
+	req_rssi_score = &req_score_params->rssi_scoring;
+
+	bss_score_params = &mac_ctx->mlme_cfg->scoring;
+	weight_config = &bss_score_params->weight_cfg;
+	rssi_score = &bss_score_params->rssi_score;
+
+	if (!bss_score_params->enable_scoring_for_roam)
+			req_score_params->disable_bitmap =
+				WLAN_ROAM_SCORING_DISABLE_ALL;
+
+	req_score_params->rssi_weightage = weight_config->rssi_weightage;
+	req_score_params->ht_weightage = weight_config->ht_caps_weightage;
+	req_score_params->vht_weightage = weight_config->vht_caps_weightage;
+	req_score_params->he_weightage = weight_config->he_caps_weightage;
+	req_score_params->bw_weightage = weight_config->chan_width_weightage;
+	req_score_params->band_weightage = weight_config->chan_band_weightage;
+	req_score_params->nss_weightage = weight_config->nss_weightage;
+	req_score_params->esp_qbss_weightage =
+		weight_config->channel_congestion_weightage;
+	req_score_params->beamforming_weightage =
+		weight_config->beamforming_cap_weightage;
+	req_score_params->pcl_weightage =
+		weight_config->pcl_weightage;
+	req_score_params->oce_wan_weightage = weight_config->oce_wan_weightage;
+
+	req_score_params->bw_index_score =
+		bss_score_params->bandwidth_weight_per_index;
+	req_score_params->band_index_score =
+		bss_score_params->band_weight_per_index;
+	req_score_params->nss_index_score =
+		bss_score_params->nss_weight_per_index;
+
+	req_rssi_score->best_rssi_threshold = rssi_score->best_rssi_threshold;
+	req_rssi_score->good_rssi_threshold = rssi_score->good_rssi_threshold;
+	req_rssi_score->bad_rssi_threshold = rssi_score->bad_rssi_threshold;
+	req_rssi_score->good_rssi_pcnt = rssi_score->good_rssi_pcnt;
+	req_rssi_score->bad_rssi_pcnt = rssi_score->bad_rssi_pcnt;
+	req_rssi_score->good_bucket_size = rssi_score->good_rssi_bucket_size;
+	req_rssi_score->bad_bucket_size = rssi_score->bad_rssi_bucket_size;
+	req_rssi_score->rssi_pref_5g_rssi_thresh =
+			rssi_score->rssi_pref_5g_rssi_thresh;
+
+	req_score_params->esp_qbss_scoring.num_slot =
+		bss_score_params->esp_qbss_scoring.num_slot;
+	req_score_params->esp_qbss_scoring.score_pcnt3_to_0 =
+		bss_score_params->esp_qbss_scoring.score_pcnt3_to_0;
+	req_score_params->esp_qbss_scoring.score_pcnt7_to_4 =
+		bss_score_params->esp_qbss_scoring.score_pcnt7_to_4;
+	req_score_params->esp_qbss_scoring.score_pcnt11_to_8 =
+		bss_score_params->esp_qbss_scoring.score_pcnt11_to_8;
+	req_score_params->esp_qbss_scoring.score_pcnt15_to_12 =
+		bss_score_params->esp_qbss_scoring.score_pcnt15_to_12;
+
+	req_score_params->oce_wan_scoring.num_slot =
+		bss_score_params->oce_wan_scoring.num_slot;
+	req_score_params->oce_wan_scoring.score_pcnt3_to_0 =
+		bss_score_params->oce_wan_scoring.score_pcnt3_to_0;
+	req_score_params->oce_wan_scoring.score_pcnt7_to_4 =
+		bss_score_params->oce_wan_scoring.score_pcnt7_to_4;
+	req_score_params->oce_wan_scoring.score_pcnt11_to_8 =
+		bss_score_params->oce_wan_scoring.score_pcnt11_to_8;
+	req_score_params->oce_wan_scoring.score_pcnt15_to_12 =
+		bss_score_params->oce_wan_scoring.score_pcnt15_to_12;
+}
+
+uint8_t csr_get_roam_enabled_sta_sessionid(tpAniSirGlobal mac_ctx)
+{
+	struct csr_roam_session *session;
+	tpCsrNeighborRoamControlInfo roam_info;
+	uint8_t i;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		session = CSR_GET_SESSION(mac_ctx, i);
+		if (!session || !CSR_IS_SESSION_VALID(mac_ctx, i))
+			continue;
+		if (!session->pCurRoamProfile ||
+		    session->pCurRoamProfile->csrPersona != QDF_STA_MODE)
+			continue;
+		roam_info = &mac_ctx->roam.neighborRoamInfo[i];
+		if (roam_info->b_roam_scan_offload_started) {
+			sme_debug("Roaming enabled on iface, session: %d", i);
+			return i;
+		}
+	}
+
+	return CSR_SESSION_ID_INVALID;
+}
+
+/**
+ * csr_roam_offload_scan() - populates roam offload scan request and sends to
+ * WMA
+ *
+ * parameters
+ * @mac_ctx:      global mac ctx
+ * @session_id:   session id
+ * @command:      roam scan offload command input
+ * @reason:       reason to roam
+ *
+ * Return: result of operation
+ */
+QDF_STATUS
+csr_roam_offload_scan(tpAniSirGlobal mac_ctx, uint8_t session_id,
+		      uint8_t command, uint8_t reason)
+{
+	uint8_t *state = NULL;
+	tSirRoamOffloadScanReq *req_buf;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+	tpCsrNeighborRoamControlInfo roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	struct roam_ext_params *roam_params_dst;
+	struct roam_ext_params *roam_params_src;
+	uint8_t i, temp_session_id;
+	uint8_t op_channel;
+	bool prev_roaming_state;
+
+	sme_debug("RSO Command %d, Session id %d, Reason %d", command,
+		   session_id, reason);
+	if (NULL == session) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			 "session is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	temp_session_id = csr_get_roam_enabled_sta_sessionid(mac_ctx);
+	if ((temp_session_id != CSR_SESSION_ID_INVALID) &&
+	    (session_id != temp_session_id)) {
+		sme_debug("Roam cmd not for session %d on which roaming is enabled",
+			   temp_session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (command == ROAM_SCAN_OFFLOAD_START &&
+	    (session->pCurRoamProfile &&
+	    session->pCurRoamProfile->driver_disabled_roaming)) {
+		if (reason == REASON_DRIVER_ENABLED) {
+			session->pCurRoamProfile->driver_disabled_roaming =
+									false;
+			sme_debug("driver_disabled_roaming reset for session %d",
+				  session_id);
+		} else {
+			sme_debug("Roam start received for session %d on which driver has disabled roaming",
+				  session_id);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	if ((ROAM_SCAN_OFFLOAD_START == command &&
+	    REASON_CTX_INIT != reason) &&
+	    (session->pCurRoamProfile &&
+	    session->pCurRoamProfile->supplicant_disabled_roaming)) {
+		sme_debug("Supplicant disabled driver roaming");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (0 == csr_roam_is_roam_offload_scan_enabled(mac_ctx)) {
+		sme_err("isRoamOffloadScanEnabled not set");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (!csr_is_RSO_cmd_allowed(mac_ctx, command, session_id) &&
+			reason != REASON_ROAM_SET_BLACKLIST_BSSID) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			("RSO out-of-sync command %d lastSentCmd %d"),
+			command, roam_info->last_sent_cmd);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	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;
+	}
+
+	/* Roaming is not supported currently for FILS akm */
+	if (session->pCurRoamProfile && CSR_IS_AUTH_TYPE_FILS(
+	    session->pCurRoamProfile->AuthType.authType[0]) &&
+	    !mac_ctx->is_fils_roaming_supported) {
+		sme_info("FILS Roaming not suppprted by fw");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* Roaming is not supported currently for OWE akm */
+	if (session->pCurRoamProfile &&
+	   (session->pCurRoamProfile->AuthType.authType[0] ==
+	   eCSR_AUTH_TYPE_OWE)) {
+		sme_info("OWE Roaming not suppprted by fw");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* Roaming is not supported currently for SAE authentication */
+	if (session->pCurRoamProfile &&
+			CSR_IS_AUTH_TYPE_SAE(
+		session->pCurRoamProfile->AuthType.authType[0])) {
+		sme_info("Roaming not suppprted for SAE connection");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/*
+	 * The Dynamic Config Items Update may happen even if the state is in
+	 * INIT. It is important to ensure that the command is passed down to
+	 * the FW only if the Infra Station is in a connected state. A connected
+	 * station could also be in a PREAUTH or REASSOC states.
+	 * 1) Block all CMDs that are not STOP in INIT State. For STOP always
+	 *    inform firmware irrespective of state.
+	 * 2) Block update cfg CMD if its for REASON_ROAM_SET_BLACKLIST_BSSID,
+	 *    because we need to inform firmware of blacklisted AP for PNO in
+	 *    all states.
+	 */
+
+	if ((roam_info->neighborRoamState ==
+	     eCSR_NEIGHBOR_ROAM_STATE_INIT) &&
+	    (command != ROAM_SCAN_OFFLOAD_STOP) &&
+	    (reason != REASON_ROAM_SET_BLACKLIST_BSSID)) {
+		state = mac_trace_get_neighbour_roam_state(
+				roam_info->neighborRoamState);
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			 FL("Scan Command not sent to FW state=%s and cmd=%d"),
+			  state,  command);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	req_buf = csr_create_roam_scan_offload_request(mac_ctx, command,
+						       session_id, reason,
+						       session, roam_info);
+	if (!req_buf) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			 "Failed to create req packet");
+		return QDF_STATUS_E_FAILURE;
+	}
+	roam_params_dst = &req_buf->roam_params;
+	roam_params_src = &mac_ctx->roam.configParam.roam_params;
+	if (reason == REASON_ROAM_SET_SSID_ALLOWED)
+		check_allowed_ssid_list(req_buf, roam_params_src);
+
+	/*
+	 * For CTX INT cmd if rssi disallow bssid list have any member
+	 * fill it and send it to firmware so that firmware does not
+	 * try to roam to these BSS until RSSI OR time condition are
+	 * matched.
+	 */
+	if (reason == REASON_CTX_INIT)
+		csr_add_rssi_reject_ap_list(mac_ctx, roam_params_src);
+	/*
+	 * Configure the lookup threshold either from INI or from framework.
+	 * If both are present, give higher priority to the one from framework.
+	 */
+	if (roam_params_src->alert_rssi_threshold)
+		req_buf->LookupThreshold =
+			roam_params_src->alert_rssi_threshold;
+	else
+		req_buf->LookupThreshold =
+			(int8_t)roam_info->cfgParams.neighborLookupThreshold *
+			(-1);
+	req_buf->rssi_thresh_offset_5g =
+		roam_info->cfgParams.rssi_thresh_offset_5g;
+	sme_debug("5g offset threshold: %d", req_buf->rssi_thresh_offset_5g);
+	qdf_mem_copy(roam_params_dst, roam_params_src,
+		sizeof(*roam_params_dst));
+	roam_params_dst->traffic_threshold =
+		mac_ctx->mlme_cfg->lfr.roam_dense_traffic_threshold;
+	roam_params_dst->dense_rssi_thresh_offset =
+		mac_ctx->mlme_cfg->lfr.roam_dense_rssi_thre_offset;
+	roam_params_dst->dense_min_aps_cnt =
+		mac_ctx->mlme_cfg->lfr.roam_dense_min_aps;
+	roam_params_dst->bg_scan_bad_rssi_thresh =
+		mac_ctx->mlme_cfg->lfr.roam_bg_scan_bad_rssi_threshold;
+	roam_params_dst->bg_scan_client_bitmap =
+		mac_ctx->mlme_cfg->lfr.roam_bg_scan_client_bitmap;
+	roam_params_dst->roam_bad_rssi_thresh_offset_2g =
+		mac_ctx->mlme_cfg->lfr.roam_bg_scan_bad_rssi_offset_2g;
+	roam_params_dst->raise_rssi_thresh_5g =
+		mac_ctx->mlme_cfg->lfr.rssi_boost_threshold_5g;
+	roam_params_dst->drop_rssi_thresh_5g =
+		mac_ctx->mlme_cfg->lfr.rssi_penalize_threshold_5g;
+	roam_params_dst->raise_factor_5g =
+		mac_ctx->mlme_cfg->lfr.rssi_boost_factor_5g;
+	roam_params_dst->drop_factor_5g =
+		mac_ctx->mlme_cfg->lfr.rssi_penalize_factor_5g;
+	roam_params_dst->max_raise_rssi_5g =
+		mac_ctx->mlme_cfg->lfr.max_rssi_boost_5g;
+	roam_params_dst->max_drop_rssi_5g =
+		mac_ctx->mlme_cfg->lfr.max_rssi_penalize_5g;
+
+	/*
+	 * rssi_diff which is updated via framework is equivalent to the
+	 * INI RoamRssiDiff parameter and hence should be updated.
+	 */
+	if (roam_params_src->rssi_diff)
+		req_buf->RoamRssiDiff = roam_params_src->rssi_diff;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		"num_bssid_avoid_list: %d num_ssid_allowed_list: %d num_bssid_favored: %d raise_rssi_thresh_5g: %d drop_rssi_thresh_5g: %d raise_rssi_type_5g: %d raise_factor_5g: %d drop_rssi_type_5g: %d drop_factor_5g: %d max_raise_rssi_5g: %d max_drop_rssi_5g: %d rssi_diff: %d alert_rssi_threshold: %d",
+		roam_params_dst->num_bssid_avoid_list,
+		roam_params_dst->num_ssid_allowed_list,
+		roam_params_dst->num_bssid_favored,
+		roam_params_dst->raise_rssi_thresh_5g,
+		roam_params_dst->drop_rssi_thresh_5g,
+		roam_params_dst->raise_rssi_type_5g,
+		roam_params_dst->raise_factor_5g,
+		roam_params_dst->drop_rssi_type_5g,
+		roam_params_dst->drop_factor_5g,
+		roam_params_dst->max_raise_rssi_5g,
+		roam_params_dst->max_drop_rssi_5g,
+		req_buf->RoamRssiDiff, roam_params_dst->alert_rssi_threshold);
+
+	/* Set initial dense roam status */
+	if (mac_ctx->scan.roam_candidate_count[session_id] >
+	    roam_params_dst->dense_min_aps_cnt)
+		roam_params_dst->initial_dense_status = true;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		"dense_rssi_thresh_offset: %d, dense_min_aps_cnt:%d, traffic_threshold:%d, "
+		"initial_dense_status:%d, candidate count:%d",
+		roam_params_dst->dense_rssi_thresh_offset,
+		roam_params_dst->dense_min_aps_cnt,
+		roam_params_dst->traffic_threshold,
+		roam_params_dst->initial_dense_status,
+		mac_ctx->scan.roam_candidate_count[session_id]);
+	sme_debug("BG Scan Bad RSSI:%d, bitmap:0x%x Offset for 2G to 5G Roam %d",
+			roam_params_dst->bg_scan_bad_rssi_thresh,
+			roam_params_dst->bg_scan_client_bitmap,
+			roam_params_dst->roam_bad_rssi_thresh_offset_2g);
+
+	for (i = 0; i < roam_params_dst->num_bssid_avoid_list; i++) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"Blacklist Bssid:"MAC_ADDRESS_STR")",
+			MAC_ADDR_ARRAY(roam_params_dst->bssid_avoid_list[i].
+				bytes));
+	}
+	for (i = 0; i < roam_params_dst->num_ssid_allowed_list; i++) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"Whitelist: %.*s",
+			roam_params_dst->ssid_allowed_list[i].length,
+			roam_params_dst->ssid_allowed_list[i].ssId);
+	}
+	for (i = 0; i < roam_params_dst->num_bssid_favored; i++) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"Preferred Bssid:"MAC_ADDRESS_STR") score: %d",
+			MAC_ADDR_ARRAY(roam_params_dst->bssid_favored[i].bytes),
+			roam_params_dst->bssid_favored_factor[i]);
+	}
+
+	op_channel = session->connectedProfile.operationChannel;
+	req_buf->hi_rssi_scan_max_count =
+		roam_info->cfgParams.hi_rssi_scan_max_count;
+	req_buf->hi_rssi_scan_delay =
+		roam_info->cfgParams.hi_rssi_scan_delay;
+	req_buf->hi_rssi_scan_rssi_ub =
+		roam_info->cfgParams.hi_rssi_scan_rssi_ub;
+	/*
+	 * If the current operation channel is 5G frequency band, then
+	 * there is no need to enable the HI_RSSI feature. This feature
+	 * is useful only if we are connected to a 2.4 GHz AP and we wish
+	 * to connect to a better 5GHz AP is available.
+	 */
+	if (session->disable_hi_rssi)
+		req_buf->hi_rssi_scan_rssi_delta = 0;
+	else
+		req_buf->hi_rssi_scan_rssi_delta =
+			roam_info->cfgParams.hi_rssi_scan_rssi_delta;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		"hi_rssi:delta=%d, max_count=%d, delay=%d, ub=%d",
+			req_buf->hi_rssi_scan_rssi_delta,
+			req_buf->hi_rssi_scan_max_count,
+			req_buf->hi_rssi_scan_delay,
+			req_buf->hi_rssi_scan_rssi_ub);
+
+	if (command != ROAM_SCAN_OFFLOAD_STOP) {
+		req_buf->assoc_ie.length = session->nAddIEAssocLength;
+		qdf_mem_copy(req_buf->assoc_ie.addIEdata,
+				session->pAddIEAssoc,
+				session->nAddIEAssocLength);
+		csr_update_driver_assoc_ies(mac_ctx, session, req_buf);
+		csr_update_score_params(mac_ctx, req_buf);
+		csr_update_fils_params_rso(mac_ctx, session, req_buf);
+	}
+
+	/*
+	 * 11k offload is enabled during RSO Start after connect indication and
+	 * 11k offload is disabled during RSO Stop after disconnect indication
+	 */
+	if (command == ROAM_SCAN_OFFLOAD_START &&
+	    reason == REASON_CTX_INIT)
+		csr_update_11k_offload_params(mac_ctx, session, req_buf, TRUE);
+	else if (command == ROAM_SCAN_OFFLOAD_STOP &&
+		 reason == REASON_DISCONNECTED)
+		csr_update_11k_offload_params(mac_ctx, session, req_buf, FALSE);
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"Assoc IE buffer:");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			req_buf->assoc_ie.addIEdata, req_buf->assoc_ie.length);
+
+	prev_roaming_state = roam_info->b_roam_scan_offload_started;
+	if (ROAM_SCAN_OFFLOAD_START == command)
+		roam_info->b_roam_scan_offload_started = true;
+	else if (ROAM_SCAN_OFFLOAD_STOP == command)
+		roam_info->b_roam_scan_offload_started = false;
+	policy_mgr_set_pcl_for_existing_combo(mac_ctx->psoc, PM_STA_MODE);
+
+	if (!QDF_IS_STATUS_SUCCESS(
+		csr_roam_send_rso_cmd(mac_ctx, session_id, req_buf))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Not able to post message to PE",
+			  __func__);
+		roam_info->b_roam_scan_offload_started = prev_roaming_state;
+		policy_mgr_set_pcl_for_existing_combo(mac_ctx->psoc,
+						      PM_STA_MODE);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* update the last sent cmd */
+	roam_info->last_sent_cmd = command;
+
+	/* Update PER config to FW after sending the command */
+	csr_roam_offload_per_scan(mac_ctx, session_id);
+	return status;
+}
+
+QDF_STATUS csr_roam_offload_scan_rsp_hdlr(tpAniSirGlobal pMac,
+					  tpSirRoamOffloadScanRsp
+						scanOffloadRsp)
+{
+	switch (scanOffloadRsp->reason) {
+	case 0:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "Rsp for Roam Scan Offload with failure status");
+		break;
+	case REASON_OS_REQUESTED_ROAMING_NOW:
+		csr_neighbor_roam_proceed_with_handoff_req(pMac,
+						scanOffloadRsp->sessionId);
+		break;
+
+	default:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "Rsp for Roam Scan Offload with reason %d",
+			  scanOffloadRsp->reason);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifndef QCA_SUPPORT_CP_STATS
+/* pStaEntry is no longer invalid upon the return of this function. */
+static void csr_roam_remove_stat_list_entry(tpAniSirGlobal pMac,
+						tListElem *pEntry)
+{
+	if (pEntry) {
+		if (csr_ll_remove_entry(&pMac->roam.statsClientReqList,
+						pEntry, LL_ACCESS_LOCK))
+			qdf_mem_free(GET_BASE_ADDR(pEntry,
+					struct csr_statsclient_reqinfo, link));
+	}
+}
+
+static void csr_roam_remove_entry_from_pe_stats_req_list(
+tpAniSirGlobal pMac, struct csr_pestats_reqinfo *pPeStaEntry)
+{
+	tListElem *pEntry;
+	struct csr_pestats_reqinfo *pTempStaEntry;
+
+	pEntry = csr_ll_peek_head(&pMac->roam.peStatsReqList, LL_ACCESS_LOCK);
+	if (!pEntry) {
+		sme_err("List empty, no stats req for PE");
+		return;
+	}
+	while (pEntry) {
+		pTempStaEntry = GET_BASE_ADDR(pEntry,
+				struct csr_pestats_reqinfo, link);
+		if (NULL == pTempStaEntry
+			|| (pTempStaEntry->statsMask !=
+				pPeStaEntry->statsMask)) {
+			pEntry = csr_ll_next(&pMac->roam.peStatsReqList, pEntry,
+					LL_ACCESS_NOLOCK);
+			continue;
+		}
+		sme_debug("Match found");
+		if (csr_ll_remove_entry(&pMac->roam.peStatsReqList, pEntry,
+					LL_ACCESS_LOCK)) {
+			qdf_mem_free(pTempStaEntry);
+			pTempStaEntry = NULL;
+			break;
+		}
+		pEntry = csr_ll_next(&pMac->roam.peStatsReqList, pEntry,
+				     LL_ACCESS_NOLOCK);
+	} /* end of while loop */
+}
+
+static void csr_roam_report_statistics(tpAniSirGlobal pMac,
+		uint32_t statsMask,
+		tCsrStatsCallback callback, uint8_t staId,
+		void *pContext)
+{
+	uint8_t stats[500];
+	uint8_t *pStats = NULL;
+	uint32_t tempMask = 0;
+	uint8_t counter = 0;
+
+	if (!callback) {
+		sme_err("Cannot report callback NULL");
+		return;
+	}
+	if (!statsMask) {
+		sme_err("Cannot report statsMask is 0");
+		return;
+	}
+	pStats = stats;
+	tempMask = statsMask;
+	while (tempMask) {
+		if (tempMask & 1) {
+			/* new stats info from PE, fill up the stats
+			 * strucutres in PMAC
+			 */
+			switch (counter) {
+			case eCsrSummaryStats:
+				sme_debug("Summary stats");
+				qdf_mem_copy(pStats,
+					     (uint8_t *) &pMac->roam.
+					     summaryStatsInfo,
+					     sizeof(tCsrSummaryStatsInfo));
+				pStats += sizeof(tCsrSummaryStatsInfo);
+				break;
+			case eCsrGlobalClassAStats:
+				sme_debug("ClassA stats");
+				qdf_mem_copy(pStats,
+					     (uint8_t *) &pMac->roam.
+					     classAStatsInfo,
+					     sizeof(tCsrGlobalClassAStatsInfo));
+				pStats += sizeof(tCsrGlobalClassAStatsInfo);
+				break;
+			case eCsrGlobalClassDStats:
+				sme_debug("ClassD stats");
+				qdf_mem_copy(pStats,
+					     (uint8_t *) &pMac->roam.
+					     classDStatsInfo,
+					     sizeof(tCsrGlobalClassDStatsInfo));
+				pStats += sizeof(tCsrGlobalClassDStatsInfo);
+				break;
+			case csr_per_chain_rssi_stats:
+				sme_debug("Per Chain RSSI stats");
+				qdf_mem_copy(pStats,
+				  (uint8_t *)&pMac->roam.per_chain_rssi_stats,
+				  sizeof(struct csr_per_chain_rssi_stats_info));
+				pStats += sizeof(
+					struct csr_per_chain_rssi_stats_info);
+				break;
+			default:
+				sme_err(
+					"Unknown stats type and counter %d",
+					counter);
+				break;
+			}
+		}
+		tempMask >>= 1;
+		counter++;
+	}
+	callback(stats, pContext);
+}
+
+static QDF_STATUS csr_roam_dereg_statistics_req(
+	tpAniSirGlobal pMac)
+{
+	tListElem *pEntry = NULL;
+	tListElem *pPrevEntry = NULL;
+	struct csr_statsclient_reqinfo *pTempStaEntry = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	pEntry = csr_ll_peek_head(&pMac->roam.statsClientReqList,
+							LL_ACCESS_LOCK);
+	if (!pEntry) {
+		/* list empty */
+		sme_debug("List empty, no request from upper layer client(s)");
+		return status;
+	}
+	while (pEntry) {
+		if (pPrevEntry) {
+			pTempStaEntry =
+				GET_BASE_ADDR(pPrevEntry,
+					struct csr_statsclient_reqinfo, link);
+			/* send up the stats report */
+			csr_roam_report_statistics(pMac,
+						pTempStaEntry->statsMask,
+						   pTempStaEntry->callback,
+						   pTempStaEntry->staId,
+						   pTempStaEntry->pContext);
+			csr_roam_remove_stat_list_entry(pMac, pPrevEntry);
+		}
+		pTempStaEntry =
+		GET_BASE_ADDR(pEntry, struct csr_statsclient_reqinfo, link);
+		if (pTempStaEntry->pPeStaEntry) {
+			/* pPeStaEntry can be NULL */
+			pTempStaEntry->pPeStaEntry->numClient--;
+			/* check if we need to delete the entry from
+			 * peStatsReqList too
+			 */
+			if (!pTempStaEntry->pPeStaEntry->numClient) {
+				csr_roam_remove_entry_from_pe_stats_req_list(
+								pMac,
+								pTempStaEntry->
+								pPeStaEntry);
+			}
+		}
+		/* check if we need to stop the tl stats timer too */
+		pMac->roam.tlStatsReqInfo.numClient--;
+		pPrevEntry = pEntry;
+		pEntry = csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
+				     LL_ACCESS_NOLOCK);
+	}
+	/* the last one */
+	if (pPrevEntry) {
+		pTempStaEntry =
+		GET_BASE_ADDR(pPrevEntry, struct csr_statsclient_reqinfo, link);
+		/* send up the stats report */
+		csr_roam_report_statistics(pMac, pTempStaEntry->statsMask,
+					   pTempStaEntry->callback,
+					   pTempStaEntry->staId,
+					   pTempStaEntry->pContext);
+		csr_roam_remove_stat_list_entry(pMac, pPrevEntry);
+	}
+	return status;
+
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+tSmeCmd *csr_get_command_buffer(tpAniSirGlobal pMac)
+{
+	tSmeCmd *pCmd = sme_get_command_buffer(pMac);
+
+	if (pCmd)
+		pMac->roam.sPendingCommands++;
+
+	return pCmd;
+}
+
+static void csr_free_cmd_memory(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	if (!pCommand) {
+		sme_err("pCommand is NULL");
+		return;
+	}
+	switch (pCommand->command) {
+	case eSmeCommandRoam:
+		csr_release_command_roam(pMac, pCommand);
+		break;
+	case eSmeCommandWmStatusChange:
+		csr_release_command_wm_status_change(pMac, pCommand);
+		break;
+	default:
+		break;
+	}
+}
+
+void csr_release_command_buffer(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	if (pMac->roam.sPendingCommands > 0) {
+		/*
+		 * All command allocated through csr_get_command_buffer
+		 * need to decrement the pending count when releasing
+		 */
+		pMac->roam.sPendingCommands--;
+		csr_free_cmd_memory(pMac, pCommand);
+		sme_release_command(pMac, pCommand);
+	} else {
+		sme_err("no pending commands");
+		QDF_ASSERT(0);
+	}
+}
+
+void csr_release_command(tpAniSirGlobal mac_ctx, tSmeCmd *sme_cmd)
+{
+	struct wlan_serialization_queued_cmd_info cmd_info;
+	struct wlan_serialization_command cmd;
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!sme_cmd) {
+		sme_err("sme_cmd is NULL");
+		return;
+	}
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
+			sme_cmd->sessionId, WLAN_LEGACY_SME_ID);
+	if (!vdev) {
+		sme_err("Invalid vdev");
+		return;
+	}
+	qdf_mem_zero(&cmd_info,
+			sizeof(struct wlan_serialization_queued_cmd_info));
+
+	sme_debug("filled cmd_id = %d", sme_cmd->cmd_id);
+	cmd_info.cmd_id = sme_cmd->cmd_id;
+	cmd_info.req_type = WLAN_SER_CANCEL_NON_SCAN_CMD;
+	cmd_info.cmd_type = csr_get_cmd_type(sme_cmd);
+	cmd_info.vdev = vdev;
+	qdf_mem_zero(&cmd, sizeof(struct wlan_serialization_command));
+	cmd.cmd_id = cmd_info.cmd_id;
+	cmd.cmd_type = cmd_info.cmd_type;
+	cmd.vdev = cmd_info.vdev;
+	if (wlan_serialization_is_cmd_present_in_active_queue(
+				mac_ctx->psoc, &cmd)) {
+		sme_debug("Releasing active cmd_id[%d] cmd_type[%d]",
+				cmd_info.cmd_id, cmd_info.cmd_type);
+		wlan_serialization_remove_cmd(&cmd_info);
+	} else if (wlan_serialization_is_cmd_present_in_pending_queue(
+				mac_ctx->psoc, &cmd)) {
+		sme_debug("Releasing pending cmd_id[%d] cmd_type[%d]",
+				cmd_info.cmd_id, cmd_info.cmd_type);
+		wlan_serialization_cancel_request(&cmd_info);
+	} else {
+		sme_debug("can't find cmd_id[%d] cmd_type[%d]",
+				cmd_info.cmd_id, cmd_info.cmd_type);
+	}
+	if (cmd_info.vdev)
+		wlan_objmgr_vdev_release_ref(cmd_info.vdev, WLAN_LEGACY_SME_ID);
+}
+
+
+static enum wlan_serialization_cmd_type csr_get_roam_cmd_type(
+		tSmeCmd *sme_cmd)
+{
+	enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX;
+
+	switch (sme_cmd->u.roamCmd.roamReason) {
+	case eCsrForcedDisassoc:
+		cmd_type = WLAN_SER_CMD_FORCE_DISASSOC;
+		break;
+	case eCsrHddIssued:
+		cmd_type = WLAN_SER_CMD_HDD_ISSUED;
+		break;
+	case eCsrForcedDisassocMICFailure:
+		cmd_type = WLAN_SER_CMD_FORCE_DISASSOC_MIC_FAIL;
+		break;
+	case eCsrHddIssuedReassocToSameAP:
+		cmd_type = WLAN_SER_CMD_HDD_ISSUE_REASSOC_SAME_AP;
+		break;
+	case eCsrSmeIssuedReassocToSameAP:
+		cmd_type = WLAN_SER_CMD_SME_ISSUE_REASSOC_SAME_AP;
+		break;
+	case eCsrForcedDeauth:
+		cmd_type = WLAN_SER_CMD_FORCE_DEAUTH;
+		break;
+	case eCsrSmeIssuedDisassocForHandoff:
+		cmd_type =
+			WLAN_SER_CMD_SME_ISSUE_DISASSOC_FOR_HANDOFF;
+		break;
+	case eCsrSmeIssuedAssocToSimilarAP:
+		cmd_type =
+			WLAN_SER_CMD_SME_ISSUE_ASSOC_TO_SIMILAR_AP;
+		break;
+	case eCsrForcedIbssLeave:
+		cmd_type = WLAN_SER_CMD_FORCE_IBSS_LEAVE;
+		break;
+	case eCsrStopBss:
+		cmd_type = WLAN_SER_CMD_VDEV_STOP_BSS;
+		break;
+	case eCsrSmeIssuedFTReassoc:
+		cmd_type = WLAN_SER_CMD_SME_ISSUE_FT_REASSOC;
+		break;
+	case eCsrForcedDisassocSta:
+		cmd_type = WLAN_SER_CMD_FORCE_DISASSOC_STA;
+		break;
+	case eCsrForcedDeauthSta:
+		cmd_type = WLAN_SER_CMD_FORCE_DEAUTH_STA;
+		break;
+	case eCsrPerformPreauth:
+		cmd_type = WLAN_SER_CMD_PERFORM_PRE_AUTH;
+		break;
+	default:
+		break;
+	}
+
+	return cmd_type;
+}
+
+enum wlan_serialization_cmd_type csr_get_cmd_type(tSmeCmd *sme_cmd)
+{
+	enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX;
+
+	switch (sme_cmd->command) {
+	case eSmeCommandRoam:
+		cmd_type = csr_get_roam_cmd_type(sme_cmd);
+		break;
+	case eSmeCommandWmStatusChange:
+		cmd_type = WLAN_SER_CMD_WM_STATUS_CHANGE;
+		break;
+	case e_sme_command_del_sta_session:
+		cmd_type = WLAN_SER_CMD_DEL_STA_SESSION;
+		break;
+	case eSmeCommandAddTs:
+		cmd_type = WLAN_SER_CMD_ADDTS;
+		break;
+	case eSmeCommandDelTs:
+		cmd_type = WLAN_SER_CMD_DELTS;
+		break;
+	case e_sme_command_set_hw_mode:
+		cmd_type = WLAN_SER_CMD_SET_HW_MODE;
+		break;
+	case e_sme_command_nss_update:
+		cmd_type = WLAN_SER_CMD_NSS_UPDATE;
+		break;
+	case e_sme_command_set_dual_mac_config:
+		cmd_type = WLAN_SER_CMD_SET_DUAL_MAC_CONFIG;
+		break;
+	case e_sme_command_set_antenna_mode:
+		cmd_type = WLAN_SER_CMD_SET_ANTENNA_MODE;
+		break;
+	default:
+		break;
+	}
+
+	return cmd_type;
+}
+
+static uint32_t csr_get_monotonous_number(tpAniSirGlobal mac_ctx)
+{
+	uint32_t cmd_id;
+	uint32_t mask = 0x00FFFFFF, prefix = 0x0D000000;
+
+	cmd_id = qdf_atomic_inc_return(&mac_ctx->global_cmd_id);
+	cmd_id = (cmd_id & mask);
+	cmd_id = (cmd_id | prefix);
+
+	return cmd_id;
+}
+
+QDF_STATUS csr_set_serialization_params_to_cmd(tpAniSirGlobal mac_ctx,
+		tSmeCmd *sme_cmd, struct wlan_serialization_command *cmd,
+		uint8_t high_priority)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!sme_cmd) {
+		sme_err("Invalid sme_cmd");
+		return status;
+	}
+	if (!cmd) {
+		sme_err("Invalid serialization_cmd");
+		return status;
+	}
+
+	/*
+	 * no need to fill command id for non-scan as they will be
+	 * zero always
+	 */
+	sme_cmd->cmd_id = csr_get_monotonous_number(mac_ctx);
+	cmd->cmd_id = sme_cmd->cmd_id;
+	sme_debug("cmd_id = %d", cmd->cmd_id);
+
+	cmd->cmd_type = csr_get_cmd_type(sme_cmd);
+	sme_debug("filled cmd_type[%d] cmd_id[%d]",
+		cmd->cmd_type, cmd->cmd_id);
+	if (cmd->cmd_type == WLAN_SER_CMD_MAX) {
+		sme_err("serialization enum not found");
+		return status;
+	}
+	cmd->vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
+				sme_cmd->sessionId, WLAN_LEGACY_SME_ID);
+	if (!cmd->vdev) {
+		sme_err("vdev is NULL for sme_session:%d", sme_cmd->sessionId);
+		return status;
+	}
+	cmd->umac_cmd = sme_cmd;
+
+	/*
+	 * For START BSS and STOP BSS commands for SAP, the command timeout
+	 * is set to 10 seconds. For all other commands its 30 seconds
+	 */
+	if ((cmd->vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) &&
+	    ((cmd->cmd_type == WLAN_SER_CMD_HDD_ISSUED) ||
+	    (cmd->cmd_type == WLAN_SER_CMD_VDEV_STOP_BSS)))
+		cmd->cmd_timeout_duration = SME_START_STOP_BSS_CMD_TIMEOUT;
+	else if (cmd->cmd_type == WLAN_SER_CMD_DEL_STA_SESSION)
+		cmd->cmd_timeout_duration = SME_VDEV_DELETE_CMD_TIMEOUT;
+	else
+		cmd->cmd_timeout_duration = SME_DEFAULT_CMD_TIMEOUT;
+
+	cmd->cmd_cb = sme_ser_cmd_callback;
+	cmd->is_high_priority = high_priority;
+	cmd->is_blocking = true;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS csr_queue_sme_command(tpAniSirGlobal mac_ctx, tSmeCmd *sme_cmd,
+				 bool high_priority)
+{
+	struct wlan_serialization_command cmd;
+	struct wlan_objmgr_vdev *vdev = NULL;
+	enum wlan_serialization_status ser_cmd_status;
+	QDF_STATUS status;
+
+	if (!SME_IS_START(mac_ctx)) {
+		sme_err("Sme in stop state");
+		QDF_ASSERT(0);
+		goto error;
+	}
+
+	if (CSR_IS_WAIT_FOR_KEY(mac_ctx, sme_cmd->sessionId)) {
+		if (!CSR_IS_DISCONNECT_COMMAND(sme_cmd)) {
+			sme_err("Can't process cmd(%d), waiting for key",
+				sme_cmd->command);
+			goto error;
+		}
+	}
+
+	qdf_mem_zero(&cmd, sizeof(struct wlan_serialization_command));
+	status = csr_set_serialization_params_to_cmd(mac_ctx, sme_cmd,
+					&cmd, high_priority);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failed to set ser params");
+		goto error;
+	}
+
+	vdev = cmd.vdev;
+	ser_cmd_status = wlan_serialization_request(&cmd);
+	sme_debug("wlan_serialization_request status:%d", ser_cmd_status);
+
+	switch (ser_cmd_status) {
+	case WLAN_SER_CMD_PENDING:
+	case WLAN_SER_CMD_ACTIVE:
+		/* Command posted to active/pending list */
+		status = QDF_STATUS_SUCCESS;
+		break;
+	case WLAN_SER_CMD_DENIED_LIST_FULL:
+	case WLAN_SER_CMD_DENIED_RULES_FAILED:
+	case WLAN_SER_CMD_DENIED_UNSPECIFIED:
+		status = QDF_STATUS_E_FAILURE;
+		goto error;
+	default:
+		QDF_ASSERT(0);
+		status = QDF_STATUS_E_FAILURE;
+		goto error;
+	}
+
+	return status;
+
+error:
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+
+	csr_release_command_buffer(mac_ctx, sme_cmd);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS csr_roam_update_config(tpAniSirGlobal mac_ctx, uint8_t session_id,
+				  uint16_t capab, uint32_t value)
+{
+	struct update_config *msg;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	sme_debug("update HT config requested");
+	if (NULL == session) {
+		sme_err("Session does not exist for session id %d", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	msg = qdf_mem_malloc(sizeof(*msg));
+	if (!msg)
+		return QDF_STATUS_E_NOMEM;
+
+	msg->messageType = eWNI_SME_UPDATE_CONFIG;
+	msg->sme_session_id = session_id;
+	msg->capab = capab;
+	msg->value = value;
+	msg->length = sizeof(*msg);
+	status = umac_send_mb_message_to_mac(msg);
+
+	return status;
+}
+
+/*
+ * pBuf points to the beginning of the message
+ * LIM packs disassoc rsp as below,
+ * messageType - 2 bytes
+ * messageLength - 2 bytes
+ * sessionId - 1 byte
+ * transactionId - 2 bytes (uint16_t)
+ * reasonCode - 4 bytes (sizeof(tSirResultCodes))
+ * peerMacAddr - 6 bytes
+ * The rest is conditionally defined of (WNI_POLARIS_FW_PRODUCT == AP)
+ * and not used
+ */
+static void csr_ser_des_unpack_diassoc_rsp(uint8_t *pBuf, tSirSmeDisassocRsp
+									*pRsp)
+{
+	if (pBuf && pRsp) {
+		pBuf += 4;      /* skip type and length */
+		pRsp->sessionId = *pBuf++;
+		qdf_get_u16(pBuf, (uint16_t *) &pRsp->transactionId);
+		pBuf += 2;
+		qdf_get_u32(pBuf, (uint32_t *) &pRsp->statusCode);
+		pBuf += 4;
+		qdf_mem_copy(pRsp->peer_macaddr.bytes, pBuf, QDF_MAC_ADDR_SIZE);
+	}
+}
+
+/* Returns whether a session is in QDF_STA_MODE...or not */
+bool csr_roam_is_sta_mode(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	struct csr_roam_session *pSession = NULL;
+
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found",	sessionId);
+		return false;
+	}
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		sme_err("Inactive session_id: %d", sessionId);
+		return false;
+	}
+	if (eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType)
+		return false;
+	/* There is a possibility that the above check may fail,because
+	 * P2P CLI also uses the same BSSType (eCSR_BSS_TYPE_INFRASTRUCTURE)
+	 * when it is connected.So,we may sneak through the above check even
+	 * if we are not a STA mode INFRA station. So, if we sneak through
+	 * the above condition, we can use the following check if we are
+	 * really in STA Mode.
+	 */
+
+	if (NULL != pSession->pCurRoamProfile) {
+		if (pSession->pCurRoamProfile->csrPersona == QDF_STA_MODE)
+			return true;
+		else
+			return false;
+	}
+
+	return false;
+}
+
+QDF_STATUS csr_handoff_request(tpAniSirGlobal pMac,
+			       uint8_t sessionId,
+			       tCsrHandoffRequest *pHandoffInfo)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msg = {0};
+
+	tAniHandoffReq *pMsg;
+
+	pMsg = qdf_mem_malloc(sizeof(tAniHandoffReq));
+	if (NULL == pMsg) {
+		return QDF_STATUS_E_NOMEM;
+	}
+	pMsg->msgType = eWNI_SME_HANDOFF_REQ;
+	pMsg->msgLen = (uint16_t) sizeof(tAniHandoffReq);
+	pMsg->sessionId = sessionId;
+	pMsg->channel = pHandoffInfo->channel;
+	pMsg->handoff_src = pHandoffInfo->src;
+	qdf_mem_copy(pMsg->bssid, pHandoffInfo->bssid.bytes, QDF_MAC_ADDR_SIZE);
+	msg.type = eWNI_SME_HANDOFF_REQ;
+	msg.bodyptr = pMsg;
+	msg.reserved = 0;
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_SME,
+							 &msg)) {
+		sme_err("scheduler_post_msg failed to post msg to self");
+		qdf_mem_free((void *)pMsg);
+		status = QDF_STATUS_E_FAILURE;
+	}
+	return status;
+}
+
+/**
+ * csr_roam_channel_change_req() - Post channel change request to LIM
+ * @pMac: mac context
+ * @bssid: SAP bssid
+ * @ch_params: channel information
+ * @profile: CSR profile
+ *
+ * This API is primarily used to post Channel Change Req for SAP
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS csr_roam_channel_change_req(tpAniSirGlobal pMac,
+				       struct qdf_mac_addr bssid,
+				       struct ch_params *ch_params,
+				       struct csr_roam_profile *profile)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirChanChangeRequest *pMsg;
+	struct csr_roamstart_bssparams param;
+	bool skip_hostapd_rate = !profile->chan_switch_hostapd_rate_enabled;
+
+	/*
+	 * while changing the channel, use basic rates given by driver
+	 * and not by hostapd as there is a chance that hostapd might
+	 * give us rates based on original channel which may not be
+	 * suitable for new channel
+	 */
+	qdf_mem_zero(&param, sizeof(struct csr_roamstart_bssparams));
+
+	status = csr_roam_get_bss_start_parms(pMac, profile, &param,
+					      skip_hostapd_rate);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("Failed to get bss parameters");
+		return status;
+	}
+
+	pMsg = qdf_mem_malloc(sizeof(tSirChanChangeRequest));
+	if (!pMsg)
+		return QDF_STATUS_E_NOMEM;
+
+	pMsg->messageType = eWNI_SME_CHANNEL_CHANGE_REQ;
+	pMsg->messageLen = sizeof(tSirChanChangeRequest);
+	pMsg->targetChannel = profile->ChannelInfo.ChannelList[0];
+	pMsg->sec_ch_offset = ch_params->sec_ch_offset;
+	pMsg->ch_width = profile->ch_params.ch_width;
+	pMsg->dot11mode = csr_translate_to_wni_cfg_dot11_mode(pMac,
+					param.uCfgDot11Mode);
+	if (IS_24G_CH(pMsg->targetChannel) &&
+	    !pMac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band &&
+	    (WNI_CFG_DOT11_MODE_11AC == pMsg->dot11mode ||
+	    WNI_CFG_DOT11_MODE_11AC_ONLY == pMsg->dot11mode))
+		pMsg->dot11mode = WNI_CFG_DOT11_MODE_11N;
+	pMsg->nw_type = param.sirNwType;
+	pMsg->center_freq_seg_0 = ch_params->center_freq_seg0;
+	pMsg->center_freq_seg_1 = ch_params->center_freq_seg1;
+	pMsg->cac_duration_ms = profile->cac_duration_ms;
+	pMsg->dfs_regdomain = profile->dfs_regdomain;
+	qdf_mem_copy(pMsg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(&pMsg->operational_rateset,
+		&param.operationalRateSet, sizeof(pMsg->operational_rateset));
+	qdf_mem_copy(&pMsg->extended_rateset,
+		&param.extendedRateSet, sizeof(pMsg->extended_rateset));
+
+	sme_debug("target_chan %d ch_width %d dot11mode %d",
+		  pMsg->targetChannel, pMsg->ch_width, pMsg->dot11mode);
+	status = umac_send_mb_message_to_mac(pMsg);
+
+	return status;
+}
+
+/*
+ * Post Beacon Tx Start request to LIM
+ * immediately after SAP CAC WAIT is
+ * completed without any RADAR indications.
+ */
+QDF_STATUS csr_roam_start_beacon_req(tpAniSirGlobal pMac,
+				     struct qdf_mac_addr bssid,
+				     uint8_t dfsCacWaitStatus)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirStartBeaconIndication *pMsg;
+
+	pMsg = qdf_mem_malloc(sizeof(tSirStartBeaconIndication));
+	if (!pMsg)
+		return QDF_STATUS_E_NOMEM;
+
+	pMsg->messageType = eWNI_SME_START_BEACON_REQ;
+	pMsg->messageLen = sizeof(tSirStartBeaconIndication);
+	pMsg->beaconStartStatus = dfsCacWaitStatus;
+	qdf_mem_copy(pMsg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE);
+
+	status = umac_send_mb_message_to_mac(pMsg);
+
+	return status;
+}
+
+/*
+ * csr_roam_modify_add_ies -
+ * This function sends msg to modify the additional IE buffers in PE
+ *
+ * @pMac: pMac global structure
+ * @pModifyIE: pointer to tSirModifyIE structure
+ * @updateType: Type of buffer
+ *
+ *
+ * Return: QDF_STATUS -  Success or failure
+ */
+QDF_STATUS
+csr_roam_modify_add_ies(tpAniSirGlobal pMac,
+			 tSirModifyIE *pModifyIE, eUpdateIEsType updateType)
+{
+	tpSirModifyIEsInd pModifyAddIEInd = NULL;
+	uint8_t *pLocalBuffer = NULL;
+	QDF_STATUS status;
+
+	/* following buffer will be freed by consumer (PE) */
+	pLocalBuffer = qdf_mem_malloc(pModifyIE->ieBufferlength);
+	if (!pLocalBuffer)
+		return QDF_STATUS_E_NOMEM;
+
+	pModifyAddIEInd = qdf_mem_malloc(sizeof(tSirModifyIEsInd));
+	if (!pModifyAddIEInd) {
+		qdf_mem_free(pLocalBuffer);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	/*copy the IE buffer */
+	qdf_mem_copy(pLocalBuffer, pModifyIE->pIEBuffer,
+		     pModifyIE->ieBufferlength);
+	qdf_mem_zero(pModifyAddIEInd, sizeof(tSirModifyIEsInd));
+
+	pModifyAddIEInd->msgType = eWNI_SME_MODIFY_ADDITIONAL_IES;
+	pModifyAddIEInd->msgLen = sizeof(tSirModifyIEsInd);
+
+	qdf_copy_macaddr(&pModifyAddIEInd->modifyIE.bssid, &pModifyIE->bssid);
+
+	pModifyAddIEInd->modifyIE.smeSessionId = pModifyIE->smeSessionId;
+	pModifyAddIEInd->modifyIE.notify = pModifyIE->notify;
+	pModifyAddIEInd->modifyIE.ieID = pModifyIE->ieID;
+	pModifyAddIEInd->modifyIE.ieIDLen = pModifyIE->ieIDLen;
+	pModifyAddIEInd->modifyIE.pIEBuffer = pLocalBuffer;
+	pModifyAddIEInd->modifyIE.ieBufferlength = pModifyIE->ieBufferlength;
+	pModifyAddIEInd->modifyIE.oui_length = pModifyIE->oui_length;
+
+	pModifyAddIEInd->updateType = updateType;
+
+	status = umac_send_mb_message_to_mac(pModifyAddIEInd);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg status %d",
+			status);
+		qdf_mem_free(pLocalBuffer);
+	}
+	return status;
+}
+
+/*
+ * csr_roam_update_add_ies -
+ * This function sends msg to updates the additional IE buffers in PE
+ *
+ * @pMac: pMac global structure
+ * @sessionId: SME session id
+ * @bssid: BSSID
+ * @additionIEBuffer: buffer containing addition IE from hostapd
+ * @length: length of buffer
+ * @updateType: Type of buffer
+ * @append: append or replace completely
+ *
+ *
+ * Return: QDF_STATUS -  Success or failure
+ */
+QDF_STATUS
+csr_roam_update_add_ies(tpAniSirGlobal pMac,
+			 tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType)
+{
+	tpSirUpdateIEsInd pUpdateAddIEs = NULL;
+	uint8_t *pLocalBuffer = NULL;
+	QDF_STATUS status;
+
+	if (pUpdateIE->ieBufferlength != 0) {
+		/* Following buffer will be freed by consumer (PE) */
+		pLocalBuffer = qdf_mem_malloc(pUpdateIE->ieBufferlength);
+		if (!pLocalBuffer) {
+			return QDF_STATUS_E_NOMEM;
+		}
+		qdf_mem_copy(pLocalBuffer, pUpdateIE->pAdditionIEBuffer,
+			     pUpdateIE->ieBufferlength);
+	}
+
+	pUpdateAddIEs = qdf_mem_malloc(sizeof(tSirUpdateIEsInd));
+	if (!pUpdateAddIEs) {
+		qdf_mem_free(pLocalBuffer);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	pUpdateAddIEs->msgType = eWNI_SME_UPDATE_ADDITIONAL_IES;
+	pUpdateAddIEs->msgLen = sizeof(tSirUpdateIEsInd);
+
+	qdf_copy_macaddr(&pUpdateAddIEs->updateIE.bssid, &pUpdateIE->bssid);
+
+	pUpdateAddIEs->updateIE.smeSessionId = pUpdateIE->smeSessionId;
+	pUpdateAddIEs->updateIE.append = pUpdateIE->append;
+	pUpdateAddIEs->updateIE.notify = pUpdateIE->notify;
+	pUpdateAddIEs->updateIE.ieBufferlength = pUpdateIE->ieBufferlength;
+	pUpdateAddIEs->updateIE.pAdditionIEBuffer = pLocalBuffer;
+
+	pUpdateAddIEs->updateType = updateType;
+
+	status = umac_send_mb_message_to_mac(pUpdateAddIEs);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg status %d",
+			status);
+		qdf_mem_free(pLocalBuffer);
+	}
+	return status;
+}
+
+/**
+ * csr_send_ext_change_channel()- function to post send ECSA
+ * action frame to lim.
+ * @mac_ctx: pointer to global mac structure
+ * @channel: new channel to switch
+ * @session_id: senssion it should be sent on.
+ *
+ * This function is called to post ECSA frame to lim.
+ *
+ * Return: success if msg posted to LIM else return failure
+ */
+QDF_STATUS csr_send_ext_change_channel(tpAniSirGlobal mac_ctx, uint32_t channel,
+					uint8_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct sir_sme_ext_cng_chan_req *msg;
+
+	msg = qdf_mem_malloc(sizeof(*msg));
+	if (NULL == msg)
+		return QDF_STATUS_E_NOMEM;
+
+	msg->message_type = eWNI_SME_EXT_CHANGE_CHANNEL;
+	msg->length = sizeof(*msg);
+	msg->new_channel = channel;
+	msg->session_id = session_id;
+	status = umac_send_mb_message_to_mac(msg);
+	return status;
+}
+
+#ifdef CONFIG_VDEV_SM
+QDF_STATUS csr_csa_restart(tpAniSirGlobal mac_ctx, uint8_t session_id)
+{
+	QDF_STATUS status;
+	struct scheduler_msg message = {0};
+
+	/* Serialize the req through MC thread */
+	message.bodyval = session_id;
+	message.type    = eWNI_SME_CSA_RESTART_REQ;
+	status = scheduler_post_msg(QDF_MODULE_ID_PE, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("scheduler_post_msg failed!(err=%d)", status);
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+#endif
+
+/**
+ * csr_roam_send_chan_sw_ie_request() - Request to transmit CSA IE
+ * @mac_ctx:        Global MAC context
+ * @bssid:          BSSID
+ * @target_channel: Channel on which to send the IE
+ * @csa_ie_reqd:    Include/Exclude CSA IE.
+ * @ch_params:  operating Channel related information
+ *
+ * This function sends request to transmit channel switch announcement
+ * IE to lower layers
+ *
+ * Return: success or failure
+ **/
+QDF_STATUS csr_roam_send_chan_sw_ie_request(tpAniSirGlobal mac_ctx,
+					    struct qdf_mac_addr bssid,
+					    uint8_t target_channel,
+					    uint8_t csa_ie_reqd,
+					    struct ch_params *ch_params)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirDfsCsaIeRequest *msg;
+
+	msg = qdf_mem_malloc(sizeof(tSirDfsCsaIeRequest));
+	if (!msg)
+		return QDF_STATUS_E_NOMEM;
+
+	msg->msgType = eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ;
+	msg->msgLen = sizeof(tSirDfsCsaIeRequest);
+
+	msg->targetChannel = target_channel;
+	msg->csaIeRequired = csa_ie_reqd;
+	msg->ch_switch_beacon_cnt =
+		 mac_ctx->sap.SapDfsInfo.sap_ch_switch_beacon_cnt;
+	msg->ch_switch_mode = mac_ctx->sap.SapDfsInfo.sap_ch_switch_mode;
+	msg->dfs_ch_switch_disable =
+		mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch;
+	qdf_mem_copy(msg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(&msg->ch_params, ch_params, sizeof(struct ch_params));
+
+	status = umac_send_mb_message_to_mac(msg);
+
+	return status;
+}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+/**
+ * csr_roaming_report_diag_event() - Diag events for LFR3
+ * @mac_ctx:              MAC context
+ * @roam_synch_ind_ptr:   Roam Synch Indication Pointer
+ * @reason:               Reason for this event to happen
+ *
+ * The major events in the host for LFR3 roaming such as
+ * roam synch indication, roam synch completion and
+ * roam synch handoff fail will be indicated to the
+ * diag framework using this API.
+ *
+ * Return: None
+ */
+void csr_roaming_report_diag_event(tpAniSirGlobal mac_ctx,
+		roam_offload_synch_ind *roam_synch_ind_ptr,
+		enum csr_diagwlan_status_eventreason reason)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(roam_connection,
+		host_event_wlan_status_payload_type);
+	qdf_mem_set(&roam_connection,
+		sizeof(host_event_wlan_status_payload_type), 0);
+	switch (reason) {
+	case eCSR_REASON_ROAM_SYNCH_IND:
+		roam_connection.eventId = eCSR_WLAN_STATUS_CONNECT;
+		if (roam_synch_ind_ptr) {
+			roam_connection.rssi = roam_synch_ind_ptr->rssi;
+			roam_connection.channel =
+				cds_freq_to_chan(roam_synch_ind_ptr->chan_freq);
+		}
+		break;
+	case eCSR_REASON_ROAM_SYNCH_CNF:
+		roam_connection.eventId = eCSR_WLAN_STATUS_CONNECT;
+		break;
+	case eCSR_REASON_ROAM_HO_FAIL:
+		roam_connection.eventId = eCSR_WLAN_STATUS_DISCONNECT;
+		break;
+	default:
+		sme_err("LFR3: Unsupported reason %d", reason);
+		return;
+	}
+	roam_connection.reason = reason;
+	WLAN_HOST_DIAG_EVENT_REPORT(&roam_connection, EVENT_WLAN_STATUS_V2);
+}
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/*
+ * fn csr_process_ho_fail_ind
+ * brief  This function will process the Hand Off Failure indication
+ *        received from the firmware. It will trigger a disconnect on
+ *        the session which the firmware reported a hand off failure
+ * param  pMac global structure
+ * param  pMsgBuf - Contains the session ID for which the handler should apply
+ */
+void csr_process_ho_fail_ind(tpAniSirGlobal mac_ctx, void *pMsgBuf)
+{
+	tSirSmeHOFailureInd *pSmeHOFailInd = (tSirSmeHOFailureInd *) pMsgBuf;
+	uint32_t sessionId;
+
+	if (pSmeHOFailInd)
+		sessionId = pSmeHOFailInd->sessionId;
+	else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "LFR3: Hand-Off Failure Ind is NULL");
+		return;
+	}
+	/* Roaming is supported only on Infra STA Mode. */
+	if (!csr_roam_is_sta_mode(mac_ctx, sessionId)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "LFR3:HO Fail cannot be handled for session %d",
+			  sessionId);
+		return;
+	}
+	mac_ctx->sme.set_connection_info_cb(false);
+	csr_roam_roaming_offload_timer_action(mac_ctx, 0, sessionId,
+			ROAMING_OFFLOAD_TIMER_STOP);
+	csr_roam_call_callback(mac_ctx, sessionId, NULL, 0,
+			eCSR_ROAM_NAPI_OFF, eCSR_ROAM_RESULT_FAILURE);
+	csr_roam_synch_clean_up(mac_ctx, sessionId);
+	csr_roaming_report_diag_event(mac_ctx, NULL,
+			eCSR_REASON_ROAM_HO_FAIL);
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+		  "LFR3:Issue Disconnect on session %d", sessionId);
+	csr_roam_disconnect(mac_ctx, sessionId,
+			eCSR_DISCONNECT_REASON_ROAM_HO_FAIL);
+	if (mac_ctx->mlme_cfg->gen.fatal_event_trigger)
+		cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+				WLAN_LOG_INDICATOR_HOST_DRIVER,
+				WLAN_LOG_REASON_ROAM_HO_FAILURE,
+				true, false);
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+/**
+ * csr_update_op_class_array() - update op class for each band
+ * @mac_ctx:          mac global context
+ * @op_classes:       out param, operating class array to update
+ * @channel_info:     channel info
+ * @ch_name:          channel band name to display in debug messages
+ * @i:                out param, stores number of operating classes
+ *
+ * Return: void
+ */
+static void
+csr_update_op_class_array(tpAniSirGlobal mac_ctx,
+			  uint8_t *op_classes,
+			  struct csr_channel *channel_info,
+			  char *ch_name,
+			  uint8_t *i)
+{
+	uint8_t j = 0, idx = 0, class = 0;
+	bool found = false;
+	uint8_t num_channels = channel_info->numChannels;
+	uint8_t ch_bandwidth;
+
+	sme_debug("Num of %s channels,  %d",
+		ch_name, num_channels);
+
+	for (idx = 0; idx < num_channels &&
+			*i < (REG_MAX_SUPP_OPER_CLASSES - 1); idx++) {
+		for (ch_bandwidth = BW20; ch_bandwidth < BWALL;
+			ch_bandwidth++) {
+			class = wlan_reg_dmn_get_opclass_from_channel(
+					mac_ctx->scan.countryCodeCurrent,
+					channel_info->channelList[idx],
+					ch_bandwidth);
+			sme_debug("for chan %d, op class: %d",
+				channel_info->channelList[idx], class);
+
+			found = false;
+			for (j = 0; j < REG_MAX_SUPP_OPER_CLASSES - 1;
+				j++) {
+				if (op_classes[j] == class) {
+					found = true;
+					break;
+				}
+			}
+
+			if (!found) {
+				op_classes[*i] = class;
+				*i = *i + 1;
+			}
+		}
+	}
+}
+
+/**
+ * csr_init_operating_classes() - update op class for all bands
+ * @mac: pointer to mac context.
+ *
+ * Return: void
+ */
+static void csr_init_operating_classes(struct mac_context *mac)
+{
+	uint8_t i = 0;
+	uint8_t j = 0;
+	uint8_t swap = 0;
+	uint8_t numClasses = 0;
+	uint8_t opClasses[REG_MAX_SUPP_OPER_CLASSES] = {0,};
+
+	sme_debug("Current Country = %c%c",
+		  mac->scan.countryCodeCurrent[0],
+		  mac->scan.countryCodeCurrent[1]);
+
+	csr_update_op_class_array(mac, opClasses,
+				  &mac->scan.base_channels, "20MHz", &i);
+	numClasses = i;
+
+	/* As per spec the operating classes should be in ascending order.
+	 * Bubble sort is fine since we don't have many classes
+	 */
+	for (i = 0; i < (numClasses - 1); i++) {
+		for (j = 0; j < (numClasses - i - 1); j++) {
+			/* For decreasing order use < */
+			if (opClasses[j] > opClasses[j + 1]) {
+				swap = opClasses[j];
+				opClasses[j] = opClasses[j + 1];
+				opClasses[j + 1] = swap;
+			}
+		}
+	}
+
+	sme_debug("Number of unique supported op classes %d",
+		numClasses);
+	for (i = 0; i < numClasses; i++)
+		sme_debug("supported opClasses[%d] = %d", i, opClasses[i]);
+
+	/* Set the ordered list of op classes in regdomain
+	 * for use by other modules
+	 */
+	wlan_reg_dmn_set_curr_opclasses(numClasses, &opClasses[0]);
+}
+
+/**
+ * csr_find_session_by_type() - This function will find given session type from
+ * all sessions.
+ * @mac_ctx: pointer to mac context.
+ * @type:    session type
+ *
+ * Return: session id for give session type.
+ **/
+static uint32_t
+csr_find_session_by_type(tpAniSirGlobal mac_ctx, enum QDF_OPMODE type)
+{
+	uint32_t i, session_id = CSR_SESSION_ID_INVALID;
+	struct csr_roam_session *session_ptr;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (!CSR_IS_SESSION_VALID(mac_ctx, i))
+			continue;
+
+		session_ptr = CSR_GET_SESSION(mac_ctx, i);
+		if (type == session_ptr->bssParams.bssPersona) {
+			session_id = i;
+			break;
+		}
+	}
+	return session_id;
+}
+/**
+ * csr_find_session_by_bssid() - This function will find given bssid from
+ * all sessions.
+ * @mac_ctx: pointer to mac context.
+ * @bssid: session bssid
+ * Return: false or true.
+ **/
+bool
+csr_find_session_by_bssid(tpAniSirGlobal mac_ctx, uint8_t *bssid)
+{
+	tpPESession session_entry;
+	uint8_t session_id;      /* PE session_id */
+
+	session_entry = pe_find_session_by_bssid(mac_ctx,
+						 bssid, &session_id);
+	if (session_entry)
+		return true;
+	else
+		return false;
+}
+
+/**
+ * csr_is_conn_allow_2g_band() - This function will check if station's conn
+ * is allowed in 2.4Ghz band.
+ * @mac_ctx: pointer to mac context.
+ * @chnl: station's channel.
+ *
+ * This function will check if station's connection is allowed in 5Ghz band
+ * after comparing it with SAP's operating channel. If SAP's operating
+ * channel and Station's channel is different than this function will return
+ * false else true.
+ *
+ * Return: true or false.
+ **/
+static bool csr_is_conn_allow_2g_band(tpAniSirGlobal mac_ctx, uint32_t chnl)
+{
+	uint32_t sap_session_id;
+	struct csr_roam_session *sap_session;
+
+	if (0 == chnl) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("channel is zero, connection not allowed"));
+
+		return false;
+	}
+
+	sap_session_id = csr_find_session_by_type(mac_ctx, QDF_SAP_MODE);
+	if (CSR_SESSION_ID_INVALID != sap_session_id) {
+		sap_session = CSR_GET_SESSION(mac_ctx, sap_session_id);
+		if ((0 != sap_session->bssParams.operationChn) &&
+				(sap_session->bssParams.operationChn != chnl)) {
+
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"Can't allow STA to connect, chnls not same");
+			return false;
+		}
+	}
+	return true;
+}
+
+/**
+ * csr_is_conn_allow_5g_band() - This function will check if station's conn
+ * is allowed in 5Ghz band.
+ * @mac_ctx: pointer to mac context.
+ * @chnl: station's channel.
+ *
+ * This function will check if station's connection is allowed in 5Ghz band
+ * after comparing it with P2PGO's operating channel. If P2PGO's operating
+ * channel and Station's channel is different than this function will return
+ * false else true.
+ *
+ * Return: true or false.
+ **/
+static bool csr_is_conn_allow_5g_band(tpAniSirGlobal mac_ctx, uint32_t chnl)
+{
+	uint32_t p2pgo_session_id;
+	struct csr_roam_session *p2pgo_session;
+
+	if (0 == chnl) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("channel is zero, connection not allowed"));
+		return false;
+	}
+
+	p2pgo_session_id = csr_find_session_by_type(mac_ctx, QDF_P2P_GO_MODE);
+	if (CSR_SESSION_ID_INVALID != p2pgo_session_id) {
+		p2pgo_session = CSR_GET_SESSION(mac_ctx, p2pgo_session_id);
+		if ((0 != p2pgo_session->bssParams.operationChn) &&
+				(eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED !=
+				 p2pgo_session->connectState) &&
+				(p2pgo_session->bssParams.operationChn !=
+				 chnl)) {
+
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"Can't allow STA to connect, chnls not same");
+			return false;
+		}
+	}
+	return true;
+}
+
+/**
+ * csr_clear_joinreq_param() - This function will clear station's params
+ * for stored join request to csr.
+ * @hal_handle: pointer to hal context.
+ * @session_id: station's session id.
+ *
+ * This function will clear station's allocated memory for cached join
+ * request.
+ *
+ * Return: true or false based on function's overall success.
+ **/
+bool csr_clear_joinreq_param(tpAniSirGlobal mac_ctx,
+		uint32_t session_id)
+{
+	struct csr_roam_session *sta_session;
+	struct scan_result_list *bss_list;
+
+	if (NULL == mac_ctx)
+		return false;
+
+	sta_session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (NULL == sta_session)
+		return false;
+
+	/* Release the memory allocated by previous join request */
+	bss_list =
+		(struct scan_result_list *)&sta_session->stored_roam_profile.
+		bsslist_handle;
+	if (NULL != bss_list) {
+		csr_scan_result_purge(mac_ctx,
+			sta_session->stored_roam_profile.bsslist_handle);
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("bss list is released for session %d"), session_id);
+		sta_session->stored_roam_profile.bsslist_handle = NULL;
+	}
+	sta_session->stored_roam_profile.bsslist_handle = NULL;
+	csr_release_profile(mac_ctx, &sta_session->stored_roam_profile.profile);
+	sta_session->stored_roam_profile.reason = 0;
+	sta_session->stored_roam_profile.roam_id = 0;
+	sta_session->stored_roam_profile.imediate_flag = false;
+	sta_session->stored_roam_profile.clear_flag = false;
+	return true;
+}
+
+/**
+ * csr_store_joinreq_param() - This function will store station's join
+ * request to that station's session.
+ * @mac_ctx: pointer to mac context.
+ * @profile: pointer to station's roam profile.
+ * @scan_cache: pointer to station's scan cache.
+ * @roam_id: reference to roam_id variable being passed.
+ * @session_id: station's session id.
+ *
+ * This function will store station's join request to one of the
+ * csr structure and add it to station's session.
+ *
+ * Return: true or false based on function's overall success.
+ **/
+bool csr_store_joinreq_param(tpAniSirGlobal mac_ctx,
+		struct csr_roam_profile *profile,
+		tScanResultHandle scan_cache,
+		uint32_t *roam_id,
+		uint32_t session_id)
+{
+	struct csr_roam_session *sta_session;
+
+	if (NULL == mac_ctx)
+		return false;
+
+	sta_session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (NULL == sta_session)
+		return false;
+
+	sta_session->stored_roam_profile.session_id = session_id;
+	csr_roam_copy_profile(mac_ctx,
+			&sta_session->stored_roam_profile.profile, profile);
+	/* new bsslist_handle's memory will be relased later */
+	sta_session->stored_roam_profile.bsslist_handle = scan_cache;
+	sta_session->stored_roam_profile.reason = eCsrHddIssued;
+	sta_session->stored_roam_profile.roam_id = *roam_id;
+	sta_session->stored_roam_profile.imediate_flag = false;
+	sta_session->stored_roam_profile.clear_flag = false;
+
+	return true;
+}
+
+/**
+ * csr_issue_stored_joinreq() - This function will issues station's stored
+ * the join request.
+ * @mac_ctx: pointer to mac context.
+ * @roam_id: reference to roam_id variable being passed.
+ * @session_id: station's session id.
+ *
+ * This function will issue station's stored join request, from this point
+ * onwards the flow will be just like normal connect request.
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
+ **/
+QDF_STATUS csr_issue_stored_joinreq(tpAniSirGlobal mac_ctx,
+		uint32_t *roam_id,
+		uint32_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *sta_session;
+	uint32_t new_roam_id;
+
+	sta_session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (NULL == sta_session)
+		return QDF_STATUS_E_FAILURE;
+	new_roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam);
+	*roam_id = new_roam_id;
+	status = csr_roam_issue_connect(mac_ctx,
+			sta_session->stored_roam_profile.session_id,
+			&sta_session->stored_roam_profile.profile,
+			sta_session->stored_roam_profile.bsslist_handle,
+			sta_session->stored_roam_profile.reason,
+			new_roam_id,
+			sta_session->stored_roam_profile.imediate_flag,
+			sta_session->stored_roam_profile.clear_flag);
+
+	sta_session->stored_roam_profile.bsslist_handle =
+					CSR_INVALID_SCANRESULT_HANDLE;
+
+	if (QDF_STATUS_SUCCESS != status) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL
+			("CSR failed issuing connect cmd with status = 0x%08X"),
+				status);
+		csr_clear_joinreq_param(mac_ctx, session_id);
+	}
+	return status;
+}
+
+/**
+ * csr_process_set_hw_mode() - Set HW mode command to PE
+ * @mac: Globacl MAC pointer
+ * @command: Command received from SME
+ *
+ * Posts the set HW mode command to PE. This message passing
+ * through PE is required for PE's internal management
+ *
+ * Return: None
+ */
+void csr_process_set_hw_mode(tpAniSirGlobal mac, tSmeCmd *command)
+{
+	uint32_t len;
+	struct s_sir_set_hw_mode *cmd = NULL;
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+	struct sir_set_hw_mode_resp *param;
+	enum policy_mgr_hw_mode_change hw_mode;
+
+	/* Setting HW mode is for the entire system.
+	 * So, no need to check session
+	 */
+
+	if (!command) {
+		sme_err("Set HW mode param is NULL");
+		goto fail;
+	}
+
+	len = sizeof(*cmd);
+	cmd = qdf_mem_malloc(len);
+	if (!cmd)
+		/* Probably the fail response will also fail during malloc.
+		 * Still proceeding to send response!
+		 */
+		goto fail;
+
+	/* For hidden SSID case, if there is any scan command pending
+	 * it needs to be cleared before issuing set HW mode
+	 */
+	if (command->u.set_hw_mode_cmd.reason ==
+		POLICY_MGR_UPDATE_REASON_HIDDEN_STA) {
+		sme_err("clear any pending scan command");
+		status = csr_scan_abort_mac_scan(mac,
+			command->u.set_hw_mode_cmd.session_id, INVAL_SCAN_ID);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("Failed to clear scan cmd");
+			goto fail;
+		}
+	}
+
+	if ((POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC ==
+		command->u.set_hw_mode_cmd.reason) &&
+		(true == mac->sme.get_connection_info_cb(NULL, NULL))) {
+		sme_err("Set HW mode refused: conn in progress");
+		policy_mgr_restart_opportunistic_timer(mac->psoc, false);
+		goto fail;
+	}
+
+	if ((POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC ==
+		command->u.set_hw_mode_cmd.reason) &&
+		(!command->u.set_hw_mode_cmd.hw_mode_index &&
+		!policy_mgr_need_opportunistic_upgrade(mac->psoc, NULL))) {
+		sme_err("Set HW mode to SMM not needed anymore");
+		goto fail;
+	}
+
+	hw_mode = policy_mgr_get_hw_mode_change_from_hw_mode_index(
+			mac->psoc, command->u.set_hw_mode_cmd.hw_mode_index);
+
+	if (POLICY_MGR_HW_MODE_NOT_IN_PROGRESS == hw_mode) {
+		sme_err("hw_mode %d, failing", hw_mode);
+		goto fail;
+	}
+
+	policy_mgr_set_hw_mode_change_in_progress(mac->psoc, hw_mode);
+
+	cmd->messageType = eWNI_SME_SET_HW_MODE_REQ;
+	cmd->length = len;
+	cmd->set_hw.hw_mode_index = command->u.set_hw_mode_cmd.hw_mode_index;
+	cmd->set_hw.reason = command->u.set_hw_mode_cmd.reason;
+	/*
+	 * Below callback and context info are not needed for PE as of now.
+	 * Storing the passed value in the same s_sir_set_hw_mode format.
+	 */
+	cmd->set_hw.set_hw_mode_cb = command->u.set_hw_mode_cmd.set_hw_mode_cb;
+
+	sme_debug(
+		"Posting set hw mode req to PE session:%d reason:%d",
+		command->u.set_hw_mode_cmd.session_id,
+		command->u.set_hw_mode_cmd.reason);
+
+	status = umac_send_mb_message_to_mac(cmd);
+	if (QDF_STATUS_SUCCESS != status) {
+		policy_mgr_set_hw_mode_change_in_progress(mac->psoc,
+			POLICY_MGR_HW_MODE_NOT_IN_PROGRESS);
+		sme_err("Posting to PE failed");
+		cmd = NULL;
+		goto fail;
+	}
+	return;
+fail:
+	if (cmd)
+		qdf_mem_free(cmd);
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return;
+
+	sme_err("Sending set HW fail response to SME");
+	param->status = SET_HW_MODE_STATUS_ECANCELED;
+	param->cfgd_hw_mode_index = 0;
+	param->num_vdev_mac_entries = 0;
+	msg.type = eWNI_SME_SET_HW_MODE_RESP;
+	msg.bodyptr = param;
+	msg.bodyval = 0;
+	sys_process_mmh_msg(mac, &msg);
+}
+
+/**
+ * csr_process_set_dual_mac_config() - Set HW mode command to PE
+ * @mac: Global MAC pointer
+ * @command: Command received from SME
+ *
+ * Posts the set dual mac config command to PE.
+ *
+ * Return: None
+ */
+void csr_process_set_dual_mac_config(tpAniSirGlobal mac, tSmeCmd *command)
+{
+	uint32_t len;
+	struct sir_set_dual_mac_cfg *cmd;
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+	struct sir_dual_mac_config_resp *param;
+
+	/* Setting MAC configuration is for the entire system.
+	 * So, no need to check session
+	 */
+
+	if (!command) {
+		sme_err("Set HW mode param is NULL");
+		goto fail;
+	}
+
+	len = sizeof(*cmd);
+	cmd = qdf_mem_malloc(len);
+	if (!cmd)
+		/* Probably the fail response will also fail during malloc.
+		 * Still proceeding to send response!
+		 */
+		goto fail;
+
+	cmd->message_type = eWNI_SME_SET_DUAL_MAC_CFG_REQ;
+	cmd->length = len;
+	cmd->set_dual_mac.scan_config = command->u.set_dual_mac_cmd.scan_config;
+	cmd->set_dual_mac.fw_mode_config =
+		command->u.set_dual_mac_cmd.fw_mode_config;
+	/*
+	 * Below callback and context info are not needed for PE as of now.
+	 * Storing the passed value in the same sir_set_dual_mac_cfg format.
+	 */
+	cmd->set_dual_mac.set_dual_mac_cb =
+		command->u.set_dual_mac_cmd.set_dual_mac_cb;
+
+	sme_debug("Posting eWNI_SME_SET_DUAL_MAC_CFG_REQ to PE: %x %x",
+		  cmd->set_dual_mac.scan_config,
+		  cmd->set_dual_mac.fw_mode_config);
+
+	status = umac_send_mb_message_to_mac(cmd);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("Posting to PE failed");
+		goto fail;
+	}
+	return;
+fail:
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return;
+
+	sme_err("Sending set dual mac fail response to SME");
+	param->status = SET_HW_MODE_STATUS_ECANCELED;
+	msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP;
+	msg.bodyptr = param;
+	msg.bodyval = 0;
+	sys_process_mmh_msg(mac, &msg);
+}
+
+/**
+ * csr_process_set_antenna_mode() - Set antenna mode command to
+ * PE
+ * @mac: Global MAC pointer
+ * @command: Command received from SME
+ *
+ * Posts the set dual mac config command to PE.
+ *
+ * Return: None
+ */
+void csr_process_set_antenna_mode(tpAniSirGlobal mac, tSmeCmd *command)
+{
+	uint32_t len;
+	struct sir_set_antenna_mode *cmd;
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+	struct sir_antenna_mode_resp *param;
+
+	/* Setting MAC configuration is for the entire system.
+	 * So, no need to check session
+	 */
+
+	if (!command) {
+		sme_err("Set antenna mode param is NULL");
+		goto fail;
+	}
+
+	len = sizeof(*cmd);
+	cmd = qdf_mem_malloc(len);
+	if (!cmd)
+		goto fail;
+
+	cmd->message_type = eWNI_SME_SET_ANTENNA_MODE_REQ;
+	cmd->length = len;
+	cmd->set_antenna_mode = command->u.set_antenna_mode_cmd;
+
+	sme_debug(
+		"Posting eWNI_SME_SET_ANTENNA_MODE_REQ to PE: %d %d",
+		cmd->set_antenna_mode.num_rx_chains,
+		cmd->set_antenna_mode.num_tx_chains);
+
+	status = umac_send_mb_message_to_mac(cmd);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("Posting to PE failed");
+		/*
+		 * umac_send_mb_message_to_mac would've released the mem
+		 * allocated by cmd.
+		 */
+		goto fail;
+	}
+
+	return;
+fail:
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return;
+
+	sme_err("Sending set dual mac fail response to SME");
+	param->status = SET_ANTENNA_MODE_STATUS_ECANCELED;
+	msg.type = eWNI_SME_SET_ANTENNA_MODE_RESP;
+	msg.bodyptr = param;
+	msg.bodyval = 0;
+	sys_process_mmh_msg(mac, &msg);
+}
+
+/**
+ * csr_process_nss_update_req() - Update nss command to PE
+ * @mac: Globacl MAC pointer
+ * @command: Command received from SME
+ *
+ * Posts the nss update command to PE. This message passing
+ * through PE is required for PE's internal management
+ *
+ * Return: None
+ */
+void csr_process_nss_update_req(tpAniSirGlobal mac, tSmeCmd *command)
+{
+	uint32_t len;
+	struct sir_nss_update_request *msg;
+	QDF_STATUS status;
+	struct scheduler_msg msg_return = {0};
+	struct sir_bcn_update_rsp *param;
+	struct csr_roam_session *session;
+
+
+	if (!CSR_IS_SESSION_VALID(mac, command->sessionId)) {
+		sme_err("Invalid session id %d", command->sessionId);
+		goto fail;
+	}
+	session = CSR_GET_SESSION(mac, command->sessionId);
+
+	len = sizeof(*msg);
+	msg = qdf_mem_malloc(len);
+	if (!msg)
+		/* Probably the fail response is also fail during malloc.
+		 * Still proceeding to send response!
+		 */
+		goto fail;
+
+	msg->msgType = eWNI_SME_NSS_UPDATE_REQ;
+	msg->msgLen = sizeof(*msg);
+
+	msg->new_nss = command->u.nss_update_cmd.new_nss;
+	msg->vdev_id = command->u.nss_update_cmd.session_id;
+
+	sme_debug("Posting eWNI_SME_NSS_UPDATE_REQ to PE");
+
+	status = umac_send_mb_message_to_mac(msg);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return;
+
+	sme_err("Posting to PE failed");
+fail:
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return;
+
+	sme_err("Sending nss update fail response to SME");
+	param->status = QDF_STATUS_E_FAILURE;
+	param->vdev_id = command->u.nss_update_cmd.session_id;
+	param->reason = REASON_NSS_UPDATE;
+	msg_return.type = eWNI_SME_NSS_UPDATE_RSP;
+	msg_return.bodyptr = param;
+	msg_return.bodyval = 0;
+	sys_process_mmh_msg(mac, &msg_return);
+}
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * csr_roam_fill_tdls_info() - Fill TDLS information
+ * @roam_info: Roaming information buffer
+ * @join_rsp: Join response which has TDLS info
+ *
+ * Return: None
+ */
+void csr_roam_fill_tdls_info(tpAniSirGlobal mac_ctx,
+			     struct csr_roam_info *roam_info,
+			     tpSirSmeJoinRsp join_rsp)
+{
+	roam_info->tdls_prohibited = join_rsp->tdls_prohibited;
+	roam_info->tdls_chan_swit_prohibited =
+		join_rsp->tdls_chan_swit_prohibited;
+	sme_debug(
+		"tdls:prohibit: %d, chan_swit_prohibit: %d",
+		roam_info->tdls_prohibited,
+		roam_info->tdls_chan_swit_prohibited);
+}
+#endif
+
+#if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
+static void csr_copy_fils_join_rsp_roam_info(struct csr_roam_info *roam_info,
+				      roam_offload_synch_ind *roam_synch_data)
+{
+	struct fils_join_rsp_params *roam_fils_info;
+
+	roam_info->fils_join_rsp = qdf_mem_malloc(sizeof(*roam_fils_info));
+	if (!roam_info->fils_join_rsp)
+		return;
+
+	roam_fils_info = roam_info->fils_join_rsp;
+	cds_copy_hlp_info(&roam_synch_data->dst_mac,
+			&roam_synch_data->src_mac,
+			roam_synch_data->hlp_data_len,
+			roam_synch_data->hlp_data,
+			&roam_fils_info->dst_mac,
+			&roam_fils_info->src_mac,
+			&roam_fils_info->hlp_data_len,
+			roam_fils_info->hlp_data);
+}
+#else
+static inline
+void csr_copy_fils_join_rsp_roam_info(struct csr_roam_info *roam_info,
+				      roam_offload_synch_ind *roam_synch_data)
+{}
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static QDF_STATUS csr_process_roam_sync_callback(tpAniSirGlobal mac_ctx,
+		roam_offload_synch_ind *roam_synch_data,
+		tpSirBssDescription bss_desc, enum sir_roam_op_code reason)
+{
+	uint8_t session_id = roam_synch_data->roamedVdevId;
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+	tDot11fBeaconIEs *ies_local = NULL;
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	struct csr_roam_info *roam_info;
+	tCsrRoamConnectedProfile *conn_profile = NULL;
+	sme_QosAssocInfo assoc_info;
+	tpAddBssParams add_bss_params;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tPmkidCacheInfo pmkid_cache;
+	uint32_t pmkid_index;
+	uint16_t len;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	tSirSmeHTProfile *src_profile = NULL;
+	tCsrRoamHTProfile *dst_profile = NULL;
+#endif
+
+	if (!session) {
+		sme_err("LFR3: Session not found");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_debug("LFR3: reason: %d", reason);
+	switch (reason) {
+	case SIR_ROAMING_DEREGISTER_STA:
+		/*
+		 * The following is the first thing done in CSR
+		 * after receiving RSI. Hence stopping the timer here.
+		 */
+		csr_roam_roaming_offload_timer_action(mac_ctx,
+				0, session_id, ROAMING_OFFLOAD_TIMER_STOP);
+		if (session->discon_in_progress ||
+		    !CSR_IS_ROAM_JOINED(mac_ctx, session_id)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				FL("LFR3: Session not in connected state or disconnect is in progress %d"),
+				session->discon_in_progress);
+			return QDF_STATUS_E_FAILURE;
+		}
+		csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
+				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, eCSR_ROAM_RESULT_SUCCESS);
+		wlan_abort_scan(mac_ctx->pdev, INVAL_PDEV_ID,
+				session_id, INVAL_SCAN_ID, false);
+		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, 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, eCSR_ROAM_RESULT_SUCCESS);
+		return status;
+	case SIR_ROAMING_INVOKE_FAIL:
+		/* Userspace roam request failed, disconnect with current AP */
+		sme_debug("LFR3: roam invoke from user-space fail, dis cur AP");
+		csr_roam_disconnect(mac_ctx, session_id,
+				    eCSR_DISCONNECT_REASON_DEAUTH);
+		return status;
+	case SIR_ROAM_SYNCH_PROPAGATION:
+		break;
+	case SIR_ROAM_SYNCH_COMPLETE:
+		/*
+		 * Following operations need to be done once roam sync
+		 * completion is sent to FW, hence called here:
+		 * 1) Firmware has already updated DBS policy. Update connection
+		 *    table in the host driver.
+		 * 2) Force SCC switch if needed
+		 * 3) Set connection in progress = false
+		 */
+		/* first update connection info from wma interface */
+		policy_mgr_update_connection_info(mac_ctx->psoc, session_id);
+		/* then update remaining parameters from roam sync ctx */
+		sme_debug("Update DBS hw mode");
+		policy_mgr_hw_mode_transition_cb(
+			roam_synch_data->hw_mode_trans_ind.old_hw_mode_index,
+			roam_synch_data->hw_mode_trans_ind.new_hw_mode_index,
+			roam_synch_data->hw_mode_trans_ind.num_vdev_mac_entries,
+			roam_synch_data->hw_mode_trans_ind.vdev_mac_map,
+			mac_ctx->psoc);
+		mac_ctx->sme.set_connection_info_cb(false);
+		session->roam_synch_in_progress = false;
+		policy_mgr_check_concurrent_intf_and_restart_sap(mac_ctx->psoc);
+		csr_roam_offload_scan(mac_ctx, session_id,
+				ROAM_SCAN_OFFLOAD_START,
+				REASON_CONNECT);
+		return status;
+	default:
+		sme_debug("LFR3: callback reason %d", reason);
+		return QDF_STATUS_E_FAILURE;
+	}
+	session->roam_synch_in_progress = true;
+	session->roam_synch_data = roam_synch_data;
+	status = csr_get_parsed_bss_description_ies(
+			mac_ctx, bss_desc, &ies_local);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("LFR3: fail to parse IEs");
+		session->roam_synch_in_progress = false;
+		return status;
+	}
+	conn_profile = &session->connectedProfile;
+	csr_roam_stop_network(mac_ctx, session_id,
+		session->pCurRoamProfile,
+		bss_desc,
+		ies_local);
+	ps_global_info->remain_in_power_active_till_dhcp = false;
+	session->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+	roam_info = qdf_mem_malloc(sizeof(struct csr_roam_info));
+	if (!roam_info) {
+		session->roam_synch_in_progress = false;
+		qdf_mem_free(ies_local);
+		return QDF_STATUS_E_NOMEM;
+	}
+	csr_scan_save_roam_offload_ap_to_scan_cache(mac_ctx, roam_synch_data,
+			bss_desc);
+	roam_info->sessionId = session_id;
+
+	qdf_mem_copy(&roam_info->bssid.bytes, &bss_desc->bssId,
+			sizeof(struct qdf_mac_addr));
+	csr_roam_save_connected_information(mac_ctx, session_id,
+			session->pCurRoamProfile,
+			bss_desc,
+			ies_local);
+	csr_roam_save_security_rsp_ie(mac_ctx, session_id,
+			session->pCurRoamProfile->negotiatedAuthType,
+			bss_desc, ies_local);
+
+#ifdef FEATURE_WLAN_ESE
+	roam_info->isESEAssoc = conn_profile->isESEAssoc;
+#endif
+
+	/*
+	 * Encryption keys for new connection are obtained as follows:
+	 * authStatus = CSR_ROAM_AUTH_STATUS_AUTHENTICATED
+	 * Open - No keys required.
+	 * Static WEP - Firmware copies keys from old AP to new AP.
+	 * Fast roaming authentications e.g. PSK, FT, CCKM - firmware
+	 *      supplicant obtains them through 4-way handshake.
+	 *
+	 * authStatus = CSR_ROAM_AUTH_STATUS_CONNECTED
+	 * All other authentications - Host supplicant performs EAPOL
+	 *      with AP after this point and sends new keys to the driver.
+	 *      Driver starts wait_for_key timer for that purpose.
+	 */
+	if (roam_synch_data->authStatus
+				== CSR_ROAM_AUTH_STATUS_AUTHENTICATED) {
+		QDF_TRACE(QDF_MODULE_ID_SME,
+				QDF_TRACE_LEVEL_DEBUG,
+				FL("LFR3:Don't start waitforkey timer"));
+		csr_roam_substate_change(mac_ctx,
+				eCSR_ROAM_SUBSTATE_NONE, session_id);
+		/*
+		 * If authStatus is AUTHENTICATED, then we have done successful
+		 * 4 way handshake in FW using the cached PMKID.
+		 * However, the session->psk_pmk has the PMK of the older AP
+		 * as set_key is not received from supplicant.
+		 * When any RSO command is sent for the current AP, the older
+		 * AP's PMK is sent to the FW which leads to incorrect PMK and
+		 * leads to 4 way handshake failure when roaming happens to
+		 * this AP again.
+		 * Check if a PMK cache exists for the roamed AP and update
+		 * it into the session pmk.
+		 */
+		qdf_mem_zero(&pmkid_cache, sizeof(pmkid_cache));
+		qdf_copy_macaddr(&pmkid_cache.BSSID,
+				 &session->connectedProfile.bssid);
+		sme_debug("Trying to find PMKID for " QDF_MAC_ADDR_STR,
+			  QDF_MAC_ADDR_ARRAY(pmkid_cache.BSSID.bytes));
+		if (csr_lookup_pmkid_using_bssid(mac_ctx, session,
+						 &pmkid_cache,
+						 &pmkid_index)) {
+			session->pmk_len =
+				session->PmkidCacheInfo[pmkid_index].pmk_len;
+			qdf_mem_zero(session->psk_pmk,
+				     sizeof(session->psk_pmk));
+			qdf_mem_copy(session->psk_pmk,
+				     session->PmkidCacheInfo[pmkid_index].pmk,
+				     session->pmk_len);
+			sme_debug("pmkid found for " QDF_MAC_ADDR_STR " at %d len %d",
+				  QDF_MAC_ADDR_ARRAY(pmkid_cache.BSSID.bytes),
+				  pmkid_index, (uint32_t)session->pmk_len);
+		} else {
+			sme_debug("PMKID Not found in cache for " QDF_MAC_ADDR_STR,
+				  QDF_MAC_ADDR_ARRAY(pmkid_cache.BSSID.bytes));
+		}
+	} else {
+		roam_info->fAuthRequired = true;
+		csr_roam_substate_change(mac_ctx,
+				eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY,
+				session_id);
+
+		ps_global_info->remain_in_power_active_till_dhcp = true;
+		mac_ctx->roam.WaitForKeyTimerInfo.sessionId = session_id;
+		if (!QDF_IS_STATUS_SUCCESS(csr_roam_start_wait_for_key_timer(
+				mac_ctx, CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD))
+		   ) {
+			sme_err("Failed wait for key timer start");
+			csr_roam_substate_change(mac_ctx,
+					eCSR_ROAM_SUBSTATE_NONE,
+					session_id);
+		}
+	}
+	roam_info->nBeaconLength = 0;
+	roam_info->nAssocReqLength = roam_synch_data->reassoc_req_length -
+		SIR_MAC_HDR_LEN_3A - SIR_MAC_REASSOC_SSID_OFFSET;
+	roam_info->nAssocRspLength = roam_synch_data->reassocRespLength -
+		SIR_MAC_HDR_LEN_3A;
+	roam_info->pbFrames = qdf_mem_malloc(roam_info->nBeaconLength +
+		roam_info->nAssocReqLength + roam_info->nAssocRspLength);
+	if (!roam_info->pbFrames) {
+		session->roam_synch_in_progress = false;
+		if (roam_info)
+			qdf_mem_free(roam_info);
+		qdf_mem_free(ies_local);
+		return QDF_STATUS_E_NOMEM;
+	}
+	qdf_mem_copy(roam_info->pbFrames,
+			(uint8_t *)roam_synch_data +
+			roam_synch_data->reassoc_req_offset +
+			SIR_MAC_HDR_LEN_3A + SIR_MAC_REASSOC_SSID_OFFSET,
+			roam_info->nAssocReqLength);
+	qdf_mem_copy(roam_info->pbFrames + roam_info->nAssocReqLength,
+			(uint8_t *)roam_synch_data +
+			roam_synch_data->reassocRespOffset +
+			SIR_MAC_HDR_LEN_3A,
+			roam_info->nAssocRspLength);
+
+	QDF_TRACE(QDF_MODULE_ID_SME,
+			QDF_TRACE_LEVEL_DEBUG,
+			FL("LFR3:Clear Connected info"));
+	csr_roam_free_connected_info(mac_ctx,
+			&session->connectedInfo);
+	len = roam_synch_data->join_rsp->parsedRicRspLen;
+
+#ifdef FEATURE_WLAN_ESE
+	len += roam_synch_data->join_rsp->tspecIeLen;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL("LFR3: tspecLen %d"),
+		roam_synch_data->join_rsp->tspecIeLen);
+#endif
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL("LFR3: RIC length - %d"),
+		roam_synch_data->join_rsp->parsedRicRspLen);
+	if (len) {
+		session->connectedInfo.pbFrames =
+			qdf_mem_malloc(len);
+		if (session->connectedInfo.pbFrames != NULL) {
+			qdf_mem_copy(session->connectedInfo.pbFrames,
+				roam_synch_data->join_rsp->frames, len);
+			session->connectedInfo.nRICRspLength =
+				roam_synch_data->join_rsp->parsedRicRspLen;
+
+#ifdef FEATURE_WLAN_ESE
+			session->connectedInfo.nTspecIeLength =
+				roam_synch_data->join_rsp->tspecIeLen;
+#endif
+		}
+	}
+	conn_profile->vht_channel_width =
+		roam_synch_data->join_rsp->vht_channel_width;
+	add_bss_params = (tpAddBssParams)roam_synch_data->add_bss_params;
+	session->connectedInfo.staId = add_bss_params->staContext.staIdx;
+	roam_info->staId = session->connectedInfo.staId;
+	roam_info->timingMeasCap =
+		roam_synch_data->join_rsp->timingMeasCap;
+	roam_info->chan_info.nss = roam_synch_data->join_rsp->nss;
+	roam_info->chan_info.rate_flags =
+		roam_synch_data->join_rsp->max_rate_flags;
+	roam_info->chan_info.ch_width =
+		roam_synch_data->join_rsp->vht_channel_width;
+	csr_roam_fill_tdls_info(mac_ctx, roam_info, roam_synch_data->join_rsp);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	src_profile = &roam_synch_data->join_rsp->HTProfile;
+	dst_profile = &conn_profile->HTProfile;
+	if (mac_ctx->roam.configParam.cc_switch_mode
+			!= QDF_MCC_TO_SCC_SWITCH_DISABLE)
+		csr_roam_copy_ht_profile(dst_profile,
+				src_profile);
+#endif
+	assoc_info.pBssDesc = bss_desc;
+	roam_info->statusCode = eSIR_SME_SUCCESS;
+	roam_info->reasonCode = eSIR_SME_SUCCESS;
+	assoc_info.pProfile = session->pCurRoamProfile;
+	mac_ctx->roam.roamSession[session_id].connectState =
+		eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+	sme_qos_csr_event_ind(mac_ctx, session_id,
+		SME_QOS_CSR_HANDOFF_ASSOC_REQ, NULL);
+	sme_qos_csr_event_ind(mac_ctx, session_id,
+		SME_QOS_CSR_REASSOC_REQ, NULL);
+	sme_qos_csr_event_ind(mac_ctx, session_id,
+		SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
+	mac_ctx->roam.roamSession[session_id].connectState =
+		eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+	sme_qos_csr_event_ind(mac_ctx, session_id,
+		SME_QOS_CSR_REASSOC_COMPLETE, &assoc_info);
+	roam_info->pBssDesc = bss_desc;
+	conn_profile->acm_mask = sme_qos_get_acm_mask(mac_ctx,
+			bss_desc, NULL);
+	if (conn_profile->modifyProfileFields.uapsd_mask) {
+		sme_debug(
+				" uapsd_mask (0x%X) set, request UAPSD now",
+				conn_profile->modifyProfileFields.uapsd_mask);
+		sme_ps_start_uapsd(MAC_HANDLE(mac_ctx), session_id);
+	}
+	conn_profile->dot11Mode = session->bssParams.uCfgDot11Mode;
+	roam_info->u.pConnectedProfile = conn_profile;
+
+	sme_debug(
+		"vht ch width %d staId %d nss %d rate_flag %d dot11Mode %d",
+		conn_profile->vht_channel_width,
+		roam_info->staId,
+		roam_info->chan_info.nss,
+		roam_info->chan_info.rate_flags,
+		conn_profile->dot11Mode);
+
+	if (!IS_FEATURE_SUPPORTED_BY_FW
+			(SLM_SESSIONIZATION) &&
+			(csr_is_concurrent_session_running(mac_ctx))) {
+		mac_ctx->roam.configParam.doBMPSWorkaround = 1;
+	}
+	roam_info->roamSynchInProgress = true;
+	roam_info->synchAuthStatus = roam_synch_data->authStatus;
+	roam_info->kek_len = roam_synch_data->kek_len;
+	roam_info->pmk_len = roam_synch_data->pmk_len;
+	qdf_mem_copy(roam_info->kck, roam_synch_data->kck, SIR_KCK_KEY_LEN);
+	qdf_mem_copy(roam_info->kek, roam_synch_data->kek, roam_info->kek_len);
+
+	if (roam_synch_data->pmk_len)
+		qdf_mem_copy(roam_info->pmk, roam_synch_data->pmk,
+			     roam_synch_data->pmk_len);
+
+	qdf_mem_copy(roam_info->pmkid, roam_synch_data->pmkid, SIR_PMKID_LEN);
+	roam_info->update_erp_next_seq_num =
+			roam_synch_data->update_erp_next_seq_num;
+	roam_info->next_erp_seq_num = roam_synch_data->next_erp_seq_num;
+	sme_debug("Update ERP Seq Num : %d, Next ERP Seq Num : %d",
+			roam_info->update_erp_next_seq_num,
+			roam_info->next_erp_seq_num);
+	qdf_mem_copy(roam_info->replay_ctr, roam_synch_data->replay_ctr,
+			SIR_REPLAY_CTR_LEN);
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL("LFR3: Copy KCK, KEK(len %d) and Replay Ctr"),
+		roam_info->kek_len);
+	roam_info->subnet_change_status =
+		CSR_GET_SUBNET_STATUS(roam_synch_data->roamReason);
+
+	csr_copy_fils_join_rsp_roam_info(roam_info, roam_synch_data);
+
+	csr_roam_call_callback(mac_ctx, session_id, roam_info, 0,
+		eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_ASSOCIATED);
+	csr_reset_pmkid_candidate_list(mac_ctx, session_id);
+#ifdef FEATURE_WLAN_WAPI
+	csr_reset_bkid_candidate_list(mac_ctx, session_id);
+#endif
+	if (!CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id)) {
+		QDF_TRACE(QDF_MODULE_ID_SME,
+				QDF_TRACE_LEVEL_DEBUG,
+				FL
+				("NO CSR_IS_WAIT_FOR_KEY -> csr_roam_link_up"));
+		csr_roam_link_up(mac_ctx, conn_profile->bssid);
+	}
+
+	session->fRoaming = false;
+	session->roam_synch_in_progress = false;
+	sme_free_join_rsp_fils_params(roam_info);
+	qdf_mem_free(roam_info->pbFrames);
+	qdf_mem_free(roam_info);
+	qdf_mem_free(ies_local);
+
+	return status;
+}
+
+/**
+ * csr_roam_synch_callback() - SME level callback for roam synch propagation
+ * @mac_ctx: MAC Context
+ * @roam_synch_data: Roam synch data buffer pointer
+ * @bss_desc: BSS descriptor pointer
+ * @reason: Reason for calling the callback
+ *
+ * This callback is registered with WMA and used after roaming happens in
+ * firmware and the call to this routine completes the roam synch
+ * propagation at both CSR and HDD levels. The HDD level propagation
+ * is achieved through the already defined callback for assoc completion
+ * handler.
+ *
+ * Return: Success or Failure.
+ */
+QDF_STATUS csr_roam_synch_callback(tpAniSirGlobal mac_ctx,
+		roam_offload_synch_ind *roam_synch_data,
+		tpSirBssDescription  bss_desc, enum sir_roam_op_code reason)
+{
+	QDF_STATUS status;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("LFR3: Locking failed, bailing out");
+		return status;
+	}
+
+	status = csr_process_roam_sync_callback(mac_ctx, roam_synch_data,
+					    bss_desc, reason);
+
+	sme_release_global_lock(&mac_ctx->sme);
+
+	return status;
+}
+#endif
diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c
new file mode 100644
index 0000000..96516a0
--- /dev/null
+++ b/core/sme/src/csr/csr_api_scan.c
@@ -0,0 +1,3280 @@
+/*
+ * Copyright (c) 2011-2018 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: csr_api_scan.c
+ *
+ * Implementation for the Common Scan interfaces.
+ */
+
+#include "ani_global.h"
+
+#include "csr_inside_api.h"
+#include "sme_inside.h"
+
+#include "csr_support.h"
+
+#include "host_diag_core_log.h"
+#include "host_diag_core_event.h"
+
+#include "cds_reg_service.h"
+#include "wma_types.h"
+#include "cds_utils.h"
+#include "cfg_api.h"
+#include "wma.h"
+
+#include "wlan_policy_mgr_api.h"
+#include "wlan_hdd_main.h"
+#include "pld_common.h"
+#include "csr_internal.h"
+#include <wlan_scan_ucfg_api.h>
+#include <wlan_scan_tgt_api.h>
+#include <wlan_scan_utils_api.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_utility.h>
+#include "wlan_reg_services_api.h"
+
+/* Purpose of HIDDEN_TIMER
+ * When we remove hidden ssid from the profile i.e., forget the SSID via GUI
+ * that SSID shouldn't see in the profile For above requirement we used timer
+ * limit, logic is explained below Timer value is initialsed to current time
+ * when it receives corresponding probe response of hidden SSID (The probe
+ * request is received regularly till SSID in the profile. Once it is removed
+ * from profile probe request is not sent.) when we receive probe response for
+ * broadcast probe request, during update SSID with saved SSID we will diff
+ * current time with saved SSID time if it is greater than 1 min then we are
+ * not updating with old one
+ */
+
+#define HIDDEN_TIMER (1*60*1000)
+/* must be less than 100, represent the persentage of new RSSI */
+#define CSR_SCAN_RESULT_RSSI_WEIGHT     80
+#define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL 140
+#define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL 120
+
+#define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 30
+#define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 20
+
+#define PCL_ADVANTAGE 30
+#define PCL_RSSI_THRESHOLD -75
+
+static void csr_set_cfg_valid_channel_list(tpAniSirGlobal pMac, uint8_t
+					*pChannelList, uint8_t NumChannels);
+static void csr_save_tx_power_to_cfg(tpAniSirGlobal pMac, tDblLinkList *pList,
+			      uint32_t cfgId);
+static void csr_set_cfg_country_code(tpAniSirGlobal pMac, uint8_t *countryCode);
+static void csr_purge_channel_power(tpAniSirGlobal pMac, tDblLinkList
+							*pChannelList);
+static bool csr_roam_is_valid_channel(tpAniSirGlobal pMac, uint8_t channel);
+
+#define CSR_IS_SOCIAL_CHANNEL(channel) \
+	(((channel) == 1) || ((channel) == 6) || ((channel) == 11))
+
+/* pResult is invalid calling this function. */
+void csr_free_scan_result_entry(tpAniSirGlobal pMac, struct tag_csrscan_result
+				*pResult)
+{
+	if (NULL != pResult->Result.pvIes)
+		qdf_mem_free(pResult->Result.pvIes);
+
+	qdf_mem_free(pResult);
+}
+
+static QDF_STATUS csr_ll_scan_purge_result(tpAniSirGlobal pMac,
+					   tDblLinkList *pList)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tListElem *pEntry;
+	struct tag_csrscan_result *pBssDesc;
+
+	csr_ll_lock(pList);
+
+	while ((pEntry = csr_ll_remove_head(pList, LL_ACCESS_NOLOCK)) != NULL) {
+		pBssDesc = GET_BASE_ADDR(pEntry, struct tag_csrscan_result,
+					Link);
+		csr_free_scan_result_entry(pMac, pBssDesc);
+	}
+
+	csr_ll_unlock(pList);
+
+	return status;
+}
+
+QDF_STATUS csr_scan_open(tpAniSirGlobal mac_ctx)
+{
+	csr_ll_open(&mac_ctx->scan.channelPowerInfoList24);
+	csr_ll_open(&mac_ctx->scan.channelPowerInfoList5G);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS csr_scan_close(tpAniSirGlobal pMac)
+{
+	csr_purge_channel_power(pMac, &pMac->scan.channelPowerInfoList24);
+	csr_purge_channel_power(pMac, &pMac->scan.channelPowerInfoList5G);
+	csr_ll_close(&pMac->scan.channelPowerInfoList24);
+	csr_ll_close(&pMac->scan.channelPowerInfoList5G);
+	ucfg_scan_set_enable(pMac->psoc, false);
+	return QDF_STATUS_SUCCESS;
+}
+QDF_STATUS csr_scan_handle_search_for_ssid(tpAniSirGlobal mac_ctx,
+					   uint32_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tScanResultHandle hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
+	tCsrScanResultFilter *pScanFilter = NULL;
+	struct csr_roam_profile *profile;
+	struct csr_roam_session *session;
+
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (!session) {
+		sme_err("session %d not found", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	profile = session->scan_info.profile;
+	sme_debug("session %d", session_id);
+	do {
+		/* If this scan is for HDD reassociate */
+		if (mac_ctx->roam.neighborRoamInfo[session_id].
+				uOsRequestedHandoff) {
+			/* notify LFR state m/c */
+			status = csr_neighbor_roam_sssid_scan_done
+				(mac_ctx, session_id, QDF_STATUS_SUCCESS);
+			if (!QDF_IS_STATUS_SUCCESS(status))
+				csr_neighbor_roam_start_lfr_scan(mac_ctx,
+								 session_id);
+			status = QDF_STATUS_SUCCESS;
+			break;
+		}
+		/*
+		 * If there is roam command waiting, ignore this roam because
+		 * the newer roam command is the one to execute
+		 */
+		if (csr_is_roam_command_waiting_for_session(mac_ctx, session_id)) {
+			sme_warn("aborts because roam command waiting");
+			break;
+		}
+		if (profile == NULL)
+			break;
+		pScanFilter = qdf_mem_malloc(sizeof(tCsrScanResultFilter));
+		if (NULL == pScanFilter) {
+			status = QDF_STATUS_E_NOMEM;
+			break;
+		}
+		status = csr_roam_prepare_filter_from_profile(mac_ctx, profile,
+							      pScanFilter);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+		status = csr_scan_get_result(mac_ctx, pScanFilter, &hBSSList);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			break;
+		if (mac_ctx->roam.roamSession[session_id].connectState ==
+				eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING) {
+			sme_err("upper layer issued disconnetion");
+			status = QDF_STATUS_E_FAILURE;
+			break;
+		}
+		status = csr_roam_issue_connect(mac_ctx, session_id, profile,
+						hBSSList, eCsrHddIssued,
+						session->scan_info.roam_id,
+						true, true);
+		hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
+	} while (0);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_INVALID_SCANRESULT_HANDLE != hBSSList) {
+			csr_scan_result_purge(mac_ctx, hBSSList);
+		}
+		/* We haven't done anything to this profile */
+		csr_roam_call_callback(mac_ctx, session_id, NULL,
+				       session->scan_info.roam_id,
+				       eCSR_ROAM_ASSOCIATION_FAILURE,
+				       eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE);
+	}
+	if (pScanFilter) {
+		csr_free_scan_filter(mac_ctx, pScanFilter);
+		qdf_mem_free(pScanFilter);
+	}
+	return status;
+}
+
+/**
+ * csr_handle_fils_scan_for_ssid_failure() - Checks and fills FILS seq number
+ * in roam_info structure to send to hdd
+ *
+ * @roam_profile: Pointer to current roam_profile structure
+ * @roam_info: Pointer to roam_info strucure to be filled
+ *
+ * Return: true for FILS connection else false
+ */
+#ifdef WLAN_FEATURE_FILS_SK
+static bool
+csr_handle_fils_scan_for_ssid_failure(struct csr_roam_profile *roam_profile,
+				      struct csr_roam_info *roam_info)
+{
+	if (roam_profile && roam_profile->fils_con_info &&
+	    roam_profile->fils_con_info->is_fils_connection) {
+		sme_debug("send roam_info for FILS connection failure, seq %d",
+			  roam_profile->fils_con_info->sequence_number);
+		roam_info->is_fils_connection = true;
+		roam_info->fils_seq_num =
+				roam_profile->fils_con_info->sequence_number;
+		return true;
+	}
+
+	return false;
+}
+#else
+static bool
+csr_handle_fils_scan_for_ssid_failure(struct csr_roam_profile *roam_profile,
+				      struct csr_roam_info *roam_info)
+{
+	return false;
+}
+#endif
+
+QDF_STATUS csr_scan_handle_search_for_ssid_failure(tpAniSirGlobal mac_ctx,
+						  uint32_t session_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_profile *profile;
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+	eCsrRoamResult roam_result;
+	struct csr_roam_info *roam_info = NULL;
+	struct tag_csrscan_result *scan_result;
+
+	if (!session) {
+		sme_err("session %d not found", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* If this scan is for HDD reassociate */
+	if (mac_ctx->roam.neighborRoamInfo[session_id].uOsRequestedHandoff) {
+		/* notify LFR state m/c */
+		status = csr_neighbor_roam_sssid_scan_done
+				(mac_ctx, session_id, QDF_STATUS_E_FAILURE);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			csr_neighbor_roam_start_lfr_scan(mac_ctx, session_id);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	profile = session->scan_info.profile;
+
+	/*
+	 * Check whether it is for start ibss. No need to do anything if it
+	 * is a JOIN request
+	 */
+	if (profile && CSR_IS_START_IBSS(profile)) {
+		status = csr_roam_issue_connect(mac_ctx, session_id, profile, NULL,
+				eCsrHddIssued, session->scan_info.roam_id,
+				true, true);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			sme_err("failed to issue startIBSS, session_id %d status: 0x%08X roam id %d",
+				session_id, status, session->scan_info.roam_id);
+			csr_roam_call_callback(mac_ctx, session_id, NULL,
+				session->scan_info.roam_id, eCSR_ROAM_FAILED,
+				eCSR_ROAM_RESULT_FAILURE);
+		}
+		return status;
+	}
+	roam_result = eCSR_ROAM_RESULT_FAILURE;
+	if (NULL != profile && csr_is_bss_type_ibss(profile->BSSType)) {
+		roam_result = eCSR_ROAM_RESULT_IBSS_START_FAILED;
+		goto roam_completion;
+	}
+
+	roam_info = qdf_mem_malloc(sizeof(struct csr_roam_info));
+	if (!roam_info)
+		goto roam_completion;
+
+	if (session->scan_info.roambssentry) {
+		scan_result = GET_BASE_ADDR(session->scan_info.roambssentry,
+				struct tag_csrscan_result, Link);
+		roam_info->pBssDesc = &scan_result->Result.BssDescriptor;
+	}
+	roam_info->statusCode = session->joinFailStatusCode.statusCode;
+	roam_info->reasonCode = session->joinFailStatusCode.reasonCode;
+
+	/* Only indicate assoc_completion if we indicate assoc_start. */
+	if (session->bRefAssocStartCnt > 0) {
+		session->bRefAssocStartCnt--;
+		csr_roam_call_callback(mac_ctx, session_id, roam_info,
+				       session->scan_info.roam_id,
+				       eCSR_ROAM_ASSOCIATION_COMPLETION,
+				       eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE);
+	} else {
+		if (!csr_handle_fils_scan_for_ssid_failure(
+		    profile, roam_info)) {
+			qdf_mem_free(roam_info);
+			roam_info = NULL;
+		}
+		csr_roam_call_callback(mac_ctx, session_id, roam_info,
+				       session->scan_info.roam_id,
+				       eCSR_ROAM_ASSOCIATION_FAILURE,
+				       eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE);
+	}
+
+	if (roam_info)
+		qdf_mem_free(roam_info);
+roam_completion:
+	csr_roam_completion(mac_ctx, session_id, NULL, NULL, roam_result,
+			    false);
+	return status;
+}
+
+QDF_STATUS csr_scan_result_purge(tpAniSirGlobal pMac,
+				 tScanResultHandle hScanList)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	struct scan_result_list *pScanList =
+				(struct scan_result_list *) hScanList;
+
+	if (pScanList) {
+		status = csr_ll_scan_purge_result(pMac, &pScanList->List);
+		csr_ll_close(&pScanList->List);
+		qdf_mem_free(pScanList);
+	}
+	return status;
+}
+
+/* Add the channel to the occupiedChannels array */
+static void csr_scan_add_to_occupied_channels(tpAniSirGlobal pMac,
+					struct tag_csrscan_result *pResult,
+					uint8_t sessionId,
+					struct csr_channel *occupied_ch,
+					tDot11fBeaconIEs *pIes,
+					bool is_init_list)
+{
+	QDF_STATUS status;
+	uint8_t ch;
+	uint8_t num_occupied_ch = occupied_ch->numChannels;
+	uint8_t *occupied_ch_lst = occupied_ch->channelList;
+
+	ch = pResult->Result.BssDescriptor.channelId;
+	if (!csr_neighbor_roam_connected_profile_match(pMac,
+						sessionId, pResult, pIes))
+		return;
+
+	if (is_init_list)
+		pMac->scan.roam_candidate_count[sessionId]++;
+
+	if (csr_is_channel_present_in_list(occupied_ch_lst,
+					   num_occupied_ch, ch))
+		return;
+
+	status = csr_add_to_channel_list_front(occupied_ch_lst,
+					       num_occupied_ch, ch);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		occupied_ch->numChannels++;
+		sme_debug("Added channel %d to the list (count=%d)",
+			ch, occupied_ch->numChannels);
+		if (occupied_ch->numChannels >
+		    CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN)
+			occupied_ch->numChannels =
+				CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN;
+	}
+}
+
+/* Put the BSS into the scan result list */
+/* pIes can not be NULL */
+static void csr_scan_add_result(tpAniSirGlobal mac_ctx,
+				struct tag_csrscan_result *pResult)
+{
+	qdf_nbuf_t buf;
+	uint8_t *data;
+	struct mgmt_rx_event_params rx_param = {0};
+	struct wlan_frame_hdr *hdr;
+	struct wlan_bcn_frame *fixed_frame;
+	uint32_t buf_len, i;
+	tSirBssDescription *bss_desc;
+	enum mgmt_frame_type frm_type = MGMT_BEACON;
+
+	if (!pResult) {
+		sme_err("pResult is null");
+		return;
+	}
+
+	bss_desc = &pResult->Result.BssDescriptor;
+	if (bss_desc->fProbeRsp)
+		frm_type = MGMT_PROBE_RESP;
+
+	rx_param.pdev_id = 0;
+	rx_param.channel = bss_desc->channelId;
+	rx_param.rssi = bss_desc->rssi;
+	rx_param.tsf_delta = bss_desc->tsf_delta;
+
+	/* Set all per chain rssi as invalid */
+	for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++)
+		rx_param.rssi_ctl[i] = WLAN_INVALID_PER_CHAIN_RSSI;
+
+	buf_len = GET_IE_LEN_IN_BSS(bss_desc->length) +
+		+ offsetof(struct wlan_bcn_frame, ie) + sizeof(*hdr);
+
+	buf = qdf_nbuf_alloc(NULL, qdf_roundup(buf_len, 4),
+				0, 4, false);
+	if (!buf)
+		return;
+
+	qdf_nbuf_put_tail(buf, buf_len);
+	qdf_nbuf_set_protocol(buf, ETH_P_CONTROL);
+
+	data = qdf_nbuf_data(buf);
+	hdr = (struct wlan_frame_hdr *) data;
+	qdf_mem_copy(hdr->i_addr3, bss_desc->bssId, QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(hdr->i_addr2, bss_desc->bssId, QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(hdr->i_seq,
+		&bss_desc->seq_ctrl, sizeof(uint16_t));
+
+	data += sizeof(*hdr);
+	fixed_frame = (struct wlan_bcn_frame *)data;
+	qdf_mem_copy(fixed_frame->timestamp,
+		bss_desc->timeStamp, 8);
+	fixed_frame->beacon_interval = bss_desc->beaconInterval;
+	fixed_frame->capability.value = bss_desc->capabilityInfo;
+	data += offsetof(struct wlan_bcn_frame, ie);
+
+	qdf_mem_copy(data, bss_desc->ieFields,
+		GET_IE_LEN_IN_BSS(bss_desc->length));
+	tgt_scan_bcn_probe_rx_callback(mac_ctx->psoc, NULL, buf, &rx_param,
+		frm_type);
+}
+
+/*
+ * NOTE: This routine is being added to make
+ * sure that scan results are not being flushed
+ * while roaming. If the scan results are flushed,
+ * we are unable to recover from
+ * csr_roam_roaming_state_disassoc_rsp_processor.
+ * If it is needed to remove this routine,
+ * first ensure that we recover gracefully from
+ * csr_roam_roaming_state_disassoc_rsp_processor if
+ * csr_scan_get_result returns with a failure because
+ * of not being able to find the roaming BSS.
+ */
+static bool csr_scan_flush_denied(tpAniSirGlobal pMac)
+{
+	uint8_t sessionId;
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+			if (csr_neighbor_middle_of_roaming(pMac, sessionId))
+				return 1;
+		}
+	}
+	return 0;
+}
+
+static bool csr_scan_save_bss_description(tpAniSirGlobal pMac,
+						     tSirBssDescription *
+						     pBSSDescription)
+{
+	struct tag_csrscan_result *pCsrBssDescription = NULL;
+	uint32_t cbBSSDesc;
+	uint32_t cbAllocated;
+
+	/* figure out how big the BSS description is (the BSSDesc->length does
+	 * NOT include the size of the length field itself).
+	 */
+	cbBSSDesc = pBSSDescription->length + sizeof(pBSSDescription->length);
+
+	cbAllocated = sizeof(struct tag_csrscan_result) + cbBSSDesc;
+
+	pCsrBssDescription = qdf_mem_malloc(cbAllocated);
+	if (!pCsrBssDescription)
+		return false;
+
+	pCsrBssDescription->AgingCount =
+		(int32_t) pMac->roam.configParam.agingCount;
+	sme_debug(
+		"Set Aging Count = %d for BSS " MAC_ADDRESS_STR " ",
+		pCsrBssDescription->AgingCount,
+		MAC_ADDR_ARRAY(pCsrBssDescription->Result.BssDescriptor.
+			       bssId));
+	qdf_mem_copy(&pCsrBssDescription->Result.BssDescriptor,
+		     pBSSDescription, cbBSSDesc);
+	csr_scan_add_result(pMac, pCsrBssDescription);
+	csr_free_scan_result_entry(pMac, pCsrBssDescription);
+
+	return true;
+}
+
+/* Append a Bss Description... */
+bool csr_scan_append_bss_description(tpAniSirGlobal pMac,
+				     tSirBssDescription *pSirBssDescription)
+{
+	return csr_scan_save_bss_description(pMac,
+					pSirBssDescription);
+}
+
+static void csr_purge_channel_power(tpAniSirGlobal pMac, tDblLinkList
+					*pChannelList)
+{
+	struct csr_channel_powerinfo *pChannelSet;
+	tListElem *pEntry;
+
+	csr_ll_lock(pChannelList);
+	/*
+	 * Remove the channel sets from the learned list and put them
+	 * in the free list
+	 */
+	while ((pEntry = csr_ll_remove_head(pChannelList,
+					    LL_ACCESS_NOLOCK)) != NULL) {
+		pChannelSet = GET_BASE_ADDR(pEntry,
+					struct csr_channel_powerinfo, link);
+		if (pChannelSet)
+			qdf_mem_free(pChannelSet);
+	}
+	csr_ll_unlock(pChannelList);
+}
+
+/*
+ * Save the channelList into the ultimate storage as the final stage of channel
+ * Input: pCountryInfo -- the country code (e.g. "USI"), channel list, and power
+ * limit are all stored inside this data structure
+ */
+QDF_STATUS csr_save_to_channel_power2_g_5_g(tpAniSirGlobal pMac,
+					    uint32_t tableSize,
+					    tSirMacChanInfo *channelTable)
+{
+	uint32_t i = tableSize / sizeof(tSirMacChanInfo);
+	tSirMacChanInfo *pChannelInfo;
+	struct csr_channel_powerinfo *pChannelSet;
+	bool f2GHzInfoFound = false;
+	bool f2GListPurged = false, f5GListPurged = false;
+
+	pChannelInfo = channelTable;
+	/* atleast 3 bytes have to be remaining  -- from "countryString" */
+	while (i--) {
+	pChannelSet = qdf_mem_malloc(sizeof(struct csr_channel_powerinfo));
+		if (NULL == pChannelSet) {
+			pChannelInfo++;
+			continue;
+		}
+		pChannelSet->firstChannel = pChannelInfo->firstChanNum;
+		pChannelSet->numChannels = pChannelInfo->numChannels;
+		/*
+		 * Now set the inter-channel offset based on the frequency band
+		 * the channel set lies in
+		 */
+		if ((WLAN_REG_IS_24GHZ_CH(pChannelSet->firstChannel)) &&
+		    ((pChannelSet->firstChannel +
+		      (pChannelSet->numChannels - 1)) <=
+		     WLAN_REG_MAX_24GHZ_CH_NUM)) {
+			pChannelSet->interChannelOffset = 1;
+			f2GHzInfoFound = true;
+		} else if ((WLAN_REG_IS_5GHZ_CH(pChannelSet->firstChannel))
+		    && ((pChannelSet->firstChannel +
+		      ((pChannelSet->numChannels - 1) * 4)) <=
+		     WLAN_REG_MAX_5GHZ_CH_NUM)) {
+			pChannelSet->interChannelOffset = 4;
+			f2GHzInfoFound = false;
+		} else {
+			sme_warn("Invalid Channel %d Present in Country IE",
+				pChannelSet->firstChannel);
+			qdf_mem_free(pChannelSet);
+			return QDF_STATUS_E_FAILURE;
+		}
+		pChannelSet->txPower = QDF_MIN(pChannelInfo->maxTxPower,
+					pMac->roam.configParam.nTxPowerCap);
+		if (f2GHzInfoFound) {
+			if (!f2GListPurged) {
+				/* purge previous results if found new */
+				csr_purge_channel_power(pMac,
+							&pMac->scan.
+							channelPowerInfoList24);
+				f2GListPurged = true;
+			}
+			if (CSR_IS_OPERATING_BG_BAND(pMac)) {
+				/* add to the list of 2.4 GHz channel sets */
+				csr_ll_insert_tail(&pMac->scan.
+						   channelPowerInfoList24,
+						   &pChannelSet->link,
+						   LL_ACCESS_LOCK);
+			} else {
+				sme_debug(
+					"Adding 11B/G ch in 11A. 1st ch %d",
+					pChannelSet->firstChannel);
+				qdf_mem_free(pChannelSet);
+			}
+		} else {
+			/* 5GHz info found */
+			if (!f5GListPurged) {
+				/* purge previous results if found new */
+				csr_purge_channel_power(pMac,
+							&pMac->scan.
+							channelPowerInfoList5G);
+				f5GListPurged = true;
+			}
+			if (CSR_IS_OPERATING_A_BAND(pMac)) {
+				/* add to the list of 5GHz channel sets */
+				csr_ll_insert_tail(&pMac->scan.
+						   channelPowerInfoList5G,
+						   &pChannelSet->link,
+						   LL_ACCESS_LOCK);
+			} else {
+				sme_debug(
+					"Adding 11A ch in B/G. 1st ch %d",
+					pChannelSet->firstChannel);
+				qdf_mem_free(pChannelSet);
+			}
+		}
+		pChannelInfo++; /* move to next entry */
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+static void csr_clear_dfs_channel_list(tpAniSirGlobal pMac)
+{
+	tSirMbMsg *pMsg;
+	uint16_t msgLen;
+
+	msgLen = (uint16_t) (sizeof(tSirMbMsg));
+	pMsg = qdf_mem_malloc(msgLen);
+	if (NULL != pMsg) {
+		pMsg->type = eWNI_SME_CLEAR_DFS_CHANNEL_LIST;
+		pMsg->msgLen = msgLen;
+		umac_send_mb_message_to_mac(pMsg);
+	}
+}
+
+void csr_apply_power2_current(tpAniSirGlobal pMac)
+{
+	sme_debug("Updating Cfg with power settings");
+	csr_save_tx_power_to_cfg(pMac, &pMac->scan.channelPowerInfoList24,
+				 WNI_CFG_MAX_TX_POWER_2_4);
+	csr_save_tx_power_to_cfg(pMac, &pMac->scan.channelPowerInfoList5G,
+				 WNI_CFG_MAX_TX_POWER_5);
+}
+
+void csr_apply_channel_power_info_to_fw(tpAniSirGlobal mac_ctx,
+					  struct csr_channel *ch_lst,
+					  uint8_t *countryCode)
+{
+	int i;
+	uint8_t num_ch = 0;
+	uint8_t tempNumChannels = 0;
+	struct csr_channel tmp_ch_lst;
+
+	if (ch_lst->numChannels) {
+		tempNumChannels = CSR_MIN(ch_lst->numChannels,
+					  WNI_CFG_VALID_CHANNEL_LIST_LEN);
+		for (i = 0; i < tempNumChannels; i++) {
+			tmp_ch_lst.channelList[num_ch] = ch_lst->channelList[i];
+			num_ch++;
+		}
+		tmp_ch_lst.numChannels = num_ch;
+		/* Store the channel+power info in the global place: Cfg */
+		csr_apply_power2_current(mac_ctx);
+		csr_set_cfg_valid_channel_list(mac_ctx, tmp_ch_lst.channelList,
+					       tmp_ch_lst.numChannels);
+		/*
+		 * extend scan capability, build a scan list based on the
+		 * channel list : channel# + active/passive scan
+		 */
+		csr_set_cfg_scan_control_list(mac_ctx, countryCode,
+					      &tmp_ch_lst);
+		/* Send msg to Lim to clear DFS channel list */
+		csr_clear_dfs_channel_list(mac_ctx);
+	} else {
+		sme_err("11D channel list is empty");
+	}
+	csr_set_cfg_country_code(mac_ctx, countryCode);
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void csr_diag_reset_country_information(tpAniSirGlobal pMac)
+{
+
+	host_log_802_11d_pkt_type *p11dLog;
+	int Index;
+
+	WLAN_HOST_DIAG_LOG_ALLOC(p11dLog, host_log_802_11d_pkt_type,
+				 LOG_WLAN_80211D_C);
+	if (!p11dLog)
+		return;
+
+	p11dLog->eventId = WLAN_80211D_EVENT_RESET;
+	qdf_mem_copy(p11dLog->countryCode, pMac->scan.countryCodeCurrent, 3);
+	p11dLog->numChannel = pMac->scan.base_channels.numChannels;
+	if (p11dLog->numChannel <= HOST_LOG_MAX_NUM_CHANNEL) {
+		qdf_mem_copy(p11dLog->Channels,
+			     pMac->scan.base_channels.channelList,
+			     p11dLog->numChannel);
+		for (Index = 0;
+		     Index < pMac->scan.base_channels.numChannels;
+		     Index++) {
+			p11dLog->TxPwr[Index] = QDF_MIN(
+				pMac->scan.defaultPowerTable[Index].tx_power,
+				pMac->roam.configParam.nTxPowerCap);
+		}
+	}
+	if (!pMac->roam.configParam.Is11dSupportEnabled)
+		p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED;
+	else
+		p11dLog->supportMultipleDomain =
+			WLAN_80211D_SUPPORT_MULTI_DOMAIN;
+	WLAN_HOST_DIAG_LOG_REPORT(p11dLog);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+/**
+ * csr_apply_channel_power_info_wrapper() - sends channel info to fw
+ * @pMac: main MAC data structure
+ *
+ * This function sends the channel power info to firmware
+ *
+ * Return: none
+ */
+void csr_apply_channel_power_info_wrapper(tpAniSirGlobal pMac)
+{
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_diag_reset_country_information(pMac);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	csr_prune_channel_list_for_mode(pMac, &pMac->scan.base_channels);
+	csr_save_channel_power_for_band(pMac, false);
+	csr_save_channel_power_for_band(pMac, true);
+	/* apply the channel list, power settings, and the country code. */
+	csr_apply_channel_power_info_to_fw(pMac,
+		&pMac->scan.base_channels, pMac->scan.countryCodeCurrent);
+	/* clear the 11d channel list */
+	qdf_mem_set(&pMac->scan.channels11d, sizeof(pMac->scan.channels11d), 0);
+}
+
+void csr_clear_votes_for_country_info(tpAniSirGlobal pMac)
+{
+	pMac->scan.countryCodeCount = 0;
+	qdf_mem_set(pMac->scan.votes11d,
+		    sizeof(struct csr_votes11d) * CSR_MAX_NUM_COUNTRY_CODE, 0);
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+/* caller allocated memory for pNumChn and pChnPowerInfo */
+/* As input, *pNumChn has the size of the array of pChnPowerInfo */
+/* Upon return, *pNumChn has the number of channels assigned. */
+static void csr_get_channel_power_info(tpAniSirGlobal pMac, tDblLinkList *list,
+				       uint32_t *num_ch,
+				       struct channel_power *chn_pwr_info)
+{
+	tListElem *entry;
+	uint32_t chn_idx = 0, idx;
+	struct csr_channel_powerinfo *ch_set;
+
+	/* Get 2.4Ghz first */
+	entry = csr_ll_peek_head(list, LL_ACCESS_LOCK);
+	while (entry && (chn_idx < *num_ch)) {
+		ch_set = GET_BASE_ADDR(entry,
+				struct csr_channel_powerinfo, link);
+		for (idx = 0; (idx < ch_set->numChannels)
+				&& (chn_idx < *num_ch); idx++) {
+			chn_pwr_info[chn_idx].chan_num =
+				(uint8_t) (ch_set->firstChannel
+				 + (idx * ch_set->interChannelOffset));
+			chn_pwr_info[chn_idx++].tx_power = ch_set->txPower;
+		}
+		entry = csr_ll_next(list, entry, LL_ACCESS_LOCK);
+	}
+	*num_ch = chn_idx;
+}
+
+static void csr_diag_apply_country_info(tpAniSirGlobal mac_ctx)
+{
+	host_log_802_11d_pkt_type *p11dLog;
+	struct channel_power chnPwrInfo[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	uint32_t nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN, nTmp;
+
+	WLAN_HOST_DIAG_LOG_ALLOC(p11dLog, host_log_802_11d_pkt_type,
+				 LOG_WLAN_80211D_C);
+	if (!p11dLog)
+		return;
+
+	p11dLog->eventId = WLAN_80211D_EVENT_COUNTRY_SET;
+	qdf_mem_copy(p11dLog->countryCode, mac_ctx->scan.countryCode11d, 3);
+	p11dLog->numChannel = mac_ctx->scan.channels11d.numChannels;
+	if (p11dLog->numChannel > HOST_LOG_MAX_NUM_CHANNEL)
+		goto diag_end;
+
+	qdf_mem_copy(p11dLog->Channels,
+		     mac_ctx->scan.channels11d.channelList,
+		     p11dLog->numChannel);
+	csr_get_channel_power_info(mac_ctx,
+				&mac_ctx->scan.channelPowerInfoList24,
+				&nChnInfo, chnPwrInfo);
+	nTmp = nChnInfo;
+	nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN - nTmp;
+	csr_get_channel_power_info(mac_ctx,
+				&mac_ctx->scan.channelPowerInfoList5G,
+				&nChnInfo, &chnPwrInfo[nTmp]);
+	for (nTmp = 0; nTmp < p11dLog->numChannel; nTmp++) {
+		for (nChnInfo = 0;
+		     nChnInfo < WNI_CFG_VALID_CHANNEL_LIST_LEN;
+		     nChnInfo++) {
+			if (p11dLog->Channels[nTmp] ==
+			    chnPwrInfo[nChnInfo].chan_num) {
+				p11dLog->TxPwr[nTmp] =
+					chnPwrInfo[nChnInfo].tx_power;
+				break;
+			}
+		}
+	}
+diag_end:
+	if (!mac_ctx->roam.configParam.Is11dSupportEnabled)
+		p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED;
+	else
+		p11dLog->supportMultipleDomain =
+				WLAN_80211D_SUPPORT_MULTI_DOMAIN;
+	WLAN_HOST_DIAG_LOG_REPORT(p11dLog);
+}
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+/**
+ * csr_apply_country_information() - apply country code information
+ * @pMac: core MAC data structure
+ *
+ * This function programs the new country code
+ *
+ * Return: none
+ */
+void csr_apply_country_information(tpAniSirGlobal pMac)
+{
+	v_REGDOMAIN_t domainId;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!wlan_reg_11d_enabled_on_host(pMac->psoc))
+		return;
+	status = csr_get_regulatory_domain_for_country(pMac,
+			pMac->scan.countryCode11d, &domainId, SOURCE_QUERY);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return;
+	/* Check whether we need to enforce default domain */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_diag_apply_country_info(pMac);
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+	if (pMac->scan.domainIdCurrent != domainId)
+		return;
+	if (pMac->scan.domainIdCurrent != domainId) {
+		sme_debug("Domain Changed Old %d, new %d",
+			pMac->scan.domainIdCurrent, domainId);
+		if (domainId >= REGDOMAIN_COUNT)
+			sme_err("fail to set regId %d", domainId);
+	}
+	pMac->scan.domainIdCurrent = domainId;
+	/* switch to active scans using this new channel list */
+	pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
+}
+
+void csr_save_channel_power_for_band(tpAniSirGlobal pMac, bool fill_5f)
+{
+	uint32_t idx, count = 0;
+	tSirMacChanInfo *chan_info;
+	tSirMacChanInfo *ch_info_start;
+	int32_t max_ch_idx;
+	bool tmp_bool;
+	uint8_t ch = 0;
+
+	max_ch_idx =
+		(pMac->scan.base_channels.numChannels <
+		WNI_CFG_VALID_CHANNEL_LIST_LEN) ?
+		pMac->scan.base_channels.numChannels :
+		WNI_CFG_VALID_CHANNEL_LIST_LEN;
+
+	chan_info = qdf_mem_malloc(sizeof(tSirMacChanInfo) *
+				   WNI_CFG_VALID_CHANNEL_LIST_LEN);
+	if (NULL == chan_info)
+		return;
+
+	ch_info_start = chan_info;
+	for (idx = 0; idx < max_ch_idx; idx++) {
+		ch = pMac->scan.defaultPowerTable[idx].chan_num;
+		tmp_bool = (fill_5f && WLAN_REG_IS_5GHZ_CH(ch)) ||
+			(!fill_5f && WLAN_REG_IS_24GHZ_CH(ch));
+		if (!tmp_bool)
+			continue;
+
+		if (count >= WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+			sme_warn("count: %d exceeded", count);
+			break;
+		}
+
+		chan_info->firstChanNum =
+			pMac->scan.defaultPowerTable[idx].chan_num;
+		chan_info->numChannels = 1;
+		chan_info->maxTxPower =
+			QDF_MIN(pMac->scan.defaultPowerTable[idx].tx_power,
+				pMac->roam.configParam.nTxPowerCap);
+		chan_info++;
+		count++;
+	}
+	if (count) {
+		csr_save_to_channel_power2_g_5_g(pMac,
+				count * sizeof(tSirMacChanInfo), ch_info_start);
+	}
+	qdf_mem_free(ch_info_start);
+}
+
+bool csr_is_supported_channel(tpAniSirGlobal pMac, uint8_t channelId)
+{
+	bool fRet = false;
+	uint32_t i;
+
+	for (i = 0; i < pMac->scan.base_channels.numChannels; i++) {
+		if (channelId ==
+		    pMac->scan.base_channels.channelList[i]) {
+			fRet = true;
+			break;
+		}
+	}
+
+	return fRet;
+}
+
+/*
+ * 802.11D only: Gather 11d IE via beacon or Probe response and store them in
+ * pAdapter->channels11d
+ */
+bool csr_learn_11dcountry_information(tpAniSirGlobal pMac,
+				   tSirBssDescription *pSirBssDesc,
+				   tDot11fBeaconIEs *pIes, bool fForce)
+{
+	QDF_STATUS status;
+	uint8_t *pCountryCodeSelected;
+	bool fRet = false;
+	v_REGDOMAIN_t domainId;
+	tDot11fBeaconIEs *pIesLocal = pIes;
+	bool useVoting = false;
+
+	if ((NULL == pSirBssDesc) && (NULL == pIes))
+		useVoting = true;
+
+	/* check if .11d support is enabled */
+	if (!wlan_reg_11d_enabled_on_host(pMac->psoc))
+		goto free_ie;
+
+	if (false == useVoting) {
+		if (!pIesLocal &&
+		   (!QDF_IS_STATUS_SUCCESS(
+			csr_get_parsed_bss_description_ies(
+				pMac, pSirBssDesc, &pIesLocal))))
+			goto free_ie;
+		/* check if country information element is present */
+		if (!pIesLocal->Country.present)
+			/* No country info */
+			goto free_ie;
+		status = csr_get_regulatory_domain_for_country(pMac,
+				pIesLocal->Country.country, &domainId,
+				SOURCE_QUERY);
+		if (QDF_IS_STATUS_SUCCESS(status)
+		    && (domainId == REGDOMAIN_WORLD))
+			goto free_ie;
+	} /* useVoting == false */
+
+	if (false == useVoting)
+		pCountryCodeSelected = pIesLocal->Country.country;
+	else
+		pCountryCodeSelected = pMac->scan.countryCodeElected;
+
+	if (qdf_mem_cmp(pCountryCodeSelected, pMac->scan.countryCodeCurrent,
+			CDS_COUNTRY_CODE_LEN) == 0) {
+		qdf_mem_copy(pMac->scan.countryCode11d,
+			     pMac->scan.countryCodeCurrent,
+			     CDS_COUNTRY_CODE_LEN);
+		goto free_ie;
+	}
+
+	pMac->reg_hint_src = SOURCE_11D;
+	status = csr_get_regulatory_domain_for_country(pMac,
+				pCountryCodeSelected, &domainId, SOURCE_11D);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("fail to get regId %d", domainId);
+		fRet = false;
+		goto free_ie;
+	}
+
+	fRet = true;
+free_ie:
+	if (!pIes && pIesLocal) {
+		/* locally allocated */
+		qdf_mem_free(pIesLocal);
+	}
+	return fRet;
+}
+
+static enum csr_scancomplete_nextcommand csr_scan_get_next_command_state(
+						tpAniSirGlobal mac_ctx,
+						uint32_t session_id,
+						eCsrScanStatus scan_status,
+						uint8_t *chan)
+{
+	enum csr_scancomplete_nextcommand NextCommand = eCsrNextScanNothing;
+	int8_t channel;
+	struct csr_roam_session *session;
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("session %d is invalid", session_id);
+		return NextCommand;
+	}
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+	switch (session->scan_info.scan_reason) {
+	case eCsrScanForSsid:
+		sme_debug("Resp for Scan For Ssid");
+		channel = csr_scan_get_channel_for_hw_mode_change(
+				mac_ctx,
+				session_id,
+				session->scan_info.profile);
+		if ((!channel) || scan_status) {
+			NextCommand = eCsrNexteScanForSsidFailure;
+			sme_err("next Scan For Ssid Failure %d %d",
+				channel, scan_status);
+		} else {
+			NextCommand = eCsrNextCheckAllowConc;
+			*chan = channel;
+			sme_debug("next CheckAllowConc");
+		}
+		break;
+	default:
+		NextCommand = eCsrNextScanNothing;
+		break;
+	}
+	sme_debug("Next Command %d", NextCommand);
+	return NextCommand;
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void
+csr_diag_scan_complete(tpAniSirGlobal mac_ctx,
+		       eCsrScanStatus scan_status)
+{
+	host_log_scan_pkt_type *pScanLog = NULL;
+	qdf_list_t *list = NULL;
+	struct wlan_objmgr_pdev *pdev = NULL;
+	struct scan_cache_node *cur_node = NULL;
+	struct scan_cache_node *next_node = NULL;
+	int n = 0, c = 0;
+
+	WLAN_HOST_DIAG_LOG_ALLOC(pScanLog,
+				 host_log_scan_pkt_type,
+				 LOG_WLAN_SCAN_C);
+	if (!pScanLog)
+		return;
+
+	pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_RSP;
+
+	if (eCSR_SCAN_SUCCESS != scan_status) {
+		pScanLog->status = WLAN_SCAN_STATUS_FAILURE;
+		WLAN_HOST_DIAG_LOG_REPORT(pScanLog);
+		return;
+	}
+	pdev = wlan_objmgr_get_pdev_by_id(mac_ctx->psoc,
+		0, WLAN_LEGACY_MAC_ID);
+
+	if (!pdev) {
+		sme_err("pdev is NULL");
+		return;
+	}
+
+	list = ucfg_scan_get_result(pdev, NULL);
+	if (list)
+		sme_debug("num_entries %d", qdf_list_size(list));
+	if (!list || (list && !qdf_list_size(list))) {
+		sme_err("get scan result failed");
+		WLAN_HOST_DIAG_LOG_REPORT(pScanLog);
+		wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID);
+		if (list)
+			ucfg_scan_purge_results(list);
+		return;
+	}
+
+	qdf_list_peek_front(list,
+		   (qdf_list_node_t **) &cur_node);
+	while (cur_node) {
+		if (n < HOST_LOG_MAX_NUM_BSSID) {
+			qdf_mem_copy(pScanLog->bssid[n],
+				cur_node->entry->bssid.bytes,
+				QDF_MAC_ADDR_SIZE);
+			if (cur_node->entry->ssid.length >
+			   WLAN_SSID_MAX_LEN)
+				cur_node->entry->ssid.length =
+				  WLAN_SSID_MAX_LEN;
+			qdf_mem_copy(pScanLog->ssid[n],
+				cur_node->entry->ssid.ssid,
+				cur_node->entry->ssid.length);
+			n++;
+		}
+		c++;
+		qdf_list_peek_next(
+		  list,
+		  (qdf_list_node_t *) cur_node,
+		  (qdf_list_node_t **) &next_node);
+		cur_node = next_node;
+		next_node = NULL;
+	}
+	pScanLog->numSsid = (uint8_t) n;
+	pScanLog->totalSsid = (uint8_t) c;
+	ucfg_scan_purge_results(list);
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID);
+	WLAN_HOST_DIAG_LOG_REPORT(pScanLog);
+}
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+/**
+ * csr_saved_scan_cmd_free_fields() - Free internal fields of scan command
+ *
+ * @mac_ctx: Global MAC context
+ * @session: sme session
+ *
+ * Frees data structures allocated inside saved_scan_cmd and releases
+ * the profile.
+ * Return: None
+ */
+
+void csr_saved_scan_cmd_free_fields(tpAniSirGlobal mac_ctx,
+				    struct csr_roam_session *session)
+{
+	if (session->scan_info.profile) {
+		csr_release_profile(mac_ctx,
+				    session->scan_info.profile);
+		qdf_mem_free(session->scan_info.profile);
+		session->scan_info.profile = NULL;
+	}
+
+	if (session->scan_info.roambssentry) {
+		qdf_mem_free(session->scan_info.roambssentry);
+		session->scan_info.roambssentry = NULL;
+	}
+}
+/**
+ * csr_save_profile() - Save the profile info from sme command
+ * @mac_ctx: Global MAC context
+ * @save_cmd: Pointer where the command will be saved
+ * @command: Command from which the profile will be saved
+ *
+ * Saves the profile information from the SME's scan command
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS csr_save_profile(tpAniSirGlobal mac_ctx,
+				   uint32_t session_id)
+{
+	struct tag_csrscan_result *scan_result;
+	struct tag_csrscan_result *temp;
+	uint32_t bss_len;
+	struct csr_roam_session *session;
+
+	/*
+	 * check the session's validity first, if session itself
+	 * is not valid then there is no point of releasing the memory
+	 * for invalid session (i.e. "goto error" case)
+	 */
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("session %d is invalid", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (!session->scan_info.roambssentry)
+		return QDF_STATUS_SUCCESS;
+
+	scan_result = GET_BASE_ADDR(session->scan_info.roambssentry,
+			struct tag_csrscan_result, Link);
+
+	bss_len = scan_result->Result.BssDescriptor.length +
+		sizeof(scan_result->Result.BssDescriptor.length);
+
+	temp = qdf_mem_malloc(sizeof(struct tag_csrscan_result) + bss_len);
+	if (!temp)
+		goto error;
+
+	temp->AgingCount = scan_result->AgingCount;
+	temp->preferValue = scan_result->preferValue;
+	temp->capValue = scan_result->capValue;
+	temp->ucEncryptionType = scan_result->ucEncryptionType;
+	temp->mcEncryptionType = scan_result->mcEncryptionType;
+	temp->authType = scan_result->authType;
+	/* pvIes is unsued in success/failure */
+	temp->Result.pvIes = NULL;
+
+	qdf_mem_copy(temp->Result.pvIes,
+			scan_result->Result.pvIes,
+			sizeof(*scan_result->Result.pvIes));
+	temp->Result.ssId.length = scan_result->Result.ssId.length;
+	qdf_mem_copy(temp->Result.ssId.ssId,
+			scan_result->Result.ssId.ssId,
+			sizeof(scan_result->Result.ssId.ssId));
+	temp->Result.timer = scan_result->Result.timer;
+	qdf_mem_copy(&temp->Result.BssDescriptor,
+			&scan_result->Result.BssDescriptor,
+			sizeof(temp->Result.BssDescriptor));
+	temp->Link.last = temp->Link.next = NULL;
+	session->scan_info.roambssentry = (tListElem *)temp;
+
+	return QDF_STATUS_SUCCESS;
+error:
+	csr_scan_handle_search_for_ssid_failure(mac_ctx,
+			session_id);
+	csr_saved_scan_cmd_free_fields(mac_ctx, session);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+static void csr_handle_nxt_cmd(tpAniSirGlobal mac_ctx,
+		   enum csr_scancomplete_nextcommand nxt_cmd,
+		   uint32_t session_id,
+		   uint8_t chan)
+{
+	QDF_STATUS status, ret;
+
+	switch (nxt_cmd) {
+
+	case eCsrNexteScanForSsidSuccess:
+		csr_scan_handle_search_for_ssid(mac_ctx, session_id);
+		break;
+	case eCsrNexteScanForSsidFailure:
+		csr_scan_handle_search_for_ssid_failure(mac_ctx, session_id);
+		break;
+	case eCsrNextCheckAllowConc:
+		ret = policy_mgr_current_connections_update(mac_ctx->psoc,
+					session_id, chan,
+					POLICY_MGR_UPDATE_REASON_HIDDEN_STA);
+		sme_debug("chan: %d session: %d status: %d",
+					chan, session_id, ret);
+
+		status = csr_save_profile(mac_ctx, session_id);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			/* csr_save_profile should report error */
+			sme_err("profile save failed %d", status);
+			return;
+		}
+
+		if (QDF_STATUS_E_FAILURE == ret) {
+			sme_err("conn update fail %d", chan);
+			csr_scan_handle_search_for_ssid_failure(mac_ctx,
+								session_id);
+		} else if ((QDF_STATUS_E_NOSUPPORT == ret) ||
+			(QDF_STATUS_E_ALREADY == ret)) {
+			sme_err("conn update ret %d", ret);
+			csr_scan_handle_search_for_ssid(mac_ctx, session_id);
+		}
+		/* Else: Set hw mode was issued and the saved connect would
+		 * be issued after set hw mode response
+		 */
+		break;
+	default:
+		break;
+	}
+}
+
+void csr_scan_callback(struct wlan_objmgr_vdev *vdev,
+				struct scan_event *event, void *arg)
+{
+	eCsrScanStatus scan_status = eCSR_SCAN_FAILURE;
+	enum csr_scancomplete_nextcommand NextCommand = eCsrNextScanNothing;
+	tpAniSirGlobal mac_ctx;
+	struct csr_roam_session *session;
+	uint32_t session_id = 0;
+	uint8_t chan = 0;
+	bool success = false;
+
+	mac_ctx = (tpAniSirGlobal)arg;
+
+	qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SME, event->type,
+		   event->vdev_id, event->scan_id);
+
+	if (!util_is_scan_completed(event, &success))
+		return;
+
+	if (success)
+		scan_status = eCSR_SCAN_SUCCESS;
+
+	session_id = wlan_vdev_get_id(vdev);
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("session %d is invalid", session_id);
+		return;
+	}
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	sme_debug("Scan Completion: status %d session %d scan_id %d",
+			scan_status, session_id, event->scan_id);
+
+	/* verify whether scan event is related to scan interested by CSR */
+	if (session->scan_info.scan_id != event->scan_id) {
+		sme_debug("Scan Completion on wrong scan_id %d, expected %d",
+			session->scan_info.scan_id, event->scan_id);
+		return;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_diag_scan_complete(mac_ctx, scan_status);
+#endif
+	NextCommand = csr_scan_get_next_command_state(mac_ctx,
+					session_id, scan_status,
+					&chan);
+	/* We reuse the command here instead reissue a new command */
+	csr_handle_nxt_cmd(mac_ctx, NextCommand,
+			   session_id, chan);
+
+	if (session->scan_info.profile != NULL) {
+		sme_debug("Free the profile scan_id %d", event->scan_id);
+		csr_release_profile(mac_ctx, session->scan_info.profile);
+		qdf_mem_free(session->scan_info.profile);
+		session->scan_info.profile = NULL;
+	}
+
+}
+
+tCsrScanResultInfo *csr_scan_result_get_first(tpAniSirGlobal pMac,
+					      tScanResultHandle hScanResult)
+{
+	tListElem *pEntry;
+	struct tag_csrscan_result *pResult;
+	tCsrScanResultInfo *pRet = NULL;
+	struct scan_result_list *pResultList =
+				(struct scan_result_list *) hScanResult;
+
+	if (pResultList) {
+		csr_ll_lock(&pResultList->List);
+		pEntry = csr_ll_peek_head(&pResultList->List, LL_ACCESS_NOLOCK);
+		if (pEntry) {
+			pResult = GET_BASE_ADDR(pEntry, struct
+						tag_csrscan_result, Link);
+			pRet = &pResult->Result;
+		}
+		pResultList->pCurEntry = pEntry;
+		csr_ll_unlock(&pResultList->List);
+	}
+
+	return pRet;
+}
+
+tCsrScanResultInfo *csr_scan_result_get_next(tpAniSirGlobal pMac,
+					     tScanResultHandle hScanResult)
+{
+	tListElem *pEntry = NULL;
+	struct tag_csrscan_result *pResult = NULL;
+	tCsrScanResultInfo *pRet = NULL;
+	struct scan_result_list *pResultList =
+				(struct scan_result_list *) hScanResult;
+
+	if (!pResultList)
+		return NULL;
+
+	csr_ll_lock(&pResultList->List);
+	if (NULL == pResultList->pCurEntry)
+		pEntry = csr_ll_peek_head(&pResultList->List, LL_ACCESS_NOLOCK);
+	else
+		pEntry = csr_ll_next(&pResultList->List, pResultList->pCurEntry,
+				     LL_ACCESS_NOLOCK);
+
+	if (pEntry) {
+		pResult = GET_BASE_ADDR(pEntry, struct tag_csrscan_result,
+					Link);
+		pRet = &pResult->Result;
+	}
+	pResultList->pCurEntry = pEntry;
+	csr_ll_unlock(&pResultList->List);
+	return pRet;
+}
+
+/*
+ * This function moves the first BSS that matches the bssid to the
+ * head of the result
+ */
+QDF_STATUS csr_move_bss_to_head_from_bssid(tpAniSirGlobal pMac,
+					   struct qdf_mac_addr *bssid,
+					   tScanResultHandle hScanResult)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct scan_result_list *pResultList =
+				(struct scan_result_list *) hScanResult;
+	struct tag_csrscan_result *pResult = NULL;
+	tListElem *pEntry = NULL;
+
+	if (!(pResultList && bssid))
+		return status;
+
+	csr_ll_lock(&pResultList->List);
+	pEntry = csr_ll_peek_head(&pResultList->List, LL_ACCESS_NOLOCK);
+	while (pEntry) {
+		pResult = GET_BASE_ADDR(pEntry, struct tag_csrscan_result,
+					Link);
+		if (!qdf_mem_cmp(bssid, pResult->Result.BssDescriptor.bssId,
+				    sizeof(struct qdf_mac_addr))) {
+			status = QDF_STATUS_SUCCESS;
+			csr_ll_remove_entry(&pResultList->List, pEntry,
+					    LL_ACCESS_NOLOCK);
+			csr_ll_insert_head(&pResultList->List, pEntry,
+					   LL_ACCESS_NOLOCK);
+			break;
+		}
+		pEntry = csr_ll_next(&pResultList->List, pResultList->pCurEntry,
+				     LL_ACCESS_NOLOCK);
+	}
+	csr_ll_unlock(&pResultList->List);
+
+	return status;
+}
+
+/**
+ * csr_scan_for_ssid() -  Function usually used for BSSs that suppresses SSID
+ * @mac_ctx: Pointer to Global Mac structure
+ * @profile: pointer to struct csr_roam_profile
+ * @roam_id: variable representing roam id
+ * @notify: boolean variable
+ *
+ * Function is usually used for BSSs that suppresses SSID so the profile
+ * shall have one and only one SSID.
+ *
+ * Return: Success - QDF_STATUS_SUCCESS, Failure - error number
+ */
+QDF_STATUS csr_scan_for_ssid(tpAniSirGlobal mac_ctx, uint32_t session_id,
+			struct csr_roam_profile *profile, uint32_t roam_id,
+			bool notify)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint32_t num_ssid = profile->SSIDs.numOfSSIDs;
+	struct scan_start_request *req;
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t i, chan, num_chan = 0;
+	uint8_t pdev_id;
+	wlan_scan_id scan_id;
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("session %d is invalid", session_id);
+		return status;
+	}
+
+	if (!ucfg_scan_get_enable(mac_ctx->psoc) && (num_ssid != 1)) {
+		sme_err(
+			"cannot scan because scanEnable (%d) or numSSID (%d) is invalid",
+			ucfg_scan_get_enable(mac_ctx->psoc), profile->SSIDs.numOfSSIDs);
+		return status;
+	}
+
+	if (!mac_ctx->pdev) {
+		sme_err("pdev ctx is NULL");
+		return status;
+	}
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(mac_ctx->pdev);
+
+	session->scan_info.profile =
+			qdf_mem_malloc(sizeof(struct csr_roam_profile));
+	if (!session->scan_info.profile)
+		status = QDF_STATUS_E_NOMEM;
+	else
+		status = csr_roam_copy_profile(mac_ctx,
+					session->scan_info.profile,
+					profile);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		goto error;
+	scan_id = ucfg_scan_get_scan_id(mac_ctx->psoc);
+	session->scan_info.scan_id = scan_id;
+	session->scan_info.scan_reason = eCsrScanForSsid;
+	session->scan_info.roam_id = roam_id;
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		goto error;
+
+	vdev = wlan_objmgr_get_vdev_by_macaddr_from_psoc(mac_ctx->psoc,
+				pdev_id,
+				session->selfMacAddr.bytes,
+				WLAN_LEGACY_SME_ID);
+	ucfg_scan_init_default_params(vdev, req);
+	req->scan_req.dwell_time_active = 0;
+	req->scan_req.scan_id = scan_id;
+	req->scan_req.vdev_id = session_id;
+	req->scan_req.scan_req_id = mac_ctx->scan.requester_id;
+	req->scan_req.scan_f_passive = false;
+	req->scan_req.scan_f_bcast_probe = false;
+
+
+	if (QDF_P2P_CLIENT_MODE == profile->csrPersona)
+		req->scan_req.scan_priority = SCAN_PRIORITY_HIGH;
+
+	/* Allocate memory for IE field */
+	if (profile->pAddIEScan) {
+		req->scan_req.extraie.ptr =
+			qdf_mem_malloc(profile->nAddIEScanLength);
+
+		if (NULL == req->scan_req.extraie.ptr)
+			status = QDF_STATUS_E_NOMEM;
+		else
+			status = QDF_STATUS_SUCCESS;
+
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			qdf_mem_copy(req->scan_req.extraie.ptr,
+					profile->pAddIEScan,
+					profile->nAddIEScanLength);
+			req->scan_req.extraie.len = profile->nAddIEScanLength;
+		} else {
+			sme_err("No memory for scanning IE fields");
+		}
+	}
+
+	req->scan_req.num_bssid = 1;
+	if (profile->BSSIDs.numOfBSSIDs == 1)
+		qdf_copy_macaddr(&req->scan_req.bssid_list[0],
+					profile->BSSIDs.bssid);
+	else
+		qdf_set_macaddr_broadcast(&req->scan_req.bssid_list[0]);
+
+	if (profile->ChannelInfo.numOfChannels) {
+		for (i = 0; i < profile->ChannelInfo.numOfChannels; i++) {
+			if (csr_roam_is_valid_channel(mac_ctx,
+				profile->ChannelInfo.ChannelList[i])) {
+				chan = profile->ChannelInfo.ChannelList[i];
+				req->scan_req.chan_list.chan[num_chan].freq =
+						wlan_chan_to_freq(chan);
+				num_chan++;
+			}
+		}
+		req->scan_req.chan_list.num_chan = num_chan;
+	}
+
+	/* Extend it for multiple SSID */
+	if (profile->SSIDs.numOfSSIDs) {
+		if (profile->SSIDs.SSIDList[0].SSID.length > MAX_SSID_LEN) {
+			sme_debug("wrong ssid length = %d",
+					profile->SSIDs.SSIDList[0].SSID.length);
+			status = QDF_STATUS_E_INVAL;
+			goto error;
+		}
+		req->scan_req.num_ssids = 1;
+		qdf_mem_copy(&req->scan_req.ssid[0].ssid,
+				&profile->SSIDs.SSIDList[0].SSID.ssId,
+				profile->SSIDs.SSIDList[0].SSID.length);
+		req->scan_req.ssid[0].length =
+				profile->SSIDs.SSIDList[0].SSID.length;
+		sme_debug("scan for SSID = %.*s", req->scan_req.ssid[0].length,
+			  req->scan_req.ssid[0].ssid);
+	}
+	status = ucfg_scan_start(req);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+error:
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("failed to initiate scan with status: %d", status);
+		csr_release_profile(mac_ctx, session->scan_info.profile);
+		qdf_mem_free(session->scan_info.profile);
+		session->scan_info.profile = NULL;
+		if (notify)
+			csr_roam_call_callback(mac_ctx, session_id, NULL,
+					roam_id, eCSR_ROAM_FAILED,
+					eCSR_ROAM_RESULT_FAILURE);
+	}
+	return status;
+}
+
+static void csr_set_cfg_valid_channel_list(tpAniSirGlobal pMac,
+				uint8_t *pChannelList, uint8_t NumChannels)
+{
+	uint32_t dataLen = sizeof(uint8_t) * NumChannels;
+	QDF_STATUS status;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: dump valid channel list(NumChannels(%d))",
+		  __func__, NumChannels);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			   pChannelList, NumChannels);
+	cfg_set_str(pMac, WNI_CFG_VALID_CHANNEL_LIST, pChannelList,
+			dataLen);
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "Scan offload is enabled, update default chan list");
+	/*
+	 * disable fcc constraint since new country code
+	 * is being set
+	 */
+	pMac->scan.fcc_constraint = false;
+	status = csr_update_channel_list(pMac);
+	if (QDF_STATUS_SUCCESS != status) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "failed to update the supported channel list");
+	}
+}
+
+/*
+ * The Tx power limits are saved in the cfg for future usage.
+ */
+static void csr_save_tx_power_to_cfg(tpAniSirGlobal pMac, tDblLinkList *pList,
+			      uint32_t cfgId)
+{
+	tListElem *pEntry;
+	uint32_t cbLen = 0, dataLen, tmp_len;
+	struct csr_channel_powerinfo *ch_set;
+	uint32_t idx;
+	tSirMacChanInfo *ch_pwr_set;
+	uint8_t *pBuf = NULL;
+
+	/* allocate maximum space for all channels */
+	dataLen = WNI_CFG_VALID_CHANNEL_LIST_LEN * sizeof(tSirMacChanInfo);
+	pBuf = qdf_mem_malloc(dataLen);
+	if (pBuf == NULL)
+		return;
+
+	ch_pwr_set = (tSirMacChanInfo *) (pBuf);
+	pEntry = csr_ll_peek_head(pList, LL_ACCESS_LOCK);
+	/*
+	 * write the tuples (startChan, numChan, txPower) for each channel found
+	 * in the channel power list.
+	 */
+	while (pEntry) {
+		ch_set = GET_BASE_ADDR(pEntry,
+				struct csr_channel_powerinfo, link);
+		if (1 != ch_set->interChannelOffset) {
+			/*
+			 * we keep the 5G channel sets internally with an
+			 * interchannel offset of 4. Expand these to the right
+			 * format. (inter channel offset of 1 is the only option
+			 * for the triplets that 11d advertises.
+			 */
+			tmp_len = cbLen + (ch_set->numChannels *
+						sizeof(tSirMacChanInfo));
+			if (tmp_len >= dataLen) {
+				/*
+				 * expanding this entry will overflow our
+				 * allocation
+				 */
+				sme_err(
+					"Buffer overflow, start %d, num %d, offset %d",
+					ch_set->firstChannel,
+					ch_set->numChannels,
+					ch_set->interChannelOffset);
+				break;
+			}
+
+			for (idx = 0; idx < ch_set->numChannels; idx++) {
+				ch_pwr_set->firstChanNum = (tSirMacChanNum)
+					(ch_set->firstChannel + (idx *
+						ch_set->interChannelOffset));
+				sme_debug(
+					"Setting Channel Number %d",
+					ch_pwr_set->firstChanNum);
+				ch_pwr_set->numChannels = 1;
+				ch_pwr_set->maxTxPower =
+					QDF_MIN(ch_set->txPower,
+					pMac->roam.configParam.nTxPowerCap);
+				sme_debug(
+					"Setting Max Transmit Power %d",
+					ch_pwr_set->maxTxPower);
+				cbLen += sizeof(tSirMacChanInfo);
+				ch_pwr_set++;
+			}
+		} else {
+			if (cbLen >= dataLen) {
+				/* this entry will overflow our allocation */
+				sme_err(
+					"Buffer overflow, start %d, num %d, offset %d",
+					ch_set->firstChannel,
+					ch_set->numChannels,
+					ch_set->interChannelOffset);
+				break;
+			}
+			ch_pwr_set->firstChanNum = ch_set->firstChannel;
+			sme_debug("Setting Channel Number %d",
+				ch_pwr_set->firstChanNum);
+			ch_pwr_set->numChannels = ch_set->numChannels;
+			ch_pwr_set->maxTxPower = QDF_MIN(ch_set->txPower,
+					pMac->roam.configParam.nTxPowerCap);
+			sme_debug(
+				"Setting Max Tx Power %d, nTxPower %d",
+				ch_pwr_set->maxTxPower,
+				pMac->roam.configParam.nTxPowerCap);
+			cbLen += sizeof(tSirMacChanInfo);
+			ch_pwr_set++;
+		}
+		pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_LOCK);
+	}
+	if (cbLen)
+		cfg_set_str(pMac, cfgId, (uint8_t *) pBuf, cbLen);
+
+	qdf_mem_free(pBuf);
+}
+
+static void csr_set_cfg_country_code(tpAniSirGlobal pMac, uint8_t *countryCode)
+{
+	uint8_t cc[WNI_CFG_COUNTRY_CODE_LEN];
+	/* v_REGDOMAIN_t DomainId */
+
+	sme_debug("Setting Country Code in Cfg %s", countryCode);
+	qdf_mem_copy(cc, countryCode, WNI_CFG_COUNTRY_CODE_LEN);
+
+	/*
+	 * Don't program the bogus country codes that we created for Korea in
+	 * the MAC. if we see the bogus country codes, program the MAC with
+	 * the right country code.
+	 */
+	if (('K' == countryCode[0] && '1' == countryCode[1]) ||
+	    ('K' == countryCode[0] && '2' == countryCode[1]) ||
+	    ('K' == countryCode[0] && '3' == countryCode[1]) ||
+	    ('K' == countryCode[0] && '4' == countryCode[1])) {
+		/*
+		 * replace the alternate Korea country codes, 'K1', 'K2', ..
+		 * with 'KR' for Korea
+		 */
+		cc[1] = 'R';
+	}
+	cfg_set_str(pMac, WNI_CFG_COUNTRY_CODE, cc, WNI_CFG_COUNTRY_CODE_LEN);
+
+	/*
+	 * Need to let HALPHY know about the current domain so it can apply some
+	 * domain-specific settings (TX filter...)
+	 */
+}
+
+QDF_STATUS csr_get_country_code(tpAniSirGlobal pMac, uint8_t *pBuf,
+				uint8_t *pbLen)
+{
+	QDF_STATUS 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 (status == QDF_STATUS_SUCCESS) {
+			*pbLen = (uint8_t) len;
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	return QDF_STATUS_E_INVAL;
+}
+
+void csr_set_cfg_scan_control_list(tpAniSirGlobal pMac, uint8_t *countryCode,
+				   struct csr_channel *pChannelList)
+{
+	uint8_t i, j;
+	bool found = false;
+	uint8_t *pControlList = NULL;
+	uint32_t len = WNI_CFG_SCAN_CONTROL_LIST_LEN;
+
+	pControlList = qdf_mem_malloc(WNI_CFG_SCAN_CONTROL_LIST_LEN);
+	if (pControlList != NULL) {
+		if (QDF_IS_STATUS_SUCCESS(wlan_cfg_get_str(pMac,
+					WNI_CFG_SCAN_CONTROL_LIST,
+					pControlList, &len))) {
+			for (i = 0; i < pChannelList->numChannels; i++) {
+				for (j = 0; j < len; j += 2) {
+					if (pControlList[j] ==
+					    pChannelList->channelList[i]) {
+						found = true;
+						break;
+					}
+				}
+
+				if (found) {
+					/* insert a pair(channel#, flag) */
+					pControlList[j + 1] =
+						csr_get_scan_type(pMac,
+							pControlList[j]);
+					found = false;  /* reset the flag */
+				}
+
+			}
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: dump scan control list", __func__);
+			QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_SME,
+					   QDF_TRACE_LEVEL_DEBUG, pControlList,
+					   len);
+
+			cfg_set_str(pMac, WNI_CFG_SCAN_CONTROL_LIST,
+					pControlList, len);
+		} /* Successfully getting scan control list */
+		qdf_mem_free(pControlList);
+	} /* AllocateMemory */
+}
+
+QDF_STATUS csr_scan_abort_mac_scan(tpAniSirGlobal mac_ctx, uint32_t vdev_id,
+				   uint32_t scan_id)
+{
+	struct scan_cancel_request *req;
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return QDF_STATUS_E_NOMEM;
+
+	/* Get NL global context from objmgr*/
+	if (vdev_id == INVAL_VDEV_ID)
+		vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev,
+				0, WLAN_LEGACY_SME_ID);
+	else
+		vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev,
+				vdev_id, WLAN_LEGACY_SME_ID);
+
+	if (!vdev) {
+		sme_err("Failed get vdev");
+		qdf_mem_free(req);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	req->vdev = vdev;
+	req->cancel_req.scan_id = scan_id;
+	req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(mac_ctx->pdev);
+	req->cancel_req.vdev_id = vdev_id;
+	if (scan_id != INVAL_SCAN_ID)
+		req->cancel_req.req_type = WLAN_SCAN_CANCEL_SINGLE;
+	if (vdev_id == INVAL_VDEV_ID)
+		req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL;
+	else
+		req->cancel_req.req_type = WLAN_SCAN_CANCEL_VDEV_ALL;
+
+	status = ucfg_scan_cancel(req);
+	if (QDF_IS_STATUS_ERROR(status))
+		sme_err("Cancel scan request failed");
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+
+	return status;
+}
+QDF_STATUS csr_remove_nonscan_cmd_from_pending_list(tpAniSirGlobal pMac,
+						uint8_t sessionId,
+						eSmeCommandType commandType)
+{
+	tDblLinkList localList;
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+	tListElem *pEntryToRemove;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	qdf_mem_zero(&localList, sizeof(tDblLinkList));
+	if (!QDF_IS_STATUS_SUCCESS(csr_ll_open(&localList))) {
+		sme_err("failed to open list");
+		return status;
+	}
+
+	csr_nonscan_pending_ll_lock(pMac);
+	pEntry = csr_nonscan_pending_ll_peek_head(pMac, LL_ACCESS_NOLOCK);
+
+	/*
+	 * Have to make sure we don't loop back to the head of the list,
+	 * which will happen if the entry is NOT on the list
+	 */
+	while (pEntry) {
+		pEntryToRemove = pEntry;
+		pEntry = csr_nonscan_pending_ll_next(pMac,
+					pEntry, LL_ACCESS_NOLOCK);
+		pCommand = GET_BASE_ADDR(pEntryToRemove, tSmeCmd, Link);
+
+		if ((pCommand->command == commandType) &&
+		    (pCommand->sessionId == sessionId)) {
+			/* Insert to localList and remove later */
+			csr_ll_insert_tail(&localList, pEntryToRemove,
+					   LL_ACCESS_NOLOCK);
+			status = QDF_STATUS_SUCCESS;
+		}
+	}
+	csr_nonscan_pending_ll_unlock(pMac);
+
+	while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		sme_debug("Sending abort for command ID %d",
+			sessionId);
+		csr_release_command(pMac, pCommand);
+	}
+
+	csr_ll_close(&localList);
+	return status;
+}
+bool csr_roam_is_valid_channel(tpAniSirGlobal pMac, uint8_t channel)
+{
+	bool fValid = false;
+	uint32_t idx_valid_ch;
+	uint32_t len = pMac->roam.numValidChannels;
+
+	for (idx_valid_ch = 0; (idx_valid_ch < len); idx_valid_ch++) {
+		if (channel == pMac->roam.validChannelList[idx_valid_ch]) {
+			fValid = true;
+			break;
+		}
+	}
+	return fValid;
+}
+
+QDF_STATUS csr_scan_create_entry_in_scan_cache(tpAniSirGlobal pMac,
+					       uint32_t sessionId,
+					       struct qdf_mac_addr bssid,
+					       uint8_t channel)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tSirBssDescription *pNewBssDescriptor = NULL;
+	uint32_t size = 0;
+
+	if (NULL == pSession) {
+		return QDF_STATUS_E_FAILURE;
+	}
+	sme_debug("Current bssid::"MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(pSession->pConnectBssDesc->bssId));
+	sme_debug("My bssid::"MAC_ADDRESS_STR" channel %d",
+		MAC_ADDR_ARRAY(bssid.bytes), channel);
+
+	size = pSession->pConnectBssDesc->length +
+		sizeof(pSession->pConnectBssDesc->length);
+	if (!size) {
+		sme_err("length of bss descriptor is 0");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pNewBssDescriptor = qdf_mem_malloc(size);
+	if (pNewBssDescriptor)
+		return QDF_STATUS_E_FAILURE;
+
+	qdf_mem_copy(pNewBssDescriptor, pSession->pConnectBssDesc, size);
+	/* change the BSSID & channel as passed */
+	qdf_mem_copy(pNewBssDescriptor->bssId, bssid.bytes,
+			sizeof(tSirMacAddr));
+	pNewBssDescriptor->channelId = channel;
+	if (!csr_scan_append_bss_description(pMac, pNewBssDescriptor)) {
+		sme_err("csr_scan_append_bss_description failed");
+		status = QDF_STATUS_E_FAILURE;
+		goto free_mem;
+	}
+	sme_err("entry successfully added in scan cache");
+
+free_mem:
+	if (pNewBssDescriptor)
+		qdf_mem_free(pNewBssDescriptor);
+
+	return status;
+}
+
+#ifdef FEATURE_WLAN_ESE
+/*  Update the TSF with the difference in system time */
+void update_cckmtsf(uint32_t *timeStamp0, uint32_t *timeStamp1,
+		    uint64_t *incr)
+{
+	uint64_t timeStamp64 = ((uint64_t) *timeStamp1 << 32) | (*timeStamp0);
+
+	timeStamp64 = (uint64_t)(timeStamp64 + (*incr));
+	*timeStamp0 = (uint32_t) (timeStamp64 & 0xffffffff);
+	*timeStamp1 = (uint32_t) ((timeStamp64 >> 32) & 0xffffffff);
+}
+#endif
+
+/**
+ * csr_scan_save_roam_offload_ap_to_scan_cache
+ * This function parses the received beacon/probe response
+ * from the firmware as part of the roam synch indication.
+ * The beacon or the probe response is parsed and is also
+ * saved into the scan cache
+ *
+ * @param  pMac Pointer to Global Mac
+ * @param  roam_sync_ind_ptr Roam Synch Indication from
+ *         firmware which also contains the beacon/probe
+ *         response
+ * @return Status
+ */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS csr_scan_save_roam_offload_ap_to_scan_cache(tpAniSirGlobal pMac,
+		roam_offload_synch_ind *roam_sync_ind_ptr,
+		tpSirBssDescription  bss_desc_ptr)
+{
+	uint32_t length = 0;
+	struct tag_csrscan_result *scan_res_ptr = NULL;
+
+	length = roam_sync_ind_ptr->beaconProbeRespLength -
+		(SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
+	scan_res_ptr = qdf_mem_malloc(sizeof(struct tag_csrscan_result) +
+				length);
+	if (!scan_res_ptr)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(&scan_res_ptr->Result.BssDescriptor,
+			bss_desc_ptr,
+			(sizeof(tSirBssDescription) + length));
+
+	sme_debug("LFR3:Add BSSID to scan cache" MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(scan_res_ptr->Result.BssDescriptor.bssId));
+	csr_scan_add_result(pMac, scan_res_ptr);
+	csr_free_scan_result_entry(pMac, scan_res_ptr);
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+/**
+ * csr_get_fst_bssdescr_ptr() - This function returns the pointer to first bss
+ * description from scan handle
+ * @result_handle: an object for the result.
+ *
+ * Return: first bss descriptor from the scan handle.
+ */
+tpSirBssDescription csr_get_fst_bssdescr_ptr(tScanResultHandle result_handle)
+{
+	tListElem *first_element = NULL;
+	struct tag_csrscan_result *scan_result = NULL;
+	struct scan_result_list *bss_list =
+				(struct scan_result_list *)result_handle;
+
+	if (NULL == bss_list) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("Empty bss_list"));
+		return NULL;
+	}
+	if (csr_ll_is_list_empty(&bss_list->List, LL_ACCESS_NOLOCK)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("bss_list->List is empty"));
+		return NULL;
+	}
+	first_element = csr_ll_peek_head(&bss_list->List, LL_ACCESS_NOLOCK);
+	if (NULL == first_element) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("peer head return NULL"));
+		return NULL;
+	}
+
+	scan_result = GET_BASE_ADDR(first_element, struct tag_csrscan_result,
+					Link);
+
+	return &scan_result->Result.BssDescriptor;
+}
+
+/**
+ * csr_get_bssdescr_from_scan_handle() - This function to extract
+ *                                       first bss description from scan handle
+ * @result_handle: an object for the result.
+ *
+ * This function is written to extract first bss from scan handle.
+ *
+ * Return: first bss descriptor from the scan handle.
+ */
+tSirBssDescription*
+csr_get_bssdescr_from_scan_handle(tScanResultHandle result_handle,
+				tSirBssDescription *bss_descr)
+{
+	tListElem *first_element = NULL;
+	struct tag_csrscan_result *scan_result = NULL;
+	struct scan_result_list *bss_list =
+				(struct scan_result_list *)result_handle;
+
+	if (NULL == bss_list) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("Empty bss_list"));
+		return NULL;
+	}
+	if (csr_ll_is_list_empty(&bss_list->List, LL_ACCESS_NOLOCK)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("bss_list->List is empty"));
+		qdf_mem_free(bss_list);
+		return NULL;
+	}
+	first_element = csr_ll_peek_head(&bss_list->List, LL_ACCESS_NOLOCK);
+	if (first_element) {
+		scan_result = GET_BASE_ADDR(first_element,
+				struct tag_csrscan_result,
+				Link);
+		qdf_mem_copy(bss_descr,
+				&scan_result->Result.BssDescriptor,
+				sizeof(tSirBssDescription));
+	}
+	return bss_descr;
+}
+
+uint8_t
+csr_get_channel_for_hw_mode_change(tpAniSirGlobal mac_ctx,
+				   tScanResultHandle result_handle,
+				   uint32_t session_id)
+{
+	tListElem *next_element = NULL;
+	struct tag_csrscan_result *scan_result = NULL;
+	struct scan_result_list *bss_list =
+				(struct scan_result_list *)result_handle;
+	uint8_t channel_id = 0;
+
+	if (NULL == bss_list) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Empty bss_list"));
+		goto end;
+	}
+
+	if (policy_mgr_is_hw_dbs_capable(mac_ctx->psoc) == false) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("driver isn't dbs capable"));
+		goto end;
+	}
+
+	if (policy_mgr_is_current_hwmode_dbs(mac_ctx->psoc)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("driver is already in DBS"));
+		goto end;
+	}
+
+	if (!policy_mgr_is_dbs_allowed_for_concurrency(mac_ctx->psoc,
+						       QDF_STA_MODE)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("DBS is not allowed for this concurrency combo"));
+		goto end;
+	}
+
+	if (!policy_mgr_is_hw_dbs_2x2_capable(mac_ctx->psoc) &&
+	    !policy_mgr_get_connection_count(mac_ctx->psoc)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("1x1 DBS HW with no prior connection"));
+		goto end;
+	}
+
+	if (csr_ll_is_list_empty(&bss_list->List, LL_ACCESS_NOLOCK)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("bss_list->List is empty"));
+		qdf_mem_free(bss_list);
+		goto end;
+	}
+
+	next_element = csr_ll_peek_head(&bss_list->List, LL_ACCESS_NOLOCK);
+	while (next_element) {
+		scan_result = GET_BASE_ADDR(next_element,
+					    struct tag_csrscan_result,
+					    Link);
+		if (policy_mgr_is_hw_dbs_2x2_capable(mac_ctx->psoc)) {
+			if (WLAN_REG_IS_24GHZ_CH
+				(scan_result->Result.BssDescriptor.channelId)) {
+				channel_id =
+					scan_result->
+					Result.BssDescriptor.channelId;
+				break;
+			}
+		} else {
+			if (WLAN_REG_IS_24GHZ_CH
+				(scan_result->Result.BssDescriptor.channelId) &&
+			    policy_mgr_is_any_mode_active_on_band_along_with_session
+				(mac_ctx->psoc,
+				 session_id, POLICY_MGR_BAND_5)) {
+				channel_id =
+					scan_result->
+					Result.BssDescriptor.channelId;
+				break;
+			}
+			if (WLAN_REG_IS_5GHZ_CH
+				(scan_result->Result.BssDescriptor.channelId) &&
+			    policy_mgr_is_any_mode_active_on_band_along_with_session
+				(mac_ctx->psoc,
+				 session_id, POLICY_MGR_BAND_24)) {
+				channel_id =
+					scan_result->
+					Result.BssDescriptor.channelId;
+				break;
+			}
+		}
+		next_element = csr_ll_next(&bss_list->List, next_element,
+					   LL_ACCESS_NOLOCK);
+	}
+end:
+	return channel_id;
+}
+
+uint8_t
+csr_scan_get_channel_for_hw_mode_change(
+	tpAniSirGlobal mac_ctx, uint32_t session_id,
+	struct csr_roam_profile *profile)
+{
+	tScanResultHandle result_handle = NULL;
+	QDF_STATUS status;
+	uint8_t first_ap_ch = 0;
+	uint8_t candidate_chan;
+
+	status = sme_get_ap_channel_from_scan_cache(profile, &result_handle,
+						    &first_ap_ch);
+	if (status != QDF_STATUS_SUCCESS || !result_handle || !first_ap_ch) {
+		if (result_handle)
+			sme_scan_result_purge(result_handle);
+		sme_err("fail get scan result: status %d first ap ch %d",
+			status, first_ap_ch);
+		return 0;
+	}
+	if (!policy_mgr_check_for_session_conc(mac_ctx->psoc, session_id,
+					       first_ap_ch)) {
+		sme_scan_result_purge(result_handle);
+		sme_err("Conc not allowed for the session %d ch %d",
+			session_id, first_ap_ch);
+		return 0;
+	}
+
+	candidate_chan = csr_get_channel_for_hw_mode_change(mac_ctx,
+							    result_handle,
+							    session_id);
+	sme_scan_result_purge(result_handle);
+	if (!candidate_chan)
+		candidate_chan = first_ap_ch;
+	sme_debug("session %d hw mode check candidate_chan %d", session_id,
+		  candidate_chan);
+
+	return candidate_chan;
+}
+
+static enum wlan_auth_type csr_covert_auth_type_new(eCsrAuthType auth)
+{
+	switch (auth) {
+	case eCSR_AUTH_TYPE_NONE:
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		return WLAN_AUTH_TYPE_OPEN_SYSTEM;
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		return WLAN_AUTH_TYPE_SHARED_KEY;
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+		return WLAN_AUTH_TYPE_AUTOSWITCH;
+	case eCSR_AUTH_TYPE_WPA:
+		return WLAN_AUTH_TYPE_WPA;
+	case eCSR_AUTH_TYPE_WPA_PSK:
+		return WLAN_AUTH_TYPE_WPA_PSK;
+	case eCSR_AUTH_TYPE_WPA_NONE:
+		return WLAN_AUTH_TYPE_WPA_NONE;
+	case eCSR_AUTH_TYPE_RSN:
+		return WLAN_AUTH_TYPE_RSN;
+	case eCSR_AUTH_TYPE_RSN_PSK:
+		return WLAN_AUTH_TYPE_RSN_PSK;
+	case eCSR_AUTH_TYPE_FT_RSN:
+		return WLAN_AUTH_TYPE_FT_RSN;
+	case eCSR_AUTH_TYPE_FT_RSN_PSK:
+		return WLAN_AUTH_TYPE_FT_RSN_PSK;
+	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
+		return WLAN_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
+	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
+		return WLAN_AUTH_TYPE_WAPI_WAI_PSK;
+	case eCSR_AUTH_TYPE_CCKM_WPA:
+		return WLAN_AUTH_TYPE_CCKM_WPA;
+	case eCSR_AUTH_TYPE_CCKM_RSN:
+		return WLAN_AUTH_TYPE_CCKM_RSN;
+	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+		return WLAN_AUTH_TYPE_RSN_PSK_SHA256;
+	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
+		return WLAN_AUTH_TYPE_RSN_8021X_SHA256;
+	case eCSR_AUTH_TYPE_FILS_SHA256:
+		return WLAN_AUTH_TYPE_FILS_SHA256;
+	case eCSR_AUTH_TYPE_FILS_SHA384:
+		return WLAN_AUTH_TYPE_FILS_SHA384;
+	case eCSR_AUTH_TYPE_FT_FILS_SHA256:
+		return WLAN_AUTH_TYPE_FT_FILS_SHA256;
+	case eCSR_AUTH_TYPE_FT_FILS_SHA384:
+		return WLAN_AUTH_TYPE_FT_FILS_SHA384;
+	case eCSR_AUTH_TYPE_DPP_RSN:
+		return WLAN_AUTH_TYPE_DPP_RSN;
+	case eCSR_AUTH_TYPE_OWE:
+		return WLAN_AUTH_TYPE_OWE;
+	case eCSR_AUTH_TYPE_SUITEB_EAP_SHA256:
+		return WLAN_AUTH_TYPE_SUITEB_EAP_SHA256;
+	case eCSR_AUTH_TYPE_SUITEB_EAP_SHA384:
+		return WLAN_AUTH_TYPE_SUITEB_EAP_SHA384;
+	case eCSR_AUTH_TYPE_SAE:
+		return WLAN_AUTH_TYPE_SAE;
+	case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
+	default:
+		return WLAN_AUTH_TYPE_OPEN_SYSTEM;
+	}
+}
+
+static eCsrAuthType csr_covert_auth_type_old(enum wlan_auth_type auth)
+{
+	switch (auth) {
+	case WLAN_AUTH_TYPE_OPEN_SYSTEM:
+		return eCSR_AUTH_TYPE_OPEN_SYSTEM;
+	case WLAN_AUTH_TYPE_SHARED_KEY:
+		return eCSR_AUTH_TYPE_SHARED_KEY;
+	case WLAN_AUTH_TYPE_AUTOSWITCH:
+		return eCSR_AUTH_TYPE_AUTOSWITCH;
+	case WLAN_AUTH_TYPE_WPA:
+		return eCSR_AUTH_TYPE_WPA;
+	case WLAN_AUTH_TYPE_WPA_PSK:
+		return eCSR_AUTH_TYPE_WPA_PSK;
+	case WLAN_AUTH_TYPE_WPA_NONE:
+		return eCSR_AUTH_TYPE_WPA_NONE;
+	case WLAN_AUTH_TYPE_RSN:
+		return eCSR_AUTH_TYPE_RSN;
+	case WLAN_AUTH_TYPE_RSN_PSK:
+		return eCSR_AUTH_TYPE_RSN_PSK;
+	case WLAN_AUTH_TYPE_FT_RSN:
+		return eCSR_AUTH_TYPE_FT_RSN;
+	case WLAN_AUTH_TYPE_FT_RSN_PSK:
+		return eCSR_AUTH_TYPE_FT_RSN_PSK;
+	case WLAN_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
+		return eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
+	case WLAN_AUTH_TYPE_WAPI_WAI_PSK:
+		return eCSR_AUTH_TYPE_WAPI_WAI_PSK;
+	case WLAN_AUTH_TYPE_CCKM_WPA:
+		return eCSR_AUTH_TYPE_CCKM_WPA;
+	case WLAN_AUTH_TYPE_CCKM_RSN:
+		return eCSR_AUTH_TYPE_CCKM_RSN;
+	case WLAN_AUTH_TYPE_RSN_PSK_SHA256:
+		return eCSR_AUTH_TYPE_RSN_PSK_SHA256;
+	case WLAN_AUTH_TYPE_RSN_8021X_SHA256:
+		return eCSR_AUTH_TYPE_RSN_8021X_SHA256;
+	case WLAN_AUTH_TYPE_FILS_SHA256:
+		return eCSR_AUTH_TYPE_FILS_SHA256;
+	case WLAN_AUTH_TYPE_FILS_SHA384:
+		return eCSR_AUTH_TYPE_FILS_SHA384;
+	case WLAN_AUTH_TYPE_FT_FILS_SHA256:
+		return eCSR_AUTH_TYPE_FT_FILS_SHA256;
+	case WLAN_AUTH_TYPE_FT_FILS_SHA384:
+		return eCSR_AUTH_TYPE_FT_FILS_SHA384;
+	case WLAN_AUTH_TYPE_DPP_RSN:
+		return eCSR_AUTH_TYPE_DPP_RSN;
+	case WLAN_AUTH_TYPE_OWE:
+		return eCSR_AUTH_TYPE_OWE;
+	case WLAN_AUTH_TYPE_SUITEB_EAP_SHA256:
+		return eCSR_AUTH_TYPE_SUITEB_EAP_SHA256;
+	case WLAN_AUTH_TYPE_SUITEB_EAP_SHA384:
+		return eCSR_AUTH_TYPE_SUITEB_EAP_SHA384;
+	case WLAN_AUTH_TYPE_SAE:
+		return eCSR_AUTH_TYPE_SAE;
+	case WLAN_NUM_OF_SUPPORT_AUTH_TYPE:
+	default:
+		return eCSR_AUTH_TYPE_OPEN_SYSTEM;
+	}
+}
+
+static enum wlan_enc_type csr_covert_enc_type_new(eCsrEncryptionType enc)
+{
+	switch (enc) {
+	case eCSR_ENCRYPT_TYPE_NONE:
+		return WLAN_ENCRYPT_TYPE_NONE;
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+		return WLAN_ENCRYPT_TYPE_WEP40_STATICKEY;
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+		return WLAN_ENCRYPT_TYPE_WEP104_STATICKEY;
+	case eCSR_ENCRYPT_TYPE_WEP40:
+		return WLAN_ENCRYPT_TYPE_WEP40;
+	case eCSR_ENCRYPT_TYPE_WEP104:
+		return WLAN_ENCRYPT_TYPE_WEP104;
+	case eCSR_ENCRYPT_TYPE_TKIP:
+		return WLAN_ENCRYPT_TYPE_TKIP;
+	case eCSR_ENCRYPT_TYPE_AES:
+		return WLAN_ENCRYPT_TYPE_AES;
+	case eCSR_ENCRYPT_TYPE_WPI:
+		return WLAN_ENCRYPT_TYPE_WPI;
+	case eCSR_ENCRYPT_TYPE_KRK:
+		return WLAN_ENCRYPT_TYPE_KRK;
+	case eCSR_ENCRYPT_TYPE_BTK:
+		return WLAN_ENCRYPT_TYPE_BTK;
+	case eCSR_ENCRYPT_TYPE_AES_CMAC:
+		return WLAN_ENCRYPT_TYPE_AES_CMAC;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP:
+		return WLAN_ENCRYPT_TYPE_AES_GCMP;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
+		return WLAN_ENCRYPT_TYPE_AES_GCMP_256;
+	case eCSR_ENCRYPT_TYPE_ANY:
+	default:
+		return WLAN_ENCRYPT_TYPE_NONE;
+	}
+}
+
+static eCsrEncryptionType csr_covert_enc_type_old(enum wlan_enc_type enc)
+{
+	switch (enc) {
+	case WLAN_ENCRYPT_TYPE_NONE:
+		return eCSR_ENCRYPT_TYPE_NONE;
+	case WLAN_ENCRYPT_TYPE_WEP40_STATICKEY:
+		return eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
+	case WLAN_ENCRYPT_TYPE_WEP104_STATICKEY:
+		return eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
+	case WLAN_ENCRYPT_TYPE_WEP40:
+		return eCSR_ENCRYPT_TYPE_WEP40;
+	case WLAN_ENCRYPT_TYPE_WEP104:
+		return eCSR_ENCRYPT_TYPE_WEP104;
+	case WLAN_ENCRYPT_TYPE_TKIP:
+		return eCSR_ENCRYPT_TYPE_TKIP;
+	case WLAN_ENCRYPT_TYPE_AES:
+		return eCSR_ENCRYPT_TYPE_AES;
+	case WLAN_ENCRYPT_TYPE_WPI:
+		return eCSR_ENCRYPT_TYPE_WPI;
+	case WLAN_ENCRYPT_TYPE_KRK:
+		return eCSR_ENCRYPT_TYPE_KRK;
+	case WLAN_ENCRYPT_TYPE_BTK:
+		return eCSR_ENCRYPT_TYPE_BTK;
+	case WLAN_ENCRYPT_TYPE_AES_CMAC:
+		return eCSR_ENCRYPT_TYPE_AES_CMAC;
+	case WLAN_ENCRYPT_TYPE_AES_GCMP:
+		return eCSR_ENCRYPT_TYPE_AES_GCMP;
+	case WLAN_ENCRYPT_TYPE_AES_GCMP_256:
+		return eCSR_ENCRYPT_TYPE_AES_GCMP_256;
+	case WLAN_ENCRYPT_TYPE_ANY:
+	default:
+		return eCSR_ENCRYPT_TYPE_NONE;
+	}
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * csr_update_pmf_cap: Updates PMF cap
+ * @src_filter: Source filter
+ * @dst_filter: Destination filter
+ *
+ * Return: None
+ */
+static void csr_update_pmf_cap(tCsrScanResultFilter *src_filter,
+		struct scan_filter *dst_filter) {
+
+	if (src_filter->MFPCapable || src_filter->MFPEnabled)
+		dst_filter->pmf_cap = WLAN_PMF_CAPABLE;
+	if (src_filter->MFPRequired)
+		dst_filter->pmf_cap = WLAN_PMF_REQUIRED;
+}
+#else
+static inline void csr_update_pmf_cap(tCsrScanResultFilter *src_filter,
+		struct scan_filter *dst_filter)
+{}
+#endif
+
+/**
+ * csr_convert_dotllmod_phymode: Convert eCsrPhyMode to wlan_phymode
+ * @dotllmode: phy mode
+ *
+ * Return: returns enum wlan_phymode
+ */
+static enum wlan_phymode csr_convert_dotllmod_phymode(eCsrPhyMode dotllmode)
+{
+
+	enum wlan_phymode con_phy_mode;
+
+	switch (dotllmode) {
+	case eCSR_DOT11_MODE_abg:
+		con_phy_mode = WLAN_PHYMODE_AUTO;
+		break;
+	case eCSR_DOT11_MODE_11a:
+		con_phy_mode = WLAN_PHYMODE_11A;
+		break;
+	case eCSR_DOT11_MODE_11b:
+		con_phy_mode = WLAN_PHYMODE_11B;
+		break;
+	case eCSR_DOT11_MODE_11g:
+		con_phy_mode = WLAN_PHYMODE_11G;
+		break;
+	case eCSR_DOT11_MODE_11n:
+		con_phy_mode = WLAN_PHYMODE_11NA_HT20;
+		break;
+	case eCSR_DOT11_MODE_11g_ONLY:
+		con_phy_mode = WLAN_PHYMODE_11G;
+		break;
+	case eCSR_DOT11_MODE_11n_ONLY:
+		con_phy_mode = WLAN_PHYMODE_11NA_HT20;
+		break;
+	case eCSR_DOT11_MODE_11b_ONLY:
+		con_phy_mode = WLAN_PHYMODE_11B;
+		break;
+	case eCSR_DOT11_MODE_11ac:
+		con_phy_mode = WLAN_PHYMODE_11AC_VHT160;
+		break;
+	case eCSR_DOT11_MODE_11ac_ONLY:
+		con_phy_mode = WLAN_PHYMODE_11AC_VHT160;
+		break;
+	case eCSR_DOT11_MODE_AUTO:
+		con_phy_mode = WLAN_PHYMODE_AUTO;
+		break;
+	case eCSR_DOT11_MODE_11ax:
+		con_phy_mode = WLAN_PHYMODE_11AXA_HE160;
+		break;
+	case eCSR_DOT11_MODE_11ax_ONLY:
+		con_phy_mode = WLAN_PHYMODE_11AXA_HE160;
+		break;
+	default:
+		con_phy_mode = WLAN_PHYMODE_AUTO;
+		break;
+	}
+
+	return con_phy_mode;
+}
+
+static QDF_STATUS csr_prepare_scan_filter(tpAniSirGlobal mac_ctx,
+	tCsrScanResultFilter *pFilter, struct scan_filter *filter)
+{
+	int i;
+	uint32_t len = 0;
+	QDF_STATUS status;
+	enum policy_mgr_con_mode new_mode;
+
+	filter->num_of_bssid = pFilter->BSSIDs.numOfBSSIDs;
+	if (filter->num_of_bssid > WLAN_SCAN_FILTER_NUM_BSSID)
+		filter->num_of_bssid = WLAN_SCAN_FILTER_NUM_BSSID;
+	for (i = 0; i < filter->num_of_bssid; i++)
+		qdf_mem_copy(filter->bssid_list[i].bytes,
+			pFilter->BSSIDs.bssid[i].bytes,
+			QDF_MAC_ADDR_SIZE);
+
+	filter->num_of_ssid = pFilter->SSIDs.numOfSSIDs;
+	if (filter->num_of_ssid > WLAN_SCAN_FILTER_NUM_SSID)
+		filter->num_of_ssid = WLAN_SCAN_FILTER_NUM_SSID;
+	for (i = 0; i < filter->num_of_ssid; i++) {
+		filter->ssid_list[i].length =
+			pFilter->SSIDs.SSIDList[i].SSID.length;
+		qdf_mem_copy(filter->ssid_list[i].ssid,
+			pFilter->SSIDs.SSIDList[i].SSID.ssId,
+			filter->ssid_list[i].length);
+	}
+
+	filter->num_of_channels =
+		pFilter->ChannelInfo.numOfChannels;
+	if (filter->num_of_channels > QDF_MAX_NUM_CHAN)
+		filter->num_of_channels = QDF_MAX_NUM_CHAN;
+	qdf_mem_copy(filter->channel_list,
+			pFilter->ChannelInfo.ChannelList,
+			filter->num_of_channels);
+
+	if (pFilter->realm_check) {
+		filter->fils_scan_filter.realm_check = true;
+		qdf_mem_copy(filter->fils_scan_filter.fils_realm,
+			pFilter->fils_realm, REAM_HASH_LEN);
+	}
+
+	if (pFilter->force_rsne_override) {
+
+		sme_debug("force_rsne_override set auth type and enctype to any and ignore pmf cap");
+
+		filter->num_of_auth = 1;
+		filter->auth_type[0] = WLAN_AUTH_TYPE_ANY;
+		filter->num_of_enc_type = 1;
+		filter->enc_type[0] = WLAN_ENCRYPT_TYPE_ANY;
+		filter->num_of_mc_enc_type = 1;
+		filter->mc_enc_type[0] = WLAN_ENCRYPT_TYPE_ANY;
+
+		filter->ignore_pmf_cap = true;
+	} else {
+		filter->num_of_auth =
+			pFilter->authType.numEntries;
+		if (filter->num_of_auth > WLAN_NUM_OF_SUPPORT_AUTH_TYPE)
+			filter->num_of_auth = WLAN_NUM_OF_SUPPORT_AUTH_TYPE;
+		for (i = 0; i < filter->num_of_auth; i++)
+			filter->auth_type[i] =
+			  csr_covert_auth_type_new(
+			  pFilter->authType.authType[i]);
+		filter->num_of_enc_type =
+			pFilter->EncryptionType.numEntries;
+		if (filter->num_of_enc_type > WLAN_NUM_OF_ENCRYPT_TYPE)
+			filter->num_of_enc_type = WLAN_NUM_OF_ENCRYPT_TYPE;
+		for (i = 0; i < filter->num_of_enc_type; i++)
+			filter->enc_type[i] =
+			  csr_covert_enc_type_new(
+			  pFilter->EncryptionType.encryptionType[i]);
+		filter->num_of_mc_enc_type =
+				pFilter->mcEncryptionType.numEntries;
+		if (filter->num_of_mc_enc_type > WLAN_NUM_OF_ENCRYPT_TYPE)
+			filter->num_of_mc_enc_type = WLAN_NUM_OF_ENCRYPT_TYPE;
+		for (i = 0; i < filter->num_of_mc_enc_type; i++)
+			filter->mc_enc_type[i] =
+			  csr_covert_enc_type_new(
+			  pFilter->mcEncryptionType.encryptionType[i]);
+	}
+	qdf_mem_copy(filter->country,
+		pFilter->countryCode, WNI_CFG_COUNTRY_CODE_LEN);
+
+	if (pFilter->bWPSAssociation || pFilter->bOSENAssociation)
+		filter->ignore_auth_enc_type = true;
+
+	filter->rrm_measurement_filter = pFilter->fMeasurement;
+
+	filter->mobility_domain = pFilter->MDID.mobilityDomain;
+
+	filter->p2p_results = pFilter->p2pResult;
+
+	csr_update_pmf_cap(pFilter, filter);
+
+	if (pFilter->BSSType == eCSR_BSS_TYPE_INFRASTRUCTURE)
+		filter->bss_type = WLAN_TYPE_BSS;
+	else if (pFilter->BSSType == eCSR_BSS_TYPE_IBSS ||
+		pFilter->BSSType == eCSR_BSS_TYPE_START_IBSS)
+		filter->bss_type = WLAN_TYPE_IBSS;
+	else
+		filter->bss_type = WLAN_TYPE_ANY;
+
+	filter->dot11_mode = csr_convert_dotllmod_phymode(pFilter->phyMode);
+
+	// enable bss scoring for only STA mode
+	if (pFilter->csrPersona == QDF_STA_MODE)
+		filter->bss_scoring_required = true;
+	else
+		filter->bss_scoring_required = false;
+	if (!pFilter->BSSIDs.numOfBSSIDs) {
+		if (policy_mgr_map_concurrency_mode(
+		   &pFilter->csrPersona, &new_mode)) {
+			status = policy_mgr_get_pcl(mac_ctx->psoc, new_mode,
+				filter->pcl_channel_list, &len,
+				filter->pcl_weight_list, QDF_MAX_NUM_CHAN);
+			filter->num_of_pcl_channels = (uint8_t)len;
+		}
+	}
+	qdf_mem_copy(filter->bssid_hint.bytes,
+			pFilter->bssid_hint.bytes,
+			QDF_MAC_ADDR_SIZE);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * csr_update_bss_with_fils_data: Fill FILS params in bss desc from scan entry
+ * @mac_ctx: mac context
+ * @scan_entry: scan entry
+ * @bss_descr: bss description
+ */
+static void csr_update_bss_with_fils_data(tpAniSirGlobal mac_ctx,
+					  struct scan_cache_entry *scan_entry,
+					  tSirBssDescription *bss_descr)
+{
+	int ret;
+	tDot11fIEfils_indication fils_indication = {0};
+	struct sir_fils_indication fils_ind;
+
+	if (!scan_entry->ie_list.fils_indication)
+		return;
+
+	ret = dot11f_unpack_ie_fils_indication(mac_ctx,
+				scan_entry->ie_list.fils_indication +
+				SIR_FILS_IND_ELEM_OFFSET,
+				*(scan_entry->ie_list.fils_indication + 1),
+				&fils_indication, false);
+	if (DOT11F_FAILED(ret)) {
+		sme_err("unpack failed ret: 0x%x", ret);
+		return;
+	}
+
+	update_fils_data(&fils_ind, &fils_indication);
+	if (fils_ind.realm_identifier.realm_cnt > SIR_MAX_REALM_COUNT)
+		fils_ind.realm_identifier.realm_cnt = SIR_MAX_REALM_COUNT;
+
+	bss_descr->fils_info_element.realm_cnt =
+		fils_ind.realm_identifier.realm_cnt;
+	qdf_mem_copy(bss_descr->fils_info_element.realm,
+			fils_ind.realm_identifier.realm,
+			bss_descr->fils_info_element.realm_cnt * SIR_REALM_LEN);
+	if (fils_ind.cache_identifier.is_present) {
+		bss_descr->fils_info_element.is_cache_id_present = true;
+		qdf_mem_copy(bss_descr->fils_info_element.cache_id,
+			fils_ind.cache_identifier.identifier, CACHE_ID_LEN);
+	}
+	if (fils_ind.is_fils_sk_auth_supported)
+		bss_descr->fils_info_element.is_fils_sk_supported = true;
+}
+#else
+static void csr_update_bss_with_fils_data(tpAniSirGlobal mac_ctx,
+					  struct scan_cache_entry *scan_entry,
+					  tSirBssDescription *bss_descr)
+{ }
+#endif
+
+static QDF_STATUS csr_fill_bss_from_scan_entry(tpAniSirGlobal mac_ctx,
+	struct scan_cache_entry *scan_entry,
+	struct tag_csrscan_result **p_result)
+{
+	tDot11fBeaconIEs *bcn_ies;
+	tSirBssDescription *bss_desc;
+	tCsrScanResultInfo *result_info;
+	tpSirMacMgmtHdr hdr;
+	uint8_t *ie_ptr;
+	struct tag_csrscan_result *bss;
+	uint32_t bss_len, alloc_len, ie_len;
+	QDF_STATUS status;
+
+	ie_len = util_scan_entry_ie_len(scan_entry);
+	ie_ptr = util_scan_entry_ie_data(scan_entry);
+
+	hdr = (tpSirMacMgmtHdr)scan_entry->raw_frame.ptr;
+
+	bss_len = (uint16_t)(offsetof(tSirBssDescription,
+			   ieFields[0]) + ie_len);
+	alloc_len = sizeof(struct tag_csrscan_result) + bss_len;
+	bss = qdf_mem_malloc(alloc_len);
+	if (!bss)
+		return QDF_STATUS_E_NOMEM;
+
+	bss->AgingCount =
+		(int32_t) mac_ctx->roam.configParam.agingCount;
+	bss->ucEncryptionType =
+		csr_covert_enc_type_old(scan_entry->neg_sec_info.uc_enc);
+	bss->mcEncryptionType =
+		csr_covert_enc_type_old(scan_entry->neg_sec_info.mc_enc);
+	bss->authType =
+		csr_covert_auth_type_old(scan_entry->neg_sec_info.auth_type);
+	bss->bss_score = scan_entry->bss_score;
+
+	result_info = &bss->Result;
+	result_info->ssId.length = scan_entry->ssid.length;
+	qdf_mem_copy(result_info->ssId.ssId,
+		scan_entry->ssid.ssid,
+		result_info->ssId.length);
+	result_info->timer = scan_entry->hidden_ssid_timestamp;
+
+	bss_desc = &result_info->BssDescriptor;
+
+	bss_desc->length = (uint16_t) (offsetof(tSirBssDescription,
+			   ieFields[0]) - sizeof(bss_desc->length) + ie_len);
+
+	qdf_mem_copy(bss_desc->bssId,
+			scan_entry->bssid.bytes,
+			QDF_MAC_ADDR_SIZE);
+	bss_desc->scansystimensec = scan_entry->scan_entry_time;
+	qdf_mem_copy(bss_desc->timeStamp,
+		scan_entry->tsf_info.data, 8);
+
+	bss_desc->beaconInterval = scan_entry->bcn_int;
+	bss_desc->capabilityInfo = scan_entry->cap_info.value;
+
+	if (WLAN_REG_IS_5GHZ_CH(scan_entry->channel.chan_idx))
+		bss_desc->nwType = eSIR_11A_NW_TYPE;
+	else if (scan_entry->phy_mode == WLAN_PHYMODE_11B)
+		bss_desc->nwType = eSIR_11B_NW_TYPE;
+	else
+		bss_desc->nwType = eSIR_11G_NW_TYPE;
+
+	bss_desc->rssi = scan_entry->rssi_raw;
+	bss_desc->rssi_raw = scan_entry->rssi_raw;
+
+	/* channelId what peer sent in beacon/probersp. */
+	bss_desc->channelId =
+		scan_entry->channel.chan_idx;
+	/* channelId on which we are parked at. */
+	/* used only in scan case. */
+	bss_desc->channelIdSelf =
+		scan_entry->channel.chan_idx;
+	bss_desc->rx_channel = bss_desc->channelIdSelf;
+	bss_desc->received_time =
+		scan_entry->scan_entry_time;
+	bss_desc->startTSF[0] =
+		mac_ctx->rrm.rrmPEContext.startTSF[0];
+	bss_desc->startTSF[1] =
+		mac_ctx->rrm.rrmPEContext.startTSF[1];
+	bss_desc->parentTSF =
+		scan_entry->rrm_parent_tsf;
+	bss_desc->fProbeRsp = (scan_entry->frm_subtype ==
+			  IEEE80211_FC0_SUBTYPE_PROBE_RESP);
+	bss_desc->seq_ctrl = hdr->seqControl;
+	bss_desc->tsf_delta = scan_entry->tsf_delta;
+
+	qdf_mem_copy((uint8_t *) &bss_desc->ieFields,
+		ie_ptr, ie_len);
+
+	status = csr_get_parsed_bss_description_ies(mac_ctx,
+			  bss_desc, &bcn_ies);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		qdf_mem_free(bss);
+		return status;
+	}
+	result_info->pvIes = bcn_ies;
+
+	if (bcn_ies->MobilityDomain.present) {
+		bss_desc->mdiePresent = true;
+		qdf_mem_copy((uint8_t *)&(bss_desc->mdie[0]),
+			     (uint8_t *)&(bcn_ies->MobilityDomain.MDID),
+			     sizeof(uint16_t));
+		bss_desc->mdie[2] =
+			((bcn_ies->MobilityDomain.overDSCap << 0) |
+			(bcn_ies->MobilityDomain.resourceReqCap << 1));
+	}
+#ifdef FEATURE_WLAN_ESE
+	if (bcn_ies->QBSSLoad.present) {
+		bss_desc->QBSSLoad_present = true;
+		bss_desc->QBSSLoad_avail =
+			bcn_ies->QBSSLoad.avail;
+	}
+#endif
+	csr_update_bss_with_fils_data(mac_ctx, scan_entry, bss_desc);
+	if (scan_entry->alt_wcn_ie.ptr) {
+		bss_desc->WscIeLen = scan_entry->alt_wcn_ie.len;
+		qdf_mem_copy(bss_desc->WscIeProbeRsp,
+			scan_entry->alt_wcn_ie.ptr,
+			scan_entry->alt_wcn_ie.len);
+	}
+
+	*p_result = bss;
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS csr_parse_scan_list(tpAniSirGlobal mac_ctx,
+	struct scan_result_list *ret_list,
+	qdf_list_t *scan_list)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct tag_csrscan_result *pResult = NULL;
+	struct scan_cache_node *cur_node = NULL;
+	struct scan_cache_node *next_node = NULL;
+
+	status =
+		qdf_list_peek_front(scan_list,
+		   (qdf_list_node_t **) &cur_node);
+
+	while (cur_node) {
+		qdf_list_peek_next(
+		  scan_list,
+		  (qdf_list_node_t *) cur_node,
+		  (qdf_list_node_t **) &next_node);
+		status = csr_fill_bss_from_scan_entry(mac_ctx,
+			cur_node->entry, &pResult);
+		if (QDF_IS_STATUS_ERROR(status))
+			return status;
+		if (pResult)
+			csr_ll_insert_tail(&ret_list->List, &pResult->Link,
+			   LL_ACCESS_NOLOCK);
+		cur_node = next_node;
+		next_node = NULL;
+	}
+
+	return status;
+}
+
+/**
+ * csr_remove_ap_due_to_rssi() - check if bss is present in
+ * list of BSSID which rejected Assoc due to RSSI
+ * @list: rssi based rejected BSS list
+ * @bss_descr: pointer to bss description
+ *
+ * Check if the time interval indicated in last Assoc reject
+ * has expired OR rssi has improved by margin indicated
+ * in last Assoc reject. If any of the condition match remove
+ * the AP from the avoid list, else do not try to conenct
+ * to the AP
+ *
+ * Return: true if connection cannot be tried with AP else false
+ */
+static bool csr_remove_ap_due_to_rssi(qdf_list_t *list,
+	tSirBssDescription *bss_descr)
+{
+	QDF_STATUS status;
+	struct sir_rssi_disallow_lst *cur_node = NULL;
+	qdf_list_node_t *cur_lst = NULL, *next_lst = NULL;
+	qdf_time_t cur_time;
+	uint32_t time_diff;
+
+	if (!qdf_list_size(list))
+		return false;
+
+	cur_time = qdf_do_div(qdf_get_monotonic_boottime(),
+		QDF_MC_TIMER_TO_MS_UNIT);
+
+	qdf_list_peek_front(list, &cur_lst);
+	while (cur_lst) {
+		cur_node = qdf_container_of(cur_lst,
+				struct sir_rssi_disallow_lst, node);
+
+		qdf_list_peek_next(list, cur_lst, &next_lst);
+
+		time_diff = cur_time - cur_node->time_during_rejection;
+		if ((time_diff > cur_node->retry_delay)) {
+			sme_debug("Remove %pM as time diff %d is greater retry delay %d",
+				cur_node->bssid.bytes, time_diff,
+				cur_node->retry_delay);
+			status = qdf_list_remove_node(list, cur_lst);
+			if (QDF_IS_STATUS_SUCCESS(status))
+				qdf_mem_free(cur_node);
+			cur_lst = next_lst;
+			next_lst = NULL;
+			cur_node = NULL;
+			continue;
+		}
+
+		if (!qdf_mem_cmp(cur_node->bssid.bytes,
+		    bss_descr->bssId, QDF_MAC_ADDR_SIZE))
+			break;
+		cur_lst = next_lst;
+		next_lst = NULL;
+		cur_node = NULL;
+	}
+
+	if (cur_node) {
+		time_diff = cur_time - cur_node->time_during_rejection;
+		if (!(time_diff > cur_node->retry_delay ||
+		   bss_descr->rssi_raw >= cur_node->expected_rssi)) {
+			sme_err("Don't Attempt to connect %pM (time diff %d retry delay %d rssi %d expected rssi %d)",
+				cur_node->bssid.bytes, time_diff,
+				cur_node->retry_delay, bss_descr->rssi_raw,
+				cur_node->expected_rssi);
+			return true;
+		}
+		sme_debug("Remove %pM as time diff %d is greater retry delay %d or RSSI %d is greater than expected %d",
+				cur_node->bssid.bytes, time_diff,
+				cur_node->retry_delay,
+				bss_descr->rssi_raw,
+				cur_node->expected_rssi);
+		status = qdf_list_remove_node(list, cur_lst);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			qdf_mem_free(cur_node);
+	}
+
+	return false;
+}
+
+/**
+ * csr_filter_ap_due_to_rssi_reject() - filter the AP who has sent
+ * assoc reject due to RSSI if condition has not improved
+ * @mac_ctx: mac context
+ * @scan_list: candidate list for the connection
+ *
+ * Return: void
+ */
+static void csr_filter_ap_due_to_rssi_reject(tpAniSirGlobal mac_ctx,
+	struct scan_result_list *scan_list)
+{
+	tListElem *cur_entry;
+	tListElem *next_entry;
+	struct tag_csrscan_result *scan_res;
+	bool remove;
+
+	if (!scan_list ||
+	   !qdf_list_size(&mac_ctx->roam.rssi_disallow_bssid))
+		return;
+
+	csr_ll_lock(&scan_list->List);
+
+	cur_entry = csr_ll_peek_head(&scan_list->List, LL_ACCESS_NOLOCK);
+	while (cur_entry) {
+		scan_res = GET_BASE_ADDR(cur_entry, struct tag_csrscan_result,
+					Link);
+		next_entry = csr_ll_next(&scan_list->List,
+						cur_entry, LL_ACCESS_NOLOCK);
+		remove = csr_remove_ap_due_to_rssi(
+			&mac_ctx->roam.rssi_disallow_bssid,
+			&scan_res->Result.BssDescriptor);
+		if (remove) {
+			csr_ll_remove_entry(&scan_list->List,
+				cur_entry, LL_ACCESS_NOLOCK);
+			csr_free_scan_result_entry(mac_ctx, scan_res);
+		}
+		cur_entry = next_entry;
+		next_entry = NULL;
+	}
+	csr_ll_unlock(&scan_list->List);
+
+}
+
+QDF_STATUS csr_scan_get_result(tpAniSirGlobal mac_ctx,
+			       tCsrScanResultFilter *pFilter,
+			       tScanResultHandle *results)
+{
+	QDF_STATUS status;
+	struct scan_result_list *ret_list = NULL;
+	qdf_list_t *list = NULL;
+	struct scan_filter *filter = NULL;
+	struct wlan_objmgr_pdev *pdev = NULL;
+
+	if (results)
+		*results = CSR_INVALID_SCANRESULT_HANDLE;
+
+	pdev = wlan_objmgr_get_pdev_by_id(mac_ctx->psoc,
+		0, WLAN_LEGACY_MAC_ID);
+	if (!pdev) {
+		sme_err("pdev is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (pFilter) {
+		filter = qdf_mem_malloc(sizeof(*filter));
+		if (!filter) {
+			status = QDF_STATUS_E_NOMEM;
+			goto error;
+		}
+
+		status = csr_prepare_scan_filter(mac_ctx, pFilter, filter);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			sme_err("Prepare filter failed");
+			goto error;
+		}
+	}
+
+	list = ucfg_scan_get_result(pdev,
+		    pFilter ? filter : NULL);
+	if (list)
+		sme_debug("num_entries %d", qdf_list_size(list));
+
+	if (!list || (list && !qdf_list_size(list))) {
+		sme_err("get scan result failed");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto error;
+	}
+
+	ret_list = qdf_mem_malloc(sizeof(struct scan_result_list));
+	if (!ret_list) {
+		status = QDF_STATUS_E_NOMEM;
+		goto error;
+	}
+
+	csr_ll_open(&ret_list->List);
+	ret_list->pCurEntry = NULL;
+	status = csr_parse_scan_list(mac_ctx,
+		ret_list, list);
+	sme_debug("status: %d No of BSS: %d",
+		  status, csr_ll_count(&ret_list->List));
+	if (QDF_IS_STATUS_ERROR(status) || !results)
+		/* Fail or No one wants the result. */
+		csr_scan_result_purge(mac_ctx, (tScanResultHandle) ret_list);
+	else {
+		if (pFilter)
+			csr_filter_ap_due_to_rssi_reject(mac_ctx, ret_list);
+		if (!csr_ll_count(&ret_list->List)) {
+			/* This mean that there is no match */
+			csr_ll_close(&ret_list->List);
+			qdf_mem_free(ret_list);
+			status = QDF_STATUS_E_NULL_VALUE;
+		} else if (results) {
+			*results = ret_list;
+		}
+	}
+
+error:
+	if (filter)
+		qdf_mem_free(filter);
+	if (list)
+		ucfg_scan_purge_results(list);
+	if (pdev)
+		wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID);
+
+	return status;
+}
+
+QDF_STATUS csr_scan_get_result_for_bssid(tpAniSirGlobal mac_ctx,
+					struct qdf_mac_addr *bssid,
+					tCsrScanResultInfo *res)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tCsrScanResultFilter *scan_filter = NULL;
+	tScanResultHandle filtered_scan_result = NULL;
+	tCsrScanResultInfo *scan_result;
+
+	if (!mac_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("mac_ctx is NULL"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (!scan_filter)
+		return QDF_STATUS_E_NOMEM;
+
+	scan_filter->BSSIDs.bssid = qdf_mem_malloc(sizeof(*bssid));
+	if (!scan_filter->BSSIDs.bssid) {
+		status = QDF_STATUS_E_FAILURE;
+		goto free_filter;
+	}
+
+	scan_filter->BSSIDs.numOfBSSIDs = 1;
+	qdf_mem_copy(scan_filter->BSSIDs.bssid, bssid, sizeof(*bssid));
+
+	status = csr_scan_get_result(mac_ctx, scan_filter,
+				&filtered_scan_result);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Failed to get scan result");
+		goto free_filter;
+	}
+
+	scan_result = csr_scan_result_get_first(mac_ctx, filtered_scan_result);
+
+	if (scan_result) {
+		res->pvIes = NULL;
+		res->ssId.length = scan_result->ssId.length;
+		qdf_mem_copy(&res->ssId.ssId, &scan_result->ssId.ssId,
+			res->ssId.length);
+		res->timer = scan_result->timer;
+		qdf_mem_copy(&res->BssDescriptor, &scan_result->BssDescriptor,
+			sizeof(tSirBssDescription));
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	csr_scan_result_purge(mac_ctx, filtered_scan_result);
+
+free_filter:
+	csr_free_scan_filter(mac_ctx, scan_filter);
+	if (scan_filter)
+		qdf_mem_free(scan_filter);
+
+	return status;
+}
+
+static inline QDF_STATUS
+csr_flush_scan_results(tpAniSirGlobal mac_ctx,
+	struct scan_filter *filter)
+{
+	struct wlan_objmgr_pdev *pdev = NULL;
+	QDF_STATUS status;
+
+	pdev = wlan_objmgr_get_pdev_by_id(mac_ctx->psoc,
+		0, WLAN_LEGACY_MAC_ID);
+	if (!pdev) {
+		sme_err("pdev is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	status = ucfg_scan_flush_results(pdev, filter);
+
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID);
+	return status;
+}
+
+QDF_STATUS csr_scan_flush_result(tpAniSirGlobal mac_ctx)
+{
+
+	if (csr_scan_flush_denied(mac_ctx)) {
+		sme_err("scan flush denied in roam state");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return csr_flush_scan_results(mac_ctx, NULL);
+}
+
+QDF_STATUS csr_scan_flush_selective_result(tpAniSirGlobal mac_ctx,
+	bool flush_p2p)
+{
+	struct scan_filter *filter;
+	QDF_STATUS status;
+
+	filter = qdf_mem_malloc(sizeof(*filter));
+	if (!filter) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+	filter->p2p_results = flush_p2p;
+	status = csr_flush_scan_results(mac_ctx, filter);
+	if (filter)
+		qdf_mem_free(filter);
+end:
+	return status;
+}
+
+static inline void csr_flush_bssid(tpAniSirGlobal mac_ctx,
+	uint8_t *bssid)
+{
+	struct scan_filter *filter;
+
+	filter = qdf_mem_malloc(sizeof(*filter));
+	if (!filter)
+		return;
+
+	filter->num_of_bssid = 1;
+	qdf_mem_copy(filter->bssid_list[0].bytes,
+		     bssid, QDF_MAC_ADDR_SIZE);
+
+	csr_flush_scan_results(mac_ctx, filter);
+	sme_debug("Removed BSS entry:%pM", bssid);
+	if (filter)
+		qdf_mem_free(filter);
+}
+
+void csr_scan_flush_bss_entry(tpAniSirGlobal mac_ctx,
+			tpSmeCsaOffloadInd csa_off_ind)
+{
+	csr_flush_bssid(mac_ctx,
+		csa_off_ind->bssid.bytes);
+}
+
+void csr_remove_bssid_from_scan_list(tpAniSirGlobal mac_ctx,
+			tSirMacAddr bssid)
+{
+	csr_flush_bssid(mac_ctx, bssid);
+}
+
+void csr_init_occupied_channels_list(tpAniSirGlobal mac_ctx,
+	uint8_t sessionId)
+{
+	tScanResultHandle results;
+	struct scan_result_list *scan_list = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tListElem *scan_entry = NULL;
+	struct tag_csrscan_result *bss_desc = NULL;
+	tDot11fBeaconIEs *ie_ptr = NULL;
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[sessionId];
+
+	if (neighbor_roam_info->cfgParams.channelInfo.numOfChannels) {
+		/*
+		 * Ini file contains neighbor scan channel list, hence NO need
+		 * to build occupied channel list"
+		 */
+		sme_debug("Ini contains neighbor scan ch list");
+		return;
+	}
+
+	if (!csr_neighbor_roam_is_new_connected_profile(mac_ctx, sessionId)) {
+		/*
+		 * Do not flush occupied list since current roam profile matches
+		 * previous
+		 */
+		sme_debug("Current roam profile matches prev");
+		return;
+	}
+
+	/* Empty occupied channels here */
+	mac_ctx->scan.occupiedChannels[sessionId].numChannels = 0;
+	mac_ctx->scan.roam_candidate_count[sessionId] = 0;
+
+	status = csr_scan_get_result(mac_ctx, NULL, &results);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			return;
+	scan_list = results;
+	csr_ll_lock(&scan_list->List);
+	scan_entry = csr_ll_peek_head(&scan_list->List, LL_ACCESS_NOLOCK);
+	while (scan_entry) {
+		bss_desc = GET_BASE_ADDR(scan_entry, struct tag_csrscan_result,
+					 Link);
+		ie_ptr = (tDot11fBeaconIEs *) (bss_desc->Result.pvIes);
+		if (!ie_ptr && !QDF_IS_STATUS_SUCCESS(
+			csr_get_parsed_bss_description_ies(mac_ctx,
+				&bss_desc->Result.BssDescriptor, &ie_ptr))) {
+			/* Pick next bss entry before continuing */
+			scan_entry = csr_ll_next(&scan_list->List, scan_entry,
+				     LL_ACCESS_NOLOCK);
+			continue;
+		}
+		csr_scan_add_to_occupied_channels(mac_ctx, bss_desc, sessionId,
+				&mac_ctx->scan.occupiedChannels[sessionId], ie_ptr,
+				true);
+		/*
+		 * Free the memory allocated for pIes in
+		 * csr_get_parsed_bss_description_ies
+		 */
+		if ((bss_desc->Result.pvIes == NULL) && ie_ptr)
+			qdf_mem_free(ie_ptr);
+		scan_entry = csr_ll_next(&scan_list->List, scan_entry,
+				     LL_ACCESS_NOLOCK);
+	}
+	csr_ll_unlock(&scan_list->List);
+
+	csr_scan_result_purge(mac_ctx, scan_list);
+}
+
+/**
+ * csr_scan_filter_results: filter scan result based
+ * on valid channel list number.
+ * @mac_ctx: mac context
+ *
+ * Get scan result from scan list and Check Scan result channel number
+ * with 11d channel list if channel number is found in 11d channel list
+ * then do not remove scan result entry from scan list
+ *
+ * return: QDF Status
+ */
+QDF_STATUS csr_scan_filter_results(tpAniSirGlobal mac_ctx)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t len = sizeof(mac_ctx->roam.validChannelList);
+	struct wlan_objmgr_pdev *pdev = NULL;
+
+	pdev = wlan_objmgr_get_pdev_by_id(mac_ctx->psoc,
+		0, WLAN_LEGACY_MAC_ID);
+	if (!pdev) {
+		sme_err("pdev is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	status = csr_get_cfg_valid_channels(mac_ctx,
+			  mac_ctx->roam.validChannelList,
+			  &len);
+
+	/* Get valid channels list from CFG */
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID);
+		sme_err("Failed to get Channel list from CFG");
+		return status;
+	}
+	sme_debug("No of valid channel %d", len);
+
+	ucfg_scan_filter_valid_channel(pdev,
+		mac_ctx->roam.validChannelList, len);
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID);
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/core/sme/src/csr/csr_cmd_process.c b/core/sme/src/csr/csr_cmd_process.c
new file mode 100644
index 0000000..a6f58cd
--- /dev/null
+++ b/core/sme/src/csr/csr_cmd_process.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2011-2018 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: csr_cmd_process.c
+ *
+ * Implementation for processing various commands.
+ */
+#include "ani_global.h"
+#include "csr_inside_api.h"
+#include "sme_inside.h"
+#include "mac_trace.h"
+
+/**
+ * csr_msg_processor() - To process all csr msg
+ * @mac_ctx: mac context
+ * @msg_buf: message buffer
+ *
+ * This routine will handle all the message for csr to process
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS csr_msg_processor(tpAniSirGlobal mac_ctx, void *msg_buf)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSirSmeRsp *sme_rsp = (tSirSmeRsp *) msg_buf;
+	uint8_t session_id = sme_rsp->sessionId;
+	enum csr_roam_state cur_state;
+
+	cur_state = sme_get_current_roam_state(MAC_HANDLE(mac_ctx), session_id);
+	sme_debug("msg %d[0x%04X] recvd in curstate %s & substate %s id(%d)",
+		sme_rsp->messageType, sme_rsp->messageType,
+		mac_trace_getcsr_roam_state(cur_state),
+		mac_trace_getcsr_roam_sub_state(
+			mac_ctx->roam.curSubState[session_id]),
+		session_id);
+
+	/* Process the message based on the state of the roaming states... */
+	switch (cur_state) {
+	case eCSR_ROAMING_STATE_JOINED:
+		/* are we in joined state */
+		csr_roam_joined_state_msg_processor(mac_ctx, msg_buf);
+		break;
+	case eCSR_ROAMING_STATE_JOINING:
+		/* are we in roaming states */
+		csr_roaming_state_msg_processor(mac_ctx, msg_buf);
+		break;
+
+	default:
+		if (sme_rsp->messageType ==
+		    eWNI_SME_GET_STATISTICS_RSP) {
+			csr_roam_joined_state_msg_processor(mac_ctx,
+							    msg_buf);
+			break;
+		}
+
+		/*
+		 * For all other messages, we ignore it
+		 * To work-around an issue where checking for set/remove
+		 * key base on connection state is no longer workable
+		 * due to failure or finding the condition meets both
+		 * SAP and infra/IBSS requirement.
+		 */
+		if (eWNI_SME_SETCONTEXT_RSP == sme_rsp->messageType ||
+		    eWNI_SME_DISCONNECT_DONE_IND ==
+		    sme_rsp->messageType) {
+			sme_warn("handling msg 0x%X CSR state is %d",
+				sme_rsp->messageType, cur_state);
+			csr_roam_check_for_link_status_change(mac_ctx,
+					sme_rsp);
+		} else if (eWNI_SME_GET_RSSI_REQ ==
+				sme_rsp->messageType) {
+			tAniGetRssiReq *pGetRssiReq =
+				(tAniGetRssiReq *) msg_buf;
+			if (NULL == pGetRssiReq->rssiCallback) {
+				sme_err("rssiCallback is NULL");
+				return status;
+			}
+			((tCsrRssiCallback)(pGetRssiReq->rssiCallback))(
+					pGetRssiReq->lastRSSI,
+					pGetRssiReq->staId,
+					pGetRssiReq->pDevContext);
+		} else {
+			sme_err("Message 0x%04X is not handled by CSR state is %d session Id %d",
+				sme_rsp->messageType, cur_state,
+				session_id);
+
+			if (eWNI_SME_FT_PRE_AUTH_RSP ==
+					sme_rsp->messageType) {
+				sme_err("Dequeue eSmeCommandRoam command with reason eCsrPerformPreauth");
+				csr_dequeue_roam_command(mac_ctx,
+					eCsrPerformPreauth, session_id);
+			} else if (eWNI_SME_REASSOC_RSP ==
+					sme_rsp->messageType) {
+				sme_err("Dequeue eSmeCommandRoam command with reason eCsrSmeIssuedFTReassoc");
+				csr_dequeue_roam_command(mac_ctx,
+					eCsrSmeIssuedFTReassoc,
+					session_id);
+			}
+		}
+		break;
+	} /* switch */
+	return status;
+}
diff --git a/core/sme/src/csr/csr_host_scan_roam.c b/core/sme/src/csr/csr_host_scan_roam.c
new file mode 100644
index 0000000..79d419e
--- /dev/null
+++ b/core/sme/src/csr/csr_host_scan_roam.c
@@ -0,0 +1,807 @@
+/*
+ * Copyright (c) 2016-2018 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: csr_host_scan_roam.c
+ *
+ * Host based roaming processing scan results and initiating the roaming
+ */
+
+#include "wma_types.h"
+#include "csr_inside_api.h"
+#include "sme_qos_internal.h"
+#include "sme_inside.h"
+#include "host_diag_core_event.h"
+#include "host_diag_core_log.h"
+#include "csr_api.h"
+#include "sme_api.h"
+#include "csr_neighbor_roam.h"
+#include "mac_trace.h"
+#include "wlan_policy_mgr_api.h"
+
+/**
+ * csr_roam_issue_reassociate() - Issue Reassociate
+ * @pMac: Global MAC Context
+ * @sessionId: SME Session ID
+ * @pSirBssDesc: BSS Descriptor
+ * @pIes: Pointer to the IE's
+ * @pProfile: Roaming profile
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS csr_roam_issue_reassociate(tpAniSirGlobal pMac,
+	uint32_t sessionId, tSirBssDescription *pSirBssDesc,
+	tDot11fBeaconIEs *pIes, struct csr_roam_profile *pProfile)
+{
+	csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING, sessionId);
+	/* Set the roaming substate to 'join attempt'... */
+	csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_REASSOC_REQ,
+			sessionId);
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL(" calling csr_send_join_req_msg (eWNI_SME_REASSOC_REQ)"));
+	/* attempt to Join this BSS... */
+	return csr_send_join_req_msg(pMac, sessionId, pSirBssDesc, pProfile,
+			pIes, eWNI_SME_REASSOC_REQ);
+}
+
+/**
+ * csr_roam_issue_reassociate_cmd() - Issue the reassociate command
+ * @pMac: Global MAC Context
+ * @sessionId: SME Session ID
+ *
+ * Return: Success or Failure status
+ */
+QDF_STATUS csr_roam_issue_reassociate_cmd(tpAniSirGlobal pMac,
+		uint32_t sessionId)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand = NULL;
+	bool fHighPriority = true;
+	bool fRemoveCmd = false;
+	tListElem *pEntry;
+	tSmeCmd *tmp_command;
+
+	pEntry = csr_nonscan_active_ll_peek_head(pMac, LL_ACCESS_LOCK);
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if (!pCommand) {
+			sme_err("fail to get command buffer");
+			return QDF_STATUS_E_RESOURCES;
+		}
+		if (eSmeCommandRoam == pCommand->command) {
+			if (pCommand->u.roamCmd.roamReason ==
+			    eCsrSmeIssuedAssocToSimilarAP)
+				fRemoveCmd =
+					csr_nonscan_active_ll_remove_entry(pMac,
+							    pEntry,
+							    LL_ACCESS_LOCK);
+			else
+				sme_err("Unexpected roam cmd present");
+			if (fRemoveCmd == false)
+				pCommand = NULL;
+		}
+	}
+	if (NULL == pCommand) {
+		sme_err("fail to get cmd buf based on prev roam command");
+		return QDF_STATUS_E_RESOURCES;
+	}
+	do {
+		/*
+		 * Get a new sme command to save the necessary info for
+		 * the following roaming process, such as BSS list and
+		 * roam profile. Or those info will be freed in function
+		 * csr_reinit_roam_cmd when releasing the current command.
+		 */
+		tmp_command = csr_get_command_buffer(pMac);
+		if (tmp_command == NULL) {
+			sme_err("fail to get cmd buf!");
+			csr_release_command(pMac, pCommand);
+			return QDF_STATUS_E_RESOURCES;
+		}
+		qdf_mem_copy(tmp_command, pCommand, sizeof(*pCommand));
+		pCommand->u.roamCmd.fReleaseBssList = false;
+		pCommand->u.roamCmd.hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
+		pCommand->u.roamCmd.fReleaseProfile = false;
+		/*
+		 * Invoking csr_release_command to release the current command
+		 * or the following command will be stuck in pending queue.
+		 * Because the API csr_nonscan_active_ll_remove_entry does
+		 * not remove the current command from active queue.
+		 */
+		csr_release_command(pMac, pCommand);
+
+		pCommand = tmp_command;
+		/* Change the substate in case it is wait-for-key */
+		if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
+			csr_roam_stop_wait_for_key_timer(pMac);
+			csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+						 sessionId);
+		}
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.roamReason = eCsrSmeIssuedFTReassoc;
+		status = csr_queue_sme_command(pMac, pCommand, fHighPriority);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			sme_err("fail to send message status: %d", status);
+	} while (0);
+
+	return status;
+}
+
+/**
+ * csr_neighbor_roam_process_scan_results() - build roaming candidate list
+ *
+ * @mac_ctx: The handle returned by mac_open.
+ * @sessionid: Session information
+ * @scan_results_list: List obtained from csr_scan_get_result()
+ *
+ * This function applies various candidate checks like LFR, 11r, preauth, ESE
+ * and builds a roamable AP list. It applies age limit only if no suitable
+ * recent candidates are found.
+ *
+ * Output list is built in mac_ctx->roam.neighborRoamInfo[sessionid].
+ *
+ * Return: void
+ */
+
+void csr_neighbor_roam_process_scan_results(tpAniSirGlobal mac_ctx,
+		uint8_t sessionid, tScanResultHandle *scan_results_list)
+{
+	tCsrScanResultInfo *scan_result;
+	tpCsrNeighborRoamControlInfo n_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[sessionid];
+	tpCsrNeighborRoamBSSInfo bss_info;
+	uint64_t age = 0;
+	uint8_t num_candidates = 0;
+	uint8_t num_dropped = 0;
+	/*
+	 * first iteration of scan list should consider
+	 * age constraint for candidates
+	 */
+	bool age_constraint = true;
+#ifdef FEATURE_WLAN_ESE
+	uint16_t qpresent;
+	uint16_t qavail;
+	bool voadmitted;
+#endif
+	/*
+	 * Expecting the scan result already to be in the sorted order based on
+	 * RSSI. Based on the previous state we need to check whether the list
+	 * should be sorted again taking neighbor score into consideration. If
+	 * previous state is CFG_CHAN_LIST_SCAN, there should not be a neighbor
+	 * score associated with any of the BSS. If the previous state is
+	 * REPORT_QUERY, then there will be neighbor score for each of the APs.
+	 * For now, let us take top of the list provided as it is by CSR Scan
+	 * result API. Hence it is assumed that neighbor score and rssi score
+	 * are in the same order. This will be taken care later.
+	 */
+
+	do {
+		while (true) {
+			tSirBssDescription *descr;
+
+			scan_result = csr_scan_result_get_next(
+						mac_ctx, *scan_results_list);
+			if (NULL == scan_result)
+				break;
+			descr = &scan_result->BssDescriptor;
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  FL("Scan result: BSSID " MAC_ADDRESS_STR
+				     " (Rssi %d, Ch:%d)"),
+				  MAC_ADDR_ARRAY(descr->bssId),
+				  (int)abs(descr->rssi), descr->channelId);
+
+			if (!qdf_mem_cmp(descr->bssId,
+					n_roam_info->currAPbssid.bytes,
+					sizeof(tSirMacAddr))) {
+				/*
+				 * currently associated AP. Do not have this
+				 * in the roamable AP list
+				 */
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "SKIP-currently associated AP");
+				continue;
+			}
+
+			/*
+			 * Continue if MCC is disabled in INI and if AP
+			 * will create MCC
+			 */
+			if (policy_mgr_concurrent_open_sessions_running(
+				mac_ctx->psoc) &&
+				!mac_ctx->roam.configParam.fenableMCCMode) {
+				uint8_t conc_channel;
+
+				conc_channel =
+				  csr_get_concurrent_operation_channel(mac_ctx);
+				if (conc_channel &&
+				   (conc_channel !=
+				   scan_result->BssDescriptor.channelId)) {
+					sme_debug("MCC not supported so Ignore AP on channel %d",
+					  scan_result->BssDescriptor.channelId);
+					continue;
+				}
+			}
+			/*
+			 * In case of reassoc requested by upper layer, look
+			 * for exact match of bssid & channel. csr cache might
+			 * have duplicates
+			 */
+			if ((n_roam_info->uOsRequestedHandoff) &&
+			    ((qdf_mem_cmp(descr->bssId,
+					n_roam_info->handoffReqInfo.bssid.bytes,
+					sizeof(tSirMacAddr)))
+			     || (descr->channelId !=
+				 n_roam_info->handoffReqInfo.channel))) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "SKIP-not a candidate AP for OS requested roam");
+				continue;
+			}
+
+			if ((n_roam_info->is11rAssoc) &&
+			    (!csr_neighbor_roam_is_preauth_candidate(mac_ctx,
+					sessionid, descr->bssId))) {
+				sme_err("BSSID in preauth fail list. Ignore");
+				continue;
+			}
+
+#ifdef FEATURE_WLAN_ESE
+			if (!csr_roam_is_roam_offload_scan_enabled(mac_ctx) &&
+			    (n_roam_info->isESEAssoc) &&
+			    !csr_neighbor_roam_is_preauth_candidate(mac_ctx,
+				sessionid, descr->bssId)) {
+				sme_err("BSSID in preauth faillist. Ignore");
+				continue;
+			}
+
+			qpresent = descr->QBSSLoad_present;
+			qavail = descr->QBSSLoad_avail;
+			voadmitted = n_roam_info->isVOAdmitted;
+			if (voadmitted)
+				sme_debug("New QBSS=%s,BWavail=0x%x,req=0x%x",
+					((qpresent) ? "yes" : "no"), qavail,
+					n_roam_info->MinQBssLoadRequired);
+			if (voadmitted && qpresent &&
+			    (qavail < n_roam_info->MinQBssLoadRequired)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_DEBUG,
+					"BSSID:" MAC_ADDRESS_STR "has no BW",
+					MAC_ADDR_ARRAY(descr->bssId));
+				continue;
+			}
+			if (voadmitted && !qpresent) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_DEBUG,
+					"BSSID:" MAC_ADDRESS_STR "no LOAD IE",
+					MAC_ADDR_ARRAY(descr->bssId));
+				continue;
+			}
+#endif /* FEATURE_WLAN_ESE */
+
+			/*
+			 * If we are supporting legacy roaming, and
+			 * if the candidate is on the "pre-auth failed" list,
+			 * ignore it.
+			 */
+			if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionid) &&
+			    !csr_neighbor_roam_is_preauth_candidate(mac_ctx,
+				sessionid, descr->bssId)) {
+				sme_err("BSSID in preauth faillist Ignore");
+				continue;
+			}
+
+			/* check the age of the AP */
+			age = (uint64_t) qdf_mc_timer_get_system_time() -
+					descr->received_time;
+			if (age_constraint == true &&
+				age > ROAM_AP_AGE_LIMIT_MS) {
+				num_dropped++;
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_WARN,
+					FL("Old AP (probe rsp/beacon) skipped.")
+					);
+				continue;
+			}
+
+			/* Finished all checks, now add it to candidate list */
+			bss_info =
+				qdf_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
+			if (!bss_info)
+				continue;
+
+			bss_info->pBssDescription =
+				qdf_mem_malloc(descr->length +
+					sizeof(descr->length));
+			if (bss_info->pBssDescription != NULL) {
+				qdf_mem_copy(bss_info->pBssDescription, descr,
+					descr->length + sizeof(descr->length));
+			} else {
+				qdf_mem_free(bss_info);
+				continue;
+			}
+			/*
+			 * Assign some preference value for now. Need to
+			 * calculate theactual score based on RSSI and neighbor
+			 * AP score
+			 */
+			bss_info->apPreferenceVal = 10;
+			num_candidates++;
+			csr_ll_insert_tail(&n_roam_info->roamableAPList,
+				&bss_info->List, LL_ACCESS_LOCK);
+		} /* end of while (csr_scan_result_get_next) */
+
+		/* if some candidates were found, then no need to repeat */
+		if (num_candidates)
+			break;
+		/*
+		 * if age_constraint is already false, we have done two
+		 * iterations and no candidate were found
+		 */
+		if (age_constraint == false) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: No roam able candidates found",
+				  __func__);
+			break;
+		}
+		/*
+		 * if all candidates were dropped rescan the scan
+		 * list but this time without age constraint.
+		 */
+		age_constraint = false;
+		/* if no candidates were dropped no need to repeat */
+	} while (num_dropped);
+
+	/*
+	 * Now we have all the scan results in our local list. Good time to free
+	 * up the the list we got as a part of csrGetScanResult
+	 */
+	csr_scan_result_purge(mac_ctx, *scan_results_list);
+}
+
+/**
+ * csr_neighbor_roam_trigger_handoff() - Start roaming
+ * @mac_ctx: Global MAC Context
+ * @session_id: SME Session ID
+ *
+ * Return: None
+ */
+void csr_neighbor_roam_trigger_handoff(tpAniSirGlobal mac_ctx,
+				      uint8_t session_id)
+{
+	if (csr_roam_is_fast_roam_enabled(mac_ctx, session_id))
+		csr_neighbor_roam_issue_preauth_req(mac_ctx, session_id);
+	else
+		sme_err("Roaming is disabled");
+}
+
+/**
+ * csr_neighbor_roam_process_scan_complete() - Post process the scan results
+ * @pMac: Global MAC Context
+ * @sessionId: SME Session ID
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS csr_neighbor_roam_process_scan_complete(tpAniSirGlobal pMac,
+		uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	tCsrScanResultFilter scanFilter;
+	tScanResultHandle scanResult;
+	uint32_t tempVal = 0;
+	QDF_STATUS hstatus;
+
+	hstatus = csr_neighbor_roam_prepare_scan_profile_filter(pMac,
+								&scanFilter,
+								sessionId);
+	sme_debug("Prepare scan to find neighbor AP filter status: %d",
+		hstatus);
+	if (QDF_STATUS_SUCCESS != hstatus) {
+		sme_err("Scan Filter prep fail for Assoc %d Bail out",
+			tempVal);
+		return QDF_STATUS_E_FAILURE;
+	}
+	hstatus = csr_scan_get_result(pMac, &scanFilter, &scanResult);
+	if (hstatus != QDF_STATUS_SUCCESS)
+		sme_err("Get Scan Result status code %d", hstatus);
+	/* Process the scan results and update roamable AP list */
+	csr_neighbor_roam_process_scan_results(pMac, sessionId, &scanResult);
+
+	/* Free the scan filter */
+	csr_free_scan_filter(pMac, &scanFilter);
+
+	tempVal = csr_ll_count(&pNeighborRoamInfo->roamableAPList);
+
+	if (tempVal) {
+		csr_neighbor_roam_trigger_handoff(pMac, sessionId);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (csr_roam_is_roam_offload_scan_enabled(pMac)) {
+		if (pNeighborRoamInfo->uOsRequestedHandoff) {
+			csr_roam_offload_scan(pMac, sessionId,
+				ROAM_SCAN_OFFLOAD_START,
+				REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+			pNeighborRoamInfo->uOsRequestedHandoff = 0;
+		} else {
+			/* There is no candidate or We are not roaming Now.
+			 * Inform the FW to restart Roam Offload Scan
+			 */
+			csr_roam_offload_scan(pMac, sessionId,
+				ROAM_SCAN_OFFLOAD_RESTART,
+				REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+		}
+		csr_neighbor_roam_state_transition(pMac,
+				eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, sessionId);
+	}
+	return QDF_STATUS_SUCCESS;
+
+}
+
+/**
+ * csr_neighbor_roam_candidate_found_ind_hdlr()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to msg buff
+ *
+ * This function is called by CSR as soon as TL posts the candidate
+ * found indication to SME via MC thread
+ *
+ * Return: QDF_STATUS_SUCCESS on success, corresponding error code otherwise
+ */
+QDF_STATUS csr_neighbor_roam_candidate_found_ind_hdlr(tpAniSirGlobal pMac,
+		void *pMsg)
+{
+	tSirSmeCandidateFoundInd *pSirSmeCandidateFoundInd =
+		(tSirSmeCandidateFoundInd *) pMsg;
+	uint32_t sessionId = pSirSmeCandidateFoundInd->sessionId;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	sme_debug("Received indication from firmware");
+
+	/* we must be in connected state, if not ignore it */
+	if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED !=
+	     pNeighborRoamInfo->neighborRoamState)
+	    || (pNeighborRoamInfo->uOsRequestedHandoff)) {
+		sme_err("Recvd in NotCONNECTED or OsReqHandoff. Ignore");
+		status = QDF_STATUS_E_FAILURE;
+	} else {
+		/* Future enhancements:
+		 * If firmware tags candidate beacons, give them preference
+		 * for roaming.
+		 * Age out older entries so that new candidate beacons
+		 * will get preference.
+		 */
+		status = csr_neighbor_roam_process_scan_complete(pMac,
+								 sessionId);
+		if (QDF_STATUS_SUCCESS != status) {
+			sme_err("scan process complete failed, status %d",
+				status);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return status;
+}
+
+/**
+ * csr_neighbor_roam_free_roamable_bss_list() - Frees roamable APs list
+ * @mac_ctx: The handle returned by mac_open.
+ * @llist: Neighbor Roam BSS List to be emptied
+ *
+ * Empties and frees all the nodes in the roamable AP list
+ *
+ * Return: none
+ */
+void csr_neighbor_roam_free_roamable_bss_list(tpAniSirGlobal mac_ctx,
+					      tDblLinkList *llist)
+{
+	tpCsrNeighborRoamBSSInfo result = NULL;
+
+	sme_debug("Emptying the BSS list. Current count: %d",
+		csr_ll_count(llist));
+
+	/*
+	 * Pick up the head, remove and free the node till
+	 * the list becomes empty
+	 */
+	while ((result = csr_neighbor_roam_next_roamable_ap(mac_ctx, llist,
+							NULL)) != NULL) {
+		csr_neighbor_roam_remove_roamable_ap_list_entry(mac_ctx,
+			llist, result);
+		csr_neighbor_roam_free_neighbor_roam_bss_node(mac_ctx, result);
+	}
+}
+
+/**
+ * csr_neighbor_roam_remove_roamable_ap_list_entry()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @pList: The list from which the entry should be removed
+ * @pNeighborEntry: Neighbor Roam BSS Node to be removed
+ *
+ * This function removes a given entry from the given list
+ *
+ * Return: true if successfully removed, else false
+ */
+bool csr_neighbor_roam_remove_roamable_ap_list_entry(tpAniSirGlobal pMac,
+						     tDblLinkList *pList,
+						     tpCsrNeighborRoamBSSInfo
+						     pNeighborEntry)
+{
+	if (pList) {
+		return csr_ll_remove_entry(pList, &pNeighborEntry->List,
+					   LL_ACCESS_LOCK);
+	}
+
+	sme_debug("Remove neigh BSS node from fail list. Current count: %d",
+		csr_ll_count(pList));
+
+	return false;
+}
+
+/**
+ * csr_neighbor_roam_next_roamable_ap() - Get next AP from roamable AP list
+ * @mac_ctx - The handle returned by mac_open.
+ * @plist - The list from which the entry should be returned
+ * @neighbor_entry - Neighbor Roam BSS Node whose next entry should be returned
+ *
+ * Gets the entry next to passed entry. If NULL is passed, return the entry
+ * in the head of the list
+ *
+ * Return: Neighbor Roam BSS Node to be returned
+ */
+tpCsrNeighborRoamBSSInfo csr_neighbor_roam_next_roamable_ap(
+				tpAniSirGlobal mac_ctx, tDblLinkList *llist,
+				tpCsrNeighborRoamBSSInfo neighbor_entry)
+{
+	tListElem *entry = NULL;
+	tpCsrNeighborRoamBSSInfo result = NULL;
+
+	if (llist) {
+		if (NULL == neighbor_entry)
+			entry = csr_ll_peek_head(llist, LL_ACCESS_LOCK);
+		else
+			entry = csr_ll_next(llist, &neighbor_entry->List,
+					LL_ACCESS_LOCK);
+		if (entry)
+			result = GET_BASE_ADDR(entry, tCsrNeighborRoamBSSInfo,
+					List);
+	}
+
+	return result;
+}
+
+
+/**
+ * csr_neighbor_roam_request_handoff() - Handoff to a different AP
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ *
+ * This function triggers actual switching from one AP to the new AP.
+ * It issues disassociate with reason code as Handoff and CSR as a part of
+ * handling disassoc rsp, issues reassociate to the new AP
+ *
+ * Return: none
+ */
+void csr_neighbor_roam_request_handoff(tpAniSirGlobal mac_ctx,
+		uint8_t session_id)
+{
+	struct csr_roam_info roam_info;
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	tCsrNeighborRoamBSSInfo handoff_node;
+	uint32_t roamid = 0;
+	QDF_STATUS status;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "%s session_id=%d",
+		  __func__, session_id);
+
+	if (neighbor_roam_info->neighborRoamState !=
+		eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) {
+		sme_err("Roam requested when Neighbor roam is in %s state",
+			mac_trace_get_neighbour_roam_state(
+			neighbor_roam_info->neighborRoamState));
+		return;
+	}
+
+	if (false == csr_neighbor_roam_get_handoff_ap_info(mac_ctx,
+			&handoff_node, session_id)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+		FL("failed to obtain handoff AP"));
+		return;
+	}
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("HANDOFF CANDIDATE BSSID "MAC_ADDRESS_STR),
+		  MAC_ADDR_ARRAY(handoff_node.pBssDescription->bssId));
+
+	qdf_mem_zero(&roam_info, sizeof(struct csr_roam_info));
+	csr_roam_call_callback(mac_ctx, session_id, &roam_info, roamid,
+			       eCSR_ROAM_FT_START, eCSR_ROAM_RESULT_SUCCESS);
+
+	qdf_mem_zero(&roam_info, sizeof(struct csr_roam_info));
+	csr_neighbor_roam_state_transition(mac_ctx,
+			eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING, session_id);
+
+	csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
+		handoff_node.pBssDescription->bssId,
+		eCSR_ROAM_HANDOVER_SUCCESS);
+	/* Free the profile.. Just to make sure we dont leak memory here */
+	csr_release_profile(mac_ctx,
+		&neighbor_roam_info->csrNeighborRoamProfile);
+	/*
+	 * Create the Handoff AP profile. Copy the currently connected profile
+	 * and update only the BSSID and channel number. This should happen
+	 * before issuing disconnect
+	 */
+	status = csr_roam_copy_connected_profile(mac_ctx, session_id,
+			&neighbor_roam_info->csrNeighborRoamProfile);
+	if (QDF_STATUS_SUCCESS != status) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("csr_roam_copy_connected_profile failed %d"),
+			status);
+		return;
+	}
+	qdf_mem_copy(neighbor_roam_info->csrNeighborRoamProfile.BSSIDs.bssid,
+		     handoff_node.pBssDescription->bssId, sizeof(tSirMacAddr));
+	neighbor_roam_info->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] =
+		handoff_node.pBssDescription->channelId;
+
+	sme_debug("csr_roamHandoffRequested: disassociating with current AP");
+
+	if (!QDF_IS_STATUS_SUCCESS
+		    (csr_roam_issue_disassociate_cmd
+			    (mac_ctx, session_id,
+			    eCSR_DISCONNECT_REASON_HANDOFF))) {
+		sme_warn("csr_roamHandoffRequested: fail to issue disassoc");
+		return;
+	}
+	/* notify HDD for handoff, providing the BSSID too */
+	roam_info.reasonCode = eCsrRoamReasonBetterAP;
+
+	qdf_mem_copy(roam_info.bssid.bytes,
+		     handoff_node.pBssDescription->bssId,
+		     sizeof(struct qdf_mac_addr));
+
+	csr_roam_call_callback(mac_ctx, session_id, &roam_info, 0,
+			       eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE);
+
+}
+
+
+/**
+ * csr_neighbor_roam_get_handoff_ap_info - Identifies the best AP for roaming
+ *
+ * @pMac:        mac context
+ * @session_id:     Session Id
+ * @hand_off_node:    AP node that is the handoff candidate returned
+ *
+ * This function returns the best possible AP for handoff. For 11R case, it
+ * returns the 1st entry from pre-auth done list. For non-11r case, it returns
+ * the 1st entry from roamable AP list
+ *
+ * Return: true if able find handoff AP, false otherwise
+ */
+
+bool csr_neighbor_roam_get_handoff_ap_info(tpAniSirGlobal pMac,
+			tpCsrNeighborRoamBSSInfo hand_off_node,
+			uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo ngbr_roam_info =
+		&pMac->roam.neighborRoamInfo[session_id];
+	tpCsrNeighborRoamBSSInfo bss_node = NULL;
+
+	if (NULL == hand_off_node) {
+		QDF_ASSERT(NULL != hand_off_node);
+		return false;
+	}
+	if (ngbr_roam_info->is11rAssoc) {
+		/* Always the BSS info in the head is the handoff candidate */
+		bss_node = csr_neighbor_roam_next_roamable_ap(
+			pMac,
+			&ngbr_roam_info->FTRoamInfo.preAuthDoneList,
+			NULL);
+		sme_debug("Number of Handoff candidates: %d",
+			csr_ll_count(&
+				ngbr_roam_info->FTRoamInfo.preAuthDoneList));
+	} else
+#ifdef FEATURE_WLAN_ESE
+	if (ngbr_roam_info->isESEAssoc) {
+		/* Always the BSS info in the head is the handoff candidate */
+		bss_node =
+			csr_neighbor_roam_next_roamable_ap(pMac,
+				&ngbr_roam_info->FTRoamInfo.preAuthDoneList,
+				NULL);
+		sme_debug("Number of Handoff candidates: %d",
+			csr_ll_count(&ngbr_roam_info->FTRoamInfo.
+			preAuthDoneList));
+	} else
+#endif
+	if (csr_roam_is_fast_roam_enabled(pMac, session_id)) {
+		/* Always the BSS info in the head is the handoff candidate */
+		bss_node =
+			csr_neighbor_roam_next_roamable_ap(pMac,
+			&ngbr_roam_info->FTRoamInfo.preAuthDoneList,
+			NULL);
+		sme_debug("Number of Handoff candidates: %d",
+			csr_ll_count(
+				&ngbr_roam_info->FTRoamInfo.preAuthDoneList));
+	} else {
+		bss_node =
+			csr_neighbor_roam_next_roamable_ap(pMac,
+				&ngbr_roam_info->roamableAPList,
+				NULL);
+		sme_debug("Number of Handoff candidates: %d",
+			csr_ll_count(&ngbr_roam_info->roamableAPList));
+	}
+	if (NULL == bss_node)
+		return false;
+	qdf_mem_copy(hand_off_node, bss_node, sizeof(tCsrNeighborRoamBSSInfo));
+	return true;
+}
+
+/**
+ * csr_neighbor_roam_is_handoff_in_progress()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ *
+ * This function returns whether handoff is in progress or not based on
+ * the current neighbor roam state
+ *
+ * Return: true if reassoc in progress, false otherwise
+ */
+bool csr_neighbor_roam_is_handoff_in_progress(tpAniSirGlobal pMac,
+		uint8_t sessionId)
+{
+	if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING ==
+	    pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)
+		return true;
+
+	return false;
+}
+
+/**
+ * csr_neighbor_roam_free_neighbor_roam_bss_node()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @neighborRoamBSSNode: Neighbor Roam BSS Node to be freed
+ *
+ * This function frees all the internal pointers CSR NeighborRoam BSS Info
+ * and also frees the node itself
+ *
+ * Return: None
+ */
+void csr_neighbor_roam_free_neighbor_roam_bss_node(tpAniSirGlobal pMac,
+						   tpCsrNeighborRoamBSSInfo
+						   neighborRoamBSSNode)
+{
+	if (neighborRoamBSSNode) {
+		if (neighborRoamBSSNode->pBssDescription) {
+			qdf_mem_free(neighborRoamBSSNode->pBssDescription);
+			neighborRoamBSSNode->pBssDescription = NULL;
+		}
+		qdf_mem_free(neighborRoamBSSNode);
+		neighborRoamBSSNode = NULL;
+	}
+}
+
diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h
new file mode 100644
index 0000000..3ab6bac
--- /dev/null
+++ b/core/sme/src/csr/csr_inside_api.h
@@ -0,0 +1,1147 @@
+/*
+ * Copyright (c) 2011-2018 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: csr_inside_api.h
+ *
+ * Define interface only used by CSR.
+ */
+#ifndef CSR_INSIDE_API_H__
+#define CSR_INSIDE_API_H__
+
+#include "csr_support.h"
+#include "sme_inside.h"
+#include "cds_reg_service.h"
+#include "wlan_objmgr_vdev_obj.h"
+
+#define CSR_PASSIVE_MAX_CHANNEL_TIME   110
+#define CSR_ACTIVE_MAX_CHANNEL_TIME    40
+#define CSR_PASSIVE_MAX_CHANNEL_TIME_CONC   110
+#define CSR_PASSIVE_MIN_CHANNEL_TIME_CONC   60
+
+#define CSR_ACTIVE_MAX_CHANNEL_TIME_CONC    27
+#define CSR_ACTIVE_MIN_CHANNEL_TIME_CONC    20
+
+#define CSR_REST_TIME_CONC                  100
+#define CSR_MIN_REST_TIME_CONC              50
+#define CSR_IDLE_TIME_CONC                  25
+
+#define CSR_MAX_NUM_SUPPORTED_CHANNELS 55
+
+#define CSR_MAX_2_4_GHZ_SUPPORTED_CHANNELS 14
+
+#define CSR_MAX_BSS_SUPPORT            512
+
+/* This number minus 1 means the number of times a channel is scanned before
+ * a BSS is remvoed from
+ */
+/* cache scan result */
+#define CSR_AGING_COUNT     3
+/* 5 seconds */
+#define CSR_SCAN_GET_RESULT_INTERVAL    (5 * QDF_MC_TIMER_TO_SEC_UNIT)
+/* 60 seconds */
+#define CSR_MIC_ERROR_TIMEOUT  (60 * QDF_MC_TIMER_TO_SEC_UNIT)
+/* 60 seconds */
+#define CSR_TKIP_COUNTER_MEASURE_TIMEOUT  (60 * QDF_MC_TIMER_TO_SEC_UNIT)
+
+/* the following defines are NOT used by palTimer */
+#define CSR_JOIN_FAILURE_TIMEOUT_DEFAULT (3000)
+#define CSR_JOIN_FAILURE_TIMEOUT_MIN   (1000)   /* minimal value */
+/* These are going against the signed RSSI (int8_t) so it is between -+127 */
+#define CSR_BEST_RSSI_VALUE         (-30)       /* RSSI >= this is in CAT4 */
+#define CSR_DEFAULT_RSSI_DB_GAP     30  /* every 30 dbm for one category */
+#define CSR_BSS_CAP_VALUE_NONE  0       /* not much value */
+#define CSR_BSS_CAP_VALUE_HT    1
+#define CSR_BSS_CAP_VALUE_VHT    2
+#define CSR_BSS_CAP_VALUE_WMM   1
+#define CSR_BSS_CAP_VALUE_UAPSD 1
+#define CSR_BSS_CAP_VALUE_5GHZ  2
+
+#define CSR_ROAMING_DFS_CHANNEL_DISABLED           (0)
+#define CSR_ROAMING_DFS_CHANNEL_ENABLED_NORMAL     (1)
+#define CSR_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE     (2)
+
+#ifdef QCA_WIFI_3_0_EMU
+#define CSR_ACTIVE_SCAN_LIST_CMD_TIMEOUT (1000*30*20)
+#else
+#define CSR_ACTIVE_SCAN_LIST_CMD_TIMEOUT (1000*30)
+#endif
+/* ***************************************************************************
+ * The MAX BSSID Count should be lower than the command timeout value and it
+ * can be of a fraction of 1/3 to 1/2 of the total command timeout value.
+ * ***************************************************************************/
+#define CSR_MAX_BSSID_COUNT     (SME_ACTIVE_LIST_CMD_TIMEOUT_VALUE/3000) - 2
+#define CSR_CUSTOM_CONC_GO_BI    100
+extern uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE];
+bool csr_is_supported_channel(tpAniSirGlobal pMac, uint8_t channelId);
+
+enum csr_scancomplete_nextcommand {
+	eCsrNextScanNothing,
+	eCsrNexteScanForSsidSuccess,
+	eCsrNexteScanForSsidFailure,
+	eCsrNextCheckAllowConc,
+};
+
+enum csr_roamcomplete_result {
+	eCsrJoinSuccess,
+	eCsrJoinFailure,
+	eCsrReassocSuccess,
+	eCsrReassocFailure,
+	eCsrNothingToJoin,
+	eCsrStartBssSuccess,
+	eCsrStartBssFailure,
+	eCsrSilentlyStopRoaming,
+	eCsrSilentlyStopRoamingSaveState,
+	eCsrJoinFailureDueToConcurrency,
+	eCsrStopBssSuccess,
+	eCsrStopBssFailure,
+};
+
+struct tag_scanreq_param {
+	uint8_t bReturnAfter1stMatch;
+	uint8_t fUniqueResult;
+	uint8_t freshScan;
+	uint8_t hiddenSsid;
+	uint8_t reserved;
+};
+
+struct tag_csrscan_result {
+	tListElem Link;
+	/* This BSS is removed when it reaches 0 or less */
+	int32_t AgingCount;
+	/* The bigger the number, the better the BSS.
+	 * This value override capValue
+	 */
+	uint32_t preferValue;
+	/* The biggger the better. This value is in use only if we have
+	 * equal preferValue
+	 */
+	uint32_t capValue;
+	/* This member must be the last in the structure because the end of
+	 * tSirBssDescription (inside) is an
+	 * array with nonknown size at this time
+	 */
+	/* Preferred Encryption type that matched with profile. */
+	eCsrEncryptionType ucEncryptionType;
+	eCsrEncryptionType mcEncryptionType;
+	/* Preferred auth type that matched with the profile. */
+	eCsrAuthType authType;
+	int  bss_score;
+
+	tCsrScanResultInfo Result;
+	/*
+	 * WARNING - Do not add any element here
+	 * This member Result must be the last in the structure because the end
+	 * of tSirBssDescription (inside) is an array with nonknown size at
+	 * this time.
+	 */
+};
+
+struct scan_result_list {
+	tDblLinkList List;
+	tListElem *pCurEntry;
+};
+
+#define CSR_IS_ROAM_REASON(pCmd, reason) \
+					((reason) == (pCmd)->roamCmd.roamReason)
+#define CSR_IS_BETTER_PREFER_VALUE(v1, v2)   ((v1) > (v2))
+#define CSR_IS_EQUAL_PREFER_VALUE(v1, v2)   ((v1) == (v2))
+#define CSR_IS_BETTER_CAP_VALUE(v1, v2)     ((v1) > (v2))
+#define CSR_IS_EQUAL_CAP_VALUE(v1, v2)  ((v1) == (v2))
+#define CSR_IS_BETTER_RSSI(v1, v2)   ((v1) > (v2))
+#define CSR_IS_ENC_TYPE_STATIC(encType) ((eCSR_ENCRYPT_TYPE_NONE == (encType)) \
+			|| (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == (encType)) || \
+			(eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == (encType)))
+
+#define CSR_IS_AUTH_TYPE_FILS(auth_type) \
+		((eCSR_AUTH_TYPE_FILS_SHA256 == auth_type) || \
+		(eCSR_AUTH_TYPE_FILS_SHA384 == auth_type) || \
+		(eCSR_AUTH_TYPE_FT_FILS_SHA256 == auth_type) || \
+		(eCSR_AUTH_TYPE_FT_FILS_SHA384 == auth_type))
+#define CSR_IS_WAIT_FOR_KEY(pMac, sessionId) \
+		 (CSR_IS_ROAM_JOINED(pMac, sessionId) && \
+		  CSR_IS_ROAM_SUBSTATE_WAITFORKEY(pMac, sessionId))
+/* WIFI has a test case for not using HT rates with TKIP as encryption */
+/* We may need to add WEP but for now, TKIP only. */
+
+#define CSR_IS_11n_ALLOWED(encType) ((eCSR_ENCRYPT_TYPE_TKIP != (encType)) && \
+			(eCSR_ENCRYPT_TYPE_WEP40_STATICKEY != (encType)) && \
+			(eCSR_ENCRYPT_TYPE_WEP104_STATICKEY != (encType)) && \
+				     (eCSR_ENCRYPT_TYPE_WEP40 != (encType)) && \
+				       (eCSR_ENCRYPT_TYPE_WEP104 != (encType)))
+
+#define CSR_IS_DISCONNECT_COMMAND(pCommand) ((eSmeCommandRoam == \
+		(pCommand)->command) && \
+		((eCsrForcedDisassoc == (pCommand)->u.roamCmd.roamReason) || \
+		(eCsrForcedDeauth == (pCommand)->u.roamCmd.roamReason) || \
+					(eCsrSmeIssuedDisassocForHandoff == \
+					(pCommand)->u.roamCmd.roamReason) || \
+					(eCsrForcedDisassocMICFailure == \
+					(pCommand)->u.roamCmd.roamReason)))
+
+enum csr_roam_state csr_roam_state_change(tpAniSirGlobal pMac,
+					  enum csr_roam_state NewRoamState,
+					  uint8_t sessionId);
+void csr_roaming_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf);
+void csr_roam_joined_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf);
+void csr_scan_callback(struct wlan_objmgr_vdev *vdev,
+				struct scan_event *event, void *arg);
+void csr_release_command_roam(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+void csr_release_command_wm_status_change(tpAniSirGlobal pMac,
+					  tSmeCmd *pCommand);
+void csr_release_roc_req_cmd(tpAniSirGlobal mac_ctx,
+			     tSmeCmd *pCommand);
+
+QDF_STATUS csr_roam_save_connected_bss_desc(tpAniSirGlobal pMac,
+					    uint32_t sessionId,
+					    tSirBssDescription *pBssDesc);
+bool csr_is_network_type_equal(tSirBssDescription *pSirBssDesc1,
+			       tSirBssDescription *pSirBssDesc2);
+/*
+ * Prepare a filter base on a profile for parsing the scan results.
+ * Upon successful return, caller MUST call csr_free_scan_filter on
+ * pScanFilter when it is done with the filter.
+ */
+QDF_STATUS
+csr_roam_prepare_filter_from_profile(tpAniSirGlobal pMac,
+				     struct csr_roam_profile *pProfile,
+				     tCsrScanResultFilter *pScanFilter);
+
+QDF_STATUS csr_roam_copy_profile(tpAniSirGlobal pMac,
+				 struct csr_roam_profile *pDstProfile,
+				 struct csr_roam_profile *pSrcProfile);
+QDF_STATUS csr_roam_start(tpAniSirGlobal pMac);
+void csr_roam_stop(tpAniSirGlobal pMac, uint32_t sessionId);
+void csr_roam_startMICFailureTimer(tpAniSirGlobal pMac);
+void csr_roam_stopMICFailureTimer(tpAniSirGlobal pMac);
+void csr_roam_startTKIPCounterMeasureTimer(tpAniSirGlobal pMac);
+void csr_roam_stopTKIPCounterMeasureTimer(tpAniSirGlobal pMac);
+
+QDF_STATUS csr_scan_open(tpAniSirGlobal pMac);
+QDF_STATUS csr_scan_close(tpAniSirGlobal pMac);
+bool csr_scan_append_bss_description(tpAniSirGlobal pMac,
+				     tSirBssDescription *pSirBssDescription);
+QDF_STATUS csr_scan_for_ssid(tpAniSirGlobal pMac, uint32_t sessionId,
+			     struct csr_roam_profile *pProfile, uint32_t roamId,
+			     bool notify);
+/**
+ * csr_scan_abort_mac_scan() - Generic API to abort scan request
+ * @pMac: pointer to pmac
+ * @vdev_id: pdev id
+ * @scan_id: scan id
+ *
+ * Generic API to abort scans
+ *
+ * Return: 0 for success, non zero for failure
+ */
+QDF_STATUS csr_scan_abort_mac_scan(tpAniSirGlobal pMac, uint32_t vdev_id,
+				   uint32_t scan_id);
+QDF_STATUS csr_remove_nonscan_cmd_from_pending_list(tpAniSirGlobal pMac,
+			uint8_t sessionId, eSmeCommandType commandType);
+
+/* If fForce is true we will save the new String that is learn't. */
+/* Typically it will be true in case of Join or user initiated ioctl */
+bool csr_learn_11dcountry_information(tpAniSirGlobal pMac,
+				   tSirBssDescription *pSirBssDesc,
+				   tDot11fBeaconIEs *pIes, bool fForce);
+void csr_apply_country_information(tpAniSirGlobal pMac);
+void csr_set_cfg_scan_control_list(tpAniSirGlobal pMac, uint8_t *countryCode,
+				   struct csr_channel *pChannelList);
+void csr_free_scan_result_entry(tpAniSirGlobal pMac, struct tag_csrscan_result
+				*pResult);
+
+QDF_STATUS csr_roam_call_callback(tpAniSirGlobal pMac, uint32_t sessionId,
+				  struct csr_roam_info *roam_info,
+				  uint32_t roamId,
+				  eRoamCmdStatus u1, eCsrRoamResult u2);
+QDF_STATUS csr_roam_issue_connect(tpAniSirGlobal pMac, uint32_t sessionId,
+				  struct csr_roam_profile *pProfile,
+				  tScanResultHandle hBSSList,
+				  enum csr_roam_reason reason, uint32_t roamId,
+				  bool fImediate, bool fClearScan);
+QDF_STATUS csr_roam_issue_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
+				  struct csr_roam_profile *pProfile,
+				 tCsrRoamModifyProfileFields *pModProfileFields,
+				  enum csr_roam_reason reason, uint32_t roamId,
+				  bool fImediate);
+void csr_roam_complete(tpAniSirGlobal pMac, enum csr_roamcomplete_result Result,
+		       void *Context, uint8_t session_id);
+QDF_STATUS csr_roam_issue_set_context_req(tpAniSirGlobal pMac,
+					uint32_t sessionId,
+					  eCsrEncryptionType EncryptType,
+					  tSirBssDescription *pBssDescription,
+					  tSirMacAddr *bssId, bool addKey,
+					  bool fUnicast,
+					  tAniKeyDirection aniKeyDirection,
+					  uint8_t keyId, uint16_t keyLength,
+					  uint8_t *pKey, uint8_t paeRole);
+QDF_STATUS csr_roam_process_disassoc_deauth(tpAniSirGlobal pMac,
+						tSmeCmd *pCommand,
+					    bool fDisassoc, bool fMICFailure);
+QDF_STATUS csr_roam_save_connected_information(tpAniSirGlobal pMac,
+					      uint32_t sessionId,
+					      struct csr_roam_profile *pProfile,
+					      tSirBssDescription *pSirBssDesc,
+					      tDot11fBeaconIEs *pIes);
+void csr_roam_check_for_link_status_change(tpAniSirGlobal pMac,
+					tSirSmeRsp *pSirMsg);
+
+#ifndef QCA_SUPPORT_CP_STATS
+void csr_roam_stats_rsp_processor(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg);
+#else
+static inline void csr_roam_stats_rsp_processor(tpAniSirGlobal pMac,
+						tSirSmeRsp *pSirMsg) {}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+QDF_STATUS csr_roam_issue_start_bss(tpAniSirGlobal pMac, uint32_t sessionId,
+				    struct csr_roamstart_bssparams *pParam,
+				    struct csr_roam_profile *pProfile,
+				    tSirBssDescription *pBssDesc,
+					uint32_t roamId);
+QDF_STATUS csr_roam_issue_stop_bss(tpAniSirGlobal pMac, uint32_t sessionId,
+				   enum csr_roam_substate NewSubstate);
+bool csr_is_same_profile(tpAniSirGlobal pMac, tCsrRoamConnectedProfile
+			*pProfile1, struct csr_roam_profile *pProfile2);
+bool csr_is_roam_command_waiting_for_session(tpAniSirGlobal pMac,
+					uint32_t sessionId);
+eRoamCmdStatus csr_get_roam_complete_status(tpAniSirGlobal pMac,
+					    uint32_t sessionId);
+/* pBand can be NULL if caller doesn't need to get it */
+QDF_STATUS csr_roam_issue_disassociate_cmd(tpAniSirGlobal pMac,
+					uint32_t sessionId,
+					   eCsrRoamDisconnectReason reason);
+QDF_STATUS csr_roam_disconnect_internal(tpAniSirGlobal pMac, uint32_t sessionId,
+					eCsrRoamDisconnectReason reason);
+/* pCommand may be NULL */
+void csr_roam_remove_duplicate_command(tpAniSirGlobal pMac, uint32_t sessionId,
+				       tSmeCmd *pCommand,
+				       enum csr_roam_reason eRoamReason);
+
+QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+				 tSirBssDescription *pBssDescription,
+				 struct csr_roam_profile *pProfile,
+				 tDot11fBeaconIEs *pIes, uint16_t messageType);
+QDF_STATUS csr_send_mb_disassoc_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+					tSirMacAddr bssId, uint16_t reasonCode);
+QDF_STATUS csr_send_mb_deauth_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+				      tSirMacAddr bssId, uint16_t reasonCode);
+QDF_STATUS csr_send_mb_disassoc_cnf_msg(tpAniSirGlobal pMac,
+					tpSirSmeDisassocInd pDisassocInd);
+QDF_STATUS csr_send_mb_deauth_cnf_msg(tpAniSirGlobal pMac,
+				      tpSirSmeDeauthInd pDeauthInd);
+QDF_STATUS csr_send_assoc_cnf_msg(tpAniSirGlobal pMac, tpSirSmeAssocInd
+				pAssocInd,
+				  QDF_STATUS status);
+QDF_STATUS csr_send_assoc_ind_to_upper_layer_cnf_msg(tpAniSirGlobal pMac,
+						     tpSirSmeAssocInd pAssocInd,
+						     QDF_STATUS Halstatus,
+						     uint8_t sessionId);
+QDF_STATUS csr_send_mb_start_bss_req_msg(tpAniSirGlobal pMac,
+					uint32_t sessionId,
+					 eCsrRoamBssType bssType,
+					 struct csr_roamstart_bssparams *pParam,
+					 tSirBssDescription *pBssDesc);
+QDF_STATUS csr_send_mb_stop_bss_req_msg(tpAniSirGlobal pMac,
+					uint32_t sessionId);
+
+/* Caller should put the BSS' ssid to fiedl bssSsid when
+ * comparing SSID for a BSS.
+ */
+bool csr_is_ssid_match(tpAniSirGlobal pMac, uint8_t *ssid1, uint8_t ssid1Len,
+		       uint8_t *bssSsid, uint8_t bssSsidLen,
+			bool fSsidRequired);
+bool csr_is_phy_mode_match(tpAniSirGlobal pMac, uint32_t phyMode,
+			   tSirBssDescription *pSirBssDesc,
+			   struct csr_roam_profile *pProfile,
+			   enum csr_cfgdot11mode *pReturnCfgDot11Mode,
+			   tDot11fBeaconIEs *pIes);
+bool csr_roam_is_channel_valid(tpAniSirGlobal pMac, uint8_t channel);
+
+/* pNumChan is a caller allocated space with the sizeof pChannels */
+QDF_STATUS csr_get_cfg_valid_channels(tpAniSirGlobal pMac, uint8_t *pChannels,
+				      uint32_t *pNumChan);
+int8_t csr_get_cfg_max_tx_power(tpAniSirGlobal pMac, uint8_t channel);
+
+/* To free the last roaming profile */
+void csr_free_roam_profile(tpAniSirGlobal pMac, uint32_t sessionId);
+void csr_free_connect_bss_desc(tpAniSirGlobal pMac, uint32_t sessionId);
+QDF_STATUS csr_move_bss_to_head_from_bssid(tpAniSirGlobal pMac,
+					   struct qdf_mac_addr *bssid,
+					   tScanResultHandle hScanResult);
+
+/* to free memory allocated inside the profile structure */
+void csr_release_profile(tpAniSirGlobal pMac,
+			 struct csr_roam_profile *pProfile);
+
+/* To free memory allocated inside scanFilter */
+void csr_free_scan_filter(tpAniSirGlobal pMac, tCsrScanResultFilter
+			*pScanFilter);
+
+enum csr_cfgdot11mode
+csr_get_cfg_dot11_mode_from_csr_phy_mode(struct csr_roam_profile *pProfile,
+					 eCsrPhyMode phyMode,
+					 bool fProprietary);
+
+uint32_t csr_translate_to_wni_cfg_dot11_mode(tpAniSirGlobal pMac,
+				    enum csr_cfgdot11mode csrDot11Mode);
+void csr_save_channel_power_for_band(tpAniSirGlobal pMac, bool fPopulate5GBand);
+void csr_apply_channel_power_info_to_fw(tpAniSirGlobal pMac,
+					struct csr_channel *pChannelList,
+					uint8_t *countryCode);
+void csr_apply_power2_current(tpAniSirGlobal pMac);
+void csr_assign_rssi_for_category(tpAniSirGlobal pMac, int8_t bestApRssi,
+				  uint8_t catOffset);
+QDF_STATUS csr_roam_start_roaming(tpAniSirGlobal pMac, uint32_t sessionId,
+				  enum csr_roaming_reason roamingReason);
+/* return a bool to indicate whether roaming completed or continue. */
+bool csr_roam_complete_roaming(tpAniSirGlobal pMac, uint32_t sessionId,
+			       bool fForce, eCsrRoamResult roamResult);
+void csr_roam_completion(tpAniSirGlobal pMac, uint32_t sessionId,
+			 struct csr_roam_info *roam_info, tSmeCmd *pCommand,
+			 eCsrRoamResult roamResult, bool fSuccess);
+void csr_roam_cancel_roaming(tpAniSirGlobal pMac, uint32_t sessionId);
+void csr_apply_channel_power_info_wrapper(tpAniSirGlobal pMac);
+void csr_reset_pmkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId);
+#ifdef FEATURE_WLAN_WAPI
+void csr_reset_bkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId);
+#endif /* FEATURE_WLAN_WAPI */
+QDF_STATUS csr_save_to_channel_power2_g_5_g(tpAniSirGlobal pMac,
+					uint32_t tableSize, tSirMacChanInfo
+					*channelTable);
+QDF_STATUS csr_roam_set_key(tpAniSirGlobal pMac, uint32_t sessionId,
+			    tCsrRoamSetKey *pSetKey, uint32_t roamId);
+QDF_STATUS csr_roam_open_session(tpAniSirGlobal pMac,
+				 struct sme_session_params *session_param);
+QDF_STATUS csr_roam_close_session(tpAniSirGlobal mac_ctx,
+				  uint32_t session_id, bool sync);
+void csr_cleanup_session(tpAniSirGlobal pMac, uint32_t sessionId);
+QDF_STATUS csr_roam_get_session_id_from_bssid(tpAniSirGlobal pMac,
+						struct qdf_mac_addr *bssid,
+					      uint32_t *pSessionId);
+enum csr_cfgdot11mode csr_find_best_phy_mode(tpAniSirGlobal pMac,
+							uint32_t phyMode);
+
+/*
+ * csr_scan_get_result() -
+ * Return scan results.
+ *
+ * pFilter - If pFilter is NULL, all cached results are returned
+ * phResult - an object for the result.
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_scan_get_result(tpAniSirGlobal pMac, tCsrScanResultFilter
+				*pFilter, tScanResultHandle *phResult);
+
+/**
+ * csr_scan_get_result_for_bssid - gets the scan result from scan cache for the
+ *      bssid specified
+ * @mac_ctx: mac context
+ * @bssid: bssid to get the scan result for
+ * @res: pointer to tCsrScanResultInfo
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS csr_scan_get_result_for_bssid(tpAniSirGlobal mac_ctx,
+					 struct qdf_mac_addr *bssid,
+					 tCsrScanResultInfo *res);
+
+/*
+ * csr_scan_flush_result() -
+ * Clear scan results.
+ *
+ * pMac - pMac global pointer
+ * sessionId - Session Identifier
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_scan_flush_result(tpAniSirGlobal mac_ctx);
+/*
+ * csr_scan_filter_results() -
+ *  Filter scan results based on valid channel list.
+ *
+ * pMac - Pointer to Global MAC structure
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_scan_filter_results(tpAniSirGlobal pMac);
+
+QDF_STATUS csr_scan_flush_selective_result(tpAniSirGlobal pMac, bool flushP2P);
+
+/*
+ * csr_scan_result_get_first
+ * Returns the first element of scan result.
+ *
+ * hScanResult - returned from csr_scan_get_result
+ * tCsrScanResultInfo * - NULL if no result
+ */
+tCsrScanResultInfo *csr_scan_result_get_first(tpAniSirGlobal pMac,
+					      tScanResultHandle hScanResult);
+/*
+ * csr_scan_result_get_next
+ * Returns the next element of scan result. It can be called without calling
+ * csr_scan_result_get_first first
+ *
+ * hScanResult - returned from csr_scan_get_result
+ * Return Null if no result or reach the end
+ */
+tCsrScanResultInfo *csr_scan_result_get_next(tpAniSirGlobal pMac,
+					     tScanResultHandle hScanResult);
+
+/*
+ * csr_get_country_code() -
+ * This function is to get the country code current being used
+ * pBuf - Caller allocated buffer with at least 3 bytes, upon success return,
+ * this has the country code
+ * pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon
+ * success return, this contains the length of the data in pBuf
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_get_country_code(tpAniSirGlobal pMac, uint8_t *pBuf,
+				uint8_t *pbLen);
+
+/*
+ * csr_get_regulatory_domain_for_country() -
+ * This function is to get the regulatory domain for a country.
+ * This function must be called after CFG is downloaded and all the band/mode
+ * setting already passed into CSR.
+ *
+ * pCountry - Caller allocated buffer with at least 3 bytes specifying the
+ * country code
+ * pDomainId - Caller allocated buffer to get the return domain ID upon
+ * success return. Can be NULL.
+ * source - the source of country information.
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_get_regulatory_domain_for_country(tpAniSirGlobal pMac,
+						 uint8_t *pCountry,
+						 v_REGDOMAIN_t *pDomainId,
+						 enum country_src source);
+
+/* some support functions */
+bool csr_is11d_supported(tpAniSirGlobal pMac);
+bool csr_is11h_supported(tpAniSirGlobal pMac);
+bool csr_is11e_supported(tpAniSirGlobal pMac);
+bool csr_is_wmm_supported(tpAniSirGlobal pMac);
+bool csr_is_mcc_supported(tpAniSirGlobal pMac);
+
+/* Return SUCCESS is the command is queued, failed */
+QDF_STATUS csr_queue_sme_command(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+				 bool fHighPriority);
+tSmeCmd *csr_get_command_buffer(tpAniSirGlobal pMac);
+void csr_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+void csr_release_command_buffer(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+void csr_scan_flush_bss_entry(tpAniSirGlobal pMac,
+			      tpSmeCsaOffloadInd pCsaOffloadInd);
+
+#ifdef FEATURE_WLAN_WAPI
+bool csr_is_profile_wapi(struct csr_roam_profile *pProfile);
+#endif /* FEATURE_WLAN_WAPI */
+
+void csr_get_vdev_type_nss(tpAniSirGlobal mac_ctx,
+		enum QDF_OPMODE dev_mode,
+		uint8_t *nss_2g, uint8_t *nss_5g);
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+
+/* Security */
+#define WLAN_SECURITY_EVENT_REMOVE_KEY_REQ  5
+#define WLAN_SECURITY_EVENT_REMOVE_KEY_RSP  6
+#define WLAN_SECURITY_EVENT_PMKID_CANDIDATE_FOUND  7
+#define WLAN_SECURITY_EVENT_PMKID_UPDATE    8
+#define WLAN_SECURITY_EVENT_MIC_ERROR       9
+#define WLAN_SECURITY_EVENT_SET_UNICAST_REQ  10
+#define WLAN_SECURITY_EVENT_SET_UNICAST_RSP  11
+#define WLAN_SECURITY_EVENT_SET_BCAST_REQ    12
+#define WLAN_SECURITY_EVENT_SET_BCAST_RSP    13
+
+#define NO_MATCH    0
+#define MATCH       1
+
+#define WLAN_SECURITY_STATUS_SUCCESS        0
+#define WLAN_SECURITY_STATUS_FAILURE        1
+
+/* Scan */
+#define WLAN_SCAN_EVENT_ACTIVE_SCAN_REQ     1
+#define WLAN_SCAN_EVENT_ACTIVE_SCAN_RSP     2
+#define WLAN_SCAN_EVENT_PASSIVE_SCAN_REQ    3
+#define WLAN_SCAN_EVENT_PASSIVE_SCAN_RSP    4
+#define WLAN_SCAN_EVENT_HO_SCAN_REQ         5
+#define WLAN_SCAN_EVENT_HO_SCAN_RSP         6
+
+#define WLAN_SCAN_STATUS_SUCCESS        0
+#define WLAN_SCAN_STATUS_FAILURE        1
+#define WLAN_SCAN_STATUS_ABORT          2
+
+/* Ibss */
+#define WLAN_IBSS_EVENT_START_IBSS_REQ      0
+#define WLAN_IBSS_EVENT_START_IBSS_RSP      1
+#define WLAN_IBSS_EVENT_JOIN_IBSS_REQ       2
+#define WLAN_IBSS_EVENT_JOIN_IBSS_RSP       3
+#define WLAN_IBSS_EVENT_COALESCING          4
+#define WLAN_IBSS_EVENT_PEER_JOIN           5
+#define WLAN_IBSS_EVENT_PEER_LEAVE          6
+#define WLAN_IBSS_EVENT_STOP_REQ            7
+#define WLAN_IBSS_EVENT_STOP_RSP            8
+
+#define AUTO_PICK       0
+#define SPECIFIED       1
+
+#define WLAN_IBSS_STATUS_SUCCESS        0
+#define WLAN_IBSS_STATUS_FAILURE        1
+
+/* 11d */
+#define WLAN_80211D_EVENT_COUNTRY_SET   0
+#define WLAN_80211D_EVENT_RESET         1
+
+#define WLAN_80211D_DISABLED         0
+#define WLAN_80211D_SUPPORT_MULTI_DOMAIN     1
+#define WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN     2
+
+/**
+ * diag_auth_type_from_csr_type() - to convert CSR auth type to DIAG auth type
+ * @authtype: CSR auth type
+ *
+ * DIAG tool understands its own ENUMs, so this API can be used to convert
+ * CSR defined auth type ENUMs to DIAG defined auth type ENUMs
+ *
+ *
+ * Return: DIAG auth type
+ */
+enum mgmt_auth_type diag_auth_type_from_csr_type(eCsrAuthType authtype);
+/**
+ * diag_enc_type_from_csr_type() - to convert CSR encr type to DIAG encr type
+ * @enctype: CSR encryption type
+ *
+ * DIAG tool understands its own ENUMs, so this API can be used to convert
+ * CSR defined encr type ENUMs to DIAG defined encr type ENUMs
+ *
+ * Return: DIAG encryption type
+ */
+enum mgmt_encrypt_type diag_enc_type_from_csr_type(eCsrEncryptionType enctype);
+/**
+ * diag_dot11_mode_from_csr_type() - to convert CSR .11 mode to DIAG .11 mode
+ * @dot11mode: CSR 80211 mode
+ *
+ * DIAG tool understands its own ENUMs, so this API can be used to convert
+ * CSR defined 80211 mode ENUMs to DIAG defined 80211 mode ENUMs
+ *
+ * Return: DIAG 80211mode
+ */
+enum mgmt_dot11_mode
+diag_dot11_mode_from_csr_type(enum csr_cfgdot11mode dot11mode);
+/**
+ * diag_ch_width_from_csr_type() - to convert CSR ch width to DIAG ch width
+ * @ch_width: CSR channel width
+ *
+ * DIAG tool understands its own ENUMs, so this API can be used to convert
+ * CSR defined ch width ENUMs to DIAG defined ch width ENUMs
+ *
+ * Return: DIAG channel width
+ */
+enum mgmt_ch_width diag_ch_width_from_csr_type(enum phy_ch_width ch_width);
+/**
+ * diag_persona_from_csr_type() - to convert QDF persona to DIAG persona
+ * @persona: QDF persona
+ *
+ * DIAG tool understands its own ENUMs, so this API can be used to convert
+ * QDF defined persona type ENUMs to DIAG defined persona type ENUMs
+ *
+ * Return: DIAG persona
+ */
+enum mgmt_bss_type diag_persona_from_csr_type(enum QDF_OPMODE persona);
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+/*
+ * csr_scan_result_purge() -
+ * Remove all items(tCsrScanResult) in the list and free memory for each item
+ * hScanResult - returned from csr_scan_get_result. hScanResult is considered
+ * gone by calling this function and even before this function reutrns.
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_scan_result_purge(tpAniSirGlobal pMac,
+				 tScanResultHandle hScanResult);
+
+/* /////////////////////////////////////////Common Scan ends */
+
+/*
+ * csr_roam_connect() -
+ * To inititiate an association
+ * pProfile - can be NULL to join to any open ones
+ * pRoamId - to get back the request ID
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_roam_connect(tpAniSirGlobal pMac, uint32_t sessionId,
+			    struct csr_roam_profile *pProfile,
+			    uint32_t *pRoamId);
+
+/*
+ * csr_roam_reassoc() -
+ * To inititiate a re-association
+ * pProfile - can be NULL to join the currently connected AP. In that
+ * case modProfileFields should carry the modified field(s) which could trigger
+ * reassoc
+ * modProfileFields - fields which are part of tCsrRoamConnectedProfile
+ * that might need modification dynamically once STA is up & running and this
+ * could trigger a reassoc
+ * pRoamId - to get back the request ID
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_roam_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
+			    struct csr_roam_profile *pProfile,
+			    tCsrRoamModifyProfileFields modProfileFields,
+			    uint32_t *pRoamId);
+
+/*
+ * csr_roam_reconnect() -
+ * To disconnect and reconnect with the same profile
+ *
+ * Return QDF_STATUS. It returns fail if currently not connected
+ */
+QDF_STATUS csr_roam_reconnect(tpAniSirGlobal pMac, uint32_t sessionId);
+
+/*
+ * csr_roam_set_pmkid_cache() -
+ * return the PMKID candidate list
+ *
+ * pPMKIDCache - caller allocated buffer point to an array of tPmkidCacheInfo
+ * numItems - a variable that has the number of tPmkidCacheInfo allocated
+ * when retruning, this is either the number needed or number of items put
+ * into pPMKIDCache
+ * Return QDF_STATUS - when fail, it usually means the buffer allocated is not
+ * big enough and pNumItems has the number of tPmkidCacheInfo.
+ * \Note: pNumItems is a number of tPmkidCacheInfo, not
+ * sizeof(tPmkidCacheInfo) * something
+ */
+QDF_STATUS csr_roam_set_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
+				    tPmkidCacheInfo *pPMKIDCache,
+				   uint32_t numItems, bool update_entire_cache);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/*
+ * csr_get_pmk_info(): store PMK in pmk_cache
+ * @mac_ctx: pointer to global structure for MAC
+ * @session_id: Sme session id
+ * @pmk_cache: pointer to a structure of Pmk
+ *
+ * This API gets the PMK from the session and
+ * stores it in the pmk_cache
+ *
+ * Return: none
+ */
+void csr_get_pmk_info(tpAniSirGlobal mac_ctx, uint8_t session_id,
+		      tPmkidCacheInfo *pmk_cache);
+
+/*
+ * csr_roam_set_psk_pmk() -
+ * store PSK/PMK
+ * pMac  - pointer to global structure for MAC
+ * sessionId - Sme session id
+ * pPSK_PMK - pointer to an array of Psk/Pmk
+ * Return QDF_STATUS - usually it succeed unless sessionId is not found
+ * Note:
+ */
+QDF_STATUS csr_roam_set_psk_pmk(tpAniSirGlobal pMac, uint32_t sessionId,
+				uint8_t *pPSK_PMK, size_t pmk_len);
+
+QDF_STATUS csr_roam_set_key_mgmt_offload(tpAniSirGlobal mac_ctx,
+					 uint32_t session_id,
+					 bool roam_key_mgmt_offload_enabled,
+					 struct pmkid_mode_bits *pmkid_modes);
+#endif
+/*
+ * csr_roam_get_wpa_rsn_req_ie() -
+ * Return the WPA or RSN IE CSR passes to PE to JOIN request or START_BSS
+ * request
+ * pLen - caller allocated memory that has the length of pBuf as input.
+ * Upon returned, *pLen has the needed or IE length in pBuf.
+ * pBuf - Caller allocated memory that contain the IE field, if any, upon return
+ * Return QDF_STATUS - when fail, it usually means the buffer allocated is not
+ * big enough
+ */
+QDF_STATUS csr_roam_get_wpa_rsn_req_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				       uint32_t *pLen, uint8_t *pBuf);
+
+/*
+ * csr_roam_get_wpa_rsn_rsp_ie() -
+ * Return the WPA or RSN IE from the beacon or probe rsp if connected
+ *
+ * pLen - caller allocated memory that has the length of pBuf as input.
+ * Upon returned, *pLen has the needed or IE length in pBuf.
+ * pBuf - Caller allocated memory that contain the IE field, if any, upon return
+ * Return QDF_STATUS - when fail, it usually means the buffer allocated is not
+ * big enough
+ */
+QDF_STATUS csr_roam_get_wpa_rsn_rsp_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				       uint32_t *pLen, uint8_t *pBuf);
+
+/*
+ * csr_roam_get_num_pmkid_cache() -
+ * Return number of PMKID cache entries
+ *
+ * Return uint32_t - the number of PMKID cache entries
+ */
+uint32_t csr_roam_get_num_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId);
+
+/*
+ * csr_roam_get_pmkid_cache() -
+ * Return PMKID cache from CSR
+ *
+ * pNum - caller allocated memory that has the space of the number of pBuf
+ * tPmkidCacheInfo as input. Upon returned, *pNum has the needed or actually
+ * number in tPmkidCacheInfo.
+ * pPmkidCache - Caller allocated memory that contains PMKID cache, if any,
+ * upon return
+ * Return QDF_STATUS - when fail, it usually means the buffer allocated is
+ * not big enough
+ */
+QDF_STATUS csr_roam_get_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
+				  uint32_t *pNum, tPmkidCacheInfo *pPmkidCache);
+
+/**
+ * csr_roam_get_connect_profile() - To return the current connect profile,
+ * caller must call csr_roam_free_connect_profile after it is done and before
+ * reuse for another csr_roam_get_connect_profile call.
+ *
+ * @pMac:          pointer to global adapter context
+ * @sessionId:     session ID
+ * @pProfile:      pointer to a caller allocated structure
+ *                 tCsrRoamConnectedProfile
+ *
+ * Return: QDF_STATUS. Failure if not connected, success otherwise
+ */
+QDF_STATUS csr_roam_get_connect_profile(tpAniSirGlobal pMac, uint32_t sessionId,
+					tCsrRoamConnectedProfile *pProfile);
+
+/*
+ * csr_roam_get_connect_state()
+ *  To return the current connect state of Roaming
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_roam_get_connect_state(tpAniSirGlobal pMac, uint32_t sessionId,
+				      eCsrConnectState *pState);
+
+void csr_roam_free_connect_profile(tCsrRoamConnectedProfile *profile);
+
+/*
+ * csr_apply_channel_and_power_list() -
+ *  HDD calls this function to set the WNI_CFG_VALID_CHANNEL_LIST base on the
+ * band/mode settings. This function must be called after CFG is downloaded
+ * and all the band/mode setting already passed into CSR.
+
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_apply_channel_and_power_list(tpAniSirGlobal pMac);
+
+/*
+ * csr_roam_connect_to_last_profile() -
+ * To disconnect and reconnect with the same profile
+ *
+ * Return QDF_STATUS. It returns fail if currently connected
+ */
+QDF_STATUS csr_roam_connect_to_last_profile(tpAniSirGlobal pMac,
+					uint32_t sessionId);
+
+/*
+ * csr_roam_disconnect() -
+ *  To disconnect from a network
+ *
+ * Reason -- To indicate the reason for disconnecting. Currently, only
+ * eCSR_DISCONNECT_REASON_MIC_ERROR is meanful.
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_roam_disconnect(tpAniSirGlobal pMac, uint32_t sessionId,
+			       eCsrRoamDisconnectReason reason);
+
+/* This function is used to stop a BSS. It is similar of csr_roamIssueDisconnect
+ * but this function doesn't have any logic other than blindly trying to stop
+ * BSS
+ */
+QDF_STATUS csr_roam_issue_stop_bss_cmd(tpAniSirGlobal pMac, uint32_t sessionId,
+				       bool fHighPriority);
+
+void csr_call_roaming_completion_callback(tpAniSirGlobal pMac,
+					  struct csr_roam_session *pSession,
+					  struct csr_roam_info *roam_info,
+					  uint32_t roamId,
+					  eCsrRoamResult roamResult);
+/**
+ * csr_roam_issue_disassociate_sta_cmd() - disassociate a associated station
+ * @pMac:          Pointer to global structure for MAC
+ * @sessionId:     Session Id for Soft AP
+ * @p_del_sta_params: Pointer to parameters of the station to disassoc
+ *
+ * CSR function that HDD calls to issue a deauthenticate station command
+ *
+ * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_* on error
+ */
+QDF_STATUS csr_roam_issue_disassociate_sta_cmd(tpAniSirGlobal pMac,
+					       uint32_t sessionId,
+					       struct csr_del_sta_params
+					       *p_del_sta_params);
+/**
+ * csr_roam_issue_deauth_sta_cmd() - issue deauthenticate station command
+ * @pMac:          Pointer to global structure for MAC
+ * @sessionId:     Session Id for Soft AP
+ * @pDelStaParams: Pointer to parameters of the station to deauthenticate
+ *
+ * CSR function that HDD calls to issue a deauthenticate station command
+ *
+ * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_** on error
+ */
+QDF_STATUS csr_roam_issue_deauth_sta_cmd(tpAniSirGlobal pMac,
+		uint32_t sessionId,
+		struct csr_del_sta_params *pDelStaParams);
+
+/*
+ * csr_roam_get_associated_stas
+ *  csr function that HDD calls to get list of associated stations based on
+ * module ID
+ * sessionId - session Id for Soft AP
+ * modId - module ID - PE/HAL/TL
+ * pUsrContext - Opaque HDD context
+ * pfnSapEventCallback - Sap event callback in HDD
+ * pAssocStasBuf - Caller allocated memory to be filled with associatd
+ * stations info
+ * Return QDF_STATUS
+ */
+QDF_STATUS csr_roam_get_associated_stas(tpAniSirGlobal pMac, uint32_t sessionId,
+					QDF_MODULE_ID modId, void *pUsrContext,
+					void *pfnSapEventCallback,
+					uint8_t *pAssocStasBuf);
+
+QDF_STATUS csr_send_mb_get_associated_stas_req_msg(tpAniSirGlobal pMac,
+						   uint32_t sessionId,
+						   QDF_MODULE_ID modId,
+						   struct qdf_mac_addr bssId,
+						   void *pUsrContext,
+						   void *pfnSapEventCallback,
+						   uint8_t *pAssocStasBuf);
+
+/*
+ * csr_send_chng_mcc_beacon_interval() -
+ *   csr function that HDD calls to send Update beacon interval
+ *
+ * sessionId - session Id for Soft AP
+ * Return QDF_STATUS
+ */
+QDF_STATUS
+csr_send_chng_mcc_beacon_interval(tpAniSirGlobal pMac, uint32_t sessionId);
+
+/**
+ * csr_roam_ft_pre_auth_rsp_processor() - Handle the preauth response
+ * @mac_ctx: Global MAC context
+ * @preauth_rsp: Received preauthentication response
+ *
+ * Return: None
+ */
+#ifdef WLAN_FEATURE_HOST_ROAM
+void csr_roam_ft_pre_auth_rsp_processor(tpAniSirGlobal mac_ctx,
+					tpSirFTPreAuthRsp pFTPreAuthRsp);
+#else
+static inline
+void csr_roam_ft_pre_auth_rsp_processor(tpAniSirGlobal mac_ctx,
+					tpSirFTPreAuthRsp pFTPreAuthRsp)
+{}
+#endif
+
+#if defined(FEATURE_WLAN_ESE)
+void update_cckmtsf(uint32_t *timeStamp0, uint32_t *timeStamp1,
+		    uint64_t *incr);
+#endif
+
+QDF_STATUS csr_roam_enqueue_preauth(tpAniSirGlobal pMac, uint32_t sessionId,
+			    tpSirBssDescription pBssDescription,
+			    enum csr_roam_reason reason, bool fImmediate);
+QDF_STATUS csr_dequeue_roam_command(tpAniSirGlobal pMac,
+				enum csr_roam_reason reason,
+				uint8_t session_id);
+void csr_init_occupied_channels_list(tpAniSirGlobal pMac, uint8_t sessionId);
+bool csr_neighbor_roam_is_new_connected_profile(tpAniSirGlobal pMac,
+						uint8_t sessionId);
+bool csr_neighbor_roam_connected_profile_match(tpAniSirGlobal pMac,
+					       uint8_t sessionId,
+					       struct tag_csrscan_result
+						*pResult,
+					       tDot11fBeaconIEs *pIes);
+
+QDF_STATUS csr_scan_create_entry_in_scan_cache(tpAniSirGlobal pMac,
+						uint32_t sessionId,
+						struct qdf_mac_addr bssid,
+						uint8_t channel);
+
+QDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac);
+QDF_STATUS csr_roam_del_pmkid_from_cache(tpAniSirGlobal pMac,
+					 uint32_t sessionId,
+					 tPmkidCacheInfo *pmksa,
+					 bool flush_cache);
+
+bool csr_elected_country_info(tpAniSirGlobal pMac);
+void csr_add_vote_for_country_info(tpAniSirGlobal pMac, uint8_t *pCountryCode);
+void csr_clear_votes_for_country_info(tpAniSirGlobal pMac);
+
+QDF_STATUS csr_send_ext_change_channel(tpAniSirGlobal mac_ctx,
+				uint32_t channel, uint8_t session_id);
+#ifdef CONFIG_VDEV_SM
+/**
+ * csr_csa_start() - request CSA IE transmission from PE
+ * @mac_ctx: handle returned by mac_open
+ * @session_id: SAP session id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS csr_csa_restart(tpAniSirGlobal mac_ctx, uint8_t session_id);
+#endif
+
+
+#ifdef QCA_HT_2040_COEX
+QDF_STATUS csr_set_ht2040_mode(tpAniSirGlobal pMac, uint32_t sessionId,
+			       ePhyChanBondState cbMode, bool obssEnabled);
+#endif
+QDF_STATUS csr_scan_handle_search_for_ssid(tpAniSirGlobal mac_ctx,
+					   uint32_t session_id);
+QDF_STATUS csr_scan_handle_search_for_ssid_failure(tpAniSirGlobal mac,
+		uint32_t session_id);
+void csr_saved_scan_cmd_free_fields(tpAniSirGlobal mac_ctx,
+				    struct csr_roam_session *session);
+tpSirBssDescription csr_get_fst_bssdescr_ptr(tScanResultHandle result_handle);
+
+tSirBssDescription*
+csr_get_bssdescr_from_scan_handle(tScanResultHandle result_handle,
+				  tSirBssDescription *bss_descr);
+bool is_disconnect_pending(tpAniSirGlobal mac_ctx,
+				   uint8_t sessionid);
+void csr_scan_active_list_timeout_handle(void *userData);
+QDF_STATUS csr_prepare_disconnect_command(tpAniSirGlobal mac,
+			uint32_t session_id, tSmeCmd **sme_cmd);
+
+QDF_STATUS
+csr_roam_prepare_bss_config_from_profile(tpAniSirGlobal mac_ctx,
+					 struct csr_roam_profile *profile,
+					 struct bss_config_param *bss_cfg,
+					 tSirBssDescription *bss_desc);
+
+void csr_roam_prepare_bss_params(tpAniSirGlobal mac_ctx, uint32_t session_id,
+		struct csr_roam_profile *profile, tSirBssDescription *bss_desc,
+		struct bss_config_param *bss_cfg, tDot11fBeaconIEs *ies);
+
+/**
+ * csr_remove_bssid_from_scan_list() - remove the bssid from
+ * scan list
+ * @mac_tx: mac context.
+ * @bssid: bssid to be removed
+ *
+ * This function remove the given bssid from scan list.
+ *
+ * Return: void.
+ */
+void csr_remove_bssid_from_scan_list(tpAniSirGlobal mac_ctx,
+	tSirMacAddr bssid);
+
+QDF_STATUS csr_roam_set_bss_config_cfg(tpAniSirGlobal mac_ctx,
+		uint32_t session_id,
+		struct csr_roam_profile *profile, tSirBssDescription *bss_desc,
+		struct bss_config_param *bss_cfg, tDot11fBeaconIEs *ies,
+		bool reset_country);
+void csr_prune_channel_list_for_mode(tpAniSirGlobal pMac,
+				     struct csr_channel *pChannelList);
+
+#ifdef WLAN_FEATURE_11W
+bool csr_is_mfpc_capable(struct sDot11fIERSN *rsn);
+#else
+static inline bool csr_is_mfpc_capable(struct sDot11fIERSN *rsn)
+{
+	return false;
+}
+#endif
+
+/**
+ * csr_get_rf_band()
+ *
+ * @channel: channel number
+ *
+ * This function is used to translate channel number to band
+ *
+ * Return: BAND_2G -  if 2.4GHZ channel
+ *         BAND_5G -  if 5GHZ channel
+ */
+enum band_info csr_get_rf_band(uint8_t channel);
+
+/**
+ * csr_lookup_pmkid_using_bssid() - lookup pmkid using bssid
+ * @mac: pointer to mac
+ * @session: sme session pointer
+ * @pmk_cache: pointer to pmk cache
+ * @index: index value needs to be seached
+ *
+ * Return: true if pmkid is found else false
+ */
+bool csr_lookup_pmkid_using_bssid(tpAniSirGlobal mac,
+					struct csr_roam_session *session,
+					tPmkidCacheInfo *pmk_cache,
+					uint32_t *index);
+#ifdef WLAN_FEATURE_11AX
+void csr_update_session_he_cap(tpAniSirGlobal mac_ctx,
+			struct csr_roam_session *session);
+#else
+static inline void csr_update_session_he_cap(tpAniSirGlobal mac_ctx,
+			struct csr_roam_session *session)
+{
+}
+#endif
+/**
+ * csr_get_channel_for_hw_mode_change() - This function to find
+ *                                       out if HW mode change
+ *                                       is needed for any of
+ *                                       the candidate AP which
+ *                                       STA could join
+ * @mac_ctx: mac context
+ * @result_handle: an object for the result.
+ * @session_id: STA session ID
+ *
+ * This function is written to find out for any bss from scan
+ * handle a HW mode change to DBS will be needed or not.
+ *
+ * Return: AP channel for which DBS HW mode will be needed. 0
+ * means no HW mode change is needed.
+ */
+uint8_t
+csr_get_channel_for_hw_mode_change(tpAniSirGlobal mac_ctx,
+				   tScanResultHandle result_handle,
+				   uint32_t session_id);
+
+/**
+ * csr_scan_get_channel_for_hw_mode_change() - This function to find
+ *                                       out if HW mode change
+ *                                       is needed for any of
+ *                                       the candidate AP which
+ *                                       STA could join
+ * @mac_ctx: mac context
+ * @session_id: STA session ID
+ * @profile: profile
+ *
+ * This function is written to find out for any bss from scan
+ * handle a HW mode change to DBS will be needed or not.
+ * If there is no candidate AP which requires DBS, this function will return
+ * the first Candidate AP's chan.
+ *
+ * Return: AP channel for which HW mode change will be needed. 0
+ * means no candidate AP to connect.
+ */
+uint8_t
+csr_scan_get_channel_for_hw_mode_change(
+	tpAniSirGlobal mac_ctx, uint32_t session_id,
+	struct csr_roam_profile *profile);
+#endif /* CSR_INSIDE_API_H__ */
diff --git a/core/sme/src/csr/csr_link_list.c b/core/sme/src/csr/csr_link_list.c
new file mode 100644
index 0000000..5d120dc
--- /dev/null
+++ b/core/sme/src/csr/csr_link_list.c
@@ -0,0 +1,526 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2018 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: csr_link_list.c
+ *
+ * Implementation for the Common link list interfaces.
+ */
+#include "csr_link_list.h"
+#include "qdf_lock.h"
+#include "qdf_mem.h"
+#include "qdf_trace.h"
+#include "qdf_mc_timer.h"
+
+static inline void csr_list_init(tListElem *pList)
+{
+	pList->last = pList->next = pList;
+}
+
+static inline void csr_list_remove_entry(tListElem *pEntry)
+{
+	tListElem *pLast;
+	tListElem *pNext;
+
+	pLast = pEntry->last;
+	pNext = pEntry->next;
+	pLast->next = pNext;
+	pNext->last = pLast;
+}
+
+static inline tListElem *csr_list_remove_head(tListElem *pHead)
+{
+	tListElem *pEntry;
+	tListElem *pNext;
+
+	pEntry = pHead->next;
+	pNext = pEntry->next;
+	pHead->next = pNext;
+	pNext->last = pHead;
+
+	return pEntry;
+}
+
+static inline tListElem *csr_list_remove_tail(tListElem *pHead)
+{
+	tListElem *pEntry;
+	tListElem *pLast;
+
+	pEntry = pHead->last;
+	pLast = pEntry->last;
+	pHead->last = pLast;
+	pLast->next = pHead;
+
+	return pEntry;
+}
+
+static inline void csr_list_insert_tail(tListElem *pHead, tListElem *pEntry)
+{
+	tListElem *pLast;
+
+	pLast = pHead->last;
+	pEntry->last = pLast;
+	pEntry->next = pHead;
+	pLast->next = pEntry;
+	pHead->last = pEntry;
+}
+
+static inline void csr_list_insert_head(tListElem *pHead, tListElem *pEntry)
+{
+	tListElem *pNext;
+
+	pNext = pHead->next;
+	pEntry->next = pNext;
+	pEntry->last = pHead;
+	pNext->last = pEntry;
+	pHead->next = pEntry;
+}
+
+/* Insert pNewEntry before pEntry */
+static void csr_list_insert_entry(tListElem *pEntry, tListElem *pNewEntry)
+{
+	tListElem *pLast;
+
+	if (!pEntry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pEntry is Null", __func__);
+		return;
+	}
+
+	pLast = pEntry->last;
+	pLast->next = pNewEntry;
+	pEntry->last = pNewEntry;
+	pNewEntry->next = pEntry;
+	pNewEntry->last = pLast;
+}
+
+uint32_t csr_ll_count(tDblLinkList *pList)
+{
+	uint32_t c = 0;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return c;
+	}
+
+	if (pList && (LIST_FLAG_OPEN == pList->Flag))
+		c = pList->Count;
+
+	return c;
+}
+
+void csr_ll_lock(tDblLinkList *pList)
+{
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag)
+		qdf_mutex_acquire(&pList->Lock);
+}
+
+void csr_ll_unlock(tDblLinkList *pList)
+{
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag)
+		qdf_mutex_release(&pList->Lock);
+}
+
+bool csr_ll_is_list_empty(tDblLinkList *pList, bool fInterlocked)
+{
+	bool fEmpty = true;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return fEmpty;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		fEmpty = csrIsListEmpty(&pList->ListHead);
+
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+	return fEmpty;
+}
+
+bool csr_ll_find_entry(tDblLinkList *pList, tListElem *pEntryToFind)
+{
+	bool fFound = false;
+	tListElem *pEntry;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return fFound;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
+
+		/* Have to make sure we don't loop back to the head of the list,
+		 * which will happen if the entry is NOT on the list.
+		 */
+
+		while (pEntry && (pEntry != &pList->ListHead)) {
+			if (pEntry == pEntryToFind) {
+				fFound = true;
+				break;
+			}
+			pEntry = pEntry->next;
+		}
+
+	}
+	return fFound;
+}
+
+QDF_STATUS csr_ll_open(tDblLinkList *pList)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS qdf_status;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (LIST_FLAG_OPEN != pList->Flag) {
+		pList->Count = 0;
+		qdf_status = qdf_mutex_create(&pList->Lock);
+
+		if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			csr_list_init(&pList->ListHead);
+			pList->Flag = LIST_FLAG_OPEN;
+		} else
+			status = QDF_STATUS_E_FAILURE;
+	}
+	return status;
+}
+
+void csr_ll_close(tDblLinkList *pList)
+{
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		/* Make sure the list is empty... */
+		csr_ll_purge(pList, LL_ACCESS_LOCK);
+		qdf_mutex_destroy(&pList->Lock);
+		pList->Flag = LIST_FLAG_CLOSE;
+	}
+}
+
+void csr_ll_insert_tail(tDblLinkList *pList, tListElem *pEntry,
+			bool fInterlocked)
+{
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		csr_list_insert_tail(&pList->ListHead, pEntry);
+		pList->Count++;
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+}
+
+void csr_ll_insert_head(tDblLinkList *pList, tListElem *pEntry,
+			bool fInterlocked)
+{
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		csr_list_insert_head(&pList->ListHead, pEntry);
+		pList->Count++;
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+}
+
+void csr_ll_insert_entry(tDblLinkList *pList, tListElem *pEntry,
+			 tListElem *pNewEntry, bool fInterlocked)
+{
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		csr_list_insert_entry(pEntry, pNewEntry);
+		pList->Count++;
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+}
+
+tListElem *csr_ll_remove_tail(tDblLinkList *pList, bool fInterlocked)
+{
+	tListElem *pEntry = NULL;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return pEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		if (!csrIsListEmpty(&pList->ListHead)) {
+			pEntry = csr_list_remove_tail(&pList->ListHead);
+			pList->Count--;
+		}
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+
+	return pEntry;
+}
+
+tListElem *csr_ll_peek_tail(tDblLinkList *pList, bool fInterlocked)
+{
+	tListElem *pEntry = NULL;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return pEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		if (!csrIsListEmpty(&pList->ListHead))
+			pEntry = pList->ListHead.last;
+
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+
+	return pEntry;
+}
+
+tListElem *csr_ll_remove_head(tDblLinkList *pList, bool fInterlocked)
+{
+	tListElem *pEntry = NULL;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return pEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		if (!csrIsListEmpty(&pList->ListHead)) {
+			pEntry = csr_list_remove_head(&pList->ListHead);
+			pList->Count--;
+		}
+
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+
+	return pEntry;
+}
+
+tListElem *csr_ll_peek_head(tDblLinkList *pList, bool fInterlocked)
+{
+	tListElem *pEntry = NULL;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return pEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		if (!csrIsListEmpty(&pList->ListHead))
+			pEntry = pList->ListHead.next;
+
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+
+	return pEntry;
+}
+
+void csr_ll_purge(tDblLinkList *pList, bool fInterlocked)
+{
+	tListElem *pEntry;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		/* Remove everything from the list */
+		while ((pEntry = csr_ll_remove_head(pList, LL_ACCESS_NOLOCK)))
+			;
+
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+}
+
+bool csr_ll_remove_entry(tDblLinkList *pList, tListElem *pEntryToRemove,
+			 bool fInterlocked)
+{
+	bool fFound = false;
+	tListElem *pEntry;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return fFound;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
+
+		/* Have to make sure we don't loop back to the head of the
+		 * list, which will happen if the entry is NOT on the list.
+		 */
+		while (pEntry && (pEntry != &pList->ListHead)) {
+			if (pEntry == pEntryToRemove) {
+				csr_list_remove_entry(pEntry);
+				pList->Count--;
+
+				fFound = true;
+				break;
+			}
+
+			pEntry = pEntry->next;
+		}
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+
+	return fFound;
+}
+
+tListElem *csr_ll_next(tDblLinkList *pList, tListElem *pEntry,
+		       bool fInterlocked)
+{
+	tListElem *pNextEntry = NULL;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return pNextEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		if (!csrIsListEmpty(&pList->ListHead)
+		    && csr_ll_find_entry(pList, pEntry)) {
+			pNextEntry = pEntry->next;
+			/* Make sure we don't walk past the head */
+			if (pNextEntry == &pList->ListHead)
+				pNextEntry = NULL;
+		}
+
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+
+	return pNextEntry;
+}
+
+tListElem *csr_ll_previous(tDblLinkList *pList, tListElem *pEntry,
+			   bool fInterlocked)
+{
+	tListElem *pNextEntry = NULL;
+
+	if (!pList) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Error!! pList is Null", __func__);
+		return pNextEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked)
+			csr_ll_lock(pList);
+
+		if (!csrIsListEmpty(&pList->ListHead)
+		    && csr_ll_find_entry(pList, pEntry)) {
+			pNextEntry = pEntry->last;
+			/* Make sure we don't walk past the head */
+			if (pNextEntry == &pList->ListHead)
+				pNextEntry = NULL;
+		}
+
+		if (fInterlocked)
+			csr_ll_unlock(pList);
+	}
+
+	return pNextEntry;
+}
diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c
new file mode 100644
index 0000000..5d021a3
--- /dev/null
+++ b/core/sme/src/csr/csr_neighbor_roam.c
@@ -0,0 +1,1742 @@
+/*
+ * Copyright (c) 2011-2018 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: csr_neighbor_roam.c
+ *
+ * Implementation for the simple roaming algorithm for 802.11r Fast
+ * transitions and Legacy roaming for Android platform.
+ */
+
+#include "wma_types.h"
+#include "csr_inside_api.h"
+#include "sme_qos_internal.h"
+#include "sme_inside.h"
+#include "host_diag_core_event.h"
+#include "host_diag_core_log.h"
+#include "csr_api.h"
+#include "sme_api.h"
+#include "csr_neighbor_roam.h"
+#include "mac_trace.h"
+#include "wlan_policy_mgr_api.h"
+
+static const char *lfr_get_config_item_string(uint8_t reason)
+{
+	switch (reason) {
+	CASE_RETURN_STRING(REASON_LOOKUP_THRESH_CHANGED);
+	CASE_RETURN_STRING(REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED);
+	CASE_RETURN_STRING(REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED);
+	CASE_RETURN_STRING(REASON_ROAM_BMISS_FIRST_BCNT_CHANGED);
+	CASE_RETURN_STRING(REASON_ROAM_BMISS_FINAL_BCNT_CHANGED);
+	CASE_RETURN_STRING(REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED);
+	default:
+		return "unknown";
+	}
+}
+
+static void csr_neighbor_roam_reset_channel_info(tpCsrNeighborRoamChannelInfo
+						 rChInfo);
+
+void csr_neighbor_roam_state_transition(tpAniSirGlobal mac_ctx,
+		uint8_t newstate, uint8_t session)
+{
+	mac_ctx->roam.neighborRoamInfo[session].prevNeighborRoamState =
+		mac_ctx->roam.neighborRoamInfo[session].neighborRoamState;
+	mac_ctx->roam.neighborRoamInfo[session].neighborRoamState = newstate;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL("Sessionid (%d) NeighborRoam transition from %s to %s"),
+		session, csr_neighbor_roam_state_to_string(
+		mac_ctx->roam.neighborRoamInfo[session].prevNeighborRoamState),
+		csr_neighbor_roam_state_to_string(newstate));
+}
+
+uint8_t *csr_neighbor_roam_state_to_string(uint8_t state)
+{
+	switch (state) {
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CLOSED);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_INIT);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
+	default:
+		return "eCSR_NEIGHBOR_ROAM_STATE_UNKNOWN";
+	}
+
+}
+
+#ifdef FEATURE_WLAN_LFR_METRICS
+/**
+ * csr_neighbor_roam_send_lfr_metric_event() - Send event of LFR metric
+ * @mac_ctx: Handle returned by mac_open.
+ * @session_id: Session information
+ * @bssid: BSSID of attempted AP
+ * @status: Result of LFR operation
+ *
+ * LFR metrics - pre-auth completion metric
+ * Send the event to supplicant indicating pre-auth result
+ *
+ * Return: void
+ */
+
+void csr_neighbor_roam_send_lfr_metric_event(
+				tpAniSirGlobal mac_ctx,
+				uint8_t session_id,
+				tSirMacAddr bssid,
+				eRoamCmdStatus status)
+{
+	struct csr_roam_info *roam_info;
+
+	roam_info = qdf_mem_malloc(sizeof(struct csr_roam_info));
+	if (roam_info) {
+		qdf_mem_copy((void *)roam_info->bssid.bytes,
+			     (void *)bssid, sizeof(struct qdf_mac_addr));
+		csr_roam_call_callback(mac_ctx, session_id, roam_info, 0,
+			status, 0);
+		qdf_mem_free(roam_info);
+	}
+}
+#endif
+
+/**
+ * csr_neighbor_roam_update_fast_roaming_enabled() - update roaming capability
+ *
+ * @mac_ctx: Global MAC context
+ * @session_id: Session
+ * @fast_roam_enabled: Is fast roaming enabled on this device?
+ *                     This capability can be changed dynamically.
+ *
+ * Return: None
+ */
+QDF_STATUS csr_neighbor_roam_update_fast_roaming_enabled(tpAniSirGlobal mac_ctx,
+						uint8_t session_id,
+						const bool fast_roam_enabled)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+
+	switch (neighbor_roam_info->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
+		qdf_status = sme_acquire_global_lock(&mac_ctx->sme);
+		if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			if (fast_roam_enabled) {
+				csr_roam_offload_scan(mac_ctx, session_id,
+						ROAM_SCAN_OFFLOAD_START,
+						REASON_CONNECT);
+			} else {
+				csr_roam_offload_scan(mac_ctx, session_id,
+						ROAM_SCAN_OFFLOAD_STOP,
+						REASON_DISCONNECTED);
+			}
+			sme_release_global_lock(&mac_ctx->sme);
+		} else {
+			sme_err("Failed to acquire SME lock");
+		}
+	break;
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		sme_debug("Currently in INIT state, Nothing to do");
+		break;
+	default:
+		sme_err("Unexpected state %s, returning failure",
+			    mac_trace_get_neighbour_roam_state
+			    (neighbor_roam_info->neighborRoamState));
+		qdf_status = QDF_STATUS_E_FAILURE;
+		break;
+	}
+	return qdf_status;
+}
+QDF_STATUS csr_neighbor_roam_update_config(tpAniSirGlobal mac_ctx,
+		uint8_t session_id, uint8_t value, uint8_t reason)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+	    &mac_ctx->roam.neighborRoamInfo[session_id];
+	tpCsrNeighborRoamCfgParams cfg_params;
+	eCsrNeighborRoamState state;
+	uint8_t old_value;
+
+	if (NULL == pNeighborRoamInfo) {
+		sme_err("Invalid Session ID %d", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	cfg_params = &pNeighborRoamInfo->cfgParams;
+	state = pNeighborRoamInfo->neighborRoamState;
+	if ((state == eCSR_NEIGHBOR_ROAM_STATE_CONNECTED) ||
+			state == eCSR_NEIGHBOR_ROAM_STATE_INIT) {
+		switch (reason) {
+		case REASON_LOOKUP_THRESH_CHANGED:
+			old_value = cfg_params->neighborLookupThreshold;
+			cfg_params->neighborLookupThreshold = value;
+			pNeighborRoamInfo->currentNeighborLookupThreshold =
+				value;
+			break;
+		case REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED:
+			old_value = cfg_params->nOpportunisticThresholdDiff;
+			cfg_params->nOpportunisticThresholdDiff = value;
+			pNeighborRoamInfo->currentOpportunisticThresholdDiff =
+				value;
+			break;
+		case REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED:
+			old_value = cfg_params->nRoamRescanRssiDiff;
+			cfg_params->nRoamRescanRssiDiff = value;
+			pNeighborRoamInfo->currentRoamRescanRssiDiff = value;
+			break;
+		case REASON_ROAM_BMISS_FIRST_BCNT_CHANGED:
+			old_value = cfg_params->nRoamBmissFirstBcnt;
+			cfg_params->nRoamBmissFirstBcnt = value;
+			pNeighborRoamInfo->currentRoamBmissFirstBcnt = value;
+			break;
+		case REASON_ROAM_BMISS_FINAL_BCNT_CHANGED:
+			old_value = cfg_params->nRoamBmissFinalBcnt;
+			cfg_params->nRoamBmissFinalBcnt = value;
+			pNeighborRoamInfo->currentRoamBmissFinalBcnt = value;
+			break;
+		case REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED:
+			old_value = cfg_params->nRoamBeaconRssiWeight;
+			cfg_params->nRoamBeaconRssiWeight = value;
+			pNeighborRoamInfo->currentRoamBeaconRssiWeight = value;
+			break;
+		default:
+			sme_debug("Unknown update cfg reason");
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		sme_err("Unexpected state %s, return fail",
+			mac_trace_get_neighbour_roam_state(state));
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (state == eCSR_NEIGHBOR_ROAM_STATE_CONNECTED) {
+		sme_debug("CONNECTED, send update cfg cmd");
+		csr_roam_offload_scan(mac_ctx, session_id,
+			ROAM_SCAN_OFFLOAD_UPDATE_CFG, reason);
+	}
+	sme_debug("LFR config for %s changed from %d to %d",
+			lfr_get_config_item_string(reason), old_value, value);
+	return QDF_STATUS_SUCCESS;
+}
+
+/*CleanUP Routines*/
+static void csr_neighbor_roam_reset_channel_info(tpCsrNeighborRoamChannelInfo
+						 rChInfo)
+{
+	if ((rChInfo->IAPPNeighborListReceived == false) &&
+	    (rChInfo->currentChannelListInfo.numOfChannels)) {
+		rChInfo->currentChanIndex =
+			CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
+		rChInfo->currentChannelListInfo.numOfChannels = 0;
+
+		if (rChInfo->currentChannelListInfo.ChannelList)
+			qdf_mem_free(rChInfo->currentChannelListInfo.
+				     ChannelList);
+
+		rChInfo->currentChannelListInfo.ChannelList = NULL;
+	} else {
+		rChInfo->currentChanIndex = 0;
+	}
+}
+
+/**
+ * csr_neighbor_roam_reset_connected_state_control_info()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @sessionId : session id
+ *
+ * This function will reset the neighbor roam control info data structures.
+ * This function should be invoked whenever we move to CONNECTED state from
+ * any state other than INIT state
+ *
+ * Return: None
+ */
+static void csr_neighbor_roam_reset_connected_state_control_info(
+							tpAniSirGlobal pMac,
+							uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	csr_neighbor_roam_reset_channel_info(&pNeighborRoamInfo->
+					roamChannelInfo);
+	csr_neighbor_roam_free_roamable_bss_list(pMac,
+					&pNeighborRoamInfo->roamableAPList);
+
+	/* Do not free up the preauth done list here */
+	pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
+	pNeighborRoamInfo->FTRoamInfo.neighborRptPending = false;
+	pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
+	pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
+	pNeighborRoamInfo->FTRoamInfo.preauthRspPending = 0;
+	qdf_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo,
+		     sizeof(tCsrNeighborReportBssInfo) *
+		     MAX_BSS_IN_NEIGHBOR_RPT);
+	pNeighborRoamInfo->uOsRequestedHandoff = 0;
+	qdf_mem_zero(&pNeighborRoamInfo->handoffReqInfo,
+		     sizeof(tCsrHandoffRequest));
+}
+
+static void csr_neighbor_roam_reset_report_scan_state_control_info(
+							tpAniSirGlobal pMac,
+							uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	qdf_zero_macaddr(&pNeighborRoamInfo->currAPbssid);
+#ifdef FEATURE_WLAN_ESE
+	pNeighborRoamInfo->isESEAssoc = false;
+	pNeighborRoamInfo->isVOAdmitted = false;
+	pNeighborRoamInfo->MinQBssLoadRequired = 0;
+#endif
+
+	/* Purge roamable AP list */
+	csr_neighbor_roam_free_roamable_bss_list(pMac,
+					&pNeighborRoamInfo->roamableAPList);
+}
+
+/**
+ * csr_neighbor_roam_reset_init_state_control_info()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @sessionId : session id
+ *
+ * This function will reset the neighbor roam control info data structures.
+ * This function should be invoked whenever we move to CONNECTED state from
+ * INIT state
+ *
+ * Return: None
+ */
+static void csr_neighbor_roam_reset_init_state_control_info(tpAniSirGlobal pMac,
+							    uint8_t sessionId)
+{
+	csr_neighbor_roam_reset_connected_state_control_info(pMac, sessionId);
+
+	/* In addition to the above resets,
+	 * we should clear off the curAPBssId/Session ID in the timers
+	 */
+	csr_neighbor_roam_reset_report_scan_state_control_info(pMac, sessionId);
+}
+
+/**
+ * csr_neighbor_roam_prepare_scan_profile_filter()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ * @scan_filter: Populated scan filter based on the connected profile
+ *
+ * This function creates a scan filter based on the currently
+ * connected profile. Based on this filter, scan results are obtained
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
+ */
+QDF_STATUS
+csr_neighbor_roam_prepare_scan_profile_filter(tpAniSirGlobal pMac,
+					      tCsrScanResultFilter *pScanFilter,
+					      uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo nbr_roam_info =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	tCsrRoamConnectedProfile *pCurProfile =
+		&pMac->roam.roamSession[sessionId].connectedProfile;
+	uint8_t i = 0;
+	struct roam_ext_params *roam_params;
+	uint8_t num_ch = 0;
+
+	QDF_ASSERT(pScanFilter != NULL);
+	if (pScanFilter == NULL)
+		return QDF_STATUS_E_FAILURE;
+
+	qdf_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
+	roam_params = &pMac->roam.configParam.roam_params;
+	/* We dont want to set BSSID based Filter */
+	pScanFilter->BSSIDs.numOfBSSIDs = 0;
+	pScanFilter->scan_filter_for_roam = 1;
+	/* only for HDD requested handoff fill in the BSSID in the filter */
+	if (nbr_roam_info->uOsRequestedHandoff) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("OS Requested Handoff"));
+		pScanFilter->BSSIDs.numOfBSSIDs = 1;
+		pScanFilter->BSSIDs.bssid =
+			qdf_mem_malloc(sizeof(tSirMacAddr) *
+				       pScanFilter->BSSIDs.numOfBSSIDs);
+		if (!pScanFilter->BSSIDs.bssid)
+			return QDF_STATUS_E_NOMEM;
+
+		/* Populate the BSSID from handoff info received from HDD */
+		for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++) {
+			qdf_copy_macaddr(&pScanFilter->BSSIDs.bssid[i],
+				 &nbr_roam_info->handoffReqInfo.bssid);
+		}
+	}
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL("No of Allowed SSID List:%d"),
+		roam_params->num_ssid_allowed_list);
+	if (roam_params->num_ssid_allowed_list) {
+		pScanFilter->SSIDs.numOfSSIDs =
+			roam_params->num_ssid_allowed_list;
+		pScanFilter->SSIDs.SSIDList =
+			qdf_mem_malloc(sizeof(tCsrSSIDInfo) *
+				pScanFilter->SSIDs.numOfSSIDs);
+		if (!pScanFilter->SSIDs.SSIDList)
+			return QDF_STATUS_E_NOMEM;
+
+		for (i = 0; i < roam_params->num_ssid_allowed_list; i++) {
+			pScanFilter->SSIDs.SSIDList[i].handoffPermitted = 1;
+			pScanFilter->SSIDs.SSIDList[i].ssidHidden = 0;
+			qdf_mem_copy((void *)
+				pScanFilter->SSIDs.SSIDList[i].SSID.ssId,
+				roam_params->ssid_allowed_list[i].ssId,
+				roam_params->ssid_allowed_list[i].length);
+			pScanFilter->SSIDs.SSIDList[i].SSID.length =
+				roam_params->ssid_allowed_list[i].length;
+		}
+	} else {
+		/* Populate all the information from the connected profile */
+		pScanFilter->SSIDs.numOfSSIDs = 1;
+		pScanFilter->SSIDs.SSIDList =
+			qdf_mem_malloc(sizeof(tCsrSSIDInfo));
+		if (!pScanFilter->SSIDs.SSIDList)
+			return QDF_STATUS_E_NOMEM;
+
+		pScanFilter->SSIDs.SSIDList->handoffPermitted = 1;
+		pScanFilter->SSIDs.SSIDList->ssidHidden = 0;
+		pScanFilter->SSIDs.SSIDList->SSID.length =
+			pCurProfile->SSID.length;
+		qdf_mem_copy((void *)pScanFilter->SSIDs.SSIDList->SSID.ssId,
+			(void *)pCurProfile->SSID.ssId,
+			pCurProfile->SSID.length);
+
+		sme_debug("Filtering for SSID %.*s,length of SSID = %u",
+			pScanFilter->SSIDs.SSIDList->SSID.length,
+			pScanFilter->SSIDs.SSIDList->SSID.ssId,
+			pScanFilter->SSIDs.SSIDList->SSID.length);
+	}
+	pScanFilter->authType.numEntries = 1;
+	pScanFilter->authType.authType[0] = pCurProfile->AuthType;
+
+	pScanFilter->EncryptionType.numEntries = 1;     /* This must be 1 */
+	pScanFilter->EncryptionType.encryptionType[0] =
+		pCurProfile->EncryptionType;
+
+	pScanFilter->mcEncryptionType.numEntries = 1;
+	pScanFilter->mcEncryptionType.encryptionType[0] =
+		pCurProfile->mcEncryptionType;
+
+	pScanFilter->BSSType = pCurProfile->BSSType;
+
+	num_ch =
+	    nbr_roam_info->roamChannelInfo.currentChannelListInfo.numOfChannels;
+	if (num_ch) {
+		/*
+		 * We are intrested only in the scan results on channels we
+		 * scanned
+		 */
+		pScanFilter->ChannelInfo.numOfChannels = num_ch;
+		pScanFilter->ChannelInfo.ChannelList =
+			qdf_mem_malloc(num_ch * sizeof(uint8_t));
+		if (!pScanFilter->ChannelInfo.ChannelList) {
+			qdf_mem_free(pScanFilter->SSIDs.SSIDList);
+			pScanFilter->SSIDs.SSIDList = NULL;
+			return QDF_STATUS_E_NOMEM;
+		}
+		for (i = 0; i < pScanFilter->ChannelInfo.numOfChannels; i++) {
+			pScanFilter->ChannelInfo.ChannelList[i] =
+			  nbr_roam_info->roamChannelInfo.currentChannelListInfo.
+			  ChannelList[i];
+		}
+	} else {
+		pScanFilter->ChannelInfo.numOfChannels = 0;
+		pScanFilter->ChannelInfo.ChannelList = NULL;
+	}
+
+	if (nbr_roam_info->is11rAssoc) {
+		/*
+		 * MDIE should be added as a part of profile. This should be
+		 * added as a part of filter as well
+		 */
+		pScanFilter->MDID.mdiePresent = pCurProfile->MDID.mdiePresent;
+		pScanFilter->MDID.mobilityDomain =
+			pCurProfile->MDID.mobilityDomain;
+	}
+
+#ifdef WLAN_FEATURE_11W
+	pScanFilter->MFPEnabled = pCurProfile->MFPEnabled;
+	pScanFilter->MFPRequired = pCurProfile->MFPRequired;
+	pScanFilter->MFPCapable = pCurProfile->MFPCapable;
+#endif
+	return QDF_STATUS_SUCCESS;
+}
+
+enum band_info csr_get_rf_band(uint8_t channel)
+{
+	if ((channel >= SIR_11A_CHANNEL_BEGIN) &&
+	    (channel <= SIR_11A_CHANNEL_END))
+		return BAND_5G;
+
+	if ((channel >= SIR_11B_CHANNEL_BEGIN) &&
+	    (channel <= SIR_11B_CHANNEL_END))
+		return BAND_2G;
+
+	return BAND_UNKNOWN;
+}
+
+/**
+ * csr_neighbor_roam_channels_filter_by_current_band()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ * @input_ch_list: The input channel list
+ * @input_num_of_ch: The number of channels in input channel list
+ * @output_ch_list: The output channel list
+ * @output_num_of_ch: The number of channels in output channel list
+ * @merged_output_num_of_ch: The final number of channels in the
+ *				output channel list.
+ *
+ * This function is used to filter out the channels based on the
+ * currently associated AP channel
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
+ */
+QDF_STATUS csr_neighbor_roam_channels_filter_by_current_band(tpAniSirGlobal
+						pMac,
+						uint8_t sessionId,
+						uint8_t *pInputChannelList,
+						uint8_t inputNumOfChannels,
+						uint8_t *pOutputChannelList,
+						uint8_t *
+						pMergedOutputNumOfChannels)
+{
+	uint8_t i = 0;
+	uint8_t numChannels = 0;
+	uint8_t currAPoperationChannel =
+		pMac->roam.neighborRoamInfo[sessionId].currAPoperationChannel;
+	/* Check for NULL pointer */
+	if (!pInputChannelList)
+		return QDF_STATUS_E_INVAL;
+
+	/* Check for NULL pointer */
+	if (!pOutputChannelList)
+		return QDF_STATUS_E_INVAL;
+
+	if (inputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Wrong Number of Input Channels %d",
+			  __func__, inputNumOfChannels);
+		return QDF_STATUS_E_INVAL;
+	}
+	for (i = 0; i < inputNumOfChannels; i++) {
+		if (csr_get_rf_band(currAPoperationChannel) ==
+		    csr_get_rf_band(pInputChannelList[i])) {
+			pOutputChannelList[numChannels] = pInputChannelList[i];
+			numChannels++;
+		}
+	}
+
+	/* Return final number of channels */
+	*pMergedOutputNumOfChannels = numChannels;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_neighbor_roam_channels_filter_by_current_band()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ * @input_ch_list: The additional channels to merge in to the
+ *			"merged" channels list.
+ * @input_num_of_ch: The number of additional channels.
+ * @output_ch_list: The place to put the "merged" channel list.
+ * @output_num_of_ch: The original number of channels in the
+ *			"merged" channels list.
+ * @merged_output_num_of_ch: The final number of channels in the
+ *				"merged" channel list.
+ *
+ * This function is used to merge two channel list.
+ * NB: If called with outputNumOfChannels == 0, this routines simply
+ * copies the input channel list to the output channel list. if number
+ * of merged channels are more than 100, num of channels set to 100
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
+ */
+QDF_STATUS csr_neighbor_roam_merge_channel_lists(tpAniSirGlobal pMac,
+						 uint8_t *pInputChannelList,
+						 uint8_t inputNumOfChannels,
+						 uint8_t *pOutputChannelList,
+						 uint8_t outputNumOfChannels,
+						 uint8_t *
+						 pMergedOutputNumOfChannels)
+{
+	uint8_t i = 0;
+	uint8_t j = 0;
+	uint8_t numChannels = outputNumOfChannels;
+
+	/* Check for NULL pointer */
+	if (!pInputChannelList)
+		return QDF_STATUS_E_INVAL;
+
+	/* Check for NULL pointer */
+	if (!pOutputChannelList)
+		return QDF_STATUS_E_INVAL;
+
+	if (inputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Wrong Number of Input Channels %d",
+			  __func__, inputNumOfChannels);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (outputNumOfChannels >= WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Wrong Number of Output Channels %d",
+			  __func__, outputNumOfChannels);
+		return QDF_STATUS_E_INVAL;
+	}
+	/* Add the "new" channels in the input list to the end of the
+	 * output list.
+	 */
+	for (i = 0; i < inputNumOfChannels; i++) {
+		for (j = 0; j < outputNumOfChannels; j++) {
+			if (pInputChannelList[i] == pOutputChannelList[j])
+				break;
+		}
+		if (j == outputNumOfChannels) {
+			if (pInputChannelList[i]) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "%s: [INFOLOG] Adding extra %d to Neighbor channel list",
+					  __func__, pInputChannelList[i]);
+				pOutputChannelList[numChannels] =
+					pInputChannelList[i];
+				numChannels++;
+			}
+		}
+		if (numChannels >= WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: Merge Neighbor channel list reached Max limit %d",
+				__func__, numChannels);
+			break;
+		}
+	}
+
+	/* Return final number of channels */
+	*pMergedOutputNumOfChannels = numChannels;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_neighbor_roam_is_ssid_and_security_match() - to match ssid/security
+ * @pMac: Pointer to mac context
+ * @pCurProfile: pointer to current roam profile
+ * @pBssDesc: pointer to bss description
+ * @pIes: pointer to local ies
+ *
+ * This routine will be called to see if SSID and security parameters
+ * are matching.
+ *
+ * Return: bool
+ */
+static bool csr_neighbor_roam_is_ssid_and_security_match(tpAniSirGlobal pMac,
+		tCsrRoamConnectedProfile *pCurProfile,
+		tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes)
+{
+	tCsrAuthList authType;
+	tCsrEncryptionList uCEncryptionType;
+	tCsrEncryptionList mCEncryptionType;
+	bool fMatch = false;
+
+	authType.numEntries = 1;
+	authType.authType[0] = pCurProfile->AuthType;
+	uCEncryptionType.numEntries = 1;
+	uCEncryptionType.encryptionType[0] = pCurProfile->EncryptionType;
+	mCEncryptionType.numEntries = 1;
+	mCEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType;
+
+	/* Again, treat missing pIes as a non-match. */
+	if (!pIes)
+		return false;
+
+	/* Treat a missing SSID as a non-match. */
+	if (!pIes->SSID.present)
+		return false;
+
+	fMatch = csr_is_ssid_match(pMac,
+			(void *)pCurProfile->SSID.ssId,
+			pCurProfile->SSID.length,
+			pIes->SSID.ssid,
+			pIes->SSID.num_ssid, true);
+	if (true == fMatch) {
+#ifdef WLAN_FEATURE_11W
+		/*
+		 * We are sending current connected APs profile setting
+		 * if other AP doesn't have the same PMF setting as currently
+		 * connected AP then we will have some issues in roaming.
+		 *
+		 * Make sure all the APs have same PMF settings to avoid
+		 * any corner cases.
+		 */
+		fMatch = csr_is_security_match(pMac, &authType,
+				&uCEncryptionType, &mCEncryptionType,
+				&pCurProfile->MFPEnabled,
+				&pCurProfile->MFPRequired,
+				&pCurProfile->MFPCapable,
+				pBssDesc, pIes, NULL, NULL, NULL);
+#else
+		fMatch = csr_is_security_match(pMac, &authType,
+				&uCEncryptionType,
+				&mCEncryptionType, NULL,
+				NULL, NULL, pBssDesc,
+				pIes, NULL, NULL, NULL);
+#endif
+		return fMatch;
+	} else {
+		return fMatch;
+	}
+
+}
+
+bool csr_neighbor_roam_is_new_connected_profile(tpAniSirGlobal pMac,
+						uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	tCsrRoamConnectedProfile *pCurrProfile = NULL;
+	tCsrRoamConnectedProfile *pPrevProfile = NULL;
+	tDot11fBeaconIEs *pIes = NULL;
+	tSirBssDescription *pBssDesc = NULL;
+	bool fNew = true;
+
+	if (!(pMac->roam.roamSession && CSR_IS_SESSION_VALID(pMac, sessionId)))
+		return fNew;
+
+	pCurrProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
+	if (!pCurrProfile)
+		return fNew;
+
+	pPrevProfile = &pNeighborRoamInfo->prevConnProfile;
+	if (!pPrevProfile)
+		return fNew;
+
+	pBssDesc = pPrevProfile->pBssDesc;
+	if (pBssDesc) {
+		if (QDF_IS_STATUS_SUCCESS(
+		    csr_get_parsed_bss_description_ies(pMac, pBssDesc, &pIes))
+		    && csr_neighbor_roam_is_ssid_and_security_match(pMac,
+					pCurrProfile, pBssDesc, pIes)) {
+			fNew = false;
+		}
+		if (pIes)
+			qdf_mem_free(pIes);
+	}
+
+	sme_debug("roam profile match: %d", !fNew);
+
+	return fNew;
+}
+
+bool csr_neighbor_roam_connected_profile_match(tpAniSirGlobal pMac,
+					       uint8_t sessionId,
+					       struct tag_csrscan_result
+						*pResult,
+					       tDot11fBeaconIEs *pIes)
+{
+	tCsrRoamConnectedProfile *pCurProfile = NULL;
+	tSirBssDescription *pBssDesc = &pResult->Result.BssDescriptor;
+
+	if (!(pMac->roam.roamSession && CSR_IS_SESSION_VALID(pMac, sessionId)))
+		return false;
+
+	pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
+
+	if (!pCurProfile)
+		return false;
+
+	return csr_neighbor_roam_is_ssid_and_security_match(pMac, pCurProfile,
+							    pBssDesc, pIes);
+}
+
+/**
+ * csr_roam_reset_roam_params - API to reset the roaming parameters
+ * @mac_ctx:          Pointer to the global MAC structure
+ *
+ * The BSSID blacklist should not be cleared since it has to
+ * be used across connections. These parameters will be cleared
+ * and sent to firmware with with the roaming STOP command.
+ *
+ * Return: VOID
+ */
+void csr_roam_reset_roam_params(tpAniSirGlobal mac_ctx)
+{
+	struct roam_ext_params *roam_params = NULL;
+
+	/*
+	 * clear all the whitelist parameters and remaining
+	 * needs to be retained across connections.
+	 */
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL("Roaming parameters are reset"));
+	roam_params = &mac_ctx->roam.configParam.roam_params;
+	roam_params->num_ssid_allowed_list = 0;
+	qdf_mem_set(&roam_params->ssid_allowed_list, 0,
+			sizeof(tSirMacSSid) * MAX_SSID_ALLOWED_LIST);
+}
+
+/**
+ * csr_neighbor_roam_indicate_disconnect() - To indicate disconnect
+ * @pMac: The handle returned by mac_open
+ * @sessionId: CSR session id that got disconnected
+ *
+ * This function is called by CSR as soon as the station disconnects
+ * from the AP. This function does the necessary cleanup of neighbor roam
+ * data structures. Neighbor roam state transitions to INIT state whenever
+ * this function is called except if the current state is REASSOCIATING
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS csr_neighbor_roam_indicate_disconnect(tpAniSirGlobal pMac,
+						 uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+			&pMac->roam.neighborRoamInfo[sessionId];
+	tCsrRoamConnectedProfile *pPrevProfile =
+			&pNeighborRoamInfo->prevConnProfile;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+	struct csr_roam_session *roam_session = NULL;
+
+	if (NULL == pSession) {
+		sme_err("pSession is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("Disconn ind on session %d in state %d from bss :"
+			MAC_ADDRESS_STR), sessionId,
+			pNeighborRoamInfo->neighborRoamState,
+			MAC_ADDR_ARRAY(pSession->connectedProfile.bssid.bytes));
+	/*
+	 * Free the current previous profile and move
+	 * the current profile to prev profile.
+	 */
+	csr_roam_free_connect_profile(pPrevProfile);
+	csr_roam_copy_connect_profile(pMac, sessionId, pPrevProfile);
+	/*
+	 * clear the roaming parameters that are per connection.
+	 * For a new connection, they have to be programmed again.
+	 */
+	if (!csr_neighbor_middle_of_roaming(pMac, sessionId))
+		csr_roam_reset_roam_params(pMac);
+	if (NULL != pSession) {
+		roam_session = &pMac->roam.roamSession[sessionId];
+		if (NULL != pSession->pCurRoamProfile && (QDF_STA_MODE !=
+			roam_session->pCurRoamProfile->csrPersona)) {
+			sme_err("Ignore disconn ind rcvd from nonSTA persona sessionId: %d csrPersonna %d",
+				sessionId,
+				(int)roam_session->pCurRoamProfile->csrPersona);
+			return QDF_STATUS_SUCCESS;
+		}
+#ifdef FEATURE_WLAN_ESE
+		if (pSession->connectedProfile.isESEAssoc) {
+			qdf_mem_copy(&pSession->prevApSSID,
+				&pSession->connectedProfile.SSID,
+				sizeof(tSirMacSSid));
+			qdf_copy_macaddr(&pSession->prevApBssid,
+					&pSession->connectedProfile.bssid);
+			pSession->prevOpChannel =
+				pSession->connectedProfile.operationChannel;
+			pSession->isPrevApInfoValid = true;
+			pSession->roamTS1 = qdf_mc_timer_get_system_time();
+		}
+#endif
+	}
+
+	switch (pNeighborRoamInfo->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
+		/*
+		 * Stop scan and neighbor refresh timers.
+		 * These are indeed not required when we'r in reassoc state.
+		 */
+		if (!CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId)) {
+			/*
+			 * Disconnect indication during Disassoc Handoff
+			 * sub-state is received when we are trying to
+			 * disconnect with the old AP during roam.
+			 * BUT, if receive a disconnect indication outside of
+			 * Disassoc Handoff sub-state, then it means that
+			 * this is a genuine disconnect and we need to clean up.
+			 * Otherwise, we will be stuck in reassoc state which'll
+			 * in-turn block scans.
+			 */
+		csr_neighbor_roam_state_transition(pMac,
+				eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId);
+			pNeighborRoamInfo->roamChannelInfo.
+				IAPPNeighborListReceived = false;
+			pNeighborRoamInfo->uOsRequestedHandoff = 0;
+		}
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		csr_neighbor_roam_reset_init_state_control_info(pMac,
+				sessionId);
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
+		csr_neighbor_roam_state_transition(pMac,
+				eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId);
+		pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived =
+				false;
+		csr_neighbor_roam_reset_connected_state_control_info(pMac,
+				sessionId);
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE:
+		/* Stop pre-auth to reassoc interval timer */
+		qdf_mc_timer_stop(&pSession->ftSmeContext.
+				preAuthReassocIntvlTimer);
+	case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING:
+		csr_neighbor_roam_state_transition(pMac,
+				eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId);
+		pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived =
+				false;
+		csr_neighbor_roam_reset_preauth_control_info(pMac, sessionId);
+		csr_neighbor_roam_reset_report_scan_state_control_info(pMac,
+				sessionId);
+		break;
+	default:
+		sme_debug("Received disconnect event in state %s",
+			mac_trace_get_neighbour_roam_state(
+				pNeighborRoamInfo->neighborRoamState));
+		sme_debug("Transit to INIT state");
+		csr_neighbor_roam_state_transition(pMac,
+				eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId);
+			pNeighborRoamInfo->roamChannelInfo.
+			IAPPNeighborListReceived = false;
+			pNeighborRoamInfo->uOsRequestedHandoff = 0;
+		break;
+	}
+	/*Inform the Firmware to STOP Scanning as the host has a disconnect. */
+	if (csr_roam_is_sta_mode(pMac, sessionId)) {
+		csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_STOP,
+				REASON_DISCONNECTED);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_neighbor_roam_info_ctx_init() - Initialize neighbor roam struct
+ * @pMac: mac context
+ * @session_id: Session Id
+ *
+ * This initializes all the necessary data structures related to the
+ * associated AP.
+ *
+ * Return: QDF status
+ */
+static void csr_neighbor_roam_info_ctx_init(
+		tpAniSirGlobal pMac,
+		uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo ngbr_roam_info =
+		&pMac->roam.neighborRoamInfo[session_id];
+	struct csr_roam_session *session = &pMac->roam.roamSession[session_id];
+	struct csr_roam_profile *roam_profile = session->pCurRoamProfile;
+	int init_ft_flag = false;
+
+	/*
+	 * Initialize the occupied list ONLY if we are
+	 * transitioning from INIT state to CONNECTED state.
+	 */
+	if (eCSR_NEIGHBOR_ROAM_STATE_INIT ==
+		ngbr_roam_info->neighborRoamState)
+		csr_init_occupied_channels_list(pMac, session_id);
+	csr_neighbor_roam_state_transition(pMac,
+			eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, session_id);
+
+	qdf_copy_macaddr(&ngbr_roam_info->currAPbssid,
+			&session->connectedProfile.bssid);
+	ngbr_roam_info->currAPoperationChannel =
+		session->connectedProfile.operationChannel;
+	ngbr_roam_info->currentNeighborLookupThreshold =
+		ngbr_roam_info->cfgParams.neighborLookupThreshold;
+	ngbr_roam_info->currentOpportunisticThresholdDiff =
+		ngbr_roam_info->cfgParams.nOpportunisticThresholdDiff;
+	ngbr_roam_info->currentRoamRescanRssiDiff =
+		ngbr_roam_info->cfgParams.nRoamRescanRssiDiff;
+	ngbr_roam_info->currentRoamBmissFirstBcnt =
+		ngbr_roam_info->cfgParams.nRoamBmissFirstBcnt;
+	ngbr_roam_info->currentRoamBmissFinalBcnt =
+		ngbr_roam_info->cfgParams.nRoamBmissFinalBcnt;
+	ngbr_roam_info->currentRoamBeaconRssiWeight =
+		ngbr_roam_info->cfgParams.nRoamBeaconRssiWeight;
+
+	/*
+	 * Now we can clear the preauthDone that
+	 * was saved as we are connected afresh
+	 */
+	csr_neighbor_roam_free_roamable_bss_list(pMac,
+		&ngbr_roam_info->FTRoamInfo.preAuthDoneList);
+
+	/* Based on the auth scheme tell if we are 11r */
+	if (csr_is_auth_type11r
+		(pMac, session->connectedProfile.AuthType,
+		session->connectedProfile.MDID.mdiePresent)) {
+		if (pMac->roam.configParam.isFastTransitionEnabled)
+			init_ft_flag = true;
+		ngbr_roam_info->is11rAssoc = true;
+	} else
+		ngbr_roam_info->is11rAssoc = false;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("11rAssoc is = %d"), ngbr_roam_info->is11rAssoc);
+
+#ifdef FEATURE_WLAN_ESE
+	/* Based on the auth scheme tell if we are 11r */
+	if (session->connectedProfile.isESEAssoc) {
+		if (pMac->roam.configParam.isFastTransitionEnabled)
+			init_ft_flag = true;
+		ngbr_roam_info->isESEAssoc = true;
+	} else
+		ngbr_roam_info->isESEAssoc = false;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("isESEAssoc is = %d ft = %d"),
+			ngbr_roam_info->isESEAssoc, init_ft_flag);
+#endif
+	/* If "Legacy Fast Roaming" is enabled */
+	if (csr_roam_is_fast_roam_enabled(pMac, session_id))
+		init_ft_flag = true;
+	if (init_ft_flag == false)
+		return;
+	/* Initialize all the data structures needed for the 11r FT Preauth */
+	ngbr_roam_info->FTRoamInfo.currentNeighborRptRetryNum = 0;
+	csr_neighbor_roam_purge_preauth_failed_list(pMac);
+	if (csr_roam_is_roam_offload_scan_enabled(pMac)) {
+		/*
+		 * If this is not a INFRA type BSS, then do not send the command
+		 * down to firmware.Do not send the START command for
+		 * other session connections.
+		 */
+		if (!csr_roam_is_sta_mode(pMac, session_id)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"Wrong Mode %d",
+				session->connectedProfile.BSSType);
+			return;
+		}
+		ngbr_roam_info->uOsRequestedHandoff = 0;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		if (session->roam_synch_in_progress) {
+			if (pMac->roam.pReassocResp != NULL) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_DEBUG,
+					"Free Reassoc Rsp");
+				qdf_mem_free(pMac->roam.pReassocResp);
+				pMac->roam.pReassocResp = NULL;
+			}
+		} else
+#endif
+		{
+			csr_roam_offload_scan(pMac, session_id,
+				ROAM_SCAN_OFFLOAD_START,
+				REASON_CTX_INIT);
+
+			if (roam_profile &&
+				roam_profile->supplicant_disabled_roaming) {
+				sme_debug("Supplicant disabled driver roaming");
+				csr_roam_offload_scan(pMac, session_id,
+					ROAM_SCAN_OFFLOAD_STOP,
+					REASON_SUPPLICANT_DISABLED_ROAMING);
+			}
+		}
+	}
+}
+
+/**
+ * csr_neighbor_roam_indicate_connect()
+ * @pMac: mac context
+ * @session_id: Session Id
+ * @qdf_status: QDF status
+ *
+ * This function is called by CSR as soon as the station connects to an AP.
+ * This initializes all the necessary data structures related to the
+ * associated AP and transitions the state to CONNECTED state
+ *
+ * Return: QDF status
+ */
+QDF_STATUS csr_neighbor_roam_indicate_connect(
+		tpAniSirGlobal pMac, uint8_t session_id,
+		QDF_STATUS qdf_status)
+{
+	tpCsrNeighborRoamControlInfo ngbr_roam_info =
+		&pMac->roam.neighborRoamInfo[session_id];
+	struct csr_roam_session *session = &pMac->roam.roamSession[session_id];
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	struct csr_roam_info roamInfo;
+#endif
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	/* if session id invalid then we need return failure */
+	if (NULL == ngbr_roam_info || !CSR_IS_SESSION_VALID(pMac, session_id)
+	|| (NULL == pMac->roam.roamSession[session_id].pCurRoamProfile)) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_debug("Connect ind. received with session id %d in state %s",
+		session_id, mac_trace_get_neighbour_roam_state(
+			ngbr_roam_info->neighborRoamState));
+
+	/* Bail out if this is NOT a STA persona */
+	if (pMac->roam.roamSession[session_id].pCurRoamProfile->csrPersona !=
+	QDF_STA_MODE) {
+		sme_err("Ignoring Connect ind received from a non STA. session_id: %d, csrPersonna %d",
+			session_id,
+			(int)session->pCurRoamProfile->csrPersona);
+		return QDF_STATUS_SUCCESS;
+	}
+	/* if a concurrent session is running */
+	if ((false ==
+		CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED(pMac)) &&
+		(csr_is_concurrent_session_running(pMac))) {
+		sme_err("Ignoring Connect ind. received in multisession %d",
+			csr_is_concurrent_session_running(pMac));
+		return QDF_STATUS_SUCCESS;
+	}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (session->roam_synch_in_progress &&
+		(eSIR_ROAM_AUTH_STATUS_AUTHENTICATED ==
+		session->roam_synch_data->authStatus)) {
+		sme_debug("LFR3: Authenticated");
+		qdf_copy_macaddr(&roamInfo.peerMac,
+			&session->connectedProfile.bssid);
+		roamInfo.roamSynchInProgress =
+			session->roam_synch_in_progress;
+		csr_roam_call_callback(pMac, session_id, &roamInfo, 0,
+			eCSR_ROAM_SET_KEY_COMPLETE,
+			eCSR_ROAM_RESULT_AUTHENTICATED);
+		csr_neighbor_roam_reset_init_state_control_info(pMac,
+			session_id);
+		csr_neighbor_roam_info_ctx_init(pMac, session_id);
+		return status;
+	}
+#endif
+
+	switch (ngbr_roam_info->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
+		if (QDF_STATUS_SUCCESS != qdf_status) {
+			/**
+			 * Just transition the state to INIT state.Rest of the
+			 * clean up happens when we get next connect indication
+			 */
+			csr_neighbor_roam_state_transition(pMac,
+				eCSR_NEIGHBOR_ROAM_STATE_INIT, session_id);
+			ngbr_roam_info->roamChannelInfo.
+					IAPPNeighborListReceived = false;
+			ngbr_roam_info->uOsRequestedHandoff = 0;
+			break;
+		}
+	/* Fall through if the status is SUCCESS */
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		/* Reset all the data structures here */
+		csr_neighbor_roam_reset_init_state_control_info(pMac,
+			session_id);
+		csr_neighbor_roam_info_ctx_init(pMac, session_id);
+		break;
+	default:
+		sme_err("Connect evt received in invalid state %s Ignoring",
+			mac_trace_get_neighbour_roam_state(
+			ngbr_roam_info->neighborRoamState));
+		break;
+	}
+	return status;
+}
+
+/*
+ * csr_neighbor_roam_init11r_assoc_info -
+ * This function initializes 11r related neighbor roam data structures
+ *
+ * @pMac: The handle returned by mac_open.
+ *
+ * return QDF_STATUS_SUCCESS on success, corresponding error code otherwise
+ */
+static QDF_STATUS csr_neighbor_roam_init11r_assoc_info(tpAniSirGlobal pMac)
+{
+	QDF_STATUS status;
+	uint8_t i;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+	tpCsr11rAssocNeighborInfo pFTRoamInfo = NULL;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[i];
+		pFTRoamInfo = &pNeighborRoamInfo->FTRoamInfo;
+
+		pNeighborRoamInfo->is11rAssoc = false;
+
+		pFTRoamInfo->neighborReportTimeout =
+			CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT;
+		pFTRoamInfo->PEPreauthRespTimeout =
+			CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER *
+			pNeighborRoamInfo->cfgParams.neighborScanPeriod;
+		pFTRoamInfo->neighborRptPending = false;
+		pFTRoamInfo->preauthRspPending = false;
+
+		pFTRoamInfo->currentNeighborRptRetryNum = 0;
+		pFTRoamInfo->numBssFromNeighborReport = 0;
+
+		qdf_mem_zero(pFTRoamInfo->neighboReportBssInfo,
+			     sizeof(tCsrNeighborReportBssInfo) *
+			     MAX_BSS_IN_NEIGHBOR_RPT);
+
+		status = csr_ll_open(&pFTRoamInfo->preAuthDoneList);
+		if (QDF_STATUS_SUCCESS != status) {
+			sme_err("LL Open of preauth done AP List failed");
+			return QDF_STATUS_E_RESOURCES;
+		}
+	}
+	return status;
+}
+
+/*
+ * csr_neighbor_roam_init() -
+ * This function initializes neighbor roam data structures
+ *
+ * @pMac: The handle returned by mac_open.
+ * sessionId: Session identifier
+ *
+ * Return QDF_STATUS_SUCCESS on success, corresponding error code otherwise
+ */
+QDF_STATUS csr_neighbor_roam_init(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	QDF_STATUS status;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
+	pNeighborRoamInfo->prevNeighborRoamState =
+		eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
+	pNeighborRoamInfo->cfgParams.maxChannelScanTime =
+		pMac->roam.configParam.neighborRoamConfig.
+		nNeighborScanMaxChanTime;
+	pNeighborRoamInfo->cfgParams.minChannelScanTime =
+		pMac->roam.configParam.neighborRoamConfig.
+		nNeighborScanMinChanTime;
+	pNeighborRoamInfo->cfgParams.neighborLookupThreshold =
+		pMac->roam.configParam.neighborRoamConfig.
+		nNeighborLookupRssiThreshold;
+	pNeighborRoamInfo->cfgParams.rssi_thresh_offset_5g =
+		pMac->mlme_cfg->lfr.rssi_threshold_offset_5g;
+	pNeighborRoamInfo->cfgParams.delay_before_vdev_stop =
+		pMac->roam.configParam.neighborRoamConfig.
+		delay_before_vdev_stop;
+	pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff =
+		pMac->roam.configParam.neighborRoamConfig.
+		nOpportunisticThresholdDiff;
+	pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff =
+		pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff;
+	pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt =
+		pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt;
+	pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt =
+		pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt;
+	pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight =
+		pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight;
+	pNeighborRoamInfo->cfgParams.neighborScanPeriod =
+		pMac->roam.configParam.neighborRoamConfig.
+		nNeighborScanTimerPeriod;
+	pNeighborRoamInfo->cfgParams.neighbor_scan_min_period =
+		pMac->roam.configParam.neighborRoamConfig.
+		neighbor_scan_min_timer_period;
+	pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod =
+		pMac->roam.configParam.neighborRoamConfig.
+		nNeighborResultsRefreshPeriod;
+	pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod =
+		pMac->roam.configParam.neighborRoamConfig.
+		nEmptyScanRefreshPeriod;
+
+	pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels =
+		pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
+		numChannels;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("number of channels: %u"),
+			pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels);
+	if (pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels != 0) {
+		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
+		qdf_mem_malloc(pMac->roam.configParam.neighborRoamConfig.
+				neighborScanChanList.numChannels);
+		if (!pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
+			return QDF_STATUS_E_NOMEM;
+
+	} else {
+		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
+	}
+
+	/* Update the roam global structure from CFG */
+	qdf_mem_copy(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
+		     pMac->roam.configParam.neighborRoamConfig.
+		     neighborScanChanList.channelList,
+		     pMac->roam.configParam.neighborRoamConfig.
+		     neighborScanChanList.numChannels);
+	pNeighborRoamInfo->cfgParams.hi_rssi_scan_max_count =
+		pMac->roam.configParam.neighborRoamConfig.
+			nhi_rssi_scan_max_count;
+	pNeighborRoamInfo->cfgParams.hi_rssi_scan_rssi_delta =
+		pMac->roam.configParam.neighborRoamConfig.
+			nhi_rssi_scan_rssi_delta;
+	pNeighborRoamInfo->cfgParams.hi_rssi_scan_delay =
+		pMac->roam.configParam.neighborRoamConfig.
+			nhi_rssi_scan_delay;
+	pNeighborRoamInfo->cfgParams.hi_rssi_scan_rssi_ub =
+		pMac->roam.configParam.neighborRoamConfig.
+			nhi_rssi_scan_rssi_ub;
+
+	qdf_zero_macaddr(&pNeighborRoamInfo->currAPbssid);
+	pNeighborRoamInfo->currentNeighborLookupThreshold =
+		pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
+	pNeighborRoamInfo->currentOpportunisticThresholdDiff =
+		pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff;
+	pNeighborRoamInfo->currentRoamRescanRssiDiff =
+		pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff;
+	pNeighborRoamInfo->currentRoamBmissFirstBcnt =
+		pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt;
+	pNeighborRoamInfo->currentRoamBmissFinalBcnt =
+		pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt;
+	pNeighborRoamInfo->currentRoamBeaconRssiWeight =
+		pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight;
+	qdf_mem_set(&pNeighborRoamInfo->prevConnProfile,
+		    sizeof(tCsrRoamConnectedProfile), 0);
+
+	status = csr_ll_open(&pNeighborRoamInfo->roamableAPList);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("LL Open of roam able AP List failed");
+		qdf_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.
+			     ChannelList);
+		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	pNeighborRoamInfo->roamChannelInfo.currentChanIndex =
+		CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+	numOfChannels = 0;
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList =
+		NULL;
+	pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false;
+
+	status = csr_neighbor_roam_init11r_assoc_info(pMac);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("LL Open of roam able AP List failed");
+		qdf_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.
+			     ChannelList);
+		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
+		csr_ll_close(&pNeighborRoamInfo->roamableAPList);
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	csr_neighbor_roam_state_transition(pMac,
+			eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId);
+	pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false;
+	pNeighborRoamInfo->uOsRequestedHandoff = 0;
+	/* Set the Last Sent Cmd as RSO_STOP */
+	pNeighborRoamInfo->last_sent_cmd = ROAM_SCAN_OFFLOAD_STOP;
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * csr_neighbor_roam_close() -
+ * This function closes/frees all the neighbor roam data structures
+ *
+ * @pMac: The handle returned by mac_open.
+ * @sessionId: Session identifier
+ *
+ * Return VOID
+ */
+void csr_neighbor_roam_close(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED ==
+	    pNeighborRoamInfo->neighborRoamState) {
+		sme_warn("Neighbor Roam Algorithm Already Closed");
+		return;
+	}
+
+	if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
+		qdf_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.
+			     ChannelList);
+
+	pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
+
+	/* Should free up the nodes in the list before closing the
+	 * double Linked list
+	 */
+	csr_neighbor_roam_free_roamable_bss_list(pMac,
+					&pNeighborRoamInfo->roamableAPList);
+	csr_ll_close(&pNeighborRoamInfo->roamableAPList);
+
+	if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+	    ChannelList) {
+		qdf_mem_free(pNeighborRoamInfo->roamChannelInfo.
+			     currentChannelListInfo.ChannelList);
+	}
+
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList =
+		NULL;
+	pNeighborRoamInfo->roamChannelInfo.currentChanIndex =
+		CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+	numOfChannels = 0;
+	pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false;
+
+	/* Free the profile.. */
+	csr_release_profile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
+	csr_roam_free_connect_profile(&pNeighborRoamInfo->prevConnProfile);
+	pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
+	pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
+	qdf_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo,
+		     sizeof(tCsrNeighborReportBssInfo) *
+		     MAX_BSS_IN_NEIGHBOR_RPT);
+	csr_neighbor_roam_free_roamable_bss_list(pMac,
+						 &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);
+
+}
+
+/**
+ * csr_neighbor_roam_is11r_assoc() - Check if association type is 11R
+ * @mac_ctx: MAC Global context
+ * @session_id: Session ID
+ *
+ * Return: true if 11r Association, false otherwise.
+ */
+bool csr_neighbor_roam_is11r_assoc(tpAniSirGlobal mac_ctx, uint8_t session_id)
+{
+	return mac_ctx->roam.neighborRoamInfo[session_id].is11rAssoc;
+}
+
+/*
+ * csr_neighbor_middle_of_roaming() -
+ * This function returns true if STA is in the middle of roaming states
+ *
+ * @halHandle: The handle from HDD context.
+ * @sessionId: Session identifier
+ *
+ * Return bool
+ */
+bool csr_neighbor_middle_of_roaming(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	bool val = (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING ==
+		    pNeighborRoamInfo->neighborRoamState) ||
+		   (eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING ==
+		    pNeighborRoamInfo->neighborRoamState) ||
+		   (eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE ==
+		    pNeighborRoamInfo->neighborRoamState);
+	return val;
+}
+
+/**
+ * csr_neighbor_roam_process_handoff_req - Processes handoff request
+ *
+ * @mac_ctx  Pointer to mac context
+ * @session_id  SME session id
+ *
+ * This function is called start with the handoff process. First do a
+ * SSID scan for the BSSID provided.
+ *
+ * Return: status
+ */
+static QDF_STATUS csr_neighbor_roam_process_handoff_req(
+			tpAniSirGlobal mac_ctx,
+			uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo roam_ctrl_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t roam_id;
+	struct csr_roam_profile *profile = NULL;
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+	uint8_t i = 0;
+	uint8_t roam_now = 0;
+	uint8_t roamable_ap_count = 0;
+	tCsrScanResultFilter    scan_filter;
+	tScanResultHandle       scan_result;
+
+	if (NULL == session) {
+		sme_err("session is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam);
+	profile = qdf_mem_malloc(sizeof(struct csr_roam_profile));
+	if (!profile)
+		return QDF_STATUS_E_NOMEM;
+
+	status =
+		csr_roam_copy_profile(mac_ctx, profile,
+				      session->pCurRoamProfile);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Profile copy failed");
+		goto end;
+	}
+	/* Add the BSSID & Channel */
+	profile->BSSIDs.numOfBSSIDs = 1;
+	if (NULL == profile->BSSIDs.bssid) {
+		profile->BSSIDs.bssid =
+			qdf_mem_malloc(sizeof(tSirMacAddr) *
+				profile->BSSIDs.numOfBSSIDs);
+		if (!profile->BSSIDs.bssid) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+	}
+
+	/* Populate the BSSID from handoff info received from HDD */
+	for (i = 0; i < profile->BSSIDs.numOfBSSIDs; i++) {
+		qdf_copy_macaddr(&profile->BSSIDs.bssid[i],
+				&roam_ctrl_info->handoffReqInfo.bssid);
+	}
+
+	profile->ChannelInfo.numOfChannels = 1;
+	if (NULL == profile->ChannelInfo.ChannelList) {
+		profile->ChannelInfo.ChannelList =
+			qdf_mem_malloc(sizeof(*profile->
+				ChannelInfo.ChannelList) *
+				profile->ChannelInfo.numOfChannels);
+		if (!profile->ChannelInfo.ChannelList) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+	}
+	profile->ChannelInfo.ChannelList[0] =
+		roam_ctrl_info->handoffReqInfo.channel;
+
+	/*
+	 * For User space connect requests, the scan has already been done.
+	 * So, check if the BSS descriptor exists in the scan cache and
+	 * proceed with the handoff instead of a redundant scan again.
+	 */
+	if (roam_ctrl_info->handoffReqInfo.src == CONNECT_CMD_USERSPACE) {
+		sme_debug("Connect cmd with bssid within same ESS");
+		status = csr_neighbor_roam_prepare_scan_profile_filter(mac_ctx,
+								&scan_filter,
+								session_id);
+		sme_debug("Filter creation status: %d", status);
+		status = csr_scan_get_result(mac_ctx, &scan_filter,
+					     &scan_result);
+		csr_neighbor_roam_process_scan_results(mac_ctx, session_id,
+							&scan_result);
+		roamable_ap_count = csr_ll_count(
+					&roam_ctrl_info->roamableAPList);
+		csr_free_scan_filter(mac_ctx, &scan_filter);
+		sme_debug("roam_now=%d, roamable_ap_count=%d",
+			roam_now, roamable_ap_count);
+	}
+	if (roam_now && roamable_ap_count) {
+		csr_neighbor_roam_trigger_handoff(mac_ctx, session_id);
+	} else {
+		status = csr_scan_for_ssid(mac_ctx, session_id, profile,
+					   roam_id, false);
+		if (status != QDF_STATUS_SUCCESS)
+			sme_err("SSID scan failed");
+	}
+
+end:
+	if (NULL != profile) {
+		csr_release_profile(mac_ctx, profile);
+		qdf_mem_free(profile);
+	}
+
+	return status;
+}
+
+/*
+ * csr_neighbor_roam_sssid_scan_done() -
+ * This function is called once SSID scan is done. If SSID scan failed
+ * to find our candidate add an entry to csr scan cache ourself before starting
+ * the handoff process
+
+ * @pMac: The handle returned by mac_open.
+ * @session_id  SME session id
+ *
+ * Return QDF_STATUS_SUCCESS on success, corresponding error code otherwise
+ */
+QDF_STATUS csr_neighbor_roam_sssid_scan_done(tpAniSirGlobal pMac,
+					   uint8_t sessionId, QDF_STATUS status)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	QDF_STATUS hstatus;
+
+	/* we must be in connected state, if not ignore it */
+	if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED !=
+	    pNeighborRoamInfo->neighborRoamState) {
+		sme_err("Received in not CONNECTED state. Ignore it");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* if SSID scan failed to find our candidate add an entry to
+	 * csr scan cache ourself
+	 */
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("Add an entry to csr scan cache");
+		hstatus = csr_scan_create_entry_in_scan_cache(pMac, sessionId,
+							pNeighborRoamInfo->
+							handoffReqInfo.bssid,
+							pNeighborRoamInfo->
+							handoffReqInfo.channel);
+		if (QDF_STATUS_SUCCESS != hstatus) {
+			sme_err(
+				"csr_scan_create_entry_in_scan_cache failed with status %d",
+				hstatus);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	/* Now we have completed scanning for the candidate provided by HDD.
+	 * Let move on to HO
+	 */
+	hstatus = csr_neighbor_roam_process_scan_complete(pMac, sessionId);
+
+	if (QDF_STATUS_SUCCESS != hstatus) {
+		sme_err("Neighbor scan process complete failed with status %d",
+			hstatus);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+
+/**
+ * csr_neighbor_roam_handoff_req_hdlr - Processes handoff request
+ * @mac_ctx  Pointer to mac context
+ * @msg  message sent to HDD
+ *
+ * This function is called by CSR as soon as it gets a handoff request
+ * to SME via MC thread
+ *
+ * Return: status
+ */
+QDF_STATUS csr_neighbor_roam_handoff_req_hdlr(
+			tpAniSirGlobal mac_ctx, void *msg)
+{
+	tAniHandoffReq *handoff_req = (tAniHandoffReq *) msg;
+	uint32_t session_id = handoff_req->sessionId;
+	tpCsrNeighborRoamControlInfo roam_ctrl_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	/* we must be in connected state, if not ignore it */
+	if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED !=
+		roam_ctrl_info->neighborRoamState) {
+		sme_err("Received in not CONNECTED state. Ignore it");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* save the handoff info came from HDD as part of the reassoc req */
+	handoff_req = (tAniHandoffReq *) msg;
+	if (NULL == handoff_req) {
+		sme_err("Received msg is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* sanity check */
+	if (!qdf_mem_cmp(handoff_req->bssid,
+		roam_ctrl_info->currAPbssid.bytes,
+		sizeof(tSirMacAddr))) {
+		sme_err("Received req has same BSSID as current AP!!");
+		return QDF_STATUS_E_FAILURE;
+	}
+	roam_ctrl_info->handoffReqInfo.channel =
+		handoff_req->channel;
+	roam_ctrl_info->handoffReqInfo.src =
+		handoff_req->handoff_src;
+	qdf_mem_copy(&roam_ctrl_info->handoffReqInfo.bssid.bytes,
+			&handoff_req->bssid, QDF_MAC_ADDR_SIZE);
+	roam_ctrl_info->uOsRequestedHandoff = 1;
+	status = csr_roam_offload_scan(mac_ctx, session_id,
+		ROAM_SCAN_OFFLOAD_STOP,
+		REASON_OS_REQUESTED_ROAMING_NOW);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("csr_roam_offload_scan failed");
+		roam_ctrl_info->uOsRequestedHandoff = 0;
+	}
+	return status;
+}
+
+/**
+ * csr_neighbor_roam_proceed_with_handoff_req()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ *
+ * This function is called by CSR as soon as it gets rsp back for
+ * ROAM_SCAN_OFFLOAD_STOP with reason REASON_OS_REQUESTED_ROAMING_NOW
+ *
+ * Return: QDF_STATUS_SUCCESS on success, corresponding error code otherwise
+ */
+QDF_STATUS csr_neighbor_roam_proceed_with_handoff_req(tpAniSirGlobal pMac,
+						      uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	/* we must be in connected state, if not ignore it */
+	if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED !=
+	     pNeighborRoamInfo->neighborRoamState)
+	    || (!pNeighborRoamInfo->uOsRequestedHandoff)) {
+		sme_err(
+			"Received in not CONNECTED state(%d) or uOsRequestedHandoff(%d) is not set. Ignore it",
+			pNeighborRoamInfo->neighborRoamState,
+			pNeighborRoamInfo->uOsRequestedHandoff);
+		status = QDF_STATUS_E_FAILURE;
+	} else
+		/* Let's go ahead with handoff */
+		status = csr_neighbor_roam_process_handoff_req(pMac, sessionId);
+
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		pNeighborRoamInfo->uOsRequestedHandoff = 0;
+
+	return status;
+}
+
+/*
+ * csr_neighbor_roam_start_lfr_scan() -
+ * This function is called if HDD requested handoff failed for some
+ * reason. start the LFR logic at that point.By the time, this function is
+ * called, a STOP command has already been issued.
+
+ * @pMac: The handle returned by mac_open.
+ * @session_id: Session ID
+ *
+ * Return QDF_STATUS_SUCCESS on success, corresponding error code otherwise
+ */
+QDF_STATUS csr_neighbor_roam_start_lfr_scan(tpAniSirGlobal pMac,
+						uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	pNeighborRoamInfo->uOsRequestedHandoff = 0;
+	/* There is no candidate or We are not roaming Now.
+	 * Inform the FW to restart Roam Offload Scan
+	 */
+	csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START,
+			      REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+
+	return QDF_STATUS_SUCCESS;
+
+
+
+}
diff --git a/core/sme/src/csr/csr_roam_preauth.c b/core/sme/src/csr/csr_roam_preauth.c
new file mode 100644
index 0000000..376a0c8
--- /dev/null
+++ b/core/sme/src/csr/csr_roam_preauth.c
@@ -0,0 +1,770 @@
+/*
+ * Copyright (c) 2016-2018 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: csr_roam_preauth.c
+ *
+ * Host based roaming preauthentication implementation
+ */
+
+#include "wma_types.h"
+#include "csr_inside_api.h"
+#include "sme_qos_internal.h"
+#include "sme_inside.h"
+#include "host_diag_core_event.h"
+#include "host_diag_core_log.h"
+#include "csr_api.h"
+#include "sme_api.h"
+#include "csr_neighbor_roam.h"
+#include "mac_trace.h"
+#include "wlan_policy_mgr_api.h"
+#include "sir_api.h"
+
+static QDF_STATUS csr_neighbor_roam_add_preauth_fail(tpAniSirGlobal mac_ctx,
+			uint8_t session_id, tSirMacAddr bssid);
+
+/**
+ * csr_neighbor_roam_state_preauth_done() - Check if state is preauth done
+ * @mac_ctx: Global MAC context
+ * @session_id: SME session ID
+ *
+ * Return: True if the state id preauth done, false otherwise
+ */
+bool csr_neighbor_roam_state_preauth_done(tpAniSirGlobal mac_ctx,
+		uint8_t session_id)
+{
+	return mac_ctx->roam.neighborRoamInfo[session_id].neighborRoamState ==
+		eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE;
+}
+
+/**
+ * csr_neighbor_roam_tranistion_preauth_done_to_disconnected() - Transition
+ * the state from preauth done to disconnected
+ * @mac_ctx: Global MAC Context
+ * @session_id: SME Session ID
+ *
+ * In the event that we are associated with AP1 and we have
+ * completed pre auth with AP2. Then we receive a deauth/disassoc from AP1.
+ * At this point neighbor roam is in pre auth done state, pre auth timer
+ * is running. We now handle this case by stopping timer and clearing
+ * the pre-auth state. We basically clear up and just go to disconnected
+ * state
+ *
+ * Return: None
+ */
+void csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+		tpAniSirGlobal mac_ctx, uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (!session) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("session is NULL"));
+		return;
+	}
+
+	if (pNeighborRoamInfo->neighborRoamState !=
+	    eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
+		return;
+
+	qdf_mc_timer_stop(&session->ftSmeContext.preAuthReassocIntvlTimer);
+	csr_neighbor_roam_state_transition(mac_ctx,
+		eCSR_NEIGHBOR_ROAM_STATE_INIT, session_id);
+	pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false;
+	pNeighborRoamInfo->uOsRequestedHandoff = 0;
+}
+
+/**
+ * csr_roam_enqueue_preauth() - Put the preauth command in the queue
+ * @mac_ctx: Global MAC Context
+ * @session_id: SME Session ID
+ * @bss_desc: BSS descriptor
+ * @reason: roaming reason
+ * @immediate: High priority in the queue or not
+ *
+ * Return: Success if queued properly, false otherwise.
+ */
+QDF_STATUS csr_roam_enqueue_preauth(tpAniSirGlobal mac_ctx,
+		uint32_t session_id, tpSirBssDescription bss_desc,
+		enum csr_roam_reason reason, bool immediate)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tSmeCmd *command;
+
+	command = csr_get_command_buffer(mac_ctx);
+	if (NULL == command) {
+		sme_err("fail to get command buffer");
+		status = QDF_STATUS_E_RESOURCES;
+	} else {
+		if (bss_desc) {
+			command->command = eSmeCommandRoam;
+			command->sessionId = (uint8_t) session_id;
+			command->u.roamCmd.roamReason = reason;
+			command->u.roamCmd.pLastRoamBss = bss_desc;
+			status = csr_queue_sme_command(mac_ctx, command,
+					immediate);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				sme_err("fail to queue preauth,status: %d",
+					status);
+			}
+		} else {
+			status = QDF_STATUS_E_RESOURCES;
+		}
+	}
+	return status;
+}
+
+/**
+ * csr_neighbor_roam_purge_preauth_failed_list() - Purge the preauth fail list
+ * @mac_ctx: Global MAC Context
+ *
+ * Return: None
+ */
+void csr_neighbor_roam_purge_preauth_failed_list(tpAniSirGlobal mac_ctx)
+{
+	uint8_t i;
+	uint8_t j;
+	uint8_t num_mac_addr;
+	tpCsrNeighborRoamControlInfo neigh_roam_info = NULL;
+	tpCsrPreauthFailListInfo fail_list;
+
+	for (j = 0; j < CSR_ROAM_SESSION_MAX; j++) {
+		neigh_roam_info = &mac_ctx->roam.neighborRoamInfo[j];
+		fail_list = &neigh_roam_info->FTRoamInfo.preAuthFailList;
+		num_mac_addr = fail_list->numMACAddress;
+		for (i = 0; i < num_mac_addr; i++)
+			qdf_mem_zero(fail_list->macAddress[i],
+					sizeof(tSirMacAddr));
+		fail_list->numMACAddress = 0;
+	}
+}
+
+/**
+ * @csr_neighbor_roam_reset_preauth_control_info - Reset preauth info
+ * @mac_ctx: Global MAC Context
+ * @session_id: SME Session ID
+ *
+ * Return: None
+ */
+void csr_neighbor_roam_reset_preauth_control_info(tpAniSirGlobal mac_ctx,
+		uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo neigh_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+
+	neigh_roam_info->is11rAssoc = false;
+	csr_neighbor_roam_purge_preauth_failed_list(mac_ctx);
+
+	neigh_roam_info->FTRoamInfo.preauthRspPending = false;
+	neigh_roam_info->FTRoamInfo.numPreAuthRetries = 0;
+	neigh_roam_info->FTRoamInfo.currentNeighborRptRetryNum = 0;
+	neigh_roam_info->FTRoamInfo.neighborRptPending = false;
+	neigh_roam_info->FTRoamInfo.numBssFromNeighborReport = 0;
+	qdf_mem_zero(neigh_roam_info->FTRoamInfo.neighboReportBssInfo,
+		     sizeof(tCsrNeighborReportBssInfo) *
+		     MAX_BSS_IN_NEIGHBOR_RPT);
+	neigh_roam_info->uOsRequestedHandoff = 0;
+	qdf_mem_zero(&neigh_roam_info->handoffReqInfo,
+		     sizeof(tCsrHandoffRequest));
+}
+
+/**
+ * csr_neighbor_roam_preauth_rsp_handler() - handle preauth response
+ * @mac_ctx: The handle returned by mac_open.
+ * @session_id: SME session
+ * @lim_status: QDF_STATUS_SUCCESS/QDF_STATUS_E_FAILURE/QDF_STATUS_E_NOSPC/
+ *              eSIT_LIM_AUTH_RSP_TIMEOUT status from PE
+ *
+ * This function handle the Preauth response from PE
+ * Every preauth is allowed max 3 tries if it fails. If a bssid failed
+ * for more than MAX_TRIES, we will remove it from the list and try
+ * with the next node in the roamable AP list and add the BSSID to
+ * pre-auth failed list. If no more entries present in roamable AP list,
+ * transition to REPORT_SCAN state.
+ *
+ * Return: QDF_STATUS_SUCCESS on success (i.e. pre-auth processed),
+ *         QDF_STATUS_E_FAILURE otherwise
+ */
+QDF_STATUS csr_neighbor_roam_preauth_rsp_handler(tpAniSirGlobal mac_ctx,
+						 uint8_t session_id,
+						 QDF_STATUS lim_status)
+{
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS preauth_processed = QDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamBSSInfo preauth_rsp_node = NULL;
+
+	if (false == neighbor_roam_info->FTRoamInfo.preauthRspPending) {
+		/*
+		 * This can happen when we disconnect immediately
+		 * after sending a pre-auth request. During processing
+		 * of the disconnect command, we would have reset
+		 * preauthRspPending and transitioned to INIT state.
+		 */
+		sme_warn("Unexpected pre-auth response in state %d",
+			neighbor_roam_info->neighborRoamState);
+		preauth_processed = QDF_STATUS_E_FAILURE;
+		goto DEQ_PREAUTH;
+	}
+	/* We can receive it in these 2 states. */
+	if ((neighbor_roam_info->neighborRoamState !=
+	     eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING)) {
+		sme_debug("Preauth response received in state %s",
+			mac_trace_get_neighbour_roam_state
+				(neighbor_roam_info->neighborRoamState));
+		preauth_processed = QDF_STATUS_E_FAILURE;
+		goto DEQ_PREAUTH;
+	}
+
+	neighbor_roam_info->FTRoamInfo.preauthRspPending = false;
+
+	if (QDF_STATUS_SUCCESS == lim_status)
+		preauth_rsp_node =
+			csr_neighbor_roam_next_roamable_ap(
+				mac_ctx, &neighbor_roam_info->roamableAPList,
+				NULL);
+	if ((QDF_STATUS_SUCCESS == lim_status) && (NULL != preauth_rsp_node)) {
+		sme_debug("Preauth completed successfully after %d tries",
+			neighbor_roam_info->FTRoamInfo.numPreAuthRetries);
+		sme_debug("After Pre-Auth: BSSID " MAC_ADDRESS_STR ", Ch:%d",
+			MAC_ADDR_ARRAY(
+				preauth_rsp_node->pBssDescription->bssId),
+			(int)preauth_rsp_node->pBssDescription->channelId);
+
+		csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
+			preauth_rsp_node->pBssDescription->bssId,
+			eCSR_ROAM_PREAUTH_STATUS_SUCCESS);
+		/*
+		 * Preauth completed successfully. Insert the preauthenticated
+		 * node to tail of preAuthDoneList.
+		 */
+		csr_neighbor_roam_remove_roamable_ap_list_entry(mac_ctx,
+			&neighbor_roam_info->roamableAPList,
+			preauth_rsp_node);
+		csr_ll_insert_tail(
+			&neighbor_roam_info->FTRoamInfo.preAuthDoneList,
+			&preauth_rsp_node->List, LL_ACCESS_LOCK);
+
+		csr_neighbor_roam_state_transition(mac_ctx,
+			eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE, session_id);
+		neighbor_roam_info->FTRoamInfo.numPreAuthRetries = 0;
+
+		/*
+		 * The caller of this function would start a timer and by
+		 * the time it expires, supplicant should have provided
+		 * the updated FTIEs to SME. So, when it expires, handoff
+		 * will be triggered then.
+		 */
+	} else {
+		tpCsrNeighborRoamBSSInfo neighbor_bss_node = NULL;
+		tListElem *entry;
+		bool is_dis_pending = false;
+
+		sme_err("Preauth failed retry number %d, status: 0x%x",
+			neighbor_roam_info->FTRoamInfo.numPreAuthRetries,
+			lim_status);
+
+		/*
+		 * Preauth failed. Add the bssId to the preAuth failed list
+		 * of MAC Address. Also remove the AP from roamable AP list.
+		 */
+		if ((neighbor_roam_info->FTRoamInfo.numPreAuthRetries >=
+		     CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES) ||
+		    (QDF_STATUS_E_NOSPC == lim_status)) {
+			/*
+			 * We are going to remove the node as it fails for
+			 * more than MAX tries. Reset this count to 0
+			 */
+			neighbor_roam_info->FTRoamInfo.numPreAuthRetries = 0;
+
+			/*
+			 * The one in the head of the list should be one with
+			 * which we issued pre-auth and failed
+			 */
+			entry = csr_ll_remove_head(
+					&neighbor_roam_info->roamableAPList,
+					LL_ACCESS_LOCK);
+			if (!entry) {
+				sme_err("Preauth list is empty");
+				goto NEXT_PREAUTH;
+			}
+			neighbor_bss_node = GET_BASE_ADDR(entry,
+					tCsrNeighborRoamBSSInfo,
+					List);
+			/*
+			 * Add the BSSID to pre-auth fail list if
+			 * it is not requested by HDD
+			 */
+			if (!neighbor_roam_info->uOsRequestedHandoff)
+				status =
+					csr_neighbor_roam_add_preauth_fail(
+						mac_ctx, session_id,
+						neighbor_bss_node->
+							pBssDescription->bssId);
+			csr_neighbor_roam_send_lfr_metric_event(mac_ctx,
+				session_id,
+				neighbor_bss_node->pBssDescription->bssId,
+				eCSR_ROAM_PREAUTH_STATUS_FAILURE);
+			/* Now we can free this node */
+			csr_neighbor_roam_free_neighbor_roam_bss_node(
+				mac_ctx, neighbor_bss_node);
+		}
+NEXT_PREAUTH:
+		is_dis_pending = is_disconnect_pending(mac_ctx, session_id);
+		if (is_dis_pending) {
+			sme_err("Disconnect in progress, Abort preauth");
+			goto ABORT_PREAUTH;
+		}
+		/* Issue preauth request for the same/next entry */
+		if (QDF_STATUS_SUCCESS == csr_neighbor_roam_issue_preauth_req(
+						mac_ctx, session_id))
+			goto DEQ_PREAUTH;
+ABORT_PREAUTH:
+		if (csr_roam_is_roam_offload_scan_enabled(mac_ctx)) {
+			if (neighbor_roam_info->uOsRequestedHandoff) {
+				neighbor_roam_info->uOsRequestedHandoff = 0;
+				csr_roam_offload_scan(mac_ctx, session_id,
+					ROAM_SCAN_OFFLOAD_START,
+					REASON_PREAUTH_FAILED_FOR_ALL);
+			} else {
+				csr_roam_offload_scan(mac_ctx, session_id,
+					ROAM_SCAN_OFFLOAD_RESTART,
+					REASON_PREAUTH_FAILED_FOR_ALL);
+			}
+			csr_neighbor_roam_state_transition(mac_ctx,
+				eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, session_id);
+		}
+	}
+
+DEQ_PREAUTH:
+	csr_dequeue_roam_command(mac_ctx, eCsrPerformPreauth, session_id);
+	return preauth_processed;
+}
+
+/**
+ * csr_neighbor_roam_add_preauth_fail() - add bssid to preauth failed list
+ * @mac_ctx: The handle returned by mac_open.
+ * @bssid: BSSID to be added to the preauth fail list
+ *
+ * This function adds the given BSSID to the Preauth fail list
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
+ */
+static QDF_STATUS csr_neighbor_roam_add_preauth_fail(tpAniSirGlobal mac_ctx,
+			uint8_t session_id, tSirMacAddr bssid)
+{
+	uint8_t i = 0;
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	uint8_t num_mac_addr = neighbor_roam_info->FTRoamInfo.preAuthFailList.
+				numMACAddress;
+
+	sme_warn("Added BSSID " MAC_ADDRESS_STR " to Preauth failed list",
+		MAC_ADDR_ARRAY(bssid));
+
+	for (i = 0;
+	     i < neighbor_roam_info->FTRoamInfo.preAuthFailList.numMACAddress;
+	     i++) {
+		if (!qdf_mem_cmp(
+		   neighbor_roam_info->FTRoamInfo.preAuthFailList.macAddress[i],
+		   bssid, sizeof(tSirMacAddr))) {
+			sme_warn("BSSID "MAC_ADDRESS_STR" already fail list",
+			MAC_ADDR_ARRAY(bssid));
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	if ((num_mac_addr + 1) > MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS) {
+		sme_err("Cannot add, preauth fail list is full");
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_copy(neighbor_roam_info->FTRoamInfo.preAuthFailList.
+		     macAddress[num_mac_addr], bssid, sizeof(tSirMacAddr));
+	neighbor_roam_info->FTRoamInfo.preAuthFailList.numMACAddress++;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_neighbor_roam_is_preauth_candidate()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @bssId : BSSID of the candidate
+ *
+ * This function checks whether the given MAC address is already present
+ * in the preauth fail list and returns true/false accordingly
+ *
+ * Return: true if preauth candidate, false otherwise
+ */
+bool csr_neighbor_roam_is_preauth_candidate(tpAniSirGlobal pMac,
+		    uint8_t sessionId, tSirMacAddr bssId)
+{
+	uint8_t i = 0;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	if (csr_roam_is_roam_offload_scan_enabled(pMac))
+		return true;
+	if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
+		return true;
+
+	for (i = 0;
+	     i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress;
+	     i++) {
+		if (!qdf_mem_cmp(pNeighborRoamInfo->FTRoamInfo.
+				    preAuthFailList.macAddress[i], bssId,
+				    sizeof(tSirMacAddr))) {
+			sme_err("BSSID exists in fail list" MAC_ADDRESS_STR,
+					MAC_ADDR_ARRAY(bssId));
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/**
+ * csr_get_dot11_mode() - Derives dot11mode
+ * @mac_ctx: Global MAC context
+ * @session_id: SME Session ID
+ * @bss_desc: BSS descriptor
+ *
+ * Return: dot11mode
+ */
+static uint32_t csr_get_dot11_mode(tpAniSirGlobal mac_ctx,
+				   uint32_t session_id,
+				   tpSirBssDescription bss_desc)
+{
+	struct csr_roam_session *csr_session = CSR_GET_SESSION(mac_ctx,
+				session_id);
+	enum csr_cfgdot11mode ucfg_dot11_mode, cfg_dot11_mode;
+	QDF_STATUS status;
+	tDot11fBeaconIEs *ies_local = NULL;
+	uint32_t dot11mode = 0;
+
+	if (!csr_session) {
+		sme_err("Invalid session id %d", session_id);
+		return 0;
+	}
+
+	sme_debug("phyMode %d", csr_session->pCurRoamProfile->phyMode);
+
+	/* Get IE's */
+	status = csr_get_parsed_bss_description_ies(mac_ctx, bss_desc,
+							&ies_local);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_err("csr_get_parsed_bss_description_ies failed");
+		return 0;
+	}
+	if (ies_local == NULL) {
+		sme_err("ies_local is NULL");
+		return 0;
+	}
+
+	if (csr_is_phy_mode_match(mac_ctx,
+			csr_session->pCurRoamProfile->phyMode,
+			bss_desc, csr_session->pCurRoamProfile,
+			&cfg_dot11_mode, ies_local))
+		ucfg_dot11_mode = cfg_dot11_mode;
+	else {
+		sme_err("Can not find match phy mode");
+		if (WLAN_REG_IS_5GHZ_CH(bss_desc->channelId))
+			ucfg_dot11_mode = eCSR_CFG_DOT11_MODE_11A;
+		else
+			ucfg_dot11_mode = eCSR_CFG_DOT11_MODE_11G;
+	}
+
+	/* dot11mode */
+	dot11mode = csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
+							ucfg_dot11_mode);
+	sme_debug("dot11mode %d ucfg_dot11_mode %d",
+			dot11mode, ucfg_dot11_mode);
+
+	if (bss_desc->channelId <= 14 &&
+		!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band &&
+		WNI_CFG_DOT11_MODE_11AC == dot11mode) {
+		/* Need to disable VHT operation in 2.4 GHz band */
+		dot11mode = WNI_CFG_DOT11_MODE_11N;
+	}
+	qdf_mem_free(ies_local);
+	return dot11mode;
+}
+
+QDF_STATUS csr_roam_issue_ft_preauth_req(tpAniSirGlobal mac_ctx,
+					 uint32_t session_id,
+					 tpSirBssDescription bss_desc)
+{
+	tpSirFTPreAuthReq preauth_req;
+	uint16_t auth_req_len = 0;
+	struct csr_roam_session *csr_session = CSR_GET_SESSION(mac_ctx,
+				session_id);
+
+	if (NULL == csr_session) {
+		sme_err("Session does not exist for session id: %d",
+			session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	auth_req_len = sizeof(tSirFTPreAuthReq);
+	preauth_req = qdf_mem_malloc(auth_req_len);
+	if (!preauth_req)
+		return QDF_STATUS_E_NOMEM;
+
+	/* Save the SME Session ID. We need it while processing preauth resp */
+	csr_session->ftSmeContext.smeSessionId = session_id;
+	preauth_req->pbssDescription = qdf_mem_malloc(sizeof(bss_desc->length)
+				+ bss_desc->length);
+	if (!preauth_req->pbssDescription)
+		return QDF_STATUS_E_NOMEM;
+
+	preauth_req->messageType = eWNI_SME_FT_PRE_AUTH_REQ;
+
+	preauth_req->preAuthchannelNum = bss_desc->channelId;
+	preauth_req->dot11mode = csr_get_dot11_mode(mac_ctx, session_id,
+						    bss_desc);
+	if (!preauth_req->dot11mode) {
+		sme_err("preauth_req->dot11mode is zero");
+		qdf_mem_free(preauth_req);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_copy((void *)&preauth_req->currbssId,
+			(void *)csr_session->connectedProfile.bssid.bytes,
+			sizeof(tSirMacAddr));
+	qdf_mem_copy((void *)&preauth_req->preAuthbssId,
+			(void *)bss_desc->bssId, sizeof(tSirMacAddr));
+	qdf_mem_copy((void *)&preauth_req->self_mac_addr,
+		(void *)&csr_session->selfMacAddr.bytes, sizeof(tSirMacAddr));
+
+	if (csr_roam_is11r_assoc(mac_ctx, session_id) &&
+	     (mac_ctx->roam.roamSession[session_id].connectedProfile.AuthType !=
+	      eCSR_AUTH_TYPE_OPEN_SYSTEM)) {
+		preauth_req->ft_ies_length =
+			(uint16_t) csr_session->ftSmeContext.auth_ft_ies_length;
+		qdf_mem_copy(preauth_req->ft_ies,
+				csr_session->ftSmeContext.auth_ft_ies,
+				csr_session->ftSmeContext.auth_ft_ies_length);
+	} else {
+		preauth_req->ft_ies_length = 0;
+	}
+	qdf_mem_copy(preauth_req->pbssDescription, bss_desc,
+			sizeof(bss_desc->length) + bss_desc->length);
+	preauth_req->length = auth_req_len;
+	return umac_send_mb_message_to_mac(preauth_req);
+}
+
+void csr_roam_ft_pre_auth_rsp_processor(tpAniSirGlobal mac_ctx,
+					tpSirFTPreAuthRsp preauth_rsp)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_info roam_info;
+	eCsrAuthType conn_Auth_type;
+	uint32_t session_id = preauth_rsp->smeSessionId;
+	struct csr_roam_session *csr_session = CSR_GET_SESSION(mac_ctx,
+				session_id);
+	tDot11fAuthentication *p_auth = NULL;
+
+	if (NULL == csr_session) {
+		sme_err("CSR session is NULL");
+		return;
+	}
+	status = csr_neighbor_roam_preauth_rsp_handler(mac_ctx,
+			preauth_rsp->smeSessionId, preauth_rsp->status);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("Preauth was not processed: %d SessionID: %d",
+			status, session_id);
+		return;
+	}
+
+	if (QDF_STATUS_SUCCESS != (QDF_STATUS) preauth_rsp->status)
+		return;
+	csr_session->ftSmeContext.FTState = eFT_AUTH_COMPLETE;
+	csr_session->ftSmeContext.psavedFTPreAuthRsp = preauth_rsp;
+	/* No need to notify qos module if this is a non 11r & ESE roam */
+	if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->smeSessionId)
+#ifdef FEATURE_WLAN_ESE
+		|| csr_roam_is_ese_assoc(mac_ctx, preauth_rsp->smeSessionId)
+#endif
+	   ) {
+		sme_qos_csr_event_ind(mac_ctx,
+			csr_session->ftSmeContext.smeSessionId,
+			SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL);
+	}
+	status =
+		qdf_mc_timer_start(
+			&csr_session->ftSmeContext.preAuthReassocIntvlTimer,
+			60);
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("PreauthReassocInterval timer failed status %d",
+			status);
+		return;
+	}
+	qdf_mem_copy((void *)&csr_session->ftSmeContext.preAuthbssId,
+		(void *)preauth_rsp->preAuthbssId,
+		sizeof(struct qdf_mac_addr));
+	if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->smeSessionId))
+		csr_roam_call_callback(mac_ctx, preauth_rsp->smeSessionId,
+			NULL, 0, eCSR_ROAM_FT_RESPONSE, eCSR_ROAM_RESULT_NONE);
+
+#ifdef FEATURE_WLAN_ESE
+	if (csr_roam_is_ese_assoc(mac_ctx, preauth_rsp->smeSessionId)) {
+		csr_roam_read_tsf(mac_ctx, (uint8_t *) roam_info.timestamp,
+				preauth_rsp->smeSessionId);
+		qdf_mem_copy((void *)&roam_info.bssid,
+				(void *)preauth_rsp->preAuthbssId,
+				sizeof(struct qdf_mac_addr));
+		csr_roam_call_callback(mac_ctx, preauth_rsp->smeSessionId,
+				&roam_info, 0, eCSR_ROAM_CCKM_PREAUTH_NOTIFY,
+				0);
+	}
+#endif
+
+	if (csr_roam_is_fast_roam_enabled(mac_ctx, preauth_rsp->smeSessionId)) {
+		/* Save the bssid from the received response */
+		qdf_mem_copy((void *)&roam_info.bssid,
+				(void *)preauth_rsp->preAuthbssId,
+				sizeof(struct qdf_mac_addr));
+		csr_roam_call_callback(mac_ctx, preauth_rsp->smeSessionId,
+				&roam_info, 0, eCSR_ROAM_PMK_NOTIFY, 0);
+	}
+
+	/* If its an Open Auth, FT IEs are not provided by supplicant */
+	/* Hence populate them here */
+	conn_Auth_type =
+		mac_ctx->roam.roamSession[session_id].connectedProfile.AuthType;
+
+	csr_session->ftSmeContext.addMDIE = false;
+
+	/* Done with it, init it. */
+	csr_session->ftSmeContext.psavedFTPreAuthRsp = NULL;
+
+	if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->smeSessionId) &&
+			(conn_Auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM)) {
+		uint16_t ft_ies_length;
+
+		ft_ies_length = preauth_rsp->ric_ies_length;
+
+		if ((csr_session->ftSmeContext.reassoc_ft_ies) &&
+			(csr_session->ftSmeContext.reassoc_ft_ies_length)) {
+			qdf_mem_free(csr_session->ftSmeContext.reassoc_ft_ies);
+			csr_session->ftSmeContext.reassoc_ft_ies_length = 0;
+			csr_session->ftSmeContext.reassoc_ft_ies = NULL;
+		}
+		p_auth = (tDot11fAuthentication *) qdf_mem_malloc(
+						sizeof(tDot11fAuthentication));
+
+		if (p_auth == NULL)
+			return;
+
+		status = dot11f_unpack_authentication(mac_ctx,
+				preauth_rsp->ft_ies,
+				preauth_rsp->ft_ies_length, p_auth, false);
+		if (DOT11F_FAILED(status))
+			sme_err("Failed to parse an Authentication frame");
+		else if (p_auth->MobilityDomain.present)
+			csr_session->ftSmeContext.addMDIE = true;
+
+		qdf_mem_free(p_auth);
+
+		if (!ft_ies_length)
+			return;
+
+		csr_session->ftSmeContext.reassoc_ft_ies =
+			qdf_mem_malloc(ft_ies_length);
+		if (!csr_session->ftSmeContext.reassoc_ft_ies)
+			return;
+
+		/* Copy the RIC IEs to reassoc IEs */
+		qdf_mem_copy(((uint8_t *) csr_session->ftSmeContext.
+					reassoc_ft_ies),
+					(uint8_t *) preauth_rsp->ric_ies,
+					preauth_rsp->ric_ies_length);
+		csr_session->ftSmeContext.reassoc_ft_ies_length = ft_ies_length;
+		csr_session->ftSmeContext.addMDIE = true;
+	}
+}
+
+/**
+ * csr_neighbor_roam_issue_preauth_req() - Send preauth request to first AP
+ * @mac_ctx: The handle returned by mac_open.
+ * @session_id: Session information
+ *
+ * This function issues preauth request to PE with the 1st AP entry in the
+ * roamable AP list
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
+ */
+QDF_STATUS csr_neighbor_roam_issue_preauth_req(tpAniSirGlobal mac_ctx,
+						      uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamBSSInfo neighbor_bss_node;
+
+
+	if (false != neighbor_roam_info->FTRoamInfo.preauthRspPending) {
+		/* This must not be true here */
+		QDF_ASSERT(neighbor_roam_info->FTRoamInfo.preauthRspPending ==
+			   false);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Issue Preauth request to PE here.
+	 * Need to issue the preauth request with the BSSID that is in the
+	 * head of the roamable AP list. Parameters that should be passed are
+	 * BSSID, Channel number and the neighborScanPeriod(probably). If
+	 * roamableAPList gets empty, should transition to REPORT_SCAN state
+	 */
+	neighbor_bss_node = csr_neighbor_roam_next_roamable_ap(mac_ctx,
+				&neighbor_roam_info->roamableAPList, NULL);
+
+	if (NULL == neighbor_bss_node) {
+		sme_err("Roamable AP list is empty");
+		return QDF_STATUS_E_FAILURE;
+	}
+	csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
+			neighbor_bss_node->pBssDescription->bssId,
+			eCSR_ROAM_PREAUTH_INIT_NOTIFY);
+	status = csr_roam_enqueue_preauth(mac_ctx, session_id,
+				neighbor_bss_node->pBssDescription,
+				eCsrPerformPreauth, true);
+
+	sme_debug("Before Pre-Auth: BSSID " MAC_ADDRESS_STR ", Ch:%d",
+			MAC_ADDR_ARRAY(
+				neighbor_bss_node->pBssDescription->bssId),
+			(int)neighbor_bss_node->pBssDescription->channelId);
+
+	if (QDF_STATUS_SUCCESS != status) {
+		sme_err("Return failed preauth request status %d",
+			status);
+		return status;
+	}
+
+	neighbor_roam_info->FTRoamInfo.preauthRspPending = true;
+	neighbor_roam_info->FTRoamInfo.numPreAuthRetries++;
+	csr_neighbor_roam_state_transition(mac_ctx,
+		eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING, session_id);
+
+	return status;
+}
+
diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c
new file mode 100644
index 0000000..e40b9ec
--- /dev/null
+++ b/core/sme/src/csr/csr_util.c
@@ -0,0 +1,6360 @@
+/*
+ * Copyright (c) 2011-2018 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: csr_util.c
+ *
+ * Implementation supporting routines for CSR.
+ */
+
+#include "ani_global.h"
+
+#include "csr_support.h"
+#include "csr_inside_api.h"
+#include "sme_qos_internal.h"
+#include "wma_types.h"
+#include "cds_utils.h"
+#include "wlan_policy_mgr_api.h"
+#include "wlan_serialization_legacy_api.h"
+#include "wlan_reg_services_api.h"
+
+
+uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE] = {
+	{0x00, 0x50, 0xf2, 0x00}
+	,
+	{0x00, 0x50, 0xf2, 0x01}
+	,
+	{0x00, 0x50, 0xf2, 0x02}
+	,
+	{0x00, 0x50, 0xf2, 0x03}
+	,
+	{0x00, 0x50, 0xf2, 0x04}
+	,
+	{0x00, 0x50, 0xf2, 0x05}
+	,
+#ifdef FEATURE_WLAN_ESE
+	{0x00, 0x40, 0x96, 0x00}
+	,                       /* CCKM */
+#endif /* FEATURE_WLAN_ESE */
+};
+
+/*
+ * PLEASE DO NOT ADD THE #IFDEF IN BELOW TABLE,
+ * IF STILL REQUIRE THEN PLEASE ADD NULL ENTRIES
+ * OTHERWISE IT WILL BREAK OTHER LOWER
+ * SECUIRTY MODES.
+ */
+
+uint8_t csr_rsn_oui[][CSR_RSN_OUI_SIZE] = {
+	{0x00, 0x0F, 0xAC, 0x00}
+	,                       /* group cipher */
+	{0x00, 0x0F, 0xAC, 0x01}
+	,                       /* WEP-40 or RSN */
+	{0x00, 0x0F, 0xAC, 0x02}
+	,                       /* TKIP or RSN-PSK */
+	{0x00, 0x0F, 0xAC, 0x03}
+	,                       /* Reserved */
+	{0x00, 0x0F, 0xAC, 0x04}
+	,                       /* AES-CCMP */
+	{0x00, 0x0F, 0xAC, 0x05}
+	,                       /* WEP-104 */
+	{0x00, 0x40, 0x96, 0x00}
+	,                       /* CCKM */
+	{0x00, 0x0F, 0xAC, 0x06}
+	,                       /* BIP (encryption type) or
+				 * RSN-PSK-SHA256 (authentication type)
+				 */
+	/* RSN-8021X-SHA256 (authentication type) */
+	{0x00, 0x0F, 0xAC, 0x05},
+#ifdef WLAN_FEATURE_FILS_SK
+#define ENUM_FILS_SHA256 9
+	/* FILS SHA256 */
+	{0x00, 0x0F, 0xAC, 0x0E},
+#define ENUM_FILS_SHA384 10
+	/* FILS SHA384 */
+	{0x00, 0x0F, 0xAC, 0x0F},
+#define ENUM_FT_FILS_SHA256 11
+	/* FILS FT SHA256 */
+	{0x00, 0x0F, 0xAC, 0x10},
+#define ENUM_FT_FILS_SHA384 12
+	/* FILS FT SHA384 */
+	{0x00, 0x0F, 0xAC, 0x11},
+#else
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+#endif
+	/* AES GCMP */
+	{0x00, 0x0F, 0xAC, 0x08},
+	/* AES GCMP-256 */
+	{0x00, 0x0F, 0xAC, 0x09},
+#define ENUM_DPP_RSN 15
+	/* DPP RSN */
+	{0x50, 0x6F, 0x9A, 0x02},
+#define ENUM_OWE 16
+	/* OWE https://tools.ietf.org/html/rfc8110 */
+	{0x00, 0x0F, 0xAC, 0x12},
+#define ENUM_SUITEB_EAP256 17
+	{0x00, 0x0F, 0xAC, 0x0B},
+#define ENUM_SUITEB_EAP384 18
+	{0x00, 0x0F, 0xAC, 0x0C},
+
+#ifdef WLAN_FEATURE_SAE
+#define ENUM_SAE 19
+	/* SAE */
+	{0x00, 0x0F, 0xAC, 0x08},
+#define ENUM_FT_SAE 20
+	/* FT SAE */
+	{0x00, 0x0F, 0xAC, 0x09},
+#else
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+#endif
+
+	/* define new oui here, update #define CSR_OUI_***_INDEX  */
+};
+
+#ifdef FEATURE_WLAN_WAPI
+uint8_t csr_wapi_oui[][CSR_WAPI_OUI_SIZE] = {
+	{0x00, 0x14, 0x72, 0x00}
+	,                       /* Reserved */
+	{0x00, 0x14, 0x72, 0x01}
+	,                       /* WAI certificate or SMS4 */
+	{0x00, 0x14, 0x72, 0x02} /* WAI PSK */
+};
+#endif /* FEATURE_WLAN_WAPI */
+uint8_t csr_wme_info_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
+uint8_t csr_wme_parm_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
+
+uint8_t csr_group_mgmt_oui[][CSR_RSN_OUI_SIZE] = {
+#define ENUM_CMAC 0
+	{0x00, 0x0F, 0xAC, 0x06},
+#define ENUM_GMAC_128 1
+	{0x00, 0x0F, 0xAC, 0x0B},
+#define ENUM_GMAC_256 2
+	{0x00, 0x0F, 0xAC, 0x0C},
+};
+
+
+/* ////////////////////////////////////////////////////////////////////// */
+
+/**
+ * \var g_phy_rates_suppt
+ *
+ * \brief Rate support lookup table
+ *
+ *
+ * This is a  lookup table indexing rates &  configuration parameters to
+ * support.  Given a rate (in  unites of 0.5Mpbs) & three bools (MIMO
+ * Enabled, Channel  Bonding Enabled, & Concatenation  Enabled), one can
+ * determine  whether  the given  rate  is  supported  by computing  two
+ * indices.  The  first maps  the rate to  table row as  indicated below
+ * (i.e. eHddSuppRate_6Mbps maps to  row zero, eHddSuppRate_9Mbps to row
+ * 1, and so on).  Index two can be computed like so:
+ *
+ * \code
+ *  idx2 = ( fEsf  ? 0x4 : 0x0 ) |
+ *         ( fCb   ? 0x2 : 0x0 ) |
+ *         ( fMimo ? 0x1 : 0x0 );
+ * \endcode
+ *
+ *
+ * Given that:
+ *
+ *  \code
+ *  fSupported = g_phy_rates_suppt[idx1][idx2];
+ *  \endcode
+ *
+ *
+ * This table is based on  the document "PHY Supported Rates.doc".  This
+ * table is  permissive in that a  rate is reflected  as being supported
+ * even  when turning  off an  enabled feature  would be  required.  For
+ * instance, "PHY Supported Rates"  lists 42Mpbs as unsupported when CB,
+ * ESF, &  MIMO are all  on.  However,  if we turn  off either of  CB or
+ * MIMO, it then becomes supported.   Therefore, we mark it as supported
+ * even in index 7 of this table.
+ *
+ *
+ */
+
+static const bool g_phy_rates_suppt[24][8] = {
+
+	/* SSF   SSF    SSF    SSF    ESF    ESF    ESF    ESF */
+	/* SIMO  MIMO   SIMO   MIMO   SIMO   MIMO   SIMO   MIMO */
+	/* No CB No CB  CB     CB     No CB  No CB  CB     CB */
+	{true, true, true, true, true, true, true, true},       /* 6Mbps */
+	{true, true, true, true, true, true, true, true},       /* 9Mbps */
+	{true, true, true, true, true, true, true, true},       /* 12Mbps */
+	{true, true, true, true, true, true, true, true},       /* 18Mbps */
+	{false, false, true, true, false, false, true, true},   /* 20Mbps */
+	{true, true, true, true, true, true, true, true},       /* 24Mbps */
+	{true, true, true, true, true, true, true, true},       /* 36Mbps */
+	{false, false, true, true, false, true, true, true},    /* 40Mbps */
+	{false, false, true, true, false, true, true, true},    /* 42Mbps */
+	{true, true, true, true, true, true, true, true},       /* 48Mbps */
+	{true, true, true, true, true, true, true, true},       /* 54Mbps */
+	{false, true, true, true, false, true, true, true},     /* 72Mbps */
+	{false, false, true, true, false, true, true, true},    /* 80Mbps */
+	{false, false, true, true, false, true, true, true},    /* 84Mbps */
+	{false, true, true, true, false, true, true, true},     /* 96Mbps */
+	{false, true, true, true, false, true, true, true},     /* 108Mbps */
+	{false, false, true, true, false, true, true, true},    /* 120Mbps */
+	{false, false, true, true, false, true, true, true},    /* 126Mbps */
+	{false, false, false, true, false, false, false, true}, /* 144Mbps */
+	{false, false, false, true, false, false, false, true}, /* 160Mbps */
+	{false, false, false, true, false, false, false, true}, /* 168Mbps */
+	{false, false, false, true, false, false, false, true}, /* 192Mbps */
+	{false, false, false, true, false, false, false, true}, /* 216Mbps */
+	{false, false, false, true, false, false, false, true}, /* 240Mbps */
+
+};
+
+#define CASE_RETURN_STR(n) {\
+	case (n): return (# n);\
+}
+
+const char *get_e_roam_cmd_status_str(eRoamCmdStatus val)
+{
+	switch (val) {
+		CASE_RETURN_STR(eCSR_ROAM_CANCELLED);
+		CASE_RETURN_STR(eCSR_ROAM_FAILED);
+		CASE_RETURN_STR(eCSR_ROAM_ROAMING_START);
+		CASE_RETURN_STR(eCSR_ROAM_ROAMING_COMPLETION);
+		CASE_RETURN_STR(eCSR_ROAM_CONNECT_COMPLETION);
+		CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_START);
+		CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_COMPLETION);
+		CASE_RETURN_STR(eCSR_ROAM_DISASSOCIATED);
+		CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_FAILURE);
+		CASE_RETURN_STR(eCSR_ROAM_SHOULD_ROAM);
+		CASE_RETURN_STR(eCSR_ROAM_SCAN_FOUND_NEW_BSS);
+		CASE_RETURN_STR(eCSR_ROAM_LOSTLINK);
+		CASE_RETURN_STR(eCSR_ROAM_LOSTLINK_DETECTED);
+		CASE_RETURN_STR(eCSR_ROAM_MIC_ERROR_IND);
+		CASE_RETURN_STR(eCSR_ROAM_IBSS_IND);
+		CASE_RETURN_STR(eCSR_ROAM_CONNECT_STATUS_UPDATE);
+		CASE_RETURN_STR(eCSR_ROAM_GEN_INFO);
+		CASE_RETURN_STR(eCSR_ROAM_SET_KEY_COMPLETE);
+		CASE_RETURN_STR(eCSR_ROAM_IBSS_LEAVE);
+		CASE_RETURN_STR(eCSR_ROAM_INFRA_IND);
+		CASE_RETURN_STR(eCSR_ROAM_WPS_PBC_PROBE_REQ_IND);
+		CASE_RETURN_STR(eCSR_ROAM_FT_RESPONSE);
+		CASE_RETURN_STR(eCSR_ROAM_FT_START);
+		CASE_RETURN_STR(eCSR_ROAM_SESSION_OPENED);
+		CASE_RETURN_STR(eCSR_ROAM_FT_REASSOC_FAILED);
+		CASE_RETURN_STR(eCSR_ROAM_PMK_NOTIFY);
+#ifdef FEATURE_WLAN_LFR_METRICS
+		CASE_RETURN_STR(eCSR_ROAM_PREAUTH_INIT_NOTIFY);
+		CASE_RETURN_STR(eCSR_ROAM_PREAUTH_STATUS_SUCCESS);
+		CASE_RETURN_STR(eCSR_ROAM_PREAUTH_STATUS_FAILURE);
+		CASE_RETURN_STR(eCSR_ROAM_HANDOVER_SUCCESS);
+#endif
+#ifdef FEATURE_WLAN_TDLS
+		CASE_RETURN_STR(eCSR_ROAM_TDLS_STATUS_UPDATE);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND);
+#endif
+		CASE_RETURN_STR(eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS);
+		CASE_RETURN_STR(eCSR_ROAM_SEND_P2P_STOP_BSS);
+#ifdef WLAN_FEATURE_11W
+		CASE_RETURN_STR(eCSR_ROAM_UNPROT_MGMT_FRAME_IND);
+#endif
+#ifdef WLAN_FEATURE_RMC
+		CASE_RETURN_STR(eCSR_ROAM_IBSS_PEER_INFO_COMPLETE);
+#endif
+#ifdef FEATURE_WLAN_ESE
+		CASE_RETURN_STR(eCSR_ROAM_TSM_IE_IND);
+		CASE_RETURN_STR(eCSR_ROAM_CCKM_PREAUTH_NOTIFY);
+		CASE_RETURN_STR(eCSR_ROAM_ESE_ADJ_AP_REPORT_IND);
+		CASE_RETURN_STR(eCSR_ROAM_ESE_BCN_REPORT_IND);
+#endif /* FEATURE_WLAN_ESE */
+		CASE_RETURN_STR(eCSR_ROAM_DFS_RADAR_IND);
+		CASE_RETURN_STR(eCSR_ROAM_SET_CHANNEL_RSP);
+		CASE_RETURN_STR(eCSR_ROAM_DFS_CHAN_SW_NOTIFY);
+		CASE_RETURN_STR(eCSR_ROAM_EXT_CHG_CHNL_IND);
+		CASE_RETURN_STR(eCSR_ROAM_STA_CHANNEL_SWITCH);
+		CASE_RETURN_STR(eCSR_ROAM_NDP_STATUS_UPDATE);
+		CASE_RETURN_STR(eCSR_ROAM_UPDATE_SCAN_RESULT);
+		CASE_RETURN_STR(eCSR_ROAM_START);
+		CASE_RETURN_STR(eCSR_ROAM_ABORT);
+		CASE_RETURN_STR(eCSR_ROAM_NAPI_OFF);
+		CASE_RETURN_STR(eCSR_ROAM_CHANNEL_COMPLETE_IND);
+		CASE_RETURN_STR(eCSR_ROAM_SAE_COMPUTE);
+	default:
+		return "unknown";
+	}
+}
+
+const char *get_e_csr_roam_result_str(eCsrRoamResult val)
+{
+	switch (val) {
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NONE);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_FAILURE);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_ASSOCIATED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NOT_ASSOCIATED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_MIC_FAILURE);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_FORCED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_DISASSOC_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_DEAUTH_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_CAP_CHANGED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_STARTED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_START_FAILED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_JOIN_FAILED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_CONNECT);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_INACTIVE);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_NEW_PEER);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_COALESCED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_STOP);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_LOSTLINK);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_MIC_ERROR_UNICAST);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_MIC_ERROR_GROUP);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_AUTHENTICATED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NEW_RSN_BSS);
+ #ifdef FEATURE_WLAN_WAPI
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NEW_WAPI_BSS);
+ #endif /* FEATURE_WLAN_WAPI */
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_INFRA_STARTED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_INFRA_START_FAILED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_INFRA_STOPPED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_INFRA_DISASSOCIATED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_SEND_ACTION_FAIL);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_ADD_TDLS_PEER);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_UPDATE_TDLS_PEER);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_DELETE_TDLS_PEER);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED);
+		CASE_RETURN_STR
+			(eCSR_ROAM_RESULT_TDLS_CONNECTION_TRACKER_NOTIFICATION);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_PEER_INFO_SUCCESS);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_PEER_INFO_FAILED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_CSA_RESTART_RSP);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS);
+		CASE_RETURN_STR(eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NDI_CREATE_RSP);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NDI_DELETE_RSP);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NDP_INITIATOR_RSP);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NDP_NEW_PEER_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NDP_CONFIRM_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NDP_INDICATION);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NDP_SCHED_UPDATE_RSP);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NDP_RESPONDER_RSP);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NDP_END_RSP);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NDP_END_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE);
+	default:
+		return "unknown";
+	}
+}
+
+const char *csr_phy_mode_str(eCsrPhyMode phy_mode)
+{
+	switch (phy_mode) {
+	case eCSR_DOT11_MODE_abg:
+		return "abg";
+	case eCSR_DOT11_MODE_11a:
+		return "11a";
+	case eCSR_DOT11_MODE_11b:
+		return "11b";
+	case eCSR_DOT11_MODE_11g:
+		return "11g";
+	case eCSR_DOT11_MODE_11n:
+		return "11n";
+	case eCSR_DOT11_MODE_11g_ONLY:
+		return "11g_only";
+	case eCSR_DOT11_MODE_11n_ONLY:
+		return "11n_only";
+	case eCSR_DOT11_MODE_11b_ONLY:
+		return "11b_only";
+	case eCSR_DOT11_MODE_11ac:
+		return "11ac";
+	case eCSR_DOT11_MODE_11ac_ONLY:
+		return "11ac_only";
+	case eCSR_DOT11_MODE_AUTO:
+		return "auto";
+	case eCSR_DOT11_MODE_11ax:
+		return "11ax";
+	case eCSR_DOT11_MODE_11ax_ONLY:
+		return "11ax_only";
+	default:
+		return "unknown";
+	}
+}
+
+void csr_purge_vdev_pending_ser_cmd_list(struct mac_context *mac_ctx,
+					 uint32_t vdev_id)
+{
+	wlan_serialization_purge_cmd_list_by_vdev_id(mac_ctx->psoc, vdev_id,
+						     false, true, false,
+						     true, false);
+}
+
+void csr_purge_vdev_all_ser_cmd_list(struct mac_context *mac_ctx,
+				     uint32_t vdev_id)
+{
+	wlan_serialization_purge_cmd_list_by_vdev_id(mac_ctx->psoc, vdev_id,
+						     true, true, true,
+						     true, true);
+}
+
+void csr_purge_vdev_all_scan_ser_cmd_list(struct mac_context *mac_ctx,
+					  uint32_t vdev_id)
+{
+	wlan_serialization_purge_cmd_list_by_vdev_id(mac_ctx->psoc, vdev_id,
+						     true, true, false,
+						     false, false);
+}
+
+void csr_purge_pdev_all_ser_cmd_list(struct mac_context *mac_ctx)
+{
+	wlan_serialization_purge_cmd_list(mac_ctx->psoc, NULL, true, true,
+					  true, true, true);
+}
+
+void csr_nonscan_active_ll_insert_head(struct mac_context *mac_ctx,
+				       tListElem *entry, bool inter_locked)
+{
+}
+
+void csr_nonscan_pending_ll_insert_head(struct mac_context *mac_ctx,
+					tListElem *entry, bool inter_locked)
+{
+}
+
+void csr_nonscan_pending_ll_insert_tail(struct mac_context *mac_ctx,
+					tListElem *entry, bool inter_locked)
+{
+}
+
+void csr_nonscan_pending_ll_unlock(struct mac_context *mac_ctx)
+{
+}
+
+void csr_nonscan_active_ll_unlock(struct mac_context *mac_ctx)
+{
+}
+
+void csr_nonscan_pending_ll_lock(struct mac_context *mac_ctx)
+{
+}
+
+void csr_nonscan_active_ll_lock(struct mac_context *mac_ctx)
+{
+}
+
+uint32_t csr_nonscan_active_ll_count(struct mac_context *mac_ctx)
+{
+	return wlan_serialization_get_active_list_count(mac_ctx->psoc, false);
+}
+
+uint32_t csr_nonscan_pending_ll_count(struct mac_context *mac_ctx)
+{
+	return wlan_serialization_get_pending_list_count(mac_ctx->psoc, false);
+}
+
+bool csr_nonscan_active_ll_is_list_empty(struct mac_context *mac_ctx,
+					 bool inter_locked)
+{
+	return !wlan_serialization_get_active_list_count(mac_ctx->psoc, false);
+}
+
+bool csr_nonscan_pending_ll_is_list_empty(struct mac_context *mac_ctx,
+					  bool inter_locked)
+{
+	return !wlan_serialization_get_pending_list_count(mac_ctx->psoc, false);
+}
+
+tListElem *csr_nonscan_active_ll_peek_head(struct mac_context *mac_ctx,
+					   bool inter_locked)
+{
+	struct wlan_serialization_command *cmd;
+	tSmeCmd *sme_cmd;
+
+	cmd = wlan_serialization_peek_head_active_cmd_using_psoc(mac_ctx->psoc,
+								 false);
+	if (!cmd) {
+		sme_err("No cmd found");
+		return NULL;
+	}
+	sme_cmd = cmd->umac_cmd;
+
+	return &sme_cmd->Link;
+}
+
+tListElem *csr_nonscan_pending_ll_peek_head(struct mac_context *mac_ctx,
+					    bool inter_locked)
+{
+	struct wlan_serialization_command *cmd;
+	tSmeCmd *sme_cmd;
+
+	cmd = wlan_serialization_peek_head_pending_cmd_using_psoc(mac_ctx->psoc,
+								  false);
+	if (!cmd)
+		return NULL;
+
+	sme_cmd = cmd->umac_cmd;
+
+	return &sme_cmd->Link;
+}
+
+bool csr_nonscan_active_ll_remove_entry(struct mac_context *mac_ctx,
+					tListElem *entry, bool inter_locked)
+{
+	tListElem *head;
+
+	head = csr_nonscan_active_ll_peek_head(mac_ctx, inter_locked);
+	if (head == entry)
+	return true;
+
+	return false;
+}
+
+tListElem *csr_nonscan_active_ll_remove_head(struct mac_context *mac_ctx,
+					     bool inter_locked)
+{
+	return csr_nonscan_active_ll_peek_head(mac_ctx, inter_locked);
+}
+
+tListElem *csr_nonscan_pending_ll_remove_head(struct mac_context *mac_ctx,
+					      bool inter_locked)
+{
+	return csr_nonscan_pending_ll_peek_head(mac_ctx, inter_locked);
+}
+
+tListElem *csr_nonscan_pending_ll_next(struct mac_context *mac_ctx,
+				       tListElem *entry, bool inter_locked)
+{
+	tSmeCmd *sme_cmd;
+	struct wlan_serialization_command cmd, *tcmd;
+
+	if (!entry)
+		return NULL;
+	sme_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
+	cmd.cmd_id = sme_cmd->cmd_id;
+	cmd.cmd_type = csr_get_cmd_type(sme_cmd);
+	cmd.vdev = wlan_objmgr_get_vdev_by_id_from_psoc_no_state(
+				mac_ctx->psoc,
+				sme_cmd->sessionId, WLAN_LEGACY_SME_ID);
+	tcmd = wlan_serialization_get_pending_list_next_node_using_psoc(
+				mac_ctx->psoc, &cmd, false);
+	if (cmd.vdev)
+		wlan_objmgr_vdev_release_ref(cmd.vdev, WLAN_LEGACY_SME_ID);
+	if (!tcmd) {
+		sme_err("No cmd found");
+		return NULL;
+	}
+	sme_cmd = tcmd->umac_cmd;
+	return &sme_cmd->Link;
+}
+
+bool csr_get_bss_id_bss_desc(tSirBssDescription *pSirBssDesc,
+			     struct qdf_mac_addr *pBssId)
+{
+	qdf_mem_copy(pBssId, &pSirBssDesc->bssId[0],
+			sizeof(struct qdf_mac_addr));
+	return true;
+}
+
+bool csr_is_bss_id_equal(tSirBssDescription *pSirBssDesc1,
+			 tSirBssDescription *pSirBssDesc2)
+{
+	bool fEqual = false;
+	struct qdf_mac_addr bssId1;
+	struct qdf_mac_addr bssId2;
+
+	do {
+		if (!pSirBssDesc1)
+			break;
+		if (!pSirBssDesc2)
+			break;
+
+		if (!csr_get_bss_id_bss_desc(pSirBssDesc1, &bssId1))
+			break;
+		if (!csr_get_bss_id_bss_desc(pSirBssDesc2, &bssId2))
+			break;
+
+		fEqual = qdf_is_macaddr_equal(&bssId1, &bssId2);
+	} while (0);
+
+	return fEqual;
+}
+
+static bool csr_is_conn_state(tpAniSirGlobal mac_ctx, uint32_t session_id,
+			      eCsrConnectState state)
+{
+	QDF_BUG(session_id < CSR_ROAM_SESSION_MAX);
+	if (session_id >= CSR_ROAM_SESSION_MAX)
+		return false;
+
+	return mac_ctx->roam.roamSession[session_id].connectState == state;
+}
+
+bool csr_is_conn_state_connected_ibss(tpAniSirGlobal mac_ctx,
+				      uint32_t session_id)
+{
+	return csr_is_conn_state(mac_ctx, session_id,
+				 eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED);
+}
+
+bool csr_is_conn_state_disconnected_ibss(tpAniSirGlobal mac_ctx,
+					 uint32_t session_id)
+{
+	return csr_is_conn_state(mac_ctx, session_id,
+				 eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED);
+}
+
+bool csr_is_conn_state_connected_infra(tpAniSirGlobal mac_ctx,
+				       uint32_t session_id)
+{
+	return csr_is_conn_state(mac_ctx, session_id,
+				 eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED);
+}
+
+bool csr_is_conn_state_connected(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return csr_is_conn_state_connected_ibss(pMac, sessionId) ||
+		csr_is_conn_state_connected_infra(pMac, sessionId) ||
+		csr_is_conn_state_connected_wds(pMac, sessionId);
+}
+
+bool csr_is_conn_state_infra(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return csr_is_conn_state_connected_infra(pMac, sessionId);
+}
+
+bool csr_is_conn_state_ibss(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return csr_is_conn_state_connected_ibss(pMac, sessionId) ||
+	       csr_is_conn_state_disconnected_ibss(pMac, sessionId);
+}
+
+bool csr_is_conn_state_connected_wds(tpAniSirGlobal mac_ctx,
+				     uint32_t session_id)
+{
+	return csr_is_conn_state(mac_ctx, session_id,
+				 eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED);
+}
+
+bool csr_is_conn_state_connected_infra_ap(tpAniSirGlobal mac_ctx,
+					  uint32_t session_id)
+{
+	return csr_is_conn_state(mac_ctx, session_id,
+				 eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED) ||
+		csr_is_conn_state(mac_ctx, session_id,
+				  eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED);
+}
+
+bool csr_is_conn_state_disconnected_wds(tpAniSirGlobal mac_ctx,
+					uint32_t session_id)
+{
+	return csr_is_conn_state(mac_ctx, session_id,
+				 eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED);
+}
+
+bool csr_is_conn_state_wds(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return csr_is_conn_state_connected_wds(pMac, sessionId) ||
+	       csr_is_conn_state_disconnected_wds(pMac, sessionId);
+}
+
+static bool csr_is_conn_state_ap(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	struct csr_roam_session *pSession;
+
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession)
+		return false;
+	if (CSR_IS_INFRA_AP(&pSession->connectedProfile))
+		return true;
+	return false;
+}
+
+bool csr_is_any_session_in_connect_state(tpAniSirGlobal pMac)
+{
+	uint32_t i;
+	bool fRc = false;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i) &&
+		    (csr_is_conn_state_infra(pMac, i)
+		     || csr_is_conn_state_ibss(pMac, i)
+		     || csr_is_conn_state_ap(pMac, i))) {
+			fRc = true;
+			break;
+		}
+	}
+
+	return fRc;
+}
+
+int8_t csr_get_infra_session_id(tpAniSirGlobal pMac)
+{
+	uint8_t i;
+	int8_t sessionid = -1;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && csr_is_conn_state_infra(pMac, i)) {
+			sessionid = i;
+			break;
+		}
+	}
+
+	return sessionid;
+}
+
+uint8_t csr_get_infra_operation_channel(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	uint8_t channel;
+
+	if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		channel =
+			pMac->roam.roamSession[sessionId].connectedProfile.
+			operationChannel;
+	} else {
+		channel = 0;
+	}
+	return channel;
+}
+
+bool csr_is_session_client_and_connected(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	struct csr_roam_session *pSession = NULL;
+
+	if (CSR_IS_SESSION_VALID(pMac, sessionId)
+	    && csr_is_conn_state_infra(pMac, sessionId)) {
+		pSession = CSR_GET_SESSION(pMac, sessionId);
+		if (NULL != pSession->pCurRoamProfile) {
+			if ((pSession->pCurRoamProfile->csrPersona ==
+			     QDF_STA_MODE)
+			    || (pSession->pCurRoamProfile->csrPersona ==
+				QDF_P2P_CLIENT_MODE))
+				return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * csr_get_concurrent_operation_channel() - To get concurrent operating channel
+ * @mac_ctx: Pointer to mac context
+ *
+ * This routine will return operating channel on FIRST BSS that is
+ * active/operating to be used for concurrency mode.
+ * If other BSS is not up or not connected it will return 0
+ *
+ * Return: uint8_t
+ */
+uint8_t csr_get_concurrent_operation_channel(tpAniSirGlobal mac_ctx)
+{
+	struct csr_roam_session *session = NULL;
+	uint8_t i = 0;
+	enum QDF_OPMODE persona;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (!CSR_IS_SESSION_VALID(mac_ctx, i))
+			continue;
+		session = CSR_GET_SESSION(mac_ctx, i);
+		if (NULL == session->pCurRoamProfile)
+			continue;
+		persona = session->pCurRoamProfile->csrPersona;
+		if ((((persona == QDF_STA_MODE) ||
+			(persona == QDF_P2P_CLIENT_MODE)) &&
+			(session->connectState ==
+				eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) ||
+			(((persona == QDF_P2P_GO_MODE) ||
+				(persona == QDF_SAP_MODE))
+				 && (session->connectState !=
+					 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)))
+			return session->connectedProfile.operationChannel;
+
+	}
+	return 0;
+}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+
+#define HALF_BW_OF(eCSR_bw_val) ((eCSR_bw_val)/2)
+
+/* calculation of center channel based on V/HT BW and WIFI channel bw=5MHz) */
+
+#define CSR_GET_HT40_PLUS_CCH(och) ((och)+2)
+#define CSR_GET_HT40_MINUS_CCH(och) ((och)-2)
+
+#define CSR_GET_HT80_PLUS_LL_CCH(och) ((och)+6)
+#define CSR_GET_HT80_PLUS_HL_CCH(och) ((och)+2)
+#define CSR_GET_HT80_MINUS_LH_CCH(och) ((och)-2)
+#define CSR_GET_HT80_MINUS_HH_CCH(och) ((och)-6)
+
+/**
+ * csr_get_ch_from_ht_profile() - to get channel from HT profile
+ * @pMac: pointer to Mac context
+ * @htp: pointer to HT profile
+ * @och: operating channel
+ * @cfreq: channel frequency
+ * @hbw: half bandwidth
+ *
+ * This function will fill half bandwidth and channel frequency based
+ * on the HT profile
+ *
+ * Return: none
+ */
+static void csr_get_ch_from_ht_profile(tpAniSirGlobal pMac,
+				       tCsrRoamHTProfile *htp,
+				       uint16_t och, uint16_t *cfreq,
+				       uint16_t *hbw)
+{
+	uint16_t cch, ch_bond;
+
+	if (och > 14)
+		ch_bond = pMac->roam.configParam.channelBondingMode5GHz;
+	else
+		ch_bond = pMac->roam.configParam.channelBondingMode24GHz;
+
+	cch = och;
+	*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
+
+	if (!ch_bond)
+		goto ret;
+
+	sme_debug("HTC: %d scbw: %d rcbw: %d sco: %d VHTC: %d apc: %d apbw: %d",
+			htp->htCapability, htp->htSupportedChannelWidthSet,
+			htp->htRecommendedTxWidthSet,
+			htp->htSecondaryChannelOffset,
+			htp->vhtCapability, htp->apCenterChan, htp->apChanWidth
+	       );
+
+	if (htp->vhtCapability) {
+		cch = htp->apCenterChan;
+		if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
+			*hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL);
+		else if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
+			*hbw = HALF_BW_OF(eCSR_BW_160MHz_VAL);
+
+		if (!*hbw && htp->htCapability) {
+			if (htp->htSupportedChannelWidthSet ==
+				eHT_CHANNEL_WIDTH_40MHZ)
+				*hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
+			else
+				*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
+		}
+	} else if (htp->htCapability) {
+		if (htp->htSupportedChannelWidthSet ==
+					eHT_CHANNEL_WIDTH_40MHZ) {
+			*hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
+			if (htp->htSecondaryChannelOffset ==
+					PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+				cch = CSR_GET_HT40_PLUS_CCH(och);
+			else if (htp->htSecondaryChannelOffset ==
+					PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+				cch = CSR_GET_HT40_MINUS_CCH(och);
+		} else {
+			cch = och;
+			*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
+		}
+	}
+
+ret:
+	*cfreq = cds_chan_to_freq(cch);
+}
+
+/**
+ * csr_calc_chb_for_sap_phymode() - to calc channel bandwidth for sap phymode
+ * @mac_ctx: pointer to mac context
+ * @sap_ch: SAP operating channel
+ * @sap_phymode: SAP physical mode
+ * @sap_cch: concurrency channel
+ * @sap_hbw: SAP half bw
+ * @chb: channel bandwidth
+ *
+ * This routine is called to calculate channel bandwidth
+ *
+ * Return: none
+ */
+static void csr_calc_chb_for_sap_phymode(tpAniSirGlobal mac_ctx,
+		uint16_t *sap_ch, eCsrPhyMode *sap_phymode,
+		uint16_t *sap_cch, uint16_t *sap_hbw, uint8_t *chb)
+{
+	if (*sap_phymode == eCSR_DOT11_MODE_11n ||
+			*sap_phymode == eCSR_DOT11_MODE_11n_ONLY) {
+
+		*sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
+		if (*chb == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+			*sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
+		else if (*chb == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+			*sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
+
+	} else if (*sap_phymode == eCSR_DOT11_MODE_11ac ||
+		   *sap_phymode == eCSR_DOT11_MODE_11ac_ONLY ||
+		   *sap_phymode == eCSR_DOT11_MODE_11ax ||
+		   *sap_phymode == eCSR_DOT11_MODE_11ax_ONLY) {
+		/*11AC only 80/40/20 Mhz supported in Rome */
+		if (mac_ctx->roam.configParam.nVhtChannelWidth ==
+				(WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1)) {
+			*sap_hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL);
+			if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1))
+				*sap_cch = CSR_GET_HT80_PLUS_LL_CCH(*sap_ch);
+			else if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW
+				     - 1))
+				*sap_cch = CSR_GET_HT80_PLUS_HL_CCH(*sap_ch);
+			else if (*chb ==
+				 (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH
+				     - 1))
+				*sap_cch = CSR_GET_HT80_MINUS_LH_CCH(*sap_ch);
+			else if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH
+				     - 1))
+				*sap_cch = CSR_GET_HT80_MINUS_HH_CCH(*sap_ch);
+		} else {
+			*sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
+			if (*chb == (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW
+					- 1))
+				*sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
+			else if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW
+				     - 1))
+				*sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
+			else if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH
+				     - 1))
+				*sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
+			else if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH
+				     - 1))
+				*sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
+		}
+	}
+}
+
+/**
+ * csr_handle_conc_chnl_overlap_for_sap_go - To handle overlap for AP+AP
+ * @mac_ctx: pointer to mac context
+ * @session: Current session
+ * @sap_ch: SAP/GO operating channel
+ * @sap_hbw: SAP/GO half bw
+ * @sap_cfreq: SAP/GO channel frequency
+ * @intf_ch: concurrent SAP/GO operating channel
+ * @intf_hbw: concurrent SAP/GO half bw
+ * @intf_cfreq: concurrent SAP/GO channel frequency
+ *
+ * This routine is called to check if one SAP/GO channel is overlapping with
+ * other SAP/GO channel
+ *
+ * Return: none
+ */
+static void csr_handle_conc_chnl_overlap_for_sap_go(tpAniSirGlobal mac_ctx,
+		struct csr_roam_session *session,
+		uint16_t *sap_ch, uint16_t *sap_hbw, uint16_t *sap_cfreq,
+		uint16_t *intf_ch, uint16_t *intf_hbw, uint16_t *intf_cfreq)
+{
+	/*
+	 * if conc_custom_rule1 is defined then we don't
+	 * want p2pgo to follow SAP's channel or SAP to
+	 * follow P2PGO's channel.
+	 */
+	if (0 == mac_ctx->roam.configParam.conc_custom_rule1 &&
+		0 == mac_ctx->roam.configParam.conc_custom_rule2) {
+		if (*sap_ch == 0) {
+			*sap_ch = session->connectedProfile.operationChannel;
+			csr_get_ch_from_ht_profile(mac_ctx,
+				&session->connectedProfile.HTProfile,
+				*sap_ch, sap_cfreq, sap_hbw);
+		} else if (*sap_ch !=
+				session->connectedProfile.operationChannel) {
+			*intf_ch = session->connectedProfile.operationChannel;
+			csr_get_ch_from_ht_profile(mac_ctx,
+					&session->connectedProfile.HTProfile,
+					*intf_ch, intf_cfreq, intf_hbw);
+		}
+	} else if (*sap_ch == 0 &&
+			(session->pCurRoamProfile->csrPersona ==
+					QDF_SAP_MODE)) {
+		*sap_ch = session->connectedProfile.operationChannel;
+		csr_get_ch_from_ht_profile(mac_ctx,
+				&session->connectedProfile.HTProfile,
+				*sap_ch, sap_cfreq, sap_hbw);
+	}
+}
+
+
+/**
+ * csr_check_concurrent_channel_overlap() - To check concurrent overlap chnls
+ * @mac_ctx: Pointer to mac context
+ * @sap_ch: SAP channel
+ * @sap_phymode: SAP phy mode
+ * @cc_switch_mode: concurrent switch mode
+ *
+ * This routine will be called to check concurrent overlap channels
+ *
+ * Return: uint16_t
+ */
+uint16_t csr_check_concurrent_channel_overlap(tpAniSirGlobal mac_ctx,
+			uint16_t sap_ch, eCsrPhyMode sap_phymode,
+			uint8_t cc_switch_mode)
+{
+	struct csr_roam_session *session = NULL;
+	uint8_t i = 0, chb = PHY_SINGLE_CHANNEL_CENTERED;
+	uint16_t intf_ch = 0, sap_hbw = 0, intf_hbw = 0, intf_cfreq = 0;
+	uint16_t sap_cfreq = 0;
+	uint16_t sap_lfreq, sap_hfreq, intf_lfreq, intf_hfreq, sap_cch = 0;
+	QDF_STATUS status;
+
+	sme_debug("sap_ch: %d sap_phymode: %d", sap_ch, sap_phymode);
+
+	if (mac_ctx->roam.configParam.cc_switch_mode ==
+			QDF_MCC_TO_SCC_SWITCH_DISABLE)
+		return 0;
+
+	if (sap_ch != 0) {
+		sap_cch = sap_ch;
+		sap_hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
+
+		if (sap_ch > 14)
+			chb = mac_ctx->roam.configParam.channelBondingMode5GHz;
+		else
+			chb = mac_ctx->roam.configParam.channelBondingMode24GHz;
+
+		if (chb)
+			csr_calc_chb_for_sap_phymode(mac_ctx, &sap_ch,
+					&sap_phymode, &sap_cch, &sap_hbw, &chb);
+		sap_cfreq = cds_chan_to_freq(sap_cch);
+	}
+
+	sme_debug("sap_ch:%d sap_phymode:%d sap_cch:%d sap_hbw:%d chb:%d",
+		sap_ch, sap_phymode, sap_cch, sap_hbw, chb);
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (!CSR_IS_SESSION_VALID(mac_ctx, i))
+			continue;
+
+		session = CSR_GET_SESSION(mac_ctx, i);
+		if (NULL == session->pCurRoamProfile)
+			continue;
+		if (((session->pCurRoamProfile->csrPersona == QDF_STA_MODE) ||
+			(session->pCurRoamProfile->csrPersona ==
+				QDF_P2P_CLIENT_MODE)) &&
+			(session->connectState ==
+				eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) {
+			intf_ch = session->connectedProfile.operationChannel;
+			csr_get_ch_from_ht_profile(mac_ctx,
+				&session->connectedProfile.HTProfile,
+				intf_ch, &intf_cfreq, &intf_hbw);
+			sme_debug("%d: intf_ch:%d intf_cfreq:%d intf_hbw:%d",
+				i, intf_ch, intf_cfreq, intf_hbw);
+		} else if (((session->pCurRoamProfile->csrPersona ==
+					QDF_P2P_GO_MODE) ||
+				(session->pCurRoamProfile->csrPersona ==
+					QDF_SAP_MODE)) &&
+				(session->connectState !=
+					eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
+			if (session->ch_switch_in_progress)
+				continue;
+
+			csr_handle_conc_chnl_overlap_for_sap_go(mac_ctx,
+					session, &sap_ch, &sap_hbw, &sap_cfreq,
+					&intf_ch, &intf_hbw, &intf_cfreq);
+
+			sme_debug("%d: sap_ch:%d sap_hbw:%d sap_cfreq:%d intf_ch:%d intf_hbw:%d, intf_cfreq:%d",
+					i, sap_ch, sap_hbw, sap_cfreq,
+					intf_ch, intf_hbw, intf_cfreq);
+		}
+		if (intf_ch && ((intf_ch > 14 && sap_ch > 14) ||
+				(intf_ch <= 14 && sap_ch <= 14)))
+			break;
+	}
+
+	sme_debug("intf_ch:%d sap_ch:%d cc_switch_mode:%d, dbs:%d",
+			intf_ch, sap_ch, cc_switch_mode,
+			policy_mgr_is_dbs_enable(mac_ctx->psoc));
+
+	if (intf_ch && sap_ch != intf_ch &&
+	    !policy_mgr_is_force_scc(mac_ctx->psoc)) {
+		sap_lfreq = sap_cfreq - sap_hbw;
+		sap_hfreq = sap_cfreq + sap_hbw;
+		intf_lfreq = intf_cfreq - intf_hbw;
+		intf_hfreq = intf_cfreq + intf_hbw;
+
+		sme_err("SAP:  OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d INTF: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d",
+			sap_ch, cds_chan_to_freq(sap_ch),
+			cds_freq_to_chan(sap_cfreq), sap_cfreq, sap_hbw * 2,
+			sap_lfreq, sap_hfreq, intf_ch,
+			cds_chan_to_freq(intf_ch), cds_freq_to_chan(intf_cfreq),
+			intf_cfreq, intf_hbw * 2, intf_lfreq, intf_hfreq);
+
+		if (!(((sap_lfreq > intf_lfreq && sap_lfreq < intf_hfreq) ||
+			(sap_hfreq > intf_lfreq && sap_hfreq < intf_hfreq)) ||
+			((intf_lfreq > sap_lfreq && intf_lfreq < sap_hfreq) ||
+			(intf_hfreq > sap_lfreq && intf_hfreq < sap_hfreq))))
+			intf_ch = 0;
+	} else if (intf_ch && sap_ch != intf_ch &&
+		((cc_switch_mode == QDF_MCC_TO_SCC_SWITCH_FORCE) ||
+		 policy_mgr_is_force_scc(mac_ctx->psoc))) {
+		if (!((intf_ch <= 14 && sap_ch <= 14) ||
+			(intf_ch > 14 && sap_ch > 14))) {
+			if (policy_mgr_is_dbs_enable(mac_ctx->psoc) ||
+			    cc_switch_mode ==
+			    QDF_MCC_TO_SCC_WITH_PREFERRED_BAND)
+				intf_ch = 0;
+		} else if (cc_switch_mode ==
+			QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) {
+			status =
+				policy_mgr_get_sap_mandatory_channel(
+				mac_ctx->psoc,
+				(uint32_t *)&intf_ch);
+			if (QDF_IS_STATUS_ERROR(status))
+				sme_err("no mandatory channel");
+		}
+	} else if ((intf_ch == sap_ch) && (cc_switch_mode ==
+				QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)) {
+		if (cds_chan_to_band(intf_ch) == CDS_BAND_2GHZ) {
+			status =
+				policy_mgr_get_sap_mandatory_channel(
+					mac_ctx->psoc, (uint32_t *)&intf_ch);
+			if (QDF_IS_STATUS_ERROR(status))
+				sme_err("no mandatory channel");
+		}
+	}
+
+	if (intf_ch == sap_ch)
+		intf_ch = 0;
+
+	sme_err("##Concurrent Channels %s Interfering",
+		intf_ch == 0 ? "Not" : "Are");
+	return intf_ch;
+}
+#endif
+
+bool csr_is_all_session_disconnected(tpAniSirGlobal pMac)
+{
+	uint32_t i;
+	bool fRc = true;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && !csr_is_conn_state_disconnected(pMac, i)) {
+			fRc = false;
+			break;
+		}
+	}
+
+	return fRc;
+}
+
+/**
+ * csr_is_sta_session_connected() - to find if concurrent sta is active
+ * @mac_ctx: pointer to mac context
+ *
+ * This function will iterate through each session and check if sta
+ * session exist and active
+ *
+ * Return: true or false
+ */
+bool csr_is_sta_session_connected(tpAniSirGlobal mac_ctx)
+{
+	uint32_t i;
+	struct csr_roam_session *pSession = NULL;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(mac_ctx, i) &&
+			!csr_is_conn_state_disconnected(mac_ctx, i)) {
+			pSession = CSR_GET_SESSION(mac_ctx, i);
+
+			if ((NULL != pSession->pCurRoamProfile) &&
+				(QDF_STA_MODE ==
+					pSession->pCurRoamProfile->csrPersona))
+				return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * csr_is_p2p_session_connected() - to find if any p2p session is active
+ * @mac_ctx: pointer to mac context
+ *
+ * This function will iterate through each session and check if any p2p
+ * session exist and active
+ *
+ * Return: true or false
+ */
+bool csr_is_p2p_session_connected(tpAniSirGlobal pMac)
+{
+	uint32_t i;
+	struct csr_roam_session *pSession = NULL;
+	enum QDF_OPMODE persona;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (!CSR_IS_SESSION_VALID(pMac, i))
+			continue;
+
+		if (csr_is_conn_state_disconnected(pMac, i))
+			continue;
+
+		pSession = CSR_GET_SESSION(pMac, i);
+		if (pSession->pCurRoamProfile == NULL)
+			continue;
+
+		persona = pSession->pCurRoamProfile->csrPersona;
+		if (QDF_P2P_CLIENT_MODE == persona ||
+				QDF_P2P_GO_MODE == persona)
+			return true;
+	}
+
+	return false;
+}
+
+bool csr_is_any_session_connected(tpAniSirGlobal pMac)
+{
+	uint32_t i, count;
+	bool fRc = false;
+
+	count = 0;
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && !csr_is_conn_state_disconnected(pMac, i))
+			count++;
+	}
+
+	if (count > 0)
+		fRc = true;
+	return fRc;
+}
+
+bool csr_is_infra_connected(tpAniSirGlobal pMac)
+{
+	uint32_t i;
+	bool fRc = false;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && csr_is_conn_state_connected_infra(pMac, i)) {
+			fRc = true;
+			break;
+		}
+	}
+
+	return fRc;
+}
+
+uint8_t csr_get_connected_infra(tpAniSirGlobal mac_ctx)
+{
+	uint32_t i;
+	uint8_t connected_session = CSR_SESSION_ID_INVALID;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(mac_ctx, i)
+		    && csr_is_conn_state_connected_infra(mac_ctx, i)) {
+			connected_session = i;
+			break;
+		}
+	}
+
+	return connected_session;
+}
+
+
+bool csr_is_concurrent_infra_connected(tpAniSirGlobal pMac)
+{
+	uint32_t i, noOfConnectedInfra = 0;
+
+	bool fRc = false;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && csr_is_conn_state_connected_infra(pMac, i)) {
+			++noOfConnectedInfra;
+		}
+	}
+
+	/* More than one Infra Sta Connected */
+	if (noOfConnectedInfra > 1)
+		fRc = true;
+	return fRc;
+}
+
+bool csr_is_ibss_started(tpAniSirGlobal pMac)
+{
+	uint32_t i;
+	bool fRc = false;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && csr_is_conn_state_ibss(pMac, i)) {
+			fRc = true;
+			break;
+		}
+	}
+
+	return fRc;
+}
+
+bool csr_is_concurrent_session_running(tpAniSirGlobal pMac)
+{
+	uint32_t sessionId, noOfCocurrentSession = 0;
+	eCsrConnectState connectState;
+
+	bool fRc = false;
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+			connectState =
+				pMac->roam.roamSession[sessionId].connectState;
+			if ((eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED ==
+			     connectState)
+			    || (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED ==
+				connectState)
+			    || (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED ==
+				connectState)) {
+				++noOfCocurrentSession;
+			}
+		}
+	}
+
+	/* More than one session is Up and Running */
+	if (noOfCocurrentSession > 1)
+		fRc = true;
+	return fRc;
+}
+
+bool csr_is_infra_ap_started(tpAniSirGlobal pMac)
+{
+	uint32_t sessionId;
+	bool fRc = false;
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId) &&
+				(csr_is_conn_state_connected_infra_ap(pMac,
+					sessionId))) {
+			fRc = true;
+			break;
+		}
+	}
+
+	return fRc;
+
+}
+
+bool csr_is_conn_state_disconnected(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED ==
+	       pMac->roam.roamSession[sessionId].connectState;
+}
+
+/**
+ * csr_is_valid_mc_concurrent_session() - To check concurren session is valid
+ * @mac_ctx: pointer to mac context
+ * @session_id: session id
+ * @bss_descr: bss description
+ *
+ * This function validates the concurrent session
+ *
+ * Return: true or false
+ */
+bool csr_is_valid_mc_concurrent_session(tpAniSirGlobal mac_ctx,
+		uint32_t session_id,
+		tSirBssDescription *bss_descr)
+{
+	struct csr_roam_session *pSession = NULL;
+
+	/* Check for MCC support */
+	if (!mac_ctx->roam.configParam.fenableMCCMode)
+		return false;
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id))
+		return false;
+	/* Validate BeaconInterval */
+	pSession = CSR_GET_SESSION(mac_ctx, session_id);
+	if (NULL == pSession->pCurRoamProfile)
+		return false;
+	if (QDF_STATUS_SUCCESS == csr_validate_mcc_beacon_interval(mac_ctx,
+					bss_descr->channelId,
+					&bss_descr->beaconInterval, session_id,
+					pSession->pCurRoamProfile->csrPersona))
+		return true;
+	return false;
+}
+
+static tSirMacCapabilityInfo csr_get_bss_capabilities(tSirBssDescription *
+						      pSirBssDesc)
+{
+	tSirMacCapabilityInfo dot11Caps;
+
+	/* tSirMacCapabilityInfo is 16-bit */
+	qdf_get_u16((uint8_t *) &pSirBssDesc->capabilityInfo,
+		    (uint16_t *) &dot11Caps);
+
+	return dot11Caps;
+}
+
+bool csr_is_infra_bss_desc(tSirBssDescription *pSirBssDesc)
+{
+	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
+
+	return (bool) dot11Caps.ess;
+}
+
+bool csr_is_ibss_bss_desc(tSirBssDescription *pSirBssDesc)
+{
+	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
+
+	return (bool) dot11Caps.ibss;
+}
+
+static bool csr_is_qos_bss_desc(tSirBssDescription *pSirBssDesc)
+{
+	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
+
+	return (bool) dot11Caps.qos;
+}
+
+bool csr_is_privacy(tSirBssDescription *pSirBssDesc)
+{
+	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
+
+	return (bool) dot11Caps.privacy;
+}
+
+bool csr_is11d_supported(tpAniSirGlobal pMac)
+{
+	return pMac->roam.configParam.Is11dSupportEnabled;
+}
+
+bool csr_is11h_supported(tpAniSirGlobal pMac)
+{
+	return pMac->roam.configParam.Is11hSupportEnabled;
+}
+
+bool csr_is11e_supported(tpAniSirGlobal pMac)
+{
+	return pMac->roam.configParam.Is11eSupportEnabled;
+}
+
+bool csr_is_mcc_supported(tpAniSirGlobal pMac)
+{
+	return pMac->roam.configParam.fenableMCCMode;
+
+}
+
+bool csr_is_wmm_supported(tpAniSirGlobal pMac)
+{
+	if (eCsrRoamWmmNoQos == pMac->roam.configParam.WMMSupportMode)
+		return false;
+	else
+		return true;
+}
+
+/* pIes is the IEs for pSirBssDesc2 */
+bool csr_is_ssid_equal(tpAniSirGlobal pMac,
+		       tSirBssDescription *pSirBssDesc1,
+		       tSirBssDescription *pSirBssDesc2,
+		       tDot11fBeaconIEs *pIes2)
+{
+	bool fEqual = false;
+	tSirMacSSid Ssid1, Ssid2;
+	tDot11fBeaconIEs *pIes1 = NULL;
+	tDot11fBeaconIEs *pIesLocal = pIes2;
+
+	do {
+		if ((NULL == pSirBssDesc1) || (NULL == pSirBssDesc2))
+			break;
+		if (!pIesLocal
+		    &&
+		    !QDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies
+						   (pMac, pSirBssDesc2,
+						    &pIesLocal))) {
+			sme_err("fail to parse IEs");
+			break;
+		}
+		if (!QDF_IS_STATUS_SUCCESS
+			(csr_get_parsed_bss_description_ies(pMac,
+				pSirBssDesc1, &pIes1))) {
+			break;
+		}
+		if ((!pIes1->SSID.present) || (!pIesLocal->SSID.present))
+			break;
+		if (pIes1->SSID.num_ssid != pIesLocal->SSID.num_ssid)
+			break;
+		qdf_mem_copy(Ssid1.ssId, pIes1->SSID.ssid,
+			     pIes1->SSID.num_ssid);
+		qdf_mem_copy(Ssid2.ssId, pIesLocal->SSID.ssid,
+			     pIesLocal->SSID.num_ssid);
+
+		fEqual = (!qdf_mem_cmp(Ssid1.ssId, Ssid2.ssId,
+					pIesLocal->SSID.num_ssid));
+
+	} while (0);
+	if (pIes1)
+		qdf_mem_free(pIes1);
+	if (pIesLocal && !pIes2)
+		qdf_mem_free(pIesLocal);
+
+	return fEqual;
+}
+
+/* pIes can be passed in as NULL if the caller doesn't have one prepared */
+static bool csr_is_bss_description_wme(tpAniSirGlobal pMac,
+				       tSirBssDescription *pSirBssDesc,
+				       tDot11fBeaconIEs *pIes)
+{
+	/* Assume that WME is found... */
+	bool fWme = true;
+	tDot11fBeaconIEs *pIesTemp = pIes;
+
+	do {
+		if (pIesTemp == NULL) {
+			if (!QDF_IS_STATUS_SUCCESS
+				    (csr_get_parsed_bss_description_ies
+					    (pMac, pSirBssDesc, &pIesTemp))) {
+				fWme = false;
+				break;
+			}
+		}
+		/* if the Wme Info IE is found, then WME is supported... */
+		if (CSR_IS_QOS_BSS(pIesTemp))
+			break;
+		/* if none of these are found, then WME is NOT supported... */
+		fWme = false;
+	} while (0);
+	if (!csr_is_wmm_supported(pMac) && fWme)
+		if (!pIesTemp->HTCaps.present)
+			fWme = false;
+
+	if ((pIes == NULL) && (NULL != pIesTemp))
+		/* we allocate memory here so free it before returning */
+		qdf_mem_free(pIesTemp);
+
+	return fWme;
+}
+
+eCsrMediaAccessType csr_get_qos_from_bss_desc(tpAniSirGlobal mac_ctx,
+					      tSirBssDescription *pSirBssDesc,
+					      tDot11fBeaconIEs *pIes)
+{
+	eCsrMediaAccessType qosType = eCSR_MEDIUM_ACCESS_DCF;
+
+	if (NULL == pIes) {
+		QDF_ASSERT(pIes != NULL);
+		return qosType;
+	}
+
+	do {
+		/* If we find WMM in the Bss Description, then we let this
+		 * override and use WMM.
+		 */
+		if (csr_is_bss_description_wme(mac_ctx, pSirBssDesc, pIes))
+			qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP;
+		else {
+			/* If the QoS bit is on, then the AP is
+			 * advertising 11E QoS.
+			 */
+			if (csr_is_qos_bss_desc(pSirBssDesc))
+				qosType = eCSR_MEDIUM_ACCESS_11e_eDCF;
+			else
+				qosType = eCSR_MEDIUM_ACCESS_DCF;
+
+			/* Scale back based on the types turned on
+			 * for the adapter.
+			 */
+			if (eCSR_MEDIUM_ACCESS_11e_eDCF == qosType
+			    && !csr_is11e_supported(mac_ctx))
+				qosType = eCSR_MEDIUM_ACCESS_DCF;
+		}
+
+	} while (0);
+
+	return qosType;
+}
+
+/* Caller allocates memory for pIEStruct */
+QDF_STATUS csr_parse_bss_description_ies(tpAniSirGlobal mac_ctx,
+					 tSirBssDescription *pBssDesc,
+					 tDot11fBeaconIEs *pIEStruct)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	int ieLen =
+		(int)(pBssDesc->length + sizeof(pBssDesc->length) -
+		      GET_FIELD_OFFSET(tSirBssDescription, ieFields));
+
+	if (ieLen > 0 && pIEStruct) {
+		if (!DOT11F_FAILED(dot11f_unpack_beacon_i_es
+				    (mac_ctx, (uint8_t *) pBssDesc->ieFields,
+				    ieLen, pIEStruct, false)))
+		status = QDF_STATUS_SUCCESS;
+	}
+
+	return status;
+}
+
+/* This function will allocate memory for the parsed IEs to the caller.
+ * Caller must free the memory after it is done with the data only if
+ * this function succeeds
+ */
+QDF_STATUS csr_get_parsed_bss_description_ies(tpAniSirGlobal mac_ctx,
+					      tSirBssDescription *pBssDesc,
+					      tDot11fBeaconIEs **ppIEStruct)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	if (pBssDesc && ppIEStruct) {
+		*ppIEStruct = qdf_mem_malloc(sizeof(tDot11fBeaconIEs));
+		if ((*ppIEStruct) != NULL) {
+			status = csr_parse_bss_description_ies(mac_ctx,
+							       pBssDesc,
+							       *ppIEStruct);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				qdf_mem_free(*ppIEStruct);
+				*ppIEStruct = NULL;
+			}
+		} else {
+			sme_err("failed to allocate memory");
+			QDF_ASSERT(0);
+			return QDF_STATUS_E_NOMEM;
+		}
+	}
+
+	return status;
+}
+
+bool csr_is_nullssid(uint8_t *pBssSsid, uint8_t len)
+{
+	bool fNullSsid = false;
+
+	uint32_t SsidLength;
+	uint8_t *pSsidStr;
+
+	do {
+		if (0 == len) {
+			fNullSsid = true;
+			break;
+		}
+		/* Consider 0 or space for hidden SSID */
+		if (0 == pBssSsid[0]) {
+			fNullSsid = true;
+			break;
+		}
+
+		SsidLength = len;
+		pSsidStr = pBssSsid;
+
+		while (SsidLength) {
+			if (*pSsidStr)
+				break;
+
+			pSsidStr++;
+			SsidLength--;
+		}
+
+		if (0 == SsidLength) {
+			fNullSsid = true;
+			break;
+		}
+	} while (0);
+
+	return fNullSsid;
+}
+
+uint32_t csr_get_frag_thresh(tpAniSirGlobal mac_ctx)
+{
+	return mac_ctx->mlme_cfg->threshold.frag_threshold;
+}
+
+uint32_t csr_get_rts_thresh(tpAniSirGlobal mac_ctx)
+{
+	return mac_ctx->mlme_cfg->threshold.rts_threshold;
+}
+
+static eCsrPhyMode
+csr_translate_to_phy_mode_from_bss_desc(tpAniSirGlobal mac_ctx,
+					tSirBssDescription *pSirBssDesc,
+					tDot11fBeaconIEs *ies)
+{
+	eCsrPhyMode phyMode;
+	uint8_t i;
+
+	switch (pSirBssDesc->nwType) {
+	case eSIR_11A_NW_TYPE:
+		phyMode = eCSR_DOT11_MODE_11a;
+		break;
+
+	case eSIR_11B_NW_TYPE:
+		phyMode = eCSR_DOT11_MODE_11b;
+		break;
+
+	case eSIR_11G_NW_TYPE:
+		phyMode = eCSR_DOT11_MODE_11g_ONLY;
+
+		/* Check if the BSS is in b/g mixed mode or g_only mode */
+		if (!ies || !ies->SuppRates.present) {
+			sme_debug("Unable to get rates, assume G only mode");
+			break;
+		}
+
+		for (i = 0; i < ies->SuppRates.num_rates; i++) {
+			if (csr_rates_is_dot11_rate11b_supported_rate(
+			    ies->SuppRates.rates[i])) {
+				sme_debug("One B rate is supported");
+				phyMode = eCSR_DOT11_MODE_11g;
+				break;
+			}
+		}
+		break;
+	case eSIR_11N_NW_TYPE:
+		phyMode = eCSR_DOT11_MODE_11n;
+		break;
+	case eSIR_11AX_NW_TYPE:
+		phyMode = eCSR_DOT11_MODE_11ax;
+		break;
+	case eSIR_11AC_NW_TYPE:
+	default:
+		phyMode = eCSR_DOT11_MODE_11ac;
+		break;
+	}
+	return phyMode;
+}
+
+uint32_t csr_translate_to_wni_cfg_dot11_mode(tpAniSirGlobal pMac,
+					     enum csr_cfgdot11mode csrDot11Mode)
+{
+	uint32_t ret;
+
+	switch (csrDot11Mode) {
+	case eCSR_CFG_DOT11_MODE_AUTO:
+		sme_debug("eCSR_CFG_DOT11_MODE_AUTO");
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX))
+			ret = WNI_CFG_DOT11_MODE_11AX;
+		else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			ret = WNI_CFG_DOT11_MODE_11AC;
+		else
+			ret = WNI_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_CFG_DOT11_MODE_11A:
+		ret = WNI_CFG_DOT11_MODE_11A;
+		break;
+	case eCSR_CFG_DOT11_MODE_11B:
+		ret = WNI_CFG_DOT11_MODE_11B;
+		break;
+	case eCSR_CFG_DOT11_MODE_11G:
+		ret = WNI_CFG_DOT11_MODE_11G;
+		break;
+	case eCSR_CFG_DOT11_MODE_11N:
+		ret = WNI_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_CFG_DOT11_MODE_11G_ONLY:
+		ret = WNI_CFG_DOT11_MODE_11G_ONLY;
+		break;
+	case eCSR_CFG_DOT11_MODE_11N_ONLY:
+		ret = WNI_CFG_DOT11_MODE_11N_ONLY;
+		break;
+	case eCSR_CFG_DOT11_MODE_11AC_ONLY:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			ret = WNI_CFG_DOT11_MODE_11AC_ONLY;
+		else
+			ret = WNI_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_CFG_DOT11_MODE_11AC:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			ret = WNI_CFG_DOT11_MODE_11AC;
+		else
+			ret = WNI_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_CFG_DOT11_MODE_11AX_ONLY:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX))
+			ret = WNI_CFG_DOT11_MODE_11AX_ONLY;
+		else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			ret = WNI_CFG_DOT11_MODE_11AC;
+		else
+			ret = WNI_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_CFG_DOT11_MODE_11AX:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX))
+			ret = WNI_CFG_DOT11_MODE_11AX;
+		else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			ret = WNI_CFG_DOT11_MODE_11AC;
+		else
+			ret = WNI_CFG_DOT11_MODE_11N;
+		break;
+	default:
+		sme_warn("doesn't expect %d as csrDo11Mode", csrDot11Mode);
+		if (BAND_2G == pMac->mlme_cfg->gen.band)
+			ret = WNI_CFG_DOT11_MODE_11G;
+		else
+			ret = WNI_CFG_DOT11_MODE_11A;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * csr_get_phy_mode_from_bss() - Get Phy Mode
+ * @pMac:           Global MAC context
+ * @pBSSDescription: BSS Descriptor
+ * @pPhyMode:        Physical Mode
+ * @pIes:            Pointer to the IE fields
+ *
+ * This function should only return the super set of supported modes
+ * 11n implies 11b/g/a/n.
+ *
+ * Return: success
+ **/
+QDF_STATUS csr_get_phy_mode_from_bss(tpAniSirGlobal pMac,
+		tSirBssDescription *pBSSDescription,
+		eCsrPhyMode *pPhyMode, tDot11fBeaconIEs *pIes)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	eCsrPhyMode phyMode =
+		csr_translate_to_phy_mode_from_bss_desc(pMac, pBSSDescription,
+							pIes);
+
+	if (pIes) {
+		if (pIes->HTCaps.present) {
+			phyMode = eCSR_DOT11_MODE_11n;
+			if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps) ||
+				IS_BSS_VHT_CAPABLE(pIes->vendor_vht_ie.VHTCaps))
+				phyMode = eCSR_DOT11_MODE_11ac;
+			if (pIes->he_cap.present)
+				phyMode = eCSR_DOT11_MODE_11ax;
+		}
+		*pPhyMode = phyMode;
+	}
+
+	return status;
+}
+
+/**
+ * csr_get_phy_mode_in_use() - to get phymode
+ * @phyModeIn: physical mode
+ * @bssPhyMode: physical mode in bss
+ * @f5GhzBand: 5Ghz band
+ * @pCfgDot11ModeToUse: dot11 mode in use
+ *
+ * This function returns the correct eCSR_CFG_DOT11_MODE is the two phyModes
+ * matches. bssPhyMode is the mode derived from the BSS description
+ * f5GhzBand is derived from the channel id of BSS description
+ *
+ * Return: true or false
+ */
+static bool csr_get_phy_mode_in_use(tpAniSirGlobal mac_ctx,
+				    eCsrPhyMode phyModeIn,
+				    eCsrPhyMode bssPhyMode,
+				    bool f5GhzBand,
+				    enum csr_cfgdot11mode *pCfgDot11ModeToUse)
+{
+	bool fMatch = false;
+	enum csr_cfgdot11mode cfgDot11Mode;
+
+	cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+	switch (phyModeIn) {
+	/* 11a or 11b or 11g */
+	case eCSR_DOT11_MODE_abg:
+		fMatch = true;
+		if (f5GhzBand)
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+		else if (eCSR_DOT11_MODE_11b == bssPhyMode)
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+		else
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+		break;
+
+	case eCSR_DOT11_MODE_11a:
+		if (f5GhzBand) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11g:
+		if (!f5GhzBand) {
+			fMatch = true;
+			if (eCSR_DOT11_MODE_11b == bssPhyMode)
+				cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+			else
+				cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11g_ONLY:
+		if ((bssPhyMode == eCSR_DOT11_MODE_11g) ||
+		    (bssPhyMode == eCSR_DOT11_MODE_11g_ONLY)) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11b:
+	case eCSR_DOT11_MODE_11b_ONLY:
+		if (!f5GhzBand && (bssPhyMode != eCSR_DOT11_MODE_11g_ONLY)) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11n:
+		fMatch = true;
+		switch (bssPhyMode) {
+		case eCSR_DOT11_MODE_11g:
+		case eCSR_DOT11_MODE_11g_ONLY:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+			break;
+		case eCSR_DOT11_MODE_11b:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+			break;
+		case eCSR_DOT11_MODE_11a:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+			break;
+		case eCSR_DOT11_MODE_11n:
+		case eCSR_DOT11_MODE_11ac:
+		case eCSR_DOT11_MODE_11ax:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+			break;
+
+		default:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+			break;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11n_ONLY:
+		if (eCSR_DOT11_MODE_11n == bssPhyMode) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+
+		}
+
+		break;
+	case eCSR_DOT11_MODE_11ac:
+		fMatch = true;
+		switch (bssPhyMode) {
+		case eCSR_DOT11_MODE_11g:
+		case eCSR_DOT11_MODE_11g_ONLY:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+			break;
+		case eCSR_DOT11_MODE_11b:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+			break;
+		case eCSR_DOT11_MODE_11a:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+			break;
+		case eCSR_DOT11_MODE_11n:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+			break;
+		case eCSR_DOT11_MODE_11ac:
+		case eCSR_DOT11_MODE_11ax:
+		default:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+			break;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11ac_ONLY:
+		if (eCSR_DOT11_MODE_11ac == bssPhyMode) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+		}
+		break;
+	case eCSR_DOT11_MODE_11ax:
+		fMatch = true;
+		switch (bssPhyMode) {
+		case eCSR_DOT11_MODE_11g:
+		case eCSR_DOT11_MODE_11g_ONLY:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+			break;
+		case eCSR_DOT11_MODE_11b:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+			break;
+		case eCSR_DOT11_MODE_11a:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+			break;
+		case eCSR_DOT11_MODE_11n:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+			break;
+		case eCSR_DOT11_MODE_11ac:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+			break;
+		case eCSR_DOT11_MODE_11ax:
+		default:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AX;
+			break;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11ax_ONLY:
+		if (eCSR_DOT11_MODE_11ax == bssPhyMode) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AX;
+		}
+		break;
+
+	default:
+		fMatch = true;
+		switch (bssPhyMode) {
+		case eCSR_DOT11_MODE_11g:
+		case eCSR_DOT11_MODE_11g_ONLY:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+			break;
+		case eCSR_DOT11_MODE_11b:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+			break;
+		case eCSR_DOT11_MODE_11a:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+			break;
+		case eCSR_DOT11_MODE_11n:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+			break;
+		case eCSR_DOT11_MODE_11ac:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+			break;
+		case eCSR_DOT11_MODE_11ax:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AX;
+			break;
+		default:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
+			break;
+		}
+		break;
+	}
+
+	if (fMatch && pCfgDot11ModeToUse) {
+		if (cfgDot11Mode == eCSR_CFG_DOT11_MODE_11AX) {
+			if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX))
+				*pCfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AX;
+			else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+				*pCfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AC;
+			else
+				*pCfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
+		} else {
+			if (cfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC
+			    && (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)))
+				*pCfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
+			else
+				*pCfgDot11ModeToUse = cfgDot11Mode;
+		}
+	}
+	return fMatch;
+}
+
+/**
+ * csr_is_phy_mode_match() - to find if phy mode matches
+ * @pMac: pointer to mac context
+ * @phyMode: physical mode
+ * @pSirBssDesc: bss description
+ * @pProfile: pointer to roam profile
+ * @pReturnCfgDot11Mode: dot1 mode to return
+ * @pIes: pointer to IEs
+ *
+ * This function decides whether the one of the bit of phyMode is matching the
+ * mode in the BSS and allowed by the user setting
+ *
+ * Return: true or false based on mode that fits the criteria
+ */
+bool csr_is_phy_mode_match(tpAniSirGlobal pMac, uint32_t phyMode,
+			   tSirBssDescription *pSirBssDesc,
+			   struct csr_roam_profile *pProfile,
+			   enum csr_cfgdot11mode *pReturnCfgDot11Mode,
+			   tDot11fBeaconIEs *pIes)
+{
+	bool fMatch = false;
+	eCsrPhyMode phyModeInBssDesc = eCSR_DOT11_MODE_AUTO, phyMode2;
+	enum csr_cfgdot11mode cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_AUTO;
+	uint32_t bitMask, loopCount;
+
+	if (!QDF_IS_STATUS_SUCCESS(csr_get_phy_mode_from_bss(pMac, pSirBssDesc,
+					&phyModeInBssDesc, pIes)))
+		return fMatch;
+
+	if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) {
+		if (eCSR_CFG_DOT11_MODE_ABG ==
+				pMac->roam.configParam.uCfgDot11Mode) {
+			phyMode = eCSR_DOT11_MODE_abg;
+		} else if (eCSR_CFG_DOT11_MODE_AUTO ==
+				pMac->roam.configParam.uCfgDot11Mode) {
+			if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX))
+				phyMode = eCSR_DOT11_MODE_11ax;
+			else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+				phyMode = eCSR_DOT11_MODE_11ac;
+			else
+				phyMode = eCSR_DOT11_MODE_11n;
+		} else {
+			/* user's pick */
+			phyMode = pMac->roam.configParam.phyMode;
+		}
+	}
+
+	if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) {
+		if (0 != phyMode) {
+			if (eCSR_DOT11_MODE_AUTO & phyMode) {
+				phyMode2 =
+					eCSR_DOT11_MODE_AUTO & phyMode;
+			}
+		} else {
+			phyMode2 = phyMode;
+		}
+		fMatch = csr_get_phy_mode_in_use(pMac, phyMode2,
+						 phyModeInBssDesc,
+						 WLAN_REG_IS_5GHZ_CH(
+						 pSirBssDesc->channelId),
+						 &cfgDot11ModeToUse);
+	} else {
+		bitMask = 1;
+		loopCount = 0;
+		while (loopCount < eCSR_NUM_PHY_MODE) {
+			phyMode2 = (phyMode & (bitMask << loopCount++));
+			if (0 != phyMode2 &&
+			    csr_get_phy_mode_in_use(pMac, phyMode2,
+			    phyModeInBssDesc,
+			    WLAN_REG_IS_5GHZ_CH(pSirBssDesc->channelId),
+			    &cfgDot11ModeToUse)) {
+				fMatch = true;
+				break;
+			}
+		}
+	}
+	if (fMatch && pReturnCfgDot11Mode) {
+		if (pProfile) {
+			/*
+			 * IEEE 11n spec (8.4.3): HT STA shall
+			 * eliminate TKIP as a choice for the pairwise
+			 * cipher suite if CCMP is advertised by the AP
+			 * or if the AP included an HT capabilities
+			 * element in its Beacons and Probe Response.
+			 */
+			if ((!CSR_IS_11n_ALLOWED(
+					pProfile->negotiatedUCEncryptionType))
+					&& ((eCSR_CFG_DOT11_MODE_11N ==
+						cfgDot11ModeToUse) ||
+					(eCSR_CFG_DOT11_MODE_11AC ==
+						cfgDot11ModeToUse) ||
+					(eCSR_CFG_DOT11_MODE_11AX ==
+						cfgDot11ModeToUse))) {
+				/* We cannot do 11n here */
+				if (!WLAN_REG_IS_5GHZ_CH
+						(pSirBssDesc->channelId)) {
+					cfgDot11ModeToUse =
+						eCSR_CFG_DOT11_MODE_11G;
+				} else {
+					cfgDot11ModeToUse =
+						eCSR_CFG_DOT11_MODE_11A;
+				}
+			}
+		}
+		*pReturnCfgDot11Mode = cfgDot11ModeToUse;
+	}
+
+	return fMatch;
+}
+
+enum csr_cfgdot11mode csr_find_best_phy_mode(tpAniSirGlobal pMac,
+			uint32_t phyMode)
+{
+	enum csr_cfgdot11mode cfgDot11ModeToUse;
+	enum band_info eBand = pMac->mlme_cfg->gen.band;
+
+	if ((0 == phyMode) ||
+	    (eCSR_DOT11_MODE_AUTO & phyMode) ||
+	    (eCSR_DOT11_MODE_11ax & phyMode)) {
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) {
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AX;
+		} else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AC;
+		} else {
+			/* Default to 11N mode if user has configured 11ac mode
+			 * and FW doesn't supports 11ac mode .
+			 */
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
+		}
+	} else if (eCSR_DOT11_MODE_11ac & phyMode) {
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AC;
+		} else {
+			/* Default to 11N mode if user has configured 11ac mode
+			 * and FW doesn't supports 11ac mode .
+			 */
+		}	cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
+	} else {
+		if ((eCSR_DOT11_MODE_11n | eCSR_DOT11_MODE_11n_ONLY) & phyMode)
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
+		else if (eCSR_DOT11_MODE_abg & phyMode) {
+			if (BAND_2G != eBand)
+				cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
+			else
+				cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
+		} else if (eCSR_DOT11_MODE_11a & phyMode)
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
+		else if ((eCSR_DOT11_MODE_11g | eCSR_DOT11_MODE_11g_ONLY) &
+			   phyMode)
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
+		else
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11B;
+	}
+
+	return cfgDot11ModeToUse;
+}
+
+uint32_t csr_get11h_power_constraint(tpAniSirGlobal mac_ctx,
+				     tDot11fIEPowerConstraints *constraints)
+{
+	uint32_t localPowerConstraint = 0;
+
+	/* check if .11h support is enabled, if not,
+	 * the power constraint is 0.
+	 */
+	if (mac_ctx->roam.configParam.Is11hSupportEnabled &&
+	    constraints->present) {
+		localPowerConstraint = constraints->localPowerConstraints;
+	}
+
+	return localPowerConstraint;
+}
+
+bool csr_is_profile_wpa(struct csr_roam_profile *pProfile)
+{
+	bool fWpaProfile = false;
+
+	switch (pProfile->negotiatedAuthType) {
+	case eCSR_AUTH_TYPE_WPA:
+	case eCSR_AUTH_TYPE_WPA_PSK:
+	case eCSR_AUTH_TYPE_WPA_NONE:
+#ifdef FEATURE_WLAN_ESE
+	case eCSR_AUTH_TYPE_CCKM_WPA:
+#endif
+		fWpaProfile = true;
+		break;
+
+	default:
+		fWpaProfile = false;
+		break;
+	}
+
+	if (fWpaProfile) {
+		switch (pProfile->negotiatedUCEncryptionType) {
+		case eCSR_ENCRYPT_TYPE_WEP40:
+		case eCSR_ENCRYPT_TYPE_WEP104:
+		case eCSR_ENCRYPT_TYPE_TKIP:
+		case eCSR_ENCRYPT_TYPE_AES:
+			fWpaProfile = true;
+			break;
+
+		default:
+			fWpaProfile = false;
+			break;
+		}
+	}
+	return fWpaProfile;
+}
+
+bool csr_is_profile_rsn(struct csr_roam_profile *pProfile)
+{
+	bool fRSNProfile = false;
+
+	switch (pProfile->negotiatedAuthType) {
+	case eCSR_AUTH_TYPE_RSN:
+	case eCSR_AUTH_TYPE_RSN_PSK:
+	case eCSR_AUTH_TYPE_FT_RSN:
+	case eCSR_AUTH_TYPE_FT_RSN_PSK:
+#ifdef FEATURE_WLAN_ESE
+	case eCSR_AUTH_TYPE_CCKM_RSN:
+#endif
+#ifdef WLAN_FEATURE_11W
+	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
+#endif
+	/* fallthrough */
+	case eCSR_AUTH_TYPE_FILS_SHA256:
+	case eCSR_AUTH_TYPE_FILS_SHA384:
+	case eCSR_AUTH_TYPE_FT_FILS_SHA256:
+	case eCSR_AUTH_TYPE_FT_FILS_SHA384:
+	case eCSR_AUTH_TYPE_DPP_RSN:
+		fRSNProfile = true;
+		break;
+
+	case eCSR_AUTH_TYPE_OWE:
+	case eCSR_AUTH_TYPE_SUITEB_EAP_SHA256:
+	case eCSR_AUTH_TYPE_SUITEB_EAP_SHA384:
+		fRSNProfile = true;
+		break;
+	case eCSR_AUTH_TYPE_SAE:
+		fRSNProfile = true;
+		break;
+
+	default:
+		fRSNProfile = false;
+		break;
+	}
+
+	if (fRSNProfile) {
+		switch (pProfile->negotiatedUCEncryptionType) {
+		/* !!REVIEW - For WPA2, use of RSN IE mandates */
+		/* use of AES as encryption. Here, we qualify */
+		/* even if encryption type is WEP or TKIP */
+		case eCSR_ENCRYPT_TYPE_WEP40:
+		case eCSR_ENCRYPT_TYPE_WEP104:
+		case eCSR_ENCRYPT_TYPE_TKIP:
+		case eCSR_ENCRYPT_TYPE_AES:
+		case eCSR_ENCRYPT_TYPE_AES_GCMP:
+		case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
+			fRSNProfile = true;
+			break;
+
+		default:
+			fRSNProfile = false;
+			break;
+		}
+	}
+	return fRSNProfile;
+}
+
+/**
+ * csr_update_mcc_p2p_beacon_interval() - update p2p beacon interval
+ * @mac_ctx: pointer to mac context
+ *
+ * This function is to update the mcc p2p beacon interval
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS csr_update_mcc_p2p_beacon_interval(tpAniSirGlobal mac_ctx)
+{
+	uint32_t session_id = 0;
+	struct csr_roam_session *roam_session;
+
+	/* If MCC is not supported just break and return SUCCESS */
+	if (!mac_ctx->roam.configParam.fenableMCCMode)
+		return QDF_STATUS_E_FAILURE;
+
+	for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
+		/*
+		 * If GO in MCC support different beacon interval,
+		 * change the BI of the P2P-GO
+		 */
+		roam_session = &mac_ctx->roam.roamSession[session_id];
+		if (roam_session->bssParams.bssPersona != QDF_P2P_GO_MODE)
+			continue;
+		/*
+		 * Handle different BI scneario based on the
+		 * configuration set.If Config is set to 0x02 then
+		 * Disconnect all the P2P clients associated. If config
+		 * is set to 0x04 then update the BI without
+		 * disconnecting all the clients
+		 */
+		if ((mac_ctx->roam.configParam.fAllowMCCGODiffBI == 0x04)
+				&& (roam_session->bssParams.
+					updatebeaconInterval)) {
+			return csr_send_chng_mcc_beacon_interval(mac_ctx,
+					session_id);
+		} else if (roam_session->bssParams.updatebeaconInterval) {
+			/*
+			 * If the configuration of fAllowMCCGODiffBI is set to
+			 * other than 0x04
+			 */
+			return csr_roam_call_callback(mac_ctx,
+					session_id,
+					NULL, 0,
+					eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS,
+					eCSR_ROAM_RESULT_NONE);
+		}
+	}
+	return QDF_STATUS_E_FAILURE;
+}
+
+static uint16_t csr_calculate_mcc_beacon_interval(tpAniSirGlobal pMac,
+						  uint16_t sta_bi,
+						  uint16_t go_gbi)
+{
+	uint8_t num_beacons = 0;
+	uint8_t is_multiple = 0;
+	uint16_t go_cbi = 0;
+	uint16_t go_fbi = 0;
+	uint16_t sta_cbi = 0;
+
+	/* If GO's given beacon Interval is less than 100 */
+	if (go_gbi < 100)
+		go_cbi = 100;
+	/* if GO's given beacon Interval is greater than or equal to 100 */
+	else
+		go_cbi = 100 + (go_gbi % 100);
+
+	if (sta_bi == 0) {
+		/* There is possibility to receive zero as value.
+		 * Which will cause divide by zero. Hence initialise with 100
+		 */
+		sta_bi = 100;
+		sme_warn("sta_bi 2nd parameter is zero, initialize to %d",
+			sta_bi);
+	}
+	/* check, if either one is multiple of another */
+	if (sta_bi > go_cbi)
+		is_multiple = !(sta_bi % go_cbi);
+	else
+		is_multiple = !(go_cbi % sta_bi);
+
+	/* if it is multiple, then accept GO's beacon interval
+	 * range [100,199] as it is
+	 */
+	if (is_multiple)
+		return go_cbi;
+
+	/* else , if it is not multiple, then then check for number of beacons
+	 * to be inserted based on sta BI
+	 */
+	num_beacons = sta_bi / 100;
+	if (num_beacons) {
+		/* GO's final beacon interval will be aligned to sta beacon
+		 * interval, but in the range of [100, 199].
+		 */
+		sta_cbi = sta_bi / num_beacons;
+		go_fbi = sta_cbi;
+	} else
+		/* if STA beacon interval is less than 100, use GO's change
+		 * bacon interval instead of updating to STA's beacon interval.
+		 */
+		go_fbi = go_cbi;
+
+	return go_fbi;
+}
+
+/**
+ * csr_validate_p2pcli_bcn_intrvl() - to validate p2pcli beacon interval
+ * @mac_ctx: pointer to mac context
+ * @chnl_id: channel id variable
+ * @bcn_interval: pointer to given beacon interval
+ * @session_id: given session id
+ * @status: fill the status in terms of QDF_STATUS to inform caller
+ *
+ * This API can provide the validation the beacon interval and re-calculate
+ * in case concurrency
+ *
+ * Return: bool
+ */
+static bool csr_validate_p2pcli_bcn_intrvl(tpAniSirGlobal mac_ctx,
+		uint8_t chnl_id, uint16_t *bcn_interval, uint32_t session_id,
+		QDF_STATUS *status)
+{
+	struct csr_roam_session *roamsession;
+
+	roamsession = &mac_ctx->roam.roamSession[session_id];
+	if (roamsession->pCurRoamProfile &&
+		(roamsession->pCurRoamProfile->csrPersona ==
+			 QDF_STA_MODE)) {
+		/* check for P2P client mode */
+		sme_debug("Ignore Beacon Interval Validation...");
+	} else if (roamsession->bssParams.bssPersona == QDF_P2P_GO_MODE) {
+		/* Check for P2P go scenario */
+		if ((roamsession->bssParams.operationChn != chnl_id)
+			&& (roamsession->bssParams.beaconInterval !=
+				*bcn_interval)) {
+			sme_err("BcnIntrvl is diff can't connect to P2P_GO network");
+			*status = QDF_STATUS_E_FAILURE;
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * csr_validate_p2pgo_bcn_intrvl() - to validate p2pgo beacon interval
+ * @mac_ctx: pointer to mac context
+ * @chnl_id: channel id variable
+ * @bcn_interval: pointer to given beacon interval
+ * @session_id: given session id
+ * @status: fill the status in terms of QDF_STATUS to inform caller
+ *
+ * This API can provide the validation the beacon interval and re-calculate
+ * in case concurrency
+ *
+ * Return: bool
+ */
+static bool csr_validate_p2pgo_bcn_intrvl(tpAniSirGlobal mac_ctx,
+		uint8_t chnl_id, uint16_t *bcn_interval,
+		uint32_t session_id, QDF_STATUS *status)
+{
+	struct csr_roam_session *roamsession;
+	struct csr_config *cfg_param;
+	tCsrRoamConnectedProfile *conn_profile;
+	uint16_t new_bcn_interval;
+
+	roamsession = &mac_ctx->roam.roamSession[session_id];
+	cfg_param = &mac_ctx->roam.configParam;
+	conn_profile = &roamsession->connectedProfile;
+	if (roamsession->pCurRoamProfile &&
+		((roamsession->pCurRoamProfile->csrPersona ==
+			  QDF_P2P_CLIENT_MODE) ||
+		(roamsession->pCurRoamProfile->csrPersona ==
+			  QDF_STA_MODE))) {
+		/* check for P2P_client scenario */
+		if ((conn_profile->operationChannel == 0) &&
+			(conn_profile->beaconInterval == 0))
+			return false;
+
+		if (csr_is_conn_state_connected_infra(mac_ctx, session_id) &&
+			(conn_profile->operationChannel != chnl_id) &&
+			(conn_profile->beaconInterval != *bcn_interval)) {
+			/*
+			 * Updated beaconInterval should be used only when
+			 * we are starting a new BSS not incase of
+			 * client or STA case
+			 */
+
+			/* Calculate beacon Interval for P2P-GO incase of MCC */
+			if (cfg_param->conc_custom_rule1 ||
+					cfg_param->conc_custom_rule2) {
+				new_bcn_interval = CSR_CUSTOM_CONC_GO_BI;
+			} else {
+				new_bcn_interval =
+					csr_calculate_mcc_beacon_interval(
+						mac_ctx,
+						conn_profile->beaconInterval,
+						*bcn_interval);
+			}
+			if (*bcn_interval != new_bcn_interval)
+				*bcn_interval = new_bcn_interval;
+			*status = QDF_STATUS_SUCCESS;
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * csr_validate_sta_bcn_intrvl() - to validate sta beacon interval
+ * @mac_ctx: pointer to mac context
+ * @chnl_id: channel id variable
+ * @bcn_interval: pointer to given beacon interval
+ * @session_id: given session id
+ * @status: fill the status in terms of QDF_STATUS to inform caller
+ *
+ * This API can provide the validation the beacon interval and re-calculate
+ * in case concurrency
+ *
+ * Return: bool
+ */
+static bool csr_validate_sta_bcn_intrvl(tpAniSirGlobal mac_ctx,
+			uint8_t chnl_id, uint16_t *bcn_interval,
+			uint32_t session_id, QDF_STATUS *status)
+{
+	struct csr_roam_session *roamsession;
+	struct csr_config *cfg_param;
+	uint16_t new_bcn_interval;
+
+	roamsession = &mac_ctx->roam.roamSession[session_id];
+	cfg_param = &mac_ctx->roam.configParam;
+
+	if (roamsession->pCurRoamProfile &&
+		(roamsession->pCurRoamProfile->csrPersona ==
+				QDF_P2P_CLIENT_MODE)) {
+		/* check for P2P client mode */
+		sme_debug("Bcn Intrvl validation not require for STA/CLIENT");
+		return false;
+	}
+	if ((roamsession->bssParams.bssPersona == QDF_SAP_MODE) &&
+		   (roamsession->bssParams.operationChn != chnl_id)) {
+		/*
+		 * IF SAP has started and STA wants to connect
+		 * on different channel MCC should
+		 *  MCC should not be enabled so making it
+		 * false to enforce on same channel
+		 */
+		sme_err("*** MCC with SAP+STA sessions ****");
+		*status = QDF_STATUS_SUCCESS;
+		return true;
+	}
+	/*
+	 * Check for P2P go scenario
+	 * if GO in MCC support different
+	 * beacon interval,
+	 * change the BI of the P2P-GO
+	 */
+	if ((roamsession->bssParams.bssPersona == QDF_P2P_GO_MODE) &&
+		(roamsession->bssParams.operationChn != chnl_id) &&
+		(roamsession->bssParams.beaconInterval != *bcn_interval)) {
+		/* if GO in MCC support diff beacon interval, return success */
+		if (cfg_param->fAllowMCCGODiffBI == 0x01) {
+			*status = QDF_STATUS_SUCCESS;
+			return true;
+		}
+		/*
+		 * Send only Broadcast disassoc and update bcn_interval
+		 * If configuration is set to 0x04 then dont
+		 * disconnect all the station
+		 */
+		if ((cfg_param->fAllowMCCGODiffBI == 0x02)
+			|| (cfg_param->fAllowMCCGODiffBI == 0x04)) {
+			/* Check to pass the right beacon Interval */
+			if (cfg_param->conc_custom_rule1 ||
+				cfg_param->conc_custom_rule2) {
+				new_bcn_interval = CSR_CUSTOM_CONC_GO_BI;
+			} else {
+				new_bcn_interval =
+				csr_calculate_mcc_beacon_interval(
+					mac_ctx, *bcn_interval,
+					roamsession->bssParams.beaconInterval);
+			}
+			sme_debug("Peer AP BI : %d, new Beacon Interval: %d",
+				*bcn_interval, new_bcn_interval);
+			/* Update the becon Interval */
+			if (new_bcn_interval !=
+					roamsession->bssParams.beaconInterval) {
+				/* Update the bcn_interval now */
+				sme_err("Beacon Interval got changed config used: %d",
+					cfg_param->fAllowMCCGODiffBI);
+
+				roamsession->bssParams.beaconInterval =
+					new_bcn_interval;
+				roamsession->bssParams.updatebeaconInterval =
+					true;
+				*status = csr_update_mcc_p2p_beacon_interval(
+					mac_ctx);
+				return true;
+			}
+			*status = QDF_STATUS_SUCCESS;
+			return true;
+		}
+		if (cfg_param->fAllowMCCGODiffBI
+				== 0x03) {
+			/* Disconnect the P2P session */
+			roamsession->bssParams.updatebeaconInterval = false;
+			*status = csr_roam_call_callback(mac_ctx,
+					session_id, NULL, 0,
+					eCSR_ROAM_SEND_P2P_STOP_BSS,
+					eCSR_ROAM_RESULT_NONE);
+			return true;
+		}
+		sme_err("BcnIntrvl is diff can't connect to preferred AP");
+		*status = QDF_STATUS_E_FAILURE;
+		return true;
+	}
+	return false;
+}
+
+/**
+ * csr_validate_mcc_beacon_interval() - to validate the mcc beacon interval
+ * @mac_ctx: pointer to mac context
+ * @chnl_id: channel number
+ * @bcn_interval: provided beacon interval
+ * @cur_session_id: current session id
+ * @cur_bss_persona: Current BSS persona
+ *
+ * This API will validate the mcc beacon interval
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS csr_validate_mcc_beacon_interval(tpAniSirGlobal mac_ctx,
+					uint8_t chnl_id,
+					uint16_t *bcn_interval,
+					uint32_t cur_session_id,
+					enum QDF_OPMODE cur_bss_persona)
+{
+	uint32_t session_id = 0;
+	QDF_STATUS status;
+	bool is_done;
+
+	/* If MCC is not supported just break */
+	if (!mac_ctx->roam.configParam.fenableMCCMode)
+		return QDF_STATUS_E_FAILURE;
+
+	for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
+		if (cur_session_id == session_id)
+			continue;
+
+		if (!CSR_IS_SESSION_VALID(mac_ctx, session_id))
+			continue;
+
+		switch (cur_bss_persona) {
+		case QDF_STA_MODE:
+			is_done = csr_validate_sta_bcn_intrvl(mac_ctx, chnl_id,
+					bcn_interval, session_id, &status);
+			if (true == is_done)
+				return status;
+			break;
+
+		case QDF_P2P_CLIENT_MODE:
+			is_done = csr_validate_p2pcli_bcn_intrvl(mac_ctx,
+					chnl_id, bcn_interval, session_id,
+					&status);
+			if (true == is_done)
+				return status;
+			break;
+
+		case QDF_SAP_MODE:
+		case QDF_IBSS_MODE:
+			break;
+
+		case QDF_P2P_GO_MODE:
+			is_done = csr_validate_p2pgo_bcn_intrvl(mac_ctx,
+					chnl_id, bcn_interval,
+					session_id, &status);
+			if (true == is_done)
+				return status;
+			break;
+
+		default:
+			sme_err("Persona not supported: %d", cur_bss_persona);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_is_auth_type11r() - Check if Authentication type is 11R
+ * @mac: pointer to mac context
+ * @auth_type: The authentication type that is used to make the connection
+ * @mdie_present: Is MDIE IE present
+ *
+ * Return: true if is 11R auth type, false otherwise
+ */
+bool csr_is_auth_type11r(tpAniSirGlobal mac, eCsrAuthType auth_type,
+			uint8_t mdie_present)
+{
+	switch (auth_type) {
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		if (mdie_present &&
+		    mac->roam.configParam.enable_ftopen)
+			return true;
+		break;
+	case eCSR_AUTH_TYPE_FT_RSN_PSK:
+	case eCSR_AUTH_TYPE_FT_RSN:
+		return true;
+	default:
+		break;
+	}
+	return false;
+}
+
+/* Function to return true if the profile is 11r */
+bool csr_is_profile11r(tpAniSirGlobal mac,
+			struct csr_roam_profile *pProfile)
+{
+	return csr_is_auth_type11r(mac, pProfile->negotiatedAuthType,
+				   pProfile->MDID.mdiePresent);
+}
+
+bool csr_is_auth_type_ese(eCsrAuthType AuthType)
+{
+	switch (AuthType) {
+	case eCSR_AUTH_TYPE_CCKM_WPA:
+	case eCSR_AUTH_TYPE_CCKM_RSN:
+		return true;
+	default:
+		break;
+	}
+	return false;
+}
+
+#ifdef FEATURE_WLAN_ESE
+
+/* Function to return true if the profile is ESE */
+bool csr_is_profile_ese(struct csr_roam_profile *pProfile)
+{
+	return csr_is_auth_type_ese(pProfile->negotiatedAuthType);
+}
+
+#endif
+
+#ifdef FEATURE_WLAN_WAPI
+bool csr_is_profile_wapi(struct csr_roam_profile *pProfile)
+{
+	bool fWapiProfile = false;
+
+	switch (pProfile->negotiatedAuthType) {
+	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
+	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
+		fWapiProfile = true;
+		break;
+
+	default:
+		fWapiProfile = false;
+		break;
+	}
+
+	if (fWapiProfile) {
+		switch (pProfile->negotiatedUCEncryptionType) {
+		case eCSR_ENCRYPT_TYPE_WPI:
+			fWapiProfile = true;
+			break;
+
+		default:
+			fWapiProfile = false;
+			break;
+		}
+	}
+	return fWapiProfile;
+}
+
+static bool csr_is_wapi_oui_equal(tpAniSirGlobal pMac, uint8_t *Oui1,
+				  uint8_t *Oui2)
+{
+	return !qdf_mem_cmp(Oui1, Oui2, CSR_WAPI_OUI_SIZE);
+}
+
+static bool csr_is_wapi_oui_match(tpAniSirGlobal pMac,
+				  uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE],
+				  uint8_t cAllCyphers, uint8_t Cypher[],
+				  uint8_t Oui[])
+{
+	bool fYes = false;
+	uint8_t idx;
+
+	for (idx = 0; idx < cAllCyphers; idx++) {
+		if (csr_is_wapi_oui_equal(pMac, AllCyphers[idx], Cypher)) {
+			fYes = true;
+			break;
+		}
+	}
+
+	if (fYes && Oui)
+		qdf_mem_copy(Oui, AllCyphers[idx], CSR_WAPI_OUI_SIZE);
+
+	return fYes;
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+static bool csr_is_wpa_oui_equal(tpAniSirGlobal pMac, uint8_t *Oui1,
+				 uint8_t *Oui2)
+{
+	return !qdf_mem_cmp(Oui1, Oui2, CSR_WPA_OUI_SIZE);
+}
+
+static bool csr_is_oui_match(tpAniSirGlobal pMac,
+			     uint8_t AllCyphers[][CSR_WPA_OUI_SIZE],
+			   uint8_t cAllCyphers, uint8_t Cypher[], uint8_t Oui[])
+{
+	bool fYes = false;
+	uint8_t idx;
+
+	for (idx = 0; idx < cAllCyphers; idx++) {
+		if (csr_is_wpa_oui_equal(pMac, AllCyphers[idx], Cypher)) {
+			fYes = true;
+			break;
+		}
+	}
+
+	if (fYes && Oui)
+		qdf_mem_copy(Oui, AllCyphers[idx], CSR_WPA_OUI_SIZE);
+
+	return fYes;
+}
+
+static bool csr_match_rsnoui_index(tpAniSirGlobal pMac,
+				   uint8_t AllCyphers[][CSR_RSN_OUI_SIZE],
+				   uint8_t cAllCyphers, uint8_t ouiIndex,
+				   uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllCyphers, cAllCyphers, csr_rsn_oui[ouiIndex], Oui);
+
+}
+
+#ifdef FEATURE_WLAN_WAPI
+static bool csr_match_wapi_oui_index(tpAniSirGlobal pMac,
+				     uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE],
+				     uint8_t cAllCyphers, uint8_t ouiIndex,
+				     uint8_t Oui[])
+{
+	return csr_is_wapi_oui_match
+		(pMac, AllCyphers, cAllCyphers, csr_wapi_oui[ouiIndex], Oui);
+
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+static bool csr_match_wpaoui_index(tpAniSirGlobal pMac,
+				   uint8_t AllCyphers[][CSR_RSN_OUI_SIZE],
+				   uint8_t cAllCyphers, uint8_t ouiIndex,
+				   uint8_t Oui[])
+{
+	if (ouiIndex < QDF_ARRAY_SIZE(csr_wpa_oui))
+		return csr_is_oui_match
+			(pMac, AllCyphers, cAllCyphers,
+			 csr_wpa_oui[ouiIndex], Oui);
+	else
+		return false;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+static bool csr_is_auth_wapi_cert(tpAniSirGlobal pMac,
+				  uint8_t AllSuites[][CSR_WAPI_OUI_SIZE],
+				  uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_wapi_oui_match
+		(pMac, AllSuites, cAllSuites, csr_wapi_oui[1], Oui);
+}
+
+static bool csr_is_auth_wapi_psk(tpAniSirGlobal pMac,
+				 uint8_t AllSuites[][CSR_WAPI_OUI_SIZE],
+				 uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_wapi_oui_match
+		(pMac, AllSuites, cAllSuites, csr_wapi_oui[2], Oui);
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+
+/*
+ * Function for 11R FT Authentication. We match the FT Authentication Cipher
+ * suite here. This matches for FT Auth with the 802.1X exchange.
+ */
+static bool csr_is_ft_auth_rsn(tpAniSirGlobal pMac,
+			       uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+			       uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[03], Oui);
+}
+
+/*
+ * Function for 11R FT Authentication. We match the FT Authentication Cipher
+ * suite here. This matches for FT Auth with the PSK.
+ */
+static bool csr_is_ft_auth_rsn_psk(tpAniSirGlobal pMac,
+				   uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+				   uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[04], Oui);
+}
+
+
+#ifdef FEATURE_WLAN_ESE
+
+/*
+ * Function for ESE CCKM AKM Authentication. We match the CCKM AKM
+ * Authentication Key Management suite here. This matches for CCKM AKM Auth
+ * with the 802.1X exchange.
+ */
+static bool csr_is_ese_cckm_auth_rsn(tpAniSirGlobal pMac,
+				     uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+				     uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[06], Oui);
+}
+
+static bool csr_is_ese_cckm_auth_wpa(tpAniSirGlobal pMac,
+				     uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
+				     uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_wpa_oui[06], Oui);
+}
+
+#endif
+
+static bool csr_is_auth_rsn(tpAniSirGlobal pMac,
+			    uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+			    uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[01], Oui);
+}
+
+static bool csr_is_auth_rsn_psk(tpAniSirGlobal pMac,
+				uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+				uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[02], Oui);
+}
+
+#ifdef WLAN_FEATURE_11W
+static bool csr_is_auth_rsn_psk_sha256(tpAniSirGlobal pMac,
+				       uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+				       uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[07], Oui);
+}
+static bool csr_is_auth_rsn8021x_sha256(tpAniSirGlobal pMac,
+					uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+					uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[8], Oui);
+}
+#endif
+
+#ifdef WLAN_FEATURE_FILS_SK
+/*
+ * csr_is_auth_fils_sha256() - check whether oui is fils sha256
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is FILS SHA256, false otherwise
+ */
+static bool csr_is_auth_fils_sha256(tpAniSirGlobal mac,
+					uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+					uint8_t suite_count, uint8_t oui[])
+{
+	return csr_is_oui_match(mac, all_suites, suite_count,
+				csr_rsn_oui[ENUM_FILS_SHA256], oui);
+}
+
+/*
+ * csr_is_auth_fils_sha384() - check whether oui is fils sha384
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is FILS SHA384, false otherwise
+ */
+static bool csr_is_auth_fils_sha384(tpAniSirGlobal mac,
+					uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+					uint8_t suite_count, uint8_t oui[])
+{
+	return csr_is_oui_match(mac, all_suites, suite_count,
+				csr_rsn_oui[ENUM_FILS_SHA384], oui);
+}
+
+/*
+ * csr_is_auth_fils_ft_sha256() - check whether oui is fils ft sha256
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is FT FILS SHA256, false otherwise
+ */
+static bool csr_is_auth_fils_ft_sha256(tpAniSirGlobal mac,
+					uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+					uint8_t suite_count, uint8_t oui[])
+{
+	return csr_is_oui_match(mac, all_suites, suite_count,
+				csr_rsn_oui[ENUM_FT_FILS_SHA256], oui);
+}
+
+/*
+ * csr_is_auth_fils_ft_sha384() - check whether oui is fils ft sha384
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is FT FILS SHA384, false otherwise
+ */
+static bool csr_is_auth_fils_ft_sha384(tpAniSirGlobal mac,
+					uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+					uint8_t suite_count, uint8_t oui[])
+{
+	return csr_is_oui_match(mac, all_suites, suite_count,
+				csr_rsn_oui[ENUM_FT_FILS_SHA384], oui);
+}
+#endif
+
+/*
+ * csr_is_auth_dpp_rsn() - check whether oui is dpp rsn
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is dpp rsn, false otherwise
+ */
+static bool csr_is_auth_dpp_rsn(tpAniSirGlobal mac,
+					uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+					uint8_t suite_count, uint8_t oui[])
+{
+	return csr_is_oui_match(mac, all_suites, suite_count,
+				csr_rsn_oui[ENUM_DPP_RSN], oui);
+}
+
+/*
+ * csr_is_auth_wpa_owe() - check whether oui is OWE
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is OWE, false otherwise
+ */
+static bool csr_is_auth_wpa_owe(tpAniSirGlobal mac,
+			       uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+			       uint8_t suite_count, uint8_t oui[])
+{
+	return csr_is_oui_match
+		(mac, all_suites, suite_count, csr_rsn_oui[ENUM_OWE], oui);
+}
+
+/*
+ * csr_is_auth_suiteb_eap_256() - check whether oui is SuiteB EAP256
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is SuiteB EAP256, false otherwise
+ */
+static bool csr_is_auth_suiteb_eap_256(tpAniSirGlobal mac,
+			       uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+			       uint8_t suite_count, uint8_t oui[])
+{
+	return csr_is_oui_match(mac, all_suites, suite_count,
+				csr_rsn_oui[ENUM_SUITEB_EAP256], oui);
+}
+
+/*
+ * csr_is_auth_suiteb_eap_384() - check whether oui is SuiteB EAP384
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is SuiteB EAP384, false otherwise
+ */
+static bool csr_is_auth_suiteb_eap_384(tpAniSirGlobal mac,
+			       uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+			       uint8_t suite_count, uint8_t oui[])
+{
+	return csr_is_oui_match(mac, all_suites, suite_count,
+				csr_rsn_oui[ENUM_SUITEB_EAP384], oui);
+}
+
+#ifdef WLAN_FEATURE_SAE
+/*
+ * csr_is_auth_wpa_sae() - check whether oui is SAE
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is SAE, false otherwise
+ */
+static bool csr_is_auth_wpa_sae(tpAniSirGlobal mac,
+			       uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+			       uint8_t suite_count, uint8_t oui[])
+{
+	return csr_is_oui_match
+		(mac, all_suites, suite_count, csr_rsn_oui[ENUM_SAE], oui);
+}
+#endif
+
+static bool csr_is_auth_wpa(tpAniSirGlobal pMac,
+			    uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
+			    uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_wpa_oui[01], Oui);
+}
+
+static bool csr_is_auth_wpa_psk(tpAniSirGlobal pMac,
+				uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
+				uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_wpa_oui[02], Oui);
+}
+
+/*
+ * csr_is_group_mgmt_gmac_128() - check whether oui is GMAC_128
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is GMAC_128, false otherwise
+ */
+static bool csr_is_group_mgmt_gmac_128(tpAniSirGlobal pMac,
+				uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+				uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match(pMac, AllSuites, cAllSuites,
+				csr_group_mgmt_oui[ENUM_GMAC_128], Oui);
+}
+
+/*
+ * csr_is_group_mgmt_gmac_256() - check whether oui is GMAC_256
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is GMAC_256, false otherwise
+ */
+static bool csr_is_group_mgmt_gmac_256(tpAniSirGlobal pMac,
+				uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+				uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match(pMac, AllSuites, cAllSuites,
+				csr_group_mgmt_oui[ENUM_GMAC_256], Oui);
+}
+
+static uint8_t csr_get_oui_index_from_cipher(eCsrEncryptionType enType)
+{
+	uint8_t OUIIndex;
+
+	switch (enType) {
+	case eCSR_ENCRYPT_TYPE_WEP40:
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+		OUIIndex = CSR_OUI_WEP40_OR_1X_INDEX;
+		break;
+	case eCSR_ENCRYPT_TYPE_WEP104:
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+		OUIIndex = CSR_OUI_WEP104_INDEX;
+		break;
+	case eCSR_ENCRYPT_TYPE_TKIP:
+		OUIIndex = CSR_OUI_TKIP_OR_PSK_INDEX;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES:
+		OUIIndex = CSR_OUI_AES_INDEX;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP:
+		OUIIndex = CSR_OUI_AES_GCMP_INDEX;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
+		OUIIndex = CSR_OUI_AES_GCMP_256_INDEX;
+		break;
+	case eCSR_ENCRYPT_TYPE_NONE:
+		OUIIndex = CSR_OUI_USE_GROUP_CIPHER_INDEX;
+		break;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_ENCRYPT_TYPE_WPI:
+		OUIIndex = CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX;
+		break;
+#endif /* FEATURE_WLAN_WAPI */
+	default:                /* HOWTO handle this? */
+		OUIIndex = CSR_OUI_RESERVED_INDEX;
+		break;
+	} /* switch */
+
+	return OUIIndex;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * csr_is_fils_auth() - update negotiated auth if matches to FILS auth type
+ * @mac_ctx: pointer to mac context
+ * @authsuites: auth suites
+ * @c_auth_suites: auth suites count
+ * @authentication: authentication
+ * @auth_type: authentication type list
+ * @index: current counter
+ * @neg_authtype: pointer to negotiated auth
+ *
+ * Return: None
+ */
+static void csr_is_fils_auth(tpAniSirGlobal mac_ctx,
+	uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites,
+	uint8_t authentication[], tCsrAuthList *auth_type,
+	uint8_t index, eCsrAuthType *neg_authtype)
+{
+	/*
+	 * TODO Always try with highest security
+	 * move this down once sha384 is validated
+	 */
+	if (csr_is_auth_fils_sha256(mac_ctx, authsuites,
+				c_auth_suites, authentication)) {
+		if (eCSR_AUTH_TYPE_FILS_SHA256 ==
+				auth_type->authType[index])
+			*neg_authtype = eCSR_AUTH_TYPE_FILS_SHA256;
+	}
+	if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+			csr_is_auth_fils_sha384(mac_ctx, authsuites,
+				c_auth_suites, authentication)) {
+		if (eCSR_AUTH_TYPE_FILS_SHA384 ==
+				auth_type->authType[index])
+			*neg_authtype = eCSR_AUTH_TYPE_FILS_SHA384;
+	}
+	if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+			csr_is_auth_fils_ft_sha256(mac_ctx, authsuites,
+				c_auth_suites, authentication)) {
+		if (eCSR_AUTH_TYPE_FT_FILS_SHA256 ==
+				auth_type->authType[index])
+			*neg_authtype = eCSR_AUTH_TYPE_FT_FILS_SHA256;
+	}
+	if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+			csr_is_auth_fils_ft_sha384(mac_ctx, authsuites,
+				c_auth_suites, authentication)) {
+		if (eCSR_AUTH_TYPE_FT_FILS_SHA384 ==
+				auth_type->authType[index])
+			*neg_authtype = eCSR_AUTH_TYPE_FT_FILS_SHA384;
+	}
+	sme_debug("negotiated auth type is %d", *neg_authtype);
+}
+#else
+static void csr_is_fils_auth(tpAniSirGlobal mac_ctx,
+	uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites,
+	uint8_t authentication[], tCsrAuthList *auth_type,
+	uint8_t index, eCsrAuthType *neg_authtype)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * csr_check_sae_auth() - update negotiated auth if matches to SAE auth type
+ * @mac_ctx: pointer to mac context
+ * @authsuites: auth suites
+ * @c_auth_suites: auth suites count
+ * @authentication: authentication
+ * @auth_type: authentication type list
+ * @index: current counter
+ * @neg_authtype: pointer to negotiated auth
+ *
+ * Return: None
+ */
+static void csr_check_sae_auth(tpAniSirGlobal mac_ctx,
+	uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites,
+	uint8_t authentication[], tCsrAuthList *auth_type,
+	uint8_t index, eCsrAuthType *neg_authtype)
+{
+	if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+	   csr_is_auth_wpa_sae(mac_ctx, authsuites,
+	   c_auth_suites, authentication)) {
+		if (eCSR_AUTH_TYPE_SAE == auth_type->authType[index])
+			*neg_authtype = eCSR_AUTH_TYPE_SAE;
+	}
+	sme_debug("negotiated auth type is %d", *neg_authtype);
+}
+#else
+static void csr_check_sae_auth(tpAniSirGlobal mac_ctx,
+	uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites,
+	uint8_t authentication[], tCsrAuthList *auth_type,
+	uint8_t index, eCsrAuthType *neg_authtype)
+{
+}
+#endif
+
+/**
+ * csr_get_rsn_information() - to get RSN information
+ * @mac_ctx: pointer to global MAC context
+ * @auth_type: auth type
+ * @encr_type: encryption type
+ * @mc_encryption: multicast encryption type
+ * @rsn_ie: pointer to RSN IE
+ * @ucast_cipher: Unicast cipher
+ * @mcast_cipher: Multicast cipher
+ * @auth_suite: Authentication suite
+ * @capabilities: RSN capabilities
+ * @negotiated_authtype: Negotiated auth type
+ * @negotiated_mccipher: negotiated multicast cipher
+ * @gp_mgmt_cipher: group management cipher
+ * @mgmt_encryption_type: group management encryption type
+ *
+ * This routine will get all RSN information
+ *
+ * Return: bool
+ */
+static bool csr_get_rsn_information(tpAniSirGlobal mac_ctx,
+				    tCsrAuthList *auth_type,
+				    eCsrEncryptionType encr_type,
+				    tCsrEncryptionList *mc_encryption,
+				    tDot11fIERSN *rsn_ie, uint8_t *ucast_cipher,
+				    uint8_t *mcast_cipher, uint8_t *auth_suite,
+				    struct rsn_caps *capabilities,
+				    eCsrAuthType *negotiated_authtype,
+				    eCsrEncryptionType *negotiated_mccipher,
+				    uint8_t *gp_mgmt_cipher,
+				    tAniEdType *mgmt_encryption_type)
+{
+	bool acceptable_cipher = false;
+	bool group_mgmt_acceptable_cipher = false;
+	uint8_t c_ucast_cipher = 0;
+	uint8_t c_mcast_cipher = 0;
+	uint8_t c_group_mgmt_cipher = 0;
+	uint8_t c_auth_suites = 0, i;
+	uint8_t unicast[CSR_RSN_OUI_SIZE];
+	uint8_t multicast[CSR_RSN_OUI_SIZE];
+	uint8_t group_mgmt[CSR_RSN_OUI_SIZE];
+	uint8_t authsuites[CSR_RSN_MAX_AUTH_SUITES][CSR_RSN_OUI_SIZE];
+	uint8_t authentication[CSR_RSN_OUI_SIZE];
+	uint8_t mccipher_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE];
+	uint8_t group_mgmt_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE];
+	eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
+
+	if (!rsn_ie->present)
+		goto end;
+	c_mcast_cipher++;
+	qdf_mem_copy(mccipher_arr, rsn_ie->gp_cipher_suite,
+			CSR_RSN_OUI_SIZE);
+	c_ucast_cipher =
+		(uint8_t) (rsn_ie->pwise_cipher_suite_count);
+
+	c_auth_suites = (uint8_t) (rsn_ie->akm_suite_cnt);
+	for (i = 0; i < c_auth_suites && i < CSR_RSN_MAX_AUTH_SUITES; i++) {
+		qdf_mem_copy((void *)&authsuites[i],
+			(void *)&rsn_ie->akm_suite[i], CSR_RSN_OUI_SIZE);
+	}
+
+	/* Check - Is requested unicast Cipher supported by the BSS. */
+	acceptable_cipher = csr_match_rsnoui_index(mac_ctx,
+				rsn_ie->pwise_cipher_suites, c_ucast_cipher,
+				csr_get_oui_index_from_cipher(encr_type),
+				unicast);
+
+	if (!acceptable_cipher)
+		goto end;
+
+	/* unicast is supported. Pick the first matching Group cipher, if any */
+	for (i = 0; i < mc_encryption->numEntries; i++) {
+		acceptable_cipher = csr_match_rsnoui_index(mac_ctx,
+					mccipher_arr, c_mcast_cipher,
+					csr_get_oui_index_from_cipher(
+					    mc_encryption->encryptionType[i]),
+					multicast);
+		if (acceptable_cipher)
+			break;
+	}
+	if (!acceptable_cipher)
+		goto end;
+
+	if (negotiated_mccipher)
+		*negotiated_mccipher = mc_encryption->encryptionType[i];
+
+	/* Group Management Cipher only for 11w */
+	if (mgmt_encryption_type) {
+		c_group_mgmt_cipher++;
+		qdf_mem_copy(group_mgmt_arr, rsn_ie->gp_mgmt_cipher_suite,
+						CSR_RSN_OUI_SIZE);
+		if (csr_is_group_mgmt_gmac_128(mac_ctx, group_mgmt_arr,
+			  c_group_mgmt_cipher, group_mgmt)) {
+			group_mgmt_acceptable_cipher = true;
+			*mgmt_encryption_type = eSIR_ED_AES_GMAC_128;
+		} else if (csr_is_group_mgmt_gmac_256(mac_ctx, group_mgmt_arr,
+			  c_group_mgmt_cipher, group_mgmt)) {
+			group_mgmt_acceptable_cipher = true;
+			*mgmt_encryption_type = eSIR_ED_AES_GMAC_256;
+		} else {
+			/* Default is CMAC */
+			group_mgmt_acceptable_cipher = true;
+			*mgmt_encryption_type = eSIR_ED_AES_128_CMAC;
+			qdf_mem_copy(group_mgmt, csr_group_mgmt_oui[ENUM_CMAC],
+						CSR_RSN_OUI_SIZE);
+		}
+	}
+
+	/* Initializing with false as it has true value already */
+	acceptable_cipher = false;
+	for (i = 0; i < auth_type->numEntries; i++) {
+		/*
+		 * Ciphers are supported, Match authentication algorithm and
+		 * pick first matching authtype.
+		 */
+		/* Set FILS as first preference */
+		csr_is_fils_auth(mac_ctx, authsuites, c_auth_suites,
+			authentication, auth_type, i, &neg_authtype);
+		/* Changed the AKM suites according to order of preference */
+		csr_check_sae_auth(mac_ctx, authsuites, c_auth_suites,
+			authentication, auth_type, i, &neg_authtype);
+
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+				csr_is_auth_dpp_rsn(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_DPP_RSN == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_DPP_RSN;
+		}
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+				csr_is_ft_auth_rsn(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_FT_RSN == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_FT_RSN;
+		}
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
+				&& csr_is_ft_auth_rsn_psk(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_FT_RSN_PSK ==
+					auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_FT_RSN_PSK;
+		}
+#ifdef FEATURE_WLAN_ESE
+		/* ESE only supports 802.1X.  No PSK. */
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+				csr_is_ese_cckm_auth_rsn(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_CCKM_RSN == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_CCKM_RSN;
+		}
+#endif
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
+				&& csr_is_auth_rsn(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_RSN == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_RSN;
+		}
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
+				&& csr_is_auth_rsn_psk(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_RSN_PSK == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_RSN_PSK;
+		}
+#ifdef WLAN_FEATURE_11W
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
+			&& csr_is_auth_rsn_psk_sha256(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 ==
+					auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
+		}
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+				csr_is_auth_rsn8021x_sha256(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
+					auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
+		}
+#endif
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+				csr_is_auth_wpa_owe(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_OWE == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_OWE;
+		}
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+		   csr_is_auth_suiteb_eap_256(mac_ctx, authsuites,
+		   c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_SUITEB_EAP_SHA256 ==
+						auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256;
+		}
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+		   csr_is_auth_suiteb_eap_384(mac_ctx, authsuites,
+		   c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_SUITEB_EAP_SHA384 ==
+						auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384;
+		}
+
+		/*
+		 * The 1st auth type in the APs RSN IE, to match stations
+		 * connecting profiles auth type will cause us to exit this
+		 * loop. This is added as some APs advertise multiple akms in
+		 * the RSN IE
+		 */
+		if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) {
+			acceptable_cipher = true;
+			break;
+		}
+	} /* for */
+end:
+	if (acceptable_cipher) {
+		if (mcast_cipher)
+			qdf_mem_copy(mcast_cipher, multicast,
+					CSR_RSN_OUI_SIZE);
+
+		if (ucast_cipher)
+			qdf_mem_copy(ucast_cipher, unicast, CSR_RSN_OUI_SIZE);
+
+		if (gp_mgmt_cipher && group_mgmt_acceptable_cipher)
+			qdf_mem_copy(gp_mgmt_cipher, group_mgmt,
+				     CSR_RSN_OUI_SIZE);
+
+		if (auth_suite)
+			qdf_mem_copy(auth_suite, authentication,
+					CSR_RSN_OUI_SIZE);
+
+		if (negotiated_authtype)
+			*negotiated_authtype = neg_authtype;
+
+		if (capabilities) {
+			/* Bit 0 Preauthentication */
+			capabilities->PreAuthSupported =
+				(rsn_ie->RSN_Cap[0] >> 0) & 0x1;
+			/* Bit 1 No Pairwise */
+			capabilities->NoPairwise =
+				(rsn_ie->RSN_Cap[0] >> 1) & 0x1;
+			/* Bit 2, 3 PTKSA Replay Counter */
+			capabilities->PTKSAReplayCounter =
+				(rsn_ie->RSN_Cap[0] >> 2) & 0x3;
+			/* Bit 4, 5 GTKSA Replay Counter */
+			capabilities->GTKSAReplayCounter =
+				(rsn_ie->RSN_Cap[0] >> 4) & 0x3;
+#ifdef WLAN_FEATURE_11W
+			/* Bit 6 MFPR */
+			capabilities->MFPRequired =
+				(rsn_ie->RSN_Cap[0] >> 6) & 0x1;
+			/* Bit 7 MFPC */
+			capabilities->MFPCapable =
+				(rsn_ie->RSN_Cap[0] >> 7) & 0x1;
+#else
+			/* Bit 6 MFPR */
+			capabilities->MFPRequired = 0;
+			/* Bit 7 MFPC */
+			capabilities->MFPCapable = 0;
+#endif
+			/* remaining reserved */
+			capabilities->Reserved = rsn_ie->RSN_Cap[1] & 0xff;
+		}
+	}
+	return acceptable_cipher;
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * csr_is_pmf_capabilities_in_rsn_match() - check for PMF capability
+ * @mac:                   Global MAC Context
+ * @pFilterMFPEnabled:     given by supplicant to us to specify what kind
+ *                         of connection supplicant is expecting to make
+ *                         if it is enabled then make PMF connection.
+ *                         if it is disabled then make normal connection.
+ * @pFilterMFPRequired:    given by supplicant based on our configuration
+ *                         if it is 1 then we will require mandatory
+ *                         PMF connection and if it is 0 then we PMF
+ *                         connection is optional.
+ * @pFilterMFPCapable:     given by supplicant based on our configuration
+ *                         if it 1 then we are PMF capable and if it 0
+ *                         then we are not PMF capable.
+ * @pRSNIe:                RSNIe from Beacon/probe response of
+ *                         neighbor AP against which we will compare
+ *                         our capabilities.
+ *
+ * This function is to match our current capabilities with the AP
+ * to which we are expecting make the connection.
+ *
+ * Return:   if our PMF capabilities matches with AP then we
+ *           will return true to indicate that we are good
+ *           to make connection with it. Else we will return false
+ **/
+static bool
+csr_is_pmf_capabilities_in_rsn_match(tpAniSirGlobal mac,
+				     bool *pFilterMFPEnabled,
+				     uint8_t *pFilterMFPRequired,
+				     uint8_t *pFilterMFPCapable,
+				     tDot11fIERSN *pRSNIe)
+{
+	uint8_t apProfileMFPCapable = 0;
+	uint8_t apProfileMFPRequired = 0;
+
+	if (pRSNIe && pFilterMFPEnabled && pFilterMFPCapable
+	    && pFilterMFPRequired) {
+		/* Extracting MFPCapable bit from RSN Ie */
+		apProfileMFPCapable = csr_is_mfpc_capable(pRSNIe);
+		apProfileMFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1;
+
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"pFilterMFPEnabled: %d pFilterMFPRequired: %d pFilterMFPCapable: %d apProfileMFPCapable: %d apProfileMFPRequired: %d",
+			 *pFilterMFPEnabled, *pFilterMFPRequired,
+			 *pFilterMFPCapable, apProfileMFPCapable,
+			 apProfileMFPRequired);
+
+		if (*pFilterMFPEnabled && *pFilterMFPCapable
+		    && *pFilterMFPRequired && (apProfileMFPCapable == 0)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "AP is not capable to make PMF connection");
+			return false;
+		}  else if (!(*pFilterMFPCapable) &&
+			   apProfileMFPCapable && apProfileMFPRequired) {
+
+			/*
+			 * In this case, AP with whom we trying to connect
+			 * requires mandatory PMF connections and we are not
+			 * capable so this AP is not good choice to connect
+			 */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "AP needs PMF connection and we are not capable of pmf connection");
+			return false;
+		}
+	}
+	return true;
+}
+#endif
+
+static bool csr_is_rsn_match(tpAniSirGlobal mac_ctx, tCsrAuthList *pAuthType,
+			     eCsrEncryptionType enType,
+			     tCsrEncryptionList *pEnMcType,
+			     bool *pMFPEnabled, uint8_t *pMFPRequired,
+			     uint8_t *pMFPCapable,
+			     tDot11fBeaconIEs *pIes,
+			     eCsrAuthType *pNegotiatedAuthType,
+			     eCsrEncryptionType *pNegotiatedMCCipher)
+{
+	bool fRSNMatch = false;
+
+	/* See if the cyphers in the Bss description match with the
+	 * settings in the profile.
+	 */
+	fRSNMatch = csr_get_rsn_information(mac_ctx, pAuthType, enType,
+					pEnMcType, &pIes->RSN,
+					NULL, NULL, NULL, NULL,
+					pNegotiatedAuthType,
+					pNegotiatedMCCipher, NULL, NULL);
+#ifdef WLAN_FEATURE_11W
+	/* If all the filter matches then finally checks for PMF capabilities */
+	if (fRSNMatch)
+		fRSNMatch = csr_is_pmf_capabilities_in_rsn_match(mac_ctx,
+								pMFPEnabled,
+								 pMFPRequired,
+								 pMFPCapable,
+								 &pIes->RSN);
+#endif
+	return fRSNMatch;
+}
+
+/**
+ * csr_lookup_pmkid_using_ssid() - lookup pmkid using ssid and cache_id
+ * @mac: pointer to mac
+ * @session: sme session pointer
+ * @pmk_cache: pointer to pmk cache
+ * @index: index value needs to be seached
+ *
+ * Return: true if pmkid is found else false
+ */
+static bool csr_lookup_pmkid_using_ssid(tpAniSirGlobal mac,
+					struct csr_roam_session *session,
+					tPmkidCacheInfo *pmk_cache,
+					uint32_t *index)
+{
+	uint32_t i;
+	tPmkidCacheInfo *session_pmk;
+
+	for (i = 0; i < session->NumPmkidCache; i++) {
+		session_pmk = &session->PmkidCacheInfo[i];
+		sme_debug("match PMKID ssid %*.*s cache id %x %x ssid_len %d to ssid %s cache_id %x %x",
+			pmk_cache->ssid_len, pmk_cache->ssid_len,
+			pmk_cache->ssid, pmk_cache->cache_id[0],
+			pmk_cache->cache_id[1], pmk_cache->ssid_len,
+			session_pmk->ssid,
+			session_pmk->cache_id[0], session_pmk->cache_id[1]);
+
+		if ((!qdf_mem_cmp(pmk_cache->ssid, session_pmk->ssid,
+				  pmk_cache->ssid_len)) &&
+		    (!qdf_mem_cmp(session_pmk->cache_id,
+				  pmk_cache->cache_id, CACHE_ID_LEN))) {
+			/* match found */
+			*index = i;
+			sme_debug("PMKID found at index %d", i);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+bool csr_lookup_pmkid_using_bssid(tpAniSirGlobal mac,
+					struct csr_roam_session *session,
+					tPmkidCacheInfo *pmk_cache,
+					uint32_t *index)
+{
+	uint32_t i;
+	tPmkidCacheInfo *session_pmk;
+
+	for (i = 0; i < session->NumPmkidCache; i++) {
+		session_pmk = &session->PmkidCacheInfo[i];
+		sme_debug("Matching BSSID: " MAC_ADDRESS_STR " to cached BSSID:"
+			MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pmk_cache->BSSID.bytes),
+			MAC_ADDR_ARRAY(session_pmk->BSSID.bytes));
+		if (qdf_is_macaddr_equal(&pmk_cache->BSSID,
+					 &session_pmk->BSSID)) {
+			/* match found */
+			*index = i;
+			sme_debug("PMKID found at index %d", i);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * csr_lookup_pmkid() - lookup pmkid using bssid or ssid + cache_id
+ * @mac: pointer to mac
+ * @session: sme session pointer
+ * @pmk_cache: pointer to pmk cache
+ * @index: index value needs to be seached
+ *
+ * Return: true if pmkid is found else false
+ */
+static bool csr_lookup_pmkid(tpAniSirGlobal pMac, uint32_t sessionId,
+				tPmkidCacheInfo *pmk_cache)
+{
+	bool fRC = false, fMatchFound = false;
+	uint32_t Index;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return false;
+	}
+
+	if (pmk_cache->ssid_len) {
+		/* Try to find based on cache_id and ssid first */
+		fMatchFound = csr_lookup_pmkid_using_ssid(pMac, pSession,
+							  pmk_cache, &Index);
+	}
+
+	/* If not able to find using cache id or ssid_len is not present */
+	if (!fMatchFound)
+		fMatchFound = csr_lookup_pmkid_using_bssid(pMac,
+						pSession, pmk_cache, &Index);
+
+	if (!fMatchFound) {
+		sme_debug("no pmkid match found NumPmkidCache = %d",
+			pSession->NumPmkidCache);
+		return false;
+	}
+
+	qdf_mem_copy(pmk_cache->PMKID,
+		     pSession->PmkidCacheInfo[Index].PMKID,
+		     CSR_RSN_PMKID_SIZE);
+
+	qdf_mem_copy(pmk_cache->pmk,
+		     pSession->PmkidCacheInfo[Index].pmk,
+		     pSession->PmkidCacheInfo[Index].pmk_len);
+	pmk_cache->pmk_len = pSession->PmkidCacheInfo[Index].pmk_len;
+
+	fRC = true;
+	sme_debug("match = %d NumPmkidCache = %d",
+		fRC, pSession->NumPmkidCache);
+
+	return fRC;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+/*
+ * csr_update_pmksa_for_cache_id: update tPmkidCacheInfo to lookup using
+ * ssid and cache id
+ * @bss_desc: bss description
+ * @profile: csr roam profile
+ * @pmkid_cache: pmksa cache
+ *
+ * Return: true if cache identifier present else false
+ */
+static bool csr_update_pmksa_for_cache_id(tSirBssDescription *bss_desc,
+				struct csr_roam_profile *profile,
+				tPmkidCacheInfo *pmkid_cache)
+{
+	if (!bss_desc->fils_info_element.is_cache_id_present)
+		return false;
+
+	pmkid_cache->ssid_len =
+		profile->SSIDs.SSIDList[0].SSID.length;
+	qdf_mem_copy(pmkid_cache->ssid,
+		profile->SSIDs.SSIDList[0].SSID.ssId,
+		profile->SSIDs.SSIDList[0].SSID.length);
+	qdf_mem_copy(pmkid_cache->cache_id,
+		bss_desc->fils_info_element.cache_id,
+		CACHE_ID_LEN);
+	qdf_mem_copy(pmkid_cache->BSSID.bytes,
+		bss_desc->bssId, QDF_MAC_ADDR_SIZE);
+
+	return true;
+
+}
+
+/*
+ * csr_update_pmksa_to_profile: update pmk and pmkid to profile which will be
+ * used in case of fils session
+ * @profile: profile
+ * @pmkid_cache: pmksa cache
+ *
+ * Return: None
+ */
+static inline void csr_update_pmksa_to_profile(struct csr_roam_profile *profile,
+					       tPmkidCacheInfo *pmkid_cache)
+{
+	if (!profile->fils_con_info)
+		return;
+
+	profile->fils_con_info->pmk_len = pmkid_cache->pmk_len;
+	qdf_mem_copy(profile->fils_con_info->pmk,
+			pmkid_cache->pmk, pmkid_cache->pmk_len);
+	qdf_mem_copy(profile->fils_con_info->pmkid,
+		pmkid_cache->PMKID, CSR_RSN_PMKID_SIZE);
+
+}
+#else
+static inline bool csr_update_pmksa_for_cache_id(tSirBssDescription *bss_desc,
+				struct csr_roam_profile *profile,
+				tPmkidCacheInfo *pmkid_cache)
+{
+	return false;
+}
+
+static inline void csr_update_pmksa_to_profile(struct csr_roam_profile *profile,
+					       tPmkidCacheInfo *pmkid_cache)
+{
+}
+#endif
+
+/**
+ * csr_update_session_pmk() - Update the pmk len and pmk in the roam session
+ * @session: pointer to the CSR Roam session
+ * @pmkid_cache: pointer to the pmkid cache
+ *
+ * Return: None
+ */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static void csr_update_session_pmk(struct csr_roam_session *session,
+				   tPmkidCacheInfo *pmkid_cache)
+{
+	session->pmk_len = pmkid_cache->pmk_len;
+	qdf_mem_zero(session->psk_pmk, sizeof(session->psk_pmk));
+	qdf_mem_copy(session->psk_pmk, pmkid_cache->pmk, session->pmk_len);
+}
+#else
+static inline void csr_update_session_pmk(struct csr_roam_session *session,
+					  tPmkidCacheInfo *pmkid_cache)
+{
+}
+#endif
+
+uint8_t csr_construct_rsn_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+			     struct csr_roam_profile *pProfile,
+			     tSirBssDescription *pSirBssDesc,
+			     tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe)
+{
+	uint32_t ret;
+	bool fRSNMatch;
+	uint8_t cbRSNIe = 0;
+	uint8_t UnicastCypher[CSR_RSN_OUI_SIZE];
+	uint8_t MulticastCypher[CSR_RSN_OUI_SIZE];
+	uint8_t gp_mgmt_cipher_suite[CSR_RSN_OUI_SIZE];
+	uint8_t AuthSuite[CSR_RSN_OUI_SIZE];
+	tCsrRSNAuthIe *pAuthSuite;
+	struct rsn_caps RSNCapabilities;
+	tCsrRSNPMKIe *pPMK;
+	tPmkidCacheInfo pmkid_cache;
+#ifdef WLAN_FEATURE_11W
+	uint8_t *pGroupMgmtCipherSuite;
+#endif
+	tDot11fBeaconIEs *pIesLocal = pIes;
+	eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN;
+	tDot11fIERSN rsn_ie = {0};
+	struct csr_roam_session *session = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId) || !session)
+		return 0;
+	qdf_mem_zero(&pmkid_cache, sizeof(pmkid_cache));
+	qdf_mem_zero(&rsn_ie, sizeof(rsn_ie));
+
+	do {
+		if (!csr_is_profile_rsn(pProfile))
+			break;
+
+		if (!pIesLocal
+		    &&
+		    (!QDF_IS_STATUS_SUCCESS
+			     (csr_get_parsed_bss_description_ies
+				     (pMac, pSirBssDesc, &pIesLocal)))) {
+			break;
+		}
+
+		/*
+		 * Use intersection of the RSN cap sent by user space and
+		 * the AP, so that only common capability are enabled.
+		 */
+		if (pProfile->pRSNReqIE && pProfile->nRSNReqIELength) {
+			ret = dot11f_unpack_ie_rsn(pMac,
+						   pProfile->pRSNReqIE + 2,
+				  pProfile->nRSNReqIELength -2, &rsn_ie, false);
+			if (!DOT11F_FAILED(ret)) {
+				pIesLocal->RSN.RSN_Cap[0] =
+						pIesLocal->RSN.RSN_Cap[0] &
+						rsn_ie.RSN_Cap[0];
+				pIesLocal->RSN.RSN_Cap[1] =
+						pIesLocal->RSN.RSN_Cap[1] &
+						rsn_ie.RSN_Cap[1];
+			}
+		}
+		/* See if the cyphers in the Bss description match with the
+		 * settings in the profile.
+		 */
+		fRSNMatch = csr_get_rsn_information(pMac, &pProfile->AuthType,
+					pProfile->negotiatedUCEncryptionType,
+					&pProfile->mcEncryptionType,
+					&pIesLocal->RSN, UnicastCypher,
+					MulticastCypher, AuthSuite,
+					&RSNCapabilities, &negAuthType, NULL,
+					gp_mgmt_cipher_suite,
+					&pProfile->mgmt_encryption_type);
+		if (!fRSNMatch)
+			break;
+
+		pRSNIe->IeHeader.ElementID = SIR_MAC_RSN_EID;
+
+		pRSNIe->Version = CSR_RSN_VERSION_SUPPORTED;
+
+		qdf_mem_copy(pRSNIe->MulticastOui, MulticastCypher,
+			     sizeof(MulticastCypher));
+
+		pRSNIe->cUnicastCyphers = 1;
+
+		qdf_mem_copy(&pRSNIe->UnicastOui[0], UnicastCypher,
+			     sizeof(UnicastCypher));
+
+		pAuthSuite =
+			(tCsrRSNAuthIe *) (&pRSNIe->
+					   UnicastOui[pRSNIe->cUnicastCyphers]);
+
+		pAuthSuite->cAuthenticationSuites = 1;
+		qdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite,
+			     sizeof(AuthSuite));
+
+		/* PreAuthSupported is an AP only capability */
+		RSNCapabilities.PreAuthSupported = 0;
+		/*
+		 * Use the Management Frame Protection values given by the
+		 * supplicant, if AP and STA both are MFP capable.
+		 */
+#ifdef WLAN_FEATURE_11W
+		if (RSNCapabilities.MFPCapable && pProfile->MFPCapable) {
+			RSNCapabilities.MFPCapable = pProfile->MFPCapable;
+			RSNCapabilities.MFPRequired = pProfile->MFPRequired;
+		} else {
+			RSNCapabilities.MFPCapable = 0;
+			RSNCapabilities.MFPRequired = 0;
+		}
+#endif
+		*(uint16_t *) (&pAuthSuite->AuthOui[1]) =
+			*((uint16_t *) (&RSNCapabilities));
+
+		pPMK = (tCsrRSNPMKIe *) (((uint8_t *) (&pAuthSuite->AuthOui[1]))
+				+ sizeof(uint16_t));
+
+		if (!csr_update_pmksa_for_cache_id(pSirBssDesc,
+			pProfile, &pmkid_cache))
+			qdf_mem_copy(pmkid_cache.BSSID.bytes,
+				pSirBssDesc->bssId, QDF_MAC_ADDR_SIZE);
+		/* Don't include the PMK SA IDs for CCKM associations. */
+		if (
+#ifdef FEATURE_WLAN_ESE
+			(eCSR_AUTH_TYPE_CCKM_RSN != negAuthType) &&
+#endif
+			csr_lookup_pmkid(pMac, sessionId, &pmkid_cache)) {
+			pPMK->cPMKIDs = 1;
+
+			qdf_trace_hex_dump(QDF_MODULE_ID_PE,
+				   QDF_TRACE_LEVEL_INFO,
+				   pmkid_cache.pmk, pmkid_cache.pmk_len);
+			qdf_mem_copy(pPMK->PMKIDList[0].PMKID,
+				     pmkid_cache.PMKID,
+				     CSR_RSN_PMKID_SIZE);
+
+			/*
+			 * If a PMK cache is found for the BSSID, then
+			 * update the PMK in CSR session also as this
+			 * will be sent to the FW during RSO.
+			 */
+			csr_update_session_pmk(session, &pmkid_cache);
+
+			csr_update_pmksa_to_profile(pProfile, &pmkid_cache);
+		} else {
+			pPMK->cPMKIDs = 0;
+		}
+		session->rsn_caps = RSNCapabilities;
+
+#ifdef WLAN_FEATURE_11W
+		/* Advertise BIP in group cipher key management only if PMF is
+		 * enabled and AP is capable.
+		 */
+		if (pProfile->MFPEnabled &&
+			(RSNCapabilities.MFPCapable && pProfile->MFPCapable)) {
+			pGroupMgmtCipherSuite =
+				(uint8_t *) pPMK + sizeof(uint16_t) +
+				(pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE);
+			qdf_mem_copy(pGroupMgmtCipherSuite,
+				     gp_mgmt_cipher_suite, CSR_RSN_OUI_SIZE);
+		}
+#endif
+	host_log_rsn_info(UnicastCypher, MulticastCypher,
+			  AuthSuite, gp_mgmt_cipher_suite);
+
+		/* Add in the fixed fields plus 1 Unicast cypher, less the
+		 * IE Header length Add in the size of the Auth suite (count
+		 * plus a single OUI) Add in the RSN caps field.
+		 * Add PMKID count and PMKID (if any)
+		 * Add group management cipher suite
+		 */
+		pRSNIe->IeHeader.Length =
+			(uint8_t) (sizeof(*pRSNIe) - sizeof(pRSNIe->IeHeader) +
+				   sizeof(*pAuthSuite) +
+				   sizeof(struct rsn_caps));
+		if (pPMK->cPMKIDs)
+			pRSNIe->IeHeader.Length += (uint8_t) (sizeof(uint16_t) +
+							      (pPMK->cPMKIDs *
+							CSR_RSN_PMKID_SIZE));
+#ifdef WLAN_FEATURE_11W
+		if (pProfile->MFPEnabled &&
+			(RSNCapabilities.MFPCapable && pProfile->MFPCapable)) {
+			if (0 == pPMK->cPMKIDs)
+				pRSNIe->IeHeader.Length += sizeof(uint16_t);
+			pRSNIe->IeHeader.Length += CSR_WPA_OUI_SIZE;
+		}
+#endif
+
+		/* return the size of the IE header (total) constructed... */
+		cbRSNIe = pRSNIe->IeHeader.Length + sizeof(pRSNIe->IeHeader);
+
+	} while (0);
+
+	if (!pIes && pIesLocal)
+		/* locally allocated */
+		qdf_mem_free(pIesLocal);
+
+	return cbRSNIe;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+/**
+ * csr_get_wapi_information() - to get WAPI information
+ * @mac_ctx: pointer to global MAC context
+ * @auth_type: auth type
+ * @encr_type: encryption type
+ * @mc_encryption: multicast encryption type
+ * @wapi_ie: pointer to WAPI IE
+ * @ucast_cipher: Unicast cipher
+ * @mcast_cipher: Multicast cipher
+ * @auth_suite: Authentication suite
+ * @negotiated_authtype: Negotiated auth type
+ * @negotiated_mccipher: negotiated multicast cipher
+ *
+ * This routine will get all WAPI information
+ *
+ * Return: bool
+ */
+static bool csr_get_wapi_information(tpAniSirGlobal mac_ctx,
+				     tCsrAuthList *auth_type,
+				     eCsrEncryptionType encr_type,
+				     tCsrEncryptionList *mc_encryption,
+				     tDot11fIEWAPI *wapi_ie,
+				     uint8_t *ucast_cipher,
+				     uint8_t *mcast_cipher, uint8_t *auth_suite,
+				     eCsrAuthType *negotiated_authtype,
+				     eCsrEncryptionType *negotiated_mccipher)
+{
+	bool acceptable_cipher = false;
+	uint8_t c_ucast_cipher = 0;
+	uint8_t c_mcast_cipher = 0;
+	uint8_t c_auth_suites = 0, i;
+	uint8_t unicast[CSR_WAPI_OUI_SIZE];
+	uint8_t multicast[CSR_WAPI_OUI_SIZE];
+	uint8_t authsuites[CSR_WAPI_MAX_AUTH_SUITES][CSR_WAPI_OUI_SIZE];
+	uint8_t authentication[CSR_WAPI_OUI_SIZE];
+	uint8_t mccipher_arr[CSR_WAPI_MAX_MULTICAST_CYPHERS][CSR_WAPI_OUI_SIZE];
+	eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
+	uint8_t wapioui_idx = 0;
+
+	if (!wapi_ie->present)
+		goto end;
+
+	c_mcast_cipher++;
+	qdf_mem_copy(mccipher_arr, wapi_ie->multicast_cipher_suite,
+			CSR_WAPI_OUI_SIZE);
+	c_ucast_cipher = (uint8_t) (wapi_ie->unicast_cipher_suite_count);
+	c_auth_suites = (uint8_t) (wapi_ie->akm_suite_count);
+	for (i = 0; i < c_auth_suites && i < CSR_WAPI_MAX_AUTH_SUITES; i++)
+		qdf_mem_copy((void *)&authsuites[i],
+			(void *)&wapi_ie->akm_suites[i], CSR_WAPI_OUI_SIZE);
+
+	wapioui_idx = csr_get_oui_index_from_cipher(encr_type);
+	if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) {
+		sme_err("Wapi OUI index = %d out of limit",
+			wapioui_idx);
+		acceptable_cipher = false;
+		goto end;
+	}
+	/* Check - Is requested unicast Cipher supported by the BSS. */
+	acceptable_cipher = csr_match_wapi_oui_index(mac_ctx,
+				wapi_ie->unicast_cipher_suites,
+				c_ucast_cipher, wapioui_idx, unicast);
+	if (!acceptable_cipher)
+		goto end;
+
+	/* unicast is supported. Pick the first matching Group cipher, if any */
+	for (i = 0; i < mc_encryption->numEntries; i++) {
+		wapioui_idx = csr_get_oui_index_from_cipher(
+					mc_encryption->encryptionType[i]);
+		if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) {
+			sme_err("Wapi OUI index = %d out of limit",
+				wapioui_idx);
+			acceptable_cipher = false;
+			break;
+		}
+		acceptable_cipher = csr_match_wapi_oui_index(mac_ctx,
+						mccipher_arr, c_mcast_cipher,
+						wapioui_idx, multicast);
+		if (acceptable_cipher)
+			break;
+	}
+	if (!acceptable_cipher)
+		goto end;
+
+	if (negotiated_mccipher)
+		*negotiated_mccipher =
+			mc_encryption->encryptionType[i];
+
+	/*
+	 * Ciphers are supported, Match authentication algorithm and
+	 * pick first matching authtype
+	 */
+	if (csr_is_auth_wapi_cert
+			(mac_ctx, authsuites, c_auth_suites, authentication)) {
+		neg_authtype =
+			eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
+	} else if (csr_is_auth_wapi_psk(mac_ctx, authsuites,
+				c_auth_suites, authentication)) {
+		neg_authtype = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
+	} else {
+		acceptable_cipher = false;
+		neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
+	}
+
+	/* Caller doesn't care about auth type, or BSS doesn't match */
+	if ((0 == auth_type->numEntries) || (false == acceptable_cipher))
+		goto end;
+
+	acceptable_cipher = false;
+	for (i = 0; i < auth_type->numEntries; i++) {
+		if (auth_type->authType[i] == neg_authtype) {
+			acceptable_cipher = true;
+			break;
+		}
+	}
+
+end:
+	if (acceptable_cipher) {
+		if (mcast_cipher)
+			qdf_mem_copy(mcast_cipher, multicast,
+					CSR_WAPI_OUI_SIZE);
+		if (ucast_cipher)
+			qdf_mem_copy(ucast_cipher, unicast, CSR_WAPI_OUI_SIZE);
+		if (auth_suite)
+			qdf_mem_copy(auth_suite, authentication,
+					CSR_WAPI_OUI_SIZE);
+		if (negotiated_authtype)
+			*negotiated_authtype = neg_authtype;
+	}
+	return acceptable_cipher;
+}
+
+static bool csr_is_wapi_match(tpAniSirGlobal mac_ctx, tCsrAuthList *pAuthType,
+			      eCsrEncryptionType enType,
+			      tCsrEncryptionList *pEnMcType,
+			      tDot11fBeaconIEs *pIes,
+			      eCsrAuthType *pNegotiatedAuthType,
+			      eCsrEncryptionType *pNegotiatedMCCipher)
+{
+	bool fWapiMatch = false;
+
+	/* See if the cyphers in the Bss description match with the
+	 * settings in the profile.
+	 */
+	fWapiMatch =
+		csr_get_wapi_information(mac_ctx, pAuthType, enType, pEnMcType,
+					 &pIes->WAPI, NULL, NULL, NULL,
+					 pNegotiatedAuthType,
+					 pNegotiatedMCCipher);
+
+	return fWapiMatch;
+}
+
+static bool csr_lookup_bkid(tpAniSirGlobal pMac, uint32_t sessionId,
+			    uint8_t *pBSSId, uint8_t *pBKId)
+{
+	bool fRC = false, fMatchFound = false;
+	uint32_t Index;
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sme_err("session %d not found", sessionId);
+		return false;
+	}
+
+	do {
+		for (Index = 0; Index < pSession->NumBkidCache; Index++) {
+			sme_debug("match BKID " MAC_ADDRESS_STR " to ",
+				MAC_ADDR_ARRAY(pBSSId));
+			if (!qdf_mem_cmp
+			    (pBSSId, pSession->BkidCacheInfo[Index].BSSID.bytes,
+				    sizeof(struct qdf_mac_addr))) {
+				/* match found */
+				fMatchFound = true;
+				break;
+			}
+		}
+
+		if (!fMatchFound)
+			break;
+
+		qdf_mem_copy(pBKId, pSession->BkidCacheInfo[Index].BKID,
+			     CSR_WAPI_BKID_SIZE);
+
+		fRC = true;
+	} while (0);
+	sme_debug(
+		"return match = %d pMac->roam.NumBkidCache = %d",
+		fRC, pSession->NumBkidCache);
+
+	return fRC;
+}
+
+uint8_t csr_construct_wapi_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+			      struct csr_roam_profile *pProfile,
+			      tSirBssDescription *pSirBssDesc,
+			      tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe)
+{
+	bool fWapiMatch = false;
+	uint8_t cbWapiIe = 0;
+	uint8_t UnicastCypher[CSR_WAPI_OUI_SIZE];
+	uint8_t MulticastCypher[CSR_WAPI_OUI_SIZE];
+	uint8_t AuthSuite[CSR_WAPI_OUI_SIZE];
+	uint8_t BKId[CSR_WAPI_BKID_SIZE];
+	uint8_t *pWapi = NULL;
+	bool fBKIDFound = false;
+	tDot11fBeaconIEs *pIesLocal = pIes;
+
+	do {
+		if (!csr_is_profile_wapi(pProfile))
+			break;
+
+		if (!pIesLocal
+		    &&
+		    (!QDF_IS_STATUS_SUCCESS
+			     (csr_get_parsed_bss_description_ies
+				     (pMac, pSirBssDesc, &pIesLocal)))) {
+			break;
+		}
+		/* See if the cyphers in the Bss description match with the
+		 * settings in the profile.
+		 */
+		fWapiMatch =
+			csr_get_wapi_information(pMac, &pProfile->AuthType,
+					pProfile->negotiatedUCEncryptionType,
+					&pProfile->mcEncryptionType,
+					&pIesLocal->WAPI, UnicastCypher,
+					MulticastCypher, AuthSuite, NULL,
+						 NULL);
+		if (!fWapiMatch)
+			break;
+
+		qdf_mem_set(pWapiIe, sizeof(tCsrWapiIe), 0);
+
+		pWapiIe->IeHeader.ElementID = DOT11F_EID_WAPI;
+
+		pWapiIe->Version = CSR_WAPI_VERSION_SUPPORTED;
+
+		pWapiIe->cAuthenticationSuites = 1;
+		qdf_mem_copy(&pWapiIe->AuthOui[0], AuthSuite,
+			     sizeof(AuthSuite));
+
+		pWapi = (uint8_t *) (&pWapiIe->AuthOui[1]);
+
+		*pWapi = (uint16_t) 1;  /* cUnicastCyphers */
+		pWapi += 2;
+		qdf_mem_copy(pWapi, UnicastCypher, sizeof(UnicastCypher));
+		pWapi += sizeof(UnicastCypher);
+
+		qdf_mem_copy(pWapi, MulticastCypher, sizeof(MulticastCypher));
+		pWapi += sizeof(MulticastCypher);
+
+		/* WAPI capabilities follows the Auth Suite (two octects)
+		 * we shouldn't EVER be sending out "pre-auth supported".
+		 * It is an AP only capability & since we already did a memset
+		 * pWapiIe to 0, skip these fields
+		 */
+		pWapi += 2;
+
+		fBKIDFound =
+			csr_lookup_bkid(pMac, sessionId, pSirBssDesc->bssId,
+					&(BKId[0]));
+
+		if (fBKIDFound) {
+			/* Do we need to change the endianness here */
+			*pWapi = (uint16_t) 1;  /* cBKIDs */
+			pWapi += 2;
+			qdf_mem_copy(pWapi, BKId, CSR_WAPI_BKID_SIZE);
+		} else {
+			*pWapi = 0;
+			pWapi += 1;
+			*pWapi = 0;
+			pWapi += 1;
+		}
+
+		/* Add in the IE fields except the IE header */
+		/* Add BKID count and BKID (if any) */
+		pWapiIe->IeHeader.Length =
+			(uint8_t) (sizeof(*pWapiIe) -
+				sizeof(pWapiIe->IeHeader));
+
+		/*2 bytes for BKID Count field */
+		pWapiIe->IeHeader.Length += sizeof(uint16_t);
+
+		if (fBKIDFound)
+			pWapiIe->IeHeader.Length += CSR_WAPI_BKID_SIZE;
+
+		/* return the size of the IE header (total) constructed... */
+		cbWapiIe = pWapiIe->IeHeader.Length + sizeof(pWapiIe->IeHeader);
+
+	} while (0);
+
+	if (!pIes && pIesLocal)
+		/* locally allocated */
+		qdf_mem_free(pIesLocal);
+
+	return cbWapiIe;
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+/**
+ * csr_get_wpa_cyphers() - to get WPA cipher info
+ * @mac_ctx: pointer to mac context
+ * @auth_type: auth type
+ * @encr_type: encryption type
+ * @mc_encryption: multicast encryption type
+ * @wpa_ie: pointer to WPA IE
+ * @ucast_cipher: Unicast cipher
+ * @mcast_cipher: Multicast cipher
+ * @auth_suite: Authentication suite
+ * @negotiated_authtype: Negotiated auth type
+ * @negotiated_mccipher: negotiated multicast cipher
+ *
+ * This routine will get all WPA information
+ *
+ * Return: bool
+ */
+static bool csr_get_wpa_cyphers(tpAniSirGlobal mac_ctx, tCsrAuthList *auth_type,
+				eCsrEncryptionType encr_type,
+				tCsrEncryptionList *mc_encryption,
+				tDot11fIEWPA *wpa_ie, uint8_t *ucast_cipher,
+				uint8_t *mcast_cipher, uint8_t *auth_suite,
+				eCsrAuthType *negotiated_authtype,
+				eCsrEncryptionType *negotiated_mccipher)
+{
+	bool acceptable_cipher = false;
+	uint8_t c_ucast_cipher = 0;
+	uint8_t c_mcast_cipher = 0;
+	uint8_t c_auth_suites = 0;
+	uint8_t unicast[CSR_WPA_OUI_SIZE];
+	uint8_t multicast[CSR_WPA_OUI_SIZE];
+	uint8_t authentication[CSR_WPA_OUI_SIZE];
+	uint8_t mccipher_arr[1][CSR_WPA_OUI_SIZE];
+	uint8_t i;
+	uint8_t index;
+	eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
+
+	if (!wpa_ie->present)
+		goto end;
+	c_mcast_cipher = 1;
+	qdf_mem_copy(mccipher_arr, wpa_ie->multicast_cipher, CSR_WPA_OUI_SIZE);
+	c_ucast_cipher = (uint8_t) (wpa_ie->unicast_cipher_count);
+	c_auth_suites = (uint8_t) (wpa_ie->auth_suite_count);
+
+	/*
+	 * csr_match_wpaoui_index will provide the index of the
+	 * array csr_wpa_oui to be read and determine if it is
+	 * accepatable cipher or not. Below check ensures that
+	 * the index will not be out of range of the array size.
+	 */
+	index = csr_get_oui_index_from_cipher(encr_type);
+	if (!(index < (sizeof(csr_wpa_oui)/CSR_WPA_OUI_SIZE))) {
+		sme_debug("Unacceptable index: %d", index);
+		goto end;
+	}
+
+	sme_debug("kw_dbg: index: %d", index);
+	/* Check - Is requested unicast Cipher supported by the BSS. */
+	acceptable_cipher = csr_match_wpaoui_index(mac_ctx,
+				wpa_ie->unicast_ciphers, c_ucast_cipher,
+				index, unicast);
+	if (!acceptable_cipher)
+		goto end;
+	/* unicast is supported. Pick the first matching Group cipher, if any */
+	for (i = 0; i < mc_encryption->numEntries; i++) {
+		index = csr_get_oui_index_from_cipher(
+				mc_encryption->encryptionType[i]);
+		sme_debug("kw_dbg: index: %d", index);
+		if (!(index < (sizeof(csr_wpa_oui)/CSR_WPA_OUI_SIZE))) {
+			sme_debug("Unacceptable MC index: %d", index);
+			acceptable_cipher = false;
+			continue;
+		}
+		acceptable_cipher = csr_match_wpaoui_index(mac_ctx,
+					mccipher_arr, c_mcast_cipher,
+					index, multicast);
+		if (acceptable_cipher)
+			break;
+	}
+	if (!acceptable_cipher)
+		goto end;
+
+	if (negotiated_mccipher)
+		*negotiated_mccipher = mc_encryption->encryptionType[i];
+
+	/* Initializing with false as it has true value already */
+	acceptable_cipher = false;
+	for (i = 0; i < auth_type->numEntries; i++) {
+		/*
+		 * Ciphers are supported, Match authentication algorithm and
+		 * pick first matching authtype
+		 */
+		if (csr_is_auth_wpa(mac_ctx, wpa_ie->auth_suites, c_auth_suites,
+			authentication)) {
+			if (eCSR_AUTH_TYPE_WPA == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_WPA;
+		}
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+			csr_is_auth_wpa_psk(mac_ctx,
+				wpa_ie->auth_suites, c_auth_suites,
+				authentication)) {
+			if (eCSR_AUTH_TYPE_WPA_PSK == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_WPA_PSK;
+		}
+#ifdef FEATURE_WLAN_ESE
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
+			&& csr_is_ese_cckm_auth_wpa(mac_ctx,
+				wpa_ie->auth_suites, c_auth_suites,
+				authentication)) {
+			if (eCSR_AUTH_TYPE_CCKM_WPA == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_CCKM_WPA;
+		}
+#endif /* FEATURE_WLAN_ESE */
+
+		/*
+		 * The 1st auth type in the APs WPA IE, to match stations
+		 * connecting profiles auth type will cause us to exit this
+		 * loop. This is added as some APs advertise multiple akms in
+		 * the WPA IE
+		 */
+		if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) {
+			acceptable_cipher = true;
+			break;
+		}
+	}
+
+end:
+	if (acceptable_cipher) {
+		if (mcast_cipher)
+			qdf_mem_copy((uint8_t **) mcast_cipher, multicast,
+					CSR_WPA_OUI_SIZE);
+
+		if (ucast_cipher)
+			qdf_mem_copy((uint8_t **) ucast_cipher, unicast,
+					CSR_WPA_OUI_SIZE);
+
+		if (auth_suite)
+			qdf_mem_copy((uint8_t **) auth_suite, authentication,
+					CSR_WPA_OUI_SIZE);
+
+		if (negotiated_authtype)
+			*negotiated_authtype = neg_authtype;
+	}
+
+	return acceptable_cipher;
+}
+
+static bool csr_is_wpa_encryption_match(tpAniSirGlobal pMac,
+					tCsrAuthList *pAuthType,
+					eCsrEncryptionType enType,
+					tCsrEncryptionList *pEnMcType,
+					tDot11fBeaconIEs *pIes,
+					eCsrAuthType *pNegotiatedAuthtype,
+					eCsrEncryptionType *pNegotiatedMCCipher)
+{
+	bool fWpaMatch = false;
+
+	/* See if the cyphers in the Bss description match with the
+	 * settings in the profile.
+	 */
+	fWpaMatch =
+		csr_get_wpa_cyphers(pMac, pAuthType, enType, pEnMcType,
+				&pIes->WPA,
+				    NULL, NULL, NULL, pNegotiatedAuthtype,
+				    pNegotiatedMCCipher);
+
+	return fWpaMatch;
+}
+
+uint8_t csr_construct_wpa_ie(tpAniSirGlobal pMac,
+			     struct csr_roam_profile *pProfile,
+			     tSirBssDescription *pSirBssDesc,
+			     tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe)
+{
+	bool fWpaMatch;
+	uint8_t cbWpaIe = 0;
+	uint8_t UnicastCypher[CSR_WPA_OUI_SIZE];
+	uint8_t MulticastCypher[CSR_WPA_OUI_SIZE];
+	uint8_t AuthSuite[CSR_WPA_OUI_SIZE];
+	tCsrWpaAuthIe *pAuthSuite;
+	tDot11fBeaconIEs *pIesLocal = pIes;
+
+	do {
+		if (!csr_is_profile_wpa(pProfile))
+			break;
+
+		if (!pIesLocal
+		    &&
+		    (!QDF_IS_STATUS_SUCCESS
+			     (csr_get_parsed_bss_description_ies
+				     (pMac, pSirBssDesc, &pIesLocal))))
+			break;
+		/* See if the cyphers in the Bss description match with the
+		 * settings in the profile.
+		 */
+		fWpaMatch =
+			csr_get_wpa_cyphers(pMac, &pProfile->AuthType,
+					   pProfile->negotiatedUCEncryptionType,
+					    &pProfile->mcEncryptionType,
+					    &pIesLocal->WPA, UnicastCypher,
+					MulticastCypher, AuthSuite, NULL, NULL);
+		if (!fWpaMatch)
+			break;
+
+		pWpaIe->IeHeader.ElementID = SIR_MAC_WPA_EID;
+
+		qdf_mem_copy(pWpaIe->Oui, csr_wpa_oui[01], sizeof(pWpaIe->Oui));
+
+		pWpaIe->Version = CSR_WPA_VERSION_SUPPORTED;
+
+		qdf_mem_copy(pWpaIe->MulticastOui, MulticastCypher,
+			     sizeof(MulticastCypher));
+
+		pWpaIe->cUnicastCyphers = 1;
+
+		qdf_mem_copy(&pWpaIe->UnicastOui[0], UnicastCypher,
+			     sizeof(UnicastCypher));
+
+		pAuthSuite =
+			(tCsrWpaAuthIe *) (&pWpaIe->
+					   UnicastOui[pWpaIe->cUnicastCyphers]);
+
+		pAuthSuite->cAuthenticationSuites = 1;
+		qdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite,
+			     sizeof(AuthSuite));
+
+		/* The WPA capabilities follows the Auth Suite (two octects)-
+		 * this field is optional, and we always "send" zero, so just
+		 * remove it.  This is consistent with our assumptions in the
+		 * frames compiler; c.f. bug 15234:
+		 * http://gold.woodsidenet.com/bugzilla/show_bug.cgi?id=15234
+		 * Add in the fixed fields plus 1 Unicast cypher, less the IE
+		 * Header length Add in the size of the Auth suite (count plus
+		 * a single OUI)
+		 */
+		pWpaIe->IeHeader.Length =
+			sizeof(*pWpaIe) - sizeof(pWpaIe->IeHeader) +
+			sizeof(*pAuthSuite);
+
+		/* return the size of the IE header (total) constructed... */
+		cbWpaIe = pWpaIe->IeHeader.Length + sizeof(pWpaIe->IeHeader);
+
+	} while (0);
+
+	if (!pIes && pIesLocal)
+		/* locally allocated */
+		qdf_mem_free(pIesLocal);
+
+	return cbWpaIe;
+}
+
+/* If a WPAIE exists in the profile, just use it. Or else construct
+ * one from the BSS Caller allocated memory for pWpaIe and guarrantee
+ * it can contain a max length WPA IE
+ */
+uint8_t csr_retrieve_wpa_ie(tpAniSirGlobal pMac,
+			    struct csr_roam_profile *pProfile,
+			    tSirBssDescription *pSirBssDesc,
+			    tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe)
+{
+	uint8_t cbWpaIe = 0;
+
+	do {
+		if (!csr_is_profile_wpa(pProfile))
+			break;
+		if (pProfile->nWPAReqIELength && pProfile->pWPAReqIE) {
+			if (pProfile->nWPAReqIELength <=
+					DOT11F_IE_RSN_MAX_LEN) {
+				cbWpaIe = (uint8_t) pProfile->nWPAReqIELength;
+				qdf_mem_copy(pWpaIe, pProfile->pWPAReqIE,
+					     cbWpaIe);
+			} else
+				sme_warn("Invalid WPA IE length: %d",
+					pProfile->nWPAReqIELength);
+		} else
+			cbWpaIe = csr_construct_wpa_ie(pMac, pProfile,
+						pSirBssDesc, pIes, pWpaIe);
+	} while (0);
+
+	return cbWpaIe;
+}
+
+/* If a RSNIE exists in the profile, just use it. Or else construct
+ * one from the BSS Caller allocated memory for pWpaIe and guarrantee
+ * it can contain a max length WPA IE
+ */
+uint8_t csr_retrieve_rsn_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+			    struct csr_roam_profile *pProfile,
+			    tSirBssDescription *pSirBssDesc,
+			    tDot11fBeaconIEs *pIes, tCsrRSNIe *pRsnIe)
+{
+	uint8_t cbRsnIe = 0;
+
+	do {
+		if (!csr_is_profile_rsn(pProfile))
+			break;
+		/* copy RSNIE from user as it is if test mode is enabled */
+		if (pProfile->force_rsne_override &&
+		    pProfile->nRSNReqIELength && pProfile->pRSNReqIE) {
+			sme_debug("force_rsne_override, copy RSN IE provided by user");
+			if (pProfile->nRSNReqIELength <=
+					DOT11F_IE_RSN_MAX_LEN) {
+				cbRsnIe = (uint8_t) pProfile->nRSNReqIELength;
+				qdf_mem_copy(pRsnIe, pProfile->pRSNReqIE,
+					     cbRsnIe);
+			} else {
+				sme_warn("Invalid RSN IE length: %d",
+					pProfile->nRSNReqIELength);
+			}
+			break;
+		}
+
+		cbRsnIe = csr_construct_rsn_ie(pMac, sessionId, pProfile,
+					       pSirBssDesc, pIes, pRsnIe);
+	} while (0);
+
+	return cbRsnIe;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+/* If a WAPI IE exists in the profile, just use it. Or else construct
+ * one from the BSS Caller allocated memory for pWapiIe and guarrantee
+ * it can contain a max length WAPI IE
+ */
+uint8_t csr_retrieve_wapi_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+			     struct csr_roam_profile *pProfile,
+			     tSirBssDescription *pSirBssDesc,
+			     tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe)
+{
+	uint8_t cbWapiIe = 0;
+
+	do {
+		if (!csr_is_profile_wapi(pProfile))
+			break;
+		if (pProfile->nWAPIReqIELength && pProfile->pWAPIReqIE) {
+			if (DOT11F_IE_WAPI_MAX_LEN >=
+			    pProfile->nWAPIReqIELength) {
+				cbWapiIe = (uint8_t) pProfile->nWAPIReqIELength;
+				qdf_mem_copy(pWapiIe, pProfile->pWAPIReqIE,
+					     cbWapiIe);
+			} else
+				sme_warn("Invalid WAPI IE length: %d",
+					pProfile->nWAPIReqIELength);
+		} else
+			cbWapiIe =
+				csr_construct_wapi_ie(pMac, sessionId, pProfile,
+						    pSirBssDesc, pIes, pWapiIe);
+	} while (0);
+
+	return cbWapiIe;
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+bool csr_rates_is_dot11_rate11b_supported_rate(uint8_t dot11Rate)
+{
+	bool fSupported = false;
+	uint16_t nonBasicRate =
+		(uint16_t) (BITS_OFF(dot11Rate, CSR_DOT11_BASIC_RATE_MASK));
+
+	switch (nonBasicRate) {
+	case eCsrSuppRate_1Mbps:
+	case eCsrSuppRate_2Mbps:
+	case eCsrSuppRate_5_5Mbps:
+	case eCsrSuppRate_11Mbps:
+		fSupported = true;
+		break;
+
+	default:
+		break;
+	}
+
+	return fSupported;
+}
+
+bool csr_rates_is_dot11_rate11a_supported_rate(uint8_t dot11Rate)
+{
+	bool fSupported = false;
+	uint16_t nonBasicRate =
+		(uint16_t) (BITS_OFF(dot11Rate, CSR_DOT11_BASIC_RATE_MASK));
+
+	switch (nonBasicRate) {
+	case eCsrSuppRate_6Mbps:
+	case eCsrSuppRate_9Mbps:
+	case eCsrSuppRate_12Mbps:
+	case eCsrSuppRate_18Mbps:
+	case eCsrSuppRate_24Mbps:
+	case eCsrSuppRate_36Mbps:
+	case eCsrSuppRate_48Mbps:
+	case eCsrSuppRate_54Mbps:
+		fSupported = true;
+		break;
+
+	default:
+		break;
+	}
+
+	return fSupported;
+}
+
+tAniEdType csr_translate_encrypt_type_to_ed_type(eCsrEncryptionType EncryptType)
+{
+	tAniEdType edType;
+
+	switch (EncryptType) {
+	default:
+	case eCSR_ENCRYPT_TYPE_NONE:
+		edType = eSIR_ED_NONE;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP40:
+		edType = eSIR_ED_WEP40;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP104:
+		edType = eSIR_ED_WEP104;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_TKIP:
+		edType = eSIR_ED_TKIP;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_AES:
+		edType = eSIR_ED_CCMP;
+		break;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_ENCRYPT_TYPE_WPI:
+		edType = eSIR_ED_WPI;
+		break;
+#endif
+#ifdef WLAN_FEATURE_11W
+	/* 11w BIP */
+	case eCSR_ENCRYPT_TYPE_AES_CMAC:
+		edType = eSIR_ED_AES_128_CMAC;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP:
+		edType = eSIR_ED_GCMP;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
+		edType = eSIR_ED_GCMP_256;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GMAC_128:
+		edType = eSIR_ED_AES_GMAC_128;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES_GMAC_256:
+		edType = eSIR_ED_AES_GMAC_256;
+		break;
+#endif
+	}
+
+	return edType;
+}
+
+/**
+ * csr_validate_wep() - to validate wep
+ * @uc_encry_type: unicast encryption type
+ * @auth_list: Auth list
+ * @mc_encryption_list: multicast encryption type
+ * @negotiated_authtype: negotiated auth type
+ * @negotiated_mc_encry: negotiated mc encry type
+ * @bss_descr: BSS description
+ * @ie_ptr: IE pointer
+ *
+ * This function just checks whether HDD is giving correct values for
+ * Multicast cipher and Auth
+ *
+ * Return: bool
+ */
+static bool csr_validate_wep(tpAniSirGlobal mac_ctx,
+			     eCsrEncryptionType uc_encry_type,
+			     tCsrAuthList *auth_list,
+			     tCsrEncryptionList *mc_encryption_list,
+			     eCsrAuthType *negotiated_authtype,
+			     eCsrEncryptionType *negotiated_mc_encry,
+			     tSirBssDescription *bss_descr,
+			     tDot11fBeaconIEs *ie_ptr)
+{
+	uint32_t idx;
+	bool match = false;
+	eCsrAuthType negotiated_auth = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+	eCsrEncryptionType negotiated_mccipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
+	uint8_t oui_index;
+
+	/* If privacy bit is not set, consider no match */
+	if (!csr_is_privacy(bss_descr))
+		goto end;
+
+	for (idx = 0; idx < mc_encryption_list->numEntries; idx++) {
+		switch (mc_encryption_list->encryptionType[idx]) {
+		case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+		case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+		case eCSR_ENCRYPT_TYPE_WEP40:
+		case eCSR_ENCRYPT_TYPE_WEP104:
+			/*
+			 * Multicast list may contain WEP40/WEP104.
+			 * Check whether it matches UC.
+			 */
+			if (uc_encry_type ==
+				mc_encryption_list->encryptionType[idx]) {
+				match = true;
+				negotiated_mccipher =
+					mc_encryption_list->encryptionType[idx];
+			}
+			break;
+		default:
+			match = false;
+			break;
+		}
+		if (match)
+			break;
+	}
+
+	if (!match)
+		goto end;
+
+	for (idx = 0; idx < auth_list->numEntries; idx++) {
+		switch (auth_list->authType[idx]) {
+		case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		case eCSR_AUTH_TYPE_SHARED_KEY:
+		case eCSR_AUTH_TYPE_AUTOSWITCH:
+			match = true;
+			negotiated_auth = auth_list->authType[idx];
+			break;
+		default:
+			match = false;
+		}
+		if (match)
+			break;
+	}
+
+	if (!match)
+		goto end;
+
+	if (!ie_ptr)
+		goto end;
+
+	/*
+	 * In case of WPA / WPA2, check whether it supports WEP as well.
+	 * Prepare the encryption type for WPA/WPA2 functions
+	 */
+	if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == uc_encry_type)
+		uc_encry_type = eCSR_ENCRYPT_TYPE_WEP40;
+	else if (eCSR_ENCRYPT_TYPE_WEP104 == uc_encry_type)
+		uc_encry_type = eCSR_ENCRYPT_TYPE_WEP104;
+
+	/* else we can use the encryption type directly */
+	if (ie_ptr->WPA.present) {
+		oui_index = csr_get_oui_index_from_cipher(uc_encry_type);
+		if (oui_index < QDF_ARRAY_SIZE(csr_wpa_oui))
+			match = (!qdf_mem_cmp(ie_ptr->WPA.multicast_cipher,
+					csr_wpa_oui[oui_index],
+					CSR_WPA_OUI_SIZE));
+		if (match)
+			goto end;
+	}
+	if (ie_ptr->RSN.present) {
+		match = (!qdf_mem_cmp(ie_ptr->RSN.gp_cipher_suite,
+				csr_rsn_oui[csr_get_oui_index_from_cipher(
+					uc_encry_type)],
+				CSR_RSN_OUI_SIZE));
+	}
+
+
+end:
+	if (match) {
+		if (negotiated_authtype)
+			*negotiated_authtype = negotiated_auth;
+		if (negotiated_mc_encry)
+			*negotiated_mc_encry = negotiated_mccipher;
+	}
+	return match;
+}
+
+/**
+ * csr_validate_open_none() - Check if the security is matching
+ * @bss_desc:          BSS Descriptor on which the check is done
+ * @mc_enc_type:       Multicast encryption type
+ * @mc_cipher:         Multicast Cipher
+ * @auth_type:         Authentication type
+ * @neg_auth_type:     Negotiated Auth type with the AP
+ *
+ * Return: Boolean value to tell if matched or not.
+ */
+static bool csr_validate_open_none(tSirBssDescription *bss_desc,
+	tCsrEncryptionList *mc_enc_type, eCsrEncryptionType *mc_cipher,
+	tCsrAuthList *auth_type, eCsrAuthType *neg_auth_type)
+{
+	bool match;
+	uint8_t idx;
+
+	/*
+	 * for NO encryption, if the Bss description has the
+	 * Privacy bit turned on, then encryption is required
+	 * so we have to reject this Bss.
+	 */
+	if (csr_is_privacy(bss_desc))
+		match = false;
+	else
+		match = true;
+	if (match) {
+		match = false;
+		/* Check MC cipher and Auth type requested. */
+		for (idx = 0; idx < mc_enc_type->numEntries; idx++) {
+			if (eCSR_ENCRYPT_TYPE_NONE ==
+				mc_enc_type->encryptionType[idx]) {
+				match = true;
+				*mc_cipher = mc_enc_type->encryptionType[idx];
+				break;
+			}
+		}
+		if (!match)
+			return match;
+
+		match = false;
+		/* Check Auth list. It should contain AuthOpen. */
+		for (idx = 0; idx < auth_type->numEntries; idx++) {
+			if ((eCSR_AUTH_TYPE_OPEN_SYSTEM ==
+				auth_type->authType[idx]) ||
+				(eCSR_AUTH_TYPE_AUTOSWITCH ==
+				auth_type->authType[idx])) {
+				match = true;
+				*neg_auth_type =
+					eCSR_AUTH_TYPE_OPEN_SYSTEM;
+				break;
+			}
+		}
+		if (!match)
+			return match;
+
+	}
+	return match;
+}
+
+/**
+ * csr_validate_any_default() - Check if the security is matching
+ * @mac_ctx:           Global MAC context
+ * @auth_type:         Authentication type
+ * @mc_enc_type:       Multicast encryption type
+ * @mfp_enabled:       Management frame protection feature
+ * @mfp_required:      Management frame protection mandatory
+ * @mfp_capable:       Device capable of MFP
+ * @ies_ptr:           Pointer to the IE fields
+ * @neg_auth_type:     Negotiated Auth type with the AP
+ * @bss_desc:          BSS Descriptor
+ * @neg_uc_cipher:     Negotiated unicast cipher suite
+ * @neg_mc_cipher:     Negotiated multicast cipher
+ *
+ * Return: Boolean value to tell if matched or not.
+ */
+static bool csr_validate_any_default(tpAniSirGlobal mac_ctx,
+				     tCsrAuthList *auth_type,
+				     tCsrEncryptionList *mc_enc_type,
+				     bool *mfp_enabled,
+				     uint8_t *mfp_required,
+				     uint8_t *mfp_capable,
+				     tDot11fBeaconIEs *ies_ptr,
+				     eCsrAuthType *neg_auth_type,
+				     tSirBssDescription *bss_desc,
+				     eCsrEncryptionType *uc_cipher,
+				     eCsrEncryptionType *mc_cipher)
+{
+	bool match_any = false;
+	bool match = true;
+	/* It is allowed to match anything. Try the more secured ones first. */
+	if (ies_ptr) {
+		/* Check GCMP-256 first */
+		*uc_cipher = eCSR_ENCRYPT_TYPE_AES_GCMP_256;
+		match_any = csr_is_rsn_match(mac_ctx, auth_type,
+				*uc_cipher, mc_enc_type, mfp_enabled,
+				mfp_required, mfp_capable, ies_ptr,
+				neg_auth_type, mc_cipher);
+		/* Check GCMP second */
+		*uc_cipher = eCSR_ENCRYPT_TYPE_AES_GCMP;
+		match_any = csr_is_rsn_match(mac_ctx, auth_type,
+				*uc_cipher, mc_enc_type, mfp_enabled,
+				mfp_required, mfp_capable, ies_ptr,
+				neg_auth_type, mc_cipher);
+		/* Check AES third */
+		*uc_cipher = eCSR_ENCRYPT_TYPE_AES;
+		match_any = csr_is_rsn_match(mac_ctx, auth_type,
+				*uc_cipher, mc_enc_type, mfp_enabled,
+				mfp_required, mfp_capable, ies_ptr,
+				neg_auth_type, mc_cipher);
+		if (!match_any) {
+			/* Check TKIP */
+			*uc_cipher = eCSR_ENCRYPT_TYPE_TKIP;
+			match_any = csr_is_rsn_match(mac_ctx, auth_type,
+					*uc_cipher,
+					mc_enc_type, mfp_enabled, mfp_required,
+					mfp_capable, ies_ptr, neg_auth_type,
+					mc_cipher);
+		}
+#ifdef FEATURE_WLAN_WAPI
+		if (!match_any) {
+			/* Check WAPI */
+			*uc_cipher = eCSR_ENCRYPT_TYPE_WPI;
+			match_any = csr_is_wapi_match(mac_ctx, auth_type,
+					*uc_cipher, mc_enc_type, ies_ptr,
+					neg_auth_type, mc_cipher);
+		}
+#endif
+	}
+	if (match_any)
+		return match;
+	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP104;
+	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
+			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
+		return match;
+	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP40;
+	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
+			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
+		return match;
+	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
+	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
+			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
+		return match;
+	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
+	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
+			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
+		return match;
+	/* It must be open and no enc */
+	if (csr_is_privacy(bss_desc)) {
+		match = false;
+		return match;
+	}
+
+	*neg_auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+	*mc_cipher = eCSR_ENCRYPT_TYPE_NONE;
+	*uc_cipher = eCSR_ENCRYPT_TYPE_NONE;
+	return match;
+
+}
+
+/**
+ * csr_is_security_match() - Check if the security is matching
+ * @mac_ctx:           Global MAC context
+ * @auth_type:         Authentication type
+ * @uc_enc_type:       Unicast Encryption type
+ * @mc_enc_type:       Multicast encryption type
+ * @mfp_enabled:       Management frame protection feature
+ * @mfp_required:      Management frame protection mandatory
+ * @mfp_capable:       Device capable of MFP
+ * @bss_desc:          BSS Descriptor
+ * @ies_ptr:           Pointer to the IE fields
+ * @neg_auth_type:     Negotiated Auth type with the AP
+ * @neg_uc_cipher:     Negotiated unicast cipher suite
+ * @neg_mc_cipher:     Negotiated multicast cipher
+ *
+ * Return: Boolean value to tell if matched or not.
+ */
+bool csr_is_security_match(tpAniSirGlobal mac_ctx, tCsrAuthList *auth_type,
+	tCsrEncryptionList *uc_enc_type,
+	tCsrEncryptionList *mc_enc_type, bool *mfp_enabled,
+	uint8_t *mfp_required, uint8_t *mfp_capable,
+	tSirBssDescription *bss_desc, tDot11fBeaconIEs *ies_ptr,
+	eCsrAuthType *neg_auth_type,
+	eCsrEncryptionType *neg_uc_cipher,
+	eCsrEncryptionType *neg_mc_cipher)
+{
+	bool match = false;
+	uint8_t i;
+	eCsrEncryptionType mc_cipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
+	eCsrEncryptionType uc_cipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
+	eCsrAuthType local_neg_auth_type = eCSR_AUTH_TYPE_UNKNOWN;
+
+	for (i = 0; ((i < uc_enc_type->numEntries) && (!match)); i++) {
+		uc_cipher = uc_enc_type->encryptionType[i];
+		/*
+		 * If the Bss description shows the Privacy bit is on, then we
+		 * must have some sort of encryption configured for the profile
+		 * to work.  Don't attempt to join networks with Privacy bit
+		 * set when profiles say NONE for encryption type.
+		 */
+		switch (uc_cipher) {
+		case eCSR_ENCRYPT_TYPE_NONE:
+			match = csr_validate_open_none(bss_desc, mc_enc_type,
+					&mc_cipher, auth_type,
+					&local_neg_auth_type);
+			break;
+
+		case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+		case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+			/*
+			 * !! might want to check for WEP keys set in the
+			 * Profile.... ? !! don't need to have the privacy bit
+			 * in the Bss description.  Many AP policies make
+			 * legacy encryption 'optional' so we don't know if we
+			 * can associate or not.  The AP will reject if
+			 * encryption is not allowed without the Privacy bit
+			 * turned on.
+			 */
+			match = csr_validate_wep(mac_ctx, uc_cipher, auth_type,
+					mc_enc_type, &local_neg_auth_type,
+					&mc_cipher, bss_desc, ies_ptr);
+
+			break;
+		/* these are all of the WPA encryption types... */
+		case eCSR_ENCRYPT_TYPE_WEP40:
+		case eCSR_ENCRYPT_TYPE_WEP104:
+			match = csr_validate_wep(mac_ctx, uc_cipher, auth_type,
+					mc_enc_type, &local_neg_auth_type,
+					&mc_cipher, bss_desc, ies_ptr);
+			break;
+
+		case eCSR_ENCRYPT_TYPE_TKIP:
+		case eCSR_ENCRYPT_TYPE_AES:
+		case eCSR_ENCRYPT_TYPE_AES_GCMP:
+		case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
+			if (!ies_ptr) {
+				match = false;
+				break;
+			}
+			/* First check if there is a RSN match */
+			match = csr_is_rsn_match(mac_ctx, auth_type,
+					uc_cipher, mc_enc_type,
+					mfp_enabled, mfp_required,
+					mfp_capable, ies_ptr,
+					&local_neg_auth_type,
+					&mc_cipher);
+			/* If not RSN, then check WPA match */
+			if (!match)
+				match = csr_is_wpa_encryption_match(
+						mac_ctx, auth_type,
+						uc_cipher, mc_enc_type,
+						ies_ptr,
+						&local_neg_auth_type,
+						&mc_cipher);
+			break;
+#ifdef FEATURE_WLAN_WAPI
+		case eCSR_ENCRYPT_TYPE_WPI:     /* WAPI */
+			if (ies_ptr)
+				match = csr_is_wapi_match(mac_ctx, auth_type,
+						uc_cipher, mc_enc_type, ies_ptr,
+						&local_neg_auth_type,
+						&mc_cipher);
+			else
+				match = false;
+			break;
+#endif /* FEATURE_WLAN_WAPI */
+		case eCSR_ENCRYPT_TYPE_ANY:
+		default:
+			match  = csr_validate_any_default(mac_ctx, auth_type,
+					mc_enc_type, mfp_enabled, mfp_required,
+					mfp_capable, ies_ptr,
+					&local_neg_auth_type, bss_desc,
+					&uc_cipher, &mc_cipher);
+			break;
+		}
+
+	}
+
+	if (match) {
+		if (neg_uc_cipher)
+			*neg_uc_cipher = uc_cipher;
+		if (neg_mc_cipher)
+			*neg_mc_cipher = mc_cipher;
+		if (neg_auth_type)
+			*neg_auth_type = local_neg_auth_type;
+	}
+	return match;
+}
+
+bool csr_is_ssid_match(tpAniSirGlobal pMac, uint8_t *ssid1, uint8_t ssid1Len,
+		       uint8_t *bssSsid, uint8_t bssSsidLen, bool fSsidRequired)
+{
+	bool fMatch = false;
+
+	do {
+		/*
+		 * Check for the specification of the Broadcast SSID at the
+		 * beginning of the list. If specified, then all SSIDs are
+		 * matches (broadcast SSID means accept all SSIDs).
+		 */
+		if (ssid1Len == 0) {
+			fMatch = true;
+			break;
+		}
+
+		/* There are a few special cases.  If the Bss description has
+		 * a Broadcast SSID, then our Profile must have a single SSID
+		 * without Wildcards so we can program the SSID.
+		 *
+		 * SSID could be suppressed in beacons. In that case SSID IE
+		 * has valid length but the SSID value is all NULL characters.
+		 * That condition is trated same as NULL SSID
+		 */
+		if (csr_is_nullssid(bssSsid, bssSsidLen)) {
+			if (false == fSsidRequired) {
+				fMatch = true;
+				break;
+			}
+		}
+
+		if (ssid1Len != bssSsidLen)
+			break;
+		if (!qdf_mem_cmp(bssSsid, ssid1, bssSsidLen)) {
+			fMatch = true;
+			break;
+		}
+
+	} while (0);
+
+	return fMatch;
+}
+
+/* Null ssid means match */
+bool csr_is_ssid_in_list(tSirMacSSid *pSsid, tCsrSSIDs *pSsidList)
+{
+	bool fMatch = false;
+	uint32_t i;
+
+	if (pSsidList && pSsid) {
+		for (i = 0; i < pSsidList->numOfSSIDs; i++) {
+			if (csr_is_nullssid
+				    (pSsidList->SSIDList[i].SSID.ssId,
+				    pSsidList->SSIDList[i].SSID.length)
+			    ||
+			    ((pSsidList->SSIDList[i].SSID.length ==
+			      pSsid->length)
+			     && (!qdf_mem_cmp(pSsid->ssId,
+						pSsidList->SSIDList[i].SSID.
+						ssId, pSsid->length)))) {
+				fMatch = true;
+				break;
+			}
+		}
+	}
+
+	return fMatch;
+}
+
+bool csr_is_bssid_match(struct qdf_mac_addr *pProfBssid,
+			struct qdf_mac_addr *BssBssid)
+{
+	bool fMatch = false;
+	struct qdf_mac_addr ProfileBssid;
+
+	/* for efficiency of the MAC_ADDRESS functions, move the */
+	/* Bssid's into MAC_ADDRESS structs. */
+	qdf_mem_copy(&ProfileBssid, pProfBssid, sizeof(struct qdf_mac_addr));
+
+	do {
+		/* Give the profile the benefit of the doubt... accept
+		 * either all 0 or the real broadcast Bssid (all 0xff)
+		 * as broadcast Bssids (meaning to match any Bssids).
+		 */
+		if (qdf_is_macaddr_zero(&ProfileBssid) ||
+		    qdf_is_macaddr_broadcast(&ProfileBssid)) {
+			fMatch = true;
+			break;
+		}
+
+		if (qdf_is_macaddr_equal(BssBssid, &ProfileBssid)) {
+			fMatch = true;
+			break;
+		}
+
+	} while (0);
+
+	return fMatch;
+}
+
+bool csr_is_bss_type_match(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2)
+{
+	if ((eCSR_BSS_TYPE_ANY != bssType1 && eCSR_BSS_TYPE_ANY != bssType2)
+	    && (bssType1 != bssType2))
+		return false;
+	else
+		return true;
+}
+
+bool csr_is_bss_type_ibss(eCsrRoamBssType bssType)
+{
+	return (bool)
+		(eCSR_BSS_TYPE_START_IBSS == bssType
+		 || eCSR_BSS_TYPE_IBSS == bssType);
+}
+
+/**
+ * csr_is_aggregate_rate_supported() - to check if aggregate rate is supported
+ * @mac_ctx: pointer to mac context
+ * @rate: A rate in units of 500kbps
+ *
+ *
+ * The rate encoding  is just as in 802.11  Information Elements, except
+ * that the high bit is \em  not interpreted as indicating a Basic Rate,
+ * and proprietary rates are allowed, too.
+ *
+ * Note  that if the  adapter's dot11Mode  is g,  we don't  restrict the
+ * rates.  According to hwReadEepromParameters, this will happen when:
+ * ... the  card is  configured for ALL  bands through  the property
+ * page.  If this occurs, and the card is not an ABG card ,then this
+ * code  is  setting the  dot11Mode  to  assume  the mode  that  the
+ * hardware can support.   For example, if the card  is an 11BG card
+ * and we  are configured to support  ALL bands, then  we change the
+ * dot11Mode  to 11g  because  ALL in  this  case is  only what  the
+ * hardware can support.
+ *
+ * Return: true if  the adapter is currently capable of supporting this rate
+ */
+
+static bool csr_is_aggregate_rate_supported(tpAniSirGlobal mac_ctx,
+			uint16_t rate)
+{
+	bool supported = false;
+	uint16_t idx, new_rate;
+
+	/* In case basic rate flag is set */
+	new_rate = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
+	if (eCSR_CFG_DOT11_MODE_11A ==
+			mac_ctx->roam.configParam.uCfgDot11Mode) {
+		switch (new_rate) {
+		case eCsrSuppRate_6Mbps:
+		case eCsrSuppRate_9Mbps:
+		case eCsrSuppRate_12Mbps:
+		case eCsrSuppRate_18Mbps:
+		case eCsrSuppRate_24Mbps:
+		case eCsrSuppRate_36Mbps:
+		case eCsrSuppRate_48Mbps:
+		case eCsrSuppRate_54Mbps:
+			supported = true;
+			break;
+		default:
+			supported = false;
+			break;
+		}
+
+	} else if (eCSR_CFG_DOT11_MODE_11B ==
+		   mac_ctx->roam.configParam.uCfgDot11Mode) {
+		switch (new_rate) {
+		case eCsrSuppRate_1Mbps:
+		case eCsrSuppRate_2Mbps:
+		case eCsrSuppRate_5_5Mbps:
+		case eCsrSuppRate_11Mbps:
+			supported = true;
+			break;
+		default:
+			supported = false;
+			break;
+		}
+	} else if (!mac_ctx->roam.configParam.ProprietaryRatesEnabled) {
+
+		switch (new_rate) {
+		case eCsrSuppRate_1Mbps:
+		case eCsrSuppRate_2Mbps:
+		case eCsrSuppRate_5_5Mbps:
+		case eCsrSuppRate_6Mbps:
+		case eCsrSuppRate_9Mbps:
+		case eCsrSuppRate_11Mbps:
+		case eCsrSuppRate_12Mbps:
+		case eCsrSuppRate_18Mbps:
+		case eCsrSuppRate_24Mbps:
+		case eCsrSuppRate_36Mbps:
+		case eCsrSuppRate_48Mbps:
+		case eCsrSuppRate_54Mbps:
+			supported = true;
+			break;
+		default:
+			supported = false;
+			break;
+		}
+	} else if (eCsrSuppRate_1Mbps == new_rate ||
+			eCsrSuppRate_2Mbps == new_rate ||
+			eCsrSuppRate_5_5Mbps == new_rate ||
+			eCsrSuppRate_11Mbps == new_rate)
+		supported = true;
+	else {
+		idx = 0x1;
+
+		switch (new_rate) {
+		case eCsrSuppRate_6Mbps:
+			supported = g_phy_rates_suppt[0][idx];
+			break;
+		case eCsrSuppRate_9Mbps:
+			supported = g_phy_rates_suppt[1][idx];
+			break;
+		case eCsrSuppRate_12Mbps:
+			supported = g_phy_rates_suppt[2][idx];
+			break;
+		case eCsrSuppRate_18Mbps:
+			supported = g_phy_rates_suppt[3][idx];
+			break;
+		case eCsrSuppRate_20Mbps:
+			supported = g_phy_rates_suppt[4][idx];
+			break;
+		case eCsrSuppRate_24Mbps:
+			supported = g_phy_rates_suppt[5][idx];
+			break;
+		case eCsrSuppRate_36Mbps:
+			supported = g_phy_rates_suppt[6][idx];
+			break;
+		case eCsrSuppRate_40Mbps:
+			supported = g_phy_rates_suppt[7][idx];
+			break;
+		case eCsrSuppRate_42Mbps:
+			supported = g_phy_rates_suppt[8][idx];
+			break;
+		case eCsrSuppRate_48Mbps:
+			supported = g_phy_rates_suppt[9][idx];
+			break;
+		case eCsrSuppRate_54Mbps:
+			supported = g_phy_rates_suppt[10][idx];
+			break;
+		case eCsrSuppRate_72Mbps:
+			supported = g_phy_rates_suppt[11][idx];
+			break;
+		case eCsrSuppRate_80Mbps:
+			supported = g_phy_rates_suppt[12][idx];
+			break;
+		case eCsrSuppRate_84Mbps:
+			supported = g_phy_rates_suppt[13][idx];
+			break;
+		case eCsrSuppRate_96Mbps:
+			supported = g_phy_rates_suppt[14][idx];
+			break;
+		case eCsrSuppRate_108Mbps:
+			supported = g_phy_rates_suppt[15][idx];
+			break;
+		case eCsrSuppRate_120Mbps:
+			supported = g_phy_rates_suppt[16][idx];
+			break;
+		case eCsrSuppRate_126Mbps:
+			supported = g_phy_rates_suppt[17][idx];
+			break;
+		case eCsrSuppRate_144Mbps:
+			supported = g_phy_rates_suppt[18][idx];
+			break;
+		case eCsrSuppRate_160Mbps:
+			supported = g_phy_rates_suppt[19][idx];
+			break;
+		case eCsrSuppRate_168Mbps:
+			supported = g_phy_rates_suppt[20][idx];
+			break;
+		case eCsrSuppRate_192Mbps:
+			supported = g_phy_rates_suppt[21][idx];
+			break;
+		case eCsrSuppRate_216Mbps:
+			supported = g_phy_rates_suppt[22][idx];
+			break;
+		case eCsrSuppRate_240Mbps:
+			supported = g_phy_rates_suppt[23][idx];
+			break;
+		default:
+			supported = false;
+			break;
+		}
+	}
+	return supported;
+}
+
+void csr_add_rate_bitmap(uint8_t rate, uint16_t *pRateBitmap)
+{
+	uint16_t rateBitmap;
+	uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
+
+	rateBitmap = *pRateBitmap;
+	switch (n) {
+	case SIR_MAC_RATE_1:
+		rateBitmap |= SIR_MAC_RATE_1_BITMAP;
+		break;
+	case SIR_MAC_RATE_2:
+		rateBitmap |= SIR_MAC_RATE_2_BITMAP;
+		break;
+	case SIR_MAC_RATE_5_5:
+		rateBitmap |= SIR_MAC_RATE_5_5_BITMAP;
+		break;
+	case SIR_MAC_RATE_11:
+		rateBitmap |= SIR_MAC_RATE_11_BITMAP;
+		break;
+	case SIR_MAC_RATE_6:
+		rateBitmap |= SIR_MAC_RATE_6_BITMAP;
+		break;
+	case SIR_MAC_RATE_9:
+		rateBitmap |= SIR_MAC_RATE_9_BITMAP;
+		break;
+	case SIR_MAC_RATE_12:
+		rateBitmap |= SIR_MAC_RATE_12_BITMAP;
+		break;
+	case SIR_MAC_RATE_18:
+		rateBitmap |= SIR_MAC_RATE_18_BITMAP;
+		break;
+	case SIR_MAC_RATE_24:
+		rateBitmap |= SIR_MAC_RATE_24_BITMAP;
+		break;
+	case SIR_MAC_RATE_36:
+		rateBitmap |= SIR_MAC_RATE_36_BITMAP;
+		break;
+	case SIR_MAC_RATE_48:
+		rateBitmap |= SIR_MAC_RATE_48_BITMAP;
+		break;
+	case SIR_MAC_RATE_54:
+		rateBitmap |= SIR_MAC_RATE_54_BITMAP;
+		break;
+	}
+	*pRateBitmap = rateBitmap;
+}
+
+bool csr_check_rate_bitmap(uint8_t rate, uint16_t rateBitmap)
+{
+	uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
+
+	switch (n) {
+	case SIR_MAC_RATE_1:
+		rateBitmap &= SIR_MAC_RATE_1_BITMAP;
+		break;
+	case SIR_MAC_RATE_2:
+		rateBitmap &= SIR_MAC_RATE_2_BITMAP;
+		break;
+	case SIR_MAC_RATE_5_5:
+		rateBitmap &= SIR_MAC_RATE_5_5_BITMAP;
+		break;
+	case SIR_MAC_RATE_11:
+		rateBitmap &= SIR_MAC_RATE_11_BITMAP;
+		break;
+	case SIR_MAC_RATE_6:
+		rateBitmap &= SIR_MAC_RATE_6_BITMAP;
+		break;
+	case SIR_MAC_RATE_9:
+		rateBitmap &= SIR_MAC_RATE_9_BITMAP;
+		break;
+	case SIR_MAC_RATE_12:
+		rateBitmap &= SIR_MAC_RATE_12_BITMAP;
+		break;
+	case SIR_MAC_RATE_18:
+		rateBitmap &= SIR_MAC_RATE_18_BITMAP;
+		break;
+	case SIR_MAC_RATE_24:
+		rateBitmap &= SIR_MAC_RATE_24_BITMAP;
+		break;
+	case SIR_MAC_RATE_36:
+		rateBitmap &= SIR_MAC_RATE_36_BITMAP;
+		break;
+	case SIR_MAC_RATE_48:
+		rateBitmap &= SIR_MAC_RATE_48_BITMAP;
+		break;
+	case SIR_MAC_RATE_54:
+		rateBitmap &= SIR_MAC_RATE_54_BITMAP;
+		break;
+	}
+	return !!rateBitmap;
+}
+
+bool csr_rates_is_dot11_rate_supported(tpAniSirGlobal mac_ctx, uint8_t rate)
+{
+	uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
+
+	return csr_is_aggregate_rate_supported(mac_ctx, n);
+}
+
+static uint16_t csr_rates_mac_prop_to_dot11(uint16_t Rate)
+{
+	uint16_t ConvertedRate = Rate;
+
+	switch (Rate) {
+	case SIR_MAC_RATE_1:
+		ConvertedRate = 2;
+		break;
+	case SIR_MAC_RATE_2:
+		ConvertedRate = 4;
+		break;
+	case SIR_MAC_RATE_5_5:
+		ConvertedRate = 11;
+		break;
+	case SIR_MAC_RATE_11:
+		ConvertedRate = 22;
+		break;
+
+	case SIR_MAC_RATE_6:
+		ConvertedRate = 12;
+		break;
+	case SIR_MAC_RATE_9:
+		ConvertedRate = 18;
+		break;
+	case SIR_MAC_RATE_12:
+		ConvertedRate = 24;
+		break;
+	case SIR_MAC_RATE_18:
+		ConvertedRate = 36;
+		break;
+	case SIR_MAC_RATE_24:
+		ConvertedRate = 48;
+		break;
+	case SIR_MAC_RATE_36:
+		ConvertedRate = 72;
+		break;
+	case SIR_MAC_RATE_42:
+		ConvertedRate = 84;
+		break;
+	case SIR_MAC_RATE_48:
+		ConvertedRate = 96;
+		break;
+	case SIR_MAC_RATE_54:
+		ConvertedRate = 108;
+		break;
+
+	case SIR_MAC_RATE_72:
+		ConvertedRate = 144;
+		break;
+	case SIR_MAC_RATE_84:
+		ConvertedRate = 168;
+		break;
+	case SIR_MAC_RATE_96:
+		ConvertedRate = 192;
+		break;
+	case SIR_MAC_RATE_108:
+		ConvertedRate = 216;
+		break;
+	case SIR_MAC_RATE_126:
+		ConvertedRate = 252;
+		break;
+	case SIR_MAC_RATE_144:
+		ConvertedRate = 288;
+		break;
+	case SIR_MAC_RATE_168:
+		ConvertedRate = 336;
+		break;
+	case SIR_MAC_RATE_192:
+		ConvertedRate = 384;
+		break;
+	case SIR_MAC_RATE_216:
+		ConvertedRate = 432;
+		break;
+	case SIR_MAC_RATE_240:
+		ConvertedRate = 480;
+		break;
+
+	case 0xff:
+		ConvertedRate = 0;
+		break;
+	}
+
+	return ConvertedRate;
+}
+
+uint16_t csr_rates_find_best_rate(tSirMacRateSet *pSuppRates,
+				  tSirMacRateSet *pExtRates,
+				  tSirMacPropRateSet *pPropRates)
+{
+	uint8_t i;
+	uint16_t nBest;
+
+	nBest = pSuppRates->rate[0] & (~CSR_DOT11_BASIC_RATE_MASK);
+
+	if (pSuppRates->numRates > SIR_MAC_RATESET_EID_MAX)
+		pSuppRates->numRates = SIR_MAC_RATESET_EID_MAX;
+
+	for (i = 1U; i < pSuppRates->numRates; ++i) {
+		nBest =
+			(uint16_t) CSR_MAX(nBest,
+					   pSuppRates->
+					rate[i] & (~CSR_DOT11_BASIC_RATE_MASK));
+	}
+
+	if (NULL != pExtRates) {
+		for (i = 0U; i < pExtRates->numRates; ++i) {
+			nBest =
+				(uint16_t) CSR_MAX(nBest,
+						   pExtRates->
+						   rate[i] &
+						  (~CSR_DOT11_BASIC_RATE_MASK));
+		}
+	}
+
+	if (NULL != pPropRates) {
+		for (i = 0U; i < pPropRates->numPropRates; ++i) {
+			nBest =
+				(uint16_t) CSR_MAX(nBest,
+						   csr_rates_mac_prop_to_dot11
+						(pPropRates->propRate[i]));
+		}
+	}
+
+	return nBest;
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+static inline void csr_free_fils_profile_info(struct csr_roam_profile *profile)
+{
+	if (profile->fils_con_info) {
+		qdf_mem_free(profile->fils_con_info);
+		profile->fils_con_info = NULL;
+	}
+
+	if (profile->hlp_ie) {
+		qdf_mem_free(profile->hlp_ie);
+		profile->hlp_ie = NULL;
+		profile->hlp_ie_len = 0;
+	}
+}
+#else
+static inline void csr_free_fils_profile_info(struct csr_roam_profile *profile)
+{ }
+#endif
+
+void csr_release_profile(tpAniSirGlobal pMac, struct csr_roam_profile *pProfile)
+{
+	if (pProfile) {
+		if (pProfile->BSSIDs.bssid) {
+			qdf_mem_free(pProfile->BSSIDs.bssid);
+			pProfile->BSSIDs.bssid = NULL;
+		}
+		if (pProfile->SSIDs.SSIDList) {
+			qdf_mem_free(pProfile->SSIDs.SSIDList);
+			pProfile->SSIDs.SSIDList = NULL;
+		}
+		if (pProfile->pWPAReqIE) {
+			qdf_mem_free(pProfile->pWPAReqIE);
+			pProfile->pWPAReqIE = NULL;
+		}
+		if (pProfile->pRSNReqIE) {
+			qdf_mem_free(pProfile->pRSNReqIE);
+			pProfile->pRSNReqIE = NULL;
+		}
+#ifdef FEATURE_WLAN_WAPI
+		if (pProfile->pWAPIReqIE) {
+			qdf_mem_free(pProfile->pWAPIReqIE);
+			pProfile->pWAPIReqIE = NULL;
+		}
+#endif /* FEATURE_WLAN_WAPI */
+
+		if (pProfile->pAddIEScan) {
+			qdf_mem_free(pProfile->pAddIEScan);
+			pProfile->pAddIEScan = NULL;
+		}
+
+		if (pProfile->pAddIEAssoc) {
+			qdf_mem_free(pProfile->pAddIEAssoc);
+			pProfile->pAddIEAssoc = NULL;
+		}
+		if (pProfile->ChannelInfo.ChannelList) {
+			qdf_mem_free(pProfile->ChannelInfo.ChannelList);
+			pProfile->ChannelInfo.ChannelList = NULL;
+		}
+		csr_free_fils_profile_info(pProfile);
+		qdf_mem_set(pProfile, sizeof(struct csr_roam_profile), 0);
+	}
+}
+
+void csr_free_scan_filter(tpAniSirGlobal pMac, tCsrScanResultFilter
+						*pScanFilter)
+{
+	if (pScanFilter->BSSIDs.bssid) {
+		qdf_mem_free(pScanFilter->BSSIDs.bssid);
+		pScanFilter->BSSIDs.bssid = NULL;
+	}
+	if (pScanFilter->ChannelInfo.ChannelList) {
+		qdf_mem_free(pScanFilter->ChannelInfo.ChannelList);
+		pScanFilter->ChannelInfo.ChannelList = NULL;
+	}
+	if (pScanFilter->SSIDs.SSIDList) {
+		qdf_mem_free(pScanFilter->SSIDs.SSIDList);
+		pScanFilter->SSIDs.SSIDList = NULL;
+	}
+}
+
+void csr_free_roam_profile(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	struct csr_roam_session *pSession = &pMac->roam.roamSession[sessionId];
+
+	if (pSession->pCurRoamProfile) {
+		csr_release_profile(pMac, pSession->pCurRoamProfile);
+		qdf_mem_free(pSession->pCurRoamProfile);
+		pSession->pCurRoamProfile = NULL;
+	}
+}
+
+void csr_free_connect_bss_desc(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	struct csr_roam_session *pSession = &pMac->roam.roamSession[sessionId];
+
+	if (pSession->pConnectBssDesc) {
+		qdf_mem_free(pSession->pConnectBssDesc);
+		pSession->pConnectBssDesc = NULL;
+	}
+}
+
+tSirResultCodes csr_get_disassoc_rsp_status_code(tSirSmeDisassocRsp *
+						 pSmeDisassocRsp)
+{
+	uint8_t *pBuffer = (uint8_t *) pSmeDisassocRsp;
+	uint32_t ret;
+
+	pBuffer += (sizeof(uint16_t) + sizeof(uint16_t) + sizeof(tSirMacAddr));
+	/* tSirResultCodes is an enum, assuming is 32bit */
+	/* If we cannot make this assumption, use copymemory */
+	qdf_get_u32(pBuffer, &ret);
+
+	return (tSirResultCodes) ret;
+}
+
+tSirResultCodes csr_get_de_auth_rsp_status_code(tSirSmeDeauthRsp *pSmeRsp)
+{
+	uint8_t *pBuffer = (uint8_t *) pSmeRsp;
+	uint32_t ret;
+
+	pBuffer +=
+		(sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint8_t) +
+		 sizeof(uint16_t));
+	/* tSirResultCodes is an enum, assuming is 32bit */
+	/* If we cannot make this assumption, use copymemory */
+	qdf_get_u32(pBuffer, &ret);
+
+	return (tSirResultCodes) ret;
+}
+
+tSirScanType csr_get_scan_type(tpAniSirGlobal pMac, uint8_t chnId)
+{
+	tSirScanType scanType = eSIR_PASSIVE_SCAN;
+	enum channel_state channelEnabledType;
+
+	channelEnabledType = wlan_reg_get_channel_state(pMac->pdev, chnId);
+	if (CHANNEL_STATE_ENABLE == channelEnabledType)
+		scanType = eSIR_ACTIVE_SCAN;
+
+	return scanType;
+}
+
+uint8_t csr_to_upper(uint8_t ch)
+{
+	uint8_t chOut;
+
+	if (ch >= 'a' && ch <= 'z')
+		chOut = ch - 'a' + 'A';
+	else
+		chOut = ch;
+
+	return chOut;
+}
+
+tSirBssType csr_translate_bsstype_to_mac_type(eCsrRoamBssType csrtype)
+{
+	tSirBssType ret;
+
+	switch (csrtype) {
+	case eCSR_BSS_TYPE_INFRASTRUCTURE:
+		ret = eSIR_INFRASTRUCTURE_MODE;
+		break;
+	case eCSR_BSS_TYPE_IBSS:
+	case eCSR_BSS_TYPE_START_IBSS:
+		ret = eSIR_IBSS_MODE;
+		break;
+	case eCSR_BSS_TYPE_INFRA_AP:
+		ret = eSIR_INFRA_AP_MODE;
+		break;
+	case eCSR_BSS_TYPE_NDI:
+		ret = eSIR_NDI_MODE;
+		break;
+	case eCSR_BSS_TYPE_ANY:
+	default:
+		ret = eSIR_AUTO_MODE;
+		break;
+	}
+
+	return ret;
+}
+
+/* This function use the parameters to decide the CFG value. */
+/* CSR never sets WNI_CFG_DOT11_MODE_ALL to the CFG */
+/* So PE should not see WNI_CFG_DOT11_MODE_ALL when it gets the CFG value */
+enum csr_cfgdot11mode
+csr_get_cfg_dot11_mode_from_csr_phy_mode(struct csr_roam_profile *pProfile,
+					 eCsrPhyMode phyMode,
+					 bool fProprietary)
+{
+	uint32_t cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG;
+
+	switch (phyMode) {
+	case eCSR_DOT11_MODE_11a:
+		cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+		break;
+	case eCSR_DOT11_MODE_11b:
+	case eCSR_DOT11_MODE_11b_ONLY:
+		cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+		break;
+	case eCSR_DOT11_MODE_11g:
+	case eCSR_DOT11_MODE_11g_ONLY:
+		if (pProfile && (CSR_IS_INFRA_AP(pProfile))
+		    && (phyMode == eCSR_DOT11_MODE_11g_ONLY))
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G_ONLY;
+		else
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+		break;
+	case eCSR_DOT11_MODE_11n:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_DOT11_MODE_11n_ONLY:
+		if (pProfile && CSR_IS_INFRA_AP(pProfile))
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N_ONLY;
+		else
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_DOT11_MODE_abg:
+		cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG;
+		break;
+	case eCSR_DOT11_MODE_AUTO:
+		cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
+		break;
+
+	case eCSR_DOT11_MODE_11ac:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+		else
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_DOT11_MODE_11ac_ONLY:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC_ONLY;
+		else
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_DOT11_MODE_11ax:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX))
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AX;
+		else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+		else
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_DOT11_MODE_11ax_ONLY:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX))
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AX_ONLY;
+		else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+		else
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+		break;
+
+	default:
+		/* No need to assign anything here */
+		break;
+	}
+
+	return cfgDot11Mode;
+}
+
+QDF_STATUS csr_get_regulatory_domain_for_country(tpAniSirGlobal pMac,
+						 uint8_t *pCountry,
+						 v_REGDOMAIN_t *pDomainId,
+						 enum country_src source)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	QDF_STATUS qdf_status;
+	uint8_t countryCode[CDS_COUNTRY_CODE_LEN + 1];
+	v_REGDOMAIN_t domainId;
+
+	if (pCountry) {
+		countryCode[0] = pCountry[0];
+		countryCode[1] = pCountry[1];
+		qdf_status = wlan_reg_get_domain_from_country_code(&domainId,
+								  countryCode,
+								  source);
+
+		if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			if (pDomainId)
+				*pDomainId = domainId;
+			status = QDF_STATUS_SUCCESS;
+		} else {
+			sme_warn("Couldn't find domain for country code %c%c",
+				pCountry[0], pCountry[1]);
+			status = QDF_STATUS_E_INVAL;
+		}
+	}
+
+	return status;
+}
+
+QDF_STATUS csr_get_modify_profile_fields(tpAniSirGlobal pMac,
+					uint32_t sessionId,
+					 tCsrRoamModifyProfileFields *
+					 pModifyProfileFields)
+{
+	if (!pModifyProfileFields)
+		return QDF_STATUS_E_FAILURE;
+
+	qdf_mem_copy(pModifyProfileFields,
+		     &pMac->roam.roamSession[sessionId].connectedProfile.
+		     modifyProfileFields, sizeof(tCsrRoamModifyProfileFields));
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS csr_set_modify_profile_fields(tpAniSirGlobal pMac,
+					uint32_t sessionId,
+					 tCsrRoamModifyProfileFields *
+					 pModifyProfileFields)
+{
+	struct csr_roam_session *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	qdf_mem_copy(&pSession->connectedProfile.modifyProfileFields,
+		     pModifyProfileFields, sizeof(tCsrRoamModifyProfileFields));
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
+bool csr_is_set_key_allowed(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	bool fRet = true;
+	struct csr_roam_session *pSession;
+
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	/*
+	 * This condition is not working for infra state. When infra is in
+	 * not-connected state the pSession->pCurRoamProfile is NULL, this
+	 * function returns true, that is incorrect.
+	 * Since SAP requires to set key without any BSS started, it needs
+	 * this condition to be met. In other words, this function is useless.
+	 * The current work-around is to process setcontext_rsp no matter
+	 * what the state is.
+	 */
+	sme_debug("is not what it intends to. Must be revisit or removed");
+	if ((NULL == pSession)
+	    || (csr_is_conn_state_disconnected(pMac, sessionId)
+		&& (pSession->pCurRoamProfile != NULL)
+		&& (!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile))))
+	    ) {
+		fRet = false;
+	}
+
+	return fRet;
+}
+
+/* no need to acquire lock for this basic function */
+uint16_t sme_chn_to_freq(uint8_t chanNum)
+{
+	int i;
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		if (WLAN_REG_CH_NUM(i) == chanNum)
+			return WLAN_REG_CH_TO_FREQ(i);
+	}
+
+	return 0;
+}
+
+struct lim_channel_status *
+csr_get_channel_status(tpAniSirGlobal mac, uint32_t channel_id)
+{
+	uint8_t i;
+	struct lim_scan_channel_status *channel_status;
+	struct lim_channel_status *entry;
+
+	if (!mac->sap.acs_with_more_param)
+		return NULL;
+
+	channel_status = &mac->lim.scan_channel_status;
+	for (i = 0; i < channel_status->total_channel; i++) {
+		entry = &channel_status->channel_status_list[i];
+		if (entry->channel_id == channel_id)
+			return entry;
+	}
+	sme_err("Channel %d status info not exist", channel_id);
+
+	return NULL;
+}
+
+void csr_clear_channel_status(tpAniSirGlobal mac)
+{
+	struct lim_scan_channel_status *channel_status;
+
+	if (!mac->sap.acs_with_more_param)
+		return;
+
+	channel_status = &mac->lim.scan_channel_status;
+	channel_status->total_channel = 0;
+
+	return;
+}
+
+bool csr_is_channel_present_in_list(uint8_t *pChannelList,
+				    int numChannels, uint8_t channel)
+{
+	int i = 0;
+
+	/* Check for NULL pointer */
+	if (!pChannelList || (numChannels == 0))
+		return false;
+
+	/* Look for the channel in the list */
+	for (i = 0; (i < numChannels) &&
+	     (i < WNI_CFG_VALID_CHANNEL_LIST_LEN); i++) {
+		if (pChannelList[i] == channel)
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * sme_bsstype_to_string() - converts bss type to string.
+ * @bss_type: bss type enum
+ *
+ * Return: printable string for bss type
+ */
+const char *sme_bss_type_to_string(const uint8_t bss_type)
+{
+	switch (bss_type) {
+	CASE_RETURN_STRING(eCSR_BSS_TYPE_INFRASTRUCTURE);
+	CASE_RETURN_STRING(eCSR_BSS_TYPE_INFRA_AP);
+	CASE_RETURN_STRING(eCSR_BSS_TYPE_IBSS);
+	CASE_RETURN_STRING(eCSR_BSS_TYPE_START_IBSS);
+	CASE_RETURN_STRING(eCSR_BSS_TYPE_ANY);
+	default:
+		return "unknown bss type";
+	}
+}
+
+QDF_STATUS csr_add_to_channel_list_front(uint8_t *pChannelList,
+					 int numChannels, uint8_t channel)
+{
+	int i = 0;
+
+	/* Check for NULL pointer */
+	if (!pChannelList)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	/* Make room for the addition.  (Start moving from the back.) */
+	for (i = numChannels; i > 0; i--)
+		pChannelList[i] = pChannelList[i - 1];
+
+	/* Now add the NEW channel...at the front */
+	pChannelList[0] = channel;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_wait_for_connection_update() - Wait for hw mode update
+ * @mac: Pointer to the MAC context
+ * @do_release_reacquire_lock: Indicates whether release and
+ * re-acquisition of SME global lock is required.
+ *
+ * Waits for CONNECTION_UPDATE_TIMEOUT time so that the
+ * hw mode update can get processed.
+ *
+ * Return: True if the wait was successful, false otherwise
+ */
+bool csr_wait_for_connection_update(tpAniSirGlobal mac,
+		bool do_release_reacquire_lock)
+{
+	QDF_STATUS status, ret;
+
+	if (do_release_reacquire_lock == true) {
+		ret = sme_release_global_lock(&mac->sme);
+		if (!QDF_IS_STATUS_SUCCESS(ret)) {
+			cds_err("lock release fail %d", ret);
+			return false;
+		}
+	}
+
+	status = policy_mgr_wait_for_connection_update(mac->psoc);
+
+	if (do_release_reacquire_lock == true) {
+		ret = sme_acquire_global_lock(&mac->sme);
+		if (!QDF_IS_STATUS_SUCCESS(ret)) {
+			cds_err("lock acquire fail %d", ret);
+			return false;
+		}
+	}
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		cds_err("wait for event failed");
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * csr_get_session_persona() - get persona of a session
+ * @pmac: pointer to global MAC context
+ * @session_id: session id
+ *
+ * This function is to return the persona of a session
+ *
+ * Reture: enum QDF_OPMODE persona
+ */
+enum QDF_OPMODE csr_get_session_persona(tpAniSirGlobal pmac,
+					uint32_t session_id)
+{
+	struct csr_roam_session *session = NULL;
+
+	session = CSR_GET_SESSION(pmac, session_id);
+	if (NULL == session || NULL == session->pCurRoamProfile)
+		return QDF_MAX_NO_OF_MODE;
+
+	return session->pCurRoamProfile->csrPersona;
+}
+
+/**
+ * csr_is_ndi_started() - function to check if NDI is started
+ * @mac_ctx: handle to mac context
+ * @session_id: session identifier
+ *
+ * returns: true if NDI is started, false otherwise
+ */
+bool csr_is_ndi_started(tpAniSirGlobal mac_ctx, uint32_t session_id)
+{
+	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (!session)
+		return false;
+
+	return eCSR_CONNECT_STATE_TYPE_NDI_STARTED == session->connectState;
+}
+
+bool csr_is_mcc_channel(tpAniSirGlobal mac_ctx, uint8_t channel)
+{
+	struct csr_roam_session *session;
+	enum QDF_OPMODE oper_mode;
+	uint8_t oper_channel = 0;
+	uint8_t session_id;
+
+	if (channel == 0)
+		return false;
+
+	for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
+		if (CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+			session = CSR_GET_SESSION(mac_ctx, session_id);
+			if (NULL == session->pCurRoamProfile)
+				continue;
+			oper_mode = session->pCurRoamProfile->csrPersona;
+			if ((((oper_mode == QDF_STA_MODE) ||
+			    (oper_mode == QDF_P2P_CLIENT_MODE)) &&
+			    (session->connectState ==
+			    eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) ||
+			    (((oper_mode == QDF_P2P_GO_MODE) ||
+			    (oper_mode == QDF_SAP_MODE))
+			    && (session->connectState !=
+			    eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)))
+				oper_channel = session->connectedProfile.
+					operationChannel;
+
+			if (oper_channel && channel != oper_channel &&
+			    (!policy_mgr_is_hw_dbs_capable(mac_ctx->psoc) ||
+			    WLAN_REG_IS_SAME_BAND_CHANNELS(channel,
+						 oper_channel)))
+				return true;
+		}
+	}
+
+	return false;
+}
+
diff --git a/core/sme/src/nan/nan_api.c b/core/sme/src/nan/nan_api.c
new file mode 100644
index 0000000..43ac3af
--- /dev/null
+++ b/core/sme/src/nan/nan_api.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014-2018 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.
+ */
+
+#include <sir_common.h>
+#include <ani_global.h>
+#include "sme_api.h"
+#include "csr_inside_api.h"
+#include "sme_inside.h"
+#include "nan_api.h"
+#include "cfg_api.h"
+#include "wma_types.h"
+
+void sme_nan_register_callback(mac_handle_t mac_handle, nan_callback callback)
+{
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	if (!mac) {
+		sme_err("Invalid MAC handle");
+		return;
+	}
+	mac->sme.nan_callback = callback;
+}
+
+void sme_nan_deregister_callback(mac_handle_t mac_handle)
+{
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	if (!mac) {
+		sme_err("Invalid MAC handle");
+		return;
+	}
+	mac->sme.nan_callback = NULL;
+}
+
+QDF_STATUS sme_nan_request(tpNanRequestReq input)
+{
+	struct scheduler_msg msg = {0};
+	tpNanRequest data;
+	size_t data_len;
+
+	data_len = sizeof(tNanRequest) + input->request_data_len;
+	data = qdf_mem_malloc(data_len);
+	if (!data)
+		return QDF_STATUS_E_NOMEM;
+
+	data->request_data_len = input->request_data_len;
+	if (input->request_data_len) {
+		qdf_mem_copy(data->request_data,
+			     input->request_data, input->request_data_len);
+	}
+
+	msg.type = WMA_NAN_REQUEST;
+	msg.reserved = 0;
+	msg.bodyptr = data;
+
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_WMA,
+							 QDF_MODULE_ID_WMA,
+							 &msg)) {
+		sme_err("Not able to post WMA_NAN_REQUEST message to WMA");
+		qdf_mem_free(data);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void sme_nan_event(mac_handle_t mac_handle, tSirNanEvent *event)
+{
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	sme_debug("Received eWNI_SME_NAN_EVENT");
+
+	if (!mac) {
+		sme_err("Invalid MAC handle");
+		return;
+	}
+
+	if (!event) {
+		sme_err("NULL event");
+		return;
+	}
+
+	if (mac->sme.nan_callback)
+		mac->sme.nan_callback(mac->hdd_handle, event);
+}
diff --git a/core/sme/src/nan/nan_datapath_api.c b/core/sme/src/nan/nan_datapath_api.c
new file mode 100644
index 0000000..9cf33a3
--- /dev/null
+++ b/core/sme/src/nan/nan_datapath_api.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2016-2018 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: nan_datapath_api.c
+ *
+ * SME NAN Data path API implementation
+ */
+#include <sir_common.h>
+#include <ani_global.h>
+#include "sme_api.h"
+#include "sme_inside.h"
+#include "csr_internal.h"
+#include "sme_nan_datapath.h"
+
+/**
+ * csr_roam_start_ndi() - Start connection for NAN datapath
+ * @mac_ctx: Global MAC context
+ * @session: SME session ID
+ * @profile: Configuration profile
+ *
+ * Return: Success or failure code
+ */
+QDF_STATUS csr_roam_start_ndi(tpAniSirGlobal mac_ctx, uint32_t session,
+			struct csr_roam_profile *profile)
+{
+	QDF_STATUS status;
+	struct bss_config_param bss_cfg = {0};
+
+	/* Build BSS configuration from profile */
+	status = csr_roam_prepare_bss_config_from_profile(mac_ctx, profile,
+						    &bss_cfg, NULL);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac_ctx->roam.roamSession[session].bssParams.uCfgDot11Mode
+			= bss_cfg.uCfgDot11Mode;
+		/* Copy profile parameters to PE session */
+		csr_roam_prepare_bss_params(mac_ctx, session, profile, NULL,
+			&bss_cfg, NULL);
+		/*
+		 * Following routine will eventually call
+		 * csrRoamIssueStartBss through csrRoamCcmCfgSetCallback
+		 */
+		status = csr_roam_set_bss_config_cfg(mac_ctx, session, profile,
+						NULL, &bss_cfg, NULL, false);
+	}
+
+	sme_debug("profile config validity: %d", status);
+
+	return status;
+}
+
+/**
+ * csr_roam_save_ndi_connected_info() - Save connected profile parameters
+ * @mac_ctx: Global MAC context
+ * @session_id: Session ID
+ * @roam_profile: Profile given for starting BSS
+ * @bssdesc: BSS description from tSirSmeStartBssRsp response
+ *
+ * Saves NDI profile parameters into session's connected profile.
+ *
+ * Return: None
+ */
+void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx,
+				      uint32_t session_id,
+				      struct csr_roam_profile *roam_profile,
+				      tSirBssDescription *bssdesc)
+{
+	struct csr_roam_session *roam_session;
+	tCsrRoamConnectedProfile *connect_profile;
+
+	roam_session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (!roam_session) {
+		sme_err("session %d not found", session_id);
+		return;
+	}
+
+	connect_profile = &roam_session->connectedProfile;
+	qdf_mem_zero(connect_profile, sizeof(*connect_profile));
+	connect_profile->AuthType = roam_profile->negotiatedAuthType;
+		connect_profile->AuthInfo = roam_profile->AuthType;
+	connect_profile->EncryptionType =
+		roam_profile->negotiatedUCEncryptionType;
+		connect_profile->EncryptionInfo = roam_profile->EncryptionType;
+	connect_profile->mcEncryptionType =
+		roam_profile->negotiatedMCEncryptionType;
+		connect_profile->mcEncryptionInfo =
+			roam_profile->mcEncryptionType;
+	connect_profile->BSSType = roam_profile->BSSType;
+	connect_profile->modifyProfileFields.uapsd_mask =
+		roam_profile->uapsd_mask;
+	connect_profile->operationChannel = bssdesc->channelId;
+	connect_profile->beaconInterval = 0;
+	qdf_mem_copy(&connect_profile->Keys, &roam_profile->Keys,
+		     sizeof(roam_profile->Keys));
+	csr_get_bss_id_bss_desc(bssdesc, &connect_profile->bssid);
+	connect_profile->SSID.length = 0;
+	csr_free_connect_bss_desc(mac_ctx, session_id);
+	connect_profile->qap = false;
+	connect_profile->qosConnection = false;
+}
+
+/**
+ * csr_roam_update_ndp_return_params() - updates ndp return parameters
+ * @mac_ctx: MAC context handle
+ * @result: result of the roaming command
+ * @roam_status: roam status returned to the roam command initiator
+ * @roam_result: roam result returned to the roam command initiator
+ * @roam_info: Roam info data structure to be updated
+ *
+ * Results: None
+ */
+void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx,
+					uint32_t result,
+					uint32_t *roam_status,
+					uint32_t *roam_result,
+					struct csr_roam_info *roam_info)
+{
+
+	switch (result) {
+	case eCsrStartBssSuccess:
+		roam_info->ndp.ndi_create_params.reason = 0;
+		roam_info->ndp.ndi_create_params.status =
+					NDP_RSP_STATUS_SUCCESS;
+		roam_info->ndp.ndi_create_params.sta_id = roam_info->staId;
+		*roam_status = eCSR_ROAM_NDP_STATUS_UPDATE;
+		*roam_result = eCSR_ROAM_RESULT_NDI_CREATE_RSP;
+		break;
+	case eCsrStartBssFailure:
+		roam_info->ndp.ndi_create_params.status = NDP_RSP_STATUS_ERROR;
+		roam_info->ndp.ndi_create_params.reason =
+					NDP_NAN_DATA_IFACE_CREATE_FAILED;
+		*roam_status = eCSR_ROAM_NDP_STATUS_UPDATE;
+		*roam_result = eCSR_ROAM_RESULT_NDI_CREATE_RSP;
+		break;
+	case eCsrStopBssSuccess:
+		roam_info->ndp.ndi_delete_params.reason = 0;
+		roam_info->ndp.ndi_delete_params.status =
+						NDP_RSP_STATUS_SUCCESS;
+		*roam_status = eCSR_ROAM_NDP_STATUS_UPDATE;
+		*roam_result = eCSR_ROAM_RESULT_NDI_DELETE_RSP;
+		break;
+	case eCsrStopBssFailure:
+		roam_info->ndp.ndi_delete_params.status = NDP_RSP_STATUS_ERROR;
+		roam_info->ndp.ndi_delete_params.reason =
+					NDP_NAN_DATA_IFACE_DELETE_FAILED;
+		*roam_status = eCSR_ROAM_NDP_STATUS_UPDATE;
+		*roam_result = eCSR_ROAM_RESULT_NDI_DELETE_RSP;
+		break;
+	default:
+		sme_err("Invalid CSR Roam result code: %d", result);
+		break;
+	}
+}
diff --git a/core/sme/src/qos/sme_qos.c b/core/sme/src/qos/sme_qos.c
new file mode 100644
index 0000000..a7efae2
--- /dev/null
+++ b/core/sme/src/qos/sme_qos.c
@@ -0,0 +1,7602 @@
+/*
+ * Copyright (c) 2012-2018 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: sme_qos.c
+ *
+ *  Implementation for SME QoS APIs
+ */
+/* $Header$ */
+/* Include Files */
+
+#include "ani_global.h"
+
+#include "sme_inside.h"
+#include "csr_inside_api.h"
+#include "host_diag_core_event.h"
+#include "host_diag_core_log.h"
+
+#include "utils_parser.h"
+#include "sme_power_save_api.h"
+
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+/* TODO : 6Mbps as Cisco APs seem to like only this value; analysis req.   */
+#define SME_QOS_MIN_PHY_RATE         0x5B8D80
+#define SME_QOS_SURPLUS_BW_ALLOWANCE  0x2000    /* Ratio of 1.0           */
+/* Max values to bound tspec params against and avoid rollover */
+#define SME_QOS_32BIT_MAX  0xFFFFFFFF
+#define SME_QOS_16BIT_MAX  0xFFFF
+#define SME_QOS_16BIT_MSB  0x8000
+/* Adds y to x, but saturates at 32-bit max to avoid rollover */
+#define SME_QOS_BOUNDED_U32_ADD_Y_TO_X(_x, _y) \
+	do { \
+		(_x) = ((SME_QOS_32BIT_MAX - (_x)) < (_y)) ? \
+		       (SME_QOS_32BIT_MAX) : (_x) + (_y); \
+	} while (0)
+
+/*
+ * As per WMM spec there could be max 2 TSPEC running on the same AC with
+ *  different direction. We will refer each TSPEC with an index
+ */
+#define SME_QOS_TSPEC_INDEX_0            0
+#define SME_QOS_TSPEC_INDEX_1            1
+#define SME_QOS_TSPEC_INDEX_MAX          2
+#define SME_QOS_TSPEC_MASK_BIT_1_SET     1
+#define SME_QOS_TSPEC_MASK_BIT_2_SET     2
+#define SME_QOS_TSPEC_MASK_BIT_1_2_SET   3
+#define SME_QOS_TSPEC_MASK_CLEAR         0
+
+/* which key to search on, in the flowlist (1 = flowID, 2 = AC, 4 = reason) */
+#define SME_QOS_SEARCH_KEY_INDEX_1       1
+#define SME_QOS_SEARCH_KEY_INDEX_2       2
+#define SME_QOS_SEARCH_KEY_INDEX_3       4
+#define SME_QOS_SEARCH_KEY_INDEX_4       8      /* ac + direction */
+#define SME_QOS_SEARCH_KEY_INDEX_5       0x10   /* ac + tspec_mask */
+/* special value for searching any Session Id */
+#define SME_QOS_SEARCH_SESSION_ID_ANY    CSR_ROAM_SESSION_MAX
+#define SME_QOS_ACCESS_POLICY_EDCA       1
+#define SME_QOS_MAX_TID                  255
+#define SME_QOS_TSPEC_IE_LENGTH          61
+#define SME_QOS_TSPEC_IE_TYPE            2
+#define SME_QOS_MIN_FLOW_ID              1
+#define SME_QOS_MAX_FLOW_ID              0xFFFFFFFE
+#define SME_QOS_INVALID_FLOW_ID          0xFFFFFFFF
+/* per the WMM Specification v1.2 Section 2.2.10 */
+/* The Dialog Token field shall be set [...] to a non-zero value */
+#define SME_QOS_MIN_DIALOG_TOKEN         1
+#define SME_QOS_MAX_DIALOG_TOKEN         0xFF
+/* Type declarations */
+/* Enumeration of the various states in the QoS state m/c */
+enum sme_qos_states {
+	SME_QOS_CLOSED = 0,
+	SME_QOS_INIT,
+	SME_QOS_LINK_UP,
+	SME_QOS_REQUESTED,
+	SME_QOS_QOS_ON,
+	SME_QOS_HANDOFF,
+
+};
+/* Enumeration of the various Release QoS trigger */
+enum sme_qosrel_triggers {
+	SME_QOS_RELEASE_DEFAULT = 0,
+	SME_QOS_RELEASE_BY_AP,
+};
+/* Enumeration of the various QoS cmds */
+enum sme_qos_cmdtype {
+	SME_QOS_SETUP_REQ = 0,
+	SME_QOS_RELEASE_REQ,
+	SME_QOS_MODIFY_REQ,
+	SME_QOS_RESEND_REQ,
+	SME_QOS_CMD_MAX
+};
+/* Enumeration of the various QoS reason codes to be used in the Flow list */
+enum sme_qos_reasontype {
+	SME_QOS_REASON_SETUP = 0,
+	SME_QOS_REASON_RELEASE,
+	SME_QOS_REASON_MODIFY,
+	SME_QOS_REASON_MODIFY_PENDING,
+	SME_QOS_REASON_REQ_SUCCESS,
+	SME_QOS_REASON_MAX
+};
+
+/* Table to map user priority passed in as an argument to appropriate Access
+ * Category as specified in 802.11e/WMM
+ */
+sme_QosEdcaAcType sme_qos_u_pto_ac_map[SME_QOS_WMM_UP_MAX] = {
+	SME_QOS_EDCA_AC_BE,     /* User Priority 0 */
+	SME_QOS_EDCA_AC_BK,     /* User Priority 1 */
+	SME_QOS_EDCA_AC_BK,     /* User Priority 2 */
+	SME_QOS_EDCA_AC_BE,     /* User Priority 3 */
+	SME_QOS_EDCA_AC_VI,     /* User Priority 4 */
+	SME_QOS_EDCA_AC_VI,     /* User Priority 5 */
+	SME_QOS_EDCA_AC_VO,     /* User Priority 6 */
+	SME_QOS_EDCA_AC_VO      /* User Priority 7 */
+};
+
+/*
+ * Table to map access category (AC) to appropriate user priority as specified
+ * in 802.11e/WMM
+ * Note: there is a quantization loss here because 4 ACs are mapped to 8 UPs
+ * Mapping is done for consistency
+ */
+enum sme_qos_wmmuptype sme_qos_a_cto_up_map[SME_QOS_EDCA_AC_MAX] = {
+	SME_QOS_WMM_UP_BE,      /* AC BE */
+	SME_QOS_WMM_UP_BK,      /* AC BK */
+	SME_QOS_WMM_UP_VI,      /* AC VI */
+	SME_QOS_WMM_UP_VO       /* AC VO */
+};
+
+/*
+ * DESCRIPTION
+ * SME QoS module's FLOW Link List structure. This list can hold information
+ * per flow/request, like TSPEC params requested, which AC it is running on
+ */
+struct sme_qos_flowinfoentry {
+	tListElem link;         /* list links */
+	uint8_t sessionId;
+	uint8_t tspec_mask;
+	enum sme_qos_reasontype reason;
+	uint32_t QosFlowID;
+	sme_QosEdcaAcType ac_type;
+	struct sme_qos_wmmtspecinfo QoSInfo;
+	void *HDDcontext;
+	sme_QosCallback QoSCallback;
+	bool hoRenewal;       /* set to true while re-negotiating flows after */
+	/* handoff, will set to false once done with */
+	/* the process. Helps SME to decide if at all */
+	/* to notify HDD/LIS for flow renewal after HO */
+};
+/*
+ *  DESCRIPTION
+ *  SME QoS module's setup request cmd related information structure.
+ */
+struct sme_qos_setupcmdinfo {
+	uint32_t QosFlowID;
+	struct sme_qos_wmmtspecinfo QoSInfo;
+	void *HDDcontext;
+	sme_QosCallback QoSCallback;
+	enum sme_qos_wmmuptype UPType;
+	bool hoRenewal;       /* set to true while re-negotiating flows after */
+	/* handoff, will set to false once done with */
+	/* the process. Helps SME to decide if at all */
+	/* to notify HDD/LIS for flow renewal after HO */
+};
+/*
+ *  DESCRIPTION
+ *  SME QoS module's modify cmd related information structure.
+ */
+struct sme_qos_modifycmdinfo {
+	uint32_t QosFlowID;
+	sme_QosEdcaAcType ac;
+	struct sme_qos_wmmtspecinfo QoSInfo;
+};
+/*
+ *  DESCRIPTION
+ *  SME QoS module's resend cmd related information structure.
+ */
+struct sme_qos_resendcmdinfo {
+	uint8_t tspecMask;
+	sme_QosEdcaAcType ac;
+	struct sme_qos_wmmtspecinfo QoSInfo;
+};
+/*
+ *  DESCRIPTION
+ *  SME QoS module's release cmd related information structure.
+ */
+struct sme_qos_releasecmdinfo {
+	uint32_t QosFlowID;
+};
+/*
+ *  DESCRIPTION
+ *  SME QoS module's buffered cmd related information structure.
+ */
+struct sme_qos_cmdinfo {
+	enum sme_qos_cmdtype command;
+	tpAniSirGlobal pMac;
+	uint8_t sessionId;
+	union {
+		struct sme_qos_setupcmdinfo setupCmdInfo;
+		struct sme_qos_modifycmdinfo modifyCmdInfo;
+		struct sme_qos_resendcmdinfo resendCmdInfo;
+		struct sme_qos_releasecmdinfo releaseCmdInfo;
+	} u;
+};
+/*
+ *  DESCRIPTION
+ *  SME QoS module's buffered cmd List structure. This list can hold information
+ *  related to any pending cmd from HDD
+ */
+struct sme_qos_cmdinfoentry {
+	tListElem link;         /* list links */
+	struct sme_qos_cmdinfo cmdInfo;
+};
+/*
+ *  DESCRIPTION
+ *  SME QoS module's Per AC information structure. This can hold information on
+ *  how many flows running on the AC, the current, previous states the AC is in
+ */
+struct sme_qos_acinfo {
+	uint8_t num_flows[SME_QOS_TSPEC_INDEX_MAX];
+	enum sme_qos_states curr_state;
+	enum sme_qos_states prev_state;
+	struct sme_qos_wmmtspecinfo curr_QoSInfo[SME_QOS_TSPEC_INDEX_MAX];
+	struct sme_qos_wmmtspecinfo requested_QoSInfo[SME_QOS_TSPEC_INDEX_MAX];
+	/* reassoc requested for APSD */
+	bool reassoc_pending;
+	/*
+	 * As per WMM spec there could be max 2 TSPEC running on the same
+	 * AC with different direction. We will refer each TSPEC with an index
+	 */
+	/* status showing if both the indices are in use */
+	uint8_t tspec_mask_status;
+	/* tspec negotiation going on for which index */
+	uint8_t tspec_pending;
+	/* set to true while re-negotiating flows after */
+	bool hoRenewal;
+	/*
+	 * handoff, will set to false once done with the process. Helps SME to
+	 * decide if at all to notify HDD/LIS for flow renewal after HO
+	 */
+	uint8_t ricIdentifier[SME_QOS_TSPEC_INDEX_MAX];
+	/*
+	 * stores the ADD TS response for each AC. The ADD TS response is
+	 * formed by parsing the RIC received in the the reassoc response
+	 */
+	tSirAddtsRsp addTsRsp[SME_QOS_TSPEC_INDEX_MAX];
+	enum sme_qosrel_triggers relTrig;
+
+};
+/*
+ *  DESCRIPTION
+ *  SME QoS module's Per session information structure. This can hold
+ *  information on the state of the session
+ */
+struct sme_qos_sessioninfo {
+	/* what is this entry's session id */
+	uint8_t sessionId;
+	/* is the session currently active */
+	bool sessionActive;
+	/* All AC info for this session */
+	struct sme_qos_acinfo ac_info[SME_QOS_EDCA_AC_MAX];
+	/* Bitmask of the ACs with APSD on */
+	/* Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored */
+	uint8_t apsdMask;
+	/* association information for this session */
+	sme_QosAssocInfo assocInfo;
+	/* ID assigned to our reassoc request */
+	uint32_t roamID;
+	/* are we in the process of handing off to a different AP */
+	bool handoffRequested;
+	/* commands that are being buffered for this session */
+	tDblLinkList bufferedCommandList;
+
+	bool ftHandoffInProgress;
+
+};
+/*
+ *  DESCRIPTION
+ *  Search key union. We can use the flowID, ac type, or reason to find an
+ *  entry in the flow list
+ */
+union sme_qos_searchkey {
+	uint32_t QosFlowID;
+	sme_QosEdcaAcType ac_type;
+	enum sme_qos_reasontype reason;
+};
+/*
+ *  DESCRIPTION
+ *  We can either use the flowID or the ac type to find an entry in the flow
+ *  list. The index is a bitmap telling us which key to use. Starting from LSB,
+ *  bit 0 - Flow ID
+ *  bit 1 - AC type
+ */
+struct sme_qos_searchinfo {
+	uint8_t sessionId;
+	uint8_t index;
+	union sme_qos_searchkey key;
+	enum sme_qos_wmm_dir_type direction;
+	uint8_t tspec_mask;
+};
+
+typedef QDF_STATUS (*sme_QosProcessSearchEntry)(tpAniSirGlobal pMac,
+						tListElem *pEntry);
+
+static enum sme_qos_statustype sme_qos_internal_setup_req(tpAniSirGlobal pMac,
+					  uint8_t sessionId,
+					  struct sme_qos_wmmtspecinfo *pQoSInfo,
+					  sme_QosCallback QoSCallback,
+					  void *HDDcontext,
+					  enum sme_qos_wmmuptype UPType,
+					  uint32_t QosFlowID,
+					  bool buffered_cmd, bool hoRenewal);
+static enum sme_qos_statustype sme_qos_internal_modify_req(tpAniSirGlobal pMac,
+					  struct sme_qos_wmmtspecinfo *pQoSInfo,
+					  uint32_t QosFlowID,
+					  bool buffered_cmd);
+static enum sme_qos_statustype sme_qos_internal_release_req(tpAniSirGlobal pMac,
+					       uint8_t session_id,
+					       uint32_t QosFlowID,
+					       bool buffered_cmd);
+static enum sme_qos_statustype sme_qos_setup(tpAniSirGlobal pMac,
+				uint8_t sessionId,
+				struct sme_qos_wmmtspecinfo *pTspec_Info,
+				sme_QosEdcaAcType ac);
+static QDF_STATUS sme_qos_add_ts_req(tpAniSirGlobal pMac,
+			      uint8_t sessionId,
+			      struct sme_qos_wmmtspecinfo *pTspec_Info,
+			      sme_QosEdcaAcType ac);
+static QDF_STATUS sme_qos_del_ts_req(tpAniSirGlobal pMac,
+			      uint8_t sessionId,
+			      sme_QosEdcaAcType ac, uint8_t tspec_mask);
+static QDF_STATUS sme_qos_process_add_ts_rsp(tpAniSirGlobal pMac,
+						void *pMsgBuf);
+static QDF_STATUS sme_qos_process_del_ts_ind(tpAniSirGlobal pMac,
+						void *pMsgBuf);
+static QDF_STATUS sme_qos_process_del_ts_rsp(tpAniSirGlobal pMac,
+						void *pMsgBuf);
+static QDF_STATUS sme_qos_process_assoc_complete_ev(tpAniSirGlobal pMac,
+					uint8_t sessionId, void *pEvent_info);
+static QDF_STATUS sme_qos_process_reassoc_req_ev(tpAniSirGlobal pMac,
+					uint8_t sessionId, void *pEvent_info);
+static QDF_STATUS sme_qos_process_reassoc_success_ev(tpAniSirGlobal pMac,
+					  uint8_t sessionId, void *pEvent_info);
+static QDF_STATUS sme_qos_process_reassoc_failure_ev(tpAniSirGlobal pMac,
+					  uint8_t sessionId, void *pEvent_info);
+static QDF_STATUS sme_qos_process_disconnect_ev(tpAniSirGlobal pMac, uint8_t
+					sessionId, void *pEvent_info);
+static QDF_STATUS sme_qos_process_join_req_ev(tpAniSirGlobal pMac, uint8_t
+						sessionId, void *pEvent_info);
+static QDF_STATUS sme_qos_process_handoff_assoc_req_ev(tpAniSirGlobal pMac,
+						uint8_t sessionId,
+						void *pEvent_info);
+static QDF_STATUS sme_qos_process_handoff_success_ev(tpAniSirGlobal pMac,
+					  uint8_t sessionId, void *pEvent_info);
+static QDF_STATUS sme_qos_process_preauth_success_ind(tpAniSirGlobal pMac,
+					       uint8_t sessionId,
+					       void *pEvent_info);
+static QDF_STATUS sme_qos_process_set_key_success_ind(tpAniSirGlobal pMac,
+					       uint8_t sessionId,
+						void *pEvent_info);
+static QDF_STATUS sme_qos_process_aggr_qos_rsp(tpAniSirGlobal pMac,
+						void *pMsgBuf);
+static QDF_STATUS sme_qos_ft_aggr_qos_req(tpAniSirGlobal pMac, uint8_t
+					sessionId);
+static QDF_STATUS sme_qos_process_add_ts_success_rsp(tpAniSirGlobal pMac,
+					      uint8_t sessionId,
+					      tSirAddtsRspInfo *pRsp);
+static QDF_STATUS sme_qos_process_add_ts_failure_rsp(tpAniSirGlobal pMac,
+					      uint8_t sessionId,
+					      tSirAddtsRspInfo *pRsp);
+static QDF_STATUS sme_qos_aggregate_params(
+	struct sme_qos_wmmtspecinfo *pInput_Tspec_Info,
+	struct sme_qos_wmmtspecinfo *pCurrent_Tspec_Info,
+	struct sme_qos_wmmtspecinfo *pUpdated_Tspec_Info);
+static QDF_STATUS sme_qos_update_params(uint8_t sessionId,
+				      sme_QosEdcaAcType ac,
+				      uint8_t tspec_mask,
+				      struct sme_qos_wmmtspecinfo *pTspec_Info);
+static sme_QosEdcaAcType sme_qos_up_to_ac(enum sme_qos_wmmuptype up);
+static bool sme_qos_is_acm(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc,
+		    sme_QosEdcaAcType ac, tDot11fBeaconIEs *pIes);
+static tListElem *sme_qos_find_in_flow_list(struct sme_qos_searchinfo
+						search_key);
+static QDF_STATUS sme_qos_find_all_in_flow_list(tpAniSirGlobal pMac,
+					 struct sme_qos_searchinfo search_key,
+					 sme_QosProcessSearchEntry fnp);
+static void sme_qos_state_transition(uint8_t sessionId,
+				     sme_QosEdcaAcType ac,
+				     enum sme_qos_states new_state);
+static QDF_STATUS sme_qos_buffer_cmd(struct sme_qos_cmdinfo *pcmd, bool
+					insert_head);
+static QDF_STATUS sme_qos_process_buffered_cmd(uint8_t sessionId);
+static QDF_STATUS sme_qos_save_assoc_info(struct sme_qos_sessioninfo *pSession,
+				   sme_QosAssocInfo *pAssoc_info);
+static QDF_STATUS sme_qos_setup_fnp(tpAniSirGlobal pMac, tListElem *pEntry);
+static QDF_STATUS sme_qos_modification_notify_fnp(tpAniSirGlobal pMac,
+					   tListElem *pEntry);
+static QDF_STATUS sme_qos_modify_fnp(tpAniSirGlobal pMac, tListElem *pEntry);
+static QDF_STATUS sme_qos_del_ts_ind_fnp(tpAniSirGlobal pMac, tListElem
+					*pEntry);
+static QDF_STATUS sme_qos_reassoc_success_ev_fnp(tpAniSirGlobal pMac,
+					tListElem *pEntry);
+static QDF_STATUS sme_qos_add_ts_failure_fnp(tpAniSirGlobal pMac, tListElem
+						*pEntry);
+static QDF_STATUS sme_qos_add_ts_success_fnp(tpAniSirGlobal pMac, tListElem
+						*pEntry);
+static bool sme_qos_is_rsp_pending(uint8_t sessionId, sme_QosEdcaAcType ac);
+static bool sme_qos_is_uapsd_active(void);
+
+static QDF_STATUS sme_qos_buffer_existing_flows(tpAniSirGlobal pMac,
+						uint8_t sessionId);
+static QDF_STATUS sme_qos_delete_existing_flows(tpAniSirGlobal pMac,
+						uint8_t sessionId);
+static void sme_qos_cleanup_ctrl_blk_for_handoff(tpAniSirGlobal pMac,
+						 uint8_t sessionId);
+static QDF_STATUS sme_qos_delete_buffered_requests(tpAniSirGlobal pMac,
+						   uint8_t sessionId);
+static bool sme_qos_validate_requested_params(tpAniSirGlobal pMac,
+				       struct sme_qos_wmmtspecinfo *pQoSInfo,
+				       uint8_t sessionId);
+
+static QDF_STATUS qos_issue_command(tpAniSirGlobal pMac, uint8_t sessionId,
+				    eSmeCommandType cmdType,
+				    struct sme_qos_wmmtspecinfo *pQoSInfo,
+				    sme_QosEdcaAcType ac, uint8_t tspec_mask);
+/* sme_qos_re_request_add_ts to re-send AddTS for the combined QoS request */
+static enum sme_qos_statustype sme_qos_re_request_add_ts(tpAniSirGlobal pMac,
+					  uint8_t sessionId,
+					  struct sme_qos_wmmtspecinfo *pQoSInfo,
+					  sme_QosEdcaAcType ac,
+					  uint8_t tspecMask);
+static void sme_qos_init_a_cs(tpAniSirGlobal pMac, uint8_t sessionId);
+static QDF_STATUS sme_qos_request_reassoc(tpAniSirGlobal pMac,
+					uint8_t sessionId,
+					  tCsrRoamModifyProfileFields *
+					  pModFields, bool fForce);
+static uint32_t sme_qos_assign_flow_id(void);
+static uint8_t sme_qos_assign_dialog_token(void);
+static QDF_STATUS sme_qos_update_tspec_mask(uint8_t sessionId,
+					   struct sme_qos_searchinfo search_key,
+					    uint8_t new_tspec_mask);
+
+/*
+ *  DESCRIPTION
+ *  SME QoS module's internal control block.
+ */
+struct sme_qos_cb_s {
+	/* global Mac pointer */
+	tpAniSirGlobal pMac;
+	/* All Session Info */
+	struct sme_qos_sessioninfo *sessionInfo;
+	/* All FLOW info */
+	tDblLinkList flow_list;
+	/* default TSPEC params */
+	struct sme_qos_wmmtspecinfo *def_QoSInfo;
+	/* counter for assigning Flow IDs */
+	uint32_t nextFlowId;
+	/* counter for assigning Dialog Tokens */
+	uint8_t nextDialogToken;
+} sme_qos_cb;
+
+#ifdef WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY
+static inline QDF_STATUS sme_qos_allocate_control_block_buffer(void)
+{
+	uint32_t buf_size;
+
+	buf_size = CSR_ROAM_SESSION_MAX * sizeof(struct sme_qos_sessioninfo);
+	sme_qos_cb.sessionInfo = qdf_mem_malloc(buf_size);
+	if (!sme_qos_cb.sessionInfo)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_size = SME_QOS_EDCA_AC_MAX * sizeof(struct sme_qos_wmmtspecinfo);
+	sme_qos_cb.def_QoSInfo = qdf_mem_malloc(buf_size);
+
+	if (!sme_qos_cb.def_QoSInfo) {
+		qdf_mem_free(sme_qos_cb.sessionInfo);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void sme_qos_free_control_block_buffer(void)
+{
+	qdf_mem_free(sme_qos_cb.sessionInfo);
+	sme_qos_cb.sessionInfo = NULL;
+
+	qdf_mem_free(sme_qos_cb.def_QoSInfo);
+	sme_qos_cb.def_QoSInfo = NULL;
+}
+
+#else /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
+
+struct sme_qos_sessioninfo sessionInfo[CSR_ROAM_SESSION_MAX];
+struct sme_qos_wmmtspecinfo def_QoSInfo[SME_QOS_EDCA_AC_MAX];
+
+static inline QDF_STATUS sme_qos_allocate_control_block_buffer(void)
+{
+	qdf_mem_zero(&sessionInfo, sizeof(sessionInfo));
+	sme_qos_cb.sessionInfo = sessionInfo;
+	qdf_mem_zero(&def_QoSInfo, sizeof(def_QoSInfo));
+	sme_qos_cb.def_QoSInfo = def_QoSInfo;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void sme_qos_free_control_block_buffer(void)
+{
+	sme_qos_cb.sessionInfo = NULL;
+	sme_qos_cb.def_QoSInfo = NULL;
+}
+#endif /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
+
+/* External APIs definitions */
+
+/**
+ * sme_qos_open() - called to initialize SME QoS module.
+ * @pMac: global MAC context
+ *
+ * This function must be called before any API call to
+ * SME QoS module.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_qos_open(tpAniSirGlobal pMac)
+{
+	struct sme_qos_sessioninfo *pSession;
+	uint8_t sessionId;
+	QDF_STATUS status;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: initializing SME-QoS module", __func__, __LINE__);
+	/* alloc and init the control block */
+	/* (note that this will make all sessions invalid) */
+	if (!QDF_IS_STATUS_SUCCESS(sme_qos_allocate_control_block_buffer())) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SME,
+				"%s: %d: Failed to allocate buffer",
+				__func__, __LINE__);
+		return QDF_STATUS_E_NOMEM;
+	}
+	sme_qos_cb.pMac = pMac;
+	sme_qos_cb.nextFlowId = SME_QOS_MIN_FLOW_ID;
+	sme_qos_cb.nextDialogToken = SME_QOS_MIN_DIALOG_TOKEN;
+
+	/* init flow list */
+	status = csr_ll_open(&sme_qos_cb.flow_list);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: cannot initialize Flow List",
+			  __func__, __LINE__);
+		sme_qos_free_control_block_buffer();
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) {
+		pSession = &sme_qos_cb.sessionInfo[sessionId];
+		pSession->sessionId = sessionId;
+		/* initialize the session's per-AC information */
+		sme_qos_init_a_cs(pMac, sessionId);
+		/* initialize the session's buffered command list */
+		status = csr_ll_open(&pSession->bufferedCommandList);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: cannot initialize cmd list for session %d",
+				  __func__, __LINE__, sessionId);
+			sme_qos_free_control_block_buffer();
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: done initializing SME-QoS module",
+		  __func__, __LINE__);
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_close() - To close down SME QoS module. There should not be
+ *   any API call into this module after calling this function until another
+ *   call of sme_qos_open.
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_qos_close(tpAniSirGlobal pMac)
+{
+	struct sme_qos_sessioninfo *pSession;
+	sme_QosEdcaAcType ac;
+	uint8_t sessionId;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: closing down SME-QoS", __func__, __LINE__);
+
+	/* cleanup control block */
+	/* close the flow list */
+	csr_ll_close(&sme_qos_cb.flow_list);
+	/* shut down all of the sessions */
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) {
+		pSession = &sme_qos_cb.sessionInfo[sessionId];
+		if (pSession == NULL)
+			continue;
+
+		sme_qos_init_a_cs(pMac, sessionId);
+		/* this session doesn't require UAPSD */
+		pSession->apsdMask = 0;
+
+		pSession->handoffRequested = false;
+		pSession->roamID = 0;
+		/* need to clean up buffered req */
+		sme_qos_delete_buffered_requests(pMac, sessionId);
+		/* need to clean up flows */
+		sme_qos_delete_existing_flows(pMac, sessionId);
+
+		/* Clean up the assoc info if already allocated */
+		if (pSession->assocInfo.pBssDesc) {
+			qdf_mem_free(pSession->assocInfo.pBssDesc);
+			pSession->assocInfo.pBssDesc = NULL;
+		}
+		/* close the session's buffered command list */
+		csr_ll_close(&pSession->bufferedCommandList);
+		for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
+			sme_qos_state_transition(sessionId, ac, SME_QOS_CLOSED);
+
+		pSession->sessionActive = false;
+	}
+	sme_qos_free_control_block_buffer();
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: closed down QoS", __func__, __LINE__);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_setup_req() - The SME QoS API exposed to HDD to request for QoS
+ *                       on a particular AC.
+ * @hHal: The handle returned by mac_open.
+ * @sessionId: sessionId returned by sme_open_session.
+ * @pQoSInfo: Pointer to struct sme_qos_wmmtspecinfo which contains the
+ *             WMM TSPEC related info as defined above, provided by HDD
+ * @QoSCallback: The callback which is registered per flow while
+ *               requesting for QoS. Used for any notification for the
+ *               flow (i.e. setup success/failure/release) which needs to
+ *               be sent to HDD
+ * @HDDcontext: A cookie passed by HDD to be used by SME during any QoS
+ *              notification (through the callabck) to HDD
+ * @UPType: Useful only if HDD or any other upper layer module (BAP etc.)
+ *          looking for implicit QoS setup, in that
+ *          case, the pQoSInfo will be NULL & SME will know about the AC
+ *          (from the UP provided in this param) QoS is requested on
+ * @pQosFlowID: Identification per flow running on each AC generated by
+ *              SME. It is only meaningful if the QoS setup for the flow is
+ *              successful
+ * This function should be called after a link has been
+ * established, i.e. STA is associated with an AP etc. If the request involves
+ * admission control on the requested AC, HDD needs to provide the necessary
+ * Traffic Specification (TSPEC) parameters otherwise SME is going to use the
+ * default params.
+ * Return: QDF_STATUS_SUCCESS - Setup is successful.
+ *          Other status means Setup request failed
+ */
+enum sme_qos_statustype sme_qos_setup_req(tHalHandle hHal, uint32_t sessionId,
+				    struct sme_qos_wmmtspecinfo *pQoSInfo,
+				    sme_QosCallback QoSCallback,
+				    void *HDDcontext,
+				    enum sme_qos_wmmuptype UPType,
+				    uint32_t *pQosFlowID)
+{
+	struct sme_qos_sessioninfo *pSession;
+	QDF_STATUS lock_status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	enum sme_qos_statustype status;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: QoS Setup requested by client on session %d",
+		  __func__, __LINE__, sessionId);
+	lock_status = sme_acquire_global_lock(&pMac->sme);
+	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_SETUP_FAILURE_RSP;
+	}
+	/* Make sure the session is valid */
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Supplied Session ID %d is invalid",
+			  __func__, __LINE__, sessionId);
+		status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
+	} else {
+		/* Make sure the session is active */
+		pSession = &sme_qos_cb.sessionInfo[sessionId];
+		if (!pSession->sessionActive) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: Supplied Session ID %d is inactive",
+				  __func__, __LINE__, sessionId);
+			status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
+		} else {
+			/* Assign a Flow ID */
+			*pQosFlowID = sme_qos_assign_flow_id();
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: QoS request on session %d assigned Flow ID %d",
+				  __func__, __LINE__, sessionId, *pQosFlowID);
+			/* Call the internal function for QoS setup, */
+			/* adding a layer of abstraction */
+			status =
+				sme_qos_internal_setup_req(pMac, (uint8_t)
+							sessionId,
+							  pQoSInfo, QoSCallback,
+							   HDDcontext, UPType,
+							   *pQosFlowID, false,
+							   false);
+		}
+	}
+	sme_release_global_lock(&pMac->sme);
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: QoS setup return status on session %d is %d",
+		  __func__, __LINE__, sessionId, status);
+	return status;
+}
+
+/**
+ * sme_qos_modify_req() - The SME QoS API exposed to HDD to request for
+ *  modification of certain QoS params on a flow running on a particular AC.
+ * @hHal: The handle returned by mac_open.
+ * @pQoSInfo: Pointer to struct sme_qos_wmmtspecinfo which contains the
+ *             WMM TSPEC related info as defined above, provided by HDD
+ * @QosFlowID: Identification per flow running on each AC generated by
+ *             SME. It is only meaningful if the QoS setup for the flow has
+ *             been successful already
+ *
+ * This function should be called after a link has been established,
+ * i.e. STA is associated with an AP etc. & a QoS setup has been successful for
+ * that flow. If the request involves admission control on the requested AC,
+ * HDD needs to provide the necessary Traffic Specification (TSPEC) parameters &
+ * SME might start the renegotiation process through ADDTS.
+ *
+ * Return: SME_QOS_STATUS_SETUP_SUCCESS_RSP - Modification is successful.
+ *         Other status means request failed
+ */
+enum sme_qos_statustype sme_qos_modify_req(tHalHandle hHal,
+				     struct sme_qos_wmmtspecinfo *pQoSInfo,
+				     uint32_t QosFlowID)
+{
+	QDF_STATUS lock_status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	enum sme_qos_statustype status;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: QoS Modify requested by client for Flow %d",
+		  __func__, __LINE__, QosFlowID);
+	lock_status = sme_acquire_global_lock(&pMac->sme);
+	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_MODIFY_SETUP_FAILURE_RSP;
+	}
+	/* Call the internal function for QoS modify, adding a
+	 * layer of abstraction
+	 */
+	status = sme_qos_internal_modify_req(pMac, pQoSInfo, QosFlowID, false);
+	sme_release_global_lock(&pMac->sme);
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: QoS Modify return status on Flow %d is %d",
+		  __func__, __LINE__, QosFlowID, status);
+	return status;
+}
+
+/**
+ * sme_qos_release_req() - The SME QoS API exposed to HDD to request for
+ *                         releasing a QoS flow running on a particular AC.
+ *
+ * @hHal: The handle returned by mac_open.
+ * @session_id: session_id returned by sme_open_session.
+ * @QosFlowID: Identification per flow running on each AC generated by SME
+ *             It is only meaningful if the QoS setup for the flow is successful
+ *
+ * This function should be called only if a QoS is set up with a valid FlowID.
+ * HDD sould invoke this API only if an explicit request for QoS release has
+ * come from Application
+ *
+ * Return: QDF_STATUS_SUCCESS - Release is successful.
+ */
+enum sme_qos_statustype sme_qos_release_req(tHalHandle hHal, uint8_t session_id,
+				      uint32_t QosFlowID)
+{
+	QDF_STATUS lock_status = QDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	enum sme_qos_statustype status;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: QoS Release requested by client for Flow %d",
+		  __func__, __LINE__, QosFlowID);
+	lock_status = sme_acquire_global_lock(&pMac->sme);
+	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;
+	}
+	/* Call the internal function for QoS release, adding a
+	 * layer of abstraction
+	 */
+	status = sme_qos_internal_release_req(pMac, session_id, QosFlowID,
+					      false);
+	sme_release_global_lock(&pMac->sme);
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: QoS Release return status on Flow %d is %d",
+		  __func__, __LINE__, QosFlowID, status);
+	return status;
+}
+
+void qos_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	qdf_mem_zero(&pCommand->u.qosCmd, sizeof(tGenericQosCmd));
+	csr_release_command(pMac, pCommand);
+}
+
+/**
+ * sme_qos_msg_processor() - Processes QOS messages
+ * @mac_ctx: Pointer to the global MAC parameter structure.
+ * @msg_type: the type of msg passed by PE as defined in wni_api.h
+ * @msg: a pointer to a buffer that maps to various structures bases.
+ *
+ * sme_process_msg() calls this function for the messages that
+ * are handled by SME QoS module.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS sme_qos_msg_processor(tpAniSirGlobal mac_ctx,
+	uint16_t msg_type, void *msg)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tListElem *entry = NULL;
+	tSmeCmd *command;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL(" msg = %d for QoS"), msg_type);
+	/* switch on the msg type & make the state transition accordingly */
+	switch (msg_type) {
+	case eWNI_SME_ADDTS_RSP:
+		entry = csr_nonscan_active_ll_peek_head(mac_ctx,
+				LL_ACCESS_LOCK);
+		if (NULL == entry)
+			break;
+		command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+		if (eSmeCommandAddTs == command->command) {
+			status = sme_qos_process_add_ts_rsp(mac_ctx, msg);
+			if (csr_nonscan_active_ll_remove_entry(mac_ctx, entry,
+					LL_ACCESS_LOCK)) {
+				qos_release_command(mac_ctx, command);
+			}
+		}
+		break;
+	case eWNI_SME_DELTS_RSP:
+		entry = csr_nonscan_active_ll_peek_head(mac_ctx,
+				LL_ACCESS_LOCK);
+		if (NULL == entry)
+			break;
+		command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+		if (eSmeCommandDelTs == command->command) {
+			status = sme_qos_process_del_ts_rsp(mac_ctx, msg);
+			if (csr_nonscan_active_ll_remove_entry(mac_ctx, entry,
+					LL_ACCESS_LOCK)) {
+				qos_release_command(mac_ctx, command);
+			}
+		}
+		break;
+	case eWNI_SME_DELTS_IND:
+		status = sme_qos_process_del_ts_ind(mac_ctx, msg);
+		break;
+	case eWNI_SME_FT_AGGR_QOS_RSP:
+		status = sme_qos_process_aggr_qos_rsp(mac_ctx, msg);
+		break;
+	default:
+		/* err msg */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("unknown msg type = %d"),
+			msg_type);
+		break;
+	}
+	return status;
+}
+
+/**
+ * sme_qos_validate_params() - validate SME QOS parameters.
+ * @pMac: Pointer to the global MAC parameter structure.
+ * @pBssDesc: Pointer to the BSS Descriptor information passed down by
+ *            CSR to PE while issuing the Join request
+ *
+ * The SME QoS API exposed to CSR to validate AP
+ * capabilities regarding QoS support & any other QoS parameter validation.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_qos_validate_params(tpAniSirGlobal pMac,
+				   tSirBssDescription *pBssDesc)
+{
+	tDot11fBeaconIEs *pIes = NULL;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: validation for QAP & APSD", __func__, __LINE__);
+	do {
+		if (!QDF_IS_STATUS_SUCCESS(
+			csr_get_parsed_bss_description_ies(
+				pMac, pBssDesc,	&pIes))) {
+			/* err msg */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: csr_get_parsed_bss_description_ies() failed",
+				  __func__, __LINE__);
+			break;
+		}
+		/* check if the AP is QAP & it supports APSD */
+		if (!CSR_IS_QOS_BSS(pIes)) {
+			/* err msg */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: AP doesn't support QoS",
+				  __func__, __LINE__);
+
+			break;
+		}
+		if (!(pIes->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD) &&
+		    !(pIes->WMMInfoAp.uapsd)) {
+			/* err msg */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: AP doesn't support APSD",
+				  __func__, __LINE__);
+			break;
+		}
+		status = QDF_STATUS_SUCCESS;
+	} while (0);
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: validated with status = %d",
+		  __func__, __LINE__, status);
+	if (pIes)
+		qdf_mem_free(pIes);
+
+	return status;
+}
+
+/*
+ * 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.
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * ind - The event occurred of type sme_qos_csr_event_indType.
+ * pEvent_info - Information related to the event
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_qos_csr_event_ind(tpAniSirGlobal pMac,
+				 uint8_t sessionId,
+			sme_qos_csr_event_indType ind, void *pEvent_info)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: On Session %d Event %d received from CSR",
+		  __func__, __LINE__, sessionId, ind);
+	switch (ind) {
+	case SME_QOS_CSR_ASSOC_COMPLETE:
+		/* expecting assoc info in pEvent_info */
+		status = sme_qos_process_assoc_complete_ev(pMac, sessionId,
+							pEvent_info);
+		break;
+	case SME_QOS_CSR_REASSOC_REQ:
+		/* nothing expected in pEvent_info */
+		status = sme_qos_process_reassoc_req_ev(pMac, sessionId,
+							pEvent_info);
+		break;
+	case SME_QOS_CSR_REASSOC_COMPLETE:
+		/* expecting assoc info in pEvent_info */
+		status =
+			sme_qos_process_reassoc_success_ev(pMac, sessionId,
+							   pEvent_info);
+		break;
+	case SME_QOS_CSR_REASSOC_FAILURE:
+		/* nothing expected in pEvent_info */
+		status =
+			sme_qos_process_reassoc_failure_ev(pMac, sessionId,
+							   pEvent_info);
+		break;
+	case SME_QOS_CSR_DISCONNECT_REQ:
+	case SME_QOS_CSR_DISCONNECT_IND:
+		/* nothing expected in pEvent_info */
+		status = sme_qos_process_disconnect_ev(pMac, sessionId,
+							pEvent_info);
+		break;
+	case SME_QOS_CSR_JOIN_REQ:
+		/* nothing expected in pEvent_info */
+		status = sme_qos_process_join_req_ev(pMac, sessionId,
+							pEvent_info);
+		break;
+	case SME_QOS_CSR_HANDOFF_ASSOC_REQ:
+		/* nothing expected in pEvent_info */
+		status = sme_qos_process_handoff_assoc_req_ev(pMac, sessionId,
+							     pEvent_info);
+		break;
+	case SME_QOS_CSR_HANDOFF_COMPLETE:
+		/* nothing expected in pEvent_info */
+		status =
+			sme_qos_process_handoff_success_ev(pMac, sessionId,
+							   pEvent_info);
+		break;
+	case SME_QOS_CSR_PREAUTH_SUCCESS_IND:
+		status =
+			sme_qos_process_preauth_success_ind(pMac, sessionId,
+							    pEvent_info);
+		break;
+	case SME_QOS_CSR_SET_KEY_SUCCESS_IND:
+		status =
+			sme_qos_process_set_key_success_ind(pMac, sessionId,
+							    pEvent_info);
+		break;
+	default:
+		/* Err msg */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: On Session %d Unknown Event %d received from CSR",
+			  __func__, __LINE__, sessionId, ind);
+		break;
+	}
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: On Session %d processed Event %d with status %d",
+		  __func__, __LINE__, sessionId, ind, status);
+	return status;
+}
+
+/*
+ * sme_qos_get_acm_mask() - The QoS sub-module API to find out on which ACs
+ *  AP mandates Admission Control (ACM = 1)
+ *  (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored)
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * pSirBssDesc - The event occurred of type sme_qos_csr_event_indType.
+ * Return a bit mask indicating for which ACs AP has ACM set to 1
+ */
+uint8_t sme_qos_get_acm_mask(tpAniSirGlobal pMac, tSirBssDescription
+				*pSirBssDesc, tDot11fBeaconIEs *pIes)
+{
+	sme_QosEdcaAcType ac;
+	uint8_t acm_mask = 0;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked", __func__, __LINE__);
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		if (sme_qos_is_acm(pMac, pSirBssDesc, ac, pIes))
+			acm_mask = acm_mask | (1 << (SME_QOS_EDCA_AC_VO - ac));
+	}
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: mask is %d", __func__, __LINE__, acm_mask);
+	return acm_mask;
+}
+
+/* Internal function definitions */
+
+/**
+ *  sme_qos_internal_setup_req() - The SME QoS internal setup request handling
+ *                                 function.
+ *
+ *  @pMac: Pointer to the global MAC parameter structure.
+ *  @pQoSInfo: Pointer to struct sme_qos_wmmtspecinfo which contains the
+ *              WMM TSPEC related info as defined above, provided by HDD
+ *  @QoSCallback: The callback which is registered per flow while
+ *                requesting for QoS. Used for any notification for the
+ *                flow (i.e. setup success/failure/release) which needs to
+ *                be sent to HDD
+ *  @HDDcontext: A cookie passed by HDD to be used by SME during any QoS
+ *               notification (through the callabck) to HDD
+ *  @UPType: Useful only if HDD or any other upper layer module (BAP etc.)
+ *           looking for implicit QoS setup, in that
+ *           case, the pQoSInfo will be NULL & SME will know about the AC
+ *           (from the UP provided in this param) QoS is requested on
+ *  @QosFlowID: Identification per flow running on each AC generated by
+ *              SME. It is only meaningful if the QoS setup for the flow is
+ *              successful
+ *  @buffered_cmd: tells us if the cmd was a buffered one or fresh from
+ *                 client
+ *
+ *  If the request involves admission control on the requested AC, HDD needs to
+ *  provide the necessary Traffic Specification (TSPEC) parameters otherwise SME
+ *  is going to use the default params.
+ *
+ *  Return: QDF_STATUS_SUCCESS - Setup is successful.
+ *          Other status means Setup request failed
+ */
+static enum sme_qos_statustype sme_qos_internal_setup_req(tpAniSirGlobal pMac,
+					  uint8_t sessionId,
+					  struct sme_qos_wmmtspecinfo *pQoSInfo,
+					  sme_QosCallback QoSCallback,
+					  void *HDDcontext,
+					  enum sme_qos_wmmuptype UPType,
+					  uint32_t QosFlowID,
+					  bool buffered_cmd, bool hoRenewal)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	sme_QosEdcaAcType ac;
+	struct sme_qos_wmmtspecinfo Tspec_Info;
+	enum sme_qos_states new_state = SME_QOS_CLOSED;
+	struct sme_qos_flowinfoentry *pentry = NULL;
+	struct sme_qos_cmdinfo cmd;
+	enum sme_qos_statustype status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
+	uint8_t tmask = 0;
+	uint8_t new_tmask = 0;
+	struct sme_qos_searchinfo search_key;
+	QDF_STATUS hstatus;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d for flow %d",
+		  __func__, __LINE__, sessionId, QosFlowID);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	/* if caller sent an empty TSPEC, fill up with the default one */
+	if (!pQoSInfo) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN,
+			  "%s: %d: caller sent an empty QoS param list, using defaults",
+			  __func__, __LINE__);
+		/* find the AC with UPType passed in */
+		ac = sme_qos_up_to_ac(UPType);
+		if (SME_QOS_EDCA_AC_MAX == ac) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: invalid AC %d from UP %d",
+				  __func__, __LINE__, ac, UPType);
+
+			return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP;
+		}
+		Tspec_Info = sme_qos_cb.def_QoSInfo[ac];
+	} else {
+		/* find the AC */
+		ac = sme_qos_up_to_ac(pQoSInfo->ts_info.up);
+		if (SME_QOS_EDCA_AC_MAX == ac) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: invalid AC %d from UP %d",
+				  __func__, __LINE__, ac, pQoSInfo->ts_info.up);
+
+			return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP;
+		}
+		/* validate QoS params */
+		if (!sme_qos_validate_requested_params(pMac, pQoSInfo,
+							sessionId)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: invalid params", __func__, __LINE__);
+			return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP;
+		}
+		Tspec_Info = *pQoSInfo;
+	}
+	pACInfo = &pSession->ac_info[ac];
+	/* check to consider the following flowing scenario.
+	 * Addts request is pending on one AC, while APSD requested on another
+	 * which needs a reassoc. Will buffer a request if Addts is pending
+	 * on any AC, which will safegaurd the above scenario, & also won't
+	 * confuse PE with back to back Addts or Addts followed by Reassoc
+	 */
+	if (sme_qos_is_rsp_pending(sessionId, ac)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: buffering the setup request for flow %d in state %d since another request is pending",
+			  __func__, __LINE__, QosFlowID, pACInfo->curr_state);
+		/* we need to buffer the command */
+		cmd.command = SME_QOS_SETUP_REQ;
+		cmd.pMac = pMac;
+		cmd.sessionId = sessionId;
+		cmd.u.setupCmdInfo.HDDcontext = HDDcontext;
+		cmd.u.setupCmdInfo.QoSInfo = Tspec_Info;
+		cmd.u.setupCmdInfo.QoSCallback = QoSCallback;
+		cmd.u.setupCmdInfo.UPType = UPType;
+		cmd.u.setupCmdInfo.hoRenewal = hoRenewal;
+		cmd.u.setupCmdInfo.QosFlowID = QosFlowID;
+		hstatus = sme_qos_buffer_cmd(&cmd, buffered_cmd);
+		if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: couldn't buffer the setup request in state = %d",
+				  __func__, __LINE__, pACInfo->curr_state);
+			return SME_QOS_STATUS_SETUP_FAILURE_RSP;
+		}
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Buffered setup request for flow = %d",
+			  __func__, __LINE__, QosFlowID);
+		return SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
+	}
+	/* get into the state m/c to see if the request can be granted */
+	switch (pACInfo->curr_state) {
+	case SME_QOS_LINK_UP:
+		/* call the internal qos setup logic to decide on if the
+		 * request is NOP, or need reassoc for APSD and/or need to
+		 * send out ADDTS
+		 */
+		status = sme_qos_setup(pMac, sessionId, &Tspec_Info, ac);
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: On session %d with AC %d in state SME_QOS_LINK_UP sme_qos_setup returned with status %d",
+			  __func__, __LINE__, sessionId, ac, status);
+
+		if ((SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) ||
+		    (SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status)
+		    || (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY ==
+			status)) {
+			/* we received an expected "good" status */
+			/* create an entry in the flow list */
+			pentry = qdf_mem_malloc(sizeof(*pentry));
+			if (!pentry)
+				return SME_QOS_STATUS_SETUP_FAILURE_RSP;
+
+			pentry->ac_type = ac;
+			pentry->HDDcontext = HDDcontext;
+			pentry->QoSCallback = QoSCallback;
+			pentry->hoRenewal = hoRenewal;
+			pentry->QosFlowID = QosFlowID;
+			pentry->sessionId = sessionId;
+			/* since we are in state SME_QOS_LINK_UP this must be
+			 * the first TSPEC on this AC, so use index 0
+			 * (mask bit 1)
+			 */
+			pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0] =
+				Tspec_Info;
+			if (SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) {
+				if (pACInfo->tspec_mask_status &&
+				    !pACInfo->reassoc_pending) {
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_ERROR,
+						  "%s: %d: On session %d with AC %d in state SME_QOS_LINK_UP tspec_mask_status is %d but should not be set yet",
+						  __func__, __LINE__, sessionId,
+						  ac,
+						  pACInfo->tspec_mask_status);
+					qdf_mem_free(pentry);
+					return SME_QOS_STATUS_SETUP_FAILURE_RSP;
+				}
+				pACInfo->tspec_mask_status =
+					SME_QOS_TSPEC_MASK_BIT_1_SET;
+				if (!pACInfo->reassoc_pending)
+					/* we didn't request for reassoc, it
+					 * must be a tspec negotiation
+					 */
+					pACInfo->tspec_pending = 1;
+
+				pentry->reason = SME_QOS_REASON_SETUP;
+				new_state = SME_QOS_REQUESTED;
+			} else {
+				/* SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_
+				 * RSP or SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET
+				 * _ALREADY
+				 */
+				pentry->reason = SME_QOS_REASON_REQ_SUCCESS;
+				new_state = SME_QOS_QOS_ON;
+				pACInfo->tspec_mask_status =
+					SME_QOS_TSPEC_MASK_BIT_1_SET;
+				pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] =
+					Tspec_Info;
+				if (buffered_cmd && !pentry->hoRenewal) {
+					QoSCallback(MAC_HANDLE(pMac),
+						    HDDcontext,
+						    &pACInfo->
+						    curr_QoSInfo
+						    [SME_QOS_TSPEC_INDEX_0],
+						    status, pentry->QosFlowID);
+				}
+				pentry->hoRenewal = false;
+			}
+			pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0]++;
+
+			/* indicate on which index the flow entry belongs to &
+			 * add it to the Flow List at the end
+			 */
+			pentry->tspec_mask = pACInfo->tspec_mask_status;
+			pentry->QoSInfo = Tspec_Info;
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: Creating entry on session %d at %pK with flowID %d",
+				  __func__, __LINE__,
+				  sessionId, pentry, QosFlowID);
+			csr_ll_insert_tail(&sme_qos_cb.flow_list, &pentry->link,
+					   true);
+		} else {
+			/* unexpected status returned by sme_qos_setup() */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: On session %d unexpected status %d returned by sme_qos_setup",
+				  __func__, __LINE__, sessionId, status);
+			new_state = pACInfo->curr_state;
+			if (buffered_cmd && hoRenewal)
+				QoSCallback(MAC_HANDLE(pMac), HDDcontext,
+					    &pACInfo->
+					    curr_QoSInfo[SME_QOS_TSPEC_INDEX_0],
+					    SME_QOS_STATUS_RELEASE_QOS_LOST_IND,
+					    QosFlowID);
+		}
+		break;
+	case SME_QOS_HANDOFF:
+	case SME_QOS_REQUESTED:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Buffering setup request for flow %d in state = %d",
+			  __func__, __LINE__, QosFlowID, pACInfo->curr_state);
+		/* buffer cmd */
+		cmd.command = SME_QOS_SETUP_REQ;
+		cmd.pMac = pMac;
+		cmd.sessionId = sessionId;
+		cmd.u.setupCmdInfo.HDDcontext = HDDcontext;
+		cmd.u.setupCmdInfo.QoSInfo = Tspec_Info;
+		cmd.u.setupCmdInfo.QoSCallback = QoSCallback;
+		cmd.u.setupCmdInfo.UPType = UPType;
+		cmd.u.setupCmdInfo.hoRenewal = hoRenewal;
+		cmd.u.setupCmdInfo.QosFlowID = QosFlowID;
+		hstatus = sme_qos_buffer_cmd(&cmd, buffered_cmd);
+		if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: On session %d couldn't buffer the setup request for flow %d in state = %d",
+				  __func__, __LINE__,
+				  sessionId, QosFlowID, pACInfo->curr_state);
+			return SME_QOS_STATUS_SETUP_FAILURE_RSP;
+		}
+		status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
+		new_state = pACInfo->curr_state;
+		break;
+	case SME_QOS_QOS_ON:
+
+		/* check if multiple flows running on the ac */
+		if ((pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0] > 0) ||
+		    (pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] > 0)) {
+			/* do we need to care about the case where APSD
+			 * needed on ACM = 0 below?
+			 */
+			if (CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) ||
+			    sme_qos_is_acm(pMac, pSession->assocInfo.pBssDesc,
+					ac, NULL)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "%s: %d: tspec_mask_status = %d for AC = %d",
+					  __func__, __LINE__,
+					  pACInfo->tspec_mask_status, ac);
+				if (!pACInfo->tspec_mask_status) {
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_ERROR,
+						  "%s: %d: tspec_mask_status can't be 0 for ac: %d in state: %d",
+						__func__, __LINE__, ac,
+						  pACInfo->curr_state);
+					return status;
+				}
+				/* Flow aggregation */
+				if (((pACInfo->tspec_mask_status > 0) &&
+				     (pACInfo->tspec_mask_status <=
+				      SME_QOS_TSPEC_INDEX_MAX))) {
+					/* Either of upstream, downstream or
+					 * bidirectional flows are present If
+					 * either of new stream or current
+					 * stream is for bidirecional, aggregate
+					 * the new stream with the current
+					 * streams present and send out
+					 * aggregated Tspec.
+					 */
+					if ((Tspec_Info.ts_info.direction ==
+					     SME_QOS_WMM_TS_DIR_BOTH)
+					    || (pACInfo->
+						curr_QoSInfo[pACInfo->
+							     tspec_mask_status -
+							     1].ts_info.
+						direction ==
+						SME_QOS_WMM_TS_DIR_BOTH))
+						/* Aggregate the new stream with
+						 * the current stream(s).
+						 */
+						tmask = pACInfo->
+							tspec_mask_status;
+					/* None of new stream or current
+					 * (aggregated) streams are for
+					 * bidirectional. Check if the new
+					 * stream direction matches the current
+					 * stream direction.
+					 */
+					else if (pACInfo->
+						 curr_QoSInfo[pACInfo->
+							      tspec_mask_status
+							      -
+							      1].ts_info.
+						 direction ==
+						 Tspec_Info.ts_info.direction)
+						/* Aggregate the new stream with
+						 * the current stream(s).
+						 */
+						tmask =
+						pACInfo->tspec_mask_status;
+					/* New stream is in different
+					 * direction.
+					 */
+					else {
+						/* No Aggregation. Mark the
+						 * 2nd tpsec index also as
+						 * active.
+						 */
+						tmask =
+						SME_QOS_TSPEC_MASK_CLEAR;
+						new_tmask =
+						SME_QOS_TSPEC_MASK_BIT_1_2_SET
+							& ~pACInfo->
+							tspec_mask_status;
+						pACInfo->tspec_mask_status =
+						SME_QOS_TSPEC_MASK_BIT_1_2_SET;
+					}
+				} else if (SME_QOS_TSPEC_MASK_BIT_1_2_SET ==
+					   pACInfo->tspec_mask_status) {
+					/* Both uplink and downlink streams are
+					 * present. If new stream is
+					 * bidirectional, aggregate new stream
+					 * with all existing upstreams and down
+					 * streams. Send out new aggregated
+					 * tpsec.
+					 */
+					if (Tspec_Info.ts_info.direction ==
+					    SME_QOS_WMM_TS_DIR_BOTH) {
+						/* Only one tspec index (0) will
+						 * be in use after this
+						 * aggregation.
+						 */
+						tmask =
+						SME_QOS_TSPEC_MASK_BIT_1_2_SET;
+						pACInfo->tspec_mask_status =
+						SME_QOS_TSPEC_MASK_BIT_1_SET;
+					}
+					/* New stream is also uni-directional
+					 * Find out the tsepc index with which
+					 * it needs to be aggregated
+					 */
+					else if (pACInfo->
+						 curr_QoSInfo
+						 [SME_QOS_TSPEC_INDEX_0].
+						 ts_info.direction !=
+						 Tspec_Info.ts_info.direction)
+						/* Aggregate with 2nd tspec
+						 * index
+						 */
+						tmask =
+						SME_QOS_TSPEC_MASK_BIT_2_SET;
+					else
+						/* Aggregate with 1st tspec
+						 * index
+						 */
+						tmask =
+						SME_QOS_TSPEC_MASK_BIT_1_SET;
+				} else
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_DEBUG,
+						  "%s: %d: wrong tmask = %d",
+						  __func__, __LINE__,
+						  pACInfo->tspec_mask_status);
+			} else
+				/* ACM = 0 */
+				/* We won't be sending a TSPEC to the AP but
+				 * we still need to aggregate to calculate
+				 * trigger frame parameters
+				 */
+				tmask = SME_QOS_TSPEC_MASK_BIT_1_SET;
+
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: tmask = %d, new_tmask = %d in state = %d",
+				  __func__, __LINE__,
+				  tmask, new_tmask, pACInfo->curr_state);
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: tspec_mask_status = %d for AC = %d",
+				  __func__, __LINE__,
+				  pACInfo->tspec_mask_status, ac);
+			if (tmask) {
+				/* create the aggregate TSPEC */
+				if (tmask != SME_QOS_TSPEC_MASK_BIT_1_2_SET) {
+					hstatus =
+						sme_qos_aggregate_params(
+								&Tspec_Info,
+								&pACInfo->
+								curr_QoSInfo
+								[tmask - 1],
+								&pACInfo->
+							requested_QoSInfo
+								[tmask - 1]);
+				} else {
+					/* Aggregate the new bidirectional
+					 * stream with the existing upstreams
+					 * and downstreams in tspec indices 0
+					 * and 1.
+					 */
+					tmask = SME_QOS_TSPEC_MASK_BIT_1_SET;
+
+					hstatus = sme_qos_aggregate_params(
+							&Tspec_Info, &pACInfo->
+							curr_QoSInfo
+							[SME_QOS_TSPEC_INDEX_0],
+							&pACInfo->
+							requested_QoSInfo
+							[tmask - 1]);
+					if (hstatus == QDF_STATUS_SUCCESS) {
+						hstatus =
+							sme_qos_aggregate_params
+								(&pACInfo->
+								curr_QoSInfo
+							[SME_QOS_TSPEC_INDEX_1],
+								&pACInfo->
+						requested_QoSInfo[tmask - 1],
+								NULL);
+					}
+				}
+
+				if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+					/* err msg */
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_ERROR,
+						  "%s: %d: failed to aggregate params",
+						  __func__, __LINE__);
+					return SME_QOS_STATUS_SETUP_FAILURE_RSP;
+				}
+			} else {
+				if (!
+				    (new_tmask > 0
+				     && new_tmask <= SME_QOS_TSPEC_INDEX_MAX)) {
+					return SME_QOS_STATUS_SETUP_FAILURE_RSP;
+				}
+				tmask = new_tmask;
+				pACInfo->requested_QoSInfo[tmask - 1] =
+					Tspec_Info;
+			}
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: no flows running for ac = %d while in state = %d",
+				  __func__, __LINE__, ac, pACInfo->curr_state);
+			return status;
+		}
+		/* although aggregating, make sure to request on the correct
+		 * UP,TID,PSB and direction
+		 */
+		pACInfo->requested_QoSInfo[tmask - 1].ts_info.up =
+			Tspec_Info.ts_info.up;
+		pACInfo->requested_QoSInfo[tmask - 1].ts_info.tid =
+			Tspec_Info.ts_info.tid;
+		pACInfo->requested_QoSInfo[tmask - 1].ts_info.direction =
+			Tspec_Info.ts_info.direction;
+		pACInfo->requested_QoSInfo[tmask - 1].ts_info.psb =
+			Tspec_Info.ts_info.psb;
+		status =
+			sme_qos_setup(pMac, sessionId,
+				      &pACInfo->requested_QoSInfo[tmask - 1],
+					ac);
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON sme_qos_setup returned with status %d",
+			__func__,  __LINE__, sessionId, ac, status);
+		if ((SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) ||
+		    (SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status)
+		    || (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY ==
+			status)) {
+			/* we received an expected "good" status */
+			/* create an entry in the flow list */
+			pentry = qdf_mem_malloc(sizeof(*pentry));
+			if (!pentry)
+				return SME_QOS_STATUS_SETUP_FAILURE_RSP;
+
+			pentry->ac_type = ac;
+			pentry->HDDcontext = HDDcontext;
+			pentry->QoSCallback = QoSCallback;
+			pentry->hoRenewal = hoRenewal;
+			pentry->QosFlowID = QosFlowID;
+			pentry->sessionId = sessionId;
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: Creating flow %d",
+				  __func__, __LINE__, QosFlowID);
+			if ((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP ==
+			     status)
+			    || (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY ==
+				status)) {
+				new_state = pACInfo->curr_state;
+				pentry->reason = SME_QOS_REASON_REQ_SUCCESS;
+				pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] =
+					pACInfo->
+				requested_QoSInfo[SME_QOS_TSPEC_INDEX_0];
+				if (buffered_cmd && !pentry->hoRenewal) {
+					QoSCallback(MAC_HANDLE(pMac),
+						    HDDcontext,
+						    &pACInfo->
+						    curr_QoSInfo
+						    [SME_QOS_TSPEC_INDEX_0],
+						    status, pentry->QosFlowID);
+				}
+				if (
+				SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY
+								== status) {
+					/* if we are not in handoff, then notify
+					 * all flows on this AC that the
+					 * aggregate TSPEC may have changed
+					 */
+					if (!pentry->hoRenewal) {
+						qdf_mem_zero(&search_key,
+							     sizeof
+						(struct sme_qos_searchinfo));
+						search_key.key.ac_type = ac;
+						search_key.index =
+						SME_QOS_SEARCH_KEY_INDEX_2;
+						search_key.sessionId =
+							sessionId;
+						hstatus =
+						sme_qos_find_all_in_flow_list
+							(pMac, search_key,
+							sme_qos_setup_fnp);
+						if (!QDF_IS_STATUS_SUCCESS
+							    (hstatus)) {
+							QDF_TRACE
+							(QDF_MODULE_ID_SME,
+							QDF_TRACE_LEVEL_ERROR,
+								"%s: %d: couldn't notify other entries on this AC =%d",
+							__func__, __LINE__,
+								ac);
+						}
+					}
+				}
+				pentry->hoRenewal = false;
+			} else {
+				/* SME_QOS_STATUS_SETUP_REQ_PENDING_RSP */
+				new_state = SME_QOS_REQUESTED;
+				pentry->reason = SME_QOS_REASON_SETUP;
+				/* Need this info when addts comes back from PE
+				 * to know on which index of the AC the request
+				 * was from
+				 */
+				pACInfo->tspec_pending = tmask;
+			}
+			pACInfo->num_flows[tmask - 1]++;
+			/* indicate on which index the flow entry belongs to &
+			 * add it to the Flow List at the end
+			 */
+			pentry->tspec_mask = tmask;
+			pentry->QoSInfo = Tspec_Info;
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: On session %d creating entry at %pK with flowID %d",
+				  __func__, __LINE__,
+				  sessionId, pentry, QosFlowID);
+			csr_ll_insert_tail(&sme_qos_cb.flow_list, &pentry->link,
+					   true);
+		} else {
+			/* unexpected status returned by sme_qos_setup() */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: On session %d unexpected status %d returned by sme_qos_setup",
+				  __func__, __LINE__, sessionId, status);
+			new_state = pACInfo->curr_state;
+		}
+		break;
+	case SME_QOS_CLOSED:
+	case SME_QOS_INIT:
+	default:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: setup requested in unexpected state = %d",
+			  __func__, __LINE__, pACInfo->curr_state);
+		new_state = pACInfo->curr_state;
+	}
+	/* If current state is same as previous no need for transistion,
+	 * if we are doing reassoc & we are already in handoff state, no need to
+	 * move to requested state. But make sure to set the previous state as
+	 * requested state
+	 */
+	if ((new_state != pACInfo->curr_state) &&
+	    (!(pACInfo->reassoc_pending &&
+	       (SME_QOS_HANDOFF == pACInfo->curr_state))))
+		sme_qos_state_transition(sessionId, ac, new_state);
+
+	if (pACInfo->reassoc_pending &&
+	    (SME_QOS_HANDOFF == pACInfo->curr_state))
+		pACInfo->prev_state = SME_QOS_REQUESTED;
+
+	if ((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) ||
+	    (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status))
+		(void)sme_qos_process_buffered_cmd(sessionId);
+
+	return status;
+}
+
+/**
+ * sme_qos_internal_modify_req() - The SME QoS internal function to request
+ *  for modification of certain QoS params on a flow running on a particular AC.
+ * @pMac: Pointer to the global MAC parameter structure.
+ * @pQoSInfo: Pointer to struct sme_qos_wmmtspecinfo which contains the
+ *            WMM TSPEC related info as defined above, provided by HDD
+ * @QosFlowID: Identification per flow running on each AC generated by
+ *             SME. It is only meaningful if the QoS setup for the flow has
+ *             been successful already
+ *
+ * If the request involves admission control on the requested AC, HDD needs to
+ * provide the necessary Traffic Specification (TSPEC) parameters & SME might
+ * start the renegotiation process through ADDTS.
+ *
+ * Return: SME_QOS_STATUS_SETUP_SUCCESS_RSP - Modification is successful.
+ *         Other status means request failed
+ */
+static enum sme_qos_statustype sme_qos_internal_modify_req(tpAniSirGlobal pMac,
+					  struct sme_qos_wmmtspecinfo *pQoSInfo,
+					  uint32_t QosFlowID,
+					  bool buffered_cmd)
+{
+	tListElem *pEntry = NULL;
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	struct sme_qos_flowinfoentry *pNewEntry = NULL;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	sme_QosEdcaAcType ac;
+	enum sme_qos_states new_state = SME_QOS_CLOSED;
+	enum sme_qos_statustype status =
+		SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
+	struct sme_qos_wmmtspecinfo Aggr_Tspec_Info;
+	struct sme_qos_searchinfo search_key;
+	struct sme_qos_cmdinfo cmd;
+	uint8_t sessionId;
+	QDF_STATUS hstatus;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked for flow %d", __func__, __LINE__, QosFlowID);
+
+	qdf_mem_zero(&search_key, sizeof(struct sme_qos_searchinfo));
+	/* set the key type & the key to be searched in the Flow List */
+	search_key.key.QosFlowID = QosFlowID;
+	search_key.index = SME_QOS_SEARCH_KEY_INDEX_1;
+	search_key.sessionId = SME_QOS_SEARCH_SESSION_ID_ANY;
+	/* go through the link list to find out the details on the flow */
+	pEntry = sme_qos_find_in_flow_list(search_key);
+	if (!pEntry) {
+		/* Err msg */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: no match found for flowID = %d",
+			  __func__, __LINE__, QosFlowID);
+		return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP;
+	}
+	/* find the AC */
+	flow_info = GET_BASE_ADDR(pEntry, struct sme_qos_flowinfoentry, link);
+	ac = flow_info->ac_type;
+
+	sessionId = flow_info->sessionId;
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	pACInfo = &pSession->ac_info[ac];
+
+	/* validate QoS params */
+	if (!sme_qos_validate_requested_params(pMac, pQoSInfo, sessionId)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: invalid params", __func__, __LINE__);
+		return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP;
+	}
+	/* For modify, make sure that direction, TID and UP are not
+	 * being altered
+	 */
+	if ((pQoSInfo->ts_info.direction !=
+	     flow_info->QoSInfo.ts_info.direction)
+	    || (pQoSInfo->ts_info.up != flow_info->QoSInfo.ts_info.up)
+	    || (pQoSInfo->ts_info.tid != flow_info->QoSInfo.ts_info.tid)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Modification of direction/tid/up is not allowed",
+			  __func__, __LINE__);
+
+		return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP;
+	}
+
+	/* should not be same as previous ioctl parameters */
+	if ((pQoSInfo->nominal_msdu_size ==
+		flow_info->QoSInfo.nominal_msdu_size) &&
+	    (pQoSInfo->maximum_msdu_size ==
+		flow_info->QoSInfo.maximum_msdu_size) &&
+	    (pQoSInfo->min_data_rate ==
+		flow_info->QoSInfo.min_data_rate) &&
+	    (pQoSInfo->mean_data_rate ==
+		flow_info->QoSInfo.mean_data_rate) &&
+	    (pQoSInfo->peak_data_rate ==
+		flow_info->QoSInfo.peak_data_rate) &&
+	    (pQoSInfo->min_service_interval ==
+		flow_info->QoSInfo.min_service_interval) &&
+	    (pQoSInfo->max_service_interval ==
+		flow_info->QoSInfo.max_service_interval) &&
+	    (pQoSInfo->inactivity_interval ==
+		flow_info->QoSInfo.inactivity_interval) &&
+	    (pQoSInfo->suspension_interval ==
+		flow_info->QoSInfo.suspension_interval) &&
+	    (pQoSInfo->surplus_bw_allowance ==
+		flow_info->QoSInfo.surplus_bw_allowance)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: %d: the addts parameters are same as last request, dropping the current request",
+			__func__, __LINE__);
+
+		return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
+	}
+
+	/* check to consider the following flowing scenario.
+	 * Addts request is pending on one AC, while APSD requested on another
+	 * which needs a reassoc. Will buffer a request if Addts is pending on
+	 * any AC, which will safegaurd the above scenario, & also won't
+	 * confuse PE with back to back Addts or Addts followed by Reassoc
+	 */
+	if (sme_qos_is_rsp_pending(sessionId, ac)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: buffering the modify request for flow %d in state %d since another request is pending",
+			  __func__, __LINE__, QosFlowID, pACInfo->curr_state);
+		/* we need to buffer the command */
+		cmd.command = SME_QOS_MODIFY_REQ;
+		cmd.pMac = pMac;
+		cmd.sessionId = sessionId;
+		cmd.u.modifyCmdInfo.QosFlowID = QosFlowID;
+		cmd.u.modifyCmdInfo.QoSInfo = *pQoSInfo;
+		hstatus = sme_qos_buffer_cmd(&cmd, buffered_cmd);
+		if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: couldn't buffer the modify request in state = %d",
+				  __func__, __LINE__, pACInfo->curr_state);
+			return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
+		}
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Buffered modify request for flow = %d",
+			  __func__, __LINE__, QosFlowID);
+		return SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
+	}
+	/* get into the stat m/c to see if the request can be granted */
+	switch (pACInfo->curr_state) {
+	case SME_QOS_QOS_ON:
+		/* save the new params adding a new (duplicate) entry in the
+		 * Flow List Once we have decided on OTA exchange needed or
+		 * not we can delete the original one from the List
+		 */
+		pNewEntry = qdf_mem_malloc(sizeof(*pNewEntry));
+		if (!pNewEntry)
+			return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
+
+		pNewEntry->ac_type = ac;
+		pNewEntry->sessionId = sessionId;
+		pNewEntry->HDDcontext = flow_info->HDDcontext;
+		pNewEntry->QoSCallback = flow_info->QoSCallback;
+		pNewEntry->QosFlowID = flow_info->QosFlowID;
+		pNewEntry->reason = SME_QOS_REASON_MODIFY_PENDING;
+		/* since it is a modify request, use the same index on which
+		 * the flow entry originally was running & add it to the Flow
+		 * List at the end
+		 */
+		pNewEntry->tspec_mask = flow_info->tspec_mask;
+		pNewEntry->QoSInfo = *pQoSInfo;
+		/* update the entry from Flow List which needed to be
+		 * modified
+		 */
+		flow_info->reason = SME_QOS_REASON_MODIFY;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: On session %d creating modified entry at %pK with flowID %d",
+			  __func__, __LINE__,
+			  sessionId, pNewEntry, pNewEntry->QosFlowID);
+		/* add the new entry under construction to the Flow List */
+		csr_ll_insert_tail(&sme_qos_cb.flow_list, &pNewEntry->link,
+				   true);
+		/* update TSPEC with the new param set */
+		hstatus = sme_qos_update_params(sessionId,
+						ac, pNewEntry->tspec_mask,
+						&Aggr_Tspec_Info);
+		if (QDF_IS_STATUS_SUCCESS(hstatus)) {
+			pACInfo->requested_QoSInfo[pNewEntry->tspec_mask - 1] =
+				Aggr_Tspec_Info;
+			/* if ACM, send out a new ADDTS */
+			status = sme_qos_setup(pMac, sessionId,
+					       &pACInfo->
+					       requested_QoSInfo[pNewEntry->
+								tspec_mask - 1],
+					       ac);
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON sme_qos_setup returned with status %d",
+				  __func__, __LINE__, sessionId, ac, status);
+
+			if (SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) {
+				new_state = SME_QOS_REQUESTED;
+				status =
+					SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
+				pACInfo->tspec_pending = pNewEntry->tspec_mask;
+			} else
+			if ((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP
+			     == status)
+			    ||
+			    (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY
+			     == status)) {
+				new_state = SME_QOS_QOS_ON;
+
+				qdf_mem_zero(&search_key,
+					     sizeof(struct sme_qos_searchinfo));
+				/* delete the original entry in FLOW list which
+				 * got modified
+				 */
+				search_key.key.ac_type = ac;
+				search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
+				search_key.sessionId = sessionId;
+				hstatus = sme_qos_find_all_in_flow_list(pMac,
+							search_key,
+							sme_qos_modify_fnp);
+				if (!QDF_IS_STATUS_SUCCESS(hstatus))
+					status =
+					SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
+
+				if (SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP !=
+				    status) {
+					pACInfo->curr_QoSInfo[pNewEntry->
+							      tspec_mask - 1] =
+						pACInfo->
+						requested_QoSInfo[pNewEntry->
+								tspec_mask - 1];
+					if (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status) {
+						status =
+							SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY;
+						qdf_mem_zero(&search_key,
+							     sizeof
+						(struct sme_qos_searchinfo));
+						search_key.key.ac_type = ac;
+						search_key.index =
+						SME_QOS_SEARCH_KEY_INDEX_2;
+						search_key.sessionId =
+							sessionId;
+						hstatus =
+						sme_qos_find_all_in_flow_list
+							(pMac, search_key,
+								sme_qos_modification_notify_fnp);
+						if (!QDF_IS_STATUS_SUCCESS
+							    (hstatus)) {
+							QDF_TRACE
+							(QDF_MODULE_ID_SME,
+							QDF_TRACE_LEVEL_ERROR,
+								"%s: %d: couldn't notify other entries on this AC =%d",
+							__func__, __LINE__,
+								ac);
+						}
+					} else
+					if
+					(SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP
+					 == status)
+						status =
+							SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP;
+				}
+				if (buffered_cmd) {
+					flow_info->QoSCallback(MAC_HANDLE(pMac),
+							       flow_info->
+							       HDDcontext,
+							       &pACInfo->
+							       curr_QoSInfo
+							       [pNewEntry->
+								tspec_mask - 1],
+							       status,
+							       flow_info->
+							       QosFlowID);
+				}
+
+			} else {
+				/* unexpected status returned by
+				 * sme_qos_setup()
+				 */
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "%s: %d: On session %d unexpected status %d returned by sme_qos_setup",
+					__func__,  __LINE__, sessionId, status);
+				new_state = SME_QOS_QOS_ON;
+			}
+		} else {
+			/* err msg */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: sme_qos_update_params() failed",
+				  __func__, __LINE__);
+			new_state = SME_QOS_LINK_UP;
+		}
+		/* if we are doing reassoc & we are already in handoff state,
+		 * no need to move to requested state. But make sure to set
+		 * the previous state as requested state
+		 */
+		if (!(pACInfo->reassoc_pending &&
+		      (SME_QOS_HANDOFF == pACInfo->curr_state)))
+			sme_qos_state_transition(sessionId, ac, new_state);
+		else
+			pACInfo->prev_state = SME_QOS_REQUESTED;
+		break;
+	case SME_QOS_HANDOFF:
+	case SME_QOS_REQUESTED:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Buffering modify request for flow %d in state = %d",
+			  __func__, __LINE__, QosFlowID, pACInfo->curr_state);
+		/* buffer cmd */
+		cmd.command = SME_QOS_MODIFY_REQ;
+		cmd.pMac = pMac;
+		cmd.sessionId = sessionId;
+		cmd.u.modifyCmdInfo.QosFlowID = QosFlowID;
+		cmd.u.modifyCmdInfo.QoSInfo = *pQoSInfo;
+		hstatus = sme_qos_buffer_cmd(&cmd, buffered_cmd);
+		if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: couldn't buffer the modify request in state = %d",
+				  __func__, __LINE__, pACInfo->curr_state);
+			return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
+		}
+		status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
+		break;
+	case SME_QOS_CLOSED:
+	case SME_QOS_INIT:
+	case SME_QOS_LINK_UP:
+	default:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: modify requested in unexpected state = %d",
+			  __func__, __LINE__, pACInfo->curr_state);
+		break;
+	}
+	if ((SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status)
+	    || (SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY ==
+		status))
+		(void)sme_qos_process_buffered_cmd(sessionId);
+
+	return status;
+}
+
+/**
+ * sme_qos_internal_release_req() - release QOS flow on a particular AC
+ * @pMac: Pointer to the global MAC parameter structure.
+ * @sessionId: sessionId returned by sme_open_session.
+ * @QosFlowID: Identification per flow running on each AC generated by SME
+ *             It is only meaningful if the QoS setup for the flow is successful
+ *
+ * The SME QoS internal function to request
+ * for releasing a QoS flow running on a particular AC.
+
+ * Return: QDF_STATUS_SUCCESS - Release is successful.
+ */
+static enum sme_qos_statustype sme_qos_internal_release_req(tpAniSirGlobal pMac,
+					       uint8_t sessionId,
+					       uint32_t QosFlowID,
+					       bool buffered_cmd)
+{
+	tListElem *pEntry = NULL;
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	struct sme_qos_flowinfoentry *pDeletedFlow = NULL;
+	sme_QosEdcaAcType ac;
+	enum sme_qos_states new_state = SME_QOS_CLOSED;
+	enum sme_qos_statustype status = SME_QOS_STATUS_RELEASE_FAILURE_RSP;
+	struct sme_qos_wmmtspecinfo Aggr_Tspec_Info;
+	struct sme_qos_searchinfo search_key;
+	struct sme_qos_cmdinfo cmd;
+	tCsrRoamModifyProfileFields modifyProfileFields;
+	bool deltsIssued = false;
+	QDF_STATUS hstatus;
+	bool biDirectionalFlowsPresent = false;
+	bool uplinkFlowsPresent = false;
+	bool downlinkFlowsPresent = false;
+	tListElem *pResult = NULL;
+	mac_handle_t mac_hdl = MAC_HANDLE(pMac);
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked for flow %d", __func__, __LINE__, QosFlowID);
+
+	qdf_mem_zero(&search_key, sizeof(struct sme_qos_searchinfo));
+	/* set the key type & the key to be searched in the Flow List */
+	search_key.key.QosFlowID = QosFlowID;
+	search_key.index = SME_QOS_SEARCH_KEY_INDEX_1;
+	search_key.sessionId = SME_QOS_SEARCH_SESSION_ID_ANY;
+	/* go through the link list to find out the details on the flow */
+	pEntry = sme_qos_find_in_flow_list(search_key);
+
+	if (!pEntry) {
+		/* Err msg */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: no match found for flowID = %d",
+			  __func__, __LINE__, QosFlowID);
+
+		pSession = &sme_qos_cb.sessionInfo[sessionId];
+		if (!buffered_cmd &&
+		    !csr_ll_is_list_empty(&pSession->bufferedCommandList,
+					  false)) {
+			cmd.command = SME_QOS_RELEASE_REQ;
+			cmd.pMac = pMac;
+			cmd.sessionId = sessionId;
+			cmd.u.releaseCmdInfo.QosFlowID = QosFlowID;
+			hstatus = sme_qos_buffer_cmd(&cmd, buffered_cmd);
+			if (QDF_IS_STATUS_SUCCESS(hstatus)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "%s:%d: Buffered release request for flow = %d",
+					  __func__, __LINE__, QosFlowID);
+			}
+		}
+		return SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP;
+	}
+	/* find the AC */
+	flow_info = GET_BASE_ADDR(pEntry, struct sme_qos_flowinfoentry, link);
+	ac = flow_info->ac_type;
+	sessionId = flow_info->sessionId;
+
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: %d: Session Id: %d is invalid",
+			__func__, __LINE__, sessionId);
+		return status;
+	}
+
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	pACInfo = &pSession->ac_info[ac];
+	/* check to consider the following flowing scenario.
+	 * Addts request is pending on one AC, while APSD requested on another
+	 * which needs a reassoc. Will buffer a request if Addts is pending on
+	 * any AC, which will safegaurd the above scenario, & also won't
+	 * confuse PE with back to back Addts or Addts followed by Reassoc
+	 */
+	if (sme_qos_is_rsp_pending(sessionId, ac)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: buffering the release request for flow %d in state %d since another request is pending",
+			  __func__, __LINE__, QosFlowID, pACInfo->curr_state);
+		/* we need to buffer the command */
+		cmd.command = SME_QOS_RELEASE_REQ;
+		cmd.pMac = pMac;
+		cmd.sessionId = sessionId;
+		cmd.u.releaseCmdInfo.QosFlowID = QosFlowID;
+		hstatus = sme_qos_buffer_cmd(&cmd, buffered_cmd);
+		if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: couldn't buffer the release request in state = %d",
+				  __func__, __LINE__, pACInfo->curr_state);
+			return SME_QOS_STATUS_RELEASE_FAILURE_RSP;
+		}
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Buffered release request for flow = %d",
+			  __func__, __LINE__, QosFlowID);
+		return SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP;
+	}
+	/* get into the stat m/c to see if the request can be granted */
+	switch (pACInfo->curr_state) {
+	case SME_QOS_QOS_ON:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: tspec_mask_status = %d for AC = %d with entry tspec_mask = %d",
+			  __func__, __LINE__,
+			  pACInfo->tspec_mask_status, ac,
+			  flow_info->tspec_mask);
+
+		/* check if multiple flows running on the ac */
+		if (pACInfo->num_flows[flow_info->tspec_mask - 1] > 1) {
+			/* don't want to include the flow in the new TSPEC on
+			 * which release is requested
+			 */
+			flow_info->reason = SME_QOS_REASON_RELEASE;
+
+			/* Check if the flow being released is for bi-diretional
+			 * Following flows may present in the system.
+			 * a) bi-directional flows
+			 * b) uplink flows
+			 * c) downlink flows.
+			 * If the flow being released is for bidirectional,
+			 * splitting of existing streams into two tspec indices
+			 * is required in case ff (b), (c) are present and not
+			 * (a). In case if split occurs, all upstreams are
+			 * aggregated into tspec index 0, downstreams are
+			 * aggregaed into tspec index 1 and two tspec requests
+			 * for (aggregated) upstream(s) followed by (aggregated)
+			 * downstream(s) is sent to AP.
+			 */
+			if (flow_info->QoSInfo.ts_info.direction ==
+			    SME_QOS_WMM_TS_DIR_BOTH) {
+				qdf_mem_zero(&search_key,
+					     sizeof(struct sme_qos_searchinfo));
+				/* set the key type & the key to be searched in
+				 * the Flow List
+				 */
+				search_key.key.ac_type = ac;
+				search_key.index = SME_QOS_SEARCH_KEY_INDEX_4;
+				search_key.sessionId = sessionId;
+				search_key.direction = SME_QOS_WMM_TS_DIR_BOTH;
+				pResult = sme_qos_find_in_flow_list(search_key);
+				if (pResult)
+					biDirectionalFlowsPresent = true;
+
+				if (!biDirectionalFlowsPresent) {
+					/* The only existing bidirectional flow
+					 * is being released
+					 */
+
+					/* Check if uplink flows exist */
+					search_key.direction =
+						SME_QOS_WMM_TS_DIR_UPLINK;
+					pResult =
+					sme_qos_find_in_flow_list(search_key);
+					if (pResult)
+						uplinkFlowsPresent = true;
+
+					/* Check if downlink flows exist */
+					search_key.direction =
+						SME_QOS_WMM_TS_DIR_DOWNLINK;
+					pResult =
+					sme_qos_find_in_flow_list(search_key);
+					if (pResult)
+						downlinkFlowsPresent = true;
+
+					if (uplinkFlowsPresent
+					    && downlinkFlowsPresent) {
+						/* Need to split the uni-
+						 * directional flows into
+						 * SME_QOS_TSPEC_INDEX_0 and
+						 * SME_QOS_TSPEC_INDEX_1
+						 */
+
+						qdf_mem_zero(&search_key,
+							     sizeof
+						(struct sme_qos_searchinfo));
+						/* Mark all downstream flows as
+						 * using tspec index 1
+						 */
+						search_key.key.ac_type = ac;
+						search_key.index =
+						SME_QOS_SEARCH_KEY_INDEX_4;
+						search_key.sessionId =
+							sessionId;
+						search_key.direction =
+						SME_QOS_WMM_TS_DIR_DOWNLINK;
+						sme_qos_update_tspec_mask
+							(sessionId, search_key,
+						SME_QOS_TSPEC_MASK_BIT_2_SET);
+
+						/* Aggregate all downstream
+						 * flows
+						 */
+						hstatus =
+							sme_qos_update_params
+								(sessionId, ac,
+						SME_QOS_TSPEC_MASK_BIT_2_SET,
+							&Aggr_Tspec_Info);
+
+						QDF_TRACE(QDF_MODULE_ID_SME,
+							  QDF_TRACE_LEVEL_ERROR,
+							  "%s: %d: On session %d buffering the AddTS request for AC %d in state %d as Addts is pending on other Tspec index of this AC",
+							  __func__, __LINE__,
+							  sessionId, ac,
+							  pACInfo->curr_state);
+
+						/* Buffer the (aggregated) tspec
+						 * request for downstream flows.
+						 * Please note that the
+						 * (aggregated) tspec for
+						 * upstream flows is sent out by
+						 * the susequent logic.
+						 */
+						cmd.command =
+							SME_QOS_RESEND_REQ;
+						cmd.pMac = pMac;
+						cmd.sessionId = sessionId;
+						cmd.u.resendCmdInfo.ac = ac;
+						cmd.u.resendCmdInfo.tspecMask =
+						SME_QOS_TSPEC_MASK_BIT_2_SET;
+						cmd.u.resendCmdInfo.QoSInfo =
+							Aggr_Tspec_Info;
+						pACInfo->
+						requested_QoSInfo
+						[SME_QOS_TSPEC_MASK_BIT_2_SET
+						 - 1] = Aggr_Tspec_Info;
+						if (!QDF_IS_STATUS_SUCCESS
+							    (sme_qos_buffer_cmd
+								    (&cmd,
+								false))) {
+							QDF_TRACE
+							(QDF_MODULE_ID_SME,
+							QDF_TRACE_LEVEL_ERROR,
+								"%s: %d: On session %d unable to buffer the AddTS request for AC %d TSPEC %d in state %d",
+							__func__, __LINE__,
+								sessionId, ac,
+								SME_QOS_TSPEC_MASK_BIT_2_SET,
+								pACInfo->
+								curr_state);
+
+							return
+								SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
+						}
+						pACInfo->tspec_mask_status =
+						SME_QOS_TSPEC_MASK_BIT_1_2_SET;
+
+					}
+				}
+			}
+
+			/* In case of splitting of existing streams,
+			 * tspec_mask will be pointing to tspec index 0 and
+			 * aggregated tspec for upstream(s) is sent out here.
+			 */
+			hstatus = sme_qos_update_params(sessionId,
+						ac, flow_info->tspec_mask,
+							&Aggr_Tspec_Info);
+			if (QDF_IS_STATUS_SUCCESS(hstatus)) {
+				pACInfo->requested_QoSInfo[flow_info->
+							   tspec_mask - 1] =
+					Aggr_Tspec_Info;
+				/* if ACM, send out a new ADDTS */
+				status = sme_qos_setup(pMac, sessionId,
+						       &pACInfo->
+						       requested_QoSInfo
+						       [flow_info->tspec_mask -
+							1], ac);
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON sme_qos_setup returned with status %d",
+					  __func__, __LINE__, sessionId, ac,
+					  status);
+
+				if (SME_QOS_STATUS_SETUP_REQ_PENDING_RSP ==
+				    status) {
+					new_state = SME_QOS_REQUESTED;
+					status =
+					SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP;
+					pACInfo->tspec_pending =
+						flow_info->tspec_mask;
+				} else
+				if ((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) {
+					new_state = SME_QOS_QOS_ON;
+					pACInfo->num_flows[flow_info->
+							   tspec_mask - 1]--;
+					pACInfo->curr_QoSInfo[flow_info->
+							      tspec_mask - 1] =
+						pACInfo->
+						requested_QoSInfo[flow_info->
+								tspec_mask - 1];
+					/* delete the entry from Flow List */
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_DEBUG,
+						  "%s: %d: Deleting entry at %pK with flowID %d",
+						  __func__, __LINE__, flow_info,
+						  QosFlowID);
+					csr_ll_remove_entry(&sme_qos_cb.
+						flow_list, pEntry, true);
+					pDeletedFlow = flow_info;
+					if (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status) {
+						qdf_mem_zero(&search_key,
+							     sizeof
+						(struct sme_qos_searchinfo));
+						search_key.key.ac_type = ac;
+						search_key.index =
+						SME_QOS_SEARCH_KEY_INDEX_2;
+						search_key.sessionId =
+							sessionId;
+						hstatus =
+						sme_qos_find_all_in_flow_list
+							(pMac, search_key,
+							sme_qos_setup_fnp);
+						if (!QDF_IS_STATUS_SUCCESS
+							    (hstatus)) {
+							QDF_TRACE
+							(QDF_MODULE_ID_SME,
+							QDF_TRACE_LEVEL_ERROR,
+								"%s: %d: couldn't notify other entries on this AC =%d",
+							__func__, __LINE__,
+								ac);
+						}
+					}
+					status =
+					SME_QOS_STATUS_RELEASE_SUCCESS_RSP;
+					if (buffered_cmd) {
+						flow_info->QoSCallback(MAC_HANDLE(pMac),
+								     flow_info->
+								     HDDcontext,
+								     &pACInfo->
+								    curr_QoSInfo
+								    [flow_info->
+								tspec_mask - 1],
+								       status,
+								     flow_info->
+								     QosFlowID);
+					}
+				} else {
+					/* unexpected status returned by
+					 * sme_qos_setup()
+					 */
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_ERROR,
+						  "%s: %d: On session %d unexpected status %d returned by sme_qos_setup",
+						  __func__, __LINE__, sessionId,
+						  status);
+					new_state = SME_QOS_LINK_UP;
+					pACInfo->num_flows[flow_info->
+							   tspec_mask - 1]--;
+					pACInfo->curr_QoSInfo[flow_info->
+							      tspec_mask - 1] =
+						pACInfo->
+						requested_QoSInfo[flow_info->
+								tspec_mask - 1];
+					/* delete the entry from Flow List */
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_DEBUG,
+						  "%s: %d: On session %d deleting entry at %pK with flowID %d",
+						__func__, __LINE__, sessionId,
+						  flow_info, QosFlowID);
+					csr_ll_remove_entry(&sme_qos_cb.
+								flow_list,
+							    pEntry, true);
+					pDeletedFlow = flow_info;
+					if (buffered_cmd) {
+						flow_info->QoSCallback(MAC_HANDLE(pMac),
+								     flow_info->
+								     HDDcontext,
+								      &pACInfo->
+								    curr_QoSInfo
+								    [flow_info->
+								tspec_mask - 1],
+								       status,
+								     flow_info->
+								     QosFlowID);
+					}
+				}
+			} else {
+				/* err msg */
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "%s: %d: sme_qos_update_params() failed",
+					  __func__, __LINE__);
+				new_state = SME_QOS_LINK_UP;
+				if (buffered_cmd) {
+					flow_info->QoSCallback(MAC_HANDLE(pMac),
+							       flow_info->
+							       HDDcontext,
+							       &pACInfo->
+							       curr_QoSInfo
+							       [flow_info->
+								tspec_mask - 1],
+							       status,
+							       flow_info->
+							       QosFlowID);
+				}
+			}
+		} else {
+			/* this is the only flow aggregated in this TSPEC */
+			status = SME_QOS_STATUS_RELEASE_SUCCESS_RSP;
+			/* check if delts needs to be sent */
+			if (CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) ||
+			    sme_qos_is_acm(pMac, pSession->assocInfo.pBssDesc,
+						ac, NULL)) {
+				/* check if other TSPEC for this AC is also
+				 * in use
+				 */
+				if (SME_QOS_TSPEC_MASK_BIT_1_2_SET !=
+				    pACInfo->tspec_mask_status) {
+					/* this is the only TSPEC active on this
+					 * AC so indicate that we no longer
+					 * require APSD
+					 */
+					pSession->apsdMask &=
+					~(1 << (SME_QOS_EDCA_AC_VO - ac));
+					/* Also update modifyProfileFields.
+					 * uapsd_mask in CSR for consistency
+					 */
+					csr_get_modify_profile_fields(pMac,
+								     flow_info->
+								      sessionId,
+							&modifyProfileFields);
+					modifyProfileFields.uapsd_mask =
+						pSession->apsdMask;
+					csr_set_modify_profile_fields(pMac,
+								     flow_info->
+								      sessionId,
+							&modifyProfileFields);
+					if (!pSession->apsdMask) {
+						/* this session no longer needs
+						 * UAPSD do any sessions still
+						 * require UAPSD?
+						 */
+						if (!sme_qos_is_uapsd_active())
+							/* No sessions require
+							 * UAPSD so turn it off
+							 * (really don't care
+							 * when PMC stops it)
+							 */
+							sme_ps_uapsd_disable(
+							      mac_hdl,
+							      sessionId);
+					}
+				}
+				if (SME_QOS_RELEASE_DEFAULT ==
+							pACInfo->relTrig) {
+					/* send delts */
+					hstatus =
+						qos_issue_command(pMac,
+								sessionId,
+							eSmeCommandDelTs,
+								  NULL, ac,
+								  flow_info->
+								  tspec_mask);
+					if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+						/* err msg */
+						QDF_TRACE(QDF_MODULE_ID_SME,
+							  QDF_TRACE_LEVEL_ERROR,
+							  "%s: %d: sme_qos_del_ts_req() failed",
+							  __func__, __LINE__);
+						status =
+							SME_QOS_STATUS_RELEASE_FAILURE_RSP;
+					} else {
+						pACInfo->tspec_mask_status &=
+						SME_QOS_TSPEC_MASK_BIT_1_2_SET
+						& (~flow_info->tspec_mask);
+						deltsIssued = true;
+					}
+				} else {
+					pACInfo->tspec_mask_status &=
+						SME_QOS_TSPEC_MASK_BIT_1_2_SET &
+						(~flow_info->tspec_mask);
+					deltsIssued = true;
+				}
+			} else if (pSession->apsdMask &
+				(1 << (SME_QOS_EDCA_AC_VO - ac))) {
+				/* reassoc logic */
+				csr_get_modify_profile_fields(pMac, sessionId,
+							  &modifyProfileFields);
+				modifyProfileFields.uapsd_mask |=
+					pSession->apsdMask;
+				modifyProfileFields.uapsd_mask &=
+					~(1 << (SME_QOS_EDCA_AC_VO - ac));
+				pSession->apsdMask &=
+					~(1 << (SME_QOS_EDCA_AC_VO - ac));
+				if (!pSession->apsdMask) {
+					/* this session no longer needs UAPSD
+					 * do any sessions still require UAPSD?
+					 */
+					if (!sme_qos_is_uapsd_active())
+						/* No sessions require UAPSD so
+						 * turn it off (really don't
+						 * care when PMC stops it)
+						 */
+						sme_ps_uapsd_disable(
+							mac_hdl, sessionId);
+				}
+				hstatus = sme_qos_request_reassoc(pMac,
+								sessionId,
+							&modifyProfileFields,
+								  false);
+				if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+					/* err msg */
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_ERROR,
+						  "%s: %d: Reassoc failed",
+						  __func__, __LINE__);
+					status =
+					SME_QOS_STATUS_RELEASE_FAILURE_RSP;
+				} else {
+					/* no need to wait */
+					pACInfo->reassoc_pending = false;
+					pACInfo->prev_state = SME_QOS_LINK_UP;
+					pACInfo->tspec_pending = 0;
+				}
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "%s: %d: nothing to do for AC = %d",
+					  __func__, __LINE__, ac);
+			}
+
+			if (SME_QOS_RELEASE_BY_AP == pACInfo->relTrig) {
+				flow_info->QoSCallback(MAC_HANDLE(pMac),
+						       flow_info->HDDcontext,
+						       &pACInfo->
+						       curr_QoSInfo[flow_info->
+								    tspec_mask -
+								    1],
+					SME_QOS_STATUS_RELEASE_QOS_LOST_IND,
+						       flow_info->QosFlowID);
+
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "%s: %d: Deleting entry at %pK with flowID %d",
+					  __func__, __LINE__, flow_info,
+					  flow_info->QosFlowID);
+			} else if (buffered_cmd) {
+				flow_info->QoSCallback(MAC_HANDLE(pMac),
+						       flow_info->HDDcontext,
+						       NULL, status,
+						       flow_info->QosFlowID);
+			}
+
+			if (SME_QOS_STATUS_RELEASE_FAILURE_RSP == status)
+				break;
+
+			if (((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~flow_info->
+			      tspec_mask) > 0)
+			    &&
+			    ((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~flow_info->
+			      tspec_mask) <= SME_QOS_TSPEC_INDEX_MAX)) {
+				if (pACInfo->
+				    num_flows[(SME_QOS_TSPEC_MASK_BIT_1_2_SET &
+					       ~flow_info->tspec_mask) - 1] >
+				    0)
+					new_state = SME_QOS_QOS_ON;
+				else
+					new_state = SME_QOS_LINK_UP;
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "%s: %d: Exceeded the array bounds of pACInfo->num_flows",
+					  __func__, __LINE__);
+				return
+				SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP;
+			}
+
+			if (false == deltsIssued) {
+				qdf_mem_zero(&pACInfo->
+					curr_QoSInfo[flow_info->
+					tspec_mask - 1],
+					sizeof(struct sme_qos_wmmtspecinfo));
+			}
+			qdf_mem_zero(&pACInfo->
+				     requested_QoSInfo[flow_info->tspec_mask -
+						       1],
+				     sizeof(struct sme_qos_wmmtspecinfo));
+			pACInfo->num_flows[flow_info->tspec_mask - 1]--;
+			/* delete the entry from Flow List */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: On session %d deleting entry at %pK with flowID %d",
+				  __func__, __LINE__,
+				  sessionId, flow_info, QosFlowID);
+			csr_ll_remove_entry(&sme_qos_cb.flow_list, pEntry,
+					    true);
+			pDeletedFlow = flow_info;
+			pACInfo->relTrig = SME_QOS_RELEASE_DEFAULT;
+		}
+		/* if we are doing reassoc & we are already in handoff state, no
+		 * need to move to requested state. But make sure to set the
+		 * previous state as requested state
+		 */
+		if (SME_QOS_HANDOFF != pACInfo->curr_state)
+			sme_qos_state_transition(sessionId, ac, new_state);
+
+		if (pACInfo->reassoc_pending)
+			pACInfo->prev_state = SME_QOS_REQUESTED;
+		break;
+	case SME_QOS_HANDOFF:
+	case SME_QOS_REQUESTED:
+		/* buffer cmd */
+		cmd.command = SME_QOS_RELEASE_REQ;
+		cmd.pMac = pMac;
+		cmd.sessionId = sessionId;
+		cmd.u.releaseCmdInfo.QosFlowID = QosFlowID;
+		hstatus = sme_qos_buffer_cmd(&cmd, buffered_cmd);
+		if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: couldn't buffer the release request in state = %d",
+				  __func__, __LINE__, pACInfo->curr_state);
+			return SME_QOS_STATUS_RELEASE_FAILURE_RSP;
+		}
+		status = SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP;
+		break;
+	case SME_QOS_CLOSED:
+	case SME_QOS_INIT:
+	case SME_QOS_LINK_UP:
+	default:
+		/* print error msg */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: release request in unexpected state = %d",
+			  __func__, __LINE__, pACInfo->curr_state);
+		break;
+	}
+	/* if we deleted a flow, reclaim the memory */
+	if (pDeletedFlow)
+		qdf_mem_free(pDeletedFlow);
+
+	if (SME_QOS_STATUS_RELEASE_SUCCESS_RSP == status)
+		(void)sme_qos_process_buffered_cmd(sessionId);
+
+	return status;
+}
+
+/**
+ * sme_qos_setup() - internal SME QOS setup function.
+ * @pMac: Pointer to the global MAC parameter structure.
+ * @sessionId: Session upon which setup is being performed
+ * @pTspec_Info: Pointer to struct sme_qos_wmmtspecinfo which contains the WMM
+ *               TSPEC related info as defined above
+ * @ac: Enumeration of the various EDCA Access Categories.
+ *
+ * The internal qos setup function which has the intelligence
+ * if the request is NOP, or for APSD and/or need to send out ADDTS.
+ * It also does the sanity check for QAP, AP supports APSD etc.
+ * The logic used in the code might be confusing.
+ *
+ * Trying to cover all the cases here.
+ *    AP supports  App wants   ACM = 1  Already set APSD   Result
+ * |    0     |    0     |     0   |       0          |  NO ACM NO APSD
+ * |    0     |    0     |     0   |       1          |  NO ACM NO APSD/INVALID
+ * |    0     |    0     |     1   |       0          |  ADDTS
+ * |    0     |    0     |     1   |       1          |  ADDTS
+ * |    0     |    1     |     0   |       0          |  FAILURE
+ * |    0     |    1     |     0   |       1          |  INVALID
+ * |    0     |    1     |     1   |       0          |  ADDTS
+ * |    0     |    1     |     1   |       1          |  ADDTS
+ * |    1     |    0     |     0   |       0          |  NO ACM NO APSD
+ * |    1     |    0     |     0   |       1          |  NO ACM NO APSD
+ * |    1     |    0     |     1   |       0          |  ADDTS
+ * |    1     |    0     |     1   |       1          |  ADDTS
+ * |    1     |    1     |     0   |       0          |  REASSOC
+ * |    1     |    1     |     0   |       1          |  NOP: APSD SET ALREADY
+ * |    1     |    1     |     1   |       0          |  ADDTS
+ * |    1     |    1     |     1   |       1          |  ADDTS
+ *
+ * Return: SME_QOS_STATUS_SETUP_SUCCESS_RSP if the setup is successful'
+ */
+static enum sme_qos_statustype sme_qos_setup(tpAniSirGlobal pMac,
+				uint8_t sessionId,
+				struct sme_qos_wmmtspecinfo *pTspec_Info,
+				sme_QosEdcaAcType ac)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	enum sme_qos_statustype status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
+	tDot11fBeaconIEs *pIes = NULL;
+	tCsrRoamModifyProfileFields modifyProfileFields;
+	QDF_STATUS hstatus;
+
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Session Id %d is invalid",
+			  __func__, __LINE__, sessionId);
+		return status;
+	}
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	if (!pSession->sessionActive) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Session %d is inactive",
+			  __func__, __LINE__, sessionId);
+		return status;
+	}
+	if (!pSession->assocInfo.pBssDesc) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Session %d has an Invalid BSS Descriptor",
+			  __func__, __LINE__, sessionId);
+		return status;
+	}
+	hstatus = csr_get_parsed_bss_description_ies(pMac,
+						   pSession->assocInfo.pBssDesc,
+						      &pIes);
+	if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: On session %d unable to parse BSS IEs",
+			  __func__, __LINE__, sessionId);
+		return status;
+	}
+
+	/* success so pIes was allocated */
+
+	if (!CSR_IS_QOS_BSS(pIes)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: On session %d AP doesn't support QoS",
+			  __func__, __LINE__, sessionId);
+		qdf_mem_free(pIes);
+		/* notify HDD through the synchronous status msg */
+		return SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: UAPSD/PSB set %d: ", __func__, __LINE__,
+		  pTspec_Info->ts_info.psb);
+
+	pACInfo = &pSession->ac_info[ac];
+	do {
+		/* is ACM enabled for this AC? */
+		if (CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) ||
+		    sme_qos_is_acm(pMac, pSession->assocInfo.pBssDesc,
+				   ac, NULL)) {
+			/* ACM is enabled for this AC so we must send an
+			 * AddTS
+			 */
+			if (pTspec_Info->ts_info.psb &&
+			    !(pIes->WMMParams.
+			      qosInfo & SME_QOS_AP_SUPPORTS_APSD)
+			    && !(pIes->WMMInfoAp.uapsd)) {
+				/* application is looking for APSD but AP
+				 * doesn't support it
+				 */
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "%s: %d: On session %d AP doesn't support APSD",
+					  __func__, __LINE__, sessionId);
+				break;
+			}
+
+			if (SME_QOS_MAX_TID == pTspec_Info->ts_info.tid) {
+				/* App didn't set TID, generate one */
+				pTspec_Info->ts_info.tid =
+					(uint8_t) (SME_QOS_WMM_UP_NC -
+						   pTspec_Info->ts_info.up);
+			}
+			/* addts logic */
+			hstatus =
+				qos_issue_command(pMac, sessionId,
+						eSmeCommandAddTs,
+						  pTspec_Info, ac, 0);
+			if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "%s: %d: sme_qos_add_ts_req() failed",
+					  __func__, __LINE__);
+				break;
+			}
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: On session %d AddTS on AC %d is pending",
+				  __func__, __LINE__, sessionId, ac);
+			status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
+			break;
+		}
+		/* ACM is not enabled for this AC */
+		/* Is the application looking for APSD? */
+		if (0 == pTspec_Info->ts_info.psb) {
+			/* no, we don't need APSD but check the case, if the
+			 * setup is called as a result of a release or modify
+			 * which boils down to the fact that APSD was set on
+			 * this AC but no longer needed - so we need a reassoc
+			 * for the above case to let the AP know
+			 */
+			if (pSession->
+			    apsdMask & (1 << (SME_QOS_EDCA_AC_VO - ac))) {
+				/* APSD was formerly enabled on this AC but is
+				 * no longer required so we must reassociate
+				 */
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "%s: %d: On session %d reassoc needed to disable APSD on AC %d",
+					__func__,  __LINE__, sessionId, ac);
+				csr_get_modify_profile_fields(pMac, sessionId,
+							  &modifyProfileFields);
+				modifyProfileFields.uapsd_mask |=
+					pSession->apsdMask;
+				modifyProfileFields.uapsd_mask &=
+					~(1 << (SME_QOS_EDCA_AC_VO - ac));
+				hstatus =
+					sme_qos_request_reassoc(pMac, sessionId,
+							&modifyProfileFields,
+								false);
+				if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+					/* err msg */
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						  QDF_TRACE_LEVEL_ERROR,
+						  "%s: %d: Unable to request reassociation",
+						  __func__, __LINE__);
+					break;
+				} else {
+					QDF_TRACE(QDF_MODULE_ID_SME,
+						QDF_TRACE_LEVEL_DEBUG,
+						"%s: %d: On session %d reassociation to enable APSD on AC %d is pending",
+						__func__, __LINE__, sessionId,
+						ac);
+					status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
+					pACInfo->reassoc_pending = true;
+				}
+			} else {
+				/* we don't need APSD on this AC and we don't
+				 * currently have APSD on this AC
+				 */
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "%s: %d: Request is not looking for APSD & Admission Control isn't mandatory for the AC",
+					  __func__, __LINE__);
+				/* return success right away */
+				status =
+				SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP;
+			}
+			break;
+		} else if (!(pIes->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD)
+			   && !(pIes->WMMInfoAp.uapsd)) {
+			/* application is looking for APSD but AP doesn't
+			 * support it
+			 */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: On session %d AP doesn't support APSD",
+				  __func__, __LINE__, sessionId);
+			break;
+		} else if (pSession->
+			   apsdMask & (1 << (SME_QOS_EDCA_AC_VO - ac))) {
+			/* application is looking for APSD */
+			/* and it is already enabled on this AC */
+			status = SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY;
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: Request is looking for APSD and it is already set for the AC",
+				__func__, __LINE__);
+			break;
+		} else {
+			/* application is looking for APSD but it is not enabled on this
+			 * AC so we need to reassociate
+			 */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"On session %d reassoc needed to enable APSD on AC %d",
+				sessionId, ac);
+			/* reassoc logic */
+			/* update the UAPSD mask to include the new */
+			/* AC on which APSD is requested */
+			csr_get_modify_profile_fields(pMac, sessionId,
+						&modifyProfileFields);
+			modifyProfileFields.uapsd_mask |=
+					pSession->apsdMask;
+			modifyProfileFields.uapsd_mask |=
+					1 << (SME_QOS_EDCA_AC_VO - ac);
+			hstatus = sme_qos_request_reassoc(pMac, sessionId,
+							&modifyProfileFields,
+							false);
+			if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+				/* err msg */
+				QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+					"%s: %d: Unable to request reassociation",
+					__func__, __LINE__);
+				break;
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+					"On session %d reassociation to enable APSD on AC %d is pending",
+					sessionId, ac);
+				status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
+				pACInfo->reassoc_pending = true;
+			}
+		}
+	} while (0);
+
+	qdf_mem_free(pIes);
+	return status;
+}
+
+/* This is a dummy function now. But the purpose of me adding this was to
+ * delay the TSPEC processing till SET_KEY completes. This function can be
+ * used to do any SME_QOS processing after the SET_KEY. As of now, it is
+ * not required as we are ok with tspec getting programmed before set_key
+ * as the roam timings are measured without tspec in reassoc!
+ */
+static QDF_STATUS sme_qos_process_set_key_success_ind(tpAniSirGlobal pMac,
+					   uint8_t sessionId, void *pEvent_info)
+{
+	sme_debug("Set Key complete");
+	(void)sme_qos_process_buffered_cmd(sessionId);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * sme_qos_ese_save_tspec_response() - save TSPEC parameters.
+ * @pMac: Pointer to the global MAC parameter structure.
+ * @sessionId: SME session ID
+ * @pTspec: Pointer to the TSPEC IE from the reassoc rsp
+ * @ac:  Access Category for which this TSPEC rsp is received
+ * @tspecIndex: flow/direction
+ *
+ * This function saves the TSPEC parameters that came along in the TSPEC IE
+ * in the reassoc response
+ *
+ * Return: QDF_STATUS_SUCCESS - Release is successful.
+ */
+static QDF_STATUS
+sme_qos_ese_save_tspec_response(tpAniSirGlobal pMac, uint8_t sessionId,
+				tDot11fIEWMMTSPEC *pTspec, uint8_t ac,
+				uint8_t tspecIndex)
+{
+	tpSirAddtsRsp pAddtsRsp =
+		&sme_qos_cb.sessionInfo[sessionId].ac_info[ac].
+		addTsRsp[tspecIndex];
+
+	ac = sme_qos_u_pto_ac_map[pTspec->user_priority];
+
+	qdf_mem_zero(pAddtsRsp, sizeof(tSirAddtsRsp));
+
+	pAddtsRsp->messageType = eWNI_SME_ADDTS_RSP;
+	pAddtsRsp->length = sizeof(tSirAddtsRsp);
+	pAddtsRsp->rc = QDF_STATUS_SUCCESS;
+	pAddtsRsp->sessionId = sessionId;
+	pAddtsRsp->rsp.dialogToken = 0;
+	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",
+		  __func__, ac, tspecIndex);
+
+	if (pAddtsRsp->rsp.wmeTspecPresent)
+		/* Copy TSPEC params received in assoc response to addts
+		 * response
+		 */
+		convert_wmmtspec(pMac, &pAddtsRsp->rsp.tspec, pTspec);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_ese_process_reassoc_tspec_rsp() - process ese reassoc tspec response
+ * @pMac: Pointer to the global MAC parameter structure.
+ * @sessionId: SME session ID
+ * @pEven_info: Pointer to the smeJoinRsp structure
+ *
+ * This function processes the WMM TSPEC IE in the reassoc response.
+ * Reassoc triggered as part of ESE roaming to another ESE capable AP.
+ * If the TSPEC was added before reassoc, as part of Call Admission Control,
+ * the reasso req from the STA would carry the TSPEC parameters which were
+ * already negotiated with the older AP.
+ *
+ * Return: QDF_STATUS_SUCCESS - Release is successful.
+ */
+static
+QDF_STATUS sme_qos_ese_process_reassoc_tspec_rsp(tpAniSirGlobal pMac,
+						 uint8_t sessionId,
+						 void *pEvent_info)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	tDot11fIEWMMTSPEC *pTspecIE = NULL;
+	struct csr_roam_session *pCsrSession = NULL;
+	struct csr_roam_connectedinfo *pCsrConnectedInfo = NULL;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint8_t ac, numTspec, cnt;
+	uint8_t tspec_flow_index, tspec_mask_status;
+	uint32_t tspecIeLen;
+
+	pCsrSession = CSR_GET_SESSION(pMac, sessionId);
+	if (NULL == pCsrSession) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("session %d not found"), sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pCsrConnectedInfo = &pCsrSession->connectedInfo;
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+
+	/* Get the TSPEC IEs which came along with the reassoc response */
+	/* from the pbFrames pointer */
+	pTspecIE =
+		(tDot11fIEWMMTSPEC *) (pCsrConnectedInfo->pbFrames +
+				       pCsrConnectedInfo->nBeaconLength +
+				       pCsrConnectedInfo->nAssocReqLength +
+				       pCsrConnectedInfo->nAssocRspLength +
+				       pCsrConnectedInfo->nRICRspLength);
+
+	/* Get the number of tspecs Ies in the frame, the min length */
+	/* should be atleast equal to the one TSPEC IE */
+	tspecIeLen = pCsrConnectedInfo->nTspecIeLength;
+	if (tspecIeLen < sizeof(tDot11fIEWMMTSPEC)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("ESE Tspec IE len %d less than min %zu"),
+			  tspecIeLen, sizeof(tDot11fIEWMMTSPEC));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN,
+		  "TspecLen = %d, pbFrames = %pK, pTspecIE = %pK",
+		  tspecIeLen, pCsrConnectedInfo->pbFrames, pTspecIE);
+
+	numTspec = (tspecIeLen) / sizeof(tDot11fIEWMMTSPEC);
+	for (cnt = 0; cnt < numTspec; cnt++) {
+		ac = sme_qos_up_to_ac(pTspecIE->user_priority);
+		if (ac >= SME_QOS_EDCA_AC_MAX) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("ac %d more than it`s max value"), ac);
+			return QDF_STATUS_E_FAILURE;
+		}
+		pACInfo = &pSession->ac_info[ac];
+		tspec_mask_status = pACInfo->tspec_mask_status;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN,
+			  FL("UP=%d, ac=%d, tspec_mask_status=%x"),
+			  pTspecIE->user_priority, ac, tspec_mask_status);
+
+		for (tspec_flow_index = 0;
+		     tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX;
+		     tspec_flow_index++) {
+			if (tspec_mask_status & (1 << tspec_flow_index)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_WARN,
+					  "Found Tspec entry flow = %d AC = %d",
+					  tspec_flow_index, ac);
+				sme_qos_ese_save_tspec_response(pMac, sessionId,
+								pTspecIE, ac,
+							tspec_flow_index);
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_WARN,
+					"Not found Tspec entry flow = %d AC = %d",
+					  tspec_flow_index, ac);
+			}
+		}
+		/* Increment the pointer to point it to the next TSPEC IE */
+		pTspecIE++;
+	}
+
+	/* Send the Aggregated QoS request to HAL */
+	status = sme_qos_ft_aggr_qos_req(pMac, sessionId);
+
+	return status;
+}
+
+/**
+ * sme_qos_copy_tspec_info() - copy tspec info.
+ * @pMac: Pointer to the global MAC parameter structure.
+ * @pTspec_Info: source structure
+ * @pTspec: destination structure
+ *
+ * This function copies the existing TSPEC parameters from the source structure
+ * to the destination structure.
+ *
+ * Return: None
+ */
+static void sme_qos_copy_tspec_info(tpAniSirGlobal pMac,
+				    struct sme_qos_wmmtspecinfo *pTspec_Info,
+				    tSirMacTspecIE *pTspec)
+{
+	/* As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum
+	 * Service Interval, Service Start Time, Suspension Interval and Delay
+	 * Bound are all intended for HCCA operation and therefore must be set
+	 * to zero
+	 */
+	pTspec->delayBound = pTspec_Info->delay_bound;
+	pTspec->inactInterval = pTspec_Info->inactivity_interval;
+	pTspec->length = SME_QOS_TSPEC_IE_LENGTH;
+	pTspec->maxBurstSz = pTspec_Info->max_burst_size;
+	pTspec->maxMsduSz = pTspec_Info->maximum_msdu_size;
+	pTspec->maxSvcInterval = pTspec_Info->max_service_interval;
+	pTspec->meanDataRate = pTspec_Info->mean_data_rate;
+	pTspec->mediumTime = pTspec_Info->medium_time;
+	pTspec->minDataRate = pTspec_Info->min_data_rate;
+	pTspec->minPhyRate = pTspec_Info->min_phy_rate;
+	pTspec->minSvcInterval = pTspec_Info->min_service_interval;
+	pTspec->nomMsduSz = pTspec_Info->nominal_msdu_size;
+	pTspec->peakDataRate = pTspec_Info->peak_data_rate;
+	pTspec->surplusBw = pTspec_Info->surplus_bw_allowance;
+	pTspec->suspendInterval = pTspec_Info->suspension_interval;
+	pTspec->svcStartTime = pTspec_Info->svc_start_time;
+	pTspec->tsinfo.traffic.direction = pTspec_Info->ts_info.direction;
+
+	/* Make sure UAPSD is allowed */
+	if (pTspec_Info->ts_info.psb)
+		pTspec->tsinfo.traffic.psb = pTspec_Info->ts_info.psb;
+	else {
+		pTspec->tsinfo.traffic.psb = 0;
+		pTspec_Info->ts_info.psb = 0;
+	}
+	pTspec->tsinfo.traffic.tsid = pTspec_Info->ts_info.tid;
+	pTspec->tsinfo.traffic.userPrio = pTspec_Info->ts_info.up;
+	pTspec->tsinfo.traffic.accessPolicy = SME_QOS_ACCESS_POLICY_EDCA;
+	pTspec->tsinfo.traffic.burstSizeDefn =
+		pTspec_Info->ts_info.burst_size_defn;
+	pTspec->tsinfo.traffic.ackPolicy = pTspec_Info->ts_info.ack_policy;
+	pTspec->type = SME_QOS_TSPEC_IE_TYPE;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: up = %d, tid = %d",
+		  __func__, __LINE__,
+		  pTspec_Info->ts_info.up, pTspec_Info->ts_info.tid);
+}
+
+/**
+ * sme_qos_ese_retrieve_tspec_info() - retrieve tspec info.
+ * @pMac: Pointer to the global MAC parameter structure.
+ * @sessionId: SME session ID
+ * @pTspecInfo: Pointer to the structure to carry back the TSPEC parameters
+ *
+ * This function is called by CSR when try to create reassoc request message to
+ * PE - csrSendSmeReassocReqMsg. This functions get the existing tspec
+ * parameters to be included in the reassoc request.
+ *
+ * Return: uint8_t - number of existing negotiated TSPECs
+ */
+uint8_t sme_qos_ese_retrieve_tspec_info(tpAniSirGlobal mac_ctx,
+	 uint8_t session_id, tTspecInfo *tspec_info)
+{
+	struct sme_qos_sessioninfo *session;
+	struct sme_qos_acinfo *ac_info;
+	uint8_t ac, num_tspec = 0;
+	tTspecInfo *dst_tspec = tspec_info;
+	uint8_t tspec_mask;
+	uint8_t tspec_pending;
+
+	/* TODO: Check if TSPEC has already been established
+	 * if not return
+	 */
+	session = &sme_qos_cb.sessionInfo[session_id];
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		volatile uint8_t index = 0;
+
+		ac_info = &session->ac_info[ac];
+		tspec_pending = ac_info->tspec_pending;
+		tspec_mask = ac_info->tspec_mask_status;
+		do {
+			/*
+			 * If a tspec status is pending, take
+			 * requested_QoSInfo for RIC request,
+			 * else use curr_QoSInfo for the
+			 * RIC request
+			 */
+			if ((tspec_mask & SME_QOS_TSPEC_MASK_BIT_1_SET)
+				&& (tspec_pending &
+				SME_QOS_TSPEC_MASK_BIT_1_SET)){
+				sme_qos_copy_tspec_info(mac_ctx,
+					&ac_info->requested_QoSInfo[index],
+					&dst_tspec->tspec);
+				dst_tspec->valid = true;
+				num_tspec++;
+				dst_tspec++;
+			} else if ((tspec_mask & SME_QOS_TSPEC_MASK_BIT_1_SET)
+				&& !(tspec_pending &
+				SME_QOS_TSPEC_MASK_BIT_1_SET)){
+				sme_qos_copy_tspec_info(mac_ctx,
+					&ac_info->curr_QoSInfo[index],
+					&dst_tspec->tspec);
+				dst_tspec->valid = true;
+				num_tspec++;
+				dst_tspec++;
+			}
+			tspec_mask >>= 1;
+			tspec_pending >>= 1;
+			index++;
+		} while (tspec_mask);
+	}
+	return num_tspec;
+}
+
+#endif
+
+static
+QDF_STATUS sme_qos_create_tspec_ricie(tpAniSirGlobal pMac,
+				      struct sme_qos_wmmtspecinfo *pTspec_Info,
+				      uint8_t *pRICBuffer, uint32_t *pRICLength,
+				      uint8_t *pRICIdentifier)
+{
+	tDot11fIERICDataDesc ricIE;
+	uint32_t nStatus;
+
+	if (pRICBuffer == NULL || pRICIdentifier == NULL || pRICLength ==
+								NULL) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("RIC data is NULL, %pK, %pK, %pK"),
+			pRICBuffer, pRICIdentifier, pRICLength);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_zero(&ricIE, sizeof(tDot11fIERICDataDesc));
+
+	ricIE.present = 1;
+	ricIE.RICData.present = 1;
+	ricIE.RICData.resourceDescCount = 1;
+	ricIE.RICData.statusCode = 0;
+	ricIE.RICData.Identifier = sme_qos_assign_dialog_token();
+#ifndef USE_80211_WMMTSPEC_FOR_RIC
+	ricIE.TSPEC.present = 1;
+	ricIE.TSPEC.delay_bound = pTspec_Info->delay_bound;
+	ricIE.TSPEC.inactivity_int = pTspec_Info->inactivity_interval;
+	ricIE.TSPEC.burst_size = pTspec_Info->max_burst_size;
+	ricIE.TSPEC.max_msdu_size = pTspec_Info->maximum_msdu_size;
+	ricIE.TSPEC.max_service_int = pTspec_Info->max_service_interval;
+	ricIE.TSPEC.mean_data_rate = pTspec_Info->mean_data_rate;
+	ricIE.TSPEC.medium_time = 0;
+	ricIE.TSPEC.min_data_rate = pTspec_Info->min_data_rate;
+	ricIE.TSPEC.min_phy_rate = pTspec_Info->min_phy_rate;
+	ricIE.TSPEC.min_service_int = pTspec_Info->min_service_interval;
+	ricIE.TSPEC.size = pTspec_Info->nominal_msdu_size;
+	ricIE.TSPEC.peak_data_rate = pTspec_Info->peak_data_rate;
+	ricIE.TSPEC.surplus_bw_allowance = pTspec_Info->surplus_bw_allowance;
+	ricIE.TSPEC.suspension_int = pTspec_Info->suspension_interval;
+	ricIE.TSPEC.service_start_time = pTspec_Info->svc_start_time;
+	ricIE.TSPEC.direction = pTspec_Info->ts_info.direction;
+	/* Make sure UAPSD is allowed */
+	if (pTspec_Info->ts_info.psb)
+		ricIE.TSPEC.psb = pTspec_Info->ts_info.psb;
+	else
+		ricIE.TSPEC.psb = 0;
+
+	ricIE.TSPEC.tsid = pTspec_Info->ts_info.tid;
+	ricIE.TSPEC.user_priority = pTspec_Info->ts_info.up;
+	ricIE.TSPEC.access_policy = SME_QOS_ACCESS_POLICY_EDCA;
+
+	*pRICIdentifier = ricIE.RICData.Identifier;
+
+	nStatus =
+		dot11f_pack_ie_ric_data_desc(pMac, &ricIE, pRICBuffer,
+					sizeof(ricIE), pRICLength);
+	if (DOT11F_FAILED(nStatus)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"Packing of RIC Data of length %d failed with status %d",
+			  *pRICLength, nStatus);
+	}
+#else                           /* WMM TSPEC */
+	/* As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum
+	 * Service Interval, Service Start Time, Suspension Interval and Delay
+	 * Bound are all intended for HCCA operation and therefore must be set
+	 * to zero
+	 */
+	ricIE.WMMTSPEC.present = 1;
+	ricIE.WMMTSPEC.version = 1;
+	ricIE.WMMTSPEC.delay_bound = pTspec_Info->delay_bound;
+	ricIE.WMMTSPEC.inactivity_int = pTspec_Info->inactivity_interval;
+	ricIE.WMMTSPEC.burst_size = pTspec_Info->max_burst_size;
+	ricIE.WMMTSPEC.max_msdu_size = pTspec_Info->maximum_msdu_size;
+	ricIE.WMMTSPEC.max_service_int = pTspec_Info->max_service_interval;
+	ricIE.WMMTSPEC.mean_data_rate = pTspec_Info->mean_data_rate;
+	ricIE.WMMTSPEC.medium_time = 0;
+	ricIE.WMMTSPEC.min_data_rate = pTspec_Info->min_data_rate;
+	ricIE.WMMTSPEC.min_phy_rate = pTspec_Info->min_phy_rate;
+	ricIE.WMMTSPEC.min_service_int = pTspec_Info->min_service_interval;
+	ricIE.WMMTSPEC.size = pTspec_Info->nominal_msdu_size;
+	ricIE.WMMTSPEC.peak_data_rate = pTspec_Info->peak_data_rate;
+	ricIE.WMMTSPEC.surplus_bw_allowance = pTspec_Info->surplus_bw_allowance;
+	ricIE.WMMTSPEC.suspension_int = pTspec_Info->suspension_interval;
+	ricIE.WMMTSPEC.service_start_time = pTspec_Info->svc_start_time;
+	ricIE.WMMTSPEC.direction = pTspec_Info->ts_info.direction;
+	/* Make sure UAPSD is allowed */
+	if (pTspec_Info->ts_info.psb)
+		ricIE.WMMTSPEC.psb = pTspec_Info->ts_info.psb;
+	else
+		ricIE.WMMTSPEC.psb = 0;
+
+	ricIE.WMMTSPEC.tsid = pTspec_Info->ts_info.tid;
+	ricIE.WMMTSPEC.user_priority = pTspec_Info->ts_info.up;
+	ricIE.WMMTSPEC.access_policy = SME_QOS_ACCESS_POLICY_EDCA;
+
+	nStatus =
+		dot11f_pack_ie_ric_data_desc(pMac, &ricIE, pRICBuffer,
+					sizeof(ricIE), pRICLength);
+	if (DOT11F_FAILED(nStatus)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"Packing of RIC Data of length %d failed with status %d",
+			  *pRICLength, nStatus);
+	}
+#endif /* 80211_TSPEC */
+	*pRICIdentifier = ricIE.RICData.Identifier;
+	return nStatus;
+}
+/**
+ * sme_qos_process_ft_reassoc_req_ev()- processes reassoc request
+ *
+ * @session_id: SME Session Id
+ *
+ * This function Process reassoc request related to QOS
+ *
+ * Return: QDF_STATUS enumeration value.
+ */
+static QDF_STATUS sme_qos_process_ft_reassoc_req_ev(
+	uint8_t sessionId)
+{
+	struct sme_qos_sessioninfo *session;
+	struct sme_qos_acinfo *ac_info;
+	uint8_t ac, qos_requested = false;
+	uint8_t tspec_index;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	tListElem *entry = NULL;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL("Invoked on session %d"), sessionId);
+
+	session = &sme_qos_cb.sessionInfo[sessionId];
+
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		ac_info = &session->ac_info[ac];
+		qos_requested = false;
+
+		for (tspec_index = 0;
+			tspec_index < SME_QOS_TSPEC_INDEX_MAX;
+			tspec_index++) {
+			/*
+			 * Only in the below case, copy the AC's curr
+			 * QoS Info to requested QoS info
+			 */
+			if ((ac_info->ricIdentifier[tspec_index]
+				&& !ac_info->tspec_pending)
+				|| (ac_info->
+				tspec_mask_status & (1 << tspec_index))) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_DEBUG,
+					"Copying the currentQos to requestedQos for AC=%d, flow=%d",
+					ac, tspec_index);
+
+				ac_info->requested_QoSInfo[tspec_index] =
+					ac_info->curr_QoSInfo[tspec_index];
+				qdf_mem_zero(
+					&ac_info->curr_QoSInfo[tspec_index],
+					sizeof(struct sme_qos_wmmtspecinfo));
+				qos_requested = true;
+			}
+		}
+
+		/*
+		 * Only if the tspec is required, transition the state to
+		 * SME_QOS_REQUESTED for this AC
+		 */
+		if (qos_requested) {
+			switch (ac_info->curr_state) {
+			case SME_QOS_HANDOFF:
+				sme_qos_state_transition(sessionId, ac,
+					SME_QOS_REQUESTED);
+				break;
+			default:
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_ERROR,
+					"FT Reassoc req event in unexpected state %d",
+					ac_info->curr_state);
+			}
+		}
+	}
+
+	/*
+	 * At this point of time, we are
+	 * disconnected from the old AP, so it is safe
+	 * to reset all these session variables
+	 */
+	session->apsdMask = 0;
+
+	/*
+	 * Now change reason and HO renewal of
+	 * all the flow in this session only
+	 */
+	entry = csr_ll_peek_head(&sme_qos_cb.flow_list, false);
+	if (!entry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN,
+			FL("Flow List empty, nothing to update"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	do {
+		flow_info = GET_BASE_ADDR(entry, struct sme_qos_flowinfoentry,
+					link);
+		if (sessionId == flow_info->sessionId) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"Changing FlowID %d reason to SETUP and HO renewal to false",
+				flow_info->QosFlowID);
+			flow_info->reason = SME_QOS_REASON_SETUP;
+			flow_info->hoRenewal = true;
+		}
+		entry = csr_ll_next(&sme_qos_cb.flow_list, entry, false);
+	} while (entry);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_fill_aggr_info - fill QOS Aggregation info
+ *
+ * @ac_id - index to the AC
+ * @ts_id - index to TS for a given AC
+ * @direction - traffic direction
+ * @msg - QOS message
+ * @session - sme session information
+ *
+ * this is a helper function to populate aggregation information
+ * for QOS message.
+ *
+ * Return: None
+ */
+static void sme_qos_fill_aggr_info(int ac_id, int ts_id,
+				   enum sme_qos_wmm_dir_type direction,
+				   tSirAggrQosReq *msg,
+				   struct sme_qos_sessioninfo *session)
+{
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN,
+		  FL("Found tspec entry AC=%d, flow=%d, direction = %d"),
+		  ac_id, ts_id, direction);
+
+	msg->aggrInfo.aggrAddTsInfo[ac_id].dialogToken =
+			sme_qos_assign_dialog_token();
+	msg->aggrInfo.aggrAddTsInfo[ac_id].lleTspecPresent =
+		session->ac_info[ac_id].addTsRsp[ts_id].rsp.lleTspecPresent;
+	msg->aggrInfo.aggrAddTsInfo[ac_id].numTclas =
+		session->ac_info[ac_id].addTsRsp[ts_id].rsp.numTclas;
+	qdf_mem_copy(msg->aggrInfo.aggrAddTsInfo[ac_id].tclasInfo,
+		     session->ac_info[ac_id].addTsRsp[ts_id].rsp.tclasInfo,
+		     SIR_MAC_TCLASIE_MAXNUM);
+	msg->aggrInfo.aggrAddTsInfo[ac_id].tclasProc =
+		session->ac_info[ac_id].addTsRsp[ts_id].rsp.tclasProc;
+	msg->aggrInfo.aggrAddTsInfo[ac_id].tclasProcPresent =
+		session->ac_info[ac_id].addTsRsp[ts_id].rsp.tclasProcPresent;
+	msg->aggrInfo.aggrAddTsInfo[ac_id].tspec =
+		session->ac_info[ac_id].addTsRsp[ts_id].rsp.tspec;
+	msg->aggrInfo.aggrAddTsInfo[ac_id].wmeTspecPresent =
+		session->ac_info[ac_id].addTsRsp[ts_id].rsp.wmeTspecPresent;
+	msg->aggrInfo.aggrAddTsInfo[ac_id].wsmTspecPresent =
+		session->ac_info[ac_id].addTsRsp[ts_id].rsp.wsmTspecPresent;
+	msg->aggrInfo.tspecIdx |= (1 << ac_id);
+
+	/* Mark the index for this AC as pending for response, which would be */
+	/* used to validate the AddTS response from HAL->PE->SME */
+	session->ac_info[ac_id].tspec_pending = (1 << ts_id);
+
+}
+
+/**
+ * sme_qos_ft_aggr_qos_req - send aggregated QOS request
+ *
+ * @mac_ctx - global MAC context
+ * @session_id - sme session Id
+ *
+ * This function is used to send aggregated QOS request to HAL.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_qos_ft_aggr_qos_req(tpAniSirGlobal mac_ctx, uint8_t
+					session_id)
+{
+	tSirAggrQosReq *aggr_req = NULL;
+	struct sme_qos_sessioninfo *session;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	int i, j = 0;
+	uint8_t direction;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("invoked on session %d"), session_id);
+
+	session = &sme_qos_cb.sessionInfo[session_id];
+
+	aggr_req = qdf_mem_malloc(sizeof(tSirAggrQosReq));
+	if (!aggr_req)
+		return QDF_STATUS_E_NOMEM;
+
+	aggr_req->messageType = eWNI_SME_FT_AGGR_QOS_REQ;
+	aggr_req->length = sizeof(tSirAggrQosReq);
+	aggr_req->sessionId = session_id;
+	aggr_req->timeout = 0;
+	aggr_req->rspReqd = true;
+	qdf_mem_copy(&aggr_req->bssid.bytes[0],
+		     &session->assocInfo.pBssDesc->bssId[0],
+		     sizeof(struct qdf_mac_addr));
+
+	for (i = 0; i < SME_QOS_EDCA_AC_MAX; i++) {
+		for (j = 0; j < SME_QOS_TSPEC_INDEX_MAX; j++) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"ac=%d, tspec_mask_staus=%x, tspec_index=%d",
+				  i, session->ac_info[i].tspec_mask_status, j);
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  FL("direction = %d"),
+				  session->ac_info[i].addTsRsp[j].rsp.tspec.
+				  tsinfo.traffic.direction);
+			/* Check if any flow is active on this AC */
+			if (!((session->ac_info[i].tspec_mask_status) &
+			     (1 << j)))
+				continue;
+
+			direction = session->ac_info[i].addTsRsp[j].rsp.tspec.
+					tsinfo.traffic.direction;
+
+			if ((direction == SME_QOS_WMM_TS_DIR_UPLINK) ||
+			    (direction == SME_QOS_WMM_TS_DIR_BOTH))
+				sme_qos_fill_aggr_info(i, j, direction,
+						aggr_req, session);
+		}
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
+		  FL("Sending aggregated message to HAL 0x%x"),
+		  aggr_req->aggrInfo.tspecIdx);
+
+	if (QDF_IS_STATUS_SUCCESS(umac_send_mb_message_to_mac(aggr_req))) {
+		status = QDF_STATUS_SUCCESS;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_HIGH,
+			  FL("sent down a AGGR QoS req to PE"));
+	}
+
+	return status;
+}
+
+static
+QDF_STATUS sme_qos_process_ftric_response(tpAniSirGlobal pMac,
+					  uint8_t sessionId,
+					  tDot11fIERICDataDesc *pRicDataDesc,
+					  uint8_t ac, uint8_t tspecIndex)
+{
+	uint8_t i = 0;
+	tpSirAddtsRsp pAddtsRsp = &sme_qos_cb.sessionInfo[sessionId].
+					ac_info[ac].addTsRsp[tspecIndex];
+
+	qdf_mem_zero(pAddtsRsp, sizeof(tSirAddtsRsp));
+
+	pAddtsRsp->messageType = eWNI_SME_ADDTS_RSP;
+	pAddtsRsp->length = sizeof(tSirAddtsRsp);
+	pAddtsRsp->rc = pRicDataDesc->RICData.statusCode;
+	pAddtsRsp->sessionId = sessionId;
+	pAddtsRsp->rsp.dialogToken = pRicDataDesc->RICData.Identifier;
+	pAddtsRsp->rsp.status = pRicDataDesc->RICData.statusCode;
+	pAddtsRsp->rsp.wmeTspecPresent = pRicDataDesc->TSPEC.present;
+	if (pAddtsRsp->rsp.wmeTspecPresent)
+		/* Copy TSPEC params received in RIC response to addts
+		 * response
+		 */
+		convert_tspec(pMac, &pAddtsRsp->rsp.tspec,
+				&pRicDataDesc->TSPEC);
+
+	pAddtsRsp->rsp.numTclas = pRicDataDesc->num_TCLAS;
+	if (pAddtsRsp->rsp.numTclas) {
+		for (i = 0; i < pAddtsRsp->rsp.numTclas; i++)
+			/* Copy TCLAS info per index to the addts response */
+			convert_tclas(pMac, &pAddtsRsp->rsp.tclasInfo[i],
+				      &pRicDataDesc->TCLAS[i]);
+	}
+
+	pAddtsRsp->rsp.tclasProcPresent = pRicDataDesc->TCLASSPROC.present;
+	if (pAddtsRsp->rsp.tclasProcPresent)
+		pAddtsRsp->rsp.tclasProc = pRicDataDesc->TCLASSPROC.processing;
+
+	pAddtsRsp->rsp.schedulePresent = pRicDataDesc->Schedule.present;
+	if (pAddtsRsp->rsp.schedulePresent) {
+		/* Copy Schedule IE params to addts response */
+		convert_schedule(pMac, &pAddtsRsp->rsp.schedule,
+				 &pRicDataDesc->Schedule);
+	}
+	/* Need to check the below portion is a part of WMM TSPEC */
+	/* Process Delay element */
+	if (pRicDataDesc->TSDelay.present)
+		convert_ts_delay(pMac, &pAddtsRsp->rsp.delay,
+				 &pRicDataDesc->TSDelay);
+
+	/* Need to call for WMMTSPEC */
+	if (pRicDataDesc->WMMTSPEC.present)
+		convert_wmmtspec(pMac, &pAddtsRsp->rsp.tspec,
+				 &pRicDataDesc->WMMTSPEC);
+
+	/* return sme_qos_process_add_ts_rsp(pMac, &addtsRsp); */
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_process_aggr_qos_rsp - process qos aggregation response
+ *
+ * @mac_ctx - global mac context
+ * @msgbuf - SME message buffer
+ *
+ * this function process the QOS aggregation response received.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_aggr_qos_rsp(tpAniSirGlobal mac_ctx,
+					void *msgbuf)
+{
+	tpSirAggrQosRsp rsp = (tpSirAggrQosRsp) msgbuf;
+	tSirAddtsRsp addtsrsp;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	int i, j = 0;
+	uint8_t sessionid = rsp->sessionId;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("Received AGGR_QOS resp from LIM"));
+
+	/* Copy the updated response information for TSPEC of all the ACs */
+	for (i = 0; i < SIR_QOS_NUM_AC_MAX; i++) {
+		uint8_t tspec_mask_status =
+			sme_qos_cb.sessionInfo[sessionid].ac_info[i].
+			tspec_mask_status;
+		for (j = 0; j < SME_QOS_TSPEC_INDEX_MAX; j++) {
+			uint8_t direction =
+				sme_qos_cb.sessionInfo[sessionid].
+				ac_info[i].addTsRsp[j].rsp.tspec.tsinfo.traffic.
+				direction;
+
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"Addts rsp from LIM AC=%d, flow=%d dir=%d, tspecIdx=%x",
+				  i, j, direction, rsp->aggrInfo.tspecIdx);
+
+			/* Check if the direction is Uplink or bi-directional */
+			if (!(((1 << i) & rsp->aggrInfo.tspecIdx) &&
+			    ((tspec_mask_status) & (1 << j)) &&
+			    ((direction == SME_QOS_WMM_TS_DIR_UPLINK) ||
+			     (direction == SME_QOS_WMM_TS_DIR_BOTH)))) {
+				continue;
+			}
+			addtsrsp =
+				sme_qos_cb.sessionInfo[sessionid].ac_info[i].
+				addTsRsp[j];
+			addtsrsp.rc = rsp->aggrInfo.aggrRsp[i].status;
+			addtsrsp.rsp.status = rsp->aggrInfo.aggrRsp[i].status;
+			addtsrsp.rsp.tspec = rsp->aggrInfo.aggrRsp[i].tspec;
+
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"Processing Addts rsp from LIM AC=%d, flow=%d",
+				  i, j);
+			/* post ADD TS response for each */
+			if (sme_qos_process_add_ts_rsp(mac_ctx, &addtsrsp) !=
+			    QDF_STATUS_SUCCESS)
+				status = QDF_STATUS_E_FAILURE;
+		}
+	}
+	return status;
+}
+
+/**
+ * sme_qos_find_matching_tspec() - utility function to find matching tspec
+ * @mac_ctx: global MAC context
+ * @sessionid: session ID
+ * @ac: AC index
+ * @ac_info: Current AC info
+ * @ric_data_desc: pointer to ric data
+ * @ric_rsplen: pointer to ric response length
+ *
+ * This utility function is called by sme_qos_process_ft_reassoc_rsp_ev
+ * to find the matching tspec
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_qos_find_matching_tspec(tpAniSirGlobal mac_ctx,
+		uint8_t sessionid, uint8_t ac, struct sme_qos_acinfo *ac_info,
+		tDot11fIERICDataDesc *ric_data_desc, uint32_t *ric_rsplen)
+{
+	uint8_t tspec_flow_index;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("invoked on session %d"), sessionid);
+
+	for (tspec_flow_index = 0;
+	     tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX; tspec_flow_index++) {
+		/*
+		 * Only in the below case, copy the AC's curr QoS Info
+		 * to requested QoS info
+		 */
+		if (!ac_info->ricIdentifier[tspec_flow_index])
+			continue;
+
+		if (!*ric_rsplen) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"RIC Response not received for AC %d on TSPEC Index %d, RIC Req Identifier = %d",
+			  ac, tspec_flow_index,
+			  ac_info->ricIdentifier[tspec_flow_index]);
+			continue;
+		}
+		/* Now we got response for this identifier. Process it. */
+		if (!ric_data_desc->present)
+			continue;
+		if (!ric_data_desc->RICData.present)
+			continue;
+
+		if (ric_data_desc->RICData.Identifier !=
+			ac_info->ricIdentifier[tspec_flow_index]) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"RIC response order not same as request sent. Request ID = %d, Response ID = %d",
+			  ac_info->ricIdentifier[tspec_flow_index],
+			  ric_data_desc->RICData.Identifier);
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"Processing RIC Response for AC %d, TSPEC Flow index %d with RIC ID %d",
+			  ac, tspec_flow_index,
+			  ric_data_desc->RICData.Identifier);
+			status = sme_qos_process_ftric_response(mac_ctx,
+					sessionid, ric_data_desc, ac,
+					tspec_flow_index);
+			if (QDF_STATUS_SUCCESS != status) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+				  QDF_TRACE_LEVEL_ERROR,
+					"Failed with status %d for AC %d in TSPEC Flow index = %d",
+				  status, ac, tspec_flow_index);
+			}
+		}
+		ric_data_desc++;
+		*ric_rsplen -= sizeof(tDot11fIERICDataDesc);
+	}
+	return status;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * sme_qos_find_matching_tspec_lfr3() - utility function to find matching tspec
+ * @mac_ctx: global MAC context
+ * @sessionid: session ID
+ * @ac: AC index
+ * @qos_session: QOS session
+ * @ric_data_desc: pointer to ric data
+ * @ric_rsplen: ric response length
+ *
+ * This utility function is called by sme_qos_process_ft_reassoc_rsp_ev
+ * to find the matching tspec while LFR3 is enabled.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_qos_find_matching_tspec_lfr3(tpAniSirGlobal mac_ctx,
+		uint8_t sessionid, uint8_t ac, struct sme_qos_sessioninfo
+		*qos_session,
+		tDot11fIERICDataDesc *ric_data_desc, uint32_t ric_rsplen)
+{
+	struct sme_qos_acinfo *ac_info;
+	uint8_t tspec_flow_idx;
+	bool found = false;
+	enum sme_qos_wmm_dir_type direction, qos_dir;
+	uint8_t ac1;
+	tDot11fIERICDataDesc *ric_data = NULL;
+	uint32_t ric_len;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("invoked on session %d"), sessionid);
+
+	if (ac == SME_QOS_EDCA_AC_MAX) {
+		sme_err("Invalid AC %d", ac);
+		return QDF_STATUS_E_FAILURE;
+	}
+	ric_data = ric_data_desc;
+	ric_len = ric_rsplen;
+	ac_info = &qos_session->ac_info[ac];
+	for (tspec_flow_idx = 0; tspec_flow_idx < SME_QOS_TSPEC_INDEX_MAX;
+	     tspec_flow_idx++) {
+		if (!((qos_session->ac_info[ac].tspec_mask_status) &
+		    (1 << tspec_flow_idx)))
+			goto sme_qos_next_ric;
+		qos_dir =
+		  ac_info->requested_QoSInfo[tspec_flow_idx].ts_info.direction;
+		do {
+			ac1 = sme_qos_up_to_ac(
+				ric_data->WMMTSPEC.user_priority);
+			if (ac1 == SME_QOS_EDCA_AC_MAX) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+				  QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid AC %d UP %d"), ac1,
+				  ric_data->WMMTSPEC.user_priority);
+				break;
+			}
+			direction = ric_data->WMMTSPEC.direction;
+			if (ac == ac1 && direction == qos_dir) {
+				found = true;
+				status = sme_qos_process_ftric_response(mac_ctx,
+						sessionid, ric_data, ac,
+						tspec_flow_idx);
+				if (QDF_STATUS_SUCCESS != status) {
+					QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+						"Failed with status %d for AC %d in TSPEC Flow index = %d",
+					  status, ac, tspec_flow_idx);
+				}
+				break;
+			}
+			ric_data++;
+			ric_len -= sizeof(tDot11fIERICDataDesc);
+		} while (ric_len);
+sme_qos_next_ric:
+		ric_data = ric_data_desc;
+		ric_len = ric_rsplen;
+		found = false;
+	}
+
+	return status;
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+static
+QDF_STATUS sme_qos_process_ft_reassoc_rsp_ev(tpAniSirGlobal mac_ctx,
+				uint8_t sessionid, void *event_info)
+{
+	struct sme_qos_sessioninfo *qos_session;
+	struct sme_qos_acinfo *ac_info;
+	uint8_t ac;
+	tDot11fIERICDataDesc *ric_data_desc = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *csr_session = CSR_GET_SESSION(mac_ctx,
+				sessionid);
+	struct csr_roam_connectedinfo *csr_conn_info = NULL;
+	uint32_t ric_rsplen;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	tDot11fIERICDataDesc *ric_data = NULL;
+	uint32_t ric_len;
+#endif
+
+	if (NULL == csr_session) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("The Session pointer is NULL"));
+		return QDF_STATUS_E_FAILURE;
+	}
+	csr_conn_info = &csr_session->connectedInfo;
+	ric_rsplen = csr_conn_info->nRICRspLength;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("invoked on session %d"), sessionid);
+
+	qos_session = &sme_qos_cb.sessionInfo[sessionid];
+
+	ric_data_desc = (tDot11fIERICDataDesc *) ((csr_conn_info->pbFrames) +
+				(csr_conn_info->nBeaconLength +
+				 csr_conn_info->nAssocReqLength +
+				 csr_conn_info->nAssocRspLength));
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (!csr_session->roam_synch_in_progress) {
+#endif
+		for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+			ac_info = &qos_session->ac_info[ac];
+			sme_qos_find_matching_tspec(mac_ctx, sessionid, ac,
+					ac_info, ric_data_desc, &ric_rsplen);
+		}
+
+		if (ric_rsplen) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("RIC Resp still follows . Rem len = %d"),
+				ric_rsplen);
+		}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"LFR3-11r Compare RIC in Reassoc Resp to find matching tspec in host");
+		ric_data = ric_data_desc;
+		ric_len = ric_rsplen;
+		if (ric_rsplen && ric_data_desc->present &&
+		    ric_data_desc->WMMTSPEC.present) {
+			for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX;
+			     ac++) {
+				sme_qos_find_matching_tspec_lfr3(mac_ctx,
+					sessionid, ac, qos_session, ric_data,
+					ric_len);
+			}
+		} else
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				"LFR3-11r ric_rsplen is zero or ric_data_desc is not present or wmmtspec is not present");
+	}
+#endif
+
+	/* Send the Aggregated QoS request to HAL */
+	status = sme_qos_ft_aggr_qos_req(mac_ctx, sessionid);
+
+	return status;
+}
+
+/**
+ * sme_qos_add_ts_req() - send ADDTS request.
+ * @pMac: Pointer to the global MAC parameter structure.
+ * @sessionId: Session upon which the TSPEC should be added
+ * @pTspec_Info: Pointer to struct sme_qos_wmmtspecinfo which contains the WMM
+ *               TSPEC related info as defined above
+ * @ac: Enumeration of the various EDCA Access Categories.
+ *
+ * This function is used to send down the ADDTS request with TSPEC params to PE
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_qos_add_ts_req(tpAniSirGlobal pMac,
+			      uint8_t sessionId,
+			      struct sme_qos_wmmtspecinfo *pTspec_Info,
+			      sme_QosEdcaAcType ac)
+{
+	tSirAddtsReq *pMsg = NULL;
+	struct sme_qos_sessioninfo *pSession;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+#ifdef FEATURE_WLAN_ESE
+	struct csr_roam_session *pCsrSession = CSR_GET_SESSION(pMac, sessionId);
+#endif
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	WLAN_HOST_DIAG_EVENT_DEF(qos, host_event_wlan_qos_payload_type);
+#endif
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d for AC %d",
+		  __func__, __LINE__, sessionId, ac);
+	if (sessionId >= CSR_ROAM_SESSION_MAX) {
+		/* err msg */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: sessionId(%d) is invalid",
+			  __func__, __LINE__, sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	pMsg = qdf_mem_malloc(sizeof(tSirAddtsReq));
+	if (!pMsg)
+		return QDF_STATUS_E_NOMEM;
+
+	pMsg->messageType = eWNI_SME_ADDTS_REQ;
+	pMsg->length = sizeof(tSirAddtsReq);
+	pMsg->sessionId = sessionId;
+	pMsg->timeout = 0;
+	pMsg->rspReqd = true;
+	pMsg->req.dialogToken = sme_qos_assign_dialog_token();
+	/* As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum
+	 * Service Interval, Service Start Time, Suspension Interval and Delay
+	 * Bound are all intended for HCCA operation and therefore must be set
+	 * to zero
+	 */
+	pMsg->req.tspec.delayBound = 0;
+	pMsg->req.tspec.inactInterval = pTspec_Info->inactivity_interval;
+	pMsg->req.tspec.length = SME_QOS_TSPEC_IE_LENGTH;
+	pMsg->req.tspec.maxBurstSz = pTspec_Info->max_burst_size;
+	pMsg->req.tspec.maxMsduSz = pTspec_Info->maximum_msdu_size;
+	pMsg->req.tspec.maxSvcInterval = pTspec_Info->max_service_interval;
+	pMsg->req.tspec.meanDataRate = pTspec_Info->mean_data_rate;
+	pMsg->req.tspec.mediumTime = pTspec_Info->medium_time;
+	pMsg->req.tspec.minDataRate = pTspec_Info->min_data_rate;
+	pMsg->req.tspec.minPhyRate = pTspec_Info->min_phy_rate;
+	pMsg->req.tspec.minSvcInterval = pTspec_Info->min_service_interval;
+	pMsg->req.tspec.nomMsduSz = pTspec_Info->nominal_msdu_size;
+	pMsg->req.tspec.peakDataRate = pTspec_Info->peak_data_rate;
+	pMsg->req.tspec.surplusBw = pTspec_Info->surplus_bw_allowance;
+	pMsg->req.tspec.suspendInterval = pTspec_Info->suspension_interval;
+	pMsg->req.tspec.svcStartTime = 0;
+	pMsg->req.tspec.tsinfo.traffic.direction =
+		pTspec_Info->ts_info.direction;
+	/* Make sure UAPSD is allowed */
+	if (pTspec_Info->ts_info.psb) {
+		pMsg->req.tspec.tsinfo.traffic.psb = pTspec_Info->ts_info.psb;
+	} else {
+		pMsg->req.tspec.tsinfo.traffic.psb = 0;
+		pTspec_Info->ts_info.psb = 0;
+	}
+	pMsg->req.tspec.tsinfo.traffic.tsid = pTspec_Info->ts_info.tid;
+	pMsg->req.tspec.tsinfo.traffic.userPrio = pTspec_Info->ts_info.up;
+	pMsg->req.tspec.tsinfo.traffic.accessPolicy =
+		SME_QOS_ACCESS_POLICY_EDCA;
+	pMsg->req.tspec.tsinfo.traffic.burstSizeDefn =
+		pTspec_Info->ts_info.burst_size_defn;
+	pMsg->req.tspec.tsinfo.traffic.ackPolicy =
+		pTspec_Info->ts_info.ack_policy;
+	pMsg->req.tspec.type = SME_QOS_TSPEC_IE_TYPE;
+	/*Fill the BSSID pMsg->req.bssId */
+	if (NULL == pSession->assocInfo.pBssDesc) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: BSS descriptor is NULL so we don't send request to PE",
+			  __func__, __LINE__);
+		qdf_mem_free(pMsg);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_copy(&pMsg->bssid.bytes[0],
+		     &pSession->assocInfo.pBssDesc->bssId[0],
+		     sizeof(struct qdf_mac_addr));
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: up = %d, tid = %d",
+		  __func__, __LINE__,
+		  pTspec_Info->ts_info.up, pTspec_Info->ts_info.tid);
+#ifdef FEATURE_WLAN_ESE
+	if (pCsrSession->connectedProfile.isESEAssoc) {
+		pMsg->req.tsrsIE.tsid = pTspec_Info->ts_info.up;
+		pMsg->req.tsrsPresent = 1;
+	}
+#endif
+	if (QDF_IS_STATUS_SUCCESS(umac_send_mb_message_to_mac(pMsg))) {
+		status = QDF_STATUS_SUCCESS;
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: sent down a ADDTS req to PE",
+			  __func__, __LINE__);
+		/* event: EVENT_WLAN_QOS */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+		qos.eventId = SME_QOS_DIAG_ADDTS_REQ;
+		qos.reasonCode = SME_QOS_DIAG_USER_REQUESTED;
+		WLAN_HOST_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+	}
+	return status;
+}
+
+/*
+ * sme_qos_del_ts_req() - To send down the DELTS request with TSPEC params
+ *  to PE
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * sessionId - Session from which the TSPEC should be deleted
+ * ac - Enumeration of the various EDCA Access Categories.
+ * tspec_mask - on which tspec per AC, the delts is requested
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_del_ts_req(tpAniSirGlobal pMac,
+			      uint8_t sessionId,
+			      sme_QosEdcaAcType ac, uint8_t tspec_mask)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	tSirDeltsReq *pMsg;
+	struct sme_qos_wmmtspecinfo *pTspecInfo;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	WLAN_HOST_DIAG_EVENT_DEF(qos, host_event_wlan_qos_payload_type);
+#endif
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d for AC %d",
+		  __func__, __LINE__, sessionId, ac);
+	pMsg = qdf_mem_malloc(sizeof(tSirDeltsReq));
+	if (!pMsg)
+		return QDF_STATUS_E_NOMEM;
+
+	/* get pointer to the TSPEC being deleted */
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	pACInfo = &pSession->ac_info[ac];
+	pTspecInfo = &pACInfo->curr_QoSInfo[tspec_mask - 1];
+	pMsg->messageType = eWNI_SME_DELTS_REQ;
+	pMsg->length = sizeof(tSirDeltsReq);
+	pMsg->sessionId = sessionId;
+	pMsg->rspReqd = true;
+	pMsg->req.tspec.delayBound = pTspecInfo->delay_bound;
+	pMsg->req.tspec.inactInterval = pTspecInfo->inactivity_interval;
+	pMsg->req.tspec.length = SME_QOS_TSPEC_IE_LENGTH;
+	pMsg->req.tspec.maxBurstSz = pTspecInfo->max_burst_size;
+	pMsg->req.tspec.maxMsduSz = pTspecInfo->maximum_msdu_size;
+	pMsg->req.tspec.maxSvcInterval = pTspecInfo->max_service_interval;
+	pMsg->req.tspec.meanDataRate = pTspecInfo->mean_data_rate;
+	pMsg->req.tspec.mediumTime = pTspecInfo->medium_time;
+	pMsg->req.tspec.minDataRate = pTspecInfo->min_data_rate;
+	pMsg->req.tspec.minPhyRate = pTspecInfo->min_phy_rate;
+	pMsg->req.tspec.minSvcInterval = pTspecInfo->min_service_interval;
+	pMsg->req.tspec.nomMsduSz = pTspecInfo->nominal_msdu_size;
+	pMsg->req.tspec.peakDataRate = pTspecInfo->peak_data_rate;
+	pMsg->req.tspec.surplusBw = pTspecInfo->surplus_bw_allowance;
+	pMsg->req.tspec.suspendInterval = pTspecInfo->suspension_interval;
+	pMsg->req.tspec.svcStartTime = pTspecInfo->svc_start_time;
+	pMsg->req.tspec.tsinfo.traffic.direction =
+		pTspecInfo->ts_info.direction;
+	pMsg->req.tspec.tsinfo.traffic.psb = pTspecInfo->ts_info.psb;
+	pMsg->req.tspec.tsinfo.traffic.tsid = pTspecInfo->ts_info.tid;
+	pMsg->req.tspec.tsinfo.traffic.userPrio = pTspecInfo->ts_info.up;
+	pMsg->req.tspec.tsinfo.traffic.accessPolicy =
+		SME_QOS_ACCESS_POLICY_EDCA;
+	pMsg->req.tspec.tsinfo.traffic.burstSizeDefn =
+		pTspecInfo->ts_info.burst_size_defn;
+	pMsg->req.tspec.tsinfo.traffic.ackPolicy =
+		pTspecInfo->ts_info.ack_policy;
+	pMsg->req.tspec.type = SME_QOS_TSPEC_IE_TYPE;
+	/*Fill the BSSID pMsg->req.bssId */
+	if (NULL == pSession->assocInfo.pBssDesc) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: BSS descriptor is NULL so we don't send request to PE",
+			  __func__, __LINE__);
+		qdf_mem_free(pMsg);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_copy(&pMsg->bssid.bytes[0],
+		     &pSession->assocInfo.pBssDesc->bssId[0],
+		     sizeof(struct qdf_mac_addr));
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: up = %d, tid = %d",
+		  __func__, __LINE__,
+		  pTspecInfo->ts_info.up, pTspecInfo->ts_info.tid);
+	qdf_mem_zero(&pACInfo->curr_QoSInfo[tspec_mask - 1],
+		     sizeof(struct sme_qos_wmmtspecinfo));
+
+	if (!QDF_IS_STATUS_SUCCESS(umac_send_mb_message_to_mac(pMsg))) {
+		sme_err("DELTS req to PE failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_debug("sent down a DELTS req to PE");
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	qos.eventId = SME_QOS_DIAG_DELTS;
+	qos.reasonCode = SME_QOS_DIAG_USER_REQUESTED;
+	WLAN_HOST_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS);
+#endif
+
+	sme_set_tspec_uapsd_mask_per_session(pMac, &pMsg->req.tspec.tsinfo,
+					     sessionId);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_process_add_ts_rsp() - Function to process the
+ *  eWNI_SME_ADDTS_RSP came from PE
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * pMsgBuf - Pointer to the msg buffer came from PE.
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_add_ts_rsp(tpAniSirGlobal pMac, void *pMsgBuf)
+{
+	tpSirAddtsRsp paddts_rsp = (tpSirAddtsRsp) pMsgBuf;
+	struct sme_qos_sessioninfo *pSession;
+	uint8_t sessionId = paddts_rsp->sessionId;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	enum sme_qos_wmmuptype up =
+		(enum sme_qos_wmmuptype)
+		paddts_rsp->rsp.tspec.tsinfo.traffic.userPrio;
+	struct sme_qos_acinfo *pACInfo;
+	sme_QosEdcaAcType ac;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	WLAN_HOST_DIAG_EVENT_DEF(qos, host_event_wlan_qos_payload_type);
+#endif
+
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d for UP %d",
+		  __func__, __LINE__, sessionId, up);
+
+	ac = sme_qos_up_to_ac(up);
+	if (SME_QOS_EDCA_AC_MAX == ac) {
+		/* err msg */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: invalid AC %d from UP %d",
+			  __func__, __LINE__, ac, up);
+
+		return QDF_STATUS_E_FAILURE;
+	}
+	pACInfo = &pSession->ac_info[ac];
+	if (SME_QOS_HANDOFF == pACInfo->curr_state) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			"ADDTS Rsp received for AC %d in HANDOFF State. Dropping",
+			ac);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: Invoked on session %d with return code %d",
+		  __func__, __LINE__, sessionId, paddts_rsp->rc);
+	if (paddts_rsp->rc) {
+		/* event: EVENT_WLAN_QOS */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+		qos.eventId = SME_QOS_DIAG_ADDTS_RSP;
+		qos.reasonCode = SME_QOS_DIAG_ADDTS_REFUSED;
+		WLAN_HOST_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+		status =
+			sme_qos_process_add_ts_failure_rsp(pMac, sessionId,
+							   &paddts_rsp->rsp);
+	} else {
+		status =
+			sme_qos_process_add_ts_success_rsp(pMac, sessionId,
+							   &paddts_rsp->rsp);
+	}
+	return status;
+}
+
+/*
+ * sme_qos_process_del_ts_rsp() - Function to process the
+ *  eWNI_SME_DELTS_RSP came from PE
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * pMsgBuf - Pointer to the msg buffer came from PE.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_del_ts_rsp(tpAniSirGlobal pMac, void *pMsgBuf)
+{
+	tpSirDeltsRsp pDeltsRsp = (tpSirDeltsRsp) pMsgBuf;
+	struct sme_qos_sessioninfo *pSession;
+	uint8_t sessionId = pDeltsRsp->sessionId;
+
+	/* msg */
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: Invoked on session %d with return code %d",
+		  __func__, __LINE__, sessionId, pDeltsRsp->rc);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	(void)sme_qos_process_buffered_cmd(sessionId);
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_process_del_ts_ind() - Function to process the
+ *  eWNI_SME_DELTS_IND came from PE
+ *
+ * Since it's a DELTS indication from AP, will notify all the flows running on
+ * this AC about QoS release
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * pMsgBuf - Pointer to the msg buffer came from PE.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_del_ts_ind(tpAniSirGlobal pMac, void *pMsgBuf)
+{
+	tpSirDeltsRsp pdeltsind = (tpSirDeltsRsp) pMsgBuf;
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	uint8_t sessionId = pdeltsind->sessionId;
+	sme_QosEdcaAcType ac;
+	struct sme_qos_searchinfo search_key;
+	tSirMacTSInfo *tsinfo;
+	enum sme_qos_wmmuptype up =
+		(enum sme_qos_wmmuptype)
+		pdeltsind->rsp.tspec.tsinfo.traffic.userPrio;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	WLAN_HOST_DIAG_EVENT_DEF(qos, host_event_wlan_qos_payload_type);
+#endif
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: Invoked on session %d for UP %d",
+		  __func__, __LINE__, sessionId, up);
+	tsinfo = &pdeltsind->rsp.tspec.tsinfo;
+	ac = sme_qos_up_to_ac(up);
+	if (SME_QOS_EDCA_AC_MAX == ac) {
+		/* err msg */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: invalid AC %d from UP %d",
+			  __func__, __LINE__, ac, up);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	pACInfo = &pSession->ac_info[ac];
+
+	qdf_mem_zero(&search_key, sizeof(struct sme_qos_searchinfo));
+	/* set the key type & the key to be searched in the Flow List */
+	search_key.key.ac_type = ac;
+	search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
+	search_key.sessionId = sessionId;
+	/* find all Flows on the perticular AC & delete them, also send HDD
+	 * indication through the callback it registered per request
+	 */
+	if (!QDF_IS_STATUS_SUCCESS
+		    (sme_qos_find_all_in_flow_list(pMac, search_key,
+						sme_qos_del_ts_ind_fnp))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: no match found for ac = %d", __func__,
+			  __LINE__, search_key.key.ac_type);
+		return QDF_STATUS_E_FAILURE;
+	}
+	sme_set_tspec_uapsd_mask_per_session(pMac, tsinfo, sessionId);
+/* event: EVENT_WLAN_QOS */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	qos.eventId = SME_QOS_DIAG_DELTS;
+	qos.reasonCode = SME_QOS_DIAG_DELTS_IND_FROM_AP;
+	WLAN_HOST_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_process_assoc_complete_ev() - Function to process the
+ *  SME_QOS_CSR_ASSOC_COMPLETE event indication from CSR
+ *
+ * pEvent_info - Pointer to relevant info from CSR.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_assoc_complete_ev(tpAniSirGlobal pMac, uint8_t
+						sessionId, void *pEvent_info)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	sme_QosEdcaAcType ac = SME_QOS_EDCA_AC_BE;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d",
+		  __func__, __LINE__, sessionId);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	if (((SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_BE].curr_state)
+	     && (SME_QOS_INIT ==
+		 pSession->ac_info[SME_QOS_EDCA_AC_BK].curr_state)
+	     && (SME_QOS_INIT ==
+		 pSession->ac_info[SME_QOS_EDCA_AC_VI].curr_state)
+	     && (SME_QOS_INIT ==
+		 pSession->ac_info[SME_QOS_EDCA_AC_VO].curr_state))
+	    || (pSession->handoffRequested)) {
+		/* get the association info */
+		if (!pEvent_info) {
+			/* err msg */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: pEvent_info is NULL",
+				  __func__, __LINE__);
+			return status;
+		}
+		if (!((sme_QosAssocInfo *) pEvent_info)->pBssDesc) {
+			/* err msg */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: pBssDesc is NULL",
+				  __func__, __LINE__);
+			return status;
+		}
+		if ((pSession->assocInfo.pBssDesc) &&
+		    (csr_is_bssid_match
+			     ((struct qdf_mac_addr *)
+					&pSession->assocInfo.pBssDesc->bssId,
+			     (struct qdf_mac_addr *) &(((sme_QosAssocInfo *)
+					pEvent_info)->pBssDesc->bssId)))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: assoc with the same BSS, no update needed",
+				  __func__, __LINE__);
+		} else
+			status = sme_qos_save_assoc_info(pSession, pEvent_info);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: wrong state: BE %d, BK %d, VI %d, VO %d",
+			  __func__, __LINE__,
+			  pSession->ac_info[SME_QOS_EDCA_AC_BE].curr_state,
+			  pSession->ac_info[SME_QOS_EDCA_AC_BK].curr_state,
+			  pSession->ac_info[SME_QOS_EDCA_AC_VI].curr_state,
+			  pSession->ac_info[SME_QOS_EDCA_AC_VO].curr_state);
+		return status;
+	}
+	/* the session is active */
+	pSession->sessionActive = true;
+	if (pSession->handoffRequested) {
+		pSession->handoffRequested = false;
+		/* renew all flows */
+		(void)sme_qos_process_buffered_cmd(sessionId);
+		status = QDF_STATUS_SUCCESS;
+	} else {
+		for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+			pACInfo = &pSession->ac_info[ac];
+			switch (pACInfo->curr_state) {
+			case SME_QOS_INIT:
+				sme_qos_state_transition(sessionId, ac,
+							 SME_QOS_LINK_UP);
+				break;
+			case SME_QOS_LINK_UP:
+			case SME_QOS_REQUESTED:
+			case SME_QOS_QOS_ON:
+			case SME_QOS_HANDOFF:
+			case SME_QOS_CLOSED:
+			default:
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "%s: %d: On session %d AC %d is in wrong state %d",
+					  __func__, __LINE__, sessionId, ac,
+					  pACInfo->curr_state);
+				break;
+			}
+		}
+	}
+	return status;
+}
+
+/*
+ * sme_qos_process_reassoc_req_ev() - Function to process the
+ *  SME_QOS_CSR_REASSOC_REQ event indication from CSR
+ *
+ * pEvent_info - Pointer to relevant info from CSR.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_reassoc_req_ev(tpAniSirGlobal pMac, uint8_t
+						sessionId, void *pEvent_info)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	sme_QosEdcaAcType ac;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	tListElem *entry = NULL;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_HIGH,
+		  "%s: %d: invoked on session %d",
+		  __func__, __LINE__, sessionId);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+
+	if (pSession->ftHandoffInProgress) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: %d: no need for state transition, should "
+			  "already be in handoff state", __func__, __LINE__);
+		if ((pSession->ac_info[0].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[1].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[2].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[3].curr_state != SME_QOS_HANDOFF)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("curr_state is not HANDOFF, session %d"),
+					 sessionId);
+			return QDF_STATUS_E_FAILURE;
+		}
+		sme_qos_process_ft_reassoc_req_ev(sessionId);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (pSession->handoffRequested) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: no need for state transition, should already be in handoff state",
+			__func__, __LINE__);
+
+		if ((pSession->ac_info[0].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[1].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[2].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[3].curr_state != SME_QOS_HANDOFF)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("curr_state is not HANDOFF, session %d"),
+					 sessionId);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		/*
+		 * Now change reason and HO renewal of
+		 * all the flow in this session only
+		 */
+		entry = csr_ll_peek_head(&sme_qos_cb.flow_list, false);
+		if (!entry) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				FL("Flow List empty, nothing to update"));
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		do {
+			flow_info = GET_BASE_ADDR(entry, struct sme_qos_flowinfoentry,
+						  link);
+			if (sessionId == flow_info->sessionId) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_INFO_HIGH,
+					  FL("Changing FlowID %d reason to"
+					     " SETUP and HO renewal to true"),
+					  flow_info->QosFlowID);
+				flow_info->reason = SME_QOS_REASON_SETUP;
+				flow_info->hoRenewal = true;
+			}
+			entry = csr_ll_next(&sme_qos_cb.flow_list, entry,
+					    false);
+		} while (entry);
+
+		/* buffer the existing flows to be renewed after handoff is
+		 * done
+		 */
+		sme_qos_buffer_existing_flows(pMac, sessionId);
+		/* clean up the control block partially for handoff */
+		sme_qos_cleanup_ctrl_blk_for_handoff(pMac, sessionId);
+		return QDF_STATUS_SUCCESS;
+	}
+/* TBH: Assuming both handoff algo & 11r willn't be enabled at the same time */
+	if (pSession->ftHandoffInProgress) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: no need for state transition, should already be in handoff state",
+			__func__, __LINE__);
+
+		if ((pSession->ac_info[0].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[1].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[2].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[3].curr_state != SME_QOS_HANDOFF)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("curr_state is not HANDOFF, session %d"),
+					 sessionId);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		sme_qos_process_ft_reassoc_req_ev(sessionId);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		pACInfo = &pSession->ac_info[ac];
+		switch (pACInfo->curr_state) {
+		case SME_QOS_LINK_UP:
+		case SME_QOS_REQUESTED:
+		case SME_QOS_QOS_ON:
+			sme_qos_state_transition(sessionId, ac,
+						SME_QOS_HANDOFF);
+			break;
+		case SME_QOS_HANDOFF:
+			/* This is normal because sme_qos_request_reassoc may
+			 * already change the state
+			 */
+			break;
+		case SME_QOS_CLOSED:
+		case SME_QOS_INIT:
+		default:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: On session %d AC %d is in wrong state %d",
+				  __func__, __LINE__,
+				  sessionId, ac, pACInfo->curr_state);
+			break;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_handle_handoff_state() - utility function called by
+ *                                  sme_qos_process_reassoc_success_ev
+ * @mac_ctx: global MAC context
+ * @qos_session: QOS session
+ * @ac_info: AC information
+ * @ac: current AC index
+ * @sessionid: session id
+ *
+ * This function is called by sme_qos_process_reassoc_success_ev
+ * to update the state machine on the reception of reassoc success
+ * notificaiton
+ *
+ * Return: QDF_STATUS
+ */
+static
+QDF_STATUS sme_qos_handle_handoff_state(tpAniSirGlobal mac_ctx,
+		struct sme_qos_sessioninfo *qos_session,
+		struct sme_qos_acinfo *ac_info,
+		sme_QosEdcaAcType ac, uint8_t sessionid)
+
+{
+	struct sme_qos_searchinfo search_key;
+	struct sme_qos_searchinfo search_key1;
+	sme_QosEdcaAcType ac_index;
+	tListElem *list_elt = NULL;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	/* return to our previous state */
+	sme_qos_state_transition(sessionid, ac, ac_info->prev_state);
+	/* for which ac APSD (hence the reassoc) is requested */
+	if (!ac_info->reassoc_pending)
+		return QDF_STATUS_SUCCESS;
+
+	/*
+	 * update the apsd mask in CB - make sure to take care of the
+	 * case where we are resetting the bit in apsd_mask
+	 */
+	if (ac_info->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.psb)
+		qos_session->apsdMask |= 1 << (SME_QOS_EDCA_AC_VO - ac);
+	else
+		qos_session->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac));
+
+	ac_info->reassoc_pending = false;
+	/*
+	 * during setup it gets set as addts & reassoc both gets a
+	 * pending flag ac_info->tspec_pending = 0;
+	 */
+	sme_qos_state_transition(sessionid, ac, SME_QOS_QOS_ON);
+	/* notify HDD with new Service Interval */
+	ac_info->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] =
+		ac_info->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0];
+	qdf_mem_zero(&search_key, sizeof(struct sme_qos_searchinfo));
+	/* set the key type & the key to be searched in the Flow List */
+	search_key.key.ac_type = ac;
+	search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
+	search_key.sessionId = sessionid;
+	/* notify PMC that reassoc is done for APSD on certain AC?? */
+
+	qdf_mem_zero(&search_key1, sizeof(struct sme_qos_searchinfo));
+	/* set the hoRenewal field in control block if needed */
+	search_key1.index = SME_QOS_SEARCH_KEY_INDEX_3;
+	search_key1.key.reason = SME_QOS_REASON_SETUP;
+	search_key1.sessionId = sessionid;
+	for (ac_index = SME_QOS_EDCA_AC_BE; ac_index < SME_QOS_EDCA_AC_MAX;
+	     ac_index++) {
+		list_elt = sme_qos_find_in_flow_list(search_key1);
+		if (list_elt) {
+			flow_info = GET_BASE_ADDR(list_elt,
+					struct sme_qos_flowinfoentry, link);
+			if (flow_info->ac_type == ac) {
+				ac_info->hoRenewal = flow_info->hoRenewal;
+				break;
+			}
+		}
+	}
+	/*
+	 * notify HDD the success for the requested flow notify all the
+	 * other flows running on the AC that QoS got modified
+	 */
+	status = sme_qos_find_all_in_flow_list(mac_ctx, search_key,
+			sme_qos_reassoc_success_ev_fnp);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("no match found for ac = %d"),
+			  search_key.key.ac_type);
+		return QDF_STATUS_E_FAILURE;
+	}
+	ac_info->hoRenewal = false;
+	qdf_mem_zero(&ac_info->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0],
+		     sizeof(struct sme_qos_wmmtspecinfo));
+
+	return status;
+}
+
+/**
+ * sme_qos_process_reassoc_success_ev() - process SME_QOS_CSR_REASSOC_COMPLETE
+ *
+ * @mac_ctx: global MAC context
+ * @sessionid: session ID
+ * @event_info: event buffer from CSR
+ *
+ * Function to process the SME_QOS_CSR_REASSOC_COMPLETE event indication
+ * from CSR
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_reassoc_success_ev(tpAniSirGlobal mac_ctx,
+				uint8_t sessionid, void *event_info)
+{
+
+	struct csr_roam_session *csr_roam_session = NULL;
+	struct sme_qos_sessioninfo *qos_session;
+	struct sme_qos_acinfo *ac_info;
+	sme_QosEdcaAcType ac;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("invoked on session %d"), sessionid);
+
+	if (CSR_ROAM_SESSION_MAX <= sessionid) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("invoked on session %d"), sessionid);
+		return status;
+	}
+
+	csr_roam_session = CSR_GET_SESSION(mac_ctx, sessionid);
+
+	qos_session = &sme_qos_cb.sessionInfo[sessionid];
+
+	/* get the association info */
+	if (!event_info) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("event_info is NULL"));
+		return status;
+	}
+
+	if (!((sme_QosAssocInfo *) event_info)->pBssDesc) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("pBssDesc is NULL"));
+		return status;
+	}
+	status = sme_qos_save_assoc_info(qos_session, event_info);
+	if (status)
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("sme_qos_save_assoc_info() failed"));
+
+	/*
+	 * Assuming both handoff algo & 11r willn't be enabled
+	 * at the same time
+	 */
+	if (qos_session->handoffRequested) {
+		qos_session->handoffRequested = false;
+		/* renew all flows */
+		(void)sme_qos_process_buffered_cmd(sessionid);
+		return QDF_STATUS_SUCCESS;
+	}
+	if (qos_session->ftHandoffInProgress) {
+		if (csr_roam_is11r_assoc(mac_ctx, sessionid)) {
+			if (csr_roam_session &&
+			    csr_roam_session->connectedInfo.nRICRspLength) {
+				status = sme_qos_process_ft_reassoc_rsp_ev(
+						mac_ctx, sessionid,
+						event_info);
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					QDF_TRACE_LEVEL_ERROR, FL(
+					"session or RIC data is not present"));
+			}
+		}
+#ifdef FEATURE_WLAN_ESE
+		/*
+		 * If ESE association check for TSPEC IEs in the
+		 * reassoc rsp frame
+		 */
+		if (csr_roam_is_ese_assoc(mac_ctx, sessionid)) {
+			if (csr_roam_session &&
+			    csr_roam_session->connectedInfo.nTspecIeLength) {
+				status = sme_qos_ese_process_reassoc_tspec_rsp(
+						mac_ctx, sessionid, event_info);
+			}
+		}
+#endif
+		qos_session->ftHandoffInProgress = false;
+		qos_session->handoffRequested = false;
+		return status;
+	}
+
+	qos_session->sessionActive = true;
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		ac_info = &qos_session->ac_info[ac];
+		switch (ac_info->curr_state) {
+		case SME_QOS_HANDOFF:
+			status = sme_qos_handle_handoff_state(mac_ctx,
+					qos_session, ac_info, ac, sessionid);
+			break;
+		case SME_QOS_INIT:
+		case SME_QOS_CLOSED:
+			/* NOP */
+			status = QDF_STATUS_SUCCESS;
+			break;
+		case SME_QOS_LINK_UP:
+		case SME_QOS_REQUESTED:
+		case SME_QOS_QOS_ON:
+		default:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("session %d AC %d is in wrong state %d"),
+				  sessionid, ac, ac_info->curr_state);
+			break;
+		}
+	}
+	(void)sme_qos_process_buffered_cmd(sessionid);
+	return status;
+}
+
+/*
+ * sme_qos_process_reassoc_failure_ev() - Function to process the
+ *  SME_QOS_CSR_REASSOC_FAILURE event indication from CSR
+ *
+ * pEvent_info - Pointer to relevant info from CSR.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_reassoc_failure_ev(tpAniSirGlobal pMac,
+					   uint8_t sessionId, void *pEvent_info)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	sme_QosEdcaAcType ac;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d",
+		  __func__, __LINE__, sessionId);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		pACInfo = &pSession->ac_info[ac];
+		switch (pACInfo->curr_state) {
+		case SME_QOS_HANDOFF:
+			sme_qos_state_transition(sessionId, ac, SME_QOS_INIT);
+			if (pACInfo->reassoc_pending)
+				pACInfo->reassoc_pending = false;
+
+			qdf_mem_zero(&pACInfo->
+				     curr_QoSInfo[SME_QOS_TSPEC_INDEX_0],
+				     sizeof(struct sme_qos_wmmtspecinfo));
+			qdf_mem_zero(&pACInfo->
+				     requested_QoSInfo[SME_QOS_TSPEC_INDEX_0],
+				     sizeof(struct sme_qos_wmmtspecinfo));
+			qdf_mem_zero(&pACInfo->
+				     curr_QoSInfo[SME_QOS_TSPEC_INDEX_1],
+				     sizeof(struct sme_qos_wmmtspecinfo));
+			qdf_mem_zero(&pACInfo->
+				     requested_QoSInfo[SME_QOS_TSPEC_INDEX_1],
+				     sizeof(struct sme_qos_wmmtspecinfo));
+			pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_CLEAR;
+			pACInfo->tspec_pending = 0;
+			pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0] = 0;
+			pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] = 0;
+			break;
+		case SME_QOS_INIT:
+		case SME_QOS_CLOSED:
+			/* NOP */
+			break;
+		case SME_QOS_LINK_UP:
+		case SME_QOS_REQUESTED:
+		case SME_QOS_QOS_ON:
+		default:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: On session %d AC %d is in wrong state %d",
+				  __func__, __LINE__,
+				  sessionId, ac, pACInfo->curr_state);
+			break;
+		}
+	}
+	/* need to clean up flows */
+	sme_qos_delete_existing_flows(pMac, sessionId);
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_process_handoff_assoc_req_ev() - Function to process the
+ *  SME_QOS_CSR_HANDOFF_ASSOC_REQ event indication from CSR
+ *
+ * pEvent_info - Pointer to relevant info from CSR.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_handoff_assoc_req_ev(tpAniSirGlobal pMac,
+					uint8_t sessionId, void *pEvent_info)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	uint8_t ac;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d",
+		  __func__, __LINE__, sessionId);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		pACInfo = &pSession->ac_info[ac];
+		switch (pACInfo->curr_state) {
+		case SME_QOS_LINK_UP:
+		case SME_QOS_REQUESTED:
+		case SME_QOS_QOS_ON:
+			sme_qos_state_transition(sessionId, ac,
+						SME_QOS_HANDOFF);
+			break;
+		case SME_QOS_HANDOFF:
+			/* print error msg */
+			if (pSession->ftHandoffInProgress) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "%s: %d: SME_QOS_CSR_HANDOFF_ASSOC_REQ received in SME_QOS_HANDOFF state with FT in progress",
+					  __func__, __LINE__);
+				break;
+			}
+
+		case SME_QOS_CLOSED:
+		case SME_QOS_INIT:
+		default:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: On session %d AC %d is in wrong state %d",
+				  __func__, __LINE__,
+				  sessionId, ac, pACInfo->curr_state);
+			break;
+		}
+	}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (csr_roam_is11r_assoc(pMac, sessionId))
+		pSession->ftHandoffInProgress = true;
+#endif
+	/* If FT handoff/ESE in progress, legacy handoff need not be enabled */
+	if (!pSession->ftHandoffInProgress
+#ifdef FEATURE_WLAN_ESE
+	    && !csr_roam_is_ese_assoc(pMac, sessionId)
+#endif
+	   )
+		pSession->handoffRequested = true;
+
+	/* this session no longer needs UAPSD */
+	pSession->apsdMask = 0;
+	/* do any sessions still require UAPSD? */
+	sme_ps_uapsd_disable(MAC_HANDLE(pMac), sessionId);
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_process_handoff_success_ev() - Function to process the
+ *  SME_QOS_CSR_HANDOFF_COMPLETE event indication from CSR
+ *
+ * pEvent_info - Pointer to relevant info from CSR.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_handoff_success_ev(tpAniSirGlobal pMac,
+					   uint8_t sessionId, void *pEvent_info)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	uint8_t ac;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d",
+		  __func__, __LINE__, sessionId);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	/* go back to original state before handoff */
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		pACInfo = &pSession->ac_info[ac];
+		switch (pACInfo->curr_state) {
+		case SME_QOS_HANDOFF:
+			sme_qos_state_transition(sessionId, ac,
+						 pACInfo->prev_state);
+			/* we will retry for the requested flow(s) with the
+			 * new AP
+			 */
+			if (SME_QOS_REQUESTED == pACInfo->curr_state)
+				pACInfo->curr_state = SME_QOS_LINK_UP;
+
+			status = QDF_STATUS_SUCCESS;
+			break;
+		/* FT logic, has already moved it to QOS_REQUESTED state during
+		 * the reassoc request event, which would include the Qos
+		 * (TSPEC) params in the reassoc req frame
+		 */
+		case SME_QOS_REQUESTED:
+			break;
+		case SME_QOS_INIT:
+		case SME_QOS_CLOSED:
+		case SME_QOS_LINK_UP:
+		case SME_QOS_QOS_ON:
+		default:
+/* In case of 11r - RIC, we request QoS and Hand-off at the same time hence the
+ *  state may be SME_QOS_REQUESTED
+ */
+			if (pSession->ftHandoffInProgress)
+				break;
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: On session %d AC %d is in wrong state %d",
+				  __func__, __LINE__,
+				  sessionId, ac, pACInfo->curr_state);
+			break;
+		}
+	}
+	return status;
+}
+
+/*
+ * sme_qos_process_disconnect_ev() - Function to process the
+ *  SME_QOS_CSR_DISCONNECT_REQ or  SME_QOS_CSR_DISCONNECT_IND event indication
+ *  from CSR
+ *
+ * pEvent_info - Pointer to relevant info from CSR.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_disconnect_ev(tpAniSirGlobal pMac, uint8_t
+					sessionId, void *pEvent_info)
+{
+	struct sme_qos_sessioninfo *pSession;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d",
+		  __func__, __LINE__, sessionId);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	/*
+	 * In case of 11r - RIC, we request QoS and Hand-off at the
+	 * same time hence the state may be SME_QOS_REQUESTED
+	 */
+	if ((pSession->handoffRequested)
+	    && !pSession->ftHandoffInProgress) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: no need for state transition, should already be in handoff state",
+			__func__, __LINE__);
+		if ((pSession->ac_info[0].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[1].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[2].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[3].curr_state != SME_QOS_HANDOFF)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("curr_state is not HANDOFF, session %d"),
+					 sessionId);
+			return QDF_STATUS_SUCCESS;
+		}
+
+		return QDF_STATUS_SUCCESS;
+	}
+	sme_qos_init_a_cs(pMac, sessionId);
+	/* this session doesn't require UAPSD */
+	pSession->apsdMask = 0;
+
+	sme_ps_uapsd_disable(MAC_HANDLE(pMac), sessionId);
+
+	pSession->handoffRequested = false;
+	pSession->roamID = 0;
+	/* need to clean up buffered req */
+	sme_qos_delete_buffered_requests(pMac, sessionId);
+	/* need to clean up flows */
+	sme_qos_delete_existing_flows(pMac, sessionId);
+	/* clean up the assoc info */
+	if (pSession->assocInfo.pBssDesc) {
+		qdf_mem_free(pSession->assocInfo.pBssDesc);
+		pSession->assocInfo.pBssDesc = NULL;
+	}
+	sme_qos_cb.sessionInfo[sessionId].sessionActive = false;
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_process_join_req_ev() - Function to process the
+ *  SME_QOS_CSR_JOIN_REQ event indication from CSR
+ *
+ * pEvent_info - Pointer to relevant info from CSR.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_join_req_ev(tpAniSirGlobal pMac, uint8_t
+						sessionId, void *pEvent_info)
+{
+	struct sme_qos_sessioninfo *pSession;
+	sme_QosEdcaAcType ac;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d",
+		  __func__, __LINE__, sessionId);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	if (pSession->handoffRequested) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: no need for state transition, should already be in handoff state",
+			__func__, __LINE__);
+		if ((pSession->ac_info[0].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[1].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[2].curr_state != SME_QOS_HANDOFF) ||
+		    (pSession->ac_info[3].curr_state != SME_QOS_HANDOFF))
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("curr_state is not HANDOFF, session %d"),
+					 sessionId);
+		/* buffer the existing flows to be renewed after handoff is
+		 * done
+		 */
+		sme_qos_buffer_existing_flows(pMac, sessionId);
+		/* clean up the control block partially for handoff */
+		sme_qos_cleanup_ctrl_blk_for_handoff(pMac, sessionId);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++)
+		sme_qos_state_transition(sessionId, ac, SME_QOS_INIT);
+
+	/* clean up the assoc info if already set */
+	if (pSession->assocInfo.pBssDesc) {
+		qdf_mem_free(pSession->assocInfo.pBssDesc);
+		pSession->assocInfo.pBssDesc = NULL;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_process_preauth_success_ind() - process preauth success indication
+ * @mac_ctx: global MAC context
+ * @sessionid: session ID
+ * @event_info: event buffer
+ *
+ * Function to process the SME_QOS_CSR_PREAUTH_SUCCESS_IND event indication
+ * from CSR
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_preauth_success_ind(tpAniSirGlobal mac_ctx,
+				uint8_t sessionid, void *event_info)
+{
+	struct sme_qos_sessioninfo *qos_session;
+	struct csr_roam_session *sme_session = CSR_GET_SESSION(mac_ctx,
+							       sessionid);
+	struct sme_qos_acinfo *ac_info;
+	uint8_t ac;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint16_t ric_offset = 0;
+	uint32_t ric_ielen = 0;
+	uint8_t *ric_ie;
+	uint8_t tspec_mask_status = 0;
+	uint8_t tspec_pending_status = 0;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("invoked on SME session %d"), sessionid);
+
+	if (NULL == sme_session) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("sme_session is NULL"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qos_session = &sme_qos_cb.sessionInfo[sessionid];
+
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		ac_info = &qos_session->ac_info[ac];
+
+		switch (ac_info->curr_state) {
+		case SME_QOS_LINK_UP:
+		case SME_QOS_REQUESTED:
+		case SME_QOS_QOS_ON:
+		    sme_qos_state_transition(sessionid, ac, SME_QOS_HANDOFF);
+			break;
+		case SME_QOS_HANDOFF:
+		/* print error msg */
+		case SME_QOS_CLOSED:
+		case SME_QOS_INIT:
+		default:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("Session %d AC %d is in wrong state %d"),
+				  sessionid, ac, ac_info->curr_state);
+			break;
+		}
+	}
+
+	qos_session->ftHandoffInProgress = true;
+
+	/* Check if its a 11R roaming before preparing the RIC IEs */
+	if (!csr_roam_is11r_assoc(mac_ctx, sessionid))
+		return status;
+
+	/* Data is accessed from saved PreAuth Rsp */
+	if (NULL == sme_session->ftSmeContext.psavedFTPreAuthRsp) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("psavedFTPreAuthRsp is NULL"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/*
+	 * Any Block Ack info there, should have been already filled by PE and
+	 * present in this buffer and the ric_ies_length should contain the
+	 * length of the whole RIC IEs. Filling of TSPEC info should start
+	 * from this length
+	 */
+	ric_ie = sme_session->ftSmeContext.psavedFTPreAuthRsp->ric_ies;
+	ric_offset =
+		sme_session->ftSmeContext.psavedFTPreAuthRsp->ric_ies_length;
+
+	/*
+	 * Now we have to process the currentTspeInfo inside this session and
+	 * create the RIC IEs
+	 */
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		volatile uint8_t tspec_idx = 0;
+
+		ric_ielen = 0;
+		ac_info = &qos_session->ac_info[ac];
+		tspec_pending_status = ac_info->tspec_pending;
+		tspec_mask_status = ac_info->tspec_mask_status;
+		qdf_mem_zero(ac_info->ricIdentifier, SME_QOS_TSPEC_INDEX_MAX);
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("AC %d ==> TSPEC status = %d, tspec pending = %d"),
+			  ac, tspec_mask_status, tspec_pending_status);
+
+		do {
+			if (!(tspec_mask_status & 0x1))
+				goto add_next_ric;
+
+			/*
+			 * If a tspec status is pending, take requested_QoSInfo
+			 * for RIC request, else use curr_QoSInfo for the
+			 * RIC request
+			 */
+			if (tspec_pending_status & 0x1) {
+				status = sme_qos_create_tspec_ricie(mac_ctx,
+					&ac_info->requested_QoSInfo[tspec_idx],
+					ric_ie + ric_offset, &ric_ielen,
+					&ac_info->ricIdentifier[tspec_idx]);
+			} else {
+				status = sme_qos_create_tspec_ricie(mac_ctx,
+					&ac_info->curr_QoSInfo[tspec_idx],
+					ric_ie + ric_offset, &ric_ielen,
+					&ac_info->ricIdentifier[tspec_idx]);
+			}
+add_next_ric:
+			ric_offset += ric_ielen;
+			sme_session->ftSmeContext.psavedFTPreAuthRsp->
+				ric_ies_length += ric_ielen;
+			tspec_mask_status >>= 1;
+			tspec_pending_status >>= 1;
+			tspec_idx++;
+		} while (tspec_mask_status);
+	}
+	return status;
+}
+
+/*
+ * sme_qos_process_add_ts_failure_rsp() - Function to process the
+ *  Addts request failure response came from PE
+ *
+ * We will notify HDD only for the requested Flow, other Flows running on the AC
+ * stay intact
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * pRsp - Pointer to the addts response structure came from PE.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_add_ts_failure_rsp(tpAniSirGlobal pMac,
+					      uint8_t sessionId,
+					      tSirAddtsRspInfo *pRsp)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	sme_QosEdcaAcType ac;
+	struct sme_qos_searchinfo search_key;
+	uint8_t tspec_pending;
+	enum sme_qos_wmmuptype up =
+		(enum sme_qos_wmmuptype) pRsp->tspec.tsinfo.traffic.userPrio;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d for UP %d", __func__, __LINE__,
+		  sessionId, up);
+	ac = sme_qos_up_to_ac(up);
+	if (SME_QOS_EDCA_AC_MAX == ac) {
+		/* err msg */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: invalid AC %d from UP %d",
+			  __func__, __LINE__, ac, up);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	pACInfo = &pSession->ac_info[ac];
+	/* is there a TSPEC request pending on this AC? */
+	tspec_pending = pACInfo->tspec_pending;
+	if (!tspec_pending) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: On session %d an AddTS is not pending on AC %d",
+			  __func__, __LINE__, sessionId, ac);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_zero(&search_key, sizeof(struct sme_qos_searchinfo));
+	/* set the key type & the key to be searched in the Flow List */
+	search_key.key.ac_type = ac;
+	search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
+	search_key.sessionId = sessionId;
+	if (!QDF_IS_STATUS_SUCCESS
+		    (sme_qos_find_all_in_flow_list
+			    (pMac, search_key, sme_qos_add_ts_failure_fnp))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: On session %d no match found for ac = %d",
+			  __func__, __LINE__, sessionId,
+			  search_key.key.ac_type);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_zero(&pACInfo->requested_QoSInfo[tspec_pending - 1],
+		     sizeof(struct sme_qos_wmmtspecinfo));
+
+	if ((!pACInfo->num_flows[0]) && (!pACInfo->num_flows[1])) {
+		pACInfo->tspec_mask_status &= SME_QOS_TSPEC_MASK_BIT_1_2_SET &
+					      (~pACInfo->tspec_pending);
+		sme_qos_state_transition(sessionId, ac, SME_QOS_LINK_UP);
+	} else
+		sme_qos_state_transition(sessionId, ac, SME_QOS_QOS_ON);
+
+	pACInfo->tspec_pending = 0;
+
+	(void)sme_qos_process_buffered_cmd(sessionId);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_update_tspec_mask() - Utility function to update the tspec.
+ * @sessionid: Session upon which the TSPEC is being updated
+ * @search_key: search key
+ * @new_tspec_mask: tspec to be set for this AC
+ *
+ * Typical usage while aggregating unidirectional flows into a bi-directional
+ * flow on AC which is running multiple flows
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_qos_update_tspec_mask(uint8_t sessionid,
+					    struct sme_qos_searchinfo
+						search_key,
+					    uint8_t new_tspec_mask)
+{
+	tListElem *list_elt = NULL, *list_next_elt = NULL;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	struct sme_qos_sessioninfo *qos_session;
+	struct sme_qos_acinfo *ac_info;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("invoked on session %d for AC %d TSPEC %d"),
+		  sessionid, search_key.key.ac_type, new_tspec_mask);
+
+	qos_session = &sme_qos_cb.sessionInfo[sessionid];
+
+	if (search_key.key.ac_type < SME_QOS_EDCA_AC_MAX) {
+		ac_info = &qos_session->ac_info[search_key.key.ac_type];
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("Exceeded the array bounds"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	list_elt = csr_ll_peek_head(&sme_qos_cb.flow_list, false);
+	if (!list_elt) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Flow List empty, nothing to update"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	while (list_elt) {
+		list_next_elt = csr_ll_next(&sme_qos_cb.flow_list, list_elt,
+					    false);
+		flow_info = GET_BASE_ADDR(list_elt, struct
+					sme_qos_flowinfoentry, link);
+
+		if (search_key.sessionId != flow_info->sessionId) {
+			list_elt = list_next_elt;
+			continue;
+		}
+
+		if (search_key.index & SME_QOS_SEARCH_KEY_INDEX_4) {
+			if ((search_key.key.ac_type == flow_info->ac_type) &&
+			    (search_key.direction ==
+				flow_info->QoSInfo.ts_info.direction)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+				  QDF_TRACE_LEVEL_DEBUG,
+				  FL("Flow %d matches"), flow_info->QosFlowID);
+				ac_info->num_flows[flow_info->tspec_mask - 1]--;
+				ac_info->num_flows[new_tspec_mask - 1]++;
+				flow_info->tspec_mask = new_tspec_mask;
+			}
+		} else if (search_key.index & SME_QOS_SEARCH_KEY_INDEX_5) {
+			if ((search_key.key.ac_type == flow_info->ac_type) &&
+			    (search_key.tspec_mask == flow_info->tspec_mask)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+				  QDF_TRACE_LEVEL_DEBUG,
+				  FL("Flow %d matches"), flow_info->QosFlowID);
+				ac_info->num_flows[flow_info->tspec_mask - 1]--;
+				ac_info->num_flows[new_tspec_mask - 1]++;
+				flow_info->tspec_mask = new_tspec_mask;
+			}
+		}
+		list_elt = list_next_elt;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_process_add_ts_success_rsp() - Function to process the
+ *  Addts request success response came from PE
+ *
+ * We will notify HDD with addts success for the requested Flow, & for other
+ * Flows running on the AC we will send an addts modify status
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * pRsp - Pointer to the addts response structure came from PE.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_add_ts_success_rsp(tpAniSirGlobal pMac,
+					      uint8_t sessionId,
+					      tSirAddtsRspInfo *pRsp)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	sme_QosEdcaAcType ac, ac_index;
+	struct sme_qos_searchinfo search_key;
+	struct sme_qos_searchinfo search_key1;
+	struct csr_roam_session *csr_session;
+	uint8_t tspec_pending;
+	tListElem *pEntry = NULL;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	enum sme_qos_wmmuptype up =
+		(enum sme_qos_wmmuptype) pRsp->tspec.tsinfo.traffic.userPrio;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	WLAN_HOST_DIAG_EVENT_DEF(qos, host_event_wlan_qos_payload_type);
+	host_log_qos_tspec_pkt_type *log_ptr = NULL;
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d for UP %d",
+		  __func__, __LINE__, sessionId, up);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	ac = sme_qos_up_to_ac(up);
+	if (SME_QOS_EDCA_AC_MAX == ac) {
+		/* err msg */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: invalid AC %d from UP %d",
+			  __func__, __LINE__, ac, up);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pACInfo = &pSession->ac_info[ac];
+	/* is there a TSPEC request pending on this AC? */
+	tspec_pending = pACInfo->tspec_pending;
+	if (!tspec_pending) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: On session %d an AddTS is not pending on AC %d",
+			  __func__, __LINE__, sessionId, ac);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* App is looking for APSD or the App which was looking for APSD has
+	 * been released, so STA re-negotiated with AP
+	 */
+	if (pACInfo->requested_QoSInfo[tspec_pending - 1].ts_info.psb) {
+		/* update the session's apsd mask */
+		pSession->apsdMask |= 1 << (SME_QOS_EDCA_AC_VO - ac);
+	} else {
+		if (((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) > 0) &&
+		    ((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) <=
+		     SME_QOS_TSPEC_INDEX_MAX)) {
+			if (!pACInfo->requested_QoSInfo
+			    [(SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) -
+			     1].ts_info.psb)
+				/* update the session's apsd mask */
+				pSession->apsdMask &=
+					~(1 << (SME_QOS_EDCA_AC_VO - ac));
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: Exceeded the array bounds of pACInfo->requested_QosInfo",
+				  __func__, __LINE__);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.burst_size_defn =
+		pRsp->tspec.tsinfo.traffic.burstSizeDefn;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.ack_policy =
+		pRsp->tspec.tsinfo.traffic.ackPolicy;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.up =
+		pRsp->tspec.tsinfo.traffic.userPrio;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.psb =
+		pRsp->tspec.tsinfo.traffic.psb;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.direction =
+		pRsp->tspec.tsinfo.traffic.direction;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.tid =
+		pRsp->tspec.tsinfo.traffic.tsid;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].nominal_msdu_size =
+		pRsp->tspec.nomMsduSz;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].maximum_msdu_size =
+		pRsp->tspec.maxMsduSz;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].min_service_interval =
+		pRsp->tspec.minSvcInterval;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].max_service_interval =
+		pRsp->tspec.maxSvcInterval;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].inactivity_interval =
+		pRsp->tspec.inactInterval;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].suspension_interval =
+		pRsp->tspec.suspendInterval;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].svc_start_time =
+		pRsp->tspec.svcStartTime;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].min_data_rate =
+		pRsp->tspec.minDataRate;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].mean_data_rate =
+		pRsp->tspec.meanDataRate;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].peak_data_rate =
+		pRsp->tspec.peakDataRate;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].max_burst_size =
+		pRsp->tspec.maxBurstSz;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].delay_bound =
+		pRsp->tspec.delayBound;
+
+	pACInfo->curr_QoSInfo[tspec_pending - 1].min_phy_rate =
+		pRsp->tspec.minPhyRate;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].surplus_bw_allowance =
+		pRsp->tspec.surplusBw;
+	pACInfo->curr_QoSInfo[tspec_pending - 1].medium_time =
+		pRsp->tspec.mediumTime;
+
+	sme_set_tspec_uapsd_mask_per_session(pMac,
+			&pRsp->tspec.tsinfo, sessionId);
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: On session %d AddTspec Medium Time %d",
+		  __func__, __LINE__, sessionId, pRsp->tspec.mediumTime);
+
+	/* Check if the current flow is for bi-directional. If so, update the
+	 * number of flows to reflect that all flows are aggregated into tspec
+	 * index 0.
+	 */
+	if ((pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1].ts_info.
+	     direction == SME_QOS_WMM_TS_DIR_BOTH)
+	    && (pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] > 0)) {
+		qdf_mem_zero(&search_key, sizeof(struct sme_qos_searchinfo));
+		/* update tspec_mask for all the flows having
+		 * SME_QOS_TSPEC_MASK_BIT_2_SET to SME_QOS_TSPEC_MASK_BIT_1_SET
+		 */
+		search_key.key.ac_type = ac;
+		search_key.index = SME_QOS_SEARCH_KEY_INDEX_5;
+		search_key.sessionId = sessionId;
+		search_key.tspec_mask = SME_QOS_TSPEC_MASK_BIT_2_SET;
+		sme_qos_update_tspec_mask(sessionId, search_key,
+					  SME_QOS_TSPEC_MASK_BIT_1_SET);
+	}
+
+	qdf_mem_zero(&search_key1, sizeof(struct sme_qos_searchinfo));
+	/* set the horenewal field in control block if needed */
+	search_key1.index = SME_QOS_SEARCH_KEY_INDEX_3;
+	search_key1.key.reason = SME_QOS_REASON_SETUP;
+	search_key1.sessionId = sessionId;
+	for (ac_index = SME_QOS_EDCA_AC_BE; ac_index < SME_QOS_EDCA_AC_MAX;
+	     ac_index++) {
+		pEntry = sme_qos_find_in_flow_list(search_key1);
+		if (pEntry) {
+			flow_info = GET_BASE_ADDR(pEntry,
+					struct sme_qos_flowinfoentry, link);
+			if (flow_info->ac_type == ac) {
+				pACInfo->hoRenewal = flow_info->hoRenewal;
+				break;
+			}
+		}
+	}
+	qdf_mem_zero(&search_key, sizeof(struct sme_qos_searchinfo));
+	/* set the key type & the key to be searched in the Flow List */
+	search_key.key.ac_type = ac;
+	search_key.index = SME_QOS_SEARCH_KEY_INDEX_2;
+	search_key.sessionId = sessionId;
+	/* notify HDD the success for the requested flow */
+	/* notify all the other flows running on the AC that QoS got modified */
+	if (!QDF_IS_STATUS_SUCCESS
+		    (sme_qos_find_all_in_flow_list
+			    (pMac, search_key, sme_qos_add_ts_success_fnp))) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: On session %d no match found for ac %d",
+			  __func__, __LINE__, sessionId,
+			  search_key.key.ac_type);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pACInfo->hoRenewal = false;
+	qdf_mem_zero(&pACInfo->requested_QoSInfo[tspec_pending - 1],
+		     sizeof(struct sme_qos_wmmtspecinfo));
+	/* event: EVENT_WLAN_QOS */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+	qos.eventId = SME_QOS_DIAG_ADDTS_RSP;
+	qos.reasonCode = SME_QOS_DIAG_ADDTS_ADMISSION_ACCEPTED;
+	WLAN_HOST_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS);
+	WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_qos_tspec_pkt_type,
+				 LOG_WLAN_QOS_TSPEC_C);
+	if (log_ptr) {
+		log_ptr->delay_bound =
+			pACInfo->curr_QoSInfo[tspec_pending - 1].delay_bound;
+		log_ptr->inactivity_interval =
+			pACInfo->curr_QoSInfo[tspec_pending -
+					      1].inactivity_interval;
+		log_ptr->max_burst_size =
+			pACInfo->curr_QoSInfo[tspec_pending - 1].max_burst_size;
+		log_ptr->max_service_interval =
+			pACInfo->curr_QoSInfo[tspec_pending -
+					      1].max_service_interval;
+		log_ptr->maximum_msdu_size =
+			pACInfo->curr_QoSInfo[tspec_pending - 1].
+			maximum_msdu_size;
+		log_ptr->mean_data_rate =
+			pACInfo->curr_QoSInfo[tspec_pending - 1].mean_data_rate;
+		log_ptr->medium_time =
+			pACInfo->curr_QoSInfo[tspec_pending - 1].medium_time;
+		log_ptr->min_data_rate =
+			pACInfo->curr_QoSInfo[tspec_pending - 1].min_data_rate;
+		log_ptr->min_phy_rate =
+			pACInfo->curr_QoSInfo[tspec_pending - 1].min_phy_rate;
+		log_ptr->min_service_interval =
+			pACInfo->curr_QoSInfo[tspec_pending -
+					      1].min_service_interval;
+		log_ptr->nominal_msdu_size =
+			pACInfo->curr_QoSInfo[tspec_pending - 1].
+			nominal_msdu_size;
+		log_ptr->peak_data_rate =
+			pACInfo->curr_QoSInfo[tspec_pending - 1].peak_data_rate;
+		log_ptr->surplus_bw_allowance =
+			pACInfo->curr_QoSInfo[tspec_pending -
+					      1].surplus_bw_allowance;
+		log_ptr->suspension_interval =
+			pACInfo->curr_QoSInfo[tspec_pending -
+					      1].suspension_interval;
+		log_ptr->svc_start_time =
+			pACInfo->curr_QoSInfo[tspec_pending - 1].svc_start_time;
+		log_ptr->tsinfo[0] =
+			pACInfo->curr_QoSInfo[tspec_pending -
+					      1].ts_info.direction << 5 |
+			pACInfo->
+			curr_QoSInfo[tspec_pending - 1].ts_info.tid << 1;
+		log_ptr->tsinfo[1] =
+			pACInfo->curr_QoSInfo[tspec_pending -
+					      1].ts_info.up << 11 | pACInfo->
+			curr_QoSInfo[tspec_pending - 1].ts_info.psb << 10;
+		log_ptr->tsinfo[2] = 0;
+	}
+	WLAN_HOST_DIAG_LOG_REPORT(log_ptr);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+	pACInfo->tspec_pending = 0;
+
+	sme_qos_state_transition(sessionId, ac, SME_QOS_QOS_ON);
+
+	/* Inform this TSPEC IE change to FW */
+	csr_session = CSR_GET_SESSION(pMac, sessionId);
+	if ((csr_session != NULL) && (NULL != csr_session->pCurRoamProfile) &&
+	    (csr_session->pCurRoamProfile->csrPersona == QDF_STA_MODE))
+		csr_roam_offload_scan(pMac, sessionId,
+				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				      REASON_CONNECT_IES_CHANGED);
+
+	(void)sme_qos_process_buffered_cmd(sessionId);
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_aggregate_params() - Utility function to increament the TSPEC
+ *  params per AC. Typical usage while using flow aggregation or deletion of
+ *  flows
+ *
+ * pInput_Tspec_Info - Pointer to sme_QosWmmTspecInfo which contains the
+ *  WMM TSPEC related info with which pCurrent_Tspec_Info will be updated
+ * pCurrent_Tspec_Info - Pointer to sme_QosWmmTspecInfo which contains
+ *  current the WMM TSPEC related info
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_aggregate_params(
+		struct sme_qos_wmmtspecinfo *pInput_Tspec_Info,
+		struct sme_qos_wmmtspecinfo *pCurrent_Tspec_Info,
+		struct sme_qos_wmmtspecinfo *pUpdated_Tspec_Info)
+{
+	struct sme_qos_wmmtspecinfo TspecInfo;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked", __func__, __LINE__);
+	if (!pInput_Tspec_Info) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: input is NULL, nothing to aggregate",
+			  __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (!pCurrent_Tspec_Info) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Current is NULL, can't aggregate",
+			  __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_copy(&TspecInfo, pCurrent_Tspec_Info,
+		     sizeof(struct sme_qos_wmmtspecinfo));
+	TspecInfo.ts_info.psb = pInput_Tspec_Info->ts_info.psb;
+	/* APSD preference is only meaningful if service interval
+	 * was set by app
+	 */
+	if (pCurrent_Tspec_Info->min_service_interval &&
+	    pInput_Tspec_Info->min_service_interval &&
+	    (pCurrent_Tspec_Info->ts_info.direction !=
+	     pInput_Tspec_Info->ts_info.direction)) {
+		TspecInfo.min_service_interval =
+			QDF_MIN(pCurrent_Tspec_Info->min_service_interval,
+				pInput_Tspec_Info->min_service_interval);
+	} else if (pInput_Tspec_Info->min_service_interval) {
+		TspecInfo.min_service_interval =
+			pInput_Tspec_Info->min_service_interval;
+	}
+	if (pCurrent_Tspec_Info->max_service_interval &&
+	    pInput_Tspec_Info->max_service_interval &&
+	    (pCurrent_Tspec_Info->ts_info.direction !=
+	     pInput_Tspec_Info->ts_info.direction)) {
+		TspecInfo.max_service_interval =
+			QDF_MIN(pCurrent_Tspec_Info->max_service_interval,
+				pInput_Tspec_Info->max_service_interval);
+	} else {
+		TspecInfo.max_service_interval =
+			pInput_Tspec_Info->max_service_interval;
+	}
+	/* If directions don't match, it must necessarily be both uplink and
+	 *  downlink
+	 */
+	if (pCurrent_Tspec_Info->ts_info.direction !=
+	    pInput_Tspec_Info->ts_info.direction)
+		TspecInfo.ts_info.direction =
+			pInput_Tspec_Info->ts_info.direction;
+
+	/* Max MSDU size : these sizes are `maxed' */
+	TspecInfo.maximum_msdu_size =
+		QDF_MAX(pCurrent_Tspec_Info->maximum_msdu_size,
+			pInput_Tspec_Info->maximum_msdu_size);
+
+	/* Inactivity interval : these sizes are `maxed' */
+	TspecInfo.inactivity_interval =
+		QDF_MAX(pCurrent_Tspec_Info->inactivity_interval,
+			pInput_Tspec_Info->inactivity_interval);
+
+	/* Delay bounds: min of all values
+	 * Check on 0: if 0, it means initial value since delay can never be 0!!
+	 */
+	if (pCurrent_Tspec_Info->delay_bound) {
+		TspecInfo.delay_bound =
+			QDF_MIN(pCurrent_Tspec_Info->delay_bound,
+				pInput_Tspec_Info->delay_bound);
+	} else
+		TspecInfo.delay_bound = pInput_Tspec_Info->delay_bound;
+
+	TspecInfo.max_burst_size = QDF_MAX(pCurrent_Tspec_Info->max_burst_size,
+					   pInput_Tspec_Info->max_burst_size);
+
+	/* Nominal MSDU size also has a fixed bit that needs to be `handled'
+	 * before aggregation This can be handled only if previous size is the
+	 * same as new or both have the fixed bit set These sizes are not added
+	 * but `maxed'
+	 */
+	TspecInfo.nominal_msdu_size =
+		QDF_MAX(pCurrent_Tspec_Info->nominal_msdu_size &
+			~SME_QOS_16BIT_MSB, pInput_Tspec_Info->nominal_msdu_size
+			& ~SME_QOS_16BIT_MSB);
+
+	if (((pCurrent_Tspec_Info->nominal_msdu_size == 0) ||
+	     (pCurrent_Tspec_Info->nominal_msdu_size & SME_QOS_16BIT_MSB)) &&
+	    ((pInput_Tspec_Info->nominal_msdu_size == 0) ||
+	     (pInput_Tspec_Info->nominal_msdu_size & SME_QOS_16BIT_MSB)))
+		TspecInfo.nominal_msdu_size |= SME_QOS_16BIT_MSB;
+
+	/* Data rates: Add up the rates for aggregation */
+	SME_QOS_BOUNDED_U32_ADD_Y_TO_X(TspecInfo.peak_data_rate,
+				       pInput_Tspec_Info->peak_data_rate);
+	SME_QOS_BOUNDED_U32_ADD_Y_TO_X(TspecInfo.min_data_rate,
+				       pInput_Tspec_Info->min_data_rate);
+	/* mean data rate = peak data rate: aggregate to be flexible on apps */
+	SME_QOS_BOUNDED_U32_ADD_Y_TO_X(TspecInfo.mean_data_rate,
+				       pInput_Tspec_Info->mean_data_rate);
+
+	/*
+	 * Suspension interval : this is set to the inactivity interval since
+	 * per spec it is less than or equal to inactivity interval
+	 * This is not provided by app since we currently don't support the HCCA
+	 * mode of operation Currently set it to 0 to avoid confusion: Cisco ESE
+	 * needs ~0; spec requires inactivity interval to be > suspension
+	 * interval: this could be tricky!
+	 */
+	TspecInfo.suspension_interval = pInput_Tspec_Info->suspension_interval;
+	/* Remaining parameters do not come from app as they are very WLAN
+	 * air interface specific Set meaningful values here
+	 */
+	TspecInfo.medium_time = 0;      /* per WMM spec                 */
+	TspecInfo.min_phy_rate = SME_QOS_MIN_PHY_RATE;
+	TspecInfo.svc_start_time = 0;   /* arbitrary                  */
+	TspecInfo.surplus_bw_allowance +=
+		pInput_Tspec_Info->surplus_bw_allowance;
+	if (TspecInfo.surplus_bw_allowance > SME_QOS_SURPLUS_BW_ALLOWANCE)
+		TspecInfo.surplus_bw_allowance = SME_QOS_SURPLUS_BW_ALLOWANCE;
+
+	/* Set ack_policy to block ack even if one stream requests block
+	 * ack policy
+	 */
+	if ((pInput_Tspec_Info->ts_info.ack_policy ==
+	     SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
+	    || (pCurrent_Tspec_Info->ts_info.ack_policy ==
+		SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK))
+		TspecInfo.ts_info.ack_policy =
+			SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
+
+	if (pInput_Tspec_Info->ts_info.burst_size_defn
+	    || pCurrent_Tspec_Info->ts_info.burst_size_defn)
+		TspecInfo.ts_info.burst_size_defn = 1;
+
+	if (pUpdated_Tspec_Info)
+		qdf_mem_copy(pUpdated_Tspec_Info, &TspecInfo,
+			     sizeof(struct sme_qos_wmmtspecinfo));
+	else
+		qdf_mem_copy(pCurrent_Tspec_Info, &TspecInfo,
+			     sizeof(struct sme_qos_wmmtspecinfo));
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_update_params() - Utility function to update the TSPEC
+ *  params per AC. Typical usage while deleting flows on AC which is running
+ *  multiple flows
+ *
+ * sessionId - Session upon which the TSPEC is being updated
+ * ac - Enumeration of the various EDCA Access Categories.
+ * tspec_mask - on which tspec per AC, the update is requested
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_update_params(uint8_t sessionId,
+		sme_QosEdcaAcType ac,
+		uint8_t tspec_mask,
+		struct sme_qos_wmmtspecinfo *pTspec_Info)
+{
+	tListElem *pEntry = NULL, *pNextEntry = NULL;
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	struct sme_qos_wmmtspecinfo Tspec_Info;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: invoked on session %d for AC %d TSPEC %d",
+		  __func__, __LINE__, sessionId, ac, tspec_mask);
+	if (!pTspec_Info) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: output is NULL, can't aggregate",
+			  __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	qdf_mem_zero(&Tspec_Info, sizeof(struct sme_qos_wmmtspecinfo));
+	pEntry = csr_ll_peek_head(&sme_qos_cb.flow_list, false);
+	if (!pEntry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Flow List empty, nothing to update",
+			  __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	pACInfo = &pSession->ac_info[ac];
+	/* init the TS info field */
+	Tspec_Info.ts_info.up =
+		pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.up;
+	Tspec_Info.ts_info.psb =
+		pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.psb;
+	Tspec_Info.ts_info.tid =
+		pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.tid;
+	while (pEntry) {
+		pNextEntry = csr_ll_next(&sme_qos_cb.flow_list, pEntry, false);
+		flow_info = GET_BASE_ADDR(pEntry, struct sme_qos_flowinfoentry,
+					link);
+		if ((sessionId == flow_info->sessionId) &&
+		    (ac == flow_info->ac_type) &&
+		    (tspec_mask == flow_info->tspec_mask)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: Flow %d matches",
+				  __func__, __LINE__, flow_info->QosFlowID);
+
+			if ((SME_QOS_REASON_RELEASE == flow_info->reason) ||
+			    (SME_QOS_REASON_MODIFY == flow_info->reason)) {
+				/* msg */
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					  "%s: %d: Skipping Flow %d as it is marked for release/modify",
+					__func__,
+					  __LINE__, flow_info->QosFlowID);
+			} else
+			if (!QDF_IS_STATUS_SUCCESS
+				    (sme_qos_aggregate_params
+					    (&flow_info->QoSInfo, &Tspec_Info,
+						NULL))) {
+				/* err msg */
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "%s: %d: sme_qos_aggregate_params() failed",
+					  __func__, __LINE__);
+			}
+		}
+		pEntry = pNextEntry;
+	}
+	/* return the aggregate */
+	*pTspec_Info = Tspec_Info;
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_up_to_ac() - Utility function to map an UP to AC
+ *
+ * up - Enumeration of the various User priorities (UP).
+ * Return an Access Category
+ */
+static sme_QosEdcaAcType sme_qos_up_to_ac(enum sme_qos_wmmuptype up)
+{
+	sme_QosEdcaAcType ac = SME_QOS_EDCA_AC_MAX;
+
+	if (up >= 0 && up < SME_QOS_WMM_UP_MAX)
+		ac = sme_qos_u_pto_ac_map[up];
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: up = %d ac = %d returned",
+		  __func__, __LINE__, up, ac);
+	return ac;
+}
+
+/*
+ * sme_qos_state_transition() - The state transition function per AC. We
+ *  save the previous state also.
+ *
+ * sessionId - Session upon which the state machine is running
+ * ac - Enumeration of the various EDCA Access Categories.
+ * new_state - The state FSM is moving to.
+ *
+ * Return None
+ */
+static void sme_qos_state_transition(uint8_t sessionId,
+				     sme_QosEdcaAcType ac,
+				     enum sme_qos_states new_state)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	pACInfo = &pSession->ac_info[ac];
+	pACInfo->prev_state = pACInfo->curr_state;
+	pACInfo->curr_state = new_state;
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: On session %d new state=%d, old state=%d, for AC=%d",
+		  __func__, __LINE__,
+		  sessionId, pACInfo->curr_state, pACInfo->prev_state, ac);
+}
+
+/**
+ * sme_qos_find_in_flow_list() - find a flow entry from the flow list
+ * @search_key: We can either use the flowID or the ac type to find the
+ *              entry in the flow list.
+ *              A bitmap in struct sme_qos_searchinfo tells which key to use.
+ *              Starting from LSB,
+ *              bit 0 - Flow ID
+ *              bit 1 - AC type
+ *
+ * Utility function to find an flow entry from the flow_list.
+ *
+ * Return: pointer to the list element
+ */
+static tListElem *sme_qos_find_in_flow_list(struct sme_qos_searchinfo
+						search_key)
+{
+	tListElem *list_elt = NULL, *list_next_elt = NULL;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+
+	list_elt = csr_ll_peek_head(&sme_qos_cb.flow_list, false);
+	if (!list_elt) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Flow List empty, can't search"));
+		return NULL;
+	}
+
+	while (list_elt) {
+		list_next_elt = csr_ll_next(&sme_qos_cb.flow_list, list_elt,
+					    false);
+		flow_info = GET_BASE_ADDR(list_elt, struct
+					sme_qos_flowinfoentry, link);
+
+		if ((search_key.sessionId != flow_info->sessionId) &&
+		    (search_key.sessionId != SME_QOS_SEARCH_SESSION_ID_ANY)) {
+			list_elt = list_next_elt;
+			continue;
+		}
+
+		if (search_key.index & SME_QOS_SEARCH_KEY_INDEX_1) {
+			if (search_key.key.QosFlowID == flow_info->QosFlowID) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+				  QDF_TRACE_LEVEL_DEBUG,
+				  FL("match found on flowID, ending search"));
+				break;
+			}
+		} else if (search_key.index & SME_QOS_SEARCH_KEY_INDEX_2) {
+			if (search_key.key.ac_type == flow_info->ac_type) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+				  QDF_TRACE_LEVEL_DEBUG,
+				  FL("match found on ac, ending search"));
+				break;
+			}
+		} else if (search_key.index & SME_QOS_SEARCH_KEY_INDEX_3) {
+			if (search_key.key.reason == flow_info->reason) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+				  QDF_TRACE_LEVEL_DEBUG,
+				  FL("match found on reason, ending search"));
+				break;
+			}
+		} else if (search_key.index & SME_QOS_SEARCH_KEY_INDEX_4) {
+			if ((search_key.key.ac_type == flow_info->ac_type) &&
+			    (search_key.direction ==
+				flow_info->QoSInfo.ts_info.direction)) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+				  QDF_TRACE_LEVEL_DEBUG,
+				  FL("match found on reason, ending search"));
+				break;
+			}
+		}
+		list_elt = list_next_elt;
+	}
+	return list_elt;
+}
+
+/**
+ * sme_qos_find_all_in_flow_list() - find a flow entry in the flow list
+ * @mac_ctx: global MAC context
+ * @search_key: search key
+ * @fnp: function pointer specifying the action type for the entry found
+ *
+ * Utility function to find an flow entry from the flow_list & act on it.
+ * search_key -  We can either use the flowID or the ac type to find the
+ *   entry in the flow list.
+ *  A bitmap in struct sme_qos_searchinfo tells which key to use. Starting from
+ * LSB,
+ *  bit 0 - Flow ID
+ *  bit 1 - AC type
+ *
+ * Return: None
+ */
+static QDF_STATUS sme_qos_find_all_in_flow_list(tpAniSirGlobal mac_ctx,
+					 struct sme_qos_searchinfo search_key,
+					 sme_QosProcessSearchEntry fnp)
+{
+	tListElem *list_elt = NULL, *list_next_elt = NULL;
+	struct sme_qos_sessioninfo *qos_session;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	sme_QosEdcaAcType ac_type;
+
+	list_elt = csr_ll_peek_head(&sme_qos_cb.flow_list, false);
+	if (!list_elt) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Flow List empty, can't search"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	while (list_elt) {
+		list_next_elt = csr_ll_next(&sme_qos_cb.flow_list, list_elt,
+					    false);
+		flow_info = GET_BASE_ADDR(list_elt, struct
+					sme_qos_flowinfoentry, link);
+		qos_session = &sme_qos_cb.sessionInfo[flow_info->sessionId];
+		if ((search_key.sessionId != flow_info->sessionId) &&
+		    (search_key.sessionId != SME_QOS_SEARCH_SESSION_ID_ANY)) {
+			list_elt = list_next_elt;
+			continue;
+		}
+
+		if ((search_key.index & SME_QOS_SEARCH_KEY_INDEX_1) &&
+		    (search_key.key.QosFlowID == flow_info->QosFlowID)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			    FL("match found on flowID, ending search"));
+			status = fnp(mac_ctx, list_elt);
+			if (QDF_STATUS_E_FAILURE == status) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+				    QDF_TRACE_LEVEL_ERROR,
+				    FL("Failed to process entry"));
+				break;
+			}
+		} else if ((search_key.index & SME_QOS_SEARCH_KEY_INDEX_2) &&
+			   (search_key.key.ac_type == flow_info->ac_type)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			    FL("match found on ac, ending search"));
+			ac_type = flow_info->ac_type;
+			flow_info->hoRenewal =
+				qos_session->ac_info[ac_type].hoRenewal;
+			status = fnp(mac_ctx, list_elt);
+			if (QDF_STATUS_E_FAILURE == status) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+				    QDF_TRACE_LEVEL_ERROR,
+				    FL("Failed to process entry"));
+				break;
+			}
+		}
+		list_elt = list_next_elt;
+	}
+	return status;
+}
+
+/*
+ * sme_qos_is_acm() - Utility function to check if a particular AC
+ *  mandates Admission Control.
+ *
+ * ac - Enumeration of the various EDCA Access Categories.
+ *
+ * Return true if the AC mandates Admission Control
+ */
+static bool sme_qos_is_acm(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc,
+		    sme_QosEdcaAcType ac, tDot11fBeaconIEs *pIes)
+{
+	bool ret_val = false;
+	tDot11fBeaconIEs *pIesLocal;
+
+	if (!pSirBssDesc) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: pSirBssDesc is NULL", __func__, __LINE__);
+		return false;
+	}
+
+	if (NULL != pIes)
+		/* IEs were provided so use them locally */
+		pIesLocal = pIes;
+	else {
+		/* IEs were not provided so parse them ourselves */
+		if (!QDF_IS_STATUS_SUCCESS
+			    (csr_get_parsed_bss_description_ies
+				    (pMac, pSirBssDesc, &pIesLocal))) {
+			/* err msg */
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: csr_get_parsed_bss_description_ies() failed",
+				  __func__, __LINE__);
+			return false;
+		}
+
+		/* if success then pIesLocal was allocated */
+	}
+
+	if (CSR_IS_QOS_BSS(pIesLocal)) {
+		switch (ac) {
+		case SME_QOS_EDCA_AC_BE:
+			if (pIesLocal->WMMParams.acbe_acm)
+				ret_val = true;
+			break;
+		case SME_QOS_EDCA_AC_BK:
+			if (pIesLocal->WMMParams.acbk_acm)
+				ret_val = true;
+			break;
+		case SME_QOS_EDCA_AC_VI:
+			if (pIesLocal->WMMParams.acvi_acm)
+				ret_val = true;
+			break;
+		case SME_QOS_EDCA_AC_VO:
+			if (pIesLocal->WMMParams.acvo_acm)
+				ret_val = true;
+			break;
+		default:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: unknown AC = %d",
+				  __func__, __LINE__, ac);
+			break;
+		}
+	} /* IS_QOS_BSS */
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: ACM = %d for AC = %d",
+		  __func__, __LINE__, ret_val, ac);
+	if (NULL == pIes)
+		/* IEs were allocated locally so free them */
+		qdf_mem_free(pIesLocal);
+
+	return ret_val;
+}
+
+/**
+ * sme_qos_buffer_existing_flows() - buffer existing flows in flow_list
+ * @mac_ctx: global MAC context
+ * @sessionid: session ID
+ *
+ * Utility function to buffer the existing flows in flow_list,
+ * so that we can renew them after handoff is done.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_qos_buffer_existing_flows(tpAniSirGlobal mac_ctx,
+						uint8_t sessionid)
+{
+	tListElem *list_entry = NULL, *list_nextentry = NULL;
+	struct sme_qos_sessioninfo *qos_session;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	struct sme_qos_cmdinfo cmd;
+	struct sme_qos_setupcmdinfo *setupinfo;
+
+	list_entry = csr_ll_peek_head(&sme_qos_cb.flow_list, false);
+	if (!list_entry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("Flow List empty, nothing to buffer"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	while (list_entry) {
+		list_nextentry = csr_ll_next(&sme_qos_cb.flow_list, list_entry,
+					     false);
+		flow_info = GET_BASE_ADDR(list_entry, struct
+					sme_qos_flowinfoentry, link);
+		if (flow_info->sessionId != sessionid) {
+			list_entry = list_nextentry;
+			continue;
+		}
+
+		if ((SME_QOS_REASON_REQ_SUCCESS == flow_info->reason) ||
+		    (SME_QOS_REASON_SETUP == flow_info->reason)) {
+			cmd.command = SME_QOS_SETUP_REQ;
+			cmd.pMac = mac_ctx;
+			cmd.sessionId = sessionid;
+			setupinfo = &cmd.u.setupCmdInfo;
+
+			setupinfo->HDDcontext = flow_info->HDDcontext;
+			setupinfo->QoSInfo = flow_info->QoSInfo;
+			setupinfo->QoSCallback = flow_info->QoSCallback;
+			/* shouldn't be needed */
+			setupinfo->UPType = SME_QOS_WMM_UP_MAX;
+			setupinfo->QosFlowID = flow_info->QosFlowID;
+			if (SME_QOS_REASON_SETUP == flow_info->reason)
+				setupinfo->hoRenewal = false;
+			else
+				setupinfo->hoRenewal = true;
+
+			if (!QDF_IS_STATUS_SUCCESS
+				    (sme_qos_buffer_cmd(&cmd, true)))
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					"couldn't buffer the setup request for flow %d in handoff state",
+					  flow_info->QosFlowID);
+			else
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					"buffered a setup request for flow %d in handoff state",
+					  flow_info->QosFlowID);
+		} else if (SME_QOS_REASON_RELEASE == flow_info->reason) {
+			cmd.command = SME_QOS_RELEASE_REQ;
+			cmd.pMac = mac_ctx;
+			cmd.sessionId = sessionid;
+			cmd.u.releaseCmdInfo.QosFlowID = flow_info->QosFlowID;
+			if (!QDF_IS_STATUS_SUCCESS
+				    (sme_qos_buffer_cmd(&cmd, true)))
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					"couldn't buffer the release req for flow %d in handoff state",
+					  flow_info->QosFlowID);
+			else
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					"buffered a release request for flow %d in handoff state",
+					  flow_info->QosFlowID);
+		} else if (SME_QOS_REASON_MODIFY_PENDING ==
+			   flow_info->reason) {
+			cmd.command = SME_QOS_MODIFY_REQ;
+			cmd.pMac = mac_ctx;
+			cmd.sessionId = sessionid;
+			cmd.u.modifyCmdInfo.QosFlowID = flow_info->QosFlowID;
+			cmd.u.modifyCmdInfo.QoSInfo = flow_info->QoSInfo;
+			if (!QDF_IS_STATUS_SUCCESS
+				    (sme_qos_buffer_cmd(&cmd, true)))
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					"couldn't buffer the modify req for flow %d in handoff state",
+					  flow_info->QosFlowID);
+			else
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_DEBUG,
+					"buffered a modify request for flow %d in handoff state",
+					  flow_info->QosFlowID);
+		}
+		/* delete the entry from Flow List */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("Deleting original entry at %pK with flowID %d"),
+			  flow_info, flow_info->QosFlowID);
+		csr_ll_remove_entry(&sme_qos_cb.flow_list, list_entry, true);
+		qdf_mem_free(flow_info);
+
+		list_entry = list_nextentry;
+	}
+	qos_session = &sme_qos_cb.sessionInfo[sessionid];
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_delete_existing_flows() - Utility function to Delete the existing
+ * flows in flow_list, if we lost connectivity.
+ *
+ *  Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_delete_existing_flows(tpAniSirGlobal pMac,
+						uint8_t sessionId)
+{
+	tListElem *pEntry = NULL, *pNextEntry = NULL;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+
+	pEntry = csr_ll_peek_head(&sme_qos_cb.flow_list, true);
+	if (!pEntry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Flow List empty, nothing to delete",
+			  __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	while (pEntry) {
+		pNextEntry = csr_ll_next(&sme_qos_cb.flow_list, pEntry, true);
+		flow_info = GET_BASE_ADDR(pEntry, struct sme_qos_flowinfoentry,
+					link);
+		if (flow_info->sessionId == sessionId) {
+			if ((SME_QOS_REASON_REQ_SUCCESS == flow_info->reason) ||
+			    (SME_QOS_REASON_SETUP == flow_info->reason) ||
+			    (SME_QOS_REASON_RELEASE == flow_info->reason) ||
+			    (SME_QOS_REASON_MODIFY == flow_info->reason)) {
+				flow_info->QoSCallback(MAC_HANDLE(pMac),
+						       flow_info->HDDcontext,
+						       NULL,
+					SME_QOS_STATUS_RELEASE_QOS_LOST_IND,
+						       flow_info->QosFlowID);
+			}
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: Deleting entry at %pK with flowID %d",
+				  __func__, __LINE__,
+				  flow_info, flow_info->QosFlowID);
+			/* delete the entry from Flow List */
+			csr_ll_remove_entry(&sme_qos_cb.flow_list, pEntry,
+					    true);
+			qdf_mem_free(flow_info);
+		}
+		pEntry = pNextEntry;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_buffer_cmd() - buffer a request.
+ * @pcmd: a pointer to the cmd structure to be saved inside the buffered
+ *               cmd link list
+ * @insert_head: flag indicate if cmd should be added to the list head.
+ *
+ * Utility function to buffer a request (setup/modify/release) from client
+ * while processing another one on the same AC.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_qos_buffer_cmd(struct sme_qos_cmdinfo *pcmd,
+					bool insert_head)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_cmdinfoentry *pentry = NULL;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: Invoked", __func__, __LINE__);
+	pentry = qdf_mem_malloc(sizeof(struct sme_qos_cmdinfoentry));
+	if (!pentry)
+		return QDF_STATUS_E_NOMEM;
+
+	/* copy the entire CmdInfo */
+	pentry->cmdInfo = *pcmd;
+
+	pSession = &sme_qos_cb.sessionInfo[pcmd->sessionId];
+	if (insert_head)
+		csr_ll_insert_head(&pSession->bufferedCommandList,
+				&pentry->link, true);
+	else
+		csr_ll_insert_tail(&pSession->bufferedCommandList,
+				&pentry->link, true);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_process_buffered_cmd() - process qos buffered request
+ * @session_id: Session ID
+ *
+ * Utility function to process a buffered request (setup/modify/release)
+ * initially came from the client.
+ *
+ * Return:QDF_STATUS
+ */
+static QDF_STATUS sme_qos_process_buffered_cmd(uint8_t session_id)
+{
+	struct sme_qos_sessioninfo *qos_session;
+	struct sme_qos_cmdinfoentry *pcmd = NULL;
+	tListElem *list_elt = NULL;
+	enum sme_qos_statustype hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
+	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
+	struct sme_qos_cmdinfo *qos_cmd = NULL;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("Invoked on session %d"), session_id);
+	qos_session = &sme_qos_cb.sessionInfo[session_id];
+	if (!csr_ll_is_list_empty(&qos_session->bufferedCommandList, false)) {
+		list_elt = csr_ll_remove_head(&qos_session->bufferedCommandList,
+					      true);
+		if (!list_elt) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("no more buffered commands on session %d"),
+				  session_id);
+			return QDF_STATUS_E_FAILURE;
+		}
+		pcmd = GET_BASE_ADDR(list_elt, struct sme_qos_cmdinfoentry,
+					link);
+		qos_cmd = &pcmd->cmdInfo;
+
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("Qos cmd %d"), qos_cmd->command);
+		switch (qos_cmd->command) {
+		case SME_QOS_SETUP_REQ:
+			hdd_status = sme_qos_internal_setup_req(
+				       qos_cmd->pMac, qos_cmd->sessionId,
+				       &qos_cmd->u.setupCmdInfo.QoSInfo,
+				       qos_cmd->u.setupCmdInfo.QoSCallback,
+				       qos_cmd->u.setupCmdInfo.HDDcontext,
+				       qos_cmd->u.setupCmdInfo.UPType,
+				       qos_cmd->u.setupCmdInfo.QosFlowID,
+				       true, qos_cmd->u.setupCmdInfo.hoRenewal);
+			if (SME_QOS_STATUS_SETUP_FAILURE_RSP == hdd_status) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					"sme_qos_internal_setup_req failed on session %d",
+					  session_id);
+				qdf_ret_status = QDF_STATUS_E_FAILURE;
+			}
+			break;
+		case SME_QOS_RELEASE_REQ:
+			hdd_status = sme_qos_internal_release_req(qos_cmd->pMac,
+					qos_cmd->sessionId,
+					qos_cmd->u.releaseCmdInfo.QosFlowID,
+					true);
+			if (SME_QOS_STATUS_RELEASE_FAILURE_RSP == hdd_status) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					"sme_qos_internal_release_req failed on session %d",
+					  session_id);
+				qdf_ret_status = QDF_STATUS_E_FAILURE;
+			}
+			break;
+		case SME_QOS_MODIFY_REQ:
+			hdd_status = sme_qos_internal_modify_req(qos_cmd->pMac,
+					&qos_cmd->u.modifyCmdInfo.QoSInfo,
+					qos_cmd->u.modifyCmdInfo.QosFlowID,
+					true);
+			if (SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP ==
+				hdd_status) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					"sme_qos_internal_modify_req failed on session %d",
+					  session_id);
+				qdf_ret_status = QDF_STATUS_E_FAILURE;
+			}
+			break;
+		case SME_QOS_RESEND_REQ:
+			hdd_status = sme_qos_re_request_add_ts(qos_cmd->pMac,
+					qos_cmd->sessionId,
+					&qos_cmd->u.resendCmdInfo.QoSInfo,
+					qos_cmd->u.resendCmdInfo.ac,
+					qos_cmd->u.resendCmdInfo.tspecMask);
+			if (SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP ==
+				hdd_status) {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					"sme_qos_re_request_add_ts failed on session %d",
+					  session_id);
+				qdf_ret_status = QDF_STATUS_E_FAILURE;
+			}
+			break;
+		default:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("On session %d unknown cmd = %d"),
+				  session_id, qos_cmd->command);
+			break;
+		}
+		/* buffered command has been processed, reclaim the memory */
+		qdf_mem_free(pcmd);
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("cmd buffer empty"));
+	}
+	return qdf_ret_status;
+}
+
+/*
+ * sme_qos_delete_buffered_requests() - Utility function to Delete the buffered
+ *  requests in the buffered_cmd_list, if we lost connectivity.
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_delete_buffered_requests(tpAniSirGlobal pMac,
+						   uint8_t sessionId)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_cmdinfoentry *pcmd = NULL;
+	tListElem *pEntry = NULL, *pNextEntry = NULL;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: Invoked on session %d",
+		  __func__, __LINE__, sessionId);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	pEntry = csr_ll_peek_head(&pSession->bufferedCommandList, true);
+	if (!pEntry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Buffered List empty, nothing to delete on session %d",
+			  __func__, __LINE__, sessionId);
+		return QDF_STATUS_E_FAILURE;
+	}
+	while (pEntry) {
+		pNextEntry = csr_ll_next(&pSession->bufferedCommandList, pEntry,
+					true);
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: deleting entry from buffered List", __func__,
+			  __LINE__);
+		/* delete the entry from Flow List */
+		csr_ll_remove_entry(&pSession->bufferedCommandList, pEntry,
+				    true);
+		/* reclaim the memory */
+		pcmd = GET_BASE_ADDR(pEntry, struct sme_qos_cmdinfoentry,
+					link);
+		qdf_mem_free(pcmd);
+		pEntry = pNextEntry;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_save_assoc_info() - save assoc info.
+ * @pSession: pointer to QOS session
+ * @pAssoc_info: pointer to the assoc structure to store the BSS descriptor
+ *               of the AP, the profile that HDD sent down with the
+ *               connect request
+ *
+ * Utility function to save the assoc info in the CB like BSS descriptor
+ * of the AP, the profile that HDD sent down with the connect request,
+ * while CSR notifies for assoc/reassoc success.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_qos_save_assoc_info(struct sme_qos_sessioninfo *pSession,
+				   sme_QosAssocInfo *pAssoc_info)
+{
+	tSirBssDescription *pBssDesc = NULL;
+	uint32_t bssLen = 0;
+
+	if (NULL == pAssoc_info) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: pAssoc_info is NULL", __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* clean up the assoc info if already set */
+	if (pSession->assocInfo.pBssDesc) {
+		qdf_mem_free(pSession->assocInfo.pBssDesc);
+		pSession->assocInfo.pBssDesc = NULL;
+	}
+	bssLen = pAssoc_info->pBssDesc->length +
+		 sizeof(pAssoc_info->pBssDesc->length);
+	/* save the bss Descriptor */
+	pBssDesc = qdf_mem_malloc(bssLen);
+	if (!pBssDesc)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(pBssDesc, pAssoc_info->pBssDesc, bssLen);
+	pSession->assocInfo.pBssDesc = pBssDesc;
+	/* save the apsd info from assoc */
+	if (pAssoc_info->pProfile)
+		pSession->apsdMask |= pAssoc_info->pProfile->uapsd_mask;
+
+	/* [TODO] Do we need to update the global APSD bitmap? */
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_setup_fnp() - Utility function (pointer) to notify other entries
+ *  in FLOW list on the same AC that qos params got modified
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_setup_fnp(tpAniSirGlobal pMac, tListElem *pEntry)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	enum sme_qos_statustype hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND;
+	sme_QosEdcaAcType ac;
+
+	if (!pEntry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Entry is NULL", __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	flow_info = GET_BASE_ADDR(pEntry, struct sme_qos_flowinfoentry, link);
+	ac = flow_info->ac_type;
+	pSession = &sme_qos_cb.sessionInfo[flow_info->sessionId];
+	pACInfo = &pSession->ac_info[ac];
+	if (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason) {
+		/* notify HDD, only the other Flows running on the AC */
+		flow_info->QoSCallback(MAC_HANDLE(pMac),
+				       flow_info->HDDcontext,
+				       &pACInfo->curr_QoSInfo[flow_info->
+							      tspec_mask - 1],
+				       hdd_status, flow_info->QosFlowID);
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Entry with flowID = %d getting notified",
+			  __func__, __LINE__, flow_info->QosFlowID);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_modification_notify_fnp() - Utility function (pointer) to notify
+ *  other entries in FLOW list on the same AC that qos params got modified
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_modification_notify_fnp(tpAniSirGlobal pMac, tListElem
+					*pEntry)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	enum sme_qos_statustype hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND;
+	sme_QosEdcaAcType ac;
+
+	if (!pEntry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Entry is NULL", __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	flow_info = GET_BASE_ADDR(pEntry, struct sme_qos_flowinfoentry, link);
+	ac = flow_info->ac_type;
+	pSession = &sme_qos_cb.sessionInfo[flow_info->sessionId];
+	pACInfo = &pSession->ac_info[ac];
+	if (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason) {
+		/* notify HDD, only the other Flows running on the AC */
+		flow_info->QoSCallback(MAC_HANDLE(pMac),
+				       flow_info->HDDcontext,
+				       &pACInfo->curr_QoSInfo[flow_info->
+							      tspec_mask - 1],
+				       hdd_status, flow_info->QosFlowID);
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Entry with flowID = %d getting notified",
+			  __func__, __LINE__, flow_info->QosFlowID);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_modify_fnp() - Utility function (pointer) to delete the origianl
+ *  entry in FLOW list & add the modified one
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_modify_fnp(tpAniSirGlobal pMac, tListElem *pEntry)
+{
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+
+	if (!pEntry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Entry is NULL", __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	flow_info = GET_BASE_ADDR(pEntry, struct sme_qos_flowinfoentry, link);
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("reason %d"), flow_info->reason);
+	switch (flow_info->reason) {
+	case SME_QOS_REASON_MODIFY_PENDING:
+		/* set the proper reason code for the new (with modified params)
+		 * entry
+		 */
+		flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
+		break;
+	case SME_QOS_REASON_MODIFY:
+		/* delete the original entry from Flow List */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Deleting original entry at %pK with flowID %d",
+			  __func__, __LINE__, flow_info, flow_info->QosFlowID);
+		csr_ll_remove_entry(&sme_qos_cb.flow_list, pEntry, true);
+		/* reclaim the memory */
+		qdf_mem_free(flow_info);
+		break;
+	default:
+		break;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_del_ts_ind_fnp() - Utility function (pointer) to find all Flows on
+ *  the perticular AC & delete them, also send HDD indication through the
+ * callback it registered per request
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_del_ts_ind_fnp(tpAniSirGlobal pMac, tListElem *pEntry)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	sme_QosEdcaAcType ac;
+	QDF_STATUS lock_status = QDF_STATUS_E_FAILURE;
+	enum sme_qos_statustype status;
+
+	if (!pEntry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Entry is NULL", __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* delete the entry from Flow List */
+	flow_info = GET_BASE_ADDR(pEntry, struct sme_qos_flowinfoentry, link);
+	ac = flow_info->ac_type;
+	pSession = &sme_qos_cb.sessionInfo[flow_info->sessionId];
+	pACInfo = &pSession->ac_info[ac];
+	pACInfo->relTrig = SME_QOS_RELEASE_BY_AP;
+
+	lock_status = sme_acquire_global_lock(&pMac->sme);
+	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 QDF_STATUS_E_FAILURE;
+	}
+	/* Call the internal function for QoS release, adding a layer of
+	 * abstraction
+	 */
+	status =
+		sme_qos_internal_release_req(pMac, flow_info->sessionId,
+					     flow_info->QosFlowID, false);
+	sme_release_global_lock(&pMac->sme);
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: QoS Release return status on Flow %d is %d",
+		  __func__, __LINE__, flow_info->QosFlowID, status);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_reassoc_success_ev_fnp  Notification function to HDD
+ *
+ * @mac_ctx: Mac context
+ * @entry:   Pointer to an entry in the flow_list
+ *
+ * Utility function (pointer) to notify HDD
+ * the success for the requested flow & notify all the other flows
+ * running on the same AC that QoS params got modified
+ *
+ * Return:  QDF_STATUS enumaration
+ */
+static QDF_STATUS
+sme_qos_reassoc_success_ev_fnp(tpAniSirGlobal mac_ctx,
+		tListElem *entry)
+{
+	struct sme_qos_sessioninfo *qos_session;
+	struct sme_qos_acinfo *ac_info;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	bool delete_entry = false;
+	enum sme_qos_statustype hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
+	sme_QosEdcaAcType ac;
+	QDF_STATUS pmc_status = QDF_STATUS_E_FAILURE;
+
+	if (!entry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: %d: Entry is NULL", __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	flow_info = GET_BASE_ADDR(entry, struct sme_qos_flowinfoentry, link);
+	ac = flow_info->ac_type;
+	qos_session = &sme_qos_cb.sessionInfo[flow_info->sessionId];
+	ac_info = &qos_session->ac_info[ac];
+	switch (flow_info->reason) {
+	case SME_QOS_REASON_SETUP:
+		hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND;
+		delete_entry = false;
+		flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
+		/* -Check for the case where we had to do reassoc to
+		 * reset the apsd bit for the ac - release or modify
+		 * scenario.Notify PMC as App is looking for APSD
+		 * If we already requested then we don't need to
+		 * do anything.
+		 */
+		if (ac_info->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].
+				ts_info.psb) {
+			/* this is the first flow to detect we need
+			 * PMC in UAPSD mode
+			 */
+			pmc_status = sme_ps_start_uapsd(MAC_HANDLE(mac_ctx),
+							flow_info->sessionId);
+			/* if PMC doesn't return success right away means
+			 * it is yet to put the module in BMPS state & later
+			 * to UAPSD state
+			 */
+			if (QDF_STATUS_E_FAILURE == pmc_status) {
+				hdd_status =
+					SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED;
+				/* we need to always notify this case */
+				flow_info->hoRenewal = false;
+			}
+		}
+		/* for any other pmc status we declare success */
+		break;
+	case SME_QOS_REASON_RELEASE:
+		ac_info->num_flows[SME_QOS_TSPEC_INDEX_0]--;
+	/* fall through */
+	case SME_QOS_REASON_MODIFY:
+		delete_entry = true;
+		break;
+	case SME_QOS_REASON_MODIFY_PENDING:
+		hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND;
+		delete_entry = false;
+		flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
+		if (ac_info->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].
+				ts_info.psb) {
+			/* this is the first flow to detect we need
+			 * PMC in UAPSD mode
+			 */
+			pmc_status = sme_ps_start_uapsd(MAC_HANDLE(mac_ctx),
+							flow_info->sessionId);
+			/* if PMC doesn't return success right away means
+			 * it is yet to put the module in BMPS state &
+			 * later to UAPSD state
+			 */
+			if (QDF_STATUS_E_FAILURE == pmc_status) {
+				hdd_status =
+					SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED;
+				/* we need to always notify this case */
+				flow_info->hoRenewal = false;
+			}
+		}
+		/* for any other pmc status we declare success */
+		break;
+	case SME_QOS_REASON_REQ_SUCCESS:
+		hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND;
+	/* fall through */
+	default:
+		delete_entry = false;
+		break;
+	}
+	if (!delete_entry) {
+		if (!flow_info->hoRenewal) {
+			flow_info->QoSCallback(MAC_HANDLE(mac_ctx),
+					       flow_info->HDDcontext,
+					       &ac_info->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0],
+					       hdd_status,
+					       flow_info->QosFlowID);
+		} else
+			flow_info->hoRenewal = false;
+	} else {
+		/* delete the entry from Flow List */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("Deleting entry at %pK with flowID %d"),
+			flow_info, flow_info->QosFlowID);
+		csr_ll_remove_entry(&sme_qos_cb.flow_list, entry, true);
+		/* reclaim the memory */
+		qdf_mem_free(flow_info);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_add_ts_failure_fnp() - Utility function (pointer),
+ * if the Addts request was for for an flow setup request, delete the entry from
+ * Flow list & notify HDD if the Addts request was for downgrading of QoS params
+ * because of an flow release requested on the AC, delete the entry from Flow
+ * list & notify HDD if the Addts request was for change of QoS params because
+ * of an flow modification requested on the AC, delete the new entry from Flow
+ * list & notify HDD
+ *
+ * pMac - Pointer to the global MAC parameter structure.
+ * pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure)
+ *
+ *  Return QDF_STATUS
+ */
+static QDF_STATUS sme_qos_add_ts_failure_fnp(tpAniSirGlobal pMac, tListElem
+						*pEntry)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	bool inform_hdd = false;
+	enum sme_qos_statustype hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
+	sme_QosEdcaAcType ac;
+
+	if (!pEntry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Entry is NULL", __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	flow_info = GET_BASE_ADDR(pEntry, struct sme_qos_flowinfoentry, link);
+	ac = flow_info->ac_type;
+	pSession = &sme_qos_cb.sessionInfo[flow_info->sessionId];
+	pACInfo = &pSession->ac_info[ac];
+	switch (flow_info->reason) {
+	case SME_QOS_REASON_SETUP:
+		hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
+		pACInfo->num_flows[pACInfo->tspec_pending - 1]--;
+		inform_hdd = true;
+		break;
+	case SME_QOS_REASON_RELEASE:
+		hdd_status = SME_QOS_STATUS_RELEASE_FAILURE_RSP;
+		pACInfo->num_flows[pACInfo->tspec_pending - 1]--;
+		inform_hdd = true;
+		break;
+	case SME_QOS_REASON_MODIFY_PENDING:
+		hdd_status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
+		inform_hdd = true;
+		break;
+	case SME_QOS_REASON_MODIFY:
+		flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
+	case SME_QOS_REASON_REQ_SUCCESS:
+	/* fallthrough */
+	default:
+		inform_hdd = false;
+		break;
+	}
+	if (inform_hdd) {
+		/* notify HDD, only the requested Flow, other Flows running on
+		 * the AC stay intact
+		 */
+		if (!flow_info->hoRenewal) {
+			flow_info->QoSCallback(MAC_HANDLE(pMac),
+					       flow_info->HDDcontext,
+					       &pACInfo->curr_QoSInfo[pACInfo->
+								   tspec_pending
+								      - 1],
+					       hdd_status,
+					       flow_info->QosFlowID);
+		} else {
+			flow_info->QoSCallback(MAC_HANDLE(pMac),
+					       flow_info->HDDcontext,
+					       &pACInfo->curr_QoSInfo[pACInfo->
+								   tspec_pending
+								      - 1],
+					    SME_QOS_STATUS_RELEASE_QOS_LOST_IND,
+					       flow_info->QosFlowID);
+		}
+		/* delete the entry from Flow List */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Deleting entry at %pK with flowID %d",
+			  __func__, __LINE__, flow_info, flow_info->QosFlowID);
+		csr_ll_remove_entry(&sme_qos_cb.flow_list, pEntry, true);
+		/* reclaim the memory */
+		qdf_mem_free(flow_info);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_qos_add_ts_success_fnp() - Utility function (pointer) to notify HDD
+ *
+ * @mac_ctx: Mac context
+ * @entry:   Pointer to an entry in the flow_list(i.e. tListElem structure).
+ *
+ * Description : Utility function (pointer),
+ * If the Addts request was for for an flow setup request, notify
+ * HDD for success for the flow & notify all the other flows running
+ * on the same AC that QoS params got modified
+ * if the Addts request was for downgrading of QoS params
+ * because of an flow release requested on the AC, delete
+ * the entry from Flow list & notify HDD if the Addts request
+ * was for change of QoS params because of an flow modification
+ * requested on the AC, delete the old entry from Flow list & notify
+ * HDD for success for the flow & notify all the other flows running
+ * on the same AC that QoS params got modified
+ *
+ * Return: Status
+ */
+
+static QDF_STATUS sme_qos_add_ts_success_fnp(tpAniSirGlobal mac_ctx,
+		tListElem *entry)
+{
+	struct sme_qos_sessioninfo *qos_session;
+	struct sme_qos_acinfo *ac_info;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+	bool inform_hdd = false;
+	bool delete_entry = false;
+	enum sme_qos_statustype hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP;
+	sme_QosEdcaAcType ac;
+	QDF_STATUS pmc_status = QDF_STATUS_E_FAILURE;
+	tCsrRoamModifyProfileFields profile_fields;
+	uint8_t psb;
+	uint8_t tspec_index;
+
+	if (!entry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("Entry is NULL"));
+		return QDF_STATUS_E_FAILURE;
+	}
+	flow_info = GET_BASE_ADDR(entry, struct sme_qos_flowinfoentry, link);
+	ac = flow_info->ac_type;
+	qos_session = &sme_qos_cb.sessionInfo[flow_info->sessionId];
+	ac_info = &qos_session->ac_info[ac];
+	tspec_index = ac_info->tspec_pending - 1;
+	if (flow_info->tspec_mask != ac_info->tspec_pending) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			" No need to notify the HDD, the ADDTS success is not for index = %d of the AC = %d",
+			flow_info->tspec_mask, ac);
+		return QDF_STATUS_SUCCESS;
+	}
+	switch (flow_info->reason) {
+	case SME_QOS_REASON_SETUP:
+		hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND;
+		flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
+		delete_entry = false;
+		inform_hdd = true;
+		/* check if App is looking for APSD
+		 * notify PMC as App is looking for APSD. If we already
+		 * requested then we don't need to do anything
+		 */
+		if (ac_info->requested_QoSInfo[tspec_index].ts_info.psb) {
+			/* this is the first flow to detect we need
+			 * PMC in UAPSD mode
+			 */
+			pmc_status = sme_ps_start_uapsd(MAC_HANDLE(mac_ctx),
+							flow_info->sessionId);
+			/* if PMC doesn't return success right away means
+			 * it is yet to put the module in BMPS state & later
+			 * to UAPSD state
+			 */
+			if (QDF_STATUS_E_FAILURE == pmc_status) {
+				hdd_status =
+					SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED;
+				/* we need to always notify this case */
+				flow_info->hoRenewal = false;
+			}
+		}
+		break;
+	case SME_QOS_REASON_RELEASE:
+		ac_info->num_flows[tspec_index]--;
+		hdd_status = SME_QOS_STATUS_RELEASE_SUCCESS_RSP;
+		inform_hdd = true;
+		delete_entry = true;
+		break;
+	case SME_QOS_REASON_MODIFY:
+		delete_entry = true;
+		inform_hdd = false;
+		break;
+	case SME_QOS_REASON_MODIFY_PENDING:
+		hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND;
+		delete_entry = false;
+		flow_info->reason = SME_QOS_REASON_REQ_SUCCESS;
+		inform_hdd = true;
+		psb = ac_info->requested_QoSInfo[tspec_index].ts_info.psb;
+		/* notify PMC if App is looking for APSD
+		 */
+		if (psb) {
+			/* this is the first flow to detect
+			 * we need PMC in UAPSD mode
+			 */
+			pmc_status = sme_ps_start_uapsd(MAC_HANDLE(mac_ctx),
+							flow_info->sessionId);
+			/* if PMC doesn't return success right
+			 * away means it is yet to put
+			 * the module in BMPS state & later to UAPSD state
+			 */
+			if (QDF_STATUS_E_FAILURE == pmc_status) {
+				hdd_status =
+				 SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED;
+				/* we need to always notify this case */
+				flow_info->hoRenewal = false;
+			}
+		} else if (!psb &&
+		((ac_info->num_flows[flow_info->tspec_mask - 1] == 1)
+			    && (SME_QOS_TSPEC_MASK_BIT_1_2_SET !=
+			ac_info->tspec_mask_status))) {
+			/* this is the only TSPEC active on this AC */
+			/* so indicate that we no longer require APSD */
+			qos_session->apsdMask &=
+				~(1 << (SME_QOS_EDCA_AC_VO - ac));
+			/* Also update modifyProfileFields.uapsd_mask
+			 * in CSR for consistency
+			 */
+			csr_get_modify_profile_fields(mac_ctx,
+				flow_info->sessionId,
+				&profile_fields);
+			profile_fields.uapsd_mask =
+				qos_session->apsdMask;
+			csr_set_modify_profile_fields(mac_ctx,
+				flow_info->sessionId,
+				&profile_fields);
+			if (!qos_session->apsdMask)
+				sme_ps_uapsd_disable(MAC_HANDLE(mac_ctx),
+					flow_info->sessionId);
+		}
+		break;
+	case SME_QOS_REASON_REQ_SUCCESS:
+		hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND;
+		inform_hdd = true;
+	/* fallthrough */
+	default:
+		delete_entry = false;
+		break;
+	}
+	if (inform_hdd) {
+		if (!flow_info->hoRenewal) {
+			flow_info->QoSCallback(MAC_HANDLE(mac_ctx),
+					       flow_info->HDDcontext,
+					       &ac_info->curr_QoSInfo[tspec_index],
+					       hdd_status,
+					       flow_info->QosFlowID);
+		} else
+			flow_info->hoRenewal = false;
+	}
+	if (delete_entry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("Deleting entry at %pK with flowID %d"),
+			flow_info, flow_info->QosFlowID);
+		/* delete the entry from Flow List */
+		csr_ll_remove_entry(&sme_qos_cb.flow_list, entry, true);
+		/* reclaim the memory */
+		qdf_mem_free(flow_info);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * sme_qos_is_rsp_pending() - Utility function to check if we are waiting
+ *  for an AddTS or reassoc response on some AC other than the given AC
+ *
+ * sessionId - Session we are interted in
+ * ac - Enumeration of the various EDCA Access Categories.
+ *
+ * Return bool
+ *  true - Response is pending on an AC
+ */
+static bool sme_qos_is_rsp_pending(uint8_t sessionId, sme_QosEdcaAcType ac)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	sme_QosEdcaAcType acIndex;
+	bool status = false;
+
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	for (acIndex = SME_QOS_EDCA_AC_BE; acIndex < SME_QOS_EDCA_AC_MAX;
+	     acIndex++) {
+		if (acIndex == ac)
+			continue;
+		pACInfo = &pSession->ac_info[acIndex];
+		if ((pACInfo->tspec_pending) || (pACInfo->reassoc_pending)) {
+			status = true;
+			break;
+		}
+	}
+	return status;
+}
+
+/*
+ * sme_qos_update_hand_off() - Function which can be called to update
+ *  Hand-off state of SME QoS Session
+ *
+ * sessionId - session id
+ * updateHandOff - value True/False to update the handoff flag
+ */
+void sme_qos_update_hand_off(uint8_t sessionId, bool updateHandOff)
+{
+	struct sme_qos_sessioninfo *pSession;
+
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: handoffRequested %d updateHandOff %d",
+		  __func__, __LINE__, pSession->handoffRequested,
+		  updateHandOff);
+
+	pSession->handoffRequested = updateHandOff;
+
+}
+
+/*
+ * sme_qos_is_uapsd_active() - Function which can be called to determine
+ *  if any sessions require PMC to be in U-APSD mode.
+ * Return bool
+ *
+ *  Returns true if at least one session required PMC to be in U-APSD mode
+ *  Returns false if no sessions require PMC to be in U-APSD mode
+ */
+static bool sme_qos_is_uapsd_active(void)
+{
+	struct sme_qos_sessioninfo *pSession;
+	uint8_t sessionId;
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) {
+		pSession = &sme_qos_cb.sessionInfo[sessionId];
+		if ((pSession->sessionActive) && (pSession->apsdMask))
+			return true;
+	}
+	/* no active sessions have U-APSD active */
+	return false;
+}
+
+QDF_STATUS sme_offload_qos_process_out_of_uapsd_mode(tpAniSirGlobal pMac,
+						     uint32_t sessionId)
+{
+	struct sme_qos_sessioninfo *pSession;
+	tListElem *pEntry = NULL, *pNextEntry = NULL;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+
+	pEntry = csr_ll_peek_head(&sme_qos_cb.flow_list, false);
+	if (!pEntry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Flow List empty, can't search",
+			  __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	while (pEntry) {
+		pNextEntry = csr_ll_next(&sme_qos_cb.flow_list, pEntry, false);
+		flow_info = GET_BASE_ADDR(pEntry, struct sme_qos_flowinfoentry,
+					link);
+		pSession = &sme_qos_cb.sessionInfo[flow_info->sessionId];
+		/* only notify the flows which already successfully setup
+		 * UAPSD
+		 */
+		if ((sessionId == flow_info->sessionId) &&
+		    (flow_info->QoSInfo.max_service_interval ||
+		     flow_info->QoSInfo.min_service_interval) &&
+		    (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason)) {
+			flow_info->QoSCallback(MAC_HANDLE(pMac),
+					       flow_info->HDDcontext,
+					       &pSession->ac_info[flow_info->
+							ac_type].curr_QoSInfo
+					       [flow_info->tspec_mask - 1],
+				SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND,
+					       flow_info->QosFlowID);
+		}
+		pEntry = pNextEntry;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS sme_offload_qos_process_into_uapsd_mode(tpAniSirGlobal pMac,
+						   uint32_t sessionId)
+{
+	struct sme_qos_sessioninfo *pSession;
+	tListElem *pEntry = NULL, *pNextEntry = NULL;
+	struct sme_qos_flowinfoentry *flow_info = NULL;
+
+	pEntry = csr_ll_peek_head(&sme_qos_cb.flow_list, false);
+	if (!pEntry) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Flow List empty, can't search",
+			  __func__, __LINE__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	while (pEntry) {
+		pNextEntry = csr_ll_next(&sme_qos_cb.flow_list, pEntry, false);
+		flow_info = GET_BASE_ADDR(pEntry, struct sme_qos_flowinfoentry,
+					link);
+		pSession = &sme_qos_cb.sessionInfo[flow_info->sessionId];
+		/* only notify the flows which already successfully setup
+		 * UAPSD
+		 */
+		if ((sessionId == flow_info->sessionId) &&
+		    (flow_info->QoSInfo.max_service_interval ||
+		     flow_info->QoSInfo.min_service_interval) &&
+		    (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason)) {
+			flow_info->QoSCallback(MAC_HANDLE(pMac),
+					       flow_info->HDDcontext,
+					       &pSession->ac_info[flow_info->
+							ac_type].curr_QoSInfo
+					       [flow_info->tspec_mask - 1],
+					SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND,
+					       flow_info->QosFlowID);
+		}
+		pEntry = pNextEntry;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+void sme_qos_cleanup_ctrl_blk_for_handoff(tpAniSirGlobal pMac,
+					uint8_t sessionId)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	sme_QosEdcaAcType ac;
+
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("invoked on session %d"), sessionId);
+
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		pACInfo = &pSession->ac_info[ac];
+		qdf_mem_zero(pACInfo->curr_QoSInfo,
+			     sizeof(struct sme_qos_wmmtspecinfo) *
+			     SME_QOS_TSPEC_INDEX_MAX);
+		qdf_mem_zero(pACInfo->requested_QoSInfo,
+			     sizeof(struct sme_qos_wmmtspecinfo) *
+			     SME_QOS_TSPEC_INDEX_MAX);
+		pACInfo->num_flows[0] = 0;
+		pACInfo->num_flows[1] = 0;
+		pACInfo->reassoc_pending = false;
+		pACInfo->tspec_mask_status = 0;
+		pACInfo->tspec_pending = false;
+		pACInfo->hoRenewal = false;
+		pACInfo->prev_state = SME_QOS_LINK_UP;
+	}
+}
+
+/**
+ * sme_qos_is_ts_info_ack_policy_valid() - check if ACK policy is allowed.
+ * @mac_handle: The handle returned by mac_open.
+ * @pQoSInfo: Pointer to struct sme_qos_wmmtspecinfo which contains the
+ *            WMM TSPEC related info, provided by HDD
+ * @sessionId: sessionId returned by sme_open_session.
+ *
+ * The SME QoS API exposed to HDD to check if TS info ack policy field can be
+ * set to "HT-immediate block acknowledgment"
+ *
+ * Return: true - Current Association is HT association and so TS info ack
+ *                 policy can be set to "HT-immediate block acknowledgment"
+ */
+bool sme_qos_is_ts_info_ack_policy_valid(mac_handle_t mac_handle,
+					 struct sme_qos_wmmtspecinfo *pQoSInfo,
+					 uint8_t sessionId)
+{
+	tDot11fBeaconIEs *pIes = NULL;
+	struct sme_qos_sessioninfo *pSession;
+	QDF_STATUS hstatus;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
+
+	if (!CSR_IS_SESSION_VALID(mac, sessionId)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Session Id %d is invalid",
+			  __func__, __LINE__, sessionId);
+		return false;
+	}
+
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+
+	if (!pSession->sessionActive) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Session %d is inactive",
+			  __func__, __LINE__, sessionId);
+		return false;
+	}
+
+	if (!pSession->assocInfo.pBssDesc) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: Session %d has an Invalid BSS Descriptor",
+			  __func__, __LINE__, sessionId);
+		return false;
+	}
+
+	hstatus = csr_get_parsed_bss_description_ies(mac,
+						   pSession->assocInfo.pBssDesc,
+						      &pIes);
+	if (!QDF_IS_STATUS_SUCCESS(hstatus)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: On session %d unable to parse BSS IEs",
+			  __func__, __LINE__, sessionId);
+		return false;
+	}
+
+	/* success means pIes was allocated */
+
+	if (!pIes->HTCaps.present &&
+	    pQoSInfo->ts_info.ack_policy ==
+	    SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "%s: %d: On session %d HT Caps aren't present but application set ack policy to HT ",
+			  __func__, __LINE__, sessionId);
+
+		qdf_mem_free(pIes);
+		return false;
+	}
+
+	qdf_mem_free(pIes);
+	return true;
+}
+
+static bool sme_qos_validate_requested_params(tpAniSirGlobal mac,
+				       struct sme_qos_wmmtspecinfo *qos_info,
+				       uint8_t session_id)
+{
+	if (SME_QOS_WMM_TS_DIR_RESV == qos_info->ts_info.direction)
+		return false;
+	if (!sme_qos_is_ts_info_ack_policy_valid(MAC_HANDLE(mac),
+						 qos_info, session_id))
+		return false;
+
+	return true;
+}
+
+static QDF_STATUS qos_issue_command(tpAniSirGlobal pMac, uint8_t sessionId,
+				    eSmeCommandType cmdType,
+				    struct sme_qos_wmmtspecinfo *pQoSInfo,
+				    sme_QosEdcaAcType ac, uint8_t tspec_mask)
+{
+	QDF_STATUS status = QDF_STATUS_E_RESOURCES;
+	tSmeCmd *pCommand = NULL;
+
+	do {
+		pCommand = csr_get_command_buffer(pMac);
+		if (!pCommand) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: fail to get command buffer for command %d",
+				  __func__, __LINE__, cmdType);
+			break;
+		}
+		pCommand->command = cmdType;
+		pCommand->sessionId = sessionId;
+		switch (cmdType) {
+		case eSmeCommandAddTs:
+			if (pQoSInfo) {
+				status = QDF_STATUS_SUCCESS;
+				pCommand->u.qosCmd.tspecInfo = *pQoSInfo;
+				pCommand->u.qosCmd.ac = ac;
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_SME,
+					  QDF_TRACE_LEVEL_ERROR,
+					  "%s: %d: NULL pointer passed",
+					  __func__, __LINE__);
+				status = QDF_STATUS_E_INVAL;
+			}
+			break;
+		case eSmeCommandDelTs:
+			status = QDF_STATUS_SUCCESS;
+			pCommand->u.qosCmd.ac = ac;
+			pCommand->u.qosCmd.tspec_mask = tspec_mask;
+			break;
+		default:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: invalid command type %d",
+				  __func__, __LINE__, cmdType);
+			status = QDF_STATUS_E_INVAL;
+			break;
+		}
+	} while (0);
+	if (QDF_IS_STATUS_SUCCESS(status) && pCommand)
+		csr_queue_sme_command(pMac, pCommand, false);
+	else if (pCommand)
+		qos_release_command(pMac, pCommand);
+
+	return status;
+}
+
+bool qos_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	bool fRemoveCmd = true;
+
+	do {
+		switch (pCommand->command) {
+		case eSmeCommandAddTs:
+			status =
+				sme_qos_add_ts_req(pMac, (uint8_t)
+						pCommand->sessionId,
+						  &pCommand->u.qosCmd.tspecInfo,
+						   pCommand->u.qosCmd.ac);
+			if (QDF_IS_STATUS_SUCCESS(status))
+				fRemoveCmd = false;
+			break;
+		case eSmeCommandDelTs:
+			status =
+				sme_qos_del_ts_req(pMac, (uint8_t)
+						pCommand->sessionId,
+						   pCommand->u.qosCmd.ac,
+						 pCommand->u.qosCmd.tspec_mask);
+			if (QDF_IS_STATUS_SUCCESS(status))
+				fRemoveCmd = false;
+			break;
+		default:
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  "%s: %d: invalid command type %d",
+				  __func__, __LINE__, pCommand->command);
+			break;
+		} /* switch */
+	} while (0);
+	return fRemoveCmd;
+}
+
+/**
+ * sme_qos_re_request_add_ts - Re-send AddTS for the combined QoS request
+ *
+ * @mac_ctx  Pointer to mac context
+ * @session_id  SME session id
+ * @qos_info - Tspec information
+ * @ac - Access category
+ * @tspec_mask - Tspec Mask
+ *
+ * This function is called to re-send AddTS for the combined QoS request
+ *
+ * Return: status
+ */
+static
+enum sme_qos_statustype sme_qos_re_request_add_ts(tpAniSirGlobal mac_ctx,
+		uint8_t session_id, struct sme_qos_wmmtspecinfo *qos_info,
+		sme_QosEdcaAcType ac, uint8_t tspec_mask)
+{
+	struct sme_qos_sessioninfo *session;
+	struct sme_qos_acinfo *ac_info;
+	enum sme_qos_statustype status =
+		SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
+	struct sme_qos_cmdinfo cmd;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		FL(" Invoked on session %d for AC %d TSPEC %d"),
+		session_id, ac, tspec_mask);
+	session = &sme_qos_cb.sessionInfo[session_id];
+	ac_info = &session->ac_info[ac];
+	/*
+	 * call PMC's request for power function
+	 * AND another check is added considering the flowing scenario
+	 * Addts reqest is pending on one AC, while APSD requested on
+	 * another which needs a reassoc. Will buffer a request if Addts
+	 * is pending on any AC, which will safegaurd the above scenario,
+	 * 2& also won't confuse PE with back to back Addts or Addts
+	 * followed by Reassoc.
+	 */
+	if (sme_qos_is_rsp_pending(session_id, ac)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"On session %d buffering the AddTS request for AC %d in state %d as Addts is pending on other AC or waiting for full power",
+			session_id, ac, ac_info->curr_state);
+		/* buffer cmd */
+		cmd.command = SME_QOS_RESEND_REQ;
+		cmd.pMac = mac_ctx;
+		cmd.sessionId = session_id;
+		cmd.u.resendCmdInfo.ac = ac;
+		cmd.u.resendCmdInfo.tspecMask = tspec_mask;
+		cmd.u.resendCmdInfo.QoSInfo = *qos_info;
+		if (!QDF_IS_STATUS_SUCCESS(sme_qos_buffer_cmd(&cmd, false))) {
+			QDF_TRACE(QDF_MODULE_ID_SME,
+				QDF_TRACE_LEVEL_ERROR,
+				"On session %d unable to buffer the AddTS request for AC %d TSPEC %d in state %d",
+				session_id, ac, tspec_mask,
+				ac_info->curr_state);
+			return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
+		}
+		return SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
+	}
+
+	/* get into the stat m/c to see if the request can be granted */
+	switch (ac_info->curr_state) {
+	case SME_QOS_QOS_ON:
+	{
+		/* if ACM, send out a new ADDTS */
+		ac_info->hoRenewal = true;
+		status = sme_qos_setup(mac_ctx, session_id, qos_info, ac);
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("sme_qos_setup returned in SME_QOS_QOS_ON state"));
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			FL("sme_qos_setup AC %d with status =%d"), ac, status);
+		if (SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) {
+			status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
+			ac_info->tspec_pending = tspec_mask;
+		} else if ((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP ==
+			status) ||
+			(SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY ==
+			status) ||
+			(SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING ==
+			status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("UAPSD is setup already status = %d "),
+				status);
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL("sme_qos_setup return status = %d "),
+				status);
+		}
+	}
+	break;
+	case SME_QOS_HANDOFF:
+	case SME_QOS_REQUESTED:
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("Re-Add request in state = %d  buffer the request"),
+			ac_info->curr_state);
+		cmd.command = SME_QOS_RESEND_REQ;
+		cmd.pMac = mac_ctx;
+		cmd.sessionId = session_id;
+		cmd.u.resendCmdInfo.ac = ac;
+		cmd.u.resendCmdInfo.tspecMask = tspec_mask;
+		cmd.u.resendCmdInfo.QoSInfo = *qos_info;
+		if (!QDF_IS_STATUS_SUCCESS(sme_qos_buffer_cmd(&cmd, false))) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				FL(" couldn't buf the read request state = %d"),
+				ac_info->curr_state);
+			return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP;
+		}
+		status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP;
+		break;
+	case SME_QOS_CLOSED:
+	case SME_QOS_INIT:
+	case SME_QOS_LINK_UP:
+	default:
+		/* print error msg, */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			FL("ReAdd request in unexpected state = %d"),
+			ac_info->curr_state);
+		break;
+	}
+	if ((SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP ==
+		status) ||
+		(SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY ==
+		status))
+		(void)sme_qos_process_buffered_cmd(session_id);
+
+	return status;
+}
+
+static void sme_qos_init_a_cs(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	struct sme_qos_sessioninfo *pSession;
+	sme_QosEdcaAcType ac;
+
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+		qdf_mem_zero(&pSession->ac_info[ac],
+				sizeof(struct sme_qos_acinfo));
+		sme_qos_state_transition(sessionId, ac, SME_QOS_INIT);
+	}
+}
+
+static QDF_STATUS sme_qos_request_reassoc(tpAniSirGlobal pMac,
+					uint8_t sessionId,
+					  tCsrRoamModifyProfileFields *
+					  pModFields, bool fForce)
+{
+	struct sme_qos_sessioninfo *pSession;
+	struct sme_qos_acinfo *pACInfo;
+	QDF_STATUS status;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: %d: Invoked on session %d with UAPSD mask 0x%X",
+		  __func__, __LINE__, sessionId, pModFields->uapsd_mask);
+	pSession = &sme_qos_cb.sessionInfo[sessionId];
+	status = csr_reassoc(pMac, sessionId, pModFields, &pSession->roamID,
+				fForce);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		/* Update the state to Handoff so subsequent requests are
+		 * queued until this one is finished
+		 */
+		sme_QosEdcaAcType ac;
+
+		for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+			pACInfo = &pSession->ac_info[ac];
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+				  "%s: %d: AC[%d] is in state [%d]",
+				  __func__, __LINE__, ac, pACInfo->curr_state);
+			/* If it is already in HANDOFF state, don't do
+			 * anything since we MUST preserve the previous state
+			 * and sme_qos_state_transition will change the previous
+			 * state
+			 */
+			if (SME_QOS_HANDOFF != pACInfo->curr_state)
+				sme_qos_state_transition(sessionId, ac,
+							 SME_QOS_HANDOFF);
+		}
+	}
+	return status;
+}
+
+static uint32_t sme_qos_assign_flow_id(void)
+{
+	uint32_t flowId;
+
+	flowId = sme_qos_cb.nextFlowId;
+	if (SME_QOS_MAX_FLOW_ID == flowId) {
+		/* The Flow ID wrapped.  This is obviously not a real life
+		 * scenario but handle it to keep the software test folks happy
+		 */
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: %d: Software Test made the flow counter wrap, QoS may no longer be functional",
+			  __func__, __LINE__);
+		sme_qos_cb.nextFlowId = SME_QOS_MIN_FLOW_ID;
+	} else
+		sme_qos_cb.nextFlowId++;
+
+	return flowId;
+}
+
+static uint8_t sme_qos_assign_dialog_token(void)
+{
+	uint8_t token;
+
+	token = sme_qos_cb.nextDialogToken;
+	if (SME_QOS_MAX_DIALOG_TOKEN == token)
+		/* wrap is ok */
+		sme_qos_cb.nextDialogToken = SME_QOS_MIN_DIALOG_TOKEN;
+	else
+		sme_qos_cb.nextDialogToken++;
+
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("token %d"), token);
+	return token;
+}
+#endif /* WLAN_MDM_CODE_REDUCTION_OPT */
diff --git a/core/sme/src/rrm/sme_rrm.c b/core/sme/src/rrm/sme_rrm.c
new file mode 100644
index 0000000..d86d72f
--- /dev/null
+++ b/core/sme/src/rrm/sme_rrm.c
@@ -0,0 +1,1597 @@
+/*
+ * Copyright (c) 2011-2018 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: sme_rrm.c
+ *
+ * Implementation for SME RRM APIs
+ */
+
+#include "ani_global.h"
+#include "sme_inside.h"
+#include "sme_api.h"
+#include "cfg_api.h"
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+#include "host_diag_core_event.h"
+#include "host_diag_core_log.h"
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+#include "csr_inside_api.h"
+
+#include "rrm_global.h"
+#include <wlan_scan_ucfg_api.h>
+#include <wlan_scan_utils_api.h>
+#include <wlan_utility.h>
+
+/* Roam score for a neighbor AP will be calculated based on the below
+ * definitions. The calculated roam score will be used to select the
+ * roamable candidate from neighbor AP list
+ */
+#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY             0
+/* When we support 11r over the DS, this should have a non-zero value */
+#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY                 10
+#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE                20
+#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT 0
+/* Not used */
+#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS           5
+#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD          3
+#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM           8
+#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA    0
+/* We dont support delayed BA */
+#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA  3
+#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN          30
+
+#ifdef FEATURE_WLAN_ESE
+#define RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST                       30
+#endif
+
+uint64_t rrm_scan_timer;
+
+/**
+ * rrm_ll_purge_neighbor_cache() -Purges all the entries in the neighbor cache
+ *
+ * @pMac: Pointer to the Hal Handle.
+ * @pList: Pointer the List that should be purged.
+ *
+ * This function purges all the entries in the neighbor cache and frees up all
+ * the internal nodes
+ *
+ * Return: void
+ */
+static void rrm_ll_purge_neighbor_cache(tpAniSirGlobal pMac,
+	tDblLinkList *pList)
+{
+	tListElem *pEntry;
+	tRrmNeighborReportDesc *pNeighborReportDesc;
+
+	csr_ll_lock(pList);
+	while ((pEntry = csr_ll_remove_head(pList, LL_ACCESS_NOLOCK)) != NULL) {
+		pNeighborReportDesc =
+			GET_BASE_ADDR(pEntry, tRrmNeighborReportDesc, List);
+		qdf_mem_free(pNeighborReportDesc->pNeighborBssDescription);
+		qdf_mem_free(pNeighborReportDesc);
+	}
+	csr_ll_unlock(pList);
+}
+
+/**
+ * rrm_indicate_neighbor_report_result() -calls the callback registered for
+ *                                                      neighbor report
+ * @pMac: Pointer to the Hal Handle.
+ * @qdf_status - QDF_STATUS_SUCCESS/QDF_STATUS_FAILURE based on whether a valid
+ *                       report is received or neighbor timer expired
+ *
+ * This function calls the callback register by the caller while requesting for
+ * neighbor report. This function gets invoked if a neighbor report is received
+ * from an AP or neighbor response wait timer expires.
+ *
+ * Return: void
+ */
+static void rrm_indicate_neighbor_report_result(tpAniSirGlobal pMac,
+						QDF_STATUS qdf_status)
+{
+	NeighborReportRspCallback callback;
+	void *callbackContext;
+
+	/* Reset the neighbor response pending status */
+	pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending =
+		false;
+
+	/* Stop the timer if it is already running.
+	 *  The timer should be running only in the SUCCESS case.
+	 */
+	if (QDF_TIMER_STATE_RUNNING ==
+	    qdf_mc_timer_get_current_state(&pMac->rrm.rrmSmeContext.
+					   neighborReqControlInfo.
+					   neighborRspWaitTimer)) {
+		sme_debug("No entry in neighbor report cache");
+		qdf_mc_timer_stop(&pMac->rrm.rrmSmeContext.
+				  neighborReqControlInfo.neighborRspWaitTimer);
+	}
+	callback =
+		pMac->rrm.rrmSmeContext.neighborReqControlInfo.
+		neighborRspCallbackInfo.neighborRspCallback;
+	callbackContext =
+		pMac->rrm.rrmSmeContext.neighborReqControlInfo.
+		neighborRspCallbackInfo.neighborRspCallbackContext;
+
+	/* Reset the callback and the callback context before calling the
+	 * callback. It is very likely that there may be a registration in
+	 * callback itself.
+	 */
+	pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.
+	neighborRspCallback = NULL;
+	pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.
+	neighborRspCallbackContext = NULL;
+
+	/* Call the callback with the status received from caller */
+	if (callback)
+		callback(callbackContext, qdf_status);
+
+
+}
+
+/**
+ * sme_RrmBeaconReportXmitInd () - Send beacon report
+ * @mac_ctx  Pointer to mac context
+ * @result_arr scan results
+ * @msrmnt_status flag to indicate that the measurement is done.
+ * @bss_count  bss count
+ *
+ * Create and send the beacon report Xmit ind message to PE.
+ *
+ * Return: status
+ */
+
+static QDF_STATUS
+sme_rrm_send_beacon_report_xmit_ind(tpAniSirGlobal mac_ctx,
+	tCsrScanResultInfo **result_arr, uint8_t msrmnt_status,
+	uint8_t bss_count)
+{
+	tpSirBssDescription bss_desc = NULL;
+	tpSirBeaconReportXmitInd beacon_rep;
+	uint16_t length;
+	uint32_t size;
+	uint8_t  i = 0, j = 0, counter = 0;
+	tCsrScanResultInfo *cur_result = NULL;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tpRrmSMEContext rrm_ctx = &mac_ctx->rrm.rrmSmeContext;
+	tpSirBssDescription bss_desc_to_free[SIR_BCN_REPORT_MAX_BSS_DESC] = {0};
+
+	if (NULL == result_arr && !msrmnt_status) {
+		sme_err("Beacon report xmit Ind to PE Failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (result_arr)
+		cur_result = result_arr[j];
+
+	do {
+		length = sizeof(tSirBeaconReportXmitInd);
+		beacon_rep = qdf_mem_malloc(length);
+		if (!beacon_rep)
+			return QDF_STATUS_E_NOMEM;
+
+		beacon_rep->messageType = eWNI_SME_BEACON_REPORT_RESP_XMIT_IND;
+		beacon_rep->length = length;
+		beacon_rep->uDialogToken = rrm_ctx->token;
+		beacon_rep->duration = rrm_ctx->duration[0];
+		beacon_rep->regClass = rrm_ctx->regClass;
+		qdf_mem_copy(beacon_rep->bssId, rrm_ctx->sessionBssId.bytes,
+			QDF_MAC_ADDR_SIZE);
+
+		i = 0;
+		while (cur_result) {
+			bss_desc = &cur_result->BssDescriptor;
+			if (bss_desc == NULL)
+				break;
+			size =  bss_desc->length + sizeof(bss_desc->length);
+			beacon_rep->pBssDescription[i] = qdf_mem_malloc(size);
+			if (NULL ==
+				beacon_rep->pBssDescription[i])
+				break;
+			qdf_mem_copy(beacon_rep->pBssDescription[i],
+				bss_desc, size);
+			bss_desc_to_free[i] =
+				beacon_rep->pBssDescription[i];
+			sme_debug("RRM Result Bssid = " MAC_ADDRESS_STR
+				" chan= %d, rssi = -%d",
+				MAC_ADDR_ARRAY(
+				beacon_rep->pBssDescription[i]->bssId),
+				beacon_rep->pBssDescription[i]->channelId,
+				beacon_rep->pBssDescription[i]->rssi * (-1));
+			beacon_rep->numBssDesc++;
+			if (++i >= SIR_BCN_REPORT_MAX_BSS_DESC)
+				break;
+			if (i + j >= bss_count)
+				break;
+			cur_result =
+				result_arr[j + i];
+		}
+
+		j += i;
+		if (!result_arr || (cur_result == NULL)
+			|| (j >= bss_count)) {
+			cur_result = NULL;
+			sme_debug("Reached to  max/last BSS in cur_result list");
+		} else {
+			cur_result = result_arr[j];
+			sme_debug("Move to the next BSS set in cur_result list");
+		}
+		beacon_rep->fMeasureDone =
+			(cur_result) ? false : msrmnt_status;
+		sme_debug("SME Sending BcnRepXmit to PE numBss %d i %d j %d",
+			beacon_rep->numBssDesc, i, j);
+		status = umac_send_mb_message_to_mac(beacon_rep);
+		if (status != QDF_STATUS_SUCCESS)
+			for (counter = 0; counter < i; ++counter)
+				qdf_mem_free(bss_desc_to_free[counter]);
+	} while (cur_result);
+
+	return status;
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * sme_ese_send_beacon_req_scan_results () - Send beacon report
+ * @mac_ctx  Pointer to mac context
+ * @session_id - session id
+ * @result_arr scan results
+ * @msrmnt_status flag to indicate that the measurement is done.
+ * @bss_count  number of bss found
+ *
+ * This function sends up the scan results received as a part of
+ * beacon request scanning.
+ * This function is called after receiving the scan results per channel
+ * Due to the limitation on the size of the IWEVCUSTOM buffer, we send
+ * 3 BSSIDs of beacon report information in one custom event;
+ *
+ * Return: status
+ */
+static QDF_STATUS sme_ese_send_beacon_req_scan_results(
+	tpAniSirGlobal mac_ctx, uint32_t session_id,
+	uint8_t channel, tCsrScanResultInfo **result_arr,
+	uint8_t msrmnt_status, uint8_t bss_count)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	QDF_STATUS fill_ie_status;
+	tpSirBssDescription bss_desc = NULL;
+	uint32_t ie_len = 0;
+	uint32_t out_ie_len = 0;
+	uint8_t bss_counter = 0;
+	tCsrScanResultInfo *cur_result = NULL;
+	tpRrmSMEContext rrm_ctx = &mac_ctx->rrm.rrmSmeContext;
+	struct csr_roam_info roam_info;
+	tSirEseBcnReportRsp bcn_rpt_rsp;
+	tpSirEseBcnReportRsp bcn_report = &bcn_rpt_rsp;
+	tpCsrEseBeaconReqParams cur_meas_req = NULL;
+	uint8_t i = 0, j = 0;
+	tBcnReportFields *bcn_rpt_fields;
+
+	if (NULL == rrm_ctx) {
+		sme_err("rrm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (NULL == result_arr && !msrmnt_status) {
+		sme_err("Beacon report xmit Ind to HDD Failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (result_arr)
+		cur_result = result_arr[bss_counter];
+
+	qdf_mem_zero(&bcn_rpt_rsp, sizeof(tSirEseBcnReportRsp));
+	do {
+		cur_meas_req = NULL;
+		for (i = 0; i < rrm_ctx->eseBcnReqInfo.numBcnReqIe; i++) {
+			if (rrm_ctx->eseBcnReqInfo.bcnReq[i].channel ==
+				channel) {
+				cur_meas_req =
+					&rrm_ctx->eseBcnReqInfo.bcnReq[i];
+				break;
+			}
+		}
+		if (NULL != cur_meas_req)
+			bcn_report->measurementToken =
+				cur_meas_req->measurementToken;
+		sme_debug("Channel: %d MeasToken: %d", channel,
+			bcn_report->measurementToken);
+
+		j = 0;
+		while (cur_result) {
+			bss_desc = &cur_result->BssDescriptor;
+			if (NULL == bss_desc) {
+				cur_result = NULL;
+				break;
+			}
+			ie_len = GET_IE_LEN_IN_BSS(bss_desc->length);
+			bcn_rpt_fields =
+				&bcn_report->bcnRepBssInfo[j].bcnReportFields;
+			bcn_rpt_fields->ChanNum =
+				bss_desc->channelId;
+			bcn_report->bcnRepBssInfo[j].bcnReportFields.Spare = 0;
+			if (NULL != cur_meas_req)
+				bcn_rpt_fields->MeasDuration =
+					cur_meas_req->measurementDuration;
+			bcn_rpt_fields->PhyType = bss_desc->nwType;
+			bcn_rpt_fields->RecvSigPower = bss_desc->rssi;
+			bcn_rpt_fields->ParentTsf = bss_desc->parentTSF;
+			bcn_rpt_fields->TargetTsf[0] = bss_desc->timeStamp[0];
+			bcn_rpt_fields->TargetTsf[1] = bss_desc->timeStamp[1];
+			bcn_rpt_fields->BcnInterval = bss_desc->beaconInterval;
+			bcn_rpt_fields->CapabilityInfo =
+				bss_desc->capabilityInfo;
+
+			qdf_mem_copy(bcn_rpt_fields->Bssid,
+				bss_desc->bssId, sizeof(tSirMacAddr));
+				fill_ie_status =
+					sir_beacon_ie_ese_bcn_report(mac_ctx,
+						(uint8_t *) bss_desc->ieFields,
+						ie_len,
+						&(bcn_report->bcnRepBssInfo[j].
+						pBuf),
+						&out_ie_len);
+			if (QDF_STATUS_E_FAILURE == fill_ie_status)
+				continue;
+			bcn_report->bcnRepBssInfo[j].ieLen = out_ie_len;
+
+			sme_debug("Bssid"MAC_ADDRESS_STR" Channel: %d Rssi: %d",
+				MAC_ADDR_ARRAY(bss_desc->bssId),
+				bss_desc->channelId, (-1) * bss_desc->rssi);
+			bcn_report->numBss++;
+			if (++j >= SIR_BCN_REPORT_MAX_BSS_DESC)
+				break;
+			if (j >= bss_count)
+				break;
+			cur_result = result_arr[j];
+		}
+
+		bss_counter += j;
+		if (!result_arr || !cur_result
+		|| (bss_counter >= SIR_BCN_REPORT_MAX_BSS_DESC)) {
+			cur_result = NULL;
+			sme_err("Reached to the max/last BSS in cur_result list");
+		} else {
+			cur_result = result_arr[bss_counter];
+			sme_err("Move to the next BSS set in cur_result list");
+		}
+
+		bcn_report->flag =
+			(msrmnt_status << 1) | ((cur_result) ? true : false);
+
+		sme_debug("SME Sending BcnRep to HDD numBss: %d j: %d bss_counter: %d flag: %d",
+			bcn_report->numBss, j, bss_counter,
+			bcn_report->flag);
+
+		roam_info.pEseBcnReportRsp = bcn_report;
+		status = csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+			0, eCSR_ROAM_ESE_BCN_REPORT_IND, 0);
+
+		/* Free the memory allocated to IE */
+		for (i = 0; i < j; i++)
+			if (bcn_report->bcnRepBssInfo[i].pBuf)
+				qdf_mem_free(bcn_report->bcnRepBssInfo[i].pBuf);
+	} while (cur_result);
+	return status;
+}
+
+#endif /* FEATURE_WLAN_ESE */
+
+/**
+ * sme_rrm_send_scan_result() - to get scan result and send the beacon report
+ * @mac_ctx: pointer to mac context
+ * @num_chan: number of channels
+ * @chan_list: list of channels to fetch the result from
+ * @measurementdone: Flag to indicate measurement done or no
+ *
+ * This function is called to get the scan result from CSR and send the beacon
+ * report xmit ind message to PE
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_rrm_send_scan_result(tpAniSirGlobal mac_ctx,
+					   uint8_t num_chan,
+					   uint8_t *chan_list,
+					   uint8_t measurementdone)
+{
+	mac_handle_t mac_handle = MAC_HANDLE(mac_ctx);
+	tCsrScanResultFilter filter;
+	tScanResultHandle result_handle;
+	tCsrScanResultInfo *scan_results, *next_result;
+	tCsrScanResultInfo **scanresults_arr = NULL;
+	struct scan_result_list *result_list;
+	QDF_STATUS status;
+	uint8_t num_scan_results, counter = 0;
+	tpRrmSMEContext rrm_ctx = &mac_ctx->rrm.rrmSmeContext;
+	uint32_t session_id;
+	struct csr_roam_info *roam_info = NULL;
+	tSirScanType scan_type;
+	struct csr_roam_session *session;
+
+	qdf_mem_zero(&filter, sizeof(filter));
+	filter.BSSIDs.numOfBSSIDs = 1;
+	filter.BSSIDs.bssid = (struct qdf_mac_addr *)&rrm_ctx->bssId;
+
+	if (rrm_ctx->ssId.length) {
+		filter.SSIDs.SSIDList = qdf_mem_malloc(sizeof(tCsrSSIDInfo));
+		if (!filter.SSIDs.SSIDList)
+			return QDF_STATUS_E_NOMEM;
+
+		filter.SSIDs.SSIDList->SSID.length =
+			rrm_ctx->ssId.length;
+		qdf_mem_copy(filter.SSIDs.SSIDList->SSID.ssId,
+				rrm_ctx->ssId.ssId, rrm_ctx->ssId.length);
+		filter.SSIDs.numOfSSIDs = 1;
+	} else {
+		filter.SSIDs.numOfSSIDs = 0;
+	}
+
+	filter.ChannelInfo.numOfChannels = num_chan;
+	filter.ChannelInfo.ChannelList = chan_list;
+	filter.fMeasurement = true;
+
+	/*
+	 * In case this is beacon report request from last AP (before roaming)
+	 * following call to csr_roam_get_session_id_from_bssid will fail,
+	 * hence use current session ID instead of one stored in SME rrm context
+	 */
+	if (QDF_STATUS_E_FAILURE == csr_roam_get_session_id_from_bssid(mac_ctx,
+			&rrm_ctx->sessionBssId, &session_id)) {
+		sme_debug("BSSID mismatch, using current session_id");
+		session_id = mac_ctx->roam.roamSession->sessionId;
+	}
+	status = sme_scan_get_result(mac_handle, (uint8_t)session_id,
+				     &filter, &result_handle);
+
+	if (filter.SSIDs.SSIDList)
+		qdf_mem_free(filter.SSIDs.SSIDList);
+
+	sme_debug("RRM Measurement Done %d", measurementdone);
+	if (NULL == result_handle) {
+		/*
+		 * no scan results
+		 * Spec. doesn't say anything about such condition
+		 * Since section 7.4.6.2 (IEEE802.11k-2008) says-rrm report
+		 * frame should contain one or more report IEs. It probably
+		 * means dont send any respose if no matching BSS found.
+		 * Moreover, there is no flag or field in measurement report
+		 * IE(7.3.2.22) OR beacon report IE(7.3.2.22.6) that can be set
+		 * to indicate no BSS found on a given channel. If we finished
+		 * measurement on all the channels, we still need to send a
+		 * xmit indication with moreToFollow set to MEASURMENT_DONE so
+		 * that PE can clean any context allocated.
+		 */
+		if (!measurementdone)
+			return status;
+#ifdef FEATURE_WLAN_ESE
+		if (eRRM_MSG_SOURCE_ESE_UPLOAD == rrm_ctx->msgSource)
+			status = sme_ese_send_beacon_req_scan_results(mac_ctx,
+					session_id, chan_list[0],
+					NULL, measurementdone, 0);
+		else
+#endif /* FEATURE_WLAN_ESE */
+			status = sme_rrm_send_beacon_report_xmit_ind(mac_ctx,
+					NULL, measurementdone, 0);
+		return status;
+	}
+	scan_results = sme_scan_result_get_first(mac_handle, result_handle);
+	if (NULL == scan_results && measurementdone) {
+#ifdef FEATURE_WLAN_ESE
+		if (eRRM_MSG_SOURCE_ESE_UPLOAD == rrm_ctx->msgSource) {
+			status = sme_ese_send_beacon_req_scan_results(mac_ctx,
+					session_id,
+					chan_list[0],
+					NULL,
+					measurementdone,
+					0);
+		} else
+#endif /* FEATURE_WLAN_ESE */
+			status = sme_rrm_send_beacon_report_xmit_ind(mac_ctx,
+						NULL, measurementdone, 0);
+	}
+
+	result_list = (struct scan_result_list *)result_handle;
+	num_scan_results = csr_ll_count(&result_list->List);
+	if (!num_scan_results) {
+		sme_err("num_scan_results is %d", num_scan_results);
+		status = QDF_STATUS_E_FAILURE;
+		goto rrm_send_scan_results_done;
+	}
+
+	sme_debug("num_scan_results %d", num_scan_results);
+	scanresults_arr = qdf_mem_malloc(num_scan_results *
+					 sizeof(next_result));
+	if (!scanresults_arr) {
+		status = QDF_STATUS_E_NOMEM;
+		goto rrm_send_scan_results_done;
+	}
+
+	roam_info = qdf_mem_malloc(sizeof(*roam_info));
+	if (!roam_info) {
+		status = QDF_STATUS_E_NOMEM;
+		goto rrm_send_scan_results_done;
+	}
+
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+	if ((!session) ||  (!csr_is_conn_state_connected_infra(
+	    mac_ctx, session_id)) ||
+	    (NULL == session->pConnectBssDesc)) {
+		sme_err("Invaild session");
+		status = QDF_STATUS_E_FAILURE;
+		goto rrm_send_scan_results_done;
+	}
+
+	if (eRRM_MSG_SOURCE_ESE_UPLOAD == rrm_ctx->msgSource ||
+	    eRRM_MSG_SOURCE_LEGACY_ESE == rrm_ctx->msgSource)
+		scan_type = rrm_ctx->measMode[rrm_ctx->currentIndex];
+	else
+		scan_type = rrm_ctx->measMode[0];
+
+	while (scan_results) {
+		/*
+		 * In passive scan, sta listens beacon. Connected AP beacon
+		 * is offloaded to firmware. Firmware will discard
+		 * connected AP beacon except that special IE exists.
+		 * Connected AP beacon will not be sent to host. Hence, timer
+		 * of connected AP in scan results is not updated and can
+		 * not meet "pScanResult->timer >= RRM_scan_timer".
+		 */
+		uint8_t is_conn_bss_found = false;
+
+		if ((scan_type == eSIR_PASSIVE_SCAN) &&
+		     (!qdf_mem_cmp(scan_results->BssDescriptor.bssId,
+		      session->pConnectBssDesc->bssId,
+		      sizeof(struct qdf_mac_addr)))) {
+			is_conn_bss_found = true;
+			sme_debug("Connected BSS in scan results");
+		}
+		next_result = sme_scan_result_get_next(mac_handle,
+						       result_handle);
+		sme_debug("Scan res timer:%lu, rrm scan timer:%llu",
+				scan_results->timer, rrm_scan_timer);
+		if ((scan_results->timer >= rrm_scan_timer) ||
+		    (is_conn_bss_found == true)) {
+			roam_info->pBssDesc = &scan_results->BssDescriptor;
+			csr_roam_call_callback(mac_ctx, session_id, roam_info,
+						0, eCSR_ROAM_UPDATE_SCAN_RESULT,
+						eCSR_ROAM_RESULT_NONE);
+			scanresults_arr[counter++] = scan_results;
+		}
+		scan_results = next_result;
+		if (counter >= num_scan_results)
+			break;
+	}
+	/*
+	 * The beacon report should be sent whether the counter is zero or
+	 * non-zero. There might be a few scan results in the cache but not
+	 * actually are a result of this scan. During that scenario, the
+	 * counter will be zero. The report should be sent and LIM will further
+	 * cleanup the RRM to accept the further incoming requests
+	 * In case the counter is Zero, the pScanResultsArr will be NULL.
+	 * The next level routine does a check for the measurementDone to
+	 * determine whether to send a report or not.
+	 */
+	sme_debug("Number of BSS Desc with RRM Scan %d", counter);
+	if (counter || measurementdone) {
+#ifdef FEATURE_WLAN_ESE
+		if (eRRM_MSG_SOURCE_ESE_UPLOAD == rrm_ctx->msgSource)
+			status = sme_ese_send_beacon_req_scan_results(mac_ctx,
+					session_id, chan_list[0],
+					scanresults_arr, measurementdone,
+					counter);
+		else
+#endif /* FEATURE_WLAN_ESE */
+			status = sme_rrm_send_beacon_report_xmit_ind(mac_ctx,
+					scanresults_arr, measurementdone,
+					counter);
+	}
+
+rrm_send_scan_results_done:
+	if (scanresults_arr)
+		qdf_mem_free(scanresults_arr);
+	qdf_mem_free(roam_info);
+	sme_scan_result_purge(result_handle);
+
+	return status;
+}
+
+
+/**
+ * sme_rrm_scan_request_callback() -Sends the beacon report xmit to PE
+ * @halHandle: Pointer to the Hal Handle.
+ * @sessionId: session id
+ * @scanId: Scan ID.
+ * @status: CSR Status.
+ *
+ * The sme module calls this callback function once it finish the scan request
+ * and this function send the beacon report xmit to PE and starts a timer of
+ * random interval to issue next request.
+ *
+ * Return : 0 for success, non zero for failure
+ */
+static QDF_STATUS sme_rrm_scan_request_callback(tHalHandle halHandle,
+						uint8_t sessionId,
+						uint32_t scanId,
+						eCsrScanStatus status)
+{
+	uint16_t interval;
+	tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
+	tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
+	uint32_t time_tick;
+
+	/* if any more channels are pending, start a timer of a random value
+	 * within randomization interval.
+	 */
+	if ((pSmeRrmContext->currentIndex + 1) <
+	    pSmeRrmContext->channelList.numOfChannels) {
+		sme_rrm_send_scan_result(pMac, 1,
+					 &pSmeRrmContext->channelList.
+					 ChannelList[pSmeRrmContext
+					->currentIndex],
+					 false);
+		/* Advance the current index. */
+		pSmeRrmContext->currentIndex++;
+		/* start the timer to issue next request. */
+		/* From timer tick get a random number within 10ms and max
+		 * randmization interval.
+		 */
+		time_tick = qdf_mc_timer_get_system_ticks();
+		interval =
+			time_tick % (pSmeRrmContext->randnIntvl - 10 + 1) + 10;
+
+		sme_debug("Set timer for interval %d ", interval);
+		qdf_mc_timer_start(&pSmeRrmContext->IterMeasTimer, interval);
+
+	} else {
+		/* Done with the measurement. Clean up all context and send a
+		 * message to PE with measurement done flag set.
+		 */
+		sme_rrm_send_scan_result(pMac, 1,
+					 &pSmeRrmContext->channelList.
+					 ChannelList[pSmeRrmContext
+					->currentIndex],
+					 true);
+		qdf_mem_free(pSmeRrmContext->channelList.ChannelList);
+#ifdef FEATURE_WLAN_ESE
+		pSmeRrmContext->eseBcnReqInProgress = false;
+#endif
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void sme_rrm_scan_event_callback(struct wlan_objmgr_vdev *vdev,
+			struct scan_event *event, void *arg)
+{
+	uint32_t scan_id;
+	uint8_t session_id;
+	eCsrScanStatus scan_status = eCSR_SCAN_FAILURE;
+	tHalHandle hal_handle;
+	bool success = false;
+	session_id = wlan_vdev_get_id(vdev);
+	scan_id = event->scan_id;
+	hal_handle = cds_get_context(QDF_MODULE_ID_SME);
+	if (!hal_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
+			  FL("invalid h_hal"));
+		return;
+	}
+
+	qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SME, event->type,
+		   event->vdev_id, event->scan_id);
+
+	if (!util_is_scan_completed(event, &success))
+		return;
+
+	if (success)
+		scan_status = eCSR_SCAN_SUCCESS;
+
+	sme_rrm_scan_request_callback(hal_handle, session_id,
+					scan_id, scan_status);
+}
+
+
+/**
+ * sme_rrm_issue_scan_req() - To issue rrm scan request
+ * @mac_ctx: pointer to mac context
+ *
+ * This routine is called to issue rrm scan request
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_rrm_issue_scan_req(tpAniSirGlobal mac_ctx)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpRrmSMEContext sme_rrm_ctx = &mac_ctx->rrm.rrmSmeContext;
+	uint32_t session_id;
+	tSirScanType scan_type;
+
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+			&sme_rrm_ctx->sessionBssId, &session_id);
+	if (status != QDF_STATUS_SUCCESS) {
+		sme_err("sme session ID not found for bssid= "MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(sme_rrm_ctx->sessionBssId.bytes));
+		status = QDF_STATUS_E_FAILURE;
+		goto free_ch_lst;
+	}
+
+	if ((sme_rrm_ctx->currentIndex) >=
+			sme_rrm_ctx->channelList.numOfChannels) {
+		sme_rrm_send_beacon_report_xmit_ind(mac_ctx, NULL, true, 0);
+		sme_debug("done with the complete ch lt. finish and fee now");
+		goto free_ch_lst;
+	}
+
+	if (eRRM_MSG_SOURCE_ESE_UPLOAD == sme_rrm_ctx->msgSource ||
+		eRRM_MSG_SOURCE_LEGACY_ESE == sme_rrm_ctx->msgSource)
+		scan_type = sme_rrm_ctx->measMode[sme_rrm_ctx->currentIndex];
+	else
+		scan_type = sme_rrm_ctx->measMode[0];
+
+	if ((eSIR_ACTIVE_SCAN == scan_type) ||
+			(eSIR_PASSIVE_SCAN == scan_type)) {
+		uint32_t max_chan_time;
+		uint64_t current_time;
+		struct scan_start_request *req;
+		struct wlan_objmgr_vdev *vdev;
+		uint32_t chan_num;
+
+		req = qdf_mem_malloc(sizeof(*req));
+		if (!req)
+			return QDF_STATUS_E_NOMEM;
+
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+						mac_ctx->psoc,
+						session_id,
+						WLAN_LEGACY_SME_ID);
+		if (!vdev) {
+			sme_err("VDEV is null %d", session_id);
+			return QDF_STATUS_E_INVAL;
+		}
+		ucfg_scan_init_default_params(vdev, req);
+		req->scan_req.dwell_time_active = 0;
+		req->scan_req.scan_id = ucfg_scan_get_scan_id(mac_ctx->psoc);
+		req->scan_req.scan_f_passive =
+				(scan_type == eSIR_ACTIVE_SCAN) ? false : true;
+		req->scan_req.vdev_id = wlan_vdev_get_id(vdev);
+		req->scan_req.scan_req_id = sme_rrm_ctx->req_id;
+		qdf_mem_copy(&req->scan_req.bssid_list[0], sme_rrm_ctx->bssId,
+				QDF_MAC_ADDR_SIZE);
+		req->scan_req.num_bssid = 1;
+		if (sme_rrm_ctx->ssId.length) {
+			req->scan_req.num_ssids = 1;
+			qdf_mem_copy(&req->scan_req.ssid[0].ssid,
+					sme_rrm_ctx->ssId.ssId,
+					sme_rrm_ctx->ssId.length);
+			req->scan_req.ssid[0].length = sme_rrm_ctx->ssId.length;
+		}
+
+		/*
+		 * set min and max channel time
+		 * sme_rrm_ctx->duration; Dont use min timeout.
+		 */
+		if (eRRM_MSG_SOURCE_ESE_UPLOAD == sme_rrm_ctx->msgSource ||
+			eRRM_MSG_SOURCE_LEGACY_ESE == sme_rrm_ctx->msgSource)
+			req->scan_req.dwell_time_active = sme_rrm_ctx->duration[
+						sme_rrm_ctx->currentIndex];
+		else
+			req->scan_req.dwell_time_active =
+						sme_rrm_ctx->duration[0];
+
+		sme_debug("Scan Type(%d) Max Dwell Time(%d)",
+				scan_type,
+				req->scan_req.dwell_time_active);
+		/*
+		 * Use gPassive/gActiveMaxChannelTime if maxChanTime is less
+		 * than default.
+		 */
+		if (eSIR_ACTIVE_SCAN == scan_type)
+			max_chan_time =
+				mac_ctx->roam.configParam.nActiveMaxChnTime;
+		else
+			max_chan_time =
+				mac_ctx->roam.configParam.nPassiveMaxChnTime;
+
+		if (req->scan_req.dwell_time_active < max_chan_time) {
+			req->scan_req.dwell_time_active = max_chan_time;
+			sme_debug("Setting default max %d ChanTime",
+				max_chan_time);
+		}
+
+		req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC;
+		/*
+		 * For RRM scans timing is very important especially when the
+		 * request is for limited channels. There is no need for
+		 * firmware to rest for about 100-200 ms on the home channel.
+		 * Instead, it can start the scan right away which will make the
+		 * host to respond with the beacon report as quickly as
+		 * possible. Ensure that the scan requests are not back to back
+		 * and hence there is a check to see if the requests are atleast
+		 * 1 second apart.
+		 */
+		current_time = (uint64_t)qdf_mc_timer_get_system_time();
+		sme_debug("prev scan triggered before %llu ms, totalchannels %d",
+				current_time - rrm_scan_timer,
+				sme_rrm_ctx->channelList.numOfChannels);
+		if ((abs(current_time - rrm_scan_timer) > 1000) &&
+				(sme_rrm_ctx->channelList.numOfChannels == 1)) {
+			req->scan_req.max_rest_time = 1;
+			req->scan_req.min_rest_time = 1;
+			req->scan_req.idle_time = 1;
+		}
+
+		rrm_scan_timer = (uint64_t)qdf_mc_timer_get_system_time();
+
+		/* set requestType to full scan */
+		req->scan_req.chan_list.num_chan = 1;
+		chan_num = sme_rrm_ctx->channelList.ChannelList[
+			   sme_rrm_ctx->currentIndex];
+		req->scan_req.chan_list.chan[0].freq =
+			wlan_chan_to_freq(chan_num);
+		sme_debug("Duration %d On channel %d freq %d",
+				req->scan_req.dwell_time_active,
+				chan_num,
+				req->scan_req.chan_list.chan[0].freq);
+		status = ucfg_scan_start(req);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+
+		return status;
+	} else if (eSIR_BEACON_TABLE == scan_type) {
+		/*
+		 * In beacon table mode, scan results are taken directly from
+		 * scan cache without issuing any scan request. So, it is not
+		 * proper to update rrm_scan_timer with latest time and hence
+		 * made it to zero to satisfy
+		 * pScanResult->timer >= rrm_scan_timer
+		 */
+		rrm_scan_timer = 0;
+		if ((sme_rrm_ctx->currentIndex + 1) <
+			sme_rrm_ctx->channelList.numOfChannels) {
+			sme_rrm_send_scan_result(mac_ctx, 1,
+				&sme_rrm_ctx->channelList.ChannelList[
+					sme_rrm_ctx->currentIndex], false);
+			/* Advance the current index. */
+			sme_rrm_ctx->currentIndex++;
+			sme_rrm_issue_scan_req(mac_ctx);
+#ifdef FEATURE_WLAN_ESE
+			sme_rrm_ctx->eseBcnReqInProgress = false;
+#endif
+			return status;
+		} else {
+			/*
+			 * Done with the measurement. Clean up all context and
+			 * send a message to PE with measurement done flag set.
+			 */
+			sme_rrm_send_scan_result(mac_ctx, 1,
+				&sme_rrm_ctx->channelList.ChannelList[
+					sme_rrm_ctx->currentIndex], true);
+			goto free_ch_lst;
+		}
+	} else {
+		sme_err("Unknown beacon report req mode(%d)", scan_type);
+		/*
+		 * Indicate measurement completion to PE
+		 * If this is not done, pCurrentReq pointer will not be freed
+		 * and PE will not handle subsequent Beacon requests
+		 */
+		sme_rrm_send_beacon_report_xmit_ind(mac_ctx, NULL, true, 0);
+		goto free_ch_lst;
+	}
+
+free_ch_lst:
+	qdf_mem_free(sme_rrm_ctx->channelList.ChannelList);
+	sme_rrm_ctx->channelList.ChannelList = NULL;
+	return status;
+}
+
+/**
+ * sme_rrm_calculate_total_scan_time() - calculate total time req for
+ * scan for all channels
+ * @mac_ctx: The handle returned by mac_open.
+ *
+ * Return: total rrm scan time
+ */
+static uint32_t sme_rrm_calculate_total_scan_time(tpAniSirGlobal mac_ctx)
+{
+	uint32_t dwell_time_active;
+	uint16_t interval;
+	tpRrmSMEContext pSmeRrmContext = &mac_ctx->rrm.rrmSmeContext;
+	uint8_t num_channels;
+	uint32_t rrm_scan_time = 0;
+
+	num_channels = pSmeRrmContext->channelList.numOfChannels;
+
+	interval = pSmeRrmContext->randnIntvl + 10;
+
+	dwell_time_active = pSmeRrmContext->duration[0];
+
+	/*
+	 * Add 1 sec extra in actual total rrm scan time
+	 * to accommodate any delay
+	 */
+	if (num_channels)
+		rrm_scan_time = ((num_channels * dwell_time_active) +
+				 ((num_channels - 1) * interval) + 1000);
+
+	return rrm_scan_time;
+}
+
+/**
+ * sme_rrm_process_beacon_report_req_ind() -Process beacon report request
+ * @pMac:- Global Mac structure
+ * @pMsgBuf:- a pointer to a buffer that maps to various structures base
+ *                  on the message type.The beginning of the buffer can always
+ *                  map to tSirSmeRsp.
+ *
+ * This is called to process the Beacon
+ * report request from peer AP forwarded through PE .
+ *
+ * Return : QDF_STATUS_SUCCESS - Validation is successful.
+ */
+QDF_STATUS sme_rrm_process_beacon_report_req_ind(tpAniSirGlobal pMac,
+						void *pMsgBuf)
+{
+	tpSirBeaconReportReqInd pBeaconReq = (tpSirBeaconReportReqInd) pMsgBuf;
+	tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
+	uint32_t len = 0, i = 0;
+	uint32_t total_rrm_scan_time;
+
+	sme_debug("Received Beacon report request ind Channel = %d",
+		pBeaconReq->channelInfo.channelNum);
+
+	if (pBeaconReq->channelList.numChannels >
+	    SIR_ESE_MAX_MEAS_IE_REQS) {
+		sme_err("Beacon report request numChannels:%u exceeds max num channels",
+			pBeaconReq->channelList.numChannels);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* section 11.10.8.1 (IEEE Std 802.11k-2008) */
+	/* channel 0 and 255 has special meaning. */
+	if ((pBeaconReq->channelInfo.channelNum == 0) ||
+	    ((pBeaconReq->channelInfo.channelNum == 255)
+	     && (pBeaconReq->channelList.numChannels == 0))) {
+		/* Add all the channel in the regulatory domain. */
+		wlan_cfg_get_str_len(pMac, WNI_CFG_VALID_CHANNEL_LIST, &len);
+		pSmeRrmContext->channelList.ChannelList = qdf_mem_malloc(len);
+		if (!pSmeRrmContext->channelList.ChannelList)
+			return QDF_STATUS_E_NOMEM;
+
+		csr_get_cfg_valid_channels(pMac, pSmeRrmContext->channelList.
+					ChannelList, &len);
+		pSmeRrmContext->channelList.numOfChannels = (uint8_t) len;
+	} else {
+		len = 0;
+		pSmeRrmContext->channelList.numOfChannels = 0;
+
+		/* If valid channel is present. We first Measure on the given
+		 * channel and if there are additional channels present in
+		 * APchannelreport, measure on these also.
+		 */
+		if (pBeaconReq->channelInfo.channelNum != 255)
+			len = 1;
+
+		len += pBeaconReq->channelList.numChannels;
+
+		pSmeRrmContext->channelList.ChannelList = qdf_mem_malloc(len);
+		if (!pSmeRrmContext->channelList.ChannelList)
+			return QDF_STATUS_E_NOMEM;
+
+		if (pBeaconReq->channelInfo.channelNum != 255) {
+			if (csr_roam_is_channel_valid
+				    (pMac, pBeaconReq->channelInfo.channelNum))
+				pSmeRrmContext->channelList.
+				ChannelList[pSmeRrmContext->channelList.
+					    numOfChannels++] =
+					pBeaconReq->channelInfo.channelNum;
+			else
+				sme_err("Invalid channel: %d",
+					pBeaconReq->channelInfo.channelNum);
+		}
+
+		for (i = 0; i < pBeaconReq->channelList.numChannels; i++) {
+			if (csr_roam_is_channel_valid(pMac, pBeaconReq->
+					channelList.channelNumber[i])) {
+				pSmeRrmContext->channelList.
+					ChannelList[pSmeRrmContext->channelList.
+				numOfChannels] = pBeaconReq->channelList.
+					channelNumber[i];
+				pSmeRrmContext->channelList.numOfChannels++;
+			}
+		}
+	}
+
+	/* Copy session bssid */
+	qdf_mem_copy(pSmeRrmContext->sessionBssId.bytes, pBeaconReq->bssId,
+		     sizeof(tSirMacAddr));
+
+	/* copy measurement bssid */
+	qdf_mem_copy(pSmeRrmContext->bssId, pBeaconReq->macaddrBssid,
+		     sizeof(tSirMacAddr));
+
+	/* Copy ssid */
+	qdf_mem_copy(&pSmeRrmContext->ssId, &pBeaconReq->ssId,
+		     sizeof(tAniSSID));
+
+	pSmeRrmContext->token = pBeaconReq->uDialogToken;
+	pSmeRrmContext->regClass = pBeaconReq->channelInfo.regulatoryClass;
+	pSmeRrmContext->randnIntvl =
+		QDF_MAX(pBeaconReq->randomizationInterval,
+			pSmeRrmContext->rrmConfig.max_randn_interval);
+	pSmeRrmContext->currentIndex = 0;
+	pSmeRrmContext->msgSource = pBeaconReq->msgSource;
+	qdf_mem_copy((uint8_t *) &pSmeRrmContext->measMode,
+		     (uint8_t *) &pBeaconReq->fMeasurementtype,
+		     SIR_ESE_MAX_MEAS_IE_REQS);
+	qdf_mem_copy((uint8_t *) &pSmeRrmContext->duration,
+		     (uint8_t *) &pBeaconReq->measurementDuration,
+		     SIR_ESE_MAX_MEAS_IE_REQS);
+
+	sme_debug("token: %d regClass: %d randnIntvl: %d msgSource: %d",
+		pSmeRrmContext->token, pSmeRrmContext->regClass,
+		pSmeRrmContext->randnIntvl, pSmeRrmContext->msgSource);
+
+	total_rrm_scan_time = sme_rrm_calculate_total_scan_time(pMac);
+
+	if (total_rrm_scan_time)
+		qdf_wake_lock_timeout_acquire(&pSmeRrmContext->scan_wake_lock,
+					      total_rrm_scan_time);
+
+	return sme_rrm_issue_scan_req(pMac);
+}
+
+/**
+ * sme_rrm_neighbor_report_request() - This is API can be used to trigger a
+ *        Neighbor report from the peer.
+ * @sessionId: session identifier on which the request should be made.
+ * @pNeighborReq: a pointer to a neighbor report request.
+ *
+ * This is API can be used to trigger a  Neighbor report from the peer.
+ *
+ * Return: QDF_STATUS_SUCCESS - Validation is successful.
+ */
+QDF_STATUS sme_rrm_neighbor_report_request(tpAniSirGlobal pMac, uint8_t
+					sessionId, tpRrmNeighborReq
+					pNeighborReq,
+					tpRrmNeighborRspCallbackInfo
+					callbackInfo)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpSirNeighborReportReqInd pMsg;
+	struct csr_roam_session *pSession;
+
+	sme_debug("Request to send Neighbor report request received ");
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		sme_err("Invalid session %d", sessionId);
+		return QDF_STATUS_E_INVAL;
+	}
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	/* If already a report is pending, return failure */
+	if (true ==
+	    pMac->rrm.rrmSmeContext.neighborReqControlInfo.
+	    isNeighborRspPending) {
+		sme_err("Neighbor request already pending.. Not allowed");
+		return QDF_STATUS_E_AGAIN;
+	}
+
+	pMsg = qdf_mem_malloc(sizeof(tSirNeighborReportReqInd));
+	if (!pMsg)
+		return QDF_STATUS_E_NOMEM;
+
+	rrm_ll_purge_neighbor_cache(pMac,
+			    &pMac->rrm.rrmSmeContext.neighborReportCache);
+
+	pMsg->messageType = eWNI_SME_NEIGHBOR_REPORT_REQ_IND;
+	pMsg->length = sizeof(tSirNeighborReportReqInd);
+	qdf_mem_copy(&pMsg->bssId, &pSession->connectedProfile.bssid,
+		     sizeof(tSirMacAddr));
+	pMsg->noSSID = pNeighborReq->no_ssid;
+	qdf_mem_copy(&pMsg->ucSSID, &pNeighborReq->ssid, sizeof(tSirMacSSid));
+
+	status = umac_send_mb_message_to_mac(pMsg);
+	if (status != QDF_STATUS_SUCCESS)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Neighbor report request message sent successfully to PE.
+	 * Now register the callbacks
+	 */
+	pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.
+	neighborRspCallback = callbackInfo->neighborRspCallback;
+	pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.
+	neighborRspCallbackContext =
+		callbackInfo->neighborRspCallbackContext;
+	pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending =
+		true;
+
+	/* Start neighbor response wait timer now */
+	qdf_mc_timer_start(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.
+			   neighborRspWaitTimer, callbackInfo->timeout);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * rrm_calculate_neighbor_ap_roam_score() - caclulates roam score
+ * @mac_ctx:                mac global context
+ * @pNeighborReportDesc:    Neighbor BSS Descriptor node for which roam score
+ *                          should be calculated
+ *
+ * This API is called while handling individual neighbor reports from the APs
+ * neighbor AP report to calculate the cumulative roam score before storing it
+ * in neighbor cache.
+ *
+ * Return: void
+ */
+static void
+rrm_calculate_neighbor_ap_roam_score(tpAniSirGlobal mac_ctx,
+				tpRrmNeighborReportDesc nbr_report_desc)
+{
+	tpSirNeighborBssDescripton nbr_bss_desc;
+	uint32_t roam_score = 0;
+#ifdef FEATURE_WLAN_ESE
+	uint8_t session_id;
+#endif
+	if (NULL == nbr_report_desc) {
+		QDF_ASSERT(0);
+		return;
+	}
+
+	if (NULL == nbr_report_desc->pNeighborBssDescription) {
+		QDF_ASSERT(0);
+		return;
+	}
+
+	nbr_bss_desc = nbr_report_desc->pNeighborBssDescription;
+	if (!nbr_bss_desc->bssidInfo.rrmInfo.fMobilityDomain)
+		goto check_11r_assoc;
+
+	roam_score += RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN;
+	if (!nbr_bss_desc->bssidInfo.rrmInfo.fSameSecurityMode)
+		goto check_11r_assoc;
+
+	roam_score += RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY;
+	if (!nbr_bss_desc->bssidInfo.rrmInfo.fSameAuthenticator)
+		goto check_11r_assoc;
+
+	roam_score += RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE;
+	if (!nbr_bss_desc->bssidInfo.rrmInfo.fCapRadioMeasurement)
+		goto check_11r_assoc;
+
+	roam_score += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM;
+	if (nbr_bss_desc->bssidInfo.rrmInfo.fCapSpectrumMeasurement)
+		roam_score +=
+			RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT;
+
+	if (nbr_bss_desc->bssidInfo.rrmInfo.fCapQos)
+		roam_score += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS;
+
+	if (nbr_bss_desc->bssidInfo.rrmInfo.fCapApsd)
+		roam_score += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD;
+
+	if (nbr_bss_desc->bssidInfo.rrmInfo.fCapDelayedBlockAck)
+		roam_score +=
+			RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA;
+
+	if (nbr_bss_desc->bssidInfo.rrmInfo.fCapImmediateBlockAck)
+		roam_score +=
+			RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA;
+
+	if (nbr_bss_desc->bssidInfo.rrmInfo.fApPreauthReachable)
+		roam_score += RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY;
+
+check_11r_assoc:
+#ifdef FEATURE_WLAN_ESE
+	session_id = nbr_report_desc->sessionId;
+	/* It has come in the report so its the best score */
+	if (csr_neighbor_roam_is11r_assoc(mac_ctx, session_id) == false) {
+		/* IAPP Route so lets make use of this info save all AP, as the
+		 * list does not come all the time. Save and reuse till the next
+		 * AP List comes to us. Even save our own MAC address. Will be
+		 * useful next time around.
+		 */
+		roam_score += RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST;
+	}
+#endif
+	nbr_report_desc->roamScore = roam_score;
+}
+
+/**
+ * rrm_store_neighbor_rpt_by_roam_score()-store Neighbor BSS descriptor
+ * @pNeighborReportDesc - Neighbor BSS Descriptor node to be stored in cache
+ *
+ * This API is called to store a given
+ * Neighbor BSS descriptor to the neighbor cache. This function
+ * stores the neighbor BSS descriptors in such a way that descriptors
+ * are sorted by roamScore in descending order
+ *
+ * Return: void.
+ */
+static void rrm_store_neighbor_rpt_by_roam_score(tpAniSirGlobal pMac,
+				tpRrmNeighborReportDesc pNeighborReportDesc)
+{
+	tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
+	tListElem *pEntry;
+	tRrmNeighborReportDesc *pTempNeighborReportDesc;
+
+	if (NULL == pNeighborReportDesc) {
+		QDF_ASSERT(0);
+		return;
+	}
+	if (NULL == pNeighborReportDesc->pNeighborBssDescription) {
+		QDF_ASSERT(0);
+		return;
+	}
+
+	if (csr_ll_is_list_empty
+		    (&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK)) {
+		sme_err("Neighbor report cache is empty.. Adding a entry now");
+		/* Neighbor list cache is empty. Insert this entry
+		 * in the tail
+		 */
+		csr_ll_insert_tail(&pSmeRrmContext->neighborReportCache,
+				   &pNeighborReportDesc->List, LL_ACCESS_LOCK);
+		return;
+	}
+	/* Should store the neighbor BSS description in the order
+	 * sorted by roamScore in descending order. APs with highest
+	 * roamScore should be the 1st entry in the list
+	 */
+	pEntry = csr_ll_peek_head(&pSmeRrmContext->neighborReportCache,
+				LL_ACCESS_LOCK);
+	while (pEntry != NULL) {
+		pTempNeighborReportDesc = GET_BASE_ADDR(pEntry,
+					tRrmNeighborReportDesc, List);
+		if (pTempNeighborReportDesc->roamScore <
+				pNeighborReportDesc->roamScore)
+			break;
+		pEntry = csr_ll_next(&pSmeRrmContext->
+				neighborReportCache, pEntry, LL_ACCESS_LOCK);
+		}
+
+	if (pEntry)
+		/* This BSS roamscore is better than something in the
+		 * list. Insert this before that one
+		 */
+		csr_ll_insert_entry(&pSmeRrmContext->neighborReportCache,
+					pEntry, &pNeighborReportDesc->List,
+					LL_ACCESS_LOCK);
+	else
+		/* All the entries in the list has a better roam Score
+		 * than this one. Insert this at the last
+		 */
+		csr_ll_insert_tail(&pSmeRrmContext->neighborReportCache,
+					&pNeighborReportDesc->List,
+					LL_ACCESS_LOCK);
+}
+
+/**
+ * sme_rrm_process_neighbor_report() -Process the Neighbor report received
+ *                                                     from PE
+ * @pMac - Global MAC structure
+ * @pMsgBuf - a pointer to a buffer that maps to various structures base
+ *                  on the message type.
+ *                  The beginning of the buffer can always map to tSirSmeRsp.
+ * This is called to process the Neighbor report received from PE.
+ *
+ * Return: QDF_STATUS_SUCCESS - Validation is successful
+ */
+static QDF_STATUS sme_rrm_process_neighbor_report(tpAniSirGlobal pMac,
+						  void *pMsgBuf)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpSirNeighborReportInd pNeighborRpt = (tpSirNeighborReportInd) pMsgBuf;
+	tpRrmNeighborReportDesc pNeighborReportDesc;
+	uint8_t i = 0;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	uint32_t sessionId;
+
+	/* Get the session id */
+	status =
+		csr_roam_get_session_id_from_bssid(pMac,
+			   (struct qdf_mac_addr *) pNeighborRpt->bssId,
+			   &sessionId);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+#ifdef FEATURE_WLAN_ESE
+		/* Clear the cache for ESE. */
+		if (csr_roam_is_ese_assoc(pMac, sessionId)) {
+			rrm_ll_purge_neighbor_cache(pMac,
+						    &pMac->rrm.rrmSmeContext.
+						    neighborReportCache);
+		}
+#endif
+	}
+
+	for (i = 0; i < pNeighborRpt->numNeighborReports; i++) {
+		pNeighborReportDesc =
+			qdf_mem_malloc(sizeof(tRrmNeighborReportDesc));
+		if (!pNeighborReportDesc) {
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+
+		}
+
+		pNeighborReportDesc->pNeighborBssDescription =
+			qdf_mem_malloc(sizeof(tSirNeighborBssDescription));
+		if (!pNeighborReportDesc->pNeighborBssDescription) {
+			qdf_mem_free(pNeighborReportDesc);
+			status = QDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		qdf_mem_copy(pNeighborReportDesc->pNeighborBssDescription,
+			     &pNeighborRpt->sNeighborBssDescription[i],
+			     sizeof(tSirNeighborBssDescription));
+
+		sme_debug("Received neighbor report with Neighbor BSSID: "
+			MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(
+			       pNeighborRpt->sNeighborBssDescription[i].bssId));
+
+		rrm_calculate_neighbor_ap_roam_score(pMac, pNeighborReportDesc);
+
+		if (pNeighborReportDesc->roamScore > 0) {
+			rrm_store_neighbor_rpt_by_roam_score(pMac,
+				     pNeighborReportDesc);
+		} else {
+			sme_err("Roam score of BSSID  " MAC_ADDRESS_STR
+				" is 0, Ignoring..",
+				MAC_ADDR_ARRAY(pNeighborRpt->
+					       sNeighborBssDescription[i].
+					       bssId));
+
+			qdf_mem_free(
+				pNeighborReportDesc->pNeighborBssDescription);
+			qdf_mem_free(pNeighborReportDesc);
+		}
+	}
+end:
+
+	if (!csr_ll_count(&pMac->rrm.rrmSmeContext.neighborReportCache))
+		qdf_status = QDF_STATUS_E_FAILURE;
+
+	rrm_indicate_neighbor_report_result(pMac, qdf_status);
+	return status;
+}
+
+/**
+ * sme_rrm_msg_processor()-Process RRM message
+ * @pMac - Pointer to the global MAC parameter structure.
+ * @msg_type - the type of msg passed by PE as defined in wni_api.h
+ * @pMsgBuf - a pointer to a buffer that maps to various structures base
+ *                  on the message type.
+ *                  The beginning of the buffer can always map to tSirSmeRsp.
+ * sme_process_msg() calls this function for the
+ * messages that are handled by SME RRM module.
+ *
+ * Return: QDF_STATUS_SUCCESS - Validation is successful.
+ */
+QDF_STATUS sme_rrm_msg_processor(tpAniSirGlobal pMac, uint16_t msg_type,
+				 void *pMsgBuf)
+{
+	sme_debug("Msg = %d for RRM measurement", msg_type);
+
+	/* switch on the msg type & make the state transition accordingly */
+	switch (msg_type) {
+	case eWNI_SME_NEIGHBOR_REPORT_IND:
+		sme_rrm_process_neighbor_report(pMac, pMsgBuf);
+		break;
+
+	case eWNI_SME_BEACON_REPORT_REQ_IND:
+		sme_rrm_process_beacon_report_req_ind(pMac, pMsgBuf);
+		break;
+
+	default:
+		sme_err("Unknown msg type: %d", msg_type);
+		break;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * rrm_iter_meas_timer_handle() - Timer handler to handlet the timeout
+ * @ pMac - The handle returned by mac_open.
+ *
+ * Timer handler to handlet the timeout condition when a specific BT
+ * stop event does not come back, in which case to restore back the
+ * heartbeat timer.
+ *
+ * Return: NULL
+ */
+static void rrm_iter_meas_timer_handle(void *userData)
+{
+	tpAniSirGlobal pMac = (tpAniSirGlobal) userData;
+
+	sme_warn("Randomization timer expired...send on next channel");
+	/* Issue a scan req for next channel. */
+	sme_rrm_issue_scan_req(pMac);
+}
+/**
+ * rrm_neighbor_rsp_timeout_handler() - Timer handler to handlet the timeout
+ * @pMac - The handle returned by mac_open.
+ *
+ * Timer handler to handle the timeout condition when a neighbor request is sent
+ * and no neighbor response is received from the AP
+ *
+ * Return: NULL
+ */
+static void rrm_neighbor_rsp_timeout_handler(void *userData)
+{
+	tpAniSirGlobal pMac = (tpAniSirGlobal) userData;
+
+	sme_warn("Neighbor Response timed out");
+	rrm_indicate_neighbor_report_result(pMac, QDF_STATUS_E_FAILURE);
+}
+
+/**
+ * rrm_open() - Initialze all RRM module
+ * @ pMac: The handle returned by mac_open.
+ *
+ * Initialze all RRM module.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS rrm_open(tpAniSirGlobal pMac)
+{
+
+	QDF_STATUS qdf_status;
+	tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
+	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
+
+	pSmeRrmContext->rrmConfig.max_randn_interval = 50;        /* ms */
+	qdf_wake_lock_create(&pSmeRrmContext->scan_wake_lock,
+			     "wlan_rrm_scan_wl");
+
+	qdf_status = qdf_mc_timer_init(&pSmeRrmContext->IterMeasTimer,
+				       QDF_TIMER_TYPE_SW,
+				       rrm_iter_meas_timer_handle,
+					(void *)pMac);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		sme_err("Fail to init measurement timer");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_status =
+		qdf_mc_timer_init(&pSmeRrmContext->neighborReqControlInfo.
+				  neighborRspWaitTimer, QDF_TIMER_TYPE_SW,
+				  rrm_neighbor_rsp_timeout_handler,
+					(void *)pMac);
+
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		sme_err("Fail to init neighbor rsp wait timer");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pSmeRrmContext->neighborReqControlInfo.isNeighborRspPending = false;
+
+	qdf_ret_status = csr_ll_open(&pSmeRrmContext->neighborReportCache);
+	if (QDF_STATUS_SUCCESS != qdf_ret_status) {
+		sme_err("Fail to open neighbor cache result");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * rrm_close() - Release all RRM modules and their resources.
+ * @pMac - The handle returned by mac_open.
+ *
+ * Release all RRM modules and their resources.
+ *
+ * Return: QDF_STATUS
+ *           QDF_STATUS_E_FAILURE  success
+ *           QDF_STATUS_SUCCESS  failure
+ */
+
+QDF_STATUS rrm_close(tpAniSirGlobal pMac)
+{
+
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
+
+	if (QDF_TIMER_STATE_RUNNING ==
+	    qdf_mc_timer_get_current_state(&pSmeRrmContext->IterMeasTimer)) {
+		qdf_status = qdf_mc_timer_stop(&pSmeRrmContext->IterMeasTimer);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("Timer stop fail"));
+		}
+	}
+
+	qdf_status = qdf_mc_timer_destroy(&pSmeRrmContext->IterMeasTimer);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Fail to destroy timer"));
+
+	}
+
+	if (QDF_TIMER_STATE_RUNNING ==
+	    qdf_mc_timer_get_current_state(&pSmeRrmContext->
+					   neighborReqControlInfo.
+					   neighborRspWaitTimer)) {
+		qdf_status = qdf_mc_timer_stop(&pSmeRrmContext->
+					neighborReqControlInfo.
+					  neighborRspWaitTimer);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				  FL("Timer stop fail"));
+		}
+	}
+
+	qdf_status =
+		qdf_mc_timer_destroy(&pSmeRrmContext->neighborReqControlInfo.
+				     neighborRspWaitTimer);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  FL("Fail to destroy timer"));
+
+	}
+
+	rrm_ll_purge_neighbor_cache(pMac, &pSmeRrmContext->neighborReportCache);
+
+	csr_ll_close(&pSmeRrmContext->neighborReportCache);
+
+	qdf_wake_lock_destroy(&pSmeRrmContext->scan_wake_lock);
+
+	return qdf_status;
+
+}
+
+/**
+ * rrm_change_default_config_param() - Changing default config param to new
+ * @pMac - The handle returned by mac_open.
+ * param  pRrmConfig - pointer to new rrm configs.
+ *
+ * Return: QDF_STATUS
+ *           QDF_STATUS_SUCCESS  success
+ */
+QDF_STATUS rrm_change_default_config_param(tpAniSirGlobal pMac,
+					   struct rrm_config_param *rrm_config)
+{
+	qdf_mem_copy(&pMac->rrm.rrmSmeContext.rrmConfig, rrm_config,
+		     sizeof(struct rrm_config_param));
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS rrm_start(tpAniSirGlobal mac_ctx)
+{
+	tpRrmSMEContext smerrmctx = &mac_ctx->rrm.rrmSmeContext;
+
+	/* Register with scan component */
+	smerrmctx->req_id = ucfg_scan_register_requester(mac_ctx->psoc,
+					"RRM",
+					sme_rrm_scan_event_callback,
+					smerrmctx);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS rrm_stop(tpAniSirGlobal mac_ctx)
+{
+	tpRrmSMEContext smerrmctx = &mac_ctx->rrm.rrmSmeContext;
+
+	ucfg_scan_unregister_requester(mac_ctx->psoc, smerrmctx->req_id);
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
new file mode 100644
index 0000000..9129ab1
--- /dev/null
+++ b/core/wma/inc/wma.h
@@ -0,0 +1,2583 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#ifndef WMA_H
+#define WMA_H
+
+#include "a_types.h"
+#include "qdf_types.h"
+#include "osapi_linux.h"
+#include "htc_packet.h"
+#include "i_qdf_event.h"
+#include "wmi_services.h"
+#include "wmi_unified.h"
+#include "wmi_version.h"
+#include "qdf_types.h"
+#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>
+#include "utils_api.h"
+#include "lim_types.h"
+#include "wmi_unified_api.h"
+#include "cdp_txrx_cmn.h"
+#include "dbglog.h"
+#include "cds_ieee80211_common.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include <cdp_txrx_handle.h>
+#include <wlan_policy_mgr_api.h>
+
+/* Platform specific configuration for max. no. of fragments */
+#define QCA_OL_11AC_TX_MAX_FRAGS            2
+
+/* Private */
+
+#define WMA_READY_EVENTID_TIMEOUT          6000
+#define WMA_SERVICE_READY_EXT_TIMEOUT      6000
+#define NAN_CLUSTER_ID_BYTES               4
+
+#define WMA_CRASH_INJECT_TIMEOUT           5000
+
+/* MAC ID to PDEV ID mapping is as given below
+ * MAC_ID           PDEV_ID
+ * 0                    1
+ * 1                    2
+ * SOC Level            WMI_PDEV_ID_SOC
+ */
+#define WMA_MAC_TO_PDEV_MAP(x) ((x) + (1))
+#define WMA_PDEV_TO_MAC_MAP(x) ((x) - (1))
+
+#define WMA_MAX_SUPPORTED_BSS     SIR_MAX_SUPPORTED_BSS
+
+#define WMA_MAX_MGMT_MPDU_LEN 2000
+
+#define MAX_PRINT_FAILURE_CNT 50
+
+#define WMA_INVALID_VDEV_ID                             0xFF
+
+/* Deprecated logging macros, to be removed. Please do not use in new code */
+#define WMA_LOGD(params ...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_WMA, params)
+#define WMA_LOGI(params ...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_WMA, params)
+#define WMA_LOGW(params ...) \
+	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_WMA, params)
+#define WMA_LOGE(params ...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_WMA, params)
+#define WMA_LOGP(params ...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_WMA, params)
+
+#define wma_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_WMA, params)
+#define wma_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_WMA, params)
+#define wma_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_WMA, params)
+#define wma_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_WMA, params)
+#define wma_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_WMA, params)
+#define wma_err_rl(params...) QDF_TRACE_ERROR_RL(QDF_MODULE_ID_WMA, params)
+
+#define wma_nofl_alert(params...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_WMA, params)
+#define wma_nofl_err(params...) \
+	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_WMA, params)
+#define wma_nofl_warn(params...) \
+	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_WMA, params)
+#define wma_nofl_info(params...) \
+	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_WMA, params)
+#define wma_nofl_debug(params...) \
+	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_WMA, params)
+
+#define WMA_DEBUG_ALWAYS
+
+#ifdef WMA_DEBUG_ALWAYS
+#define WMA_LOGA(params ...) \
+	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_WMA, params)
+#else
+#define WMA_LOGA(params ...)
+#endif
+
+#define WMA_WILDCARD_PDEV_ID 0x0
+
+#define WMA_HW_DEF_SCAN_MAX_DURATION      30000 /* 30 secs */
+
+#define WMA_SCAN_NPROBES_DEFAULT            (2)
+
+#define WMA_BCAST_MAC_ADDR (0xFF)
+#define WMA_MCAST_IPV4_MAC_ADDR (0x01)
+#define WMA_MCAST_IPV6_MAC_ADDR (0x33)
+#define WMA_ICMP_PROTOCOL (0x01)
+
+#define WMA_IS_EAPOL_GET_MIN_LEN          14
+#define WMA_EAPOL_SUBTYPE_GET_MIN_LEN     21
+#define WMA_EAPOL_INFO_GET_MIN_LEN        23
+#define WMA_IS_DHCP_GET_MIN_LEN           38
+#define WMA_DHCP_SUBTYPE_GET_MIN_LEN      0x11D
+#define WMA_DHCP_INFO_GET_MIN_LEN         50
+#define WMA_IS_ARP_GET_MIN_LEN            14
+#define WMA_ARP_SUBTYPE_GET_MIN_LEN       22
+#define WMA_IPV4_PROTO_GET_MIN_LEN        24
+#define WMA_IPV4_PKT_INFO_GET_MIN_LEN     42
+#define WMA_ICMP_SUBTYPE_GET_MIN_LEN      35
+#define WMA_IPV6_PROTO_GET_MIN_LEN        21
+#define WMA_IPV6_PKT_INFO_GET_MIN_LEN     62
+#define WMA_ICMPV6_SUBTYPE_GET_MIN_LEN    55
+
+/* Beacon tx rate */
+#define WMA_BEACON_TX_RATE_1_M            10
+#define WMA_BEACON_TX_RATE_2_M            20
+#define WMA_BEACON_TX_RATE_5_5_M          55
+#define WMA_BEACON_TX_RATE_11_M           110
+#define WMA_BEACON_TX_RATE_6_M            60
+#define WMA_BEACON_TX_RATE_9_M            90
+#define WMA_BEACON_TX_RATE_12_M           120
+#define WMA_BEACON_TX_RATE_18_M           180
+#define WMA_BEACON_TX_RATE_24_M           240
+#define WMA_BEACON_TX_RATE_36_M           360
+#define WMA_BEACON_TX_RATE_48_M           480
+#define WMA_BEACON_TX_RATE_54_M           540
+
+/**
+ * ds_mode: distribution system mode
+ * @IEEE80211_NO_DS: NO DS at either side
+ * @IEEE80211_TO_DS: DS at receiver side
+ * @IEEE80211_FROM_DS: DS at sender side
+ * @IEEE80211_DS_TO_DS: DS at both sender and revceiver side
+ */
+enum ds_mode {
+	IEEE80211_NO_DS,
+	IEEE80211_TO_DS,
+	IEEE80211_FROM_DS,
+	IEEE80211_DS_TO_DS
+};
+
+/* Roaming default values
+ * All time and period values are in milliseconds.
+ * All rssi values are in dB except for WMA_NOISE_FLOOR_DBM_DEFAULT.
+ */
+
+#define WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME    (4)
+#define WMA_NOISE_FLOOR_DBM_DEFAULT          (-96)
+#define WMA_ROAM_RSSI_DIFF_DEFAULT           (5)
+#define WMA_ROAM_DWELL_TIME_ACTIVE_DEFAULT   (100)
+#define WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT  (110)
+#define WMA_ROAM_MIN_REST_TIME_DEFAULT       (50)
+#define WMA_ROAM_MAX_REST_TIME_DEFAULT       (500)
+
+#define WMA_INVALID_KEY_IDX     0xff
+
+#define WMA_MAX_RF_CHAINS(x)    ((1 << x) - 1)
+#define WMA_MIN_RF_CHAINS               (1)
+#define WMA_MAX_NSS               (2)
+
+
+#ifdef FEATURE_WLAN_EXTSCAN
+#define WMA_MAX_EXTSCAN_MSG_SIZE        1536
+#define WMA_EXTSCAN_REST_TIME           100
+#define WMA_EXTSCAN_MAX_SCAN_TIME       50000
+#define WMA_EXTSCAN_BURST_DURATION      150
+#endif
+
+#define WMA_CHAN_START_RESP          0
+#define WMA_CHAN_END_RESP            1
+
+#define WMA_BCN_BUF_MAX_SIZE 512
+#define WMA_NOA_IE_SIZE(num_desc) (2 + (13 * (num_desc)))
+#define WMA_MAX_NOA_DESCRIPTORS 4
+
+#define WMA_TIM_SUPPORTED_PVB_LENGTH ((HAL_NUM_STA / 8) + 1)
+
+#define WMA_WOW_PTRN_MASK_VALID     0xFF
+#define WMA_NUM_BITS_IN_BYTE           8
+
+#define WMA_AP_WOW_DEFAULT_PTRN_MAX    4
+
+#define WMA_BSS_STATUS_STARTED 0x1
+#define WMA_BSS_STATUS_STOPPED 0x2
+
+#define WMA_TARGET_REQ_TYPE_VDEV_START 0x1
+#define WMA_TARGET_REQ_TYPE_VDEV_STOP  0x2
+#define WMA_TARGET_REQ_TYPE_VDEV_DEL   0x3
+
+#define WMA_PEER_ASSOC_CNF_START 0x01
+#define WMA_PEER_ASSOC_TIMEOUT (6000) /* 6 seconds */
+
+#define WMA_DELETE_STA_RSP_START 0x02
+#define WMA_DELETE_STA_TIMEOUT (6000) /* 6 seconds */
+
+#define WMA_DEL_P2P_SELF_STA_RSP_START 0x03
+#define WMA_SET_LINK_PEER_RSP 0x04
+#define WMA_DELETE_PEER_RSP 0x05
+
+#define WMA_PDEV_SET_HW_MODE_RESP 0x06
+#define WMA_PDEV_MAC_CFG_RESP 0x07
+
+#ifdef CONFIG_SLUB_DEBUG_ON
+#define SLUB_DEBUG_FACTOR (2)
+#else
+#define SLUB_DEBUG_FACTOR (1)
+#endif
+
+/* FW response timeout values in milli seconds */
+#define WMA_VDEV_START_REQUEST_TIMEOUT   (6000) * (SLUB_DEBUG_FACTOR)
+#define WMA_VDEV_STOP_REQUEST_TIMEOUT    (6000) * (SLUB_DEBUG_FACTOR)
+#define WMA_VDEV_HW_MODE_REQUEST_TIMEOUT (6000) * (SLUB_DEBUG_FACTOR)
+#define WMA_VDEV_PLCY_MGR_CMD_TIMEOUT    (6000) * (SLUB_DEBUG_FACTOR)
+#define WMA_VDEV_DUAL_MAC_CFG_TIMEOUT    (5000) * (SLUB_DEBUG_FACTOR)
+
+#define WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT	WAKELOCK_DURATION_RECOMMENDED
+
+#define WMA_TGT_INVALID_SNR (0)
+
+#define WMA_TGT_IS_VALID_SNR(x)  ((x) >= 0 && (x) < WMA_TGT_MAX_SNR)
+#define WMA_TGT_IS_INVALID_SNR(x) (!WMA_TGT_IS_VALID_SNR(x))
+
+#define WMA_TX_Q_RECHECK_TIMER_WAIT      2      /* 2 ms */
+#define WMA_TX_Q_RECHECK_TIMER_MAX_WAIT  20     /* 20 ms */
+#define WMA_MAX_NUM_ARGS 8
+
+#define WMA_SMPS_MASK_LOWER_16BITS 0xFF
+#define WMA_SMPS_MASK_UPPER_3BITS 0x7
+#define WMA_SMPS_PARAM_VALUE_S 29
+
+/*
+ * Setting the Tx Comp Timeout to 1 secs.
+ * TODO: Need to Revist the Timing
+ */
+#define WMA_TX_FRAME_COMPLETE_TIMEOUT  1000
+#define WMA_TX_FRAME_BUFFER_NO_FREE    0
+#define WMA_TX_FRAME_BUFFER_FREE       1
+
+/* Default InActivity Time is 200 ms */
+#define POWERSAVE_DEFAULT_INACTIVITY_TIME 200
+
+/* Default WOW InActivity Time is 50 ms */
+#define WOW_POWERSAVE_DEFAULT_INACTIVITY_TIME 50
+
+/* Default Listen Interval */
+#define POWERSAVE_DEFAULT_LISTEN_INTERVAL 1
+
+/*
+ * TODO: Add WMI_CMD_ID_MAX as part of WMI_CMD_ID
+ * instead of assigning it to the last valid wmi
+ * cmd+1 to avoid updating this when a command is
+ * added/deleted.
+ */
+#define WMI_CMDID_MAX (WMI_TXBF_CMDID + 1)
+
+#define WMA_NLO_FREQ_THRESH          1000       /* in MHz */
+#define WMA_SEC_TO_MSEC(sec)         (sec * 1000)       /* sec to msec */
+#define WMA_MSEC_TO_USEC(msec)	     (msec * 1000) /* msec to usec */
+
+/* Default rssi threshold defined in CFG80211 */
+#define WMA_RSSI_THOLD_DEFAULT   -300
+
+#define WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT     WAKELOCK_DURATION_RECOMMENDED
+#define WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION   WAKELOCK_DURATION_RECOMMENDED
+#define WMA_DEAUTH_RECV_WAKE_LOCK_DURATION      WAKELOCK_DURATION_RECOMMENDED
+#define WMA_DISASSOC_RECV_WAKE_LOCK_DURATION    WAKELOCK_DURATION_RECOMMENDED
+#define WMA_ROAM_HO_WAKE_LOCK_DURATION          (500)          /* in msec */
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+#define WMA_AUTO_SHUTDOWN_WAKE_LOCK_DURATION    WAKELOCK_DURATION_RECOMMENDED
+#endif
+#define WMA_BMISS_EVENT_WAKE_LOCK_DURATION      WAKELOCK_DURATION_RECOMMENDED
+#define WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION     WAKELOCK_DURATION_MAX
+
+#define WMA_TXMIC_LEN 8
+#define WMA_RXMIC_LEN 8
+#define WMA_IV_KEY_LEN 16
+
+/*
+ * Length = (2 octets for Index and CTWin/Opp PS) and
+ * (13 octets for each NOA Descriptors)
+ */
+
+#define WMA_P2P_NOA_IE_OPP_PS_SET (0x80)
+#define WMA_P2P_NOA_IE_CTWIN_MASK (0x7F)
+
+#define WMA_P2P_IE_ID 0xdd
+#define WMA_P2P_WFA_OUI { 0x50, 0x6f, 0x9a }
+#define WMA_P2P_WFA_VER 0x09    /* ver 1.0 */
+#define WMA_WSC_OUI { 0x00, 0x50, 0xF2 } /* Microsoft WSC OUI byte */
+
+/* P2P Sub element definitions (according to table 5 of Wifi's P2P spec) */
+#define WMA_P2P_SUB_ELEMENT_STATUS                    0
+#define WMA_P2P_SUB_ELEMENT_MINOR_REASON              1
+#define WMA_P2P_SUB_ELEMENT_CAPABILITY                2
+#define WMA_P2P_SUB_ELEMENT_DEVICE_ID                 3
+#define WMA_P2P_SUB_ELEMENT_GO_INTENT                 4
+#define WMA_P2P_SUB_ELEMENT_CONFIGURATION_TIMEOUT     5
+#define WMA_P2P_SUB_ELEMENT_LISTEN_CHANNEL            6
+#define WMA_P2P_SUB_ELEMENT_GROUP_BSSID               7
+#define WMA_P2P_SUB_ELEMENT_EXTENDED_LISTEN_TIMING    8
+#define WMA_P2P_SUB_ELEMENT_INTENDED_INTERFACE_ADDR   9
+#define WMA_P2P_SUB_ELEMENT_MANAGEABILITY             10
+#define WMA_P2P_SUB_ELEMENT_CHANNEL_LIST              11
+#define WMA_P2P_SUB_ELEMENT_NOA                       12
+#define WMA_P2P_SUB_ELEMENT_DEVICE_INFO               13
+#define WMA_P2P_SUB_ELEMENT_GROUP_INFO                14
+#define WMA_P2P_SUB_ELEMENT_GROUP_ID                  15
+#define WMA_P2P_SUB_ELEMENT_INTERFACE                 16
+#define WMA_P2P_SUB_ELEMENT_OP_CHANNEL                17
+#define WMA_P2P_SUB_ELEMENT_INVITATION_FLAGS          18
+#define WMA_P2P_SUB_ELEMENT_VENDOR                    221
+
+/* Macros for handling unaligned memory accesses */
+#define P2PIE_PUT_LE16(a, val)		\
+	do {			\
+		(a)[1] = ((uint16_t) (val)) >> 8;	\
+		(a)[0] = ((uint16_t) (val)) & 0xff;	\
+	} while (0)
+
+#define P2PIE_PUT_LE32(a, val)			\
+	do {				\
+		(a)[3] = (uint8_t) ((((uint32_t) (val)) >> 24) & 0xff);	\
+		(a)[2] = (uint8_t) ((((uint32_t) (val)) >> 16) & 0xff);	\
+		(a)[1] = (uint8_t) ((((uint32_t) (val)) >> 8) & 0xff);	\
+		(a)[0] = (uint8_t) (((uint32_t) (val)) & 0xff);	    \
+	} while (0)
+
+
+#define WMA_DEFAULT_MAX_PSPOLL_BEFORE_WAKE 1
+
+#define WMA_DEFAULT_QPOWER_MAX_PSPOLL_BEFORE_WAKE 1
+#define WMA_DEFAULT_QPOWER_TX_WAKE_THRESHOLD 2
+
+#define WMA_VHT_PPS_PAID_MATCH 1
+#define WMA_VHT_PPS_GID_MATCH 2
+#define WMA_VHT_PPS_DELIM_CRC_FAIL 3
+
+#define WMA_DEFAULT_HW_MODE_INDEX 0xFFFF
+#define TWO_THIRD (2/3)
+
+/**
+ * WMA hardware mode list bit-mask definitions.
+ * Bits 4:0, 31:29 are unused.
+ *
+ * The below definitions are added corresponding to WMI DBS HW mode
+ * list to make it independent of firmware changes for WMI definitions.
+ * Currently these definitions have dependency with BIT positions of
+ * the existing WMI macros. Thus, if the BIT positions are changed for
+ * WMI macros, then these macros' BIT definitions are also need to be
+ * changed.
+ */
+#define WMA_HW_MODE_MAC0_TX_STREAMS_BITPOS  (28)
+#define WMA_HW_MODE_MAC0_RX_STREAMS_BITPOS  (24)
+#define WMA_HW_MODE_MAC1_TX_STREAMS_BITPOS  (20)
+#define WMA_HW_MODE_MAC1_RX_STREAMS_BITPOS  (16)
+#define WMA_HW_MODE_MAC0_BANDWIDTH_BITPOS   (12)
+#define WMA_HW_MODE_MAC1_BANDWIDTH_BITPOS   (8)
+#define WMA_HW_MODE_DBS_MODE_BITPOS         (7)
+#define WMA_HW_MODE_AGILE_DFS_MODE_BITPOS   (6)
+#define WMA_HW_MODE_SBS_MODE_BITPOS         (5)
+
+#define WMA_HW_MODE_MAC0_TX_STREAMS_MASK    \
+			(0xf << WMA_HW_MODE_MAC0_TX_STREAMS_BITPOS)
+#define WMA_HW_MODE_MAC0_RX_STREAMS_MASK    \
+			(0xf << WMA_HW_MODE_MAC0_RX_STREAMS_BITPOS)
+#define WMA_HW_MODE_MAC1_TX_STREAMS_MASK    \
+			(0xf << WMA_HW_MODE_MAC1_TX_STREAMS_BITPOS)
+#define WMA_HW_MODE_MAC1_RX_STREAMS_MASK    \
+			(0xf << WMA_HW_MODE_MAC1_RX_STREAMS_BITPOS)
+#define WMA_HW_MODE_MAC0_BANDWIDTH_MASK     \
+			(0xf << WMA_HW_MODE_MAC0_BANDWIDTH_BITPOS)
+#define WMA_HW_MODE_MAC1_BANDWIDTH_MASK     \
+			(0xf << WMA_HW_MODE_MAC1_BANDWIDTH_BITPOS)
+#define WMA_HW_MODE_DBS_MODE_MASK           \
+			(0x1 << WMA_HW_MODE_DBS_MODE_BITPOS)
+#define WMA_HW_MODE_AGILE_DFS_MODE_MASK     \
+			(0x1 << WMA_HW_MODE_AGILE_DFS_MODE_BITPOS)
+#define WMA_HW_MODE_SBS_MODE_MASK           \
+			(0x1 << WMA_HW_MODE_SBS_MODE_BITPOS)
+
+#define WMA_HW_MODE_MAC0_TX_STREAMS_SET(hw_mode, value) \
+	WMI_SET_BITS(hw_mode, WMA_HW_MODE_MAC0_TX_STREAMS_BITPOS, 4, value)
+#define WMA_HW_MODE_MAC0_RX_STREAMS_SET(hw_mode, value) \
+	WMI_SET_BITS(hw_mode, WMA_HW_MODE_MAC0_RX_STREAMS_BITPOS, 4, value)
+#define WMA_HW_MODE_MAC1_TX_STREAMS_SET(hw_mode, value) \
+	WMI_SET_BITS(hw_mode, WMA_HW_MODE_MAC1_TX_STREAMS_BITPOS, 4, value)
+#define WMA_HW_MODE_MAC1_RX_STREAMS_SET(hw_mode, value) \
+	WMI_SET_BITS(hw_mode, WMA_HW_MODE_MAC1_RX_STREAMS_BITPOS, 4, value)
+#define WMA_HW_MODE_MAC0_BANDWIDTH_SET(hw_mode, value)  \
+	WMI_SET_BITS(hw_mode, WMA_HW_MODE_MAC0_BANDWIDTH_BITPOS, 4, value)
+#define WMA_HW_MODE_MAC1_BANDWIDTH_SET(hw_mode, value)  \
+	WMI_SET_BITS(hw_mode, WMA_HW_MODE_MAC1_BANDWIDTH_BITPOS, 4, value)
+#define WMA_HW_MODE_DBS_MODE_SET(hw_mode, value)        \
+	WMI_SET_BITS(hw_mode, WMA_HW_MODE_DBS_MODE_BITPOS, 1, value)
+#define WMA_HW_MODE_AGILE_DFS_SET(hw_mode, value)       \
+	WMI_SET_BITS(hw_mode, WMA_HW_MODE_AGILE_DFS_MODE_BITPOS, 1, value)
+#define WMA_HW_MODE_SBS_MODE_SET(hw_mode, value)        \
+	WMI_SET_BITS(hw_mode, WMA_HW_MODE_SBS_MODE_BITPOS, 1, value)
+
+#define WMA_HW_MODE_MAC0_TX_STREAMS_GET(hw_mode)                \
+	((hw_mode & WMA_HW_MODE_MAC0_TX_STREAMS_MASK) >>        \
+		WMA_HW_MODE_MAC0_TX_STREAMS_BITPOS)
+#define WMA_HW_MODE_MAC0_RX_STREAMS_GET(hw_mode)                \
+	((hw_mode & WMA_HW_MODE_MAC0_RX_STREAMS_MASK) >>        \
+		WMA_HW_MODE_MAC0_RX_STREAMS_BITPOS)
+#define WMA_HW_MODE_MAC1_TX_STREAMS_GET(hw_mode)                \
+	((hw_mode & WMA_HW_MODE_MAC1_TX_STREAMS_MASK) >>        \
+		WMA_HW_MODE_MAC1_TX_STREAMS_BITPOS)
+#define WMA_HW_MODE_MAC1_RX_STREAMS_GET(hw_mode)                \
+	((hw_mode & WMA_HW_MODE_MAC1_RX_STREAMS_MASK) >>        \
+		WMA_HW_MODE_MAC1_RX_STREAMS_BITPOS)
+#define WMA_HW_MODE_MAC0_BANDWIDTH_GET(hw_mode)                 \
+	((hw_mode & WMA_HW_MODE_MAC0_BANDWIDTH_MASK) >>         \
+		WMA_HW_MODE_MAC0_BANDWIDTH_BITPOS)
+#define WMA_HW_MODE_MAC1_BANDWIDTH_GET(hw_mode)                 \
+	((hw_mode & WMA_HW_MODE_MAC1_BANDWIDTH_MASK) >>         \
+		WMA_HW_MODE_MAC1_BANDWIDTH_BITPOS)
+#define WMA_HW_MODE_DBS_MODE_GET(hw_mode)                       \
+	((hw_mode & WMA_HW_MODE_DBS_MODE_MASK) >>               \
+		WMA_HW_MODE_DBS_MODE_BITPOS)
+#define WMA_HW_MODE_AGILE_DFS_GET(hw_mode)                      \
+	((hw_mode & WMA_HW_MODE_AGILE_DFS_MODE_MASK) >>         \
+		WMA_HW_MODE_AGILE_DFS_MODE_BITPOS)
+#define WMA_HW_MODE_SBS_MODE_GET(hw_mode)                       \
+	((hw_mode & WMA_HW_MODE_SBS_MODE_MASK) >>               \
+		WMA_HW_MODE_SBS_MODE_BITPOS)
+
+/*
+ * PROBE_REQ_TX_DELAY
+ * param to specify probe request Tx delay for scans triggered on this VDEV
+ */
+#define PROBE_REQ_TX_DELAY 10
+
+/* PROBE_REQ_TX_TIME_GAP
+ * param to specify the time gap between each set of probe request transmission.
+ * The number of probe requests in each set depends on the ssid_list and,
+ * bssid_list in the scan request. This parameter will get applied only,
+ * for the scans triggered on this VDEV.
+ */
+#define PROBE_REQ_TX_TIME_GAP 20
+
+typedef void (*txFailIndCallback)(uint8_t *peer_mac, uint8_t seqNo);
+
+typedef void (*tp_wma_packetdump_cb)(qdf_nbuf_t netbuf,
+			uint8_t status, uint8_t vdev_id, uint8_t type);
+
+/**
+ * enum wma_rx_exec_ctx - wma rx execution context
+ * @WMA_RX_WORK_CTX: work queue context execution
+ * @WMA_RX_TASKLET_CTX: tasklet context execution
+ * @WMA_RX_SERIALIZER_CTX: MC thread context execution
+ *
+ */
+enum wma_rx_exec_ctx {
+	WMA_RX_WORK_CTX,
+	WMA_RX_TASKLET_CTX,
+	WMA_RX_SERIALIZER_CTX
+};
+
+/**
+ * struct beacon_info - structure to store beacon template
+ * @buf: skb ptr
+ * @len: length
+ * @dma_mapped: is it dma mapped or not
+ * @tim_ie_offset: TIM IE offset
+ * @dtim_count: DTIM count
+ * @seq_no: sequence no
+ * @noa_sub_ie: NOA sub IE
+ * @noa_sub_ie_len: NOA sub IE length
+ * @noa_ie: NOA IE
+ * @p2p_ie_offset: p2p IE offset
+ * @lock: lock
+ */
+struct beacon_info {
+	qdf_nbuf_t buf;
+	uint32_t len;
+	uint8_t dma_mapped;
+	uint32_t tim_ie_offset;
+	uint8_t dtim_count;
+	uint16_t seq_no;
+	uint8_t noa_sub_ie[2 + WMA_NOA_IE_SIZE(WMA_MAX_NOA_DESCRIPTORS)];
+	uint16_t noa_sub_ie_len;
+	uint8_t *noa_ie;
+	uint16_t p2p_ie_offset;
+	qdf_spinlock_t lock;
+};
+
+/**
+ * struct beacon_tim_ie - structure to store TIM IE of beacon
+ * @tim_ie: tim ie
+ * @tim_len: tim ie length
+ * @dtim_count: dtim count
+ * @dtim_period: dtim period
+ * @tim_bitctl: tim bit control
+ * @tim_bitmap: tim bitmap
+ */
+struct beacon_tim_ie {
+	uint8_t tim_ie;
+	uint8_t tim_len;
+	uint8_t dtim_count;
+	uint8_t dtim_period;
+	uint8_t tim_bitctl;
+	uint8_t tim_bitmap[1];
+} __ATTRIB_PACK;
+
+/**
+ * struct pps - packet power save parameter
+ * @paid_match_enable: paid match enable
+ * @gid_match_enable: gid match enable
+ * @tim_clear: time clear
+ * @dtim_clear: dtim clear
+ * @eof_delim: eof delim
+ * @mac_match: mac match
+ * @delim_fail: delim fail
+ * @nsts_zero: nsts zero
+ * @rssi_chk: RSSI check
+ * @ebt_5g: ebt 5GHz
+ */
+struct pps {
+	bool paid_match_enable;
+	bool gid_match_enable;
+	bool tim_clear;
+	bool dtim_clear;
+	bool eof_delim;
+	bool mac_match;
+	bool delim_fail;
+	bool nsts_zero;
+	bool rssi_chk;
+	bool ebt_5g;
+};
+
+/**
+ * struct qpower_params - qpower related parameters
+ * @max_ps_poll_cnt: max ps poll count
+ * @max_tx_before_wake: max tx before wake
+ * @spec_ps_poll_wake_interval: ps poll wake interval
+ * @max_spec_nodata_ps_poll: no data ps poll
+ */
+struct qpower_params {
+	uint32_t max_ps_poll_cnt;
+	uint32_t max_tx_before_wake;
+	uint32_t spec_ps_poll_wake_interval;
+	uint32_t max_spec_nodata_ps_poll;
+};
+
+
+/**
+ * struct gtx_config_t - GTX config
+ * @gtxRTMask: for HT and VHT rate masks
+ * @gtxUsrcfg: host request for GTX mask
+ * @gtxPERThreshold: PER Threshold (default: 10%)
+ * @gtxPERMargin: PER margin (default: 2%)
+ * @gtxTPCstep: TCP step (default: 1)
+ * @gtxTPCMin: TCP min (default: 5)
+ * @gtxBWMask: BW mask (20/40/80/160 Mhz)
+ */
+typedef struct {
+	uint32_t gtxRTMask[2];
+	uint32_t gtxUsrcfg;
+	uint32_t gtxPERThreshold;
+	uint32_t gtxPERMargin;
+	uint32_t gtxTPCstep;
+	uint32_t gtxTPCMin;
+	uint32_t gtxBWMask;
+} gtx_config_t;
+
+/**
+ * struct pdev_cli_config_t - store pdev parameters
+ * @ani_enable: ANI is enabled/disable on target
+ * @ani_poll_len: store ANI polling period
+ * @ani_listen_len: store ANI listening period
+ * @ani_ofdm_level: store ANI OFDM immunity level
+ * @ani_cck_level: store ANI CCK immunity level
+ * @cwmenable: Dynamic bw is enable/disable in fw
+ * @txchainmask: tx chain mask
+ * @rxchainmask: rx chain mask
+ * @txpow2g: tx power limit for 2GHz
+ * @txpow5g: tx power limit for 5GHz
+ *
+ * This structure stores pdev parameters.
+ * Some of these parameters are set in fw and some
+ * parameters are only maintained in host.
+ */
+typedef struct {
+	uint32_t ani_enable;
+	uint32_t ani_poll_len;
+	uint32_t ani_listen_len;
+	uint32_t ani_ofdm_level;
+	uint32_t ani_cck_level;
+	uint32_t cwmenable;
+	uint32_t cts_cbw;
+	uint32_t txchainmask;
+	uint32_t rxchainmask;
+	uint32_t txpow2g;
+	uint32_t txpow5g;
+} pdev_cli_config_t;
+
+/**
+ * struct vdev_cli_config_t - store vdev parameters
+ * @nss: nss width
+ * @ldpc: is ldpc is enable/disable
+ * @tx_stbc: TX STBC is enable/disable
+ * @rx_stbc: RX STBC is enable/disable
+ * @shortgi: short gi is enable/disable
+ * @rtscts_en: RTS/CTS is enable/disable
+ * @chwidth: channel width
+ * @tx_rate: tx rate
+ * @ampdu: ampdu size
+ * @amsdu: amsdu size
+ * @erx_adjust: enable/disable early rx enable
+ * @erx_bmiss_num: target bmiss number per sample
+ * @erx_bmiss_cycle: sample cycle
+ * @erx_slop_step: slop_step value
+ * @erx_init_slop: init slop
+ * @erx_adj_pause: pause adjust enable/disable
+ * @erx_dri_sample: enable/disable drift sample
+ * @pps_params: packet power save parameters
+ * @qpower_params: qpower parameters
+ * @gtx_info: GTX offload info
+ * @dcm: DCM enable/disable
+ * @range_ext: HE range extension enable/disable
+ *
+ * This structure stores vdev parameters.
+ * Some of these parameters are set in fw and some
+ * parameters are only maintained in host.
+ */
+typedef struct {
+	uint32_t nss;
+	uint32_t ldpc;
+	uint32_t tx_stbc;
+	uint32_t rx_stbc;
+	uint32_t shortgi;
+	uint32_t rtscts_en;
+	uint32_t chwidth;
+	uint32_t tx_rate;
+	uint32_t ampdu;
+	uint32_t amsdu;
+	uint32_t erx_adjust;
+	uint32_t erx_bmiss_num;
+	uint32_t erx_bmiss_cycle;
+	uint32_t erx_slop_step;
+	uint32_t erx_init_slop;
+	uint32_t erx_adj_pause;
+	uint32_t erx_dri_sample;
+	struct pps pps_params;
+	struct qpower_params qpower_params;
+	gtx_config_t gtx_info;
+#ifdef WLAN_FEATURE_11AX
+	uint8_t dcm;
+	uint8_t range_ext;
+#endif
+} vdev_cli_config_t;
+
+/**
+ * struct wma_version_info - Store wmi version info
+ * @major: wmi major version
+ * @minor: wmi minor version
+ * @revision: wmi revision number
+ */
+struct wma_version_info {
+	u_int32_t major;
+	u_int32_t minor;
+	u_int32_t revision;
+};
+
+/**
+ * struct wma_wow - store wow patterns
+ * @magic_ptrn_enable: magic pattern enable/disable
+ * @wow_enable: wow enable/disable
+ * @wow_enable_cmd_sent: is wow enable command sent to fw
+ * @deauth_enable: is deauth wakeup enable/disable
+ * @disassoc_enable: is disassoc wakeup enable/disable
+ * @gtk_pdev_enable: is GTK based wakeup enable/disable
+ * @gtk_err_enable: is GTK error wakeup enable/disable
+ * @lphb_cache: lphb cache
+ *
+ * This structure stores wow patterns and
+ * wow related parameters in host.
+ */
+struct wma_wow {
+	bool magic_ptrn_enable;
+	bool wow_enable;
+	bool wow_enable_cmd_sent;
+	bool deauth_enable;
+	bool disassoc_enable;
+	bool gtk_err_enable[WMA_MAX_SUPPORTED_BSS];
+};
+
+#ifdef WLAN_FEATURE_11W
+#define CMAC_IPN_LEN         (6)
+#define WMA_IGTK_KEY_INDEX_4 (4)
+#define WMA_IGTK_KEY_INDEX_5 (5)
+
+/**
+ * struct wma_igtk_ipn_t - GTK IPN info
+ * @ipn: IPN info
+ */
+typedef struct {
+	uint8_t ipn[CMAC_IPN_LEN];
+} wma_igtk_ipn_t;
+
+/**
+ * struct wma_igtk_key_t - GTK key
+ * @key_length: key length
+ * @key: key
+ * @key_id: key id
+ * @key_cipher: key type
+ */
+typedef struct {
+	uint16_t key_length;
+	uint8_t key[CSR_AES_GMAC_256_KEY_LEN];
+
+	/* IPN is maintained per iGTK keyID
+	 * 0th index for iGTK keyID = 4;
+	 * 1st index for iGTK KeyID = 5
+	 */
+	wma_igtk_ipn_t key_id[2];
+	uint32_t key_cipher;
+} wma_igtk_key_t;
+#endif
+
+/**
+ * struct vdev_restart_params_t - vdev restart parameters
+ * @vdev_id: vdev id
+ * @ssid: ssid
+ * @flags: flags
+ * @requestor_id: requestor id
+ * @chan: channel
+ * @hidden_ssid_restart_in_progress: hidden ssid restart flag
+ * @ssidHidden: is ssid hidden or not
+ */
+typedef struct {
+	A_UINT32 vdev_id;
+	wmi_ssid ssid;
+	A_UINT32 flags;
+	A_UINT32 requestor_id;
+	A_UINT32 disable_hw_ack;
+	wmi_channel chan;
+#ifndef CONFIG_VDEV_SM
+	qdf_atomic_t hidden_ssid_restart_in_progress;
+#endif
+	uint8_t ssidHidden;
+} vdev_restart_params_t;
+
+struct roam_synch_frame_ind {
+	uint32_t bcn_probe_rsp_len;
+	uint8_t *bcn_probe_rsp;
+	uint8_t is_beacon;
+	uint32_t reassoc_req_len;
+	uint8_t *reassoc_req;
+	uint32_t reassoc_rsp_len;
+	uint8_t *reassoc_rsp;
+};
+
+
+/**
+ * struct wma_txrx_node - txrx node
+ * @vdev: pointer to vdev object
+ * @addr: mac address
+ * @bssid: bssid
+ * @handle: wma handle
+ * @beacon: beacon info
+ * @vdev_restart_params: vdev restart parameters
+ * @config: per vdev config parameters
+ * @scan_info: scan info
+ * @type: type
+ * @sub_type: sub type
+ * @nlo_match_evt_received: is nlo match event received or not
+ * @pno_in_progress: is pno in progress or not
+ * @plm_in_progress: is plm in progress or not
+ * @ptrn_match_enable: is pattern match is enable or not
+ * @num_wow_default_patterns: number of default wow patterns configured for vdev
+ * @num_wow_user_patterns: number of user wow patterns configured for vdev
+ * @conn_state: connection state
+ * @beaconInterval: beacon interval
+ * @llbCoexist: 11b coexist
+ * @shortSlotTimeSupported: is short slot time supported or not
+ * @dtimPeriod: DTIM period
+ * @chanmode: channel mode
+ * @vht_capable: VHT capablity flag
+ * @ht_capable: HT capablity flag
+ * @mhz: channel frequency in KHz
+ * @chan_width: channel bandwidth
+ * @vdev_up: is vdev up or not
+ * @tsfadjust: TSF adjust
+ * @addBssStaContext: add bss context
+ * @aid: association id
+ * @rmfEnabled: Robust Management Frame (RMF) enabled/disabled
+ * @key: GTK key
+ * @uapsd_cached_val: uapsd cached value
+ * @stats_rsp: stats response
+ * @fw_stats_set: fw stats value
+ * @del_staself_req: delete sta self request
+ * @bss_status: bss status
+ * @rate_flags: rate flags
+ * @nss: nss value
+ * @is_channel_switch: is channel switch
+ * @pause_bitmap: pause bitmap
+ * @tx_power: tx power in dbm
+ * @max_tx_power: max tx power in dbm
+ * @nwType: network type (802.11a/b/g/n/ac)
+ * @staKeyParams: sta key parameters
+ * @ps_enabled: is powersave enable/disable
+ * @peer_count: peer count
+ * @roam_synch_in_progress: flag is in progress or not
+ * @plink_status_req: link status request
+ * @psnr_req: snr request
+ * @delay_before_vdev_stop: delay
+ * @tx_streams: number of tx streams can be used by the vdev
+ * @rx_streams: number of rx streams can be used by the vdev
+ * @chain_mask: chain mask can be used by the vdev
+ * @mac_id: the mac on which vdev is on
+ * @wep_default_key_idx: wep default index for group key
+ * @arp_offload_req: cached arp offload request
+ * @ns_offload_req: cached ns offload request
+ * @wow_stats: stat counters for WoW related events
+ * @rcpi_req: rcpi request
+ * @in_bmps: Whether bmps for this interface has been enabled
+ * @vdev_start_wakelock: wakelock to protect vdev start op with firmware
+ * @vdev_stop_wakelock: wakelock to protect vdev stop op with firmware
+ * @vdev_set_key_wakelock: wakelock to protect vdev set key op with firmware
+ * @channel: channel
+ * @roam_scan_stats_req: cached roam scan stats request
+ *
+ * It stores parameters per vdev in wma.
+ */
+struct wma_txrx_node {
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t addr[IEEE80211_ADDR_LEN];
+	uint8_t bssid[IEEE80211_ADDR_LEN];
+	struct cdp_vdev *handle;
+	struct beacon_info *beacon;
+	vdev_restart_params_t vdev_restart_params;
+	vdev_cli_config_t config;
+	uint32_t type;
+	uint32_t sub_type;
+#ifdef FEATURE_WLAN_ESE
+	bool plm_in_progress;
+#endif
+	bool ptrn_match_enable;
+	uint8_t num_wow_default_patterns;
+	uint8_t num_wow_user_patterns;
+	bool conn_state;
+	tSirMacBeaconInterval beaconInterval;
+	uint8_t llbCoexist;
+	uint8_t shortSlotTimeSupported;
+	uint8_t dtimPeriod;
+	WMI_HOST_WLAN_PHY_MODE chanmode;
+	uint8_t vht_capable;
+	uint8_t ht_capable;
+	A_UINT32 mhz;
+	enum phy_ch_width chan_width;
+	bool vdev_active;
+	uint64_t tsfadjust;
+	void *addBssStaContext;
+	uint8_t aid;
+	uint8_t rmfEnabled;
+#ifdef WLAN_FEATURE_11W
+	wma_igtk_key_t key;
+	uint32_t ucast_key_cipher;
+#endif /* WLAN_FEATURE_11W */
+	uint32_t uapsd_cached_val;
+	tAniGetPEStatsRsp *stats_rsp;
+	uint8_t fw_stats_set;
+	void *del_staself_req;
+	bool is_del_sta_defered;
+	qdf_atomic_t bss_status;
+	uint8_t rate_flags;
+	uint8_t nss;
+#ifndef CONFIG_VDEV_SM
+	bool is_channel_switch;
+#endif
+	uint16_t pause_bitmap;
+	int8_t tx_power;
+	int8_t max_tx_power;
+	uint32_t nwType;
+	void *staKeyParams;
+	uint32_t peer_count;
+	bool roam_synch_in_progress;
+	void *plink_status_req;
+	void *psnr_req;
+	uint8_t delay_before_vdev_stop;
+#ifdef FEATURE_WLAN_EXTSCAN
+	bool extscan_in_progress;
+#endif
+	uint32_t tx_streams;
+	uint32_t rx_streams;
+	uint32_t chain_mask;
+	uint32_t mac_id;
+	bool roaming_in_progress;
+	int32_t roam_synch_delay;
+	uint8_t nss_2g;
+	uint8_t nss_5g;
+	bool p2p_lo_in_progress;
+	uint8_t wep_default_key_idx;
+	tSirHostOffloadReq arp_offload_req;
+	tSirHostOffloadReq ns_offload_req;
+#ifndef QCA_SUPPORT_CP_STATS
+	struct sir_vdev_wow_stats wow_stats;
+#endif
+	struct sme_rcpi_req *rcpi_req;
+#ifdef WLAN_FEATURE_11AX
+	bool he_capable;
+	uint32_t he_ops;
+#endif
+	bool in_bmps;
+	struct beacon_filter_param beacon_filter;
+	bool beacon_filter_enabled;
+	qdf_wake_lock_t vdev_start_wakelock;
+	qdf_wake_lock_t vdev_stop_wakelock;
+	qdf_wake_lock_t vdev_set_key_wakelock;
+	struct roam_synch_frame_ind roam_synch_frame_ind;
+	bool is_waiting_for_key;
+	uint8_t channel;
+	struct sir_roam_scan_stats *roam_scan_stats_req;
+};
+
+/**
+ * struct ibss_power_save_params - IBSS power save parameters
+ * @atimWindowLength: ATIM window length
+ * @isPowerSaveAllowed: is power save allowed
+ * @isPowerCollapseAllowed: is power collapsed allowed
+ * @isAwakeonTxRxEnabled: is awake on tx/rx enabled
+ * @inactivityCount: inactivity count
+ * @txSPEndInactivityTime: tx SP end inactivity time
+ * @ibssPsWarmupTime: IBSS power save warm up time
+ * @ibssPs1RxChainInAtimEnable: IBSS power save rx chain in ATIM enable
+ */
+typedef struct {
+	uint32_t atimWindowLength;
+	uint32_t isPowerSaveAllowed;
+	uint32_t isPowerCollapseAllowed;
+	uint32_t isAwakeonTxRxEnabled;
+	uint32_t inactivityCount;
+	uint32_t txSPEndInactivityTime;
+	uint32_t ibssPsWarmupTime;
+	uint32_t ibssPs1RxChainInAtimEnable;
+} ibss_power_save_params;
+
+/**
+ * struct mac_ss_bw_info - hw_mode_list PHY/MAC params for each MAC
+ * @mac_tx_stream: Max TX stream
+ * @mac_rx_stream: Max RX stream
+ * @mac_bw: Max bandwidth
+ */
+struct mac_ss_bw_info {
+	uint32_t mac_tx_stream;
+	uint32_t mac_rx_stream;
+	uint32_t mac_bw;
+};
+
+/**
+ * struct wma_ini_config - Structure to hold wma ini configuration
+ * @max_no_of_peers: Max Number of supported
+ *
+ * Placeholder for WMA ini parameters.
+ */
+struct wma_ini_config {
+	uint8_t max_no_of_peers;
+};
+
+/**
+ * struct wmi_valid_channels - Channel details part of WMI_SCAN_CHAN_LIST_CMDID
+ * @num_channels: Number of channels
+ * @channel_list: Channel list
+ */
+struct wma_valid_channels {
+	uint8_t num_channels;
+	uint8_t channel_list[MAX_NUM_CHAN];
+};
+
+/**
+ * struct t_wma_handle - wma context
+ * @wmi_handle: wmi handle
+ * @cds_context: cds handle
+ * @mac_context: mac context
+ * @psoc: psoc context
+ * @pdev: physical device global object
+ * @wma_resume_event: wma resume event
+ * @target_suspend: target suspend event
+ * @recovery_event: wma FW recovery event
+ * @max_station: max stations
+ * @max_bssid: max bssid
+ * @myaddr: current mac address
+ * @hwaddr: mac address from EEPROM
+ * @lpss_support: LPSS feature is supported in target or not
+ * @wmi_ready: wmi status flag
+ * @wlan_init_status: wlan init status
+ * @qdf_dev: qdf device
+ * @wmi_service_bitmap: wmi services bitmap received from Target
+ * @wmi_service_ext_bitmap: extended wmi services bitmap received from Target
+ * @tx_frm_download_comp_cb: Tx Frame Compl Cb registered by umac
+ * @tx_frm_download_comp_event: Event to wait for tx download completion
+ * @tx_queue_empty_event: Dummy event to wait for draining MSDUs left
+ *   in hardware tx queue and before requesting VDEV_STOP. Nobody will
+ *   set this and wait will timeout, and code will poll the pending tx
+ *   descriptors number to be zero.
+ * @umac_ota_ack_cb: Ack Complete Callback registered by umac
+ * @umac_data_ota_ack_cb: ack complete callback
+ * @last_umac_data_ota_timestamp: timestamp when OTA of last umac data
+ *   was done
+ * @last_umac_data_nbuf: cache nbuf ptr for the last umac data buf
+ * @needShutdown: is shutdown needed or not
+ * @tgt_cfg_update_cb: configuration update callback
+ * @reg_cap: regulatory capablities
+ * @scan_id: scan id
+ * @interfaces: txrx nodes(per vdev)
+ * @pdevconfig: pdev related configrations
+ * @vdev_resp_queue: vdev response queue
+ * @vdev_respq_lock: vdev response queue lock
+ * @wma_hold_req_queue: Queue use to serialize requests to firmware
+ * @wma_hold_req_q_lock: Mutex for @wma_hold_req_queue
+ * @vht_supp_mcs: VHT supported MCS
+ * @is_fw_assert: is fw asserted
+ * @wow: wow related patterns & parameters
+ * @no_of_suspend_ind: number of suspend indications
+ * @no_of_resume_ind: number of resume indications
+ * @ack_work_ctx: Context for deferred processing of TX ACK
+ * @powersave_mode: power save mode
+ * @ptrn_match_enable_all_vdev: is pattern match is enable/disable
+ * @pGetRssiReq: get RSSI request
+ * @get_one_peer_info: When a "get peer info" request is active, is
+ *   the request for a single peer?
+ * @get_sta_peer_info: Is a "get peer info" request active?
+ * @peer_macaddr: When @get_one_peer_info is true, the peer's mac address
+ * @thermal_mgmt_info: Thermal mitigation related info
+ * @roam_offload_enabled: is roam offload enable/disable
+ * @ssdp: ssdp flag
+ * @enable_mc_list: To Check if Multicast list filtering is enabled in FW
+ * @ibss_started: is IBSS started or not
+ * @ibsskey_info: IBSS key info
+ * @hddTxFailCb: tx fail indication callback
+ * @extscan_wake_lock: extscan wake lock
+ * @wow_wake_lock: wow wake lock
+ * @wow_auth_req_wl: wow wake lock for auth req
+ * @wow_assoc_req_wl: wow wake lock for assoc req
+ * @wow_deauth_rec_wl: wow wake lock for deauth req
+ * @wow_disassoc_rec_wl: wow wake lock for disassoc req
+ * @wow_ap_assoc_lost_wl: wow wake lock for assoc lost req
+ * @wow_auto_shutdown_wl: wow wake lock for shutdown req
+ * @roam_ho_wl: wake lock for roam handoff req
+ * @wow_nack: wow negative ack flag
+ * @is_wow_bus_suspended: is wow bus suspended flag
+ * @wma_scan_comp_timer: scan completion timer
+ * @suitable_ap_hb_failure: better ap found
+ * @suitable_ap_hb_failure_rssi: RSSI when suitable_ap_hb_failure
+ *   triggered for later usage to report RSSI at beacon miss scenario
+ * @wma_ibss_power_save_params: IBSS Power Save config Parameters
+ * @IsRArateLimitEnabled: RA rate limiti s enabled or not
+ * @RArateLimitInterval: RA rate limit interval
+ * @is_lpass_enabled: Flag to indicate if LPASS feature is enabled or not
+ * @is_nan_enabled: Flag to indicate if NaN feature is enabled or not
+ * @staMaxLIModDtim: station max listen interval
+ * @staModDtim: station mode DTIM
+ * @staDynamicDtim: station dynamic DTIM
+ * @enable_mhf_offload: is MHF offload enable/disable
+ * @last_mhf_entries_timestamp: timestamp when last entries where set
+ * @hw_bd_id: hardware board id
+ * @hw_bd_info: hardware board info
+ * @miracast_value: miracast value
+ * @log_completion_timer: log completion timer
+ * @num_dbs_hw_modes: Number of HW modes supported by the FW
+ * @hw_mode: DBS HW mode list
+ * @old_hw_mode_index: Previous configured HW mode index
+ * @new_hw_mode_index: Current configured HW mode index
+ * @peer_authorized_cb: peer authorized hdd callback
+ * @wow_unspecified_wake_count: Number of wake events which did not
+ *   correspond to known wake events. Note that known wake events are
+ *   tracked on a per-vdev basis via the struct sir_vdev_wow_stats
+ *   wow_stats in struct wma_txrx_node
+ * @ocb_config_req: OCB request context
+ * @max_scan:  maximum scan requests than can be queued
+ * @self_gen_frm_pwr: Self-generated frame power
+ * @tx_chain_mask_cck: Is the CCK tx chain mask enabled
+ * @service_ready_ext_timer: Timer for service ready extended.  Note
+ *   this is a a timer instead of wait event because on receiving the
+ *   service ready event, we will be waiting on the MC thread for the
+ *   service extended ready event which is also processed in MC
+ *   thread.  This leads to MC thread being stuck. Alternative was to
+ *   process these events in tasklet/workqueue context. But, this
+ *   leads to race conditions when the events are processed in two
+ *   different context. So, processing ready event and extended ready
+ *   event in the serialized MC thread context with a timer.
+ * @csr_roam_synch_cb: CSR callback for firmware Roam Sync events
+ * @pe_roam_synch_cb: pe callback for firmware Roam Sync events
+ * @wmi_cmd_rsp_wake_lock: wmi command response wake lock
+ * @wmi_cmd_rsp_runtime_lock: wmi command response bus lock
+ * @active_uc_apf_mode: Setting that determines how APF is applied in
+ *   active mode for uc packets
+ * @active_mc_bc_apf_mode: Setting that determines how APF is applied in
+ *   active mode for MC/BC packets
+ * @ini_config: Initial configuration from upper layer
+ * @saved_chan: saved channel list sent as part of
+ *   WMI_SCAN_CHAN_LIST_CMDID
+ * @nan_datapath_enabled: Is NAN datapath support enabled in firmware?
+ * @pe_ndp_event_handler: Handler function for NAN Data Path events
+ * @fw_timeout_crash: Should firmware be reset upon response timeout?
+ * @sub_20_support: Does target support sub-20MHz bandwidth (aka
+ *   half-rate and quarter-rate)?
+ * @is_dfs_offloaded: Is dfs and cac timer offloaded?
+ * @wma_mgmt_tx_packetdump_cb: Callback function for TX packet dump
+ * @wma_mgmt_rx_packetdump_cb: Callback function for RX packet dump
+ * @rcpi_enabled: Is RCPI enabled?
+ * @link_stats_results: Structure for handing link stats from firmware
+ * @tx_fail_cnt: Number of TX failures
+ * @he_cap: 802.11ax capabilities
+ * @bandcapability: band capability configured through ini
+ * @tx_bfee_8ss_enabled: Is Tx Beamformee support for 8x8 enabled?
+ * @in_imps: Is device in Idle Mode Power Save?
+ * @ito_repeat_count: Indicates ito repeated count
+ * @wma_fw_time_sync_timer: timer used for firmware time sync
+ * @critical_events_in_flight: number of suspend-preventing events
+ *   in flight
+ *
+ * This structure is the global wma context.  It contains global wma
+ * module parameters and handles of other modules.
+
+ */
+typedef struct {
+	void *wmi_handle;
+	void *cds_context;
+	void *mac_context;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	qdf_event_t wma_resume_event;
+	qdf_event_t target_suspend;
+	qdf_event_t runtime_suspend;
+	qdf_event_t recovery_event;
+	uint16_t max_station;
+	uint16_t max_bssid;
+	uint8_t myaddr[IEEE80211_ADDR_LEN];
+	uint8_t hwaddr[IEEE80211_ADDR_LEN];
+#ifdef WLAN_FEATURE_LPSS
+	uint8_t lpss_support;
+#endif
+	uint8_t ap_arpns_support;
+	bool wmi_ready;
+	uint32_t wlan_init_status;
+	qdf_device_t qdf_dev;
+	uint32_t wmi_service_bitmap[WMI_SERVICE_BM_SIZE];
+	uint32_t wmi_service_ext_bitmap[WMI_SERVICE_SEGMENT_BM_SIZE32];
+	wma_tx_dwnld_comp_callback tx_frm_download_comp_cb;
+	qdf_event_t tx_frm_download_comp_event;
+	qdf_event_t tx_queue_empty_event;
+	wma_tx_ota_comp_callback
+				umac_ota_ack_cb[SIR_MAC_MGMT_RESERVED15];
+	wma_tx_ota_comp_callback umac_data_ota_ack_cb;
+	unsigned long last_umac_data_ota_timestamp;
+	qdf_nbuf_t last_umac_data_nbuf;
+	bool needShutdown;
+	wma_tgt_cfg_cb tgt_cfg_update_cb;
+	HAL_REG_CAPABILITIES reg_cap;
+	uint32_t scan_id;
+	struct wma_txrx_node *interfaces;
+	pdev_cli_config_t pdevconfig;
+	qdf_list_t vdev_resp_queue;
+	qdf_spinlock_t vdev_respq_lock;
+	qdf_list_t wma_hold_req_queue;
+	qdf_spinlock_t wma_hold_req_q_lock;
+	uint32_t vht_supp_mcs;
+	uint8_t is_fw_assert;
+	struct wma_wow wow;
+	uint8_t no_of_suspend_ind;
+	uint8_t no_of_resume_ind;
+	struct wma_tx_ack_work_ctx *ack_work_ctx;
+	uint8_t powersave_mode;
+	bool ptrn_match_enable_all_vdev;
+	void *pGetRssiReq;
+	bool get_one_peer_info;
+	bool get_sta_peer_info;
+	struct qdf_mac_addr peer_macaddr;
+	t_thermal_mgmt thermal_mgmt_info;
+	bool roam_offload_enabled;
+	bool ssdp;
+	bool enable_mc_list;
+	uint8_t ibss_started;
+	tSetBssKeyParams ibsskey_info;
+	txFailIndCallback hddTxFailCb;
+#ifdef FEATURE_WLAN_EXTSCAN
+	qdf_wake_lock_t extscan_wake_lock;
+#endif
+	qdf_wake_lock_t wow_wake_lock;
+	qdf_wake_lock_t wow_auth_req_wl;
+	qdf_wake_lock_t wow_assoc_req_wl;
+	qdf_wake_lock_t wow_deauth_rec_wl;
+	qdf_wake_lock_t wow_disassoc_rec_wl;
+	qdf_wake_lock_t wow_ap_assoc_lost_wl;
+	qdf_wake_lock_t wow_auto_shutdown_wl;
+	qdf_wake_lock_t roam_ho_wl;
+	int wow_nack;
+	qdf_atomic_t is_wow_bus_suspended;
+	qdf_mc_timer_t wma_scan_comp_timer;
+	bool suitable_ap_hb_failure;
+	uint32_t suitable_ap_hb_failure_rssi;
+	ibss_power_save_params wma_ibss_power_save_params;
+#ifdef FEATURE_WLAN_RA_FILTERING
+	bool IsRArateLimitEnabled;
+	uint16_t RArateLimitInterval;
+#endif
+#ifdef WLAN_FEATURE_LPSS
+	bool is_lpass_enabled;
+#endif
+#ifdef WLAN_FEATURE_NAN
+	bool is_nan_enabled;
+#endif
+	uint8_t staMaxLIModDtim;
+	uint8_t staModDtim;
+	uint8_t staDynamicDtim;
+	uint8_t enable_mhf_offload;
+	unsigned long last_mhf_entries_timestamp;
+	uint32_t hw_bd_id;
+	uint32_t hw_bd_info[HW_BD_INFO_SIZE];
+	uint32_t miracast_value;
+	qdf_mc_timer_t log_completion_timer;
+	uint32_t num_dbs_hw_modes;
+	struct dbs_hw_mode_info hw_mode;
+	uint32_t old_hw_mode_index;
+	uint32_t new_hw_mode_index;
+	wma_peer_authorized_fp peer_authorized_cb;
+	uint32_t wow_unspecified_wake_count;
+	struct sir_ocb_config *ocb_config_req;
+	uint8_t max_scan;
+	uint16_t self_gen_frm_pwr;
+	bool tx_chain_mask_cck;
+	qdf_mc_timer_t service_ready_ext_timer;
+
+	QDF_STATUS (*csr_roam_synch_cb)(tpAniSirGlobal mac,
+		roam_offload_synch_ind *roam_synch_data,
+		tpSirBssDescription  bss_desc_ptr,
+		enum sir_roam_op_code reason);
+	QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac,
+		roam_offload_synch_ind *roam_synch_data,
+		tpSirBssDescription  bss_desc_ptr,
+		enum sir_roam_op_code reason);
+	qdf_wake_lock_t wmi_cmd_rsp_wake_lock;
+	qdf_runtime_lock_t wmi_cmd_rsp_runtime_lock;
+	enum active_apf_mode active_uc_apf_mode;
+	enum active_apf_mode active_mc_bc_apf_mode;
+	struct wma_ini_config ini_config;
+	struct wma_valid_channels saved_chan;
+	bool nan_datapath_enabled;
+	QDF_STATUS (*pe_ndp_event_handler)(tpAniSirGlobal mac_ctx,
+					   struct scheduler_msg *msg);
+	bool fw_timeout_crash;
+	bool sub_20_support;
+	bool is_dfs_offloaded;
+	tp_wma_packetdump_cb wma_mgmt_tx_packetdump_cb;
+	tp_wma_packetdump_cb wma_mgmt_rx_packetdump_cb;
+	bool rcpi_enabled;
+	tSirLLStatsResults *link_stats_results;
+	uint64_t tx_fail_cnt;
+#ifdef WLAN_FEATURE_11AX
+	struct he_capability he_cap;
+#endif
+	uint8_t bandcapability;
+	bool tx_bfee_8ss_enabled;
+	bool in_imps;
+	uint8_t  ito_repeat_count;
+	qdf_mc_timer_t wma_fw_time_sync_timer;
+	qdf_atomic_t critical_events_in_flight;
+} t_wma_handle, *tp_wma_handle;
+
+extern void cds_wma_complete_cback(void);
+extern void wma_send_regdomain_info_to_fw(uint32_t reg_dmn, uint16_t regdmn2G,
+					  uint16_t regdmn5G, uint8_t ctl2G,
+					  uint8_t ctl5G);
+/**
+ * enum frame_index - Frame index
+ * @GENERIC_NODOWNLD_NOACK_COMP_INDEX: Frame index for no download comp no ack
+ * @GENERIC_DOWNLD_COMP_NOACK_COMP_INDEX: Frame index for download comp no ack
+ * @GENERIC_DOWNLD_COMP_ACK_COMP_INDEX: Frame index for download comp and ack
+ * @GENERIC_NODOWLOAD_ACK_COMP_INDEX: Frame index for no download comp and ack
+ * @FRAME_INDEX_MAX: maximum frame index
+ */
+enum frame_index {
+	GENERIC_NODOWNLD_NOACK_COMP_INDEX,
+	GENERIC_DOWNLD_COMP_NOACK_COMP_INDEX,
+	GENERIC_DOWNLD_COMP_ACK_COMP_INDEX,
+	GENERIC_NODOWLOAD_ACK_COMP_INDEX,
+	FRAME_INDEX_MAX
+};
+
+/**
+ * struct wma_tx_ack_work_ctx - tx ack work context
+ * @wma_handle: wma handle
+ * @sub_type: sub type
+ * @status: status
+ * @ack_cmp_work: work structure
+ */
+struct wma_tx_ack_work_ctx {
+	tp_wma_handle wma_handle;
+	uint16_t sub_type;
+	int32_t status;
+	qdf_work_t ack_cmp_work;
+};
+
+/**
+ * struct wma_target_req - target request parameters
+ * @event_timeout: event timeout
+ * @node: list
+ * @user_data: user data
+ * @msg_type: message type
+ * @vdev_id: vdev id
+ * @type: type
+ */
+struct wma_target_req {
+	qdf_mc_timer_t event_timeout;
+	qdf_list_node_t node;
+	void *user_data;
+	uint32_t msg_type;
+	uint8_t vdev_id;
+	uint8_t type;
+};
+
+/**
+ * struct wma_vdev_start_req - vdev start request parameters
+ * @beacon_intval: beacon interval
+ * @dtim_period: dtim period
+ * @max_txpow: max tx power
+ * @chan_offset: channel offset
+ * @is_dfs: is dfs supported or not
+ * @vdev_id: vdev id
+ * @chan: channel
+ * @oper_mode: operating mode
+ * @ssid: ssid
+ * @hidden_ssid: hidden ssid
+ * @pmf_enabled: is pmf enabled or not
+ * @vht_capable: VHT capabality
+ * @ht_capable: HT capabality
+ * @dot11_mode: 802.11 mode
+ * @is_half_rate: is the channel operating at 10MHz
+ * @is_quarter_rate: is the channel operating at 5MHz
+ * @preferred_tx_streams: policy manager indicates the preferred
+ *			number of transmit streams
+ * @preferred_rx_streams: policy manager indicates the preferred
+ *			number of receive streams
+ * @beacon_tx_rate: beacon tx rate
+ * @he_capable: HE capability
+ * @he_ops: HE operation
+ * @cac_duration_ms: cac duration in milliseconds
+ * @dfs_regdomain: dfs region
+ */
+struct wma_vdev_start_req {
+	uint32_t beacon_intval;
+	uint32_t dtim_period;
+	int32_t max_txpow;
+	enum phy_ch_width chan_width;
+	bool is_dfs;
+	uint8_t vdev_id;
+	uint8_t chan;
+	uint8_t oper_mode;
+	tSirMacSSid ssid;
+	uint8_t hidden_ssid;
+	uint8_t pmf_enabled;
+	uint8_t vht_capable;
+	uint8_t ch_center_freq_seg0;
+	uint8_t ch_center_freq_seg1;
+	uint8_t ht_capable;
+	uint8_t dot11_mode;
+	bool is_half_rate;
+	bool is_quarter_rate;
+	uint32_t preferred_tx_streams;
+	uint32_t preferred_rx_streams;
+	uint16_t beacon_tx_rate;
+#ifdef WLAN_FEATURE_11AX
+	bool he_capable;
+	uint32_t he_ops;
+#endif
+	uint32_t cac_duration_ms;
+	uint32_t dfs_regdomain;
+};
+
+/**
+ * struct wma_set_key_params - set key parameters
+ * @vdev_id: vdev id
+ * @def_key_idx: used to see if we have to read the key from cfg
+ * @key_len: key length
+ * @peer_mac: peer mac address
+ * @singl_tid_rc: 1=Single TID based Replay Count, 0=Per TID based RC
+ * @key_type: key type
+ * @key_idx: key index
+ * @unicast: unicast flag
+ * @key_data: key data
+ */
+struct wma_set_key_params {
+	uint8_t vdev_id;
+	/* def_key_idx can be used to see if we have to read the key from cfg */
+	uint32_t def_key_idx;
+	uint16_t key_len;
+	uint8_t peer_mac[IEEE80211_ADDR_LEN];
+	uint8_t singl_tid_rc;
+	enum eAniEdType key_type;
+	uint32_t key_idx;
+	bool unicast;
+	uint8_t key_data[SIR_MAC_MAX_KEY_LENGTH];
+	uint8_t key_rsc[SIR_MAC_MAX_KEY_RSC_LEN];
+};
+
+/**
+ * struct t_thermal_cmd_params - thermal command parameters
+ * @minTemp: minimum temprature
+ * @maxTemp: maximum temprature
+ * @thermalEnable: thermal enable
+ */
+typedef struct {
+	uint16_t minTemp;
+	uint16_t maxTemp;
+	uint8_t thermalEnable;
+} t_thermal_cmd_params, *tp_thermal_cmd_params;
+
+/**
+ * enum wma_cfg_cmd_id - wma cmd ids
+ * @WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID: txrx firmware stats enable command
+ * @WMA_VDEV_TXRX_FWSTATS_RESET_CMDID: txrx firmware stats reset command
+ * @WMA_VDEV_MCC_SET_TIME_LATENCY: set MCC latency time
+ * @WMA_VDEV_MCC_SET_TIME_QUOTA: set MCC time quota
+ * @WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE: set IBSS ATIM window size
+ * @WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED: set IBSS enable power save
+ * @WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED: set IBSS power collapse enable
+ * @WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX: awake IBSS on TX/RX
+ * @WMA_VDEV_IBSS_SET_INACTIVITY_TIME: set IBSS inactivity time
+ * @WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME: set IBSS TXSP
+ * @WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS: set IBSS power save warmup time
+ * @WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW: set IBSS power save ATIM
+ * @WMA_VDEV_TXRX_GET_IPA_UC_FW_STATS_CMDID: get IPA microcontroller fw stats
+ * @WMA_VDEV_TXRX_GET_IPA_UC_SHARING_STATS_CMDID: get IPA uC wifi-sharing stats
+ * @WMA_VDEV_TXRX_SET_IPA_UC_QUOTA_CMDID: set IPA uC quota limit
+ *
+ * wma command ids for configuration request which
+ * does not involve sending a wmi command.
+ */
+enum wma_cfg_cmd_id {
+	WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID = WMI_CMDID_MAX,
+	WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
+	WMA_VDEV_MCC_SET_TIME_LATENCY,
+	WMA_VDEV_MCC_SET_TIME_QUOTA,
+	WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE,
+	WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED,
+	WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED,
+	WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX,
+	WMA_VDEV_IBSS_SET_INACTIVITY_TIME,
+	WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME,
+	WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS,
+	WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW,
+	WMA_VDEV_TXRX_GET_IPA_UC_FW_STATS_CMDID,
+	WMA_VDEV_TXRX_GET_IPA_UC_SHARING_STATS_CMDID,
+	WMA_VDEV_TXRX_SET_IPA_UC_QUOTA_CMDID,
+	WMA_CMD_ID_MAX
+};
+
+/**
+ * struct wma_trigger_uapsd_params - trigger uapsd parameters
+ * @wmm_ac: wmm access category
+ * @user_priority: user priority
+ * @service_interval: service interval
+ * @suspend_interval: suspend interval
+ * @delay_interval: delay interval
+ */
+typedef struct wma_trigger_uapsd_params {
+	uint32_t wmm_ac;
+	uint32_t user_priority;
+	uint32_t service_interval;
+	uint32_t suspend_interval;
+	uint32_t delay_interval;
+} t_wma_trigger_uapsd_params, *tp_wma_trigger_uapsd_params;
+
+/**
+ * enum uapsd_peer_param_max_sp - U-APSD maximum service period of peer station
+ * @UAPSD_MAX_SP_LEN_UNLIMITED: unlimited max service period
+ * @UAPSD_MAX_SP_LEN_2: max service period = 2
+ * @UAPSD_MAX_SP_LEN_4: max service period = 4
+ * @UAPSD_MAX_SP_LEN_6: max service period = 6
+ */
+enum uapsd_peer_param_max_sp {
+	UAPSD_MAX_SP_LEN_UNLIMITED = 0,
+	UAPSD_MAX_SP_LEN_2 = 2,
+	UAPSD_MAX_SP_LEN_4 = 4,
+	UAPSD_MAX_SP_LEN_6 = 6
+};
+
+/**
+ * enum uapsd_peer_param_enabled_ac - U-APSD Enabled AC's of peer station
+ * @UAPSD_VO_ENABLED: enable uapsd for voice
+ * @UAPSD_VI_ENABLED: enable uapsd for video
+ * @UAPSD_BK_ENABLED: enable uapsd for background
+ * @UAPSD_BE_ENABLED: enable uapsd for best effort
+ */
+enum uapsd_peer_param_enabled_ac {
+	UAPSD_VO_ENABLED = 0x01,
+	UAPSD_VI_ENABLED = 0x02,
+	UAPSD_BK_ENABLED = 0x04,
+	UAPSD_BE_ENABLED = 0x08
+};
+
+/**
+ * enum profile_id_t - Firmware profiling index
+ * @PROF_CPU_IDLE: cpu idle profile
+ * @PROF_PPDU_PROC: ppdu processing profile
+ * @PROF_PPDU_POST: ppdu post profile
+ * @PROF_HTT_TX_INPUT: htt tx input profile
+ * @PROF_MSDU_ENQ: msdu enqueue profile
+ * @PROF_PPDU_POST_HAL: ppdu post profile
+ * @PROF_COMPUTE_TX_TIME: tx time profile
+ * @PROF_MAX_ID: max profile index
+ */
+enum profile_id_t {
+	PROF_CPU_IDLE,
+	PROF_PPDU_PROC,
+	PROF_PPDU_POST,
+	PROF_HTT_TX_INPUT,
+	PROF_MSDU_ENQ,
+	PROF_PPDU_POST_HAL,
+	PROF_COMPUTE_TX_TIME,
+	PROF_MAX_ID,
+};
+
+/**
+ * struct p2p_ie - P2P IE structural definition.
+ * @p2p_id: p2p id
+ * @p2p_len: p2p length
+ * @p2p_oui: p2p OUI
+ * @p2p_oui_type: p2p OUI type
+ */
+struct p2p_ie {
+	uint8_t p2p_id;
+	uint8_t p2p_len;
+	uint8_t p2p_oui[3];
+	uint8_t p2p_oui_type;
+} __packed;
+
+/**
+ * struct p2p_noa_descriptor - noa descriptor
+ * @type_count: 255: continuous schedule, 0: reserved
+ * @duration: Absent period duration in micro seconds
+ * @interval: Absent period interval in micro seconds
+ * @start_time: 32 bit tsf time when in starts
+ */
+struct p2p_noa_descriptor {
+	uint8_t type_count;
+	uint32_t duration;
+	uint32_t interval;
+	uint32_t start_time;
+} __packed;
+
+/**
+ * struct p2p_sub_element_noa - p2p noa element
+ * @p2p_sub_id: p2p sub id
+ * @p2p_sub_len: p2p sub length
+ * @index: identifies instance of NOA su element
+ * @oppPS: oppPS state of the AP
+ * @ctwindow: ctwindow in TUs
+ * @num_descriptors: number of NOA descriptors
+ * @noa_descriptors: noa descriptors
+ */
+struct p2p_sub_element_noa {
+	uint8_t p2p_sub_id;
+	uint8_t p2p_sub_len;
+	uint8_t index;          /* identifies instance of NOA su element */
+	uint8_t oppPS:1,        /* oppPS state of the AP */
+		ctwindow:7;     /* ctwindow in TUs */
+	uint8_t num_descriptors;        /* number of NOA descriptors */
+	struct p2p_noa_descriptor noa_descriptors[WMA_MAX_NOA_DESCRIPTORS];
+};
+
+/**
+ * struct wma_decap_info_t - decapsulation info
+ * @hdr: header
+ * @hdr_len: header length
+ */
+struct wma_decap_info_t {
+	uint8_t hdr[sizeof(struct ieee80211_qosframe_addr4)];
+	int32_t hdr_len;
+};
+
+/**
+ * enum packet_power_save - packet power save params
+ * @WMI_VDEV_PPS_PAID_MATCH: paid match param
+ * @WMI_VDEV_PPS_GID_MATCH: gid match param
+ * @WMI_VDEV_PPS_EARLY_TIM_CLEAR: early tim clear param
+ * @WMI_VDEV_PPS_EARLY_DTIM_CLEAR: early dtim clear param
+ * @WMI_VDEV_PPS_EOF_PAD_DELIM: eof pad delim param
+ * @WMI_VDEV_PPS_MACADDR_MISMATCH: macaddr mismatch param
+ * @WMI_VDEV_PPS_DELIM_CRC_FAIL: delim CRC fail param
+ * @WMI_VDEV_PPS_GID_NSTS_ZERO: gid nsts zero param
+ * @WMI_VDEV_PPS_RSSI_CHECK: RSSI check param
+ * @WMI_VDEV_PPS_5G_EBT: 5G ebt param
+ */
+typedef enum {
+	WMI_VDEV_PPS_PAID_MATCH = 0,
+	WMI_VDEV_PPS_GID_MATCH = 1,
+	WMI_VDEV_PPS_EARLY_TIM_CLEAR = 2,
+	WMI_VDEV_PPS_EARLY_DTIM_CLEAR = 3,
+	WMI_VDEV_PPS_EOF_PAD_DELIM = 4,
+	WMI_VDEV_PPS_MACADDR_MISMATCH = 5,
+	WMI_VDEV_PPS_DELIM_CRC_FAIL = 6,
+	WMI_VDEV_PPS_GID_NSTS_ZERO = 7,
+	WMI_VDEV_PPS_RSSI_CHECK = 8,
+	WMI_VDEV_VHT_SET_GID_MGMT = 9,
+	WMI_VDEV_PPS_5G_EBT = 10
+} packet_power_save;
+
+/**
+ * enum green_tx_param - green tx parameters
+ * @WMI_VDEV_PARAM_GTX_HT_MCS: ht mcs param
+ * @WMI_VDEV_PARAM_GTX_VHT_MCS: vht mcs param
+ * @WMI_VDEV_PARAM_GTX_USR_CFG: user cfg param
+ * @WMI_VDEV_PARAM_GTX_THRE: thre param
+ * @WMI_VDEV_PARAM_GTX_MARGIN: green tx margin param
+ * @WMI_VDEV_PARAM_GTX_STEP: green tx step param
+ * @WMI_VDEV_PARAM_GTX_MINTPC: mintpc param
+ * @WMI_VDEV_PARAM_GTX_BW_MASK: bandwidth mask
+ */
+typedef enum {
+	WMI_VDEV_PARAM_GTX_HT_MCS,
+	WMI_VDEV_PARAM_GTX_VHT_MCS,
+	WMI_VDEV_PARAM_GTX_USR_CFG,
+	WMI_VDEV_PARAM_GTX_THRE,
+	WMI_VDEV_PARAM_GTX_MARGIN,
+	WMI_VDEV_PARAM_GTX_STEP,
+	WMI_VDEV_PARAM_GTX_MINTPC,
+	WMI_VDEV_PARAM_GTX_BW_MASK,
+} green_tx_param;
+
+/**
+ * enum uapsd_ac - U-APSD Access Categories
+ * @UAPSD_BE: best effort
+ * @UAPSD_BK: back ground
+ * @UAPSD_VI: video
+ * @UAPSD_VO: voice
+ */
+enum uapsd_ac {
+	UAPSD_BE,
+	UAPSD_BK,
+	UAPSD_VI,
+	UAPSD_VO
+};
+
+QDF_STATUS wma_disable_uapsd_per_ac(tp_wma_handle wma_handle,
+				    uint32_t vdev_id, enum uapsd_ac ac);
+
+/**
+ * enum uapsd_up - U-APSD User Priorities
+ * @UAPSD_UP_BE: best effort
+ * @UAPSD_UP_BK: back ground
+ * @UAPSD_UP_RESV: reserve
+ * @UAPSD_UP_EE: Excellent Effort
+ * @UAPSD_UP_CL: Critical Applications
+ * @UAPSD_UP_VI: video
+ * @UAPSD_UP_VO: voice
+ * @UAPSD_UP_NC: Network Control
+ */
+enum uapsd_up {
+	UAPSD_UP_BE,
+	UAPSD_UP_BK,
+	UAPSD_UP_RESV,
+	UAPSD_UP_EE,
+	UAPSD_UP_CL,
+	UAPSD_UP_VI,
+	UAPSD_UP_VO,
+	UAPSD_UP_NC,
+	UAPSD_UP_MAX
+};
+
+/**
+ * struct wma_roam_invoke_cmd - roam invoke command
+ * @vdev_id: vdev id
+ * @bssid: mac address
+ * @channel: channel
+ * @frame_len: frame length, includs mac header, fixed params and ies
+ * @frame_buf: buffer contaning probe response or beacon
+ * @is_same_bssid: flag to indicate if roaming is requested for same bssid
+ */
+struct wma_roam_invoke_cmd {
+	uint32_t vdev_id;
+	uint8_t bssid[IEEE80211_ADDR_LEN];
+	uint32_t channel;
+	uint32_t frame_len;
+	uint8_t *frame_buf;
+	uint8_t is_same_bssid;
+};
+
+/**
+ * struct wma_process_fw_event_params - fw event parameters
+ * @wmi_handle: wmi handle
+ * @evt_buf: event buffer
+ */
+typedef struct {
+	void *wmi_handle;
+	void *evt_buf;
+} wma_process_fw_event_params;
+
+int wma_process_fw_event_handler(void *ctx, void *ev, uint8_t rx_ctx);
+
+A_UINT32 e_csr_auth_type_to_rsn_authmode(eCsrAuthType authtype,
+					 eCsrEncryptionType encr);
+A_UINT32 e_csr_encryption_type_to_rsn_cipherset(eCsrEncryptionType encr);
+
+QDF_STATUS wma_trigger_uapsd_params(tp_wma_handle wma_handle, uint32_t vdev_id,
+				    tp_wma_trigger_uapsd_params
+				    trigger_uapsd_params);
+
+/* added to get average snr for both data and beacon */
+QDF_STATUS wma_send_snr_request(tp_wma_handle wma_handle, void *pGetRssiReq);
+
+
+QDF_STATUS wma_update_vdev_tbl(tp_wma_handle wma_handle, uint8_t vdev_id,
+			       void *tx_rx_vdev_handle,
+			       uint8_t *mac, uint32_t vdev_type, bool add_del);
+
+void wma_send_flush_logs_to_fw(tp_wma_handle wma_handle);
+void wma_log_completion_timeout(void *data);
+
+#ifdef FEATURE_RSSI_MONITOR
+QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma,
+				   struct rssi_monitor_req *req);
+#else /* FEATURE_RSSI_MONITOR */
+static inline
+QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma,
+				   struct rssi_monitor_req *req)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_RSSI_MONITOR */
+
+QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle,
+				     struct set_pcl_req *msg);
+
+QDF_STATUS wma_send_pdev_set_hw_mode_cmd(tp_wma_handle wma_handle,
+		struct policy_mgr_hw_mode *msg);
+
+QDF_STATUS wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle,
+		struct policy_mgr_dual_mac_config *msg);
+QDF_STATUS wma_send_pdev_set_antenna_mode(tp_wma_handle wma_handle,
+		struct sir_antenna_mode_param *msg);
+
+struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma,
+					 uint8_t vdev_id,
+					 uint32_t msg_type, uint8_t type,
+					 void *params, uint32_t timeout);
+struct wma_target_req *wma_fill_hold_req(tp_wma_handle wma,
+				    uint8_t vdev_id, uint32_t msg_type,
+				    uint8_t type, void *params,
+				    uint32_t timeout);
+
+QDF_STATUS wma_vdev_start(tp_wma_handle wma,
+			  struct wma_vdev_start_req *req, bool isRestart);
+
+void wma_remove_vdev_req(tp_wma_handle wma, uint8_t vdev_id,
+				uint8_t type);
+
+int wma_mgmt_tx_completion_handler(void *handle, uint8_t *cmpl_event_params,
+				   uint32_t len);
+int wma_mgmt_tx_bundle_completion_handler(void *handle,
+	uint8_t *cmpl_event_params, uint32_t len);
+uint32_t wma_get_vht_ch_width(void);
+QDF_STATUS
+wma_config_debug_module_cmd(wmi_unified_t wmi_handle, A_UINT32 param,
+		A_UINT32 val, A_UINT32 *module_id_bitmap,
+		A_UINT32 bitmap_len);
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+QDF_STATUS wma_set_gateway_params(tp_wma_handle wma,
+					struct gateway_param_update_req *req);
+#else
+static inline QDF_STATUS wma_set_gateway_params(tp_wma_handle wma,
+					struct gateway_param_update_req *req)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+
+QDF_STATUS wma_lro_config_cmd(void *handle,
+	 struct cdp_lro_hash_config *wma_lro_cmd);
+
+void
+wma_indicate_err(enum ol_rx_err_type err_type,
+	 struct ol_error_info *err_info);
+
+/**
+ * wma_rx_mic_error_ind() - indicate mic error to the protocol stack
+ * @scn_handle: pdev handle from osif layer
+ * @vdev_id: vdev id
+ * @wh: pointer to ieee80211_frame structure
+ *
+ * This function indicates TKIP MIC errors encountered in the RX data path
+ * to the protocol stack
+ *
+ * Return: none
+ */
+void wma_rx_mic_error_ind(void *scn_handle, uint16_t vdev_id, void *wh);
+
+QDF_STATUS wma_ht40_stop_obss_scan(tp_wma_handle wma_handle,
+				int32_t vdev_id);
+
+void wma_process_fw_test_cmd(WMA_HANDLE handle,
+				      struct set_fwtest_params *wma_fwtest);
+
+QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma,
+	struct obss_ht40_scanind *req);
+
+uint32_t wma_get_num_of_setbits_from_bitmask(uint32_t mask);
+
+#ifdef FEATURE_WLAN_APF
+/**
+ *  wma_get_apf_caps_event_handler() - Event handler for get apf capability
+ *  @handle: WMA global handle
+ *  @cmd_param_info: command event data
+ *  @len: Length of @cmd_param_info
+ *
+ *  Return: 0 on Success or Errno on failure
+ */
+int wma_get_apf_caps_event_handler(void *handle,
+				   u_int8_t *cmd_param_info,
+				   u_int32_t len);
+
+/**
+ * wma_get_apf_capabilities - Send get apf capability to firmware
+ * @wma_handle: wma handle
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS wma_get_apf_capabilities(tp_wma_handle wma);
+
+/**
+ *  wma_set_apf_instructions - Set apf instructions to firmware
+ *  @wma: wma handle
+ *  @apf_set_offload: APF offload information to set to firmware
+ *
+ *  Return: QDF_STATUS enumeration
+ */
+QDF_STATUS
+wma_set_apf_instructions(tp_wma_handle wma,
+			 struct sir_apf_set_offload *apf_set_offload);
+
+/**
+ * wma_send_apf_enable_cmd - Send apf enable/disable cmd
+ * @wma_handle: wma handle
+ * @vdev_id: vdev id
+ * @apf_enable: true: Enable APF Int., false: Disable APF Int.
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS wma_send_apf_enable_cmd(WMA_HANDLE handle, uint8_t vdev_id,
+				   bool apf_enable);
+
+/**
+ * wma_send_apf_write_work_memory_cmd - Command to write into the apf work
+ * memory
+ * @wma_handle: wma handle
+ * @write_params: APF parameters for the write operation
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS
+wma_send_apf_write_work_memory_cmd(WMA_HANDLE handle,
+				   struct wmi_apf_write_memory_params
+								*write_params);
+
+/**
+ * wma_send_apf_read_work_memory_cmd - Command to get part of apf work memory
+ * @wma_handle: wma handle
+ * @callback: HDD callback to receive apf get mem event
+ * @context: Context for the HDD callback
+ * @read_params: APF parameters for the get operation
+ *
+ * Return: QDF_STATUS enumeration.
+ */
+QDF_STATUS
+wma_send_apf_read_work_memory_cmd(WMA_HANDLE handle,
+				  struct wmi_apf_read_memory_params
+								*read_params);
+
+/**
+ * wma_apf_read_work_memory_event_handler - Event handler for get apf mem
+ * operation
+ * @handle: wma handle
+ * @evt_buf: Buffer pointer to the event
+ * @len: Length of the event buffer
+ *
+ * Return: status.
+ */
+int wma_apf_read_work_memory_event_handler(void *handle, uint8_t *evt_buf,
+					   uint32_t len);
+#else /* FEATURE_WLAN_APF */
+static inline QDF_STATUS wma_get_apf_capabilities(tp_wma_handle wma)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+wma_set_apf_instructions(tp_wma_handle wma,
+			 struct sir_apf_set_offload *apf_set_offload)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_APF */
+
+void wma_process_set_pdev_ie_req(tp_wma_handle wma,
+		struct set_ie_param *ie_params);
+void wma_process_set_pdev_ht_ie_req(tp_wma_handle wma,
+		struct set_ie_param *ie_params);
+void wma_process_set_pdev_vht_ie_req(tp_wma_handle wma,
+		struct set_ie_param *ie_params);
+
+QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *bssid,
+			   uint8_t vdev_id, void *peer,
+			   bool roam_synch_in_progress);
+
+QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev,
+			    struct cdp_vdev *vdev, uint8_t peer_addr[6],
+			   u_int32_t peer_type, u_int8_t vdev_id,
+			   bool roam_synch_in_progress);
+
+/**
+ * wma_get_cca_stats() - send request to fw to get CCA
+ * @wmi_hdl: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_get_cca_stats(tp_wma_handle wma_handle,
+				uint8_t vdev_id);
+
+struct wma_ini_config *wma_get_ini_handle(tp_wma_handle wma_handle);
+WLAN_PHY_MODE wma_chan_phy_mode(uint8_t chan, enum phy_ch_width chan_width,
+				uint8_t dot11_mode);
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+QDF_STATUS wma_start_oem_data_req(tp_wma_handle wma_handle,
+				  struct oem_data_req *oem_req);
+#endif
+
+QDF_STATUS wma_enable_disable_caevent_ind(tp_wma_handle wma_handle,
+				uint8_t val);
+void wma_register_packetdump_callback(
+		tp_wma_packetdump_cb wma_mgmt_tx_packetdump_cb,
+		tp_wma_packetdump_cb wma_mgmt_rx_packetdump_cb);
+void wma_deregister_packetdump_callback(void);
+void wma_update_sta_inactivity_timeout(tp_wma_handle wma,
+		struct sme_sta_inactivity_timeout  *sta_inactivity_timer);
+
+/**
+ * wma_form_rx_packet() - form rx cds packet
+ * @buf: buffer
+ * @mgmt_rx_params: mgmt rx params
+ * @rx_pkt: cds packet
+ *
+ * This functions forms a cds packet from the rx mgmt frame received.
+ *
+ * Return: 0 for success or error code
+ */
+int wma_form_rx_packet(qdf_nbuf_t buf,
+			struct mgmt_rx_event_params *mgmt_rx_params,
+			cds_pkt_t *rx_pkt);
+
+/**
+ * wma_mgmt_unified_cmd_send() - send the mgmt tx packet
+ * @vdev: objmgr vdev
+ * @buf: buffer
+ * @desc_id: desc id
+ * @mgmt_tx_params: mgmt rx params
+ *
+ * This functions sends mgmt tx packet to WMI layer.
+ *
+ * Return: 0 for success or error code
+ */
+QDF_STATUS wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev *vdev,
+				qdf_nbuf_t buf, uint32_t desc_id,
+				void *mgmt_tx_params);
+
+/**
+ * wma_mgmt_nbuf_unmap_cb() - dma unmap for pending mgmt pkts
+ * @pdev: objmgr pdev
+ * @buf: buffer
+ *
+ * This function does the dma unmap of the pending mgmt packet cleanup
+ *
+ * Return: None
+ */
+void wma_mgmt_nbuf_unmap_cb(struct wlan_objmgr_pdev *pdev,
+			    qdf_nbuf_t buf);
+
+/**
+ * wma_chan_info_event_handler() - chan info event handler
+ * @handle: wma handle
+ * @event_buf: event handler data
+ * @len: length of @event_buf
+ *
+ * this function will handle the WMI_CHAN_INFO_EVENTID
+ *
+ * Return: int
+ */
+int wma_chan_info_event_handler(void *handle, uint8_t *event_buf,
+						uint32_t len);
+
+#ifndef CONFIG_VDEV_SM
+/**
+ * wma_vdev_set_mlme_state() - Set vdev mlme state
+ * @wma: wma handle
+ * @vdev_id: the Id of the vdev to configure
+ * @state: vdev state
+ *
+ * Return: None
+ */
+static inline
+void wma_vdev_set_mlme_state(tp_wma_handle wma, uint8_t vdev_id,
+		enum wlan_vdev_state state)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc, vdev_id,
+			WLAN_LEGACY_WMA_ID);
+	if (vdev) {
+		wlan_vdev_obj_lock(vdev);
+		wlan_vdev_mlme_set_state(vdev, state);
+		wlan_vdev_obj_unlock(vdev);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+	}
+}
+#endif
+/**
+ * wma_update_vdev_pause_bitmap() - update vdev pause bitmap
+ * @vdev_id: the Id of the vdev to configure
+ * @value: value pause bitmap value
+ *
+ * Return: None
+ */
+static inline
+void wma_vdev_update_pause_bitmap(uint8_t vdev_id, uint16_t value)
+{
+	tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_txrx_node *iface;
+
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return;
+	}
+
+	if (vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: Invalid vdev_id: %d", __func__, vdev_id);
+		return;
+	}
+
+	iface = &wma->interfaces[vdev_id];
+
+	if (!iface) {
+		WMA_LOGE("%s: Failed to get iface: NULL",
+			 __func__);
+		return;
+	}
+
+	if (!iface->handle) {
+		WMA_LOGE("%s: Failed to get iface handle: NULL",
+			 __func__);
+		return;
+	}
+
+	iface->pause_bitmap = value;
+}
+
+/**
+ * wma_vdev_get_pause_bitmap() - Get vdev pause bitmap
+ * @vdev_id: the Id of the vdev to configure
+ *
+ * Return: Vdev pause bitmap value else 0 on error
+ */
+static inline
+uint16_t wma_vdev_get_pause_bitmap(uint8_t vdev_id)
+{
+	tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_txrx_node *iface;
+
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return 0;
+	}
+
+	iface = &wma->interfaces[vdev_id];
+
+	if (!iface) {
+		WMA_LOGE("%s: Failed to get iface: NULL",
+			 __func__);
+		return 0;
+	}
+
+	if (!iface->handle) {
+		WMA_LOGE("%s: Failed to get iface handle: NULL",
+			 __func__);
+		return 0;
+	}
+
+	return iface->pause_bitmap;
+}
+
+/**
+ * wma_vdev_get_dp_handle() - Get vdev datapth handle
+ * @vdev_id: the Id of the vdev to configure
+ *
+ * Return: Vdev datapath handle else NULL on error
+ */
+static inline
+struct cdp_vdev *wma_vdev_get_vdev_dp_handle(uint8_t vdev_id)
+{
+	tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_txrx_node *iface;
+
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return NULL;
+	}
+
+	if (vdev_id >= wma->max_bssid)
+		return NULL;
+
+	iface = &wma->interfaces[vdev_id];
+
+	if (!iface) {
+		WMA_LOGE("%s: Failed to get iface: NULL",
+			 __func__);
+		return NULL;
+	}
+
+	return iface->handle;
+}
+
+/**
+ * wma_vdev_is_device_in_low_pwr_mode - is device in power save mode
+ * @vdev_id: the Id of the vdev to configure
+ *
+ * Return: true if device is in low power mode else false
+ */
+static inline bool wma_vdev_is_device_in_low_pwr_mode(uint8_t vdev_id)
+{
+	tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_txrx_node *iface;
+
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return 0;
+	}
+
+	iface = &wma->interfaces[vdev_id];
+
+	if (!iface) {
+		WMA_LOGE("%s: Failed to get iface: NULL",
+			 __func__);
+		return 0;
+	}
+
+	if (!iface->handle) {
+		WMA_LOGE("%s: Failed to get iface handle:NULL",
+			 __func__);
+		return 0;
+	}
+
+	return iface->in_bmps || wma->in_imps;
+}
+
+/**
+ * wma_vdev_get_cfg_int - Get cfg integer value
+ * @cfg_id: cfg item number
+ * @value: fill the out value
+ *
+ * Note caller must verify return status before using value
+ *
+ * Return: QDF_STATUS_SUCCESS when got item from cfg else QDF_STATUS_E_FAILURE
+ */
+static inline
+QDF_STATUS wma_vdev_get_cfg_int(int cfg_id, int *value)
+{
+	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	*value = 0;
+
+	if (!mac)
+		return QDF_STATUS_E_FAILURE;
+
+	return wlan_cfg_get_int(mac, cfg_id, value);
+}
+
+/**
+ * wma_vdev_get_dtim_period - Get dtim period value from mlme
+ * @vdev_id: vdev index number
+ * @value: pointer to the value to fill out
+ *
+ * Note caller must verify return status before using value
+ *
+ * Return: QDF_STATUS_SUCCESS when fetched a valid value from cfg else
+ * QDF_STATUS_E_FAILURE
+ */
+static inline
+QDF_STATUS wma_vdev_get_dtim_period(uint8_t vdev_id, uint8_t *value)
+{
+	tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_txrx_node *iface;
+	/* set value to zero */
+	*value = 0;
+
+	if (!wma)
+		return QDF_STATUS_E_FAILURE;
+
+	iface = &wma->interfaces[vdev_id];
+
+	if (!iface || !iface->handle)
+		return QDF_STATUS_E_FAILURE;
+
+	*value = iface->dtimPeriod;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_vdev_get_beacon_interval - Get beacon interval from mlme
+ * @vdev_id: vdev index number
+ * @value: pointer to the value to fill out
+ *
+ * Note caller must verify return status before using value
+ *
+ * Return: QDF_STATUS_SUCCESS when fetched a valid value from cfg else
+ * QDF_STATUS_E_FAILURE
+ */
+static inline
+QDF_STATUS wma_vdev_get_beacon_interval(uint8_t  vdev_id, uint16_t *value)
+{
+	tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_txrx_node *iface;
+	/* set value to zero */
+	*value = 0;
+
+	if (!wma)
+		return QDF_STATUS_E_FAILURE;
+
+	iface = &wma->interfaces[vdev_id];
+
+	if (!iface || !iface->handle)
+		return QDF_STATUS_E_FAILURE;
+
+	*value = iface->beaconInterval;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_vdev_set_pause_bit() - Set a bit in vdev pause bitmap
+ * @vdev_id: the Id of the vdev to configure
+ * @bit_pos: set bit position in pause bitmap
+ *
+ * Return: None
+ */
+static inline
+void wma_vdev_set_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos)
+{
+	tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_txrx_node *iface;
+
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return;
+	}
+
+	iface = &wma->interfaces[vdev_id];
+
+	if (!iface) {
+		WMA_LOGE("%s: Failed to get iface: NULL",
+			 __func__);
+		return;
+	}
+
+	if (!iface->handle) {
+		WMA_LOGE("%s: Failed to get iface handle: NULL",
+			 __func__);
+		return;
+	}
+
+	iface->pause_bitmap |= (1 << bit_pos);
+}
+
+/**
+ * wma_vdev_clear_pause_bit() - Clear a bit from vdev pause bitmap
+ * @vdev_id: the Id of the vdev to configure
+ * @bit_pos: set bit position in pause bitmap
+ *
+ * Return: None
+ */
+static inline
+void wma_vdev_clear_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos)
+{
+	tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_txrx_node *iface;
+
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return;
+	}
+
+	iface = &wma->interfaces[vdev_id];
+
+	if (!iface) {
+		WMA_LOGE("%s: Failed to get iface: NULL",
+			 __func__);
+		return;
+	}
+
+	if (!iface->handle) {
+		WMA_LOGE("%s: Failed to get iface handle: NULL",
+			 __func__);
+		return;
+	}
+
+	iface->pause_bitmap &= ~(1 << bit_pos);
+}
+
+/**
+ * wma_process_roaming_config() - process roam request
+ * @wma_handle: wma handle
+ * @roam_req: roam request parameters
+ *
+ * Main routine to handle ROAM commands coming from CSR module.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle,
+				     tSirRoamOffloadScanReq *roam_req);
+
+#ifdef WMI_INTERFACE_EVENT_LOGGING
+static inline void wma_print_wmi_cmd_log(uint32_t count,
+					 qdf_abstract_print *print,
+					 void *print_priv)
+{
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (wma) {
+		print(print_priv, "Command Log (count %u)", count);
+		wmi_print_cmd_log(wma->wmi_handle, count, print, print_priv);
+	}
+}
+
+static inline void wma_print_wmi_cmd_tx_cmp_log(uint32_t count,
+						qdf_abstract_print *print,
+						void *print_priv)
+{
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (wma) {
+		print(print_priv, "Command Tx Complete Log (count %u)", count);
+		wmi_print_cmd_tx_cmp_log(wma->wmi_handle, count, print,
+					 print_priv);
+	}
+}
+
+static inline void wma_print_wmi_mgmt_cmd_log(uint32_t count,
+					      qdf_abstract_print *print,
+					      void *print_priv)
+{
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (wma) {
+		print(print_priv, "Management Command Log (count %u)", count);
+		wmi_print_mgmt_cmd_log(wma->wmi_handle, count, print,
+				       print_priv);
+	}
+}
+
+static inline void wma_print_wmi_mgmt_cmd_tx_cmp_log(uint32_t count,
+						     qdf_abstract_print *print,
+						     void *print_priv)
+{
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (wma) {
+		print(print_priv,
+		"Management Command Tx Complete Log (count %u)", count);
+		wmi_print_mgmt_cmd_tx_cmp_log(wma->wmi_handle, count, print,
+					      print_priv);
+	}
+}
+
+static inline void wma_print_wmi_event_log(uint32_t count,
+					   qdf_abstract_print *print,
+					   void *print_priv)
+{
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (wma) {
+		print(print_priv, "Event Log (count %u)", count);
+		wmi_print_event_log(wma->wmi_handle, count, print, print_priv);
+	}
+}
+
+static inline void wma_print_wmi_rx_event_log(uint32_t count,
+					      qdf_abstract_print *print,
+					      void *print_priv)
+{
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (wma) {
+		print(print_priv, "Rx Event Log (count %u)", count);
+		wmi_print_rx_event_log(wma->wmi_handle, count, print,
+				       print_priv);
+	}
+}
+
+static inline void wma_print_wmi_mgmt_event_log(uint32_t count,
+						qdf_abstract_print *print,
+						void *print_priv)
+{
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (wma) {
+		print(print_priv, "Management Event Log (count %u)", count);
+		wmi_print_mgmt_event_log(wma->wmi_handle, count, print,
+					 print_priv);
+	}
+}
+#else
+
+static inline void wma_print_wmi_cmd_log(uint32_t count,
+					 qdf_abstract_print *print,
+					 void *print_priv)
+{
+}
+
+static inline void wma_print_wmi_cmd_tx_cmp_log(uint32_t count,
+						qdf_abstract_print *print,
+						void *print_priv)
+{
+}
+
+static inline void wma_print_wmi_mgmt_cmd_log(uint32_t count,
+					      qdf_abstract_print *print,
+					      void *print_priv)
+{
+}
+
+static inline void wma_print_wmi_mgmt_cmd_tx_cmp_log(uint32_t count,
+						     qdf_abstract_print *print,
+						     void *print_priv)
+{
+}
+
+static inline void wma_print_wmi_event_log(uint32_t count,
+					   qdf_abstract_print *print,
+					   void *print_priv)
+{
+}
+
+static inline void wma_print_wmi_rx_event_log(uint32_t count,
+					      qdf_abstract_print *print,
+					      void *print_priv)
+{
+}
+
+static inline void wma_print_wmi_mgmt_event_log(uint32_t count,
+						qdf_abstract_print *print,
+						void *print_priv)
+{
+}
+#endif /* WMI_INTERFACE_EVENT_LOGGING */
+
+/**
+ * wma_ipa_uc_stat_request() - set ipa config parameters
+ * @privcmd: private command
+ *
+ * Return: None
+ */
+void wma_ipa_uc_stat_request(wma_cli_set_cmd_t *privcmd);
+
+/**
+ * wma_set_rx_reorder_timeout_val() - set rx recorder timeout value
+ * @wma_handle: pointer to wma handle
+ * @reorder_timeout: rx reorder timeout value
+ *
+ * Return: VOS_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_set_rx_reorder_timeout_val(tp_wma_handle wma_handle,
+	struct sir_set_rx_reorder_timeout_val *reorder_timeout);
+
+/**
+ * wma_set_rx_blocksize() - set rx blocksize
+ * @wma_handle: pointer to wma handle
+ * @peer_rx_blocksize: rx blocksize for peer mac
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_set_rx_blocksize(tp_wma_handle wma_handle,
+	struct sir_peer_set_rx_blocksize *peer_rx_blocksize);
+/**
+ * wma_configure_smps_params() - Configures the smps parameters to set
+ * @vdev_id: Virtual device for the command
+ * @param_id: SMPS parameter ID
+ * @param_val: Value to be set for the parameter
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS wma_configure_smps_params(uint32_t vdev_id, uint32_t param_id,
+							uint32_t param_val);
+
+/*
+ * wma_chip_power_save_failure_detected_handler() - chip pwr save fail detected
+ * event handler
+ * @handle: wma handle
+ * @cmd_param_info: event handler data
+ * @len: length of @cmd_param_info
+ *
+ * Return: QDF_STATUS_SUCCESS on success; error code otherwise
+ */
+int wma_chip_power_save_failure_detected_handler(void *handle,
+						 uint8_t *cmd_param_info,
+						 uint32_t len);
+
+/**
+ * wma_get_chain_rssi() - send wmi cmd to get chain rssi
+ * @wma_handle: wma handler
+ * @req_params: requset params
+ *
+ * Return: Return QDF_STATUS
+ */
+QDF_STATUS wma_get_chain_rssi(tp_wma_handle wma_handle,
+		struct get_chain_rssi_req_params *req_params);
+
+/**
+ * wma_config_bmiss_bcnt_params() - set bmiss config parameters
+ * @vdev_id: virtual device for the command
+ * @first_cnt: bmiss first value
+ * @final_cnt: bmiss final value
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS wma_config_bmiss_bcnt_params(uint32_t vdev_id, uint32_t first_cnt,
+		uint32_t final_cnt);
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+/**
+ * wma_check_and_set_wake_timer(): checks all interfaces and if any interface
+ * has install_key pending, sets timer pattern in fw to wake up host after
+ * specified time has elapsed.
+ * @time: time after which host wants to be awaken.
+ *
+ * Return: None
+ */
+void wma_check_and_set_wake_timer(uint32_t time);
+#endif
+
+/**
+ * wma_rx_invalid_peer_ind(): the callback for DP to notify WMA layer
+ * invalid peer data is received, this function will send message to
+ * lim module.
+ * @vdev_id: virtual device ID
+ * @wh: Pointer to 802.11 frame header
+ *
+ * Return: 0 for success or non-zero on failure
+ */
+uint8_t wma_rx_invalid_peer_ind(uint8_t vdev_id, void *wh);
+
+#endif
diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h
new file mode 100644
index 0000000..c5c710d
--- /dev/null
+++ b/core/wma/inc/wma_api.h
@@ -0,0 +1,554 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef WMA_API_H
+#define WMA_API_H
+
+#include "osdep.h"
+#include "ani_global.h"
+#include "a_types.h"
+#include "osapi_linux.h"
+#include "wmi_unified.h"
+#ifdef NOT_YET
+#include "htc_api.h"
+#endif
+#include "lim_global.h"
+#include "cds_utils.h"
+#include "scheduler_api.h"
+#include "wlan_policy_mgr_api.h"
+#include "wma_sar_public_structs.h"
+#include <cdp_txrx_ops.h>
+#include "include/wlan_vdev_mlme.h"
+#include "wlan_mlme_vdev_mgr_interface.h"
+
+typedef void *WMA_HANDLE;
+
+/**
+ * enum GEN_PARAM - general parameters
+ * @GEN_VDEV_PARAM_AMPDU: Set ampdu size
+ * @GEN_VDEV_PARAM_AMSDU: Set amsdu size
+ * @GEN_PARAM_CRASH_INJECT: inject crash
+ * @GEN_PARAM_MODULATED_DTIM: moduled dtim
+ * @GEN_PARAM_CAPTURE_TSF: read tsf
+ * @GEN_PARAM_RESET_TSF_GPIO: reset tsf gpio
+ * @GEN_VDEV_ROAM_SYNCH_DELAY: roam sync delay
+ * @GEN_PARAM_LISTEN_INTERVAL: listen interval
+ */
+enum GEN_PARAM {
+	GEN_VDEV_PARAM_AMPDU = 0x1,
+	GEN_VDEV_PARAM_AMSDU,
+	GEN_PARAM_CRASH_INJECT,
+	GEN_PARAM_MODULATED_DTIM,
+	GEN_PARAM_CAPTURE_TSF,
+	GEN_PARAM_RESET_TSF_GPIO,
+	GEN_VDEV_ROAM_SYNCH_DELAY,
+	GEN_PARAM_LISTEN_INTERVAL,
+};
+
+/**
+ * struct wma_caps_per_phy - various caps per phy
+ * @ht_2g: entire HT cap for 2G band in terms of 32 bit flag
+ * @ht_5g: entire HT cap for 5G band in terms of 32 bit flag
+ * @vht_2g: entire VHT cap for 2G band in terms of 32 bit flag
+ * @vht_5g: entire VHT cap for 5G band in terms of 32 bit flag
+ * @he_2g: entire HE cap for 2G band in terms of 32 bit flag
+ * @he_5g: entire HE cap for 5G band in terms of 32 bit flag
+ * @tx_chain_mask_2G: tx chain mask for 2g
+ * @rx_chain_mask_2G: rx chain mask for 2g
+ * @tx_chain_mask_5G: tx chain mask for 5g
+ * @rx_chain_mask_5G: rx chain mask for 5g
+ */
+struct wma_caps_per_phy {
+	uint32_t ht_2g;
+	uint32_t ht_5g;
+	uint32_t vht_2g;
+	uint32_t vht_5g;
+	uint32_t he_2g[PSOC_HOST_MAX_MAC_SIZE];
+	uint32_t he_5g[PSOC_HOST_MAX_MAC_SIZE];
+	uint32_t tx_chain_mask_2G;
+	uint32_t rx_chain_mask_2G;
+	uint32_t tx_chain_mask_5G;
+	uint32_t rx_chain_mask_5G;
+};
+
+
+#define VDEV_CMD 1
+#define PDEV_CMD 2
+#define GEN_CMD  3
+#define DBG_CMD  4
+#define PPS_CMD  5
+#define QPOWER_CMD 6
+#define GTX_CMD  7
+
+typedef void (*wma_peer_authorized_fp) (uint32_t vdev_id);
+
+
+QDF_STATUS wma_pre_start(void);
+
+QDF_STATUS wma_mc_process_handler(struct scheduler_msg *msg);
+
+QDF_STATUS wma_start(void);
+
+/**
+ * wma_stop() - wma stop function.
+ *
+ * Performs all of the operations required to stop the WMA layer
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF Error on failure
+ */
+QDF_STATUS wma_stop(void);
+
+QDF_STATUS wma_close(void);
+
+QDF_STATUS wma_wmi_service_close(void);
+
+QDF_STATUS wma_wmi_work_close(void);
+
+int wma_rx_ready_event(void *handle, uint8_t *ev, uint32_t len);
+
+int  wma_rx_service_ready_event(void *handle, uint8_t *ev, uint32_t len);
+
+int wma_rx_service_ready_ext_event(void *handle, uint8_t *ev, uint32_t len);
+
+void wma_setneedshutdown(void);
+
+bool wma_needshutdown(void);
+
+QDF_STATUS wma_wait_for_ready_event(WMA_HANDLE handle);
+
+uint8_t wma_map_channel(uint8_t mapChannel);
+
+int wma_cli_get_command(int vdev_id, int param_id, int vpdev);
+int wma_cli_set_command(int vdev_id, int param_id, int sval, int vpdev);
+int wma_cli_set2_command(int vdev_id, int param_id, int sval1,
+			 int sval2, int vpdev);
+
+QDF_STATUS wma_set_htconfig(uint8_t vdev_id, uint16_t ht_capab, int value);
+
+/**
+ * wma_get_wcnss_software_version() - get wcnss software version
+ * @version: version pointer
+ * @version_buffer_size: buffer size
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_get_wcnss_software_version(uint8_t *version,
+					  uint32_t version_buffer_size);
+
+void wma_set_peer_authorized_cb(void *wma_ctx, wma_peer_authorized_fp auth_cb);
+QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr,
+		  uint32_t param_id,
+		  uint32_t param_value, uint32_t vdev_id);
+QDF_STATUS wma_get_link_speed(WMA_HANDLE handle, tSirLinkSpeedInfo *pLinkSpeed);
+#ifdef NOT_YET
+QDF_STATUS wma_update_channel_list(WMA_HANDLE handle, void *scan_chan_info);
+#endif
+
+uint8_t *wma_get_vdev_address_by_vdev_id(uint8_t vdev_id);
+struct wma_txrx_node *wma_get_interface_by_vdev_id(uint8_t vdev_id);
+QDF_STATUS wma_get_connection_info(uint8_t vdev_id,
+		struct policy_mgr_vdev_entry_info *conn_table_entry);
+
+bool wma_is_vdev_up(uint8_t vdev_id);
+
+void *wma_get_beacon_buffer_by_vdev_id(uint8_t vdev_id, uint32_t *buffer_size);
+
+bool wma_get_fw_wlan_feat_caps(enum cap_bitmap feature);
+void wma_set_fw_wlan_feat_caps(enum cap_bitmap feature);
+
+QDF_STATUS wma_post_ctrl_msg(tpAniSirGlobal pMac, struct scheduler_msg *pMsg);
+
+void wma_register_wow_wakeup_events(WMA_HANDLE handle, uint8_t vdev_id,
+					uint8_t vdev_type, uint8_t sub_type);
+void wma_register_wow_default_patterns(WMA_HANDLE handle, uint8_t vdev_id);
+int8_t wma_get_mac_id_of_vdev(uint32_t vdev_id);
+void wma_update_intf_hw_mode_params(uint32_t vdev_id, uint32_t mac_id,
+				uint32_t cfgd_hw_mode_index);
+void wma_set_dbs_capability_ut(uint32_t dbs);
+QDF_STATUS wma_get_caps_for_phyidx_hwmode(struct wma_caps_per_phy *caps_per_phy,
+		enum hw_mode_dbs_capab hw_mode, enum cds_band_type band);
+bool wma_is_rx_ldpc_supported_for_channel(uint32_t channel);
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+int wma_unified_radio_tx_mem_free(void *handle);
+#else /* WLAN_FEATURE_LINK_LAYER_STATS */
+static inline int wma_unified_radio_tx_mem_free(void *handle)
+{
+	return 0;
+}
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+/**
+ * wma_form_unit_test_cmd_and_send() - to form a wma command and send it to FW
+ * @session_id: wma session id to be filled while forming the command
+ * @module_id: module id given by user to be filled in the command
+ * @arg_count: number of argument count
+ * @arg: pointer to argument list
+ *
+ * This API exposed to HDD layer which takes the argument from user and forms
+ * the wma unit test command to be sent down to firmware
+ *
+ * Return: QDF_STATUS based on overall success
+ */
+QDF_STATUS wma_form_unit_test_cmd_and_send(uint32_t vdev_id,
+		uint32_t module_id, uint32_t arg_count, uint32_t *arg);
+
+/**
+ * wma_lro_init() - sends LRO configuration to FW
+ * @lro_config:         pointer to the config parameters
+ *
+ * This function ends LRO configuration to FW.
+ *
+ * Return: 0 for success or reasons for failure
+ */
+int wma_lro_init(struct cdp_lro_hash_config *lro_config);
+
+QDF_STATUS wma_remove_beacon_filter(WMA_HANDLE wma,
+				struct beacon_filter_param *filter_params);
+
+QDF_STATUS wma_add_beacon_filter(WMA_HANDLE wma,
+				struct beacon_filter_param *filter_params);
+QDF_STATUS wma_send_adapt_dwelltime_params(WMA_HANDLE handle,
+			struct adaptive_dwelltime_params *dwelltime_params);
+
+/**
+ * wma_send_dbs_scan_selection_params() - send DBS scan selection configuration
+ * params to firmware
+ * @handle: wma handler
+ * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
+ */
+QDF_STATUS wma_send_dbs_scan_selection_params(WMA_HANDLE handle,
+			struct wmi_dbs_scan_sel_params *dbs_scan_params);
+QDF_STATUS wma_set_tx_power_scale(uint8_t vdev_id, int value);
+QDF_STATUS wma_set_tx_power_scale_decr_db(uint8_t vdev_id, int value);
+
+bool wma_is_csa_offload_enabled(void);
+#ifdef FEATURE_P2P_LISTEN_OFFLOAD
+bool wma_is_p2p_lo_capable(void);
+QDF_STATUS wma_p2p_lo_start(struct sir_p2p_lo_start *params);
+QDF_STATUS wma_p2p_lo_stop(u_int32_t vdev_id);
+#else
+static inline bool wma_is_p2p_lo_capable(void)
+{
+	return 0;
+}
+#endif
+bool wma_capability_enhanced_mcast_filter(void);
+#ifndef QCA_SUPPORT_CP_STATS
+QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *wake_lock_stats);
+#endif
+void wma_process_pdev_hw_mode_trans_ind(void *wma,
+	wmi_pdev_hw_mode_transition_event_fixed_param *fixed_param,
+	wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry,
+	struct sir_hw_mode_trans_ind *hw_mode_trans_ind);
+
+/**
+ * wma_set_cts2self_for_p2p_go() - set CTS2SELF command for P2P GO.
+ * @wma_handle:                  pointer to wma handle.
+ * @cts2self_for_p2p_go:         value needs to set to firmware.
+ *
+ * At the time of driver startup, inform about ini parma to FW that
+ * if legacy client connects to P2P GO, stop using NOA for P2P GO.
+ *
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS wma_set_cts2self_for_p2p_go(void *wma_handle,
+		uint32_t cts2self_for_p2p_go);
+QDF_STATUS wma_set_tx_rx_aggregation_size
+	(struct sir_set_tx_rx_aggregation_size *tx_rx_aggregation_size);
+
+/**
+ * wma_set_tx_rx_aggregation_size_per_ac() - set aggregation size per ac
+ * @tx_rx_aggregation_size: the parameter for aggregation size
+ *
+ *  This function try to set the aggregation size per AC.
+ *
+ *  Return: QDF_STATUS enumeration
+ */
+QDF_STATUS wma_set_tx_rx_aggregation_size_per_ac
+	(struct sir_set_tx_rx_aggregation_size *tx_rx_aggregation_size);
+/**
+ * wma_set_sw_retry_threshold() - set sw retry threshold per AC for tx
+ * @handle: wma handle
+ * @tx_sw_retry_threshold: value needs to set to firmware
+ *
+ * This function sends WMI command to set the sw retry threshold per AC
+ * for Tx.
+ *
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS wma_set_sw_retry_threshold
+	(WMA_HANDLE handle,
+	 struct sir_set_tx_sw_retry_threshold *tx_sw_retry_threshold);
+/**
+ * wma_get_sar_limit() - get SAR limits from the target
+ * @handle: wma handle
+ * @callback: Callback function to invoke with the results
+ * @context: Opaque context to pass back to caller in the callback
+ *
+ *  This function sends WMI command to get SAR limits.
+ *
+ *  Return: QDF_STATUS enumeration
+ */
+QDF_STATUS wma_get_sar_limit(WMA_HANDLE handle,
+			     wma_sar_cb callback, void *context);
+
+/**
+ * wma_set_sar_limit() - set sar limits in the target
+ * @handle: wma handle
+ * @sar_limit_cmd_params: sar limit cmd params
+ *
+ *  This function sends WMI command to set SAR limits.
+ *
+ *  Return: QDF_STATUS enumeration
+ */
+QDF_STATUS wma_set_sar_limit(WMA_HANDLE handle,
+		struct sar_limit_cmd_params *sar_limit_params);
+
+/**
+ * wma_send_coex_config_cmd() - Send coex config params
+ * @wma_handle: wma handle
+ * @coex_cfg_params: struct to coex cofig params
+ *
+ * This function sends WMI command to send coex cofig params
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_send_coex_config_cmd(WMA_HANDLE wma_handle,
+				    struct coex_config_params *coex_cfg_params);
+
+/**
+ * wma_set_qpower_config() - update qpower config in wma
+ * @vdev_id:	the Id of the vdev to configure
+ * @qpower:	new qpower value
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error number otherwise
+ */
+QDF_STATUS wma_set_qpower_config(uint8_t vdev_id, uint8_t qpower);
+
+#ifdef FEATURE_WLAN_D0WOW
+static inline bool wma_d0_wow_is_supported(void)
+{
+	return true;
+}
+#else
+static inline bool wma_d0_wow_is_supported(void)
+{
+	return false;
+}
+#endif
+
+/**
+ * wma_store_pdev() - store pdev
+ * @wma_ctx:	wma context
+ * @pdev:	pdev context
+ *
+ * Return: void
+ */
+void wma_store_pdev(void *wma_ctx, struct wlan_objmgr_pdev *pdev);
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+/**
+ * wmi_to_sir_peer_type() - convert peer type from WMI to SIR enum
+ * @type: enum wmi_peer_type
+ *
+ * Return: tSirWifiPeerType
+ */
+tSirWifiPeerType wmi_to_sir_peer_type(enum wmi_peer_type type);
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+QDF_STATUS wma_crash_inject(WMA_HANDLE wma_handle, uint32_t type,
+			    uint32_t delay_time_ms);
+
+/**
+ * wma_critical_events_in_flight() - get the number of critical events in flight
+ *
+ * This API gets the number of events in flight which should prevent power
+ * collapse.
+ *
+ * Return: the number of critical events in flight
+ */
+uint32_t wma_critical_events_in_flight(void);
+
+#ifdef FEATURE_WLAN_DYNAMIC_CVM
+/**
+ * wma_set_vc_mode_config() - set voltage corner mode config to FW.
+ * @wma_handle:	pointer to wma handle.
+ * @vc_bitmap:	value needs to set to firmware.
+ *
+ * At the time of driver startup, set operating voltage corner mode
+ * for differenet phymode and bw configurations.
+ *
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS wma_set_vc_mode_config(void *wma_handle,
+		uint32_t vc_bitmap);
+#endif
+
+QDF_STATUS wma_process_dhcp_ind(WMA_HANDLE wma_handle,
+				tAniDHCPInd *ta_dhcp_ind);
+
+/**
+ * wma_wmi_stop() - send wmi stop cmd
+ *
+ *  Return: None
+ */
+void wma_wmi_stop(void);
+
+/**
+ * wma_get_mcs_idx() - get mcs index
+ * @max_rate: max rate
+ * @rate_flags: rate flags
+ * @nss: nss
+ * @mcs_rate_flag: mcs rate flags
+ *
+ *  Return: mcs index
+ */
+uint8_t wma_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
+			uint8_t *nss, uint8_t *mcs_rate_flag);
+
+/**
+ * wma_get_hidden_ssid_restart_in_progress() - check if hidden ssid restart is
+ * in progress
+ * @iface: iface pointer
+ *
+ * Return: true if hidden ssid restart is in progress else false
+ */
+bool wma_get_hidden_ssid_restart_in_progress(struct wma_txrx_node *iface);
+
+#ifdef CONFIG_VDEV_SM
+
+/**
+ * wma_sta_mlme_vdev_start_continue - VDEV start response handling
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes VDEV start response actions
+ *
+ * Return: SUCCESS on successful completion of start response operation
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS wma_sta_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme,
+					    uint16_t data_len, void *data);
+
+/**
+ * wma_ap_mlme_vdev_start_continue - VDEV start response handling
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes VDEV start response actions
+ *
+ * Return: SUCCESS on successful completion of start response operation
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS wma_ap_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme,
+					   uint16_t data_len, void *data);
+
+/**
+ * wma_sta_vdev_up_send - Send VDEV UP command
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes VDEV UP Command
+ *
+ * Return: SUCCESS on successful completion of start response operation
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS wma_sta_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
+				uint16_t data_len, void *data);
+
+/**
+ * wma_mlme_vdev_stop_continue - VDEV stop response handling
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes VDEV stop response actions
+ *
+ * Return: SUCCESS on successful completion of stop response operation
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS wma_mlme_vdev_stop_continue(struct vdev_mlme_obj *vdev_mlme,
+				       uint16_t data_len, void *data);
+
+/**
+ * wma_ap_mlme_vdev_down_send - VDEV down operation
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes VDEV down operation
+ *
+ * Return: SUCCESS on successful completion of VDEV down operation
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
+				      uint16_t data_len, void *data);
+
+/**
+ * wma_mlme_vdev_notify_down_complete - VDEV init state transition
+ * notification
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API notifies MLME on moving to INIT state
+ *
+ * Return: SUCCESS on successful completion of down notification
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS
+wma_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
+				   uint16_t data_len, void *data);
+
+/**
+ * wma_ap_mlme_vdev_stop_start_send - handle vdev stop during start req
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @type: restart req or start req
+ * @data_len: data size
+ * @data: event data
+ *
+ * API handle vdev stop during start req
+ *
+ * Return: SUCCESS alsways
+ */
+QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme,
+					    enum vdev_cmd_type type,
+					    uint16_t data_len, void *data);
+
+/**
+ * wma_sta_mlme_vdev_down_send - VDEV down operation
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes VDEV down operation
+ *
+ * Return: SUCCESS on successful completion of VDEV down operation
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS wma_sta_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
+				       uint16_t data_len, void *data);
+
+#endif
+#endif
diff --git a/core/wma/inc/wma_he.h b/core/wma/inc/wma_he.h
new file mode 100644
index 0000000..9f3d036
--- /dev/null
+++ b/core/wma/inc/wma_he.h
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2017-2018 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.
+ */
+
+#ifndef __WMA_HE_H
+#define __WMA_HE_H
+
+#include "wma.h"
+#include "sir_api.h"
+#include "target_if.h"
+
+#ifdef WLAN_FEATURE_11AX
+/**
+ * wma_print_he_cap() - Print HE capabilities
+ * @he_cap: pointer to HE Capability
+ *
+ * Received HE capabilities are converted into dot11f structure.
+ * This function will print all the HE capabilities as stored
+ * in the dot11f structure.
+ *
+ * Return: None
+ */
+void wma_print_he_cap(tDot11fIEhe_cap *he_cap);
+
+/**
+ * wma_print_he_ppet() - Prints HE PPE Threshold
+ * @he_ppet: PPE Threshold
+ *
+ * This function prints HE PPE Threshold as received from FW.
+ * Refer to the definition of wmi_ppe_threshold to understand
+ * how PPE thresholds are packed by FW for a given NSS and RU.
+ *
+ * Return: none
+ */
+void wma_print_he_ppet(void *ppet);
+
+/**
+ * wma_print_he_phy_cap() - Print HE PHY Capability
+ * @phy_cap: pointer to PHY Capability
+ *
+ * This function prints HE PHY Capability received from FW.
+ *
+ * Return: none
+ */
+void wma_print_he_phy_cap(uint32_t *phy_cap);
+
+/**
+ * wma_print_he_mac_cap_w1() - Print HE MAC Capability
+ * @mac_cap: MAC Capability
+ *
+ * This function prints HE MAC Capability received from FW.
+ *
+ * Return: none
+ */
+void wma_print_he_mac_cap_w1(uint32_t mac_cap);
+
+/**
+ * wma_print_he_mac_cap_w2() - Print HE MAC Capability
+ * @mac_cap: MAC Capability
+ *
+ * This function prints HE MAC Capability received from FW.
+ *
+ * Return: none
+ */
+void wma_print_he_mac_cap_w2(uint32_t mac_cap);
+
+/**
+ * wma_print_he_op() - Print HE Operation
+ * @he_cap: pointer to HE Operation
+ *
+ * Print HE operation stored as dot11f structure
+ *
+ * Return: None
+ */
+void wma_print_he_op(tDot11fIEhe_op *he_ops);
+
+/**
+ * wma_update_target_ext_he_cap() - Update HE caps with given extended cap
+ * @tgt_hdl: target psoc information
+ * @tgt_cfg: Target config
+ *
+ * This function loop through each hardware mode and for each hardware mode
+ * again it loop through each MAC/PHY and pull the caps 2G and 5G specific
+ * HE caps and derives the final cap.
+ *
+ * Return: None
+ */
+void wma_update_target_ext_he_cap(struct target_psoc_info *tgt_hdl,
+				  struct wma_tgt_cfg *tgt_cfg);
+
+/*
+ * wma_he_update_tgt_services() - update tgt cfg to indicate 11ax support
+ * @wmi_handle: pointer to WMI handle
+ * @cfg: pointer to WMA target services
+ *
+ * Based on WMI SERVICES information, enable 11ax support and set DOT11AX bit
+ * in feature caps bitmap.
+ *
+ * Return: None
+ */
+void wma_he_update_tgt_services(struct wmi_unified *wmi_handle,
+				struct wma_tgt_services *cfg);
+
+/**
+ * wma_populate_peer_he_cap() - populate peer HE capabilities in peer assoc cmd
+ * @peer: pointer to peer assoc params
+ * @params: pointer to ADD STA params
+ *
+ * Return: None
+ */
+void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
+			      tpAddStaParams params);
+
+/**
+ * wma_update_vdev_he_ops() - update he ops in vdev start request
+ * @req: pointer to vdev start request
+ * @add_bss: pointer to ADD BSS params
+ *
+ * Return: None
+ */
+void wma_update_vdev_he_ops(struct wma_vdev_start_req *req,
+		tpAddBssParams add_bss);
+
+/**
+ * wma_copy_txrxnode_he_ops() - copy HE ops from vdev start req to txrx node
+ * @node: pointer to txrx node
+ * @req: pointer to vdev start request
+ *
+ * Return: None
+ */
+void wma_copy_txrxnode_he_ops(struct wma_txrx_node *node,
+		struct wma_vdev_start_req *req);
+
+/**
+ * wma_copy_vdev_start_he_ops() - copy HE ops from vdev start req to vdev start
+ * @params: pointer to vdev_start_params
+ * @req: pointer to vdev start request
+ *
+ * Return: None
+ */
+void wma_copy_vdev_start_he_ops(struct vdev_start_params *params,
+		struct wma_vdev_start_req *req);
+
+/**
+ * wma_vdev_set_he_bss_params() - set HE OPs in vdev start
+ * @wma: pointer to wma handle
+ * @vdev_id: VDEV id
+ * @req: pointer to vdev start request
+ *
+ * Return: None
+ */
+void wma_vdev_set_he_bss_params(tp_wma_handle wma, uint8_t vdev_id,
+				struct wma_vdev_start_req *req);
+
+/**
+ * wma_vdev_set_he_config() - set HE Config in vdev start
+ * @wma: pointer to wma handle
+ * @vdev_id: VDEV id
+ * @add_bss: BSS params
+ *
+ * Return: None
+ */
+void wma_vdev_set_he_config(tp_wma_handle wma, uint8_t vdev_id,
+				tpAddBssParams add_bss);
+
+static inline bool wma_is_peer_he_capable(tpAddStaParams params)
+{
+	return params->he_capable;
+}
+
+/**
+ * wma_update_vdev_he_capable() - update vdev start request he capability
+ * @req: pointer to vdev start request
+ * @params: pointer to chan switch params
+ *
+ * Return: None
+ */
+void wma_update_vdev_he_capable(struct wma_vdev_start_req *req,
+		tpSwitchChannelParams params);
+
+/**
+ * wma_update_he_ops_ie() - update the HE OPS IE to firmware
+ * @wma: pointer to wma context
+ * @vdev_id: vdev id
+ * @he_ops: 32bit value of HE ops
+ *
+ * This API is used to send updated HE operational IE to firmware, so that
+ * firmware can be in sync with host
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_update_he_ops_ie(tp_wma_handle wma, uint8_t vdev_id,
+				tDot11fIEhe_op *he_ops);
+
+/**
+ * wma_get_he_capabilities() - Get HE capabilities from WMA
+ * @he_cap: Pointer to HE capabilities
+ *
+ * Currently HE capabilities are not updated in wma_handle. This
+ * is an interface for upper layer to query capabilities from WMA.
+ * When the real use case arise, update wma_handle with HE capabilities
+ * as required.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_get_he_capabilities(struct he_capability *he_cap);
+
+/**
+ * wma_set_he_vdev_param() - update he vdev param in wma
+ * @intr: pointer to wma_txrx_node
+ * @param_id: vdev param id
+ * @value: value of vdev param
+ *
+ * Result: None
+ */
+void wma_set_he_vdev_param(struct wma_txrx_node *intr, WMI_VDEV_PARAM param_id,
+			   uint32_t value);
+
+/**
+ * wma_get_he_vdev_param() - retrieve he vdev param from wma
+ * @intr: pointer to wma_txrx_node
+ * @param_id: vdev param id
+ *
+ * Result: param value
+ */
+uint32_t wma_get_he_vdev_param(struct wma_txrx_node *intr,
+			       WMI_VDEV_PARAM param_id);
+
+#else
+static inline void wma_print_he_cap(tDot11fIEhe_cap *he_cap)
+{
+}
+
+static inline void wma_print_he_ppet(void *ppet)
+{
+}
+
+static inline void wma_print_he_phy_cap(uint32_t *phy_cap)
+{
+}
+
+static inline void wma_print_he_mac_cap_w1(uint32_t mac_cap)
+{
+}
+
+static inline void wma_print_he_mac_cap_w2(uint32_t mac_cap)
+{
+}
+
+static inline void wma_print_he_op(tDot11fIEhe_op *he_ops)
+{
+}
+
+static inline void wma_update_target_ext_he_cap(struct
+						target_psoc_info *tgt_hdl,
+						struct wma_tgt_cfg *tgt_cfg)
+{
+}
+
+static inline void wma_he_update_tgt_services(struct wmi_unified *wmi_handle,
+					      struct wma_tgt_services *cfg)
+{
+	cfg->en_11ax = false;
+	return;
+}
+
+static inline void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
+					    tpAddStaParams params)
+{
+}
+
+static inline void wma_update_vdev_he_ops(struct wma_vdev_start_req *req,
+			tpAddBssParams add_bss)
+{
+}
+static inline void wma_copy_txrxnode_he_ops(struct wma_txrx_node *intr,
+			struct wma_vdev_start_req *req)
+{
+}
+
+static inline void wma_copy_vdev_start_he_ops(struct vdev_start_params *params,
+			struct wma_vdev_start_req *req)
+{
+}
+
+static inline  QDF_STATUS wma_update_he_ops_ie(tp_wma_handle wma,
+			uint8_t vdev_id, tDot11fIEhe_op *he_ops)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void wma_vdev_set_he_bss_params(tp_wma_handle wma,
+				uint8_t vdev_id, struct wma_vdev_start_req *req)
+{
+}
+
+static inline void wma_vdev_set_he_config(tp_wma_handle wma, uint8_t vdev_id,
+					tpAddBssParams add_bss)
+{
+}
+
+static inline bool wma_is_peer_he_capable(tpAddStaParams params)
+{
+	return false;
+}
+
+static inline void wma_update_vdev_he_capable(struct wma_vdev_start_req *req,
+					      tpSwitchChannelParams params)
+{
+}
+
+static inline void wma_set_he_vdev_param(struct wma_txrx_node *intr,
+			WMI_VDEV_PARAM param_id, uint32_t value)
+{
+	WMA_LOGI(FL("Unable to update WMI_VDEV_PARAM: %0x"), param_id);
+}
+
+static inline uint32_t wma_get_he_vdev_param(struct wma_txrx_node *intr,
+					     WMI_VDEV_PARAM param_id)
+{
+	WMA_LOGI(FL("Unable to update WMI_VDEV_PARAM: %0x"), param_id);
+	return 0;
+}
+
+#endif
+
+#endif /* __WMA_HE_H */
diff --git a/core/wma/inc/wma_if.h b/core/wma/inc/wma_if.h
new file mode 100644
index 0000000..dc46fbe
--- /dev/null
+++ b/core/wma/inc/wma_if.h
@@ -0,0 +1,1505 @@
+/*
+ * Copyright (c) 2011-2018 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.
+ */
+
+#ifndef _HALMSGAPI_H_
+#define _HALMSGAPI_H_
+
+#include "qdf_types.h"
+#include "sir_api.h"
+#include "sir_params.h"
+
+
+/*
+ * Validate the OS Type being built
+ */
+
+#if defined(ANI_OS_TYPE_ANDROID)        /* ANDROID */
+
+#if defined(ANI_OS_TYPE_QNX)
+#error "more than one ANI_OS_TYPE_xxx is defined for this build"
+#endif
+
+#elif defined(ANI_OS_TYPE_QNX)        /* QNX */
+
+#if defined(ANI_OS_TYPE_ANDROID)
+#error "more than one ANI_OS_TYPE_xxx is defined for this build"
+#endif
+
+#elif !defined(ANI_OS_TYPE_ANDROID) && !defined(ANI_OS_TYPE_QNX) /* NONE */
+#error "NONE of the ANI_OS_TYPE_xxx are defined for this build"
+#endif
+
+#define WMA_CONFIG_PARAM_UPDATE_REQ    SIR_CFG_PARAM_UPDATE_IND
+
+#define HAL_NUM_BSSID 2
+/* operMode in ADD BSS message */
+#define BSS_OPERATIONAL_MODE_AP     0
+#define BSS_OPERATIONAL_MODE_STA    1
+#define BSS_OPERATIONAL_MODE_IBSS   2
+#define BSS_OPERATIONAL_MODE_NDI    3
+
+/* STA entry type in add sta message */
+#define STA_ENTRY_SELF              0
+#define STA_ENTRY_OTHER             1
+#define STA_ENTRY_BSSID             2
+/* Special station id for transmitting broadcast frames. */
+#define STA_ENTRY_BCAST             3
+#define STA_ENTRY_PEER              STA_ENTRY_OTHER
+#ifdef FEATURE_WLAN_TDLS
+#define STA_ENTRY_TDLS_PEER         4
+#endif /* FEATURE_WLAN_TDLS */
+#define STA_ENTRY_NDI_PEER          5
+
+#define STA_INVALID_IDX 0xFF
+
+/* invalid channel id. */
+#define INVALID_CHANNEL_ID 0
+
+/*
+ * From NOVA Mac Arch document
+ *  Encryp. mode    The encryption mode
+ *  000: Encryption functionality is not enabled
+ *  001: Encryption is set to WEP
+ *  010: Encryption is set to WEP 104
+ *  011: Encryption is set to TKIP
+ *  100: Encryption is set to AES
+ *  101 - 111: Reserved for future
+ */
+#define ENC_POLICY_NULL        0
+#define ENC_POLICY_WEP40       1
+#define ENC_POLICY_WEP104      2
+#define ENC_POLICY_TKIP        3
+#define ENC_POLICY_AES_CCM     4
+
+/* Max number of bytes required for stations bitmap aligned at 4 bytes boundary
+ */
+#define HALMSG_NUMBYTES_STATION_BITMAP(x) (((x / 32) + ((x % 32) ? 1 : 0)) * 4)
+
+
+#define HAL_MAX_SUPP_CHANNELS     128
+#define HAL_MAX_SUPP_OPER_CLASSES 32
+
+/**
+ * enum eFrameType - frame types
+ * @TXRX_FRM_RAW: raw frame
+ * @TXRX_FRM_ETH2: ethernet frame
+ * @TXRX_FRM_802_3: 802.3 frame
+ * @TXRX_FRM_802_11_MGMT: 802.11 mgmt frame
+ * @TXRX_FRM_802_11_CTRL: 802.11 control frame
+ * @TXRX_FRM_802_11_DATA: 802.11 data frame
+ */
+typedef enum {
+	TXRX_FRM_RAW,
+	TXRX_FRM_ETH2,
+	TXRX_FRM_802_3,
+	TXRX_FRM_802_11_MGMT,
+	TXRX_FRM_802_11_CTRL,
+	TXRX_FRM_802_11_DATA,
+	TXRX_FRM_IGNORED,   /* This frame will be dropped */
+	TXRX_FRM_MAX
+} eFrameType;
+
+/**
+ * enum eFrameTxDir - frame tx direction
+ * @ANI_TXDIR_IBSS: IBSS frame
+ * @ANI_TXDIR_TODS: frame to DS
+ * @ANI_TXDIR_FROMDS: Frame from DS
+ * @ANI_TXDIR_WDS: WDS frame
+ */
+typedef enum {
+	ANI_TXDIR_IBSS = 0,
+	ANI_TXDIR_TODS,
+	ANI_TXDIR_FROMDS,
+	ANI_TXDIR_WDS
+} eFrameTxDir;
+
+/**
+ *struct sAniBeaconStruct - Beacon structure
+ * @beaconLength: beacon length
+ * @macHdr: mac header for beacon
+ */
+typedef struct sAniBeaconStruct {
+	uint32_t beaconLength;
+	tSirMacMgmtHdr macHdr;
+} qdf_packed tAniBeaconStruct, *tpAniBeaconStruct;
+
+/**
+ * struct sAniProbeRspStruct - probeRsp template structure
+ * @macHdr: mac header for probe response
+ */
+typedef struct sAniProbeRspStruct {
+	tSirMacMgmtHdr macHdr;
+	/* probeRsp body follows here */
+} qdf_packed tAniProbeRspStruct, *tpAniProbeRspStruct;
+
+/**
+ * struct tAddStaParams - add sta related parameters
+ * @bssId: bssid of sta
+ * @assocId: associd
+ * @staType: 0 - Self, 1 other/remote, 2 - bssid
+ * @staMac: MAC Address of STA
+ * @shortPreambleSupported: is short preamble supported or not
+ * @listenInterval: Listen interval
+ * @wmmEnabled: Support for 11e/WMM
+ * @uAPSD: U-APSD Flags: 1b per AC
+ * @maxSPLen: Max SP Length
+ * @htCapable: 11n HT capable STA
+ * @greenFieldCapable: 11n Green Field preamble support
+ * @txChannelWidthSet: TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz
+ * @mimoPS: MIMO Power Save
+ * @rifsMode: RIFS mode: 0 - NA, 1 - Allowed
+ * @lsigTxopProtection: L-SIG TXOP Protection mechanism
+ * @us32MaxAmpduDuration: in units of 32 us
+ * @maxAmpduSize:  0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k
+ * @maxAmpduDensity: 3 : 0~7 : 2^(11nAMPDUdensity -4)
+ * @maxAmsduSize: 1 : 3839 bytes, 0 : 7935 bytes
+ * @fDsssCckMode40Mhz: DSSS CCK supported 40MHz
+ * @fShortGI40Mhz: short GI support for 40Mhz packets
+ * @fShortGI20Mhz: short GI support for 20Mhz packets
+ * @supportedRates: legacy supported rates
+ * @status: QDF status
+ * @staIdx: station index
+ * @bssIdx: BSSID of BSS to which the station is associated
+ * @updateSta: pdate the existing STA entry, if this flag is set
+ * @respReqd: A flag to indicate to HAL if the response message is required
+ * @rmfEnabled: Robust Management Frame (RMF) enabled/disabled
+ * @encryptType: The unicast encryption type in the association
+ * @sessionId: PE session id
+ * @p2pCapableSta: if this is a P2P Capable Sta
+ * @csaOffloadEnable: CSA offload enable flag
+ * @vhtCapable: is VHT capabale or not
+ * @vhtTxChannelWidthSet: VHT channel width
+ * @vhtSupportedRxNss: VHT supported RX NSS
+ * @vhtTxBFCapable: txbf capable or not
+ * @vhtTxMUBformeeCapable: Bformee capable or not
+ * @enableVhtpAid: enable VHT AID
+ * @enableVhtGid: enable VHT GID
+ * @enableAmpduPs: AMPDU power save
+ * @enableHtSmps: enable HT SMPS
+ * @htSmpsconfig: HT SMPS config
+ * @htLdpcCapable: HT LDPC capable
+ * @vhtLdpcCapable: VHT LDPC capable
+ * @smesessionId: sme session id
+ * @wpa_rsn: RSN capable
+ * @capab_info: capabality info
+ * @ht_caps: HT capabalities
+ * @vht_caps: VHT vapabalities
+ * @nwType: NW Type
+ * @maxTxPower: max tx power
+ * @atimIePresent: Peer Atim Info
+ * @peerAtimWindowLength: peer ATIM Window length
+ * @nss: Return the number of spatial streams supported
+ * @stbc_capable: stbc capable
+ * @max_amsdu_num: Maximum number of MSDUs in a tx aggregate frame
+ *
+ * This structure contains parameter required for
+ * add sta request of upper layer.
+ */
+typedef struct {
+	tSirMacAddr bssId;
+	uint16_t assocId;
+	/* Field to indicate if this is sta entry for itself STA adding entry
+	 * for itself or remote (AP adding STA after successful association.
+	 * This may or may not be required in production driver.
+	 */
+	uint8_t staType;
+	uint8_t shortPreambleSupported;
+	tSirMacAddr staMac;
+	uint16_t listenInterval;
+	uint8_t wmmEnabled;
+	uint8_t uAPSD;
+	uint8_t maxSPLen;
+	uint8_t htCapable;
+	/* 11n Green Field preamble support
+	 * 0 - Not supported, 1 - Supported
+	 * Add it to RA related fields of sta entry in HAL
+	 */
+	uint8_t greenFieldCapable;
+	uint8_t ch_width;
+
+	tSirMacHTMIMOPowerSaveState mimoPS;
+	uint8_t rifsMode;
+	/* L-SIG TXOP Protection mechanism
+	 * 0 - No Support, 1 - Supported
+	 * SG - there is global field.
+	 */
+	uint8_t lsigTxopProtection;
+	uint8_t us32MaxAmpduDuration;
+	uint8_t maxAmpduSize;
+	uint8_t maxAmpduDensity;
+	uint8_t maxAmsduSize;
+
+	/* 11n Parameters */
+	/* HT STA should set it to 1 if it is enabled in BSS
+	 * HT STA should set it to 0 if AP does not support it.
+	 * This indication is sent to HAL and HAL uses this flag
+	 * to pickup up appropriate 40Mhz rates.
+	 */
+	uint8_t fDsssCckMode40Mhz;
+	uint8_t fShortGI40Mhz;
+	uint8_t fShortGI20Mhz;
+	tSirSupportedRates supportedRates;
+	/*
+	 * Following parameters are for returning status and station index from
+	 * HAL to PE via response message. HAL does not read them.
+	 */
+	/* The return status of SIR_HAL_ADD_STA_REQ is reported here */
+	QDF_STATUS status;
+	/* Station index; valid only when 'status' field value is
+	 * QDF_STATUS_SUCCESS
+	 */
+	uint8_t staIdx;
+	/* BSSID of BSS to which the station is associated.
+	 * This should be filled back in by HAL, and sent back to LIM as part of
+	 * the response message, so LIM can cache it in the station entry of
+	 * hash table. When station is deleted, LIM will make use of this bssIdx
+	 * to delete BSS from hal tables and from softmac.
+	 */
+	uint8_t bssIdx;
+	uint8_t updateSta;
+	uint8_t respReqd;
+	uint8_t rmfEnabled;
+	uint32_t encryptType;
+	uint8_t sessionId;
+	uint8_t p2pCapableSta;
+	uint8_t csaOffloadEnable;
+	uint8_t vhtCapable;
+	uint8_t vhtSupportedRxNss;
+	uint8_t vhtTxBFCapable;
+	uint8_t enable_su_tx_bformer;
+	uint8_t vhtTxMUBformeeCapable;
+	uint8_t enableVhtpAid;
+	uint8_t enableVhtGid;
+	uint8_t enableAmpduPs;
+	uint8_t enableHtSmps;
+	uint8_t htSmpsconfig;
+	bool send_smps_action;
+	uint8_t htLdpcCapable;
+	uint8_t vhtLdpcCapable;
+	uint8_t smesessionId;
+	uint8_t wpa_rsn;
+	uint16_t capab_info;
+	uint16_t ht_caps;
+	uint32_t vht_caps;
+	tSirNwType nwType;
+	int8_t maxTxPower;
+	uint8_t atimIePresent;
+	uint32_t peerAtimWindowLength;
+	uint8_t nonRoamReassoc;
+	uint32_t nss;
+#ifdef WLAN_FEATURE_11AX
+	bool he_capable;
+	tDot11fIEhe_cap he_config;
+	tDot11fIEhe_op he_op;
+#endif
+	uint8_t stbc_capable;
+	uint8_t max_amsdu_num;
+#ifdef WLAN_SUPPORT_TWT
+	uint8_t twt_requestor;
+	uint8_t twt_responder;
+#endif
+} tAddStaParams, *tpAddStaParams;
+
+/**
+ * struct tDeleteStaParams - parameters required for del sta request
+ * @staIdx: station index
+ * @assocId: association index
+ * @status: status
+ * @respReqd: is response required
+ * @sessionId: PE session id
+ * @smesessionId: SME session id
+ * @staType: station type
+ * @staMac: station mac
+ */
+typedef struct {
+	uint16_t staIdx;
+	uint16_t assocId;
+	QDF_STATUS status;
+	uint8_t respReqd;
+	uint8_t sessionId;
+	uint8_t smesessionId;
+	uint8_t staType;
+	tSirMacAddr staMac;
+} tDeleteStaParams, *tpDeleteStaParams;
+
+/**
+ * struct tSetStaKeyParams - set key params
+ * @staIdx: station id
+ * @encType: encryption type
+ * @wepType: WEP type
+ * @defWEPIdx: Default WEP key, valid only for static WEP, must between 0 and 3
+ * @key: valid only for non-static WEP encyrptions
+ * @singleTidRc: 1=Single TID based Replay Count, 0=Per TID based RC
+ * @smesessionId: sme session id
+ * @peerMacAddr: peer mac address
+ * @status: status
+ * @sessionId: session id
+ * @sendRsp: send response
+ *
+ * This is used by PE to configure the key information on a given station.
+ * When the secType is WEP40 or WEP104, the defWEPIdx is used to locate
+ * a preconfigured key from a BSS the station assoicated with; otherwise
+ * a new key descriptor is created based on the key field.
+ */
+typedef struct {
+	uint16_t staIdx;
+	tAniEdType encType;
+	tAniWepType wepType;
+	uint8_t defWEPIdx;
+	tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS];
+	uint8_t singleTidRc;
+	uint8_t smesessionId;
+	struct qdf_mac_addr peer_macaddr;
+	QDF_STATUS status;
+	uint8_t sessionId;
+	uint8_t sendRsp;
+} tSetStaKeyParams, *tpSetStaKeyParams;
+
+/**
+ * struct sLimMlmSetKeysReq - set key request parameters
+ * @peerMacAddr: peer mac address
+ * @sessionId: PE session id
+ * @smesessionId: SME session id
+ * @aid: association id
+ * @edType: Encryption/Decryption type
+ * @numKeys: number of keys
+ * @key: key data
+ */
+typedef struct sLimMlmSetKeysReq {
+	struct qdf_mac_addr peer_macaddr;
+	uint8_t sessionId;      /* Added For BT-AMP Support */
+	uint8_t smesessionId;   /* Added for drivers based on wmi interface */
+	uint16_t aid;
+	tAniEdType edType;      /* Encryption/Decryption type */
+	uint8_t numKeys;
+	tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS];
+} tLimMlmSetKeysReq, *tpLimMlmSetKeysReq;
+
+/**
+ * struct tAddBssParams - parameters required for add bss params
+ * @bssId: MAC Address/BSSID
+ * @selfMacAddr: Self Mac Address
+ * @bssType: BSS type
+ * @operMode: AP - 0; STA - 1;
+ * @nwType: network type
+ * @shortSlotTimeSupported: is short slot time supported or not
+ * @llaCoexist: is 11a coexist or not
+ * @llbCoexist: 11b coexist supported or not
+ * @llgCoexist: 11g coexist supported or not
+ * @ht20Coexist: HT20 coexist supported or not
+ * @fLsigTXOPProtectionFullSupport: TXOP protection supported or not
+ * @fRIFSMode: RIFS is supported or not
+ * @beaconInterval: beacon interval
+ * @dtimPeriod: DTIM period
+ * @cfParamSet: CF Param Set
+ * @rateSet: MAC Rate Set
+ * @htCapable: Enable/Disable HT capabilities
+ * @obssProtEnabled: Enable/Disable OBSS protection
+ * @rmfEnabled: RMF enabled/disabled
+ * @htOperMode: HT Operating Mode
+ * @HT Operating Mode: Dual CTS Protection: 0 - Unused, 1 - Used
+ * @txChannelWidthSet: TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz
+ * @currentOperChannel: Current Operating Channel
+ * @currentExtChannel: Current Extension Channel, if applicable
+ * @staContext: sta context
+ * @status: status
+ * @bssIdx: BSS index allocated by HAL
+ * @updateBss: update the existing BSS entry, if this flag is set
+ * @ssId: Add BSSID info for rxp filter
+ * @respReqd: send the response message to LIM only when this flag is set
+ * @sessionId: PE session id
+ * @txMgmtPower: tx power used for mgmt frames
+ * @maxTxPower: max power to be used after applying the power constraint
+ * @extSetStaKeyParamValid: Ext Bss Config Msg if set
+ * @extSetStaKeyParam: SetStaKeyParams for ext bss msg
+ * @ucMaxProbeRespRetryLimit: probe Response Max retries
+ * @bHiddenSSIDEn: To Enable Hidden ssid.
+ * @bProxyProbeRespEn: To Enable Disable FW Proxy Probe Resp
+ * @halPersona: Persona for the BSS can be STA,AP,GO,CLIENT value
+ * @bSpectrumMgtEnabled: Spectrum Management Capability, 1:Enabled, 0:Disabled.
+ * @vhtCapable: VHT capablity
+ * @vhtTxChannelWidthSet: VHT tx channel width
+ * @reassocReq: Set only during roaming reassociation
+ * @chainMask: chain mask
+ * @smpsMode: SMPS mode
+ * @dot11_mode: 802.11 mode
+ * @he_capable: HE Capability
+ * @cac_duration_ms: cac duration in milliseconds
+ * @dfs_regdomain: dfs region
+ */
+typedef struct {
+	tSirMacAddr bssId;
+	tSirMacAddr selfMacAddr;
+	tSirBssType bssType;
+	uint8_t operMode;
+	tSirNwType nwType;
+	uint8_t shortSlotTimeSupported;
+	uint8_t llaCoexist;
+	uint8_t llbCoexist;
+	uint8_t llgCoexist;
+	uint8_t ht20Coexist;
+	uint8_t llnNonGFCoexist;
+	uint8_t fLsigTXOPProtectionFullSupport;
+	uint8_t fRIFSMode;
+	tSirMacBeaconInterval beaconInterval;
+	uint8_t dtimPeriod;
+	tSirMacCfParamSet cfParamSet;
+	tSirMacRateSet rateSet;
+	uint8_t htCapable;
+	uint8_t obssProtEnabled;
+	uint8_t rmfEnabled;
+	tSirMacHTOperatingMode htOperMode;
+	uint8_t dualCTSProtection;
+	uint8_t txChannelWidthSet;
+	uint8_t currentOperChannel;
+	tAddStaParams staContext;
+	QDF_STATUS status;
+	uint16_t bssIdx;
+	/* HAL should update the existing BSS entry, if this flag is set.
+	 * PE will set this flag in case of reassoc, where we want to resue the
+	 * the old bssID and still return success.
+	 */
+	uint8_t updateBss;
+	tSirMacSSid ssId;
+	uint8_t respReqd;
+	uint8_t sessionId;
+	int8_t txMgmtPower;
+	int8_t maxTxPower;
+
+	uint8_t extSetStaKeyParamValid;
+	tSetStaKeyParams extSetStaKeyParam;
+
+	uint8_t ucMaxProbeRespRetryLimit;
+	uint8_t bHiddenSSIDEn;
+	uint8_t bProxyProbeRespEn;
+	uint8_t halPersona;
+	uint8_t bSpectrumMgtEnabled;
+	uint8_t vhtCapable;
+	enum phy_ch_width ch_width;
+	uint8_t ch_center_freq_seg0;
+	uint8_t ch_center_freq_seg1;
+	uint8_t reassocReq;     /* Set only during roaming reassociation */
+	uint16_t chainMask;
+	uint16_t smpsMode;
+	uint8_t dot11_mode;
+	uint8_t nonRoamReassoc;
+	uint8_t wps_state;
+	uint8_t nss;
+	uint8_t nss_2g;
+	uint8_t nss_5g;
+	uint16_t beacon_tx_rate;
+	uint32_t tx_aggregation_size;
+	uint32_t tx_aggregation_size_be;
+	uint32_t tx_aggregation_size_bk;
+	uint32_t tx_aggregation_size_vi;
+	uint32_t tx_aggregation_size_vo;
+	uint32_t rx_aggregation_size;
+#ifdef WLAN_FEATURE_11AX
+	bool he_capable;
+	tDot11fIEhe_cap he_config;
+	tDot11fIEhe_op he_op;
+	uint32_t he_sta_obsspd;
+#endif
+	uint32_t cac_duration_ms;
+	uint32_t dfs_regdomain;
+} tAddBssParams, *tpAddBssParams;
+
+/**
+ * struct tDeleteBssParams - params required for del bss request
+ * @bssIdx: BSSID
+ * @status: QDF status
+ * @respReqd: response message to LIM only when this flag is set
+ * @sessionId: PE session id
+ * @bssid: BSSID mac address
+ * @smesessionId: sme session id
+ */
+typedef struct {
+	uint8_t bssIdx;
+	QDF_STATUS status;
+	uint8_t respReqd;
+	uint8_t sessionId;
+	tSirMacAddr bssid;
+	uint8_t smesessionId;
+} tDeleteBssParams, *tpDeleteBssParams;
+
+/**
+ * struct sSirScanEntry - scan entry
+ * @bssIdx: BSSID
+ * @activeBSScnt: active BSS count
+ */
+typedef struct sSirScanEntry {
+	uint8_t bssIdx[HAL_NUM_BSSID];
+	uint8_t activeBSScnt;
+} tSirScanEntry, *ptSirScanEntry;
+
+/**
+ * struct tInitScanParams - params required for init scan request
+ * @bssid: BSSID
+ * @notifyBss: notify BSS
+ * @useNoA: use NOA
+ * @notifyHost: notify UMAC if set
+ * @frameLength: frame length
+ * @frameType: frame type
+ * @scanDuration: Indicates the scan duration (in ms)
+ * @macMgmtHdr: For creation of CTS-to-Self and Data-NULL MAC packets
+ * @scanEntry: scan entry
+ * @checkLinkTraffic: when this flag is set, HAL should check for
+ *                    link traffic prior to scan
+ * @status: status
+ */
+typedef struct {
+	tSirMacAddr bssid;
+	uint8_t notifyBss;
+	uint8_t useNoA;
+	uint8_t notifyHost;
+	uint8_t frameLength;
+	uint8_t frameType;
+	uint16_t scanDuration;
+	tSirMacMgmtHdr macMgmtHdr;
+	tSirScanEntry scanEntry;
+	tSirLinkTrafficCheck checkLinkTraffic;
+	QDF_STATUS status;
+} tInitScanParams, *tpInitScanParams;
+
+typedef enum eDelStaReasonCode {
+	HAL_DEL_STA_REASON_CODE_KEEP_ALIVE = 0x1,
+	HAL_DEL_STA_REASON_CODE_TIM_BASED = 0x2,
+	HAL_DEL_STA_REASON_CODE_RA_BASED = 0x3,
+	HAL_DEL_STA_REASON_CODE_UNKNOWN_A2 = 0x4,
+	HAL_DEL_STA_REASON_CODE_BTM_DISASSOC_IMMINENT = 0x5
+} tDelStaReasonCode;
+
+typedef enum eSmpsModeValue {
+	STATIC_SMPS_MODE = 0x0,
+	DYNAMIC_SMPS_MODE = 0x1,
+	SMPS_MODE_RESERVED = 0x2,
+	SMPS_MODE_DISABLED = 0x3
+} tSmpsModeValue;
+
+/**
+ * struct tDeleteStaContext - params required for delete sta request
+ * @assocId: association id
+ * @staId: station id
+ * @bssId: mac address
+ * @addr2: mac address
+ * @reasonCode: reason code
+ * @rssi: rssi value during disconnection
+ */
+typedef struct {
+	bool is_tdls;
+	uint8_t vdev_id;
+	uint16_t assocId;
+	uint16_t staId;
+	tSirMacAddr bssId;
+	tSirMacAddr addr2;
+	uint16_t reasonCode;
+	int8_t rssi;
+} tDeleteStaContext, *tpDeleteStaContext;
+
+/**
+ * struct tStartScanParams - params required for start scan request
+ * @scanChannel: Indicates the current scan channel
+ * @status: return status
+ * @startTSF: TSF value
+ * @txMgmtPower: TX mgmt power
+ */
+typedef struct {
+	uint8_t scanChannel;
+	QDF_STATUS status;
+	uint32_t startTSF[2];
+	int8_t txMgmtPower;
+} tStartScanParams, *tpStartScanParams;
+
+/**
+ * struct tEndScanParams - params required for end scan request
+ * @scanChannel: Indicates the current scan channel
+ * @status: return status
+ */
+typedef struct {
+	uint8_t scanChannel;
+	QDF_STATUS status;
+} tEndScanParams, *tpEndScanParams;
+
+/**
+ * struct tFinishScanParams - params required for finish scan request
+ * @bssid: BSSID
+ * @currentOperChannel: Current operating channel
+ * @cbState: channel bond state
+ * @notifyBss: notify BSS flag
+ * @notifyHost: notify host flag
+ * @frameLength: frame length
+ * @frameType: frame type
+ * @macMgmtHdr: For creation of CTS-to-Self and Data-NULL MAC packets
+ * @scanEntry: scan entry
+ * @status: return status
+ * Request Type = SIR_HAL_FINISH_SCAN_REQ
+ */
+typedef struct {
+	tSirMacAddr bssid;
+	uint8_t currentOperChannel;
+	/* If 20/40 MHz is operational, this will indicate the 40 MHz extension
+	 * channel in combination with the control channel
+	 */
+	ePhyChanBondState cbState;
+	/* For an STA, indicates if a Data NULL frame needs to be sent
+	 * to the AP with FrameControl.PwrMgmt bit set to 0
+	 */
+	uint8_t notifyBss;
+	uint8_t notifyHost;
+	uint8_t frameLength;
+	uint8_t frameType;
+	tSirMacMgmtHdr macMgmtHdr;
+	tSirScanEntry scanEntry;
+	QDF_STATUS status;
+} tFinishScanParams, *tpFinishScanParams;
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
+#ifndef OEM_DATA_RSP_SIZE
+#define OEM_DATA_RSP_SIZE 1724
+#endif
+
+/**
+ * struct tStartOemDataRsp - start OEM Data response
+ * @target_rsp: Indicates if the rsp is from Target or WMA generated.
+ * @rsp_len: oem data response length
+ * @oem_data_rsp: pointer to OEM Data response
+ */
+typedef struct {
+	bool target_rsp;
+	uint32_t rsp_len;
+	uint8_t *oem_data_rsp;
+} tStartOemDataRsp, *tpStartOemDataRsp;
+#endif /* FEATURE_OEM_DATA_SUPPORT */
+
+/**
+ * struct tBeaconGenParams - params required for beacon gen request
+ * @bssIdx: Identifies the BSSID for which it is time to generate a beacon
+ * @bssId: BSSID
+ * @numOfSta: Number of stations in power save, who have data pending
+ * @numOfStaWithoutData: Number of stations in power save,
+ *                       who don't have any data pending
+ * @fBroadcastTrafficPending: broadcast traffic pending flag
+ * @dtimCount: DTIM count
+ * @rsvd: reserved(padding)
+ */
+typedef struct sBeaconGenParams {
+	uint8_t bssIdx;
+	tSirMacAddr bssId;
+#ifdef FIXME_VOLANS
+	uint8_t numOfSta;
+	uint8_t numOfStaWithoutData;
+	uint8_t fBroadcastTrafficPending;
+	uint8_t dtimCount;
+#endif /* FIXME_VOLANS */
+	uint8_t rsvd[3];
+} tBeaconGenParams, *tpBeaconGenParams;
+
+/**
+ * struct tSendbeaconParams - send beacon parameters
+ * vdev_id: vdev id
+ * @bssId: BSSID mac address
+ * @beacon: beacon data
+ * @beaconLength: beacon length of template
+ * @timIeOffset: TIM IE offset
+ * @p2pIeOffset: P2P IE offset
+ * @csa_count_offset: Offset of Switch count field in CSA IE
+ * @ecsa_count_offset: Offset of Switch count field in ECSA IE
+ * @reason: bcn update reason
+ * @status: beacon send status
+ */
+typedef struct {
+	uint8_t vdev_id;
+	tSirMacAddr bssId;
+	uint8_t beacon[SIR_MAX_BEACON_SIZE];
+	uint32_t beaconLength;
+	uint32_t timIeOffset;
+	uint16_t p2pIeOffset;
+	uint32_t csa_count_offset;
+	uint32_t ecsa_count_offset;
+	enum sir_bcn_update_reason reason;
+	QDF_STATUS status;
+} tSendbeaconParams, *tpSendbeaconParams;
+
+/**
+ * struct tSendProbeRespParams - send probe response parameters
+ * @bssId: BSSID
+ * @probeRespTemplate: probe response template
+ * @probeRespTemplateLen: probe response template length
+ * @ucProxyProbeReqValidIEBmap: valid IE bitmap
+ */
+typedef struct sSendProbeRespParams {
+	tSirMacAddr bssId;
+	uint8_t probeRespTemplate[SIR_MAX_PROBE_RESP_SIZE];
+	uint32_t probeRespTemplateLen;
+	uint32_t ucProxyProbeReqValidIEBmap[8];
+} tSendProbeRespParams, *tpSendProbeRespParams;
+
+/**
+ * struct tSetBssKeyParams - BSS key parameters
+ * @bssIdx: BSSID index
+ * @encType: encryption Type
+ * @numKeys: number of keys
+ * @key: key data
+ * @singleTidRc: 1=Single TID based Replay Count, 0=Per TID based RC
+ * @smesessionId: sme session id
+ * @status: return status of command
+ * @sessionId: PE session id
+ */
+typedef struct {
+	uint8_t bssIdx;
+	tAniEdType encType;
+	uint8_t numKeys;
+	tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS];
+	uint8_t singleTidRc;
+	uint8_t smesessionId;
+	QDF_STATUS status;
+	uint8_t sessionId;
+} tSetBssKeyParams, *tpSetBssKeyParams;
+
+/**
+ * struct tUpdateBeaconParams - update beacon request parameters
+ * @bssIdx: BSSID index
+ * @fShortPreamble: shortPreamble mode
+ * @fShortSlotTime: short Slot time
+ * @beaconInterval: Beacon Interval
+ * @llaCoexist: 11a coexist
+ * @llbCoexist: 11b coexist
+ * @llgCoexist: 11g coexist
+ * @ht20MhzCoexist: HT 20MHz coexist
+ * @fLsigTXOPProtectionFullSupport: TXOP protection supported or not
+ * @fRIFSMode: RIFS mode
+ * @paramChangeBitmap: change bitmap
+ * @smeSessionId: SME  session id
+ */
+typedef struct {
+	uint8_t bssIdx;
+	uint8_t fShortPreamble;
+	uint8_t fShortSlotTime;
+	uint16_t beaconInterval;
+	uint8_t llaCoexist;
+	uint8_t llbCoexist;
+	uint8_t llgCoexist;
+	uint8_t ht20MhzCoexist;
+	uint8_t llnNonGFCoexist;
+	uint8_t fLsigTXOPProtectionFullSupport;
+	uint8_t fRIFSMode;
+	uint16_t paramChangeBitmap;
+	uint8_t smeSessionId;
+	uint32_t bss_color;
+	bool bss_color_disabled;
+} tUpdateBeaconParams, *tpUpdateBeaconParams;
+
+/**
+ * struct tUpdateVHTOpMode - VHT operating mode
+ * @opMode: VHT operating mode
+ * @staId: station id
+ * @smesessionId: SME session id
+ * @peer_mac: peer mac address
+ */
+typedef struct {
+	uint16_t opMode;
+	uint16_t staId;
+	uint16_t smesessionId;
+	tSirMacAddr peer_mac;
+} tUpdateVHTOpMode, *tpUpdateVHTOpMode;
+
+/**
+ * struct tUpdateRxNss - update rx nss parameters
+ * @rxNss: rx nss value
+ * @staId: station id
+ * @smesessionId: sme session id
+ * @peer_mac: peer mac address
+ */
+typedef struct {
+	uint16_t rxNss;
+	uint16_t staId;
+	uint16_t smesessionId;
+	tSirMacAddr peer_mac;
+} tUpdateRxNss, *tpUpdateRxNss;
+
+/**
+ * struct tUpdateMembership - update membership parmaters
+ * @membership: membership value
+ * @staId: station id
+ * @smesessionId: SME session id
+ * @peer_mac: peer mac address
+ */
+typedef struct {
+	uint32_t membership;
+	uint16_t staId;
+	uint16_t smesessionId;
+	tSirMacAddr peer_mac;
+} tUpdateMembership, *tpUpdateMembership;
+
+/**
+ * struct tUpdateUserPos - update user position parmeters
+ * @userPos: user position
+ * @staId: station id
+ * @smesessionId: sme session id
+ * @peer_mac: peer mac address
+ */
+typedef struct {
+	uint32_t userPos;
+	uint16_t staId;
+	uint16_t smesessionId;
+	tSirMacAddr peer_mac;
+} tUpdateUserPos, *tpUpdateUserPos;
+
+/**
+ * struct tUpdateCFParams -CF parameters
+ * @bssIdx: BSSID index
+ * @cfpCount: CFP count
+ * @cfpPeriod: the number of DTIM intervals between the start of CFPs
+ */
+typedef struct {
+	uint8_t bssIdx;
+	/*
+	 * cfpCount indicates how many DTIMs (including the current frame)
+	 * appear before the next CFP start. A CFPCount of 0 indicates that
+	 * the current DTIM marks the start of the CFP.
+	 */
+	uint8_t cfpCount;
+	uint8_t cfpPeriod;
+} tUpdateCFParams, *tpUpdateCFParams;
+
+/**
+ * struct tSwitchChannelParams - switch channel request parameter
+ * @channelNumber: channel number
+ * @localPowerConstraint: local power constraint
+ * @secondaryChannelOffset: scondary channel offset
+ * @peSessionId: PE session id
+ * @txMgmtPower: TX mgmt power
+ * @maxTxPower: max tx power
+ * @selfStaMacAddr: self mac address
+ * @bssId: bssid
+ * @status: QDF status
+ * @chainMask: chanin mask
+ * @smpsMode: SMPS mode
+ * @isDfsChannel: is DFS channel
+ * @vhtCapable: VHT capable
+ * @dot11_mode: 802.11 mode
+ * @cac_duration_ms: cac duration in milliseconds
+ * @dfs_regdomain: dfs region
+ */
+typedef struct {
+	uint8_t channelNumber;
+	uint8_t peSessionId;
+	int8_t txMgmtPower;
+	int8_t maxTxPower;
+	tSirMacAddr selfStaMacAddr;
+	/* the request has power constraints, this should be applied only to
+	 * that session
+	 * VO Wifi comment: BSSID is needed to identify which session issued
+	 * this request. As the request has power constraints, this should be
+	 * applied only to that session
+	 * V IMP: Keep bssId field at the end of this msg.
+	 * It is used to mantain backward compatbility by way of ignoring if
+	 * using new host/old FW or old host/new FW since it is at the end of
+	 * this struct
+	 */
+	tSirMacAddr bssId;
+	QDF_STATUS status;
+	uint16_t chainMask;
+	uint16_t smpsMode;
+	uint8_t isDfsChannel;
+	uint8_t vhtCapable;
+	enum phy_ch_width ch_width;
+	uint8_t ch_center_freq_seg0;
+	uint8_t ch_center_freq_seg1;
+	uint8_t dot11_mode;
+
+	uint8_t restart_on_chan_switch;
+	uint8_t nss;
+#ifdef WLAN_FEATURE_11AX
+	bool he_capable;
+#endif
+	uint32_t cac_duration_ms;
+	uint32_t dfs_regdomain;
+	uint16_t reduced_beacon_interval;
+} tSwitchChannelParams, *tpSwitchChannelParams;
+
+typedef void (*tpSetLinkStateCallback)(tpAniSirGlobal pMac, void *msgParam,
+		bool status);
+
+/**
+ * struct tLinkStateParams - link state parameters
+ * @bssid: BSSID
+ * @selfMacAddr: self mac address
+ * @state: link state
+ * @callback: callback function pointer
+ * @callbackArg: callback argument
+ * @session: session context
+ */
+typedef struct sLinkStateParams {
+	/* SIR_HAL_SET_LINK_STATE */
+	tSirMacAddr bssid;
+	tSirMacAddr selfMacAddr;
+	tSirLinkState state;
+	tpSetLinkStateCallback callback;
+	void *callbackArg;
+	int ft;
+	void *session;
+	bool status;
+} tLinkStateParams, *tpLinkStateParams;
+
+/**
+ * struct tAddTsParams - ADDTS related parameters
+ * @staIdx: station index
+ * @tspecIdx: TSPEC handler uniquely identifying a TSPEC for a STA in a BSS
+ * @tspec: tspec value
+ * @status: QDF status
+ * @sessionId: session id
+ * @tsm_interval: TSM interval period passed from lim to WMA
+ * @setRICparams: RIC parameters
+ * @sme_session_id: sme session id
+ */
+typedef struct {
+	uint16_t staIdx;
+	uint16_t tspecIdx;
+	tSirMacTspecIE tspec;
+	QDF_STATUS status;
+	uint8_t sessionId;
+#ifdef FEATURE_WLAN_ESE
+	uint16_t tsm_interval;
+#endif /* FEATURE_WLAN_ESE */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	uint8_t setRICparams;
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+	uint8_t sme_session_id;
+} tAddTsParams, *tpAddTsParams;
+
+/**
+ * struct tDelTsParams - DELTS related parameters
+ * @staIdx: station index
+ * @tspecIdx: TSPEC identifier uniquely identifying a TSPEC for a STA in a BSS
+ * @bssId: BSSID
+ * @sessionId: session id
+ * @userPrio: user priority
+ * @delTsInfo: DELTS info
+ * @setRICparams: RIC parameters
+ */
+typedef struct {
+	uint16_t staIdx;
+	uint16_t tspecIdx;
+	tSirMacAddr bssId;
+	uint8_t sessionId;
+	uint8_t userPrio;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	tSirDeltsReqInfo delTsInfo;
+	uint8_t setRICparams;
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+} tDelTsParams, *tpDelTsParams;
+
+
+#define HAL_QOS_NUM_TSPEC_MAX 2
+#define HAL_QOS_NUM_AC_MAX 4
+
+/**
+ * struct tAggrAddTsParams - ADDTS parameters
+ * @staIdx: station index
+ * @tspecIdx: TSPEC handler uniquely identifying a TSPEC for a STA in a BSS
+ * @tspec: tspec value
+ * @status: QDF status
+ * @sessionId: session id
+ * @vdev_id: vdev id
+ */
+typedef struct {
+	uint16_t staIdx;
+	uint16_t tspecIdx;
+	tSirMacTspecIE tspec[HAL_QOS_NUM_AC_MAX];
+	QDF_STATUS status[HAL_QOS_NUM_AC_MAX];
+	uint8_t sessionId;
+	uint8_t vdev_id;
+} tAggrAddTsParams, *tpAggrAddTsParams;
+
+
+typedef QDF_STATUS (*tHalMsgCallback)(tpAniSirGlobal pMac, uint32_t mesgId,
+				      void *mesgParam);
+
+/**
+ * struct tEdcaParams - EDCA parameters
+ * @bssIdx: BSSID index
+ * @acbe: best effort access category
+ * @acbk: Background access category
+ * @acvi: video access category
+ * @acvo: voice access category
+ * @mu_edca_params: flag to indicate MU EDCA
+ */
+typedef struct {
+	uint16_t bssIdx;
+	tSirMacEdcaParamRecord acbe;
+	tSirMacEdcaParamRecord acbk;
+	tSirMacEdcaParamRecord acvi;
+	tSirMacEdcaParamRecord acvo;
+	bool mu_edca_params;
+} tEdcaParams, *tpEdcaParams;
+
+/**
+ * struct tSetMIMOPS - MIMO power save related parameters
+ * @staIdx: station index
+ * @htMIMOPSState: MIMO Power Save State
+ * @status: response status
+ * @fsendRsp: send response flag
+ * @peerMac: peer mac address
+ * @sessionId: session id
+ */
+typedef struct sSet_MIMOPS {
+	uint16_t staIdx;
+	tSirMacHTMIMOPowerSaveState htMIMOPSState;
+	QDF_STATUS status;
+	uint8_t fsendRsp;
+	tSirMacAddr peerMac;
+	uint8_t sessionId;
+} tSetMIMOPS, *tpSetMIMOPS;
+
+/**
+ * struct tUapsdParams - Uapsd related parameters
+ * @bkDeliveryEnabled: BK delivery enable flag
+ * @beDeliveryEnabled: BE delivery enable flag
+ * @viDeliveryEnabled: VI delivery enable flag
+ * @voDeliveryEnabled: VO delivery enable flag
+ * @bkTriggerEnabled: BK trigger enable flag
+ * @beTriggerEnabled: BE trigger enable flag
+ * @viTriggerEnabled: VI trigger enable flag
+ * @voTriggerEnabled: VO trigger enable flag
+ * @status: response status
+ * @bssIdx: BSSID index
+ * Request Type = SIR_HAL_ENTER_UAPSD_REQ
+ */
+typedef struct sUapsdParams {
+	uint8_t bkDeliveryEnabled:1;
+	uint8_t beDeliveryEnabled:1;
+	uint8_t viDeliveryEnabled:1;
+	uint8_t voDeliveryEnabled:1;
+	uint8_t bkTriggerEnabled:1;
+	uint8_t beTriggerEnabled:1;
+	uint8_t viTriggerEnabled:1;
+	uint8_t voTriggerEnabled:1;
+	QDF_STATUS status;
+	uint8_t bssIdx;
+} tUapsdParams, *tpUapsdParams;
+
+/**
+ * struct tHalIndCB - hal message indication callback
+ * @pHalIndCB: hal message indication callabck
+ */
+typedef struct tHalIndCB {
+	tHalMsgCallback pHalIndCB;
+} tHalIndCB, *tpHalIndCB;
+
+/**
+ * struct sControlTxParams - control tx parameters
+ * @stopTx: stop transmission
+ * @fCtrlGlobal:  Master flag to stop or resume all transmission
+ * @ctrlSta: If this flag is set, staBitmap
+ * @ctrlBss: If this flag is set, bssBitmap and beaconBitmap is valid
+ * @bssBitmap: bitmap of BSS indices to be stopped for resumed
+ * @beaconBitmap: this bitmap contains bitmap of BSS indices to be
+ *                stopped for resumed for beacon transmission
+ */
+typedef struct sControlTxParams {
+	bool stopTx;
+	uint8_t fCtrlGlobal;
+	uint8_t ctrlSta;
+	uint8_t ctrlBss;
+	/* When ctrlBss is set, this bitmap contains bitmap of BSS indices to be
+	 * stopped for resumed for transmission.
+	 * This is 32 bit bitmap, not array of bytes.
+	 */
+	uint32_t bssBitmap;
+	/* When ctrlBss is set, this bitmap contains bitmap of BSS indices to be
+	 * stopped for resumed for beacon transmission.
+	 */
+	uint32_t beaconBitmap;
+} tTxControlParams, *tpTxControlParams;
+
+/**
+ * struct tMaxTxPowerParams - Max Tx Power parameters
+ * @bssId: BSSID is needed to identify which session issued this request
+ * @selfStaMacAddr: self mac address
+ * @power: tx power in dbm
+ * @dev_mode: device mode
+ * Request Type = SIR_HAL_SET_MAX_TX_POWER_REQ
+ */
+typedef struct sMaxTxPowerParams {
+	struct qdf_mac_addr bssId;
+	struct qdf_mac_addr selfStaMacAddr;
+	/* In request,
+	 * power == MaxTx power to be used.
+	 * In response,
+	 * power == tx power used for management frames.
+	 */
+	int8_t power;
+	enum QDF_OPMODE dev_mode;
+} tMaxTxPowerParams, *tpMaxTxPowerParams;
+
+/**
+ * struct tMaxTxPowerPerBandParams - max tx power per band info
+ * @bandInfo: band info
+ * @power: power in dbm
+ */
+typedef struct sMaxTxPowerPerBandParams {
+	enum band_info bandInfo;
+	int8_t power;
+} tMaxTxPowerPerBandParams, *tpMaxTxPowerPerBandParams;
+
+/**
+ * struct add_sta_self_params - Add Sta Self params
+ * @self_mac_addr: self MAC Address
+ * @curr_device_mode: operating device mode
+ * @type: Vdev Type
+ * @sub_type: Vdev Sub Type
+ * @session_id: SME Session ID
+ * @nss_2g: vdev nss in 2.4G
+ * @nss_5g: vdev nss in 5G
+ * @status: response status code
+ * @tx_aggregation_size: Tx aggregation size
+ * @rx_aggregation_size: Rx aggregation size
+ * @enable_bcast_probe_rsp: enable broadcast probe response
+ * @fils_max_chan_guard_time: FILS max channel guard time
+ * @pkt_err_disconn_th: packet drop threshold
+ * @tx_aggr_sw_retry_threshold_be: aggr sw retry threshold for be
+ * @tx_aggr_sw_retry_threshold_bk: aggr sw retry threshold for bk
+ * @tx_aggr_sw_retry_threshold_vi: aggr sw retry threshold for vi
+ * @tx_aggr_sw_retry_threshold_vo: aggr sw retry threshold for vo
+ * @tx_non_aggr_sw_retry_threshold_be: non aggr sw retry threshold for be
+ * @tx_non_aggr_sw_retry_threshold_bk: non aggr sw retry threshold for bk
+ * @tx_non_aggr_sw_retry_threshold_vi: non aggr sw retry threshold for vi
+ * @tx_non_aggr_sw_retry_threshold_vo: non aggr sw retry threshold for vo
+ */
+struct add_sta_self_params {
+	tSirMacAddr self_mac_addr;
+	enum QDF_OPMODE curr_device_mode;
+	uint32_t type;
+	uint32_t sub_type;
+	uint8_t session_id;
+	uint8_t nss_2g;
+	uint8_t nss_5g;
+	uint32_t status;
+	uint32_t tx_aggregation_size;
+	uint32_t tx_aggregation_size_be;
+	uint32_t tx_aggregation_size_bk;
+	uint32_t tx_aggregation_size_vi;
+	uint32_t tx_aggregation_size_vo;
+	uint32_t rx_aggregation_size;
+	bool enable_bcast_probe_rsp;
+	uint8_t fils_max_chan_guard_time;
+	uint16_t pkt_err_disconn_th;
+	uint8_t oce_feature_bitmap;
+	uint32_t tx_aggr_sw_retry_threshold_be;
+	uint32_t tx_aggr_sw_retry_threshold_bk;
+	uint32_t tx_aggr_sw_retry_threshold_vi;
+	uint32_t tx_aggr_sw_retry_threshold_vo;
+	uint32_t tx_non_aggr_sw_retry_threshold_be;
+	uint32_t tx_non_aggr_sw_retry_threshold_bk;
+	uint32_t tx_non_aggr_sw_retry_threshold_vi;
+	uint32_t tx_non_aggr_sw_retry_threshold_vo;
+};
+
+/**
+ * struct set_ie_param - set IE params structure
+ * @pdev_id: pdev id
+ * @ie_type: IE type
+ * @nss: Nss value
+ * @ie_len: IE length
+ * @ie_ptr: Pointer to IE data
+ *
+ * Holds the set pdev IE req data.
+ */
+struct set_ie_param {
+	uint8_t pdev_id;
+	uint8_t ie_type;
+	uint8_t nss;
+	uint8_t ie_len;
+	uint8_t *ie_ptr;
+};
+
+/**
+ * struct set_dtim_params - dtim params
+ * @session_id: SME Session ID
+ * @dtim_period: dtim period
+ */
+struct set_dtim_params {
+	uint8_t session_id;
+	uint8_t dtim_period;
+};
+
+#define DOT11_HT_IE     1
+#define DOT11_VHT_IE    2
+
+#ifdef FEATURE_WLAN_TDLS
+
+#define HAL_TDLS_MAX_SUPP_CHANNELS       128
+#define HAL_TDLS_MAX_SUPP_OPER_CLASSES   32
+
+/**
+ * struct tTdlsPeerCapParams - TDLS peer capablities parameters
+ * @isPeerResponder: is peer responder or not
+ * @peerUapsdQueue: peer uapsd queue
+ * @peerMaxSp: peer max SP value
+ * @peerBuffStaSupport: peer buffer sta supported or not
+ * @peerOffChanSupport: peer offchannel support
+ * @peerCurrOperClass: peer current operating class
+ * @selfCurrOperClass: self current operating class
+ * @peerChanLen: peer channel length
+ * @peerChan: peer channel list
+ * @peerOperClassLen: peer operating class length
+ * @peerOperClass: peer operating class
+ * @prefOffChanNum: peer offchannel number
+ * @prefOffChanBandwidth: peer offchannel bandwidth
+ * @opClassForPrefOffChan: operating class for offchannel
+ */
+typedef struct {
+	uint8_t isPeerResponder;
+	uint8_t peerUapsdQueue;
+	uint8_t peerMaxSp;
+	uint8_t peerBuffStaSupport;
+	uint8_t peerOffChanSupport;
+	uint8_t peerCurrOperClass;
+	uint8_t selfCurrOperClass;
+	uint8_t peerChanLen;
+	tSirUpdateChanParam peerChan[HAL_TDLS_MAX_SUPP_CHANNELS];
+	uint8_t peerOperClassLen;
+	uint8_t peerOperClass[HAL_TDLS_MAX_SUPP_OPER_CLASSES];
+	uint8_t prefOffChanNum;
+	uint8_t prefOffChanBandwidth;
+	uint8_t opClassForPrefOffChan;
+} tTdlsPeerCapParams;
+
+/**
+ * struct tTdlsPeerStateParams - TDLS peer state parameters
+ * @vdevId: vdev id
+ * @peerMacAddr: peer mac address
+ * @peerCap: peer capabality
+ */
+typedef struct sTdlsPeerStateParams {
+	uint32_t vdevId;
+	tSirMacAddr peerMacAddr;
+	uint32_t peerState;
+	tTdlsPeerCapParams peerCap;
+	bool resp_reqd;
+} tTdlsPeerStateParams;
+
+/**
+ * struct tdls_chan_switch_params - channel switch parameter structure
+ * @vdev_id: vdev ID
+ * @peer_mac_addr: Peer mac address
+ * @tdls_off_ch_bw_offset: Target off-channel bandwitdh offset
+ * @tdls_off_ch: Target Off Channel
+ * @oper_class: Operating class for target channel
+ * @is_responder: Responder or initiator
+ */
+typedef struct tdls_chan_switch_params_struct {
+	uint32_t    vdev_id;
+	tSirMacAddr peer_mac_addr;
+	uint16_t    tdls_off_ch_bw_offset;
+	uint8_t     tdls_off_ch;
+	uint8_t     tdls_sw_mode;
+	uint8_t     oper_class;
+	uint8_t     is_responder;
+} tdls_chan_switch_params;
+
+#endif /* FEATURE_WLAN_TDLS */
+
+/**
+ * struct tAbortScanParams - Abort scan parameters
+ * @SessionId: PE session id
+ * @scan_id: Scan ID used for original scan request
+ * @scan_requestor_id: Scan requesting entity
+ */
+typedef struct sAbortScanParams {
+	uint8_t SessionId;
+	uint32_t scan_id;
+	uint32_t scan_requestor_id;
+} tAbortScanParams, *tpAbortScanParams;
+
+/**
+ * struct del_sta_self_params - Del Sta Self params
+ * @session_id: SME Session ID
+ * @status: response status code
+ * @sme_callback: callback to be called from WMA to SME
+ * @sme_ctx: pointer to context provided by SME
+ */
+struct del_sta_self_params {
+	tSirMacAddr self_mac_addr;
+	uint8_t session_id;
+	uint32_t status;
+	csr_session_close_cb sme_callback;
+	void *sme_ctx;
+};
+
+/**
+ * struct del_sta_self_rsp_params - Del Sta Self response params
+ * @self_sta_param: sta params
+ * @generate_rsp: generate response to upper layers
+ */
+struct del_sta_self_rsp_params {
+	struct del_sta_self_params *self_sta_param;
+	uint8_t generate_rsp;
+};
+
+/**
+ * struct tP2pPsParams - P2P powersave related params
+ * @opp_ps: opportunistic power save
+ * @ctWindow: CT window
+ * @count: count
+ * @duration: duration
+ * @interval: interval
+ * @single_noa_duration: single shot noa duration
+ * @psSelection: power save selection
+ * @sessionId: session id
+ */
+typedef struct sP2pPsParams {
+	uint8_t opp_ps;
+	uint32_t ctWindow;
+	uint8_t count;
+	uint32_t duration;
+	uint32_t interval;
+	uint32_t single_noa_duration;
+	uint8_t psSelection;
+	uint8_t sessionId;
+} tP2pPsParams, *tpP2pPsParams;
+
+/**
+ * struct tTdlsLinkEstablishParams - TDLS Link establish parameters
+ * @staIdx: station index
+ * @isResponder: responder flag
+ * @uapsdQueues: uapsd queue
+ * @maxSp: max SP period
+ * @isBufsta: is station flag
+ * @isOffChannelSupported: offchannel supported or not
+ * @peerCurrOperClass: peer current operating class
+ * @selfCurrOperClass: self current operating class
+ * @validChannelsLen: valid channel length
+ * @validChannels: valid channels
+ * @validOperClassesLen: valid operating class length
+ * @validOperClasses: valid operating class
+ * @status: return status of command
+ */
+typedef struct sTdlsLinkEstablishParams {
+	uint16_t staIdx;
+	uint8_t isResponder;
+	uint8_t uapsdQueues;
+	uint8_t maxSp;
+	uint8_t isBufsta;
+	uint8_t isOffChannelSupported;
+	uint8_t peerCurrOperClass;
+	uint8_t selfCurrOperClass;
+	uint8_t validChannelsLen;
+	uint8_t validChannels[HAL_MAX_SUPP_CHANNELS];
+	uint8_t validOperClassesLen;
+	uint8_t validOperClasses[HAL_MAX_SUPP_OPER_CLASSES];
+	uint32_t status;
+} tTdlsLinkEstablishParams, *tpTdlsLinkEstablishParams;
+
+/**
+ * struct tHalHiddenSsidVdevRestart - hidden ssid vdev restart params
+ * @ssidHidden: is hidden ssid or not
+ * @sessionId: session id
+ */
+typedef struct tHalHiddenSsidVdevRestart {
+	uint8_t ssidHidden;
+	uint8_t sessionId;
+	uint16_t pe_session_id;
+} tHalHiddenSsidVdevRestart, *tpHalHiddenSsidVdevRestart;
+
+
+extern void sys_process_mmh_msg(tpAniSirGlobal pMac,
+				struct scheduler_msg *pMsg);
+
+/**
+ * struct tBeaconFilterMsg - Beacon Filtering data structure
+ * @capabilityInfo: capability info
+ * @capabilityMask: capabality mask
+ * @beaconInterval: beacon interval
+ * @ieNum: IE number
+ * @reserved: reserved
+ */
+typedef struct sBeaconFilterMsg {
+	uint16_t capabilityInfo;
+	uint16_t capabilityMask;
+	uint16_t beaconInterval;
+	uint16_t ieNum;
+	uint8_t bssIdx;
+	uint8_t reserved;
+} qdf_packed tBeaconFilterMsg, *tpBeaconFilterMsg;
+
+/**
+ * struct tEidByteInfo - Eid byte info
+ * @offset: offset
+ * @value: value
+ * @bitMask: BIT mask
+ * @ref: reference
+ */
+typedef struct sEidByteInfo {
+	uint8_t offset;
+	uint8_t value;
+	uint8_t bitMask;
+	uint8_t ref;
+} qdf_packed tEidByteInfo, *tpEidByteInfo;
+
+/**
+ * struct tBeaconFilterIe - beacon filter IE
+ * @elementId: element IE
+ * @checkIePresence: check IE presence
+ * @byte: Eid byte info
+ */
+typedef struct sBeaconFilterIe {
+	uint8_t elementId;
+	uint8_t checkIePresence;
+	tEidByteInfo byte;
+} qdf_packed tBeaconFilterIe, *tpBeaconFilterIe;
+
+/**
+ * struct tDisableIntraBssFwd - intra bss forward parameters
+ * @sessionId: session id
+ * @disableintrabssfwd: disable intra bss forward flag
+ */
+typedef struct sDisableIntraBssFwd {
+	uint16_t sessionId;
+	bool disableintrabssfwd;
+} qdf_packed tDisableIntraBssFwd, *tpDisableIntraBssFwd;
+
+#ifdef WLAN_FEATURE_STATS_EXT
+/**
+ * struct tStatsExtRequest - ext stats request
+ * @vdev_id: vdev id
+ * @request_data_len: request data length
+ * @request_data: request data
+ */
+typedef struct sStatsExtRequest {
+	uint32_t vdev_id;
+	uint32_t request_data_len;
+	uint8_t request_data[];
+} tStatsExtRequest, *tpStatsExtRequest;
+#endif /* WLAN_FEATURE_STATS_EXT */
+
+#ifdef WLAN_FEATURE_NAN
+/**
+ * struct tNanRequest - NAN request params
+ * @request_data_len: request data length
+ * @request_data: request data
+ */
+typedef struct sNanRequest {
+	uint16_t request_data_len;
+	uint8_t request_data[];
+} tNanRequest, *tpNanRequest;
+#endif /* WLAN_FEATURE_NAN */
+
+#endif /* _HALMSGAPI_H_ */
diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h
new file mode 100644
index 0000000..907723c
--- /dev/null
+++ b/core/wma/inc/wma_internal.h
@@ -0,0 +1,1593 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#ifndef WMA_INTERNAL_H
+#define WMA_INTERNAL_H
+#include <cdp_txrx_handle.h>
+#if !defined(REMOVE_PKT_LOG)
+#include "pktlog_ac.h"
+#endif
+
+/* ################### defines ################### */
+/*
+ * TODO: Following constant should be shared by firwmare in
+ * wmi_unified.h. This will be done once wmi_unified.h is updated.
+ */
+#define WMI_PEER_STATE_AUTHORIZED 0x2
+
+#define WMA_2_4_GHZ_MAX_FREQ  3000
+#define WOW_CSA_EVENT_OFFSET 12
+
+#define WMA_DEFAULT_SCAN_REQUESTER_ID        1
+#define WMI_SCAN_FINISH_EVENTS (WMI_SCAN_EVENT_START_FAILED | \
+				WMI_SCAN_EVENT_COMPLETED | \
+				WMI_SCAN_EVENT_DEQUEUED)
+/* default value */
+#define DEFAULT_INFRA_STA_KEEP_ALIVE_PERIOD  20
+#define DEFAULT_STA_SA_QUERY_MAX_RETRIES_COUNT       (5)
+#define DEFAULT_STA_SA_QUERY_RETRY_INTERVAL    (200)
+
+/* pdev vdev and peer stats*/
+#define FW_PDEV_STATS_SET 0x1
+#define FW_VDEV_STATS_SET 0x2
+#define FW_PEER_STATS_SET 0x4
+#define FW_RSSI_PER_CHAIN_STATS_SET 0x8
+#define FW_STATS_SET 0xf
+
+/*AR9888/AR6320  noise floor approx value
+ * similar to the mentioned the WMA
+ */
+#define WMA_TGT_NOISE_FLOOR_DBM (-96)
+#define WMA_TGT_MAX_SNR         (WMA_TGT_NOISE_FLOOR_DBM * (-1))
+
+/*
+ * Make sure that link monitor and keep alive
+ * default values should be in sync with CFG.
+ */
+#define WMA_LINK_MONITOR_DEFAULT_TIME_SECS 10
+#define WMA_KEEP_ALIVE_DEFAULT_TIME_SECS   5
+
+#define AGC_DUMP  1
+#define CHAN_DUMP 2
+#define WD_DUMP   3
+#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
+#define PCIE_DUMP 4
+#endif
+
+/* conformance test limits */
+#define FCC       0x10
+#define MKK       0x40
+#define ETSI      0x30
+
+#define WMI_DEFAULT_NOISE_FLOOR_DBM (-96)
+
+#define WMI_MCC_MIN_CHANNEL_QUOTA             20
+#define WMI_MCC_MAX_CHANNEL_QUOTA             80
+#define WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY  30
+
+/* The maximum number of patterns that can be transmitted by the firmware
+ *  and maximum patterns size.
+ */
+#ifndef WMA_MAXNUM_PERIODIC_TX_PTRNS
+#define WMA_MAXNUM_PERIODIC_TX_PTRNS 6
+#endif
+
+#define WMI_MAX_HOST_CREDITS 2
+#define WMI_WOW_REQUIRED_CREDITS 1
+
+#define WMI_MAX_MHF_ENTRIES 32
+
+
+#define MAX_HT_MCS_IDX 8
+#define MAX_VHT_MCS_IDX 10
+#define INVALID_MCS_IDX 255
+
+#define LINK_STATUS_LEGACY      0
+#define LINK_STATUS_VHT         0x1
+#define LINK_STATUS_MIMO        0x2
+#define LINK_SUPPORT_VHT	0x4
+#define LINK_SUPPORT_MIMO	0x8
+
+#define LINK_RATE_VHT           0x3
+
+#define MAX_ENTRY_HOLD_REQ_QUEUE 2
+#define MAX_ENTRY_VDEV_RESP_QUEUE 10
+
+/* Time(in ms) to detect DOS attack */
+#define WMA_MGMT_FRAME_DETECT_DOS_TIMER 1000
+
+#define MAX_NUM_HW_MODE    0xff
+#define MAX_NUM_PHY        0xff
+
+/**
+ * struct index_data_rate_type - non vht data rate type
+ * @mcs_index: mcs rate index
+ * @ht20_rate: HT20 supported rate table
+ * @ht40_rate: HT40 supported rate table
+ */
+struct index_data_rate_type {
+	uint8_t  mcs_index;
+	uint16_t ht20_rate[2];
+	uint16_t ht40_rate[2];
+};
+
+/**
+ * struct index_vht_data_rate_type - vht data rate type
+ * @mcs_index: mcs rate index
+ * @ht20_rate: VHT20 supported rate table
+ * @ht40_rate: VHT40 supported rate table
+ * @ht80_rate: VHT80 supported rate table
+ */
+struct index_vht_data_rate_type {
+	uint8_t mcs_index;
+	uint16_t ht20_rate[2];
+	uint16_t ht40_rate[2];
+	uint16_t ht80_rate[2];
+};
+
+struct wifi_scan_cmd_req_params;
+/*
+ * wma_main.c functions declarations
+ */
+
+int
+wmi_unified_pdev_set_param(wmi_unified_t wmi_handle, WMI_PDEV_PARAM param_id,
+			   uint32_t param_value);
+
+/**
+ * wma_send_msg_by_priority() - Send wma message to PE with priority.
+ * @wma_handle: wma handle
+ * @msg_type: message type
+ * @body_ptr: message body ptr
+ * @body_val: message body value
+ * @is_high_priority: if msg is high priority
+ *
+ * Return: none
+ */
+void wma_send_msg_by_priority(tp_wma_handle wma_handle, uint16_t msg_type,
+		void *body_ptr, uint32_t body_val, bool is_high_priority);
+
+/**
+ * wma_send_msg() - Send wma message to PE.
+ * @wma_handle: wma handle
+ * @msg_type: message type
+ * @body_ptr: message body ptr
+ * @body_val: message body value
+ *
+ * Return: none
+ */
+void wma_send_msg(tp_wma_handle wma_handle, uint16_t msg_type,
+			 void *body_ptr, uint32_t body_val);
+
+/**
+ * wma_send_msg_high_priority() - Send wma message to PE with high priority.
+ * @wma_handle: wma handle
+ * @msg_type: message type
+ * @body_ptr: message body ptr
+ * @body_val: message body value
+ *
+ * Return: none
+ */
+void wma_send_msg_high_priority(tp_wma_handle wma_handle, uint16_t msg_type,
+			void *body_ptr, uint32_t body_val);
+
+void wma_data_tx_ack_comp_hdlr(void *wma_context,
+				      qdf_nbuf_t netbuf, int32_t status);
+
+QDF_STATUS wma_set_ppsconfig(uint8_t vdev_id, uint16_t pps_param,
+				    int value);
+
+/*
+ * wma_scan_roam.c functions declarations
+ */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+void wma_process_roam_invoke(WMA_HANDLE handle,
+				struct wma_roam_invoke_cmd *roaminvoke);
+
+void wma_process_roam_synch_fail(WMA_HANDLE handle,
+				 struct roam_offload_synch_fail *synch_fail);
+
+int wma_roam_synch_event_handler(void *handle, uint8_t *event,
+					uint32_t len);
+
+/**
+ * wma_roam_synch_frame_event_handler() - roam synch frame event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: length of data
+ *
+ * This function is roam synch frame event handler.
+ *
+ * Return: Success or Failure status
+ */
+int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event,
+					uint32_t len);
+#endif
+
+/**
+ * wma_update_per_roam_config() -per roam config parameter updation to FW
+ * @handle: wma handle
+ * @req_buf: per roam config parameters
+ *
+ * Return: none
+ */
+void wma_update_per_roam_config(WMA_HANDLE handle,
+				 struct wmi_per_roam_config_req *req_buf);
+
+QDF_STATUS wma_update_channel_list(WMA_HANDLE handle,
+				   tSirUpdateChanList *chan_list);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS wma_roam_scan_fill_self_caps(tp_wma_handle wma_handle,
+					roam_offload_param *
+					roam_offload_params,
+					tSirRoamOffloadScanReq *roam_req);
+#endif
+
+QDF_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle,
+				      wmi_start_scan_cmd_fixed_param *
+				      scan_cmd_fp,
+				      tSirRoamOffloadScanReq *roam_req,
+				      uint32_t mode, uint32_t vdev_id);
+
+/**
+ * wma_roam_scan_mawc_params() - send roam scan mode request to fw
+ * @wma_handle: wma handle
+ * @roam_req: roam request param
+ *
+ * Fill the MAWC roaming parameters and send
+ * WMI_ROAM_CONFIGURE_MAWC_CMDID TLV to firmware.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_roam_scan_mawc_params(tp_wma_handle wma_handle,
+		tSirRoamOffloadScanReq *roam_req);
+
+QDF_STATUS wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle,
+					     tSirRoamOffloadScanReq *roam_req);
+
+QDF_STATUS wma_roam_scan_offload_scan_period(tp_wma_handle wma_handle,
+					     uint32_t scan_period,
+					     uint32_t scan_age,
+					     uint32_t vdev_id);
+
+QDF_STATUS wma_roam_scan_offload_rssi_change(tp_wma_handle wma_handle,
+					     uint32_t vdev_id,
+					     int32_t rssi_change_thresh,
+					     uint32_t bcn_rssi_weight,
+					     uint32_t hirssi_delay_btw_scans);
+
+QDF_STATUS wma_roam_scan_offload_chan_list(tp_wma_handle wma_handle,
+					   uint8_t chan_count,
+					   uint8_t *chan_list,
+					   uint8_t list_type, uint32_t vdev_id);
+
+A_UINT32 e_csr_auth_type_to_rsn_authmode(eCsrAuthType authtype,
+					 eCsrEncryptionType encr);
+
+A_UINT32 e_csr_encryption_type_to_rsn_cipherset(eCsrEncryptionType encr);
+
+void wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle,
+				    tpAniSirGlobal pMac,
+				    tSirRoamOffloadScanReq *roam_req,
+				    wmi_start_scan_cmd_fixed_param *
+				    scan_params);
+
+QDF_STATUS wma_roam_scan_bmiss_cnt(tp_wma_handle wma_handle,
+				   A_INT32 first_bcnt,
+				   A_UINT32 final_bcnt, uint32_t vdev_id);
+
+QDF_STATUS wma_roam_scan_offload_command(tp_wma_handle wma_handle,
+					 uint32_t command, uint32_t vdev_id);
+
+QDF_STATUS wma_roam_preauth_chan_set(tp_wma_handle wma_handle,
+				     tpSwitchChannelParams params,
+				     uint8_t vdev_id);
+
+QDF_STATUS wma_roam_preauth_chan_cancel(tp_wma_handle wma_handle,
+					tpSwitchChannelParams params,
+					uint8_t vdev_id);
+
+void wma_roam_preauth_scan_event_handler(tp_wma_handle wma_handle,
+						uint8_t vdev_id,
+						wmi_scan_event_fixed_param *
+						wmi_event);
+
+void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+void wma_set_ric_req(tp_wma_handle wma, void *msg, uint8_t is_add_ts);
+#endif
+
+#ifdef FEATURE_WLAN_EXTSCAN
+
+int wma_extscan_start_stop_event_handler(void *handle,
+					 uint8_t *cmd_param_info,
+					 uint32_t len);
+
+int wma_extscan_operations_event_handler(void *handle,
+					 uint8_t *cmd_param_info,
+					 uint32_t len);
+
+int wma_extscan_table_usage_event_handler(void *handle,
+					  uint8_t *cmd_param_info,
+					  uint32_t len);
+
+int wma_extscan_capabilities_event_handler(void *handle,
+					   uint8_t *cmd_param_info,
+					   uint32_t len);
+
+int wma_extscan_hotlist_match_event_handler(void *handle,
+					    uint8_t *cmd_param_info,
+					    uint32_t len);
+
+int wma_extscan_cached_results_event_handler(void *handle,
+					     uint8_t *cmd_param_info,
+					     uint32_t len);
+
+int wma_extscan_change_results_event_handler(void *handle,
+					     uint8_t *cmd_param_info,
+					     uint32_t len);
+
+int wma_passpoint_match_event_handler(void *handle,
+				     uint8_t  *cmd_param_info,
+				     uint32_t len);
+
+#endif
+
+#ifdef FEATURE_WLAN_EXTSCAN
+int wma_extscan_wow_event_callback(void *handle, void *event, uint32_t len);
+
+void wma_register_extscan_event_handler(tp_wma_handle wma_handle);
+
+/**
+ * wma_start_extscan() - start extscan command to fw.
+ * @wma: wma handle
+ * @params: extscan command request params
+ *
+ * This function sends start extscan request to fw.
+ *
+ * Return: QDF Status.
+ */
+QDF_STATUS wma_start_extscan(tp_wma_handle wma,
+			     struct wifi_scan_cmd_req_params *pstart);
+
+/**
+ * wma_stop_extscan() - stop extscan command to fw.
+ * @wma: wma handle
+ * @params: stop scan command request params
+ *
+ * This function sends stop extscan request to fw.
+ *
+ * Return: QDF Status.
+ */
+QDF_STATUS wma_stop_extscan(tp_wma_handle wma,
+			    struct extscan_stop_req_params *params);
+
+/**
+ * wma_extscan_start_hotlist_monitor() - start hotlist monitor
+ * @wma: wma handle
+ * @params: hotlist request params
+ *
+ * This function configures hotlist monitor in fw.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_extscan_start_hotlist_monitor(tp_wma_handle wma,
+			struct extscan_bssid_hotlist_set_params *params);
+
+/**
+ * wma_extscan_stop_hotlist_monitor() - stop hotlist monitor
+ * @wma: wma handle
+ * @params: hotlist request params
+ *
+ * This function configures hotlist monitor to stop in fw.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_extscan_stop_hotlist_monitor(tp_wma_handle wma,
+			struct extscan_bssid_hotlist_reset_params *params);
+
+/**
+ * wma_extscan_start_change_monitor() - send start change monitor cmd
+ * @wma: wma handle
+ * @params: change monitor request params
+ *
+ * This function sends start change monitor request to fw.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+wma_extscan_start_change_monitor(tp_wma_handle wma,
+			struct extscan_set_sig_changereq_params *params);
+
+/**
+ * wma_extscan_stop_change_monitor() - send stop change monitor cmd
+ * @wma: wma handle
+ * @params: change monitor request params
+ *
+ * This function sends stop change monitor request to fw.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+wma_extscan_stop_change_monitor(tp_wma_handle wma,
+			struct extscan_capabilities_reset_params *params);
+
+/**
+ * wma_extscan_get_cached_results() - extscan get cached results
+ * @wma: wma handle
+ * @params: cached results parameters
+ *
+ * This function send request to fw to get cached results.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+wma_extscan_get_cached_results(tp_wma_handle wma,
+			       struct extscan_cached_result_params *params);
+
+/**
+ * wma_extscan_get_capabilities() - extscan get capabilities
+ * @wma: wma handle
+ * @params: get capabilities params
+ *
+ * This function sends request to fw to get extscan capabilities.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+wma_extscan_get_capabilities(tp_wma_handle wma,
+			     struct extscan_capabilities_params *params);
+
+/**
+ * wma_set_epno_network_list() - set epno network list
+ * @wma: WMA handle
+ * @req: epno config params request structure
+ *
+ * This function reads the incoming epno config request structure
+ * and constructs the WMI message to the firmware.
+ *
+ * Return: 0 on success, error number otherwise
+ */
+QDF_STATUS wma_set_epno_network_list(tp_wma_handle wma,
+				     struct wifi_enhanced_pno_params *req);
+
+/**
+ * wma_set_passpoint_network_list() - set passpoint network list
+ * @wma: WMA handle
+ * @params: passpoint network request structure
+ *
+ * This function sends the passpoint configs down to the firmware
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS
+wma_set_passpoint_network_list(tp_wma_handle wma,
+			       struct wifi_passpoint_req_param *params);
+
+/**
+ * wma_reset_passpoint_network_list() - reset passpoint network list
+ * @wma: WMA handle
+ * @params: passpoint network request structure
+ *
+ * This function sends down WMI command with network id set to wildcard id.
+ * firmware shall clear all the config entries
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS
+wma_reset_passpoint_network_list(tp_wma_handle wma,
+				 struct wifi_passpoint_req_param *params);
+#endif
+
+QDF_STATUS wma_scan_probe_setoui(tp_wma_handle wma, tSirScanMacOui *psetoui);
+
+int wma_scan_event_callback(WMA_HANDLE handle, uint8_t *data, uint32_t len);
+
+void wma_roam_better_ap_handler(tp_wma_handle wma, uint32_t vdev_id);
+
+int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf,
+			    uint32_t len);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id);
+static inline bool wma_is_roam_synch_in_progress(tp_wma_handle wma,
+		uint8_t vdev_id)
+{
+	return wma->interfaces[vdev_id].roam_synch_in_progress;
+}
+#else
+static inline bool wma_is_roam_synch_in_progress(tp_wma_handle wma,
+		uint8_t vdev_id)
+{
+	return false;
+}
+static inline uint32_t wma_roam_scan_get_cckm_mode(
+		struct sSirRoamOffloadScanReq *roam_req, uint32_t auth_mode)
+{
+	return WMI_AUTH_CCKM;
+}
+#endif
+
+/*
+ * wma_dev_if.c functions declarations
+ */
+
+struct cdp_vdev *wma_find_vdev_by_addr(tp_wma_handle wma, uint8_t *addr,
+				   uint8_t *vdev_id);
+
+/**
+ * wma_find_vdev_by_id() - Returns vdev handle for given vdev id.
+ * @wma - wma handle
+ * @vdev_id - vdev ID
+ *
+ * Return: Returns vdev handle if given vdev id is valid.
+ *         Otherwise returns NULL.
+ */
+static inline
+struct cdp_vdev *wma_find_vdev_by_id(tp_wma_handle wma, uint8_t vdev_id)
+{
+	if (vdev_id >= wma->max_bssid)
+		return NULL;
+
+	return wma->interfaces[vdev_id].handle;
+}
+
+bool wma_is_vdev_in_ap_mode(tp_wma_handle wma, uint8_t vdev_id);
+
+#ifdef QCA_IBSS_SUPPORT
+bool wma_is_vdev_in_ibss_mode(tp_wma_handle wma, uint8_t vdev_id);
+#else
+/**
+ * wma_is_vdev_in_ibss_mode(): dummy function
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return false since no vdev can be in ibss mode without ibss support
+ */
+static inline
+bool wma_is_vdev_in_ibss_mode(tp_wma_handle wma, uint8_t vdev_id)
+{
+	return false;
+}
+#endif
+
+/**
+ * wma_find_bssid_by_vdev_id() - Get the BSS ID corresponding to the vdev ID
+ * @wma - wma handle
+ * @vdev_id - vdev ID
+ *
+ * Return: Returns pointer to bssid on success,
+ *         otherwise returns NULL.
+ */
+static inline uint8_t *wma_find_bssid_by_vdev_id(tp_wma_handle wma,
+						 uint8_t vdev_id)
+{
+	if (vdev_id >= wma->max_bssid)
+		return NULL;
+
+	return wma->interfaces[vdev_id].bssid;
+}
+
+struct cdp_vdev *wma_find_vdev_by_bssid(tp_wma_handle wma, uint8_t *bssid,
+				    uint8_t *vdev_id);
+
+QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
+			struct del_sta_self_params *pdel_sta_self_req_param,
+			uint8_t generateRsp);
+
+int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
+				       uint32_t len);
+
+QDF_STATUS wma_vdev_set_param(wmi_unified_t wmi_handle, uint32_t if_id,
+				uint32_t param_id, uint32_t param_value);
+
+QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *bssid,
+			   uint8_t vdev_id, void *peer,
+			   bool roam_synch_in_progress);
+
+QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev,
+			  struct cdp_vdev *vdev,
+			  uint8_t peer_addr[IEEE80211_ADDR_LEN],
+			  uint32_t peer_type, uint8_t vdev_id,
+			  bool roam_synch_in_progress);
+
+/**
+ * wma_send_del_bss_response() - send delete bss resp
+ * @wma: wma handle
+ * @req: target request
+ *
+ * Return: none
+ */
+void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req);
+
+/**
+ * wma_send_set_link_response() - send set link response
+ * @wma: wma handle
+ * @req: target request
+ *
+ * Return: none
+ */
+void wma_send_set_link_response(tp_wma_handle wma, struct wma_target_req *req);
+
+/**
+ * __wma_vdev_stop_resp_handler() - vdev stop response handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: buffer length
+ *
+ * Return: QDF_STATUS_SUCCESS for success or QDF_ERROR code
+ */
+QDF_STATUS
+__wma_vdev_stop_resp_handler(wmi_vdev_stopped_event_fixed_param *resp_event);
+
+/**
+ * wma_vdev_stop_resp_handler() - vdev stop response handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
+				      uint32_t len);
+
+struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
+				struct add_sta_self_params *self_sta_req,
+				uint8_t generateRsp);
+
+QDF_STATUS wma_vdev_start(tp_wma_handle wma, struct wma_vdev_start_req *req,
+			  bool isRestart);
+
+void wma_vdev_resp_timer(void *data);
+
+struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma,
+						uint8_t vdev_id,
+						uint32_t msg_type, uint8_t type,
+						void *params, uint32_t timeout);
+
+void wma_hold_req_timer(void *data);
+struct wma_target_req *wma_fill_hold_req(tp_wma_handle wma,
+				    uint8_t vdev_id, uint32_t msg_type,
+				    uint8_t type, void *params,
+				    uint32_t timeout);
+
+void wma_remove_vdev_req(tp_wma_handle wma, uint8_t vdev_id,
+				uint8_t type);
+
+void wma_add_bss(tp_wma_handle wma, tpAddBssParams params);
+
+void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta);
+
+void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta);
+
+void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params);
+
+int32_t wma_find_vdev_by_type(tp_wma_handle wma, int32_t type);
+
+void wma_set_vdev_intrabss_fwd(tp_wma_handle wma_handle,
+				      tpDisableIntraBssFwd pdis_intra_fwd);
+
+void wma_delete_bss_ho_fail(tp_wma_handle wma, tpDeleteBssParams params);
+
+uint32_t wma_get_bcn_rate_code(uint16_t rate);
+
+/*
+ * wma_mgmt.c functions declarations
+ */
+
+int wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len);
+
+int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event,
+				       uint32_t len);
+
+int wma_unified_bcntx_status_event_handler(void *handle,
+					   uint8_t *cmd_param_info,
+					   uint32_t len);
+
+void wma_set_sta_sa_query_param(tp_wma_handle wma,
+				  uint8_t vdev_id);
+
+void wma_set_sta_keep_alive(tp_wma_handle wma, uint8_t vdev_id,
+				   uint32_t method, uint32_t timeperiod,
+				   uint8_t *hostv4addr, uint8_t *destv4addr,
+				   uint8_t *destmac);
+
+int wma_vdev_install_key_complete_event_handler(void *handle,
+						uint8_t *event,
+						uint32_t len);
+
+QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma,
+					   tSirNwType nw_type,
+					   tpAddStaParams params);
+
+QDF_STATUS wmi_unified_vdev_set_gtx_cfg_send(wmi_unified_t wmi_handle,
+				  uint32_t if_id,
+				  gtx_config_t *gtx_info);
+
+void wma_update_protection_mode(tp_wma_handle wma, uint8_t vdev_id,
+			   uint8_t llbcoexist);
+
+void wma_process_update_beacon_params(tp_wma_handle wma,
+				 tUpdateBeaconParams *bcn_params);
+
+void wma_update_rts_params(tp_wma_handle wma, uint32_t value);
+
+void wma_update_frag_params(tp_wma_handle wma, uint32_t value);
+
+void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info);
+
+void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma,
+				      uint8_t vdev_id,
+				      int8_t peer_num_delta);
+
+void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info);
+
+QDF_STATUS wma_process_update_edca_param_req(WMA_HANDLE handle,
+						    tEdcaParams *edca_params);
+
+int wma_tbttoffset_update_event_handler(void *handle, uint8_t *event,
+					       uint32_t len);
+
+void wma_send_probe_rsp_tmpl(tp_wma_handle wma,
+				    tpSendProbeRespParams probe_rsp_info);
+
+/**
+ * wma_set_ap_vdev_up() - send vdev up req
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_set_ap_vdev_up(tp_wma_handle wma, uint8_t vdev_id);
+
+void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info);
+
+void wma_set_keepalive_req(tp_wma_handle wma,
+				  tSirKeepAliveReq *keepalive);
+
+void wma_beacon_miss_handler(tp_wma_handle wma, uint32_t vdev_id,
+			     int32_t rssi);
+
+void wma_process_update_opmode(tp_wma_handle wma_handle,
+				      tUpdateVHTOpMode *update_vht_opmode);
+
+void wma_process_update_rx_nss(tp_wma_handle wma_handle,
+				      tUpdateRxNss *update_rx_nss);
+
+void wma_process_update_membership(tp_wma_handle wma_handle,
+					  tUpdateMembership *membership);
+
+void wma_process_update_userpos(tp_wma_handle wma_handle,
+				       tUpdateUserPos *userpos);
+
+void wma_hidden_ssid_vdev_restart(tp_wma_handle wma_handle,
+				  tHalHiddenSsidVdevRestart *pReq);
+
+/*
+ * wma_power.c functions declarations
+ */
+
+void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req);
+
+QDF_STATUS wma_unified_set_sta_ps_param(wmi_unified_t wmi_handle,
+					    uint32_t vdev_id, uint32_t param,
+					    uint32_t value);
+
+QDF_STATUS
+wma_set_ibss_pwrsave_params(tp_wma_handle wma, uint8_t vdev_id);
+
+QDF_STATUS wma_set_ap_peer_uapsd(tp_wma_handle wma, uint32_t vdev_id,
+				     uint8_t *peer_addr, uint8_t uapsd_value,
+				     uint8_t max_sp);
+
+void wma_update_edca_params_for_ac(tSirMacEdcaParamRecord *edca_param,
+				   struct wmi_host_wme_vparams *wmm_param,
+				   int ac, bool mu_edca_param);
+
+void wma_set_tx_power(WMA_HANDLE handle,
+			     tMaxTxPowerParams *tx_pwr_params);
+
+void wma_set_max_tx_power(WMA_HANDLE handle,
+				 tMaxTxPowerParams *tx_pwr_params);
+
+void wma_disable_sta_ps_mode(tp_wma_handle wma, tpDisablePsParams ps_req);
+
+void wma_enable_uapsd_mode(tp_wma_handle wma, tpEnableUapsdParams ps_req);
+
+void wma_disable_uapsd_mode(tp_wma_handle wma, tpDisableUapsdParams ps_req);
+
+QDF_STATUS wma_get_temperature(tp_wma_handle wma_handle);
+
+int wma_pdev_temperature_evt_handler(void *handle, uint8_t *event,
+					    uint32_t len);
+
+QDF_STATUS wma_process_tx_power_limits(WMA_HANDLE handle,
+				       tSirTxPowerLimit *ptxlim);
+
+void wma_update_noa(struct beacon_info *beacon,
+			   struct p2p_sub_element_noa *noa_ie);
+
+void wma_update_probe_resp_noa(tp_wma_handle wma_handle,
+				      struct p2p_sub_element_noa *noa_ie);
+
+int wma_p2p_noa_event_handler(void *handle, uint8_t *event,
+				     uint32_t len);
+
+void wma_process_set_mimops_req(tp_wma_handle wma_handle,
+				       tSetMIMOPS *mimops);
+
+QDF_STATUS wma_set_mimops(tp_wma_handle wma, uint8_t vdev_id, int value);
+
+QDF_STATUS wma_notify_modem_power_state(void *wma_ptr,
+					tSirModemPowerStateInd *pReq);
+
+QDF_STATUS wma_set_smps_params(tp_wma_handle wma, uint8_t vdev_id,
+				      int value);
+
+/*
+ * wma_data.c functions declarations
+ */
+
+void wma_set_bss_rate_flags(tp_wma_handle wma, uint8_t vdev_id,
+			    tpAddBssParams add_bss);
+
+int32_t wmi_unified_send_txbf(tp_wma_handle wma, tpAddStaParams params);
+
+/**
+ * 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,
+					       uint32_t len);
+
+QDF_STATUS wma_set_enable_disable_mcc_adaptive_scheduler(uint32_t
+						mcc_adaptive_scheduler);
+
+QDF_STATUS wma_set_mcc_channel_time_latency
+	(tp_wma_handle wma,
+	uint32_t mcc_channel, uint32_t mcc_channel_time_latency);
+
+QDF_STATUS wma_set_mcc_channel_time_quota
+	(tp_wma_handle wma,
+	uint32_t adapter_1_chan_number,
+	uint32_t adapter_1_quota, uint32_t adapter_2_chan_number);
+
+void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params);
+
+QDF_STATUS wma_process_rate_update_indicate(tp_wma_handle wma,
+					    tSirRateUpdateInd *
+					    pRateUpdateParams);
+
+QDF_STATUS wma_tx_attach(tp_wma_handle wma_handle);
+
+QDF_STATUS wma_tx_detach(tp_wma_handle wma_handle);
+
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \
+	defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(CONFIG_HL_SUPPORT)
+
+int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event,
+					     uint32_t len);
+#endif
+
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
+QDF_STATUS wma_process_init_bad_peer_tx_ctl_info(tp_wma_handle wma,
+					struct t_bad_peer_txtcl_config *config);
+#else
+static inline QDF_STATUS
+wma_process_init_bad_peer_tx_ctl_info(tp_wma_handle wma,
+			struct t_bad_peer_txtcl_config *config)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+#endif
+
+QDF_STATUS wma_process_init_thermal_info(tp_wma_handle wma,
+					 t_thermal_mgmt *pThermalParams);
+
+QDF_STATUS wma_process_set_thermal_level(tp_wma_handle wma,
+					 uint8_t thermal_level);
+
+QDF_STATUS wma_set_thermal_mgmt(tp_wma_handle wma_handle,
+				       t_thermal_cmd_params thermal_info);
+
+int wma_thermal_mgmt_evt_handler(void *handle, uint8_t *event,
+					uint32_t len);
+
+int wma_ibss_peer_info_event_handler(void *handle, uint8_t *data,
+					    uint32_t len);
+
+int wma_fast_tx_fail_event_handler(void *handle, uint8_t *data,
+					  uint32_t len);
+
+/*
+ * wma_utils.c functions declarations
+ */
+
+#ifdef WLAN_FEATURE_STATS_EXT
+int wma_stats_ext_event_handler(void *handle, uint8_t *event_buf,
+				       uint32_t len);
+#endif
+
+enum eSmpsModeValue host_map_smps_mode(A_UINT32 fw_smps_mode);
+int wma_smps_mode_to_force_mode_param(uint8_t smps_mode);
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+void wma_register_ll_stats_event_handler(tp_wma_handle wma_handle);
+
+QDF_STATUS wma_process_ll_stats_clear_req
+	(tp_wma_handle wma, const tpSirLLStatsClearReq clearReq);
+
+QDF_STATUS wma_process_ll_stats_set_req
+	(tp_wma_handle wma, const tpSirLLStatsSetReq setReq);
+
+QDF_STATUS wma_process_ll_stats_get_req
+	(tp_wma_handle wma, const tpSirLLStatsGetReq getReq);
+
+int wma_unified_link_iface_stats_event_handler(void *handle,
+					       uint8_t *cmd_param_info,
+					       uint32_t len);
+void wma_config_stats_ext_threshold(tp_wma_handle wma,
+				    struct sir_ll_ext_stats_threshold *thresh);
+#endif
+
+void wma_post_link_status(tAniGetLinkStatus *pGetLinkStatus,
+			  uint8_t link_status);
+
+int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info,
+				  uint32_t len);
+
+/**
+ * wma_rso_cmd_status_event_handler() - RSO Command status event handler
+ * @wmi_event: WMI event
+ *
+ * This function is used to send RSO command status to upper layer
+ *
+ * Return: 0 for success
+ */
+int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event);
+
+int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info,
+			    uint32_t len);
+
+QDF_STATUS wma_send_link_speed(uint32_t link_speed);
+
+int wma_link_speed_event_handler(void *handle, uint8_t *cmd_param_info,
+				 uint32_t len);
+
+QDF_STATUS wma_wni_cfg_dnld(tp_wma_handle wma_handle);
+
+int wma_unified_debug_print_event_handler(void *handle, uint8_t *datap,
+					  uint32_t len);
+
+bool wma_is_sap_active(tp_wma_handle wma_handle);
+
+bool wma_is_p2p_go_active(tp_wma_handle wma_handle);
+
+bool wma_is_p2p_cli_active(tp_wma_handle wma_handle);
+
+bool wma_is_sta_active(tp_wma_handle wma_handle);
+
+WLAN_PHY_MODE wma_peer_phymode(tSirNwType nw_type, uint8_t sta_type,
+			       uint8_t is_ht, uint8_t ch_width,
+			       uint8_t is_vht, bool is_he);
+
+int32_t wma_txrx_fw_stats_reset(tp_wma_handle wma_handle,
+				uint8_t vdev_id, uint32_t value);
+
+int32_t wma_set_txrx_fw_stats_level(tp_wma_handle wma_handle,
+				    uint8_t vdev_id, uint32_t value);
+
+#ifdef QCA_SUPPORT_CP_STATS
+static inline void wma_get_stats_req(WMA_HANDLE handle,
+				struct sAniGetPEStatsReq *get_stats_param) {}
+#else
+void wma_get_stats_req(WMA_HANDLE handle,
+		       struct sAniGetPEStatsReq *get_stats_param);
+#endif
+/*
+ * wma_features.c functions declarations
+ */
+
+/**
+ * wma_sar_register_event_handlers() - Register SAR event handlers
+ * @handle: WMA Handle
+ *
+ * Function to be called during WMA initialization to register SAR
+ * event handlers with WMI
+ *
+ * Return: QDF_STATUS_SUCCESS if registration is successful, otherwise
+ *         an error enumeration
+ */
+QDF_STATUS wma_sar_register_event_handlers(WMA_HANDLE handle);
+
+void wma_process_link_status_req(tp_wma_handle wma,
+				 tAniGetLinkStatus *pGetLinkStatus);
+
+QDF_STATUS wma_get_peer_info(WMA_HANDLE handle,
+				struct sir_peer_info_req *peer_info_req);
+
+/**
+ * wma_get_peer_info_ext() - get peer info
+ * @handle: wma interface
+ * @peer_info_req: get peer info request information
+ *
+ * This function will send WMI_REQUEST_PEER_STATS_INFO_CMDID to FW
+ *
+ * Return: 0 on success, otherwise error value
+ */
+QDF_STATUS wma_get_peer_info_ext(WMA_HANDLE handle,
+				struct sir_peer_info_ext_req *peer_info_req);
+
+/**
+ * wma_peer_info_event_handler() - Handler for WMI_PEER_STATS_INFO_EVENTID
+ * @handle: WMA global handle
+ * @cmd_param_info: Command event data
+ * @len: Length of cmd_param_info
+ *
+ * This function will handle WMI_PEER_STATS_INFO_EVENTID
+ *
+ * Return: 0 on success, error code otherwise
+ */
+int wma_peer_info_event_handler(void *handle, u_int8_t *cmd_param_info,
+				   u_int32_t len);
+
+int wma_profile_data_report_event_handler(void *handle, uint8_t *event_buf,
+				       uint32_t len);
+
+QDF_STATUS wma_unified_fw_profiling_cmd(wmi_unified_t wmi_handle,
+				uint32_t cmd, uint32_t value1, uint32_t value2);
+
+void wma_wow_tx_complete(void *wma);
+
+int wma_unified_csa_offload_enable(tp_wma_handle wma, uint8_t vdev_id);
+
+#ifdef WLAN_FEATURE_NAN
+int wma_nan_rsp_event_handler(void *handle, uint8_t *event_buf, uint32_t len);
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+int wma_tdls_event_handler(void *handle, uint8_t *event, uint32_t len);
+#endif
+
+int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len);
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+int wma_oem_data_response_handler(void *handle, uint8_t *datap,
+				  uint32_t len);
+#endif
+
+#if !defined(REMOVE_PKT_LOG)
+QDF_STATUS wma_pktlog_wmi_send_cmd(WMA_HANDLE handle,
+				   struct ath_pktlog_wmi_params *params);
+#endif
+
+int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
+				     uint32_t len);
+
+int wma_d0_wow_disable_ack_event(void *handle, uint8_t *event, uint32_t len);
+
+int wma_pdev_resume_event_handler(void *handle, uint8_t *event, uint32_t len);
+
+void wma_del_ts_req(tp_wma_handle wma, tDelTsParams *msg);
+
+void wma_aggr_qos_req(tp_wma_handle wma,
+			     tAggrAddTsParams *pAggrQosRspMsg);
+
+void wma_add_ts_req(tp_wma_handle wma, tAddTsParams *msg);
+
+#ifdef FEATURE_WLAN_ESE
+QDF_STATUS wma_process_tsm_stats_req(tp_wma_handle wma_handler,
+				     void *pTsmStatsMsg);
+QDF_STATUS wma_plm_start(tp_wma_handle wma, const tpSirPlmReq plm);
+QDF_STATUS wma_plm_stop(tp_wma_handle wma, const tpSirPlmReq plm);
+void wma_config_plm(tp_wma_handle wma, tpSirPlmReq plm);
+#endif
+
+QDF_STATUS wma_process_mcbc_set_filter_req(tp_wma_handle wma_handle,
+					   tSirRcvFltMcAddrList * mcbc_param);
+QDF_STATUS wma_process_cesium_enable_ind(tp_wma_handle wma);
+
+QDF_STATUS wma_process_get_peer_info_req
+	(tp_wma_handle wma, tSirIbssGetPeerInfoReqParams *pReq);
+
+QDF_STATUS wma_process_tx_fail_monitor_ind
+	(tp_wma_handle wma, tAniTXFailMonitorInd *pReq);
+
+#ifdef FEATURE_WLAN_RMC
+QDF_STATUS wma_process_rmc_enable_ind(tp_wma_handle wma);
+
+QDF_STATUS wma_process_rmc_disable_ind(tp_wma_handle wma);
+
+QDF_STATUS wma_process_rmc_action_period_ind(tp_wma_handle wma);
+#else
+static inline
+QDF_STATUS wma_process_rmc_enable_ind(tp_wma_handle wma)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS wma_process_rmc_disable_ind(tp_wma_handle wma)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS wma_process_rmc_action_period_ind(tp_wma_handle wma)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+QDF_STATUS wma_process_add_periodic_tx_ptrn_ind(WMA_HANDLE handle,
+						tSirAddPeriodicTxPtrn *
+						pAddPeriodicTxPtrnParams);
+
+QDF_STATUS wma_process_del_periodic_tx_ptrn_ind(WMA_HANDLE handle,
+						tSirDelPeriodicTxPtrn *
+						pDelPeriodicTxPtrnParams);
+
+#ifdef WLAN_FEATURE_STATS_EXT
+QDF_STATUS wma_stats_ext_req(void *wma_ptr, tpStatsExtRequest preq);
+#endif
+
+QDF_STATUS wma_process_ibss_route_table_update_ind(void *wma_handle,
+						   tAniIbssRouteTable * pData);
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+QDF_STATUS wma_enable_ext_wow(tp_wma_handle wma, tpSirExtWoWParams params);
+
+int wma_set_app_type1_params_in_fw(tp_wma_handle wma,
+				   tpSirAppType1Params appType1Params);
+
+QDF_STATUS wma_set_app_type2_params_in_fw(tp_wma_handle wma,
+				   tpSirAppType2Params appType2Params);
+#endif
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+int wma_auto_shutdown_event_handler(void *handle, uint8_t *event,
+				    uint32_t len);
+
+QDF_STATUS wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle,
+					   tSirAutoShutdownCmdParams *
+					   auto_sh_cmd);
+#endif
+
+#ifdef WLAN_FEATURE_TSF
+int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len);
+QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id);
+QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id);
+QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin);
+#else
+static inline QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle,
+					uint32_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle,
+					 uint32_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline int wma_vdev_tsf_handler(void *handle, uint8_t *data,
+					uint32_t data_len)
+{
+	return 0;
+}
+
+static inline QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin)
+{
+	return QDF_STATUS_E_INVAL;
+}
+#endif
+QDF_STATUS wma_set_wisa_params(tp_wma_handle wma, struct sir_wisa_params *wisa);
+
+#ifdef WLAN_FEATURE_NAN
+QDF_STATUS wma_nan_req(void *wma_ptr, tpNanRequest nan_req);
+#endif
+
+#ifdef DHCP_SERVER_OFFLOAD
+int wma_process_dhcpserver_offload(tp_wma_handle wma_handle,
+				   tSirDhcpSrvOffloadInfo *
+				   pDhcpSrvOffloadInfo);
+#endif
+
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+QDF_STATUS wma_set_led_flashing(tp_wma_handle wma_handle,
+				struct flashing_req_params *flashing);
+#endif
+
+/**
+ * wma_sar_rsp_evt_handler() -  process sar response event from FW.
+ * @handle: ol scn handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_sar_rsp_evt_handler(ol_scn_t handle, uint8_t *event, uint32_t len);
+
+#ifdef FEATURE_WLAN_CH_AVOID
+QDF_STATUS wma_process_ch_avoid_update_req(tp_wma_handle wma_handle,
+					   tSirChAvoidUpdateReq *
+					   ch_avoid_update_req);
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+
+QDF_STATUS wma_update_fw_tdls_state(WMA_HANDLE handle, void *pwmaTdlsparams);
+int wma_update_tdls_peer_state(WMA_HANDLE handle,
+			       tTdlsPeerStateParams *peerStateParams);
+/**
+ * wma_set_tdls_offchan_mode() - set tdls off channel mode
+ * @handle: wma handle
+ * @chan_switch_params: Pointer to tdls channel switch parameter structure
+ *
+ * This function sets tdls off channel mode
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+QDF_STATUS wma_set_tdls_offchan_mode(WMA_HANDLE wma_handle,
+			      tdls_chan_switch_params *chan_switch_params);
+#endif
+
+void wma_set_vdev_mgmt_rate(tp_wma_handle wma, uint8_t vdev_id);
+void wma_set_sap_keepalive(tp_wma_handle wma, uint8_t vdev_id);
+
+#ifdef FEATURE_RSSI_MONITOR
+int wma_rssi_breached_event_handler(void *handle,
+				u_int8_t  *cmd_param_info, u_int32_t len);
+#else /* FEATURE_RSSI_MONITOR */
+static inline
+int wma_rssi_breached_event_handler(void *handle,
+				u_int8_t  *cmd_param_info, u_int32_t len)
+{
+	return 0;
+}
+#endif /* FEATURE_RSSI_MONITOR */
+
+QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma,
+				   struct vdev_ie_info *ie_info);
+int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info,
+				uint32_t len);
+int wma_vdev_delete_handler(void *handle, uint8_t *cmd_param_info,
+				uint32_t len);
+
+int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info,
+				uint32_t len);
+void wma_remove_req(tp_wma_handle wma, uint8_t vdev_id,
+			    uint8_t type);
+#ifdef FEATURE_P2P_LISTEN_OFFLOAD
+int wma_p2p_lo_event_handler(void *handle, uint8_t *event_buf,
+				uint32_t len);
+#endif
+
+QDF_STATUS wma_process_hal_pwr_dbg_cmd(WMA_HANDLE handle,
+				       struct sir_mac_pwr_dbg_cmd *
+				       sir_pwr_dbg_params);
+
+/**
+ * wma_lost_link_info_handler() - collect lost link information and inform SME
+ * @wma: WMA handle
+ * @vdev_id: vdev ID
+ * @rssi: rssi at disconnection time
+ *
+ * Return: none
+ */
+void wma_lost_link_info_handler(tp_wma_handle wma, uint32_t vdev_id,
+				int32_t rssi);
+int wma_unified_power_debug_stats_event_handler(void *handle,
+			uint8_t *cmd_param_info, uint32_t len);
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * wma_sta_kickout_event()- send sta kickout event
+ * @kickout_reason - reasoncode for kickout
+ * @macaddr[IEEE80211_ADDR_LEN]: Peer mac address
+ * @vdev_id: Unique id for identifying the VDEV
+ *
+ * This function sends sta kickout diag event
+ *
+ * Return: void.
+ */
+void wma_sta_kickout_event(uint32_t kickout_reason, uint8_t vdev_id,
+							uint8_t *macaddr);
+#else
+static inline void wma_sta_kickout_event(uint32_t kickout_reason,
+					uint8_t vdev_id, uint8_t *macaddr)
+{
+
+};
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+/**
+ * wma_get_rcpi_req() - get rcpi request
+ * @handle: wma handle
+ * @rcpi_request: rcpi params
+ *
+ * Return: none
+ */
+QDF_STATUS wma_get_rcpi_req(WMA_HANDLE handle,
+			    struct sme_rcpi_req *rcpi_request);
+
+/**
+ * wma_rcpi_event_handler() - rcpi event handler
+ * @handle: wma handle
+ * @cmd_param_info: data from event
+ * @len: length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_rcpi_event_handler(void *handle, uint8_t *cmd_param_info,
+			   uint32_t len);
+
+/**
+ * wma_acquire_wakelock() - acquire the given wakelock
+ * @wl: the wakelock to acquire
+ * @msec: the wakelock duration in milliseconds
+ *
+ * This also acquires the wma runtime pm lock.
+ *
+ * Return: None
+ */
+void wma_acquire_wakelock(qdf_wake_lock_t *wl, uint32_t msec);
+
+/**
+ * wma_release_wakelock() - release the given wakelock
+ * @wl: the wakelock to release
+ *
+ * This also releases the wma runtime pm lock.
+ *
+ * Return: None
+ */
+void wma_release_wakelock(qdf_wake_lock_t *wl);
+
+/**
+ * wma_send_vdev_start_to_fw() - send the vdev start command to firmware
+ * @wma: a reference to the global WMA handle
+ * @params: the vdev start params to send to firmware
+ *
+ * Consumers should call wma_release_wakelock() upon receipt of the vdev start
+ * response from firmware to avoid power penalties. Alternatively, calling the
+ * matching vdev_up or vdev_down APIs will also release this lock.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wma_send_vdev_start_to_fw(t_wma_handle *wma, struct vdev_start_params *params);
+
+/**
+ * wma_send_vdev_stop_to_fw() - send the vdev stop command to firmware
+ * @wma: a reference to the global WMA handle
+ * @vdev_id: the Id of the vdev to stop
+ *
+ * Consumers should call wma_release_wakelock() upon receipt of the vdev stop
+ * response from firmware to avoid power penalties.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_send_vdev_stop_to_fw(t_wma_handle *wma, uint8_t vdev_id);
+
+int wma_get_arp_stats_handler(void *handle, uint8_t *data, uint32_t data_len);
+
+/**
+ * wma_send_vdev_up_to_fw() - send the vdev up command to firmware
+ * @wma: a reference to the global WMA handle
+ * @params: the vdev up params to send to firmware
+ * @bssid: the BssId to send to firmware
+ *
+ * This also releases the vdev start wakelock.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma,
+				  struct vdev_up_params *params,
+				  uint8_t bssid[IEEE80211_ADDR_LEN]);
+
+/**
+ * wma_send_vdev_down_to_fw() - send the vdev down command to firmware
+ * @wma: a reference to the global WMA handle
+ * @vdev_id: the Id of the vdev to down
+ *
+ * This also releases the vdev start wakelock.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_send_vdev_down_to_fw(t_wma_handle *wma, uint8_t vdev_id);
+
+/*
+ * wma_rx_aggr_failure_event_handler - event handler to handle rx aggr failure
+ * @handle: the wma handle
+ * @event_buf: buffer with event
+ * @len: buffer length
+ *
+ * This function receives rx aggregation failure event and then pass to upper
+ * layer
+ *
+ * Return: 0 on success
+ */
+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);
+
+/**
+ * wma_pdev_div_info_evt_handler - event handler to handle antenna info
+ * @handle: the wma handle
+ * @event_buf: buffer with event
+ * @len: buffer length
+ *
+ * This function receives antenna info from firmware and passes the event
+ * to upper layer
+ *
+ * Return: 0 on success
+ */
+int wma_pdev_div_info_evt_handler(void *handle, u_int8_t *event_buf,
+	u_int32_t len);
+
+/**
+ * wma_update_beacon_interval() - update beacon interval in fw
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @beaconInterval: becon interval
+ *
+ * Return: none
+ */
+void
+wma_update_beacon_interval(tp_wma_handle wma, uint8_t vdev_id,
+				uint16_t beaconInterval);
+
+#define RESET_BEACON_INTERVAL_TIMEOUT 200
+
+struct wma_beacon_interval_reset_req {
+	qdf_timer_t event_timeout;
+	uint8_t vdev_id;
+	uint16_t interval;
+};
+
+/**
+ * wma_fill_beacon_interval_reset_req() - req to reset beacon interval
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @beacon_interval: beacon interval
+ * @timeout: timeout val
+ *
+ * Return: status
+ */
+int wma_fill_beacon_interval_reset_req(tp_wma_handle wma, uint8_t vdev_id,
+				uint16_t beacon_interval, uint32_t timeout);
+/*
+ * wma_is_vdev_valid() - check the vdev status
+ * @vdev_id: vdev identifier
+ *
+ * This function verifies the vdev validity
+ *
+ * Return: 'true' on valid vdev else 'false'
+ */
+bool wma_is_vdev_valid(uint32_t vdev_id);
+
+/**
+ * wma_vdev_obss_detection_info_handler - event handler to handle obss detection
+ * @handle: the wma handle
+ * @event: buffer with event
+ * @len: buffer length
+ *
+ * This function receives obss detection info from firmware which is used to
+ * decide obss protection.
+ *
+ * Return: 0 on success
+ */
+int wma_vdev_obss_detection_info_handler(void *handle, uint8_t *event,
+					 uint32_t len);
+
+/**
+ * wma_vdev_bss_color_collision_info_handler - event handler to
+ *  handle obss color collision detection.
+ * @handle: the wma handle
+ * @event: buffer with event
+ * @len: buffer length
+ *
+ * This function receives obss color collision detection info from firmware
+ * which is used to select new bss color.
+ *
+ * Return: 0 on success
+ */
+int wma_vdev_bss_color_collision_info_handler(void *handle,
+					      uint8_t *event,
+					      uint32_t len);
+
+int wma_twt_en_complete_event_handler(void *handle,
+				      uint8_t *event, uint32_t len);
+/**
+ * wma_get_roam_scan_stats() - Get roam scan stats request
+ * @handle: wma handle
+ * @req: request details
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_get_roam_scan_stats(WMA_HANDLE handle,
+				   struct sir_roam_scan_stats *req);
+
+/**
+ * wma_remove_peer_on_add_bss_failure() - remove the CDP peers in case of
+ *					  ADD BSS request failed
+ * @add_bss_params: Pointer to the Add BSS request params
+ *
+ * This API deletes the CDP peer created during ADD BSS in case of ADD BSS
+ * request sent to the FW fails.
+ *
+ * Return: None;
+ */
+void wma_remove_peer_on_add_bss_failure(tpAddBssParams add_bss_params);
+
+/**
+ * wma_roam_scan_stats_event_handler() - roam scan stats event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: length of data
+ *
+ * Return: Success or Failure status
+ */
+int wma_roam_scan_stats_event_handler(void *handle, uint8_t *event,
+				      uint32_t len);
+
+/**
+ * wma_send_del_bss_response() - send del bss resp to upper layer
+ * @wma: wma handle.
+ * @vdev_id: vdev ID of device for which MCC has to be checked
+ *
+ * This function sends del bss resp to upper layer
+ *
+ * Return: none
+ */
+void wma_send_vdev_down_bss(tp_wma_handle wma, struct wma_target_req *req);
+
+/**
+ * wma_sta_send_vdev_down_bss() - send vdev down to firmware
+ * @wma: wma handle.
+ * @req: vdev request
+ *
+ * This function sends vdev down to firmware
+ *
+ * Return: none
+ */
+void wma_sta_send_vdev_down_bss(tp_wma_handle wma, struct wma_target_req *req);
+#endif
diff --git a/core/wma/inc/wma_tgt_cfg.h b/core/wma/inc/wma_tgt_cfg.h
new file mode 100644
index 0000000..ff10026
--- /dev/null
+++ b/core/wma/inc/wma_tgt_cfg.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+#ifndef WMA_TGT_CFG_H
+#define WMA_TGT_CFG_H
+
+#include "wma_sar_public_structs.h"
+
+/**
+ * struct wma_tgt_services - target services
+ * @sta_power_save: sta power save
+ * @uapsd: uapsd
+ * @ap_dfs: ap dfs
+ * @en_11ac: enable 11ac
+ * @arp_offload: arp offload
+ * @early_rx: early rx
+ * @pno_offload: pno offload
+ * @beacon_offload: beacon offload
+ * @lte_coex_ant_share: LTE coex ant share
+ * @en_tdls: enable tdls
+ * @en_tdls_offchan: enable tdls offchan
+ * @en_tdls_uapsd_buf_sta: enable sta tdls uapsd buf
+ * @en_tdls_uapsd_sleep_sta: enable sta tdls uapsd sleep
+ * @en_roam_offload: enable roam offload
+ * @en_11ax: enable 11ax
+ * @is_fw_mawc_capable: Motion Aided Wireless Connectivity feature
+ * @twt_requestor: TWT requestor capability
+ * @twt_responder: TWT responder capability
+ */
+struct wma_tgt_services {
+	uint32_t sta_power_save;
+	uint32_t uapsd;
+	uint32_t ap_dfs;
+	uint32_t en_11ac;
+	uint32_t arp_offload;
+	uint32_t early_rx;
+#ifdef FEATURE_WLAN_SCAN_PNO
+	bool pno_offload;
+#endif /* FEATURE_WLAN_SCAN_PNO */
+	bool beacon_offload;
+	bool pmf_offload;
+	uint32_t lte_coex_ant_share;
+#ifdef FEATURE_WLAN_TDLS
+	bool en_tdls;
+	bool en_tdls_offchan;
+	bool en_tdls_uapsd_buf_sta;
+	bool en_tdls_uapsd_sleep_sta;
+#endif /* FEATURE_WLAN_TDLS */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	bool en_roam_offload;
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+	bool en_11ax;
+	bool get_peer_info_enabled;
+	bool is_fils_roaming_supported;
+	bool is_fw_mawc_capable;
+	bool is_11k_offload_supported;
+	bool twt_requestor;
+	bool twt_responder;
+	bool obss_scan_offload;
+};
+
+/**
+ * struct wma_tgt_ht_cap - ht capabalitiy
+ * @mpdu_density: mpdu density
+ * @ht_rx_stbc: ht rx stbc
+ * @ht_tx_stbc: ht tx stbc
+ * @ht_rx_ldpc: ht rx ldpc
+ * @ht_sgi_20: ht sgi 20
+ * @ht_sgi_40: ht sgi 40
+ * @num_rf_chains: num of rf chains
+ */
+struct wma_tgt_ht_cap {
+	uint32_t mpdu_density;
+	bool ht_rx_stbc;
+	bool ht_tx_stbc;
+	bool ht_rx_ldpc;
+	bool ht_sgi_20;
+	bool ht_sgi_40;
+	uint32_t num_rf_chains;
+};
+
+/**
+ * struct wma_tgt_vht_cap - vht capabalities
+ * @vht_max_mpdu: vht max mpdu
+ * @supp_chan_width: supported channel width
+ * @vht_rx_ldpc: vht rx ldpc
+ * @vht_short_gi_80: vht short gi 80
+ * @vht_short_gi_160: vht short gi 160
+ * @vht_tx_stbc: vht tx stbc
+ * @vht_rx_stbc: vht rx stbc
+ * @vht_su_bformer: vht su bformer
+ * @vht_su_bformee: vht su bformee
+ * @vht_mu_bformer: vht mu bformer
+ * @vht_mu_bformee: vht mu bformee
+ * @vht_max_ampdu_len_exp: vht max ampdu len exp
+ * @vht_txop_ps: vht txop ps
+ */
+struct wma_tgt_vht_cap {
+	uint32_t vht_max_mpdu;
+	uint32_t supp_chan_width;
+	uint32_t vht_rx_ldpc;
+	uint32_t vht_short_gi_80;
+	uint32_t vht_short_gi_160;
+	uint32_t vht_tx_stbc;
+	uint32_t vht_rx_stbc;
+	uint32_t vht_su_bformer;
+	uint32_t vht_su_bformee;
+	uint32_t vht_mu_bformer;
+	uint32_t vht_mu_bformee;
+	uint32_t vht_max_ampdu_len_exp;
+	uint32_t vht_txop_ps;
+};
+
+/**
+ * struct wma_dfs_radar_ind - dfs radar indication
+ * @ieee_chan_number: ieee channel number
+ * @chan_freq: channel freq
+ * @dfs_radar_status: dfs radar status
+ */
+struct wma_dfs_radar_ind {
+	uint8_t ieee_chan_number;
+	uint32_t chan_freq;
+	uint32_t dfs_radar_status;
+};
+
+/**
+ * struct board_info - Structure for board related information
+ * @bdf_version: board file version
+ * @ref_design_id: reference design id
+ * @customer_id: customer id
+ * @project_id: project id
+ * @board_data_rev: board data revision
+ *
+ * This board information will be stored in board file during the
+ * calibration and customization.
+ *
+ */
+struct board_info {
+	uint32_t bdf_version;
+	uint32_t ref_design_id;
+	uint32_t customer_id;
+	uint32_t project_id;
+	uint32_t board_data_rev;
+};
+
+/**
+ * struct wma_tgt_cfg - target config
+ * @target_fw_version: target fw version
+ * @target_fw_vers_ext: target fw extended sub version
+ * @band_cap: band capability
+ * @reg_domain: reg domain
+ * @eeprom_rd_ext: eeprom rd ext
+ * @hw_macaddr: hw mcast addr
+ * @services: struct wma_tgt_services
+ * @ht_cap: struct wma_tgt_ht_cap
+ * @vht_cap: struct wma_tgt_vht_cap
+ * @max_intf_count: max interface count
+ * @lpss_support: lpass support
+ * @egap_support: enhanced green ap support
+ * @nan_datapath_enabled: nan data path support
+ * @bool is_ra_rate_limit_enabled: RA filter support
+ * @he_cap: HE capability received from FW
+ * @dfs_cac_offload: dfs and cac timer offloaded
+ * @tx_bfee_8ss_enabled: Tx Beamformee support for 8x8
+ * @rcpi_enabled: for checking rcpi support
+ * @obss_detection_offloaded: obss detection offloaded to firmware
+ * @obss_color_collision_offloaded: obss color collision offloaded to firmware
+ * @sar_version: Version of SAR supported by firmware
+ */
+struct wma_tgt_cfg {
+	uint32_t target_fw_version;
+	uint32_t target_fw_vers_ext;
+	uint8_t band_cap;
+	uint32_t reg_domain;
+	uint32_t eeprom_rd_ext;
+	struct qdf_mac_addr hw_macaddr;
+	struct wma_tgt_services services;
+	struct wma_tgt_ht_cap ht_cap;
+	struct wma_tgt_vht_cap vht_cap;
+	uint8_t max_intf_count;
+#ifdef WLAN_FEATURE_LPSS
+	uint8_t lpss_support;
+#endif
+	uint8_t ap_arpns_support;
+	uint32_t fine_time_measurement_cap;
+#ifdef FEATURE_WLAN_RA_FILTERING
+	bool is_ra_rate_limit_enabled;
+#endif
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+	bool nan_datapath_enabled;
+#endif
+	bool sub_20_support;
+	uint16_t wmi_max_len;
+#ifdef WLAN_FEATURE_11AX
+	tDot11fIEhe_cap he_cap;
+	uint8_t ppet_2g[HE_MAX_PPET_SIZE];
+	uint8_t ppet_5g[HE_MAX_PPET_SIZE];
+	tDot11fIEhe_cap he_cap_2g;
+	tDot11fIEhe_cap he_cap_5g;
+#endif
+	bool dfs_cac_offload;
+	bool tx_bfee_8ss_enabled;
+	bool rcpi_enabled;
+	bool obss_detection_offloaded;
+	bool obss_color_collision_offloaded;
+	uint32_t hw_bd_id;
+	struct board_info hw_bd_info;
+	enum sar_version sar_version;
+};
+#endif /* WMA_TGT_CFG_H */
diff --git a/core/wma/inc/wma_twt.h b/core/wma/inc/wma_twt.h
new file mode 100644
index 0000000..8efec5b
--- /dev/null
+++ b/core/wma/inc/wma_twt.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef __WMA_TWT_H
+#define __WMA_TWT_H
+
+#include "wma.h"
+
+#ifdef WLAN_SUPPORT_TWT
+/**
+ * wma_send_twt_enable_cmd() - Send TWT Enable command to firmware
+ * @pdev_id: pdev id
+ * @congestion_timeout: Timeout value for the TWT congestion timer
+ *
+ * Return: None
+ */
+void wma_send_twt_enable_cmd(uint32_t pdev_id, uint32_t congestion_timeout);
+
+/**
+ * wma_set_twt_peer_caps() - Fill the peer TWT capabilities
+ * @params: STA context params which will store the capabilities
+ * @cmd: Command in which the capabilities should be populated
+ *
+ * Return: None
+ */
+void wma_set_twt_peer_caps(tpAddStaParams params,
+			   struct peer_assoc_params *cmd);
+#else
+static inline void wma_send_twt_enable_cmd(uint32_t pdev_id,
+					   uint32_t congestion_timeout)
+{
+	WMA_LOGD(FL("TWT not supported as WLAN_SUPPORT_TWT is disabled"));
+}
+
+static inline void wma_set_twt_peer_caps(tpAddStaParams params,
+					 struct peer_assoc_params *cmd)
+{
+}
+#endif
+
+#endif /* __WMA_HE_H */
diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h
new file mode 100644
index 0000000..a9fbb8c
--- /dev/null
+++ b/core/wma/inc/wma_types.h
@@ -0,0 +1,773 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef WLAN_QCT_WMA_H
+#define WLAN_QCT_WMA_H
+
+#include "ani_global.h"
+
+#include "wma_api.h"
+#include "wma_tgt_cfg.h"
+#include "i_cds_packet.h"
+
+#define IS_MCC_SUPPORTED 1
+#define IS_FEATURE_SUPPORTED_BY_FW(feat_enum_value) \
+				wma_get_fw_wlan_feat_caps(feat_enum_value)
+
+#define IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE 1
+
+#define IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE 1
+
+#ifdef FEATURE_WLAN_TDLS
+#define IS_ADVANCE_TDLS_ENABLE 0
+#endif
+
+#define WMA_NVDownload_Start(x)    ({ QDF_STATUS_SUCCESS; })
+
+#define DPU_FEEDBACK_UNPROTECTED_ERROR 0x0F
+
+#define WMA_GET_RX_MAC_HEADER(pRxMeta) \
+	(tpSirMacMgmtHdr)(((t_packetmeta *)pRxMeta)->mpdu_hdr_ptr)
+
+#define WMA_GET_RX_MPDUHEADER3A(pRxMeta) \
+	(tpSirMacDataHdr3a)(((t_packetmeta *)pRxMeta)->mpdu_hdr_ptr)
+
+#define WMA_GET_RX_MPDU_HEADER_LEN(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->mpdu_hdr_len)
+
+#define WMA_GET_RX_MPDU_LEN(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->mpdu_len)
+
+#define WMA_GET_RX_PAYLOAD_LEN(pRxMeta)	\
+	(((t_packetmeta *)pRxMeta)->mpdu_data_len)
+
+#define WMA_GET_RX_TSF_DELTA(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->tsf_delta)
+
+#define WMA_GET_RX_MAC_RATE_IDX(pRxMeta) 0
+
+#define WMA_GET_RX_MPDU_DATA(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->mpdu_data_ptr)
+
+#define WMA_GET_RX_MPDU_HEADER_OFFSET(pRxMeta) 0
+
+#define WMA_GET_RX_UNKNOWN_UCAST(pRxMeta) 0
+
+#define WMA_GET_RX_CH(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->channel)
+
+#define WMA_IS_RX_BCAST(pRxMeta) 0
+
+#define WMA_GET_RX_FT_DONE(pRxMeta) 0
+
+#define WMA_GET_RX_DPU_FEEDBACK(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->dpuFeedback)
+
+#define WMA_GET_RX_BEACON_SENT(pRxMeta) 0
+
+#define WMA_GET_RX_TSF_LATER(pRxMeta) 0
+
+#define WMA_GET_RX_TIMESTAMP(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->timestamp)
+
+#define WMA_IS_RX_IN_SCAN(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->scan)
+
+#define WMA_GET_OFFLOADSCANLEARN(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->offloadScanLearn)
+#define WMA_GET_ROAMCANDIDATEIND(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->roamCandidateInd)
+#define WMA_GET_SESSIONID(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->sessionId)
+#define WMA_GET_SCAN_SRC(pRxMeta) \
+	(((t_packetmeta *)pRxMeta)->scan_src)
+
+#ifdef FEATURE_WLAN_EXTSCAN
+#define WMA_IS_EXTSCAN_SCAN_SRC(pRxMeta) \
+	((((t_packetmeta *)pRxMeta)->scan_src) == WMI_MGMT_RX_HDR_EXTSCAN)
+#define WMA_IS_EPNO_SCAN_SRC(pRxMeta) \
+	((((t_packetmeta *)pRxMeta)->scan_src) & WMI_MGMT_RX_HDR_ENLO)
+#endif /* FEATURE_WLAN_EXTSCAN */
+
+#define WMA_GET_RX_SNR(pRxMeta)	\
+	(((t_packetmeta *)pRxMeta)->snr)
+
+#define WMA_GET_RX_RFBAND(pRxMeta) 0
+
+#define WMA_MAX_TXPOWER_INVALID        127
+/* rssi value normalized to noise floor of -96 dBm */
+#define WMA_GET_RX_RSSI_NORMALIZED(pRxMeta) \
+		       (((t_packetmeta *)pRxMeta)->rssi)
+
+/* raw rssi based on actual noise floor in hardware */
+#define WMA_GET_RX_RSSI_RAW(pRxMeta) \
+		       (((t_packetmeta *)pRxMeta)->rssi_raw)
+
+/*
+ * the repeat_cnt is reserved by FW team, the current value
+ * is always 0xffffffff
+ */
+#define WMI_WOW_PULSE_REPEAT_CNT 0xffffffff
+
+
+/* WMA Messages */
+#define WMA_MSG_TYPES_BEGIN            SIR_HAL_MSG_TYPES_BEGIN
+#define WMA_ITC_MSG_TYPES_BEGIN        SIR_HAL_ITC_MSG_TYPES_BEGIN
+#define WMA_RADAR_DETECTED_IND         SIR_HAL_RADAR_DETECTED_IND
+
+#define WMA_ADD_STA_REQ                SIR_HAL_ADD_STA_REQ
+#define WMA_ADD_STA_RSP                SIR_HAL_ADD_STA_RSP
+#define WMA_ADD_STA_SELF_RSP           SIR_HAL_ADD_STA_SELF_RSP
+#define WMA_DELETE_STA_REQ             SIR_HAL_DELETE_STA_REQ
+#define WMA_DELETE_STA_RSP             SIR_HAL_DELETE_STA_RSP
+#define WMA_ADD_BSS_REQ                SIR_HAL_ADD_BSS_REQ
+#define WMA_ADD_BSS_RSP                SIR_HAL_ADD_BSS_RSP
+#define WMA_DELETE_BSS_REQ             SIR_HAL_DELETE_BSS_REQ
+#define WMA_DELETE_BSS_HO_FAIL_REQ     SIR_HAL_DELETE_BSS_HO_FAIL_REQ
+#define WMA_DELETE_BSS_RSP             SIR_HAL_DELETE_BSS_RSP
+#define WMA_DELETE_BSS_HO_FAIL_RSP     SIR_HAL_DELETE_BSS_HO_FAIL_RSP
+#define WMA_SEND_BEACON_REQ            SIR_HAL_SEND_BEACON_REQ
+#define WMA_SEND_BCN_RSP               SIR_HAL_SEND_BCN_RSP
+#define WMA_SEND_PROBE_RSP_TMPL        SIR_HAL_SEND_PROBE_RSP_TMPL
+
+#define WMA_SET_BSSKEY_REQ             SIR_HAL_SET_BSSKEY_REQ
+#define WMA_SET_BSSKEY_RSP             SIR_HAL_SET_BSSKEY_RSP
+#define WMA_SET_STAKEY_REQ             SIR_HAL_SET_STAKEY_REQ
+#define WMA_SET_STAKEY_RSP             SIR_HAL_SET_STAKEY_RSP
+#define WMA_UPDATE_EDCA_PROFILE_IND    SIR_HAL_UPDATE_EDCA_PROFILE_IND
+
+#define WMA_UPDATE_BEACON_IND          SIR_HAL_UPDATE_BEACON_IND
+#define WMA_UPDATE_CF_IND              SIR_HAL_UPDATE_CF_IND
+#define WMA_CHNL_SWITCH_REQ            SIR_HAL_CHNL_SWITCH_REQ
+#define WMA_ADD_TS_REQ                 SIR_HAL_ADD_TS_REQ
+#define WMA_DEL_TS_REQ                 SIR_HAL_DEL_TS_REQ
+
+#define WMA_MISSED_BEACON_IND          SIR_HAL_MISSED_BEACON_IND
+
+#define WMA_ENTER_PS_REQ               SIR_HAL_ENTER_PS_REQ
+#define WMA_EXIT_PS_REQ                SIR_HAL_EXIT_PS_REQ
+
+#define WMA_HIDDEN_SSID_RESTART_RSP    SIR_HAL_HIDDEN_SSID_RESTART_RSP
+#define WMA_SWITCH_CHANNEL_RSP         SIR_HAL_SWITCH_CHANNEL_RSP
+#define WMA_P2P_NOA_ATTR_IND           SIR_HAL_P2P_NOA_ATTR_IND
+#define WMA_PWR_SAVE_CFG               SIR_HAL_PWR_SAVE_CFG
+#define WMA_REGISTER_PE_CALLBACK       SIR_HAL_REGISTER_PE_CALLBACK
+
+#define WMA_IBSS_STA_ADD               SIR_HAL_IBSS_STA_ADD
+#define WMA_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND SIR_HAL_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND
+#define WMA_SET_LINK_STATE             SIR_HAL_SET_LINK_STATE
+#define WMA_SET_LINK_STATE_RSP         SIR_HAL_SET_LINK_STATE_RSP
+#define WMA_SET_STA_BCASTKEY_REQ       SIR_HAL_SET_STA_BCASTKEY_REQ
+#define WMA_SET_STA_BCASTKEY_RSP       SIR_HAL_SET_STA_BCASTKEY_RSP
+#define WMA_ADD_TS_RSP                 SIR_HAL_ADD_TS_RSP
+#define WMA_DPU_MIC_ERROR              SIR_HAL_DPU_MIC_ERROR
+#define WMA_TIMER_CHIP_MONITOR_TIMEOUT SIR_HAL_TIMER_CHIP_MONITOR_TIMEOUT
+#define WMA_TIMER_TRAFFIC_ACTIVITY_REQ SIR_HAL_TIMER_TRAFFIC_ACTIVITY_REQ
+#define WMA_TIMER_ADC_RSSI_STATS       SIR_HAL_TIMER_ADC_RSSI_STATS
+#define WMA_TIMER_TRAFFIC_STATS_IND    SIR_HAL_TRAFFIC_STATS_IND
+
+#ifdef WLAN_FEATURE_11W
+#define WMA_EXCLUDE_UNENCRYPTED_IND    SIR_HAL_EXCLUDE_UNENCRYPTED_IND
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+#define WMA_TSM_STATS_REQ              SIR_HAL_TSM_STATS_REQ
+#define WMA_TSM_STATS_RSP              SIR_HAL_TSM_STATS_RSP
+#endif
+
+#define WMA_HT40_OBSS_SCAN_IND                  SIR_HAL_HT40_OBSS_SCAN_IND
+
+#define WMA_SET_MIMOPS_REQ                      SIR_HAL_SET_MIMOPS_REQ
+#define WMA_SET_MIMOPS_RSP                      SIR_HAL_SET_MIMOPS_RSP
+#define WMA_SYS_READY_IND                       SIR_HAL_SYS_READY_IND
+#define WMA_SET_TX_POWER_REQ                    SIR_HAL_SET_TX_POWER_REQ
+#define WMA_SET_TX_POWER_RSP                    SIR_HAL_SET_TX_POWER_RSP
+#define WMA_GET_TX_POWER_REQ                    SIR_HAL_GET_TX_POWER_REQ
+
+/* Messages to support transmit_halt and transmit_resume */
+#define WMA_TRANSMISSION_CONTROL_IND            SIR_HAL_TRANSMISSION_CONTROL_IND
+
+#define WMA_ENABLE_UAPSD_REQ            SIR_HAL_ENABLE_UAPSD_REQ
+#define WMA_DISABLE_UAPSD_REQ           SIR_HAL_DISABLE_UAPSD_REQ
+
+/* / PE <-> HAL statistics messages */
+#define WMA_GET_STATISTICS_REQ         SIR_HAL_GET_STATISTICS_REQ
+#define WMA_GET_STATISTICS_RSP         SIR_HAL_GET_STATISTICS_RSP
+#define WMA_SET_KEY_DONE               SIR_HAL_SET_KEY_DONE
+
+/* / PE <-> HAL BTC messages */
+#define WMA_BTC_SET_CFG                SIR_HAL_BTC_SET_CFG
+#define WMA_HANDLE_FW_MBOX_RSP         SIR_HAL_HANDLE_FW_MBOX_RSP
+
+#define WMA_SET_MAX_TX_POWER_REQ       SIR_HAL_SET_MAX_TX_POWER_REQ
+#define WMA_SET_MAX_TX_POWER_RSP       SIR_HAL_SET_MAX_TX_POWER_RSP
+#define WMA_SET_DTIM_PERIOD            SIR_HAL_SET_DTIM_PERIOD
+
+#define WMA_SET_MAX_TX_POWER_PER_BAND_REQ \
+	SIR_HAL_SET_MAX_TX_POWER_PER_BAND_REQ
+
+/* / PE <-> HAL Host Offload message */
+#define WMA_SET_HOST_OFFLOAD           SIR_HAL_SET_HOST_OFFLOAD
+
+/* / PE <-> HAL Keep Alive message */
+#define WMA_SET_KEEP_ALIVE             SIR_HAL_SET_KEEP_ALIVE
+
+#ifdef WLAN_NS_OFFLOAD
+#define WMA_SET_NS_OFFLOAD             SIR_HAL_SET_NS_OFFLOAD
+#endif /* WLAN_NS_OFFLOAD */
+#define WMA_ADD_STA_SELF_REQ           SIR_HAL_ADD_STA_SELF_REQ
+#define WMA_DEL_STA_SELF_REQ           SIR_HAL_DEL_STA_SELF_REQ
+
+#ifdef FEATURE_WLAN_TDLS
+#define WMA_SET_TDLS_LINK_ESTABLISH_REQ SIR_HAL_TDLS_LINK_ESTABLISH_REQ
+#define WMA_SET_TDLS_LINK_ESTABLISH_REQ_RSP SIR_HAL_TDLS_LINK_ESTABLISH_REQ_RSP
+#endif
+
+#define WMA_WLAN_SUSPEND_IND           SIR_HAL_WLAN_SUSPEND_IND
+#define WMA_WLAN_RESUME_REQ           SIR_HAL_WLAN_RESUME_REQ
+#define WMA_MSG_TYPES_END    SIR_HAL_MSG_TYPES_END
+
+#define WMA_AGGR_QOS_REQ               SIR_HAL_AGGR_QOS_REQ
+#define WMA_AGGR_QOS_RSP               SIR_HAL_AGGR_QOS_RSP
+
+#define WMA_CSA_OFFLOAD_EVENT  SIR_CSA_OFFLOAD_EVENT
+
+#ifdef FEATURE_WLAN_ESE
+#define WMA_SET_PLM_REQ             SIR_HAL_SET_PLM_REQ
+#endif
+
+#define WMA_ROAM_SCAN_OFFLOAD_REQ   SIR_HAL_ROAM_SCAN_OFFLOAD_REQ
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+#define WMA_ROAM_OFFLOAD_SYNCH_IND  SIR_HAL_ROAM_OFFLOAD_SYNCH_IND
+#define WMA_ROAM_OFFLOAD_SYNCH_FAIL SIR_HAL_ROAM_OFFLOAD_SYNCH_FAIL
+#endif
+
+#define WMA_8023_MULTICAST_LIST_REQ                     SIR_HAL_8023_MULTICAST_LIST_REQ
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+#define WMA_RECEIVE_FILTER_SET_FILTER_REQ               SIR_HAL_RECEIVE_FILTER_SET_FILTER_REQ
+#define WMA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ    SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ
+#define WMA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP    SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP
+#define WMA_RECEIVE_FILTER_CLEAR_FILTER_REQ             SIR_HAL_RECEIVE_FILTER_CLEAR_FILTER_REQ
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+
+#define WMA_DHCP_START_IND              SIR_HAL_DHCP_START_IND
+#define WMA_DHCP_STOP_IND               SIR_HAL_DHCP_STOP_IND
+
+#define WMA_TX_FAIL_MONITOR_IND         SIR_HAL_TX_FAIL_MONITOR_IND
+
+#define WMA_HIDDEN_SSID_VDEV_RESTART    SIR_HAL_HIDE_SSID_VDEV_RESTART
+
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+#define WMA_GTK_OFFLOAD_REQ             SIR_HAL_GTK_OFFLOAD_REQ
+#define WMA_GTK_OFFLOAD_GETINFO_REQ     SIR_HAL_GTK_OFFLOAD_GETINFO_REQ
+#define WMA_GTK_OFFLOAD_GETINFO_RSP     SIR_HAL_GTK_OFFLOAD_GETINFO_RSP
+#endif /* WLAN_FEATURE_GTK_OFFLOAD */
+
+#define WMA_SET_TM_LEVEL_REQ       SIR_HAL_SET_TM_LEVEL_REQ
+
+#define WMA_UPDATE_OP_MODE         SIR_HAL_UPDATE_OP_MODE
+#define WMA_UPDATE_RX_NSS          SIR_HAL_UPDATE_RX_NSS
+#define WMA_UPDATE_MEMBERSHIP      SIR_HAL_UPDATE_MEMBERSHIP
+#define WMA_UPDATE_USERPOS         SIR_HAL_UPDATE_USERPOS
+
+#ifdef WLAN_FEATURE_NAN
+#define WMA_NAN_REQUEST            SIR_HAL_NAN_REQUEST
+#endif
+
+#define WMA_START_SCAN_OFFLOAD_REQ  SIR_HAL_START_SCAN_OFFLOAD_REQ
+#define WMA_STOP_SCAN_OFFLOAD_REQ  SIR_HAL_STOP_SCAN_OFFLOAD_REQ
+#define WMA_UPDATE_CHAN_LIST_REQ    SIR_HAL_UPDATE_CHAN_LIST_REQ
+#define WMA_RX_SCAN_EVENT           SIR_HAL_RX_SCAN_EVENT
+#define WMA_RX_CHN_STATUS_EVENT     SIR_HAL_RX_CHN_STATUS_EVENT
+#define WMA_IBSS_PEER_INACTIVITY_IND SIR_HAL_IBSS_PEER_INACTIVITY_IND
+
+#define WMA_CLI_SET_CMD             SIR_HAL_CLI_SET_CMD
+
+#ifndef REMOVE_PKT_LOG
+#define WMA_PKTLOG_ENABLE_REQ       SIR_HAL_PKTLOG_ENABLE_REQ
+#endif
+
+#ifdef FEATURE_WLAN_LPHB
+#define WMA_LPHB_CONF_REQ          SIR_HAL_LPHB_CONF_IND
+#endif /* FEATURE_WLAN_LPHB */
+
+#ifdef FEATURE_WLAN_CH_AVOID
+#define WMA_CH_AVOID_UPDATE_REQ    SIR_HAL_CH_AVOID_UPDATE_REQ
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+#define WMA_SET_AUTO_SHUTDOWN_TIMER_REQ SIR_HAL_SET_AUTO_SHUTDOWN_TIMER_REQ
+#endif
+
+#define WMA_ADD_PERIODIC_TX_PTRN_IND    SIR_HAL_ADD_PERIODIC_TX_PTRN_IND
+#define WMA_DEL_PERIODIC_TX_PTRN_IND    SIR_HAL_DEL_PERIODIC_TX_PTRN_IND
+
+#define WMA_TX_POWER_LIMIT          SIR_HAL_SET_TX_POWER_LIMIT
+
+#define WMA_RATE_UPDATE_IND         SIR_HAL_RATE_UPDATE_IND
+
+#define WMA_SEND_ADDBA_REQ          SIR_HAL_SEND_ADDBA_REQ
+#define WMA_INIT_THERMAL_INFO_CMD   SIR_HAL_INIT_THERMAL_INFO_CMD
+#define WMA_SET_THERMAL_LEVEL       SIR_HAL_SET_THERMAL_LEVEL
+#define WMA_RMC_ENABLE_IND          SIR_HAL_RMC_ENABLE_IND
+#define WMA_RMC_DISABLE_IND         SIR_HAL_RMC_DISABLE_IND
+#define WMA_RMC_ACTION_PERIOD_IND   SIR_HAL_RMC_ACTION_PERIOD_IND
+
+/* IBSS peer info related message */
+#define WMA_GET_IBSS_PEER_INFO_REQ  SIR_HAL_IBSS_PEER_INFO_REQ
+
+#define WMA_IBSS_CESIUM_ENABLE_IND  SIR_HAL_IBSS_CESIUM_ENABLE_IND
+
+#define WMA_INIT_BAD_PEER_TX_CTL_INFO_CMD   SIR_HAL_BAD_PEER_TX_CTL_INI_CMD
+
+#ifdef FEATURE_WLAN_TDLS
+#define WMA_UPDATE_TDLS_PEER_STATE        SIR_HAL_UPDATE_TDLS_PEER_STATE
+#define WMA_TDLS_SHOULD_DISCOVER_CMD      SIR_HAL_TDLS_SHOULD_DISCOVER
+#define WMA_TDLS_SHOULD_TEARDOWN_CMD      SIR_HAL_TDLS_SHOULD_TEARDOWN
+#define WMA_TDLS_PEER_DISCONNECTED_CMD    SIR_HAL_TDLS_PEER_DISCONNECTED
+#define WMA_TDLS_SET_OFFCHAN_MODE         SIR_HAL_TDLS_SET_OFFCHAN_MODE
+#define WMA_TDLS_CONNECTION_TRACKER_NOTIFICATION_CMD SIR_HAL_TDLS_CONNECTION_TRACKER_NOTIFICATION
+#endif
+#define WMA_SET_SAP_INTRABSS_DIS          SIR_HAL_SET_SAP_INTRABSS_DIS
+
+/* Message to indicate beacon tx completion after beacon template update
+ * beacon offload case
+ */
+#define WMA_DFS_BEACON_TX_SUCCESS_IND   SIR_HAL_BEACON_TX_SUCCESS_IND
+#define WMA_DISASSOC_TX_COMP       SIR_HAL_DISASSOC_TX_COMP
+#define WMA_DEAUTH_TX_COMP         SIR_HAL_DEAUTH_TX_COMP
+
+#define WMA_GET_PEER_INFO          SIR_HAL_GET_PEER_INFO
+#define WMA_GET_PEER_INFO_EXT      SIR_HAL_GET_PEER_INFO_EXT
+
+#define WMA_MODEM_POWER_STATE_IND SIR_HAL_MODEM_POWER_STATE_IND
+
+#ifdef WLAN_FEATURE_STATS_EXT
+#define WMA_STATS_EXT_REQUEST              SIR_HAL_STATS_EXT_REQUEST
+#endif
+
+#define WMA_GET_TEMPERATURE_REQ     SIR_HAL_GET_TEMPERATURE_REQ
+#define WMA_SET_WISA_PARAMS         SIR_HAL_SET_WISA_PARAMS
+
+#ifdef FEATURE_WLAN_EXTSCAN
+#define WMA_EXTSCAN_GET_CAPABILITIES_REQ    SIR_HAL_EXTSCAN_GET_CAPABILITIES_REQ
+#define WMA_EXTSCAN_START_REQ               SIR_HAL_EXTSCAN_START_REQ
+#define WMA_EXTSCAN_STOP_REQ                SIR_HAL_EXTSCAN_STOP_REQ
+#define WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ   SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_REQ
+#define WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_REQ
+#define WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ    SIR_HAL_EXTSCAN_SET_SIGNF_CHANGE_REQ
+#define WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ  SIR_HAL_EXTSCAN_RESET_SIGNF_CHANGE_REQ
+#define WMA_EXTSCAN_GET_CACHED_RESULTS_REQ  SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_REQ
+#define WMA_SET_EPNO_LIST_REQ               SIR_HAL_SET_EPNO_LIST_REQ
+#define WMA_SET_PASSPOINT_LIST_REQ          SIR_HAL_SET_PASSPOINT_LIST_REQ
+#define WMA_RESET_PASSPOINT_LIST_REQ        SIR_HAL_RESET_PASSPOINT_LIST_REQ
+
+#endif /* FEATURE_WLAN_EXTSCAN */
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+#define WMA_LINK_LAYER_STATS_CLEAR_REQ        SIR_HAL_LL_STATS_CLEAR_REQ
+#define WMA_LINK_LAYER_STATS_SET_REQ          SIR_HAL_LL_STATS_SET_REQ
+#define WMA_LINK_LAYER_STATS_GET_REQ          SIR_HAL_LL_STATS_GET_REQ
+#define WMA_LINK_LAYER_STATS_RESULTS_RSP      SIR_HAL_LL_STATS_RESULTS_RSP
+#define WDA_LINK_LAYER_STATS_SET_THRESHOLD    SIR_HAL_LL_STATS_EXT_SET_THRESHOLD
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+#define WMA_LINK_STATUS_GET_REQ SIR_HAL_LINK_STATUS_GET_REQ
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+#define WMA_WLAN_EXT_WOW                      SIR_HAL_CONFIG_EXT_WOW
+#define WMA_WLAN_SET_APP_TYPE1_PARAMS         SIR_HAL_CONFIG_APP_TYPE1_PARAMS
+#define WMA_WLAN_SET_APP_TYPE2_PARAMS         SIR_HAL_CONFIG_APP_TYPE2_PARAMS
+#endif
+
+#define WMA_SET_SCAN_MAC_OUI_REQ              SIR_HAL_SET_SCAN_MAC_OUI_REQ
+#define WMA_TSF_GPIO_PIN                      SIR_HAL_TSF_GPIO_PIN_REQ
+
+#ifdef DHCP_SERVER_OFFLOAD
+#define WMA_SET_DHCP_SERVER_OFFLOAD_CMD       SIR_HAL_SET_DHCP_SERVER_OFFLOAD
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+#define WMA_LED_FLASHING_REQ   SIR_HAL_LED_FLASHING_REQ
+#endif
+
+/* Message posted by wmi when wmi event is received from FW */
+#define WMA_PROCESS_FW_EVENT		     SIR_HAL_PROCESS_FW_EVENT
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+#define WMA_UPDATE_Q2Q_IE_IND                 SIR_HAL_UPDATE_Q2Q_IE_IND
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+#define WMA_SET_RSSI_MONITOR_REQ              SIR_HAL_SET_RSSI_MONITOR_REQ
+
+#define WMA_OCB_SET_CONFIG_CMD               SIR_HAL_OCB_SET_CONFIG_CMD
+#define WMA_OCB_SET_UTC_TIME_CMD             SIR_HAL_OCB_SET_UTC_TIME_CMD
+#define WMA_OCB_START_TIMING_ADVERT_CMD      SIR_HAL_OCB_START_TIMING_ADVERT_CMD
+#define WMA_OCB_STOP_TIMING_ADVERT_CMD       SIR_HAL_OCB_STOP_TIMING_ADVERT_CMD
+#define WMA_OCB_GET_TSF_TIMER_CMD            SIR_HAL_OCB_GET_TSF_TIMER_CMD
+#define WMA_DCC_GET_STATS_CMD                SIR_HAL_DCC_GET_STATS_CMD
+#define WMA_DCC_CLEAR_STATS_CMD              SIR_HAL_DCC_CLEAR_STATS_CMD
+#define WMA_DCC_UPDATE_NDL_CMD               SIR_HAL_DCC_UPDATE_NDL_CMD
+#define WMA_SET_IE_INFO                      SIR_HAL_SET_IE_INFO
+
+#define WMA_LRO_CONFIG_CMD                   SIR_HAL_LRO_CONFIG_CMD
+#define WMA_GW_PARAM_UPDATE_REQ              SIR_HAL_GATEWAY_PARAM_UPDATE_REQ
+#define WMA_ADD_BCN_FILTER_CMDID             SIR_HAL_ADD_BCN_FILTER_CMDID
+#define WMA_REMOVE_BCN_FILTER_CMDID          SIR_HAL_REMOVE_BCN_FILTER_CMDID
+#define WMA_SET_ADAPT_DWELLTIME_CONF_PARAMS  SIR_HAL_SET_ADAPT_DWELLTIME_PARAMS
+
+#define WDA_APF_GET_CAPABILITIES_REQ         SIR_HAL_APF_GET_CAPABILITIES_REQ
+#define WDA_APF_SET_INSTRUCTIONS_REQ         SIR_HAL_APF_SET_INSTRUCTIONS_REQ
+
+#define WMA_SET_PDEV_IE_REQ                  SIR_HAL_SET_PDEV_IE_REQ
+#define WMA_UPDATE_WEP_DEFAULT_KEY           SIR_HAL_UPDATE_WEP_DEFAULT_KEY
+#define WMA_SEND_FREQ_RANGE_CONTROL_IND      SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND
+#define WMA_POWER_DEBUG_STATS_REQ            SIR_HAL_POWER_DEBUG_STATS_REQ
+#define WMA_GET_RCPI_REQ                     SIR_HAL_GET_RCPI_REQ
+
+#define WMA_SET_DBS_SCAN_SEL_CONF_PARAMS     SIR_HAL_SET_DBS_SCAN_SEL_PARAMS
+
+#define WMA_SET_WOW_PULSE_CMD                SIR_HAL_SET_WOW_PULSE_CMD
+
+#define WMA_SET_PER_ROAM_CONFIG_CMD          SIR_HAL_SET_PER_ROAM_CONFIG_CMD
+
+#define WMA_SEND_AP_VDEV_UP                  SIR_HAL_SEND_AP_VDEV_UP
+
+#define WMA_SET_ARP_STATS_REQ                SIR_HAL_SET_ARP_STATS_REQ
+#define WMA_GET_ARP_STATS_REQ                SIR_HAL_GET_ARP_STATS_REQ
+#define WMA_SET_LIMIT_OFF_CHAN               SIR_HAL_SET_LIMIT_OFF_CHAN
+#define WMA_OBSS_DETECTION_REQ               SIR_HAL_OBSS_DETECTION_REQ
+#define WMA_OBSS_DETECTION_INFO              SIR_HAL_OBSS_DETECTION_INFO
+#define WMA_INVOKE_NEIGHBOR_REPORT           SIR_HAL_INVOKE_NEIGHBOR_REPORT
+#define WMA_OBSS_COLOR_COLLISION_REQ         SIR_HAL_OBSS_COLOR_COLLISION_REQ
+#define WMA_OBSS_COLOR_COLLISION_INFO        SIR_HAL_OBSS_COLOR_COLLISION_INFO
+
+#define WMA_GET_ROAM_SCAN_STATS              SIR_HAL_GET_ROAM_SCAN_STATS
+
+/* Bit 6 will be used to control BD rate for Management frames */
+#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40
+
+#define wma_tx_frame(hHal, pFrmBuf, frmLen, frmType, txDir, tid, pCompFunc, \
+		   pData, txFlag, sessionid, channel_freq, rid) \
+	(QDF_STATUS)( wma_tx_packet( \
+		      cds_get_context(QDF_MODULE_ID_WMA), \
+		      (pFrmBuf), \
+		      (frmLen), \
+		      (frmType), \
+		      (txDir), \
+		      (tid), \
+		      (pCompFunc), \
+		      (pData), \
+		      (NULL), \
+		      (txFlag), \
+		      (sessionid), \
+		      (false), \
+		      (channel_freq), \
+		      (rid)))
+
+#define wma_tx_frameWithTxComplete(hHal, pFrmBuf, frmLen, frmType, txDir, tid, \
+	 pCompFunc, pData, pCBackFnTxComp, txFlag, sessionid, tdlsflag, \
+	 channel_freq, rid) \
+	(QDF_STATUS)( wma_tx_packet( \
+		      cds_get_context(QDF_MODULE_ID_WMA), \
+		      (pFrmBuf), \
+		      (frmLen), \
+		      (frmType), \
+		      (txDir), \
+		      (tid), \
+		      (pCompFunc), \
+		      (pData), \
+		      (pCBackFnTxComp), \
+		      (txFlag), \
+		      (sessionid), \
+		      (tdlsflag), \
+		      (channel_freq), \
+		      (rid)))
+
+
+#define WMA_SetEnableSSR(enable_ssr) ((void)enable_ssr)
+
+/**
+ * struct sUapsd_Params - Powersave Offload Changes
+ * @bkDeliveryEnabled: BK delivery enabled flag
+ * @beDeliveryEnabled: BE delivery enabled flag
+ * @viDeliveryEnabled: VI delivery enabled flag
+ * @voDeliveryEnabled: VO delivery enabled flag
+ * @bkTriggerEnabled: BK trigger enabled flag
+ * @beTriggerEnabled: BE trigger enabled flag
+ * @viTriggerEnabled: VI trigger enabled flag
+ * @voTriggerEnabled: VO trigger enabled flag
+ */
+typedef struct sUapsd_Params {
+	uint8_t bkDeliveryEnabled:1;
+	uint8_t beDeliveryEnabled:1;
+	uint8_t viDeliveryEnabled:1;
+	uint8_t voDeliveryEnabled:1;
+	uint8_t bkTriggerEnabled:1;
+	uint8_t beTriggerEnabled:1;
+	uint8_t viTriggerEnabled:1;
+	uint8_t voTriggerEnabled:1;
+	bool enable_ps;
+} tUapsd_Params, *tpUapsd_Params;
+
+/**
+ * struct sEnablePsParams - Enable PowerSave Params
+ * @psSetting: power save setting
+ * @uapsdParams: UAPSD Parameters
+ * @bssid: mac address
+ * @sessionid: sme session id / vdev id
+ * @bcnDtimPeriod: beacon DTIM Period
+ * @status: success/failure
+ */
+typedef struct sEnablePsParams {
+	tSirAddonPsReq psSetting;
+	tUapsd_Params uapsdParams;
+	tSirMacAddr bssid;
+	uint32_t sessionid;
+	uint8_t bcnDtimPeriod;
+	uint32_t status;
+} tEnablePsParams, *tpEnablePsParams;
+
+/**
+ * struct sDisablePsParams - Disable PowerSave Params
+ * @psSetting: power save setting
+ * @bssid: mac address
+ * @sessionid: sme session id / vdev id
+ * @status: success/failure
+ */
+typedef struct sDisablePsParams {
+	tSirAddonPsReq psSetting;
+	tSirMacAddr bssid;
+	uint32_t sessionid;
+	uint32_t status;
+} tDisablePsParams, *tpDisablePsParams;
+
+/**
+ * struct sEnableUapsdParams - Enable Uapsd Params
+ * @uapsdParams: UAPSD parameters
+ * @bssid: mac address
+ * @sessionid: sme session id/ vdev id
+ * @status: success/failure
+ */
+typedef struct sEnableUapsdParams {
+	tUapsd_Params uapsdParams;
+	tSirMacAddr bssid;
+	uint32_t sessionid;
+	uint32_t status;
+} tEnableUapsdParams, *tpEnableUapsdParams;
+
+/**
+ * struct sDisableUapsdParams - Disable Uapsd Params
+ * @bssid: mac address
+ * @sessionid: sme session id/ vdev id
+ * @status: success/failure
+ */
+typedef struct sDisableUapsdParams {
+	tSirMacAddr bssid;
+	uint32_t sessionid;
+	uint32_t status;
+} tDisableUapsdParams, *tpDisableUapsdParams;
+
+/**
+ * wma_tx_dwnld_comp_callback - callback function for TX dwnld complete
+ * @context: global pMac pointer
+ * @buf: buffer
+ * @bFreeData: to free/not free the buffer
+ *
+ * callback function for mgmt tx download completion.
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success
+ */
+typedef QDF_STATUS (*wma_tx_dwnld_comp_callback)(void *context, qdf_nbuf_t buf,
+				 bool bFreeData);
+
+/**
+ * wma_tx_ota_comp_callback - callback function for TX complete
+ * @context: global pMac pointer
+ * @buf: buffer
+ * @status: tx completion status
+ * @params: tx completion params
+ *
+ * callback function for mgmt tx ota completion.
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success
+ */
+typedef QDF_STATUS (*wma_tx_ota_comp_callback)(void *context, qdf_nbuf_t buf,
+				      uint32_t status, void *params);
+
+typedef void (*wma_txFailIndCallback)(uint8_t *, uint8_t);
+
+/* generic callback for updating parameters from target to HDD */
+typedef void (*wma_tgt_cfg_cb)(hdd_handle_t handle, struct wma_tgt_cfg *cfg);
+
+/**
+ * struct wma_cli_set_cmd_t - set command parameters
+ * @param_id: parameter id
+ * @param_value: parameter value
+ * @param_sec_value: parameter sec value
+ * @param_vdev_id: parameter vdev id
+ * @param_vp_dev: is it per vdev/pdev
+ */
+typedef struct {
+	uint32_t param_id;
+	uint32_t param_value;
+	uint32_t param_sec_value;
+	uint32_t param_vdev_id;
+	uint32_t param_vp_dev;
+} wma_cli_set_cmd_t;
+
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * enum WMA_TdlsPeerState - TDLS PEER state
+ * @WMA_TDLS_PEER_STATE_PEERING: peer is making connection
+ * @WMA_TDLS_PEER_STATE_CONNECTED: peer is connected
+ * @WMA_TDLS_PEER_STATE_TEARDOWN: peer is teardown
+ * @WMA_TDLS_PEER_ADD_MAC_ADDR: add peer into connection table
+ * @WMA_TDLS_PEER_REMOVE_MAC_ADDR: remove peer from connection table
+ */
+enum WMA_TdlsPeerState {
+	WMA_TDLS_PEER_STATE_PEERING,
+	WMA_TDLS_PEER_STATE_CONNECTED,
+	WMA_TDLS_PEER_STATE_TEARDOWN,
+	WMA_TDLS_PEER_ADD_MAC_ADDR,
+	WMA_TDLS_PEER_REMOVE_MAC_ADDR,
+};
+
+/**
+ * enum wma_tdls_off_chan_mode - modes for WMI_TDLS_SET_OFFCHAN_MODE_CMDID
+ * @WMA_TDLS_ENABLE_OFFCHANNEL: enable off channel
+ * @WMA_TDLS_DISABLE_OFFCHANNEL: disable off channel
+ */
+enum wma_tdls_off_chan_mode {
+	WMA_TDLS_ENABLE_OFFCHANNEL,
+	WMA_TDLS_DISABLE_OFFCHANNEL
+};
+
+#endif /* FEATURE_WLAN_TDLS */
+
+enum rateid {
+	RATEID_1MBPS = 0,
+	RATEID_2MBPS,
+	RATEID_5_5MBPS,
+	RATEID_11MBPS,
+	RATEID_6MBPS,
+	RATEID_9MBPS,
+	RATEID_12MBPS,
+	RATEID_18MBPS,
+	RATEID_24MBPS,
+	RATEID_36MBPS,
+	RATEID_48MBPS = 10,
+	RATEID_54MBPS,
+	RATEID_DEFAULT
+};
+
+QDF_STATUS wma_post_ctrl_msg(tpAniSirGlobal pMac, struct scheduler_msg *pMsg);
+
+QDF_STATUS u_mac_post_ctrl_msg(void *pSirGlobal, tSirMbMsg *pMb);
+
+QDF_STATUS wma_set_idle_ps_config(void *wma_ptr, uint32_t idle_ps);
+QDF_STATUS wma_get_snr(tAniGetSnrReq *psnr_req);
+
+/**
+ * wma_set_wlm_latency_level() - set latency level to FW
+ * @wma_ptr: wma handle
+ * @latency_params: latency params
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_set_wlm_latency_level(void *wma_ptr,
+			struct wlm_latency_level_param *latency_params);
+
+QDF_STATUS
+wma_ds_peek_rx_packet_info
+	(cds_pkt_t *vosDataBuff, void **ppRxHeader, bool bSwap);
+
+
+void wma_tx_abort(uint8_t vdev_id);
+
+QDF_STATUS wma_tx_packet(void *pWMA,
+			 void *pFrmBuf,
+			 uint16_t frmLen,
+			 eFrameType frmType,
+			 eFrameTxDir txDir,
+			 uint8_t tid,
+			 wma_tx_dwnld_comp_callback pCompFunc,
+			 void *pData,
+			 wma_tx_ota_comp_callback pAckTxComp,
+			 uint8_t txFlag, uint8_t sessionId, bool tdlsflag,
+			 uint16_t channel_freq, enum rateid rid);
+
+/**
+ * wma_open() - Allocate wma context and initialize it.
+ * @psoc: Psoc pointer
+ * @pTgtUpdCB: tgt config update callback fun
+ * @cds_cfg:  mac parameters
+ * @target_type: Target type
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
+		    wma_tgt_cfg_cb pTgtUpdCB, struct cds_config_info *cds_cfg,
+		    uint32_t target_type);
+
+/**
+ * wma_vdev_init() - initialize a wma vdev
+ * @vdev: the vdev to initialize
+ *
+ * Return: None
+ */
+void wma_vdev_init(struct wma_txrx_node *vdev);
+
+/**
+ * wma_vdev_deinit() - de-initialize a wma vdev
+ * @vdev: the vdev to de-initialize
+ *
+ * Return: None
+ */
+void wma_vdev_deinit(struct wma_txrx_node *vdev);
+
+QDF_STATUS wma_register_mgmt_frm_client(void);
+
+QDF_STATUS wma_de_register_mgmt_frm_client(void);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS wma_register_roaming_callbacks(
+		QDF_STATUS (*csr_roam_synch_cb)(tpAniSirGlobal mac,
+			roam_offload_synch_ind *roam_synch_data,
+			tpSirBssDescription  bss_desc_ptr,
+			enum sir_roam_op_code reason),
+		QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac,
+			roam_offload_synch_ind *roam_synch_data,
+			tpSirBssDescription  bss_desc_ptr,
+			enum sir_roam_op_code reason));
+#else
+static inline QDF_STATUS wma_register_roaming_callbacks(
+		QDF_STATUS (*csr_roam_synch_cb)(tpAniSirGlobal mac,
+			roam_offload_synch_ind *roam_synch_data,
+			tpSirBssDescription  bss_desc_ptr,
+			enum sir_roam_op_code reason),
+		QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac,
+			roam_offload_synch_ind *roam_synch_data,
+			tpSirBssDescription  bss_desc_ptr,
+			enum sir_roam_op_code reason))
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+
+#endif
diff --git a/core/wma/src/wlan_qct_wma_legacy.c b/core/wma/src/wlan_qct_wma_legacy.c
new file mode 100644
index 0000000..dd3316a
--- /dev/null
+++ b/core/wma/src/wlan_qct_wma_legacy.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2013-2018 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: wlan_qct_wma_legacy.c
+ *
+ * This software unit holds the implementation of the WLAN Device Adaptation
+ * Layer for the legacy functionalities that were part of the old HAL.
+ *
+ * The functions externalized by this module are to be called ONLY by other
+ * WLAN modules that properly register with the Transport Layer initially.
+ *
+ */
+
+/* Standard include files */
+/* Application Specific include files */
+#include "lim_api.h"
+#include "cfg_api.h"
+#include "wma.h"
+#include "sme_power_save_api.h"
+/* Locally used Defines */
+
+#define HAL_MMH_MB_MSG_TYPE_MASK    0xFF00
+
+/**
+ * wma_post_ctrl_msg() - Posts WMA messages to MC thread
+ * @pMac: MAC parameters structure
+ * @pMsg: pointer with message
+ *
+ * Return: Success or Failure
+ */
+
+QDF_STATUS wma_post_ctrl_msg(tpAniSirGlobal pMac, struct scheduler_msg *pMsg)
+{
+	if (QDF_STATUS_SUCCESS !=
+	    scheduler_post_message(QDF_MODULE_ID_WMA,
+				   QDF_MODULE_ID_WMA,
+				   QDF_MODULE_ID_WMA, pMsg))
+		return QDF_STATUS_E_FAILURE;
+	else
+		return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_post_cfg_msg() - Posts MNT messages to gSirMntMsgQ
+ * @pMac: MAC parameters structure
+ * @pMsg: A pointer to the msg
+ *
+ * Return: Success or Failure
+ */
+
+static QDF_STATUS wma_post_cfg_msg(tpAniSirGlobal pMac,
+				   struct scheduler_msg *pMsg)
+{
+	QDF_STATUS rc = QDF_STATUS_SUCCESS;
+
+	do {
+		/*
+		 *For Windows based MAC, instead of posting message to different
+		 * queues we will call the handler routines directly
+		 */
+
+		cfg_process_mb_msg(pMac, (tSirMbMsg *) pMsg->bodyptr);
+		rc = QDF_STATUS_SUCCESS;
+	} while (0);
+
+	return rc;
+}
+
+/**
+ * u_mac_post_ctrl_msg() - post ctrl msg
+ * @pMb: A pointer to the maibox message
+ *
+ * Forwards the completely received message to the respective
+ * modules for further processing.
+ *
+ * NOTE:
+ *  This function has been moved to the API file because for MAC running
+ *  on Windows host, the host module will call this routine directly to
+ *  send any mailbox messages. Making this function an API makes sure that
+ *  outside world (any module outside MMH) only calls APIs to use MMH
+ *  services and not an internal function.
+ *
+ * Return: success/error code
+ */
+
+QDF_STATUS u_mac_post_ctrl_msg(void *pSirGlobal, tSirMbMsg *pMb)
+{
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = (tpAniSirGlobal) pSirGlobal;
+
+	msg.type = pMb->type;
+	msg.bodyval = 0;
+	msg.bodyptr = pMb;
+
+	switch (msg.type & HAL_MMH_MB_MSG_TYPE_MASK) {
+	case WMA_MSG_TYPES_BEGIN:       /* Posts a message to the HAL MsgQ */
+		status = wma_post_ctrl_msg(pMac, &msg);
+		break;
+
+	case SIR_LIM_MSG_TYPES_BEGIN:   /* Posts a message to the LIM MsgQ */
+		status = lim_post_msg_api(pMac, &msg);
+		break;
+
+	case SIR_CFG_MSG_TYPES_BEGIN:   /* Posts a message to the CFG MsgQ */
+		status = wma_post_cfg_msg(pMac, &msg);
+		break;
+
+	case SIR_PMM_MSG_TYPES_BEGIN:   /* Posts a message to the LIM MsgQ */
+		status = sme_post_pe_message(pMac, &msg);
+		break;
+
+	default:
+		WMA_LOGD("Unknown message type = 0x%X\n", msg.type);
+		qdf_mem_free(msg.bodyptr);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (status != QDF_STATUS_SUCCESS)
+		qdf_mem_free(msg.bodyptr);
+
+	return status;
+
+} /* u_mac_post_ctrl_msg() */
+
+QDF_STATUS umac_send_mb_message_to_mac(void *msg)
+{
+	void *mac_handle = cds_get_context(QDF_MODULE_ID_SME);
+
+	if (!mac_handle) {
+		QDF_TRACE_ERROR(QDF_MODULE_ID_SYS, "Invalid MAC handle");
+		qdf_mem_free(msg);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return u_mac_post_ctrl_msg(mac_handle, msg);
+}
diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c
new file mode 100644
index 0000000..fb969c4
--- /dev/null
+++ b/core/wma/src/wma_data.c
@@ -0,0 +1,3228 @@
+/*
+ * Copyright (c) 2013-2018 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:    wma_data.c
+ *  This file contains tx/rx and data path related functions.
+ */
+
+/* Header files */
+
+#include "wma.h"
+#include "wma_api.h"
+#include "cds_api.h"
+#include "wmi_unified_api.h"
+#include "wlan_qct_sys.h"
+#include "wni_api.h"
+#include "ani_global.h"
+#include "wmi_unified.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include <cdp_txrx_tx_throttle.h>
+#if defined(CONFIG_HL_SUPPORT)
+#include "wlan_tgt_def_config_hl.h"
+#else
+#include "wlan_tgt_def_config.h"
+#endif
+#include "qdf_nbuf.h"
+#include "qdf_types.h"
+#include "qdf_mem.h"
+#include "qdf_util.h"
+
+#include "wma_types.h"
+#include "lim_api.h"
+#include "lim_session_utils.h"
+
+#include "cds_utils.h"
+
+#if !defined(REMOVE_PKT_LOG)
+#include "pktlog_ac.h"
+#endif /* REMOVE_PKT_LOG */
+
+#include "dbglog_host.h"
+#include "csr_api.h"
+#include "ol_fw.h"
+
+#include "wma_internal.h"
+#include "cdp_txrx_flow_ctrl_legacy.h"
+#include "cdp_txrx_cmn.h"
+#include "cdp_txrx_misc.h"
+#include <cdp_txrx_peer_ops.h>
+#include <cdp_txrx_cfg.h>
+#include "cdp_txrx_stats.h"
+#include <cdp_txrx_misc.h>
+#include "enet.h"
+#include "wlan_mgmt_txrx_utils_api.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 <cdp_txrx_handle.h>
+#include <wlan_pmo_ucfg_api.h>
+#include "wlan_lmac_if_api.h"
+#include <wlan_cp_stats_mc_ucfg_api.h>
+
+struct wma_search_rate {
+	int32_t rate;
+	uint8_t flag;
+};
+
+#define WMA_MAX_OFDM_CCK_RATE_TBL_SIZE 12
+/* In ofdm_cck_rate_tbl->flag, if bit 7 is 1 it's CCK, otherwise it ofdm.
+ * Lower bit carries the ofdm/cck index for encoding the rate
+ */
+static struct wma_search_rate ofdm_cck_rate_tbl[WMA_MAX_OFDM_CCK_RATE_TBL_SIZE] = {
+	{540, 4},               /* 4: OFDM 54 Mbps */
+	{480, 0},               /* 0: OFDM 48 Mbps */
+	{360, 5},               /* 5: OFDM 36 Mbps */
+	{240, 1},               /* 1: OFDM 24 Mbps */
+	{180, 6},               /* 6: OFDM 18 Mbps */
+	{120, 2},               /* 2: OFDM 12 Mbps */
+	{110, (1 << 7)},        /* 0: CCK 11 Mbps Long */
+	{90, 7},                /* 7: OFDM 9 Mbps  */
+	{60, 3},                /* 3: OFDM 6 Mbps  */
+	{55, ((1 << 7) | 1)},   /* 1: CCK 5.5 Mbps Long */
+	{20, ((1 << 7) | 2)},   /* 2: CCK 2 Mbps Long   */
+	{10, ((1 << 7) | 3)} /* 3: CCK 1 Mbps Long   */
+};
+
+#define WMA_MAX_VHT20_RATE_TBL_SIZE 9
+/* In vht20_400ns_rate_tbl flag carries the mcs index for encoding the rate */
+static struct wma_search_rate vht20_400ns_rate_tbl[WMA_MAX_VHT20_RATE_TBL_SIZE] = {
+	{867, 8},               /* MCS8 1SS short GI */
+	{722, 7},               /* MCS7 1SS short GI */
+	{650, 6},               /* MCS6 1SS short GI */
+	{578, 5},               /* MCS5 1SS short GI */
+	{433, 4},               /* MCS4 1SS short GI */
+	{289, 3},               /* MCS3 1SS short GI */
+	{217, 2},               /* MCS2 1SS short GI */
+	{144, 1},               /* MCS1 1SS short GI */
+	{72, 0} /* MCS0 1SS short GI */
+};
+
+/* In vht20_800ns_rate_tbl flag carries the mcs index for encoding the rate */
+static struct wma_search_rate vht20_800ns_rate_tbl[WMA_MAX_VHT20_RATE_TBL_SIZE] = {
+	{780, 8},               /* MCS8 1SS long GI */
+	{650, 7},               /* MCS7 1SS long GI */
+	{585, 6},               /* MCS6 1SS long GI */
+	{520, 5},               /* MCS5 1SS long GI */
+	{390, 4},               /* MCS4 1SS long GI */
+	{260, 3},               /* MCS3 1SS long GI */
+	{195, 2},               /* MCS2 1SS long GI */
+	{130, 1},               /* MCS1 1SS long GI */
+	{65, 0} /* MCS0 1SS long GI */
+};
+
+#define WMA_MAX_VHT40_RATE_TBL_SIZE 10
+/* In vht40_400ns_rate_tbl flag carries the mcs index for encoding the rate */
+static struct wma_search_rate vht40_400ns_rate_tbl[WMA_MAX_VHT40_RATE_TBL_SIZE] = {
+	{2000, 9},              /* MCS9 1SS short GI */
+	{1800, 8},              /* MCS8 1SS short GI */
+	{1500, 7},              /* MCS7 1SS short GI */
+	{1350, 6},              /* MCS6 1SS short GI */
+	{1200, 5},              /* MCS5 1SS short GI */
+	{900, 4},               /* MCS4 1SS short GI */
+	{600, 3},               /* MCS3 1SS short GI */
+	{450, 2},               /* MCS2 1SS short GI */
+	{300, 1},               /* MCS1 1SS short GI */
+	{150, 0},               /* MCS0 1SS short GI */
+};
+
+static struct wma_search_rate vht40_800ns_rate_tbl[WMA_MAX_VHT40_RATE_TBL_SIZE] = {
+	{1800, 9},              /* MCS9 1SS long GI */
+	{1620, 8},              /* MCS8 1SS long GI */
+	{1350, 7},              /* MCS7 1SS long GI */
+	{1215, 6},              /* MCS6 1SS long GI */
+	{1080, 5},              /* MCS5 1SS long GI */
+	{810, 4},               /* MCS4 1SS long GI */
+	{540, 3},               /* MCS3 1SS long GI */
+	{405, 2},               /* MCS2 1SS long GI */
+	{270, 1},               /* MCS1 1SS long GI */
+	{135, 0} /* MCS0 1SS long GI */
+};
+
+#define WMA_MAX_VHT80_RATE_TBL_SIZE 10
+static struct wma_search_rate vht80_400ns_rate_tbl[WMA_MAX_VHT80_RATE_TBL_SIZE] = {
+	{4333, 9},              /* MCS9 1SS short GI */
+	{3900, 8},              /* MCS8 1SS short GI */
+	{3250, 7},              /* MCS7 1SS short GI */
+	{2925, 6},              /* MCS6 1SS short GI */
+	{2600, 5},              /* MCS5 1SS short GI */
+	{1950, 4},              /* MCS4 1SS short GI */
+	{1300, 3},              /* MCS3 1SS short GI */
+	{975, 2},               /* MCS2 1SS short GI */
+	{650, 1},               /* MCS1 1SS short GI */
+	{325, 0} /* MCS0 1SS short GI */
+};
+
+static struct wma_search_rate vht80_800ns_rate_tbl[WMA_MAX_VHT80_RATE_TBL_SIZE] = {
+	{3900, 9},              /* MCS9 1SS long GI */
+	{3510, 8},              /* MCS8 1SS long GI */
+	{2925, 7},              /* MCS7 1SS long GI */
+	{2633, 6},              /* MCS6 1SS long GI */
+	{2340, 5},              /* MCS5 1SS long GI */
+	{1755, 4},              /* MCS4 1SS long GI */
+	{1170, 3},              /* MCS3 1SS long GI */
+	{878, 2},               /* MCS2 1SS long GI */
+	{585, 1},               /* MCS1 1SS long GI */
+	{293, 0} /* MCS0 1SS long GI */
+};
+
+#define WMA_MAX_HT20_RATE_TBL_SIZE 8
+static struct wma_search_rate ht20_400ns_rate_tbl[WMA_MAX_HT20_RATE_TBL_SIZE] = {
+	{722, 7},               /* MCS7 1SS short GI */
+	{650, 6},               /* MCS6 1SS short GI */
+	{578, 5},               /* MCS5 1SS short GI */
+	{433, 4},               /* MCS4 1SS short GI */
+	{289, 3},               /* MCS3 1SS short GI */
+	{217, 2},               /* MCS2 1SS short GI */
+	{144, 1},               /* MCS1 1SS short GI */
+	{72, 0} /* MCS0 1SS short GI */
+};
+
+static struct wma_search_rate ht20_800ns_rate_tbl[WMA_MAX_HT20_RATE_TBL_SIZE] = {
+	{650, 7},               /* MCS7 1SS long GI */
+	{585, 6},               /* MCS6 1SS long GI */
+	{520, 5},               /* MCS5 1SS long GI */
+	{390, 4},               /* MCS4 1SS long GI */
+	{260, 3},               /* MCS3 1SS long GI */
+	{195, 2},               /* MCS2 1SS long GI */
+	{130, 1},               /* MCS1 1SS long GI */
+	{65, 0} /* MCS0 1SS long GI */
+};
+
+#define WMA_MAX_HT40_RATE_TBL_SIZE 8
+static struct wma_search_rate ht40_400ns_rate_tbl[WMA_MAX_HT40_RATE_TBL_SIZE] = {
+	{1500, 7},              /* MCS7 1SS short GI */
+	{1350, 6},              /* MCS6 1SS short GI */
+	{1200, 5},              /* MCS5 1SS short GI */
+	{900, 4},               /* MCS4 1SS short GI */
+	{600, 3},               /* MCS3 1SS short GI */
+	{450, 2},               /* MCS2 1SS short GI */
+	{300, 1},               /* MCS1 1SS short GI */
+	{150, 0} /* MCS0 1SS short GI */
+};
+
+static struct wma_search_rate ht40_800ns_rate_tbl[WMA_MAX_HT40_RATE_TBL_SIZE] = {
+	{1350, 7},              /* MCS7 1SS long GI */
+	{1215, 6},              /* MCS6 1SS long GI */
+	{1080, 5},              /* MCS5 1SS long GI */
+	{810, 4},               /* MCS4 1SS long GI */
+	{540, 3},               /* MCS3 1SS long GI */
+	{405, 2},               /* MCS2 1SS long GI */
+	{270, 1},               /* MCS1 1SS long GI */
+	{135, 0} /* MCS0 1SS long GI */
+};
+
+/**
+ * wma_bin_search_rate() - binary search function to find rate
+ * @tbl: rate table
+ * @tbl_size: table size
+ * @mbpsx10_rate: return mbps rate
+ * @ret_flag: return flag
+ *
+ * Return: none
+ */
+static void wma_bin_search_rate(struct wma_search_rate *tbl, int32_t tbl_size,
+				int32_t *mbpsx10_rate, uint8_t *ret_flag)
+{
+	int32_t upper, lower, mid;
+
+	/* the table is descenting. index holds the largest value and the
+	 * bottom index holds the smallest value
+	 */
+
+	upper = 0;              /* index 0 */
+	lower = tbl_size - 1;   /* last index */
+
+	if (*mbpsx10_rate >= tbl[upper].rate) {
+		/* use the largest rate */
+		*mbpsx10_rate = tbl[upper].rate;
+		*ret_flag = tbl[upper].flag;
+		return;
+	} else if (*mbpsx10_rate <= tbl[lower].rate) {
+		/* use the smallest rate */
+		*mbpsx10_rate = tbl[lower].rate;
+		*ret_flag = tbl[lower].flag;
+		return;
+	}
+	/* now we do binery search to get the floor value */
+	while (lower - upper > 1) {
+		mid = (upper + lower) >> 1;
+		if (*mbpsx10_rate == tbl[mid].rate) {
+			/* found the exact match */
+			*mbpsx10_rate = tbl[mid].rate;
+			*ret_flag = tbl[mid].flag;
+			return;
+		}
+		/* not found. if mid's rate is larger than input move
+		 * upper to mid. If mid's rate is larger than input
+		 * move lower to mid.
+		 */
+		if (*mbpsx10_rate > tbl[mid].rate)
+			lower = mid;
+		else
+			upper = mid;
+	}
+	/* after the bin search the index is the ceiling of rate */
+	*mbpsx10_rate = tbl[upper].rate;
+	*ret_flag = tbl[upper].flag;
+	return;
+}
+
+/**
+ * wma_fill_ofdm_cck_mcast_rate() - fill ofdm cck mcast rate
+ * @mbpsx10_rate: mbps rates
+ * @nss: nss
+ * @rate: rate
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_fill_ofdm_cck_mcast_rate(int32_t mbpsx10_rate,
+					       uint8_t nss, uint8_t *rate)
+{
+	uint8_t idx = 0;
+
+	wma_bin_search_rate(ofdm_cck_rate_tbl, WMA_MAX_OFDM_CCK_RATE_TBL_SIZE,
+			    &mbpsx10_rate, &idx);
+
+	/* if bit 7 is set it uses CCK */
+	if (idx & 0x80)
+		*rate |= (1 << 6) | (idx & 0xF); /* set bit 6 to 1 for CCK */
+	else
+		*rate |= (idx & 0xF);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_set_ht_vht_mcast_rate() - set ht/vht mcast rate
+ * @shortgi: short gaurd interval
+ * @mbpsx10_rate: mbps rates
+ * @sgi_idx: shortgi index
+ * @sgi_rate: shortgi rate
+ * @lgi_idx: longgi index
+ * @lgi_rate: longgi rate
+ * @premable: preamble
+ * @rate: rate
+ * @streaming_rate: streaming rate
+ *
+ * Return: none
+ */
+static void wma_set_ht_vht_mcast_rate(uint32_t shortgi, int32_t mbpsx10_rate,
+				      uint8_t sgi_idx, int32_t sgi_rate,
+				      uint8_t lgi_idx, int32_t lgi_rate,
+				      uint8_t premable, uint8_t *rate,
+				      int32_t *streaming_rate)
+{
+	if (shortgi == 0) {
+		*rate |= (premable << 6) | (lgi_idx & 0xF);
+		*streaming_rate = lgi_rate;
+	} else {
+		*rate |= (premable << 6) | (sgi_idx & 0xF);
+		*streaming_rate = sgi_rate;
+	}
+}
+
+/**
+ * wma_fill_ht20_mcast_rate() - fill ht20 mcast rate
+ * @shortgi: short gaurd interval
+ * @mbpsx10_rate: mbps rates
+ * @nss: nss
+ * @rate: rate
+ * @streaming_rate: streaming rate
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_fill_ht20_mcast_rate(uint32_t shortgi,
+					   int32_t mbpsx10_rate, uint8_t nss,
+					   uint8_t *rate,
+					   int32_t *streaming_rate)
+{
+	uint8_t sgi_idx = 0, lgi_idx = 0;
+	int32_t sgi_rate, lgi_rate;
+
+	if (nss == 1)
+		mbpsx10_rate = mbpsx10_rate >> 1;
+
+	sgi_rate = mbpsx10_rate;
+	lgi_rate = mbpsx10_rate;
+	if (shortgi)
+		wma_bin_search_rate(ht20_400ns_rate_tbl,
+				    WMA_MAX_HT20_RATE_TBL_SIZE, &sgi_rate,
+				    &sgi_idx);
+	else
+		wma_bin_search_rate(ht20_800ns_rate_tbl,
+				    WMA_MAX_HT20_RATE_TBL_SIZE, &lgi_rate,
+				    &lgi_idx);
+
+	wma_set_ht_vht_mcast_rate(shortgi, mbpsx10_rate, sgi_idx, sgi_rate,
+				  lgi_idx, lgi_rate, 2, rate, streaming_rate);
+	if (nss == 1)
+		*streaming_rate = *streaming_rate << 1;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_fill_ht40_mcast_rate() - fill ht40 mcast rate
+ * @shortgi: short gaurd interval
+ * @mbpsx10_rate: mbps rates
+ * @nss: nss
+ * @rate: rate
+ * @streaming_rate: streaming rate
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_fill_ht40_mcast_rate(uint32_t shortgi,
+					   int32_t mbpsx10_rate, uint8_t nss,
+					   uint8_t *rate,
+					   int32_t *streaming_rate)
+{
+	uint8_t sgi_idx = 0, lgi_idx = 0;
+	int32_t sgi_rate, lgi_rate;
+
+	/* for 2x2 divide the rate by 2 */
+	if (nss == 1)
+		mbpsx10_rate = mbpsx10_rate >> 1;
+
+	sgi_rate = mbpsx10_rate;
+	lgi_rate = mbpsx10_rate;
+	if (shortgi)
+		wma_bin_search_rate(ht40_400ns_rate_tbl,
+				    WMA_MAX_HT40_RATE_TBL_SIZE, &sgi_rate,
+				    &sgi_idx);
+	else
+		wma_bin_search_rate(ht40_800ns_rate_tbl,
+				    WMA_MAX_HT40_RATE_TBL_SIZE, &lgi_rate,
+				    &lgi_idx);
+
+	wma_set_ht_vht_mcast_rate(shortgi, mbpsx10_rate, sgi_idx, sgi_rate,
+				  lgi_idx, lgi_rate, 2, rate, streaming_rate);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_fill_vht20_mcast_rate() - fill vht20 mcast rate
+ * @shortgi: short gaurd interval
+ * @mbpsx10_rate: mbps rates
+ * @nss: nss
+ * @rate: rate
+ * @streaming_rate: streaming rate
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_fill_vht20_mcast_rate(uint32_t shortgi,
+					    int32_t mbpsx10_rate, uint8_t nss,
+					    uint8_t *rate,
+					    int32_t *streaming_rate)
+{
+	uint8_t sgi_idx = 0, lgi_idx = 0;
+	int32_t sgi_rate, lgi_rate;
+
+	/* for 2x2 divide the rate by 2 */
+	if (nss == 1)
+		mbpsx10_rate = mbpsx10_rate >> 1;
+
+	sgi_rate = mbpsx10_rate;
+	lgi_rate = mbpsx10_rate;
+	if (shortgi)
+		wma_bin_search_rate(vht20_400ns_rate_tbl,
+				    WMA_MAX_VHT20_RATE_TBL_SIZE, &sgi_rate,
+				    &sgi_idx);
+	else
+		wma_bin_search_rate(vht20_800ns_rate_tbl,
+				    WMA_MAX_VHT20_RATE_TBL_SIZE, &lgi_rate,
+				    &lgi_idx);
+
+	wma_set_ht_vht_mcast_rate(shortgi, mbpsx10_rate, sgi_idx, sgi_rate,
+				  lgi_idx, lgi_rate, 3, rate, streaming_rate);
+	if (nss == 1)
+		*streaming_rate = *streaming_rate << 1;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_fill_vht40_mcast_rate() - fill vht40 mcast rate
+ * @shortgi: short gaurd interval
+ * @mbpsx10_rate: mbps rates
+ * @nss: nss
+ * @rate: rate
+ * @streaming_rate: streaming rate
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_fill_vht40_mcast_rate(uint32_t shortgi,
+					    int32_t mbpsx10_rate, uint8_t nss,
+					    uint8_t *rate,
+					    int32_t *streaming_rate)
+{
+	uint8_t sgi_idx = 0, lgi_idx = 0;
+	int32_t sgi_rate, lgi_rate;
+
+	/* for 2x2 divide the rate by 2 */
+	if (nss == 1)
+		mbpsx10_rate = mbpsx10_rate >> 1;
+
+	sgi_rate = mbpsx10_rate;
+	lgi_rate = mbpsx10_rate;
+	if (shortgi)
+		wma_bin_search_rate(vht40_400ns_rate_tbl,
+				    WMA_MAX_VHT40_RATE_TBL_SIZE, &sgi_rate,
+				    &sgi_idx);
+	else
+		wma_bin_search_rate(vht40_800ns_rate_tbl,
+				    WMA_MAX_VHT40_RATE_TBL_SIZE, &lgi_rate,
+				    &lgi_idx);
+
+	wma_set_ht_vht_mcast_rate(shortgi, mbpsx10_rate,
+				  sgi_idx, sgi_rate, lgi_idx, lgi_rate,
+				  3, rate, streaming_rate);
+	if (nss == 1)
+		*streaming_rate = *streaming_rate << 1;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_fill_vht80_mcast_rate() - fill vht80 mcast rate
+ * @shortgi: short gaurd interval
+ * @mbpsx10_rate: mbps rates
+ * @nss: nss
+ * @rate: rate
+ * @streaming_rate: streaming rate
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_fill_vht80_mcast_rate(uint32_t shortgi,
+					    int32_t mbpsx10_rate, uint8_t nss,
+					    uint8_t *rate,
+					    int32_t *streaming_rate)
+{
+	uint8_t sgi_idx = 0, lgi_idx = 0;
+	int32_t sgi_rate, lgi_rate;
+
+	/* for 2x2 divide the rate by 2 */
+	if (nss == 1)
+		mbpsx10_rate = mbpsx10_rate >> 1;
+
+	sgi_rate = mbpsx10_rate;
+	lgi_rate = mbpsx10_rate;
+	if (shortgi)
+		wma_bin_search_rate(vht80_400ns_rate_tbl,
+				    WMA_MAX_VHT80_RATE_TBL_SIZE, &sgi_rate,
+				    &sgi_idx);
+	else
+		wma_bin_search_rate(vht80_800ns_rate_tbl,
+				    WMA_MAX_VHT80_RATE_TBL_SIZE, &lgi_rate,
+				    &lgi_idx);
+
+	wma_set_ht_vht_mcast_rate(shortgi, mbpsx10_rate, sgi_idx, sgi_rate,
+				  lgi_idx, lgi_rate, 3, rate, streaming_rate);
+	if (nss == 1)
+		*streaming_rate = *streaming_rate << 1;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_fill_ht_mcast_rate() - fill ht mcast rate
+ * @shortgi: short gaurd interval
+ * @chwidth: channel width
+ * @chanmode: channel mode
+ * @mhz: frequency
+ * @mbpsx10_rate: mbps rates
+ * @nss: nss
+ * @rate: rate
+ * @streaming_rate: streaming rate
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_fill_ht_mcast_rate(uint32_t shortgi,
+					 uint32_t chwidth, int32_t mbpsx10_rate,
+					 uint8_t nss, WMI_HOST_WLAN_PHY_MODE chanmode,
+					 uint8_t *rate,
+					 int32_t *streaming_rate)
+{
+	int32_t ret = 0;
+
+	*streaming_rate = 0;
+	if (chwidth == 0)
+		ret = wma_fill_ht20_mcast_rate(shortgi, mbpsx10_rate,
+					       nss, rate, streaming_rate);
+	else if (chwidth == 1)
+		ret = wma_fill_ht40_mcast_rate(shortgi, mbpsx10_rate,
+					       nss, rate, streaming_rate);
+	else
+		WMA_LOGE("%s: Error, Invalid chwidth enum %d", __func__,
+			 chwidth);
+	return (*streaming_rate != 0) ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
+}
+
+/**
+ * wma_fill_vht_mcast_rate() - fill vht mcast rate
+ * @shortgi: short gaurd interval
+ * @chwidth: channel width
+ * @chanmode: channel mode
+ * @mhz: frequency
+ * @mbpsx10_rate: mbps rates
+ * @nss: nss
+ * @rate: rate
+ * @streaming_rate: streaming rate
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_fill_vht_mcast_rate(uint32_t shortgi,
+					  uint32_t chwidth,
+					  int32_t mbpsx10_rate, uint8_t nss,
+					  WMI_HOST_WLAN_PHY_MODE chanmode,
+					  uint8_t *rate,
+					  int32_t *streaming_rate)
+{
+	int32_t ret = 0;
+
+	*streaming_rate = 0;
+	if (chwidth == 0)
+		ret = wma_fill_vht20_mcast_rate(shortgi, mbpsx10_rate, nss,
+						rate, streaming_rate);
+	else if (chwidth == 1)
+		ret = wma_fill_vht40_mcast_rate(shortgi, mbpsx10_rate, nss,
+						rate, streaming_rate);
+	else if (chwidth == 2)
+		ret = wma_fill_vht80_mcast_rate(shortgi, mbpsx10_rate, nss,
+						rate, streaming_rate);
+	else
+		WMA_LOGE("%s: chwidth enum %d not supported",
+			 __func__, chwidth);
+	return (*streaming_rate != 0) ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
+}
+
+#define WMA_MCAST_1X1_CUT_OFF_RATE 2000
+/**
+ * wma_encode_mc_rate() - fill mc rates
+ * @shortgi: short gaurd interval
+ * @chwidth: channel width
+ * @chanmode: channel mode
+ * @mhz: frequency
+ * @mbpsx10_rate: mbps rates
+ * @nss: nss
+ * @rate: rate
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_encode_mc_rate(uint32_t shortgi, uint32_t chwidth,
+			     WMI_HOST_WLAN_PHY_MODE chanmode, A_UINT32 mhz,
+			     int32_t mbpsx10_rate, uint8_t nss,
+			     uint8_t *rate)
+{
+	int32_t ret = 0;
+
+	/* nss input value: 0 - 1x1; 1 - 2x2; 2 - 3x3
+	 * the phymode selection is based on following assumption:
+	 * (1) if the app specifically requested 1x1 or 2x2 we hornor it
+	 * (2) if mbpsx10_rate <= 540: always use BG
+	 * (3) 540 < mbpsx10_rate <= 2000: use 1x1 HT/VHT
+	 * (4) 2000 < mbpsx10_rate: use 2x2 HT/VHT
+	 */
+	WMA_LOGE("%s: Input: nss = %d, chanmode = %d, mbpsx10 = 0x%x, chwidth = %d, shortgi = %d",
+		 __func__, nss, chanmode, mbpsx10_rate, chwidth, shortgi);
+	if ((mbpsx10_rate & 0x40000000) && nss > 0) {
+		/* bit 30 indicates user inputed nss,
+		 * bit 28 and 29 used to encode nss
+		 */
+		uint8_t user_nss = (mbpsx10_rate & 0x30000000) >> 28;
+
+		nss = (user_nss < nss) ? user_nss : nss;
+		/* zero out bits 19 - 21 to recover the actual rate */
+		mbpsx10_rate &= ~0x70000000;
+	} else if (mbpsx10_rate <= WMA_MCAST_1X1_CUT_OFF_RATE) {
+		/* if the input rate is less or equal to the
+		 * 1x1 cutoff rate we use 1x1 only
+		 */
+		nss = 0;
+	}
+	/* encode NSS bits (bit 4, bit 5) */
+	*rate = (nss & 0x3) << 4;
+	/* if mcast input rate exceeds the ofdm/cck max rate 54mpbs
+	 * we try to choose best ht/vht mcs rate
+	 */
+	if (540 < mbpsx10_rate) {
+		/* cannot use ofdm/cck, choose closest ht/vht mcs rate */
+		uint8_t rate_ht = *rate;
+		uint8_t rate_vht = *rate;
+		int32_t stream_rate_ht = 0;
+		int32_t stream_rate_vht = 0;
+		int32_t stream_rate = 0;
+
+		ret = wma_fill_ht_mcast_rate(shortgi, chwidth, mbpsx10_rate,
+					     nss, chanmode, &rate_ht,
+					     &stream_rate_ht);
+		if (ret != QDF_STATUS_SUCCESS)
+			stream_rate_ht = 0;
+		if (mhz < WMA_2_4_GHZ_MAX_FREQ) {
+			/* not in 5 GHZ frequency */
+			*rate = rate_ht;
+			stream_rate = stream_rate_ht;
+			goto ht_vht_done;
+		}
+		/* capable doing 11AC mcast so that search vht tables */
+		ret = wma_fill_vht_mcast_rate(shortgi, chwidth, mbpsx10_rate,
+					      nss, chanmode, &rate_vht,
+					      &stream_rate_vht);
+		if (ret != QDF_STATUS_SUCCESS) {
+			if (stream_rate_ht != 0)
+				ret = QDF_STATUS_SUCCESS;
+			*rate = rate_ht;
+			stream_rate = stream_rate_ht;
+			goto ht_vht_done;
+		}
+		if (stream_rate_ht == 0) {
+			/* only vht rate available */
+			*rate = rate_vht;
+			stream_rate = stream_rate_vht;
+		} else {
+			/* set ht as default first */
+			*rate = rate_ht;
+			stream_rate = stream_rate_ht;
+			if (stream_rate < mbpsx10_rate) {
+				if (mbpsx10_rate <= stream_rate_vht ||
+				    stream_rate < stream_rate_vht) {
+					*rate = rate_vht;
+					stream_rate = stream_rate_vht;
+				}
+			} else {
+				if (stream_rate_vht >= mbpsx10_rate &&
+				    stream_rate_vht < stream_rate) {
+					*rate = rate_vht;
+					stream_rate = stream_rate_vht;
+				}
+			}
+		}
+ht_vht_done:
+		WMA_LOGE("%s: NSS = %d, ucast_chanmode = %d, freq = %d",
+			 __func__, nss, chanmode, mhz);
+		WMA_LOGD(" %s: input_rate = %d, chwidth = %d rate = 0x%x, streaming_rate = %d",
+			 __func__, mbpsx10_rate, chwidth, *rate, stream_rate);
+	} else {
+		if (mbpsx10_rate > 0)
+			ret = wma_fill_ofdm_cck_mcast_rate(mbpsx10_rate,
+							   nss, rate);
+		else
+			*rate = 0xFF;
+
+		WMA_LOGE("%s: NSS = %d, ucast_chanmode = %d, input_rate = %d, rate = 0x%x",
+			 __func__, nss, chanmode, mbpsx10_rate, *rate);
+	}
+	return ret;
+}
+
+#ifdef QCA_SUPPORT_CP_STATS
+/**
+ * wma_cp_stats_set_rate_flag() - set rate flags within cp_stats priv object
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: none
+ */
+static void wma_cp_stats_set_rate_flag(tp_wma_handle wma, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_psoc *psoc = wma->psoc;
+	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_LEGACY_WMA_ID);
+	if (!vdev) {
+		WMA_LOGE("%s, vdev not found for id: %d", __func__,
+			 vdev_id);
+		return;
+	}
+
+	ucfg_mc_cp_stats_set_rate_flags(vdev, iface->rate_flags);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+}
+#else
+static void wma_cp_stats_set_rate_flag(tp_wma_handle wma, uint8_t vdev_id) {}
+#endif
+
+/**
+ * wma_set_bss_rate_flags() - set rate flags based on BSS capability
+ * @iface: txrx_node ctx
+ * @add_bss: add_bss params
+ *
+ * Return: none
+ */
+void wma_set_bss_rate_flags(tp_wma_handle wma, uint8_t vdev_id,
+			    tpAddBssParams add_bss)
+{
+	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
+
+	iface->rate_flags = 0;
+	if (add_bss->vhtCapable) {
+		if (add_bss->ch_width == CH_WIDTH_80P80MHZ)
+			iface->rate_flags |= TX_RATE_VHT80;
+		if (add_bss->ch_width == CH_WIDTH_160MHZ)
+			iface->rate_flags |= TX_RATE_VHT80;
+		if (add_bss->ch_width == CH_WIDTH_80MHZ)
+			iface->rate_flags |= TX_RATE_VHT80;
+		else if (add_bss->ch_width)
+			iface->rate_flags |= TX_RATE_VHT40;
+		else
+			iface->rate_flags |= TX_RATE_VHT20;
+	}
+	/* avoid to conflict with htCapable flag */
+	else if (add_bss->htCapable) {
+		if (add_bss->ch_width)
+			iface->rate_flags |= TX_RATE_HT40;
+		else
+			iface->rate_flags |= TX_RATE_HT20;
+	}
+
+	if (add_bss->staContext.fShortGI20Mhz ||
+	    add_bss->staContext.fShortGI40Mhz)
+		iface->rate_flags |= TX_RATE_SGI;
+
+	if (!add_bss->htCapable && !add_bss->vhtCapable)
+		iface->rate_flags = TX_RATE_LEGACY;
+
+	wma_cp_stats_set_rate_flag(wma, vdev_id);
+}
+
+/**
+ * wmi_unified_send_txbf() - set txbf parameter to fw
+ * @wma: wma handle
+ * @params: txbf parameters
+ *
+ * Return: 0 for success or error code
+ */
+int32_t wmi_unified_send_txbf(tp_wma_handle wma, tpAddStaParams params)
+{
+	wmi_vdev_txbf_en txbf_en = {0};
+
+	/* This is set when Other partner is Bformer
+	 * and we are capable bformee(enabled both in ini and fw)
+	 */
+	txbf_en.sutxbfee = params->vhtTxBFCapable;
+	txbf_en.mutxbfee = params->vhtTxMUBformeeCapable;
+	txbf_en.sutxbfer = params->enable_su_tx_bformer;
+
+	/* When MU TxBfee is set, SU TxBfee must be set by default */
+	if (txbf_en.mutxbfee)
+		txbf_en.sutxbfee = txbf_en.mutxbfee;
+
+	WMA_LOGD("txbf_en.sutxbfee %d txbf_en.mutxbfee %d, sutxbfer %d",
+		 txbf_en.sutxbfee, txbf_en.mutxbfee, txbf_en.sutxbfer);
+
+	return wma_vdev_set_param(wma->wmi_handle,
+						params->smesessionId,
+						WMI_VDEV_PARAM_TXBF,
+						*((A_UINT8 *) &txbf_en));
+}
+
+/**
+ * wma_data_tx_ack_work_handler() - process data tx ack
+ * @ack_work: work structure
+ *
+ * Return: none
+ */
+static void wma_data_tx_ack_work_handler(void *ack_work)
+{
+	struct wma_tx_ack_work_ctx *work;
+	tp_wma_handle wma_handle;
+	wma_tx_ota_comp_callback ack_cb;
+
+	if (cds_is_load_or_unload_in_progress()) {
+		WMA_LOGE("%s: Driver load/unload in progress", __func__);
+		return;
+	}
+
+	work = (struct wma_tx_ack_work_ctx *)ack_work;
+
+	wma_handle = work->wma_handle;
+	ack_cb = wma_handle->umac_data_ota_ack_cb;
+
+	if (work->status)
+		WMA_LOGE("Data Tx Ack Cb Status %d", work->status);
+	else
+		WMA_LOGD("Data Tx Ack Cb Status %d", work->status);
+
+	/* Call the Ack Cb registered by UMAC */
+	if (ack_cb)
+		ack_cb((tpAniSirGlobal) (wma_handle->mac_context), NULL,
+			work->status ? 0 : 1, NULL);
+	else
+		WMA_LOGE("Data Tx Ack Cb is NULL");
+
+	wma_handle->umac_data_ota_ack_cb = NULL;
+	wma_handle->last_umac_data_nbuf = NULL;
+	qdf_mem_free(work);
+	wma_handle->ack_work_ctx = NULL;
+}
+
+/**
+ * wma_data_tx_ack_comp_hdlr() - handles tx data ack completion
+ * @context: context with which the handler is registered
+ * @netbuf: tx data nbuf
+ * @err: status of tx completion
+ *
+ * This is the cb registered with TxRx for
+ * Ack Complete
+ *
+ * Return: none
+ */
+void
+wma_data_tx_ack_comp_hdlr(void *wma_context, qdf_nbuf_t netbuf, int32_t status)
+{
+	void *pdev;
+	tp_wma_handle wma_handle = (tp_wma_handle) wma_context;
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: Invalid WMA Handle", __func__);
+		return;
+	}
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		return;
+	}
+
+	/*
+	 * if netBuf does not match with pending nbuf then just free the
+	 * netbuf and do not call ack cb
+	 */
+	if (wma_handle->last_umac_data_nbuf != netbuf) {
+		if (wma_handle->umac_data_ota_ack_cb) {
+			WMA_LOGE("%s: nbuf does not match but umac_data_ota_ack_cb is not null",
+				__func__);
+		} else {
+			WMA_LOGE("%s: nbuf does not match and umac_data_ota_ack_cb is also null",
+				__func__);
+		}
+		goto free_nbuf;
+	}
+
+	if (wma_handle && wma_handle->umac_data_ota_ack_cb) {
+		struct wma_tx_ack_work_ctx *ack_work;
+
+		ack_work = qdf_mem_malloc(sizeof(struct wma_tx_ack_work_ctx));
+		wma_handle->ack_work_ctx = ack_work;
+		if (ack_work) {
+			ack_work->wma_handle = wma_handle;
+			ack_work->sub_type = 0;
+			ack_work->status = status;
+
+			qdf_create_work(0, &ack_work->ack_cmp_work,
+					wma_data_tx_ack_work_handler,
+					ack_work);
+			qdf_sched_work(0, &ack_work->ack_cmp_work);
+		}
+	}
+
+free_nbuf:
+	/* unmap and freeing the tx buf as txrx is not taking care */
+	qdf_nbuf_unmap_single(wma_handle->qdf_dev, netbuf, QDF_DMA_TO_DEVICE);
+	qdf_nbuf_free(netbuf);
+}
+
+/**
+ * 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)
+{
+	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;
+}
+
+/**
+ * wma_peer_state_change_event_handler() - peer state change event handler
+ * @handle: wma handle
+ * @event_buff: event buffer
+ * @len: length of buffer
+ *
+ * This event handler unpauses vdev if peer state change to AUTHORIZED STATE
+ *
+ * Return: 0 for success or error code
+ */
+int wma_peer_state_change_event_handler(void *handle,
+					uint8_t *event_buff,
+					uint32_t len)
+{
+	WMI_PEER_STATE_EVENTID_param_tlvs *param_buf;
+	wmi_peer_state_event_fixed_param *event;
+	struct cdp_vdev *vdev;
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+
+	if (!event_buff) {
+		WMA_LOGE("%s: Received NULL event ptr from FW", __func__);
+		return -EINVAL;
+	}
+	param_buf = (WMI_PEER_STATE_EVENTID_param_tlvs *) event_buff;
+	if (!param_buf) {
+		WMA_LOGE("%s: Received NULL buf ptr from FW", __func__);
+		return -ENOMEM;
+	}
+
+	event = param_buf->fixed_param;
+	vdev = wma_find_vdev_by_id(wma_handle, event->vdev_id);
+	if (NULL == vdev) {
+		WMA_LOGD("%s: Couldn't find vdev for vdev_id: %d",
+			 __func__, event->vdev_id);
+		return -EINVAL;
+	}
+
+	if ((cdp_get_opmode(cds_get_context(QDF_MODULE_ID_SOC),
+			vdev) ==
+			wlan_op_mode_sta) &&
+		event->state == WMI_PEER_STATE_AUTHORIZED) {
+		/*
+		 * set event so that hdd
+		 * can procced and unpause tx queue
+		 */
+#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
+		if (!wma_handle->peer_authorized_cb) {
+			WMA_LOGE("%s: peer authorized cb not registered",
+				 __func__);
+			return -EINVAL;
+		}
+		wma_handle->peer_authorized_cb(event->vdev_id);
+#endif
+	}
+
+	return 0;
+}
+
+/**
+ * wma_set_enable_disable_mcc_adaptive_scheduler() -enable/disable mcc scheduler
+ * @mcc_adaptive_scheduler: enable/disable
+ *
+ * This function enable/disable mcc adaptive scheduler in fw.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_set_enable_disable_mcc_adaptive_scheduler(uint32_t
+							 mcc_adaptive_scheduler)
+{
+	tp_wma_handle wma = NULL;
+	uint32_t pdev_id;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (NULL == wma) {
+		WMA_LOGE("%s : Failed to get wma", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	/*
+	 * Since there could be up to two instances of OCS in FW (one per MAC),
+	 * FW provides the option of enabling and disabling MAS on a per MAC
+	 * basis. But, Host does not have enable/disable option for individual
+	 * MACs. So, FW agreed for the Host to send down a 'pdev id' of 0.
+	 * When 'pdev id' of 0 is used, FW treats this as a SOC level command
+	 * and applies the same value to both MACs. Irrespective of the value
+	 * of 'WMI_SERVICE_DEPRECATED_REPLACE', the pdev id needs to be '0'
+	 * (SOC level) for WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID
+	 */
+	pdev_id = WMI_PDEV_ID_SOC;
+
+	return wmi_unified_set_enable_disable_mcc_adaptive_scheduler_cmd(
+			wma->wmi_handle, mcc_adaptive_scheduler, pdev_id);
+}
+
+/**
+ * wma_set_mcc_channel_time_latency() -set MCC channel time latency
+ * @wma: wma handle
+ * @mcc_channel: mcc channel
+ * @mcc_channel_time_latency: MCC channel time latency.
+ *
+ * Currently used to set time latency for an MCC vdev/adapter using operating
+ * channel of it and channel number. The info is provided run time using
+ * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_set_mcc_channel_time_latency(tp_wma_handle wma,
+	uint32_t mcc_channel, uint32_t mcc_channel_time_latency)
+{
+	uint32_t cfg_val = 0;
+	struct mac_context *pMac = NULL;
+	uint32_t channel1 = mcc_channel;
+	uint32_t chan1_freq = cds_chan_to_freq(channel1);
+
+	if (!wma) {
+		WMA_LOGE("%s:NULL wma ptr. Exiting", __func__);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pMac = cds_get_context(QDF_MODULE_ID_PE);
+	if (!pMac) {
+		WMA_LOGE("%s:NULL pMac ptr. Exiting", __func__);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* First step is to confirm if MCC is active */
+	if (!lim_is_in_mcc(pMac)) {
+		WMA_LOGE("%s: MCC is not active. Exiting", __func__);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Confirm MCC adaptive scheduler feature is disabled */
+	if (wlan_cfg_get_int(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED,
+			     &cfg_val) == QDF_STATUS_SUCCESS) {
+		if (cfg_val == WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX) {
+			WMA_LOGD("%s: Can't set channel latency while MCC ADAPTIVE SCHED is enabled. Exit",
+				__func__);
+			return QDF_STATUS_SUCCESS;
+		}
+	} else {
+		WMA_LOGE("%s: Failed to get value for MCC_ADAPTIVE_SCHED, "
+			 "Exit w/o setting latency", __func__);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wmi_unified_set_mcc_channel_time_latency_cmd(wma->wmi_handle,
+						chan1_freq,
+						mcc_channel_time_latency);
+}
+
+/**
+ * wma_set_mcc_channel_time_quota() -set MCC channel time quota
+ * @wma: wma handle
+ * @adapter_1_chan_number: adapter 1 channel number
+ * @adapter_1_quota: adapter 1 quota
+ * @adapter_2_chan_number: adapter 2 channel number
+ *
+ * Currently used to set time quota for 2 MCC vdevs/adapters using (operating
+ * channel, quota) for each mode . The info is provided run time using
+ * iwpriv command: iwpriv <wlan0 | p2p0> setMccQuota <quota in ms>.
+ * Note: the quota provided in command is for the same mode in cmd. HDD
+ * checks if MCC mode is active, gets the second mode and its operating chan.
+ * Quota for the 2nd role is calculated as 100 - quota of first mode.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_set_mcc_channel_time_quota(tp_wma_handle wma,
+		uint32_t adapter_1_chan_number,	uint32_t adapter_1_quota,
+		uint32_t adapter_2_chan_number)
+{
+	uint32_t cfg_val = 0;
+	struct mac_context *pMac = NULL;
+	uint32_t chan1_freq = cds_chan_to_freq(adapter_1_chan_number);
+	uint32_t chan2_freq = cds_chan_to_freq(adapter_2_chan_number);
+
+	if (!wma) {
+		WMA_LOGE("%s:NULL wma ptr. Exiting", __func__);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pMac = cds_get_context(QDF_MODULE_ID_PE);
+	if (!pMac) {
+		WMA_LOGE("%s:NULL pMac ptr. Exiting", __func__);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* First step is to confirm if MCC is active */
+	if (!lim_is_in_mcc(pMac)) {
+		WMA_LOGD("%s: MCC is not active. Exiting", __func__);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Confirm MCC adaptive scheduler feature is disabled */
+	if (wlan_cfg_get_int(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED,
+			     &cfg_val) == QDF_STATUS_SUCCESS) {
+		if (cfg_val == WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX) {
+			WMA_LOGD("%s: Can't set channel quota while MCC_ADAPTIVE_SCHED is enabled. Exit",
+				 __func__);
+			return QDF_STATUS_SUCCESS;
+		}
+	} else {
+		WMA_LOGE("%s: Failed to retrieve WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED. Exit",
+			__func__);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wmi_unified_set_mcc_channel_time_quota_cmd(wma->wmi_handle,
+						chan1_freq,
+						adapter_1_quota,
+						chan2_freq);
+}
+
+/**
+ * wma_set_linkstate() - set wma linkstate
+ * @wma: wma handle
+ * @params: link state params
+ *
+ * Return: none
+ */
+void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params)
+{
+	struct cdp_pdev *pdev;
+	struct cdp_vdev *vdev;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	uint8_t vdev_id;
+	bool roam_synch_in_progress = false;
+	QDF_STATUS status;
+	struct wma_target_req *msg;
+
+	params->status = true;
+	WMA_LOGD("%s: state %d selfmac %pM", __func__,
+		 params->state, params->selfMacAddr);
+	if ((params->state != eSIR_LINK_PREASSOC_STATE) &&
+	    (params->state != eSIR_LINK_DOWN_STATE)) {
+		WMA_LOGD("%s: unsupported link state %d",
+			 __func__, params->state);
+		params->status = false;
+		goto out;
+	}
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Unable to get TXRX context", __func__);
+		params->status = false;
+		goto out;
+	}
+
+	vdev = wma_find_vdev_by_addr(wma, params->selfMacAddr, &vdev_id);
+	if (!vdev) {
+		WMA_LOGP("%s: vdev not found for addr: %pM",
+			 __func__, params->selfMacAddr);
+		params->status = false;
+		goto out;
+	}
+
+	if (wma_is_vdev_in_ap_mode(wma, vdev_id)) {
+		WMA_LOGD("%s: Ignoring set link req in ap mode", __func__);
+		params->status = false;
+		goto out;
+	}
+
+	if (params->state == eSIR_LINK_PREASSOC_STATE) {
+		if (wma_is_roam_synch_in_progress(wma, vdev_id))
+			roam_synch_in_progress = true;
+		status = wma_create_peer(wma, pdev, vdev, params->bssid,
+				WMI_PEER_TYPE_DEFAULT, vdev_id,
+				roam_synch_in_progress);
+		if (status != QDF_STATUS_SUCCESS) {
+			WMA_LOGE("%s: Unable to create peer", __func__);
+			params->status = false;
+		}
+		if (roam_synch_in_progress)
+			return;
+	} else {
+		WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP",
+			 __func__, vdev_id);
+		cdp_fc_vdev_pause(soc,
+			wma->interfaces[vdev_id].handle,
+			OL_TXQ_PAUSE_REASON_VDEV_STOP);
+		msg = wma_fill_vdev_req(wma, vdev_id,
+				WMA_SET_LINK_STATE,
+				WMA_TARGET_REQ_TYPE_VDEV_STOP, params,
+				WMA_VDEV_STOP_REQUEST_TIMEOUT);
+		if (!msg) {
+			WMA_LOGP(FL("Failed to fill vdev request for vdev_id %d"),
+				 vdev_id);
+			params->status = false;
+			status = QDF_STATUS_E_NOMEM;
+			goto out;
+		}
+		wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST);
+		if (wma_send_vdev_stop_to_fw(wma, vdev_id)) {
+			WMA_LOGP("%s: %d Failed to send vdev stop",
+				 __func__, __LINE__);
+			params->status = false;
+			wma_remove_vdev_req(wma, vdev_id,
+				WMA_TARGET_REQ_TYPE_VDEV_STOP);
+		} else {
+			WMA_LOGP("%s: %d vdev stop sent vdev %d",
+				 __func__, __LINE__, vdev_id);
+			/*
+			 * Remove peer, Vdev down and sending set link
+			 * response will be handled in vdev stop response
+			 * handler
+			 */
+			return;
+		}
+	}
+out:
+	wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
+}
+
+/**
+ * wma_process_rate_update_indate() - rate update indication
+ * @wma: wma handle
+ * @pRateUpdateParams: Rate update params
+ *
+ * This function update rate & short GI interval to fw based on params
+ * send by SME.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_rate_update_indicate(tp_wma_handle wma,
+					    tSirRateUpdateInd *
+					    pRateUpdateParams)
+{
+	int32_t ret = 0;
+	uint8_t vdev_id = 0;
+	void *pdev;
+	int32_t mbpsx10_rate = -1;
+	uint32_t paramId;
+	uint8_t rate = 0;
+	uint32_t short_gi;
+	struct wma_txrx_node *intr = wma->interfaces;
+	QDF_STATUS status;
+
+	/* Get the vdev id */
+	pdev = wma_find_vdev_by_addr(wma, pRateUpdateParams->bssid.bytes,
+					&vdev_id);
+	if (!pdev) {
+		WMA_LOGE("vdev handle is invalid for %pM",
+			 pRateUpdateParams->bssid.bytes);
+		qdf_mem_free(pRateUpdateParams);
+		return QDF_STATUS_E_INVAL;
+	}
+	short_gi = intr[vdev_id].config.shortgi;
+	if (short_gi == 0)
+		short_gi = (intr[vdev_id].rate_flags & TX_RATE_SGI) ?
+								 true : false;
+	/* first check if reliable TX mcast rate is used. If not check the bcast
+	 * Then is mcast. Mcast rate is saved in mcastDataRate24GHz
+	 */
+	if (pRateUpdateParams->reliableMcastDataRateTxFlag > 0) {
+		mbpsx10_rate = pRateUpdateParams->reliableMcastDataRate;
+		paramId = WMI_VDEV_PARAM_MCAST_DATA_RATE;
+		if (pRateUpdateParams->
+		    reliableMcastDataRateTxFlag & TX_RATE_SGI)
+			short_gi = 1;   /* upper layer specified short GI */
+	} else if (pRateUpdateParams->bcastDataRate > -1) {
+		mbpsx10_rate = pRateUpdateParams->bcastDataRate;
+		paramId = WMI_VDEV_PARAM_BCAST_DATA_RATE;
+	} else {
+		mbpsx10_rate = pRateUpdateParams->mcastDataRate24GHz;
+		paramId = WMI_VDEV_PARAM_MCAST_DATA_RATE;
+		if (pRateUpdateParams->
+		    mcastDataRate24GHzTxFlag & TX_RATE_SGI)
+			short_gi = 1;   /* upper layer specified short GI */
+	}
+	WMA_LOGE("%s: dev_id = %d, dev_type = %d, dev_mode = %d,",
+		 __func__, vdev_id, intr[vdev_id].type,
+		 pRateUpdateParams->dev_mode);
+	WMA_LOGE("%s: mac = %pM, config.shortgi = %d, rate_flags = 0x%x",
+		 __func__, pRateUpdateParams->bssid.bytes,
+		 intr[vdev_id].config.shortgi, intr[vdev_id].rate_flags);
+	ret = wma_encode_mc_rate(short_gi, intr[vdev_id].config.chwidth,
+				 intr[vdev_id].chanmode, intr[vdev_id].mhz,
+				 mbpsx10_rate, pRateUpdateParams->nss, &rate);
+	if (ret != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Error, Invalid input rate value", __func__);
+		qdf_mem_free(pRateUpdateParams);
+		return ret;
+	}
+	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					      WMI_VDEV_PARAM_SGI, short_gi);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("%s: Fail to Set WMI_VDEV_PARAM_SGI(%d), status = %d",
+			 __func__, short_gi, status);
+		qdf_mem_free(pRateUpdateParams);
+		return status;
+	}
+	status = wma_vdev_set_param(wma->wmi_handle,
+					      vdev_id, paramId, rate);
+	qdf_mem_free(pRateUpdateParams);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("%s: Fail to Set rate, status = %d", __func__, status);
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_mgmt_tx_ack_comp_hdlr() - handles tx ack mgmt completion
+ * @context: context with which the handler is registered
+ * @netbuf: tx mgmt nbuf
+ * @status: status of tx completion
+ *
+ * This is callback registered with TxRx for
+ * Ack Complete.
+ *
+ * Return: none
+ */
+static void
+wma_mgmt_tx_ack_comp_hdlr(void *wma_context, qdf_nbuf_t netbuf, int32_t status)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) wma_context;
+	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)
+					wma_handle->pdev;
+	uint16_t desc_id;
+
+	desc_id = QDF_NBUF_CB_MGMT_TXRX_DESC_ID(netbuf);
+
+	mgmt_txrx_tx_completion_handler(pdev, desc_id, status, NULL);
+}
+
+/**
+ * wma_mgmt_tx_dload_comp_hldr() - handles tx mgmt completion
+ * @context: context with which the handler is registered
+ * @netbuf: tx mgmt nbuf
+ * @status: status of tx completion
+ *
+ * This function calls registered download callback while sending mgmt packet.
+ *
+ * Return: none
+ */
+static void
+wma_mgmt_tx_dload_comp_hldr(void *wma_context, qdf_nbuf_t netbuf,
+			    int32_t status)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	tp_wma_handle wma_handle = (tp_wma_handle) wma_context;
+	void *mac_context = wma_handle->mac_context;
+
+	WMA_LOGD("Tx Complete Status %d", status);
+
+	if (!wma_handle->tx_frm_download_comp_cb) {
+		WMA_LOGE("Tx Complete Cb not registered by umac");
+		return;
+	}
+
+	/* Call Tx Mgmt Complete Callback registered by umac */
+	wma_handle->tx_frm_download_comp_cb(mac_context, netbuf, 0);
+
+	/* Reset Callback */
+	wma_handle->tx_frm_download_comp_cb = NULL;
+
+	/* Set the Tx Mgmt Complete Event */
+	qdf_status = qdf_event_set(&wma_handle->tx_frm_download_comp_event);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		WMA_LOGP("%s: Event Set failed - tx_frm_comp_event", __func__);
+}
+
+/**
+ * wma_tx_attach() - attach tx related callbacks
+ * @pwmaCtx: wma context
+ *
+ * attaches tx fn with underlying layer.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_tx_attach(tp_wma_handle wma_handle)
+{
+	/* Get the Vos Context */
+	struct cds_context *cds_handle =
+		(struct cds_context *) (wma_handle->cds_context);
+
+	/* Get the txRx Pdev handle */
+	struct cdp_pdev *txrx_pdev = cds_handle->pdev_txrx_ctx;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	/* Register for Tx Management Frames */
+	cdp_mgmt_tx_cb_set(soc, txrx_pdev, 0,
+			wma_mgmt_tx_dload_comp_hldr,
+			wma_mgmt_tx_ack_comp_hdlr, wma_handle);
+
+	/* Store the Mac Context */
+	wma_handle->mac_context = cds_handle->mac_context;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_tx_detach() - detach tx related callbacks
+ * @tp_wma_handle: wma context
+ *
+ * Deregister with TxRx for Tx Mgmt Download and Ack completion.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_tx_detach(tp_wma_handle wma_handle)
+{
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	/* Get the Vos Context */
+	struct cds_context *cds_handle =
+		(struct cds_context *) (wma_handle->cds_context);
+
+	/* Get the txRx Pdev handle */
+	struct cdp_pdev *txrx_pdev = cds_handle->pdev_txrx_ctx;
+
+	if (!soc) {
+		WMA_LOGE("%s:SOC context is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (txrx_pdev) {
+		/* Deregister with TxRx for Tx Mgmt completion call back */
+		cdp_mgmt_tx_cb_set(soc, txrx_pdev, 0, NULL, NULL, txrx_pdev);
+	}
+
+	/* Reset Tx Frm Callbacks */
+	wma_handle->tx_frm_download_comp_cb = NULL;
+
+	/* Reset Tx Data Frame Ack Cb */
+	wma_handle->umac_data_ota_ack_cb = NULL;
+
+	/* Reset last Tx Data Frame nbuf ptr */
+	wma_handle->last_umac_data_nbuf = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \
+	defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(CONFIG_HL_SUPPORT)
+
+/**
+ * wma_mcc_vdev_tx_pause_evt_handler() - pause event handler
+ * @handle: wma handle
+ * @event: event buffer
+ * @len: data length
+ *
+ * This function handle pause event from fw and pause/unpause
+ * vdev.
+ *
+ * Return: 0 for success or error code.
+ */
+int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event,
+				      uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_TX_PAUSE_EVENTID_param_tlvs *param_buf;
+	wmi_tx_pause_event_fixed_param *wmi_event;
+	uint8_t vdev_id;
+	A_UINT32 vdev_map;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	param_buf = (WMI_TX_PAUSE_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("Invalid roam event buffer");
+		return -EINVAL;
+	}
+
+	if (ucfg_pmo_get_wow_bus_suspend(wma->psoc)) {
+		WMA_LOGD(" Suspend is in progress: Pause/Unpause Tx is NoOp");
+		return 0;
+	}
+
+	if (!soc) {
+		WMA_LOGE("%s:SOC context is NULL", __func__);
+		return -EINVAL;
+	}
+
+	wmi_event = param_buf->fixed_param;
+	vdev_map = wmi_event->vdev_map;
+	/* FW mapped vdev from ID
+	 * vdev_map = (1 << vdev_id)
+	 * So, host should unmap to ID
+	 */
+	for (vdev_id = 0; vdev_map != 0 && vdev_id < wma->max_bssid;
+	     vdev_id++) {
+		if (!(vdev_map & 0x1)) {
+			/* No Vdev */
+		} else {
+			if (!wma->interfaces[vdev_id].handle) {
+				WMA_LOGE("%s: invalid vdev ID %d", __func__,
+					 vdev_id);
+				/* Test Next VDEV */
+				vdev_map >>= 1;
+				continue;
+			}
+
+			/* PAUSE action, add bitmap */
+			if (ACTION_PAUSE == wmi_event->action) {
+				/*
+				 * Now only support per-dev pause so it is not
+				 * necessary to pause a paused queue again.
+				 */
+				if (!wma_vdev_get_pause_bitmap(vdev_id))
+					cdp_fc_vdev_pause(soc,
+						wma->
+						interfaces[vdev_id].handle,
+						OL_TXQ_PAUSE_REASON_FW);
+				wma_vdev_set_pause_bit(vdev_id,
+					wmi_event->pause_type);
+			}
+			/* UNPAUSE action, clean bitmap */
+			else if (ACTION_UNPAUSE == wmi_event->action) {
+				/* Handle unpause only if already paused */
+				if (wma_vdev_get_pause_bitmap(vdev_id)) {
+					wma_vdev_clear_pause_bit(vdev_id,
+						wmi_event->pause_type);
+
+					if (!wma->interfaces[vdev_id].
+					    pause_bitmap) {
+						/* PAUSE BIT MAP is cleared
+						 * UNPAUSE VDEV
+						 */
+						cdp_fc_vdev_unpause(soc,
+							wma->interfaces[vdev_id]
+							.handle,
+							OL_TXQ_PAUSE_REASON_FW);
+					}
+				}
+			} else {
+				WMA_LOGE("Not Valid Action Type %d",
+					 wmi_event->action);
+			}
+
+			WMA_LOGD
+				("vdev_id %d, pause_map 0x%x, pause type %d, action %d",
+				vdev_id, wma_vdev_get_pause_bitmap(vdev_id),
+				wmi_event->pause_type, wmi_event->action);
+		}
+		/* Test Next VDEV */
+		vdev_map >>= 1;
+	}
+
+	return 0;
+}
+
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+
+#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
+
+/**
+ * wma_set_peer_rate_report_condition -
+ *                    this function set peer rate report
+ *                    condition info to firmware.
+ * @handle:	Handle of WMA
+ * @config:	Bad peer configuration from SIR module
+ *
+ * It is a wrapper function to sent WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID
+ * to the firmare\target.If the command sent to firmware failed, free the
+ * buffer that allocated.
+ *
+ * Return: QDF_STATUS based on values sent to firmware
+ */
+static
+QDF_STATUS wma_set_peer_rate_report_condition(WMA_HANDLE handle,
+			struct t_bad_peer_txtcl_config *config)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle)handle;
+	struct wmi_peer_rate_report_params rate_report_params = {0};
+	u_int32_t i, j;
+
+	rate_report_params.rate_report_enable = config->enable;
+	rate_report_params.backoff_time = config->tgt_backoff;
+	rate_report_params.timer_period = config->tgt_report_prd;
+	for (i = 0; i < WMI_PEER_RATE_REPORT_COND_MAX_NUM; i++) {
+		rate_report_params.report_per_phy[i].cond_flags =
+			config->threshold[i].cond;
+		rate_report_params.report_per_phy[i].delta.delta_min  =
+			config->threshold[i].delta;
+		rate_report_params.report_per_phy[i].delta.percent =
+			config->threshold[i].percentage;
+		for (j = 0; j < WMI_MAX_NUM_OF_RATE_THRESH; j++) {
+			rate_report_params.report_per_phy[i].
+				report_rate_threshold[j] =
+					config->threshold[i].thresh[j];
+		}
+	}
+
+	return wmi_unified_peer_rate_report_cmd(wma_handle->wmi_handle,
+						&rate_report_params);
+}
+
+/**
+ * wma_process_init_bad_peer_tx_ctl_info -
+ *                this function to initialize peer rate report config info.
+ * @handle:	Handle of WMA
+ * @config:	Bad peer configuration from SIR module
+ *
+ * This function initializes the bad peer tx control data structure in WMA,
+ * sends down the initial configuration to the firmware and configures
+ * the peer status update seeting in the tx_rx module.
+ *
+ * Return: QDF_STATUS based on procedure status
+ */
+
+QDF_STATUS wma_process_init_bad_peer_tx_ctl_info(tp_wma_handle wma,
+					struct t_bad_peer_txtcl_config *config)
+{
+	/* Parameter sanity check */
+	struct cdp_pdev *curr_pdev;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (NULL == wma || NULL == config) {
+		WMA_LOGE("%s Invalid input\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	curr_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (NULL == curr_pdev) {
+		WMA_LOGE("%s: Failed to get pdev\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGE("%s enable %d period %d txq limit %d\n", __func__,
+		 config->enable,
+		 config->period,
+		 config->txq_limit);
+
+	/* Only need to initialize the setting
+	 * when the feature is enabled
+	 */
+	if (config->enable) {
+		int i = 0;
+
+		cdp_bad_peer_txctl_set_setting(soc,
+					curr_pdev,
+					config->enable,
+					config->period,
+					config->txq_limit);
+
+		for (i = 0; i < WLAN_WMA_IEEE80211_MAX_LEVEL; i++) {
+			u_int32_t threshold, limit;
+
+			threshold = config->threshold[i].thresh[0];
+			limit =	config->threshold[i].txlimit;
+			cdp_bad_peer_txctl_update_threshold(soc,
+						curr_pdev,
+						i,
+						threshold,
+						limit);
+		}
+	}
+
+	return wma_set_peer_rate_report_condition(wma, config);
+}
+#endif /* defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL) */
+
+
+/**
+ * wma_process_init_thermal_info() - initialize thermal info
+ * @wma: Pointer to WMA handle
+ * @pThermalParams: Pointer to thermal mitigation parameters
+ *
+ * This function initializes the thermal management table in WMA,
+ * sends down the initial temperature thresholds to the firmware
+ * and configures the throttle period in the tx rx module
+ *
+ * Returns: QDF_STATUS_SUCCESS for success otherwise failure
+ */
+QDF_STATUS wma_process_init_thermal_info(tp_wma_handle wma,
+					 t_thermal_mgmt *pThermalParams)
+{
+	t_thermal_cmd_params thermal_params;
+	struct cdp_pdev *curr_pdev;
+
+	if (NULL == wma || NULL == pThermalParams) {
+		WMA_LOGE("TM Invalid input");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	curr_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (NULL == curr_pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("TM enable %d period %d", pThermalParams->thermalMgmtEnabled,
+		 pThermalParams->throttlePeriod);
+
+	WMA_LOGD("Throttle Duty Cycle Level in percentage:\n"
+		 "0 %d\n"
+		 "1 %d\n"
+		 "2 %d\n"
+		 "3 %d",
+		 pThermalParams->throttle_duty_cycle_tbl[0],
+		 pThermalParams->throttle_duty_cycle_tbl[1],
+		 pThermalParams->throttle_duty_cycle_tbl[2],
+		 pThermalParams->throttle_duty_cycle_tbl[3]);
+
+	wma->thermal_mgmt_info.thermalMgmtEnabled =
+		pThermalParams->thermalMgmtEnabled;
+	wma->thermal_mgmt_info.thermalLevels[0].minTempThreshold =
+		pThermalParams->thermalLevels[0].minTempThreshold;
+	wma->thermal_mgmt_info.thermalLevels[0].maxTempThreshold =
+		pThermalParams->thermalLevels[0].maxTempThreshold;
+	wma->thermal_mgmt_info.thermalLevels[1].minTempThreshold =
+		pThermalParams->thermalLevels[1].minTempThreshold;
+	wma->thermal_mgmt_info.thermalLevels[1].maxTempThreshold =
+		pThermalParams->thermalLevels[1].maxTempThreshold;
+	wma->thermal_mgmt_info.thermalLevels[2].minTempThreshold =
+		pThermalParams->thermalLevels[2].minTempThreshold;
+	wma->thermal_mgmt_info.thermalLevels[2].maxTempThreshold =
+		pThermalParams->thermalLevels[2].maxTempThreshold;
+	wma->thermal_mgmt_info.thermalLevels[3].minTempThreshold =
+		pThermalParams->thermalLevels[3].minTempThreshold;
+	wma->thermal_mgmt_info.thermalLevels[3].maxTempThreshold =
+		pThermalParams->thermalLevels[3].maxTempThreshold;
+	wma->thermal_mgmt_info.thermalCurrLevel = WLAN_WMA_THERMAL_LEVEL_0;
+
+	WMA_LOGD("TM level min max:\n"
+		 "0 %d   %d\n"
+		 "1 %d   %d\n"
+		 "2 %d   %d\n"
+		 "3 %d   %d",
+		 wma->thermal_mgmt_info.thermalLevels[0].minTempThreshold,
+		 wma->thermal_mgmt_info.thermalLevels[0].maxTempThreshold,
+		 wma->thermal_mgmt_info.thermalLevels[1].minTempThreshold,
+		 wma->thermal_mgmt_info.thermalLevels[1].maxTempThreshold,
+		 wma->thermal_mgmt_info.thermalLevels[2].minTempThreshold,
+		 wma->thermal_mgmt_info.thermalLevels[2].maxTempThreshold,
+		 wma->thermal_mgmt_info.thermalLevels[3].minTempThreshold,
+		 wma->thermal_mgmt_info.thermalLevels[3].maxTempThreshold);
+
+	if (wma->thermal_mgmt_info.thermalMgmtEnabled) {
+		cdp_throttle_init_period(cds_get_context(QDF_MODULE_ID_SOC),
+				curr_pdev,
+				pThermalParams->throttlePeriod,
+				&pThermalParams->throttle_duty_cycle_tbl[0]);
+
+		/* Get the temperature thresholds to set in firmware */
+		thermal_params.minTemp =
+			wma->thermal_mgmt_info.thermalLevels[WLAN_WMA_THERMAL_LEVEL_0].minTempThreshold;
+		thermal_params.maxTemp =
+			wma->thermal_mgmt_info.thermalLevels[WLAN_WMA_THERMAL_LEVEL_0].maxTempThreshold;
+		thermal_params.thermalEnable =
+			wma->thermal_mgmt_info.thermalMgmtEnabled;
+
+		WMA_LOGE("TM sending the following to firmware: min %d max %d enable %d",
+			thermal_params.minTemp, thermal_params.maxTemp,
+			thermal_params.thermalEnable);
+
+		if (QDF_STATUS_SUCCESS !=
+		    wma_set_thermal_mgmt(wma, thermal_params)) {
+			WMA_LOGE("Could not send thermal mgmt command to the firmware!");
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_set_thermal_level_ind() - send SME set thermal level indication message
+ * @level:  thermal level
+ *
+ * Send SME SET_THERMAL_LEVEL_IND message
+ *
+ * Returns: none
+ */
+static void wma_set_thermal_level_ind(u_int8_t level)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg sme_msg = {0};
+
+	WMA_LOGI(FL("Thermal level: %d"), level);
+
+	sme_msg.type = eWNI_SME_SET_THERMAL_LEVEL_IND;
+	sme_msg.bodyptr = NULL;
+	sme_msg.bodyval = level;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		WMA_LOGE(FL(
+			"Fail to post set thermal level ind msg"));
+}
+
+/**
+ * wma_process_set_thermal_level() - sets thermal level
+ * @wma: Pointer to WMA handle
+ * @thermal_level : Thermal level
+ *
+ * This function sets the new thermal throttle level in the
+ * txrx module and sends down the corresponding temperature
+ * thresholds to the firmware
+ *
+ * Returns: QDF_STATUS_SUCCESS for success otherwise failure
+ */
+QDF_STATUS wma_process_set_thermal_level(tp_wma_handle wma,
+					 uint8_t thermal_level)
+{
+	struct cdp_pdev *curr_pdev;
+
+	if (NULL == wma) {
+		WMA_LOGE("TM Invalid input");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	curr_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (NULL == curr_pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGE("TM set level %d", thermal_level);
+
+	/* Check if thermal mitigation is enabled */
+	if (!wma->thermal_mgmt_info.thermalMgmtEnabled) {
+		WMA_LOGE("Thermal mgmt is not enabled, ignoring set level command");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (thermal_level >= WLAN_WMA_MAX_THERMAL_LEVELS) {
+		WMA_LOGE("Invalid thermal level set %d", thermal_level);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (thermal_level == wma->thermal_mgmt_info.thermalCurrLevel) {
+		WMA_LOGD("Current level %d is same as the set level, ignoring",
+			 wma->thermal_mgmt_info.thermalCurrLevel);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	wma->thermal_mgmt_info.thermalCurrLevel = thermal_level;
+
+	cdp_throttle_set_level(cds_get_context(QDF_MODULE_ID_SOC),
+			curr_pdev,
+			thermal_level);
+
+	/* Send SME SET_THERMAL_LEVEL_IND message */
+	wma_set_thermal_level_ind(thermal_level);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
+/**
+ * wma_set_thermal_mgmt() - set thermal mgmt command to fw
+ * @wma_handle: Pointer to WMA handle
+ * @thermal_info: Thermal command information
+ *
+ * This function sends the thermal management command
+ * to the firmware
+ *
+ * Return: QDF_STATUS_SUCCESS for success otherwise failure
+ */
+QDF_STATUS wma_set_thermal_mgmt(tp_wma_handle wma_handle,
+				t_thermal_cmd_params thermal_info)
+{
+	struct thermal_cmd_params mgmt_thermal_info = {0};
+
+	if (!wma_handle) {
+		wma_err("Invalid input");
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mgmt_thermal_info.min_temp = thermal_info.minTemp;
+	mgmt_thermal_info.max_temp = thermal_info.maxTemp;
+	mgmt_thermal_info.thermal_enable = thermal_info.thermalEnable;
+
+	return wmi_unified_set_thermal_mgmt_cmd(wma_handle->wmi_handle,
+						&mgmt_thermal_info);
+}
+
+/**
+ * wma_thermal_mgmt_get_level() - returns throttle level
+ * @handle: Pointer to WMA handle
+ * @temp: temperature
+ *
+ * This function returns the thermal(throttle) level
+ * given the temperature
+ *
+ * Return: thermal (throttle) level
+ */
+static uint8_t wma_thermal_mgmt_get_level(void *handle, uint32_t temp)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	int i;
+	uint8_t level;
+
+	level = i = wma->thermal_mgmt_info.thermalCurrLevel;
+	while (temp < wma->thermal_mgmt_info.thermalLevels[i].minTempThreshold
+	       && i > 0) {
+		i--;
+		level = i;
+	}
+
+	i = wma->thermal_mgmt_info.thermalCurrLevel;
+	while (temp > wma->thermal_mgmt_info.thermalLevels[i].maxTempThreshold
+	       && i < (WLAN_WMA_MAX_THERMAL_LEVELS - 1)) {
+		i++;
+		level = i;
+	}
+
+	WMA_LOGW("Change thermal level from %d -> %d\n",
+		 wma->thermal_mgmt_info.thermalCurrLevel, level);
+
+	return level;
+}
+
+/**
+ * wma_thermal_mgmt_evt_handler() - thermal mgmt event handler
+ * @wma_handle: Pointer to WMA handle
+ * @event: Thermal event information
+ *
+ * This function handles the thermal mgmt event from the firmware len
+ *
+ * Return: 0 for success otherwise failure
+ */
+int wma_thermal_mgmt_evt_handler(void *handle, uint8_t *event,
+					uint32_t len)
+{
+	tp_wma_handle wma;
+	wmi_thermal_mgmt_event_fixed_param *tm_event;
+	uint8_t thermal_level;
+	t_thermal_cmd_params thermal_params;
+	WMI_THERMAL_MGMT_EVENTID_param_tlvs *param_buf;
+	struct cdp_pdev *curr_pdev;
+
+	if (NULL == event || NULL == handle) {
+		WMA_LOGE("Invalid thermal mitigation event buffer");
+		return -EINVAL;
+	}
+
+	wma = (tp_wma_handle) handle;
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: Failed to get wma handle", __func__);
+		return -EINVAL;
+	}
+
+	param_buf = (WMI_THERMAL_MGMT_EVENTID_param_tlvs *) event;
+
+	curr_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (NULL == curr_pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		return -EINVAL;
+	}
+
+	/* Check if thermal mitigation is enabled */
+	if (!wma->thermal_mgmt_info.thermalMgmtEnabled) {
+		WMA_LOGE("Thermal mgmt is not enabled, ignoring event");
+		return -EINVAL;
+	}
+
+	tm_event = param_buf->fixed_param;
+	WMA_LOGD("Thermal mgmt event received with temperature %d",
+		 tm_event->temperature_degreeC);
+
+	/* Get the thermal mitigation level for the reported temperature */
+	thermal_level = wma_thermal_mgmt_get_level(handle,
+					tm_event->temperature_degreeC);
+	WMA_LOGD("Thermal mgmt level  %d", thermal_level);
+
+	if (thermal_level == wma->thermal_mgmt_info.thermalCurrLevel) {
+		WMA_LOGD("Current level %d is same as the set level, ignoring",
+			 wma->thermal_mgmt_info.thermalCurrLevel);
+		return 0;
+	}
+
+	wma->thermal_mgmt_info.thermalCurrLevel = thermal_level;
+
+	/* Inform txrx */
+	cdp_throttle_set_level(cds_get_context(QDF_MODULE_ID_SOC),
+			curr_pdev,
+			thermal_level);
+
+	/* Send SME SET_THERMAL_LEVEL_IND message */
+	wma_set_thermal_level_ind(thermal_level);
+
+	/* Get the temperature thresholds to set in firmware */
+	thermal_params.minTemp =
+		wma->thermal_mgmt_info.thermalLevels[thermal_level].
+		minTempThreshold;
+	thermal_params.maxTemp =
+		wma->thermal_mgmt_info.thermalLevels[thermal_level].
+		maxTempThreshold;
+	thermal_params.thermalEnable =
+		wma->thermal_mgmt_info.thermalMgmtEnabled;
+
+	if (QDF_STATUS_SUCCESS != wma_set_thermal_mgmt(wma, thermal_params)) {
+		WMA_LOGE("Could not send thermal mgmt command to the firmware!");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_ibss_peer_info_event_handler() - IBSS peer info event handler
+ * @handle: wma handle
+ * @data: event data
+ * @len: length of data
+ *
+ * This function handles IBSS peer info event from FW.
+ *
+ * Return: 0 for success or error code
+ */
+int wma_ibss_peer_info_event_handler(void *handle, uint8_t *data,
+					    uint32_t len)
+{
+	struct scheduler_msg cds_msg = {0};
+	wmi_peer_info *peer_info;
+	void *pdev;
+	tSirIbssPeerInfoParams *pSmeRsp;
+	uint32_t count, num_peers, status;
+	tSirIbssGetPeerInfoRspParams *pRsp;
+	WMI_PEER_INFO_EVENTID_param_tlvs *param_tlvs;
+	wmi_peer_info_event_fixed_param *fix_param;
+	uint8_t peer_mac[IEEE80211_ADDR_LEN];
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (NULL == pdev) {
+		WMA_LOGE("%s: could not get pdev context", __func__);
+		return 0;
+	}
+
+	param_tlvs = (WMI_PEER_INFO_EVENTID_param_tlvs *) data;
+	fix_param = param_tlvs->fixed_param;
+	peer_info = param_tlvs->peer_info;
+	num_peers = fix_param->num_peers;
+	status = 0;
+
+	WMA_LOGE("%s: num_peers %d", __func__, num_peers);
+
+	pRsp = qdf_mem_malloc(sizeof(tSirIbssGetPeerInfoRspParams));
+	if (!pRsp)
+		return 0;
+
+	/*sanity check */
+	if (!(num_peers) || (num_peers > 32) ||
+	     (num_peers > param_tlvs->num_peer_info) ||
+	     (!peer_info)) {
+		WMA_LOGE("%s: Invalid event data from target num_peers %d peer_info %pK",
+			__func__, num_peers, peer_info);
+		status = 1;
+		goto send_response;
+	}
+
+	/*
+	 *For displaying only connected IBSS peer info, iterate till
+	 *last but one entry only as last entry is used for IBSS creator
+	 */
+	for (count = 0; count < num_peers-1; count++) {
+		pSmeRsp = &pRsp->ibssPeerInfoRspParams.peerInfoParams[count];
+
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_info->peer_mac_address,
+					   peer_mac);
+		qdf_mem_copy(pSmeRsp->mac_addr, peer_mac,
+			sizeof(pSmeRsp->mac_addr));
+		pSmeRsp->mcsIndex = 0;
+		pSmeRsp->rssi = peer_info->rssi + WMA_TGT_NOISE_FLOOR_DBM;
+		pSmeRsp->txRate = peer_info->data_rate;
+		pSmeRsp->txRateFlags = 0;
+
+		WMA_LOGE("peer " MAC_ADDRESS_STR "rssi %d txRate %d",
+			MAC_ADDR_ARRAY(peer_mac),
+			pSmeRsp->rssi, pSmeRsp->txRate);
+
+		peer_info++;
+	}
+
+send_response:
+	/* message header */
+	pRsp->mesgType = eWNI_SME_IBSS_PEER_INFO_RSP;
+	pRsp->mesgLen = sizeof(tSirIbssGetPeerInfoRspParams);
+	pRsp->ibssPeerInfoRspParams.status = status;
+	pRsp->ibssPeerInfoRspParams.numPeers = num_peers;
+
+	/* cds message wrapper */
+	cds_msg.type = eWNI_SME_IBSS_PEER_INFO_RSP;
+	cds_msg.bodyptr = (void *)pRsp;
+	cds_msg.bodyval = 0;
+
+	if (QDF_STATUS_SUCCESS !=
+	    scheduler_post_message(QDF_MODULE_ID_WMA,
+				   QDF_MODULE_ID_SME,
+				   QDF_MODULE_ID_SME,  &cds_msg)) {
+		WMA_LOGE("%s: could not post peer info rsp msg to SME",
+			 __func__);
+		/* free the mem and return */
+		qdf_mem_free((void *)pRsp);
+	}
+
+	return 0;
+}
+
+/**
+ * wma_fast_tx_fail_event_handler() -tx failure event handler
+ * @handle: wma handle
+ * @data: event data
+ * @len: data length
+ *
+ * Handle fast tx failure indication event from FW
+ *
+ * Return: 0 for success or error code.
+ */
+int wma_fast_tx_fail_event_handler(void *handle, uint8_t *data,
+					  uint32_t len)
+{
+	uint8_t tx_fail_cnt;
+	uint8_t peer_mac[IEEE80211_ADDR_LEN];
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_PEER_TX_FAIL_CNT_THR_EVENTID_param_tlvs *param_tlvs;
+	wmi_peer_tx_fail_cnt_thr_event_fixed_param *fix_param;
+
+	param_tlvs = (WMI_PEER_TX_FAIL_CNT_THR_EVENTID_param_tlvs *) data;
+	fix_param = param_tlvs->fixed_param;
+
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->peer_mac_address, peer_mac);
+	WMA_LOGE("%s: received fast tx failure event for peer 0x:%2x:0x%2x:0x%2x:0x%2x:0x%2x:0x%2x seq No %d",
+		 __func__,
+		 peer_mac[0], peer_mac[1], peer_mac[2], peer_mac[3],
+		 peer_mac[4], peer_mac[5], fix_param->seq_no);
+
+	tx_fail_cnt = fix_param->seq_no;
+
+	/*call HDD callback */
+	if (wma->hddTxFailCb != NULL)
+		wma->hddTxFailCb(peer_mac, tx_fail_cnt);
+	else
+		WMA_LOGE("%s: HDD callback is %pK", __func__, wma->hddTxFailCb);
+
+	return 0;
+}
+
+/**
+ * wma_decap_to_8023() - Decapsulate to 802.3 format
+ * @msdu: skb buffer
+ * @info: decapsulate info
+ *
+ * Return: none
+ */
+static void wma_decap_to_8023(qdf_nbuf_t msdu, struct wma_decap_info_t *info)
+{
+	struct llc_snap_hdr_t *llc_hdr;
+	uint16_t ether_type;
+	uint16_t l2_hdr_space;
+	struct ieee80211_qosframe_addr4 *wh;
+	uint8_t local_buf[ETHERNET_HDR_LEN];
+	uint8_t *buf;
+	struct ethernet_hdr_t *ethr_hdr;
+
+	buf = (uint8_t *) qdf_nbuf_data(msdu);
+	llc_hdr = (struct llc_snap_hdr_t *)buf;
+	ether_type = (llc_hdr->ethertype[0] << 8) | llc_hdr->ethertype[1];
+	/* do llc remove if needed */
+	l2_hdr_space = 0;
+	if (IS_SNAP(llc_hdr)) {
+		if (IS_BTEP(llc_hdr)) {
+			/* remove llc */
+			l2_hdr_space += sizeof(struct llc_snap_hdr_t);
+			llc_hdr = NULL;
+		} else if (IS_RFC1042(llc_hdr)) {
+			if (!(ether_type == ETHERTYPE_AARP ||
+			      ether_type == ETHERTYPE_IPX)) {
+				/* remove llc */
+				l2_hdr_space += sizeof(struct llc_snap_hdr_t);
+				llc_hdr = NULL;
+			}
+		}
+	}
+	if (l2_hdr_space > ETHERNET_HDR_LEN)
+		buf = qdf_nbuf_pull_head(msdu, l2_hdr_space - ETHERNET_HDR_LEN);
+	else if (l2_hdr_space < ETHERNET_HDR_LEN)
+		buf = qdf_nbuf_push_head(msdu, ETHERNET_HDR_LEN - l2_hdr_space);
+
+	/* mpdu hdr should be present in info,re-create ethr_hdr based on
+	 * mpdu hdr
+	 */
+	wh = (struct ieee80211_qosframe_addr4 *)info->hdr;
+	ethr_hdr = (struct ethernet_hdr_t *)local_buf;
+	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
+	case IEEE80211_FC1_DIR_NODS:
+		qdf_mem_copy(ethr_hdr->dest_addr, wh->i_addr1,
+			     ETHERNET_ADDR_LEN);
+		qdf_mem_copy(ethr_hdr->src_addr, wh->i_addr2,
+			     ETHERNET_ADDR_LEN);
+		break;
+	case IEEE80211_FC1_DIR_TODS:
+		qdf_mem_copy(ethr_hdr->dest_addr, wh->i_addr3,
+			     ETHERNET_ADDR_LEN);
+		qdf_mem_copy(ethr_hdr->src_addr, wh->i_addr2,
+			     ETHERNET_ADDR_LEN);
+		break;
+	case IEEE80211_FC1_DIR_FROMDS:
+		qdf_mem_copy(ethr_hdr->dest_addr, wh->i_addr1,
+			     ETHERNET_ADDR_LEN);
+		qdf_mem_copy(ethr_hdr->src_addr, wh->i_addr3,
+			     ETHERNET_ADDR_LEN);
+		break;
+	case IEEE80211_FC1_DIR_DSTODS:
+		qdf_mem_copy(ethr_hdr->dest_addr, wh->i_addr3,
+			     ETHERNET_ADDR_LEN);
+		qdf_mem_copy(ethr_hdr->src_addr, wh->i_addr4,
+			     ETHERNET_ADDR_LEN);
+		break;
+	}
+
+	if (llc_hdr == NULL) {
+		ethr_hdr->ethertype[0] = (ether_type >> 8) & 0xff;
+		ethr_hdr->ethertype[1] = (ether_type) & 0xff;
+	} else {
+		uint32_t pktlen =
+			qdf_nbuf_len(msdu) - sizeof(ethr_hdr->ethertype);
+		ether_type = (uint16_t) pktlen;
+		ether_type = qdf_nbuf_len(msdu) - sizeof(struct ethernet_hdr_t);
+		ethr_hdr->ethertype[0] = (ether_type >> 8) & 0xff;
+		ethr_hdr->ethertype[1] = (ether_type) & 0xff;
+	}
+	qdf_mem_copy(buf, ethr_hdr, ETHERNET_HDR_LEN);
+}
+
+/**
+ * wma_ieee80211_hdrsize() - get 802.11 header size
+ * @data: 80211 frame
+ *
+ * Return: size of header
+ */
+static int32_t wma_ieee80211_hdrsize(const void *data)
+{
+	const struct ieee80211_frame *wh = (const struct ieee80211_frame *)data;
+	int32_t size = sizeof(struct ieee80211_frame);
+
+	if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
+		size += IEEE80211_ADDR_LEN;
+	if (IEEE80211_QOS_HAS_SEQ(wh))
+		size += sizeof(uint16_t);
+	return size;
+}
+
+/**
+ * rate_pream: Mapping from data rates to preamble.
+ */
+static uint32_t rate_pream[] = {WMI_RATE_PREAMBLE_CCK, WMI_RATE_PREAMBLE_CCK,
+				WMI_RATE_PREAMBLE_CCK, WMI_RATE_PREAMBLE_CCK,
+				WMI_RATE_PREAMBLE_OFDM, WMI_RATE_PREAMBLE_OFDM,
+				WMI_RATE_PREAMBLE_OFDM, WMI_RATE_PREAMBLE_OFDM,
+				WMI_RATE_PREAMBLE_OFDM, WMI_RATE_PREAMBLE_OFDM,
+				WMI_RATE_PREAMBLE_OFDM, WMI_RATE_PREAMBLE_OFDM};
+
+/**
+ * rate_mcs: Mapping from data rates to MCS (+4 for OFDM to keep the sequence).
+ */
+static uint32_t rate_mcs[] = {WMI_MAX_CCK_TX_RATE_1M, WMI_MAX_CCK_TX_RATE_2M,
+			      WMI_MAX_CCK_TX_RATE_5_5M, WMI_MAX_CCK_TX_RATE_11M,
+			      WMI_MAX_OFDM_TX_RATE_6M + 4,
+			      WMI_MAX_OFDM_TX_RATE_9M + 4,
+			      WMI_MAX_OFDM_TX_RATE_12M + 4,
+			      WMI_MAX_OFDM_TX_RATE_18M + 4,
+			      WMI_MAX_OFDM_TX_RATE_24M + 4,
+			      WMI_MAX_OFDM_TX_RATE_36M + 4,
+			      WMI_MAX_OFDM_TX_RATE_48M + 4,
+			      WMI_MAX_OFDM_TX_RATE_54M + 4};
+
+#define WMA_TX_SEND_MGMT_TYPE 0
+#define WMA_TX_SEND_DATA_TYPE 1
+
+/**
+ * wma_update_tx_send_params() - Update tx_send_params TLV info
+ * @tx_param: Pointer to tx_send_params
+ * @rid: rate ID passed by PE
+ *
+ * Return: None
+ */
+static void wma_update_tx_send_params(struct tx_send_params *tx_param,
+				      enum rateid rid)
+{
+	uint8_t  preamble = 0, nss = 0, rix = 0;
+
+	preamble = rate_pream[rid];
+	rix = rate_mcs[rid];
+
+	tx_param->mcs_mask = (1 << rix);
+	tx_param->nss_mask = (1 << nss);
+	tx_param->preamble_type = (1 << preamble);
+	tx_param->frame_type = WMA_TX_SEND_MGMT_TYPE;
+
+	WMA_LOGD(FL("rate_id: %d, mcs: %0x, nss: %0x, preamble: %0x"),
+		     rid, tx_param->mcs_mask, tx_param->nss_mask,
+		     tx_param->preamble_type);
+}
+
+/**
+ * wma_tx_packet() - Sends Tx Frame to TxRx
+ * @wma_context: wma context
+ * @tx_frame: frame buffer
+ * @frmLen: frame length
+ * @frmType: frame type
+ * @txDir: tx diection
+ * @tid: TID
+ * @tx_frm_download_comp_cb: tx download callback handler
+ * @tx_frm_ota_comp_cb: OTA complition handler
+ * @tx_flag: tx flag
+ * @vdev_id: vdev id
+ * @tdlsFlag: tdls flag
+ *
+ * This function sends the frame corresponding to the
+ * given vdev id.
+ * This is blocking call till the downloading of frame is complete.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen,
+			 eFrameType frmType, eFrameTxDir txDir, uint8_t tid,
+			 wma_tx_dwnld_comp_callback tx_frm_download_comp_cb,
+			 void *pData,
+			 wma_tx_ota_comp_callback tx_frm_ota_comp_cb,
+			 uint8_t tx_flag, uint8_t vdev_id, bool tdlsFlag,
+			 uint16_t channel_freq, enum rateid rid)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) (wma_context);
+	int32_t status;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	int32_t is_high_latency;
+	struct cdp_vdev *txrx_vdev;
+	enum frame_index tx_frm_index = GENERIC_NODOWNLD_NOACK_COMP_INDEX;
+	tpSirMacFrameCtl pFc = (tpSirMacFrameCtl) (qdf_nbuf_data(tx_frame));
+	uint8_t use_6mbps = 0;
+	uint8_t downld_comp_required = 0;
+	uint16_t chanfreq;
+#ifdef WLAN_FEATURE_11W
+	uint8_t *pFrame = NULL;
+	void *pPacket = NULL;
+	uint16_t newFrmLen = 0;
+#endif /* WLAN_FEATURE_11W */
+	struct wma_txrx_node *iface;
+	tpAniSirGlobal pMac;
+	tpSirMacMgmtHdr mHdr;
+	struct wmi_mgmt_params mgmt_param = {0};
+	struct cdp_cfg *ctrl_pdev;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct ieee80211_frame *wh;
+	struct wlan_objmgr_peer *peer = NULL;
+	struct wlan_objmgr_psoc *psoc;
+	void *mac_addr;
+	bool is_5g = false;
+	uint8_t pdev_id;
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("wma_handle is NULL");
+		cds_packet_free((void *)tx_frame);
+		return QDF_STATUS_E_FAILURE;
+	}
+	iface = &wma_handle->interfaces[vdev_id];
+	/* Get the vdev handle from vdev id */
+	txrx_vdev = wma_handle->interfaces[vdev_id].handle;
+
+	if (!txrx_vdev) {
+		WMA_LOGE("TxRx Vdev Handle is NULL");
+		cds_packet_free((void *)tx_frame);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!soc) {
+		WMA_LOGE("%s:SOC context is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cdp_hl_tdls_flag_reset(soc, txrx_vdev, false);
+
+	if (frmType >= TXRX_FRM_MAX) {
+		WMA_LOGE("Invalid Frame Type Fail to send Frame");
+		cds_packet_free((void *)tx_frame);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pMac = cds_get_context(QDF_MODULE_ID_PE);
+	if (!pMac) {
+		WMA_LOGE("pMac Handle is NULL");
+		cds_packet_free((void *)tx_frame);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/*
+	 * Currently only support to
+	 * send 80211 Mgmt and 80211 Data are added.
+	 */
+	if (!((frmType == TXRX_FRM_802_11_MGMT) ||
+	      (frmType == TXRX_FRM_802_11_DATA))) {
+		WMA_LOGE("No Support to send other frames except 802.11 Mgmt/Data");
+		cds_packet_free((void *)tx_frame);
+		return QDF_STATUS_E_FAILURE;
+	}
+#ifdef WLAN_FEATURE_11W
+	if ((iface && iface->rmfEnabled) &&
+	    (frmType == TXRX_FRM_802_11_MGMT) &&
+	    (pFc->subType == SIR_MAC_MGMT_DISASSOC ||
+	     pFc->subType == SIR_MAC_MGMT_DEAUTH ||
+	     pFc->subType == SIR_MAC_MGMT_ACTION)) {
+		struct ieee80211_frame *wh =
+			(struct ieee80211_frame *)qdf_nbuf_data(tx_frame);
+		if (!IEEE80211_IS_BROADCAST(wh->i_addr1) &&
+		    !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+			if (pFc->wep) {
+				uint8_t mic_len, hdr_len;
+
+				/* Allocate extra bytes for privacy header and
+				 * trailer
+				 */
+				if (iface->ucast_key_cipher ==
+				    WMI_CIPHER_AES_GCM) {
+					hdr_len = WLAN_IEEE80211_GCMP_HEADERLEN;
+					mic_len = WLAN_IEEE80211_GCMP_MICLEN;
+				} else {
+					hdr_len = IEEE80211_CCMP_HEADERLEN;
+					mic_len = IEEE80211_CCMP_MICLEN;
+				}
+				newFrmLen = frmLen + hdr_len + mic_len;
+				qdf_status =
+					cds_packet_alloc((uint16_t) newFrmLen,
+							 (void **)&pFrame,
+							 (void **)&pPacket);
+
+				if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+					WMA_LOGP("%s: Failed to allocate %d bytes for RMF status code (%x)",
+						__func__, newFrmLen,
+						qdf_status);
+					/* Free the original packet memory */
+					cds_packet_free((void *)tx_frame);
+					goto error;
+				}
+
+				/*
+				 * Initialize the frame with 0's and only fill
+				 * MAC header and data, Keep the CCMP header and
+				 * trailer as 0's, firmware shall fill this
+				 */
+				qdf_mem_set(pFrame, newFrmLen, 0);
+				qdf_mem_copy(pFrame, wh, sizeof(*wh));
+				qdf_mem_copy(pFrame + sizeof(*wh) +
+					     hdr_len,
+					     pData + sizeof(*wh),
+					     frmLen - sizeof(*wh));
+
+				cds_packet_free((void *)tx_frame);
+				tx_frame = pPacket;
+				pData = pFrame;
+				frmLen = newFrmLen;
+				pFc = (tpSirMacFrameCtl)
+						(qdf_nbuf_data(tx_frame));
+			}
+		} else {
+			/* Allocate extra bytes for MMIE */
+			newFrmLen = frmLen + IEEE80211_MMIE_LEN;
+			qdf_status = cds_packet_alloc((uint16_t) newFrmLen,
+						      (void **)&pFrame,
+						      (void **)&pPacket);
+
+			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+				WMA_LOGP("%s: Failed to allocate %d bytes for RMF status code (%x)",
+					__func__, newFrmLen,
+					qdf_status);
+				/* Free the original packet memory */
+				cds_packet_free((void *)tx_frame);
+				goto error;
+			}
+			/*
+			 * Initialize the frame with 0's and only fill
+			 * MAC header and data. MMIE field will be
+			 * filled by cds_attach_mmie API
+			 */
+			qdf_mem_set(pFrame, newFrmLen, 0);
+			qdf_mem_copy(pFrame, wh, sizeof(*wh));
+			qdf_mem_copy(pFrame + sizeof(*wh),
+				     pData + sizeof(*wh), frmLen - sizeof(*wh));
+			if (!cds_attach_mmie(iface->key.key,
+					     iface->key.key_id[0].ipn,
+					     WMA_IGTK_KEY_INDEX_4,
+					     pFrame,
+					     pFrame + newFrmLen, newFrmLen)) {
+				WMA_LOGP("%s: Failed to attach MMIE at the end of frame",
+					 __func__);
+				/* Free the original packet memory */
+				cds_packet_free((void *)tx_frame);
+				goto error;
+			}
+			cds_packet_free((void *)tx_frame);
+			tx_frame = pPacket;
+			pData = pFrame;
+			frmLen = newFrmLen;
+			pFc = (tpSirMacFrameCtl) (qdf_nbuf_data(tx_frame));
+		}
+		/*
+		 * Some target which support sending mgmt frame based on htt
+		 * would DMA write this PMF tx frame buffer, it may cause smmu
+		 * check permission fault, set a flag to do bi-direction DMA
+		 * map, normal tx unmap is enough for this case.
+		 */
+		QDF_NBUF_CB_TX_DMA_BI_MAP((qdf_nbuf_t)tx_frame) = 1;
+	}
+#endif /* WLAN_FEATURE_11W */
+	mHdr = (tpSirMacMgmtHdr)qdf_nbuf_data(tx_frame);
+	if ((frmType == TXRX_FRM_802_11_MGMT) &&
+	    (pFc->subType == SIR_MAC_MGMT_PROBE_RSP)) {
+		uint64_t adjusted_tsf_le;
+		struct ieee80211_frame *wh =
+			(struct ieee80211_frame *)qdf_nbuf_data(tx_frame);
+
+		/* Make the TSF offset negative to match TSF in beacons */
+		adjusted_tsf_le = cpu_to_le64(0ULL -
+					      wma_handle->interfaces[vdev_id].
+					      tsfadjust);
+		A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le));
+	}
+	if (frmType == TXRX_FRM_802_11_DATA) {
+		qdf_nbuf_t ret;
+		qdf_nbuf_t skb = (qdf_nbuf_t) tx_frame;
+		void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+		struct wma_decap_info_t decap_info;
+		struct ieee80211_frame *wh =
+			(struct ieee80211_frame *)qdf_nbuf_data(skb);
+		unsigned long curr_timestamp = qdf_mc_timer_get_system_ticks();
+
+		if (pdev == NULL) {
+			WMA_LOGE("%s: pdev pointer is not available", __func__);
+			cds_packet_free((void *)tx_frame);
+			return QDF_STATUS_E_FAULT;
+		}
+
+		/*
+		 * 1) TxRx Module expects data input to be 802.3 format
+		 * So Decapsulation has to be done.
+		 * 2) Only one Outstanding Data pending for Ack is allowed
+		 */
+		if (tx_frm_ota_comp_cb) {
+			if (wma_handle->umac_data_ota_ack_cb) {
+				/*
+				 * If last data frame was sent more than 5 secs
+				 * ago and still we didn't receive ack/nack from
+				 * fw then allow Tx of this data frame
+				 */
+				if (curr_timestamp >=
+				    wma_handle->last_umac_data_ota_timestamp +
+				    500) {
+					WMA_LOGE("%s: No Tx Ack for last data frame for more than 5 secs, allow Tx of current data frame",
+						__func__);
+				} else {
+					WMA_LOGE("%s: Already one Data pending for Ack, reject Tx of data frame",
+						__func__);
+					cds_packet_free((void *)tx_frame);
+					return QDF_STATUS_E_FAILURE;
+				}
+			}
+		} else {
+			/*
+			 * Data Frames are sent through TxRx Non Standard Data
+			 * path so Ack Complete Cb is must
+			 */
+			WMA_LOGE("No Ack Complete Cb. Don't Allow");
+			cds_packet_free((void *)tx_frame);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		/* Take out 802.11 header from skb */
+		decap_info.hdr_len = wma_ieee80211_hdrsize(wh);
+		qdf_mem_copy(decap_info.hdr, wh, decap_info.hdr_len);
+		qdf_nbuf_pull_head(skb, decap_info.hdr_len);
+
+		/*  Decapsulate to 802.3 format */
+		wma_decap_to_8023(skb, &decap_info);
+
+		/* Zero out skb's context buffer for the driver to use */
+		qdf_mem_set(skb->cb, sizeof(skb->cb), 0);
+
+		/* Terminate the (single-element) list of tx frames */
+		skb->next = NULL;
+
+		/* Store the Ack Complete Cb */
+		wma_handle->umac_data_ota_ack_cb = tx_frm_ota_comp_cb;
+
+		/* Store the timestamp and nbuf for this data Tx */
+		wma_handle->last_umac_data_ota_timestamp = curr_timestamp;
+		wma_handle->last_umac_data_nbuf = skb;
+
+		/* Send the Data frame to TxRx in Non Standard Path */
+		cdp_hl_tdls_flag_reset(soc,
+			txrx_vdev, tdlsFlag);
+
+		ret = cdp_tx_non_std(soc,
+			txrx_vdev,
+			OL_TX_SPEC_NO_FREE, skb);
+
+		cdp_hl_tdls_flag_reset(soc,
+			txrx_vdev, false);
+
+		if (ret) {
+			WMA_LOGE("TxRx Rejected. Fail to do Tx");
+			/* Call Download Cb so that umac can free the buffer */
+			if (tx_frm_download_comp_cb)
+				tx_frm_download_comp_cb(wma_handle->mac_context,
+						tx_frame,
+						WMA_TX_FRAME_BUFFER_FREE);
+			wma_handle->umac_data_ota_ack_cb = NULL;
+			wma_handle->last_umac_data_nbuf = NULL;
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		/* Call Download Callback if passed */
+		if (tx_frm_download_comp_cb)
+			tx_frm_download_comp_cb(wma_handle->mac_context,
+						tx_frame,
+						WMA_TX_FRAME_BUFFER_NO_FREE);
+
+		return QDF_STATUS_SUCCESS;
+	}
+
+	ctrl_pdev = cdp_get_ctrl_pdev_from_vdev(soc,
+				txrx_vdev);
+	if (ctrl_pdev == NULL) {
+		WMA_LOGE("ol_pdev_handle is NULL\n");
+		cds_packet_free((void *)tx_frame);
+		return QDF_STATUS_E_FAILURE;
+	}
+	is_high_latency = cdp_cfg_is_high_latency(soc, ctrl_pdev);
+
+	downld_comp_required = tx_frm_download_comp_cb && is_high_latency &&
+					tx_frm_ota_comp_cb;
+
+	/* Fill the frame index to send */
+	if (pFc->type == SIR_MAC_MGMT_FRAME) {
+		if (tx_frm_ota_comp_cb) {
+			if (downld_comp_required)
+				tx_frm_index =
+					GENERIC_DOWNLD_COMP_ACK_COMP_INDEX;
+			else
+				tx_frm_index = GENERIC_NODOWLOAD_ACK_COMP_INDEX;
+
+		} else {
+			tx_frm_index =
+				GENERIC_NODOWNLD_NOACK_COMP_INDEX;
+		}
+	}
+
+	/*
+	 * If Dowload Complete is required
+	 * Wait for download complete
+	 */
+	if (downld_comp_required) {
+		/* Store Tx Comp Cb */
+		wma_handle->tx_frm_download_comp_cb = tx_frm_download_comp_cb;
+
+		/* Reset the Tx Frame Complete Event */
+		qdf_status = qdf_event_reset(
+				&wma_handle->tx_frm_download_comp_event);
+
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			WMA_LOGP("%s: Event Reset failed tx comp event %x",
+				 __func__, qdf_status);
+			goto error;
+		}
+	}
+
+	/* If the frame has to be sent at BD Rate2 inform TxRx */
+	if (tx_flag & HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)
+		use_6mbps = 1;
+
+	if (pFc->subType == SIR_MAC_MGMT_PROBE_RSP) {
+		if ((wma_is_vdev_in_ap_mode(wma_handle, vdev_id)) &&
+		    (0 != wma_handle->interfaces[vdev_id].mhz))
+			chanfreq = wma_handle->interfaces[vdev_id].mhz;
+		else
+			chanfreq = channel_freq;
+		WMA_LOGD("%s: Probe response frame on channel %d vdev:%d",
+			__func__, chanfreq, vdev_id);
+		if (wma_is_vdev_in_ap_mode(wma_handle, vdev_id) && !chanfreq)
+			WMA_LOGE("%s: AP oper chan is zero", __func__);
+	} else if (pFc->subType == SIR_MAC_MGMT_ACTION) {
+		chanfreq = channel_freq;
+	} else {
+		chanfreq = 0;
+	}
+	if (pMac->mlme_cfg->gen.debug_packet_log & 0x1) {
+		if ((pFc->type == SIR_MAC_MGMT_FRAME) &&
+		    (pFc->subType != SIR_MAC_MGMT_PROBE_REQ) &&
+		    (pFc->subType != SIR_MAC_MGMT_PROBE_RSP)) {
+			WMA_LOGD("TX MGMT - Type %hu, SubType %hu seq_num[%d]",
+				 pFc->type, pFc->subType,
+				 ((mHdr->seqControl.seqNumHi << 4) |
+				 mHdr->seqControl.seqNumLo));
+		}
+	}
+
+	if (wma_handle->interfaces[vdev_id].channel >= SIR_11A_CHANNEL_BEGIN)
+		is_5g = true;
+
+	mgmt_param.tx_frame = tx_frame;
+	mgmt_param.frm_len = frmLen;
+	mgmt_param.vdev_id = vdev_id;
+	mgmt_param.pdata = pData;
+	mgmt_param.chanfreq = chanfreq;
+	mgmt_param.qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	mgmt_param.use_6mbps = use_6mbps;
+	mgmt_param.tx_type = tx_frm_index;
+
+	/*
+	 * Update the tx_params TLV only for rates
+	 * other than 1Mbps and 6 Mbps
+	 */
+	if (rid < RATEID_DEFAULT &&
+	    (rid != RATEID_1MBPS && !(rid == RATEID_6MBPS && is_5g))) {
+		WMA_LOGD(FL("using rate id: %d for Tx"), rid);
+		mgmt_param.tx_params_valid = true;
+		wma_update_tx_send_params(&mgmt_param.tx_param, rid);
+	}
+
+	psoc = wma_handle->psoc;
+	if (!psoc) {
+		WMA_LOGE("%s: psoc ctx is NULL", __func__);
+		goto error;
+	}
+
+	if (!wma_handle->pdev) {
+		WMA_LOGE("%s: pdev ctx is NULL", __func__);
+		goto error;
+	}
+
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(wma_handle->pdev);
+	wh = (struct ieee80211_frame *)(qdf_nbuf_data(tx_frame));
+	mac_addr = wh->i_addr1;
+	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_MGMT_NB_ID);
+	if (!peer) {
+		mac_addr = wh->i_addr2;
+		peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
+					WLAN_MGMT_NB_ID);
+	}
+
+	status = wlan_mgmt_txrx_mgmt_frame_tx(peer,
+			(tpAniSirGlobal)wma_handle->mac_context,
+			(qdf_nbuf_t)tx_frame,
+			NULL, tx_frm_ota_comp_cb,
+			WLAN_UMAC_COMP_MLME, &mgmt_param);
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: mgmt tx failed", __func__);
+		qdf_nbuf_free((qdf_nbuf_t)tx_frame);
+		goto error;
+	}
+
+	/*
+	 * Failed to send Tx Mgmt Frame
+	 */
+	if (status) {
+	/* Call Download Cb so that umac can free the buffer */
+		uint32_t rem;
+
+		if (tx_frm_download_comp_cb)
+			tx_frm_download_comp_cb(wma_handle->mac_context,
+						tx_frame,
+						WMA_TX_FRAME_BUFFER_FREE);
+		rem = qdf_do_div_rem(wma_handle->tx_fail_cnt,
+				     MAX_PRINT_FAILURE_CNT);
+		if (!rem)
+			WMA_LOGE("%s: Failed to send Mgmt Frame", __func__);
+		else
+			WMA_LOGD("%s: Failed to send Mgmt Frame", __func__);
+		wma_handle->tx_fail_cnt++;
+		goto error;
+	}
+
+	if (!tx_frm_download_comp_cb)
+		return QDF_STATUS_SUCCESS;
+
+	/*
+	 * Wait for Download Complete
+	 * if required
+	 */
+	if (downld_comp_required) {
+		/*
+		 * Wait for Download Complete
+		 * @ Integrated : Dxe Complete
+		 * @ Discrete : Target Download Complete
+		 */
+		qdf_status =
+			qdf_wait_for_event_completion(&wma_handle->
+					      tx_frm_download_comp_event,
+					      WMA_TX_FRAME_COMPLETE_TIMEOUT);
+
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			WMA_LOGP("Wait Event failed txfrm_comp_event");
+			/*
+			 * @Integrated: Something Wrong with Dxe
+			 *   TODO: Some Debug Code
+			 * Here We need to trigger SSR since
+			 * since system went into a bad state where
+			 * we didn't get Download Complete for almost
+			 * WMA_TX_FRAME_COMPLETE_TIMEOUT (1 sec)
+			 */
+			/* display scheduler stats */
+			return cdp_display_stats(soc, CDP_SCHEDULER_STATS,
+						QDF_STATS_VERBOSITY_LEVEL_HIGH);
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+error:
+	wma_handle->tx_frm_download_comp_cb = NULL;
+	wma_handle->umac_data_ota_ack_cb = NULL;
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * wma_ds_peek_rx_packet_info() - peek rx packet info
+ * @pkt: packet
+ * @pkt_meta: packet meta
+ * @bSwap: byte swap
+ *
+ * Function fills the rx packet meta info from the the cds packet
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_ds_peek_rx_packet_info(cds_pkt_t *pkt, void **pkt_meta,
+				      bool bSwap)
+{
+	/* Sanity Check */
+	if (pkt == NULL) {
+		WMA_LOGE("wma:Invalid parameter sent on wma_peek_rx_pkt_info");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	*pkt_meta = &(pkt->pkt_meta);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef HL_RX_AGGREGATION_HOLE_DETECTION
+void ol_rx_aggregation_hole(uint32_t hole_info)
+{
+	struct sir_sme_rx_aggr_hole_ind *rx_aggr_hole_event;
+	uint32_t alloc_len;
+	cds_msg_t cds_msg = { 0 };
+	QDF_STATUS status;
+
+	alloc_len = sizeof(*rx_aggr_hole_event) +
+		sizeof(rx_aggr_hole_event->hole_info_array[0]);
+	rx_aggr_hole_event = qdf_mem_malloc(alloc_len);
+	if (!rx_aggr_hole_event)
+		return;
+
+	rx_aggr_hole_event->hole_cnt = 1;
+	rx_aggr_hole_event->hole_info_array[0] = hole_info;
+
+	cds_msg.type = eWNI_SME_RX_AGGR_HOLE_IND;
+	cds_msg.bodyptr = rx_aggr_hole_event;
+	cds_msg.bodyval = 0;
+
+	status = cds_mq_post_message(CDS_MQ_ID_SME, &cds_msg);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Failed to post aggr event to SME", __func__);
+		qdf_mem_free(rx_aggr_hole_event);
+		return;
+	}
+}
+#endif
+
+/**
+ * ol_rx_err() - ol rx err handler
+ * @pdev: ol pdev
+ * @vdev_id: vdev id
+ * @peer_mac_addr: peer mac address
+ * @tid: TID
+ * @tsf32: TSF
+ * @err_type: error type
+ * @rx_frame: rx frame
+ * @pn: PN Number
+ * @key_id: key id
+ *
+ * This function handles rx error and send MIC error failure to LIM
+ *
+ * Return: none
+ */
+/*
+ * Local prototype added to temporarily address warning caused by
+ * -Wmissing-prototypes. A more correct solution will come later
+ * as a solution to IR-196435 at whihc point this prototype will
+ * be removed.
+ */
+void ol_rx_err(void *pdev, uint8_t vdev_id,
+	       uint8_t *peer_mac_addr, int tid, uint32_t tsf32,
+	       enum ol_rx_err_type err_type, qdf_nbuf_t rx_frame,
+	       uint64_t *pn, uint8_t key_id);
+void ol_rx_err(void *pdev, uint8_t vdev_id,
+	       uint8_t *peer_mac_addr, int tid, uint32_t tsf32,
+	       enum ol_rx_err_type err_type, qdf_nbuf_t rx_frame,
+	       uint64_t *pn, uint8_t key_id)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	tpSirSmeMicFailureInd mic_err_ind;
+	struct ether_header *eth_hdr;
+	struct scheduler_msg cds_msg = {0};
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: Failed to get wma", __func__);
+		return;
+	}
+
+	if (err_type != OL_RX_ERR_TKIP_MIC)
+		return;
+
+	if (qdf_nbuf_len(rx_frame) < sizeof(*eth_hdr))
+		return;
+	eth_hdr = (struct ether_header *)qdf_nbuf_data(rx_frame);
+	mic_err_ind = qdf_mem_malloc(sizeof(*mic_err_ind));
+	if (!mic_err_ind)
+		return;
+
+	mic_err_ind->messageType = eWNI_SME_MIC_FAILURE_IND;
+	mic_err_ind->length = sizeof(*mic_err_ind);
+	mic_err_ind->sessionId = vdev_id;
+	qdf_copy_macaddr(&mic_err_ind->bssId,
+		     (struct qdf_mac_addr *) &wma->interfaces[vdev_id].bssid);
+	qdf_mem_copy(mic_err_ind->info.taMacAddr,
+		     (struct qdf_mac_addr *) peer_mac_addr,
+			sizeof(tSirMacAddr));
+	qdf_mem_copy(mic_err_ind->info.srcMacAddr,
+		     (struct qdf_mac_addr *) eth_hdr->ether_shost,
+			sizeof(tSirMacAddr));
+	qdf_mem_copy(mic_err_ind->info.dstMacAddr,
+		     (struct qdf_mac_addr *) eth_hdr->ether_dhost,
+			sizeof(tSirMacAddr));
+	mic_err_ind->info.keyId = key_id;
+	mic_err_ind->info.multicast =
+		IEEE80211_IS_MULTICAST(eth_hdr->ether_dhost);
+	qdf_mem_copy(mic_err_ind->info.TSC, pn, SIR_CIPHER_SEQ_CTR_SIZE);
+
+	qdf_mem_set(&cds_msg, sizeof(struct scheduler_msg), 0);
+	cds_msg.type = eWNI_SME_MIC_FAILURE_IND;
+	cds_msg.bodyptr = (void *) mic_err_ind;
+
+	if (QDF_STATUS_SUCCESS !=
+		scheduler_post_message(QDF_MODULE_ID_TXRX,
+				       QDF_MODULE_ID_SME,
+				       QDF_MODULE_ID_SME,
+				       &cds_msg)) {
+		WMA_LOGE("%s: could not post mic failure indication to SME",
+			 __func__);
+		qdf_mem_free((void *)mic_err_ind);
+	}
+}
+
+/**
+ * wma_tx_abort() - abort tx
+ * @vdev_id: vdev id
+ *
+ * In case of deauth host abort transmitting packet.
+ *
+ * Return: none
+ */
+void wma_tx_abort(uint8_t vdev_id)
+{
+#define PEER_ALL_TID_BITMASK 0xffffffff
+	tp_wma_handle wma;
+	uint32_t peer_tid_bitmap = PEER_ALL_TID_BITMASK;
+	struct wma_txrx_node *iface;
+	struct peer_flush_params param = {0};
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (NULL == wma) {
+		WMA_LOGE("%s: wma is NULL", __func__);
+		return;
+	}
+
+	iface = &wma->interfaces[vdev_id];
+	if (!iface->handle) {
+		WMA_LOGE("%s: Failed to get iface handle: %pK",
+			 __func__, iface->handle);
+		return;
+	}
+	WMA_LOGD("%s: vdevid %d bssid %pM", __func__, vdev_id, iface->bssid);
+	wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST);
+	cdp_fc_vdev_pause(cds_get_context(QDF_MODULE_ID_SOC),
+			iface->handle,
+			OL_TXQ_PAUSE_REASON_TX_ABORT);
+
+	/* Flush all TIDs except MGMT TID for this peer in Target */
+	peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID);
+	param.peer_tid_bitmap = peer_tid_bitmap;
+	param.vdev_id = vdev_id;
+	wmi_unified_peer_flush_tids_send(wma->wmi_handle, iface->bssid,
+					 &param);
+}
+
+/**
+ * wma_lro_config_cmd() - process the LRO config command
+ * @wma: Pointer to WMA handle
+ * @wma_lro_cmd: Pointer to LRO configuration parameters
+ *
+ * This function sends down the LRO configuration parameters to
+ * the firmware to enable LRO, sets the TCP flags and sets the
+ * seed values for the toeplitz hash generation
+ *
+ * Return: QDF_STATUS_SUCCESS for success otherwise failure
+ */
+QDF_STATUS wma_lro_config_cmd(void *handle,
+	 struct cdp_lro_hash_config *wma_lro_cmd)
+{
+	struct wmi_lro_config_cmd_t wmi_lro_cmd = {0};
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma || NULL == wma_lro_cmd) {
+		wma_err("Invalid input!");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wmi_lro_cmd.lro_enable = wma_lro_cmd->lro_enable;
+	wmi_lro_cmd.tcp_flag = wma_lro_cmd->tcp_flag;
+	wmi_lro_cmd.tcp_flag_mask = wma_lro_cmd->tcp_flag_mask;
+	qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv4,
+			wma_lro_cmd->toeplitz_hash_ipv4,
+			LRO_IPV4_SEED_ARR_SZ * sizeof(uint32_t));
+	qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv6,
+			wma_lro_cmd->toeplitz_hash_ipv6,
+			LRO_IPV6_SEED_ARR_SZ * sizeof(uint32_t));
+
+	return wmi_unified_lro_config_cmd(wma->wmi_handle,
+						&wmi_lro_cmd);
+}
+
+/**
+ * wma_indicate_err() - indicate an error to the protocol stack
+ * @err_type: error type
+ * @err_info: information associated with the error
+ *
+ * This function indicates an error encountered in the data path
+ * to the protocol stack
+ *
+ * Return: none
+ */
+void
+wma_indicate_err(
+	enum ol_rx_err_type err_type,
+	struct ol_error_info *err_info)
+{
+	switch (err_type) {
+	case OL_RX_ERR_TKIP_MIC:
+	{
+		tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+		tpSirSmeMicFailureInd mic_err_ind;
+		struct scheduler_msg cds_msg = {0};
+		uint8_t vdev_id;
+
+		if (NULL == wma) {
+			WMA_LOGE("%s: Failed to get wma context",
+				 __func__);
+			return;
+		}
+
+		mic_err_ind = qdf_mem_malloc(sizeof(*mic_err_ind));
+		if (!mic_err_ind)
+			return;
+
+		qdf_mem_set((void *) mic_err_ind, 0,
+			 sizeof(*mic_err_ind));
+		mic_err_ind->messageType = eWNI_SME_MIC_FAILURE_IND;
+		mic_err_ind->length = sizeof(*mic_err_ind);
+		vdev_id = err_info->u.mic_err.vdev_id;
+		qdf_copy_macaddr(&mic_err_ind->bssId,
+		     (struct qdf_mac_addr *) &wma->interfaces[vdev_id].bssid);
+		WMA_LOGE("MIC error: BSSID:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			mic_err_ind->bssId.bytes[0],
+			mic_err_ind->bssId.bytes[1],
+			mic_err_ind->bssId.bytes[2],
+			mic_err_ind->bssId.bytes[3],
+			mic_err_ind->bssId.bytes[4],
+			mic_err_ind->bssId.bytes[5]);
+		qdf_mem_copy(mic_err_ind->info.taMacAddr,
+			 (struct qdf_mac_addr *) err_info->u.mic_err.ta,
+			 sizeof(tSirMacAddr));
+		qdf_mem_copy(mic_err_ind->info.srcMacAddr,
+			 (struct qdf_mac_addr *) err_info->u.mic_err.sa,
+			 sizeof(tSirMacAddr));
+		qdf_mem_copy(mic_err_ind->info.dstMacAddr,
+			(struct qdf_mac_addr *) err_info->u.mic_err.da,
+			 sizeof(tSirMacAddr));
+		mic_err_ind->info.keyId = err_info->u.mic_err.key_id;
+		mic_err_ind->info.multicast =
+			 IEEE80211_IS_MULTICAST(err_info->u.mic_err.da);
+		qdf_mem_copy(mic_err_ind->info.TSC,
+			 (void *)&err_info->
+			 u.mic_err.pn, SIR_CIPHER_SEQ_CTR_SIZE);
+
+		qdf_mem_set(&cds_msg, sizeof(struct scheduler_msg), 0);
+		cds_msg.type = eWNI_SME_MIC_FAILURE_IND;
+		cds_msg.bodyptr = (void *) mic_err_ind;
+		if (QDF_STATUS_SUCCESS !=
+			scheduler_post_message(QDF_MODULE_ID_WMA,
+					       QDF_MODULE_ID_SME,
+					       QDF_MODULE_ID_SME,
+				  &cds_msg)) {
+			WMA_LOGE("%s: mic failure ind post to SME failed",
+					 __func__);
+			qdf_mem_free((void *)mic_err_ind);
+		}
+		break;
+	}
+	default:
+	{
+		WMA_LOGE("%s: unhandled ol error type %d", __func__, err_type);
+		break;
+	}
+	}
+}
+
+void wma_rx_mic_error_ind(void *scn_handle, uint16_t vdev_id, void *wh)
+{
+	struct ieee80211_frame *w = (struct ieee80211_frame *)wh;
+	struct ol_error_info err_info;
+
+	err_info.u.mic_err.vdev_id = vdev_id;
+	qdf_mem_copy(err_info.u.mic_err.da, w->i_addr1, OL_TXRX_MAC_ADDR_LEN);
+	qdf_mem_copy(err_info.u.mic_err.ta, w->i_addr2, OL_TXRX_MAC_ADDR_LEN);
+
+	WMA_LOGD("MIC vdev_id %d\n", vdev_id);
+	WMA_LOGD("MIC DA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+						err_info.u.mic_err.da[0],
+						err_info.u.mic_err.da[1],
+						err_info.u.mic_err.da[2],
+						err_info.u.mic_err.da[3],
+						err_info.u.mic_err.da[4],
+						err_info.u.mic_err.da[5]);
+	WMA_LOGD("MIC TA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+						err_info.u.mic_err.ta[0],
+						err_info.u.mic_err.ta[1],
+						err_info.u.mic_err.ta[2],
+						err_info.u.mic_err.ta[3],
+						err_info.u.mic_err.ta[4],
+						err_info.u.mic_err.ta[5]);
+
+	wma_indicate_err(OL_RX_ERR_TKIP_MIC, &err_info);
+}
+
+uint8_t wma_rx_invalid_peer_ind(uint8_t vdev_id, void *wh)
+{
+	struct ol_rx_inv_peer_params *rx_inv_msg;
+	struct ieee80211_frame *wh_l = (struct ieee80211_frame *)wh;
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	rx_inv_msg = qdf_mem_malloc(sizeof(struct ol_rx_inv_peer_params));
+	if (!rx_inv_msg)
+		return -ENOMEM;
+
+	rx_inv_msg->vdev_id = vdev_id;
+	qdf_mem_copy(rx_inv_msg->ra, wh_l->i_addr1, OL_TXRX_MAC_ADDR_LEN);
+	qdf_mem_copy(rx_inv_msg->ta, wh_l->i_addr2, OL_TXRX_MAC_ADDR_LEN);
+
+	WMA_LOGD("%s: vdev_id %d", __func__, vdev_id);
+	WMA_LOGD("%s: RA:" MAC_ADDRESS_STR,
+		 __func__,
+		 MAC_ADDR_ARRAY(rx_inv_msg->ra));
+	WMA_LOGD("%s: TA:" MAC_ADDRESS_STR,
+		 __func__,
+		 MAC_ADDR_ARRAY(rx_inv_msg->ta));
+
+	wma_send_msg(wma, SIR_LIM_RX_INVALID_PEER, (void *)rx_inv_msg, 0);
+
+	return 0;
+}
diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c
new file mode 100644
index 0000000..749db0d
--- /dev/null
+++ b/core/wma/src/wma_dev_if.c
@@ -0,0 +1,6061 @@
+/*
+ * Copyright (c) 2013-2018 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:    wma_dev_if.c
+ *  This file contains vdev & peer related operations.
+ */
+
+/* Header files */
+
+#include "wma.h"
+#include "wma_api.h"
+#include "cds_api.h"
+#include "wmi_unified_api.h"
+#include "wlan_qct_sys.h"
+#include "wni_api.h"
+#include "ani_global.h"
+#include "wmi_unified.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+
+#include "qdf_nbuf.h"
+#include "qdf_types.h"
+#include "qdf_mem.h"
+
+#include "wma_types.h"
+#include "lim_api.h"
+#include "lim_session_utils.h"
+
+#include "cds_utils.h"
+
+#if !defined(REMOVE_PKT_LOG)
+#include "pktlog_ac.h"
+#endif /* REMOVE_PKT_LOG */
+
+#include "dbglog_host.h"
+#include "csr_api.h"
+
+#include "wma_internal.h"
+
+#include "wma_ocb.h"
+#include "cdp_txrx_cfg.h"
+#include "cdp_txrx_flow_ctrl_legacy.h"
+#include <cdp_txrx_peer_ops.h>
+#include <cdp_txrx_cfg.h>
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_misc.h>
+
+#include "wlan_policy_mgr_api.h"
+#include "wma_nan_datapath.h"
+#include "wlan_tgt_def_config.h"
+#include <wlan_dfs_tgt_api.h>
+#include <cdp_txrx_handle.h>
+#include "wlan_pmo_ucfg_api.h"
+#include "wlan_reg_services_api.h"
+
+#include "wma_he.h"
+#include "wlan_roam_debug.h"
+#include "wlan_ocb_ucfg_api.h"
+#include "init_deinit_lmac.h"
+#include <target_if.h>
+#include "wlan_mlme_public_struct.h"
+#include "wlan_mlme_api.h"
+
+/**
+ * wma_find_vdev_by_addr() - find vdev_id from mac address
+ * @wma: wma handle
+ * @addr: mac address
+ * @vdev_id: return vdev_id
+ *
+ * Return: Returns vdev handle or NULL if mac address don't match
+ */
+struct cdp_vdev *wma_find_vdev_by_addr(tp_wma_handle wma, uint8_t *addr,
+				   uint8_t *vdev_id)
+{
+	uint8_t i;
+
+	for (i = 0; i < wma->max_bssid; i++) {
+		if (qdf_is_macaddr_equal(
+			(struct qdf_mac_addr *) wma->interfaces[i].addr,
+			(struct qdf_mac_addr *) addr) == true) {
+			*vdev_id = i;
+			return wma->interfaces[i].handle;
+		}
+	}
+	return NULL;
+}
+
+
+/**
+ * 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
+ */
+bool wma_is_vdev_in_ap_mode(tp_wma_handle wma, uint8_t vdev_id)
+{
+	struct wma_txrx_node *intf = wma->interfaces;
+
+	if (vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: Invalid vdev_id %hu", __func__, vdev_id);
+		QDF_ASSERT(0);
+		return false;
+	}
+
+	if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) &&
+	    ((intf[vdev_id].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO) ||
+	     (intf[vdev_id].sub_type == 0)))
+		return true;
+
+	return false;
+}
+
+#ifdef QCA_IBSS_SUPPORT
+/**
+ * wma_is_vdev_in_ibss_mode() - check that vdev is in ibss mode or not
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Helper function to know whether given vdev id
+ * is in IBSS mode or not.
+ *
+ * Return: True/False
+ */
+bool wma_is_vdev_in_ibss_mode(tp_wma_handle wma, uint8_t vdev_id)
+{
+	struct wma_txrx_node *intf = wma->interfaces;
+
+	if (vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: Invalid vdev_id %hu", __func__, vdev_id);
+		QDF_ASSERT(0);
+		return false;
+	}
+
+	if (intf[vdev_id].type == WMI_VDEV_TYPE_IBSS)
+		return true;
+
+	return false;
+}
+#endif /* QCA_IBSS_SUPPORT */
+
+/**
+ * wma_find_vdev_by_bssid() - Get the corresponding vdev_id from BSSID
+ * @wma - wma handle
+ * @vdev_id - vdev ID
+ *
+ * Return: fill vdev_id with appropriate vdev id and return vdev
+ *         handle or NULL if not found.
+ */
+struct cdp_vdev *wma_find_vdev_by_bssid(tp_wma_handle wma, uint8_t *bssid,
+				    uint8_t *vdev_id)
+{
+	int i;
+
+	for (i = 0; i < wma->max_bssid; i++) {
+		if (qdf_is_macaddr_equal(
+			(struct qdf_mac_addr *) wma->interfaces[i].bssid,
+			(struct qdf_mac_addr *) bssid) == true) {
+			*vdev_id = i;
+			return wma->interfaces[i].handle;
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * wma_get_txrx_vdev_type() - return operating mode of vdev
+ * @type: vdev_type
+ *
+ * Return: return operating mode as enum wlan_op_mode type
+ */
+static enum wlan_op_mode wma_get_txrx_vdev_type(uint32_t type)
+{
+	enum wlan_op_mode vdev_type = wlan_op_mode_unknown;
+
+	switch (type) {
+	case WMI_VDEV_TYPE_AP:
+		vdev_type = wlan_op_mode_ap;
+		break;
+	case WMI_VDEV_TYPE_STA:
+		vdev_type = wlan_op_mode_sta;
+		break;
+#ifdef QCA_IBSS_SUPPORT
+	case WMI_VDEV_TYPE_IBSS:
+		vdev_type = wlan_op_mode_ibss;
+		break;
+#endif /* QCA_IBSS_SUPPORT */
+	case WMI_VDEV_TYPE_OCB:
+		vdev_type = wlan_op_mode_ocb;
+		break;
+	case WMI_VDEV_TYPE_MONITOR:
+		vdev_type = wlan_op_mode_monitor;
+		break;
+	case WMI_VDEV_TYPE_NDI:
+		vdev_type = wlan_op_mode_ndi;
+		break;
+	default:
+		WMA_LOGE("Invalid vdev type %u", type);
+		vdev_type = wlan_op_mode_unknown;
+	}
+
+	return vdev_type;
+}
+
+/**
+ * wma_find_req() - find target request for vdev id
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @type: request type
+ *
+ * Find target request for given vdev id & type of request.
+ * Remove that request from active list.
+ *
+ * Return: return target request if found or NULL.
+ */
+static struct wma_target_req *wma_find_req(tp_wma_handle wma,
+					   uint8_t vdev_id, uint8_t type)
+{
+	struct wma_target_req *req_msg = NULL;
+	bool found = false;
+	qdf_list_node_t *node1 = NULL, *node2 = NULL;
+	QDF_STATUS status;
+
+	qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
+	if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue,
+						      &node2)) {
+		qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
+		WMA_LOGE(FL("unable to get msg node from request queue"));
+		return NULL;
+	}
+
+	do {
+		node1 = node2;
+		req_msg = qdf_container_of(node1, struct wma_target_req, node);
+		if (req_msg->vdev_id != vdev_id)
+			continue;
+		if (req_msg->type != type)
+			continue;
+
+		found = true;
+		status = qdf_list_remove_node(&wma->wma_hold_req_queue, node1);
+		if (QDF_STATUS_SUCCESS != status) {
+			qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
+			WMA_LOGD(FL("Failed to remove request for vdev_id %d type %d"),
+				 vdev_id, type);
+			return NULL;
+		}
+		break;
+	} while (QDF_STATUS_SUCCESS  ==
+			qdf_list_peek_next(&wma->wma_hold_req_queue, node1,
+					   &node2));
+
+	qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
+	if (!found) {
+		WMA_LOGE(FL("target request not found for vdev_id %d type %d"),
+			 vdev_id, type);
+		return NULL;
+	}
+
+	WMA_LOGD(FL("target request found for vdev id: %d type %d"),
+		 vdev_id, type);
+
+	return req_msg;
+}
+
+/**
+ * wma_find_remove_req_msgtype() - find and remove request for vdev id
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @msg_type: message request type
+ *
+ * Find target request for given vdev id & sub type of request.
+ * Remove the same from active list.
+ *
+ * Return: Success if request found, failure other wise
+ */
+static struct wma_target_req *wma_find_remove_req_msgtype(tp_wma_handle wma,
+					   uint8_t vdev_id, uint32_t msg_type)
+{
+	struct wma_target_req *req_msg = NULL;
+	bool found = false;
+	qdf_list_node_t *node1 = NULL, *node2 = NULL;
+	QDF_STATUS status;
+
+	qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
+	if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue,
+						      &node2)) {
+		qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
+		WMA_LOGE(FL("unable to get msg node from request queue"));
+		return NULL;
+	}
+
+	do {
+		node1 = node2;
+		req_msg = qdf_container_of(node1, struct wma_target_req, node);
+		if (req_msg->vdev_id != vdev_id)
+			continue;
+		if (req_msg->msg_type != msg_type)
+			continue;
+
+		found = true;
+		status = qdf_list_remove_node(&wma->wma_hold_req_queue, node1);
+		if (QDF_STATUS_SUCCESS != status) {
+			qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
+			WMA_LOGD(FL("Failed to remove request. vdev_id %d type %d"),
+				 vdev_id, msg_type);
+			return NULL;
+		}
+		break;
+	} while (QDF_STATUS_SUCCESS  ==
+			qdf_list_peek_next(&wma->wma_hold_req_queue, node1,
+					   &node2));
+
+	qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
+	if (!found) {
+		WMA_LOGE(FL("target request not found for vdev_id %d type %d"),
+			 vdev_id, msg_type);
+		return NULL;
+	}
+
+	WMA_LOGD(FL("target request found for vdev id: %d type %d"),
+		 vdev_id, msg_type);
+
+	return req_msg;
+}
+
+
+/**
+ * wma_find_vdev_req() - find target request for vdev id
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @type: request type
+ * @remove_req_from_list: flag to indicate remove req or not.
+ *
+ * Return: return target request if found or NULL.
+ */
+static struct wma_target_req *wma_find_vdev_req(tp_wma_handle wma,
+						uint8_t vdev_id, uint8_t type,
+						bool remove_req_from_list)
+{
+	struct wma_target_req *req_msg = NULL;
+	bool found = false;
+	qdf_list_node_t *node1 = NULL, *node2 = NULL;
+	QDF_STATUS status;
+
+	qdf_spin_lock_bh(&wma->vdev_respq_lock);
+	if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->vdev_resp_queue,
+						      &node2)) {
+		qdf_spin_unlock_bh(&wma->vdev_respq_lock);
+		WMA_LOGD(FL("unable to get target req from vdev resp queue vdev_id: %d type: %d"),
+				vdev_id, type);
+		return NULL;
+	}
+
+	do {
+		node1 = node2;
+		req_msg = qdf_container_of(node1, struct wma_target_req, node);
+		if (req_msg->vdev_id != vdev_id)
+			continue;
+		if (req_msg->type != type)
+			continue;
+
+		found = true;
+		if (remove_req_from_list) {
+			status = qdf_list_remove_node(&wma->vdev_resp_queue,
+					node1);
+			if (QDF_STATUS_SUCCESS != status) {
+				qdf_spin_unlock_bh(&wma->vdev_respq_lock);
+				WMA_LOGD(FL(
+				"Failed to target req for vdev_id %d type %d"),
+						vdev_id, type);
+				return NULL;
+			}
+		}
+		break;
+	} while (QDF_STATUS_SUCCESS  ==
+			qdf_list_peek_next(&wma->vdev_resp_queue,
+					   node1, &node2));
+
+	qdf_spin_unlock_bh(&wma->vdev_respq_lock);
+	if (!found) {
+		WMA_LOGD(FL("target request not found for vdev_id %d type %d"),
+			 vdev_id, type);
+		return NULL;
+	}
+	WMA_LOGD(FL("target request found for vdev id: %d type %d msg %d"),
+		 vdev_id, type, req_msg->msg_type);
+	return req_msg;
+}
+
+/**
+ * wma_send_del_sta_self_resp() - send del sta self resp to Upper layer
+ * @param: params of del sta resp
+ *
+ * Return: none
+ */
+static inline void wma_send_del_sta_self_resp(struct del_sta_self_params *param)
+{
+	struct scheduler_msg sme_msg = {0};
+	QDF_STATUS status;
+
+	sme_msg.type = eWNI_SME_DEL_STA_SELF_RSP;
+	sme_msg.bodyptr = param;
+
+	status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		WMA_LOGE("Failed to post eWNI_SME_DEL_STA_SELF_RSP");
+		qdf_mem_free(param);
+	}
+}
+
+/**
+ * wma_vdev_detach_callback() - send vdev detach response to upper layer
+ * @ctx: txrx node ptr
+ *
+ * Return: none
+ */
+static void wma_vdev_detach_callback(void *ctx)
+{
+	tp_wma_handle wma;
+	struct wma_txrx_node *iface = (struct wma_txrx_node *)ctx;
+	struct del_sta_self_params *param;
+	struct wma_target_req *req_msg;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma || !iface->del_staself_req) {
+		WMA_LOGE("%s: wma %pK iface %pK", __func__, wma,
+			 iface->del_staself_req);
+		return;
+	}
+	param = (struct del_sta_self_params *) iface->del_staself_req;
+	iface->del_staself_req = NULL;
+	WMA_LOGD("%s: sending eWNI_SME_DEL_STA_SELF_RSP for vdev %d",
+		 __func__, param->session_id);
+	if (!wmi_service_enabled(wma->wmi_handle,
+				    wmi_service_sync_delete_cmds)) {
+		req_msg = wma_find_vdev_req(wma, param->session_id,
+					    WMA_TARGET_REQ_TYPE_VDEV_DEL,
+					    true);
+		if (req_msg) {
+			WMA_LOGD("%s: Found vdev request for vdev id %d",
+				 __func__, param->session_id);
+			qdf_mc_timer_stop(&req_msg->event_timeout);
+			qdf_mc_timer_destroy(&req_msg->event_timeout);
+			qdf_mem_free(req_msg);
+		}
+	}
+
+	if (iface->roam_scan_stats_req) {
+		struct sir_roam_scan_stats *roam_scan_stats_req =
+						iface->roam_scan_stats_req;
+
+		iface->roam_scan_stats_req = NULL;
+		qdf_mem_free(roam_scan_stats_req);
+	}
+
+	wma_vdev_deinit(iface);
+	qdf_mem_zero(iface, sizeof(*iface));
+	wma_vdev_init(iface);
+
+	param->status = QDF_STATUS_SUCCESS;
+	wma_send_del_sta_self_resp(param);
+}
+
+
+/**
+ * wma_self_peer_remove() - Self peer remove handler
+ * @wma: wma handle
+ * @del_sta_self_req_param: vdev id
+ * @generate_vdev_rsp: request type
+ *
+ * Return: success if peer delete command sent to firmware, else failure.
+ */
+
+static QDF_STATUS wma_self_peer_remove(tp_wma_handle wma_handle,
+			struct del_sta_self_params *del_sta_self_req_param,
+			uint8_t generate_vdev_rsp)
+{
+	void *peer;
+	struct cdp_pdev *pdev;
+	QDF_STATUS qdf_status;
+	uint8_t peer_id;
+	uint8_t vdev_id = del_sta_self_req_param->session_id;
+	struct wma_target_req *msg = NULL;
+	struct del_sta_self_rsp_params *sta_self_wmi_rsp;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	WMA_LOGD("P2P Device: removing self peer %pM",
+		 del_sta_self_req_param->self_mac_addr);
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto error;
+	}
+
+	peer = cdp_peer_find_by_addr(soc, pdev,
+			del_sta_self_req_param->self_mac_addr,
+			&peer_id);
+	if (!peer) {
+		WMA_LOGE("%s Failed to find peer %pM", __func__,
+			 del_sta_self_req_param->self_mac_addr);
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto error;
+	}
+
+	qdf_status = wma_remove_peer(wma_handle,
+				     del_sta_self_req_param->self_mac_addr,
+				     vdev_id, peer, false);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		WMA_LOGE(FL("wma_remove_peer is failed"));
+		goto error;
+	}
+
+	if (wmi_service_enabled(wma_handle->wmi_handle,
+				wmi_service_sync_delete_cmds)) {
+		sta_self_wmi_rsp =
+			qdf_mem_malloc(sizeof(struct del_sta_self_rsp_params));
+		if (!sta_self_wmi_rsp) {
+			qdf_status = QDF_STATUS_E_NOMEM;
+			goto error;
+		}
+		sta_self_wmi_rsp->self_sta_param = del_sta_self_req_param;
+		sta_self_wmi_rsp->generate_rsp = generate_vdev_rsp;
+		msg = wma_fill_hold_req(wma_handle, vdev_id,
+				   WMA_DELETE_STA_REQ,
+				   WMA_DEL_P2P_SELF_STA_RSP_START,
+				   sta_self_wmi_rsp,
+				   WMA_DELETE_STA_TIMEOUT);
+		if (!msg) {
+			WMA_LOGE(FL("Failed to allocate request for vdev_id %d"),
+				 vdev_id);
+			wma_remove_req(wma_handle, vdev_id,
+				WMA_DEL_P2P_SELF_STA_RSP_START);
+			qdf_mem_free(sta_self_wmi_rsp);
+			qdf_status = QDF_STATUS_E_FAILURE;
+			goto error;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+error:
+	return qdf_status;
+}
+
+static void
+wma_cdp_vdev_detach(ol_txrx_soc_handle soc,
+			tp_wma_handle wma_handle,
+			uint8_t vdev_id)
+{
+	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
+
+	cdp_vdev_detach(soc,
+		iface->handle, NULL, NULL);
+	iface->handle = NULL;
+}
+
+/**
+ * wma_release_vdev_ref() - Release vdev object reference count
+ * @wma_handle: wma handle
+ * @vdev_id: used to get wma interface txrx node
+ *
+ * Purpose of this function is to release vdev object reference count
+ * from wma interface txrx node.
+ *
+ * Return: None
+ */
+static void
+wma_release_vdev_ref(tp_wma_handle wma_handle, uint8_t vdev_id)
+{
+	struct wma_txrx_node *iface;
+	struct wlan_objmgr_vdev *vdev;
+
+	iface = &wma_handle->interfaces[vdev_id];
+	vdev = iface->vdev;
+
+	iface->vdev = NULL;
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+}
+
+static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle,
+			struct del_sta_self_params *del_sta_self_req_param,
+			uint8_t generate_rsp)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t vdev_id = del_sta_self_req_param->session_id;
+	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
+	struct wma_target_req *msg = NULL;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!soc) {
+		WMA_LOGE("%s:SOC context is NULL", __func__);
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	status = wmi_unified_vdev_delete_send(wma_handle->wmi_handle, vdev_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Unable to remove an interface");
+		goto out;
+	}
+
+	WMA_LOGD("vdev_id:%hu vdev_hdl:%pK", vdev_id, iface->handle);
+	if (!generate_rsp) {
+		WMA_LOGE("Call txrx detach w/o callback for vdev %d", vdev_id);
+		goto out;
+	}
+
+	iface->del_staself_req = del_sta_self_req_param;
+	msg = wma_fill_vdev_req(wma_handle, vdev_id, WMA_DEL_STA_SELF_REQ,
+				WMA_TARGET_REQ_TYPE_VDEV_DEL, iface, 6000);
+	if (!msg) {
+		WMA_LOGE("%s: Failed to fill vdev request for vdev_id %d",
+			 __func__, vdev_id);
+		status = QDF_STATUS_E_NOMEM;
+		iface->del_staself_req = NULL;
+		goto out;
+	}
+
+	/* Acquire wake lock only when you expect a response from firmware */
+	if (wmi_service_enabled(wma_handle->wmi_handle,
+				   wmi_service_sync_delete_cmds)) {
+		wma_acquire_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock,
+				     WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION);
+	}
+	WMA_LOGD("Call txrx detach with callback for vdev %d", vdev_id);
+	wma_release_vdev_ref(wma_handle, vdev_id);
+	wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
+
+	/*
+	 * send the response immediately if WMI_SERVICE_SYNC_DELETE_CMDS
+	 * service is not supported by firmware
+	 */
+	if (!wmi_service_enabled(wma_handle->wmi_handle,
+				    wmi_service_sync_delete_cmds))
+		wma_vdev_detach_callback(iface);
+	return status;
+out:
+	WMA_LOGE("Call txrx detach callback for vdev %d, generate_rsp %u",
+		vdev_id, generate_rsp);
+	wma_release_vdev_ref(wma_handle, vdev_id);
+	wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
+
+	wma_vdev_deinit(iface);
+	qdf_mem_zero(iface, sizeof(*iface));
+	wma_vdev_init(iface);
+
+	del_sta_self_req_param->status = status;
+	if (generate_rsp)
+		wma_send_del_sta_self_resp(del_sta_self_req_param);
+	return status;
+}
+
+/**
+ * wma_force_objmgr_vdev_peer_cleanup() - Cleanup ObjMgr Vdev peers during SSR
+ * @wma_handle: WMA handle
+ * @vdev_id: vdev ID
+ *
+ * Return: none
+ */
+static void wma_force_objmgr_vdev_peer_cleanup(tp_wma_handle wma,
+					       uint8_t vdev_id)
+{
+	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_peer *peer = NULL;
+	struct wlan_objmgr_peer *peer_next = NULL;
+	qdf_list_t *peer_list;
+
+	WMA_LOGE("%s: SSR: force cleanup peers in vdev(%d)",
+		 __func__, vdev_id);
+	iface->vdev_active = false;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc, vdev_id,
+						    WLAN_LEGACY_WMA_ID);
+
+	if (!vdev) {
+		WMA_LOGE("Failed to get Objmgr Vdev");
+		return;
+	}
+
+	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
+	if (!peer_list) {
+		WMA_LOGE("%s: peer_list is NULL", __func__);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+		return;
+	}
+
+	/*
+	 * We get refcount for each peer first, logically delete it and
+	 * then release the refcount so that the peer is physically
+	 * deleted.
+	 */
+	peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list,
+						    WLAN_LEGACY_WMA_ID);
+	while (peer) {
+		WMA_LOGD("%s: Deleting Peer %pM",
+			 __func__, peer->macaddr);
+		wlan_objmgr_peer_obj_delete(peer);
+		peer_next = wlan_peer_get_next_active_peer_of_vdev(vdev,
+					peer_list, peer, WLAN_LEGACY_WMA_ID);
+		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
+		peer = peer_next;
+	}
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+
+	/* Force delete all the peers, set the wma interface peer_count to 0 */
+	iface->peer_count = 0;
+}
+
+static bool wma_vdev_uses_self_peer(uint32_t vdev_type, uint32_t vdev_subtype)
+{
+	switch (vdev_type) {
+	case WMI_VDEV_TYPE_AP:
+		return vdev_subtype == WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE;
+
+	case WMI_VDEV_TYPE_MONITOR:
+	case WMI_VDEV_TYPE_OCB:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+/**
+ * wma_remove_objmgr_peer() - remove objmgr peer information from host driver
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @peer_addr: peer mac address
+ *
+ * Return: none
+ */
+static void wma_remove_objmgr_peer(tp_wma_handle wma, uint8_t vdev_id,
+				   uint8_t *peer_addr)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_peer *obj_peer;
+	struct wlan_objmgr_vdev *obj_vdev;
+	struct wlan_objmgr_pdev *obj_pdev;
+	uint8_t pdev_id = 0;
+
+	psoc = wma->psoc;
+	if (!psoc) {
+		WMA_LOGE("%s:PSOC is NULL", __func__);
+		return;
+	}
+
+	obj_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+							WLAN_LEGACY_WMA_ID);
+	if (!obj_vdev) {
+		WMA_LOGE("Obj vdev not found. Unable to remove peer");
+		return;
+	}
+	obj_pdev = wlan_vdev_get_pdev(obj_vdev);
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(obj_pdev);
+	obj_peer = wlan_objmgr_get_peer(psoc, pdev_id, peer_addr,
+					WLAN_LEGACY_WMA_ID);
+	if (obj_peer) {
+		wlan_objmgr_peer_obj_delete(obj_peer);
+		/* Unref to decrement ref happened in find_peer */
+		wlan_objmgr_peer_release_ref(obj_peer, WLAN_LEGACY_WMA_ID);
+		WMA_LOGD("Peer %pM deleted", peer_addr);
+	} else {
+		WMA_LOGE("Peer %pM not found", peer_addr);
+	}
+
+	wlan_objmgr_vdev_release_ref(obj_vdev, WLAN_LEGACY_WMA_ID);
+}
+
+/**
+ * wma_vdev_detach() - send vdev delete command to fw
+ * @wma_handle: wma handle
+ * @pdel_sta_self_req_param: del sta params
+ * @generateRsp: generate Response flag
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
+			struct del_sta_self_params *pdel_sta_self_req_param,
+			uint8_t generateRsp)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	uint8_t vdev_id = pdel_sta_self_req_param->session_id;
+	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
+	struct wma_target_req *req_msg;
+
+	if (!iface->handle) {
+		WMA_LOGE("handle of vdev_id %d is NULL vdev is already freed",
+			 vdev_id);
+		goto send_rsp;
+	}
+
+	/*
+	 * In SSR case or if FW is down we only need to clean up the host.
+	 * There is no need to destroy vdev in firmware since it
+	 * has already asserted.
+	 * Cleanup the ObjMgr Peers for the current vdev and detach the
+	 * CDP Vdev.
+	 */
+	if (!cds_is_target_ready()) {
+		wma_force_objmgr_vdev_peer_cleanup(wma_handle, vdev_id);
+		wma_release_vdev_ref(wma_handle, vdev_id);
+		wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
+		goto send_rsp;
+	}
+
+	if (qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) {
+		req_msg = wma_find_vdev_req(wma_handle, vdev_id,
+				WMA_TARGET_REQ_TYPE_VDEV_STOP, false);
+		if (!req_msg)
+			goto send_fail_rsp;
+		if (req_msg->msg_type != WMA_DELETE_BSS_REQ)
+			goto send_fail_rsp;
+		WMA_LOGA("BSS is not yet stopped. Defering vdev(vdev id %x) deletion",
+			vdev_id);
+		iface->del_staself_req = pdel_sta_self_req_param;
+		iface->is_del_sta_defered = true;
+		return status;
+	}
+	iface->is_del_sta_defered = false;
+
+	if (wma_vdev_uses_self_peer(iface->type, iface->sub_type)) {
+		status = wma_self_peer_remove(wma_handle,
+					pdel_sta_self_req_param, generateRsp);
+		if ((status != QDF_STATUS_SUCCESS) && generateRsp) {
+			WMA_LOGE("can't remove selfpeer, send rsp session: %d",
+				 vdev_id);
+			status = wma_handle_vdev_detach(wma_handle,
+							pdel_sta_self_req_param,
+							generateRsp);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				WMA_LOGE("Trigger recovery for vdev %d",
+					 vdev_id);
+				cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
+			}
+			return status;
+		} else if (status != QDF_STATUS_SUCCESS) {
+			WMA_LOGE("can't remove selfpeer, free msg session: %d",
+				 vdev_id);
+			qdf_mem_free(pdel_sta_self_req_param);
+			pdel_sta_self_req_param = NULL;
+			return status;
+		}
+		if (!wmi_service_enabled(wma_handle->wmi_handle,
+				wmi_service_sync_delete_cmds))
+			status = wma_handle_vdev_detach(wma_handle,
+				pdel_sta_self_req_param, generateRsp);
+	} else {
+		if (iface->type == WMI_VDEV_TYPE_STA) {
+			wma_remove_objmgr_peer(wma_handle, vdev_id,
+				pdel_sta_self_req_param->self_mac_addr);
+		}
+		status = wma_handle_vdev_detach(wma_handle,
+				pdel_sta_self_req_param, generateRsp);
+	}
+
+	if (QDF_IS_STATUS_SUCCESS(status))
+		iface->vdev_active = false;
+	return status;
+
+send_fail_rsp:
+	WMA_LOGE("rcvd del_self_sta without del_bss; vdev_id:%d", vdev_id);
+	cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
+	status = QDF_STATUS_E_FAILURE;
+
+send_rsp:
+	if (generateRsp) {
+		pdel_sta_self_req_param->status = status;
+		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;
+}
+
+/**
+ * wma_send_start_resp() - send vdev start response to upper layer
+ * @wma: wma handle
+ * @add_bss: add bss params
+ * @resp_event: response params
+ *
+ * Return: none
+ */
+#ifdef CONFIG_VDEV_SM
+static void wma_send_start_resp(tp_wma_handle wma,
+				tpAddBssParams add_bss,
+				wmi_vdev_start_response_event_fixed_param *
+				resp_event)
+{
+	struct wma_txrx_node *iface = &wma->interfaces[resp_event->vdev_id];
+
+	if (!resp_event->status && QDF_IS_STATUS_SUCCESS(add_bss->status)) {
+		add_bss->status =
+		  wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+						WLAN_VDEV_SM_EV_START_RESP,
+						sizeof(*add_bss), add_bss);
+		if (QDF_IS_STATUS_SUCCESS(add_bss->status))
+			return;
+	}
+
+	/* Send vdev stop if vdev start was success */
+	if (QDF_IS_STATUS_ERROR(add_bss->status) &&
+	    !resp_event->status) {
+		wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+					      WLAN_VDEV_SM_EV_DOWN,
+					      sizeof(*add_bss),	add_bss);
+		return;
+	}
+
+	wma_remove_peer_on_add_bss_failure(add_bss);
+
+	WMA_LOGD(FL("Sending add bss rsp to umac(vdev %d status %d)"),
+		 resp_event->vdev_id, add_bss->status);
+	wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
+}
+#else
+static void wma_send_start_resp(tp_wma_handle wma,
+				tpAddBssParams add_bss,
+				wmi_vdev_start_response_event_fixed_param *
+				resp_event)
+{
+	/* Send vdev stop if vdev start was success */
+	if (QDF_IS_STATUS_ERROR(add_bss->status)) {
+		if (!resp_event->status)
+			if (wma_send_vdev_stop_to_fw(wma, resp_event->vdev_id))
+				WMA_LOGE(FL("Failed to send vdev stop"));
+
+		wma_remove_peer_on_add_bss_failure(add_bss);
+	}
+
+	WMA_LOGD(FL("Sending add bss rsp to umac(vdev %d status %d)"),
+		 resp_event->vdev_id, add_bss->status);
+	wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
+}
+#endif
+
+/**
+ * wma_vdev_start_rsp() - send vdev start response to upper layer
+ * @wma: wma handle
+ * @add_bss: add bss params
+ * @resp_event: response params
+ *
+ * Return: none
+ */
+static void wma_vdev_start_rsp(tp_wma_handle wma,
+			       tpAddBssParams add_bss,
+			       wmi_vdev_start_response_event_fixed_param *
+			       resp_event)
+{
+	struct beacon_info *bcn;
+
+#ifdef QCA_IBSS_SUPPORT
+	WMA_LOGD("%s: vdev start response received for %s mode", __func__,
+		 add_bss->operMode ==
+		 BSS_OPERATIONAL_MODE_IBSS ? "IBSS" : "non-IBSS");
+#endif /* QCA_IBSS_SUPPORT */
+
+	if (resp_event->status) {
+		add_bss->status = QDF_STATUS_E_FAILURE;
+		goto send_fail_resp;
+	}
+
+	if ((add_bss->operMode == BSS_OPERATIONAL_MODE_AP)
+#ifdef QCA_IBSS_SUPPORT
+	    || (add_bss->operMode == BSS_OPERATIONAL_MODE_IBSS)
+#endif /* QCA_IBSS_SUPPORT */
+	    ) {
+		wma->interfaces[resp_event->vdev_id].beacon =
+			qdf_mem_malloc(sizeof(struct beacon_info));
+
+		bcn = wma->interfaces[resp_event->vdev_id].beacon;
+		if (!bcn) {
+			add_bss->status = QDF_STATUS_E_NOMEM;
+			goto send_fail_resp;
+		}
+		bcn->buf = qdf_nbuf_alloc(NULL, SIR_MAX_BEACON_SIZE, 0,
+					  sizeof(uint32_t), 0);
+		if (!bcn->buf) {
+			qdf_mem_free(bcn);
+			add_bss->status = QDF_STATUS_E_FAILURE;
+			goto send_fail_resp;
+		}
+		bcn->seq_no = MIN_SW_SEQ;
+		qdf_spinlock_create(&bcn->lock);
+		qdf_atomic_set(&wma->interfaces[resp_event->vdev_id].bss_status,
+			       WMA_BSS_STATUS_STARTED);
+		WMA_LOGD("%s: AP mode (type %d subtype %d) BSS is started",
+			 __func__, wma->interfaces[resp_event->vdev_id].type,
+			 wma->interfaces[resp_event->vdev_id].sub_type);
+
+		WMA_LOGD("%s: Allocated beacon struct %pK, template memory %pK",
+			 __func__, bcn, bcn->buf);
+	}
+	add_bss->status = QDF_STATUS_SUCCESS;
+	add_bss->bssIdx = resp_event->vdev_id;
+	add_bss->chainMask = resp_event->chain_mask;
+	if ((2 != resp_event->cfgd_rx_streams) ||
+		(2 != resp_event->cfgd_tx_streams)) {
+		add_bss->nss = 1;
+	}
+	add_bss->smpsMode = host_map_smps_mode(resp_event->smps_mode);
+
+send_fail_resp:
+	wma_send_start_resp(wma, add_bss, resp_event);
+}
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+/**
+ * wma_find_mcc_ap() - finds if device is operating AP in MCC mode or not
+ * @wma: wma handle.
+ * @vdev_id: vdev ID of device for which MCC has to be checked
+ * @add: flag indicating if current device is added or deleted
+ *
+ * This function parses through all the interfaces in wma and finds if
+ * any of those devces are in MCC mode with AP. If such a vdev is found
+ * involved AP vdevs are sent WDA_UPDATE_Q2Q_IE_IND msg to update their
+ * beacon template to include Q2Q IE.
+ *
+ * Return: none
+ */
+static void wma_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id, bool add)
+{
+	uint8_t i;
+	uint16_t prev_ch_freq = 0;
+	bool is_ap = false;
+	bool result = false;
+	uint8_t *ap_vdev_ids = NULL;
+	uint8_t num_ch = 0;
+
+	ap_vdev_ids = qdf_mem_malloc(wma->max_bssid);
+	if (!ap_vdev_ids)
+		return;
+
+	for (i = 0; i < wma->max_bssid; i++) {
+		ap_vdev_ids[i] = -1;
+		if (add == false && i == vdev_id)
+			continue;
+
+		if (wma_is_vdev_up(vdev_id) || (i == vdev_id && add)) {
+			if (wma->interfaces[i].type == WMI_VDEV_TYPE_AP) {
+				is_ap = true;
+				ap_vdev_ids[i] = i;
+			}
+
+			if (wma->interfaces[i].mhz != prev_ch_freq) {
+				num_ch++;
+				prev_ch_freq = wma->interfaces[i].mhz;
+			}
+		}
+	}
+
+	if (is_ap && (num_ch > 1))
+		result = true;
+	else
+		result = false;
+
+	wma_send_msg(wma, WMA_UPDATE_Q2Q_IE_IND, (void *)ap_vdev_ids, result);
+}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+/**
+ * wma_vdev_start_resp_handler() - vdev start response handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
+				uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf;
+	wmi_vdev_start_response_event_fixed_param *resp_event;
+	struct wma_target_req *req_msg;
+	struct wma_txrx_node *iface;
+	struct vdev_up_params param = {0};
+	QDF_STATUS status;
+	int err;
+	wmi_host_channel_width chanwidth;
+	target_resource_config *wlan_res_cfg;
+	struct wlan_objmgr_psoc *psoc = wma->psoc;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+#endif
+#ifdef CONFIG_VDEV_SM
+	enum wlan_vdev_sm_evt  event;
+#endif
+	if (!psoc) {
+		WMA_LOGE("%s: psoc is NULL", __func__);
+		return -EINVAL;
+	}
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	if (NULL == mac_ctx) {
+		WMA_LOGE("%s: Failed to get mac_ctx", __func__);
+		policy_mgr_set_do_hw_mode_change_flag(
+			psoc, false);
+		return -EINVAL;
+	}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	wlan_res_cfg = lmac_get_tgt_res_cfg(psoc);
+	if (!wlan_res_cfg) {
+		WMA_LOGE("%s: Wlan resource config is NULL", __func__);
+		return -EINVAL;
+	}
+
+	param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("Invalid start response event buffer");
+		policy_mgr_set_do_hw_mode_change_flag(
+			wma->psoc, false);
+		return -EINVAL;
+	}
+
+	resp_event = param_buf->fixed_param;
+	if (!resp_event) {
+		WMA_LOGE("Invalid start response event buffer");
+		policy_mgr_set_do_hw_mode_change_flag(
+			wma->psoc, false);
+		return -EINVAL;
+	}
+
+	if (resp_event->vdev_id >= wma->max_bssid) {
+		WMA_LOGE("Invalid vdev id received from firmware");
+		return -EINVAL;
+	}
+
+	if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id))
+		tgt_dfs_radar_enable(wma->pdev, 0, 0);
+
+	if (resp_event->status == QDF_STATUS_SUCCESS) {
+		wma->interfaces[resp_event->vdev_id].tx_streams =
+			resp_event->cfgd_tx_streams;
+		wma->interfaces[resp_event->vdev_id].rx_streams =
+			resp_event->cfgd_rx_streams;
+		wma->interfaces[resp_event->vdev_id].chain_mask =
+			resp_event->chain_mask;
+		if (wlan_res_cfg->use_pdev_id) {
+			if (resp_event->pdev_id == WMI_PDEV_ID_SOC) {
+				WMA_LOGE("%s: soc level id received for mac id",
+					__func__);
+				return -EINVAL;
+			}
+			wma->interfaces[resp_event->vdev_id].mac_id =
+				WMA_PDEV_TO_MAC_MAP(resp_event->pdev_id);
+		} else {
+			wma->interfaces[resp_event->vdev_id].mac_id =
+				resp_event->mac_id;
+		}
+
+		WMA_LOGD("%s: vdev:%d tx ss=%d rx ss=%d chain mask=%d mac=%d",
+				__func__,
+				resp_event->vdev_id,
+				wma->interfaces[resp_event->vdev_id].tx_streams,
+				wma->interfaces[resp_event->vdev_id].rx_streams,
+				wma->interfaces[resp_event->vdev_id].chain_mask,
+				wma->interfaces[resp_event->vdev_id].mac_id);
+	}
+
+	iface = &wma->interfaces[resp_event->vdev_id];
+
+	req_msg = wma_find_vdev_req(wma, resp_event->vdev_id,
+				    WMA_TARGET_REQ_TYPE_VDEV_START,
+				    true);
+
+	if (!req_msg) {
+		WMA_LOGE("%s: Failed to lookup request message for vdev %d",
+			 __func__, resp_event->vdev_id);
+		policy_mgr_set_do_hw_mode_change_flag(wma->psoc, false);
+		return -EINVAL;
+	}
+	qdf_mc_timer_stop(&req_msg->event_timeout);
+
+	if (wma_get_hidden_ssid_restart_in_progress(iface) &&
+	    wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id) &&
+	    (req_msg->msg_type == WMA_HIDDEN_SSID_VDEV_RESTART)) {
+		tpHalHiddenSsidVdevRestart hidden_ssid_restart =
+			(tpHalHiddenSsidVdevRestart)req_msg->user_data;
+		WMA_LOGE("%s: vdev restart event recevied for hidden ssid set using IOCTL",
+			__func__);
+#ifdef CONFIG_VDEV_SM
+		wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+					      WLAN_VDEV_SM_EV_RESTART_RESP,
+					      sizeof(*hidden_ssid_restart),
+					      hidden_ssid_restart);
+#else
+		qdf_atomic_set(&iface->vdev_restart_params.
+			       hidden_ssid_restart_in_progress, 0);
+		wma_send_msg(wma, WMA_HIDDEN_SSID_RESTART_RSP,
+				(void *)hidden_ssid_restart, 0);
+#endif
+	}
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	if (resp_event->status == QDF_STATUS_SUCCESS
+		&& mac_ctx->sap.sap_channel_avoidance)
+		wma_find_mcc_ap(wma, resp_event->vdev_id, true);
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+	if (req_msg->msg_type == WMA_CHNL_SWITCH_REQ) {
+		tpSwitchChannelParams params =
+			(tpSwitchChannelParams) req_msg->user_data;
+
+		if (!params) {
+			WMA_LOGE("%s: channel switch params is NULL for vdev %d",
+				__func__, resp_event->vdev_id);
+			policy_mgr_set_do_hw_mode_change_flag(wma->psoc, false);
+			return -EINVAL;
+		}
+
+		WMA_LOGD("%s: Send channel switch resp vdev %d status %d",
+			 __func__, resp_event->vdev_id, resp_event->status);
+		params->chainMask = resp_event->chain_mask;
+		if ((2 != resp_event->cfgd_rx_streams) ||
+			(2 != resp_event->cfgd_tx_streams)) {
+			params->nss = 1;
+		}
+		params->smpsMode = host_map_smps_mode(resp_event->smps_mode);
+		params->status = resp_event->status;
+#ifndef CONFIG_VDEV_SM
+		if (wma->interfaces[resp_event->vdev_id].is_channel_switch) {
+			wma->interfaces[resp_event->vdev_id].is_channel_switch =
+				false;
+		}
+#endif
+		if ((QDF_IS_STATUS_SUCCESS(resp_event->status) &&
+		     (resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT) &&
+		     ((iface->type == WMI_VDEV_TYPE_STA) ||
+		      (iface->type == WMI_VDEV_TYPE_MONITOR))) ||
+		    ((resp_event->resp_type == WMI_VDEV_START_RESP_EVENT) &&
+		     (iface->type == WMI_VDEV_TYPE_MONITOR))) {
+			/* for CSA case firmware expects phymode before ch_wd */
+			err = wma_set_peer_param(wma, iface->bssid,
+					WMI_PEER_PHYMODE, iface->chanmode,
+					resp_event->vdev_id);
+			WMA_LOGD("%s:vdev_id %d chanmode %d status %d",
+				__func__, resp_event->vdev_id,
+				iface->chanmode, err);
+
+			chanwidth =
+				wmi_get_ch_width_from_phy_mode(wma->wmi_handle,
+							       iface->chanmode);
+			err = wma_set_peer_param(wma, iface->bssid,
+					WMI_PEER_CHWIDTH, chanwidth,
+					resp_event->vdev_id);
+			WMA_LOGD("%s:vdev_id %d chanwidth %d status %d",
+				__func__, resp_event->vdev_id,
+				chanwidth, err);
+
+			param.vdev_id = resp_event->vdev_id;
+			param.assoc_id = iface->aid;
+			status = wma_send_vdev_up_to_fw(wma, &param,
+							iface->bssid);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				WMA_LOGE("%s:vdev_up failed vdev_id %d",
+					 __func__, resp_event->vdev_id);
+#ifndef CONFIG_VDEV_SM
+				wma_vdev_set_mlme_state(wma,
+					resp_event->vdev_id, WLAN_VDEV_S_STOP);
+#endif
+				policy_mgr_set_do_hw_mode_change_flag(
+					wma->psoc, false);
+			} else {
+#ifndef CONFIG_VDEV_SM
+				wma_vdev_set_mlme_state(wma,
+					resp_event->vdev_id, WLAN_VDEV_S_RUN);
+#endif
+				if (iface->beacon_filter_enabled)
+					wma_add_beacon_filter(wma,
+							&iface->beacon_filter);
+			}
+		}
+#ifdef CONFIG_VDEV_SM
+		if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id))
+			event = WLAN_VDEV_SM_EV_RESTART_RESP;
+		else
+			event = WLAN_VDEV_SM_EV_START_RESP;
+		wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+					      event,
+					      sizeof(*params), params);
+#else
+		wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP,
+					   (void *)params, 0);
+#endif
+	} else if (req_msg->msg_type == WMA_ADD_BSS_REQ) {
+		tpAddBssParams bssParams = (tpAddBssParams) req_msg->user_data;
+
+		qdf_mem_copy(iface->bssid, bssParams->bssId,
+				IEEE80211_ADDR_LEN);
+		wma_vdev_start_rsp(wma, bssParams, resp_event);
+	} else if (req_msg->msg_type == WMA_OCB_SET_CONFIG_CMD) {
+		param.vdev_id = resp_event->vdev_id;
+		param.assoc_id = iface->aid;
+		if (wma_send_vdev_up_to_fw(wma, &param, iface->bssid) !=
+		    QDF_STATUS_SUCCESS) {
+			WMA_LOGE(FL("failed to send vdev up"));
+			policy_mgr_set_do_hw_mode_change_flag(
+				wma->psoc, false);
+			return -EEXIST;
+		}
+#ifndef CONFIG_VDEV_SM
+		wma_vdev_set_mlme_state(wma, resp_event->vdev_id,
+			WLAN_VDEV_S_RUN);
+#endif
+		ucfg_ocb_config_channel(wma->pdev);
+	}
+
+	if ((wma->interfaces[resp_event->vdev_id].type == WMI_VDEV_TYPE_AP) &&
+		wma_is_vdev_up(resp_event->vdev_id))
+		wma_set_sap_keepalive(wma, resp_event->vdev_id);
+
+	qdf_mc_timer_destroy(&req_msg->event_timeout);
+	qdf_mem_free(req_msg);
+
+	return 0;
+}
+
+bool wma_is_vdev_valid(uint32_t vdev_id)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		WMA_LOGD("%s: vdev_id: %d, null wma_handle", __func__, vdev_id);
+		return false;
+	}
+
+	/* No of interface are allocated based on max_bssid value */
+	if (vdev_id >= wma_handle->max_bssid) {
+		WMA_LOGD("%s: vdev_id: %d is invalid, max_bssid: %d",
+				__func__, vdev_id, wma_handle->max_bssid);
+		return false;
+	}
+
+	WMA_LOGD("%s: vdev_id: %d, vdev_active: %d", __func__, vdev_id,
+		 wma_handle->interfaces[vdev_id].vdev_active);
+
+	return wma_handle->interfaces[vdev_id].vdev_active;
+}
+
+/**
+ * wma_vdev_set_param() - set per vdev params in fw
+ * @wmi_handle: wmi handle
+ * @if_id: vdev id
+ * @param_id: parameter id
+ * @param_value: parameter value
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS
+wma_vdev_set_param(wmi_unified_t wmi_handle, uint32_t if_id,
+				uint32_t param_id, uint32_t param_value)
+{
+	struct vdev_set_params param = {0};
+
+	if (!wma_is_vdev_valid(if_id)) {
+		WMA_LOGE(FL("vdev_id: %d is not active reject the req: param id %d val %d"),
+			if_id, param_id, param_value);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	param.if_id = if_id;
+	param.param_id = param_id;
+	param.param_value = param_value;
+
+	return wmi_unified_vdev_set_param_send(wmi_handle, &param);
+}
+
+/**
+ * wma_set_peer_authorized_cb() - set peer authorized callback function
+ * @wma_ctx: wma handle
+ * @auth_cb: peer authorized callback
+ *
+ * Return: none
+ */
+void wma_set_peer_authorized_cb(void *wma_ctx, wma_peer_authorized_fp auth_cb)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) wma_ctx;
+
+	wma_handle->peer_authorized_cb = auth_cb;
+}
+
+/**
+ * wma_set_peer_param() - set peer parameter in fw
+ * @wma_ctx: wma handle
+ * @peer_addr: peer mac address
+ * @param_id: parameter id
+ * @param_value: parameter value
+ * @vdev_id: vdev id
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr,
+			      uint32_t param_id, uint32_t param_value,
+			      uint32_t vdev_id)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) wma_ctx;
+	struct peer_set_params param = {0};
+	int err;
+
+	param.vdev_id = vdev_id;
+	param.param_value = param_value;
+	param.param_id = param_id;
+
+	err = wmi_set_peer_param_send(wma_handle->wmi_handle, peer_addr,
+					   &param);
+
+	return err;
+}
+
+/**
+ * wma_remove_peer() - remove peer information from host driver and fw
+ * @wma: wma handle
+ * @bssid: mac address
+ * @vdev_id: vdev id
+ * @peer: peer ptr
+ * @roam_synch_in_progress: roam in progress flag
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *bssid,
+			   uint8_t vdev_id, void *peer,
+			   bool roam_synch_in_progress)
+{
+#define PEER_ALL_TID_BITMASK 0xffffffff
+	uint32_t peer_tid_bitmap = PEER_ALL_TID_BITMASK;
+	uint8_t *peer_addr = bssid;
+	uint8_t peer_mac[QDF_MAC_ADDR_SIZE] = {0};
+	struct peer_flush_params param = {0};
+	uint8_t *peer_mac_addr;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	void *vdev;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	uint32_t bitmap = 1 << CDP_PEER_DELETE_NO_SPECIAL;
+
+	if (!wma->interfaces[vdev_id].peer_count) {
+		WMA_LOGE("%s: Can't remove peer with peer_addr %pM vdevid %d peer_count %d",
+			 __func__, bssid, vdev_id,
+			wma->interfaces[vdev_id].peer_count);
+		cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!soc) {
+		WMA_LOGE("%s:SOC context is NULL", __func__);
+		QDF_BUG(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!peer) {
+		WMA_LOGE("%s: PEER is NULL for vdev_id: %d", __func__, vdev_id);
+		QDF_BUG(0);
+		return QDF_STATUS_E_INVAL;
+	}
+	peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer);
+	if (peer_mac_addr == NULL) {
+		WMA_LOGE("%s: peer mac addr is NULL, Can't remove peer with peer_addr %pM vdevid %d peer_count %d",
+			 __func__, bssid, vdev_id,
+			 wma->interfaces[vdev_id].peer_count);
+		QDF_BUG(0);
+		return QDF_STATUS_E_INVAL;
+	}
+	vdev = cdp_get_vdev_from_vdev_id(soc, pdev, vdev_id);
+	if (!vdev) {
+		WMA_LOGE("%s vdev is null for peer peer->mac_addr %pM",
+			 __func__, peer_mac_addr);
+		QDF_BUG(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	cdp_peer_teardown(soc, vdev, peer);
+
+	if (roam_synch_in_progress)
+		goto peer_detach;
+	/* Flush all TIDs except MGMT TID for this peer in Target */
+	peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID);
+	param.peer_tid_bitmap = peer_tid_bitmap;
+	param.vdev_id = vdev_id;
+	wmi_unified_peer_flush_tids_send(wma->wmi_handle, bssid,
+			&param);
+
+	if (wma_is_vdev_in_ibss_mode(wma, vdev_id)) {
+		WMA_LOGD("%s: bssid %pM peer->mac_addr %pM", __func__,
+			 bssid, peer_mac_addr);
+		peer_addr = peer_mac_addr;
+	}
+
+	/* peer->ref_cnt is not visible in WMA */
+	wlan_roam_debug_log(vdev_id, DEBUG_PEER_DELETE_SEND,
+			    DEBUG_INVALID_PEER_ID, peer_addr, peer,
+			    0, 0);
+	qdf_status = wmi_unified_peer_delete_send(wma->wmi_handle, peer_addr,
+						  vdev_id);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		WMA_LOGE("%s Peer delete could not be sent to firmware %d",
+			 __func__, qdf_status);
+		/* Clear default bit and set to NOT_START_UNMAP */
+		bitmap = 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER;
+		qdf_status = QDF_STATUS_E_FAILURE;
+	}
+
+peer_detach:
+	WMA_LOGD("%s: vdev %pK is detaching %pK with peer_addr %pM vdevid %d peer_count %d",
+		__func__, vdev, peer, peer_mac_addr, vdev_id,
+		wma->interfaces[vdev_id].peer_count);
+	/* Copy peer mac to find and delete objmgr peer */
+	qdf_mem_copy(peer_mac, peer_mac_addr, QDF_MAC_ADDR_SIZE);
+	if (roam_synch_in_progress &&
+	    is_cdp_peer_detach_force_delete_supported(soc)) {
+		WMA_LOGD("%s: LFR3: trigger force delete for peer %pM",
+			 __func__, peer_mac_addr);
+		cdp_peer_detach_force_delete(soc, peer);
+	} else {
+		if (roam_synch_in_progress) {
+			WMA_LOGD("%s: LFR3: normal peer delete for peer %pM",
+				 __func__, peer_mac_addr);
+		}
+		cdp_peer_delete(soc, peer, bitmap);
+	}
+
+	wma_remove_objmgr_peer(wma, vdev_id, peer_mac);
+
+	wma->interfaces[vdev_id].peer_count--;
+#undef PEER_ALL_TID_BITMASK
+
+	return qdf_status;
+}
+
+/**
+ * wma_find_duplicate_peer_on_other_vdev() - Find if same peer exist
+ * on other vdevs
+ * @wma: wma handle
+ * @pdev: txrx pdev ptr
+ * @vdev_id: vdev id of vdev on which the peer
+ *           needs to be added
+ * @peer_mac: peer mac addr which needs to be added
+ *
+ * Check if peer with same MAC is present on vdev other then
+ * the provided vdev_id
+ *
+ * Return: true if same peer is present on vdev other then vdev_id
+ * else return false
+ */
+static bool wma_find_duplicate_peer_on_other_vdev(tp_wma_handle wma,
+	struct cdp_pdev *pdev, uint8_t vdev_id, uint8_t *peer_mac)
+{
+	int i;
+	uint8_t peer_id;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	for (i = 0; i < wma->max_bssid; i++) {
+		/* Need to check vdevs other than the vdev_id */
+		if (vdev_id == i ||
+		   !wma->interfaces[i].handle)
+			continue;
+		if (cdp_peer_find_by_addr_and_vdev(soc, pdev,
+			wma->interfaces[i].handle, peer_mac, &peer_id)) {
+			WMA_LOGE("%s :Duplicate peer %pM (peer id %d) already exist on vdev %d",
+				__func__, peer_mac, peer_id, i);
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * wma_get_peer_type() - Determine the type of peer(eg. STA/AP) and return it
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @peer_addr: peer mac address
+ * @wma_peer_type: wma peer type
+ *
+ * Return: Peer type
+ */
+static int wma_get_obj_mgr_peer_type(tp_wma_handle wma, uint8_t vdev_id,
+				     uint8_t *peer_addr, uint32_t wma_peer_type)
+
+{
+	uint32_t obj_peer_type = 0;
+
+	WMA_LOGD("vdev id %d vdev type %d vdev subtype %d peer addr %pM vdev addr %pM",
+		 vdev_id, wma->interfaces[vdev_id].type,
+		 wma->interfaces[vdev_id].sub_type, peer_addr,
+		 wma->interfaces[vdev_id].addr);
+
+	if (wma_peer_type == WMI_PEER_TYPE_TDLS)
+		return WLAN_PEER_TDLS;
+
+	if (!qdf_mem_cmp(wma->interfaces[vdev_id].addr, peer_addr,
+					IEEE80211_ADDR_LEN)) {
+		obj_peer_type = WLAN_PEER_SELF;
+	} else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA) {
+		if (wma->interfaces[vdev_id].sub_type ==
+					WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT)
+			obj_peer_type = WLAN_PEER_P2P_GO;
+		else
+			obj_peer_type = WLAN_PEER_AP;
+	} else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_AP) {
+		if (wma->interfaces[vdev_id].sub_type ==
+				WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO)
+			obj_peer_type = WLAN_PEER_P2P_CLI;
+		else
+			obj_peer_type = WLAN_PEER_STA;
+	} else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_IBSS) {
+		obj_peer_type = WLAN_PEER_IBSS;
+	} else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_NDI) {
+		obj_peer_type = WLAN_PEER_NDP;
+	} else {
+		WMA_LOGE("Couldnt find peertype for type %d and sub type %d",
+			 wma->interfaces[vdev_id].type,
+			 wma->interfaces[vdev_id].sub_type);
+	}
+
+	return obj_peer_type;
+
+}
+
+/**
+ * wma_create_objmgr_peer() - create objmgr peer information in host driver
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @peer_addr: peer mac address
+ * @wma_peer_type: peer type
+ *
+ * Return: objmgr peer pointer
+ */
+
+static struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
+						       uint8_t vdev_id,
+						       uint8_t *peer_addr,
+						       uint32_t wma_peer_type)
+{
+	uint32_t obj_peer_type = 0;
+	struct wlan_objmgr_peer *obj_peer = NULL;
+	struct wlan_objmgr_vdev *obj_vdev = NULL;
+	struct wlan_objmgr_psoc *psoc = wma->psoc;
+
+	obj_peer_type = wma_get_obj_mgr_peer_type(wma, vdev_id, peer_addr,
+						  wma_peer_type);
+	if (!obj_peer_type) {
+		WMA_LOGE("Invalid obj peer type. Unable to create peer %d",
+							obj_peer_type);
+		return NULL;
+	}
+
+	/* Create obj_mgr peer */
+	obj_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_LEGACY_WMA_ID);
+
+	if (!obj_vdev) {
+		WMA_LOGE("Invalid obj vdev. Unable to create peer %d",
+							obj_peer_type);
+		return NULL;
+	}
+
+	obj_peer = wlan_objmgr_peer_obj_create(obj_vdev, obj_peer_type,
+						peer_addr);
+	wlan_objmgr_vdev_release_ref(obj_vdev, WLAN_LEGACY_WMA_ID);
+	if (obj_peer)
+		WMA_LOGD("Peer %pM added successfully! Type: %d", peer_addr,
+			 obj_peer_type);
+
+	return obj_peer;
+
+}
+/**
+ * wma_create_peer() - send peer create command to fw
+ * @wma: wma handle
+ * @pdev: txrx pdev ptr
+ * @vdev: txrx vdev ptr
+ * @peer_addr: peer mac addr
+ * @peer_type: peer type
+ * @vdev_id: vdev id
+ * @roam_synch_in_progress: roam in progress
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev,
+			  struct cdp_vdev *vdev,
+			  uint8_t peer_addr[IEEE80211_ADDR_LEN],
+			  uint32_t peer_type, uint8_t vdev_id,
+			  bool roam_synch_in_progress)
+{
+	void *peer = NULL;
+	struct peer_create_params param = {0};
+	uint8_t *mac_addr_raw;
+	void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct wlan_objmgr_psoc *psoc = wma->psoc;
+	target_resource_config *wlan_res_cfg;
+	struct wlan_objmgr_peer *obj_peer = NULL;
+
+	if (!psoc) {
+		WMA_LOGE("%s: psoc is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wlan_res_cfg = lmac_get_tgt_res_cfg(psoc);
+	if (!wlan_res_cfg) {
+		WMA_LOGE("%s: psoc target res cfg is null", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (++wma->interfaces[vdev_id].peer_count >
+	    wlan_res_cfg->num_peers) {
+		WMA_LOGE("%s, the peer count exceeds the limit %d", __func__,
+			 wma->interfaces[vdev_id].peer_count - 1);
+		goto err;
+	}
+
+	if (!dp_soc) {
+		WMA_LOGE("%s:DP SOC context is NULL", __func__);
+		goto err;
+	}
+
+	/*
+	 * Check if peer with same MAC exist on other Vdev, If so avoid
+	 * adding this peer, as it will cause FW to crash.
+	 */
+	if (wma_find_duplicate_peer_on_other_vdev(wma, pdev,
+	   vdev_id, peer_addr))
+		goto err;
+
+	obj_peer = wma_create_objmgr_peer(wma, vdev_id, peer_addr, peer_type);
+	if (!obj_peer)
+		goto err;
+
+	/* The peer object should be created before sending the WMI peer
+	 * create command to firmware. This is to prevent a race condition
+	 * where the HTT peer map event is received before the peer object
+	 * is created in the data path
+	 */
+	peer = cdp_peer_create(dp_soc, vdev, peer_addr,
+			       (struct cdp_ctrl_objmgr_peer *)obj_peer);
+	if (!peer) {
+		WMA_LOGE("%s : Unable to attach peer %pM", __func__, peer_addr);
+		wlan_objmgr_peer_obj_delete(obj_peer);
+		goto err;
+	}
+	WMA_LOGD("%s: vdev %pK is attaching peer:%pK peer_addr %pM to vdev_id %d, peer_count - %d",
+		 __func__, vdev, peer, peer_addr, vdev_id,
+		 wma->interfaces[vdev_id].peer_count);
+
+	wlan_peer_set_dp_handle(obj_peer, peer);
+
+	if (roam_synch_in_progress) {
+		WMA_LOGD("%s: LFR3: Created peer %pK with peer_addr %pM vdev_id %d, peer_count - %d",
+			 __func__, peer, peer_addr, vdev_id,
+			 wma->interfaces[vdev_id].peer_count);
+		return QDF_STATUS_SUCCESS;
+	}
+	param.peer_addr = peer_addr;
+	param.peer_type = peer_type;
+	param.vdev_id = vdev_id;
+	if (wmi_unified_peer_create_send(wma->wmi_handle,
+					 &param) != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s : Unable to create peer in Target", __func__);
+		cdp_peer_delete(dp_soc, peer,
+				1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER);
+		wlan_objmgr_peer_obj_delete(obj_peer);
+		goto err;
+	}
+
+	WMA_LOGD("%s: Created peer %pK with peer_addr %pM vdev_id %d, peer_count - %d",
+		  __func__, peer, peer_addr, vdev_id,
+		  wma->interfaces[vdev_id].peer_count);
+
+	wlan_roam_debug_log(vdev_id, DEBUG_PEER_CREATE_SEND,
+			    DEBUG_INVALID_PEER_ID, peer_addr, peer, 0, 0);
+	cdp_peer_setup(dp_soc, vdev, peer);
+
+	WMA_LOGD("%s: Initialized peer with peer_addr %pM vdev_id %d",
+		__func__, peer_addr, vdev_id);
+
+	mac_addr_raw = cdp_get_vdev_mac_addr(dp_soc, vdev);
+	if (mac_addr_raw == NULL) {
+		WMA_LOGE("%s: peer mac addr is NULL", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	/* for each remote ibss peer, clear its keys */
+	if (wma_is_vdev_in_ibss_mode(wma, vdev_id) &&
+	    qdf_mem_cmp(peer_addr, mac_addr_raw, IEEE80211_ADDR_LEN)) {
+		tSetStaKeyParams key_info;
+
+		WMA_LOGD("%s: remote ibss peer %pM key clearing\n", __func__,
+			 peer_addr);
+		qdf_mem_set(&key_info, sizeof(key_info), 0);
+		key_info.smesessionId = vdev_id;
+		qdf_mem_copy(key_info.peer_macaddr.bytes, peer_addr,
+				IEEE80211_ADDR_LEN);
+		key_info.sendRsp = false;
+
+		wma_set_stakey(wma, &key_info);
+	}
+
+	return QDF_STATUS_SUCCESS;
+err:
+	wma->interfaces[vdev_id].peer_count--;
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * wma_cleanup_target_req_param() - free param memory of target request
+ * @tgt_req: target request params
+ *
+ * Return: none
+ */
+static void wma_cleanup_target_req_param(struct wma_target_req *tgt_req)
+{
+	if (tgt_req->msg_type == WMA_CHNL_SWITCH_REQ ||
+	   tgt_req->msg_type == WMA_DELETE_BSS_REQ ||
+	   tgt_req->msg_type == WMA_ADD_BSS_REQ) {
+		qdf_mem_free(tgt_req->user_data);
+		tgt_req->user_data = NULL;
+	}
+
+	if (tgt_req->msg_type == WMA_SET_LINK_STATE && tgt_req->user_data) {
+		tpLinkStateParams params =
+			(tpLinkStateParams) tgt_req->user_data;
+		qdf_mem_free(params->callbackArg);
+		params->callbackArg = NULL;
+		qdf_mem_free(tgt_req->user_data);
+		tgt_req->user_data = NULL;
+	}
+}
+
+/**
+ * wma_remove_bss_peer() - remove BSS peer
+ * @wma: pointer to WMA handle
+ * @pdev: pointer to PDEV
+ * @req_msg: pointer to WMA target Request
+ * @vdev_id: vdev id on which delete BSS request was received
+ * @params: pointer to Delete BSS params
+ *
+ * This function is called on receiving vdev stop response from FW or
+ * vdev stop response timeout. In case of IBSS/NDI, use vdev's self MAC
+ * for removing the peer. In case of STA/SAP use bssid passed as part of
+ * delete STA parameter.
+ *
+ * Return: 0 on success, ERROR code on failure
+ */
+static int wma_remove_bss_peer(tp_wma_handle wma, void *pdev,
+		struct wma_target_req *req_msg, uint32_t vdev_id,
+		tpDeleteBssParams params)
+{
+	void *peer, *vdev;
+	uint8_t peer_id;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	uint8_t *mac_addr = NULL;
+	struct wma_target_req *del_req;
+	int ret_value = 0;
+
+	vdev = cdp_get_vdev_from_vdev_id(soc, pdev, vdev_id);
+	if (!vdev) {
+		WMA_LOGE(FL("vdev is NULL for vdev_id = %d"), vdev_id);
+		wma_cleanup_target_req_param(req_msg);
+		return -EINVAL;
+	}
+
+	if (wma_is_vdev_in_ibss_mode(wma, vdev_id) ||
+	    WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, vdev_id)) {
+		mac_addr = cdp_get_vdev_mac_addr(soc, vdev);
+		if (!mac_addr) {
+			WMA_LOGE(FL("mac_addr is NULL for vdev_id = %d"),
+				 vdev_id);
+			wma_cleanup_target_req_param(req_msg);
+			return -EINVAL;
+		}
+	} else {
+		mac_addr = params->bssid;
+	}
+
+	peer = cdp_peer_find_by_addr(soc, pdev, mac_addr, &peer_id);
+	if (!peer) {
+		WMA_LOGE(FL("peer NULL for vdev_id = %d"), vdev_id);
+		wma_cleanup_target_req_param(req_msg);
+		return -EINVAL;
+	}
+
+	wma_remove_peer(wma, mac_addr, vdev_id, peer, false);
+	if (wmi_service_enabled(
+	   wma->wmi_handle,
+	   wmi_service_sync_delete_cmds)) {
+		WMA_LOGD(FL("Wait for the peer delete. vdev_id %d"),
+				 req_msg->vdev_id);
+		del_req = wma_fill_hold_req(wma,
+				   req_msg->vdev_id,
+				   WMA_DELETE_STA_REQ,
+				   WMA_DELETE_PEER_RSP,
+				   params,
+				   WMA_DELETE_STA_TIMEOUT);
+		if (!del_req) {
+			WMA_LOGE(FL("Failed to allocate request. vdev_id %d"),
+				 req_msg->vdev_id);
+			params->status = QDF_STATUS_E_NOMEM;
+			ret_value = -EINVAL;
+		}
+	}
+
+	return ret_value;
+}
+
+#ifdef FEATURE_WLAN_APF
+/*
+ * get_fw_active_apf_mode() - convert HDD APF mode to FW configurable APF
+ * mode
+ * @mode: APF mode maintained in HDD
+ *
+ * Return: FW configurable BP mode
+ */
+static enum wmi_host_active_apf_mode
+get_fw_active_apf_mode(enum active_apf_mode mode)
+{
+	switch (mode) {
+	case ACTIVE_APF_DISABLED:
+		return WMI_HOST_ACTIVE_APF_DISABLED;
+	case ACTIVE_APF_ENABLED:
+		return WMI_HOST_ACTIVE_APF_ENABLED;
+	case ACTIVE_APF_ADAPTIVE:
+		return WMI_HOST_ACTIVE_APF_ADAPTIVE;
+	default:
+		WMA_LOGE("Invalid Active APF Mode %d; Using 'disabled'", mode);
+		return WMI_HOST_ACTIVE_APF_DISABLED;
+	}
+}
+
+/**
+ * wma_config_active_apf_mode() - Config active APF mode in FW
+ * @wma: the WMA handle
+ * @vdev_id: the Id of the vdev for which the configuration should be applied
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_config_active_apf_mode(t_wma_handle *wma, uint8_t vdev_id)
+{
+	enum wmi_host_active_apf_mode uc_mode, mcbc_mode;
+
+	uc_mode = get_fw_active_apf_mode(wma->active_uc_apf_mode);
+	mcbc_mode = get_fw_active_apf_mode(wma->active_mc_bc_apf_mode);
+
+	WMA_LOGD("Configuring Active APF Mode UC:%d MC/BC:%d for vdev %u",
+		 uc_mode, mcbc_mode, vdev_id);
+
+	return wmi_unified_set_active_apf_mode_cmd(wma->wmi_handle, vdev_id,
+						   uc_mode, mcbc_mode);
+}
+#else /* FEATURE_WLAN_APF */
+static QDF_STATUS wma_config_active_apf_mode(t_wma_handle *wma, uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_APF */
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+/**
+ * wma_check_and_find_mcc_ap() - finds if device is operating AP
+ * in MCC mode or not
+ * @wma: wma handle.
+ * @vdev_id: vdev ID of device for which MCC has to be checked
+ *
+ * This function internally calls wma_find_mcc_ap finds if
+ * device is operating AP in MCC mode or not
+ *
+ * Return: none
+ */
+static void
+wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id)
+{
+	tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (NULL == mac_ctx) {
+		WMA_LOGE("%s: Failed to get mac_ctx", __func__);
+		return;
+	}
+	if (mac_ctx->sap.sap_channel_avoidance)
+		wma_find_mcc_ap(wma, vdev_id, false);
+}
+#else
+static inline void
+wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id)
+{}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+void wma_send_set_link_response(tp_wma_handle wma, struct wma_target_req *req)
+{
+	tpLinkStateParams params = (tpLinkStateParams) req->user_data;
+
+	wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
+}
+
+void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req)
+{
+	struct wma_txrx_node *iface;
+	struct beacon_info *bcn;
+	tpDeleteBssParams params;
+	uint8_t vdev_id;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!req) {
+		WMA_LOGE("%s req is NULL", __func__);
+		return;
+	}
+
+	vdev_id = req->vdev_id;
+	iface = &wma->interfaces[vdev_id];
+	if (!iface->handle) {
+		WMA_LOGE("%s vdev id %d is already deleted",
+			 __func__, vdev_id);
+		if (req->user_data)
+			qdf_mem_free(req->user_data);
+		req->user_data = NULL;
+		return;
+	}
+
+	params = (tpDeleteBssParams)req->user_data;
+
+	cdp_fc_vdev_flush(soc, iface->handle);
+	WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp",
+		 __func__, vdev_id);
+	cdp_fc_vdev_unpause(soc, iface->handle,
+		OL_TXQ_PAUSE_REASON_VDEV_STOP);
+	wma_vdev_clear_pause_bit(vdev_id, PAUSE_TYPE_HOST);
+	qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
+	WMA_LOGD("%s: (type %d subtype %d) BSS is stopped",
+		 __func__, iface->type, iface->sub_type);
+
+	bcn = wma->interfaces[vdev_id].beacon;
+	if (bcn) {
+		WMA_LOGD("%s: Freeing beacon struct %pK, template memory %pK",
+			 __func__, bcn, bcn->buf);
+		if (bcn->dma_mapped)
+			qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf,
+					  QDF_DMA_TO_DEVICE);
+		qdf_nbuf_free(bcn->buf);
+		qdf_mem_free(bcn);
+		wma->interfaces[vdev_id].beacon = NULL;
+	}
+
+	/* Timeout status means its WMA generated DEL BSS REQ when ADD
+	 * BSS REQ was timed out to stop the VDEV in this case no need
+	 * to send response to UMAC
+	 */
+	if (params->status == QDF_STATUS_FW_MSG_TIMEDOUT) {
+		qdf_mem_free(req->user_data);
+		req->user_data = NULL;
+		WMA_LOGE("%s: DEL BSS from ADD BSS timeout do not send resp to UMAC (vdev id %x)",
+			 __func__, vdev_id);
+	} else {
+		params->status = QDF_STATUS_SUCCESS;
+		wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP,
+					   (void *)params, 0);
+	}
+
+	if (iface->del_staself_req && iface->is_del_sta_defered) {
+		iface->is_del_sta_defered = false;
+		WMA_LOGA("scheduling defered deletion (vdev id %x)",
+			 vdev_id);
+		wma_vdev_detach(wma, iface->del_staself_req, 1);
+	}
+}
+
+void wma_send_vdev_down_bss(tp_wma_handle wma, struct wma_target_req *req)
+{
+	uint8_t vdev_id;
+#ifdef CONFIG_VDEV_SM
+	struct wma_txrx_node *iface = &wma->interfaces[req->vdev_id];
+#endif
+	if (!req) {
+		WMA_LOGE("%s req is NULL", __func__);
+		return;
+	}
+
+	vdev_id = req->vdev_id;
+
+	if (wma_send_vdev_down_to_fw(wma, vdev_id) != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to send vdev down cmd: vdev %d", vdev_id);
+	} else {
+#ifndef CONFIG_VDEV_SM
+		wma_vdev_set_mlme_state(wma, vdev_id, WLAN_VDEV_S_STOP);
+#endif
+		wma_check_and_find_mcc_ap(wma, vdev_id);
+	}
+
+#ifdef CONFIG_VDEV_SM
+	wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+				      WLAN_VDEV_SM_EV_DOWN_COMPLETE,
+				      sizeof(*req), req);
+#else
+	wma_send_del_bss_response(wma, req);
+#endif
+}
+
+QDF_STATUS
+__wma_vdev_stop_resp_handler(wmi_vdev_stopped_event_fixed_param *resp_event)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_target_req *req_msg, *del_req;
+	struct cdp_pdev *pdev;
+	void *peer = NULL;
+	uint8_t peer_id;
+	struct wma_txrx_node *iface;
+	int status = 0;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!wma) {
+		WMA_LOGE("%s: wma is null", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	iface = &wma->interfaces[resp_event->vdev_id];
+
+	/* vdev in stopped state, no more waiting for key */
+	iface->is_waiting_for_key = false;
+
+	/*
+	 * Reset the rmfEnabled as there might be MGMT action frames
+	 * sent on this vdev before the next session is established.
+	 */
+	if (iface->rmfEnabled) {
+		iface->rmfEnabled = 0;
+		WMA_LOGD(FL("Reset rmfEnabled for vdev %d"),
+			 resp_event->vdev_id);
+	}
+
+	wma_release_wakelock(&iface->vdev_stop_wakelock);
+
+	req_msg = wma_find_vdev_req(wma, resp_event->vdev_id,
+				    WMA_TARGET_REQ_TYPE_VDEV_STOP, true);
+	if (!req_msg) {
+		WMA_LOGE("%s: Failed to lookup vdev request for vdev id %d",
+			 __func__, resp_event->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE("%s: pdev is NULL", __func__);
+		status = -EINVAL;
+		wma_cleanup_target_req_param(req_msg);
+		qdf_mc_timer_stop(&req_msg->event_timeout);
+		goto free_req_msg;
+	}
+
+	qdf_mc_timer_stop(&req_msg->event_timeout);
+	if (req_msg->msg_type == WMA_DELETE_BSS_REQ) {
+		tpDeleteBssParams params =
+			(tpDeleteBssParams) req_msg->user_data;
+
+		if (iface->handle == NULL) {
+			WMA_LOGE("%s vdev id %d is already deleted",
+				 __func__, resp_event->vdev_id);
+			wma_cleanup_target_req_param(req_msg);
+			status = -EINVAL;
+			goto free_req_msg;
+		}
+
+		/* CCA is required only for sta interface */
+		if (iface->type == WMI_VDEV_TYPE_STA)
+			wma_get_cca_stats(wma, resp_event->vdev_id);
+
+		/* Clear arp and ns offload cache */
+		qdf_mem_zero(&iface->ns_offload_req,
+			sizeof(iface->ns_offload_req));
+		qdf_mem_zero(&iface->arp_offload_req,
+			sizeof(iface->arp_offload_req));
+
+		status = wma_remove_bss_peer(wma, pdev, req_msg,
+					     resp_event->vdev_id, params);
+		if (status != 0)
+			goto free_req_msg;
+
+		if (wmi_service_enabled(
+		   wma->wmi_handle,
+		   wmi_service_sync_delete_cmds))
+			goto free_req_msg;
+#ifdef CONFIG_VDEV_SM
+		wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+					      WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
+					      sizeof(*req_msg), req_msg);
+#else
+		wma_send_vdev_down_bss(wma, req_msg);
+#endif
+	} else if (req_msg->msg_type == WMA_SET_LINK_STATE) {
+		tpLinkStateParams params =
+			(tpLinkStateParams) req_msg->user_data;
+
+		peer = cdp_peer_find_by_addr(soc, pdev, params->bssid,
+					     &peer_id);
+		if (peer) {
+			WMA_LOGP(FL("Deleting peer %pM vdev id %d"),
+				 params->bssid, req_msg->vdev_id);
+			wma_remove_peer(wma, params->bssid, req_msg->vdev_id,
+				peer, false);
+			if (wmi_service_enabled(wma->wmi_handle,
+				    wmi_service_sync_delete_cmds)) {
+				WMA_LOGI(FL("Wait for the peer delete. vdev_id %d"),
+						 req_msg->vdev_id);
+				del_req = wma_fill_hold_req(wma,
+						   req_msg->vdev_id,
+						   WMA_DELETE_STA_REQ,
+						   WMA_SET_LINK_PEER_RSP,
+						   params,
+						   WMA_DELETE_STA_TIMEOUT);
+				if (!del_req) {
+					WMA_LOGE(FL("Failed to allocate request. vdev_id %d"),
+						 req_msg->vdev_id);
+					params->status = QDF_STATUS_E_NOMEM;
+				} else {
+					goto free_req_msg;
+				}
+			}
+		}
+#ifdef CONFIG_VDEV_SM
+		wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+					      WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
+					      sizeof(*req_msg), req_msg);
+#else
+		if (wma_send_vdev_down_to_fw(wma, req_msg->vdev_id) !=
+		    QDF_STATUS_SUCCESS) {
+			WMA_LOGE("Failed to send vdev down cmd: vdev %d",
+				req_msg->vdev_id);
+		}
+		wma_send_set_link_response(wma, req_msg);
+#endif
+	}
+
+free_req_msg:
+	qdf_mc_timer_destroy(&req_msg->event_timeout);
+	qdf_mem_free(req_msg);
+
+	if (status)
+		return QDF_STATUS_E_INVAL;
+	else
+		return QDF_STATUS_SUCCESS;
+}
+
+int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
+			       uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf;
+	wmi_vdev_stopped_event_fixed_param *resp_event;
+#ifdef CONFIG_VDEV_SM
+	struct wma_txrx_node *iface;
+#endif
+	int32_t status = 0;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("Invalid event buffer");
+		return -EINVAL;
+	}
+
+	resp_event = param_buf->fixed_param;
+
+	if (resp_event->vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: Invalid vdev_id %d from FW",
+				__func__, resp_event->vdev_id);
+		return -EINVAL;
+	}
+
+#ifdef CONFIG_VDEV_SM
+	iface = &wma->interfaces[resp_event->vdev_id];
+	status =  wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+						WLAN_VDEV_SM_EV_STOP_RESP,
+						sizeof(*resp_event),
+						resp_event);
+#else
+	status = __wma_vdev_stop_resp_handler(resp_event);
+#endif
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * wma_vdev_attach() - create vdev in fw
+ * @wma_handle: wma handle
+ * @self_sta_req: self sta request
+ * @generateRsp: generate response
+ *
+ * This function creates vdev in target and
+ * attach this vdev to txrx module. It also set
+ * vdev related params to fw.
+ *
+ * Return: txrx vdev handle
+ */
+struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
+				struct add_sta_self_params *self_sta_req,
+				uint8_t generateRsp)
+{
+	struct cdp_vdev *txrx_vdev_handle = NULL;
+	struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	enum wlan_op_mode txrx_vdev_type;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
+	uint32_t cfg_val;
+	QDF_STATUS ret;
+	struct mlme_ht_capabilities_info *ht_cap_info;
+	struct scheduler_msg sme_msg = { 0 };
+	struct vdev_create_params params = { 0 };
+	u_int8_t vdev_id;
+	struct sir_set_tx_rx_aggregation_size tx_rx_aggregation_size;
+	struct sir_set_tx_sw_retry_threshold tx_sw_retry_threshold;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct wlan_objmgr_peer *obj_peer;
+	struct wlan_objmgr_vdev *vdev;
+
+	qdf_mem_zero(&tx_rx_aggregation_size, sizeof(tx_rx_aggregation_size));
+	WMA_LOGD("mac %pM, vdev_id %hu, type %d, sub_type %d, nss 2g %d, 5g %d",
+		self_sta_req->self_mac_addr, self_sta_req->session_id,
+		self_sta_req->type, self_sta_req->sub_type,
+		self_sta_req->nss_2g, self_sta_req->nss_5g);
+	if (NULL == mac) {
+		WMA_LOGE("%s: Failed to get mac", __func__);
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	vdev_id = self_sta_req->session_id;
+	if (wma_is_vdev_valid(vdev_id)) {
+		WMA_LOGE("%s: vdev %d already active", __func__, vdev_id);
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	params.if_id = self_sta_req->session_id;
+	params.type = self_sta_req->type;
+	params.subtype = self_sta_req->sub_type;
+	params.nss_2g = self_sta_req->nss_2g;
+	params.nss_5g = self_sta_req->nss_5g;
+
+	/* Create a vdev in target */
+	ret = wmi_unified_vdev_create_send(wma_handle->wmi_handle,
+					   self_sta_req->self_mac_addr,
+					   &params);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("%s: Unable to add an interface for ath_dev",
+			 __func__);
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	txrx_vdev_type = wma_get_txrx_vdev_type(self_sta_req->type);
+
+	if (wlan_op_mode_unknown == txrx_vdev_type) {
+		WMA_LOGE("Failed to get txrx vdev type");
+		wmi_unified_vdev_delete_send(wma_handle->wmi_handle,
+					     self_sta_req->session_id);
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	txrx_vdev_handle = cdp_vdev_attach(soc, txrx_pdev,
+					   self_sta_req->self_mac_addr,
+					   vdev_id, txrx_vdev_type);
+
+	WMA_LOGD("vdev_id %hu, txrx_vdev_handle = %pK", vdev_id,
+		 txrx_vdev_handle);
+
+	if (!txrx_vdev_handle) {
+		WMA_LOGE("%s: cdp_vdev_attach failed", __func__);
+		status = QDF_STATUS_E_FAILURE;
+		wmi_unified_vdev_delete_send(wma_handle->wmi_handle,
+					     self_sta_req->session_id);
+		goto end;
+	}
+
+	wma_handle->interfaces[vdev_id].vdev_active = true;
+	wma_handle->interfaces[vdev_id].handle = txrx_vdev_handle;
+	wma_vdev_update_pause_bitmap(vdev_id, 0);
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc, vdev_id,
+						    WLAN_LEGACY_WMA_ID);
+	if (!vdev) {
+		WMA_LOGE(FL("vdev obj is NULL for vdev_id: %u"), vdev_id);
+		status = QDF_STATUS_E_FAILURE;
+		wma_handle->interfaces[vdev_id].vdev_active = false;
+		wmi_unified_vdev_delete_send(wma_handle->wmi_handle, vdev_id);
+		goto end;
+	}
+
+	wma_handle->interfaces[vdev_id].vdev = vdev;
+	wma_handle->interfaces[vdev_id].ptrn_match_enable =
+		wma_handle->ptrn_match_enable_all_vdev ? true : false;
+
+	wma_handle->wow.deauth_enable =
+		ucfg_pmo_is_wowlan_deauth_enabled(wma_handle->psoc);
+
+	wma_handle->wow.disassoc_enable =
+		ucfg_pmo_is_wowlan_disassoc_enabled(wma_handle->psoc);
+
+	qdf_mem_copy(wma_handle->interfaces[vdev_id].addr,
+		     self_sta_req->self_mac_addr,
+		     sizeof(wma_handle->interfaces[vdev_id].addr));
+
+	tx_rx_aggregation_size.tx_aggregation_size =
+				self_sta_req->tx_aggregation_size;
+	tx_rx_aggregation_size.rx_aggregation_size =
+				self_sta_req->rx_aggregation_size;
+	tx_rx_aggregation_size.vdev_id = self_sta_req->session_id;
+	tx_rx_aggregation_size.aggr_type = WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU;
+
+	ret = wma_set_tx_rx_aggregation_size(&tx_rx_aggregation_size);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("failed to set aggregation sizes(err=%d)", ret);
+
+	tx_rx_aggregation_size.tx_aggregation_size_be =
+				self_sta_req->tx_aggregation_size_be;
+	tx_rx_aggregation_size.tx_aggregation_size_bk =
+				self_sta_req->tx_aggregation_size_bk;
+	tx_rx_aggregation_size.tx_aggregation_size_vi =
+				self_sta_req->tx_aggregation_size_vi;
+	tx_rx_aggregation_size.tx_aggregation_size_vo =
+				self_sta_req->tx_aggregation_size_vo;
+
+	tx_sw_retry_threshold.tx_aggr_sw_retry_threshold_be =
+				self_sta_req->tx_aggr_sw_retry_threshold_be;
+	tx_sw_retry_threshold.tx_aggr_sw_retry_threshold_bk =
+				self_sta_req->tx_aggr_sw_retry_threshold_bk;
+	tx_sw_retry_threshold.tx_aggr_sw_retry_threshold_vi =
+				self_sta_req->tx_aggr_sw_retry_threshold_vi;
+	tx_sw_retry_threshold.tx_aggr_sw_retry_threshold_vo =
+				self_sta_req->tx_aggr_sw_retry_threshold_vo;
+
+	tx_sw_retry_threshold.tx_non_aggr_sw_retry_threshold_be =
+				self_sta_req->tx_non_aggr_sw_retry_threshold_be;
+	tx_sw_retry_threshold.tx_non_aggr_sw_retry_threshold_bk =
+				self_sta_req->tx_non_aggr_sw_retry_threshold_bk;
+	tx_sw_retry_threshold.tx_non_aggr_sw_retry_threshold_vi =
+				self_sta_req->tx_non_aggr_sw_retry_threshold_vi;
+	tx_sw_retry_threshold.tx_non_aggr_sw_retry_threshold_vo =
+				self_sta_req->tx_non_aggr_sw_retry_threshold_vo;
+
+	tx_sw_retry_threshold.vdev_id = self_sta_req->session_id;
+
+
+	switch (self_sta_req->type) {
+	case WMI_VDEV_TYPE_STA:
+		ret = wma_set_tx_rx_aggregation_size_per_ac(
+						&tx_rx_aggregation_size);
+		if (QDF_IS_STATUS_ERROR(ret))
+			WMA_LOGE("set aggr sizes per ac(err=%d) failed", ret);
+
+		cfg_val = mac->mlme_cfg->sta.sta_keep_alive_period;
+		wma_set_sta_keep_alive(wma_handle,
+				       self_sta_req->session_id,
+				       SIR_KEEP_ALIVE_NULL_PKT,
+				       cfg_val, NULL, NULL, NULL);
+
+		/* offload STA SA query related params to fwr */
+		if (wmi_service_enabled(wma_handle->wmi_handle,
+			wmi_service_sta_pmf_offload)) {
+			wma_set_sta_sa_query_param(wma_handle, vdev_id);
+		}
+
+		ret = wma_set_sw_retry_threshold(wma_handle,
+						 &tx_sw_retry_threshold);
+		if (QDF_IS_STATUS_ERROR(ret))
+			WMA_LOGE("failed to set retry threshold(err=%d)", ret);
+		break;
+	}
+
+	wma_handle->interfaces[vdev_id].type = self_sta_req->type;
+	wma_handle->interfaces[vdev_id].sub_type = self_sta_req->sub_type;
+	qdf_atomic_init(&wma_handle->interfaces[vdev_id].bss_status);
+
+	if (wma_vdev_uses_self_peer(self_sta_req->type,
+				    self_sta_req->sub_type)) {
+		ret = wma_create_peer(wma_handle, txrx_pdev, txrx_vdev_handle,
+				      self_sta_req->self_mac_addr,
+				      WMI_PEER_TYPE_DEFAULT,
+				      self_sta_req->session_id, false);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			WMA_LOGE("%s: Failed to create peer", __func__);
+			status = QDF_STATUS_E_FAILURE;
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+			wmi_unified_vdev_delete_send(wma_handle->wmi_handle,
+						     self_sta_req->session_id);
+			wma_handle->interfaces[vdev_id].vdev_active = false;
+			wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
+			wma_handle->interfaces[vdev_id].vdev = NULL;
+			goto end;
+		}
+	} else if (self_sta_req->type == WMI_VDEV_TYPE_STA) {
+		obj_peer = wma_create_objmgr_peer(wma_handle, vdev_id,
+						  self_sta_req->self_mac_addr,
+						  WMI_PEER_TYPE_DEFAULT);
+		if (!obj_peer) {
+			WMA_LOGE("%s: Failed to create obj mgr peer for self sta",
+				 __func__);
+			status = QDF_STATUS_E_FAILURE;
+			wmi_unified_vdev_delete_send(wma_handle->wmi_handle,
+						     self_sta_req->session_id);
+			wma_handle->interfaces[vdev_id].vdev_active = false;
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+			wma_handle->interfaces[vdev_id].vdev = NULL;
+			wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
+			goto end;
+		}
+	}
+
+	WMA_LOGD("Setting WMI_VDEV_PARAM_DISCONNECT_TH: %d",
+		 self_sta_req->pkt_err_disconn_th);
+	ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
+				 WMI_VDEV_PARAM_DISCONNECT_TH,
+				 self_sta_req->pkt_err_disconn_th);
+	if (ret)
+		WMA_LOGE("Failed to set WMI_VDEV_PARAM_DISCONNECT_TH");
+
+	ret = wma_vdev_set_param(wma_handle->wmi_handle,
+				self_sta_req->session_id,
+				WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE,
+				mac->roam.configParam.mcc_rts_cts_prot_enable);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Failed to set WMI VDEV MCC_RTSCTS_PROTECTION_ENABLE");
+
+	ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE,
+			mac->roam.configParam.mcc_bcast_prob_resp_enable);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Failed to set WMI VDEV MCC_BROADCAST_PROBE_ENABLE");
+
+	if (wlan_mlme_get_rts_threshold(mac->psoc,
+					&cfg_val) ==
+					QDF_STATUS_SUCCESS) {
+		ret = wma_vdev_set_param(wma_handle->wmi_handle,
+					self_sta_req->session_id,
+					WMI_VDEV_PARAM_RTS_THRESHOLD,
+					cfg_val);
+		if (QDF_IS_STATUS_ERROR(ret))
+			WMA_LOGE("Failed to set WMI_VDEV_PARAM_RTS_THRESHOLD");
+	} else {
+		WMA_LOGE("Fail to get val for rts threshold, leave unchanged");
+	}
+
+	if (wlan_mlme_get_frag_threshold(mac->psoc,
+					 &cfg_val) ==
+					 QDF_STATUS_SUCCESS) {
+		ret = wma_vdev_set_param(wma_handle->wmi_handle,
+					self_sta_req->session_id,
+					WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
+					cfg_val);
+		if (QDF_IS_STATUS_ERROR(ret))
+			WMA_LOGE("Failed to set WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD");
+	} else {
+		WMA_LOGE("Fail to get val for frag threshold, leave unchanged");
+	}
+
+	ht_cap_info = &mac->mlme_cfg->ht_caps.ht_cap_info;
+
+	ret = wma_vdev_set_param(wma_handle->wmi_handle,
+				 self_sta_req->session_id,
+				 WMI_VDEV_PARAM_TX_STBC,
+				 ht_cap_info->tx_stbc);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Failed to set WMI_VDEV_PARAM_TX_STBC");
+
+	wma_set_vdev_mgmt_rate(wma_handle, self_sta_req->session_id);
+
+	/* Initialize roaming offload state */
+	if ((self_sta_req->type == WMI_VDEV_TYPE_STA) &&
+	    (self_sta_req->sub_type == 0)) {
+		wma_handle->roam_offload_enabled = true;
+		ret = wma_vdev_set_param(wma_handle->wmi_handle,
+					self_sta_req->session_id,
+					WMI_VDEV_PARAM_ROAM_FW_OFFLOAD,
+					(WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG |
+					WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG));
+		if (QDF_IS_STATUS_ERROR(ret))
+			WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD");
+
+		/* Pass down enable/disable bcast probe rsp to FW */
+		ret = wma_vdev_set_param(
+				wma_handle->wmi_handle,
+				self_sta_req->session_id,
+				WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE,
+				self_sta_req->enable_bcast_probe_rsp);
+		if (QDF_IS_STATUS_ERROR(ret))
+			WMA_LOGE("Failed to set WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE");
+
+		/* Pass down the FILS max channel guard time to FW */
+		ret = wma_vdev_set_param(
+				wma_handle->wmi_handle,
+				self_sta_req->session_id,
+				WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME,
+				self_sta_req->fils_max_chan_guard_time);
+		if (QDF_IS_STATUS_ERROR(ret))
+			WMA_LOGE("Failed to set WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME");
+
+		/* Pass down the Probe Request tx delay(in ms) to FW */
+		ret = wma_vdev_set_param(
+				wma_handle->wmi_handle,
+				self_sta_req->session_id,
+				WMI_VDEV_PARAM_PROBE_DELAY,
+				PROBE_REQ_TX_DELAY);
+		if (QDF_IS_STATUS_ERROR(ret))
+			WMA_LOGE("Failed to set WMI_VDEV_PARAM_PROBE_DELAY");
+
+		/* Pass down the probe request tx time gap(in ms) to FW */
+		ret = wma_vdev_set_param(
+				wma_handle->wmi_handle,
+				self_sta_req->session_id,
+				WMI_VDEV_PARAM_REPEAT_PROBE_TIME,
+				PROBE_REQ_TX_TIME_GAP);
+		if (QDF_IS_STATUS_ERROR(ret))
+			WMA_LOGE("Failed to set WMI_VDEV_PARAM_REPEAT_PROBE_TIME");
+	}
+
+	if ((self_sta_req->type == WMI_VDEV_TYPE_STA ||
+	     self_sta_req->type == WMI_VDEV_TYPE_AP) &&
+	    self_sta_req->sub_type == 0) {
+		ret = wma_vdev_set_param(wma_handle->wmi_handle,
+				     self_sta_req->session_id,
+				     WMI_VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES,
+				     self_sta_req->oce_feature_bitmap);
+		if (QDF_IS_STATUS_ERROR(ret))
+			WMA_LOGE("Failed to set WMI_VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES");
+	}
+
+	/* Initialize BMISS parameters */
+	if ((self_sta_req->type == WMI_VDEV_TYPE_STA) &&
+	    (self_sta_req->sub_type == 0))
+		wma_roam_scan_bmiss_cnt(wma_handle,
+		mac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt,
+		mac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt,
+		self_sta_req->session_id);
+
+	if (wlan_cfg_get_int(mac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED,
+			     &cfg_val) == QDF_STATUS_SUCCESS) {
+		WMA_LOGD("%s: setting ini value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED: %d",
+			__func__, cfg_val);
+		ret = wma_set_enable_disable_mcc_adaptive_scheduler(cfg_val);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			WMA_LOGE("Failed to set WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED");
+		}
+	} else {
+		WMA_LOGE("Failed to get value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, leaving unchanged");
+	}
+
+	if (self_sta_req->type == WMI_VDEV_TYPE_STA) {
+		ret = wma_config_active_apf_mode(wma_handle,
+						 self_sta_req->session_id);
+		if (QDF_IS_STATUS_ERROR(ret))
+			WMA_LOGE("Failed to configure active APF mode");
+	}
+
+end:
+	self_sta_req->status = status;
+
+#ifdef QCA_IBSS_SUPPORT
+	if (generateRsp)
+#endif
+	{
+		sme_msg.type = eWNI_SME_ADD_STA_SELF_RSP;
+		sme_msg.bodyptr = self_sta_req;
+		sme_msg.bodyval = 0;
+
+		status = scheduler_post_message(QDF_MODULE_ID_WMA,
+						QDF_MODULE_ID_SME,
+						QDF_MODULE_ID_SME, &sme_msg);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			WMA_LOGE("Failed to post eWNI_SME_ADD_STA_SELF_RSP");
+			qdf_mem_free(self_sta_req);
+		}
+	}
+	return txrx_vdev_handle;
+}
+
+uint32_t wma_get_bcn_rate_code(uint16_t rate)
+{
+	/* rate in multiples of 100 Kbps */
+	switch (rate) {
+	case WMA_BEACON_TX_RATE_1_M:
+		return WMI_BCN_TX_RATE_CODE_1_M;
+	case WMA_BEACON_TX_RATE_2_M:
+		return WMI_BCN_TX_RATE_CODE_2_M;
+	case WMA_BEACON_TX_RATE_5_5_M:
+		return WMI_BCN_TX_RATE_CODE_5_5_M;
+	case WMA_BEACON_TX_RATE_11_M:
+		return WMI_BCN_TX_RATE_CODE_11M;
+	case WMA_BEACON_TX_RATE_6_M:
+		return WMI_BCN_TX_RATE_CODE_6_M;
+	case WMA_BEACON_TX_RATE_9_M:
+		return WMI_BCN_TX_RATE_CODE_9_M;
+	case WMA_BEACON_TX_RATE_12_M:
+		return WMI_BCN_TX_RATE_CODE_12_M;
+	case WMA_BEACON_TX_RATE_18_M:
+		return WMI_BCN_TX_RATE_CODE_18_M;
+	case WMA_BEACON_TX_RATE_24_M:
+		return WMI_BCN_TX_RATE_CODE_24_M;
+	case WMA_BEACON_TX_RATE_36_M:
+		return WMI_BCN_TX_RATE_CODE_36_M;
+	case WMA_BEACON_TX_RATE_48_M:
+		return WMI_BCN_TX_RATE_CODE_48_M;
+	case WMA_BEACON_TX_RATE_54_M:
+		return WMI_BCN_TX_RATE_CODE_54_M;
+	default:
+		return WMI_BCN_TX_RATE_CODE_1_M;
+	}
+}
+
+/**
+ * wma_vdev_start() - send vdev start request to fw
+ * @wma: wma handle
+ * @req: vdev start params
+ * @isRestart: isRestart flag
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_vdev_start(tp_wma_handle wma,
+			  struct wma_vdev_start_req *req, bool isRestart)
+{
+	struct vdev_start_params params = { 0 };
+	wmi_vdev_start_request_cmd_fixed_param *cmd;
+	struct wma_txrx_node *intr = wma->interfaces;
+	tpAniSirGlobal mac_ctx = NULL;
+	uint32_t temp_ssid_len = 0;
+	uint32_t temp_flags = 0;
+	uint32_t temp_chan_info = 0;
+	uint32_t temp_reg_info_1 = 0;
+	uint32_t temp_reg_info_2 = 0;
+	uint16_t bw_val;
+	struct wma_txrx_node *iface = &wma->interfaces[req->vdev_id];
+	struct wma_target_req *req_msg;
+	uint32_t chan_mode;
+	enum phy_ch_width ch_width;
+
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (mac_ctx == NULL) {
+		WMA_LOGE("%s: vdev start failed as mac_ctx is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (req->chan == 0) {
+		WMA_LOGE("%s: invalid channel: %d", __func__, req->chan);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	params.band_center_freq1 = cds_chan_to_freq(req->chan);
+	ch_width = req->chan_width;
+	bw_val = wlan_reg_get_bw_value(req->chan_width);
+	if (20 < bw_val) {
+		if (req->ch_center_freq_seg0) {
+			params.band_center_freq1 =
+				cds_chan_to_freq(req->ch_center_freq_seg0);
+		} else {
+			WMA_LOGE("%s: invalid cntr_freq for bw %d, drop to 20",
+					__func__, bw_val);
+			params.band_center_freq1 = cds_chan_to_freq(req->chan);
+			ch_width = CH_WIDTH_20MHZ;
+			bw_val = 20;
+		}
+	}
+	if (80 < bw_val) {
+		if (req->ch_center_freq_seg1) {
+			params.band_center_freq2 =
+				cds_chan_to_freq(req->ch_center_freq_seg1);
+		} else {
+			WMA_LOGE("%s: invalid cntr_freq for bw %d, drop to 80",
+					__func__, bw_val);
+			params.band_center_freq2 = 0;
+			ch_width = CH_WIDTH_80MHZ;
+		}
+	} else {
+		params.band_center_freq2 = 0;
+	}
+	chan_mode = wma_chan_phy_mode(req->chan, ch_width,
+				      req->dot11_mode);
+
+	if (chan_mode == MODE_UNKNOWN) {
+		WMA_LOGE("%s: invalid phy mode!", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!params.band_center_freq1) {
+		WMA_LOGE("%s: invalid center freq1", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (((ch_width == CH_WIDTH_160MHZ) || (ch_width == CH_WIDTH_80P80MHZ))
+				&& !params.band_center_freq2) {
+		WMA_LOGE("%s: invalid center freq2 for 160MHz", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Fill channel info */
+	params.chan_freq = cds_chan_to_freq(req->chan);
+	params.chan_mode = chan_mode;
+
+	/* For Rome, only supports LFR2, not LFR3, for reassoc, need send vdev
+	 * start cmd to F/W while vdev started first, then send reassoc frame
+	 */
+	if (!isRestart &&
+	    qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED &&
+	    wmi_service_enabled(wma->wmi_handle, wmi_service_roam_ho_offload)) {
+		req_msg = wma_find_vdev_req(wma, req->vdev_id,
+					    WMA_TARGET_REQ_TYPE_VDEV_STOP,
+					    false);
+		if (!req_msg || req_msg->msg_type != WMA_DELETE_BSS_REQ) {
+			WMA_LOGE("BSS is in started state before vdev start");
+			cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
+		}
+	}
+
+	WMA_LOGD("%s: Enter isRestart=%d vdev=%d", __func__, isRestart,
+		 req->vdev_id);
+	params.vdev_id = req->vdev_id;
+
+	intr[params.vdev_id].chanmode = params.chan_mode;
+	intr[params.vdev_id].ht_capable = req->ht_capable;
+	intr[params.vdev_id].vht_capable = req->vht_capable;
+	intr[params.vdev_id].config.gtx_info.gtxRTMask[0] =
+		CFG_TGT_DEFAULT_GTX_HT_MASK;
+	intr[params.vdev_id].config.gtx_info.gtxRTMask[1] =
+		CFG_TGT_DEFAULT_GTX_VHT_MASK;
+
+	intr[params.vdev_id].config.gtx_info.gtxUsrcfg =
+		mac_ctx->mlme_cfg->sta.tgt_gtx_usr_cfg;
+
+	intr[params.vdev_id].config.gtx_info.gtxPERThreshold =
+		CFG_TGT_DEFAULT_GTX_PER_THRESHOLD;
+	intr[params.vdev_id].config.gtx_info.gtxPERMargin =
+		CFG_TGT_DEFAULT_GTX_PER_MARGIN;
+	intr[params.vdev_id].config.gtx_info.gtxTPCstep =
+		CFG_TGT_DEFAULT_GTX_TPC_STEP;
+	intr[params.vdev_id].config.gtx_info.gtxTPCMin =
+		CFG_TGT_DEFAULT_GTX_TPC_MIN;
+	intr[params.vdev_id].config.gtx_info.gtxBWMask =
+		CFG_TGT_DEFAULT_GTX_BW_MASK;
+	intr[params.vdev_id].mhz = params.chan_freq;
+	intr[params.vdev_id].chan_width = ch_width;
+	intr[params.vdev_id].channel = req->chan;
+	wma_copy_txrxnode_he_ops(&intr[params.vdev_id], req);
+
+	temp_chan_info &= 0xffffffc0;
+	temp_chan_info |= params.chan_mode;
+
+	/* Set half or quarter rate WMI flags */
+	params.is_half_rate = req->is_half_rate;
+	params.is_quarter_rate = req->is_quarter_rate;
+
+	if (req->is_half_rate)
+		temp_chan_info |=  (1 << WMI_CHAN_FLAG_HALF_RATE);
+	else if (req->is_quarter_rate)
+		temp_chan_info |=  (1 << WMI_CHAN_FLAG_QUARTER_RATE);
+
+	/*
+	 * If the channel has DFS set, flip on radar reporting.
+	 *
+	 * It may be that this should only be done for IBSS/hostap operation
+	 * as this flag may be interpreted (at some point in the future)
+	 * by the firmware as "oh, and please do radar DETECTION."
+	 *
+	 * If that is ever the case we would insert the decision whether to
+	 * enable the firmware flag here.
+	 */
+
+	params.is_dfs = req->is_dfs;
+	params.is_restart = isRestart;
+	params.cac_duration_ms = req->cac_duration_ms;
+	params.regdomain = req->dfs_regdomain;
+	if ((QDF_GLOBAL_MONITOR_MODE != cds_get_conparam()) && req->is_dfs) {
+		temp_chan_info |=  (1 << WMI_CHAN_FLAG_DFS);
+		params.dis_hw_ack = true;
+
+		/*
+		 * If channel is DFS and operating in AP mode,
+		 * set the WMI_CHAN_FLAG_DFS flag.
+		 */
+		if (wma_is_vdev_in_ap_mode(wma, params.vdev_id) == true)
+			params.flag_dfs = WMI_CHAN_FLAG_DFS;
+	}
+
+	params.beacon_intval = req->beacon_intval;
+	params.dtim_period = req->dtim_period;
+
+	if (req->beacon_tx_rate) {
+		WMA_LOGD("%s: beacon tx rate [%hu * 100 Kbps]",
+				__func__, req->beacon_tx_rate);
+		temp_flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT;
+		/*
+		 * beacon_tx_rate is in multiples of 100 Kbps.
+		 * Convert the data rate to hw rate code.
+		 */
+		params.bcn_tx_rate_code =
+			wma_get_bcn_rate_code(req->beacon_tx_rate);
+	}
+
+	/* FIXME: Find out min, max and regulatory power levels */
+	params.max_txpow = req->max_txpow;
+	temp_reg_info_1 &= 0xff00ffff;
+	temp_reg_info_1 |= ((req->max_txpow&0xff) << 16);
+
+	temp_reg_info_2 &= 0xffff00ff;
+	temp_reg_info_2 |= ((req->max_txpow&0xff)<<8);
+
+	/* TODO: Handle regulatory class, max antenna */
+	if (!isRestart) {
+		params.beacon_intval = req->beacon_intval;
+		params.dtim_period = req->dtim_period;
+
+		/* Copy the SSID */
+		if (req->ssid.length) {
+			params.ssid.length = req->ssid.length;
+			if (req->ssid.length < sizeof(cmd->ssid.ssid))
+				temp_ssid_len = req->ssid.length;
+			else
+				temp_ssid_len = sizeof(cmd->ssid.ssid);
+			qdf_mem_copy(params.ssid.mac_ssid, req->ssid.ssId,
+				     temp_ssid_len);
+		}
+
+		params.pmf_enabled = req->pmf_enabled;
+		if (req->pmf_enabled)
+			temp_flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED;
+	}
+
+	params.hidden_ssid = req->hidden_ssid;
+	if (req->hidden_ssid)
+		temp_flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
+
+	params.num_noa_descriptors = 0;
+	params.preferred_rx_streams = req->preferred_rx_streams;
+	params.preferred_tx_streams = req->preferred_tx_streams;
+
+	wma_copy_vdev_start_he_ops(&params, req);
+
+	/* Store vdev params in SAP mode which can be used in vdev restart */
+	if (intr[req->vdev_id].type == WMI_VDEV_TYPE_AP &&
+	    intr[req->vdev_id].sub_type == 0) {
+		intr[req->vdev_id].vdev_restart_params.vdev_id = req->vdev_id;
+		intr[req->vdev_id].vdev_restart_params.ssid.ssid_len =
+			temp_ssid_len;
+		qdf_mem_copy(intr[req->vdev_id].vdev_restart_params.ssid.ssid,
+			     params.ssid.mac_ssid, temp_ssid_len);
+		intr[req->vdev_id].vdev_restart_params.flags = temp_flags;
+		intr[req->vdev_id].vdev_restart_params.requestor_id = 0;
+		intr[req->vdev_id].vdev_restart_params.disable_hw_ack =
+			params.dis_hw_ack;
+		intr[req->vdev_id].vdev_restart_params.chan.mhz =
+			params.chan_freq;
+		intr[req->vdev_id].vdev_restart_params.chan.band_center_freq1 =
+			params.band_center_freq1;
+		intr[req->vdev_id].vdev_restart_params.chan.band_center_freq2 =
+			params.band_center_freq2;
+		intr[req->vdev_id].vdev_restart_params.chan.info =
+			temp_chan_info;
+		intr[req->vdev_id].vdev_restart_params.chan.reg_info_1 =
+			temp_reg_info_1;
+		intr[req->vdev_id].vdev_restart_params.chan.reg_info_2 =
+			temp_reg_info_2;
+	}
+
+	if (isRestart) {
+#ifndef CONFIG_VDEV_SM
+		/*
+		 * Marking the VDEV UP STATUS to false
+		 * since, VDEV RESTART will do a VDEV DOWN
+		 * in the firmware.
+		 */
+		wma_vdev_set_mlme_state(wma, params.vdev_id, WLAN_VDEV_S_STOP);
+#endif
+	} else {
+		WMA_LOGD("%s, vdev_id: %d, unpausing tx_ll_queue at VDEV_START",
+			 __func__, params.vdev_id);
+		cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
+			wma->interfaces[params.vdev_id].handle,
+			0xffffffff);
+		wma_vdev_update_pause_bitmap(params.vdev_id, 0);
+	}
+
+	return wma_send_vdev_start_to_fw(wma, &params);
+}
+
+/**
+ * wma_peer_assoc_conf_handler() - peer assoc conf handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info,
+				uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_PEER_ASSOC_CONF_EVENTID_param_tlvs *param_buf;
+	wmi_peer_assoc_conf_event_fixed_param *event;
+	struct wma_target_req *req_msg;
+	uint8_t macaddr[IEEE80211_ADDR_LEN];
+	int status = 0;
+
+	WMA_LOGD(FL("Enter"));
+	param_buf = (WMI_PEER_ASSOC_CONF_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("Invalid peer assoc conf event buffer");
+		return -EINVAL;
+	}
+
+	event = param_buf->fixed_param;
+	if (!event) {
+		WMA_LOGE("Invalid peer assoc conf event buffer");
+		return -EINVAL;
+	}
+
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr);
+	WMA_LOGD(FL("peer assoc conf for vdev:%d mac=%pM"),
+		 event->vdev_id, macaddr);
+
+	req_msg = wma_find_req(wma, event->vdev_id,
+				    WMA_PEER_ASSOC_CNF_START);
+
+	if (!req_msg) {
+		WMA_LOGE(FL("Failed to lookup request message for vdev %d"),
+			 event->vdev_id);
+		return -EINVAL;
+	}
+
+	qdf_mc_timer_stop(&req_msg->event_timeout);
+
+	if (req_msg->msg_type == WMA_ADD_STA_REQ) {
+		tpAddStaParams params = (tpAddStaParams)req_msg->user_data;
+
+		if (!params) {
+			WMA_LOGE(FL("add STA params is NULL for vdev %d"),
+				 event->vdev_id);
+			status = -EINVAL;
+			goto free_req_msg;
+		}
+
+		/* peer assoc conf event means the cmd succeeds */
+		params->status = QDF_STATUS_SUCCESS;
+		WMA_LOGD(FL("Send ADD_STA_RSP: statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d"),
+			 params->staType, params->smesessionId,
+			 params->assocId, params->bssId, params->staIdx,
+			 params->status);
+		wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
+					   (void *)params, 0);
+	} else if (req_msg->msg_type == WMA_ADD_BSS_REQ) {
+		tpAddBssParams  params = (tpAddBssParams) req_msg->user_data;
+
+		if (!params) {
+			WMA_LOGE(FL("add BSS params is NULL for vdev %d"),
+				 event->vdev_id);
+			status = -EINVAL;
+			goto free_req_msg;
+		}
+
+		/* peer assoc conf event means the cmd succeeds */
+		params->status = QDF_STATUS_SUCCESS;
+		WMA_LOGD(FL("Send ADD BSS RSP: opermode: %d update_bss: %d nw_type: %d bssid: %pM staIdx %d status %d"),
+			params->operMode,
+			params->updateBss, params->nwType, params->bssId,
+			params->staContext.staIdx, params->status);
+		wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP,
+					   (void *)params, 0);
+	} else {
+		WMA_LOGE(FL("Unhandled request message type: %d"),
+		req_msg->msg_type);
+	}
+
+free_req_msg:
+	qdf_mc_timer_destroy(&req_msg->event_timeout);
+	qdf_mem_free(req_msg);
+
+	return status;
+}
+
+/**
+ * wma_vdev_delete_handler() - vdev delete response handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_vdev_delete_handler(void *handle, uint8_t *cmd_param_info,
+				uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf;
+	wmi_vdev_delete_cmd_fixed_param *event;
+	struct wma_target_req *req_msg;
+	int status = 0;
+
+	param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *)cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("Invalid vdev delete event buffer");
+		return -EINVAL;
+	}
+
+	event = (wmi_vdev_delete_cmd_fixed_param *)param_buf->fixed_param;
+	if (!event) {
+		WMA_LOGE("Invalid vdev delete event buffer");
+		return -EINVAL;
+	}
+
+	WMA_LOGD("%s Vdev delete resp vdev id %d", __func__, event->vdev_id);
+	req_msg = wma_find_vdev_req(wma, event->vdev_id,
+				WMA_TARGET_REQ_TYPE_VDEV_DEL, true);
+	if (!req_msg) {
+		WMA_LOGD(FL("Vdev delete resp is not handled! vdev id %d"),
+				event->vdev_id);
+		return -EINVAL;
+	}
+	qdf_mc_timer_stop(&req_msg->event_timeout);
+	qdf_mc_timer_destroy(&req_msg->event_timeout);
+
+	wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+
+	/* Send response to upper layers */
+	wma_vdev_detach_callback(req_msg->user_data);
+	qdf_mem_free(req_msg);
+
+	return status;
+}
+
+/**
+ * wma_peer_delete_handler() - peer delete response handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info,
+				uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf;
+	wmi_peer_delete_cmd_fixed_param *event;
+	struct wma_target_req *req_msg;
+	tDeleteStaParams *del_sta;
+	uint8_t macaddr[IEEE80211_ADDR_LEN];
+	int status = 0;
+
+	param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("Invalid vdev delete event buffer");
+		return -EINVAL;
+	}
+
+	event = (wmi_peer_delete_cmd_fixed_param *)param_buf->fixed_param;
+	if (!event) {
+		WMA_LOGE("Invalid vdev delete event buffer");
+		return -EINVAL;
+	}
+
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr);
+	WMA_LOGD(FL("Peer Delete Response, vdev %d Peer %pM"),
+			event->vdev_id, macaddr);
+	wlan_roam_debug_log(event->vdev_id, DEBUG_PEER_DELETE_RESP,
+			    DEBUG_INVALID_PEER_ID, macaddr, NULL, 0, 0);
+	req_msg = wma_find_remove_req_msgtype(wma, event->vdev_id,
+					WMA_DELETE_STA_REQ);
+	if (!req_msg) {
+		WMA_LOGD("Peer Delete response is not handled");
+		return -EINVAL;
+	}
+
+	wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+
+	/* Cleanup timeout handler */
+	qdf_mc_timer_stop(&req_msg->event_timeout);
+	qdf_mc_timer_destroy(&req_msg->event_timeout);
+
+	if (req_msg->type == WMA_DELETE_STA_RSP_START) {
+		del_sta = req_msg->user_data;
+		if (del_sta->respReqd) {
+			WMA_LOGD(FL("Sending peer del rsp to umac"));
+			wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
+				(void *)del_sta, QDF_STATUS_SUCCESS);
+		} else {
+			qdf_mem_free(del_sta);
+		}
+	} else if (req_msg->type == WMA_DEL_P2P_SELF_STA_RSP_START) {
+		struct del_sta_self_rsp_params *data;
+
+		data = (struct del_sta_self_rsp_params *)req_msg->user_data;
+		WMA_LOGD(FL("Calling vdev detach handler"));
+		wma_handle_vdev_detach(wma, data->self_sta_param,
+				data->generate_rsp);
+		qdf_mem_free(data);
+	} else if (req_msg->type == WMA_SET_LINK_PEER_RSP) {
+#ifdef CONFIG_VDEV_SM
+		struct wma_txrx_node *iface =
+					&wma->interfaces[req_msg->vdev_id];
+
+		wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+					      WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
+					      sizeof(*req_msg), req_msg);
+#else
+		if (wma_send_vdev_down_to_fw(wma, req_msg->vdev_id) !=
+		    QDF_STATUS_SUCCESS) {
+			WMA_LOGE("Failed to send vdev down cmd: vdev %d",
+					req_msg->vdev_id);
+		}
+		wma_send_set_link_response(wma, req_msg);
+#endif
+	} else if (req_msg->type == WMA_DELETE_PEER_RSP) {
+#ifdef CONFIG_VDEV_SM
+		struct wma_txrx_node *iface =
+					&wma->interfaces[req_msg->vdev_id];
+
+		wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+					      WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
+					      sizeof(*req_msg), req_msg);
+#else
+		wma_send_vdev_down_bss(wma, req_msg);
+#endif
+
+	}
+	qdf_mem_free(req_msg);
+	return status;
+}
+
+static void wma_trigger_recovery_assert_on_fw_timeout(uint16_t wma_msg)
+{
+	WMA_LOGE("%s timed out, triggering recovery",
+		 mac_trace_get_wma_msg_string(wma_msg));
+	cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
+}
+
+static inline bool wma_crash_on_fw_timeout(bool crash_enabled)
+{
+	/* Discard FW timeouts and dont crash during SSR */
+	if (cds_is_driver_recovering())
+		return false;
+
+	/* Firmware is down send failure response */
+	if (cds_is_fw_down())
+		return false;
+
+	if (cds_is_driver_unloading())
+		return false;
+
+	return crash_enabled;
+}
+
+/**
+ * wma_hold_req_timer() - wma hold request timeout function
+ * @data: target request params
+ *
+ * Return: none
+ */
+void wma_hold_req_timer(void *data)
+{
+	tp_wma_handle wma;
+	struct wma_target_req *tgt_req = (struct wma_target_req *)data;
+	struct wma_target_req *msg;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (NULL == wma) {
+		WMA_LOGE(FL("Failed to get wma"));
+		return;
+	}
+
+	WMA_LOGA(FL("request %d is timed out for vdev_id - %d"),
+		 tgt_req->msg_type, tgt_req->vdev_id);
+	msg = wma_find_req(wma, tgt_req->vdev_id, tgt_req->type);
+
+	if (!msg) {
+		WMA_LOGE(FL("Failed to lookup request message - %d"),
+			 tgt_req->msg_type);
+		/*
+		 * if find request failed, then firmware rsp should have
+		 * consumed the buffer. Do not free.
+		 */
+		return;
+	}
+
+	if (tgt_req->msg_type == WMA_ADD_STA_REQ) {
+		tpAddStaParams params = (tpAddStaParams) tgt_req->user_data;
+
+		params->status = QDF_STATUS_E_TIMEOUT;
+		WMA_LOGA(FL("WMA_ADD_STA_REQ timed out"));
+		WMA_LOGD(FL("Sending add sta rsp to umac (mac:%pM, status:%d)"),
+			 params->staMac, params->status);
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+				WMA_ADD_STA_REQ);
+		} else {
+			wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
+						   (void *)params, 0);
+		}
+	} else if (tgt_req->msg_type == WMA_ADD_BSS_REQ) {
+		tpAddBssParams  params = (tpAddBssParams) tgt_req->user_data;
+
+		params->status = QDF_STATUS_E_TIMEOUT;
+		WMA_LOGA(FL("WMA_ADD_BSS_REQ timed out"));
+		WMA_LOGD(FL("Sending add bss rsp to umac (mac:%pM, status:%d)"),
+			params->selfMacAddr, params->status);
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+				WMA_ADD_BSS_REQ);
+		} else {
+			wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP,
+						   (void *)params, 0);
+		}
+	} else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
+		(tgt_req->type == WMA_DELETE_STA_RSP_START)) {
+		tpDeleteStaParams params =
+				(tpDeleteStaParams) tgt_req->user_data;
+		params->status = QDF_STATUS_E_TIMEOUT;
+		WMA_LOGE(FL("WMA_DEL_STA_REQ timed out"));
+		WMA_LOGE(FL("Sending del sta rsp to umac (mac:%pM, status:%d)"),
+			 params->staMac, params->status);
+
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+				WMA_DELETE_STA_REQ);
+		} else {
+			/*
+			 * Assert in development build only.
+			 * Send response in production builds.
+			 */
+			QDF_ASSERT(0);
+			wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
+				    (void *)params, 0);
+		}
+	} else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
+		(tgt_req->type == WMA_DEL_P2P_SELF_STA_RSP_START)) {
+		struct del_sta_self_rsp_params *del_sta;
+
+		del_sta = (struct del_sta_self_rsp_params *)tgt_req->user_data;
+
+		del_sta->self_sta_param->status = QDF_STATUS_E_TIMEOUT;
+		WMA_LOGA(FL("wma delete sta p2p request timed out"));
+
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+				WMA_DELETE_STA_REQ);
+		} else {
+			wma_handle_vdev_detach(wma, del_sta->self_sta_param,
+					       del_sta->generate_rsp);
+		}
+		qdf_mem_free(tgt_req->user_data);
+	} else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
+			(tgt_req->type == WMA_SET_LINK_PEER_RSP)) {
+		tpLinkStateParams params =
+			(tpLinkStateParams) tgt_req->user_data;
+
+		params->status = false;
+		WMA_LOGA(FL("wma delete peer for set link timed out"));
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+				WMA_DELETE_STA_REQ);
+		} else {
+			wma_send_msg(wma, WMA_SET_LINK_STATE_RSP,
+					params, 0);
+		}
+	} else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
+			(tgt_req->type == WMA_DELETE_PEER_RSP)) {
+		tpDeleteBssParams params =
+			(tpDeleteBssParams) tgt_req->user_data;
+
+		params->status = QDF_STATUS_E_TIMEOUT;
+		WMA_LOGE(FL("wma delete peer for del bss req timed out"));
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+				WMA_DELETE_STA_REQ);
+		} else {
+			wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP,
+						   params, 0);
+		}
+	} else if ((tgt_req->msg_type == SIR_HAL_PDEV_SET_HW_MODE) &&
+			(tgt_req->type == WMA_PDEV_SET_HW_MODE_RESP)) {
+		struct sir_set_hw_mode_resp *params =
+			qdf_mem_malloc(sizeof(*params));
+
+		WMA_LOGE(FL("set hw mode req timed out"));
+
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+						SIR_HAL_PDEV_SET_HW_MODE);
+		} else if (params) {
+			params->status = SET_HW_MODE_STATUS_ECANCELED;
+			params->cfgd_hw_mode_index = 0;
+			params->num_vdev_mac_entries = 0;
+			wma_send_msg_high_priority(wma,
+				SIR_HAL_PDEV_SET_HW_MODE_RESP, params, 0);
+		}
+	} else if ((tgt_req->msg_type == SIR_HAL_PDEV_DUAL_MAC_CFG_REQ) &&
+			(tgt_req->type == WMA_PDEV_MAC_CFG_RESP)) {
+		struct sir_dual_mac_config_resp *resp =
+						qdf_mem_malloc(sizeof(*resp));
+
+		WMA_LOGE(FL("set dual mac config timeout"));
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+						SIR_HAL_PDEV_DUAL_MAC_CFG_REQ);
+		} else if (resp) {
+			resp->status = SET_HW_MODE_STATUS_ECANCELED;
+			wma_send_msg_high_priority(wma,
+						   SIR_HAL_PDEV_MAC_CFG_RESP,
+						   resp, 0);
+		}
+	} else {
+		WMA_LOGE(FL("Unhandled timeout for msg_type:%d and type:%d"),
+				tgt_req->msg_type, tgt_req->type);
+		QDF_BUG(0);
+	}
+	qdf_mc_timer_destroy(&tgt_req->event_timeout);
+	qdf_mem_free(tgt_req);
+}
+
+/**
+ * wma_fill_hold_req() - fill wma request
+ * @wma: wma handle
+ * @msg_type: message type
+ * @type: request type
+ * @params: request params
+ * @timeout: timeout value
+ *
+ * Return: wma_target_req ptr
+ */
+struct wma_target_req *wma_fill_hold_req(tp_wma_handle wma,
+					 uint8_t vdev_id,
+					 uint32_t msg_type, uint8_t type,
+					 void *params, uint32_t timeout)
+{
+	struct wma_target_req *req;
+	QDF_STATUS status;
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return NULL;
+
+	WMA_LOGD(FL("vdev_id %d msg %d type %d"), vdev_id, msg_type, type);
+	qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
+	req->vdev_id = vdev_id;
+	req->msg_type = msg_type;
+	req->type = type;
+	req->user_data = params;
+	status = qdf_list_insert_back(&wma->wma_hold_req_queue, &req->node);
+	if (QDF_STATUS_SUCCESS != status) {
+		qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
+		WMA_LOGE(FL("Failed add request in queue"));
+		qdf_mem_free(req);
+		return NULL;
+	}
+	qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
+	qdf_mc_timer_init(&req->event_timeout, QDF_TIMER_TYPE_SW,
+			  wma_hold_req_timer, req);
+	qdf_mc_timer_start(&req->event_timeout, timeout);
+	return req;
+}
+
+/**
+ * wma_remove_req() - remove request
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @type: type
+ *
+ * Return: none
+ */
+void wma_remove_req(tp_wma_handle wma, uint8_t vdev_id,
+		    uint8_t type)
+{
+	struct wma_target_req *req_msg;
+
+	WMA_LOGD(FL("Remove req for vdev: %d type: %d"), vdev_id, type);
+	req_msg = wma_find_req(wma, vdev_id, type);
+	if (!req_msg) {
+		WMA_LOGE(FL("target req not found for vdev: %d type: %d"),
+			 vdev_id, type);
+		return;
+	}
+
+	qdf_mc_timer_stop(&req_msg->event_timeout);
+	qdf_mc_timer_destroy(&req_msg->event_timeout);
+	qdf_mem_free(req_msg);
+}
+
+/**
+ * wma_vdev_resp_timer() - wma response timeout function
+ * @data: target request params
+ *
+ * Return: none
+ */
+void wma_vdev_resp_timer(void *data)
+{
+	tp_wma_handle wma;
+	struct wma_target_req *tgt_req = (struct wma_target_req *)data;
+	struct cdp_pdev *pdev;
+	struct wma_target_req *msg;
+	uint8_t peer_id;
+	int status;
+	void *peer;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct wma_txrx_node *iface;
+	struct del_sta_self_params *del_sta_self_params;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	tpAniSirGlobal mac_ctx;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: Failed to get wma", __func__);
+		wma_cleanup_target_req_param(tgt_req);
+		goto free_tgt_req;
+	}
+
+	WMA_LOGA("%s: request %d is timed out for vdev_id - %d", __func__,
+		 tgt_req->msg_type, tgt_req->vdev_id);
+	msg = wma_find_vdev_req(wma, tgt_req->vdev_id, tgt_req->type, true);
+
+	if (!msg) {
+		WMA_LOGE("%s: Failed to lookup request message - %d",
+			 __func__, tgt_req->msg_type);
+		return;
+	}
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		wma_cleanup_target_req_param(tgt_req);
+		qdf_mc_timer_stop(&tgt_req->event_timeout);
+		goto free_tgt_req;
+	}
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac_ctx) {
+		WMA_LOGE("%s: Failed to get mac_ctx", __func__);
+		wma_cleanup_target_req_param(tgt_req);
+		goto free_tgt_req;
+	}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+	if (tgt_req->msg_type == WMA_CHNL_SWITCH_REQ) {
+		tpSwitchChannelParams params =
+			(tpSwitchChannelParams) tgt_req->user_data;
+		params->status = QDF_STATUS_E_TIMEOUT;
+		WMA_LOGA("%s: WMA_SWITCH_CHANNEL_REQ timedout", __func__);
+
+		/*
+		 * Trigger host crash if the flag is set or if the timeout
+		 * is not due to fw down
+		 */
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+				WMA_CHNL_SWITCH_REQ);
+		} else {
+#ifdef CONFIG_VDEV_SM
+			iface = &wma->interfaces[tgt_req->vdev_id];
+
+			wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+						   WLAN_VDEV_SM_EV_RESTART_RESP,
+						   sizeof(*params), params);
+#else
+			wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP,
+				    (void *)params, 0);
+#endif
+		}
+#ifndef CONFIG_VDEV_SM
+		if (wma->interfaces[tgt_req->vdev_id].is_channel_switch) {
+			wma->interfaces[tgt_req->vdev_id].is_channel_switch =
+				false;
+		}
+#endif
+	} else if (tgt_req->msg_type == WMA_DELETE_BSS_REQ) {
+		tpDeleteBssParams params =
+			(tpDeleteBssParams) tgt_req->user_data;
+		struct beacon_info *bcn;
+
+		if (tgt_req->vdev_id >= wma->max_bssid) {
+			WMA_LOGE("%s: Invalid vdev_id %d", __func__,
+				 tgt_req->vdev_id);
+			wma_cleanup_target_req_param(tgt_req);
+			qdf_mc_timer_stop(&tgt_req->event_timeout);
+			goto free_tgt_req;
+		}
+
+		iface = &wma->interfaces[tgt_req->vdev_id];
+		if (iface->handle == NULL) {
+			WMA_LOGE("%s vdev id %d is already deleted",
+				 __func__, tgt_req->vdev_id);
+			wma_cleanup_target_req_param(tgt_req);
+			qdf_mc_timer_stop(&tgt_req->event_timeout);
+			goto free_tgt_req;
+		}
+		/*
+		 * Trigger host crash if the flag is set or if the timeout
+		 * is not due to fw down
+		 */
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+				WMA_DELETE_BSS_REQ);
+			wma_cleanup_target_req_param(tgt_req);
+			goto free_tgt_req;
+		}
+
+		status = wma_remove_bss_peer(wma, pdev, tgt_req,
+					     tgt_req->vdev_id, params);
+		if (status != 0) {
+			wma_cleanup_target_req_param(tgt_req);
+			goto free_tgt_req;
+		}
+
+		if (wmi_service_enabled(
+		   wma->wmi_handle,
+		   wmi_service_sync_delete_cmds)) {
+			wma_cleanup_target_req_param(tgt_req);
+			goto free_tgt_req;
+		}
+
+		if (wma_send_vdev_down_to_fw(wma, tgt_req->vdev_id) !=
+		    QDF_STATUS_SUCCESS) {
+			WMA_LOGE("Failed to send vdev down cmd: vdev %d",
+				 tgt_req->vdev_id);
+		} else {
+#ifndef CONFIG_VDEV_SM
+			wma_vdev_set_mlme_state(wma, tgt_req->vdev_id,
+				WLAN_VDEV_S_STOP);
+#endif
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+		if (mac_ctx->sap.sap_channel_avoidance)
+			wma_find_mcc_ap(wma, tgt_req->vdev_id, false);
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+		}
+		cdp_fc_vdev_flush(soc, iface->handle);
+		WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for WDA_DELETE_BSS_REQ timeout",
+			 __func__, tgt_req->vdev_id);
+		cdp_fc_vdev_unpause(soc, iface->handle,
+				     OL_TXQ_PAUSE_REASON_VDEV_STOP);
+		wma_vdev_clear_pause_bit(tgt_req->vdev_id, PAUSE_TYPE_HOST);
+		qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
+		WMA_LOGD("%s: (type %d subtype %d) BSS is stopped",
+			 __func__, iface->type, iface->sub_type);
+
+		bcn = wma->interfaces[tgt_req->vdev_id].beacon;
+
+		if (bcn) {
+			WMA_LOGD("%s: Freeing beacon struct %pK, template memory %pK",
+				 __func__, bcn, bcn->buf);
+			if (bcn->dma_mapped)
+				qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf,
+						      QDF_DMA_TO_DEVICE);
+			qdf_nbuf_free(bcn->buf);
+			qdf_mem_free(bcn);
+			wma->interfaces[tgt_req->vdev_id].beacon = NULL;
+		}
+		params->status = QDF_STATUS_E_TIMEOUT;
+		WMA_LOGA("%s: WMA_DELETE_BSS_REQ timedout", __func__);
+		wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP,
+					   (void *)params, 0);
+		if (iface->del_staself_req && iface->is_del_sta_defered) {
+			iface->is_del_sta_defered = false;
+			WMA_LOGA("scheduling defered deletion(vdev id %x)",
+				 tgt_req->vdev_id);
+			wma_vdev_detach(wma, iface->del_staself_req, 1);
+		}
+	} else if (tgt_req->msg_type == WMA_DEL_STA_SELF_REQ) {
+		iface = (struct wma_txrx_node *)tgt_req->user_data;
+		del_sta_self_params =
+			(struct del_sta_self_params *) iface->del_staself_req;
+
+		if (wmi_service_enabled(wma->wmi_handle,
+					   wmi_service_sync_delete_cmds)) {
+			wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+		}
+		del_sta_self_params->status = QDF_STATUS_E_TIMEOUT;
+
+		WMA_LOGA("%s: WMA_DEL_STA_SELF_REQ timedout", __func__);
+
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+				WMA_DEL_STA_SELF_REQ);
+		} else if (!cds_is_driver_unloading() &&
+			   (cds_is_fw_down() || cds_is_driver_recovering())) {
+			qdf_mem_free(iface->del_staself_req);
+			iface->del_staself_req = NULL;
+		} else {
+			wma_send_del_sta_self_resp(iface->del_staself_req);
+			iface->del_staself_req = NULL;
+		}
+
+		wma_vdev_deinit(iface);
+		qdf_mem_zero(iface, sizeof(*iface));
+		wma_vdev_init(iface);
+	} else if (tgt_req->msg_type == WMA_ADD_BSS_REQ) {
+		tpAddBssParams params = (tpAddBssParams) tgt_req->user_data;
+
+		params->status = QDF_STATUS_E_TIMEOUT;
+		WMA_LOGA("%s: WMA_ADD_BSS_REQ timedout", __func__);
+		WMA_LOGD("%s: bssid %pM vdev_id %d", __func__, params->bssId,
+			 tgt_req->vdev_id);
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+				WMA_ADD_BSS_REQ);
+		} else {
+#ifdef CONFIG_VDEV_SM
+			iface = &wma->interfaces[tgt_req->vdev_id];
+			wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+						      WLAN_VDEV_SM_EV_DOWN,
+						      sizeof(*params), params);
+#else
+			if (wma_send_vdev_stop_to_fw(wma, tgt_req->vdev_id))
+				WMA_LOGE("%s: Failed to send vdev stop to fw",
+					 __func__);
+
+			wma_remove_peer_on_add_bss_failure(params);
+
+			wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP,
+						   (void *)params, 0);
+#endif
+		}
+		goto free_tgt_req;
+
+	} else if (tgt_req->msg_type == WMA_OCB_SET_CONFIG_CMD) {
+		WMA_LOGE(FL("Failed to send OCB set config cmd"));
+		iface = &wma->interfaces[tgt_req->vdev_id];
+#ifndef CONFIG_VDEV_SM
+		wma_vdev_set_mlme_state(wma, tgt_req->vdev_id,
+			WLAN_VDEV_S_STOP);
+#endif
+		wma_ocb_set_config_resp(wma, QDF_STATUS_E_TIMEOUT);
+	} else if (tgt_req->msg_type == WMA_HIDDEN_SSID_VDEV_RESTART) {
+		if (wma_get_hidden_ssid_restart_in_progress(
+		    &wma->interfaces[tgt_req->vdev_id]) &&
+		    wma_is_vdev_in_ap_mode(wma, tgt_req->vdev_id)) {
+
+			WMA_LOGE("Hidden ssid vdev restart Timed Out; vdev_id: %d, type = %d",
+				 tgt_req->vdev_id, tgt_req->type);
+#ifndef CONFIG_VDEV_SM
+			qdf_atomic_set(&wma->interfaces[tgt_req->vdev_id].
+				       vdev_restart_params.
+				       hidden_ssid_restart_in_progress, 0);
+#endif
+			qdf_mem_free(tgt_req->user_data);
+		}
+	} else if (tgt_req->msg_type == WMA_SET_LINK_STATE) {
+		tpLinkStateParams params =
+			(tpLinkStateParams) tgt_req->user_data;
+
+		peer = cdp_peer_find_by_addr(soc, pdev, params->bssid, &peer_id);
+		if (peer) {
+			WMA_LOGP(FL("Deleting peer %pM vdev id %d"),
+				 params->bssid, tgt_req->vdev_id);
+			wma_remove_peer(wma, params->bssid, tgt_req->vdev_id,
+					peer, false);
+		}
+		if (wma_send_vdev_down_to_fw(wma, tgt_req->vdev_id) !=
+		    QDF_STATUS_SUCCESS) {
+			WMA_LOGE("Failed to send vdev down cmd: vdev %d",
+				tgt_req->vdev_id);
+		}
+		params->status = QDF_STATUS_E_TIMEOUT;
+		WMA_LOGA("%s: WMA_SET_LINK_STATE timedout vdev %d", __func__,
+			tgt_req->vdev_id);
+		wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
+	}
+free_tgt_req:
+	qdf_mc_timer_destroy(&tgt_req->event_timeout);
+	qdf_mem_free(tgt_req);
+}
+
+/**
+ * wma_fill_vdev_req() - fill vdev request
+ * @wma: wma handle
+ * @msg_type: message type
+ * @type: request type
+ * @params: request params
+ * @timeout: timeout value
+ *
+ * Return: wma_target_req ptr
+ */
+struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma,
+					 uint8_t vdev_id,
+					 uint32_t msg_type, uint8_t type,
+					 void *params, uint32_t timeout)
+{
+	struct wma_target_req *req;
+	QDF_STATUS status;
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return NULL;
+
+	WMA_LOGD("%s: vdev_id %d msg %d", __func__, vdev_id, msg_type);
+	qdf_spin_lock_bh(&wma->vdev_respq_lock);
+	req->vdev_id = vdev_id;
+	req->msg_type = msg_type;
+	req->type = type;
+	req->user_data = params;
+	status = qdf_list_insert_back(&wma->vdev_resp_queue, &req->node);
+	if (QDF_STATUS_SUCCESS != status) {
+		qdf_spin_unlock_bh(&wma->vdev_respq_lock);
+		WMA_LOGE(FL("Failed add request in queue for vdev_id %d type %d"),
+			 vdev_id, type);
+		qdf_mem_free(req);
+		return NULL;
+	}
+	qdf_spin_unlock_bh(&wma->vdev_respq_lock);
+	qdf_mc_timer_init(&req->event_timeout, QDF_TIMER_TYPE_SW,
+			  wma_vdev_resp_timer, req);
+	qdf_mc_timer_start(&req->event_timeout, timeout);
+	return req;
+}
+
+/**
+ * wma_remove_vdev_req() - remove vdev request
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @type: type
+ *
+ * Return: none
+ */
+void wma_remove_vdev_req(tp_wma_handle wma, uint8_t vdev_id,
+				uint8_t type)
+{
+	struct wma_target_req *req_msg;
+
+	req_msg = wma_find_vdev_req(wma, vdev_id, type, true);
+	if (!req_msg)
+		return;
+
+	qdf_mc_timer_stop(&req_msg->event_timeout);
+	qdf_mc_timer_destroy(&req_msg->event_timeout);
+	qdf_mem_free(req_msg);
+}
+
+/**
+ * wma_vdev_set_bss_params() - BSS set params functions
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @beaconInterval: beacon interval
+ * @dtimPeriod: DTIM period
+ * @shortSlotTimeSupported: short slot time
+ * @llbCoexist: llbCoexist
+ * @maxTxPower: max tx power
+ *
+ * Return: none
+ */
+static void
+wma_vdev_set_bss_params(tp_wma_handle wma, int vdev_id,
+			tSirMacBeaconInterval beaconInterval,
+			uint8_t dtimPeriod, uint8_t shortSlotTimeSupported,
+			uint8_t llbCoexist, int8_t maxTxPower)
+{
+	QDF_STATUS ret;
+	uint32_t slot_time;
+	struct wma_txrx_node *intr = wma->interfaces;
+
+	/* Beacon Interval setting */
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					      WMI_VDEV_PARAM_BEACON_INTERVAL,
+					      beaconInterval);
+
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("failed to set WMI_VDEV_PARAM_BEACON_INTERVAL");
+	ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, vdev_id,
+						&intr[vdev_id].config.gtx_info);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("failed to set WMI_VDEV_PARAM_DTIM_PERIOD");
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					      WMI_VDEV_PARAM_DTIM_PERIOD,
+					      dtimPeriod);
+	intr[vdev_id].dtimPeriod = dtimPeriod;
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("failed to set WMI_VDEV_PARAM_DTIM_PERIOD");
+
+	if (!maxTxPower)
+		WMA_LOGW("Setting Tx power limit to 0");
+	WMA_LOGD("Set maxTx pwr [WMI_VDEV_PARAM_TX_PWRLIMIT] to %d",
+						maxTxPower);
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					      WMI_VDEV_PARAM_TX_PWRLIMIT,
+					      maxTxPower);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("failed to set WMI_VDEV_PARAM_TX_PWRLIMIT");
+	else
+		intr[vdev_id].max_tx_power = maxTxPower;
+
+	/* Slot time */
+	if (shortSlotTimeSupported)
+		slot_time = WMI_VDEV_SLOT_TIME_SHORT;
+	else
+		slot_time = WMI_VDEV_SLOT_TIME_LONG;
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					      WMI_VDEV_PARAM_SLOT_TIME,
+					      slot_time);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("failed to set WMI_VDEV_PARAM_SLOT_TIME");
+
+	/* Initialize protection mode in case of coexistence */
+	wma_update_protection_mode(wma, vdev_id, llbCoexist);
+
+}
+
+#ifdef WLAN_FEATURE_11W
+static void wma_set_mgmt_frame_protection(tp_wma_handle wma)
+{
+	struct pdev_params param = {0};
+	QDF_STATUS ret;
+
+	/*
+	 * when 802.11w PMF is enabled for hw encr/decr
+	 * use hw MFP Qos bits 0x10
+	 */
+	param.param_id = WMI_PDEV_PARAM_PMF_QOS;
+	param.param_value = true;
+	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
+					 &param, WMA_WILDCARD_PDEV_ID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("%s: Failed to set QOS MFP/PMF (%d)",
+			 __func__, ret);
+	} else {
+		WMA_LOGD("%s: QOS MFP/PMF set", __func__);
+	}
+}
+#else
+static inline void wma_set_mgmt_frame_protection(tp_wma_handle wma)
+{
+}
+#endif /* WLAN_FEATURE_11W */
+
+/**
+ * wma_add_bss_ap_mode() - process add bss request in ap mode
+ * @wma: wma handle
+ * @add_bss: add bss parameters
+ *
+ * Return: none
+ */
+static void wma_add_bss_ap_mode(tp_wma_handle wma, tpAddBssParams add_bss)
+{
+	struct cdp_pdev *pdev;
+	struct cdp_vdev *vdev;
+	struct wma_vdev_start_req req;
+	void *peer;
+	struct wma_target_req *msg;
+	uint8_t vdev_id, peer_id;
+	QDF_STATUS status;
+	int8_t maxTxPower;
+	struct policy_mgr_hw_mode_params hw_mode = {0};
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		goto send_fail_resp;
+	}
+
+	vdev = wma_find_vdev_by_addr(wma, add_bss->bssId, &vdev_id);
+	if (!vdev) {
+		WMA_LOGE("%s: Failed to get vdev handle:"MAC_ADDRESS_STR,
+			__func__, MAC_ADDR_ARRAY(add_bss->bssId));
+
+		goto send_fail_resp;
+	}
+	if (SAP_WPS_DISABLED == add_bss->wps_state)
+		ucfg_pmo_disable_wakeup_event(wma->psoc, vdev_id,
+					      WOW_PROBE_REQ_WPS_IE_EVENT);
+	wma_set_bss_rate_flags(wma, vdev_id, add_bss);
+	status = wma_create_peer(wma, pdev, vdev, add_bss->bssId,
+				 WMI_PEER_TYPE_DEFAULT, vdev_id, false);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Failed to create peer", __func__);
+		goto send_fail_resp;
+	}
+
+	peer = cdp_peer_find_by_addr(soc, pdev,
+			add_bss->bssId, &peer_id);
+	if (!peer) {
+		WMA_LOGE("%s Failed to find peer %pM", __func__,
+			 add_bss->bssId);
+		goto send_fail_resp;
+	}
+	msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ,
+				WMA_TARGET_REQ_TYPE_VDEV_START, add_bss,
+				WMA_VDEV_START_REQUEST_TIMEOUT);
+	if (!msg) {
+		WMA_LOGE("%s Failed to allocate vdev request vdev_id %d",
+			 __func__, vdev_id);
+		goto peer_cleanup;
+	}
+
+	add_bss->staContext.staIdx = cdp_peer_get_local_peer_id(soc, peer);
+
+	qdf_mem_zero(&req, sizeof(req));
+	req.vdev_id = vdev_id;
+	req.chan = add_bss->currentOperChannel;
+	req.chan_width = add_bss->ch_width;
+	req.dot11_mode = add_bss->dot11_mode;
+
+	if (add_bss->ch_width == CH_WIDTH_10MHZ)
+		req.is_half_rate = 1;
+	else if (add_bss->ch_width == CH_WIDTH_5MHZ)
+		req.is_quarter_rate = 1;
+
+	req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0;
+	req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1;
+	req.vht_capable = add_bss->vhtCapable;
+	wma_update_vdev_he_ops(&req, add_bss);
+
+	req.max_txpow = add_bss->maxTxPower;
+	maxTxPower = add_bss->maxTxPower;
+
+	if (add_bss->rmfEnabled)
+		wma_set_mgmt_frame_protection(wma);
+
+	req.dot11_mode = add_bss->dot11_mode;
+	req.beacon_intval = add_bss->beaconInterval;
+	req.dtim_period = add_bss->dtimPeriod;
+	req.beacon_tx_rate = add_bss->beacon_tx_rate;
+	req.hidden_ssid = add_bss->bHiddenSSIDEn;
+	req.is_dfs = add_bss->bSpectrumMgtEnabled;
+	req.oper_mode = BSS_OPERATIONAL_MODE_AP;
+	req.ssid.length = add_bss->ssId.length;
+	req.cac_duration_ms = add_bss->cac_duration_ms;
+	req.dfs_regdomain = add_bss->dfs_regdomain;
+	if (req.ssid.length > 0)
+		qdf_mem_copy(req.ssid.ssId, add_bss->ssId.ssId,
+			     add_bss->ssId.length);
+	status = policy_mgr_get_current_hw_mode(wma->psoc, &hw_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		WMA_LOGE("policy_mgr_get_current_hw_mode failed");
+
+	if (add_bss->nss == 2) {
+		req.preferred_rx_streams = 2;
+		req.preferred_tx_streams = 2;
+	} else {
+		req.preferred_rx_streams = 1;
+		req.preferred_tx_streams = 1;
+	}
+
+	status = wma_vdev_start(wma, &req, false);
+	if (status != QDF_STATUS_SUCCESS) {
+		wma_remove_vdev_req(wma, vdev_id,
+				    WMA_TARGET_REQ_TYPE_VDEV_START);
+		goto peer_cleanup;
+	}
+
+	wma_vdev_set_bss_params(wma, vdev_id,
+				add_bss->beaconInterval, add_bss->dtimPeriod,
+				add_bss->shortSlotTimeSupported,
+				add_bss->llbCoexist, maxTxPower);
+
+	wma_vdev_set_he_bss_params(wma, vdev_id, &req);
+	return;
+
+peer_cleanup:
+	wma_remove_peer(wma, add_bss->bssId, vdev_id, peer, false);
+send_fail_resp:
+	add_bss->status = QDF_STATUS_E_FAILURE;
+	wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
+}
+
+#ifdef QCA_IBSS_SUPPORT
+/**
+ * wma_add_bss_ibss_mode() -  process add bss request in IBSS mode
+ * @wma: wma handle
+ * @add_bss: add bss parameters
+ *
+ * Return: none
+ */
+static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
+{
+	struct cdp_pdev *pdev;
+	struct cdp_vdev *vdev;
+	struct wma_vdev_start_req req;
+	void *peer = NULL;
+	struct wma_target_req *msg;
+	uint8_t vdev_id, peer_id;
+	QDF_STATUS status;
+	tSetBssKeyParams key_info;
+	struct policy_mgr_hw_mode_params hw_mode = {0};
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	vdev = wma_find_vdev_by_addr(wma, add_bss->selfMacAddr, &vdev_id);
+	if (!vdev) {
+		WMA_LOGE("%s: vdev not found for vdev id %d.",
+				__func__, vdev_id);
+		goto send_fail_resp;
+	}
+	WMA_LOGD("%s: add_bss->sessionId = %d", __func__, vdev_id);
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		goto send_fail_resp;
+	}
+	wma_set_bss_rate_flags(wma, vdev_id, add_bss);
+
+	/* create ibss bss peer */
+	status = wma_create_peer(wma, pdev, vdev, add_bss->selfMacAddr,
+				 WMI_PEER_TYPE_DEFAULT, vdev_id,
+				 false);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Failed to create peer", __func__);
+		goto send_fail_resp;
+	}
+	WMA_LOGA("IBSS BSS peer created with mac %pM",
+		 add_bss->selfMacAddr);
+
+	peer = cdp_peer_find_by_addr(soc, pdev,
+			add_bss->selfMacAddr, &peer_id);
+	if (!peer) {
+		WMA_LOGE("%s Failed to find peer %pM", __func__,
+			 add_bss->selfMacAddr);
+		goto send_fail_resp;
+	}
+
+	/* clear leftover ibss keys on bss peer */
+
+	WMA_LOGD("%s: ibss bss key clearing", __func__);
+	qdf_mem_set(&key_info, sizeof(key_info), 0);
+	key_info.smesessionId = vdev_id;
+	key_info.numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
+	qdf_mem_copy(&wma->ibsskey_info, &key_info, sizeof(tSetBssKeyParams));
+
+	/* start ibss vdev */
+
+	add_bss->operMode = BSS_OPERATIONAL_MODE_IBSS;
+
+	msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ,
+				WMA_TARGET_REQ_TYPE_VDEV_START, add_bss,
+				WMA_VDEV_START_REQUEST_TIMEOUT);
+	if (!msg) {
+		WMA_LOGE("%s Failed to allocate vdev request vdev_id %d",
+			 __func__, vdev_id);
+		goto peer_cleanup;
+	}
+	WMA_LOGD("%s: vdev start request for IBSS enqueued", __func__);
+
+	add_bss->staContext.staIdx = cdp_peer_get_local_peer_id(soc, peer);
+
+	/*
+	 * If IBSS Power Save is supported by firmware
+	 * set the IBSS power save params to firmware.
+	 */
+	if (wmi_service_enabled(wma->wmi_handle,
+				   wmi_service_ibss_pwrsave)) {
+		status = wma_set_ibss_pwrsave_params(wma, vdev_id);
+		if (status != QDF_STATUS_SUCCESS) {
+			WMA_LOGE("%s: Failed to Set IBSS Power Save Params to firmware",
+				__func__);
+			goto peer_cleanup;
+		}
+	}
+
+	qdf_mem_zero(&req, sizeof(req));
+	req.vdev_id = vdev_id;
+	req.chan = add_bss->currentOperChannel;
+	req.chan_width = add_bss->ch_width;
+	req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0;
+	req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1;
+	req.vht_capable = add_bss->vhtCapable;
+#if defined WLAN_FEATURE_VOWIF
+	req.max_txpow = add_bss->maxTxPower;
+#else
+	req.max_txpow = 0;
+#endif /* WLAN_FEATURE_VOWIF */
+	req.beacon_intval = add_bss->beaconInterval;
+	req.dtim_period = add_bss->dtimPeriod;
+	req.hidden_ssid = add_bss->bHiddenSSIDEn;
+	req.is_dfs = add_bss->bSpectrumMgtEnabled;
+	req.oper_mode = BSS_OPERATIONAL_MODE_IBSS;
+	req.ssid.length = add_bss->ssId.length;
+	if (req.ssid.length > 0)
+		qdf_mem_copy(req.ssid.ssId, add_bss->ssId.ssId,
+			     add_bss->ssId.length);
+	status = policy_mgr_get_current_hw_mode(wma->psoc, &hw_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		WMA_LOGE("policy_mgr_get_current_hw_mode failed");
+
+	if (add_bss->nss == 2) {
+		req.preferred_rx_streams = 2;
+		req.preferred_tx_streams = 2;
+	} else {
+		req.preferred_rx_streams = 1;
+		req.preferred_tx_streams = 1;
+	}
+
+	WMA_LOGD("%s: chan %d chan_width %d", __func__, req.chan,
+		 req.chan_width);
+	WMA_LOGD("%s: ssid = %s", __func__, req.ssid.ssId);
+
+	status = wma_vdev_start(wma, &req, false);
+	if (status != QDF_STATUS_SUCCESS) {
+		wma_remove_vdev_req(wma, vdev_id,
+				    WMA_TARGET_REQ_TYPE_VDEV_START);
+		goto peer_cleanup;
+	}
+	WMA_LOGD("%s: vdev start request for IBSS sent to target", __func__);
+
+	/* Initialize protection mode to no protection */
+	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					 WMI_VDEV_PARAM_PROTECTION_MODE,
+					 IEEE80211_PROT_NONE);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGE("Failed to initialize protection mode");
+
+	return;
+
+peer_cleanup:
+	if (peer)
+		wma_remove_peer(wma, add_bss->bssId, vdev_id, peer, false);
+send_fail_resp:
+	add_bss->status = QDF_STATUS_E_FAILURE;
+	wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
+}
+#endif /* QCA_IBSS_SUPPORT */
+
+/**
+ * wma_add_bss_sta_mode() -  process add bss request in sta mode
+ * @wma: wma handle
+ * @add_bss: add bss parameters
+ *
+ * Return: none
+ */
+static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss)
+{
+	struct cdp_pdev *pdev;
+	struct wma_vdev_start_req req;
+	struct wma_target_req *msg;
+	uint8_t vdev_id = 0, peer_id;
+	void *peer = NULL;
+	QDF_STATUS status;
+	struct wma_txrx_node *iface;
+	int pps_val = 0;
+	bool roam_synch_in_progress = false;
+	tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
+	struct policy_mgr_hw_mode_params hw_mode = {0};
+	bool peer_assoc_sent = false;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (NULL == pMac) {
+		WMA_LOGE("%s: Unable to get PE context", __func__);
+		goto send_fail_resp;
+	}
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s Failed to get pdev", __func__);
+		goto send_fail_resp;
+	}
+
+	vdev_id = add_bss->staContext.smesessionId;
+	iface = &wma->interfaces[vdev_id];
+
+	wma_set_bss_rate_flags(wma, vdev_id, add_bss);
+	if (add_bss->operMode) {
+		/* Save parameters later needed by WMA_ADD_STA_REQ */
+		if (iface->addBssStaContext)
+			qdf_mem_free(iface->addBssStaContext);
+		iface->addBssStaContext = qdf_mem_malloc(sizeof(tAddStaParams));
+		if (!iface->addBssStaContext)
+			goto send_fail_resp;
+
+		qdf_mem_copy(iface->addBssStaContext, &add_bss->staContext,
+			     sizeof(tAddStaParams));
+
+		if (iface->staKeyParams) {
+			qdf_mem_free(iface->staKeyParams);
+			iface->staKeyParams = NULL;
+		}
+		if (add_bss->extSetStaKeyParamValid) {
+			iface->staKeyParams =
+				qdf_mem_malloc(sizeof(tSetStaKeyParams));
+			if (!iface->staKeyParams)
+				goto send_fail_resp;
+
+			qdf_mem_copy(iface->staKeyParams,
+				     &add_bss->extSetStaKeyParam,
+				     sizeof(tSetStaKeyParams));
+		}
+		/* Save parameters later needed by WMA_ADD_STA_REQ */
+		iface->rmfEnabled = add_bss->rmfEnabled;
+		iface->beaconInterval = add_bss->beaconInterval;
+		iface->llbCoexist = add_bss->llbCoexist;
+		iface->shortSlotTimeSupported = add_bss->shortSlotTimeSupported;
+		iface->nwType = add_bss->nwType;
+		if (add_bss->nonRoamReassoc) {
+			peer = cdp_peer_find_by_addr(soc,
+					pdev, add_bss->bssId,
+					&peer_id);
+			if (peer) {
+				add_bss->staContext.staIdx =
+					cdp_peer_get_local_peer_id(soc, peer);
+				goto send_bss_resp;
+			}
+		}
+		if (add_bss->reassocReq) {
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
+			struct cdp_vdev *vdev;
+#endif
+			/* Called in preassoc state. BSSID peer is already
+			 * added by set_linkstate
+			 */
+			peer = cdp_peer_find_by_addr(soc,
+					pdev,
+					add_bss->bssId,
+					&peer_id);
+			if (!peer) {
+				WMA_LOGE("%s Failed to find peer %pM", __func__,
+					 add_bss->bssId);
+				goto send_fail_resp;
+			}
+			if (wma_is_roam_synch_in_progress(wma, vdev_id)) {
+				add_bss->staContext.staIdx =
+					cdp_peer_get_local_peer_id(soc, peer);
+				WMA_LOGD("LFR3:%s: bssid %pM staIdx %d",
+					__func__, add_bss->bssId,
+					add_bss->staContext.staIdx);
+				return;
+			}
+			msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ,
+						WMA_TARGET_REQ_TYPE_VDEV_START,
+						add_bss,
+						WMA_VDEV_START_REQUEST_TIMEOUT);
+			if (!msg) {
+				WMA_LOGE("%s Failed to allocate vdev request vdev_id %d",
+					__func__, vdev_id);
+				goto peer_cleanup;
+			}
+
+			add_bss->staContext.staIdx =
+				cdp_peer_get_local_peer_id(soc, peer);
+
+			qdf_mem_zero(&req, sizeof(req));
+			req.vdev_id = vdev_id;
+			req.chan = add_bss->currentOperChannel;
+			req.chan_width = add_bss->ch_width;
+
+			if (add_bss->ch_width == CH_WIDTH_10MHZ)
+				req.is_half_rate = 1;
+			else if (add_bss->ch_width == CH_WIDTH_5MHZ)
+				req.is_quarter_rate = 1;
+
+			req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0;
+			req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1;
+			req.max_txpow = add_bss->maxTxPower;
+			req.beacon_intval = add_bss->beaconInterval;
+			req.dtim_period = add_bss->dtimPeriod;
+			req.hidden_ssid = add_bss->bHiddenSSIDEn;
+			req.is_dfs = add_bss->bSpectrumMgtEnabled;
+			req.ssid.length = add_bss->ssId.length;
+			req.oper_mode = BSS_OPERATIONAL_MODE_STA;
+			if (req.ssid.length > 0)
+				qdf_mem_copy(req.ssid.ssId, add_bss->ssId.ssId,
+					     add_bss->ssId.length);
+			status = policy_mgr_get_current_hw_mode(wma->psoc,
+				&hw_mode);
+			if (!QDF_IS_STATUS_SUCCESS(status))
+				WMA_LOGE("policy_mgr_get_current_hw_mode failed");
+
+			if (add_bss->nss == 2) {
+				req.preferred_rx_streams = 2;
+				req.preferred_tx_streams = 2;
+			} else {
+				req.preferred_rx_streams = 1;
+				req.preferred_tx_streams = 1;
+			}
+
+			status = wma_vdev_start(wma, &req, false);
+			if (status != QDF_STATUS_SUCCESS) {
+				wma_remove_vdev_req(wma, vdev_id,
+					    WMA_TARGET_REQ_TYPE_VDEV_START);
+				goto peer_cleanup;
+			}
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
+			vdev = wma_find_vdev_by_id(wma, vdev_id);
+			if (!vdev) {
+				WMA_LOGE("%s Invalid txrx vdev", __func__);
+				goto peer_cleanup;
+			}
+			cdp_fc_vdev_pause(soc, vdev,
+				   OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
+#endif
+			/* ADD_BSS_RESP will be deferred to completion of
+			 * VDEV_START
+			 */
+			return;
+		}
+		if (!add_bss->updateBss)
+			goto send_bss_resp;
+		/* Update peer state */
+		if (add_bss->staContext.encryptType == eSIR_ED_NONE) {
+			WMA_LOGD("%s: Update peer(%pM) state into auth",
+				 __func__, add_bss->bssId);
+			cdp_peer_state_update(soc, pdev, add_bss->bssId,
+						  OL_TXRX_PEER_STATE_AUTH);
+		} else {
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
+			struct cdp_vdev *vdev;
+#endif
+			WMA_LOGD("%s: Update peer(%pM) state into conn",
+				 __func__, add_bss->bssId);
+			cdp_peer_state_update(soc, pdev, add_bss->bssId,
+						  OL_TXRX_PEER_STATE_CONN);
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
+			peer = cdp_peer_find_by_addr(soc, pdev, add_bss->bssId,
+					&peer_id);
+			if (!peer) {
+				WMA_LOGE("%s:%d Failed to find peer %pM",
+					 __func__, __LINE__, add_bss->bssId);
+				goto send_fail_resp;
+			}
+
+			vdev = wma_find_vdev_by_id(wma, vdev_id);
+			if (!vdev) {
+				WMA_LOGE("%s Invalid txrx vdev", __func__);
+				goto peer_cleanup;
+			}
+			cdp_fc_vdev_pause(soc, vdev,
+					OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
+#endif
+		}
+
+		wmi_unified_send_txbf(wma, &add_bss->staContext);
+
+		pps_val = ((pMac->mlme_cfg->sta.enable_5g_ebt << 31) &
+			   0xffff0000) | (PKT_PWR_SAVE_5G_EBT & 0xffff);
+		status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+						WMI_VDEV_PARAM_PACKET_POWERSAVE,
+						pps_val);
+		if (QDF_IS_STATUS_ERROR(status))
+			WMA_LOGE("Failed to send wmi packet power save cmd");
+		else
+			WMA_LOGD("Sent PKT_PWR_SAVE_5G_EBT cmd to target, val = %x, status = %d",
+				pps_val, status);
+		status = wma_send_peer_assoc(wma, add_bss->nwType,
+					     &add_bss->staContext);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			WMA_LOGE("Failed to send peer assoc status:%d", status);
+			goto peer_cleanup;
+		}
+		peer_assoc_sent = true;
+
+		/* we just had peer assoc, so install key will be done later */
+		if (add_bss->staContext.encryptType != eSIR_ED_NONE)
+			iface->is_waiting_for_key = true;
+
+		if (add_bss->rmfEnabled)
+			wma_set_mgmt_frame_protection(wma);
+
+		wma_vdev_set_bss_params(wma, add_bss->staContext.smesessionId,
+					add_bss->beaconInterval,
+					add_bss->dtimPeriod,
+					add_bss->shortSlotTimeSupported,
+					add_bss->llbCoexist,
+					add_bss->maxTxPower);
+
+		/*
+		 * Store the bssid in interface table, bssid will
+		 * be used during group key setting sta mode.
+		 */
+		qdf_mem_copy(iface->bssid, add_bss->bssId, IEEE80211_ADDR_LEN);
+
+	}
+send_bss_resp:
+
+	wma_vdev_set_he_config(wma, vdev_id, add_bss);
+	if (NULL == cdp_peer_find_by_addr(soc, pdev, add_bss->bssId,
+					&add_bss->staContext.staIdx))
+		add_bss->status = QDF_STATUS_E_FAILURE;
+	else
+		add_bss->status = QDF_STATUS_SUCCESS;
+	add_bss->bssIdx = add_bss->staContext.smesessionId;
+	qdf_mem_copy(add_bss->staContext.staMac, add_bss->bssId,
+		     sizeof(add_bss->staContext.staMac));
+
+	if (!wmi_service_enabled(wma->wmi_handle,
+				    wmi_service_peer_assoc_conf)) {
+		WMA_LOGE(FL("WMI_SERVICE_PEER_ASSOC_CONF not enabled"));
+		goto send_final_rsp;
+	}
+
+	/* In case of reassoc, peer assoc cmd will not be sent */
+	if (!peer_assoc_sent)
+		goto send_final_rsp;
+
+	msg = wma_fill_hold_req(wma, vdev_id, WMA_ADD_BSS_REQ,
+			   WMA_PEER_ASSOC_CNF_START, add_bss,
+			   WMA_PEER_ASSOC_TIMEOUT);
+	if (!msg) {
+		WMA_LOGE(FL("Failed to allocate request for vdev_id %d"),
+			 vdev_id);
+		wma_remove_req(wma, vdev_id, WMA_PEER_ASSOC_CNF_START);
+		goto peer_cleanup;
+	}
+	return;
+
+send_final_rsp:
+	WMA_LOGD("%s: opermode %d update_bss %d nw_type %d bssid %pM staIdx %d status %d",
+		 __func__, add_bss->operMode,
+		 add_bss->updateBss, add_bss->nwType, add_bss->bssId,
+		 add_bss->staContext.staIdx, add_bss->status);
+	wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
+	return;
+
+peer_cleanup:
+	if (peer)
+		wma_remove_peer(wma, add_bss->bssId, vdev_id, peer,
+				roam_synch_in_progress);
+send_fail_resp:
+	add_bss->status = QDF_STATUS_E_FAILURE;
+	if (!wma_is_roam_synch_in_progress(wma, vdev_id))
+		wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP,
+					   (void *)add_bss, 0);
+}
+
+/**
+ * wma_add_bss() - Add BSS request to fw as per opmode
+ * @wma: wma handle
+ * @params: add bss params
+ *
+ * Return: none
+ */
+void wma_add_bss(tp_wma_handle wma, tpAddBssParams params)
+{
+	WMA_LOGD("%s: add_bss_param.halPersona = %d",
+		 __func__, params->halPersona);
+
+	switch (params->halPersona) {
+
+	case QDF_SAP_MODE:
+	case QDF_P2P_GO_MODE:
+		wma_add_bss_ap_mode(wma, params);
+		break;
+
+#ifdef QCA_IBSS_SUPPORT
+	case QDF_IBSS_MODE:
+		wma_add_bss_ibss_mode(wma, params);
+		break;
+#endif
+
+	case QDF_NDI_MODE:
+		wma_add_bss_ndi_mode(wma, params);
+		break;
+
+	default:
+		wma_add_bss_sta_mode(wma, params);
+		break;
+	}
+}
+
+/**
+ * wma_add_sta_req_ap_mode() - process add sta request in ap mode
+ * @wma: wma handle
+ * @add_sta: add sta params
+ *
+ * Return: none
+ */
+static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
+{
+	enum ol_txrx_peer_state state = OL_TXRX_PEER_STATE_CONN;
+	struct cdp_pdev *pdev;
+	struct cdp_vdev *vdev;
+	void *peer;
+	uint8_t peer_id;
+	QDF_STATUS status;
+	int32_t ret;
+	struct wma_txrx_node *iface = NULL;
+	struct wma_target_req *msg;
+	bool peer_assoc_cnf = false;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	uint32_t i, j;
+	uint16_t mcs_limit;
+	uint8_t *rate_pos;
+	struct mac_context *mac = (struct mac_context *)wma->mac_context;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to find pdev", __func__);
+		add_sta->status = QDF_STATUS_E_FAILURE;
+		goto send_rsp;
+	}
+	/* UMAC sends WMA_ADD_STA_REQ msg twice to WMA when the station
+	 * associates. First WMA_ADD_STA_REQ will have staType as
+	 * STA_ENTRY_PEER and second posting will have STA_ENTRY_SELF.
+	 * Peer creation is done in first WMA_ADD_STA_REQ and second
+	 * WMA_ADD_STA_REQ which has STA_ENTRY_SELF is ignored and
+	 * send fake response with success to UMAC. Otherwise UMAC
+	 * will get blocked.
+	 */
+	if (add_sta->staType != STA_ENTRY_PEER) {
+		add_sta->status = QDF_STATUS_SUCCESS;
+		goto send_rsp;
+	}
+
+	vdev = wma_find_vdev_by_id(wma, add_sta->smesessionId);
+	if (!vdev) {
+		WMA_LOGE("%s: Failed to find vdev", __func__);
+		add_sta->status = QDF_STATUS_E_FAILURE;
+		goto send_rsp;
+	}
+
+	iface = &wma->interfaces[add_sta->smesessionId];
+	peer = cdp_peer_find_by_addr_and_vdev(soc, pdev, vdev,
+				add_sta->staMac, &peer_id);
+	if (peer) {
+		wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
+				peer, false);
+		WMA_LOGE("%s: Peer already exists, Deleted peer with peer_addr %pM",
+			__func__, add_sta->staMac);
+	}
+	/* The code above only checks the peer existence on its own vdev.
+	 * Need to check whether the peer exists on other vDevs because firmware
+	 * can't create the peer if the peer with same MAC address already
+	 * exists on the pDev. As this peer belongs to other vDevs, just return
+	 * here.
+	 */
+	peer = cdp_peer_find_by_addr(soc, pdev,
+			add_sta->staMac, &peer_id);
+	if (peer) {
+		WMA_LOGE("%s: My vdev:%pK, but Peer exists on other vdev with peer_addr %pM and peer_id %d",
+			__func__, vdev, add_sta->staMac, peer_id);
+		add_sta->status = QDF_STATUS_E_FAILURE;
+		goto send_rsp;
+	}
+
+	status = wma_create_peer(wma, pdev, vdev, add_sta->staMac,
+				 WMI_PEER_TYPE_DEFAULT, add_sta->smesessionId,
+				 false);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Failed to create peer for %pM",
+			 __func__, add_sta->staMac);
+		add_sta->status = status;
+		goto send_rsp;
+	}
+
+	peer = cdp_peer_find_by_addr_and_vdev(soc, pdev,
+				vdev,
+				add_sta->staMac, &peer_id);
+	if (!peer) {
+		WMA_LOGE("%s: Failed to find peer handle using peer mac %pM",
+			 __func__, add_sta->staMac);
+		add_sta->status = QDF_STATUS_E_FAILURE;
+		wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
+				peer, false);
+		goto send_rsp;
+	}
+
+	wmi_unified_send_txbf(wma, add_sta);
+
+	/*
+	 * Get MCS limit from ini configure, and map it to rate parameters
+	 * This will limit HT rate upper bound. CFG_CTRL_MASK is used to
+	 * check whether ini config is enabled and CFG_DATA_MASK to get the
+	 * MCS value.
+	 */
+#define CFG_CTRL_MASK              0xFF00
+#define CFG_DATA_MASK              0x00FF
+
+	mcs_limit = mac->mlme_cfg->rates.sap_max_mcs_txdata;
+
+	if (mcs_limit & CFG_CTRL_MASK) {
+		WMA_LOGD("%s: set mcs_limit %x", __func__, mcs_limit);
+
+		mcs_limit &= CFG_DATA_MASK;
+		rate_pos = (u_int8_t *)add_sta->supportedRates.supportedMCSSet;
+		for (i = 0, j = 0; i < MAX_SUPPORTED_RATES;) {
+			if (j < mcs_limit / 8) {
+				rate_pos[j] = 0xff;
+				j++;
+				i += 8;
+			} else if (j < mcs_limit / 8 + 1) {
+				if (i <= mcs_limit)
+					rate_pos[i / 8] |= 1 << (i % 8);
+				else
+					rate_pos[i / 8] &= ~(1 << (i % 8));
+				i++;
+
+				if (i >= (j + 1) * 8)
+					j++;
+			} else {
+				rate_pos[j++] = 0;
+				i += 8;
+			}
+		}
+	}
+
+	if (wmi_service_enabled(wma->wmi_handle,
+				    wmi_service_peer_assoc_conf)) {
+		peer_assoc_cnf = true;
+		msg = wma_fill_hold_req(wma, add_sta->smesessionId,
+				   WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
+				   add_sta, WMA_PEER_ASSOC_TIMEOUT);
+		if (!msg) {
+			WMA_LOGE(FL("Failed to alloc request for vdev_id %d"),
+				 add_sta->smesessionId);
+			add_sta->status = QDF_STATUS_E_FAILURE;
+			wma_remove_req(wma, add_sta->smesessionId,
+				       WMA_PEER_ASSOC_CNF_START);
+			wma_remove_peer(wma, add_sta->staMac,
+				add_sta->smesessionId, peer, false);
+			peer_assoc_cnf = false;
+			goto send_rsp;
+		}
+	} else {
+		WMA_LOGE(FL("WMI_SERVICE_PEER_ASSOC_CONF not enabled"));
+	}
+
+	ret = wma_send_peer_assoc(wma, add_sta->nwType, add_sta);
+	if (ret) {
+		add_sta->status = QDF_STATUS_E_FAILURE;
+		wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
+				peer, false);
+		goto send_rsp;
+	}
+#ifdef QCA_IBSS_SUPPORT
+	/*
+	 * In IBSS mode send the peer
+	 * Atim Window length if IBSS
+	 * power save is enabled by the
+	 * firmware.
+	 */
+	if (wma_is_vdev_in_ibss_mode(wma, add_sta->smesessionId) &&
+	    wmi_service_enabled(wma->wmi_handle,
+				   wmi_service_ibss_pwrsave)) {
+		/*
+		 * If ATIM Window is present in the peer
+		 * beacon then send it to firmware else
+		 * configure Zero ATIM Window length to
+		 * firmware.
+		 */
+		if (add_sta->atimIePresent) {
+			wma_set_peer_param(wma, add_sta->staMac,
+					   WMI_PEER_IBSS_ATIM_WINDOW_LENGTH,
+					   add_sta->peerAtimWindowLength,
+					   add_sta->smesessionId);
+		} else {
+			wma_set_peer_param(wma, add_sta->staMac,
+					   WMI_PEER_IBSS_ATIM_WINDOW_LENGTH,
+					   0, add_sta->smesessionId);
+		}
+	}
+#endif
+
+	iface->rmfEnabled = add_sta->rmfEnabled;
+	if (add_sta->rmfEnabled)
+		wma_set_mgmt_frame_protection(wma);
+
+	if (add_sta->uAPSD) {
+		status = wma_set_ap_peer_uapsd(wma, add_sta->smesessionId,
+					    add_sta->staMac,
+					    add_sta->uAPSD, add_sta->maxSPLen);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			WMA_LOGE("Failed to set peer uapsd param for %pM",
+				 add_sta->staMac);
+			add_sta->status = QDF_STATUS_E_FAILURE;
+			wma_remove_peer(wma, add_sta->staMac,
+					add_sta->smesessionId, peer, false);
+			goto send_rsp;
+		}
+	}
+
+	WMA_LOGD("%s: Moving peer %pM to state %d",
+		 __func__, add_sta->staMac, state);
+	cdp_peer_state_update(soc, pdev, add_sta->staMac, state);
+
+	add_sta->staIdx = cdp_peer_get_local_peer_id(soc, peer);
+	add_sta->nss    = iface->nss;
+	add_sta->status = QDF_STATUS_SUCCESS;
+send_rsp:
+	/* Do not send add stat resp when peer assoc cnf is enabled */
+	if (peer_assoc_cnf) {
+		WMA_LOGD(FL("WMI_SERVICE_PEER_ASSOC_CONF is enabled"));
+		return;
+	}
+
+	WMA_LOGD(FL("statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d"),
+		 add_sta->staType, add_sta->smesessionId,
+		 add_sta->assocId, add_sta->bssId, add_sta->staIdx,
+		 add_sta->status);
+	wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0);
+}
+
+#ifdef FEATURE_WLAN_TDLS
+
+/**
+ * wma_add_tdls_sta() - process add sta request in TDLS mode
+ * @wma: wma handle
+ * @add_sta: add sta params
+ *
+ * Return: none
+ */
+static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta)
+{
+	struct cdp_pdev *pdev;
+	struct cdp_vdev *vdev;
+	void *peer;
+	uint8_t peer_id;
+	QDF_STATUS status;
+	int32_t ret;
+	tTdlsPeerStateParams *peerStateParams;
+	struct wma_target_req *msg;
+	bool peer_assoc_cnf = false;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	WMA_LOGD("%s: staType: %d, staIdx: %d, updateSta: %d, bssId: %pM, staMac: %pM",
+		 __func__, add_sta->staType, add_sta->staIdx,
+		 add_sta->updateSta, add_sta->bssId, add_sta->staMac);
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to find pdev", __func__);
+		add_sta->status = QDF_STATUS_E_FAILURE;
+		goto send_rsp;
+	}
+
+	vdev = wma_find_vdev_by_id(wma, add_sta->smesessionId);
+	if (!vdev) {
+		WMA_LOGE("%s: Failed to find vdev", __func__);
+		add_sta->status = QDF_STATUS_E_FAILURE;
+		goto send_rsp;
+	}
+
+	if (wma_is_roam_synch_in_progress(wma, add_sta->smesessionId)) {
+		WMA_LOGE("%s: roaming in progress, reject add sta!", __func__);
+		add_sta->status = QDF_STATUS_E_PERM;
+		goto send_rsp;
+	}
+
+	if (0 == add_sta->updateSta) {
+		/* its a add sta request * */
+
+		cdp_peer_copy_mac_addr_raw(soc, vdev, add_sta->bssId);
+
+		WMA_LOGD("%s: addSta, calling wma_create_peer for %pM, vdev_id %hu",
+			__func__, add_sta->staMac, add_sta->smesessionId);
+
+		status = wma_create_peer(wma, pdev, vdev, add_sta->staMac,
+					 WMI_PEER_TYPE_TDLS,
+					 add_sta->smesessionId, false);
+		if (status != QDF_STATUS_SUCCESS) {
+			WMA_LOGE("%s: Failed to create peer for %pM",
+				 __func__, add_sta->staMac);
+			add_sta->status = status;
+			goto send_rsp;
+		}
+
+		peer = cdp_peer_find_by_addr(soc, pdev,
+				add_sta->staMac,
+				&peer_id);
+		if (!peer) {
+			WMA_LOGE("%s: addSta, failed to find peer handle for mac %pM",
+				__func__, add_sta->staMac);
+			add_sta->status = QDF_STATUS_E_FAILURE;
+			cdp_peer_add_last_real_peer(soc, pdev, vdev, &peer_id);
+			goto send_rsp;
+		}
+
+		add_sta->staIdx = cdp_peer_get_local_peer_id(soc, peer);
+		WMA_LOGD("%s: addSta, after calling cdp_local_peer_id, staIdx: %d, staMac: %pM",
+			 __func__, add_sta->staIdx, add_sta->staMac);
+
+		peerStateParams = qdf_mem_malloc(sizeof(tTdlsPeerStateParams));
+		if (!peerStateParams) {
+			add_sta->status = QDF_STATUS_E_NOMEM;
+			goto send_rsp;
+		}
+
+		peerStateParams->peerState = WMI_TDLS_PEER_STATE_PEERING;
+		peerStateParams->vdevId = add_sta->smesessionId;
+		qdf_mem_copy(&peerStateParams->peerMacAddr,
+			     &add_sta->staMac, sizeof(tSirMacAddr));
+		wma_update_tdls_peer_state(wma, peerStateParams);
+	} else {
+		/* its a change sta request * */
+		peer =
+			cdp_peer_find_by_addr(soc, pdev,
+				add_sta->staMac,
+				&peer_id);
+		if (!peer) {
+			WMA_LOGE("%s: changeSta,failed to find peer handle for mac %pM",
+				__func__, add_sta->staMac);
+			add_sta->status = QDF_STATUS_E_FAILURE;
+
+			cdp_peer_add_last_real_peer(soc, pdev, vdev, &peer_id);
+
+			goto send_rsp;
+		}
+
+		if (wmi_service_enabled(wma->wmi_handle,
+					    wmi_service_peer_assoc_conf)) {
+			WMA_LOGE(FL("WMI_SERVICE_PEER_ASSOC_CONF is enabled"));
+			peer_assoc_cnf = true;
+			msg = wma_fill_hold_req(wma, add_sta->smesessionId,
+				WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
+				add_sta, WMA_PEER_ASSOC_TIMEOUT);
+			if (!msg) {
+				WMA_LOGE(FL("Failed to alloc request for vdev_id %d"),
+					 add_sta->smesessionId);
+				add_sta->status = QDF_STATUS_E_FAILURE;
+				wma_remove_req(wma, add_sta->smesessionId,
+					       WMA_PEER_ASSOC_CNF_START);
+				wma_remove_peer(wma, add_sta->staMac,
+					add_sta->smesessionId, peer, false);
+				peer_assoc_cnf = false;
+				goto send_rsp;
+			}
+		} else {
+			WMA_LOGE(FL("WMI_SERVICE_PEER_ASSOC_CONF not enabled"));
+		}
+
+		WMA_LOGD("%s: changeSta, calling wma_send_peer_assoc",
+			 __func__);
+
+		ret =
+			wma_send_peer_assoc(wma, add_sta->nwType, add_sta);
+		if (ret) {
+			add_sta->status = QDF_STATUS_E_FAILURE;
+			wma_remove_peer(wma, add_sta->staMac,
+					add_sta->smesessionId, peer, false);
+			cdp_peer_add_last_real_peer(soc, pdev, vdev, &peer_id);
+			wma_remove_req(wma, add_sta->smesessionId,
+				       WMA_PEER_ASSOC_CNF_START);
+			peer_assoc_cnf = false;
+
+			goto send_rsp;
+		}
+	}
+
+send_rsp:
+	/* Do not send add stat resp when peer assoc cnf is enabled */
+	if (peer_assoc_cnf)
+		return;
+
+	WMA_LOGD(FL("statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d"),
+		 add_sta->staType, add_sta->smesessionId,
+		 add_sta->assocId, add_sta->bssId, add_sta->staIdx,
+		 add_sta->status);
+	wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0);
+}
+#endif
+
+/**
+ * wma_send_bss_color_change_enable() - send bss color change enable cmd.
+ * @wma: wma handle
+ * @params: add sta params
+ *
+ * Send bss color change command to firmware, to enable firmware to update
+ * internally if any change in bss color in advertised by associated AP.
+ *
+ * Return: none
+ */
+#ifdef WLAN_FEATURE_11AX
+static void wma_send_bss_color_change_enable(tp_wma_handle wma,
+					     tpAddStaParams params)
+{
+	QDF_STATUS status;
+	uint32_t vdev_id = params->smesessionId;
+
+	if (!params->he_capable) {
+		WMA_LOGD("%s: he_capable is not set for vdev_id:%d",
+			 __func__, vdev_id);
+		return;
+	}
+
+	status = wmi_unified_send_bss_color_change_enable_cmd(wma->wmi_handle,
+							      vdev_id,
+							      true);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Failed to enable bss color change offload, vdev:%d",
+			 vdev_id);
+	}
+
+	return;
+}
+#else
+static void wma_send_bss_color_change_enable(tp_wma_handle wma,
+					     tpAddStaParams params)
+{
+}
+#endif
+
+/**
+ * wma_add_sta_req_sta_mode() - process add sta request in sta mode
+ * @wma: wma handle
+ * @params: add sta params
+ *
+ * Return: none
+ */
+static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
+{
+	struct cdp_pdev *pdev;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	void *peer;
+	struct wma_txrx_node *iface;
+	int8_t maxTxPower;
+	int ret = 0;
+	struct wma_target_req *msg;
+	bool peer_assoc_cnf = false;
+	struct vdev_up_params param = {0};
+	int smps_param;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+#ifdef FEATURE_WLAN_TDLS
+	if (STA_ENTRY_TDLS_PEER == params->staType) {
+		wma_add_tdls_sta(wma, params);
+		return;
+	}
+#endif
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Unable to get pdev", __func__);
+		goto out;
+	}
+
+	iface = &wma->interfaces[params->smesessionId];
+	if (params->staType != STA_ENTRY_SELF) {
+		WMA_LOGE("%s: unsupported station type %d",
+			 __func__, params->staType);
+		goto out;
+	}
+	peer = cdp_peer_find_by_addr(soc,
+			pdev,
+			params->bssId, &params->staIdx);
+	if (peer == NULL) {
+		WMA_LOGE("%s: Peer is not present vdev id %d for %pM", __func__,
+			params->smesessionId, params->bssId);
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+	if (params->nonRoamReassoc) {
+		cdp_peer_state_update(soc, pdev, params->bssId,
+					  OL_TXRX_PEER_STATE_AUTH);
+		qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED);
+		iface->aid = params->assocId;
+		goto out;
+	}
+
+	if (wma_is_vdev_up(params->smesessionId)) {
+		WMA_LOGE("%s: vdev id %d is already UP for %pM", __func__,
+			params->smesessionId, params->bssId);
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	if (peer != NULL &&
+	    (cdp_peer_state_get(soc, peer) == OL_TXRX_PEER_STATE_DISC)) {
+		/*
+		 * This is the case for reassociation.
+		 * peer state update and peer_assoc is required since it
+		 * was not done by WMA_ADD_BSS_REQ.
+		 */
+
+		/* Update peer state */
+		if (params->encryptType == eSIR_ED_NONE) {
+			WMA_LOGD("%s: Update peer(%pM) state into auth",
+				 __func__, params->bssId);
+			cdp_peer_state_update(soc, pdev, params->bssId,
+						  OL_TXRX_PEER_STATE_AUTH);
+		} else {
+			WMA_LOGD("%s: Update peer(%pM) state into conn",
+				 __func__, params->bssId);
+			cdp_peer_state_update(soc, pdev, params->bssId,
+						  OL_TXRX_PEER_STATE_CONN);
+		}
+
+		if (wma_is_roam_synch_in_progress(wma, params->smesessionId)) {
+			/* iface->nss = params->nss; */
+			/*In LFR2.0, the following operations are performed as
+			 * part of wma_send_peer_assoc. As we are
+			 * skipping this operation, we are just executing the
+			 * following which are useful for LFR3.0
+			 */
+			cdp_peer_state_update(soc, pdev, params->bssId,
+						  OL_TXRX_PEER_STATE_AUTH);
+			qdf_atomic_set(&iface->bss_status,
+				       WMA_BSS_STATUS_STARTED);
+			iface->aid = params->assocId;
+			WMA_LOGD("LFR3:statype %d vdev %d aid %d bssid %pM",
+					params->staType, params->smesessionId,
+					params->assocId, params->bssId);
+			return;
+		}
+		wmi_unified_send_txbf(wma, params);
+
+		if (wmi_service_enabled(wma->wmi_handle,
+					    wmi_service_peer_assoc_conf)) {
+			WMA_LOGD(FL("WMI_SERVICE_PEER_ASSOC_CONF is enabled"));
+			peer_assoc_cnf = true;
+			msg = wma_fill_hold_req(wma, params->smesessionId,
+				WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
+				params, WMA_PEER_ASSOC_TIMEOUT);
+			if (!msg) {
+				WMA_LOGD(FL("Failed to alloc request for vdev_id %d"),
+					 params->smesessionId);
+				params->status = QDF_STATUS_E_FAILURE;
+				wma_remove_req(wma, params->smesessionId,
+					       WMA_PEER_ASSOC_CNF_START);
+				wma_remove_peer(wma, params->staMac,
+					params->smesessionId, peer, false);
+				peer_assoc_cnf = false;
+				goto out;
+			}
+		} else {
+			WMA_LOGD(FL("WMI_SERVICE_PEER_ASSOC_CONF not enabled"));
+		}
+
+		ret = wma_send_peer_assoc(wma,
+				iface->nwType,
+				(tAddStaParams *) iface->addBssStaContext);
+		if (ret) {
+			status = QDF_STATUS_E_FAILURE;
+			wma_remove_peer(wma, params->bssId,
+					params->smesessionId, peer, false);
+			goto out;
+		}
+
+		if (params->rmfEnabled)
+			wma_set_mgmt_frame_protection(wma);
+
+		/*
+		 * Set the PTK in 11r mode because we already have it.
+		 */
+		if (iface->staKeyParams) {
+			wma_set_stakey(wma,
+				       (tpSetStaKeyParams) iface->staKeyParams);
+		}
+	}
+	maxTxPower = params->maxTxPower;
+	wma_vdev_set_bss_params(wma, params->smesessionId,
+				iface->beaconInterval, iface->dtimPeriod,
+				iface->shortSlotTimeSupported,
+				iface->llbCoexist, maxTxPower);
+
+	params->csaOffloadEnable = 0;
+	if (wmi_service_enabled(wma->wmi_handle,
+				   wmi_service_csa_offload)) {
+		params->csaOffloadEnable = 1;
+		if (wma_unified_csa_offload_enable(wma, params->smesessionId) <
+		    0) {
+			WMA_LOGE("Unable to enable CSA offload for vdev_id:%d",
+				 params->smesessionId);
+		}
+	}
+
+	if (wmi_service_enabled(wma->wmi_handle,
+				wmi_service_filter_ipsec_natkeepalive)) {
+		if (wmi_unified_nat_keepalive_en_cmd(wma->wmi_handle,
+						     params->smesessionId)) {
+			WMA_LOGE("Unable to enable NAT keepalive for vdev_id:%d",
+				params->smesessionId);
+		}
+	}
+
+	param.vdev_id = params->smesessionId;
+	param.assoc_id = params->assocId;
+#ifdef CONFIG_VDEV_SM
+	status = wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+					       WLAN_VDEV_SM_EV_START_SUCCESS,
+					       sizeof(param), (void *)&param);
+#else
+	status = wma_send_vdev_up_to_fw(wma, &param, params->bssId);
+#endif
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("%s: Failed to send vdev up cmd: vdev %d bssid %pM",
+			 __func__, params->smesessionId, params->bssId);
+		policy_mgr_set_do_hw_mode_change_flag(
+			wma->psoc, false);
+		status = QDF_STATUS_E_FAILURE;
+	} else {
+		wma_set_vdev_mgmt_rate(wma, params->smesessionId);
+#ifndef CONFIG_VDEV_SM
+		wma_vdev_set_mlme_state(wma, params->smesessionId,
+				WLAN_VDEV_S_RUN);
+#endif
+	}
+
+	qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED);
+	WMA_LOGD("%s: STA mode (type %d subtype %d) BSS is started",
+		 __func__, iface->type, iface->sub_type);
+	/* Sta is now associated, configure various params */
+
+	/* Send SMPS force command to FW to send the required
+	 * action frame only when SM power save is enbaled in
+	 * from INI. In case dynamic antenna selection, the
+	 * action frames are sent by the chain mask manager
+	 * In addition to the action frames, The SM power save is
+	 * published in the assoc request HT SMPS IE for both cases.
+	 */
+	if ((params->enableHtSmps) && (params->send_smps_action)) {
+		smps_param = wma_smps_mode_to_force_mode_param(
+			params->htSmpsconfig);
+		if (smps_param >= 0) {
+			WMA_LOGD("%s: Send SMPS force mode: %d",
+				__func__, params->htSmpsconfig);
+			wma_set_mimops(wma, params->smesessionId,
+				smps_param);
+		}
+	}
+
+	wma_send_bss_color_change_enable(wma, params);
+
+	/* Partial AID match power save, enable when SU bformee */
+	if (params->enableVhtpAid && params->vhtTxBFCapable)
+		wma_set_ppsconfig(params->smesessionId,
+				  WMA_VHT_PPS_PAID_MATCH, 1);
+
+	/* Enable AMPDU power save, if htCapable/vhtCapable */
+	if (params->enableAmpduPs && (params->htCapable || params->vhtCapable))
+		wma_set_ppsconfig(params->smesessionId,
+				  WMA_VHT_PPS_DELIM_CRC_FAIL, 1);
+	if (wmi_service_enabled(wma->wmi_handle,
+				wmi_service_listen_interval_offload_support)) {
+		WMA_LOGD("%s: listen interval offload enabled, setting params",
+			 __func__);
+		status = wma_vdev_set_param(wma->wmi_handle,
+					    params->smesessionId,
+					    WMI_VDEV_PARAM_MAX_LI_OF_MODDTIM,
+					    wma->staMaxLIModDtim);
+		if (status != QDF_STATUS_SUCCESS) {
+			WMA_LOGE(FL("can't set MAX_LI for session: %d"),
+				 params->smesessionId);
+		}
+		status = wma_vdev_set_param(wma->wmi_handle,
+					    params->smesessionId,
+					    WMI_VDEV_PARAM_DYNDTIM_CNT,
+					    wma->staDynamicDtim);
+		if (status != QDF_STATUS_SUCCESS) {
+			WMA_LOGE(FL("can't set DYNDTIM_CNT for session: %d"),
+				 params->smesessionId);
+		}
+		status  = wma_vdev_set_param(wma->wmi_handle,
+					     params->smesessionId,
+					     WMI_VDEV_PARAM_MODDTIM_CNT,
+					     wma->staModDtim);
+		if (status != QDF_STATUS_SUCCESS) {
+			WMA_LOGE(FL("can't set DTIM_CNT for session: %d"),
+				 params->smesessionId);
+		}
+
+	} else {
+		WMA_LOGD("%s: listen interval offload is not set",
+			 __func__);
+	}
+
+	iface->aid = params->assocId;
+	params->nss = iface->nss;
+out:
+	/* Do not send add stat resp when peer assoc cnf is enabled */
+	if (peer_assoc_cnf)
+		return;
+
+	params->status = status;
+	WMA_LOGD(FL("statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d"),
+		 params->staType, params->smesessionId,
+		 params->assocId, params->bssId, params->staIdx,
+		 params->status);
+	/* Don't send a response during roam sync operation */
+	if (!wma_is_roam_synch_in_progress(wma, params->smesessionId))
+		wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
+					   (void *)params, 0);
+}
+
+/**
+ * wma_delete_sta_req_ap_mode() - process delete sta request from UMAC in AP mode
+ * @wma: wma handle
+ * @del_sta: delete sta params
+ *
+ * Return: none
+ */
+static void wma_delete_sta_req_ap_mode(tp_wma_handle wma,
+				       tpDeleteStaParams del_sta)
+{
+	struct cdp_pdev *pdev;
+	void *peer;
+	struct wma_target_req *msg;
+	uint8_t *peer_mac_addr;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		del_sta->status = QDF_STATUS_E_FAILURE;
+		goto send_del_rsp;
+	}
+
+	peer = cdp_peer_find_by_local_id(soc,
+			pdev, del_sta->staIdx);
+	if (!peer) {
+		WMA_LOGE("%s: Failed to get peer handle using peer id %d",
+			 __func__, del_sta->staIdx);
+		del_sta->status = QDF_STATUS_E_FAILURE;
+		goto send_del_rsp;
+	}
+	peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer);
+
+	wma_remove_peer(wma, peer_mac_addr, del_sta->smesessionId, peer,
+			false);
+	del_sta->status = QDF_STATUS_SUCCESS;
+
+	if (wmi_service_enabled(wma->wmi_handle,
+				    wmi_service_sync_delete_cmds)) {
+		msg = wma_fill_hold_req(wma, del_sta->smesessionId,
+				   WMA_DELETE_STA_REQ,
+				   WMA_DELETE_STA_RSP_START, del_sta,
+				   WMA_DELETE_STA_TIMEOUT);
+		if (!msg) {
+			WMA_LOGE(FL("Failed to allocate request. vdev_id %d"),
+				 del_sta->smesessionId);
+			wma_remove_req(wma, del_sta->smesessionId,
+				WMA_DELETE_STA_RSP_START);
+			del_sta->status = QDF_STATUS_E_NOMEM;
+			goto send_del_rsp;
+		}
+
+		wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
+				     WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION);
+
+		return;
+	}
+
+send_del_rsp:
+	if (del_sta->respReqd) {
+		WMA_LOGD("%s: Sending del rsp to umac (status: %d)",
+			 __func__, del_sta->status);
+		wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
+					   (void *)del_sta, 0);
+	}
+}
+
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * wma_del_tdls_sta() - process delete sta request from UMAC in TDLS
+ * @wma: wma handle
+ * @del_sta: delete sta params
+ *
+ * Return: none
+ */
+static void wma_del_tdls_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
+{
+	tTdlsPeerStateParams *peerStateParams;
+	struct wma_target_req *msg;
+	int status;
+
+	peerStateParams = qdf_mem_malloc(sizeof(tTdlsPeerStateParams));
+	if (!peerStateParams) {
+		del_sta->status = QDF_STATUS_E_NOMEM;
+		goto send_del_rsp;
+	}
+
+	if (wma_is_roam_synch_in_progress(wma, del_sta->smesessionId)) {
+		WMA_LOGE("%s: roaming in progress, reject del sta!", __func__);
+		del_sta->status = QDF_STATUS_E_PERM;
+		goto send_del_rsp;
+	}
+
+	peerStateParams->peerState = WMA_TDLS_PEER_STATE_TEARDOWN;
+	peerStateParams->vdevId = del_sta->smesessionId;
+	peerStateParams->resp_reqd = del_sta->respReqd;
+	qdf_mem_copy(&peerStateParams->peerMacAddr,
+		     &del_sta->staMac, sizeof(tSirMacAddr));
+
+	WMA_LOGD("%s: sending tdls_peer_state for peer mac: %pM, peerState: %d",
+		 __func__, peerStateParams->peerMacAddr,
+		 peerStateParams->peerState);
+
+	status = wma_update_tdls_peer_state(wma, peerStateParams);
+
+	if (status < 0) {
+		WMA_LOGE("%s: wma_update_tdls_peer_state returned failure",
+				__func__);
+		goto send_del_rsp;
+	}
+
+	if (del_sta->respReqd &&
+			wmi_service_enabled(wma->wmi_handle,
+				wmi_service_sync_delete_cmds)) {
+		del_sta->status = QDF_STATUS_SUCCESS;
+		msg = wma_fill_hold_req(wma,
+				del_sta->smesessionId,
+				WMA_DELETE_STA_REQ,
+				WMA_DELETE_STA_RSP_START, del_sta,
+				WMA_DELETE_STA_TIMEOUT);
+		if (!msg) {
+			WMA_LOGE(FL("Failed to allocate vdev_id %d"),
+					del_sta->smesessionId);
+			wma_remove_req(wma,
+					del_sta->smesessionId,
+					WMA_DELETE_STA_RSP_START);
+			del_sta->status = QDF_STATUS_E_NOMEM;
+			goto send_del_rsp;
+		}
+
+		wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
+				WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION);
+	}
+
+	return;
+
+send_del_rsp:
+	if (del_sta->respReqd) {
+		WMA_LOGD("%s: Sending del rsp to umac (status: %d)",
+			 __func__, del_sta->status);
+		wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
+					   (void *)del_sta, 0);
+	}
+}
+#endif
+
+/**
+ * wma_delete_sta_req_sta_mode() - process delete sta request from UMAC
+ * @wma: wma handle
+ * @params: delete sta params
+ *
+ * Return: none
+ */
+static void wma_delete_sta_req_sta_mode(tp_wma_handle wma,
+					tpDeleteStaParams params)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wma_txrx_node *iface;
+
+	iface = &wma->interfaces[params->smesessionId];
+	iface->uapsd_cached_val = 0;
+	if (wma_is_roam_synch_in_progress(wma, params->smesessionId))
+		return;
+#ifdef FEATURE_WLAN_TDLS
+	if (STA_ENTRY_TDLS_PEER == params->staType) {
+		wma_del_tdls_sta(wma, params);
+		return;
+	}
+#endif
+	params->status = status;
+	if (params->respReqd) {
+		WMA_LOGD("%s: vdev_id %d status %d", __func__,
+			 params->smesessionId, status);
+		wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
+					   (void *)params, 0);
+	}
+}
+
+/**
+ * wma_add_sta() - process add sta request as per opmode
+ * @wma: wma handle
+ * @add_Sta: add sta params
+ *
+ * Return: none
+ */
+void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta)
+{
+	uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA;
+	void *htc_handle;
+
+	htc_handle = lmac_get_htc_hdl(wma->psoc);
+	if (!htc_handle) {
+		WMA_LOGE(":%sHTC handle is NULL:%d", __func__, __LINE__);
+		return;
+	}
+
+	WMA_LOGD("%s: add_sta->sessionId = %d.", __func__,
+		 add_sta->smesessionId);
+	WMA_LOGD("%s: add_sta->bssId = %x:%x:%x:%x:%x:%x", __func__,
+		 add_sta->bssId[0], add_sta->bssId[1], add_sta->bssId[2],
+		 add_sta->bssId[3], add_sta->bssId[4], add_sta->bssId[5]);
+
+	if (wma_is_vdev_in_ap_mode(wma, add_sta->smesessionId))
+		oper_mode = BSS_OPERATIONAL_MODE_AP;
+	else if (wma_is_vdev_in_ibss_mode(wma, add_sta->smesessionId))
+		oper_mode = BSS_OPERATIONAL_MODE_IBSS;
+
+	if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, add_sta->smesessionId))
+		oper_mode = BSS_OPERATIONAL_MODE_NDI;
+	switch (oper_mode) {
+	case BSS_OPERATIONAL_MODE_STA:
+		wma_add_sta_req_sta_mode(wma, add_sta);
+		break;
+
+	/* IBSS should share the same code as AP mode */
+	case BSS_OPERATIONAL_MODE_IBSS:
+	case BSS_OPERATIONAL_MODE_AP:
+		htc_vote_link_up(htc_handle);
+		wma_add_sta_req_ap_mode(wma, add_sta);
+		break;
+	case BSS_OPERATIONAL_MODE_NDI:
+		wma_add_sta_ndi_mode(wma, add_sta);
+		break;
+	}
+
+#ifdef QCA_IBSS_SUPPORT
+	/* adjust heart beat thresold timer value for detecting ibss peer
+	 * departure
+	 */
+	if (oper_mode == BSS_OPERATIONAL_MODE_IBSS)
+		wma_adjust_ibss_heart_beat_timer(wma, add_sta->smesessionId, 1);
+#endif
+
+}
+
+/**
+ * wma_delete_sta() - process del sta request as per opmode
+ * @wma: wma handle
+ * @del_sta: delete sta params
+ *
+ * Return: none
+ */
+void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
+{
+	uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA;
+	uint8_t smesession_id = del_sta->smesessionId;
+	bool rsp_requested = del_sta->respReqd;
+	void *htc_handle;
+
+	htc_handle = lmac_get_htc_hdl(wma->psoc);
+	if (!htc_handle) {
+		WMA_LOGE(":%sHTC handle is NULL:%d", __func__, __LINE__);
+		return;
+	}
+
+	if (wma_is_vdev_in_ap_mode(wma, smesession_id))
+		oper_mode = BSS_OPERATIONAL_MODE_AP;
+	if (wma_is_vdev_in_ibss_mode(wma, smesession_id)) {
+		oper_mode = BSS_OPERATIONAL_MODE_IBSS;
+		WMA_LOGD("%s: to delete sta for IBSS mode", __func__);
+	}
+	if (del_sta->staType == STA_ENTRY_NDI_PEER)
+		oper_mode = BSS_OPERATIONAL_MODE_NDI;
+
+	WMA_LOGD(FL("oper_mode %d"), oper_mode);
+
+	switch (oper_mode) {
+	case BSS_OPERATIONAL_MODE_STA:
+		wma_delete_sta_req_sta_mode(wma, del_sta);
+		if (wma_is_roam_synch_in_progress(wma, smesession_id)) {
+			WMA_LOGD(FL("LFR3: Del STA on vdev_id %d"),
+				 del_sta->smesessionId);
+			qdf_mem_free(del_sta);
+			return;
+		}
+		if (!rsp_requested) {
+			WMA_LOGD(FL("vdev_id %d status %d"),
+				 del_sta->smesessionId, del_sta->status);
+			qdf_mem_free(del_sta);
+		}
+		break;
+
+	case BSS_OPERATIONAL_MODE_IBSS: /* IBSS shares AP code */
+	case BSS_OPERATIONAL_MODE_AP:
+		htc_vote_link_down(htc_handle);
+		wma_delete_sta_req_ap_mode(wma, del_sta);
+		/* free the memory here only if sync feature is not enabled */
+		if (!rsp_requested &&
+		    !wmi_service_enabled(wma->wmi_handle,
+				wmi_service_sync_delete_cmds)) {
+			WMA_LOGD(FL("vdev_id %d status %d"),
+				 del_sta->smesessionId, del_sta->status);
+			qdf_mem_free(del_sta);
+		} else if (!rsp_requested &&
+				(del_sta->status != QDF_STATUS_SUCCESS)) {
+			WMA_LOGD(FL("Release del_sta mem vdev_id %d status %d"),
+				 del_sta->smesessionId, del_sta->status);
+			qdf_mem_free(del_sta);
+		}
+		break;
+	case BSS_OPERATIONAL_MODE_NDI:
+		wma_delete_sta_req_ndi_mode(wma, del_sta);
+		break;
+	default:
+		WMA_LOGE(FL("Incorrect oper mode %d"), oper_mode);
+		qdf_mem_free(del_sta);
+	}
+
+#ifdef QCA_IBSS_SUPPORT
+	/* adjust heart beat thresold timer value for
+	 * detecting ibss peer departure
+	 */
+	if (oper_mode == BSS_OPERATIONAL_MODE_IBSS)
+		wma_adjust_ibss_heart_beat_timer(wma, smesession_id, -1);
+#endif
+}
+
+/**
+ * wma_delete_bss_ho_fail() - process delete bss request for handoff failure
+ * @wma: wma handle
+ * @params: del bss parameters
+ *
+ * Delete BSS in case of ROAM_HO_FAIL processing is handled separately in
+ * this routine. It needs to be done without sending any commands to firmware
+ * because firmware has already stopped and deleted peer and vdev is down.
+ * Relevant logic is aggregated from other routines. It changes the host
+ * data structures without sending VDEV_STOP, PEER_FLUSH_TIDS, PEER_DELETE
+ * and VDEV_DOWN commands to firmware.
+ *
+ * Return: none
+ */
+void wma_delete_bss_ho_fail(tp_wma_handle wma, tpDeleteBssParams params)
+{
+	struct cdp_pdev *pdev;
+	void *peer = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t peer_id;
+	struct cdp_vdev *txrx_vdev = NULL;
+	struct wma_txrx_node *iface;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s:Unable to get TXRX context", __func__);
+		goto fail_del_bss_ho_fail;
+	}
+
+	peer = cdp_peer_find_by_addr(soc,
+			pdev,
+			params->bssid, &peer_id);
+	if (!peer) {
+		WMA_LOGE("%s: Failed to find peer %pM", __func__,
+			 params->bssid);
+		status = QDF_STATUS_E_FAILURE;
+		goto fail_del_bss_ho_fail;
+	}
+
+	iface = &wma->interfaces[params->smesessionId];
+	if (!iface || !iface->handle) {
+		WMA_LOGE("%s vdev id %d is already deleted",
+				__func__, params->smesessionId);
+		goto fail_del_bss_ho_fail;
+	}
+	qdf_mem_zero(iface->bssid, IEEE80211_ADDR_LEN);
+
+	txrx_vdev = wma_find_vdev_by_id(wma, params->smesessionId);
+	if (!txrx_vdev) {
+		WMA_LOGE("%s:Invalid vdev handle", __func__);
+		status = QDF_STATUS_E_FAILURE;
+		goto fail_del_bss_ho_fail;
+	}
+
+	/* Free the allocated stats response buffer for the the session */
+	if (iface->stats_rsp) {
+		qdf_mem_free(iface->stats_rsp);
+		iface->stats_rsp = NULL;
+	}
+
+	if (iface->psnr_req) {
+		qdf_mem_free(iface->psnr_req);
+		iface->psnr_req = NULL;
+	}
+
+	if (iface->rcpi_req) {
+		struct sme_rcpi_req *rcpi_req = iface->rcpi_req;
+
+		iface->rcpi_req = NULL;
+		qdf_mem_free(rcpi_req);
+	}
+
+	if (iface->roam_scan_stats_req) {
+		struct sir_roam_scan_stats *roam_scan_stats_req =
+						iface->roam_scan_stats_req;
+
+		iface->roam_scan_stats_req = NULL;
+		qdf_mem_free(roam_scan_stats_req);
+	}
+
+	qdf_mem_zero(&iface->ns_offload_req,
+			sizeof(iface->ns_offload_req));
+	qdf_mem_zero(&iface->arp_offload_req,
+			sizeof(iface->arp_offload_req));
+
+	WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)",
+		 __func__, params->smesessionId);
+	cdp_fc_vdev_pause(soc, iface->handle,
+			   OL_TXQ_PAUSE_REASON_VDEV_STOP);
+	wma_vdev_set_pause_bit(params->smesessionId, PAUSE_TYPE_HOST);
+
+	cdp_fc_vdev_flush(soc, iface->handle);
+	WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp",
+			__func__, params->smesessionId);
+	cdp_fc_vdev_unpause(soc, iface->handle,
+			OL_TXQ_PAUSE_REASON_VDEV_STOP);
+	wma_vdev_clear_pause_bit(params->smesessionId, PAUSE_TYPE_HOST);
+	qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
+	WMA_LOGD("%s: (type %d subtype %d) BSS is stopped",
+			__func__, iface->type, iface->sub_type);
+#ifndef CONFIG_VDEV_SM
+	wma_vdev_set_mlme_state(wma, params->smesessionId, WLAN_VDEV_S_STOP);
+#endif
+	params->status = QDF_STATUS_SUCCESS;
+	if (!iface->peer_count) {
+		WMA_LOGE("%s: Can't remove peer with peer_addr %pM vdevid %d peer_count %d",
+			__func__, params->bssid,  params->smesessionId,
+			iface->peer_count);
+		goto fail_del_bss_ho_fail;
+	}
+
+	if (peer) {
+		WMA_LOGD("%s: vdev %pK is detaching peer:%pK peer_addr %pM to vdev_id %d, peer_count - %d",
+			 __func__, txrx_vdev, peer, params->bssid,
+			 params->smesessionId, iface->peer_count);
+		cdp_peer_delete(soc, peer, 1 << CDP_PEER_DELETE_NO_SPECIAL);
+		wma_remove_objmgr_peer(wma, params->smesessionId,
+							params->bssid);
+	}
+	iface->peer_count--;
+
+	WMA_LOGI("%s: Removed peer %pK with peer_addr %pM vdevid %d peer_count %d",
+		 __func__, peer, params->bssid,  params->smesessionId,
+		 iface->peer_count);
+fail_del_bss_ho_fail:
+	params->status = status;
+	wma_send_msg_high_priority(wma, WMA_DELETE_BSS_HO_FAIL_RSP,
+				   (void *)params, 0);
+}
+
+/**
+ * wma_wait_tx_complete() - Wait till tx packets are drained
+ * @wma: wma handle
+ * @session_id: vdev id
+ *
+ * Return: none
+ */
+static void wma_wait_tx_complete(tp_wma_handle wma,
+				uint32_t session_id)
+{
+	struct cdp_pdev *pdev;
+	uint8_t max_wait_iterations = 0;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!wma_is_vdev_valid(session_id)) {
+		WMA_LOGE("%s: Vdev is not valid: %d",
+			 __func__, session_id);
+		return;
+	}
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (pdev == NULL) {
+		WMA_LOGE("%s: pdev is not valid: %d",
+			 __func__, session_id);
+		return;
+	}
+	max_wait_iterations =
+		wma->interfaces[session_id].delay_before_vdev_stop /
+		WMA_TX_Q_RECHECK_TIMER_WAIT;
+
+	while (cdp_get_tx_pending(soc, pdev) && max_wait_iterations) {
+		WMA_LOGW(FL("Waiting for outstanding packet to drain."));
+		qdf_wait_for_event_completion(&wma->tx_queue_empty_event,
+				      WMA_TX_Q_RECHECK_TIMER_WAIT);
+		max_wait_iterations--;
+	}
+}
+/**
+ * wma_delete_bss() - process delete bss request from upper layer
+ * @wma: wma handle
+ * @params: del bss parameters
+ *
+ * Return: none
+ */
+void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params)
+{
+	struct cdp_pdev *pdev;
+	void *peer = NULL;
+	struct wma_target_req *msg;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t peer_id;
+	struct cdp_vdev *txrx_vdev = NULL;
+	bool roam_synch_in_progress = false;
+	struct wma_txrx_node *iface;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s:Unable to get TXRX context", __func__);
+		goto out;
+	}
+	if (wma_is_vdev_in_ibss_mode(wma, params->smesessionId))
+		/* in rome ibss case, self mac is used to create the bss peer */
+		peer = cdp_peer_find_by_addr(soc,
+			pdev,
+			wma->interfaces[params->smesessionId].addr,
+			&peer_id);
+	else if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces,
+			params->smesessionId))
+		/* In ndi case, self mac is used to create the self peer */
+		peer = cdp_peer_find_by_addr(soc, pdev,
+				wma->interfaces[params->smesessionId].addr,
+				&peer_id);
+	else
+		peer = cdp_peer_find_by_addr(soc, pdev,
+				params->bssid,
+				&peer_id);
+
+	if (!peer) {
+		WMA_LOGE("%s: Failed to find peer %pM", __func__,
+			 params->bssid);
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	qdf_mem_zero(wma->interfaces[params->smesessionId].bssid,
+			IEEE80211_ADDR_LEN);
+
+	txrx_vdev = wma_find_vdev_by_id(wma, params->smesessionId);
+	if (!txrx_vdev) {
+		WMA_LOGE("%s:Invalid vdev handle", __func__);
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	iface = &wma->interfaces[params->smesessionId];
+	if (!iface || !iface->handle) {
+		WMA_LOGE("%s vdev id %d is already deleted",
+				__func__, params->smesessionId);
+		goto out;
+	}
+	/*Free the allocated stats response buffer for the the session */
+	if (iface->stats_rsp) {
+		qdf_mem_free(iface->stats_rsp);
+		iface->stats_rsp = NULL;
+	}
+
+	if (iface->psnr_req) {
+		qdf_mem_free(iface->psnr_req);
+		iface->psnr_req = NULL;
+	}
+
+	if (iface->rcpi_req) {
+		struct sme_rcpi_req *rcpi_req = iface->rcpi_req;
+
+		iface->rcpi_req = NULL;
+		qdf_mem_free(rcpi_req);
+	}
+
+	if (iface->roam_scan_stats_req) {
+		struct sir_roam_scan_stats *roam_scan_stats_req =
+						iface->roam_scan_stats_req;
+
+		iface->roam_scan_stats_req = NULL;
+		qdf_mem_free(roam_scan_stats_req);
+	}
+
+	if (wlan_op_mode_ibss == cdp_get_opmode(soc, txrx_vdev))
+		wma->ibss_started = 0;
+
+	if (wma_is_roam_synch_in_progress(wma, params->smesessionId)) {
+		roam_synch_in_progress = true;
+		WMA_LOGD("LFR3:%s: Setting vdev_up to FALSE for session %d",
+			__func__, params->smesessionId);
+#ifndef CONFIG_VDEV_SM
+		wma_vdev_set_mlme_state(wma, params->smesessionId,
+			WLAN_VDEV_S_STOP);
+#endif
+		goto detach_peer;
+	}
+	msg = wma_fill_vdev_req(wma, params->smesessionId, WMA_DELETE_BSS_REQ,
+				WMA_TARGET_REQ_TYPE_VDEV_STOP, params,
+				WMA_VDEV_STOP_REQUEST_TIMEOUT);
+	if (!msg) {
+		WMA_LOGE("%s: Failed to fill vdev request for vdev_id %d",
+			 __func__, params->smesessionId);
+		status = QDF_STATUS_E_NOMEM;
+		goto detach_peer;
+	}
+
+	WMA_LOGD(FL("Outstanding msdu packets: %d"),
+		 cdp_get_tx_pending(soc, pdev));
+	wma_wait_tx_complete(wma, params->smesessionId);
+
+	if (cdp_get_tx_pending(soc, pdev)) {
+		WMA_LOGW(FL("Outstanding msdu packets before VDEV_STOP : %d"),
+			 cdp_get_tx_pending(soc, pdev));
+	}
+
+	WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)",
+		 __func__, params->smesessionId);
+	wma_vdev_set_pause_bit(params->smesessionId, PAUSE_TYPE_HOST);
+	cdp_fc_vdev_pause(soc,
+		wma->interfaces[params->smesessionId].handle,
+		OL_TXQ_PAUSE_REASON_VDEV_STOP);
+
+	if (wma_send_vdev_stop_to_fw(wma, params->smesessionId)) {
+		WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__);
+		wma_remove_vdev_req(wma, params->smesessionId,
+				WMA_TARGET_REQ_TYPE_VDEV_STOP);
+		status = QDF_STATUS_E_FAILURE;
+		goto detach_peer;
+		}
+	WMA_LOGD("%s: bssid %pM vdev_id %d",
+		 __func__, params->bssid, params->smesessionId);
+	return;
+detach_peer:
+	wma_remove_peer(wma, params->bssid, params->smesessionId, peer,
+			roam_synch_in_progress);
+	if (wma_is_roam_synch_in_progress(wma, params->smesessionId))
+		return;
+
+out:
+	params->status = status;
+	wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP, (void *)params, 0);
+}
+
+/**
+ * wma_find_ibss_vdev() - This function finds vdev_id based on input type
+ * @wma: wma handle
+ * @type: vdev type
+ *
+ * Return: vdev id
+ */
+int32_t wma_find_vdev_by_type(tp_wma_handle wma, int32_t type)
+{
+	int32_t vdev_id = 0;
+	struct wma_txrx_node *intf = wma->interfaces;
+
+	for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
+		if (NULL != intf) {
+			if (intf[vdev_id].type == type)
+				return vdev_id;
+		}
+	}
+
+	return -EFAULT;
+}
+
+/**
+ * wma_set_vdev_intrabss_fwd() - set intra_fwd value to wni_in.
+ * @wma_handle: wma handle
+ * @pdis_intra_fwd: Pointer to DisableIntraBssFwd struct
+ *
+ * Return: none
+ */
+void wma_set_vdev_intrabss_fwd(tp_wma_handle wma_handle,
+				      tpDisableIntraBssFwd pdis_intra_fwd)
+{
+	struct cdp_vdev *txrx_vdev;
+
+	WMA_LOGD("%s:intra_fwd:vdev(%d) intrabss_dis=%s",
+		 __func__, pdis_intra_fwd->sessionId,
+		 (pdis_intra_fwd->disableintrabssfwd ? "true" : "false"));
+
+	txrx_vdev = wma_handle->interfaces[pdis_intra_fwd->sessionId].handle;
+	cdp_cfg_vdev_rx_set_intrabss_fwd(cds_get_context(QDF_MODULE_ID_SOC),
+				    txrx_vdev,
+				    pdis_intra_fwd->disableintrabssfwd);
+}
+
+void wma_store_pdev(void *wma_ctx, struct wlan_objmgr_pdev *pdev)
+{
+	tp_wma_handle wma = (tp_wma_handle)wma_ctx;
+	QDF_STATUS status;
+
+	status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_LEGACY_WMA_ID);
+	if (QDF_STATUS_SUCCESS != status) {
+		wma->pdev = NULL;
+		return;
+	}
+
+	wma->pdev = pdev;
+}
+
+/**
+ * wma_vdev_reset_beacon_interval_timer() - reset beacon interval back
+ * to its original value after the channel switch.
+ *
+ * @data: data
+ *
+ * Return: void
+ */
+static void wma_vdev_reset_beacon_interval_timer(void *data)
+{
+	tp_wma_handle wma;
+	struct wma_beacon_interval_reset_req *req =
+		(struct wma_beacon_interval_reset_req *)data;
+	uint16_t beacon_interval = req->interval;
+	uint8_t vdev_id = req->vdev_id;
+
+	wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+	if (NULL == wma) {
+		WMA_LOGE("%s: Failed to get wma", __func__);
+		goto end;
+	}
+
+	/* Change the beacon interval back to its original value */
+	WMA_LOGE("%s: Change beacon interval back to %d",
+			__func__, beacon_interval);
+	wma_update_beacon_interval(wma, vdev_id, beacon_interval);
+
+end:
+	qdf_timer_stop(&req->event_timeout);
+	qdf_timer_free(&req->event_timeout);
+	qdf_mem_free(req);
+}
+
+int wma_fill_beacon_interval_reset_req(tp_wma_handle wma, uint8_t vdev_id,
+				uint16_t beacon_interval, uint32_t timeout)
+{
+	struct wma_beacon_interval_reset_req *req;
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return -ENOMEM;
+
+	WMA_LOGD("%s: vdev_id %d ", __func__, vdev_id);
+	req->vdev_id = vdev_id;
+	req->interval = beacon_interval;
+	qdf_timer_init(NULL, &req->event_timeout,
+		wma_vdev_reset_beacon_interval_timer, req, QDF_TIMER_TYPE_SW);
+	qdf_timer_start(&req->event_timeout, timeout);
+
+	return 0;
+}
+
+QDF_STATUS wma_set_wlm_latency_level(void *wma_ptr,
+			struct wlm_latency_level_param *latency_params)
+{
+	QDF_STATUS ret;
+	tp_wma_handle wma = (tp_wma_handle)wma_ptr;
+
+	WMA_LOGD("%s: set latency level %d, flags flag 0x%x",
+		 __func__, latency_params->wlm_latency_level,
+		 latency_params->wlm_latency_flags);
+
+	ret = wmi_unified_wlm_latency_level_cmd(wma->wmi_handle,
+						latency_params);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGW("Failed to set latency level");
+
+	return ret;
+}
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
new file mode 100644
index 0000000..ff01e67
--- /dev/null
+++ b/core/wma/src/wma_features.c
@@ -0,0 +1,5861 @@
+/*
+ * Copyright (c) 2013-2018 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:    wma_features.c
+ *  This file contains different features related functions like WoW,
+ *  Offloads, TDLS etc.
+ */
+
+/* Header files */
+
+#include "cds_ieee80211_common.h"	/* ieee80211_frame */
+#include "wma.h"
+#include "wma_api.h"
+#include "cds_api.h"
+#include "wmi_unified_api.h"
+#include "wlan_qct_sys.h"
+#include "wni_api.h"
+#include "ani_global.h"
+#include "wmi_unified.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include <cdp_txrx_tx_delay.h>
+#include <cdp_txrx_peer_ops.h>
+
+#include "qdf_nbuf.h"
+#include "qdf_types.h"
+#include "qdf_mem.h"
+#include "qdf_util.h"
+
+#include "wma_types.h"
+#include "lim_api.h"
+#include "lim_session_utils.h"
+
+#include "cds_utils.h"
+
+#if !defined(REMOVE_PKT_LOG)
+#include "pktlog_ac.h"
+#endif /* REMOVE_PKT_LOG */
+
+#include "dbglog_host.h"
+#include "csr_api.h"
+#include "ol_fw.h"
+
+#include "wma_internal.h"
+#include "wma_nan_datapath.h"
+#include <cdp_txrx_handle.h>
+#include "wlan_pmo_ucfg_api.h"
+#include <target_if_scan.h>
+#include "wlan_reg_services_api.h"
+#include "wlan_roam_debug.h"
+#include <wlan_cp_stats_mc_ucfg_api.h>
+
+#ifndef ARRAY_LENGTH
+#define ARRAY_LENGTH(a)         (sizeof(a) / sizeof((a)[0]))
+#endif
+
+/**
+ * WMA_SET_VDEV_IE_SOURCE_HOST - Flag to identify the source of VDEV SET IE
+ * command. The value is 0x0 for the VDEV SET IE WMI commands from mobile
+ * MCL platform.
+ */
+#define WMA_SET_VDEV_IE_SOURCE_HOST 0x0
+
+
+#if defined(FEATURE_WLAN_DIAG_SUPPORT)
+/**
+ * qdf_wma_wow_wakeup_stats_event()- send wow wakeup stats
+ * @tp_wma_handle wma: WOW wakeup packet counter
+ *
+ * This function sends wow wakeup stats diag event
+ *
+ * Return: void.
+ */
+#ifdef QCA_SUPPORT_CP_STATS
+static inline void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma)
+{
+	QDF_STATUS status;
+	struct wake_lock_stats stats = {0};
+
+	WLAN_HOST_DIAG_EVENT_DEF(wow_stats,
+	struct host_event_wlan_powersave_wow_stats);
+
+	status = ucfg_mc_cp_stats_get_psoc_wake_lock_stats(wma->psoc, &stats);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+	qdf_mem_zero(&wow_stats, sizeof(wow_stats));
+
+	wow_stats.wow_bcast_wake_up_count = stats.bcast_wake_up_count;
+	wow_stats.wow_ipv4_mcast_wake_up_count = stats.ipv4_mcast_wake_up_count;
+	wow_stats.wow_ipv6_mcast_wake_up_count = stats.ipv6_mcast_wake_up_count;
+	wow_stats.wow_ipv6_mcast_ra_stats = stats.ipv6_mcast_ra_stats;
+	wow_stats.wow_ipv6_mcast_ns_stats = stats.ipv6_mcast_ns_stats;
+	wow_stats.wow_ipv6_mcast_na_stats = stats.ipv6_mcast_na_stats;
+	wow_stats.wow_pno_match_wake_up_count = stats.pno_match_wake_up_count;
+	wow_stats.wow_pno_complete_wake_up_count =
+				stats.pno_complete_wake_up_count;
+	wow_stats.wow_gscan_wake_up_count = stats.gscan_wake_up_count;
+	wow_stats.wow_low_rssi_wake_up_count = stats.low_rssi_wake_up_count;
+	wow_stats.wow_rssi_breach_wake_up_count =
+				stats.rssi_breach_wake_up_count;
+	wow_stats.wow_icmpv4_count = stats.icmpv4_count;
+	wow_stats.wow_icmpv6_count = stats.icmpv6_count;
+	wow_stats.wow_oem_response_wake_up_count =
+				stats.oem_response_wake_up_count;
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&wow_stats, EVENT_WLAN_POWERSAVE_WOW_STATS);
+}
+#else /* QCA_SUPPORT_CP_STATS*/
+static inline void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma)
+{
+	QDF_STATUS status;
+	struct sir_wake_lock_stats stats;
+
+	WLAN_HOST_DIAG_EVENT_DEF(WowStats,
+	struct host_event_wlan_powersave_wow_stats);
+
+	status = wma_get_wakelock_stats(&stats);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+	qdf_mem_zero(&WowStats, sizeof(WowStats));
+
+	WowStats.wow_bcast_wake_up_count =
+		stats.wow_bcast_wake_up_count;
+	WowStats.wow_ipv4_mcast_wake_up_count =
+		stats.wow_ipv4_mcast_wake_up_count;
+	WowStats.wow_ipv6_mcast_wake_up_count =
+		stats.wow_ipv6_mcast_wake_up_count;
+	WowStats.wow_ipv6_mcast_ra_stats =
+		stats.wow_ipv6_mcast_ra_stats;
+	WowStats.wow_ipv6_mcast_ns_stats =
+		stats.wow_ipv6_mcast_ns_stats;
+	WowStats.wow_ipv6_mcast_na_stats =
+		stats.wow_ipv6_mcast_na_stats;
+	WowStats.wow_pno_match_wake_up_count =
+		stats.wow_pno_match_wake_up_count;
+	WowStats.wow_pno_complete_wake_up_count =
+		stats.wow_pno_complete_wake_up_count;
+	WowStats.wow_gscan_wake_up_count =
+		stats.wow_gscan_wake_up_count;
+	WowStats.wow_low_rssi_wake_up_count =
+		stats.wow_low_rssi_wake_up_count;
+	WowStats.wow_rssi_breach_wake_up_count =
+		stats.wow_rssi_breach_wake_up_count;
+	WowStats.wow_icmpv4_count =
+		stats.wow_icmpv4_count;
+	WowStats.wow_icmpv6_count =
+		stats.wow_icmpv6_count;
+	WowStats.wow_oem_response_wake_up_count =
+		stats.wow_oem_response_wake_up_count;
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&WowStats, EVENT_WLAN_POWERSAVE_WOW_STATS);
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+#else
+static inline void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma)
+{
+	return;
+}
+#endif
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+/**
+ * wma_post_auto_shutdown_msg() - to post auto shutdown event to sme
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_wake_reason_auto_shutdown(void)
+{
+	tSirAutoShutdownEvtParams *auto_sh_evt;
+	QDF_STATUS qdf_status;
+	struct scheduler_msg sme_msg = { 0 };
+
+	auto_sh_evt = qdf_mem_malloc(sizeof(tSirAutoShutdownEvtParams));
+	if (!auto_sh_evt)
+		return -ENOMEM;
+
+	auto_sh_evt->shutdown_reason =
+		WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY;
+	sme_msg.type = eWNI_SME_AUTO_SHUTDOWN_IND;
+	sme_msg.bodyptr = auto_sh_evt;
+	sme_msg.bodyval = 0;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("Fail to post eWNI_SME_AUTO_SHUTDOWN_IND msg to SME");
+		qdf_mem_free(auto_sh_evt);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#else
+static inline int wma_wake_reason_auto_shutdown(void)
+{
+	return 0;
+}
+#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+static int wma_wake_reason_nlod(t_wma_handle *wma, uint8_t vdev_id)
+{
+	wmi_nlo_event nlo_event = { .vdev_id = vdev_id };
+	WMI_NLO_MATCH_EVENTID_param_tlvs param = { .fixed_param = &nlo_event };
+
+	return target_if_nlo_match_event_handler(wma, (uint8_t *)&param,
+						 sizeof(param));
+}
+#else
+static inline int wma_wake_reason_nlod(uint8_t vdev_id)
+{
+	return 0;
+}
+#endif /* FEATURE_WLAN_SCAN_PNO */
+
+/**
+ * wma_send_snr_request() - send request to fw to get RSSI stats
+ * @wma_handle: wma handle
+ * @pGetRssiReq: get RSSI request
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_send_snr_request(tp_wma_handle wma_handle,
+				void *pGetRssiReq)
+{
+	tAniGetRssiReq *pRssiBkUp = NULL;
+
+	/* command is in progress */
+	if (NULL != wma_handle->pGetRssiReq)
+		return QDF_STATUS_SUCCESS;
+
+	/* create a copy of csrRssiCallback to send rssi value
+	 * after wmi event
+	 */
+	if (pGetRssiReq) {
+		pRssiBkUp = qdf_mem_malloc(sizeof(tAniGetRssiReq));
+		if (!pRssiBkUp) {
+			wma_handle->pGetRssiReq = NULL;
+			return QDF_STATUS_E_NOMEM;
+		}
+		pRssiBkUp->sessionId =
+			((tAniGetRssiReq *) pGetRssiReq)->sessionId;
+		pRssiBkUp->rssiCallback =
+			((tAniGetRssiReq *) pGetRssiReq)->rssiCallback;
+		pRssiBkUp->pDevContext =
+			((tAniGetRssiReq *) pGetRssiReq)->pDevContext;
+		wma_handle->pGetRssiReq = (void *)pRssiBkUp;
+	}
+
+	if (wmi_unified_snr_request_cmd(wma_handle->wmi_handle)) {
+		WMA_LOGE("Failed to send host stats request to fw");
+		qdf_mem_free(pRssiBkUp);
+		wma_handle->pGetRssiReq = NULL;
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_get_snr() - get RSSI from fw
+ * @psnr_req: request params
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_get_snr(tAniGetSnrReq *psnr_req)
+{
+	tAniGetSnrReq *psnr_req_bkp;
+	tp_wma_handle wma_handle = NULL;
+	struct wma_txrx_node *intr;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s : Failed to get wma_handle", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	intr = &wma_handle->interfaces[psnr_req->sessionId];
+	/* command is in progress */
+	if (NULL != intr->psnr_req) {
+		WMA_LOGE("%s : previous snr request is pending", __func__);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	psnr_req_bkp = qdf_mem_malloc(sizeof(tAniGetSnrReq));
+	if (!psnr_req_bkp)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_set(psnr_req_bkp, sizeof(tAniGetSnrReq), 0);
+	psnr_req_bkp->staId = psnr_req->staId;
+	psnr_req_bkp->pDevContext = psnr_req->pDevContext;
+	psnr_req_bkp->snrCallback = psnr_req->snrCallback;
+	intr->psnr_req = (void *)psnr_req_bkp;
+
+	if (wmi_unified_snr_cmd(wma_handle->wmi_handle,
+				 psnr_req->sessionId)) {
+		WMA_LOGE("Failed to send host stats request to fw");
+		qdf_mem_free(psnr_req_bkp);
+		intr->psnr_req = NULL;
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_link_status_req() - process link status request from UMAC
+ * @wma: wma handle
+ * @pGetLinkStatus: get link params
+ *
+ * Return: none
+ */
+void wma_process_link_status_req(tp_wma_handle wma,
+				 tAniGetLinkStatus *pGetLinkStatus)
+{
+	struct link_status_params cmd = {0};
+	struct wma_txrx_node *iface =
+		&wma->interfaces[pGetLinkStatus->sessionId];
+
+	if (iface->plink_status_req) {
+		WMA_LOGE("%s:previous link status request is pending,deleting the new request",
+			__func__);
+		qdf_mem_free(pGetLinkStatus);
+		return;
+	}
+
+	iface->plink_status_req = pGetLinkStatus;
+	cmd.session_id = pGetLinkStatus->sessionId;
+	if (wmi_unified_link_status_req_cmd(wma->wmi_handle, &cmd)) {
+		WMA_LOGE("Failed to send WMI link  status request to fw");
+		iface->plink_status_req = NULL;
+		goto end;
+	}
+
+	return;
+
+end:
+	wma_post_link_status(pGetLinkStatus, LINK_STATUS_LEGACY);
+}
+
+#ifdef WLAN_FEATURE_TSF
+/**
+ * wma_vdev_tsf_handler() - handle tsf event indicated by FW
+ * @handle: wma context
+ * @data: event buffer
+ * @data len: length of event buffer
+ *
+ * Return: 0 on success
+ */
+int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len)
+{
+	struct scheduler_msg tsf_msg = {0};
+	WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf;
+	wmi_vdev_tsf_report_event_fixed_param *tsf_event;
+	struct stsf *ptsf;
+
+	if (data == NULL) {
+		WMA_LOGE("%s: invalid pointer", __func__);
+		return -EINVAL;
+	}
+	ptsf = qdf_mem_malloc(sizeof(*ptsf));
+	if (!ptsf)
+		return -ENOMEM;
+
+	param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)data;
+	tsf_event = param_buf->fixed_param;
+
+	ptsf->vdev_id = tsf_event->vdev_id;
+	ptsf->tsf_low = tsf_event->tsf_low;
+	ptsf->tsf_high = tsf_event->tsf_high;
+	ptsf->soc_timer_low = tsf_event->qtimer_low;
+	ptsf->soc_timer_high = tsf_event->qtimer_high;
+
+	wma_nofl_debug("receive WMI_VDEV_TSF_REPORT_EVENTID on %d, tsf: %d %d",
+		       ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high);
+
+	tsf_msg.type = eWNI_SME_TSF_EVENT;
+	tsf_msg.bodyptr = ptsf;
+	tsf_msg.bodyval = 0;
+
+	if (QDF_STATUS_SUCCESS !=
+		scheduler_post_message(QDF_MODULE_ID_WMA,
+				       QDF_MODULE_ID_SME,
+				       QDF_MODULE_ID_SME, &tsf_msg)) {
+
+		WMA_LOGP("%s: Failed to post eWNI_SME_TSF_EVENT", __func__);
+		qdf_mem_free(ptsf);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+#ifdef QCA_WIFI_3_0
+#define TSF_FW_ACTION_CMD TSF_TSTAMP_QTIMER_CAPTURE_REQ
+#else
+#define TSF_FW_ACTION_CMD TSF_TSTAMP_CAPTURE_REQ
+#endif
+/**
+ * wma_capture_tsf() - send wmi to fw to capture tsf
+ * @wma_handle: wma handler
+ * @vdev_id: vdev id
+ *
+ * Return: wmi send state
+ */
+QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	wmi_buf_t buf;
+	wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
+	int ret;
+	int len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) wmi_buf_data(buf);
+	cmd->vdev_id = vdev_id;
+	cmd->tsf_action = TSF_FW_ACTION_CMD;
+	WMA_LOGD("%s :vdev_id %u, tsf_cmd: %d", __func__, cmd->vdev_id,
+						cmd->tsf_action);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
+	WMITLV_GET_STRUCT_TLVLEN(
+	wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
+
+	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+				   WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
+	if (ret != EOK) {
+		status = QDF_STATUS_E_FAILURE;
+		goto error;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+error:
+	if (buf)
+		wmi_buf_free(buf);
+	return status;
+}
+
+/**
+ * wma_reset_tsf_gpio() - send wmi to fw to reset GPIO
+ * @wma_handle: wma handler
+ * @vdev_id: vdev id
+ *
+ * Return: wmi send state
+ */
+QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	wmi_buf_t buf;
+	wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
+	int ret;
+	int len = sizeof(*cmd);
+	uint8_t *buf_ptr;
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+	cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) buf_ptr;
+	cmd->vdev_id = vdev_id;
+	cmd->tsf_action = TSF_TSTAMP_CAPTURE_RESET;
+
+	WMA_LOGD("%s :vdev_id %u, TSF_TSTAMP_CAPTURE_RESET", __func__,
+		 cmd->vdev_id);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+				wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
+
+	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+				   WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
+
+	if (ret != EOK) {
+		status = QDF_STATUS_E_FAILURE;
+		goto error;
+	}
+	return QDF_STATUS_SUCCESS;
+
+error:
+	if (buf)
+		wmi_buf_free(buf);
+	return status;
+}
+
+/**
+ * wma_set_tsf_gpio_pin() - send wmi cmd to configure gpio pin
+ * @handle: wma handler
+ * @pin: GPIO pin id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_set_tsf_gpio_pin(WMA_HANDLE handle, uint32_t pin)
+{
+	tp_wma_handle wma = (tp_wma_handle)handle;
+	struct pdev_params pdev_param = {0};
+	int32_t ret;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not set gpio", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	WMA_LOGD("%s: set tsf gpio pin: %d", __func__, pin);
+
+	pdev_param.param_id = WMI_PDEV_PARAM_WNTS_CONFIG;
+	pdev_param.param_value = pin;
+	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
+					 &pdev_param,
+					 WMA_WILDCARD_PDEV_ID);
+	if (ret) {
+		WMA_LOGE("%s: Failed to set tsf gpio pin (%d)", __func__, ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * wma_set_wisa_params(): Set WISA features related params in FW
+ * @wma_handle: WMA handle
+ * @wisa: Pointer to WISA param struct
+ *
+ * Return: CDF status
+ */
+QDF_STATUS wma_set_wisa_params(tp_wma_handle wma_handle,
+				struct sir_wisa_params *wisa)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	wmi_buf_t buf;
+	wmi_vdev_wisa_cmd_fixed_param *cmd;
+	int ret, len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_vdev_wisa_cmd_fixed_param *) wmi_buf_data(buf);
+	cmd->wisa_mode = wisa->mode;
+	cmd->vdev_id = wisa->vdev_id;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_vdev_wisa_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+				wmi_vdev_wisa_cmd_fixed_param));
+
+	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+				   WMI_VDEV_WISA_CMDID);
+	if (ret != EOK) {
+		status = QDF_STATUS_E_FAILURE;
+		goto error;
+	}
+	return QDF_STATUS_SUCCESS;
+
+error:
+	wmi_buf_free(buf);
+	return status;
+}
+
+/**
+ * wma_process_dhcp_ind() - process dhcp indication from SME
+ * @wma_handle: wma handle
+ * @ta_dhcp_ind: DHCP indication
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wma_process_dhcp_ind(WMA_HANDLE handle,
+				tAniDHCPInd *ta_dhcp_ind)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	uint8_t vdev_id;
+	int status = 0;
+	wmi_peer_set_param_cmd_fixed_param peer_set_param_fp = {0};
+
+	if (!wma_handle) {
+		WMA_LOGE("%s : wma_handle is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!ta_dhcp_ind) {
+		WMA_LOGE("%s : DHCP indication is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!wma_find_vdev_by_addr(wma_handle,
+				   ta_dhcp_ind->adapterMacAddr.bytes,
+				   &vdev_id)) {
+		WMA_LOGE("%s: Failed to find vdev id for DHCP indication",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("%s: WMA --> WMI_PEER_SET_PARAM triggered by DHCP, msgType=%s, device_mode=%d, macAddr=" MAC_ADDRESS_STR,
+		__func__, ta_dhcp_ind->msgType == WMA_DHCP_START_IND ?
+		"WMA_DHCP_START_IND" : "WMA_DHCP_STOP_IND",
+		ta_dhcp_ind->device_mode,
+		MAC_ADDR_ARRAY(ta_dhcp_ind->peerMacAddr.bytes));
+
+	/* fill in values */
+	peer_set_param_fp.vdev_id = vdev_id;
+	peer_set_param_fp.param_id = WMI_PEER_CRIT_PROTO_HINT_ENABLED;
+	if (WMA_DHCP_START_IND == ta_dhcp_ind->msgType)
+		peer_set_param_fp.param_value = 1;
+	else
+		peer_set_param_fp.param_value = 0;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(ta_dhcp_ind->peerMacAddr.bytes,
+				   &peer_set_param_fp.peer_macaddr);
+
+	status = wmi_unified_process_dhcp_ind(wma_handle->wmi_handle,
+						&peer_set_param_fp);
+	if (status != EOK)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_chan_phy__mode() - get WLAN_PHY_MODE for channel
+ * @chan: channel number
+ * @chan_width: maximum channel width possible
+ * @dot11_mode: maximum phy_mode possible
+ *
+ * Return: return WLAN_PHY_MODE
+ */
+WLAN_PHY_MODE wma_chan_phy_mode(uint8_t chan, enum phy_ch_width chan_width,
+				uint8_t dot11_mode)
+{
+	WLAN_PHY_MODE phymode = MODE_UNKNOWN;
+	uint16_t bw_val = wlan_reg_get_bw_value(chan_width);
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma) {
+		WMA_LOGE("%s : wma_handle is NULL", __func__);
+		return MODE_UNKNOWN;
+	}
+
+	if (chan_width >= CH_WIDTH_INVALID) {
+		WMA_LOGE("%s : Invalid channel width", __func__);
+		return MODE_UNKNOWN;
+	}
+
+	if (WLAN_REG_IS_24GHZ_CH(chan)) {
+		if (((CH_WIDTH_5MHZ == chan_width) ||
+		     (CH_WIDTH_10MHZ == chan_width)) &&
+		    ((WNI_CFG_DOT11_MODE_11B == dot11_mode) ||
+		     (WNI_CFG_DOT11_MODE_11G == dot11_mode) ||
+		     (WNI_CFG_DOT11_MODE_11N == dot11_mode) ||
+		     (WNI_CFG_DOT11_MODE_ALL == dot11_mode) ||
+		     (WNI_CFG_DOT11_MODE_11AC == dot11_mode) ||
+		     (WNI_CFG_DOT11_MODE_11AX == dot11_mode)))
+			phymode = MODE_11G;
+		else {
+			switch (dot11_mode) {
+			case WNI_CFG_DOT11_MODE_11B:
+				if ((bw_val == 20) || (bw_val == 40))
+					phymode = MODE_11B;
+				break;
+			case WNI_CFG_DOT11_MODE_11G:
+				if ((bw_val == 20) || (bw_val == 40))
+					phymode = MODE_11G;
+				break;
+			case WNI_CFG_DOT11_MODE_11G_ONLY:
+				if ((bw_val == 20) || (bw_val == 40))
+					phymode = MODE_11GONLY;
+				break;
+			case WNI_CFG_DOT11_MODE_11N:
+			case WNI_CFG_DOT11_MODE_11N_ONLY:
+				if (bw_val == 20)
+					phymode = MODE_11NG_HT20;
+				else if (bw_val == 40)
+					phymode = MODE_11NG_HT40;
+				break;
+			case WNI_CFG_DOT11_MODE_ALL:
+			case WNI_CFG_DOT11_MODE_11AC:
+			case WNI_CFG_DOT11_MODE_11AC_ONLY:
+				if (bw_val == 20)
+					phymode = MODE_11AC_VHT20_2G;
+				else if (bw_val == 40)
+					phymode = MODE_11AC_VHT40_2G;
+				break;
+			case WNI_CFG_DOT11_MODE_11AX:
+			case WNI_CFG_DOT11_MODE_11AX_ONLY:
+				if (20 == bw_val)
+					phymode = MODE_11AX_HE20_2G;
+				else if (40 == bw_val)
+					phymode = MODE_11AX_HE40_2G;
+				break;
+			default:
+				break;
+			}
+		}
+	} else if (wlan_reg_is_dsrc_chan(wma->pdev, chan))
+		phymode = MODE_11A;
+	else {
+		if (((CH_WIDTH_5MHZ == chan_width) ||
+		     (CH_WIDTH_10MHZ == chan_width)) &&
+		    ((WNI_CFG_DOT11_MODE_11A == dot11_mode) ||
+		     (WNI_CFG_DOT11_MODE_11N == dot11_mode) ||
+		     (WNI_CFG_DOT11_MODE_ALL == dot11_mode) ||
+		     (WNI_CFG_DOT11_MODE_11AC == dot11_mode) ||
+		     (WNI_CFG_DOT11_MODE_11AX == dot11_mode)))
+			phymode = MODE_11A;
+		else {
+			switch (dot11_mode) {
+			case WNI_CFG_DOT11_MODE_11A:
+				if (0 < bw_val)
+					phymode = MODE_11A;
+				break;
+			case WNI_CFG_DOT11_MODE_11N:
+			case WNI_CFG_DOT11_MODE_11N_ONLY:
+				if (bw_val == 20)
+					phymode = MODE_11NA_HT20;
+				else if (40 <= bw_val)
+					phymode = MODE_11NA_HT40;
+				break;
+			case WNI_CFG_DOT11_MODE_ALL:
+			case WNI_CFG_DOT11_MODE_11AC:
+			case WNI_CFG_DOT11_MODE_11AC_ONLY:
+				if (bw_val == 20)
+					phymode = MODE_11AC_VHT20;
+				else if (bw_val == 40)
+					phymode = MODE_11AC_VHT40;
+				else if (bw_val == 80)
+					phymode = MODE_11AC_VHT80;
+				else if (chan_width == CH_WIDTH_160MHZ)
+					phymode = MODE_11AC_VHT160;
+				else if (chan_width == CH_WIDTH_80P80MHZ)
+					phymode = MODE_11AC_VHT80_80;
+				break;
+			case WNI_CFG_DOT11_MODE_11AX:
+			case WNI_CFG_DOT11_MODE_11AX_ONLY:
+				if (20 == bw_val)
+					phymode = MODE_11AX_HE20;
+				else if (40 == bw_val)
+					phymode = MODE_11AX_HE40;
+				else if (80 == bw_val)
+					phymode = MODE_11AX_HE80;
+				else if (CH_WIDTH_160MHZ == chan_width)
+					phymode = MODE_11AX_HE160;
+				else if (CH_WIDTH_80P80MHZ == chan_width)
+					phymode = MODE_11AX_HE80_80;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	WMA_LOGD("%s: phymode %d channel %d ch_width %d dot11_mode %d",
+		 __func__, phymode, chan, chan_width, dot11_mode);
+
+	QDF_ASSERT(MODE_UNKNOWN != phymode);
+	return phymode;
+}
+
+/**
+ * wma_get_link_speed() -send command to get linkspeed
+ * @handle: wma handle
+ * @pLinkSpeed: link speed info
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_get_link_speed(WMA_HANDLE handle, tSirLinkSpeedInfo *pLinkSpeed)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	wmi_mac_addr peer_macaddr;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue get link speed cmd",
+			 __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!wmi_service_enabled(wma_handle->wmi_handle,
+				    wmi_service_estimate_linkspeed)) {
+		WMA_LOGE("%s: Linkspeed feature bit not enabled Sending value 0 as link speed.",
+			__func__);
+		wma_send_link_speed(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Copy the peer macaddress to the wma buffer */
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(pLinkSpeed->peer_macaddr.bytes,
+				   &peer_macaddr);
+	WMA_LOGD("%s: pLinkSpeed->peerMacAddr: %pM, peer_macaddr.mac_addr31to0: 0x%x, peer_macaddr.mac_addr47to32: 0x%x",
+		 __func__, pLinkSpeed->peer_macaddr.bytes,
+		 peer_macaddr.mac_addr31to0,
+		 peer_macaddr.mac_addr47to32);
+	if (wmi_unified_get_link_speed_cmd(wma_handle->wmi_handle,
+					peer_macaddr)) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wma_get_peer_info(WMA_HANDLE handle,
+				struct sir_peer_info_req *peer_info_req)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle)handle;
+	wmi_request_stats_cmd_fixed_param *cmd;
+	wmi_buf_t  wmi_buf;
+	uint32_t  len;
+	uint8_t *buf_ptr;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue get rssi",
+			__func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	len  = sizeof(wmi_request_stats_cmd_fixed_param);
+	wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!wmi_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(wmi_buf);
+
+	cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(wmi_request_stats_cmd_fixed_param));
+
+	cmd->stats_id = WMI_REQUEST_PEER_STAT;
+	cmd->vdev_id = peer_info_req->sessionid;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_info_req->peer_macaddr.bytes,
+				   &cmd->peer_macaddr);
+	wma_handle->get_sta_peer_info = true;
+
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
+				WMI_REQUEST_STATS_CMDID)) {
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_copy(&(wma_handle->peer_macaddr),
+					&(peer_info_req->peer_macaddr),
+					QDF_MAC_ADDR_SIZE);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wma_get_peer_info_ext(WMA_HANDLE handle,
+				struct sir_peer_info_ext_req *peer_info_req)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle)handle;
+	wmi_request_peer_stats_info_cmd_fixed_param *cmd;
+	wmi_buf_t  wmi_buf;
+	uint32_t  len;
+	uint8_t *buf_ptr;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue get rssi",
+			__func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	WMA_LOGI("%s send WMI_REQUEST_PEER_STATS_INFO_CMDID", __func__);
+
+	len  = sizeof(wmi_request_peer_stats_info_cmd_fixed_param);
+	wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!wmi_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(wmi_buf);
+
+	cmd = (wmi_request_peer_stats_info_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_request_peer_stats_info_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_request_peer_stats_info_cmd_fixed_param));
+	cmd->vdev_id = peer_info_req->sessionid;
+	cmd->request_type = WMI_REQUEST_ONE_PEER_STATS_INFO;
+	wma_handle->get_one_peer_info = true;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_info_req->peer_macaddr.bytes,
+			&cmd->peer_macaddr);
+	cmd->reset_after_request = peer_info_req->reset_after_request;
+
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
+				WMI_REQUEST_PEER_STATS_INFO_CMDID)) {
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGI("%s vdev_id %d, mac %pM, req_type %x, reset %x",
+			__func__,
+			cmd->vdev_id,
+			peer_info_req->peer_macaddr.bytes,
+			cmd->request_type,
+			cmd->reset_after_request);
+
+	qdf_mem_copy(&(wma_handle->peer_macaddr),
+					&(peer_info_req->peer_macaddr),
+					QDF_MAC_ADDR_SIZE);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_add_beacon_filter() - Issue WMI command to set beacon filter
+ * @wma: wma handler
+ * @filter_params: beacon_filter_param to set
+ *
+ * Return: Return QDF_STATUS
+ */
+QDF_STATUS wma_add_beacon_filter(WMA_HANDLE handle,
+				struct beacon_filter_param *filter_params)
+{
+	int i;
+	wmi_buf_t wmi_buf;
+	u_int8_t *buf;
+	A_UINT32 *ie_map;
+	int ret;
+	struct wma_txrx_node *iface;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	wmi_add_bcn_filter_cmd_fixed_param *cmd;
+	int len = sizeof(wmi_add_bcn_filter_cmd_fixed_param);
+
+	len += WMI_TLV_HDR_SIZE;
+	len += BCN_FLT_MAX_ELEMS_IE_LIST*sizeof(A_UINT32);
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue set beacon filter",
+			__func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	iface = &wma->interfaces[filter_params->vdev_id];
+	qdf_mem_copy(&iface->beacon_filter, filter_params,
+			sizeof(struct beacon_filter_param));
+	iface->beacon_filter_enabled = true;
+
+	wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!wmi_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf = (u_int8_t *) wmi_buf_data(wmi_buf);
+
+	cmd = (wmi_add_bcn_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf);
+	cmd->vdev_id = filter_params->vdev_id;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+			WMITLV_TAG_STRUC_wmi_add_bcn_filter_cmd_fixed_param,
+			WMITLV_GET_STRUCT_TLVLEN(
+				wmi_add_bcn_filter_cmd_fixed_param));
+
+	buf += sizeof(wmi_add_bcn_filter_cmd_fixed_param);
+
+	WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_UINT32,
+			(BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(u_int32_t)));
+
+	ie_map = (A_UINT32 *)(buf + WMI_TLV_HDR_SIZE);
+	for (i = 0; i < BCN_FLT_MAX_ELEMS_IE_LIST; i++) {
+		ie_map[i] = filter_params->ie_map[i];
+		WMA_LOGD("beacon filter ie map = %u", ie_map[i]);
+	}
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
+			WMI_ADD_BCN_FILTER_CMDID);
+	if (ret) {
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+* wma_remove_beacon_filter() - Issue WMI command to remove beacon filter
+* @wma: wma handler
+* @filter_params: beacon_filter_params
+*
+* Return: Return QDF_STATUS
+*/
+QDF_STATUS wma_remove_beacon_filter(WMA_HANDLE handle,
+				struct beacon_filter_param *filter_params)
+{
+	wmi_buf_t buf;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	wmi_rmv_bcn_filter_cmd_fixed_param *cmd;
+	int len = sizeof(wmi_rmv_bcn_filter_cmd_fixed_param);
+	int ret;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, cannot issue remove beacon filter",
+			__func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_rmv_bcn_filter_cmd_fixed_param *)wmi_buf_data(buf);
+	cmd->vdev_id = filter_params->vdev_id;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+			WMITLV_TAG_STRUC_wmi_rmv_bcn_filter_cmd_fixed_param,
+			WMITLV_GET_STRUCT_TLVLEN(
+				wmi_rmv_bcn_filter_cmd_fixed_param));
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+			WMI_RMV_BCN_FILTER_CMDID);
+	if (ret) {
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_send_adapt_dwelltime_params() - send adaptive dwelltime configuration
+ * params to firmware
+ * @wma_handle:	 wma handler
+ * @dwelltime_params: pointer to dwelltime_params
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
+ */
+QDF_STATUS wma_send_adapt_dwelltime_params(WMA_HANDLE handle,
+			struct adaptive_dwelltime_params *dwelltime_params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	struct wmi_adaptive_dwelltime_params wmi_param = {0};
+	int32_t err;
+
+	wmi_param.is_enabled = dwelltime_params->is_enabled;
+	wmi_param.dwelltime_mode = dwelltime_params->dwelltime_mode;
+	wmi_param.lpf_weight = dwelltime_params->lpf_weight;
+	wmi_param.passive_mon_intval = dwelltime_params->passive_mon_intval;
+	wmi_param.wifi_act_threshold = dwelltime_params->wifi_act_threshold;
+	err = wmi_unified_send_adapt_dwelltime_params_cmd(wma_handle->
+					wmi_handle, &wmi_param);
+	if (err)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wma_send_dbs_scan_selection_params(WMA_HANDLE handle,
+			struct wmi_dbs_scan_sel_params *dbs_scan_params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	int32_t err;
+
+	err = wmi_unified_send_dbs_scan_sel_params_cmd(wma_handle->
+					wmi_handle, dbs_scan_params);
+	if (err)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_unified_fw_profiling_cmd() - send FW profiling cmd to WLAN FW
+ * @wma: wma handle
+ * @cmd: Profiling command index
+ * @value1: parameter1 value
+ * @value2: parameter2 value
+ *
+ * Return: 0 for success else error code
+ */
+QDF_STATUS wma_unified_fw_profiling_cmd(wmi_unified_t wmi_handle,
+			uint32_t cmd, uint32_t value1, uint32_t value2)
+{
+	int ret;
+
+	ret = wmi_unified_fw_profiling_data_cmd(wmi_handle, cmd,
+			value1, value2);
+	if (ret) {
+		WMA_LOGE("enable cmd Failed for id %d value %d",
+				value1, value2);
+		return ret;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_wow_set_wake_time() - set timer pattern tlv, so that firmware will wake
+ * up host after specified time is elapsed
+ * @wma_handle: wma handle
+ * @vdev_id: vdev id
+ * @cookie: value to identify reason why host set up wake call.
+ * @time: time in ms
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_wow_set_wake_time(WMA_HANDLE wma_handle, uint8_t vdev_id,
+					uint32_t cookie, uint32_t time)
+{
+	int ret;
+	tp_wma_handle wma = (tp_wma_handle)wma_handle;
+
+	WMA_LOGD(FL("send timer patter with time: %d and vdev = %d to fw"),
+		    time, vdev_id);
+	ret = wmi_unified_wow_timer_pattern_cmd(wma->wmi_handle, vdev_id,
+						cookie, time);
+	if (ret) {
+		WMA_LOGE(FL("Failed to send timer patter to fw"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+/**
+ * wma_check_and_set_wake_timer(): checks all interfaces and if any interface
+ * has install_key pending, sets timer pattern in fw to wake up host after
+ * specified time has elapsed.
+ * @wma: wma handle
+ * @time: time after which host wants to be awaken.
+ *
+ * Return: None
+ */
+void wma_check_and_set_wake_timer(uint32_t time)
+{
+	int i;
+	struct wma_txrx_node *iface;
+	bool is_set_key_in_progress = false;
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma) {
+		WMA_LOGE("%s: WMA is closed",
+			__func__);
+		return;
+	}
+
+	if (!wmi_service_enabled(wma->wmi_handle,
+		wmi_service_wow_wakeup_by_timer_pattern)) {
+		WMA_LOGD("TIME_PATTERN is not enabled");
+		return;
+	}
+
+	for (i = 0; i < wma->max_bssid; i++) {
+		iface = &wma->interfaces[i];
+		if (iface->vdev_active && iface->is_waiting_for_key) {
+			/*
+			 * right now cookie is dont care, since FW disregards
+			 * that.
+			 */
+			is_set_key_in_progress = true;
+			wma_wow_set_wake_time((WMA_HANDLE)wma, i, 0, time);
+			break;
+		}
+	}
+
+	if (!is_set_key_in_progress)
+		WMA_LOGD("set key not in progress for any vdev");
+}
+
+/**
+ * wma_unified_csa_offload_enable() - sen CSA offload enable command
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: 0 for success or error code
+ */
+int wma_unified_csa_offload_enable(tp_wma_handle wma, uint8_t vdev_id)
+{
+	if (wmi_unified_csa_offload_enable(wma->wmi_handle,
+				 vdev_id)) {
+		WMA_LOGP("%s: Failed to send CSA offload enable command",
+			 __func__);
+		return -EIO;
+	}
+
+	return 0;
+}
+#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+#ifdef WLAN_FEATURE_NAN
+/**
+ * wma_nan_rsp_event_handler() - Function is used to handle nan response
+ * @handle: wma handle
+ * @event_buf: event buffer
+ * @len: length of buffer
+ *
+ * Return: 0 for success or error code
+ */
+int wma_nan_rsp_event_handler(void *handle, uint8_t *event_buf,
+			      uint32_t len)
+{
+	WMI_NAN_EVENTID_param_tlvs *param_buf;
+	tSirNanEvent *nan_rsp_event;
+	wmi_nan_event_hdr *nan_rsp_event_hdr;
+	QDF_STATUS status;
+	struct scheduler_msg message = {0};
+	uint8_t *buf_ptr;
+	uint32_t alloc_len;
+
+	/*
+	 * This is how received event_buf looks like
+	 *
+	 * <-------------------- event_buf ----------------------------------->
+	 *
+	 * <--wmi_nan_event_hdr--><---WMI_TLV_HDR_SIZE---><----- data -------->
+	 *
+	 * +-----------+---------+-----------------------+--------------------+
+	 * | tlv_header| data_len| WMITLV_TAG_ARRAY_BYTE | nan_rsp_event_data |
+	 * +-----------+---------+-----------------------+--------------------+
+	 */
+
+	WMA_LOGD("%s: Posting NaN response event to SME", __func__);
+	param_buf = (WMI_NAN_EVENTID_param_tlvs *) event_buf;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid nan response event buf", __func__);
+		return -EINVAL;
+	}
+	nan_rsp_event_hdr = param_buf->fixed_param;
+	buf_ptr = (uint8_t *) nan_rsp_event_hdr;
+	alloc_len = sizeof(tSirNanEvent);
+	alloc_len += nan_rsp_event_hdr->data_len;
+	if (nan_rsp_event_hdr->data_len > ((WMI_SVC_MSG_MAX_SIZE -
+	    WMI_TLV_HDR_SIZE - sizeof(*nan_rsp_event_hdr)) / sizeof(uint8_t)) ||
+	    nan_rsp_event_hdr->data_len > param_buf->num_data) {
+		WMA_LOGE("excess data length:%d, num_data:%d",
+			nan_rsp_event_hdr->data_len, param_buf->num_data);
+		return -EINVAL;
+	}
+	nan_rsp_event = qdf_mem_malloc(alloc_len);
+	if (!nan_rsp_event)
+		return -ENOMEM;
+
+	nan_rsp_event->event_data_len = nan_rsp_event_hdr->data_len;
+	qdf_mem_copy(nan_rsp_event->event_data, buf_ptr +
+		     sizeof(wmi_nan_event_hdr) + WMI_TLV_HDR_SIZE,
+		     nan_rsp_event->event_data_len);
+	message.type = eWNI_SME_NAN_EVENT;
+	message.bodyptr = (void *)nan_rsp_event;
+	message.bodyval = 0;
+
+	status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_SME, &message);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Failed to post NaN response event to SME",
+			 __func__);
+		qdf_mem_free(nan_rsp_event);
+		return -EFAULT;
+	}
+	WMA_LOGD("%s: NaN response event Posted to SME", __func__);
+	return 0;
+}
+#else
+static int wma_nan_rsp_event_handler(void *handle, uint8_t *event_buf,
+				     uint32_t len)
+{
+	return 0;
+}
+#endif /* WLAN_FEATURE_NAN */
+
+/**
+ * wma_csa_offload_handler() - CSA event handler
+ * @handle: wma handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * This event is sent by firmware when it receives CSA IE.
+ *
+ * Return: 0 for success or error code
+ */
+int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_CSA_HANDLING_EVENTID_param_tlvs *param_buf;
+	wmi_csa_event_fixed_param *csa_event;
+	uint8_t bssid[IEEE80211_ADDR_LEN];
+	uint8_t vdev_id = 0;
+	uint8_t cur_chan = 0;
+	struct ieee80211_channelswitch_ie *csa_ie;
+	struct csa_offload_params *csa_offload_event;
+	struct ieee80211_extendedchannelswitch_ie *xcsa_ie;
+	struct ieee80211_ie_wide_bw_switch *wb_ie;
+	struct wma_txrx_node *intr = wma->interfaces;
+
+	param_buf = (WMI_CSA_HANDLING_EVENTID_param_tlvs *) event;
+
+	WMA_LOGD("%s: Enter", __func__);
+	if (!param_buf) {
+		WMA_LOGE("Invalid csa event buffer");
+		return -EINVAL;
+	}
+	csa_event = param_buf->fixed_param;
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_event->i_addr2, &bssid[0]);
+
+	if (wma_find_vdev_by_bssid(wma, bssid, &vdev_id) == NULL) {
+		WMA_LOGE("Invalid bssid received %s:%d", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	csa_offload_event = qdf_mem_malloc(sizeof(*csa_offload_event));
+	if (!csa_offload_event)
+		return -EINVAL;
+
+	if (wma->interfaces[vdev_id].roaming_in_progress ||
+		wma->interfaces[vdev_id].roam_synch_in_progress) {
+		WMA_LOGE("Roaming in progress for vdev %d, ignore csa_offload_event",
+				vdev_id);
+		qdf_mem_free(csa_offload_event);
+		return -EINVAL;
+	}
+
+	qdf_mem_zero(csa_offload_event, sizeof(*csa_offload_event));
+	qdf_mem_copy(csa_offload_event->bssId, &bssid, IEEE80211_ADDR_LEN);
+
+	if (csa_event->ies_present_flag & WMI_CSA_IE_PRESENT) {
+		csa_ie = (struct ieee80211_channelswitch_ie *)
+						(&csa_event->csa_ie[0]);
+		csa_offload_event->channel = csa_ie->newchannel;
+		csa_offload_event->switch_mode = csa_ie->switchmode;
+	} else if (csa_event->ies_present_flag & WMI_XCSA_IE_PRESENT) {
+		xcsa_ie = (struct ieee80211_extendedchannelswitch_ie *)
+						(&csa_event->xcsa_ie[0]);
+		csa_offload_event->channel = xcsa_ie->newchannel;
+		csa_offload_event->switch_mode = xcsa_ie->switchmode;
+		csa_offload_event->new_op_class = xcsa_ie->newClass;
+	} else {
+		WMA_LOGE("CSA Event error: No CSA IE present");
+		qdf_mem_free(csa_offload_event);
+		return -EINVAL;
+	}
+
+	if (csa_event->ies_present_flag & WMI_WBW_IE_PRESENT) {
+		wb_ie = (struct ieee80211_ie_wide_bw_switch *)
+						(&csa_event->wb_ie[0]);
+		csa_offload_event->new_ch_width = wb_ie->new_ch_width;
+		csa_offload_event->new_ch_freq_seg1 = wb_ie->new_ch_freq_seg1;
+		csa_offload_event->new_ch_freq_seg2 = wb_ie->new_ch_freq_seg2;
+	}
+
+	csa_offload_event->ies_present_flag = csa_event->ies_present_flag;
+
+	WMA_LOGD("CSA: New Channel = %d BSSID:%pM",
+		 csa_offload_event->channel, csa_offload_event->bssId);
+
+	cur_chan = cds_freq_to_chan(intr[vdev_id].mhz);
+	/*
+	 * basic sanity check: requested channel should not be 0
+	 * and equal to home 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);
+		return -EINVAL;
+	}
+#ifndef CONFIG_VDEV_SM
+	wma->interfaces[vdev_id].is_channel_switch = true;
+#endif
+	wma_send_msg(wma, WMA_CSA_OFFLOAD_EVENT, (void *)csa_offload_event, 0);
+	return 0;
+}
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+/**
+ * wma_oem_data_response_handler() - OEM data response event handler
+ * @handle: wma handle
+ * @datap: data ptr
+ * @len: data length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_oem_data_response_handler(void *handle,
+				  uint8_t *datap, uint32_t len)
+{
+	WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf;
+	uint8_t *data;
+	uint32_t datalen;
+	struct oem_data_rsp *oem_rsp;
+	tpAniSirGlobal pmac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!pmac) {
+		WMA_LOGE(FL("Invalid pmac"));
+		return -EINVAL;
+	}
+
+	if (!pmac->sme.oem_data_rsp_callback) {
+		WMA_LOGE(FL("Callback not registered"));
+		return -EINVAL;
+	}
+
+	param_buf = (WMI_OEM_RESPONSE_EVENTID_param_tlvs *) datap;
+	if (!param_buf) {
+		WMA_LOGE(FL("Received NULL buf ptr from FW"));
+		return -ENOMEM;
+	}
+
+	data = param_buf->data;
+	datalen = param_buf->num_data;
+
+	if (!data) {
+		WMA_LOGE(FL("Received NULL data from FW"));
+		return -EINVAL;
+	}
+
+	if (datalen > OEM_DATA_RSP_SIZE) {
+		WMA_LOGE(FL("Received data len %d exceeds max value %d"),
+			 datalen, OEM_DATA_RSP_SIZE);
+		return -EINVAL;
+	}
+
+	oem_rsp = qdf_mem_malloc(sizeof(*oem_rsp));
+	if (!oem_rsp)
+		return -ENOMEM;
+
+	oem_rsp->rsp_len = datalen;
+	if (oem_rsp->rsp_len) {
+		oem_rsp->data = qdf_mem_malloc(oem_rsp->rsp_len);
+		if (!oem_rsp->data) {
+			qdf_mem_free(oem_rsp);
+			return -ENOMEM;
+		}
+	} else {
+		WMA_LOGE(FL("Invalid rsp length: %d"),
+			 oem_rsp->rsp_len);
+		qdf_mem_free(oem_rsp);
+		return -EINVAL;
+	}
+
+	qdf_mem_copy(oem_rsp->data, data, datalen);
+
+	WMA_LOGD("Sending OEM_DATA_RSP(len: %d) to upper layer", datalen);
+
+	pmac->sme.oem_data_rsp_callback(oem_rsp);
+
+	if (oem_rsp->data)
+		qdf_mem_free(oem_rsp->data);
+	qdf_mem_free(oem_rsp);
+
+	return 0;
+}
+
+/**
+ * wma_start_oem_data_req() - start OEM data request to target
+ * @wma_handle: wma handle
+ * @oem_data_req: start request params
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_start_oem_data_req(tp_wma_handle wma_handle,
+			    struct oem_data_req *oem_data_req)
+{
+	int ret = 0;
+
+	WMA_LOGD(FL("Send OEM Data Request to target"));
+
+	if (!oem_data_req || !oem_data_req->data) {
+		WMA_LOGE(FL("oem_data_req is null"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE(FL("WMA - closed, can not send Oem data request cmd"));
+		qdf_mem_free(oem_data_req->data);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	ret = wmi_unified_start_oem_data_cmd(wma_handle->wmi_handle,
+				   oem_data_req->data_len,
+				   oem_data_req->data);
+
+	if (!QDF_IS_STATUS_SUCCESS(ret))
+		WMA_LOGE(FL("wmi cmd send failed"));
+
+	return ret;
+}
+#endif /* FEATURE_OEM_DATA_SUPPORT */
+
+#if !defined(REMOVE_PKT_LOG)
+/**
+ * wma_pktlog_wmi_send_cmd() - send pktlog enable/disable command to target
+ * @handle: wma handle
+ * @params: pktlog params
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_pktlog_wmi_send_cmd(WMA_HANDLE handle,
+				   struct ath_pktlog_wmi_params *params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	int ret;
+
+	ret = wmi_unified_pktlog_wmi_send_cmd(wma_handle->wmi_handle,
+			params->pktlog_event,
+			params->cmd_id, params->user_triggered);
+	if (ret)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* REMOVE_PKT_LOG */
+
+/**
+ * wma_wow_wake_reason_str() -  Converts wow wakeup reason code to text format
+ * @wake_reason - WOW wake reason
+ *
+ * Return: reason code in string format
+ */
+static const uint8_t *wma_wow_wake_reason_str(A_INT32 wake_reason)
+{
+	switch (wake_reason) {
+	case WOW_REASON_UNSPECIFIED:
+		return "UNSPECIFIED";
+	case WOW_REASON_NLOD:
+		return "NLOD";
+	case WOW_REASON_AP_ASSOC_LOST:
+		return "AP_ASSOC_LOST";
+	case WOW_REASON_LOW_RSSI:
+		return "LOW_RSSI";
+	case WOW_REASON_DEAUTH_RECVD:
+		return "DEAUTH_RECVD";
+	case WOW_REASON_DISASSOC_RECVD:
+		return "DISASSOC_RECVD";
+	case WOW_REASON_GTK_HS_ERR:
+		return "GTK_HS_ERR";
+	case WOW_REASON_EAP_REQ:
+		return "EAP_REQ";
+	case WOW_REASON_FOURWAY_HS_RECV:
+		return "FOURWAY_HS_RECV";
+	case WOW_REASON_TIMER_INTR_RECV:
+		return "TIMER_INTR_RECV";
+	case WOW_REASON_PATTERN_MATCH_FOUND:
+		return "PATTERN_MATCH_FOUND";
+	case WOW_REASON_RECV_MAGIC_PATTERN:
+		return "RECV_MAGIC_PATTERN";
+	case WOW_REASON_P2P_DISC:
+		return "P2P_DISC";
+	case WOW_REASON_WLAN_HB:
+		return "WLAN_HB";
+	case WOW_REASON_CSA_EVENT:
+		return "CSA_EVENT";
+	case WOW_REASON_PROBE_REQ_WPS_IE_RECV:
+		return "PROBE_REQ_WPS_IE_RECV";
+	case WOW_REASON_AUTH_REQ_RECV:
+		return "AUTH_REQ_RECV";
+	case WOW_REASON_ASSOC_REQ_RECV:
+		return "ASSOC_REQ_RECV";
+	case WOW_REASON_HTT_EVENT:
+		return "HTT_EVENT";
+	case WOW_REASON_RA_MATCH:
+		return "RA_MATCH";
+	case WOW_REASON_HOST_AUTO_SHUTDOWN:
+		return "HOST_AUTO_SHUTDOWN";
+	case WOW_REASON_IOAC_MAGIC_EVENT:
+		return "IOAC_MAGIC_EVENT";
+	case WOW_REASON_IOAC_SHORT_EVENT:
+		return "IOAC_SHORT_EVENT";
+	case WOW_REASON_IOAC_EXTEND_EVENT:
+		return "IOAC_EXTEND_EVENT";
+	case WOW_REASON_IOAC_TIMER_EVENT:
+		return "IOAC_TIMER_EVENT";
+	case WOW_REASON_ROAM_HO:
+		return "ROAM_HO";
+	case WOW_REASON_DFS_PHYERR_RADADR_EVENT:
+		return "DFS_PHYERR_RADADR_EVENT";
+	case WOW_REASON_BEACON_RECV:
+		return "BEACON_RECV";
+	case WOW_REASON_CLIENT_KICKOUT_EVENT:
+		return "CLIENT_KICKOUT_EVENT";
+	case WOW_REASON_NAN_EVENT:
+		return "NAN_EVENT";
+	case WOW_REASON_EXTSCAN:
+		return "EXTSCAN";
+	case WOW_REASON_RSSI_BREACH_EVENT:
+		return "RSSI_BREACH_EVENT";
+	case WOW_REASON_IOAC_REV_KA_FAIL_EVENT:
+		return "IOAC_REV_KA_FAIL_EVENT";
+	case WOW_REASON_IOAC_SOCK_EVENT:
+		return "IOAC_SOCK_EVENT";
+	case WOW_REASON_NLO_SCAN_COMPLETE:
+		return "NLO_SCAN_COMPLETE";
+	case WOW_REASON_PACKET_FILTER_MATCH:
+		return "PACKET_FILTER_MATCH";
+	case WOW_REASON_ASSOC_RES_RECV:
+		return "ASSOC_RES_RECV";
+	case WOW_REASON_REASSOC_REQ_RECV:
+		return "REASSOC_REQ_RECV";
+	case WOW_REASON_REASSOC_RES_RECV:
+		return "REASSOC_RES_RECV";
+	case WOW_REASON_ACTION_FRAME_RECV:
+		return "ACTION_FRAME_RECV";
+	case WOW_REASON_BPF_ALLOW:
+		return "BPF_ALLOW";
+	case WOW_REASON_NAN_DATA:
+		return "NAN_DATA";
+	case WOW_REASON_OEM_RESPONSE_EVENT:
+		return "OEM_RESPONSE_EVENT";
+	case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
+		return "TDLS_CONN_TRACKER_EVENT";
+	case WOW_REASON_CRITICAL_LOG:
+		return "CRITICAL_LOG";
+	case WOW_REASON_P2P_LISTEN_OFFLOAD:
+		return "P2P_LISTEN_OFFLOAD";
+	case WOW_REASON_NAN_EVENT_WAKE_HOST:
+		return "NAN_EVENT_WAKE_HOST";
+	case WOW_REASON_DEBUG_TEST:
+		return "DEBUG_TEST";
+	case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
+		return "CHIP_POWER_FAILURE_DETECT";
+	case WOW_REASON_11D_SCAN:
+		return "11D_SCAN";
+	case WOW_REASON_SAP_OBSS_DETECTION:
+		return "SAP_OBSS_DETECTION";
+	case WOW_REASON_BSS_COLOR_COLLISION_DETECT:
+		return "BSS_COLOR_COLLISION_DETECT";
+	default:
+		return "unknown";
+	}
+}
+
+#ifdef QCA_SUPPORT_CP_STATS
+static bool wma_wow_reason_has_stats(enum wake_reason_e reason)
+{
+	switch (reason) {
+	case WOW_REASON_ASSOC_REQ_RECV:
+	case WOW_REASON_DISASSOC_RECVD:
+	case WOW_REASON_ASSOC_RES_RECV:
+	case WOW_REASON_REASSOC_REQ_RECV:
+	case WOW_REASON_REASSOC_RES_RECV:
+	case WOW_REASON_AUTH_REQ_RECV:
+	case WOW_REASON_DEAUTH_RECVD:
+	case WOW_REASON_ACTION_FRAME_RECV:
+	case WOW_REASON_BPF_ALLOW:
+	case WOW_REASON_PATTERN_MATCH_FOUND:
+	case WOW_REASON_RA_MATCH:
+	case WOW_REASON_NLOD:
+	case WOW_REASON_NLO_SCAN_COMPLETE:
+	case WOW_REASON_LOW_RSSI:
+	case WOW_REASON_EXTSCAN:
+	case WOW_REASON_RSSI_BREACH_EVENT:
+	case WOW_REASON_OEM_RESPONSE_EVENT:
+	case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
+	case WOW_REASON_11D_SCAN:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static void wma_inc_wow_stats(t_wma_handle *wma,
+			      WOW_EVENT_INFO_fixed_param *wake_info)
+{
+	ucfg_mc_cp_stats_inc_wake_lock_stats(wma->psoc,
+					     wake_info->vdev_id,
+					     wake_info->wake_reason);
+}
+
+static void wma_wow_stats_display(struct wake_lock_stats *stats)
+{
+	WMA_LOGA("WLAN wake reason counters:");
+	WMA_LOGA("uc:%d bc:%d v4_mc:%d v6_mc:%d ra:%d ns:%d na:%d "
+		 "icmp:%d icmpv6:%d",
+		 stats->ucast_wake_up_count,
+		 stats->bcast_wake_up_count,
+		 stats->ipv4_mcast_wake_up_count,
+		 stats->ipv6_mcast_wake_up_count,
+		 stats->ipv6_mcast_ra_stats,
+		 stats->ipv6_mcast_ns_stats,
+		 stats->ipv6_mcast_na_stats,
+		 stats->icmpv4_count,
+		 stats->icmpv6_count);
+
+	WMA_LOGA("assoc:%d disassoc:%d assoc_resp:%d reassoc:%d "
+		 "reassoc_resp:%d auth:%d deauth:%d action:%d",
+		 stats->mgmt_assoc,
+		 stats->mgmt_disassoc,
+		 stats->mgmt_assoc_resp,
+		 stats->mgmt_reassoc,
+		 stats->mgmt_reassoc_resp,
+		 stats->mgmt_auth,
+		 stats->mgmt_deauth,
+		 stats->mgmt_action);
+
+	WMA_LOGA("pno_match:%d pno_complete:%d gscan:%d "
+		 "low_rssi:%d rssi_breach:%d oem:%d scan_11d:%d",
+		 stats->pno_match_wake_up_count,
+		 stats->pno_complete_wake_up_count,
+		 stats->gscan_wake_up_count,
+		 stats->low_rssi_wake_up_count,
+		 stats->rssi_breach_wake_up_count,
+		 stats->oem_response_wake_up_count,
+		 stats->scan_11d);
+}
+
+static void wma_print_wow_stats(t_wma_handle *wma,
+				WOW_EVENT_INFO_fixed_param *wake_info)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct wake_lock_stats stats = {0};
+
+	if (!wma_wow_reason_has_stats(wake_info->wake_reason))
+		return;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
+						    wake_info->vdev_id,
+						    WLAN_LEGACY_WMA_ID);
+	ucfg_mc_cp_stats_get_vdev_wake_lock_stats(vdev, &stats);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+	wma_wow_stats_display(&stats);
+}
+#else
+/**
+ * wma_wow_stats_display() - display wow wake up stats
+ * @stats: per vdev stats counters
+ *
+ * Return: none
+ */
+static void wma_wow_stats_display(struct sir_vdev_wow_stats *stats)
+{
+	WMA_LOGA("uc %d bc %d v4_mc %d v6_mc %d ra %d ns %d na %d pno_match %d pno_complete %d gscan %d low_rssi %d rssi_breach %d icmp %d icmpv6 %d oem %d",
+		stats->ucast,
+		stats->bcast,
+		stats->ipv4_mcast,
+		stats->ipv6_mcast,
+		stats->ipv6_mcast_ra,
+		stats->ipv6_mcast_ns,
+		stats->ipv6_mcast_na,
+		stats->pno_match,
+		stats->pno_complete,
+		stats->gscan,
+		stats->low_rssi,
+		stats->rssi_breach,
+		stats->icmpv4,
+		stats->icmpv6,
+		stats->oem_response);
+}
+
+static void wma_print_wow_stats(t_wma_handle *wma,
+				WOW_EVENT_INFO_fixed_param *wake_info)
+{
+	struct sir_vdev_wow_stats *stats;
+
+	switch (wake_info->wake_reason) {
+	case WOW_REASON_BPF_ALLOW:
+	case WOW_REASON_PATTERN_MATCH_FOUND:
+	case WOW_REASON_RA_MATCH:
+	case WOW_REASON_NLOD:
+	case WOW_REASON_NLO_SCAN_COMPLETE:
+	case WOW_REASON_LOW_RSSI:
+	case WOW_REASON_EXTSCAN:
+	case WOW_REASON_RSSI_BREACH_EVENT:
+	case WOW_REASON_OEM_RESPONSE_EVENT:
+	case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
+	case WOW_REASON_11D_SCAN:
+		break;
+	default:
+		return;
+	}
+
+	stats = &wma->interfaces[wake_info->vdev_id].wow_stats;
+	wma_wow_stats_display(stats);
+}
+
+/**
+ * wma_inc_wow_stats() - maintain wow pattern match wake up stats
+ * @wma: wma handle, containing the stats counters
+ * @wake_info: the wake event information
+ *
+ * Return: none
+ */
+static void wma_inc_wow_stats(t_wma_handle *wma,
+			      WOW_EVENT_INFO_fixed_param *wake_info)
+{
+	struct sir_vdev_wow_stats *stats;
+
+	if (wake_info->wake_reason == WOW_REASON_UNSPECIFIED) {
+		wma->wow_unspecified_wake_count++;
+		return;
+	}
+
+	stats = &wma->interfaces[wake_info->vdev_id].wow_stats;
+	switch (wake_info->wake_reason) {
+	case WOW_REASON_RA_MATCH:
+		stats->ipv6_mcast++;
+		stats->ipv6_mcast_ra++;
+		stats->icmpv6++;
+		break;
+	case WOW_REASON_NLOD:
+		stats->pno_match++;
+		break;
+	case WOW_REASON_NLO_SCAN_COMPLETE:
+		stats->pno_complete++;
+		break;
+	case WOW_REASON_LOW_RSSI:
+		stats->low_rssi++;
+		break;
+	case WOW_REASON_EXTSCAN:
+		stats->gscan++;
+		break;
+	case WOW_REASON_RSSI_BREACH_EVENT:
+		stats->rssi_breach++;
+		break;
+	case WOW_REASON_OEM_RESPONSE_EVENT:
+		stats->oem_response++;
+		break;
+	case WOW_REASON_11D_SCAN:
+		stats->scan_11d++;
+		break;
+	case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
+		stats->pwr_save_fail_detected++;
+		break;
+	}
+}
+#endif
+
+#ifdef FEATURE_WLAN_EXTSCAN
+/**
+ * wma_extscan_get_eventid_from_tlvtag() - map tlv tag to corresponding event id
+ * @tag: WMI TLV tag
+ *
+ * Return:
+ *	0 if TLV tag is invalid
+ *	else return corresponding WMI event id
+ */
+static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
+{
+	uint32_t event_id;
+
+	switch (tag) {
+	case WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param:
+		event_id = WMI_EXTSCAN_START_STOP_EVENTID;
+		break;
+
+	case WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param:
+		event_id = WMI_EXTSCAN_OPERATION_EVENTID;
+		break;
+
+	case WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param:
+		event_id = WMI_EXTSCAN_TABLE_USAGE_EVENTID;
+		break;
+
+	case WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param:
+		event_id = WMI_EXTSCAN_CACHED_RESULTS_EVENTID;
+		break;
+
+	case WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param:
+		event_id = WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID;
+		break;
+
+	case WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param:
+		event_id = WMI_EXTSCAN_HOTLIST_MATCH_EVENTID;
+		break;
+
+	case WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param:
+		event_id = WMI_EXTSCAN_CAPABILITIES_EVENTID;
+		break;
+
+	default:
+		event_id = 0;
+		WMA_LOGE("%s: Unknown tag: %d", __func__, tag);
+		break;
+	}
+
+	WMA_LOGI("%s: For tag %d WMI event 0x%x", __func__, tag, event_id);
+	return event_id;
+}
+#else
+static int wma_extscan_get_eventid_from_tlvtag(uint32_t tag)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wow_get_wmi_eventid() - map reason or tlv tag to corresponding event id
+ * @tag: WMI TLV tag
+ * @reason: WOW reason
+ *
+ * WOW reason type is primarily used to find the ID. If there could be
+ * multiple events that can be sent as a WOW event with same reason
+ * then tlv tag is used to identify the corresponding event.
+ *
+ * Return:
+ *      0 if TLV tag/reason is invalid
+ *      else return corresponding WMI event id
+ */
+static int wow_get_wmi_eventid(int32_t reason, uint32_t tag)
+{
+	int event_id;
+
+	switch (reason) {
+	case WOW_REASON_AP_ASSOC_LOST:
+		event_id = WMI_ROAM_EVENTID;
+		break;
+	case WOW_REASON_NLO_SCAN_COMPLETE:
+		event_id = WMI_NLO_SCAN_COMPLETE_EVENTID;
+		break;
+	case WOW_REASON_CSA_EVENT:
+		event_id = WMI_CSA_HANDLING_EVENTID;
+		break;
+	case WOW_REASON_LOW_RSSI:
+		event_id = WMI_ROAM_EVENTID;
+		break;
+	case WOW_REASON_CLIENT_KICKOUT_EVENT:
+		event_id = WMI_PEER_STA_KICKOUT_EVENTID;
+		break;
+	case WOW_REASON_EXTSCAN:
+		event_id = wma_extscan_get_eventid_from_tlvtag(tag);
+		break;
+	case WOW_REASON_RSSI_BREACH_EVENT:
+		event_id = WMI_RSSI_BREACH_EVENTID;
+		break;
+	case WOW_REASON_NAN_EVENT:
+		event_id = WMI_NAN_EVENTID;
+		break;
+	case WOW_REASON_NAN_DATA:
+		event_id = wma_ndp_get_eventid_from_tlvtag(tag);
+		break;
+	case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
+		event_id = WOW_TDLS_CONN_TRACKER_EVENT;
+		break;
+	case WOW_REASON_ROAM_HO:
+		event_id = WMI_ROAM_EVENTID;
+		break;
+	case WOW_REASON_11D_SCAN:
+		event_id = WMI_11D_NEW_COUNTRY_EVENTID;
+		break;
+	default:
+		WMA_LOGD(FL("No Event Id for WOW reason %s(%d)"),
+			 wma_wow_wake_reason_str(reason), reason);
+		event_id = 0;
+		break;
+	}
+	wlan_roam_debug_log(WMA_INVALID_VDEV_ID, DEBUG_WOW_REASON,
+			    DEBUG_INVALID_PEER_ID, NULL, NULL,
+			    reason, event_id);
+
+	return event_id;
+}
+
+/**
+ * is_piggybacked_event() - Returns true if the given wake reason indicates
+ *	there will be piggybacked TLV event data
+ * @reason: WOW reason
+ *
+ * There are three types of WoW event payloads: none, piggybacked event, and
+ * network packet. This function returns true for wake reasons that fall into
+ * the piggybacked event case.
+ *
+ * Return: true for piggybacked event data
+ */
+static bool is_piggybacked_event(int32_t reason)
+{
+	switch (reason) {
+	case WOW_REASON_AP_ASSOC_LOST:
+	case WOW_REASON_NLO_SCAN_COMPLETE:
+	case WOW_REASON_CSA_EVENT:
+	case WOW_REASON_LOW_RSSI:
+	case WOW_REASON_CLIENT_KICKOUT_EVENT:
+	case WOW_REASON_EXTSCAN:
+	case WOW_REASON_RSSI_BREACH_EVENT:
+	case WOW_REASON_NAN_EVENT:
+	case WOW_REASON_NAN_DATA:
+	case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
+	case WOW_REASON_ROAM_HO:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/**
+ * wma_pkt_proto_subtype_to_string() - to convert proto subtype
+ *         of data packet to string.
+ * @proto_subtype: proto subtype for data packet
+ *
+ * This function returns the string for the proto subtype of
+ * data packet.
+ *
+ * Return: string for proto subtype for data packet
+ */
+static const char *
+wma_pkt_proto_subtype_to_string(enum qdf_proto_subtype proto_subtype)
+{
+	switch (proto_subtype) {
+	case QDF_PROTO_EAPOL_M1:
+		return "EAPOL M1";
+	case QDF_PROTO_EAPOL_M2:
+		return "EAPOL M2";
+	case QDF_PROTO_EAPOL_M3:
+		return "EAPOL M3";
+	case QDF_PROTO_EAPOL_M4:
+		return "EAPOL M4";
+	case QDF_PROTO_DHCP_DISCOVER:
+		return "DHCP DISCOVER";
+	case QDF_PROTO_DHCP_REQUEST:
+		return "DHCP REQUEST";
+	case QDF_PROTO_DHCP_OFFER:
+		return "DHCP OFFER";
+	case QDF_PROTO_DHCP_ACK:
+		return "DHCP ACK";
+	case QDF_PROTO_DHCP_NACK:
+		return "DHCP NACK";
+	case QDF_PROTO_DHCP_RELEASE:
+		return "DHCP RELEASE";
+	case QDF_PROTO_DHCP_INFORM:
+		return "DHCP INFORM";
+	case QDF_PROTO_DHCP_DECLINE:
+		return "DHCP DECLINE";
+	case QDF_PROTO_ARP_REQ:
+		return "ARP REQUEST";
+	case QDF_PROTO_ARP_RES:
+		return "ARP RESPONSE";
+	case QDF_PROTO_ICMP_REQ:
+		return "ICMP REQUEST";
+	case QDF_PROTO_ICMP_RES:
+		return "ICMP RESPONSE";
+	case QDF_PROTO_ICMPV6_REQ:
+		return "ICMPV6 REQUEST";
+	case QDF_PROTO_ICMPV6_RES:
+		return "ICMPV6 RESPONSE";
+	case QDF_PROTO_ICMPV6_RS:
+		return "ICMPV6 RS";
+	case QDF_PROTO_ICMPV6_RA:
+		return "ICMPV6 RA";
+	case QDF_PROTO_ICMPV6_NS:
+		return "ICMPV6 NS";
+	case QDF_PROTO_ICMPV6_NA:
+		return "ICMPV6 NA";
+	case QDF_PROTO_IPV4_UDP:
+		return "IPV4 UDP Packet";
+	case QDF_PROTO_IPV4_TCP:
+		return "IPV4 TCP Packet";
+	case QDF_PROTO_IPV6_UDP:
+		return "IPV6 UDP Packet";
+	case QDF_PROTO_IPV6_TCP:
+		return "IPV6 TCP Packet";
+	default:
+		return NULL;
+	}
+}
+
+/**
+ * wma_wow_get_pkt_proto_subtype() - get the proto subtype of the packet.
+ * @data: Pointer to the packet data buffer
+ * @len: length of the packet data buffer
+ *
+ * Return: proto subtype of the packet.
+ */
+static enum qdf_proto_subtype
+wma_wow_get_pkt_proto_subtype(uint8_t *data, uint32_t len)
+{
+	uint16_t eth_type;
+	uint8_t proto_type;
+
+	if (len < QDF_NBUF_TRAC_ETH_TYPE_OFFSET + 2) {
+		WMA_LOGE("Malformed ethernet packet: length %u < %d",
+			 len, QDF_NBUF_TRAC_ETH_TYPE_OFFSET + 2);
+		return QDF_PROTO_INVALID;
+	}
+
+	eth_type = *(uint16_t *)(data + QDF_NBUF_TRAC_ETH_TYPE_OFFSET);
+	eth_type = qdf_cpu_to_be16(eth_type);
+
+	WMA_LOGD("Ether Type: 0x%04x", eth_type);
+	switch (eth_type) {
+	case QDF_NBUF_TRAC_EAPOL_ETH_TYPE:
+		if (len < WMA_EAPOL_SUBTYPE_GET_MIN_LEN)
+			return QDF_PROTO_INVALID;
+
+		WMA_LOGD("EAPOL Packet");
+		return qdf_nbuf_data_get_eapol_subtype(data);
+
+	case QDF_NBUF_TRAC_ARP_ETH_TYPE:
+		if (len < WMA_ARP_SUBTYPE_GET_MIN_LEN)
+			return QDF_PROTO_INVALID;
+
+		WMA_LOGD("ARP Packet");
+		return qdf_nbuf_data_get_arp_subtype(data);
+
+	case QDF_NBUF_TRAC_IPV4_ETH_TYPE:
+		if (len < WMA_IPV4_PROTO_GET_MIN_LEN)
+			return QDF_PROTO_INVALID;
+
+		WMA_LOGD("IPV4 Packet");
+
+		proto_type = qdf_nbuf_data_get_ipv4_proto(data);
+		WMA_LOGD("IPV4_proto_type: %u", proto_type);
+
+		switch (proto_type) {
+		case QDF_NBUF_TRAC_ICMP_TYPE:
+			if (len < WMA_ICMP_SUBTYPE_GET_MIN_LEN)
+				return QDF_PROTO_INVALID;
+
+			WMA_LOGD("ICMP Packet");
+			return qdf_nbuf_data_get_icmp_subtype(data);
+
+		case QDF_NBUF_TRAC_UDP_TYPE:
+			if (len < WMA_IS_DHCP_GET_MIN_LEN)
+				return QDF_PROTO_IPV4_UDP;
+
+			if (!qdf_nbuf_data_is_ipv4_dhcp_pkt(data))
+				return QDF_PROTO_INVALID;
+
+			if (len < WMA_DHCP_SUBTYPE_GET_MIN_LEN)
+				return QDF_PROTO_INVALID;
+
+			WMA_LOGD("DHCP Packet");
+			return qdf_nbuf_data_get_dhcp_subtype(data);
+
+		case QDF_NBUF_TRAC_TCP_TYPE:
+			return QDF_PROTO_IPV4_TCP;
+
+		default:
+			return QDF_PROTO_INVALID;
+		}
+
+	case QDF_NBUF_TRAC_IPV6_ETH_TYPE:
+		if (len < WMA_IPV6_PROTO_GET_MIN_LEN)
+			return QDF_PROTO_INVALID;
+
+		WMA_LOGD("IPV6 Packet");
+
+		proto_type = qdf_nbuf_data_get_ipv6_proto(data);
+		WMA_LOGD("IPV6_proto_type: %u", proto_type);
+
+		switch (proto_type) {
+		case QDF_NBUF_TRAC_ICMPV6_TYPE:
+			if (len < WMA_ICMPV6_SUBTYPE_GET_MIN_LEN)
+				return QDF_PROTO_INVALID;
+
+			WMA_LOGD("ICMPV6 Packet");
+			return qdf_nbuf_data_get_icmpv6_subtype(data);
+
+		case QDF_NBUF_TRAC_UDP_TYPE:
+			return QDF_PROTO_IPV6_UDP;
+
+		case QDF_NBUF_TRAC_TCP_TYPE:
+			return QDF_PROTO_IPV6_TCP;
+
+		default:
+			return QDF_PROTO_INVALID;
+		}
+
+	default:
+		return QDF_PROTO_INVALID;
+	}
+}
+
+static void wma_log_pkt_eapol(uint8_t *data, uint32_t length)
+{
+	uint16_t pkt_len, key_len;
+
+	if (length < WMA_EAPOL_INFO_GET_MIN_LEN)
+		return;
+
+	pkt_len = *(uint16_t *)(data + EAPOL_PKT_LEN_OFFSET);
+	key_len = *(uint16_t *)(data + EAPOL_KEY_LEN_OFFSET);
+	WMA_LOGD("Pkt_len: %u, Key_len: %u",
+		 qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(key_len));
+}
+
+static void wma_log_pkt_dhcp(uint8_t *data, uint32_t length)
+{
+	uint16_t pkt_len;
+	uint32_t trans_id;
+
+	if (length < WMA_DHCP_INFO_GET_MIN_LEN)
+		return;
+
+	pkt_len = *(uint16_t *)(data + DHCP_PKT_LEN_OFFSET);
+	trans_id = *(uint32_t *)(data + DHCP_TRANSACTION_ID_OFFSET);
+	WMA_LOGD("Pkt_len: %u, Transaction_id: %u",
+		 qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(trans_id));
+}
+
+static void wma_log_pkt_icmpv4(uint8_t *data, uint32_t length)
+{
+	uint16_t pkt_len, seq_num;
+
+	if (length < WMA_IPV4_PKT_INFO_GET_MIN_LEN)
+		return;
+
+	pkt_len = *(uint16_t *)(data + IPV4_PKT_LEN_OFFSET);
+	seq_num = *(uint16_t *)(data + ICMP_SEQ_NUM_OFFSET);
+	WMA_LOGD("Pkt_len: %u, Seq_num: %u",
+		 qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(seq_num));
+}
+
+static void wma_log_pkt_icmpv6(uint8_t *data, uint32_t length)
+{
+	uint16_t pkt_len, seq_num;
+
+	if (length < WMA_IPV6_PKT_INFO_GET_MIN_LEN)
+		return;
+
+	pkt_len = *(uint16_t *)(data + IPV6_PKT_LEN_OFFSET);
+	seq_num = *(uint16_t *)(data + ICMPV6_SEQ_NUM_OFFSET);
+	WMA_LOGD("Pkt_len: %u, Seq_num: %u",
+		 qdf_cpu_to_be16(pkt_len), qdf_cpu_to_be16(seq_num));
+}
+
+static void wma_log_pkt_ipv4(uint8_t *data, uint32_t length)
+{
+	uint16_t pkt_len, src_port, dst_port;
+	char *ip_addr;
+
+	if (length < WMA_IPV4_PKT_INFO_GET_MIN_LEN)
+		return;
+
+	pkt_len = *(uint16_t *)(data + IPV4_PKT_LEN_OFFSET);
+	ip_addr = (char *)(data + IPV4_SRC_ADDR_OFFSET);
+	WMA_LOGD("src addr %d:%d:%d:%d", ip_addr[0], ip_addr[1],
+		 ip_addr[2], ip_addr[3]);
+	ip_addr = (char *)(data + IPV4_DST_ADDR_OFFSET);
+	WMA_LOGD("dst addr %d:%d:%d:%d", ip_addr[0], ip_addr[1],
+		 ip_addr[2], ip_addr[3]);
+	src_port = *(uint16_t *)(data + IPV4_SRC_PORT_OFFSET);
+	dst_port = *(uint16_t *)(data + IPV4_DST_PORT_OFFSET);
+	WMA_LOGI("Pkt_len: %u, src_port: %u, dst_port: %u",
+		 qdf_cpu_to_be16(pkt_len),
+		 qdf_cpu_to_be16(src_port),
+		 qdf_cpu_to_be16(dst_port));
+}
+
+static void wma_log_pkt_ipv6(uint8_t *data, uint32_t length)
+{
+	uint16_t pkt_len, src_port, dst_port;
+	char *ip_addr;
+
+	if (length < WMA_IPV6_PKT_INFO_GET_MIN_LEN)
+		return;
+
+	pkt_len = *(uint16_t *)(data + IPV6_PKT_LEN_OFFSET);
+	ip_addr = (char *)(data + IPV6_SRC_ADDR_OFFSET);
+	WMA_LOGD("src addr "IPV6_ADDR_STR, ip_addr[0],
+		 ip_addr[1], ip_addr[2], ip_addr[3], ip_addr[4],
+		 ip_addr[5], ip_addr[6], ip_addr[7], ip_addr[8],
+		 ip_addr[9], ip_addr[10], ip_addr[11],
+		 ip_addr[12], ip_addr[13], ip_addr[14],
+		 ip_addr[15]);
+	ip_addr = (char *)(data + IPV6_DST_ADDR_OFFSET);
+	WMA_LOGD("dst addr "IPV6_ADDR_STR, ip_addr[0],
+		 ip_addr[1], ip_addr[2], ip_addr[3], ip_addr[4],
+		 ip_addr[5], ip_addr[6], ip_addr[7], ip_addr[8],
+		 ip_addr[9], ip_addr[10], ip_addr[11],
+		 ip_addr[12], ip_addr[13], ip_addr[14],
+		 ip_addr[15]);
+	src_port = *(uint16_t *)(data + IPV6_SRC_PORT_OFFSET);
+	dst_port = *(uint16_t *)(data + IPV6_DST_PORT_OFFSET);
+	WMA_LOGI("Pkt_len: %u, src_port: %u, dst_port: %u",
+		 qdf_cpu_to_be16(pkt_len),
+		 qdf_cpu_to_be16(src_port),
+		 qdf_cpu_to_be16(dst_port));
+}
+
+static void wma_log_pkt_tcpv4(uint8_t *data, uint32_t length)
+{
+	uint32_t seq_num;
+
+	if (length < WMA_IPV4_PKT_INFO_GET_MIN_LEN)
+		return;
+
+	seq_num = *(uint32_t *)(data + IPV4_TCP_SEQ_NUM_OFFSET);
+	WMA_LOGD("TCP_seq_num: %u", qdf_cpu_to_be16(seq_num));
+}
+
+static void wma_log_pkt_tcpv6(uint8_t *data, uint32_t length)
+{
+	uint32_t seq_num;
+
+	if (length < WMA_IPV6_PKT_INFO_GET_MIN_LEN)
+		return;
+
+	seq_num = *(uint32_t *)(data + IPV6_TCP_SEQ_NUM_OFFSET);
+	WMA_LOGD("TCP_seq_num: %u", qdf_cpu_to_be16(seq_num));
+}
+
+#ifdef QCA_SUPPORT_CP_STATS
+static void wma_wow_inc_wake_lock_stats_by_dst_addr(t_wma_handle *wma,
+						    uint8_t vdev_id,
+						    uint8_t *dest_mac)
+{
+	ucfg_mc_cp_stats_inc_wake_lock_stats_by_dst_addr(wma->psoc,
+							 vdev_id,
+							 dest_mac);
+}
+
+static void wma_wow_inc_wake_lock_stats_by_protocol(t_wma_handle *wma,
+			uint8_t vdev_id, enum qdf_proto_subtype proto_subtype)
+{
+	ucfg_mc_cp_stats_inc_wake_lock_stats_by_protocol(wma->psoc,
+							 vdev_id,
+							 proto_subtype);
+}
+#else
+static void wma_wow_inc_wake_lock_stats_by_dst_addr(t_wma_handle *wma,
+						    uint8_t vdev_id,
+						    uint8_t *dest_mac)
+{
+	struct wma_txrx_node *vdev;
+	struct sir_vdev_wow_stats *stats;
+
+	vdev = &wma->interfaces[vdev_id];
+	stats = &vdev->wow_stats;
+
+	switch (*dest_mac) {
+	case WMA_BCAST_MAC_ADDR:
+		stats->bcast++;
+		break;
+	case WMA_MCAST_IPV4_MAC_ADDR:
+		stats->ipv4_mcast++;
+		break;
+	case WMA_MCAST_IPV6_MAC_ADDR:
+		stats->ipv6_mcast++;
+		break;
+	default:
+		stats->ucast++;
+		break;
+	}
+}
+
+static void wma_wow_inc_wake_lock_stats_by_protocol(t_wma_handle *wma,
+			uint8_t vdev_id, enum qdf_proto_subtype proto_subtype)
+{
+	struct wma_txrx_node *vdev;
+	struct sir_vdev_wow_stats *stats;
+
+	vdev = &wma->interfaces[vdev_id];
+	stats = &vdev->wow_stats;
+
+	switch (proto_subtype) {
+	case QDF_PROTO_ICMP_RES:
+		stats->icmpv4++;
+		break;
+	case QDF_PROTO_ICMPV6_REQ:
+	case QDF_PROTO_ICMPV6_RES:
+	case QDF_PROTO_ICMPV6_RS:
+		stats->icmpv6++;
+		break;
+	case QDF_PROTO_ICMPV6_RA:
+		stats->icmpv6++;
+		stats->ipv6_mcast_ra++;
+		break;
+	case QDF_PROTO_ICMPV6_NS:
+		stats->icmpv6++;
+		stats->ipv6_mcast_ns++;
+		break;
+	case QDF_PROTO_ICMPV6_NA:
+		stats->icmpv6++;
+		stats->ipv6_mcast_na++;
+		break;
+	default:
+		break;
+	}
+}
+#endif
+
+/**
+ * wma_wow_parse_data_pkt() - API to parse data buffer for data
+ *    packet that resulted in WOW wakeup.
+ * @stats: per-vdev stats for tracking packet types
+ * @data: Pointer to data buffer
+ * @length: data buffer length
+ *
+ * This function parses the data buffer received (first few bytes of
+ * skb->data) to get information like src mac addr, dst mac addr, packet
+ * len, seq_num, etc. It also increments stats for different packet types.
+ *
+ * Return: void
+ */
+static void wma_wow_parse_data_pkt(t_wma_handle *wma,
+				   uint8_t vdev_id, uint8_t *data,
+				   uint32_t length)
+{
+	uint8_t *src_mac;
+	uint8_t *dest_mac;
+	const char *proto_subtype_name;
+	enum qdf_proto_subtype proto_subtype;
+
+	WMA_LOGD("packet length: %u", length);
+	if (length < QDF_NBUF_TRAC_IPV4_OFFSET)
+		return;
+
+	src_mac = data + QDF_NBUF_SRC_MAC_OFFSET;
+	dest_mac = data + QDF_NBUF_DEST_MAC_OFFSET;
+	WMA_LOGI("Src_mac: " MAC_ADDRESS_STR ", Dst_mac: " MAC_ADDRESS_STR,
+		 MAC_ADDR_ARRAY(src_mac), MAC_ADDR_ARRAY(dest_mac));
+
+	wma_wow_inc_wake_lock_stats_by_dst_addr(wma, vdev_id, dest_mac);
+
+	proto_subtype = wma_wow_get_pkt_proto_subtype(data, length);
+	proto_subtype_name = wma_pkt_proto_subtype_to_string(proto_subtype);
+	if (proto_subtype_name)
+		WMA_LOGI("WOW Wakeup: %s rcvd", proto_subtype_name);
+
+	switch (proto_subtype) {
+	case QDF_PROTO_EAPOL_M1:
+	case QDF_PROTO_EAPOL_M2:
+	case QDF_PROTO_EAPOL_M3:
+	case QDF_PROTO_EAPOL_M4:
+		wma_log_pkt_eapol(data, length);
+		break;
+
+	case QDF_PROTO_DHCP_DISCOVER:
+	case QDF_PROTO_DHCP_REQUEST:
+	case QDF_PROTO_DHCP_OFFER:
+	case QDF_PROTO_DHCP_ACK:
+	case QDF_PROTO_DHCP_NACK:
+	case QDF_PROTO_DHCP_RELEASE:
+	case QDF_PROTO_DHCP_INFORM:
+	case QDF_PROTO_DHCP_DECLINE:
+		wma_log_pkt_dhcp(data, length);
+		break;
+
+	case QDF_PROTO_ICMP_REQ:
+	case QDF_PROTO_ICMP_RES:
+		wma_wow_inc_wake_lock_stats_by_protocol(wma, vdev_id,
+							proto_subtype);
+		wma_log_pkt_icmpv4(data, length);
+		break;
+
+	case QDF_PROTO_ICMPV6_REQ:
+	case QDF_PROTO_ICMPV6_RES:
+	case QDF_PROTO_ICMPV6_RS:
+	case QDF_PROTO_ICMPV6_RA:
+	case QDF_PROTO_ICMPV6_NS:
+	case QDF_PROTO_ICMPV6_NA:
+		wma_wow_inc_wake_lock_stats_by_protocol(wma, vdev_id,
+							proto_subtype);
+		wma_log_pkt_icmpv6(data, length);
+		break;
+
+	case QDF_PROTO_IPV4_UDP:
+		wma_log_pkt_ipv4(data, length);
+		break;
+	case QDF_PROTO_IPV4_TCP:
+		wma_log_pkt_ipv4(data, length);
+		wma_log_pkt_tcpv4(data, length);
+		break;
+
+	case QDF_PROTO_IPV6_UDP:
+		wma_log_pkt_ipv6(data, length);
+		break;
+	case QDF_PROTO_IPV6_TCP:
+		wma_log_pkt_ipv6(data, length);
+		wma_log_pkt_tcpv6(data, length);
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ * wma_wow_dump_mgmt_buffer() - API to parse data buffer for mgmt.
+ *    packet that resulted in WOW wakeup.
+ * @wow_packet_buffer: Pointer to data buffer
+ * @buf_len: length of data buffer
+ *
+ * This function parses the data buffer received (802.11 header)
+ * to get information like src mac addr, dst mac addr, seq_num,
+ * frag_num, etc.
+ *
+ * Return: void
+ */
+static void wma_wow_dump_mgmt_buffer(uint8_t *wow_packet_buffer,
+				     uint32_t buf_len)
+{
+	struct ieee80211_frame_addr4 *wh;
+
+	WMA_LOGD("wow_buf_pkt_len: %u", buf_len);
+	wh = (struct ieee80211_frame_addr4 *)
+		(wow_packet_buffer);
+	if (buf_len >= sizeof(struct ieee80211_frame)) {
+		uint8_t to_from_ds, frag_num;
+		uint32_t seq_num;
+
+		WMA_LOGE("RA: " MAC_ADDRESS_STR " TA: " MAC_ADDRESS_STR,
+			MAC_ADDR_ARRAY(wh->i_addr1),
+			MAC_ADDR_ARRAY(wh->i_addr2));
+
+		WMA_LOGE("TO_DS: %u, FROM_DS: %u",
+			wh->i_fc[1] & IEEE80211_FC1_DIR_TODS,
+			wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS);
+
+		to_from_ds = wh->i_fc[1] & IEEE80211_FC1_DIR_DSTODS;
+
+		switch (to_from_ds) {
+		case IEEE80211_NO_DS:
+			WMA_LOGE("BSSID: " MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(wh->i_addr3));
+			break;
+		case IEEE80211_TO_DS:
+			WMA_LOGE("DA: " MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(wh->i_addr3));
+			break;
+		case IEEE80211_FROM_DS:
+			WMA_LOGE("SA: " MAC_ADDRESS_STR,
+				MAC_ADDR_ARRAY(wh->i_addr3));
+			break;
+		case IEEE80211_DS_TO_DS:
+			if (buf_len >= sizeof(struct ieee80211_frame_addr4))
+				WMA_LOGE("DA: " MAC_ADDRESS_STR " SA: "
+					MAC_ADDRESS_STR,
+					MAC_ADDR_ARRAY(wh->i_addr3),
+					MAC_ADDR_ARRAY(wh->i_addr4));
+			break;
+		}
+
+		seq_num = (((*(uint16_t *)wh->i_seq) &
+				IEEE80211_SEQ_SEQ_MASK) >>
+				IEEE80211_SEQ_SEQ_SHIFT);
+		frag_num = (((*(uint16_t *)wh->i_seq) &
+				IEEE80211_SEQ_FRAG_MASK) >>
+				IEEE80211_SEQ_FRAG_SHIFT);
+
+		WMA_LOGE("SEQ_NUM: %u, FRAG_NUM: %u",
+				seq_num, frag_num);
+	} else {
+		WMA_LOGE("Insufficient buffer length for mgmt. packet");
+	}
+}
+
+/**
+ * wma_acquire_wakelock() - conditionally aquires a wakelock base on wake reason
+ * @wma: the wma handle with the wakelocks to aquire
+ * @wake_reason: wow wakeup reason
+ *
+ * Return: None
+ */
+static void wma_acquire_wow_wakelock(t_wma_handle *wma, int wake_reason)
+{
+	qdf_wake_lock_t *wl;
+	uint32_t ms;
+
+	switch (wake_reason) {
+	case WOW_REASON_AUTH_REQ_RECV:
+		wl = &wma->wow_auth_req_wl;
+		ms = WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT;
+		break;
+	case WOW_REASON_ASSOC_REQ_RECV:
+		wl = &wma->wow_assoc_req_wl;
+		ms = WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION;
+		break;
+	case WOW_REASON_DEAUTH_RECVD:
+		wl = &wma->wow_deauth_rec_wl;
+		ms = WMA_DEAUTH_RECV_WAKE_LOCK_DURATION;
+		break;
+	case WOW_REASON_DISASSOC_RECVD:
+		wl = &wma->wow_disassoc_rec_wl;
+		ms = WMA_DISASSOC_RECV_WAKE_LOCK_DURATION;
+		break;
+	case WOW_REASON_AP_ASSOC_LOST:
+		wl = &wma->wow_ap_assoc_lost_wl;
+		ms = WMA_BMISS_EVENT_WAKE_LOCK_DURATION;
+		break;
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+	case WOW_REASON_HOST_AUTO_SHUTDOWN:
+		wl = &wma->wow_auto_shutdown_wl;
+		ms = WMA_AUTO_SHUTDOWN_WAKE_LOCK_DURATION;
+		break;
+#endif
+	case WOW_REASON_ROAM_HO:
+		wl = &wma->roam_ho_wl;
+		ms = WMA_ROAM_HO_WAKE_LOCK_DURATION;
+		break;
+	default:
+		return;
+	}
+
+	WMA_LOGA("Holding %d msec wake_lock", ms);
+	cds_host_diag_log_work(wl, ms, WIFI_POWER_EVENT_WAKELOCK_WOW);
+	qdf_wake_lock_timeout_acquire(wl, ms);
+}
+
+/**
+ * wma_wake_reason_ap_assoc_lost() - WOW_REASON_AP_ASSOC_LOST handler
+ * @wma: Pointer to wma handle
+ * @event: pointer to piggybacked WMI_ROAM_EVENTID_param_tlvs buffer
+ * @len: length of the event buffer
+ *
+ * Return: Errno
+ */
+static int
+wma_wake_reason_ap_assoc_lost(t_wma_handle *wma, void *event, uint32_t len)
+{
+	WMI_ROAM_EVENTID_param_tlvs *event_param;
+	wmi_roam_event_fixed_param *roam_event;
+
+	event_param = event;
+	if (!event_param) {
+		WMA_LOGE("AP Assoc Lost event data is null");
+		return -EINVAL;
+	}
+
+	roam_event = event_param->fixed_param;
+	WMA_LOGA(FL("Beacon miss indication on vdev %d"), roam_event->vdev_id);
+
+	wma_beacon_miss_handler(wma, roam_event->vdev_id, roam_event->rssi);
+
+	return 0;
+}
+
+static const char *wma_vdev_type_str(uint32_t vdev_type)
+{
+	switch (vdev_type) {
+	case WMI_VDEV_TYPE_AP:
+		return "AP";
+	case WMI_VDEV_TYPE_STA:
+		return "STA";
+	case WMI_VDEV_TYPE_IBSS:
+		return "IBSS";
+	case WMI_VDEV_TYPE_MONITOR:
+		return "MONITOR";
+	case WMI_VDEV_TYPE_NAN:
+		return "NAN";
+	case WMI_VDEV_TYPE_OCB:
+		return "OCB";
+	case WMI_VDEV_TYPE_NDI:
+		return "NDI";
+	default:
+		return "unknown";
+	}
+}
+
+static int wma_wake_event_packet(
+	t_wma_handle *wma,
+	WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param,
+	uint32_t length)
+{
+	WOW_EVENT_INFO_fixed_param *wake_info;
+	struct wma_txrx_node *vdev;
+	uint8_t *packet;
+	uint32_t packet_len;
+
+	if (event_param->num_wow_packet_buffer <= 4) {
+		WMA_LOGE("Invalid wow packet buffer from firmware %u",
+			 event_param->num_wow_packet_buffer);
+		return -EINVAL;
+	}
+	/* first 4 bytes are the length, followed by the buffer */
+	packet_len = *(uint32_t *)event_param->wow_packet_buffer;
+	packet = event_param->wow_packet_buffer + 4;
+
+	if (!packet_len) {
+		WMA_LOGE("Wake event packet is empty");
+		return 0;
+	}
+
+	if (packet_len > (event_param->num_wow_packet_buffer - 4)) {
+		WMA_LOGE("Invalid packet_len from firmware, packet_len: %u, num_wow_packet_buffer: %u",
+			 packet_len,
+			 event_param->num_wow_packet_buffer);
+		return -EINVAL;
+	}
+
+	wake_info = event_param->fixed_param;
+
+	switch (wake_info->wake_reason) {
+	case WOW_REASON_AUTH_REQ_RECV:
+	case WOW_REASON_ASSOC_REQ_RECV:
+	case WOW_REASON_DEAUTH_RECVD:
+	case WOW_REASON_DISASSOC_RECVD:
+	case WOW_REASON_ASSOC_RES_RECV:
+	case WOW_REASON_REASSOC_REQ_RECV:
+	case WOW_REASON_REASSOC_RES_RECV:
+	case WOW_REASON_BEACON_RECV:
+	case WOW_REASON_ACTION_FRAME_RECV:
+		/* management frame case */
+		wma_wow_dump_mgmt_buffer(packet, packet_len);
+		break;
+
+	case WOW_REASON_BPF_ALLOW:
+	case WOW_REASON_PATTERN_MATCH_FOUND:
+	case WOW_REASON_RA_MATCH:
+	case WOW_REASON_RECV_MAGIC_PATTERN:
+		WMA_LOGD("Wake event packet:");
+		qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
+				   packet, packet_len);
+
+		vdev = &wma->interfaces[wake_info->vdev_id];
+		wma_wow_parse_data_pkt(wma, wake_info->vdev_id,
+				       packet, packet_len);
+		break;
+
+	default:
+		WMA_LOGE("Wake reason %s(%u) is not a packet event",
+			 wma_wow_wake_reason_str(wake_info->wake_reason),
+			 wake_info->wake_reason);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int wma_wake_event_no_payload(
+	t_wma_handle *wma,
+	WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param,
+	uint32_t length)
+{
+	WOW_EVENT_INFO_fixed_param *wake_info = event_param->fixed_param;
+
+	switch (wake_info->wake_reason) {
+	case WOW_REASON_HOST_AUTO_SHUTDOWN:
+		return wma_wake_reason_auto_shutdown();
+
+	case WOW_REASON_NLOD:
+		return wma_wake_reason_nlod(wma, wake_info->vdev_id);
+
+	default:
+		return 0;
+	}
+}
+
+static int wma_wake_event_piggybacked(
+	t_wma_handle *wma,
+	WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param,
+	uint32_t length)
+{
+	int errno = 0;
+	void *pb_event;
+	uint32_t pb_event_len;
+	uint32_t wake_reason;
+	uint32_t event_id;
+	uint8_t *bssid;
+	uint8_t peer_id;
+	void *peer, *pdev;
+	tpDeleteStaContext del_sta_ctx;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	/*
+	 * There are "normal" cases where a wake reason that usually contains a
+	 * piggybacked event is empty. In these cases we just want to wake up,
+	 * and no action is needed. Bail out now if that is the case.
+	 */
+	if (!event_param->wow_packet_buffer ||
+	    event_param->num_wow_packet_buffer <= 4) {
+		WMA_LOGE("Invalid wow packet buffer from firmware %u",
+			 event_param->num_wow_packet_buffer);
+		return 0;
+	}
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	bssid = wma->interfaces[event_param->fixed_param->vdev_id].bssid;
+	peer = cdp_peer_find_by_addr(soc, pdev, bssid, &peer_id);
+	wake_reason = event_param->fixed_param->wake_reason;
+
+	/* parse piggybacked event from param buffer */
+	{
+		int ret_code;
+		uint8_t *pb_event_buf;
+		uint32_t tag;
+
+		/* first 4 bytes are the length, followed by the buffer */
+		pb_event_len = *(uint32_t *)event_param->wow_packet_buffer;
+		if (pb_event_len > (event_param->num_wow_packet_buffer - 4)) {
+			WMA_LOGE("Invalid pb_event_len from firmware, pb_event_len: %u, num_wow_packet_buffer: %u",
+				 pb_event_len,
+				 event_param->num_wow_packet_buffer);
+			return -EINVAL;
+		}
+		pb_event_buf = event_param->wow_packet_buffer + 4;
+
+		WMA_LOGD("piggybacked event buffer:");
+		qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
+				   pb_event_buf, pb_event_len);
+
+		tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(pb_event_buf));
+		event_id = wow_get_wmi_eventid(wake_reason, tag);
+		if (!event_id) {
+			WMA_LOGE(FL("Unable to find Event Id"));
+			return -EINVAL;
+		}
+
+		ret_code = wmitlv_check_and_pad_event_tlvs(wma, pb_event_buf,
+							   pb_event_len,
+							   event_id, &pb_event);
+		if (ret_code) {
+			WMA_LOGE(FL("Bad TLVs; len:%d, event_id:%d, status:%d"),
+				 pb_event_len, event_id, ret_code);
+			return -EINVAL;
+		}
+	}
+
+	switch (wake_reason) {
+	case WOW_REASON_AP_ASSOC_LOST:
+		errno = wma_wake_reason_ap_assoc_lost(wma, pb_event,
+						      pb_event_len);
+		break;
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+	case WOW_REASON_NLO_SCAN_COMPLETE:
+		errno = target_if_nlo_complete_handler(wma, pb_event,
+						       pb_event_len);
+		break;
+#endif /* FEATURE_WLAN_SCAN_PNO */
+
+	case WOW_REASON_CSA_EVENT:
+		errno = wma_csa_offload_handler(wma, pb_event, pb_event_len);
+		break;
+
+	/*
+	 * WOW_REASON_LOW_RSSI is used for following roaming events -
+	 * WMI_ROAM_REASON_BETTER_AP, WMI_ROAM_REASON_BMISS,
+	 * WMI_ROAM_REASON_SUITABLE_AP will be handled by
+	 * wma_roam_event_callback().
+	 * WOW_REASON_ROAM_HO is associated with
+	 * WMI_ROAM_REASON_HO_FAILED event and it will be handled by
+	 * wma_roam_event_callback().
+	 */
+	case WOW_REASON_LOW_RSSI:
+	case WOW_REASON_ROAM_HO:
+		wlan_roam_debug_log(event_param->fixed_param->vdev_id,
+				    DEBUG_WOW_ROAM_EVENT,
+				    DEBUG_INVALID_PEER_ID,
+				    NULL, NULL, wake_reason,
+				    pb_event_len);
+		if (pb_event_len > 0) {
+			errno = wma_roam_event_callback(wma, pb_event,
+							pb_event_len);
+		} else {
+			/*
+			 * No wow_packet_buffer means a better AP beacon
+			 * will follow in a later event.
+			 */
+			WMA_LOGD("Host woken up because of better AP beacon");
+		}
+		break;
+
+	case WOW_REASON_CLIENT_KICKOUT_EVENT:
+		errno = wma_peer_sta_kickout_event_handler(wma, pb_event,
+							   pb_event_len);
+		break;
+
+#ifdef FEATURE_WLAN_EXTSCAN
+	case WOW_REASON_EXTSCAN:
+		errno = wma_extscan_wow_event_callback(wma, pb_event,
+						       pb_event_len);
+		break;
+#endif
+
+	case WOW_REASON_RSSI_BREACH_EVENT:
+		errno = wma_rssi_breached_event_handler(wma, pb_event,
+							pb_event_len);
+		break;
+
+	case WOW_REASON_NAN_EVENT:
+		errno = wma_nan_rsp_event_handler(wma, pb_event, pb_event_len);
+		break;
+
+	case WOW_REASON_NAN_DATA:
+		errno = wma_ndp_wow_event_callback(wma, pb_event, pb_event_len,
+						   event_id);
+		break;
+
+#ifdef FEATURE_WLAN_TDLS
+	case WOW_REASON_TDLS_CONN_TRACKER_EVENT:
+		errno = wma_tdls_event_handler(wma, pb_event, pb_event_len);
+		break;
+#endif
+
+	case WOW_REASON_TIMER_INTR_RECV:
+		/*
+		 * Right now firmware is not returning any cookie host has
+		 * programmed. So do not check for cookie.
+		 */
+		WMA_LOGE("WOW_REASON_TIMER_INTR_RECV received, indicating key exchange did not finish. Initiate disconnect");
+		del_sta_ctx = qdf_mem_malloc(sizeof(*del_sta_ctx));
+		if (!del_sta_ctx)
+			break;
+
+		del_sta_ctx->is_tdls = false;
+		del_sta_ctx->vdev_id = event_param->fixed_param->vdev_id;
+		del_sta_ctx->staId = peer_id;
+		qdf_mem_copy(del_sta_ctx->addr2, bssid, IEEE80211_ADDR_LEN);
+		qdf_mem_copy(del_sta_ctx->bssId, bssid, IEEE80211_ADDR_LEN);
+		del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE;
+		wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND, del_sta_ctx,
+			     0);
+		break;
+
+	default:
+		WMA_LOGE("Wake reason %s(%u) is not a piggybacked event",
+			 wma_wow_wake_reason_str(wake_reason), wake_reason);
+		errno = -EINVAL;
+		break;
+	}
+
+	wmitlv_free_allocated_event_tlvs(event_id, &pb_event);
+
+	return errno;
+}
+
+static void wma_wake_event_log_reason(t_wma_handle *wma,
+				      WOW_EVENT_INFO_fixed_param *wake_info)
+{
+	struct wma_txrx_node *vdev;
+
+	/* "Unspecified" means APPS triggered wake, else firmware triggered */
+	if (wake_info->wake_reason != WOW_REASON_UNSPECIFIED) {
+		vdev = &wma->interfaces[wake_info->vdev_id];
+		WMA_LOGA("WLAN triggered wakeup: %s (%d), vdev: %d (%s)",
+			 wma_wow_wake_reason_str(wake_info->wake_reason),
+			 wake_info->wake_reason,
+			 wake_info->vdev_id,
+			 wma_vdev_type_str(vdev->type));
+	} else if (!wmi_get_runtime_pm_inprogress(wma->wmi_handle)) {
+		WMA_LOGA("Non-WLAN triggered wakeup: %s (%d)",
+			 wma_wow_wake_reason_str(wake_info->wake_reason),
+			 wake_info->wake_reason);
+	}
+
+	qdf_wow_wakeup_host_event(wake_info->wake_reason);
+	qdf_wma_wow_wakeup_stats_event(wma);
+}
+
+/**
+ * wma_wow_wakeup_host_event() - wakeup host event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: buffer length
+ *
+ * Handler to catch wow wakeup host event. This event will have
+ * reason why the firmware has woken the host.
+ *
+ * Return: Errno
+ */
+int wma_wow_wakeup_host_event(void *handle, uint8_t *event, uint32_t len)
+{
+	int errno;
+	t_wma_handle *wma = handle;
+	WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *event_param;
+	WOW_EVENT_INFO_fixed_param *wake_info;
+
+	event_param = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *)event;
+	if (!event_param) {
+		WMA_LOGE("Wake event data is null");
+		return -EINVAL;
+	}
+
+	wake_info = event_param->fixed_param;
+
+	if (wake_info->vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: received invalid vdev_id %d",
+			 __func__, wake_info->vdev_id);
+		return -EINVAL;
+	}
+
+	wma_wake_event_log_reason(wma, wake_info);
+
+	ucfg_pmo_psoc_wakeup_host_event_received(wma->psoc);
+
+	wma_print_wow_stats(wma, wake_info);
+	/* split based on payload type */
+	if (is_piggybacked_event(wake_info->wake_reason))
+		errno = wma_wake_event_piggybacked(wma, event_param, len);
+	else if (event_param->wow_packet_buffer)
+		errno = wma_wake_event_packet(wma, event_param, len);
+	else
+		errno = wma_wake_event_no_payload(wma, event_param, len);
+
+	wma_inc_wow_stats(wma, wake_info);
+	wma_print_wow_stats(wma, wake_info);
+	wma_acquire_wow_wakelock(wma, wake_info->wake_reason);
+
+	return errno;
+}
+
+#ifdef FEATURE_WLAN_D0WOW
+/**
+ * wma_d0_wow_disable_ack_event() - wakeup host event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: buffer length
+ *
+ * Handler to catch D0-WOW disable ACK event.  This event will have
+ * reason why the firmware has woken the host.
+ * This is for backward compatible with cld2.0.
+ *
+ * Return: 0 for success or error
+ */
+int wma_d0_wow_disable_ack_event(void *handle, uint8_t *event, uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle)handle;
+	WMI_D0_WOW_DISABLE_ACK_EVENTID_param_tlvs *param_buf;
+	wmi_d0_wow_disable_ack_event_fixed_param *resp_data;
+
+	param_buf = (WMI_D0_WOW_DISABLE_ACK_EVENTID_param_tlvs *)event;
+	if (!param_buf) {
+		WMA_LOGE("Invalid D0-WOW disable ACK event buffer!");
+		return -EINVAL;
+	}
+
+	resp_data = param_buf->fixed_param;
+
+	ucfg_pmo_psoc_wakeup_host_event_received(wma->psoc);
+
+	WMA_LOGD("Received D0-WOW disable ACK");
+
+	return 0;
+}
+#else
+int wma_d0_wow_disable_ack_event(void *handle, uint8_t *event, uint32_t len)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wma_pdev_resume_event_handler() - PDEV resume event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: buffer length
+ *
+ * Return: 0 for success or error
+ */
+int wma_pdev_resume_event_handler(void *handle, uint8_t *event, uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	WMA_LOGA("Received PDEV resume event");
+
+	ucfg_pmo_psoc_wakeup_host_event_received(wma->psoc);
+
+	return 0;
+}
+
+/**
+ * wma_del_ts_req() - send DELTS request to fw
+ * @wma: wma handle
+ * @msg: delts params
+ *
+ * Return: none
+ */
+void wma_del_ts_req(tp_wma_handle wma, tDelTsParams *msg)
+{
+	if (!wma_is_vdev_valid(msg->sessionId)) {
+		WMA_LOGE("%s: vdev id:%d is not active ", __func__,
+			 msg->sessionId);
+		qdf_mem_free(msg);
+		return;
+	}
+	if (wmi_unified_del_ts_cmd(wma->wmi_handle,
+				 msg->sessionId,
+				 TID_TO_WME_AC(msg->userPrio))) {
+		WMA_LOGP("%s: Failed to send vdev DELTS command", __func__);
+	}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (msg->setRICparams == true)
+		wma_set_ric_req(wma, msg, false);
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+	qdf_mem_free(msg);
+}
+
+/**
+ * wma_aggr_qos_req() - send aggr qos request to fw
+ * @wma: handle to wma
+ * @pAggrQosRspMsg - combined struct for all ADD_TS requests.
+ *
+ * A function to handle WMA_AGGR_QOS_REQ. This will send out
+ * ADD_TS requestes to firmware in loop for all the ACs with
+ * active flow.
+ *
+ * Return: none
+ */
+void wma_aggr_qos_req(tp_wma_handle wma,
+		      tAggrAddTsParams *pAggrQosRspMsg)
+{
+	wmi_unified_aggr_qos_cmd(wma->wmi_handle,
+			   (struct aggr_add_ts_param *)pAggrQosRspMsg);
+	/* send response to upper layers from here only. */
+	wma_send_msg_high_priority(wma, WMA_AGGR_QOS_RSP, pAggrQosRspMsg, 0);
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * wma_set_tsm_interval() - Set TSM interval
+ * @req: pointer to ADDTS request
+ *
+ * Return: QDF_STATUS_E_FAILURE or QDF_STATUS_SUCCESS
+ */
+static QDF_STATUS wma_set_tsm_interval(tAddTsParams *req)
+{
+	/*
+	 * msmt_interval is in unit called TU (1 TU = 1024 us)
+	 * max value of msmt_interval cannot make resulting
+	 * interval_milliseconds overflow 32 bit
+	 *
+	 */
+	uint32_t interval_milliseconds;
+	struct cdp_pdev *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	interval_milliseconds = (req->tsm_interval * 1024) / 1000;
+
+	cdp_tx_set_compute_interval(cds_get_context(QDF_MODULE_ID_SOC),
+			pdev,
+			interval_milliseconds);
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS wma_set_tsm_interval(tAddTsParams *req)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_ESE */
+
+/**
+ * wma_add_ts_req() - send ADDTS request to fw
+ * @wma: wma handle
+ * @msg: ADDTS params
+ *
+ * Return: none
+ */
+void wma_add_ts_req(tp_wma_handle wma, tAddTsParams *msg)
+{
+	struct add_ts_param cmd = {0};
+
+	msg->status = QDF_STATUS_SUCCESS;
+	if (wma_set_tsm_interval(msg) == QDF_STATUS_SUCCESS) {
+
+		cmd.sme_session_id = msg->sme_session_id;
+		cmd.tspec.tsinfo.traffic.userPrio =
+			TID_TO_WME_AC(msg->tspec.tsinfo.traffic.userPrio);
+		cmd.tspec.mediumTime = msg->tspec.mediumTime;
+		if (wmi_unified_add_ts_cmd(wma->wmi_handle, &cmd))
+			msg->status = QDF_STATUS_E_FAILURE;
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		if (msg->setRICparams == true)
+			wma_set_ric_req(wma, msg, true);
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+	}
+	wma_send_msg_high_priority(wma, WMA_ADD_TS_RSP, msg, 0);
+}
+
+#ifdef FEATURE_WLAN_ESE
+
+#define TSM_DELAY_HISTROGRAM_BINS 4
+/**
+ * wma_process_tsm_stats_req() - process tsm stats request
+ * @wma_handler - handle to wma
+ * @pTsmStatsMsg - TSM stats struct that needs to be populated and
+ *         passed in message.
+ *
+ * A parallel function to WMA_ProcessTsmStatsReq for pronto. This
+ * function fetches stats from data path APIs and post
+ * WMA_TSM_STATS_RSP msg back to LIM.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_tsm_stats_req(tp_wma_handle wma_handler,
+				     void *pTsmStatsMsg)
+{
+	uint8_t counter;
+	uint32_t queue_delay_microsec = 0;
+	uint32_t tx_delay_microsec = 0;
+	uint16_t packet_count = 0;
+	uint16_t packet_loss_count = 0;
+	tpAniTrafStrmMetrics pTsmMetric = NULL;
+	tpAniGetTsmStatsReq pStats = (tpAniGetTsmStatsReq) pTsmStatsMsg;
+	tpAniGetTsmStatsRsp pTsmRspParams = NULL;
+	int tid = pStats->tid;
+	/*
+	 * The number of histrogram bin report by data path api are different
+	 * than required by TSM, hence different (6) size array used
+	 */
+	uint16_t bin_values[QCA_TX_DELAY_HIST_REPORT_BINS] = { 0, };
+	struct cdp_pdev *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		qdf_mem_free(pTsmStatsMsg);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* get required values from data path APIs */
+	cdp_tx_delay(soc,
+		pdev,
+		&queue_delay_microsec,
+		&tx_delay_microsec, tid);
+	cdp_tx_delay_hist(soc,
+		pdev,
+		bin_values, tid);
+	cdp_tx_packet_count(soc,
+		pdev,
+		&packet_count,
+		&packet_loss_count, tid);
+
+	pTsmRspParams = qdf_mem_malloc(sizeof(*pTsmRspParams));
+	if (!pTsmRspParams) {
+		QDF_ASSERT(0);
+		qdf_mem_free(pTsmStatsMsg);
+		return QDF_STATUS_E_NOMEM;
+	}
+	pTsmRspParams->staId = pStats->staId;
+	pTsmRspParams->rc = QDF_STATUS_E_FAILURE;
+	pTsmRspParams->tsmStatsReq = pStats;
+	pTsmMetric = &pTsmRspParams->tsmMetrics;
+	/* populate pTsmMetric */
+	pTsmMetric->UplinkPktQueueDly = queue_delay_microsec;
+	/* store only required number of bin values */
+	for (counter = 0; counter < TSM_DELAY_HISTROGRAM_BINS; counter++) {
+		pTsmMetric->UplinkPktQueueDlyHist[counter] =
+			bin_values[counter];
+	}
+	pTsmMetric->UplinkPktTxDly = tx_delay_microsec;
+	pTsmMetric->UplinkPktLoss = packet_loss_count;
+	pTsmMetric->UplinkPktCount = packet_count;
+
+	/*
+	 * No need to populate roaming delay and roaming count as they are
+	 * being populated just before sending IAPP frame out
+	 */
+	/* post this message to LIM/PE */
+	wma_send_msg(wma_handler, WMA_TSM_STATS_RSP, (void *)pTsmRspParams, 0);
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif /* FEATURE_WLAN_ESE */
+
+/**
+ * wma_process_mcbc_set_filter_req() - process mcbc set filter request
+ * @wma_handle: wma handle
+ * @mcbc_param: mcbc params
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_mcbc_set_filter_req(tp_wma_handle wma_handle,
+					   tSirRcvFltMcAddrList *mcbc_param)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_cesium_enable_ind() - enables cesium functionality in target
+ * @wma: wma handle
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_cesium_enable_ind(tp_wma_handle wma)
+{
+	QDF_STATUS ret;
+	int32_t vdev_id;
+
+	vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
+	if (vdev_id < 0) {
+		WMA_LOGE("%s: IBSS vdev does not exist could not enable cesium",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Send enable cesium command to target */
+	WMA_LOGE("Enable cesium in target for vdevId %d ", vdev_id);
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+				 WMI_VDEV_PARAM_ENABLE_RMC, 1);
+	if (ret) {
+		WMA_LOGE("Enable cesium failed for vdevId %d", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_get_peer_info_req() - sends get peer info cmd to target
+ * @wma: wma handle
+ * @preq: get peer info request
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_get_peer_info_req
+	(tp_wma_handle wma, tSirIbssGetPeerInfoReqParams *pReq)
+{
+	int32_t ret;
+	uint8_t *p;
+	uint16_t len;
+	wmi_buf_t buf;
+	int32_t vdev_id;
+	struct cdp_pdev *pdev;
+	void *peer;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	uint8_t peer_mac[IEEE80211_ADDR_LEN];
+	uint8_t *peer_mac_raw;
+	wmi_peer_info_req_cmd_fixed_param *p_get_peer_info_cmd;
+	uint8_t bcast_mac[IEEE80211_ADDR_LEN] = { 0xff, 0xff, 0xff,
+						  0xff, 0xff, 0xff };
+
+	if (NULL == soc) {
+		WMA_LOGE("%s: SOC context is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
+	if (vdev_id < 0) {
+		WMA_LOGE("%s: IBSS vdev does not exist could not get peer info",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev context", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (0xFF == pReq->staIdx) {
+		/*get info for all peers */
+		qdf_mem_copy(peer_mac, bcast_mac, IEEE80211_ADDR_LEN);
+	} else {
+		/*get info for a single peer */
+		peer = cdp_peer_find_by_local_id(soc,
+				pdev, pReq->staIdx);
+		if (!peer) {
+			WMA_LOGE("%s: Failed to get peer handle using peer id %d",
+				__func__, pReq->staIdx);
+			return QDF_STATUS_E_FAILURE;
+		}
+		peer_mac_raw = cdp_peer_get_peer_mac_addr(soc, peer);
+		if (peer_mac_raw == NULL) {
+			WMA_LOGE("peer_mac_raw is NULL");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		WMA_LOGE("%s: staIdx %d peer mac: 0x%2x:0x%2x:0x%2x:0x%2x:0x%2x:0x%2x",
+			__func__, pReq->staIdx, peer_mac_raw[0],
+			peer_mac_raw[1], peer_mac_raw[2],
+			peer_mac_raw[3], peer_mac_raw[4],
+			peer_mac_raw[5]);
+		qdf_mem_copy(peer_mac, peer_mac_raw, IEEE80211_ADDR_LEN);
+	}
+
+	len = sizeof(wmi_peer_info_req_cmd_fixed_param);
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_FAILURE;
+
+	p = (uint8_t *) wmi_buf_data(buf);
+	qdf_mem_zero(p, len);
+	p_get_peer_info_cmd = (wmi_peer_info_req_cmd_fixed_param *) p;
+
+	WMITLV_SET_HDR(&p_get_peer_info_cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_peer_info_req_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_peer_info_req_cmd_fixed_param));
+
+	p_get_peer_info_cmd->vdev_id = vdev_id;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac,
+				   &p_get_peer_info_cmd->peer_mac_address);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_PEER_INFO_REQ_CMDID);
+	if (ret != QDF_STATUS_SUCCESS)
+		wmi_buf_free(buf);
+
+	WMA_LOGE("IBSS get peer info cmd sent len: %d, vdev %d command id: %d, status: %d",
+		len, vdev_id, WMI_PEER_INFO_REQ_CMDID, ret);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_tx_fail_monitor_ind() - sends tx fail monitor cmd to target
+ * @wma: wma handle
+ * @pReq: tx fail monitor command params
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_tx_fail_monitor_ind(tp_wma_handle wma,
+					tAniTXFailMonitorInd *pReq)
+{
+	QDF_STATUS ret;
+	int32_t vdev_id;
+
+	vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
+	if (vdev_id < 0) {
+		WMA_LOGE("%s: IBSS vdev does not exist could not send fast tx fail monitor indication message to target",
+			__func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Send enable cesium command to target */
+	WMA_LOGE("send fast tx fail monitor ind cmd target for vdevId %d val %d",
+		vdev_id, pReq->tx_fail_count);
+
+	if (pReq->tx_fail_count == 0)
+		wma->hddTxFailCb = NULL;
+	else
+		wma->hddTxFailCb = pReq->txFailIndCallback;
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+				 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR,
+				 pReq->tx_fail_count);
+	if (ret) {
+		WMA_LOGE("tx fail monitor failed for vdevId %d", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_WLAN_RMC
+/**
+ * wma_process_rmc_enable_ind() - enables RMC functionality in target
+ * @wma: wma handle
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_rmc_enable_ind(tp_wma_handle wma)
+{
+	int ret;
+	uint8_t *p;
+	uint16_t len;
+	wmi_buf_t buf;
+	int32_t vdev_id;
+	wmi_rmc_set_mode_cmd_fixed_param *p_rmc_enable_cmd;
+
+	vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
+	if (vdev_id < 0) {
+		WMA_LOGE("%s: IBSS vdev does not exist could not enable RMC",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	len = sizeof(wmi_rmc_set_mode_cmd_fixed_param);
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_FAILURE;
+
+	p = (uint8_t *) wmi_buf_data(buf);
+	qdf_mem_zero(p, len);
+	p_rmc_enable_cmd = (wmi_rmc_set_mode_cmd_fixed_param *) p;
+
+	WMITLV_SET_HDR(&p_rmc_enable_cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_rmc_set_mode_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_rmc_set_mode_cmd_fixed_param));
+
+	p_rmc_enable_cmd->vdev_id = vdev_id;
+	p_rmc_enable_cmd->enable_rmc = WMI_RMC_MODE_ENABLED;
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_RMC_SET_MODE_CMDID);
+	if (ret != QDF_STATUS_SUCCESS)
+		wmi_buf_free(buf);
+
+	WMA_LOGE("Enable RMC cmd sent len: %d, vdev %d command id: %d, status: %d",
+		 len, vdev_id, WMI_RMC_SET_MODE_CMDID, ret);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_rmc_disable_ind() - disables rmc functionality in target
+ * @wma: wma handle
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_rmc_disable_ind(tp_wma_handle wma)
+{
+	int ret;
+	uint8_t *p;
+	uint16_t len;
+	wmi_buf_t buf;
+	int32_t vdev_id;
+	wmi_rmc_set_mode_cmd_fixed_param *p_rmc_disable_cmd;
+
+	vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
+	if (vdev_id < 0) {
+		WMA_LOGE("%s: IBSS vdev does not exist could not disable RMC",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	len = sizeof(wmi_rmc_set_mode_cmd_fixed_param);
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_FAILURE;
+
+	p = (uint8_t *) wmi_buf_data(buf);
+	qdf_mem_zero(p, len);
+	p_rmc_disable_cmd = (wmi_rmc_set_mode_cmd_fixed_param *) p;
+
+	WMITLV_SET_HDR(&p_rmc_disable_cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_rmc_set_mode_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_rmc_set_mode_cmd_fixed_param));
+
+	p_rmc_disable_cmd->vdev_id = vdev_id;
+	p_rmc_disable_cmd->enable_rmc = WMI_RMC_MODE_DISABLED;
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_RMC_SET_MODE_CMDID);
+	if (ret != QDF_STATUS_SUCCESS)
+		wmi_buf_free(buf);
+
+	WMA_LOGE("Disable RMC cmd sent len: %d, vdev %d command id: %d, status: %d",
+		 len, vdev_id, WMI_RMC_SET_MODE_CMDID, ret);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_rmc_action_period_ind() - sends RMC action period to target
+ * @wma: wma handle
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_rmc_action_period_ind(tp_wma_handle wma)
+{
+	int ret;
+	uint8_t *p;
+	uint16_t len;
+	uint32_t periodicity_msec;
+	wmi_buf_t buf;
+	int32_t vdev_id;
+	wmi_rmc_set_action_period_cmd_fixed_param *p_rmc_cmd;
+	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (NULL == mac) {
+		WMA_LOGE("%s: MAC mac does not exist", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vdev_id = wma_find_vdev_by_type(wma, WMI_VDEV_TYPE_IBSS);
+	if (vdev_id < 0) {
+		WMA_LOGE("%s: IBSS vdev does not exist could not send RMC action period to target",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	len = sizeof(wmi_rmc_set_action_period_cmd_fixed_param);
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_FAILURE;
+
+	p = (uint8_t *) wmi_buf_data(buf);
+	qdf_mem_zero(p, len);
+	p_rmc_cmd = (wmi_rmc_set_action_period_cmd_fixed_param *) p;
+
+	WMITLV_SET_HDR(&p_rmc_cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_rmc_set_action_period_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_rmc_set_action_period_cmd_fixed_param));
+
+	periodicity_msec = mac->mlme_cfg->sap_cfg.rmc_action_period_freq;
+	p_rmc_cmd->vdev_id = vdev_id;
+	p_rmc_cmd->periodicity_msec = periodicity_msec;
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				   WMI_RMC_SET_ACTION_PERIOD_CMDID);
+	if (ret != QDF_STATUS_SUCCESS)
+		wmi_buf_free(buf);
+
+	WMA_LOGE("RMC action period %d cmd sent len: %d, vdev %d command id: %d, status: %d",
+		periodicity_msec, len, vdev_id, WMI_RMC_SET_ACTION_PERIOD_CMDID,
+		ret);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_RMC */
+
+/**
+ * wma_process_add_periodic_tx_ptrn_ind - add periodic tx ptrn
+ * @handle: wma handle
+ * @pAddPeriodicTxPtrnParams: tx ptrn params
+ *
+ * Retrun: QDF status
+ */
+QDF_STATUS wma_process_add_periodic_tx_ptrn_ind(WMA_HANDLE handle,
+						tSirAddPeriodicTxPtrn *
+						pAddPeriodicTxPtrnParams)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	struct periodic_tx_pattern *params_ptr;
+	uint8_t vdev_id;
+	QDF_STATUS status;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue fw add pattern cmd",
+			 __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	params_ptr = qdf_mem_malloc(sizeof(*params_ptr));
+	if (!params_ptr)
+		return QDF_STATUS_E_NOMEM;
+
+	if (!wma_find_vdev_by_addr(wma_handle,
+				   pAddPeriodicTxPtrnParams->mac_address.bytes,
+				   &vdev_id)) {
+		WMA_LOGE("%s: Failed to find vdev id for %pM", __func__,
+			 pAddPeriodicTxPtrnParams->mac_address.bytes);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	params_ptr->ucPtrnId = pAddPeriodicTxPtrnParams->ucPtrnId;
+	params_ptr->ucPtrnSize = pAddPeriodicTxPtrnParams->ucPtrnSize;
+	params_ptr->usPtrnIntervalMs =
+				pAddPeriodicTxPtrnParams->usPtrnIntervalMs;
+	qdf_mem_copy(&params_ptr->mac_address,
+			&pAddPeriodicTxPtrnParams->mac_address,
+			sizeof(struct qdf_mac_addr));
+	qdf_mem_copy(params_ptr->ucPattern,
+			pAddPeriodicTxPtrnParams->ucPattern,
+			params_ptr->ucPtrnSize);
+
+	status =  wmi_unified_process_add_periodic_tx_ptrn_cmd(
+			wma_handle->wmi_handle,	params_ptr, vdev_id);
+
+	qdf_mem_free(params_ptr);
+	return status;
+}
+
+/**
+ * wma_process_del_periodic_tx_ptrn_ind - del periodic tx ptrn
+ * @handle: wma handle
+ * @pDelPeriodicTxPtrnParams: tx ptrn params
+ *
+ * Retrun: QDF status
+ */
+QDF_STATUS wma_process_del_periodic_tx_ptrn_ind(WMA_HANDLE handle,
+						tSirDelPeriodicTxPtrn *
+						pDelPeriodicTxPtrnParams)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	uint8_t vdev_id;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue Del Pattern cmd",
+			 __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wma_find_vdev_by_addr(wma_handle,
+				   pDelPeriodicTxPtrnParams->mac_address.bytes,
+				   &vdev_id)) {
+		WMA_LOGE("%s: Failed to find vdev id for %pM", __func__,
+			 pDelPeriodicTxPtrnParams->mac_address.bytes);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wmi_unified_process_del_periodic_tx_ptrn_cmd(
+				wma_handle->wmi_handle, vdev_id,
+				pDelPeriodicTxPtrnParams->ucPtrnId);
+}
+
+#ifdef WLAN_FEATURE_STATS_EXT
+/**
+ * wma_stats_ext_req() - request ext stats from fw
+ * @wma_ptr: wma handle
+ * @preq: stats ext params
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_stats_ext_req(void *wma_ptr, tpStatsExtRequest preq)
+{
+	tp_wma_handle wma = (tp_wma_handle) wma_ptr;
+	struct stats_ext_params *params;
+	size_t params_len;
+	QDF_STATUS status;
+
+	if (!wma) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	params_len = sizeof(*params) + preq->request_data_len;
+	params = qdf_mem_malloc(params_len);
+	if (!params)
+		return QDF_STATUS_E_NOMEM;
+
+	params->vdev_id = preq->vdev_id;
+	params->request_data_len = preq->request_data_len;
+	if (preq->request_data_len > 0)
+		qdf_mem_copy(params->request_data, preq->request_data,
+			     params->request_data_len);
+
+	status = wmi_unified_stats_ext_req_cmd(wma->wmi_handle, params);
+	qdf_mem_free(params);
+
+	return status;
+}
+
+#endif /* WLAN_FEATURE_STATS_EXT */
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+/**
+ * wma_send_status_of_ext_wow() - send ext wow status to SME
+ * @wma: wma handle
+ * @status: status
+ *
+ * Return: none
+ */
+static void wma_send_status_of_ext_wow(tp_wma_handle wma, bool status)
+{
+	tSirReadyToExtWoWInd *ready_to_extwow;
+	QDF_STATUS vstatus;
+	struct scheduler_msg message = {0};
+	uint8_t len;
+
+	WMA_LOGD("Posting ready to suspend indication to umac");
+
+	len = sizeof(tSirReadyToExtWoWInd);
+	ready_to_extwow = qdf_mem_malloc(len);
+	if (!ready_to_extwow)
+		return;
+
+	ready_to_extwow->mesgType = eWNI_SME_READY_TO_EXTWOW_IND;
+	ready_to_extwow->mesgLen = len;
+	ready_to_extwow->status = status;
+
+	message.type = eWNI_SME_READY_TO_EXTWOW_IND;
+	message.bodyptr = (void *)ready_to_extwow;
+	message.bodyval = 0;
+
+	vstatus = scheduler_post_message(QDF_MODULE_ID_WMA,
+					 QDF_MODULE_ID_SME,
+					 QDF_MODULE_ID_SME, &message);
+	if (vstatus != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to post ready to suspend");
+		qdf_mem_free(ready_to_extwow);
+	}
+}
+
+/**
+ * wma_enable_ext_wow() - enable ext wow in fw
+ * @wma: wma handle
+ * @params: ext wow params
+ *
+ * Return:0 for success or error code
+ */
+QDF_STATUS wma_enable_ext_wow(tp_wma_handle wma, tpSirExtWoWParams params)
+{
+	struct ext_wow_params wow_params = {0};
+	QDF_STATUS status;
+
+	if (!wma) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wow_params.vdev_id = params->vdev_id;
+	wow_params.type = (enum wmi_ext_wow_type) params->type;
+	wow_params.wakeup_pin_num = params->wakeup_pin_num;
+
+	status = wmi_unified_enable_ext_wow_cmd(wma->wmi_handle,
+				&wow_params);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	wma_send_status_of_ext_wow(wma, true);
+	return status;
+
+}
+
+/**
+ * wma_set_app_type1_params_in_fw() - set app type1 params in fw
+ * @wma: wma handle
+ * @appType1Params: app type1 params
+ *
+ * Return: QDF status
+ */
+int wma_set_app_type1_params_in_fw(tp_wma_handle wma,
+				   tpSirAppType1Params appType1Params)
+{
+	int ret;
+
+	ret = wmi_unified_app_type1_params_in_fw_cmd(wma->wmi_handle,
+				   (struct app_type1_params *)appType1Params);
+	if (ret) {
+		WMA_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_set_app_type2_params_in_fw() - set app type2 params in fw
+ * @wma: wma handle
+ * @appType2Params: app type2 params
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_set_app_type2_params_in_fw(tp_wma_handle wma,
+					  tpSirAppType2Params appType2Params)
+{
+	struct app_type2_params params = {0};
+
+	if (!wma) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	params.vdev_id = appType2Params->vdev_id;
+	params.rc4_key_len = appType2Params->rc4_key_len;
+	qdf_mem_copy(params.rc4_key, appType2Params->rc4_key, 16);
+	params.ip_id = appType2Params->ip_id;
+	params.ip_device_ip = appType2Params->ip_device_ip;
+	params.ip_server_ip = appType2Params->ip_server_ip;
+	params.tcp_src_port = appType2Params->tcp_src_port;
+	params.tcp_dst_port = appType2Params->tcp_dst_port;
+	params.tcp_seq = appType2Params->tcp_seq;
+	params.tcp_ack_seq = appType2Params->tcp_ack_seq;
+	params.keepalive_init = appType2Params->keepalive_init;
+	params.keepalive_min = appType2Params->keepalive_min;
+	params.keepalive_max = appType2Params->keepalive_max;
+	params.keepalive_inc = appType2Params->keepalive_inc;
+	params.tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val;
+	params.tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val;
+	qdf_mem_copy(&params.gateway_mac, &appType2Params->gateway_mac,
+			sizeof(struct qdf_mac_addr));
+
+	return wmi_unified_set_app_type2_params_in_fw_cmd(wma->wmi_handle,
+							&params);
+}
+#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+/**
+ * wma_auto_shutdown_event_handler() - process auto shutdown timer trigger
+ * @handle: wma handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_auto_shutdown_event_handler(void *handle, uint8_t *event,
+				    uint32_t len)
+{
+	wmi_host_auto_shutdown_event_fixed_param *wmi_auto_sh_evt;
+	WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *param_buf =
+		(WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *)
+		event;
+
+	if (!param_buf || !param_buf->fixed_param) {
+		WMA_LOGE("%s:%d: Invalid Auto shutdown timer evt", __func__,
+			 __LINE__);
+		return -EINVAL;
+	}
+
+	wmi_auto_sh_evt = param_buf->fixed_param;
+
+	if (wmi_auto_sh_evt->shutdown_reason
+	    != WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY) {
+		WMA_LOGE("%s:%d: Invalid Auto shutdown timer evt", __func__,
+			 __LINE__);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("%s:%d: Auto Shutdown Evt: %d", __func__, __LINE__,
+		 wmi_auto_sh_evt->shutdown_reason);
+	return wma_post_auto_shutdown_msg();
+}
+
+/**
+ * wma_set_auto_shutdown_timer_req() - sets auto shutdown timer in firmware
+ * @wma: wma handle
+ * @auto_sh_cmd: auto shutdown timer value
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle,
+						  tSirAutoShutdownCmdParams *
+						  auto_sh_cmd)
+{
+	if (auto_sh_cmd == NULL) {
+		WMA_LOGE("%s : Invalid Autoshutdown cfg cmd", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wmi_unified_set_auto_shutdown_timer_cmd(wma_handle->wmi_handle,
+					auto_sh_cmd->timer_val);
+}
+#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
+
+#ifdef WLAN_FEATURE_NAN
+/**
+ * wma_nan_req() - to send nan request to target
+ * @wma: wma_handle
+ * @nan_req: request data which will be non-null
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_nan_req(void *wma_ptr, tpNanRequest nan_req)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) wma_ptr;
+	struct nan_req_params *params;
+	size_t params_len;
+	QDF_STATUS status;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	params_len = sizeof(*params) + nan_req->request_data_len;
+	params = qdf_mem_malloc(params_len);
+	if (!params)
+		return QDF_STATUS_E_NOMEM;
+
+	params->request_data_len = nan_req->request_data_len;
+	if (params->request_data_len > 0)
+		qdf_mem_copy(params->request_data, nan_req->request_data,
+			     params->request_data_len);
+
+	status = wmi_unified_nan_req_cmd(wma_handle->wmi_handle, params);
+	qdf_mem_free(params);
+
+	return status;
+}
+#endif /* WLAN_FEATURE_NAN */
+
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * wma_process_dhcpserver_offload() - enable DHCP server offload
+ * @wma_handle: wma handle
+ * @pDhcpSrvOffloadInfo: DHCP server offload info
+ *
+ * Return: 0 for success or error code
+ */
+QDF_STATUS wma_process_dhcpserver_offload(tp_wma_handle wma_handle,
+					  tSirDhcpSrvOffloadInfo *
+					  pDhcpSrvOffloadInfo)
+{
+	struct dhcp_offload_info_params params = {0};
+	QDF_STATUS status;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return -EIO;
+	}
+
+	params.vdev_id = pDhcpSrvOffloadInfo->vdev_id;
+	params.dhcp_offload_enabled =
+				pDhcpSrvOffloadInfo->dhcpSrvOffloadEnabled;
+	params.dhcp_client_num = pDhcpSrvOffloadInfo->dhcpClientNum;
+	params.dhcp_srv_addr = pDhcpSrvOffloadInfo->dhcpSrvIP;
+
+	status = wmi_unified_process_dhcpserver_offload_cmd(
+				wma_handle->wmi_handle, &params);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	WMA_LOGD("Set dhcp server offload to vdevId %d",
+		 pDhcpSrvOffloadInfo->vdev_id);
+	return status;
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+/**
+ * wma_set_led_flashing() - set led flashing in fw
+ * @wma_handle: wma handle
+ * @flashing: flashing request
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_set_led_flashing(tp_wma_handle wma_handle,
+				struct flashing_req_params *flashing)
+{
+	QDF_STATUS status;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE(FL("WMA is closed, can not issue cmd"));
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!flashing) {
+		WMA_LOGE(FL("invalid parameter: flashing"));
+		return QDF_STATUS_E_INVAL;
+	}
+	status = wmi_unified_set_led_flashing_cmd(wma_handle->wmi_handle,
+						  flashing);
+	return status;
+}
+#endif /* WLAN_FEATURE_GPIO_LED_FLASHING */
+
+int wma_sar_rsp_evt_handler(ol_scn_t handle, uint8_t *event, uint32_t len)
+{
+	tp_wma_handle wma_handle;
+	wmi_unified_t wmi_handle;
+	QDF_STATUS status;
+
+	WMA_LOGD(FL("handle:%pK event:%pK len:%u"), handle, event, len);
+
+	wma_handle = handle;
+	if (!wma_handle) {
+		WMA_LOGE(FL("NULL wma_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_handle = wma_handle->wmi_handle;
+	if (!wmi_handle) {
+		WMA_LOGE(FL("NULL wmi_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_extract_sar2_result_event(wmi_handle,
+						       event, len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE(FL("Event extract failure: %d"), status);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+#ifdef FEATURE_WLAN_CH_AVOID
+/**
+ * wma_process_ch_avoid_update_req() - handles channel avoid update request
+ * @wma_handle: wma handle
+ * @ch_avoid_update_req: channel avoid update params
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_ch_avoid_update_req(tp_wma_handle wma_handle,
+					   tSirChAvoidUpdateReq *
+					   ch_avoid_update_req)
+{
+	QDF_STATUS status;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (ch_avoid_update_req == NULL) {
+		WMA_LOGE("%s : ch_avoid_update_req is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("%s: WMA --> WMI_CHAN_AVOID_UPDATE", __func__);
+
+	status = wmi_unified_process_ch_avoid_update_cmd(
+					wma_handle->wmi_handle);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	WMA_LOGD("%s: WMA --> WMI_CHAN_AVOID_UPDATE sent through WMI",
+		 __func__);
+	return status;
+}
+#endif
+
+/**
+ * wma_send_regdomain_info_to_fw() - send regdomain info to fw
+ * @reg_dmn: reg domain
+ * @regdmn2G: 2G reg domain
+ * @regdmn5G: 5G reg domain
+ * @ctl2G: 2G test limit
+ * @ctl5G: 5G test limit
+ *
+ * Return: none
+ */
+void wma_send_regdomain_info_to_fw(uint32_t reg_dmn, uint16_t regdmn2G,
+				   uint16_t regdmn5G, uint8_t ctl2G,
+				   uint8_t ctl5G)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	int32_t cck_mask_val = 0;
+	struct pdev_params pdev_param = {0};
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	WMA_LOGD("reg_dmn: %d regdmn2g: %d regdmn5g :%d ctl2g: %d ctl5g: %d",
+		 reg_dmn, regdmn2G, regdmn5G, ctl2G, ctl5G);
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: wma context is NULL", __func__);
+		return;
+	}
+
+	status = wmi_unified_send_regdomain_info_to_fw_cmd(wma->wmi_handle,
+			reg_dmn, regdmn2G, regdmn5G, ctl2G, ctl5G);
+	if (status == QDF_STATUS_E_NOMEM)
+		return;
+
+	if ((((reg_dmn & ~CTRY_FLAG) == CTRY_JAPAN15) ||
+	     ((reg_dmn & ~CTRY_FLAG) == CTRY_KOREA_ROC)) &&
+	    (true == wma->tx_chain_mask_cck))
+		cck_mask_val = 1;
+
+	cck_mask_val |= (wma->self_gen_frm_pwr << 16);
+	pdev_param.param_id = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK;
+	pdev_param.param_value = cck_mask_val;
+	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
+					 &pdev_param,
+					 WMA_WILDCARD_PDEV_ID);
+
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("failed to set PDEV tx_chain_mask_cck %d",
+			 ret);
+}
+
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * wma_tdls_event_handler() - handle TDLS event
+ * @handle: wma handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_tdls_event_handler(void *handle, uint8_t *event, uint32_t len)
+{
+	/* TODO update with target rx ops */
+	return 0;
+}
+
+/**
+ * wma_set_tdls_offchan_mode() - set tdls off channel mode
+ * @handle: wma handle
+ * @chan_switch_params: Pointer to tdls channel switch parameter structure
+ *
+ * This function sets tdls off channel mode
+ *
+ * Return: 0 on success; Negative errno otherwise
+ */
+QDF_STATUS wma_set_tdls_offchan_mode(WMA_HANDLE handle,
+			      tdls_chan_switch_params *chan_switch_params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	struct tdls_channel_switch_params params = {0};
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE(FL(
+			    "WMA is closed, can not issue tdls off channel cmd"
+			 ));
+		ret = -EINVAL;
+		goto end;
+	}
+
+	if (wma_is_roam_synch_in_progress(wma_handle,
+					  chan_switch_params->vdev_id)) {
+		WMA_LOGE("%s: roaming in progress, reject offchan mode cmd!",
+			 __func__);
+		ret = -EPERM;
+		goto end;
+	}
+
+	params.vdev_id = chan_switch_params->vdev_id;
+	params.tdls_off_ch_bw_offset =
+			chan_switch_params->tdls_off_ch_bw_offset;
+	params.tdls_off_ch = chan_switch_params->tdls_off_ch;
+	params.tdls_sw_mode = chan_switch_params->tdls_sw_mode;
+	params.oper_class = chan_switch_params->oper_class;
+	params.is_responder = chan_switch_params->is_responder;
+	qdf_mem_copy(params.peer_mac_addr, chan_switch_params->peer_mac_addr,
+		     IEEE80211_ADDR_LEN);
+
+	ret = wmi_unified_set_tdls_offchan_mode_cmd(wma_handle->wmi_handle,
+							&params);
+
+end:
+	if (chan_switch_params)
+		qdf_mem_free(chan_switch_params);
+	return ret;
+}
+
+/**
+ * wma_update_tdls_peer_state() - update TDLS peer state
+ * @handle: wma handle
+ * @peerStateParams: TDLS peer state params
+ *
+ * Return: 0 for success or error code
+ */
+int wma_update_tdls_peer_state(WMA_HANDLE handle,
+			       tTdlsPeerStateParams *peerStateParams)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	uint32_t i;
+	struct cdp_pdev *pdev;
+	uint8_t peer_id;
+	void *peer;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	uint8_t *peer_mac_addr;
+	int ret = 0;
+	uint32_t *ch_mhz = NULL;
+	bool restore_last_peer = false;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
+		ret = -EINVAL;
+		goto end_tdls_peer_state;
+	}
+
+	if (!soc) {
+		WMA_LOGE("%s: SOC context is NULL", __func__);
+		ret = -EINVAL;
+		goto end_tdls_peer_state;
+	}
+
+	if (wma_is_roam_synch_in_progress(wma_handle,
+					  peerStateParams->vdevId)) {
+		WMA_LOGE("%s: roaming in progress, reject peer update cmd!",
+			 __func__);
+		ret = -EPERM;
+		goto end_tdls_peer_state;
+	}
+
+	/* peer capability info is valid only when peer state is connected */
+	if (WMA_TDLS_PEER_STATE_CONNECTED != peerStateParams->peerState) {
+		qdf_mem_zero(&peerStateParams->peerCap,
+			     sizeof(tTdlsPeerCapParams));
+	}
+
+	if (peerStateParams->peerCap.peerChanLen) {
+		ch_mhz = qdf_mem_malloc(sizeof(uint32_t) *
+				peerStateParams->peerCap.peerChanLen);
+		if (!ch_mhz) {
+			ret = -ENOMEM;
+			goto end_tdls_peer_state;
+		}
+	}
+
+	for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) {
+		ch_mhz[i] =
+			cds_chan_to_freq(peerStateParams->peerCap.peerChan[i].
+					 chanId);
+	}
+
+	/* Make sure that peer exists before sending peer state cmd*/
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE("%s: Failed to find pdev", __func__);
+		ret = -EIO;
+		goto end_tdls_peer_state;
+	}
+
+	peer = cdp_peer_find_by_addr(soc,
+			pdev,
+			peerStateParams->peerMacAddr,
+			&peer_id);
+	if (!peer) {
+		WMA_LOGE("%s: Failed to get peer handle using peer mac %pM",
+				__func__, peerStateParams->peerMacAddr);
+		ret = -EIO;
+		goto end_tdls_peer_state;
+	}
+
+	if (wmi_unified_update_tdls_peer_state_cmd(wma_handle->wmi_handle,
+			 (struct tdls_peer_state_params *)peerStateParams,
+			 ch_mhz)) {
+		WMA_LOGE("%s: failed to send tdls peer update state command",
+			 __func__);
+		ret = -EIO;
+		goto end_tdls_peer_state;
+	}
+
+	/* in case of teardown, remove peer from fw */
+	if (WMA_TDLS_PEER_STATE_TEARDOWN == peerStateParams->peerState) {
+		peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer);
+		if (peer_mac_addr == NULL) {
+			WMA_LOGE("peer_mac_addr is NULL");
+			ret = -EIO;
+			goto end_tdls_peer_state;
+		}
+
+		restore_last_peer = cdp_peer_is_vdev_restore_last_peer(
+						soc, peer);
+
+		WMA_LOGD("%s: calling wma_remove_peer for peer " MAC_ADDRESS_STR
+			 " vdevId: %d", __func__,
+			 MAC_ADDR_ARRAY(peer_mac_addr),
+			 peerStateParams->vdevId);
+		wma_remove_peer(wma_handle, peer_mac_addr,
+				peerStateParams->vdevId, peer, false);
+		cdp_peer_update_last_real_peer(soc,
+				pdev, peer, &peer_id,
+				restore_last_peer);
+	}
+
+end_tdls_peer_state:
+	if (ch_mhz)
+		qdf_mem_free(ch_mhz);
+	if (peerStateParams)
+		qdf_mem_free(peerStateParams);
+	return ret;
+}
+#endif /* FEATURE_WLAN_TDLS */
+
+
+/*
+ * wma_process_set_ie_info() - Function to send IE info to firmware
+ * @wma:                Pointer to WMA handle
+ * @ie_data:       Pointer for ie data
+ *
+ * This function sends IE information to firmware
+ *
+ * Return: QDF_STATUS_SUCCESS for success otherwise failure
+ *
+ */
+QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma,
+				   struct vdev_ie_info *ie_info)
+{
+	struct wma_txrx_node *interface;
+	struct vdev_ie_info_param cmd = {0};
+
+	if (!ie_info || !wma) {
+		WMA_LOGE(FL("input pointer is NULL"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Validate the input */
+	if (ie_info->length  <= 0) {
+		WMA_LOGE(FL("Invalid IE length"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wma_is_vdev_valid(ie_info->vdev_id)) {
+		WMA_LOGE(FL("vdev_id: %d is not active"), ie_info->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	interface = &wma->interfaces[ie_info->vdev_id];
+	cmd.vdev_id = ie_info->vdev_id;
+	cmd.ie_id = ie_info->ie_id;
+	cmd.length = ie_info->length;
+	cmd.band = ie_info->band;
+	cmd.data = ie_info->data;
+	cmd.ie_source = WMA_SET_VDEV_IE_SOURCE_HOST;
+
+	WMA_LOGD(FL("vdev id: %d, ie_id: %d, band: %d, len: %d"),
+		 ie_info->vdev_id, ie_info->ie_id, ie_info->band,
+		 ie_info->length);
+
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
+		ie_info->data, ie_info->length);
+
+	return wmi_unified_process_set_ie_info_cmd(wma->wmi_handle, &cmd);
+}
+
+#ifdef FEATURE_WLAN_APF
+/**
+ *  wma_get_apf_caps_event_handler() - Event handler for get apf capability
+ *  @handle: WMA global handle
+ *  @cmd_param_info: command event data
+ *  @len: Length of @cmd_param_info
+ *
+ *  Return: 0 on Success or Errno on failure
+ */
+int wma_get_apf_caps_event_handler(void *handle, u_int8_t *cmd_param_info,
+				   u_int32_t len)
+{
+	WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs  *param_buf;
+	wmi_bpf_capability_info_evt_fixed_param *event;
+	struct sir_apf_get_offload *apf_get_offload;
+	tpAniSirGlobal pmac = (tpAniSirGlobal)cds_get_context(
+				QDF_MODULE_ID_PE);
+
+	if (!pmac) {
+		WMA_LOGE("%s: Invalid pmac", __func__);
+		return -EINVAL;
+	}
+	if (!pmac->sme.apf_get_offload_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+
+	param_buf = (WMI_BPF_CAPABILIY_INFO_EVENTID_param_tlvs *)cmd_param_info;
+	event = param_buf->fixed_param;
+	apf_get_offload = qdf_mem_malloc(sizeof(*apf_get_offload));
+	if (!apf_get_offload)
+		return -ENOMEM;
+
+	apf_get_offload->apf_version = event->bpf_version;
+	apf_get_offload->max_apf_filters = event->max_bpf_filters;
+	apf_get_offload->max_bytes_for_apf_inst =
+			event->max_bytes_for_bpf_inst;
+	WMA_LOGD("%s: APF capabilities version: %d max apf filter size: %d",
+		 __func__, apf_get_offload->apf_version,
+		 apf_get_offload->max_bytes_for_apf_inst);
+
+	WMA_LOGD("%s: sending apf capabilities event to hdd", __func__);
+	pmac->sme.apf_get_offload_cb(pmac->sme.apf_get_offload_context,
+				     apf_get_offload);
+	qdf_mem_free(apf_get_offload);
+	return 0;
+}
+
+QDF_STATUS wma_get_apf_capabilities(tp_wma_handle wma)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	wmi_bpf_get_capability_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint32_t   len;
+	u_int8_t *buf_ptr;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE(FL("WMA is closed, can not issue get APF capab"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wmi_service_enabled(wma->wmi_handle, wmi_service_apf_offload)) {
+		WMA_LOGE(FL("APF cababilities feature bit not enabled"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	len = sizeof(*cmd);
+	wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!wmi_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf);
+	cmd = (wmi_bpf_get_capability_cmd_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	WMITLV_TAG_STRUC_wmi_bpf_get_capability_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+		wmi_bpf_get_capability_cmd_fixed_param));
+
+	if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
+				 WMI_BPF_GET_CAPABILITY_CMDID)) {
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return status;
+}
+
+QDF_STATUS wma_set_apf_instructions(tp_wma_handle wma,
+				    struct sir_apf_set_offload *apf_set_offload)
+{
+	wmi_bpf_set_vdev_instructions_cmd_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint32_t   len = 0, len_aligned = 0;
+	u_int8_t *buf_ptr;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue set APF capability",
+			__func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wmi_service_enabled(wma->wmi_handle,
+		wmi_service_apf_offload)) {
+		WMA_LOGE(FL("APF offload feature Disabled"));
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	if (!apf_set_offload) {
+		WMA_LOGE("%s: Invalid APF instruction request", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (apf_set_offload->session_id >= wma->max_bssid) {
+		WMA_LOGE(FL("Invalid vdev_id: %d"),
+			 apf_set_offload->session_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wma_is_vdev_up(apf_set_offload->session_id)) {
+		WMA_LOGE("vdev %d is not up skipping APF offload",
+			 apf_set_offload->session_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (apf_set_offload->total_length) {
+		len_aligned = roundup(apf_set_offload->current_length,
+					sizeof(A_UINT32));
+		len = len_aligned + WMI_TLV_HDR_SIZE;
+	}
+
+	len += sizeof(*cmd);
+	wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!wmi_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf);
+	cmd = (wmi_bpf_set_vdev_instructions_cmd_fixed_param *) buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_bpf_set_vdev_instructions_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_bpf_set_vdev_instructions_cmd_fixed_param));
+	cmd->vdev_id = apf_set_offload->session_id;
+	cmd->filter_id = apf_set_offload->filter_id;
+	cmd->total_length = apf_set_offload->total_length;
+	cmd->current_offset = apf_set_offload->current_offset;
+	cmd->current_length = apf_set_offload->current_length;
+
+	if (apf_set_offload->total_length) {
+		buf_ptr +=
+			sizeof(wmi_bpf_set_vdev_instructions_cmd_fixed_param);
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, len_aligned);
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		qdf_mem_copy(buf_ptr, apf_set_offload->program,
+			     apf_set_offload->current_length);
+	}
+
+	if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
+				 WMI_BPF_SET_VDEV_INSTRUCTIONS_CMDID)) {
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+	WMA_LOGD(FL("APF offload enabled in fw"));
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wma_send_apf_enable_cmd(WMA_HANDLE handle, uint8_t vdev_id,
+				   bool apf_enable)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE(FL("WMA is closed, can not issue get APF capab"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
+		WMI_SERVICE_BPF_OFFLOAD)) {
+		WMA_LOGE(FL("APF cababilities feature bit not enabled"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = wmi_unified_send_apf_enable_cmd(wma->wmi_handle, vdev_id,
+						 apf_enable);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Failed to send apf enable/disable cmd");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (apf_enable)
+		WMA_LOGD("Sent APF Enable on vdevid: %d", vdev_id);
+	else
+		WMA_LOGD("Sent APF Disable on vdevid: %d", vdev_id);
+
+	return status;
+}
+
+QDF_STATUS
+wma_send_apf_write_work_memory_cmd(WMA_HANDLE handle,
+				   struct wmi_apf_write_memory_params
+								*write_params)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE(FL("WMA is closed, can not issue write APF mem"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
+		WMI_SERVICE_BPF_OFFLOAD)) {
+		WMA_LOGE(FL("APF cababilities feature bit not enabled"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (wmi_unified_send_apf_write_work_memory_cmd(wma->wmi_handle,
+						       write_params)) {
+		WMA_LOGE(FL("Failed to send APF write mem command"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("Sent APF wite mem on vdevid: %d", write_params->vdev_id);
+	return status;
+}
+
+int wma_apf_read_work_memory_event_handler(void *handle, uint8_t *evt_buf,
+					   uint32_t len)
+{
+	tp_wma_handle wma_handle;
+	wmi_unified_t wmi_handle;
+	struct wmi_apf_read_memory_resp_event_params evt_params = {0};
+	QDF_STATUS status;
+	tpAniSirGlobal pmac = cds_get_context(QDF_MODULE_ID_PE);
+
+	WMA_LOGD(FL("handle:%pK event:%pK len:%u"), handle, evt_buf, len);
+
+	wma_handle = handle;
+	if (!wma_handle) {
+		WMA_LOGE(FL("NULL wma_handle"));
+		return -EINVAL;
+	}
+
+	wmi_handle = wma_handle->wmi_handle;
+	if (!wmi_handle) {
+		WMA_LOGE(FL("NULL wmi_handle"));
+		return -EINVAL;
+	}
+
+	if (!pmac) {
+		WMA_LOGE(FL("Invalid pmac"));
+		return -EINVAL;
+	}
+
+	if (!pmac->sme.apf_read_mem_cb) {
+		WMA_LOGE(FL("Callback not registered"));
+		return -EINVAL;
+	}
+
+	status = wmi_extract_apf_read_memory_resp_event(wmi_handle,
+						evt_buf, &evt_params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE(FL("Event extract failure: %d"), status);
+		return -EINVAL;
+	}
+
+	pmac->sme.apf_read_mem_cb(pmac->hdd_handle, &evt_params);
+
+	return 0;
+}
+
+QDF_STATUS wma_send_apf_read_work_memory_cmd(WMA_HANDLE handle,
+					     struct wmi_apf_read_memory_params
+								  *read_params)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE(FL("WMA is closed, can not issue read APF memory"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
+		WMI_SERVICE_BPF_OFFLOAD)) {
+		WMA_LOGE(FL("APF cababilities feature bit not enabled"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (wmi_unified_send_apf_read_work_memory_cmd(wma->wmi_handle,
+						      read_params)) {
+		WMA_LOGE(FL("Failed to send APF read memory command"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("Sent APF read memory on vdevid: %d", read_params->vdev_id);
+	return status;
+}
+#endif /* FEATURE_WLAN_APF */
+
+/**
+ * wma_set_tx_rx_aggregation_size() - sets tx rx aggregation sizes
+ * @tx_rx_aggregation_size: aggregation size parameters
+ *
+ * This function sets tx rx aggregation sizes
+ *
+ * Return: VOS_STATUS_SUCCESS on success, error number otherwise
+ */
+QDF_STATUS wma_set_tx_rx_aggregation_size(
+	struct sir_set_tx_rx_aggregation_size *tx_rx_aggregation_size)
+{
+	tp_wma_handle wma_handle;
+	wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd;
+	int32_t len;
+	wmi_buf_t buf;
+	u_int8_t *buf_ptr;
+	int ret;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!tx_rx_aggregation_size) {
+		WMA_LOGE("%s: invalid pointer", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
+	cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) buf_ptr;
+	qdf_mem_zero(cmd, sizeof(*cmd));
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_vdev_set_custom_aggr_size_cmd_fixed_param));
+
+	cmd->vdev_id = tx_rx_aggregation_size->vdev_id;
+	cmd->tx_aggr_size = tx_rx_aggregation_size->tx_aggregation_size;
+	cmd->rx_aggr_size = tx_rx_aggregation_size->rx_aggregation_size;
+	/* bit 2 (aggr_type): TX Aggregation Type (0=A-MPDU, 1=A-MSDU) */
+	if (tx_rx_aggregation_size->aggr_type ==
+	    WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU)
+		cmd->enable_bitmap |= 0x04;
+
+	WMA_LOGD("tx aggr: %d rx aggr: %d vdev: %d enable_bitmap %d",
+		 cmd->tx_aggr_size, cmd->rx_aggr_size, cmd->vdev_id,
+		 cmd->enable_bitmap);
+
+	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+				WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID);
+	if (ret) {
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wma_set_tx_rx_aggregation_size_per_ac(
+	struct sir_set_tx_rx_aggregation_size *tx_rx_aggregation_size)
+{
+	tp_wma_handle wma_handle;
+	wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd;
+	int32_t len;
+	wmi_buf_t buf;
+	u_int8_t *buf_ptr;
+	int ret;
+	int queue_num;
+	uint32_t tx_aggr_size[4];
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!tx_rx_aggregation_size) {
+		WMA_LOGE("%s: invalid pointer", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_aggr_size[0] = tx_rx_aggregation_size->tx_aggregation_size_be;
+	tx_aggr_size[1] = tx_rx_aggregation_size->tx_aggregation_size_bk;
+	tx_aggr_size[2] = tx_rx_aggregation_size->tx_aggregation_size_vi;
+	tx_aggr_size[3] = tx_rx_aggregation_size->tx_aggregation_size_vo;
+
+	for (queue_num = 0; queue_num < 4; queue_num++) {
+		if (tx_aggr_size[queue_num] == 0)
+			continue;
+
+		len = sizeof(*cmd);
+		buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+		if (!buf)
+			return QDF_STATUS_E_NOMEM;
+
+		buf_ptr = (u_int8_t *)wmi_buf_data(buf);
+		cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *)buf_ptr;
+		qdf_mem_zero(cmd, sizeof(*cmd));
+
+		WMITLV_SET_HDR(&cmd->tlv_header,
+			       WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param,
+			       WMITLV_GET_STRUCT_TLVLEN(
+					wmi_vdev_set_custom_aggr_size_cmd_fixed_param));
+
+		cmd->vdev_id = tx_rx_aggregation_size->vdev_id;
+		cmd->rx_aggr_size =
+				  tx_rx_aggregation_size->rx_aggregation_size;
+
+		cmd->tx_aggr_size = tx_aggr_size[queue_num];
+		/* bit 5: tx_ac_enable, if set, ac bitmap is valid. */
+		cmd->enable_bitmap = 0x20 | queue_num;
+		/* bit 2 (aggr_type): TX Aggregation Type (0=A-MPDU, 1=A-MSDU) */
+		if (tx_rx_aggregation_size->aggr_type ==
+		    WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU)
+			cmd->enable_bitmap |= 0x04;
+
+		WMA_LOGD("queue_num: %d, tx aggr: %d rx aggr: %d vdev: %d, bitmap: %d",
+			 queue_num, cmd->tx_aggr_size,
+			 cmd->rx_aggr_size, cmd->vdev_id,
+			 cmd->enable_bitmap);
+
+		ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+					WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID);
+		if (ret) {
+			wmi_buf_free(buf);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS wma_set_sw_retry_by_qos(
+	tp_wma_handle handle, uint8_t vdev_id,
+	wmi_vdev_custom_sw_retry_type_t retry_type,
+	wmi_traffic_ac ac_type,
+	uint32_t sw_retry)
+{
+	wmi_vdev_set_custom_sw_retry_th_cmd_fixed_param *cmd;
+	int32_t len;
+	wmi_buf_t buf;
+	u_int8_t *buf_ptr;
+	int ret;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(handle->wmi_handle, len);
+
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (u_int8_t *)wmi_buf_data(buf);
+	cmd = (wmi_vdev_set_custom_sw_retry_th_cmd_fixed_param *)buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_vdev_set_custom_sw_retry_th_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+		       wmi_vdev_set_custom_sw_retry_th_cmd_fixed_param));
+
+	cmd->vdev_id = vdev_id;
+	cmd->ac_type = ac_type;
+	cmd->sw_retry_type = retry_type;
+	cmd->sw_retry_th = sw_retry;
+
+	wma_debug("ac_type: %d re_type: %d threshold: %d vid: %d",
+		  cmd->ac_type, cmd->sw_retry_type,
+		  cmd->sw_retry_th, cmd->vdev_id);
+
+	ret = wmi_unified_cmd_send(handle->wmi_handle,
+				   buf, len,
+				   WMI_VDEV_SET_CUSTOM_SW_RETRY_TH_CMDID);
+
+	if (ret) {
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wma_set_sw_retry_threshold(
+	WMA_HANDLE handle,
+	struct sir_set_tx_sw_retry_threshold *tx_sw_retry_threshold)
+{
+	QDF_STATUS ret;
+	tp_wma_handle wma_handle;
+	uint8_t vdev_id;
+	int retry_type, queue_num;
+	uint32_t tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_MAX][WMI_AC_MAX];
+	uint32_t sw_retry;
+
+	wma_handle = (tp_wma_handle)handle;
+
+	if (!tx_sw_retry_threshold) {
+		wma_err("%s: invalid pointer", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wma_handle) {
+		wma_err("%s: WMA context is invalid!", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_BE] =
+		tx_sw_retry_threshold->tx_aggr_sw_retry_threshold_be;
+	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_BK] =
+		tx_sw_retry_threshold->tx_aggr_sw_retry_threshold_bk;
+	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_VI] =
+		tx_sw_retry_threshold->tx_aggr_sw_retry_threshold_vi;
+	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_VO] =
+		tx_sw_retry_threshold->tx_aggr_sw_retry_threshold_vo;
+
+	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_BE] =
+		tx_sw_retry_threshold->tx_non_aggr_sw_retry_threshold_be;
+	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_BK] =
+		tx_sw_retry_threshold->tx_non_aggr_sw_retry_threshold_bk;
+	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_VI] =
+		tx_sw_retry_threshold->tx_non_aggr_sw_retry_threshold_vi;
+	tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_VO] =
+		tx_sw_retry_threshold->tx_non_aggr_sw_retry_threshold_vo;
+
+	retry_type = WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR;
+	while (retry_type < WMI_VDEV_CUSTOM_SW_RETRY_TYPE_MAX) {
+		for (queue_num = 0; queue_num < WMI_AC_MAX; queue_num++) {
+			if (tx_sw_retry[retry_type][queue_num] == 0)
+				continue;
+
+			vdev_id = tx_sw_retry_threshold->vdev_id;
+			sw_retry = tx_sw_retry[retry_type][queue_num];
+			ret = wma_set_sw_retry_by_qos(wma_handle,
+						      vdev_id,
+						      retry_type,
+						      queue_num,
+						      sw_retry);
+
+			if (QDF_IS_STATUS_ERROR(ret))
+				return ret;
+		}
+		retry_type++;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_P2P_LISTEN_OFFLOAD
+/**
+ *  wma_p2p_lo_start() - P2P listen offload start
+ *  @params: p2p listen offload parameters
+ *
+ *  This function sends WMI command to start P2P listen offload.
+ *
+ *  Return: QDF_STATUS enumeration
+ */
+QDF_STATUS wma_p2p_lo_start(struct sir_p2p_lo_start *params)
+{
+	wmi_buf_t buf;
+	wmi_p2p_lo_start_cmd_fixed_param *cmd;
+	int32_t len = sizeof(*cmd);
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	uint8_t *buf_ptr;
+	int ret;
+	int device_types_len_aligned, probe_resp_len_aligned;
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: wma context is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	device_types_len_aligned = qdf_roundup(params->dev_types_len,
+						sizeof(A_UINT32));
+	probe_resp_len_aligned = qdf_roundup(params->probe_resp_len,
+						sizeof(A_UINT32));
+
+	len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned +
+			probe_resp_len_aligned;
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf);
+	buf_ptr = (uint8_t *) wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param,
+		 WMITLV_GET_STRUCT_TLVLEN(
+			wmi_p2p_lo_start_cmd_fixed_param));
+
+	cmd->vdev_id = params->vdev_id;
+	cmd->ctl_flags = params->ctl_flags;
+	cmd->channel = params->freq;
+	cmd->period = params->period;
+	cmd->interval = params->interval;
+	cmd->count = params->count;
+	cmd->device_types_len = params->dev_types_len;
+	cmd->prob_resp_len = params->probe_resp_len;
+
+	buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+				device_types_len_aligned);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	qdf_mem_copy(buf_ptr, params->device_types, params->dev_types_len);
+
+	buf_ptr += device_types_len_aligned;
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, probe_resp_len_aligned);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	qdf_mem_copy(buf_ptr, params->probe_resp_tmplt, params->probe_resp_len);
+
+	WMA_LOGI("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d",
+			__func__, cmd->channel, cmd->period,
+			cmd->interval, cmd->count);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle,
+				   buf, len,
+				   WMI_P2P_LISTEN_OFFLOAD_START_CMDID);
+	if (ret)
+		wmi_buf_free(buf);
+	else
+		WMA_LOGI("%s: Successfully sent WMI_P2P_LO_START", __func__);
+
+	wma->interfaces[params->vdev_id].p2p_lo_in_progress = true;
+
+	return ret;
+}
+
+/**
+ *  wma_p2p_lo_stop() - P2P listen offload stop
+ *  @vdev_id: vdev identifier
+ *
+ *  This function sends WMI command to stop P2P listen offload.
+ *
+ *  Return: QDF_STATUS enumeration
+ */
+QDF_STATUS wma_p2p_lo_stop(u_int32_t vdev_id)
+{
+	wmi_buf_t buf;
+	wmi_p2p_lo_stop_cmd_fixed_param *cmd;
+	int32_t len;
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	int ret;
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: wma context is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_p2p_lo_stop_cmd_fixed_param));
+
+	cmd->vdev_id = vdev_id;
+
+	WMA_LOGI("%s: Sending WMI_P2P_LO_STOP command", __func__);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle,
+				   buf, len,
+				   WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID);
+	if (ret)
+		wmi_buf_free(buf);
+	else
+		WMA_LOGI("%s: Successfully sent WMI_P2P_LO_STOP", __func__);
+	wma->interfaces[vdev_id].p2p_lo_in_progress = false;
+
+	return ret;
+}
+
+/**
+ * wma_p2p_lo_event_handler() - p2p lo event
+ * @handle: the WMA handle
+ * @event_buf: buffer with the event parameters
+ * @len: length of the buffer
+ *
+ * This function receives P2P listen offload stop event from FW and
+ * pass the event information to upper layer.
+ *
+ * Return: 0 on success
+ */
+int wma_p2p_lo_event_handler(void *handle, uint8_t *event_buf,
+				uint32_t len)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	struct sir_p2p_lo_event *event;
+	WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs;
+	wmi_p2p_lo_stopped_event_fixed_param *fix_param;
+	tpAniSirGlobal p_mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!wma) {
+		WMA_LOGE("%s: Invalid WMA Context", __func__);
+		return -EINVAL;
+	}
+
+	if (!p_mac) {
+		WMA_LOGE("%s: Invalid p_mac", __func__);
+		return -EINVAL;
+	}
+
+	if (!p_mac->sme.p2p_lo_event_callback) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+
+	param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *)
+								event_buf;
+	fix_param = param_tlvs->fixed_param;
+	if (fix_param->vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: received invalid vdev_id %d",
+			 __func__, fix_param->vdev_id);
+		return -EINVAL;
+	}
+	event = qdf_mem_malloc(sizeof(*event));
+	if (!event)
+		return -ENOMEM;
+
+	event->vdev_id = fix_param->vdev_id;
+	event->reason_code = fix_param->reason;
+
+	p_mac->sme.p2p_lo_event_callback(p_mac->sme.p2p_lo_event_context,
+					 event);
+
+	wma->interfaces[event->vdev_id].p2p_lo_in_progress = false;
+
+	return 0;
+}
+#endif /* FEATURE_P2P_LISTEN_OFFLOAD */
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * wma_get_wakelock_stats() - Populates wake lock stats
+ * @stats: non-null wakelock structure to populate
+ *
+ * This function collects wake lock stats
+ *
+ * Return: QDF_STATUS_SUCCESS on success, error value otherwise
+ */
+QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *stats)
+{
+	t_wma_handle *wma;
+	struct sir_vdev_wow_stats *vstats;
+	int i;
+
+	if (!stats) {
+		WMA_LOGE("%s: invalid stats pointer", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		WMA_LOGE("%s: invalid WMA context", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* ensure counters are zeroed */
+	qdf_mem_zero(stats, sizeof(*stats));
+
+	/* populate global level stats */
+	stats->wow_unspecified_wake_up_count = wma->wow_unspecified_wake_count;
+
+	/* populate vdev level stats */
+	for (i = 0; i < wma->max_bssid; ++i) {
+		if (!wma->interfaces[i].handle)
+			continue;
+
+		vstats = &wma->interfaces[i].wow_stats;
+
+		stats->wow_ucast_wake_up_count += vstats->ucast;
+		stats->wow_bcast_wake_up_count += vstats->bcast;
+		stats->wow_ipv4_mcast_wake_up_count += vstats->ipv4_mcast;
+		stats->wow_ipv6_mcast_wake_up_count += vstats->ipv6_mcast;
+		stats->wow_ipv6_mcast_ra_stats += vstats->ipv6_mcast_ra;
+		stats->wow_ipv6_mcast_ns_stats += vstats->ipv6_mcast_ns;
+		stats->wow_ipv6_mcast_na_stats += vstats->ipv6_mcast_na;
+		stats->wow_icmpv4_count += vstats->icmpv4;
+		stats->wow_icmpv6_count += vstats->icmpv6;
+		stats->wow_rssi_breach_wake_up_count += vstats->rssi_breach;
+		stats->wow_low_rssi_wake_up_count += vstats->low_rssi;
+		stats->wow_gscan_wake_up_count += vstats->gscan;
+		stats->wow_pno_complete_wake_up_count += vstats->pno_complete;
+		stats->wow_pno_match_wake_up_count += vstats->pno_match;
+		stats->wow_oem_response_wake_up_count += vstats->oem_response;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * wma_process_fw_test_cmd() - send unit test command to fw.
+ * @handle: wma handle
+ * @wma_fwtest: fw test command
+ *
+ * This function send fw test command to fw.
+ *
+ * Return: none
+ */
+void wma_process_fw_test_cmd(WMA_HANDLE handle,
+			     struct set_fwtest_params *wma_fwtest)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue fw test cmd",
+			 __func__);
+		return;
+	}
+
+	if (wmi_unified_fw_test_cmd(wma_handle->wmi_handle,
+				    (struct set_fwtest_params *)wma_fwtest)) {
+		WMA_LOGE("%s: Failed to issue fw test cmd",
+			 __func__);
+		return;
+	}
+}
+
+/**
+ * wma_enable_disable_caevent_ind() - Issue WMI command to enable or
+ * disable ca event indication
+ * @wma: wma handler
+ * @val: boolean value true or false
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_enable_disable_caevent_ind(tp_wma_handle wma, uint8_t val)
+{
+	WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint8_t *buf_ptr;
+	uint32_t len;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE(FL("WMA is closed, can not issue set/clear CA"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	len = sizeof(*cmd);
+	wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!wmi_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
+	cmd = (WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+				WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param));
+	cmd->rpt_allow = val;
+	if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
+				WMI_CHAN_AVOID_RPT_ALLOW_CMDID)) {
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static wma_sar_cb sar_callback;
+static void *sar_context;
+
+static int wma_sar_event_handler(void *handle, uint8_t *evt_buf, uint32_t len)
+{
+	tp_wma_handle wma_handle;
+	wmi_unified_t wmi_handle;
+	struct sar_limit_event *event;
+	wma_sar_cb callback;
+	QDF_STATUS status;
+
+	WMA_LOGI(FL("handle:%pK event:%pK len:%u"), handle, evt_buf, len);
+
+	wma_handle = handle;
+	if (!wma_handle) {
+		WMA_LOGE(FL("NULL wma_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_handle = wma_handle->wmi_handle;
+	if (!wmi_handle) {
+		WMA_LOGE(FL("NULL wmi_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	event = qdf_mem_malloc(sizeof(*event));
+	if (!event)
+		return QDF_STATUS_E_NOMEM;
+
+	status = wmi_unified_extract_sar_limit_event(wmi_handle,
+						     evt_buf, event);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE(FL("Event extract failure: %d"), status);
+		qdf_mem_free(event);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	callback = sar_callback;
+	sar_callback = NULL;
+	if (callback)
+		callback(sar_context, event);
+
+	qdf_mem_free(event);
+
+	return 0;
+}
+
+QDF_STATUS wma_sar_register_event_handlers(WMA_HANDLE handle)
+{
+	tp_wma_handle wma_handle = handle;
+	wmi_unified_t wmi_handle;
+
+	if (!wma_handle) {
+		WMA_LOGE(FL("NULL wma_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_handle = wma_handle->wmi_handle;
+	if (!wmi_handle) {
+		WMA_LOGE(FL("NULL wmi_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wmi_unified_register_event_handler(wmi_handle,
+						  wmi_sar_get_limits_event_id,
+						  wma_sar_event_handler,
+						  WMA_RX_WORK_CTX);
+}
+
+QDF_STATUS wma_get_sar_limit(WMA_HANDLE handle,
+			     wma_sar_cb callback, void *context)
+{
+	tp_wma_handle wma_handle = handle;
+	wmi_unified_t wmi_handle;
+	QDF_STATUS status;
+
+	if (!wma_handle) {
+		WMA_LOGE(FL("NULL wma_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_handle = wma_handle->wmi_handle;
+	if (!wmi_handle) {
+		WMA_LOGE(FL("NULL wmi_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	sar_callback = callback;
+	sar_context = context;
+	status = wmi_unified_get_sar_limit_cmd(wmi_handle);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE(FL("wmi_unified_get_sar_limit_cmd() error: %u"),
+			 status);
+		sar_callback = NULL;
+	}
+
+	return status;
+}
+
+QDF_STATUS wma_set_sar_limit(WMA_HANDLE handle,
+		struct sar_limit_cmd_params *sar_limit_params)
+{
+	int ret;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue set sar limit msg",
+			__func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (sar_limit_params == NULL) {
+		WMA_LOGE("%s: set sar limit ptr NULL",
+			__func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	ret = wmi_unified_send_sar_limit_cmd(wma->wmi_handle,
+				sar_limit_params);
+
+	return ret;
+}
+
+QDF_STATUS wma_send_coex_config_cmd(WMA_HANDLE wma_handle,
+				    struct coex_config_params *coex_cfg_params)
+{
+	tp_wma_handle wma = (tp_wma_handle)wma_handle;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue coex config command",
+			 __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!coex_cfg_params) {
+		WMA_LOGE("%s: coex cfg params ptr NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wmi_unified_send_coex_config_cmd(wma->wmi_handle,
+					       coex_cfg_params);
+}
+
+/**
+ * wma_get_arp_stats_handler() - handle arp stats data
+ * indicated by FW
+ * @handle: wma context
+ * @data: event buffer
+ * @data len: length of event buffer
+ *
+ * Return: 0 on success
+ */
+int wma_get_arp_stats_handler(void *handle, uint8_t *data,
+			uint32_t data_len)
+{
+	WMI_VDEV_GET_ARP_STAT_EVENTID_param_tlvs *param_buf;
+	wmi_vdev_get_arp_stats_event_fixed_param *data_event;
+	wmi_vdev_get_connectivity_check_stats *connect_stats_event;
+	uint8_t *buf_ptr;
+	struct rsp_stats rsp = {0};
+	tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac) {
+		WMA_LOGE("%s: Invalid mac context", __func__);
+		return -EINVAL;
+	}
+
+	if (!mac->sme.get_arp_stats_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+
+	if (data == NULL) {
+		WMA_LOGE("%s: invalid pointer", __func__);
+		return -EINVAL;
+	}
+	param_buf = (WMI_VDEV_GET_ARP_STAT_EVENTID_param_tlvs *)data;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid get arp stats event", __func__);
+		return -EINVAL;
+	}
+	data_event = param_buf->fixed_param;
+	if (!data_event) {
+		WMA_LOGE("%s: Invalid get arp stats data event", __func__);
+		return -EINVAL;
+	}
+	rsp.arp_req_enqueue = data_event->arp_req_enqueue;
+	rsp.vdev_id = data_event->vdev_id;
+	rsp.arp_req_tx_success = data_event->arp_req_tx_success;
+	rsp.arp_req_tx_failure = data_event->arp_req_tx_failure;
+	rsp.arp_rsp_recvd = data_event->arp_rsp_recvd;
+	rsp.out_of_order_arp_rsp_drop_cnt =
+		data_event->out_of_order_arp_rsp_drop_cnt;
+	rsp.dad_detected = data_event->dad_detected;
+	rsp.connect_status = data_event->connect_status;
+	rsp.ba_session_establishment_status =
+		data_event->ba_session_establishment_status;
+
+	buf_ptr = (uint8_t *)data_event;
+	buf_ptr = buf_ptr + sizeof(wmi_vdev_get_arp_stats_event_fixed_param) +
+		  WMI_TLV_HDR_SIZE;
+	connect_stats_event = (wmi_vdev_get_connectivity_check_stats *)buf_ptr;
+
+	if (((connect_stats_event->tlv_header & 0xFFFF0000) >> 16 ==
+	      WMITLV_TAG_STRUC_wmi_vdev_get_connectivity_check_stats)) {
+		rsp.connect_stats_present = true;
+		rsp.tcp_ack_recvd = connect_stats_event->tcp_ack_recvd;
+		rsp.icmpv4_rsp_recvd = connect_stats_event->icmpv4_rsp_recvd;
+		WMA_LOGD("tcp_ack_recvd %d icmpv4_rsp_recvd %d",
+			connect_stats_event->tcp_ack_recvd,
+			connect_stats_event->icmpv4_rsp_recvd);
+	}
+
+	mac->sme.get_arp_stats_cb(mac->hdd_handle, &rsp,
+				  mac->sme.get_arp_stats_context);
+
+	return 0;
+}
+
+/**
+ * wma_unified_power_debug_stats_event_handler() - WMA handler function to
+ * handle Power stats event from firmware
+ * @handle: Pointer to wma handle
+ * @cmd_param_info: Pointer to Power stats event TLV
+ * @len: Length of the cmd_param_info
+ *
+ * Return: 0 on success, error number otherwise
+ */
+#ifdef WLAN_POWER_DEBUGFS
+int wma_unified_power_debug_stats_event_handler(void *handle,
+			uint8_t *cmd_param_info, uint32_t len)
+{
+	WMI_PDEV_CHIP_POWER_STATS_EVENTID_param_tlvs *param_tlvs;
+	struct power_stats_response *power_stats_results;
+	wmi_pdev_chip_power_stats_event_fixed_param *param_buf;
+	uint32_t power_stats_len, stats_registers_len, *debug_registers;
+
+	tpAniSirGlobal mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
+
+	param_tlvs =
+		(WMI_PDEV_CHIP_POWER_STATS_EVENTID_param_tlvs *) cmd_param_info;
+
+	param_buf = (wmi_pdev_chip_power_stats_event_fixed_param *)
+		param_tlvs->fixed_param;
+	if (!mac || !mac->sme.power_stats_resp_callback) {
+		WMA_LOGD("%s: NULL mac ptr or HDD callback is null", __func__);
+		return -EINVAL;
+	}
+
+	if (!param_buf) {
+		WMA_LOGD("%s: NULL power stats event fixed param", __func__);
+		return -EINVAL;
+	}
+
+	if (param_buf->num_debug_register > ((WMI_SVC_MSG_MAX_SIZE -
+		sizeof(wmi_pdev_chip_power_stats_event_fixed_param)) /
+		sizeof(uint32_t)) ||
+	    param_buf->num_debug_register > param_tlvs->num_debug_registers) {
+		WMA_LOGE("excess payload: LEN num_debug_register:%u",
+				param_buf->num_debug_register);
+		return -EINVAL;
+	}
+	debug_registers = param_tlvs->debug_registers;
+	stats_registers_len =
+		(sizeof(uint32_t) * param_buf->num_debug_register);
+	power_stats_len = stats_registers_len + sizeof(*power_stats_results);
+	power_stats_results = qdf_mem_malloc(power_stats_len);
+	if (!power_stats_results)
+		return -ENOMEM;
+
+	WMA_LOGD("Cumulative sleep time %d cumulative total on time %d deep sleep enter counter %d last deep sleep enter tstamp ts %d debug registers fmt %d num debug register %d",
+			param_buf->cumulative_sleep_time_ms,
+			param_buf->cumulative_total_on_time_ms,
+			param_buf->deep_sleep_enter_counter,
+			param_buf->last_deep_sleep_enter_tstamp_ms,
+			param_buf->debug_register_fmt,
+			param_buf->num_debug_register);
+
+	power_stats_results->cumulative_sleep_time_ms
+		= param_buf->cumulative_sleep_time_ms;
+	power_stats_results->cumulative_total_on_time_ms
+		= param_buf->cumulative_total_on_time_ms;
+	power_stats_results->deep_sleep_enter_counter
+		= param_buf->deep_sleep_enter_counter;
+	power_stats_results->last_deep_sleep_enter_tstamp_ms
+		= param_buf->last_deep_sleep_enter_tstamp_ms;
+	power_stats_results->debug_register_fmt
+		= param_buf->debug_register_fmt;
+	power_stats_results->num_debug_register
+		= param_buf->num_debug_register;
+
+	power_stats_results->debug_registers
+		= (uint32_t *)(power_stats_results + 1);
+
+	qdf_mem_copy(power_stats_results->debug_registers,
+			debug_registers, stats_registers_len);
+
+	mac->sme.power_stats_resp_callback(power_stats_results,
+			mac->sme.power_debug_stats_context);
+	qdf_mem_free(power_stats_results);
+	return 0;
+}
+#else
+int wma_unified_power_debug_stats_event_handler(void *handle,
+		uint8_t *cmd_param_info, uint32_t len)
+{
+	return 0;
+}
+#endif
+
+int wma_chan_info_event_handler(void *handle, uint8_t *event_buf,
+				uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle)handle;
+	WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf;
+	wmi_chan_info_event_fixed_param *event;
+	struct scan_chan_info buf;
+	tpAniSirGlobal mac = NULL;
+	struct lim_channel_status *channel_status;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	if (wma != NULL && wma->cds_context != NULL)
+		mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac) {
+		WMA_LOGE("%s: Invalid mac context", __func__);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("%s: monitor:%d", __func__, mac->snr_monitor_enabled);
+	if (mac->snr_monitor_enabled && mac->chan_info_cb) {
+		param_buf =
+			(WMI_CHAN_INFO_EVENTID_param_tlvs *)event_buf;
+		if (!param_buf) {
+			WMA_LOGA("%s: Invalid chan info event", __func__);
+			return -EINVAL;
+		}
+
+		event = param_buf->fixed_param;
+		if (!event) {
+			WMA_LOGA("%s: Invalid fixed param", __func__);
+			return -EINVAL;
+		}
+		buf.tx_frame_count = event->tx_frame_cnt;
+		buf.clock_freq = event->mac_clk_mhz;
+		buf.cmd_flag = event->cmd_flags;
+		buf.freq = event->freq;
+		buf.noise_floor = event->noise_floor;
+		buf.cycle_count = event->cycle_count;
+		buf.rx_clear_count = event->rx_clear_count;
+		mac->chan_info_cb(&buf);
+	}
+
+	if (mac->sap.acs_with_more_param &&
+	    mac->sme.currDeviceMode == QDF_SAP_MODE) {
+		param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) event_buf;
+		if (!param_buf)  {
+			WMA_LOGE("Invalid chan info event buffer");
+			return -EINVAL;
+		}
+		event = param_buf->fixed_param;
+		channel_status = qdf_mem_malloc(sizeof(*channel_status));
+		if (!channel_status)
+			return -ENOMEM;
+
+		WMA_LOGD(FL("freq=%d nf=%d rxcnt=%u cyccnt=%u tx_r=%d tx_t=%d"),
+			 event->freq,
+			 event->noise_floor,
+			 event->rx_clear_count,
+			 event->cycle_count,
+			 event->chan_tx_pwr_range,
+			 event->chan_tx_pwr_tp);
+
+		channel_status->channelfreq = event->freq;
+		channel_status->noise_floor = event->noise_floor;
+		channel_status->rx_clear_count =
+			 event->rx_clear_count;
+		channel_status->cycle_count = event->cycle_count;
+		channel_status->chan_tx_pwr_range =
+			 event->chan_tx_pwr_range;
+		channel_status->chan_tx_pwr_throughput =
+			 event->chan_tx_pwr_tp;
+		channel_status->rx_frame_count =
+			 event->rx_frame_count;
+		channel_status->bss_rx_cycle_count =
+			event->my_bss_rx_cycle_count;
+		channel_status->rx_11b_mode_data_duration =
+			event->rx_11b_mode_data_duration;
+		channel_status->tx_frame_count = event->tx_frame_cnt;
+		channel_status->mac_clk_mhz = event->mac_clk_mhz;
+		channel_status->channel_id =
+			cds_freq_to_chan(event->freq);
+		channel_status->cmd_flags =
+			event->cmd_flags;
+
+		wma_send_msg(handle, WMA_RX_CHN_STATUS_EVENT,
+			     (void *)channel_status, 0);
+	}
+
+	return 0;
+}
+
+int wma_rx_aggr_failure_event_handler(void *handle, u_int8_t *event_buf,
+							u_int32_t len)
+{
+	WMI_REPORT_RX_AGGR_FAILURE_EVENTID_param_tlvs *param_buf;
+	struct sir_sme_rx_aggr_hole_ind *rx_aggr_hole_event;
+	wmi_rx_aggr_failure_event_fixed_param *rx_aggr_failure_info;
+	wmi_rx_aggr_failure_info *hole_info;
+	uint32_t i, alloc_len;
+	tpAniSirGlobal mac;
+
+	mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac || !mac->sme.stats_ext2_cb) {
+		WMA_LOGD("%s: NULL mac ptr or HDD callback is null", __func__);
+		return -EINVAL;
+	}
+
+	param_buf = (WMI_REPORT_RX_AGGR_FAILURE_EVENTID_param_tlvs *)event_buf;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid stats ext event buf", __func__);
+		return -EINVAL;
+	}
+
+	rx_aggr_failure_info = param_buf->fixed_param;
+	hole_info = param_buf->failure_info;
+
+	if (rx_aggr_failure_info->num_failure_info > ((WMI_SVC_MSG_MAX_SIZE -
+	    sizeof(*rx_aggr_hole_event)) /
+	    sizeof(rx_aggr_hole_event->hole_info_array[0]))) {
+		WMA_LOGE("%s: Excess data from WMI num_failure_info %d",
+			 __func__, rx_aggr_failure_info->num_failure_info);
+		return -EINVAL;
+	}
+
+	alloc_len = sizeof(*rx_aggr_hole_event) +
+		(rx_aggr_failure_info->num_failure_info)*
+		sizeof(rx_aggr_hole_event->hole_info_array[0]);
+	rx_aggr_hole_event = qdf_mem_malloc(alloc_len);
+	if (!rx_aggr_hole_event)
+		return -ENOMEM;
+
+	rx_aggr_hole_event->hole_cnt = rx_aggr_failure_info->num_failure_info;
+	if (rx_aggr_hole_event->hole_cnt > param_buf->num_failure_info) {
+		WMA_LOGE("Invalid no of hole count: %d",
+				rx_aggr_hole_event->hole_cnt);
+		qdf_mem_free(rx_aggr_hole_event);
+		return -EINVAL;
+	}
+	WMA_LOGD("aggr holes_sum: %d\n",
+		rx_aggr_failure_info->num_failure_info);
+	for (i = 0; i < rx_aggr_hole_event->hole_cnt; i++) {
+		rx_aggr_hole_event->hole_info_array[i] =
+			hole_info->end_seq - hole_info->start_seq + 1;
+		WMA_LOGD("aggr_index: %d\tstart_seq: %d\tend_seq: %d\t"
+			"hole_info: %d mpdu lost",
+			i, hole_info->start_seq, hole_info->end_seq,
+			rx_aggr_hole_event->hole_info_array[i]);
+		hole_info++;
+	}
+
+	mac->sme.stats_ext2_cb(mac->hdd_handle, rx_aggr_hole_event);
+	qdf_mem_free(rx_aggr_hole_event);
+
+	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_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    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;
+}
+
+int wma_pdev_div_info_evt_handler(void *handle, u_int8_t *event_buf,
+	u_int32_t len)
+{
+	WMI_PDEV_DIV_RSSI_ANTID_EVENTID_param_tlvs *param_buf;
+	wmi_pdev_div_rssi_antid_event_fixed_param *event;
+	struct chain_rssi_result chain_rssi_result;
+	u_int32_t i;
+	u_int8_t macaddr[IEEE80211_ADDR_LEN];
+
+	tpAniSirGlobal pmac = (tpAniSirGlobal)cds_get_context(
+					QDF_MODULE_ID_PE);
+	if (!pmac) {
+		WMA_LOGE(FL("Invalid pmac"));
+		return -EINVAL;
+	}
+
+	if (!pmac->sme.get_chain_rssi_cb) {
+		WMA_LOGE(FL("Invalid get_chain_rssi_cb"));
+		return -EINVAL;
+	}
+	param_buf = (WMI_PDEV_DIV_RSSI_ANTID_EVENTID_param_tlvs *) event_buf;
+	if (!param_buf) {
+		WMA_LOGE(FL("Invalid rssi antid event buffer"));
+		return -EINVAL;
+	}
+
+	event = param_buf->fixed_param;
+	if (!event) {
+		WMA_LOGE(FL("Invalid fixed param"));
+		return -EINVAL;
+	}
+
+	if (event->num_chains_valid > CHAIN_MAX_NUM) {
+		WMA_LOGE(FL("Invalid num of chains"));
+		return -EINVAL;
+	}
+
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->macaddr, macaddr);
+	WMA_LOGD(FL("macaddr: " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(macaddr));
+
+	WMA_LOGD(FL("num_chains_valid: %d"), event->num_chains_valid);
+	chain_rssi_result.num_chains_valid = event->num_chains_valid;
+
+	qdf_mem_copy(chain_rssi_result.chain_rssi, event->chain_rssi,
+				sizeof(event->chain_rssi));
+	for (i = 0; i < event->num_chains_valid; i++) {
+		WMA_LOGD(FL("chain_rssi: %d, ant_id: %d"),
+			 event->chain_rssi[i], event->ant_id[i]);
+		chain_rssi_result.chain_rssi[i] += WMA_TGT_NOISE_FLOOR_DBM;
+	}
+
+	qdf_mem_copy(chain_rssi_result.ant_id, event->ant_id,
+				sizeof(event->ant_id));
+
+	pmac->sme.get_chain_rssi_cb(pmac->sme.get_chain_rssi_context,
+				&chain_rssi_result);
+
+	return 0;
+}
+
+int wma_vdev_obss_detection_info_handler(void *handle, uint8_t *event,
+					 uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	struct wmi_obss_detect_info *obss_detection;
+	QDF_STATUS status;
+
+	if (!event) {
+		WMA_LOGE("Invalid obss_detection_info event buffer");
+		return -EINVAL;
+	}
+
+	obss_detection = qdf_mem_malloc(sizeof(*obss_detection));
+	if (!obss_detection)
+		return -ENOMEM;
+
+	status = wmi_unified_extract_obss_detection_info(wma->wmi_handle,
+							 event, obss_detection);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("%s: Failed to extract obss info", __func__);
+		qdf_mem_free(obss_detection);
+		return -EINVAL;
+	}
+
+	if (!wma_is_vdev_valid(obss_detection->vdev_id)) {
+		WMA_LOGE("%s: Invalid vdev id %d", __func__,
+			 obss_detection->vdev_id);
+		qdf_mem_free(obss_detection);
+		return -EINVAL;
+	}
+
+	wma_send_msg(wma, WMA_OBSS_DETECTION_INFO, obss_detection, 0);
+
+	return 0;
+}
+
+int wma_vdev_bss_color_collision_info_handler(void *handle,
+					      uint8_t *event,
+					      uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	struct wmi_obss_color_collision_info *obss_color_info;
+	QDF_STATUS status;
+
+	if (!event) {
+		WMA_LOGE("Invalid obss_color_collision event buffer");
+		return -EINVAL;
+	}
+
+	obss_color_info = qdf_mem_malloc(sizeof(*obss_color_info));
+	if (!obss_color_info)
+		return -ENOMEM;
+
+	status = wmi_unified_extract_obss_color_collision_info(wma->wmi_handle,
+							       event,
+							       obss_color_info);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("%s: Failed to extract obss color info", __func__);
+		qdf_mem_free(obss_color_info);
+		return -EINVAL;
+	}
+
+	if (!wma_is_vdev_valid(obss_color_info->vdev_id)) {
+		WMA_LOGE("%s: Invalid vdev id %d", __func__,
+			 obss_color_info->vdev_id);
+		qdf_mem_free(obss_color_info);
+		return -EINVAL;
+	}
+
+	wma_send_msg(wma, WMA_OBSS_COLOR_COLLISION_INFO, obss_color_info, 0);
+
+	return 0;
+}
diff --git a/core/wma/src/wma_fips_api.c b/core/wma/src/wma_fips_api.c
new file mode 100644
index 0000000..70f1e65
--- /dev/null
+++ b/core/wma/src/wma_fips_api.c
@@ -0,0 +1,112 @@
+/*
+ * 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: wma_fips_api.c
+ *
+ * WLAN Host Device Driver FIPS Certification Feature
+ */
+
+#include "wma.h"
+#include "wma_fips_api.h"
+#include "wmi_unified_api.h"
+
+static wma_fips_cb fips_callback;
+static void *fips_context;
+
+static int
+wma_fips_event_handler(void *handle, uint8_t *event, uint32_t len)
+{
+	tp_wma_handle wma_handle;
+	wmi_unified_t wmi_handle;
+	struct wmi_host_fips_event_param param;
+	wma_fips_cb callback;
+	QDF_STATUS status;
+
+	WMA_LOGI(FL("handle:%pK event:%pK len:%u"), handle, event, len);
+
+	wma_handle = handle;
+	if (!wma_handle) {
+		WMA_LOGE(FL("NULL wma_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_handle = wma_handle->wmi_handle;
+	if (!wmi_handle) {
+		WMA_LOGE(FL("NULL wmi_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_extract_fips_event_data(wmi_handle, event, &param);
+
+	WMA_LOGI(FL("Received FIPS event, pdev:%u status:%u data_len:%u"),
+		 param.pdev_id, param.error_status, param.data_len);
+
+	/* make sure extraction error is propagated to upper layers */
+	if (QDF_IS_STATUS_ERROR(status))
+		param.error_status = FIPS_ERROR_OPER_TIMEOUT;
+
+	callback = fips_callback;
+	fips_callback = NULL;
+	if (callback)
+		callback(fips_context, &param);
+
+	return 0;
+}
+
+QDF_STATUS wma_fips_request(WMA_HANDLE handle,
+			    struct fips_params *param,
+			    wma_fips_cb callback,
+			    void *context)
+{
+	tp_wma_handle wma_handle = handle;
+	wmi_unified_t wmi_handle;
+	QDF_STATUS status;
+
+	if (!wma_handle) {
+		WMA_LOGE(FL("NULL wma_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_handle = wma_handle->wmi_handle;
+	if (!wmi_handle) {
+		WMA_LOGE(FL("NULL wmi_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fips_callback = callback;
+	fips_context = context;
+	status = wmi_unified_pdev_fips_cmd_send(wmi_handle, param);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE(FL("wmi_unified_pdev_fips_cmd_send() error: %u"),
+			 status);
+		fips_callback = NULL;
+	}
+
+	return status;
+}
+
+QDF_STATUS wma_fips_register_event_handlers(WMA_HANDLE handle)
+{
+	tp_wma_handle wma_handle = handle;
+
+	return wmi_unified_register_event_handler(wma_handle->wmi_handle,
+						  wmi_pdev_fips_event_id,
+						  wma_fips_event_handler,
+						  WMA_RX_WORK_CTX);
+}
diff --git a/core/wma/src/wma_fips_api.h b/core/wma/src/wma_fips_api.h
new file mode 100644
index 0000000..5ca0efb
--- /dev/null
+++ b/core/wma/src/wma_fips_api.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.
+ */
+
+#ifndef __WMA_FIPS_API_H
+#define __WMA_FIPS_API_H
+
+#include "wma_api.h"
+#include "wmi_unified_api.h"
+#include "wma_fips_public_structs.h"
+
+#ifdef WLAN_FEATURE_FIPS
+/**
+ * wma_fips_request() - Perform a FIPS certification operation
+ * @handle: WMA handle of the object being certified
+ * @param: The FIPS certification parameters
+ * @callback: Callback function to invoke with the results
+ * @context: Opaque context to pass back to caller in the callback
+ *
+ * Return: QDF_STATUS_SUCCESS if the request is successfully sent
+ * to firmware for processing, otherwise an error status.
+ */
+QDF_STATUS wma_fips_request(WMA_HANDLE handle,
+			    struct fips_params *param,
+			    wma_fips_cb callback,
+			    void *context);
+
+/**
+ * wma_fips_register_event_handlers() - Register FIPS event handlers
+ * @handle: WMA handle of the object being initialized
+ *
+ * This function registers all WMI event handlers required by the FIPS
+ * feature.
+ *
+ * Return: QDF_STATUS_SUCCESS upon success, otherwise an error
+ */
+QDF_STATUS wma_fips_register_event_handlers(WMA_HANDLE handle);
+
+#else /* WLAN_FEATURE_FIPS */
+
+static inline
+QDF_STATUS wma_fips_request(WMA_HANDLE handle,
+			    const struct fips_params *param,
+			    wma_fips_cb callback,
+			    void *context)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline
+QDF_STATUS wma_fips_register_event_handlers(WMA_HANDLE wma_handle)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif /* WLAN_FEATURE_FIPS */
+
+#endif /* __WMA_FIPS_API_H */
diff --git a/core/wma/src/wma_fips_public_structs.h b/core/wma/src/wma_fips_public_structs.h
new file mode 100644
index 0000000..13c5999
--- /dev/null
+++ b/core/wma/src/wma_fips_public_structs.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#ifndef __WMA_FIPS_PUBLIC_STRUCTS_H
+#define __WMA_FIPS_PUBLIC_STRUCTS_H
+
+struct wmi_host_fips_event_param;
+
+/**
+ * typedef wma_fips_cb() - FIPS callback function
+ * @context: Opaque context provided by caller in FIPS request
+ * @param: FIPS event parameters
+ */
+typedef void (*wma_fips_cb)(void *context,
+			    struct wmi_host_fips_event_param *param);
+
+#endif /* __WMA_FIPS_PUBLIC_STRUCTS_H */
diff --git a/core/wma/src/wma_he.c b/core/wma/src/wma_he.c
new file mode 100644
index 0000000..8c07d36
--- /dev/null
+++ b/core/wma/src/wma_he.c
@@ -0,0 +1,1417 @@
+/*
+ * Copyright (c) 2017-2018 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: wma_he.c
+ *
+ * WLAN Host Device Driver 802.11ax - High Efficiency Implementation
+ */
+
+#include "wma_he.h"
+#include "wmi_unified_api.h"
+#include "cds_utils.h"
+#include "wma_internal.h"
+
+/**
+ * wma_he_ppet_merge() - Merge PPET8 and PPET16 for a given ru and nss
+ * @host_ppet: pointer to dot11f array
+ * @byte_idx_p: pointer to byte index position where ppet should be added
+ * @used_p: pointer to used position
+ * @ppet: incoming PPET to be merged
+ *
+ * This function does the actual packing of dot11f structure. Split the
+ * incoming PPET(3 bits) to fit into an octet. If there are more than
+ * 3 bits available in a given byte_idx no splitting is required.
+ *
+ * Return: None
+ */
+static void wma_he_ppet_merge(uint8_t *host_ppet, int *byte_idx_p, int *used_p,
+			      uint8_t ppet)
+{
+	int byte_idx = *byte_idx_p, used = *used_p;
+	int lshift, rshift;
+
+	if (used <= (HE_BYTE_SIZE - HE_PPET_SIZE)) {
+		/* Enough space to fit the incoming PPET */
+		lshift = used;
+		host_ppet[byte_idx] |= (ppet << lshift);
+		used += HE_PPET_SIZE;
+		if (used == HE_BYTE_SIZE) {
+			used = 0;
+			byte_idx++;
+		}
+	} else {
+		/* Need to split the PPET */
+		lshift = used;
+		rshift = HE_BYTE_SIZE - used;
+		host_ppet[byte_idx] |= (ppet << lshift);
+		byte_idx++;
+		used = 0;
+		host_ppet[byte_idx] |= (ppet >> rshift);
+		used +=  HE_PPET_SIZE - rshift;
+	}
+
+	*byte_idx_p = byte_idx;
+	*used_p = used;
+}
+
+/**
+ * wma_he_populate_ppet() - Helper function for PPET conversion
+ * @ppet: pointer to fw array
+ * @nss: Number of NSS
+ * @ru: Number of RU
+ * @host_ppet: pointer to dot11f array
+ * @req_byte: Number of bytes in dot11f array
+ *
+ * This function retrieves PPET16/PPET8 pair for combination of NSS/RU
+ * and try to pack them in the OTA type dot11f structure by calling
+ * wma_he_ppet_merge.
+ *
+ * Return: None
+ */
+static void wma_he_populate_ppet(uint32_t *ppet, int nss, int ru,
+				 uint8_t *host_ppet, int req_byte)
+{
+	int byte_idx = 0, used, i, j;
+	uint8_t ppet16, ppet8;
+
+	WMA_LOGD(FL("nss: %d ru: %d req_byte: %d\n"), nss, ru, req_byte);
+	/* NSS and RU_IDX are already populated */
+	used = HE_PPET_NSS_RU_LEN;
+
+	for (i = 0; i < nss; i++) {
+		for (j = 1; j <= ru; j++) {
+			ppet16 = WMI_GET_PPET16(ppet, j, i);
+			ppet8 = WMI_GET_PPET8(ppet, j, i);
+			WMA_LOGD(FL("ppet16 (nss:%d ru:%d): %04x"),
+				 i, j, ppet16);
+			WMA_LOGD(FL("ppet8 (nss:%d ru:%d): %04x"),
+				 i, j, ppet8);
+			wma_he_ppet_merge(host_ppet, &byte_idx, &used, ppet16);
+			wma_he_ppet_merge(host_ppet, &byte_idx, &used, ppet8);
+		}
+	}
+
+}
+
+/**
+ * wma_convert_he_ppet() - convert WMI ppet structure to dot11f structure
+ * @he_ppet: pointer to dot11f ppet structure
+ * @ppet: pointer to FW ppet structure
+ *
+ * PPET info coming from FW is stored as described in WMI definition. Convert
+ * that into equivalent dot11f structure.
+ *
+ * Return: None
+ */
+static void wma_convert_he_ppet(uint8_t *he_ppet,
+				struct wmi_host_ppe_threshold *ppet)
+{
+	int bits, req_byte;
+	struct ppet_hdr *hdr;
+	uint8_t ru_count, mask;
+	struct ppe_threshold *ppet_1;
+
+	ppet_1 = NULL;
+	if (!ppet) {
+		WMA_LOGE(FL("PPET is NULL"));
+		qdf_mem_zero(he_ppet, HE_MAX_PPET_SIZE);
+		return;
+	}
+
+	hdr = (struct ppet_hdr *)he_ppet;
+	hdr->nss = ppet->numss_m1;
+	hdr->ru_idx_mask = ppet->ru_bit_mask;
+	mask = hdr->ru_idx_mask;
+	for (ru_count = 0; mask; mask >>= 1)
+		if (mask & 0x01)
+			ru_count++;
+
+	/*
+	 * there will be two PPET for each NSS/RU pair
+	 * PPET8 and PPET16, hence HE_PPET_SIZE * 2 bits for PPET
+	 */
+	bits = HE_PPET_NSS_RU_LEN + ((hdr->nss + 1) * ru_count) *
+				     (HE_PPET_SIZE * 2);
+
+	req_byte = (bits / HE_BYTE_SIZE) + 1;
+	wma_he_populate_ppet(ppet->ppet16_ppet8_ru3_ru0, hdr->nss + 1,
+			 ru_count, he_ppet, req_byte);
+}
+
+/**
+ * wma_convert_he_cap() - convert HE capabilities into dot11f structure
+ * @he_cap: pointer to dot11f structure
+ * @mac_cap: Received HE MAC capability
+ * @phy_cap: Received HE PHY capability
+ * @supp_mcs: Max MCS supported (Tx/Rx)
+ * @tx_chain_mask: Tx chain mask
+ * @rx_chain_mask: Rx chain mask
+ *
+ * This function converts various HE capability received as part of extended
+ * service ready event into dot11f structure. GET macros are defined at WMI
+ * layer, use them to unpack the incoming FW capability.
+ *
+ * Return: None
+ */
+static void wma_convert_he_cap(tDot11fIEhe_cap *he_cap, uint32_t *mac_cap,
+			       uint32_t *phy_cap, uint32_t supp_mcs,
+			       uint32_t tx_chain_mask, uint32_t rx_chain_mask)
+{
+	uint8_t nss, chan_width;
+	uint16_t rx_mcs_le_80, tx_mcs_le_80, rx_mcs_160, tx_mcs_160;
+
+	nss = QDF_MAX(wma_get_num_of_setbits_from_bitmask(tx_chain_mask),
+			wma_get_num_of_setbits_from_bitmask(rx_chain_mask));
+
+	he_cap->present = true;
+	/* HE MAC capabilities */
+	he_cap->htc_he = WMI_HECAP_MAC_HECTRL_GET(mac_cap[0]);
+	he_cap->twt_request = WMI_HECAP_MAC_TWTREQ_GET(mac_cap[0]);
+	he_cap->twt_responder = WMI_HECAP_MAC_TWTRSP_GET(mac_cap[0]);
+	he_cap->fragmentation =  WMI_HECAP_MAC_HEFRAG_GET(mac_cap[0]);
+	he_cap->max_num_frag_msdu_amsdu_exp =
+		WMI_HECAP_MAC_MAXFRAGMSDU_GET(mac_cap[0]);
+	he_cap->min_frag_size = WMI_HECAP_MAC_MINFRAGSZ_GET(mac_cap[0]);
+	he_cap->trigger_frm_mac_pad = WMI_HECAP_MAC_TRIGPADDUR_GET(mac_cap[0]);
+	he_cap->multi_tid_aggr_rx_supp =
+		WMI_HECAP_MAC_ACKMTIDAMPDU_GET(mac_cap[0]);
+	he_cap->he_link_adaptation = WMI_HECAP_MAC_HELINK_ADPT_GET(mac_cap[0]);
+	he_cap->all_ack = WMI_HECAP_MAC_AACK_GET(mac_cap[0]);
+	he_cap->trigd_rsp_sched = WMI_HECAP_MAC_TRS_GET(mac_cap[0]);
+	he_cap->a_bsr = WMI_HECAP_MAC_BSR_GET(mac_cap[0]);
+	he_cap->broadcast_twt = WMI_HECAP_MAC_BCSTTWT_GET(mac_cap[0]);
+	he_cap->ba_32bit_bitmap = WMI_HECAP_MAC_32BITBA_GET(mac_cap[0]);
+	he_cap->mu_cascade = WMI_HECAP_MAC_MUCASCADE_GET(mac_cap[0]);
+	he_cap->ack_enabled_multitid =
+		WMI_HECAP_MAC_ACKMTIDAMPDU_GET(mac_cap[0]);
+	he_cap->omi_a_ctrl = WMI_HECAP_MAC_OMI_GET(mac_cap[0]);
+	he_cap->ofdma_ra = WMI_HECAP_MAC_OFDMARA_GET(mac_cap[0]);
+	he_cap->max_ampdu_len_exp_ext =
+		WMI_HECAP_MAC_MAXAMPDULEN_EXP_GET(mac_cap[0]);
+	he_cap->amsdu_frag = WMI_HECAP_MAC_AMSDUFRAG_GET(mac_cap[0]);
+	he_cap->flex_twt_sched = WMI_HECAP_MAC_FLEXTWT_GET(mac_cap[0]);
+	he_cap->rx_ctrl_frame = WMI_HECAP_MAC_MBSS_GET(mac_cap[0]);
+	he_cap->bsrp_ampdu_aggr = WMI_HECAP_MAC_BSRPAMPDU_GET(mac_cap[1]);
+	he_cap->qtp = WMI_HECAP_MAC_QTP_GET(mac_cap[1]);
+	he_cap->a_bqr = WMI_HECAP_MAC_ABQR_GET(mac_cap[1]);
+	he_cap->spatial_reuse_param_rspder =
+		WMI_HECAP_MAC_SRPRESP_GET(mac_cap[1]);
+	he_cap->ndp_feedback_supp = WMI_HECAP_MAC_NDPFDBKRPT_GET(mac_cap[1]);
+	he_cap->ops_supp = WMI_HECAP_MAC_OPS_GET(mac_cap[1]);
+	he_cap->amsdu_in_ampdu = WMI_HECAP_MAC_AMSDUINAMPDU_GET(mac_cap[1]);
+	he_cap->multi_tid_aggr_tx_supp = WMI_HECAP_MAC_MTID_TX_GET(mac_cap[1]);
+	he_cap->he_sub_ch_sel_tx_supp =
+		WMI_HECAP_MAC_SUBCHANSELTX_GET(mac_cap[1]);
+	he_cap->ul_2x996_tone_ru_supp = WMI_HECAP_MAC_UL2X996RU_GET(mac_cap[1]);
+	he_cap->om_ctrl_ul_mu_data_dis_rx =
+		WMI_HECAP_MAC_OMCULMUDDIS_GET(mac_cap[1]);
+	/* HE PHY capabilities */
+	chan_width = WMI_HECAP_PHY_CBW_GET(phy_cap);
+	he_cap->chan_width_0 = HE_CH_WIDTH_GET_BIT(chan_width, 0);
+	he_cap->chan_width_1 = HE_CH_WIDTH_GET_BIT(chan_width, 1);
+	he_cap->chan_width_2 = HE_CH_WIDTH_GET_BIT(chan_width, 2);
+	he_cap->chan_width_3 = HE_CH_WIDTH_GET_BIT(chan_width, 3);
+	he_cap->chan_width_4 = HE_CH_WIDTH_GET_BIT(chan_width, 4);
+	he_cap->chan_width_5 = HE_CH_WIDTH_GET_BIT(chan_width, 5);
+	he_cap->chan_width_6 = HE_CH_WIDTH_GET_BIT(chan_width, 6);
+	he_cap->rx_pream_puncturing = WMI_HECAP_PHY_PREAMBLEPUNCRX_GET(phy_cap);
+	he_cap->device_class = WMI_HECAP_PHY_COD_GET(phy_cap);
+	he_cap->ldpc_coding = WMI_HECAP_PHY_LDPC_GET(phy_cap);
+	he_cap->he_1x_ltf_800_gi_ppdu = WMI_HECAP_PHY_LTFGIFORHE_GET(phy_cap);
+	he_cap->midamble_tx_rx_max_nsts =
+		WMI_HECAP_PHY_MIDAMBLETXRXMAXNSTS_GET(phy_cap);
+	he_cap->he_4x_ltf_3200_gi_ndp = WMI_HECAP_PHY_LTFGIFORNDP_GET(phy_cap);
+	he_cap->rx_stbc_lt_80mhz = WMI_HECAP_PHY_RXSTBC_GET(phy_cap);
+	he_cap->tx_stbc_lt_80mhz = WMI_HECAP_PHY_TXSTBC_GET(phy_cap);
+	he_cap->rx_stbc_gt_80mhz = WMI_HECAP_PHY_STBCRXGT80_GET(phy_cap);
+	he_cap->tx_stbc_gt_80mhz = WMI_HECAP_PHY_STBCTXGT80_GET(phy_cap);
+
+	he_cap->doppler = (WMI_HECAP_PHY_RXDOPPLER_GET(phy_cap) << 1) |
+				WMI_HECAP_PHY_TXDOPPLER(phy_cap);
+	he_cap->ul_mu = (WMI_HECAP_PHY_ULMUMIMOOFDMA_GET(phy_cap) << 1) |
+			 WMI_HECAP_PHY_UL_MU_MIMO_GET(phy_cap);
+	he_cap->dcm_enc_tx = WMI_HECAP_PHY_DCMTX_GET(phy_cap);
+	he_cap->dcm_enc_rx = WMI_HECAP_PHY_DCMRX_GET(phy_cap);
+	he_cap->ul_he_mu = WMI_HECAP_PHY_ULHEMU_GET(phy_cap);
+	he_cap->su_beamformer = WMI_HECAP_PHY_SUBFMR_GET(phy_cap);
+	he_cap->su_beamformee = WMI_HECAP_PHY_SUBFME_GET(phy_cap);
+	he_cap->mu_beamformer = WMI_HECAP_PHY_MUBFMR_GET(phy_cap);
+	he_cap->bfee_sts_lt_80 = WMI_HECAP_PHY_BFMESTSLT80MHZ_GET(phy_cap);
+	he_cap->bfee_sts_gt_80 = WMI_HECAP_PHY_BFMESTSGT80MHZ_GET(phy_cap);
+	he_cap->num_sounding_lt_80 = WMI_HECAP_PHY_NUMSOUNDLT80MHZ_GET(phy_cap);
+	he_cap->num_sounding_gt_80 = WMI_HECAP_PHY_NUMSOUNDGT80MHZ_GET(phy_cap);
+	he_cap->su_feedback_tone16 =
+		WMI_HECAP_PHY_NG16SUFEEDBACKLT80_GET(phy_cap);
+	he_cap->mu_feedback_tone16 =
+		WMI_HECAP_PHY_NG16MUFEEDBACKGT80_GET(phy_cap);
+	he_cap->codebook_su = WMI_HECAP_PHY_CODBK42SU_GET(phy_cap);
+	he_cap->codebook_mu = WMI_HECAP_PHY_CODBK75MU_GET(phy_cap);
+	he_cap->beamforming_feedback =
+		WMI_HECAP_PHY_BFFEEDBACKTRIG_GET(phy_cap);
+	he_cap->he_er_su_ppdu = WMI_HECAP_PHY_HEERSU_GET(phy_cap);
+	he_cap->dl_mu_mimo_part_bw =
+		WMI_HECAP_PHY_DLMUMIMOPARTIALBW_GET(phy_cap);
+	he_cap->ppet_present = WMI_HECAP_PHY_PETHRESPRESENT_GET(phy_cap);
+	he_cap->srp = WMI_HECAP_PHY_SRPSPRESENT_GET(phy_cap);
+	he_cap->power_boost = WMI_HECAP_PHY_PWRBOOSTAR_GET(phy_cap);
+	he_cap->he_ltf_800_gi_4x =
+			WMI_HECAP_PHY_4XLTFAND800NSECSGI_GET(phy_cap);
+	he_cap->max_nc = WMI_HECAP_PHY_MAXNC_GET(phy_cap);
+	he_cap->tx_stbc_gt_80mhz = WMI_HECAP_PHY_STBCTXGT80_GET(phy_cap);
+	he_cap->rx_stbc_gt_80mhz = WMI_HECAP_PHY_STBCRXGT80_GET(phy_cap);
+	he_cap->er_he_ltf_800_gi_4x =
+			WMI_HECAP_PHY_ERSU4X800NSECGI_GET(phy_cap);
+	he_cap->he_ppdu_20_in_40Mhz_2G =
+		WMI_HECAP_PHY_HEPPDU20IN40MHZ2G_GET(phy_cap);
+	he_cap->he_ppdu_20_in_160_80p80Mhz =
+		WMI_HECAP_PHY_HEPPDU20IN160OR80P80MHZ_GET(phy_cap);
+	he_cap->he_ppdu_80_in_160_80p80Mhz =
+		WMI_HECAP_PHY_HEPPDU80IN160OR80P80MHZ_GET(phy_cap);
+	he_cap->er_1x_he_ltf_gi = WMI_HECAP_PHY_ERSU1X800NSECGI_GET(phy_cap);
+	he_cap->midamble_tx_rx_1x_he_ltf =
+		WMI_HECAP_PHY_MIDAMBLETXRX2XAND1XHELTF_GET(phy_cap);
+
+	he_cap->dcm_max_bw = WMI_HECAP_PHY_DCMMAXBW_GET(phy_cap);
+	he_cap->longer_than_16_he_sigb_ofdm_sym =
+		WMI_HECAP_PHY_LNG16SIGBSYMBSUPRT_GET(phy_cap);
+	he_cap->non_trig_cqi_feedback =
+		WMI_HECAP_PHY_NONTRIGCQIFEEDBK_GET(phy_cap);
+	he_cap->tx_1024_qam_lt_242_tone_ru =
+		WMI_HECAP_PHY_TX1024QAM242RUSUPRT_GET(phy_cap);
+	he_cap->rx_1024_qam_lt_242_tone_ru =
+		WMI_HECAP_PHY_RX1024QAM242RUSUPRT_GET(phy_cap);
+	he_cap->rx_full_bw_su_he_mu_compress_sigb =
+		WMI_HECAP_PHY_RXFULBWSUWCMPRSSIGB_GET(phy_cap);
+	he_cap->rx_full_bw_su_he_mu_non_cmpr_sigb =
+		WMI_HECAP_PHY_RXFULBWSUWNONCMPRSSIGB_GET(phy_cap);
+
+	/*
+	 * supp_mcs is split into 16 bits with lower indicating le_80 and
+	 * upper indicating 160 and 80_80.
+	 */
+	WMA_LOGD(FL("supported_mcs: 0x%08x\n"), supp_mcs);
+	rx_mcs_le_80 = supp_mcs & 0xFFFF;
+	tx_mcs_le_80 = supp_mcs & 0xFFFF;
+	rx_mcs_160 = (supp_mcs & 0xFFFF0000) >> 16;
+	tx_mcs_160 = (supp_mcs & 0xFFFF0000) >> 16;
+	/* if FW indicated it is using 1x1 disable upper NSS-MCS sets */
+	if (nss == NSS_1x1_MODE) {
+		rx_mcs_le_80 |= HE_MCS_INV_MSK_4_NSS(1);
+		tx_mcs_le_80 |= HE_MCS_INV_MSK_4_NSS(1);
+		rx_mcs_160 |= HE_MCS_INV_MSK_4_NSS(1);
+		tx_mcs_160 |= HE_MCS_INV_MSK_4_NSS(1);
+	}
+	he_cap->rx_he_mcs_map_lt_80 = rx_mcs_le_80;
+	he_cap->tx_he_mcs_map_lt_80 = tx_mcs_le_80;
+	*((uint16_t *)he_cap->tx_he_mcs_map_160) = rx_mcs_160;
+	*((uint16_t *)he_cap->rx_he_mcs_map_160) = tx_mcs_160;
+	*((uint16_t *)he_cap->rx_he_mcs_map_80_80) = rx_mcs_160;
+	*((uint16_t *)he_cap->tx_he_mcs_map_80_80) = tx_mcs_160;
+}
+
+/**
+ * wma_derive_ext_he_cap() - Derive HE caps based on given value
+ * @he_cap: pointer to given HE caps to be filled
+ * @new_he_cap: new HE cap info provided.
+ *
+ * This function takes the value provided in and combines it wht the incoming
+ * HE capability. After decoding, what ever value it gets,
+ * it takes the union(max) or intersection(min) with previously derived values.
+ * Currently, intersection(min) is taken for all the capabilities.
+ *
+ * Return: none
+ */
+static void wma_derive_ext_he_cap(tDot11fIEhe_cap *he_cap,
+				  tDot11fIEhe_cap *new_cap)
+{
+	uint16_t mcs_1, mcs_2;
+
+	if (!he_cap->present) {
+		/* First time update, copy the capability as is */
+		qdf_mem_copy(he_cap, new_cap, sizeof(*he_cap));
+		he_cap->present = true;
+		return;
+	}
+	/* Take union(max) or intersection(min) of the capabilities */
+	he_cap->htc_he = QDF_MIN(he_cap->htc_he, new_cap->htc_he);
+	he_cap->twt_request = QDF_MIN(he_cap->twt_request,
+			new_cap->twt_request);
+	he_cap->twt_responder = QDF_MIN(he_cap->twt_responder,
+			new_cap->twt_responder);
+	he_cap->fragmentation = QDF_MIN(he_cap->fragmentation,
+			new_cap->fragmentation);
+	he_cap->max_num_frag_msdu_amsdu_exp = QDF_MIN(
+			he_cap->max_num_frag_msdu_amsdu_exp,
+			new_cap->max_num_frag_msdu_amsdu_exp);
+	he_cap->min_frag_size = QDF_MIN(he_cap->min_frag_size,
+			new_cap->min_frag_size);
+	he_cap->trigger_frm_mac_pad =
+		QDF_MIN(he_cap->trigger_frm_mac_pad,
+				new_cap->trigger_frm_mac_pad);
+	he_cap->multi_tid_aggr_rx_supp = QDF_MIN(he_cap->multi_tid_aggr_rx_supp,
+			new_cap->multi_tid_aggr_rx_supp);
+	he_cap->he_link_adaptation = QDF_MIN(he_cap->he_link_adaptation,
+			new_cap->he_link_adaptation);
+	he_cap->all_ack = QDF_MIN(he_cap->all_ack,
+			new_cap->all_ack);
+	he_cap->trigd_rsp_sched = QDF_MIN(he_cap->trigd_rsp_sched,
+			new_cap->trigd_rsp_sched);
+	he_cap->a_bsr = QDF_MIN(he_cap->a_bsr,
+			new_cap->a_bsr);
+	he_cap->broadcast_twt = QDF_MIN(he_cap->broadcast_twt,
+			new_cap->broadcast_twt);
+	he_cap->ba_32bit_bitmap = QDF_MIN(he_cap->ba_32bit_bitmap,
+			new_cap->ba_32bit_bitmap);
+	he_cap->mu_cascade = QDF_MIN(he_cap->mu_cascade,
+			new_cap->mu_cascade);
+	he_cap->ack_enabled_multitid =
+		QDF_MIN(he_cap->ack_enabled_multitid,
+				new_cap->ack_enabled_multitid);
+	he_cap->omi_a_ctrl = QDF_MIN(he_cap->omi_a_ctrl,
+			new_cap->omi_a_ctrl);
+	he_cap->ofdma_ra = QDF_MIN(he_cap->ofdma_ra,
+			new_cap->ofdma_ra);
+	he_cap->max_ampdu_len_exp_ext = QDF_MIN(he_cap->max_ampdu_len_exp_ext,
+			new_cap->max_ampdu_len_exp_ext);
+	he_cap->amsdu_frag = QDF_MIN(he_cap->amsdu_frag,
+			new_cap->amsdu_frag);
+	he_cap->flex_twt_sched = QDF_MIN(he_cap->flex_twt_sched,
+			new_cap->flex_twt_sched);
+	he_cap->rx_ctrl_frame = QDF_MIN(he_cap->rx_ctrl_frame,
+			new_cap->rx_ctrl_frame);
+	he_cap->bsrp_ampdu_aggr = QDF_MIN(he_cap->bsrp_ampdu_aggr,
+			new_cap->bsrp_ampdu_aggr);
+	he_cap->qtp = QDF_MIN(he_cap->qtp, new_cap->qtp);
+	he_cap->a_bqr = QDF_MIN(he_cap->a_bqr, new_cap->a_bqr);
+	he_cap->spatial_reuse_param_rspder = QDF_MIN(
+			he_cap->spatial_reuse_param_rspder,
+			new_cap->spatial_reuse_param_rspder);
+	he_cap->ndp_feedback_supp = QDF_MIN(he_cap->ndp_feedback_supp,
+			new_cap->ndp_feedback_supp);
+	he_cap->ops_supp = QDF_MIN(he_cap->ops_supp, new_cap->ops_supp);
+	he_cap->amsdu_in_ampdu = QDF_MIN(he_cap->amsdu_in_ampdu,
+			new_cap->amsdu_in_ampdu);
+	he_cap->reserved1 = QDF_MIN(he_cap->reserved1,
+			new_cap->reserved1);
+
+	he_cap->chan_width_0 = he_cap->chan_width_0 | new_cap->chan_width_0;
+	he_cap->chan_width_1 = he_cap->chan_width_1 | new_cap->chan_width_1;
+	he_cap->chan_width_2 = he_cap->chan_width_2 | new_cap->chan_width_2;
+	he_cap->chan_width_3 = he_cap->chan_width_3 | new_cap->chan_width_3;
+	he_cap->chan_width_4 = he_cap->chan_width_4 | new_cap->chan_width_4;
+	he_cap->chan_width_5 = he_cap->chan_width_5 | new_cap->chan_width_5;
+	he_cap->chan_width_6 = he_cap->chan_width_6 | new_cap->chan_width_6;
+
+	he_cap->rx_pream_puncturing =
+		QDF_MIN(he_cap->rx_pream_puncturing,
+				new_cap->rx_pream_puncturing);
+	he_cap->device_class = QDF_MIN(he_cap->device_class,
+			new_cap->device_class);
+	he_cap->ldpc_coding = QDF_MIN(he_cap->ldpc_coding,
+			new_cap->ldpc_coding);
+	he_cap->he_1x_ltf_800_gi_ppdu =
+		QDF_MIN(he_cap->he_1x_ltf_800_gi_ppdu,
+				new_cap->he_1x_ltf_800_gi_ppdu);
+	he_cap->midamble_tx_rx_max_nsts =
+		QDF_MIN(he_cap->midamble_tx_rx_max_nsts,
+			new_cap->midamble_tx_rx_max_nsts);
+	he_cap->he_4x_ltf_3200_gi_ndp =
+		QDF_MIN(he_cap->he_4x_ltf_3200_gi_ndp,
+				new_cap->he_4x_ltf_3200_gi_ndp);
+	he_cap->tx_stbc_lt_80mhz = QDF_MIN(he_cap->tx_stbc_lt_80mhz,
+			new_cap->tx_stbc_lt_80mhz);
+	he_cap->rx_stbc_lt_80mhz = QDF_MIN(he_cap->rx_stbc_lt_80mhz,
+			new_cap->rx_stbc_lt_80mhz);
+	he_cap->doppler = QDF_MIN(he_cap->doppler,
+			new_cap->doppler);
+	he_cap->ul_mu = QDF_MIN(he_cap->ul_mu, new_cap->ul_mu);
+	he_cap->dcm_enc_tx = QDF_MIN(he_cap->dcm_enc_tx,
+			new_cap->dcm_enc_tx);
+	he_cap->dcm_enc_rx = QDF_MIN(he_cap->dcm_enc_rx,
+			new_cap->dcm_enc_rx);
+	he_cap->ul_he_mu = QDF_MIN(he_cap->ul_he_mu, new_cap->ul_he_mu);
+	he_cap->su_beamformer = QDF_MIN(he_cap->su_beamformer,
+			new_cap->su_beamformer);
+	he_cap->su_beamformee = QDF_MIN(he_cap->su_beamformee,
+			new_cap->su_beamformee);
+	he_cap->mu_beamformer = QDF_MIN(he_cap->mu_beamformer,
+			new_cap->mu_beamformer);
+	he_cap->bfee_sts_lt_80 = QDF_MIN(he_cap->bfee_sts_lt_80,
+			new_cap->bfee_sts_lt_80);
+	he_cap->bfee_sts_gt_80 = QDF_MIN(he_cap->bfee_sts_gt_80,
+			new_cap->bfee_sts_gt_80);
+	he_cap->num_sounding_lt_80 = QDF_MIN(he_cap->num_sounding_lt_80,
+			new_cap->num_sounding_lt_80);
+	he_cap->num_sounding_gt_80 = QDF_MIN(he_cap->num_sounding_gt_80,
+			new_cap->num_sounding_gt_80);
+	he_cap->su_feedback_tone16 = QDF_MIN(he_cap->su_feedback_tone16,
+			new_cap->su_feedback_tone16);
+	he_cap->mu_feedback_tone16 = QDF_MIN(he_cap->mu_feedback_tone16,
+			new_cap->mu_feedback_tone16);
+	he_cap->codebook_su = QDF_MIN(he_cap->codebook_su,
+			new_cap->codebook_su);
+	he_cap->codebook_mu = QDF_MIN(he_cap->codebook_mu,
+			new_cap->codebook_mu);
+	he_cap->beamforming_feedback =
+		QDF_MIN(he_cap->beamforming_feedback,
+				new_cap->beamforming_feedback);
+	he_cap->he_er_su_ppdu = QDF_MIN(he_cap->he_er_su_ppdu,
+			new_cap->he_er_su_ppdu);
+	he_cap->dl_mu_mimo_part_bw = QDF_MIN(he_cap->dl_mu_mimo_part_bw,
+			new_cap->dl_mu_mimo_part_bw);
+	he_cap->ppet_present = QDF_MIN(he_cap->ppet_present,
+			new_cap->ppet_present);
+	he_cap->srp = QDF_MIN(he_cap->srp, new_cap->srp);
+	he_cap->power_boost = QDF_MIN(he_cap->power_boost,
+			new_cap->power_boost);
+	he_cap->he_ltf_800_gi_4x = QDF_MIN(he_cap->he_ltf_800_gi_4x,
+			new_cap->he_ltf_800_gi_4x);
+	he_cap->er_he_ltf_800_gi_4x =
+		QDF_MIN(he_cap->er_he_ltf_800_gi_4x,
+				new_cap->er_he_ltf_800_gi_4x);
+	he_cap->he_ppdu_20_in_40Mhz_2G =
+		QDF_MIN(he_cap->he_ppdu_20_in_40Mhz_2G,
+				new_cap->he_ppdu_20_in_40Mhz_2G);
+	he_cap->he_ppdu_20_in_160_80p80Mhz =
+		QDF_MIN(he_cap->he_ppdu_20_in_160_80p80Mhz,
+				new_cap->he_ppdu_20_in_160_80p80Mhz);
+	he_cap->he_ppdu_80_in_160_80p80Mhz =
+		QDF_MIN(he_cap->he_ppdu_80_in_160_80p80Mhz,
+				new_cap->he_ppdu_80_in_160_80p80Mhz);
+	he_cap->er_1x_he_ltf_gi = QDF_MIN(he_cap->er_1x_he_ltf_gi,
+			new_cap->er_1x_he_ltf_gi);
+	he_cap->midamble_tx_rx_1x_he_ltf =
+		QDF_MIN(he_cap->midamble_tx_rx_1x_he_ltf,
+			new_cap->midamble_tx_rx_1x_he_ltf);
+	he_cap->reserved2 = QDF_MIN(he_cap->reserved2,
+			new_cap->reserved2);
+
+	/* take intersection for MCS map */
+	mcs_1 = he_cap->rx_he_mcs_map_lt_80;
+	mcs_2 = new_cap->rx_he_mcs_map_lt_80;
+	he_cap->rx_he_mcs_map_lt_80 = HE_INTERSECT_MCS(mcs_1, mcs_2);
+	mcs_1 = he_cap->tx_he_mcs_map_lt_80;
+	mcs_2 = new_cap->tx_he_mcs_map_lt_80;
+	he_cap->tx_he_mcs_map_lt_80 = HE_INTERSECT_MCS(mcs_1, mcs_2);
+	mcs_1 = *((uint16_t *)he_cap->rx_he_mcs_map_160);
+	mcs_2 = *((uint16_t *)new_cap->rx_he_mcs_map_160);
+	*((uint16_t *)he_cap->rx_he_mcs_map_160) =
+		HE_INTERSECT_MCS(mcs_1, mcs_2);
+	mcs_1 = *((uint16_t *)he_cap->tx_he_mcs_map_160);
+	mcs_2 = *((uint16_t *)new_cap->tx_he_mcs_map_160);
+	*((uint16_t *)he_cap->tx_he_mcs_map_160) =
+		HE_INTERSECT_MCS(mcs_1, mcs_2);
+	mcs_1 = *((uint16_t *)he_cap->rx_he_mcs_map_80_80);
+	mcs_2 = *((uint16_t *)new_cap->rx_he_mcs_map_80_80);
+	*((uint16_t *)he_cap->rx_he_mcs_map_80_80) =
+		HE_INTERSECT_MCS(mcs_1, mcs_2);
+	mcs_1 = *((uint16_t *)he_cap->tx_he_mcs_map_80_80);
+	mcs_2 = *((uint16_t *)new_cap->tx_he_mcs_map_80_80);
+	*((uint16_t *)he_cap->tx_he_mcs_map_80_80) =
+		HE_INTERSECT_MCS(mcs_1, mcs_2);
+}
+
+void wma_print_he_cap(tDot11fIEhe_cap *he_cap)
+{
+	uint8_t chan_width;
+	struct ppet_hdr *hdr;
+
+	if (!he_cap->present) {
+		WMA_LOGI(FL("HE Capabilities not present"));
+		return;
+	}
+
+	WMA_LOGD(FL("HE Capabilities:"));
+
+	/* HE MAC capabilities */
+	WMA_LOGD("\tHTC-HE conrol: 0x%01x", he_cap->htc_he);
+	WMA_LOGD("\tTWT Requestor support: 0x%01x", he_cap->twt_request);
+	WMA_LOGD("\tTWT Responder support: 0x%01x", he_cap->twt_responder);
+	WMA_LOGD("\tFragmentation support: 0x%02x", he_cap->fragmentation);
+	WMA_LOGD("\tMax no.of frag MSDUs: 0x%03x",
+		 he_cap->max_num_frag_msdu_amsdu_exp);
+	WMA_LOGD("\tMin. frag size: 0x%02x", he_cap->min_frag_size);
+	WMA_LOGD("\tTrigger MAC pad duration: 0x%02x",
+			he_cap->trigger_frm_mac_pad);
+	WMA_LOGD("\tMulti-TID aggr RX support: 0x%03x",
+		 he_cap->multi_tid_aggr_rx_supp);
+	WMA_LOGD("\tLink adaptation: 0x%02x", he_cap->he_link_adaptation);
+	WMA_LOGD("\tAll ACK support: 0x%01x", he_cap->all_ack);
+	WMA_LOGD("\tTriggered resp. scheduling: 0x%01x",
+		 he_cap->trigd_rsp_sched);
+	WMA_LOGD("\tA-Buff status report: 0x%01x", he_cap->a_bsr);
+	WMA_LOGD("\tBroadcast TWT support: 0x%01x", he_cap->broadcast_twt);
+	WMA_LOGD("\t32bit BA bitmap support: 0x%01x", he_cap->ba_32bit_bitmap);
+	WMA_LOGD("\tMU Cascading support: 0x%01x", he_cap->mu_cascade);
+	WMA_LOGD("\tACK enabled Multi-TID: 0x%01x",
+			he_cap->ack_enabled_multitid);
+	WMA_LOGD("\tOMI A-Control support: 0x%01x", he_cap->omi_a_ctrl);
+	WMA_LOGD("\tOFDMA RA support: 0x%01x", he_cap->ofdma_ra);
+	WMA_LOGD("\tMax A-MPDU Length: 0x%02x", he_cap->max_ampdu_len_exp_ext);
+	WMA_LOGD("\tA-MSDU Fragmentation: 0x%01x", he_cap->amsdu_frag);
+	WMA_LOGD("\tFlex. TWT sched support: 0x%01x", he_cap->flex_twt_sched);
+	WMA_LOGD("\tRx Ctrl frame to MBSS: 0x%01x", he_cap->rx_ctrl_frame);
+	WMA_LOGD("\tBSRP A-MPDU Aggregation: 0x%01x", he_cap->bsrp_ampdu_aggr);
+	WMA_LOGD("\tQuite Time Period support: 0x%01x", he_cap->qtp);
+	WMA_LOGD("\tA-BQR support: 0x%01x", he_cap->a_bqr);
+	WMA_LOGD("\tSR Responder: 0x%01x", he_cap->spatial_reuse_param_rspder);
+	WMA_LOGD("\tndp feedback supp: 0x%01x", he_cap->ndp_feedback_supp);
+	WMA_LOGD("\tops supp: 0x%01x", he_cap->ops_supp);
+	WMA_LOGD("\tamsdu in ampdu: 0x%01x", he_cap->amsdu_in_ampdu);
+	WMA_LOGD("\tMulti-TID aggr Tx support: 0x%03x",
+		 he_cap->multi_tid_aggr_tx_supp);
+	WMA_LOGD("\tHE sub ch sel tx supp: 0x%01x",
+		 he_cap->he_sub_ch_sel_tx_supp);
+	WMA_LOGD("\tUL 2x996 tone RU supp: 0x%01x",
+		 he_cap->ul_2x996_tone_ru_supp);
+	WMA_LOGD("\tOM ctrl UL MU data dis rx supp: 0x%01x",
+		 he_cap->om_ctrl_ul_mu_data_dis_rx);
+
+	/* HE PHY capabilities */
+	chan_width = HE_CH_WIDTH_COMBINE(he_cap->chan_width_0,
+				he_cap->chan_width_1, he_cap->chan_width_2,
+				he_cap->chan_width_3, he_cap->chan_width_4,
+				he_cap->chan_width_5, he_cap->chan_width_6);
+
+	WMA_LOGD("\tChannel width support: 0x%07x", chan_width);
+	WMA_LOGD("\tPreamble puncturing Rx: 0x%04x",
+			he_cap->rx_pream_puncturing);
+	WMA_LOGD("\tClass of device: 0x%01x", he_cap->device_class);
+	WMA_LOGD("\tLDPC coding support: 0x%01x", he_cap->ldpc_coding);
+	WMA_LOGD("\tLTF and GI for HE PPDUs: 0x%02x",
+		 he_cap->he_1x_ltf_800_gi_ppdu);
+	WMA_LOGD("\tMidamble Tx Rx MAX NSTS: 0x%02x",
+		 he_cap->midamble_tx_rx_max_nsts);
+	WMA_LOGD("\tLTF and GI for NDP: 0x%02x", he_cap->he_4x_ltf_3200_gi_ndp);
+	WMA_LOGD("\tSTBC Tx support <= 80M: 0x%01x", he_cap->tx_stbc_lt_80mhz);
+	WMA_LOGD("\tSTBC Rx support <= 80M: 0x%01x", he_cap->rx_stbc_lt_80mhz);
+	WMA_LOGD("\tDoppler support: 0x%02x", he_cap->doppler);
+	WMA_LOGD("\tUL MU: 0x%02x", he_cap->ul_mu);
+	WMA_LOGD("\tDCM encoding Tx: 0x%03x", he_cap->dcm_enc_tx);
+	WMA_LOGD("\tDCM encoding Rx: 0x%03x", he_cap->dcm_enc_rx);
+	WMA_LOGD("\tHE MU PPDU payload support: 0x%01x", he_cap->ul_he_mu);
+	WMA_LOGD("\tSU Beamformer: 0x%01x", he_cap->su_beamformer);
+	WMA_LOGD("\tSU Beamformee: 0x%01x", he_cap->su_beamformee);
+	WMA_LOGD("\tMU Beamformer: 0x%01x", he_cap->mu_beamformer);
+	WMA_LOGD("\tBeamformee STS for <= 80Mhz: 0x%03x",
+			he_cap->bfee_sts_lt_80);
+	WMA_LOGD("\tBeamformee STS for > 80Mhz: 0x%03x",
+			he_cap->bfee_sts_gt_80);
+	WMA_LOGD("\tNo. of sounding dim <= 80Mhz: 0x%03x",
+			he_cap->num_sounding_lt_80);
+	WMA_LOGD("\tNo. of sounding dim > 80Mhz: 0x%03x",
+			he_cap->num_sounding_gt_80);
+	WMA_LOGD("\tNg=16 for SU feedback support: 0x%01x",
+			he_cap->su_feedback_tone16);
+	WMA_LOGD("\tNg=16 for MU feedback support: 0x%01x",
+			he_cap->mu_feedback_tone16);
+	WMA_LOGD("\tCodebook size for SU: 0x%01x", he_cap->codebook_su);
+	WMA_LOGD("\tCodebook size for MU: 0x%01x ", he_cap->codebook_mu);
+	WMA_LOGD("\tBeamforming trigger w/ Trigger: 0x%01x",
+			he_cap->beamforming_feedback);
+	WMA_LOGD("\tHE ER SU PPDU payload: 0x%01x", he_cap->he_er_su_ppdu);
+	WMA_LOGD("\tDL MUMIMO on partial BW: 0x%01x",
+			he_cap->dl_mu_mimo_part_bw);
+	WMA_LOGD("\tPPET present: 0x%01x", he_cap->ppet_present);
+	WMA_LOGD("\tSRP based SR-support: 0x%01x", he_cap->srp);
+	WMA_LOGD("\tPower boost factor: 0x%01x", he_cap->power_boost);
+	WMA_LOGD("\t4x HE LTF support: 0x%01x", he_cap->he_ltf_800_gi_4x);
+
+	WMA_LOGD("\tMax NC: 0x%01x", he_cap->max_nc);
+	WMA_LOGD("\tstbc Tx gt 80mhz: 0x%01x", he_cap->tx_stbc_gt_80mhz);
+	WMA_LOGD("\tstbc Rx gt 80mhz: 0x%01x", he_cap->rx_stbc_gt_80mhz);
+	WMA_LOGD("\ter_he_ltf_800_gi_4x: 0x%01x", he_cap->er_he_ltf_800_gi_4x);
+	WMA_LOGD("\the_ppdu_20_in_40Mhz_2G: 0x%01x",
+					he_cap->he_ppdu_20_in_40Mhz_2G);
+	WMA_LOGD("\the_ppdu_20_in_160_80p80Mhz: 0x%01x",
+					he_cap->he_ppdu_20_in_160_80p80Mhz);
+	WMA_LOGD("\the_ppdu_80_in_160_80p80Mhz: 0x%01x",
+					he_cap->he_ppdu_80_in_160_80p80Mhz);
+	WMA_LOGD("\ter_1x_he_ltf_gi: 0x%01x",
+					he_cap->er_1x_he_ltf_gi);
+	WMA_LOGD("\tmidamble_tx_rx_1x_he_ltf: 0x%01x",
+		 he_cap->midamble_tx_rx_1x_he_ltf);
+	WMA_LOGD("\tDCM max BW: 0x%02x",
+		 he_cap->dcm_max_bw);
+	WMA_LOGD("\tlonger_than_16_he_sigb_ofdm_sym: 0x%01x",
+		 he_cap->longer_than_16_he_sigb_ofdm_sym);
+	WMA_LOGD("\tnon_trig_cqi_feedback: 0x%01x",
+		 he_cap->non_trig_cqi_feedback);
+	WMA_LOGD("\ttx_1024_qam_lt_242_tone_ru: 0x%01x",
+		 he_cap->tx_1024_qam_lt_242_tone_ru);
+	WMA_LOGD("\trx_1024_qam_lt_242_tone_ru: 0x%01x",
+		 he_cap->rx_1024_qam_lt_242_tone_ru);
+	WMA_LOGD("\trx_full_bw_su_he_mu_compress_sigb: 0x%01x",
+		 he_cap->rx_full_bw_su_he_mu_compress_sigb);
+	WMA_LOGD("\trx_full_bw_su_he_mu_non_cmpr_sigb: 0x%01x",
+		 he_cap->rx_full_bw_su_he_mu_non_cmpr_sigb);
+	WMA_LOGD("\tRx MCS MAP for BW <= 80 MHz: 0x%x",
+		he_cap->rx_he_mcs_map_lt_80);
+	WMA_LOGD("\tTx MCS MAP for BW <= 80 MHz: 0x%x",
+		he_cap->tx_he_mcs_map_lt_80);
+	WMA_LOGD("\tRx MCS MAP for BW = 160 MHz: 0x%x",
+		*((uint16_t *)he_cap->rx_he_mcs_map_160));
+	WMA_LOGD("\tTx MCS MAP for BW = 160 MHz: 0x%x",
+		*((uint16_t *)he_cap->tx_he_mcs_map_160));
+	WMA_LOGD("\tRx MCS MAP for BW = 80 + 80 MHz: 0x%x",
+		*((uint16_t *)he_cap->rx_he_mcs_map_80_80));
+	WMA_LOGD("\tTx MCS MAP for BW = 80 + 80 MHz: 0x%x",
+		*((uint16_t *)he_cap->tx_he_mcs_map_80_80));
+
+	hdr = (struct ppet_hdr *)&he_cap->ppet.ppe_threshold.ppe_th[0];
+	/* HE PPET */
+	WMA_LOGD("\tNSS: %d", hdr->nss + 1);
+	WMA_LOGD("\tRU Index mask: 0x%04x", hdr->ru_idx_mask);
+	WMA_LOGD("\tnum_ppet: %d", he_cap->ppet.ppe_threshold.num_ppe_th);
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
+		he_cap->ppet.ppe_threshold.ppe_th,
+		he_cap->ppet.ppe_threshold.num_ppe_th);
+}
+
+void wma_print_he_ppet(void *he_ppet)
+{
+	int numss, ru_count, ru_bit_mask, i, j;
+	struct wmi_host_ppe_threshold *ppet = he_ppet;
+
+	if (!ppet) {
+		WMA_LOGI(FL("PPET is NULL"));
+		return;
+	}
+
+	numss = ppet->numss_m1 + 1;
+	ru_bit_mask = ppet->ru_bit_mask;
+
+	WMA_LOGD(FL("HE PPET: ru_idx_mask: %04x"), ru_bit_mask);
+	for (ru_count = 0; ru_bit_mask; ru_bit_mask >>= 1)
+		if (ru_bit_mask & 0x1)
+			ru_count++;
+
+	if (ru_count > 0) {
+		WMA_LOGD(FL("PPET has following RU INDEX,"));
+		if (ppet->ru_bit_mask & HE_RU_ALLOC_INDX0_MASK)
+			WMA_LOGD("\tRU ALLOCATION INDEX 0");
+		if (ppet->ru_bit_mask & HE_RU_ALLOC_INDX1_MASK)
+			WMA_LOGD("\tRU ALLOCATION INDEX 1");
+		if (ppet->ru_bit_mask & HE_RU_ALLOC_INDX2_MASK)
+			WMA_LOGD("\tRU ALLOCATION INDEX 2");
+		if (ppet->ru_bit_mask & HE_RU_ALLOC_INDX3_MASK)
+			WMA_LOGD("\tRU ALLOCATION INDEX 3");
+	}
+
+	WMA_LOGD(FL("HE PPET: nss: %d, ru_count: %d"), numss, ru_count);
+
+	for (i = 0; i < numss; i++) {
+		WMA_LOGD("PPET for NSS[%d]", i);
+		for (j = 1; j <= ru_count; j++) {
+			WMA_LOGD("\tNSS[%d],RU[%d]: PPET16: %02x PPET8: %02x",
+			    i, j,
+			    WMI_GET_PPET16(ppet->ppet16_ppet8_ru3_ru0, j, i),
+			    WMI_GET_PPET8(ppet->ppet16_ppet8_ru3_ru0, j, i));
+		}
+	}
+
+}
+
+void wma_print_he_phy_cap(uint32_t *phy_cap)
+{
+	WMA_LOGD(FL("HE PHY Capabilities:"));
+
+	WMA_LOGD("\tChannel width support: 0x%07x",
+		WMI_HECAP_PHY_CBW_GET(phy_cap));
+	WMA_LOGD("\tPreamble puncturing Rx: 0x%04x",
+		WMI_HECAP_PHY_PREAMBLEPUNCRX_GET(phy_cap));
+	WMA_LOGD("\tClass of device: 0x%01x", WMI_HECAP_PHY_COD_GET(phy_cap));
+	WMA_LOGD("\tLDPC coding support: 0x%01x",
+		WMI_HECAP_PHY_LDPC_GET(phy_cap));
+	WMA_LOGD("\tLTF and GI for HE PPDUs: 0x%02x",
+		WMI_HECAP_PHY_LTFGIFORHE_GET(phy_cap));
+	WMA_LOGD("\tLTF and GI for NDP: 0x%02x",
+		WMI_HECAP_PHY_LTFGIFORNDP_GET(phy_cap));
+	WMA_LOGD("\tSTBC Tx & Rx support (BW <= 80Mhz): 0x%02x",
+			(WMI_HECAP_PHY_RXSTBC_GET(phy_cap) << 1) |
+			 WMI_HECAP_PHY_TXSTBC_GET(phy_cap));
+	WMA_LOGD("\tDoppler support: 0x%02x",
+			(WMI_HECAP_PHY_RXDOPPLER_GET(phy_cap) << 1) |
+			 WMI_HECAP_PHY_TXDOPPLER(phy_cap));
+	WMA_LOGD("\tUL MU (Full BW): 0x%01x",
+		  WMI_HECAP_PHY_UL_MU_MIMO_GET(phy_cap));
+	WMA_LOGD("\tUL MU (Partial BW): 0x%01x",
+		  WMI_HECAP_PHY_ULMUMIMOOFDMA_GET(phy_cap));
+	WMA_LOGD("\tDCM encoding Tx: 0x%03x", WMI_HECAP_PHY_DCMTX_GET(phy_cap));
+	WMA_LOGD("\tDCM encoding Rx: 0x%03x", WMI_HECAP_PHY_DCMRX_GET(phy_cap));
+	WMA_LOGD("\tHE MU PPDU payload support: 0x%01x",
+		WMI_HECAP_PHY_ULHEMU_GET(phy_cap));
+	WMA_LOGD("\tSU Beamformer: 0x%01x", WMI_HECAP_PHY_SUBFMR_GET(phy_cap));
+	WMA_LOGD("\tSU Beamformee: 0x%01x", WMI_HECAP_PHY_SUBFME_GET(phy_cap));
+	WMA_LOGD("\tMU Beamformer: 0x%01x", WMI_HECAP_PHY_MUBFMR_GET(phy_cap));
+	WMA_LOGD("\tBeamformee STS for <= 80Mhz: 0x%03x",
+			WMI_HECAP_PHY_BFMESTSLT80MHZ_GET(phy_cap));
+	WMA_LOGD("\tNSTS total for <= 80Mhz: 0x%03x",
+		WMI_HECAP_PHY_NSTSLT80MHZ_GET(phy_cap));
+	WMA_LOGD("\tBeamformee STS for > 80Mhz: 0x%03x",
+		WMI_HECAP_PHY_BFMESTSGT80MHZ_GET(phy_cap));
+	WMA_LOGD("\tNSTS total for > 80Mhz: 0x%03x",
+		WMI_HECAP_PHY_NSTSGT80MHZ_GET(phy_cap));
+	WMA_LOGD("\tNo. of sounding dim <= 80Mhz: 0x%03x",
+		WMI_HECAP_PHY_NUMSOUNDLT80MHZ_GET(phy_cap));
+	WMA_LOGD("\tNo. of sounding dim > 80Mhz: 0x%03x",
+		WMI_HECAP_PHY_NUMSOUNDGT80MHZ_GET(phy_cap));
+	WMA_LOGD("\tNg=16 for SU feedback support: 0x%01x",
+		WMI_HECAP_PHY_NG16SUFEEDBACKLT80_GET(phy_cap));
+	WMA_LOGD("\tNg=16 for MU feedback support: 0x%01x",
+		WMI_HECAP_PHY_NG16MUFEEDBACKGT80_GET(phy_cap));
+	WMA_LOGD("\tCodebook size for SU: 0x%01x",
+		WMI_HECAP_PHY_CODBK42SU_GET(phy_cap));
+	WMA_LOGD("\tCodebook size for MU: 0x%01x ",
+		WMI_HECAP_PHY_CODBK75MU_GET(phy_cap));
+	WMA_LOGD("\tBeamforming trigger w/ Trigger: 0x%01x",
+		WMI_HECAP_PHY_BFFEEDBACKTRIG_GET(phy_cap));
+	WMA_LOGD("\tHE ER SU PPDU payload: 0x%01x",
+		WMI_HECAP_PHY_HEERSU_GET(phy_cap));
+	WMA_LOGD("\tDL MUMIMO on partial BW: 0x%01x",
+		WMI_HECAP_PHY_DLMUMIMOPARTIALBW_GET(phy_cap));
+	WMA_LOGD("\tPPET present: 0x%01x",
+		 WMI_HECAP_PHY_PETHRESPRESENT_GET(phy_cap));
+	WMA_LOGD("\tSRP based SR-support: 0x%01x",
+		WMI_HECAP_PHY_SRPSPRESENT_GET(phy_cap));
+	WMA_LOGD("\tPower boost factor: 0x%01x",
+		WMI_HECAP_PHY_PWRBOOSTAR_GET(phy_cap));
+	WMA_LOGD("\t4x HE LTF support: 0x%01x",
+		WMI_HECAP_PHY_4XLTFAND800NSECSGI_GET(phy_cap));
+	WMA_LOGD("\tMax Nc supported: 0x%03x",
+		WMI_HECAP_PHY_MAXNC_GET(phy_cap));
+	WMA_LOGD("\tSTBC Tx & Rx support (BW > 80Mhz): 0x%02x",
+			(WMI_HECAP_PHY_STBCRXGT80_GET(phy_cap) << 1) |
+			 WMI_HECAP_PHY_STBCTXGT80_GET(phy_cap));
+	WMA_LOGD("\tER 4x HE LTF support: 0x%01x",
+		 WMI_HECAP_PHY_ERSU4X800NSECGI_GET(phy_cap));
+}
+
+void wma_print_he_mac_cap_w1(uint32_t mac_cap)
+{
+	WMA_LOGD(FL("HE MAC Capabilities:"));
+
+	WMA_LOGD("\tHTC-HE conrol: 0x%01x", WMI_HECAP_MAC_HECTRL_GET(mac_cap));
+	WMA_LOGD("\tTWT Requestor support: 0x%01x",
+			WMI_HECAP_MAC_TWTREQ_GET(mac_cap));
+	WMA_LOGD("\tTWT Responder support: 0x%01x",
+			WMI_HECAP_MAC_TWTRSP_GET(mac_cap));
+	WMA_LOGD("\tFragmentation support: 0x%02x",
+			WMI_HECAP_MAC_HEFRAG_GET(mac_cap));
+	WMA_LOGD("\tMax no.of frag MSDUs: 0x%03x",
+			WMI_HECAP_MAC_MAXFRAGMSDU_GET(mac_cap));
+	WMA_LOGD("\tMin. frag size: 0x%02x",
+			WMI_HECAP_MAC_MINFRAGSZ_GET(mac_cap));
+	WMA_LOGD("\tTrigger MAC pad duration: 0x%02x",
+			WMI_HECAP_MAC_TRIGPADDUR_GET(mac_cap));
+	WMA_LOGD("\tMulti-TID aggr Rx support: 0x%03x",
+		 WMI_HECAP_MAC_MTID_RX_GET(mac_cap));
+	WMA_LOGD("\tLink adaptation: 0x%02x",
+			WMI_HECAP_MAC_HELINK_ADPT_GET(mac_cap));
+	WMA_LOGD("\tAll ACK support: 0x%01x",
+			WMI_HECAP_MAC_AACK_GET(mac_cap));
+	WMA_LOGD("\tUL MU resp. scheduling: 0x%01x",
+			WMI_HECAP_MAC_TRS_GET(mac_cap));
+	WMA_LOGD("\tA-Buff status report: 0x%01x",
+			WMI_HECAP_MAC_BSR_GET(mac_cap));
+	WMA_LOGD("\tBroadcast TWT support: 0x%01x",
+			WMI_HECAP_MAC_BCSTTWT_GET(mac_cap));
+	WMA_LOGD("\t32bit BA bitmap support: 0x%01x",
+			WMI_HECAP_MAC_32BITBA_GET(mac_cap));
+	WMA_LOGD("\tMU Cascading support: 0x%01x",
+			WMI_HECAP_MAC_MUCASCADE_GET(mac_cap));
+	WMA_LOGD("\tACK enabled Multi-TID: 0x%01x",
+			WMI_HECAP_MAC_ACKMTIDAMPDU_GET(mac_cap));
+	WMA_LOGD("\tOMI A-Control support: 0x%01x",
+			WMI_HECAP_MAC_OMI_GET(mac_cap));
+	WMA_LOGD("\tOFDMA RA support: 0x%01x",
+			WMI_HECAP_MAC_OFDMARA_GET(mac_cap));
+	WMA_LOGD("\tMax A-MPDU Length: 0x%02x",
+		WMI_HECAP_MAC_MAXAMPDULEN_EXP_GET(mac_cap));
+	WMA_LOGD("\tA-MSDU Fragmentation: 0x%01x",
+		WMI_HECAP_MAC_AMSDUFRAG_GET(mac_cap));
+	WMA_LOGD("\tFlex. TWT sched support: 0x%01x",
+		WMI_HECAP_MAC_FLEXTWT_GET(mac_cap));
+	WMA_LOGD("\tRx Ctrl frame to MBSS: 0x%01x",
+			WMI_HECAP_MAC_MBSS_GET(mac_cap));
+}
+
+void wma_print_he_mac_cap_w2(uint32_t mac_cap)
+{
+	WMA_LOGD("\tBSRP A-MPDU Aggregation: 0x%01x",
+		WMI_HECAP_MAC_BSRPAMPDU_GET(mac_cap));
+	WMA_LOGD("\tQuite Time Period support: 0x%01x",
+		WMI_HECAP_MAC_QTP_GET(mac_cap));
+	WMA_LOGD("\tA-BQR support: 0x%01x", WMI_HECAP_MAC_ABQR_GET(mac_cap));
+	WMA_LOGD("\tSR Responder support: 0x%01x",
+		 WMI_HECAP_MAC_SRPRESP_GET(mac_cap));
+	WMA_LOGD("\tNDP Feedback Support: 0x%01x",
+		 WMI_HECAP_MAC_NDPFDBKRPT_GET(mac_cap));
+	WMA_LOGD("\tOPS Support: 0x%01x",
+		 WMI_HECAP_MAC_OPS_GET(mac_cap));
+	WMA_LOGD("\tMulti-TID aggr Tx support: 0x%03x",
+		 WMI_HECAP_MAC_MTID_TX_GET(mac_cap));
+	WMA_LOGD("\tSub Ch selective Tx support: 0x%01x",
+		 WMI_HECAP_MAC_SUBCHANSELTX_GET(mac_cap));
+	WMA_LOGD("\tUL 2x996 tone RU: 0x%01x",
+		 WMI_HECAP_MAC_UL2X996RU_GET(mac_cap));
+	WMA_LOGD("\tOM ctrl UL MU data disable Rx: 0x%01x",
+		 WMI_HECAP_MAC_OMCULMUDDIS_GET(mac_cap));
+}
+
+void wma_update_target_ext_he_cap(struct target_psoc_info *tgt_hdl,
+				  struct wma_tgt_cfg *tgt_cfg)
+{
+	tDot11fIEhe_cap *he_cap = &tgt_cfg->he_cap;
+	int i, num_hw_modes, total_mac_phy_cnt;
+	struct wlan_psoc_host_mac_phy_caps *mac_cap, *mac_phy_cap;
+	tDot11fIEhe_cap he_cap_mac;
+	tDot11fIEhe_cap tmp_he_cap = {0};
+
+	qdf_mem_zero(&tgt_cfg->he_cap_2g, sizeof(tgt_cfg->he_cap_2g));
+	qdf_mem_zero(&tgt_cfg->he_cap_5g, sizeof(tgt_cfg->he_cap_5g));
+	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
+	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
+	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
+
+	if (!num_hw_modes) {
+		WMA_LOGE(FL("No extended HE cap for current SOC"));
+		he_cap->present = false;
+		return;
+	}
+
+	if (!tgt_cfg->services.en_11ax) {
+		WMA_LOGI(FL("Target does not support 11AX"));
+		he_cap->present = false;
+		return;
+	}
+
+	for (i = 0; i < total_mac_phy_cnt; i++) {
+		qdf_mem_zero(&he_cap_mac,
+				sizeof(tDot11fIEhe_cap));
+		mac_cap = &mac_phy_cap[i];
+		if (mac_cap->supported_bands & WLAN_2G_CAPABILITY) {
+			wma_convert_he_cap(&he_cap_mac,
+					mac_cap->he_cap_info_2G,
+					mac_cap->he_cap_phy_info_2G,
+					mac_cap->he_supp_mcs_2G,
+					mac_cap->tx_chain_mask_2G,
+					mac_cap->rx_chain_mask_2G);
+			WMA_LOGD(FL("2g phy: nss: %d, ru_idx_msk: %d"),
+					mac_cap->he_ppet2G.numss_m1,
+					mac_cap->he_ppet2G.ru_bit_mask);
+			wma_convert_he_ppet(tgt_cfg->ppet_2g,
+					(struct wmi_host_ppe_threshold *)
+					&mac_cap->he_ppet2G);
+		}
+
+		if (he_cap_mac.present) {
+			wma_derive_ext_he_cap(&tmp_he_cap,
+					      &he_cap_mac);
+			wma_derive_ext_he_cap(&tgt_cfg->he_cap_2g,
+					      &he_cap_mac);
+		}
+
+		qdf_mem_zero(&he_cap_mac,
+				sizeof(tDot11fIEhe_cap));
+		if (mac_cap->supported_bands & WLAN_5G_CAPABILITY) {
+			wma_convert_he_cap(&he_cap_mac,
+					mac_cap->he_cap_info_5G,
+					mac_cap->he_cap_phy_info_5G,
+					mac_cap->he_supp_mcs_5G,
+					mac_cap->tx_chain_mask_5G,
+					mac_cap->rx_chain_mask_5G);
+			WMA_LOGD(FL("5g phy: nss: %d, ru_idx_msk: %d"),
+					mac_cap->he_ppet2G.numss_m1,
+					mac_cap->he_ppet2G.ru_bit_mask);
+			wma_convert_he_ppet(tgt_cfg->ppet_5g,
+					(struct wmi_host_ppe_threshold *)
+					&mac_cap->he_ppet5G);
+		}
+		if (he_cap_mac.present) {
+			wma_derive_ext_he_cap(&tmp_he_cap,
+					      &he_cap_mac);
+			wma_derive_ext_he_cap(&tgt_cfg->he_cap_5g,
+					      &he_cap_mac);
+		}
+	}
+
+	qdf_mem_copy(he_cap, &tmp_he_cap, sizeof(*he_cap));
+	wma_print_he_cap(he_cap);
+}
+
+void wma_he_update_tgt_services(struct wmi_unified *wmi_handle,
+				struct wma_tgt_services *cfg)
+{
+	if (wmi_service_enabled(wmi_handle, wmi_service_11ax)) {
+		cfg->en_11ax = true;
+		wma_set_fw_wlan_feat_caps(DOT11AX);
+		WMA_LOGI(FL("11ax is enabled"));
+	} else {
+		WMA_LOGI(FL("11ax is not enabled"));
+	}
+}
+
+void wma_print_he_op(tDot11fIEhe_op *he_ops)
+{
+	WMA_LOGD(FL("bss_color %0x def_pe_dur %0x twt_req %0x txop_rts_thre %0x vht_oper %0x"),
+		 he_ops->bss_color, he_ops->default_pe,
+		 he_ops->twt_required, he_ops->txop_rts_threshold,
+		 he_ops->vht_oper_present);
+	WMA_LOGD(FL("\tpart_bss_color: %0x, MBSSID AP: %0x, BSS color dis %0x"),
+		 he_ops->partial_bss_col, he_ops->co_located_bss,
+		 he_ops->bss_col_disabled);
+}
+
+/**
+ * wma_parse_he_ppet() - Convert PPET stored in dot11f structure into FW
+ *                       structure.
+ * @rcvd_ppet: pointer to dot11f format PPET
+ * @peer_ppet: pointer peer_ppet to be sent in peer assoc
+ *
+ * This function converts the sequence of PPET stored in the host in OTA type
+ * structure into FW understandable structure to be sent as part of peer assoc
+ * command.
+ *
+ * Return: None
+ */
+static void wma_parse_he_ppet(int8_t *rcvd_ppet,
+			      struct wmi_host_ppe_threshold *peer_ppet)
+{
+	struct ppet_hdr *hdr;
+	uint8_t num_ppet, mask, mask1, mask2;
+	uint32_t ppet1, ppet2, ppet;
+	uint8_t bits, pad, pad_bits, req_byte;
+	uint8_t byte_idx, start, i, j, parsed;
+	uint32_t *ppet_r = peer_ppet->ppet16_ppet8_ru3_ru0;
+	uint8_t nss, ru;
+
+	hdr = (struct ppet_hdr *)rcvd_ppet;
+	nss = hdr->nss + 1;
+	mask = hdr->ru_idx_mask;
+	peer_ppet->numss_m1 = nss - 1;
+	peer_ppet->ru_bit_mask = mask;
+
+	for (ru = 0; mask; mask >>= 1) {
+		if (mask & 0x1)
+			ru++;
+	}
+
+	WMA_LOGD(FL("Rcvd nss=%d ru_idx_mask: %0x ru_count=%d"),
+		 nss, hdr->ru_idx_mask, ru);
+
+	/* each nss-ru pair have 2 PPET (PPET8/PPET16) */
+	bits = HE_PPET_NSS_RU_LEN + (nss + ru) * (HE_PPET_SIZE * 2);
+	pad = bits % HE_BYTE_SIZE;
+	pad_bits = HE_BYTE_SIZE - pad;
+	req_byte = (bits + pad_bits) / HE_BYTE_SIZE;
+
+	/*
+	 * PPE Threshold Field Format
+	 * +-----------+--------------+--------------------+-------------+
+	 * |   NSS     | RU idx mask  | PPE Threshold info |  Padding    |
+	 * +-----------+--------------+--------------------+-------------+
+	 *        3           4             1 + variable       variable   (bits)
+	 *
+	 * PPE Threshold Info field:
+	 * number of NSS:n, number of RU: m
+	 * +------------+-----------+-----+------------+-----------+-----+-----------+-----------+
+	 * | PPET16 for | PPET8 for | ... | PPET16 for | PPET8 for | ... | PET16 for | PPET8 for |
+	 * | NSS1, RU1  | NSS1, RU1 | ... | NSS1, RUm  | NSS1, RUm | ... | NSSn, RUm | NSSn, RUm |
+	 * +------------+-----------+-----+------------+-----------+-----+-----------+-----------+
+	 *        3           3       ...       3           3        ...       3           3
+	 */
+
+	/* first bit of first PPET is in the last bit of first byte */
+	parsed = HE_PPET_NSS_RU_LEN;
+
+	/*
+	 * refer wmi_ppe_threshold defn to understand how ppet is stored.
+	 * Index of ppet array(ppet16_ppet8_ru3_ru0) is the NSS value.
+	 * Each item in ppet16_ppet8_ru3_ru0 holds ppet for all the RUs.
+	 */
+	num_ppet = ru * 2; /* for each NSS */
+	for (i = 0; i < nss; i++) {
+		for (j = 1; j <= num_ppet; j++) {
+			start = parsed + (i * (num_ppet * HE_PPET_SIZE)) +
+				(j-1) * HE_PPET_SIZE;
+			byte_idx = start / HE_BYTE_SIZE;
+			start = start % HE_BYTE_SIZE;
+
+			if (start <= HE_BYTE_SIZE - HE_PPET_SIZE) {
+				mask = 0x07 << start;
+				ppet = (rcvd_ppet[byte_idx] & mask) >> start;
+				ppet_r[i] |= (ppet << (j - 1) * HE_PPET_SIZE);
+			} else {
+				mask1 = 0x07 << start;
+				ppet1 = (rcvd_ppet[byte_idx] & mask1) >> start;
+				mask2 = 0x07 >> (HE_BYTE_SIZE - start);
+				ppet2 = (rcvd_ppet[byte_idx + 1] & mask2) <<
+						(HE_BYTE_SIZE - start);
+				ppet = ppet1 | ppet2;
+				ppet_r[i] |= (ppet << (j - 1) * HE_PPET_SIZE);
+			}
+			WMA_LOGD(FL("nss:%d ru:%d ppet_r:%0x"), i, j/2,
+				 ppet_r[i]);
+		}
+	}
+}
+
+void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
+			      tpAddStaParams params)
+{
+	tDot11fIEhe_cap *he_cap = &params->he_config;
+	tDot11fIEhe_op *he_op = &params->he_op;
+	uint32_t *phy_cap = peer->peer_he_cap_phyinfo;
+	uint32_t mac_cap[PSOC_HOST_MAX_MAC_SIZE] = {0}, he_ops = 0;
+	uint8_t temp, i, chan_width;
+
+	if (params->he_capable)
+		peer->peer_flags |= WMI_PEER_HE;
+	else
+		return;
+
+	/* HE MAC capabilities */
+	WMI_HECAP_MAC_HECTRL_SET(mac_cap[0], he_cap->htc_he);
+	WMI_HECAP_MAC_TWTREQ_SET(mac_cap[0], he_cap->twt_request);
+	WMI_HECAP_MAC_TWTRSP_SET(mac_cap[0], he_cap->twt_responder);
+	WMI_HECAP_MAC_HEFRAG_SET(mac_cap[0], he_cap->fragmentation);
+	WMI_HECAP_MAC_MAXFRAGMSDU_SET(mac_cap[0],
+				      he_cap->max_num_frag_msdu_amsdu_exp);
+	WMI_HECAP_MAC_MINFRAGSZ_SET(mac_cap[0], he_cap->min_frag_size);
+	WMI_HECAP_MAC_TRIGPADDUR_SET(mac_cap[0], he_cap->trigger_frm_mac_pad);
+	WMI_HECAP_MAC_ACKMTIDAMPDU_SET(mac_cap[0],
+				       he_cap->multi_tid_aggr_rx_supp);
+	WMI_HECAP_MAC_HELKAD_SET(mac_cap[0], he_cap->he_link_adaptation);
+	WMI_HECAP_MAC_AACK_SET(mac_cap[0], he_cap->all_ack);
+	WMI_HECAP_MAC_TRS_SET(mac_cap[0], he_cap->trigd_rsp_sched);
+	WMI_HECAP_MAC_BSR_SET(mac_cap[0], he_cap->a_bsr);
+	WMI_HECAP_MAC_BCSTTWT_SET(mac_cap[0], he_cap->broadcast_twt);
+	WMI_HECAP_MAC_32BITBA_SET(mac_cap[0], he_cap->ba_32bit_bitmap);
+	WMI_HECAP_MAC_MUCASCADE_SET(mac_cap[0], he_cap->mu_cascade);
+	WMI_HECAP_MAC_ACKMTIDAMPDU_SET(mac_cap[0],
+				       he_cap->ack_enabled_multitid);
+	WMI_HECAP_MAC_OMI_SET(mac_cap[0], he_cap->omi_a_ctrl);
+	WMI_HECAP_MAC_OFDMARA_SET(mac_cap[0], he_cap->ofdma_ra);
+	WMI_HECAP_MAC_MAXAMPDULEN_EXP_SET(mac_cap[0],
+					  he_cap->max_ampdu_len_exp_ext);
+	WMI_HECAP_MAC_AMSDUFRAG_SET(mac_cap[0], he_cap->amsdu_frag);
+	WMI_HECAP_MAC_FLEXTWT_SET(mac_cap[0], he_cap->flex_twt_sched);
+	WMI_HECAP_MAC_MBSS_SET(mac_cap[0], he_cap->rx_ctrl_frame);
+	WMI_HECAP_MAC_BSRPAMPDU_SET(mac_cap[1], he_cap->bsrp_ampdu_aggr);
+	WMI_HECAP_MAC_QTP_SET(mac_cap[1], he_cap->qtp);
+	WMI_HECAP_MAC_ABQR_SET(mac_cap[1], he_cap->a_bqr);
+	WMI_HECAP_MAC_SRPRESP_SET(mac_cap[1],
+				  he_cap->spatial_reuse_param_rspder);
+	WMI_HECAP_MAC_OPS_SET(mac_cap[1], he_cap->ops_supp);
+	WMI_HECAP_MAC_NDPFDBKRPT_SET(mac_cap[1], he_cap->ndp_feedback_supp);
+	WMI_HECAP_MAC_AMSDUINAMPDU_SET(mac_cap[1], he_cap->amsdu_in_ampdu);
+	WMI_HECAP_MAC_MTID_TX_SET(mac_cap[1], he_cap->multi_tid_aggr_tx_supp);
+	WMI_HECAP_MAC_SUBCHANSELTX_SET(mac_cap[1],
+				       he_cap->he_sub_ch_sel_tx_supp);
+	WMI_HECAP_MAC_UL2X996RU_SET(mac_cap[1], he_cap->ul_2x996_tone_ru_supp);
+	WMI_HECAP_MAC_OMCULMUDDIS_SET(mac_cap[1],
+				      he_cap->om_ctrl_ul_mu_data_dis_rx);
+	qdf_mem_copy(peer->peer_he_cap_macinfo, mac_cap, sizeof(mac_cap));
+
+	/* HE PHY capabilities */
+	chan_width = HE_CH_WIDTH_COMBINE(he_cap->chan_width_0,
+				he_cap->chan_width_1, he_cap->chan_width_2,
+				he_cap->chan_width_3, he_cap->chan_width_4,
+				he_cap->chan_width_5, he_cap->chan_width_6);
+	WMI_HECAP_PHY_CBW_SET(phy_cap, chan_width);
+	WMI_HECAP_PHY_PREAMBLEPUNCRX_SET(phy_cap, he_cap->rx_pream_puncturing);
+	WMI_HECAP_PHY_COD_SET(phy_cap, he_cap->device_class);
+	WMI_HECAP_PHY_LDPC_SET(phy_cap, he_cap->ldpc_coding);
+	WMI_HECAP_PHY_LTFGIFORHE_SET(phy_cap, he_cap->he_1x_ltf_800_gi_ppdu);
+	WMI_HECAP_PHY_MIDAMBLETXRXMAXNSTS_SET(phy_cap,
+					      he_cap->midamble_tx_rx_max_nsts);
+	WMI_HECAP_PHY_LTFGIFORNDP_SET(phy_cap, he_cap->he_4x_ltf_3200_gi_ndp);
+
+	WMI_HECAP_PHY_RXSTBC_SET(phy_cap, he_cap->rx_stbc_lt_80mhz);
+	WMI_HECAP_PHY_TXSTBC_SET(phy_cap, he_cap->tx_stbc_lt_80mhz);
+
+	temp = he_cap->doppler & 0x1;
+	WMI_HECAP_PHY_RXDOPPLER_SET(phy_cap, temp);
+	temp = he_cap->doppler >> 0x1;
+	WMI_HECAP_PHY_TXDOPPLER_SET(phy_cap, temp);
+
+	temp = he_cap->ul_mu & 0x1;
+	WMI_HECAP_PHY_UL_MU_MIMO_SET(phy_cap, temp);
+	temp = he_cap->ul_mu >>  0x1;
+	WMI_HECAP_PHY_ULMUMIMOOFDMA_SET(phy_cap, temp);
+
+	WMI_HECAP_PHY_DCMTX_SET(phy_cap, he_cap->dcm_enc_tx);
+	WMI_HECAP_PHY_DCMRX_SET(phy_cap, he_cap->dcm_enc_rx);
+	WMI_HECAP_PHY_ULHEMU_SET(phy_cap, he_cap->ul_he_mu);
+	WMI_HECAP_PHY_SUBFMR_SET(phy_cap, he_cap->su_beamformer);
+	WMI_HECAP_PHY_SUBFME_SET(phy_cap, he_cap->su_beamformee);
+	WMI_HECAP_PHY_MUBFMR_SET(phy_cap, he_cap->mu_beamformer);
+	WMI_HECAP_PHY_BFMESTSLT80MHZ_SET(phy_cap, he_cap->bfee_sts_lt_80);
+	WMI_HECAP_PHY_BFMESTSGT80MHZ_SET(phy_cap, he_cap->bfee_sts_gt_80);
+	WMI_HECAP_PHY_NUMSOUNDLT80MHZ_SET(phy_cap, he_cap->num_sounding_lt_80);
+	WMI_HECAP_PHY_NUMSOUNDGT80MHZ_SET(phy_cap, he_cap->num_sounding_gt_80);
+	WMI_HECAP_PHY_NG16SUFEEDBACKLT80_SET(phy_cap,
+					     he_cap->su_feedback_tone16);
+	WMI_HECAP_PHY_NG16MUFEEDBACKGT80_SET(phy_cap,
+					     he_cap->mu_feedback_tone16);
+	WMI_HECAP_PHY_CODBK42SU_SET(phy_cap, he_cap->codebook_su);
+	WMI_HECAP_PHY_CODBK75MU_SET(phy_cap, he_cap->codebook_mu);
+	WMI_HECAP_PHY_BFFEEDBACKTRIG_SET(phy_cap, he_cap->beamforming_feedback);
+	WMI_HECAP_PHY_HEERSU_SET(phy_cap, he_cap->he_er_su_ppdu);
+	WMI_HECAP_PHY_DLMUMIMOPARTIALBW_SET(phy_cap,
+					    he_cap->dl_mu_mimo_part_bw);
+	WMI_HECAP_PHY_PETHRESPRESENT_SET(phy_cap, he_cap->ppet_present);
+	WMI_HECAP_PHY_SRPPRESENT_SET(phy_cap, he_cap->srp);
+	WMI_HECAP_PHY_PWRBOOSTAR_SET(phy_cap, he_cap->power_boost);
+	WMI_HECAP_PHY_4XLTFAND800NSECSGI_SET(phy_cap, he_cap->he_ltf_800_gi_4x);
+
+	WMI_HECAP_PHY_MAXNC_SET(phy_cap, he_cap->max_nc);
+
+	WMI_HECAP_PHY_STBCRXGT80_SET(phy_cap, he_cap->rx_stbc_gt_80mhz);
+	WMI_HECAP_PHY_STBCTXGT80_SET(phy_cap, he_cap->tx_stbc_gt_80mhz);
+
+	WMI_HECAP_PHY_ERSU4X800NSECGI_SET(phy_cap, he_cap->er_he_ltf_800_gi_4x);
+	WMI_HECAP_PHY_HEPPDU20IN40MHZ2G_SET(phy_cap,
+					he_cap->he_ppdu_20_in_40Mhz_2G);
+	WMI_HECAP_PHY_HEPPDU20IN160OR80P80MHZ_SET(phy_cap,
+					he_cap->he_ppdu_20_in_160_80p80Mhz);
+	WMI_HECAP_PHY_HEPPDU80IN160OR80P80MHZ_SET(phy_cap,
+					he_cap->he_ppdu_80_in_160_80p80Mhz);
+	WMI_HECAP_PHY_ERSU1X800NSECGI_SET(phy_cap, he_cap->er_1x_he_ltf_gi);
+	WMI_HECAP_PHY_MIDAMBLETXRX2XAND1XHELTF_SET(phy_cap,
+						   he_cap->
+						   midamble_tx_rx_1x_he_ltf);
+	WMI_HECAP_PHY_DCMMAXBW_SET(phy_cap, he_cap->dcm_max_bw);
+	WMI_HECAP_PHY_LNG16SIGBSYMBSUPRT_SET(phy_cap,
+					     he_cap->
+					     longer_than_16_he_sigb_ofdm_sym);
+	WMI_HECAP_PHY_NONTRIGCQIFEEDBK_SET(phy_cap,
+					   he_cap->non_trig_cqi_feedback);
+	WMI_HECAP_PHY_TX1024QAM242RUSUPRT_SET(phy_cap,
+					      he_cap->
+					      tx_1024_qam_lt_242_tone_ru);
+	WMI_HECAP_PHY_RX1024QAM242RUSUPRT_SET(phy_cap,
+					      he_cap->
+					      rx_1024_qam_lt_242_tone_ru);
+	WMI_HECAP_PHY_RXFULBWSUWCMPRSSIGB_SET(phy_cap,
+					      he_cap->rx_full_bw_su_he_mu_compress_sigb);
+	WMI_HECAP_PHY_RXFULBWSUWNONCMPRSSIGB_SET(phy_cap,
+						 he_cap->rx_full_bw_su_he_mu_non_cmpr_sigb);
+
+	/* as per 11ax draft 1.4 */
+	peer->peer_he_mcs_count = 1;
+	peer->peer_he_rx_mcs_set[0] =
+		params->supportedRates.rx_he_mcs_map_lt_80;
+	peer->peer_he_tx_mcs_set[0] =
+		params->supportedRates.tx_he_mcs_map_lt_80;
+
+	if (params->ch_width > CH_WIDTH_80MHZ) {
+		peer->peer_he_mcs_count = WMI_HOST_MAX_HE_RATE_SET;
+		peer->peer_he_rx_mcs_set[1] =
+			params->supportedRates.rx_he_mcs_map_160;
+		peer->peer_he_tx_mcs_set[1] =
+			params->supportedRates.tx_he_mcs_map_160;
+		peer->peer_he_rx_mcs_set[2] =
+			params->supportedRates.rx_he_mcs_map_80_80;
+		peer->peer_he_tx_mcs_set[2] =
+			params->supportedRates.tx_he_mcs_map_80_80;
+	}
+
+	for (i = 0; i < peer->peer_he_mcs_count; i++)
+		WMA_LOGD(FL("[HE - MCS Map: %d] rx_mcs: 0x%x, tx_mcs: 0x%x"), i,
+			peer->peer_he_rx_mcs_set[i],
+			peer->peer_he_tx_mcs_set[i]);
+
+	WMI_HEOPS_COLOR_SET(he_ops, he_op->bss_color);
+	WMI_HEOPS_DEFPE_SET(he_ops, he_op->default_pe);
+	WMI_HEOPS_TWT_SET(he_ops, he_op->twt_required);
+	WMI_HEOPS_RTSTHLD_SET(he_ops, he_op->txop_rts_threshold);
+	WMI_HEOPS_PARTBSSCOLOR_SET(he_ops, he_op->partial_bss_col);
+	WMI_HEOPS_BSSCOLORDISABLE_SET(he_ops, he_op->bss_col_disabled);
+	peer->peer_he_ops = he_ops;
+
+	wma_parse_he_ppet(he_cap->ppet.ppe_threshold.ppe_th, &peer->peer_ppet);
+
+	wma_print_he_cap(he_cap);
+	WMA_LOGD(FL("Peer HE Capabilities:"));
+	wma_print_he_phy_cap(phy_cap);
+	wma_print_he_mac_cap_w1(mac_cap[0]);
+	wma_print_he_mac_cap_w2(mac_cap[1]);
+	wma_print_he_ppet(&peer->peer_ppet);
+
+	return;
+}
+
+void wma_update_vdev_he_ops(struct wma_vdev_start_req *req,
+		tpAddBssParams add_bss)
+{
+	uint32_t he_ops = 0;
+	tDot11fIEhe_op *he_op = &add_bss->he_op;
+
+	req->he_capable = add_bss->he_capable;
+
+	WMI_HEOPS_COLOR_SET(he_ops, he_op->bss_color);
+	WMI_HEOPS_DEFPE_SET(he_ops, he_op->default_pe);
+	WMI_HEOPS_TWT_SET(he_ops, he_op->twt_required);
+	WMI_HEOPS_RTSTHLD_SET(he_ops, he_op->txop_rts_threshold);
+	WMI_HEOPS_PARTBSSCOLOR_SET(he_ops, he_op->partial_bss_col);
+	WMI_HEOPS_BSSCOLORDISABLE_SET(he_ops, he_op->bss_col_disabled);
+
+	req->he_ops = he_ops;
+}
+
+void wma_copy_txrxnode_he_ops(struct wma_txrx_node *node,
+		struct wma_vdev_start_req *req)
+{
+	node->he_capable = req->he_capable;
+	node->he_ops = req->he_ops;
+}
+
+void wma_copy_vdev_start_he_ops(struct vdev_start_params *params,
+		struct wma_vdev_start_req *req)
+{
+	params->he_ops = req->he_ops;
+}
+
+void wma_vdev_set_he_bss_params(tp_wma_handle wma, uint8_t vdev_id,
+				struct wma_vdev_start_req *req)
+{
+	QDF_STATUS ret;
+	struct wma_txrx_node *intr = wma->interfaces;
+
+	if (!req->he_capable)
+		return;
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_HEOPS_0_31, req->he_ops);
+
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE(FL("Failed to set HE OPs"));
+	else
+		intr[vdev_id].he_ops = req->he_ops;
+}
+
+void wma_vdev_set_he_config(tp_wma_handle wma, uint8_t vdev_id,
+				tpAddBssParams add_bss)
+{
+	QDF_STATUS ret;
+	int8_t pd_min, pd_max, sec_ch_ed, tx_pwr;
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+				 WMI_VDEV_PARAM_OBSSPD, add_bss->he_sta_obsspd);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE(FL("Failed to set HE Config"));
+	pd_min = add_bss->he_sta_obsspd & 0xff,
+	pd_max = (add_bss->he_sta_obsspd & 0xff00) >> 8,
+	sec_ch_ed = (add_bss->he_sta_obsspd & 0xff0000) >> 16,
+	tx_pwr = (add_bss->he_sta_obsspd & 0xff000000) >> 24;
+	WMA_LOGD(FL("HE_STA_OBSSPD: PD_MIN: %d PD_MAX: %d SEC_CH_ED: %d TX_PWR: %d"),
+		 pd_min, pd_max, sec_ch_ed, tx_pwr);
+}
+
+void wma_update_vdev_he_capable(struct wma_vdev_start_req *req,
+		tpSwitchChannelParams params)
+{
+	req->he_capable = params->he_capable;
+}
+
+QDF_STATUS wma_update_he_ops_ie(tp_wma_handle wma, uint8_t vdev_id,
+				tDot11fIEhe_op *he_op)
+{
+	QDF_STATUS ret;
+	uint32_t dword_he_op = 0;
+
+	if (!wma) {
+		WMA_LOGE(FL("wrong wma_handle...."));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMI_HEOPS_COLOR_SET(dword_he_op, he_op->bss_color);
+	WMI_HEOPS_DEFPE_SET(dword_he_op, he_op->default_pe);
+	WMI_HEOPS_TWT_SET(dword_he_op, he_op->twt_required);
+	WMI_HEOPS_RTSTHLD_SET(dword_he_op, he_op->txop_rts_threshold);
+	WMI_HEOPS_PARTBSSCOLOR_SET(dword_he_op, he_op->partial_bss_col);
+	WMI_HEOPS_BSSCOLORDISABLE_SET(dword_he_op, he_op->bss_col_disabled);
+
+	WMA_LOGD("vdev_id: %d HE_OPs: 0x%x", vdev_id, dword_he_op);
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_HEOPS_0_31, dword_he_op);
+
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE(FL("Failed to set HE OPs"));
+
+	return ret;
+}
+
+QDF_STATUS wma_get_he_capabilities(struct he_capability *he_cap)
+{
+	tp_wma_handle wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		WMA_LOGE(FL("Invalid WMA handle"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_copy(he_cap->phy_cap,
+		     &wma_handle->he_cap.phy_cap,
+		     WMI_MAX_HECAP_PHY_SIZE);
+	he_cap->mac_cap = wma_handle->he_cap.mac_cap;
+	he_cap->mcs = wma_handle->he_cap.mcs;
+
+	he_cap->ppet.numss_m1 = wma_handle->he_cap.ppet.numss_m1;
+	he_cap->ppet.ru_bit_mask = wma_handle->he_cap.ppet.ru_bit_mask;
+	qdf_mem_copy(&he_cap->ppet.ppet16_ppet8_ru3_ru0,
+		     &wma_handle->he_cap.ppet.ppet16_ppet8_ru3_ru0,
+		     WMI_MAX_NUM_SS);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wma_set_he_vdev_param(struct wma_txrx_node *intr, WMI_VDEV_PARAM param_id,
+			   uint32_t value)
+{
+	switch (param_id) {
+	case WMI_VDEV_PARAM_HE_DCM:
+		intr->config.dcm = value;
+		break;
+	case WMI_VDEV_PARAM_HE_RANGE_EXT:
+		intr->config.range_ext = value;
+		break;
+	default:
+		WMA_LOGE(FL("Unhandled HE vdev param: %0x"), param_id);
+		break;
+	}
+}
+
+uint32_t wma_get_he_vdev_param(struct wma_txrx_node *intr,
+			       WMI_VDEV_PARAM param_id)
+{
+	switch (param_id) {
+	case WMI_VDEV_PARAM_HE_DCM:
+		return intr->config.dcm;
+	case WMI_VDEV_PARAM_HE_RANGE_EXT:
+		return intr->config.range_ext;
+	default:
+		WMA_LOGE(FL("Unhandled HE vdev param: %0x"), param_id);
+		break;
+	}
+	return 0;
+}
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
new file mode 100644
index 0000000..086a6ce
--- /dev/null
+++ b/core/wma/src/wma_main.c
@@ -0,0 +1,9011 @@
+/*
+ * Copyright (c) 2013-2018 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:  wma_main.c
+ *
+ *  This file contains wma initialization and FW exchange
+ *  related functions.
+ */
+
+/* Header files */
+
+#include "wma.h"
+#include "wma_api.h"
+#include "cds_api.h"
+#include "wmi_unified_api.h"
+#include "wlan_qct_sys.h"
+#include "wni_api.h"
+#include "ani_global.h"
+#include "wmi_unified.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#if defined(CONFIG_HL_SUPPORT)
+#include "wlan_tgt_def_config_hl.h"
+#else
+#include "wlan_tgt_def_config.h"
+#endif
+#include "qdf_nbuf.h"
+#include "qdf_types.h"
+#include "qdf_mem.h"
+#include "wma_types.h"
+#include "lim_api.h"
+#include "lim_session_utils.h"
+
+#include "cds_utils.h"
+
+#if !defined(REMOVE_PKT_LOG)
+#include "pktlog_ac.h"
+#endif /* REMOVE_PKT_LOG */
+
+#include "dbglog_host.h"
+#include "csr_api.h"
+#include "ol_fw.h"
+
+#include "wma_internal.h"
+
+#include "wma_ocb.h"
+#include "wlan_policy_mgr_api.h"
+#include "cdp_txrx_cfg.h"
+#include "cdp_txrx_flow_ctrl_legacy.h"
+#include "cdp_txrx_flow_ctrl_v2.h"
+#include "cdp_txrx_ipa.h"
+#include "cdp_txrx_misc.h"
+#include "wma_fips_api.h"
+#include "wma_nan_datapath.h"
+#include "wlan_lmac_if_def.h"
+#include "wlan_lmac_if_api.h"
+#include "target_if.h"
+#include "wlan_global_lmac_if_api.h"
+#include "target_if_pmo.h"
+#include "wma_he.h"
+#include "wlan_pmo_obj_mgmt_api.h"
+
+#include "wlan_reg_tgt_api.h"
+#include "wlan_reg_services_api.h"
+#include <cdp_txrx_handle.h>
+#include <wlan_pmo_ucfg_api.h>
+#include "wifi_pos_api.h"
+#include "hif_main.h"
+#include <target_if_spectral.h>
+#include <wlan_spectral_utils_api.h>
+#include "init_event_handler.h"
+#include "init_deinit_lmac.h"
+#include "target_if_green_ap.h"
+#include "service_ready_param.h"
+#include "wlan_cp_stats_mc_ucfg_api.h"
+#include "cfg_nan_api.h"
+#include "wlan_mlme_api.h"
+
+#define WMA_LOG_COMPLETION_TIMER 3000 /* 3 seconds */
+#define WMI_TLV_HEADROOM 128
+
+#define WMA_FW_TIME_SYNC_TIMER 60000 /* 1 min */
+
+uint8_t *mac_trace_get_wma_msg_string(uint16_t wmaMsg);
+static uint32_t g_fw_wlan_feat_caps;
+/**
+ * wma_get_fw_wlan_feat_caps() - get fw feature capablity
+ * @feature: feature enum value
+ *
+ * Return: true/false
+ */
+bool wma_get_fw_wlan_feat_caps(enum cap_bitmap feature)
+{
+	return (g_fw_wlan_feat_caps & (1 << feature)) ? true : false;
+}
+
+/**
+ * wma_set_fw_wlan_feat_caps() - set fw feature capablity
+ * @feature: feature enum value
+ *
+ * Return: None
+ */
+void wma_set_fw_wlan_feat_caps(enum cap_bitmap feature)
+{
+	g_fw_wlan_feat_caps |= (1 << feature);
+}
+
+/**
+ * wma_service_ready_ext_evt_timeout() - Service ready extended event timeout
+ * @data: Timeout handler data
+ *
+ * This function is called when the FW fails to send WMI_SERVICE_READY_EXT_EVENT
+ * message
+ *
+ * Return: None
+ */
+static void wma_service_ready_ext_evt_timeout(void *data)
+{
+	tp_wma_handle wma_handle;
+
+	WMA_LOGA("%s: Timeout waiting for WMI_SERVICE_READY_EXT_EVENT",
+			__func__);
+
+	wma_handle = (tp_wma_handle) data;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+		goto end;
+	}
+
+end:
+	/* Assert here. Panic is being called in insmod thread */
+	QDF_ASSERT(0);
+}
+
+/**
+ * wma_get_ini_handle() - API to get WMA ini info handle
+ * @wma: WMA Handle
+ *
+ * Returns the pointer to WMA ini structure.
+ * Return: struct wma_ini_config
+ */
+struct wma_ini_config *wma_get_ini_handle(tp_wma_handle wma)
+{
+	if (!wma) {
+		WMA_LOGE("%s: Invalid WMA context\n", __func__);
+		return NULL;
+	}
+
+	return &wma->ini_config;
+}
+
+#define MAX_SUPPORTED_PEERS_REV1_1 14
+#define MAX_SUPPORTED_PEERS_REV1_3 32
+#define MIN_NO_OF_PEERS 1
+
+/**
+ * wma_get_number_of_peers_supported - API to query for number of peers
+ * supported
+ * @wma: WMA Handle
+ *
+ * Return: Max Number of Peers Supported
+ */
+static uint8_t wma_get_number_of_peers_supported(tp_wma_handle wma)
+{
+	struct wma_ini_config *cfg = wma_get_ini_handle(wma);
+	uint8_t max_no_of_peers = cfg ? cfg->max_no_of_peers : MIN_NO_OF_PEERS;
+
+	return max_no_of_peers;
+}
+
+/**
+ * wma_get_number_of_tids_supported - API to query for number of tids supported
+ * @no_of_peers_supported: Number of peer supported
+ *
+ * Return: Max number of tids supported
+ */
+#if defined(CONFIG_HL_SUPPORT)
+static uint32_t wma_get_number_of_tids_supported(uint8_t no_of_peers_supported,
+						 uint8_t num_vdevs)
+{
+	return 4 * no_of_peers_supported;
+}
+#else
+static uint32_t wma_get_number_of_tids_supported(uint8_t no_of_peers_supported,
+						 uint8_t num_vdevs)
+{
+	return 2 * (no_of_peers_supported + num_vdevs + 2);
+}
+#endif
+
+#ifdef PERE_IP_HDR_ALIGNMENT_WAR
+static void wma_reset_rx_decap_mode(target_resource_config *tgt_cfg)
+{
+	/*
+	 * To make the IP header begins at dword aligned address,
+	 * we make the decapsulation mode as Native Wifi.
+	 */
+	tgt_cfg->rx_decap_mode = CFG_TGT_RX_DECAP_MODE_NWIFI;
+}
+#else
+static void wma_reset_rx_decap_mode(target_resource_config *tgt_cfg)
+{
+}
+
+#endif
+
+#ifndef NUM_OF_ADDITIONAL_FW_PEERS
+#define NUM_OF_ADDITIONAL_FW_PEERS	2
+#endif
+/**
+ * wma_set_default_tgt_config() - set default tgt config
+ * @wma_handle: wma handle
+ * @tgt_cfg: Resource config given to target
+ *
+ * Return: none
+ */
+static void wma_set_default_tgt_config(tp_wma_handle wma_handle,
+				       target_resource_config *tgt_cfg,
+				       struct cds_config_info *cds_cfg)
+{
+	uint8_t no_of_peers_supported;
+
+	no_of_peers_supported = wma_get_number_of_peers_supported(wma_handle);
+
+	qdf_mem_zero(tgt_cfg, sizeof(target_resource_config));
+	tgt_cfg->num_vdevs = cds_cfg->num_vdevs;
+	tgt_cfg->num_peers = no_of_peers_supported +
+				cds_cfg->num_vdevs +
+				NUM_OF_ADDITIONAL_FW_PEERS;
+	/* The current firmware implementation requires the number of
+	 * offload peers should be (number of vdevs + 1).
+	 */
+	tgt_cfg->num_offload_peers = cds_cfg->ap_maxoffload_peers + 1;
+	tgt_cfg->num_offload_reorder_buffs =
+				cds_cfg->ap_maxoffload_reorderbuffs + 1;
+	tgt_cfg->num_peer_keys = CFG_TGT_NUM_PEER_KEYS;
+	tgt_cfg->num_tids = wma_get_number_of_tids_supported(
+				no_of_peers_supported, cds_cfg->num_vdevs);
+	tgt_cfg->ast_skid_limit = CFG_TGT_AST_SKID_LIMIT;
+	tgt_cfg->tx_chain_mask = CFG_TGT_DEFAULT_TX_CHAIN_MASK;
+	tgt_cfg->rx_chain_mask = CFG_TGT_DEFAULT_RX_CHAIN_MASK;
+	tgt_cfg->rx_timeout_pri[0] = CFG_TGT_RX_TIMEOUT_LO_PRI;
+	tgt_cfg->rx_timeout_pri[1] = CFG_TGT_RX_TIMEOUT_LO_PRI;
+	tgt_cfg->rx_timeout_pri[2] = CFG_TGT_RX_TIMEOUT_LO_PRI;
+	tgt_cfg->rx_timeout_pri[3] = CFG_TGT_RX_TIMEOUT_HI_PRI;
+	tgt_cfg->rx_decap_mode = CFG_TGT_RX_DECAP_MODE;
+	tgt_cfg->scan_max_pending_req = wma_handle->max_scan;
+	tgt_cfg->bmiss_offload_max_vdev =
+			CFG_TGT_DEFAULT_BMISS_OFFLOAD_MAX_VDEV;
+	tgt_cfg->roam_offload_max_vdev = CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_VDEV;
+	tgt_cfg->roam_offload_max_ap_profiles =
+		CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_PROFILES;
+	tgt_cfg->num_mcast_groups = CFG_TGT_DEFAULT_NUM_MCAST_GROUPS;
+	tgt_cfg->num_mcast_table_elems = CFG_TGT_DEFAULT_NUM_MCAST_TABLE_ELEMS;
+	tgt_cfg->mcast2ucast_mode = CFG_TGT_DEFAULT_MCAST2UCAST_MODE;
+	tgt_cfg->tx_dbg_log_size = CFG_TGT_DEFAULT_TX_DBG_LOG_SIZE;
+	tgt_cfg->num_wds_entries = CFG_TGT_WDS_ENTRIES;
+	tgt_cfg->dma_burst_size = CFG_TGT_DEFAULT_DMA_BURST_SIZE;
+	tgt_cfg->mac_aggr_delim = CFG_TGT_DEFAULT_MAC_AGGR_DELIM;
+	tgt_cfg->rx_skip_defrag_timeout_dup_detection_check =
+		CFG_TGT_DEFAULT_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK,
+	tgt_cfg->vow_config = CFG_TGT_DEFAULT_VOW_CONFIG;
+	tgt_cfg->gtk_offload_max_vdev = CFG_TGT_DEFAULT_GTK_OFFLOAD_MAX_VDEV;
+	tgt_cfg->num_msdu_desc = CFG_TGT_NUM_MSDU_DESC;
+	tgt_cfg->max_frag_entries = CFG_TGT_MAX_FRAG_TABLE_ENTRIES;
+	tgt_cfg->num_tdls_vdevs = CFG_TGT_NUM_TDLS_VDEVS;
+	tgt_cfg->num_tdls_conn_table_entries =
+		CFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES;
+	tgt_cfg->beacon_tx_offload_max_vdev =
+		CFG_TGT_DEFAULT_BEACON_TX_OFFLOAD_MAX_VDEV;
+	tgt_cfg->num_multicast_filter_entries =
+		CFG_TGT_MAX_MULTICAST_FILTER_ENTRIES;
+	tgt_cfg->num_wow_filters = 0;
+	tgt_cfg->num_keep_alive_pattern = WMA_MAXNUM_PERIODIC_TX_PTRNS;
+	tgt_cfg->num_max_sta_vdevs = CFG_TGT_DEFAULT_MAX_STA_VDEVS;
+	tgt_cfg->keep_alive_pattern_size = 0;
+	tgt_cfg->max_tdls_concurrent_sleep_sta =
+		CFG_TGT_NUM_TDLS_CONC_SLEEP_STAS;
+	tgt_cfg->max_tdls_concurrent_buffer_sta =
+		CFG_TGT_NUM_TDLS_CONC_BUFFER_STAS;
+	tgt_cfg->wmi_send_separate = 0;
+	tgt_cfg->num_ocb_vdevs = CFG_TGT_NUM_OCB_VDEVS;
+	tgt_cfg->num_ocb_channels = CFG_TGT_NUM_OCB_CHANNELS;
+	tgt_cfg->num_ocb_schedules = CFG_TGT_NUM_OCB_SCHEDULES;
+
+
+	tgt_cfg->mgmt_comp_evt_bundle_support = true;
+	tgt_cfg->tx_msdu_new_partition_id_support = true;
+
+	/* reduce the peer/vdev if CFG_TGT_NUM_MSDU_DESC exceeds 1000 */
+	wma_reset_rx_decap_mode(tgt_cfg);
+
+	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
+		tgt_cfg->rx_decap_mode = CFG_TGT_RX_DECAP_MODE_RAW;
+}
+
+/**
+ * wma_cli_get_command() - WMA "get" command processor
+ * @vdev_id: virtual device for the command
+ * @param_id: parameter id
+ * @vpdev: parameter category
+ *
+ * Return: parameter value on success, -EINVAL on failure
+ */
+int wma_cli_get_command(int vdev_id, int param_id, int vpdev)
+{
+	int ret = 0;
+	tp_wma_handle wma;
+	struct wma_txrx_node *intr = NULL;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: Invalid wma handle", __func__);
+		return -EINVAL;
+	}
+
+	intr = wma->interfaces;
+
+	if (VDEV_CMD == vpdev) {
+		switch (param_id) {
+		case WMI_VDEV_PARAM_NSS:
+			ret = intr[vdev_id].config.nss;
+			break;
+#ifdef QCA_SUPPORT_GTX
+		case WMI_VDEV_PARAM_GTX_HT_MCS:
+			ret = intr[vdev_id].config.gtx_info.gtxRTMask[0];
+			break;
+		case WMI_VDEV_PARAM_GTX_VHT_MCS:
+			ret = intr[vdev_id].config.gtx_info.gtxRTMask[1];
+			break;
+		case WMI_VDEV_PARAM_GTX_USR_CFG:
+			ret = intr[vdev_id].config.gtx_info.gtxUsrcfg;
+			break;
+		case WMI_VDEV_PARAM_GTX_THRE:
+			ret = intr[vdev_id].config.gtx_info.gtxPERThreshold;
+			break;
+		case WMI_VDEV_PARAM_GTX_MARGIN:
+			ret = intr[vdev_id].config.gtx_info.gtxPERMargin;
+			break;
+		case WMI_VDEV_PARAM_GTX_STEP:
+			ret = intr[vdev_id].config.gtx_info.gtxTPCstep;
+			break;
+		case WMI_VDEV_PARAM_GTX_MINTPC:
+			ret = intr[vdev_id].config.gtx_info.gtxTPCMin;
+			break;
+		case WMI_VDEV_PARAM_GTX_BW_MASK:
+			ret = intr[vdev_id].config.gtx_info.gtxBWMask;
+			break;
+#endif /* QCA_SUPPORT_GTX */
+		case WMI_VDEV_PARAM_LDPC:
+			ret = intr[vdev_id].config.ldpc;
+			break;
+		case WMI_VDEV_PARAM_TX_STBC:
+			ret = intr[vdev_id].config.tx_stbc;
+			break;
+		case WMI_VDEV_PARAM_RX_STBC:
+			ret = intr[vdev_id].config.rx_stbc;
+			break;
+		case WMI_VDEV_PARAM_SGI:
+			ret = intr[vdev_id].config.shortgi;
+			break;
+		case WMI_VDEV_PARAM_ENABLE_RTSCTS:
+			ret = intr[vdev_id].config.rtscts_en;
+			break;
+		case WMI_VDEV_PARAM_CHWIDTH:
+			ret = intr[vdev_id].config.chwidth;
+			break;
+		case WMI_VDEV_PARAM_FIXED_RATE:
+			ret = intr[vdev_id].config.tx_rate;
+			break;
+		case WMI_VDEV_PARAM_HE_DCM:
+		case WMI_VDEV_PARAM_HE_RANGE_EXT:
+			ret = wma_get_he_vdev_param(&intr[vdev_id], param_id);
+			break;
+		default:
+			WMA_LOGE("Invalid cli_get vdev command/Not yet implemented 0x%x",
+				 param_id);
+			return -EINVAL;
+		}
+	} else if (PDEV_CMD == vpdev) {
+		switch (param_id) {
+		case WMI_PDEV_PARAM_ANI_ENABLE:
+			ret = wma->pdevconfig.ani_enable;
+			break;
+		case WMI_PDEV_PARAM_ANI_POLL_PERIOD:
+			ret = wma->pdevconfig.ani_poll_len;
+			break;
+		case WMI_PDEV_PARAM_ANI_LISTEN_PERIOD:
+			ret = wma->pdevconfig.ani_listen_len;
+			break;
+		case WMI_PDEV_PARAM_ANI_OFDM_LEVEL:
+			ret = wma->pdevconfig.ani_ofdm_level;
+			break;
+		case WMI_PDEV_PARAM_ANI_CCK_LEVEL:
+			ret = wma->pdevconfig.ani_cck_level;
+			break;
+		case WMI_PDEV_PARAM_DYNAMIC_BW:
+			ret = wma->pdevconfig.cwmenable;
+			break;
+		case WMI_PDEV_PARAM_CTS_CBW:
+			ret = wma->pdevconfig.cts_cbw;
+			break;
+		case WMI_PDEV_PARAM_TX_CHAIN_MASK:
+			ret = wma->pdevconfig.txchainmask;
+			break;
+		case WMI_PDEV_PARAM_RX_CHAIN_MASK:
+			ret = wma->pdevconfig.rxchainmask;
+			break;
+		case WMI_PDEV_PARAM_TXPOWER_LIMIT2G:
+			ret = wma->pdevconfig.txpow2g;
+			break;
+		case WMI_PDEV_PARAM_TXPOWER_LIMIT5G:
+			ret = wma->pdevconfig.txpow5g;
+			break;
+		default:
+			WMA_LOGE("Invalid cli_get pdev command/Not yet implemented 0x%x",
+				 param_id);
+			return -EINVAL;
+		}
+	} else if (GEN_CMD == vpdev) {
+		switch (param_id) {
+		case GEN_VDEV_PARAM_AMPDU:
+			ret = intr[vdev_id].config.ampdu;
+			break;
+		case GEN_VDEV_PARAM_AMSDU:
+			ret = intr[vdev_id].config.amsdu;
+			break;
+		case GEN_VDEV_ROAM_SYNCH_DELAY:
+			ret = intr[vdev_id].roam_synch_delay;
+			break;
+		default:
+			WMA_LOGE("Invalid generic vdev command/Not yet implemented 0x%x",
+				 param_id);
+			return -EINVAL;
+		}
+	} else if (PPS_CMD == vpdev) {
+		switch (param_id) {
+		case WMI_VDEV_PPS_PAID_MATCH:
+			ret = intr[vdev_id].config.pps_params.paid_match_enable;
+			break;
+		case WMI_VDEV_PPS_GID_MATCH:
+			ret = intr[vdev_id].config.pps_params.gid_match_enable;
+			break;
+		case WMI_VDEV_PPS_EARLY_TIM_CLEAR:
+			ret = intr[vdev_id].config.pps_params.tim_clear;
+			break;
+		case WMI_VDEV_PPS_EARLY_DTIM_CLEAR:
+			ret = intr[vdev_id].config.pps_params.dtim_clear;
+			break;
+		case WMI_VDEV_PPS_EOF_PAD_DELIM:
+			ret = intr[vdev_id].config.pps_params.eof_delim;
+			break;
+		case WMI_VDEV_PPS_MACADDR_MISMATCH:
+			ret = intr[vdev_id].config.pps_params.mac_match;
+			break;
+		case WMI_VDEV_PPS_DELIM_CRC_FAIL:
+			ret = intr[vdev_id].config.pps_params.delim_fail;
+			break;
+		case WMI_VDEV_PPS_GID_NSTS_ZERO:
+			ret = intr[vdev_id].config.pps_params.nsts_zero;
+			break;
+		case WMI_VDEV_PPS_RSSI_CHECK:
+			ret = intr[vdev_id].config.pps_params.rssi_chk;
+			break;
+		default:
+			WMA_LOGE("Invalid pps vdev command/Not yet implemented 0x%x",
+				 param_id);
+			return -EINVAL;
+		}
+	} else if (QPOWER_CMD == vpdev) {
+		switch (param_id) {
+		case WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT:
+			ret = intr[vdev_id].config.qpower_params.
+			      max_ps_poll_cnt;
+			break;
+		case WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE:
+			ret = intr[vdev_id].config.qpower_params.
+			      max_tx_before_wake;
+			break;
+		case WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
+			ret = intr[vdev_id].config.qpower_params.
+			      spec_ps_poll_wake_interval;
+			break;
+		case WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
+			ret = intr[vdev_id].config.qpower_params.
+			      max_spec_nodata_ps_poll;
+			break;
+		default:
+			WMA_LOGE("Invalid generic vdev command/Not yet implemented 0x%x",
+				 param_id);
+			return -EINVAL;
+		}
+	} else if (GTX_CMD == vpdev) {
+		switch (param_id) {
+		case WMI_VDEV_PARAM_GTX_HT_MCS:
+			ret = intr[vdev_id].config.gtx_info.gtxRTMask[0];
+			break;
+		case WMI_VDEV_PARAM_GTX_VHT_MCS:
+			ret = intr[vdev_id].config.gtx_info.gtxRTMask[1];
+			break;
+		case WMI_VDEV_PARAM_GTX_USR_CFG:
+			ret = intr[vdev_id].config.gtx_info.gtxUsrcfg;
+			break;
+		case WMI_VDEV_PARAM_GTX_THRE:
+			ret = intr[vdev_id].config.gtx_info.gtxPERThreshold;
+			break;
+		case WMI_VDEV_PARAM_GTX_MARGIN:
+			ret = intr[vdev_id].config.gtx_info.gtxPERMargin;
+			break;
+		case WMI_VDEV_PARAM_GTX_STEP:
+			ret = intr[vdev_id].config.gtx_info.gtxTPCstep;
+			break;
+		case WMI_VDEV_PARAM_GTX_MINTPC:
+			ret = intr[vdev_id].config.gtx_info.gtxTPCMin;
+			break;
+		case WMI_VDEV_PARAM_GTX_BW_MASK:
+			ret = intr[vdev_id].config.gtx_info.gtxBWMask;
+			break;
+		default:
+			WMA_LOGE("Invalid generic vdev command/Not yet implemented 0x%x",
+				 param_id);
+			return -EINVAL;
+		}
+	}
+	return ret;
+}
+
+/**
+ * wma_cli_set2_command() - WMA "set 2 params" command processor
+ * @vdev_id: virtual device for the command
+ * @param_id: parameter id
+ * @sval1: first parameter value
+ * @sval2: second parameter value
+ * @vpdev: parameter category
+ *
+ * Command handler for set operations which require 2 parameters
+ *
+ * Return: 0 on success, errno on failure
+ */
+int wma_cli_set2_command(int vdev_id, int param_id, int sval1,
+			 int sval2, int vpdev)
+{
+	struct scheduler_msg msg = { 0 };
+	wma_cli_set_cmd_t *iwcmd;
+
+	iwcmd = qdf_mem_malloc(sizeof(*iwcmd));
+	if (!iwcmd)
+		return -ENOMEM;
+
+	qdf_mem_zero(iwcmd, sizeof(*iwcmd));
+	iwcmd->param_value = sval1;
+	iwcmd->param_sec_value = sval2;
+	iwcmd->param_vdev_id = vdev_id;
+	iwcmd->param_id = param_id;
+	iwcmd->param_vp_dev = vpdev;
+	msg.type = WMA_CLI_SET_CMD;
+	msg.reserved = 0;
+	msg.bodyptr = iwcmd;
+
+	if (QDF_STATUS_SUCCESS !=
+	    scheduler_post_message(QDF_MODULE_ID_WMA,
+				   QDF_MODULE_ID_WMA,
+				   QDF_MODULE_ID_WMA, &msg)) {
+		WMA_LOGE("%s: Failed to post WMA_CLI_SET_CMD msg",
+			  __func__);
+		qdf_mem_free(iwcmd);
+		return -EIO;
+	}
+	return 0;
+}
+
+/**
+ * wma_cli_set_command() - WMA "set" command processor
+ * @vdev_id: virtual device for the command
+ * @param_id: parameter id
+ * @sval: parameter value
+ * @vpdev: parameter category
+ *
+ * Command handler for set operations
+ *
+ * Return: 0 on success, errno on failure
+ */
+int wma_cli_set_command(int vdev_id, int param_id, int sval, int vpdev)
+{
+	return wma_cli_set2_command(vdev_id, param_id, sval, 0, vpdev);
+
+}
+
+QDF_STATUS wma_form_unit_test_cmd_and_send(uint32_t vdev_id,
+			uint32_t module_id, uint32_t arg_count, uint32_t *arg)
+{
+	struct wmi_unit_test_cmd *unit_test_args;
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	uint32_t i;
+	QDF_STATUS status;
+
+	WMA_LOGD(FL("enter"));
+	if (arg_count >= WMA_MAX_NUM_ARGS) {
+		WMA_LOGE(FL("arg_count is crossed the boundary"));
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE(FL("Invalid WMA/WMI handle"));
+		return QDF_STATUS_E_FAILURE;
+	}
+	unit_test_args = qdf_mem_malloc(sizeof(*unit_test_args));
+	if (!unit_test_args)
+		return QDF_STATUS_E_NOMEM;
+
+	unit_test_args->vdev_id = vdev_id;
+	unit_test_args->module_id = module_id;
+	unit_test_args->num_args = arg_count;
+	for (i = 0; i < arg_count; i++)
+		unit_test_args->args[i] = arg[i];
+
+	status = wmi_unified_unit_test_cmd(wma_handle->wmi_handle,
+					   unit_test_args);
+	qdf_mem_free(unit_test_args);
+	WMA_LOGD(FL("exit"));
+
+	return status;
+}
+
+static void wma_process_send_addba_req(tp_wma_handle wma_handle,
+		struct send_add_ba_req *send_addba)
+{
+	QDF_STATUS status;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE(FL("Invalid WMA/WMI handle"));
+		qdf_mem_free(send_addba);
+		return;
+	}
+
+	status = wmi_unified_addba_send_cmd_send(wma_handle->wmi_handle,
+					   send_addba->mac_addr,
+					   &send_addba->param);
+	if (QDF_STATUS_SUCCESS != status) {
+		WMA_LOGE(FL("Failed to process WMA_SEND_ADDBA_REQ"));
+	}
+	WMA_LOGD(FL("sent ADDBA req to" MAC_ADDRESS_STR "tid %d buff_size %d"),
+			MAC_ADDR_ARRAY(send_addba->mac_addr),
+			send_addba->param.tidno,
+			send_addba->param.buffersize);
+
+	qdf_mem_free(send_addba);
+}
+
+/**
+ * wma_ipa_get_stat() - get IPA data path stats from FW
+ *
+ * Return: 0 on success, errno on failure
+ */
+#ifdef IPA_OFFLOAD
+static int wma_ipa_get_stat(void)
+{
+	struct cdp_pdev *pdev;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE("pdev NULL for uc stat");
+		return -EINVAL;
+	}
+	cdp_ipa_get_stat(cds_get_context(QDF_MODULE_ID_SOC), pdev);
+
+	return 0;
+}
+#else
+static int wma_ipa_get_stat(void)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wma_ipa_uc_get_share_stats() - get Tx/Rx byte stats from FW
+ * @privcmd: private command
+ *
+ * Return: 0 on success, errno on failure
+ */
+#if defined(IPA_OFFLOAD) && defined(FEATURE_METERING)
+static int wma_ipa_uc_get_share_stats(wma_cli_set_cmd_t *privcmd)
+{
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct cdp_pdev *pdev;
+	uint8_t reset_stats = privcmd->param_value;
+
+	WMA_LOGD("%s: reset_stats=%d",
+			"WMA_VDEV_TXRX_GET_IPA_UC_SHARING_STATS_CMDID",
+			reset_stats);
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE("pdev NULL for uc get share stats");
+		return -EINVAL;
+	}
+	cdp_ipa_uc_get_share_stats(soc, pdev, reset_stats);
+
+	return 0;
+}
+#else
+static int wma_ipa_uc_get_share_stats(wma_cli_set_cmd_t *privcmd)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wma_ipa_uc_set_quota() - set quota limit to FW
+ * @privcmd: private command
+ *
+ * Return: 0 on success, errno on failure
+ */
+#if defined(IPA_OFFLOAD) && defined(FEATURE_METERING)
+static int wma_ipa_uc_set_quota(wma_cli_set_cmd_t *privcmd)
+{
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct cdp_pdev *pdev;
+	uint64_t quota_bytes = privcmd->param_sec_value;
+
+	quota_bytes <<= 32;
+	quota_bytes |= privcmd->param_value;
+
+	WMA_LOGD("%s: quota_bytes=%llu",
+			"WMA_VDEV_TXRX_SET_IPA_UC_QUOTA_CMDID",
+			quota_bytes);
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE("pdev NULL for uc set quota");
+		return -EINVAL;
+	}
+	cdp_ipa_uc_set_quota(soc, pdev, quota_bytes);
+
+	return 0;
+}
+#else
+static int wma_ipa_uc_set_quota(wma_cli_set_cmd_t *privcmd)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wma_set_priv_cfg() - set private config parameters
+ * @wma_handle: wma handle
+ * @privcmd: private command
+ *
+ * Return: 0 for success or error code
+ */
+static int32_t wma_set_priv_cfg(tp_wma_handle wma_handle,
+				wma_cli_set_cmd_t *privcmd)
+{
+	int32_t ret = 0;
+
+	switch (privcmd->param_id) {
+	case WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID:
+		ret = wma_set_txrx_fw_stats_level(wma_handle,
+						  privcmd->param_vdev_id,
+						  privcmd->param_value);
+		break;
+	case WMA_VDEV_TXRX_FWSTATS_RESET_CMDID:
+		ret = wma_txrx_fw_stats_reset(wma_handle,
+					      privcmd->param_vdev_id,
+					      privcmd->param_value);
+		break;
+	case WMI_STA_SMPS_FORCE_MODE_CMDID:
+		ret = wma_set_mimops(wma_handle,
+				     privcmd->param_vdev_id,
+				     privcmd->param_value);
+		break;
+	case WMI_STA_SMPS_PARAM_CMDID:
+		wma_set_smps_params(wma_handle, privcmd->param_vdev_id,
+				    privcmd->param_value);
+		break;
+	case WMA_VDEV_MCC_SET_TIME_LATENCY:
+	{
+		/* Extract first MCC adapter/vdev channel number and latency */
+		uint8_t mcc_channel = privcmd->param_value & 0x000000FF;
+		uint8_t mcc_channel_latency =
+			(privcmd->param_value & 0x0000FF00) >> 8;
+		int ret = -1;
+
+		WMA_LOGD("%s: Parsed input: Channel #1:%d, latency:%dms",
+			__func__, mcc_channel, mcc_channel_latency);
+		ret = wma_set_mcc_channel_time_latency(wma_handle,
+						       mcc_channel,
+						       mcc_channel_latency);
+	}
+		break;
+	case WMA_VDEV_MCC_SET_TIME_QUOTA:
+	{
+		/* Extract the MCC 2 adapters/vdevs channel numbers and time
+		 * quota value for the first adapter only (which is specified
+		 * in iwpriv command.
+		 */
+		uint8_t adapter_2_chan_number =
+			privcmd->param_value & 0x000000FF;
+		uint8_t adapter_1_chan_number =
+			(privcmd->param_value & 0x0000FF00) >> 8;
+		uint8_t adapter_1_quota =
+			(privcmd->param_value & 0x00FF0000) >> 16;
+		int ret = -1;
+
+		WMA_LOGD("%s: Parsed input: Channel #1:%d, Channel #2:%d, quota 1:%dms",
+			  __func__, adapter_1_chan_number,
+			 adapter_2_chan_number, adapter_1_quota);
+
+		ret = wma_set_mcc_channel_time_quota(wma_handle,
+						     adapter_1_chan_number,
+						     adapter_1_quota,
+						     adapter_2_chan_number);
+	}
+		break;
+	case WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE:
+	{
+		wma_handle->wma_ibss_power_save_params.atimWindowLength =
+							privcmd->param_value;
+		WMA_LOGD("%s: IBSS power save ATIM Window = %d",
+			 __func__, wma_handle->wma_ibss_power_save_params.
+			 atimWindowLength);
+	}
+		break;
+	case WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED:
+	{
+		wma_handle->wma_ibss_power_save_params.isPowerSaveAllowed =
+							privcmd->param_value;
+		WMA_LOGD("%s: IBSS is Power Save Allowed = %d",
+			 __func__, wma_handle->wma_ibss_power_save_params.
+			 isPowerSaveAllowed);
+	}
+		break;
+	case WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED:
+	{
+		wma_handle->wma_ibss_power_save_params.	isPowerCollapseAllowed =
+							 privcmd->param_value;
+		WMA_LOGD("%s: IBSS is Power Collapse Allowed = %d",
+			 __func__, wma_handle->wma_ibss_power_save_params.
+			 isPowerCollapseAllowed);
+	}
+		break;
+	case WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX:
+	{
+		wma_handle->wma_ibss_power_save_params.isAwakeonTxRxEnabled =
+							 privcmd->param_value;
+		WMA_LOGD("%s: IBSS Power Save Awake on Tx/Rx Enabled = %d",
+			__func__, wma_handle->wma_ibss_power_save_params.
+			isAwakeonTxRxEnabled);
+	}
+		break;
+	case WMA_VDEV_IBSS_SET_INACTIVITY_TIME:
+	{
+		wma_handle->wma_ibss_power_save_params.inactivityCount =
+							privcmd->param_value;
+		WMA_LOGD("%s: IBSS Power Save Data Inactivity Count = %d",
+			__func__, wma_handle->wma_ibss_power_save_params.
+			inactivityCount);
+	}
+		break;
+	case WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME:
+	{
+		wma_handle->wma_ibss_power_save_params.txSPEndInactivityTime =
+							 privcmd->param_value;
+		WMA_LOGD("%s: IBSS Power Save Transmit EOSP inactivity time out = %d",
+			__func__, wma_handle->wma_ibss_power_save_params.
+			txSPEndInactivityTime);
+	}
+		break;
+	case WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS:
+	{
+		wma_handle->wma_ibss_power_save_params.ibssPsWarmupTime =
+							privcmd->param_value;
+		WMA_LOGD("%s: IBSS Power Save Warm Up Time in Seconds = %d",
+			__func__, wma_handle->wma_ibss_power_save_params.
+			ibssPsWarmupTime);
+	}
+		break;
+	case WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW:
+	{
+		wma_handle->wma_ibss_power_save_params.ibssPs1RxChainInAtimEnable
+							 = privcmd->param_value;
+		WMA_LOGD("%s: IBSS Power Save single RX Chain Enable In ATIM  = %d",
+			__func__, wma_handle->wma_ibss_power_save_params.
+			ibssPs1RxChainInAtimEnable);
+	}
+		break;
+
+	case WMA_VDEV_TXRX_GET_IPA_UC_FW_STATS_CMDID:
+	{
+		wma_ipa_get_stat();
+	}
+		break;
+
+	case WMA_VDEV_TXRX_GET_IPA_UC_SHARING_STATS_CMDID:
+	{
+		wma_ipa_uc_get_share_stats(privcmd);
+	}
+		break;
+
+	case WMA_VDEV_TXRX_SET_IPA_UC_QUOTA_CMDID:
+	{
+		wma_ipa_uc_set_quota(privcmd);
+
+	}
+		break;
+
+	default:
+		WMA_LOGE("Invalid wma config command id:%d", privcmd->param_id);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+/**
+ * wma_set_dtim_period() - set dtim period to FW
+ * @wma: wma handle
+ * @dtim_params: dtim params
+ *
+ * Return: none
+ */
+static void wma_set_dtim_period(tp_wma_handle wma,
+				struct set_dtim_params *dtim_params)
+{
+	struct wma_txrx_node *iface =
+		&wma->interfaces[dtim_params->session_id];
+	if (!wma_is_vdev_valid(dtim_params->session_id)) {
+		WMA_LOGE("%s: invalid VDEV", __func__);
+		return;
+	}
+	WMA_LOGD("%s: set dtim_period %d", __func__,
+			dtim_params->dtim_period);
+	iface->dtimPeriod = dtim_params->dtim_period;
+
+}
+
+/**
+ * wma_process_cli_set_cmd() - set parameters to fw
+ * @wma: wma handle
+ * @privcmd: command
+ *
+ * Return: none
+ */
+static void wma_process_cli_set_cmd(tp_wma_handle wma,
+				    wma_cli_set_cmd_t *privcmd)
+{
+	int vid = privcmd->param_vdev_id, pps_val = 0;
+	QDF_STATUS ret;
+	struct wma_txrx_node *intr = wma->interfaces;
+	tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
+	struct qpower_params *qparams = &intr[vid].config.qpower_params;
+	struct pdev_params pdev_param;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct target_psoc_info *tgt_hdl;
+	struct sir_set_tx_rx_aggregation_size aggr;
+
+	WMA_LOGD("wmihandle %pK", wma->wmi_handle);
+	qdf_mem_zero(&aggr, sizeof(aggr));
+
+	if (NULL == pMac) {
+		WMA_LOGE("%s: Failed to get pMac", __func__);
+		return;
+	}
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma->psoc);
+	if (!tgt_hdl) {
+		WMA_LOGE("%s: target psoc info is NULL", __func__);
+		return;
+	}
+
+	if (privcmd->param_id >= WMI_CMDID_MAX) {
+		/*
+		 * This configuration setting is not done using any wmi
+		 * command, call appropriate handler.
+		 */
+		if (wma_set_priv_cfg(wma, privcmd))
+			WMA_LOGE("Failed to set wma priv congiuration");
+		return;
+	}
+
+	switch (privcmd->param_vp_dev) {
+	case VDEV_CMD:
+		if (!wma_is_vdev_valid(privcmd->param_vdev_id)) {
+			WMA_LOGE("%s Vdev id is not valid", __func__);
+			return;
+		}
+
+		WMA_LOGD("vdev id %d pid %d pval %d", privcmd->param_vdev_id,
+			 privcmd->param_id, privcmd->param_value);
+		ret = wma_vdev_set_param(wma->wmi_handle,
+						      privcmd->param_vdev_id,
+						      privcmd->param_id,
+						      privcmd->param_value);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			WMA_LOGE("wma_vdev_set_param failed ret %d",
+				  ret);
+			return;
+		}
+		break;
+	case PDEV_CMD:
+		WMA_LOGD("pdev pid %d pval %d", privcmd->param_id,
+			 privcmd->param_value);
+		if ((privcmd->param_id == WMI_PDEV_PARAM_RX_CHAIN_MASK) ||
+		    (privcmd->param_id == WMI_PDEV_PARAM_TX_CHAIN_MASK)) {
+			if (QDF_STATUS_SUCCESS !=
+					wma_check_txrx_chainmask(
+					target_if_get_num_rf_chains(tgt_hdl),
+					privcmd->param_value)) {
+				WMA_LOGD("Chainmask value is invalid");
+				return;
+			}
+		}
+		pdev_param.param_id = privcmd->param_id;
+		pdev_param.param_value = privcmd->param_value;
+		ret = wmi_unified_pdev_param_send(wma->wmi_handle,
+						 &pdev_param,
+						 WMA_WILDCARD_PDEV_ID);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			WMA_LOGE("wma_vdev_set_param failed ret %d",
+				 ret);
+			return;
+		}
+		break;
+	case GEN_CMD:
+	{
+		struct cdp_vdev *vdev = NULL;
+		struct wma_txrx_node *intr = wma->interfaces;
+
+		vdev = wma_find_vdev_by_id(wma, privcmd->param_vdev_id);
+		if (!vdev) {
+			WMA_LOGE("%s:Invalid vdev handle", __func__);
+			return;
+		}
+
+		WMA_LOGD("gen pid %d pval %d", privcmd->param_id,
+			 privcmd->param_value);
+
+		switch (privcmd->param_id) {
+		case GEN_VDEV_PARAM_AMSDU:
+		case GEN_VDEV_PARAM_AMPDU:
+			if (!soc) {
+				WMA_LOGE("%s:SOC context is NULL", __func__);
+				return;
+			}
+
+			if (privcmd->param_id == GEN_VDEV_PARAM_AMPDU) {
+				ret = cdp_aggr_cfg(soc, vdev,
+						privcmd->param_value, 0);
+				if (ret)
+					WMA_LOGE("cdp_aggr_cfg set ampdu failed ret %d",
+						ret);
+				else
+					intr[privcmd->param_vdev_id].config.
+						ampdu = privcmd->param_value;
+
+				aggr.aggr_type =
+					WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU;
+			} else {
+				aggr.aggr_type =
+					WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU;
+			}
+
+			aggr.vdev_id = vid;
+			aggr.tx_aggregation_size = privcmd->param_value;
+			aggr.rx_aggregation_size = privcmd->param_value;
+
+			ret = wma_set_tx_rx_aggregation_size(&aggr);
+			if (QDF_IS_STATUS_ERROR(ret)) {
+				WMA_LOGE("set_aggr_size failed ret %d", ret);
+				return;
+			}
+			break;
+		case GEN_PARAM_CRASH_INJECT:
+			if (QDF_GLOBAL_FTM_MODE  == cds_get_conparam())
+				WMA_LOGE("Crash inject not allowed in FTM mode");
+			else
+				ret = wma_crash_inject(wma,
+						privcmd->param_value,
+						privcmd->param_sec_value);
+			break;
+		case GEN_PARAM_CAPTURE_TSF:
+			ret = wma_capture_tsf(wma, privcmd->param_value);
+			break;
+		case GEN_PARAM_RESET_TSF_GPIO:
+			ret = wma_reset_tsf_gpio(wma, privcmd->param_value);
+			break;
+		default:
+			WMA_LOGE("Invalid param id 0x%x",
+				 privcmd->param_id);
+			break;
+		}
+		break;
+	}
+	case DBG_CMD:
+		WMA_LOGD("dbg pid %d pval %d", privcmd->param_id,
+			 privcmd->param_value);
+		switch (privcmd->param_id) {
+		case WMI_DBGLOG_LOG_LEVEL:
+			ret = dbglog_set_log_lvl(wma->wmi_handle,
+						   privcmd->param_value);
+			if (ret)
+				WMA_LOGE("dbglog_set_log_lvl failed ret %d",
+					 ret);
+			break;
+		case WMI_DBGLOG_VAP_ENABLE:
+			ret = dbglog_vap_log_enable(wma->wmi_handle,
+						    privcmd->param_value, true);
+			if (ret)
+				WMA_LOGE("dbglog_vap_log_enable failed ret %d",
+					 ret);
+			break;
+		case WMI_DBGLOG_VAP_DISABLE:
+			ret = dbglog_vap_log_enable(wma->wmi_handle,
+						privcmd->param_value, false);
+			if (ret)
+				WMA_LOGE("dbglog_vap_log_enable failed ret %d",
+					 ret);
+			break;
+		case WMI_DBGLOG_MODULE_ENABLE:
+			ret = dbglog_module_log_enable(wma->wmi_handle,
+						privcmd->param_value, true);
+			if (ret)
+				WMA_LOGE("dbglog_module_log_enable failed ret %d",
+					 ret);
+			break;
+		case WMI_DBGLOG_MODULE_DISABLE:
+			ret = dbglog_module_log_enable(wma->wmi_handle,
+						privcmd->param_value, false);
+			if (ret)
+				WMA_LOGE("dbglog_module_log_enable failed ret %d",
+					 ret);
+			break;
+		case WMI_DBGLOG_MOD_LOG_LEVEL:
+			ret = dbglog_set_mod_log_lvl(wma->wmi_handle,
+						       privcmd->param_value);
+			if (ret)
+				WMA_LOGE("dbglog_module_log_enable failed ret %d",
+					 ret);
+			break;
+		case WMI_DBGLOG_TYPE:
+			ret = dbglog_parser_type_init(wma->wmi_handle,
+							privcmd->param_value);
+			if (ret)
+				WMA_LOGE("dbglog_parser_type_init failed ret %d",
+					 ret);
+			break;
+		case WMI_DBGLOG_REPORT_ENABLE:
+			ret = dbglog_report_enable(wma->wmi_handle,
+						     privcmd->param_value);
+			if (ret)
+				WMA_LOGE("dbglog_report_enable failed ret %d",
+					 ret);
+			break;
+		case WMI_WLAN_PROFILE_TRIGGER_CMDID:
+			ret = wma_unified_fw_profiling_cmd(wma->wmi_handle,
+					 WMI_WLAN_PROFILE_TRIGGER_CMDID,
+					 privcmd->param_value, 0);
+			if (ret)
+				WMA_LOGE("Profile cmd failed for %d ret %d",
+					WMI_WLAN_PROFILE_TRIGGER_CMDID, ret);
+			break;
+		case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
+			ret = wma_unified_fw_profiling_cmd(wma->wmi_handle,
+				  WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
+				  privcmd->param_value,
+				  privcmd->param_sec_value);
+			if (ret)
+				WMA_LOGE("Profile cmd failed for %d ret %d",
+				   WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
+				   ret);
+			break;
+		case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
+			ret = wma_unified_fw_profiling_cmd(wma->wmi_handle,
+					 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
+					 privcmd->param_value,
+					 privcmd->param_sec_value);
+			if (ret)
+				WMA_LOGE("Profile cmd failed for %d ret %d",
+					WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
+					ret);
+			break;
+		case WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID:
+			ret = wma_unified_fw_profiling_cmd(wma->wmi_handle,
+					 WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
+					 0, 0);
+			if (ret)
+				WMA_LOGE("Profile cmd failed for %d ret %d",
+					WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
+					ret);
+			break;
+		case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
+			ret = wma_unified_fw_profiling_cmd(wma->wmi_handle,
+					WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
+					0, 0);
+			if (ret)
+				WMA_LOGE("Profile cmd failed for %d ret %d",
+				   WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
+				   ret);
+			break;
+		case WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID:
+			/* Set the Green AP */
+			ret = wmi_unified_green_ap_ps_send
+					(wma->wmi_handle, privcmd->param_value,
+					 WMA_WILDCARD_PDEV_ID);
+			if (ret) {
+				WMA_LOGE("Set GreenAP Failed val %d",
+					 privcmd->param_value);
+			}
+			break;
+
+		default:
+			WMA_LOGE("Invalid param id 0x%x", privcmd->param_id);
+			break;
+		}
+		break;
+	case PPS_CMD:
+		WMA_LOGD("dbg pid %d pval %d", privcmd->param_id,
+			 privcmd->param_value);
+		switch (privcmd->param_id) {
+
+		case WMI_VDEV_PPS_PAID_MATCH:
+			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+				  (PKT_PWR_SAVE_PAID_MATCH & 0xffff);
+			intr[vid].config.pps_params.paid_match_enable =
+				privcmd->param_value;
+			break;
+		case WMI_VDEV_PPS_GID_MATCH:
+			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+				  (PKT_PWR_SAVE_GID_MATCH & 0xffff);
+			intr[vid].config.pps_params.gid_match_enable =
+				privcmd->param_value;
+			break;
+		case WMI_VDEV_PPS_EARLY_TIM_CLEAR:
+			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+				  (PKT_PWR_SAVE_EARLY_TIM_CLEAR & 0xffff);
+			intr[vid].config.pps_params.tim_clear =
+				privcmd->param_value;
+			break;
+		case WMI_VDEV_PPS_EARLY_DTIM_CLEAR:
+			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+				  (PKT_PWR_SAVE_EARLY_DTIM_CLEAR & 0xffff);
+			intr[vid].config.pps_params.dtim_clear =
+				privcmd->param_value;
+			break;
+		case WMI_VDEV_PPS_EOF_PAD_DELIM:
+			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+				  (PKT_PWR_SAVE_EOF_PAD_DELIM & 0xffff);
+			intr[vid].config.pps_params.eof_delim =
+				privcmd->param_value;
+			break;
+		case WMI_VDEV_PPS_MACADDR_MISMATCH:
+			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+				  (PKT_PWR_SAVE_MACADDR_MISMATCH & 0xffff);
+			intr[vid].config.pps_params.mac_match =
+				privcmd->param_value;
+			break;
+		case WMI_VDEV_PPS_DELIM_CRC_FAIL:
+			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+				  (PKT_PWR_SAVE_DELIM_CRC_FAIL & 0xffff);
+			intr[vid].config.pps_params.delim_fail =
+				privcmd->param_value;
+			break;
+		case WMI_VDEV_PPS_GID_NSTS_ZERO:
+			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+				  (PKT_PWR_SAVE_GID_NSTS_ZERO & 0xffff);
+			intr[vid].config.pps_params.nsts_zero =
+				privcmd->param_value;
+			break;
+		case WMI_VDEV_PPS_RSSI_CHECK:
+			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+				  (PKT_PWR_SAVE_RSSI_CHECK & 0xffff);
+			intr[vid].config.pps_params.rssi_chk =
+				privcmd->param_value;
+			break;
+		case WMI_VDEV_PPS_5G_EBT:
+			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+				  (PKT_PWR_SAVE_5G_EBT & 0xffff);
+			intr[vid].config.pps_params.ebt_5g =
+				privcmd->param_value;
+			break;
+		default:
+			WMA_LOGE("Invalid param id 0x%x", privcmd->param_id);
+			break;
+		}
+		break;
+
+	case QPOWER_CMD:
+		WMA_LOGD("QPOWER CLI CMD pid %d pval %d", privcmd->param_id,
+			 privcmd->param_value);
+		switch (privcmd->param_id) {
+		case WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT:
+			WMA_LOGD("QPOWER CLI CMD:Ps Poll Cnt val %d",
+				 privcmd->param_value);
+			/* Set the QPower Ps Poll Count */
+			ret = wma_unified_set_sta_ps_param(wma->wmi_handle,
+				vid, WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
+				privcmd->param_value);
+			if (ret) {
+				WMA_LOGE("Set Q-PsPollCnt Failed vdevId %d val %d",
+					vid, privcmd->param_value);
+			} else {
+				qparams->max_ps_poll_cnt = privcmd->param_value;
+			}
+			break;
+		case WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE:
+			WMA_LOGD("QPOWER CLI CMD:Max Tx Before wake val %d",
+				 privcmd->param_value);
+			/* Set the QPower Max Tx Before Wake */
+			ret = wma_unified_set_sta_ps_param(wma->wmi_handle,
+				vid, WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
+				privcmd->param_value);
+			if (ret) {
+				WMA_LOGE("Set Q-MaxTxBefWake Failed vId %d val %d",
+					vid, privcmd->param_value);
+			} else {
+				qparams->max_tx_before_wake =
+						privcmd->param_value;
+			}
+			break;
+		case WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
+			WMA_LOGD("QPOWER CLI CMD:Ps Poll Wake Inv val %d",
+				 privcmd->param_value);
+			/* Set the QPower Spec Ps Poll Wake Inv */
+			ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vid,
+				WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
+				privcmd->param_value);
+			if (ret) {
+				WMA_LOGE("Set Q-PsPoll WakeIntv Failed vId %d val %d",
+					vid, privcmd->param_value);
+			} else {
+				qparams->spec_ps_poll_wake_interval =
+					privcmd->param_value;
+			}
+			break;
+		case WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
+			WMA_LOGD("QPOWER CLI CMD:Spec NoData Ps Poll val %d",
+				 privcmd->param_value);
+			/* Set the QPower Spec NoData PsPoll */
+			ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vid,
+				WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
+				privcmd->param_value);
+			if (ret) {
+				WMA_LOGE("Set Q-SpecNoDataPsPoll Failed vId %d val %d",
+					vid, privcmd->param_value);
+			} else {
+				qparams->max_spec_nodata_ps_poll =
+					privcmd->param_value;
+			}
+			break;
+
+		default:
+			WMA_LOGE("Invalid param id 0x%x", privcmd->param_id);
+			break;
+		}
+		break;
+	case GTX_CMD:
+		WMA_LOGD("vdev id %d pid %d pval %d", privcmd->param_vdev_id,
+			 privcmd->param_id, privcmd->param_value);
+		switch (privcmd->param_id) {
+		case WMI_VDEV_PARAM_GTX_HT_MCS:
+			intr[vid].config.gtx_info.gtxRTMask[0] =
+				privcmd->param_value;
+			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
+					privcmd->param_vdev_id,
+					&intr[vid].config.gtx_info);
+			break;
+		case WMI_VDEV_PARAM_GTX_VHT_MCS:
+			intr[vid].config.gtx_info.gtxRTMask[1] =
+				privcmd->param_value;
+			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
+					privcmd->param_vdev_id,
+					&intr[vid].config.gtx_info);
+			break;
+
+		case WMI_VDEV_PARAM_GTX_USR_CFG:
+			intr[vid].config.gtx_info.gtxUsrcfg =
+				privcmd->param_value;
+			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
+					privcmd->param_vdev_id,
+					&intr[vid].config.gtx_info);
+			break;
+
+		case WMI_VDEV_PARAM_GTX_THRE:
+			intr[vid].config.gtx_info.gtxPERThreshold =
+				privcmd->param_value;
+			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
+					privcmd->param_vdev_id,
+					&intr[vid].config.gtx_info);
+			break;
+
+		case WMI_VDEV_PARAM_GTX_MARGIN:
+			intr[vid].config.gtx_info.gtxPERMargin =
+				privcmd->param_value;
+			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
+					privcmd->param_vdev_id,
+					&intr[vid].config.gtx_info);
+			break;
+
+		case WMI_VDEV_PARAM_GTX_STEP:
+			intr[vid].config.gtx_info.gtxTPCstep =
+				privcmd->param_value;
+			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
+					privcmd->param_vdev_id,
+					&intr[vid].config.gtx_info);
+			break;
+
+		case WMI_VDEV_PARAM_GTX_MINTPC:
+			intr[vid].config.gtx_info.gtxTPCMin =
+				privcmd->param_value;
+			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
+					privcmd->param_vdev_id,
+					&intr[vid].config.gtx_info);
+			break;
+
+		case WMI_VDEV_PARAM_GTX_BW_MASK:
+			intr[vid].config.gtx_info.gtxBWMask =
+				privcmd->param_value;
+			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
+					privcmd->param_vdev_id,
+					&intr[vid].config.gtx_info);
+			if (ret) {
+				WMA_LOGE("wma_vdev_set_param failed ret %d",
+					 ret);
+				return;
+			}
+			break;
+		default:
+			break;
+		}
+		break;
+
+	default:
+		WMA_LOGE("Invalid vpdev command id");
+	}
+	if (1 == privcmd->param_vp_dev) {
+		switch (privcmd->param_id) {
+		case WMI_VDEV_PARAM_NSS:
+			intr[vid].config.nss = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_LDPC:
+			intr[vid].config.ldpc = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_TX_STBC:
+			intr[vid].config.tx_stbc = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_RX_STBC:
+			intr[vid].config.rx_stbc = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_SGI:
+			intr[vid].config.shortgi = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_ENABLE_RTSCTS:
+			intr[vid].config.rtscts_en = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_CHWIDTH:
+			intr[vid].config.chwidth = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_FIXED_RATE:
+			intr[vid].config.tx_rate = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE:
+			intr[vid].config.erx_adjust = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM:
+			intr[vid].config.erx_bmiss_num = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE:
+			intr[vid].config.erx_bmiss_cycle = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP:
+			intr[vid].config.erx_slop_step = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP:
+			intr[vid].config.erx_init_slop = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE:
+			intr[vid].config.erx_adj_pause = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE:
+			intr[vid].config.erx_dri_sample = privcmd->param_value;
+			break;
+		case WMI_VDEV_PARAM_HE_DCM:
+		case WMI_VDEV_PARAM_HE_RANGE_EXT:
+			wma_set_he_vdev_param(&intr[vid], privcmd->param_id,
+					      privcmd->param_value);
+			break;
+		default:
+			WMA_LOGD("Invalid wma_cli_set vdev command/Not yet implemented 0x%x",
+				 privcmd->param_id);
+			break;
+		}
+	} else if (2 == privcmd->param_vp_dev) {
+		switch (privcmd->param_id) {
+		case WMI_PDEV_PARAM_ANI_ENABLE:
+			wma->pdevconfig.ani_enable = privcmd->param_value;
+			break;
+		case WMI_PDEV_PARAM_ANI_POLL_PERIOD:
+			wma->pdevconfig.ani_poll_len = privcmd->param_value;
+			break;
+		case WMI_PDEV_PARAM_ANI_LISTEN_PERIOD:
+			wma->pdevconfig.ani_listen_len = privcmd->param_value;
+			break;
+		case WMI_PDEV_PARAM_ANI_OFDM_LEVEL:
+			wma->pdevconfig.ani_ofdm_level = privcmd->param_value;
+			break;
+		case WMI_PDEV_PARAM_ANI_CCK_LEVEL:
+			wma->pdevconfig.ani_cck_level = privcmd->param_value;
+			break;
+		case WMI_PDEV_PARAM_DYNAMIC_BW:
+			wma->pdevconfig.cwmenable = privcmd->param_value;
+			break;
+		case WMI_PDEV_PARAM_CTS_CBW:
+			wma->pdevconfig.cts_cbw = privcmd->param_value;
+			break;
+		case WMI_PDEV_PARAM_TX_CHAIN_MASK:
+			wma->pdevconfig.txchainmask = privcmd->param_value;
+			break;
+		case WMI_PDEV_PARAM_RX_CHAIN_MASK:
+			wma->pdevconfig.rxchainmask = privcmd->param_value;
+			break;
+		case WMI_PDEV_PARAM_TXPOWER_LIMIT2G:
+			wma->pdevconfig.txpow2g = privcmd->param_value;
+			if ((pMac->mlme_cfg->gen.band_capability ==
+			     BAND_ALL) ||
+			    (pMac->mlme_cfg->gen.band_capability ==
+			     BAND_2G)) {
+				if (cfg_set_int(pMac,
+						WNI_CFG_CURRENT_TX_POWER_LEVEL,
+						privcmd->param_value) !=
+				    QDF_STATUS_SUCCESS)
+					WMA_LOGE("could not set WNI_CFG_CURRENT_TX_POWER_LEVEL");
+
+			} else {
+				WMA_LOGE("Current band is not 2G");
+			}
+			break;
+		case WMI_PDEV_PARAM_TXPOWER_LIMIT5G:
+			wma->pdevconfig.txpow5g = privcmd->param_value;
+			if ((pMac->mlme_cfg->gen.band_capability ==
+			     BAND_ALL) ||
+			    (pMac->mlme_cfg->gen.band_capability ==
+			     BAND_5G)) {
+				if (cfg_set_int(pMac,
+						WNI_CFG_CURRENT_TX_POWER_LEVEL,
+						privcmd->param_value) !=
+				    QDF_STATUS_SUCCESS)
+					WMA_LOGE("could not set WNI_CFG_CURRENT_TX_POWER_LEVEL");
+
+			} else {
+				WMA_LOGE("Current band is not 5G");
+			}
+			break;
+		default:
+			WMA_LOGD("Invalid wma_cli_set pdev command/Not yet implemented 0x%x",
+				 privcmd->param_id);
+			break;
+		}
+	} else if (5 == privcmd->param_vp_dev) {
+		ret = wma_vdev_set_param(wma->wmi_handle,
+					privcmd->param_vdev_id,
+					WMI_VDEV_PARAM_PACKET_POWERSAVE,
+					pps_val);
+		if (ret)
+			WMA_LOGE("Failed to send wmi packet power save cmd");
+		else
+			WMA_LOGD("Sent packet power save cmd %d value %x to target",
+				privcmd->param_id, pps_val);
+	}
+}
+
+uint32_t wma_critical_events_in_flight(void)
+{
+	t_wma_handle *wma;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma)
+		return 0;
+
+	return qdf_atomic_read(&wma->critical_events_in_flight);
+}
+
+static bool wma_event_is_critical(uint32_t event_id)
+{
+	switch (event_id) {
+	case WMI_ROAM_SYNCH_EVENTID:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/**
+ * wma_process_fw_event() - process any fw event
+ * @wma: wma handle
+ * @buf: fw event buffer
+ *
+ * This function process any fw event to serialize it through mc thread.
+ *
+ * Return: none
+ */
+static int wma_process_fw_event(tp_wma_handle wma,
+				wma_process_fw_event_params *buf)
+{
+	struct wmi_unified *wmi_handle = (struct wmi_unified *)buf->wmi_handle;
+	uint32_t event_id = WMI_GET_FIELD(qdf_nbuf_data(buf->evt_buf),
+					  WMI_CMD_HDR, COMMANDID);
+
+	wmi_process_fw_event(wmi_handle, buf->evt_buf);
+
+	if (wma_event_is_critical(event_id))
+		qdf_atomic_dec(&wma->critical_events_in_flight);
+
+	return 0;
+}
+
+/**
+ * wmi_process_fw_event_tasklet_ctx() - process in tasklet context
+ * @ctx: handle to wmi
+ * @ev: wmi event buffer
+ *
+ * Event process by below function will be in tasket context,
+ * need to use this method only for time sensitive functions.
+ *
+ * Return: none
+ */
+static int wma_process_fw_event_tasklet_ctx(void *ctx, void *ev)
+{
+	wmi_process_fw_event(ctx, ev);
+
+	return 0;
+}
+
+/**
+ * wma_process_hal_pwr_dbg_cmd() - send hal pwr dbg cmd to fw.
+ * @handle: wma handle
+ * @sir_pwr_dbg_params: unit test command
+ *
+ * This function send unit test command to fw.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wma_process_hal_pwr_dbg_cmd(WMA_HANDLE handle,
+				       struct sir_mac_pwr_dbg_cmd *
+				       sir_pwr_dbg_params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle)handle;
+	int i;
+	struct wmi_power_dbg_params wmi_pwr_dbg_params;
+	QDF_STATUS status;
+
+	if (!sir_pwr_dbg_params) {
+		WMA_LOGE("%s: sir_pwr_dbg_params is null", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	wmi_pwr_dbg_params.module_id = sir_pwr_dbg_params->module_id;
+	wmi_pwr_dbg_params.pdev_id = sir_pwr_dbg_params->pdev_id;
+	wmi_pwr_dbg_params.num_args = sir_pwr_dbg_params->num_args;
+
+	for (i = 0; i < wmi_pwr_dbg_params.num_args; i++)
+		wmi_pwr_dbg_params.args[i] = sir_pwr_dbg_params->args[i];
+
+	status = wmi_unified_send_power_dbg_cmd(wma_handle->wmi_handle,
+						&wmi_pwr_dbg_params);
+
+	return status;
+}
+
+static void wma_discard_fw_event(struct scheduler_msg *msg)
+{
+	if (!msg->bodyptr)
+		return;
+
+	switch (msg->type) {
+	case WMA_PROCESS_FW_EVENT:
+		qdf_nbuf_free(((wma_process_fw_event_params *)msg->bodyptr)
+				->evt_buf);
+		break;
+	case WMA_SET_LINK_STATE:
+		qdf_mem_free(((tpLinkStateParams) msg->bodyptr)->callbackArg);
+		break;
+	}
+
+	qdf_mem_free(msg->bodyptr);
+	msg->bodyptr = NULL;
+	msg->bodyval = 0;
+	msg->type = 0;
+}
+
+/**
+ * wma_process_fw_event_handler() - common event handler to serialize
+ *                                  event processing through mc_thread
+ * @ctx: wmi context
+ * @ev: event buffer
+ * @rx_ctx: rx execution context
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int wma_process_fw_event_mc_thread_ctx(void *ctx, void *ev)
+{
+	wma_process_fw_event_params *params_buf;
+	struct scheduler_msg cds_msg = { 0 };
+	tp_wma_handle wma;
+	uint32_t event_id;
+
+	params_buf = qdf_mem_malloc(sizeof(wma_process_fw_event_params));
+	if (!params_buf) {
+		qdf_nbuf_free(ev);
+		return -ENOMEM;
+	}
+
+	params_buf->wmi_handle = (struct wmi_unified *)ctx;
+	params_buf->evt_buf = ev;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	event_id = WMI_GET_FIELD(qdf_nbuf_data(params_buf->evt_buf),
+				 WMI_CMD_HDR, COMMANDID);
+	if (wma && wma_event_is_critical(event_id))
+		qdf_atomic_inc(&wma->critical_events_in_flight);
+
+	cds_msg.type = WMA_PROCESS_FW_EVENT;
+	cds_msg.bodyptr = params_buf;
+	cds_msg.bodyval = 0;
+	cds_msg.flush_callback = wma_discard_fw_event;
+
+	if (QDF_STATUS_SUCCESS !=
+		scheduler_post_message(QDF_MODULE_ID_WMA,
+				       QDF_MODULE_ID_WMA,
+				       QDF_MODULE_ID_WMA, &cds_msg)) {
+		WMA_LOGE("%s: Failed to post WMA_PROCESS_FW_EVENT msg",
+			 __func__);
+		qdf_nbuf_free(ev);
+		qdf_mem_free(params_buf);
+		return -EFAULT;
+	}
+	return 0;
+
+}
+
+/**
+ * wma_process_fw_event_handler() - common event handler to serialize
+ *                                  event processing through mc_thread
+ * @ctx: wmi context
+ * @ev: event buffer
+ * @rx_ctx: rx execution context
+ *
+ * Return: 0 on success, errno on failure
+ */
+int wma_process_fw_event_handler(void *ctx, void *htc_packet, uint8_t rx_ctx)
+{
+	int err = 0;
+	ol_scn_t scn_handle;
+	struct wlan_objmgr_psoc *psoc;
+	struct target_psoc_info *tgt_hdl;
+	wmi_buf_t evt_buf;
+	bool is_wmi_ready = false;
+
+	evt_buf = (wmi_buf_t) ((HTC_PACKET *)htc_packet)->pPktContext;
+
+	scn_handle = ((wmi_unified_t)ctx)->scn_handle;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
+	if (!psoc) {
+		WMA_LOGE("psoc is null");
+		return err;
+	}
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
+	if (!tgt_hdl) {
+		WMA_LOGE("target_psoc_info is null");
+		return err;
+	}
+
+	is_wmi_ready = target_psoc_get_wmi_ready(tgt_hdl);
+	if (!is_wmi_ready) {
+		WMA_LOGD("fw event recvd before ready event processed");
+		WMA_LOGD("therefore use worker thread");
+		wmi_process_fw_event_worker_thread_ctx(ctx, htc_packet);
+		return err;
+	}
+
+	if (rx_ctx == WMA_RX_SERIALIZER_CTX) {
+		err = wma_process_fw_event_mc_thread_ctx(ctx, evt_buf);
+	} else if (rx_ctx == WMA_RX_TASKLET_CTX) {
+		wma_process_fw_event_tasklet_ctx(ctx, evt_buf);
+	} else {
+		WMA_LOGE("%s: invalid wmi event execution context", __func__);
+		qdf_nbuf_free(evt_buf);
+	}
+
+	return err;
+}
+
+#ifdef WLAN_FEATURE_NAN
+/**
+ * wma_set_nan_enable() - set nan enable flag in WMA handle
+ * @wma_handle: Pointer to wma handle
+ * @cds_cfg: Pointer to CDS Configuration
+ *
+ * Return: none
+ */
+static void wma_set_nan_enable(tp_wma_handle wma_handle,
+				struct cds_config_info *cds_cfg)
+{
+	wma_handle->is_nan_enabled = cfg_nan_get_enable(wma_handle->psoc);
+}
+#else
+static void wma_set_nan_enable(tp_wma_handle wma_handle,
+				struct cds_config_info *cds_cfg)
+{
+}
+#endif
+
+/**
+ * wma_init_max_no_of_peers - API to initialize wma configuration params
+ * @wma_handle: WMA Handle
+ * @max_peers: Max Peers supported
+ *
+ * Return: void
+ */
+static uint8_t wma_init_max_no_of_peers(tp_wma_handle wma_handle,
+				     uint16_t max_peers)
+{
+	struct wma_ini_config *cfg = wma_get_ini_handle(wma_handle);
+	struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
+	uint32_t tgt_version = hif_get_target_info_handle(scn)->target_version;
+	uint8_t max_no_of_peers;
+	uint8_t max_supported_peers = (tgt_version == AR6320_REV1_1_VERSION) ?
+			MAX_SUPPORTED_PEERS_REV1_1 : MAX_SUPPORTED_PEERS_REV1_3;
+
+	if (cfg == NULL) {
+		WMA_LOGE("%s: NULL WMA ini handle", __func__);
+		return 0;
+	}
+
+	max_no_of_peers = (max_peers > max_supported_peers) ?
+				max_supported_peers : max_peers;
+	cfg->max_no_of_peers = max_no_of_peers;
+	return max_no_of_peers;
+}
+
+/**
+ * wma_cleanup_vdev_resp_queue() - cleanup vdev response queue
+ * @wma: wma handle
+ *
+ * Return: none
+ */
+static void wma_cleanup_vdev_resp_queue(tp_wma_handle wma)
+{
+	struct wma_target_req *req_msg = NULL;
+	qdf_list_node_t *node1 = NULL;
+
+	qdf_spin_lock_bh(&wma->vdev_respq_lock);
+	if (!qdf_list_size(&wma->vdev_resp_queue)) {
+		qdf_spin_unlock_bh(&wma->vdev_respq_lock);
+		WMA_LOGD(FL("request queue maybe empty"));
+		return;
+	}
+
+	WMA_LOGD(FL("Cleaning up vdev resp queue"));
+
+	/* peek front, and then cleanup it in wma_vdev_resp_timer */
+	while (qdf_list_peek_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);
+		qdf_mc_timer_stop(&req_msg->event_timeout);
+		wma_vdev_resp_timer(req_msg);
+		qdf_spin_lock_bh(&wma->vdev_respq_lock);
+	}
+	qdf_spin_unlock_bh(&wma->vdev_respq_lock);
+}
+
+/**
+ * wma_cleanup_hold_req() - cleanup hold request queue
+ * @wma: wma handle
+ *
+ * Return: none
+ */
+static void wma_cleanup_hold_req(tp_wma_handle wma)
+{
+	struct wma_target_req *req_msg = NULL;
+	qdf_list_node_t *node1 = NULL;
+
+	qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
+	if (!qdf_list_size(&wma->wma_hold_req_queue)) {
+		qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
+		WMA_LOGD(FL("request queue is empty"));
+		return;
+	}
+
+	/* peek front, and then cleanup it in wma_hold_req_timer */
+	while (QDF_STATUS_SUCCESS ==
+		qdf_list_peek_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 */
+		qdf_mc_timer_stop(&req_msg->event_timeout);
+		wma_hold_req_timer(req_msg);
+		qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
+	}
+	qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
+}
+
+/**
+ * wma_cleanup_vdev_resp_and_hold_req() - cleaunup the vdev resp and hold req
+ * queue
+ * @msg :scheduler msg
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+wma_cleanup_vdev_resp_and_hold_req(struct scheduler_msg *msg)
+{
+	if (!msg || !msg->bodyptr) {
+		WMA_LOGE(FL("msg or body pointer is NULL"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wma_cleanup_vdev_resp_queue(msg->bodyptr);
+	wma_cleanup_hold_req(msg->bodyptr);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_shutdown_notifier_cb - Shutdown notifer call back
+ * @priv : WMA handle
+ *
+ * During recovery, WMA may wait for resume to complete if the crash happens
+ * while in suspend. This may cause delays in completing the recovery. This call
+ * back would be called during recovery and the event is completed so that if
+ * the resume is waiting on FW to respond then it can get out of the wait so
+ * that recovery thread can start bringing down all the modules.
+ *
+ * Return: None
+ */
+static void wma_shutdown_notifier_cb(void *priv)
+{
+	tp_wma_handle wma_handle = priv;
+	struct scheduler_msg msg = { 0 };
+	QDF_STATUS status;
+
+	qdf_event_set(&wma_handle->wma_resume_event);
+	ucfg_pmo_psoc_wakeup_host_event_received(wma_handle->psoc);
+	wmi_stop(wma_handle->wmi_handle);
+
+	msg.bodyptr = priv;
+	msg.callback = wma_cleanup_vdev_resp_and_hold_req;
+	status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGE(FL("Failed to post SYS_MSG_ID_CLEAN_VDEV_RSP_QUEUE"));
+}
+
+struct wma_version_info g_wmi_version_info;
+
+#ifdef WLAN_FEATURE_MEMDUMP_ENABLE
+/**
+ * wma_state_info_dump() - prints state information of wma layer
+ * @buf: buffer pointer
+ * @size: size of buffer to be filled
+ *
+ * This function is used to dump state information of wma layer
+ *
+ * Return: None
+ */
+#ifdef QCA_SUPPORT_CP_STATS
+static void wma_state_info_dump(char **buf_ptr, uint16_t *size)
+{
+	uint8_t vdev_id;
+	uint16_t len = 0;
+	t_wma_handle *wma;
+	char *buf = *buf_ptr;
+	struct wma_txrx_node *iface;
+	struct wake_lock_stats stats;
+	struct wlan_objmgr_vdev *vdev;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return;
+	}
+
+	WMA_LOGD("%s: size of buffer: %d", __func__, *size);
+
+	for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
+		iface = &wma->interfaces[vdev_id];
+		if (!iface->handle)
+			continue;
+
+		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
+						vdev_id, WLAN_LEGACY_WMA_ID);
+		if (vdev == NULL)
+			continue;
+		ucfg_mc_cp_stats_get_vdev_wake_lock_stats(vdev, &stats);
+		len += qdf_scnprintf(buf + len, *size - len,
+			"\n"
+			"vdev_id %d\n"
+			"WoW Stats\n"
+			"\tpno_match %u\n"
+			"\tpno_complete %u\n"
+			"\tgscan %u\n"
+			"\tlow_rssi %u\n"
+			"\trssi_breach %u\n"
+			"\tucast %u\n"
+			"\tbcast %u\n"
+			"\ticmpv4 %u\n"
+			"\ticmpv6 %u\n"
+			"\tipv4_mcast %u\n"
+			"\tipv6_mcast %u\n"
+			"\tipv6_mcast_ra %u\n"
+			"\tipv6_mcast_ns %u\n"
+			"\tipv6_mcast_na %u\n"
+			"\toem_response %u\n"
+			"conn_state %d\n"
+			"dtimPeriod %d\n"
+			"chanmode %d\n"
+			"vht_capable %d\n"
+			"ht_capable %d\n"
+			"chan_width %d\n"
+			"vdev_active %d\n"
+			"vdev_up %d\n"
+			"aid %d\n"
+			"rate_flags %d\n"
+			"nss %d\n"
+			"tx_power %d\n"
+			"max_tx_power %d\n"
+			"nwType %d\n"
+			"tx_streams %d\n"
+			"rx_streams %d\n"
+			"chain_mask %d\n"
+			"nss_2g %d\n"
+			"nss_5g %d",
+			vdev_id,
+			stats.pno_match_wake_up_count,
+			stats.pno_complete_wake_up_count,
+			stats.gscan_wake_up_count,
+			stats.low_rssi_wake_up_count,
+			stats.rssi_breach_wake_up_count,
+			stats.ucast_wake_up_count,
+			stats.bcast_wake_up_count,
+			stats.icmpv4_count,
+			stats.icmpv6_count,
+			stats.ipv4_mcast_wake_up_count,
+			stats.ipv6_mcast_wake_up_count,
+			stats.ipv6_mcast_ra_stats,
+			stats.ipv6_mcast_ns_stats,
+			stats.ipv6_mcast_na_stats,
+			stats.oem_response_wake_up_count,
+			iface->conn_state,
+			iface->dtimPeriod,
+			iface->chanmode,
+			iface->vht_capable,
+			iface->ht_capable,
+			iface->chan_width,
+			iface->vdev_active,
+			wma_is_vdev_up(vdev_id),
+			iface->aid,
+			iface->rate_flags,
+			iface->nss,
+			iface->tx_power,
+			iface->max_tx_power,
+			iface->nwType,
+			iface->tx_streams,
+			iface->rx_streams,
+			iface->chain_mask,
+			iface->nss_2g,
+			iface->nss_5g);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+	}
+
+	*size -= len;
+	*buf_ptr += len;
+}
+#else /* QCA_SUPPORT_CP_STATS */
+static void wma_state_info_dump(char **buf_ptr, uint16_t *size)
+{
+	t_wma_handle *wma;
+	struct sir_vdev_wow_stats *stats;
+	uint16_t len = 0;
+	char *buf = *buf_ptr;
+	struct wma_txrx_node *iface;
+	uint8_t vdev_id;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return;
+	}
+
+	WMA_LOGE("%s: size of buffer: %d", __func__, *size);
+
+	for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
+		iface = &wma->interfaces[vdev_id];
+		if (!iface->handle)
+			continue;
+
+		stats = &iface->wow_stats;
+		len += qdf_scnprintf(buf + len, *size - len,
+			"\n"
+			"vdev_id %d\n"
+			"WoW Stats\n"
+			"\tpno_match %u\n"
+			"\tpno_complete %u\n"
+			"\tgscan %u\n"
+			"\tlow_rssi %u\n"
+			"\trssi_breach %u\n"
+			"\tucast %u\n"
+			"\tbcast %u\n"
+			"\ticmpv4 %u\n"
+			"\ticmpv6 %u\n"
+			"\tipv4_mcast %u\n"
+			"\tipv6_mcast %u\n"
+			"\tipv6_mcast_ra %u\n"
+			"\tipv6_mcast_ns %u\n"
+			"\tipv6_mcast_na %u\n"
+			"\toem_response %u\n"
+			"conn_state %d\n"
+			"dtimPeriod %d\n"
+			"chanmode %d\n"
+			"vht_capable %d\n"
+			"ht_capable %d\n"
+			"chan_width %d\n"
+			"vdev_active %d\n"
+			"vdev_up %d\n"
+			"aid %d\n"
+			"rate_flags %d\n"
+			"nss %d\n"
+			"tx_power %d\n"
+			"max_tx_power %d\n"
+			"nwType %d\n"
+			"tx_streams %d\n"
+			"rx_streams %d\n"
+			"chain_mask %d\n"
+			"nss_2g %d\n"
+			"nss_5g %d",
+			vdev_id,
+			stats->pno_match,
+			stats->pno_complete,
+			stats->gscan,
+			stats->low_rssi,
+			stats->rssi_breach,
+			stats->ucast,
+			stats->bcast,
+			stats->icmpv4,
+			stats->icmpv6,
+			stats->ipv4_mcast,
+			stats->ipv6_mcast,
+			stats->ipv6_mcast_ra,
+			stats->ipv6_mcast_ns,
+			stats->ipv6_mcast_na,
+			stats->oem_response,
+			iface->conn_state,
+			iface->dtimPeriod,
+			iface->chanmode,
+			iface->vht_capable,
+			iface->ht_capable,
+			iface->chan_width,
+			iface->vdev_active,
+			wma_is_vdev_up(vdev_id),
+			iface->aid,
+			iface->rate_flags,
+			iface->nss,
+			iface->tx_power,
+			iface->max_tx_power,
+			iface->nwType,
+			iface->tx_streams,
+			iface->rx_streams,
+			iface->chain_mask,
+			iface->nss_2g,
+			iface->nss_5g);
+	}
+
+	*size -= len;
+	*buf_ptr += len;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+/**
+ * wma_register_debug_callback() - registration function for wma layer
+ * to print wma state information
+ */
+static void wma_register_debug_callback(void)
+{
+	qdf_register_debug_callback(QDF_MODULE_ID_WMA, &wma_state_info_dump);
+}
+#else /* WLAN_FEATURE_MEMDUMP_ENABLE */
+static void wma_register_debug_callback(void)
+{
+}
+#endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
+/**
+ * wma_register_tx_ops_handler() - register tx_ops of southbound
+ * @tx_ops:  tx_ops pointer in southbound
+ *
+ * Return: 0 on success, errno on failure
+ */
+static QDF_STATUS
+wma_register_tx_ops_handler(struct wlan_lmac_if_tx_ops *tx_ops)
+{
+	/*
+	 * Assign tx_ops, it's up to UMAC modules to declare and define these
+	 * functions which are used to send wmi command to target.
+	 */
+
+	if (!tx_ops) {
+		WMA_LOGE("%s: pointer to lmac if tx ops is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* mgmt_txrx component's tx ops */
+	tx_ops->mgmt_txrx_tx_ops.mgmt_tx_send = wma_mgmt_unified_cmd_send;
+
+	/* mgmt txrx component nbuf op for nbuf dma unmap */
+	tx_ops->mgmt_txrx_tx_ops.tx_drain_nbuf_op = wma_mgmt_nbuf_unmap_cb;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_target_if_open() - Attach UMAC modules' interface with wmi layer
+ * @wma_handle: wma handle
+ *
+ * Separate module defines below functions:
+ * 1. tgt_wmi_<module>_<action> api sends wmi command, assigned to south bound
+ *    tx_ops function pointers;
+ * 2. module's south dispatcher handles information from lower layer, assigned
+ *    to south bound rx_ops function pointers;
+ * 3. wmi event handler deals with wmi event, extracts umac needed information,
+ *    and call rx_ops(module's dispatcher). It executes in tasklet context and
+ *    is up to dispatcher to decide the context to reside in tasklet or in
+ *    thread context.
+ *
+ * Return: None
+ */
+static void wma_target_if_open(tp_wma_handle wma_handle)
+{
+	struct wlan_objmgr_psoc *psoc = wma_handle->psoc;
+
+	if (!psoc)
+		return;
+
+	wlan_global_lmac_if_set_txops_registration_cb(WLAN_DEV_OL,
+					target_if_register_tx_ops);
+	wlan_lmac_if_set_umac_txops_registration_cb(
+		wma_register_tx_ops_handler);
+	wlan_global_lmac_if_open(psoc);
+
+}
+
+/**
+ * wma_target_if_close() - Detach UMAC modules' interface with wmi layer
+ * @wma_handle: wma handle
+ *
+ * Return: None
+ */
+static void wma_target_if_close(tp_wma_handle wma_handle)
+{
+	struct wlan_objmgr_psoc *psoc = wma_handle->psoc;
+
+	if (!psoc)
+		return;
+
+	wlan_global_lmac_if_close(psoc);
+}
+
+/**
+ * wma_get_psoc_from_scn_handle() - API to get psoc from scn handle
+ * @scn_handle: opaque wma handle
+ *
+ * API to get psoc from scn handle
+ *
+ * Return: None
+ */
+static struct wlan_objmgr_psoc *wma_get_psoc_from_scn_handle(void *scn_handle)
+{
+	tp_wma_handle wma_handle;
+
+	if (!scn_handle) {
+		WMA_LOGE("invalid scn handle");
+		return NULL;
+	}
+	wma_handle = (tp_wma_handle)scn_handle;
+
+	return wma_handle->psoc;
+}
+
+/**
+ * wma_get_pdev_from_scn_handle() - API to get pdev from scn handle
+ * @scn_handle: opaque wma handle
+ *
+ * API to get pdev from scn handle
+ *
+ * Return: None
+ */
+static struct wlan_objmgr_pdev *wma_get_pdev_from_scn_handle(void *scn_handle)
+{
+	tp_wma_handle wma_handle;
+
+	if (!scn_handle) {
+		WMA_LOGE("invalid scn handle");
+		return NULL;
+	}
+	wma_handle = (tp_wma_handle)scn_handle;
+
+	return wma_handle->pdev;
+}
+
+/**
+ * wma_legacy_service_ready_event_handler() - legacy (ext)service ready handler
+ * @event_id: event_id
+ * @handle: wma handle
+ * @event_data: event data
+ * @length: event length
+ *
+ * Return: 0 for success, negative error code for failure
+ */
+static int wma_legacy_service_ready_event_handler(uint32_t event_id,
+						  void *handle,
+						  uint8_t *event_data,
+						  uint32_t length)
+{
+	switch (event_id) {
+	case wmi_service_ready_event_id:
+		return wma_rx_service_ready_event(handle, event_data, length);
+	case wmi_service_ready_ext_event_id:
+		return wma_rx_service_ready_ext_event(handle, event_data,
+						      length);
+	case wmi_ready_event_id:
+		return wma_rx_ready_event(handle, event_data, length);
+	default:
+		WMA_LOGE("Legacy callback invoked with invalid event_id:%d",
+			 event_id);
+		QDF_BUG(0);
+	}
+
+	return 0;
+}
+
+/**
+ * wma_flush_complete_evt_handler() - FW log flush complete event handler
+ * @handle: WMI handle
+ * @event:  Event recevied from FW
+ * @len:    Length of the event
+ *
+ */
+static int wma_flush_complete_evt_handler(void *handle,
+		u_int8_t *event,
+		u_int32_t len)
+{
+	QDF_STATUS status;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID_param_tlvs *param_buf;
+	wmi_debug_mesg_flush_complete_fixed_param *wmi_event;
+	wmi_debug_mesg_fw_data_stall_param *data_stall_event;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	uint8_t *buf_ptr;
+	uint32_t reason_code;
+
+	param_buf = (WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("Invalid log flush complete event buffer");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wmi_event = param_buf->fixed_param;
+	reason_code = wmi_event->reserved0;
+	WMA_LOGD("Received reason code %d from FW", reason_code);
+
+	buf_ptr = (uint8_t *)wmi_event;
+	buf_ptr = buf_ptr + sizeof(wmi_debug_mesg_flush_complete_fixed_param) +
+		  WMI_TLV_HDR_SIZE;
+	data_stall_event = (wmi_debug_mesg_fw_data_stall_param *) buf_ptr;
+
+	if (((data_stall_event->tlv_header & 0xFFFF0000) >> 16 ==
+	      WMITLV_TAG_STRUC_wmi_debug_mesg_fw_data_stall_param)) {
+		/**
+		 * Log data stall info received from FW:
+		 *
+		 * Possible data stall recovery types:
+		 * WLAN_DBG_DATA_STALL_RECOVERY_CONNECT_DISCONNECT
+		 * WLAN_DBG_DATA_STALL_RECOVERY_CONNECT_MAC_PHY_RESET
+		 * WLAN_DBG_DATA_STALL_RECOVERY_CONNECT_PDR
+		 *
+		 * Possible data stall event types:
+		 * WLAN_DBG_DATA_STALL_VDEV_PAUSE
+		 * WLAN_DBG_DATA_STALL_HWSCHED_CMD_FILTER
+		 * WLAN_DBG_DATA_STALL_HWSCHED_CMD_FLUSH
+		 * WLAN_DBG_DATA_STALL_RX_REFILL_FAILED
+		 * WLAN_DBG_DATA_STALL_RX_FCS_LEN_ERROR
+		 *
+		 * reason_code1:
+		 * The information stored in reason_code1 varies based on the
+		 * data stall type values:
+		 *
+		 * data_stall_type      | reason_code1
+		 * -----------------------------------------------------
+		 * HWSCHED_CMD_FLUSH    | flush req reason (0-40)
+		 * RX_REFILL_FAILED     | ring_id (0-7)
+		 * RX_FCS_LEN_ERROR     | exact error type
+		 *
+		 * reasone_code2:
+		 * on which tid/hwq stall happened
+		 *
+		 */
+		QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
+			  "Data Stall event:");
+		QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
+			  "data_stall_type: %x vdev_id_bitmap: %x reason_code1: %x reason_code2: %x recovery_type: %x ",
+			  data_stall_event->data_stall_type,
+			  data_stall_event->vdev_id_bitmap,
+			  data_stall_event->reason_code1,
+			  data_stall_event->reason_code2,
+			  data_stall_event->recovery_type);
+
+		cdp_post_data_stall_event(soc,
+					DATA_STALL_LOG_INDICATOR_FIRMWARE,
+					data_stall_event->data_stall_type,
+					0XFF,
+					data_stall_event->vdev_id_bitmap,
+					data_stall_event->recovery_type);
+	}
+
+	/*
+	 * reason_code = 0; Flush event in response to flush command
+	 * reason_code = other value; Asynchronous flush event for fatal events
+	 */
+	if (!reason_code && (cds_is_log_report_in_progress() == false)) {
+		WMA_LOGD("Received WMI flush event without sending CMD");
+		return -EINVAL;
+	} else if (!reason_code && cds_is_log_report_in_progress() == true) {
+		/* Flush event in response to flush command */
+		WMA_LOGD("Received WMI flush event in response to flush CMD");
+		status = qdf_mc_timer_stop(&wma->log_completion_timer);
+		if (status != QDF_STATUS_SUCCESS)
+			WMA_LOGE("Failed to stop the log completion timeout");
+		cds_logging_set_fw_flush_complete();
+		return QDF_STATUS_SUCCESS;
+	} else if (reason_code && cds_is_log_report_in_progress() == false) {
+		/* Asynchronous flush event for fatal events */
+		status = cds_set_log_completion(WLAN_LOG_TYPE_FATAL,
+				WLAN_LOG_INDICATOR_FIRMWARE,
+				reason_code, false);
+		if (QDF_STATUS_SUCCESS != status) {
+			WMA_LOGE("%s: Failed to set log trigger params",
+					__func__);
+			return QDF_STATUS_E_FAILURE;
+		}
+		cds_logging_set_fw_flush_complete();
+		return status;
+	} else {
+		/* Asynchronous flush event for fatal event,
+		 * but, report in progress already
+		 */
+		WMA_LOGD("%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
+				__func__, WLAN_LOG_TYPE_FATAL,
+				WLAN_LOG_INDICATOR_FIRMWARE, reason_code);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Asynchronous flush event for fatal event,
+	 * but, report in progress already
+	 */
+	WMA_LOGW("%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
+			__func__, WLAN_LOG_TYPE_FATAL,
+			WLAN_LOG_INDICATOR_FIRMWARE, reason_code);
+	return QDF_STATUS_E_FAILURE;
+}
+
+#ifdef WLAN_CONV_SPECTRAL_ENABLE
+/**
+ * wma_extract_single_phyerr_spectral() - extract single phy error from event
+ * @handle: wma handle
+ * @param evt_buf: pointer to event buffer
+ * @param datalen: data length of event buffer
+ * @param buf_offset: Pointer to hold value of current event buffer offset
+ * post extraction
+ * @param phyerr: Pointer to hold phyerr
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS wma_extract_single_phyerr_spectral(void *handle,
+		void *evt_buf,
+		uint16_t datalen, uint16_t *buf_offset,
+		wmi_host_phyerr_t *phyerr)
+{
+	wmi_single_phyerr_rx_event *ev;
+	int n = *buf_offset;
+
+	ev = (wmi_single_phyerr_rx_event *)((uint8_t *)evt_buf + n);
+
+	if (n < datalen) {
+		/* ensure there's at least space for the header */
+		if ((datalen - n) < sizeof(ev->hdr)) {
+			WMA_LOGE("%s: not enough space? (datalen=%d, n=%d, hdr=%zu bytes",
+					__func__, datalen, n, sizeof(ev->hdr));
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		phyerr->bufp = ev->bufp;
+		phyerr->buf_len = ev->hdr.buf_len;
+
+		/*
+		 * Sanity check the buffer length of the event against
+		 * what we currently have.
+		 *
+		 * Since buf_len is 32 bits, we check if it overflows
+		 * a large 32 bit value.  It's not 0x7fffffff because
+		 * we increase n by (buf_len + sizeof(hdr)), which would
+		 * in itself cause n to overflow.
+		 *
+		 * If "int" is 64 bits then this becomes a moot point.
+		 */
+		if (ev->hdr.buf_len > 0x7f000000) {
+			WMA_LOGE("%s: buf_len is garbage? (0x%x)",
+				__func__, ev->hdr.buf_len);
+			return QDF_STATUS_E_FAILURE;
+		}
+		if (n + ev->hdr.buf_len > datalen) {
+			WMA_LOGE("%s: buf_len exceeds available space n=%d, buf_len=%d, datalen=%d",
+				__func__, n, ev->hdr.buf_len, datalen);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr);
+		phyerr->tsf_timestamp = ev->hdr.tsf_timestamp;
+
+#ifdef DEBUG_SPECTRAL_SCAN
+		WMA_LOGD("%s: len=%d, tsf=0x%08x, rssi = 0x%x/0x%x/0x%x/0x%x, comb rssi = 0x%x, phycode=%d",
+				__func__,
+				ev->hdr.buf_len,
+				ev->hdr.tsf_timestamp,
+				ev->hdr.rssi_chain0,
+				ev->hdr.rssi_chain1,
+				ev->hdr.rssi_chain2,
+				ev->hdr.rssi_chain3,
+				WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr),
+					  phyerr->phy_err_code);
+
+		/*
+		 * For now, unroll this loop - the chain 'value' field isn't
+		 * a variable but glued together into a macro field definition.
+		 * Grr. :-)
+		 */
+		WMA_LOGD("%s: chain 0: raw=0x%08x; pri20=%d sec20=%d sec40=%d sec80=%d",
+				__func__,
+				ev->hdr.rssi_chain0,
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, PRI20),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC20),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC40),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC80));
+
+		WMA_LOGD("%s: chain 1: raw=0x%08x: pri20=%d sec20=%d sec40=%d sec80=%d",
+				__func__,
+				ev->hdr.rssi_chain1,
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, PRI20),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC20),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC40),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC80));
+
+		WMA_LOGD("%s: chain 2: raw=0x%08x: pri20=%d sec20=%d sec40=%d sec80=%d",
+				__func__,
+				ev->hdr.rssi_chain2,
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, PRI20),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC20),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC40),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC80));
+
+		WMA_LOGD("%s: chain 3: raw=0x%08x: pri20=%d sec20=%d sec40=%d sec80=%d",
+				__func__,
+				ev->hdr.rssi_chain3,
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, PRI20),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC20),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC40),
+				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC80));
+
+
+		WMA_LOGD("%s: freq_info_1=0x%08x, freq_info_2=0x%08x",
+			   __func__, ev->hdr.freq_info_1, ev->hdr.freq_info_2);
+
+		/*
+		 * The NF chain values are signed and are negative - hence
+		 * the cast evilness.
+		 */
+		WMA_LOGD("%s: nfval[1]=0x%08x, nfval[2]=0x%08x, nf=%d/%d/%d/%d, freq1=%d, freq2=%d, cw=%d",
+				__func__,
+				ev->hdr.nf_list_1,
+				ev->hdr.nf_list_2,
+				(int) WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 0),
+				(int) WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 1),
+				(int) WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 2),
+				(int) WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 3),
+				WMI_UNIFIED_FREQ_INFO_GET(&ev->hdr, 1),
+				WMI_UNIFIED_FREQ_INFO_GET(&ev->hdr, 2),
+				WMI_UNIFIED_CHWIDTH_GET(&ev->hdr));
+#endif
+
+		/*
+		 * If required, pass spectral events to the spectral module
+		 */
+		if (ev->hdr.buf_len > 0) {
+
+			/* Initialize the NF values to Zero. */
+			phyerr->rf_info.noise_floor[0] =
+			    WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 0);
+			phyerr->rf_info.noise_floor[1] =
+			    WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 1);
+			phyerr->rf_info.noise_floor[2] =
+			    WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 2);
+			phyerr->rf_info.noise_floor[3] =
+			    WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 3);
+
+			/* populate the rf info */
+			phyerr->rf_info.rssi_comb =
+			    WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr);
+
+			/* Need to unroll loop due to macro
+			 * constraints chain 0
+			 */
+			phyerr->rf_info.pc_rssi_info[0].rssi_pri20 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, PRI20);
+			phyerr->rf_info.pc_rssi_info[0].rssi_sec20 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC20);
+			phyerr->rf_info.pc_rssi_info[0].rssi_sec40 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC40);
+			phyerr->rf_info.pc_rssi_info[0].rssi_sec80 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC80);
+
+			/* chain 1 */
+			phyerr->rf_info.pc_rssi_info[1].rssi_pri20 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, PRI20);
+			phyerr->rf_info.pc_rssi_info[1].rssi_sec20 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC20);
+			phyerr->rf_info.pc_rssi_info[1].rssi_sec40 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC40);
+			phyerr->rf_info.pc_rssi_info[1].rssi_sec80 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC80);
+
+			/* chain 2 */
+			phyerr->rf_info.pc_rssi_info[2].rssi_pri20 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, PRI20);
+			phyerr->rf_info.pc_rssi_info[2].rssi_sec20 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC20);
+			phyerr->rf_info.pc_rssi_info[2].rssi_sec40 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC40);
+			phyerr->rf_info.pc_rssi_info[2].rssi_sec80 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC80);
+
+			/* chain 3 */
+			phyerr->rf_info.pc_rssi_info[3].rssi_pri20 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, PRI20);
+			phyerr->rf_info.pc_rssi_info[3].rssi_sec20 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC20);
+			phyerr->rf_info.pc_rssi_info[3].rssi_sec40 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC40);
+			phyerr->rf_info.pc_rssi_info[3].rssi_sec80 =
+			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC80);
+
+			phyerr->chan_info.center_freq1 =
+			    WMI_UNIFIED_FREQ_INFO_GET(&ev->hdr, 1);
+			phyerr->chan_info.center_freq2 =
+			    WMI_UNIFIED_FREQ_INFO_GET(&ev->hdr, 2);
+
+		}
+
+		/*
+		 * Advance the buffer pointer to the next PHY error.
+		 * buflen is the length of this payload, so we need to
+		 * advance past the current header _AND_ the payload.
+		 */
+		 n += sizeof(*ev) + ev->hdr.buf_len;
+	}
+	*buf_offset += n;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * spectral_phyerr_event_handler() - spectral phyerr event handler
+ * @handle: wma handle
+ * @data: data buffer
+ * @datalen: buffer length
+ *
+ * Return:  QDF_STATUS
+ */
+static QDF_STATUS spectral_phyerr_event_handler(void *handle,
+						uint8_t *data,
+						uint32_t datalen)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint16_t buf_offset, event_buf_len = 0;
+	wmi_single_phyerr_rx_event *ev;
+	wmi_host_phyerr_t phyerr;
+	struct target_if_spectral_rfqual_info rfqual_info;
+	struct target_if_spectral_chan_info chan_info;
+	struct target_if_spectral_acs_stats acs_stats;
+
+	if (NULL == wma) {
+		WMA_LOGE("%s:wma handle is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	memset(&phyerr, 0, sizeof(wmi_host_phyerr_t));
+	status = wmi_extract_comb_phyerr(wma->wmi_handle, data, datalen,
+					 &buf_offset, &phyerr);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("%s: extract comb phyerr failed", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ev = (wmi_single_phyerr_rx_event *)phyerr.bufp;
+	event_buf_len = phyerr.buf_len;
+	/* Loop over the bufp, extracting out phyerrors */
+	buf_offset = 0;
+	while (buf_offset < event_buf_len) {
+		if (wma_extract_single_phyerr_spectral(handle, ev,
+			event_buf_len, &buf_offset, &phyerr)) {
+			WMA_LOGE("%s: extract single phy err failed", __func__);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (phyerr.buf_len > 0) {
+			if (sizeof(phyerr.rf_info) > sizeof(rfqual_info))
+				qdf_mem_copy(&rfqual_info, &phyerr.rf_info,
+						sizeof(rfqual_info));
+			else
+				qdf_mem_copy(&rfqual_info, &phyerr.rf_info,
+						sizeof(phyerr.rf_info));
+
+			if (sizeof(phyerr.chan_info) > sizeof(chan_info))
+				qdf_mem_copy(&chan_info, &phyerr.chan_info,
+						sizeof(chan_info));
+			else
+				qdf_mem_copy(&chan_info, &phyerr.chan_info,
+						sizeof(phyerr.chan_info));
+
+			target_if_spectral_process_phyerr(wma->pdev, phyerr.bufp,
+							phyerr.buf_len,
+							&rfqual_info,
+							&chan_info,
+							phyerr.tsf64,
+							&acs_stats);
+		}
+	}
+
+	return status;
+}
+#else
+static QDF_STATUS
+wma_extract_single_phyerr_spectral(void *handle, void *evt_buf,
+				   uint16_t datalen,
+				   uint16_t *buf_offset,
+				   wmi_host_phyerr_t *phyerr)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS spectral_phyerr_event_handler(void *handle,
+					uint8_t *data, uint32_t datalen)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * dfs_phyerr_event_handler() - dfs phyerr event handler
+ * @handle: wma handle
+ * @data: data buffer
+ * @datalen: buffer length
+ * @fulltsf: 64 bit event TSF
+ *
+ * Function to process DFS phy errors.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS dfs_phyerr_event_handler(tp_wma_handle handle,
+					   uint8_t *data,
+					   uint32_t datalen,
+					   uint64_t fulltsf)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_lmac_if_dfs_rx_ops *dfs_rx_ops;
+	wmi_host_phyerr_t phyerr;
+	int8_t rssi_comb;
+	uint16_t buf_offset;
+
+	if (!handle->psoc) {
+		WMA_LOGE("%s: psoc is null", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	dfs_rx_ops = wlan_lmac_if_get_dfs_rx_ops(handle->psoc);
+	if (!dfs_rx_ops) {
+		WMA_LOGE("%s: dfs_rx_ops is null", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!dfs_rx_ops->dfs_process_phyerr) {
+		WMA_LOGE("%s: dfs_process_phyerr handler is null", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!handle->pdev) {
+		WMA_LOGE("%s: pdev is null", __func__);
+		return -EINVAL;
+	}
+
+	buf_offset = 0;
+	while (buf_offset < datalen) {
+		status = wmi_extract_single_phyerr(handle->wmi_handle, data, datalen,
+						   &buf_offset, &phyerr);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			/* wmi_extract_single_phyerr has logs */
+			return status;
+		}
+
+		rssi_comb = phyerr.rf_info.rssi_comb & 0xFF;
+		if (phyerr.buf_len > 0)
+			dfs_rx_ops->dfs_process_phyerr(handle->pdev,
+						       &phyerr.bufp[0],
+						       phyerr.buf_len,
+						       rssi_comb,
+						       rssi_comb,
+						       phyerr.tsf_timestamp,
+						       fulltsf);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_unified_phyerr_rx_event_handler() - phyerr event handler
+ * @handle: wma handle
+ * @data: data buffer
+ * @datalen: buffer length
+ *
+ * WMI Handler for WMI_PHYERR_EVENTID event from firmware.
+ * This handler is currently handling DFS and spectral scan
+ * phy errors.
+ *
+ * Return: 0 for success, other value for failure
+ */
+static int wma_unified_phyerr_rx_event_handler(void *handle,
+					       uint8_t *data,
+					       uint32_t datalen)
+{
+	/* phyerr handling is moved to cmn project
+	 * As WIN still uses handler registration in non-cmn code.
+	 * need complete testing of non offloaded DFS code before we enable
+	 * it in cmn code.
+	 **/
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	wmi_host_phyerr_t phyerr;
+	uint16_t buf_offset = 0;
+	wmi_single_phyerr_rx_event *ev;
+	uint16_t event_buf_len = 0;
+	wmi_host_phyerr_t phyerr2;
+	bool spectralscan = false;
+
+	if (!wma) {
+		WMA_LOGE("%s: wma handle is null", __func__);
+		return -EINVAL;
+	}
+
+	/* sanity check on data length */
+	status = wmi_extract_comb_phyerr(wma->wmi_handle, data, datalen,
+					 &buf_offset, &phyerr);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("%s: extract phyerr failed: %d", __func__, status);
+		return qdf_status_to_os_return(status);
+	}
+	ev = (wmi_single_phyerr_rx_event *)phyerr.bufp;
+	event_buf_len = phyerr.buf_len;
+	/* Loop over the bufp, extracting out phyerrors */
+	buf_offset = 0;
+	while (ev && (buf_offset < event_buf_len)) {
+		if (wma_extract_single_phyerr_spectral(handle, ev,
+						       event_buf_len,
+						       &buf_offset,
+						       &phyerr2)) {
+			WMA_LOGE("%s: extract single phy err failed", __func__);
+			return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
+		}
+		if ((buf_offset != 0) && (phyerr2.phy_err_code == 0x26 ||
+					  phyerr2.phy_err_code == 0x24)) {
+			spectralscan = true;
+		} else {
+			break;
+		}
+	}
+	if (spectralscan) {
+		status = spectral_phyerr_event_handler(wma, data, datalen);
+		return qdf_status_to_os_return(status);
+	}
+	/* handle different PHY Error conditions */
+	if (((phyerr.phy_err_mask0 & (WMI_PHY_ERROR_MASK0_RADAR |
+	    WMI_PHY_ERROR_MASK0_FALSE_RADAR_EXT |
+	    WMI_PHY_ERROR_MASK0_SPECTRAL_SCAN)) == 0)) {
+		WMA_LOGD("%s: Unknown phy error event", __func__);
+		return -EINVAL;
+	}
+
+	/* Handle Spectral or DFS PHY Error */
+	if (phyerr.phy_err_mask0 & (WMI_PHY_ERROR_MASK0_RADAR |
+	    WMI_PHY_ERROR_MASK0_FALSE_RADAR_EXT)) {
+		if (wma->is_dfs_offloaded) {
+			WMA_LOGD("%s: Unexpected phy error, dfs offloaded",
+				 __func__);
+			return -EINVAL;
+		}
+		status = dfs_phyerr_event_handler(wma,
+						  phyerr.bufp,
+						  phyerr.buf_len,
+						  phyerr.tsf64);
+	} else if (phyerr.phy_err_mask0 & (WMI_PHY_ERROR_MASK0_SPECTRAL_SCAN |
+		   WMI_PHY_ERROR_MASK0_FALSE_RADAR_EXT)) {
+		status = spectral_phyerr_event_handler(wma, data, datalen);
+	}
+
+	return qdf_status_to_os_return(status);
+}
+
+void wma_vdev_init(struct wma_txrx_node *vdev)
+{
+	qdf_wake_lock_create(&vdev->vdev_start_wakelock, "vdev_start");
+	qdf_wake_lock_create(&vdev->vdev_stop_wakelock, "vdev_stop");
+	qdf_wake_lock_create(&vdev->vdev_set_key_wakelock, "vdev_set_key");
+	vdev->is_waiting_for_key = false;
+}
+
+void wma_vdev_deinit(struct wma_txrx_node *vdev)
+{
+	struct beacon_info *bcn;
+	tp_wma_handle wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	/* validate the wma_handle */
+	if (!wma_handle) {
+		WMA_LOGE("%s: Invalid wma handle", __func__);
+		return;
+	}
+
+	bcn = vdev->beacon;
+	if (bcn) {
+		if (bcn->dma_mapped)
+			qdf_nbuf_unmap_single(wma_handle->qdf_dev,
+				bcn->buf, QDF_DMA_TO_DEVICE);
+		qdf_nbuf_free(bcn->buf);
+		qdf_mem_free(bcn);
+		vdev->beacon = NULL;
+	}
+
+	if (vdev->handle) {
+		qdf_mem_free(vdev->handle);
+		vdev->handle = NULL;
+	}
+
+	if (vdev->addBssStaContext) {
+		qdf_mem_free(vdev->addBssStaContext);
+		vdev->addBssStaContext = NULL;
+	}
+
+	if (vdev->staKeyParams) {
+		qdf_mem_free(vdev->staKeyParams);
+		vdev->staKeyParams = NULL;
+	}
+
+	if (vdev->del_staself_req) {
+		qdf_mem_free(vdev->del_staself_req);
+		vdev->del_staself_req = NULL;
+	}
+
+	if (vdev->stats_rsp) {
+		qdf_mem_free(vdev->stats_rsp);
+		vdev->stats_rsp = NULL;
+	}
+
+	if (vdev->psnr_req) {
+		qdf_mem_free(vdev->psnr_req);
+		vdev->psnr_req = NULL;
+	}
+
+	if (vdev->rcpi_req) {
+		qdf_mem_free(vdev->rcpi_req);
+		vdev->rcpi_req = NULL;
+	}
+
+	if (vdev->roam_scan_stats_req) {
+		struct sir_roam_scan_stats *req;
+
+		req = vdev->roam_scan_stats_req;
+		vdev->roam_scan_stats_req = NULL;
+		qdf_mem_free(req);
+	}
+
+	if (vdev->roam_synch_frame_ind.bcn_probe_rsp) {
+		qdf_mem_free(vdev->roam_synch_frame_ind.bcn_probe_rsp);
+		vdev->roam_synch_frame_ind.bcn_probe_rsp = NULL;
+	}
+
+	if (vdev->roam_synch_frame_ind.reassoc_req) {
+		qdf_mem_free(vdev->roam_synch_frame_ind.reassoc_req);
+		vdev->roam_synch_frame_ind.reassoc_req = NULL;
+	}
+
+	if (vdev->roam_synch_frame_ind.reassoc_rsp) {
+		qdf_mem_free(vdev->roam_synch_frame_ind.reassoc_rsp);
+		vdev->roam_synch_frame_ind.reassoc_rsp = NULL;
+	}
+
+	qdf_wake_lock_destroy(&vdev->vdev_start_wakelock);
+	qdf_wake_lock_destroy(&vdev->vdev_stop_wakelock);
+	qdf_wake_lock_destroy(&vdev->vdev_set_key_wakelock);
+	vdev->is_waiting_for_key = false;
+}
+
+/**
+ * wma_wmi_stop() - generic function to block WMI commands
+ * @return: None
+ */
+void wma_wmi_stop(void)
+{
+	tp_wma_handle wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if ((!wma_handle) || (!wma_handle->wmi_handle)) {
+		QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
+			  "wma_handle or wmi_handle is NULL\n");
+		return;
+	}
+	wmi_stop(wma_handle->wmi_handle);
+}
+
+#ifdef QCA_SUPPORT_CP_STATS
+static void wma_register_stats_events(wmi_unified_t wmi_handle) {}
+#else
+static void wma_register_stats_events(wmi_unified_t wmi_handle)
+{
+	wmi_unified_register_event_handler(wmi_handle,
+					   wmi_update_stats_event_id,
+					   wma_stats_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+}
+#endif
+
+#ifdef FEATURE_WLAN_APF
+static void wma_register_apf_events(tp_wma_handle wma_handle)
+{
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
+			  "wma_handle is NULL\n");
+		return;
+	}
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_apf_capability_info_event_id,
+					   wma_get_apf_caps_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_apf_get_vdev_work_memory_resp_event_id,
+				wma_apf_read_work_memory_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+}
+#else /* FEATURE_WLAN_APF */
+static void wma_register_apf_events(tp_wma_handle wma_handle)
+{
+}
+#endif /* FEATURE_WLAN_APF */
+
+/**
+ * wma_get_phy_mode_cb() - Callback to get current PHY Mode.
+ * @chan: channel number
+ * @chan_width: maximum channel width possible
+ * @phy_mode: PHY Mode
+ *
+ * Return: None
+ */
+static void wma_get_phy_mode_cb(uint8_t chan, uint32_t chan_width,
+				uint32_t *phy_mode)
+{
+	uint32_t dot11_mode;
+	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac) {
+		wma_err("MAC context is NULL");
+		*phy_mode = MODE_UNKNOWN;
+		return;
+	}
+
+	wlan_cfg_get_int(mac, WNI_CFG_DOT11_MODE, &dot11_mode);
+	*phy_mode = wma_chan_phy_mode(chan, chan_width, dot11_mode);
+}
+
+/**
+ * wma_open() - Allocate wma context and initialize it.
+ * @cds_context:  cds context
+ * @wma_tgt_cfg_cb: tgt config callback fun
+ * @radar_ind_cb: dfs radar indication callback
+ * @cds_cfg:  mac parameters
+ *
+ * Return: 0 on success, errno on failure
+ */
+QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
+		    wma_tgt_cfg_cb tgt_cfg_cb,
+		    struct cds_config_info *cds_cfg,
+		    uint32_t target_type)
+{
+	tp_wma_handle wma_handle;
+	HTC_HANDLE htc_handle;
+	qdf_device_t qdf_dev;
+	void *wmi_handle;
+	QDF_STATUS qdf_status;
+	struct wmi_unified_attach_params *params;
+	struct policy_mgr_wma_cbacks wma_cbacks;
+	struct target_psoc_info *tgt_psoc_info;
+	int i;
+	bool val = 0;
+	void *cds_context;
+	target_resource_config *wlan_res_cfg;
+	enum pmo_wow_enable_type wow_enable;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	cds_context = cds_get_global_context();
+	if (!cds_context) {
+		WMA_LOGE("%s: Invalid CDS context", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	g_wmi_version_info.major = __WMI_VER_MAJOR_;
+	g_wmi_version_info.minor = __WMI_VER_MINOR_;
+	g_wmi_version_info.revision = __WMI_REVISION_;
+
+	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	htc_handle = cds_get_context(QDF_MODULE_ID_HTC);
+
+	if (!htc_handle) {
+		WMA_LOGE("%s: Invalid HTC handle", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* Alloc memory for WMA Context */
+	qdf_status = cds_alloc_context(QDF_MODULE_ID_WMA,
+				       (void **)&wma_handle,
+				       sizeof(*wma_handle));
+
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Memory allocation failed for wma_handle",
+			 __func__);
+		return qdf_status;
+	}
+
+	qdf_mem_zero(wma_handle, sizeof(t_wma_handle));
+
+	if (target_if_alloc_psoc_tgt_info(psoc)) {
+		WMA_LOGE("%s target psoc info allocation failed", __func__);
+		qdf_status = QDF_STATUS_E_NOMEM;
+		goto err_free_wma_handle;
+	}
+
+	if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE) {
+#ifdef FEATURE_WLAN_EXTSCAN
+		qdf_wake_lock_create(&wma_handle->extscan_wake_lock,
+					"wlan_extscan_wl");
+#endif /* FEATURE_WLAN_EXTSCAN */
+		qdf_wake_lock_create(&wma_handle->wow_wake_lock,
+			"wlan_wow_wl");
+		qdf_wake_lock_create(&wma_handle->wow_auth_req_wl,
+			"wlan_auth_req_wl");
+		qdf_wake_lock_create(&wma_handle->wow_assoc_req_wl,
+			"wlan_assoc_req_wl");
+		qdf_wake_lock_create(&wma_handle->wow_deauth_rec_wl,
+			"wlan_deauth_rec_wl");
+		qdf_wake_lock_create(&wma_handle->wow_disassoc_rec_wl,
+			"wlan_disassoc_rec_wl");
+		qdf_wake_lock_create(&wma_handle->wow_ap_assoc_lost_wl,
+			"wlan_ap_assoc_lost_wl");
+		qdf_wake_lock_create(&wma_handle->wow_auto_shutdown_wl,
+			"wlan_auto_shutdown_wl");
+		qdf_wake_lock_create(&wma_handle->roam_ho_wl,
+			"wlan_roam_ho_wl");
+	}
+
+	qdf_status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_LEGACY_WMA_ID);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		WMA_LOGE("%s: PSOC get_ref fails", __func__);
+		goto err_get_psoc_ref;
+	}
+	wma_handle->psoc = psoc;
+
+	/* Open target_if layer and register wma callback */
+	wma_target_if_open(wma_handle);
+	target_if_open(wma_get_psoc_from_scn_handle);
+
+	/*
+	 * Allocate locally used params with its rx_ops member,
+	 * and free it immediately after used.
+	 */
+	params = qdf_mem_malloc(sizeof(*params) + sizeof(struct wmi_rx_ops));
+	if (!params) {
+		qdf_status = QDF_STATUS_E_NOMEM;
+		goto err_wma_handle;
+	}
+
+	params->rx_ops = (struct wmi_rx_ops *)(params + 1);
+	params->osdev = NULL;
+	params->target_type = WMI_TLV_TARGET;
+	params->use_cookie = false;
+	params->psoc = psoc;
+	params->max_commands = WMI_MAX_CMDS;
+	/* Attach mc_thread context processing function */
+	params->rx_ops->wma_process_fw_event_handler_cbk =
+						wma_process_fw_event_handler;
+
+	/* initialize tlv attach */
+	wmi_tlv_init();
+
+	/* attach the wmi */
+	wmi_handle = wmi_unified_attach(wma_handle, params);
+	qdf_mem_free(params);
+	if (!wmi_handle) {
+		WMA_LOGE("%s: failed to attach WMI", __func__);
+		qdf_status = QDF_STATUS_E_NOMEM;
+		goto err_wma_handle;
+	}
+
+	target_if_register_legacy_service_ready_cb(
+					wma_legacy_service_ready_event_handler);
+
+	WMA_LOGA("WMA --> wmi_unified_attach - success");
+
+	/* store the wmi handle in tgt_if_handle */
+	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
+
+	target_psoc_set_target_type(tgt_psoc_info, target_type);
+	/* Save the WMI & HTC handle */
+	target_psoc_set_wmi_hdl(tgt_psoc_info, wmi_handle);
+	wma_handle->wmi_handle = wmi_handle;
+	target_psoc_set_htc_hdl(tgt_psoc_info, htc_handle);
+	wma_handle->cds_context = cds_context;
+	wma_handle->qdf_dev = qdf_dev;
+	wma_handle->max_scan = cds_cfg->max_scan;
+
+	/* Register Converged Event handlers */
+	init_deinit_register_tgt_psoc_ev_handlers(psoc);
+
+	/* Initialize max_no_of_peers for wma_get_number_of_peers_supported() */
+	cds_cfg->max_station = wma_init_max_no_of_peers(wma_handle,
+							cds_cfg->max_station);
+
+	/* initialize default target config */
+	wlan_res_cfg = target_psoc_get_wlan_res_cfg(tgt_psoc_info);
+	if (!wlan_res_cfg) {
+		WMA_LOGE("%s: wlan_res_cfg is null", __func__);
+		qdf_status = QDF_STATUS_E_NOMEM;
+		goto err_wma_handle;
+	}
+
+	wma_set_default_tgt_config(wma_handle, wlan_res_cfg, cds_cfg);
+
+	qdf_status = wlan_mlme_get_tx_chainmask_cck(psoc, &val);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Failed to get tx_chainmask_cck", __func__);
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto err_wma_handle;
+	}
+	wma_handle->tx_chain_mask_cck = val;
+	wma_handle->self_gen_frm_pwr = cds_cfg->self_gen_frm_pwr;
+
+	cds_cfg->max_bssid = WMA_MAX_SUPPORTED_BSS;
+
+	wma_handle->max_station = cds_cfg->max_station;
+	wma_handle->max_bssid = cds_cfg->max_bssid;
+	wma_handle->ssdp = ucfg_pmo_is_ssdp_enabled(wma_handle->psoc);
+	wma_handle->enable_mc_list =
+		ucfg_pmo_is_mc_addr_list_enabled(wma_handle->psoc);
+	wma_handle->active_uc_apf_mode = cds_cfg->active_uc_apf_mode;
+	wma_handle->active_mc_bc_apf_mode = cds_cfg->active_mc_bc_apf_mode;
+	wma_handle->link_stats_results = NULL;
+#ifdef FEATURE_WLAN_RA_FILTERING
+	wma_handle->IsRArateLimitEnabled = cds_cfg->is_ra_ratelimit_enabled;
+	wma_handle->RArateLimitInterval = cds_cfg->ra_ratelimit_interval;
+#endif /* FEATURE_WLAN_RA_FILTERING */
+#ifdef WLAN_FEATURE_LPSS
+	wma_handle->is_lpass_enabled = cds_cfg->is_lpass_enabled;
+#endif
+	wma_set_nan_enable(wma_handle, cds_cfg);
+	wma_handle->interfaces = qdf_mem_malloc(sizeof(struct wma_txrx_node) *
+						wma_handle->max_bssid);
+	if (!wma_handle->interfaces) {
+		qdf_status = QDF_STATUS_E_NOMEM;
+		goto err_scn_context;
+	}
+
+	for (i = 0; i < wma_handle->max_bssid; ++i) {
+		wma_vdev_init(&wma_handle->interfaces[i]);
+		wma_handle->interfaces[i].delay_before_vdev_stop =
+			cds_cfg->delay_before_vdev_stop;
+	}
+	/* Register the debug print event handler */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					wmi_debug_print_event_id,
+					wma_unified_debug_print_event_handler,
+					WMA_RX_SERIALIZER_CTX);
+	/* Register profiling event Handler */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					wmi_wlan_profile_data_event_id,
+					wma_profile_data_report_event_handler,
+					WMA_RX_SERIALIZER_CTX);
+
+	wma_handle->tgt_cfg_update_cb = tgt_cfg_cb;
+	wma_handle->old_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX;
+	wma_handle->new_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX;
+	wma_handle->saved_chan.num_channels = 0;
+	wma_handle->fw_timeout_crash = cds_cfg->fw_timeout_crash;
+
+	qdf_status = qdf_mc_timer_init(&wma_handle->service_ready_ext_timer,
+					QDF_TIMER_TYPE_SW,
+					wma_service_ready_ext_evt_timeout,
+					wma_handle);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("Failed to initialize service ready ext timeout");
+		goto err_event_init;
+	}
+
+	qdf_status = qdf_event_create(&wma_handle->target_suspend);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: target suspend event initialization failed",
+			 __func__);
+		goto err_event_init;
+	}
+
+	/* Init Tx Frame Complete event */
+	qdf_status = qdf_event_create(&wma_handle->tx_frm_download_comp_event);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("%s: failed to init tx_frm_download_comp_event",
+			 __func__);
+		goto err_event_init;
+	}
+
+	/* Init tx queue empty check event */
+	qdf_status = qdf_event_create(&wma_handle->tx_queue_empty_event);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("%s: failed to init tx_queue_empty_event", __func__);
+		goto err_event_init;
+	}
+
+	qdf_status = qdf_event_create(&wma_handle->wma_resume_event);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: wma_resume_event initialization failed",
+			 __func__);
+		goto err_event_init;
+	}
+
+	qdf_status = cds_shutdown_notifier_register(wma_shutdown_notifier_cb,
+						    wma_handle);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Shutdown notifier register failed: %d",
+			 __func__, qdf_status);
+		goto err_event_init;
+	}
+
+	qdf_status = qdf_event_create(&wma_handle->runtime_suspend);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: runtime_suspend event initialization failed",
+			 __func__);
+		goto err_event_init;
+	}
+
+	qdf_status = qdf_event_create(&wma_handle->recovery_event);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: recovery event initialization failed", __func__);
+		goto err_event_init;
+	}
+
+	qdf_list_create(&wma_handle->vdev_resp_queue,
+		      MAX_ENTRY_VDEV_RESP_QUEUE);
+	qdf_spinlock_create(&wma_handle->vdev_respq_lock);
+	qdf_list_create(&wma_handle->wma_hold_req_queue,
+		      MAX_ENTRY_HOLD_REQ_QUEUE);
+	qdf_spinlock_create(&wma_handle->wma_hold_req_q_lock);
+	qdf_atomic_init(&wma_handle->is_wow_bus_suspended);
+
+	/* Register vdev start response event handler */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_vdev_start_resp_event_id,
+					   wma_vdev_start_resp_handler,
+					   WMA_RX_SERIALIZER_CTX);
+
+	/* Register vdev stop response event handler */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_vdev_stopped_event_id,
+					   wma_vdev_stop_resp_handler,
+					   WMA_RX_SERIALIZER_CTX);
+
+	/* register for STA kickout function */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_peer_sta_kickout_event_id,
+					   wma_peer_sta_kickout_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+
+	/* register for stats event */
+	wma_register_stats_events(wma_handle->wmi_handle);
+
+	/* register for stats response event */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_get_arp_stats_req_id,
+					   wma_get_arp_stats_handler,
+					   WMA_RX_SERIALIZER_CTX);
+
+	/* register for peer info response event */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_peer_stats_info_event_id,
+					   wma_peer_info_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+
+#ifdef WLAN_POWER_DEBUGFS
+	/* register for Chip Power stats event */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_pdev_chip_power_stats_event_id,
+				wma_unified_power_debug_stats_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+#endif
+
+	/* register for linkspeed response event */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_peer_estimated_linkspeed_event_id,
+					   wma_link_speed_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_oem_response_event_id,
+					   wma_oem_data_response_handler,
+					   WMA_RX_SERIALIZER_CTX);
+#endif /* FEATURE_OEM_DATA_SUPPORT */
+
+	/* Register peer change event handler */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_peer_state_event_id,
+					   wma_peer_state_change_event_handler,
+					   WMA_RX_WORK_CTX);
+
+	/* Register beacon tx complete event id. The event is required
+	 * for sending channel switch announcement frames
+	 */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					wmi_offload_bcn_tx_status_event_id,
+					wma_unified_bcntx_status_event_handler,
+					WMA_RX_SERIALIZER_CTX);
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_update_vdev_rate_stats_event_id,
+					   wma_link_status_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_roam_scan_stats_event_id,
+					   wma_roam_scan_stats_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+	/* Register event handler for processing Link Layer Stats
+	 * response from the FW
+	 */
+	wma_register_ll_stats_event_handler(wma_handle);
+
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+	wmi_set_tgt_assert(wma_handle->wmi_handle,
+			   cds_cfg->force_target_assert_enabled);
+	/* Firmware debug log */
+	qdf_status = dbglog_init(wma_handle->wmi_handle);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Firmware Dbglog initialization failed", __func__);
+		goto err_dbglog_init;
+	}
+
+	/*
+	 * Update Powersave mode
+	 * 1 - Legacy Powersave + Deepsleep Disabled
+	 * 2 - QPower + Deepsleep Disabled
+	 * 3 - Legacy Powersave + Deepsleep Enabled
+	 * 4 - QPower + Deepsleep Enabled
+	 */
+	wma_handle->powersave_mode =
+			ucfg_pmo_power_save_offload_enabled(wma_handle->psoc);
+	wma_handle->staMaxLIModDtim = cds_cfg->sta_maxlimod_dtim;
+	wma_handle->staModDtim = ucfg_pmo_get_sta_mod_dtim(wma_handle->psoc);
+	wma_handle->staDynamicDtim =
+			ucfg_pmo_get_sta_dynamic_dtim(wma_handle->psoc);
+
+	/*
+	 * Value of cds_cfg->wow_enable can be,
+	 * 0 - Disable both magic pattern match and pattern byte match.
+	 * 1 - Enable magic pattern match on all interfaces.
+	 * 2 - Enable pattern byte match on all interfaces.
+	 * 3 - Enable both magic patter and pattern byte match on
+	 *     all interfaces.
+	 */
+	wow_enable = ucfg_pmo_get_wow_enable(wma_handle->psoc);
+	wma_handle->wow.magic_ptrn_enable =
+		(wow_enable & 0x01) ? true : false;
+	wma_handle->ptrn_match_enable_all_vdev =
+		(wow_enable & 0x02) ? true : false;
+
+	/* register for install key completion event */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_vdev_install_key_complete_event_id,
+				wma_vdev_install_key_complete_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+#ifdef WLAN_FEATURE_NAN
+	/* register for nan response event */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_nan_event_id,
+					   wma_nan_rsp_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+#endif /* WLAN_FEATURE_NAN */
+
+#ifdef WLAN_FEATURE_STATS_EXT
+	/* register for extended stats event */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_stats_ext_event_id,
+					   wma_stats_ext_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+#endif /* WLAN_FEATURE_STATS_EXT */
+#ifdef FEATURE_WLAN_EXTSCAN
+	wma_register_extscan_event_handler(wma_handle);
+#endif /* WLAN_FEATURE_STATS_EXT */
+
+	WMA_LOGD("%s: Exit", __func__);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_roam_synch_event_id,
+					   wma_roam_synch_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				   wmi_roam_synch_frame_event_id,
+				   wma_roam_synch_frame_event_handler,
+				   WMA_RX_SERIALIZER_CTX);
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_rssi_breach_event_id,
+				wma_rssi_breached_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+
+	qdf_wake_lock_create(&wma_handle->wmi_cmd_rsp_wake_lock,
+					"wlan_fw_rsp_wakelock");
+	qdf_runtime_lock_init(&wma_handle->wmi_cmd_rsp_runtime_lock);
+
+	/* Register peer assoc conf event handler */
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_peer_assoc_conf_event_id,
+					   wma_peer_assoc_conf_handler,
+					   WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_vdev_delete_resp_event_id,
+					   wma_vdev_delete_handler,
+					   WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_peer_delete_response_event_id,
+					   wma_peer_delete_handler,
+					   WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_chan_info_event_id,
+					   wma_chan_info_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_dbg_mesg_flush_complete_event_id,
+				wma_flush_complete_evt_handler,
+				WMA_RX_WORK_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_report_rx_aggr_failure_event_id,
+				wma_rx_aggr_failure_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+
+	wma_handle->ito_repeat_count = cds_cfg->ito_repeat_count;
+	wma_handle->bandcapability = cds_cfg->bandcapability;
+
+	/* Register PWR_SAVE_FAIL event only in case of recovery(1) */
+	if (ucfg_pmo_get_auto_power_fail_mode(wma_handle->psoc) ==
+	    PMO_FW_TO_SEND_WOW_IND_ON_PWR_FAILURE) {
+		wmi_unified_register_event_handler(wma_handle->wmi_handle,
+			wmi_pdev_chip_pwr_save_failure_detect_event_id,
+			wma_chip_power_save_failure_detected_handler,
+			WMA_RX_WORK_CTX);
+	}
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_pdev_div_rssi_antid_event_id,
+				wma_pdev_div_info_evt_handler,
+				WMA_RX_WORK_CTX);
+
+
+	wma_register_debug_callback();
+	wifi_pos_register_get_phy_mode_cb(wma_handle->psoc,
+					  wma_get_phy_mode_cb);
+
+	/* Register callback with PMO so PMO can update the vdev pause bitmap*/
+	pmo_register_pause_bitmap_notifier(wma_handle->psoc,
+		wma_vdev_update_pause_bitmap);
+	pmo_register_get_pause_bitmap(wma_handle->psoc,
+		wma_vdev_get_pause_bitmap);
+	pmo_register_get_vdev_dp_handle(wma_handle->psoc,
+					wma_vdev_get_vdev_dp_handle);
+	pmo_register_is_device_in_low_pwr_mode(wma_handle->psoc,
+		wma_vdev_is_device_in_low_pwr_mode);
+	pmo_register_get_cfg_int_callback(wma_handle->psoc,
+					  wma_vdev_get_cfg_int);
+	pmo_register_get_dtim_period_callback(wma_handle->psoc,
+					      wma_vdev_get_dtim_period);
+	pmo_register_get_beacon_interval_callback(wma_handle->psoc,
+						  wma_vdev_get_beacon_interval);
+	wma_cbacks.wma_get_connection_info = wma_get_connection_info;
+	qdf_status = policy_mgr_register_wma_cb(wma_handle->psoc, &wma_cbacks);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("Failed to register wma cb with Policy Manager");
+	}
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+			wmi_phyerr_event_id,
+			wma_unified_phyerr_rx_event_handler,
+			WMA_RX_WORK_CTX);
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+			wmi_sap_obss_detection_report_event_id,
+			wma_vdev_obss_detection_info_handler,
+			WMA_RX_SERIALIZER_CTX);
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+			wmi_obss_color_collision_report_event_id,
+			wma_vdev_bss_color_collision_info_handler,
+			WMA_RX_WORK_CTX);
+
+#ifdef WLAN_SUPPORT_TWT
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_twt_enable_complete_event_id,
+					   wma_twt_en_complete_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+#endif
+
+	wma_register_apf_events(wma_handle);
+
+	return QDF_STATUS_SUCCESS;
+
+err_dbglog_init:
+	qdf_wake_lock_destroy(&wma_handle->wmi_cmd_rsp_wake_lock);
+	qdf_runtime_lock_deinit(&wma_handle->wmi_cmd_rsp_runtime_lock);
+	qdf_spinlock_destroy(&wma_handle->vdev_respq_lock);
+	qdf_spinlock_destroy(&wma_handle->wma_hold_req_q_lock);
+err_event_init:
+	wmi_unified_unregister_event_handler(wma_handle->wmi_handle,
+					     wmi_debug_print_event_id);
+
+	for (i = 0; i < wma_handle->max_bssid; ++i)
+		wma_vdev_deinit(&wma_handle->interfaces[i]);
+
+	qdf_mem_free(wma_handle->interfaces);
+
+err_scn_context:
+	qdf_mem_free(((struct cds_context *) cds_context)->cfg_ctx);
+	((struct cds_context *)cds_context)->cfg_ctx = NULL;
+	OS_FREE(wmi_handle);
+
+err_wma_handle:
+	target_if_close();
+	wlan_objmgr_psoc_release_ref(psoc, WLAN_LEGACY_WMA_ID);
+err_get_psoc_ref:
+	target_if_free_psoc_tgt_info(psoc);
+	if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE) {
+#ifdef FEATURE_WLAN_EXTSCAN
+		qdf_wake_lock_destroy(&wma_handle->extscan_wake_lock);
+#endif /* FEATURE_WLAN_EXTSCAN */
+		qdf_wake_lock_destroy(&wma_handle->wow_wake_lock);
+		qdf_wake_lock_destroy(&wma_handle->wow_auth_req_wl);
+		qdf_wake_lock_destroy(&wma_handle->wow_assoc_req_wl);
+		qdf_wake_lock_destroy(&wma_handle->wow_deauth_rec_wl);
+		qdf_wake_lock_destroy(&wma_handle->wow_disassoc_rec_wl);
+		qdf_wake_lock_destroy(&wma_handle->wow_ap_assoc_lost_wl);
+		qdf_wake_lock_destroy(&wma_handle->wow_auto_shutdown_wl);
+		qdf_wake_lock_destroy(&wma_handle->roam_ho_wl);
+	}
+err_free_wma_handle:
+	cds_free_context(QDF_MODULE_ID_WMA, wma_handle);
+
+	WMA_LOGD("%s: Exit", __func__);
+
+	return qdf_status;
+}
+
+/**
+ * wma_pre_start() - wma pre start
+ *
+ * Return: 0 on success, errno on failure
+ */
+QDF_STATUS wma_pre_start(void)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tp_wma_handle wma_handle;
+	struct scheduler_msg wma_msg = { 0 };
+	void *htc_handle;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	/* Validate the wma_handle */
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: invalid wma handle", __func__);
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto end;
+	}
+
+	htc_handle = lmac_get_htc_hdl(wma_handle->psoc);
+	if (!htc_handle) {
+		WMA_LOGE("%s: invalid htc handle", __func__);
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto end;
+	}
+
+	/* Open endpoint for ctrl path - WMI <--> HTC */
+	qdf_status = wmi_unified_connect_htc_service(wma_handle->wmi_handle,
+						     htc_handle);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: wmi_unified_connect_htc_service", __func__);
+		if (!cds_is_fw_down())
+			QDF_BUG(0);
+
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto end;
+	}
+
+	WMA_LOGD("WMA --> wmi_unified_connect_htc_service - success");
+
+	/* Trigger the CFG DOWNLOAD */
+	wma_msg.type = WNI_CFG_DNLD_REQ;
+	wma_msg.bodyptr = NULL;
+	wma_msg.bodyval = 0;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_WMA, &wma_msg);
+	if (QDF_STATUS_SUCCESS != qdf_status) {
+		WMA_LOGE("%s: Failed to post WNI_CFG_DNLD_REQ msg", __func__);
+		QDF_ASSERT(0);
+		qdf_status = QDF_STATUS_E_FAILURE;
+	}
+end:
+	WMA_LOGD("%s: Exit", __func__);
+	return qdf_status;
+}
+
+void wma_send_msg_by_priority(tp_wma_handle wma_handle, uint16_t msg_type,
+		 void *body_ptr, uint32_t body_val, bool is_high_priority)
+{
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+
+	msg.type = msg_type;
+	msg.bodyval = body_val;
+	msg.bodyptr = body_ptr;
+	msg.flush_callback = wma_discard_fw_event;
+
+	status = scheduler_post_msg_by_priority(QDF_MODULE_ID_PE,
+					       &msg, is_high_priority);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		WMA_LOGE("Failed to post msg %d to PE", msg_type);
+		if (body_ptr)
+			qdf_mem_free(body_ptr);
+	}
+}
+
+
+void wma_send_msg(tp_wma_handle wma_handle, uint16_t msg_type,
+			 void *body_ptr, uint32_t body_val)
+{
+	wma_send_msg_by_priority(wma_handle, msg_type,
+				body_ptr, body_val, false);
+}
+
+void wma_send_msg_high_priority(tp_wma_handle wma_handle, uint16_t msg_type,
+			 void *body_ptr, uint32_t body_val)
+{
+	wma_send_msg_by_priority(wma_handle, msg_type,
+				body_ptr, body_val, true);
+}
+
+/**
+ * wma_set_base_macaddr_indicate() - set base mac address in fw
+ * @wma_handle: wma handle
+ * @customAddr: base mac address
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_set_base_macaddr_indicate(tp_wma_handle wma_handle,
+					 tSirMacAddr *customAddr)
+{
+	int err;
+
+	err = wmi_unified_set_base_macaddr_indicate_cmd(wma_handle->wmi_handle,
+				     (uint8_t *)customAddr);
+	if (err)
+		return -EIO;
+	WMA_LOGD("Base MAC Addr: " MAC_ADDRESS_STR,
+		 MAC_ADDR_ARRAY((*customAddr)));
+
+	return 0;
+}
+
+/**
+ * wma_log_supported_evt_handler() - Enable/Disable FW diag/log events
+ * @handle: WMA handle
+ * @event:  Event received from FW
+ * @len:    Length of the event
+ *
+ * Enables the low frequency events and disables the high frequency
+ * events. Bit 17 indicates if the event if low/high frequency.
+ * 1 - high frequency, 0 - low frequency
+ *
+ * Return: 0 on successfully enabling/disabling the events
+ */
+static int wma_log_supported_evt_handler(void *handle,
+		uint8_t *event,
+		uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	if (wmi_unified_log_supported_evt_cmd(wma->wmi_handle,
+				event, len))
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * wma_pdev_set_hw_mode_resp_evt_handler() - Set HW mode resp evt handler
+ * @handle: WMI handle
+ * @event:  Event recevied from FW
+ * @len:    Length of the event
+ *
+ * Event handler for WMI_PDEV_SET_HW_MODE_RESP_EVENTID that is sent to host
+ * driver in response to a WMI_PDEV_SET_HW_MODE_CMDID being sent to WLAN
+ * firmware
+ *
+ * Return: QDF_STATUS
+ */
+static int wma_pdev_set_hw_mode_resp_evt_handler(void *handle,
+		uint8_t *event,
+		uint32_t len)
+{
+	WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf;
+	wmi_pdev_set_hw_mode_response_event_fixed_param *wmi_event;
+	wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry;
+	uint32_t i;
+	struct sir_set_hw_mode_resp *hw_mode_resp;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	if (!wma) {
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+		/* Since WMA handle itself is NULL, we cannot send fail
+		 * response back to LIM here
+		 */
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+	wma_remove_req(wma, 0, WMA_PDEV_SET_HW_MODE_RESP);
+
+	hw_mode_resp = qdf_mem_malloc(sizeof(*hw_mode_resp));
+	if (!hw_mode_resp) {
+		/* Since this memory allocation itself failed, we cannot
+		 * send fail response back to LIM here
+		 */
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("Invalid WMI_PDEV_SET_HW_MODE_RESP_EVENTID event");
+		/* Need to send response back to upper layer to free
+		 * active command list
+		 */
+		goto fail;
+	}
+	if (param_buf->fixed_param->num_vdev_mac_entries >=
+						MAX_VDEV_SUPPORTED) {
+		WMA_LOGE("num_vdev_mac_entries crossed max value");
+		goto fail;
+	}
+
+	wmi_event = param_buf->fixed_param;
+	if (wmi_event->num_vdev_mac_entries >
+	    param_buf->num_wmi_pdev_set_hw_mode_response_vdev_mac_mapping) {
+		WMA_LOGE("Invalid num_vdev_mac_entries: %d",
+				wmi_event->num_vdev_mac_entries);
+		goto fail;
+	}
+	hw_mode_resp->status = wmi_event->status;
+	hw_mode_resp->cfgd_hw_mode_index = wmi_event->cfgd_hw_mode_index;
+	hw_mode_resp->num_vdev_mac_entries = wmi_event->num_vdev_mac_entries;
+
+	WMA_LOGD("%s: status:%d cfgd_hw_mode_index:%d num_vdev_mac_entries:%d",
+			__func__, wmi_event->status,
+			wmi_event->cfgd_hw_mode_index,
+			wmi_event->num_vdev_mac_entries);
+	vdev_mac_entry =
+		param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping;
+
+	/* Store the vdev-mac map in WMA and prepare to send to PE  */
+	for (i = 0; i < wmi_event->num_vdev_mac_entries; i++) {
+		uint32_t vdev_id, mac_id, pdev_id;
+
+		vdev_id = vdev_mac_entry[i].vdev_id;
+		pdev_id = vdev_mac_entry[i].pdev_id;
+		if (pdev_id == WMI_PDEV_ID_SOC) {
+			WMA_LOGE("%s: soc level id received for mac id)",
+				 __func__);
+			goto fail;
+		}
+		if (vdev_id >= wma->max_bssid) {
+			WMA_LOGE("%s: vdev_id: %d is invalid, max_bssid: %d",
+				 __func__, vdev_id, wma->max_bssid);
+			goto fail;
+		}
+
+		mac_id = WMA_PDEV_TO_MAC_MAP(vdev_mac_entry[i].pdev_id);
+
+		WMA_LOGD("%s: vdev_id:%d mac_id:%d",
+			__func__, vdev_id, mac_id);
+
+		hw_mode_resp->vdev_mac_map[i].vdev_id = vdev_id;
+		hw_mode_resp->vdev_mac_map[i].mac_id = mac_id;
+		wma_update_intf_hw_mode_params(vdev_id, mac_id,
+				wmi_event->cfgd_hw_mode_index);
+	}
+
+	if (hw_mode_resp->status == SET_HW_MODE_STATUS_OK) {
+		if (WMA_DEFAULT_HW_MODE_INDEX == wma->new_hw_mode_index) {
+			wma->new_hw_mode_index = wmi_event->cfgd_hw_mode_index;
+		} else {
+			wma->old_hw_mode_index = wma->new_hw_mode_index;
+			wma->new_hw_mode_index = wmi_event->cfgd_hw_mode_index;
+		}
+		policy_mgr_update_hw_mode_index(wma->psoc,
+		wmi_event->cfgd_hw_mode_index);
+	}
+
+	WMA_LOGD("%s: Updated: old_hw_mode_index:%d new_hw_mode_index:%d",
+		__func__, wma->old_hw_mode_index, wma->new_hw_mode_index);
+
+	wma_send_msg(wma, SIR_HAL_PDEV_SET_HW_MODE_RESP,
+		     (void *) hw_mode_resp, 0);
+
+	return QDF_STATUS_SUCCESS;
+
+fail:
+	WMA_LOGE("%s: Sending fail response to LIM", __func__);
+	hw_mode_resp->status = SET_HW_MODE_STATUS_ECANCELED;
+	hw_mode_resp->cfgd_hw_mode_index = 0;
+	hw_mode_resp->num_vdev_mac_entries = 0;
+	wma_send_msg(wma, SIR_HAL_PDEV_SET_HW_MODE_RESP,
+			(void *) hw_mode_resp, 0);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * wma_process_pdev_hw_mode_trans_ind() - Process HW mode transition info
+ *
+ * @handle: WMA handle
+ * @fixed_param: Event fixed parameters
+ * @vdev_mac_entry - vdev mac entry
+ * @hw_mode_trans_ind - Buffer to store parsed information
+ *
+ * Parses fixed_param, vdev_mac_entry and fills in the information into
+ * hw_mode_trans_ind and wma
+ *
+ * Return: None
+ */
+void wma_process_pdev_hw_mode_trans_ind(void *handle,
+	wmi_pdev_hw_mode_transition_event_fixed_param *fixed_param,
+	wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry,
+	struct sir_hw_mode_trans_ind *hw_mode_trans_ind)
+{
+	uint32_t i;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	if (fixed_param->num_vdev_mac_entries > MAX_VDEV_SUPPORTED) {
+		WMA_LOGE("Number of Vdev mac entries %d exceeded"
+			 " max vdev supported %d",
+			 fixed_param->num_vdev_mac_entries,
+			 MAX_VDEV_SUPPORTED);
+		return;
+	}
+	hw_mode_trans_ind->old_hw_mode_index = fixed_param->old_hw_mode_index;
+	hw_mode_trans_ind->new_hw_mode_index = fixed_param->new_hw_mode_index;
+	hw_mode_trans_ind->num_vdev_mac_entries =
+					fixed_param->num_vdev_mac_entries;
+	WMA_LOGD("%s: old_hw_mode_index:%d new_hw_mode_index:%d entries=%d",
+		__func__, fixed_param->old_hw_mode_index,
+		fixed_param->new_hw_mode_index,
+		fixed_param->num_vdev_mac_entries);
+
+	/* Store the vdev-mac map in WMA and send to policy manager */
+	for (i = 0; i < fixed_param->num_vdev_mac_entries; i++) {
+		uint32_t vdev_id, mac_id, pdev_id;
+
+		vdev_id = vdev_mac_entry[i].vdev_id;
+		pdev_id = vdev_mac_entry[i].pdev_id;
+
+		if (pdev_id == WMI_PDEV_ID_SOC) {
+			WMA_LOGE("%s: soc level id received for mac id)",
+				 __func__);
+			return;
+		}
+		if (vdev_id >= wma->max_bssid) {
+			WMA_LOGE("%s: vdev_id: %d is invalid, max_bssid: %d",
+				 __func__, vdev_id, wma->max_bssid);
+			return;
+		}
+
+		mac_id = WMA_PDEV_TO_MAC_MAP(vdev_mac_entry[i].pdev_id);
+
+		WMA_LOGE("%s: vdev_id:%d mac_id:%d",
+				__func__, vdev_id, mac_id);
+
+		hw_mode_trans_ind->vdev_mac_map[i].vdev_id = vdev_id;
+		hw_mode_trans_ind->vdev_mac_map[i].mac_id = mac_id;
+		wma_update_intf_hw_mode_params(vdev_id, mac_id,
+				fixed_param->new_hw_mode_index);
+	}
+	wma->old_hw_mode_index = fixed_param->old_hw_mode_index;
+	wma->new_hw_mode_index = fixed_param->new_hw_mode_index;
+	policy_mgr_update_new_hw_mode_index(wma->psoc,
+		fixed_param->new_hw_mode_index);
+	policy_mgr_update_old_hw_mode_index(wma->psoc,
+		fixed_param->old_hw_mode_index);
+
+	WMA_LOGD("%s: Updated: old_hw_mode_index:%d new_hw_mode_index:%d",
+		__func__, wma->old_hw_mode_index, wma->new_hw_mode_index);
+}
+
+/**
+ * wma_pdev_hw_mode_transition_evt_handler() - HW mode transition evt handler
+ * @handle: WMI handle
+ * @event:  Event recevied from FW
+ * @len:    Length of the event
+ *
+ * Event handler for WMI_PDEV_HW_MODE_TRANSITION_EVENTID that indicates an
+ * asynchronous hardware mode transition. This event notifies the host driver
+ * that firmware independently changed the hardware mode for some reason, such
+ * as Coex, LFR 3.0, etc
+ *
+ * Return: Success on receiving valid params from FW
+ */
+static int wma_pdev_hw_mode_transition_evt_handler(void *handle,
+		uint8_t *event,
+		uint32_t len)
+{
+	WMI_PDEV_HW_MODE_TRANSITION_EVENTID_param_tlvs *param_buf;
+	wmi_pdev_hw_mode_transition_event_fixed_param *wmi_event;
+	wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry;
+	struct sir_hw_mode_trans_ind *hw_mode_trans_ind;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	if (!wma) {
+		/* This is an async event. So, not sending any event to LIM */
+		WMA_LOGE("Invalid WMA handle");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	param_buf = (WMI_PDEV_HW_MODE_TRANSITION_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		/* This is an async event. So, not sending any event to LIM */
+		WMA_LOGE("Invalid WMI_PDEV_HW_MODE_TRANSITION_EVENTID event");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (param_buf->fixed_param->num_vdev_mac_entries > MAX_VDEV_SUPPORTED) {
+		WMA_LOGE("num_vdev_mac_entries: %d crossed max value: %d",
+			param_buf->fixed_param->num_vdev_mac_entries,
+			MAX_VDEV_SUPPORTED);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hw_mode_trans_ind = qdf_mem_malloc(sizeof(*hw_mode_trans_ind));
+	if (!hw_mode_trans_ind)
+		return QDF_STATUS_E_NOMEM;
+
+	wmi_event = param_buf->fixed_param;
+	vdev_mac_entry =
+		param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping;
+	if (wmi_event->num_vdev_mac_entries >
+	    param_buf->num_wmi_pdev_set_hw_mode_response_vdev_mac_mapping) {
+		WMA_LOGE("Invalid num_vdev_mac_entries: %d",
+			 wmi_event->num_vdev_mac_entries);
+		qdf_mem_free(hw_mode_trans_ind);
+		return -EINVAL;
+	}
+	wma_process_pdev_hw_mode_trans_ind(wma, wmi_event, vdev_mac_entry,
+		hw_mode_trans_ind);
+	/* Pass the message to PE */
+	wma_send_msg(wma, SIR_HAL_PDEV_HW_MODE_TRANS_IND,
+		     (void *) hw_mode_trans_ind, 0);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_pdev_set_dual_mode_config_resp_evt_handler() - Dual mode evt handler
+ * @handle: WMI handle
+ * @event:  Event received from FW
+ * @len:    Length of the event
+ *
+ * Notifies the host driver of the completion or failure of a
+ * WMI_PDEV_SET_MAC_CONFIG_CMDID command. This event would be returned to
+ * the host driver once the firmware has completed a reconfiguration of the Scan
+ * and FW mode configuration. This changes could include entering or leaving a
+ * dual mac configuration for either scan and/or more permanent firmware mode.
+ *
+ * Return: Success on receiving valid params from FW
+ */
+static int wma_pdev_set_dual_mode_config_resp_evt_handler(void *handle,
+		uint8_t *event,
+		uint32_t len)
+{
+	WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID_param_tlvs *param_buf;
+	wmi_pdev_set_mac_config_response_event_fixed_param *wmi_event;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	struct sir_dual_mac_config_resp *dual_mac_cfg_resp;
+
+	if (!wma) {
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+		/* Since the WMA handle is NULL, we cannot send resp to LIM.
+		 * So, returning from here.
+		 */
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+	wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+	wma_remove_req(wma, 0, WMA_PDEV_MAC_CFG_RESP);
+
+	dual_mac_cfg_resp = qdf_mem_malloc(sizeof(*dual_mac_cfg_resp));
+	if (!dual_mac_cfg_resp)
+		/* Since the mem alloc failed, we cannot send resp to LIM.
+		 * So, returning from here.
+		 */
+		return QDF_STATUS_E_NULL_VALUE;
+
+	param_buf = (WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID_param_tlvs *)
+		event;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid event", __func__);
+		goto fail;
+	}
+
+	wmi_event = param_buf->fixed_param;
+	WMA_LOGD("%s: status:%d", __func__, wmi_event->status);
+	dual_mac_cfg_resp->status = wmi_event->status;
+
+	if (SET_HW_MODE_STATUS_OK == dual_mac_cfg_resp->status) {
+		policy_mgr_update_dbs_scan_config(wma->psoc);
+		policy_mgr_update_dbs_fw_config(wma->psoc);
+	}
+
+	/* Pass the message to PE */
+	wma_send_msg(wma, SIR_HAL_PDEV_MAC_CFG_RESP,
+			(void *) dual_mac_cfg_resp, 0);
+
+	return QDF_STATUS_SUCCESS;
+
+fail:
+	WMA_LOGE("%s: Sending fail response to LIM", __func__);
+	dual_mac_cfg_resp->status = SET_HW_MODE_STATUS_ECANCELED;
+	wma_send_msg(wma, SIR_HAL_PDEV_MAC_CFG_RESP,
+			(void *) dual_mac_cfg_resp, 0);
+
+	return QDF_STATUS_E_FAILURE;
+
+}
+
+/**
+ * wma_send_time_stamp_sync_cmd() - timer callback send timestamp to
+ * firmware to sync with host.
+ * @wma_handle: wma handle
+ *
+ * Return: void
+ */
+static void wma_send_time_stamp_sync_cmd(void *data)
+{
+	tp_wma_handle wma_handle;
+	QDF_STATUS qdf_status;
+
+	wma_handle = (tp_wma_handle) data;
+
+	wmi_send_time_stamp_sync_cmd_tlv(wma_handle->wmi_handle);
+
+	/* Start/Restart the timer */
+	qdf_status = qdf_mc_timer_start(&wma_handle->wma_fw_time_sync_timer,
+				       WMA_FW_TIME_SYNC_TIMER);
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		WMA_LOGE("Failed to start the firmware time sync timer");
+}
+
+#ifdef WLAN_CONV_SPECTRAL_ENABLE
+static void wma_register_spectral_cmds(tp_wma_handle wma_handle)
+{
+	struct wmi_spectral_cmd_ops cmd_ops;
+
+	cmd_ops.wmi_spectral_configure_cmd_send =
+			wmi_unified_vdev_spectral_configure_cmd_send;
+	cmd_ops.wmi_spectral_enable_cmd_send =
+			wmi_unified_vdev_spectral_enable_cmd_send;
+	wlan_register_wmi_spectral_cmd_ops(wma_handle->pdev, &cmd_ops);
+}
+#else
+static void wma_register_spectral_cmds(tp_wma_handle wma_handle)
+{
+}
+#endif
+/**
+ * wma_start() - wma start function.
+ *               Initialize event handlers and timers.
+ *
+ * Return: 0 on success, QDF Error on failure
+ */
+QDF_STATUS wma_start(void)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tp_wma_handle wma_handle;
+	int status;
+	struct wmi_unified *wmi_handle;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	/* validate the wma_handle */
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: Invalid wma handle", __func__);
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto end;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(wma_handle->psoc);
+	if (!wmi_handle) {
+		WMA_LOGE("%s: Invalid wmi handle", __func__);
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto end;
+	}
+
+	status = wmi_unified_register_event_handler(wmi_handle,
+						    wmi_roam_event_id,
+						    wma_roam_event_callback,
+						    WMA_RX_SERIALIZER_CTX);
+	if (0 != status) {
+		WMA_LOGE("%s: Failed to register Roam callback", __func__);
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	status = wmi_unified_register_event_handler(wmi_handle,
+						    wmi_wow_wakeup_host_event_id,
+						    wma_wow_wakeup_host_event,
+						    WMA_RX_TASKLET_CTX);
+	if (status) {
+		WMA_LOGE("%s: Failed to register wow wakeup host event handler",
+			 __func__);
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	if (wma_d0_wow_is_supported()) {
+		status = wmi_unified_register_event_handler(
+				wmi_handle,
+				wmi_d0_wow_disable_ack_event_id,
+				wma_d0_wow_disable_ack_event,
+				WMA_RX_TASKLET_CTX);
+		if (status) {
+			WMA_LOGE("%s: Failed to register d0wow disable ack"
+				 " event handler", __func__);
+			qdf_status = QDF_STATUS_E_FAILURE;
+			goto end;
+		}
+	}
+
+	status = wmi_unified_register_event_handler(wmi_handle,
+				wmi_pdev_resume_event_id,
+				wma_pdev_resume_event_handler,
+				WMA_RX_TASKLET_CTX);
+	if (status) {
+		WMA_LOGE("%s: Failed to register PDEV resume event handler",
+			 __func__);
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \
+	defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(CONFIG_HL_SUPPORT)
+	WMA_LOGD("MCC TX Pause Event Handler register");
+	status = wmi_unified_register_event_handler(wmi_handle,
+					wmi_tx_pause_event_id,
+					wma_mcc_vdev_tx_pause_evt_handler,
+					WMA_RX_TASKLET_CTX);
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+
+	WMA_LOGD("Registering SAR2 response handler");
+	status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
+						wmi_wlan_sar2_result_event_id,
+						wma_sar_rsp_evt_handler,
+						WMA_RX_SERIALIZER_CTX);
+	if (status) {
+		WMA_LOGE("Failed to register sar response event cb");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+	WMA_LOGD("Registering auto shutdown handler");
+	status = wmi_unified_register_event_handler(wmi_handle,
+						wmi_host_auto_shutdown_event_id,
+						wma_auto_shutdown_event_handler,
+						WMA_RX_SERIALIZER_CTX);
+	if (status) {
+		WMA_LOGE("Failed to register WMI Auto shutdown event handler");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
+	status = wmi_unified_register_event_handler(wmi_handle,
+						wmi_thermal_mgmt_event_id,
+						wma_thermal_mgmt_evt_handler,
+						WMA_RX_SERIALIZER_CTX);
+	if (status) {
+		WMA_LOGE("Failed to register thermal mitigation event cb");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	status = wma_ocb_register_callbacks(wma_handle);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		WMA_LOGE("Failed to register OCB callbacks");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	qdf_status = QDF_STATUS_SUCCESS;
+
+#ifdef QCA_WIFI_FTM
+	/*
+	 * Tx mgmt attach requires TXRX context which is not created
+	 * in FTM mode. So skip the TX mgmt attach.
+	 */
+	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE)
+		goto end;
+#endif /* QCA_WIFI_FTM */
+
+	if (wmi_service_enabled(wmi_handle, wmi_service_rmc)) {
+
+		WMA_LOGD("FW supports cesium network, registering event handlers");
+
+		status = wmi_unified_register_event_handler(
+					wmi_handle,
+					wmi_peer_info_event_id,
+					wma_ibss_peer_info_event_handler,
+					WMA_RX_SERIALIZER_CTX);
+		if (status) {
+			WMA_LOGE("Failed to register ibss peer info event cb");
+			qdf_status = QDF_STATUS_E_FAILURE;
+			goto end;
+		}
+		status = wmi_unified_register_event_handler(
+					wmi_handle,
+					wmi_peer_tx_fail_cnt_thr_event_id,
+					wma_fast_tx_fail_event_handler,
+					WMA_RX_SERIALIZER_CTX);
+		if (status) {
+			WMA_LOGE("Failed to register peer fast tx failure event cb");
+			qdf_status = QDF_STATUS_E_FAILURE;
+			goto end;
+		}
+	} else {
+		WMA_LOGE("Target does not support cesium network");
+	}
+
+	qdf_status = wma_tx_attach(wma_handle);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Failed to register tx management", __func__);
+		goto end;
+	}
+
+	if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE) {
+		/* Initialize firmware time stamp sync timer */
+		qdf_status =
+			qdf_mc_timer_init(&wma_handle->wma_fw_time_sync_timer,
+					  QDF_TIMER_TYPE_SW,
+					  wma_send_time_stamp_sync_cmd,
+					  wma_handle);
+		if (QDF_IS_STATUS_ERROR(qdf_status)) {
+			WMA_LOGE(FL("Failed to initialize firmware time stamp sync timer"));
+			goto end;
+		}
+
+		/* Start firmware time stamp sync timer */
+		wma_send_time_stamp_sync_cmd(wma_handle);
+	}
+
+	/* Initialize log completion timeout */
+	qdf_status = qdf_mc_timer_init(&wma_handle->log_completion_timer,
+			QDF_TIMER_TYPE_SW,
+			wma_log_completion_timeout,
+			wma_handle);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to initialize log completion timeout");
+		goto end;
+	}
+
+	status = wma_fips_register_event_handlers(wma_handle);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		WMA_LOGE("Failed to register FIPS event handler");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	status = wma_sar_register_event_handlers(wma_handle);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		WMA_LOGE("Failed to register SAR event handlers");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	/* Initialize the get temperature event handler */
+	status = wmi_unified_register_event_handler(wmi_handle,
+					wmi_pdev_temperature_event_id,
+					wma_pdev_temperature_evt_handler,
+					WMA_RX_SERIALIZER_CTX);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to register get_temperature event cb");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	status = wmi_unified_register_event_handler(wmi_handle,
+						wmi_vdev_tsf_report_event_id,
+						wma_vdev_tsf_handler,
+						WMA_RX_SERIALIZER_CTX);
+	if (0 != status) {
+		WMA_LOGE("%s: Failed to register tsf callback", __func__);
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	/* Initialize the wma_pdev_set_hw_mode_resp_evt_handler event handler */
+	status = wmi_unified_register_event_handler(wmi_handle,
+			wmi_pdev_set_hw_mode_rsp_event_id,
+			wma_pdev_set_hw_mode_resp_evt_handler,
+			WMA_RX_SERIALIZER_CTX);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to register set hw mode resp event cb");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	/* Initialize the WMI_SOC_HW_MODE_TRANSITION_EVENTID event handler */
+	status = wmi_unified_register_event_handler(wmi_handle,
+			wmi_pdev_hw_mode_transition_event_id,
+			wma_pdev_hw_mode_transition_evt_handler,
+			WMA_RX_SERIALIZER_CTX);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to register hw mode transition event cb");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	/* Initialize the set dual mac configuration event handler */
+	status = wmi_unified_register_event_handler(wmi_handle,
+			wmi_pdev_set_mac_config_resp_event_id,
+			wma_pdev_set_dual_mode_config_resp_evt_handler,
+			WMA_RX_SERIALIZER_CTX);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("Failed to register hw mode transition event cb");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	status = wmi_unified_register_event_handler(wmi_handle,
+			wmi_coex_bt_activity_event_id,
+			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;
+	}
+	wma_register_spectral_cmds(wma_handle);
+
+end:
+	WMA_LOGD("%s: Exit", __func__);
+	return qdf_status;
+}
+
+QDF_STATUS wma_stop(void)
+{
+	tp_wma_handle wma_handle;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	int i;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	WMA_LOGD("%s: Enter", __func__);
+	/* validate the wma_handle */
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: Invalid handle", __func__);
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto end;
+	}
+#ifdef QCA_WIFI_FTM
+	/*
+	 * Tx mgmt detach requires TXRX context which is not created
+	 * in FTM mode. So skip the TX mgmt detach.
+	 */
+	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		qdf_status = QDF_STATUS_SUCCESS;
+		goto end;
+	}
+#endif /* QCA_WIFI_FTM */
+
+	if (wma_handle->ack_work_ctx) {
+		cds_flush_work(&wma_handle->ack_work_ctx->ack_cmp_work);
+		qdf_mem_free(wma_handle->ack_work_ctx);
+		wma_handle->ack_work_ctx = NULL;
+	}
+
+	/* Destroy the timer for log completion */
+	qdf_status = qdf_mc_timer_destroy(&wma_handle->log_completion_timer);
+	if (qdf_status != QDF_STATUS_SUCCESS)
+		WMA_LOGE("Failed to destroy the log completion timer");
+	/* clean up ll-queue for all vdev */
+	for (i = 0; i < wma_handle->max_bssid; i++) {
+		if (wma_handle->interfaces[i].handle &&
+				wma_is_vdev_up(i)) {
+			cdp_fc_vdev_flush(
+				cds_get_context(QDF_MODULE_ID_SOC),
+				wma_handle->
+				interfaces[i].handle);
+		}
+	}
+
+	if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE) {
+		/* Destroy firmware time stamp sync timer */
+		qdf_status = qdf_mc_timer_destroy(
+					&wma_handle->wma_fw_time_sync_timer);
+		if (QDF_IS_STATUS_ERROR(qdf_status))
+			WMA_LOGE(FL("Failed to destroy the fw time sync timer"));
+	}
+
+	qdf_status = wma_tx_detach(wma_handle);
+	if (qdf_status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Failed to deregister tx management", __func__);
+		goto end;
+	}
+
+end:
+	WMA_LOGD("%s: Exit", __func__);
+	return qdf_status;
+}
+
+/**
+ * wma_wmi_service_close() - close wma wmi service interface.
+ *
+ * Return: 0 on success, QDF Error on failure
+ */
+QDF_STATUS wma_wmi_service_close(void)
+{
+	void *cds_ctx;
+	tp_wma_handle wma_handle;
+	int i;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	cds_ctx = cds_get_global_context();
+	if (!cds_ctx) {
+		WMA_LOGE("%s: Invalid CDS context", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	/* validate the wma_handle */
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: Invalid wma handle", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* validate the wmi handle */
+	if (NULL == wma_handle->wmi_handle) {
+		WMA_LOGE("%s: Invalid wmi handle", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* dettach the wmi serice */
+	WMA_LOGD("calling wmi_unified_detach");
+	wmi_unified_detach(wma_handle->wmi_handle);
+	wma_handle->wmi_handle = NULL;
+
+	for (i = 0; i < wma_handle->max_bssid; i++) {
+		wma_vdev_deinit(&wma_handle->interfaces[i]);
+	}
+
+	qdf_mem_free(wma_handle->interfaces);
+
+	/* free the wma_handle */
+	cds_free_context(QDF_MODULE_ID_WMA, wma_handle);
+
+	qdf_mem_free(((struct cds_context *) cds_ctx)->cfg_ctx);
+	((struct cds_context *)cds_ctx)->cfg_ctx = NULL;
+	WMA_LOGD("%s: Exit", __func__);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_wmi_work_close() - close the work queue items associated with WMI
+ *
+ * This function closes work queue items associated with WMI, but not fully
+ * closes WMI service.
+ *
+ * Return: QDF_STATUS_SUCCESS if work close is successful. Otherwise
+ *	proper error codes.
+ */
+QDF_STATUS wma_wmi_work_close(void)
+{
+	tp_wma_handle wma_handle;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	/* validate the wma_handle */
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: Invalid wma handle", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* validate the wmi handle */
+	if (NULL == wma_handle->wmi_handle) {
+		WMA_LOGE("%s: Invalid wmi handle", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* remove the wmi work */
+	WMA_LOGD("calling wmi_unified_remove_work");
+	wmi_unified_remove_work(wma_handle->wmi_handle);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_close() - wma close function.
+ *               cleanup resources attached with wma.
+ *
+ * Return: 0 on success, QDF Error on failure
+ */
+QDF_STATUS wma_close(void)
+{
+	tp_wma_handle wma_handle;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	/* validate the wma_handle */
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: Invalid wma handle", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* validate the wmi handle */
+	if (NULL == wma_handle->wmi_handle) {
+		WMA_LOGE("%s: Invalid wmi handle", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* Free DBS list */
+	if (wma_handle->hw_mode.hw_mode_list) {
+		qdf_mem_free(wma_handle->hw_mode.hw_mode_list);
+		wma_handle->hw_mode.hw_mode_list = NULL;
+		WMA_LOGD("%s: DBS list is freed", __func__);
+	}
+
+	if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE) {
+#ifdef FEATURE_WLAN_EXTSCAN
+		qdf_wake_lock_destroy(&wma_handle->extscan_wake_lock);
+#endif /* FEATURE_WLAN_EXTSCAN */
+		qdf_wake_lock_destroy(&wma_handle->wow_wake_lock);
+		qdf_wake_lock_destroy(&wma_handle->wow_auth_req_wl);
+		qdf_wake_lock_destroy(&wma_handle->wow_assoc_req_wl);
+		qdf_wake_lock_destroy(&wma_handle->wow_deauth_rec_wl);
+		qdf_wake_lock_destroy(&wma_handle->wow_disassoc_rec_wl);
+		qdf_wake_lock_destroy(&wma_handle->wow_ap_assoc_lost_wl);
+		qdf_wake_lock_destroy(&wma_handle->wow_auto_shutdown_wl);
+		qdf_wake_lock_destroy(&wma_handle->roam_ho_wl);
+	}
+
+	/* unregister Firmware debug log */
+	qdf_status = dbglog_deinit(wma_handle->wmi_handle);
+	if (qdf_status != QDF_STATUS_SUCCESS)
+		WMA_LOGE("%s: dbglog_deinit failed", __func__);
+
+	qdf_status = qdf_mc_timer_destroy(&wma_handle->service_ready_ext_timer);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		WMA_LOGE("%s: Failed to destroy service ready ext event timer",
+			__func__);
+
+	qdf_event_destroy(&wma_handle->target_suspend);
+	qdf_event_destroy(&wma_handle->wma_resume_event);
+	qdf_event_destroy(&wma_handle->runtime_suspend);
+	qdf_event_destroy(&wma_handle->recovery_event);
+	qdf_event_destroy(&wma_handle->tx_frm_download_comp_event);
+	qdf_event_destroy(&wma_handle->tx_queue_empty_event);
+	wma_cleanup_vdev_resp_queue(wma_handle);
+	wma_cleanup_hold_req(wma_handle);
+	qdf_wake_lock_destroy(&wma_handle->wmi_cmd_rsp_wake_lock);
+	qdf_runtime_lock_deinit(&wma_handle->wmi_cmd_rsp_runtime_lock);
+	qdf_spinlock_destroy(&wma_handle->vdev_respq_lock);
+	qdf_spinlock_destroy(&wma_handle->wma_hold_req_q_lock);
+
+	if (NULL != wma_handle->pGetRssiReq) {
+		qdf_mem_free(wma_handle->pGetRssiReq);
+		wma_handle->pGetRssiReq = NULL;
+	}
+
+	wma_unified_radio_tx_mem_free(wma_handle);
+
+	if (wma_handle->pdev) {
+		wlan_objmgr_pdev_release_ref(wma_handle->pdev,
+				WLAN_LEGACY_WMA_ID);
+		wma_handle->pdev = NULL;
+	}
+
+	pmo_unregister_get_beacon_interval_callback(wma_handle->psoc);
+	pmo_unregister_get_dtim_period_callback(wma_handle->psoc);
+	pmo_unregister_get_cfg_int_callback(wma_handle->psoc);
+	pmo_unregister_is_device_in_low_pwr_mode(wma_handle->psoc);
+	pmo_unregister_get_pause_bitmap(wma_handle->psoc);
+	pmo_unregister_pause_bitmap_notifier(wma_handle->psoc);
+	pmo_unregister_get_vdev_dp_handle(wma_handle->psoc);
+
+	target_if_free_psoc_tgt_info(wma_handle->psoc);
+
+	wlan_objmgr_psoc_release_ref(wma_handle->psoc, WLAN_LEGACY_WMA_ID);
+	wma_handle->psoc = NULL;
+	target_if_close();
+	wma_target_if_close(wma_handle);
+
+	WMA_LOGD("%s: Exit", __func__);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_update_fw_config() - update fw configuration
+ * @psoc: psoc to query configuration from
+ * @tgt_hdl: target capability info
+ *
+ * Return: none
+ */
+static void wma_update_fw_config(struct wlan_objmgr_psoc *psoc,
+				 struct target_psoc_info *tgt_hdl)
+{
+	target_resource_config *cfg = &tgt_hdl->info.wlan_res_cfg;
+
+	/* Override the no. of max fragments as per platform configuration */
+	cfg->max_frag_entries =	QDF_MIN(QCA_OL_11AC_TX_MAX_FRAGS,
+					target_if_get_max_frag_entry(tgt_hdl));
+	target_if_set_max_frag_entry(tgt_hdl, cfg->max_frag_entries);
+
+	cfg->num_wow_filters = ucfg_pmo_get_num_wow_filters(psoc);
+	cfg->apf_instruction_size = ucfg_pmo_get_apf_instruction_size(psoc);
+	cfg->num_packet_filters = ucfg_pmo_get_num_packet_filters(psoc);
+}
+
+/**
+ * wma_set_tx_partition_base() - set TX MSDU ID partition base for IPA
+ * @value:  TX MSDU ID partition base
+ *
+ * Return: none
+ */
+#ifdef IPA_OFFLOAD
+static void wma_set_tx_partition_base(uint32_t value)
+{
+	cdp_ipa_set_uc_tx_partition_base(
+			cds_get_context(QDF_MODULE_ID_SOC),
+			(struct cdp_cfg *)cds_get_context(QDF_MODULE_ID_CFG),
+			value);
+	WMA_LOGD("%s: TX_MSDU_ID_PARTITION=%d", __func__,
+			value);
+}
+#else
+static void wma_set_tx_partition_base(uint32_t value)
+{
+}
+#endif
+
+/**
+ * wma_update_target_services() - update target services from wma handle
+ * @wmi_handle: Unified wmi handle
+ * @cfg: target services
+ *
+ * Return: none
+ */
+static inline void wma_update_target_services(struct wmi_unified *wmi_handle,
+					      struct wma_tgt_services *cfg)
+{
+	/* STA power save */
+	cfg->sta_power_save = wmi_service_enabled(wmi_handle,
+						     wmi_service_sta_pwrsave);
+
+	/* Enable UAPSD */
+	cfg->uapsd = wmi_service_enabled(wmi_handle,
+					    wmi_service_ap_uapsd);
+
+	/* Update AP DFS service */
+	cfg->ap_dfs = wmi_service_enabled(wmi_handle,
+					     wmi_service_ap_dfs);
+
+	/* Enable 11AC */
+	cfg->en_11ac = wmi_service_enabled(wmi_handle,
+					      wmi_service_11ac);
+	if (cfg->en_11ac)
+		g_fw_wlan_feat_caps |= (1 << DOT11AC);
+
+	/* Proactive ARP response */
+	g_fw_wlan_feat_caps |= (1 << WLAN_PERIODIC_TX_PTRN);
+
+	/* Enable WOW */
+	g_fw_wlan_feat_caps |= (1 << WOW);
+
+	/* ARP offload */
+	cfg->arp_offload = wmi_service_enabled(wmi_handle,
+						  wmi_service_arpns_offload);
+
+	/* Adaptive early-rx */
+	cfg->early_rx = wmi_service_enabled(wmi_handle,
+					       wmi_service_early_rx);
+#ifdef FEATURE_WLAN_SCAN_PNO
+	/* PNO offload */
+	if (wmi_service_enabled(wmi_handle, wmi_service_nlo)) {
+		cfg->pno_offload = true;
+		g_fw_wlan_feat_caps |= (1 << PNO);
+	}
+#endif /* FEATURE_WLAN_SCAN_PNO */
+
+#ifdef FEATURE_WLAN_EXTSCAN
+	if (wmi_service_enabled(wmi_handle, wmi_service_extscan))
+		g_fw_wlan_feat_caps |= (1 << EXTENDED_SCAN);
+#endif /* FEATURE_WLAN_EXTSCAN */
+	cfg->lte_coex_ant_share = wmi_service_enabled(wmi_handle,
+					wmi_service_lte_ant_share_support);
+#ifdef FEATURE_WLAN_TDLS
+	/* Enable TDLS */
+	if (wmi_service_enabled(wmi_handle, wmi_service_tdls)) {
+		cfg->en_tdls = 1;
+		g_fw_wlan_feat_caps |= (1 << TDLS);
+	}
+	/* Enable advanced TDLS features */
+	if (wmi_service_enabled(wmi_handle, wmi_service_tdls_offchan)) {
+		cfg->en_tdls_offchan = 1;
+		g_fw_wlan_feat_caps |= (1 << TDLS_OFF_CHANNEL);
+	}
+
+	cfg->en_tdls_uapsd_buf_sta =
+		wmi_service_enabled(wmi_handle,
+				       wmi_service_tdls_uapsd_buffer_sta);
+	cfg->en_tdls_uapsd_sleep_sta =
+		wmi_service_enabled(wmi_handle,
+				       wmi_service_tdls_uapsd_sleep_sta);
+#endif /* FEATURE_WLAN_TDLS */
+	if (wmi_service_enabled
+		    (wmi_handle, wmi_service_beacon_offload))
+		cfg->beacon_offload = true;
+	if (wmi_service_enabled
+		    (wmi_handle, wmi_service_sta_pmf_offload))
+		cfg->pmf_offload = true;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	/* Enable Roam Offload */
+	cfg->en_roam_offload = wmi_service_enabled(wmi_handle,
+					      wmi_service_roam_ho_offload);
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+#ifdef WLAN_FEATURE_NAN
+	if (wmi_service_enabled(wmi_handle, wmi_service_nan))
+		g_fw_wlan_feat_caps |= (1 << NAN);
+#endif /* WLAN_FEATURE_NAN */
+
+	if (wmi_service_enabled(wmi_handle, wmi_service_rtt))
+		g_fw_wlan_feat_caps |= (1 << RTT);
+
+	if (wmi_service_enabled(wmi_handle,
+			wmi_service_tx_msdu_id_new_partition_support)) {
+		wma_set_tx_partition_base(HTT_TX_IPA_NEW_MSDU_ID_SPACE_BEGIN);
+	} else {
+		wma_set_tx_partition_base(HTT_TX_IPA_MSDU_ID_SPACE_BEGIN);
+	}
+
+	wma_he_update_tgt_services(wmi_handle, cfg);
+
+	cfg->get_peer_info_enabled =
+		wmi_service_enabled(wmi_handle,
+				       wmi_service_peer_stats_info);
+	if (wmi_service_enabled(wmi_handle, wmi_service_fils_support))
+		cfg->is_fils_roaming_supported = true;
+
+	if (wmi_service_enabled(wmi_handle, wmi_service_mawc_support))
+		cfg->is_fw_mawc_capable = true;
+
+	if (wmi_service_enabled(wmi_handle,
+				wmi_service_11k_neighbour_report_support))
+		cfg->is_11k_offload_supported = true;
+
+	if (wmi_service_enabled(wmi_handle, wmi_service_twt_requestor))
+		cfg->twt_requestor = true;
+	if (wmi_service_enabled(wmi_handle, wmi_service_twt_responder))
+		cfg->twt_responder = true;
+	if (wmi_service_enabled(wmi_handle, wmi_service_obss_scan))
+		cfg->obss_scan_offload = true;
+}
+
+/**
+ * wma_update_target_ht_cap() - update ht capabality from wma handle
+ * @tgt_hdl: pointer to structure target_psoc_info
+ * @cfg: ht capability
+ *
+ * Return: none
+ */
+static inline void
+wma_update_target_ht_cap(struct target_psoc_info *tgt_hdl,
+			 struct wma_tgt_ht_cap *cfg)
+{
+	int ht_cap_info;
+
+	ht_cap_info = target_if_get_ht_cap_info(tgt_hdl);
+	/* RX STBC */
+	cfg->ht_rx_stbc = !!(ht_cap_info & WMI_HT_CAP_RX_STBC);
+
+	/* TX STBC */
+	cfg->ht_tx_stbc = !!(ht_cap_info & WMI_HT_CAP_TX_STBC);
+
+	/* MPDU density */
+	cfg->mpdu_density = ht_cap_info & WMI_HT_CAP_MPDU_DENSITY;
+
+	/* HT RX LDPC */
+	cfg->ht_rx_ldpc = !!(ht_cap_info & WMI_HT_CAP_LDPC);
+
+	/* HT SGI */
+	cfg->ht_sgi_20 = !!(ht_cap_info & WMI_HT_CAP_HT20_SGI);
+
+	cfg->ht_sgi_40 = !!(ht_cap_info & WMI_HT_CAP_HT40_SGI);
+
+	/* RF chains */
+	cfg->num_rf_chains = target_if_get_num_rf_chains(tgt_hdl);
+
+	WMA_LOGD("%s: ht_cap_info - %x ht_rx_stbc - %d, ht_tx_stbc - %d\n"
+		 "mpdu_density - %d ht_rx_ldpc - %d ht_sgi_20 - %d\n"
+		 "ht_sgi_40 - %d num_rf_chains - %d", __func__,
+		 ht_cap_info,
+		 cfg->ht_rx_stbc, cfg->ht_tx_stbc, cfg->mpdu_density,
+		 cfg->ht_rx_ldpc, cfg->ht_sgi_20, cfg->ht_sgi_40,
+		 cfg->num_rf_chains);
+
+}
+
+/**
+ * wma_update_target_vht_cap() - update vht capabality from wma handle
+ * @tgt_hdl: pointer to structure target_psoc_info
+ * @cfg: vht capabality
+ *
+ * Return: none
+ */
+static inline void
+wma_update_target_vht_cap(struct target_psoc_info *tgt_hdl,
+			  struct wma_tgt_vht_cap *cfg)
+{
+	int vht_cap_info = target_if_get_vht_cap_info(tgt_hdl);
+
+	if (vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_11454)
+		cfg->vht_max_mpdu = WMI_VHT_CAP_MAX_MPDU_LEN_11454;
+	else if (vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_7935)
+		cfg->vht_max_mpdu = WMI_VHT_CAP_MAX_MPDU_LEN_7935;
+	else
+		cfg->vht_max_mpdu = 0;
+
+
+	if (vht_cap_info & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ) {
+		cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_80P80MHZ;
+		cfg->supp_chan_width |= 1 << eHT_CHANNEL_WIDTH_160MHZ;
+	} else if (vht_cap_info & WMI_VHT_CAP_CH_WIDTH_160MHZ) {
+		cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_160MHZ;
+	} else {
+		cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_80MHZ;
+	}
+
+	cfg->vht_rx_ldpc = vht_cap_info & WMI_VHT_CAP_RX_LDPC;
+
+	cfg->vht_short_gi_80 = vht_cap_info & WMI_VHT_CAP_SGI_80MHZ;
+	cfg->vht_short_gi_160 = vht_cap_info & WMI_VHT_CAP_SGI_160MHZ;
+
+	cfg->vht_tx_stbc = vht_cap_info & WMI_VHT_CAP_TX_STBC;
+
+	cfg->vht_rx_stbc =
+		(vht_cap_info & WMI_VHT_CAP_RX_STBC_1SS) |
+		(vht_cap_info & WMI_VHT_CAP_RX_STBC_2SS) |
+		(vht_cap_info & WMI_VHT_CAP_RX_STBC_3SS);
+
+	cfg->vht_max_ampdu_len_exp = (vht_cap_info &
+				      WMI_VHT_CAP_MAX_AMPDU_LEN_EXP)
+				     >> WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT;
+
+	cfg->vht_su_bformer = vht_cap_info & WMI_VHT_CAP_SU_BFORMER;
+
+	cfg->vht_su_bformee = vht_cap_info & WMI_VHT_CAP_SU_BFORMEE;
+
+	cfg->vht_mu_bformer = vht_cap_info & WMI_VHT_CAP_MU_BFORMER;
+
+	cfg->vht_mu_bformee = vht_cap_info & WMI_VHT_CAP_MU_BFORMEE;
+
+	cfg->vht_txop_ps = vht_cap_info & WMI_VHT_CAP_TXOP_PS;
+
+	WMA_LOGD("%s: max_mpdu %d supp_chan_width %x rx_ldpc %x\n"
+		 "short_gi_80 %x tx_stbc %x rx_stbc %x txop_ps %x\n"
+		 "su_bformee %x mu_bformee %x max_ampdu_len_exp %d", __func__,
+		 cfg->vht_max_mpdu, cfg->supp_chan_width, cfg->vht_rx_ldpc,
+		 cfg->vht_short_gi_80, cfg->vht_tx_stbc, cfg->vht_rx_stbc,
+		 cfg->vht_txop_ps, cfg->vht_su_bformee, cfg->vht_mu_bformee,
+		 cfg->vht_max_ampdu_len_exp);
+}
+
+/**
+ * wma_update_supported_bands() - update supported bands from service ready ext
+ * @supported_bands: Supported band given by FW through service ready ext params
+ * @new_supported_bands: New supported band which needs to be updated by
+ *			 this API which WMA layer understands
+ *
+ * This API will convert FW given supported band to enum which WMA layer
+ * understands
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS wma_update_supported_bands(
+			WLAN_BAND_CAPABILITY supported_bands,
+			WMI_PHY_CAPABILITY *new_supported_bands)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!new_supported_bands) {
+		WMA_LOGE("%s: NULL new supported band variable", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	switch (supported_bands) {
+	case WLAN_2G_CAPABILITY:
+		*new_supported_bands |= WMI_11G_CAPABILITY;
+		break;
+	case WLAN_5G_CAPABILITY:
+		*new_supported_bands |= WMI_11A_CAPABILITY;
+		break;
+	default:
+		WMA_LOGE("%s: wrong supported band", __func__);
+		status = QDF_STATUS_E_FAILURE;
+		break;
+	}
+	return status;
+}
+
+/**
+ * wma_derive_ext_ht_cap() - Derive HT caps based on given value
+ * @ht_cap: given pointer to HT caps which needs to be updated
+ * @tx_chain: given tx chainmask value
+ * @rx_chain: given rx chainmask value
+ * @value: new HT cap info provided in form of bitmask
+ *
+ * This function takes the value provided in form of bitmask and decodes
+ * it. After decoding, what ever value it gets, it takes the union(max) or
+ * intersection(min) with previously derived values.
+ *
+ * Return: none
+ *
+ */
+static void wma_derive_ext_ht_cap(
+			struct wma_tgt_ht_cap *ht_cap, uint32_t value,
+			uint32_t tx_chain, uint32_t rx_chain)
+{
+	struct wma_tgt_ht_cap tmp = {0};
+
+	if (ht_cap == NULL)
+		return;
+
+	if (!qdf_mem_cmp(ht_cap, &tmp, sizeof(struct wma_tgt_ht_cap))) {
+		ht_cap->ht_rx_stbc = (!!(value & WMI_HT_CAP_RX_STBC));
+		ht_cap->ht_tx_stbc = (!!(value & WMI_HT_CAP_TX_STBC));
+		ht_cap->mpdu_density = (!!(value & WMI_HT_CAP_MPDU_DENSITY));
+		ht_cap->ht_rx_ldpc = (!!(value & WMI_HT_CAP_RX_LDPC));
+		ht_cap->ht_sgi_20 = (!!(value & WMI_HT_CAP_HT20_SGI));
+		ht_cap->ht_sgi_40 = (!!(value & WMI_HT_CAP_HT40_SGI));
+		ht_cap->num_rf_chains =
+			QDF_MAX(wma_get_num_of_setbits_from_bitmask(tx_chain),
+				wma_get_num_of_setbits_from_bitmask(rx_chain));
+	} else {
+		ht_cap->ht_rx_stbc = QDF_MIN(ht_cap->ht_rx_stbc,
+					(!!(value & WMI_HT_CAP_RX_STBC)));
+		ht_cap->ht_tx_stbc = QDF_MAX(ht_cap->ht_tx_stbc,
+					(!!(value & WMI_HT_CAP_TX_STBC)));
+		ht_cap->mpdu_density = QDF_MIN(ht_cap->mpdu_density,
+					(!!(value & WMI_HT_CAP_MPDU_DENSITY)));
+		ht_cap->ht_rx_ldpc = QDF_MIN(ht_cap->ht_rx_ldpc,
+					(!!(value & WMI_HT_CAP_RX_LDPC)));
+		ht_cap->ht_sgi_20 = QDF_MIN(ht_cap->ht_sgi_20,
+					(!!(value & WMI_HT_CAP_HT20_SGI)));
+		ht_cap->ht_sgi_40 = QDF_MIN(ht_cap->ht_sgi_40,
+					(!!(value & WMI_HT_CAP_HT40_SGI)));
+		ht_cap->num_rf_chains =
+			QDF_MAX(ht_cap->num_rf_chains,
+				QDF_MAX(wma_get_num_of_setbits_from_bitmask(
+								tx_chain),
+					wma_get_num_of_setbits_from_bitmask(
+								rx_chain)));
+	}
+}
+
+/**
+ * wma_update_target_ext_ht_cap() - Update HT caps with given extended cap
+ * @tgt_hdl - target psoc information
+ * @ht_cap: HT cap structure to be filled
+ *
+ * This function loop through each hardware mode and for each hardware mode
+ * again it loop through each MAC/PHY and pull the caps 2G and 5G specific
+ * HT caps and derives the final cap.
+ *
+ * Return: none
+ *
+ */
+static void wma_update_target_ext_ht_cap(struct target_psoc_info *tgt_hdl,
+					 struct wma_tgt_ht_cap *ht_cap)
+{
+	int i, total_mac_phy_cnt;
+	uint32_t ht_2g, ht_5g;
+	struct wma_tgt_ht_cap tmp_ht_cap = {0}, tmp_cap = {0};
+	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
+	int num_hw_modes;
+
+	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
+	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
+	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
+	/*
+	 * for legacy device extended cap might not even come, so in that case
+	 * don't overwrite legacy values
+	 */
+	if (!num_hw_modes) {
+		WMA_LOGD("%s: No extended HT cap for current SOC", __func__);
+		return;
+	}
+
+	for (i = 0; i < total_mac_phy_cnt; i++) {
+		ht_2g = mac_phy_cap[i].ht_cap_info_2G;
+		ht_5g = mac_phy_cap[i].ht_cap_info_5G;
+		if (ht_2g)
+			wma_derive_ext_ht_cap(&tmp_ht_cap,
+					ht_2g,
+					mac_phy_cap[i].tx_chain_mask_2G,
+					mac_phy_cap[i].rx_chain_mask_2G);
+		if (ht_5g)
+			wma_derive_ext_ht_cap(&tmp_ht_cap,
+					ht_5g,
+					mac_phy_cap[i].tx_chain_mask_5G,
+					mac_phy_cap[i].rx_chain_mask_5G);
+	}
+
+	if (qdf_mem_cmp(&tmp_cap, &tmp_ht_cap,
+				sizeof(struct wma_tgt_ht_cap))) {
+		qdf_mem_copy(ht_cap, &tmp_ht_cap,
+				sizeof(struct wma_tgt_ht_cap));
+	}
+
+	WMA_LOGD("%s: [ext ht cap] ht_rx_stbc - %d, ht_tx_stbc - %d\n"
+			"mpdu_density - %d ht_rx_ldpc - %d ht_sgi_20 - %d\n"
+			"ht_sgi_40 - %d num_rf_chains - %d", __func__,
+			ht_cap->ht_rx_stbc, ht_cap->ht_tx_stbc,
+			ht_cap->mpdu_density, ht_cap->ht_rx_ldpc,
+			ht_cap->ht_sgi_20, ht_cap->ht_sgi_40,
+			ht_cap->num_rf_chains);
+}
+
+/**
+ * wma_derive_ext_vht_cap() - Derive VHT caps based on given value
+ * @vht_cap: pointer to given VHT caps to be filled
+ * @value: new VHT cap info provided in form of bitmask
+ *
+ * This function takes the value provided in form of bitmask and decodes
+ * it. After decoding, what ever value it gets, it takes the union(max) or
+ * intersection(min) with previously derived values.
+ *
+ * Return: none
+ *
+ */
+static void wma_derive_ext_vht_cap(
+			struct wma_tgt_vht_cap *vht_cap, uint32_t value)
+{
+	struct wma_tgt_vht_cap tmp_cap = {0};
+	uint32_t tmp = 0;
+
+	if (vht_cap == NULL)
+		return;
+
+	if (!qdf_mem_cmp(vht_cap, &tmp_cap,
+				sizeof(struct wma_tgt_vht_cap))) {
+		if (value & WMI_VHT_CAP_MAX_MPDU_LEN_11454)
+			vht_cap->vht_max_mpdu = WMI_VHT_CAP_MAX_MPDU_LEN_11454;
+		else if (value & WMI_VHT_CAP_MAX_MPDU_LEN_7935)
+			vht_cap->vht_max_mpdu = WMI_VHT_CAP_MAX_MPDU_LEN_7935;
+		else
+			vht_cap->vht_max_mpdu = 0;
+
+		if (value & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ) {
+			vht_cap->supp_chan_width =
+				1 << eHT_CHANNEL_WIDTH_80P80MHZ;
+			vht_cap->supp_chan_width |=
+				1 << eHT_CHANNEL_WIDTH_160MHZ;
+		} else if (value & WMI_VHT_CAP_CH_WIDTH_160MHZ) {
+			vht_cap->supp_chan_width =
+				1 << eHT_CHANNEL_WIDTH_160MHZ;
+		} else {
+			vht_cap->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_80MHZ;
+		}
+		vht_cap->vht_rx_ldpc = value & WMI_VHT_CAP_RX_LDPC;
+		vht_cap->vht_short_gi_80 = value & WMI_VHT_CAP_SGI_80MHZ;
+		vht_cap->vht_short_gi_160 = value & WMI_VHT_CAP_SGI_160MHZ;
+		vht_cap->vht_tx_stbc = value & WMI_VHT_CAP_TX_STBC;
+		vht_cap->vht_rx_stbc =
+			(value & WMI_VHT_CAP_RX_STBC_1SS) |
+			(value & WMI_VHT_CAP_RX_STBC_2SS) |
+			(value & WMI_VHT_CAP_RX_STBC_3SS);
+		vht_cap->vht_max_ampdu_len_exp =
+			(value & WMI_VHT_CAP_MAX_AMPDU_LEN_EXP) >>
+				WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT;
+		vht_cap->vht_su_bformer = value & WMI_VHT_CAP_SU_BFORMER;
+		vht_cap->vht_su_bformee = value & WMI_VHT_CAP_SU_BFORMEE;
+		vht_cap->vht_mu_bformer = value & WMI_VHT_CAP_MU_BFORMER;
+		vht_cap->vht_mu_bformee = value & WMI_VHT_CAP_MU_BFORMEE;
+		vht_cap->vht_txop_ps = value & WMI_VHT_CAP_TXOP_PS;
+	} else {
+		if (value & WMI_VHT_CAP_MAX_MPDU_LEN_11454)
+			tmp = WMI_VHT_CAP_MAX_MPDU_LEN_11454;
+		else if (value & WMI_VHT_CAP_MAX_MPDU_LEN_7935)
+			tmp = WMI_VHT_CAP_MAX_MPDU_LEN_7935;
+		else
+			tmp = 0;
+		vht_cap->vht_max_mpdu = QDF_MIN(vht_cap->vht_max_mpdu, tmp);
+
+		if ((value & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ)) {
+			tmp = (1 << eHT_CHANNEL_WIDTH_80P80MHZ) |
+				(1 << eHT_CHANNEL_WIDTH_160MHZ);
+		} else if (value & WMI_VHT_CAP_CH_WIDTH_160MHZ) {
+			tmp = 1 << eHT_CHANNEL_WIDTH_160MHZ;
+		} else {
+			tmp = 1 << eHT_CHANNEL_WIDTH_80MHZ;
+		}
+		vht_cap->supp_chan_width =
+			QDF_MAX(vht_cap->supp_chan_width, tmp);
+		vht_cap->vht_rx_ldpc = QDF_MIN(vht_cap->vht_rx_ldpc,
+						value & WMI_VHT_CAP_RX_LDPC);
+		vht_cap->vht_short_gi_80 = QDF_MAX(vht_cap->vht_short_gi_80,
+						value & WMI_VHT_CAP_SGI_80MHZ);
+		vht_cap->vht_short_gi_160 = QDF_MAX(vht_cap->vht_short_gi_160,
+						value & WMI_VHT_CAP_SGI_160MHZ);
+		vht_cap->vht_tx_stbc = QDF_MAX(vht_cap->vht_tx_stbc,
+						value & WMI_VHT_CAP_TX_STBC);
+		vht_cap->vht_rx_stbc = QDF_MIN(vht_cap->vht_rx_stbc,
+					(value & WMI_VHT_CAP_RX_STBC_1SS) |
+					(value & WMI_VHT_CAP_RX_STBC_2SS) |
+					(value & WMI_VHT_CAP_RX_STBC_3SS));
+		vht_cap->vht_max_ampdu_len_exp =
+			QDF_MIN(vht_cap->vht_max_ampdu_len_exp,
+				(value & WMI_VHT_CAP_MAX_AMPDU_LEN_EXP) >>
+					WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT);
+		vht_cap->vht_su_bformer = QDF_MAX(vht_cap->vht_su_bformer,
+						value & WMI_VHT_CAP_SU_BFORMER);
+		vht_cap->vht_su_bformee = QDF_MAX(vht_cap->vht_su_bformee,
+						value & WMI_VHT_CAP_SU_BFORMEE);
+		vht_cap->vht_mu_bformer = QDF_MAX(vht_cap->vht_mu_bformer,
+						value & WMI_VHT_CAP_MU_BFORMER);
+		vht_cap->vht_mu_bformee = QDF_MAX(vht_cap->vht_mu_bformee,
+						value & WMI_VHT_CAP_MU_BFORMEE);
+		vht_cap->vht_txop_ps = QDF_MIN(vht_cap->vht_txop_ps,
+						value & WMI_VHT_CAP_TXOP_PS);
+	}
+}
+
+/**
+ * wma_update_target_ext_vht_cap() - Update VHT caps with given extended cap
+ * @tgt_hdl - target psoc information
+ * @vht_cap: VHT cap structure to be filled
+ *
+ * This function loop through each hardware mode and for each hardware mode
+ * again it loop through each MAC/PHY and pull the caps 2G and 5G specific
+ * VHT caps and derives the final cap.
+ *
+ * Return: none
+ *
+ */
+static void wma_update_target_ext_vht_cap(struct target_psoc_info *tgt_hdl,
+					  struct wma_tgt_vht_cap *vht_cap)
+{
+	int i, num_hw_modes, total_mac_phy_cnt;
+	uint32_t vht_cap_info_2g, vht_cap_info_5g;
+	struct wma_tgt_vht_cap tmp_vht_cap = {0}, tmp_cap = {0};
+	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
+
+	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
+	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
+	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
+
+	/*
+	 * for legacy device extended cap might not even come, so in that case
+	 * don't overwrite legacy values
+	 */
+	if (!num_hw_modes) {
+		WMA_LOGD("%s: No extended VHT cap for current SOC", __func__);
+		return;
+	}
+
+	for (i = 0; i < total_mac_phy_cnt; i++) {
+		vht_cap_info_2g = mac_phy_cap[i].vht_cap_info_2G;
+		vht_cap_info_5g = mac_phy_cap[i].vht_cap_info_5G;
+		if (vht_cap_info_2g)
+			wma_derive_ext_vht_cap(&tmp_vht_cap,
+					vht_cap_info_2g);
+		if (vht_cap_info_5g)
+			wma_derive_ext_vht_cap(&tmp_vht_cap,
+					vht_cap_info_5g);
+	}
+
+	if (qdf_mem_cmp(&tmp_cap, &tmp_vht_cap,
+				sizeof(struct wma_tgt_vht_cap))) {
+			qdf_mem_copy(vht_cap, &tmp_vht_cap,
+					sizeof(struct wma_tgt_vht_cap));
+	}
+
+	WMA_LOGD("%s: [ext vhtcap] max_mpdu %d supp_chan_width %x rx_ldpc %x\n"
+		"short_gi_80 %x tx_stbc %x rx_stbc %x txop_ps %x\n"
+		"su_bformee %x mu_bformee %x max_ampdu_len_exp %d", __func__,
+		vht_cap->vht_max_mpdu, vht_cap->supp_chan_width,
+		vht_cap->vht_rx_ldpc, vht_cap->vht_short_gi_80,
+		vht_cap->vht_tx_stbc, vht_cap->vht_rx_stbc,
+		vht_cap->vht_txop_ps, vht_cap->vht_su_bformee,
+		vht_cap->vht_mu_bformee, vht_cap->vht_max_ampdu_len_exp);
+}
+
+/**
+ * wma_update_ra_rate_limit() - update wma config
+ * @wma_handle: wma handle
+ * @cfg: target config
+ *
+ * Return: none
+ */
+#ifdef FEATURE_WLAN_RA_FILTERING
+static void wma_update_ra_rate_limit(tp_wma_handle wma_handle,
+				     struct wma_tgt_cfg *cfg)
+{
+	cfg->is_ra_rate_limit_enabled = wma_handle->IsRArateLimitEnabled;
+}
+#else
+static void wma_update_ra_rate_limit(tp_wma_handle wma_handle,
+				     struct wma_tgt_cfg *cfg)
+{
+}
+#endif
+
+static void
+wma_update_sar_version(struct wlan_psoc_host_service_ext_param *param,
+		       struct wma_tgt_cfg *cfg)
+{
+	cfg->sar_version = param ? param->sar_version : SAR_VERSION_1;
+}
+
+/**
+ * wma_update_hdd_band_cap() - update band cap which hdd understands
+ * @supported_band: supported band which has been given by FW
+ * @tgt_cfg: target configuration to be updated
+ *
+ * Convert WMA given supported band to enum which HDD understands
+ *
+ * Return: None
+ */
+static void wma_update_hdd_band_cap(WMI_PHY_CAPABILITY supported_band,
+				    struct wma_tgt_cfg *tgt_cfg)
+{
+	switch (supported_band) {
+	case WMI_11G_CAPABILITY:
+	case WMI_11NG_CAPABILITY:
+		tgt_cfg->band_cap = BAND_2G;
+		break;
+	case WMI_11A_CAPABILITY:
+	case WMI_11NA_CAPABILITY:
+	case WMI_11AC_CAPABILITY:
+		tgt_cfg->band_cap = BAND_5G;
+		break;
+	case WMI_11AG_CAPABILITY:
+	case WMI_11NAG_CAPABILITY:
+	default:
+		tgt_cfg->band_cap = BAND_ALL;
+	}
+}
+
+/**
+ * wma_update_obss_detection_support() - update obss detection offload support
+ * @wh: wma handle
+ * @tgt_cfg: target configuration to be updated
+ *
+ * Update obss detection offload support based on service bit.
+ *
+ * Return: None
+ */
+static void wma_update_obss_detection_support(tp_wma_handle wh,
+					      struct wma_tgt_cfg *tgt_cfg)
+{
+	if (wmi_service_enabled(wh->wmi_handle,
+				wmi_service_ap_obss_detection_offload))
+		tgt_cfg->obss_detection_offloaded = true;
+	else
+		tgt_cfg->obss_detection_offloaded = false;
+}
+
+/**
+ * wma_update_obss_color_collision_support() - update obss color collision
+ *   offload support
+ * @wh: wma handle
+ * @tgt_cfg: target configuration to be updated
+ *
+ * Update obss color collision offload support based on service bit.
+ *
+ * Return: None
+ */
+static void wma_update_obss_color_collision_support(tp_wma_handle wh,
+						    struct wma_tgt_cfg *tgt_cfg)
+{
+	if (wmi_service_enabled(wh->wmi_handle, wmi_service_bss_color_offload))
+		tgt_cfg->obss_color_collision_offloaded = true;
+	else
+		tgt_cfg->obss_color_collision_offloaded = false;
+}
+
+#ifdef WLAN_SUPPORT_GREEN_AP
+static void wma_green_ap_register_handlers(tp_wma_handle wma_handle)
+{
+	if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
+				   WMI_SERVICE_EGAP))
+		target_if_green_ap_register_egap_event_handler(
+					wma_handle->pdev);
+
+}
+#else
+static void wma_green_ap_register_handlers(tp_wma_handle wma_handle)
+{
+}
+#endif
+
+/**
+ * wma_update_hdd_cfg() - update HDD config
+ * @wma_handle: wma handle
+ *
+ * Return: none
+ */
+static void wma_update_hdd_cfg(tp_wma_handle wma_handle)
+{
+	struct wma_tgt_cfg tgt_cfg;
+	void *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	target_resource_config *wlan_res_cfg;
+	struct wlan_psoc_host_service_ext_param *service_ext_param;
+	struct target_psoc_info *tgt_hdl;
+	struct wmi_unified *wmi_handle;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
+	if (!tgt_hdl) {
+		WMA_LOGE("%s: target psoc info is NULL", __func__);
+		return;
+	}
+
+	wlan_res_cfg = target_psoc_get_wlan_res_cfg(tgt_hdl);
+	if (!wlan_res_cfg) {
+		WMA_LOGE("%s: wlan_res_cfg is null", __func__);
+		return;
+	}
+	service_ext_param =
+			target_psoc_get_service_ext_param(tgt_hdl);
+	wmi_handle = get_wmi_unified_hdl_from_psoc(wma_handle->psoc);
+	if (!wmi_handle) {
+		WMA_LOGE("%s: wmi handle is NULL", __func__);
+		return;
+	}
+
+	qdf_mem_zero(&tgt_cfg, sizeof(struct wma_tgt_cfg));
+
+	tgt_cfg.sub_20_support = wma_handle->sub_20_support;
+	tgt_cfg.reg_domain = wma_handle->reg_cap.eeprom_rd;
+	tgt_cfg.eeprom_rd_ext = wma_handle->reg_cap.eeprom_rd_ext;
+
+	tgt_cfg.max_intf_count = wlan_res_cfg->num_vdevs;
+
+	qdf_mem_copy(tgt_cfg.hw_macaddr.bytes, wma_handle->hwaddr,
+		     ATH_MAC_LEN);
+
+	wma_update_target_services(wmi_handle, &tgt_cfg.services);
+	wma_update_target_ht_cap(tgt_hdl, &tgt_cfg.ht_cap);
+	wma_update_target_vht_cap(tgt_hdl, &tgt_cfg.vht_cap);
+	/*
+	 * This will overwrite the structure filled by wma_update_target_ht_cap
+	 * and wma_update_target_vht_cap APIs.
+	 */
+	wma_update_target_ext_ht_cap(tgt_hdl, &tgt_cfg.ht_cap);
+	wma_update_target_ext_vht_cap(tgt_hdl, &tgt_cfg.vht_cap);
+
+	wma_update_target_ext_he_cap(tgt_hdl, &tgt_cfg);
+
+	tgt_cfg.target_fw_version = target_if_get_fw_version(tgt_hdl);
+	if (service_ext_param)
+		tgt_cfg.target_fw_vers_ext =
+				service_ext_param->fw_build_vers_ext;
+
+	tgt_cfg.hw_bd_id = wma_handle->hw_bd_id;
+	tgt_cfg.hw_bd_info.bdf_version = wma_handle->hw_bd_info[BDF_VERSION];
+	tgt_cfg.hw_bd_info.ref_design_id =
+		wma_handle->hw_bd_info[REF_DESIGN_ID];
+	tgt_cfg.hw_bd_info.customer_id = wma_handle->hw_bd_info[CUSTOMER_ID];
+	tgt_cfg.hw_bd_info.project_id = wma_handle->hw_bd_info[PROJECT_ID];
+	tgt_cfg.hw_bd_info.board_data_rev =
+		wma_handle->hw_bd_info[BOARD_DATA_REV];
+
+#ifdef WLAN_FEATURE_LPSS
+	tgt_cfg.lpss_support = wma_handle->lpss_support;
+#endif /* WLAN_FEATURE_LPSS */
+	tgt_cfg.ap_arpns_support = wma_handle->ap_arpns_support;
+	tgt_cfg.dfs_cac_offload = wma_handle->is_dfs_offloaded;
+	tgt_cfg.rcpi_enabled = wma_handle->rcpi_enabled;
+	wma_update_ra_rate_limit(wma_handle, &tgt_cfg);
+	wma_update_hdd_band_cap(target_if_get_phy_capability(tgt_hdl),
+				&tgt_cfg);
+	wma_update_sar_version(service_ext_param, &tgt_cfg);
+	tgt_cfg.fine_time_measurement_cap =
+		target_if_get_wmi_fw_sub_feat_caps(tgt_hdl);
+	tgt_cfg.wmi_max_len = wmi_get_max_msg_len(wma_handle->wmi_handle)
+			      - WMI_TLV_HEADROOM;
+	tgt_cfg.tx_bfee_8ss_enabled = wma_handle->tx_bfee_8ss_enabled;
+	wma_update_obss_detection_support(wma_handle, &tgt_cfg);
+	wma_update_obss_color_collision_support(wma_handle, &tgt_cfg);
+	wma_update_hdd_cfg_ndp(wma_handle, &tgt_cfg);
+	wma_handle->tgt_cfg_update_cb(hdd_ctx, &tgt_cfg);
+	target_if_store_pdev_target_if_ctx(wma_get_pdev_from_scn_handle);
+	target_pdev_set_wmi_handle(wma_handle->pdev->tgt_if_handle,
+				   wma_handle->wmi_handle);
+	wma_green_ap_register_handlers(wma_handle);
+}
+
+/**
+ * wma_dump_dbs_hw_mode() - Print the DBS HW modes
+ * @wma_handle: WMA handle
+ *
+ * Prints the DBS HW modes sent by the FW as part
+ * of WMI ready event
+ *
+ * Return: None
+ */
+static void wma_dump_dbs_hw_mode(tp_wma_handle wma_handle)
+{
+	uint32_t i, param;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+		return;
+	}
+
+	for (i = 0; i < wma_handle->num_dbs_hw_modes; i++) {
+		param = wma_handle->hw_mode.hw_mode_list[i];
+		WMA_LOGD("%s:[%d]-MAC0: tx_ss:%d rx_ss:%d bw_idx:%d",
+			__func__, i,
+			WMA_HW_MODE_MAC0_TX_STREAMS_GET(param),
+			WMA_HW_MODE_MAC0_RX_STREAMS_GET(param),
+			WMA_HW_MODE_MAC0_BANDWIDTH_GET(param));
+		WMA_LOGD("%s:[%d]-MAC1: tx_ss:%d rx_ss:%d bw_idx:%d",
+			__func__, i,
+			WMA_HW_MODE_MAC1_TX_STREAMS_GET(param),
+			WMA_HW_MODE_MAC1_RX_STREAMS_GET(param),
+			WMA_HW_MODE_MAC1_BANDWIDTH_GET(param));
+		WMA_LOGD("%s:[%d] DBS:%d SBS:%d", __func__, i,
+			WMA_HW_MODE_DBS_MODE_GET(param),
+			WMA_HW_MODE_SBS_MODE_GET(param));
+	}
+	policy_mgr_dump_dbs_hw_mode(wma_handle->psoc);
+}
+
+/**
+ * wma_init_scan_fw_mode_config() - Initialize scan/fw mode config
+ * @psoc: Object manager psoc
+ * @scan_config: Scam mode configuration
+ * @fw_config: FW mode configuration
+ *
+ * Enables all the valid bits of concurrent_scan_config_bits and
+ * fw_mode_config_bits.
+ *
+ * Return: None
+ */
+static void wma_init_scan_fw_mode_config(struct wlan_objmgr_psoc *psoc,
+					 uint32_t scan_config,
+					 uint32_t fw_config)
+{
+	WMA_LOGD("%s: Enter", __func__);
+
+	if (!psoc) {
+		WMA_LOGE("%s: obj psoc is NULL", __func__);
+		return;
+	}
+
+	policy_mgr_init_dbs_config(psoc, scan_config, fw_config);
+}
+
+/**
+ * wma_update_ra_limit() - update ra limit based on apf filter
+ *  enabled or not
+ * @handle: wma handle
+ *
+ * Return: none
+ */
+#ifdef FEATURE_WLAN_RA_FILTERING
+static void wma_update_ra_limit(tp_wma_handle wma_handle)
+{
+	if (ucfg_pmo_is_apf_enabled(wma_handle->psoc))
+		wma_handle->IsRArateLimitEnabled = false;
+}
+#else
+static void wma_update_ra_limit(tp_wma_handle handle)
+{
+}
+#endif
+
+static void wma_set_pmo_caps(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+	tp_wma_handle wma;
+	struct pmo_device_caps caps;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		WMA_LOGE("%s: wma handler is null", __func__);
+		return;
+	}
+
+	caps.arp_ns_offload =
+		wmi_service_enabled(wma->wmi_handle, wmi_service_arpns_offload);
+	caps.apf =
+		wmi_service_enabled(wma->wmi_handle, wmi_service_apf_offload);
+	caps.packet_filter =
+		wmi_service_enabled(wma->wmi_handle,
+				    wmi_service_packet_filter_offload);
+	caps.unified_wow =
+		wmi_service_enabled(wma->wmi_handle,
+				    wmi_service_unified_wow_capability);
+	caps.li_offload =
+		wmi_service_enabled(wma->wmi_handle,
+				    wmi_service_listen_interval_offload_support
+				    );
+
+	status = ucfg_pmo_psoc_set_caps(psoc, &caps);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGE("Failed to set PMO capabilities; status:%d", status);
+}
+
+static void wma_set_component_caps(struct wlan_objmgr_psoc *psoc)
+{
+	wma_set_pmo_caps(psoc);
+}
+
+#if defined(WLAN_FEATURE_GTK_OFFLOAD) && defined(WLAN_POWER_MANAGEMENT_OFFLOAD)
+static QDF_STATUS wma_register_gtk_offload_event(tp_wma_handle wma_handle)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: wma_handle passed is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (wmi_service_enabled(wma_handle->wmi_handle,
+				wmi_service_gtk_offload)) {
+		status = wmi_unified_register_event_handler(
+					wma_handle->wmi_handle,
+					wmi_gtk_offload_status_event_id,
+					target_if_pmo_gtk_offload_status_event,
+					WMA_RX_WORK_CTX);
+	}
+	return status;
+}
+#else
+static QDF_STATUS wma_register_gtk_offload_event(tp_wma_handle wma_handle)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_GTK_OFFLOAD && WLAN_POWER_MANAGEMENT_OFFLOAD */
+
+/**
+ * wma_rx_service_ready_event() - event handler to process
+ *                                wmi rx sevice ready event.
+ * @handle: wma handle
+ * @cmd_param_info: command params info
+ *
+ * Return: none
+ */
+int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info,
+			       uint32_t length)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
+	wmi_service_ready_event_fixed_param *ev;
+	QDF_STATUS status;
+	uint32_t *ev_wlan_dbs_hw_mode_list;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct target_psoc_info *tgt_hdl;
+	struct wlan_psoc_target_capability_info *tgt_cap_info;
+	target_resource_config *wlan_res_cfg;
+	struct wmi_unified *wmi_handle;
+	uint32_t *service_bitmap;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	if (!handle) {
+		WMA_LOGE("%s: wma_handle passed is NULL", __func__);
+		return -EINVAL;
+	}
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
+	if (!tgt_hdl) {
+		WMA_LOGE("%s: target psoc info is NULL", __func__);
+		return -EINVAL;
+	}
+
+	wlan_res_cfg = target_psoc_get_wlan_res_cfg(tgt_hdl);
+	tgt_cap_info = target_psoc_get_target_caps(tgt_hdl);
+	service_bitmap = target_psoc_get_service_bitmap(tgt_hdl);
+
+	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid arguments", __func__);
+		return -EINVAL;
+	}
+
+	ev = param_buf->fixed_param;
+	if (!ev) {
+		WMA_LOGE("%s: Invalid buffer", __func__);
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(wma_handle->psoc);
+	if (!wmi_handle) {
+		WMA_LOGE("%s: wmi handle is NULL", __func__);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("WMA <-- WMI_SERVICE_READY_EVENTID");
+
+	if (ev->num_dbs_hw_modes > param_buf->num_wlan_dbs_hw_mode_list) {
+		WMA_LOGE("FW dbs_hw_mode entry %d more than value %d in TLV hdr",
+			 ev->num_dbs_hw_modes,
+			 param_buf->num_wlan_dbs_hw_mode_list);
+		return -EINVAL;
+	}
+
+	wma_handle->num_dbs_hw_modes = ev->num_dbs_hw_modes;
+	ev_wlan_dbs_hw_mode_list = param_buf->wlan_dbs_hw_mode_list;
+
+	/* Continuing with the rest of the processing,
+	 * even if memory allocation fails
+	 */
+	wma_handle->hw_mode.hw_mode_list =
+		qdf_mem_malloc(sizeof(*wma_handle->hw_mode.hw_mode_list) *
+				wma_handle->num_dbs_hw_modes);
+
+	if (wma_handle->hw_mode.hw_mode_list)
+		qdf_mem_copy(wma_handle->hw_mode.hw_mode_list,
+			     ev_wlan_dbs_hw_mode_list,
+			     (sizeof(*wma_handle->hw_mode.hw_mode_list) *
+			      wma_handle->num_dbs_hw_modes));
+
+	policy_mgr_init_dbs_hw_mode(wma_handle->psoc,
+	ev->num_dbs_hw_modes, ev_wlan_dbs_hw_mode_list);
+	wma_dump_dbs_hw_mode(wma_handle);
+
+	/* Initializes the fw_mode and scan_config to zero.
+	 * If ext service ready event is present it will set
+	 * the actual values of these two params.
+	 * This is to ensure that no garbage values would be
+	 * present in the absence of ext service ready event.
+	 */
+	wma_init_scan_fw_mode_config(wma_handle->psoc, 0, 0);
+
+	qdf_mem_copy(&wma_handle->reg_cap, param_buf->hal_reg_capabilities,
+				 sizeof(HAL_REG_CAPABILITIES));
+
+	wma_handle->vht_supp_mcs = ev->vht_supp_mcs;
+
+	wma_handle->new_hw_mode_index = tgt_cap_info->default_dbs_hw_mode_index;
+	policy_mgr_update_new_hw_mode_index(wma_handle->psoc,
+	tgt_cap_info->default_dbs_hw_mode_index);
+
+	WMA_LOGD("%s: Firmware default hw mode index : %d",
+		 __func__, tgt_cap_info->default_dbs_hw_mode_index);
+	WMA_LOGI("%s: Firmware build version : %08x",
+		 __func__, ev->fw_build_vers);
+	WMA_LOGD("FW fine time meas cap: 0x%x",
+		 tgt_cap_info->wmi_fw_sub_feat_caps);
+
+	wma_handle->hw_bd_id = ev->hw_bd_id;
+
+	wma_handle->hw_bd_info[BDF_VERSION] =
+		WMI_GET_BDF_VERSION(ev->hw_bd_info);
+	wma_handle->hw_bd_info[REF_DESIGN_ID] =
+		WMI_GET_REF_DESIGN(ev->hw_bd_info);
+	wma_handle->hw_bd_info[CUSTOMER_ID] =
+		WMI_GET_CUSTOMER_ID(ev->hw_bd_info);
+	wma_handle->hw_bd_info[PROJECT_ID] =
+		WMI_GET_PROJECT_ID(ev->hw_bd_info);
+	wma_handle->hw_bd_info[BOARD_DATA_REV] =
+		WMI_GET_BOARD_DATA_REV(ev->hw_bd_info);
+
+	WMA_LOGI("%s: Board id: %x, Board version: %x %x %x %x %x",
+		 __func__, wma_handle->hw_bd_id,
+		 wma_handle->hw_bd_info[BDF_VERSION],
+		 wma_handle->hw_bd_info[REF_DESIGN_ID],
+		 wma_handle->hw_bd_info[CUSTOMER_ID],
+		 wma_handle->hw_bd_info[PROJECT_ID],
+		 wma_handle->hw_bd_info[BOARD_DATA_REV]);
+
+	/* wmi service is ready */
+	qdf_mem_copy(wma_handle->wmi_service_bitmap,
+		     service_bitmap,
+		     sizeof(wma_handle->wmi_service_bitmap));
+
+	cdp_cfg_tx_set_is_mgmt_over_wmi_enabled(soc,
+		wmi_service_enabled(wmi_handle, wmi_service_mgmt_tx_wmi));
+	cdp_set_desc_global_pool_size(soc, ev->num_msdu_desc);
+	/* SWBA event handler for beacon transmission */
+	status = wmi_unified_register_event_handler(wmi_handle,
+						    wmi_host_swba_event_id,
+						    wma_beacon_swba_handler,
+						    WMA_RX_SERIALIZER_CTX);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Failed to register swba beacon event cb");
+		goto free_hw_mode_list;
+	}
+#ifdef WLAN_FEATURE_LPSS
+	wma_handle->lpss_support =
+		wmi_service_enabled(wmi_handle, wmi_service_lpass);
+#endif /* WLAN_FEATURE_LPSS */
+
+	/*
+	 * This Service bit is added to check for ARP/NS Offload
+	 * support for LL/HL targets
+	 */
+	wma_handle->ap_arpns_support =
+		wmi_service_enabled(wmi_handle, wmi_service_ap_arpns_offload);
+
+	wma_update_ra_limit(wma_handle);
+
+	if (wmi_service_enabled(wmi_handle, wmi_service_csa_offload)) {
+		WMA_LOGD("%s: FW support CSA offload capability", __func__);
+		status = wmi_unified_register_event_handler(
+						wmi_handle,
+						wmi_csa_handling_event_id,
+						wma_csa_offload_handler,
+						WMA_RX_SERIALIZER_CTX);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			WMA_LOGE("Failed to register CSA offload event cb");
+			goto free_hw_mode_list;
+		}
+	}
+
+	if (wmi_service_enabled(wmi_handle, wmi_service_mgmt_tx_wmi)) {
+		WMA_LOGD("Firmware supports management TX over WMI,use WMI interface instead of HTT for management Tx");
+		/*
+		 * Register Tx completion event handler for MGMT Tx over WMI
+		 * case
+		 */
+		status = wmi_unified_register_event_handler(
+					wmi_handle,
+					wmi_mgmt_tx_completion_event_id,
+					wma_mgmt_tx_completion_handler,
+					WMA_RX_SERIALIZER_CTX);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			WMA_LOGE("Failed to register MGMT over WMI completion handler");
+			goto free_hw_mode_list;
+		}
+
+		status = wmi_unified_register_event_handler(
+				wmi_handle,
+				wmi_mgmt_tx_bundle_completion_event_id,
+				wma_mgmt_tx_bundle_completion_handler,
+				WMA_RX_SERIALIZER_CTX);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			WMA_LOGE("Failed to register MGMT over WMI completion handler");
+			goto free_hw_mode_list;
+		}
+
+	} else {
+		WMA_LOGE("FW doesnot support WMI_SERVICE_MGMT_TX_WMI, Use HTT interface for Management Tx");
+	}
+
+	status = wma_register_gtk_offload_event(wma_handle);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Failed to register GTK offload event cb");
+		goto free_hw_mode_list;
+	}
+
+	status = wmi_unified_register_event_handler(wmi_handle,
+				wmi_tbttoffset_update_event_id,
+				wma_tbttoffset_update_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Failed to register WMI_TBTTOFFSET_UPDATE_EVENTID callback");
+		goto free_hw_mode_list;
+	}
+
+	if (wmi_service_enabled(wma_handle->wmi_handle,
+				   wmi_service_rcpi_support)) {
+		/* register for rcpi response event */
+		status = wmi_unified_register_event_handler(
+							wmi_handle,
+							wmi_update_rcpi_event_id,
+							wma_rcpi_event_handler,
+							WMA_RX_SERIALIZER_CTX);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			WMA_LOGE("Failed to register RCPI event handler");
+			goto free_hw_mode_list;
+		}
+		wma_handle->rcpi_enabled = true;
+	}
+
+	/* mac_id is replaced with pdev_id in converged firmware to have
+	 * multi-radio support. In order to maintain backward compatibility
+	 * with old fw, host needs to check WMI_SERVICE_DEPRECATED_REPLACE
+	 * in service bitmap from FW and host needs to set use_pdev_id in
+	 * wmi_resource_config to true. If WMI_SERVICE_DEPRECATED_REPLACE
+	 * service is not set, then host shall not expect MAC ID from FW in
+	 * VDEV START RESPONSE event and host shall use PDEV ID.
+	 */
+	if (wmi_service_enabled(wmi_handle, wmi_service_deprecated_replace))
+		wlan_res_cfg->use_pdev_id = true;
+	else
+		wlan_res_cfg->use_pdev_id = false;
+
+	wlan_res_cfg->max_num_dbs_scan_duty_cycle = CDS_DBS_SCAN_CLIENTS_MAX;
+
+	/* Initialize the log supported event handler */
+	status = wmi_unified_register_event_handler(wmi_handle,
+			wmi_diag_event_id_log_supported_event_id,
+			wma_log_supported_evt_handler,
+			WMA_RX_SERIALIZER_CTX);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Failed to register log supported event cb");
+		goto free_hw_mode_list;
+	}
+
+	cdp_mark_first_wakeup_packet(soc,
+		wmi_service_enabled(wmi_handle,
+			wmi_service_mark_first_wakeup_packet));
+	wma_handle->is_dfs_offloaded =
+		wmi_service_enabled(wmi_handle,
+			wmi_service_dfs_phyerr_offload);
+
+	wma_handle->nan_datapath_enabled =
+		wmi_service_enabled(wma_handle->wmi_handle,
+			wmi_service_nan_data);
+
+	wma_set_component_caps(wma_handle->psoc);
+
+	wma_update_fw_config(wma_handle->psoc, tgt_hdl);
+
+	status = wmi_unified_save_fw_version_cmd(wmi_handle, param_buf);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Failed to send WMI_INIT_CMDID command");
+		goto free_hw_mode_list;
+	}
+
+	if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) {
+		status = qdf_mc_timer_start(
+				&wma_handle->service_ready_ext_timer,
+				WMA_SERVICE_READY_EXT_TIMEOUT);
+		if (QDF_IS_STATUS_ERROR(status))
+			WMA_LOGE("Failed to start the service ready ext timer");
+	}
+	wma_handle->tx_bfee_8ss_enabled =
+		wmi_service_enabled(wmi_handle, wmi_service_8ss_tx_bfee);
+
+	target_psoc_set_num_radios(tgt_hdl, 1);
+
+	return 0;
+
+free_hw_mode_list:
+	if (wma_handle->hw_mode.hw_mode_list) {
+		qdf_mem_free(wma_handle->hw_mode.hw_mode_list);
+		wma_handle->hw_mode.hw_mode_list = NULL;
+		WMA_LOGD("%s: DBS list is freed", __func__);
+	}
+
+	return -EINVAL;
+
+}
+
+/**
+ * wma_get_phyid_for_given_band() - to get phyid for band
+ *
+ * @wma_handle: Pointer to wma handle
+*  @tgt_hdl: target psoc information
+ * @band: enum value of for 2G or 5G band
+ * @phyid: Pointer to phyid which needs to be filled
+ *
+ * This API looks in to the map to find out which particular phy supports
+ * provided band and return the idx (also called phyid) of that phy. Caller
+ * use this phyid to fetch various caps of that phy
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS wma_get_phyid_for_given_band(
+			tp_wma_handle wma_handle,
+			struct target_psoc_info *tgt_hdl,
+			enum cds_band_type band, uint8_t *phyid)
+{
+	uint8_t idx, i, num_radios;
+	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
+
+	if (!wma_handle) {
+		WMA_LOGE("Invalid wma handle");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	idx = 0;
+	*phyid = idx;
+	num_radios = target_psoc_get_num_radios(tgt_hdl);
+	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
+
+	for (i = 0; i < num_radios; i++) {
+		if ((band == CDS_BAND_2GHZ) &&
+		(WLAN_2G_CAPABILITY == mac_phy_cap[idx + i].supported_bands)) {
+			*phyid = idx + i;
+			WMA_LOGD("Select 2G capable phyid[%d]", *phyid);
+			return QDF_STATUS_SUCCESS;
+		} else if ((band == CDS_BAND_5GHZ) &&
+		(WLAN_5G_CAPABILITY == mac_phy_cap[idx + i].supported_bands)) {
+			*phyid = idx + i;
+			WMA_LOGD("Select 5G capable phyid[%d]", *phyid);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	WMA_LOGD("Using default single hw mode phyid[%d]", *phyid);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_get_caps_for_phyidx_hwmode() - to fetch caps for given hw mode and band
+ * @caps_per_phy: Pointer to capabilities structure which needs to be filled
+ * @hw_mode: Provided hardware mode
+ * @band: Provide band i.e. 2G or 5G
+ *
+ * This API finds cap which suitable for provided hw mode and band. If user
+ * is provides some invalid hw mode then it will automatically falls back to
+ * default hw mode
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_get_caps_for_phyidx_hwmode(struct wma_caps_per_phy *caps_per_phy,
+		enum hw_mode_dbs_capab hw_mode, enum cds_band_type band)
+{
+	t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	struct target_psoc_info *tgt_hdl;
+	int ht_cap_info, vht_cap_info;
+	uint8_t phyid, our_hw_mode = hw_mode, num_hw_modes;
+	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
+
+	if (!wma_handle) {
+		WMA_LOGE("Invalid wma handle");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
+	if (!tgt_hdl) {
+		WMA_LOGE("%s: target psoc info is NULL", __func__);
+		return -EINVAL;
+	}
+
+	ht_cap_info = target_if_get_ht_cap_info(tgt_hdl);
+	vht_cap_info = target_if_get_vht_cap_info(tgt_hdl);
+	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
+	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
+
+	if (!num_hw_modes) {
+		WMA_LOGD("Invalid number of hw modes, use legacy HT/VHT caps");
+		caps_per_phy->ht_2g = ht_cap_info;
+		caps_per_phy->ht_5g = ht_cap_info;
+		caps_per_phy->vht_2g = vht_cap_info;
+		caps_per_phy->vht_5g = vht_cap_info;
+		/* legacy platform doesn't support HE IE */
+		caps_per_phy->he_2g[0] = 0;
+		caps_per_phy->he_2g[1] = 0;
+		caps_per_phy->he_5g[0] = 0;
+		caps_per_phy->he_5g[1] = 0;
+
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (!policy_mgr_is_dbs_enable(wma_handle->psoc))
+		our_hw_mode = HW_MODE_DBS_NONE;
+
+	if (!caps_per_phy) {
+		WMA_LOGE("Invalid caps pointer");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (QDF_STATUS_SUCCESS !=
+		wma_get_phyid_for_given_band(wma_handle, tgt_hdl, band, &phyid)) {
+		WMA_LOGE("Invalid phyid");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	caps_per_phy->ht_2g = mac_phy_cap[phyid].ht_cap_info_2G;
+	caps_per_phy->ht_5g = mac_phy_cap[phyid].ht_cap_info_5G;
+	caps_per_phy->vht_2g = mac_phy_cap[phyid].vht_cap_info_2G;
+	caps_per_phy->vht_5g = mac_phy_cap[phyid].vht_cap_info_5G;
+	qdf_mem_copy(caps_per_phy->he_2g, mac_phy_cap[phyid].he_cap_info_2G,
+		     sizeof(caps_per_phy->he_2g));
+	qdf_mem_copy(caps_per_phy->he_5g, mac_phy_cap[phyid].he_cap_info_5G,
+		     sizeof(caps_per_phy->he_5g));
+
+	caps_per_phy->tx_chain_mask_2G = mac_phy_cap->tx_chain_mask_2G;
+	caps_per_phy->rx_chain_mask_2G = mac_phy_cap->rx_chain_mask_2G;
+	caps_per_phy->tx_chain_mask_5G = mac_phy_cap->tx_chain_mask_5G;
+	caps_per_phy->rx_chain_mask_5G = mac_phy_cap->rx_chain_mask_5G;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_is_rx_ldpc_supported_for_channel() - to find out if ldpc is supported
+ *
+ * @channel: Channel number for which it needs to check if rx ldpc is enabled
+ *
+ * This API takes channel number as argument and takes default hw mode as DBS
+ * to check if rx LDPC support is enabled for that channel or no
+ */
+bool wma_is_rx_ldpc_supported_for_channel(uint32_t channel)
+{
+	t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	struct target_psoc_info *tgt_hdl;
+	struct wma_caps_per_phy caps_per_phy = {0};
+	enum cds_band_type band;
+	bool status;
+	uint8_t num_hw_modes;
+
+	if (!wma_handle) {
+		WMA_LOGE("Invalid wma handle");
+		return false;
+	}
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
+	if (!tgt_hdl) {
+		WMA_LOGE("Target handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
+
+	if (!WLAN_REG_IS_24GHZ_CH(channel))
+		band = CDS_BAND_5GHZ;
+	else
+		band = CDS_BAND_2GHZ;
+
+	if (QDF_STATUS_SUCCESS != wma_get_caps_for_phyidx_hwmode(
+						&caps_per_phy,
+						HW_MODE_DBS, band)) {
+		return false;
+	}
+
+	/*
+	 * Legacy platforms like Rome set WMI_HT_CAP_LDPC to specify RX LDPC
+	 * capability. But new platforms like Helium set WMI_HT_CAP_RX_LDPC
+	 * instead.
+	 */
+	if (0 == num_hw_modes) {
+		status = (!!(caps_per_phy.ht_2g & WMI_HT_CAP_LDPC));
+	} else {
+		if (WLAN_REG_IS_24GHZ_CH(channel))
+			status = (!!(caps_per_phy.ht_2g & WMI_HT_CAP_RX_LDPC));
+		else
+			status = (!!(caps_per_phy.ht_5g & WMI_HT_CAP_RX_LDPC));
+	}
+
+	return status;
+}
+
+/**
+ * wma_print_mac_phy_capabilities() - Prints MAC PHY capabilities
+ * @cap: pointer to WMI_MAC_PHY_CAPABILITIES
+ * @index: MAC_PHY index
+ *
+ * Return: none
+ */
+static void wma_print_mac_phy_capabilities(struct wlan_psoc_host_mac_phy_caps
+					   *cap, int index)
+{
+	uint32_t mac_2G[PSOC_HOST_MAX_MAC_SIZE];
+	uint32_t mac_5G[PSOC_HOST_MAX_MAC_SIZE];
+	uint32_t phy_2G[WMI_MAX_HECAP_PHY_SIZE];
+	uint32_t phy_5G[WMI_MAX_HECAP_PHY_SIZE];
+	struct wlan_psoc_host_ppe_threshold ppet_2G, ppet_5G;
+
+	WMA_LOGD("\t: index [%d]", index);
+	WMA_LOGD("\t: cap for hw_mode_id[%d]", cap->hw_mode_id);
+	WMA_LOGD("\t: pdev_id[%d]", cap->pdev_id);
+	WMA_LOGD("\t: phy_id[%d]", cap->phy_id);
+	WMA_LOGD("\t: supports_11b[%d]", cap->supports_11b);
+	WMA_LOGD("\t: supports_11g[%d]", cap->supports_11g);
+	WMA_LOGD("\t: supports_11a[%d]", cap->supports_11a);
+	WMA_LOGD("\t: supports_11n[%d]", cap->supports_11n);
+	WMA_LOGD("\t: supports_11ac[%d]", cap->supports_11ac);
+	WMA_LOGD("\t: supports_11ax[%d]", cap->supports_11ax);
+	WMA_LOGD("\t: supported_bands[%d]", cap->supported_bands);
+	WMA_LOGD("\t: ampdu_density[%d]", cap->ampdu_density);
+	WMA_LOGD("\t: max_bw_supported_2G[%d]", cap->max_bw_supported_2G);
+	WMA_LOGD("\t: ht_cap_info_2G[%d]", cap->ht_cap_info_2G);
+	WMA_LOGD("\t: vht_cap_info_2G[%d]", cap->vht_cap_info_2G);
+	WMA_LOGD("\t: vht_supp_mcs_2G[%d]", cap->vht_supp_mcs_2G);
+	WMA_LOGD("\t: tx_chain_mask_2G[%d]", cap->tx_chain_mask_2G);
+	WMA_LOGD("\t: rx_chain_mask_2G[%d]", cap->rx_chain_mask_2G);
+	WMA_LOGD("\t: max_bw_supported_5G[%d]", cap->max_bw_supported_5G);
+	WMA_LOGD("\t: ht_cap_info_5G[%d]", cap->ht_cap_info_5G);
+	WMA_LOGD("\t: vht_cap_info_5G[%d]", cap->vht_cap_info_5G);
+	WMA_LOGD("\t: vht_supp_mcs_5G[%d]", cap->vht_supp_mcs_5G);
+	WMA_LOGD("\t: tx_chain_mask_5G[%d]", cap->tx_chain_mask_5G);
+	WMA_LOGD("\t: rx_chain_mask_5G[%d]", cap->rx_chain_mask_5G);
+	WMA_LOGD("\t: he_cap_info_2G[0][%08x]", cap->he_cap_info_2G[0]);
+	WMA_LOGD("\t: he_cap_info_2G[1][%08x]", cap->he_cap_info_2G[1]);
+	WMA_LOGD("\t: he_supp_mcs_2G[%08x]", cap->he_supp_mcs_2G);
+	WMA_LOGD("\t: he_cap_info_5G[0][%08x]", cap->he_cap_info_5G[0]);
+	WMA_LOGD("\t: he_cap_info_5G[1][%08x]", cap->he_cap_info_5G[1]);
+	WMA_LOGD("\t: he_supp_mcs_5G[%08x]", cap->he_supp_mcs_5G);
+	qdf_mem_copy(mac_2G, cap->he_cap_info_2G, sizeof(mac_2G));
+	qdf_mem_copy(mac_5G, cap->he_cap_info_5G, sizeof(mac_5G));
+	qdf_mem_copy(phy_2G, cap->he_cap_phy_info_2G,
+		     WMI_MAX_HECAP_PHY_SIZE * 4);
+	qdf_mem_copy(phy_5G, cap->he_cap_phy_info_5G,
+		     WMI_MAX_HECAP_PHY_SIZE * 4);
+	ppet_2G = cap->he_ppet2G;
+	ppet_5G = cap->he_ppet5G;
+
+	wma_print_he_mac_cap_w1(mac_2G[0]);
+	wma_print_he_mac_cap_w2(mac_2G[1]);
+	wma_print_he_phy_cap(phy_2G);
+	wma_print_he_ppet(&ppet_2G);
+	wma_print_he_mac_cap_w1(mac_5G[0]);
+	wma_print_he_mac_cap_w1(mac_5G[1]);
+	wma_print_he_phy_cap(phy_5G);
+	wma_print_he_ppet(&ppet_5G);
+}
+
+/**
+ * wma_print_populate_soc_caps() - Prints all the caps populated per hw mode
+ * @tgt_info: target related info
+ *
+ * This function prints all the caps populater per hw mode and per PHY
+ *
+ * Return: none
+ */
+static void wma_print_populate_soc_caps(struct target_psoc_info *tgt_hdl)
+{
+	int i, num_hw_modes, total_mac_phy_cnt;
+	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap, *tmp;
+
+	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
+	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
+
+	/* print number of hw modes */
+	WMA_LOGD("%s: num of hw modes [%d]", __func__, num_hw_modes);
+	WMA_LOGD("%s: num mac_phy_cnt [%d]", __func__, total_mac_phy_cnt);
+	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
+	WMA_LOGD("%s: <====== HW mode cap printing starts ======>", __func__);
+	/* print cap of each hw mode */
+	for (i = 0; i < total_mac_phy_cnt; i++) {
+		WMA_LOGD("====>: hw mode id[%d], phy id[%d]",
+			 mac_phy_cap[i].hw_mode_id,
+			 mac_phy_cap[i].phy_id);
+		tmp = &mac_phy_cap[i];
+		wma_print_mac_phy_capabilities(tmp, i);
+	}
+	WMA_LOGD("%s: <====== HW mode cap printing ends ======>\n", __func__);
+}
+
+/**
+ * wma_map_wmi_channel_width_to_hw_mode_bw() - returns bandwidth
+ * in terms of hw_mode_bandwidth
+ * @width: bandwidth in terms of wmi_channel_width
+ *
+ * This function returns the bandwidth in terms of hw_mode_bandwidth.
+ *
+ * Return: BW in terms of hw_mode_bandwidth.
+ */
+static enum hw_mode_bandwidth wma_map_wmi_channel_width_to_hw_mode_bw(
+			wmi_channel_width width)
+{
+	switch (width) {
+	case WMI_CHAN_WIDTH_20:
+		return HW_MODE_20_MHZ;
+	case WMI_CHAN_WIDTH_40:
+		return HW_MODE_40_MHZ;
+	case WMI_CHAN_WIDTH_80:
+		return HW_MODE_80_MHZ;
+	case WMI_CHAN_WIDTH_160:
+		return HW_MODE_160_MHZ;
+	case WMI_CHAN_WIDTH_80P80:
+		return HW_MODE_80_PLUS_80_MHZ;
+	case WMI_CHAN_WIDTH_5:
+		return HW_MODE_5_MHZ;
+	case WMI_CHAN_WIDTH_10:
+		return HW_MODE_10_MHZ;
+	default:
+		return HW_MODE_BW_NONE;
+	}
+
+	return HW_MODE_BW_NONE;
+}
+
+/**
+ * wma_get_hw_mode_params() - get TX-RX stream and bandwidth
+ * supported from the capabilities.
+ * @caps: PHY capability
+ * @info: param to store TX-RX stream and BW information
+ *
+ * This function will calculate TX-RX stream and bandwidth supported
+ * as per the PHY capability, and assign to mac_ss_bw_info.
+ *
+ * Return: none
+ */
+static void wma_get_hw_mode_params(struct wlan_psoc_host_mac_phy_caps *caps,
+			struct mac_ss_bw_info *info)
+{
+	if (!caps) {
+		WMA_LOGE("%s: Invalid capabilities", __func__);
+		return;
+	}
+
+	info->mac_tx_stream = wma_get_num_of_setbits_from_bitmask(
+				QDF_MAX(caps->tx_chain_mask_2G,
+					caps->tx_chain_mask_5G));
+	info->mac_rx_stream = wma_get_num_of_setbits_from_bitmask(
+				QDF_MAX(caps->rx_chain_mask_2G,
+					caps->rx_chain_mask_5G));
+	info->mac_bw = wma_map_wmi_channel_width_to_hw_mode_bw(
+				QDF_MAX(caps->max_bw_supported_2G,
+					caps->max_bw_supported_5G));
+}
+
+/**
+ * wma_set_hw_mode_params() - sets TX-RX stream, bandwidth and
+ * DBS in hw_mode_list
+ * @wma_handle: pointer to wma global structure
+ * @mac0_ss_bw_info: TX-RX streams, BW for MAC0
+ * @mac1_ss_bw_info: TX-RX streams, BW for MAC1
+ * @pos: refers to hw_mode_index
+ * @dbs_mode: dbs_mode for the dbs_hw_mode
+ * @sbs_mode: sbs_mode for the sbs_hw_mode
+ *
+ * This function sets TX-RX stream, bandwidth and DBS mode in
+ * hw_mode_list.
+ *
+ * Return: none
+ */
+static void wma_set_hw_mode_params(t_wma_handle *wma_handle,
+			struct mac_ss_bw_info mac0_ss_bw_info,
+			struct mac_ss_bw_info mac1_ss_bw_info,
+			uint32_t pos, uint32_t dbs_mode,
+			uint32_t sbs_mode)
+{
+	WMA_HW_MODE_MAC0_TX_STREAMS_SET(
+		wma_handle->hw_mode.hw_mode_list[pos],
+		mac0_ss_bw_info.mac_tx_stream);
+	WMA_HW_MODE_MAC0_RX_STREAMS_SET(
+		wma_handle->hw_mode.hw_mode_list[pos],
+		mac0_ss_bw_info.mac_rx_stream);
+	WMA_HW_MODE_MAC0_BANDWIDTH_SET(
+		wma_handle->hw_mode.hw_mode_list[pos],
+		mac0_ss_bw_info.mac_bw);
+	WMA_HW_MODE_MAC1_TX_STREAMS_SET(
+		wma_handle->hw_mode.hw_mode_list[pos],
+		mac1_ss_bw_info.mac_tx_stream);
+	WMA_HW_MODE_MAC1_RX_STREAMS_SET(
+		wma_handle->hw_mode.hw_mode_list[pos],
+		mac1_ss_bw_info.mac_rx_stream);
+	WMA_HW_MODE_MAC1_BANDWIDTH_SET(
+		wma_handle->hw_mode.hw_mode_list[pos],
+		mac1_ss_bw_info.mac_bw);
+	WMA_HW_MODE_DBS_MODE_SET(
+		wma_handle->hw_mode.hw_mode_list[pos],
+		dbs_mode);
+	WMA_HW_MODE_AGILE_DFS_SET(
+		wma_handle->hw_mode.hw_mode_list[pos],
+		HW_MODE_AGILE_DFS_NONE);
+	WMA_HW_MODE_SBS_MODE_SET(
+		wma_handle->hw_mode.hw_mode_list[pos],
+		sbs_mode);
+}
+
+/**
+ * wma_update_hw_mode_list() - updates hw_mode_list
+ * @wma_handle: pointer to wma global structure
+ * @tgt_hdl - target psoc information
+ *
+ * This function updates hw_mode_list with tx_streams, rx_streams,
+ * bandwidth, dbs and agile dfs for each hw_mode.
+ *
+ * Returns: 0 for success else failure.
+ */
+static QDF_STATUS wma_update_hw_mode_list(t_wma_handle *wma_handle,
+					  struct target_psoc_info *tgt_hdl)
+{
+	struct wlan_psoc_host_mac_phy_caps *tmp, *mac_phy_cap;
+	uint32_t i, hw_config_type, j = 0;
+	uint32_t dbs_mode, sbs_mode;
+	struct mac_ss_bw_info mac0_ss_bw_info = {0};
+	struct mac_ss_bw_info mac1_ss_bw_info = {0};
+	WMI_PHY_CAPABILITY new_supported_band = 0;
+	bool supported_band_update_failure = false;
+	struct wlan_psoc_target_capability_info *tgt_cap_info;
+	int num_hw_modes;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: Invalid wma handle", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
+	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
+	tgt_cap_info = target_psoc_get_target_caps(tgt_hdl);
+	/*
+	 * This list was updated as part of service ready event. Re-populate
+	 * HW mode list from the device capabilities.
+	 */
+	if (wma_handle->hw_mode.hw_mode_list) {
+		qdf_mem_free(wma_handle->hw_mode.hw_mode_list);
+		wma_handle->hw_mode.hw_mode_list = NULL;
+		WMA_LOGD("%s: DBS list is freed", __func__);
+	}
+
+	wma_handle->hw_mode.hw_mode_list =
+		qdf_mem_malloc(sizeof(*wma_handle->hw_mode.hw_mode_list) *
+			       num_hw_modes);
+	if (!wma_handle->hw_mode.hw_mode_list) {
+		wma_handle->num_dbs_hw_modes = 0;
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("%s: Updated HW mode list: Num modes:%d",
+		 __func__, num_hw_modes);
+
+	wma_handle->num_dbs_hw_modes = num_hw_modes;
+	for (i = 0; i < num_hw_modes; i++) {
+		/* Update for MAC0 */
+		tmp = &mac_phy_cap[j++];
+		wma_get_hw_mode_params(tmp, &mac0_ss_bw_info);
+		hw_config_type = mac_phy_cap[j].hw_mode_config_type;
+		dbs_mode = HW_MODE_DBS_NONE;
+		sbs_mode = HW_MODE_SBS_NONE;
+		mac1_ss_bw_info.mac_tx_stream = 0;
+		mac1_ss_bw_info.mac_rx_stream = 0;
+		mac1_ss_bw_info.mac_bw = 0;
+		if (wma_update_supported_bands(tmp->supported_bands,
+						&new_supported_band)
+		   != QDF_STATUS_SUCCESS)
+			supported_band_update_failure = true;
+
+		/* SBS and DBS have dual MAC. Upto 2 MACs are considered. */
+		if ((hw_config_type == WMI_HW_MODE_DBS) ||
+		    (hw_config_type == WMI_HW_MODE_SBS_PASSIVE) ||
+		    (hw_config_type == WMI_HW_MODE_SBS)) {
+			/* Update for MAC1 */
+			tmp = &mac_phy_cap[j++];
+			wma_get_hw_mode_params(tmp, &mac1_ss_bw_info);
+			if (hw_config_type == WMI_HW_MODE_DBS)
+				dbs_mode = HW_MODE_DBS;
+			if ((hw_config_type == WMI_HW_MODE_SBS_PASSIVE) ||
+			    (hw_config_type == WMI_HW_MODE_SBS))
+				sbs_mode = HW_MODE_SBS;
+			if (QDF_STATUS_SUCCESS !=
+			wma_update_supported_bands(tmp->supported_bands,
+						&new_supported_band))
+				supported_band_update_failure = true;
+		}
+
+		/* Updating HW mode list */
+		wma_set_hw_mode_params(wma_handle, mac0_ss_bw_info,
+				       mac1_ss_bw_info, i, dbs_mode,
+				       sbs_mode);
+	}
+
+	/* overwrite phy_capability which we got from service ready event */
+	if (!supported_band_update_failure) {
+		WMA_LOGD("%s: updating supported band from old[%d] to new[%d]",
+			 __func__, target_if_get_phy_capability(tgt_hdl),
+			 new_supported_band);
+		target_if_set_phy_capability(tgt_hdl, new_supported_band);
+	}
+
+	if (QDF_STATUS_SUCCESS !=
+			policy_mgr_update_hw_mode_list(wma_handle->psoc,
+						       tgt_hdl))
+		WMA_LOGE("%s: failed to update policy manager", __func__);
+	wma_dump_dbs_hw_mode(wma_handle);
+	return QDF_STATUS_SUCCESS;
+}
+
+static void wma_init_wifi_pos_dma_rings(t_wma_handle *wma_handle,
+					uint8_t num_mac, void *buf)
+{
+	struct hif_softc *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+	void *hal_soc;
+
+	if (!hif_ctx) {
+		WMA_LOGE("invalid hif context");
+		return;
+	}
+
+	hal_soc = hif_get_hal_handle(hif_ctx);
+
+	wifi_pos_init_cir_cfr_rings(wma_handle->psoc, hal_soc, num_mac, buf);
+}
+
+/**
+ * wma_populate_soc_caps() - populate entire SOC's capabilities
+ * @wma_handle: pointer to wma global structure
+ * @tgt_hdl: target psoc information
+ * @param_buf: pointer to param of service ready extension event from fw
+ *
+ * This API populates all capabilities of entire SOC. For example,
+ * how many number of hw modes are supported by this SOC, what are the
+ * capabilities of each phy per hw mode, what are HAL reg capabilities per
+ * phy.
+ *
+ * Return: none
+ */
+static void wma_populate_soc_caps(t_wma_handle *wma_handle,
+				  struct target_psoc_info *tgt_hdl,
+			WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf)
+{
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	wma_init_wifi_pos_dma_rings(wma_handle,
+				    param_buf->num_oem_dma_ring_caps,
+				    param_buf->oem_dma_ring_caps);
+
+	wma_print_populate_soc_caps(tgt_hdl);
+}
+
+/**
+ * wma_rx_service_ready_ext_event() - evt handler for sevice ready ext event.
+ * @handle: wma handle
+ * @event: params of the service ready extended event
+ * @length: param length
+ *
+ * Return: none
+ */
+int wma_rx_service_ready_ext_event(void *handle, uint8_t *event,
+					uint32_t length)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
+	wmi_service_ready_ext_event_fixed_param *ev;
+	QDF_STATUS ret;
+	struct target_psoc_info *tgt_hdl;
+	uint32_t conc_scan_config_bits, fw_config_bits;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+		return -EINVAL;
+	}
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
+	if (!tgt_hdl) {
+		WMA_LOGE("%s: target psoc info is NULL", __func__);
+		return -EINVAL;
+	}
+
+	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid event", __func__);
+		return -EINVAL;
+	}
+
+	ev = param_buf->fixed_param;
+	if (!ev) {
+		WMA_LOGE("%s: Invalid buffer", __func__);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("WMA <-- WMI_SERVICE_READY_EXT_EVENTID");
+
+	fw_config_bits = target_if_get_fw_config_bits(tgt_hdl);
+	conc_scan_config_bits = target_if_get_conc_scan_config_bits(tgt_hdl);
+
+	WMA_LOGD("%s: Defaults: scan config:%x FW mode config:%x",
+		__func__, conc_scan_config_bits, fw_config_bits);
+
+	ret = qdf_mc_timer_stop(&wma_handle->service_ready_ext_timer);
+	if (!QDF_IS_STATUS_SUCCESS(ret)) {
+		WMA_LOGE("Failed to stop the service ready ext timer");
+		return -EINVAL;
+	}
+	wma_populate_soc_caps(wma_handle, tgt_hdl, param_buf);
+
+	ret = wma_update_hw_mode_list(wma_handle, tgt_hdl);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Failed to update hw mode list");
+		return -EINVAL;
+	}
+
+	WMA_LOGD("WMA --> WMI_INIT_CMDID");
+
+	wma_init_scan_fw_mode_config(wma_handle->psoc, conc_scan_config_bits,
+				     fw_config_bits);
+
+	target_psoc_set_num_radios(tgt_hdl, 1);
+	return 0;
+}
+
+/**
+ * wma_rx_ready_event() - event handler to process
+ *                        wmi rx ready event.
+ * @handle: wma handle
+ * @cmd_param_info: command params info
+ * @length: param length
+ *
+ * Return: none
+ */
+int wma_rx_ready_event(void *handle, uint8_t *cmd_param_info,
+					uint32_t length)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
+	wmi_ready_event_fixed_param *ev = NULL;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	param_buf = (WMI_READY_EVENTID_param_tlvs *) cmd_param_info;
+	if (!(wma_handle && param_buf)) {
+		WMA_LOGE("%s: Invalid arguments", __func__);
+		QDF_ASSERT(0);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("WMA <-- WMI_READY_EVENTID");
+
+	ev = param_buf->fixed_param;
+	/* Indicate to the waiting thread that the ready
+	 * event was received
+	 */
+	wma_handle->sub_20_support =
+		wmi_service_enabled(wma_handle->wmi_handle,
+				wmi_service_half_rate_quarter_rate_support);
+	wma_handle->wmi_ready = true;
+	wma_handle->wlan_init_status = ev->status;
+
+	if (wma_handle->is_dfs_offloaded)
+		wmi_unified_dfs_phyerr_offload_en_cmd(
+				wma_handle->wmi_handle, 0);
+	/* copy the mac addr */
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, wma_handle->myaddr);
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, wma_handle->hwaddr);
+	wma_update_hdd_cfg(wma_handle);
+	WMA_LOGD("Exit");
+
+	return 0;
+}
+
+/**
+ * wma_setneedshutdown() - setting wma needshutdown flag
+ *
+ * Return: none
+ */
+void wma_setneedshutdown(void)
+{
+	tp_wma_handle wma_handle;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: Invalid arguments", __func__);
+		QDF_ASSERT(0);
+		return;
+	}
+
+	wma_handle->needShutdown = true;
+	WMA_LOGD("%s: Exit", __func__);
+}
+
+/**
+ * wma_needshutdown() - Is wma needs shutdown?
+ *
+ * Return: returns true/false
+ */
+bool wma_needshutdown(void)
+{
+	tp_wma_handle wma_handle;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: Invalid arguments", __func__);
+		QDF_ASSERT(0);
+		return false;
+	}
+
+	WMA_LOGD("%s: Exit", __func__);
+	return wma_handle->needShutdown;
+}
+
+/**
+ * wma_wait_for_ready_event() - wait for wma ready event
+ * @handle: wma handle
+ *
+ * Return: 0 for success or QDF error
+ */
+QDF_STATUS wma_wait_for_ready_event(WMA_HANDLE handle)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle)handle;
+	QDF_STATUS status;
+	struct target_psoc_info *tgt_hdl;
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
+	if (!tgt_hdl) {
+		wma_err("target psoc info is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = qdf_wait_for_event_completion(&tgt_hdl->info.event,
+					       WMA_READY_EVENTID_TIMEOUT);
+	if (status == QDF_STATUS_E_TIMEOUT)
+		wma_err("Timeout waiting for FW ready event");
+	else if (QDF_IS_STATUS_ERROR(status))
+		wma_err("Failed to wait for FW ready event; status:%u", status);
+	else
+		wma_info("FW ready event received");
+
+	return status;
+}
+
+/**
+ * wma_set_ppsconfig() - set pps config in fw
+ * @vdev_id: vdev id
+ * @pps_param: pps params
+ * @val : param value
+ *
+ * Return: 0 for success or QDF error
+ */
+QDF_STATUS wma_set_ppsconfig(uint8_t vdev_id, uint16_t pps_param,
+				    int val)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	int ret = -EIO;
+	uint32_t pps_val;
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: Failed to get wma", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	switch (pps_param) {
+	case WMA_VHT_PPS_PAID_MATCH:
+		pps_val = ((val << 31) & 0xffff0000) |
+			  (PKT_PWR_SAVE_PAID_MATCH & 0xffff);
+		goto pkt_pwr_save_config;
+	case WMA_VHT_PPS_GID_MATCH:
+		pps_val = ((val << 31) & 0xffff0000) |
+			  (PKT_PWR_SAVE_GID_MATCH & 0xffff);
+		goto pkt_pwr_save_config;
+	case WMA_VHT_PPS_DELIM_CRC_FAIL:
+		pps_val = ((val << 31) & 0xffff0000) |
+			  (PKT_PWR_SAVE_DELIM_CRC_FAIL & 0xffff);
+		goto pkt_pwr_save_config;
+
+		/* Enable the code below as and when the functionality
+		 * is supported/added in host.
+		 */
+#ifdef NOT_YET
+	case WMA_VHT_PPS_EARLY_TIM_CLEAR:
+		pps_val = ((val << 31) & 0xffff0000) |
+			  (PKT_PWR_SAVE_EARLY_TIM_CLEAR & 0xffff);
+		goto pkt_pwr_save_config;
+	case WMA_VHT_PPS_EARLY_DTIM_CLEAR:
+		pps_val = ((val << 31) & 0xffff0000) |
+			  (PKT_PWR_SAVE_EARLY_DTIM_CLEAR & 0xffff);
+		goto pkt_pwr_save_config;
+	case WMA_VHT_PPS_EOF_PAD_DELIM:
+		pps_val = ((val << 31) & 0xffff0000) |
+			  (PKT_PWR_SAVE_EOF_PAD_DELIM & 0xffff);
+		goto pkt_pwr_save_config;
+	case WMA_VHT_PPS_MACADDR_MISMATCH:
+		pps_val = ((val << 31) & 0xffff0000) |
+			  (PKT_PWR_SAVE_MACADDR_MISMATCH & 0xffff);
+		goto pkt_pwr_save_config;
+	case WMA_VHT_PPS_GID_NSTS_ZERO:
+		pps_val = ((val << 31) & 0xffff0000) |
+			  (PKT_PWR_SAVE_GID_NSTS_ZERO & 0xffff);
+		goto pkt_pwr_save_config;
+	case WMA_VHT_PPS_RSSI_CHECK:
+		pps_val = ((val << 31) & 0xffff0000) |
+			  (PKT_PWR_SAVE_RSSI_CHECK & 0xffff);
+		goto pkt_pwr_save_config;
+#endif /* NOT_YET */
+pkt_pwr_save_config:
+		WMA_LOGD("vdev_id:%d val:0x%x pps_val:0x%x", vdev_id,
+			 val, pps_val);
+		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					      WMI_VDEV_PARAM_PACKET_POWERSAVE,
+					      pps_val);
+		break;
+	default:
+		WMA_LOGE("%s:INVALID PPS CONFIG", __func__);
+	}
+
+	return (ret) ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_set_mas() - Function to enable/disable MAS
+ * @wma:	Pointer to WMA handle
+ * @mas_val:	1-Enable MAS, 0-Disable MAS
+ *
+ * This function enables/disables the MAS value
+ *
+ * Return: QDF_SUCCESS for success otherwise failure
+ */
+static QDF_STATUS wma_process_set_mas(tp_wma_handle wma,
+				      uint32_t *mas_val)
+{
+	uint32_t val;
+
+	if (NULL == wma || NULL == mas_val) {
+		WMA_LOGE("%s: Invalid input to enable/disable MAS", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	val = (*mas_val);
+
+	if (QDF_STATUS_SUCCESS !=
+			wma_set_enable_disable_mcc_adaptive_scheduler(val)) {
+		WMA_LOGE("%s: Unable to enable/disable MAS", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	WMA_LOGE("%s: Value is %d", __func__, val);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_set_miracast() - Function to set miracast value in WMA
+ * @wma:		Pointer to WMA handle
+ * @miracast_val:	0-Disabled,1-Source,2-Sink
+ *
+ * This function stores the miracast value in WMA
+ *
+ * Return: QDF_SUCCESS for success otherwise failure
+ *
+ */
+static QDF_STATUS wma_process_set_miracast(tp_wma_handle wma,
+					   uint32_t *miracast_val)
+{
+	if (NULL == wma || NULL == miracast_val) {
+		WMA_LOGE("%s: Invalid input to store miracast value", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wma->miracast_value = *miracast_val;
+	WMA_LOGE("%s: Miracast value is %d", __func__, wma->miracast_value);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_config_stats_factor() - Function to configure stats avg. factor
+ * @wma:  pointer to WMA handle
+ * @avg_factor:	stats. avg. factor passed down by userspace
+ *
+ * This function configures the avg. stats value in firmware
+ *
+ * Return: QDF_STATUS_SUCCESS for success otherwise failure
+ *
+ */
+static QDF_STATUS wma_config_stats_factor(tp_wma_handle wma,
+				      struct sir_stats_avg_factor *avg_factor)
+{
+	QDF_STATUS ret;
+
+	if (NULL == wma || NULL == avg_factor) {
+		WMA_LOGE("%s: Invalid input of stats avg factor", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma->wmi_handle,
+					    avg_factor->vdev_id,
+					    WMI_VDEV_PARAM_STATS_AVG_FACTOR,
+					    avg_factor->stats_avg_factor);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE(" failed to set avg_factor for vdev_id %d",
+			 avg_factor->vdev_id);
+	}
+
+	WMA_LOGD("%s: Set stats_avg_factor %d for vdev_id %d", __func__,
+		 avg_factor->stats_avg_factor, avg_factor->vdev_id);
+
+	return ret;
+}
+
+/**
+ * wma_config_guard_time() - Function to set guard time in firmware
+ * @wma:  pointer to WMA handle
+ * @guard_time:  guard time passed down by userspace
+ *
+ * This function configures the guard time in firmware
+ *
+ * Return: QDF_STATUS_SUCCESS for success otherwise failure
+ *
+ */
+static QDF_STATUS wma_config_guard_time(tp_wma_handle wma,
+				   struct sir_guard_time_request *guard_time)
+{
+	QDF_STATUS ret;
+
+	if (NULL == wma || NULL == guard_time) {
+		WMA_LOGE("%s: Invalid input of guard time", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma->wmi_handle,
+					      guard_time->vdev_id,
+					      WMI_VDEV_PARAM_RX_LEAK_WINDOW,
+					      guard_time->guard_time);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE(" failed to set guard time for vdev_id %d",
+			 guard_time->vdev_id);
+	}
+
+	WMA_LOGD("Set guard time %d for vdev_id %d",
+		 guard_time->guard_time, guard_time->vdev_id);
+
+	return ret;
+}
+
+/**
+ * wma_enable_specific_fw_logs() - Start/Stop logging of diag event/log id
+ * @wma_handle: WMA handle
+ * @start_log: Start logging related parameters
+ *
+ * Send the command to the FW based on which specific logging of diag
+ * event/log id can be started/stopped
+ *
+ * Return: None
+ */
+static void wma_enable_specific_fw_logs(tp_wma_handle wma_handle,
+					struct sir_wifi_start_log *start_log)
+{
+
+	if (!start_log) {
+		WMA_LOGE("%s: start_log pointer is NULL", __func__);
+		return;
+	}
+	if (!wma_handle) {
+		WMA_LOGE("%s: Invalid wma handle", __func__);
+		return;
+	}
+
+	if (!((start_log->ring_id == RING_ID_CONNECTIVITY) ||
+			(start_log->ring_id == RING_ID_FIRMWARE_DEBUG))) {
+		WMA_LOGD("%s: Not connectivity or fw debug ring: %d",
+				__func__, start_log->ring_id);
+		return;
+	}
+
+	wmi_unified_enable_specific_fw_logs_cmd(wma_handle->wmi_handle,
+				(struct wmi_wifi_start_log *)start_log);
+}
+
+#define MEGABYTE	(1024 * 1024)
+/**
+ * wma_set_wifi_start_packet_stats() - Start/stop packet stats
+ * @wma_handle: WMA handle
+ * @start_log: Struture containing the start wifi logger params
+ *
+ * This function is used to send the WMA commands to start/stop logging
+ * of per packet statistics
+ *
+ * Return: None
+ *
+ */
+#ifdef REMOVE_PKT_LOG
+static void wma_set_wifi_start_packet_stats(void *wma_handle,
+					struct sir_wifi_start_log *start_log)
+{
+}
+
+#else
+static void wma_set_wifi_start_packet_stats(void *wma_handle,
+					struct sir_wifi_start_log *start_log)
+{
+	struct hif_opaque_softc *scn;
+	uint32_t log_state;
+
+	if (!start_log) {
+		WMA_LOGE("%s: start_log pointer is NULL", __func__);
+		return;
+	}
+	if (!wma_handle) {
+		WMA_LOGE("%s: Invalid wma handle", __func__);
+		return;
+	}
+
+	/* No need to register for ring IDs other than packet stats */
+	if (start_log->ring_id != RING_ID_PER_PACKET_STATS) {
+		WMA_LOGD("%s: Ring id is not for per packet stats: %d",
+			__func__, start_log->ring_id);
+		return;
+	}
+
+	scn = cds_get_context(QDF_MODULE_ID_HIF);
+	if (scn == NULL) {
+		WMA_LOGE("%s: Invalid HIF handle", __func__);
+		return;
+	}
+
+#ifdef HELIUMPLUS
+	log_state = ATH_PKTLOG_ANI | ATH_PKTLOG_RCUPDATE | ATH_PKTLOG_RCFIND |
+		ATH_PKTLOG_RX | ATH_PKTLOG_TX |
+		ATH_PKTLOG_TEXT | ATH_PKTLOG_SW_EVENT;
+#elif defined(QCA_WIFI_QCA6390)
+	log_state = ATH_PKTLOG_RCFIND | ATH_PKTLOG_RCUPDATE |
+		    ATH_PKTLOG_LITE_RX | ATH_PKTLOG_LITE_T2H;
+#elif defined(QCA_WIFI_QCA6290)
+	log_state = ATH_PKTLOG_LITE_RX | ATH_PKTLOG_LITE_T2H;
+#else
+	WMA_LOGD("%s: Packet log Not supported", __func__);
+	log_state = 0;
+#endif
+	if (start_log->size != 0) {
+		pktlog_setsize(scn, start_log->size * MEGABYTE);
+		return;
+	} else if (start_log->is_pktlog_buff_clear == true) {
+		pktlog_clearbuff(scn, start_log->is_pktlog_buff_clear);
+		return;
+	}
+
+	if (start_log->verbose_level == WLAN_LOG_LEVEL_ACTIVE) {
+		pktlog_enable(scn, log_state, start_log->ini_triggered,
+			      start_log->user_triggered,
+			      start_log->is_iwpriv_command);
+		WMA_LOGD("%s: Enabling per packet stats", __func__);
+	} else {
+		pktlog_enable(scn, 0, start_log->ini_triggered,
+				start_log->user_triggered,
+				start_log->is_iwpriv_command);
+		WMA_LOGD("%s: Disabling per packet stats", __func__);
+	}
+}
+#endif
+
+/**
+ * wma_send_flush_logs_to_fw() - Send log flush command to FW
+ * @wma_handle: WMI handle
+ *
+ * This function is used to send the flush command to the FW,
+ * that will flush the fw logs that are residue in the FW
+ *
+ * Return: None
+ */
+void wma_send_flush_logs_to_fw(tp_wma_handle wma_handle)
+{
+	QDF_STATUS status;
+	int ret;
+
+	ret = wmi_unified_flush_logs_to_fw_cmd(wma_handle->wmi_handle);
+	if (ret != EOK)
+		return;
+
+	status = qdf_mc_timer_start(&wma_handle->log_completion_timer,
+			WMA_LOG_COMPLETION_TIMER);
+	if (status != QDF_STATUS_SUCCESS)
+		WMA_LOGE("Failed to start the log completion timer");
+}
+
+/**
+ * wma_update_wep_default_key - To update default key id
+ * @wma: pointer to wma handler
+ * @update_def_key: pointer to wep_update_default_key_idx
+ *
+ * This function makes a copy of default key index to txrx node
+ *
+ * Return: Success
+ */
+static QDF_STATUS wma_update_wep_default_key(tp_wma_handle wma,
+			struct wep_update_default_key_idx *update_def_key)
+{
+	struct wma_txrx_node *iface =
+		&wma->interfaces[update_def_key->session_id];
+	iface->wep_default_key_idx = update_def_key->default_idx;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_update_tx_fail_cnt_th() - Set threshold for TX pkt fail
+ * @wma_handle: WMA handle
+ * @tx_fail_cnt_th: sme_tx_fail_cnt_threshold parameter
+ *
+ * This function is used to set Tx pkt fail count threshold,
+ * FW will do disconnect with station once this threshold is reached.
+ *
+ * Return: VOS_STATUS_SUCCESS on success, error number otherwise
+ */
+static QDF_STATUS wma_update_tx_fail_cnt_th(tp_wma_handle wma,
+			struct sme_tx_fail_cnt_threshold *tx_fail_cnt_th)
+{
+	u_int8_t vdev_id;
+	u_int32_t tx_fail_disconn_th;
+	int ret = -EIO;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE(FL("WMA is closed, can not issue Tx pkt fail count threshold"));
+		return QDF_STATUS_E_INVAL;
+	}
+	vdev_id = tx_fail_cnt_th->session_id;
+	tx_fail_disconn_th = tx_fail_cnt_th->tx_fail_cnt_threshold;
+	WMA_LOGD("Set TX pkt fail count threshold  vdevId %d count %d",
+			vdev_id, tx_fail_disconn_th);
+
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_DISCONNECT_TH,
+			tx_fail_disconn_th);
+
+	if (ret) {
+		WMA_LOGE(FL("Failed to send TX pkt fail count threshold command"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_update_short_retry_limit() - Set retry limit for short frames
+ * @wma_handle: WMA handle
+ * @short_retry_limit_th: retry limir count for Short frames.
+ *
+ * This function is used to configure the transmission retry limit at which
+ * short frames needs to be retry.
+ *
+ * Return: VOS_STATUS_SUCCESS on success, error number otherwise
+ */
+static QDF_STATUS wma_update_short_retry_limit(tp_wma_handle wma,
+		struct sme_short_retry_limit *short_retry_limit_th)
+{
+	uint8_t vdev_id;
+	uint32_t short_retry_limit;
+	int ret;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("WMA is closed, can not issue short retry limit threshold");
+		return QDF_STATUS_E_INVAL;
+	}
+	vdev_id = short_retry_limit_th->session_id;
+	short_retry_limit = short_retry_limit_th->short_retry_limit;
+	WMA_LOGD("Set short retry limit threshold  vdevId %d count %d",
+		vdev_id, short_retry_limit);
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+		WMI_VDEV_PARAM_NON_AGG_SW_RETRY_TH,
+		short_retry_limit);
+
+	if (ret) {
+		WMA_LOGE("Failed to send short limit threshold command");
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_update_long_retry_limit() - Set retry limit for long frames
+ * @wma_handle: WMA handle
+ * @long_retry_limit_th: retry limir count for long frames
+ *
+ * This function is used to configure the transmission retry limit at which
+ * long frames needs to be retry
+ *
+ * Return: VOS_STATUS_SUCCESS on success, error number otherwise
+ */
+static QDF_STATUS wma_update_long_retry_limit(tp_wma_handle wma,
+		struct sme_long_retry_limit  *long_retry_limit_th)
+{
+	uint8_t vdev_id;
+	uint32_t long_retry_limit;
+	int ret;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("WMA is closed, can not issue long retry limit threshold");
+		return QDF_STATUS_E_INVAL;
+	}
+	vdev_id = long_retry_limit_th->session_id;
+	long_retry_limit = long_retry_limit_th->long_retry_limit;
+	WMA_LOGD("Set TX pkt fail count threshold  vdevId %d count %d",
+		vdev_id, long_retry_limit);
+
+	ret  = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_AGG_SW_RETRY_TH,
+			long_retry_limit);
+
+	if (ret) {
+		WMA_LOGE("Failed to send long limit threshold command");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * wma_update_sta_inactivity_timeout() - Set sta_inactivity_timeout to fw
+ * @wma_handle: WMA handle
+ * @sta_inactivity_timer: sme_sta_inactivity_timeout
+ *
+ * This function is used to set sta_inactivity_timeout.
+ * If a station does not send anything in sta_inactivity_timeout seconds, an
+ * empty data frame is sent to it in order to verify whether it is
+ * still in range. If this frame is not ACKed, the station will be
+ * disassociated and then deauthenticated.
+ *
+ * Return: None
+ */
+void wma_update_sta_inactivity_timeout(tp_wma_handle wma,
+		struct sme_sta_inactivity_timeout  *sta_inactivity_timer)
+{
+	uint8_t vdev_id;
+	uint32_t max_unresponsive_time;
+	uint32_t min_inactive_time, max_inactive_time;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("WMA is closed, can not issue sta_inactivity_timeout");
+		return;
+	}
+	vdev_id = sta_inactivity_timer->session_id;
+	max_unresponsive_time = sta_inactivity_timer->sta_inactivity_timeout;
+	max_inactive_time = max_unresponsive_time * TWO_THIRD;
+	min_inactive_time = max_unresponsive_time - max_inactive_time;
+
+	if (wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
+			min_inactive_time))
+		WMA_LOGE("Failed to Set AP MIN IDLE INACTIVE TIME");
+
+	if (wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
+			max_inactive_time))
+		WMA_LOGE("Failed to Set AP MAX IDLE INACTIVE TIME");
+
+	if (wma_vdev_set_param(wma->wmi_handle, vdev_id,
+		WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
+		max_unresponsive_time))
+		WMA_LOGE("Failed to Set MAX UNRESPONSIVE TIME");
+
+	WMA_LOGD("%s:vdev_id:%d min_inactive_time: %u max_inactive_time: %u max_unresponsive_time: %u",
+			__func__, vdev_id,
+			min_inactive_time, max_inactive_time,
+			max_unresponsive_time);
+}
+
+#ifdef WLAN_FEATURE_WOW_PULSE
+
+
+#define WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM \
+WMI_WOW_HOSTWAKEUP_GPIO_PIN_PATTERN_CONFIG_CMD_fixed_param
+
+
+#define WMITLV_TAG_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM \
+WMITLV_TAG_STRUC_wmi_wow_hostwakeup_gpio_pin_pattern_config_cmd_fixed_param
+
+/**
+ * wma_send_wow_pulse_cmd() - send wmi cmd of wow pulse cmd
+ * information to fw.
+ * @wma_handle: wma handler
+ * @udp_response: wow_pulse_mode pointer
+ *
+ * Return: Return QDF_STATUS
+ */
+static QDF_STATUS wma_send_wow_pulse_cmd(tp_wma_handle wma_handle,
+					struct wow_pulse_mode *wow_pulse_cmd)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	wmi_buf_t buf;
+	WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM *cmd;
+	u_int16_t len;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM *)wmi_buf_data(buf);
+	qdf_mem_zero(cmd, len);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM,
+		WMITLV_GET_STRUCT_TLVLEN(
+			WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM));
+
+	cmd->enable = wow_pulse_cmd->wow_pulse_enable;
+	cmd->pin = wow_pulse_cmd->wow_pulse_pin;
+	cmd->interval_low = wow_pulse_cmd->wow_pulse_interval_low;
+	cmd->interval_high = wow_pulse_cmd->wow_pulse_interval_high;
+	cmd->repeat_cnt = WMI_WOW_PULSE_REPEAT_CNT;
+
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+		WMI_WOW_HOSTWAKEUP_GPIO_PIN_PATTERN_CONFIG_CMDID)) {
+		wmi_buf_free(buf);
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("%s: Exit", __func__);
+	return status;
+}
+
+#undef WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM
+#undef WMITLV_TAG_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM
+#undef WMI_WOW_PULSE_REPEAT_CNT
+
+#else
+static inline QDF_STATUS wma_send_wow_pulse_cmd(tp_wma_handle wma_handle,
+					struct wow_pulse_mode *wow_pulse_cmd)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+#endif
+
+
+/**
+ * wma_process_power_debug_stats_req() - Process the Chip Power stats collect
+ * request and pass the Power stats request to Fw
+ * @wma_handle: WMA handle
+ *
+ * Return: QDF_STATUS
+ */
+#ifdef WLAN_POWER_DEBUGFS
+static QDF_STATUS wma_process_power_debug_stats_req(tp_wma_handle wma_handle)
+{
+	wmi_pdev_get_chip_power_stats_cmd_fixed_param *cmd;
+	int32_t len;
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	int ret;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: input pointer is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
+	cmd = (wmi_pdev_get_chip_power_stats_cmd_fixed_param *) buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_get_chip_power_stats_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_pdev_get_chip_power_stats_cmd_fixed_param));
+	cmd->pdev_id = 0;
+
+	WMA_LOGD("POWER_DEBUG_STATS - Get Request Params; Pdev id - %d",
+			cmd->pdev_id);
+	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+			WMI_PDEV_GET_CHIP_POWER_STATS_CMDID);
+	if (ret) {
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static QDF_STATUS wma_process_power_debug_stats_req(tp_wma_handle wma_handle)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * wma_set_arp_req_stats() - process set arp stats request command to fw
+ * @wma_handle: WMA handle
+ * @req_buf: set srp stats request buffer
+ *
+ * Return: None
+ */
+static void wma_set_arp_req_stats(WMA_HANDLE handle,
+				  struct set_arp_stats_params *req_buf)
+{
+	int status;
+	struct set_arp_stats *arp_stats;
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, cannot send per roam config",
+			 __func__);
+		return;
+	}
+	if (!wma_is_vdev_valid(req_buf->vdev_id)) {
+		WMA_LOGE("vdev id not active or not valid");
+		return;
+	}
+
+	arp_stats = (struct set_arp_stats *)req_buf;
+	status = wmi_unified_set_arp_stats_req(wma_handle->wmi_handle,
+					       arp_stats);
+	if (status != EOK)
+		WMA_LOGE("%s: failed to set arp stats to FW",
+			 __func__);
+}
+
+/**
+ * wma_get_arp_req_stats() - process get arp stats request command to fw
+ * @wma_handle: WMA handle
+ * @req_buf: get srp stats request buffer
+ *
+ * Return: None
+ */
+static void wma_get_arp_req_stats(WMA_HANDLE handle,
+				  struct get_arp_stats_params *req_buf)
+{
+	int status;
+	struct get_arp_stats *arp_stats;
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, cannot send per roam config",
+			 __func__);
+		return;
+	}
+	if (!wma_is_vdev_valid(req_buf->vdev_id)) {
+		WMA_LOGE("vdev id not active or not valid");
+		return;
+	}
+
+	arp_stats = (struct get_arp_stats *)req_buf;
+	status = wmi_unified_get_arp_stats_req(wma_handle->wmi_handle,
+					       arp_stats);
+	if (status != EOK)
+		WMA_LOGE("%s: failed to send get arp stats to FW",
+			 __func__);
+}
+
+/**
+ * wma_set_del_pmkid_cache() - API to set/delete PMKID cache entry in fw
+ * @handle: WMA handle
+ * @pmk_cache: PMK cache entry
+ *
+ * Return: None
+ */
+static void wma_set_del_pmkid_cache(WMA_HANDLE handle,
+				    struct wmi_unified_pmk_cache *pmk_cache)
+{
+	int status;
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("WMA is closed, cannot send set del pmkid");
+		return;
+	}
+
+	status = wmi_unified_set_del_pmkid_cache(wma_handle->wmi_handle,
+						 pmk_cache);
+	if (status != EOK)
+		WMA_LOGE("failed to send set/del pmkid cmd to fw");
+}
+
+/**
+ * wma_send_invoke_neighbor_report() - API to send invoke neighbor report
+ * command to fw
+ *
+ * @handle: WMA handle
+ * @params: Pointer to invoke neighbor report params
+ *
+ * Return: None
+ */
+static
+void wma_send_invoke_neighbor_report(WMA_HANDLE handle,
+			struct wmi_invoke_neighbor_report_params *params)
+{
+	QDF_STATUS status;
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("WMA is closed, cannot send invoke neighbor report");
+		return;
+	}
+
+	status = wmi_unified_invoke_neighbor_report_cmd(wma_handle->wmi_handle,
+							params);
+
+	if (status != QDF_STATUS_SUCCESS)
+		WMA_LOGE("failed to send invoke neighbor report command");
+}
+
+QDF_STATUS wma_set_rx_reorder_timeout_val(tp_wma_handle wma_handle,
+	struct sir_set_rx_reorder_timeout_val *reorder_timeout)
+{
+	wmi_pdev_set_reorder_timeout_val_cmd_fixed_param *cmd;
+	uint32_t len;
+	wmi_buf_t buf;
+	int ret;
+
+	if (!reorder_timeout) {
+		WMA_LOGE(FL("invalid pointer"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wma_handle) {
+		WMA_LOGE(FL("WMA context is invald!"));
+		return QDF_STATUS_E_INVAL;
+	}
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_pdev_set_reorder_timeout_val_cmd_fixed_param *)
+		wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	WMITLV_TAG_STRUC_wmi_pdev_set_reorder_timeout_val_cmd_fixed_param,
+	WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_reorder_timeout_val_cmd_fixed_param));
+
+	memcpy(cmd->rx_timeout_pri, reorder_timeout->rx_timeout_pri,
+		sizeof(reorder_timeout->rx_timeout_pri));
+
+	WMA_LOGD("rx aggr record timeout: VO: %d, VI: %d, BE: %d, BK: %d",
+		cmd->rx_timeout_pri[0], cmd->rx_timeout_pri[1],
+		cmd->rx_timeout_pri[2], cmd->rx_timeout_pri[3]);
+
+	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+			WMI_PDEV_SET_REORDER_TIMEOUT_VAL_CMDID);
+	if (ret) {
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wma_set_rx_blocksize(tp_wma_handle wma_handle,
+	struct sir_peer_set_rx_blocksize *peer_rx_blocksize)
+{
+	wmi_peer_set_rx_blocksize_cmd_fixed_param *cmd;
+	int32_t len;
+	wmi_buf_t buf;
+	u_int8_t *buf_ptr;
+	int ret;
+
+	if (!peer_rx_blocksize) {
+		WMA_LOGE(FL("invalid pointer"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wma_handle) {
+		WMA_LOGE(FL(" WMA context is invald!"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
+	cmd = (wmi_peer_set_rx_blocksize_cmd_fixed_param *) buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	WMITLV_TAG_STRUC_wmi_peer_set_rx_blocksize_cmd_fixed_param,
+	WMITLV_GET_STRUCT_TLVLEN(wmi_peer_set_rx_blocksize_cmd_fixed_param));
+
+	cmd->vdev_id = peer_rx_blocksize->vdev_id;
+	cmd->rx_block_ack_win_limit =
+		peer_rx_blocksize->rx_block_ack_win_limit;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_rx_blocksize->peer_macaddr.bytes,
+		&cmd->peer_macaddr);
+
+	WMA_LOGD("rx aggr blocksize: %d", cmd->rx_block_ack_win_limit);
+
+	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+			WMI_PEER_SET_RX_BLOCKSIZE_CMDID);
+	if (ret) {
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wma_get_chain_rssi(tp_wma_handle wma_handle,
+		struct get_chain_rssi_req_params *req_params)
+{
+	wmi_pdev_div_get_rssi_antid_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint32_t len = sizeof(wmi_pdev_div_get_rssi_antid_fixed_param);
+	u_int8_t *buf_ptr;
+
+	if (!wma_handle) {
+		WMA_LOGE(FL("WMA is closed, can not issue cmd"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!wmi_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf);
+
+	cmd = (wmi_pdev_div_get_rssi_antid_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_pdev_div_get_rssi_antid_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+		wmi_pdev_div_get_rssi_antid_fixed_param));
+	cmd->pdev_id = 0;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(req_params->peer_macaddr.bytes,
+				&cmd->macaddr);
+
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
+				 WMI_PDEV_DIV_GET_RSSI_ANTID_CMDID)) {
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#if defined(WLAN_FEATURE_FILS_SK)
+/**
+ * wma_roam_scan_send_hlp() - API to send HLP IE info to fw
+ * @wma_handle: WMA handle
+ * @req: HLP params
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS wma_roam_scan_send_hlp(tp_wma_handle wma_handle,
+					 struct hlp_params *req)
+{
+	struct hlp_params *params;
+	QDF_STATUS status;
+
+	params = qdf_mem_malloc(sizeof(*params));
+	if (!params)
+		return QDF_STATUS_E_NOMEM;
+
+	params->vdev_id = req->vdev_id;
+	params->hlp_ie_len = req->hlp_ie_len;
+	qdf_mem_copy(params->hlp_ie, req->hlp_ie, req->hlp_ie_len);
+	status = wmi_unified_roam_send_hlp_cmd(wma_handle->wmi_handle, params);
+
+	WMA_LOGD("Send HLP status %d vdev id %d", status, params->vdev_id);
+	qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
+				params->hlp_ie, 10);
+
+	qdf_mem_free(params);
+	return status;
+}
+#else
+static QDF_STATUS wma_roam_scan_send_hlp(tp_wma_handle wma_handle,
+					 struct hlp_params *req)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * wma_process_set_limit_off_chan() - set limit off chanel parameters
+ * @wma_handle: pointer to wma handle
+ * @param: pointer to sir_limit_off_chan
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+static QDF_STATUS wma_process_limit_off_chan(tp_wma_handle wma_handle,
+	struct sir_limit_off_chan *param)
+{
+	int32_t err;
+	struct wmi_limit_off_chan_param limit_off_chan_param;
+
+	if (param->vdev_id >= wma_handle->max_bssid) {
+		WMA_LOGE(FL("Invalid vdev_id: %d"), param->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!wma_is_vdev_up(param->vdev_id)) {
+		WMA_LOGD("vdev %d is not up skipping limit_off_chan_param",
+			 param->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	limit_off_chan_param.vdev_id = param->vdev_id;
+	limit_off_chan_param.status = param->is_tos_active;
+	limit_off_chan_param.max_offchan_time = param->max_off_chan_time;
+	limit_off_chan_param.rest_time = param->rest_time;
+	limit_off_chan_param.skip_dfs_chans = param->skip_dfs_chans;
+
+	err = wmi_unified_send_limit_off_chan_cmd(wma_handle->wmi_handle,
+			&limit_off_chan_param);
+	if (err) {
+		WMA_LOGE("\n failed to set limit off chan cmd");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS wma_process_obss_color_collision_req(tp_wma_handle wma_handle,
+		struct wmi_obss_color_collision_cfg_param *cfg)
+{
+	QDF_STATUS status;
+
+	if (cfg->vdev_id >= wma_handle->max_bssid) {
+		WMA_LOGE(FL("Invalid vdev_id: %d"), cfg->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!wma_is_vdev_up(cfg->vdev_id)) {
+		WMA_LOGE("vdev %d is not up skipping obss color collision req",
+			 cfg->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_send_obss_color_collision_cfg_cmd(wma_handle->
+							       wmi_handle, cfg);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGE("Failed to send obss color collision cfg");
+
+	return status;
+}
+
+/**
+ * wma_send_obss_detection_cfg() - send obss detection cfg to firmware
+ * @wma_handle: pointer to wma handle
+ * @cfg: obss detection configuration
+ *
+ * Send obss detection configuration to firmware.
+ *
+ * Return: None
+ */
+static void wma_send_obss_detection_cfg(tp_wma_handle wma_handle,
+					struct wmi_obss_detection_cfg_param
+					*cfg)
+{
+	QDF_STATUS status;
+
+	if (cfg->vdev_id >= wma_handle->max_bssid) {
+		WMA_LOGE(FL("Invalid vdev_id: %d"), cfg->vdev_id);
+		return;
+	}
+	if (!wma_is_vdev_up(cfg->vdev_id)) {
+		WMA_LOGE("vdev %d is not up skipping obss detection req",
+			 cfg->vdev_id);
+		return;
+	}
+
+	status = wmi_unified_send_obss_detection_cfg_cmd(wma_handle->wmi_handle,
+							 cfg);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGE("Failed to send obss detection cfg");
+
+	return;
+}
+
+/**
+ * wma_mc_process_msg() - process wma messages and call appropriate function.
+ * @msg: message
+ *
+ * Return: QDF_SUCCESS for success otherwise failure
+ */
+static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	tp_wma_handle wma_handle;
+	struct cdp_vdev *txrx_vdev_handle = NULL;
+
+	extern uint8_t *mac_trace_get_wma_msg_string(uint16_t wmaMsg);
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (NULL == msg) {
+		WMA_LOGE("msg is NULL");
+		QDF_ASSERT(0);
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto end;
+	}
+
+	WMA_LOGD("msg->type = %x %s", msg->type,
+		 mac_trace_get_wma_msg_string(msg->type));
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: wma_handle is NULL", __func__);
+		QDF_ASSERT(0);
+		qdf_mem_free(msg->bodyptr);
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto end;
+	}
+
+	switch (msg->type) {
+
+	/* Message posted by wmi for all control path related
+	 * FW events to serialize through mc_thread.
+	 */
+	case WMA_PROCESS_FW_EVENT:
+		wma_process_fw_event(wma_handle,
+				(wma_process_fw_event_params *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+
+#ifdef FEATURE_WLAN_ESE
+	case WMA_TSM_STATS_REQ:
+		WMA_LOGD("McThread: WMA_TSM_STATS_REQ");
+		wma_process_tsm_stats_req(wma_handle, (void *)msg->bodyptr);
+		break;
+#endif /* FEATURE_WLAN_ESE */
+	case WNI_CFG_DNLD_REQ:
+		WMA_LOGD("McThread: WNI_CFG_DNLD_REQ");
+		qdf_status = wma_wni_cfg_dnld(wma_handle);
+		if (QDF_IS_STATUS_SUCCESS(qdf_status))
+			cds_wma_complete_cback();
+		else
+			WMA_LOGD("config download failure");
+		break;
+	case WMA_ADD_STA_SELF_REQ:
+		txrx_vdev_handle =
+			wma_vdev_attach(wma_handle,
+				(struct add_sta_self_params *) msg->
+				bodyptr, 1);
+		if (!txrx_vdev_handle) {
+			WMA_LOGE("Failed to attach vdev");
+		} else {
+			/* Register with TxRx Module for Data Ack Complete Cb */
+			if (soc) {
+				cdp_data_tx_cb_set(soc, txrx_vdev_handle,
+						wma_data_tx_ack_comp_hdlr,
+						wma_handle);
+			} else {
+				WMA_LOGE("%s: SOC context is NULL", __func__);
+				qdf_status = QDF_STATUS_E_FAILURE;
+				goto end;
+			}
+		}
+		break;
+	case WMA_DEL_STA_SELF_REQ:
+		wma_vdev_detach(wma_handle,
+				(struct del_sta_self_params *) msg->bodyptr, 1);
+		break;
+	case WMA_UPDATE_CHAN_LIST_REQ:
+		wma_update_channel_list(wma_handle,
+					(tSirUpdateChanList *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_LINK_STATE:
+		wma_set_linkstate(wma_handle, (tpLinkStateParams) msg->bodyptr);
+		break;
+	case WMA_CHNL_SWITCH_REQ:
+		wma_set_channel(wma_handle,
+				(tpSwitchChannelParams) msg->bodyptr);
+		break;
+	case WMA_ADD_BSS_REQ:
+		wma_add_bss(wma_handle, (tpAddBssParams) msg->bodyptr);
+		break;
+	case WMA_ADD_STA_REQ:
+		wma_add_sta(wma_handle, (tpAddStaParams) msg->bodyptr);
+		break;
+	case WMA_SET_BSSKEY_REQ:
+		wma_set_bsskey(wma_handle, (tpSetBssKeyParams) msg->bodyptr);
+		break;
+	case WMA_SET_STAKEY_REQ:
+		wma_set_stakey(wma_handle, (tpSetStaKeyParams) msg->bodyptr);
+		break;
+	case WMA_DELETE_STA_REQ:
+		wma_delete_sta(wma_handle, (tpDeleteStaParams) msg->bodyptr);
+		break;
+	case WMA_DELETE_BSS_HO_FAIL_REQ:
+		wma_delete_bss_ho_fail(wma_handle,
+			(tpDeleteBssParams) msg->bodyptr);
+		break;
+	case WMA_DELETE_BSS_REQ:
+		wma_delete_bss(wma_handle, (tpDeleteBssParams) msg->bodyptr);
+		break;
+	case WMA_UPDATE_EDCA_PROFILE_IND:
+		wma_process_update_edca_param_req(wma_handle,
+						  (tEdcaParams *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SEND_BEACON_REQ:
+		wma_send_beacon(wma_handle, (tpSendbeaconParams) msg->bodyptr);
+		break;
+	case WMA_SEND_AP_VDEV_UP:
+		wma_set_ap_vdev_up(wma_handle, msg->bodyval);
+		break;
+	case WMA_SEND_PROBE_RSP_TMPL:
+		wma_send_probe_rsp_tmpl(wma_handle,
+					(tpSendProbeRespParams) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_CLI_SET_CMD:
+		wma_process_cli_set_cmd(wma_handle,
+					(wma_cli_set_cmd_t *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_PDEV_IE_REQ:
+		wma_process_set_pdev_ie_req(wma_handle,
+				(struct set_ie_param *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#if !defined(REMOVE_PKT_LOG)
+	case WMA_PKTLOG_ENABLE_REQ:
+		wma_pktlog_wmi_send_cmd(wma_handle,
+			(struct ath_pktlog_wmi_params *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#endif /* REMOVE_PKT_LOG */
+	case WMA_ENTER_PS_REQ:
+		wma_enable_sta_ps_mode(wma_handle,
+				       (tpEnablePsParams) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_EXIT_PS_REQ:
+		wma_disable_sta_ps_mode(wma_handle,
+					(tpDisablePsParams) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_ENABLE_UAPSD_REQ:
+		wma_enable_uapsd_mode(wma_handle,
+				      (tpEnableUapsdParams) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_DISABLE_UAPSD_REQ:
+		wma_disable_uapsd_mode(wma_handle,
+				       (tpDisableUapsdParams) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_DTIM_PERIOD:
+		wma_set_dtim_period(wma_handle,
+				    (struct set_dtim_params *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_TX_POWER_REQ:
+		wma_set_tx_power(wma_handle, (tpMaxTxPowerParams) msg->bodyptr);
+		break;
+	case WMA_SET_MAX_TX_POWER_REQ:
+		wma_set_max_tx_power(wma_handle,
+				     (tpMaxTxPowerParams) msg->bodyptr);
+		break;
+	case WMA_SET_KEEP_ALIVE:
+		wma_set_keepalive_req(wma_handle,
+				      (tSirKeepAliveReq *) msg->bodyptr);
+		break;
+#ifdef FEATURE_WLAN_ESE
+	case WMA_SET_PLM_REQ:
+		wma_config_plm(wma_handle, (tpSirPlmReq) msg->bodyptr);
+		break;
+#endif
+	case WMA_GET_STATISTICS_REQ:
+		wma_get_stats_req(wma_handle,
+				  (tAniGetPEStatsReq *) msg->bodyptr);
+		break;
+
+	case WMA_UPDATE_OP_MODE:
+		wma_process_update_opmode(wma_handle,
+					  (tUpdateVHTOpMode *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_UPDATE_RX_NSS:
+		wma_process_update_rx_nss(wma_handle,
+					  (tUpdateRxNss *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_UPDATE_MEMBERSHIP:
+		wma_process_update_membership(wma_handle,
+			(tUpdateMembership *) msg->bodyptr);
+		break;
+	case WMA_UPDATE_USERPOS:
+		wma_process_update_userpos(wma_handle,
+					   (tUpdateUserPos *) msg->bodyptr);
+		break;
+	case WMA_UPDATE_BEACON_IND:
+		wma_process_update_beacon_params(wma_handle,
+			(tUpdateBeaconParams *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+
+	case WMA_ADD_TS_REQ:
+		wma_add_ts_req(wma_handle, (tAddTsParams *) msg->bodyptr);
+		break;
+
+	case WMA_DEL_TS_REQ:
+		wma_del_ts_req(wma_handle, (tDelTsParams *) msg->bodyptr);
+		break;
+
+	case WMA_AGGR_QOS_REQ:
+		wma_aggr_qos_req(wma_handle, (tAggrAddTsParams *) msg->bodyptr);
+		break;
+
+	case WMA_8023_MULTICAST_LIST_REQ:
+		wma_process_mcbc_set_filter_req(wma_handle,
+				(tpSirRcvFltMcAddrList) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_ROAM_SCAN_OFFLOAD_REQ:
+		/*
+		 * Main entry point or roaming directives from CSR.
+		 */
+		wma_process_roaming_config(wma_handle,
+				(tSirRoamOffloadScanReq *) msg->bodyptr);
+		break;
+
+	case WMA_RATE_UPDATE_IND:
+		wma_process_rate_update_indicate(wma_handle,
+				(tSirRateUpdateInd *) msg->bodyptr);
+		break;
+
+#ifdef FEATURE_WLAN_TDLS
+	case WMA_UPDATE_TDLS_PEER_STATE:
+		wma_update_tdls_peer_state(wma_handle,
+				(tTdlsPeerStateParams *) msg->bodyptr);
+		break;
+	case WMA_TDLS_SET_OFFCHAN_MODE:
+		wma_set_tdls_offchan_mode(wma_handle,
+			(tdls_chan_switch_params *)msg->bodyptr);
+		break;
+#endif /* FEATURE_WLAN_TDLS */
+	case WMA_ADD_PERIODIC_TX_PTRN_IND:
+		wma_process_add_periodic_tx_ptrn_ind(wma_handle,
+				(tSirAddPeriodicTxPtrn *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_DEL_PERIODIC_TX_PTRN_IND:
+		wma_process_del_periodic_tx_ptrn_ind(wma_handle,
+				(tSirDelPeriodicTxPtrn *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_TX_POWER_LIMIT:
+		wma_process_tx_power_limits(wma_handle,
+					    (tSirTxPowerLimit *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SEND_ADDBA_REQ:
+		wma_process_send_addba_req(wma_handle,
+				(struct send_add_ba_req *)msg->bodyptr);
+		break;
+
+#ifdef FEATURE_WLAN_CH_AVOID
+	case WMA_CH_AVOID_UPDATE_REQ:
+		wma_process_ch_avoid_update_req(wma_handle,
+				(tSirChAvoidUpdateReq *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#endif /* FEATURE_WLAN_CH_AVOID */
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+	case WMA_SET_AUTO_SHUTDOWN_TIMER_REQ:
+		wma_set_auto_shutdown_timer_req(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
+	case WMA_DHCP_START_IND:
+	case WMA_DHCP_STOP_IND:
+		wma_process_dhcp_ind(wma_handle, (tAniDHCPInd *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+
+	case WMA_IBSS_CESIUM_ENABLE_IND:
+		wma_process_cesium_enable_ind(wma_handle);
+		break;
+	case WMA_GET_IBSS_PEER_INFO_REQ:
+		wma_process_get_peer_info_req(wma_handle,
+					      (tSirIbssGetPeerInfoReqParams *)
+					      msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_TX_FAIL_MONITOR_IND:
+		wma_process_tx_fail_monitor_ind(wma_handle,
+				(tAniTXFailMonitorInd *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+
+	case WMA_RMC_ENABLE_IND:
+		wma_process_rmc_enable_ind(wma_handle);
+		break;
+	case WMA_RMC_DISABLE_IND:
+		wma_process_rmc_disable_ind(wma_handle);
+		break;
+	case WMA_RMC_ACTION_PERIOD_IND:
+		wma_process_rmc_action_period_ind(wma_handle);
+		break;
+	case WMA_INIT_THERMAL_INFO_CMD:
+		wma_process_init_thermal_info(wma_handle,
+					      (t_thermal_mgmt *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+
+	case WMA_SET_THERMAL_LEVEL:
+		wma_process_set_thermal_level(wma_handle, msg->bodyval);
+		break;
+#ifdef CONFIG_HL_SUPPORT
+	case WMA_INIT_BAD_PEER_TX_CTL_INFO_CMD:
+		wma_process_init_bad_peer_tx_ctl_info(
+			wma_handle,
+			(struct t_bad_peer_txtcl_config *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+			break;
+#endif
+	case WMA_SET_MIMOPS_REQ:
+		wma_process_set_mimops_req(wma_handle,
+					   (tSetMIMOPS *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_SAP_INTRABSS_DIS:
+		wma_set_vdev_intrabss_fwd(wma_handle,
+					  (tDisableIntraBssFwd *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_GET_PEER_INFO:
+		wma_get_peer_info(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_GET_PEER_INFO_EXT:
+		wma_get_peer_info_ext(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_MODEM_POWER_STATE_IND:
+		wma_notify_modem_power_state(wma_handle,
+				(tSirModemPowerStateInd *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#ifdef WLAN_FEATURE_STATS_EXT
+	case WMA_STATS_EXT_REQUEST:
+		wma_stats_ext_req(wma_handle,
+				  (tpStatsExtRequest) (msg->bodyptr));
+		qdf_mem_free(msg->bodyptr);
+		break;
+#endif /* WLAN_FEATURE_STATS_EXT */
+	case WMA_HIDDEN_SSID_VDEV_RESTART:
+		wma_hidden_ssid_vdev_restart(wma_handle,
+				(tHalHiddenSsidVdevRestart *) msg->bodyptr);
+		break;
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+	case WMA_WLAN_EXT_WOW:
+		wma_enable_ext_wow(wma_handle,
+				   (tSirExtWoWParams *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_WLAN_SET_APP_TYPE1_PARAMS:
+		wma_set_app_type1_params_in_fw(wma_handle,
+				(tSirAppType1Params *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_WLAN_SET_APP_TYPE2_PARAMS:
+		wma_set_app_type2_params_in_fw(wma_handle,
+				(tSirAppType2Params *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
+#ifdef FEATURE_WLAN_EXTSCAN
+	case WMA_EXTSCAN_START_REQ:
+		wma_start_extscan(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_EXTSCAN_STOP_REQ:
+		wma_stop_extscan(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ:
+		wma_extscan_start_hotlist_monitor(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ:
+		wma_extscan_stop_hotlist_monitor(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ:
+		wma_extscan_start_change_monitor(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ:
+		wma_extscan_stop_change_monitor(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_EXTSCAN_GET_CACHED_RESULTS_REQ:
+		wma_extscan_get_cached_results(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_EXTSCAN_GET_CAPABILITIES_REQ:
+		wma_extscan_get_capabilities(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_EPNO_LIST_REQ:
+		wma_set_epno_network_list(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_PER_ROAM_CONFIG_CMD:
+		wma_update_per_roam_config(wma_handle,
+			(struct wmi_per_roam_config_req *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_PASSPOINT_LIST_REQ:
+		/* Issue reset passpoint network list first and clear
+		 * the entries
+		 */
+		wma_reset_passpoint_network_list(wma_handle, msg->bodyptr);
+
+		wma_set_passpoint_network_list(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_RESET_PASSPOINT_LIST_REQ:
+		wma_reset_passpoint_network_list(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#endif /* FEATURE_WLAN_EXTSCAN */
+	case WMA_SET_SCAN_MAC_OUI_REQ:
+		wma_scan_probe_setoui(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+	case WMA_LINK_LAYER_STATS_CLEAR_REQ:
+		wma_process_ll_stats_clear_req(wma_handle,
+			(tpSirLLStatsClearReq) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_LINK_LAYER_STATS_SET_REQ:
+		wma_process_ll_stats_set_req(wma_handle,
+					     (tpSirLLStatsSetReq) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_LINK_LAYER_STATS_GET_REQ:
+		wma_process_ll_stats_get_req(wma_handle,
+					     (tpSirLLStatsGetReq) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WDA_LINK_LAYER_STATS_SET_THRESHOLD:
+		wma_config_stats_ext_threshold(wma_handle,
+			(struct sir_ll_ext_stats_threshold *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	case WMA_ROAM_OFFLOAD_SYNCH_FAIL:
+		wma_process_roam_synch_fail(wma_handle,
+			(struct roam_offload_synch_fail *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_ROAM_INVOKE:
+		wma_process_roam_invoke(wma_handle,
+			(struct wma_roam_invoke_cmd *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+#ifdef WLAN_FEATURE_NAN
+	case WMA_NAN_REQUEST:
+		wma_nan_req(wma_handle, (tNanRequest *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#endif /* WLAN_FEATURE_NAN */
+	case SIR_HAL_SET_BASE_MACADDR_IND:
+		wma_set_base_macaddr_indicate(wma_handle,
+					      (tSirMacAddr *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_LINK_STATUS_GET_REQ:
+		wma_process_link_status_req(wma_handle,
+					    (tAniGetLinkStatus *) msg->bodyptr);
+		break;
+	case WMA_GET_TEMPERATURE_REQ:
+		wma_get_temperature(wma_handle);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_TSF_GPIO_PIN:
+		wma_set_tsf_gpio_pin(wma_handle, msg->bodyval);
+		break;
+
+#ifdef DHCP_SERVER_OFFLOAD
+	case WMA_SET_DHCP_SERVER_OFFLOAD_CMD:
+		wma_process_dhcpserver_offload(wma_handle,
+			(tSirDhcpSrvOffloadInfo *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#endif /* DHCP_SERVER_OFFLOAD */
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+	case WMA_LED_FLASHING_REQ:
+		wma_set_led_flashing(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+#endif /* WLAN_FEATURE_GPIO_LED_FLASHING */
+	case SIR_HAL_SET_MAS:
+		wma_process_set_mas(wma_handle,
+				(uint32_t *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_SET_MIRACAST:
+		wma_process_set_miracast(wma_handle,
+				(uint32_t *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_CONFIG_STATS_FACTOR:
+		wma_config_stats_factor(wma_handle,
+					(struct sir_stats_avg_factor *)
+					msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_CONFIG_GUARD_TIME:
+		wma_config_guard_time(wma_handle,
+				      (struct sir_guard_time_request *)
+				      msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_START_STOP_LOGGING:
+		wma_set_wifi_start_packet_stats(wma_handle,
+				(struct sir_wifi_start_log *)msg->bodyptr);
+		wma_enable_specific_fw_logs(wma_handle,
+				(struct sir_wifi_start_log *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_FLUSH_LOG_TO_FW:
+		wma_send_flush_logs_to_fw(wma_handle);
+		/* Body ptr is NULL here */
+		break;
+	case WMA_SET_RSSI_MONITOR_REQ:
+		wma_set_rssi_monitoring(wma_handle,
+			(struct rssi_monitor_req *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_PDEV_SET_PCL_TO_FW:
+		wma_send_pdev_set_pcl_cmd(wma_handle,
+				(struct set_pcl_req *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_PDEV_SET_HW_MODE:
+		wma_send_pdev_set_hw_mode_cmd(wma_handle,
+				(struct policy_mgr_hw_mode *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_OCB_SET_CONFIG_CMD:
+		wma_ocb_set_config_req(wma_handle,
+			(struct sir_ocb_config *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_OCB_SET_UTC_TIME_CMD:
+		wma_ocb_set_utc_time(wma_handle,
+			(struct sir_ocb_utc *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_OCB_START_TIMING_ADVERT_CMD:
+		wma_ocb_start_timing_advert(wma_handle,
+			(struct sir_ocb_timing_advert *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_OCB_STOP_TIMING_ADVERT_CMD:
+		wma_ocb_stop_timing_advert(wma_handle,
+			(struct sir_ocb_timing_advert *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_DCC_CLEAR_STATS_CMD:
+		wma_dcc_clear_stats(wma_handle,
+			(struct sir_dcc_clear_stats *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_OCB_GET_TSF_TIMER_CMD:
+		wma_ocb_get_tsf_timer(wma_handle,
+			(struct sir_ocb_get_tsf_timer *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_WISA_PARAMS:
+		wma_set_wisa_params(wma_handle,
+			(struct sir_wisa_params *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_DCC_GET_STATS_CMD:
+		wma_dcc_get_stats(wma_handle,
+			(struct sir_dcc_get_stats *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_DCC_UPDATE_NDL_CMD:
+		wma_dcc_update_ndl(wma_handle,
+			(struct sir_dcc_update_ndl *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_PDEV_DUAL_MAC_CFG_REQ:
+		wma_send_pdev_set_dual_mac_config(wma_handle,
+				(struct policy_mgr_dual_mac_config *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_IE_INFO:
+		wma_process_set_ie_info(wma_handle,
+			(struct vdev_ie_info *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_SOC_ANTENNA_MODE_REQ:
+		wma_send_pdev_set_antenna_mode(wma_handle,
+			(struct sir_antenna_mode_param *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_LRO_CONFIG_CMD:
+		wma_lro_config_cmd(wma_handle,
+			(struct cdp_lro_hash_config *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_GW_PARAM_UPDATE_REQ:
+		wma_set_gateway_params(wma_handle,
+			(struct gateway_param_update_req *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_ADAPT_DWELLTIME_CONF_PARAMS:
+		wma_send_adapt_dwelltime_params(wma_handle,
+			(struct adaptive_dwelltime_params *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_HT40_OBSS_SCAN_IND:
+		wma_send_ht40_obss_scanind(wma_handle,
+			(struct obss_ht40_scanind *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_ADD_BCN_FILTER_CMDID:
+		wma_add_beacon_filter(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_REMOVE_BCN_FILTER_CMDID:
+		wma_remove_beacon_filter(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WDA_APF_GET_CAPABILITIES_REQ:
+		wma_get_apf_capabilities(wma_handle);
+		break;
+	case WDA_APF_SET_INSTRUCTIONS_REQ:
+		wma_set_apf_instructions(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_POWER_DBG_CMD:
+		wma_process_hal_pwr_dbg_cmd(wma_handle,
+					    msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_UPDATE_WEP_DEFAULT_KEY:
+		wma_update_wep_default_key(wma_handle,
+			(struct wep_update_default_key_idx *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SEND_FREQ_RANGE_CONTROL_IND:
+		wma_enable_disable_caevent_ind(wma_handle, msg->bodyval);
+		break;
+	case SIR_HAL_UPDATE_TX_FAIL_CNT_TH:
+		wma_update_tx_fail_cnt_th(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_LONG_RETRY_LIMIT_CNT:
+		wma_update_long_retry_limit(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_SHORT_RETRY_LIMIT_CNT:
+		wma_update_short_retry_limit(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_POWER_DEBUG_STATS_REQ:
+		wma_process_power_debug_stats_req(wma_handle);
+		break;
+	case WMA_GET_RCPI_REQ:
+		wma_get_rcpi_req(wma_handle,
+				 (struct sme_rcpi_req *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_WOW_PULSE_CMD:
+		wma_send_wow_pulse_cmd(wma_handle,
+			(struct wow_pulse_mode *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_DBS_SCAN_SEL_CONF_PARAMS:
+		wma_send_dbs_scan_selection_params(wma_handle,
+			(struct wmi_dbs_scan_sel_params *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_ARP_STATS_REQ:
+		wma_set_arp_req_stats(wma_handle,
+			(struct set_arp_stats_params *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_GET_ARP_STATS_REQ:
+		wma_get_arp_req_stats(wma_handle,
+			(struct get_arp_stats_params *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_SET_DEL_PMKID_CACHE:
+		wma_set_del_pmkid_cache(wma_handle,
+			(struct wmi_unified_pmk_cache *) msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case SIR_HAL_HLP_IE_INFO:
+		wma_roam_scan_send_hlp(wma_handle,
+			(struct hlp_params *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_SET_LIMIT_OFF_CHAN:
+		wma_process_limit_off_chan(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_OBSS_DETECTION_REQ:
+		wma_send_obss_detection_cfg(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_INVOKE_NEIGHBOR_REPORT:
+		wma_send_invoke_neighbor_report(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_OBSS_COLOR_COLLISION_REQ:
+		wma_process_obss_color_collision_req(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_GET_ROAM_SCAN_STATS:
+		wma_get_roam_scan_stats(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	default:
+		WMA_LOGD("Unhandled WMA message of type %d", msg->type);
+		if (msg->bodyptr)
+			qdf_mem_free(msg->bodyptr);
+	}
+end:
+	return qdf_status;
+}
+
+QDF_STATUS wma_mc_process_handler(struct scheduler_msg *msg)
+{
+	return wma_mc_process_msg(msg);
+}
+
+/**
+ * wma_log_completion_timeout() - Log completion timeout
+ * @data: Timeout handler data
+ *
+ * This function is called when log completion timer expires
+ *
+ * Return: None
+ */
+void wma_log_completion_timeout(void *data)
+{
+	tp_wma_handle wma_handle;
+
+	WMA_LOGD("%s: Timeout occurred for log completion command", __func__);
+
+	wma_handle = (tp_wma_handle) data;
+	if (!wma_handle)
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+
+	/* Though we did not receive any event from FW,
+	 * we can flush whatever logs we have with us
+	 */
+	cds_logging_set_fw_flush_complete();
+}
+
+/**
+ * wma_map_pcl_weights() - Map PCL weights
+ * @pcl_weight: Internal PCL weights
+ *
+ * Maps the internal weights of PCL to the weights needed by FW
+ *
+ * Return: Mapped channel weight of type wmi_pcl_chan_weight
+ */
+static wmi_pcl_chan_weight wma_map_pcl_weights(uint32_t pcl_weight)
+{
+	switch (pcl_weight) {
+	case WEIGHT_OF_GROUP1_PCL_CHANNELS:
+		return WMI_PCL_WEIGHT_VERY_HIGH;
+	case WEIGHT_OF_GROUP2_PCL_CHANNELS:
+		return WMI_PCL_WEIGHT_HIGH;
+	case WEIGHT_OF_GROUP3_PCL_CHANNELS:
+		return WMI_PCL_WEIGHT_MEDIUM;
+	case WEIGHT_OF_NON_PCL_CHANNELS:
+		return WMI_PCL_WEIGHT_LOW;
+	default:
+		return WMI_PCL_WEIGHT_DISALLOW;
+	}
+}
+
+/**
+ * wma_send_pdev_set_pcl_cmd() - Send WMI_SOC_SET_PCL_CMDID to FW
+ * @wma_handle: WMA handle
+ * @msg: PCL structure containing the PCL and the number of channels
+ *
+ * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
+ * firmware. The DBS Manager is the consumer of this information in the WLAN
+ * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
+ * to migrate to a new channel without host driver involvement. An example of
+ * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
+ * manage the channel selection without firmware involvement.
+ *
+ * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
+ * channel list. The weights corresponds to the channels sent in
+ * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
+ * weightage compared to the non PCL channels.
+ *
+ * Return: Success if the cmd is sent successfully to the firmware
+ */
+QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle,
+				     struct set_pcl_req *msg)
+{
+	uint32_t i;
+	QDF_STATUS status;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: WMA handle is NULL. Cannot issue command",
+				__func__);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	for (i = 0; i < wma_handle->saved_chan.num_channels; i++) {
+		msg->chan_weights.saved_chan_list[i] =
+			wma_handle->saved_chan.channel_list[i];
+	}
+
+	msg->chan_weights.saved_num_chan = wma_handle->saved_chan.num_channels;
+	status = policy_mgr_get_valid_chan_weights(wma_handle->psoc,
+		(struct policy_mgr_pcl_chan_weights *)&msg->chan_weights);
+
+	for (i = 0; i < msg->chan_weights.saved_num_chan; i++) {
+		msg->chan_weights.weighed_valid_list[i] =
+			wma_map_pcl_weights(
+				msg->chan_weights.weighed_valid_list[i]);
+		/* Dont allow roaming on 2G when 5G_ONLY configured */
+		if (((wma_handle->bandcapability == BAND_5G) ||
+		    (msg->band == BAND_5G)) &&
+		    (WLAN_REG_IS_24GHZ_CH(
+				msg->chan_weights.saved_chan_list[i]))) {
+			msg->chan_weights.weighed_valid_list[i] =
+				WEIGHT_OF_DISALLOWED_CHANNELS;
+		}
+		if ((msg->band == BAND_2G) &&
+		    WLAN_REG_IS_5GHZ_CH(msg->chan_weights.saved_chan_list[i]))
+			msg->chan_weights.weighed_valid_list[i] =
+				WEIGHT_OF_DISALLOWED_CHANNELS;
+		WMA_LOGD("%s: chan:%d weight[%d]=%d", __func__,
+			 msg->chan_weights.saved_chan_list[i], i,
+			 msg->chan_weights.weighed_valid_list[i]);
+	}
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		WMA_LOGE("%s: Error in creating weighed pcl", __func__);
+		return status;
+	}
+
+	if (wmi_unified_pdev_set_pcl_cmd(wma_handle->wmi_handle,
+					 &msg->chan_weights))
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_send_pdev_set_hw_mode_cmd() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW
+ * @wma_handle: WMA handle
+ * @msg: Structure containing the following parameters
+ *
+ * - hw_mode_index: The HW_Mode field is a enumerated type that is selected
+ * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID.
+ *
+ * Provides notification to the WLAN firmware that host driver is requesting a
+ * HardWare (HW) Mode change. This command is needed to support iHelium in the
+ * configurations that include the Dual Band Simultaneous (DBS) feature.
+ *
+ * Return: Success if the cmd is sent successfully to the firmware
+ */
+QDF_STATUS wma_send_pdev_set_hw_mode_cmd(tp_wma_handle wma_handle,
+					 struct policy_mgr_hw_mode *msg)
+{
+	struct sir_set_hw_mode_resp *param;
+	struct wma_target_req *timeout_msg;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: WMA handle is NULL. Cannot issue command",
+				__func__);
+		/* Handle is NULL. Will not be able to send failure
+		 * response as well
+		 */
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!msg) {
+		WMA_LOGE("%s: Set HW mode param is NULL", __func__);
+		/* Lets try to free the active command list */
+		goto fail;
+	}
+
+	wma_acquire_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock,
+			     WMA_VDEV_HW_MODE_REQUEST_TIMEOUT);
+	if (wmi_unified_soc_set_hw_mode_cmd(wma_handle->wmi_handle,
+					    msg->hw_mode_index)) {
+		wma_release_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock);
+		goto fail;
+	}
+	timeout_msg = wma_fill_hold_req(wma_handle, 0,
+			SIR_HAL_PDEV_SET_HW_MODE,
+			WMA_PDEV_SET_HW_MODE_RESP, NULL,
+			WMA_VDEV_HW_MODE_REQUEST_TIMEOUT - 1);
+	if (!timeout_msg) {
+		WMA_LOGE("Failed to allocate request for SIR_HAL_PDEV_SET_HW_MODE");
+		wma_remove_req(wma_handle, 0, WMA_PDEV_SET_HW_MODE_RESP);
+	}
+
+	return QDF_STATUS_SUCCESS;
+fail:
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	param->status = SET_HW_MODE_STATUS_ECANCELED;
+	param->cfgd_hw_mode_index = 0;
+	param->num_vdev_mac_entries = 0;
+	WMA_LOGE("%s: Sending HW mode fail response to LIM", __func__);
+	wma_send_msg(wma_handle, SIR_HAL_PDEV_SET_HW_MODE_RESP,
+			(void *) param, 0);
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * wma_send_pdev_set_dual_mac_config() - Set dual mac config to FW
+ * @wma_handle: WMA handle
+ * @msg: Dual MAC config parameters
+ *
+ * Configures WLAN firmware with the dual MAC features
+ *
+ * Return: QDF_STATUS. 0 on success.
+ */
+QDF_STATUS wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle,
+		struct policy_mgr_dual_mac_config *msg)
+{
+	QDF_STATUS status;
+	struct wma_target_req *req_msg;
+	struct sir_dual_mac_config_resp *resp;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: WMA handle is NULL. Cannot issue command",
+				__func__);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!msg) {
+		WMA_LOGE("%s: Set dual mode config is NULL", __func__);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	/*
+	 * aquire the wake lock here and release it in response handler function
+	 * In error condition, release the wake lock right away
+	 */
+	wma_acquire_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock,
+			     WMA_VDEV_PLCY_MGR_CMD_TIMEOUT);
+	status = wmi_unified_pdev_set_dual_mac_config_cmd(
+				wma_handle->wmi_handle,
+				(struct policy_mgr_dual_mac_config *)msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("%s: Failed to send WMI_PDEV_SET_DUAL_MAC_CONFIG_CMDID: %d",
+				__func__, status);
+		wma_release_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock);
+		goto fail;
+	}
+	policy_mgr_update_dbs_req_config(wma_handle->psoc,
+	msg->scan_config, msg->fw_mode_config);
+
+	req_msg = wma_fill_hold_req(wma_handle, 0,
+				SIR_HAL_PDEV_DUAL_MAC_CFG_REQ,
+				WMA_PDEV_MAC_CFG_RESP, NULL,
+				WMA_VDEV_DUAL_MAC_CFG_TIMEOUT);
+	if (!req_msg) {
+		WMA_LOGE("Failed to allocate request for SIR_HAL_PDEV_DUAL_MAC_CFG_REQ");
+		wma_remove_req(wma_handle, 0, WMA_PDEV_MAC_CFG_RESP);
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+fail:
+	resp = qdf_mem_malloc(sizeof(*resp));
+	if (!resp)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	resp->status = SET_HW_MODE_STATUS_ECANCELED;
+	WMA_LOGE("%s: Sending failure response to LIM", __func__);
+	wma_send_msg(wma_handle, SIR_HAL_PDEV_MAC_CFG_RESP, (void *) resp, 0);
+	return QDF_STATUS_E_FAILURE;
+
+}
+
+/**
+ * wma_send_pdev_set_antenna_mode() - Set antenna mode to FW
+ * @wma_handle: WMA handle
+ * @msg: Antenna mode parameters
+ *
+ * Send WMI_PDEV_SET_ANTENNA_MODE_CMDID to FW requesting to
+ * modify the number of TX/RX chains from host
+ *
+ * Return: QDF_STATUS. 0 on success.
+ */
+QDF_STATUS wma_send_pdev_set_antenna_mode(tp_wma_handle wma_handle,
+		struct sir_antenna_mode_param *msg)
+{
+	wmi_pdev_set_antenna_mode_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint32_t len;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct sir_antenna_mode_resp *param;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: WMA handle is NULL. Cannot issue command",
+				__func__);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!msg) {
+		WMA_LOGE("%s: Set antenna mode param is NULL", __func__);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+	if (!buf) {
+		status = QDF_STATUS_E_NOMEM;
+		goto resp;
+	}
+
+	cmd = (wmi_pdev_set_antenna_mode_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_pdev_set_antenna_mode_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_pdev_set_antenna_mode_cmd_fixed_param));
+
+	cmd->pdev_id = WMI_PDEV_ID_SOC;
+	/* Bits 0-15 is num of RX chains 16-31 is num of TX chains */
+	cmd->num_txrx_chains = msg->num_rx_chains;
+	cmd->num_txrx_chains |= (msg->num_tx_chains << 16);
+
+	WMA_LOGD("%s: Num of chains TX: %d RX: %d txrx_chains: 0x%x",
+		 __func__, msg->num_tx_chains,
+		 msg->num_rx_chains, cmd->num_txrx_chains);
+
+	if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+				 WMI_PDEV_SET_ANTENNA_MODE_CMDID)) {
+		wmi_buf_free(buf);
+		status = QDF_STATUS_E_FAILURE;
+		goto resp;
+	}
+	status = QDF_STATUS_SUCCESS;
+
+resp:
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return QDF_STATUS_E_NOMEM;
+
+	param->status = (status) ?
+		SET_ANTENNA_MODE_STATUS_ECANCELED :
+		SET_ANTENNA_MODE_STATUS_OK;
+	WMA_LOGE("%s: Send antenna mode resp to LIM status: %d",
+		 __func__, param->status);
+	wma_send_msg(wma_handle, SIR_HAL_SOC_ANTENNA_MODE_RESP,
+			(void *) param, 0);
+	return status;
+}
+
+/**
+ * wma_crash_inject() - sends command to FW to simulate crash
+ * @wma_handle:         pointer of WMA context
+ * @type:               subtype of the command
+ * @delay_time_ms:      time in milliseconds for FW to delay the crash
+ *
+ * This function will send a command to FW in order to simulate different
+ * kinds of FW crashes.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_crash_inject(WMA_HANDLE wma_handle, uint32_t type,
+			    uint32_t delay_time_ms)
+{
+	struct crash_inject param;
+	tp_wma_handle wma = (tp_wma_handle)wma_handle;
+
+	param.type = type;
+	param.delay_time_ms = delay_time_ms;
+	return wmi_crash_inject(wma->wmi_handle, &param);
+}
+
+#ifdef RECEIVE_OFFLOAD
+int wma_lro_init(struct cdp_lro_hash_config *lro_config)
+{
+	struct scheduler_msg msg = {0};
+	struct cdp_lro_hash_config *iwcmd;
+
+	iwcmd = qdf_mem_malloc(sizeof(*iwcmd));
+	if (!iwcmd)
+		return -ENOMEM;
+
+	*iwcmd = *lro_config;
+
+	msg.type = WMA_LRO_CONFIG_CMD;
+	msg.reserved = 0;
+	msg.bodyptr = iwcmd;
+
+	if (QDF_STATUS_SUCCESS !=
+		scheduler_post_message(QDF_MODULE_ID_WMA,
+				       QDF_MODULE_ID_WMA,
+				       QDF_MODULE_ID_WMA, &msg)) {
+		WMA_LOGE("Failed to post WMA_LRO_CONFIG_CMD msg!");
+		qdf_mem_free(iwcmd);
+		return -EAGAIN;
+	}
+
+	WMA_LOGD("sending the LRO configuration to the fw");
+	return 0;
+}
+#endif
+
+QDF_STATUS wma_configure_smps_params(uint32_t vdev_id, uint32_t param_id,
+							uint32_t param_val)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	int smps_cmd_value;
+	int status = QDF_STATUS_E_INVAL;
+
+	if (!wma) {
+		WMA_LOGE("%s: Failed to get wma", __func__);
+		return status;
+	}
+
+	smps_cmd_value = param_id << WMI_SMPS_PARAM_VALUE_S;
+	smps_cmd_value = smps_cmd_value | param_val;
+
+	status = wma_set_smps_params(wma, vdev_id, smps_cmd_value);
+	if (status)
+		WMA_LOGE("Failed to set SMPS Param");
+
+	return status;
+}
+
+
+void wma_ipa_uc_stat_request(wma_cli_set_cmd_t *privcmd)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma) {
+		WMA_LOGE("%s: Failed to get wma", __func__);
+		return;
+	}
+
+	if (wma_set_priv_cfg(wma, privcmd))
+		WMA_LOGE("Failed to set wma priv congiuration");
+}
+
+/**
+ * wma_config_bmiss_bcnt_params() - set bmiss config parameters
+ * @vdev_id: virtual device for the command
+ * @first_cnt: bmiss first value
+ * @final_cnt: bmiss final value
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS wma_config_bmiss_bcnt_params(uint32_t vdev_id, uint32_t first_cnt,
+		uint32_t final_cnt)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	int status = QDF_STATUS_E_INVAL;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: Failed to get wma", __func__);
+		return status;
+	}
+
+	status = wma_roam_scan_bmiss_cnt(wma_handle, first_cnt, final_cnt,
+			vdev_id);
+
+	if (status)
+		WMA_LOGE("Failed to set Bmiss Param");
+
+	return status;
+}
+
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
new file mode 100644
index 0000000..5102100
--- /dev/null
+++ b/core/wma/src/wma_mgmt.c
@@ -0,0 +1,4431 @@
+/*
+ * Copyright (c) 2013-2018 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:  wma_mgmt.c
+ *
+ *  This file contains STA/SAP/IBSS and protocol related functions.
+ */
+
+/* Header files */
+
+#include "wma.h"
+#include "wma_api.h"
+#include "cds_api.h"
+#include "wmi_unified_api.h"
+#include "wlan_qct_sys.h"
+#include "wni_api.h"
+#include "ani_global.h"
+#include "wmi_unified.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+
+#include "qdf_nbuf.h"
+#include "qdf_types.h"
+#include "qdf_mem.h"
+
+#include "wma_types.h"
+#include "lim_api.h"
+#include "lim_session_utils.h"
+
+#include "cds_utils.h"
+
+#if !defined(REMOVE_PKT_LOG)
+#include "pktlog_ac.h"
+#else
+#include "pktlog_ac_fmt.h"
+#endif /* REMOVE_PKT_LOG */
+
+#include "dbglog_host.h"
+#include "csr_api.h"
+#include "ol_fw.h"
+#include "wma_internal.h"
+#include "wlan_policy_mgr_api.h"
+#include "cdp_txrx_flow_ctrl_legacy.h"
+#include <cdp_txrx_peer_ops.h>
+#include <cdp_txrx_pmf.h>
+#include <cdp_txrx_cfg.h>
+#include <cdp_txrx_cmn.h>
+#include <cdp_txrx_misc.h>
+#include <cdp_txrx_misc.h>
+#include "wlan_mgmt_txrx_tgt_api.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_lmac_if_api.h"
+#include <cdp_txrx_handle.h>
+#include "wma_he.h"
+#include <qdf_crypto.h>
+#include "wma_twt.h"
+#include "wlan_p2p_cfg_api.h"
+#include "cfg_ucfg_api.h"
+#include "cfg_mlme_sta.h"
+#include "wlan_mlme_api.h"
+
+/**
+ * wma_send_bcn_buf_ll() - prepare and send beacon buffer to fw for LL
+ * @wma: wma handle
+ * @pdev: txrx pdev
+ * @vdev_id: vdev id
+ * @param_buf: SWBA parameters
+ *
+ * Return: none
+ */
+static void wma_send_bcn_buf_ll(tp_wma_handle wma,
+				struct cdp_pdev *pdev,
+				uint8_t vdev_id,
+				WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf)
+{
+	struct ieee80211_frame *wh;
+	struct beacon_info *bcn;
+	wmi_tim_info *tim_info = param_buf->tim_info;
+	uint8_t *bcn_payload;
+	QDF_STATUS ret;
+	struct beacon_tim_ie *tim_ie;
+	wmi_p2p_noa_info *p2p_noa_info = param_buf->p2p_noa_info;
+	struct p2p_sub_element_noa noa_ie;
+	struct wmi_bcn_send_from_host params;
+	uint8_t i;
+
+	bcn = wma->interfaces[vdev_id].beacon;
+	if (!bcn || !bcn->buf) {
+		WMA_LOGE("%s: Invalid beacon buffer", __func__);
+		return;
+	}
+
+	if (!param_buf->tim_info || !param_buf->p2p_noa_info) {
+		WMA_LOGE("%s: Invalid tim info or p2p noa info", __func__);
+		return;
+	}
+
+	if (WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info) >
+			WMI_P2P_MAX_NOA_DESCRIPTORS) {
+		WMA_LOGE("%s: Too many descriptors %d", __func__,
+			WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info));
+		return;
+	}
+
+	qdf_spin_lock_bh(&bcn->lock);
+
+	bcn_payload = qdf_nbuf_data(bcn->buf);
+
+	tim_ie = (struct beacon_tim_ie *)(&bcn_payload[bcn->tim_ie_offset]);
+
+	if (tim_info->tim_changed) {
+		if (tim_info->tim_num_ps_pending)
+			qdf_mem_copy(&tim_ie->tim_bitmap, tim_info->tim_bitmap,
+				     WMA_TIM_SUPPORTED_PVB_LENGTH);
+		else
+			qdf_mem_zero(&tim_ie->tim_bitmap,
+				     WMA_TIM_SUPPORTED_PVB_LENGTH);
+		/*
+		 * Currently we support fixed number of
+		 * peers as limited by HAL_NUM_STA.
+		 * tim offset is always 0
+		 */
+		tim_ie->tim_bitctl = 0;
+	}
+
+	/* Update DTIM Count */
+	if (tim_ie->dtim_count == 0)
+		tim_ie->dtim_count = tim_ie->dtim_period - 1;
+	else
+		tim_ie->dtim_count--;
+
+	/*
+	 * DTIM count needs to be backedup so that
+	 * when umac updates the beacon template
+	 * current dtim count can be updated properly
+	 */
+	bcn->dtim_count = tim_ie->dtim_count;
+
+	/* update state for buffered multicast frames on DTIM */
+	if (tim_info->tim_mcast && (tim_ie->dtim_count == 0 ||
+				    tim_ie->dtim_period == 1))
+		tim_ie->tim_bitctl |= 1;
+	else
+		tim_ie->tim_bitctl &= ~1;
+
+	/* To avoid sw generated frame sequence the same as H/W generated frame,
+	 * the value lower than min_sw_seq is reserved for HW generated frame
+	 */
+	if ((bcn->seq_no & IEEE80211_SEQ_MASK) < MIN_SW_SEQ)
+		bcn->seq_no = MIN_SW_SEQ;
+
+	wh = (struct ieee80211_frame *)bcn_payload;
+	*(uint16_t *) &wh->i_seq[0] = htole16(bcn->seq_no
+					      << IEEE80211_SEQ_SEQ_SHIFT);
+	bcn->seq_no++;
+
+	if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) {
+		qdf_mem_zero(&noa_ie, sizeof(noa_ie));
+
+		noa_ie.index =
+			(uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info);
+		noa_ie.oppPS =
+			(uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info);
+		noa_ie.ctwindow =
+			(uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info);
+		noa_ie.num_descriptors = (uint8_t)
+				WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info);
+		WMA_LOGI("%s: index %u, oppPs %u, ctwindow %u, num_descriptors = %u",
+			 __func__, noa_ie.index,
+			 noa_ie.oppPS, noa_ie.ctwindow, noa_ie.num_descriptors);
+		for (i = 0; i < noa_ie.num_descriptors; i++) {
+			noa_ie.noa_descriptors[i].type_count =
+				(uint8_t) p2p_noa_info->noa_descriptors[i].
+				type_count;
+			noa_ie.noa_descriptors[i].duration =
+				p2p_noa_info->noa_descriptors[i].duration;
+			noa_ie.noa_descriptors[i].interval =
+				p2p_noa_info->noa_descriptors[i].interval;
+			noa_ie.noa_descriptors[i].start_time =
+				p2p_noa_info->noa_descriptors[i].start_time;
+			WMA_LOGI("%s: NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
+				 __func__, i,
+				 noa_ie.noa_descriptors[i].type_count,
+				 noa_ie.noa_descriptors[i].duration,
+				 noa_ie.noa_descriptors[i].interval,
+				 noa_ie.noa_descriptors[i].start_time);
+		}
+		wma_update_noa(bcn, &noa_ie);
+
+		/* Send a msg to LIM to update the NoA IE in probe response
+		 * frames transmitted by the host
+		 */
+		wma_update_probe_resp_noa(wma, &noa_ie);
+	}
+
+	if (bcn->dma_mapped) {
+		qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf, QDF_DMA_TO_DEVICE);
+		bcn->dma_mapped = 0;
+	}
+	ret = qdf_nbuf_map_single(wma->qdf_dev, bcn->buf, QDF_DMA_TO_DEVICE);
+	if (ret != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: failed map beacon buf to DMA region", __func__);
+		qdf_spin_unlock_bh(&bcn->lock);
+		return;
+	}
+
+	bcn->dma_mapped = 1;
+	params.vdev_id = vdev_id;
+	params.data_len = bcn->len;
+	params.frame_ctrl = *((A_UINT16 *) wh->i_fc);
+	params.frag_ptr = qdf_nbuf_get_frag_paddr(bcn->buf, 0);
+	params.dtim_flag = 0;
+	/* notify Firmware of DTM and mcast/bcast traffic */
+	if (tim_ie->dtim_count == 0) {
+		params.dtim_flag |= WMI_BCN_SEND_DTIM_ZERO;
+		/* deliver mcast/bcast traffic in next DTIM beacon */
+		if (tim_ie->tim_bitctl & 0x01)
+			params.dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET;
+	}
+
+	wmi_unified_bcn_buf_ll_cmd(wma->wmi_handle,
+					&params);
+
+	qdf_spin_unlock_bh(&bcn->lock);
+}
+
+/**
+ * wma_beacon_swba_handler() - swba event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: data length
+ *
+ * SWBA event is alert event to Host requesting host to Queue a beacon
+ * for transmission use only in host beacon mode
+ *
+ * Return: 0 for success or error code
+ */
+int wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
+	wmi_host_swba_event_fixed_param *swba_event;
+	uint32_t vdev_map;
+	struct cdp_pdev *pdev;
+	uint8_t vdev_id = 0;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("Invalid swba event buffer");
+		return -EINVAL;
+	}
+	swba_event = param_buf->fixed_param;
+	vdev_map = swba_event->vdev_map;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE("%s: pdev is NULL", __func__);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("vdev_map = %d", vdev_map);
+	for (; vdev_map && vdev_id < wma->max_bssid;
+			vdev_id++, vdev_map >>= 1) {
+		if (!(vdev_map & 0x1))
+			continue;
+		if (!cdp_cfg_is_high_latency(soc,
+			(struct cdp_cfg *)cds_get_context(QDF_MODULE_ID_CFG)))
+			wma_send_bcn_buf_ll(wma, pdev, vdev_id, param_buf);
+		break;
+	}
+	return 0;
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void wma_sta_kickout_event(uint32_t kickout_reason, uint8_t vdev_id,
+							uint8_t *macaddr)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(sta_kickout, struct host_event_wlan_kickout);
+	qdf_mem_zero(&sta_kickout, sizeof(sta_kickout));
+	sta_kickout.reasoncode = kickout_reason;
+	sta_kickout.vdev_id = vdev_id;
+	if (macaddr)
+		qdf_mem_copy(sta_kickout.peer_mac, macaddr,
+							IEEE80211_ADDR_LEN);
+	WLAN_HOST_DIAG_EVENT_REPORT(&sta_kickout, EVENT_WLAN_STA_KICKOUT);
+}
+#endif
+
+/**
+ * wma_peer_sta_kickout_event_handler() - kickout event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: data length
+ *
+ * Kickout event is received from firmware on observing beacon miss
+ * It handles kickout event for different modes and indicate to
+ * upper layers.
+ *
+ * Return: 0 for success or error code
+ */
+int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event,
+				       uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL;
+	wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL;
+	uint8_t vdev_id, peer_id, macaddr[IEEE80211_ADDR_LEN];
+	void *peer;
+	struct cdp_pdev *pdev;
+	tpDeleteStaContext del_sta_ctx;
+	tpSirIbssPeerInactivityInd p_inactivity;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	WMA_LOGD("%s: Enter", __func__);
+	param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) event;
+	kickout_event = param_buf->fixed_param;
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE("%s: pdev is NULL", __func__);
+		return -EINVAL;
+	}
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, macaddr);
+	peer = cdp_peer_find_by_addr(soc, pdev,	macaddr, &peer_id);
+	if (!peer) {
+		WMA_LOGE("PEER [%pM] not found", macaddr);
+		return -EINVAL;
+	}
+
+	if (cdp_peer_get_vdevid(soc, peer, &vdev_id) != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("Not able to find BSSID for peer [%pM]", macaddr);
+		return -EINVAL;
+	}
+
+	WMA_LOGA("%s: PEER:[%pM], ADDR:[%pN], INTERFACE:%d, peer_id:%d, reason:%d",
+		__func__, macaddr, wma->interfaces[vdev_id].addr, vdev_id,
+		 peer_id, kickout_event->reason);
+	if (wma->interfaces[vdev_id].roaming_in_progress) {
+		WMA_LOGE("Ignore STA kick out since roaming is in progress");
+		return -EINVAL;
+	}
+
+	switch (kickout_event->reason) {
+	case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT:
+		p_inactivity = (tpSirIbssPeerInactivityInd)
+					qdf_mem_malloc(sizeof(
+						tSirIbssPeerInactivityInd));
+		if (!p_inactivity) {
+			WMA_LOGE("QDF MEM Alloc Failed for tSirIbssPeerInactivity");
+			return -ENOMEM;
+		}
+
+		p_inactivity->staIdx = peer_id;
+		qdf_mem_copy(p_inactivity->peer_addr.bytes, macaddr,
+			     IEEE80211_ADDR_LEN);
+		wma_send_msg(wma, WMA_IBSS_PEER_INACTIVITY_IND,
+			     (void *)p_inactivity, 0);
+		goto exit_handler;
+#ifdef FEATURE_WLAN_TDLS
+	case WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT:
+		del_sta_ctx = (tpDeleteStaContext)
+			qdf_mem_malloc(sizeof(tDeleteStaContext));
+		if (!del_sta_ctx) {
+			WMA_LOGE("%s: mem alloc failed for struct del_sta_context for TDLS peer: %pM",
+				__func__, macaddr);
+			return -ENOMEM;
+		}
+
+		del_sta_ctx->is_tdls = true;
+		del_sta_ctx->vdev_id = vdev_id;
+		del_sta_ctx->staId = peer_id;
+		qdf_mem_copy(del_sta_ctx->addr2, macaddr, IEEE80211_ADDR_LEN);
+		qdf_mem_copy(del_sta_ctx->bssId, wma->interfaces[vdev_id].bssid,
+			     IEEE80211_ADDR_LEN);
+		del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE;
+		wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND,
+			     (void *)del_sta_ctx, 0);
+		goto exit_handler;
+#endif /* FEATURE_WLAN_TDLS */
+	case WMI_PEER_STA_KICKOUT_REASON_XRETRY:
+		if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA &&
+		    (wma->interfaces[vdev_id].sub_type == 0 ||
+		     wma->interfaces[vdev_id].sub_type ==
+		     WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) &&
+		    !qdf_mem_cmp(wma->interfaces[vdev_id].bssid,
+				    macaddr, IEEE80211_ADDR_LEN)) {
+			wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_XRETRY,
+							vdev_id, macaddr);
+			/*
+			 * KICKOUT event is for current station-AP connection.
+			 * Treat it like final beacon miss. Station may not have
+			 * missed beacons but not able to transmit frames to AP
+			 * for a long time. Must disconnect to get out of
+			 * this sticky situation.
+			 * In future implementation, roaming module will also
+			 * handle this event and perform a scan.
+			 */
+			WMA_LOGW("%s: WMI_PEER_STA_KICKOUT_REASON_XRETRY event for STA",
+				__func__);
+			wma_beacon_miss_handler(wma, vdev_id,
+						kickout_event->rssi);
+			goto exit_handler;
+		}
+		break;
+
+	case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED:
+		/*
+		 * Default legacy value used by original firmware implementation
+		 */
+		if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA &&
+		    (wma->interfaces[vdev_id].sub_type == 0 ||
+		     wma->interfaces[vdev_id].sub_type ==
+		     WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) &&
+		    !qdf_mem_cmp(wma->interfaces[vdev_id].bssid,
+				    macaddr, IEEE80211_ADDR_LEN)) {
+			wma_sta_kickout_event(
+			HOST_STA_KICKOUT_REASON_UNSPECIFIED, vdev_id, macaddr);
+			/*
+			 * KICKOUT event is for current station-AP connection.
+			 * Treat it like final beacon miss. Station may not have
+			 * missed beacons but not able to transmit frames to AP
+			 * for a long time. Must disconnect to get out of
+			 * this sticky situation.
+			 * In future implementation, roaming module will also
+			 * handle this event and perform a scan.
+			 */
+			WMA_LOGW("%s: WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED event for STA",
+				__func__);
+			wma_beacon_miss_handler(wma, vdev_id,
+						kickout_event->rssi);
+			goto exit_handler;
+		}
+		break;
+
+	case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY:
+	/*
+	 * Handle SA query kickout is same as inactivity kickout.
+	 * This could be for STA or SAP role
+	 */
+	case WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT:
+	default:
+		break;
+	}
+
+	/*
+	 * default action is to send delete station context indication to LIM
+	 */
+	del_sta_ctx =
+		(tDeleteStaContext *) qdf_mem_malloc(sizeof(tDeleteStaContext));
+	if (!del_sta_ctx) {
+		WMA_LOGE("QDF MEM Alloc Failed for struct del_sta_context");
+		return -ENOMEM;
+	}
+
+	del_sta_ctx->is_tdls = false;
+	del_sta_ctx->vdev_id = vdev_id;
+	del_sta_ctx->staId = peer_id;
+	qdf_mem_copy(del_sta_ctx->addr2, macaddr, IEEE80211_ADDR_LEN);
+	qdf_mem_copy(del_sta_ctx->bssId, wma->interfaces[vdev_id].addr,
+		     IEEE80211_ADDR_LEN);
+	del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE;
+	del_sta_ctx->rssi = kickout_event->rssi + WMA_TGT_NOISE_FLOOR_DBM;
+	wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_KEEP_ALIVE,
+							vdev_id, macaddr);
+	wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND, (void *)del_sta_ctx,
+		     0);
+	wma_lost_link_info_handler(wma, vdev_id, kickout_event->rssi +
+						 WMA_TGT_NOISE_FLOOR_DBM);
+exit_handler:
+	WMA_LOGD("%s: Exit", __func__);
+	return 0;
+}
+
+/**
+ * wma_unified_bcntx_status_event_handler() - beacon tx status event handler
+ * @handle: wma handle
+ * @cmd_param_info: event data
+ * @len: data length
+ *
+ * WMI Handler for WMI_OFFLOAD_BCN_TX_STATUS_EVENTID event from firmware.
+ * This event is generated by FW when the beacon transmission is offloaded
+ * and the host performs beacon template modification using WMI_BCN_TMPL_CMDID
+ * The FW generates this event when the first successful beacon transmission
+ * after template update
+ *
+ * Return: 0 for success or error code
+ */
+int wma_unified_bcntx_status_event_handler(void *handle,
+					   uint8_t *cmd_param_info,
+					   uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf;
+	wmi_offload_bcn_tx_status_event_fixed_param *resp_event;
+	tSirFirstBeaconTxCompleteInd *beacon_tx_complete_ind;
+
+	param_buf =
+		(WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("Invalid bcn tx response event buffer");
+		return -EINVAL;
+	}
+
+	resp_event = param_buf->fixed_param;
+
+	WMA_LOGD("%s", __func__);
+
+	if (resp_event->vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: received invalid vdev_id %d",
+			 __func__, resp_event->vdev_id);
+		return -EINVAL;
+	}
+
+	/* Check for valid handle to ensure session is not
+	 * deleted in any race
+	 */
+	if (!wma->interfaces[resp_event->vdev_id].handle) {
+		WMA_LOGE("%s: The session does not exist", __func__);
+		return -EINVAL;
+	}
+
+	/* Beacon Tx Indication supports only AP mode. Ignore in other modes */
+	if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id) == false) {
+		WMA_LOGI("%s: Beacon Tx Indication does not support type %d and sub_type %d",
+			__func__, wma->interfaces[resp_event->vdev_id].type,
+			wma->interfaces[resp_event->vdev_id].sub_type);
+		return 0;
+	}
+
+	beacon_tx_complete_ind = (tSirFirstBeaconTxCompleteInd *)
+			qdf_mem_malloc(sizeof(tSirFirstBeaconTxCompleteInd));
+	if (!beacon_tx_complete_ind) {
+		WMA_LOGE("%s: Failed to alloc beacon_tx_complete_ind",
+			 __func__);
+		return -ENOMEM;
+	}
+
+	beacon_tx_complete_ind->messageType = WMA_DFS_BEACON_TX_SUCCESS_IND;
+	beacon_tx_complete_ind->length = sizeof(tSirFirstBeaconTxCompleteInd);
+	beacon_tx_complete_ind->bssIdx = resp_event->vdev_id;
+
+	wma_send_msg(wma, WMA_DFS_BEACON_TX_SUCCESS_IND,
+		     (void *)beacon_tx_complete_ind, 0);
+	return 0;
+}
+
+/**
+ * wma_get_go_probe_timeout() - get P2P GO probe timeout
+ * @mac: UMAC handler
+ * @max_inactive_time: return max inactive time
+ * @max_unresponsive_time: return max unresponsive time
+ *
+ * Return: none
+ */
+#ifdef CONVERGED_P2P_ENABLE
+static inline void
+wma_get_go_probe_timeout(struct mac_context *mac,
+			 uint32_t *max_inactive_time,
+			 uint32_t *max_unresponsive_time)
+{
+	uint32_t keep_alive;
+	QDF_STATUS status;
+
+	status = cfg_p2p_get_go_link_monitor_period(mac->psoc,
+						    max_inactive_time);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Failed to go monitor period");
+		*max_inactive_time = WMA_LINK_MONITOR_DEFAULT_TIME_SECS;
+	}
+	status = cfg_p2p_get_go_keepalive_period(mac->psoc,
+						 &keep_alive);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Failed to read go keep alive");
+		keep_alive = WMA_KEEP_ALIVE_DEFAULT_TIME_SECS;
+	}
+
+	*max_unresponsive_time = *max_inactive_time + keep_alive;
+}
+#else
+static inline void
+wma_get_go_probe_timeout(struct mac_context *mac,
+			 uint32_t *max_inactive_time,
+			 uint32_t *max_unresponsive_time)
+{
+}
+#endif
+
+/**
+ * wma_get_link_probe_timeout() - get link timeout based on sub type
+ * @mac: UMAC handler
+ * @sub_type: vdev syb type
+ * @max_inactive_time: return max inactive time
+ * @max_unresponsive_time: return max unresponsive time
+ *
+ * Return: none
+ */
+static inline void
+wma_get_link_probe_timeout(struct mac_context *mac,
+			   uint32_t sub_type,
+			   uint32_t *max_inactive_time,
+			   uint32_t *max_unresponsive_time)
+{
+	if (sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO) {
+		wma_get_go_probe_timeout(mac, max_inactive_time,
+					 max_unresponsive_time);
+	} else {
+		*max_inactive_time =
+			mac->mlme_cfg->timeouts.ap_link_monitor_timeout;
+		*max_unresponsive_time = *max_inactive_time +
+			mac->mlme_cfg->timeouts.ap_keep_alive_timeout;
+	}
+}
+
+/**
+ * wma_verify_rate_code() - verify if rate code is valid.
+ * @rate_code:     rate code
+ * @band:     band information
+ *
+ * Return: verify result
+ */
+static bool wma_verify_rate_code(u_int32_t rate_code, enum cds_band_type band)
+{
+	uint8_t preamble, nss, rate;
+	bool valid = true;
+
+	preamble = (rate_code & 0xc0) >> 6;
+	nss = (rate_code & 0x30) >> 4;
+	rate = rate_code & 0xf;
+
+	switch (preamble) {
+	case WMI_RATE_PREAMBLE_CCK:
+		if (nss != 0 || rate > 3 || band == CDS_BAND_5GHZ)
+			valid = false;
+		break;
+	case WMI_RATE_PREAMBLE_OFDM:
+		if (nss != 0 || rate > 7)
+			valid = false;
+		break;
+	case WMI_RATE_PREAMBLE_HT:
+		if (nss != 0 || rate > 7)
+			valid = false;
+		break;
+	case WMI_RATE_PREAMBLE_VHT:
+		if (nss != 0 || rate > 9)
+			valid = false;
+		break;
+	default:
+		break;
+	}
+	return valid;
+}
+
+#define TX_MGMT_RATE_2G_ENABLE_OFFSET 30
+#define TX_MGMT_RATE_5G_ENABLE_OFFSET 31
+#define TX_MGMT_RATE_2G_OFFSET 0
+#define TX_MGMT_RATE_5G_OFFSET 12
+
+/**
+ * wma_set_mgmt_rate() - set vdev mgmt rate.
+ * @wma:     wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void wma_set_vdev_mgmt_rate(tp_wma_handle wma, uint8_t vdev_id)
+{
+	uint32_t cfg_val;
+	int ret;
+	uint32_t per_band_mgmt_tx_rate = 0;
+	enum cds_band_type band = 0;
+	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (NULL == mac) {
+		WMA_LOGE("%s: Failed to get mac", __func__);
+		return;
+	}
+
+	cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
+	band = CDS_BAND_ALL;
+	if ((cfg_val == MLME_CFG_TX_MGMT_RATE_DEF) ||
+	    !wma_verify_rate_code(cfg_val, band)) {
+		WMA_LOGD("default WNI_CFG_RATE_FOR_TX_MGMT, ignore");
+	} else {
+		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					 WMI_VDEV_PARAM_MGMT_TX_RATE,
+					 cfg_val);
+		if (ret)
+			WMA_LOGE("Failed to set WMI_VDEV_PARAM_MGMT_TX_RATE");
+	}
+
+	cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt_2g;
+	band = CDS_BAND_2GHZ;
+	if ((cfg_val == MLME_CFG_TX_MGMT_2G_RATE_DEF) ||
+	    !wma_verify_rate_code(cfg_val, band)) {
+		WMA_LOGD("use default 2G MGMT rate.");
+		per_band_mgmt_tx_rate &=
+		    ~(1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
+	} else {
+		per_band_mgmt_tx_rate |=
+		    (1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
+		per_band_mgmt_tx_rate |=
+		    ((cfg_val & 0x7FF) << TX_MGMT_RATE_2G_OFFSET);
+	}
+
+	cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
+	band = CDS_BAND_5GHZ;
+	if ((cfg_val == MLME_CFG_TX_MGMT_5G_RATE_DEF) ||
+	    !wma_verify_rate_code(cfg_val, band)) {
+		WMA_LOGD("use default 5G MGMT rate.");
+		per_band_mgmt_tx_rate &=
+		    ~(1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
+	} else {
+		per_band_mgmt_tx_rate |=
+		    (1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
+		per_band_mgmt_tx_rate |=
+		    ((cfg_val & 0x7FF) << TX_MGMT_RATE_5G_OFFSET);
+	}
+
+	ret = wma_vdev_set_param(
+		wma->wmi_handle,
+		vdev_id,
+		WMI_VDEV_PARAM_PER_BAND_MGMT_TX_RATE,
+		per_band_mgmt_tx_rate);
+	if (ret)
+		WMA_LOGE("Failed to set WMI_VDEV_PARAM_PER_BAND_MGMT_TX_RATE");
+
+}
+
+/**
+ * wma_set_sap_keepalive() - set SAP keep alive parameters to fw
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: none
+ */
+void wma_set_sap_keepalive(tp_wma_handle wma, uint8_t vdev_id)
+{
+	uint32_t min_inactive_time, max_inactive_time, max_unresponsive_time;
+	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
+	QDF_STATUS status;
+
+	if (NULL == mac) {
+		WMA_LOGE("%s: Failed to get mac", __func__);
+		return;
+	}
+
+	wma_get_link_probe_timeout(mac, wma->interfaces[vdev_id].sub_type,
+				   &max_inactive_time, &max_unresponsive_time);
+
+	min_inactive_time = max_inactive_time / 2;
+
+	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
+			min_inactive_time);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGE("Failed to Set AP MIN IDLE INACTIVE TIME");
+
+	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
+			max_inactive_time);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGE("Failed to Set AP MAX IDLE INACTIVE TIME");
+
+	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
+			max_unresponsive_time);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGE("Failed to Set MAX UNRESPONSIVE TIME");
+
+	WMA_LOGD("%s:vdev_id:%d min_inactive_time: %u max_inactive_time: %u max_unresponsive_time: %u",
+		 __func__, vdev_id,
+		 min_inactive_time, max_inactive_time, max_unresponsive_time);
+}
+
+/**
+ * wma_set_sta_sa_query_param() - set sta sa query parameters
+ * @wma: wma handle
+ * @vdev_id: vdev id
+
+ * This function sets sta query related parameters in fw.
+ *
+ * Return: none
+ */
+
+void wma_set_sta_sa_query_param(tp_wma_handle wma,
+				  uint8_t vdev_id)
+{
+	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
+	uint8_t max_retries;
+	uint16_t retry_interval;
+
+	WMA_LOGD(FL("Enter:"));
+
+	if (!mac) {
+		WMA_LOGE(FL("mac context is NULL"));
+		return;
+	}
+
+	max_retries = mac->mlme_cfg->gen.pmf_sa_query_max_retries;
+	retry_interval = mac->mlme_cfg->gen.pmf_sa_query_retry_interval;
+
+	wmi_unified_set_sta_sa_query_param_cmd(wma->wmi_handle,
+						vdev_id,
+						max_retries,
+						retry_interval);
+
+	WMA_LOGD(FL("Exit :"));
+}
+
+/**
+ * wma_set_sta_keep_alive() - set sta keep alive parameters
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @method: method for keep alive
+ * @timeperiod: time period
+ * @hostv4addr: host ipv4 address
+ * @destv4addr: dst ipv4 address
+ * @destmac: destination mac
+ *
+ * This function sets keep alive related parameters in fw.
+ *
+ * Return: none
+ */
+void wma_set_sta_keep_alive(tp_wma_handle wma, uint8_t vdev_id,
+			    uint32_t method, uint32_t timeperiod,
+			    uint8_t *hostv4addr, uint8_t *destv4addr,
+			    uint8_t *destmac)
+{
+	struct sta_params params;
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	if (!wma) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return;
+	}
+
+	if (timeperiod > cfg_max(CFG_INFRA_STA_KEEP_ALIVE_PERIOD)) {
+		WMI_LOGE("Invalid period %d Max limit %d", timeperiod,
+			 cfg_max(CFG_INFRA_STA_KEEP_ALIVE_PERIOD));
+		return;
+	}
+
+	params.vdev_id = vdev_id;
+	params.method = method;
+	params.timeperiod = timeperiod;
+	params.hostv4addr = hostv4addr;
+	params.destv4addr = destv4addr;
+	params.destmac = destmac;
+
+	wmi_unified_set_sta_keep_alive_cmd(wma->wmi_handle,
+						&params);
+	WMA_LOGD("%s: Exit", __func__);
+}
+
+/**
+ * wma_vdev_install_key_complete_event_handler() - install key complete handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: data length
+ *
+ * This event is sent by fw once WPA/WPA2 keys are installed in fw.
+ *
+ * Return: 0 for success or error code
+ */
+int wma_vdev_install_key_complete_event_handler(void *handle,
+						uint8_t *event,
+						uint32_t len)
+{
+	WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf = NULL;
+	wmi_vdev_install_key_complete_event_fixed_param *key_fp = NULL;
+
+	if (!event) {
+		WMA_LOGE("%s: event param null", __func__);
+		return -EINVAL;
+	}
+
+	param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("%s: received null buf from target", __func__);
+		return -EINVAL;
+	}
+
+	key_fp = param_buf->fixed_param;
+	if (!key_fp) {
+		WMA_LOGE("%s: received null event data from target", __func__);
+		return -EINVAL;
+	}
+	/*
+	 * Do nothing for now. Completion of set key is already indicated to lim
+	 */
+	WMA_LOGD("%s: WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID", __func__);
+	return 0;
+}
+/*
+ * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
+ *   0 for no restriction
+ *   1 for 1/4 us - Our lower layer calculations limit our precision to 1 msec
+ *   2 for 1/2 us - Our lower layer calculations limit our precision to 1 msec
+ *   3 for 1 us
+ *   4 for 2 us
+ *   5 for 4 us
+ *   6 for 8 us
+ *   7 for 16 us
+ */
+static const uint8_t wma_mpdu_spacing[] = { 0, 1, 1, 1, 2, 4, 8, 16 };
+
+/**
+ * wma_parse_mpdudensity() - give mpdu spacing from mpdu density
+ * @mpdudensity: mpdu density
+ *
+ * Return: mpdu spacing or 0 for error
+ */
+static inline uint8_t wma_parse_mpdudensity(uint8_t mpdudensity)
+{
+	if (mpdudensity < sizeof(wma_mpdu_spacing))
+		return wma_mpdu_spacing[mpdudensity];
+	else
+		return 0;
+}
+
+#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
+
+/**
+ * wma_unified_peer_state_update() - update peer state
+ * @pdev: pdev handle
+ * @sta_mac: pointer to sta mac addr
+ * @bss_addr: bss address
+ * @sta_type: sta entry type
+ *
+ *
+ * Return: None
+ */
+static void
+wma_unified_peer_state_update(
+	struct cdp_pdev *pdev,
+	uint8_t *sta_mac,
+	uint8_t *bss_addr,
+	uint8_t sta_type)
+{
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (STA_ENTRY_TDLS_PEER == sta_type)
+		cdp_peer_state_update(soc, pdev, sta_mac,
+					  OL_TXRX_PEER_STATE_AUTH);
+	else
+		cdp_peer_state_update(soc, pdev, bss_addr,
+					  OL_TXRX_PEER_STATE_AUTH);
+}
+#else
+
+static inline void
+wma_unified_peer_state_update(
+	struct cdp_pdev *pdev,
+	uint8_t *sta_mac,
+	uint8_t *bss_addr,
+	uint8_t sta_type)
+{
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	cdp_peer_state_update(soc, pdev, bss_addr, OL_TXRX_PEER_STATE_AUTH);
+}
+#endif
+
+#define CFG_CTRL_MASK              0xFF00
+#define CFG_DATA_MASK              0x00FF
+
+/**
+ * wma_mask_tx_ht_rate() - mask tx ht rate based on config
+ * @wma:     wma handle
+ * @mcs_set  mcs set buffer
+ *
+ * Return: None
+ */
+static void wma_mask_tx_ht_rate(tp_wma_handle wma, uint8_t *mcs_set)
+{
+	uint32_t i, j;
+	uint16_t mcs_limit;
+	uint8_t *rate_pos = mcs_set;
+	struct mac_context *mac = (struct mac_context *)wma->mac_context;
+
+	/*
+	 * Get MCS limit from ini configure, and map it to rate parameters
+	 * This will limit HT rate upper bound. CFG_CTRL_MASK is used to
+	 * check whether ini config is enabled and CFG_DATA_MASK to get the
+	 * MCS value.
+	 */
+	mcs_limit = mac->mlme_cfg->rates.max_htmcs_txdata;
+
+	if (mcs_limit & CFG_CTRL_MASK) {
+		WMA_LOGD("%s: set mcs_limit %x", __func__, mcs_limit);
+
+		mcs_limit &= CFG_DATA_MASK;
+		for (i = 0, j = 0; i < MAX_SUPPORTED_RATES;) {
+			if (j < mcs_limit / 8) {
+				rate_pos[j] = 0xff;
+				j++;
+				i += 8;
+			} else if (j < mcs_limit / 8 + 1) {
+				if (i <= mcs_limit)
+					rate_pos[i / 8] |= 1 << (i % 8);
+				else
+					rate_pos[i / 8] &= ~(1 << (i % 8));
+				i++;
+
+				if (i >= (j + 1) * 8)
+					j++;
+			} else {
+				rate_pos[j++] = 0;
+				i += 8;
+			}
+		}
+	}
+}
+
+#if SUPPORT_11AX
+/**
+ * wma_fw_to_host_phymode_11ac() - convert fw to host phymode for 11ax phymodes
+ * @wma:     wma handle
+ * @phymode: phymode to convert
+ *
+ * Return: None
+ */
+static enum wlan_phymode wma_fw_to_host_phymode_11ac(WLAN_PHY_MODE phymode)
+{
+	switch (phymode) {
+	default:
+		return WLAN_PHYMODE_AUTO;
+	case MODE_11AX_HE20:
+		return WLAN_PHYMODE_11AC_VHT20;
+	case MODE_11AX_HE40:
+		return WLAN_PHYMODE_11AC_VHT40;
+	case MODE_11AX_HE80:
+		return WLAN_PHYMODE_11AC_VHT80;
+	case MODE_11AX_HE80_80:
+		return WLAN_PHYMODE_11AC_VHT80_80;
+	case MODE_11AX_HE160:
+		return WLAN_PHYMODE_11AC_VHT160;
+	case MODE_11AX_HE20_2G:
+		return WLAN_PHYMODE_11AC_VHT20;
+	case MODE_11AX_HE40_2G:
+		return WLAN_PHYMODE_11AC_VHT40;
+	case MODE_11AX_HE80_2G:
+		return WLAN_PHYMODE_11AC_VHT80;
+	}
+	return WLAN_PHYMODE_AUTO;
+}
+#else
+static enum wlan_phymode wma_fw_to_host_phymode_11ac(WLAN_PHY_MODE phymode)
+{
+	return WLAN_PHYMODE_AUTO;
+}
+#endif
+
+#ifdef CONFIG_160MHZ_SUPPORT
+/**
+ * wma_fw_to_host_phymode_160() - convert fw to host phymode for 160 mhz
+ * phymodes
+ * @wma:     wma handle
+ * @phymode: phymode to convert
+ *
+ * Return: None
+ */
+static enum wlan_phymode wma_fw_to_host_phymode_160(WLAN_PHY_MODE phymode)
+{
+	switch (phymode) {
+	default:
+		return WLAN_PHYMODE_AUTO;
+	case MODE_11AC_VHT80_80:
+		return WLAN_PHYMODE_11AC_VHT80_80;
+	case MODE_11AC_VHT160:
+		return WLAN_PHYMODE_11AC_VHT160;
+	}
+}
+#else
+static enum wlan_phymode wma_fw_to_host_phymode_160(WLAN_PHY_MODE phymode)
+{
+	return WLAN_PHYMODE_AUTO;
+}
+#endif
+/**
+ * wma_fw_to_host_phymode() - convert fw to host phymode
+ * @wma:     wma handle
+ * @phymode: phymode to convert
+ *
+ * Return: None
+ */
+static enum wlan_phymode wma_fw_to_host_phymode(WLAN_PHY_MODE phymode)
+{
+	enum wlan_phymode host_phymode;
+	switch (phymode) {
+	default:
+		host_phymode = wma_fw_to_host_phymode_160(phymode);
+		if (host_phymode != WLAN_PHYMODE_AUTO)
+			return host_phymode;
+		return wma_fw_to_host_phymode_11ac(phymode);
+	case MODE_11A:
+		return WLAN_PHYMODE_11A;
+	case MODE_11G:
+		return WLAN_PHYMODE_11G;
+	case MODE_11B:
+		return WLAN_PHYMODE_11B;
+	case MODE_11GONLY:
+		return WLAN_PHYMODE_11G;
+	case MODE_11NA_HT20:
+		return WLAN_PHYMODE_11NA_HT20;
+	case MODE_11NG_HT20:
+		return WLAN_PHYMODE_11NG_HT20;
+	case MODE_11NA_HT40:
+		return WLAN_PHYMODE_11NA_HT40;
+	case MODE_11NG_HT40:
+		return WLAN_PHYMODE_11NG_HT40;
+	case MODE_11AC_VHT20:
+		return WLAN_PHYMODE_11AC_VHT20;
+	case MODE_11AC_VHT40:
+		return WLAN_PHYMODE_11AC_VHT40;
+	case MODE_11AC_VHT80:
+		return WLAN_PHYMODE_11AC_VHT80;
+	case MODE_11AC_VHT20_2G:
+		return WLAN_PHYMODE_11AC_VHT20;
+	case MODE_11AC_VHT40_2G:
+		return WLAN_PHYMODE_11AC_VHT40;
+	case MODE_11AC_VHT80_2G:
+		return WLAN_PHYMODE_11AC_VHT80;
+	}
+}
+
+/**
+ * wma_objmgr_set_peer_mlme_phymode() - set phymode to peer object
+ * @wma:      wma handle
+ * @mac_addr: mac addr of peer
+ * @phymode:  phymode value to set
+ *
+ * Return: None
+ */
+static void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma,
+					     uint8_t *mac_addr,
+					     WLAN_PHY_MODE phymode)
+{
+	uint8_t pdev_id;
+	struct wlan_objmgr_peer *peer;
+	struct wlan_objmgr_psoc *psoc = wma->psoc;
+
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(wma->pdev);
+	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
+				    WLAN_LEGACY_WMA_ID);
+	if (!peer) {
+		WMA_LOGE(FL("peer object null"));
+		return;
+	}
+
+	wlan_peer_obj_lock(peer);
+	wlan_peer_set_phymode(peer, wma_fw_to_host_phymode(phymode));
+	wlan_peer_obj_unlock(peer);
+	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
+}
+
+/**
+ * wmi_unified_send_peer_assoc() - send peer assoc command to fw
+ * @wma: wma handle
+ * @nw_type: nw type
+ * @params: add sta params
+ *
+ * This function send peer assoc command to firmware with
+ * different parameters.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma,
+				    tSirNwType nw_type,
+				    tpAddStaParams params)
+{
+	struct cdp_pdev *pdev;
+	struct peer_assoc_params *cmd;
+	int32_t ret, max_rates, i;
+	uint8_t *rate_pos;
+	wmi_rate_set peer_legacy_rates, peer_ht_rates;
+	uint32_t num_peer_11b_rates = 0;
+	uint32_t num_peer_11a_rates = 0;
+	uint32_t phymode;
+	uint32_t peer_nss = 1;
+	struct wma_txrx_node *intr = NULL;
+	bool is_he;
+	QDF_STATUS status;
+	struct mac_context *mac = (struct mac_context *)wma->mac_context;
+
+	cmd = qdf_mem_malloc(sizeof(struct peer_assoc_params));
+	if (!cmd) {
+		WMA_LOGE("Failed to allocate peer_assoc_params param");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	intr = &wma->interfaces[params->smesessionId];
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		qdf_mem_free(cmd);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wma_mask_tx_ht_rate(wma, params->supportedRates.supportedMCSSet);
+
+	qdf_mem_zero(&peer_legacy_rates, sizeof(wmi_rate_set));
+	qdf_mem_zero(&peer_ht_rates, sizeof(wmi_rate_set));
+	qdf_mem_zero(cmd, sizeof(struct peer_assoc_params));
+
+	is_he = wma_is_peer_he_capable(params);
+	phymode = wma_peer_phymode(nw_type, params->staType,
+				   params->htCapable, params->ch_width,
+				   params->vhtCapable, is_he);
+
+	wma_objmgr_set_peer_mlme_phymode(wma, params->staMac, phymode);
+
+	if (!mac->mlme_cfg->rates.disable_abg_rate_txdata) {
+		/* Legacy Rateset */
+		rate_pos = (uint8_t *) peer_legacy_rates.rates;
+		for (i = 0; i < SIR_NUM_11B_RATES; i++) {
+			if (!params->supportedRates.llbRates[i])
+				continue;
+			rate_pos[peer_legacy_rates.num_rates++] =
+				params->supportedRates.llbRates[i];
+			num_peer_11b_rates++;
+		}
+		for (i = 0; i < SIR_NUM_11A_RATES; i++) {
+			if (!params->supportedRates.llaRates[i])
+				continue;
+			rate_pos[peer_legacy_rates.num_rates++] =
+				params->supportedRates.llaRates[i];
+			num_peer_11a_rates++;
+		}
+	}
+
+	if ((phymode == MODE_11A && num_peer_11a_rates == 0) ||
+	    (phymode == MODE_11B && num_peer_11b_rates == 0)) {
+		WMA_LOGW("%s: Invalid phy rates. phymode 0x%x, 11b_rates %d, 11a_rates %d",
+			__func__, phymode, num_peer_11b_rates,
+			num_peer_11a_rates);
+		qdf_mem_free(cmd);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* HT Rateset */
+	max_rates = sizeof(peer_ht_rates.rates) /
+		    sizeof(peer_ht_rates.rates[0]);
+	rate_pos = (uint8_t *) peer_ht_rates.rates;
+	for (i = 0; i < MAX_SUPPORTED_RATES; i++) {
+		if (params->supportedRates.supportedMCSSet[i / 8] &
+		    (1 << (i % 8))) {
+			rate_pos[peer_ht_rates.num_rates++] = i;
+			if (i >= 8) {
+				/* MCS8 or higher rate is present, must be 2x2 */
+				peer_nss = 2;
+			}
+		}
+		if (peer_ht_rates.num_rates == max_rates)
+			break;
+	}
+
+	if (params->htCapable && !peer_ht_rates.num_rates) {
+		uint8_t temp_ni_rates[8] = { 0x0, 0x1, 0x2, 0x3,
+					     0x4, 0x5, 0x6, 0x7};
+		/*
+		 * Workaround for EV 116382: The peer is marked HT but with
+		 * supported rx mcs set is set to 0. 11n spec mandates MCS0-7
+		 * for a HT STA. So forcing the supported rx mcs rate to
+		 * MCS 0-7. This workaround will be removed once we get
+		 * clarification from WFA regarding this STA behavior.
+		 */
+
+		/* TODO: Do we really need this? */
+		WMA_LOGW("Peer is marked as HT capable but supported mcs rate is 0");
+		peer_ht_rates.num_rates = sizeof(temp_ni_rates);
+		qdf_mem_copy((uint8_t *) peer_ht_rates.rates, temp_ni_rates,
+			     peer_ht_rates.num_rates);
+	}
+
+	/* in ap/ibss mode and for tdls peer, use mac address of the peer in
+	 * the other end as the new peer address; in sta mode, use bss id to
+	 * be the new peer address
+	 */
+	if ((wma_is_vdev_in_ap_mode(wma, params->smesessionId))
+	    || (wma_is_vdev_in_ibss_mode(wma, params->smesessionId))
+#ifdef FEATURE_WLAN_TDLS
+	    || (STA_ENTRY_TDLS_PEER == params->staType)
+#endif /* FEATURE_WLAN_TDLS */
+	    )
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(params->staMac, &cmd->peer_macaddr);
+	else
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(params->bssId, &cmd->peer_macaddr);
+	cmd->vdev_id = params->smesessionId;
+	cmd->peer_new_assoc = 1;
+	cmd->peer_associd = params->assocId;
+
+	/*
+	 * The target only needs a subset of the flags maintained in the host.
+	 * Just populate those flags and send it down
+	 */
+	cmd->peer_flags = 0;
+
+	if (params->wmmEnabled)
+		cmd->peer_flags |= WMI_PEER_QOS;
+
+	if (params->uAPSD) {
+		cmd->peer_flags |= WMI_PEER_APSD;
+		WMA_LOGD("Set WMI_PEER_APSD: uapsd Mask %d", params->uAPSD);
+	}
+
+	if (params->htCapable) {
+		cmd->peer_flags |= (WMI_PEER_HT | WMI_PEER_QOS);
+		cmd->peer_rate_caps |= WMI_RC_HT_FLAG;
+
+		if (params->ch_width) {
+			cmd->peer_flags |= WMI_PEER_40MHZ;
+			cmd->peer_rate_caps |= WMI_RC_CW40_FLAG;
+			if (params->fShortGI40Mhz)
+				cmd->peer_rate_caps |= WMI_RC_SGI_FLAG;
+		} else if (params->fShortGI20Mhz) {
+			cmd->peer_rate_caps |= WMI_RC_SGI_FLAG;
+		}
+	}
+
+	if (params->vhtCapable) {
+		cmd->peer_flags |= (WMI_PEER_HT | WMI_PEER_VHT | WMI_PEER_QOS);
+		cmd->peer_rate_caps |= WMI_RC_HT_FLAG;
+	}
+
+	if (params->ch_width == CH_WIDTH_80MHZ)
+		cmd->peer_flags |= WMI_PEER_80MHZ;
+	else if (params->ch_width == CH_WIDTH_160MHZ)
+		cmd->peer_flags |= WMI_PEER_160MHZ;
+	else if (params->ch_width == CH_WIDTH_80P80MHZ)
+		cmd->peer_flags |= WMI_PEER_160MHZ;
+
+	cmd->peer_vht_caps = params->vht_caps;
+	if (params->p2pCapableSta)
+		cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE;
+
+	if (params->rmfEnabled)
+		cmd->peer_flags |= WMI_PEER_PMF;
+
+	if (params->stbc_capable)
+		cmd->peer_flags |= WMI_PEER_STBC;
+
+	if (params->htLdpcCapable || params->vhtLdpcCapable)
+		cmd->peer_flags |= WMI_PEER_LDPC;
+
+	switch (params->mimoPS) {
+	case eSIR_HT_MIMO_PS_STATIC:
+		cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS;
+		break;
+	case eSIR_HT_MIMO_PS_DYNAMIC:
+		cmd->peer_flags |= WMI_PEER_DYN_MIMOPS;
+		break;
+	case eSIR_HT_MIMO_PS_NO_LIMIT:
+		cmd->peer_flags |= WMI_PEER_SPATIAL_MUX;
+		break;
+	default:
+		break;
+	}
+
+	wma_set_twt_peer_caps(params, cmd);
+#ifdef FEATURE_WLAN_TDLS
+	if (STA_ENTRY_TDLS_PEER == params->staType)
+		cmd->peer_flags |= WMI_PEER_AUTH;
+#endif /* FEATURE_WLAN_TDLS */
+
+	if (params->wpa_rsn
+#ifdef FEATURE_WLAN_WAPI
+	    || params->encryptType == eSIR_ED_WPI
+#endif /* FEATURE_WLAN_WAPI */
+	    ) {
+		cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
+		WMA_LOGD("Acquire set key wake lock for %d ms",
+			WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT);
+		wma_acquire_wakelock(&intr->vdev_set_key_wakelock,
+			WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT);
+	}
+	if (params->wpa_rsn >> 1)
+		cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
+
+	wma_unified_peer_state_update(pdev, params->staMac,
+				      params->bssId, params->staType);
+
+#ifdef FEATURE_WLAN_WAPI
+	if (params->encryptType == eSIR_ED_WPI) {
+		ret = wma_vdev_set_param(wma->wmi_handle, params->smesessionId,
+				      WMI_VDEV_PARAM_DROP_UNENCRY, false);
+		if (ret) {
+			WMA_LOGE
+				("Set WMI_VDEV_PARAM_DROP_UNENCRY Param status:%d\n",
+				ret);
+			qdf_mem_free(cmd);
+			return ret;
+		}
+	}
+#endif /* FEATURE_WLAN_WAPI */
+
+	cmd->peer_caps = params->capab_info;
+	cmd->peer_listen_intval = params->listenInterval;
+	cmd->peer_ht_caps = params->ht_caps;
+	cmd->peer_max_mpdu = (1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
+				    params->maxAmpduSize)) - 1;
+	cmd->peer_mpdu_density = wma_parse_mpdudensity(params->maxAmpduDensity);
+
+	if (params->supportedRates.supportedMCSSet[1] &&
+	    params->supportedRates.supportedMCSSet[2])
+		cmd->peer_rate_caps |= WMI_RC_TS_FLAG;
+	else if (params->supportedRates.supportedMCSSet[1])
+		cmd->peer_rate_caps |= WMI_RC_DS_FLAG;
+
+	/* Update peer legacy rate information */
+	cmd->peer_legacy_rates.num_rates = peer_legacy_rates.num_rates;
+	qdf_mem_copy(cmd->peer_legacy_rates.rates, peer_legacy_rates.rates,
+		     peer_legacy_rates.num_rates);
+
+	/* Update peer HT rate information */
+	cmd->peer_ht_rates.num_rates = peer_ht_rates.num_rates;
+	qdf_mem_copy(cmd->peer_ht_rates.rates, peer_ht_rates.rates,
+				 peer_ht_rates.num_rates);
+
+	/* VHT Rates */
+
+	cmd->peer_nss = peer_nss;
+	/*
+	 * Because of DBS a vdev may come up in any of the two MACs with
+	 * different capabilities. STBC capab should be fetched for given
+	 * hard_mode->MAC_id combo. It is planned that firmware should provide
+	 * these dev capabilities. But for now number of tx streams can be used
+	 * to identify if Tx STBC needs to be disabled.
+	 */
+	if (intr->tx_streams < 2) {
+		cmd->peer_vht_caps &= ~(1 << SIR_MAC_VHT_CAP_TXSTBC);
+		WMA_LOGD("Num tx_streams: %d, Disabled txSTBC",
+			 intr->tx_streams);
+	}
+	WMA_LOGD("peer_nss %d peer_ht_rates.num_rates %d ", cmd->peer_nss,
+		 peer_ht_rates.num_rates);
+
+	cmd->vht_capable = params->vhtCapable;
+	if (params->vhtCapable) {
+#define VHT2x2MCSMASK 0xc
+		cmd->rx_max_rate = params->supportedRates.vhtRxHighestDataRate;
+		cmd->rx_mcs_set = params->supportedRates.vhtRxMCSMap;
+		cmd->tx_max_rate = params->supportedRates.vhtTxHighestDataRate;
+		cmd->tx_mcs_set = params->supportedRates.vhtTxMCSMap;
+
+		if (params->vhtSupportedRxNss) {
+			cmd->peer_nss = params->vhtSupportedRxNss;
+		} else {
+			cmd->peer_nss = ((cmd->rx_mcs_set & VHT2x2MCSMASK)
+					 == VHT2x2MCSMASK) ? 1 : 2;
+		}
+	}
+
+	WMA_LOGD(FL("rx_max_rate: %d, rx_mcs: %x, tx_max_rate: %d, tx_mcs: %x"),
+		 cmd->rx_max_rate, cmd->rx_mcs_set, cmd->tx_max_rate,
+		 cmd->tx_mcs_set);
+
+	/*
+	 * Limit nss to max number of rf chain supported by target
+	 * Otherwise Fw will crash
+	 */
+	if (cmd->peer_nss > WMA_MAX_NSS)
+		cmd->peer_nss = WMA_MAX_NSS;
+
+	wma_populate_peer_he_cap(cmd, params);
+
+	intr->nss = cmd->peer_nss;
+	cmd->peer_phymode = phymode;
+	WMA_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x peer_caps %x",
+		 __func__,  cmd->vdev_id, cmd->peer_associd, cmd->peer_flags,
+		 cmd->peer_rate_caps, cmd->peer_caps);
+	WMA_LOGD("%s:listen_intval %d ht_caps %x max_mpdu %d nss %d phymode %d",
+		 __func__, cmd->peer_listen_intval, cmd->peer_ht_caps,
+		 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode);
+	WMA_LOGD("%s: peer_mpdu_density %d encr_type %d cmd->peer_vht_caps %x",
+		 __func__, cmd->peer_mpdu_density, params->encryptType,
+		 cmd->peer_vht_caps);
+
+	status = wmi_unified_peer_assoc_send(wma->wmi_handle,
+					 cmd);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGP(FL("Failed to send peer assoc command status = %d"),
+			status);
+	qdf_mem_free(cmd);
+
+	return status;
+}
+
+/**
+ * wmi_unified_vdev_set_gtx_cfg_send() - set GTX params
+ * @wmi_handle: wmi handle
+ * @if_id: vdev id
+ * @gtx_info: GTX config params
+ *
+ * This function set GTX related params in firmware.
+ *
+ * Return: 0 for success or error code
+ */
+QDF_STATUS wmi_unified_vdev_set_gtx_cfg_send(wmi_unified_t wmi_handle,
+				  uint32_t if_id,
+				  gtx_config_t *gtx_info)
+{
+	struct wmi_gtx_config params;
+
+	params.gtx_rt_mask[0] = gtx_info->gtxRTMask[0];
+	params.gtx_rt_mask[1] = gtx_info->gtxRTMask[1];
+	params.gtx_usrcfg = gtx_info->gtxUsrcfg;
+	params.gtx_threshold = gtx_info->gtxPERThreshold;
+	params.gtx_margin = gtx_info->gtxPERMargin;
+	params.gtx_tpcstep = gtx_info->gtxTPCstep;
+	params.gtx_tpcmin = gtx_info->gtxTPCMin;
+	params.gtx_bwmask = gtx_info->gtxBWMask;
+
+	return wmi_unified_vdev_set_gtx_cfg_cmd(wmi_handle,
+						if_id, &params);
+
+}
+
+/**
+ * wma_update_protection_mode() - update protection mode
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @llbcoexist: protection mode info
+ *
+ * This function set protection mode(RTS/CTS) to fw for passed vdev id.
+ *
+ * Return: none
+ */
+void wma_update_protection_mode(tp_wma_handle wma, uint8_t vdev_id,
+			   uint8_t llbcoexist)
+{
+	QDF_STATUS ret;
+	enum ieee80211_protmode prot_mode;
+
+	prot_mode = llbcoexist ? IEEE80211_PROT_CTSONLY : IEEE80211_PROT_NONE;
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					      WMI_VDEV_PARAM_PROTECTION_MODE,
+					      prot_mode);
+
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Failed to send wmi protection mode cmd");
+	else
+		WMA_LOGD("Updated protection mode %d to target", prot_mode);
+}
+
+void
+wma_update_beacon_interval(tp_wma_handle wma, uint8_t vdev_id,
+			   uint16_t beaconInterval)
+{
+	QDF_STATUS ret;
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					      WMI_VDEV_PARAM_BEACON_INTERVAL,
+					      beaconInterval);
+
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Failed to update beacon interval");
+	else
+		WMA_LOGI("Updated beacon interval %d for vdev %d",
+			 beaconInterval, vdev_id);
+}
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+/**
+ * wma_update_bss_color() - update beacon bss color in fw
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @he_ops: HE operation, only the bss_color and bss_color_disabled fields
+ * are updated.
+ *
+ * Return: none
+ */
+static void
+wma_update_bss_color(tp_wma_handle wma, uint8_t vdev_id,
+		     tUpdateBeaconParams *bcn_params)
+{
+	QDF_STATUS ret;
+	uint32_t dword_he_ops = 0;
+
+	WMI_HEOPS_COLOR_SET(dword_he_ops, bcn_params->bss_color);
+	WMI_HEOPS_BSSCOLORDISABLE_SET(dword_he_ops,
+				bcn_params->bss_color_disabled);
+	WMA_LOGD("vdev: %d, update bss color, HE_OPS: 0x%x",
+		vdev_id, dword_he_ops);
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			      WMI_VDEV_PARAM_BSS_COLOR, dword_he_ops);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Failed to update HE operations");
+}
+#else
+static void wma_update_bss_color(tp_wma_handle wma, uint8_t vdev_id,
+			   tUpdateBeaconParams *bcn_params)
+{
+}
+#endif
+
+/**
+ * wma_process_update_beacon_params() - update beacon parameters to target
+ * @wma: wma handle
+ * @bcn_params: beacon parameters
+ *
+ * Return: none
+ */
+void
+wma_process_update_beacon_params(tp_wma_handle wma,
+				 tUpdateBeaconParams *bcn_params)
+{
+	if (!bcn_params) {
+		WMA_LOGE("bcn_params NULL");
+		return;
+	}
+
+	if (bcn_params->smeSessionId >= wma->max_bssid) {
+		WMA_LOGE("Invalid vdev id %d", bcn_params->smeSessionId);
+		return;
+	}
+
+	if (bcn_params->paramChangeBitmap & PARAM_BCN_INTERVAL_CHANGED) {
+		wma_update_beacon_interval(wma, bcn_params->smeSessionId,
+					   bcn_params->beaconInterval);
+	}
+
+	if (bcn_params->paramChangeBitmap & PARAM_llBCOEXIST_CHANGED)
+		wma_update_protection_mode(wma, bcn_params->smeSessionId,
+					   bcn_params->llbCoexist);
+
+	if (bcn_params->paramChangeBitmap & PARAM_BSS_COLOR_CHANGED)
+		wma_update_bss_color(wma, bcn_params->smeSessionId,
+				     bcn_params);
+}
+
+/**
+ * wma_update_rts_params() - update cfg parameters to target
+ * @wma: wma handle
+ * @value: rts_threshold
+ *
+ * Return: none
+ */
+void wma_update_rts_params(tp_wma_handle wma, uint32_t value)
+{
+	uint8_t vdev_id;
+	QDF_STATUS ret;
+
+	for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
+		if (wma->interfaces[vdev_id].handle != 0) {
+			ret = wma_vdev_set_param(wma->wmi_handle,
+						 vdev_id,
+						 WMI_VDEV_PARAM_RTS_THRESHOLD,
+						 value);
+			if (QDF_IS_STATUS_ERROR(ret))
+				WMA_LOGE("Update cfg param fail for vdevId %d",
+					 vdev_id);
+		}
+	}
+}
+
+/**
+ * wma_update_frag_params() - update cfg parameters to target
+ * @wma: wma handle
+ * @value: frag_threshold
+ *
+ * Return: none
+ */
+void wma_update_frag_params(tp_wma_handle wma, uint32_t value)
+{
+	uint8_t vdev_id;
+	QDF_STATUS ret;
+
+	for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
+		if (wma->interfaces[vdev_id].handle != 0) {
+			ret = wma_vdev_set_param(wma->wmi_handle,
+					vdev_id,
+					WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
+					value);
+			if (QDF_IS_STATUS_ERROR(ret))
+				WMA_LOGE("Update cfg params failed for vdevId %d",
+					vdev_id);
+		}
+	}
+}
+
+/**
+ * wma_read_cfg_wepkey() - fill key_info for WEP key
+ * @wma_handle: wma handle
+ * @key_info: key_info ptr
+ * @def_key_idx: default key index
+ * @num_keys: number of keys
+ *
+ * This function reads WEP keys from cfg and fills
+ * up key_info.
+ *
+ * Return: none
+ */
+static void wma_read_cfg_wepkey(tp_wma_handle wma_handle,
+				tSirKeys *key_info, uint32_t *def_key_idx,
+				uint8_t *num_keys)
+{
+	QDF_STATUS status;
+	uint32_t val = SIR_MAC_KEY_LENGTH;
+	uint8_t i, j;
+	tpAniSirGlobal mac_ctx = wma_handle->mac_context;
+
+	WMA_LOGD("Reading WEP keys from cfg");
+
+	/* NOTE:def_key_idx is initialized to 0 by the caller */
+	*def_key_idx = mac_ctx->mlme_cfg->wep_params.wep_default_key_id;
+
+	for (i = 0, j = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) {
+		status = mlme_get_wep_key(&mac_ctx->mlme_cfg->wep_params,
+					  (MLME_WEP_DEFAULT_KEY_1 +
+					  i), key_info[j].key, val);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			WMA_LOGE("WEP key is not configured at :%d", i);
+		} else {
+			key_info[j].keyId = i;
+			key_info[j].keyLength = (uint16_t) val;
+			j++;
+		}
+	}
+	*num_keys = j;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+#define WPI_IV_LEN 16
+#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390)
+/**
+ * wma_fill_in_wapi_key_params() - update key parameters about wapi
+ * @key_params: wma key parameters
+ * @params: parameters pointer to be set
+ * @mode: operation mode
+ *
+ * Return: None
+ */
+static inline void wma_fill_in_wapi_key_params(
+		struct wma_set_key_params *key_params,
+		struct set_key_params *params, uint8_t mode)
+{
+	/*
+	 * Since MCL shares same FW with WIN for Napier/Hasting, FW WAPI logic
+	 * is fit for WIN, change it to align with WIN.
+	 */
+	unsigned char iv_init_ap[16] = { 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
+					 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
+					 0x5c, 0x36, 0x5c, 0x37};
+	unsigned char iv_init_sta[16] = { 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
+					  0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
+					  0x5c, 0x36, 0x5c, 0x36};
+
+	if (mode == wlan_op_mode_ap) {
+		qdf_mem_copy(params->rx_iv, iv_init_sta,
+			     WPI_IV_LEN);
+		qdf_mem_copy(params->tx_iv, iv_init_ap,
+			     WPI_IV_LEN);
+	} else {
+		qdf_mem_copy(params->rx_iv, iv_init_ap,
+			     WPI_IV_LEN);
+		qdf_mem_copy(params->tx_iv, iv_init_sta,
+			     WPI_IV_LEN);
+	}
+
+	params->key_txmic_len = WMA_TXMIC_LEN;
+	params->key_rxmic_len = WMA_RXMIC_LEN;
+
+	params->key_cipher = WMI_CIPHER_WAPI;
+}
+#else
+static inline void wma_fill_in_wapi_key_params(
+		struct wma_set_key_params *key_params,
+		struct set_key_params *params, uint8_t mode)
+{
+	/*initialize receive and transmit IV with default values */
+	/* **Note: tx_iv must be sent in reverse** */
+	unsigned char tx_iv[16] = { 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c,
+				    0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c,
+				    0x36, 0x5c, 0x36, 0x5c};
+	unsigned char rx_iv[16] = { 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
+				    0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
+				    0x5c, 0x36, 0x5c, 0x37};
+	if (mode == wlan_op_mode_ap) {
+		/* Authenticator initializes the value of PN as
+		 * 0x5C365C365C365C365C365C365C365C36 for MCastkeyUpdate
+		 */
+		if (key_params->unicast)
+			tx_iv[0] = 0x37;
+
+		rx_iv[WPI_IV_LEN - 1] = 0x36;
+	} else {
+		if (!key_params->unicast)
+			rx_iv[WPI_IV_LEN - 1] = 0x36;
+	}
+
+	params->key_txmic_len = WMA_TXMIC_LEN;
+	params->key_rxmic_len = WMA_RXMIC_LEN;
+
+	qdf_mem_copy(params->rx_iv, &rx_iv,
+		     WPI_IV_LEN);
+	qdf_mem_copy(params->tx_iv, &tx_iv,
+		     WPI_IV_LEN);
+	params->key_cipher = WMI_CIPHER_WAPI;
+}
+#endif
+#endif
+
+/**
+ * wma_setup_install_key_cmd() - set key parameters
+ * @wma_handle: wma handle
+ * @key_params: key parameters
+ * @mode: op mode
+ *
+ * This function fills structure from information
+ * passed in key_params.
+ *
+ * Return: QDF_STATUS_SUCCESS - success
+	QDF_STATUS_E_FAILURE - failure
+	QDF_STATUS_E_NOMEM - invalid request
+ */
+static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle,
+					   struct wma_set_key_params
+					   *key_params, uint8_t mode)
+{
+	struct set_key_params params;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wma_txrx_node *iface = NULL;
+	enum cdp_sec_type sec_type = cdp_sec_type_none;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	struct cdp_vdev *txrx_vdev;
+	uint32_t pn[4] = {0, 0, 0, 0};
+	uint8_t peer_id;
+	struct cdp_peer *peer;
+
+	if ((key_params->key_type == eSIR_ED_NONE &&
+	     key_params->key_len) || (key_params->key_type != eSIR_ED_NONE &&
+				      !key_params->key_len)) {
+		WMA_LOGE("%s:Invalid set key request", __func__);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	if (NULL == wma_handle) {
+		WMA_LOGE(FL("Invalid wma_handle for vdev_id: %d"),
+			key_params->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wma_is_vdev_valid(key_params->vdev_id)) {
+		WMA_LOGE("%s: vdev id:%d is not active ", __func__,
+			 key_params->vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	txrx_vdev = wma_find_vdev_by_id(wma_handle,
+					key_params->vdev_id);
+	peer = cdp_peer_find_by_addr(soc, txrx_pdev,
+				key_params->peer_mac, &peer_id);
+	iface = &wma_handle->interfaces[key_params->vdev_id];
+
+	params.vdev_id = key_params->vdev_id;
+	params.key_idx = key_params->key_idx;
+	qdf_mem_copy(params.peer_mac, key_params->peer_mac, IEEE80211_ADDR_LEN);
+
+#ifdef FEATURE_WLAN_WAPI
+	qdf_mem_set(params.tx_iv, 16, 0);
+	qdf_mem_set(params.rx_iv, 16, 0);
+#endif
+	params.key_txmic_len = 0;
+	params.key_rxmic_len = 0;
+	params.key_rsc_counter = qdf_mem_malloc(sizeof(uint64_t));
+	if (!params.key_rsc_counter) {
+		WMA_LOGE(FL("can't allocate memory for key_rsc_counter"));
+		return QDF_STATUS_E_NOMEM;
+	}
+	qdf_mem_copy(params.key_rsc_counter,
+		     &key_params->key_rsc[0], sizeof(uint64_t));
+	params.key_flags = 0;
+	if (key_params->unicast)
+		params.key_flags |= PAIRWISE_USAGE;
+	else
+		params.key_flags |= GROUP_USAGE;
+
+	switch (key_params->key_type) {
+	case eSIR_ED_NONE:
+		params.key_cipher = WMI_CIPHER_NONE;
+		sec_type = cdp_sec_type_none;
+		break;
+	case eSIR_ED_WEP40:
+	case eSIR_ED_WEP104:
+		params.key_cipher = WMI_CIPHER_WEP;
+		if (key_params->unicast &&
+		    params.key_idx == key_params->def_key_idx) {
+			WMA_LOGD("STA Mode: cmd->key_flags |= TX_USAGE");
+			params.key_flags |= TX_USAGE;
+		} else if ((mode == wlan_op_mode_ap) &&
+			(params.key_idx == key_params->def_key_idx)) {
+			WMA_LOGD("AP Mode: cmd->key_flags |= TX_USAGE");
+			params.key_flags |= TX_USAGE;
+		}
+		sec_type = cdp_sec_type_wep104;
+		break;
+	case eSIR_ED_TKIP:
+		params.key_txmic_len = WMA_TXMIC_LEN;
+		params.key_rxmic_len = WMA_RXMIC_LEN;
+		params.key_cipher = WMI_CIPHER_TKIP;
+		sec_type = cdp_sec_type_tkip;
+		break;
+#ifdef FEATURE_WLAN_WAPI
+	case eSIR_ED_WPI:
+	{
+		wma_fill_in_wapi_key_params(key_params, &params, mode);
+		break;
+	}
+#endif /* FEATURE_WLAN_WAPI */
+	case eSIR_ED_CCMP:
+		params.key_cipher = WMI_CIPHER_AES_CCM;
+		sec_type = cdp_sec_type_aes_ccmp;
+		break;
+#ifdef WLAN_FEATURE_11W
+	case eSIR_ED_AES_128_CMAC:
+		params.key_cipher = WMI_CIPHER_AES_CMAC;
+		break;
+	case eSIR_ED_AES_GMAC_128:
+	case eSIR_ED_AES_GMAC_256:
+		params.key_cipher = WMI_CIPHER_AES_GMAC;
+		break;
+#endif /* WLAN_FEATURE_11W */
+	/* Firmware uses length to detect GCMP 128/256*/
+	case eSIR_ED_GCMP:
+	case eSIR_ED_GCMP_256:
+		params.key_cipher = WMI_CIPHER_AES_GCM;
+		break;
+	default:
+		/* TODO: MFP ? */
+		WMA_LOGE("%s:Invalid encryption type:%d", __func__,
+			 key_params->key_type);
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+
+#ifdef BIG_ENDIAN_HOST
+	{
+		/* for big endian host, copy engine byte_swap is enabled
+		 * But the key data content is in network byte order
+		 * Need to byte swap the key data content - so when copy engine
+		 * does byte_swap - target gets key_data content in the correct
+		 * order.
+		 */
+		int8_t i;
+		uint32_t *destp, *srcp;
+
+		destp = (uint32_t *) params.key_data;
+		srcp = (uint32_t *) key_params->key_data;
+		for (i = 0;
+		     i < roundup(key_params->key_len, sizeof(uint32_t)) / 4;
+		     i++) {
+			*destp = le32_to_cpu(*srcp);
+			destp++;
+			srcp++;
+		}
+	}
+#else
+	qdf_mem_copy((void *)params.key_data,
+		     (const void *)key_params->key_data, key_params->key_len);
+#endif /* BIG_ENDIAN_HOST */
+	params.key_len = key_params->key_len;
+
+#ifdef WLAN_FEATURE_11W
+	iface = &wma_handle->interfaces[key_params->vdev_id];
+
+	if ((key_params->key_type == eSIR_ED_AES_128_CMAC) ||
+	   (key_params->key_type == eSIR_ED_AES_GMAC_128) ||
+	   (key_params->key_type == eSIR_ED_AES_GMAC_256)) {
+		if (iface) {
+			iface->key.key_length = key_params->key_len;
+			iface->key.key_cipher = params.key_cipher;
+			qdf_mem_copy(iface->key.key,
+				     (const void *)key_params->key_data,
+				     iface->key.key_length);
+			if ((params.key_idx == WMA_IGTK_KEY_INDEX_4) ||
+			    (params.key_idx == WMA_IGTK_KEY_INDEX_5))
+				qdf_mem_zero(iface->key.key_id[params.key_idx -
+						    WMA_IGTK_KEY_INDEX_4].ipn,
+					     CMAC_IPN_LEN);
+		}
+	}
+
+	if (key_params->unicast && iface)
+		iface->ucast_key_cipher = params.key_cipher;
+#endif /* WLAN_FEATURE_11W */
+
+	WMA_LOGD("Key setup : vdev_id %d key_idx %d key_type %d key_len %d",
+		 key_params->vdev_id, key_params->key_idx,
+		 key_params->key_type, key_params->key_len);
+	WMA_LOGD("unicast %d peer_mac %pM def_key_idx %d",
+		 key_params->unicast, key_params->peer_mac,
+		 key_params->def_key_idx);
+	WMA_LOGD("keyrsc param %llu", *(params.key_rsc_counter));
+
+	/* Set PN check & security type in data path */
+	cdp_set_pn_check(soc, txrx_vdev, peer, sec_type, pn);
+	cdp_set_key(soc, peer, key_params->unicast,
+		    (uint32_t *)(key_params->key_data +
+				WMA_IV_KEY_LEN +
+				WMA_TXMIC_LEN));
+
+	status = wmi_unified_setup_install_key_cmd(wma_handle->wmi_handle,
+								&params);
+	if (!key_params->unicast) {
+		/* Its GTK release the wake lock */
+		WMA_LOGD("Release set key wake lock");
+		wma_release_wakelock(&iface->vdev_set_key_wakelock);
+	}
+
+	/* install key was requested */
+	if (iface)
+		iface->is_waiting_for_key = false;
+
+end:
+	qdf_mem_free(params.key_rsc_counter);
+	return status;
+}
+
+/**
+ * wma_set_bsskey() - set encryption key to fw.
+ * @wma_handle: wma handle
+ * @key_info: key info
+ *
+ * Return: none
+ */
+void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info)
+{
+	struct wma_set_key_params key_params;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t i;
+	uint32_t def_key_idx = 0;
+	uint32_t wlan_opmode;
+	struct cdp_vdev *txrx_vdev;
+	uint8_t *mac_addr;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	WMA_LOGD("BSS key setup");
+	txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId);
+	if (!txrx_vdev) {
+		WMA_LOGE("%s:Invalid vdev handle", __func__);
+		key_info->status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+	wlan_opmode = cdp_get_opmode(soc, txrx_vdev);
+
+	/*
+	 * For IBSS, WMI expects the BSS key to be set per peer key
+	 * So cache the BSS key in the wma_handle and re-use it when the
+	 * STA key is been setup for a peer
+	 */
+	if (wlan_op_mode_ibss == wlan_opmode) {
+		key_info->status = QDF_STATUS_SUCCESS;
+		if (wma_handle->ibss_started > 0)
+			goto out;
+		WMA_LOGD("Caching IBSS Key");
+		qdf_mem_copy(&wma_handle->ibsskey_info, key_info,
+			     sizeof(tSetBssKeyParams));
+	}
+
+	qdf_mem_set(&key_params, sizeof(key_params), 0);
+	key_params.vdev_id = key_info->smesessionId;
+	key_params.key_type = key_info->encType;
+	key_params.singl_tid_rc = key_info->singleTidRc;
+	key_params.unicast = false;
+	if (wlan_opmode == wlan_op_mode_sta) {
+		qdf_mem_copy(key_params.peer_mac,
+			wma_handle->interfaces[key_info->smesessionId].bssid,
+			IEEE80211_ADDR_LEN);
+	} else {
+		mac_addr = cdp_get_vdev_mac_addr(soc,
+					txrx_vdev);
+		if (mac_addr == NULL) {
+			WMA_LOGE("%s: mac_addr is NULL for vdev with id %d",
+				 __func__, key_info->smesessionId);
+			goto out;
+		}
+		/* vdev mac address will be passed for all other modes */
+		qdf_mem_copy(key_params.peer_mac, mac_addr,
+			     IEEE80211_ADDR_LEN);
+		WMA_LOGD("BSS Key setup with vdev_mac %pM\n",
+			 mac_addr);
+	}
+
+	if (key_info->numKeys == 0 &&
+	    (key_info->encType == eSIR_ED_WEP40 ||
+	     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++) {
+		if (key_params.key_type != eSIR_ED_NONE &&
+		    !key_info->key[i].keyLength)
+			continue;
+		if (key_info->encType == eSIR_ED_WPI) {
+			key_params.key_idx = key_info->key[i].keyId;
+			key_params.def_key_idx = key_info->key[i].keyId;
+		} else
+			key_params.key_idx = key_info->key[i].keyId;
+
+		key_params.key_len = key_info->key[i].keyLength;
+		qdf_mem_copy(key_params.key_rsc,
+				key_info->key[i].keyRsc,
+				SIR_MAC_MAX_KEY_RSC_LEN);
+		if (key_info->encType == eSIR_ED_TKIP) {
+			qdf_mem_copy(key_params.key_data,
+				     key_info->key[i].key, 16);
+			qdf_mem_copy(&key_params.key_data[16],
+				     &key_info->key[i].key[24], 8);
+			qdf_mem_copy(&key_params.key_data[24],
+				     &key_info->key[i].key[16], 8);
+		} else
+			qdf_mem_copy((void *)key_params.key_data,
+				     (const void *)key_info->key[i].key,
+				     key_info->key[i].keyLength);
+
+		WMA_LOGD("%s: bss key[%d] length %d", __func__, i,
+			 key_info->key[i].keyLength);
+
+		status = wma_setup_install_key_cmd(wma_handle, &key_params,
+						   wlan_opmode);
+		if (status == QDF_STATUS_E_NOMEM) {
+			WMA_LOGE("%s:Failed to setup install key buf",
+				 __func__);
+			key_info->status = QDF_STATUS_E_NOMEM;
+			goto out;
+		} else if (status == QDF_STATUS_E_FAILURE) {
+			WMA_LOGE("%s:Failed to send install key command",
+				 __func__);
+			key_info->status = QDF_STATUS_E_FAILURE;
+			goto out;
+		}
+	}
+
+	wma_handle->ibss_started++;
+	/* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */
+	key_info->status = QDF_STATUS_SUCCESS;
+
+out:
+	wma_send_msg_high_priority(wma_handle, WMA_SET_BSSKEY_RSP,
+				   (void *)key_info, 0);
+}
+
+#ifdef QCA_IBSS_SUPPORT
+/**
+ * wma_calc_ibss_heart_beat_timer() - calculate IBSS heart beat timer
+ * @peer_num: number of peers
+ *
+ * Return: heart beat timer value
+ */
+static uint16_t wma_calc_ibss_heart_beat_timer(int16_t peer_num)
+{
+	/* heart beat timer value look-up table */
+	/* entry index : (the number of currently connected peers) - 1
+	 * entry value : the heart time threshold value in seconds for
+	 * detecting ibss peer departure
+	 */
+	static const uint16_t heart_beat_timer[MAX_PEERS] = {
+		4, 4, 4, 4, 4, 4, 4, 4,
+		8, 8, 8, 8, 8, 8, 8, 8,
+		12, 12, 12, 12, 12, 12, 12, 12,
+		16, 16, 16, 16, 16, 16, 16, 16
+	};
+
+	if (peer_num < 1 || peer_num > MAX_PEERS)
+		return 0;
+
+	return heart_beat_timer[peer_num - 1];
+
+}
+
+/**
+ * wma_adjust_ibss_heart_beat_timer() - set ibss heart beat timer in fw.
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @peer_num_delta: peer number delta value
+ *
+ * Return: none
+ */
+void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma,
+				      uint8_t vdev_id,
+				      int8_t peer_num_delta)
+{
+	struct cdp_vdev *vdev;
+	int16_t new_peer_num;
+	uint16_t new_timer_value_sec;
+	uint32_t new_timer_value_ms;
+	QDF_STATUS status;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (peer_num_delta != 1 && peer_num_delta != -1) {
+		WMA_LOGE("Invalid peer_num_delta value %d", peer_num_delta);
+		return;
+	}
+
+	vdev = wma_find_vdev_by_id(wma, vdev_id);
+	if (!vdev) {
+		WMA_LOGE("vdev not found : vdev_id %d", vdev_id);
+		return;
+	}
+
+	/* adjust peer numbers */
+	new_peer_num = cdp_peer_update_ibss_add_peer_num_of_vdev(soc,
+					vdev, peer_num_delta);
+	if (OL_TXRX_INVALID_NUM_PEERS == new_peer_num) {
+		WMA_LOGE("new peer num %d out of valid boundary", new_peer_num);
+		return;
+	}
+
+	/* reset timer value if all peers departed */
+	if (new_peer_num == 0) {
+		cdp_set_ibss_vdev_heart_beat_timer(soc, vdev, 0);
+		return;
+	}
+
+	/* calculate new timer value */
+	new_timer_value_sec = wma_calc_ibss_heart_beat_timer(new_peer_num);
+	if (new_timer_value_sec == 0) {
+		WMA_LOGE("timer value %d is invalid for peer number %d",
+			 new_timer_value_sec, new_peer_num);
+		return;
+	}
+	if (new_timer_value_sec ==
+	    cdp_set_ibss_vdev_heart_beat_timer(soc,
+						vdev, new_timer_value_sec)) {
+		WMA_LOGD("timer value %d stays same, no need to notify target",
+			 new_timer_value_sec);
+		return;
+	}
+
+	new_timer_value_ms = ((uint32_t) new_timer_value_sec) * 1000;
+
+	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS,
+					 new_timer_value_ms);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Failed to set IBSS link monitoring timer value");
+		return;
+	}
+
+	WMA_LOGD("Set IBSS link monitor timer: peer_num = %d timer_value = %d",
+		 new_peer_num, new_timer_value_ms);
+}
+
+#endif /* QCA_IBSS_SUPPORT */
+/**
+ * wma_set_ibsskey_helper() - cached IBSS key in wma handle
+ * @wma_handle: wma handle
+ * @key_info: set bss key info
+ * @peerMacAddr: peer mac address
+ *
+ * Return: none
+ */
+static void wma_set_ibsskey_helper(tp_wma_handle wma_handle,
+				   tpSetBssKeyParams key_info,
+				   struct qdf_mac_addr peer_macaddr)
+{
+	struct wma_set_key_params key_params;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t i;
+	uint32_t def_key_idx = 0;
+	struct cdp_vdev *txrx_vdev;
+	int opmode;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	WMA_LOGD("BSS key setup for peer");
+	txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId);
+	if (!txrx_vdev) {
+		WMA_LOGE("%s:Invalid vdev handle", __func__);
+		key_info->status = QDF_STATUS_E_FAILURE;
+		return;
+	}
+
+	qdf_mem_set(&key_params, sizeof(key_params), 0);
+	opmode = cdp_get_opmode(soc, txrx_vdev);
+	qdf_mem_set(&key_params, sizeof(key_params), 0);
+	key_params.vdev_id = key_info->smesessionId;
+	key_params.key_type = key_info->encType;
+	key_params.singl_tid_rc = key_info->singleTidRc;
+	key_params.unicast = false;
+	ASSERT(wlan_op_mode_ibss == opmode);
+
+	qdf_mem_copy(key_params.peer_mac, peer_macaddr.bytes,
+			IEEE80211_ADDR_LEN);
+
+	if (key_info->numKeys == 0 &&
+	    (key_info->encType == eSIR_ED_WEP40 ||
+	     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++) {
+		if (key_params.key_type != eSIR_ED_NONE &&
+		    !key_info->key[i].keyLength)
+			continue;
+		key_params.key_idx = key_info->key[i].keyId;
+		key_params.key_len = key_info->key[i].keyLength;
+		if (key_info->encType == eSIR_ED_TKIP) {
+			qdf_mem_copy(key_params.key_data,
+				     key_info->key[i].key, 16);
+			qdf_mem_copy(&key_params.key_data[16],
+				     &key_info->key[i].key[24], 8);
+			qdf_mem_copy(&key_params.key_data[24],
+				     &key_info->key[i].key[16], 8);
+		} else
+			qdf_mem_copy((void *)key_params.key_data,
+				     (const void *)key_info->key[i].key,
+				     key_info->key[i].keyLength);
+
+		WMA_LOGD("%s: peer bcast key[%d] length %d", __func__, i,
+			 key_info->key[i].keyLength);
+
+		status = wma_setup_install_key_cmd(wma_handle, &key_params,
+						   opmode);
+		if (status == QDF_STATUS_E_NOMEM) {
+			WMA_LOGE("%s:Failed to setup install key buf",
+				 __func__);
+			return;
+		} else if (status == QDF_STATUS_E_FAILURE) {
+			WMA_LOGE("%s:Failed to send install key command",
+				 __func__);
+		}
+	}
+}
+
+/**
+ * wma_set_stakey() - set encryption key
+ * @wma_handle: wma handle
+ * @key_info: station key info
+ *
+ * This function sets encryption key for WEP/WPA/WPA2
+ * encryption mode in firmware and send response to upper layer.
+ *
+ * Return: none
+ */
+void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info)
+{
+	int32_t i;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct cdp_pdev *txrx_pdev;
+	struct cdp_vdev *txrx_vdev;
+	void *peer;
+	uint8_t num_keys = 0, peer_id;
+	struct wma_set_key_params key_params;
+	uint32_t def_key_idx = 0;
+	int opmode;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	WMA_LOGD("STA key setup");
+
+	/* Get the txRx Pdev handle */
+	txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!txrx_pdev) {
+		WMA_LOGE("%s:Invalid txrx pdev handle", __func__);
+		key_info->status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	peer = cdp_peer_find_by_addr(soc, txrx_pdev,
+				key_info->peer_macaddr.bytes,
+				&peer_id);
+	if (!peer) {
+		WMA_LOGE("%s:Invalid peer for key setting", __func__);
+		key_info->status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId);
+	if (!txrx_vdev) {
+		WMA_LOGE("%s:TxRx Vdev Handle is NULL", __func__);
+		key_info->status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+	opmode = cdp_get_opmode(soc, txrx_vdev);
+
+	if (key_info->defWEPIdx == WMA_INVALID_KEY_IDX &&
+	    (key_info->encType == eSIR_ED_WEP40 ||
+	     key_info->encType == eSIR_ED_WEP104) &&
+	    opmode != wlan_op_mode_ap) {
+		wma_read_cfg_wepkey(wma_handle, key_info->key,
+				    &def_key_idx, &num_keys);
+		key_info->defWEPIdx = def_key_idx;
+	} else {
+		num_keys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
+		if (key_info->encType != eSIR_ED_NONE) {
+			for (i = 0; i < num_keys; i++) {
+				if (key_info->key[i].keyDirection ==
+				    eSIR_TX_DEFAULT) {
+					key_info->defWEPIdx = i;
+					break;
+				}
+			}
+		}
+	}
+	qdf_mem_set(&key_params, sizeof(key_params), 0);
+	key_params.vdev_id = key_info->smesessionId;
+	key_params.key_type = key_info->encType;
+	key_params.singl_tid_rc = key_info->singleTidRc;
+	key_params.unicast = true;
+	key_params.def_key_idx = key_info->defWEPIdx;
+	qdf_mem_copy((void *)key_params.peer_mac,
+		     (const void *)key_info->peer_macaddr.bytes,
+		     IEEE80211_ADDR_LEN);
+	for (i = 0; i < num_keys; i++) {
+		if (key_params.key_type != eSIR_ED_NONE &&
+		    !key_info->key[i].keyLength)
+			continue;
+		if (key_info->encType == eSIR_ED_TKIP) {
+			qdf_mem_copy(key_params.key_data,
+				     key_info->key[i].key, 16);
+			qdf_mem_copy(&key_params.key_data[16],
+				     &key_info->key[i].key[24], 8);
+			qdf_mem_copy(&key_params.key_data[24],
+				     &key_info->key[i].key[16], 8);
+		} else
+			qdf_mem_copy(key_params.key_data, key_info->key[i].key,
+				     key_info->key[i].keyLength);
+		if (key_info->encType == eSIR_ED_WPI) {
+			key_params.key_idx = key_info->key[i].keyId;
+			key_params.def_key_idx = key_info->key[i].keyId;
+		} else
+			key_params.key_idx = i;
+
+		key_params.key_len = key_info->key[i].keyLength;
+		status = wma_setup_install_key_cmd(wma_handle, &key_params,
+						   opmode);
+		if (status == QDF_STATUS_E_NOMEM) {
+			WMA_LOGE("%s:Failed to setup install key buf",
+				 __func__);
+			key_info->status = QDF_STATUS_E_NOMEM;
+			goto out;
+		}
+
+		WMA_LOGD("%s: peer unicast key[%d] %d ", __func__, i,
+			 key_info->key[i].keyLength);
+
+		if (status == QDF_STATUS_E_FAILURE) {
+			WMA_LOGE("%s:Failed to send install key command",
+				 __func__);
+			key_info->status = QDF_STATUS_E_FAILURE;
+			goto out;
+		}
+	}
+
+	/* In IBSS mode, set the BSS KEY for this peer
+	 * BSS key is supposed to be cache into wma_handle
+	 */
+	if (wlan_op_mode_ibss == opmode) {
+		wma_set_ibsskey_helper(wma_handle, &wma_handle->ibsskey_info,
+				       key_info->peer_macaddr);
+	}
+
+	/* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */
+	key_info->status = QDF_STATUS_SUCCESS;
+out:
+	if (key_info->sendRsp)
+		wma_send_msg_high_priority(wma_handle, WMA_SET_STAKEY_RSP,
+					   (void *)key_info, 0);
+}
+
+/**
+ * wma_process_update_edca_param_req() - update EDCA params
+ * @handle: wma handle
+ * @edca_params: edca parameters
+ *
+ * This function updates EDCA parameters to the target
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wma_process_update_edca_param_req(WMA_HANDLE handle,
+					     tEdcaParams *edca_params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	struct wmi_host_wme_vparams wmm_param[WME_NUM_AC];
+	tSirMacEdcaParamRecord *edca_record;
+	int ac;
+	struct cdp_pdev *pdev;
+	struct ol_tx_wmm_param_t ol_tx_wmm_param;
+	uint8_t vdev_id;
+	QDF_STATUS status;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	vdev_id = edca_params->bssIdx;
+
+	for (ac = 0; ac < WME_NUM_AC; ac++) {
+		switch (ac) {
+		case WME_AC_BE:
+			edca_record = &edca_params->acbe;
+			break;
+		case WME_AC_BK:
+			edca_record = &edca_params->acbk;
+			break;
+		case WME_AC_VI:
+			edca_record = &edca_params->acvi;
+			break;
+		case WME_AC_VO:
+			edca_record = &edca_params->acvo;
+			break;
+		default:
+			goto fail;
+		}
+
+		wma_update_edca_params_for_ac(edca_record, &wmm_param[ac], ac,
+				edca_params->mu_edca_params);
+
+		ol_tx_wmm_param.ac[ac].aifs = wmm_param[ac].aifs;
+		ol_tx_wmm_param.ac[ac].cwmin = wmm_param[ac].cwmin;
+		ol_tx_wmm_param.ac[ac].cwmax = wmm_param[ac].cwmax;
+	}
+
+	status = wmi_unified_process_update_edca_param(wma_handle->wmi_handle,
+						vdev_id,
+						edca_params->mu_edca_params,
+						wmm_param);
+	if (status == QDF_STATUS_E_NOMEM)
+		return status;
+	else if (status == QDF_STATUS_E_FAILURE)
+		goto fail;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (pdev)
+		cdp_set_wmm_param(soc, (struct cdp_pdev *)pdev,
+				 ol_tx_wmm_param);
+	else
+		QDF_ASSERT(0);
+
+	return QDF_STATUS_SUCCESS;
+
+fail:
+	WMA_LOGE("%s: Failed to set WMM Paremeters", __func__);
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * wmi_unified_probe_rsp_tmpl_send() - send probe response template to fw
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @probe_rsp_info: probe response info
+ *
+ * Return: 0 for success or error code
+ */
+static int wmi_unified_probe_rsp_tmpl_send(tp_wma_handle wma,
+				   uint8_t vdev_id,
+				   tpSendProbeRespParams probe_rsp_info)
+{
+	uint64_t adjusted_tsf_le;
+	struct ieee80211_frame *wh;
+	struct wmi_probe_resp_params params;
+
+	WMA_LOGD(FL("Send probe response template for vdev %d"), vdev_id);
+
+	/*
+	 * Make the TSF offset negative so probe response in the same
+	 * staggered batch have the same TSF.
+	 */
+	adjusted_tsf_le = cpu_to_le64(0ULL -
+				      wma->interfaces[vdev_id].tsfadjust);
+	/* Update the timstamp in the probe response buffer with adjusted TSF */
+	wh = (struct ieee80211_frame *)probe_rsp_info->probeRespTemplate;
+	A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le));
+
+	params.prb_rsp_template_len = probe_rsp_info->probeRespTemplateLen;
+	params.prb_rsp_template_frm = probe_rsp_info->probeRespTemplate;
+
+	return wmi_unified_probe_rsp_tmpl_send_cmd(wma->wmi_handle, vdev_id,
+						   &params);
+}
+
+/**
+ * wma_unified_bcn_tmpl_send() - send beacon template to fw
+ * @wma:wma handle
+ * @vdev_id: vdev id
+ * @bcn_info: beacon info
+ * @bytes_to_strip: bytes to strip
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS wma_unified_bcn_tmpl_send(tp_wma_handle wma,
+				     uint8_t vdev_id,
+				     const tpSendbeaconParams bcn_info,
+				     uint8_t bytes_to_strip)
+{
+	struct beacon_tmpl_params params = {0};
+	uint32_t tmpl_len, tmpl_len_aligned;
+	uint8_t *frm;
+	QDF_STATUS ret;
+	uint8_t *p2p_ie;
+	uint16_t p2p_ie_len = 0;
+	uint64_t adjusted_tsf_le;
+	struct ieee80211_frame *wh;
+
+	WMA_LOGD("Send beacon template for vdev %d", vdev_id);
+
+	if (bcn_info->p2pIeOffset) {
+		p2p_ie = bcn_info->beacon + bcn_info->p2pIeOffset;
+		p2p_ie_len = (uint16_t) p2p_ie[1] + 2;
+	}
+
+	/*
+	 * XXX: The first byte of beacon buffer contains beacon length
+	 * only when UMAC in sending the beacon template. In othercases
+	 * (ex: from tbtt update) beacon length is read from beacon
+	 * information.
+	 */
+	if (bytes_to_strip)
+		tmpl_len = *(uint32_t *) &bcn_info->beacon[0];
+	else
+		tmpl_len = bcn_info->beaconLength;
+	if (p2p_ie_len)
+		tmpl_len -= (uint32_t) p2p_ie_len;
+	frm = bcn_info->beacon + bytes_to_strip;
+	tmpl_len_aligned = roundup(tmpl_len, sizeof(A_UINT32));
+	/*
+	 * Make the TSF offset negative so beacons in the same
+	 * staggered batch have the same TSF.
+	 */
+	adjusted_tsf_le = cpu_to_le64(0ULL -
+				      wma->interfaces[vdev_id].tsfadjust);
+	/* Update the timstamp in the beacon buffer with adjusted TSF */
+	wh = (struct ieee80211_frame *)frm;
+	A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le));
+
+
+
+	params.vdev_id = vdev_id;
+	params.tim_ie_offset = bcn_info->timIeOffset - bytes_to_strip;
+	params.tmpl_len = tmpl_len;
+	params.frm = frm;
+	params.tmpl_len_aligned = tmpl_len_aligned;
+	if (bcn_info->csa_count_offset &&
+	    (bcn_info->csa_count_offset > bytes_to_strip))
+		params.csa_switch_count_offset =
+			bcn_info->csa_count_offset - bytes_to_strip;
+	if (bcn_info->ecsa_count_offset &&
+	    (bcn_info->ecsa_count_offset > bytes_to_strip))
+		params.ext_csa_switch_count_offset =
+			bcn_info->ecsa_count_offset - bytes_to_strip;
+
+	ret = wmi_unified_beacon_tmpl_send_cmd(wma->wmi_handle,
+				 &params);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret);
+
+	return ret;
+}
+
+/**
+ * wma_store_bcn_tmpl() - store beacon template
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @bcn_info: beacon params
+ *
+ * This function stores beacon template locally.
+ * This will send to target on the reception of
+ * SWBA event.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_store_bcn_tmpl(tp_wma_handle wma, uint8_t vdev_id,
+				     tpSendbeaconParams bcn_info)
+{
+	struct beacon_info *bcn;
+	uint32_t len;
+	uint8_t *bcn_payload;
+	struct beacon_tim_ie *tim_ie;
+
+	bcn = wma->interfaces[vdev_id].beacon;
+	if (!bcn || !bcn->buf) {
+		WMA_LOGE("%s: Memory is not allocated to hold bcn template",
+			 __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	len = *(uint32_t *) &bcn_info->beacon[0];
+	if (len > SIR_MAX_BEACON_SIZE - sizeof(uint32_t)) {
+		WMA_LOGE("%s: Received beacon len %u exceeding max limit %lu",
+			 __func__, len, (unsigned long)(
+			 SIR_MAX_BEACON_SIZE - sizeof(uint32_t)));
+		return QDF_STATUS_E_INVAL;
+	}
+	WMA_LOGD("%s: Storing received beacon template buf to local buffer",
+		 __func__);
+	qdf_spin_lock_bh(&bcn->lock);
+
+	/*
+	 * Copy received beacon template content in local buffer.
+	 * this will be send to target on the reception of SWBA
+	 * event from target.
+	 */
+	qdf_nbuf_trim_tail(bcn->buf, qdf_nbuf_len(bcn->buf));
+	memcpy(qdf_nbuf_data(bcn->buf),
+	       bcn_info->beacon + 4 /* Exclude beacon length field */,
+	       len);
+	if (bcn_info->timIeOffset > 3)
+		bcn->tim_ie_offset = bcn_info->timIeOffset - 4;
+	else
+		bcn->tim_ie_offset = bcn_info->timIeOffset;
+
+	if (bcn_info->p2pIeOffset > 3)
+		bcn->p2p_ie_offset = bcn_info->p2pIeOffset - 4;
+	else
+		bcn->p2p_ie_offset = bcn_info->p2pIeOffset;
+
+	bcn_payload = qdf_nbuf_data(bcn->buf);
+	if (bcn->tim_ie_offset) {
+		tim_ie = (struct beacon_tim_ie *)
+				(&bcn_payload[bcn->tim_ie_offset]);
+		/*
+		 * Initial Value of bcn->dtim_count will be 0.
+		 * But if the beacon gets updated then current dtim
+		 * count will be restored
+		 */
+		tim_ie->dtim_count = bcn->dtim_count;
+		tim_ie->tim_bitctl = 0;
+	}
+
+	qdf_nbuf_put_tail(bcn->buf, len);
+	bcn->len = len;
+
+	qdf_spin_unlock_bh(&bcn->lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_tbttoffset_update_event_handler() - tbtt offset update handler
+ * @handle: wma handle
+ * @event: event buffer
+ * @len: data length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_tbttoffset_update_event_handler(void *handle, uint8_t *event,
+					       uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
+	wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
+	struct wma_txrx_node *intf;
+	struct beacon_info *bcn;
+	tSendbeaconParams bcn_info;
+	uint32_t *adjusted_tsf = NULL;
+	uint32_t if_id = 0, vdev_map;
+
+	if (!wma) {
+		WMA_LOGE("Invalid wma handle");
+		return -EINVAL;
+	}
+
+	param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("Invalid tbtt update event buffer");
+		return -EINVAL;
+	}
+
+	tbtt_offset_event = param_buf->fixed_param;
+	intf = wma->interfaces;
+	vdev_map = tbtt_offset_event->vdev_map;
+	adjusted_tsf = param_buf->tbttoffset_list;
+	if (!adjusted_tsf) {
+		WMA_LOGE("%s: Invalid adjusted_tsf", __func__);
+		return -EINVAL;
+	}
+
+	for (; (if_id < wma->max_bssid && vdev_map); vdev_map >>= 1, if_id++) {
+		if (!(vdev_map & 0x1) || (!(intf[if_id].handle)))
+			continue;
+
+		bcn = intf[if_id].beacon;
+		if (!bcn) {
+			WMA_LOGE("%s: Invalid beacon", __func__);
+			return -EINVAL;
+		}
+		if (!bcn->buf) {
+			WMA_LOGE("%s: Invalid beacon buffer", __func__);
+			return -EINVAL;
+		}
+		/* Save the adjusted TSF */
+		intf[if_id].tsfadjust = adjusted_tsf[if_id];
+
+		qdf_spin_lock_bh(&bcn->lock);
+		qdf_mem_zero(&bcn_info, sizeof(bcn_info));
+		qdf_mem_copy(bcn_info.beacon,
+			     qdf_nbuf_data(bcn->buf), bcn->len);
+		bcn_info.p2pIeOffset = bcn->p2p_ie_offset;
+		bcn_info.beaconLength = bcn->len;
+		bcn_info.timIeOffset = bcn->tim_ie_offset;
+		qdf_spin_unlock_bh(&bcn->lock);
+
+		/* Update beacon template in firmware */
+		wma_unified_bcn_tmpl_send(wma, if_id, &bcn_info, 0);
+	}
+	return 0;
+}
+
+/**
+ * wma_p2p_go_set_beacon_ie() - set beacon IE for p2p go
+ * @wma_handle: wma handle
+ * @vdev_id: vdev id
+ * @p2pIe: p2p IE
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_p2p_go_set_beacon_ie(t_wma_handle *wma_handle,
+				    A_UINT32 vdev_id, uint8_t *p2pIe)
+{
+	if (!wma_handle) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wmi_unified_p2p_go_set_beacon_ie_cmd(wma_handle->wmi_handle,
+							vdev_id, p2pIe);
+}
+
+/**
+ * wma_send_probe_rsp_tmpl() - send probe resp template
+ * @wma: wma handle
+ * @probe_rsp_info: probe response info
+ *
+ * This funciton sends probe response template to fw which
+ * firmware will use in case of probe response offload.
+ *
+ * Return: none
+ */
+void wma_send_probe_rsp_tmpl(tp_wma_handle wma,
+				    tpSendProbeRespParams probe_rsp_info)
+{
+	struct cdp_vdev *vdev;
+	uint8_t vdev_id;
+	struct sAniProbeRspStruct *probe_rsp;
+
+	if (!probe_rsp_info) {
+		WMA_LOGE(FL("probe_rsp_info is NULL"));
+		return;
+	}
+
+	probe_rsp = (struct sAniProbeRspStruct *)
+			(probe_rsp_info->probeRespTemplate);
+	if (!probe_rsp) {
+		WMA_LOGE(FL("probe_rsp is NULL"));
+		return;
+	}
+
+	vdev = wma_find_vdev_by_addr(wma, probe_rsp->macHdr.sa, &vdev_id);
+	if (!vdev) {
+		WMA_LOGE(FL("failed to get vdev handle"));
+		return;
+	}
+
+	if (wmi_service_enabled(wma->wmi_handle,
+				   wmi_service_beacon_offload)) {
+		WMA_LOGD("Beacon Offload Enabled Sending Unified command");
+		if (wmi_unified_probe_rsp_tmpl_send(wma, vdev_id,
+						    probe_rsp_info) < 0) {
+			WMA_LOGE(FL("wmi_unified_probe_rsp_tmpl_send Failed "));
+			return;
+		}
+	}
+}
+
+#ifdef CONFIG_VDEV_SM
+QDF_STATUS wma_set_ap_vdev_up(tp_wma_handle wma, uint8_t vdev_id)
+{
+	struct vdev_up_params param = {0};
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	param.vdev_id = vdev_id;
+	param.assoc_id = 0;
+	status = wma_send_vdev_up_to_fw(wma, &param,
+					wma->interfaces[vdev_id].bssid);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE(FL("failed to send vdev up"));
+		policy_mgr_set_do_hw_mode_change_flag(
+			wma->psoc, false);
+		return status;
+	}
+	wma_set_sap_keepalive(wma, vdev_id);
+	wma_set_vdev_mgmt_rate(wma, vdev_id);
+
+	return status;
+}
+#else
+QDF_STATUS wma_set_ap_vdev_up(tp_wma_handle wma, uint8_t vdev_id)
+{
+	struct vdev_up_params param = {0};
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!wma_get_hidden_ssid_restart_in_progress(
+	     &wma->interfaces[vdev_id]) ||
+	    (wma->interfaces[vdev_id].is_channel_switch)) {
+		if (wma_is_vdev_up(vdev_id))
+			return status;
+		param.vdev_id = vdev_id;
+		param.assoc_id = 0;
+		status = wma_send_vdev_up_to_fw(wma, &param,
+						wma->interfaces[vdev_id].bssid);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			WMA_LOGE(FL("failed to send vdev up"));
+			policy_mgr_set_do_hw_mode_change_flag(
+				wma->psoc, false);
+			return status;
+		}
+		wma_vdev_set_mlme_state(wma, vdev_id, WLAN_VDEV_S_RUN);
+		wma_set_sap_keepalive(wma, vdev_id);
+		wma_set_vdev_mgmt_rate(wma, vdev_id);
+	}
+
+	return status;
+}
+#endif
+
+/**
+ * wma_send_beacon() - send beacon template
+ * @wma: wma handle
+ * @bcn_info: beacon info
+ *
+ * This funciton store beacon template locally and
+ * update keep alive parameters
+ *
+ * Return: none
+ */
+void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info)
+{
+	struct cdp_vdev *vdev;
+	uint8_t vdev_id;
+	QDF_STATUS status;
+	uint8_t *p2p_ie;
+	struct sAniBeaconStruct *beacon;
+
+	WMA_LOGD("Beacon update reason %d", bcn_info->reason);
+	beacon = (struct sAniBeaconStruct *) (bcn_info->beacon);
+	vdev = wma_find_vdev_by_addr(wma, beacon->macHdr.sa, &vdev_id);
+	if (!vdev) {
+		WMA_LOGE("%s : failed to get vdev handle", __func__);
+		status = QDF_STATUS_E_INVAL;
+		goto send_rsp;
+	}
+
+	if (wmi_service_enabled(wma->wmi_handle,
+				   wmi_service_beacon_offload)) {
+		WMA_LOGD("Beacon Offload Enabled Sending Unified command");
+		status = wma_unified_bcn_tmpl_send(wma, vdev_id, bcn_info, 4);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			WMA_LOGE("%s : wmi_unified_bcn_tmpl_send Failed ",
+				 __func__);
+			goto send_rsp;
+		}
+
+		if (bcn_info->p2pIeOffset) {
+			p2p_ie = bcn_info->beacon + bcn_info->p2pIeOffset;
+			WMA_LOGD("%s: p2pIe is present - vdev_id %hu, p2p_ie = %pK, p2p ie len = %hu",
+				 __func__, vdev_id, p2p_ie, p2p_ie[1]);
+			if (wma_p2p_go_set_beacon_ie(wma, vdev_id,
+							 p2p_ie) < 0) {
+				WMA_LOGE("%s : wmi_unified_bcn_tmpl_send Failed ",
+					__func__);
+				status = QDF_STATUS_E_INVAL;
+				goto send_rsp;
+			}
+		}
+	}
+	status = wma_store_bcn_tmpl(wma, vdev_id, bcn_info);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s : wma_store_bcn_tmpl Failed", __func__);
+		goto send_rsp;
+	}
+#ifndef CONFIG_VDEV_SM
+	wma_set_ap_vdev_up(wma, vdev_id);
+#endif
+
+send_rsp:
+	bcn_info->status = status;
+	wma_send_msg(wma, WMA_SEND_BCN_RSP, (void *)bcn_info, 0);
+}
+
+/**
+ * wma_set_keepalive_req() - send keep alive request to fw
+ * @wma: wma handle
+ * @keepalive: keep alive parameters
+ *
+ * Return: none
+ */
+void wma_set_keepalive_req(tp_wma_handle wma,
+			   tSirKeepAliveReq *keepalive)
+{
+	WMA_LOGD("KEEPALIVE:PacketType:%d", keepalive->packetType);
+	wma_set_sta_keep_alive(wma, keepalive->sessionId,
+			       keepalive->packetType,
+			       keepalive->timePeriod,
+			       keepalive->hostIpv4Addr,
+			       keepalive->destIpv4Addr,
+			       keepalive->dest_macaddr.bytes);
+
+	qdf_mem_free(keepalive);
+}
+
+/**
+ * wma_beacon_miss_handler() - beacon miss event handler
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @riis: rssi value
+ *
+ * This function send beacon miss indication to upper layers.
+ *
+ * Return: none
+ */
+void wma_beacon_miss_handler(tp_wma_handle wma, uint32_t vdev_id, int32_t rssi)
+{
+	tSirSmeMissedBeaconInd *beacon_miss_ind;
+	tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	beacon_miss_ind = (tSirSmeMissedBeaconInd *) qdf_mem_malloc
+				  (sizeof(tSirSmeMissedBeaconInd));
+
+	if (NULL == beacon_miss_ind) {
+		WMA_LOGE("%s: Memory allocation failure", __func__);
+		return;
+	}
+	if (mac && mac->sme.tx_queue_cb)
+		mac->sme.tx_queue_cb(mac->hdd_handle, vdev_id,
+				     WLAN_STOP_ALL_NETIF_QUEUE,
+				     WLAN_CONTROL_PATH);
+	beacon_miss_ind->messageType = WMA_MISSED_BEACON_IND;
+	beacon_miss_ind->length = sizeof(tSirSmeMissedBeaconInd);
+	beacon_miss_ind->bssIdx = vdev_id;
+
+	wma_send_msg(wma, WMA_MISSED_BEACON_IND, (void *)beacon_miss_ind, 0);
+	wma_lost_link_info_handler(wma, vdev_id, rssi +
+						 WMA_TGT_NOISE_FLOOR_DBM);
+}
+
+/**
+ * wma_get_status_str() - get string of tx status from firmware
+ * @status: tx status
+ *
+ * Return: converted string of tx status
+ */
+static const char *wma_get_status_str(uint32_t status)
+{
+	switch (status) {
+	default:
+		return "unknown";
+	CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK);
+	CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_DISCARD);
+	CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_INSPECT);
+	CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK);
+	CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_MAX);
+	}
+}
+
+/**
+ * wma_process_mgmt_tx_completion() - process mgmt completion
+ * @wma_handle: wma handle
+ * @desc_id: descriptor id
+ * @status: status
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle,
+					  uint32_t desc_id, uint32_t status)
+{
+	struct wlan_objmgr_pdev *pdev;
+	qdf_nbuf_t buf = NULL;
+	uint8_t vdev_id = 0;
+	QDF_STATUS ret;
+	tp_wma_packetdump_cb packetdump_cb;
+
+	if (wma_handle == NULL) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("%s: status: %s wmi_desc_id: %d", __func__,
+		wma_get_status_str(status), desc_id);
+
+	pdev = wma_handle->pdev;
+	if (pdev == NULL) {
+		WMA_LOGE("%s: psoc ptr is NULL", __func__);
+		return -EINVAL;
+	}
+
+	buf = mgmt_txrx_get_nbuf(pdev, desc_id);
+	vdev_id = mgmt_txrx_get_vdev_id(pdev, desc_id);
+
+	if (buf)
+		qdf_nbuf_unmap_single(wma_handle->qdf_dev, buf,
+					  QDF_DMA_TO_DEVICE);
+
+	packetdump_cb = wma_handle->wma_mgmt_tx_packetdump_cb;
+	if (packetdump_cb)
+		packetdump_cb(buf, QDF_STATUS_SUCCESS,
+			vdev_id, TX_MGMT_PKT);
+
+	ret = mgmt_txrx_tx_completion_handler(pdev, desc_id, status, NULL);
+
+	if (ret != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Failed to process mgmt tx completion", __func__);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_mgmt_tx_completion_handler() - wma mgmt Tx completion event handler
+ * @handle: wma handle
+ * @cmpl_event_params: completion event handler data
+ * @len: length of @cmpl_event_params
+ *
+ * Return: 0 on success; error number otherwise
+ */
+
+int wma_mgmt_tx_completion_handler(void *handle, uint8_t *cmpl_event_params,
+				   uint32_t len)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle)handle;
+	WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
+	wmi_mgmt_tx_compl_event_fixed_param	*cmpl_params;
+
+	param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *)
+		cmpl_event_params;
+	if (!param_buf || !wma_handle) {
+		WMA_LOGE("%s: Invalid mgmt Tx completion event", __func__);
+		return -EINVAL;
+	}
+	cmpl_params = param_buf->fixed_param;
+
+	wma_process_mgmt_tx_completion(wma_handle,
+		cmpl_params->desc_id, cmpl_params->status);
+
+	return 0;
+}
+
+/**
+ * wma_mgmt_tx_bundle_completion_handler() - mgmt bundle comp handler
+ * @handle: wma handle
+ * @buf: buffer
+ * @len: length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_mgmt_tx_bundle_completion_handler(void *handle, uint8_t *buf,
+				   uint32_t len)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle)handle;
+	WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID_param_tlvs *param_buf;
+	wmi_mgmt_tx_compl_bundle_event_fixed_param	*cmpl_params;
+	uint32_t num_reports;
+	uint32_t *desc_ids;
+	uint32_t *status;
+	uint32_t i, buf_len;
+	bool excess_data = false;
+
+	param_buf = (WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID_param_tlvs *)buf;
+	if (!param_buf || !wma_handle) {
+		WMA_LOGE("%s: Invalid mgmt Tx completion event", __func__);
+		return -EINVAL;
+	}
+	cmpl_params = param_buf->fixed_param;
+	num_reports = cmpl_params->num_reports;
+	desc_ids = (uint32_t *)(param_buf->desc_ids);
+	status = (uint32_t *)(param_buf->status);
+
+	/* buf contains num_reports * sizeof(uint32) len of desc_ids and
+	 * num_reports * sizeof(uint32) status,
+	 * so (2 x (num_reports * sizeof(uint32)) should not exceed MAX
+	 */
+	if (cmpl_params->num_reports > (WMI_SVC_MSG_MAX_SIZE /
+	    (2 * sizeof(uint32_t))))
+		excess_data = true;
+	else
+		buf_len = cmpl_params->num_reports * (2 * sizeof(uint32_t));
+
+	if (excess_data || (sizeof(*cmpl_params) > (WMI_SVC_MSG_MAX_SIZE -
+	    buf_len))) {
+		WMA_LOGE("excess wmi buffer: num_reports %d",
+			  cmpl_params->num_reports);
+		return -EINVAL;
+	}
+
+	if ((cmpl_params->num_reports > param_buf->num_desc_ids) ||
+	    (cmpl_params->num_reports > param_buf->num_status)) {
+		WMA_LOGE("Invalid num_reports %d, num_desc_ids %d, num_status %d",
+			 cmpl_params->num_reports, param_buf->num_desc_ids,
+			 param_buf->num_status);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < num_reports; i++)
+		wma_process_mgmt_tx_completion(wma_handle,
+			desc_ids[i], status[i]);
+	return 0;
+}
+
+/**
+ * wma_process_update_opmode() - process update VHT opmode cmd from UMAC
+ * @wma_handle: wma handle
+ * @update_vht_opmode: vht opmode
+ *
+ * Return: none
+ */
+void wma_process_update_opmode(tp_wma_handle wma_handle,
+			       tUpdateVHTOpMode *update_vht_opmode)
+{
+	struct wma_txrx_node *iface;
+	wmi_host_channel_width ch_width;
+
+	iface = &wma_handle->interfaces[update_vht_opmode->smesessionId];
+	ch_width = wmi_get_ch_width_from_phy_mode(wma_handle->wmi_handle,
+						  iface->chanmode);
+	if (ch_width < update_vht_opmode->opMode) {
+		WMA_LOGE("%s: Invalid peer bw update %d, self bw %d",
+				__func__, update_vht_opmode->opMode,
+				ch_width);
+		return;
+	}
+	WMA_LOGD("%s: opMode = %d", __func__, update_vht_opmode->opMode);
+	wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac,
+			   WMI_PEER_CHWIDTH, update_vht_opmode->opMode,
+			   update_vht_opmode->smesessionId);
+}
+
+/**
+ * wma_process_update_rx_nss() - process update RX NSS cmd from UMAC
+ * @wma_handle: wma handle
+ * @update_rx_nss: rx nss value
+ *
+ * Return: none
+ */
+void wma_process_update_rx_nss(tp_wma_handle wma_handle,
+			       tUpdateRxNss *update_rx_nss)
+{
+	struct target_psoc_info *tgt_hdl;
+	struct wma_txrx_node *intr =
+		&wma_handle->interfaces[update_rx_nss->smesessionId];
+	int rx_nss = update_rx_nss->rxNss;
+	int num_rf_chains;
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
+	if (!tgt_hdl) {
+		WMA_LOGE("%s: target psoc info is NULL", __func__);
+		return;
+	}
+
+	num_rf_chains = target_if_get_num_rf_chains(tgt_hdl);
+	if (rx_nss > num_rf_chains || rx_nss > WMA_MAX_NSS)
+		rx_nss = QDF_MIN(num_rf_chains, WMA_MAX_NSS);
+
+	intr->nss = (uint8_t)rx_nss;
+	update_rx_nss->rxNss = (uint32_t)rx_nss;
+
+	WMA_LOGD("%s: Rx Nss = %d", __func__, update_rx_nss->rxNss);
+
+	wma_set_peer_param(wma_handle, update_rx_nss->peer_mac,
+			   WMI_PEER_NSS, update_rx_nss->rxNss,
+			   update_rx_nss->smesessionId);
+}
+
+/**
+ * wma_process_update_membership() - process update group membership cmd
+ * @wma_handle: wma handle
+ * @membership: group membership info
+ *
+ * Return: none
+ */
+void wma_process_update_membership(tp_wma_handle wma_handle,
+				   tUpdateMembership *membership)
+{
+	WMA_LOGD("%s: membership = %x ", __func__, membership->membership);
+
+	wma_set_peer_param(wma_handle, membership->peer_mac,
+			   WMI_PEER_MEMBERSHIP, membership->membership,
+			   membership->smesessionId);
+}
+
+/**
+ * wma_process_update_userpos() - process update user pos cmd from UMAC
+ * @wma_handle: wma handle
+ * @userpos: user pos value
+ *
+ * Return: none
+ */
+void wma_process_update_userpos(tp_wma_handle wma_handle,
+				tUpdateUserPos *userpos)
+{
+	WMA_LOGD("%s: userPos = %x ", __func__, userpos->userPos);
+
+	wma_set_peer_param(wma_handle, userpos->peer_mac,
+			   WMI_PEER_USERPOS, userpos->userPos,
+			   userpos->smesessionId);
+
+	/* Now that membership/userpos is updated in fw,
+	 * enable GID PPS.
+	 */
+	wma_set_ppsconfig(userpos->smesessionId, WMA_VHT_PPS_GID_MATCH, 1);
+
+}
+
+QDF_STATUS wma_set_cts2self_for_p2p_go(void *wma_handle,
+				    uint32_t cts2self_for_p2p_go)
+{
+	int32_t ret;
+	tp_wma_handle wma = (tp_wma_handle)wma_handle;
+	struct pdev_params pdevparam;
+
+	pdevparam.param_id = WMI_PDEV_PARAM_CTS2SELF_FOR_P2P_GO_CONFIG;
+	pdevparam.param_value = cts2self_for_p2p_go;
+
+	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
+			&pdevparam,
+			WMA_WILDCARD_PDEV_ID);
+	if (ret) {
+		WMA_LOGE("Fail to Set CTS2SELF for p2p GO %d",
+			cts2self_for_p2p_go);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("Successfully Set CTS2SELF for p2p GO %d",
+		cts2self_for_p2p_go);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
+/**
+ * wma_set_htconfig() - set ht config parameters to target
+ * @vdev_id: vdev id
+ * @ht_capab: ht capablity
+ * @value: value of ht param
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_set_htconfig(uint8_t vdev_id, uint16_t ht_capab, int value)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
+
+	if (NULL == wma) {
+		WMA_LOGE("%s: Failed to get wma", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	switch (ht_capab) {
+	case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
+		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+						      WMI_VDEV_PARAM_LDPC,
+						      value);
+		break;
+	case WNI_CFG_HT_CAP_INFO_TX_STBC:
+		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+						      WMI_VDEV_PARAM_TX_STBC,
+						      value);
+		break;
+	case WNI_CFG_HT_CAP_INFO_RX_STBC:
+		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+						      WMI_VDEV_PARAM_RX_STBC,
+						      value);
+		break;
+	case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
+	case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
+		WMA_LOGE("%s: ht_capab = %d, value = %d", __func__, ht_capab,
+			 value);
+		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+						WMI_VDEV_PARAM_SGI, value);
+		if (ret == QDF_STATUS_SUCCESS)
+			wma->interfaces[vdev_id].config.shortgi = value;
+		break;
+	default:
+		WMA_LOGE("%s:INVALID HT CONFIG", __func__);
+	}
+
+	return ret;
+}
+
+/**
+ * wma_hidden_ssid_vdev_restart() - vdev restart for hidden ssid
+ * @wma_handle: wma handle
+ * @pReq: hidden ssid vdev restart request
+ *
+ * Return: none
+ */
+void wma_hidden_ssid_vdev_restart(tp_wma_handle wma,
+				  tHalHiddenSsidVdevRestart *pReq)
+{
+	struct wma_txrx_node *intr = wma->interfaces;
+	struct wma_target_req *msg;
+	struct hidden_ssid_vdev_restart_params params;
+	QDF_STATUS status;
+	uint8_t vdev_id;
+
+	vdev_id = pReq->sessionId;
+	if ((vdev_id != intr[vdev_id].vdev_restart_params.vdev_id)
+	    || !((intr[vdev_id].type == WMI_VDEV_TYPE_AP)
+		 && (intr[vdev_id].sub_type == 0))) {
+		WMA_LOGE(FL("invalid vdev_id %d"), vdev_id);
+		return;
+	}
+
+	intr[vdev_id].vdev_restart_params.ssidHidden = pReq->ssidHidden;
+#ifndef CONFIG_VDEV_SM
+	qdf_atomic_set(&intr[vdev_id].vdev_restart_params.
+		       hidden_ssid_restart_in_progress, 1);
+#endif
+	WMA_LOGD(FL("hidden ssid set using IOCTL for vdev %d ssid_hidden %d"),
+		 vdev_id, pReq->ssidHidden);
+
+	msg = wma_fill_vdev_req(wma, vdev_id,
+			WMA_HIDDEN_SSID_VDEV_RESTART,
+			WMA_TARGET_REQ_TYPE_VDEV_START,
+			pReq,
+			WMA_VDEV_START_REQUEST_TIMEOUT);
+	if (!msg) {
+		WMA_LOGE(FL("Failed to fill vdev request, vdev_id %d"),
+			 vdev_id);
+#ifndef CONFIG_VDEV_SM
+		qdf_atomic_set(&intr[vdev_id].vdev_restart_params.
+			       hidden_ssid_restart_in_progress, 0);
+#endif
+		qdf_mem_free(pReq);
+		return;
+	}
+
+	params.session_id = vdev_id;
+	params.ssid_len = intr[vdev_id].vdev_restart_params.ssid.ssid_len;
+	qdf_mem_copy(params.ssid,
+		     intr[vdev_id].vdev_restart_params.ssid.ssid,
+		     params.ssid_len);
+	params.flags = intr[vdev_id].vdev_restart_params.flags;
+	if (intr[vdev_id].vdev_restart_params.ssidHidden)
+		params.flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
+	else
+		params.flags &= (0xFFFFFFFE);
+	params.requestor_id = intr[vdev_id].vdev_restart_params.requestor_id;
+	params.disable_hw_ack =
+		intr[vdev_id].vdev_restart_params.disable_hw_ack;
+
+	params.mhz = intr[vdev_id].vdev_restart_params.chan.mhz;
+	params.band_center_freq1 =
+		intr[vdev_id].vdev_restart_params.chan.band_center_freq1;
+	params.band_center_freq2 =
+		intr[vdev_id].vdev_restart_params.chan.band_center_freq2;
+	params.info = intr[vdev_id].vdev_restart_params.chan.info;
+	params.reg_info_1 = intr[vdev_id].vdev_restart_params.chan.reg_info_1;
+	params.reg_info_2 = intr[vdev_id].vdev_restart_params.chan.reg_info_2;
+
+#ifndef CONFIG_VDEV_SM
+	wma_vdev_set_mlme_state(wma, vdev_id, WLAN_VDEV_S_STOP);
+#endif
+	status = wmi_unified_hidden_ssid_vdev_restart_send(wma->wmi_handle,
+							   &params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE(FL("Failed to send vdev restart command"));
+#ifndef CONFIG_VDEV_SM
+		qdf_atomic_set(&intr[vdev_id].vdev_restart_params.
+			       hidden_ssid_restart_in_progress, 0);
+#endif
+		wma_remove_vdev_req(wma, vdev_id,
+				    WMA_TARGET_REQ_TYPE_VDEV_START);
+		qdf_mem_free(pReq);
+	}
+}
+
+
+#ifdef WLAN_FEATURE_11W
+
+/**
+ * wma_extract_ccmp_pn() - extract 6 byte PN from the CCMP header
+ * @ccmp_ptr: CCMP header
+ *
+ * Return: PN extracted from header.
+ */
+static uint64_t wma_extract_ccmp_pn(uint8_t *ccmp_ptr)
+{
+	uint8_t rsvd, key, pn[6];
+	uint64_t new_pn;
+
+	/*
+	 *   +-----+-----+------+----------+-----+-----+-----+-----+
+	 *   | PN0 | PN1 | rsvd | rsvd/key | PN2 | PN3 | PN4 | PN5 |
+	 *   +-----+-----+------+----------+-----+-----+-----+-----+
+	 *                   CCMP Header Format
+	 */
+
+	/* Extract individual bytes */
+	pn[0] = (uint8_t) *ccmp_ptr;
+	pn[1] = (uint8_t) *(ccmp_ptr + 1);
+	rsvd = (uint8_t) *(ccmp_ptr + 2);
+	key = (uint8_t) *(ccmp_ptr + 3);
+	pn[2] = (uint8_t) *(ccmp_ptr + 4);
+	pn[3] = (uint8_t) *(ccmp_ptr + 5);
+	pn[4] = (uint8_t) *(ccmp_ptr + 6);
+	pn[5] = (uint8_t) *(ccmp_ptr + 7);
+
+	/* Form 6 byte PN with 6 individual bytes of PN */
+	new_pn = ((uint64_t) pn[5] << 40) |
+		 ((uint64_t) pn[4] << 32) |
+		 ((uint64_t) pn[3] << 24) |
+		 ((uint64_t) pn[2] << 16) |
+		 ((uint64_t) pn[1] << 8) | ((uint64_t) pn[0] << 0);
+
+	WMA_LOGE("PN of received packet is %llu", new_pn);
+	return new_pn;
+}
+
+/**
+ * wma_is_ccmp_pn_replay_attack() - detect replay attacking using PN in CCMP
+ * @cds_ctx: cds context
+ * @wh: 802.11 frame header
+ * @ccmp_ptr: CCMP frame header
+ *
+ * Return: true/false
+ */
+static bool
+wma_is_ccmp_pn_replay_attack(void *cds_ctx, struct ieee80211_frame *wh,
+			 uint8_t *ccmp_ptr)
+{
+	struct cdp_pdev *pdev;
+	struct cdp_vdev *vdev;
+	void *peer;
+	uint8_t vdev_id, peer_id;
+	uint8_t *last_pn_valid = NULL;
+	uint64_t *last_pn = NULL, new_pn;
+	uint32_t *rmf_pn_replays = NULL;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	bool ret = false;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE("%s: Failed to find pdev", __func__);
+		return true;
+	}
+
+	vdev = wma_find_vdev_by_bssid(cds_ctx, wh->i_addr3, &vdev_id);
+	if (!vdev) {
+		WMA_LOGE("%s: Failed to find vdev", __func__);
+		return true;
+	}
+
+	/* Retrieve the peer based on vdev and addr */
+	peer = cdp_peer_get_ref_by_addr(soc, pdev, wh->i_addr2, &peer_id,
+					PEER_DEBUG_ID_WMA_CCMP_REPLAY_ATTACK);
+
+	if (!peer) {
+		WMA_LOGE("%s: Failed to find peer, Not able to validate PN",
+			    __func__);
+		return true;
+	}
+
+	new_pn = wma_extract_ccmp_pn(ccmp_ptr);
+
+	cdp_get_pn_info(soc, peer, &last_pn_valid, &last_pn, &rmf_pn_replays);
+
+	if (!last_pn_valid || !last_pn || !rmf_pn_replays) {
+		WMA_LOGE("%s: PN validation seems not supported", __func__);
+		goto rel_peer_ref;
+	}
+
+	if (*last_pn_valid) {
+		if (new_pn > *last_pn) {
+			*last_pn = new_pn;
+			WMA_LOGE("%s: PN validation successful", __func__);
+		} else {
+			WMA_LOGE("%s: PN Replay attack detected", __func__);
+			/* per 11W amendment, keeping track of replay attacks */
+			*rmf_pn_replays += 1;
+			ret = true;
+		}
+	} else {
+		*last_pn_valid = 1;
+		*last_pn = new_pn;
+	}
+
+rel_peer_ref:
+	cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_CCMP_REPLAY_ATTACK);
+	return ret;
+}
+
+/**
+ * wma_process_bip() - process mmie in rmf frame
+ * @wma_handle: wma handle
+ * @iface: txrx node
+ * @wh: 80211 frame
+ * @wbuf: Buffer
+ *
+ * Return: 0 for success or error code
+ */
+
+static
+int wma_process_bip(tp_wma_handle wma_handle,
+	struct wma_txrx_node *iface,
+	struct ieee80211_frame *wh,
+	qdf_nbuf_t wbuf
+)
+{
+	uint16_t mmie_size;
+	uint16_t key_id;
+	uint8_t *efrm;
+
+	efrm = qdf_nbuf_data(wbuf) + qdf_nbuf_len(wbuf);
+
+	if (iface->key.key_cipher == WMI_CIPHER_AES_CMAC) {
+		mmie_size = cds_get_mmie_size();
+	} else if (iface->key.key_cipher == WMI_CIPHER_AES_GMAC) {
+		mmie_size = cds_get_gmac_mmie_size();
+	} else {
+		WMA_LOGE(FL("Invalid key cipher %d"), iface->key.key_cipher);
+		return -EINVAL;
+	}
+
+	/* Check if frame is invalid length */
+	if (efrm - (uint8_t *)wh < sizeof(*wh) + mmie_size) {
+		WMA_LOGE(FL("Invalid frame length"));
+		return -EINVAL;
+	}
+
+	key_id = (uint16_t)*(efrm - mmie_size + 2);
+	if (!((key_id == WMA_IGTK_KEY_INDEX_4)
+	     || (key_id == WMA_IGTK_KEY_INDEX_5))) {
+		WMA_LOGE(FL("Invalid KeyID(%d) dropping the frame"), key_id);
+		return -EINVAL;
+	}
+
+	WMA_LOGD(FL("key_cipher %d key_id %d"), iface->key.key_cipher, key_id);
+
+	switch (iface->key.key_cipher) {
+	case WMI_CIPHER_AES_CMAC:
+		if (wmi_service_enabled(wma_handle->wmi_handle,
+				wmi_service_sta_pmf_offload)) {
+			/*
+			 * if 11w offload is enabled then mmie validation is
+			 * performed in firmware, host just need to trim the
+			 * mmie.
+			 */
+			qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size());
+		} else {
+			if (cds_is_mmie_valid(iface->key.key,
+			   iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn,
+			   (uint8_t *) wh, efrm)) {
+				WMA_LOGD(FL("Protected BC/MC frame MMIE validation successful"));
+				/* Remove MMIE */
+				qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size());
+			} else {
+				WMA_LOGD(FL("BC/MC MIC error or MMIE not present, dropping the frame"));
+				return -EINVAL;
+			}
+		}
+		break;
+
+	case WMI_CIPHER_AES_GMAC:
+		if (wmi_service_enabled(wma_handle->wmi_handle,
+				wmi_service_gmac_offload_support)) {
+			/*
+			 * if gmac offload is enabled then mmie validation is
+			 * performed in firmware, host just need to trim the
+			 * mmie.
+			 */
+			WMA_LOGD(FL("Trim GMAC MMIE"));
+			qdf_nbuf_trim_tail(wbuf, cds_get_gmac_mmie_size());
+		} else {
+			if (cds_is_gmac_mmie_valid(iface->key.key,
+			   iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn,
+			   (uint8_t *) wh, efrm, iface->key.key_length)) {
+				WMA_LOGD(FL("Protected BC/MC frame GMAC MMIE validation successful"));
+				/* Remove MMIE */
+				qdf_nbuf_trim_tail(wbuf,
+						   cds_get_gmac_mmie_size());
+			} else {
+				WMA_LOGD(FL("BC/MC GMAC MIC error or MMIE not present, dropping the frame"));
+				return -EINVAL;
+			}
+		}
+		break;
+
+	default:
+		WMA_LOGE(FL("Unsupported key cipher %d"),
+			iface->key.key_cipher);
+	}
+
+
+	return 0;
+}
+
+/**
+ * wma_process_rmf_frame() - process rmf frame
+ * @wma_handle: wma handle
+ * @iface: txrx node
+ * @wh: 80211 frame
+ * @rx_pkt: rx packet
+ * @wbuf: Buffer
+ *
+ * Return: 0 for success or error code
+ */
+static
+int wma_process_rmf_frame(tp_wma_handle wma_handle,
+	struct wma_txrx_node *iface,
+	struct ieee80211_frame *wh,
+	cds_pkt_t *rx_pkt,
+	qdf_nbuf_t wbuf)
+{
+	uint8_t *orig_hdr;
+	uint8_t *ccmp;
+	uint8_t mic_len, hdr_len;
+
+	if ((wh)->i_fc[1] & IEEE80211_FC1_WEP) {
+		if (IEEE80211_IS_BROADCAST(wh->i_addr1) ||
+		    IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+			WMA_LOGE("Encrypted BC/MC frame dropping the frame");
+			cds_pkt_return_packet(rx_pkt);
+			return -EINVAL;
+		}
+	if (iface->ucast_key_cipher == WMI_CIPHER_AES_GCM) {
+		hdr_len = WLAN_IEEE80211_GCMP_HEADERLEN;
+		mic_len = WLAN_IEEE80211_GCMP_MICLEN;
+	} else {
+		hdr_len = IEEE80211_CCMP_HEADERLEN;
+		mic_len = IEEE80211_CCMP_MICLEN;
+	}
+	if (qdf_nbuf_len(wbuf) < (sizeof(*wh) + hdr_len + mic_len)) {
+		WMA_LOGE("Buffer length less than expected %d",
+					(int)qdf_nbuf_len(wbuf));
+		cds_pkt_return_packet(rx_pkt);
+		return -EINVAL;
+	}
+
+		orig_hdr = (uint8_t *) qdf_nbuf_data(wbuf);
+		/* Pointer to head of CCMP header */
+		ccmp = orig_hdr + sizeof(*wh);
+		if (wma_is_ccmp_pn_replay_attack(
+			wma_handle, wh, ccmp)) {
+			WMA_LOGE("Dropping the frame");
+			cds_pkt_return_packet(rx_pkt);
+			return -EINVAL;
+		}
+
+		/* Strip privacy headers (and trailer)
+		 * for a received frame
+		 */
+		qdf_mem_move(orig_hdr +
+			hdr_len, wh,
+			sizeof(*wh));
+		qdf_nbuf_pull_head(wbuf,
+			hdr_len);
+		qdf_nbuf_trim_tail(wbuf, mic_len);
+		/*
+		 * CCMP header has been pulled off
+		 * reinitialize the start pointer of mac header
+		 * to avoid accessing incorrect address
+		 */
+		wh = (struct ieee80211_frame *) qdf_nbuf_data(wbuf);
+		rx_pkt->pkt_meta.mpdu_hdr_ptr =
+				qdf_nbuf_data(wbuf);
+		rx_pkt->pkt_meta.mpdu_len = qdf_nbuf_len(wbuf);
+		rx_pkt->pkt_buf = wbuf;
+		if (rx_pkt->pkt_meta.mpdu_len >=
+			rx_pkt->pkt_meta.mpdu_hdr_len) {
+			rx_pkt->pkt_meta.mpdu_data_len =
+				rx_pkt->pkt_meta.mpdu_len -
+				rx_pkt->pkt_meta.mpdu_hdr_len;
+		} else {
+			WMA_LOGE("mpdu len %d less than hdr %d, dropping frame",
+				rx_pkt->pkt_meta.mpdu_len,
+				rx_pkt->pkt_meta.mpdu_hdr_len);
+			cds_pkt_return_packet(rx_pkt);
+			return -EINVAL;
+		}
+
+		if (rx_pkt->pkt_meta.mpdu_data_len > WMA_MAX_MGMT_MPDU_LEN) {
+			WMA_LOGE("Data Len %d greater than max, dropping frame",
+				rx_pkt->pkt_meta.mpdu_data_len);
+			cds_pkt_return_packet(rx_pkt);
+			return -EINVAL;
+		}
+		rx_pkt->pkt_meta.mpdu_data_ptr =
+		rx_pkt->pkt_meta.mpdu_hdr_ptr +
+		rx_pkt->pkt_meta.mpdu_hdr_len;
+		WMA_LOGD(FL("BSSID: "MAC_ADDRESS_STR" tsf_delta: %u"),
+		    MAC_ADDR_ARRAY(wh->i_addr3), rx_pkt->pkt_meta.tsf_delta);
+	} else {
+		if (IEEE80211_IS_BROADCAST(wh->i_addr1) ||
+		    IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+			if (0 != wma_process_bip(wma_handle, iface, wh, wbuf)) {
+				cds_pkt_return_packet(rx_pkt);
+				return -EINVAL;
+			}
+		} else {
+			WMA_LOGE("Rx unprotected unicast mgmt frame");
+			rx_pkt->pkt_meta.dpuFeedback =
+				DPU_FEEDBACK_UNPROTECTED_ERROR;
+		}
+	}
+	return 0;
+}
+#else
+static inline int wma_process_rmf_frame(tp_wma_handle wma_handle,
+	struct wma_txrx_node *iface,
+	struct ieee80211_frame *wh,
+	cds_pkt_t *rx_pkt,
+	qdf_nbuf_t wbuf)
+{
+	return 0;
+}
+
+#endif
+
+/**
+ * wma_is_pkt_drop_candidate() - check if the mgmt frame should be droppped
+ * @wma_handle: wma handle
+ * @peer_addr: peer MAC address
+ * @bssid: BSSID Address
+ * @subtype: Management frame subtype
+ *
+ * This function is used to decide if a particular management frame should be
+ * dropped to prevent DOS attack. Timestamp is used to decide the DOS attack.
+ *
+ * Return: true if the packet should be dropped and false oterwise
+ */
+static bool wma_is_pkt_drop_candidate(tp_wma_handle wma_handle,
+				      uint8_t *peer_addr, uint8_t *bssid,
+				      uint8_t subtype)
+{
+	bool should_drop = false;
+	uint8_t nan_addr[] = {0x50, 0x6F, 0x9A, 0x01, 0x00, 0x00};
+
+	/* Drop the beacons from NAN device */
+	if ((subtype == IEEE80211_FC0_SUBTYPE_BEACON) &&
+		(!qdf_mem_cmp(nan_addr, bssid, NAN_CLUSTER_ID_BYTES))) {
+			should_drop = true;
+			goto end;
+	}
+end:
+	return should_drop;
+}
+
+#define RATE_LIMIT 16
+
+int wma_form_rx_packet(qdf_nbuf_t buf,
+			struct mgmt_rx_event_params *mgmt_rx_params,
+			cds_pkt_t *rx_pkt)
+{
+	struct wma_txrx_node *iface = NULL;
+	uint8_t vdev_id = WMA_INVALID_VDEV_ID;
+	struct ieee80211_frame *wh;
+	uint8_t mgt_type, mgt_subtype;
+	int status;
+	tp_wma_handle wma_handle = (tp_wma_handle)
+				cds_get_context(QDF_MODULE_ID_WMA);
+	tp_wma_packetdump_cb packetdump_cb;
+	static uint8_t limit_prints_invalid_len = RATE_LIMIT - 1;
+	static uint8_t limit_prints_load_unload = RATE_LIMIT - 1;
+	static uint8_t limit_prints_recovery = RATE_LIMIT - 1;
+
+	if (!wma_handle) {
+		WMA_LOGE(FL("wma handle is NULL"));
+		qdf_nbuf_free(buf);
+		qdf_mem_free(rx_pkt);
+		return -EINVAL;
+	}
+
+	if (!mgmt_rx_params) {
+		limit_prints_invalid_len++;
+		if (limit_prints_invalid_len == RATE_LIMIT) {
+			WMA_LOGD(FL("mgmt rx params is NULL"));
+			limit_prints_invalid_len = 0;
+		}
+		qdf_nbuf_free(buf);
+		qdf_mem_free(rx_pkt);
+		return -EINVAL;
+	}
+
+	if (cds_is_load_or_unload_in_progress()) {
+		limit_prints_load_unload++;
+		if (limit_prints_load_unload == RATE_LIMIT) {
+			WMA_LOGD(FL("Load/Unload in progress"));
+			limit_prints_load_unload = 0;
+		}
+		qdf_nbuf_free(buf);
+		qdf_mem_free(rx_pkt);
+		return -EINVAL;
+	}
+
+	if (cds_is_driver_recovering()) {
+		limit_prints_recovery++;
+		if (limit_prints_recovery == RATE_LIMIT) {
+			WMA_LOGD(FL("Recovery in progress"));
+			limit_prints_recovery = 0;
+		}
+		qdf_nbuf_free(buf);
+		qdf_mem_free(rx_pkt);
+		return -EINVAL;
+	}
+
+	if (cds_is_driver_in_bad_state()) {
+		limit_prints_recovery++;
+		if (limit_prints_recovery == RATE_LIMIT) {
+			WMA_LOGD(FL("Driver in bad state"));
+			limit_prints_recovery = 0;
+		}
+		qdf_nbuf_free(buf);
+		qdf_mem_free(rx_pkt);
+		return -EINVAL;
+	}
+
+	/*
+	 * Fill in meta information needed by pe/lim
+	 * TODO: Try to maintain rx metainfo as part of skb->data.
+	 */
+	rx_pkt->pkt_meta.channel = mgmt_rx_params->channel;
+	rx_pkt->pkt_meta.scan_src = mgmt_rx_params->flags;
+
+	/*
+	 * Get the rssi value from the current snr value
+	 * using standard noise floor of -96.
+	 */
+	rx_pkt->pkt_meta.rssi = mgmt_rx_params->snr +
+				WMA_NOISE_FLOOR_DBM_DEFAULT;
+	rx_pkt->pkt_meta.snr = mgmt_rx_params->snr;
+
+	/* If absolute rssi is available from firmware, use it */
+	if (mgmt_rx_params->rssi != 0)
+		rx_pkt->pkt_meta.rssi_raw = mgmt_rx_params->rssi;
+	else
+		rx_pkt->pkt_meta.rssi_raw = rx_pkt->pkt_meta.rssi;
+
+
+	/*
+	 * FIXME: Assigning the local timestamp as hw timestamp is not
+	 * available. Need to see if pe/lim really uses this data.
+	 */
+	rx_pkt->pkt_meta.timestamp = (uint32_t) jiffies;
+	rx_pkt->pkt_meta.mpdu_hdr_len = sizeof(struct ieee80211_frame);
+	rx_pkt->pkt_meta.mpdu_len = mgmt_rx_params->buf_len;
+
+	/*
+	 * The buf_len should be at least 802.11 header len
+	 */
+	if (mgmt_rx_params->buf_len < rx_pkt->pkt_meta.mpdu_hdr_len) {
+		WMA_LOGE("MPDU Len %d lesser than header len %d",
+			 mgmt_rx_params->buf_len,
+			 rx_pkt->pkt_meta.mpdu_hdr_len);
+		qdf_nbuf_free(buf);
+		qdf_mem_free(rx_pkt);
+		return -EINVAL;
+	}
+
+	rx_pkt->pkt_meta.mpdu_data_len = mgmt_rx_params->buf_len -
+					 rx_pkt->pkt_meta.mpdu_hdr_len;
+
+	rx_pkt->pkt_meta.roamCandidateInd = 0;
+
+	wh = (struct ieee80211_frame *)qdf_nbuf_data(buf);
+
+	/*
+	 * If the mpdu_data_len is greater than Max (2k), drop the frame
+	 */
+	if (rx_pkt->pkt_meta.mpdu_data_len > WMA_MAX_MGMT_MPDU_LEN) {
+		WMA_LOGE("Data Len %d greater than max, dropping frame from "MAC_ADDRESS_STR,
+			 rx_pkt->pkt_meta.mpdu_data_len,
+			 MAC_ADDR_ARRAY(wh->i_addr3));
+		qdf_nbuf_free(buf);
+		qdf_mem_free(rx_pkt);
+		return -EINVAL;
+	}
+
+	rx_pkt->pkt_meta.mpdu_hdr_ptr = qdf_nbuf_data(buf);
+	rx_pkt->pkt_meta.mpdu_data_ptr = rx_pkt->pkt_meta.mpdu_hdr_ptr +
+					 rx_pkt->pkt_meta.mpdu_hdr_len;
+	rx_pkt->pkt_meta.tsf_delta = mgmt_rx_params->tsf_delta;
+	rx_pkt->pkt_buf = buf;
+
+	/* If it is a beacon/probe response, save it for future use */
+	mgt_type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+	mgt_subtype = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+	WMA_LOGD(FL("BSSID: "MAC_ADDRESS_STR" snr = %d, Type = %x, Subtype = %x, seq_num = %u, rssi = %d, rssi_raw = %d tsf_delta: %u"),
+			MAC_ADDR_ARRAY(wh->i_addr3),
+			mgmt_rx_params->snr, mgt_type, mgt_subtype,
+			*(uint16_t *)wh->i_seq, rx_pkt->pkt_meta.rssi,
+			rx_pkt->pkt_meta.rssi_raw, mgmt_rx_params->tsf_delta);
+
+	if (mgt_type == IEEE80211_FC0_TYPE_MGT &&
+	    (mgt_subtype == IEEE80211_FC0_SUBTYPE_DISASSOC ||
+	     mgt_subtype == IEEE80211_FC0_SUBTYPE_DEAUTH ||
+	     mgt_subtype == IEEE80211_FC0_SUBTYPE_ACTION)) {
+		if (wma_find_vdev_by_bssid(
+			wma_handle, wh->i_addr3, &vdev_id)) {
+			iface = &(wma_handle->interfaces[vdev_id]);
+			if (iface->rmfEnabled) {
+				status = wma_process_rmf_frame(wma_handle,
+					iface, wh, rx_pkt, buf);
+				if (status != 0)
+					return status;
+				/*
+				 * CCMP header might have been pulled off
+				 * reinitialize the start pointer of mac header
+				 */
+				wh = (struct ieee80211_frame *)
+						qdf_nbuf_data(buf);
+			}
+		}
+	}
+
+	rx_pkt->pkt_meta.sessionId =
+		(vdev_id == WMA_INVALID_VDEV_ID ? 0 : vdev_id);
+
+	if (mgt_type == IEEE80211_FC0_TYPE_MGT &&
+	    (mgt_subtype == IEEE80211_FC0_SUBTYPE_BEACON ||
+	     mgt_subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) {
+		if (mgmt_rx_params->buf_len <=
+			(sizeof(struct ieee80211_frame) +
+			offsetof(struct wlan_bcn_frame, ie))) {
+			WMA_LOGD("Dropping frame from "MAC_ADDRESS_STR,
+				 MAC_ADDR_ARRAY(wh->i_addr3));
+			cds_pkt_return_packet(rx_pkt);
+			return -EINVAL;
+		}
+	}
+
+	if (wma_is_pkt_drop_candidate(wma_handle, wh->i_addr2, wh->i_addr3,
+					mgt_subtype)) {
+		cds_pkt_return_packet(rx_pkt);
+		return -EINVAL;
+	}
+
+	packetdump_cb = wma_handle->wma_mgmt_rx_packetdump_cb;
+	if ((mgt_type == IEEE80211_FC0_TYPE_MGT &&
+			mgt_subtype != IEEE80211_FC0_SUBTYPE_BEACON) &&
+			packetdump_cb)
+		packetdump_cb(rx_pkt->pkt_buf, QDF_STATUS_SUCCESS,
+			rx_pkt->pkt_meta.sessionId, RX_MGMT_PKT);
+
+	return 0;
+}
+
+/**
+ * wma_mem_endianness_based_copy() - does memory copy from src to dst
+ * @dst: destination address
+ * @src: source address
+ * @size: size to be copied
+ *
+ * This function copies the memory of size passed from source
+ * address to destination address.
+ *
+ * Return: Nothing
+ */
+#ifdef BIG_ENDIAN_HOST
+static void wma_mem_endianness_based_copy(
+			uint8_t *dst, uint8_t *src, uint32_t size)
+{
+	/*
+	 * For big endian host, copy engine byte_swap is enabled
+	 * But the rx mgmt frame buffer content is in network byte order
+	 * Need to byte swap the mgmt frame buffer content - so when
+	 * copy engine does byte_swap - host gets buffer content in the
+	 * correct byte order.
+	 */
+
+	uint32_t i;
+	uint32_t *destp, *srcp;
+
+	destp = (uint32_t *) dst;
+	srcp = (uint32_t *) src;
+	for (i = 0; i < (roundup(size, sizeof(uint32_t)) / 4); i++) {
+		*destp = cpu_to_le32(*srcp);
+		destp++;
+		srcp++;
+	}
+}
+#else
+static void wma_mem_endianness_based_copy(
+			uint8_t *dst, uint8_t *src, uint32_t size)
+{
+	qdf_mem_copy(dst, src, size);
+}
+#endif
+
+#define RESERVE_BYTES                   100
+/**
+ * wma_mgmt_rx_process() - process management rx frame.
+ * @handle: wma handle
+ * @data: rx data
+ * @data_len: data length
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_mgmt_rx_process(void *handle, uint8_t *data,
+				  uint32_t data_len)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	struct mgmt_rx_event_params *mgmt_rx_params;
+	struct wlan_objmgr_psoc *psoc;
+	uint8_t *bufp;
+	qdf_nbuf_t wbuf;
+	QDF_STATUS status;
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: Failed to get WMA  context", __func__);
+		return -EINVAL;
+	}
+
+	mgmt_rx_params = qdf_mem_malloc(sizeof(*mgmt_rx_params));
+	if (!mgmt_rx_params) {
+		WMA_LOGE("%s: memory allocation failed", __func__);
+		return -ENOMEM;
+	}
+
+	if (wmi_extract_mgmt_rx_params(wma_handle->wmi_handle,
+			data, mgmt_rx_params, &bufp) != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Extraction of mgmt rx params failed", __func__);
+		qdf_mem_free(mgmt_rx_params);
+		return -EINVAL;
+	}
+
+	if (mgmt_rx_params->buf_len > data_len) {
+		WMA_LOGE("%s: Invalid rx mgmt packet, data_len %u, mgmt_rx_params->buf_len %u",
+			__func__, data_len, mgmt_rx_params->buf_len);
+		qdf_mem_free(mgmt_rx_params);
+		return -EINVAL;
+	}
+
+	mgmt_rx_params->pdev_id = 0;
+	mgmt_rx_params->rx_params = NULL;
+
+	/*
+	 * Allocate the memory for this rx packet, add extra 100 bytes for:-
+	 *
+	 * 1.  Filling the missing RSN capabilites by some APs, which fill the
+	 *     RSN IE length as extra 2 bytes but dont fill the IE data with
+	 *     capabilities, resulting in failure in unpack core due to length
+	 *     mismatch. Check sir_validate_and_rectify_ies for more info.
+	 *
+	 * 2.  In the API wma_process_rmf_frame(), the driver trims the CCMP
+	 *     header by overwriting the IEEE header to memory occupied by CCMP
+	 *     header, but an overflow is possible if the memory allocated to
+	 *     frame is less than the sizeof(struct ieee80211_frame) +CCMP
+	 *     HEADER len, so allocating 100 bytes would solve this issue too.
+	 *
+	 * 3.  CCMP header is pointing to orig_hdr +
+	 *     sizeof(struct ieee80211_frame) which could also result in OOB
+	 *     access, if the data len is less than
+	 *     sizeof(struct ieee80211_frame), allocating extra bytes would
+	 *     result in solving this issue too.
+	 */
+	wbuf = qdf_nbuf_alloc(NULL, roundup(mgmt_rx_params->buf_len +
+							RESERVE_BYTES,
+							4), 0, 4, false);
+	if (!wbuf) {
+		qdf_mem_free(mgmt_rx_params);
+		return -ENOMEM;
+	}
+
+	qdf_nbuf_put_tail(wbuf, mgmt_rx_params->buf_len);
+	qdf_nbuf_set_protocol(wbuf, ETH_P_CONTROL);
+
+	qdf_mem_zero(((uint8_t *)qdf_nbuf_data(wbuf) + mgmt_rx_params->buf_len),
+		     (roundup(mgmt_rx_params->buf_len + RESERVE_BYTES, 4) -
+		     mgmt_rx_params->buf_len));
+
+	wma_mem_endianness_based_copy(qdf_nbuf_data(wbuf),
+			bufp, mgmt_rx_params->buf_len);
+
+	psoc = (struct wlan_objmgr_psoc *)
+				wma_handle->psoc;
+	if (!psoc) {
+		WMA_LOGE("%s: psoc ctx is NULL", __func__);
+		qdf_nbuf_free(wbuf);
+		qdf_mem_free(mgmt_rx_params);
+		return -EINVAL;
+	}
+
+	status = mgmt_txrx_rx_handler(psoc, wbuf, mgmt_rx_params);
+	if (status != QDF_STATUS_SUCCESS) {
+		wma_err_rl("Failed to process mgmt rx frame");
+		qdf_mem_free(mgmt_rx_params);
+		return -EINVAL;
+	}
+
+	qdf_mem_free(mgmt_rx_params);
+	return 0;
+}
+
+/**
+ * wma_de_register_mgmt_frm_client() - deregister management frame
+ *
+ * This function deregisters the event handler registered for
+ * WMI_MGMT_RX_EVENTID.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_de_register_mgmt_frm_client(void)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle)
+				cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: Failed to get WMA context", __func__);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+#ifdef QCA_WIFI_FTM
+	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE)
+		return QDF_STATUS_SUCCESS;
+#endif
+
+	if (wmi_unified_unregister_event_handler(wma_handle->wmi_handle,
+						 wmi_mgmt_rx_event_id) != 0) {
+		WMA_LOGE("Failed to Unregister rx mgmt handler with wmi");
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * wma_register_roaming_callbacks() - Register roaming callbacks
+ * @csr_roam_synch_cb: CSR roam synch callback routine pointer
+ * @pe_roam_synch_cb: PE roam synch callback routine pointer
+ *
+ * Register the SME and PE callback routines with WMA for
+ * handling roaming
+ *
+ * Return: Success or Failure Status
+ */
+QDF_STATUS wma_register_roaming_callbacks(
+	QDF_STATUS (*csr_roam_synch_cb)(tpAniSirGlobal mac,
+		roam_offload_synch_ind *roam_synch_data,
+		tpSirBssDescription  bss_desc_ptr,
+		enum sir_roam_op_code reason),
+	QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac,
+		roam_offload_synch_ind *roam_synch_data,
+		tpSirBssDescription  bss_desc_ptr,
+		enum sir_roam_op_code reason))
+{
+
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma) {
+		WMA_LOGE("%s: Failed to get WMA context", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	wma->csr_roam_synch_cb = csr_roam_synch_cb;
+	wma->pe_roam_synch_cb = pe_roam_synch_cb;
+	WMA_LOGD("Registered roam synch callbacks with WMA successfully");
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * wma_register_mgmt_frm_client() - register management frame callback
+ *
+ * This function registers event handler for WMI_MGMT_RX_EVENTID.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_register_mgmt_frm_client(void)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle)
+				cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		WMA_LOGE("%s: Failed to get WMA context", __func__);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					       wmi_mgmt_rx_event_id,
+					       wma_mgmt_rx_process,
+					       WMA_RX_WORK_CTX) != 0) {
+		WMA_LOGE("Failed to register rx mgmt handler with wmi");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_register_packetdump_callback() - stores tx and rx mgmt packet dump
+ *   callback handler
+ * @wma_mgmt_tx_packetdump_cb: tx mgmt packetdump cb
+ * @wma_mgmt_rx_packetdump_cb: rx mgmt packetdump cb
+ *
+ * This function is used to store tx and rx mgmt. packet dump callback
+ *
+ * Return: None
+ *
+ */
+void wma_register_packetdump_callback(
+	tp_wma_packetdump_cb wma_mgmt_tx_packetdump_cb,
+	tp_wma_packetdump_cb wma_mgmt_rx_packetdump_cb)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		WMA_LOGE("wma handle is NULL");
+		return;
+	}
+
+	wma_handle->wma_mgmt_tx_packetdump_cb = wma_mgmt_tx_packetdump_cb;
+	wma_handle->wma_mgmt_rx_packetdump_cb = wma_mgmt_rx_packetdump_cb;
+}
+
+/**
+ * wma_deregister_packetdump_callback() - removes tx and rx mgmt packet dump
+ *   callback handler
+ *
+ * This function is used to remove tx and rx mgmt. packet dump callback
+ *
+ * Return: None
+ *
+ */
+void wma_deregister_packetdump_callback(void)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma_handle) {
+		WMA_LOGE("wma handle is NULL");
+		return;
+	}
+
+	wma_handle->wma_mgmt_tx_packetdump_cb = NULL;
+	wma_handle->wma_mgmt_rx_packetdump_cb = NULL;
+}
+
+QDF_STATUS wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev *vdev,
+				qdf_nbuf_t buf, uint32_t desc_id,
+				void *mgmt_tx_params)
+{
+	tp_wma_handle wma_handle;
+	int ret;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	struct wmi_mgmt_params *mgmt_params =
+			(struct wmi_mgmt_params *)mgmt_tx_params;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct cdp_vdev *txrx_vdev;
+
+	if (!mgmt_params) {
+		WMA_LOGE("%s: mgmt_params ptr passed is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	mgmt_params->desc_id = desc_id;
+
+	if (!vdev) {
+		WMA_LOGE("%s: vdev ptr passed is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	txrx_vdev = wma_handle->interfaces[mgmt_params->vdev_id].handle;
+
+	if (wmi_service_enabled(wma_handle->wmi_handle,
+				   wmi_service_mgmt_tx_wmi)) {
+		status = wmi_mgmt_unified_cmd_send(wma_handle->wmi_handle,
+						   mgmt_params);
+	} else if (txrx_vdev) {
+		QDF_NBUF_CB_MGMT_TXRX_DESC_ID(buf)
+						= mgmt_params->desc_id;
+
+		ret = cdp_mgmt_send_ext(soc, txrx_vdev, buf,
+					mgmt_params->tx_type,
+					mgmt_params->use_6mbps,
+					mgmt_params->chanfreq);
+		status = qdf_status_from_os_return(ret);
+	}
+
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: mgmt tx failed", __func__);
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wma_mgmt_nbuf_unmap_cb(struct wlan_objmgr_pdev *pdev,
+			    qdf_nbuf_t buf)
+{
+	struct wlan_objmgr_psoc *psoc;
+	qdf_device_t dev;
+
+	if (!buf)
+		return;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc) {
+		WMA_LOGE("%s: Psoc handle NULL", __func__);
+		return;
+	}
+
+	dev = wlan_psoc_get_qdf_dev(psoc);
+	if (wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_WMI_MGMT_REF))
+		qdf_nbuf_unmap_single(dev, buf, QDF_DMA_TO_DEVICE);
+}
diff --git a/core/wma/src/wma_nan_datapath.c b/core/wma/src/wma_nan_datapath.c
new file mode 100644
index 0000000..e7143c1
--- /dev/null
+++ b/core/wma/src/wma_nan_datapath.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2016-2018 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: wma_nan_datapath.c
+ *
+ * WMA NAN Data path API implementation
+ */
+
+#include "wma.h"
+#include "wma_api.h"
+#include "wmi_unified_api.h"
+#include "wmi_unified.h"
+#include "wma_nan_datapath.h"
+#include "wma_internal.h"
+#include "cds_utils.h"
+#include "cdp_txrx_peer_ops.h"
+#include "cdp_txrx_tx_delay.h"
+#include "cdp_txrx_misc.h"
+#include <cdp_txrx_handle.h>
+
+/**
+ * wma_add_bss_ndi_mode() - Process BSS creation request while adding NaN
+ * Data interface
+ * @wma: wma handle
+ * @add_bss: Parameters for ADD_BSS command
+ *
+ * Sends VDEV_START command to firmware
+ * Return: None
+ */
+void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss)
+{
+	struct cdp_pdev *pdev;
+	struct cdp_vdev *vdev;
+	struct wma_vdev_start_req req;
+	void *peer = NULL;
+	struct wma_target_req *msg;
+	uint8_t vdev_id, peer_id;
+	QDF_STATUS status;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	WMA_LOGD("%s: enter", __func__);
+	vdev = wma_find_vdev_by_addr(wma, add_bss->bssId, &vdev_id);
+	if (!vdev) {
+		WMA_LOGE("%s: Failed to find vdev", __func__);
+		goto send_fail_resp;
+	}
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (!pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		goto send_fail_resp;
+	}
+
+	wma_set_bss_rate_flags(wma, vdev_id, add_bss);
+
+	status = wma_create_peer(wma, pdev, vdev, add_bss->selfMacAddr,
+				 WMI_PEER_TYPE_DEFAULT, vdev_id, false);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("%s: Failed to create peer", __func__);
+		goto send_fail_resp;
+	}
+
+	peer = cdp_peer_find_by_addr(soc, pdev, add_bss->selfMacAddr, &peer_id);
+	if (!peer) {
+		WMA_LOGE("%s Failed to find peer %pM", __func__,
+			 add_bss->selfMacAddr);
+		goto send_fail_resp;
+	}
+
+	msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ,
+			WMA_TARGET_REQ_TYPE_VDEV_START, add_bss,
+			WMA_VDEV_START_REQUEST_TIMEOUT);
+	if (!msg) {
+		WMA_LOGE("%s Failed to allocate vdev request vdev_id %d",
+			 __func__, vdev_id);
+		goto send_fail_resp;
+	}
+
+	add_bss->staContext.staIdx = cdp_peer_get_local_peer_id(soc, peer);
+
+	/*
+	 * beacon_intval, dtim_period, hidden_ssid, is_dfs, ssid
+	 * will be ignored for NDI device.
+	 */
+	qdf_mem_zero(&req, sizeof(req));
+	req.vdev_id = vdev_id;
+	req.chan = add_bss->currentOperChannel;
+	req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0;
+	req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1;
+	req.vht_capable = add_bss->vhtCapable;
+	req.max_txpow = add_bss->maxTxPower;
+	req.oper_mode = add_bss->operMode;
+
+	status = wma_vdev_start(wma, &req, false);
+	if (status != QDF_STATUS_SUCCESS) {
+		wma_remove_vdev_req(wma, vdev_id,
+			WMA_TARGET_REQ_TYPE_VDEV_START);
+		goto send_fail_resp;
+	}
+	WMA_LOGD("%s: vdev start request for NDI sent to target", __func__);
+
+	/* Initialize protection mode to no protection */
+	wma_vdev_set_param(wma->wmi_handle, vdev_id,
+		WMI_VDEV_PARAM_PROTECTION_MODE, IEEE80211_PROT_NONE);
+
+	return;
+
+send_fail_resp:
+	add_bss->status = QDF_STATUS_E_FAILURE;
+	wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
+}
+
+/**
+ * wma_add_sta_ndi_mode() - Process ADD_STA for NaN Data path
+ * @wma: wma handle
+ * @add_sta: Parameters of ADD_STA command
+ *
+ * Sends CREATE_PEER command to firmware
+ * Return: void
+ */
+void wma_add_sta_ndi_mode(tp_wma_handle wma, tpAddStaParams add_sta)
+{
+	enum ol_txrx_peer_state state = OL_TXRX_PEER_STATE_CONN;
+	struct cdp_pdev *pdev;
+	struct cdp_vdev *vdev;
+	void *peer;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	u_int8_t peer_id;
+	QDF_STATUS status;
+	struct wma_txrx_node *iface;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+	if (NULL == pdev) {
+		WMA_LOGE(FL("Failed to find pdev"));
+		add_sta->status = QDF_STATUS_E_FAILURE;
+		goto send_rsp;
+	}
+
+	vdev = wma_find_vdev_by_id(wma, add_sta->smesessionId);
+	if (!vdev) {
+		WMA_LOGE(FL("Failed to find vdev"));
+		add_sta->status = QDF_STATUS_E_FAILURE;
+		goto send_rsp;
+	}
+
+	iface = &wma->interfaces[cdp_get_vdev_id(soc, vdev)];
+	WMA_LOGD(FL("vdev: %d, peer_mac_addr: "MAC_ADDRESS_STR),
+		add_sta->smesessionId, MAC_ADDR_ARRAY(add_sta->staMac));
+
+	peer = cdp_peer_find_by_addr_and_vdev(soc,
+			pdev, vdev,
+			add_sta->staMac, &peer_id);
+	if (peer) {
+		WMA_LOGE(FL("NDI peer already exists, peer_addr %pM"),
+			 add_sta->staMac);
+		add_sta->status = QDF_STATUS_E_EXISTS;
+		goto send_rsp;
+	}
+
+	/*
+	 * The code above only checks the peer existence on its own vdev.
+	 * Need to check whether the peer exists on other vDevs because firmware
+	 * can't create the peer if the peer with same MAC address already
+	 * exists on the pDev. As this peer belongs to other vDevs, just return
+	 * here.
+	 */
+	peer = cdp_peer_find_by_addr(soc,
+			pdev,
+			add_sta->staMac, &peer_id);
+	if (peer) {
+		WMA_LOGE(FL("vdev:%d, peer exists on other vdev with peer_addr %pM and peer_id %d"),
+			cdp_get_vdev_id(soc, vdev),
+			add_sta->staMac, peer_id);
+		add_sta->status = QDF_STATUS_E_EXISTS;
+		goto send_rsp;
+	}
+
+	status = wma_create_peer(wma, pdev, vdev, add_sta->staMac,
+				 WMI_PEER_TYPE_NAN_DATA, add_sta->smesessionId,
+				 false);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE(FL("Failed to create peer for %pM"), add_sta->staMac);
+		add_sta->status = status;
+		goto send_rsp;
+	}
+
+	peer = cdp_peer_find_by_addr_and_vdev(soc,
+			pdev, vdev,
+			add_sta->staMac, &peer_id);
+	if (!peer) {
+		WMA_LOGE(FL("Failed to find peer handle using peer mac %pM"),
+			 add_sta->staMac);
+		add_sta->status = QDF_STATUS_E_FAILURE;
+		wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
+				peer, false);
+		goto send_rsp;
+	}
+
+	WMA_LOGD(FL("Moving peer %pM to state %d"), add_sta->staMac, state);
+	cdp_peer_state_update(soc, pdev, add_sta->staMac, state);
+
+	add_sta->staIdx = cdp_peer_get_local_peer_id(soc, peer);
+	add_sta->nss    = iface->nss;
+	add_sta->status = QDF_STATUS_SUCCESS;
+send_rsp:
+	WMA_LOGD(FL("Sending add sta rsp to umac (mac:%pM, status:%d)"),
+		 add_sta->staMac, add_sta->status);
+	wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0);
+}
+
+/**
+ * wma_delete_sta_req_ndi_mode() - Process DEL_STA request for NDI data peer
+ * @wma: WMA context
+ * @del_sta: DEL_STA parameters from LIM
+ *
+ * Removes wma/txrx peer entry for the NDI STA
+ *
+ * Return: None
+ */
+void wma_delete_sta_req_ndi_mode(tp_wma_handle wma,
+					tpDeleteStaParams del_sta)
+{
+	struct cdp_pdev *pdev;
+	void *peer;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		WMA_LOGE(FL("Failed to get pdev"));
+		del_sta->status = QDF_STATUS_E_FAILURE;
+		goto send_del_rsp;
+	}
+
+	peer = cdp_peer_find_by_local_id(cds_get_context(QDF_MODULE_ID_SOC),
+			pdev, del_sta->staIdx);
+	if (!peer) {
+		WMA_LOGE(FL("Failed to get peer handle using peer id %d"),
+			 del_sta->staIdx);
+		del_sta->status = QDF_STATUS_E_FAILURE;
+		goto send_del_rsp;
+	}
+
+	wma_remove_peer(wma, cdp_peer_get_peer_mac_addr(soc, peer),
+			del_sta->smesessionId, peer, false);
+	del_sta->status = QDF_STATUS_SUCCESS;
+
+send_del_rsp:
+	if (del_sta->respReqd) {
+		WMA_LOGD(FL("Sending del rsp to umac (status: %d)"),
+				del_sta->status);
+		wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP, del_sta, 0);
+	} else {
+		WMA_LOGD(FL("NDI Del Sta resp not needed"));
+		qdf_mem_free(del_sta);
+	}
+
+}
diff --git a/core/wma/src/wma_nan_datapath.h b/core/wma/src/wma_nan_datapath.h
new file mode 100644
index 0000000..95394fb
--- /dev/null
+++ b/core/wma/src/wma_nan_datapath.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016-2018 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: wma_nan_datapath.h
+ *
+ * WMA NAN Data path API specification
+ */
+
+#ifndef __WMA_NAN_DATAPATH_H
+#define __WMA_NAN_DATAPATH_H
+
+#include <sir_common.h>
+#include <ani_global.h>
+#include "wma.h"
+#include "sir_api.h"
+#include "sme_nan_datapath.h"
+
+static inline int wma_ndp_wow_event_callback(void *handle, void *event,
+					     uint32_t len, uint32_t event_id)
+{
+	return 0;
+}
+
+static inline uint32_t wma_ndp_get_eventid_from_tlvtag(uint32_t tag)
+{
+	return 0;
+}
+
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+#define WMA_IS_VDEV_IN_NDI_MODE(intf, vdev_id) \
+				(WMI_VDEV_TYPE_NDI == intf[vdev_id].type)
+
+void wma_add_sta_ndi_mode(tp_wma_handle wma, tpAddStaParams add_sta);
+
+/**
+ * wma_update_hdd_cfg_ndp() - Update target device NAN datapath capability
+ * @wma_handle: pointer to WMA context
+ * @tgt_cfg: Pointer to target configuration data structure
+ *
+ * Return: none
+ */
+static inline void wma_update_hdd_cfg_ndp(tp_wma_handle wma_handle,
+					struct wma_tgt_cfg *tgt_cfg)
+{
+	tgt_cfg->nan_datapath_enabled = wma_handle->nan_datapath_enabled;
+}
+
+void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss);
+
+void wma_delete_sta_req_ndi_mode(tp_wma_handle wma,
+					tpDeleteStaParams del_sta);
+
+/**
+ * wma_is_ndi_active() - Determines of the nan data iface is active
+ * @wma_handle: handle to wma context
+ *
+ * Returns: true if ndi active, flase otherwise
+ */
+static inline bool wma_is_ndi_active(tp_wma_handle wma_handle)
+{
+	int i;
+
+	for (i = 0; i < wma_handle->max_bssid; i++) {
+		if (wma_handle->interfaces[i].type == WMI_VDEV_TYPE_NDI &&
+				wma_handle->interfaces[i].peer_count > 0)
+			return true;
+	}
+	return false;
+}
+#else
+#define WMA_IS_VDEV_IN_NDI_MODE(intf, vdev_id) (false)
+static inline void wma_update_hdd_cfg_ndp(tp_wma_handle wma_handle,
+					struct wma_tgt_cfg *tgt_cfg)
+{
+	return;
+}
+
+static inline void wma_add_bss_ndi_mode(tp_wma_handle wma,
+					tpAddBssParams add_bss)
+{
+	return;
+}
+
+static inline void wma_delete_sta_req_ndi_mode(tp_wma_handle wma,
+					tpDeleteStaParams del_sta)
+{
+}
+static inline void wma_add_sta_ndi_mode(tp_wma_handle wma,
+					tpAddStaParams add_sta) {}
+
+static inline bool wma_is_ndi_active(tp_wma_handle wma_handle) { return false; }
+#endif /* WLAN_FEATURE_NAN_DATAPATH */
+
+#endif /* __WMA_NAN_DATAPATH_H */
diff --git a/core/wma/src/wma_ocb.c b/core/wma/src/wma_ocb.c
new file mode 100644
index 0000000..64da7c2
--- /dev/null
+++ b/core/wma/src/wma_ocb.c
@@ -0,0 +1,809 @@
+/*
+ * Copyright (c) 2013-2018 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: wma_ocb.c
+ *
+ * WLAN Host Device Driver 802.11p OCB implementation
+ */
+
+#include "wma_ocb.h"
+#include "wmi_unified_api.h"
+#include "cds_utils.h"
+#include "cds_api.h"
+#include <cdp_txrx_ocb.h>
+#include <cdp_txrx_handle.h>
+#include "wlan_ocb_ucfg_api.h"
+
+/**
+ * wma_ocb_resp() - send the OCB set config response via callback
+ * @wma_handle: pointer to the WMA handle
+ * @status: status of the set config command
+ */
+int wma_ocb_set_config_resp(tp_wma_handle wma_handle, uint8_t status)
+{
+	QDF_STATUS qdf_status;
+	struct sir_ocb_set_config_response *resp;
+	struct scheduler_msg msg = {0};
+	struct sir_ocb_config *req = wma_handle->ocb_config_req;
+	void *vdev = (req ?
+		wma_handle->interfaces[req->session_id].handle : NULL);
+	struct ol_txrx_ocb_set_chan ocb_set_chan;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	/*
+	 * If the command was successful, save the channel information in the
+	 * vdev.
+	 */
+	if (status == QDF_STATUS_SUCCESS && vdev && req) {
+		ocb_set_chan.ocb_channel_info = cdp_get_ocb_chan_info(soc,
+						(struct cdp_vdev *)vdev);
+		if (ocb_set_chan.ocb_channel_info)
+			qdf_mem_free(ocb_set_chan.ocb_channel_info);
+		ocb_set_chan.ocb_channel_count =
+			req->channel_count;
+		if (req->channel_count) {
+			int i;
+			int buf_size = sizeof(*ocb_set_chan.ocb_channel_info) *
+			    req->channel_count;
+			ocb_set_chan.ocb_channel_info =
+				qdf_mem_malloc(buf_size);
+			if (!ocb_set_chan.ocb_channel_info)
+				return -ENOMEM;
+			qdf_mem_zero(ocb_set_chan.ocb_channel_info, buf_size);
+			for (i = 0; i < req->channel_count; i++) {
+				ocb_set_chan.ocb_channel_info[i].chan_freq =
+					req->channels[i].chan_freq;
+				if (req->channels[i].flags &
+					OCB_CHANNEL_FLAG_DISABLE_RX_STATS_HDR)
+					ocb_set_chan.ocb_channel_info[i].
+					disable_rx_stats_hdr = 1;
+			}
+		} else {
+			ocb_set_chan.ocb_channel_info = 0;
+			ocb_set_chan.ocb_channel_count = 0;
+		}
+		cdp_set_ocb_chan_info(soc,
+			(struct cdp_vdev *)vdev,
+			ocb_set_chan);
+	}
+
+	/* Free the configuration that was saved in wma_ocb_set_config. */
+	qdf_mem_free(wma_handle->ocb_config_req);
+	wma_handle->ocb_config_req = NULL;
+
+	resp = qdf_mem_malloc(sizeof(*resp));
+	if (!resp)
+		return -ENOMEM;
+
+	resp->status = status;
+
+	msg.type = eWNI_SME_OCB_SET_CONFIG_RSP;
+	msg.bodyptr = resp;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE(FL("Fail to post msg to SME"));
+		qdf_mem_free(resp);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * copy_sir_ocb_config() - deep copy of an OCB config struct
+ * @src: pointer to the source struct
+ *
+ * Return: pointer to the copied struct
+ */
+static struct sir_ocb_config *copy_sir_ocb_config(struct sir_ocb_config *src)
+{
+	struct sir_ocb_config *dst;
+	uint32_t length;
+	void *cursor;
+
+	length = sizeof(*src) +
+		src->channel_count * sizeof(*src->channels) +
+		src->schedule_size * sizeof(*src->schedule) +
+		src->dcc_ndl_chan_list_len +
+		src->dcc_ndl_active_state_list_len;
+
+	dst = qdf_mem_malloc(length);
+	if (!dst)
+		return NULL;
+
+	*dst = *src;
+
+	cursor = dst;
+	cursor += sizeof(*dst);
+	dst->channels = cursor;
+	cursor += src->channel_count * sizeof(*dst->channels);
+	qdf_mem_copy(dst->channels, src->channels,
+		     src->channel_count * sizeof(*dst->channels));
+	dst->schedule = cursor;
+	cursor += src->schedule_size * sizeof(*dst->schedule);
+	qdf_mem_copy(dst->schedule, src->schedule,
+		     src->schedule_size * sizeof(*dst->schedule));
+	dst->dcc_ndl_chan_list = cursor;
+	cursor += src->dcc_ndl_chan_list_len;
+	qdf_mem_copy(dst->dcc_ndl_chan_list, src->dcc_ndl_chan_list,
+		     src->dcc_ndl_chan_list_len);
+	dst->dcc_ndl_active_state_list = cursor;
+	cursor += src->dcc_ndl_active_state_list_len;
+	qdf_mem_copy(dst->dcc_ndl_active_state_list,
+		     src->dcc_ndl_active_state_list,
+		     src->dcc_ndl_active_state_list_len);
+	return dst;
+}
+
+/**
+ * wma_ocb_set_config_req() - send the OCB config request
+ * @wma_handle: pointer to the WMA handle
+ * @config_req: the configuration to be set.
+ */
+int wma_ocb_set_config_req(tp_wma_handle wma_handle,
+			   struct sir_ocb_config *config_req)
+{
+	struct wma_target_req *msg;
+	struct wma_vdev_start_req req;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	/* if vdev is not yet up, send vdev start request and wait for response.
+	 * OCB set_config request should be sent on receiving
+	 * vdev start response message
+	 */
+	if (!wma_is_vdev_up(config_req->session_id)) {
+		qdf_mem_zero(&req, sizeof(req));
+		/* Enqueue OCB Set Schedule request message */
+		msg = wma_fill_vdev_req(wma_handle, config_req->session_id,
+					WMA_OCB_SET_CONFIG_CMD,
+					WMA_TARGET_REQ_TYPE_VDEV_START,
+					(void *)config_req, 1000);
+		if (!msg) {
+			WMA_LOGE(FL("Failed to fill vdev req %d"), req.vdev_id);
+			status = QDF_STATUS_E_NOMEM;
+			return status;
+		}
+		req.chan = cds_freq_to_chan(config_req->channels[0].chan_freq);
+		req.vdev_id = msg->vdev_id;
+		if (cds_chan_to_band(req.chan) == CDS_BAND_2GHZ)
+			req.dot11_mode = WNI_CFG_DOT11_MODE_11G;
+		else
+			req.dot11_mode = WNI_CFG_DOT11_MODE_11A;
+
+		if (wma_handle->ocb_config_req)
+			qdf_mem_free(wma_handle->ocb_config_req);
+		wma_handle->ocb_config_req = copy_sir_ocb_config(config_req);
+		req.preferred_rx_streams = 2;
+		req.preferred_tx_streams = 2;
+
+		status = wma_vdev_start(wma_handle, &req, false);
+		if (status != QDF_STATUS_SUCCESS) {
+			wma_remove_vdev_req(wma_handle, req.vdev_id,
+					    WMA_TARGET_REQ_TYPE_VDEV_START);
+			WMA_LOGE(FL("vdev_start failed, status = %d"), status);
+		}
+		return 0;
+	} else {
+		return wma_ocb_set_config(wma_handle, config_req);
+	}
+}
+
+int wma_ocb_start_resp_ind_cont(tp_wma_handle wma_handle)
+{
+	QDF_STATUS qdf_status = 0;
+
+	if (!wma_handle->ocb_config_req) {
+		WMA_LOGE(FL("The request could not be found"));
+		return QDF_STATUS_E_EMPTY;
+	}
+
+	qdf_status = wma_ocb_set_config(wma_handle, wma_handle->ocb_config_req);
+	return qdf_status;
+}
+
+static WLAN_PHY_MODE wma_ocb_freq_to_mode(uint32_t freq)
+{
+	if (cds_chan_to_band(cds_freq_to_chan(freq)) == CDS_BAND_2GHZ)
+		return MODE_11G;
+	else
+		return MODE_11A;
+}
+
+/**
+ * wma_send_ocb_set_config() - send the OCB config to the FW
+ * @wma_handle: pointer to the WMA handle
+ * @config: the OCB configuration
+ *
+ * Return: 0 on success
+ */
+int wma_ocb_set_config(tp_wma_handle wma_handle, struct sir_ocb_config *config)
+{
+	int32_t ret, i;
+	uint32_t *ch_mhz;
+	struct ocb_config tconfig = {0};
+
+	tconfig.vdev_id = config->session_id;
+	tconfig.channel_count = config->channel_count;
+	tconfig.schedule_size = config->schedule_size;
+	tconfig.flags = config->flags;
+	tconfig.channels = (struct ocb_config_chan *)config->channels;
+	tconfig.schedule = (struct ocb_config_schdl *)config->schedule;
+	tconfig.dcc_ndl_chan_list_len = config->dcc_ndl_chan_list_len;
+	tconfig.dcc_ndl_chan_list = config->dcc_ndl_chan_list;
+	tconfig.dcc_ndl_active_state_list_len =
+				config->dcc_ndl_active_state_list_len;
+	tconfig.dcc_ndl_active_state_list = config->dcc_ndl_active_state_list;
+	ch_mhz = qdf_mem_malloc(sizeof(uint32_t)*config->channel_count);
+	if (!ch_mhz)
+		return -ENOMEM;
+
+	for (i = 0; i < config->channel_count; i++)
+		ch_mhz[i] = wma_ocb_freq_to_mode(config->channels[i].chan_freq);
+
+	/*
+	 * Save the configuration so that it can be used in
+	 * wma_ocb_set_config_event_handler.
+	 */
+	if (wma_handle->ocb_config_req != config) {
+		if (wma_handle->ocb_config_req)
+			qdf_mem_free(wma_handle->ocb_config_req);
+		wma_handle->ocb_config_req = copy_sir_ocb_config(config);
+	}
+
+	ret = wmi_unified_ocb_set_config(wma_handle->wmi_handle, &tconfig);
+	if (ret != EOK) {
+		if (wma_handle->ocb_config_req) {
+			qdf_mem_free(wma_handle->ocb_config_req);
+			wma_handle->ocb_config_req = NULL;
+		}
+		qdf_mem_free(ch_mhz);
+		WMA_LOGE("Failed to set OCB config");
+		return -EIO;
+	}
+	qdf_mem_free(ch_mhz);
+
+	return 0;
+}
+
+/**
+ * wma_ocb_set_config_event_handler() - Response event for the set config cmd
+ * @handle: the WMA handle
+ * @event_buf: buffer with the event parameters
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+int wma_ocb_set_config_event_handler(void *handle, uint8_t *event_buf,
+				     uint32_t len)
+{
+	WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs;
+	wmi_ocb_set_config_resp_event_fixed_param *fix_param;
+
+	param_tlvs = (WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *)event_buf;
+	fix_param = param_tlvs->fixed_param;
+	return wma_ocb_set_config_resp(handle, fix_param->status);
+};
+
+/**
+ * wma_ocb_set_utc_time() - send the UTC time to the firmware
+ * @wma_handle: pointer to the WMA handle
+ * @utc: pointer to the UTC time struct
+ *
+ * Return: 0 on succes
+ */
+int wma_ocb_set_utc_time(tp_wma_handle wma_handle, struct sir_ocb_utc *utc)
+{
+	int32_t ret;
+	struct ocb_utc_param cmd = {0};
+
+	cmd.vdev_id = utc->vdev_id;
+	qdf_mem_copy(&cmd.utc_time, &utc->utc_time, WMI_SIZE_UTC_TIME);
+	qdf_mem_copy(&cmd.time_error, &utc->time_error,
+				 WMI_SIZE_UTC_TIME_ERROR);
+	ret = wmi_unified_ocb_set_utc_time_cmd(wma_handle->wmi_handle, &cmd);
+	if (ret != EOK) {
+		WMA_LOGE(FL("Failed to set OCB UTC time"));
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_ocb_start_timing_advert() - start sending the timing advertisement
+ *				   frames on a channel
+ * @wma_handle: pointer to the WMA handle
+ * @timing_advert: pointer to the timing advertisement struct
+ *
+ * Return: 0 on succes
+ */
+int wma_ocb_start_timing_advert(tp_wma_handle wma_handle,
+	struct sir_ocb_timing_advert *timing_advert)
+{
+	int32_t ret;
+	struct ocb_timing_advert_param cmd = {0};
+
+	cmd.vdev_id = timing_advert->vdev_id;
+	cmd.repeat_rate = timing_advert->repeat_rate;
+	cmd.chan_freq = timing_advert->chan_freq;
+	cmd.timestamp_offset = timing_advert->timestamp_offset;
+	cmd.time_value_offset = timing_advert->time_value_offset;
+	cmd.template_length = timing_advert->template_length;
+	cmd.template_value = (uint8_t *)timing_advert->template_value;
+
+	ret = wmi_unified_ocb_start_timing_advert(wma_handle->wmi_handle,
+				   &cmd);
+	if (ret != EOK) {
+		WMA_LOGE(FL("Failed to start OCB timing advert"));
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_ocb_stop_timing_advert() - stop sending the timing advertisement frames
+ *				  on a channel
+ * @wma_handle: pointer to the WMA handle
+ * @timing_advert: pointer to the timing advertisement struct
+ *
+ * Return: 0 on succes
+ */
+int wma_ocb_stop_timing_advert(tp_wma_handle wma_handle,
+	struct sir_ocb_timing_advert *timing_advert)
+{
+	int32_t ret;
+	struct ocb_timing_advert_param cmd = {0};
+
+	cmd.vdev_id = timing_advert->vdev_id;
+	cmd.chan_freq = timing_advert->chan_freq;
+	ret = wmi_unified_ocb_stop_timing_advert(wma_handle->wmi_handle,
+				   &cmd);
+	if (ret != EOK) {
+		WMA_LOGE(FL("Failed to stop OCB timing advert"));
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_ocb_get_tsf_timer() - stop sending the timing advertisement frames on a
+ *			     channel
+ * @wma_handle: pointer to the WMA handle
+ * @request: pointer to the request
+ *
+ * Return: 0 on succes
+ */
+int wma_ocb_get_tsf_timer(tp_wma_handle wma_handle,
+			  struct sir_ocb_get_tsf_timer *request)
+{
+	QDF_STATUS ret;
+
+	/* Send the WMI command */
+	ret = wmi_unified_ocb_get_tsf_timer(wma_handle->wmi_handle,
+			(struct ocb_get_tsf_timer_param *)request);
+	/* If there is an error, set the completion event */
+	if (ret != EOK) {
+		WMA_LOGE(FL("Failed to send WMI message: %d"), ret);
+		return -EIO;
+	}
+	return 0;
+}
+
+/**
+ * wma_ocb_get_tsf_timer_resp_event_handler() - Event for the get TSF timer cmd
+ * @handle: the WMA handle
+ * @event_buf: buffer with the event parameters
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+static int wma_ocb_get_tsf_timer_resp_event_handler(void *handle,
+						    uint8_t *event_buf,
+						    uint32_t len)
+{
+	QDF_STATUS qdf_status;
+	struct sir_ocb_get_tsf_timer_response *response;
+	WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs;
+	wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param;
+	struct scheduler_msg msg = {0};
+
+	param_tlvs = (WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *)event_buf;
+	fix_param = param_tlvs->fixed_param;
+
+	/* Allocate and populate the response */
+	response = qdf_mem_malloc(sizeof(*response));
+	if (!response)
+		return -ENOMEM;
+
+	response->vdev_id = fix_param->vdev_id;
+	response->timer_high = fix_param->tsf_timer_high;
+	response->timer_low = fix_param->tsf_timer_low;
+
+	msg.type = eWNI_SME_OCB_GET_TSF_TIMER_RSP;
+	msg.bodyptr = response;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE(FL("Failed to post msg to SME"));
+		qdf_mem_free(response);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_dcc_get_stats() - get the DCC channel stats
+ * @wma_handle: pointer to the WMA handle
+ * @get_stats_param: pointer to the dcc stats
+ *
+ * Return: 0 on succes
+ */
+int wma_dcc_get_stats(tp_wma_handle wma_handle,
+		      struct sir_dcc_get_stats *get_stats_param)
+{
+	int32_t ret;
+	struct ocb_dcc_get_stats_param cmd = {0};
+
+	cmd.vdev_id = get_stats_param->vdev_id;
+	cmd.channel_count = get_stats_param->channel_count;
+	cmd.request_array_len = get_stats_param->request_array_len;
+	cmd.request_array = get_stats_param->request_array;
+
+	/* Send the WMI command */
+	ret = wmi_unified_dcc_get_stats_cmd(wma_handle->wmi_handle, &cmd);
+
+	if (ret != EOK) {
+		WMA_LOGE(FL("Failed to send WMI message: %d"), ret);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_dcc_get_stats_resp_event_handler() - Response event for the get stats cmd
+ * @handle: the WMA handle
+ * @event_buf: buffer with the event parameters
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+static int wma_dcc_get_stats_resp_event_handler(void *handle,
+						uint8_t *event_buf,
+						uint32_t len)
+{
+	QDF_STATUS qdf_status;
+	struct sir_dcc_get_stats_response *response;
+	WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs;
+	wmi_dcc_get_stats_resp_event_fixed_param *fix_param;
+	struct scheduler_msg msg = {0};
+
+	param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)event_buf;
+	fix_param = param_tlvs->fixed_param;
+
+	/* Allocate and populate the response */
+	if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE -
+	    sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel)) ||
+	    fix_param->num_channels > param_tlvs->num_stats_per_channel_list) {
+		WMA_LOGE("%s: too many channels:%d, param_tlvs->num_stats_per_channel_list:%d",
+			__func__, fix_param->num_channels,
+			param_tlvs->num_stats_per_channel_list);
+		return -EINVAL;
+	}
+	response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels *
+		sizeof(wmi_dcc_ndl_stats_per_channel));
+	if (!response)
+		return -ENOMEM;
+
+	response->vdev_id = fix_param->vdev_id;
+	response->num_channels = fix_param->num_channels;
+	response->channel_stats_array_len =
+		fix_param->num_channels * sizeof(wmi_dcc_ndl_stats_per_channel);
+	response->channel_stats_array = ((void *)response) + sizeof(*response);
+	qdf_mem_copy(response->channel_stats_array,
+		     param_tlvs->stats_per_channel_list,
+		     response->channel_stats_array_len);
+
+	msg.type = eWNI_SME_DCC_GET_STATS_RSP;
+	msg.bodyptr = response;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE(FL("Failed to post msg to SME"));
+		qdf_mem_free(response);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_dcc_clear_stats() - command to clear the DCC stats
+ * @wma_handle: pointer to the WMA handle
+ * @clear_stats_param: parameters to the command
+ *
+ * Return: 0 on succes
+ */
+int wma_dcc_clear_stats(tp_wma_handle wma_handle,
+			struct sir_dcc_clear_stats *clear_stats_param)
+{
+	int32_t ret;
+
+	/* Send the WMI command */
+	ret = wmi_unified_dcc_clear_stats(wma_handle->wmi_handle,
+		(struct ocb_dcc_clear_stats_param *)clear_stats_param);
+	if (ret != EOK) {
+		WMA_LOGE(FL("Failed to send the WMI command"));
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_dcc_update_ndl() - command to update the NDL data
+ * @wma_handle: pointer to the WMA handle
+ * @update_ndl_param: pointer to the request parameters
+ *
+ * Return: 0 on success
+ */
+int wma_dcc_update_ndl(tp_wma_handle wma_handle,
+		       struct sir_dcc_update_ndl *update_ndl_param)
+{
+	QDF_STATUS qdf_status;
+	struct ocb_dcc_update_ndl_param *cmd;
+
+	cmd = (struct ocb_dcc_update_ndl_param *) update_ndl_param;
+	/* Send the WMI command */
+	qdf_status = wmi_unified_dcc_update_ndl(wma_handle->wmi_handle,
+				   cmd);
+	/* If there is an error, set the completion event */
+	if (qdf_status) {
+		WMA_LOGE(FL("Failed to send WMI message: %d"), qdf_status);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_dcc_update_ndl_resp_event_handler() - Response event for the update NDL
+ * command
+ * @handle: the WMA handle
+ * @event_buf: buffer with the event parameters
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+static int wma_dcc_update_ndl_resp_event_handler(void *handle,
+						 uint8_t *event_buf,
+						 uint32_t len)
+{
+	QDF_STATUS qdf_status;
+	struct sir_dcc_update_ndl_response *resp;
+	WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs;
+	wmi_dcc_update_ndl_resp_event_fixed_param *fix_param;
+	struct scheduler_msg msg = {0};
+
+	param_tlvs = (WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *)event_buf;
+	fix_param = param_tlvs->fixed_param;
+	/* Allocate and populate the response */
+	resp = qdf_mem_malloc(sizeof(*resp));
+	if (!resp)
+		return -ENOMEM;
+
+	resp->vdev_id = fix_param->vdev_id;
+	resp->status = fix_param->status;
+
+	msg.type = eWNI_SME_DCC_UPDATE_NDL_RSP;
+	msg.bodyptr = resp;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))	{
+		WMA_LOGE(FL("Failed to post msg to SME"));
+		qdf_mem_free(resp);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_dcc_stats_event_handler() - Response event for the get stats cmd
+ * @handle: the WMA handle
+ * @event_buf: buffer with the event parameters
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+static int wma_dcc_stats_event_handler(void *handle, uint8_t *event_buf,
+				       uint32_t len)
+{
+	QDF_STATUS qdf_status;
+	struct sir_dcc_get_stats_response *response;
+	WMI_DCC_STATS_EVENTID_param_tlvs *param_tlvs;
+	wmi_dcc_stats_event_fixed_param *fix_param;
+	struct scheduler_msg msg = {0};
+
+	param_tlvs = (WMI_DCC_STATS_EVENTID_param_tlvs *)event_buf;
+	fix_param = param_tlvs->fixed_param;
+	/* Allocate and populate the response */
+	if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE -
+	    sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) {
+		WMA_LOGE("%s: too many channels:%d", __func__,
+			fix_param->num_channels);
+		QDF_ASSERT(0);
+		return -EINVAL;
+	}
+	response = qdf_mem_malloc(sizeof(*response) +
+	    fix_param->num_channels * sizeof(wmi_dcc_ndl_stats_per_channel));
+	if (!response)
+		return -ENOMEM;
+
+	response->vdev_id = fix_param->vdev_id;
+	response->num_channels = fix_param->num_channels;
+	response->channel_stats_array_len =
+		fix_param->num_channels * sizeof(wmi_dcc_ndl_stats_per_channel);
+
+	if (fix_param->num_channels > param_tlvs->num_stats_per_channel_list) {
+		WMA_LOGE("FW message num_chan %d more than TLV hdr %d",
+			 fix_param->num_channels,
+			 param_tlvs->num_stats_per_channel_list);
+		return -EINVAL;
+	}
+
+	response->channel_stats_array = ((void *)response) + sizeof(*response);
+	qdf_mem_copy(response->channel_stats_array,
+		     param_tlvs->stats_per_channel_list,
+		     response->channel_stats_array_len);
+
+	msg.type = eWNI_SME_DCC_STATS_EVENT;
+	msg.bodyptr = response;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))	{
+		WMA_LOGE(FL("Failed to post msg to SME"));
+		qdf_mem_free(response);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_ocb_register_event_handlers() - register handlers for the OCB WMI
+ * events
+ * @wma_handle: pointer to the WMA handle
+ *
+ * Return: 0 on success, non-zero on failure
+ */
+int wma_ocb_register_event_handlers(tp_wma_handle wma_handle)
+{
+	int status;
+
+	if (!wma_handle) {
+		WMA_LOGE(FL("wma_handle is NULL"));
+		return -EINVAL;
+	}
+
+	/* Initialize the members in WMA used by wma_ocb */
+	status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
+			wmi_ocb_set_config_resp_event_id,
+			wma_ocb_set_config_event_handler,
+			WMA_RX_SERIALIZER_CTX);
+	if (status)
+		return status;
+
+	status = wmi_unified_register_event_handler(
+			wma_handle->wmi_handle,
+			wmi_ocb_get_tsf_timer_resp_event_id,
+			wma_ocb_get_tsf_timer_resp_event_handler,
+			WMA_RX_SERIALIZER_CTX);
+	if (status)
+		return status;
+
+	status = wmi_unified_register_event_handler(
+			wma_handle->wmi_handle,
+			wmi_dcc_get_stats_resp_event_id,
+			wma_dcc_get_stats_resp_event_handler,
+			WMA_RX_SERIALIZER_CTX);
+	if (status)
+		return status;
+
+	status = wmi_unified_register_event_handler(
+			wma_handle->wmi_handle,
+			wmi_dcc_update_ndl_resp_event_id,
+			wma_dcc_update_ndl_resp_event_handler,
+			WMA_RX_SERIALIZER_CTX);
+	if (status)
+		return status;
+
+	status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
+			wmi_dcc_stats_event_id,
+			wma_dcc_stats_event_handler,
+			WMA_RX_SERIALIZER_CTX);
+	if (status)
+		return status;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_start_ocb_vdev() - start OCB vdev
+ * @config: ocb channel config
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS wma_start_ocb_vdev(struct ocb_config *config)
+{
+	struct wma_target_req *msg;
+	struct wma_vdev_start_req req;
+	QDF_STATUS status;
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	qdf_mem_zero(&req, sizeof(req));
+	msg = wma_fill_vdev_req(wma, config->vdev_id,
+				WMA_OCB_SET_CONFIG_CMD,
+				WMA_TARGET_REQ_TYPE_VDEV_START,
+				(void *)config, 1000);
+	if (!msg) {
+		WMA_LOGE(FL("Failed to fill vdev req %d"), config->vdev_id);
+
+		return QDF_STATUS_E_NOMEM;
+	}
+	req.chan = cds_freq_to_chan(config->channels[0].chan_freq);
+	req.vdev_id = msg->vdev_id;
+	if (cds_chan_to_band(req.chan) == CDS_BAND_2GHZ)
+		req.dot11_mode = WNI_CFG_DOT11_MODE_11G;
+	else
+		req.dot11_mode = WNI_CFG_DOT11_MODE_11A;
+
+	req.preferred_rx_streams = 2;
+	req.preferred_tx_streams = 2;
+
+	status = wma_vdev_start(wma, &req, false);
+	if (status != QDF_STATUS_SUCCESS) {
+		wma_remove_vdev_req(wma, req.vdev_id,
+				    WMA_TARGET_REQ_TYPE_VDEV_START);
+		WMA_LOGE(FL("vdev_start failed, status = %d"), status);
+	}
+
+	return status;
+}
+
+QDF_STATUS wma_ocb_register_callbacks(tp_wma_handle wma_handle)
+{
+	ucfg_ocb_register_vdev_start(wma_handle->pdev, wma_start_ocb_vdev);
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/core/wma/src/wma_ocb.h b/core/wma/src/wma_ocb.h
new file mode 100644
index 0000000..0817b20
--- /dev/null
+++ b/core/wma/src/wma_ocb.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2015-2018 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.
+ */
+
+#ifndef __WMA_OCB_H
+#define __WMA_OCB_H
+
+#include "wma.h"
+#include "sir_api.h"
+
+#ifdef WLAN_FEATURE_DSRC
+int wma_ocb_set_config_resp(tp_wma_handle wma_handle, uint8_t status);
+
+int wma_ocb_set_config_req(tp_wma_handle handle,
+			   struct sir_ocb_config *config_req);
+
+int wma_ocb_set_config_event_handler(void *handle, uint8_t *event_buf,
+				     uint32_t len);
+
+int wma_ocb_start_resp_ind_cont(tp_wma_handle wma_handle);
+
+int wma_ocb_set_config(tp_wma_handle wma_handle, struct sir_ocb_config *config);
+
+int wma_ocb_set_utc_time(tp_wma_handle wma_handle, struct sir_ocb_utc *utc);
+
+int wma_ocb_start_timing_advert(tp_wma_handle wma_handle,
+				struct sir_ocb_timing_advert *timing_advert);
+
+int wma_ocb_stop_timing_advert(tp_wma_handle wma_handle,
+			       struct sir_ocb_timing_advert *timing_advert);
+
+int wma_ocb_get_tsf_timer(tp_wma_handle wma_handle,
+			  struct sir_ocb_get_tsf_timer *request);
+
+int wma_dcc_get_stats(tp_wma_handle wma_handle,
+		      struct sir_dcc_get_stats *get_stats_param);
+
+int wma_dcc_clear_stats(tp_wma_handle wma_handle,
+			struct sir_dcc_clear_stats *clear_stats_param);
+
+int wma_dcc_update_ndl(tp_wma_handle wma_handle,
+		       struct sir_dcc_update_ndl *update_ndl_param);
+
+int wma_ocb_register_event_handlers(tp_wma_handle wma_handle);
+
+/**
+ * wma_ocb_register_callbacks() - register WMA layer callback for OCB
+ * @wma_handle: wma handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS wma_ocb_register_callbacks(tp_wma_handle wma_handle);
+#else
+static inline int wma_ocb_set_config_resp(tp_wma_handle wma_handle,
+		uint8_t status)
+{
+	return 0;
+}
+
+static inline int wma_ocb_set_config_req(tp_wma_handle handle,
+		struct sir_ocb_config *config_req)
+{
+	return 0;
+}
+
+static inline int wma_ocb_set_config_event_handler(void *handle,
+		uint8_t *event_buf, uint32_t len)
+{
+	return 0;
+}
+
+static inline int wma_ocb_start_resp_ind_cont(tp_wma_handle wma_handle)
+{
+	return 0;
+}
+
+static inline int wma_ocb_set_config(tp_wma_handle wma_handle,
+		struct sir_ocb_config *config)
+{
+	return 0;
+}
+
+static inline int wma_ocb_set_utc_time(tp_wma_handle wma_handle,
+		struct sir_ocb_utc *utc)
+{
+	return 0;
+}
+
+static inline int wma_ocb_start_timing_advert(tp_wma_handle wma_handle,
+		struct sir_ocb_timing_advert *timing_advert)
+{
+	return 0;
+}
+
+static inline int wma_ocb_stop_timing_advert(tp_wma_handle wma_handle,
+		struct sir_ocb_timing_advert *timing_advert)
+{
+	return 0;
+}
+
+static inline int wma_ocb_get_tsf_timer(tp_wma_handle wma_handle,
+		struct sir_ocb_get_tsf_timer *request)
+{
+	return 0;
+}
+
+static inline int wma_dcc_get_stats(tp_wma_handle wma_handle,
+		struct sir_dcc_get_stats *get_stats_param)
+{
+	return 0;
+}
+
+static inline int wma_dcc_clear_stats(tp_wma_handle wma_handle,
+		struct sir_dcc_clear_stats *clear_stats_param)
+{
+	return 0;
+}
+
+static inline int wma_dcc_update_ndl(tp_wma_handle wma_handle,
+		struct sir_dcc_update_ndl *update_ndl_param)
+{
+	return 0;
+}
+
+static inline int wma_ocb_register_event_handlers(tp_wma_handle wma_handle)
+{
+	return 0;
+}
+
+/**
+ * wma_ocb_register_callbacks() - register WMA layer callback for OCB
+ * @wma_handle: wma handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static inline QDF_STATUS wma_ocb_register_callbacks(tp_wma_handle wma_handle)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#endif /* __WMA_OCB_H */
diff --git a/core/wma/src/wma_power.c b/core/wma/src/wma_power.c
new file mode 100644
index 0000000..6d48e11
--- /dev/null
+++ b/core/wma/src/wma_power.c
@@ -0,0 +1,1733 @@
+/*
+ * Copyright (c) 2013-2018 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:    wma_power.c
+ *  This file contains powersave related functions.
+ */
+
+/* Header files */
+
+#include "wma.h"
+#include "wma_api.h"
+#include "cds_api.h"
+#include "wmi_unified_api.h"
+#include "wlan_qct_sys.h"
+#include "wni_api.h"
+#include "ani_global.h"
+#include "wmi_unified.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+
+#include "qdf_nbuf.h"
+#include "qdf_types.h"
+#include "qdf_mem.h"
+#include "wma_types.h"
+#include "lim_api.h"
+#include "lim_session_utils.h"
+
+#include "cds_utils.h"
+
+#if !defined(REMOVE_PKT_LOG)
+#include "pktlog_ac.h"
+#endif /* REMOVE_PKT_LOG */
+
+#include "dbglog_host.h"
+#include "csr_api.h"
+#include "ol_fw.h"
+
+#include "wma_internal.h"
+#include "wlan_pmo_ucfg_api.h"
+
+/**
+ * wma_unified_modem_power_state() - set modem power state to fw
+ * @wmi_handle: wmi handle
+ * @param_value: parameter value
+ *
+ * Return: 0 for success or error code
+ */
+static int
+wma_unified_modem_power_state(wmi_unified_t wmi_handle, uint32_t param_value)
+{
+	int ret;
+	wmi_modem_power_state_cmd_param *cmd;
+	wmi_buf_t buf;
+	uint16_t len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return -ENOMEM;
+
+	cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_modem_power_state_cmd_param));
+	cmd->modem_power_state = param_value;
+	WMA_LOGD("%s: Setting cmd->modem_power_state = %u", __func__,
+		 param_value);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				     WMI_MODEM_POWER_STATE_CMDID);
+	if (ret != EOK)
+		wmi_buf_free(buf);
+
+	return ret;
+}
+
+/**
+ * wma_unified_set_sta_ps_param() - set sta power save parameter to fw
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @param: param
+ * @value: parameter value
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_unified_set_sta_ps_param(wmi_unified_t wmi_handle,
+					    uint32_t vdev_id, uint32_t param,
+					    uint32_t value)
+{
+	tp_wma_handle wma;
+	struct wma_txrx_node *iface;
+	struct sta_ps_params sta_ps_param = {0};
+	QDF_STATUS status;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (NULL == wma) {
+		WMA_LOGE("%s: wma is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	WMA_LOGD("Set Sta Ps param vdevId %d Param %d val %d",
+		 vdev_id, param, value);
+	iface = &wma->interfaces[vdev_id];
+
+	sta_ps_param.vdev_id = vdev_id;
+	sta_ps_param.param = param;
+	sta_ps_param.value = value;
+	status = wmi_unified_sta_ps_cmd_send(wmi_handle, &sta_ps_param);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	return status;
+}
+
+#ifdef QCA_IBSS_SUPPORT
+/**
+ * wma_set_ibss_pwrsave_params() - set ibss power save parameter to fw
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: 0 for success or error code.
+ */
+QDF_STATUS
+wma_set_ibss_pwrsave_params(tp_wma_handle wma, uint8_t vdev_id)
+{
+	QDF_STATUS ret;
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_ATIM_WINDOW_LENGTH,
+			wma->wma_ibss_power_save_params.atimWindowLength);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Failed to set WMI_VDEV_PARAM_ATIM_WINDOW_LENGTH ret = %d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED,
+			wma->wma_ibss_power_save_params.isPowerSaveAllowed);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Failed, set WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED ret=%d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED,
+			wma->wma_ibss_power_save_params.isPowerCollapseAllowed);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Failed, set WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED ret=%d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED,
+			 wma->wma_ibss_power_save_params.isAwakeonTxRxEnabled);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Failed, set WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED ret=%d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_INACTIVITY_CNT,
+			wma->wma_ibss_power_save_params.inactivityCount);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Failed, set WMI_VDEV_PARAM_INACTIVITY_CNT ret=%d",
+			 ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS,
+			wma->wma_ibss_power_save_params.txSPEndInactivityTime);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Failed, set WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS ret=%d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS,
+			wma->wma_ibss_power_save_params.ibssPsWarmupTime);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Failed, set WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS ret=%d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE,
+			wma->wma_ibss_power_save_params.ibssPs1RxChainInAtimEnable);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Failed to set IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE ret=%d",
+			ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* QCA_IBSS_SUPPORT */
+
+/**
+ * wma_set_ap_peer_uapsd() - set powersave parameters in ap mode to fw
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @peer_addr: peer mac address
+ * @uapsd_value: uapsd value
+ * @max_sp: maximum service period
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_set_ap_peer_uapsd(tp_wma_handle wma, uint32_t vdev_id,
+			      uint8_t *peer_addr, uint8_t uapsd_value,
+			      uint8_t max_sp)
+{
+	uint32_t uapsd = 0;
+	uint32_t max_sp_len = 0;
+	QDF_STATUS ret;
+	struct ap_ps_params param = {0};
+
+	if (uapsd_value & UAPSD_VO_ENABLED) {
+		uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
+			 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
+	}
+
+	if (uapsd_value & UAPSD_VI_ENABLED) {
+		uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
+			 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
+	}
+
+	if (uapsd_value & UAPSD_BK_ENABLED) {
+		uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
+			 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
+	}
+
+	if (uapsd_value & UAPSD_BE_ENABLED) {
+		uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
+			 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
+	}
+
+	switch (max_sp) {
+	case UAPSD_MAX_SP_LEN_2:
+		max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_2;
+		break;
+	case UAPSD_MAX_SP_LEN_4:
+		max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_4;
+		break;
+	case UAPSD_MAX_SP_LEN_6:
+		max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_6;
+		break;
+	default:
+		max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_UNLIMITED;
+		break;
+	}
+
+	WMA_LOGD("Set WMI_AP_PS_PEER_PARAM_UAPSD 0x%x for %pM",
+		 uapsd, peer_addr);
+	param.vdev_id = vdev_id;
+	param.param = WMI_AP_PS_PEER_PARAM_UAPSD;
+	param.value = uapsd;
+	ret = wmi_unified_ap_ps_cmd_send(wma->wmi_handle, peer_addr,
+						&param);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Failed to set WMI_AP_PS_PEER_PARAM_UAPSD for %pM",
+			 peer_addr);
+		return ret;
+	}
+
+	WMA_LOGD("Set WMI_AP_PS_PEER_PARAM_MAX_SP 0x%x for %pM",
+		 max_sp_len, peer_addr);
+
+	param.vdev_id = vdev_id;
+	param.param = WMI_AP_PS_PEER_PARAM_MAX_SP;
+	param.value = max_sp_len;
+	ret = wmi_unified_ap_ps_cmd_send(wma->wmi_handle, peer_addr,
+					  &param);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Failed to set WMI_AP_PS_PEER_PARAM_MAX_SP for %pM",
+			 peer_addr);
+		return ret;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_update_edca_params_for_ac() - to update per ac EDCA parameters
+ * @edca_param: EDCA parameters
+ * @wmm_param: wmm parameters
+ * @ac: access category
+ *
+ * Return: none
+ */
+void wma_update_edca_params_for_ac(tSirMacEdcaParamRecord *edca_param,
+				   struct wmi_host_wme_vparams *wmm_param,
+				   int ac, bool mu_edca_param)
+{
+#define WMA_WMM_EXPO_TO_VAL(val)        ((1 << (val)) - 1)
+	if (mu_edca_param) {
+		wmm_param->cwmin = edca_param->cw.min;
+		wmm_param->cwmax = edca_param->cw.max;
+	} else {
+		wmm_param->cwmin = WMA_WMM_EXPO_TO_VAL(edca_param->cw.min);
+		wmm_param->cwmax = WMA_WMM_EXPO_TO_VAL(edca_param->cw.max);
+	}
+	wmm_param->aifs = edca_param->aci.aifsn;
+	if (mu_edca_param)
+		wmm_param->mu_edca_timer = edca_param->mu_edca_timer;
+	else
+		wmm_param->txoplimit = edca_param->txoplimit;
+	wmm_param->acm = edca_param->aci.acm;
+
+	wmm_param->noackpolicy = edca_param->no_ack;
+
+	WMA_LOGD("WMM PARAMS AC[%d]: AIFS %d Min %d Max %d %s %d ACM %d NOACK %d",
+			ac, wmm_param->aifs, wmm_param->cwmin,
+			wmm_param->cwmax,
+			mu_edca_param ? "MU_EDCA TIMER" : "TXOP",
+			mu_edca_param ? wmm_param->mu_edca_timer :
+				wmm_param->txoplimit,
+			wmm_param->acm, wmm_param->noackpolicy);
+}
+
+/**
+ * wma_set_tx_power() - set tx power limit in fw
+ * @handle: wma handle
+ * @tx_pwr_params: tx power parameters
+ *
+ * Return: none
+ */
+void wma_set_tx_power(WMA_HANDLE handle,
+		      tMaxTxPowerParams *tx_pwr_params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	uint8_t vdev_id;
+	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
+	struct cdp_vdev *vdev;
+
+	if (tx_pwr_params->dev_mode == QDF_SAP_MODE ||
+	    tx_pwr_params->dev_mode == QDF_P2P_GO_MODE) {
+		vdev = wma_find_vdev_by_addr(wma_handle,
+					     tx_pwr_params->bssId.bytes,
+					     &vdev_id);
+	} else {
+		vdev = wma_find_vdev_by_bssid(wma_handle,
+					      tx_pwr_params->bssId.bytes,
+					      &vdev_id);
+	}
+	if (!vdev) {
+		WMA_LOGE("vdev handle is invalid for %pM",
+			 tx_pwr_params->bssId.bytes);
+		qdf_mem_free(tx_pwr_params);
+		return;
+	}
+
+	if (!wma_is_vdev_up(vdev_id)) {
+		WMA_LOGE("%s: vdev id %d is not up for %pM", __func__, vdev_id,
+			 tx_pwr_params->bssId.bytes);
+		qdf_mem_free(tx_pwr_params);
+		return;
+	}
+
+	if (tx_pwr_params->power == 0) {
+		/* set to default. Since the app does not care the tx power
+		 * we keep the previous setting
+		 */
+		wma_handle->interfaces[vdev_id].tx_power = 0;
+		ret = 0;
+		goto end;
+	}
+	if (wma_handle->interfaces[vdev_id].max_tx_power != 0) {
+		/* make sure tx_power less than max_tx_power */
+		if (tx_pwr_params->power >
+		    wma_handle->interfaces[vdev_id].max_tx_power) {
+			tx_pwr_params->power =
+				wma_handle->interfaces[vdev_id].max_tx_power;
+		}
+	}
+	if (wma_handle->interfaces[vdev_id].tx_power != tx_pwr_params->power) {
+
+		/* tx_power changed, Push the tx_power to FW */
+		WMA_LOGI("%s: Set TX pwr limit [WMI_VDEV_PARAM_TX_PWRLIMIT] to %d",
+			__func__, tx_pwr_params->power);
+		ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
+					      WMI_VDEV_PARAM_TX_PWRLIMIT,
+					      tx_pwr_params->power);
+		if (ret == QDF_STATUS_SUCCESS)
+			wma_handle->interfaces[vdev_id].tx_power =
+				tx_pwr_params->power;
+	} else {
+		/* no tx_power change */
+		ret = QDF_STATUS_SUCCESS;
+	}
+end:
+	qdf_mem_free(tx_pwr_params);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Failed to set vdev param WMI_VDEV_PARAM_TX_PWRLIMIT");
+}
+
+/**
+ * wma_set_max_tx_power() - set max tx power limit in fw
+ * @handle: wma handle
+ * @tx_pwr_params: tx power parameters
+ *
+ * Return: none
+ */
+void wma_set_max_tx_power(WMA_HANDLE handle,
+			  tMaxTxPowerParams *tx_pwr_params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	uint8_t vdev_id;
+	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
+	struct cdp_vdev *vdev;
+	int8_t prev_max_power;
+
+	vdev = wma_find_vdev_by_addr(wma_handle, tx_pwr_params->bssId.bytes,
+				     &vdev_id);
+	if (vdev == NULL) {
+		/* not in SAP array. Try the station/p2p array */
+		vdev = wma_find_vdev_by_bssid(wma_handle,
+					      tx_pwr_params->bssId.bytes,
+					      &vdev_id);
+	}
+	if (!vdev) {
+		WMA_LOGE("vdev handle is invalid for %pM",
+			 tx_pwr_params->bssId.bytes);
+		qdf_mem_free(tx_pwr_params);
+		return;
+	}
+
+	if (!wma_is_vdev_up(vdev_id)) {
+		WMA_LOGE("%s: vdev id %d is not up", __func__, vdev_id);
+		qdf_mem_free(tx_pwr_params);
+		return;
+	}
+
+	if (wma_handle->interfaces[vdev_id].max_tx_power ==
+	    tx_pwr_params->power) {
+		ret = QDF_STATUS_SUCCESS;
+		goto end;
+	}
+	prev_max_power = wma_handle->interfaces[vdev_id].max_tx_power;
+	wma_handle->interfaces[vdev_id].max_tx_power = tx_pwr_params->power;
+	if (wma_handle->interfaces[vdev_id].max_tx_power == 0) {
+		ret = QDF_STATUS_SUCCESS;
+		goto end;
+	}
+	WMA_LOGI("Set MAX TX pwr limit [WMI_VDEV_PARAM_TX_PWRLIMIT] to %d",
+		 wma_handle->interfaces[vdev_id].max_tx_power);
+	ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
+				WMI_VDEV_PARAM_TX_PWRLIMIT,
+				wma_handle->interfaces[vdev_id].max_tx_power);
+	if (ret == QDF_STATUS_SUCCESS)
+		wma_handle->interfaces[vdev_id].tx_power =
+			wma_handle->interfaces[vdev_id].max_tx_power;
+	else
+		wma_handle->interfaces[vdev_id].max_tx_power = prev_max_power;
+end:
+	qdf_mem_free(tx_pwr_params);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("%s: Failed to set vdev param WMI_VDEV_PARAM_TX_PWRLIMIT",
+			__func__);
+}
+
+/**
+ * wmi_unified_set_sta_ps() - set sta powersave params in fw
+ * @handle: wma handle
+ * @vdev_id: vdev id
+ * @val: value
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS wmi_unified_set_sta_ps(wmi_unified_t wmi_handle,
+					 uint32_t vdev_id, uint8_t val)
+{
+	QDF_STATUS ret;
+
+	ret = wmi_unified_set_sta_ps_mode(wmi_handle, vdev_id,
+				   val);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Failed to send set Mimo PS ret = %d", ret);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_get_uapsd_mask() - get uapsd mask based on uapsd parameters
+ * @uapsd_params: uapsed parameters
+ *
+ * Return: uapsd mask
+ */
+static inline uint32_t wma_get_uapsd_mask(tpUapsd_Params uapsd_params)
+{
+	uint32_t uapsd_val = 0;
+
+	if (uapsd_params->beDeliveryEnabled)
+		uapsd_val |= WMI_STA_PS_UAPSD_AC0_DELIVERY_EN;
+
+	if (uapsd_params->beTriggerEnabled)
+		uapsd_val |= WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
+
+	if (uapsd_params->bkDeliveryEnabled)
+		uapsd_val |= WMI_STA_PS_UAPSD_AC1_DELIVERY_EN;
+
+	if (uapsd_params->bkTriggerEnabled)
+		uapsd_val |= WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
+
+	if (uapsd_params->viDeliveryEnabled)
+		uapsd_val |= WMI_STA_PS_UAPSD_AC2_DELIVERY_EN;
+
+	if (uapsd_params->viTriggerEnabled)
+		uapsd_val |= WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
+
+	if (uapsd_params->voDeliveryEnabled)
+		uapsd_val |= WMI_STA_PS_UAPSD_AC3_DELIVERY_EN;
+
+	if (uapsd_params->voTriggerEnabled)
+		uapsd_val |= WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
+
+	return uapsd_val;
+}
+
+/**
+ * wma_set_force_sleep() - set power save parameters to fw
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @enable: enable/disable
+ * @qpower_config: qpower configuration
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS wma_set_force_sleep(tp_wma_handle wma,
+				uint32_t vdev_id,
+				uint8_t enable,
+				enum powersave_qpower_mode qpower_config,
+				bool enable_ps)
+{
+	QDF_STATUS ret;
+	uint32_t cfg_data_val = 0;
+	/* get mac to access CFG data base */
+	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
+	uint32_t rx_wake_policy;
+	uint32_t tx_wake_threshold;
+	uint32_t pspoll_count;
+	uint32_t inactivity_time;
+	uint32_t psmode;
+
+	WMA_LOGD("Set Force Sleep vdevId %d val %d", vdev_id, enable);
+
+	if (NULL == mac) {
+		WMA_LOGE("%s: Unable to get PE context", __func__);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	inactivity_time = mac->mlme_cfg->timeouts.ps_data_inactivity_timeout;
+
+	if (enable) {
+		/* override normal configuration and force station asleep */
+		rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
+		tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
+
+		if (ucfg_pmo_get_max_ps_poll(mac->psoc))
+			pspoll_count =
+				(uint32_t)ucfg_pmo_get_max_ps_poll(mac->psoc);
+		else
+			pspoll_count = WMA_DEFAULT_MAX_PSPOLL_BEFORE_WAKE;
+
+		psmode = WMI_STA_PS_MODE_ENABLED;
+	} else {
+		/* Ps Poll Wake Policy */
+		if (ucfg_pmo_get_max_ps_poll(mac->psoc)) {
+			/* Ps Poll is enabled */
+			rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
+			pspoll_count =
+				(uint32_t)ucfg_pmo_get_max_ps_poll(mac->psoc);
+			tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
+		} else {
+			rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
+			pspoll_count = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
+			tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
+		}
+		psmode = WMI_STA_PS_MODE_ENABLED;
+	}
+
+	/*
+	 * QPower is enabled by default in Firmware
+	 * So Disable QPower explicitly
+	 */
+	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
+					   WMI_STA_PS_ENABLE_QPOWER,
+					   qpower_config);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("%s(%d) QPower Failed vdevId %d",
+			qpower_config ? "Enable" : "Disable",
+			qpower_config, vdev_id);
+		return ret;
+	}
+	WMA_LOGD("QPower %s(%d) vdevId %d",
+			qpower_config ? "Enabled" : "Disabled",
+			qpower_config, vdev_id);
+
+	/* Set the Wake Policy to WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD */
+	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
+					   WMI_STA_PS_PARAM_RX_WAKE_POLICY,
+					   rx_wake_policy);
+
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Setting wake policy Failed vdevId %d", vdev_id);
+		return ret;
+	}
+	WMA_LOGD("Setting wake policy to %d vdevId %d",
+		 rx_wake_policy, vdev_id);
+
+	/* Set the Tx Wake Threshold */
+	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
+					   WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD,
+					   tx_wake_threshold);
+
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Setting TxWake Threshold vdevId %d", vdev_id);
+		return ret;
+	}
+	WMA_LOGD("Setting TxWake Threshold to %d vdevId %d",
+		 tx_wake_threshold, vdev_id);
+
+	/* Set the Ps Poll Count */
+	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
+					   WMI_STA_PS_PARAM_PSPOLL_COUNT,
+					   pspoll_count);
+
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Set Ps Poll Count Failed vdevId %d ps poll cnt %d",
+			 vdev_id, pspoll_count);
+		return ret;
+	}
+	WMA_LOGD("Set Ps Poll Count vdevId %d ps poll cnt %d",
+		 vdev_id, pspoll_count);
+
+	/* Set the Tx/Rx InActivity */
+	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
+					   WMI_STA_PS_PARAM_INACTIVITY_TIME,
+					   inactivity_time);
+
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Setting Tx/Rx InActivity Failed vdevId %d InAct %d",
+			 vdev_id, inactivity_time);
+		return ret;
+	}
+	WMA_LOGD("Set Tx/Rx InActivity vdevId %d InAct %d",
+		 vdev_id, inactivity_time);
+
+	/* Enable Sta Mode Power save */
+	if (enable_ps) {
+		ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, true);
+
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			WMA_LOGE("Enable Sta Mode Ps Failed vdevId %d",
+				vdev_id);
+			return ret;
+		}
+	}
+
+	/* Set Listen Interval */
+	cfg_data_val = mac->mlme_cfg->sap_cfg.listen_interval;
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+					      WMI_VDEV_PARAM_LISTEN_INTERVAL,
+					      cfg_data_val);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		/* Even it fails continue Fw will take default LI */
+		WMA_LOGE("Failed to Set Listen Interval vdevId %d", vdev_id);
+	}
+	WMA_LOGD("Set Listen Interval vdevId %d Listen Intv %d",
+		 vdev_id, cfg_data_val);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_get_qpower_config() - get qpower configuration
+ * @wma: WMA 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 enum powersave_qpower_mode wma_get_qpower_config(tp_wma_handle wma)
+{
+	switch (wma->powersave_mode) {
+	case PS_QPOWER_NODEEPSLEEP:
+	case PS_QPOWER_DEEPSLEEP:
+		WMA_LOGI("QPOWER is enabled in power save mode %d",
+			wma->powersave_mode);
+		return QPOWER_ENABLED;
+	case PS_DUTY_CYCLING_QPOWER:
+		WMA_LOGI("DUTY cycling QPOWER is enabled in power save mode %d",
+			wma->powersave_mode);
+		return QPOWER_DUTY_CYCLING;
+
+	default:
+		WMA_LOGI("QPOWER is disabled in power save mode %d",
+			wma->powersave_mode);
+		return QPOWER_DISABLED;
+	}
+}
+
+/**
+ * wma_enable_sta_ps_mode() - enable sta powersave params in fw
+ * @wma: wma handle
+ * @ps_req: power save request
+ *
+ * Return: none
+ */
+void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req)
+{
+	uint32_t vdev_id = ps_req->sessionid;
+	QDF_STATUS ret;
+	enum powersave_qpower_mode qpower_config = wma_get_qpower_config(wma);
+	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
+
+	if (!iface->handle) {
+		WMA_LOGE("vdev id %d is not active", vdev_id);
+		return;
+	}
+	if (eSIR_ADDON_NOTHING == ps_req->psSetting) {
+		if (qpower_config && iface->uapsd_cached_val) {
+			qpower_config = 0;
+			WMA_LOGD("Qpower is disabled");
+		}
+		WMA_LOGD("Enable Sta Mode Ps vdevId %d", vdev_id);
+		ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
+				WMI_STA_PS_PARAM_UAPSD, 0);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			WMA_LOGE("Set Uapsd param 0 Failed vdevId %d", vdev_id);
+			return;
+		}
+
+		ret = wma_set_force_sleep(wma, vdev_id, false,
+				qpower_config, true);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			WMA_LOGE("Enable Sta Ps Failed vdevId %d", vdev_id);
+			return;
+		}
+	} else if (eSIR_ADDON_ENABLE_UAPSD == ps_req->psSetting) {
+		uint32_t uapsd_val = 0;
+
+		uapsd_val = wma_get_uapsd_mask(&ps_req->uapsdParams);
+		if (uapsd_val != iface->uapsd_cached_val) {
+			WMA_LOGD("Enable Uapsd vdevId %d Mask %d",
+					vdev_id, uapsd_val);
+			ret = wma_unified_set_sta_ps_param(wma->wmi_handle,
+					vdev_id,
+					WMI_STA_PS_PARAM_UAPSD,
+					uapsd_val);
+			if (QDF_IS_STATUS_ERROR(ret)) {
+				WMA_LOGE("Enable Uapsd Failed vdevId %d",
+						vdev_id);
+				return;
+			}
+			/* Cache the Uapsd Mask */
+			iface->uapsd_cached_val = uapsd_val;
+		} else {
+			WMA_LOGD("Already Uapsd Enabled vdevId %d Mask %d",
+					vdev_id, uapsd_val);
+		}
+
+		if (qpower_config && iface->uapsd_cached_val) {
+			qpower_config = 0;
+			WMA_LOGD("Qpower is disabled");
+		}
+		WMA_LOGD("Enable Forced Sleep vdevId %d", vdev_id);
+		ret = wma_set_force_sleep(wma, vdev_id, true,
+				qpower_config, true);
+
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			WMA_LOGE("Enable Forced Sleep Failed vdevId %d",
+					vdev_id);
+			return;
+		}
+	}
+
+	if (wma->ito_repeat_count) {
+		WMA_LOGI("Set ITO count to %d for vdevId %d",
+					wma->ito_repeat_count, vdev_id);
+
+		ret = wma_unified_set_sta_ps_param(wma->wmi_handle,
+			vdev_id,
+			WMI_STA_PS_PARAM_MAX_RESET_ITO_COUNT_ON_TIM_NO_TXRX,
+			wma->ito_repeat_count);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			WMA_LOGE("Set ITO count failed vdevId %d Error %d",
+								vdev_id, ret);
+			return;
+		}
+	}
+
+	/* power save request succeeded */
+	iface->in_bmps = true;
+}
+
+/**
+ * wma_disable_sta_ps_mode() - disable sta powersave params in fw
+ * @wma: wma handle
+ * @ps_req: power save request
+ *
+ * Return: none
+ */
+void wma_disable_sta_ps_mode(tp_wma_handle wma, tpDisablePsParams ps_req)
+{
+	QDF_STATUS ret;
+	uint32_t vdev_id = ps_req->sessionid;
+	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
+
+	WMA_LOGD("Disable Sta Mode Ps vdevId %d", vdev_id);
+
+	/* Disable Sta Mode Power save */
+	ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Disable Sta Mode Ps Failed vdevId %d", vdev_id);
+		return;
+	}
+	iface->in_bmps = false;
+
+	/* Disable UAPSD incase if additional Req came */
+	if (eSIR_ADDON_DISABLE_UAPSD == ps_req->psSetting) {
+		WMA_LOGD("Disable Uapsd vdevId %d", vdev_id);
+		ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
+				WMI_STA_PS_PARAM_UAPSD, 0);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			WMA_LOGE("Disable Uapsd Failed vdevId %d", vdev_id);
+			/*
+			 * Even this fails we can proceed as success
+			 * since we disabled powersave
+			 */
+		}
+	}
+}
+
+QDF_STATUS wma_set_qpower_config(uint8_t vdev_id, uint8_t qpower)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	WMA_LOGI("configuring qpower: %d", qpower);
+	wma->powersave_mode = qpower;
+	return wma_unified_set_sta_ps_param(wma->wmi_handle,
+					    vdev_id,
+					    WMI_STA_PS_ENABLE_QPOWER,
+					    wma_get_qpower_config(wma));
+}
+
+/**
+ * wma_enable_uapsd_mode() - enable uapsd mode in fw
+ * @wma: wma handle
+ * @ps_req: power save request
+ *
+ * Return: none
+ */
+void wma_enable_uapsd_mode(tp_wma_handle wma, tpEnableUapsdParams ps_req)
+{
+	QDF_STATUS ret;
+	uint32_t vdev_id = ps_req->sessionid;
+	uint32_t uapsd_val = 0;
+	enum powersave_qpower_mode qpower_config = wma_get_qpower_config(wma);
+	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
+
+	if (!iface->handle) {
+		WMA_LOGE("vdev id %d is not active", vdev_id);
+		return;
+	}
+
+	/* Disable Sta Mode Power save */
+	ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Disable Sta Mode Ps Failed vdevId %d", vdev_id);
+		return;
+	}
+
+	uapsd_val = wma_get_uapsd_mask(&ps_req->uapsdParams);
+
+	WMA_LOGD("Enable Uapsd vdevId %d Mask %d", vdev_id, uapsd_val);
+	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
+			WMI_STA_PS_PARAM_UAPSD, uapsd_val);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Enable Uapsd Failed vdevId %d", vdev_id);
+		return;
+	}
+
+	if (qpower_config && uapsd_val) {
+		qpower_config = 0;
+		WMA_LOGD("Disable Qpower %d", vdev_id);
+	}
+	iface->uapsd_cached_val = uapsd_val;
+	WMA_LOGD("Enable Forced Sleep vdevId %d", vdev_id);
+	ret = wma_set_force_sleep(wma, vdev_id, true,
+			qpower_config, ps_req->uapsdParams.enable_ps);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Enable Forced Sleep Failed vdevId %d", vdev_id);
+		return;
+	}
+
+}
+
+/**
+ * wma_disable_uapsd_mode() - disable uapsd mode in fw
+ * @wma: wma handle
+ * @ps_req: power save request
+ *
+ * Return: none
+ */
+void wma_disable_uapsd_mode(tp_wma_handle wma,
+			    tpDisableUapsdParams ps_req)
+{
+	QDF_STATUS ret;
+	uint32_t vdev_id = ps_req->sessionid;
+	enum powersave_qpower_mode qpower_config = wma_get_qpower_config(wma);
+
+	WMA_LOGD("Disable Uapsd vdevId %d", vdev_id);
+
+	/* Disable Sta Mode Power save */
+	ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Disable Sta Mode Ps Failed vdevId %d", vdev_id);
+		return;
+	}
+
+	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
+			WMI_STA_PS_PARAM_UAPSD, 0);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Disable Uapsd Failed vdevId %d", vdev_id);
+		return;
+	}
+
+	/* Re enable Sta Mode Powersave with proper configuration */
+	ret = wma_set_force_sleep(wma, vdev_id, false,
+			qpower_config, true);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Disable Forced Sleep Failed vdevId %d", vdev_id);
+		return;
+	}
+}
+
+/**
+ * wma_set_sta_uapsd_auto_trig_cmd() - set uapsd auto trigger command
+ * @wmi_handle: wma handle
+ * @vdevid: vdev id
+ * @peer_addr: peer mac address
+ * @trig_param: auto trigger parameters
+ * @num_ac: number of access category
+ *
+ * This function sets the trigger
+ * uapsd params such as service interval, delay interval
+ * and suspend interval which will be used by the firmware
+ * to send trigger frames periodically when there is no
+ * traffic on the transmit side.
+ *
+ * Return: 0 for success or error code.
+ */
+static QDF_STATUS wma_set_sta_uapsd_auto_trig_cmd(wmi_unified_t wmi_handle,
+					uint32_t vdevid,
+					uint8_t peer_addr[IEEE80211_ADDR_LEN],
+					struct sta_uapsd_params *trig_param,
+					uint32_t num_ac)
+{
+	QDF_STATUS ret;
+	struct sta_uapsd_trig_params cmd = {0};
+
+	cmd.vdevid = vdevid;
+	cmd.auto_triggerparam = trig_param;
+	cmd.num_ac = num_ac;
+
+	qdf_mem_copy((uint8_t *) cmd.peer_addr, (uint8_t *) peer_addr,
+		     sizeof(uint8_t) * IEEE80211_ADDR_LEN);
+	ret = wmi_unified_set_sta_uapsd_auto_trig_cmd(wmi_handle,
+				   &cmd);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Failed to send set uapsd param ret = %d", ret);
+
+	return ret;
+}
+
+/**
+ * wma_trigger_uapsd_params() - set trigger uapsd parameter
+ * @wmi_handle: wma handle
+ * @vdev_id: vdev id
+ * @trigger_uapsd_params: trigger uapsd parameters
+ *
+ * This function sets the trigger uapsd
+ * params such as service interval, delay
+ * interval and suspend interval which
+ * will be used by the firmware to send
+ * trigger frames periodically when there
+ * is no traffic on the transmit side.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_trigger_uapsd_params(tp_wma_handle wma_handle, uint32_t vdev_id,
+				    tp_wma_trigger_uapsd_params
+				    trigger_uapsd_params)
+{
+	QDF_STATUS ret;
+	struct sta_uapsd_params uapsd_trigger_param;
+
+	WMA_LOGD("Trigger uapsd params vdev id %d", vdev_id);
+
+	WMA_LOGD("WMM AC %d User Priority %d SvcIntv %d DelIntv %d SusIntv %d",
+		 trigger_uapsd_params->wmm_ac,
+		 trigger_uapsd_params->user_priority,
+		 trigger_uapsd_params->service_interval,
+		 trigger_uapsd_params->delay_interval,
+		 trigger_uapsd_params->suspend_interval);
+
+	if (!wmi_service_enabled(wma_handle->wmi_handle,
+				    wmi_sta_uapsd_basic_auto_trig) ||
+	    !wmi_service_enabled(wma_handle->wmi_handle,
+				    wmi_sta_uapsd_var_auto_trig)) {
+		WMA_LOGD("Trigger uapsd is not supported vdev id %d", vdev_id);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	uapsd_trigger_param.wmm_ac = trigger_uapsd_params->wmm_ac;
+	uapsd_trigger_param.user_priority = trigger_uapsd_params->user_priority;
+	uapsd_trigger_param.service_interval =
+		trigger_uapsd_params->service_interval;
+	uapsd_trigger_param.suspend_interval =
+		trigger_uapsd_params->suspend_interval;
+	uapsd_trigger_param.delay_interval =
+		trigger_uapsd_params->delay_interval;
+
+	ret = wma_set_sta_uapsd_auto_trig_cmd(wma_handle->wmi_handle,
+			vdev_id, wma_handle->interfaces[vdev_id].bssid,
+			&uapsd_trigger_param, 1);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Fail to send uapsd param cmd for vdevid %d ret = %d",
+			 ret, vdev_id);
+		return ret;
+	}
+
+	return ret;
+}
+
+/**
+ * wma_disable_uapsd_per_ac() - disable uapsd per ac
+ * @wmi_handle: wma handle
+ * @vdev_id: vdev id
+ * @ac: access category
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_disable_uapsd_per_ac(tp_wma_handle wma_handle,
+				    uint32_t vdev_id, enum uapsd_ac ac)
+{
+	QDF_STATUS ret;
+	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
+	struct sta_uapsd_params uapsd_trigger_param;
+	enum uapsd_up user_priority;
+
+	WMA_LOGD("Disable Uapsd per ac vdevId %d ac %d", vdev_id, ac);
+
+	switch (ac) {
+	case UAPSD_VO:
+		iface->uapsd_cached_val &=
+			~(WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
+			  WMI_STA_PS_UAPSD_AC3_TRIGGER_EN);
+		user_priority = UAPSD_UP_VO;
+		break;
+	case UAPSD_VI:
+		iface->uapsd_cached_val &=
+			~(WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
+			  WMI_STA_PS_UAPSD_AC2_TRIGGER_EN);
+		user_priority = UAPSD_UP_VI;
+		break;
+	case UAPSD_BK:
+		iface->uapsd_cached_val &=
+			~(WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
+			  WMI_STA_PS_UAPSD_AC1_TRIGGER_EN);
+		user_priority = UAPSD_UP_BK;
+		break;
+	case UAPSD_BE:
+		iface->uapsd_cached_val &=
+			~(WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
+			  WMI_STA_PS_UAPSD_AC0_TRIGGER_EN);
+		user_priority = UAPSD_UP_BE;
+		break;
+	default:
+		WMA_LOGE("Invalid AC vdevId %d ac %d", vdev_id, ac);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Disable Auto Trigger Functionality before
+	 * disabling uapsd for a particular AC
+	 */
+	uapsd_trigger_param.wmm_ac = ac;
+	uapsd_trigger_param.user_priority = user_priority;
+	uapsd_trigger_param.service_interval = 0;
+	uapsd_trigger_param.suspend_interval = 0;
+	uapsd_trigger_param.delay_interval = 0;
+
+	ret = wma_set_sta_uapsd_auto_trig_cmd(wma_handle->wmi_handle,
+		vdev_id, wma_handle->interfaces[vdev_id].bssid,
+		&uapsd_trigger_param, 1);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Fail to send auto trig cmd for vdevid %d ret = %d",
+			 ret, vdev_id);
+		return ret;
+	}
+
+	ret = wma_unified_set_sta_ps_param(wma_handle->wmi_handle, vdev_id,
+					   WMI_STA_PS_PARAM_UAPSD,
+					   iface->uapsd_cached_val);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMA_LOGE("Disable Uapsd per ac Failed vdevId %d ac %d", vdev_id,
+			 ac);
+		return ret;
+	}
+	WMA_LOGD("Disable Uapsd per ac vdevId %d val %d", vdev_id,
+		 iface->uapsd_cached_val);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_get_temperature() - get pdev temperature req
+ * @wmi_handle: wma handle
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_get_temperature(tp_wma_handle wma_handle)
+{
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+
+	ret = wmi_unified_get_temperature(wma_handle->wmi_handle);
+	if (ret)
+		WMA_LOGE("Failed to send set Mimo PS ret = %d", ret);
+
+	return ret;
+}
+
+/**
+ * wma_pdev_temperature_evt_handler() - pdev temperature event handler
+ * @handle: wma handle
+ * @event: event buffer
+ * @len : length
+ *
+ * Return: 0 for success or error code.
+ */
+int wma_pdev_temperature_evt_handler(void *handle, uint8_t *event,
+				     uint32_t len)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg sme_msg = { 0 };
+	WMI_PDEV_TEMPERATURE_EVENTID_param_tlvs *param_buf;
+	wmi_pdev_temperature_event_fixed_param *wmi_event;
+
+	param_buf = (WMI_PDEV_TEMPERATURE_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("Invalid pdev_temperature event buffer");
+		return -EINVAL;
+	}
+
+	wmi_event = param_buf->fixed_param;
+	WMA_LOGI(FL("temperature: %d"), wmi_event->value);
+
+	sme_msg.type = eWNI_SME_MSG_GET_TEMPERATURE_IND;
+	sme_msg.bodyptr = NULL;
+	sme_msg.bodyval = wmi_event->value;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		WMA_LOGE(FL("Fail to post get temperature ind msg"));
+	return 0;
+}
+
+/**
+ * wma_process_tx_power_limits() - sends the power limits for 2g/5g to firmware
+ * @handle: wma handle
+ * @ptxlim: power limit value
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_process_tx_power_limits(WMA_HANDLE handle,
+				       tSirTxPowerLimit *ptxlim)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	int32_t ret = 0;
+	uint32_t txpower_params2g = 0;
+	uint32_t txpower_params5g = 0;
+	struct pdev_params pdevparam;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue tx power limit",
+			 __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	/* Set value and reason code for 2g and 5g power limit */
+
+	SET_PDEV_PARAM_TXPOWER_REASON(txpower_params2g,
+				      WMI_PDEV_PARAM_TXPOWER_REASON_SAR);
+	SET_PDEV_PARAM_TXPOWER_VALUE(txpower_params2g, ptxlim->txPower2g);
+
+	SET_PDEV_PARAM_TXPOWER_REASON(txpower_params5g,
+				      WMI_PDEV_PARAM_TXPOWER_REASON_SAR);
+	SET_PDEV_PARAM_TXPOWER_VALUE(txpower_params5g, ptxlim->txPower5g);
+
+	WMA_LOGD("%s: txpower2g: %x txpower5g: %x",
+		 __func__, txpower_params2g, txpower_params5g);
+
+	pdevparam.param_id = WMI_PDEV_PARAM_TXPOWER_LIMIT2G;
+	pdevparam.param_value = txpower_params2g;
+	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
+					 &pdevparam,
+					 WMA_WILDCARD_PDEV_ID);
+	if (ret) {
+		WMA_LOGE("%s: Failed to set txpower 2g (%d)", __func__, ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+	pdevparam.param_id = WMI_PDEV_PARAM_TXPOWER_LIMIT5G;
+	pdevparam.param_value = txpower_params5g;
+	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
+					 &pdevparam,
+					 WMA_WILDCARD_PDEV_ID);
+	if (ret) {
+		WMA_LOGE("%s: Failed to set txpower 5g (%d)", __func__, ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_add_p2p_ie() - add p2p IE
+ * @frm: ptr where p2p ie needs to add
+ *
+ * Return: ptr after p2p ie
+ */
+static uint8_t *wma_add_p2p_ie(uint8_t *frm)
+{
+	uint8_t wfa_oui[3] = WMA_P2P_WFA_OUI;
+	struct p2p_ie *p2p_ie = (struct p2p_ie *)frm;
+
+	p2p_ie->p2p_id = WMA_P2P_IE_ID;
+	p2p_ie->p2p_oui[0] = wfa_oui[0];
+	p2p_ie->p2p_oui[1] = wfa_oui[1];
+	p2p_ie->p2p_oui[2] = wfa_oui[2];
+	p2p_ie->p2p_oui_type = WMA_P2P_WFA_VER;
+	p2p_ie->p2p_len = 4;
+	return frm + sizeof(struct p2p_ie);
+}
+
+/**
+ * wma_update_beacon_noa_ie() - update beacon ie
+ * @bcn: beacon info
+ * @new_noa_sub_ie_len: ie length
+ *
+ * Return: none
+ */
+static void wma_update_beacon_noa_ie(struct beacon_info *bcn,
+				     uint16_t new_noa_sub_ie_len)
+{
+	struct p2p_ie *p2p_ie;
+	uint8_t *buf;
+
+	/* if there is nothing to add, just return */
+	if (new_noa_sub_ie_len == 0) {
+		if (bcn->noa_sub_ie_len && bcn->noa_ie) {
+			WMA_LOGD("%s: NoA is present in previous beacon, but not present in swba event, So Reset the NoA",
+				 __func__);
+			/* TODO: Assuming p2p noa ie is last ie in the beacon */
+			qdf_mem_zero(bcn->noa_ie, (bcn->noa_sub_ie_len +
+						   sizeof(struct p2p_ie)));
+			bcn->len -= (bcn->noa_sub_ie_len +
+				     sizeof(struct p2p_ie));
+			bcn->noa_ie = NULL;
+			bcn->noa_sub_ie_len = 0;
+		}
+		WMA_LOGD("%s: No need to update NoA", __func__);
+		return;
+	}
+
+	if (bcn->noa_sub_ie_len && bcn->noa_ie) {
+		/* NoA present in previous beacon, update it */
+		WMA_LOGD("%s: NoA present in previous beacon, update the NoA IE, bcn->len %u bcn->noa_sub_ie_len %u",
+			 __func__, bcn->len, bcn->noa_sub_ie_len);
+		bcn->len -= (bcn->noa_sub_ie_len + sizeof(struct p2p_ie));
+		qdf_mem_zero(bcn->noa_ie,
+			     (bcn->noa_sub_ie_len + sizeof(struct p2p_ie)));
+	} else {                /* NoA is not present in previous beacon */
+		WMA_LOGD("%s: NoA not present in previous beacon, add it bcn->len %u",
+			 __func__, bcn->len);
+		buf = qdf_nbuf_data(bcn->buf);
+		bcn->noa_ie = buf + bcn->len;
+	}
+
+	bcn->noa_sub_ie_len = new_noa_sub_ie_len;
+	wma_add_p2p_ie(bcn->noa_ie);
+	p2p_ie = (struct p2p_ie *)bcn->noa_ie;
+	p2p_ie->p2p_len += new_noa_sub_ie_len;
+	qdf_mem_copy((bcn->noa_ie + sizeof(struct p2p_ie)), bcn->noa_sub_ie,
+		     new_noa_sub_ie_len);
+
+	bcn->len += (new_noa_sub_ie_len + sizeof(struct p2p_ie));
+	WMA_LOGI("%s: Updated beacon length with NoA Ie is %u",
+		 __func__, bcn->len);
+}
+
+/**
+ * wma_p2p_create_sub_ie_noa() - put p2p noa ie
+ * @buf: buffer
+ * @noa: noa element ie
+ * @new_noa_sub_ie_len: ie length
+ *
+ * Return: none
+ */
+static void wma_p2p_create_sub_ie_noa(uint8_t *buf,
+				      struct p2p_sub_element_noa *noa,
+				      uint16_t *new_noa_sub_ie_len)
+{
+	uint8_t tmp_octet = 0;
+	int i;
+	uint8_t *buf_start = buf;
+
+	*buf++ = WMA_P2P_SUB_ELEMENT_NOA;       /* sub-element id */
+	ASSERT(noa->num_descriptors <= WMA_MAX_NOA_DESCRIPTORS);
+
+	/*
+	 * Length = (2 octets for Index and CTWin/Opp PS) and
+	 * (13 octets for each NOA Descriptors)
+	 */
+	P2PIE_PUT_LE16(buf, WMA_NOA_IE_SIZE(noa->num_descriptors));
+	buf += 2;
+
+	*buf++ = noa->index;    /* Instance Index */
+
+	tmp_octet = noa->ctwindow & WMA_P2P_NOA_IE_CTWIN_MASK;
+	if (noa->oppPS)
+		tmp_octet |= WMA_P2P_NOA_IE_OPP_PS_SET;
+	*buf++ = tmp_octet;     /* Opp Ps and CTWin capabilities */
+
+	for (i = 0; i < noa->num_descriptors; i++) {
+		ASSERT(noa->noa_descriptors[i].type_count != 0);
+
+		*buf++ = noa->noa_descriptors[i].type_count;
+
+		P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].duration);
+		buf += 4;
+		P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].interval);
+		buf += 4;
+		P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].start_time);
+		buf += 4;
+	}
+	*new_noa_sub_ie_len = (buf - buf_start);
+}
+
+/**
+ * wma_update_noa() - update noa params
+ * @beacon: beacon info
+ * @noa_ie: noa ie
+ *
+ * Return: none
+ */
+void wma_update_noa(struct beacon_info *beacon,
+		    struct p2p_sub_element_noa *noa_ie)
+{
+	uint16_t new_noa_sub_ie_len;
+
+	/* Call this function by holding the spinlock on beacon->lock */
+
+	if (noa_ie) {
+		if ((noa_ie->ctwindow == 0) && (noa_ie->oppPS == 0) &&
+		    (noa_ie->num_descriptors == 0)) {
+			/* NoA is not present */
+			WMA_LOGD("%s: NoA is not present", __func__);
+			new_noa_sub_ie_len = 0;
+		} else {
+			/* Create the binary blob containing NOA sub-IE */
+			WMA_LOGD("%s: Create NOA sub ie", __func__);
+			wma_p2p_create_sub_ie_noa(&beacon->noa_sub_ie[0],
+						  noa_ie, &new_noa_sub_ie_len);
+		}
+	} else {
+		WMA_LOGD("%s: No need to add NOA", __func__);
+		new_noa_sub_ie_len = 0; /* no NOA IE sub-attributes */
+	}
+
+	wma_update_beacon_noa_ie(beacon, new_noa_sub_ie_len);
+}
+
+/**
+ * wma_update_probe_resp_noa() - update noa IE in probe response
+ * @wma_handle: wma handle
+ * @noa_ie: noa ie
+ *
+ * Return: none
+ */
+void wma_update_probe_resp_noa(tp_wma_handle wma_handle,
+			       struct p2p_sub_element_noa *noa_ie)
+{
+	tSirP2PNoaAttr *noa_attr = qdf_mem_malloc(sizeof(tSirP2PNoaAttr));
+	WMA_LOGD("Received update NoA event");
+	if (!noa_attr)
+		return;
+
+	qdf_mem_zero(noa_attr, sizeof(tSirP2PNoaAttr));
+
+	noa_attr->index = noa_ie->index;
+	noa_attr->oppPsFlag = noa_ie->oppPS;
+	noa_attr->ctWin = noa_ie->ctwindow;
+	if (!noa_ie->num_descriptors) {
+		WMA_LOGD("Zero NoA descriptors");
+	} else {
+		WMA_LOGD("%d NoA descriptors", noa_ie->num_descriptors);
+		noa_attr->uNoa1IntervalCnt =
+			noa_ie->noa_descriptors[0].type_count;
+		noa_attr->uNoa1Duration = noa_ie->noa_descriptors[0].duration;
+		noa_attr->uNoa1Interval = noa_ie->noa_descriptors[0].interval;
+		noa_attr->uNoa1StartTime =
+			noa_ie->noa_descriptors[0].start_time;
+		if (noa_ie->num_descriptors > 1) {
+			noa_attr->uNoa2IntervalCnt =
+				noa_ie->noa_descriptors[1].type_count;
+			noa_attr->uNoa2Duration =
+				noa_ie->noa_descriptors[1].duration;
+			noa_attr->uNoa2Interval =
+				noa_ie->noa_descriptors[1].interval;
+			noa_attr->uNoa2StartTime =
+				noa_ie->noa_descriptors[1].start_time;
+		}
+	}
+	WMA_LOGI("Sending SIR_HAL_P2P_NOA_ATTR_IND to LIM");
+	wma_send_msg(wma_handle, SIR_HAL_P2P_NOA_ATTR_IND, (void *)noa_attr, 0);
+}
+
+/**
+ * wma_p2p_noa_event_handler() - p2p noa event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: length
+ *
+ * Return: 0 for success or error code.
+ */
+int wma_p2p_noa_event_handler(void *handle, uint8_t *event,
+			      uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_P2P_NOA_EVENTID_param_tlvs *param_buf;
+	wmi_p2p_noa_event_fixed_param *p2p_noa_event;
+	uint8_t vdev_id, i;
+	wmi_p2p_noa_info *p2p_noa_info;
+	struct p2p_sub_element_noa noa_ie;
+	uint8_t *buf_ptr;
+	uint32_t descriptors;
+
+	param_buf = (WMI_P2P_NOA_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("Invalid P2P NoA event buffer");
+		return -EINVAL;
+	}
+
+	p2p_noa_event = param_buf->fixed_param;
+	buf_ptr = (uint8_t *) p2p_noa_event;
+	buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param);
+	p2p_noa_info = (wmi_p2p_noa_info *) (buf_ptr);
+	vdev_id = p2p_noa_event->vdev_id;
+
+	if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) {
+
+		qdf_mem_zero(&noa_ie, sizeof(noa_ie));
+		noa_ie.index =
+			(uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info);
+		noa_ie.oppPS =
+			(uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info);
+		noa_ie.ctwindow =
+			(uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info);
+		descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info);
+		noa_ie.num_descriptors = (uint8_t) descriptors;
+
+		if (noa_ie.num_descriptors > WMA_MAX_NOA_DESCRIPTORS) {
+			WMA_LOGD("Sizing down the no of desc %d to max",
+					noa_ie.num_descriptors);
+			noa_ie.num_descriptors = WMA_MAX_NOA_DESCRIPTORS;
+		}
+		WMA_LOGD("%s: index %u, oppPs %u, ctwindow %u, num_desc = %u",
+			 __func__, noa_ie.index,
+			 noa_ie.oppPS, noa_ie.ctwindow, noa_ie.num_descriptors);
+		for (i = 0; i < noa_ie.num_descriptors; i++) {
+			noa_ie.noa_descriptors[i].type_count =
+				(uint8_t) p2p_noa_info->noa_descriptors[i].
+				type_count;
+			noa_ie.noa_descriptors[i].duration =
+				p2p_noa_info->noa_descriptors[i].duration;
+			noa_ie.noa_descriptors[i].interval =
+				p2p_noa_info->noa_descriptors[i].interval;
+			noa_ie.noa_descriptors[i].start_time =
+				p2p_noa_info->noa_descriptors[i].start_time;
+			WMA_LOGI("%s: NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
+				 __func__, i,
+				 noa_ie.noa_descriptors[i].type_count,
+				 noa_ie.noa_descriptors[i].duration,
+				 noa_ie.noa_descriptors[i].interval,
+				 noa_ie.noa_descriptors[i].start_time);
+		}
+
+		/* Send a msg to LIM to update the NoA IE in probe response
+		 * frames transmitted by the host
+		 */
+		wma_update_probe_resp_noa(wma, &noa_ie);
+	}
+
+	return 0;
+}
+
+/**
+ * wma_process_set_mimops_req() - Set the received MiMo PS state to firmware
+ * @handle: wma handle
+ * @mimops: MIMO powersave params
+ *
+ * Return: none
+ */
+void wma_process_set_mimops_req(tp_wma_handle wma_handle,
+				tSetMIMOPS *mimops)
+{
+	/* Translate to what firmware understands */
+	if (mimops->htMIMOPSState == eSIR_HT_MIMO_PS_DYNAMIC)
+		mimops->htMIMOPSState = WMI_PEER_MIMO_PS_DYNAMIC;
+	else if (mimops->htMIMOPSState == eSIR_HT_MIMO_PS_STATIC)
+		mimops->htMIMOPSState = WMI_PEER_MIMO_PS_STATIC;
+	else if (mimops->htMIMOPSState == eSIR_HT_MIMO_PS_NO_LIMIT)
+		mimops->htMIMOPSState = WMI_PEER_MIMO_PS_NONE;
+
+	WMA_LOGD("%s: htMIMOPSState = %d, sessionId = %d peerMac <%02x:%02x:%02x:%02x:%02x:%02x>",
+		 __func__,
+		 mimops->htMIMOPSState, mimops->sessionId, mimops->peerMac[0],
+		 mimops->peerMac[1], mimops->peerMac[2], mimops->peerMac[3],
+		 mimops->peerMac[4], mimops->peerMac[5]);
+
+	wma_set_peer_param(wma_handle, mimops->peerMac,
+			   WMI_PEER_MIMO_PS_STATE, mimops->htMIMOPSState,
+			   mimops->sessionId);
+}
+
+/**
+ * wma_set_mimops() - set MIMO powersave
+ * @handle: wma handle
+ * @vdev_id: vdev id
+ * @value: value
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_set_mimops(tp_wma_handle wma, uint8_t vdev_id, int value)
+{
+	QDF_STATUS ret;
+
+	ret = wmi_unified_set_mimops(wma->wmi_handle, vdev_id,
+				   value);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Failed to send set Mimo PS ret = %d", ret);
+
+	return ret;
+}
+
+/**
+ * wma_notify_modem_power_state() - notify modem power state
+ * @wma_ptr: wma handle
+ * @pReq: modem power state
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_notify_modem_power_state(void *wma_ptr,
+					tSirModemPowerStateInd *pReq)
+{
+	int32_t ret;
+	tp_wma_handle wma = (tp_wma_handle) wma_ptr;
+
+	WMA_LOGD("%s: WMA notify Modem Power State %d", __func__, pReq->param);
+
+	ret = wma_unified_modem_power_state(wma->wmi_handle, pReq->param);
+	if (ret) {
+		WMA_LOGE("%s: Fail to notify Modem Power State %d",
+			 __func__, pReq->param);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("Successfully notify Modem Power State %d", pReq->param);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_set_idle_ps_config() - enable/disble Low Power Support(Pdev Specific)
+ * @wma_ptr: wma handle
+ * @idle_ps: idle powersave
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_set_idle_ps_config(void *wma_ptr, uint32_t idle_ps)
+{
+	int32_t ret;
+	tp_wma_handle wma = (tp_wma_handle) wma_ptr;
+	struct pdev_params pdevparam;
+
+	WMA_LOGD("WMA Set Idle Ps Config [1:set 0:clear] val %d", idle_ps);
+
+	/* Set Idle Mode Power Save Config */
+	pdevparam.param_id = WMI_PDEV_PARAM_IDLE_PS_CONFIG;
+	pdevparam.param_value = idle_ps;
+	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
+					 &pdevparam,
+					 WMA_WILDCARD_PDEV_ID);
+
+	if (ret) {
+		WMA_LOGE("Fail to Set Idle Ps Config %d", idle_ps);
+		return QDF_STATUS_E_FAILURE;
+	}
+	wma->in_imps = !!idle_ps;
+
+	WMA_LOGD("Successfully Set Idle Ps Config %d", idle_ps);
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_set_smps_params() - set smps params
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @value: value
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_set_smps_params(tp_wma_handle wma, uint8_t vdev_id,
+			       int value)
+{
+	QDF_STATUS ret;
+
+	ret = wmi_unified_set_smps_params(wma->wmi_handle, vdev_id,
+				   value);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Failed to send set Mimo PS ret = %d", ret);
+
+	return ret;
+}
+
+#ifdef FEATURE_TX_POWER
+/**
+ * wma_set_tx_power_scale() - set tx power scale
+ * @vdev_id: vdev id
+ * @value: value
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_set_tx_power_scale(uint8_t vdev_id, int value)
+{
+	QDF_STATUS ret;
+	tp_wma_handle wma_handle =
+			(tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: wma_handle is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!wma_is_vdev_up(vdev_id)) {
+		WMA_LOGE("%s: vdev id %d is not up", __func__, vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
+				WMI_VDEV_PARAM_TXPOWER_SCALE, value);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Set tx power scale failed");
+
+	return ret;
+}
+
+/**
+ * wma_set_tx_power_scale_decr_db() - decrease power by DB value
+ * @vdev_id: vdev id
+ * @value: value
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code.
+ */
+QDF_STATUS wma_set_tx_power_scale_decr_db(uint8_t vdev_id, int value)
+{
+	QDF_STATUS ret;
+	tp_wma_handle wma_handle =
+			(tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: wma_handle is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!wma_is_vdev_up(vdev_id)) {
+		WMA_LOGE("%s: vdev id %d is not up", __func__, vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
+				WMI_VDEV_PARAM_TXPOWER_SCALE_DECR_DB, value);
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE("Decrease tx power value failed");
+
+	return ret;
+}
+#endif /* FEATURE_TX_POWER */
+
diff --git a/core/wma/src/wma_sar_public_structs.h b/core/wma/src/wma_sar_public_structs.h
new file mode 100644
index 0000000..f2b330b
--- /dev/null
+++ b/core/wma/src/wma_sar_public_structs.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef __WMA_SAR_PUBLIC_STRUCTS_H
+#define __WMA_SAR_PUBLIC_STRUCTS_H
+
+struct sar_limit_event;
+
+enum sar_version {
+	SAR_VERSION_1,
+	SAR_VERSION_2
+};
+
+/**
+ * typedef wma_sar_cb() - SAR callback function
+ * @context: Opaque context provided by caller in the original request
+ * @event: SAR limits event
+ */
+typedef void (*wma_sar_cb)(void *context, struct sar_limit_event *event);
+
+#endif /* __WMA_SAR_PUBLIC_STRUCTS_H */
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
new file mode 100644
index 0000000..eaa15fd
--- /dev/null
+++ b/core/wma/src/wma_scan_roam.c
@@ -0,0 +1,5112 @@
+/*
+ * Copyright (c) 2013-2018 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:    wma_scan_roam.c
+ *  This file contains functions related to scan and
+ *  roaming functionality.
+ */
+
+/* Header files */
+
+#include "wma.h"
+#include "wma_api.h"
+#include "cds_api.h"
+#include "wmi_unified_api.h"
+#include "wlan_qct_sys.h"
+#include "wni_api.h"
+#include "ani_global.h"
+#include "wmi_unified.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include <cdp_txrx_peer_ops.h>
+#include <cdp_txrx_cfg.h>
+
+#include "qdf_nbuf.h"
+#include "qdf_types.h"
+#include "qdf_mem.h"
+
+#include "wma_types.h"
+#include "lim_api.h"
+#include "lim_session_utils.h"
+
+#include "cds_utils.h"
+#include "wlan_policy_mgr_api.h"
+
+#if !defined(REMOVE_PKT_LOG)
+#include "pktlog_ac.h"
+#endif /* REMOVE_PKT_LOG */
+
+#include "dbglog_host.h"
+#include "csr_api.h"
+#include "ol_fw.h"
+
+#include "wma_internal.h"
+#include "wlan_tgt_def_config.h"
+#include "wlan_reg_services_api.h"
+#include "wlan_roam_debug.h"
+#include "wlan_mlme_public_struct.h"
+
+/* This is temporary, should be removed */
+#include "ol_htt_api.h"
+#include <cdp_txrx_handle.h>
+#include "wma_he.h"
+#include <wlan_scan_public_structs.h>
+#include <wlan_scan_ucfg_api.h>
+#include "wma_nan_datapath.h"
+#include "wlan_mlme_api.h"
+
+#define WMA_MCC_MIRACAST_REST_TIME 400
+#define WMA_SCAN_ID_MASK 0x0fff
+
+#ifdef FEATURE_WLAN_EXTSCAN
+/**
+ * enum extscan_report_events_type - extscan report events type
+ * @EXTSCAN_REPORT_EVENTS_BUFFER_FULL: report only when scan history is % full
+ * @EXTSCAN_REPORT_EVENTS_EACH_SCAN: report a scan completion event after scan
+ * @EXTSCAN_REPORT_EVENTS_FULL_RESULTS: forward scan results
+ *		(beacons/probe responses + IEs)
+ *		in real time to HAL, in addition to completion events.
+ *		Note: To keep backward compatibility,
+ *		fire completion events regardless of REPORT_EVENTS_EACH_SCAN.
+ * @EXTSCAN_REPORT_EVENTS_NO_BATCH: controls batching,
+ *		0 => batching, 1 => no batching
+ * @EXTSCAN_REPORT_EVENTS_CONTEXT_HUB: forward results to context hub
+ */
+enum extscan_report_events_type {
+	EXTSCAN_REPORT_EVENTS_BUFFER_FULL   = 0x00,
+	EXTSCAN_REPORT_EVENTS_EACH_SCAN     = 0x01,
+	EXTSCAN_REPORT_EVENTS_FULL_RESULTS  = 0x02,
+	EXTSCAN_REPORT_EVENTS_NO_BATCH      = 0x04,
+	EXTSCAN_REPORT_EVENTS_CONTEXT_HUB   = 0x08,
+};
+
+#define WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION WAKELOCK_DURATION_RECOMMENDED
+
+/*
+ * Maximum number of entires that could be present in the
+ * WMI_EXTSCAN_HOTLIST_MATCH_EVENT buffer from the firmware
+ */
+#define WMA_EXTSCAN_MAX_HOTLIST_ENTRIES 10
+#endif
+
+/**
+ * wma_update_channel_list() - update channel list
+ * @handle: wma handle
+ * @chan_list: channel list
+ *
+ * Function is used to update the support channel list in fw.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_update_channel_list(WMA_HANDLE handle,
+				   tSirUpdateChanList *chan_list)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	int i;
+	struct scan_chan_list_params scan_ch_param = {0};
+	wmi_channel_param *tchan_info;
+
+	scan_ch_param.chan_info = qdf_mem_malloc(sizeof(wmi_channel) *
+				 chan_list->numChan);
+	if (!scan_ch_param.chan_info)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_zero(scan_ch_param.chan_info, sizeof(wmi_channel) *
+				 chan_list->numChan);
+	WMA_LOGD("no of channels = %d", chan_list->numChan);
+	tchan_info = scan_ch_param.chan_info;
+	scan_ch_param.num_scan_chans = chan_list->numChan;
+	wma_handle->saved_chan.num_channels = chan_list->numChan;
+	WMA_LOGD("ht %d, vht %d, vht_24 %d", chan_list->ht_en,
+			chan_list->vht_en, chan_list->vht_24_en);
+
+	for (i = 0; i < chan_list->numChan; ++i) {
+		tchan_info->mhz =
+			cds_chan_to_freq(chan_list->chanParam[i].chanId);
+		tchan_info->band_center_freq1 =
+					  tchan_info->mhz;
+		tchan_info->band_center_freq2 = 0;
+		wma_handle->saved_chan.channel_list[i] =
+				chan_list->chanParam[i].chanId;
+
+		WMA_LOGD("chan[%d] = freq:%u chan:%d DFS:%d tx power:%d",
+			 i, tchan_info->mhz,
+			 chan_list->chanParam[i].chanId,
+			 chan_list->chanParam[i].dfsSet,
+			 chan_list->chanParam[i].pwr);
+
+		if (chan_list->chanParam[i].dfsSet) {
+			WMI_SET_CHANNEL_FLAG(tchan_info,
+					     WMI_CHAN_FLAG_PASSIVE);
+			WMI_SET_CHANNEL_FLAG(tchan_info,
+					     WMI_CHAN_FLAG_DFS);
+		}
+
+		if (tchan_info->mhz < WMA_2_4_GHZ_MAX_FREQ) {
+			WMI_SET_CHANNEL_MODE(tchan_info, MODE_11G);
+			if (chan_list->vht_en && chan_list->vht_24_en)
+				WMI_SET_CHANNEL_FLAG(tchan_info,
+						WMI_CHAN_FLAG_ALLOW_VHT);
+		} else {
+			WMI_SET_CHANNEL_MODE(tchan_info, MODE_11A);
+			if (chan_list->vht_en)
+				WMI_SET_CHANNEL_FLAG(tchan_info,
+					WMI_CHAN_FLAG_ALLOW_VHT);
+		}
+
+		if (chan_list->ht_en)
+			WMI_SET_CHANNEL_FLAG(tchan_info,
+					WMI_CHAN_FLAG_ALLOW_HT);
+
+		if (chan_list->chanParam[i].half_rate)
+			WMI_SET_CHANNEL_FLAG(tchan_info,
+				WMI_CHAN_FLAG_HALF_RATE);
+		else if (chan_list->chanParam[i].quarter_rate)
+			WMI_SET_CHANNEL_FLAG(tchan_info,
+				WMI_CHAN_FLAG_QUARTER_RATE);
+
+		WMI_SET_CHANNEL_MAX_TX_POWER(tchan_info,
+					     chan_list->chanParam[i].pwr);
+
+		WMI_SET_CHANNEL_REG_POWER(tchan_info,
+					  chan_list->chanParam[i].pwr);
+		tchan_info++;
+	}
+
+	qdf_status = wmi_unified_scan_chan_list_cmd_send(wma_handle->wmi_handle,
+				&scan_ch_param);
+
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		WMA_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
+
+	qdf_mem_free(scan_ch_param.chan_info);
+
+	return qdf_status;
+}
+
+QDF_STATUS wma_roam_scan_mawc_params(tp_wma_handle wma_handle,
+		tSirRoamOffloadScanReq *roam_req)
+{
+	struct wmi_mawc_roam_params *params;
+	QDF_STATUS status;
+
+	if (!roam_req) {
+		WMA_LOGE("No MAWC parameters to send");
+		return QDF_STATUS_E_INVAL;
+	}
+	params = qdf_mem_malloc(sizeof(*params));
+	if (!params)
+		return QDF_STATUS_E_NOMEM;
+
+	params->vdev_id = roam_req->sessionId;
+	params->enable = roam_req->mawc_roam_params.mawc_enabled &&
+		roam_req->mawc_roam_params.mawc_roam_enabled;
+	params->traffic_load_threshold =
+		roam_req->mawc_roam_params.mawc_roam_traffic_threshold;
+	params->best_ap_rssi_threshold =
+		roam_req->mawc_roam_params.mawc_roam_ap_rssi_threshold -
+		WMA_NOISE_FLOOR_DBM_DEFAULT;
+	params->rssi_stationary_high_adjust =
+		roam_req->mawc_roam_params.mawc_roam_rssi_high_adjust;
+	params->rssi_stationary_low_adjust =
+		roam_req->mawc_roam_params.mawc_roam_rssi_low_adjust;
+	status = wmi_unified_roam_mawc_params_cmd(
+			wma_handle->wmi_handle, params);
+	qdf_mem_free(params);
+
+	return status;
+}
+#ifdef WLAN_FEATURE_FILS_SK
+/**
+ * wma_roam_scan_fill_fils_params() - API to fill FILS params in RSO command
+ * @wma_handle: WMA handle
+ * @params: Pointer to destination RSO params to be filled
+ * @roam_req: Pointer to RSO params from CSR
+ *
+ * Return: None
+ */
+static void wma_roam_scan_fill_fils_params(tp_wma_handle wma_handle,
+					   struct roam_offload_scan_params
+					   *params, tSirRoamOffloadScanReq
+					   *roam_req)
+{
+	struct roam_fils_params *dst_fils_params, *src_fils_params;
+
+	if (!params || !roam_req || !roam_req->is_fils_connection) {
+		wma_err("Invalid input");
+		return;
+	}
+
+	src_fils_params = &roam_req->roam_fils_params;
+	dst_fils_params = &params->roam_fils_params;
+
+	params->add_fils_tlv = true;
+
+	dst_fils_params->username_length = src_fils_params->username_length;
+	qdf_mem_copy(dst_fils_params->username, src_fils_params->username,
+		     dst_fils_params->username_length);
+
+	dst_fils_params->next_erp_seq_num = src_fils_params->next_erp_seq_num;
+	dst_fils_params->rrk_length = src_fils_params->rrk_length;
+	qdf_mem_copy(dst_fils_params->rrk, src_fils_params->rrk,
+		     dst_fils_params->rrk_length);
+
+	dst_fils_params->rik_length = src_fils_params->rik_length;
+	qdf_mem_copy(dst_fils_params->rik, src_fils_params->rik,
+		     dst_fils_params->rik_length);
+
+	dst_fils_params->realm_len = src_fils_params->realm_len;
+	qdf_mem_copy(dst_fils_params->realm, src_fils_params->realm,
+		     dst_fils_params->realm_len);
+}
+#else
+static inline void wma_roam_scan_fill_fils_params(
+					tp_wma_handle wma_handle,
+					struct roam_offload_scan_params *params,
+					tSirRoamOffloadScanReq *roam_req)
+
+{ }
+#endif
+
+/**
+ * wma_roam_scan_offload_mode() - send roam scan mode request to fw
+ * @wma_handle: wma handle
+ * @scan_cmd_fp: start scan command ptr
+ * @roam_req: roam request param
+ * @mode: mode
+ * @vdev_id: vdev id
+ *
+ * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
+ * of WMI_ROAM_SCAN_MODE.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle,
+				      wmi_start_scan_cmd_fixed_param *
+				      scan_cmd_fp,
+				      tSirRoamOffloadScanReq *roam_req,
+				      uint32_t mode, uint32_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct roam_offload_scan_params *params =
+				qdf_mem_malloc(sizeof(*params));
+
+	if (!params)
+		return QDF_STATUS_E_NOMEM;
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	params->auth_mode = WMI_AUTH_NONE;
+	if (roam_req)
+		params->auth_mode = e_csr_auth_type_to_rsn_authmode
+				    (roam_req->ConnectedNetwork.authentication,
+				    roam_req->ConnectedNetwork.encryption);
+	WMA_LOGD("%s : auth mode = %d", __func__, params->auth_mode);
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+	params->is_roam_req_valid = 0;
+	params->mode = mode;
+	params->vdev_id = vdev_id;
+	if (roam_req) {
+		params->is_roam_req_valid = 1;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		params->roam_offload_enabled = roam_req->RoamOffloadEnabled;
+		params->roam_offload_params.ho_delay_for_rx =
+				roam_req->ho_delay_for_rx;
+		params->roam_offload_params.roam_preauth_retry_count =
+				roam_req->roam_preauth_retry_count;
+		params->roam_offload_params.roam_preauth_no_ack_timeout =
+				roam_req->roam_preauth_no_ack_timeout;
+		params->prefer_5ghz = roam_req->Prefer5GHz;
+		params->roam_rssi_cat_gap = roam_req->RoamRssiCatGap;
+		params->select_5ghz_margin = roam_req->Select5GHzMargin;
+		params->reassoc_failure_timeout =
+				roam_req->ReassocFailureTimeout;
+		params->rokh_id_length = roam_req->R0KH_ID_Length;
+		qdf_mem_copy(params->rokh_id, roam_req->R0KH_ID,
+				WMI_ROAM_R0KH_ID_MAX_LEN);
+		qdf_mem_copy(params->krk, roam_req->KRK, WMI_KRK_KEY_LEN);
+		qdf_mem_copy(params->btk, roam_req->BTK, WMI_BTK_KEY_LEN);
+		qdf_mem_copy(params->psk_pmk, roam_req->PSK_PMK,
+				WMI_ROAM_SCAN_PSK_SIZE);
+		params->pmk_len = roam_req->pmk_len;
+		params->roam_key_mgmt_offload_enabled =
+				roam_req->RoamKeyMgmtOffloadEnabled;
+		wma_roam_scan_fill_self_caps(wma_handle,
+			&params->roam_offload_params, roam_req);
+		params->fw_okc = roam_req->pmkid_modes.fw_okc;
+		params->fw_pmksa_cache = roam_req->pmkid_modes.fw_pmksa_cache;
+#endif
+		params->min_delay_btw_roam_scans =
+				roam_req->min_delay_btw_roam_scans;
+		params->roam_trigger_reason_bitmask =
+				roam_req->roam_trigger_reason_bitmask;
+		params->is_ese_assoc = roam_req->IsESEAssoc;
+		params->is_11r_assoc = roam_req->is_11r_assoc;
+		params->mdid.mdie_present = roam_req->MDID.mdiePresent;
+		params->mdid.mobility_domain = roam_req->MDID.mobilityDomain;
+		params->assoc_ie_length = roam_req->assoc_ie.length;
+		qdf_mem_copy(params->assoc_ie, roam_req->assoc_ie.addIEdata,
+						roam_req->assoc_ie.length);
+
+		wma_roam_scan_fill_fils_params(wma_handle, params, roam_req);
+	}
+
+	WMA_LOGD(FL("qos_caps: %d, qos_enabled: %d, ho_delay_for_rx: %d, roam_scan_mode: %d"),
+		params->roam_offload_params.qos_caps,
+		params->roam_offload_params.qos_enabled,
+		params->roam_offload_params.ho_delay_for_rx, params->mode);
+
+	WMA_LOGD(FL("min_delay_btw_roam_scans:%d, roam_tri_reason_bitmask:%d"),
+		 params->min_delay_btw_roam_scans,
+		 params->roam_trigger_reason_bitmask);
+
+	WMA_LOGD(FL("roam_preauth_retry_count: %d, roam_preauth_no_ack_timeout: %d"),
+		 params->roam_offload_params.roam_preauth_retry_count,
+		 params->roam_offload_params.roam_preauth_no_ack_timeout);
+
+	status = wmi_unified_roam_scan_offload_mode_cmd(wma_handle->wmi_handle,
+				scan_cmd_fp, params);
+	qdf_mem_free(params);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	WMA_LOGD("%s: WMA --> WMI_ROAM_SCAN_MODE", __func__);
+	return status;
+}
+
+/**
+ * wma_roam_scan_offload_rssi_threshold() - set scan offload rssi threashold
+ * @wma_handle: wma handle
+ * @roam_req:   Roaming request buffer
+ *
+ * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle,
+	tSirRoamOffloadScanReq *roam_req)
+{
+	struct roam_offload_scan_rssi_params params = {0};
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	int rssi_thresh, rssi_thresh_diff;
+	struct roam_ext_params *roam_params;
+	int32_t good_rssi_threshold;
+	uint32_t hirssi_scan_max_count;
+	uint32_t hirssi_scan_delta;
+	int32_t hirssi_upper_bound;
+
+	/* Send rssi threshold */
+	roam_params = &roam_req->roam_params;
+	rssi_thresh = roam_req->LookupThreshold - WMA_NOISE_FLOOR_DBM_DEFAULT;
+	rssi_thresh_diff = roam_req->OpportunisticScanThresholdDiff;
+	hirssi_scan_max_count = roam_req->hi_rssi_scan_max_count;
+	hirssi_scan_delta = roam_req->hi_rssi_scan_rssi_delta;
+	hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub -
+				     WMA_NOISE_FLOOR_DBM_DEFAULT;
+
+	/* fill in threshold values */
+	params.session_id = roam_req->sessionId;
+	params.rssi_thresh = rssi_thresh & 0x000000ff;
+	params.rssi_thresh_diff = rssi_thresh_diff & 0x000000ff;
+	params.hi_rssi_scan_max_count = hirssi_scan_max_count;
+	params.hi_rssi_scan_rssi_delta = hirssi_scan_delta;
+	params.hi_rssi_scan_rssi_ub = hirssi_upper_bound & 0x00000ff;
+	params.raise_rssi_thresh_5g = roam_params->raise_rssi_thresh_5g;
+	params.dense_rssi_thresh_offset =
+			 roam_params->dense_rssi_thresh_offset;
+	params.dense_min_aps_cnt = roam_params->dense_min_aps_cnt;
+	params.traffic_threshold =
+			roam_params->traffic_threshold;
+	params.initial_dense_status = roam_params->initial_dense_status;
+	params.bg_scan_bad_rssi_thresh = roam_params->bg_scan_bad_rssi_thresh -
+		WMA_NOISE_FLOOR_DBM_DEFAULT;
+	params.bg_scan_client_bitmap = roam_params->bg_scan_client_bitmap;
+	params.roam_bad_rssi_thresh_offset_2g =
+				roam_params->roam_bad_rssi_thresh_offset_2g;
+	if (params.roam_bad_rssi_thresh_offset_2g)
+		params.flags |= WMI_ROAM_BG_SCAN_FLAGS_2G_TO_5G_ONLY;
+
+	/*
+	 * The current Noise floor in firmware is -96dBm. Penalty/Boost
+	 * threshold is applied on a weaker signal to make it even more weaker.
+	 * So, there is a chance that the user may configure a very low
+	 * Penalty/Boost threshold beyond the noise floor. If that is the case,
+	 * then suppress the penalty/boost threshold to the noise floor.
+	 */
+	if (roam_params->raise_rssi_thresh_5g < WMA_NOISE_FLOOR_DBM_DEFAULT)
+		params.penalty_threshold_5g = 0;
+	else
+		params.boost_threshold_5g =
+			(roam_params->raise_rssi_thresh_5g -
+			 WMA_NOISE_FLOOR_DBM_DEFAULT) & 0x000000ff;
+	if (roam_params->drop_rssi_thresh_5g < WMA_NOISE_FLOOR_DBM_DEFAULT)
+		params.penalty_threshold_5g = 0;
+	else
+		params.penalty_threshold_5g =
+			(roam_params->drop_rssi_thresh_5g -
+			 WMA_NOISE_FLOOR_DBM_DEFAULT) & 0x000000ff;
+	params.raise_factor_5g = roam_params->raise_factor_5g;
+	params.drop_factor_5g = roam_params->drop_factor_5g;
+	params.max_raise_rssi_5g = roam_params->max_raise_rssi_5g;
+	params.max_drop_rssi_5g = roam_params->max_drop_rssi_5g;
+
+	if (roam_params->good_rssi_roam)
+		good_rssi_threshold = WMA_NOISE_FLOOR_DBM_DEFAULT;
+	else
+		good_rssi_threshold = 0;
+	params.good_rssi_threshold =
+	    (good_rssi_threshold - WMA_NOISE_FLOOR_DBM_DEFAULT) & 0x000000ff;
+
+	WMA_LOGD("WMA --> good_rssi_threshold=%d",
+		 params.good_rssi_threshold);
+
+	if (roam_req->early_stop_scan_enable) {
+		params.roam_earlystop_thres_min =
+			roam_req->early_stop_scan_min_threshold -
+			WMA_NOISE_FLOOR_DBM_DEFAULT;
+		params.roam_earlystop_thres_max =
+			roam_req->early_stop_scan_max_threshold -
+			WMA_NOISE_FLOOR_DBM_DEFAULT;
+	} else {
+		params.roam_earlystop_thres_min = 0;
+		params.roam_earlystop_thres_max = 0;
+	}
+	params.rssi_thresh_offset_5g =
+		roam_req->rssi_thresh_offset_5g;
+
+	WMA_LOGD("early_stop_thresholds en=%d, min=%d, max=%d",
+		roam_req->early_stop_scan_enable,
+		params.roam_earlystop_thres_min,
+		params.roam_earlystop_thres_max);
+	WMA_LOGD("rssi_thresh_offset_5g = %d", params.rssi_thresh_offset_5g);
+
+	status = wmi_unified_roam_scan_offload_rssi_thresh_cmd(
+			wma_handle->wmi_handle, &params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("roam_scan_offload_rssi_thresh_cmd failed %d", status);
+		return status;
+	}
+
+	WMA_LOGD(FL("roam_scan_rssi_thresh=%d, roam_rssi_thresh_diff=%d"),
+		rssi_thresh, rssi_thresh_diff);
+	WMA_LOGD(
+		FL("hirssi_scan max_count=%d, delta=%d, hirssi_upper_bound=%d"),
+		hirssi_scan_max_count, hirssi_scan_delta, hirssi_upper_bound);
+	WMA_LOGD(
+		FL("dense_rssi_thresh_offset=%d, dense_min_aps_cnt=%d, traffic_threshold=%d initial_dense_status=%d"),
+			roam_params->dense_rssi_thresh_offset,
+			roam_params->dense_min_aps_cnt,
+			roam_params->traffic_threshold,
+			roam_params->initial_dense_status);
+	WMA_LOGD(FL("BG Scan Bad RSSI:%d, bitmap:0x%x Offset for 2G to 5G Roam:%d"),
+			roam_params->bg_scan_bad_rssi_thresh,
+			roam_params->bg_scan_client_bitmap,
+			roam_params->roam_bad_rssi_thresh_offset_2g);
+	return status;
+}
+
+/**
+ * wma_roam_scan_offload_scan_period() - set roam offload scan period
+ * @wma_handle: wma handle
+ * @scan_period: scan period
+ * @scan_age: scan age
+ * @vdev_id: vdev id
+ *
+ * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_roam_scan_offload_scan_period(tp_wma_handle wma_handle,
+					     uint32_t scan_period,
+					     uint32_t scan_age,
+					     uint32_t vdev_id)
+{
+	return wmi_unified_roam_scan_offload_scan_period(wma_handle->wmi_handle,
+				  scan_period, scan_age, vdev_id);
+}
+
+/**
+ * wma_roam_scan_offload_rssi_change() - set roam offload RSSI change threshold
+ * @wma_handle: wma handle
+ * @rssi_change_thresh: RSSI Change threshold
+ * @bcn_rssi_weight: beacon RSSI weight
+ * @vdev_id: vdev id
+ *
+ * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_roam_scan_offload_rssi_change(tp_wma_handle wma_handle,
+	uint32_t vdev_id,
+	int32_t rssi_change_thresh,
+	uint32_t bcn_rssi_weight,
+	uint32_t hirssi_delay_btw_scans)
+{
+	int status;
+
+	status = wmi_unified_roam_scan_offload_rssi_change_cmd(
+				wma_handle->wmi_handle,
+				vdev_id, rssi_change_thresh,
+				bcn_rssi_weight, hirssi_delay_btw_scans);
+	if (status != EOK)
+		return QDF_STATUS_E_FAILURE;
+
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_roam_scan_offload_chan_list() - set roam offload channel list
+ * @wma_handle: wma handle
+ * @chan_count: channel count
+ * @chan_list: channel list
+ * @list_type: list type
+ * @vdev_id: vdev id
+ *
+ * Set roam offload channel list.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_roam_scan_offload_chan_list(tp_wma_handle wma_handle,
+					   uint8_t chan_count,
+					   uint8_t *chan_list,
+					   uint8_t list_type, uint32_t vdev_id)
+{
+	QDF_STATUS status;
+	int i;
+	uint32_t *chan_list_mhz;
+
+	if (chan_count == 0) {
+		WMA_LOGD("%s : invalid number of channels %d", __func__,
+			 chan_count);
+		return QDF_STATUS_E_EMPTY;
+	}
+	chan_list_mhz = qdf_mem_malloc(chan_count * sizeof(*chan_list_mhz));
+	if (!chan_list_mhz)
+		return QDF_STATUS_E_NOMEM;
+
+	for (i = 0; ((i < chan_count) &&
+		     (i < SIR_ROAM_MAX_CHANNELS)); i++) {
+		chan_list_mhz[i] = cds_chan_to_freq(chan_list[i]);
+		WMA_LOGD("%d,", chan_list_mhz[i]);
+	}
+
+	status = wmi_unified_roam_scan_offload_chan_list_cmd(
+					wma_handle->wmi_handle,
+					chan_count, chan_list_mhz,
+					list_type, vdev_id);
+	qdf_mem_free(chan_list_mhz);
+
+	return status;
+}
+
+/**
+ * e_csr_auth_type_to_rsn_authmode() - map csr auth type to rsn authmode
+ * @authtype: CSR authtype
+ * @encr: CSR Encryption
+ *
+ * Map CSR's authentication type into RSN auth mode used by firmware
+ *
+ * Return: WMI RSN auth mode
+ */
+A_UINT32 e_csr_auth_type_to_rsn_authmode(eCsrAuthType authtype,
+					 eCsrEncryptionType encr)
+{
+	switch (authtype) {
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		return WMI_AUTH_OPEN;
+	case eCSR_AUTH_TYPE_WPA:
+		return WMI_AUTH_WPA;
+	case eCSR_AUTH_TYPE_WPA_PSK:
+		return WMI_AUTH_WPA_PSK;
+	case eCSR_AUTH_TYPE_RSN:
+		return WMI_AUTH_RSNA;
+	case eCSR_AUTH_TYPE_RSN_PSK:
+		return WMI_AUTH_RSNA_PSK;
+	case eCSR_AUTH_TYPE_FT_RSN:
+		return WMI_AUTH_FT_RSNA;
+	case eCSR_AUTH_TYPE_FT_RSN_PSK:
+		return WMI_AUTH_FT_RSNA_PSK;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
+		return WMI_AUTH_WAPI;
+	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
+		return WMI_AUTH_WAPI_PSK;
+#endif /* FEATURE_WLAN_WAPI */
+#ifdef FEATURE_WLAN_ESE
+	case eCSR_AUTH_TYPE_CCKM_WPA:
+		return WMI_AUTH_CCKM_WPA;
+	case eCSR_AUTH_TYPE_CCKM_RSN:
+		return WMI_AUTH_CCKM_RSNA;
+#endif /* FEATURE_WLAN_ESE */
+#ifdef WLAN_FEATURE_11W
+	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+		return WMI_AUTH_RSNA_PSK_SHA256;
+	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
+		return WMI_AUTH_RSNA_8021X_SHA256;
+#endif /* WLAN_FEATURE_11W */
+	case eCSR_AUTH_TYPE_NONE:
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+		/* In case of WEP and other keys, NONE means OPEN auth */
+		if (encr == eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ||
+		    encr == eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ||
+		    encr == eCSR_ENCRYPT_TYPE_WEP40 ||
+		    encr == eCSR_ENCRYPT_TYPE_WEP104 ||
+		    encr == eCSR_ENCRYPT_TYPE_TKIP ||
+		    encr == eCSR_ENCRYPT_TYPE_AES ||
+		    encr == eCSR_ENCRYPT_TYPE_AES_GCMP ||
+		    encr == eCSR_ENCRYPT_TYPE_AES_GCMP_256) {
+			return WMI_AUTH_OPEN;
+		}
+		return WMI_AUTH_NONE;
+	case eCSR_AUTH_TYPE_FILS_SHA256:
+		return WMI_AUTH_RSNA_FILS_SHA256;
+	case eCSR_AUTH_TYPE_FILS_SHA384:
+		return WMI_AUTH_RSNA_FILS_SHA384;
+	case eCSR_AUTH_TYPE_SUITEB_EAP_SHA256:
+		return WMI_AUTH_RSNA_SUITE_B_8021X_SHA256;
+	case eCSR_AUTH_TYPE_SUITEB_EAP_SHA384:
+		return WMI_AUTH_RSNA_SUITE_B_8021X_SHA384;
+	default:
+		return WMI_AUTH_NONE;
+	}
+}
+
+/**
+ * e_csr_encryption_type_to_rsn_cipherset() - map csr enc type to ESN cipher
+ * @encr: CSR Encryption
+ *
+ * Map CSR's encryption type into RSN cipher types used by firmware
+ *
+ * Return: WMI RSN cipher
+ */
+A_UINT32 e_csr_encryption_type_to_rsn_cipherset(eCsrEncryptionType encr)
+{
+
+	switch (encr) {
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP40:
+	case eCSR_ENCRYPT_TYPE_WEP104:
+		return WMI_CIPHER_WEP;
+	case eCSR_ENCRYPT_TYPE_TKIP:
+		return WMI_CIPHER_TKIP;
+	case eCSR_ENCRYPT_TYPE_AES:
+		return WMI_CIPHER_AES_CCM;
+	/* FWR will use key length to distinguish GCMP 128 or 256 */
+	case eCSR_ENCRYPT_TYPE_AES_GCMP:
+	case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
+		return WMI_CIPHER_AES_GCM;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_ENCRYPT_TYPE_WPI:
+		return WMI_CIPHER_WAPI;
+#endif /* FEATURE_WLAN_WAPI */
+	case eCSR_ENCRYPT_TYPE_ANY:
+		return WMI_CIPHER_ANY;
+	case eCSR_ENCRYPT_TYPE_NONE:
+	default:
+		return WMI_CIPHER_NONE;
+	}
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * wma_roam_scan_get_cckm_mode() - Get the CCKM auth mode
+ * @roam_req: Roaming request buffer
+ * @auth_mode: Auth mode to be converted
+ *
+ * Based on LFR2.0 or LFR3.0, return the proper auth type
+ *
+ * Return: if LFR2.0, then return WMI_AUTH_CCKM for backward compatibility
+ *         if LFR3.0 then return the appropriate auth type
+ */
+static uint32_t wma_roam_scan_get_cckm_mode(tSirRoamOffloadScanReq *roam_req,
+		uint32_t auth_mode)
+{
+	if (roam_req->RoamOffloadEnabled)
+		return auth_mode;
+	else
+		return WMI_AUTH_CCKM;
+
+}
+#endif
+/**
+ * wma_roam_scan_fill_ap_profile() - fill ap_profile
+ * @roam_req: roam offload scan request
+ * @profile: ap profile
+ *
+ * Fill ap_profile structure from configured parameters
+ *
+ * Return: none
+ */
+static void wma_roam_scan_fill_ap_profile(tSirRoamOffloadScanReq *roam_req,
+					  struct ap_profile *profile)
+{
+	uint32_t rsn_authmode;
+
+	qdf_mem_zero(profile, sizeof(*profile));
+	if (roam_req == NULL) {
+		profile->ssid.length = 0;
+		profile->ssid.mac_ssid[0] = 0;
+		profile->rsn_authmode = WMI_AUTH_NONE;
+		profile->rsn_ucastcipherset = WMI_CIPHER_NONE;
+		profile->rsn_mcastcipherset = WMI_CIPHER_NONE;
+		profile->rsn_mcastmgmtcipherset = WMI_CIPHER_NONE;
+		profile->rssi_threshold = WMA_ROAM_RSSI_DIFF_DEFAULT;
+	} else {
+		profile->ssid.length =
+			roam_req->ConnectedNetwork.ssId.length;
+		qdf_mem_copy(profile->ssid.mac_ssid,
+			     roam_req->ConnectedNetwork.ssId.ssId,
+			     profile->ssid.length);
+		profile->rsn_authmode =
+			e_csr_auth_type_to_rsn_authmode(
+				roam_req->ConnectedNetwork.authentication,
+				roam_req->ConnectedNetwork.encryption);
+		rsn_authmode = profile->rsn_authmode;
+
+		if ((rsn_authmode == WMI_AUTH_CCKM_WPA) ||
+			(rsn_authmode == WMI_AUTH_CCKM_RSNA))
+			profile->rsn_authmode =
+				wma_roam_scan_get_cckm_mode(
+						roam_req, rsn_authmode);
+		profile->rsn_ucastcipherset =
+			e_csr_encryption_type_to_rsn_cipherset(
+					roam_req->ConnectedNetwork.encryption);
+		profile->rsn_mcastcipherset =
+			e_csr_encryption_type_to_rsn_cipherset(
+				roam_req->ConnectedNetwork.mcencryption);
+		profile->rsn_mcastmgmtcipherset =
+			profile->rsn_mcastcipherset;
+		profile->rssi_threshold = roam_req->RoamRssiDiff;
+		if (roam_req->rssi_abs_thresh)
+			profile->rssi_abs_thresh =
+				roam_req->rssi_abs_thresh -
+						WMA_NOISE_FLOOR_DBM_DEFAULT;
+#ifdef WLAN_FEATURE_11W
+		if (roam_req->ConnectedNetwork.mfp_enabled)
+			profile->flags |= WMI_AP_PROFILE_FLAG_PMF;
+#endif
+	}
+}
+
+/**
+ * wma_process_set_pdev_ie_req() - process the pdev set IE req
+ * @wma: Pointer to wma handle
+ * @ie_params: Pointer to IE data.
+ *
+ * Sends the WMI req to set the IE to FW.
+ *
+ * Return: None
+ */
+void wma_process_set_pdev_ie_req(tp_wma_handle wma,
+		struct set_ie_param *ie_params)
+{
+	if (ie_params->ie_type == DOT11_HT_IE)
+		wma_process_set_pdev_ht_ie_req(wma, ie_params);
+	if (ie_params->ie_type == DOT11_VHT_IE)
+		wma_process_set_pdev_vht_ie_req(wma, ie_params);
+
+	qdf_mem_free(ie_params->ie_ptr);
+}
+
+/**
+ * wma_process_set_pdev_ht_ie_req() - sends HT IE data to FW
+ * @wma: Pointer to wma handle
+ * @ie_params: Pointer to IE data.
+ * @nss: Nss values to prepare the HT IE.
+ *
+ * Sends the WMI req to set the HT IE to FW.
+ *
+ * Return: None
+ */
+void wma_process_set_pdev_ht_ie_req(tp_wma_handle wma,
+		struct set_ie_param *ie_params)
+{
+	int ret;
+	wmi_pdev_set_ht_ie_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint16_t len;
+	uint16_t ie_len_pad;
+	uint8_t *buf_ptr;
+
+	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
+	ie_len_pad = roundup(ie_params->ie_len, sizeof(uint32_t));
+	len += ie_len_pad;
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return;
+
+	cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+			       wmi_pdev_set_ht_ie_cmd_fixed_param));
+	cmd->reserved0 = 0;
+	cmd->ie_len = ie_params->ie_len;
+	cmd->tx_streams = ie_params->nss;
+	cmd->rx_streams = ie_params->nss;
+	WMA_LOGD("Setting pdev HT ie with Nss = %u",
+			ie_params->nss);
+	buf_ptr = (uint8_t *)cmd + sizeof(*cmd);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_pad);
+	if (ie_params->ie_len) {
+		qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
+			     (uint8_t *)ie_params->ie_ptr,
+			     ie_params->ie_len);
+	}
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+					WMI_PDEV_SET_HT_CAP_IE_CMDID);
+	if (ret != EOK)
+		wmi_buf_free(buf);
+}
+
+/**
+ * wma_process_set_pdev_vht_ie_req() - sends VHT IE data to FW
+ * @wma: Pointer to wma handle
+ * @ie_params: Pointer to IE data.
+ * @nss: Nss values to prepare the VHT IE.
+ *
+ * Sends the WMI req to set the VHT IE to FW.
+ *
+ * Return: None
+ */
+void wma_process_set_pdev_vht_ie_req(tp_wma_handle wma,
+		struct set_ie_param *ie_params)
+{
+	int ret;
+	wmi_pdev_set_vht_ie_cmd_fixed_param *cmd;
+	wmi_buf_t buf;
+	uint16_t len;
+	uint16_t ie_len_pad;
+	uint8_t *buf_ptr;
+
+	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
+	ie_len_pad = roundup(ie_params->ie_len, sizeof(uint32_t));
+	len += ie_len_pad;
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return;
+
+	cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+			WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param,
+			WMITLV_GET_STRUCT_TLVLEN(
+				wmi_pdev_set_vht_ie_cmd_fixed_param));
+	cmd->reserved0 = 0;
+	cmd->ie_len = ie_params->ie_len;
+	cmd->tx_streams = ie_params->nss;
+	cmd->rx_streams = ie_params->nss;
+	WMA_LOGD("Setting pdev VHT ie with Nss = %u",
+			ie_params->nss);
+	buf_ptr = (uint8_t *)cmd + sizeof(*cmd);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_pad);
+	if (ie_params->ie_len) {
+		qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
+				(uint8_t *)ie_params->ie_ptr,
+				ie_params->ie_len);
+	}
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+			WMI_PDEV_SET_VHT_CAP_IE_CMDID);
+	if (ret != EOK)
+		wmi_buf_free(buf);
+}
+
+/**
+ * wma_roam_scan_scan_params() - fill roam scan params
+ * @wma_handle: wma handle
+ * @pMac: Mac ptr
+ * @scan_params: scan parameters
+ * @roam_req: NULL if this routine is called before connect
+ *            It will be non-NULL if called after assoc.
+ *
+ * Fill scan_params structure from configured parameters
+ *
+ * Return: none
+ */
+void wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle,
+				    tpAniSirGlobal pMac,
+				    tSirRoamOffloadScanReq *roam_req,
+				    wmi_start_scan_cmd_fixed_param *
+				    scan_params)
+{
+	uint8_t channels_per_burst = 0;
+	uint32_t val = 0;
+
+	if (NULL == pMac) {
+		WMA_LOGE("%s: pMac is NULL", __func__);
+		return;
+	}
+
+	qdf_mem_zero(scan_params, sizeof(wmi_start_scan_cmd_fixed_param));
+	scan_params->scan_ctrl_flags = WMI_SCAN_ADD_CCK_RATES |
+				       WMI_SCAN_ADD_OFDM_RATES |
+				       WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
+	if (roam_req != NULL) {
+		/* Parameters updated after association is complete */
+		WMA_LOGD("%s: NeighborScanChannelMinTime: %d NeighborScanChannelMaxTime: %d",
+			 __func__,
+			 roam_req->NeighborScanChannelMinTime,
+			 roam_req->NeighborScanChannelMaxTime);
+		WMA_LOGD("%s: NeighborScanTimerPeriod: %d "
+			 "neighbor_scan_min_timer_period %d "
+			 "HomeAwayTime: %d nProbes: %d",
+			 __func__,
+			 roam_req->NeighborScanTimerPeriod,
+			 roam_req->neighbor_scan_min_timer_period,
+			 roam_req->HomeAwayTime, roam_req->nProbes);
+
+		/*
+		 * roam_req->NeighborScanChannelMaxTime = SCAN_CHANNEL_TIME
+		 * roam_req->HomeAwayTime               = SCAN_HOME_AWAY_TIME
+		 * roam_req->NeighborScanTimerPeriod    = SCAN_HOME_TIME
+		 *
+		 * scan_params->dwell_time_active :time station stays on channel
+		 *                                   and sends probes;
+		 * scan_params->dwell_time_passive:time station stays on channel
+		 *                                   and listens probes;
+		 * scan_params->burst_duration    :time station goes off channel
+		 *                                   to scan;
+		 */
+
+		if (wlan_cfg_get_int
+			    (pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
+			    &val) != QDF_STATUS_SUCCESS) {
+			/*
+			 * Could not get max channel value from CFG. Log error.
+			 */
+			WMA_LOGE("could not retrieve passive max channel value");
+
+			/* use a default value of 110ms */
+			val = WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT;
+		}
+
+		scan_params->dwell_time_passive = val;
+		/*
+		 * Here is the formula,
+		 * T(HomeAway) = N * T(dwell) + (N+1) * T(cs)
+		 * where N is number of channels scanned in single burst
+		 */
+		scan_params->dwell_time_active =
+			roam_req->NeighborScanChannelMaxTime;
+		if (roam_req->HomeAwayTime <
+		    2 * WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME) {
+			/* clearly we can't follow home away time.
+			 * Make it a split scan.
+			 */
+			scan_params->burst_duration = 0;
+		} else {
+			channels_per_burst =
+				(roam_req->HomeAwayTime -
+				 WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME)
+				/ (scan_params->dwell_time_active +
+				   WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME);
+
+			if (channels_per_burst < 1) {
+				/* dwell time and home away time conflicts */
+				/* we will override dwell time */
+				scan_params->dwell_time_active =
+					roam_req->HomeAwayTime -
+					2 * WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME;
+				scan_params->burst_duration =
+					scan_params->dwell_time_active;
+			} else {
+				scan_params->burst_duration =
+					channels_per_burst *
+					scan_params->dwell_time_active;
+			}
+		}
+		if (roam_req->allowDFSChannelRoam ==
+		    SIR_ROAMING_DFS_CHANNEL_ENABLED_NORMAL
+		    && roam_req->HomeAwayTime > 0
+		    && roam_req->ChannelCacheType != CHANNEL_LIST_STATIC) {
+			/* Roaming on DFS channels is supported and it is not
+			 * app channel list. It is ok to override homeAwayTime
+			 * to accommodate DFS dwell time in burst
+			 * duration.
+			 */
+			scan_params->burst_duration =
+				QDF_MAX(scan_params->burst_duration,
+					scan_params->dwell_time_passive);
+		}
+		scan_params->min_rest_time =
+			roam_req->neighbor_scan_min_timer_period;
+		scan_params->max_rest_time = roam_req->NeighborScanTimerPeriod;
+		scan_params->repeat_probe_time = (roam_req->nProbes > 0) ?
+				 QDF_MAX(scan_params->dwell_time_active /
+						roam_req->nProbes, 1) : 0;
+		scan_params->probe_spacing_time = 0;
+		scan_params->probe_delay = 0;
+		/* 30 seconds for full scan cycle */
+		scan_params->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION;
+		scan_params->idle_time = scan_params->min_rest_time;
+		scan_params->n_probes = roam_req->nProbes;
+		if (roam_req->allowDFSChannelRoam ==
+		    SIR_ROAMING_DFS_CHANNEL_DISABLED) {
+			scan_params->scan_ctrl_flags |= WMI_SCAN_BYPASS_DFS_CHN;
+		} else {
+			/* Roaming scan on DFS channel is allowed.
+			 * No need to change any flags for default
+			 * allowDFSChannelRoam = 1.
+			 * Special case where static channel list is given by\
+			 * application that contains DFS channels.
+			 * Assume that the application has knowledge of matching
+			 * APs being active and that probe request transmission
+			 * is permitted on those channel.
+			 * Force active scans on those channels.
+			 */
+
+			if (roam_req->allowDFSChannelRoam ==
+			    SIR_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE &&
+			    roam_req->ChannelCacheType == CHANNEL_LIST_STATIC &&
+			    roam_req->ConnectedNetwork.ChannelCount > 0) {
+				scan_params->scan_ctrl_flags |=
+					WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS;
+			}
+		}
+		WMI_SCAN_SET_DWELL_MODE(scan_params->scan_ctrl_flags,
+				roam_req->roamscan_adaptive_dwell_mode);
+
+	} else {
+		/* roam_req = NULL during initial or pre-assoc invocation */
+		scan_params->dwell_time_active =
+			WMA_ROAM_DWELL_TIME_ACTIVE_DEFAULT;
+		scan_params->dwell_time_passive =
+			WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT;
+		scan_params->min_rest_time = WMA_ROAM_MIN_REST_TIME_DEFAULT;
+		scan_params->max_rest_time = WMA_ROAM_MAX_REST_TIME_DEFAULT;
+		scan_params->repeat_probe_time = 0;
+		scan_params->probe_spacing_time = 0;
+		scan_params->probe_delay = 0;
+		scan_params->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION;
+		scan_params->idle_time = scan_params->min_rest_time;
+		scan_params->burst_duration = 0;
+		scan_params->n_probes = 0;
+	}
+
+	WMA_LOGD("%s: Rome roam scan parameters:  dwell_time_active = %d, dwell_time_passive = %d",
+		 __func__, scan_params->dwell_time_active,
+		 scan_params->dwell_time_passive);
+	WMA_LOGD("%s: min_rest_time = %d, max_rest_time = %d, repeat_probe_time = %d n_probes = %d",
+		 __func__, scan_params->min_rest_time,
+		 scan_params->max_rest_time,
+		 scan_params->repeat_probe_time, scan_params->n_probes);
+	WMA_LOGD("%s: max_scan_time = %d, idle_time = %d, burst_duration = %d, scan_ctrl_flags = 0x%x",
+		 __func__, scan_params->max_scan_time, scan_params->idle_time,
+		 scan_params->burst_duration, scan_params->scan_ctrl_flags);
+}
+
+/**
+ * wma_roam_scan_offload_ap_profile() - set roam ap profile in fw
+ * @wma_handle: wma handle
+ * @mac_ctx: Mac ptr
+ * @roam_req: Request which contains the ap profile
+ *
+ * Send WMI_ROAM_AP_PROFILE to firmware
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_roam_scan_offload_ap_profile(tp_wma_handle wma_handle,
+				tSirRoamOffloadScanReq *roam_req)
+{
+	struct ap_profile_params ap_profile;
+
+	ap_profile.vdev_id = roam_req->sessionId;
+	wma_roam_scan_fill_ap_profile(roam_req, &ap_profile.profile);
+	ap_profile.param = roam_req->score_params;
+	return wmi_unified_send_roam_scan_offload_ap_cmd(wma_handle->wmi_handle,
+							 &ap_profile);
+}
+
+/**
+ * wma_roam_scan_filter() - Filter to be applied while roaming
+ * @wma_handle:     Global WMA Handle
+ * @roam_req:       Request which contains the filters
+ *
+ * There are filters such as whitelist, blacklist and preferred
+ * list that need to be applied to the scan results to form the
+ * probable candidates for roaming.
+ *
+ * Return: Return success upon successfully passing the
+ *         parameters to the firmware, otherwise failure.
+ */
+static QDF_STATUS wma_roam_scan_filter(tp_wma_handle wma_handle,
+				       tSirRoamOffloadScanReq *roam_req)
+{
+	int i;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t num_bssid_black_list = 0, num_ssid_white_list = 0,
+	   num_bssid_preferred_list = 0,  num_rssi_rejection_ap = 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)
+		return QDF_STATUS_E_NOMEM;
+
+	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;
+			break;
+		case REASON_ROAM_SET_SSID_ALLOWED:
+			op_bitmap |= 0x2;
+			num_ssid_white_list =
+				roam_params->num_ssid_allowed_list;
+			break;
+		case REASON_ROAM_SET_FAVORED_BSSID:
+			op_bitmap |= 0x4;
+			num_bssid_preferred_list =
+				roam_params->num_bssid_favored;
+			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 |
+					ROAM_FILTER_OP_BITMAP_RSSI_REJECTION_OCE;
+				num_rssi_rejection_ap =
+					roam_params->num_rssi_rejection_ap;
+			} 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__);
+			qdf_mem_free(params);
+			return QDF_STATUS_SUCCESS;
+		}
+	} else {
+		/* In case of STOP command, reset all the variables
+		 * except for blacklist BSSID which should be retained
+		 * across connections.
+		 */
+		op_bitmap = 0x2 | 0x4;
+		num_ssid_white_list = roam_params->num_ssid_allowed_list;
+		num_bssid_preferred_list = roam_params->num_bssid_favored;
+	}
+
+	/* fill in fixed values */
+	params->session_id = roam_req->sessionId;
+	params->op_bitmap = op_bitmap;
+	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->num_rssi_rejection_ap = num_rssi_rejection_ap;
+	qdf_mem_copy(params->bssid_avoid_list, roam_params->bssid_avoid_list,
+			MAX_BSSID_AVOID_LIST * sizeof(struct qdf_mac_addr));
+
+	for (i = 0; i < num_ssid_white_list; i++) {
+		qdf_mem_copy(params->ssid_allowed_list[i].mac_ssid,
+				roam_params->ssid_allowed_list[i].ssId,
+			roam_params->ssid_allowed_list[i].length);
+		params->ssid_allowed_list[i].length =
+				roam_params->ssid_allowed_list[i].length;
+		WMA_LOGD("%s: SSID length=%d", __func__,
+				params->ssid_allowed_list[i].length);
+		qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
+			(uint8_t *)params->ssid_allowed_list[i].mac_ssid,
+			params->ssid_allowed_list[i].length);
+	}
+	qdf_mem_copy(params->bssid_favored, roam_params->bssid_favored,
+			MAX_BSSID_FAVORED * sizeof(struct qdf_mac_addr));
+	qdf_mem_copy(params->bssid_favored_factor,
+			roam_params->bssid_favored_factor, MAX_BSSID_FAVORED);
+	qdf_mem_copy(params->rssi_rejection_ap,
+		roam_params->rssi_rejection_ap,
+		MAX_RSSI_AVOID_BSSID_LIST *
+		sizeof(struct rssi_disallow_bssid));
+
+	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);
+
+	qdf_mem_free(params);
+	return status;
+}
+
+/**
+ * wma_roam_scan_bmiss_cnt() - set bmiss count to fw
+ * @wma_handle: wma handle
+ * @first_bcnt: first bmiss count
+ * @final_bcnt: final bmiss count
+ * @vdev_id: vdev id
+ *
+ * set first & final biss count to fw.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_roam_scan_bmiss_cnt(tp_wma_handle wma_handle,
+				   A_INT32 first_bcnt,
+				   A_UINT32 final_bcnt, uint32_t vdev_id)
+{
+	QDF_STATUS status;
+
+	WMA_LOGD("%s: first_bcnt: %d, final_bcnt: %d", __func__, first_bcnt,
+		 final_bcnt);
+
+	status = wma_vdev_set_param(wma_handle->wmi_handle,
+				vdev_id, WMI_VDEV_PARAM_BMISS_FIRST_BCNT,
+				first_bcnt);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("wma_vdev_set_param WMI_VDEV_PARAM_BMISS_FIRST_BCNT returned Error %d",
+			status);
+		return status;
+	}
+
+	status = wma_vdev_set_param(wma_handle->wmi_handle,
+				vdev_id, WMI_VDEV_PARAM_BMISS_FINAL_BCNT,
+				final_bcnt);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("wma_vdev_set_param WMI_VDEV_PARAM_BMISS_FINAL_BCNT returned Error %d",
+			status);
+		return status;
+	}
+
+	return status;
+}
+
+/**
+ * wma_roam_scan_offload_command() - set roam offload command
+ * @wma_handle: wma handle
+ * @command: command
+ * @vdev_id: vdev id
+ *
+ * This function set roam offload command to fw.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_roam_scan_offload_command(tp_wma_handle wma_handle,
+					 uint32_t command, uint32_t vdev_id)
+{
+	return wmi_unified_roam_scan_offload_cmd(wma_handle->wmi_handle,
+			  command, vdev_id);
+}
+
+/**
+ * wma_roam_scan_btm_offload() - Send BTM offload config
+ * @wma_handle: wma handle
+ * @roam_req: roam request parameters
+ *
+ * This function is used to send BTM offload config to fw
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS wma_roam_scan_btm_offload(tp_wma_handle wma_handle,
+					    tSirRoamOffloadScanReq *roam_req)
+{
+	struct wmi_btm_config *params;
+	QDF_STATUS status;
+
+	params = qdf_mem_malloc(sizeof(struct wmi_btm_config));
+	if (!params)
+		return QDF_STATUS_E_FAILURE;
+
+	params->vdev_id = roam_req->sessionId;
+	params->btm_offload_config = roam_req->btm_offload_config;
+	params->btm_solicited_timeout = roam_req->btm_solicited_timeout;
+	params->btm_max_attempt_cnt = roam_req->btm_max_attempt_cnt;
+	params->btm_sticky_time = roam_req->btm_sticky_time;
+
+	WMA_LOGD("%s: Sending BTM offload to FW for vdev %u btm_offload_config %u",
+		 __func__, params->vdev_id, params->btm_offload_config);
+
+	status = wmi_unified_send_btm_config(wma_handle->wmi_handle, params);
+	qdf_mem_free(params);
+
+
+	return status;
+}
+
+/**
+ * wma_send_offload_11k_params() - API to send 11k offload params to FW
+ * @handle: WMA handle
+ * @params: Pointer to 11k offload params
+ *
+ * Return: None
+ */
+static
+QDF_STATUS wma_send_offload_11k_params(WMA_HANDLE handle,
+				    struct wmi_11k_offload_params *params)
+{
+	QDF_STATUS status;
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, cannot send 11k offload cmd",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!wmi_service_enabled(wma_handle->wmi_handle,
+	    wmi_service_11k_neighbour_report_support)) {
+		WMA_LOGE(FL("FW doesn't support 11k offload"));
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	/*
+	 * If 11k enable command and ssid length is 0, drop it
+	 */
+	if (params->offload_11k_bitmask &&
+	    !params->neighbor_report_params.ssid.length) {
+		WMA_LOGD("%s: SSID Len 0", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_offload_11k_cmd(wma_handle->wmi_handle, params);
+
+	if (status != QDF_STATUS_SUCCESS)
+		WMA_LOGE("failed to send 11k offload command");
+
+	return status;
+}
+
+/**
+ * wma_process_roaming_config() - process roam request
+ * @wma_handle: wma handle
+ * @roam_req: roam request parameters
+ *
+ * Main routine to handle ROAM commands coming from CSR module.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle,
+				     tSirRoamOffloadScanReq *roam_req)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	wmi_start_scan_cmd_fixed_param scan_params;
+	tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
+	uint32_t mode = 0;
+	struct wma_txrx_node *intr = NULL;
+
+	if (NULL == pMac) {
+		WMA_LOGE("%s: pMac is NULL", __func__);
+		qdf_mem_free(roam_req);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!wma_handle->roam_offload_enabled) {
+		/* roam scan offload is not enabled in firmware.
+		 * Cannot initialize it in the middle of connection.
+		 */
+		qdf_mem_free(roam_req);
+		return QDF_STATUS_E_PERM;
+	}
+	WMA_LOGD("%s: RSO Command:%d, reason:%d session ID %d en %d", __func__,
+		 roam_req->Command, roam_req->reason, roam_req->sessionId,
+		 roam_req->RoamScanOffloadEnabled);
+	wma_handle->interfaces[roam_req->sessionId].roaming_in_progress = false;
+	switch (roam_req->Command) {
+	case ROAM_SCAN_OFFLOAD_START:
+		intr = &wma_handle->interfaces[roam_req->sessionId];
+		intr->delay_before_vdev_stop = roam_req->delay_before_vdev_stop;
+		/*
+		 * Scan/Roam threshold parameters are translated from fields of
+		 * tSirRoamOffloadScanReq to WMITLV values sent to Rome firmware
+		 * some of these parameters are configurable in qcom_cfg.ini
+		 */
+
+		/* First param is positive rssi value to trigger rssi based scan
+		 * Opportunistic scan is started at 30dB > trigger rssi.
+		 */
+		wma_handle->suitable_ap_hb_failure = false;
+
+		qdf_status = wma_roam_scan_offload_rssi_thresh(wma_handle,
+								roam_req);
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			break;
+		qdf_status = wma_roam_scan_bmiss_cnt(wma_handle,
+					     roam_req->RoamBmissFirstBcnt,
+					     roam_req->RoamBmissFinalBcnt,
+					     roam_req->sessionId);
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			break;
+
+		/* Opportunistic scan runs on a timer, value set by
+		 * EmptyRefreshScanPeriod. Age out the entries after 3 such
+		 * cycles.
+		 */
+		if (roam_req->EmptyRefreshScanPeriod > 0) {
+			qdf_status =
+				wma_roam_scan_offload_scan_period(wma_handle,
+					  roam_req->EmptyRefreshScanPeriod,
+					  roam_req->EmptyRefreshScanPeriod * 3,
+					  roam_req->sessionId);
+			if (qdf_status != QDF_STATUS_SUCCESS)
+				break;
+
+			mode = WMI_ROAM_SCAN_MODE_PERIODIC;
+			/* Don't use rssi triggered roam scans if external app
+			 * is in control of channel list.
+			 */
+			if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC ||
+			    roam_req->roam_force_rssi_trigger)
+				mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
+
+		} else {
+			mode = WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
+		}
+
+		/* Start new rssi triggered scan only if it changes by
+		 * RoamRssiDiff value. Beacon weight of 14 means average rssi
+		 * is taken over 14 previous samples + 2 times the current
+		 * beacon's rssi.
+		 */
+		qdf_status = wma_roam_scan_offload_rssi_change(wma_handle,
+					roam_req->sessionId,
+					roam_req->RoamRescanRssiDiff,
+					roam_req->RoamBeaconRssiWeight,
+					roam_req->hi_rssi_scan_delay);
+
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			break;
+
+		qdf_status = wma_roam_scan_offload_ap_profile(wma_handle,
+						roam_req);
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			break;
+
+		qdf_status = wma_roam_scan_offload_chan_list(wma_handle,
+				roam_req->ConnectedNetwork.ChannelCount,
+				&roam_req->ConnectedNetwork.ChannelCache[0],
+				roam_req->ChannelCacheType,
+				roam_req->sessionId);
+		if ((qdf_status != QDF_STATUS_SUCCESS) &&
+			(qdf_status != QDF_STATUS_E_EMPTY))
+			break;
+
+
+		wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req,
+					       &scan_params);
+		qdf_status =
+			wma_roam_scan_offload_mode(wma_handle, &scan_params,
+						   roam_req, mode,
+						   roam_req->sessionId);
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			break;
+		if (wmi_service_enabled(wma_handle->wmi_handle,
+					wmi_service_mawc_support)) {
+			qdf_status =
+				wma_roam_scan_mawc_params(wma_handle, roam_req);
+			if (qdf_status != QDF_STATUS_SUCCESS) {
+				WMA_LOGE("Sending roaming MAWC params failed");
+				break;
+			}
+		} else {
+			WMA_LOGD("MAWC roaming not supported by firmware");
+		}
+		qdf_status = wma_roam_scan_filter(wma_handle, roam_req);
+		if (qdf_status != QDF_STATUS_SUCCESS) {
+			WMA_LOGE("Sending start for roam scan filter failed");
+			break;
+		}
+		qdf_status = wma_roam_scan_btm_offload(wma_handle, roam_req);
+		if (qdf_status != QDF_STATUS_SUCCESS) {
+			WMA_LOGE("Sending BTM config to fw failed");
+			break;
+		}
+
+		/*
+		 * Send 11k offload enable to FW as part of RSO Start
+		 */
+		if (roam_req->reason == REASON_CTX_INIT) {
+			qdf_status = wma_send_offload_11k_params(wma_handle,
+						&roam_req->offload_11k_params);
+			if (qdf_status != QDF_STATUS_SUCCESS) {
+				WMA_LOGE("11k offload enable not sent, status %d",
+					 qdf_status);
+				break;
+			}
+		}
+		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;
+		}
+
+		/*
+		 * Send 11k offload disable command to FW as part of RSO Stop
+		 */
+		if (roam_req->reason == REASON_DISCONNECTED) {
+			qdf_status = wma_send_offload_11k_params(wma_handle,
+						&roam_req->offload_11k_params);
+			if (qdf_status != QDF_STATUS_SUCCESS) {
+				WMA_LOGE("11k offload disable not sent, status %d",
+					 qdf_status);
+				break;
+			}
+		}
+
+		/* Send BTM config as disabled during RSO Stop */
+		qdf_status = wma_roam_scan_btm_offload(wma_handle, roam_req);
+		if (qdf_status != QDF_STATUS_SUCCESS) {
+			WMA_LOGE(FL("Sending BTM config to fw failed"));
+			break;
+		}
+
+		wma_handle->suitable_ap_hb_failure = false;
+		if (wma_handle->roam_offload_enabled) {
+			uint32_t mode;
+
+			wma_roam_scan_fill_scan_params(wma_handle, pMac,
+						       NULL, &scan_params);
+
+			if (roam_req->reason == REASON_ROAM_STOP_ALL ||
+			    roam_req->reason == REASON_DISCONNECTED ||
+			    roam_req->reason == REASON_ROAM_SYNCH_FAILED) {
+				mode = WMI_ROAM_SCAN_MODE_NONE;
+			} else {
+				if (csr_roamIsRoamOffloadEnabled(pMac))
+					mode = WMI_ROAM_SCAN_MODE_NONE |
+						WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
+				else
+					mode = WMI_ROAM_SCAN_MODE_NONE;
+			}
+
+			qdf_status = wma_roam_scan_offload_mode(wma_handle,
+						&scan_params, NULL, mode,
+						roam_req->sessionId);
+		}
+		/*
+		 * After sending the roam scan mode because of a disconnect,
+		 * clear the scan bitmap client as well by sending
+		 * the following command
+		 */
+		wma_roam_scan_offload_rssi_thresh(wma_handle, roam_req);
+		/*
+		 * If the STOP command is due to a disconnect, then
+		 * send the filter command to clear all the filter
+		 * entries. If it is roaming scenario, then do not
+		 * send the cleared entries.
+		 */
+		if (!roam_req->middle_of_roaming) {
+			qdf_status = wma_roam_scan_filter(wma_handle, roam_req);
+			if (qdf_status != QDF_STATUS_SUCCESS) {
+				WMA_LOGE("clear for roam scan filter failed");
+				break;
+			}
+		}
+
+		if (roam_req->reason ==
+		    REASON_OS_REQUESTED_ROAMING_NOW) {
+			struct scheduler_msg cds_msg = {0};
+			tSirRoamOffloadScanRsp *scan_offload_rsp;
+
+			scan_offload_rsp =
+				qdf_mem_malloc(sizeof(*scan_offload_rsp));
+			if (!scan_offload_rsp) {
+				qdf_mem_free(roam_req);
+				return QDF_STATUS_E_NOMEM;
+			}
+			cds_msg.type = eWNI_SME_ROAM_SCAN_OFFLOAD_RSP;
+			scan_offload_rsp->sessionId = roam_req->sessionId;
+			scan_offload_rsp->reason = roam_req->reason;
+			cds_msg.bodyptr = scan_offload_rsp;
+			/*
+			 * Since REASSOC request is processed in
+			 * Roam_Scan_Offload_Rsp post a dummy rsp msg back to
+			 * SME with proper reason code.
+			 */
+			if (QDF_STATUS_SUCCESS !=
+			    scheduler_post_message(QDF_MODULE_ID_WMA,
+						   QDF_MODULE_ID_SME,
+						   QDF_MODULE_ID_SME,
+						   &cds_msg)) {
+				qdf_mem_free(scan_offload_rsp);
+				QDF_TRACE(QDF_MODULE_ID_WMA,
+					  QDF_TRACE_LEVEL_INFO,
+					  "%s: Failed to post Scan Offload Rsp to UMAC",
+					  __func__);
+			}
+		}
+		break;
+
+	case ROAM_SCAN_OFFLOAD_ABORT_SCAN:
+		/* If roam scan is running, stop that cycle.
+		 * It will continue automatically on next trigger.
+		 */
+		qdf_status = wma_roam_scan_offload_command(wma_handle,
+						   WMI_ROAM_SCAN_STOP_CMD,
+						   roam_req->sessionId);
+		break;
+
+	case ROAM_SCAN_OFFLOAD_RESTART:
+		/* Rome offload engine does not stop after any scan.
+		 * If this command is sent because all preauth attempts failed
+		 * and WMI_ROAM_REASON_SUITABLE_AP event was received earlier,
+		 * now it is time to call it heartbeat failure.
+		 */
+		if ((roam_req->reason == REASON_PREAUTH_FAILED_FOR_ALL)
+		    && wma_handle->suitable_ap_hb_failure) {
+			WMA_LOGE("%s: Sending heartbeat failure after preauth failures",
+				__func__);
+			wma_beacon_miss_handler(wma_handle,
+				roam_req->sessionId,
+				wma_handle->suitable_ap_hb_failure_rssi);
+			wma_handle->suitable_ap_hb_failure = false;
+		}
+		break;
+
+	case ROAM_SCAN_OFFLOAD_UPDATE_CFG:
+		wma_handle->suitable_ap_hb_failure = false;
+
+		if (roam_req->RoamScanOffloadEnabled) {
+			wma_roam_scan_fill_scan_params(wma_handle, pMac,
+						       roam_req, &scan_params);
+			qdf_status =
+				wma_roam_scan_offload_mode(
+					wma_handle, &scan_params, roam_req,
+					WMI_ROAM_SCAN_MODE_NONE,
+					roam_req->sessionId);
+			if (qdf_status != QDF_STATUS_SUCCESS)
+				break;
+		}
+
+		qdf_status = wma_roam_scan_bmiss_cnt(wma_handle,
+					     roam_req->RoamBmissFirstBcnt,
+					     roam_req->RoamBmissFinalBcnt,
+					     roam_req->sessionId);
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			break;
+
+		qdf_status = wma_roam_scan_filter(wma_handle, roam_req);
+		if (qdf_status != QDF_STATUS_SUCCESS) {
+			WMA_LOGE("Sending update for roam scan filter failed");
+			break;
+		}
+
+
+		/*
+		 * Runtime (after association) changes to rssi thresholds and
+		 * other parameters.
+		 */
+		qdf_status = wma_roam_scan_offload_chan_list(wma_handle,
+			     roam_req->ConnectedNetwork.ChannelCount,
+			     &roam_req->ConnectedNetwork.ChannelCache[0],
+			     roam_req->ChannelCacheType,
+			     roam_req->sessionId);
+		/*
+		 * Even though the channel list is empty, we can
+		 * still go ahead and start Roaming.
+		 */
+		if ((qdf_status != QDF_STATUS_SUCCESS) &&
+			(qdf_status != QDF_STATUS_E_EMPTY))
+			break;
+
+
+		qdf_status = wma_roam_scan_offload_rssi_thresh(wma_handle,
+							       roam_req);
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			break;
+
+		if (roam_req->EmptyRefreshScanPeriod > 0) {
+			qdf_status = wma_roam_scan_offload_scan_period(
+					wma_handle,
+					roam_req->EmptyRefreshScanPeriod,
+					roam_req->EmptyRefreshScanPeriod * 3,
+					roam_req->sessionId);
+			if (qdf_status != QDF_STATUS_SUCCESS)
+				break;
+
+			mode = WMI_ROAM_SCAN_MODE_PERIODIC;
+			/* Don't use rssi triggered roam scans if external app
+			 * is in control of channel list.
+			 */
+			if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC ||
+			    roam_req->roam_force_rssi_trigger)
+				mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
+
+		} else {
+			mode = WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
+		}
+
+		qdf_status = wma_roam_scan_offload_rssi_change(wma_handle,
+				    roam_req->sessionId,
+				    roam_req->RoamRescanRssiDiff,
+				    roam_req->RoamBeaconRssiWeight,
+				    roam_req->hi_rssi_scan_delay);
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			break;
+
+		qdf_status = wma_roam_scan_offload_ap_profile(wma_handle,
+					roam_req);
+		if (qdf_status != QDF_STATUS_SUCCESS)
+			break;
+
+		if (!roam_req->RoamScanOffloadEnabled)
+			break;
+
+		wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req,
+					       &scan_params);
+		qdf_status =
+			wma_roam_scan_offload_mode(wma_handle, &scan_params,
+						   roam_req, mode,
+						   roam_req->sessionId);
+
+		break;
+
+	default:
+		break;
+	}
+	qdf_mem_free(roam_req);
+	return qdf_status;
+}
+
+void wma_update_per_roam_config(WMA_HANDLE handle,
+				 struct wmi_per_roam_config_req *req_buf)
+{
+	int status;
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, cannot send per roam config",
+			__func__);
+		return;
+	}
+
+	status = wmi_unified_set_per_roam_config(wma_handle->wmi_handle,
+						req_buf);
+	if (status != EOK)
+		WMA_LOGE("%s: failed to set per roam config to FW",
+			__func__);
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+
+/**
+ * wma_process_roam_invoke() - send roam invoke command to fw.
+ * @handle: wma handle
+ * @roaminvoke: roam invoke command
+ *
+ * Send roam invoke command to fw for fastreassoc.
+ *
+ * Return: none
+ */
+void wma_process_roam_invoke(WMA_HANDLE handle,
+		struct wma_roam_invoke_cmd *roaminvoke)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	uint32_t ch_hz;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not send roam invoke",
+				__func__);
+		goto free_frame_buf;
+	}
+	ch_hz = (A_UINT32)cds_chan_to_freq(roaminvoke->channel);
+	wmi_unified_roam_invoke_cmd(wma_handle->wmi_handle,
+				(struct wmi_roam_invoke_cmd *)roaminvoke,
+				ch_hz);
+free_frame_buf:
+	if (roaminvoke->frame_len) {
+		qdf_mem_free(roaminvoke->frame_buf);
+		roaminvoke->frame_buf = NULL;
+	}
+}
+
+/**
+ * wma_process_roam_synch_fail() -roam synch failure handle
+ * @handle: wma handle
+ * @synch_fail: roam synch fail parameters
+ *
+ * Return: none
+ */
+void wma_process_roam_synch_fail(WMA_HANDLE handle,
+				 struct roam_offload_synch_fail *synch_fail)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not clean-up roam synch",
+			__func__);
+		return;
+	}
+	wlan_roam_debug_log(synch_fail->session_id,
+			    DEBUG_ROAM_SYNCH_FAIL,
+			    DEBUG_INVALID_PEER_ID, NULL, NULL, 0, 0);
+
+	/* Hand Off Failure could happen as an exception, when a roam synch
+	 * indication is posted to Host, but a roam synch complete is not
+	 * posted to the firmware.So, clear the roam synch in progress
+	 * flag before disconnecting the session through this event.
+	 */
+	wma_handle->interfaces[synch_fail->session_id].roam_synch_in_progress =
+		false;
+}
+
+/**
+ * wma_free_roam_synch_frame_ind() - Free the bcn_probe_rsp, reassoc_req,
+ * reassoc_rsp received as part of the ROAM_SYNC_FRAME event
+ *
+ * @iface - interaface corresponding to a vdev
+ *
+ * This API is used to free the buffer allocated during the ROAM_SYNC_FRAME
+ * event
+ *
+ */
+static void wma_free_roam_synch_frame_ind(struct wma_txrx_node *iface)
+{
+	if (iface->roam_synch_frame_ind.bcn_probe_rsp) {
+		qdf_mem_free(iface->roam_synch_frame_ind.bcn_probe_rsp);
+		iface->roam_synch_frame_ind.bcn_probe_rsp_len = 0;
+		iface->roam_synch_frame_ind.bcn_probe_rsp = NULL;
+	}
+	if (iface->roam_synch_frame_ind.reassoc_req) {
+		qdf_mem_free(iface->roam_synch_frame_ind.reassoc_req);
+		iface->roam_synch_frame_ind.reassoc_req_len = 0;
+		iface->roam_synch_frame_ind.reassoc_req = NULL;
+	}
+	if (iface->roam_synch_frame_ind.reassoc_rsp) {
+		qdf_mem_free(iface->roam_synch_frame_ind.reassoc_rsp);
+		iface->roam_synch_frame_ind.reassoc_rsp_len = 0;
+		iface->roam_synch_frame_ind.reassoc_rsp = NULL;
+	}
+}
+
+/**
+ * wma_fill_data_synch_frame_event() - Fill the the roam sync data buffer using
+ * synch frame event data
+ * @wma: Global WMA Handle
+ * @roam_synch_ind_ptr: Buffer to be filled
+ * @param_buf: Source buffer
+ *
+ * Firmware sends all the required information required for roam
+ * synch propagation as TLV's and stored in param_buf. These
+ * parameters are parsed and filled into the roam synch indication
+ * buffer which will be used at different layers for propagation.
+ *
+ * Return: None
+ */
+static void wma_fill_data_synch_frame_event(tp_wma_handle wma,
+				roam_offload_synch_ind *roam_synch_ind_ptr,
+				struct wma_txrx_node *iface)
+{
+	uint8_t *bcn_probersp_ptr;
+	uint8_t *reassoc_rsp_ptr;
+	uint8_t *reassoc_req_ptr;
+
+	/* Beacon/Probe Rsp data */
+	roam_synch_ind_ptr->beaconProbeRespOffset =
+		sizeof(roam_offload_synch_ind);
+	bcn_probersp_ptr = (uint8_t *) roam_synch_ind_ptr +
+		roam_synch_ind_ptr->beaconProbeRespOffset;
+	roam_synch_ind_ptr->beaconProbeRespLength =
+		iface->roam_synch_frame_ind.bcn_probe_rsp_len;
+	qdf_mem_copy(bcn_probersp_ptr,
+		iface->roam_synch_frame_ind.bcn_probe_rsp,
+		roam_synch_ind_ptr->beaconProbeRespLength);
+	qdf_mem_free(iface->roam_synch_frame_ind.bcn_probe_rsp);
+		iface->roam_synch_frame_ind.bcn_probe_rsp = NULL;
+
+	/* ReAssoc Rsp data */
+	roam_synch_ind_ptr->reassocRespOffset =
+		sizeof(roam_offload_synch_ind) +
+		roam_synch_ind_ptr->beaconProbeRespLength;
+	roam_synch_ind_ptr->reassocRespLength =
+		iface->roam_synch_frame_ind.reassoc_rsp_len;
+	reassoc_rsp_ptr = (uint8_t *) roam_synch_ind_ptr +
+			  roam_synch_ind_ptr->reassocRespOffset;
+	qdf_mem_copy(reassoc_rsp_ptr,
+		     iface->roam_synch_frame_ind.reassoc_rsp,
+		     roam_synch_ind_ptr->reassocRespLength);
+	qdf_mem_free(iface->roam_synch_frame_ind.reassoc_rsp);
+	iface->roam_synch_frame_ind.reassoc_rsp = NULL;
+
+	/* ReAssoc Req data */
+	roam_synch_ind_ptr->reassoc_req_offset =
+		sizeof(roam_offload_synch_ind) +
+		roam_synch_ind_ptr->beaconProbeRespLength +
+		roam_synch_ind_ptr->reassocRespLength;
+	roam_synch_ind_ptr->reassoc_req_length =
+		iface->roam_synch_frame_ind.reassoc_req_len;
+	reassoc_req_ptr = (uint8_t *) roam_synch_ind_ptr +
+			  roam_synch_ind_ptr->reassoc_req_offset;
+	qdf_mem_copy(reassoc_req_ptr,
+		     iface->roam_synch_frame_ind.reassoc_req,
+		     roam_synch_ind_ptr->reassoc_req_length);
+	qdf_mem_free(iface->roam_synch_frame_ind.reassoc_req);
+	iface->roam_synch_frame_ind.reassoc_req = NULL;
+}
+
+/**
+ * wma_fill_data_synch_event() - Fill the the roam sync data buffer using synch
+ * event data
+ * @wma: Global WMA Handle
+ * @roam_synch_ind_ptr: Buffer to be filled
+ * @param_buf: Source buffer
+ *
+ * Firmware sends all the required information required for roam
+ * synch propagation as TLV's and stored in param_buf. These
+ * parameters are parsed and filled into the roam synch indication
+ * buffer which will be used at different layers for propagation.
+ *
+ * Return: None
+ */
+static void wma_fill_data_synch_event(tp_wma_handle wma,
+				roam_offload_synch_ind *roam_synch_ind_ptr,
+				WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf)
+{
+	uint8_t *bcn_probersp_ptr;
+	uint8_t *reassoc_rsp_ptr;
+	uint8_t *reassoc_req_ptr;
+	wmi_roam_synch_event_fixed_param *synch_event;
+
+	synch_event = param_buf->fixed_param;
+
+	/* Beacon/Probe Rsp data */
+	roam_synch_ind_ptr->beaconProbeRespOffset =
+		sizeof(roam_offload_synch_ind);
+	bcn_probersp_ptr = (uint8_t *) roam_synch_ind_ptr +
+		roam_synch_ind_ptr->beaconProbeRespOffset;
+	roam_synch_ind_ptr->beaconProbeRespLength =
+		synch_event->bcn_probe_rsp_len;
+	qdf_mem_copy(bcn_probersp_ptr, param_buf->bcn_probe_rsp_frame,
+		     roam_synch_ind_ptr->beaconProbeRespLength);
+	/* ReAssoc Rsp data */
+	roam_synch_ind_ptr->reassocRespOffset =
+		sizeof(roam_offload_synch_ind) +
+		roam_synch_ind_ptr->beaconProbeRespLength;
+	roam_synch_ind_ptr->reassocRespLength = synch_event->reassoc_rsp_len;
+	reassoc_rsp_ptr = (uint8_t *) roam_synch_ind_ptr +
+			  roam_synch_ind_ptr->reassocRespOffset;
+	qdf_mem_copy(reassoc_rsp_ptr,
+		     param_buf->reassoc_rsp_frame,
+		     roam_synch_ind_ptr->reassocRespLength);
+
+	/* ReAssoc Req data */
+	roam_synch_ind_ptr->reassoc_req_offset =
+		sizeof(roam_offload_synch_ind) +
+		roam_synch_ind_ptr->beaconProbeRespLength +
+		roam_synch_ind_ptr->reassocRespLength;
+	roam_synch_ind_ptr->reassoc_req_length = synch_event->reassoc_req_len;
+	reassoc_req_ptr = (uint8_t *) roam_synch_ind_ptr +
+			  roam_synch_ind_ptr->reassoc_req_offset;
+	qdf_mem_copy(reassoc_req_ptr, param_buf->reassoc_req_frame,
+		     roam_synch_ind_ptr->reassoc_req_length);
+}
+
+/**
+ * wma_fill_roam_synch_buffer() - Fill the the roam sync buffer
+ * @wma: Global WMA Handle
+ * @roam_synch_ind_ptr: Buffer to be filled
+ * @param_buf: Source buffer
+ *
+ * Firmware sends all the required information required for roam
+ * synch propagation as TLV's and stored in param_buf. These
+ * parameters are parsed and filled into the roam synch indication
+ * buffer which will be used at different layers for propagation.
+ *
+ * Return: Success or Failure
+ */
+static int wma_fill_roam_synch_buffer(tp_wma_handle wma,
+				roam_offload_synch_ind *roam_synch_ind_ptr,
+				WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf)
+{
+	wmi_roam_synch_event_fixed_param *synch_event;
+	wmi_channel *chan;
+	wmi_key_material *key;
+	struct wma_txrx_node *iface = NULL;
+	wmi_roam_fils_synch_tlv_param *fils_info;
+	int status = -EINVAL;
+
+	synch_event = param_buf->fixed_param;
+	roam_synch_ind_ptr->roamedVdevId = synch_event->vdev_id;
+	roam_synch_ind_ptr->authStatus = synch_event->auth_status;
+	roam_synch_ind_ptr->roamReason = synch_event->roam_reason;
+	roam_synch_ind_ptr->rssi = synch_event->rssi;
+	iface = &wma->interfaces[synch_event->vdev_id];
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&synch_event->bssid,
+				   roam_synch_ind_ptr->bssid.bytes);
+	WMA_LOGD("%s: roamedVdevId %d authStatus %d roamReason %d rssi %d isBeacon %d",
+		__func__, roam_synch_ind_ptr->roamedVdevId,
+		roam_synch_ind_ptr->authStatus, roam_synch_ind_ptr->roamReason,
+		roam_synch_ind_ptr->rssi, roam_synch_ind_ptr->isBeacon);
+
+	if (!QDF_IS_STATUS_SUCCESS(
+		wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
+		roam_synch_ind_ptr, NULL, SIR_ROAMING_DEREGISTER_STA))) {
+		WMA_LOGE("LFR3: CSR Roam synch cb failed");
+		wma_free_roam_synch_frame_ind(iface);
+		return status;
+	}
+
+	/*
+	 * If lengths of bcn_probe_rsp, reassoc_req and reassoc_rsp are zero in
+	 * synch_event driver would have received bcn_probe_rsp, reassoc_req
+	 * and reassoc_rsp via the event WMI_ROAM_SYNCH_FRAME_EVENTID
+	 */
+	if ((!synch_event->bcn_probe_rsp_len) &&
+		(!synch_event->reassoc_req_len) &&
+		(!synch_event->reassoc_rsp_len)) {
+		if (!iface->roam_synch_frame_ind.bcn_probe_rsp) {
+			WMA_LOGE("LFR3: bcn_probe_rsp is NULL");
+			QDF_ASSERT(iface->roam_synch_frame_ind.
+				   bcn_probe_rsp != NULL);
+			wma_free_roam_synch_frame_ind(iface);
+			return status;
+		}
+		if (!iface->roam_synch_frame_ind.reassoc_rsp) {
+			WMA_LOGE("LFR3: reassoc_rsp is NULL");
+			QDF_ASSERT(iface->roam_synch_frame_ind.
+				   reassoc_rsp != NULL);
+			wma_free_roam_synch_frame_ind(iface);
+			return status;
+		}
+		if (!iface->roam_synch_frame_ind.reassoc_req) {
+			WMA_LOGE("LFR3: reassoc_req is NULL");
+			QDF_ASSERT(iface->roam_synch_frame_ind.
+				   reassoc_req != NULL);
+			wma_free_roam_synch_frame_ind(iface);
+			return status;
+		}
+		wma_fill_data_synch_frame_event(wma, roam_synch_ind_ptr, iface);
+	} else {
+		wma_fill_data_synch_event(wma, roam_synch_ind_ptr, param_buf);
+	}
+
+	chan = (wmi_channel *) param_buf->chan;
+	roam_synch_ind_ptr->chan_freq = chan->mhz;
+	key = (wmi_key_material *) param_buf->key;
+	if (key != NULL) {
+		qdf_mem_copy(roam_synch_ind_ptr->kck, key->kck,
+			     SIR_KCK_KEY_LEN);
+		roam_synch_ind_ptr->kek_len = SIR_KEK_KEY_LEN;
+		qdf_mem_copy(roam_synch_ind_ptr->kek, key->kek,
+			     SIR_KEK_KEY_LEN);
+		qdf_mem_copy(roam_synch_ind_ptr->replay_ctr,
+			     key->replay_counter, SIR_REPLAY_CTR_LEN);
+	}
+	if (param_buf->hw_mode_transition_fixed_param)
+		wma_process_pdev_hw_mode_trans_ind(wma,
+		    param_buf->hw_mode_transition_fixed_param,
+		    param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping,
+		    &roam_synch_ind_ptr->hw_mode_trans_ind);
+	else
+		WMA_LOGD(FL("hw_mode transition fixed param is NULL"));
+
+	fils_info = (wmi_roam_fils_synch_tlv_param *)
+			(param_buf->roam_fils_synch_info);
+	if (fils_info) {
+		if ((fils_info->kek_len > SIR_KEK_KEY_LEN_FILS) ||
+		    (fils_info->pmk_len > SIR_PMK_LEN)) {
+			WMA_LOGE("%s: Invalid kek_len %d or pmk_len %d",
+				 __func__,
+				 fils_info->kek_len,
+				 fils_info->pmk_len);
+			wma_free_roam_synch_frame_ind(iface);
+			return status;
+		}
+
+		roam_synch_ind_ptr->kek_len = fils_info->kek_len;
+		qdf_mem_copy(roam_synch_ind_ptr->kek, fils_info->kek,
+			     fils_info->kek_len);
+
+		roam_synch_ind_ptr->pmk_len = fils_info->pmk_len;
+		qdf_mem_copy(roam_synch_ind_ptr->pmk, fils_info->pmk,
+			     fils_info->pmk_len);
+
+		qdf_mem_copy(roam_synch_ind_ptr->pmkid, fils_info->pmkid,
+			     SIR_PMKID_LEN);
+
+		roam_synch_ind_ptr->update_erp_next_seq_num =
+				fils_info->update_erp_next_seq_num;
+		roam_synch_ind_ptr->next_erp_seq_num =
+				fils_info->next_erp_seq_num;
+
+		WMA_LOGD("Update ERP Seq Num %d, Next ERP Seq Num %d",
+			 roam_synch_ind_ptr->update_erp_next_seq_num,
+			 roam_synch_ind_ptr->next_erp_seq_num);
+	}
+	wma_free_roam_synch_frame_ind(iface);
+	return 0;
+}
+
+/**
+ * wma_roam_update_vdev() - Update the STA and BSS
+ * @wma: Global WMA Handle
+ * @roam_synch_ind_ptr: Information needed for roam sync propagation
+ *
+ * This function will perform all the vdev related operations with
+ * respect to the self sta and the peer after roaming and completes
+ * the roam synch propagation with respect to WMA layer.
+ *
+ * Return: None
+ */
+static void wma_roam_update_vdev(tp_wma_handle wma,
+				 roam_offload_synch_ind *roam_synch_ind_ptr)
+{
+	tDeleteBssParams *del_bss_params;
+	tDeleteStaParams *del_sta_params;
+	tLinkStateParams *set_link_params;
+	tAddStaParams *add_sta_params;
+	uint8_t vdev_id;
+
+	vdev_id = roam_synch_ind_ptr->roamedVdevId;
+	wma->interfaces[vdev_id].nss = roam_synch_ind_ptr->nss;
+	del_bss_params = qdf_mem_malloc(sizeof(*del_bss_params));
+	del_sta_params = qdf_mem_malloc(sizeof(*del_sta_params));
+	set_link_params = qdf_mem_malloc(sizeof(*set_link_params));
+	add_sta_params = qdf_mem_malloc(sizeof(*add_sta_params));
+	if (!del_bss_params || !del_sta_params ||
+	    !set_link_params || !add_sta_params)
+		return;
+
+	qdf_mem_zero(del_bss_params, sizeof(*del_bss_params));
+	qdf_mem_zero(del_sta_params, sizeof(*del_sta_params));
+	qdf_mem_zero(set_link_params, sizeof(*set_link_params));
+	qdf_mem_zero(add_sta_params, sizeof(*add_sta_params));
+
+	del_bss_params->smesessionId = vdev_id;
+	del_sta_params->smesessionId = vdev_id;
+	qdf_mem_copy(del_bss_params->bssid, wma->interfaces[vdev_id].bssid,
+			IEEE80211_ADDR_LEN);
+	set_link_params->state = eSIR_LINK_PREASSOC_STATE;
+	qdf_mem_copy(set_link_params->selfMacAddr,
+		roam_synch_ind_ptr->self_mac.bytes, IEEE80211_ADDR_LEN);
+	qdf_mem_copy(set_link_params->bssid, roam_synch_ind_ptr->bssid.bytes,
+			IEEE80211_ADDR_LEN);
+	add_sta_params->staType = STA_ENTRY_SELF;
+	add_sta_params->smesessionId = vdev_id;
+	qdf_mem_copy(&add_sta_params->bssId, &roam_synch_ind_ptr->bssid.bytes,
+			IEEE80211_ADDR_LEN);
+	add_sta_params->staIdx = STA_INVALID_IDX;
+	add_sta_params->assocId = roam_synch_ind_ptr->aid;
+
+	wma_delete_sta(wma, del_sta_params);
+	wma_delete_bss(wma, del_bss_params);
+	wma_set_linkstate(wma, set_link_params);
+	wma_add_bss(wma, (tpAddBssParams)roam_synch_ind_ptr->add_bss_params);
+	wma_add_sta(wma, add_sta_params);
+#ifndef CONFIG_VDEV_SM
+	wma_vdev_set_mlme_state(wma, vdev_id, WLAN_VDEV_S_RUN);
+#endif
+	qdf_mem_copy(wma->interfaces[vdev_id].bssid,
+			roam_synch_ind_ptr->bssid.bytes, IEEE80211_ADDR_LEN);
+	qdf_mem_free(del_bss_params);
+	qdf_mem_free(set_link_params);
+	qdf_mem_free(add_sta_params);
+}
+
+/**
+ * wma_roam_synch_event_handler() - roam synch event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: length of data
+ *
+ * This function is roam synch event handler. It sends roam
+ * indication for upper layer.
+ *
+ * Return: Success or Failure status
+ */
+int wma_roam_synch_event_handler(void *handle, uint8_t *event,
+					uint32_t len)
+{
+	WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf = NULL;
+	wmi_roam_synch_event_fixed_param *synch_event = NULL;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	roam_offload_synch_ind *roam_synch_ind_ptr = NULL;
+	tpSirBssDescription  bss_desc_ptr = NULL;
+	uint16_t ie_len = 0;
+	int status = -EINVAL;
+	tSirRoamOffloadScanReq *roam_req;
+	qdf_time_t roam_synch_received = qdf_get_system_timestamp();
+	uint32_t roam_synch_data_len;
+	A_UINT32 bcn_probe_rsp_len;
+	A_UINT32 reassoc_rsp_len;
+	A_UINT32 reassoc_req_len;
+
+	WMA_LOGD("LFR3:%s", __func__);
+	if (!event) {
+		WMA_LOGE("%s: event param null", __func__);
+		goto cleanup_label;
+	}
+
+	param_buf = (WMI_ROAM_SYNCH_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("%s: received null buf from target", __func__);
+		goto cleanup_label;
+	}
+
+	synch_event = param_buf->fixed_param;
+	if (!synch_event) {
+		WMA_LOGE("%s: received null event data from target", __func__);
+		goto cleanup_label;
+	}
+
+	if (synch_event->vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: received invalid vdev_id %d",
+				__func__, synch_event->vdev_id);
+		return status;
+	}
+
+	/*
+	 * This flag is set during ROAM_START and once this event is being
+	 * executed which is a run to completion, no other event can interrupt
+	 * this in MC thread context. So, it is OK to reset the flag here as
+	 * soon as we receive this event.
+	 */
+	wma->interfaces[synch_event->vdev_id].roaming_in_progress = false;
+
+	if (synch_event->bcn_probe_rsp_len >
+	    param_buf->num_bcn_probe_rsp_frame ||
+	    synch_event->reassoc_req_len >
+	    param_buf->num_reassoc_req_frame ||
+	    synch_event->reassoc_rsp_len >
+	    param_buf->num_reassoc_rsp_frame) {
+		WMA_LOGD("Invalid synch payload: LEN bcn:%d, req:%d, rsp:%d",
+			synch_event->bcn_probe_rsp_len,
+			synch_event->reassoc_req_len,
+			synch_event->reassoc_rsp_len);
+		goto cleanup_label;
+	}
+
+	wlan_roam_debug_log(synch_event->vdev_id, DEBUG_ROAM_SYNCH_IND,
+			    DEBUG_INVALID_PEER_ID, NULL, NULL,
+			    synch_event->bssid.mac_addr31to0,
+			    synch_event->bssid.mac_addr47to32);
+	DPTRACE(qdf_dp_trace_record_event(QDF_DP_TRACE_EVENT_RECORD,
+		synch_event->vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
+		QDF_PROTO_TYPE_EVENT, QDF_ROAM_SYNCH));
+
+	if (wma_is_roam_synch_in_progress(wma, synch_event->vdev_id)) {
+		WMA_LOGE("%s: Ignoring RSI since one is already in progress",
+				__func__);
+		goto cleanup_label;
+	}
+	WMA_LOGD("LFR3: Received WMA_ROAM_OFFLOAD_SYNCH_IND");
+
+	/*
+	 * All below length fields are unsigned and hence positive numbers.
+	 * Maximum number during the addition would be (3 * MAX_LIMIT(UINT32) +
+	 * few fixed fields).
+	 */
+	WMA_LOGD("synch payload: LEN bcn:%d, req:%d, rsp:%d",
+			synch_event->bcn_probe_rsp_len,
+			synch_event->reassoc_req_len,
+			synch_event->reassoc_rsp_len);
+
+	/*
+	 * If lengths of bcn_probe_rsp, reassoc_req and reassoc_rsp are zero in
+	 * synch_event driver would have received bcn_probe_rsp, reassoc_req
+	 * and reassoc_rsp via the event WMI_ROAM_SYNCH_FRAME_EVENTID
+	 */
+	if ((!synch_event->bcn_probe_rsp_len) &&
+		(!synch_event->reassoc_req_len) &&
+		(!synch_event->reassoc_rsp_len)) {
+		bcn_probe_rsp_len = wma->interfaces[synch_event->vdev_id].
+				      roam_synch_frame_ind.
+				      bcn_probe_rsp_len;
+		reassoc_req_len = wma->interfaces[synch_event->vdev_id].
+				      roam_synch_frame_ind.reassoc_req_len;
+		reassoc_rsp_len = wma->interfaces[synch_event->vdev_id].
+				      roam_synch_frame_ind.reassoc_rsp_len;
+
+		roam_synch_data_len = bcn_probe_rsp_len + reassoc_rsp_len +
+			reassoc_req_len + sizeof(roam_offload_synch_ind);
+
+		WMA_LOGD("Updated synch payload: LEN bcn:%d, req:%d, rsp:%d",
+			bcn_probe_rsp_len,
+			reassoc_req_len,
+			reassoc_rsp_len);
+	} else {
+		bcn_probe_rsp_len = synch_event->bcn_probe_rsp_len;
+		reassoc_req_len = synch_event->reassoc_req_len;
+		reassoc_rsp_len = synch_event->reassoc_rsp_len;
+
+		if (synch_event->bcn_probe_rsp_len > WMI_SVC_MSG_MAX_SIZE)
+			goto cleanup_label;
+		if (synch_event->reassoc_rsp_len >
+		    (WMI_SVC_MSG_MAX_SIZE - synch_event->bcn_probe_rsp_len))
+			goto cleanup_label;
+		if (synch_event->reassoc_req_len >
+		    WMI_SVC_MSG_MAX_SIZE - (synch_event->bcn_probe_rsp_len +
+			synch_event->reassoc_rsp_len))
+			goto cleanup_label;
+
+		roam_synch_data_len = bcn_probe_rsp_len +
+			reassoc_rsp_len + reassoc_req_len;
+
+		/*
+		 * Below is the check for the entire size of the message
+		 * received from the firmware.
+		 */
+		if (roam_synch_data_len > WMI_SVC_MSG_MAX_SIZE -
+			(sizeof(*synch_event) + sizeof(wmi_channel) +
+			 sizeof(wmi_key_material) + sizeof(uint32_t)))
+			goto cleanup_label;
+
+		roam_synch_data_len += sizeof(roam_offload_synch_ind);
+	}
+
+	WMA_LOGD("synch payload: LEN bcn:%d, req:%d, rsp:%d",
+			bcn_probe_rsp_len,
+			reassoc_req_len,
+			reassoc_rsp_len);
+
+	cds_host_diag_log_work(&wma->roam_ho_wl,
+			       WMA_ROAM_HO_WAKE_LOCK_DURATION,
+			       WIFI_POWER_EVENT_WAKELOCK_WOW);
+	qdf_wake_lock_timeout_acquire(&wma->roam_ho_wl,
+				      WMA_ROAM_HO_WAKE_LOCK_DURATION);
+
+	wma->interfaces[synch_event->vdev_id].roam_synch_in_progress = true;
+
+	roam_synch_ind_ptr = qdf_mem_malloc(roam_synch_data_len);
+	if (!roam_synch_ind_ptr) {
+		QDF_ASSERT(roam_synch_ind_ptr != NULL);
+		status = -ENOMEM;
+		goto cleanup_label;
+	}
+	qdf_mem_zero(roam_synch_ind_ptr, roam_synch_data_len);
+	status = wma_fill_roam_synch_buffer(wma,
+			roam_synch_ind_ptr, param_buf);
+	if (status != 0)
+		goto cleanup_label;
+	/* 24 byte MAC header and 12 byte to ssid IE */
+	if (roam_synch_ind_ptr->beaconProbeRespLength >
+			(SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET)) {
+		ie_len = roam_synch_ind_ptr->beaconProbeRespLength -
+			(SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
+	} else {
+		WMA_LOGE("LFR3: Invalid Beacon Length");
+		goto cleanup_label;
+	}
+	bss_desc_ptr = qdf_mem_malloc(sizeof(tSirBssDescription) + ie_len);
+	if (!bss_desc_ptr) {
+		QDF_ASSERT(bss_desc_ptr != NULL);
+		status = -ENOMEM;
+		goto cleanup_label;
+	}
+	qdf_mem_zero(bss_desc_ptr, sizeof(tSirBssDescription) + ie_len);
+	if (QDF_IS_STATUS_ERROR(wma->pe_roam_synch_cb(
+			(tpAniSirGlobal)wma->mac_context,
+			roam_synch_ind_ptr, bss_desc_ptr,
+			SIR_ROAM_SYNCH_PROPAGATION))) {
+		WMA_LOGE("LFR3: PE roam synch cb failed");
+		status = -EBUSY;
+		goto cleanup_label;
+	}
+
+	wma_roam_update_vdev(wma, roam_synch_ind_ptr);
+	wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
+		roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_PROPAGATION);
+	wma_process_roam_synch_complete(wma, synch_event->vdev_id);
+
+	/* update freq and channel width */
+	wma->interfaces[synch_event->vdev_id].mhz =
+		roam_synch_ind_ptr->chan_freq;
+	if (roam_synch_ind_ptr->join_rsp)
+		wma->interfaces[synch_event->vdev_id].chan_width =
+			roam_synch_ind_ptr->join_rsp->vht_channel_width;
+
+	wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
+		roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_COMPLETE);
+	wma->interfaces[synch_event->vdev_id].roam_synch_delay =
+		qdf_get_system_timestamp() - roam_synch_received;
+	WMA_LOGD("LFR3: roam_synch_delay:%d",
+		wma->interfaces[synch_event->vdev_id].roam_synch_delay);
+	wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
+		roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_NAPI_OFF);
+
+	status = 0;
+
+cleanup_label:
+	if (status != 0) {
+		if (roam_synch_ind_ptr)
+			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 && 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);
+		}
+	}
+	if (roam_synch_ind_ptr && roam_synch_ind_ptr->join_rsp)
+		qdf_mem_free(roam_synch_ind_ptr->join_rsp);
+	if (roam_synch_ind_ptr)
+		qdf_mem_free(roam_synch_ind_ptr);
+	if (bss_desc_ptr)
+		qdf_mem_free(bss_desc_ptr);
+	if (wma && synch_event)
+		wma->interfaces[synch_event->vdev_id].roam_synch_in_progress =
+			false;
+
+	return status;
+}
+
+int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event,
+					uint32_t len)
+{
+	WMI_ROAM_SYNCH_FRAME_EVENTID_param_tlvs *param_buf = NULL;
+	wmi_roam_synch_frame_event_fixed_param *synch_frame_event = NULL;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	A_UINT32 vdev_id;
+	struct wma_txrx_node *iface = NULL;
+	int status = -EINVAL;
+
+	WMA_LOGD("LFR3:Synch Frame event");
+	if (!event) {
+		WMA_LOGE("event param null");
+		return status;
+	}
+
+	param_buf = (WMI_ROAM_SYNCH_FRAME_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("received null buf from target");
+		return status;
+	}
+
+	synch_frame_event = param_buf->fixed_param;
+	if (!synch_frame_event) {
+		WMA_LOGE("received null event data from target");
+		return status;
+	}
+
+	if (synch_frame_event->vdev_id >= wma->max_bssid) {
+		WMA_LOGE("received invalid vdev_id %d",
+				 synch_frame_event->vdev_id);
+		return status;
+	}
+
+	if (synch_frame_event->bcn_probe_rsp_len >
+	    param_buf->num_bcn_probe_rsp_frame ||
+	    synch_frame_event->reassoc_req_len >
+	    param_buf->num_reassoc_req_frame ||
+	    synch_frame_event->reassoc_rsp_len >
+	    param_buf->num_reassoc_rsp_frame) {
+		WMA_LOGE("fixed/actual len err: bcn:%d/%d req:%d/%d rsp:%d/%d",
+			 synch_frame_event->bcn_probe_rsp_len,
+			 param_buf->num_bcn_probe_rsp_frame,
+			 synch_frame_event->reassoc_req_len,
+			 param_buf->num_reassoc_req_frame,
+			 synch_frame_event->reassoc_rsp_len,
+			 param_buf->num_reassoc_rsp_frame);
+		return status;
+	}
+
+	vdev_id = synch_frame_event->vdev_id;
+	iface = &wma->interfaces[vdev_id];
+
+	if (wma_is_roam_synch_in_progress(wma, vdev_id)) {
+		WMA_LOGE("Ignoring this event as it is unexpected");
+		wma_free_roam_synch_frame_ind(iface);
+		return status;
+	}
+	WMA_LOGD("LFR3: Received ROAM_SYNCH_FRAME_EVENT");
+
+	WMA_LOGD("synch frame payload: LEN bcn:%d, req:%d, rsp:%d morefrag: %d",
+				synch_frame_event->bcn_probe_rsp_len,
+				synch_frame_event->reassoc_req_len,
+				synch_frame_event->reassoc_rsp_len,
+				synch_frame_event->more_frag);
+
+	if (synch_frame_event->bcn_probe_rsp_len) {
+		iface->roam_synch_frame_ind.bcn_probe_rsp_len =
+				synch_frame_event->bcn_probe_rsp_len;
+		iface->roam_synch_frame_ind.is_beacon =
+				synch_frame_event->is_beacon;
+
+		if (iface->roam_synch_frame_ind.bcn_probe_rsp)
+			qdf_mem_free(iface->roam_synch_frame_ind.
+				     bcn_probe_rsp);
+		iface->roam_synch_frame_ind.bcn_probe_rsp =
+			qdf_mem_malloc(iface->roam_synch_frame_ind.
+				       bcn_probe_rsp_len);
+		if (!iface->roam_synch_frame_ind.bcn_probe_rsp) {
+			QDF_ASSERT(iface->roam_synch_frame_ind.
+				   bcn_probe_rsp != NULL);
+			status = -ENOMEM;
+			wma_free_roam_synch_frame_ind(iface);
+			return status;
+		}
+		qdf_mem_copy(iface->roam_synch_frame_ind.
+			bcn_probe_rsp,
+			param_buf->bcn_probe_rsp_frame,
+			iface->roam_synch_frame_ind.bcn_probe_rsp_len);
+	}
+
+	if (synch_frame_event->reassoc_req_len) {
+		iface->roam_synch_frame_ind.reassoc_req_len =
+				synch_frame_event->reassoc_req_len;
+
+		if (iface->roam_synch_frame_ind.reassoc_req)
+			qdf_mem_free(iface->roam_synch_frame_ind.reassoc_req);
+		iface->roam_synch_frame_ind.reassoc_req =
+			qdf_mem_malloc(iface->roam_synch_frame_ind.
+				       reassoc_req_len);
+		if (!iface->roam_synch_frame_ind.reassoc_req) {
+			QDF_ASSERT(iface->roam_synch_frame_ind.
+				   reassoc_req != NULL);
+			status = -ENOMEM;
+			wma_free_roam_synch_frame_ind(iface);
+			return status;
+		}
+		qdf_mem_copy(iface->roam_synch_frame_ind.reassoc_req,
+			     param_buf->reassoc_req_frame,
+			     iface->roam_synch_frame_ind.reassoc_req_len);
+	}
+
+	if (synch_frame_event->reassoc_rsp_len) {
+		iface->roam_synch_frame_ind.reassoc_rsp_len =
+				synch_frame_event->reassoc_rsp_len;
+
+		if (iface->roam_synch_frame_ind.reassoc_rsp)
+			qdf_mem_free(iface->roam_synch_frame_ind.reassoc_rsp);
+
+		iface->roam_synch_frame_ind.reassoc_rsp =
+			qdf_mem_malloc(iface->roam_synch_frame_ind.
+				       reassoc_rsp_len);
+		if (!iface->roam_synch_frame_ind.reassoc_rsp) {
+			QDF_ASSERT(iface->roam_synch_frame_ind.
+				   reassoc_rsp != NULL);
+			status = -ENOMEM;
+			wma_free_roam_synch_frame_ind(iface);
+			return status;
+		}
+		qdf_mem_copy(iface->roam_synch_frame_ind.reassoc_rsp,
+			     param_buf->reassoc_rsp_frame,
+			     iface->roam_synch_frame_ind.reassoc_rsp_len);
+	}
+	return 0;
+}
+
+#define RSN_CAPS_SHIFT               16
+/**
+ * wma_roam_scan_fill_self_caps() - fill capabilities
+ * @wma_handle: wma handle
+ * @roam_offload_params: offload parameters
+ * @roam_req: roam request
+ *
+ * This function fills roam self capablities.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_roam_scan_fill_self_caps(tp_wma_handle wma_handle,
+					roam_offload_param *
+					roam_offload_params,
+					tSirRoamOffloadScanReq *roam_req)
+{
+	qdf_size_t val_len;
+	struct mac_context *pMac = NULL;
+	tSirMacCapabilityInfo selfCaps;
+	uint32_t val = 0;
+	uint32_t nCfgValue;
+	uint16_t *pCfgValue16;
+	uint8_t nCfgValue8, *pCfgValue8;
+	tSirMacQosInfoStation macQosInfoSta;
+
+	qdf_mem_set(&macQosInfoSta, sizeof(tSirMacQosInfoStation), 0);
+	/* Roaming is done only for INFRA STA type.
+	 * So, ess will be one and ibss will be Zero
+	 */
+	pMac = cds_get_context(QDF_MODULE_ID_PE);
+	if (!pMac) {
+		WMA_LOGE("%s:NULL pMac ptr. Exiting", __func__);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	selfCaps.ess = 1;
+	selfCaps.ibss = 0;
+
+	val = pMac->mlme_cfg->wep_params.is_privacy_enabled;
+	if (val)
+		selfCaps.privacy = 1;
+
+	if (pMac->mlme_cfg->ht_caps.short_preamble)
+		selfCaps.shortPreamble = 1;
+
+	selfCaps.pbcc = 0;
+	selfCaps.channelAgility = 0;
+
+	if (pMac->mlme_cfg->feature_flags.enable_short_slot_time_11g)
+		selfCaps.shortSlotTime = 1;
+	if (wlan_cfg_get_int(pMac, WNI_CFG_11H_ENABLED, &val) !=
+							QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
+			  "Failed to get WNI_CFG_11H_ENABLED");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (val)
+		selfCaps.spectrumMgt = 1;
+
+	if (pMac->mlme_cfg->wmm_params.qos_enabled)
+		selfCaps.qos = 1;
+
+	if (wlan_cfg_get_int(pMac, WNI_CFG_APSD_ENABLED, &val) !=
+							QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
+			  "Failed to get WNI_CFG_APSD_ENABLED");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (val)
+		selfCaps.apsd = 1;
+
+	selfCaps.rrm = pMac->rrm.rrmSmeContext.rrmConfig.rrm_enabled;
+
+	val = pMac->mlme_cfg->feature_flags.enable_block_ack;
+	selfCaps.delayedBA =
+		(uint16_t) ((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1);
+	selfCaps.immediateBA =
+		(uint16_t) ((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1);
+	pCfgValue16 = (uint16_t *) &selfCaps;
+
+	/*
+	 * RSN caps arent been sent to firmware, so in case of PMF required,
+	 * the firmware connects to a non PMF AP advertising PMF not required
+	 * in the re-assoc request which violates protocol.
+	 * So send this to firmware in the roam SCAN offload command to
+	 * let it configure the params in the re-assoc request too.
+	 * Instead of making another infra, send the RSN-CAPS in MSB of
+	 * beacon Caps.
+	 */
+	roam_offload_params->capability = *((uint32_t *)(&roam_req->rsn_caps));
+	roam_offload_params->capability <<= RSN_CAPS_SHIFT;
+	roam_offload_params->capability |= ((*pCfgValue16) & 0xFFFF);
+
+	roam_offload_params->ht_caps_info =
+		*(uint32_t *)&pMac->mlme_cfg->ht_caps.ht_cap_info;
+
+	roam_offload_params->ampdu_param =
+		*(uint32_t *)&pMac->mlme_cfg->ht_caps.ampdu_params;
+
+	roam_offload_params->ht_ext_cap =
+		*(uint32_t *)&pMac->mlme_cfg->ht_caps.ext_cap_info;
+
+	val_len = ROAM_OFFLOAD_NUM_MCS_SET;
+	if (wlan_mlme_get_cfg_str((uint8_t *)roam_offload_params->mcsset,
+				  &pMac->mlme_cfg->rates.supported_mcs_set,
+				  &val_len) != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
+			  "Failed to get CFG_SUPPORTED_MCS_SET");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (wlan_cfg_get_int(pMac, WNI_CFG_TX_BF_CAP, &nCfgValue) !=
+							QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
+			  "Failed to get WNI_CFG_TX_BF_CAP");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* tSirMacTxBFCapabilityInfo */
+	nCfgValue8 = (uint8_t) nCfgValue;
+	roam_offload_params->ht_txbf = nCfgValue8 & 0xFF;
+	if (wlan_cfg_get_int(pMac, WNI_CFG_AS_CAP, &nCfgValue) !=
+							QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
+			  "Failed to get WNI_CFG_AS_CAP");
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* tSirMacASCapabilityInfo */
+	nCfgValue8 = (uint8_t) nCfgValue;
+	roam_offload_params->asel_cap = nCfgValue8 & 0xFF;
+
+	/* QOS Info */
+	nCfgValue8 = pMac->mlme_cfg->wmm_params.max_sp_length;
+	macQosInfoSta.maxSpLen = nCfgValue8;
+	macQosInfoSta.moreDataAck = 0;
+	macQosInfoSta.qack = 0;
+	macQosInfoSta.acbe_uapsd = roam_req->AcUapsd.acbe_uapsd;
+	macQosInfoSta.acbk_uapsd = roam_req->AcUapsd.acbk_uapsd;
+	macQosInfoSta.acvi_uapsd = roam_req->AcUapsd.acvi_uapsd;
+	macQosInfoSta.acvo_uapsd = roam_req->AcUapsd.acvo_uapsd;
+	pCfgValue8 = (uint8_t *) &macQosInfoSta;
+	/* macQosInfoSta Only queue_request is set.Refer to
+	 * populate_dot11f_wmm_caps for more details
+	 */
+	roam_offload_params->qos_caps = (*pCfgValue8) & 0xFF;
+	if (roam_offload_params->qos_caps)
+		roam_offload_params->qos_enabled = true;
+	roam_offload_params->wmm_caps = 0x4 & 0xFF;
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_set_ric_req() - set ric request element
+ * @wma: wma handle
+ * @msg: message
+ * @is_add_ts: is addts required
+ *
+ * This function sets ric request element for 11r roaming.
+ *
+ * Return: none
+ */
+void wma_set_ric_req(tp_wma_handle wma, void *msg, uint8_t is_add_ts)
+{
+	if (!wma) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return;
+	}
+
+	wmi_unified_set_ric_req_cmd(wma->wmi_handle, msg, is_add_ts);
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+#ifdef FEATURE_RSSI_MONITOR
+/**
+ * wma_set_rssi_monitoring() - set rssi monitoring
+ * @handle: WMA handle
+ * @req: rssi monitoring request structure
+ *
+ * This function reads the incoming @req and fill in the destination
+ * WMI structure and send down the rssi monitoring configs down to the firmware
+ *
+ * Return: 0 on success; error number otherwise
+ */
+QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma,
+				   struct rssi_monitor_req *req)
+{
+	struct rssi_monitor_param params = {0};
+
+	if (!wma) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	params.request_id = req->request_id;
+	params.session_id = req->session_id;
+	params.min_rssi = req->min_rssi;
+	params.max_rssi = req->max_rssi;
+	params.control = req->control;
+
+	return wmi_unified_set_rssi_monitoring_cmd(wma->wmi_handle,
+						   &params);
+}
+
+/**
+ * wma_rssi_breached_event_handler() - rssi breached event handler
+ * @handle: wma handle
+ * @cmd_param_info: event handler data
+ * @len: length of @cmd_param_info
+ *
+ * Return: 0 on success; error number otherwise
+ */
+int wma_rssi_breached_event_handler(void *handle,
+				u_int8_t  *cmd_param_info, u_int32_t len)
+{
+	WMI_RSSI_BREACH_EVENTID_param_tlvs *param_buf;
+	wmi_rssi_breach_event_fixed_param  *event;
+	struct rssi_breach_event  rssi;
+	tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac) {
+		WMA_LOGE("%s: Invalid mac context", __func__);
+		return -EINVAL;
+	}
+	if (!mac->sme.rssi_threshold_breached_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+	param_buf = (WMI_RSSI_BREACH_EVENTID_param_tlvs *)cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid rssi breached event", __func__);
+		return -EINVAL;
+	}
+	event = param_buf->fixed_param;
+
+	rssi.request_id = event->request_id;
+	rssi.session_id = event->vdev_id;
+	rssi.curr_rssi = event->rssi + WMA_TGT_NOISE_FLOOR_DBM;
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->bssid, rssi.curr_bssid.bytes);
+
+	WMA_LOGD("%s: req_id: %u vdev_id: %d curr_rssi: %d", __func__,
+		 rssi.request_id, rssi.session_id, rssi.curr_rssi);
+	WMA_LOGI("%s: curr_bssid: %pM", __func__, rssi.curr_bssid.bytes);
+
+	mac->sme.rssi_threshold_breached_cb(mac->hdd_handle, &rssi);
+	WMA_LOGD("%s: Invoke HDD rssi breached callback", __func__);
+	return 0;
+}
+#endif /* FEATURE_RSSI_MONITOR */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * wma_roam_ho_fail_handler() - LFR3.0 roam hand off failed handler
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: none
+ */
+static void wma_roam_ho_fail_handler(tp_wma_handle wma, uint32_t vdev_id)
+{
+	tSirSmeHOFailureInd *ho_failure_ind;
+	struct scheduler_msg sme_msg = { 0 };
+	QDF_STATUS qdf_status;
+
+	ho_failure_ind = qdf_mem_malloc(sizeof(tSirSmeHOFailureInd));
+	if (!ho_failure_ind)
+		return;
+
+	ho_failure_ind->sessionId = vdev_id;
+	sme_msg.type = eWNI_SME_HO_FAIL_IND;
+	sme_msg.bodyptr = ho_failure_ind;
+	sme_msg.bodyval = 0;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("Fail to post eWNI_SME_HO_FAIL_IND msg to SME");
+		qdf_mem_free(ho_failure_ind);
+		return;
+	}
+}
+
+/**
+ * wma_process_roam_synch_complete() - roam synch complete command to fw.
+ * @handle: wma handle
+ * @synchcnf: offload synch confirmation params
+ *
+ * This function sends roam synch complete event to fw.
+ *
+ * Return: none
+ */
+void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+
+	if (!wma_handle || !wma_handle->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue roam synch cnf",
+			 __func__);
+		return;
+	}
+
+	if (wmi_unified_roam_synch_complete_cmd(wma_handle->wmi_handle,
+				 vdev_id)) {
+		return;
+	}
+
+	DPTRACE(qdf_dp_trace_record_event(QDF_DP_TRACE_EVENT_RECORD,
+		vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
+		QDF_PROTO_TYPE_EVENT, QDF_ROAM_COMPLETE));
+
+	WMA_LOGI("LFR3: Posting WMA_ROAM_OFFLOAD_SYNCH_CNF");
+	wlan_roam_debug_log(vdev_id, DEBUG_ROAM_SYNCH_CNF,
+			    DEBUG_INVALID_PEER_ID, NULL, NULL, 0, 0);
+
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+/**
+ * wma_set_channel() - set channel
+ * @wma: wma handle
+ * @params: switch channel parameters
+ *
+ * Return: none
+ */
+void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params)
+{
+	struct wma_vdev_start_req req;
+	struct wma_target_req *msg;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t vdev_id, peer_id;
+	void *peer;
+	struct cdp_pdev *pdev;
+	struct wma_txrx_node *intr = wma->interfaces;
+	struct policy_mgr_hw_mode_params hw_mode = {0};
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	uint16_t beacon_interval_ori;
+
+	WMA_LOGD("%s: Enter", __func__);
+	if (!wma_find_vdev_by_addr(wma, params->selfStaMacAddr, &vdev_id)) {
+		WMA_LOGP("%s: Failed to find vdev id for %pM",
+			 __func__, params->selfStaMacAddr);
+		status = QDF_STATUS_E_FAILURE;
+		goto send_resp;
+	}
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (NULL == pdev) {
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+		status = QDF_STATUS_E_FAILURE;
+		goto send_resp;
+	}
+
+	peer = cdp_peer_find_by_addr(soc,
+			pdev,
+			intr[vdev_id].bssid, &peer_id);
+
+	qdf_mem_zero(&req, sizeof(req));
+	req.vdev_id = vdev_id;
+	req.chan = params->channelNumber;
+	req.chan_width = params->ch_width;
+
+	if (params->ch_width == CH_WIDTH_10MHZ)
+		req.is_half_rate = 1;
+	else if (params->ch_width == CH_WIDTH_5MHZ)
+		req.is_quarter_rate = 1;
+
+	req.vht_capable = params->vhtCapable;
+	req.ch_center_freq_seg0 = params->ch_center_freq_seg0;
+	req.ch_center_freq_seg1 = params->ch_center_freq_seg1;
+	req.dot11_mode = params->dot11_mode;
+	wma_update_vdev_he_capable(&req, params);
+
+	WMA_LOGI(FL("vht_capable: %d, dot11_mode: %d"),
+		 req.vht_capable, req.dot11_mode);
+
+	status = policy_mgr_get_current_hw_mode(wma->psoc, &hw_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		WMA_LOGE("policy_mgr_get_current_hw_mode failed");
+
+	if (params->nss == 2) {
+		req.preferred_rx_streams = 2;
+		req.preferred_tx_streams = 2;
+	} else {
+		req.preferred_rx_streams = 1;
+		req.preferred_tx_streams = 1;
+	}
+
+	req.max_txpow = params->maxTxPower;
+	req.beacon_intval = 100;
+	req.dtim_period = 1;
+	req.is_dfs = params->isDfsChannel;
+	req.cac_duration_ms = params->cac_duration_ms;
+	req.dfs_regdomain = params->dfs_regdomain;
+
+	/* In case of AP mode, once radar is detected, we need to
+	 * issuse VDEV RESTART, so we making is_channel_switch as
+	 * true
+	 */
+	if ((wma_is_vdev_in_ap_mode(wma, req.vdev_id) == true) ||
+	    (params->restart_on_chan_switch == true)) {
+#ifndef CONFIG_VDEV_SM
+		wma->interfaces[req.vdev_id].is_channel_switch = true;
+#endif
+		req.hidden_ssid = intr[vdev_id].vdev_restart_params.ssidHidden;
+	}
+
+	if (params->restart_on_chan_switch == true &&
+			wma->interfaces[req.vdev_id].beacon_filter_enabled)
+		wma_remove_beacon_filter(wma,
+				&wma->interfaces[req.vdev_id].beacon_filter);
+
+	if ((wma_is_vdev_in_ap_mode(wma, req.vdev_id) == true) &&
+		(params->reduced_beacon_interval)) {
+		/* Reduce the beacon interval just before the channel switch.
+		 * This would help in reducing the downtime on the STA side
+		 * (which is waiting for beacons from the AP to resume back
+		 * transmission). Switch back the beacon_interval to its
+		 * original value after the channel switch based on the
+		 * timeout. This would ensure there are atleast some beacons
+		 * sent with increased frequency.
+		 */
+
+		WMA_LOGD("%s: Changing beacon interval to %d",
+			__func__, params->reduced_beacon_interval);
+
+		/* Add a timer to reset the beacon interval back*/
+		beacon_interval_ori = req.beacon_intval;
+		req.beacon_intval = params->reduced_beacon_interval;
+		if (wma_fill_beacon_interval_reset_req(wma,
+			req.vdev_id,
+			beacon_interval_ori,
+			RESET_BEACON_INTERVAL_TIMEOUT)) {
+
+			WMA_LOGD("%s: Failed to fill beacon interval reset req",
+				__func__);
+		}
+	}
+
+	if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() &&
+	    wma_is_vdev_up(vdev_id)) {
+		WMA_LOGD("%s: setting channel switch to true for vdev_id:%d",
+			 __func__, req.vdev_id);
+#ifndef CONFIG_VDEV_SM
+		wma->interfaces[req.vdev_id].is_channel_switch = true;
+#endif
+	}
+
+	msg = wma_fill_vdev_req(wma, req.vdev_id, WMA_CHNL_SWITCH_REQ,
+			WMA_TARGET_REQ_TYPE_VDEV_START, params,
+			WMA_VDEV_START_REQUEST_TIMEOUT);
+	if (!msg) {
+		WMA_LOGP("%s: Failed to fill channel switch request for vdev %d",
+			__func__, req.vdev_id);
+		status = QDF_STATUS_E_NOMEM;
+		goto send_resp;
+	}
+#ifdef CONFIG_VDEV_SM
+	status = wma_vdev_start(wma, &req,
+				mlme_is_chan_switch_in_progress(
+				wma->interfaces[req.vdev_id].vdev));
+#else
+	status = wma_vdev_start(wma, &req,
+			wma->interfaces[req.vdev_id].is_channel_switch);
+#endif
+	if (status != QDF_STATUS_SUCCESS) {
+		wma_remove_vdev_req(wma, req.vdev_id,
+				    WMA_TARGET_REQ_TYPE_VDEV_START);
+		WMA_LOGP("%s: vdev start failed status = %d", __func__,
+			status);
+		goto send_resp;
+	}
+
+	/* This is temporary, should be removed */
+	if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
+		ol_htt_mon_note_chan(pdev, req.chan);
+
+	return;
+send_resp:
+	WMA_LOGD("%s: channel %d ch_width %d txpower %d status %d", __func__,
+		 params->channelNumber, params->ch_width,
+		 params->maxTxPower,
+		 status);
+	params->status = status;
+	WMA_LOGI("%s: sending WMA_SWITCH_CHANNEL_RSP, status = 0x%x",
+		 __func__, status);
+	wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP,
+				   (void *)params, 0);
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * wma_plm_start() - plm start request
+ * @wma: wma handle
+ * @plm: plm request parameters
+ *
+ * This function request FW to start PLM.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_plm_start(tp_wma_handle wma, const tpSirPlmReq plm)
+{
+	struct plm_req_params params = {0};
+	uint32_t num_channels;
+	uint32_t *channel_list = NULL;
+	uint32_t i;
+	QDF_STATUS status;
+
+	if (NULL == plm || NULL == wma) {
+		WMA_LOGE("%s: input pointer is NULL ", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	WMA_LOGD("PLM Start");
+
+	num_channels =  plm->plmNumCh;
+
+	if (num_channels) {
+		channel_list = qdf_mem_malloc(sizeof(uint32_t) * num_channels);
+		if (!channel_list)
+			return QDF_STATUS_E_FAILURE;
+
+		for (i = 0; i < num_channels; i++) {
+			channel_list[i] = plm->plmChList[i];
+
+			if (channel_list[i] < WMA_NLO_FREQ_THRESH)
+				channel_list[i] =
+					cds_chan_to_freq(channel_list[i]);
+		}
+	}
+
+	params.diag_token = plm->diag_token;
+	params.meas_token = plm->meas_token;
+	params.num_bursts = plm->numBursts;
+	params.burst_int = plm->burstInt;
+	params.meas_duration = plm->measDuration;
+	params.burst_len = plm->burstLen;
+	params.desired_tx_pwr = plm->desiredTxPwr;
+	params.plm_num_ch = plm->plmNumCh;
+	params.session_id = plm->sessionId;
+	params.enable = plm->enable;
+	qdf_mem_copy(&params.mac_addr, &plm->mac_addr,
+			sizeof(struct qdf_mac_addr));
+	qdf_mem_copy(params.plm_ch_list, plm->plmChList,
+				WMI_CFG_VALID_CHANNEL_LIST_LEN);
+
+	status = wmi_unified_plm_start_cmd(wma->wmi_handle,
+				&params, channel_list);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		qdf_mem_free(channel_list);
+		return status;
+	}
+
+	qdf_mem_free(channel_list);
+	wma->interfaces[plm->sessionId].plm_in_progress = true;
+
+	WMA_LOGD("Plm start request sent successfully for vdev %d",
+		 plm->sessionId);
+
+	return status;
+}
+
+/**
+ * wma_plm_stop() - plm stop request
+ * @wma: wma handle
+ * @plm: plm request parameters
+ *
+ * This function request FW to stop PLM.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_plm_stop(tp_wma_handle wma, const tpSirPlmReq plm)
+{
+	struct plm_req_params params = {0};
+	QDF_STATUS status;
+
+	if (NULL == plm || NULL == wma) {
+		WMA_LOGE("%s: input pointer is NULL ", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (false == wma->interfaces[plm->sessionId].plm_in_progress) {
+		WMA_LOGE("No active plm req found, skip plm stop req");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("PLM Stop");
+
+	params.diag_token = plm->diag_token;
+	params.meas_token = plm->meas_token;
+	params.num_bursts = plm->numBursts;
+	params.burst_int = plm->burstInt;
+	params.meas_duration = plm->measDuration;
+	params.burst_len = plm->burstLen;
+	params.desired_tx_pwr = plm->desiredTxPwr;
+	params.plm_num_ch = plm->plmNumCh;
+	params.session_id = plm->sessionId;
+	params.enable = plm->enable;
+	qdf_mem_copy(&params.mac_addr, &plm->mac_addr,
+			sizeof(struct qdf_mac_addr));
+	qdf_mem_copy(params.plm_ch_list, plm->plmChList,
+				WMI_CFG_VALID_CHANNEL_LIST_LEN);
+
+	status = wmi_unified_plm_stop_cmd(wma->wmi_handle,
+						&params);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	wma->interfaces[plm->sessionId].plm_in_progress = false;
+
+	WMA_LOGD("Plm stop request sent successfully for vdev %d",
+		 plm->sessionId);
+
+	return status;
+}
+
+/**
+ * wma_config_plm()- config PLM
+ * @wma: wma handle
+ * @plm: plm request parameters
+ *
+ * Return: none
+ */
+void wma_config_plm(tp_wma_handle wma, tpSirPlmReq plm)
+{
+	QDF_STATUS ret = 0;
+
+	if (NULL == plm || NULL == wma)
+		return;
+
+	if (plm->enable)
+		ret = wma_plm_start(wma, plm);
+	else
+		ret = wma_plm_stop(wma, plm);
+
+	if (ret)
+		WMA_LOGE("%s: PLM %s failed %d", __func__,
+			 plm->enable ? "start" : "stop", ret);
+
+	/* SME expects WMA to free tpSirPlmReq memory after
+	 * processing PLM request.
+	 */
+	qdf_mem_free(plm);
+	plm = NULL;
+}
+#endif
+
+#ifdef FEATURE_WLAN_EXTSCAN
+/**
+ * wma_extscan_wow_event_callback() - extscan wow event callback
+ * @handle: WMA handle
+ * @event: event buffer
+ * @len: length of @event buffer
+ *
+ * In wow case, the wow event is followed by the payload of the event
+ * which generated the wow event.
+ * payload is 4 bytes of length followed by event buffer. the first 4 bytes
+ * of event buffer is common tlv header, which is a combination
+ * of tag (higher 2 bytes) and length (lower 2 bytes). The tag is used to
+ * identify the event which triggered wow event.
+ * Payload is extracted and converted into generic tlv structure before
+ * being passed to this function.
+ *
+ * @Return: Errno
+ */
+int wma_extscan_wow_event_callback(void *handle, void *event, uint32_t len)
+{
+	uint32_t tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(event));
+
+	switch (tag) {
+	case WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param:
+		return wma_extscan_start_stop_event_handler(handle, event, len);
+
+	case WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param:
+		return wma_extscan_operations_event_handler(handle, event, len);
+
+	case WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param:
+		return wma_extscan_table_usage_event_handler(handle, event,
+							     len);
+
+	case WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param:
+		return wma_extscan_cached_results_event_handler(handle, event,
+								len);
+
+	case WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param:
+		return wma_extscan_change_results_event_handler(handle, event,
+								len);
+
+	case WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param:
+		return wma_extscan_hotlist_match_event_handler(handle,	event,
+							       len);
+
+	case WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param:
+		return wma_extscan_capabilities_event_handler(handle, event,
+							      len);
+
+	default:
+		WMA_LOGE(FL("Unknown tag: %d"), tag);
+		return 0;
+	}
+}
+
+/**
+ * wma_register_extscan_event_handler() - register extscan event handler
+ * @wma_handle: wma handle
+ *
+ * This function register extscan related event handlers.
+ *
+ * Return: none
+ */
+void wma_register_extscan_event_handler(tp_wma_handle wma_handle)
+{
+	if (!wma_handle) {
+		WMA_LOGE("%s: extscan wma_handle is NULL", __func__);
+		return;
+	}
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_extscan_start_stop_event_id,
+					   wma_extscan_start_stop_event_handler,
+					   WMA_RX_SERIALIZER_CTX);
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					wmi_extscan_capabilities_event_id,
+					wma_extscan_capabilities_event_handler,
+					WMA_RX_SERIALIZER_CTX);
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_extscan_hotlist_match_event_id,
+				wma_extscan_hotlist_match_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_extscan_wlan_change_results_event_id,
+				wma_extscan_change_results_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_extscan_operation_event_id,
+				wma_extscan_operations_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_extscan_table_usage_event_id,
+				wma_extscan_table_usage_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_extscan_cached_results_event_id,
+				wma_extscan_cached_results_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+			wmi_passpoint_match_event_id,
+			wma_passpoint_match_event_handler,
+			WMA_RX_SERIALIZER_CTX);
+}
+
+/**
+ * wma_extscan_start_stop_event_handler() -  extscan start/stop event handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: data length
+ *
+ * This function handles different extscan related commands
+ * like start/stop/get results etc and indicate to upper layers.
+ *
+ * Return: 0 for success or error code.
+ */
+int wma_extscan_start_stop_event_handler(void *handle,
+					 uint8_t *cmd_param_info,
+					 uint32_t len)
+{
+	WMI_EXTSCAN_START_STOP_EVENTID_param_tlvs *param_buf;
+	wmi_extscan_start_stop_event_fixed_param *event;
+	struct sir_extscan_generic_response   *extscan_ind;
+	uint16_t event_type;
+	tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!pMac) {
+		WMA_LOGE("%s: Invalid pMac", __func__);
+		return -EINVAL;
+	}
+	if (!pMac->sme.ext_scan_ind_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+	param_buf = (WMI_EXTSCAN_START_STOP_EVENTID_param_tlvs *)
+		    cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid extscan event", __func__);
+		return -EINVAL;
+	}
+	event = param_buf->fixed_param;
+	extscan_ind = qdf_mem_malloc(sizeof(*extscan_ind));
+	if (!extscan_ind)
+		return -ENOMEM;
+
+	switch (event->command) {
+	case WMI_EXTSCAN_START_CMDID:
+		event_type = eSIR_EXTSCAN_START_RSP;
+		extscan_ind->status = event->status;
+		extscan_ind->request_id = event->request_id;
+		break;
+	case WMI_EXTSCAN_STOP_CMDID:
+		event_type = eSIR_EXTSCAN_STOP_RSP;
+		extscan_ind->status = event->status;
+		extscan_ind->request_id = event->request_id;
+		break;
+	case WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID:
+		extscan_ind->status = event->status;
+		extscan_ind->request_id = event->request_id;
+		if (event->mode == WMI_EXTSCAN_MODE_STOP)
+			event_type =
+				eSIR_EXTSCAN_RESET_SIGNIFICANT_WIFI_CHANGE_RSP;
+		else
+			event_type =
+				eSIR_EXTSCAN_SET_SIGNIFICANT_WIFI_CHANGE_RSP;
+		break;
+	case WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID:
+		extscan_ind->status = event->status;
+		extscan_ind->request_id = event->request_id;
+		if (event->mode == WMI_EXTSCAN_MODE_STOP)
+			event_type = eSIR_EXTSCAN_RESET_BSSID_HOTLIST_RSP;
+		else
+			event_type = eSIR_EXTSCAN_SET_BSSID_HOTLIST_RSP;
+		break;
+	case WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID:
+		extscan_ind->status = event->status;
+		extscan_ind->request_id = event->request_id;
+		event_type = eSIR_EXTSCAN_CACHED_RESULTS_RSP;
+		break;
+	case WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID:
+		extscan_ind->status = event->status;
+		extscan_ind->request_id = event->request_id;
+		if (event->mode == WMI_EXTSCAN_MODE_STOP)
+			event_type =
+				eSIR_EXTSCAN_RESET_SSID_HOTLIST_RSP;
+		else
+			event_type =
+				eSIR_EXTSCAN_SET_SSID_HOTLIST_RSP;
+		break;
+	default:
+		WMA_LOGE("%s: Unknown event(%d) from target",
+			 __func__, event->status);
+		qdf_mem_free(extscan_ind);
+		return -EINVAL;
+	}
+	pMac->sme.ext_scan_ind_cb(pMac->hdd_handle, event_type, extscan_ind);
+	WMA_LOGD("%s: sending event to umac for requestid %u with status %d",
+		__func__, extscan_ind->request_id, extscan_ind->status);
+	qdf_mem_free(extscan_ind);
+	return 0;
+}
+
+/**
+ * wma_extscan_operations_event_handler() - extscan operation event handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: length
+ *
+ * This function handles different operations related event and indicate
+ * upper layers with appropriate callback.
+ *
+ * Return: 0 for success or error code.
+ */
+int wma_extscan_operations_event_handler(void *handle,
+					 uint8_t *cmd_param_info,
+					 uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_EXTSCAN_OPERATION_EVENTID_param_tlvs *param_buf;
+	wmi_extscan_operation_event_fixed_param *oprn_event;
+	tSirExtScanOnScanEventIndParams *oprn_ind;
+	uint32_t cnt;
+	tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!pMac) {
+		WMA_LOGE("%s: Invalid pMac", __func__);
+		return -EINVAL;
+	}
+	if (!pMac->sme.ext_scan_ind_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+	param_buf = (WMI_EXTSCAN_OPERATION_EVENTID_param_tlvs *)
+		    cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid scan operation event", __func__);
+		return -EINVAL;
+	}
+	oprn_event = param_buf->fixed_param;
+	oprn_ind = qdf_mem_malloc(sizeof(*oprn_ind));
+	if (!oprn_ind)
+		return -ENOMEM;
+
+	oprn_ind->requestId = oprn_event->request_id;
+
+	switch (oprn_event->event) {
+	case WMI_EXTSCAN_BUCKET_COMPLETED_EVENT:
+		oprn_ind->status = 0;
+		goto exit_handler;
+	case WMI_EXTSCAN_CYCLE_STARTED_EVENT:
+		WMA_LOGD("%s: received WMI_EXTSCAN_CYCLE_STARTED_EVENT",
+			 __func__);
+
+		if (oprn_event->num_buckets > param_buf->num_bucket_id) {
+			WMA_LOGE("FW mesg num_buk %d more than TLV hdr %d",
+				 oprn_event->num_buckets,
+				 param_buf->num_bucket_id);
+			return -EINVAL;
+		}
+
+		cds_host_diag_log_work(&wma->extscan_wake_lock,
+				       WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION,
+				       WIFI_POWER_EVENT_WAKELOCK_EXT_SCAN);
+		qdf_wake_lock_timeout_acquire(&wma->extscan_wake_lock,
+				      WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION);
+		oprn_ind->scanEventType = WIFI_EXTSCAN_CYCLE_STARTED_EVENT;
+		oprn_ind->status = 0;
+		oprn_ind->buckets_scanned = 0;
+		for (cnt = 0; cnt < oprn_event->num_buckets; cnt++)
+			oprn_ind->buckets_scanned |=
+				(1 << param_buf->bucket_id[cnt]);
+		WMA_LOGD(FL("num_buckets %u request_id %u buckets_scanned %u"),
+			oprn_event->num_buckets, oprn_ind->requestId,
+			oprn_ind->buckets_scanned);
+		break;
+	case WMI_EXTSCAN_CYCLE_COMPLETED_EVENT:
+		WMA_LOGD("%s: received WMI_EXTSCAN_CYCLE_COMPLETED_EVENT",
+			 __func__);
+		qdf_wake_lock_release(&wma->extscan_wake_lock,
+				      WIFI_POWER_EVENT_WAKELOCK_EXT_SCAN);
+		oprn_ind->scanEventType = WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT;
+		oprn_ind->status = 0;
+		/* Set bucket scanned mask to zero on cycle complete */
+		oprn_ind->buckets_scanned = 0;
+		break;
+	case WMI_EXTSCAN_BUCKET_STARTED_EVENT:
+		WMA_LOGD("%s: received WMI_EXTSCAN_BUCKET_STARTED_EVENT",
+			__func__);
+		oprn_ind->scanEventType = WIFI_EXTSCAN_BUCKET_STARTED_EVENT;
+		oprn_ind->status = 0;
+		goto exit_handler;
+	case WMI_EXTSCAN_THRESHOLD_NUM_SCANS:
+		WMA_LOGD("%s: received WMI_EXTSCAN_THRESHOLD_NUM_SCANS",
+			__func__);
+		oprn_ind->scanEventType = WIFI_EXTSCAN_THRESHOLD_NUM_SCANS;
+		oprn_ind->status = 0;
+		break;
+	case WMI_EXTSCAN_THRESHOLD_PERCENT:
+		WMA_LOGD("%s: received WMI_EXTSCAN_THRESHOLD_PERCENT",
+			__func__);
+		oprn_ind->scanEventType = WIFI_EXTSCAN_THRESHOLD_PERCENT;
+		oprn_ind->status = 0;
+		break;
+	default:
+		WMA_LOGE("%s: Unknown event(%d) from target",
+			 __func__, oprn_event->event);
+		qdf_mem_free(oprn_ind);
+		return -EINVAL;
+	}
+	pMac->sme.ext_scan_ind_cb(pMac->hdd_handle,
+				eSIR_EXTSCAN_SCAN_PROGRESS_EVENT_IND, oprn_ind);
+	WMA_LOGI("%s: sending scan progress event to hdd", __func__);
+exit_handler:
+	qdf_mem_free(oprn_ind);
+	return 0;
+}
+
+/**
+ * wma_extscan_table_usage_event_handler() - extscan table usage event handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: length
+ *
+ * This function handles table usage related event and indicate
+ * upper layers with appropriate callback.
+ *
+ * Return: 0 for success or error code.
+ */
+int wma_extscan_table_usage_event_handler(void *handle,
+					  uint8_t *cmd_param_info,
+					  uint32_t len)
+{
+	WMI_EXTSCAN_TABLE_USAGE_EVENTID_param_tlvs *param_buf;
+	wmi_extscan_table_usage_event_fixed_param *event;
+	tSirExtScanResultsAvailableIndParams *tbl_usg_ind;
+	tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!pMac) {
+		WMA_LOGE("%s: Invalid pMac", __func__);
+		return -EINVAL;
+	}
+	if (!pMac->sme.ext_scan_ind_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+	param_buf = (WMI_EXTSCAN_TABLE_USAGE_EVENTID_param_tlvs *)
+		    cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid table usage event", __func__);
+		return -EINVAL;
+	}
+	event = param_buf->fixed_param;
+	tbl_usg_ind = qdf_mem_malloc(sizeof(*tbl_usg_ind));
+	if (!tbl_usg_ind)
+		return -ENOMEM;
+
+	tbl_usg_ind->requestId = event->request_id;
+	tbl_usg_ind->numResultsAvailable = event->entries_in_use;
+	pMac->sme.ext_scan_ind_cb(pMac->hdd_handle,
+				eSIR_EXTSCAN_SCAN_RES_AVAILABLE_IND,
+				tbl_usg_ind);
+	WMA_LOGI("%s: sending scan_res available event to hdd", __func__);
+	qdf_mem_free(tbl_usg_ind);
+	return 0;
+}
+
+/**
+ * wma_extscan_capabilities_event_handler() - extscan capabilities event handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: length
+ *
+ * This function handles capabilities event and indicate
+ * upper layers with registered callback.
+ *
+ * Return: 0 for success or error code.
+ */
+int wma_extscan_capabilities_event_handler(void *handle,
+					   uint8_t *cmd_param_info,
+					   uint32_t len)
+{
+	WMI_EXTSCAN_CAPABILITIES_EVENTID_param_tlvs *param_buf;
+	wmi_extscan_capabilities_event_fixed_param *event;
+	wmi_extscan_cache_capabilities *src_cache;
+	wmi_extscan_hotlist_monitor_capabilities *src_hotlist;
+	wmi_extscan_wlan_change_monitor_capabilities *src_change;
+	struct ext_scan_capabilities_response  *dest_capab;
+	tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!pMac) {
+		WMA_LOGE("%s: Invalid pMac", __func__);
+		return -EINVAL;
+	}
+	if (!pMac->sme.ext_scan_ind_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+	param_buf = (WMI_EXTSCAN_CAPABILITIES_EVENTID_param_tlvs *)
+		    cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid capabilities event", __func__);
+		return -EINVAL;
+	}
+	event = param_buf->fixed_param;
+	src_cache = param_buf->extscan_cache_capabilities;
+	src_hotlist = param_buf->hotlist_capabilities;
+	src_change = param_buf->wlan_change_capabilities;
+
+	if (!src_cache || !src_hotlist || !src_change) {
+		WMA_LOGE("%s: Invalid capabilities list", __func__);
+		return -EINVAL;
+	}
+	dest_capab = qdf_mem_malloc(sizeof(*dest_capab));
+	if (!dest_capab)
+		return -ENOMEM;
+
+	dest_capab->requestId = event->request_id;
+	dest_capab->max_scan_buckets = src_cache->max_buckets;
+	dest_capab->max_scan_cache_size = src_cache->scan_cache_entry_size;
+	dest_capab->max_ap_cache_per_scan = src_cache->max_bssid_per_scan;
+	dest_capab->max_scan_reporting_threshold =
+		src_cache->max_table_usage_threshold;
+
+	dest_capab->max_hotlist_bssids = src_hotlist->max_hotlist_entries;
+	dest_capab->max_rssi_sample_size =
+					src_change->max_rssi_averaging_samples;
+	dest_capab->max_bssid_history_entries =
+		src_change->max_rssi_history_entries;
+	dest_capab->max_significant_wifi_change_aps =
+		src_change->max_wlan_change_entries;
+	dest_capab->max_hotlist_ssids =
+				event->num_extscan_hotlist_ssid;
+	dest_capab->max_number_epno_networks =
+				event->num_epno_networks;
+	dest_capab->max_number_epno_networks_by_ssid =
+				event->num_epno_networks;
+	dest_capab->max_number_of_white_listed_ssid =
+				event->num_roam_ssid_whitelist;
+	dest_capab->max_number_of_black_listed_bssid =
+				event->num_roam_bssid_blacklist;
+	dest_capab->status = 0;
+
+	WMA_LOGD("%s: request_id: %u status: %d",
+		__func__, dest_capab->requestId, dest_capab->status);
+
+	WMA_LOGD("%s: Capabilities: max_scan_buckets: %d, max_hotlist_bssids: %d, max_scan_cache_size: %d, max_ap_cache_per_scan: %d",
+		 __func__, dest_capab->max_scan_buckets,
+		dest_capab->max_hotlist_bssids, dest_capab->max_scan_cache_size,
+		dest_capab->max_ap_cache_per_scan);
+	WMA_LOGD("%s: max_scan_reporting_threshold: %d, max_rssi_sample_size: %d, max_bssid_history_entries: %d, max_significant_wifi_change_aps: %d",
+		__func__, dest_capab->max_scan_reporting_threshold,
+		dest_capab->max_rssi_sample_size,
+		dest_capab->max_bssid_history_entries,
+		dest_capab->max_significant_wifi_change_aps);
+
+	WMA_LOGD("%s: Capabilities: max_hotlist_ssids: %d, max_number_epno_networks: %d, max_number_epno_networks_by_ssid: %d",
+		 __func__, dest_capab->max_hotlist_ssids,
+		dest_capab->max_number_epno_networks,
+		dest_capab->max_number_epno_networks_by_ssid);
+	WMA_LOGD("%s: max_number_of_white_listed_ssid: %d, max_number_of_black_listed_bssid: %d",
+		__func__, dest_capab->max_number_of_white_listed_ssid,
+		dest_capab->max_number_of_black_listed_bssid);
+
+	pMac->sme.ext_scan_ind_cb(pMac->hdd_handle,
+				eSIR_EXTSCAN_GET_CAPABILITIES_IND, dest_capab);
+	qdf_mem_free(dest_capab);
+	return 0;
+}
+
+/**
+ * wma_extscan_hotlist_match_event_handler() - hotlist match event handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: length
+ *
+ * This function handles hotlist match event and indicate
+ * upper layers with registered callback.
+ *
+ * Return: 0 for success or error code.
+ */
+int wma_extscan_hotlist_match_event_handler(void *handle,
+					    uint8_t *cmd_param_info,
+					    uint32_t len)
+{
+	WMI_EXTSCAN_HOTLIST_MATCH_EVENTID_param_tlvs *param_buf;
+	wmi_extscan_hotlist_match_event_fixed_param *event;
+	struct extscan_hotlist_match *dest_hotlist;
+	tSirWifiScanResult *dest_ap;
+	wmi_extscan_wlan_descriptor *src_hotlist;
+	uint32_t numap;
+	int j, ap_found = 0;
+	uint32_t buf_len;
+	tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!pMac) {
+		WMA_LOGE("%s: Invalid pMac", __func__);
+		return -EINVAL;
+	}
+	if (!pMac->sme.ext_scan_ind_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+	param_buf = (WMI_EXTSCAN_HOTLIST_MATCH_EVENTID_param_tlvs *)
+		    cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid hotlist match event", __func__);
+		return -EINVAL;
+	}
+	event = param_buf->fixed_param;
+	src_hotlist = param_buf->hotlist_match;
+	numap = event->total_entries;
+
+	if (!src_hotlist || !numap) {
+		WMA_LOGE("%s: Hotlist AP's list invalid", __func__);
+		return -EINVAL;
+	}
+	if (numap > param_buf->num_hotlist_match) {
+		WMA_LOGE("Invalid no of total enteries %d", numap);
+		return -EINVAL;
+	}
+	if (numap > WMA_EXTSCAN_MAX_HOTLIST_ENTRIES) {
+		WMA_LOGE("%s: Total Entries %u greater than max",
+			__func__, numap);
+		numap = WMA_EXTSCAN_MAX_HOTLIST_ENTRIES;
+	}
+
+	buf_len = sizeof(wmi_extscan_hotlist_match_event_fixed_param) +
+		  WMI_TLV_HDR_SIZE +
+		  (numap * sizeof(wmi_extscan_wlan_descriptor));
+
+	if (buf_len > len) {
+		WMA_LOGE("Invalid buf len from FW %d numap %d", len, numap);
+		return -EINVAL;
+	}
+
+	dest_hotlist = qdf_mem_malloc(sizeof(*dest_hotlist) +
+				      sizeof(*dest_ap) * numap);
+	if (!dest_hotlist)
+		return -ENOMEM;
+
+	dest_ap = &dest_hotlist->ap[0];
+	dest_hotlist->numOfAps = event->total_entries;
+	dest_hotlist->requestId = event->config_request_id;
+
+	if (event->first_entry_index +
+		event->num_entries_in_page < event->total_entries)
+		dest_hotlist->moreData = 1;
+	else
+		dest_hotlist->moreData = 0;
+
+	WMA_LOGD("%s: Hotlist match: requestId: %u,"
+		 "numOfAps: %d", __func__,
+		 dest_hotlist->requestId, dest_hotlist->numOfAps);
+
+	/*
+	 * Currently firmware sends only one bss information in-case
+	 * of both hotlist ap found and lost.
+	 */
+	for (j = 0; j < numap; j++) {
+		dest_ap->rssi = 0;
+		dest_ap->channel = src_hotlist->channel;
+		dest_ap->ts = src_hotlist->tstamp;
+		ap_found = src_hotlist->flags & WMI_HOTLIST_FLAG_PRESENCE;
+		dest_ap->rtt = src_hotlist->rtt;
+		dest_ap->rtt_sd = src_hotlist->rtt_sd;
+		dest_ap->beaconPeriod = src_hotlist->beacon_interval;
+		dest_ap->capability = src_hotlist->capabilities;
+		dest_ap->ieLength = src_hotlist->ie_length;
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_hotlist->bssid,
+					   dest_ap->bssid.bytes);
+		if (src_hotlist->ssid.ssid_len > SIR_MAC_MAX_SSID_LENGTH) {
+			WMA_LOGE("%s Invalid SSID len %d, truncating",
+				 __func__, src_hotlist->ssid.ssid_len);
+			src_hotlist->ssid.ssid_len = SIR_MAC_MAX_SSID_LENGTH;
+		}
+		qdf_mem_copy(dest_ap->ssid, src_hotlist->ssid.ssid,
+			     src_hotlist->ssid.ssid_len);
+		dest_ap->ssid[src_hotlist->ssid.ssid_len] = '\0';
+		dest_ap++;
+		src_hotlist++;
+	}
+	dest_hotlist->ap_found = ap_found;
+	pMac->sme.ext_scan_ind_cb(pMac->hdd_handle,
+				eSIR_EXTSCAN_HOTLIST_MATCH_IND, dest_hotlist);
+	WMA_LOGI("%s: sending hotlist match event to hdd", __func__);
+	qdf_mem_free(dest_hotlist);
+	return 0;
+}
+
+/** wma_extscan_find_unique_scan_ids() - find unique scan ids
+ * @cmd_param_info: event data.
+ *
+ * This utility function parses the input bss table of information
+ * and find the unique number of scan ids
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int wma_extscan_find_unique_scan_ids(const u_int8_t *cmd_param_info)
+{
+	WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
+	wmi_extscan_cached_results_event_fixed_param  *event;
+	wmi_extscan_wlan_descriptor  *src_hotlist;
+	wmi_extscan_rssi_info  *src_rssi;
+	int prev_scan_id, scan_ids_cnt, i;
+
+	param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
+						cmd_param_info;
+	event = param_buf->fixed_param;
+	src_hotlist = param_buf->bssid_list;
+	src_rssi = param_buf->rssi_list;
+
+	/* Find the unique number of scan_id's for grouping */
+	prev_scan_id = src_rssi->scan_cycle_id;
+	scan_ids_cnt = 1;
+	for (i = 1; i < param_buf->num_rssi_list; i++) {
+		src_rssi++;
+
+		if (prev_scan_id != src_rssi->scan_cycle_id) {
+			scan_ids_cnt++;
+			prev_scan_id = src_rssi->scan_cycle_id;
+		}
+	}
+
+	return scan_ids_cnt;
+}
+
+/** wma_fill_num_results_per_scan_id() - fill number of bss per scan id
+ * @cmd_param_info: event data.
+ * @scan_id_group: pointer to scan id group.
+ *
+ * This utility function parses the input bss table of information
+ * and finds how many bss are there per unique scan id.
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int wma_fill_num_results_per_scan_id(const u_int8_t *cmd_param_info,
+			struct extscan_cached_scan_result *scan_id_group)
+{
+	WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
+	wmi_extscan_cached_results_event_fixed_param  *event;
+	wmi_extscan_wlan_descriptor  *src_hotlist;
+	wmi_extscan_rssi_info  *src_rssi;
+	struct extscan_cached_scan_result *t_scan_id_grp;
+	int i, prev_scan_id;
+
+	param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
+						cmd_param_info;
+	event = param_buf->fixed_param;
+	src_hotlist = param_buf->bssid_list;
+	src_rssi = param_buf->rssi_list;
+	t_scan_id_grp = scan_id_group;
+
+	prev_scan_id = src_rssi->scan_cycle_id;
+
+	t_scan_id_grp->scan_id = src_rssi->scan_cycle_id;
+	t_scan_id_grp->flags = src_rssi->flags;
+	t_scan_id_grp->buckets_scanned = src_rssi->buckets_scanned;
+	t_scan_id_grp->num_results = 1;
+	for (i = 1; i < param_buf->num_rssi_list; i++) {
+		src_rssi++;
+		if (prev_scan_id == src_rssi->scan_cycle_id) {
+			t_scan_id_grp->num_results++;
+		} else {
+			t_scan_id_grp++;
+			prev_scan_id = t_scan_id_grp->scan_id =
+				src_rssi->scan_cycle_id;
+			t_scan_id_grp->flags = src_rssi->flags;
+			t_scan_id_grp->buckets_scanned =
+				src_rssi->buckets_scanned;
+			t_scan_id_grp->num_results = 1;
+		}
+	}
+	return 0;
+}
+
+/** wma_group_num_bss_to_scan_id() - group bss to scan id table
+ * @cmd_param_info: event data.
+ * @cached_result: pointer to cached table.
+ *
+ * This function reads the bss information from the format
+ * ------------------------------------------------------------------------
+ * | bss info {rssi, channel, ssid, bssid, timestamp} | scan id_1 | flags |
+ * | bss info {rssi, channel, ssid, bssid, timestamp} | scan id_2 | flags |
+ * ........................................................................
+ * | bss info {rssi, channel, ssid, bssid, timestamp} | scan id_N | flags |
+ * ------------------------------------------------------------------------
+ *
+ * and converts it into the below format and store it
+ *
+ * ------------------------------------------------------------------------
+ * | scan id_1 | -> bss info_1 -> bss info_2 -> .... bss info_M1
+ * | scan id_2 | -> bss info_1 -> bss info_2 -> .... bss info_M2
+ * ......................
+ * | scan id_N | -> bss info_1 -> bss info_2 -> .... bss info_Mn
+ * ------------------------------------------------------------------------
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int wma_group_num_bss_to_scan_id(const u_int8_t *cmd_param_info,
+			struct extscan_cached_scan_results *cached_result)
+{
+	WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
+	wmi_extscan_cached_results_event_fixed_param  *event;
+	wmi_extscan_wlan_descriptor  *src_hotlist;
+	wmi_extscan_rssi_info  *src_rssi;
+	struct extscan_cached_scan_results *t_cached_result;
+	struct extscan_cached_scan_result *t_scan_id_grp;
+	int i, j;
+	tSirWifiScanResult *ap;
+
+	param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
+						cmd_param_info;
+	event = param_buf->fixed_param;
+	src_hotlist = param_buf->bssid_list;
+	src_rssi = param_buf->rssi_list;
+	t_cached_result = cached_result;
+	t_scan_id_grp = &t_cached_result->result[0];
+
+	WMA_LOGD("%s: num_scan_ids:%d", __func__,
+			t_cached_result->num_scan_ids);
+	for (i = 0; i < t_cached_result->num_scan_ids; i++) {
+		WMA_LOGD("%s: num_results:%d", __func__,
+			t_scan_id_grp->num_results);
+		t_scan_id_grp->ap = qdf_mem_malloc(t_scan_id_grp->num_results *
+						sizeof(*ap));
+		if (!t_scan_id_grp->ap)
+			return -ENOMEM;
+
+		ap = &t_scan_id_grp->ap[0];
+		for (j = 0; j < QDF_MIN(t_scan_id_grp->num_results,
+					param_buf->num_bssid_list); j++) {
+			ap->channel = src_hotlist->channel;
+			ap->ts = WMA_MSEC_TO_USEC(src_rssi->tstamp);
+			ap->rtt = src_hotlist->rtt;
+			ap->rtt_sd = src_hotlist->rtt_sd;
+			ap->beaconPeriod = src_hotlist->beacon_interval;
+			ap->capability = src_hotlist->capabilities;
+			ap->ieLength = src_hotlist->ie_length;
+
+			/* Firmware already applied noise floor adjustment and
+			 * due to WMI interface "UINT32 rssi", host driver
+			 * receives a positive value, hence convert to
+			 * signed char to get the absolute rssi.
+			 */
+			ap->rssi = (signed char) src_rssi->rssi;
+			WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_hotlist->bssid,
+						   ap->bssid.bytes);
+
+			if (src_hotlist->ssid.ssid_len >
+			    SIR_MAC_MAX_SSID_LENGTH) {
+				WMA_LOGD("%s Invalid SSID len %d, truncating",
+					 __func__, src_hotlist->ssid.ssid_len);
+				src_hotlist->ssid.ssid_len =
+						SIR_MAC_MAX_SSID_LENGTH;
+			}
+			qdf_mem_copy(ap->ssid, src_hotlist->ssid.ssid,
+					src_hotlist->ssid.ssid_len);
+			ap->ssid[src_hotlist->ssid.ssid_len] = '\0';
+			ap++;
+			src_rssi++;
+			src_hotlist++;
+		}
+		t_scan_id_grp++;
+	}
+	return 0;
+}
+
+/**
+ * wma_extscan_cached_results_event_handler() - cached results event handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: length of @cmd_param_info
+ *
+ * This function handles cached results event and indicate
+ * cached results to upper layer.
+ *
+ * Return: 0 for success or error code.
+ */
+int wma_extscan_cached_results_event_handler(void *handle,
+					     uint8_t *cmd_param_info,
+					     uint32_t len)
+{
+	WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
+	wmi_extscan_cached_results_event_fixed_param *event;
+	struct extscan_cached_scan_results *dest_cachelist;
+	struct extscan_cached_scan_result *dest_result;
+	struct extscan_cached_scan_results empty_cachelist;
+	wmi_extscan_wlan_descriptor *src_hotlist;
+	wmi_extscan_rssi_info *src_rssi;
+	int i, moredata, scan_ids_cnt, buf_len, status;
+	tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
+	uint32_t total_len;
+	bool excess_data = false;
+
+	if (!pMac) {
+		WMA_LOGE("%s: Invalid pMac", __func__);
+		return -EINVAL;
+	}
+	if (!pMac->sme.ext_scan_ind_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+	param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
+		    cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid cached results event", __func__);
+		return -EINVAL;
+	}
+	event = param_buf->fixed_param;
+	src_hotlist = param_buf->bssid_list;
+	src_rssi = param_buf->rssi_list;
+	WMA_LOGI("Total_entries: %u first_entry_index: %u num_entries_in_page: %d",
+			event->total_entries,
+			event->first_entry_index,
+			event->num_entries_in_page);
+
+	if (!src_hotlist || !src_rssi || !event->num_entries_in_page) {
+		WMA_LOGW("%s: Cached results empty, send 0 results", __func__);
+		goto noresults;
+	}
+
+	if (event->num_entries_in_page >
+	    (WMI_SVC_MSG_MAX_SIZE - sizeof(*event))/sizeof(*src_hotlist) ||
+	    event->num_entries_in_page > param_buf->num_bssid_list) {
+		WMA_LOGE("%s:excess num_entries_in_page %d in WMI event. num_bssid_list %d",
+			 __func__,
+			 event->num_entries_in_page, param_buf->num_bssid_list);
+		return -EINVAL;
+	} else {
+		total_len = sizeof(*event) +
+			(event->num_entries_in_page * sizeof(*src_hotlist));
+	}
+	for (i = 0; i < event->num_entries_in_page; i++) {
+		if (src_hotlist[i].ie_length >
+		    WMI_SVC_MSG_MAX_SIZE - total_len) {
+			excess_data = true;
+			break;
+		} else {
+			total_len += src_hotlist[i].ie_length;
+			WMA_LOGD("total len IE: %d", total_len);
+		}
+
+		if (src_hotlist[i].number_rssi_samples >
+		    (WMI_SVC_MSG_MAX_SIZE - total_len) / sizeof(*src_rssi)) {
+			excess_data = true;
+			break;
+		} else {
+			total_len += (src_hotlist[i].number_rssi_samples *
+					sizeof(*src_rssi));
+			WMA_LOGD("total len RSSI samples: %d", total_len);
+		}
+	}
+	if (excess_data) {
+		WMA_LOGE("%s:excess data in WMI event",
+			 __func__);
+		return -EINVAL;
+	}
+
+	if (event->first_entry_index +
+	    event->num_entries_in_page < event->total_entries)
+		moredata = 1;
+	else
+		moredata = 0;
+
+	dest_cachelist = qdf_mem_malloc(sizeof(*dest_cachelist));
+	if (!dest_cachelist)
+		return -ENOMEM;
+
+	qdf_mem_zero(dest_cachelist, sizeof(*dest_cachelist));
+	dest_cachelist->request_id = event->request_id;
+	dest_cachelist->more_data = moredata;
+
+	scan_ids_cnt = wma_extscan_find_unique_scan_ids(cmd_param_info);
+	WMA_LOGD("%s: scan_ids_cnt %d", __func__, scan_ids_cnt);
+	dest_cachelist->num_scan_ids = scan_ids_cnt;
+
+	buf_len = sizeof(*dest_result) * scan_ids_cnt;
+	dest_cachelist->result = qdf_mem_malloc(buf_len);
+	if (!dest_cachelist->result) {
+		qdf_mem_free(dest_cachelist);
+		return -ENOMEM;
+	}
+
+	dest_result = dest_cachelist->result;
+	wma_fill_num_results_per_scan_id(cmd_param_info, dest_result);
+
+	status = wma_group_num_bss_to_scan_id(cmd_param_info, dest_cachelist);
+	if (!status)
+	pMac->sme.ext_scan_ind_cb(pMac->hdd_handle,
+				eSIR_EXTSCAN_CACHED_RESULTS_IND,
+				dest_cachelist);
+	else
+		WMA_LOGD("wma_group_num_bss_to_scan_id failed, not calling callback");
+
+	dest_result = dest_cachelist->result;
+	for (i = 0; i < dest_cachelist->num_scan_ids; i++) {
+		if (dest_result->ap)
+		qdf_mem_free(dest_result->ap);
+		dest_result++;
+	}
+	qdf_mem_free(dest_cachelist->result);
+	qdf_mem_free(dest_cachelist);
+	return status;
+
+noresults:
+	empty_cachelist.request_id = event->request_id;
+	empty_cachelist.more_data = 0;
+	empty_cachelist.num_scan_ids = 0;
+
+	pMac->sme.ext_scan_ind_cb(pMac->hdd_handle,
+				eSIR_EXTSCAN_CACHED_RESULTS_IND,
+				&empty_cachelist);
+	return 0;
+}
+
+/**
+ * wma_extscan_change_results_event_handler() - change results event handler
+ * @handle: wma handle
+ * @cmd_param_info: event buffer
+ * @len: length
+ *
+ * This function handles change results event and indicate
+ * change results to upper layer.
+ *
+ * Return: 0 for success or error code.
+ */
+int wma_extscan_change_results_event_handler(void *handle,
+					     uint8_t *cmd_param_info,
+					     uint32_t len)
+{
+	WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID_param_tlvs *param_buf;
+	wmi_extscan_wlan_change_results_event_fixed_param *event;
+	tSirWifiSignificantChangeEvent *dest_chglist;
+	tSirWifiSignificantChange *dest_ap;
+	wmi_extscan_wlan_change_result_bssid *src_chglist;
+
+	uint32_t numap;
+	int i, k;
+	uint8_t *src_rssi;
+	int count = 0;
+	int moredata;
+	uint32_t rssi_num = 0;
+	tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
+	uint32_t buf_len;
+	bool excess_data = false;
+
+	if (!pMac) {
+		WMA_LOGE("%s: Invalid pMac", __func__);
+		return -EINVAL;
+	}
+	if (!pMac->sme.ext_scan_ind_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+	param_buf = (WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID_param_tlvs *)
+		    cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid change monitor event", __func__);
+		return -EINVAL;
+	}
+	event = param_buf->fixed_param;
+	src_chglist = param_buf->bssid_signal_descriptor_list;
+	src_rssi = param_buf->rssi_list;
+	numap = event->num_entries_in_page;
+
+	if (!src_chglist || !numap) {
+		WMA_LOGE("%s: Results invalid", __func__);
+		return -EINVAL;
+	}
+	if (numap > param_buf->num_bssid_signal_descriptor_list) {
+		WMA_LOGE("%s: Invalid num of entries in page: %d", __func__, numap);
+		return -EINVAL;
+	}
+	for (i = 0; i < numap; i++) {
+		if (src_chglist->num_rssi_samples > (UINT_MAX - rssi_num)) {
+			WMA_LOGE("%s: Invalid num of rssi samples %d numap %d rssi_num %d",
+				 __func__, src_chglist->num_rssi_samples,
+				 numap, rssi_num);
+			return -EINVAL;
+		}
+		rssi_num += src_chglist->num_rssi_samples;
+		src_chglist++;
+	}
+	src_chglist = param_buf->bssid_signal_descriptor_list;
+
+	if (event->first_entry_index +
+	    event->num_entries_in_page < event->total_entries) {
+		moredata = 1;
+	} else {
+		moredata = 0;
+	}
+
+	do {
+		if (event->num_entries_in_page >
+			(WMI_SVC_MSG_MAX_SIZE - sizeof(*event))/
+			sizeof(*src_chglist)) {
+			excess_data = true;
+			break;
+		} else {
+			buf_len =
+				sizeof(*event) + (event->num_entries_in_page *
+						sizeof(*src_chglist));
+		}
+		if (rssi_num >
+			(WMI_SVC_MSG_MAX_SIZE - buf_len)/sizeof(int32_t)) {
+			excess_data = true;
+			break;
+		}
+	} while (0);
+
+	if (excess_data) {
+		WMA_LOGE("buffer len exceeds WMI payload,numap:%d, rssi_num:%d",
+				numap, rssi_num);
+		QDF_ASSERT(0);
+		return -EINVAL;
+	}
+	dest_chglist = qdf_mem_malloc(sizeof(*dest_chglist) +
+				      sizeof(*dest_ap) * numap +
+				      sizeof(int32_t) * rssi_num);
+	if (!dest_chglist)
+		return -ENOMEM;
+
+	dest_ap = &dest_chglist->ap[0];
+	for (i = 0; i < numap; i++) {
+		dest_ap->channel = src_chglist->channel;
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_chglist->bssid,
+					   dest_ap->bssid.bytes);
+		dest_ap->numOfRssi = src_chglist->num_rssi_samples;
+		if (dest_ap->numOfRssi) {
+			if ((dest_ap->numOfRssi + count) >
+			    param_buf->num_rssi_list) {
+				WMA_LOGE("%s: Invalid num in rssi list: %d",
+					__func__, dest_ap->numOfRssi);
+				qdf_mem_free(dest_chglist);
+				return -EINVAL;
+			}
+			for (k = 0; k < dest_ap->numOfRssi; k++) {
+				dest_ap->rssi[k] = WMA_TGT_NOISE_FLOOR_DBM +
+						   src_rssi[count++];
+			}
+		}
+		dest_ap = (tSirWifiSignificantChange *)((char *)dest_ap +
+					dest_ap->numOfRssi * sizeof(int32_t) +
+					sizeof(*dest_ap));
+		src_chglist++;
+	}
+	dest_chglist->requestId = event->request_id;
+	dest_chglist->moreData = moredata;
+	dest_chglist->numResults = numap;
+
+	pMac->sme.ext_scan_ind_cb(pMac->hdd_handle,
+			eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND,
+			dest_chglist);
+	WMA_LOGI("%s: sending change monitor results", __func__);
+	qdf_mem_free(dest_chglist);
+	return 0;
+}
+
+/**
+ * wma_passpoint_match_event_handler() - passpoint match found event handler
+ * @handle: WMA handle
+ * @cmd_param_info: event data
+ * @len: event data length
+ *
+ * This is the passpoint match found event handler; it reads event data from
+ * @cmd_param_info and fill in the destination buffer and sends indication
+ * up layer.
+ *
+ * Return: 0 on success; error number otherwise
+ */
+int wma_passpoint_match_event_handler(void *handle,
+				     uint8_t  *cmd_param_info,
+				     uint32_t len)
+{
+	WMI_PASSPOINT_MATCH_EVENTID_param_tlvs *param_buf;
+	wmi_passpoint_event_hdr  *event;
+	struct wifi_passpoint_match  *dest_match;
+	tSirWifiScanResult      *dest_ap;
+	uint8_t *buf_ptr;
+	uint32_t buf_len = 0;
+	bool excess_data = false;
+	tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac) {
+		WMA_LOGE("%s: Invalid mac", __func__);
+		return -EINVAL;
+	}
+	if (!mac->sme.ext_scan_ind_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+
+	param_buf = (WMI_PASSPOINT_MATCH_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid passpoint match event", __func__);
+		return -EINVAL;
+	}
+	event = param_buf->fixed_param;
+	buf_ptr = (uint8_t *)param_buf->fixed_param;
+
+	do {
+		if (event->ie_length > (WMI_SVC_MSG_MAX_SIZE)) {
+			excess_data = true;
+			break;
+		} else {
+			buf_len = event->ie_length;
+		}
+
+		if (event->anqp_length > (WMI_SVC_MSG_MAX_SIZE)) {
+			excess_data = true;
+			break;
+		} else {
+			buf_len += event->anqp_length;
+		}
+
+	} while (0);
+
+	if (excess_data || buf_len > (WMI_SVC_MSG_MAX_SIZE - sizeof(*event)) ||
+	    buf_len > (WMI_SVC_MSG_MAX_SIZE - sizeof(*dest_match)) ||
+	    (event->ie_length + event->anqp_length) > param_buf->num_bufp) {
+		WMA_LOGE("IE Length: %u or ANQP Length: %u is huge, num_bufp: %u",
+			event->ie_length, event->anqp_length,
+			param_buf->num_bufp);
+		return -EINVAL;
+	}
+
+	if (event->ssid.ssid_len > SIR_MAC_MAX_SSID_LENGTH) {
+		WMA_LOGD("%s: Invalid ssid len %d, truncating",
+			 __func__, event->ssid.ssid_len);
+		event->ssid.ssid_len = SIR_MAC_MAX_SSID_LENGTH;
+	}
+
+	dest_match = qdf_mem_malloc(sizeof(*dest_match) + buf_len);
+
+	if (!dest_match)
+		return -EINVAL;
+
+	dest_ap = &dest_match->ap;
+	dest_match->request_id = 0;
+	dest_match->id = event->id;
+	dest_match->anqp_len = event->anqp_length;
+	WMA_LOGI("%s: passpoint match: id: %u anqp length %u", __func__,
+		 dest_match->id, dest_match->anqp_len);
+
+	dest_ap->channel = event->channel_mhz;
+	dest_ap->ts = event->timestamp;
+	dest_ap->rtt = event->rtt;
+	dest_ap->rssi = event->rssi;
+	dest_ap->rtt_sd = event->rtt_sd;
+	dest_ap->beaconPeriod = event->beacon_period;
+	dest_ap->capability = event->capability;
+	dest_ap->ieLength = event->ie_length;
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->bssid, dest_ap->bssid.bytes);
+	qdf_mem_copy(dest_ap->ssid, event->ssid.ssid,
+				event->ssid.ssid_len);
+	dest_ap->ssid[event->ssid.ssid_len] = '\0';
+	qdf_mem_copy(dest_ap->ieData, buf_ptr + sizeof(*event) +
+			WMI_TLV_HDR_SIZE, dest_ap->ieLength);
+	qdf_mem_copy(dest_match->anqp, buf_ptr + sizeof(*event) +
+			WMI_TLV_HDR_SIZE + dest_ap->ieLength,
+			dest_match->anqp_len);
+
+	mac->sme.ext_scan_ind_cb(mac->hdd_handle,
+				eSIR_PASSPOINT_NETWORK_FOUND_IND,
+				dest_match);
+	WMA_LOGI("%s: sending passpoint match event to hdd", __func__);
+	qdf_mem_free(dest_match);
+	return 0;
+}
+
+QDF_STATUS wma_start_extscan(tp_wma_handle wma,
+			     struct wifi_scan_cmd_req_params *params)
+{
+	QDF_STATUS status;
+
+	if (!wma || !wma->wmi_handle) {
+		wma_err("WMA is closed, can not issue cmd");
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!wmi_service_enabled(wma->wmi_handle, wmi_service_extscan)) {
+		wma_err("extscan not enabled");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!params)
+		wma_err("NULL param");
+		return QDF_STATUS_E_NOMEM;
+
+	status = wmi_unified_start_extscan_cmd(wma->wmi_handle, params);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		wma->interfaces[params->vdev_id].extscan_in_progress = true;
+
+	wma_debug("Exit, vdev %d, status %d", params->vdev_id, status);
+
+	return status;
+}
+
+QDF_STATUS wma_stop_extscan(tp_wma_handle wma,
+			    struct extscan_stop_req_params *params)
+{
+	QDF_STATUS status;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, cannot issue cmd", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!wmi_service_enabled(wma->wmi_handle, wmi_service_extscan)) {
+		WMA_LOGE("%s: extscan not enabled", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = wmi_unified_stop_extscan_cmd(wma->wmi_handle, params);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	wma->interfaces[params->vdev_id].extscan_in_progress = false;
+	WMA_LOGD("Extscan stop request sent successfully for vdev %d",
+		 params->vdev_id);
+
+	return status;
+}
+
+/** wma_get_hotlist_entries_per_page() - hotlist entries per page
+ * @wmi_handle: wmi handle.
+ * @cmd: size of command structure.
+ * @per_entry_size: per entry size.
+ *
+ * This utility function calculates how many hotlist entries can
+ * fit in one page.
+ *
+ * Return: number of entries
+ */
+static inline int wma_get_hotlist_entries_per_page(wmi_unified_t wmi_handle,
+						   size_t cmd_size,
+						   size_t per_entry_size)
+{
+	uint32_t avail_space = 0;
+	int num_entries = 0;
+	uint16_t max_msg_len = wmi_get_max_msg_len(wmi_handle);
+
+	/* Calculate number of hotlist entries that can
+	 * be passed in wma message request.
+	 */
+	avail_space = max_msg_len - cmd_size;
+	num_entries = avail_space / per_entry_size;
+	return num_entries;
+}
+
+QDF_STATUS wma_extscan_start_hotlist_monitor(tp_wma_handle wma,
+			struct extscan_bssid_hotlist_set_params *params)
+{
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue hotlist cmd",
+			 __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!params) {
+		WMA_LOGE("%s: Invalid params", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return wmi_unified_extscan_start_hotlist_monitor_cmd(wma->wmi_handle,
+							     params);
+}
+
+QDF_STATUS wma_extscan_stop_hotlist_monitor(tp_wma_handle wma,
+		    struct extscan_bssid_hotlist_reset_params *params)
+{
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!params) {
+		WMA_LOGE("%s: Invalid params", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!wmi_service_enabled(wma->wmi_handle,
+				 wmi_service_extscan)) {
+		WMA_LOGE("%s: extscan not enabled", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wmi_unified_extscan_stop_hotlist_monitor_cmd(wma->wmi_handle,
+							    params);
+}
+
+QDF_STATUS
+wma_extscan_start_change_monitor(tp_wma_handle wma,
+			struct extscan_set_sig_changereq_params *params)
+{
+	QDF_STATUS status;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed,can not issue cmd",
+			 __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!params) {
+		WMA_LOGE("%s: NULL params", __func__);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	status = wmi_unified_extscan_start_change_monitor_cmd(wma->wmi_handle,
+							      params);
+	return status;
+}
+
+QDF_STATUS wma_extscan_stop_change_monitor(tp_wma_handle wma,
+			struct extscan_capabilities_reset_params *params)
+{
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue  cmd", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!wmi_service_enabled(wma->wmi_handle,
+				    wmi_service_extscan)) {
+		WMA_LOGE("%s: ext scan not enabled", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wmi_unified_extscan_stop_change_monitor_cmd(wma->wmi_handle,
+							   params);
+}
+
+QDF_STATUS
+wma_extscan_get_cached_results(tp_wma_handle wma,
+			       struct extscan_cached_result_params *params)
+{
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, cannot issue cmd", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!wmi_service_enabled(wma->wmi_handle, wmi_service_extscan)) {
+		WMA_LOGE("%s: extscan not enabled", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wmi_unified_extscan_get_cached_results_cmd(wma->wmi_handle,
+							  params);
+}
+
+QDF_STATUS
+wma_extscan_get_capabilities(tp_wma_handle wma,
+			     struct extscan_capabilities_params *params)
+{
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!wmi_service_enabled(wma->wmi_handle, wmi_service_extscan)) {
+		WMA_LOGE("%s: extscan not enabled", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wmi_unified_extscan_get_capabilities_cmd(wma->wmi_handle,
+							params);
+}
+
+QDF_STATUS wma_set_epno_network_list(tp_wma_handle wma,
+				     struct wifi_enhanced_pno_params *req)
+{
+	QDF_STATUS status;
+
+	wma_debug("Enter");
+
+	if (!wma || !wma->wmi_handle) {
+		wma_err("WMA is closed, can not issue cmd");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!wmi_service_enabled(wma->wmi_handle, wmi_service_extscan)) {
+		wma_err("extscan not enabled");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	status = wmi_unified_set_epno_network_list_cmd(wma->wmi_handle, req);
+	wma_debug("Exit, vdev %d, status %d", req->vdev_id, status);
+
+	return status;
+}
+
+QDF_STATUS
+wma_set_passpoint_network_list(tp_wma_handle wma,
+			       struct wifi_passpoint_req_param *params)
+{
+	QDF_STATUS status;
+
+	wma_debug("Enter");
+
+	if (!wma || !wma->wmi_handle) {
+		wma_err("WMA is closed, can not issue cmd");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (!wmi_service_enabled(wma->wmi_handle, wmi_service_extscan)) {
+		wma_err("extscan not enabled");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	status = wmi_unified_set_passpoint_network_list_cmd(wma->wmi_handle,
+							    params);
+	wma_debug("Exit, vdev %d, status %d", params->vdev_id, status);
+
+	return status;
+}
+
+QDF_STATUS
+wma_reset_passpoint_network_list(tp_wma_handle wma,
+				 struct wifi_passpoint_req_param *params)
+{
+	QDF_STATUS status;
+
+	wma_debug("Enter");
+
+	if (!wma || !wma->wmi_handle) {
+		wma_err("WMA is closed, can not issue cmd");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (!wmi_service_enabled(wma->wmi_handle, wmi_service_extscan)) {
+		wma_err("extscan not enabled");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	status = wmi_unified_reset_passpoint_network_list_cmd(wma->wmi_handle,
+							      params);
+	wma_debug("Exit, vdev %d, status %d", params->vdev_id, status);
+
+	return status;
+}
+
+#endif
+
+/**
+ * wma_scan_probe_setoui() - set scan probe OUI
+ * @wma: wma handle
+ * @psetoui: OUI parameters
+ *
+ * set scan probe OUI parameters in firmware
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_scan_probe_setoui(tp_wma_handle wma, tSirScanMacOui *psetoui)
+{
+	struct scan_mac_oui set_oui;
+
+	qdf_mem_set(&set_oui, sizeof(struct scan_mac_oui), 0);
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("%s: WMA is closed, can not issue  cmd", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_mem_copy(set_oui.oui, psetoui->oui,
+				WMI_WIFI_SCANNING_MAC_OUI_LENGTH);
+
+	set_oui.vdev_id = psetoui->vdev_id;
+	set_oui.enb_probe_req_sno_randomization =
+				psetoui->enb_probe_req_sno_randomization;
+	set_oui.ie_whitelist = psetoui->ie_whitelist;
+
+	return wmi_unified_scan_probe_setoui_cmd(wma->wmi_handle,
+						&set_oui);
+}
+/**
+ * wma_roam_better_ap_handler() - better ap event handler
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Handler for WMI_ROAM_REASON_BETTER_AP event from roam firmware in Rome.
+ * This event means roam algorithm in Rome has found a better matching
+ * candidate AP. The indication is sent to SME.
+ *
+ * Return: none
+ */
+void wma_roam_better_ap_handler(tp_wma_handle wma, uint32_t vdev_id)
+{
+	struct scheduler_msg cds_msg = {0};
+	tSirSmeCandidateFoundInd *candidate_ind;
+
+	candidate_ind = qdf_mem_malloc(sizeof(tSirSmeCandidateFoundInd));
+	if (!candidate_ind)
+		return;
+
+	wma->interfaces[vdev_id].roaming_in_progress = true;
+	candidate_ind->messageType = eWNI_SME_CANDIDATE_FOUND_IND;
+	candidate_ind->sessionId = vdev_id;
+	candidate_ind->length = sizeof(tSirSmeCandidateFoundInd);
+
+	cds_msg.type = eWNI_SME_CANDIDATE_FOUND_IND;
+	cds_msg.bodyptr = candidate_ind;
+	cds_msg.callback = sme_mc_process_handler;
+	QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_INFO,
+		  FL("posting candidate ind to SME, vdev %d"), vdev_id);
+
+	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_WMA,
+							 QDF_MODULE_ID_SME,
+							 QDF_MODULE_ID_SCAN,
+							 &cds_msg)) {
+		qdf_mem_free(candidate_ind);
+		QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
+			  FL("Failed to post candidate ind to SME"));
+	}
+}
+
+/**
+ * wma_handle_btm_disassoc_imminent_msg() - Send del sta msg to lim on receiving
+ * BTM request from AP with disassoc imminent reason
+ * @wma_handle: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+static void wma_handle_btm_disassoc_imminent_msg(tp_wma_handle wma_handle,
+						 uint32_t vdev_id)
+{
+	tpDeleteStaContext del_sta_ctx;
+
+	del_sta_ctx = qdf_mem_malloc(sizeof(tDeleteStaContext));
+	if (!del_sta_ctx)
+		return;
+
+	del_sta_ctx->vdev_id = vdev_id;
+	del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_BTM_DISASSOC_IMMINENT;
+	wma_send_msg(wma_handle, SIR_LIM_DELETE_STA_CONTEXT_IND,
+		     (void *)del_sta_ctx, 0);
+}
+
+/**
+ * wma_roam_event_callback() - roam event callback
+ * @handle: wma handle
+ * @event_buf: event buffer
+ * @len: buffer length
+ *
+ * Handler for all events from roam engine in firmware
+ *
+ * Return: 0 for success or error code
+ */
+int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf,
+				   uint32_t len)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	WMI_ROAM_EVENTID_param_tlvs *param_buf;
+	wmi_roam_event_fixed_param *wmi_event;
+	struct sSirSmeRoamOffloadSynchInd *roam_synch_data;
+	enum sir_roam_op_code op_code = {0};
+
+	param_buf = (WMI_ROAM_EVENTID_param_tlvs *) event_buf;
+	if (!param_buf) {
+		WMA_LOGE("Invalid roam event buffer");
+		return -EINVAL;
+	}
+
+	wmi_event = param_buf->fixed_param;
+	WMA_LOGD("%s: Reason %x, Notif %x for vdevid %x, rssi %d",
+		 __func__, wmi_event->reason, wmi_event->notif,
+		 wmi_event->vdev_id, wmi_event->rssi);
+
+	if (wmi_event->vdev_id >= wma_handle->max_bssid) {
+		WMA_LOGE("Invalid vdev id from firmware");
+		return -EINVAL;
+	}
+	wlan_roam_debug_log(wmi_event->vdev_id, DEBUG_ROAM_EVENT,
+			    DEBUG_INVALID_PEER_ID, NULL, NULL,
+			    wmi_event->reason,
+			    (wmi_event->reason == WMI_ROAM_REASON_INVALID) ?
+				wmi_event->notif : wmi_event->rssi);
+
+	DPTRACE(qdf_dp_trace_record_event(QDF_DP_TRACE_EVENT_RECORD,
+		wmi_event->vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
+		QDF_PROTO_TYPE_EVENT, QDF_ROAM_EVENTID));
+
+	switch (wmi_event->reason) {
+	case WMI_ROAM_REASON_BTM:
+		/*
+		 * This event is received from firmware if firmware is unable to
+		 * find candidate AP after roam scan and BTM request from AP
+		 * has disassoc imminent bit set.
+		 */
+		WMA_LOGD("Kickout due to btm request");
+		wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_BTM,
+				      wmi_event->vdev_id, NULL);
+		wma_handle_btm_disassoc_imminent_msg(wma_handle,
+						   wmi_event->vdev_id);
+		break;
+	case WMI_ROAM_REASON_BMISS:
+		WMA_LOGD("Beacon Miss for vdevid %x", wmi_event->vdev_id);
+		wma_beacon_miss_handler(wma_handle, wmi_event->vdev_id,
+					wmi_event->rssi);
+		wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_BMISS,
+						wmi_event->vdev_id, NULL);
+		break;
+	case WMI_ROAM_REASON_BETTER_AP:
+		WMA_LOGD("%s:Better AP found for vdevid %x, rssi %d", __func__,
+			 wmi_event->vdev_id, wmi_event->rssi);
+		wma_handle->suitable_ap_hb_failure = false;
+		wma_roam_better_ap_handler(wma_handle, wmi_event->vdev_id);
+		break;
+	case WMI_ROAM_REASON_SUITABLE_AP:
+		wma_handle->suitable_ap_hb_failure = true;
+		wma_handle->suitable_ap_hb_failure_rssi = wmi_event->rssi;
+		WMA_LOGD("%s:Bmiss scan AP found for vdevid %x, rssi %d",
+			 __func__, wmi_event->vdev_id, wmi_event->rssi);
+		wma_roam_better_ap_handler(wma_handle, wmi_event->vdev_id);
+		break;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	case WMI_ROAM_REASON_HO_FAILED:
+		WMA_LOGE("LFR3:Hand-Off Failed for vdevid %x",
+			 wmi_event->vdev_id);
+		wma_roam_ho_fail_handler(wma_handle, wmi_event->vdev_id);
+		wma_handle->interfaces[wmi_event->vdev_id].
+			roaming_in_progress = false;
+		break;
+#endif
+	case WMI_ROAM_REASON_INVALID:
+		roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data));
+		if (!roam_synch_data)
+			return -ENOMEM;
+
+		if (wmi_event->notif == WMI_ROAM_NOTIF_ROAM_START) {
+			op_code = SIR_ROAMING_START;
+			wma_handle->interfaces[wmi_event->vdev_id].
+				roaming_in_progress = true;
+		}
+		if (wmi_event->notif == WMI_ROAM_NOTIF_ROAM_ABORT) {
+			op_code = SIR_ROAMING_ABORT;
+			wma_handle->interfaces[wmi_event->vdev_id].
+				roaming_in_progress = false;
+		}
+		roam_synch_data->roamedVdevId = wmi_event->vdev_id;
+		wma_handle->pe_roam_synch_cb(
+				(tpAniSirGlobal)wma_handle->mac_context,
+				roam_synch_data, NULL, op_code);
+		wma_handle->csr_roam_synch_cb(
+				(tpAniSirGlobal)wma_handle->mac_context,
+				roam_synch_data, NULL, op_code);
+		qdf_mem_free(roam_synch_data);
+		break;
+	case WMI_ROAM_REASON_RSO_STATUS:
+		wma_rso_cmd_status_event_handler(wmi_event);
+		break;
+	case WMI_ROAM_REASON_INVOKE_ROAM_FAIL:
+		roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data));
+		if (!roam_synch_data)
+			return -ENOMEM;
+
+		roam_synch_data->roamedVdevId = wmi_event->vdev_id;
+		wma_handle->csr_roam_synch_cb(
+				(tpAniSirGlobal)wma_handle->mac_context,
+				roam_synch_data, NULL, SIR_ROAMING_INVOKE_FAIL);
+		qdf_mem_free(roam_synch_data);
+		break;
+	default:
+		WMA_LOGD("%s:Unhandled Roam Event %x for vdevid %x", __func__,
+			 wmi_event->reason, wmi_event->vdev_id);
+		break;
+	}
+	return 0;
+}
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+/**
+ * wma_set_gateway_params() - set gateway parameters
+ * @wma: WMA handle
+ * @req: gateway parameter update request structure
+ *
+ * This function reads the incoming @req and fill in the destination
+ * WMI structure and sends down the gateway configs down to the firmware
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_set_gateway_params(tp_wma_handle wma,
+					struct gateway_param_update_req *req)
+{
+	struct gateway_update_req_param params = {0};
+
+	if (!wma) {
+		WMA_LOGE("%s: wma handle is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	params.request_id = req->request_id;
+	params.session_id = req->session_id;
+	params.max_retries = req->max_retries;
+	params.timeout = req->timeout;
+	params.ipv4_addr_type = req->ipv4_addr_type;
+	params.ipv6_addr_type = req->ipv6_addr_type;
+	qdf_mem_copy(&params.gw_mac_addr, &req->gw_mac_addr,
+			sizeof(struct qdf_mac_addr));
+	qdf_mem_copy(params.ipv4_addr, req->ipv4_addr,
+				QDF_IPV4_ADDR_SIZE);
+	qdf_mem_copy(params.ipv6_addr, req->ipv6_addr,
+				QDF_IPV6_ADDR_SIZE);
+
+	return wmi_unified_set_gateway_params_cmd(wma->wmi_handle,
+							&params);
+}
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+
+/**
+ * wma_ht40_stop_obss_scan() - ht40 obss stop scan
+ * @wma: WMA handel
+ * @vdev_id: vdev identifier
+ *
+ * Return: Return QDF_STATUS, otherwise appropriate failure code
+ */
+QDF_STATUS wma_ht40_stop_obss_scan(tp_wma_handle wma, int32_t vdev_id)
+{
+
+	wmi_buf_t buf;
+	wmi_obss_scan_disable_cmd_fixed_param *cmd;
+	int ret;
+	int len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	WMA_LOGD("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id);
+
+	cmd = (wmi_obss_scan_disable_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_obss_scan_disable_cmd_fixed_param));
+
+	cmd->vdev_id = vdev_id;
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				WMI_OBSS_SCAN_DISABLE_CMDID);
+	if (ret != EOK) {
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_send_ht40_obss_scanind() - ht40 obss start scan indication
+ * @wma: WMA handel
+ * @req: start scan request
+ *
+ * Return: Return QDF_STATUS, otherwise appropriate failure code
+ */
+QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma,
+				struct obss_ht40_scanind *req)
+{
+	wmi_buf_t buf;
+	wmi_obss_scan_enable_cmd_fixed_param *cmd;
+	int ret;
+	int len = 0;
+	uint8_t *buf_ptr, i;
+	uint8_t *channel_list;
+
+	len += sizeof(wmi_obss_scan_enable_cmd_fixed_param);
+
+	len += WMI_TLV_HDR_SIZE;
+	len += qdf_roundup(sizeof(uint8_t) * req->channel_count,
+				sizeof(uint32_t));
+
+	len += WMI_TLV_HDR_SIZE;
+	len += qdf_roundup(sizeof(uint8_t) * 1, sizeof(uint32_t));
+
+	WMA_LOGE("cmdlen %d vdev_id %d channel count %d iefield_len %d",
+			len, req->bss_id, req->channel_count, req->iefield_len);
+
+	WMA_LOGE("scantype %d active_time %d passive %d Obss interval %d",
+			req->scan_type, req->obss_active_dwelltime,
+			req->obss_passive_dwelltime,
+			req->obss_width_trigger_interval);
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_obss_scan_enable_cmd_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_obss_scan_enable_cmd_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(wmi_obss_scan_enable_cmd_fixed_param));
+
+	buf_ptr = (uint8_t *) cmd;
+
+	cmd->vdev_id = req->bss_id;
+	cmd->scan_type = req->scan_type;
+	cmd->obss_scan_active_dwell =
+		req->obss_active_dwelltime;
+	cmd->obss_scan_passive_dwell =
+		req->obss_passive_dwelltime;
+	cmd->bss_channel_width_trigger_scan_interval =
+		req->obss_width_trigger_interval;
+	cmd->bss_width_channel_transition_delay_factor =
+		req->bsswidth_ch_trans_delay;
+	cmd->obss_scan_active_total_per_channel =
+		req->obss_active_total_per_channel;
+	cmd->obss_scan_passive_total_per_channel =
+		req->obss_passive_total_per_channel;
+	cmd->obss_scan_activity_threshold =
+		req->obss_activity_threshold;
+
+	cmd->channel_len = req->channel_count;
+	cmd->forty_mhz_intolerant =  req->fortymhz_intolerent;
+	cmd->current_operating_class = req->current_operatingclass;
+	cmd->ie_len = req->iefield_len;
+
+	buf_ptr += sizeof(wmi_obss_scan_enable_cmd_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+		qdf_roundup(req->channel_count, sizeof(uint32_t)));
+
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	channel_list = (uint8_t *) buf_ptr;
+
+	for (i = 0; i < req->channel_count; i++) {
+		channel_list[i] = req->channels[i];
+		WMA_LOGD("Ch[%d]: %d ", i, channel_list[i]);
+	}
+
+	buf_ptr += qdf_roundup(sizeof(uint8_t) * req->channel_count,
+				sizeof(uint32_t));
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
+			qdf_roundup(1, sizeof(uint32_t)));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				WMI_OBSS_SCAN_ENABLE_CMDID);
+	if (ret != EOK) {
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/core/wma/src/wma_twt.c b/core/wma/src/wma_twt.c
new file mode 100644
index 0000000..9ccf323
--- /dev/null
+++ b/core/wma/src/wma_twt.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2018 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: wma_twt.c
+ *
+ * WLAN Host Device Driver TWT - Target Wake Time Implementation
+ */
+
+#include "wma_twt.h"
+#include "wmi_unified_twt_api.h"
+#include "wma_internal.h"
+#include "wmi_unified_priv.h"
+
+void wma_send_twt_enable_cmd(uint32_t pdev_id, uint32_t congestion_timeout)
+{
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+	struct wmi_twt_enable_param twt_enable_params = {0};
+	int32_t ret;
+
+	if (!wma) {
+		WMA_LOGE("Invalid WMA context, enable TWT failed");
+		return;
+	}
+	twt_enable_params.pdev_id = pdev_id;
+	twt_enable_params.sta_cong_timer_ms = congestion_timeout;
+	ret = wmi_unified_twt_enable_cmd(wma->wmi_handle, &twt_enable_params);
+
+	if (ret)
+		WMA_LOGE("Failed to enable TWT");
+}
+
+int wma_twt_en_complete_event_handler(void *handle,
+				      uint8_t *event, uint32_t len)
+{
+	struct wmi_twt_enable_complete_event_param param;
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	wmi_unified_t wmi_handle;
+	tpAniSirGlobal mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
+	int status = -EINVAL;
+
+	if (!wma_handle) {
+		WMA_LOGE("Invalid wma handle for TWT complete");
+		return status;
+	}
+	wmi_handle = (wmi_unified_t)wma_handle->wmi_handle;
+	if (!wmi_handle) {
+		WMA_LOGE("Invalid wmi handle for TWT complete");
+		return status;
+	}
+	if (!mac) {
+		WMA_LOGE("Invalid MAC context");
+		return status;
+	}
+	if (wmi_handle->ops->extract_twt_enable_comp_event)
+		status = wmi_handle->ops->extract_twt_enable_comp_event(
+								wmi_handle,
+								event,
+								&param);
+	WMA_LOGD("TWT: Received TWT enable comp event, status:%d", status);
+
+	if (mac->sme.twt_enable_cb)
+		mac->sme.twt_enable_cb(mac->hdd_handle, &param);
+
+	return status;
+}
+
+void wma_set_twt_peer_caps(tpAddStaParams params, struct peer_assoc_params *cmd)
+{
+	if (params->twt_requestor)
+		cmd->peer_flags |= WMI_PEER_TWT_REQ;
+	if (params->twt_responder)
+		cmd->peer_flags |= WMI_PEER_TWT_RESP;
+}
+
diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c
new file mode 100644
index 0000000..4c0c64a
--- /dev/null
+++ b/core/wma/src/wma_utils.c
@@ -0,0 +1,4943 @@
+/*
+ * Copyright (c) 2013-2018 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:    wma_utis.c
+ *  This file contains utilities and stats related functions.
+ */
+
+/* Header files */
+
+#include "wma.h"
+#include "wma_api.h"
+#include "cds_api.h"
+#include "wmi_unified_api.h"
+#include "wlan_qct_sys.h"
+#include "wni_api.h"
+#include "ani_global.h"
+#include "wmi_unified.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+
+#include "qdf_nbuf.h"
+#include "qdf_types.h"
+#include "qdf_mem.h"
+
+#include "wma_types.h"
+#include "lim_api.h"
+#include "lim_session_utils.h"
+
+#include "cds_utils.h"
+
+#if !defined(REMOVE_PKT_LOG)
+#include "pktlog_ac.h"
+#endif /* REMOVE_PKT_LOG */
+
+#include "dbglog_host.h"
+#include "csr_api.h"
+#include "ol_fw.h"
+
+#include "wma_internal.h"
+#include "wlan_policy_mgr_api.h"
+#include "wmi_unified_param.h"
+#include "linux/ieee80211.h"
+#include <cdp_txrx_handle.h>
+#include <cdp_txrx_peer_ops.h>
+#include "cds_reg_service.h"
+#include "target_if.h"
+#include <wlan_utility.h>
+
+
+/* MCS Based rate table */
+/* HT MCS parameters with Nss = 1 */
+static struct index_data_rate_type mcs_nss1[] = {
+	/* MCS L20  S20   L40   S40 */
+	{0,  {65,  72},  {135,  150 } },
+	{1,  {130, 144}, {270,  300 } },
+	{2,  {195, 217}, {405,  450 } },
+	{3,  {260, 289}, {540,  600 } },
+	{4,  {390, 433}, {815,  900 } },
+	{5,  {520, 578}, {1080, 1200} },
+	{6,  {585, 650}, {1215, 1350} },
+	{7,  {650, 722}, {1350, 1500} }
+};
+
+/* HT MCS parameters with Nss = 2 */
+static struct index_data_rate_type mcs_nss2[] = {
+	/* MCS L20  S20    L40   S40 */
+	{0,  {130,  144},  {270,  300 } },
+	{1,  {260,  289},  {540,  600 } },
+	{2,  {390,  433},  {810,  900 } },
+	{3,  {520,  578},  {1080, 1200} },
+	{4,  {780,  867},  {1620, 1800} },
+	{5,  {1040, 1156}, {2160, 2400} },
+	{6,  {1170, 1300}, {2430, 2700} },
+	{7,  {1300, 1440}, {2700, 3000} }
+};
+
+/* MCS Based VHT rate table */
+/* MCS parameters with Nss = 1*/
+static struct index_vht_data_rate_type vht_mcs_nss1[] = {
+	/* MCS L20  S20    L40   S40    L80   S80 */
+	{0,  {65,   72 }, {135,  150},  {293,  325} },
+	{1,  {130,  144}, {270,  300},  {585,  650} },
+	{2,  {195,  217}, {405,  450},  {878,  975} },
+	{3,  {260,  289}, {540,  600},  {1170, 1300} },
+	{4,  {390,  433}, {810,  900},  {1755, 1950} },
+	{5,  {520,  578}, {1080, 1200}, {2340, 2600} },
+	{6,  {585,  650}, {1215, 1350}, {2633, 2925} },
+	{7,  {650,  722}, {1350, 1500}, {2925, 3250} },
+	{8,  {780,  867}, {1620, 1800}, {3510, 3900} },
+	{9,  {865,  960}, {1800, 2000}, {3900, 4333} }
+};
+
+/*MCS parameters with Nss = 2*/
+static struct index_vht_data_rate_type vht_mcs_nss2[] = {
+	/* MCS L20  S20    L40    S40    L80    S80 */
+	{0,  {130,  144},  {270,  300},  { 585,  650} },
+	{1,  {260,  289},  {540,  600},  {1170, 1300} },
+	{2,  {390,  433},  {810,  900},  {1755, 1950} },
+	{3,  {520,  578},  {1080, 1200}, {2340, 2600} },
+	{4,  {780,  867},  {1620, 1800}, {3510, 3900} },
+	{5,  {1040, 1156}, {2160, 2400}, {4680, 5200} },
+	{6,  {1170, 1300}, {2430, 2700}, {5265, 5850} },
+	{7,  {1300, 1444}, {2700, 3000}, {5850, 6500} },
+	{8,  {1560, 1733}, {3240, 3600}, {7020, 7800} },
+	{9,  {1730, 1920}, {3600, 4000}, {7800, 8667} }
+};
+
+#ifdef BIG_ENDIAN_HOST
+
+/* ############# function definitions ############ */
+
+/**
+ * wma_swap_bytes() - swap bytes
+ * @pv: buffer
+ * @n: swap bytes
+ *
+ * Return: none
+ */
+void wma_swap_bytes(void *pv, uint32_t n)
+{
+	int32_t no_words;
+	int32_t i;
+	uint32_t *word_ptr;
+
+	no_words = n / sizeof(uint32_t);
+	word_ptr = (uint32_t *) pv;
+	for (i = 0; i < no_words; i++)
+		*(word_ptr + i) = __cpu_to_le32(*(word_ptr + i));
+}
+
+#define SWAPME(x, len) wma_swap_bytes(&x, len)
+#endif /* BIG_ENDIAN_HOST */
+
+/**
+ * wma_mcs_rate_match() - find the match mcs rate
+ * @match_rate:	the rate to look up
+ * @is_sgi:	return if the SGI rate is found
+ * @nss:	the nss in use
+ * @nss1_rate:	the nss1 rate
+ * @nss1_srate:	the nss1 SGI rate
+ * @nss2_rate:	the nss2 rate
+ * @nss2_srate:	the nss2 SGI rate
+ *
+ * This is a helper function to find the match of the tx_rate
+ * in terms of the nss1/nss2 rate with non-SGI/SGI.
+ *
+ * Return: the found rate or 0 otherwise
+ */
+static inline uint16_t wma_mcs_rate_match(uint16_t match_rate, bool *is_sgi,
+					  uint8_t *nss, uint16_t nss1_rate,
+					  uint16_t nss1_srate,
+					  uint16_t nss2_rate,
+					  uint16_t nss2_srate)
+{
+	WMA_LOGD("%s match_rate: %d, %d %d %d %d",
+		__func__, match_rate, nss1_rate, nss1_srate, nss2_rate,
+		nss2_srate);
+
+	if (match_rate == nss1_rate) {
+		*nss = 1;
+		return nss1_rate;
+	} else if (match_rate == nss1_srate) {
+		*is_sgi = true;
+		*nss = 1;
+		return nss1_srate;
+	} else if (*nss == 2 && match_rate == nss2_rate)
+		return nss2_rate;
+	else if (*nss == 2 && match_rate == nss2_srate) {
+		*is_sgi = true;
+		return nss2_srate;
+	} else
+		return 0;
+}
+
+uint8_t wma_get_mcs_idx(uint16_t maxRate, uint8_t rate_flags,
+			uint8_t *nss, uint8_t *mcsRateFlag)
+{
+	uint8_t  index = 0;
+	uint16_t match_rate = 0;
+	bool is_sgi = false;
+
+	WMA_LOGD("%s rate:%d rate_flgs: 0x%x, nss: %d",
+		 __func__, maxRate, rate_flags, *nss);
+
+	*mcsRateFlag = rate_flags;
+	*mcsRateFlag &= ~TX_RATE_SGI;
+	for (index = 0; index < MAX_VHT_MCS_IDX; index++) {
+		if (rate_flags & TX_RATE_VHT80) {
+			/* check for vht80 nss1/2 rate set */
+			match_rate = wma_mcs_rate_match(maxRate, &is_sgi, nss,
+					vht_mcs_nss1[index].ht80_rate[0],
+					vht_mcs_nss1[index].ht80_rate[1],
+					vht_mcs_nss2[index].ht80_rate[0],
+					vht_mcs_nss2[index].ht80_rate[1]);
+			if (match_rate)
+				goto rate_found;
+		}
+		if ((rate_flags & TX_RATE_VHT40) |
+		    (rate_flags & TX_RATE_VHT80)) {
+			/* check for vht40 nss1/2 rate set */
+			match_rate = wma_mcs_rate_match(maxRate, &is_sgi, nss,
+					vht_mcs_nss1[index].ht40_rate[0],
+					vht_mcs_nss1[index].ht40_rate[1],
+					vht_mcs_nss2[index].ht40_rate[0],
+					vht_mcs_nss2[index].ht40_rate[1]);
+			if (match_rate) {
+				*mcsRateFlag &= ~TX_RATE_VHT80;
+				goto rate_found;
+			}
+		}
+		if ((rate_flags & TX_RATE_VHT20) |
+		    (rate_flags & TX_RATE_VHT40) |
+		    (rate_flags & TX_RATE_VHT80)) {
+			/* check for vht20 nss1/2 rate set */
+			match_rate = wma_mcs_rate_match(maxRate, &is_sgi, nss,
+					vht_mcs_nss1[index].ht20_rate[0],
+					vht_mcs_nss1[index].ht20_rate[1],
+					vht_mcs_nss2[index].ht20_rate[0],
+					vht_mcs_nss2[index].ht20_rate[1]);
+			if (match_rate) {
+				*mcsRateFlag &= ~(TX_RATE_VHT80 |
+						TX_RATE_VHT40);
+				goto rate_found;
+			}
+		}
+	}
+	for (index = 0; index < MAX_HT_MCS_IDX; index++) {
+		if (rate_flags & TX_RATE_HT40) {
+			/* check for ht40 nss1/2 rate set */
+			match_rate = wma_mcs_rate_match(maxRate, &is_sgi, nss,
+					mcs_nss1[index].ht40_rate[0],
+					mcs_nss1[index].ht40_rate[1],
+					mcs_nss2[index].ht40_rate[0],
+					mcs_nss2[index].ht40_rate[1]);
+			if (match_rate) {
+				*mcsRateFlag = TX_RATE_HT40;
+				if (*nss == 2)
+					index += MAX_HT_MCS_IDX;
+				goto rate_found;
+			}
+		}
+		if ((rate_flags & TX_RATE_HT20) ||
+			(rate_flags & TX_RATE_HT40)) {
+			/* check for ht20 nss1/2 rate set */
+			match_rate = wma_mcs_rate_match(maxRate, &is_sgi, nss,
+					mcs_nss1[index].ht20_rate[0],
+					mcs_nss1[index].ht20_rate[1],
+					mcs_nss2[index].ht20_rate[0],
+					mcs_nss2[index].ht20_rate[1]);
+			if (match_rate) {
+				*mcsRateFlag = TX_RATE_HT20;
+				if (*nss == 2)
+					index += MAX_HT_MCS_IDX;
+				goto rate_found;
+			}
+		}
+	}
+
+rate_found:
+	/* set SGI flag only if this is SGI rate */
+	if (match_rate && is_sgi == true)
+		*mcsRateFlag |= TX_RATE_SGI;
+
+	WMA_LOGD("%s - match_rate: %d index: %d rate_flag: 0x%x is_sgi: %d",
+		 __func__, match_rate, index, *mcsRateFlag, is_sgi);
+
+	return match_rate ? index : INVALID_MCS_IDX;
+}
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * wma_peek_vdev_req() - peek what request message is queued for response.
+ *			 the function does not delete the node after found
+ * @wma: WMA handle
+ * @vdev_id: vdev ID
+ * @type: request message type
+ *
+ * Return: the request message found
+ */
+static struct wma_target_req *wma_peek_vdev_req(tp_wma_handle wma,
+						uint8_t vdev_id, uint8_t type)
+{
+	struct wma_target_req *req_msg = NULL;
+	bool found = false;
+	qdf_list_node_t *node1 = NULL, *node2 = NULL;
+
+	qdf_spin_lock_bh(&wma->vdev_respq_lock);
+	if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->vdev_resp_queue,
+							&node2)) {
+		qdf_spin_unlock_bh(&wma->vdev_respq_lock);
+		return NULL;
+	}
+
+	do {
+		node1 = node2;
+		req_msg = qdf_container_of(node1, struct wma_target_req, node);
+		if (req_msg->vdev_id != vdev_id)
+			continue;
+		if (req_msg->type != type)
+			continue;
+
+		found = true;
+		break;
+	} while (QDF_STATUS_SUCCESS == qdf_list_peek_next(&wma->vdev_resp_queue,
+							  node1, &node2));
+	qdf_spin_unlock_bh(&wma->vdev_respq_lock);
+	if (!found) {
+		WMA_LOGE(FL("target request not found for vdev_id %d type %d"),
+			 vdev_id, type);
+		return NULL;
+	}
+	WMA_LOGD(FL("target request found for vdev id: %d type %d msg %d"),
+		 vdev_id, type, req_msg->msg_type);
+	return req_msg;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+void wma_lost_link_info_handler(tp_wma_handle wma, uint32_t vdev_id,
+					int32_t rssi)
+{
+	struct sir_lost_link_info *lost_link_info;
+	QDF_STATUS qdf_status;
+	struct scheduler_msg sme_msg = {0};
+
+	if (vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: received invalid vdev_id %d",
+			 __func__, vdev_id);
+		return;
+	}
+
+	/* report lost link information only for STA mode */
+	if (wma_is_vdev_up(vdev_id) &&
+	    (WMI_VDEV_TYPE_STA == wma->interfaces[vdev_id].type) &&
+	    (0 == wma->interfaces[vdev_id].sub_type)) {
+		lost_link_info = qdf_mem_malloc(sizeof(*lost_link_info));
+		if (!lost_link_info)
+			return;
+
+		lost_link_info->vdev_id = vdev_id;
+		lost_link_info->rssi = rssi;
+		sme_msg.type = eWNI_SME_LOST_LINK_INFO_IND;
+		sme_msg.bodyptr = lost_link_info;
+		sme_msg.bodyval = 0;
+		WMA_LOGD("%s: post msg to SME, bss_idx %d, rssi %d",  __func__,
+			 lost_link_info->vdev_id, lost_link_info->rssi);
+
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_SME,
+						    &sme_msg);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			WMA_LOGE("%s: fail to post msg to SME", __func__);
+			qdf_mem_free(lost_link_info);
+		}
+	}
+}
+
+/**
+ * host_map_smps_mode() - map fw smps mode to enum eSmpsModeValue
+ * @fw_smps_mode: fw smps mode
+ *
+ * Return: return enum eSmpsModeValue
+ */
+enum eSmpsModeValue host_map_smps_mode(A_UINT32 fw_smps_mode)
+{
+	enum eSmpsModeValue smps_mode = SMPS_MODE_DISABLED;
+
+	switch (fw_smps_mode) {
+	case WMI_SMPS_FORCED_MODE_STATIC:
+		smps_mode = STATIC_SMPS_MODE;
+		break;
+	case WMI_SMPS_FORCED_MODE_DYNAMIC:
+		smps_mode = DYNAMIC_SMPS_MODE;
+		break;
+	default:
+		smps_mode = SMPS_MODE_DISABLED;
+	}
+
+	return smps_mode;
+}
+
+/**
+ * wma_smps_mode_to_force_mode_param() - Map smps mode to force
+ * mode commmand param
+ * @smps_mode: SMPS mode according to the protocol
+ *
+ * Return: int > 0 for success else failure
+ */
+int wma_smps_mode_to_force_mode_param(uint8_t smps_mode)
+{
+	int param = -EINVAL;
+
+	switch (smps_mode) {
+	case STATIC_SMPS_MODE:
+		param = WMI_SMPS_FORCED_MODE_STATIC;
+		break;
+	case DYNAMIC_SMPS_MODE:
+		param = WMI_SMPS_FORCED_MODE_DYNAMIC;
+		break;
+	case SMPS_MODE_DISABLED:
+		param = WMI_SMPS_FORCED_MODE_DISABLED;
+		break;
+	default:
+		WMA_LOGE(FL("smps mode cannot be mapped :%d "),
+			 smps_mode);
+	}
+	return param;
+}
+
+#ifdef WLAN_FEATURE_STATS_EXT
+/**
+ * wma_stats_ext_event_handler() - extended stats event handler
+ * @handle:     wma handle
+ * @event_buf:  event buffer received from fw
+ * @len:        length of data
+ *
+ * Return: 0 for success or error code
+ */
+int wma_stats_ext_event_handler(void *handle, uint8_t *event_buf,
+				uint32_t len)
+{
+	WMI_STATS_EXT_EVENTID_param_tlvs *param_buf;
+	tSirStatsExtEvent *stats_ext_event;
+	wmi_stats_ext_event_fixed_param *stats_ext_info;
+	QDF_STATUS status;
+	struct scheduler_msg cds_msg = {0};
+	uint8_t *buf_ptr;
+	uint32_t alloc_len;
+
+	WMA_LOGD("%s: Posting stats ext event to SME", __func__);
+
+	param_buf = (WMI_STATS_EXT_EVENTID_param_tlvs *) event_buf;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid stats ext event buf", __func__);
+		return -EINVAL;
+	}
+
+	stats_ext_info = param_buf->fixed_param;
+	buf_ptr = (uint8_t *) stats_ext_info;
+
+	alloc_len = sizeof(tSirStatsExtEvent);
+	alloc_len += stats_ext_info->data_len;
+
+	if (stats_ext_info->data_len > (WMI_SVC_MSG_MAX_SIZE -
+	    WMI_TLV_HDR_SIZE - sizeof(*stats_ext_info)) ||
+	    stats_ext_info->data_len > param_buf->num_data) {
+		WMA_LOGE("Excess data_len:%d, num_data:%d",
+			stats_ext_info->data_len, param_buf->num_data);
+		return -EINVAL;
+	}
+	stats_ext_event = qdf_mem_malloc(alloc_len);
+	if (!stats_ext_event)
+		return -ENOMEM;
+
+	buf_ptr += sizeof(wmi_stats_ext_event_fixed_param) + WMI_TLV_HDR_SIZE;
+
+	stats_ext_event->vdev_id = stats_ext_info->vdev_id;
+	stats_ext_event->event_data_len = stats_ext_info->data_len;
+	qdf_mem_copy(stats_ext_event->event_data,
+		     buf_ptr, stats_ext_event->event_data_len);
+
+	cds_msg.type = eWNI_SME_STATS_EXT_EVENT;
+	cds_msg.bodyptr = (void *)stats_ext_event;
+	cds_msg.bodyval = 0;
+
+	status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_SME, &cds_msg);
+	if (status != QDF_STATUS_SUCCESS) {
+		WMA_LOGE("%s: Failed to post stats ext event to SME", __func__);
+		qdf_mem_free(stats_ext_event);
+		return -EFAULT;
+	}
+
+	WMA_LOGD("%s: stats ext event Posted to SME", __func__);
+	return 0;
+}
+#endif /* WLAN_FEATURE_STATS_EXT */
+
+
+/**
+ * wma_profile_data_report_event_handler() - fw profiling handler
+ * @handle:     wma handle
+ * @event_buf:  event buffer received from fw
+ * @len:        length of data
+ *
+ * Return: 0 for success or error code
+ */
+int wma_profile_data_report_event_handler(void *handle, uint8_t *event_buf,
+				uint32_t len)
+{
+	WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf;
+	wmi_wlan_profile_ctx_t *profile_ctx;
+	wmi_wlan_profile_t *profile_data;
+	uint32_t i = 0;
+	uint32_t entries;
+	uint8_t *buf_ptr;
+	char temp_str[150];
+
+	param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *) event_buf;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid profile data event buf", __func__);
+		return -EINVAL;
+	}
+	profile_ctx = param_buf->profile_ctx;
+	buf_ptr = (uint8_t *)profile_ctx;
+	buf_ptr = buf_ptr + sizeof(wmi_wlan_profile_ctx_t) + WMI_TLV_HDR_SIZE;
+	profile_data = (wmi_wlan_profile_t *) buf_ptr;
+	entries = profile_ctx->bin_count;
+
+	if (entries > param_buf->num_profile_data) {
+		WMA_LOGE("FW bin count %d more than data %d in TLV hdr",
+			 entries,
+			 param_buf->num_profile_data);
+		return -EINVAL;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
+				"Profile data stats\n");
+	QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
+		"TOT: %d\n"
+		"tx_msdu_cnt: %d\n"
+		"tx_mpdu_cnt: %d\n"
+		"tx_ppdu_cnt: %d\n"
+		"rx_msdu_cnt: %d\n"
+		"rx_mpdu_cnt: %d\n"
+		"bin_count: %d\n",
+		profile_ctx->tot,
+		profile_ctx->tx_msdu_cnt,
+		profile_ctx->tx_mpdu_cnt,
+		profile_ctx->tx_ppdu_cnt,
+		profile_ctx->rx_msdu_cnt,
+		profile_ctx->rx_mpdu_cnt,
+		profile_ctx->bin_count);
+
+	QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
+		  "Profile ID: Count: TOT: Min: Max: hist_intvl: hist[0]: hist[1]:hist[2]");
+
+	for (i = 0; i < entries; i++) {
+		if (i == WMI_WLAN_PROFILE_MAX_BIN_CNT)
+			break;
+		snprintf(temp_str, sizeof(temp_str),
+			 " %d : %d : %d : %d : %d : %d : %d : %d : %d",
+			profile_data[i].id,
+			profile_data[i].cnt,
+			profile_data[i].tot,
+			profile_data[i].min,
+			profile_data[i].max,
+			profile_data[i].hist_intvl,
+			profile_data[i].hist[0],
+			profile_data[i].hist[1],
+			profile_data[i].hist[2]);
+		QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
+			"%s", temp_str);
+	}
+
+	return 0;
+}
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+
+#define WMA_FILL_TX_STATS(eve, msg)   do {\
+	(msg)->msdus = (eve)->tx_msdu_cnt;\
+	(msg)->mpdus = (eve)->tx_mpdu_cnt;\
+	(msg)->ppdus = (eve)->tx_ppdu_cnt;\
+	(msg)->bytes = (eve)->tx_bytes;\
+	(msg)->drops = (eve)->tx_msdu_drop_cnt;\
+	(msg)->drop_bytes = (eve)->tx_drop_bytes;\
+	(msg)->retries = (eve)->tx_mpdu_retry_cnt;\
+	(msg)->failed = (eve)->tx_mpdu_fail_cnt;\
+} while (0)
+
+#define WMA_FILL_RX_STATS(eve, msg)       do {\
+	(msg)->mpdus = (eve)->mac_rx_mpdu_cnt;\
+	(msg)->bytes = (eve)->mac_rx_bytes;\
+	(msg)->ppdus = (eve)->phy_rx_ppdu_cnt;\
+	(msg)->ppdu_bytes = (eve)->phy_rx_bytes;\
+	(msg)->mpdu_retry = (eve)->rx_mpdu_retry_cnt;\
+	(msg)->mpdu_dup = (eve)->rx_mpdu_dup_cnt;\
+	(msg)->mpdu_discard = (eve)->rx_mpdu_discard_cnt;\
+} while (0)
+
+/**
+ * wma_get_ll_stats_ext_buf() - alloc result buffer for MAC counters
+ * @len: buffer length output
+ * @peer_num: peer number
+ * @fixed_param: fixed parameters in WMI event
+ *
+ * Structure of the stats message
+ * LL_EXT_STATS
+ *  |
+ *  |--Channel stats[1~n]
+ *  |--Peer[1~n]
+ *      |
+ *      +---Signal
+ *      +---TX
+ *      |    +---BE
+ *      |    +---BK
+ *      |    +---VI
+ *      |    +---VO
+ *      |
+ *      +---RX
+ *           +---BE
+ *           +---BK
+ *           +---VI
+ *           +---VO
+ * For each Access Category, the arregation and mcs
+ * stats are as this:
+ *  TX
+ *   +-BE/BK/VI/VO
+ *         +----tx_mpdu_aggr_array
+ *         +----tx_succ_mcs_array
+ *         +----tx_fail_mcs_array
+ *         +----tx_delay_array
+ *  RX
+ *   +-BE/BK/VI/VO
+ *         +----rx_mpdu_aggr_array
+ *         +----rx_mcs_array
+ *
+ * return: Address for result buffer.
+ */
+static tSirLLStatsResults *wma_get_ll_stats_ext_buf(uint32_t *len,
+						    uint32_t peer_num,
+			wmi_report_stats_event_fixed_param *fixed_param)
+{
+	tSirLLStatsResults *buf;
+	uint32_t buf_len;
+	uint32_t total_array_len, total_peer_len;
+	bool excess_data = false;
+
+	if (!len || !fixed_param) {
+		WMA_LOGE(FL("Invalid input parameters."));
+		return NULL;
+	}
+
+	/*
+	 * Result buffer has a structure like this:
+	 *     ---------------------------------
+	 *     |      trigger_cond_i           |
+	 *     +-------------------------------+
+	 *     |      cca_chgd_bitmap          |
+	 *     +-------------------------------+
+	 *     |      sig_chgd_bitmap          |
+	 *     +-------------------------------+
+	 *     |      tx_chgd_bitmap           |
+	 *     +-------------------------------+
+	 *     |      rx_chgd_bitmap           |
+	 *     +-------------------------------+
+	 *     |      peer_num                 |
+	 *     +-------------------------------+
+	 *     |      channel_num              |
+	 *     +-------------------------------+
+	 *     |      tx_mpdu_aggr_array_len   |
+	 *     +-------------------------------+
+	 *     |      tx_succ_mcs_array_len    |
+	 *     +-------------------------------+
+	 *     |      tx_fail_mcs_array_len    |
+	 *     +-------------------------------+
+	 *     |      tx_delay_array_len       |
+	 *     +-------------------------------+
+	 *     |      rx_mpdu_aggr_array_len   |
+	 *     +-------------------------------+
+	 *     |      rx_mcs_array_len         |
+	 *     +-------------------------------+
+	 *     |      pointer to CCA stats     |
+	 *     +-------------------------------+
+	 *     |      CCA stats                |
+	 *     +-------------------------------+
+	 *     |      peer_stats               |----+
+	 *     +-------------------------------+    |
+	 *     | TX aggr/mcs parameters array  |    |
+	 *     | Length of this buffer is      |    |
+	 *     | not fixed.                    |<-+ |
+	 *     +-------------------------------+  | |
+	 *     |      per peer tx stats        |--+ |
+	 *     |         BE                    | <--+
+	 *     |         BK                    |    |
+	 *     |         VI                    |    |
+	 *     |         VO                    |    |
+	 *     +-------------------------------+    |
+	 *     | TX aggr/mcs parameters array  |    |
+	 *     | Length of this buffer is      |    |
+	 *     | not fixed.                    |<-+ |
+	 *     +-------------------------------+  | |
+	 *     |      peer peer rx stats       |--+ |
+	 *     |         BE                    | <--+
+	 *     |         BK                    |
+	 *     |         VI                    |
+	 *     |         VO                    |
+	 *     ---------------------------------
+	 */
+
+	buf_len = sizeof(tSirLLStatsResults) +
+		  sizeof(struct sir_wifi_ll_ext_stats);
+	do {
+		if (fixed_param->num_chan_cca_stats > (WMI_SVC_MSG_MAX_SIZE /
+		    sizeof(struct sir_wifi_chan_cca_stats))) {
+			excess_data = true;
+			break;
+		}
+		buf_len += (fixed_param->num_chan_cca_stats *
+				sizeof(struct sir_wifi_chan_cca_stats));
+		if (fixed_param->tx_mpdu_aggr_array_len >
+		    WMI_SVC_MSG_MAX_SIZE) {
+			excess_data = true;
+			break;
+		} else {
+			total_array_len = fixed_param->tx_mpdu_aggr_array_len;
+		}
+		if (fixed_param->tx_succ_mcs_array_len >
+		    (WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
+			excess_data = true;
+			break;
+		} else {
+			total_array_len += fixed_param->tx_succ_mcs_array_len;
+		}
+		if (fixed_param->tx_fail_mcs_array_len >
+		    (WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
+			excess_data = true;
+			break;
+		} else {
+			total_array_len += fixed_param->tx_fail_mcs_array_len;
+		}
+		if (fixed_param->tx_ppdu_delay_array_len >
+		    (WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
+			excess_data = true;
+			break;
+		} else {
+			total_array_len += fixed_param->tx_ppdu_delay_array_len;
+		}
+		if (fixed_param->rx_mpdu_aggr_array_len >
+		    (WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
+			excess_data = true;
+			break;
+		} else {
+			total_array_len += fixed_param->rx_mpdu_aggr_array_len;
+		}
+		if (fixed_param->rx_mcs_array_len >
+		    (WMI_SVC_MSG_MAX_SIZE - total_array_len)) {
+			excess_data = true;
+			break;
+		} else {
+			total_array_len += fixed_param->rx_mcs_array_len;
+		}
+
+		if (total_array_len > (WMI_SVC_MSG_MAX_SIZE /
+		    (sizeof(uint32_t) * WLAN_MAX_AC))) {
+			excess_data = true;
+			break;
+		} else {
+			total_peer_len = (sizeof(uint32_t) * WLAN_MAX_AC *
+					 total_array_len) +
+					 (WLAN_MAX_AC *
+					 (sizeof(struct sir_wifi_tx) +
+					 sizeof(struct sir_wifi_rx)));
+		}
+		if (total_peer_len > WMI_SVC_MSG_MAX_SIZE) {
+			excess_data = true;
+			break;
+		}
+		if (peer_num > WMI_SVC_MSG_MAX_SIZE / (total_peer_len +
+		    sizeof(struct sir_wifi_ll_ext_peer_stats))) {
+			excess_data = true;
+			break;
+		} else {
+			buf_len += peer_num *
+				   (sizeof(struct sir_wifi_ll_ext_peer_stats) +
+				    total_peer_len);
+		}
+	} while (0);
+
+	if (excess_data || (buf_len > WMI_SVC_MSG_MAX_SIZE)) {
+		WMA_LOGE("%s: excess wmi buffer: peer %d cca %d tx_mpdu %d tx_succ%d tx_fail %d tx_ppdu %d rx_mpdu %d rx_mcs %d",
+			 __func__, peer_num, fixed_param->num_chan_cca_stats,
+			 fixed_param->tx_mpdu_aggr_array_len,
+			 fixed_param->tx_succ_mcs_array_len,
+			 fixed_param->tx_fail_mcs_array_len,
+			 fixed_param->tx_ppdu_delay_array_len,
+			 fixed_param->rx_mpdu_aggr_array_len,
+			 fixed_param->rx_mcs_array_len);
+		return NULL;
+	}
+
+	buf = qdf_mem_malloc(buf_len);
+	if (!buf)
+		*len = 0;
+	else
+		*len = buf_len;
+
+	return buf;
+}
+
+/**
+ * wma_fill_tx_stats() - Fix TX stats into result buffer
+ * @ll_stats: LL stats buffer
+ * @fix_param: parameters with fixed length in WMI event
+ * @param_buf: parameters without fixed length in WMI event
+ * @buf: buffer for TLV parameters
+ *
+ * Return: None
+ */
+static void wma_fill_tx_stats(struct sir_wifi_ll_ext_stats *ll_stats,
+			      wmi_report_stats_event_fixed_param *fix_param,
+			      WMI_REPORT_STATS_EVENTID_param_tlvs *param_buf,
+			      uint8_t **buf, uint32_t *buf_length)
+{
+	uint8_t *result;
+	uint32_t i, j, k;
+	wmi_peer_ac_tx_stats *wmi_peer_tx;
+	wmi_tx_stats *wmi_tx;
+	struct sir_wifi_tx *tx_stats;
+	struct sir_wifi_ll_ext_peer_stats *peer_stats;
+	uint32_t *tx_mpdu_aggr, *tx_succ_mcs, *tx_fail_mcs, *tx_delay;
+	uint32_t len, dst_len, tx_mpdu_aggr_array_len, tx_succ_mcs_array_len,
+		 tx_fail_mcs_array_len, tx_delay_array_len;
+
+	result = *buf;
+	dst_len = *buf_length;
+	tx_mpdu_aggr_array_len = fix_param->tx_mpdu_aggr_array_len;
+	ll_stats->tx_mpdu_aggr_array_len = tx_mpdu_aggr_array_len;
+	tx_succ_mcs_array_len = fix_param->tx_succ_mcs_array_len;
+	ll_stats->tx_succ_mcs_array_len = tx_succ_mcs_array_len;
+	tx_fail_mcs_array_len = fix_param->tx_fail_mcs_array_len;
+	ll_stats->tx_fail_mcs_array_len = tx_fail_mcs_array_len;
+	tx_delay_array_len = fix_param->tx_ppdu_delay_array_len;
+	ll_stats->tx_delay_array_len = tx_delay_array_len;
+	wmi_peer_tx = param_buf->peer_ac_tx_stats;
+	wmi_tx = param_buf->tx_stats;
+
+	len = fix_param->num_peer_ac_tx_stats *
+		WLAN_MAX_AC * tx_mpdu_aggr_array_len * sizeof(uint32_t);
+	if (len <= dst_len) {
+		tx_mpdu_aggr = (uint32_t *)result;
+		qdf_mem_copy(tx_mpdu_aggr, param_buf->tx_mpdu_aggr, len);
+		result += len;
+		dst_len -= len;
+	} else {
+		WMA_LOGE(FL("TX_MPDU_AGGR buffer length is wrong."));
+		tx_mpdu_aggr = NULL;
+	}
+
+	len = fix_param->num_peer_ac_tx_stats * WLAN_MAX_AC *
+		tx_succ_mcs_array_len * sizeof(uint32_t);
+	if (len <= dst_len) {
+		tx_succ_mcs = (uint32_t *)result;
+		qdf_mem_copy(tx_succ_mcs, param_buf->tx_succ_mcs, len);
+		result += len;
+		dst_len -= len;
+	} else {
+		WMA_LOGE(FL("TX_SUCC_MCS buffer length is wrong."));
+		tx_succ_mcs = NULL;
+	}
+
+	len = fix_param->num_peer_ac_tx_stats * WLAN_MAX_AC *
+		tx_fail_mcs_array_len * sizeof(uint32_t);
+	if (len <= dst_len) {
+		tx_fail_mcs = (uint32_t *)result;
+		qdf_mem_copy(tx_fail_mcs, param_buf->tx_fail_mcs, len);
+		result += len;
+		dst_len -= len;
+	} else {
+		WMA_LOGE(FL("TX_FAIL_MCS buffer length is wrong."));
+		tx_fail_mcs = NULL;
+	}
+
+	len = fix_param->num_peer_ac_tx_stats *
+		WLAN_MAX_AC * tx_delay_array_len * sizeof(uint32_t);
+	if (len <= dst_len) {
+		tx_delay = (uint32_t *)result;
+		qdf_mem_copy(tx_delay, param_buf->tx_ppdu_delay, len);
+		result += len;
+		dst_len -= len;
+	} else {
+		WMA_LOGE(FL("TX_DELAY buffer length is wrong."));
+		tx_delay = NULL;
+	}
+
+	/* per peer tx stats */
+	peer_stats = ll_stats->peer_stats;
+
+	for (i = 0; i < fix_param->num_peer_ac_tx_stats; i++) {
+		uint32_t peer_id = wmi_peer_tx[i].peer_id;
+		struct sir_wifi_tx *ac;
+		wmi_tx_stats *wmi_tx_stats;
+
+		for (j = 0; j < ll_stats->peer_num; j++) {
+			peer_stats += j;
+			if (peer_stats->peer_id == WIFI_INVALID_PEER_ID ||
+			    peer_stats->peer_id == peer_id)
+				break;
+		}
+
+		if (j < ll_stats->peer_num) {
+			peer_stats->peer_id = wmi_peer_tx[i].peer_id;
+			peer_stats->vdev_id = wmi_peer_tx[i].vdev_id;
+			tx_stats = (struct sir_wifi_tx *)result;
+			for (k = 0; k < WLAN_MAX_AC; k++) {
+				wmi_tx_stats = &wmi_tx[i * WLAN_MAX_AC + k];
+				ac = &tx_stats[k];
+				WMA_FILL_TX_STATS(wmi_tx_stats, ac);
+				ac->mpdu_aggr_size = tx_mpdu_aggr;
+				ac->aggr_len = tx_mpdu_aggr_array_len *
+							sizeof(uint32_t);
+				ac->success_mcs_len = tx_succ_mcs_array_len *
+							sizeof(uint32_t);
+				ac->success_mcs = tx_succ_mcs;
+				ac->fail_mcs = tx_fail_mcs;
+				ac->fail_mcs_len = tx_fail_mcs_array_len *
+							sizeof(uint32_t);
+				ac->delay = tx_delay;
+				ac->delay_len = tx_delay_array_len *
+							sizeof(uint32_t);
+				peer_stats->ac_stats[k].tx_stats = ac;
+				peer_stats->ac_stats[k].type = k;
+				tx_mpdu_aggr += tx_mpdu_aggr_array_len;
+				tx_succ_mcs += tx_succ_mcs_array_len;
+				tx_fail_mcs += tx_fail_mcs_array_len;
+				tx_delay += tx_delay_array_len;
+			}
+			result += WLAN_MAX_AC * sizeof(struct sir_wifi_tx);
+		} else {
+			/*
+			 * Buffer for Peer TX counter overflow.
+			 * There is peer ID mismatch between TX, RX,
+			 * signal counters.
+			 */
+			WMA_LOGE(FL("One peer TX info is dropped."));
+
+			tx_mpdu_aggr += tx_mpdu_aggr_array_len * WLAN_MAX_AC;
+			tx_succ_mcs += tx_succ_mcs_array_len * WLAN_MAX_AC;
+			tx_fail_mcs += tx_fail_mcs_array_len * WLAN_MAX_AC;
+			tx_delay += tx_delay_array_len * WLAN_MAX_AC;
+		}
+	}
+	*buf = result;
+	*buf_length = dst_len;
+}
+
+/**
+ * wma_fill_rx_stats() - Fix RX stats into result buffer
+ * @ll_stats: LL stats buffer
+ * @fix_param: parameters with fixed length in WMI event
+ * @param_buf: parameters without fixed length in WMI event
+ * @buf: buffer for TLV parameters
+ *
+ * Return: None
+ */
+static void wma_fill_rx_stats(struct sir_wifi_ll_ext_stats *ll_stats,
+			      wmi_report_stats_event_fixed_param *fix_param,
+			      WMI_REPORT_STATS_EVENTID_param_tlvs *param_buf,
+			      uint8_t **buf, uint32_t *buf_length)
+{
+	uint8_t *result;
+	uint32_t i, j, k;
+	uint32_t *rx_mpdu_aggr, *rx_mcs;
+	wmi_rx_stats *wmi_rx;
+	wmi_peer_ac_rx_stats *wmi_peer_rx;
+	struct sir_wifi_rx *rx_stats;
+	struct sir_wifi_ll_ext_peer_stats *peer_stats;
+	uint32_t len, dst_len, rx_mpdu_aggr_array_len, rx_mcs_array_len;
+
+	rx_mpdu_aggr_array_len = fix_param->rx_mpdu_aggr_array_len;
+	ll_stats->rx_mpdu_aggr_array_len = rx_mpdu_aggr_array_len;
+	rx_mcs_array_len = fix_param->rx_mcs_array_len;
+	ll_stats->rx_mcs_array_len = rx_mcs_array_len;
+	wmi_peer_rx = param_buf->peer_ac_rx_stats;
+	wmi_rx = param_buf->rx_stats;
+
+	result = *buf;
+	dst_len = *buf_length;
+	len = sizeof(uint32_t) * (fix_param->num_peer_ac_rx_stats *
+				  WLAN_MAX_AC * rx_mpdu_aggr_array_len);
+	if (len <= dst_len) {
+		rx_mpdu_aggr = (uint32_t *)result;
+		qdf_mem_copy(rx_mpdu_aggr, param_buf->rx_mpdu_aggr, len);
+		result += len;
+		dst_len -= len;
+	} else {
+		WMA_LOGE(FL("RX_MPDU_AGGR array length is wrong."));
+		rx_mpdu_aggr = NULL;
+	}
+
+	len = sizeof(uint32_t) * (fix_param->num_peer_ac_rx_stats *
+				  WLAN_MAX_AC * rx_mcs_array_len);
+	if (len <= dst_len) {
+		rx_mcs = (uint32_t *)result;
+		qdf_mem_copy(rx_mcs, param_buf->rx_mcs, len);
+		result += len;
+		dst_len -= len;
+	} else {
+		WMA_LOGE(FL("RX_MCS array length is wrong."));
+		rx_mcs = NULL;
+	}
+
+	/* per peer rx stats */
+	peer_stats = ll_stats->peer_stats;
+	for (i = 0; i < fix_param->num_peer_ac_rx_stats; i++) {
+		uint32_t peer_id = wmi_peer_rx[i].peer_id;
+		struct sir_wifi_rx *ac;
+		wmi_rx_stats *wmi_rx_stats;
+
+		for (j = 0; j < ll_stats->peer_num; j++) {
+			peer_stats += j;
+			if ((peer_stats->peer_id == WIFI_INVALID_PEER_ID) ||
+			    (peer_stats->peer_id == peer_id))
+				break;
+		}
+
+		if (j < ll_stats->peer_num) {
+			peer_stats->peer_id = wmi_peer_rx[i].peer_id;
+			peer_stats->vdev_id = wmi_peer_rx[i].vdev_id;
+			peer_stats->sta_ps_inds = wmi_peer_rx[i].sta_ps_inds;
+			peer_stats->sta_ps_durs = wmi_peer_rx[i].sta_ps_durs;
+			peer_stats->rx_probe_reqs =
+						wmi_peer_rx[i].rx_probe_reqs;
+			peer_stats->rx_oth_mgmts = wmi_peer_rx[i].rx_oth_mgmts;
+			rx_stats = (struct sir_wifi_rx *)result;
+
+			for (k = 0; k < WLAN_MAX_AC; k++) {
+				wmi_rx_stats = &wmi_rx[i * WLAN_MAX_AC + k];
+				ac = &rx_stats[k];
+				WMA_FILL_RX_STATS(wmi_rx_stats, ac);
+				ac->mpdu_aggr = rx_mpdu_aggr;
+				ac->aggr_len = rx_mpdu_aggr_array_len *
+							sizeof(uint32_t);
+				ac->mcs = rx_mcs;
+				ac->mcs_len = rx_mcs_array_len *
+							sizeof(uint32_t);
+				peer_stats->ac_stats[k].rx_stats = ac;
+				peer_stats->ac_stats[k].type = k;
+				rx_mpdu_aggr += rx_mpdu_aggr_array_len;
+				rx_mcs += rx_mcs_array_len;
+			}
+			result += WLAN_MAX_AC * sizeof(struct sir_wifi_rx);
+		} else {
+			/*
+			 * Buffer for Peer RX counter overflow.
+			 * There is peer ID mismatch between TX, RX,
+			 * signal counters.
+			 */
+			WMA_LOGE(FL("One peer RX info is dropped."));
+			rx_mpdu_aggr += rx_mpdu_aggr_array_len * WLAN_MAX_AC;
+			rx_mcs += rx_mcs_array_len * WLAN_MAX_AC;
+		}
+	}
+	*buf = result;
+	*buf_length = dst_len;
+}
+
+/**
+ * wma_ll_stats_evt_handler() - handler for MAC layer counters.
+ * @handle - wma handle
+ * @event - FW event
+ * @len - length of FW event
+ *
+ * return: 0 success.
+ */
+static int wma_ll_stats_evt_handler(void *handle, u_int8_t *event,
+				    u_int32_t len)
+{
+	WMI_REPORT_STATS_EVENTID_param_tlvs *param_buf;
+	wmi_report_stats_event_fixed_param *fixed_param;
+	tSirLLStatsResults *link_stats_results;
+	wmi_chan_cca_stats *wmi_cca_stats;
+	wmi_peer_signal_stats *wmi_peer_signal;
+	wmi_peer_ac_rx_stats *wmi_peer_rx;
+	struct sir_wifi_ll_ext_stats *ll_stats;
+	struct sir_wifi_ll_ext_peer_stats *peer_stats;
+	struct sir_wifi_chan_cca_stats *cca_stats;
+	struct sir_wifi_peer_signal_stats *peer_signal;
+	uint8_t *result;
+	uint32_t i, peer_num, result_size, dst_len;
+	tpAniSirGlobal mac;
+	struct scheduler_msg sme_msg = { 0 };
+	QDF_STATUS qdf_status;
+
+	mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac) {
+		WMA_LOGD("%s: NULL mac ptr. Exiting", __func__);
+		return -EINVAL;
+	}
+
+	if (!mac->sme.link_layer_stats_ext_cb) {
+		WMA_LOGD("%s: HDD callback is null", __func__);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("%s: Posting MAC counters event to HDD", __func__);
+
+	param_buf = (WMI_REPORT_STATS_EVENTID_param_tlvs *)event;
+	fixed_param = param_buf->fixed_param;
+	wmi_cca_stats = param_buf->chan_cca_stats;
+	wmi_peer_signal = param_buf->peer_signal_stats;
+	wmi_peer_rx = param_buf->peer_ac_rx_stats;
+	if (fixed_param->num_peer_signal_stats >
+		param_buf->num_peer_signal_stats ||
+		fixed_param->num_peer_ac_tx_stats >
+		param_buf->num_peer_ac_tx_stats ||
+		fixed_param->num_peer_ac_rx_stats >
+		param_buf->num_peer_ac_rx_stats) {
+		WMA_LOGE("%s: excess num_peer_signal_stats:%d, num_peer_ac_tx_stats:%d, num_peer_ac_rx_stats:%d",
+			__func__, fixed_param->num_peer_signal_stats,
+			fixed_param->num_peer_ac_tx_stats,
+			fixed_param->num_peer_ac_rx_stats);
+		return -EINVAL;
+	}
+
+	/* Get the MAX of three peer numbers */
+	peer_num = fixed_param->num_peer_signal_stats >
+			fixed_param->num_peer_ac_tx_stats ?
+			fixed_param->num_peer_signal_stats :
+			fixed_param->num_peer_ac_tx_stats;
+	peer_num = peer_num > fixed_param->num_peer_ac_rx_stats ?
+			peer_num : fixed_param->num_peer_ac_rx_stats;
+
+	if (peer_num == 0)
+		return -EINVAL;
+
+	link_stats_results = wma_get_ll_stats_ext_buf(&result_size,
+						      peer_num,
+						      fixed_param);
+	if (!link_stats_results) {
+		WMA_LOGE("%s: Fail to allocate stats buffer", __func__);
+		return -EINVAL;
+	}
+	link_stats_results->paramId = WMI_LL_STATS_EXT_MAC_COUNTER;
+	link_stats_results->num_peers = peer_num;
+	link_stats_results->peer_event_number = 1;
+	link_stats_results->moreResultToFollow = 0;
+
+	ll_stats = (struct sir_wifi_ll_ext_stats *)link_stats_results->results;
+	ll_stats->trigger_cond_id = fixed_param->trigger_cond_id;
+	ll_stats->cca_chgd_bitmap = fixed_param->cca_chgd_bitmap;
+	ll_stats->sig_chgd_bitmap = fixed_param->sig_chgd_bitmap;
+	ll_stats->tx_chgd_bitmap = fixed_param->tx_chgd_bitmap;
+	ll_stats->rx_chgd_bitmap = fixed_param->rx_chgd_bitmap;
+	ll_stats->channel_num = fixed_param->num_chan_cca_stats;
+	ll_stats->peer_num = peer_num;
+
+	result = (uint8_t *)ll_stats->stats;
+	peer_stats = (struct sir_wifi_ll_ext_peer_stats *)result;
+	ll_stats->peer_stats = peer_stats;
+
+	for (i = 0; i < peer_num; i++) {
+		peer_stats[i].peer_id = WIFI_INVALID_PEER_ID;
+		peer_stats[i].vdev_id = WIFI_INVALID_VDEV_ID;
+	}
+
+	/* Per peer signal */
+	result_size -= sizeof(struct sir_wifi_ll_ext_stats);
+	dst_len = sizeof(struct sir_wifi_peer_signal_stats);
+	for (i = 0; i < fixed_param->num_peer_signal_stats; i++) {
+		peer_stats[i].peer_id = wmi_peer_signal->peer_id;
+		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) {
+			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."));
+		}
+		wmi_peer_signal++;
+	}
+
+	result += peer_num * sizeof(struct sir_wifi_ll_ext_peer_stats);
+	cca_stats = (struct sir_wifi_chan_cca_stats *)result;
+	ll_stats->cca = cca_stats;
+	dst_len = sizeof(struct sir_wifi_chan_cca_stats);
+	for (i = 0; i < ll_stats->channel_num; i++) {
+		if (dst_len <= result_size) {
+			qdf_mem_copy(&cca_stats[i], &wmi_cca_stats->vdev_id,
+				     dst_len);
+			result_size -= dst_len;
+		} else {
+			WMA_LOGE(FL("Invalid length of CCA."));
+		}
+	}
+
+	result += i * sizeof(struct sir_wifi_chan_cca_stats);
+	wma_fill_tx_stats(ll_stats, fixed_param, param_buf,
+			  &result, &result_size);
+	wma_fill_rx_stats(ll_stats, fixed_param, param_buf,
+			  &result, &result_size);
+	sme_msg.type = eWMI_SME_LL_STATS_IND;
+	sme_msg.bodyptr = (void *)link_stats_results;
+	sme_msg.bodyval = 0;
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGP(FL("Failed to post peer stat change msg!"));
+		qdf_mem_free(link_stats_results);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * wma_unified_link_peer_stats_event_handler() - peer stats event handler
+ * @handle:          wma handle
+ * @cmd_param_info:  data received with event from fw
+ * @len:             length of data
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_unified_link_peer_stats_event_handler(void *handle,
+						     uint8_t *cmd_param_info,
+						     uint32_t len)
+{
+	WMI_PEER_LINK_STATS_EVENTID_param_tlvs *param_tlvs;
+	wmi_peer_stats_event_fixed_param *fixed_param;
+	wmi_peer_link_stats *peer_stats, *temp_peer_stats;
+	wmi_rate_stats *rate_stats;
+	tSirLLStatsResults *link_stats_results;
+	uint8_t *results, *t_peer_stats, *t_rate_stats;
+	uint32_t count, rate_cnt;
+	uint32_t total_num_rates = 0;
+	uint32_t next_res_offset, next_peer_offset, next_rate_offset;
+	size_t peer_info_size, peer_stats_size, rate_stats_size;
+	size_t link_stats_results_size;
+	bool excess_data = false;
+	uint32_t buf_len = 0;
+
+	tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac) {
+		WMA_LOGD("%s: NULL mac ptr. Exiting", __func__);
+		return -EINVAL;
+	}
+
+	if (!mac->sme.link_layer_stats_cb) {
+		WMA_LOGD("%s: HDD callback is null", __func__);
+		return -EINVAL;
+	}
+
+	param_tlvs = (WMI_PEER_LINK_STATS_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_tlvs) {
+		WMA_LOGA("%s: Invalid stats event", __func__);
+		return -EINVAL;
+	}
+	/*
+	 * cmd_param_info contains
+	 * wmi_peer_stats_event_fixed_param fixed_param;
+	 * num_peers * size of(struct wmi_peer_link_stats)
+	 * total_num_rates * size of(struct wmi_rate_stats)
+	 * total_num_rates is the sum of the rates of all the peers.
+	 */
+	fixed_param = param_tlvs->fixed_param;
+	peer_stats = param_tlvs->peer_stats;
+	rate_stats = param_tlvs->peer_rate_stats;
+
+	if (!fixed_param || !peer_stats ||
+	    (peer_stats->num_rates && !rate_stats)) {
+		WMA_LOGA("%s: Invalid param_tlvs for Peer Stats", __func__);
+		return -EINVAL;
+	}
+
+	do {
+		if (fixed_param->num_peers >
+		    WMI_SVC_MSG_MAX_SIZE/sizeof(wmi_peer_link_stats) ||
+		    fixed_param->num_peers > param_tlvs->num_peer_stats) {
+			excess_data = true;
+			break;
+		} else {
+			buf_len = fixed_param->num_peers *
+				sizeof(wmi_peer_link_stats);
+		}
+		temp_peer_stats = (wmi_peer_link_stats *) peer_stats;
+		for (count = 0; count < fixed_param->num_peers; count++) {
+			if (temp_peer_stats->num_rates >
+			    WMI_SVC_MSG_MAX_SIZE / sizeof(wmi_rate_stats)) {
+				excess_data = true;
+				break;
+			} else {
+				total_num_rates += temp_peer_stats->num_rates;
+				if (total_num_rates >
+				    WMI_SVC_MSG_MAX_SIZE /
+				    sizeof(wmi_rate_stats) || total_num_rates >
+				    param_tlvs->num_peer_rate_stats) {
+					excess_data = true;
+					break;
+				}
+				buf_len += temp_peer_stats->num_rates *
+					sizeof(wmi_rate_stats);
+			}
+			temp_peer_stats++;
+		}
+	} while (0);
+
+	if (excess_data ||
+	    (buf_len > WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param))) {
+		WMA_LOGE("excess wmi buffer: rates:%d, peers:%d",
+			peer_stats->num_rates, fixed_param->num_peers);
+		return -EINVAL;
+	}
+
+	peer_stats_size = sizeof(tSirWifiPeerStat);
+	peer_info_size = sizeof(tSirWifiPeerInfo);
+	rate_stats_size = sizeof(tSirWifiRateStat);
+	link_stats_results_size =
+		sizeof(*link_stats_results) + peer_stats_size +
+		(fixed_param->num_peers * peer_info_size) +
+		(total_num_rates * rate_stats_size);
+
+	link_stats_results = qdf_mem_malloc(link_stats_results_size);
+	if (!link_stats_results)
+		return -ENOMEM;
+
+	qdf_mem_zero(link_stats_results, link_stats_results_size);
+
+	link_stats_results->paramId = WMI_LINK_STATS_ALL_PEER;
+	link_stats_results->rspId = fixed_param->request_id;
+	link_stats_results->ifaceId = 0;
+	link_stats_results->num_peers = fixed_param->num_peers;
+	link_stats_results->peer_event_number = fixed_param->peer_event_number;
+	link_stats_results->moreResultToFollow = fixed_param->more_data;
+
+	qdf_mem_copy(link_stats_results->results,
+		     &fixed_param->num_peers, peer_stats_size);
+
+	results = (uint8_t *) link_stats_results->results;
+	t_peer_stats = (uint8_t *) peer_stats;
+	t_rate_stats = (uint8_t *) rate_stats;
+	next_res_offset = peer_stats_size;
+	next_peer_offset = WMI_TLV_HDR_SIZE;
+	next_rate_offset = WMI_TLV_HDR_SIZE;
+	for (rate_cnt = 0; rate_cnt < fixed_param->num_peers; rate_cnt++) {
+		qdf_mem_copy(results + next_res_offset,
+			     t_peer_stats + next_peer_offset, peer_info_size);
+		next_res_offset += peer_info_size;
+
+		/* Copy rate stats associated with this peer */
+		for (count = 0; count < peer_stats->num_rates; count++) {
+			rate_stats++;
+
+			qdf_mem_copy(results + next_res_offset,
+				     t_rate_stats + next_rate_offset,
+				     rate_stats_size);
+			next_res_offset += rate_stats_size;
+			next_rate_offset += sizeof(*rate_stats);
+		}
+		next_peer_offset += sizeof(*peer_stats);
+		peer_stats++;
+	}
+
+	/* call hdd callback with Link Layer Statistics
+	 * vdev_id/ifacId in link_stats_results will be
+	 * used to retrieve the correct HDD context
+	 */
+	mac->sme.link_layer_stats_cb(mac->hdd_handle,
+				     WMA_LINK_LAYER_STATS_RESULTS_RSP,
+				     link_stats_results,
+				     mac->sme.ll_stats_context);
+	qdf_mem_free(link_stats_results);
+
+	return 0;
+}
+
+/**
+ * wma_unified_radio_tx_mem_free() - Free radio tx power stats memory
+ * @handle: WMI handle
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+int wma_unified_radio_tx_mem_free(void *handle)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	tSirWifiRadioStat *rs_results;
+	uint32_t i = 0;
+
+	if (!wma_handle->link_stats_results)
+		return 0;
+
+	rs_results = (tSirWifiRadioStat *)
+				&wma_handle->link_stats_results->results[0];
+	for (i = 0; i < wma_handle->link_stats_results->num_radio; i++) {
+		if (rs_results->tx_time_per_power_level) {
+			qdf_mem_free(rs_results->tx_time_per_power_level);
+			rs_results->tx_time_per_power_level = NULL;
+		}
+
+		if (rs_results->channels) {
+			qdf_mem_free(rs_results->channels);
+			rs_results->channels = NULL;
+		}
+		rs_results++;
+	}
+
+	qdf_mem_free(wma_handle->link_stats_results);
+	wma_handle->link_stats_results = NULL;
+
+	return 0;
+}
+
+/**
+ * wma_unified_radio_tx_power_level_stats_event_handler() - tx power level stats
+ * @handle: WMI handle
+ * @cmd_param_info: command param info
+ * @len: Length of @cmd_param_info
+ *
+ * This is the WMI event handler function to receive radio stats tx
+ * power level stats.
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+static int wma_unified_radio_tx_power_level_stats_event_handler(void *handle,
+			u_int8_t *cmd_param_info, u_int32_t len)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID_param_tlvs *param_tlvs;
+	wmi_tx_power_level_stats_evt_fixed_param *fixed_param;
+	uint8_t *tx_power_level_values;
+	tSirLLStatsResults *link_stats_results;
+	tSirWifiRadioStat *rs_results;
+	uint32_t max_total_num_tx_power_levels = MAX_TPC_LEVELS * NUM_OF_BANDS *
+						MAX_SPATIAL_STREAM_ANY_V3;
+
+	tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac) {
+		WMA_LOGD("%s: NULL pMac ptr. Exiting", __func__);
+		return -EINVAL;
+	}
+
+	if (!mac->sme.link_layer_stats_cb) {
+		WMA_LOGD("%s: HDD callback is null", __func__);
+		return -EINVAL;
+	}
+
+	param_tlvs = (WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID_param_tlvs *)
+								cmd_param_info;
+	if (!param_tlvs) {
+		WMA_LOGA("%s: Invalid tx power level stats event", __func__);
+		return -EINVAL;
+	}
+
+	fixed_param = param_tlvs->fixed_param;
+	if (!fixed_param) {
+		WMA_LOGA("%s:Invalid param_tlvs for Radio tx_power level Stats",
+			 __func__);
+		return -EINVAL;
+	}
+
+	link_stats_results = wma_handle->link_stats_results;
+	if (!link_stats_results) {
+		WMA_LOGA("%s: link_stats_results is NULL", __func__);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("%s: tot_num_tx_pwr_lvls: %u num_tx_pwr_lvls: %u pwr_lvl_offset: %u radio_id: %u",
+			__func__, fixed_param->total_num_tx_power_levels,
+			 fixed_param->num_tx_power_levels,
+			 fixed_param->power_level_offset,
+			 fixed_param->radio_id);
+
+	if (fixed_param->num_tx_power_levels > ((WMI_SVC_MSG_MAX_SIZE -
+	    sizeof(*fixed_param)) / sizeof(uint32_t)) ||
+	    fixed_param->num_tx_power_levels >
+	    param_tlvs->num_tx_time_per_power_level) {
+		WMA_LOGE("%s: excess tx_power buffers:%d, num_tx_time_per_power_level:%d",
+			__func__, fixed_param->num_tx_power_levels,
+			param_tlvs->num_tx_time_per_power_level);
+		return -EINVAL;
+	}
+
+	if (fixed_param->radio_id >= link_stats_results->num_radio) {
+		WMA_LOGE("%s: Invalid radio_id %d num_radio %d",
+			 __func__, fixed_param->radio_id,
+			 link_stats_results->num_radio);
+		return -EINVAL;
+	}
+
+	if (fixed_param->total_num_tx_power_levels >
+	    max_total_num_tx_power_levels) {
+		WMA_LOGD("Invalid total_num_tx_power_levels %d",
+			 fixed_param->total_num_tx_power_levels);
+		return -EINVAL;
+	}
+
+	rs_results = (tSirWifiRadioStat *) &link_stats_results->results[0] +
+							 fixed_param->radio_id;
+	tx_power_level_values = (uint8_t *) param_tlvs->tx_time_per_power_level;
+
+	if (rs_results->total_num_tx_power_levels &&
+	    fixed_param->total_num_tx_power_levels >
+		rs_results->total_num_tx_power_levels) {
+		WMA_LOGE("%s: excess tx_power buffers:%d, total_num_tx_power_levels:%d",
+			 __func__, fixed_param->total_num_tx_power_levels,
+			 rs_results->total_num_tx_power_levels);
+		return -EINVAL;
+	}
+
+	rs_results->total_num_tx_power_levels =
+				fixed_param->total_num_tx_power_levels;
+	if (!rs_results->total_num_tx_power_levels) {
+		link_stats_results->nr_received++;
+		goto post_stats;
+	}
+
+	if ((fixed_param->power_level_offset >
+	    rs_results->total_num_tx_power_levels) ||
+	    (fixed_param->num_tx_power_levels >
+	    rs_results->total_num_tx_power_levels -
+	    fixed_param->power_level_offset)) {
+		WMA_LOGE("%s: Invalid offset %d total_num %d num %d",
+			 __func__, fixed_param->power_level_offset,
+			 rs_results->total_num_tx_power_levels,
+			 fixed_param->num_tx_power_levels);
+		return -EINVAL;
+	}
+
+	if (!rs_results->tx_time_per_power_level) {
+		rs_results->tx_time_per_power_level = qdf_mem_malloc(
+				sizeof(uint32_t) *
+				rs_results->total_num_tx_power_levels);
+		if (!rs_results->tx_time_per_power_level) {
+			/* In error case, atleast send the radio stats without
+			 * tx_power_level stats */
+			rs_results->total_num_tx_power_levels = 0;
+			link_stats_results->nr_received++;
+			goto post_stats;
+		}
+	}
+	qdf_mem_copy(&rs_results->tx_time_per_power_level[
+					fixed_param->power_level_offset],
+		tx_power_level_values,
+		sizeof(uint32_t) * fixed_param->num_tx_power_levels);
+	if (rs_results->total_num_tx_power_levels ==
+	   (fixed_param->num_tx_power_levels +
+					 fixed_param->power_level_offset)) {
+		link_stats_results->moreResultToFollow = 0;
+		link_stats_results->nr_received++;
+	}
+
+	WMA_LOGD("%s: moreResultToFollow: %u nr: %u nr_received: %u",
+			__func__, link_stats_results->moreResultToFollow,
+			link_stats_results->num_radio,
+			link_stats_results->nr_received);
+
+	/* If still data to receive, return from here */
+	if (link_stats_results->moreResultToFollow)
+		return 0;
+
+post_stats:
+	if (link_stats_results->num_radio != link_stats_results->nr_received) {
+		/* Not received all radio stats yet, don't post yet */
+		return 0;
+	}
+
+	/* call hdd callback with Link Layer Statistics
+	 * vdev_id/ifacId in link_stats_results will be
+	 * used to retrieve the correct HDD context
+	 */
+	mac->sme.link_layer_stats_cb(mac->hdd_handle,
+		WMA_LINK_LAYER_STATS_RESULTS_RSP,
+		link_stats_results,
+		mac->sme.ll_stats_context);
+	wma_unified_radio_tx_mem_free(handle);
+
+	return 0;
+}
+
+/**
+ * wma_unified_link_radio_stats_event_handler() - radio link stats event handler
+ * @handle:          wma handle
+ * @cmd_param_info:  data received with event from fw
+ * @len:             length of data
+ *
+ * Return: 0 for success or error code
+ */
+static int wma_unified_link_radio_stats_event_handler(void *handle,
+						      uint8_t *cmd_param_info,
+						      uint32_t len)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	WMI_RADIO_LINK_STATS_EVENTID_param_tlvs *param_tlvs;
+	wmi_radio_link_stats_event_fixed_param *fixed_param;
+	wmi_radio_link_stats *radio_stats;
+	wmi_channel_stats *channel_stats;
+	tSirLLStatsResults *link_stats_results;
+	uint8_t *results, *t_radio_stats, *t_channel_stats;
+	uint32_t next_chan_offset, count;
+	size_t radio_stats_size, chan_stats_size;
+	size_t link_stats_results_size;
+	tSirWifiRadioStat *rs_results;
+	tSirWifiChannelStats *chn_results;
+
+	tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac) {
+		WMA_LOGD("%s: NULL mac ptr. Exiting", __func__);
+		return -EINVAL;
+	}
+
+	if (!mac->sme.link_layer_stats_cb) {
+		WMA_LOGD("%s: HDD callback is null", __func__);
+		return -EINVAL;
+	}
+
+	param_tlvs = (WMI_RADIO_LINK_STATS_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_tlvs) {
+		WMA_LOGA("%s: Invalid stats event", __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * cmd_param_info contains
+	 * wmi_radio_link_stats_event_fixed_param fixed_param;
+	 * size of(struct wmi_radio_link_stats);
+	 * num_channels * size of(struct wmi_channel_stats)
+	 */
+	fixed_param = param_tlvs->fixed_param;
+	radio_stats = param_tlvs->radio_stats;
+	channel_stats = param_tlvs->channel_stats;
+
+	if (!fixed_param || !radio_stats ||
+	    (radio_stats->num_channels && !channel_stats)) {
+		WMA_LOGA("%s: Invalid param_tlvs for Radio Stats", __func__);
+		return -EINVAL;
+	}
+	if (radio_stats->num_channels >
+		(NUM_24GHZ_CHANNELS + NUM_5GHZ_CHANNELS) ||
+		radio_stats->num_channels > param_tlvs->num_channel_stats) {
+		WMA_LOGE("%s: Too many channels %d",
+			__func__, radio_stats->num_channels);
+		return -EINVAL;
+	}
+
+	radio_stats_size = sizeof(tSirWifiRadioStat);
+	chan_stats_size = sizeof(tSirWifiChannelStats);
+	if (fixed_param->num_radio >
+		(UINT_MAX - sizeof(*link_stats_results))/radio_stats_size) {
+		WMA_LOGE("excess num_radio %d is leading to int overflow",
+			fixed_param->num_radio);
+		return -EINVAL;
+	}
+	link_stats_results_size = sizeof(*link_stats_results) +
+				  fixed_param->num_radio * radio_stats_size;
+
+	if (radio_stats->radio_id >= fixed_param->num_radio) {
+		WMA_LOGE("%s, invalid radio id:%d, num radio:%d",
+			__func__, radio_stats->radio_id,
+			fixed_param->num_radio);
+		return -EINVAL;
+	}
+
+	if (!wma_handle->link_stats_results) {
+		wma_handle->link_stats_results = qdf_mem_malloc(
+						link_stats_results_size);
+		if (!wma_handle->link_stats_results)
+			return -ENOMEM;
+	}
+	link_stats_results = wma_handle->link_stats_results;
+	if (link_stats_results->num_radio == 0) {
+		link_stats_results->num_radio = fixed_param->num_radio;
+	} else if (link_stats_results->num_radio < fixed_param->num_radio) {
+		/*
+		 * The link stats results size allocated based on num_radio of
+		 * first event must be same as following events. Otherwise these
+		 * events may be spoofed. Drop all of them and report error.
+		 */
+		WMA_LOGE("Invalid following WMI_RADIO_LINK_STATS_EVENTID. Discarding this set");
+		wma_unified_radio_tx_mem_free(handle);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("Radio stats Fixed Param:");
+	WMA_LOGD("req_id: %u num_radio: %u more_radio_events: %u",
+		 fixed_param->request_id, fixed_param->num_radio,
+		 fixed_param->more_radio_events);
+
+	WMA_LOGD("Radio Info: radio_id: %u on_time: %u tx_time: %u rx_time: %u on_time_scan: %u",
+		radio_stats->radio_id, radio_stats->on_time,
+		radio_stats->tx_time, radio_stats->rx_time,
+		radio_stats->on_time_scan);
+	WMA_LOGD("on_time_nbd: %u on_time_gscan: %u on_time_roam_scan: %u",
+		radio_stats->on_time_nbd,
+		radio_stats->on_time_gscan, radio_stats->on_time_roam_scan);
+	WMA_LOGD("on_time_pno_scan: %u on_time_hs20: %u num_channels: %u",
+		radio_stats->on_time_pno_scan, radio_stats->on_time_hs20,
+		radio_stats->num_channels);
+	WMA_LOGD("on_time_host_scan: %u, on_time_lpi_scan: %u",
+		radio_stats->on_time_host_scan, radio_stats->on_time_lpi_scan);
+
+	link_stats_results->paramId = WMI_LINK_STATS_RADIO;
+	link_stats_results->rspId = fixed_param->request_id;
+	link_stats_results->ifaceId = 0;
+	link_stats_results->peer_event_number = 0;
+
+	/*
+	 * Backward compatibility:
+	 * There are firmware(s) which will send Radio stats only with
+	 * more_radio_events set to 0 and firmware which sends Radio stats
+	 * followed by tx_power level stats with more_radio_events set to 1.
+	 * if more_radio_events is set to 1, buffer the radio stats and
+	 * wait for tx_power_level stats.
+	 */
+	link_stats_results->moreResultToFollow = fixed_param->more_radio_events;
+
+	results = (uint8_t *) link_stats_results->results;
+	t_radio_stats = (uint8_t *) radio_stats;
+	t_channel_stats = (uint8_t *) channel_stats;
+
+	rs_results = (tSirWifiRadioStat *) &results[0] + radio_stats->radio_id;
+	rs_results->radio = radio_stats->radio_id;
+	rs_results->onTime = radio_stats->on_time;
+	rs_results->txTime = radio_stats->tx_time;
+	rs_results->rxTime = radio_stats->rx_time;
+	rs_results->onTimeScan = radio_stats->on_time_scan;
+	rs_results->onTimeNbd = radio_stats->on_time_nbd;
+	rs_results->onTimeGscan = radio_stats->on_time_gscan;
+	rs_results->onTimeRoamScan = radio_stats->on_time_roam_scan;
+	rs_results->onTimePnoScan = radio_stats->on_time_pno_scan;
+	rs_results->onTimeHs20 = radio_stats->on_time_hs20;
+	rs_results->total_num_tx_power_levels = 0;
+	if (rs_results->tx_time_per_power_level) {
+		qdf_mem_free(rs_results->tx_time_per_power_level);
+		rs_results->tx_time_per_power_level = NULL;
+	}
+	if (rs_results->channels) {
+		qdf_mem_free(rs_results->channels);
+		rs_results->channels = NULL;
+	}
+	rs_results->numChannels = radio_stats->num_channels;
+	rs_results->on_time_host_scan = radio_stats->on_time_host_scan;
+	rs_results->on_time_lpi_scan = radio_stats->on_time_lpi_scan;
+	if (rs_results->numChannels) {
+		rs_results->channels = qdf_mem_malloc(
+					radio_stats->num_channels *
+					chan_stats_size);
+		if (!rs_results->channels) {
+			wma_unified_radio_tx_mem_free(handle);
+			return -ENOMEM;
+		}
+
+		chn_results = (tSirWifiChannelStats *) &rs_results->channels[0];
+		next_chan_offset = WMI_TLV_HDR_SIZE;
+		WMA_LOGD("Channel Stats Info");
+		for (count = 0; count < radio_stats->num_channels; count++) {
+			WMA_LOGD("channel_width %u center_freq %u center_freq0 %u",
+				 channel_stats->channel_width,
+				 channel_stats->center_freq,
+				 channel_stats->center_freq0);
+			WMA_LOGD("center_freq1 %u radio_awake_time %u cca_busy_time %u",
+				 channel_stats->center_freq1,
+				 channel_stats->radio_awake_time,
+				 channel_stats->cca_busy_time);
+			channel_stats++;
+
+			qdf_mem_copy(chn_results,
+				     t_channel_stats + next_chan_offset,
+				     chan_stats_size);
+			chn_results++;
+			next_chan_offset += sizeof(*channel_stats);
+		}
+	}
+
+	if (link_stats_results->moreResultToFollow) {
+		/* More results coming, don't post yet */
+		return 0;
+	}
+	link_stats_results->nr_received++;
+
+	if (link_stats_results->num_radio != link_stats_results->nr_received) {
+		/* Not received all radio stats yet, don't post yet */
+		return 0;
+	}
+
+	mac->sme.link_layer_stats_cb(mac->hdd_handle,
+				     WMA_LINK_LAYER_STATS_RESULTS_RSP,
+				     link_stats_results,
+				     mac->sme.ll_stats_context);
+	wma_unified_radio_tx_mem_free(handle);
+
+	return 0;
+}
+
+#ifdef WLAN_PEER_PS_NOTIFICATION
+/**
+ * wma_peer_ps_evt_handler() - handler for PEER power state change.
+ * @handle: wma handle
+ * @event: FW event
+ * @len: length of FW event
+ *
+ * Once peer STA power state changes, an event will be indicated by
+ * FW. This function send a link layer state change msg to HDD. HDD
+ * link layer callback will converts the event to NL msg.
+ *
+ * Return: 0 Success. Others fail.
+ */
+static int wma_peer_ps_evt_handler(void *handle, u_int8_t *event,
+				   u_int32_t len)
+{
+	WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf;
+	wmi_peer_sta_ps_statechange_event_fixed_param *fixed_param;
+	tSirWifiPeerStat *peer_stat;
+	tSirWifiPeerInfo *peer_info;
+	tSirLLStatsResults *link_stats_results;
+	tSirMacAddr mac_address;
+	uint32_t result_len;
+	cds_msg_t sme_msg = { 0 };
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+	tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac) {
+		WMA_LOGD("%s: NULL mac ptr. Exiting", __func__);
+		return -EINVAL;
+	}
+
+	if (!mac->sme.link_layer_stats_ext_cb) {
+		WMA_LOGD("%s: HDD callback is null", __func__);
+		return -EINVAL;
+	}
+
+	WMA_LOGD("%s: Posting Peer Stats PS event to HDD", __func__);
+
+	param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)event;
+	fixed_param = param_buf->fixed_param;
+
+	result_len = sizeof(tSirLLStatsResults) +
+			sizeof(tSirWifiPeerStat) +
+			sizeof(tSirWifiPeerInfo);
+	link_stats_results = qdf_mem_malloc(result_len);
+	if (!link_stats_results)
+		return -EINVAL;
+
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_param->peer_macaddr, &mac_address[0]);
+	WMA_LOGD("Peer power state change event from FW");
+	WMA_LOGD("Fixed Param:");
+	WMA_LOGD("MAC address: %2x:%2x:%2x:%2x:%2x:%2x, Power state: %d",
+		 mac_address[0], mac_address[1], mac_address[2],
+		 mac_address[3], mac_address[4], mac_address[5],
+		 fixed_param->peer_ps_state);
+
+	link_stats_results->paramId            = WMI_LL_STATS_EXT_PS_CHG;
+	link_stats_results->num_peers          = 1;
+	link_stats_results->peer_event_number  = 1;
+	link_stats_results->moreResultToFollow = 0;
+
+	peer_stat = (tSirWifiPeerStat *)link_stats_results->results;
+	peer_stat->numPeers = 1;
+	peer_info = (tSirWifiPeerInfo *)peer_stat->peerInfo;
+	qdf_mem_copy(&peer_info->peerMacAddress,
+		     &mac_address,
+		     sizeof(tSirMacAddr));
+	peer_info->power_saving = fixed_param->peer_ps_state;
+
+	sme_msg.type = eWMI_SME_LL_STATS_IND;
+	sme_msg.bodyptr = link_stats_results;
+	sme_msg.bodyval = 0;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("%s: Fail to post ps change ind msg", __func__);
+		qdf_mem_free(link_stats_results);
+	}
+
+	return 0;
+}
+#else
+/**
+ * wma_peer_ps_evt_handler() - handler for PEER power state change.
+ * @handle: wma handle
+ * @event: FW event
+ * @len: length of FW event
+ *
+ * Once peer STA power state changes, an event will be indicated by
+ * FW. This function send a link layer state change msg to HDD. HDD
+ * link layer callback will converts the event to NL msg.
+ *
+ * Return: 0 Success. Others fail.
+ */
+static inline int wma_peer_ps_evt_handler(void *handle, u_int8_t *event,
+					  u_int32_t len)
+{
+	return 0;
+}
+#endif
+
+/**
+ * wma_register_ll_stats_event_handler() - register link layer stats related
+ *                                         event handler
+ * @wma_handle: wma handle
+ *
+ * Return: none
+ */
+void wma_register_ll_stats_event_handler(tp_wma_handle wma_handle)
+{
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: wma_handle is NULL", __func__);
+		return;
+	}
+
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_iface_link_stats_event_id,
+				wma_unified_link_iface_stats_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_peer_link_stats_event_id,
+				wma_unified_link_peer_stats_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+				wmi_radio_link_stats_link,
+				wma_unified_link_radio_stats_event_handler,
+				WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+			wmi_radio_tx_power_level_stats_event_id,
+			wma_unified_radio_tx_power_level_stats_event_handler,
+			WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_peer_sta_ps_statechg_event_id,
+					   wma_peer_ps_evt_handler,
+					   WMA_RX_SERIALIZER_CTX);
+	wmi_unified_register_event_handler(wma_handle->wmi_handle,
+					   wmi_report_stats_event_id,
+					   wma_ll_stats_evt_handler,
+					   WMA_RX_SERIALIZER_CTX);
+
+}
+
+
+/**
+ * wma_process_ll_stats_clear_req() - clear link layer stats
+ * @wma: wma handle
+ * @clearReq: ll stats clear request command params
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_process_ll_stats_clear_req(tp_wma_handle wma,
+				 const tpSirLLStatsClearReq clearReq)
+{
+	struct ll_stats_clear_params cmd = {0};
+	int ret;
+
+	if (!clearReq || !wma) {
+		WMA_LOGE("%s: input pointer is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!wma->interfaces[clearReq->staId].handle) {
+		WMA_LOGE("%s: vdev_id %d handle is NULL",
+			 __func__, clearReq->staId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cmd.stop_req = clearReq->stopReq;
+	cmd.sta_id = clearReq->staId;
+	cmd.stats_clear_mask = clearReq->statsClearReqMask;
+
+	ret = wmi_unified_process_ll_stats_clear_cmd(wma->wmi_handle, &cmd,
+				   wma->interfaces[clearReq->staId].addr);
+	if (ret) {
+		WMA_LOGE("%s: Failed to send clear link stats req", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_ll_stats_set_req() - link layer stats set request
+ * @wma:       wma handle
+ * @setReq:  ll stats set request command params
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_process_ll_stats_set_req(tp_wma_handle wma,
+				 const tpSirLLStatsSetReq setReq)
+{
+	struct ll_stats_set_params cmd = {0};
+	int ret;
+
+	if (!setReq || !wma) {
+		WMA_LOGE("%s: input pointer is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cmd.mpdu_size_threshold = setReq->mpduSizeThreshold;
+	cmd.aggressive_statistics_gathering =
+		setReq->aggressiveStatisticsGathering;
+
+	ret = wmi_unified_process_ll_stats_set_cmd(wma->wmi_handle,
+					 &cmd);
+	if (ret) {
+		WMA_LOGE("%s: Failed to send set link stats request", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_process_ll_stats_get_req() - link layer stats get request
+ * @wma:wma handle
+ * @getReq:ll stats get request command params
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_process_ll_stats_get_req(tp_wma_handle wma,
+				 const tpSirLLStatsGetReq getReq)
+{
+	struct ll_stats_get_params cmd = {0};
+	int ret;
+
+	if (!getReq || !wma) {
+		WMA_LOGE("%s: input pointer is NULL", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!wma_is_vdev_valid(getReq->staId)) {
+		WMA_LOGE("%s: vdev:%d not created yet", __func__,
+			 getReq->staId);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	cmd.req_id = getReq->reqId;
+	cmd.param_id_mask = getReq->paramIdMask;
+	cmd.sta_id = getReq->staId;
+
+	ret = wmi_unified_process_ll_stats_get_cmd(wma->wmi_handle, &cmd,
+				   wma->interfaces[getReq->staId].addr);
+	if (ret) {
+		WMA_LOGE("%s: Failed to send get link stats request", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_unified_link_iface_stats_event_handler() - link iface stats event handler
+ * @wma:wma handle
+ * @cmd_param_info: data from event
+ * @len: length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_unified_link_iface_stats_event_handler(void *handle,
+					       uint8_t *cmd_param_info,
+					       uint32_t len)
+{
+	WMI_IFACE_LINK_STATS_EVENTID_param_tlvs *param_tlvs;
+	wmi_iface_link_stats_event_fixed_param *fixed_param;
+	wmi_iface_link_stats *link_stats, *iface_link_stats;
+	wmi_wmm_ac_stats *ac_stats, *iface_ac_stats;
+	wmi_iface_offload_stats *offload_stats, *iface_offload_stats;
+	tSirLLStatsResults *link_stats_results;
+	tSirWifiIfaceStat *iface_stat;
+	uint32_t count;
+	size_t link_stats_size, ac_stats_size, iface_info_size;
+	size_t link_stats_results_size, offload_stats_size;
+	size_t total_ac_size, total_offload_size;
+
+	tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	if (!mac) {
+		WMA_LOGD("%s: NULL mac ptr. Exiting", __func__);
+		return -EINVAL;
+	}
+
+	if (!mac->sme.link_layer_stats_cb) {
+		WMA_LOGD("%s: HDD callback is null", __func__);
+		return -EINVAL;
+	}
+
+	param_tlvs = (WMI_IFACE_LINK_STATS_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_tlvs) {
+		WMA_LOGA("%s: Invalid stats event", __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * cmd_param_info contains
+	 * wmi_iface_link_stats_event_fixed_param fixed_param;
+	 * wmi_iface_link_stats iface_link_stats;
+	 * iface_link_stats->num_ac * size of(struct wmi_wmm_ac_stats)
+	 * fixed_param->num_offload_stats * size of(wmi_iface_offload_stats);
+	 */
+	fixed_param = param_tlvs->fixed_param;
+	link_stats = param_tlvs->iface_link_stats;
+	ac_stats = param_tlvs->ac;
+	offload_stats = param_tlvs->iface_offload_stats;
+
+	if (!fixed_param || !link_stats || (link_stats->num_ac && !ac_stats) ||
+	    (fixed_param->num_offload_stats && !offload_stats)) {
+		WMA_LOGA("%s: Invalid param_tlvs for Iface Stats", __func__);
+		return -EINVAL;
+	}
+	if (link_stats->num_ac > WIFI_AC_MAX || link_stats->num_ac >
+	    param_tlvs->num_ac) {
+		WMA_LOGE("%s: Excess data received from firmware num_ac %d, param_tlvs->num_ac %d",
+			 __func__, link_stats->num_ac, param_tlvs->num_ac);
+		return -EINVAL;
+	}
+	if (fixed_param->num_offload_stats > WMI_OFFLOAD_STATS_TYPE_MAX ||
+	    fixed_param->num_offload_stats >
+	    param_tlvs->num_iface_offload_stats) {
+		WMA_LOGE("%s: Excess num offload stats recvd from fw: %d, um_iface_offload_stats: %d",
+			__func__, fixed_param->num_offload_stats,
+			param_tlvs->num_iface_offload_stats);
+		return -EINVAL;
+	}
+
+	link_stats_size = sizeof(tSirWifiIfaceStat);
+	iface_info_size = sizeof(tSirWifiInterfaceInfo);
+
+	ac_stats_size = sizeof(wmi_wmm_ac_stats);
+	offload_stats_size = sizeof(wmi_iface_offload_stats);
+
+	total_ac_size = ac_stats_size * WIFI_AC_MAX;
+	total_offload_size = offload_stats_size * WMI_OFFLOAD_STATS_TYPE_MAX +
+			      member_size(tSirWifiIfaceStat, num_offload_stats);
+
+	link_stats_results_size = sizeof(*link_stats_results) +	link_stats_size;
+
+	link_stats_results = qdf_mem_malloc(link_stats_results_size);
+	if (!link_stats_results)
+		return -ENOMEM;
+
+	qdf_mem_zero(link_stats_results, link_stats_results_size);
+
+	link_stats_results->paramId = WMI_LINK_STATS_IFACE;
+	link_stats_results->rspId = fixed_param->request_id;
+	link_stats_results->ifaceId = fixed_param->vdev_id;
+	link_stats_results->num_peers = link_stats->num_peers;
+	link_stats_results->peer_event_number = 0;
+	link_stats_results->moreResultToFollow = 0;
+
+	/* results is copied to tSirWifiIfaceStat in upper layer
+	 *   tSirWifiIfaceStat
+	 *    - tSirWifiInterfaceInfo (all fields except roaming is
+	 *                             filled by host in the upper layer)
+	 *    - various members of tSirWifiIfaceStat (from wmi_iface_link_stats)
+	 *    - ACs information (from wmi_wmm_ac_stats)
+	 *    - num_offload_stats (from fixed param)
+	 *    - offload stats (from wmi_iface_offload_stats)
+	 */
+
+	iface_stat = (tSirWifiIfaceStat *)link_stats_results->results;
+
+	iface_link_stats = &iface_stat->link_stats;
+	*iface_link_stats = *link_stats;
+
+	/* Copy roaming state */
+	iface_stat->info.roaming = link_stats->roam_state;
+
+	iface_ac_stats = &iface_stat->ac_stats[0];
+	for (count = 0; count < link_stats->num_ac; count++) {
+		*iface_ac_stats = *ac_stats;
+		ac_stats++;
+		iface_ac_stats++;
+	}
+
+	/* Copy wmi_iface_offload_stats to wifi_iface_offload_stat */
+	iface_stat->num_offload_stats = fixed_param->num_offload_stats;
+	iface_offload_stats = &iface_stat->offload_stats[0];
+	for (count = 0; count < fixed_param->num_offload_stats; count++) {
+		*iface_offload_stats = *offload_stats;
+		offload_stats++;
+		iface_offload_stats++;
+	}
+
+	/* call hdd callback with Link Layer Statistics
+	 * vdev_id/ifacId in link_stats_results will be
+	 * used to retrieve the correct HDD context
+	 */
+	mac->sme.link_layer_stats_cb(mac->hdd_handle,
+				     WMA_LINK_LAYER_STATS_RESULTS_RSP,
+				     link_stats_results,
+				     mac->sme.ll_stats_context);
+	qdf_mem_free(link_stats_results);
+
+	return 0;
+}
+
+/**
+ * wma_config_stats_ext_threshold - set threthold for MAC counters
+ * @wma: wma handler
+ * @threshold: threhold for MAC counters
+ *
+ * For each MAC layer counter, FW holds two copies. One is the current value.
+ * The other is the last report. Once a current counter's increment is larger
+ * than the threshold, FW will indicate that counter to host even if the
+ * monitoring timer does not expire.
+ *
+ * Return: None
+ */
+void wma_config_stats_ext_threshold(tp_wma_handle wma,
+				    struct sir_ll_ext_stats_threshold *thresh)
+{
+	uint32_t len, tag, hdr_len;
+	uint8_t *buf_ptr;
+	wmi_buf_t buf;
+	wmi_pdev_set_stats_threshold_cmd_fixed_param *cmd;
+	wmi_chan_cca_stats_thresh *cca;
+	wmi_peer_signal_stats_thresh *signal;
+	wmi_tx_stats_thresh *tx;
+	wmi_rx_stats_thresh *rx;
+
+	if (!thresh) {
+		WMA_LOGE(FL("Invalid threshold input."));
+		return;
+	}
+
+	len = sizeof(wmi_pdev_set_stats_threshold_cmd_fixed_param) +
+	      sizeof(wmi_chan_cca_stats_thresh) +
+	      sizeof(wmi_peer_signal_stats_thresh) +
+	      sizeof(wmi_tx_stats_thresh) +
+	      sizeof(wmi_rx_stats_thresh) +
+	      5 * WMI_TLV_HDR_SIZE;
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf)
+		return;
+
+	buf_ptr = (u_int8_t *)wmi_buf_data(buf);
+	tag = WMITLV_TAG_STRUC_wmi_pdev_set_stats_threshold_cmd_fixed_param;
+	hdr_len = WMITLV_GET_STRUCT_TLVLEN(
+			wmi_pdev_set_stats_threshold_cmd_fixed_param);
+	WMA_LOGD(FL("Setting fixed parameters. tag=%d, len=%d"), tag, hdr_len);
+	cmd = (wmi_pdev_set_stats_threshold_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header, tag, hdr_len);
+	cmd->enable_thresh = thresh->enable;
+	cmd->use_thresh_bitmap = thresh->enable_bitmap;
+	cmd->gbl_thresh = thresh->global_threshold;
+	cmd->cca_thresh_enable_bitmap = thresh->cca_bitmap;
+	cmd->signal_thresh_enable_bitmap = thresh->signal_bitmap;
+	cmd->tx_thresh_enable_bitmap = thresh->tx_bitmap;
+	cmd->rx_thresh_enable_bitmap = thresh->rx_bitmap;
+	len = sizeof(wmi_pdev_set_stats_threshold_cmd_fixed_param);
+
+	tag = WMITLV_TAG_STRUC_wmi_chan_cca_stats_thresh,
+	hdr_len = WMITLV_GET_STRUCT_TLVLEN(wmi_chan_cca_stats_thresh);
+	cca = (wmi_chan_cca_stats_thresh *)(buf_ptr + len);
+	WMITLV_SET_HDR(&cca->tlv_header, tag, hdr_len);
+	WMA_LOGD(FL("Setting cca parameters. tag=%d, len=%d"), tag, hdr_len);
+	cca->idle_time = thresh->cca.idle_time;
+	cca->tx_time = thresh->cca.tx_time;
+	cca->rx_in_bss_time = thresh->cca.rx_in_bss_time;
+	cca->rx_out_bss_time = thresh->cca.rx_out_bss_time;
+	cca->rx_busy_time = thresh->cca.rx_busy_time;
+	cca->rx_in_bad_cond_time = thresh->cca.rx_in_bad_cond_time;
+	cca->tx_in_bad_cond_time = thresh->cca.tx_in_bad_cond_time;
+	cca->wlan_not_avail_time = thresh->cca.wlan_not_avail_time;
+	WMA_LOGD(FL("idle time=%d, tx_time=%d, in_bss=%d, out_bss=%d"),
+		 cca->idle_time, cca->tx_time,
+		 cca->rx_in_bss_time, cca->rx_out_bss_time);
+	WMA_LOGD(FL("rx_busy=%d, rx_bad=%d, tx_bad=%d, not_avail=%d"),
+		 cca->rx_busy_time, cca->rx_in_bad_cond_time,
+		 cca->tx_in_bad_cond_time, cca->wlan_not_avail_time);
+	len += sizeof(wmi_chan_cca_stats_thresh);
+
+	signal = (wmi_peer_signal_stats_thresh *)(buf_ptr + len);
+	tag = WMITLV_TAG_STRUC_wmi_peer_signal_stats_thresh;
+	hdr_len = WMITLV_GET_STRUCT_TLVLEN(wmi_peer_signal_stats_thresh);
+	WMA_LOGD(FL("Setting signal parameters. tag=%d, len=%d"), tag, hdr_len);
+	WMITLV_SET_HDR(&signal->tlv_header, tag, hdr_len);
+	signal->per_chain_snr = thresh->signal.snr;
+	signal->per_chain_nf = thresh->signal.nf;
+	WMA_LOGD(FL("snr=%d, nf=%d"), signal->per_chain_snr,
+		 signal->per_chain_nf);
+	len += sizeof(wmi_peer_signal_stats_thresh);
+
+	tx = (wmi_tx_stats_thresh *)(buf_ptr + len);
+	tag = WMITLV_TAG_STRUC_wmi_tx_stats_thresh;
+	hdr_len = WMITLV_GET_STRUCT_TLVLEN(wmi_tx_stats_thresh);
+	WMA_LOGD(FL("Setting TX parameters. tag=%d, len=%d"), tag, len);
+	WMITLV_SET_HDR(&tx->tlv_header, tag, hdr_len);
+	tx->tx_msdu_cnt = thresh->tx.msdu;
+	tx->tx_mpdu_cnt = thresh->tx.mpdu;
+	tx->tx_ppdu_cnt = thresh->tx.ppdu;
+	tx->tx_bytes = thresh->tx.bytes;
+	tx->tx_msdu_drop_cnt = thresh->tx.msdu_drop;
+	tx->tx_drop_bytes = thresh->tx.byte_drop;
+	tx->tx_mpdu_retry_cnt = thresh->tx.mpdu_retry;
+	tx->tx_mpdu_fail_cnt = thresh->tx.mpdu_fail;
+	tx->tx_ppdu_fail_cnt = thresh->tx.ppdu_fail;
+	tx->tx_mpdu_aggr = thresh->tx.aggregation;
+	tx->tx_succ_mcs = thresh->tx.succ_mcs;
+	tx->tx_fail_mcs = thresh->tx.fail_mcs;
+	tx->tx_ppdu_delay = thresh->tx.delay;
+	WMA_LOGD(FL("msdu=%d, mpdu=%d, ppdu=%d, bytes=%d, msdu_drop=%d"),
+		 tx->tx_msdu_cnt, tx->tx_mpdu_cnt, tx->tx_ppdu_cnt,
+		 tx->tx_bytes, tx->tx_msdu_drop_cnt);
+	WMA_LOGD(FL("byte_drop=%d, mpdu_retry=%d, mpdu_fail=%d, ppdu_fail=%d"),
+		 tx->tx_drop_bytes, tx->tx_mpdu_retry_cnt,
+		 tx->tx_mpdu_fail_cnt, tx->tx_ppdu_fail_cnt);
+	WMA_LOGD(FL("aggr=%d, succ_mcs=%d, fail_mcs=%d, delay=%d"),
+		 tx->tx_mpdu_aggr, tx->tx_succ_mcs, tx->tx_fail_mcs,
+		 tx->tx_ppdu_delay);
+	len += sizeof(wmi_tx_stats_thresh);
+
+	rx = (wmi_rx_stats_thresh *)(buf_ptr + len);
+	tag = WMITLV_TAG_STRUC_wmi_rx_stats_thresh,
+	hdr_len = WMITLV_GET_STRUCT_TLVLEN(wmi_rx_stats_thresh);
+	WMITLV_SET_HDR(&rx->tlv_header, tag, hdr_len);
+	WMA_LOGD(FL("Setting RX parameters. tag=%d, len=%d"), tag, hdr_len);
+	rx->mac_rx_mpdu_cnt = thresh->rx.mpdu;
+	rx->mac_rx_bytes = thresh->rx.bytes;
+	rx->phy_rx_ppdu_cnt = thresh->rx.ppdu;
+	rx->phy_rx_bytes = thresh->rx.ppdu_bytes;
+	rx->rx_disorder_cnt = thresh->rx.disorder;
+	rx->rx_mpdu_retry_cnt = thresh->rx.mpdu_retry;
+	rx->rx_mpdu_dup_cnt = thresh->rx.mpdu_dup;
+	rx->rx_mpdu_discard_cnt = thresh->rx.mpdu_discard;
+	rx->rx_mpdu_aggr = thresh->rx.aggregation;
+	rx->rx_mcs = thresh->rx.mcs;
+	rx->sta_ps_inds = thresh->rx.ps_inds;
+	rx->sta_ps_durs = thresh->rx.ps_durs;
+	rx->rx_probe_reqs = thresh->rx.probe_reqs;
+	rx->rx_oth_mgmts = thresh->rx.other_mgmt;
+	WMA_LOGD(FL("rx_mpdu=%d, rx_bytes=%d, rx_ppdu=%d, rx_pbytes=%d"),
+		 rx->mac_rx_mpdu_cnt, rx->mac_rx_bytes,
+		 rx->phy_rx_ppdu_cnt, rx->phy_rx_bytes);
+	WMA_LOGD(FL("disorder=%d, rx_dup=%d, rx_aggr=%d, rx_mcs=%d"),
+		 rx->rx_disorder_cnt, rx->rx_mpdu_dup_cnt,
+		 rx->rx_mpdu_aggr, rx->rx_mcs);
+	WMA_LOGD(FL("rx_ind=%d, rx_dur=%d, rx_probe=%d, rx_mgmt=%d"),
+		 rx->sta_ps_inds, rx->sta_ps_durs,
+		 rx->rx_probe_reqs, rx->rx_oth_mgmts);
+	len += sizeof(wmi_rx_stats_thresh);
+
+	WMA_LOGA("WMA --> WMI_PDEV_SET_STATS_THRESHOLD_CMDID(0x%x), length=%d",
+		 WMI_PDEV_SET_STATS_THRESHOLD_CMDID, len);
+	if (EOK != wmi_unified_cmd_send(wma->wmi_handle,
+					buf, len,
+					WMI_PDEV_SET_STATS_THRESHOLD_CMDID))
+		wmi_buf_free(buf);
+}
+
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * wma_update_pdev_stats() - update pdev stats
+ * @wma: wma handle
+ * @pdev_stats: pdev stats
+ *
+ * Return: none
+ */
+static void wma_update_pdev_stats(tp_wma_handle wma,
+				  wmi_pdev_stats *pdev_stats)
+{
+	tAniGetPEStatsRsp *stats_rsp_params;
+	uint32_t temp_mask;
+	uint8_t *stats_buf;
+	tCsrGlobalClassAStatsInfo *classa_stats = NULL;
+	struct wma_txrx_node *node;
+	uint8_t i;
+
+	for (i = 0; i < wma->max_bssid; i++) {
+		node = &wma->interfaces[i];
+		stats_rsp_params = node->stats_rsp;
+		if (stats_rsp_params) {
+			node->fw_stats_set |= FW_PDEV_STATS_SET;
+			WMA_LOGD("<---FW PDEV STATS received for vdevId:%d", i);
+			stats_buf = (uint8_t *) (stats_rsp_params + 1);
+			temp_mask = stats_rsp_params->statsMask;
+			if (temp_mask & (1 << eCsrSummaryStats))
+				stats_buf += sizeof(tCsrSummaryStatsInfo);
+
+			if (temp_mask & (1 << eCsrGlobalClassAStats)) {
+				classa_stats =
+					(tCsrGlobalClassAStatsInfo *) stats_buf;
+				classa_stats->max_pwr = pdev_stats->chan_tx_pwr;
+			}
+		}
+	}
+}
+
+/**
+ * wma_vdev_stats_lost_link_helper() - helper function to extract
+ * lost link information from vdev statistics event while deleting BSS.
+ * @wma: WMA handle
+ * @vdev_stats: statistics information from firmware
+ *
+ * This is for informing HDD to collect lost link information while
+ * disconnection. Following conditions to check
+ * 1. vdev is up
+ * 2. bssid is zero. When handling DELETE_BSS request message, it sets bssid to
+ * zero, hence add the check here to indicate the event comes during deleting
+ * BSS
+ * 3. DELETE_BSS is the request message queued. Put this condition check on the
+ * last one as it consumes more resource searching entries in the  list
+ *
+ * Return: none
+ */
+static void wma_vdev_stats_lost_link_helper(tp_wma_handle wma,
+					    wmi_vdev_stats *vdev_stats)
+{
+	struct wma_txrx_node *node;
+	int32_t rssi;
+	struct wma_target_req *req_msg;
+	static const uint8_t zero_mac[QDF_MAC_ADDR_SIZE] = {0};
+	int32_t bcn_snr, dat_snr;
+
+	if (vdev_stats->vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: Invalid vdev_id %hu",
+			__func__, vdev_stats->vdev_id);
+		return;
+	}
+
+	node = &wma->interfaces[vdev_stats->vdev_id];
+	if (wma_is_vdev_up(vdev_stats->vdev_id) &&
+	    !qdf_mem_cmp(node->bssid, zero_mac, QDF_MAC_ADDR_SIZE)) {
+		req_msg = wma_peek_vdev_req(wma, vdev_stats->vdev_id,
+					    WMA_TARGET_REQ_TYPE_VDEV_STOP);
+		if ((NULL == req_msg) ||
+		    (WMA_DELETE_BSS_REQ != req_msg->msg_type)) {
+			WMA_LOGD(FL("cannot find DELETE_BSS request message"));
+			return;
+		}
+		bcn_snr = vdev_stats->vdev_snr.bcn_snr;
+		dat_snr = vdev_stats->vdev_snr.dat_snr;
+		WMA_LOGD(FL("get vdev id %d, beancon snr %d, data snr %d"),
+			vdev_stats->vdev_id, bcn_snr, dat_snr);
+
+		if (WMA_TGT_IS_VALID_SNR(bcn_snr))
+			rssi = bcn_snr;
+		else if (WMA_TGT_IS_VALID_SNR(dat_snr))
+			rssi = dat_snr;
+		else
+			rssi = WMA_TGT_INVALID_SNR;
+
+		/* Get the absolute rssi value from the current rssi value */
+		rssi = rssi + WMA_TGT_NOISE_FLOOR_DBM;
+		wma_lost_link_info_handler(wma, vdev_stats->vdev_id, rssi);
+	}
+}
+
+/**
+ * wma_update_vdev_stats() - update vdev stats
+ * @wma: wma handle
+ * @vdev_stats: vdev stats
+ *
+ * Return: none
+ */
+static void wma_update_vdev_stats(tp_wma_handle wma,
+				  wmi_vdev_stats *vdev_stats)
+{
+	tAniGetPEStatsRsp *stats_rsp_params;
+	tCsrSummaryStatsInfo *summary_stats = NULL;
+	uint8_t *stats_buf;
+	struct wma_txrx_node *node;
+	uint8_t i;
+	int32_t rssi = 0;
+	QDF_STATUS qdf_status;
+	tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq *) wma->pGetRssiReq;
+	struct scheduler_msg sme_msg = { 0 };
+	int32_t bcn_snr, dat_snr;
+
+	if (vdev_stats->vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: Invalid vdev_id %hu",
+			__func__, vdev_stats->vdev_id);
+		return;
+	}
+
+	bcn_snr = vdev_stats->vdev_snr.bcn_snr;
+	dat_snr = vdev_stats->vdev_snr.dat_snr;
+	WMA_LOGD("vdev id %d beancon snr %d data snr %d",
+		 vdev_stats->vdev_id, bcn_snr, dat_snr);
+
+	node = &wma->interfaces[vdev_stats->vdev_id];
+	stats_rsp_params = node->stats_rsp;
+	if (stats_rsp_params) {
+		stats_buf = (uint8_t *) (stats_rsp_params + 1);
+		node->fw_stats_set |= FW_VDEV_STATS_SET;
+		WMA_LOGD("<---FW VDEV STATS received for vdevId:%d",
+			 vdev_stats->vdev_id);
+		if (stats_rsp_params->statsMask & (1 << eCsrSummaryStats)) {
+			summary_stats = (tCsrSummaryStatsInfo *) stats_buf;
+			for (i = 0; i < 4; i++) {
+				summary_stats->tx_frm_cnt[i] =
+					vdev_stats->tx_frm_cnt[i];
+				summary_stats->fail_cnt[i] =
+					vdev_stats->fail_cnt[i];
+				summary_stats->multiple_retry_cnt[i] =
+					vdev_stats->multiple_retry_cnt[i];
+			}
+
+			summary_stats->rx_frm_cnt = vdev_stats->rx_frm_cnt;
+			summary_stats->rx_error_cnt = vdev_stats->rx_err_cnt;
+			summary_stats->rx_discard_cnt =
+				vdev_stats->rx_discard_cnt;
+			summary_stats->ack_fail_cnt = vdev_stats->ack_fail_cnt;
+			summary_stats->rts_succ_cnt = vdev_stats->rts_succ_cnt;
+			summary_stats->rts_fail_cnt = vdev_stats->rts_fail_cnt;
+			/* Update SNR and RSSI in SummaryStats */
+			if (WMA_TGT_IS_VALID_SNR(bcn_snr)) {
+				summary_stats->snr = bcn_snr;
+				summary_stats->rssi =
+					bcn_snr + WMA_TGT_NOISE_FLOOR_DBM;
+			} else if (WMA_TGT_IS_VALID_SNR(dat_snr)) {
+				summary_stats->snr = dat_snr;
+				summary_stats->rssi =
+					dat_snr + WMA_TGT_NOISE_FLOOR_DBM;
+			} else {
+				summary_stats->snr = WMA_TGT_INVALID_SNR;
+				summary_stats->rssi = 0;
+			}
+		}
+	}
+
+	if (pGetRssiReq && pGetRssiReq->sessionId == vdev_stats->vdev_id) {
+		if (WMA_TGT_IS_VALID_SNR(bcn_snr)) {
+			rssi = bcn_snr;
+			rssi = rssi + WMA_TGT_NOISE_FLOOR_DBM;
+		} else if (WMA_TGT_IS_VALID_SNR(dat_snr)) {
+			rssi = dat_snr;
+			rssi = rssi + WMA_TGT_NOISE_FLOOR_DBM;
+		} else {
+			/*
+			 * Firmware sends invalid snr till it sees
+			 * Beacon/Data after connection since after
+			 * vdev up fw resets the snr to invalid.
+			 * In this duartion Host will return the last know
+			 * rssi during connection.
+			 */
+			WMA_LOGE("Invalid SNR from firmware");
+		}
+
+		WMA_LOGD("Average Rssi = %d, vdev id= %d", rssi,
+			 pGetRssiReq->sessionId);
+
+		/* update the average rssi value to UMAC layer */
+		if (NULL != pGetRssiReq->rssiCallback) {
+			((tCsrRssiCallback) (pGetRssiReq->rssiCallback))(rssi,
+						pGetRssiReq->staId,
+						pGetRssiReq->pDevContext);
+		}
+
+		qdf_mem_free(pGetRssiReq);
+		wma->pGetRssiReq = NULL;
+	}
+
+	if (node->psnr_req) {
+		tAniGetSnrReq *p_snr_req = node->psnr_req;
+
+		if (WMA_TGT_IS_VALID_SNR(bcn_snr))
+			p_snr_req->snr = bcn_snr;
+		else if (WMA_TGT_IS_VALID_SNR(dat_snr))
+			p_snr_req->snr = dat_snr;
+		else
+			p_snr_req->snr = WMA_TGT_INVALID_SNR;
+
+		sme_msg.type = eWNI_SME_SNR_IND;
+		sme_msg.bodyptr = p_snr_req;
+		sme_msg.bodyval = 0;
+
+		qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+						    QDF_MODULE_ID_SME,
+						    QDF_MODULE_ID_SME,
+						    &sme_msg);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			WMA_LOGE("%s: Fail to post snr ind msg", __func__);
+			qdf_mem_free(p_snr_req);
+		}
+
+		node->psnr_req = NULL;
+	}
+	wma_vdev_stats_lost_link_helper(wma, vdev_stats);
+}
+
+/**
+ * wma_post_stats() - update stats to PE
+ * @wma: wma handle
+ * @node: txrx node
+ *
+ * Return: none
+ */
+static void wma_post_stats(tp_wma_handle wma, struct wma_txrx_node *node)
+{
+	/* send response to UMAC */
+	wma_send_msg(wma, WMA_GET_STATISTICS_RSP, node->stats_rsp, 0);
+	node->stats_rsp = NULL;
+	node->fw_stats_set = 0;
+}
+
+/**
+ * wma_update_peer_stats() - update peer stats
+ * @wma: wma handle
+ * @peer_stats: peer stats
+ *
+ * Return: none
+ */
+static void wma_update_peer_stats(tp_wma_handle wma,
+				  wmi_peer_stats *peer_stats)
+{
+	tAniGetPEStatsRsp *stats_rsp_params;
+	tCsrGlobalClassAStatsInfo *classa_stats = NULL;
+	struct wma_txrx_node *node;
+	uint8_t *stats_buf, vdev_id, macaddr[IEEE80211_ADDR_LEN], mcsRateFlags;
+	uint32_t temp_mask;
+	uint8_t nss;
+
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_stats->peer_macaddr, &macaddr[0]);
+	if (!wma_find_vdev_by_bssid(wma, macaddr, &vdev_id))
+		return;
+
+	node = &wma->interfaces[vdev_id];
+	stats_rsp_params = (tAniGetPEStatsRsp *) node->stats_rsp;
+	if (stats_rsp_params) {
+		node->fw_stats_set |= FW_PEER_STATS_SET;
+		WMA_LOGD("<-- FW PEER STATS received for vdevId:%d", vdev_id);
+		stats_buf = (uint8_t *) (stats_rsp_params + 1);
+		temp_mask = stats_rsp_params->statsMask;
+		if (temp_mask & (1 << eCsrSummaryStats))
+			stats_buf += sizeof(tCsrSummaryStatsInfo);
+
+		if (temp_mask & (1 << eCsrGlobalClassAStats)) {
+			classa_stats = (tCsrGlobalClassAStatsInfo *) stats_buf;
+			WMA_LOGD("peer tx rate:%d", peer_stats->peer_tx_rate);
+			WMA_LOGD("peer rx rate:%d", peer_stats->peer_rx_rate);
+			/* The linkspeed returned by fw is in kbps so convert
+			 * it in to units of 500kbps which is expected by UMAC
+			 */
+			if (peer_stats->peer_tx_rate) {
+				classa_stats->tx_rate =
+					peer_stats->peer_tx_rate / 500;
+			}
+
+			if (peer_stats->peer_rx_rate) {
+				classa_stats->rx_rate =
+					peer_stats->peer_rx_rate / 500;
+			}
+
+			classa_stats->tx_rx_rate_flags = node->rate_flags;
+			if (!(node->rate_flags & TX_RATE_LEGACY)) {
+				nss = node->nss;
+				classa_stats->tx_mcs_index =
+					wma_get_mcs_idx(
+						(peer_stats->peer_tx_rate /
+						100), node->rate_flags,
+						&nss, &mcsRateFlags);
+				classa_stats->tx_nss = nss;
+				classa_stats->tx_mcs_rate_flags = mcsRateFlags;
+			}
+
+			if (!(node->rate_flags & TX_RATE_LEGACY)) {
+				nss = node->nss;
+				classa_stats->rx_mcs_index =
+					wma_get_mcs_idx(
+						(peer_stats->peer_rx_rate /
+						100), node->rate_flags,
+						&nss, &mcsRateFlags);
+				classa_stats->rx_nss = nss;
+				classa_stats->rx_mcs_rate_flags = mcsRateFlags;
+			}
+			/* FW returns tx power in intervals of 0.5 dBm
+			 * Convert it back to intervals of 1 dBm
+			 */
+			classa_stats->max_pwr =
+				roundup(classa_stats->max_pwr, 2) >> 1;
+		}
+	}
+}
+#endif /* WMA_GET_STATISTICS_RSP */
+
+/**
+ * wma_post_link_status() - post link status to SME
+ * @pGetLinkStatus: SME Link status
+ * @link_status: Link status
+ *
+ * Return: none
+ */
+void wma_post_link_status(tAniGetLinkStatus *pGetLinkStatus,
+			  uint8_t link_status)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg sme_msg = { 0 };
+
+	pGetLinkStatus->linkStatus = link_status;
+	sme_msg.type = eWNI_SME_LINK_STATUS_IND;
+	sme_msg.bodyptr = pGetLinkStatus;
+	sme_msg.bodyval = 0;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("%s: Fail to post link status ind msg", __func__);
+		qdf_mem_free(pGetLinkStatus);
+	}
+}
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * wma_update_per_chain_rssi_stats() - to store per chain rssi stats
+ * @wma: wma handle
+ * @rssi_stats: rssi stats
+ * @rssi_per_chain_stats: buffer where rssi stats to be stored
+ *
+ * This function stores per chain rssi stats received from fw for all vdevs for
+ * which the stats were requested into a csr stats structure.
+ *
+ * Return: void
+ */
+static void wma_update_per_chain_rssi_stats(tp_wma_handle wma,
+		wmi_rssi_stats *rssi_stats,
+		struct csr_per_chain_rssi_stats_info *rssi_per_chain_stats)
+{
+	int i;
+	int32_t bcn_snr, dat_snr;
+
+	for (i = 0; i < NUM_CHAINS_MAX; i++) {
+		bcn_snr = rssi_stats->rssi_avg_beacon[i];
+		dat_snr = rssi_stats->rssi_avg_data[i];
+		WMA_LOGD("chain %d beacon snr %d data snr %d",
+			i, bcn_snr, dat_snr);
+		if (WMA_TGT_IS_VALID_SNR(bcn_snr))
+			rssi_per_chain_stats->rssi[i] = bcn_snr;
+		else if (WMA_TGT_IS_VALID_SNR(dat_snr))
+			rssi_per_chain_stats->rssi[i] = dat_snr;
+		else
+			/*
+			 * Firmware sends invalid snr till it sees
+			 * Beacon/Data after connection since after
+			 * vdev up fw resets the snr to invalid.
+			 * In this duartion Host will return an invalid rssi
+			 * value.
+			 */
+			rssi_per_chain_stats->rssi[i] = WMA_TGT_INVALID_SNR;
+
+		/*
+		 * Get the absolute rssi value from the current rssi value the
+		 * sinr value is hardcoded into 0 in the qcacld-new/CORE stack
+		 */
+		rssi_per_chain_stats->rssi[i] += WMA_TGT_NOISE_FLOOR_DBM;
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(&(rssi_stats->peer_macaddr),
+			rssi_per_chain_stats->peer_mac_addr);
+	}
+}
+
+/**
+ * wma_update_rssi_stats() - to update rssi stats for all vdevs
+ *         for which the stats were requested.
+ * @wma: wma handle
+ * @rssi_stats: rssi stats
+ *
+ * This function updates the rssi stats for all vdevs for which
+ * the stats were requested.
+ *
+ * Return: void
+ */
+static void wma_update_rssi_stats(tp_wma_handle wma,
+			wmi_rssi_stats *rssi_stats)
+{
+	tAniGetPEStatsRsp *stats_rsp_params;
+	struct csr_per_chain_rssi_stats_info *rssi_per_chain_stats = NULL;
+	struct wma_txrx_node *node;
+	uint8_t *stats_buf;
+	uint32_t temp_mask;
+	uint8_t vdev_id;
+
+	if (rssi_stats->vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: Invalid vdev_id %hu",
+			__func__, rssi_stats->vdev_id);
+		return;
+	}
+
+	vdev_id = rssi_stats->vdev_id;
+	node = &wma->interfaces[vdev_id];
+	stats_rsp_params = (tAniGetPEStatsRsp *) node->stats_rsp;
+	if (stats_rsp_params) {
+		node->fw_stats_set |=  FW_RSSI_PER_CHAIN_STATS_SET;
+		WMA_LOGD("<-- FW RSSI PER CHAIN STATS received for vdevId:%d",
+				vdev_id);
+		stats_buf = (uint8_t *) (stats_rsp_params + 1);
+		temp_mask = stats_rsp_params->statsMask;
+
+		if (temp_mask & (1 << eCsrSummaryStats))
+			stats_buf += sizeof(tCsrSummaryStatsInfo);
+		if (temp_mask & (1 << eCsrGlobalClassAStats))
+			stats_buf += sizeof(tCsrGlobalClassAStatsInfo);
+		if (temp_mask & (1 << eCsrGlobalClassDStats))
+			stats_buf += sizeof(tCsrGlobalClassDStatsInfo);
+
+		if (temp_mask & (1 << csr_per_chain_rssi_stats)) {
+			rssi_per_chain_stats =
+			     (struct csr_per_chain_rssi_stats_info *)stats_buf;
+			wma_update_per_chain_rssi_stats(wma, rssi_stats,
+					rssi_per_chain_stats);
+		}
+	}
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+/**
+ * wma_link_status_event_handler() - link status event handler
+ * @handle: wma handle
+ * @cmd_param_info: data from event
+ * @len: length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info,
+				  uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_UPDATE_VDEV_RATE_STATS_EVENTID_param_tlvs *param_buf;
+	wmi_vdev_rate_stats_event_fixed_param *event;
+	wmi_vdev_rate_ht_info *ht_info;
+	struct wma_txrx_node *intr = wma->interfaces;
+	uint8_t link_status = LINK_STATUS_LEGACY;
+	uint32_t i;
+
+	param_buf =
+	      (WMI_UPDATE_VDEV_RATE_STATS_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGA("%s: Invalid stats event", __func__);
+		return -EINVAL;
+	}
+
+	event = (wmi_vdev_rate_stats_event_fixed_param *)
+						param_buf->fixed_param;
+	ht_info = (wmi_vdev_rate_ht_info *) param_buf->ht_info;
+
+	WMA_LOGD("num_vdev_stats: %d", event->num_vdev_stats);
+
+	if (event->num_vdev_stats > ((WMI_SVC_MSG_MAX_SIZE -
+	    sizeof(*event)) / sizeof(*ht_info)) ||
+	    event->num_vdev_stats > param_buf->num_ht_info) {
+		WMA_LOGE("%s: excess vdev_stats buffers:%d, num_ht_info:%d",
+			__func__, event->num_vdev_stats,
+			param_buf->num_ht_info);
+		return -EINVAL;
+	}
+	for (i = 0; (i < event->num_vdev_stats) && ht_info; i++) {
+		WMA_LOGD("%s vdevId:%d  tx_nss:%d rx_nss:%d tx_preamble:%d rx_preamble:%d",
+			__func__, ht_info->vdevid, ht_info->tx_nss,
+			ht_info->rx_nss, ht_info->tx_preamble,
+			ht_info->rx_preamble);
+		if (ht_info->vdevid < wma->max_bssid
+		    && intr[ht_info->vdevid].plink_status_req) {
+			if (ht_info->tx_nss || ht_info->rx_nss)
+				link_status = LINK_STATUS_MIMO;
+
+			if ((ht_info->tx_preamble == LINK_RATE_VHT) ||
+			    (ht_info->rx_preamble == LINK_RATE_VHT))
+				link_status |= LINK_STATUS_VHT;
+
+			if (intr[ht_info->vdevid].nss == 2)
+				link_status |= LINK_SUPPORT_MIMO;
+
+			if (intr[ht_info->vdevid].rate_flags &
+				(TX_RATE_VHT20 | TX_RATE_VHT40 |
+				TX_RATE_VHT80))
+				link_status |= LINK_SUPPORT_VHT;
+
+			wma_post_link_status(
+					intr[ht_info->vdevid].plink_status_req,
+					link_status);
+			intr[ht_info->vdevid].plink_status_req = NULL;
+			link_status = LINK_STATUS_LEGACY;
+		}
+
+		ht_info++;
+	}
+
+	return 0;
+}
+
+int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event)
+{
+	struct rso_cmd_status *rso_status;
+	struct scheduler_msg sme_msg = {0};
+	QDF_STATUS qdf_status;
+
+	rso_status = qdf_mem_malloc(sizeof(*rso_status));
+	if (!rso_status)
+		return -ENOMEM;
+
+	rso_status->vdev_id = wmi_event->vdev_id;
+	if (WMI_ROAM_NOTIF_SCAN_MODE_SUCCESS == wmi_event->notif)
+		rso_status->status = true;
+	else if (WMI_ROAM_NOTIF_SCAN_MODE_FAIL == wmi_event->notif)
+		rso_status->status = false;
+	sme_msg.type = eWNI_SME_RSO_CMD_STATUS_IND;
+	sme_msg.bodyptr = rso_status;
+	sme_msg.bodyval = 0;
+	WMA_LOGD("%s: Post RSO cmd status to SME",  __func__);
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("%s: fail to post RSO cmd status to SME", __func__);
+		qdf_mem_free(rso_status);
+	}
+	return 0;
+}
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * wma_handle_sta_peer_info() - handle peer information in
+ * peer stats
+ * @num_peer_stats: peer number
+ * @peer_stats: peer stats received from firmware
+ * @peer_macaddr: the specified mac address
+ * @sapaddr: sap mac address
+ *
+ * This function will send eWNI_SME_GET_PEER_INFO_IND
+ * to sme with stations' information
+ *
+ */
+static void wma_handle_sta_peer_info(uint32_t num_peer_stats,
+					wmi_peer_stats *peer_stats,
+					struct qdf_mac_addr peer_macaddr,
+					uint8_t *sapaddr)
+{
+	QDF_STATUS qdf_status;
+	wmi_mac_addr temp_addr;
+	struct sir_peer_info_resp *peer_info;
+	struct scheduler_msg sme_msg = {0};
+	uint32_t  i;
+	uint32_t  j = 0;
+
+	if (!qdf_is_macaddr_broadcast(&peer_macaddr)) {
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_macaddr.bytes, &temp_addr);
+		for (i = 0; i < num_peer_stats; i++) {
+			if ((((temp_addr.mac_addr47to32) & 0x0000ffff) ==
+				((peer_stats->peer_macaddr.mac_addr47to32) &
+								0x0000ffff))
+				&& (temp_addr.mac_addr31to0 ==
+				peer_stats->peer_macaddr.mac_addr31to0)) {
+
+				break;
+			}
+			peer_stats = peer_stats + 1;
+		}
+		peer_info = qdf_mem_malloc(sizeof(*peer_info) +
+				sizeof(peer_info->info[0]));
+		if (!peer_info)
+			return;
+
+		if (i < num_peer_stats) {
+			peer_info->count = 1;
+			WMI_MAC_ADDR_TO_CHAR_ARRAY(&(peer_stats->peer_macaddr),
+				peer_info->info[0].peer_macaddr.bytes);
+			peer_info->info[0].rssi = peer_stats->peer_rssi;
+			peer_info->info[0].tx_rate = peer_stats->peer_tx_rate;
+			peer_info->info[0].rx_rate = peer_stats->peer_rx_rate;
+			WMA_LOGD("%s peer %pM rssi %d tx_rate %d rx_rate %d",
+					 __func__,
+					 peer_info->info[0].peer_macaddr.bytes,
+					 peer_stats->peer_rssi,
+					 peer_stats->peer_tx_rate,
+					 peer_stats->peer_rx_rate);
+		} else {
+			WMA_LOGE("%s: no match mac address", __func__);
+			peer_info->count = 0;
+		}
+	} else {
+		peer_info = qdf_mem_malloc(sizeof(*peer_info) +
+				num_peer_stats * sizeof(peer_info->info[0]));
+		if (!peer_info)
+			return;
+
+		peer_info->count = num_peer_stats;
+
+		for (i = 0; i < num_peer_stats; i++) {
+			WMI_MAC_ADDR_TO_CHAR_ARRAY(&(peer_stats->peer_macaddr),
+					peer_info->info[j].peer_macaddr.bytes);
+			peer_info->info[j].rssi = peer_stats->peer_rssi;
+			peer_info->info[j].tx_rate = peer_stats->peer_tx_rate;
+			peer_info->info[j].rx_rate = peer_stats->peer_rx_rate;
+			WMA_LOGD("%s peer %pM rssi %d tx_rate %d rx_rate %d",
+					__func__,
+					peer_info->info[j].peer_macaddr.bytes,
+					peer_stats->peer_rssi,
+					peer_stats->peer_tx_rate,
+					peer_stats->peer_rx_rate);
+			if (!qdf_mem_cmp(peer_info->info[j].peer_macaddr.bytes,
+					sapaddr, QDF_MAC_ADDR_SIZE)) {
+				peer_info->count = peer_info->count - 1;
+			} else {
+				j++;
+			}
+			peer_stats = peer_stats + 1;
+		}
+		WMA_LOGD("WDA send peer num %d", peer_info->count);
+	}
+
+	sme_msg.type = eWNI_SME_GET_PEER_INFO_IND;
+	sme_msg.bodyptr = peer_info;
+	sme_msg.bodyval = 0;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("%s: Fail to post get rssi msg", __func__);
+		qdf_mem_free(peer_info);
+	}
+
+	return;
+}
+
+/**
+ * wma_stats_event_handler() - stats event handler
+ * @handle: wma handle
+ * @cmd_param_info: data from event
+ * @len: length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info,
+			    uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
+	wmi_stats_event_fixed_param *event;
+	wmi_pdev_stats *pdev_stats;
+	wmi_vdev_stats *vdev_stats;
+	wmi_peer_stats *peer_stats;
+	wmi_rssi_stats *rssi_stats;
+	wmi_per_chain_rssi_stats *rssi_event;
+	struct wma_txrx_node *node;
+	uint8_t *temp;
+	uint32_t i;
+	uint32_t buf_len = 0;
+	bool excess_data = false;
+	wmi_congestion_stats *congestion_stats;
+	tpAniSirGlobal mac;
+
+	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGA("%s: Invalid stats event", __func__);
+		return -EINVAL;
+	}
+	event = param_buf->fixed_param;
+	temp = (uint8_t *) param_buf->data;
+	if ((event->num_pdev_stats + event->num_vdev_stats +
+	     event->num_peer_stats) > param_buf->num_data) {
+		WMA_LOGE("%s: Invalid num_pdev_stats:%d or num_vdev_stats:%d or num_peer_stats:%d",
+			__func__, event->num_pdev_stats, event->num_vdev_stats,
+			event->num_peer_stats);
+		return -EINVAL;
+	}
+
+	do {
+		if (event->num_pdev_stats > ((WMI_SVC_MSG_MAX_SIZE -
+		    sizeof(*event)) / sizeof(*pdev_stats))) {
+			excess_data = true;
+			break;
+		} else {
+			buf_len += event->num_pdev_stats * sizeof(*pdev_stats);
+		}
+
+		if (event->num_vdev_stats > ((WMI_SVC_MSG_MAX_SIZE -
+		    sizeof(*event)) / sizeof(*vdev_stats))) {
+			excess_data = true;
+			break;
+		} else {
+			buf_len += event->num_vdev_stats * sizeof(*vdev_stats);
+		}
+
+		if (event->num_peer_stats > ((WMI_SVC_MSG_MAX_SIZE -
+		    sizeof(*event)) / sizeof(*peer_stats))) {
+			excess_data = true;
+			break;
+		} else {
+			buf_len += event->num_peer_stats * sizeof(*peer_stats);
+		}
+
+		rssi_event =
+			(wmi_per_chain_rssi_stats *) param_buf->chain_stats;
+		if (rssi_event) {
+			if (rssi_event->num_per_chain_rssi_stats >
+			    ((WMI_SVC_MSG_MAX_SIZE - sizeof(*event)) /
+			    sizeof(*rssi_event))) {
+				excess_data = true;
+				break;
+			} else {
+				buf_len += sizeof(*rssi_event) *
+					rssi_event->num_per_chain_rssi_stats;
+			}
+		}
+	} while (0);
+
+	if (excess_data ||
+		(buf_len > WMI_SVC_MSG_MAX_SIZE - sizeof(*event))) {
+		WMA_LOGE("excess wmi buffer: stats pdev %d vdev %d peer %d",
+			 event->num_pdev_stats, event->num_vdev_stats,
+			 event->num_peer_stats);
+		QDF_ASSERT(0);
+		return -EINVAL;
+	}
+
+	if (event->num_pdev_stats > 0) {
+		for (i = 0; i < event->num_pdev_stats; i++) {
+			pdev_stats = (wmi_pdev_stats *) temp;
+			wma_update_pdev_stats(wma, pdev_stats);
+			temp += sizeof(wmi_pdev_stats);
+		}
+	}
+
+	if (event->num_vdev_stats > 0) {
+		for (i = 0; i < event->num_vdev_stats; i++) {
+			vdev_stats = (wmi_vdev_stats *) temp;
+			wma_update_vdev_stats(wma, vdev_stats);
+			temp += sizeof(wmi_vdev_stats);
+		}
+	}
+
+	if (event->num_peer_stats > 0) {
+		if (wma->get_sta_peer_info == true) {
+			wma_handle_sta_peer_info(event->num_peer_stats,
+				(wmi_peer_stats *)temp,
+				wma->peer_macaddr,
+				wma->myaddr);
+		} else {
+			for (i = 0; i < event->num_peer_stats; i++) {
+				peer_stats = (wmi_peer_stats *) temp;
+				wma_update_peer_stats(wma, peer_stats);
+				temp += sizeof(wmi_peer_stats);
+			}
+		}
+	}
+
+	rssi_event = (wmi_per_chain_rssi_stats *) param_buf->chain_stats;
+	if (rssi_event) {
+		if (rssi_event->num_per_chain_rssi_stats >
+		    param_buf->num_rssi_stats) {
+			WMA_LOGE("%s: Invalid num_per_chain_rssi_stats:%d",
+				__func__, rssi_event->num_per_chain_rssi_stats);
+			return -EINVAL;
+		}
+		if (((rssi_event->tlv_header & 0xFFFF0000) >> 16 ==
+			  WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats) &&
+			  ((rssi_event->tlv_header & 0x0000FFFF) ==
+			  WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats))) {
+			if (rssi_event->num_per_chain_rssi_stats > 0) {
+				temp = (uint8_t *) rssi_event;
+				temp += sizeof(*rssi_event);
+
+				/* skip past struct array tlv header */
+				temp += WMI_TLV_HDR_SIZE;
+
+				for (i = 0;
+				     i < rssi_event->num_per_chain_rssi_stats;
+				     i++) {
+					rssi_stats = (wmi_rssi_stats *)temp;
+					wma_update_rssi_stats(wma, rssi_stats);
+					temp += sizeof(wmi_rssi_stats);
+				}
+			}
+		}
+	}
+
+	congestion_stats = (wmi_congestion_stats *) param_buf->congestion_stats;
+	if (congestion_stats) {
+		if (((congestion_stats->tlv_header & 0xFFFF0000) >> 16 ==
+			  WMITLV_TAG_STRUC_wmi_congestion_stats) &&
+			  ((congestion_stats->tlv_header & 0x0000FFFF) ==
+			  WMITLV_GET_STRUCT_TLVLEN(wmi_congestion_stats))) {
+			mac = cds_get_context(QDF_MODULE_ID_PE);
+			if (!mac) {
+				WMA_LOGE("%s: Invalid mac", __func__);
+				return -EINVAL;
+			}
+			if (!mac->sme.congestion_cb) {
+				WMA_LOGE("%s: Callback not registered",
+					__func__);
+				return -EINVAL;
+			}
+			WMA_LOGI("%s: congestion %d", __func__,
+				congestion_stats->congestion);
+			mac->sme.congestion_cb(mac->hdd_handle,
+				congestion_stats->congestion,
+				congestion_stats->vdev_id);
+		}
+	}
+
+	for (i = 0; i < wma->max_bssid; i++) {
+		node = &wma->interfaces[i];
+		if (node->fw_stats_set & FW_PEER_STATS_SET)
+			wma_post_stats(wma, node);
+	}
+
+	return 0;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+/**
+ * wma_fill_peer_info() - fill SIR peer info from WMI peer info struct
+ * @wma: wma interface
+ * @stats_info: WMI peer info pointer
+ * @peer_info: SIR peer info pointer
+ *
+ * This function will fill SIR peer info from WMI peer info struct
+ *
+ * Return: None
+ */
+static void wma_fill_peer_info(tp_wma_handle wma,
+		wmi_peer_stats_info *stats_info,
+		struct sir_peer_info_ext *peer_info)
+{
+	peer_info->tx_packets = stats_info->tx_packets.low_32;
+	peer_info->tx_bytes = stats_info->tx_bytes.high_32;
+	peer_info->tx_bytes <<= 32;
+	peer_info->tx_bytes += stats_info->tx_bytes.low_32;
+	peer_info->rx_packets = stats_info->rx_packets.low_32;
+	peer_info->rx_bytes = stats_info->rx_bytes.high_32;
+	peer_info->rx_bytes <<= 32;
+	peer_info->rx_bytes += stats_info->rx_bytes.low_32;
+	peer_info->tx_retries = stats_info->tx_retries;
+	peer_info->tx_failed = stats_info->tx_failed;
+	peer_info->rssi = stats_info->peer_rssi;
+	peer_info->tx_rate = stats_info->last_tx_bitrate_kbps;
+	peer_info->tx_rate_code = stats_info->last_tx_rate_code;
+	peer_info->rx_rate = stats_info->last_rx_bitrate_kbps;
+	peer_info->rx_rate_code = stats_info->last_rx_rate_code;
+}
+
+/**
+ * wma_peer_info_ext_rsp() - process peer ext info ext
+ * @handle: wma interface
+ * @buf: wmi event buf pointer
+ *
+ * This function will send eWNI_SME_GET_PEER_INFO_EXT_IND to SME
+ *
+ * Return: 0 on success, error code otherwise
+ */
+static QDF_STATUS wma_peer_info_ext_rsp(tp_wma_handle wma, u_int8_t *buf)
+{
+	wmi_peer_stats_info_event_fixed_param *event;
+	wmi_peer_stats_info *stats_info;
+	struct sir_peer_info_ext_resp *resp;
+	struct sir_peer_info_ext *peer_info;
+	struct scheduler_msg sme_msg = {0};
+	int i, j = 0;
+	QDF_STATUS qdf_status;
+
+	event = (wmi_peer_stats_info_event_fixed_param *)buf;
+	stats_info = (wmi_peer_stats_info *)(buf +
+			sizeof(wmi_peer_stats_info_event_fixed_param));
+
+	if (wma->get_one_peer_info) {
+		resp = qdf_mem_malloc(sizeof(struct sir_peer_info_ext_resp) +
+				sizeof(resp->info[0]));
+		if (!resp)
+			return QDF_STATUS_E_NOMEM;
+
+		resp->count = 0;
+		peer_info = &resp->info[0];
+		for (i = 0; i < event->num_peers; i++) {
+			WMI_MAC_ADDR_TO_CHAR_ARRAY(&stats_info->peer_macaddr,
+					peer_info->peer_macaddr.bytes);
+
+			if (!qdf_mem_cmp(peer_info->peer_macaddr.bytes,
+					wma->peer_macaddr.bytes,
+					QDF_MAC_ADDR_SIZE)) {
+				wma_fill_peer_info(wma, stats_info, peer_info);
+				resp->count++;
+				break;
+			}
+
+			stats_info = stats_info + 1;
+		}
+	} else {
+		resp = qdf_mem_malloc(sizeof(struct sir_peer_info_ext_resp) +
+				event->num_peers * sizeof(resp->info[0]));
+		if (!resp)
+			return QDF_STATUS_E_NOMEM;
+
+		resp->count = event->num_peers;
+		for (i = 0; i < event->num_peers; i++) {
+			peer_info = &resp->info[j];
+			WMI_MAC_ADDR_TO_CHAR_ARRAY(&stats_info->peer_macaddr,
+					peer_info->peer_macaddr.bytes);
+
+			if (!qdf_mem_cmp(peer_info->peer_macaddr.bytes,
+					wma->myaddr, QDF_MAC_ADDR_SIZE)) {
+				resp->count = resp->count - 1;
+			} else {
+				wma_fill_peer_info(wma, stats_info, peer_info);
+				j++;
+			}
+			stats_info = stats_info + 1;
+		}
+	}
+
+	sme_msg.type = eWNI_SME_GET_PEER_INFO_EXT_IND;
+	sme_msg.bodyptr = resp;
+	sme_msg.bodyval = 0;
+
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("%s: Fail to post get peer info msg", __func__);
+		qdf_mem_free(resp);
+	}
+
+	return qdf_status;
+}
+
+/**
+ * dump_peer_stats_info() - dump wmi peer info struct
+ * @event: wmi peer info fixed param pointer
+ * @peer_stats: wmi peer stats info pointer
+ *
+ * This function will dump wmi peer info struct
+ *
+ * Return: None
+ */
+static void dump_peer_stats_info(wmi_peer_stats_info_event_fixed_param *event,
+		wmi_peer_stats_info *peer_stats)
+{
+	int i;
+	wmi_peer_stats_info *stats = peer_stats;
+	u_int8_t mac[6];
+
+	WMA_LOGI("%s vdev_id %d, num_peers %d more_data %d",
+			__func__, event->vdev_id,
+			event->num_peers, event->more_data);
+
+	for (i = 0; i < event->num_peers; i++) {
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(&stats->peer_macaddr, mac);
+		WMA_LOGI("%s mac %pM", __func__, mac);
+		WMA_LOGI("%s tx_bytes %d %d tx_packets %d %d",
+				__func__,
+				stats->tx_bytes.low_32,
+				stats->tx_bytes.high_32,
+				stats->tx_packets.low_32,
+				stats->tx_packets.high_32);
+		WMA_LOGI("%s rx_bytes %d %d rx_packets %d %d",
+				__func__,
+				stats->rx_bytes.low_32,
+				stats->rx_bytes.high_32,
+				stats->rx_packets.low_32,
+				stats->rx_packets.high_32);
+		WMA_LOGI("%s tx_retries %d tx_failed %d",
+				__func__, stats->tx_retries, stats->tx_failed);
+		WMA_LOGI("%s tx_rate_code %x rx_rate_code %x",
+				__func__,
+				stats->last_tx_rate_code,
+				stats->last_rx_rate_code);
+		WMA_LOGI("%s tx_rate %x rx_rate %x",
+				__func__,
+				stats->last_tx_bitrate_kbps,
+				stats->last_rx_bitrate_kbps);
+		WMA_LOGI("%s peer_rssi %d", __func__, stats->peer_rssi);
+		stats++;
+	}
+}
+
+int wma_peer_info_event_handler(void *handle, u_int8_t *cmd_param_info,
+				   u_int32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf;
+	wmi_peer_stats_info_event_fixed_param *event;
+	u_int32_t buf_size;
+	u_int8_t *buf;
+
+	param_buf =
+		(WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGA("%s: Invalid stats event", __func__);
+		return -EINVAL;
+	}
+
+	WMA_LOGI("%s Recv WMI_PEER_STATS_INFO_EVENTID", __func__);
+	event = param_buf->fixed_param;
+	if (event->num_peers >
+	    ((WMI_SVC_MSG_MAX_SIZE -
+	      sizeof(wmi_peer_stats_info_event_fixed_param))/
+	      sizeof(wmi_peer_stats_info)) || event->num_peers >
+	      param_buf->num_peer_stats_info) {
+		WMA_LOGE("Excess num of peers from fw: %d, num_peer_stats_info:%d",
+			event->num_peers, param_buf->num_peer_stats_info);
+		return -EINVAL;
+	}
+	buf_size = sizeof(wmi_peer_stats_info_event_fixed_param) +
+		sizeof(wmi_peer_stats_info) * event->num_peers;
+	buf = qdf_mem_malloc(buf_size);
+	if (!buf)
+		return -ENOMEM;
+
+	qdf_mem_copy(buf, param_buf->fixed_param,
+			sizeof(wmi_peer_stats_info_event_fixed_param));
+	qdf_mem_copy((buf + sizeof(wmi_peer_stats_info_event_fixed_param)),
+			param_buf->peer_stats_info,
+			sizeof(wmi_peer_stats_info) * event->num_peers);
+	WMA_LOGI("%s dump peer stats info", __func__);
+	dump_peer_stats_info(event, param_buf->peer_stats_info);
+
+	wma_peer_info_ext_rsp(wma, buf);
+	qdf_mem_free(buf);
+
+	return 0;
+}
+
+/**
+ * wma_send_link_speed() - send link speed to SME
+ * @link_speed: link speed
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_send_link_speed(uint32_t link_speed)
+{
+	tpAniSirGlobal mac_ctx;
+	tSirLinkSpeedInfo *ls_ind;
+
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac_ctx) {
+		WMA_LOGD("%s: NULL pMac ptr. Exiting", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	ls_ind = qdf_mem_malloc(sizeof(tSirLinkSpeedInfo));
+	if (!ls_ind)
+		return QDF_STATUS_E_NOMEM;
+
+	ls_ind->estLinkSpeed = link_speed;
+	if (mac_ctx->sme.pLinkSpeedIndCb)
+		mac_ctx->sme.pLinkSpeedIndCb(ls_ind,
+				mac_ctx->sme.pLinkSpeedCbContext);
+	else
+		WMA_LOGD("%s: pLinkSpeedIndCb is null", __func__);
+	qdf_mem_free(ls_ind);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_link_speed_event_handler() - link speed event handler
+ * @handle: wma handle
+ * @cmd_param_info: event data
+ * @len: length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_link_speed_event_handler(void *handle, uint8_t *cmd_param_info,
+				 uint32_t len)
+{
+	WMI_PEER_ESTIMATED_LINKSPEED_EVENTID_param_tlvs *param_buf;
+	wmi_peer_estimated_linkspeed_event_fixed_param *event;
+	QDF_STATUS qdf_status;
+
+	param_buf = (WMI_PEER_ESTIMATED_LINKSPEED_EVENTID_param_tlvs *)
+							 cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid linkspeed event", __func__);
+		return -EINVAL;
+	}
+	event = param_buf->fixed_param;
+	qdf_status = wma_send_link_speed(event->est_linkspeed_kbps);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		return -EINVAL;
+	return 0;
+}
+
+/**
+ * wma_wni_cfg_dnld() - cfg download request
+ * @handle: wma handle
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_wni_cfg_dnld(tp_wma_handle wma_handle)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	void *mac = cds_get_context(QDF_MODULE_ID_PE);
+
+	WMA_LOGD("%s: Enter", __func__);
+
+	if (NULL == mac) {
+		WMA_LOGE("%s: Invalid context", __func__);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	process_cfg_download_req(mac);
+
+	WMA_LOGD("%s: Exit", __func__);
+	return qdf_status;
+}
+
+#define BIG_ENDIAN_MAX_DEBUG_BUF   500
+/**
+ * wma_unified_debug_print_event_handler() - debug print event handler
+ * @handle: wma handle
+ * @datap: data pointer
+ * @len: length
+ *
+ * Return: 0 for success or error code
+ */
+int wma_unified_debug_print_event_handler(void *handle, uint8_t *datap,
+					  uint32_t len)
+{
+	WMI_DEBUG_PRINT_EVENTID_param_tlvs *param_buf;
+	uint8_t *data;
+	uint32_t datalen;
+
+	param_buf = (WMI_DEBUG_PRINT_EVENTID_param_tlvs *) datap;
+	if (!param_buf || !param_buf->data) {
+		WMA_LOGE("Get NULL point message from FW");
+		return -ENOMEM;
+	}
+	data = param_buf->data;
+	datalen = param_buf->num_data;
+	if (datalen > WMI_SVC_MSG_MAX_SIZE) {
+		WMA_LOGE("Received data len %d exceeds max value %d",
+				datalen, WMI_SVC_MSG_MAX_SIZE);
+		return QDF_STATUS_E_FAILURE;
+	}
+	data[datalen - 1] = '\0';
+
+#ifdef BIG_ENDIAN_HOST
+	{
+		if (datalen >= BIG_ENDIAN_MAX_DEBUG_BUF) {
+			WMA_LOGE("%s Invalid data len %d, limiting to max",
+				 __func__, datalen);
+			datalen = BIG_ENDIAN_MAX_DEBUG_BUF - 1;
+		}
+		char dbgbuf[BIG_ENDIAN_MAX_DEBUG_BUF] = { 0 };
+
+		memcpy(dbgbuf, data, datalen);
+		SWAPME(dbgbuf, datalen);
+		WMA_LOGD("FIRMWARE:%s", dbgbuf);
+		return 0;
+	}
+#else
+	WMA_LOGD("FIRMWARE:%s", data);
+	return 0;
+#endif /* BIG_ENDIAN_HOST */
+}
+
+/**
+ * wma_is_sap_active() - check sap is active or not
+ * @handle: wma handle
+ *
+ * Return: true/false
+ */
+bool wma_is_sap_active(tp_wma_handle wma_handle)
+{
+	int i;
+
+	for (i = 0; i < wma_handle->max_bssid; i++) {
+		if (!wma_is_vdev_up(i))
+			continue;
+		if (wma_handle->interfaces[i].type == WMI_VDEV_TYPE_AP &&
+		    wma_handle->interfaces[i].sub_type == 0)
+			return true;
+	}
+	return false;
+}
+
+/**
+ * wma_is_p2p_go_active() - check p2p go is active or not
+ * @handle: wma handle
+ *
+ * Return: true/false
+ */
+bool wma_is_p2p_go_active(tp_wma_handle wma_handle)
+{
+	int i;
+
+	for (i = 0; i < wma_handle->max_bssid; i++) {
+		if (!wma_is_vdev_up(i))
+			continue;
+		if (wma_handle->interfaces[i].type == WMI_VDEV_TYPE_AP &&
+		    wma_handle->interfaces[i].sub_type ==
+		    WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO)
+			return true;
+	}
+	return false;
+}
+
+/**
+ * wma_is_p2p_cli_active() - check p2p cli is active or not
+ * @handle: wma handle
+ *
+ * Return: true/false
+ */
+bool wma_is_p2p_cli_active(tp_wma_handle wma_handle)
+{
+	int i;
+
+	for (i = 0; i < wma_handle->max_bssid; i++) {
+		if (!wma_is_vdev_up(i))
+			continue;
+		if (wma_handle->interfaces[i].type == WMI_VDEV_TYPE_STA &&
+		    wma_handle->interfaces[i].sub_type ==
+		    WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT)
+			return true;
+	}
+	return false;
+}
+
+/**
+ * wma_is_sta_active() - check sta is active or not
+ * @handle: wma handle
+ *
+ * Return: true/false
+ */
+bool wma_is_sta_active(tp_wma_handle wma_handle)
+{
+	int i;
+
+	for (i = 0; i < wma_handle->max_bssid; i++) {
+		if (!wma_is_vdev_up(i))
+			continue;
+		if (wma_handle->interfaces[i].type == WMI_VDEV_TYPE_STA &&
+		    wma_handle->interfaces[i].sub_type == 0)
+			return true;
+		if (wma_handle->interfaces[i].type == WMI_VDEV_TYPE_IBSS)
+			return true;
+	}
+	return false;
+}
+
+/**
+ * wma_peer_phymode() - get phymode
+ * @nw_type: nw type
+ * @sta_type: sta type
+ * @is_ht: is ht supported
+ * @ch_width: supported channel width
+ * @is_vht: is vht supported
+ * @is_he: is HE supported
+ *
+ * Return: WLAN_PHY_MODE
+ */
+WLAN_PHY_MODE wma_peer_phymode(tSirNwType nw_type, uint8_t sta_type,
+			       uint8_t is_ht, uint8_t ch_width,
+			       uint8_t is_vht, bool is_he)
+{
+	WLAN_PHY_MODE phymode = MODE_UNKNOWN;
+
+	switch (nw_type) {
+	case eSIR_11B_NW_TYPE:
+#ifdef FEATURE_WLAN_TDLS
+	if (STA_ENTRY_TDLS_PEER == sta_type) {
+		if (is_vht) {
+			if (CH_WIDTH_80MHZ == ch_width)
+				phymode = MODE_11AC_VHT80;
+			else
+				phymode = (CH_WIDTH_40MHZ == ch_width) ?
+					  MODE_11AC_VHT40 :
+					  MODE_11AC_VHT20;
+		} else if (is_ht) {
+			phymode = (CH_WIDTH_40MHZ == ch_width) ?
+				  MODE_11NG_HT40 : MODE_11NG_HT20;
+		} else
+			phymode = MODE_11B;
+	} else
+#endif /* FEATURE_WLAN_TDLS */
+	{
+		phymode = MODE_11B;
+		if (is_ht || is_vht || is_he)
+			WMA_LOGE("HT/VHT is enabled with 11B NW type");
+	}
+		break;
+	case eSIR_11G_NW_TYPE:
+		if (!(is_ht || is_vht || is_he)) {
+			phymode = MODE_11G;
+			break;
+		}
+		if (CH_WIDTH_40MHZ < ch_width)
+			WMA_LOGE("80/160 MHz BW sent in 11G, configured 40MHz");
+		if (ch_width)
+			phymode = (is_he) ? MODE_11AX_HE40_2G : (is_vht) ?
+					MODE_11AC_VHT40_2G : MODE_11NG_HT40;
+		else
+			phymode = (is_he) ? MODE_11AX_HE20_2G : (is_vht) ?
+					MODE_11AC_VHT20_2G : MODE_11NG_HT20;
+		break;
+	case eSIR_11A_NW_TYPE:
+		if (!(is_ht || is_vht || is_he)) {
+			phymode = MODE_11A;
+			break;
+		}
+		if (is_he) {
+			if (ch_width == CH_WIDTH_160MHZ)
+				phymode = MODE_11AX_HE160;
+			else if (ch_width == CH_WIDTH_80P80MHZ)
+				phymode = MODE_11AX_HE80_80;
+			else if (ch_width == CH_WIDTH_80MHZ)
+				phymode = MODE_11AX_HE80;
+			else
+				phymode = (ch_width) ?
+					  MODE_11AX_HE40 : MODE_11AX_HE20;
+		} else if (is_vht) {
+			if (ch_width == CH_WIDTH_160MHZ)
+				phymode = MODE_11AC_VHT160;
+			else if (ch_width == CH_WIDTH_80P80MHZ)
+				phymode = MODE_11AC_VHT80_80;
+			else if (ch_width == CH_WIDTH_80MHZ)
+				phymode = MODE_11AC_VHT80;
+			else
+				phymode = (ch_width) ?
+					  MODE_11AC_VHT40 : MODE_11AC_VHT20;
+		} else
+			phymode = (ch_width) ? MODE_11NA_HT40 : MODE_11NA_HT20;
+		break;
+	default:
+		WMA_LOGE("%s: Invalid nw type %d", __func__, nw_type);
+		break;
+	}
+	WMA_LOGD(FL("nw_type %d is_ht %d ch_width %d is_vht %d is_he %d phymode %d"),
+		 nw_type, is_ht, ch_width, is_vht, is_he, phymode);
+
+	return phymode;
+}
+
+/**
+ * wma_txrx_fw_stats_reset() - reset txrx fw statistics
+ * @wma_handle: wma handle
+ * @vdev_id: vdev id
+ * @value: value
+ *
+ * Return: 0 for success or return error
+ */
+int32_t wma_txrx_fw_stats_reset(tp_wma_handle wma_handle,
+				uint8_t vdev_id, uint32_t value)
+{
+	struct ol_txrx_stats_req req;
+	struct cdp_vdev *vdev;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!soc) {
+		WMA_LOGE("%s:SOC context is NULL", __func__);
+		return -EINVAL;
+	}
+
+	vdev = wma_find_vdev_by_id(wma_handle, vdev_id);
+	if (!vdev) {
+		WMA_LOGE("%s:Invalid vdev handle", __func__);
+		return -EINVAL;
+	}
+	qdf_mem_zero(&req, sizeof(req));
+	req.stats_type_reset_mask = value;
+	cdp_fw_stats_get(soc, vdev, &req, false, false);
+
+	return 0;
+}
+
+#ifdef HELIUMPLUS
+#define SET_UPLOAD_MASK(_mask, _rate_info)	\
+	((_mask) = 1 << (_rate_info ## _V2))
+#else  /* !HELIUMPLUS */
+#define SET_UPLOAD_MASK(_mask, _rate_info)	\
+	((_mask) = 1 << (_rate_info))
+#endif
+
+#ifdef HELIUMPLUS
+static bool wma_is_valid_fw_stats_cmd(uint32_t value)
+{
+	if (value > (HTT_DBG_NUM_STATS + 1) ||
+		value == (HTT_DBG_STATS_RX_RATE_INFO + 1) ||
+		value == (HTT_DBG_STATS_TX_RATE_INFO + 1) ||
+		value == (HTT_DBG_STATS_TXBF_MUSU_NDPA_PKT + 1)) {
+		WMA_LOGE("%s: Not supported", __func__);
+		return false;
+	}
+	return true;
+}
+#else
+static bool wma_is_valid_fw_stats_cmd(uint32_t value)
+{
+	if (value > (HTT_DBG_NUM_STATS + 1) ||
+		value == (HTT_DBG_STATS_RX_RATE_INFO_V2 + 1) ||
+		value == (HTT_DBG_STATS_TX_RATE_INFO_V2 + 1) ||
+		value == (HTT_DBG_STATS_TXBF_MUSU_NDPA_PKT + 1)) {
+		WMA_LOGE("%s: Not supported", __func__);
+		return false;
+	}
+	return true;
+}
+#endif
+
+/**
+ * wma_set_txrx_fw_stats_level() - set txrx fw stats level
+ * @wma_handle: wma handle
+ * @vdev_id: vdev id
+ * @value: value
+ *
+ * Return: 0 for success or return error
+ */
+int32_t wma_set_txrx_fw_stats_level(tp_wma_handle wma_handle,
+				    uint8_t vdev_id, uint32_t value)
+{
+	struct ol_txrx_stats_req req;
+	struct cdp_vdev *vdev;
+	uint32_t l_up_mask;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (!soc) {
+		WMA_LOGE("%s:SOC context is NULL", __func__);
+		return -EINVAL;
+	}
+
+	vdev = wma_find_vdev_by_id(wma_handle, vdev_id);
+	if (!vdev) {
+		WMA_LOGE("%s:Invalid vdev handle", __func__);
+		return -EINVAL;
+	}
+
+	if (wma_is_valid_fw_stats_cmd(value) == false)
+		return -EINVAL;
+
+	qdf_mem_zero(&req, sizeof(req));
+	req.print.verbose = 1;
+
+	/* TODO: Need to check how to avoid mem leak*/
+	l_up_mask = 1 << (value - 1);
+	req.stats_type_upload_mask = l_up_mask;
+
+	cdp_fw_stats_get(soc, vdev, &req, false, true);
+
+	return 0;
+}
+
+#ifndef QCA_SUPPORT_CP_STATS
+/**
+ * wma_get_stats_rsp_buf() - fill get stats response buffer
+ * @get_stats_param: get stats parameters
+ *
+ * Return: stats response buffer
+ */
+static tAniGetPEStatsRsp *wma_get_stats_rsp_buf
+			(tAniGetPEStatsReq *get_stats_param)
+{
+	tAniGetPEStatsRsp *stats_rsp_params;
+	uint32_t len, temp_mask;
+
+	len = sizeof(tAniGetPEStatsRsp);
+	temp_mask = get_stats_param->statsMask;
+
+	if (temp_mask & (1 << eCsrSummaryStats))
+		len += sizeof(tCsrSummaryStatsInfo);
+
+	if (temp_mask & (1 << eCsrGlobalClassAStats))
+		len += sizeof(tCsrGlobalClassAStatsInfo);
+
+	if (temp_mask & (1 << eCsrGlobalClassDStats))
+		len += sizeof(tCsrGlobalClassDStatsInfo);
+
+	if (temp_mask & (1 << csr_per_chain_rssi_stats))
+		len += sizeof(struct csr_per_chain_rssi_stats_info);
+
+	stats_rsp_params = qdf_mem_malloc(len);
+	if (!stats_rsp_params) {
+		QDF_ASSERT(0);
+		return NULL;
+	}
+
+	stats_rsp_params->staId = get_stats_param->staId;
+	stats_rsp_params->statsMask = get_stats_param->statsMask;
+	stats_rsp_params->msgType = WMA_GET_STATISTICS_RSP;
+	stats_rsp_params->msgLen = len - sizeof(tAniGetPEStatsRsp);
+	stats_rsp_params->rc = QDF_STATUS_SUCCESS;
+	return stats_rsp_params;
+}
+
+/**
+ * wma_get_stats_req() - get stats request
+ * @handle: wma handle
+ * @get_stats_param: stats params
+ *
+ * Return: none
+ */
+void wma_get_stats_req(WMA_HANDLE handle,
+		       tAniGetPEStatsReq *get_stats_param)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	struct wma_txrx_node *node;
+	struct stats_request_params cmd = {0};
+	tAniGetPEStatsRsp *pGetPEStatsRspParams;
+
+
+	WMA_LOGD("%s: Enter", __func__);
+	node = &wma_handle->interfaces[get_stats_param->sessionId];
+	if (node->stats_rsp) {
+		pGetPEStatsRspParams = node->stats_rsp;
+		if (pGetPEStatsRspParams->staId == get_stats_param->staId &&
+		    pGetPEStatsRspParams->statsMask ==
+		    get_stats_param->statsMask) {
+			WMA_LOGD("Stats for staId %d with stats mask %d is pending.. ignore new request",
+				 get_stats_param->staId,
+				 get_stats_param->statsMask);
+			pGetPEStatsRspParams =
+				wma_get_stats_rsp_buf(get_stats_param);
+			if (!pGetPEStatsRspParams) {
+				WMA_LOGE("failed to allocate memory for stats response");
+				goto end;
+			}
+			goto req_pending;
+		} else {
+			qdf_mem_free(node->stats_rsp);
+			node->stats_rsp = NULL;
+			node->fw_stats_set = 0;
+		}
+	}
+
+	pGetPEStatsRspParams = wma_get_stats_rsp_buf(get_stats_param);
+	if (!pGetPEStatsRspParams)
+		goto end;
+
+	node->fw_stats_set = 0;
+	if (node->stats_rsp) {
+		WMA_LOGD(FL("stats_rsp is not null, prev_value: %pK"),
+			node->stats_rsp);
+		qdf_mem_free(node->stats_rsp);
+		node->stats_rsp = NULL;
+	}
+	node->stats_rsp = pGetPEStatsRspParams;
+	wma_handle->get_sta_peer_info = false;
+	WMA_LOGD("stats_rsp allocated: %pK, sta_id: %d, mask: %d, vdev_id: %d",
+		node->stats_rsp, node->stats_rsp->staId,
+		node->stats_rsp->statsMask, get_stats_param->sessionId);
+
+	cmd.vdev_id = get_stats_param->sessionId;
+	cmd.stats_id = get_stats_param->statsMask;
+	if (wmi_unified_stats_request_send(wma_handle->wmi_handle,
+					   node->bssid,
+					   &cmd)) {
+		WMA_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID",
+			 __func__);
+		goto failed;
+	}
+
+	goto end;
+failed:
+	node->stats_rsp = NULL;
+req_pending:
+	pGetPEStatsRspParams->rc = QDF_STATUS_E_FAILURE;
+	/* send response to UMAC */
+	wma_send_msg(wma_handle, WMA_GET_STATISTICS_RSP, pGetPEStatsRspParams,
+		     0);
+end:
+	qdf_mem_free(get_stats_param);
+	WMA_LOGD("%s: Exit", __func__);
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+/**
+ * wma_get_cca_stats() - send request to fw to get CCA
+ * @wma_handle: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: QDF status
+ */
+QDF_STATUS wma_get_cca_stats(tp_wma_handle wma_handle,
+				uint8_t vdev_id)
+{
+	if (wmi_unified_congestion_request_cmd(wma_handle->wmi_handle,
+			vdev_id)) {
+		WMA_LOGE("Failed to congestion request to fw");
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_get_beacon_buffer_by_vdev_id() - get the beacon buffer from vdev ID
+ * @vdev_id: vdev id
+ * @buffer_size: size of buffer
+ *
+ * Return: none
+ */
+void *wma_get_beacon_buffer_by_vdev_id(uint8_t vdev_id, uint32_t *buffer_size)
+{
+	tp_wma_handle wma;
+	struct beacon_info *beacon;
+	uint8_t *buf;
+	uint32_t buf_size;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+		return NULL;
+	}
+
+	if (vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: Invalid vdev_id %u", __func__, vdev_id);
+		return NULL;
+	}
+
+	if (!wma_is_vdev_in_ap_mode(wma, vdev_id)) {
+		WMA_LOGE("%s: vdevid %d is not in AP mode", __func__, vdev_id);
+		return NULL;
+	}
+
+	beacon = wma->interfaces[vdev_id].beacon;
+
+	if (!beacon) {
+		WMA_LOGE("%s: beacon invalid", __func__);
+		return NULL;
+	}
+
+	qdf_spin_lock_bh(&beacon->lock);
+
+	buf_size = qdf_nbuf_len(beacon->buf);
+	buf = qdf_mem_malloc(buf_size);
+	if (!buf) {
+		qdf_spin_unlock_bh(&beacon->lock);
+		return NULL;
+	}
+
+	qdf_mem_copy(buf, qdf_nbuf_data(beacon->buf), buf_size);
+
+	qdf_spin_unlock_bh(&beacon->lock);
+
+	if (buffer_size)
+		*buffer_size = buf_size;
+
+	return buf;
+}
+
+/**
+ * wma_get_vdev_address_by_vdev_id() - lookup MAC address from vdev ID
+ * @vdev_id: vdev id
+ *
+ * Return: mac address
+ */
+uint8_t *wma_get_vdev_address_by_vdev_id(uint8_t vdev_id)
+{
+	tp_wma_handle wma;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+		return NULL;
+	}
+
+	if (vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: Invalid vdev_id %u", __func__, vdev_id);
+		return NULL;
+	}
+
+	return wma->interfaces[vdev_id].addr;
+}
+
+QDF_STATUS wma_get_connection_info(uint8_t vdev_id,
+		struct policy_mgr_vdev_entry_info *conn_table_entry)
+{
+	struct wma_txrx_node *wma_conn_table_entry;
+
+	wma_conn_table_entry = wma_get_interface_by_vdev_id(vdev_id);
+	if (NULL == wma_conn_table_entry) {
+		WMA_LOGE("%s: can't find vdev_id %d in WMA table", __func__, vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	conn_table_entry->chan_width = wma_conn_table_entry->chan_width;
+	conn_table_entry->mac_id = wma_conn_table_entry->mac_id;
+	conn_table_entry->mhz = wma_conn_table_entry->mhz;
+	conn_table_entry->sub_type = wma_conn_table_entry->sub_type;
+	conn_table_entry->type = wma_conn_table_entry->type;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_get_interface_by_vdev_id() - lookup interface entry using vdev ID
+ * @vdev_id: vdev id
+ *
+ * Return: entry from vdev table
+ */
+struct wma_txrx_node  *wma_get_interface_by_vdev_id(uint8_t vdev_id)
+{
+	tp_wma_handle wma;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+		return NULL;
+	}
+
+	if (vdev_id >= wma->max_bssid) {
+		WMA_LOGE("%s: Invalid vdev_id %u", __func__, vdev_id);
+		return NULL;
+	}
+
+	return &wma->interfaces[vdev_id];
+}
+
+QDF_STATUS wma_get_wcnss_software_version(uint8_t *version,
+					  uint32_t version_buffer_size)
+{
+	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	struct target_psoc_info *tgt_hdl;
+
+	if (NULL == wma_handle) {
+		WMA_LOGE("%s: Failed to get wma", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
+	if (!tgt_hdl) {
+		WMA_LOGE("%s: Failed to get wma", __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	snprintf(version, version_buffer_size, "%x",
+		 target_if_get_fw_version(tgt_hdl));
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_get_mac_id_of_vdev() - Get MAC id corresponding to a vdev
+ * @vdev_id: VDEV whose MAC ID is required
+ *
+ * Get MAC id corresponding to a vdev id from the WMA structure
+ *
+ * Return: Negative value on failure and MAC id on success
+ */
+int8_t wma_get_mac_id_of_vdev(uint32_t vdev_id)
+{
+	tp_wma_handle wma;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+		return -EINVAL;
+	}
+
+	if (wma->interfaces)
+		return wma->interfaces[vdev_id].mac_id;
+
+	return -EINVAL;
+}
+
+/**
+ * wma_update_intf_hw_mode_params() - Update WMA params
+ * @vdev_id: VDEV id whose params needs to be updated
+ * @mac_id: MAC id to be updated
+ * @cfgd_hw_mode_index: HW mode index from which Tx and Rx SS will be updated
+ *
+ * Updates the MAC id, tx spatial stream, rx spatial stream in WMA
+ *
+ * Return: None
+ */
+void wma_update_intf_hw_mode_params(uint32_t vdev_id, uint32_t mac_id,
+				    uint32_t cfgd_hw_mode_index)
+{
+	tp_wma_handle wma;
+	struct policy_mgr_hw_mode_params hw_mode;
+	QDF_STATUS status;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+		return;
+	}
+
+	if (!wma->interfaces) {
+		WMA_LOGE("%s: Interface is NULL", __func__);
+		return;
+	}
+
+	status = policy_mgr_get_hw_mode_from_idx(wma->psoc, cfgd_hw_mode_index,
+						 &hw_mode);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		WMA_LOGE("%s: cfgd_hw_mode_index %d not found", __func__,
+			 cfgd_hw_mode_index);
+		return;
+	}
+	wma->interfaces[vdev_id].mac_id = mac_id;
+	if (mac_id == 0) {
+		wma->interfaces[vdev_id].tx_streams =
+			hw_mode.mac0_tx_ss;
+		wma->interfaces[vdev_id].rx_streams =
+			hw_mode.mac0_rx_ss;
+	} else {
+		wma->interfaces[vdev_id].tx_streams =
+			hw_mode.mac1_tx_ss;
+		wma->interfaces[vdev_id].rx_streams =
+			hw_mode.mac1_tx_ss;
+	}
+	WMA_LOGD("%s: vdev %d, update tx ss:%d rx ss:%d mac %d hw_mode_id %d",
+		 __func__,
+		 vdev_id,
+		 wma->interfaces[vdev_id].tx_streams,
+		 wma->interfaces[vdev_id].rx_streams,
+		 mac_id,
+		 cfgd_hw_mode_index);
+}
+
+/**
+ * wma_get_vht_ch_width - return vht channel width
+ *
+ * Return: return vht channel width
+ */
+uint32_t wma_get_vht_ch_width(void)
+{
+	uint32_t fw_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+	tp_wma_handle wm_hdl = cds_get_context(QDF_MODULE_ID_WMA);
+	struct target_psoc_info *tgt_hdl;
+	int vht_cap_info;
+
+	if (NULL == wm_hdl)
+		return fw_ch_wd;
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(wm_hdl->psoc);
+	if (!tgt_hdl)
+		return fw_ch_wd;
+
+	vht_cap_info = target_if_get_vht_cap_info(tgt_hdl);
+	if (vht_cap_info & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ)
+		fw_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ;
+	else if (vht_cap_info & WMI_VHT_CAP_CH_WIDTH_160MHZ)
+		fw_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
+
+	return fw_ch_wd;
+}
+
+/**
+ * wma_get_num_of_setbits_from_bitmask() - to get num of setbits from bitmask
+ * @mask: given bitmask
+ *
+ * This helper function should return number of setbits from bitmask
+ *
+ * Return: number of setbits from bitmask
+ */
+uint32_t wma_get_num_of_setbits_from_bitmask(uint32_t mask)
+{
+	uint32_t num_of_setbits = 0;
+
+	while (mask) {
+		mask &= (mask - 1);
+		num_of_setbits++;
+	}
+	return num_of_setbits;
+}
+
+/**
+ * wma_is_csa_offload_enabled - checks fw CSA offload capability
+ *
+ * Return: true or false
+ */
+
+bool wma_is_csa_offload_enabled(void)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma)
+		return false;
+
+	return wmi_service_enabled(wma->wmi_handle,
+				   wmi_service_csa_offload);
+}
+#ifdef FEATURE_FW_LOG_PARSING
+/**
+ * wma_config_debug_module_cmd - set debug log config
+ * @wmi_handle: wmi layer handle
+ * @param: debug log parameter
+ * @val: debug log value
+ * @module_id_bitmap: debug module id bitmap
+ * @bitmap_len:  debug module bitmap length
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS
+wma_config_debug_module_cmd(wmi_unified_t wmi_handle, A_UINT32 param,
+			    A_UINT32 val, A_UINT32 *module_id_bitmap,
+			    A_UINT32 bitmap_len)
+{
+	struct dbglog_params dbg_param;
+
+	dbg_param.param = param;
+	dbg_param.val = val;
+	dbg_param.module_id_bitmap = module_id_bitmap;
+	dbg_param.bitmap_len = bitmap_len;
+
+	return wmi_unified_dbglog_cmd_send(wmi_handle, &dbg_param);
+}
+#endif
+#ifdef FEATURE_P2P_LISTEN_OFFLOAD
+/**
+ * wma_is_p2p_lo_capable() - if driver is capable of p2p listen offload
+ *
+ * This function checks if driver is capable of p2p listen offload
+ *    true: capable of p2p offload
+ *    false: not capable
+ *
+ * Return: true - capable, false - not capable
+ */
+bool wma_is_p2p_lo_capable(void)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (wma) {
+		return wmi_service_enabled
+				(wma->wmi_handle,
+				 wmi_service_p2p_listen_offload_support);
+	}
+
+	return 0;
+}
+#endif
+
+bool wma_capability_enhanced_mcast_filter(void)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (wma) {
+		return wmi_service_enabled(wma->wmi_handle,
+					   wmi_service_enhanced_mcast_filter);
+	}
+
+	return 0;
+}
+
+
+bool wma_is_vdev_up(uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+	bool is_up = false;
+
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return is_up;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc, vdev_id,
+			WLAN_LEGACY_WMA_ID);
+	if (vdev) {
+		is_up = wlan_vdev_is_up(vdev);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+	}
+	return is_up;
+}
+
+void wma_acquire_wakelock(qdf_wake_lock_t *wl, uint32_t msec)
+{
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	cds_host_diag_log_work(wl, msec, WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP);
+	qdf_wake_lock_timeout_acquire(wl, msec);
+	qdf_runtime_pm_prevent_suspend(&wma->wmi_cmd_rsp_runtime_lock);
+}
+
+void wma_release_wakelock(qdf_wake_lock_t *wl)
+{
+	t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	qdf_wake_lock_release(wl, WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP);
+	qdf_runtime_pm_allow_suspend(&wma->wmi_cmd_rsp_runtime_lock);
+}
+
+QDF_STATUS
+wma_send_vdev_start_to_fw(t_wma_handle *wma, struct vdev_start_params *params)
+{
+	QDF_STATUS status;
+	struct wma_txrx_node *vdev = &wma->interfaces[params->vdev_id];
+
+	if (!wma_is_vdev_valid(params->vdev_id)) {
+		WMA_LOGE("%s: Invalid vdev id:%d", __func__, params->vdev_id);
+		status = QDF_STATUS_E_FAILURE;
+		return status;
+	}
+	wma_acquire_wakelock(&vdev->vdev_start_wakelock,
+			     WMA_VDEV_START_REQUEST_TIMEOUT);
+	status = wmi_unified_vdev_start_send(wma->wmi_handle, params);
+	if (QDF_IS_STATUS_ERROR(status))
+		wma_release_wakelock(&vdev->vdev_start_wakelock);
+
+	return status;
+}
+
+QDF_STATUS wma_send_vdev_stop_to_fw(t_wma_handle *wma, uint8_t vdev_id)
+{
+	QDF_STATUS status;
+	struct wma_txrx_node *vdev = &wma->interfaces[vdev_id];
+
+	if (!wma_is_vdev_valid(vdev_id)) {
+		WMA_LOGE("%s: Invalid vdev id:%d", __func__, vdev_id);
+		status = QDF_STATUS_E_FAILURE;
+		return status;
+	}
+	wma_acquire_wakelock(&vdev->vdev_stop_wakelock,
+			     WMA_VDEV_STOP_REQUEST_TIMEOUT);
+	status = wmi_unified_vdev_stop_send(wma->wmi_handle, vdev_id);
+	if (QDF_IS_STATUS_ERROR(status))
+		wma_release_wakelock(&vdev->vdev_stop_wakelock);
+
+	return status;
+}
+
+QDF_STATUS wma_get_rcpi_req(WMA_HANDLE handle,
+			    struct sme_rcpi_req *rcpi_request)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	struct rcpi_req  cmd = {0};
+	struct wma_txrx_node *iface;
+	struct sme_rcpi_req *node_rcpi_req;
+
+	WMA_LOGD("%s: Enter", __func__);
+	iface = &wma_handle->interfaces[rcpi_request->session_id];
+	/* command is in progress */
+	if (iface->rcpi_req != NULL) {
+		WMA_LOGE("%s : previous rcpi request is pending", __func__);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	node_rcpi_req = qdf_mem_malloc(sizeof(*node_rcpi_req));
+	if (!node_rcpi_req)
+		return QDF_STATUS_E_NOMEM;
+
+	*node_rcpi_req = *rcpi_request;
+	iface->rcpi_req = node_rcpi_req;
+
+	cmd.vdev_id = rcpi_request->session_id;
+	qdf_mem_copy(cmd.mac_addr, &rcpi_request->mac_addr, QDF_MAC_ADDR_SIZE);
+	cmd.measurement_type = rcpi_request->measurement_type;
+
+	if (wmi_unified_send_request_get_rcpi_cmd(wma_handle->wmi_handle,
+						  &cmd)) {
+		WMA_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID",
+			 __func__);
+		iface->rcpi_req = NULL;
+		qdf_mem_free(node_rcpi_req);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("%s: Exit", __func__);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+int wma_rcpi_event_handler(void *handle, uint8_t *cmd_param_info,
+			   uint32_t len)
+{
+	struct rcpi_res res = {0};
+	struct sme_rcpi_req *rcpi_req;
+	struct qdf_mac_addr qdf_mac;
+	struct wma_txrx_node *iface;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tp_wma_handle wma_handle = (tp_wma_handle)handle;
+
+	status = wmi_extract_rcpi_response_event(wma_handle->wmi_handle,
+						 cmd_param_info, &res);
+	if (status == QDF_STATUS_E_INVAL)
+		return -EINVAL;
+
+	iface = &wma_handle->interfaces[res.vdev_id];
+	if (!iface->rcpi_req) {
+		WMI_LOGE("rcpi_req buffer not available");
+		return 0;
+	}
+
+	rcpi_req = iface->rcpi_req;
+	if (!rcpi_req->rcpi_callback) {
+		iface->rcpi_req = NULL;
+		qdf_mem_free(rcpi_req);
+		return 0;
+	}
+
+	if ((res.measurement_type == RCPI_MEASUREMENT_TYPE_INVALID) ||
+	    (res.vdev_id != rcpi_req->session_id) ||
+	    (res.measurement_type != rcpi_req->measurement_type) ||
+	    (qdf_mem_cmp(res.mac_addr, &rcpi_req->mac_addr,
+			 QDF_MAC_ADDR_SIZE))) {
+		WMI_LOGE("invalid rcpi_response");
+		iface->rcpi_req = NULL;
+		qdf_mem_free(rcpi_req);
+		return 0;
+	}
+
+	qdf_mem_copy(&qdf_mac, res.mac_addr, QDF_MAC_ADDR_SIZE);
+	(rcpi_req->rcpi_callback)(rcpi_req->rcpi_context, qdf_mac,
+				  res.rcpi_value, status);
+	iface->rcpi_req = NULL;
+	qdf_mem_free(rcpi_req);
+
+	return 0;
+}
+
+
+
+QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma,
+				  struct vdev_up_params *params,
+				  uint8_t bssid[IEEE80211_ADDR_LEN])
+{
+	QDF_STATUS status;
+	struct wma_txrx_node *vdev;
+
+	if (!wma_is_vdev_valid(params->vdev_id)) {
+		WMA_LOGE("%s: Invalid vdev id:%d", __func__, params->vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+#ifndef CONFIG_VDEV_SM
+	if (wma_is_vdev_up(params->vdev_id)) {
+		WMA_LOGD("vdev %d is already up for bssid %pM. Do not send",
+			 params->vdev_id, bssid);
+		return QDF_STATUS_SUCCESS;
+	}
+#endif
+	vdev = &wma->interfaces[params->vdev_id];
+
+	status = wmi_unified_vdev_up_send(wma->wmi_handle, bssid, params);
+	wma_release_wakelock(&vdev->vdev_start_wakelock);
+
+	return status;
+}
+
+QDF_STATUS wma_send_vdev_down_to_fw(t_wma_handle *wma, uint8_t vdev_id)
+{
+	QDF_STATUS status;
+	struct wma_txrx_node *vdev;
+
+	if (!wma_is_vdev_valid(vdev_id)) {
+		WMA_LOGE("%s: Invalid vdev id:%d", __func__, vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vdev = &wma->interfaces[vdev_id];
+	wma->interfaces[vdev_id].roaming_in_progress = false;
+	status = wmi_unified_vdev_down_send(wma->wmi_handle, vdev_id);
+	wma_release_wakelock(&vdev->vdev_start_wakelock);
+
+	return status;
+}
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+tSirWifiPeerType wmi_to_sir_peer_type(enum wmi_peer_type type)
+{
+	switch (type) {
+	case WMI_PEER_TYPE_DEFAULT:
+		return WIFI_PEER_STA;
+	case WMI_PEER_TYPE_BSS:
+		return WIFI_PEER_AP;
+	case WMI_PEER_TYPE_TDLS:
+		return WIFI_PEER_TDLS;
+	case WMI_PEER_TYPE_NAN_DATA:
+		return WIFI_PEER_NAN;
+	default:
+		WMA_LOGE("Cannot map wmi_peer_type %d to HAL peer type", type);
+		return WIFI_PEER_INVALID;
+	}
+}
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+#ifdef FEATURE_WLAN_DYNAMIC_CVM
+/**
+ * wma_set_vc_mode_config() - set voltage corner mode config to FW.
+ * @wma_handle:	pointer to wma handle.
+ * @vc_bitmap:	value needs to set to firmware.
+ *
+ * At the time of driver startup, set operating voltage corner mode
+ * for differenet phymode and bw configurations.
+ *
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS wma_set_vc_mode_config(void *wma_handle,
+		uint32_t vc_bitmap)
+{
+	int32_t ret;
+	tp_wma_handle wma = (tp_wma_handle)wma_handle;
+	struct pdev_params pdevparam;
+
+	pdevparam.param_id = WMI_PDEV_UPDATE_WDCVS_ALGO;
+	pdevparam.param_value = vc_bitmap;
+
+	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
+			&pdevparam,
+			WMA_WILDCARD_PDEV_ID);
+	if (ret) {
+		WMA_LOGE("Fail to Set Voltage Corner config (0x%x)",
+			vc_bitmap);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("Successfully Set Voltage Corner config (0x%x)",
+		vc_bitmap);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+int wma_chip_power_save_failure_detected_handler(void *handle,
+						 uint8_t  *cmd_param_info,
+						 uint32_t len)
+{
+	tp_wma_handle wma = (tp_wma_handle)handle;
+	WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID_param_tlvs *param_buf;
+	wmi_chip_power_save_failure_detected_fixed_param  *event;
+	struct chip_pwr_save_fail_detected_params  pwr_save_fail_params;
+	tpAniSirGlobal mac = (tpAniSirGlobal)cds_get_context(
+						QDF_MODULE_ID_PE);
+	if (wma == NULL) {
+		WMA_LOGE("%s: wma_handle is NULL", __func__);
+		return -EINVAL;
+	}
+	if (!mac) {
+		WMA_LOGE("%s: Invalid mac context", __func__);
+		return -EINVAL;
+	}
+	if (!mac->sme.chip_power_save_fail_cb) {
+		WMA_LOGE("%s: Callback not registered", __func__);
+		return -EINVAL;
+	}
+
+	param_buf =
+	(WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID_param_tlvs *)
+	cmd_param_info;
+	if (!param_buf) {
+		WMA_LOGE("%s: Invalid pwr_save_fail_params breached event",
+			 __func__);
+		return -EINVAL;
+	}
+	event = param_buf->fixed_param;
+	pwr_save_fail_params.failure_reason_code =
+				event->power_save_failure_reason_code;
+	pwr_save_fail_params.wake_lock_bitmap[0] =
+				event->protocol_wake_lock_bitmap[0];
+	pwr_save_fail_params.wake_lock_bitmap[1] =
+				event->protocol_wake_lock_bitmap[1];
+	pwr_save_fail_params.wake_lock_bitmap[2] =
+				event->protocol_wake_lock_bitmap[2];
+	pwr_save_fail_params.wake_lock_bitmap[3] =
+				event->protocol_wake_lock_bitmap[3];
+	mac->sme.chip_power_save_fail_cb(mac->hdd_handle,
+				&pwr_save_fail_params);
+
+	WMA_LOGD("%s: Invoke HDD pwr_save_fail callback", __func__);
+	return 0;
+}
+
+int wma_roam_scan_stats_event_handler(void *handle, uint8_t *event,
+				      uint32_t len)
+{
+	tp_wma_handle wma_handle;
+	wmi_unified_t wmi_handle;
+	struct sir_roam_scan_stats *roam_scan_stats_req = NULL;
+	struct wma_txrx_node *iface = NULL;
+	struct wmi_roam_scan_stats_res *res = NULL;
+	int ret = 0;
+	uint32_t vdev_id;
+	QDF_STATUS status;
+
+	wma_handle = handle;
+	if (!wma_handle) {
+		WMA_LOGE(FL("NULL wma_handle"));
+		return -EINVAL;
+	}
+
+	wmi_handle = wma_handle->wmi_handle;
+	if (!wmi_handle) {
+		WMA_LOGE(FL("NULL wmi_handle"));
+		return -EINVAL;
+	}
+
+	status = wmi_extract_roam_scan_stats_res_evt(wmi_handle, event,
+						     &vdev_id,
+						     &res);
+
+	/* vdev_id can be invalid though status is success, hence validate */
+	if (vdev_id >= wma_handle->max_bssid) {
+		WMA_LOGE(FL("Received invalid vdev_id: %d"), vdev_id);
+		ret  = -EINVAL;
+		goto free_res;
+	}
+
+	/* Get interface for valid vdev_id */
+	iface = &wma_handle->interfaces[vdev_id];
+	if (!iface) {
+		WMI_LOGE(FL("Interface not available for vdev_id: %d"),
+			 vdev_id);
+		ret  = -EINVAL;
+		goto free_res;
+	}
+
+	roam_scan_stats_req = iface->roam_scan_stats_req;
+	iface->roam_scan_stats_req = NULL;
+	if (!roam_scan_stats_req) {
+		WMI_LOGE(FL("No pending request vdev_id: %d"), vdev_id);
+		ret  = -EINVAL;
+		goto free_res;
+	}
+
+	if (!QDF_IS_STATUS_SUCCESS(status) ||
+	    !roam_scan_stats_req->cb ||
+	    roam_scan_stats_req->vdev_id != vdev_id) {
+		WMI_LOGE(FL("roam_scan_stats buffer not available"));
+		ret = -EINVAL;
+		goto free_roam_scan_stats_req;
+	}
+
+	roam_scan_stats_req->cb(roam_scan_stats_req->context, res);
+
+free_roam_scan_stats_req:
+	qdf_mem_free(roam_scan_stats_req);
+	roam_scan_stats_req = NULL;
+
+free_res:
+	qdf_mem_free(res);
+	res = NULL;
+
+	return ret;
+}
+
+QDF_STATUS wma_get_roam_scan_stats(WMA_HANDLE handle,
+				   struct sir_roam_scan_stats *req)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle)handle;
+	struct wmi_roam_scan_stats_req cmd = {0};
+	struct wma_txrx_node *iface;
+	struct sir_roam_scan_stats *node_req = NULL;
+
+	WMA_LOGD("%s: Enter", __func__);
+	iface = &wma_handle->interfaces[req->vdev_id];
+	/* command is in progress */
+	if (iface->roam_scan_stats_req) {
+		WMA_LOGE(FL("previous roam scan stats req is pending"));
+		return QDF_STATUS_SUCCESS;
+	}
+
+	node_req = qdf_mem_malloc(sizeof(*node_req));
+	if (!node_req)
+		return QDF_STATUS_E_NOMEM;
+
+	*node_req = *req;
+	iface->roam_scan_stats_req = node_req;
+	cmd.vdev_id = req->vdev_id;
+
+	if (wmi_unified_send_roam_scan_stats_cmd(wma_handle->wmi_handle,
+						 &cmd)) {
+		WMA_LOGE("%s: Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID",
+			 __func__);
+		iface->roam_scan_stats_req = NULL;
+		qdf_mem_free(node_req);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	WMA_LOGD("%s: Exit", __func__);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wma_remove_peer_on_add_bss_failure(tpAddBssParams add_bss_params)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	struct cdp_pdev *pdev;
+	void *peer = NULL;
+	uint8_t peer_id;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	WMA_LOGE("%s: ADD BSS failure %d", __func__, add_bss_params->status);
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (NULL == pdev)
+		WMA_LOGE("%s: Failed to get pdev", __func__);
+
+	if (pdev)
+		peer = cdp_peer_find_by_addr(soc, pdev,
+					     add_bss_params->bssId,
+					     &peer_id);
+
+	if (!peer)
+		WMA_LOGE("%s Failed to find peer %pM",
+			 __func__, add_bss_params->bssId);
+
+	if (peer)
+		wma_remove_peer(wma, add_bss_params->bssId,
+				add_bss_params->bssIdx, peer, false);
+}
+
+#ifdef CONFIG_VDEV_SM
+
+QDF_STATUS wma_sta_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
+				uint16_t data_len, void *data)
+{
+	struct vdev_up_params *param;
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	param = (struct vdev_up_params *)data;
+	wma_send_vdev_up_to_fw(wma, param,
+			       wma->interfaces[param->vdev_id].bssid);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool wma_get_hidden_ssid_restart_in_progress(struct wma_txrx_node *iface)
+{
+	if (!iface)
+		return false;
+
+	return ap_mlme_is_hidden_ssid_restart_in_progress(iface->vdev);
+}
+
+static QDF_STATUS wma_vdev_send_start_resp(tp_wma_handle wma,
+					   tpAddBssParams add_bss)
+{
+	WMA_LOGD(FL("Sending add bss rsp to umac(vdev %d status %d)"),
+		 add_bss->bssIdx, add_bss->status);
+	wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wma_sta_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme,
+					    uint16_t data_len, void *data)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	enum vdev_assoc_type assoc_type;
+
+	assoc_type = mlme_get_assoc_type(vdev_mlme->vdev);
+	switch (assoc_type) {
+	case VDEV_ASSOC:
+	case VDEV_REASSOC:
+		wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP,
+					   data, 0);
+		break;
+	case VDEV_FT_REASSOC:
+		wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP,
+					   data, 0);
+		break;
+	default:
+		WMA_LOGE(FL("assoc_type %d is invalid"), assoc_type);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wma_ap_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme,
+					   uint16_t data_len, void *data)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev;
+
+	if (mlme_is_chan_switch_in_progress(vdev)) {
+		wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP,
+					   data, 0);
+		mlme_set_chan_switch_in_progress(vdev, false);
+	} else if (ap_mlme_is_hidden_ssid_restart_in_progress(vdev)) {
+		wma_send_msg(wma, WMA_HIDDEN_SSID_RESTART_RSP, data, 0);
+		ap_mlme_set_hidden_ssid_restart_in_progress(vdev, false);
+	} else {
+		status = wma_vdev_send_start_resp(wma, (tpAddBssParams)data);
+	}
+
+	return status;
+}
+
+QDF_STATUS wma_mlme_vdev_stop_continue(struct vdev_mlme_obj *vdev_mlme,
+				       uint16_t data_len, void *data)
+{
+	return __wma_vdev_stop_resp_handler(
+			(wmi_vdev_stopped_event_fixed_param *)data);
+}
+
+QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
+				      uint16_t data_len, void *data)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	wma_send_vdev_down_bss(wma, (struct wma_target_req *)data);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wma_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
+				   uint16_t data_len, void *data)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_target_req *req = (struct wma_target_req *)data;
+
+	if (!mlme_get_vdev_start_failed(vdev_mlme->vdev))
+		if (req->msg_type == WMA_SET_LINK_STATE ||
+			req->type == WMA_SET_LINK_PEER_RSP)
+			wma_send_set_link_response(wma, req);
+		else
+			wma_send_del_bss_response(wma, req);
+	else
+		mlme_set_vdev_start_failed(vdev_mlme->vdev, false);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme,
+					    enum vdev_cmd_type type,
+					    uint16_t data_len, void *data)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	tpAddBssParams bss_params = (tpAddBssParams)data;
+
+	if (wma_send_vdev_stop_to_fw(wma, bss_params->bssIdx))
+		WMA_LOGE(FL("Failed to send vdev stop for vdev id %d"),
+			 bss_params->bssIdx);
+
+	wma_remove_peer_on_add_bss_failure(bss_params);
+
+	return wma_vdev_send_start_resp(wma, bss_params);
+}
+#else
+bool wma_get_hidden_ssid_restart_in_progress(struct wma_txrx_node *iface)
+{
+	if (!iface)
+		return false;
+
+	if (qdf_atomic_read(
+		&iface->vdev_restart_params.hidden_ssid_restart_in_progress))
+		return true;
+
+	return false;
+}
+#endif
diff --git a/core/wma/src/wma_utils_ut.c b/core/wma/src/wma_utils_ut.c
new file mode 100644
index 0000000..c050b90
--- /dev/null
+++ b/core/wma/src/wma_utils_ut.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015-2016, 2018 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:    wma_utils_ut.c
+ *  This file contains utilities related to unit test framework
+ */
+
+/* Header files */
+
+#include "wma.h"
+
+/**
+ * wma_set_dbs_capability_ut() - Set DBS capability for UT framework
+ * @dbs: Value of DBS capability to be set
+ *
+ * Sets the DBS capability for unit test framework. If the HW mode is
+ * already sent by the FW, only the DBS capability needs to be set. If the
+ * FW did not send any HW mode list, a single entry is created and DBS mode
+ * is set in it. The DBS capability is also set in the service bit map.
+ *
+ * Return: None
+ */
+void wma_set_dbs_capability_ut(uint32_t dbs)
+{
+	tp_wma_handle wma;
+	uint32_t i;
+
+	wma = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma) {
+		WMA_LOGE("%s: Invalid WMA handle", __func__);
+		return;
+	}
+
+	/* DBS list was not configured by the FW, so
+	 * for UT, we can configure a single entry
+	 */
+	if (wma->hw_mode.hw_mode_list == NULL) {
+		wma->num_dbs_hw_modes = 1;
+		wma->hw_mode.hw_mode_list =
+			qdf_mem_malloc(sizeof(*wma->hw_mode.hw_mode_list) *
+					wma->num_dbs_hw_modes);
+		if (!wma->hw_mode.hw_mode_list)
+			return;
+
+		wma->hw_mode.hw_mode_list[0] = 0x0000;
+	}
+
+	for (i = 0; i < wma->num_dbs_hw_modes; i++) {
+		WMA_HW_MODE_DBS_MODE_SET(wma->hw_mode.hw_mode_list[i],
+				dbs);
+	}
+
+	WMI_SERVICE_ENABLE(wma->wmi_service_bitmap,
+			WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT);
+}
diff --git a/os_if/nan/inc/os_if_nan.h b/os_if/nan/inc/os_if_nan.h
new file mode 100644
index 0000000..338ea74
--- /dev/null
+++ b/os_if/nan/inc/os_if_nan.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2012-2018 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: declares nan component os interface APIs
+ */
+
+#ifndef _OS_IF_NAN_H_
+#define _OS_IF_NAN_H_
+
+#include "qdf_types.h"
+#include "nan_public_structs.h"
+#include "nan_ucfg_api.h"
+
+struct wlan_objmgr_psoc;
+struct wlan_objmgr_vdev;
+
+#ifdef WLAN_FEATURE_NAN_CONVERGENCE
+
+/**
+ * os_if_nan_process_ndp_cmd: os_if api to handle nan request message
+ * @psoc: pointer to psoc object
+ * @data: request data. contains vendor cmd tlvs
+ * @data_len: length of data
+ *
+ * Return: status of operation
+ */
+int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc,
+				const void *data, int data_len);
+
+/**
+ * os_if_nan_event_handler: os_if handler api for nan response messages
+ * @psoc: pointer to psoc object
+ * @vdev: pointer to vdev object
+ * @type: message type
+ * @msg: msg buffer
+ *
+ * Return: None
+ */
+void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc,
+			     struct wlan_objmgr_vdev *vdev,
+			     uint32_t type, void *msg);
+
+/**
+ * os_if_nan_register_hdd_callbacks: os_if api to register hdd callbacks
+ * @psoc: pointer to psoc object
+ * @cb_obj: struct pointer containing callbacks
+ *
+ * Return: status of operation
+ */
+int os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
+				     struct nan_callbacks *cb_obj);
+
+/**
+ * os_if_nan_register_lim_callbacks: os_if api to register lim callbacks
+ * @psoc: pointer to psoc object
+ * @cb_obj: struct pointer containing callbacks
+ *
+ * Return: status of operation
+ */
+int os_if_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc,
+				     struct nan_callbacks *cb_obj);
+
+/**
+ * os_if_nan_post_ndi_create_rsp: os_if api to pos ndi create rsp to umac nan
+ * component
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev id of ndi
+ * @success: if create was success or failure
+ *
+ * Return: None
+ */
+void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id, bool success);
+
+/**
+ * os_if_nan_post_ndi_delete_rsp: os_if api to pos ndi delete rsp to umac nan
+ * component
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev id of ndi
+ * @success: if delete was success or failure
+ *
+ * Return: None
+ */
+void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id, bool success);
+
+/**
+ * os_if_nan_ndi_session_end: os_if api to process ndi session end
+ * component
+ * @vdev: pointer to vdev deleted
+ *
+ * Return: None
+ */
+void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * os_if_nan_set_ndi_state: os_if api set NDI state
+ * @vdev: pointer to vdev deleted
+ * @state: value to set
+ *
+ * Return: status of operation
+ */
+static inline QDF_STATUS os_if_nan_set_ndi_state(struct wlan_objmgr_vdev *vdev,
+						 uint32_t state)
+{
+	return ucfg_nan_set_ndi_state(vdev, state);
+}
+
+/**
+ * os_if_nan_set_ndp_create_transaction_id: set ndp create transaction id
+ * @vdev: pointer to vdev object
+ * @val: value to set
+ *
+ * Return: status of operation
+ */
+static inline QDF_STATUS os_if_nan_set_ndp_create_transaction_id(
+						struct wlan_objmgr_vdev *vdev,
+						uint16_t val)
+{
+	return ucfg_nan_set_ndp_create_transaction_id(vdev, val);
+}
+
+/**
+ * os_if_nan_set_ndp_delete_transaction_id: set ndp delete transaction id
+ * @vdev: pointer to vdev object
+ * @val: value to set
+ *
+ * Return: status of operation
+ */
+static inline QDF_STATUS os_if_nan_set_ndp_delete_transaction_id(
+						struct wlan_objmgr_vdev *vdev,
+						uint16_t val)
+{
+	return ucfg_nan_set_ndp_delete_transaction_id(vdev, val);
+}
+
+#else
+
+static inline void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc,
+						 uint8_t vdev_id, bool success)
+{
+}
+
+static inline void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc,
+						 uint8_t vdev_id, bool success)
+{
+}
+
+#endif /* WLAN_FEATURE_NAN_CONVERGENCE */
+
+#endif
diff --git a/os_if/nan/src/os_if_nan.c b/os_if/nan/src/os_if_nan.c
new file mode 100644
index 0000000..6f98e93
--- /dev/null
+++ b/os_if/nan/src/os_if_nan.c
@@ -0,0 +1,2170 @@
+/*
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: defines nan component os interface APIs
+ */
+
+#include "qdf_str.h"
+#include "qdf_trace.h"
+#include "qdf_types.h"
+#include "os_if_nan.h"
+#include "wlan_nan_api.h"
+#include "nan_ucfg_api.h"
+#include "nan_public_structs.h"
+#include "wlan_osif_priv.h"
+#include <net/cfg80211.h>
+#include "wlan_cfg80211.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 "wlan_utility.h"
+
+/* NLA policy */
+static const struct nla_policy
+vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = {
+						.type = NLA_U16,
+						.len = sizeof(uint16_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = {
+						.type = NLA_NUL_STRING,
+						.len = IFNAMSIZ - 1
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = {
+						.type = NLA_UNSPEC,
+						.len = QDF_MAC_ADDR_SIZE
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = {
+						.type = NLA_U16,
+						.len = sizeof(uint16_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = {
+						.type = NLA_BINARY,
+						.len = NDP_APP_INFO_LEN
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = {
+						.type = NLA_BINARY,
+						.len = QDF_MAC_ADDR_SIZE
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = {
+						.type = NLA_BINARY,
+						.len = NDP_NUM_INSTANCE_ID
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_CSID] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_PMK] = {
+						.type = NLA_BINARY,
+						.len = NDP_PMK_LEN
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_SCID] = {
+						.type = NLA_BINARY,
+						.len = NDP_SCID_BUF_LEN
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE] = {
+						.type = NLA_BINARY,
+						.len = NAN_PASSPHRASE_MAX_LEN
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME] = {
+						.type = NLA_BINARY,
+						.len = NAN_MAX_SERVICE_NAME_LEN
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO] = {
+						.type = NLA_BINARY,
+						.len = NAN_CH_INFO_MAX_LEN
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_NSS] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR] = {
+						.type = NLA_UNSPEC,
+						.len = QDF_IPV6_ADDR_SIZE
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT] = {
+						.type = NLA_U16,
+						.len = sizeof(uint16_t)
+	},
+	[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL] = {
+						.type = NLA_U8,
+						.len = sizeof(uint8_t)
+	},
+};
+
+static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc,
+					struct nlattr **tb)
+{
+	int ret;
+	char *iface_name;
+	QDF_STATUS status;
+	uint16_t transaction_id;
+	struct wlan_objmgr_vdev *nan_vdev;
+	struct nan_callbacks cb_obj;
+
+	cfg80211_debug("enter");
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
+		cfg80211_err("Interface name string is unavailable");
+		return -EINVAL;
+	}
+	iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
+
+	nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID);
+	if (nan_vdev) {
+		cfg80211_err("NAN data interface %s is already present",
+			     iface_name);
+		wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
+		return -EEXIST;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
+		cfg80211_err("transaction id is unavailable");
+		return -EINVAL;
+	}
+	transaction_id =
+		nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
+
+	status = ucfg_nan_get_callbacks(psoc, &cb_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cfg80211_err("Couldn't get ballback object");
+		return -EINVAL;
+	}
+
+	ret = cb_obj.ndi_open(iface_name);
+	if (ret) {
+		cfg80211_err("ndi_open failed");
+		return ret;
+	}
+
+	return cb_obj.ndi_start(iface_name, transaction_id);
+}
+
+static void os_if_nan_vdev_delete_peer(struct wlan_objmgr_psoc *psoc,
+				       void *peer, void *nan_vdev)
+{
+	/* if peer belongs to nan vdev */
+	if (nan_vdev == wlan_peer_get_vdev(peer)) {
+		cfg80211_debug("deleting peer: %pM",
+			       wlan_peer_get_macaddr(peer));
+		wlan_objmgr_peer_obj_delete(peer);
+	}
+}
+
+static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc,
+					struct nlattr **tb)
+{
+	uint8_t vdev_id;
+	char *iface_name;
+	QDF_STATUS status;
+	uint32_t num_peers;
+	uint16_t transaction_id;
+	struct nan_callbacks cb_obj;
+	struct wlan_objmgr_vdev *nan_vdev = NULL;
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
+		cfg80211_err("Interface name string is unavailable");
+		return -EINVAL;
+	}
+
+	iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
+		cfg80211_err("Transaction id is unavailable");
+		return -EINVAL;
+	}
+
+	nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID);
+	if (!nan_vdev) {
+		cfg80211_err("Nan datapath interface is not present");
+		return -EINVAL;
+	}
+
+	transaction_id =
+		nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
+	vdev_id = wlan_vdev_get_id(nan_vdev);
+	num_peers = ucfg_nan_get_active_peers(nan_vdev);
+
+	/* delete all peer for this interface first */
+	wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP,
+				     os_if_nan_vdev_delete_peer,
+				     nan_vdev, 1, WLAN_NAN_ID);
+
+	/*
+	 * wlan_util_get_vdev_by_ifname increments ref count
+	 * decrement here since vdev returned by that api is not used any more
+	 */
+	wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
+
+	/* check if there are active peers on the adapter */
+	if (num_peers)
+		cfg80211_err("NDP peers active: %d, active NDPs may not be terminated",
+			     num_peers);
+
+	status = ucfg_nan_get_callbacks(psoc, &cb_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cfg80211_err("Couldn't get ballback object");
+		return -EINVAL;
+	}
+
+	return cb_obj.ndi_delete(vdev_id, iface_name, transaction_id);
+}
+
+/**
+ * os_if_nan_parse_security_params() - parse vendor attributes for security
+ * params.
+ * @tb: parsed NL attribute list
+ * @ncs_sk_type: out parameter to populate ncs_sk_type
+ * @pmk: out parameter to populate pmk
+ * @passphrase: out parameter to populate passphrase
+ * @service_name: out parameter to populate service_name
+ *
+ * Return:  0 on success or error code on failure
+ */
+static int os_if_nan_parse_security_params(struct nlattr **tb,
+			uint32_t *ncs_sk_type, struct nan_datapath_pmk *pmk,
+			struct ndp_passphrase *passphrase,
+			struct ndp_service_name *service_name)
+{
+	if (!ncs_sk_type || !pmk || !passphrase || !service_name) {
+		cfg80211_err("out buffers for one ore more parameters is null");
+		return -EINVAL;
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CSID]) {
+		*ncs_sk_type =
+			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CSID]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
+		pmk->pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
+		qdf_mem_copy(pmk->pmk,
+			     nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]),
+			     pmk->pmk_len);
+		cfg80211_err("pmk len: %d", pmk->pmk_len);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
+				   pmk->pmk, pmk->pmk_len);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]) {
+		passphrase->passphrase_len =
+			nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]);
+		qdf_mem_copy(passphrase->passphrase,
+			     nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]),
+			     passphrase->passphrase_len);
+		cfg80211_err("passphrase len: %d", passphrase->passphrase_len);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
+				   passphrase->passphrase,
+				   passphrase->passphrase_len);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]) {
+		service_name->service_name_len =
+			nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]);
+		qdf_mem_copy(service_name->service_name,
+			     nla_data(
+				     tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]),
+			     service_name->service_name_len);
+		cfg80211_err("service_name len: %d",
+			     service_name->service_name_len);
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
+				   service_name->service_name,
+				   service_name->service_name_len);
+	}
+
+	return 0;
+}
+
+/**
+ * os_if_nan_process_ndp_initiator_req() - NDP initiator request handler
+ * @ctx: hdd context
+ * @tb: parsed NL attribute list
+ *
+ * tb will contain following vendor attributes:
+ * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
+ * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
+ * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL - optional
+ * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG
+ * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID
+ * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR
+ * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
+ * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
+ * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
+ * QCA_WLAN_VENDOR_ATTR_NDP_CSID - optional
+ * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional
+ * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional
+ *
+ * Return:  0 on success or error code on failure
+ */
+static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc,
+					       struct nlattr **tb)
+{
+	int ret = 0;
+	char *iface_name;
+	QDF_STATUS status;
+	enum nan_datapath_state state;
+	struct wlan_objmgr_vdev *nan_vdev;
+	struct nan_datapath_initiator_req req = {0};
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
+		cfg80211_err("Interface name string is unavailable");
+		return -EINVAL;
+	}
+
+	iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
+	nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID);
+	if (!nan_vdev) {
+		cfg80211_err("NAN data interface %s not available", iface_name);
+		return -EINVAL;
+	}
+
+	if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) {
+		cfg80211_err("Interface found is not NDI");
+		ret = -EINVAL;
+		goto initiator_req_failed;
+	}
+
+	state = ucfg_nan_get_ndi_state(nan_vdev);
+	if (state == NAN_DATA_NDI_DELETED_STATE ||
+	    state == NAN_DATA_NDI_DELETING_STATE ||
+	    state == NAN_DATA_NDI_CREATING_STATE) {
+		cfg80211_err("Data request not allowed in NDI current state: %d",
+			     state);
+		ret = -EINVAL;
+		goto initiator_req_failed;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
+		cfg80211_err("Transaction ID is unavailable");
+		ret = -EINVAL;
+		goto initiator_req_failed;
+	}
+	req.transaction_id =
+		nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
+		req.channel = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
+
+		if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]) {
+			req.channel_cfg = nla_get_u32(
+				tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]);
+		} else {
+			cfg80211_err("Channel config is unavailable");
+			ret = -EINVAL;
+			goto initiator_req_failed;
+		}
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
+		cfg80211_err("NDP service instance ID is unavailable");
+		ret = -EINVAL;
+		goto initiator_req_failed;
+	}
+	req.service_instance_id =
+		nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
+
+	qdf_mem_copy(req.self_ndi_mac_addr.bytes,
+		     wlan_vdev_mlme_get_macaddr(nan_vdev), QDF_MAC_ADDR_SIZE);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
+		cfg80211_err("NDI peer discovery mac addr is unavailable");
+		ret = -EINVAL;
+		goto initiator_req_failed;
+	}
+	qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
+		     nla_data(
+			  tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
+		     QDF_MAC_ADDR_SIZE);
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
+		req.ndp_info.ndp_app_info_len =
+			nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
+		qdf_mem_copy(req.ndp_info.ndp_app_info,
+			     nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]),
+			     req.ndp_info.ndp_app_info_len);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
+		/* at present ndp config stores 4 bytes QOS info only */
+		req.ndp_config.ndp_cfg_len = 4;
+		*((uint32_t *)req.ndp_config.ndp_cfg) =
+			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]) {
+		req.is_ipv6_addr_present = true;
+		qdf_mem_copy(req.ipv6_addr,
+			     nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]),
+			     QDF_IPV6_ADDR_SIZE);
+	}
+	cfg80211_debug("ipv6 addr present: %d, addr: %pI6",
+		       req.is_ipv6_addr_present, req.ipv6_addr);
+
+	if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk,
+					    &req.passphrase,
+					    &req.service_name)) {
+		cfg80211_err("inconsistent security params in request.");
+		ret = -EINVAL;
+		goto initiator_req_failed;
+	}
+
+	cfg80211_debug("vdev_id: %d, transaction_id: %d, channel: %d, service_instance_id: %d, ndp_app_info_len: %d, csid: %d, peer_discovery_mac_addr: %pM",
+		       wlan_vdev_get_id(nan_vdev), req.transaction_id,
+		       req.channel, req.service_instance_id,
+		       req.ndp_info.ndp_app_info_len, req.ncs_sk_type,
+		       req.peer_discovery_mac_addr.bytes);
+
+	req.vdev = nan_vdev;
+	status = ucfg_nan_req_processor(nan_vdev, &req, NDP_INITIATOR_REQ);
+	ret = qdf_status_to_os_return(status);
+initiator_req_failed:
+	if (ret)
+		wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
+
+	return ret;
+}
+
+/**
+ * os_if_nan_process_ndp_responder_req() - NDP responder request handler
+ * @nan_ctx: hdd context
+ * @tb: parsed NL attribute list
+ *
+ * tb includes following vendor attributes:
+ * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
+ * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
+ * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID
+ * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE
+ * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
+ * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
+ * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
+ * QCA_WLAN_VENDOR_ATTR_NDP_CSID - optional
+ * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional
+ * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional
+ *
+ * Return: 0 on success or error code on failure
+ */
+static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
+					       struct nlattr **tb)
+{
+	int ret = 0;
+	char *iface_name;
+	QDF_STATUS status;
+	enum nan_datapath_state state;
+	struct wlan_objmgr_vdev *nan_vdev = NULL;
+	struct nan_datapath_responder_req req = {0};
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
+		cfg80211_err("ndp_rsp is unavailable");
+		return -EINVAL;
+	}
+	req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
+
+	if (req.ndp_rsp == NAN_DATAPATH_RESPONSE_ACCEPT) {
+		if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
+			cfg80211_err("Interface not provided");
+			return -ENODEV;
+		}
+		iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
+
+		/* Check for an existing NAN interface */
+		nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name,
+							WLAN_NAN_ID);
+		if (!nan_vdev) {
+			cfg80211_err("NAN data iface %s not available",
+				     iface_name);
+			return -ENODEV;
+		}
+
+		if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) {
+			cfg80211_err("Interface found is not NDI");
+			ret = -ENODEV;
+			goto responder_req_failed;
+		}
+	} else {
+		/*
+		 * If the data indication is rejected, the userspace
+		 * may not send the iface name. Use the first NDI
+		 * in that case
+		 */
+		cfg80211_debug("ndp rsp rejected, using first NDI");
+
+		nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
+				psoc, QDF_NDI_MODE, WLAN_NAN_ID);
+		if (!nan_vdev) {
+			cfg80211_err("NAN data iface is not available");
+			return -ENODEV;
+		}
+	}
+
+	state = ucfg_nan_get_ndi_state(nan_vdev);
+	if (state == NAN_DATA_NDI_DELETED_STATE ||
+	    state == NAN_DATA_NDI_DELETING_STATE ||
+	    state == NAN_DATA_NDI_CREATING_STATE) {
+		cfg80211_err("Data request not allowed in current NDI state:%d",
+			state);
+		ret = -EAGAIN;
+		goto responder_req_failed;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
+		cfg80211_err("Transaction ID is unavailable");
+		ret = -EINVAL;
+		goto responder_req_failed;
+	}
+	req.transaction_id =
+		nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) {
+		cfg80211_err("Instance ID is unavailable");
+		ret = -EINVAL;
+		goto responder_req_failed;
+	}
+	req.ndp_instance_id =
+		nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
+		req.ndp_info.ndp_app_info_len =
+			nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
+		qdf_mem_copy(req.ndp_info.ndp_app_info,
+			     nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]),
+			     req.ndp_info.ndp_app_info_len);
+	} else {
+		cfg80211_debug("NDP app info is unavailable");
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
+		/* at present ndp config stores 4 bytes QOS info only */
+		req.ndp_config.ndp_cfg_len = 4;
+		*((uint32_t *)req.ndp_config.ndp_cfg) =
+			nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
+	} else {
+		cfg80211_debug("NDP config data is unavailable");
+	}
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]) {
+		req.is_ipv6_addr_present = true;
+		qdf_mem_copy(req.ipv6_addr,
+			     nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]),
+			     QDF_IPV6_ADDR_SIZE);
+	}
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT]) {
+		req.is_port_present = true;
+		req.port = nla_get_u16(
+			tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT]);
+	}
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL]) {
+		req.is_protocol_present = true;
+		req.protocol = nla_get_u8(
+			tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL]);
+	}
+	cfg80211_debug("ipv6 addr present: %d, addr: %pI6",
+		       req.is_ipv6_addr_present, req.ipv6_addr);
+	cfg80211_debug("port %d,  present: %d", req.port, req.is_port_present);
+	cfg80211_debug("protocol %d,  present: %d",
+		       req.protocol, req.is_protocol_present);
+
+	if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk,
+			&req.passphrase, &req.service_name)) {
+		cfg80211_err("inconsistent security params in request.");
+		ret = -EINVAL;
+		goto responder_req_failed;
+	}
+
+	cfg80211_debug("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d, csid: %d",
+		wlan_vdev_get_id(nan_vdev), req.transaction_id, req.ndp_rsp,
+		req.ndp_instance_id, req.ndp_info.ndp_app_info_len,
+		req.ncs_sk_type);
+
+	req.vdev = nan_vdev;
+	status = ucfg_nan_req_processor(nan_vdev, &req, NDP_RESPONDER_REQ);
+	ret = qdf_status_to_os_return(status);
+
+responder_req_failed:
+	if (ret)
+		wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
+
+	return ret;
+
+}
+
+/**
+ * os_if_nan_process_ndp_end_req() - NDP end request handler
+ * @psoc: pointer to psoc object
+ *
+ * @tb: parsed NL attribute list
+ * tb includes following vendor attributes:
+ * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
+ *
+ * Return: 0 on success or error code on failure
+ */
+static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc,
+					 struct nlattr **tb)
+{
+	int ret = 0;
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *nan_vdev;
+	struct nan_datapath_end_req req = {0};
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
+		cfg80211_err("Transaction ID is unavailable");
+		return -EINVAL;
+	}
+	req.transaction_id =
+		nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
+		cfg80211_err("NDP instance ID array is unavailable");
+		return -EINVAL;
+	}
+
+	req.num_ndp_instances =
+		nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
+			sizeof(uint32_t);
+	if (0 >= req.num_ndp_instances) {
+		cfg80211_err("Num NDP instances is 0");
+		return -EINVAL;
+	}
+	qdf_mem_copy(req.ndp_ids,
+		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]),
+		     req.num_ndp_instances * sizeof(uint32_t));
+
+	cfg80211_debug("sending ndp_end_req to SME, transaction_id: %d",
+		req.transaction_id);
+
+	nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_NDI_MODE,
+							    WLAN_NAN_ID);
+	if (!nan_vdev) {
+		cfg80211_err("NAN data interface is not available");
+		return -EINVAL;
+	}
+
+	req.vdev = nan_vdev;
+	status = ucfg_nan_req_processor(nan_vdev, &req, NDP_END_REQ);
+	ret = qdf_status_to_os_return(status);
+	if (ret)
+		wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
+
+	return ret;
+}
+
+int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc,
+			      const void *data, int data_len)
+{
+	uint32_t ndp_cmd_type;
+	uint16_t transaction_id;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
+	char *iface_name;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
+				    data, data_len, vendor_attr_policy)) {
+		cfg80211_err("Invalid NDP vendor command attributes");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch NDP Command Type*/
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
+		cfg80211_err("NAN datapath cmd type failed");
+		return -EINVAL;
+	}
+	ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
+		cfg80211_err("attr transaction id failed");
+		return -EINVAL;
+	}
+	transaction_id = nla_get_u16(
+			tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
+
+	if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
+		iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
+		cfg80211_err("Transaction Id: %d NDPCmd: %d iface_name: %s",
+			transaction_id, ndp_cmd_type, iface_name);
+	} else {
+		cfg80211_err("Transaction Id: %d NDPCmd: %d iface_name: unspecified",
+			transaction_id, ndp_cmd_type);
+	}
+
+	cfg80211_debug("Received NDP cmd: %d", ndp_cmd_type);
+	switch (ndp_cmd_type) {
+	case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
+		return os_if_nan_process_ndi_create(psoc, tb);
+	case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
+		return os_if_nan_process_ndi_delete(psoc, tb);
+	case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
+		return os_if_nan_process_ndp_initiator_req(psoc, tb);
+	case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
+		return os_if_nan_process_ndp_responder_req(psoc, tb);
+	case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
+		return os_if_nan_process_ndp_end_req(psoc, tb);
+	default:
+		cfg80211_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type);
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+static inline uint32_t osif_ndp_get_ndp_initiator_rsp_len(void)
+{
+	uint32_t data_len = NLMSG_HDRLEN;
+
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
+
+	return data_len;
+}
+
+/**
+ * os_if_ndp_initiator_rsp_handler() - NDP initiator response handler
+ * @vdev: pointer to vdev object
+ * @rsp_params: response parameters
+ *
+ * Following vendor event is sent to cfg80211:
+ * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
+ *         QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
+ *
+ * Return: none
+ */
+static void os_if_ndp_initiator_rsp_handler(struct wlan_objmgr_vdev *vdev,
+					struct nan_datapath_initiator_rsp *rsp)
+{
+	uint32_t data_len;
+	struct sk_buff *vendor_event;
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
+	struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
+
+	if (!rsp) {
+		cfg80211_err("Invalid NDP Initator response");
+		return;
+	}
+
+	data_len = osif_ndp_get_ndp_initiator_rsp_len();
+	vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
+				data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
+				GFP_ATOMIC);
+	if (!vendor_event) {
+		cfg80211_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+			QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
+		goto ndp_initiator_rsp_nla_failed;
+
+	if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+			rsp->transaction_id))
+		goto ndp_initiator_rsp_nla_failed;
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
+			rsp->ndp_instance_id))
+		goto ndp_initiator_rsp_nla_failed;
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
+			rsp->status))
+		goto ndp_initiator_rsp_nla_failed;
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
+			rsp->reason))
+		goto ndp_initiator_rsp_nla_failed;
+
+	cfg80211_debug("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d",
+	       rsp->transaction_id, rsp->ndp_instance_id, rsp->status,
+	       rsp->reason);
+	cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
+	return;
+ndp_initiator_rsp_nla_failed:
+	cfg80211_err("nla_put api failed");
+	kfree_skb(vendor_event);
+}
+
+static inline uint32_t osif_ndp_get_ndp_responder_rsp_len(void)
+{
+	uint32_t data_len = NLMSG_HDRLEN;
+
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
+
+	return data_len;
+}
+
+/*
+ * os_if_ndp_responder_rsp_handler() - NDP responder response handler
+ * @vdev: pointer to vdev object
+ * @rsp: response parameters
+ *
+ * Following vendor event is sent to cfg80211:
+ * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
+ *         QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
+ *
+ * Return: none
+ */
+static void os_if_ndp_responder_rsp_handler(struct wlan_objmgr_vdev *vdev,
+				      struct nan_datapath_responder_rsp *rsp)
+{
+	uint16_t data_len;
+	struct sk_buff *vendor_event;
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
+	struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
+
+	if (!rsp) {
+		cfg80211_err("Invalid NDP Responder response");
+		return;
+	}
+
+	cfg80211_debug("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d",
+		wlan_vdev_get_id(rsp->vdev), rsp->transaction_id,
+		rsp->status, rsp->reason);
+	data_len = osif_ndp_get_ndp_responder_rsp_len();
+	vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
+				data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
+				GFP_ATOMIC);
+	if (!vendor_event) {
+		cfg80211_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+	   QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE))
+		goto ndp_responder_rsp_nla_failed;
+
+	if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+	   rsp->transaction_id))
+		goto ndp_responder_rsp_nla_failed;
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
+	   rsp->status))
+		goto ndp_responder_rsp_nla_failed;
+
+	if (nla_put_u32(vendor_event,
+	   QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
+	   rsp->reason))
+		goto ndp_responder_rsp_nla_failed;
+
+	cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
+	return;
+ndp_responder_rsp_nla_failed:
+	cfg80211_err("nla_put api failed");
+	kfree_skb(vendor_event);
+}
+
+static inline uint32_t osif_ndp_get_ndp_req_ind_len(
+				struct nan_datapath_indication_event *event)
+{
+	uint32_t data_len = NLMSG_HDRLEN;
+
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_CSID].len);
+	/* allocate space including NULL terminator */
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR].len + 1);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR].len);
+	if (event->is_ipv6_addr_present)
+		data_len += nla_total_size(vendor_attr_policy[
+				QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR].len);
+	if (event->scid.scid_len)
+		data_len += nla_total_size(event->scid.scid_len);
+	if (event->ndp_info.ndp_app_info_len)
+		data_len += nla_total_size(event->ndp_info.ndp_app_info_len);
+
+	return data_len;
+}
+
+/**
+ * os_if_ndp_indication_handler() - NDP indication handler
+ * @vdev: pointer to vdev object
+ * @ind_params: indication parameters
+ *
+ * Following vendor event is sent to cfg80211:
+ * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
+ *         QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
+ * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
+ * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_CSID(4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size)
+ * QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR (16 bytes)
+ *
+ * Return: none
+ */
+static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev,
+				struct nan_datapath_indication_event *event)
+{
+	uint8_t *ifname;
+	uint16_t data_len;
+	qdf_size_t ifname_len;
+	uint32_t ndp_qos_config;
+	struct sk_buff *vendor_event;
+	enum nan_datapath_state state;
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
+	struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
+
+	if (!event) {
+		cfg80211_err("Invalid NDP Indication");
+		return;
+	}
+
+	cfg80211_debug("NDP Indication, policy: %d", event->policy);
+	state = ucfg_nan_get_ndi_state(vdev);
+	/* check if we are in middle of deleting/creating the interface */
+
+	if (state == NAN_DATA_NDI_DELETED_STATE ||
+	    state == NAN_DATA_NDI_DELETING_STATE ||
+	    state == NAN_DATA_NDI_CREATING_STATE) {
+		cfg80211_err("Data request not allowed in current NDI state: %d",
+			state);
+		return;
+	}
+
+	ifname = wlan_util_vdev_get_if_name(vdev);
+	if (!ifname) {
+		cfg80211_err("ifname is null");
+		return;
+	}
+	ifname_len = qdf_str_len(ifname);
+	if (ifname_len > IFNAMSIZ) {
+		cfg80211_err("ifname(%zu) too long", ifname_len);
+		return;
+	}
+
+	data_len = osif_ndp_get_ndp_req_ind_len(event);
+	/* notify response to the upper layer */
+	vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy,
+					NULL, data_len,
+					QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
+					GFP_ATOMIC);
+	if (!vendor_event) {
+		cfg80211_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+			QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND))
+		goto ndp_indication_nla_failed;
+
+	if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
+		    ifname_len, ifname))
+		goto ndp_indication_nla_failed;
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
+			event->service_instance_id))
+		goto ndp_indication_nla_failed;
+
+	if (nla_put(vendor_event,
+		    QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
+		    QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes))
+		goto ndp_indication_nla_failed;
+
+	if (nla_put(vendor_event,
+		    QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
+		    QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes))
+		goto ndp_indication_nla_failed;
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
+			event->ndp_instance_id))
+		goto ndp_indication_nla_failed;
+
+	if (event->ndp_info.ndp_app_info_len)
+		if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
+			    event->ndp_info.ndp_app_info_len,
+			    event->ndp_info.ndp_app_info))
+			goto ndp_indication_nla_failed;
+
+	if (event->ndp_config.ndp_cfg_len) {
+		ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg);
+		/* at present ndp config stores 4 bytes QOS info only */
+		if (nla_put_u32(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
+				ndp_qos_config))
+			goto ndp_indication_nla_failed;
+	}
+
+	if (event->scid.scid_len) {
+		if (nla_put_u32(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_NDP_CSID,
+				event->ncs_sk_type))
+			goto ndp_indication_nla_failed;
+
+		if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID,
+			    event->scid.scid_len,
+			    event->scid.scid))
+			goto ndp_indication_nla_failed;
+
+		cfg80211_debug("csid: %d, scid_len: %d",
+			       event->ncs_sk_type, event->scid.scid_len);
+
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
+				   event->scid.scid, event->scid.scid_len);
+	}
+
+	if (event->is_ipv6_addr_present) {
+		if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR,
+			    QDF_IPV6_ADDR_SIZE, event->ipv6_addr))
+			goto ndp_indication_nla_failed;
+	}
+	cfg80211_debug("ipv6 addr present: %d, addr: %pI6",
+		       event->is_ipv6_addr_present, event->ipv6_addr);
+
+	cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
+	return;
+ndp_indication_nla_failed:
+	cfg80211_err("nla_put api failed");
+	kfree_skb(vendor_event);
+}
+
+static inline uint32_t osif_ndp_get_ndp_confirm_ind_len(
+				struct nan_datapath_confirm_event *ndp_confirm)
+{
+	uint32_t ch_info_len = 0;
+	uint32_t data_len = NLMSG_HDRLEN;
+
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR].len);
+	/* allocate space including NULL terminator */
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR].len + 1);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
+	if (ndp_confirm->ndp_info.ndp_app_info_len)
+		data_len +=
+			nla_total_size(ndp_confirm->ndp_info.ndp_app_info_len);
+
+	if (ndp_confirm->is_ipv6_addr_present)
+		data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR].len);
+	if (ndp_confirm->is_port_present)
+		data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT].len);
+	if (ndp_confirm->is_protocol_present)
+		data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL].len);
+
+	/* ch_info is a nested array of following attributes */
+	ch_info_len += nla_total_size(
+		vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL].len);
+	ch_info_len += nla_total_size(
+		vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH].len);
+	ch_info_len += nla_total_size(
+		vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_NSS].len);
+
+	if (ndp_confirm->num_channels)
+		data_len += ndp_confirm->num_channels *
+				nla_total_size(ch_info_len);
+
+	return data_len;
+}
+
+static QDF_STATUS os_if_ndp_confirm_pack_ch_info(struct sk_buff *event,
+				struct nan_datapath_confirm_event *ndp_confirm)
+{
+	int idx = 0;
+	struct nlattr *ch_array, *ch_element;
+
+	cfg80211_debug("num_ch: %d", ndp_confirm->num_channels);
+	if (!ndp_confirm->num_channels)
+		return QDF_STATUS_SUCCESS;
+
+	ch_array = nla_nest_start(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO);
+	if (!ch_array)
+		return QDF_STATUS_E_FAULT;
+
+	for (idx = 0; idx < ndp_confirm->num_channels; idx++) {
+		cfg80211_debug("ch[%d]: freq: %d, width: %d, nss: %d",
+			       idx, ndp_confirm->ch[idx].channel,
+			       ndp_confirm->ch[idx].ch_width,
+			       ndp_confirm->ch[idx].nss);
+		ch_element = nla_nest_start(event, idx);
+		if (!ch_element)
+			return QDF_STATUS_E_FAULT;
+
+		if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL,
+				ndp_confirm->ch[idx].channel))
+			return QDF_STATUS_E_FAULT;
+
+		if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH,
+				ndp_confirm->ch[idx].ch_width))
+			return QDF_STATUS_E_FAULT;
+
+		if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_NSS,
+				ndp_confirm->ch[idx].nss))
+			return QDF_STATUS_E_FAULT;
+		nla_nest_end(event, ch_element);
+	}
+	nla_nest_end(event, ch_array);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * os_if_ndp_confirm_ind_handler() - NDP confirm indication handler
+ * @vdev: pointer to vdev object
+ * @ind_params: indication parameters
+ *
+ * Following vendor event is sent to cfg80211:
+ * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
+ *         QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
+ * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
+ * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR (16 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT (2 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL (1 byte)
+ *
+ * Return: none
+ */
+static void
+os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev,
+			      struct nan_datapath_confirm_event *ndp_confirm)
+{
+	int idx = 0;
+	uint8_t *ifname;
+	uint32_t data_len;
+	QDF_STATUS status;
+	qdf_size_t ifname_len;
+	struct nan_callbacks cb_obj;
+	struct sk_buff *vendor_event;
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
+	struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
+
+	if (!ndp_confirm) {
+		cfg80211_err("Invalid NDP Initator response");
+		return;
+	}
+
+	status = ucfg_nan_get_callbacks(psoc, &cb_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cfg80211_err("couldn't get callbacks");
+		return;
+	}
+
+	/* ndp_confirm is called each time user generated ndp req succeeds */
+	idx = cb_obj.get_peer_idx(wlan_vdev_get_id(vdev),
+				&ndp_confirm->peer_ndi_mac_addr);
+
+	if (idx < 0)
+		cfg80211_err("can't find addr: %pM in vdev_id: %d, peer table.",
+			&ndp_confirm->peer_ndi_mac_addr,
+			wlan_vdev_get_id(vdev));
+	else if (ndp_confirm->rsp_code == NAN_DATAPATH_RESPONSE_ACCEPT) {
+		uint32_t active_sessions =
+			ucfg_nan_get_active_ndp_sessions(vdev, idx);
+		ucfg_nan_set_active_ndp_sessions(vdev, active_sessions + 1,
+						 idx);
+	}
+
+	ifname = wlan_util_vdev_get_if_name(vdev);
+	if (!ifname) {
+		cfg80211_err("ifname is null");
+		return;
+	}
+	ifname_len = qdf_str_len(ifname);
+	if (ifname_len > IFNAMSIZ) {
+		cfg80211_err("ifname(%zu) too long", ifname_len);
+		return;
+	}
+
+	data_len = osif_ndp_get_ndp_confirm_ind_len(ndp_confirm);
+	vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
+				data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
+				GFP_ATOMIC);
+	if (!vendor_event) {
+		cfg80211_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+			QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
+		goto ndp_confirm_nla_failed;
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
+			ndp_confirm->ndp_instance_id))
+		goto ndp_confirm_nla_failed;
+
+	if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
+		    QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
+		goto ndp_confirm_nla_failed;
+
+	if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
+		    ifname_len, ifname))
+		goto ndp_confirm_nla_failed;
+
+	if (ndp_confirm->ndp_info.ndp_app_info_len &&
+		nla_put(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
+			ndp_confirm->ndp_info.ndp_app_info_len,
+			ndp_confirm->ndp_info.ndp_app_info))
+		goto ndp_confirm_nla_failed;
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
+			ndp_confirm->rsp_code))
+		goto ndp_confirm_nla_failed;
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
+			ndp_confirm->reason_code))
+		goto ndp_confirm_nla_failed;
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS,
+			ndp_confirm->num_channels))
+		goto ndp_confirm_nla_failed;
+
+	status = os_if_ndp_confirm_pack_ch_info(vendor_event, ndp_confirm);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto ndp_confirm_nla_failed;
+
+	if (ndp_confirm->is_ipv6_addr_present) {
+		if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR,
+			    QDF_IPV6_ADDR_SIZE, ndp_confirm->ipv6_addr))
+			goto ndp_confirm_nla_failed;
+	}
+	if (ndp_confirm->is_port_present)
+		if (nla_put_u16(vendor_event,
+				QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT,
+				ndp_confirm->port))
+			goto ndp_confirm_nla_failed;
+	if (ndp_confirm->is_protocol_present)
+		if (nla_put_u8(vendor_event,
+			       QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL,
+			       ndp_confirm->protocol))
+			goto ndp_confirm_nla_failed;
+	cfg80211_debug("ipv6 addr present: %d, addr: %pI6",
+		       ndp_confirm->is_ipv6_addr_present,
+		       ndp_confirm->ipv6_addr);
+	cfg80211_debug("port %d,  present: %d",
+		       ndp_confirm->port, ndp_confirm->is_port_present);
+	cfg80211_debug("protocol %d,  present: %d",
+		       ndp_confirm->protocol, ndp_confirm->is_protocol_present);
+
+	cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
+	cfg80211_debug("NDP confim sent, ndp instance id: %d, peer addr: %pM rsp_code: %d, reason_code: %d",
+		       ndp_confirm->ndp_instance_id,
+		       ndp_confirm->peer_ndi_mac_addr.bytes,
+		       ndp_confirm->rsp_code, ndp_confirm->reason_code);
+
+	cfg80211_debug("NDP confim, ndp app info dump");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
+			   ndp_confirm->ndp_info.ndp_app_info,
+			   ndp_confirm->ndp_info.ndp_app_info_len);
+	return;
+ndp_confirm_nla_failed:
+	cfg80211_err("nla_put api failed");
+	kfree_skb(vendor_event);
+}
+
+static inline uint32_t osif_ndp_get_ndp_end_rsp_len(void)
+{
+	uint32_t data_len = NLMSG_HDRLEN;
+
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len);
+
+	return data_len;
+}
+
+/**
+ * os_if_ndp_end_rsp_handler() - NDP end response handler
+ * @vdev: pointer to vdev object
+ * @rsp_params: response parameters
+ *
+ * Following vendor event is sent to cfg80211:
+ * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
+ *         QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
+ *
+ * Return: none
+ */
+static void os_if_ndp_end_rsp_handler(struct wlan_objmgr_vdev *vdev,
+				struct nan_datapath_end_rsp_event *rsp)
+{
+	uint32_t data_len;
+	struct sk_buff *vendor_event;
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
+	struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
+
+	if (!rsp) {
+		cfg80211_err("Invalid ndp end response");
+		return;
+	}
+
+	data_len = osif_ndp_get_ndp_end_rsp_len();
+	vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
+				data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
+				GFP_ATOMIC);
+	if (!vendor_event) {
+		cfg80211_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+			QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE))
+		goto ndp_end_rsp_nla_failed;
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
+			rsp->status))
+		goto ndp_end_rsp_nla_failed;
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
+			rsp->reason))
+		goto ndp_end_rsp_nla_failed;
+
+	if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+			rsp->transaction_id))
+		goto ndp_end_rsp_nla_failed;
+
+	cfg80211_debug("NDP End rsp sent, transaction id: %d, status: %d, reason: %d",
+	       rsp->transaction_id, rsp->status, rsp->reason);
+	cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
+	return;
+
+ndp_end_rsp_nla_failed:
+	cfg80211_err("nla_put api failed");
+	kfree_skb(vendor_event);
+}
+
+static inline uint32_t osif_ndp_get_ndp_end_ind_len(
+			struct nan_datapath_end_indication_event *end_ind)
+{
+	uint32_t data_len = NLMSG_HDRLEN;
+
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
+	if (end_ind->num_ndp_ids)
+		data_len += nla_total_size(end_ind->num_ndp_ids *
+							sizeof(uint32_t));
+
+	return data_len;
+}
+
+/**
+ * os_if_ndp_end_ind_handler() - NDP end indication handler
+ * @vdev: pointer to vdev object
+ * @ind_params: indication parameters
+ *
+ * Following vendor event is sent to cfg80211:
+ * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
+ *         QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances)
+ *
+ * Return: none
+ */
+static void os_if_ndp_end_ind_handler(struct wlan_objmgr_vdev *vdev,
+			struct nan_datapath_end_indication_event *end_ind)
+{
+	QDF_STATUS status;
+	uint32_t data_len, i;
+	struct nan_callbacks cb_obj;
+	uint32_t *ndp_instance_array;
+	struct sk_buff *vendor_event;
+	struct wlan_objmgr_vdev *vdev_itr;
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
+	struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
+
+	status = ucfg_nan_get_callbacks(psoc, &cb_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cfg80211_err("failed to get callbacks");
+		return;
+	}
+
+	if (!end_ind) {
+		cfg80211_err("Invalid ndp end indication");
+		return;
+	}
+
+	ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids *
+		sizeof(*ndp_instance_array));
+	if (!ndp_instance_array) {
+		cfg80211_err("Failed to allocate ndp_instance_array");
+		return;
+	}
+	for (i = 0; i < end_ind->num_ndp_ids; i++) {
+		int idx = 0;
+
+		ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
+		vdev_itr = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+				end_ind->ndp_map[i].vdev_id, WLAN_NAN_ID);
+
+		if (vdev_itr == NULL) {
+			cfg80211_err("vdev not found for vdev_id: %d",
+				end_ind->ndp_map[i].vdev_id);
+			continue;
+		}
+
+		idx = cb_obj.get_peer_idx(wlan_vdev_get_id(vdev_itr),
+				&end_ind->ndp_map[i].peer_ndi_mac_addr);
+		if (idx < 0) {
+			cfg80211_err("can't find addr: %pM in sta_ctx.",
+				&end_ind->ndp_map[i].peer_ndi_mac_addr);
+			wlan_objmgr_vdev_release_ref(vdev_itr, WLAN_NAN_ID);
+			continue;
+		}
+		/* save the value of active sessions on each peer */
+		ucfg_nan_set_active_ndp_sessions(vdev_itr,
+				end_ind->ndp_map[i].num_active_ndp_sessions,
+				idx);
+		wlan_objmgr_vdev_release_ref(vdev_itr, WLAN_NAN_ID);
+	}
+
+	data_len = osif_ndp_get_ndp_end_ind_len(end_ind);
+	vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
+				data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
+				GFP_ATOMIC);
+	if (!vendor_event) {
+		cfg80211_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+			QCA_WLAN_VENDOR_ATTR_NDP_END_IND))
+		goto ndp_end_ind_nla_failed;
+
+	if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
+			end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
+			ndp_instance_array))
+		goto ndp_end_ind_nla_failed;
+
+	cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
+	qdf_mem_free(ndp_instance_array);
+	return;
+
+ndp_end_ind_nla_failed:
+	cfg80211_err("nla_put api failed");
+	kfree_skb(vendor_event);
+	qdf_mem_free(ndp_instance_array);
+}
+
+/**
+ * os_if_new_peer_ind_handler() - NDP new peer indication handler
+ * @adapter: pointer to adapter context
+ * @ind_params: indication parameters
+ *
+ * Return: none
+ */
+static void os_if_new_peer_ind_handler(struct wlan_objmgr_vdev *vdev,
+			struct nan_datapath_peer_ind *peer_ind)
+{
+	int ret;
+	QDF_STATUS status;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
+	uint32_t active_peers = ucfg_nan_get_active_peers(vdev);
+	struct nan_callbacks cb_obj;
+
+	if (NULL == peer_ind) {
+		cfg80211_err("Invalid new NDP peer params");
+		return;
+	}
+
+	status = ucfg_nan_get_callbacks(psoc, &cb_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cfg80211_err("failed to get callbacks");
+		return;
+	}
+
+	cfg80211_debug("vdev_id: %d, peer_mac: %pM, sta_id: %d",
+		       vdev_id, peer_ind->peer_mac_addr.bytes,
+		       peer_ind->sta_id);
+	ret = cb_obj.new_peer_ind(vdev_id, peer_ind->sta_id,
+				&peer_ind->peer_mac_addr,
+				(active_peers == 0 ? true : false));
+	if (ret) {
+		cfg80211_err("new peer handling at HDD failed %d", ret);
+		return;
+	}
+
+	active_peers++;
+	ucfg_nan_set_active_peers(vdev, active_peers);
+	cfg80211_debug("vdev_id: %d, num_peers: %d", vdev_id, active_peers);
+}
+
+/**
+ * os_if_peer_departed_ind_handler() - Handle NDP peer departed indication
+ * @adapter: pointer to adapter context
+ * @ind_params: indication parameters
+ *
+ * Return: none
+ */
+static void os_if_peer_departed_ind_handler(struct wlan_objmgr_vdev *vdev,
+			struct nan_datapath_peer_ind *peer_ind)
+{
+	QDF_STATUS status;
+	struct nan_callbacks cb_obj;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
+	uint32_t active_peers = ucfg_nan_get_active_peers(vdev);
+
+	status = ucfg_nan_get_callbacks(psoc, &cb_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cfg80211_err("failed to get callbacks");
+		return;
+	}
+
+	if (NULL == peer_ind) {
+		cfg80211_err("Invalid new NDP peer params");
+		return;
+	}
+	cfg80211_debug("vdev_id: %d, peer_mac: %pM, sta_id: %d",
+		       vdev_id, peer_ind->peer_mac_addr.bytes,
+		       peer_ind->sta_id);
+	active_peers--;
+	ucfg_nan_set_active_peers(vdev, active_peers);
+	cb_obj.peer_departed_ind(vdev_id, peer_ind->sta_id,
+				&peer_ind->peer_mac_addr,
+				(active_peers == 0 ? true : false));
+}
+
+static inline uint32_t osif_ndp_get_ndi_create_rsp_len(void)
+{
+	uint32_t data_len = NLMSG_HDRLEN;
+
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
+
+	return data_len;
+}
+
+/**
+ * os_if_ndp_iface_create_rsp_handler() - NDP iface create response handler
+ * @adapter: pointer to adapter context
+ * @rsp_params: response parameters
+ *
+ * The function is expected to send a response back to the user space
+ * even if the creation of BSS has failed
+ *
+ * Following vendor event is sent to cfg80211:
+ * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
+ * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
+ *
+ * Return: none
+ */
+static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc,
+					       struct wlan_objmgr_vdev *vdev,
+					       void *rsp_params)
+{
+	uint32_t data_len;
+	QDF_STATUS status;
+	bool create_fail = false;
+	struct nan_callbacks cb_obj;
+	struct sk_buff *vendor_event;
+	uint16_t create_transaction_id;
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
+	struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
+	uint32_t create_status = NAN_DATAPATH_RSP_STATUS_ERROR;
+	uint32_t create_reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED;
+	struct nan_datapath_inf_create_rsp *ndi_rsp =
+			(struct nan_datapath_inf_create_rsp *)rsp_params;
+
+	status = ucfg_nan_get_callbacks(psoc, &cb_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cfg80211_err("Couldn't get ballback object");
+		return;
+	}
+
+	if (ndi_rsp) {
+		create_status = ndi_rsp->status;
+		create_reason = ndi_rsp->reason;
+	} else {
+		cfg80211_err("Invalid ndi create response");
+		create_fail = true;
+	}
+
+	create_transaction_id = ucfg_nan_get_ndp_create_transaction_id(vdev);
+	data_len = osif_ndp_get_ndi_create_rsp_len();
+	/* notify response to the upper layer */
+	vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy,
+				NULL,
+				data_len,
+				QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
+				GFP_KERNEL);
+	if (!vendor_event) {
+		cfg80211_err("cfg80211_vendor_event_alloc failed");
+		create_fail = true;
+		goto close_ndi;
+	}
+
+	/* Sub vendor command */
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+		QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
+		cfg80211_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail");
+		goto nla_put_failure;
+	}
+
+	/* Transaction id */
+	if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+		create_transaction_id)) {
+		cfg80211_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
+		goto nla_put_failure;
+	}
+
+	/* Status code */
+	if (nla_put_u32(vendor_event,
+		QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
+		create_status)) {
+		cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
+		goto nla_put_failure;
+	}
+
+	/* Status return value */
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
+			create_reason)) {
+		cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
+		goto nla_put_failure;
+	}
+
+	cfg80211_debug("sub command: %d, value: %d",
+		       QCA_NL80211_VENDOR_SUBCMD_NDP,
+		       QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE);
+	cfg80211_debug("create transaction id: %d, value: %d",
+		       QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+		       create_transaction_id);
+	cfg80211_debug("status code: %d, value: %d",
+		       QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
+		       create_status);
+	cfg80211_debug("Return value: %d, value: %d",
+		       QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
+		       create_reason);
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+
+	if (!create_fail) {
+		/* update txrx queues and register self sta */
+		cb_obj.drv_ndi_create_rsp_handler(wlan_vdev_get_id(vdev),
+						  ndi_rsp);
+	} else {
+		cfg80211_err("NDI interface creation failed with reason %d",
+			     create_reason);
+		goto close_ndi;
+	}
+
+	return;
+
+nla_put_failure:
+	kfree_skb(vendor_event);
+close_ndi:
+	cb_obj.ndi_close(wlan_vdev_get_id(vdev));
+	return;
+}
+
+/**
+ * os_if_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
+ * @adapter: pointer to adapter context
+ * @rsp_params: response parameters
+ *
+ * Return: none
+ */
+static void os_if_ndp_iface_delete_rsp_handler(struct wlan_objmgr_psoc *psoc,
+					      struct wlan_objmgr_vdev *vdev,
+					      void *rsp_params)
+{
+	QDF_STATUS status;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	struct nan_datapath_inf_delete_rsp *ndi_rsp = rsp_params;
+	struct nan_callbacks cb_obj;
+
+	if (!ndi_rsp) {
+		cfg80211_err("Invalid ndi delete response");
+		return;
+	}
+
+	status = ucfg_nan_get_callbacks(psoc, &cb_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cfg80211_err("Couldn't get ballback object");
+		return;
+	}
+
+	if (ndi_rsp->status == NAN_DATAPATH_RSP_STATUS_SUCCESS)
+		cfg80211_debug("NDI BSS successfully stopped");
+	else
+		cfg80211_debug("NDI BSS stop failed with reason %d",
+			       ndi_rsp->reason);
+
+	ucfg_nan_set_ndi_delete_rsp_reason(vdev, ndi_rsp->reason);
+	ucfg_nan_set_ndi_delete_rsp_status(vdev, ndi_rsp->status);
+	cb_obj.drv_ndi_delete_rsp_handler(vdev_id);
+}
+
+static inline uint32_t osif_ndp_get_ndp_sch_update_ind_len(
+			struct nan_datapath_sch_update_event *sch_update)
+{
+	uint32_t ch_info_len = 0;
+	uint32_t data_len = NLMSG_HDRLEN;
+
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR].len);
+	if (sch_update->num_ndp_instances)
+		data_len += nla_total_size(sch_update->num_ndp_instances *
+					   sizeof(uint32_t));
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS].len);
+	/* ch_info is a nested array of following attributes */
+	ch_info_len += nla_total_size(
+		vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL].len);
+	ch_info_len += nla_total_size(
+		vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH].len);
+	ch_info_len += nla_total_size(
+		vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_NSS].len);
+
+	if (sch_update->num_ndp_instances)
+		data_len += sch_update->num_ndp_instances *
+						nla_total_size(ch_info_len);
+
+	return data_len;
+}
+
+static QDF_STATUS os_if_ndp_sch_update_pack_ch_info(struct sk_buff *event,
+			struct nan_datapath_sch_update_event *sch_update)
+{
+	int idx = 0;
+	struct nlattr *ch_array, *ch_element;
+
+	cfg80211_debug("num_ch: %d", sch_update->num_channels);
+	if (!sch_update->num_channels)
+		return QDF_STATUS_SUCCESS;
+
+	ch_array = nla_nest_start(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO);
+	if (!ch_array)
+		return QDF_STATUS_E_FAULT;
+
+	for (idx = 0; idx < sch_update->num_channels; idx++) {
+		cfg80211_debug("ch[%d]: freq: %d, width: %d, nss: %d",
+			       idx, sch_update->ch[idx].channel,
+			       sch_update->ch[idx].ch_width,
+			       sch_update->ch[idx].nss);
+		ch_element = nla_nest_start(event, idx);
+		if (!ch_element)
+			return QDF_STATUS_E_FAULT;
+
+		if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL,
+				sch_update->ch[idx].channel))
+			return QDF_STATUS_E_FAULT;
+
+		if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH,
+				sch_update->ch[idx].ch_width))
+			return QDF_STATUS_E_FAULT;
+
+		if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_NSS,
+				sch_update->ch[idx].nss))
+			return QDF_STATUS_E_FAULT;
+		nla_nest_end(event, ch_element);
+	}
+	nla_nest_end(event, ch_array);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * os_if_ndp_sch_update_ind_handler() - NDP schedule update handler
+ * @vdev: vdev object pointer
+ * @ind: sch update pointer
+ *
+ * Following vendor event is sent to cfg80211:
+ *
+ * Return: none
+ */
+static void os_if_ndp_sch_update_ind_handler(struct wlan_objmgr_vdev *vdev,
+					     void *ind)
+{
+	int idx = 0;
+	uint8_t *ifname;
+	QDF_STATUS status;
+	uint32_t data_len;
+	uint8_t ifname_len;
+	struct sk_buff *vendor_event;
+	struct nan_datapath_sch_update_event *sch_update = ind;
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
+	struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
+
+	if (!sch_update) {
+		cfg80211_err("Invalid sch update params");
+		return;
+	}
+
+	ifname = wlan_util_vdev_get_if_name(vdev);
+	if (!ifname) {
+		cfg80211_err("ifname is null");
+		return;
+	}
+	ifname_len = qdf_str_len(ifname);
+	if (ifname_len > IFNAMSIZ) {
+		cfg80211_err("ifname(%d) too long", ifname_len);
+		return;
+	}
+
+	data_len = osif_ndp_get_ndp_sch_update_ind_len(sch_update);
+	vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
+				data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
+				GFP_ATOMIC);
+	if (!vendor_event) {
+		cfg80211_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+			QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND))
+		goto ndp_sch_ind_nla_failed;
+
+	if (nla_put(vendor_event,
+		    QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
+		    QDF_MAC_ADDR_SIZE, sch_update->peer_addr.bytes))
+		goto ndp_sch_ind_nla_failed;
+
+	if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
+		    sch_update->num_ndp_instances * sizeof(uint32_t),
+		    sch_update->ndp_instances))
+		goto ndp_sch_ind_nla_failed;
+
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON,
+			sch_update->flags))
+		goto ndp_sch_ind_nla_failed;
+
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS,
+			sch_update->num_channels))
+		goto ndp_sch_ind_nla_failed;
+
+	status = os_if_ndp_sch_update_pack_ch_info(vendor_event, sch_update);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto ndp_sch_ind_nla_failed;
+
+	cfg80211_debug("Flags: %d, num_instance_id: %d", sch_update->flags,
+		       sch_update->num_ndp_instances);
+
+	for (idx = 0; idx < sch_update->num_ndp_instances; idx++)
+		cfg80211_debug("ndp_instance[%d]: %d", idx,
+			       sch_update->ndp_instances[idx]);
+
+	cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
+	return;
+
+ndp_sch_ind_nla_failed:
+	cfg80211_err("nla_put api failed");
+	kfree_skb(vendor_event);
+}
+
+void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc,
+			     struct wlan_objmgr_vdev *vdev,
+			     uint32_t type, void *msg)
+{
+	switch (type) {
+	case NAN_DATAPATH_INF_CREATE_RSP:
+		os_if_ndp_iface_create_rsp_handler(psoc, vdev, msg);
+		break;
+	case NAN_DATAPATH_INF_DELETE_RSP:
+		os_if_ndp_iface_delete_rsp_handler(psoc, vdev, msg);
+		break;
+	case NDP_CONFIRM:
+		os_if_ndp_confirm_ind_handler(vdev, msg);
+		break;
+	case NDP_INITIATOR_RSP:
+		os_if_ndp_initiator_rsp_handler(vdev, msg);
+		break;
+	case NDP_INDICATION:
+		os_if_ndp_indication_handler(vdev, msg);
+		break;
+	case NDP_NEW_PEER:
+		os_if_new_peer_ind_handler(vdev, msg);
+		break;
+	case NDP_RESPONDER_RSP:
+		os_if_ndp_responder_rsp_handler(vdev, msg);
+		break;
+	case NDP_END_RSP:
+		os_if_ndp_end_rsp_handler(vdev, msg);
+		break;
+	case NDP_END_IND:
+		os_if_ndp_end_ind_handler(vdev, msg);
+		break;
+	case NDP_PEER_DEPARTED:
+		os_if_peer_departed_ind_handler(vdev, msg);
+		break;
+	case NDP_SCHEDULE_UPDATE:
+		os_if_ndp_sch_update_ind_handler(vdev, msg);
+		break;
+	default:
+		break;
+	}
+}
+
+int os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
+				     struct nan_callbacks *cb_obj)
+{
+	return ucfg_nan_register_hdd_callbacks(psoc, cb_obj,
+						os_if_nan_event_handler);
+}
+
+int os_if_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc,
+				     struct nan_callbacks *cb_obj)
+{
+	return ucfg_nan_register_lim_callbacks(psoc, cb_obj);
+}
+
+void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id, bool success)
+{
+	struct nan_datapath_inf_create_rsp rsp = {0};
+	struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+						psoc, vdev_id, WLAN_NAN_ID);
+
+	if (!vdev) {
+		cfg80211_err("vdev is null");
+		return;
+	}
+
+	if (success) {
+		rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS;
+		rsp.reason = 0;
+		os_if_nan_event_handler(psoc, vdev,
+					NAN_DATAPATH_INF_CREATE_RSP, &rsp);
+	} else {
+		rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
+		rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED;
+		os_if_nan_event_handler(psoc, vdev,
+					NAN_DATAPATH_INF_CREATE_RSP, &rsp);
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
+}
+
+void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id, bool success)
+{
+	struct nan_datapath_inf_delete_rsp rsp = {0};
+	struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+						psoc, vdev_id, WLAN_NAN_ID);
+	if (!vdev) {
+		cfg80211_err("vdev is null");
+		return;
+	}
+
+	if (success) {
+		rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS;
+		rsp.reason = 0;
+		os_if_nan_event_handler(psoc, vdev,
+					NAN_DATAPATH_INF_DELETE_RSP, &rsp);
+	} else {
+		rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
+		rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_DELETE_FAILED;
+		os_if_nan_event_handler(psoc, vdev,
+					NAN_DATAPATH_INF_DELETE_RSP, &rsp);
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
+}
+
+static inline uint32_t osif_ndp_get_ndi_delete_rsp_len(void)
+{
+	uint32_t data_len = NLMSG_HDRLEN;
+
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len);
+	data_len += nla_total_size(vendor_attr_policy[
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
+
+	return data_len;
+}
+
+void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev)
+{
+	uint32_t data_len;
+	struct sk_buff *vendor_event;
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
+	struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
+
+	/*
+	 * The virtual adapters are stopped and closed even during
+	 * driver unload or stop, the service layer is not required
+	 * to be informed in that case (response is not expected)
+	 */
+	if (NAN_DATA_NDI_DELETING_STATE != ucfg_nan_get_ndi_state(vdev)) {
+		cfg80211_err("NDI interface deleted");
+		return;
+	}
+
+	data_len = osif_ndp_get_ndi_delete_rsp_len();
+	/* notify response to the upper layer */
+	vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
+			data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
+			GFP_KERNEL);
+
+	if (!vendor_event) {
+		cfg80211_err("cfg80211_vendor_event_alloc failed");
+		return;
+	}
+
+	/* Sub vendor command goes first */
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+			QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
+		cfg80211_err("VENDOR_ATTR_NDP_SUBCMD put fail");
+		goto failure;
+	}
+
+	/* Transaction id */
+	if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+			ucfg_nan_get_ndp_delete_transaction_id(vdev))) {
+		cfg80211_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
+		goto failure;
+	}
+
+	/* Status code */
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
+			ucfg_nan_get_ndi_delete_rsp_status(vdev))) {
+		cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
+		goto failure;
+	}
+
+	/* Status return value */
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
+			ucfg_nan_get_ndi_delete_rsp_reason(vdev))) {
+		cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
+		goto failure;
+	}
+
+	cfg80211_debug("sub command: %d, value: %d",
+		       QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+		       QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
+	cfg80211_debug("delete transaction id: %d, value: %d",
+		       QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+		       ucfg_nan_get_ndp_delete_transaction_id(vdev));
+	cfg80211_debug("status code: %d, value: %d",
+		       QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
+		       ucfg_nan_get_ndi_delete_rsp_status(vdev));
+	cfg80211_debug("Return value: %d, value: %d",
+		       QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
+		       ucfg_nan_get_ndi_delete_rsp_reason(vdev));
+
+	ucfg_nan_set_ndp_delete_transaction_id(vdev, 0);
+	ucfg_nan_set_ndi_state(vdev, NAN_DATA_NDI_DELETED_STATE);
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+
+	return;
+failure:
+	kfree_skb(vendor_event);
+}
diff --git a/uapi/linux/a_debug.h b/uapi/linux/a_debug.h
new file mode 100644
index 0000000..db21bc2
--- /dev/null
+++ b/uapi/linux/a_debug.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2013-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.
+ */
+
+#ifndef _A_DEBUG_H_
+#define _A_DEBUG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <a_types.h>
+#include "osapi_linux.h"
+
+/* standard debug print masks bits 0..7 */
+#define ATH_DEBUG_ERR   (1 << 0)        /* errors */
+#define ATH_DEBUG_WARN  (1 << 1)        /* warnings */
+#define ATH_DEBUG_INFO  (1 << 2)        /* informational (module startup info) */
+#define ATH_DEBUG_TRC   (1 << 3)        /* generic function call tracing */
+#define ATH_DEBUG_RSVD1 (1 << 4)
+#define ATH_DEBUG_RSVD2 (1 << 5)
+#define ATH_DEBUG_RSVD3 (1 << 6)
+#define ATH_DEBUG_RSVD4 (1 << 7)
+
+#define ATH_DEBUG_MASK_DEFAULTS  (ATH_DEBUG_ERR | ATH_DEBUG_WARN)
+#define ATH_DEBUG_ANY  0xFFFF
+
+/* other aliases used throughout */
+#define ATH_DEBUG_ERROR   ATH_DEBUG_ERR
+#define ATH_LOG_ERR       ATH_DEBUG_ERR
+#define ATH_LOG_INF       ATH_DEBUG_INFO
+#define ATH_LOG_TRC       ATH_DEBUG_TRC
+#define ATH_DEBUG_TRACE   ATH_DEBUG_TRC
+#define ATH_DEBUG_INIT    ATH_DEBUG_INFO
+
+/* bits 8..31 are module-specific masks */
+#define ATH_DEBUG_MODULE_MASK_SHIFT   8
+
+/* macro to make a module-specific masks */
+#define ATH_DEBUG_MAKE_MODULE_MASK(index)  (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index)))
+
+void debug_dump_bytes(A_UCHAR *buffer, A_UINT16 length,
+		      char *pDescription);
+
+/* Debug support on a per-module basis
+ *
+ * Usage:
+ *
+ *   Each module can utilize it's own debug mask variable.  A set of commonly used
+ *   masks are provided (ERRORS, WARNINGS, TRACE etc..).  It is up to each module
+ *   to define module-specific masks using the macros above.
+ *
+ *   Each module defines a single debug mask variable debug_XXX where the "name" of the module is
+ *   common to all C-files within that module.  This requires every C-file that includes a_debug.h
+ *   to define the module name in that file.
+ *
+ *   Example:
+ *
+ *   #define ATH_MODULE_NAME htc
+ *   #include "a_debug.h"
+ *
+ *   This will define a debug mask structure called debug_htc and all debug macros will reference this
+ *   variable.
+ *
+ *   A module can define module-specific bit masks using the ATH_DEBUG_MAKE_MODULE_MASK() macro:
+ *
+ *      #define ATH_DEBUG_MY_MASK1  ATH_DEBUG_MAKE_MODULE_MASK(0)
+ *      #define ATH_DEBUG_MY_MASK2  ATH_DEBUG_MAKE_MODULE_MASK(1)
+ *
+ *   The instantiation of the debug structure should be made by the module.  When a module is
+ *   instantiated, the module can set a description string, a default mask and an array of description
+ *   entries containing information on each module-defined debug mask.
+ *   NOTE: The instantiation is statically allocated, only one instance can exist per module.
+ *
+ *   Example:
+ *
+ *
+ *   #define ATH_DEBUG_BMI  ATH_DEBUG_MAKE_MODULE_MASK(0)
+ *
+ *   #ifdef DEBUG
+ *   static ATH_DEBUG_MASK_DESCRIPTION bmi_debug_desc[] = {
+ *       { ATH_DEBUG_BMI , "BMI Tracing"},   <== description of the module specific mask
+ *   };
+ *
+ *   ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
+ *                                    "bmi"  <== module name
+ *                                    "Boot Manager Interface",  <== description of module
+ *                                    ATH_DEBUG_MASK_DEFAULTS,          <== defaults
+ *                                    ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
+ *                                    bmi_debug_desc);
+ *
+ *   #endif
+ *
+ *  A module can optionally register it's debug module information in order for other tools to change the
+ *  bit mask at runtime.  A module can call  A_REGISTER_MODULE_DEBUG_INFO() in it's module
+ *  init code.  This macro can be called multiple times without consequence.  The debug info maintains
+ *  state to indicate whether the information was previously registered.
+ *
+ * */
+
+#define ATH_DEBUG_MAX_MASK_DESC_LENGTH   32
+#define ATH_DEBUG_MAX_MOD_DESC_LENGTH    64
+
+typedef struct {
+	A_UINT32 Mask;
+	A_CHAR Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH];
+} ATH_DEBUG_MASK_DESCRIPTION;
+
+#define ATH_DEBUG_INFO_FLAGS_REGISTERED (1 << 0)
+
+typedef struct _ATH_DEBUG_MODULE_DBG_INFO {
+	struct _ATH_DEBUG_MODULE_DBG_INFO *pNext;
+	A_CHAR ModuleName[16];
+	A_CHAR ModuleDescription[ATH_DEBUG_MAX_MOD_DESC_LENGTH];
+	A_UINT32 Flags;
+	A_UINT32 CurrentMask;
+	int MaxDescriptions;
+	ATH_DEBUG_MASK_DESCRIPTION *pMaskDescriptions;          /* pointer to array of descriptions */
+} ATH_DEBUG_MODULE_DBG_INFO;
+
+#define ATH_DEBUG_DESCRIPTION_COUNT(d)  (int)((sizeof((d))) / (sizeof(ATH_DEBUG_MASK_DESCRIPTION)))
+
+#define GET_ATH_MODULE_DEBUG_VAR_NAME(s) _XGET_ATH_MODULE_NAME_DEBUG_(s)
+#define GET_ATH_MODULE_DEBUG_VAR_MASK(s) _XGET_ATH_MODULE_NAME_DEBUG_(s).CurrentMask
+#define _XGET_ATH_MODULE_NAME_DEBUG_(s) debug_ ## s
+
+#ifdef WLAN_DEBUG
+
+/* for source files that will instantiate the debug variables */
+#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s, name, moddesc, initmask, count, descriptions) \
+	ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s) = \
+	{NULL, (name), (moddesc), 0, (initmask), (count), (descriptions)}
+
+#ifdef ATH_MODULE_NAME
+extern ATH_DEBUG_MODULE_DBG_INFO
+GET_ATH_MODULE_DEBUG_VAR_NAME(ATH_MODULE_NAME);
+#define AR_DEBUG_LVL_CHECK(lvl) (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (lvl))
+#endif /* ATH_MODULE_NAME */
+
+#define ATH_DEBUG_SET_DEBUG_MASK(s, lvl) GET_ATH_MODULE_DEBUG_VAR_MASK(s) = (lvl)
+
+#define ATH_DEBUG_DECLARE_EXTERN(s) \
+	extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s)
+
+#define AR_DEBUG_PRINTBUF(buffer, length, desc) debug_dump_bytes(buffer, length, desc)
+
+#define AR_DEBUG_ASSERT A_ASSERT
+
+void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo);
+void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo);
+#ifdef A_SIMOS_DEVHOST
+#define A_DUMP_MODULE_DEBUG_INFO(s) a_dump_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s)))
+#define A_REGISTER_MODULE_DEBUG_INFO(s) a_register_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s)))
+#else
+#define A_DUMP_MODULE_DEBUG_INFO(s)
+#define A_REGISTER_MODULE_DEBUG_INFO(s)
+#endif
+
+#else                           /* !DEBUG */
+/* NON DEBUG */
+#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s, name, moddesc, initmask, count, descriptions)
+#define AR_DEBUG_LVL_CHECK(lvl) 0
+#define AR_DEBUG_PRINTBUF(buffer, length, desc)
+#define AR_DEBUG_ASSERT(test)
+#define ATH_DEBUG_DECLARE_EXTERN(s)
+#define ATH_DEBUG_SET_DEBUG_MASK(s, lvl)
+#define A_DUMP_MODULE_DEBUG_INFO(s)
+#define A_REGISTER_MODULE_DEBUG_INFO(s)
+
+#endif
+
+#if defined(__linux__) && !defined(LINUX_EMULATION)
+#include "debug_linux.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/uapi/linux/a_types.h b/uapi/linux/a_types.h
new file mode 100644
index 0000000..190d40d
--- /dev/null
+++ b/uapi/linux/a_types.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013-2014 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.
+ */
+
+/* depot/sw/qca_main/perf_pwr_offload/drivers/host/include/a_types.h#7 - integrate change 1327637 (ktext) */
+/* ============================================================================== */
+/* This file contains the definitions of the basic atheros data types. */
+/* It is used to map the data types in atheros files to a platform specific */
+/* type. */
+/* */
+/* Author(s): ="Atheros" */
+/* ============================================================================== */
+
+#ifndef _A_TYPES_H_
+#define _A_TYPES_H_
+#include <athdefs.h>
+
+typedef unsigned int A_UINT32;
+typedef unsigned long long A_UINT64;
+typedef unsigned short A_UINT16;
+typedef unsigned char A_UINT8;
+typedef int A_INT32;
+typedef short A_INT16;
+typedef char A_INT8;
+typedef unsigned char A_UCHAR;
+typedef char A_CHAR;
+typedef _Bool A_BOOL;
+
+#endif /* _ATHTYPES_H_ */
diff --git a/uapi/linux/athstartpack.h b/uapi/linux/athstartpack.h
new file mode 100644
index 0000000..0b92352
--- /dev/null
+++ b/uapi/linux/athstartpack.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013-2014 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.
+ */
+
+#ifndef _ATHSTARTPACK_H
+#define _ATHSTARTPACK_H
+
+#if defined(LINUX) || defined(__linux__)
+#include "osapi_linux.h"
+#endif /* LINUX */
+
+#ifdef QNX
+#endif /* QNX */
+
+#if __LONG_MAX__ == __INT_MAX__
+/* 32-bit compilation */
+#define PREPACK64
+#define POSTPACK64
+#else
+/* 64-bit compilation */
+#define PREPACK64 PREPACK
+#define POSTPACK64 POSTPACK
+#endif
+
+#endif /* _ATHSTARTPACK_H */
diff --git a/uapi/linux/dbglog_common.h b/uapi/linux/dbglog_common.h
new file mode 100644
index 0000000..75c2d5e
--- /dev/null
+++ b/uapi/linux/dbglog_common.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2011, 2014-2015 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.
+ */
+
+#ifndef _DBGLOG_COMMON_H_
+#define _DBGLOG_COMMON_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "dbglog_id.h"
+#include "dbglog.h"
+
+#define MAX_DBG_MSGS 256
+
+#define ATH6KL_FWLOG_PAYLOAD_SIZE              1500
+
+#define DBGLOG_PRINT_PREFIX "FWLOG: "
+
+/* Handy Macros to read data length and type from FW */
+#define WLAN_DIAG_0_TYPE_S          0
+#define WLAN_DIAG_0_TYPE            0x000000ff
+#define WLAN_DIAG_0_TYPE_GET(x)     WMI_F_MS(x, WLAN_DIAG_0_TYPE)
+#define WLAN_DIAG_0_TYPE_SET(x, y)  WMI_F_RMW(x, y, WLAN_DIAG_0_TYPE)
+/* bits 8-15 reserved */
+
+/* length includes the size of wlan_diag_data */
+#define WLAN_DIAG_0_LEN_S           16
+#define WLAN_DIAG_0_LEN             0xffff0000
+#define WLAN_DIAG_0_LEN_GET(x)      WMI_F_MS(x, WLAN_DIAG_0_LEN)
+#define WLAN_DIAG_0_LEN_SET(x, y)   WMI_F_RMW(x, y, WLAN_DIAG_0_LEN)
+
+#define CNSS_DIAG_SLEEP_INTERVAL    5   /* In secs */
+
+#define ATH6KL_FWLOG_MAX_ENTRIES   20
+#define ATH6KL_FWLOG_PAYLOAD_SIZE  1500
+
+#define DIAG_WLAN_DRIVER_UNLOADED 6
+#define DIAG_WLAN_DRIVER_LOADED   7
+#define DIAG_TYPE_LOGS   1
+#define DIAG_TYPE_EVENTS 2
+
+typedef enum {
+	DBGLOG_PROCESS_DEFAULT = 0,
+	DBGLOG_PROCESS_PRINT_RAW,       /* print them in debug view */
+	DBGLOG_PROCESS_POOL_RAW,        /* user buffer pool to save them */
+	DBGLOG_PROCESS_NET_RAW,         /* user buffer pool to save them */
+	DBGLOG_PROCESS_MAX,
+} dbglog_process_t;
+
+enum cnss_diag_type {
+	DIAG_TYPE_FW_EVENT,           /* send fw event- to diag */
+	DIAG_TYPE_FW_LOG,             /* send log event- to diag */
+	DIAG_TYPE_FW_DEBUG_MSG,       /* send dbg message- to diag */
+	DIAG_TYPE_INIT_REQ,           /* cnss_diag initialization- from diag */
+	DIAG_TYPE_FW_MSG,             /* fw msg command-to diag */
+	DIAG_TYPE_HOST_MSG,           /* host command-to diag */
+	DIAG_TYPE_CRASH_INJECT,       /*crash inject-from diag */
+	DIAG_TYPE_DBG_LEVEL,          /* DBG LEVEL-from diag */
+};
+
+enum wlan_diag_config_type {
+	DIAG_VERSION_INFO,
+};
+
+enum wlan_diag_frame_type {
+	WLAN_DIAG_TYPE_CONFIG,
+	WLAN_DIAG_TYPE_EVENT,
+	WLAN_DIAG_TYPE_LOG,
+	WLAN_DIAG_TYPE_MSG,
+	WLAN_DIAG_TYPE_LEGACY_MSG,
+};
+
+/* log/event are always 32-bit aligned. Padding is inserted after
+ * optional payload to satisify this requirement */
+struct wlan_diag_data {
+	unsigned int word0;             /* type, length */
+	unsigned int target_time;
+	unsigned int code;              /* Diag log or event Code */
+	uint8_t payload[0];
+};
+
+struct dbglog_slot {
+	unsigned int diag_type;
+	unsigned int timestamp;
+	unsigned int length;
+	unsigned int dropped;
+	/* max ATH6KL_FWLOG_PAYLOAD_SIZE bytes */
+	uint8_t payload[0];
+} __packed;
+
+typedef struct event_report_s {
+	unsigned int diag_type;
+	unsigned short event_id;
+	unsigned short length;
+} event_report_t;
+
+/*
+ * Custom debug_print handlers
+ * Args:
+ * module Id
+ * vap id
+ * debug msg id
+ * Time stamp
+ * no of arguments
+ * pointer to the buffer holding the args
+ */
+typedef A_BOOL (*module_dbg_print)(A_UINT32, A_UINT16, A_UINT32,
+				   A_UINT32, A_UINT16, A_UINT32 *);
+
+/** Register module specific dbg print*/
+void dbglog_reg_modprint(A_UINT32 mod_id, module_dbg_print printfn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DBGLOG_COMMON_H_ */
diff --git a/uapi/linux/debug_linux.h b/uapi/linux/debug_linux.h
new file mode 100644
index 0000000..d91dd11
--- /dev/null
+++ b/uapi/linux/debug_linux.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013-2016 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.
+ */
+
+#ifndef _DEBUG_LINUX_H_
+#define _DEBUG_LINUX_H_
+
+/* macro to remove parens */
+#define ATH_PRINTX_ARG(arg ...) arg
+
+#ifdef WLAN_DEBUG
+/* NOTE: the AR_DEBUG_PRINTF macro is defined here to handle special handling of variable arg macros
+ * which may be compiler dependent. */
+#define AR_DEBUG_PRINTF(mask, args) do {	\
+		if (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (mask)) {			  \
+			A_LOGGER(mask, ATH_MODULE_NAME, ATH_PRINTX_ARG args);	 \
+		}					     \
+} while (0)
+#else
+/* on non-debug builds, keep in error and warning messages in the driver, all other
+ * message tracing will get compiled out */
+#define AR_DEBUG_PRINTF(mask, args) \
+	if ((mask) & (ATH_DEBUG_ERR | ATH_DEBUG_WARN)) { A_PRINTF(ATH_PRINTX_ARG args); }
+
+#endif
+
+#endif /* _DEBUG_LINUX_H_ */
diff --git a/uapi/linux/osapi_linux.h b/uapi/linux/osapi_linux.h
new file mode 100644
index 0000000..003a92c
--- /dev/null
+++ b/uapi/linux/osapi_linux.h
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2013-2018 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.
+ */
+
+/* ------------------------------------------------------------------------------ */
+/* This file contains the definitions of the basic atheros data types. */
+/* It is used to map the data types in atheros files to a platform specific */
+/* type. */
+/* ------------------------------------------------------------------------------ */
+
+#ifndef _OSAPI_LINUX_H_
+#define _OSAPI_LINUX_H_
+
+#ifdef __KERNEL__
+
+#include <linux/version.h>
+#include <generated/autoconf.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/semaphore.h>
+
+#include <linux/cache.h>
+/* #include <linux/kthread.h> */
+#include "a_types.h"
+
+#ifdef __GNUC__
+#define __ATTRIB_PACK           __attribute__ ((packed))
+#define __ATTRIB_PRINTF         __attribute__ ((format (printf, 1, 2)))
+#define __ATTRIB_NORETURN       __attribute__ ((noreturn))
+#ifndef INLINE
+#define INLINE                  __inline__
+#endif
+#else                           /* Not GCC */
+#define __ATTRIB_PACK
+#define __ATTRIB_PRINTF
+#define __ATTRIB_NORETURN
+#ifndef INLINE
+#define INLINE                  __inline
+#endif
+#endif /* End __GNUC__ */
+
+#define PREPACK
+#define POSTPACK                __ATTRIB_PACK
+
+#define A_MEMCPY(dst, src, len)         memcpy((A_UINT8 *)(dst), (src), (len))
+#define A_MEMZERO(addr, len)            memset(addr, 0, len)
+#define A_MEMSET(addr, value, size)     memset((addr), (value), (size))
+#define A_MEMCMP(addr1, addr2, len)     memcmp((addr1), (addr2), (len))
+
+#define A_LOGGER(mask, mod, args ...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, args)
+#define A_PRINTF(args ...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, args)
+#define A_SNPRINTF(buf, len, args ...)   snprintf(buf, len, args)
+
+/*
+ * Timer Functions
+ */
+#define A_MSLEEP(msecs)							   \
+	{									   \
+		set_current_state(TASK_INTERRUPTIBLE);				       \
+		schedule_timeout((HZ * (msecs)) / 1000);			       \
+		set_current_state(TASK_RUNNING);				       \
+	}
+
+typedef struct timer_list A_TIMER;
+
+/*
+ * Wait Queue related functions
+ */
+#ifndef wait_event_interruptible_timeout
+#define __wait_event_interruptible_timeout(wq, condition, ret)		\
+	do {									\
+		wait_queue_t __wait;						\
+		init_waitqueue_entry(&__wait, current);				\
+									\
+		add_wait_queue(&wq, &__wait);					\
+		for (;; ) {							 \
+			set_current_state(TASK_INTERRUPTIBLE);			\
+			if (condition)						\
+				break;						\
+			if (!signal_pending(current)) {				\
+				ret = schedule_timeout(ret);			\
+				if (!ret)					\
+					break;					\
+				continue;					\
+			}							\
+			ret = -ERESTARTSYS;					\
+			break;							\
+		}								\
+		current->state = TASK_RUNNING;					\
+		remove_wait_queue(&wq, &__wait);				\
+	} while (0)
+
+#define wait_event_interruptible_timeout(wq, condition, timeout)	\
+	({									\
+		long __ret = timeout;						 \
+		if (!(condition))						 \
+			__wait_event_interruptible_timeout(wq, condition, __ret); \
+		__ret;								 \
+	 })
+#endif /* wait_event_interruptible_timeout */
+
+#ifdef WLAN_DEBUG
+#ifdef A_SIMOS_DEVHOST
+extern unsigned int panic_on_assert;
+#define A_ASSERT(expr)	\
+	if (!(expr)) {	 \
+		printk(KERN_ALERT "Debug Assert Caught, File %s, Line: %d, Test:%s\n", __FILE__, __LINE__, # expr); \
+		if (panic_on_assert) panic(# expr);								  \
+	}
+#else
+#define A_ASSERT(expr)	\
+	if (!(expr)) {	 \
+		printk(KERN_ALERT "Debug Assert Caught, File %s, Line: %d, Test:%s\n", __FILE__, __LINE__, # expr); \
+	}
+#endif
+#else
+#define A_ASSERT(expr)
+#endif /* DEBUG */
+
+#ifdef ANDROID_ENV
+struct firmware;
+int android_request_firmware(const struct firmware **firmware_p,
+			     const char *filename, struct device *device);
+void android_release_firmware(const struct firmware *firmware);
+#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) android_request_firmware(_ppf, _pfile, _dev)
+#define A_RELEASE_FIRMWARE(_pf) android_release_firmware(_pf)
+#else
+#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) request_firmware(_ppf, _pfile, _dev)
+#define A_RELEASE_FIRMWARE(_pf) release_firmware(_pf)
+#endif
+
+/*
+ * Network buffer queue support
+ */
+typedef struct sk_buff_head A_NETBUF_QUEUE_T;
+
+#define A_NETBUF_FREE(bufPtr) \
+	a_netbuf_free(bufPtr)
+#define A_NETBUF_LEN(bufPtr) \
+	a_netbuf_to_len(bufPtr)
+#define A_NETBUF_PUSH(bufPtr, len) \
+	a_netbuf_push(bufPtr, len)
+#define A_NETBUF_PUT(bufPtr, len) \
+	a_netbuf_put(bufPtr, len)
+#define A_NETBUF_TRIM(bufPtr, len) \
+	a_netbuf_trim(bufPtr, len)
+#define A_NETBUF_PULL(bufPtr, len) \
+	a_netbuf_pull(bufPtr, len)
+#define A_NETBUF_HEADROOM(bufPtr) \
+	a_netbuf_headroom(bufPtr)
+#define A_NETBUF_SETLEN(bufPtr, len) \
+	a_netbuf_setlen(bufPtr, len)
+
+/* Add data to end of a buffer  */
+#define A_NETBUF_PUT_DATA(bufPtr, srcPtr,  len)	\
+	a_netbuf_put_data(bufPtr, srcPtr, len)
+
+/* Add data to start of the  buffer */
+#define A_NETBUF_PUSH_DATA(bufPtr, srcPtr,  len) \
+	a_netbuf_push_data(bufPtr, srcPtr, len)
+
+/* Remove data at start of the buffer */
+#define A_NETBUF_PULL_DATA(bufPtr, dstPtr, len)	\
+	a_netbuf_pull_data(bufPtr, dstPtr, len)
+
+/* Remove data from the end of the buffer */
+#define A_NETBUF_TRIM_DATA(bufPtr, dstPtr, len)	\
+	a_netbuf_trim_data(bufPtr, dstPtr, len)
+
+/* View data as "size" contiguous bytes of type "t" */
+#define A_NETBUF_VIEW_DATA(bufPtr, t, size) \
+	(t)(((struct skbuf *)(bufPtr))->data)
+
+/* return the beginning of the headroom for the buffer */
+#define A_NETBUF_HEAD(bufPtr) \
+	((((struct sk_buff *)(bufPtr))->head))
+
+/*
+ * OS specific network buffer access routines
+ */
+void a_netbuf_free(void *bufPtr);
+void *a_netbuf_to_data(void *bufPtr);
+A_UINT32 a_netbuf_to_len(void *bufPtr);
+A_STATUS a_netbuf_push(void *bufPtr, A_INT32 len);
+A_STATUS a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len);
+A_STATUS a_netbuf_put(void *bufPtr, A_INT32 len);
+A_STATUS a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len);
+A_STATUS a_netbuf_pull(void *bufPtr, A_INT32 len);
+A_STATUS a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len);
+A_STATUS a_netbuf_trim(void *bufPtr, A_INT32 len);
+A_STATUS a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len);
+A_STATUS a_netbuf_setlen(void *bufPtr, A_INT32 len);
+A_INT32 a_netbuf_headroom(void *bufPtr);
+void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt);
+void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt);
+void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q);
+int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q);
+int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
+int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
+void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q);
+
+#ifdef QCA_PARTNER_PLATFORM
+#include "ath_carr_pltfrm.h"
+#endif /* QCA_PARTNER_PLATFORM */
+
+#else                           /* __KERNEL__ */
+
+#ifdef __GNUC__
+#define __ATTRIB_PACK           __attribute__ ((packed))
+#define __ATTRIB_PRINTF         __attribute__ ((format (printf, 1, 2)))
+#define __ATTRIB_NORETURN       __attribute__ ((noreturn))
+#ifndef inline
+#define inline                  __inline__
+#endif
+#ifndef INLINE
+#define INLINE                  __inline__
+#endif
+#else                           /* Not GCC */
+#define __ATTRIB_PACK
+#define __ATTRIB_PRINTF
+#define __ATTRIB_NORETURN
+#ifndef inline
+#define inline                  __inline
+#endif
+#ifndef INLINE
+#define INLINE                  __inline
+#endif
+#endif /* End __GNUC__ */
+
+#define PREPACK
+#define POSTPACK                __ATTRIB_PACK
+
+#define A_MEMCPY(dst, src, len)         memcpy((dst), (src), (len))
+#define A_MEMSET(addr, value, size)     memset((addr), (value), (size))
+#define A_MEMZERO(addr, len)            memset((addr), 0, (len))
+#define A_MEMCMP(addr1, addr2, len)     memcmp((addr1), (addr2), (len))
+
+#ifdef ANDROID
+#ifndef err
+#include <linux/errno.h>
+#define err(_s, args ...) do { \
+		fprintf(stderr, "%s: line %d ", __FILE__, __LINE__); \
+		fprintf(stderr, args); fprintf(stderr, ": %d\n", errno); \
+		exit(_s); } while (0)
+#endif
+#else
+#include <linux/err.h>
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _OSAPI_LINUX_H_ */
diff --git a/uapi/linux/pktlog_ac_fmt.h b/uapi/linux/pktlog_ac_fmt.h
new file mode 100644
index 0000000..2fe1f65
--- /dev/null
+++ b/uapi/linux/pktlog_ac_fmt.h
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2012-2018 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.
+ */
+
+#ifndef _PKTLOG_FMT_H_
+#define _PKTLOG_FMT_H_
+
+#ifndef REMOVE_PKT_LOG
+
+#define CUR_PKTLOG_VER          10010   /* Packet log version */
+#define PKTLOG_MAGIC_NUM        7735225
+
+#ifdef __linux__
+#ifdef MULTI_IF_NAME
+#define PKTLOG_PROC_DIR "ath_pktlog" MULTI_IF_NAME
+#define WLANDEV_BASENAME "cld" MULTI_IF_NAME
+#else
+#define PKTLOG_PROC_DIR "ath_pktlog"
+#define WLANDEV_BASENAME "cld"
+#endif
+#endif
+#define PKTLOG_PROC_SYSTEM "system"
+#ifdef WIN32
+#pragma pack(push, pktlog_fmt, 1)
+#define __ATTRIB_PACK
+#elif defined(__EFI__)
+#define __ATTRIB_PACK
+#else
+#ifndef __ATTRIB_PACK
+#define __ATTRIB_PACK __attribute__ ((packed))
+#endif
+#endif
+#include <a_types.h>
+/*
+ * Each packet log entry consists of the following fixed length header
+ * followed by variable length log information determined by log_type
+ */
+
+struct ath_pktlog_hdr {
+	uint16_t flags;
+	uint16_t missed_cnt;
+#ifdef HELIUMPLUS
+	uint8_t log_type;
+	uint8_t macId;
+#else
+	uint16_t log_type;
+#endif
+	uint16_t size;
+	uint32_t timestamp;
+	uint32_t type_specific_data;
+} __ATTRIB_PACK;
+
+#define ATH_PKTLOG_HDR_FLAGS_MASK 0xffff
+#define ATH_PKTLOG_HDR_FLAGS_SHIFT 0
+#define ATH_PKTLOG_HDR_FLAGS_OFFSET 0
+#define ATH_PKTLOG_HDR_MISSED_CNT_MASK 0xffff0000
+#define ATH_PKTLOG_HDR_MISSED_CNT_SHIFT 16
+#define ATH_PKTLOG_HDR_MISSED_CNT_OFFSET 0
+#ifdef HELIUMPLUS
+#define ATH_PKTLOG_HDR_LOG_TYPE_MASK 0x00ff
+#define ATH_PKTLOG_HDR_LOG_TYPE_SHIFT 0
+#define ATH_PKTLOG_HDR_LOG_TYPE_OFFSET 1
+#define ATH_PKTLOG_HDR_MAC_ID_MASK 0xff00
+#define ATH_PKTLOG_HDR_MAC_ID_SHIFT 8
+#define ATH_PKTLOG_HDR_MAC_ID_OFFSET 1
+#else
+#define ATH_PKTLOG_HDR_LOG_TYPE_MASK 0xffff
+#define ATH_PKTLOG_HDR_LOG_TYPE_SHIFT 0
+#define ATH_PKTLOG_HDR_LOG_TYPE_OFFSET 1
+#endif
+
+#define ATH_PKTLOG_HDR_SIZE_MASK 0xffff0000
+#define ATH_PKTLOG_HDR_SIZE_SHIFT 16
+#define ATH_PKTLOG_HDR_SIZE_OFFSET 1
+#define ATH_PKTLOG_HDR_TIMESTAMP_OFFSET 2
+#define ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET 3
+
+/**
+ * enum - Pktlog flag field details
+ * packet origin [1:0]
+ * 00 - Local
+ * 01 - Remote
+ * 10 - Unknown/Not applicable
+ * 11 - Reserved
+ * reserved [15:2]
+ */
+enum {
+	PKTLOG_FLG_FRM_TYPE_LOCAL_S = 0,
+	PKTLOG_FLG_FRM_TYPE_REMOTE_S,
+	PKTLOG_FLG_FRM_TYPE_CLONE_S,
+	PKTLOG_FLG_FRM_TYPE_CBF_S,
+	PKTLOG_FLG_FRM_TYPE_UNKNOWN_S
+};
+
+#define PHFLAGS_INTERRUPT_CONTEXT 0x80000000
+
+/* Masks for setting pktlog events filters */
+#define ATH_PKTLOG_TX       0x000000001
+#define ATH_PKTLOG_RX       0x000000002
+#define ATH_PKTLOG_RCFIND   0x000000004
+#define ATH_PKTLOG_RCUPDATE 0x000000008
+#define ATH_PKTLOG_ANI      0x000000010
+#define ATH_PKTLOG_TEXT     0x000000020
+#define ATH_PKTLOG_PHYERR   0x000000040
+#define ATH_PKTLOG_PROMISC  0x000000080
+#define ATH_PKTLOG_SW_EVENT 0x000000100
+
+/* WIN defns */
+#define ATH_PKTLOG_H_INFO   0x000000200
+#define ATH_PKTLOG_STEERING 0x000000400
+#define ATH_PKTLOG_REMOTE_LOGGING_ENABLE  0x000000800
+#define ATH_PKTLOG_TX_CAPTURE_ENABLE  0x000001000
+#define ATH_PKTLOG_LITE_T2H  0x000002000
+#define ATH_PKTLOG_LITE_RX   0x000004000
+
+/* Types of packet log events */
+#define PKTLOG_TYPE_TX_CTRL      1
+#define PKTLOG_TYPE_TX_STAT      2
+#define PKTLOG_TYPE_TX_MSDU_ID   3
+#define PKTLOG_TYPE_TX_FRM_HDR   4
+#define PKTLOG_TYPE_RX_STAT      5
+#define PKTLOG_TYPE_RC_FIND      6
+#define PKTLOG_TYPE_RC_UPDATE    7
+#define PKTLOG_TYPE_TX_VIRT_ADDR 8
+#define PKTLOG_TYPE_SMART_ANTENNA 9
+#define PKTLOG_TYPE_SW_EVENT     10
+#define PKTLOG_TYPE_PKT_DUMP     11
+/* From WIN definations */
+#define PKTLOG_TYPE_LITE_T2H     23
+#define PKTLOG_TYPE_LITE_RX      24
+#define PKTLOG_TYPE_MAX          25
+
+#define PKTLOG_MAX_TXCTL_WORDS 57       /* +2 words for bitmap */
+#define PKTLOG_MAX_TXSTATUS_WORDS 32
+#define PKTLOG_MAX_PROTO_WORDS  16
+#define PKTLOG_MAX_RXDESC_WORDS 62
+#define PKTLOG_HDR_SIZE_16      0x8000
+
+struct txctl_frm_hdr {
+	uint16_t framectrl;     /* frame control field from header */
+	uint16_t seqctrl;       /* frame control field from header */
+	uint16_t bssid_tail;    /* last two octets of bssid */
+	uint16_t sa_tail;       /* last two octets of SA */
+	uint16_t da_tail;       /* last two octets of DA */
+	uint16_t resvd;
+};
+
+#if defined(HELIUMPLUS)
+/* Peregrine 11ac based */
+#define MAX_PKT_INFO_MSDU_ID 1
+#else
+/* Peregrine 11ac based */
+#define MAX_PKT_INFO_MSDU_ID 192
+#endif /* defined(HELIUMPLUS) */
+
+/*
+ * msdu_id_info_t is defined for reference only
+ */
+struct msdu_id_info {
+	uint32_t num_msdu;
+	uint8_t bound_bmap[(MAX_PKT_INFO_MSDU_ID + 7)>>3];
+	/* TODO:
+	*  Convert the id's to uint32_t
+	*  Reduces computation in the driver code
+	*/
+	uint16_t id[MAX_PKT_INFO_MSDU_ID];
+} __ATTRIB_PACK;
+#define MSDU_ID_INFO_NUM_MSDU_OFFSET 0 /* char offset */
+#define MSDU_ID_INFO_BOUND_BM_OFFSET offsetof(struct msdu_id_info, bound_bmap)
+#define MSDU_ID_INFO_ID_OFFSET  offsetof(struct msdu_id_info, id)
+
+
+struct ath_pktlog_txctl {
+	struct ath_pktlog_hdr pl_hdr;
+	/* struct txctl_frm_hdr frm_hdr; */
+	void *txdesc_hdr_ctl;   /* frm_hdr + Tx descriptor words */
+	struct {
+		struct txctl_frm_hdr frm_hdr;
+		uint32_t txdesc_ctl[PKTLOG_MAX_TXCTL_WORDS];
+		/* uint32_t *proto_hdr;   / * protocol header (variable length!) * / */
+		/* uint32_t *misc; / * Can be used for HT specific or other misc info * / */
+	} priv;
+} __ATTRIB_PACK;
+
+struct ath_pktlog_tx_status {
+	struct ath_pktlog_hdr pl_hdr;
+	void *ds_status;
+	int32_t misc[0];        /* Can be used for HT specific or other misc info */
+} __ATTRIB_PACK;
+
+struct ath_pktlog_msdu_info {
+	struct ath_pktlog_hdr pl_hdr;
+	void *ath_msdu_info;
+	A_UINT32 num_msdu;
+	struct {
+		/*
+		 * Provision to add more information fields
+		 */
+		struct msdu_info_t {
+			A_UINT32 num_msdu;
+			A_UINT8 bound_bmap[MAX_PKT_INFO_MSDU_ID >> 3];
+		} msdu_id_info;
+		/*
+		 * array of num_msdu
+		 * Static implementation will consume unwanted memory
+		 * Need to split the pktlog_get_buf to get the buffer pointer only
+		 */
+		uint16_t msdu_len[MAX_PKT_INFO_MSDU_ID];
+	} priv;
+	size_t priv_size;
+
+} __ATTRIB_PACK;
+
+struct ath_pktlog_rx_info {
+	struct ath_pktlog_hdr pl_hdr;
+	void *rx_desc;
+} __ATTRIB_PACK;
+
+struct ath_pktlog_rc_find {
+	struct ath_pktlog_hdr pl_hdr;
+	void *rcFind;
+} __ATTRIB_PACK;
+
+struct ath_pktlog_sw_event {
+	struct ath_pktlog_hdr pl_hdr;
+	void *sw_event;
+} __ATTRIB_PACK;
+
+struct ath_pktlog_rc_update {
+	struct ath_pktlog_hdr pl_hdr;
+	void *txRateCtrl;       /* rate control state proper */
+} __ATTRIB_PACK;
+
+#ifdef WIN32
+#pragma pack(pop, pktlog_fmt)
+#endif
+#ifdef __ATTRIB_PACK
+#undef __ATTRIB_PACK
+#endif /* __ATTRIB_PACK */
+
+/*
+ * The following header is included in the beginning of the file,
+ * followed by log entries when the log buffer is read through procfs
+ */
+
+struct ath_pktlog_bufhdr {
+	uint32_t magic_num;     /* Used by post processing scripts */
+	uint32_t version;       /* Set to CUR_PKTLOG_VER */
+};
+
+struct ath_pktlog_buf {
+	struct ath_pktlog_bufhdr bufhdr;
+	int32_t rd_offset;
+	volatile int32_t wr_offset;
+	/* Whenever this bytes written value croses 4K bytes,
+	 * logging will be triggered
+	 */
+	int32_t bytes_written;
+	/* Index of the messages sent to userspace */
+	uint32_t msg_index;
+	/* Offset for read */
+	loff_t offset;
+	char log_data[0];
+};
+
+#define PKTLOG_MOV_RD_IDX(_rd_offset, _log_buf, _log_size)  \
+	do { \
+		if ((_rd_offset + sizeof(struct ath_pktlog_hdr) + \
+		    ((struct ath_pktlog_hdr *)((_log_buf)->log_data + \
+					       (_rd_offset)))->size) <= _log_size) { \
+			_rd_offset = ((_rd_offset) + sizeof(struct ath_pktlog_hdr) + \
+				      ((struct ath_pktlog_hdr *)((_log_buf)->log_data +	\
+								 (_rd_offset)))->size);	\
+		} else { \
+			_rd_offset = ((struct ath_pktlog_hdr *)((_log_buf)->log_data +	\
+								(_rd_offset)))->size;  \
+		} \
+		(_rd_offset) = (((_log_size) - (_rd_offset)) >=	\
+				sizeof(struct ath_pktlog_hdr)) ? _rd_offset : 0; \
+	} while (0)
+
+#endif /* REMOVE_PKT_LOG */
+
+/**
+ * enum pkt_type - packet type
+ * @START_MONITOR: indicates parser to start packetdump parsing
+ * @STOP_MONITOR: indicates parser to stop packetdump parsing
+ * @TX_MGMT_PKT: TX management Packet
+ * @TX_DATA_PKT: TX data Packet
+ * @RX_MGMT_PKT: RX management Packet
+ * @RX_DATA_PKT: RX data Packet
+ *
+ * This enum has packet types
+ */
+enum pkt_type {
+	START_MONITOR = 1,
+	STOP_MONITOR,
+	TX_MGMT_PKT,
+	TX_DATA_PKT,
+	RX_MGMT_PKT,
+	RX_DATA_PKT,
+};
+
+/**
+ * enum tx_pkt_fate - tx packet fate
+ * @TX_PKT_FATE_ACKED: Sent over air and ACKed
+ * @TX_PKT_FATE_SENT: Sent over air but not ACKed.
+ * @TX_PKT_FATE_FW_QUEUED: Queued within firmware,
+ * but not yet sent over air
+ * @TX_PKT_FATE_FW_DROP_INVALID: Dropped by firmware as invalid.
+ * E.g. bad source address, bad checksum, or invalid for current state.
+ * @TX_PKT_FATE_FW_DROP_NOBUFS: Dropped by firmware due
+ * to lack of buffer space
+ * @TX_PKT_FATE_FW_DROP_OTHER: Dropped by firmware for any other
+ * reason. Includes frames that were sent by driver to firmware, but
+ * unaccounted for by firmware.
+ * @TX_PKT_FATE_DRV_QUEUED: Queued within driver, not yet sent to firmware.
+ * @TX_PKT_FATE_DRV_DROP_INVALID: Dropped by driver as invalid.
+ * E.g. bad source address, or invalid for current state.
+ * @TX_PKT_FATE_DRV_DROP_NOBUFS: Dropped by driver due to lack of buffer space
+ * @TX_PKT_FATE_DRV_DROP_OTHER: Dropped by driver for any other reason.
+ * E.g. out of buffers.
+ *
+ * This enum has packet fate types
+ */
+
+enum tx_pkt_fate {
+	TX_PKT_FATE_ACKED,
+	TX_PKT_FATE_SENT,
+	TX_PKT_FATE_FW_QUEUED,
+	TX_PKT_FATE_FW_DROP_INVALID,
+	TX_PKT_FATE_FW_DROP_NOBUFS,
+	TX_PKT_FATE_FW_DROP_OTHER,
+	TX_PKT_FATE_DRV_QUEUED,
+	TX_PKT_FATE_DRV_DROP_INVALID,
+	TX_PKT_FATE_DRV_DROP_NOBUFS,
+	TX_PKT_FATE_DRV_DROP_OTHER,
+};
+
+/**
+ * enum rx_pkt_fate - rx packet fate
+ * @RX_PKT_FATE_SUCCESS: Valid and delivered to
+ * network stack (e.g., netif_rx()).
+ * @RX_PKT_FATE_FW_QUEUED: Queued within firmware,
+ * but not yet sent to driver.
+ * @RX_PKT_FATE_FW_DROP_FILTER: Dropped by firmware
+ * due to host-programmable filters.
+ * @RX_PKT_FATE_FW_DROP_INVALID: Dropped by firmware
+ * as invalid. E.g. bad checksum, decrypt failed, or invalid for current state.
+ * @RX_PKT_FATE_FW_DROP_NOBUFS: Dropped by firmware
+ * due to lack of buffer space.
+ * @RX_PKT_FATE_FW_DROP_OTHER: Dropped by firmware
+ * for any other reason.
+ * @RX_PKT_FATE_DRV_QUEUED: Queued within driver,
+ * not yet delivered to network stack.
+ * @RX_PKT_FATE_DRV_DROP_FILTER: Dropped by driver
+ * due to filter rules.
+ * @RX_PKT_FATE_DRV_DROP_INVALID: Dropped by driver as invalid.
+ * E.g. not permitted in current state.
+ * @RX_PKT_FATE_DRV_DROP_NOBUFS: Dropped by driver
+ * due to lack of buffer space.
+ * @RX_PKT_FATE_DRV_DROP_OTHER: Dropped by driver for any other reason.
+ *
+ * This enum has packet fate types
+ */
+
+enum rx_pkt_fate {
+	RX_PKT_FATE_SUCCESS,
+	RX_PKT_FATE_FW_QUEUED,
+	RX_PKT_FATE_FW_DROP_FILTER,
+	RX_PKT_FATE_FW_DROP_INVALID,
+	RX_PKT_FATE_FW_DROP_NOBUFS,
+	RX_PKT_FATE_FW_DROP_OTHER,
+	RX_PKT_FATE_DRV_QUEUED,
+	RX_PKT_FATE_DRV_DROP_FILTER,
+	RX_PKT_FATE_DRV_DROP_INVALID,
+	RX_PKT_FATE_DRV_DROP_NOBUFS,
+	RX_PKT_FATE_DRV_DROP_OTHER,
+};
+
+#endif /* _PKTLOG_FMT_H_ */